summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Manifest74
-rw-r--r--README103
-rw-r--r--Roadmap45
-rw-r--r--WHATSNEW.txt2462
-rwxr-xr-xdocs/OID/allocated-arcs.txt19
-rwxr-xr-xdocs/OID/samba-oid.mail27
-rw-r--r--docs/README-NOW10
-rwxr-xr-xdocs/README.Win2kSP256
-rwxr-xr-xdocs/README.Win32-Viruses58
-rwxr-xr-xdocs/README.ldap1
-rwxr-xr-xdocs/Registry/NT4-Locking.reg24
-rwxr-xr-xdocs/Registry/NT4_PlainPassword.reg11
-rwxr-xr-xdocs/Registry/Win2000_PlainPassword.reg11
-rwxr-xr-xdocs/Registry/Win95_PlainPassword.reg4
-rwxr-xr-xdocs/Registry/Win98_PlainPassword.reg4
-rwxr-xr-xdocs/Registry/Win9X-CacheHandling.reg7
-rwxr-xr-xdocs/Registry/WinME_PlainPassword.reg4
-rwxr-xr-xdocs/Registry/WinXP_SignOrSeal.reg11
-rwxr-xr-xdocs/Registry/WindowsTerminalServer.reg7
-rwxr-xr-xdocs/Samba-HOWTO-Collection.pdf3173
-rwxr-xr-xdocs/THANKS137
-rwxr-xr-xdocs/announce150
-rwxr-xr-xdocs/docbook/Makefile.in383
-rwxr-xr-xdocs/docbook/configure1065
-rwxr-xr-xdocs/docbook/configure.in49
-rwxr-xr-xdocs/docbook/dbsgml/40chg.txt45
-rwxr-xr-xdocs/docbook/dbsgml/41chg.txt7
-rwxr-xr-xdocs/docbook/dbsgml/50issues.txt39
-rwxr-xr-xdocs/docbook/dbsgml/ChangeLog85
-rwxr-xr-xdocs/docbook/dbsgml/cals-tbl.dtd330
-rwxr-xr-xdocs/docbook/dbsgml/catalog63
-rwxr-xr-xdocs/docbook/dbsgml/dbcent.mod181
-rwxr-xr-xdocs/docbook/dbsgml/dbgenent.mod39
-rwxr-xr-xdocs/docbook/dbsgml/dbhier.mod2100
-rwxr-xr-xdocs/docbook/dbsgml/dbnotn.mod97
-rwxr-xr-xdocs/docbook/dbsgml/dbpool.mod7396
-rwxr-xr-xdocs/docbook/dbsgml/docbook.cat63
-rwxr-xr-xdocs/docbook/dbsgml/docbook.dcl106
-rwxr-xr-xdocs/docbook/dbsgml/docbook.dtd117
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamsa66
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamsb52
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamsc20
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamsn70
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamso29
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOamsr94
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISObox62
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOcyr177
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOcyr236
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOdia24
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOgrk159
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOgrk230
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOgrk353
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOgrk453
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOlat172
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOlat2131
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOnum91
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOpub100
-rwxr-xr-xdocs/docbook/dbsgml/ent/ISOtech73
-rwxr-xr-xdocs/docbook/dbsgml/readme.txt12
-rwxr-xr-xdocs/docbook/docbook.txt136
-rwxr-xr-xdocs/docbook/faq/README.NOW2
-rwxr-xr-xdocs/docbook/global.ent33
-rwxr-xr-xdocs/docbook/howto/README.NOW2
-rwxr-xr-xdocs/docbook/manpages/findsmb.1.sgml131
-rwxr-xr-xdocs/docbook/manpages/lmhosts.5.sgml114
-rwxr-xr-xdocs/docbook/manpages/make_smbcodepage.1.sgml197
-rwxr-xr-xdocs/docbook/manpages/make_unicodemap.1.sgml172
-rwxr-xr-xdocs/docbook/manpages/nmbd.8.sgml372
-rwxr-xr-xdocs/docbook/manpages/nmblookup.1.sgml257
-rwxr-xr-xdocs/docbook/manpages/pdbedit.8.sgml290
-rwxr-xr-xdocs/docbook/manpages/rpcclient.1.sgml420
-rwxr-xr-xdocs/docbook/manpages/samba.7.sgml213
-rwxr-xr-xdocs/docbook/manpages/smb.conf.5.sgml8856
-rwxr-xr-xdocs/docbook/manpages/smbcacls.1.sgml255
-rwxr-xr-xdocs/docbook/manpages/smbclient.1.sgml1088
-rwxr-xr-xdocs/docbook/manpages/smbcontrol.1.sgml189
-rwxr-xr-xdocs/docbook/manpages/smbd.8.sgml429
-rwxr-xr-xdocs/docbook/manpages/smbmnt.8.sgml113
-rwxr-xr-xdocs/docbook/manpages/smbmount.8.sgml327
-rwxr-xr-xdocs/docbook/manpages/smbpasswd.5.sgml204
-rwxr-xr-xdocs/docbook/manpages/smbpasswd.8.sgml514
-rwxr-xr-xdocs/docbook/manpages/smbsh.1.sgml235
-rwxr-xr-xdocs/docbook/manpages/smbspool.8.sgml131
-rwxr-xr-xdocs/docbook/manpages/smbstatus.1.sgml137
-rwxr-xr-xdocs/docbook/manpages/smbtar.1.sgml226
-rwxr-xr-xdocs/docbook/manpages/smbumount.8.sgml73
-rwxr-xr-xdocs/docbook/manpages/swat.8.sgml265
-rwxr-xr-xdocs/docbook/manpages/testparm.1.sgml173
-rwxr-xr-xdocs/docbook/manpages/testprns.1.sgml143
-rwxr-xr-xdocs/docbook/manpages/wbinfo.1.sgml238
-rwxr-xr-xdocs/docbook/manpages/winbindd.8.sgml515
-rwxr-xr-xdocs/docbook/projdoc/CVS-Access.sgml157
-rwxr-xr-xdocs/docbook/projdoc/DOMAIN_MEMBER.sgml224
-rwxr-xr-xdocs/docbook/projdoc/ENCRYPTION.sgml378
-rwxr-xr-xdocs/docbook/projdoc/Integrating-with-Windows.sgml935
-rwxr-xr-xdocs/docbook/projdoc/NT_Security.sgml358
-rwxr-xr-xdocs/docbook/projdoc/OS2-Client-HOWTO.sgml142
-rwxr-xr-xdocs/docbook/projdoc/PAM-Authentication-And-Samba.sgml215
-rwxr-xr-xdocs/docbook/projdoc/Samba-BDC-HOWTO.sgml262
-rwxr-xr-xdocs/docbook/projdoc/Samba-LDAP-HOWTO.sgml640
-rwxr-xr-xdocs/docbook/projdoc/Samba-PDC-HOWTO.sgml1828
-rwxr-xr-xdocs/docbook/projdoc/UNIX_INSTALL.sgml445
-rwxr-xr-xdocs/docbook/projdoc/cups.sgml445
-rwxr-xr-xdocs/docbook/projdoc/msdfs_setup.sgml117
-rwxr-xr-xdocs/docbook/projdoc/printer_driver2.sgml676
-rwxr-xr-xdocs/docbook/projdoc/samba-doc.sgml79
-rwxr-xr-xdocs/docbook/projdoc/winbind.sgml842
-rwxr-xr-xdocs/docbook/scripts/README.ldp_print60
-rwxr-xr-xdocs/docbook/scripts/collateindex.pl595
-rwxr-xr-xdocs/docbook/scripts/fix_print_html.lib172
-rwxr-xr-xdocs/docbook/scripts/ldp_print71
-rwxr-xr-xdocs/docbook/scripts/make-article.pl25
-rwxr-xr-xdocs/docbook/scripts/strip-links.pl16
-rwxr-xr-xdocs/docbook/stylesheets/ldp.dsl.in256
-rwxr-xr-xdocs/faq/README8
-rwxr-xr-xdocs/faq/Samba-Server-FAQ-1.html77
-rwxr-xr-xdocs/faq/Samba-Server-FAQ-2.html500
-rwxr-xr-xdocs/faq/Samba-Server-FAQ.html88
-rwxr-xr-xdocs/faq/Samba-Server-FAQ.sgml492
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-1.html160
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-2.html384
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-3.html101
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-4.html215
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-5.html30
-rwxr-xr-xdocs/faq/Samba-meta-FAQ-6.html30
-rwxr-xr-xdocs/faq/Samba-meta-FAQ.html102
-rwxr-xr-xdocs/faq/Samba-meta-FAQ.sgml771
-rwxr-xr-xdocs/faq/Samba-meta-FAQ.txt924
-rwxr-xr-xdocs/faq/sambafaq-1.html392
-rwxr-xr-xdocs/faq/sambafaq-2.html236
-rwxr-xr-xdocs/faq/sambafaq-3.html322
-rwxr-xr-xdocs/faq/sambafaq-4.html37
-rwxr-xr-xdocs/faq/sambafaq-5.html30
-rwxr-xr-xdocs/faq/sambafaq.html115
-rwxr-xr-xdocs/faq/sambafaq.sgml792
-rwxr-xr-xdocs/faq/sambafaq.txt1122
-rwxr-xr-xdocs/history218
-rwxr-xr-xdocs/htmldocs/CVS-Access.html193
-rwxr-xr-xdocs/htmldocs/DOMAIN_MEMBER.html372
-rwxr-xr-xdocs/htmldocs/ENCRYPTION.html656
-rwxr-xr-xdocs/htmldocs/Integrating-with-Windows.html1072
-rwxr-xr-xdocs/htmldocs/NT_Security.html783
-rwxr-xr-xdocs/htmldocs/OS2-Client-HOWTO.html210
-rwxr-xr-xdocs/htmldocs/PAM-Authentication-And-Samba.html318
-rwxr-xr-xdocs/htmldocs/Samba-BDC-HOWTO.html350
-rwxr-xr-xdocs/htmldocs/Samba-HOWTO-Collection.html11776
-rwxr-xr-xdocs/htmldocs/Samba-LDAP-HOWTO.html985
-rwxr-xr-xdocs/htmldocs/Samba-PDC-HOWTO.html2284
-rwxr-xr-xdocs/htmldocs/UNIX_INSTALL.html814
-rwxr-xr-xdocs/htmldocs/cups.html612
-rwxr-xr-xdocs/htmldocs/findsmb.1.html267
-rwxr-xr-xdocs/htmldocs/lmhosts.5.html214
-rwxr-xr-xdocs/htmldocs/make_smbcodepage.1.html354
-rwxr-xr-xdocs/htmldocs/make_unicodemap.1.html276
-rwxr-xr-xdocs/htmldocs/msdfs_setup.html210
-rwxr-xr-xdocs/htmldocs/nmbd.8.html717
-rwxr-xr-xdocs/htmldocs/nmblookup.1.html403
-rwxr-xr-xdocs/htmldocs/pdbedit.8.html426
-rwxr-xr-xdocs/htmldocs/printer_driver2.html1052
-rwxr-xr-xdocs/htmldocs/rpcclient.1.html719
-rwxr-xr-xdocs/htmldocs/samba.7.html365
-rwxr-xr-xdocs/htmldocs/smb.conf.5.html19921
-rwxr-xr-xdocs/htmldocs/smbcacls.1.html387
-rwxr-xr-xdocs/htmldocs/smbclient.1.html1613
-rwxr-xr-xdocs/htmldocs/smbcontrol.1.html349
-rwxr-xr-xdocs/htmldocs/smbd.8.html761
-rwxr-xr-xdocs/htmldocs/smbmnt.8.html178
-rwxr-xr-xdocs/htmldocs/smbmount.8.html468
-rwxr-xr-xdocs/htmldocs/smbpasswd.5.html316
-rwxr-xr-xdocs/htmldocs/smbpasswd.8.html831
-rwxr-xr-xdocs/htmldocs/smbsh.1.html468
-rwxr-xr-xdocs/htmldocs/smbspool.8.html222
-rwxr-xr-xdocs/htmldocs/smbstatus.1.html209
-rwxr-xr-xdocs/htmldocs/smbtar.1.html351
-rwxr-xr-xdocs/htmldocs/smbumount.8.html140
-rwxr-xr-xdocs/htmldocs/swat.8.html511
-rwxr-xr-xdocs/htmldocs/testparm.1.html304
-rwxr-xr-xdocs/htmldocs/testprns.1.html252
-rwxr-xr-xdocs/htmldocs/using_samba/appa_01.html153
-rwxr-xr-xdocs/htmldocs/using_samba/appa_02.html100
-rwxr-xr-xdocs/htmldocs/using_samba/appa_03.html325
-rwxr-xr-xdocs/htmldocs/using_samba/appa_04.html135
-rwxr-xr-xdocs/htmldocs/using_samba/appa_05.html460
-rwxr-xr-xdocs/htmldocs/using_samba/appb_01.html162
-rwxr-xr-xdocs/htmldocs/using_samba/appb_02.html342
-rwxr-xr-xdocs/htmldocs/using_samba/appb_03.html876
-rwxr-xr-xdocs/htmldocs/using_samba/appc_01.html3497
-rwxr-xr-xdocs/htmldocs/using_samba/appd_01.html1907
-rwxr-xr-xdocs/htmldocs/using_samba/appe_01.html96
-rwxr-xr-xdocs/htmldocs/using_samba/appf_01.html315
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_01.html167
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_02.html212
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_03.html444
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_04.html277
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_05.html130
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_06.html90
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_07.html138
-rwxr-xr-xdocs/htmldocs/using_samba/ch01_08.html89
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_01.html197
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_02.html338
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_03.html235
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_04.html186
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_05.html195
-rwxr-xr-xdocs/htmldocs/using_samba/ch02_06.html108
-rwxr-xr-xdocs/htmldocs/using_samba/ch03_01.html277
-rwxr-xr-xdocs/htmldocs/using_samba/ch03_02.html260
-rwxr-xr-xdocs/htmldocs/using_samba/ch03_03.html579
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_01.html415
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_02.html211
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_03.html190
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_04.html214
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_05.html309
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_06.html414
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_07.html151
-rwxr-xr-xdocs/htmldocs/using_samba/ch04_08.html423
-rwxr-xr-xdocs/htmldocs/using_samba/ch05_01.html786
-rwxr-xr-xdocs/htmldocs/using_samba/ch05_02.html429
-rwxr-xr-xdocs/htmldocs/using_samba/ch05_03.html426
-rwxr-xr-xdocs/htmldocs/using_samba/ch05_04.html433
-rwxr-xr-xdocs/htmldocs/using_samba/ch05_05.html399
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_01.html221
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_02.html423
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_03.html384
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_04.html738
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_05.html333
-rwxr-xr-xdocs/htmldocs/using_samba/ch06_06.html537
-rwxr-xr-xdocs/htmldocs/using_samba/ch07_01.html565
-rwxr-xr-xdocs/htmldocs/using_samba/ch07_02.html757
-rwxr-xr-xdocs/htmldocs/using_samba/ch07_03.html404
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_01.html267
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_02.html156
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_03.html472
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_04.html168
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_05.html396
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_06.html509
-rwxr-xr-xdocs/htmldocs/using_samba/ch08_07.html143
-rwxr-xr-xdocs/htmldocs/using_samba/ch09_01.html397
-rwxr-xr-xdocs/htmldocs/using_samba/ch09_02.html1772
-rwxr-xr-xdocs/htmldocs/using_samba/ch09_03.html136
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0101.gifbin0 -> 9850 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0102.gifbin0 -> 10938 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0103.gifbin0 -> 5823 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0104.gifbin0 -> 20973 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0105.gifbin0 -> 11432 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0106.gifbin0 -> 4658 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0107.gifbin0 -> 10347 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0108.gifbin0 -> 21228 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0109.gifbin0 -> 21762 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0110.gifbin0 -> 6227 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0111.gifbin0 -> 8247 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0112.gifbin0 -> 13955 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0113.gifbin0 -> 12108 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0114.gifbin0 -> 24643 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0201.gifbin0 -> 5401 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0202.gifbin0 -> 21864 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0203.gifbin0 -> 19066 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0204.gifbin0 -> 13719 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0301.gifbin0 -> 11604 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0302.gifbin0 -> 12184 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0303.gifbin0 -> 4121 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0304.gifbin0 -> 4872 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0305.gifbin0 -> 14146 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0306.gifbin0 -> 8055 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0307.gifbin0 -> 12529 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0308.gifbin0 -> 16162 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0309.gifbin0 -> 11689 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0310.gifbin0 -> 12693 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0311.gifbin0 -> 13347 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0312.gifbin0 -> 9694 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0313.gifbin0 -> 10215 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0314.gifbin0 -> 5199 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0315.gifbin0 -> 5979 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0316.gifbin0 -> 9579 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0317.gifbin0 -> 14849 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0318.gifbin0 -> 9998 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0319.gifbin0 -> 10874 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0320.gifbin0 -> 10919 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0321.gifbin0 -> 10805 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0322.gifbin0 -> 15031 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0323.gifbin0 -> 13656 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0324.gifbin0 -> 11731 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0325.gifbin0 -> 14093 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0326.gifbin0 -> 7093 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0327.gifbin0 -> 5959 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0328.gifbin0 -> 7816 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0401.gifbin0 -> 8351 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0402.gifbin0 -> 8591 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0403.gifbin0 -> 9284 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0404.gifbin0 -> 5239 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0405.gifbin0 -> 6754 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0406.gifbin0 -> 5708 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0407.gifbin0 -> 10212 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0501.gifbin0 -> 15642 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0502.gifbin0 -> 7757 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0503.gifbin0 -> 8100 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0504.gifbin0 -> 7238 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0505.gifbin0 -> 7634 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0506.gifbin0 -> 13586 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0507.gifbin0 -> 8965 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0508.gifbin0 -> 15146 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0601.gifbin0 -> 10033 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0602.gifbin0 -> 9024 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0603.gifbin0 -> 6005 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0604.gifbin0 -> 12210 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0605.gifbin0 -> 13525 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0606.gifbin0 -> 16887 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0701.gifbin0 -> 5898 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0702.gifbin0 -> 3723 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0703.gifbin0 -> 13047 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0704.gifbin0 -> 7515 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0705.gifbin0 -> 10366 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0706.gifbin0 -> 25083 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0707.gifbin0 -> 11071 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0708.gifbin0 -> 7773 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0709.gifbin0 -> 14114 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0801.gifbin0 -> 12132 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0802.gifbin0 -> 15299 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0803.gifbin0 -> 9690 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0804.gifbin0 -> 11211 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0805.gifbin0 -> 11927 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0901.gifbin0 -> 16309 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0902.gifbin0 -> 26399 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0903.gifbin0 -> 18573 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0904.gifbin0 -> 8977 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.0905.gifbin0 -> 8062 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.aa01.gifbin0 -> 15078 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.ab01.gifbin0 -> 10028 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/figs/sam.ab02.gifbin0 -> 8422 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/gifs/index.gifbin0 -> 565 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/gifs/samba.s.gifbin0 -> 6284 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/gifs/txthome.gifbin0 -> 320 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/gifs/txtnexta.gifbin0 -> 419 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/gifs/txtpreva.gifbin0 -> 588 bytes
-rwxr-xr-xdocs/htmldocs/using_samba/index.html168
-rwxr-xr-xdocs/htmldocs/using_samba/inx.html1344
-rwxr-xr-xdocs/htmldocs/using_samba/licenseinfo.html181
-rwxr-xr-xdocs/htmldocs/using_samba/this_edition.html48
-rwxr-xr-xdocs/htmldocs/wbinfo.1.html382
-rwxr-xr-xdocs/htmldocs/wfw_slip.htm175
-rwxr-xr-xdocs/htmldocs/winbind.html1211
-rwxr-xr-xdocs/htmldocs/winbindd.8.html964
-rwxr-xr-xdocs/manpages/findsmb.190
-rwxr-xr-xdocs/manpages/lmhosts.592
-rwxr-xr-xdocs/manpages/make_smbcodepage.1140
-rwxr-xr-xdocs/manpages/make_unicodemap.199
-rwxr-xr-xdocs/manpages/nmbd.8260
-rwxr-xr-xdocs/manpages/nmblookup.1159
-rwxr-xr-xdocs/manpages/pdbedit.8202
-rwxr-xr-xdocs/manpages/rpcclient.1329
-rwxr-xr-xdocs/manpages/samba.7141
-rwxr-xr-xdocs/manpages/smb.conf.57679
-rwxr-xr-xdocs/manpages/smbcacls.1191
-rwxr-xr-xdocs/manpages/smbclient.1812
-rwxr-xr-xdocs/manpages/smbcontrol.1129
-rwxr-xr-xdocs/manpages/smbd.8316
-rwxr-xr-xdocs/manpages/smbmnt.863
-rwxr-xr-x[-rw-r--r--]docs/manpages/smbmount.8 (renamed from packaging/Mandrake/mount.cifs.8)113
-rwxr-xr-xdocs/manpages/smbpasswd.5159
-rwxr-xr-xdocs/manpages/smbpasswd.8387
-rwxr-xr-xdocs/manpages/smbsh.1172
-rwxr-xr-xdocs/manpages/smbspool.8102
-rwxr-xr-xdocs/manpages/smbstatus.170
-rwxr-xr-xdocs/manpages/smbtar.1120
-rwxr-xr-xdocs/manpages/smbumount.842
-rwxr-xr-xdocs/manpages/swat.8182
-rwxr-xr-xdocs/manpages/testparm.1103
-rwxr-xr-xdocs/manpages/testprns.190
-rwxr-xr-xdocs/manpages/wbinfo.1138
-rwxr-xr-xdocs/manpages/winbindd.8393
-rwxr-xr-xdocs/textdocs/Application_Serving.txt59
-rwxr-xr-xdocs/textdocs/BROWSING-Config.txt218
-rwxr-xr-xdocs/textdocs/BROWSING.txt562
-rwxr-xr-xdocs/textdocs/BUGS.txt138
-rwxr-xr-xdocs/textdocs/CUPS-PrintingInfo.txt589
-rwxr-xr-xdocs/textdocs/DHCP-Server-Configuration.txt243
-rwxr-xr-xdocs/textdocs/DIAGNOSIS.txt324
-rwxr-xr-xdocs/textdocs/DNIX.txt72
-rwxr-xr-xdocs/textdocs/Faxing.txt223
-rwxr-xr-xdocs/textdocs/GOTCHAS.txt71
-rwxr-xr-xdocs/textdocs/HINTS.txt212
-rwxr-xr-xdocs/textdocs/INSTALL.sambatar33
-rwxr-xr-xdocs/textdocs/Imprints.txt50
-rwxr-xr-xdocs/textdocs/Macintosh_Clients.txt26
-rwxr-xr-xdocs/textdocs/NetBIOS.txt155
-rwxr-xr-xdocs/textdocs/PROFILES.txt388
-rwxr-xr-xdocs/textdocs/Passwords.txt49
-rwxr-xr-xdocs/textdocs/Printing.txt258
-rwxr-xr-xdocs/textdocs/README.DCEDFS78
-rwxr-xr-xdocs/textdocs/README.NOW8
-rwxr-xr-xdocs/textdocs/README.jis149
-rwxr-xr-xdocs/textdocs/README.sambatar23
-rwxr-xr-xdocs/textdocs/Recent-FAQs.txt289
-rwxr-xr-xdocs/textdocs/RoutedNetworks.txt66
-rwxr-xr-xdocs/textdocs/SCO.txt22
-rwxr-xr-xdocs/textdocs/SMBTAR.notes46
-rwxr-xr-xdocs/textdocs/Samba-OpenSSL.txt408
-rwxr-xr-xdocs/textdocs/Speed.txt341
-rwxr-xr-xdocs/textdocs/Speed2.txt60
-rwxr-xr-xdocs/textdocs/Tracing.txt96
-rwxr-xr-xdocs/textdocs/UNIX-SMB.txt234
-rwxr-xr-xdocs/textdocs/UNIX_SECURITY.txt57
-rwxr-xr-xdocs/textdocs/Win95.txt77
-rwxr-xr-xdocs/textdocs/WinNT.txt107
-rwxr-xr-xdocs/textdocs/cifsntdomain.txt1501
-rwxr-xr-xdocs/textdocs/outdated/NTDOMAIN.txt51
-rwxr-xr-xdocs/textdocs/outdated/PRINTER_DRIVER.txt240
-rwxr-xr-xdocs/textdocs/outdated/PROJECTS88
-rwxr-xr-xdocs/textdocs/security_level.txt103
-rwxr-xr-xdocs/yodldocs/README-NOW14
-rw-r--r--examples/LDAP/README61
-rwxr-xr-xexamples/LDAP/convertSambaAccount233
-rwxr-xr-xexamples/LDAP/export_smbpasswd.pl64
-rwxr-xr-xexamples/LDAP/import_smbpasswd.pl119
-rwxr-xr-xexamples/LDAP/ldapchpasswd152
-rw-r--r--examples/LDAP/ldapsync.pl5
-rw-r--r--examples/LDAP/samba-nds.schema352
-rw-r--r--examples/LDAP/samba-schema-netscapeds4.x158
-rw-r--r--examples/LDAP/samba-schema-netscapeds5.x100
-rw-r--r--examples/LDAP/samba-schema.IBMSecureWay2
-rw-r--r--examples/LDAP/samba.schema444
-rw-r--r--examples/LDAP/samba.schema.at.IBM-DS59
-rw-r--r--examples/LDAP/samba.schema.oc.IBM-DS19
-rwxr-xr-xexamples/LDAP/smbldap-tools/AUTHORS0
-rw-r--r--examples/LDAP/smbldap-tools/CONTRIBUTORS14
-rw-r--r--examples/LDAP/smbldap-tools/ChangeLog102
-rw-r--r--examples/LDAP/smbldap-tools/INFRASTRUCTURE9
-rw-r--r--examples/LDAP/smbldap-tools/Makefile2
-rwxr-xr-xexamples/LDAP/smbldap-tools/NEWS0
-rw-r--r--examples/LDAP/smbldap-tools/TODO1
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-groupadd.pl100
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-groupdel.pl22
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-groupmod.pl256
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-groupshow.pl10
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl100
-rw-r--r--examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl94
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-passwd.pl156
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-populate.pl236
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-tools.spec89
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-useradd.pl526
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-userdel.pl37
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-usermod.pl473
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap-usershow.pl9
-rw-r--r--examples/LDAP/smbldap-tools/smbldap_conf.pm173
-rwxr-xr-xexamples/LDAP/smbldap-tools/smbldap_tools.pm1114
-rw-r--r--examples/VFS/Makefile.in50
-rw-r--r--examples/VFS/README51
-rwxr-xr-xexamples/VFS/audit.c333
-rwxr-xr-xexamples/VFS/autogen.sh60
-rwxr-xr-xexamples/VFS/block/block.c515
-rwxr-xr-xexamples/VFS/block/samba-block.conf6
-rwxr-xr-xexamples/VFS/block/smb.conf13
-rw-r--r--examples/VFS/configure.in412
-rw-r--r--examples/VFS/install-sh238
-rwxr-xr-xexamples/VFS/recycle/README83
-rwxr-xr-xexamples/VFS/recycle/cleanup_recycle.pl25
-rwxr-xr-xexamples/VFS/recycle/recycle.c557
-rwxr-xr-xexamples/VFS/recycle/recycle.conf17
-rw-r--r--examples/VFS/shadow_copy_test.c83
-rwxr-xr-xexamples/VFS/skel.c528
-rw-r--r--examples/VFS/skel_opaque.c581
-rw-r--r--examples/VFS/skel_transparent.c548
-rw-r--r--examples/auth/Makefile31
-rw-r--r--examples/auth/auth_skel.c59
-rw-r--r--examples/genlogon/genlogon.pl71
-rw-r--r--examples/libsmbclient/Makefile17
-rw-r--r--examples/libsmbclient/testacl.c280
-rw-r--r--examples/libsmbclient/testbrowse.c91
-rw-r--r--examples/libsmbclient/testsmbc.c129
-rw-r--r--examples/libsmbclient/tree.c11
-rwxr-xr-xexamples/misc/modify_samba_config.pl2
-rw-r--r--examples/misc/swat.pl2
-rw-r--r--examples/nss/nss_winbind.c422
-rw-r--r--examples/nss/nss_winbind.h97
-rw-r--r--examples/nss/wbtest.c111
-rw-r--r--examples/ntlogon/README160
-rw-r--r--examples/ntlogon/ntlogon.conf44
-rwxr-xr-xexamples/ntlogon/ntlogon.py376
-rw-r--r--examples/pdb/Makefile31
-rw-r--r--examples/pdb/README16
-rw-r--r--examples/pdb/mysql/mysql.dump37
-rw-r--r--examples/pdb/mysql/smb.conf11
-rw-r--r--examples/pdb/pdb_test.c145
-rw-r--r--examples/pdb/sambapdb.dtd46
-rw-r--r--examples/printing/prtpub.c238
-rw-r--r--examples/printing/readme.prtpub12
-rwxr-xr-xexamples/printing/smbprint1
-rwxr-xr-xexamples/printing/smbprint.newer95
-rwxr-xr-x[-rw-r--r--]examples/printing/smbprint.safer (renamed from examples/printing/smbprint-new.sh)11
-rw-r--r--examples/printing/smbprint.sysv2
-rw-r--r--examples/smb.conf.default474
-rw-r--r--examples/wins_hook/README8
-rw-r--r--examples/wins_hook/dns_update94
-rw-r--r--make-tarball.sh43
-rwxr-xr-xpackaging/Caldera/OpenLinux/README.Public9
-rwxr-xr-xpackaging/Caldera/OpenLinux/README.home15
-rwxr-xr-xpackaging/Caldera/OpenLinux/README.profiles10
-rwxr-xr-xpackaging/Caldera/OpenLinux/findsmb (renamed from packaging/SGI/findsmb)12
-rwxr-xr-xpackaging/Caldera/OpenLinux/kanji-makefile.patch11
-rwxr-xr-xpackaging/Caldera/OpenLinux/makerpms.sh.tmpl54
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba-2.2.2-libsmbclient.patch12
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba.daemon7
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba.init66
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba.init-lsb144
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba.logrotate12
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba.pam49
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba2.spec-lsb.tmpl555
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba2.spec-sam.tmpl546
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba2.spec-team.tmpl539
-rwxr-xr-xpackaging/Caldera/OpenLinux/samba2.spec.tmpl493
-rwxr-xr-xpackaging/Caldera/OpenLinux/smb.conf52
-rwxr-xr-xpackaging/Caldera/OpenLinux/smb.conf.sample318
-rwxr-xr-xpackaging/Caldera/OpenLinux/smbadduser76
-rwxr-xr-x[-rw-r--r--]packaging/Caldera/OpenLinux/smbprint (renamed from packaging/Fedora/smbprint)61
-rwxr-xr-x[-rw-r--r--]packaging/Caldera/OpenLinux/smbusers (renamed from packaging/Fedora/smbusers)0
-rwxr-xr-xpackaging/Caldera/OpenLinux/winbind.daemon5
-rwxr-xr-xpackaging/Caldera/OpenLinux/winbind.init132
-rwxr-xr-xpackaging/Caldera/OpenServer/Clean22
-rwxr-xr-xpackaging/Caldera/OpenServer/Compile57
-rwxr-xr-xpackaging/Caldera/OpenServer/Configure102
-rwxr-xr-xpackaging/Caldera/OpenServer/Install195
-rwxr-xr-xpackaging/Caldera/OpenServer/Makevol10
-rwxr-xr-xpackaging/Caldera/OpenServer/Package13
-rwxr-xr-xpackaging/Caldera/OpenServer/README29
-rwxr-xr-xpackaging/Caldera/OpenServer/callogo.gifbin0 -> 1945 bytes
-rwxr-xr-xpackaging/Caldera/OpenServer/copyrights50
-rwxr-xr-xpackaging/Caldera/OpenServer/docview.html103
-rwxr-xr-xpackaging/Caldera/OpenServer/example.block.smb.conf5
-rwxr-xr-xpackaging/Caldera/OpenServer/findsmb145
-rwxr-xr-xpackaging/Caldera/OpenServer/initconfig254
-rwxr-xr-xpackaging/Caldera/OpenServer/lmhosts1
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/findsmb.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/make_smbcodepage.1198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/make_unicodemap.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/nmblookup.1198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/rpcclient.1396
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbcacls.1264
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbclient.11056
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbcontrol.1198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbsh.1198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbstatus.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/smbtar.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/testparm.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/testprns.1132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.1/wbinfo.1198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.5/lmhosts.5132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.5/smb.conf.59108
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.5/smbpasswd.5198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.7/samba.7198
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/nmbd.8330
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/smbd.8396
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/smbmnt.8132
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/smbmount.8264
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/smbpasswd.8462
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/smbumount.866
-rwxr-xr-xpackaging/Caldera/OpenServer/man/cat.8/swat.8264
-rwxr-xr-xpackaging/Caldera/OpenServer/osr5config.html59
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/Clean3
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/Install1
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/MakeSSO25
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/Packem15
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/Remove16
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cdmt.config36
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cntl/ccs33
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cntl/cqs111
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cntl/packages/Samba/ccs85
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cntl/packages/SambaDOC/ccs46
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/cntl/packages/SambaSWAT/ccs32
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/input/Samba.cmpnt29
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/input/Samba.pkg502
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/input/Samba.prd5
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/input/SambaDOC.pkg1370
-rwxr-xr-xpackaging/Caldera/OpenServer/pkg/input/SambaSWAT.pkg363
-rwxr-xr-xpackaging/Caldera/OpenServer/samba.desktop4
-rwxr-xr-xpackaging/Caldera/OpenServer/samba.directory3
-rwxr-xr-xpackaging/Caldera/OpenServer/samba_configure.desktop5
-rwxr-xr-xpackaging/Caldera/OpenServer/samba_help.desktop4
-rwxr-xr-xpackaging/Caldera/OpenServer/samba_using.desktop5
-rwxr-xr-xpackaging/Caldera/OpenServer/sco_logo_med.gifbin0 -> 5535 bytes
-rwxr-xr-xpackaging/Caldera/OpenServer/smb.conf294
-rwxr-xr-xpackaging/Caldera/OpenServer/smb.init71
-rwxr-xr-xpackaging/Caldera/OpenServer/smb.mkdev49
-rwxr-xr-xpackaging/Caldera/OpenServer/smbadduser73
-rwxr-xr-xpackaging/Caldera/OpenServer/smbprint77
-rwxr-xr-xpackaging/Caldera/OpenServer/smbusers3
-rwxr-xr-xpackaging/Caldera/OpenServer/swat.readme40
-rwxr-xr-xpackaging/Caldera/UnixWare/Clean22
-rwxr-xr-xpackaging/Caldera/UnixWare/Compile70
-rwxr-xr-xpackaging/Caldera/UnixWare/Configure83
-rwxr-xr-xpackaging/Caldera/UnixWare/Install145
-rwxr-xr-xpackaging/Caldera/UnixWare/Makepkg10
-rwxr-xr-xpackaging/Caldera/UnixWare/Package40
-rwxr-xr-xpackaging/Caldera/UnixWare/README54
-rwxr-xr-xpackaging/Caldera/UnixWare/findsmb145
-rwxr-xr-xpackaging/Caldera/UnixWare/pkg/admin1
-rwxr-xr-xpackaging/Caldera/UnixWare/pkg/pkginfo9
-rwxr-xr-xpackaging/Caldera/UnixWare/pkg/postinstall56
-rwxr-xr-xpackaging/Caldera/UnixWare/pkg/postremove30
-rwxr-xr-xpackaging/Caldera/UnixWare/pkg/prototype303
-rwxr-xr-xpackaging/Caldera/UnixWare/samba-2.2-uw7-prototype.patch11
-rwxr-xr-xpackaging/Caldera/UnixWare/samba-2.2-uw7.patch200
-rwxr-xr-xpackaging/Caldera/UnixWare/smb.conf291
-rwxr-xr-xpackaging/Caldera/UnixWare/smb.init76
-rwxr-xr-x[-rw-r--r--]packaging/Caldera/UnixWare/smbadduser (renamed from source/smbadduser.in)18
-rwxr-xr-xpackaging/Caldera/UnixWare/smbprint77
-rwxr-xr-xpackaging/Caldera/UnixWare/smbusers3
-rw-r--r--packaging/Debian/README47
-rw-r--r--packaging/Debian/debian/README.build-upstream47
-rw-r--r--packaging/Debian/debian/README.debian70
-rw-r--r--packaging/Debian/debian/TODO10
-rw-r--r--packaging/Debian/debian/changelog487
-rw-r--r--packaging/Debian/debian/config.cache10
-rw-r--r--packaging/Debian/debian/control53
-rw-r--r--packaging/Debian/debian/gdbcommands2
-rw-r--r--packaging/Debian/debian/libsmbclient-dev.examples1
-rw-r--r--packaging/Debian/debian/libsmbclient-dev.files1
-rwxr-xr-xpackaging/Debian/debian/libsmbclient.postinst11
-rw-r--r--packaging/Debian/debian/libsmbclient.shlibs2
-rw-r--r--packaging/Debian/debian/panic-action48
-rwxr-xr-xpackaging/Debian/debian/patches/Makefile.in.patch17
-rw-r--r--packaging/Debian/debian/patches/VERSION.patch8
-rwxr-xr-xpackaging/Debian/debian/patches/configure.patch32
-rw-r--r--packaging/Debian/debian/patches/documentation.patch68
-rw-r--r--packaging/Debian/debian/patches/fhs.patch605
-rw-r--r--packaging/Debian/debian/patches/installswat.sh.patch76
-rwxr-xr-xpackaging/Debian/debian/patches/loadparm.patch78
-rwxr-xr-xpackaging/Debian/debian/patches/lpq_parse.c.patch12
-rw-r--r--packaging/Debian/debian/patches/nmbd-signalling.patch20
-rw-r--r--packaging/Debian/debian/patches/samba.patch151
-rwxr-xr-xpackaging/Debian/debian/patches/smbadduser.patch22
-rw-r--r--packaging/Debian/debian/patches/smbclient-pager.patch7
-rw-r--r--packaging/Debian/debian/patches/smbclient-tar.patch.unused43
-rwxr-xr-xpackaging/Debian/debian/patches/smbclient-xfer-speed.patch17
-rw-r--r--packaging/Debian/debian/patches/smbmount-nomtab.patch28
-rw-r--r--packaging/Debian/debian/patches/smbstatus-locking.patch20
-rwxr-xr-xpackaging/Debian/debian/patches/smbtar-exclude.patch12
-rw-r--r--packaging/Debian/debian/po/POTFILES.in3
-rw-r--r--packaging/Debian/debian/po/es.po298
-rw-r--r--packaging/Debian/debian/po/fr.po301
-rw-r--r--packaging/Debian/debian/po/nl.po302
-rw-r--r--packaging/Debian/debian/po/pt_BR.po308
-rw-r--r--packaging/Debian/debian/po/templates.pot233
-rw-r--r--packaging/Debian/debian/python2.3-samba.files1
-rwxr-xr-xpackaging/Debian/debian/rules126
-rwxr-xr-xpackaging/Debian/debian/samba-common.conffiles1
-rw-r--r--packaging/Debian/debian/samba-common.config109
-rw-r--r--packaging/Debian/debian/samba-common.dhcp34
-rw-r--r--packaging/Debian/debian/samba-common.dirs1
-rw-r--r--packaging/Debian/debian/samba-common.files15
-rw-r--r--packaging/Debian/debian/samba-common.postinst100
-rw-r--r--packaging/Debian/debian/samba-common.templates72
-rwxr-xr-xpackaging/Debian/debian/samba-common.templates.es46
-rwxr-xr-xpackaging/Debian/debian/samba-common.templates.fr47
-rwxr-xr-xpackaging/Debian/debian/samba-common.templates.pt_BR47
-rw-r--r--packaging/Debian/debian/samba-doc.docs2
-rw-r--r--packaging/Debian/debian/samba-doc.examples3
-rwxr-xr-xpackaging/Debian/debian/samba.conffiles3
-rw-r--r--packaging/Debian/debian/samba.config62
-rw-r--r--packaging/Debian/debian/samba.dirs9
-rw-r--r--packaging/Debian/debian/samba.docs2
-rw-r--r--packaging/Debian/debian/samba.files19
-rw-r--r--packaging/Debian/debian/samba.init64
-rw-r--r--packaging/Debian/debian/samba.logrotate4
-rw-r--r--packaging/Debian/debian/samba.pamd8
-rw-r--r--packaging/Debian/debian/samba.postinst99
-rw-r--r--packaging/Debian/debian/samba.postrm16
-rwxr-xr-xpackaging/Debian/debian/samba.preinst50
-rw-r--r--packaging/Debian/debian/samba.prerm24
-rw-r--r--packaging/Debian/debian/samba.templates69
-rwxr-xr-xpackaging/Debian/debian/samba.templates.es56
-rwxr-xr-xpackaging/Debian/debian/samba.templates.fr57
-rwxr-xr-xpackaging/Debian/debian/samba.templates.pt_BR57
-rwxr-xr-xpackaging/Debian/debian/scripts/patch-source21
-rwxr-xr-xpackaging/Debian/debian/scripts/unpatch-source10
-rw-r--r--packaging/Debian/debian/smb.conf171
-rw-r--r--packaging/Debian/debian/smbclient.files6
-rw-r--r--packaging/Debian/debian/swat.config11
-rwxr-xr-xpackaging/Debian/debian/swat.docs1
-rw-r--r--packaging/Debian/debian/swat.templates6
-rwxr-xr-xpackaging/Debian/debian/winbind.conffiles2
-rw-r--r--packaging/Debian/debian/winbind.dirs1
-rw-r--r--packaging/Debian/debian/winbind.files2
-rw-r--r--packaging/Debian/debian/winbind.lintian6
-rw-r--r--packaging/Debian/debian/winbind.logrotate2
-rwxr-xr-xpackaging/Digital/Instructions55
-rwxr-xr-xpackaging/Digital/PackageDate1
-rwxr-xr-xpackaging/Digital/Packager2
-rwxr-xr-xpackaging/Digital/Packaging-instructions14
-rwxr-xr-xpackaging/Digital/package-prep30
-rwxr-xr-xpackaging/Digital/samba.init34
-rwxr-xr-xpackaging/Digital/setup.sh24
-rwxr-xr-xpackaging/Digital/skeleton.tarbin0 -> 30720 bytes
-rwxr-xr-xpackaging/Example/samba.init7
-rwxr-xr-xpackaging/Fedora/filter-requires-samba.sh3
-rw-r--r--packaging/Fedora/makerpms.sh.tmpl68
-rw-r--r--packaging/Fedora/samba.log9
-rw-r--r--packaging/Fedora/samba.pamd4
-rw-r--r--packaging/Fedora/samba.spec.tmpl398
-rw-r--r--packaging/Fedora/samba.sysconfig6
-rw-r--r--packaging/Fedora/samba.xinetd15
-rw-r--r--packaging/Fedora/smb.init119
-rw-r--r--packaging/Fedora/swat.desktop8
-rw-r--r--packaging/Fedora/winbind.init102
-rwxr-xr-xpackaging/HPUX/Instructions49
-rwxr-xr-xpackaging/HPUX/Packaging-instructions75
-rwxr-xr-xpackaging/HPUX/configure.bin44
-rwxr-xr-xpackaging/HPUX/configure.man12
-rwxr-xr-xpackaging/HPUX/configure.swat61
-rwxr-xr-xpackaging/HPUX/configure.winbind9
-rwxr-xr-xpackaging/HPUX/create_package.sh21
-rwxr-xr-xpackaging/HPUX/create_package_with_winbind.sh21
-rwxr-xr-xpackaging/HPUX/gen_psf.sh357
-rwxr-xr-xpackaging/HPUX/gen_psf_with_winbind.sh380
-rwxr-xr-xpackaging/HPUX/samba.boot72
-rwxr-xr-xpackaging/HPUX/samba.config2
-rwxr-xr-xpackaging/HPUX/unconfigure.bin8
-rwxr-xr-xpackaging/HPUX/unconfigure.swat29
-rwxr-xr-xpackaging/HPUX/unconfigure.winbind8
-rwxr-xr-xpackaging/HPUX/vendor_description2
-rw-r--r--packaging/LSB/lsb-samba.spec7
-rwxr-xr-xpackaging/LSB/samba.sh3
-rwxr-xr-xpackaging/Mandrake/findsmb4
-rw-r--r--packaging/Mandrake/makerpms-cvs.sh13
-rw-r--r--packaging/Mandrake/makerpms.sh.tmpl4
-rwxr-xr-xpackaging/Mandrake/mount.smb34
-rw-r--r--packaging/Mandrake/samba-2.2.0-buildroot.patch15
-rwxr-xr-xpackaging/Mandrake/samba-2.2.0-buildroot.patch.bz2bin0 -> 314 bytes
-rwxr-xr-xpackaging/Mandrake/samba-2.2.0-gawk.patch.bz2bin0 -> 295 bytes
-rwxr-xr-xpackaging/Mandrake/samba-2.2.5-gp-reloc-fix.patch12
-rwxr-xr-xpackaging/Mandrake/samba-2.2.7a-smbldaptools-paths.patch139
-rw-r--r--packaging/Mandrake/samba-3.0-smbmount-sbin.patch11
-rw-r--r--packaging/Mandrake/samba-print-pdf.sh82
-rw-r--r--packaging/Mandrake/samba.pamd1
-rw-r--r--packaging/Mandrake/samba2.spec.tmpl2432
-rw-r--r--packaging/Mandrake/smb.conf123
-rwxr-xr-xpackaging/Mandrake/smb.init2
-rwxr-xr-xpackaging/Mandrake/smbmount-sbin.patch.bz2bin0 -> 367 bytes
-rwxr-xr-xpackaging/Mandrake/smbprint2
-rwxr-xr-xpackaging/Mandrake/smbw.patch.bz2bin0 -> 278 bytes
-rw-r--r--packaging/Mandrake/swat_16.png.bz2bin1142 -> 0 bytes
-rwxr-xr-xpackaging/Mandrake/swat_16.xpm.bz2bin0 -> 1003 bytes
-rw-r--r--packaging/Mandrake/swat_32.png.bz2bin2870 -> 0 bytes
-rwxr-xr-xpackaging/Mandrake/swat_32.xpm.bz2bin0 -> 2727 bytes
-rw-r--r--packaging/Mandrake/swat_48.png.bz2bin5072 -> 0 bytes
-rwxr-xr-xpackaging/Mandrake/swat_48.xpm.bz2bin0 -> 3051 bytes
-rwxr-xr-xpackaging/Mandrake/system-auth14
-rw-r--r--packaging/Mandrake/winbind.init4
-rw-r--r--packaging/Mandrake/wrepld.init93
-rwxr-xr-xpackaging/PHT/TurboLinux/README11
-rwxr-xr-xpackaging/PHT/TurboLinux/findsmb145
-rwxr-xr-xpackaging/PHT/TurboLinux/makerpms.sh.tmpl14
-rwxr-xr-xpackaging/PHT/TurboLinux/samba.log11
-rwxr-xr-xpackaging/PHT/TurboLinux/samba.pamd11
-rwxr-xr-xpackaging/PHT/TurboLinux/samba2.spec.tmpl513
-rwxr-xr-x[-rw-r--r--]packaging/PHT/TurboLinux/smb.conf (renamed from packaging/Fedora/smb.conf)17
-rwxr-xr-xpackaging/PHT/TurboLinux/smb.init52
-rwxr-xr-xpackaging/PHT/TurboLinux/smbadduser73
-rwxr-xr-xpackaging/PHT/TurboLinux/smbprint77
-rwxr-xr-xpackaging/PHT/TurboLinux/smbusers3
-rwxr-xr-x[-rw-r--r--]packaging/PHT/TurboLinux/smbw.patch (renamed from packaging/Mandrake/smbw.patch)0
-rw-r--r--packaging/README18
-rwxr-xr-xpackaging/README.UnixWare6
-rw-r--r--packaging/RedHat/README12
-rwxr-xr-xpackaging/RedHat/filter-requires-samba_rh8.sh2
-rwxr-xr-xpackaging/RedHat/filter-requires-samba_rh9.sh2
-rw-r--r--packaging/RedHat/makerpms.sh.tmpl73
-rw-r--r--packaging/RedHat/samba.spec.tmpl457
-rw-r--r--packaging/RedHat/samba.xinetd2
-rwxr-xr-xpackaging/RedHat/samba2-devel.spec.tmpl547
-rwxr-xr-xpackaging/RedHat/samba2.spec.tmpl587
-rw-r--r--packaging/RedHat/smb.conf6
-rwxr-xr-xpackaging/RedHat/smb.init2
-rwxr-xr-xpackaging/RedHat/smbprint2
-rw-r--r--packaging/RedHat/winbind.init15
-rwxr-xr-xpackaging/SGI/idb.pl171
-rwxr-xr-xpackaging/SGI/mkrelease.sh10
-rw-r--r--packaging/SGI/samba.rc38
-rwxr-xr-xpackaging/SGI/spec.pl21
-rw-r--r--packaging/Solaris/copyright3
-rwxr-xr-xpackaging/Solaris/makepkg.sh (renamed from packaging/Solaris/makepkg.sh.tmpl)108
-rw-r--r--packaging/Solaris/pkg-specs/pkginfo12
-rw-r--r--packaging/Solaris/pkginfo.master2
-rw-r--r--packaging/Solaris/prototype.master18
-rwxr-xr-xpackaging/Solaris/samba.server.master2
-rwxr-xr-xpackaging/SuSE/5.2/samba-1.9.18p5.dif234
-rwxr-xr-xpackaging/SuSE/5.2/samba.spec119
-rwxr-xr-xpackaging/SuSE/7.1/samba-2.2.0-alpha0.dif224
-rwxr-xr-xpackaging/SuSE/7.1/samba.pamd3
-rwxr-xr-xpackaging/SuSE/7.1/samba.spec381
-rwxr-xr-xpackaging/SuSE/8.0/lmhosts7
-rwxr-xr-xpackaging/SuSE/8.0/rc.smb130
-rwxr-xr-xpackaging/SuSE/8.0/rc.smbfs48
-rwxr-xr-xpackaging/SuSE/8.0/samba-2.2.3-smbadduser.dif20
-rwxr-xr-xpackaging/SuSE/8.0/samba-2.2.3-smbsh.dif11
-rwxr-xr-xpackaging/SuSE/8.0/samba-2.2.4-pid_path.diff121
-rwxr-xr-xpackaging/SuSE/8.0/samba-2.2.4-vfs_modules.diff95
-rwxr-xr-xpackaging/SuSE/8.0/samba-2.2.4.dif41
-rwxr-xr-xpackaging/SuSE/8.0/samba.pamd3
-rwxr-xr-xpackaging/SuSE/8.0/samba.spec696
-rwxr-xr-xpackaging/SuSE/8.0/smb.conf120
-rwxr-xr-xpackaging/SuSE/8.0/smbpasswd5
-rwxr-xr-xpackaging/SuSE/8.0/smbusers8
-rw-r--r--packaging/SuSE/README18
-rw-r--r--packaging/SuSE/samba-3.0.0.files.tar.bz2bin7266 -> 0 bytes
-rw-r--r--packaging/SuSE/samba-mutual-auth.diff247
-rwxr-xr-xpackaging/SuSE/samba-vscan-0.3.2b.tar.bz2bin69479 -> 0 bytes
-rw-r--r--packaging/SuSE/samba3-3.0.0-Makefiles-heimdal.diff22
-rw-r--r--packaging/SuSE/samba3-3.0.0-heimdal-06.diff14
-rw-r--r--packaging/SuSE/samba3-3.0.0-pdb.diff13
-rw-r--r--packaging/SuSE/samba3-Makefile.diff16
-rw-r--r--packaging/SuSE/samba3-com_err.diff60
-rw-r--r--packaging/SuSE/samba3-net_ads_password.diff58
-rw-r--r--packaging/SuSE/samba3-smbwrapper.diff11
-rw-r--r--packaging/SuSE/samba3-vscan.diff269
-rw-r--r--packaging/SuSE/samba3.spec766
-rwxr-xr-xpackaging/bin/update-pkginfo14
-rw-r--r--pcp/Makefile7
-rw-r--r--pcp/README13
-rw-r--r--source/.dmallocrc2
-rwxr-xr-xsource/.indent.pro14
-rw-r--r--source/Makefile.in1569
-rw-r--r--source/VERSION81
-rwxr-xr-xsource/acconfig.h227
-rw-r--r--source/aclocal.m4674
-rw-r--r--source/aparser/parser.c10
-rw-r--r--source/aparser/parser.h4
-rwxr-xr-xsource/architecture.doc134
-rw-r--r--source/auth/auth.c534
-rw-r--r--source/auth/auth_builtin.c175
-rw-r--r--source/auth/auth_compat.c122
-rw-r--r--source/auth/auth_domain.c424
-rw-r--r--source/auth/auth_ntlmssp.c188
-rw-r--r--source/auth/auth_rhosts.c257
-rw-r--r--source/auth/auth_sam.c344
-rw-r--r--source/auth/auth_server.c417
-rw-r--r--source/auth/auth_unix.c136
-rw-r--r--source/auth/auth_util.c1477
-rw-r--r--source/auth/auth_winbind.c171
-rw-r--r--source/auth/pampass.c55
-rw-r--r--source/auth/pass_check.c374
-rwxr-xr-xsource/autogen.sh65
-rw-r--r--source/change-log1878
-rw-r--r--source/client/client.c2227
-rw-r--r--source/client/clitar.c2712
-rwxr-xr-xsource/client/mount.cifs.c916
-rw-r--r--source/client/smbmnt.c16
-rw-r--r--source/client/smbmount.c219
-rw-r--r--source/client/smbspool.c123
-rw-r--r--source/client/smbumount.c144
-rw-r--r--source/client/tree.c811
-rwxr-xr-xsource/codepages/CP1125.TXT263
-rwxr-xr-xsource/codepages/CP1251.TXT274
-rwxr-xr-xsource/codepages/CP437.TXT274
-rwxr-xr-xsource/codepages/CP737.TXT274
-rwxr-xr-xsource/codepages/CP775.TXT273
-rwxr-xr-xsource/codepages/CP850.TXT274
-rwxr-xr-xsource/codepages/CP852.TXT274
-rwxr-xr-xsource/codepages/CP857.TXT273
-rwxr-xr-xsource/codepages/CP861.TXT275
-rwxr-xr-xsource/codepages/CP862.TXT270
-rwxr-xr-xsource/codepages/CP866.TXT275
-rwxr-xr-xsource/codepages/CP932.TXT9881
-rwxr-xr-xsource/codepages/CP936.TXT22065
-rwxr-xr-xsource/codepages/CP949.TXT17320
-rwxr-xr-xsource/codepages/CP950.TXT13776
-rwxr-xr-xsource/codepages/CPISO8859-1.TXT230
-rwxr-xr-xsource/codepages/CPISO8859-13.TXT229
-rwxr-xr-xsource/codepages/CPISO8859-15.TXT229
-rwxr-xr-xsource/codepages/CPISO8859-2.TXT230
-rwxr-xr-xsource/codepages/CPISO8859-5.TXT230
-rwxr-xr-xsource/codepages/CPISO8859-7.TXT224
-rwxr-xr-xsource/codepages/CPISO8859-8.TXT240
-rwxr-xr-xsource/codepages/CPISO8859-9.TXT222
-rwxr-xr-xsource/codepages/CPKOI8-R.TXT302
-rwxr-xr-xsource/codepages/CPKOI8-U.TXT262
-rwxr-xr-xsource/codepages/UnicodeData-Latest.txt10617
-rwxr-xr-xsource/codepages/codepage_def.1125168
-rwxr-xr-xsource/codepages/codepage_def.125156
-rwxr-xr-xsource/codepages/codepage_def.43770
-rwxr-xr-xsource/codepages/codepage_def.73758
-rwxr-xr-xsource/codepages/codepage_def.775117
-rwxr-xr-xsource/codepages/codepage_def.85054
-rwxr-xr-xsource/codepages/codepage_def.85264
-rwxr-xr-xsource/codepages/codepage_def.85755
-rwxr-xr-xsource/codepages/codepage_def.861135
-rwxr-xr-xsource/codepages/codepage_def.86252
-rwxr-xr-xsource/codepages/codepage_def.866168
-rwxr-xr-xsource/codepages/codepage_def.932 (renamed from source/po/genmsg)33
-rwxr-xr-xsource/codepages/codepage_def.93624
-rwxr-xr-xsource/codepages/codepage_def.94924
-rwxr-xr-xsource/codepages/codepage_def.95024
-rw-r--r--source/codepages/lowcase.datbin131072 -> 0 bytes
-rw-r--r--source/codepages/upcase.datbin131072 -> 0 bytes
-rw-r--r--source/codepages/valid.datbin65536 -> 0 bytes
-rwxr-xr-xsource/config.guess337
-rwxr-xr-xsource/configure.developer4
-rw-r--r--source/configure.in2948
-rwxr-xr-xsource/configure.nodebug.developer3
-rw-r--r--source/dynconfig.c72
-rwxr-xr-xsource/groupdb/aliasdb.c388
-rwxr-xr-xsource/groupdb/aliasfile.c289
-rwxr-xr-xsource/groupdb/groupdb.c384
-rwxr-xr-xsource/groupdb/groupfile.c285
-rw-r--r--source/groupdb/mapping.c1438
-rw-r--r--source/include/MacExtensions.h5
-rw-r--r--source/include/ads.h226
-rw-r--r--source/include/adt_tree.h38
-rw-r--r--source/include/asn_1.h69
-rw-r--r--source/include/auth.h152
-rw-r--r--source/include/authdata.h152
-rw-r--r--source/include/byteorder.h2
-rw-r--r--source/include/charset.h168
-rw-r--r--source/include/client.h51
-rw-r--r--source/include/clitar.h3
-rw-r--r--source/include/debug.h104
-rw-r--r--source/include/dlinklist.h3
-rw-r--r--source/include/doserr.h65
-rw-r--r--source/include/dynconfig.h38
-rw-r--r--source/include/fake_file.h50
-rw-r--r--source/include/genparser.h78
-rw-r--r--source/include/genparser_samba.h63
-rw-r--r--source/include/gums.h272
-rw-r--r--source/include/hash.h7
-rw-r--r--source/include/hmacmd5.h32
-rw-r--r--source/include/idmap.h57
-rw-r--r--source/include/includes.h407
-rw-r--r--source/include/intl.h25
-rwxr-xr-xsource/include/kanji.h745
-rw-r--r--source/include/libsmb_internal.h67
-rw-r--r--source/include/libsmbclient.h1202
-rw-r--r--source/include/local.h56
-rw-r--r--source/include/mangle.h2
-rw-r--r--source/include/mapping.h25
-rw-r--r--source/include/md5.h24
-rw-r--r--source/include/messages.h35
-rw-r--r--source/include/modconf.h34
-rw-r--r--source/include/module.h38
-rw-r--r--source/include/msdfs.h17
-rw-r--r--source/include/nameserv.h424
-rw-r--r--source/include/nt_printing.h167
-rw-r--r--source/include/nt_status.h63
-rw-r--r--source/include/ntdomain.h165
-rw-r--r--source/include/nterr.h12
-rw-r--r--source/include/ntioctl.h63
-rw-r--r--source/include/ntlmssp.h169
-rw-r--r--source/include/ntquotas.h97
-rw-r--r--source/include/passdb.h586
-rw-r--r--source/include/popt_common.h49
-rw-r--r--source/include/printing.h24
-rw-r--r--source/include/privileges.h100
-rwxr-xr-x[-rw-r--r--]source/include/profile.h (renamed from source/include/smbprofile.h)21
-rwxr-xr-xsource/include/rap.h1
-rw-r--r--source/include/rpc_brs.h3
-rw-r--r--source/include/rpc_client.h3
-rwxr-xr-xsource/include/rpc_client_proto.h232
-rw-r--r--source/include/rpc_creds.h3
-rw-r--r--source/include/rpc_dce.h120
-rw-r--r--source/include/rpc_dfs.h3
-rw-r--r--source/include/rpc_ds.h171
-rw-r--r--source/include/rpc_echo.h75
-rw-r--r--source/include/rpc_epmapper.h118
-rw-r--r--source/include/rpc_lsa.h152
-rw-r--r--source/include/rpc_misc.h203
-rw-r--r--source/include/rpc_netlogon.h222
-rw-r--r--source/include/rpc_parse.h3
-rw-r--r--source/include/rpc_reg.h177
-rw-r--r--source/include/rpc_samr.h104
-rw-r--r--source/include/rpc_secdes.h369
-rw-r--r--source/include/rpc_shutdown.h70
-rwxr-xr-xsource/include/rpc_spoolss.h169
-rw-r--r--source/include/rpc_srvsvc.h209
-rw-r--r--source/include/rpc_wkssvc.h3
-rw-r--r--source/include/safe_string.h182
-rw-r--r--source/include/samba_linux_quota.h176
-rw-r--r--source/include/samba_xfs_quota.h165
-rw-r--r--source/include/secrets.h66
-rw-r--r--source/include/session.h40
-rwxr-xr-x[-rw-r--r--]source/include/sids.h (renamed from source/include/pstring.h)30
-rw-r--r--source/include/smb.h723
-rw-r--r--source/include/smb_acls.h8
-rw-r--r--source/include/smb_macros.h101
-rw-r--r--source/include/smbldap.h164
-rw-r--r--source/include/spnego.h65
-rw-r--r--source/include/srvstr.h33
-rw-r--r--source/include/sysquotas.h76
-rw-r--r--source/include/talloc.h23
-rw-r--r--source/include/tdbsam2_parse_info.h2
-rw-r--r--source/include/trans2.h19
-rwxr-xr-xsource/include/unicode_map_table1.h9450
-rwxr-xr-xsource/include/unicode_map_table2.h1280
-rw-r--r--source/include/util_getent.h3
-rw-r--r--source/include/vfs.h506
-rw-r--r--source/include/vfs_macros.h318
-rwxr-xr-xsource/include/vt_mode.h48
-rw-r--r--source/include/xfile.h49
-rwxr-xr-xsource/internals.doc212
-rw-r--r--source/intl/lang_tdb.c269
-rw-r--r--source/intl/linux-msg.sed100
-rw-r--r--source/lib/access.c237
-rw-r--r--source/lib/account_pol.c162
-rw-r--r--source/lib/adt_tree.c464
-rw-r--r--source/lib/afs.c262
-rw-r--r--source/lib/afs_settoken.c233
-rw-r--r--source/lib/bitmap.c46
-rw-r--r--source/lib/charcnv.c1710
-rwxr-xr-xsource/lib/charset.c398
-rw-r--r--source/lib/clobber.c60
-rw-r--r--source/lib/crc32.c7
-rw-r--r--source/lib/data_blob.c115
-rw-r--r--source/lib/debug.c462
-rw-r--r--source/lib/dmallocmsg.c72
-rwxr-xr-xsource/lib/domain_namemap.c1300
-rw-r--r--source/lib/dprintf.c113
-rw-r--r--source/lib/dummyroot.c33
-rw-r--r--source/lib/dummysmbd.c29
-rwxr-xr-xsource/lib/error.c76
-rw-r--r--source/lib/fault.c14
-rw-r--r--source/lib/fsusage.c3
-rw-r--r--source/lib/gencache.c379
-rw-r--r--source/lib/genparser.c783
-rw-r--r--source/lib/genparser_samba.c218
-rw-r--r--source/lib/genrand.c20
-rw-r--r--source/lib/getsmbpass.c151
-rw-r--r--source/lib/hash.c28
-rw-r--r--source/lib/hmacmd5.c134
-rw-r--r--source/lib/iconv.c591
-rw-r--r--source/lib/interface.c76
-rw-r--r--source/lib/interfaces.c4
-rwxr-xr-xsource/lib/kanji.c1722
-rw-r--r--source/lib/ldap_escape.c90
-rw-r--r--source/lib/md4.c9
-rw-r--r--source/lib/md5.c247
-rw-r--r--source/lib/messages.c354
-rw-r--r--source/lib/module.c304
-rw-r--r--source/lib/ms_fnmatch.c163
-rwxr-xr-xsource/lib/netatalk.c157
-rw-r--r--source/lib/pam_errors.c9
-rw-r--r--source/lib/pidfile.c6
-rw-r--r--source/lib/popt_common.c394
-rw-r--r--source/lib/privileges.c403
-rw-r--r--source/lib/readline.c132
-rw-r--r--source/lib/replace.c48
-rw-r--r--source/lib/replace1.c42
-rw-r--r--source/lib/secace.c285
-rw-r--r--source/lib/secacl.c118
-rw-r--r--source/lib/secdesc.c522
-rw-r--r--source/lib/sendfile.c4
-rw-r--r--source/lib/server_mutex.c56
-rw-r--r--source/lib/signal.c13
-rw-r--r--source/lib/smbldap.c1232
-rw-r--r--source/lib/smbldap_util.c203
-rw-r--r--source/lib/smbrun.c5
-rw-r--r--source/lib/snprintf.c146
-rw-r--r--source/lib/sock_exec.c115
-rw-r--r--source/lib/substitute.c602
-rw-r--r--source/lib/sysacls.c37
-rw-r--r--source/lib/sysquotas.c505
-rw-r--r--source/lib/sysquotas_4A.c339
-rw-r--r--source/lib/sysquotas_linux.c560
-rw-r--r--source/lib/sysquotas_xfs.c333
-rw-r--r--source/lib/system.c480
-rw-r--r--source/lib/system_smbd.c141
-rw-r--r--source/lib/talloc.c77
-rw-r--r--source/lib/tallocmsg.c58
-rw-r--r--source/lib/talloctort.c65
-rw-r--r--source/lib/time.c90
-rw-r--r--source/lib/username.c508
-rw-r--r--source/lib/util.c2022
-rw-r--r--source/lib/util_file.c148
-rw-r--r--source/lib/util_getent.c108
-rw-r--r--source/lib/util_pw.c89
-rw-r--r--source/lib/util_seaccess.c172
-rw-r--r--source/lib/util_sec.c26
-rw-r--r--source/lib/util_sid.c690
-rw-r--r--source/lib/util_smbd.c65
-rw-r--r--source/lib/util_sock.c866
-rw-r--r--source/lib/util_str.c2527
-rw-r--r--source/lib/util_unistr.c2279
-rw-r--r--source/lib/util_uuid.c174
-rw-r--r--source/lib/version.c42
-rw-r--r--source/lib/wins_srv.c585
-rw-r--r--source/lib/xfile.c378
-rw-r--r--source/libads/ads_ldap.c234
-rw-r--r--source/libads/ads_status.c142
-rw-r--r--source/libads/ads_struct.c143
-rw-r--r--source/libads/ads_utils.c137
-rw-r--r--source/libads/authdata.c617
-rw-r--r--source/libads/disp_sec.c159
-rw-r--r--source/libads/kerberos.c175
-rw-r--r--source/libads/kerberos_verify.c271
-rw-r--r--source/libads/krb5_setpw.c690
-rw-r--r--source/libads/ldap.c2135
-rw-r--r--source/libads/ldap_printer.c354
-rw-r--r--source/libads/ldap_user.c119
-rw-r--r--source/libads/ldap_utils.c108
-rw-r--r--source/libads/sasl.c438
-rw-r--r--source/libads/util.c62
-rw-r--r--source/libsmb/asn1.c441
-rwxr-xr-x[-rw-r--r--]source/libsmb/cli_dfs.c (renamed from source/rpc_client/cli_dfs.c)20
-rwxr-xr-x[-rw-r--r--]source/libsmb/cli_lsarpc.c (renamed from source/rpc_client/cli_lsarpc.c)442
-rwxr-xr-xsource/libsmb/cli_netlogon.c691
-rwxr-xr-xsource/libsmb/cli_pipe_util.c80
-rwxr-xr-x[-rw-r--r--]source/libsmb/cli_reg.c (renamed from source/rpc_client/cli_reg.c)14
-rwxr-xr-x[-rw-r--r--]source/libsmb/cli_samr.c (renamed from source/rpc_client/cli_samr.c)1061
-rwxr-xr-x[-rw-r--r--]source/libsmb/cli_spoolss.c (renamed from source/rpc_client/cli_spoolss.c)1482
-rwxr-xr-xsource/libsmb/cli_srvsvc.c79
-rw-r--r--source/libsmb/cliconnect.c1231
-rw-r--r--source/libsmb/clidgram.c14
-rw-r--r--source/libsmb/clientgen.c217
-rw-r--r--source/libsmb/clierror.c196
-rw-r--r--source/libsmb/clifile.c468
-rw-r--r--source/libsmb/clifsinfo.c76
-rw-r--r--source/libsmb/clikrb5.c468
-rw-r--r--source/libsmb/clilist.c129
-rw-r--r--source/libsmb/climessage.c63
-rw-r--r--source/libsmb/clioplock.c3
-rw-r--r--source/libsmb/cliprint.c20
-rw-r--r--source/libsmb/cliquota.c633
-rw-r--r--source/libsmb/clirap.c175
-rw-r--r--source/libsmb/clirap2.c1970
-rw-r--r--source/libsmb/clireadwrite.c106
-rw-r--r--source/libsmb/clisecdesc.c17
-rw-r--r--source/libsmb/clispnego.c387
-rw-r--r--source/libsmb/clistr.c168
-rw-r--r--source/libsmb/clitrans.c140
-rw-r--r--source/libsmb/conncache.c158
-rw-r--r--source/libsmb/credentials.c9
-rw-r--r--source/libsmb/doserr.c3
-rw-r--r--source/libsmb/errormap.c76
-rw-r--r--source/libsmb/libsmb_cache.c196
-rw-r--r--source/libsmb/libsmb_compat.c434
-rw-r--r--source/libsmb/libsmbclient.c3807
-rw-r--r--source/libsmb/namecache.c404
-rw-r--r--source/libsmb/namequery.c1332
-rw-r--r--source/libsmb/namequery_dc.c185
-rw-r--r--source/libsmb/nmblib.c1740
-rw-r--r--source/libsmb/nterr.c176
-rw-r--r--source/libsmb/ntlm_check.c457
-rw-r--r--source/libsmb/ntlmssp.c1115
-rw-r--r--source/libsmb/ntlmssp_parse.c315
-rw-r--r--source/libsmb/ntlmssp_sign.c407
-rw-r--r--source/libsmb/passchange.c96
-rw-r--r--source/libsmb/pwd_cache.c213
-rw-r--r--source/libsmb/samlogon_cache.c238
-rw-r--r--source/libsmb/smb_signing.c1051
-rw-r--r--source/libsmb/smbdes.c58
-rw-r--r--source/libsmb/smbencrypt.c528
-rw-r--r--source/libsmb/smberr.c9
-rw-r--r--source/libsmb/spnego.c343
-rw-r--r--source/libsmb/trustdom_cache.c342
-rw-r--r--source/libsmb/trusts_util.c190
-rw-r--r--source/libsmb/unexpected.c5
-rw-r--r--source/locking/brlock.c13
-rw-r--r--source/locking/locking.c128
-rw-r--r--source/locking/posix.c54
-rw-r--r--source/mainpage.dox7
-rw-r--r--source/modules/CP437.c136
-rw-r--r--source/modules/CP850.c122
-rw-r--r--source/modules/charset_macosxfs.c602
-rw-r--r--source/modules/developer.c132
-rw-r--r--source/modules/getdate.c2460
-rw-r--r--source/modules/getdate.h46
-rw-r--r--source/modules/getdate.y1115
-rw-r--r--source/modules/vfs_audit.c280
-rw-r--r--source/modules/vfs_cap.c448
-rw-r--r--source/modules/vfs_default_quota.c180
-rw-r--r--source/modules/vfs_expand_msdfs.c191
-rw-r--r--source/modules/vfs_extd_audit.c343
-rw-r--r--source/modules/vfs_fake_perms.c81
-rw-r--r--source/modules/vfs_netatalk.c401
-rw-r--r--source/modules/vfs_readonly.c98
-rw-r--r--source/modules/vfs_recycle.c498
-rw-r--r--source/modules/vfs_shadow_copy.c227
-rw-r--r--source/modules/weird.c131
-rwxr-xr-xsource/msdfs/README32
-rwxr-xr-x[-rw-r--r--]source/msdfs/msdfs.c (renamed from source/smbd/msdfs.c)521
-rw-r--r--source/nmbd/asyncdns.c86
-rw-r--r--source/nmbd/nmbd.c1186
-rw-r--r--source/nmbd/nmbd_become_dmb.c535
-rw-r--r--source/nmbd/nmbd_become_lmb.c694
-rw-r--r--source/nmbd/nmbd_browserdb.c148
-rw-r--r--source/nmbd/nmbd_browsesync.c858
-rw-r--r--source/nmbd/nmbd_elections.c536
-rw-r--r--source/nmbd/nmbd_incomingdgrams.c1094
-rw-r--r--source/nmbd/nmbd_incomingrequests.c946
-rw-r--r--source/nmbd/nmbd_lmhosts.c94
-rw-r--r--source/nmbd/nmbd_logonnames.c201
-rw-r--r--source/nmbd/nmbd_mynames.c283
-rw-r--r--source/nmbd/nmbd_namelistdb.c808
-rw-r--r--source/nmbd/nmbd_namequery.c417
-rw-r--r--source/nmbd/nmbd_nameregister.c803
-rw-r--r--source/nmbd/nmbd_namerelease.c364
-rw-r--r--source/nmbd/nmbd_nodestatus.c71
-rw-r--r--source/nmbd/nmbd_packets.c2815
-rw-r--r--source/nmbd/nmbd_processlogon.c736
-rw-r--r--source/nmbd/nmbd_responserecordsdb.c333
-rw-r--r--source/nmbd/nmbd_sendannounce.c784
-rw-r--r--source/nmbd/nmbd_serverlistdb.c544
-rw-r--r--source/nmbd/nmbd_subnetdb.c437
-rw-r--r--source/nmbd/nmbd_synclists.c67
-rw-r--r--source/nmbd/nmbd_winsproxy.c263
-rw-r--r--source/nmbd/nmbd_winsserver.c2938
-rw-r--r--source/nmbd/nmbd_workgroupdb.c378
-rwxr-xr-xsource/nsswitch/README13
-rwxr-xr-x[-rw-r--r--]source/nsswitch/hp_nss_common.h (renamed from source/nsswitch/winbind_nss_irix.h)71
-rwxr-xr-x[-rw-r--r--]source/nsswitch/hp_nss_dbdefs.h (renamed from source/nsswitch/winbind_nss_hpux.h)42
-rw-r--r--source/nsswitch/pam_winbind.c147
-rw-r--r--source/nsswitch/pam_winbind.h8
-rwxr-xr-xsource/nsswitch/sys_nss.h104
-rw-r--r--source/nsswitch/wb_client.c415
-rw-r--r--source/nsswitch/wb_common.c211
-rw-r--r--source/nsswitch/wbinfo.c845
-rw-r--r--source/nsswitch/winbind_client.h16
-rwxr-xr-x[-rw-r--r--]source/nsswitch/winbind_nss.c (renamed from source/nsswitch/winbind_nss_linux.c)836
-rw-r--r--source/nsswitch/winbind_nss.h71
-rw-r--r--source/nsswitch/winbind_nss_aix.c1019
-rw-r--r--source/nsswitch/winbind_nss_config.h35
-rw-r--r--source/nsswitch/winbind_nss_freebsd.c81
-rw-r--r--source/nsswitch/winbind_nss_irix.c515
-rw-r--r--source/nsswitch/winbind_nss_linux.h35
-rw-r--r--source/nsswitch/winbind_nss_solaris.c31
-rw-r--r--source/nsswitch/winbind_nss_solaris.h61
-rw-r--r--source/nsswitch/winbindd.c435
-rw-r--r--source/nsswitch/winbindd.h90
-rw-r--r--source/nsswitch/winbindd_acct.c1223
-rw-r--r--source/nsswitch/winbindd_ads.c1018
-rw-r--r--source/nsswitch/winbindd_cache.c802
-rw-r--r--source/nsswitch/winbindd_cm.c904
-rw-r--r--source/nsswitch/winbindd_dual.c214
-rw-r--r--source/nsswitch/winbindd_group.c703
-rwxr-xr-xsource/nsswitch/winbindd_idmap.c526
-rw-r--r--source/nsswitch/winbindd_misc.c129
-rw-r--r--source/nsswitch/winbindd_nss.h106
-rw-r--r--source/nsswitch/winbindd_pam.c627
-rw-r--r--source/nsswitch/winbindd_passdb.c339
-rw-r--r--source/nsswitch/winbindd_rpc.c579
-rw-r--r--source/nsswitch/winbindd_sid.c354
-rw-r--r--source/nsswitch/winbindd_user.c275
-rw-r--r--source/nsswitch/winbindd_util.c779
-rw-r--r--source/nsswitch/winbindd_wins.c76
-rw-r--r--source/nsswitch/wins.c202
-rw-r--r--source/pam_smbpass/README8
-rw-r--r--source/pam_smbpass/general.h12
-rw-r--r--source/pam_smbpass/pam_smb_acct.c15
-rw-r--r--source/pam_smbpass/pam_smb_auth.c31
-rw-r--r--source/pam_smbpass/pam_smb_passwd.c179
-rw-r--r--source/pam_smbpass/support.c282
-rw-r--r--source/pam_smbpass/support.h6
-rw-r--r--source/param/config_ldap.c351
-rw-r--r--source/param/loadparm.c3264
-rw-r--r--source/param/modconf.c96
-rw-r--r--source/param/params.c57
-rwxr-xr-xsource/parsing.doc363
-rw-r--r--source/passdb/login_cache.c176
-rw-r--r--source/passdb/lookup_sid.c529
-rw-r--r--source/passdb/machine_sid.c153
-rwxr-xr-xsource/passdb/pampass.c892
-rwxr-xr-xsource/passdb/pass_check.c865
-rw-r--r--source/passdb/passdb.c2954
-rwxr-xr-xsource/passdb/passgrp.c218
-rw-r--r--source/passdb/pdb_compat.c104
-rw-r--r--source/passdb/pdb_get_set.c1257
-rw-r--r--source/passdb/pdb_guest.c179
-rw-r--r--source/passdb/pdb_gums.c464
-rw-r--r--source/passdb/pdb_interface.c1722
-rw-r--r--source/passdb/pdb_ldap.c3792
-rw-r--r--source/passdb/pdb_mysql.c497
-rwxr-xr-xsource/passdb/pdb_nisplus.c1374
-rw-r--r--source/passdb/pdb_pgsql.c488
-rw-r--r--source/passdb/pdb_plugin.c80
-rw-r--r--source/passdb/pdb_smbpasswd.c743
-rw-r--r--source/passdb/pdb_sql.c493
-rw-r--r--source/passdb/pdb_tdb.c1961
-rw-r--r--source/passdb/pdb_xml.c563
-rw-r--r--source/passdb/privileges.c341
-rw-r--r--source/passdb/secrets.c693
-rwxr-xr-xsource/passdb/smbpassfile.c295
-rw-r--r--source/passdb/util_sam_sid.c340
-rw-r--r--source/po/de.msg593
-rw-r--r--source/po/en.msg593
-rw-r--r--source/po/fr.msg593
-rw-r--r--source/po/it.msg593
-rw-r--r--source/po/ja.msg595
-rw-r--r--source/po/nl.msg593
-rw-r--r--source/po/pl.msg593
-rw-r--r--source/po/tr.msg594
-rw-r--r--source/printing/load.c11
-rw-r--r--source/printing/lpq_parse.c203
-rw-r--r--source/printing/notify.c555
-rw-r--r--source/printing/nt_printing.c2351
-rw-r--r--source/printing/pcap.c75
-rw-r--r--source/printing/print_cups.c36
-rw-r--r--source/printing/print_generic.c35
-rw-r--r--source/printing/print_svid.c15
-rw-r--r--source/printing/printfsp.c35
-rw-r--r--source/printing/printing.c1902
-rw-r--r--source/printing/printing_db.c206
-rw-r--r--source/profile/profile.c18
-rw-r--r--source/python/README28
-rwxr-xr-xsource/python/examples/spoolss/changeid.py34
-rwxr-xr-xsource/python/examples/spoolss/enumprinters.py36
-rwxr-xr-xsource/python/examples/spoolss/psec.py88
-rw-r--r--source/python/examples/tdbpack/oldtdbutil.py144
-rwxr-xr-xsource/python/examples/tdbpack/tdbtimetrial.py12
-rwxr-xr-xsource/python/examples/tdbpack/test_tdbpack.py253
-rwxr-xr-xsource/python/gprinterdata39
-rwxr-xr-xsource/python/gtdbtool39
-rwxr-xr-xsource/python/gtkdictbrowser.py272
-rw-r--r--source/python/py_common.c259
-rw-r--r--source/python/py_common.h67
-rw-r--r--source/python/py_conv.c223
-rw-r--r--source/python/py_conv.h44
-rw-r--r--source/python/py_lsa.c484
-rw-r--r--source/python/py_lsa.h41
-rw-r--r--source/python/py_ntsec.c288
-rw-r--r--source/python/py_samr.c676
-rw-r--r--source/python/py_samr.h86
-rw-r--r--source/python/py_samr_conv.c131
-rw-r--r--source/python/py_smb.c442
-rw-r--r--source/python/py_smb.h39
-rw-r--r--source/python/py_spoolss.c485
-rw-r--r--source/python/py_spoolss.h160
-rw-r--r--source/python/py_spoolss_common.c35
-rw-r--r--source/python/py_spoolss_drivers.c422
-rw-r--r--source/python/py_spoolss_drivers_conv.c179
-rw-r--r--source/python/py_spoolss_forms.c266
-rw-r--r--source/python/py_spoolss_forms_conv.c91
-rw-r--r--source/python/py_spoolss_jobs.c377
-rw-r--r--source/python/py_spoolss_jobs_conv.c102
-rw-r--r--source/python/py_spoolss_ports.c137
-rw-r--r--source/python/py_spoolss_ports_conv.c58
-rw-r--r--source/python/py_spoolss_printerdata.c450
-rw-r--r--source/python/py_spoolss_printers.c475
-rw-r--r--source/python/py_spoolss_printers_conv.c354
-rw-r--r--source/python/py_srvsvc.c215
-rw-r--r--source/python/py_srvsvc.h30
-rw-r--r--source/python/py_srvsvc_conv.c41
-rw-r--r--source/python/py_tdb.c698
-rw-r--r--source/python/py_tdb.h30
-rw-r--r--source/python/py_tdbpack.c721
-rw-r--r--source/python/py_winbind.c800
-rw-r--r--source/python/py_winbind.h30
-rw-r--r--source/python/py_winbind_conv.c41
-rw-r--r--source/python/py_winreg.c82
-rw-r--r--source/python/samba/__init__.py7
-rw-r--r--source/python/samba/printerdata.py65
-rwxr-xr-xsource/python/setup.py200
-rw-r--r--source/registry/reg_cachehook.c112
-rw-r--r--source/registry/reg_db.c311
-rw-r--r--source/registry/reg_frontend.c260
-rw-r--r--source/registry/reg_objects.c374
-rw-r--r--source/registry/reg_printing.c826
-rw-r--r--source/rpc_client/cli_ds.c157
-rw-r--r--source/rpc_client/cli_echo.c187
-rw-r--r--source/rpc_client/cli_epmapper.c61
-rwxr-xr-xsource/rpc_client/cli_login.c206
-rw-r--r--source/rpc_client/cli_netlogon.c1167
-rw-r--r--source/rpc_client/cli_pipe.c1326
-rw-r--r--source/rpc_client/cli_shutdown.c104
-rw-r--r--source/rpc_client/cli_spoolss_notify.c494
-rw-r--r--source/rpc_client/cli_srvsvc.c442
-rwxr-xr-xsource/rpc_client/cli_trust.c250
-rw-r--r--source/rpc_client/cli_wkssvc.c93
-rw-r--r--source/rpc_parse/parse_dfs.c35
-rw-r--r--source/rpc_parse/parse_ds.c302
-rw-r--r--source/rpc_parse/parse_echo.c166
-rw-r--r--source/rpc_parse/parse_epmapper.c482
-rw-r--r--source/rpc_parse/parse_lsa.c537
-rw-r--r--source/rpc_parse/parse_misc.c377
-rw-r--r--source/rpc_parse/parse_net.c913
-rw-r--r--source/rpc_parse/parse_prs.c457
-rw-r--r--source/rpc_parse/parse_reg.c354
-rw-r--r--source/rpc_parse/parse_rpc.c266
-rw-r--r--source/rpc_parse/parse_samr.c947
-rw-r--r--source/rpc_parse/parse_sec.c512
-rw-r--r--source/rpc_parse/parse_shutdown.c163
-rw-r--r--source/rpc_parse/parse_spoolss.c912
-rw-r--r--source/rpc_parse/parse_srv.c1009
-rw-r--r--source/rpc_parse/parse_wks.c10
-rw-r--r--source/rpc_server/srv_dfs.c46
-rw-r--r--source/rpc_server/srv_dfs_nt.c566
-rw-r--r--source/rpc_server/srv_echo.c150
-rw-r--r--source/rpc_server/srv_echo_nt.c78
-rw-r--r--source/rpc_server/srv_epmapper.c88
-rw-r--r--source/rpc_server/srv_epmapper_nt.c70
-rw-r--r--source/rpc_server/srv_lsa.c278
-rw-r--r--source/rpc_server/srv_lsa_ds.c93
-rw-r--r--source/rpc_server/srv_lsa_ds_nt.c127
-rw-r--r--source/rpc_server/srv_lsa_hnd.c46
-rw-r--r--source/rpc_server/srv_lsa_nt.c956
-rw-r--r--source/rpc_server/srv_netlog.c86
-rw-r--r--source/rpc_server/srv_netlog_nt.c714
-rw-r--r--source/rpc_server/srv_pipe.c868
-rw-r--r--source/rpc_server/srv_pipe_hnd.c358
-rw-r--r--source/rpc_server/srv_reg.c242
-rw-r--r--source/rpc_server/srv_reg_nt.c659
-rw-r--r--source/rpc_server/srv_samr.c491
-rw-r--r--source/rpc_server/srv_samr_nt.c3409
-rw-r--r--source/rpc_server/srv_samr_util.c554
-rwxr-xr-xsource/rpc_server/srv_spoolss.c216
-rw-r--r--source/rpc_server/srv_spoolss_nt.c3886
-rw-r--r--source/rpc_server/srv_srvsvc.c92
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c734
-rw-r--r--source/rpc_server/srv_util.c436
-rw-r--r--source/rpc_server/srv_wkssvc.c29
-rw-r--r--source/rpc_server/srv_wkssvc_nt.c14
-rw-r--r--source/rpcclient/cmd_dfs.c40
-rw-r--r--source/rpcclient/cmd_ds.c79
-rw-r--r--source/rpcclient/cmd_echo.c159
-rw-r--r--source/rpcclient/cmd_epmapper.c76
-rw-r--r--source/rpcclient/cmd_lsarpc.c381
-rw-r--r--source/rpcclient/cmd_netlogon.c175
-rw-r--r--source/rpcclient/cmd_reg.c66
-rw-r--r--source/rpcclient/cmd_samr.c799
-rw-r--r--source/rpcclient/cmd_shutdown.c112
-rw-r--r--source/rpcclient/cmd_spoolss.c1214
-rw-r--r--source/rpcclient/cmd_srvsvc.c154
-rw-r--r--source/rpcclient/cmd_wkssvc.c4
-rwxr-xr-xsource/rpcclient/display.c1339
-rw-r--r--source/rpcclient/display_sec.c5
-rwxr-xr-xsource/rpcclient/display_spool.c927
-rw-r--r--source/rpcclient/rpcclient.c722
-rw-r--r--source/rpcclient/rpcclient.h17
-rwxr-xr-xsource/rpcclient/samsync.c364
-rw-r--r--source/sam/account.c305
-rw-r--r--source/sam/group.c193
-rw-r--r--source/sam/gums.c173
-rw-r--r--source/sam/gums_api.c1426
-rw-r--r--source/sam/gums_helper.c383
-rw-r--r--source/sam/gums_tdbsam2.c1220
-rw-r--r--source/sam/idmap.c317
-rw-r--r--source/sam/idmap_ldap.c790
-rw-r--r--source/sam/idmap_tdb.c676
-rw-r--r--source/sam/idmap_util.c295
-rw-r--r--source/sam/interface.c1338
-rwxr-xr-xsource/script/build_env.sh41
-rwxr-xr-xsource/script/convert_smbpasswd17
-rwxr-xr-xsource/script/creategroup27
-rwxr-xr-xsource/script/findsmb.in234
-rwxr-xr-xsource/script/findstatic.pl70
-rw-r--r--source/script/gap.awk39
-rw-r--r--source/script/gaptab.awk48
-rw-r--r--source/script/gen-8bit-gap.awk18
-rwxr-xr-xsource/script/gen-8bit-gap.sh.in49
-rwxr-xr-xsource/script/genstruct.pl299
-rwxr-xr-xsource/script/installbin.sh26
-rwxr-xr-xsource/script/installcp.sh44
-rwxr-xr-xsource/script/installdat.sh23
-rwxr-xr-xsource/script/installdirs.sh19
-rwxr-xr-xsource/script/installman.sh84
-rwxr-xr-xsource/script/installmodules.sh27
-rw-r--r--source/script/installmsg.sh23
-rwxr-xr-xsource/script/installscripts.sh2
-rwxr-xr-xsource/script/installswat.sh111
-rwxr-xr-xsource/script/linkmodules.sh12
-rwxr-xr-xsource/script/makeyodldocs.sh92
-rw-r--r--source/script/mkbuildoptions.awk262
-rwxr-xr-xsource/script/mkinstalldirs38
-rw-r--r--source/script/mkproto.awk50
-rwxr-xr-xsource/script/mkproto.sh4
-rwxr-xr-xsource/script/mksmbpasswd.sh2
-rwxr-xr-xsource/script/mkversion.sh82
-rwxr-xr-xsource/script/smbadduser76
-rw-r--r--source/script/smbtar2
-rwxr-xr-xsource/script/uninstallbin.sh12
-rwxr-xr-xsource/script/uninstallcp.sh33
-rwxr-xr-xsource/script/uninstallman.sh30
-rwxr-xr-xsource/script/uninstallmodules.sh37
-rwxr-xr-xsource/script/uninstallscripts.sh2
-rwxr-xr-xsource/script/updatesmbpasswd.sh14
-rw-r--r--source/smbd/blocking.c524
-rw-r--r--source/smbd/change_trust_pw.c99
-rw-r--r--source/smbd/chgpasswd.c696
-rw-r--r--source/smbd/close.c123
-rw-r--r--source/smbd/conn.c116
-rw-r--r--source/smbd/connection.c112
-rw-r--r--source/smbd/dfree.c30
-rw-r--r--source/smbd/dir.c1001
-rw-r--r--source/smbd/dosmode.c505
-rw-r--r--source/smbd/error.c21
-rw-r--r--source/smbd/fake_file.c166
-rw-r--r--source/smbd/fileio.c110
-rw-r--r--source/smbd/filename.c122
-rw-r--r--source/smbd/files.c37
-rwxr-xr-xsource/smbd/groupname.c240
-rw-r--r--source/smbd/ipc.c97
-rw-r--r--source/smbd/lanman.c1328
-rw-r--r--source/smbd/mangle.c7
-rw-r--r--source/smbd/mangle_hash.c941
-rw-r--r--source/smbd/mangle_hash2.c136
-rw-r--r--source/smbd/mangle_map.c4
-rw-r--r--source/smbd/message.c68
-rw-r--r--source/smbd/negprot.c685
-rw-r--r--source/smbd/noquotas.c3
-rw-r--r--source/smbd/notify.c12
-rw-r--r--source/smbd/notify_hash.c15
-rw-r--r--source/smbd/notify_kernel.c22
-rw-r--r--source/smbd/ntquotas.c262
-rw-r--r--source/smbd/nttrans.c1894
-rw-r--r--source/smbd/open.c374
-rw-r--r--source/smbd/oplock.c27
-rw-r--r--source/smbd/oplock_irix.c3
-rw-r--r--source/smbd/oplock_linux.c15
-rw-r--r--source/smbd/password.c1757
-rw-r--r--source/smbd/pipes.c35
-rw-r--r--source/smbd/posix_acls.c1159
-rw-r--r--source/smbd/process.c1183
-rw-r--r--source/smbd/quotas.c231
-rw-r--r--source/smbd/reply.c4224
-rw-r--r--source/smbd/sec_ctx.c81
-rw-r--r--source/smbd/server.c589
-rw-r--r--source/smbd/service.c803
-rw-r--r--source/smbd/session.c224
-rw-r--r--source/smbd/sesssetup.c934
-rw-r--r--source/smbd/srvstr.c44
-rwxr-xr-xsource/smbd/ssl.c287
-rw-r--r--source/smbd/statcache.c446
-rw-r--r--source/smbd/tdbutil.c85
-rw-r--r--source/smbd/trans2.c2518
-rw-r--r--source/smbd/uid.c736
-rw-r--r--source/smbd/utmp.c96
-rw-r--r--source/smbd/vfs-wrap.c624
-rw-r--r--source/smbd/vfs.c613
-rwxr-xr-x[-rw-r--r--]source/smbwrapper/init.c (renamed from source/python/py_winreg.h)14
-rw-r--r--source/smbwrapper/realcalls.c3
-rw-r--r--source/smbwrapper/realcalls.h3
-rw-r--r--source/smbwrapper/shared.c40
-rw-r--r--source/smbwrapper/smbsh.c33
-rw-r--r--source/smbwrapper/smbw.c50
-rw-r--r--source/smbwrapper/smbw.h3
-rw-r--r--source/smbwrapper/smbw_cache.c207
-rw-r--r--source/smbwrapper/smbw_dir.c63
-rw-r--r--source/smbwrapper/smbw_stat.c15
-rw-r--r--source/smbwrapper/wrapped.c10
-rw-r--r--source/stf/README.stf3
-rw-r--r--source/stf/comfychair.py445
-rwxr-xr-xsource/stf/example.py38
-rwxr-xr-xsource/stf/info3cache.py54
-rw-r--r--source/stf/notes.txt175
-rwxr-xr-xsource/stf/osver.py55
-rwxr-xr-xsource/stf/pythoncheck.py48
-rw-r--r--source/stf/sambalib.py41
-rwxr-xr-xsource/stf/smbcontrol.py238
-rwxr-xr-xsource/stf/spoolss.py288
-rw-r--r--source/stf/standardcheck.py34
-rwxr-xr-xsource/stf/stf.py101
-rwxr-xr-xsource/stf/strings.py151
-rwxr-xr-xsource/stf/test.py33
-rw-r--r--source/stf/unicodenames.py33
-rw-r--r--source/tdb/Makefile2
-rw-r--r--source/tdb/README3
-rw-r--r--source/tdb/spinlock.c75
-rw-r--r--source/tdb/spinlock.h6
-rw-r--r--source/tdb/tdb.c198
-rw-r--r--source/tdb/tdb.h35
-rw-r--r--source/tdb/tdb.magic10
-rw-r--r--source/tdb/tdbback.c211
-rw-r--r--source/tdb/tdbback.h23
-rw-r--r--source/tdb/tdbbackup.c182
-rw-r--r--source/tdb/tdbdump.c1
-rw-r--r--source/tdb/tdbtool.c110
-rw-r--r--source/tdb/tdbtorture.c11
-rw-r--r--source/tdb/tdbutil.c500
-rw-r--r--source/tdb/tdbutil.h38
-rw-r--r--source/tests/shlib.c6
-rw-r--r--source/tests/sysquotas.c94
-rw-r--r--source/tests/unixsock.c93
-rw-r--r--source/torture/cmd_vfs.c1060
-rw-r--r--source/torture/denytest.c1577
-rw-r--r--source/torture/mangle_test.c213
-rw-r--r--source/torture/nbio.c318
-rw-r--r--source/torture/nsstest.c451
-rw-r--r--source/torture/samtest.h38
-rw-r--r--source/torture/scanner.c430
-rw-r--r--source/torture/smbiconv.c243
-rw-r--r--source/torture/t_doschar.c42
-rw-r--r--source/torture/t_push_ucs2.c54
-rw-r--r--source/torture/t_strcmp.c32
-rw-r--r--source/torture/t_stringoverflow.c23
-rw-r--r--source/torture/t_strstr.c35
-rw-r--r--source/torture/torture.c4994
-rw-r--r--source/torture/utable.c193
-rw-r--r--source/torture/vfstest.c571
-rw-r--r--source/torture/vfstest.h45
-rw-r--r--source/utils/editreg.c4145
-rwxr-xr-x[-rw-r--r--]source/utils/locktest.c (renamed from source/torture/locktest.c)291
-rwxr-xr-x[-rw-r--r--]source/utils/locktest2.c (renamed from source/torture/locktest2.c)105
-rw-r--r--source/utils/log2pcaphex.c294
-rwxr-xr-xsource/utils/make_printerdef.c591
-rwxr-xr-xsource/utils/make_smbcodepage.c476
-rwxr-xr-xsource/utils/make_unicodemap.c313
-rwxr-xr-x[-rw-r--r--]source/utils/masktest.c (renamed from source/torture/masktest.c)113
-rwxr-xr-x[-rw-r--r--]source/utils/msgtest.c (renamed from source/torture/msgtest.c)13
-rwxr-xr-xsource/utils/nbio.c240
-rw-r--r--source/utils/net.c797
-rw-r--r--source/utils/net.h70
-rw-r--r--source/utils/net_ads.c1328
-rw-r--r--source/utils/net_ads_cldap.c364
-rw-r--r--source/utils/net_cache.c348
-rw-r--r--source/utils/net_groupmap.c767
-rw-r--r--source/utils/net_help.c220
-rw-r--r--source/utils/net_idmap.c264
-rw-r--r--source/utils/net_lookup.c258
-rw-r--r--source/utils/net_privileges.c380
-rw-r--r--source/utils/net_rap.c1054
-rw-r--r--source/utils/net_rpc.c3589
-rw-r--r--source/utils/net_rpc_join.c389
-rw-r--r--source/utils/net_rpc_samsync.c1080
-rw-r--r--source/utils/net_status.c257
-rw-r--r--source/utils/net_time.c180
-rw-r--r--source/utils/nmblookup.c263
-rwxr-xr-xsource/utils/nsstest.c302
-rw-r--r--source/utils/ntlm_auth.c2246
-rw-r--r--source/utils/pdbedit.c1640
-rw-r--r--source/utils/profiles.c742
-rw-r--r--source/utils/rpccheck.c10
-rwxr-xr-x[-rw-r--r--]source/utils/rpctorture.c (renamed from source/torture/rpctorture.c)40
-rw-r--r--source/utils/smbcacls.c365
-rw-r--r--source/utils/smbcontrol.c965
-rw-r--r--source/utils/smbcquotas.c546
-rw-r--r--source/utils/smbfilter.c62
-rw-r--r--source/utils/smbget.c589
-rw-r--r--source/utils/smbpasswd.c977
-rw-r--r--source/utils/smbtree.c237
-rw-r--r--source/utils/smbw_sample.c37
-rw-r--r--source/utils/status.c1017
-rw-r--r--source/utils/testparm.c406
-rw-r--r--source/utils/testprns.c16
-rwxr-xr-xsource/utils/torture.c4975
-rw-r--r--source/web/cgi.c332
-rw-r--r--source/web/diagnose.c22
-rw-r--r--source/web/neg_lang.c117
-rwxr-xr-xsource/web/po/Makefile43
-rwxr-xr-xsource/web/po/ja.po336
-rwxr-xr-xsource/web/po/swatlang.h13
-rw-r--r--source/web/startstop.c57
-rw-r--r--source/web/statuspage.c230
-rw-r--r--source/web/swat.c951
-rw-r--r--source/wrepld/parser.c759
-rw-r--r--source/wrepld/partners.c200
-rw-r--r--source/wrepld/process.c983
-rw-r--r--source/wrepld/server.c666
-rw-r--r--source/wrepld/socket.c69
-rw-r--r--source/wrepld/wins_repl.h161
-rwxr-xr-xswat/README82
-rw-r--r--swat/help/welcome.html39
-rw-r--r--swat/images/globals.gifbin2004 -> 628 bytes
-rw-r--r--swat/images/home.gifbin2044 -> 580 bytes
-rw-r--r--swat/images/passwd.gifbin1993 -> 613 bytes
-rw-r--r--swat/images/printers.gifbin2077 -> 705 bytes
-rw-r--r--swat/images/shares.gifbin2006 -> 569 bytes
-rw-r--r--swat/images/status.gifbin2080 -> 578 bytes
-rw-r--r--swat/images/viewconfig.gifbin1939 -> 820 bytes
-rw-r--r--swat/images/wizard.gifbin2554 -> 853 bytes
-rw-r--r--swat/lang/ja/help/welcome.html69
-rw-r--r--swat/lang/ja/include/footer.html3
-rw-r--r--swat/lang/ja/include/header.html12
-rw-r--r--swat/lang/ja/include/header.nocss.html11
-rw-r--r--swat/lang/ja/include/header_css.html1
-rw-r--r--swat/lang/tr/help/welcome.html69
-rw-r--r--swat/lang/tr/images/globals.gifbin442 -> 0 bytes
-rw-r--r--swat/lang/tr/images/home.gifbin608 -> 0 bytes
-rw-r--r--swat/lang/tr/images/passwd.gifbin326 -> 0 bytes
-rw-r--r--swat/lang/tr/images/printers.gifbin519 -> 0 bytes
-rw-r--r--swat/lang/tr/images/samba.gifbin3643 -> 0 bytes
-rw-r--r--swat/lang/tr/images/shares.gifbin474 -> 0 bytes
-rw-r--r--swat/lang/tr/images/status.gifbin431 -> 0 bytes
-rw-r--r--swat/lang/tr/images/viewconfig.gifbin455 -> 0 bytes
-rw-r--r--swat/lang/tr/include/header.html10
-rw-r--r--testsuite/README7
-rwxr-xr-xtestsuite/build_farm/backtrace15
-rw-r--r--testsuite/build_farm/basicsmb-domainsec-nt4.test28
-rw-r--r--testsuite/build_farm/basicsmb-domainsec.test20
-rw-r--r--testsuite/build_farm/basicsmb-hostsdeny.test18
-rw-r--r--testsuite/build_farm/basicsmb-hostsequiv.test26
-rw-r--r--testsuite/build_farm/basicsmb-invalidusers.test10
-rw-r--r--testsuite/build_farm/basicsmb-local-pass-change.test10
-rw-r--r--testsuite/build_farm/basicsmb-preexec.test28
-rw-r--r--testsuite/build_farm/basicsmb-remote-pass-change.test10
-rw-r--r--testsuite/build_farm/basicsmb-shareguest.test3
-rw-r--r--testsuite/build_farm/basicsmb-sharelist.test5
-rw-r--r--testsuite/build_farm/basicsmb.fns174
-rwxr-xr-xtestsuite/build_farm/basicsmb.smb.conf.domain2
-rwxr-xr-x[-rw-r--r--]testsuite/build_farm/basicsmb.smb.conf.server (renamed from testsuite/build_farm/template/basicsmb.smb.conf.server)2
-rwxr-xr-x[-rw-r--r--]testsuite/build_farm/basicsmb.smb.conf.share (renamed from testsuite/build_farm/template/basicsmb.smb.conf.share)0
-rwxr-xr-x[-rw-r--r--]testsuite/build_farm/basicsmb.smb.conf.template (renamed from testsuite/build_farm/template/basicsmb.smb.conf)10
-rwxr-xr-x[-rw-r--r--]testsuite/build_farm/basicsmb.smb.conf.user (renamed from testsuite/build_farm/template/basicsmb.smb.conf.user)0
-rw-r--r--testsuite/build_farm/runlist19
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.domain2
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.hostsdeny1
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.hostsequiv3
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.invalidusers1
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.preexec1
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.preexec_cl_fl2
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.preexec_close2
-rw-r--r--testsuite/build_farm/template/basicsmb.smb.conf.validusers1
-rw-r--r--testsuite/build_farm/template/preexec3
-rw-r--r--testsuite/build_farm/torture-DIR1.test2
-rw-r--r--testsuite/build_farm/torture-FDPASS.test2
-rw-r--r--testsuite/build_farm/torture-FDSESS.test2
-rw-r--r--testsuite/build_farm/torture-LOCK6.test2
-rw-r--r--testsuite/build_farm/torture-LOCK7.test2
-rw-r--r--testsuite/build_farm/torture-MANGLE.test2
-rw-r--r--testsuite/build_farm/torture-PROPERTIES.test2
-rw-r--r--testsuite/build_farm/torture-RENAME.test2
-rw-r--r--testsuite/build_farm/torture-RW2.test2
-rw-r--r--testsuite/build_farm/torture-TCON1.test2
-rw-r--r--testsuite/build_farm/torture-TCON2.test2
-rw-r--r--testsuite/build_farm/torture-TCONDEV.test2
-rw-r--r--testsuite/build_farm/torture-XCOPY.test2
-rw-r--r--testsuite/build_farm/torture_setup.fns2
-rwxr-xr-xtestsuite/config/default-nt-names.exp17
-rwxr-xr-xtestsuite/config/env.exp26
-rw-r--r--testsuite/lib/smbclient.exp2
-rw-r--r--testsuite/libsmbclient/src/Makefile817
-rw-r--r--testsuite/libsmbclient/src/chmod/chmod_1.c59
-rw-r--r--testsuite/libsmbclient/src/chown/chown_1.c59
-rw-r--r--testsuite/libsmbclient/src/close/close_1.c59
-rw-r--r--testsuite/libsmbclient/src/close/close_2.c57
-rw-r--r--testsuite/libsmbclient/src/closedir/closedir_1.c65
-rw-r--r--testsuite/libsmbclient/src/closedir/closedir_2.c61
-rw-r--r--testsuite/libsmbclient/src/closedir/closedir_3.c63
-rw-r--r--testsuite/libsmbclient/src/closedir/closedir_4.c59
-rw-r--r--testsuite/libsmbclient/src/creat/creat_1.c60
-rw-r--r--testsuite/libsmbclient/src/creat/creat_2.c63
-rw-r--r--testsuite/libsmbclient/src/creat/creat_3.c56
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_1.c62
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_2.c58
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_3.c69
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_4.c69
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_5.c77
-rw-r--r--testsuite/libsmbclient/src/fstat/fstat_6.c80
-rw-r--r--testsuite/libsmbclient/src/getdents/getdents_1.c72
-rw-r--r--testsuite/libsmbclient/src/getdents/getdents_2.c67
-rw-r--r--testsuite/libsmbclient/src/getdents/getdents_3.c155
-rw-r--r--testsuite/libsmbclient/src/getdents/getdents_4.c101
-rw-r--r--testsuite/libsmbclient/src/getdents/getdents_5.c106
-rw-r--r--testsuite/libsmbclient/src/init/init_1.c18
-rw-r--r--testsuite/libsmbclient/src/init/init_2.c23
-rw-r--r--testsuite/libsmbclient/src/init/init_3.c58
-rw-r--r--testsuite/libsmbclient/src/init/init_4.c18
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_1.c109
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_2.c105
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_3.c103
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_4.c99
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_5.c101
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_6.c110
-rw-r--r--testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_7.c106
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_1.c61
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_2.c57
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_3.c80
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_4.c80
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_5.c80
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_6.c75
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_7.c80
-rw-r--r--testsuite/libsmbclient/src/lseek/lseek_8.c75
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_1.c102
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_2.c95
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_3.c67
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_4.c61
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_5.c119
-rw-r--r--testsuite/libsmbclient/src/lseekdir/lseekdir_6.c124
-rw-r--r--testsuite/libsmbclient/src/mkdir/mkdir_1.c60
-rw-r--r--testsuite/libsmbclient/src/mkdir/mkdir_2.c56
-rw-r--r--testsuite/libsmbclient/src/mkdir/mkdir_3.c58
-rw-r--r--testsuite/libsmbclient/src/mkdir/mkdir_4.c62
-rw-r--r--testsuite/libsmbclient/src/open/open_1.c60
-rw-r--r--testsuite/libsmbclient/src/open/open_2.c56
-rw-r--r--testsuite/libsmbclient/src/open/open_3.c60
-rw-r--r--testsuite/libsmbclient/src/open/open_4.c63
-rw-r--r--testsuite/libsmbclient/src/open/open_5.c58
-rw-r--r--testsuite/libsmbclient/src/open_print_job/open_print_job_1.c60
-rw-r--r--testsuite/libsmbclient/src/open_print_job/open_print_job_2.c56
-rw-r--r--testsuite/libsmbclient/src/opendir/opendir_1.c62
-rw-r--r--testsuite/libsmbclient/src/opendir/opendir_2.c55
-rw-r--r--testsuite/libsmbclient/src/opendir/opendir_3.c65
-rw-r--r--testsuite/libsmbclient/src/opendir/opendir_4.c61
-rw-r--r--testsuite/libsmbclient/src/print_file/print_file_1.c76
-rw-r--r--testsuite/libsmbclient/src/print_file/print_file_2.c72
-rw-r--r--testsuite/libsmbclient/src/print_file/print_file_3.c59
-rw-r--r--testsuite/libsmbclient/src/print_file/print_file_4.c55
-rw-r--r--testsuite/libsmbclient/src/read/read_1.c83
-rw-r--r--testsuite/libsmbclient/src/read/read_10.c68
-rw-r--r--testsuite/libsmbclient/src/read/read_11.c83
-rw-r--r--testsuite/libsmbclient/src/read/read_12.c87
-rw-r--r--testsuite/libsmbclient/src/read/read_13.c91
-rw-r--r--testsuite/libsmbclient/src/read/read_2.c76
-rw-r--r--testsuite/libsmbclient/src/read/read_3.c83
-rw-r--r--testsuite/libsmbclient/src/read/read_4.c77
-rw-r--r--testsuite/libsmbclient/src/read/read_5.c83
-rw-r--r--testsuite/libsmbclient/src/read/read_6.c77
-rw-r--r--testsuite/libsmbclient/src/read/read_7.c60
-rw-r--r--testsuite/libsmbclient/src/read/read_8.c56
-rw-r--r--testsuite/libsmbclient/src/read/read_9.c70
-rw-r--r--testsuite/libsmbclient/src/readdir/readdir_1.c107
-rw-r--r--testsuite/libsmbclient/src/readdir/readdir_2.c102
-rw-r--r--testsuite/libsmbclient/src/readdir/readdir_3.c71
-rw-r--r--testsuite/libsmbclient/src/readdir/readdir_4.c67
-rw-r--r--testsuite/libsmbclient/src/readdir/readdir_5.c155
-rw-r--r--testsuite/libsmbclient/src/rename/rename_1.c57
-rw-r--r--testsuite/libsmbclient/src/rename/rename_10.c64
-rw-r--r--testsuite/libsmbclient/src/rename/rename_11.c63
-rw-r--r--testsuite/libsmbclient/src/rename/rename_12.c58
-rw-r--r--testsuite/libsmbclient/src/rename/rename_13.c63
-rw-r--r--testsuite/libsmbclient/src/rename/rename_14.c58
-rw-r--r--testsuite/libsmbclient/src/rename/rename_2.c54
-rw-r--r--testsuite/libsmbclient/src/rename/rename_3.c56
-rw-r--r--testsuite/libsmbclient/src/rename/rename_4.c55
-rw-r--r--testsuite/libsmbclient/src/rename/rename_5.c59
-rw-r--r--testsuite/libsmbclient/src/rename/rename_6.c57
-rw-r--r--testsuite/libsmbclient/src/rename/rename_7.c66
-rw-r--r--testsuite/libsmbclient/src/rename/rename_8.c68
-rw-r--r--testsuite/libsmbclient/src/rename/rename_9.c68
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_1.c59
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_2.c55
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_3.c61
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_4.c57
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_5.c63
-rw-r--r--testsuite/libsmbclient/src/rmdir/rmdir_6.c59
-rw-r--r--testsuite/libsmbclient/src/stat/stat_1.c62
-rw-r--r--testsuite/libsmbclient/src/stat/stat_2.c58
-rw-r--r--testsuite/libsmbclient/src/stat/stat_3.c66
-rw-r--r--testsuite/libsmbclient/src/stat/stat_4.c62
-rw-r--r--testsuite/libsmbclient/src/stat/stat_5.c77
-rw-r--r--testsuite/libsmbclient/src/stat/stat_6.c80
-rw-r--r--testsuite/libsmbclient/src/telldir/telldir_1.c102
-rw-r--r--testsuite/libsmbclient/src/telldir/telldir_2.c95
-rw-r--r--testsuite/libsmbclient/src/telldir/telldir_3.c67
-rw-r--r--testsuite/libsmbclient/src/telldir/telldir_4.c61
-rw-r--r--testsuite/libsmbclient/src/telldir/telldir_5.c122
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_1.c61
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_10.c62
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_11.c66
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_12.c65
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_2.c61
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_3.c57
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_4.c64
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_5.c62
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_6.c58
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_7.c62
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_8.c55
-rw-r--r--testsuite/libsmbclient/src/unlink/unlink_9.c57
-rw-r--r--testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_1.c107
-rw-r--r--testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_2.c102
-rw-r--r--testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_3.c106
-rw-r--r--testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_4.c101
-rw-r--r--testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_5.c141
-rw-r--r--testsuite/libsmbclient/src/write/write_1.c77
-rw-r--r--testsuite/libsmbclient/src/write/write_10.c70
-rw-r--r--testsuite/libsmbclient/src/write/write_11.c83
-rw-r--r--testsuite/libsmbclient/src/write/write_12.c83
-rw-r--r--testsuite/libsmbclient/src/write/write_13.c87
-rw-r--r--testsuite/libsmbclient/src/write/write_2.c71
-rw-r--r--testsuite/libsmbclient/src/write/write_3.c79
-rw-r--r--testsuite/libsmbclient/src/write/write_4.c74
-rw-r--r--testsuite/libsmbclient/src/write/write_5.c79
-rw-r--r--testsuite/libsmbclient/src/write/write_6.c74
-rw-r--r--testsuite/libsmbclient/src/write/write_7.c60
-rw-r--r--testsuite/libsmbclient/src/write/write_8.c56
-rw-r--r--testsuite/libsmbclient/src/write/write_9.c72
-rw-r--r--testsuite/nsswitch/domusers.exp38
-rw-r--r--testsuite/nsswitch/finger.exp8
-rw-r--r--testsuite/printing/psec.c70
1862 files changed, 366880 insertions, 250282 deletions
diff --git a/Manifest b/Manifest
index 608c7b1be98..70d044cc98f 100644
--- a/Manifest
+++ b/Manifest
@@ -1,4 +1,4 @@
-Copyright (C) 1997-2003 - Samba-Team
+Copyright (C) 1997-2001 - Samba-Team
The Samba package you have just unpacked contains the following:
@@ -8,19 +8,37 @@ Directory Notes:
docs (Samba Documentation):
---- ----------------------
- All the Samba documentation for the 3.0 release have been converted to
- docbook format. Because of this the man pages are now available
- in both traditional man page format (in the docs/manpages directory)
- and in HTML format (in the docs/htmldocs directory).
-
- The Samba HOWTO Collection has undergone some rather large changes
- and covers all parts of configuration now. It is available
- as PDF (docs/Samba-HOWTO-Collection.pdf) or in HTML format (in
- the docs/htmldocs directory). Those with the docbook utilities installed
- can generate PostScript and text versions of the HOWTO as well.
-
- The Samba FAQ is still a work in progress, but can be found in
- HTML format in docs/htmldocs.
+ The Samba documentation for the 2.2 release has had all the man pages
+ converted to DocBook v4.1 source format. Because of this the man pages
+ are now available in both traditional man page format (in
+ the doc/manpages directory) and in HTML format (in the
+ docs/htmldocs directory).
+
+ The text documentation files have been moved into a
+ docs/textdocs directory and are in the (slow) process
+ of being converted to DocBook source format to allow them
+ to be easily converted to HTML.
+
+ Note in particular two files - docs/textdocs/<your OS>_INSTALL.txt
+ and docs/textdocs/DIAGNOSIS.txt.
+
+ There is the potential for there to be many *INSTALL.txt files, one
+ for each OS that Samba supports. However we are moving all this into
+ the new structure. For now, most people will be using
+ htmldocs/UNIX_INSTALL.txt
+
+ Please pay close attention to all the files with a .txt extension
+ in the docs/textdocs directory and the htmldocs/* files. Most problems
+ can be solved by reference to the two files mentioned.
+
+ The FAQ documentation can be accessed starting from Samba-meta-FAQ.html,
+ in the docs/faq directory. This is incomplete, but to quote from the
+ abstract, it:
+
+ "contains overview information for the Samba suite of programs,
+ a quick-start guide, and pointers to all other Samba documentation.
+ Other FAQs exist for specific client and server issues, and HOWTO
+ documents for more extended topics to do with Samba software."
examples (Example configuration files):
@@ -32,15 +50,39 @@ examples (Example configuration files):
Do read the smb.conf manual page in considering what settings are
appropriate for your site.
+ There are lots of interesting examples of how people have been able
+ to implement Samba for their use. Users may also be interested in
+ the VFS (Virtual File System) modules under this directory.
+
+SWAT: The Samba Web Administration Tool
+----- ---------------------------------
+
+ SWAT is a web based tool for configuring and optimising the smb.conf
+ file. To use it, you need to have SWAT enabled in your inetd control
+ file (for more information check the packaging directories for examples
+ of how this can be done). Then you connect to SWAT using your favourite
+ web browser - point it at http://hostname:901, then log on as "root"
+ using the root password. If you log on using a non-root account SWAT
+ will not allow the smb.conf file to be changed.
+
packaging (Only for those wishing to build binary distributions):
--------- -------------------------------------------------------
Currently support is included for the following Linux Distributions :
- Pacfic HiTech, RedHat and SuSE.
+ Caldera, RedHat, SuSE, Mandrake, and TurboLinux.
+
+ Packaging support for TuboLinux is under ~samba/packaging/PHT - the
+ previous name of the company was Pacific HiTech, hence the PHT.
In addition, packaging support is available for SGI and Solaris systems.
+
+ SCO OpenServer and SCO UnixWare have been acquired by Caldera. We expect
+ that Caldera will in future integrate Samba into the above operating
+ systems. UnixWare has been renamed to OpenUnix. Look under the directory
+ ~samba/packaging/Caldera for packaging support for these platforms.
+
We hope that other Unix OS vendors will contribute their binary
distribution packaging control files - and we hope to make their binary
packages available on the master ftp site under:
@@ -54,7 +96,7 @@ source (The official Samba source files - expect more of these!):
To build your own binary files you will need a suitable ansi C
compiler.
- Samba uses the GNU autoconf system. In
+ For Samba 2.2 the GNU autoconf system has been adopted. In
order to build a default Samba for your platform cd into
the source/ directory and then type :
diff --git a/README b/README
index 789413210a6..fe20f671e11 100644
--- a/README
+++ b/README
@@ -1,48 +1,47 @@
-This is a development version of Samba, the free SMB and CIFS client and
-server for UNIX and other operating systems. Samba is maintained by
+This is version 2.2.X of Samba, the free SMB and CIFS client and
+server for unix and other operating systems. Samba is maintained by
the Samba Team, who support the original author, Andrew Tridgell.
>>>> Please read THE WHOLE of this file as it gives important information
>>>> about the configuration and use of Samba.
NOTE: Installation instructions may be found in
- docs/htmldocs/install.html
+ docs/htmldocs/UNIX_INSTALL.html
This software is freely distributable under the GNU public license, a
copy of which you should have received with this software (in a file
called COPYING).
-WHAT IS SMB/CIFS?
-=================
+WHAT IS SMB?
+============
This is a big question.
The very short answer is that it is the protocol by which a lot of
-PC-related machines share files and printers and other information
+PC-related machines share files and printers and other informatiuon
such as lists of available files and printers. Operating systems that
-support this natively include Windows 9x, Windows NT (and derivatives),
-OS/2, Mac OS X and Linux. Add on packages that achieve the same
-thing are available for DOS, Windows 3.1, VMS, Unix of all kinds,
-MVS, and more. Some Web Browsers can speak this protocol as well
-(smb://). Alternatives to SMB include Netware, NFS, Appletalk,
-Banyan Vines, Decnet etc; many of these have advantages but none are
-both public specifications and widely implemented in desktop machines
-by default.
-
-The Common Internet File system (CIFS) is what the new SMB initiative
+support this natively include Windows NT, OS/2, and Linux and add on
+packages that achieve the same thing are available for DOS, Windows,
+VMS, Unix of all kinds, MVS, and more. Apple Macs and some Web Browsers
+can speak this protocol as well. Alternatives to SMB include
+Netware, NFS, Appletalk, Banyan Vines, Decnet etc; many of these have
+advantages but none are both public specifications and widely
+implemented in desktop machines by default.
+
+The Common Internet Filesystem (CIFS) is what the new SMB initiative
is called. For details watch http://samba.org/cifs.
WHY DO PEOPLE WANT TO USE SMB?
==============================
-1. Many people want to integrate their Microsoft desktop clients
- with their Unix servers.
+1. Many people want to integrate their Microsoft or IBM style desktop
+ machines with their Unix or VMS (etc) servers.
2. Others want to integrate their Microsoft (etc) servers with Unix
- servers. This is a different problem to integrating desktop
- clients.
+ or VMS (etc) servers. This is a different problem to integrating
+ desktop clients.
3. Others want to replace protocols like NFS, DecNet and Novell NCP,
especially when used with PCs.
@@ -51,26 +50,18 @@ WHY DO PEOPLE WANT TO USE SMB?
WHAT CAN SAMBA DO?
==================
-Please refer to the WHATSNEW.txt included with this README for
-a list of features in the latest Samba release.
-
-Here is a very short list of what samba includes, and what it does.
-For many networks this can be simply summarized by "Samba provides
-a complete replacement for Windows NT, Warp, NFS or Netware servers."
+Here is a very short list of what samba includes, and what it does. For
+many networks this can be simply summarised by "Samba provides a complete
+replacement for Windows NT, Warp, NFS or Netware servers."
- a SMB server, to provide Windows NT and LAN Manager-style file and print
services to SMB clients such as Windows 95, Warp Server, smbfs and others.
-- a Windows NT 4.0 Domain Controller replacement.
-
-- a file/print server that can act as a member of a Windows NT 4.0
- or Active Directory domain.
-
- a NetBIOS (rfc1001/1002) nameserver, which amongst other things gives
browsing support. Samba can be the master browser on your LAN if you wish.
- a ftp-like SMB client so you can access PC resources (disks and
- printers) from UNIX, Netware, and other operating systems
+printers) from unix, Netware and other operating systems
- a tar extension to the client for backing up PCs
@@ -82,14 +73,16 @@ http://samba.org/samba, and browse the user survey.
Related packages include:
-- smbfs, a Linux-only filesystem allowing you to mount remote SMB
-filesystems from PCs on your Linux box. This is included as standard with
+- smbfs, a linux-only filesystem allowing you to mount remote SMB
+filesystems from PCs on your linux box. This is included as standard with
Linux 2.0 and later.
-- cifsvfs, a more advanced Linux-only filesystem allowing you to mount
-remote SMB filesystems from PCs on your Linux box. This is included
-as standard with Linux 2.5 and later.
+- tcpdump-smb, a extension to tcpdump to allow you to investigate SMB
+networking problems over netbeui and tcp/ip.
+- smblib, a library of smb functions which are designed to make it
+easy to smb-ise any particular application. See
+ftp://samba.org/pub/samba/smblib.
CONTRIBUTIONS
@@ -97,12 +90,11 @@ CONTRIBUTIONS
If you want to contribute to the development of the software then
please join the mailing list. The Samba team accepts patches
-(preferably in "diff -u" format, see http://samba.org/samba/devel/
-for more details) and are always glad to receive feedback or
-suggestions to the address samba@lists.samba.org. More information
-on the various Samba mailing lists can be found at http://lists.samba.org/.
-
-You can also get the Samba sourcecode straight from the CVS tree - see
+(preferably in "diff -u" format, see docs/textdocs/BUGS.txt for more details)
+and are always glad to receive feedback or suggestions to the address
+samba@lists.samba.org. We have recently put a new bug tracking
+system into place which should help the throughput quite a lot. You
+can also get the Samba sourcecode straight from the CVS tree - see
http://samba.org/cvs.html.
You could also send hardware/software/money/jewelry or pre-paid pizza
@@ -115,10 +107,13 @@ If you like a particular feature then look through the CVS change-log
who added it, then send them an email.
Remember that free software of this kind lives or dies by the response
-we get. If no one tells us they like it then we'll probably move onto
+we get. If noone tells us they like it then we'll probably move onto
something else. However, as you can see from the user survey quite a lot of
people do seem to like it at the moment :-)
+Samba Team
+Email: samba@samba.org
+
MORE INFO
=========
@@ -127,16 +122,17 @@ DOCUMENTATION
-------------
There is quite a bit of documentation included with the package,
-including man pages, and lots of .html files with hints and useful
+including man pages, and lots of .txt files with hints and useful
info. This is also available from the web page. There is a growing
-collection of information under docs/.
+collection of information under docs/faq; by the next release expect
+this to be the default starting point.
A list of Samba documentation in languages other than English is
available on the web page.
If you would like to help with the documentation (and we _need_ help!)
then have a look at the mailing list samba-docs, archived at
-http://lists.samba.org/listinfo/samba-docs/
+http://lists.samba.org/
MAILING LIST
@@ -204,12 +200,12 @@ A few tips when submitting to this or any mailing list.
NEWS GROUP
----------
-You might also like to look at the usenet news group comp.protocols.smb
-as it often contains lots of useful info and is frequented by lots of
-Samba users. The newsgroup was initially setup by people on the Samba
-mailing list. It is not, however, exclusive to Samba, it is a forum for
-discussing the SMB protocol (which Samba implements). The samba list
-is gatewayed to this newsgroup.
+You might also like to look at the usenet news group
+comp.protocols.smb as it often contains lots of useful info and is
+frequented by lots of Samba users. The newsgroup was initially setup
+by people on the Samba mailing list. It is not, however, exclusive to
+Samba, it is a forum for discussing the SMB protocol (which Samba
+implements). The samba list is gatewayed to this newsgroup.
WEB SITE
@@ -222,3 +218,4 @@ http://samba.org/samba/
As well as general information and documentation, this also has searchable
archives of the mailing list and a user survey that shows who else is using
this package. Have you registered with the survey yet? :-)
+
diff --git a/Roadmap b/Roadmap
index 42c63f78098..6d886f0d2a9 100644
--- a/Roadmap
+++ b/Roadmap
@@ -1,28 +1,43 @@
-Copyright (C) 1997-2003 Samba-Team
+Copyright (C) 1997-2001 - Samba-Team
The Samba-Team are committed to an aggressive program to deliver quality
controlled software to a well defined roadmap.
-The current Samba Beta series of Samba 3.0.0 is called the "Domain Integration"
-release.
+The current Samba release 2.2 is the Windows 2000 update.
-The following development objectives for future releases
-are in progress:
-----------------------------------------------------------------------------
-Samba-3.0.0 The Domain Integration Release.
+It correctly implements the Windows NT specific SMB calls,
+and will operate correctly as a client in a Windows NT and
+Windows 2000 Domain environment. In addition, preliminary
+support for Windows NT and Windows 2000 Domain Control has
+been implemented, although more remains to be done.
+
+Samba 2.2 can now support share level security changes from
+Windows NT/2000 server manager tools, and can integrate fully
+into a Windows NT/2000 Domain with no local users when using
+winbind (see the white paper on the Samba site).
+
+This is also the first official release supporting the Samba-VFS
+layer, allowing non-disk resources such as databases to be
+exported to Windows clients as disk resources. More work will
+be done on this in the 2.2.x series.
-Samba-3.0.x Improvements in Management and Migration tools, &
- general code stabilization work.
+Windows 2000 is now the base tested client for Samba. All work
+is verified against Windows 2000 clients.
-Samba-3.x.x Requirements are currently under discussion.
+The following development objectives for future releases
+are in place:
+
+----------------------------------------------------------------------------
+2.2.x - Integration with native Windows server management tools,
+ including user account management and share management.
-Samba-4 Danger Will Robinson, a big code clean up with major
- system redesign. More will be announced as this work
- starts to take shape.
+3.0 - "Domain Controller" - able to serve as a Windows NT PDC.
+ Unicode on the wire support.
+X.XX - "Full Domain Integration" - allowing both PDC and BDC modes.
-Note that it is a given that the Samba-Team will continue to track
-Windows (NT/200x) update releases, ensuring that Samba will work
+Note that it is a given that the Samba Team will continue to track
+Windows (2000/XP) update releases, ensuring that Samba will work
well with whatever "Beta" releases Redmond throws our way :-).
You may also note that the release numbers get fuzzier the
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 69036fae3c6..1d542ee28d2 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,1072 +1,1542 @@
- WHATS NEW IN Samba 3.0.0
- September 24, 2003
- ==============================
+ What's new in Samba 2.2.8a - 7th April 2003
+ ===========================================
-This is the first official release of Samba 3.0.0 code base. Work
-on the SAMBA_3_0 CVS branch continues. Please refer to the section
-on "Known Issues" for more details.
+This is the latest stable release of Samba. This is the version that
+all production Samba servers should be running for all current
+bug-fixes.
+ ****************************************
+ * IMPORTANT: Security bugfix for Samba *
+ ****************************************
-Major new features:
--------------------
+Summary
+-------
-1) Active Directory support. Samba 3.0 is now able to
- join a ADS realm as a member server and authenticate
- users using LDAP/Kerberos.
+Digital Defense, Inc. has alerted the Samba Team to a serious
+vulnerability in all stable versions of Samba currently shipping.
+The Common Vulnerabilities and Exposures (CVE) project has assigned
+the ID CAN-2003-0201 to this defect.
-2) Unicode support. Samba will now negotiate UNICODE on the wire
- and internally there is now a much better infrastructure for
- multi-byte and UNICODE character sets.
+This vulnerability, if exploited correctly, leads to an anonymous
+user gaining root access on a Samba serving system. All versions
+of Samba up to and including Samba 2.2.8 are vulnerable. An active
+exploit of the bug has been reported in the wild. Alpha versions of
+Samba 3.0 and above are *NOT* vulnerable.
-3) New authentication system. The internal authentication system
- has been almost completely rewritten. Most of the changes are
- internal, but the new auth system is also very configurable.
-4) New default filename mangling system.
+Credit
+------
-5) A new "net" command has been added. It is somewhat similar to
- the "net" command in windows. Eventually we plan to replace
- numerous other utilities (such as smbpasswd) with subcommands
- in "net".
+The Samba Team would like to thank Erik Parker and the team at
+Digital Defense, Inc. for their efforts spent in the responsible
+and timely reporting of this bug.
-6) Samba now negotiates NT-style status32 codes on the wire. This
- improves error handling a lot.
-7) Better Windows 2000/XP/2003 printing support including publishing
- printer attributes in active directory.
+Patch Availability
+------------------
-8) New loadable module support for passdb backends and character
- sets.
+The Samba 2.2.8a release contains only updates to address this
+security issue. A roll-up patch for release 2.2.7a and 2.0.10
+addressing both CAN-2003-0201 and CAN-2003-0085 can be obtained
+from http://www.samba.org/samba/ftp/patches/security/.
-9) New default dual-daemon winbindd support for better performance.
-10) Support for migrating from a Windows NT 4.0 domain to a Samba
- domain and maintaining user, group and domain SIDs.
+ ========================================
-11) Support for establishing trust relationships with Windows NT 4.0
- domain controllers.
-
-12) Initial support for a distributed Winbind architecture using
- an LDAP directory for storing SID to uid/gid mappings.
-
-13) Major updates to the Samba documentation tree.
-14) Full support for client and server SMB signing to ensure
- compatibility with default Windows 2003 security settings.
+Older releases notes for 2.2.x distributions follow
-15) Improvement of ACL mapping features based on code donated by
- Andreas Grünbacher.
+-----------------------------------------------------------------
+The release notes for 2.2.8 follow:
+ ****************************************
+ * IMPORTANT: Security bugfix for Samba *
+ ****************************************
-Plus lots of other improvements!
+Summary
+-------
+The SuSE security audit team, in particular Sebastian Krahmer
+<krahmer@suse.de>, has found an flaw in the Samba main smbd code which
+could allow an external attacker to remotely and anonymously gain
+Super User (root) privileges on a server running a Samba server.
-Additional Documentation
-------------------------
+This flaw exists in previous versions of Samba from 2.0.x to 2.2.7a
+inclusive. This is serious problem and all sites should either
+upgrade to Samba 2.2.8 immediately or prohibit access to TCP ports 139
+and 445. Advice on how to protect an unpatched Samba server created by
+Andrew Tridgell, the leader of the Samba Team, is given at the end of
+this section.
-Please refer to Samba documentation tree (included in the docs/
-subdirectory) for extensive explanations of installing, configuring
-and maintaining Samba 3.0 servers and clients. It is advised to
-begin with the Samba-HOWTO-Collection for overviews and specific
-tasks (the current book is up to approximately 400 pages) and to
-refer to the various man pages for information on individual options.
-
-We are very glad to be able to include the second edition of
-"Using Samba" by Jay Ts, Robert Eckstein, and David Collier-Brown
-(O'Reilly & Associates) in this release. The book is available
-on-line at http://samba.org/samba/docs/ and is included with
-the Samba Web Administration Tool (SWAT). Thanks to the authors and
-publisher for making "Using Samba" under the GNU Free Documentation
-License.
-
-
-######################################################################
-Changes since 3.0rc4
-####################
-
-Please refer to the CVS log for the SAMBA_3_0 branch for complete
-details:
-
-1) Fix bug that prevented restoring filenames of length
- >100 characters.
-2) Fix bug that prevented fast path code in strchr_m
- from being used.
-3) Make sure we store the desired access flag on incoming
- SAMR rpc calls.
-4) Fix smbd crash when dealing with mangled file names.
-5) Ensure that the group comment field is not overwritten
- if it already exists.
-6) Fix bug that prevented 'net rpc join' from working
- with mixed mode AD domains (bug 442).
-7) Fix crash in smbd when a Samba PDC is not able to
- enumerate trusted domains (bug 450).
-8) Fix crash bug found by the Samba4 testsuite.
-9) Fix bug that prevented smbd from returning an ACL list
- if one of the SIDs could not be resolved (bug 470).
-10) Remove -P option from smbclient printing scripts since it
- has a different meaning in Samba 3.0 (bug 473).
-11) Sync smbldap-tools with latest version
-12) Cleanup some warnings produced by the Sun C compiler.
-13) Several fixes for SWAT relating to international character
- sets.
-
-
-Changes since 3.0rc3
-####################
-
-1) Fix incorrect error message in testparm.c regarding 'map system'.
-2) Protect against core dump if ioctl for print job sends invalid
- fid.
-3) Fix bug in generic hash cacluation.
-4) Remove references to unused 'strip dot' parameter
-5) Fix CPU burn bug in multi-byte character conversion.
-6) Use opt_target_workgroup instead of lp_workgroup() in vampire
- code so we can override the value in smb.conf with the -w option.
-7) Display an error if we can't create a posix account for the
- user when running 'net rpc vampire' (bug 323).
-8) Fix UTF8 conversion bugs in LDAP passdb and idmap code (bug 296).
-9) Fix smbd crash when changing the machine trust account password
- (bug 273).
-10) Remove getpwnam() calls from init_sam_from_xxx(). This means
- that %u & %g will no longer expand in the "login ..." set of
- smb.conf options, but %U and %G still do. The payback is that
- winbindd local accounts for users work with 'wbinfo -u'
- when winbind is running on a Samba PDC.
-11) Fix unitiailized timestamp where merging print_jobs and
- lpq listing.
-12) Fix bug in debian packaging files affecting non-i386 platforms.
-
-
-Changes since 3.0rc2
-####################
-
-1) Remove Perl module dependencies in generated RedHat 8/9 RPMS.
-2) Update mount helper to take synonyms for file_mode and
- dir_mode (fmask and dmask).
-3) Fix portability bug with log2pcaphex.
-4) Use different algorithm to generate codepages source code which
- allows to take gaps into account thus making unnecessary
- extended [index] = value, syntax in to_ucs2 array (bug 380).
-5) Fix comment strings to 43 bytes as per spec.
-6) Fix pam_winbind compile bug on FreeBSD (bug 261).
-7) Support for in-memory keytabs, which are needed to make heimdal
- work properly. MIT does not support them, so this check will be
- used to decide whether to use them. (partial fix for bug 372).
-8) Disable RC4-HMAC on broken heimdal setups. (remainder of bug
- 372).
-9) Correct bug in smbclient that resulted in errors when untarring
- long filenames (bug 308).
-10) Improve autoconf checks for PAM header files and libs.
-11) Added fast path to convert_string() when dealing with
- ASCII->ASCII, UCS2-LE->ASCII, and ASCII->UCS2-LE with
- values <= 0x7F.
-12) Quiet debug messages when we don't find a module and it is not
- a critical error (bug 375).
-13) Fix UNIX passwd sync properly.
-14) Fix more transitive trust issues in winbindd (bug 305).
-15) Ensure that winbindd functions with 'disable netbios = yes'
-16) Store the real short domain name in secrets.tdb as soon as we
- know it. Also display an error message when joining an AD
- domain and the 'workgroup' parameter has not been specified.
-17) Return 0 DFS links instead of -1 when dfs support is not enabled.
-18) Update LDAP schema for Netscape DS 4.x and Novell eDirectory 8.7
-19) Ensure that name types can be specified using name#type notation
- in the 'net' command (bug 73).
-20) Add retry looks to ADS sequence number and domain SID lookups
- (bug 364).
-21) use a variant of alloc_sub_basic() for string lists such as
- 'valid users', 'write list', and 'read list' (bug 397).
-22) Fix seg fault when winbindd receives an error from the AD server
- in response to an LDAP search (bug 282).
-23) Update findsmb to use the new syntax for smbclient and nmblookup.
-24) Fix bug that prevented variables from being used in explicitly
- defined path in [homes].
-25) Only set SIDs when they're returned by the MySQL query
- (pdb_mysql.so).
-26) Include support for NTLMv2 key exchange.
-27) Revert default for 'client ntlmv2 auth' to off (bug 359).
-28) Fix crash in winbindd when the trust account password gets
- changed underneath us via 'net rpc changetrustpw' (bug 382).
-29) Use djb-algorithm string hash - faster than the tdb one we
- used to use. Does not change on disk format or hashing location.
-30) Implements some kind of improved AFS support for Samba on
- Linux with OpenAFS 1.2.10. './configure --with-fake-kaserver'
- assumes that you have OpenAFS on your machine.
-31) When enumerating dfs shares loop from 0 to lp_numservices() instead
- of relying on lp_servicename(n) to return an empty string for
- invalid service numbers (bug 403).
-32) Fix crash bug in 'net rpc samdump' (bug 334).
-33) Fix crash bug in WINS NSS module (bug 299).
-34) Fix a few minor compile errors on HP-UX.
-
-
-
-Changes since 3.0rc1
-####################
-
-1) Add levels 261 and 262 to search. Found using Samba4 tester.
-2) Correct bad error return code in session setup reply
-3) Fix bug where smbd returned DOS error codes from SMBsearch
- even when NT1 protocol was negotiated.
-4) Implement SMBexit properly.
-5) Return group lists from a Samba PDC to a Windows 9x/ME box
- in implementing user level access control (bug 314).
-6) Prevent SWAT from crashing when adding shares (bug 254)
-7) Fix various documentation issues (bugs 304 & 214)
-8) Fix wins server listing in SWAT (bug 197)
-9) Fix problem in rpcclient that caused enumerating printer
- drivers to report failure (bug 294).
-10) Use kerberos 5 authentication in our client code whenever possible
-11) Fix schannel bug that caused Active Directory DC's to downgrade our
- machine account to an NT member.
-12) Implement missing SAMR_REMOVE_USER_FOREIGN_DOMAIN call (bug 252).
-13) Implement automatic generation of include/version.h
-14) Include initial version of smbldap-tool scripts for the Samba
- 3.0 schema.
-15) Implement numerous fixes for multi-byte character strings.
-16) Enable 'unix extensions' parameter by default.
-17) Make sure we set the SID type when falling back to the rid
- algorithm (bug 245).
-18) Correct linking problems with pam_smbpass (bug 327).
-19) Add SYSV defines for Irix and Solaris to ensure the 'printing'
- parameter default to the correct value (bug 230)
-20) Fix recursion bug in alloc_string_sub() (bug 289, et. al.)
-21) Ensure that 'make install' includes the static and shared
- versions of the libsmbclient libraries.
-22) Add CP850 and CP437 internal character set support (bug 150).
-23) Add support to examples/LDAP/convertSambaAccount for generating
- LDIF modify files instead of just add (303).
-24) Fix support for -W option in smbclient (bug 39)
-25) Remove 'ldap trust ids' parameter since it could not be supported
- by the current architecture.
-26) Don't crash when no argument is given to -T in smbclient (bug 345).
-27) Ensure smbadduser contains the same paths for the smbpasswd file
- as the other Samba tools (bug 290).
-28) Port of 'available = no' fix for [homes] from SAMBA_2_2 cvs tree.
-29) Add sanity checks to DeletePrinterData[Ex]() and ensure that the
- modified printer is written to disk.
-30) Force winbindd to periodically update the trusted domain cache.
-31) Remove outdated import/export script to convert an smbpasswd file
- to and from and LDAP directory. Use the pdbedit tool instead.
-32) Ensure that %U substitution is restored on next valid packet
- if a logon fails.
-
-
-Changes since 3.0beta3
-######################
-
-1) Various memory leak fixes.
-2) Provide full support for SMB signing (server and client)
-3) Check for broken getgrouplist() in glibc.
-4) Don't get stuck in an infinite loop listing directories
- recursively if the server returns an empty directory name
- (bug 222).
-5) Idle LDAP connections after 150 seconds.
-6) Patched make uninstallmodules (bug 236).
-7) Fix bug that caused smbd to return incomplete directory listings
- when UNIX files contained MS wildcard characters.
-8) Quiet default debug messages in command line tools.
-9) Fixes to avoid panics on invalid multi-byte strings.
-10) Fix error messages when creating a new smbpasswd file (bug 198).
-11) Implemented better detection routines in autoconf scripts for
- locating ads support on the host OS.
-12) Fix bug that caused libraries in /usr/local/lib to be ignored
- (bug 174).
-13) Ensure winbindd_ads uses the correct realm or domain name when
- connecting to trusted DC.
-14) Ensure a correct prototype is created for snprintf() (bug 187)
-15) Stop files being created on read-only shares in some circumstances.
-16) Fix wbinfo -p (bug 251)
-17) Support schannel on any tcp/ip connection if necessary
-18) Correct bug in user_in_list() so that it works with winbind groups
- again.
-19) Ensure the schannel bind credentials default to the domain
- of the destination host.
-20) Default password expiration time in account_pol.tdb to never
- expire. Remove any existing account_pol.tdb file to reset
- the new default policy (bug 184).
-21) Add buttons to SWAT to change the view of smb.conf (bug 212)
-22) Fix incorrect checks that determine whether or not the 'add user
- script' has been set.
-23) More cleanup for internal character set conversions.
-24) Fixes for multi-byte strings in stat cache code.
-25) Ensure that the net command honors the 'workgroup' parameter
- in smb.conf when not overridden from the command line.
-26) Add gss-spnego support to the ntlm_auth tool.
-27) Add vfs_default_quota VFS module.
-28) Added server support for NT quota interfaces.
-29) Prevent Krb5 replay attacks by adding a replay_cache.
-30) Fix problems with winbindd and transitive trusts in AD domains.
-31) Added -S to client tools for setting SMB signing options on the
- command line.
-32) Fix bug causing the 'passwd change program' to be called as the
- connected user and not root.
-33) Fixed data corruption bug in byte-range locking (e.g. affected MS Excel).
-34) Support winbindd on FreeBSD is possible.
-35) Look at only the first OID in the security blob sent in the session
- setup request to determine the token type.
-36) Only push locks onto a blocking lock queue if the posix lock failed with
- EACCES or EAGAIN (this means another lock conflicts). Else return an
- error and don't queue the request.
-37) Fix command line argument processing for smbtar.
-38) Correct issue that caused smbd to return generic unix_user.<uid>
- for lookupsid().
-39) Default to algorithmic mapping when generating a rid for a group
- mapping.
-40) Expand %g and %G in logon script, profile path, etc... during
- a domain logon (bug 208).
-41) Make sure smbclient obeys '-s <config>'
-42) Added win2k3 shadow copy operations to VFS interface.
-43) Allow connections to samba domain member as SERVER\user (don't
- always default to DOMAIN\user).
-44) Remove checks in winbindd that caused it to attempt to use
- non-transitive trust relationships.
-45) Remove delays in winbindd caused by invalid DNS lookups.
-46) Fix supplementary group memberships on systems with slightly
- broken NSS implementations (bug 267).
-47) Correct issue that prevented smbclient from viewing shares on
- a win2k server when using a non-anonymous connection (bug 284).
-48) Add --domain=DOMAIN_NAME to wbinfo for limiting operations like
- 'wbinfo -u' to a single domain. The '.' character represents
- our domain.
-49) Fix group enumeration bug when using an LDAP directory for
- storing group mappings.
-50) Default to use NTLMv2 if available. Fallback to not use LM/NTLM
- when the extended security capability bit is not set.
-51) Fix crash in 'wbinfo -a' when using extended characters in the
- username (bug 269).
-52) Fix multi-byte strupper() panics (bug 205).
-53) Add vfs_readonly VFS module.
-54) Make sure to initialize the sambaNextUserRid and sambaNextGroupRid
- attributes when using 'idmap backend = ldap' (bug 280).
-55) Make sure that users shared between a Samba PDC and member
- samba server are seen as domain users and not local users on the
- domain member.
-56) Fix Query FS Info level 2.
-57) Allow enumeration of users and groups by win9x "file server" (bug
- 286).
-58) Create symlinks during install for modules that support mutliple
- functions (bug 91).
-59) More iconv detection fixes.
-60) Fix path length error in vfs_recycle module (bug 291).
-61) Added server support for the LSA_DS UUID on the \lsarpc pipe.
- (server DsRoleGetPrimaryDomainInfo() is currently disabled).
-62) Fix SMBseek and get/set position calls.
-62) Fix SetFileInfo level 1.
-63) Added tool to convert smbd log file to a pcap file (log2pcaphex).
-
-
-
-Changes since 3.0beta2
-######################
-
-1) Added fix for Japanese case names in statcache code;
- these can change size on upper casing.
-2) Correct issues with iconv detection in configure script
- (support needed to find iconv libraries on FreeBSD).
-3) Fix bug that caused a WINS server to be marked as dead
- incorrectly (bug #190).
-4) Removing additional deadlocks conditions that prevented
- winbindd from running on a Samba PDC (used for trust
- relationships).
-5) Add support for searching for Active Directory for
- published printers (net ads printer search).
-6) Separate UNIX username from DOMAIN\username in pipe
- credentials.
-7) Auth modules now support returning NT_STATUS_NOT_IMPLEMENTED
- for cases that they cannot handle.
-8) Flush winbindd connection cache when the machine trust account
- password is changed while a connection is open (bug #200).
-9) Add support for 'OSVersion' server printer data string
- (corrects problem with uploading printer drivers from
- WinXP clients).
-10) Numerous memory leak fixes.
-11) LDAP fixes ("passdb backend = ldapsam" & "idmap backend = ldap"):
- - Store domain SID in LDAP directory.
- - store idmap information in existing entries (use sambaSID=...
- if adding a new entry).
-12) Fix incorrect usage of primary group SID when looking up user
- groups (bug #109).
-13) Remove idmap_XX_to_XX calls from smbd. Move back to the the
- winbind_XXX and local_XXX calls used in 2.2.
-14) All uid/gid allocation must involve winbindd now (we do not
- attempt to map unknown SIDs to a UNIX identify).
-15) Add 'winbind trusted domains only' parameter to force a domain
- member. The server to use matching users names from /etc/passwd
- for its domain (needed for domain member of a Samba domain).
-16) Rename 'idmap only' to 'enable rid algorithm' for better clarity
- (defaults to "yes").
-17) Add support for multi-byte statcache code (bug #185)
-18) Fix open mode race condition.
-19) Implement winbindd local account management functions. Refer to
- the "Winbind Changes" section for details.
-20) Move RID allocation functions into idmap backend.
-21) Fix parsing error that prevented publishing printers from a
- Samba server in an AD domain.
-22) Revive NTLMSSP support for named pipes.
-23) More SCHANNEL fixes.
-24) Correct SMB signing with NTLMSSP.
-25) Fix coherency bug in print handle/printer object caching code
- that could cause XP clients to infinitely loop while updating
- their local printer cache.
-26) Make winbindd use its dual-daemon mode by default (use -Y to
- start as a single process).
-27) Add support to nmbd and winbindd for 'smbcontrol <pid>
- reload-config'.
-28) Correct problem with smbtar when dealing with files > 8Gb
- (bug #102).
-
-
-
-Changes since 3.0beta1
-######################
-
-1) Rework our smb signing code again, this factors out some of
- the common MAC calculation code, and now supports multiple
- outstanding packets (bug #40).
-2) Enforce 'client plaintext auth', 'client lanman auth' and 'client
- ntlmv2 auth'.
-3) Correct timestamp problem on 64-bit machines (bug #140).
-4) Add extra debugging statements to winbindd for tracking down
- failures.
-5) Fix bug when aliased 'winbind uid/gid' parameters are used.
- ('winbind uid/gid' are now replaced with 'idmap uid/gid').
-6) Added an auth flag that indicates if we should be allowed
- to fall back to NTLMSSP for SASL if krb5 fails.
-7) Fixed the bug that forced us not to use the winbindd cache when
- we have a primary ADS domain and a secondary (trusted) NT4
- domain.
-8) Use lp_realm() to find the default realm for 'net ads password'.
-9) Removed editreg from standard build until it is portable..
-10) Fix domain membership for servers not running winbindd.
-11) Correct race condition in determining the high water mark
- in the idmap backend (bug #181).
-12) Set the user's primary unix group from usrmgr.exe (partial
- fix for bug #45).
-13) Show comments when doing 'net group -l' (bug #3).
-14) Add trivial extension to 'net' to dump current local idmap
- and restore mappings as well.
-15) Modify 'net rpc vampire' to add new and existing users to
- both the idmap and the SAM. This code needs further testing.
-16) Fix crash bug in ADS searches.
-17) Build libnss_wins.so as part of nsswitch target (bug #160).
-18) Make net rpc vampire return an error if the sam sync RPC
- returns an error.
-19) Fail to join an NT 4 domain as a BDC if a workstation account
- using our name exists.
-20) Fix various memory leaks in server and client code
-21) Remove the short option to --set-auth-user for wbinfo (-A) to
- prevent confusion with the -a option (bug #158).
-22) Added new 'map acl inherit' parameter.
-23) Removed unused 'privileges' code from group mapping database.
-24) Don't segfault on empty passdb backend list (bug #136).
-25) Fixed acl sorting algorithm for Windows 2000 clients.
-26) Replace universal group cache with netsamlogon_cache
- from APPLIANCE_HEAD branch.
-27) Fix autoconf detection issues surrounding --with-ads=yes
- but no Krb5 header files installed (bug #152).
-28) Add LDAP lookup for domain sequence number in case we are
- joined using NT4 protocols to a native mode AD domain.
-29) Fix backend method selection for trusted NT 4 (or 2k
- mixed mode) domains.
-30) Fixed bug that caused us to enumerate domain local groups
- from native mode AD domains other than our own.
-31) Correct group enumeration for viewing in the Windows
- security tab (bug #110).
-32) Consolidate the DC location code.
-33) Moved 'ads server' functionality into 'password server' for
- backwards compatibility.
-34) Fix winbindd_idmap tdb upgrades from a 2.2 installation.
- ( if you installed beta1, be sure to
- 'mv idmap.tdb winbindd_idmap.tdb' ).
-35) Fix pdb_ldap segfaults, and wrong default values for
- ldapsam_compat.
-36) Enable negative connection cache for winbindd's ADS backend
- functions.
-37) Enable address caching for active directory DC's so we don't
- have to hit DNS so much.
-38) Fix bug in idmap code that caused mapping to randomly be
- redefined.
-39) Add tdb locking code to prevent race condition when adding a
- new mapping to idmap.
-40) Fix 'map to guest = bad user' when acting as a PDC supporting
- trust relationships.
-41) Prevent deadlock issues when running winbindd on a Samba PDC
- to handle allocating uids & gids for trusted users and groups
-42) added LOCALE patch from Steve Langasek (bug #122).
-43) Add the 'guest' passdb backend automatically to the end of
- the 'passdb backend' list if 'guest account' has a valid
- username.
-44) Remove samstrict_dc auth method. Rework 'samstrict' to only
- handle our local names (or domain name if we are a PDC).
- Move existing permissive 'sam' method to 'sam_ignoredomain'
- and make 'samstrict' the new default 'sam' auth method.
-45) Match Windows NT4/2k behavior when authenticating a user with
- and unknown domain (default to our domain if we are a DC or
- domain member; default to our local name if we are a
- standalone server).
-46) Fix Get_Pwnam() to always fall back to lookup 'user' if the
- 'DOMAIN\user' lookup fails. This matches 2.2. behavior.
-47) Fix the trustdom_cache code to update the list of trusted
- domains when operating as a domain member and not using
- winbindd.
-48) Remove 'nisplussam' passdb backend since it has suffered for
- too long without a maintainer.
-
-
-
-
-######################################################################
-Upgrading from a previous Samba 3.0 beta
-########################################
-
-Beginning with Samba 3.0.0beta3, the RID allocation functions
-have been moved into winbindd. Previously these were handled
-by each passdb backend. This means that winbindd must be running
-to automatically allocate RIDs for users and/or groups. Otherwise,
-smbd will use the 2.2 algorithm for generating new RIDs.
-
-If you are using 'passdb backend = tdbsam' with a previous Samba
-3.0 beta release (or possibly alpha), it may be necessary to
-move the RID_COUNTER entry from /usr/local/samba/private/passdb.tdb
-to winbindd_idmap.tdb. To do this:
-
-1) Ensure that winbindd_idmap.tdb exists (launch winbindd at least
- once)
-2) build tdbtool by executing 'make tdbtool' in the source/tdb/
- directory
-3) run: (note that 'tdb>' is the tool's prompt for input)
-
- root# ./tdbtool /usr/local/samba/private/passdb.tdb
- tdb> show RID_COUNTER
- key 12 bytes
- RID_COUNTER
- data 4 bytes
- [000] 0A 52 00 00 .R.
-
- tdb> move RID_COUNTER /usr/local/samba/var/locks/winbindd_idmap.tdb
- ....
- record moved
-
-If you are using 'passdb backend = ldapsam', it will be necessary to
-store idmap entries in the LDAP directory as well (i.e. idmap backend
-= ldap). Refer to the 'net idmap' command for more information on
-migrating SID<->UNIX id mappings from one backend to another.
-
-If the RID_COUNTER record does not exist, then these instructions are
-unneccessary and the new RID_COUNTER record will be correctly generated
-if needed.
-
-
-
-########################
-Upgrading from Samba 2.2
-########################
-
-This section is provided to help administrators understand the details
-involved with upgrading a Samba 2.2 server to Samba 3.0.
-
-
-Building
---------
-
-Many of the options to the GNU autoconf script have been modified
-in the 3.0 release. The most noticeable are:
-
- * removal of --with-tdbsam (is now included by default; see section
- on passdb backends and authentication for more details)
-
- * --with-ldapsam is now on used to provided backward compatible
- parameters for LDAP enabled Samba 2.2 servers. Refer to the passdb
- backend and authentication section for more details
-
- * inclusion of non-standard passdb modules may be enabled using
- --with-expsam. This includes an XML backend and a mysql backend.
-
- * removal of --with-msdfs (is now enabled by default)
-
- * removal of --with-ssl (no longer supported)
-
- * --with-utmp now defaults to 'yes' on supported systems
-
- * --with-sendfile-support is now enabled by default on supported
- systems
-
-
-Parameters
-----------
-
-This section contains a brief listing of changes to smb.conf options
-in the 3.0.0 release. Please refer to the smb.conf(5) man page for
-complete descriptions of new or modified parameters.
-
-Removed Parameters (order alphabetically):
-
- * admin log
- * alternate permissions
- * character set
- * client codepage
- * code page directory
- * coding system
- * domain admin group
- * domain guest group
- * force unknown acl user
- * nt smb support
- * postscript
- * printer driver
- * printer driver file
- * printer driver location
- * status
- * strip dot
- * total print jobs
- * use rhosts
- * valid chars
- * vfs options
-
-New Parameters (new parameters have been grouped by function):
-
- Remote management
- -----------------
- * abort shutdown script
- * shutdown script
-
- User and Group Account Management
- ---------------------------------
- * add group script
- * add machine script
- * add user to group script
- * algorithmic rid base
- * delete group script
- * delete user from group script
- * passdb backend
- * set primary group script
-
- Authentication
- --------------
- * auth methods
- * realm
-
- Protocol Options
- ----------------
- * client lanman auth
- * client NTLMv2 auth
- * client schannel
- * client signing
- * client use spnego
- * disable netbios
- * ntlm auth
- * paranoid server security
- * server schannel
- * server signing
- * smb ports
- * use spnego
-
- File Service
- ------------
- * get quota command
- * hide special files
- * hide unwriteable files
- * hostname lookups
- * kernel change notify
- * mangle prefix
- * map acl inherit
- * msdfs proxy
- * set quota command
- * use sendfile
- * vfs objects
-
- Printing
- --------
- * max reported print jobs
-
- UNICODE and Character Sets
+The SMB/CIFS protocol implemented by Samba is vulnerable to many
+attacks, even without specific security holes. The TCP ports 139 and
+the new port 445 (used by Win2k and the Samba 3.0 alpha code in
+particular) should never be exposed to untrusted networks.
+
+Description
+-----------
+
+A buffer overrun condition exists in the SMB/CIFS packet fragment
+re-assembly code in smbd which would allow an attacker to cause smbd
+to overwrite arbitrary areas of memory in its own process address
+space. This could allow a skilled attacker to inject binary specific
+exploit code into smbd.
+
+This version of Samba adds explicit overrun and overflow checks on
+fragment re-assembly of SMB/CIFS packets to ensure that only valid
+re-assembly is performed by smbd.
+
+In addition, the same checks have been added to the re-assembly
+functions in the client code, making it safe for use in other
+services.
+
+Credit
+------
+
+This security flaw was discovered and reported to the Samba Team by
+Sebastian Krahmer <krahmer@suse.de> of the SuSE Security Audit Team.
+The fix was prepared by Jeremy Allison and reviewed by engineers from
+the Samba Team, SuSE, HP, SGI, Apple, and the Linux vendor engineers
+on the Linux Vendor security mailing list.
+
+The Samba Team would like to thank SuSE and Sebastian Krahmer for
+their excellent auditing work and for drawing attention to this flaw.
+
+Patch Availability
+-----------------
+
+As this is a security issue, patches for this flaw specific to earlier
+versions of Samba will be and posted on the samba-technical@samba.org
+mailing list as requested.
+
+
+************************************
+Protecting an unpatched Samba server
+************************************
+
+ Samba Team, March 2003
+
+ This is a note on how to provide your Samba server some
+ protection against the recently discovered remote security
+ hole if you are unable to upgrade to the fixed version
+ immediately. Even if you do upgrade you might like to think
+ about the suggestions in this note to provide you with
+ additional levels of protection.
+
+
+ Using host based protection
+ ---------------------------
+
+ In many installations of Samba the greatest threat comes for
+ outside your immediate network. By default Samba will accept
+ connections from any host, which means that if you run an
+ insecure version of Samba on a host that is directly
+ connected to the Internet you can be especially vulnerable.
+
+ One of the simplest fixes in this case is to use the 'hosts
+ allow' and 'hosts deny' options in the Samba smb.conf
+ configuration file to only allow access to your server from a
+ specific range of hosts. An example might be:
+
+ hosts allow = 127.0.0.1 192.168.2.0/24 192.168.3.0/24
+ hosts deny = 0.0.0.0/0
+
+ The above will only allow SMB connections from 'localhost'
+ (your own computer) and from the two private networks
+ 192.168.2 and 192.168.3. All other connections will be
+ refused connections as soon as the client sends its first
+ packet. The refusal will be marked as a 'not listening on
+ called name' error.
+
+
+ Using interface protection
--------------------------
- * display charset
- * dos charset
- * unicode
- * unix charset
-
- SID to uid/gid Mappings
+
+ By default Samba will accept connections on any network
+ interface that it finds on your system. That means if you
+ have a ISDN line or a PPP connection to the Internet then
+ Samba will accept connections on those links. This may not be
+ what you want.
+
+ You can change this behavior using options like the
+ following:
+
+ interfaces = eth* lo
+ bind interfaces only = yes
+
+ that tells Samba to only listen for connections on interfaces
+ with a name starting with 'eth' such as eth0, eth1, plus on
+ the loopback interface called 'lo'. The name you will need to
+ use depends on what OS you are using, in the above I used the
+ common name for ethernet adapters on Linux.
+
+ If you use the above and someone tries to make a SMB
+ connection to your host over a PPP interface called 'ppp0'
+ then they will get a TCP connection refused reply. In that
+ case no Samba code is run at all as the operating system has
+ been told not to pass connections from that interface to any
+ process.
+
+
+ Using a firewall
+ ----------------
+
+ Many people use a firewall to deny access to services that
+ they don't want exposed outside their network. This can be a
+ very good idea, although I would recommend using it in
+ conjunction with the above methods so that you are protected
+ even if your firewall is not active for some reason.
+
+ If you are setting up a firewall then you need to know what
+ TCP and UDP ports to allow and block. Samba uses the
+ following:
+
+ UDP/137 - used by nmbd
+ UDP/138 - used by nmbd
+ TCP/139 - used by smbd
+ TCP/445 - used by smbd
+
+ The last one is important as many older firewall setups may
+ not be aware of it, given that this port was only added to
+ the protocol in recent years.
+
+
+ Using a IPC$ share deny
-----------------------
- * idmap backend
- * idmap gid
- * idmap uid
- * winbind enable local accounts
- * winbind trusted domains only
- * template primary group
- * enable rid algorithm
-
- LDAP
- ----
- * ldap delete dn
- * ldap group suffix
- * ldap idmap suffix
- * ldap machine suffix
- * ldap passwd sync
- * ldap user suffix
-
- General Configuration
- ---------------------
- * preload modules
- * private dir
-
-Modified Parameters (changes in behavior):
-
- * encrypt passwords (enabled by default)
- * mangling method (set to 'hash2' by default)
- * passwd chat
- * passwd program
- * restrict anonymous (integer value)
- * security (new 'ads' value)
- * strict locking (enabled by default)
- * unix extensions (enabled by default)
- * winbind cache time (increased to 5 minutes)
- * winbind uid (deprecated in favor of 'idmap uid')
- * winbind gid (deprecated in favor of 'idmap gid')
-
-
-Databases
----------
-
-This section contains brief descriptions of any new databases
-introduced in Samba 3.0. Please remember to backup your existing
-${lock directory}/*tdb before upgrading to Samba 3.0. Samba will
-upgrade databases as they are opened (if necessary), but downgrading
-from 3.0 to 2.2 is an unsupported path.
-
-Name Description Backup?
----- ----------- -------
-account_policy User policy settings yes
-gencache Generic caching db no
-group_mapping Mapping table from Windows yes
- groups/SID to unix groups
-winbindd_idmap ID map table from SIDS to UNIX yes
- uids/gids.
-namecache Name resolution cache entries no
-netsamlogon_cache Cache of NET_USER_INFO_3 structure no
- returned as part of a successful
- net_sam_logon request
-printing/*.tdb Cached output from 'lpq no
- command' created on a per print
- service basis
-registry Read-only samba registry skeleton no
- that provides support for exporting
- various db tables via the winreg RPCs
-
-
-Changes in Behavior
+
+ If the above methods are not suitable, then you could also
+ place a more specific deny on the IPC$ share that is used in
+ the recently discovered security hole. This allows you to
+ offer access to other shares while denying access to IPC$
+ from potentially untrustworthy hosts.
+
+ To do that you could use:
+
+ [ipc$]
+ hosts allow = 192.168.115.0/24 127.0.0.1
+ hosts deny = 0.0.0.0/0
+
+ this would tell Samba that IPC$ connections are not allowed
+ from anywhere but the two listed places (localhost and a
+ local subnet). Connections to other shares would still be
+ allowed. As the IPC$ share is the only share that is always
+ accessible anonymously this provides some level of protection
+ against attackers that do not know a username/password for
+ your host.
+
+ If you use this method then clients will be given a 'access
+ denied' reply when they try to access the IPC$ share. That
+ means that those clients will not be able to browse shares,
+ and may also be unable to access some other resources.
+
+ I don't recommend this method unless you cannot use one of
+ the other methods listed above for some reason.
+
+
+ Upgrading Samba
+ ---------------
+
+ Of course the best solution is to upgrade Samba to a version
+ where the bug has been fixed. If you wish to also use one of
+ the additional measures above then that would certainly be a
+ good idea.
+
+ Please check regularly on http://www.samba.org/ for updates
+ and important announcements.
+
+
+ ****************************************
+ ****************************************
+
+
+Changes since 2.2.7a
+---------------------
+
+New Parameters
+
+ * acl compatibility
+
+Additional Changes:
+ See the cvs log for SAMBA_2_2 for more details
+
+1) smbumount lazy patch from Mandrake
+2) Check for too many processes *before* the fork.
+3) make sure we don't run over the end of 'name' in unix_convert()
+4) set umask to 0 before creating socket directory.
+5) Fix the LARGE_SMB_OFF_T problems and allow smbd to do the right
+ thing in interactive mode when a log file dir is also specified.
+6) Fix delete on close semantics to match W2K.
+7) Correctly return access denied on share mode deny when we can't
+ open the file.
+8) Always use safe_strcpy not pstrcpy for malloc()'d strings
+9) Fixes for HP-UX only having limited POSIX lock range
+10) Added uid/gid caching code. Reduces load on winbindd.
+11) Removed extra copy of server name in the printername field (it was
+ mangling the the name to be \\server\\\server\printer
+12) Fix dumb perror used without errno being set.
+13) Do retries correctly if the connection to the DC has failed.
+14) Correctly check for inet_addr fail.
+15) Ensure we use getgrnam() unless BROKEN_GETGRNAM is defined.
+16) Fix for missing if (setting_acls) on default perms.
+17) Fix to cache the sidtype
+18) fix printer settings on Solaris (big-endian) print servers.
+ ASCII -> UNICODE conversion bug.
+19) Small fix check correct error return.
+20) Ensure space_avail is unsigned.
+21) patch to check for a valid [f]chmod_acl function pointer
+ before calling it. Fixes seg fault in audit VFS module
+22) When checking is_locked() new WRITE locks conflict with existing
+ READ locks even if the context is the same.
+23) Merge off-by-one crash fixes from HEAD
+24) Move off-by-one buggy malloc()/safe_strcpy() combination to
+ strdup() instead.
+25) Merge from HEAD. Use pstrcpy not safe_strcpy.
+26) Fix to allow blocking lock notification to be done rapidly (no wait
+ for smb -> smb lock release). Adds new PENDING_LOCK type to lockdb
+ (does not interfere with existing locks).
+27) Doxygen cleanups for code documentation
+28) limit the unix domain sockets used by winbindd by adding a
+ "last_access" field to winbindd connections, and will close
+ the oldest idle connection once the number of open connections goes
+ over WINBINDD_MAX_SIMULTANEOUS_CLIENTS (defined in local.h as 200
+ currently)
+29) Fix a couple of string handling errors in smbd/dir.c that would
+ cause smbd to crash
+30) Fix seg fault in smbpasswd when specifying the new password
+ as a command line argument
+31) Correct 64-but file sizes issues with smbtar and smbclient
+32) Add batch mode option to pdbedit
+33) Add protection in nmbd against malformed reply packets
+34) Fix bug with sendfile profiling support in smbstatus output
+35) Correct bug in "hide unreadable" smb.conf parameter that
+ resulted in incorrect directory listings
+36) Fix bug in group enumeration in winbindd
+37) Correct build issues with libsmbclient on Solaris
+38) Fix memory leak and bad pointer dereference in password
+ changing code in smbd
+39) Fix for changing attributes on a file truncate
+40) Ensure smbd process count never gets to -1 if limiting number
+ of processes
+41) Ensure we return disk full by default on short writes
+42) Don't delete jobs submitted after the lpq time
+43) Fix reference count bug where smbds would not terminate
+ with no open resources
+44) Performance fix when using quota support on HP-UX
+45) Fixes for --with-ldapsam
+ * Default to port 389 when "ldap ssl != on"
+ * add support for rebinding to the master directory server
+ for password changes when "ldap server" points to a read-only
+ slave
+46) Add -W and -X command line flags to smbpasswd for extracting and
+ setting the machine/domain SID in secrets.tdb. See the
+ smbpasswd(8) man page for details.
+47) Added (c) Luke Howard to winbind_nss_solaris.c for coded
+ obtained from PADL's nss_ldap library.
+48) Fix bug in samr_dispinfo query in winbindd
+49) Fix segfault in NTLMSSP password changing code for
+ guest connections
+50) Correct pstring/fstring mismatches
+51) Send level II oplock break requests synchronously to prevent
+ condition where one smbd would continually lock a share entry
+ in locking.tdb
+52) Miscellaneous cleanups for tdb error conditions and appending
+ data in a record
+53) Implement correct open file truncate semantics with DOS
+ attributes
+54) Enforce wide links = no on files as well as directories
+55) Include shared library checks for Stratus VOS
+56) Include support for CUPS printer classes and logging the remote
+ client name
+57) Include "WinXP" (Windows XP) and "Win2K3" (Windows .NET) values
+ for %a
+58) Increase the max PDU size to deal with some troublesome printer
+ drivers and Windows NT 4.0 clients
+59) increment the process counter immediately after the fork
+ (not just when we receive the first smb packet)
+60) Ensure rename sets errno correctly
+61) Unify ACL code (back-port from 3.0)
+62) Fix some further issues around off_t and large offsets
+
+
+Changes since 2.2.7
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Fix for smbclient reporting negative file sizes on dir command
+ and negative statistics being reported when using put or get
+ on large files.
+2) Fix bug in determination of allocation size
+3) Fix 64bit size problems which prevented copying of files larger
+ than 2 GBytes.
+4) Fix for xcopy /s problem with old DOS clients not sending correct
+ attributes on subsequent SMBsearch calls.
+5) Fix bug in call to standard_sub_advanced giving a 0 length. This
+ fixes the string overflow in string_sub errors.
+6) Correctly handle querygroup rpcclient command
+7) fix broken incremental tar in smbtar command
+
+
+The release notes for 2.2.7 follow :
+
+IMPORTANT: Security bugfix for Samba
+------------------------------------
+
+Summary
+-------
+
+A security hole has been discovered in versions 2.2.2 through 2.2.6
+of Samba that could potentially allow an attacker to gain root access
+on the target machine. The word "potentially" is used because there
+is no known exploit of this bug, and the Samba Team has not been able to
+craft one ourselves. However, the seriousness of the problem warrants
+this immediate 2.2.7 release.
+
+In addition to addressing this security issue, Samba 2.2.7 also includes
+thirteen unrelated improvements. These improvements result from our
+process of continuous quality assurance and code review, and are part of
+the Samba team's commitment to excellence.
+
+Details
+-------
+
+There was a bug in the length checking for encrypted password change
+requests from clients. A client could potentially send an encrypted
+password, which, when decrypted with the old hashed password could be
+used as a buffer overrun attack on the stack of smbd. The attach would
+have to be crafted such that converting a DOS codepage string to little
+endian UCS2 unicode would translate into an executable block of code.
+
+All versions of Samba between 2.2.2 to 2.2.6 inclusive are vulnerable
+to this problem. This version of Samba 2.2.7 contains a fix for this
+problem.
+
+Earlier versions of Samba are not vulnerable.
+
+There is no known exploit or exploit code for this vulnerability,
+it was discovered by a code audit by Debian Samba maintainers.
+
+Credit
+------
+
+Thanks to Steve Langasek <vorlon@debian.org> and Eloy Paris
+<peloy@debian.org> for bringing this vulnerability to our notice.
+
+Patch for Samba versions 2.2.2 to 2.2.6
+---------------------------------------
+
+The following patch applies cleanly to the above Samba versions
+and will fix the vulnerability for sites that do not wish to upgrade
+to 2.2.7 at this time.
+
+
+-------------------------------cut here---------------------------------
+--- libsmb/smbencrypt.c.orig Tue Nov 19 17:21:57 2002
++++ libsmb/smbencrypt.c Tue Nov 19 17:22:12 2002
+@@ -63,7 +63,7 @@
+ if(len > 128)
+ len = 128;
+ /* Password must be converted to NT unicode - null terminated. */
+- dos_struni2((char *)wpwd, (const char *)passwd, 256);
++ dos_struni2((char *)wpwd, (const char *)passwd, len);
+ /* Calculate length in bytes */
+ len = strlen_w((const smb_ucs2_t *)wpwd) * sizeof(int16);
+-------------------------------cut here---------------------------------
+
+
+
+Changes since 2.2.6
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) ensure we send the notify message in the same way it is expected
+ to be received by srv_spoolss_receive_message().
+2) attribute matching on truncate only matters when opening truncate
+ with current SYSTEM|HIDDEN -> NONE. It's fine to truncate on open
+ with current NONE -> SYSTEM | HIDDEN.
+3) Fix bug in rpcclient's deldriver command
+4) Don't set global_machine_password_needs_changing if
+ lp_machine_password_timeout() is set to zero
+5) don't parse the BUFFER5 if the buffer length is zero
+6) fix core dump if pdbedit is run as non-root or smbpasswd file does
+ not exist
+7) Ensure can_delete() returns correct error code
+8) correctly return NT_STATUS_DELETE_PENDING from open code
+9) fix bug that assumed dos_unistr2 length was in ucs2 units, not
+ bytes
+10) check the long_archi name is not null when deleting a printer
+ driver. fixes core dump in smbd when using rpcclient's deldriver
+11) fix fd leak with kernel change notify on Linux 2.4 kernels
+12) must add one to the extra_data size to transfer the 0 string
+ terminator. This was causing "wbinfo --sequence" to access past
+ the end of malloced memory
+13) fix for large systems allowing more than 65536 files open in
+ NTcreate&X
+14) Fix bug in %U expansion
+
+
+
+----------------------------------------------------------------------
+The release notes for 2.2.6 follow :
+
+There have been several fixes and internal enhancements which include:
+
+ * Fixes for MS-RPC printing issues affecting Windows 2000 clients
+ * New support for smb.conf generation in SWAT
+ * Inclusion of several performance enhancements (See --with-sendfile
+ & and the modified smb.conf(5) parameters in these Release Notes)
+ * Fixes for several file locking bugs and returned status codes
+
+
+New Parameters
+--------------
+
+Refer to the smb.conf(5) man page for complete descriptions of new
+parameters.
+
+ * profile acls (S) workaround for issue with WinXP SP1
+ and roaming user profiles
+
+Removed Parameters
+------------------
+
+ * max packet (G)
+ * packet size (G)
+
+Modified Parameters
-------------------
-The following issues are known changes in behavior between Samba 2.2 and
-Samba 3.0 that may affect certain installations of Samba.
-
- 1) When operating as a member of a Windows domain, Samba 2.2 would
- map any users authenticated by the remote DC to the 'guest account'
- if a uid could not be obtained via the getpwnam() call. Samba 3.0
- rejects the connection as NT_STATUS_LOGON_FAILURE. There is no
- current work around to re-establish the 2.2 behavior.
-
- 2) When adding machines to a Samba 2.2 controlled domain, the
- 'add user script' was used to create the UNIX identity of the
- machine trust account. Samba 3.0 introduces a new 'add machine
- script' that must be specified for this purpose. Samba 3.0 will
- not fall back to using the 'add user script' in the absence of
- an 'add machine script'
-
-
-######################################################################
-Passdb Backends and Authentication
-##################################
-
-There have been a few new changes that Samba administrators should be
-aware of when moving to Samba 3.0.
-
- 1) encrypted passwords have been enabled by default in order to
- inter-operate better with out-of-the-box Windows client
- installations. This does mean that either (a) a samba account
- must be created for each user, or (b) 'encrypt passwords = no'
- must be explicitly defined in smb.conf.
-
- 2) Inclusion of new 'security = ads' option for integration
- with an Active Directory domain using the native Windows
- Kerberos 5 and LDAP protocols.
-
- MIT kerberos 1.3.1 supports the ARCFOUR-HMAC-MD5 encryption
- type which is neccessary for servers on which the
- administrator password has not been changed, or kerberos-enabled
- SMB connections to servers that require Kerberos SMB signing.
- Besides this one difference, either MIT or Heimdal Kerberos
- distributions are usable by Samba 3.0.
-
-
-Samba 3.0 also includes the possibility of setting up chains
-of authentication methods (auth methods) and account storage
-backends (passdb backend). Please refer to the smb.conf(5)
-man page for details. While both parameters assume sane default
-values, it is likely that you will need to understand what the
-values actually mean in order to ensure Samba operates correctly.
-
-The recommended passdb backends at this time are
-
- * smbpasswd - 2.2 compatible flat file format
- * tdbsam - attribute rich database intended as an smbpasswd
- replacement for stand alone servers
- * ldapsam - attribute rich account storage and retrieval
- backend utilizing an LDAP directory.
- * ldapsam_compat - a 2.2 backward compatible LDAP account
- backend
-
-Certain functions of the smbpasswd(8) tool have been split between the
-new smbpasswd(8) utility, the net(8) tool, and the new pdbedit(8)
-utility. See the respective man pages for details.
-
-
-######################################################################
-LDAP
-####
-
-This section outlines the new features affecting Samba / LDAP
-integration.
-
-New Schema
-----------
-
-A new object class (sambaSamAccount) has been introduced to replace
-the old sambaAccount. This change aids us in the renaming of attributes
-to prevent clashes with attributes from other vendors. There is a
-conversion script (examples/LDAP/convertSambaAccount) to modify and LDIF
-file to the new schema.
-
-Example:
-
- $ ldapsearch .... -b "ou=people,dc=..." > old.ldif
- $ convertSambaAccount <DOM SID> old.ldif new.ldif
-
-The <DOM SID> can be obtained by running 'net getlocalsid <DOMAINNAME>'
-on the Samba PDC as root.
-
-The old sambaAccount schema may still be used by specifying the
-"ldapsam_compat" passdb backend. However, the sambaAccount and
-associated attributes have been moved to the historical section of
-the schema file and must be uncommented before use if needed.
-The 2.2 object class declaration for a sambaAccount has not changed
-in the 3.0 samba.schema file.
-
-Other new object classes and their uses include:
-
- * sambaDomain - domain information used to allocate rids
- for users and groups as necessary. The attributes are added
- in 'ldap suffix' directory entry automatically if
- an idmap uid/gid range has been set and the 'ldapsam'
- passdb backend has been selected.
-
- * sambaGroupMapping - an object representing the
- relationship between a posixGroup and a Windows
- group/SID. These entries are stored in the 'ldap
- group suffix' and managed by the 'net groupmap' command.
-
- * sambaUnixIdPool - created in the 'ldap idmap suffix' entry
- automatically and contains the next available 'idmap uid' and
- 'idmap gid'
-
- * sambaIdmapEntry - object storing a mapping between a
- SID and a UNIX uid/gid. These objects are created by the
- idmap_ldap module as needed.
-
- * sambaSidEntry - object representing a SID alone, as a Structural
- class on which to build the sambaIdmapEntry.
-
-
-New Suffix for Searching
+ * max xmit (G) new default value
+ * large readwrite (G) new default value
+
+New ./configure Options
+-----------------------
+
+ --with-sendfile Enable experimental sendfile support
+ --with-winbind-ldap-hack Enable winbindd_ldap_hack() functionality
+ for Windows 2000 native mode domains
+
+
+Changes since 2.2.5
+--------------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Fixed several compiler warnings caused by the use of const parameters
+2) Fixed a hang in the main smbd process caused by an EINTR in the
+ wrong place
+3) Fixed string substitutions to accept a length for sanity checks
+4) Fixed 17-bit length field in nmb header
+5) Removed non-portable inline declaration for functions
+6) Performance fix for including files with an smb.conf variable in the
+ path name
+7) Fix for parsing LPRng lpq output
+8) Parsing fix for PRINTER_INFO_2 structure which was causing viewing
+ printer properties to fail
+9) Fix for printer change notification and Windows NT clients which caused
+ the client to go into an infinite loop of refreshing the local printers
+ folder
+10) Allow trans2 and nttrans messages to be processed in oplock break state
+ which fixes a problem with oplock break requests and Win2k clients
+11) Don't crash on setfileinfo on printer fsp
+12) Memory fixes caught by Valgrind
+13) Updates to stop spurious error message in tdb
+14) Fix silly logic bug in 'make smbd processes' and 'status = no' check
+15) Fix compilation of pam_smbpass and --with-ldap
+16) Fix compilation of smbwrapper on Solaris hosts
+17) fix logic error in a check for enabling the winbind_pam_auth_crap() code
+ & fix formatting typo in --with-winbind-auth-challenge
+18) Correcting check for ldap_start_tls()
+19) Fixed a problem with getgroups() where it could include our current
+ effective gid
+20) fix incorrect semantics in the DeletePrinterDriver() spoolss rpc
+ to only attempt to delete the architecture specified by the client
+21) Don't allow TEMP attribute on directory open
+22) Restore VxFS quotas to the 2.2 branch
+23) Added basic "Wizard" functionality to SWAT
+24) Fix initial "allocation size" in NTcreate&X call
+25) Fix for open fid, "nametoolong"
+26) Exit server on receipt of a non-SMB packet. Ensure we have
+ at least smb_size bytes before processing a packet
+27) Replace inet_aton with inet_addr() to correct compile problems on Solaris
+28) Include the "account" objectclass when adding a new account to --with-ldapsam
+ in order to comply with the data model implemented by OpenLDAP 2.1.x
+29) Various fixes for POSIX compliance
+30) Correct alignment & offset bug in EnumPrinterDataEx()
+31) Fix access checks when modifying forms using a print server handle
+ (not just a printer handle)
+32) Account for case data_len == 0 in EnumPrinterDataEx()
+33) Fix logic error in blocking lock code
+34) Fixed various incorrect return codes to clients
+35) Add RESOLVE_DFSPATH to mkdir operations
+36) Fix longstanding bug in Win2k clients by clearing the shortname
+ buffer before returning ASCII short name
+37) added -t option to smbpasswd for explicitly changing a trust
+ account password when operating in security = domain
+38) installed -x option to testparm to eXclude printing all parameter
+ values that are at default settings.
+39) Fix shares/printers view in SWAT so that only Basic options are exposed
+ upon initial entry.
+40) Added 1125 & KOI8-U to codepage list in Makefile.in
+41) Include separate configure checks for *openbsd* & *freebsd* when
+ determining flags used to compile shared libraries.
+42) Merge in free list unlock on error fix
+43) Correctly fail opens with mismatching SYSTEM or HIDDEN attributes
+ if we are mapping system or hidden
+44) Fix bug with stat mode open being done on read-only open with truncate
+45) Fix crash bug discovered where cli struct was being deallocated in a
+ called function
+46) Ensure we open UNIX fifo's non-blocking
+47) Fix DeletePrinterDriver() (hopefully for the last time...yeah right....)
+48) only lowercase global_myname in the %L substitution, not the whole string
+49) Merged Steve French's fix for OS/2 EA return error being removed
+50) Patch from Steve French to fix difference in responses to smbclient
+ //server/share ls / on Samba and Windows 2000
+51) Print error and exit if smb.conf doesn't have security=domain and
+ encrypt passwords=yes when joining domain
+52) Added final Steve French patch for "required" attributes with old dir
+ listings
+53) Initialize user_rid value in WINBIND_USERINFO structure returned by
+ the rpc version of query_user()
+54) Ensure we've failed a lock with a lock denied message before automatically
+ pushing it onto the blocking queue
+55) Add experimental --with-sendfile code
+56) alignment fix in printing code merged from HEAD
+57) Merge fix for other sids in token from HEAD
+58) Merge winbindd with current (more advanced) state of play in APPLIANCE_HEAD
+59) fix smbclient / Win98 off by one bug
+60) Never, *ever* hold a mutex lock in the message database where there may be
+ traversals being attempted
+61) Add LDAP hack for retrieving the SAM sequence number when a member of a
+ Windows 2000 native mode domain
+62) Fix race condition when changing a machine account password as we were
+ no longer locking the secrets entry
+63) Allow '@' as a valid character in domain names
+64) remove jobs from the spool directory when using cups
+65) removed -lresolv for --enable-ldapsam
+66) Memory leak fix and correct use of negative caching in winbindd
+67) Updated spoolss parsing code with known good state of APPLIANCE_HEAD
+68) Delete printer security check was reversed
+69) Windows allows delete printer on a handle opened by an admin user, then
+ used on a pipe handle created by an anonymous user...We do to now...
+70) Make explicit the difference between a tdb key with no data attached, and
+ a non existent entry
+71) Ensure we register the 1c name on the unicast subnet.
+72) Fix inheritance problem when recursively setting ACLs on directories
+73) prevent ACL set on read-only share
+74) Ensure we never have more than MAX_PRINT_JOBS in a queue
+75) Added timeout to tdb_lock_bystring()
+76) Ensure we set FIRST+LAST flags on a bind request
+77) Add version strings to the usage message for smbcacls and smbpasswd
+78) Fix bug in the write cache code
+79) make the default printed values for boolean the same for all parameters
+80) Default all LDAP connections to v3 with compiling with --with-ldapsam
+81) Fix memory leak in smbspool
+82) Fix bug in mangling code that resulted in Win9x clients not being
+ able to execute batch files in deep, non 8.3 directory paths
+83) Fix infinite looping bug in winbindd_getgrent()
+84) Fix crash bug on 64-bit systems (merge from HEAD)
+85) Fix extended character bug when setting LanMan/NT password
+86) Negotiate same SMB read size as a Windows 2000 file server
+ to fix performance bug with NT4 clients
+
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.5 follow :
+
+There have been several fixes and internal enhancements which include:
+
+* Several compile fixes for Solaris and HP-UX
+* More printing fixes for Windows NT/2k/XP clients
+* New options for the VFS recycle bin library
+* New internal signal handling semantics relating to directory change
+ notification and oplocks
+
+New/Changed parameters in 2.2.5
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf(5).
+
+Added/changed parameters
------------------------
-
-The following new smb.conf parameters have been added to aid in directing
-certain LDAP queries when 'passdb backend = ldapsam://...' has been
-specified.
- * ldap suffix - used to search for user and computer accounts
- * ldap user suffix - used to store user accounts
- * ldap machine suffix - used to store machine trust accounts
- * ldap group suffix - location of posixGroup/sambaGroupMapping entries
- * ldap idmap suffix - location of sambaIdmapEntry objects
+* block size = <INTEGER>
+* force unknown acl user = <boolean>
+* mangling method = [hash|hash2]
+
-If an 'ldap suffix' is defined, it will be appended to all of the
-remaining sub-suffix parameters. In this case, the order of the suffix
-listings in smb.conf is important. Always place the 'ldap suffix' first
-in the list.
+Deprecated Parameters
+---------------------
-Due to a limitation in Samba's smb.conf parsing, you should not surround
-the DN's with quotation marks.
+The following parameters have been marked as deprecated and will be removed
+in Samba 3.0
+* strip dot
+* status
-IdMap LDAP support
+
+Removed Parameters
------------------
-Samba 3.0 supports an ldap backend for the idmap subsystem. The
-following options would inform Samba that the idmap table should be
-stored on the directory server onterose in the "ou=idmap,dc=plainjoe,
-dc=org" partition.
+ none
+
+
+Changes in 2.2.5
+----------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) Removal of several compiler warnings, incorrect Makefile dependencies,
+ and wrong autoconf tests on various platforms--Solaris & HP-UX 10.20
+ being the predominantly reported platforms
+2) Fixed winbindd crash bug on the IBM s390 running Linux
+3) Inclusion of enhanced Linux quota support
+4) Correctly link against Sun LDAP libraries on Solaris 8 (even through
+ there is no apparent SSL support there)
+5) POSIX conformance patches
+6) Include new configure --enable-cups option (can also be disabled even
+ if CUPS libraries are installed on the system)
+7) Set reasonable default for the "passwd program" parameter using an
+ autoconf test
+8) Added --with-winbind-auth for enabling winbindd_pam_auth_crap() code
+9) fixed bug to prevent root account from being deleted by the
+ "delete user script"
+10) Inclusion of autoconf script for building VFS modules
+11) Add new run time options to the VFS recycle bin library (see
+ examples/VFS/recycle/README for details)
+12) Include findsmb perl script as part of the "make install" process
+13) Return correct error code for EnumPrinters(PRINTER_ENUM_REMOTE, InfoLevel1)
+ to fix a bug where printers appear at the workgroup level in the Windows
+ NT/2k APW browse list
+14) Added support to nmblookup to return NMB flags (See nmblookup(8) for
+ details)
+15) Fix length bug that caused password changes from Windows NT/2k clients to
+ occasionally fail
+16) Correct false password expiration when using --with-ldapsam caused by
+ missing attributes in the directory
+17) added -S option to smbpasswd for storing the SID of a domain controller
+ as the local machine SID in secrets.tdb. See the smbpasswd(8) man page
+ for details.
+18) Various fixes for UNIX CIFS extensions commands
+19) Fixed CIDR notation in "hosts allow/deny"
+20) Change semantics of an idle connection to mean "no open files and no
+ open handles". We cannot idle a connection if there are open named
+ pipe handles. This fixes scalability problem on Samba print servers
+ and NT/2k clients introduced in 2.2.4
+21) Fix germam umlaut problem when returning ACL entries
+22) Return NT_STATUS_OBJECT_NAME_NOT_FOUND for ENOENT. This fixes the bug
+ of running the Microsoft Access executable (msaccess.exe) and database
+ files from a Samba share documented in the 2.2.4 release
+23) Corrected signal handling relating to directory change notification and
+ kernel oplocks
+24) Fix bug in unix_to_nt_time() that appeared on files dated close to Daylight
+ Savings Time
+25) Corrected alignment bug in spoolss parsing code which caused Win2k/XP
+ clients not to be able to view printer properties from a Samba host
+26) Fixed spoolss parsing bug causing printing from ACT! 2000 running on
+ Windows 2k/XP clients to fail
+27) Fixed incorrect error check in mod_share_entry()
+28) Allow %S variable in MS-DFS root paths
+29) Correct a bug regarding the use of 'wbinfo -A'
+30) Fixed libnss_wins.so to correctly work on RedHat 7.3 systems
+31) Store the key for a name-to-sid cache entry in upper case rather than
+ whatever case the request was made in. This gets rid of duplicate
+ cache entries.
+32) Fix bug causing the pid stored in winbindd's pid file to be the wrong id
+33) Enhanced error reporting messages of wbinfo
+34) Parameterize block size on disk size return
+35) Added new parameter to allow incoming ACLs to have owner and group forced
+ to the currently logged in user. This fixes the XCOPY /O problem
+36) Fixed bug in local_change_password() caused by reusing a struct
+ passwd* pointer
+37) Change default value for "ldap port" to 389 if "ldap ssl = no"
+38) Updated HOWTO's, manpages, and general documentation....
+39) Allow root as well as domain admins to open an LDAP connection
+40) Fixed veto files bug with ".*"
+41) Fixed uninitialized variable bug in smbpasswd that was causing a random
+ IP address to be used in the connection when joining a domain
+42) Fix for joining a domain with a netbios name of 15 characters and
+ pre-creating the account on the DC
+43) Added links to new documentation on SWAT welcome page
+
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.4 follow :
+
+There have been several fixes and internal enhancements which include:
+
+ * More/better SPOOLSS printing functionality for Windows
+ NT/2k/XP clients.
+ * Several fixes relating to serving PC database files such
+ as (Access and FoxPro) from a Samba file share.
+ * Several improves in Samba's VFS layer which can be seen
+ in the inclusion of a "Recycle Bin" vfs module. See
+ examples/VFS/README for more details on this.
+ * Addition of a tool (tdbbackup) for backup/restore of Samba's
+ tdb's
+ * Continued improvements to winbind for greater scalability
+ and stability
+ * Several fixes related to Samba's MS-DFS support
+ * Rpcclient's various printer commands now work (again)
+
+
+New/Changed parameters in 2.2.4
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf(5).
+
+Added/changed parameters
+------------------------
+
+* csc policy
+* inherit acls
+* nt status support
+* lock spin count
+* lock spin time
+* pid directory
+* winbind use default domain
- [global]
- ...
- idmap backend = ldap:ldap://onterose/
- ldap idmap suffix = ou=idmap,dc=plainjoe,dc=org
- idmap uid = 40000-50000
- idmap gid = 40000-50000
-This configuration allows winbind installations on multiple servers to
-share a uid/gid number space, thus avoiding the interoperability problems
-with NFS that were present in Samba 2.2.
-
+Deprecated parameters
+---------------------
+The following parameters have been marked as deprecated
+and will be removed in Samba 3.0
-######################################################################
-Trust Relationships and a Samba Domain
-######################################
+* postscript
+* printer driver
+* printer driver file
+* printer driver location
-Samba 3.0.0beta2 is able to utilize winbindd as the means of
-allocating uids and gids to trusted users and groups. More
-information regarding Samba's support for establishing trust
-relationships can be found in the Samba-HOWTO-Collection included
-in the docs/ directory of this release.
-First create your Samba PDC and ensure that everything is
-working correctly before moving on the trusts.
+Removed Parameters
+------------------
-To establish Samba as the trusting domain (named SAMBA) from a Windows NT
-4.0 domain named WINDOWS:
+ none
+
+
+Changes in 2.2.4
+----------------
+
+See the cvs log for SAMBA_2_2 for more details
+
+1) added -c option to smbpasswd
+2) reworked smbpasswd internal command line option parsing
+3) small various bug fixes to experimental pdb_tdb.c
+4) Enforce spoolss RPCs based on the access granted at PrinterOpen()
+5) Added missing access checks to [add/delete/set]form
+6) Compile fixes for pam_smbpass
+7) fix smbd crash when netbios session request fails from
+ spoolss_connect_to_client().
+8) fixed logic bug that prevent SetPrinter() from storing devmode
+9) Removed extra get_printer_snum() calls from set_printer_hnd_name()
+10) fix joining domain on big endian machine when using -U to smbpasswd
+11) allow command line arg to override smb.conf log level
+12) continue to retry to register 1b name with wins server if there is an old IP there
+13) fix smbclient print crash bug
+14) 9x pnp fix when the config file and driver file are different
+15) force testparm to print the correct value for log level
+16) fix swat to show full log level info
+17) fix server GetPrinterData() fields to be more sensible
+18) fix logic error in SetPrinterDataEx()
+19) Only set smb_read_error if not already set
+20) Fix string returns that require unicode
+21) Merge of printing performance fixes from appliance
+22) lpq parsing fixes
+23) Back port tridge's xcopy /o fix from HEAD
+24) Fix the printer change notify code (unfinished)
+25) Patch for Domain users not showing up
+26) Fixed SetPrinterData(magic key) to support zero length DEVMODE
+27) Ensure that all methods of looking up and connecting to DC's work
+ using identical logic.
+28) Merge in the mutex code to stop multiple domain logon failure
+29) Ignore 0/0 lock
+30) Fix winbindd to respect command line debuglevel as nmbd/smbd
+31) Update with tdbbackup from HEAD
+32) Fix for typo on solaris nss
+33) Merge in the locking changes from HEAD
+34) Added POSIX ACL layer into the vfs
+35) Fix the returning of domain enum
+36) Fix the generation of the MACHINE.SID file into the secrets.tdb.
+37) Enable test for -rdynamic when building binaries
+38) Remove the "stat open" code - make it inline
+39) Fix the mp3 rename bug
+40) Fix for Explorer DFS problems on older Windows 9X machines
+41) implement OpenPrinter() opnum == 0x01
+42) Matched W2K *insane* open semantics....
+43) small fix that will prevent the "failed to marshall
+ R_NET_SAMLOGON" message in the logs
+42) don't do checking of local passdb in smbpasswd if using -r option
+43) fix "smbpasswd -j DOMAIN -r * -U Admin%XXXX" so that it doesn't
+ try to connect to a server named '*'
+44) merge rpcclient code from HEAD
+45) Ensure MACHINE.SID update done before child spawns
+46) Fix the bad path errors for mkdir so mkdir \a\b\c\d works
+47) Removed --with-vfs - always built if available
+48) Fixed psec for 2.2
+49) Fixed the handle leak in the connection management code
+50) fix disable spoolss after the switch to nt status codes
+51) Added Shirish's client side caching policy change
+52) Honor the specversion when parsing the the DEVICEMODE
+53) fix parsing bug when DEVICEMODE's private data does not end
+ on a 4 byte boundary
+54) do not idle an smbd when there is an open pipe
+55) when a new driver is added to a Samba server, cycle through
+ all printers and bump the change_id for each one bound to the driver
+56) allow smbclient to work with a FIFO as well (needed for KDE
+ ioslave)
+57) various updates to pdb_nisplus.c
+58) many small documentation updates
+59) removed many compiler warnings
+
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.3a follow :
+
+This is a minor bugfix release for the 2.2.3 release. The 2.2.3
+release had a problem that was visible to Windows 2000 Explorer
+users in that copying files into a share that already existed
+failed with "Access Denied" rather than asking the user if an
+overwrite was required. This was due to an incorrect error mapping
+between the UNIX EXIST error code and the NT status error.
+
+As Windows Explorer is a highly visible end user application a quick
+bugfix release was required, hence 2.2.3a.
+
+Compilation on HP-UX versions earlier than HP-UX 11 has also been
+corrected.
+
+The cvs.log file is no longer included with this release, as it adds
+13Mb to the size of the release, and is easily available on the Web.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.3 follow :
+
+There are several important scaling bugs that have been fixed in this release
+for large server systems so an upgrade is recommended.
+
+LDAP update
+-----------
+
+Much work has been done on the LDAP backend code. The configure
+option --with-ldapsam is now considered to be stable. The schema
+used has changed, see the file examples/LDAP/samba.schema for the
+new schema.
+
+New documentation explaining how to set up a Samba only PDC/BDC
+setup has been added in the files Samba-LDAP-HOWTO and Samba-BDC-HOWTO
+in the documentation tree.
+
+winbindd daemon extended
+------------------------
- 1) create the trust account for SAMBA in "User Manager for Domains"
- 2) connect the trust from the Samba domain using
- 'net rpc trustdom establish GLASS'
+Samba 2.2.2 was the first release to include the winbind daemon.
+This code allows UNIX systems that implement the name service
+switch (nss) to be entered into a Windows NT/2000 domain and
+use the Domain controller for all user and group enumeration.
+
+Samba 2.2.3 fixes the known memory leaks in winbindd and has
+been extended to work with SGI IRIX and HP-UX (11.x) in addition
+to the earlier targets of Linux and Solaris.
+
+For more information on using winbind, see the man pages for
+winbindd and wbinfo.
+
+Note that winbindd is not installed by default.
+
+New/Changed parameters in 2.2.3
+--------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf.
+
+Added/changed parameters.
+-------------------------
+
+unix extensions
+
+Enables the experimental UNIX CIFS extensions in smbd. See the manpage
+for more details.
+
+default devmode
+
+Some printer drivers will crash the Windows NT/2000 spooler service
+if they are given a default devmode, some require it. This parameter
+allows the administrator a choice of whether smbd returns such a
+default devmode for a driver.
+
+share modes
+
+This parameter has been restored to allow people who wish smbd to ignore
+client share modes. This is *very dangerous* and should not be set without
+full knowledge of what this is designed for.
+
+Changes in 2.2.3
+-----------------
+
+1). Fixed shared library compile for Solaris with native compiler.
+2). UNIX CIFS extensions code added (donated by HP).
+3). Changed to using NT status codes on the wire if the client can support
+this.
+4). altname command to show 8.3 name added to smbclient.
+5). const-safe endian macros now used.
+6). client code now uses UNICODE on the wire.
+7). Correctly return fault PDU's on bad handle.
+8). Improved NT error code mapping table.
+9). Many new point and print RPC calls added.
+10). Win9x clients can now see full user list.
+11). field added to identify simultaneous open files (no longer
+use dev/inode/time as unique value).
+12). HP-UX ACL code added (donated by HP).
+13). vfs interfaces updated (again !).
+14). MSDOS Code Page 866 -> 1251 mapping added.
+15). winbindd now processes quit/hup signals correctly.
+16). No tdb traversal done on startup/shutdown - ensures scalability.
+17). Fix bug with paths for homes share.
+18). Fixed copyfile for OS/2.
+19). Fix group membership when groups are on more than one line.
+20). Fixed core dumps in posix ACL mapping code.
+21). Tidyup of UNICODE functions (put/get).
+22). Move rpcclient to the new libsmb code.
+23). Add missing Windows 2000 passthough trans2 calls.
+24). Return check all tdb calls.
+25). Make local name lookup work even if wins server is down.
+26). pam session code added to winbind.
+27). Added winbindd cache to all lookups.
+28). Fix allocate bugs that caused file sizes to be incorrect.
+29). Fixed write cache code - now safe to use.
+30). Fixed winbindd memory leaks.
+31). winbindd will now do name lookups (to allow non Open Source
+systems to do the nsswitch WINS lookup). Fixed by SGI.
+32). passdb memory leaks fixed.
+33). LDAP code updates and now properly maintained.
+34). Finally figured out how changeid is meant to work.
+35). Downlevel printing now looks as NT does in print monitor window.
+36). Many fixups in spoolss printing RPC parsing.
+37). Speed up password enumeration as a PDC.
+38). Fix printer changed notify messages (work from HP).
+39). Fix modify timestamp on close code.
+40). Fix long standing mangled names bug.
+41). Fix delete on close semantics.
+42). Stop opening all files with O_NONBLOCK !
+43). Use O_NOFOLLOW for systems that have it and don't want symlinks.
+44). Ensure NT supplementary groups get added to user token.
+45). Try and mitigate effects of DNS timeout (do less lookups).
+46). Added current user connection context stack.
+47). Fixes to utmp code.
+48). smbw code tidyups.
+49). Added tdb open log code. Several tdb fixes.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.2 follow :
+
+New daemon included - winbindd
+------------------------------
+
+Samba 2.2.2 is the first release to include the winbind daemon.
+This code allows UNIX systems that implement the name service
+switch (nss) to be entered into a Windows NT/2000 domain and
+use the Domain controller for all user and group enumeration.
+
+This allows a Samba server added to a Windows domain to serve
+file and print services with *NO* local users needed in /etc/passwd
+and /etc/group - all users and groups are read directly from the
+Windows domain controller. In addition with pam_winbind which allows
+a PAM enabled UNIX system to use a Windows domain for authentication
+service this allows single sign on and account control across
+UNIX and Windows systems.
+
+The current version of winbindd shipped in 2.2.2 does have some
+memory leaks, which will be addressed for the next Samba release,
+so it is advisable to monitor the winbind process. This code is
+being used in production by several vendors, so the leaks are
+manageable. In addition, this version of winbind does not work
+correctly against a Samba PDC, due to some missing calls on the
+PDC side. These problems are being addressed for the next Samba
+release, but it was thought better to release the code now rather
+than delay the main Samba code to match the winbind release schedule.
+
+For more information on using winbind, see the man pages for
+winbindd and wbinfo.
+
+Note that winbindd is not installed by default.
+
+New/Changed parameters in 2.2.2
+-------------------------------
+
+For more information on these parameters, see the man pages for
+smb.conf.
+
+Added/changed parameters.
+-------------------------
+
+strict allocate
+
+Causes Samba not to create UNIX 'sparse' files, but to follow the
+Windows behavior of always allocating on-disk space.
+
+use mmap
+
+Set to 'on' by default, only set to 'off' on HP-UX 11.x or below or other
+UNIX systems that don't have coherent mmap/read-write internal caches.
+You should not need to set this parameter.
+
+nt acl support
+
+This parameter has been changed to a per-share option, and is very
+useful in enabling Windows 2000 SP2 to load/save profiles from a
+Samba share.
+
+New printing parameters.
+------------------------
-To create a trustlationship with SAMBA as the trusted domain:
+disable spoolss
- 1) create the initial trust account for GLASS using
- 'smbpasswd -a -i GLASS'. You may need to create a UNIX
- account for GLASS$ prior to this step (depending on your
- local configuration).
- 2) connect the trust from a WINDOWS DC using "User Manager
- for Domains"
+Setting this parameter causes Samba to go back to the old 2.0.x
+LANMAN printing behavior, for people who wish to disable the
+new SPOOLSS pipe.
-Now join winbindd on the Samba PDC to the SAMBA domain using
-the normal steps for adding a Samba server to an NT4 domain:
-(note that smbd & nmbd must be running at this point)
+use client driver
- root# net rpc join -U root
- Password: <enter root password from smbpasswd file here>
+Causes Windows NT/2000 clients to need have a local printer driver
+installed and to treat the printer as local.
-Start winbindd and test the join with 'wbinfo -t'.
+New LDAP parameters.
+--------------------
-Now test the trust relationship by connecting to the SAMBA DC
-(e.g. POGO) as a user from the WINDOWS domain:
+Samba 2.2.2 contains new code to maintain a Samba SAM database
+on a remote LDAP server. These parameters have been added as
+part of this code. These parameters are only available when Samba
+has been compiled with the --with-ldapsam option.
- $ smbclient //pogo/netlogon -U Administrator -W WINDOWS
- Password:
+ldap admin dn
+ldap ssl
-Now connect to the WINDOWS DC (e.g. CRYSTAL) as a Samba user:
+New SSL parameters.
+-------------------
- $ smbclient //crystal/netlogon -U root -W WINDOWS
- Password:
+The SSL support in Samba has been fixed. These new parameters
+are part of the changes added. These parameters are only available
+when Samba has been compiled with the --with-ssl option.
+Please see the smb.conf man page for details.
-######################################################################
-Changes in Winbind
-##################
+ssl egd socket
+ssl entropy file
+ssl entropy bytes
-Beginning with Samba3.0.0beta3, winbindd has been given new account
-manage functionality equivalent to the 'add user script' family of
-smb.conf parameters. The idmap design has also been changed to
-centralize control of foreign SID lookups and matching to UNIX
-uids and gids.
+New winbindd parameters.
+------------------------
+These parameters are used by winbindd. See the man page for
+winbindd for details.
-Brief Description of Changes
-----------------------------
+winbind separator
+winbind uid
+winbind gid
+winbind cache time
+winbind enum users
+winbind enum groups
+template homedir
+template shell
-1) The sid_to_uid() family of functions (smbd/uid.c) have been
- reverted to the 2.2.x design. This means that when resolving a
- SID to a UID or similar mapping:
+Removed parameters.
+-------------------
+
+share modes
+ldap root
+ldap root passwd
- a) First consult winbindd
- b) perform a local lookup only if winbindd fails to
- return a successful answer
+New Documentation.
+------------------
+
+Some new README's have been added in the docs/ directory. These cover
+using roving profiles with Windows 2000 SP2 (docs/README.Win2kSP2),
+and how to use Samba to help prevent Windows virus spread
+(docs/README.Win32-Viruses).
+
+Quota problems on a Linux 2.4 kernel.
+-------------------------------------
+
+Currently the quota interfaces have diverged between the Linus
+2.4.x kernels and the Alan Cox 2.4.x kernels (the Alan Cox variants
+are shipped with RedHat). Running quota-enabled Samba compiled on
+an Alan Cox kernel works correctly on an Alan Cox kernel (the one
+shipped by default with RedHat 7.x) but fails on a Linus kernel.
+
+This is a mess, and hopefully Alan and Linus will sort it out soon.
+In the meantime we need to ship.....
+
+Changes in 2.2.2
+-----------------
+
+1). mmap tdb code disabled on HP-UX. This should prevent the reports of
+tdb corruption on HUPX.
+2). Large file support set to off in Solaris 5.5 and below.
+3). Better CUPS detection.
+4). New SAM (password database) backends - smbpasswd (traditional),
+LDAP, NIS+ and Samba TDB.
+5). Quota fixups on Linux.
+6). libsmbclient stand-alone code added. Can be built as a shared library
+under Linux.
+7). Tru64 ACL support added.
+8). winbindd option added.
+9). Realloc fail tidyup fixes all over the code.
+10). Large improvement in hash table code efficiency - would be found with
+large stat caches.
+11). Error code consistency improved (still needs more work).
+12). Profile shared memory support added to nmbd.
+13). New Windows 2000/NT passthrough info levels added.
+14). readraw/writeraw code rewritten - many bugs fixed.
+15). UNIX password sync (non pam) code fixed, use correct wildcard matcher.
+16). Reverse DNS lookup avoided on socket open.
+17). Bug preventing nmbd re-registering names on WINS server timeout fixed.
+18). Zero length byte range lock code added. Much closer to Windows semantics.
+19). Alignment fault fixes for Linux/Alpha.
+20). Error checking on tdb returns vastly improved.
+21). Handling of delete on close fixed. No longer possible to leave 'dead'
+file entries.
+22). Handling of oplock break failure cleanups improved. Should not be
+able to leave 'dead' entries.
+23). Fix handling of errors trying to set 64 bit locks on 32 bit NFS mounts.
+24). Misc. MS-DFS code fixes.
+25). Ignore logon packets if not a PDC (needed for PDC/BDC failover).
+26). winbind pam module added.
+27). Order N^^2 enumeration of printers problem fixed.
+28). Password backend database code re-ordered to allow different password
+backends (at compile time currently).
+29). Improved print driver version detection for Windows 2000.
+30). Driver DEVMODE initialization fixes.
+31). Improved SYSV print parse code.
+32). Fixed enumeration of large numbers of users/groups from Windows clients.
+Code still too slow.
+33). Fix for buggy NetApp RPC pipe clients.
+34). Fix for NT sending multiple SetPrinterDataEx calls.
+35). Fix for logic bug where smbd could delay oplock break request messages
+from other smbd daemons whilst client kept us busy.
+36). Fix deadlock problem with connections tdb on enumeration.
+37). Fixes for setting/getting NT ACLs - improved POSIX mapping both ways.
+38). Removed unused readbmpx/writebmpx code.
+39). Attempt to fix Linux 2.4.x quota mess.
+40). Improved ctemp code for Windows 2000 compatibility.
+41). Finally understood difference between set EOF and set allocation requests.
+Added strict allocate parameter to help.
+42). Correctly return name types on name to SID lookups.
+43). tdb spinlock code update.
+44). Use pread/pwrite on systems that have it to fix race condition in tdb code.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.1a follow :
+
+This is a minor bugfix release for 2.2.1, *NOT* security related.
+
+1). 2.2.1 had a bug where using smbpasswd -m to add a Windows NT or
+Windows2000 machine into a Samba hosted PDC would fail due to our
+stricter user name checking. We were disallowing user names
+containing '$', which is needed when using smbpasswd to add a
+machine into a domain. Automatically adding machines (using the
+native Windows tools) into a Samba domain worked correctly.
+
+2.2.1a fixes this single problem.
+
+-----------------------------------------------------------------------------
+The release notes for 2.2.1 follow :
+
+New/Changed parameters in 2.2.1
+-------------------------------
+
+Added parameters.
+-----------------
+
+obey pam restrictions
+
+When Samba is configured to use PAM, turns on or off Samba checking
+the PAM account restrictions. Defaults to off.
+
+pam password change
+
+When Samba is configured to use PAM, turns on or off Samba passing
+the password changes to PAM. Defaults to off.
+
+large readwrite
+
+New option to allow new Windows 2000 large file (64k) streaming
+read/write options. Needs a 64 bit underlying operating system
+(for Linux use kernel 2.4 with glibc 2.2 or above). Can improve performance
+by 10% with Windows 2000 clients. Defaults to off. Not as tested
+as some other Samba code paths.
+
+hide unreadable
+
+Prevents clients from seeing the existence of files that cannot
+be read. Off by default.
+
+enhanced browsing
+
+Turn on/off the enhanced Samba browsing functionality (*1B names).
+Default is "on". Can prevent eternal machines in workgroups when
+WINS servers are not synchronized.
+
+Removed parameters.
+-------------------
- There are some variations to this, but these two rules generally
- apply.
+domain groups
+domain admin users
+domain guest users
+
+Changes in 2.2.1
+-----------------
+
+1). "find" command removed for smbclient. Internal code now used.
+2). smbspool updates to retry connections from Michael Sweet.
+3). Fix for mapping 8859-15 characters to UNICODE.
+4). Changed "security=server" to try with invalid username to prevent
+ account lockouts.
+5). Fixes to allow Windows 2000 SP2 clients to join a Samba PDC.
+6). Support for Windows 9x Nexus tools to allow security changes from Win9x.
+7). Two locking fixes added. Samba 2.2.1 now passes the Clarion network
+ lock tester tool for distributed databases.
+8). Preliminary support added for Windows 2000 large file read/write SMBs.
+9). Changed random number generator in Samba to prevent guess attacks.
+10). Fixes for tdb corruption in connections.tdb and file locking brlock.tdb.
+ smbd's clean the tdb files on startup and shutdown.
+11). Fixes for default ACLs on Solaris.
+12). Tidyup of password entry caching code.
+13). Correct shutdowns added for send fails. Helps tdb cleanup code.
+14). Prevent invalid '/' characters in workgroup names.
+15). Removed more static arrays in SAMR code.
+16). Client code is now UNICODE on the wire.
+17). Fix 2 second timestamp resolution everywhere if dos timestamp set to yes.
+18). All tdb opens now going through logging function.
+19). Add pam password changing and pam restrictions code.
+20). Printer driver management improvements (delete driver).
+21). Fix difference between NULL security descriptors and empty
+ security descriptors.
+22). Fix SID returns for server roles.
+23). Allow Windows 2000 mmc to view and set Samba share security descriptors.
+24). Allow smbcontrol to forcibly disconnect a share.
+25). tdb fixes for HP-UX, OpenBSD and other OS's that don't have a coherent
+ mmap/file read/write cache.
+26). Fix race condition in returning create disposition for file create/open.
+27). Fix NT rewriting of security descriptors to their canonical form for
+ ACLs.
+28). Fix for Samba running on top of Linux VFAT ftruncate bug.
+29). Swat fixes for being run with xinetd that doesn't set the umask.
+30). Fix for slow writes with Win9x Explorer clients. Emulates Microsoft
+ TCP stack early ack specification error.
+31). Changed lock & persistent tdb directory to /var/cache/samba by default on
+ RedHat and Mandrake as they clear the /var/lock/samba directory on reboot.
-2) All idmap lookups have been moved into winbindd. This means that
- a server must run winbindd (and support NSS) in order to achieve
- any mappings of SID to dynamically allocated UNIX ids. This was
- a conscious design choice.
+-----------------------------------------------------------------------------
+The release notes for 2.2.0a follow :
-3) New functions have been added to winbindd to emulate the 'add user
- script' family of smbd functions without requiring that external
- scripts be defined. This functionality is controlled by the 'winbind
- enable local accounts' smb.conf parameter (enabled by default).
+SECURITY FIX
+============
- However, this account management functionality is only supported
- in a local tdb (winbindd_idmap.tdb). If these new UNIX accounts
- must be shared among multiple Samba servers (such as a PDC and BDCs),
- it will be necessary to define your own 'add user script', et. al.
- programs that place the accounts/groups in some form of directory
- such as NIS or LDAP. This requirement was deemed beyond the scope
- of winbind's account management functions. Solutions for
- distributing UNIX system information have been deployed and tested
- for many years. We saw no need to reinvent the wheel.
+This is a security bugfix release for Samba 2.2.0. This release provides the
+following two changes *ONLY* from the 2.2.0 release.
-4) A member of a Samba controlled domain running winbindd is now able
- to map domain users directly onto existing UNIX accounts while still
- automatically creating accounts for trusted users and groups. This
- behavior is controlled by the 'winbind trusted domains only' smb.conf
- parameter (disabled by default to provide 2.2.x winbind behavior).
+1). Fix for the security hole discovered by Michal Zalewski (lcamtuf@bos.bindview.com)
+ and described in the security advisory below.
+2). Fix for the hosts allow/hosts deny parameters not being honoured.
-5) Group mapping support is wrapped in the local_XX_to_XX() functions
- in smbd/uid.c. The reason that group mappings are not included
- in winbindd is because the purpose of Samba's group map is to
- match any Windows SID with an existing UNIX group. These UNIX
- groups can be created by winbindd (see next section), but the
- SID<->gid mapping is retreived by smbd, not winbindd.
+No other changes are being made for this release to ensure a security fix only.
+For new functionality (including these security fixes) download Samba 2.2.1
+when it is available.
+The security advisory follows :
-Examples
---------
-* security = server running winbindd to allocate accounts on demand
+ IMPORTANT: Security bugfix for Samba
+ ------------------------------------
-* Samba PDC running winbindd to handle the automatic creation of UNIX
- identities for machine trust accounts
+June 23rd 2001
-* Automtically creating UNIX user and groups when migrating a Windows NT
- 4.0 PDC to a Samba PDC. Winbindd must be running when executing
- 'net rpc vampire' for this to work.
-
-######################################################################
-Known Issues
-############
+Summary
+-------
-* There are several bugs currently logged against the 3.0 codebase
- that affect the use of NT 4.0 GUI domain management tools when run
- against a Samba 3.0 PDC. This bugs should be released in an early
- 3.0.x release.
+A serious security hole has been discovered in all versions of Samba
+that allows an attacker to gain root access on the target machine for
+certain types of common Samba configuration.
-Please refer to https://bugzilla.samba.org/ for a current list of bugs
-filed against the Samba 3.0 codebase.
+The immediate fix is to edit your smb.conf configuration file and
+remove all occurances of the macro "%m". Replacing occurances of %m
+with %I is probably the best solution for most sites.
+
+Details
+-------
+
+A remote attacker can use a netbios name containing unix path
+characters which will then be substituted into the %m macro wherever
+it occurs in smb.conf. This can be used to cause Samba to create a log
+file on top of an important system file, which in turn can be used to
+compromise security on the server.
+
+The most commonly used configuration option that can be vulnerable to
+this attack is the "log file" option. The default value for this
+option is VARDIR/log.smbd. If the default is used then Samba is not
+vulnerable to this attack.
+
+The security hole occurs when a log file option like the following is
+used:
+
+ log file = /var/log/samba/%m.log
+
+In that case the attacker can use a locally created symbolic link to
+overwrite any file on the system. This requires local access to the
+server.
+
+If your Samba configuration has something like the following:
+
+ log file = /var/log/samba/%m
+
+Then the attacker could successfully compromise your server remotely
+as no symbolic link is required. This type of configuration is very
+rare.
+
+The most commonly used log file configuration containing %m is the
+distributed in the sample configuration file that comes with Samba:
+ log file = /var/log/samba/log.%m
-######################################################################
-Reporting bugs & Development Discussion
-#######################################
+in that case your machine is not vulnerable to this attack unless you
+happen to have a subdirectory in /var/log/samba/ which starts with the
+prefix "log."
-Please discuss this release on the samba-technical mailing list or by
-joining the #samba-technical IRC channel on irc.freenode.net.
+Credit
+------
-If you do report problems then please try to send high quality
-feedback. If you don't provide vital information to help us track down
-the problem then you will probably be ignored.
+Thanks to Michal Zalewski (lcamtuf@bos.bindview.com) for finding this
+vulnerability.
-A new bugzilla installation has been established to help support the
-Samba 3.0 community of users. This server, located at
-https://bugzilla.samba.org/, has replaced the older jitterbug server
-previously located at http://bugs.samba.org/.
+New Release
+-----------
+
+While we recommend that vulnerable sites immediately change their
+smb.conf configuration file to prevent the attack we will also be
+making new releases of Samba within the next 24 hours to properly fix
+the problem. Please see http://www.samba.org/ for the new releases.
+
+Please report any attacks to the appropriate authority.
+
+ The Samba Team
+ security@samba.org
+
+---------------------------------------------------------------------------
+
+The release notes for 2.2.0 follow :
+
+This is the official Samba 2.2.0 release. This version of Samba provides
+the following new features and enhancements.
+
+Integration between Windows oplocks and NFS file opens (IRIX and Linux
+2.4 kernel only). This gives complete data and locking integrity between
+Windows and UNIX file access to the same data files.
+
+Ability to act as an authentication source for Windows 2000 clients as
+well as for NT4.x clients.
+
+Integration with the winbind daemon that provides a single
+sign on facility for UNIX servers in Windows 2000/NT4 networks
+driven by a Windows 2000/NT4 PDC. winbind is not included in
+this release, it currently must be obtained separately. We are
+committed to including winbind in a future Samba 2.2.x release.
+
+Support for native Windows 2000/NT4 printing RPCs. This includes
+support for automatic printer driver download.
+
+Support for server supported Access Control Lists (ACLs).
+This release contains support for the following filesystems:
+
+ Solaris 2.6+
+ SGI Irix
+ Linux Kernel with ACL patch from http://acl.bestbits.at
+ Linux Kernel with XFS ACL support.
+ Caldera/SCO UnixWare
+ IBM AIX
+ FreeBSD (with external patch)
+
+Other platforms will be supported as resources are
+available to test and implement the necessary modules. If
+you are interested in writing the support for a particular
+ACL filesystem, please join the samba-technical mailing
+list and coordinate your efforts.
+
+On PAM (Pluggable Authentication Module) based systems - better debugging
+messages and encrypted password users now have access control verified via
+PAM - Note: Authentication still uses the encrypted password database.
+
+Rewritten internal locking semantics for more robustness.
+This release supports full 64 bit locking semantics on all
+(even 32 bit) platforms. SMB locks are mapped onto POSIX
+locks (32 bit or 64 bit) as the underlying system allows.
+
+Conversion of various internal flat data structures to use
+database records for increased performance and
+flexibility.
+
+Support for acting as a MS-DFS (Distributed File System) server.
+
+Support for manipulating Samba shares using Windows client tools
+(server manager). Per share security can be set using these tools
+and Samba will obey the access restrictions applied.
+
+Samba profiling support (see below).
+
+Compile time option for enabling a (Virtual file system) VFS layer
+to allow non-disk resources to be exported as Windows filesystems
+(such as databases etc.).
+
+The documentation in this release has been updated and converted
+from Yodl to DocBook 4.1. There are many new parameters since 2.0.7
+and some defaults have changed.
+
+Profiling support.
+------------------
+Support for collection of profile information. A shared
+memory area has been created which contains counters for
+the number of calls to and the amount of time spent in
+various system calls, smb transactions and nmbd activity. See
+the file profile.h for a complete listing of the information
+collected. Sample code for a samba pmda (collection agent
+for Performance Co-Pilot) has been included in the pcp
+directory.
+
+To enable the profile data collection code in samba, you must
+compile samba with profile data support (run configure with
+the --with-profiling-data option). On startup, collection of
+data is disabled. To begin collecting data use the smbcontrol
+program to turn on profiling (see the smbcontrol man page).
+Profile information collection can be enabled for nmbd, all smbd
+processes or one or more selected processes. The profiling
+data collected is the aggregate for all processes that have
+profiling enabled.
+
+With samba compiled for profile data collection, you may see
+a very slight degradation in performance even with profiling
+collection turned off. On initial tests with NetBench on an
+SGI Origin 200 server, this degradation was not measurable
+with profile collection off compared to no profile collection
+compiled into samba.
+
+With count profile collection enabled on all clients, the
+degradation was less than 2%. With full profile collection
+enabled on all clients, the degradation was about 8.5%.
+
+=====================================================================
+
+If you think you have found a bug please email a report to :
+
+ samba@samba.org
+
+As always, all bugs are our responsibility.
+
+Regards,
+
+ The Samba Team.
diff --git a/docs/OID/allocated-arcs.txt b/docs/OID/allocated-arcs.txt
new file mode 100755
index 00000000000..acef4930eae
--- /dev/null
+++ b/docs/OID/allocated-arcs.txt
@@ -0,0 +1,19 @@
+!===========================================================================================
+!==
+!== Allocated Arcs from the Samba Team Private Enterprise Number
+!== ISO(1) org(3) dod(6) internet(1) private(4) enterprise(1) Samba(7165)
+!==
+!== Arc allocation is maintained by jerry carter <jerry@samba.org>. Please notify
+!== me if you need an OID and update this file.
+!==
+!== File Created : Tue May 8 09:33:31 CDT 2001
+!==
+!===========================================================================================
+
+ARC Owner Contact Purpose
+--- ----- ------- -------
+.1 Plainjoe.org Jerry Carter <jerry@samba.org> Use for Plainjoe.org domain
+ and examples in O'Reilly LDAP book
+.2 Samba 2.2. Release jerry@samba.org schema for representing smbpasswd
+.3 Jean-Francois.Micouleau@dalalu.fr Experiemental SNMP fun
+
diff --git a/docs/OID/samba-oid.mail b/docs/OID/samba-oid.mail
new file mode 100755
index 00000000000..d1ad668f880
--- /dev/null
+++ b/docs/OID/samba-oid.mail
@@ -0,0 +1,27 @@
+From gruiz@icann.org Tue May 8 04:27:07 2001
+Date: Tue, 26 Sep 2000 15:29:02 -0700
+From: GIGI RUIZ <gruiz@icann.org>
+To: jerry@samba.org
+Cc: "Iana-Mib (E-mail)" <iana-mib@iana.org>
+Subject: PEN 7165 RE: Application for Enterprise-number
+
+ [ The following text is in the "iso-8859-1" character set. ]
+ [ Your display is set for the "US-ASCII" character set. ]
+ [ Some characters may be displayed incorrectly. ]
+
+Gerald,
+
+We have assigned Private Enterprise Number 7165 to SAMBA Team, with you as
+the point of contact. Please confirm the information listed below.
+
+7165 SAMBA Team Gerald Carter jerry@samba.org
+
+Sincerely,
+
+Gigi Ruiz
+Internet Assigned Numbers Authority - MIB
+
+Voice: (310) 823-9358
+Fax: (310) 823-8649
+EMAIL: iana-mib@iana.org
+
diff --git a/docs/README-NOW b/docs/README-NOW
deleted file mode 100644
index 46a772385cc..00000000000
--- a/docs/README-NOW
+++ /dev/null
@@ -1,10 +0,0 @@
- ATTENTION
- DOCS TREE REMOVED
----------------------------------------------------
-
-This docs tree has been moved to a separate CVS
-module on cvs.samba.org name 'samba-docs'.
-See http://cvs.samba.org/ for details on accessing
-Samba cvs trees.
-
-
diff --git a/docs/README.Win2kSP2 b/docs/README.Win2kSP2
new file mode 100755
index 00000000000..49a8fbf4ae1
--- /dev/null
+++ b/docs/README.Win2kSP2
@@ -0,0 +1,56 @@
+!==
+!== README.Win2kSP2
+!==
+
+Author: Gerald (Jerry) Carter <jerry@samba.org>
+
+==================================================================
+
+There are several annoyances with Windows 2000 SP2. One of which
+only appears when using a Samba server to host user profiles
+to Windows 2000 SP2 clients in a Windows domain. This assumes
+that Samba is a member of the domain, but the problem will
+likely occur if it is not.
+
+In order to server profiles successfully to Windows 2000 SP2
+clients (when not operating as a PDC), Samba must have
+
+ nt acl support = no
+
+added to the file share which houses the roaming profiles.
+If this is not done, then the Windows 2000 SP2 client will
+complain about not being able to access the profile (Access
+Denied) and create multiple copies of it on disk (DOMAIN.user.001,
+DOMAIN.user.002, etc...). See the smb.conf(5) man page
+for more details on this option. Also note that the "nt acl support"
+parameter was formally a global parameter in releases prior
+to Samba 2.2.2.
+
+The following is a minimal profile share
+
+ [profile]
+ path = /export/profile
+ create mask = 0600
+ directory mask = 0700
+ nt acl support = no
+ read only = no
+
+The reason for this bug is that the Win2k SP2 client copies
+the security descriptor for the profile which contains
+the Samba server's SID, and not the domain SID. The client
+compares the SID for SAMBA\user and realizes it is
+different that the one assigned to DOMAIN\user. Hence the reason
+for the "access denied" message.
+
+By disabling the "nt acl support" parameter, Samba will send
+the Win2k client a response to the QuerySecurityDescriptor
+trans2 call which causes the client to set a default ACL
+for the profile. This default ACL includes
+
+ DOMAIN\user "Full Control"
+
+
+NOTE : This bug does not occur when using winbind to
+create accounts on the Samba host for Domain users.
+
+
diff --git a/docs/README.Win32-Viruses b/docs/README.Win32-Viruses
new file mode 100755
index 00000000000..07f03360cbc
--- /dev/null
+++ b/docs/README.Win32-Viruses
@@ -0,0 +1,58 @@
+While this article is specific to the recent Nimda worm,
+the information can be applied to preventing the spread
+of many Win32 viruses. Thanks to the Samba Users Group of Japan
+(SUGJ) for this article.
+===============================================================================
+Steps againt Nimba Worm for Samba
+
+Author: HASEGAWA Yosuke
+Translator: TAKAHASHI Motonobu <monyo@samba.gr.jp>
+
+The information in this article applies to
+ Samba 2.0.x
+ Samba 2.2.x
+ Windows 95/98/Me/NT/2000
+
+SYMPTOMS
+ This article has described the measure against Nimba Worm for Samba
+ server.
+
+DESCRIPTION
+ Nimba Worm is infected through the shared disk on a network besides
+ Microsoft IIS, Internet Explorer and mailer of Outlook series.
+
+ At this time, the worm copies itself by the name *.nws and *.eml on
+ the shared disk, moreover, by the name of Riched20.dll in the folder
+ where *.doc file is included.
+
+ To prevent infection through the shared disk offered by Samba, set
+ up as follows:
+
+-----
+[global]
+ ...
+ # This can break Administration installations of Office2k.
+ # in that case, don't veto the riched20.dll
+ veto files = /*.eml/*.nws/riched20.dll/
+-----
+
+ Setting up "veto files" parameter, the matched files on the Samba
+ server are completely hidden from the clients and become impossible
+ to access them at all.
+
+ In addition to it, the following setting are also pointed out by the
+ samba-jp:09448 thread: when the
+ "(Jreadme.txt.{3050F4D8-98B5-11CF-BB82-00AA00BDCE0B}"(B file exists on
+ a Samba server, it is visible only with "readme.txt" and a dangerous
+ code may be performed when this file is double-clicked.
+
+ Setting the following,
+-----
+ veto files = /*.{*}/
+-----
+ no files having CLSID in its file extension can be accessed from any
+ clients.
+
+This technical article is created based on the discussion of
+samba-jp:09448 and samba-jp:10900 threads.
+
diff --git a/docs/README.ldap b/docs/README.ldap
new file mode 100755
index 00000000000..451e27b8bf3
--- /dev/null
+++ b/docs/README.ldap
@@ -0,0 +1 @@
+The schema file is stored in ../examples/LDAP/samba.schema
diff --git a/docs/Registry/NT4-Locking.reg b/docs/Registry/NT4-Locking.reg
new file mode 100755
index 00000000000..6175fd51459
--- /dev/null
+++ b/docs/Registry/NT4-Locking.reg
@@ -0,0 +1,24 @@
+REGEDIT4
+
+;Contributor: John H Terpstra <jht@samba.org>
+;Corrected: Stefan Kanthak <skanthak@nexgo.de>
+;Updated: Jun 25, 2001
+;
+;Subject: Registry Entries That Affect Locking and Caching
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters]
+"BufFilesDenyWrite"=dword:00000000
+"BufNamedPipes"=dword:00000000
+"UseOpportunisticLocking"=dword:00000000
+"DormantFileLimit"=dword:00000000
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\Linkage]
+"UtilizeNtCaching"=dword:00000000
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Filesystem]
+"Win95TruncatedExtensions"=dword:00000000
+"NTFSDisable8dot3NameCreation"=dword:00000001
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters]
+"EnableOpLockForceClose"=dword:00000001
+"EnableOpLocks"=dword:00000000
diff --git a/docs/Registry/NT4_PlainPassword.reg b/docs/Registry/NT4_PlainPassword.reg
new file mode 100755
index 00000000000..b30db150c24
--- /dev/null
+++ b/docs/Registry/NT4_PlainPassword.reg
@@ -0,0 +1,11 @@
+REGEDIT4
+
+;Contributor: Tim Small (tim.small@virgin.net)
+;Updated: 20 August 1997
+;Status: Current
+;
+;Subject: Registry file to enable plain text passwords in NT4-SP3 and later
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Rdr\Parameters]
+"EnablePlainTextPassword"=dword:00000001
+
diff --git a/docs/Registry/Win2000_PlainPassword.reg b/docs/Registry/Win2000_PlainPassword.reg
new file mode 100755
index 00000000000..e0ae280b1c2
--- /dev/null
+++ b/docs/Registry/Win2000_PlainPassword.reg
@@ -0,0 +1,11 @@
+REGEDIT4
+
+;Contributor: Herb Lewis (herb@sgi.com)
+;Updated: 16 July 1999
+;Status: Current
+;
+;Subject: Registry file to enable plain text passwords in Windows 2000
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkStation\Parameters]
+"EnablePlainTextPassword"=dword:00000001
+
diff --git a/docs/Registry/Win95_PlainPassword.reg b/docs/Registry/Win95_PlainPassword.reg
new file mode 100755
index 00000000000..9dd3103689c
--- /dev/null
+++ b/docs/Registry/Win95_PlainPassword.reg
@@ -0,0 +1,4 @@
+REGEDIT4
+
+[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VNETSUP]
+"EnablePlainTextPassword"=dword:00000001
diff --git a/docs/Registry/Win98_PlainPassword.reg b/docs/Registry/Win98_PlainPassword.reg
new file mode 100755
index 00000000000..9dd3103689c
--- /dev/null
+++ b/docs/Registry/Win98_PlainPassword.reg
@@ -0,0 +1,4 @@
+REGEDIT4
+
+[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VNETSUP]
+"EnablePlainTextPassword"=dword:00000001
diff --git a/docs/Registry/Win9X-CacheHandling.reg b/docs/Registry/Win9X-CacheHandling.reg
new file mode 100755
index 00000000000..265e335b402
--- /dev/null
+++ b/docs/Registry/Win9X-CacheHandling.reg
@@ -0,0 +1,7 @@
+REGEDIT4
+
+; Contributor: John H Terpstra <jht@samba.org>
+; Date: Feb 15, 1999
+
+[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VREDIR]
+"DiscardCacheOnOpen"=string:00000001
diff --git a/docs/Registry/WinME_PlainPassword.reg b/docs/Registry/WinME_PlainPassword.reg
new file mode 100755
index 00000000000..9dd3103689c
--- /dev/null
+++ b/docs/Registry/WinME_PlainPassword.reg
@@ -0,0 +1,4 @@
+REGEDIT4
+
+[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VNETSUP]
+"EnablePlainTextPassword"=dword:00000001
diff --git a/docs/Registry/WinXP_SignOrSeal.reg b/docs/Registry/WinXP_SignOrSeal.reg
new file mode 100755
index 00000000000..f6f4b4cd91c
--- /dev/null
+++ b/docs/Registry/WinXP_SignOrSeal.reg
@@ -0,0 +1,11 @@
+Windows Registry Editor Version 5.00
+
+;
+; This registry key is needed for a Windows XP Client to join
+; and logon to a Samba domain. Note: Samba 2.2.3a contained
+; this key in a broken format which did nothing to the registry -
+; however XP reported "registry key imported". If in doubt
+; check the key by hand with regedit.
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters]
+"requiresignorseal"=dword:00000000
diff --git a/docs/Registry/WindowsTerminalServer.reg b/docs/Registry/WindowsTerminalServer.reg
new file mode 100755
index 00000000000..73c3b177d20
--- /dev/null
+++ b/docs/Registry/WindowsTerminalServer.reg
@@ -0,0 +1,7 @@
+REGEDIT4
+
+;Subject: Registry file to force multiple NT terminal server users to have their own connections.
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Rdr\Parameters]
+"MultipleUsersOnConnection"=dword:00000000
+
diff --git a/docs/Samba-HOWTO-Collection.pdf b/docs/Samba-HOWTO-Collection.pdf
new file mode 100755
index 00000000000..72beba7291d
--- /dev/null
+++ b/docs/Samba-HOWTO-Collection.pdf
@@ -0,0 +1,3173 @@
+%PDF-1.3
+%âãÏÓ
+1 0 obj<</Producer(htmldoc 1.8.22 Copyright 1997-2002 Easy Software Products, All Rights Reserved.)/CreationDate(D:20030201112407+0600)/Title(SAMBA Project Documentation)/Creator(Modular DocBook HTML Stylesheet Version 1.57)>>endobj
+2 0 obj<</Type/Encoding/Differences[ 32/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quotesingle/parenleft/parenright/asterisk/plus/comma/minus/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/grave/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 128/Euro 130/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 145/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 159/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]>>endobj
+3 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier/Encoding 2 0 R>>endobj
+4 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier-Bold/Encoding 2 0 R>>endobj
+5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier-Oblique/Encoding 2 0 R>>endobj
+6 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier-BoldOblique/Encoding 2 0 R>>endobj
+7 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Roman/Encoding 2 0 R>>endobj
+8 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Bold/Encoding 2 0 R>>endobj
+9 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Italic/Encoding 2 0 R>>endobj
+10 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding 2 0 R>>endobj
+11 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica-Bold/Encoding 2 0 R>>endobj
+12 0 obj<</Type/Font/Subtype/Type1/BaseFont/Symbol>>endobj
+13 0 obj<</S/URI/URI(http://www.samba.org/)>>endobj
+14 0 obj<</Subtype/Link/Rect[185.6 463.0 289.8 476.0]/Border[0 0 0]/A 13 0 R>>endobj
+15 0 obj<</S/URI/URI(mailto:jerry@samba.org)>>endobj
+16 0 obj<</Subtype/Link/Rect[72.0 449.8 148.4 462.8]/Border[0 0 0]/A 15 0 R>>endobj
+17 0 obj<</S/URI/URI(http://www.fsf.org/licenses/gpl.txt)>>endobj
+18 0 obj<</Subtype/Link/Rect[72.0 397.0 223.3 410.0]/Border[0 0 0]/A 17 0 R>>endobj
+19 0 obj[14 0 R
+16 0 R
+18 0 R]endobj
+20 0 obj<</Subtype/Link/Rect[72.0 684.0 277.3 697.0]/Border[0 0 0]/Dest[700 0 R/XYZ 0 734 0]>>endobj
+21 0 obj<</Subtype/Link/Rect[108.0 670.8 249.2 683.8]/Border[0 0 0]/Dest[700 0 R/XYZ 0 696 0]>>endobj
+22 0 obj<</Subtype/Link/Rect[108.0 657.6 255.0 670.6]/Border[0 0 0]/Dest[700 0 R/XYZ 0 572 0]>>endobj
+23 0 obj<</Subtype/Link/Rect[108.0 644.4 257.7 657.4]/Border[0 0 0]/Dest[700 0 R/XYZ 0 170 0]>>endobj
+24 0 obj<</Subtype/Link/Rect[108.0 631.2 309.0 644.2]/Border[0 0 0]/Dest[702 0 R/XYZ 0 734 0]>>endobj
+25 0 obj<</Subtype/Link/Rect[108.0 618.0 313.9 631.0]/Border[0 0 0]/Dest[702 0 R/XYZ 0 385 0]>>endobj
+26 0 obj<</Subtype/Link/Rect[108.0 604.8 284.9 617.8]/Border[0 0 0]/Dest[702 0 R/XYZ 0 287 0]>>endobj
+27 0 obj<</Subtype/Link/Rect[108.0 591.6 280.0 604.6]/Border[0 0 0]/Dest[702 0 R/XYZ 0 137 0]>>endobj
+28 0 obj<</Subtype/Link/Rect[108.0 578.4 328.6 591.4]/Border[0 0 0]/Dest[704 0 R/XYZ 0 313 0]>>endobj
+29 0 obj<</Subtype/Link/Rect[108.0 565.2 362.2 578.2]/Border[0 0 0]/Dest[706 0 R/XYZ 0 734 0]>>endobj
+30 0 obj<</Subtype/Link/Rect[108.0 552.0 315.8 565.0]/Border[0 0 0]/Dest[706 0 R/XYZ 0 569 0]>>endobj
+31 0 obj<</Subtype/Link/Rect[108.0 538.8 511.6 551.8]/Border[0 0 0]/Dest[706 0 R/XYZ 0 405 0]>>endobj
+32 0 obj<</Subtype/Link/Rect[108.0 525.6 259.4 538.6]/Border[0 0 0]/Dest[706 0 R/XYZ 0 198 0]>>endobj
+33 0 obj<</Subtype/Link/Rect[108.0 512.4 236.0 525.4]/Border[0 0 0]/Dest[708 0 R/XYZ 0 692 0]>>endobj
+34 0 obj<</Subtype/Link/Rect[108.0 499.2 186.5 512.2]/Border[0 0 0]/Dest[708 0 R/XYZ 0 633 0]>>endobj
+35 0 obj<</Subtype/Link/Rect[108.0 486.0 267.2 499.0]/Border[0 0 0]/Dest[708 0 R/XYZ 0 549 0]>>endobj
+36 0 obj<</Subtype/Link/Rect[108.0 472.8 295.6 485.8]/Border[0 0 0]/Dest[708 0 R/XYZ 0 239 0]>>endobj
+37 0 obj<</Subtype/Link/Rect[108.0 459.6 177.7 472.6]/Border[0 0 0]/Dest[708 0 R/XYZ 0 128 0]>>endobj
+38 0 obj<</Subtype/Link/Rect[108.0 446.4 232.3 459.4]/Border[0 0 0]/Dest[710 0 R/XYZ 0 335 0]>>endobj
+39 0 obj<</Subtype/Link/Rect[108.0 433.2 232.6 446.2]/Border[0 0 0]/Dest[710 0 R/XYZ 0 264 0]>>endobj
+40 0 obj<</Subtype/Link/Rect[72.0 406.8 348.8 419.8]/Border[0 0 0]/Dest[712 0 R/XYZ 0 734 0]>>endobj
+41 0 obj<</Subtype/Link/Rect[108.0 393.6 161.5 406.6]/Border[0 0 0]/Dest[712 0 R/XYZ 0 672 0]>>endobj
+42 0 obj<</Subtype/Link/Rect[108.0 380.4 327.7 393.4]/Border[0 0 0]/Dest[712 0 R/XYZ 0 442 0]>>endobj
+43 0 obj<</Subtype/Link/Rect[108.0 367.2 177.1 380.2]/Border[0 0 0]/Dest[712 0 R/XYZ 0 318 0]>>endobj
+44 0 obj<</Subtype/Link/Rect[108.0 354.0 203.6 367.0]/Border[0 0 0]/Dest[714 0 R/XYZ 0 441 0]>>endobj
+45 0 obj<</Subtype/Link/Rect[108.0 340.8 195.1 353.8]/Border[0 0 0]/Dest[714 0 R/XYZ 0 303 0]>>endobj
+46 0 obj<</Subtype/Link/Rect[108.0 327.6 215.2 340.6]/Border[0 0 0]/Dest[714 0 R/XYZ 0 155 0]>>endobj
+47 0 obj<</Subtype/Link/Rect[108.0 314.4 382.4 327.4]/Border[0 0 0]/Dest[716 0 R/XYZ 0 336 0]>>endobj
+48 0 obj<</Subtype/Link/Rect[108.0 301.2 255.6 314.2]/Border[0 0 0]/Dest[718 0 R/XYZ 0 285 0]>>endobj
+49 0 obj<</Subtype/Link/Rect[108.0 288.0 224.1 301.0]/Border[0 0 0]/Dest[720 0 R/XYZ 0 734 0]>>endobj
+50 0 obj<</Subtype/Link/Rect[108.0 274.8 187.8 287.8]/Border[0 0 0]/Dest[722 0 R/XYZ 0 456 0]>>endobj
+51 0 obj<</Subtype/Link/Rect[108.0 261.6 194.5 274.6]/Border[0 0 0]/Dest[722 0 R/XYZ 0 358 0]>>endobj
+52 0 obj<</Subtype/Link/Rect[108.0 248.4 200.6 261.4]/Border[0 0 0]/Dest[722 0 R/XYZ 0 221 0]>>endobj
+53 0 obj<</Subtype/Link/Rect[108.0 235.2 523.2 248.2]/Border[0 0 0]/Dest[724 0 R/XYZ 0 667 0]>>endobj
+54 0 obj<</Subtype/Link/Rect[108.0 222.0 497.9 235.0]/Border[0 0 0]/Dest[724 0 R/XYZ 0 130 0]>>endobj
+55 0 obj<</Subtype/Link/Rect[108.0 208.8 353.3 221.8]/Border[0 0 0]/Dest[728 0 R/XYZ 0 734 0]>>endobj
+56 0 obj<</Subtype/Link/Rect[108.0 195.6 419.0 208.6]/Border[0 0 0]/Dest[728 0 R/XYZ 0 481 0]>>endobj
+57 0 obj<</Subtype/Link/Rect[108.0 182.4 332.5 195.4]/Border[0 0 0]/Dest[728 0 R/XYZ 0 126 0]>>endobj
+58 0 obj<</Subtype/Link/Rect[108.0 169.2 181.6 182.2]/Border[0 0 0]/Dest[730 0 R/XYZ 0 228 0]>>endobj
+59 0 obj<</Subtype/Link/Rect[72.0 142.8 460.7 155.8]/Border[0 0 0]/Dest[732 0 R/XYZ 0 734 0]>>endobj
+60 0 obj<</Subtype/Link/Rect[108.0 129.6 202.4 142.6]/Border[0 0 0]/Dest[732 0 R/XYZ 0 672 0]>>endobj
+61 0 obj<</Subtype/Link/Rect[108.0 116.4 244.9 129.4]/Border[0 0 0]/Dest[734 0 R/XYZ 0 140 0]>>endobj
+62 0 obj<</Subtype/Link/Rect[108.0 103.2 270.2 116.2]/Border[0 0 0]/Dest[736 0 R/XYZ 0 692 0]>>endobj
+63 0 obj[20 0 R
+21 0 R
+22 0 R
+23 0 R
+24 0 R
+25 0 R
+26 0 R
+27 0 R
+28 0 R
+29 0 R
+30 0 R
+31 0 R
+32 0 R
+33 0 R
+34 0 R
+35 0 R
+36 0 R
+37 0 R
+38 0 R
+39 0 R
+40 0 R
+41 0 R
+42 0 R
+43 0 R
+44 0 R
+45 0 R
+46 0 R
+47 0 R
+48 0 R
+49 0 R
+50 0 R
+51 0 R
+52 0 R
+53 0 R
+54 0 R
+55 0 R
+56 0 R
+57 0 R
+58 0 R
+59 0 R
+60 0 R
+61 0 R
+62 0 R]endobj
+64 0 obj<</Subtype/Link/Rect[72.0 684.0 402.3 697.0]/Border[0 0 0]/Dest[738 0 R/XYZ 0 734 0]>>endobj
+65 0 obj<</Subtype/Link/Rect[108.0 670.8 179.2 683.8]/Border[0 0 0]/Dest[738 0 R/XYZ 0 672 0]>>endobj
+66 0 obj<</Subtype/Link/Rect[108.0 657.6 161.2 670.6]/Border[0 0 0]/Dest[740 0 R/XYZ 0 652 0]>>endobj
+67 0 obj<</Subtype/Link/Rect[72.0 631.2 412.7 644.2]/Border[0 0 0]/Dest[742 0 R/XYZ 0 734 0]>>endobj
+68 0 obj<</Subtype/Link/Rect[108.0 618.0 444.7 631.0]/Border[0 0 0]/Dest[742 0 R/XYZ 0 672 0]>>endobj
+69 0 obj<</Subtype/Link/Rect[108.0 604.8 319.1 617.8]/Border[0 0 0]/Dest[742 0 R/XYZ 0 505 0]>>endobj
+70 0 obj<</Subtype/Link/Rect[108.0 591.6 231.1 604.6]/Border[0 0 0]/Dest[742 0 R/XYZ 0 341 0]>>endobj
+71 0 obj<</Subtype/Link/Rect[108.0 578.4 292.2 591.4]/Border[0 0 0]/Dest[744 0 R/XYZ 0 665 0]>>endobj
+72 0 obj<</Subtype/Link/Rect[108.0 565.2 208.5 578.2]/Border[0 0 0]/Dest[744 0 R/XYZ 0 435 0]>>endobj
+73 0 obj<</Subtype/Link/Rect[108.0 552.0 233.6 565.0]/Border[0 0 0]/Dest[744 0 R/XYZ 0 192 0]>>endobj
+74 0 obj<</Subtype/Link/Rect[108.0 538.8 301.4 551.8]/Border[0 0 0]/Dest[746 0 R/XYZ 0 692 0]>>endobj
+75 0 obj<</Subtype/Link/Rect[108.0 525.6 392.1 538.6]/Border[0 0 0]/Dest[746 0 R/XYZ 0 264 0]>>endobj
+76 0 obj<</Subtype/Link/Rect[108.0 512.4 384.2 525.4]/Border[0 0 0]/Dest[750 0 R/XYZ 0 652 0]>>endobj
+77 0 obj<</Subtype/Link/Rect[72.0 486.0 277.1 499.0]/Border[0 0 0]/Dest[752 0 R/XYZ 0 734 0]>>endobj
+78 0 obj<</Subtype/Link/Rect[108.0 472.8 181.6 485.8]/Border[0 0 0]/Dest[752 0 R/XYZ 0 696 0]>>endobj
+79 0 obj<</Subtype/Link/Rect[108.0 459.6 189.0 472.6]/Border[0 0 0]/Dest[752 0 R/XYZ 0 281 0]>>endobj
+80 0 obj<</Subtype/Link/Rect[108.0 446.4 209.7 459.4]/Border[0 0 0]/Dest[754 0 R/XYZ 0 718 0]>>endobj
+81 0 obj<</Subtype/Link/Rect[108.0 433.2 294.4 446.2]/Border[0 0 0]/Dest[756 0 R/XYZ 0 490 0]>>endobj
+82 0 obj<</Subtype/Link/Rect[108.0 420.0 275.7 433.0]/Border[0 0 0]/Dest[758 0 R/XYZ 0 734 0]>>endobj
+83 0 obj<</Subtype/Link/Rect[108.0 406.8 287.3 419.8]/Border[0 0 0]/Dest[758 0 R/XYZ 0 464 0]>>endobj
+84 0 obj<</Subtype/Link/Rect[108.0 393.6 350.9 406.6]/Border[0 0 0]/Dest[760 0 R/XYZ 0 734 0]>>endobj
+85 0 obj<</Subtype/Link/Rect[108.0 380.4 242.1 393.4]/Border[0 0 0]/Dest[760 0 R/XYZ 0 464 0]>>endobj
+86 0 obj<</Subtype/Link/Rect[108.0 367.2 220.1 380.2]/Border[0 0 0]/Dest[760 0 R/XYZ 0 287 0]>>endobj
+87 0 obj<</Subtype/Link/Rect[108.0 354.0 214.3 367.0]/Border[0 0 0]/Dest[760 0 R/XYZ 0 136 0]>>endobj
+88 0 obj<</Subtype/Link/Rect[108.0 340.8 281.2 353.8]/Border[0 0 0]/Dest[762 0 R/XYZ 0 679 0]>>endobj
+89 0 obj<</Subtype/Link/Rect[108.0 327.6 222.3 340.6]/Border[0 0 0]/Dest[762 0 R/XYZ 0 594 0]>>endobj
+90 0 obj<</Subtype/Link/Rect[108.0 314.4 234.5 327.4]/Border[0 0 0]/Dest[762 0 R/XYZ 0 496 0]>>endobj
+91 0 obj<</Subtype/Link/Rect[108.0 301.2 300.2 314.2]/Border[0 0 0]/Dest[764 0 R/XYZ 0 613 0]>>endobj
+92 0 obj<</Subtype/Link/Rect[108.0 288.0 383.0 301.0]/Border[0 0 0]/Dest[764 0 R/XYZ 0 232 0]>>endobj
+93 0 obj<</Subtype/Link/Rect[72.0 261.6 290.8 274.6]/Border[0 0 0]/Dest[766 0 R/XYZ 0 734 0]>>endobj
+94 0 obj<</Subtype/Link/Rect[108.0 248.4 284.0 261.4]/Border[0 0 0]/Dest[766 0 R/XYZ 0 696 0]>>endobj
+95 0 obj<</Subtype/Link/Rect[108.0 235.2 270.2 248.2]/Border[0 0 0]/Dest[766 0 R/XYZ 0 611 0]>>endobj
+96 0 obj<</Subtype/Link/Rect[108.0 222.0 537.9 235.0]/Border[0 0 0]/Dest[766 0 R/XYZ 0 268 0]>>endobj
+97 0 obj<</Subtype/Link/Rect[108.0 208.8 525.3 221.8]/Border[0 0 0]/Dest[768 0 R/XYZ 0 734 0]>>endobj
+98 0 obj<</Subtype/Link/Rect[108.0 195.6 319.5 208.6]/Border[0 0 0]/Dest[768 0 R/XYZ 0 734 0]>>endobj
+99 0 obj<</Subtype/Link/Rect[108.0 182.4 355.2 195.4]/Border[0 0 0]/Dest[768 0 R/XYZ 0 183 0]>>endobj
+100 0 obj<</Subtype/Link/Rect[108.0 169.2 293.2 182.2]/Border[0 0 0]/Dest[770 0 R/XYZ 0 639 0]>>endobj
+101 0 obj<</Subtype/Link/Rect[108.0 156.0 270.6 169.0]/Border[0 0 0]/Dest[772 0 R/XYZ 0 734 0]>>endobj
+102 0 obj<</Subtype/Link/Rect[108.0 142.8 189.9 155.8]/Border[0 0 0]/Dest[772 0 R/XYZ 0 213 0]>>endobj
+103 0 obj<</Subtype/Link/Rect[72.0 116.4 272.9 129.4]/Border[0 0 0]/Dest[778 0 R/XYZ 0 734 0]>>endobj
+104 0 obj<</Subtype/Link/Rect[108.0 103.2 299.9 116.2]/Border[0 0 0]/Dest[778 0 R/XYZ 0 696 0]>>endobj
+105 0 obj<</Subtype/Link/Rect[108.0 90.0 288.0 103.0]/Border[0 0 0]/Dest[780 0 R/XYZ 0 362 0]>>endobj
+106 0 obj<</Subtype/Link/Rect[108.0 76.8 307.9 89.8]/Border[0 0 0]/Dest[780 0 R/XYZ 0 158 0]>>endobj
+107 0 obj[64 0 R
+65 0 R
+66 0 R
+67 0 R
+68 0 R
+69 0 R
+70 0 R
+71 0 R
+72 0 R
+73 0 R
+74 0 R
+75 0 R
+76 0 R
+77 0 R
+78 0 R
+79 0 R
+80 0 R
+81 0 R
+82 0 R
+83 0 R
+84 0 R
+85 0 R
+86 0 R
+87 0 R
+88 0 R
+89 0 R
+90 0 R
+91 0 R
+92 0 R
+93 0 R
+94 0 R
+95 0 R
+96 0 R
+97 0 R
+98 0 R
+99 0 R
+100 0 R
+101 0 R
+102 0 R
+103 0 R
+104 0 R
+105 0 R
+106 0 R]endobj
+108 0 obj<</Subtype/Link/Rect[72.0 684.0 416.3 697.0]/Border[0 0 0]/Dest[784 0 R/XYZ 0 734 0]>>endobj
+109 0 obj<</Subtype/Link/Rect[108.0 670.8 219.2 683.8]/Border[0 0 0]/Dest[784 0 R/XYZ 0 672 0]>>endobj
+110 0 obj<</Subtype/Link/Rect[108.0 657.6 181.0 670.6]/Border[0 0 0]/Dest[784 0 R/XYZ 0 587 0]>>endobj
+111 0 obj<</Subtype/Link/Rect[108.0 644.4 316.1 657.4]/Border[0 0 0]/Dest[786 0 R/XYZ 0 718 0]>>endobj
+112 0 obj<</Subtype/Link/Rect[108.0 631.2 430.0 644.2]/Border[0 0 0]/Dest[788 0 R/XYZ 0 613 0]>>endobj
+113 0 obj<</Subtype/Link/Rect[108.0 618.0 333.2 631.0]/Border[0 0 0]/Dest[788 0 R/XYZ 0 251 0]>>endobj
+114 0 obj<</Subtype/Link/Rect[108.0 604.8 362.5 617.8]/Border[0 0 0]/Dest[790 0 R/XYZ 0 409 0]>>endobj
+115 0 obj<</Subtype/Link/Rect[108.0 591.6 279.4 604.6]/Border[0 0 0]/Dest[790 0 R/XYZ 0 196 0]>>endobj
+116 0 obj<</Subtype/Link/Rect[108.0 578.4 261.4 591.4]/Border[0 0 0]/Dest[792 0 R/XYZ 0 520 0]>>endobj
+117 0 obj<</Subtype/Link/Rect[108.0 565.2 252.8 578.2]/Border[0 0 0]/Dest[794 0 R/XYZ 0 271 0]>>endobj
+118 0 obj<</Subtype/Link/Rect[108.0 552.0 243.6 565.0]/Border[0 0 0]/Dest[796 0 R/XYZ 0 269 0]>>endobj
+119 0 obj<</Subtype/Link/Rect[108.0 538.8 292.9 551.8]/Border[0 0 0]/Dest[802 0 R/XYZ 0 639 0]>>endobj
+120 0 obj<</Subtype/Link/Rect[108.0 525.6 332.0 538.6]/Border[0 0 0]/Dest[804 0 R/XYZ 0 652 0]>>endobj
+121 0 obj<</Subtype/Link/Rect[108.0 512.4 406.2 525.4]/Border[0 0 0]/Dest[804 0 R/XYZ 0 219 0]>>endobj
+122 0 obj<</Subtype/Link/Rect[108.0 499.2 431.0 512.2]/Border[0 0 0]/Dest[812 0 R/XYZ 0 207 0]>>endobj
+123 0 obj<</Subtype/Link/Rect[72.0 472.8 518.1 485.8]/Border[0 0 0]/Dest[818 0 R/XYZ 0 734 0]>>endobj
+124 0 obj<</Subtype/Link/Rect[108.0 459.6 224.7 472.6]/Border[0 0 0]/Dest[818 0 R/XYZ 0 672 0]>>endobj
+125 0 obj<</Subtype/Link/Rect[108.0 446.4 186.5 459.4]/Border[0 0 0]/Dest[818 0 R/XYZ 0 601 0]>>endobj
+126 0 obj<</Subtype/Link/Rect[108.0 433.2 364.6 446.2]/Border[0 0 0]/Dest[818 0 R/XYZ 0 187 0]>>endobj
+127 0 obj<</Subtype/Link/Rect[108.0 420.0 369.8 433.0]/Border[0 0 0]/Dest[820 0 R/XYZ 0 734 0]>>endobj
+128 0 obj<</Subtype/Link/Rect[108.0 406.8 256.5 419.8]/Border[0 0 0]/Dest[820 0 R/XYZ 0 609 0]>>endobj
+129 0 obj<</Subtype/Link/Rect[108.0 393.6 331.3 406.6]/Border[0 0 0]/Dest[820 0 R/XYZ 0 524 0]>>endobj
+130 0 obj<</Subtype/Link/Rect[108.0 380.4 273.6 393.4]/Border[0 0 0]/Dest[820 0 R/XYZ 0 387 0]>>endobj
+131 0 obj<</Subtype/Link/Rect[108.0 367.2 315.1 380.2]/Border[0 0 0]/Dest[822 0 R/XYZ 0 495 0]>>endobj
+132 0 obj<</Subtype/Link/Rect[72.0 340.8 484.2 353.8]/Border[0 0 0]/Dest[824 0 R/XYZ 0 734 0]>>endobj
+133 0 obj<</Subtype/Link/Rect[108.0 327.6 168.2 340.6]/Border[0 0 0]/Dest[824 0 R/XYZ 0 672 0]>>endobj
+134 0 obj<</Subtype/Link/Rect[108.0 314.4 187.1 327.4]/Border[0 0 0]/Dest[824 0 R/XYZ 0 403 0]>>endobj
+135 0 obj<</Subtype/Link/Rect[108.0 301.2 245.2 314.2]/Border[0 0 0]/Dest[826 0 R/XYZ 0 560 0]>>endobj
+136 0 obj<</Subtype/Link/Rect[108.0 288.0 384.2 301.0]/Border[0 0 0]/Dest[826 0 R/XYZ 0 462 0]>>endobj
+137 0 obj<</Subtype/Link/Rect[108.0 274.8 273.0 287.8]/Border[0 0 0]/Dest[828 0 R/XYZ 0 599 0]>>endobj
+138 0 obj<</Subtype/Link/Rect[108.0 261.6 255.6 274.6]/Border[0 0 0]/Dest[828 0 R/XYZ 0 569 0]>>endobj
+139 0 obj<</Subtype/Link/Rect[108.0 248.4 227.5 261.4]/Border[0 0 0]/Dest[830 0 R/XYZ 0 672 0]>>endobj
+140 0 obj<</Subtype/Link/Rect[108.0 235.2 270.5 248.2]/Border[0 0 0]/Dest[832 0 R/XYZ 0 734 0]>>endobj
+141 0 obj<</Subtype/Link/Rect[108.0 222.0 287.0 235.0]/Border[0 0 0]/Dest[832 0 R/XYZ 0 543 0]>>endobj
+142 0 obj<</Subtype/Link/Rect[108.0 208.8 256.2 221.8]/Border[0 0 0]/Dest[832 0 R/XYZ 0 353 0]>>endobj
+143 0 obj<</Subtype/Link/Rect[108.0 195.6 330.7 208.6]/Border[0 0 0]/Dest[834 0 R/XYZ 0 633 0]>>endobj
+144 0 obj<</Subtype/Link/Rect[108.0 182.4 324.3 195.4]/Border[0 0 0]/Dest[836 0 R/XYZ 0 626 0]>>endobj
+145 0 obj<</Subtype/Link/Rect[108.0 169.2 185.9 182.2]/Border[0 0 0]/Dest[838 0 R/XYZ 0 734 0]>>endobj
+146 0 obj<</Subtype/Link/Rect[72.0 142.8 431.7 155.8]/Border[0 0 0]/Dest[840 0 R/XYZ 0 734 0]>>endobj
+147 0 obj<</Subtype/Link/Rect[108.0 129.6 170.0 142.6]/Border[0 0 0]/Dest[840 0 R/XYZ 0 672 0]>>endobj
+148 0 obj<</Subtype/Link/Rect[108.0 116.4 187.1 129.4]/Border[0 0 0]/Dest[840 0 R/XYZ 0 548 0]>>endobj
+149 0 obj<</Subtype/Link/Rect[108.0 103.2 239.1 116.2]/Border[0 0 0]/Dest[840 0 R/XYZ 0 239 0]>>endobj
+150 0 obj<</Subtype/Link/Rect[108.0 90.0 193.8 103.0]/Border[0 0 0]/Dest[842 0 R/XYZ 0 560 0]>>endobj
+151 0 obj<</Subtype/Link/Rect[108.0 76.8 227.5 89.8]/Border[0 0 0]/Dest[842 0 R/XYZ 0 409 0]>>endobj
+152 0 obj<</Subtype/Link/Rect[108.0 63.6 294.1 76.6]/Border[0 0 0]/Dest[842 0 R/XYZ 0 298 0]>>endobj
+153 0 obj[108 0 R
+109 0 R
+110 0 R
+111 0 R
+112 0 R
+113 0 R
+114 0 R
+115 0 R
+116 0 R
+117 0 R
+118 0 R
+119 0 R
+120 0 R
+121 0 R
+122 0 R
+123 0 R
+124 0 R
+125 0 R
+126 0 R
+127 0 R
+128 0 R
+129 0 R
+130 0 R
+131 0 R
+132 0 R
+133 0 R
+134 0 R
+135 0 R
+136 0 R
+137 0 R
+138 0 R
+139 0 R
+140 0 R
+141 0 R
+142 0 R
+143 0 R
+144 0 R
+145 0 R
+146 0 R
+147 0 R
+148 0 R
+149 0 R
+150 0 R
+151 0 R
+152 0 R]endobj
+154 0 obj<</Subtype/Link/Rect[72.0 684.0 431.7 697.0]/Border[0 0 0]/Dest[840 0 R/XYZ 0 734 0]>>endobj
+155 0 obj<</Subtype/Link/Rect[108.0 670.8 236.3 683.8]/Border[0 0 0]/Dest[844 0 R/XYZ 0 734 0]>>endobj
+156 0 obj<</Subtype/Link/Rect[108.0 657.6 294.4 670.6]/Border[0 0 0]/Dest[844 0 R/XYZ 0 292 0]>>endobj
+157 0 obj<</Subtype/Link/Rect[108.0 644.4 274.8 657.4]/Border[0 0 0]/Dest[846 0 R/XYZ 0 665 0]>>endobj
+158 0 obj<</Subtype/Link/Rect[108.0 631.2 208.5 644.2]/Border[0 0 0]/Dest[846 0 R/XYZ 0 488 0]>>endobj
+159 0 obj<</Subtype/Link/Rect[108.0 618.0 265.4 631.0]/Border[0 0 0]/Dest[846 0 R/XYZ 0 351 0]>>endobj
+160 0 obj<</Subtype/Link/Rect[108.0 604.8 195.4 617.8]/Border[0 0 0]/Dest[846 0 R/XYZ 0 266 0]>>endobj
+161 0 obj<</Subtype/Link/Rect[108.0 591.6 202.1 604.6]/Border[0 0 0]/Dest[848 0 R/XYZ 0 639 0]>>endobj
+162 0 obj<</Subtype/Link/Rect[108.0 578.4 226.6 591.4]/Border[0 0 0]/Dest[848 0 R/XYZ 0 369 0]>>endobj
+163 0 obj<</Subtype/Link/Rect[108.0 565.2 183.5 578.2]/Border[0 0 0]/Dest[856 0 R/XYZ 0 346 0]>>endobj
+164 0 obj<</Subtype/Link/Rect[108.0 552.0 182.9 565.0]/Border[0 0 0]/Dest[856 0 R/XYZ 0 195 0]>>endobj
+165 0 obj<</Subtype/Link/Rect[72.0 525.6 228.8 538.6]/Border[0 0 0]/Dest[858 0 R/XYZ 0 734 0]>>endobj
+166 0 obj<</Subtype/Link/Rect[108.0 512.4 159.0 525.4]/Border[0 0 0]/Dest[858 0 R/XYZ 0 696 0]>>endobj
+167 0 obj<</Subtype/Link/Rect[108.0 499.2 496.3 512.2]/Border[0 0 0]/Dest[858 0 R/XYZ 0 666 0]>>endobj
+168 0 obj<</Subtype/Link/Rect[108.0 486.0 501.5 499.0]/Border[0 0 0]/Dest[858 0 R/XYZ 0 327 0]>>endobj
+169 0 obj<</Subtype/Link/Rect[108.0 472.8 452.9 485.8]/Border[0 0 0]/Dest[860 0 R/XYZ 0 734 0]>>endobj
+170 0 obj<</Subtype/Link/Rect[108.0 459.6 422.7 472.6]/Border[0 0 0]/Dest[860 0 R/XYZ 0 619 0]>>endobj
+171 0 obj<</Subtype/Link/Rect[72.0 433.2 342.4 446.2]/Border[0 0 0]/Dest[862 0 R/XYZ 0 734 0]>>endobj
+172 0 obj<</Subtype/Link/Rect[108.0 420.0 187.1 433.0]/Border[0 0 0]/Dest[862 0 R/XYZ 0 672 0]>>endobj
+173 0 obj<</Subtype/Link/Rect[108.0 406.8 247.6 419.8]/Border[0 0 0]/Dest[862 0 R/XYZ 0 561 0]>>endobj
+174 0 obj<</Subtype/Link/Rect[108.0 393.6 230.8 406.6]/Border[0 0 0]/Dest[862 0 R/XYZ 0 476 0]>>endobj
+175 0 obj<</Subtype/Link/Rect[108.0 380.4 205.8 393.4]/Border[0 0 0]/Dest[862 0 R/XYZ 0 365 0]>>endobj
+176 0 obj<</Subtype/Link/Rect[72.0 367.2 97.0 380.2]/Border[0 0 0]/Dest[864 0 R/XYZ 0 533 0]>>endobj
+177 0 obj[154 0 R
+155 0 R
+156 0 R
+157 0 R
+158 0 R
+159 0 R
+160 0 R
+161 0 R
+162 0 R
+163 0 R
+164 0 R
+165 0 R
+166 0 R
+167 0 R
+168 0 R
+169 0 R
+170 0 R
+171 0 R
+172 0 R
+173 0 R
+174 0 R
+175 0 R
+176 0 R]endobj
+178 0 obj<</S/URI/URI(http://www.samba.org/)>>endobj
+179 0 obj<</Subtype/Link/Rect[367.1 587.8 468.3 600.8]/Border[0 0 0]/A 178 0 R>>endobj
+180 0 obj[179 0 R]endobj
+181 0 obj<</S/Launch/F(ENCRYPTION.html)>>endobj
+182 0 obj<</Subtype/Link/Rect[174.0 575.8 270.6 588.8]/Border[0 0 0]/A 181 0 R>>endobj
+183 0 obj<</S/Launch/F(#PASSWORDLEVEL)>>endobj
+184 0 obj<</Subtype/Link/Rect[73.4 312.4 154.4 323.4]/Border[0 0 0]/A 183 0 R>>endobj
+185 0 obj<</S/Launch/F(#USERNAMELEVEL)>>endobj
+186 0 obj<</Subtype/Link/Rect[73.4 301.6 149.0 312.6]/Border[0 0 0]/A 185 0 R>>endobj
+187 0 obj[182 0 R
+184 0 R
+186 0 R]endobj
+188 0 obj<</S/Launch/F(winbind.html)>>endobj
+189 0 obj<</Subtype/Link/Rect[503.4 155.3 544.6 168.3]/Border[0 0 0]/A 188 0 R>>endobj
+190 0 obj<</S/Launch/F(winbind.html)>>endobj
+191 0 obj<</Subtype/Link/Rect[72.0 142.1 115.4 155.1]/Border[0 0 0]/A 190 0 R>>endobj
+192 0 obj[189 0 R
+191 0 R]endobj
+193 0 obj<</S/URI/URI(http://rsync.samba.org/)>>endobj
+194 0 obj<</Subtype/Link/Rect[118.1 84.0 222.3 97.0]/Border[0 0 0]/A 193 0 R>>endobj
+195 0 obj[194 0 R]endobj
+196 0 obj<</S/Launch/F(#OBEYPAMRESTRICTIONS)>>endobj
+197 0 obj<</Subtype/Link/Rect[235.4 649.4 332.9 662.4]/Border[0 0 0]/A 196 0 R>>endobj
+198 0 obj<</S/Launch/F(#ENCRYPTPASSWORDS)>>endobj
+199 0 obj<</Subtype/Link/Rect[338.7 570.2 449.4 583.2]/Border[0 0 0]/A 198 0 R>>endobj
+200 0 obj[197 0 R
+199 0 R]endobj
+201 0 obj<</S/URI/URI(http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp)>>endobj
+202 0 obj<</Subtype/Link/Rect[72.0 590.2 183.5 603.2]/Border[0 0 0]/A 201 0 R>>endobj
+203 0 obj<</S/Launch/F(#HOSTMSDFS)>>endobj
+204 0 obj<</Subtype/Link/Rect[345.1 511.0 417.7 524.0]/Border[0 0 0]/A 203 0 R>>endobj
+205 0 obj<</S/Launch/F(#MSDFSROOT)>>endobj
+206 0 obj<</Subtype/Link/Rect[380.8 497.8 453.4 510.8]/Border[0 0 0]/A 205 0 R>>endobj
+207 0 obj[202 0 R
+204 0 R
+206 0 R]endobj
+208 0 obj<</S/Launch/F(#NTACLSUPPORT)>>endobj
+209 0 obj<</Subtype/Link/Rect[339.9 533.8 438.9 546.8]/Border[0 0 0]/A 208 0 R>>endobj
+210 0 obj[209 0 R]endobj
+211 0 obj<</S/Launch/F(#SECURITYMASK)>>endobj
+212 0 obj<</Subtype/Link/Rect[493.0 76.2 545.8 89.2]/Border[0 0 0]/A 211 0 R>>endobj
+213 0 obj<</S/Launch/F(#SECURITYMASK)>>endobj
+214 0 obj<</Subtype/Link/Rect[72.0 63.0 98.4 76.0]/Border[0 0 0]/A 213 0 R>>endobj
+215 0 obj[212 0 R
+214 0 R]endobj
+216 0 obj<</S/Launch/F(#CREATEMASK)>>endobj
+217 0 obj<</Subtype/Link/Rect[356.1 655.0 428.7 668.0]/Border[0 0 0]/A 216 0 R>>endobj
+218 0 obj<</S/Launch/F(#FORCESECURITYMODE)>>endobj
+219 0 obj<</Subtype/Link/Rect[424.3 602.2 549.7 615.2]/Border[0 0 0]/A 218 0 R>>endobj
+220 0 obj<</S/Launch/F(#FORCECREATEMODE)>>endobj
+221 0 obj<</Subtype/Link/Rect[356.1 523.0 468.3 536.0]/Border[0 0 0]/A 220 0 R>>endobj
+222 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+223 0 obj<</Subtype/Link/Rect[72.0 245.8 144.6 258.8]/Border[0 0 0]/A 222 0 R>>endobj
+224 0 obj[217 0 R
+219 0 R
+221 0 R
+223 0 R]endobj
+225 0 obj<</S/URI/URI(http://imprints.sourceforge.net)>>endobj
+226 0 obj<</Subtype/Link/Rect[143.7 548.2 280.3 561.2]/Border[0 0 0]/A 225 0 R>>endobj
+227 0 obj<</S/URI/URI(http://msdn.microsoft.com/)>>endobj
+228 0 obj<</Subtype/Link/Rect[218.6 521.8 341.1 534.8]/Border[0 0 0]/A 227 0 R>>endobj
+229 0 obj<</S/URI/URI(http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP)>>endobj
+230 0 obj<</Subtype/Link/Rect[72.0 297.4 355.9 310.4]/Border[0 0 0]/A 229 0 R>>endobj
+231 0 obj<</Subtype/Link/Rect[454.1 76.3 534.8 89.3]/Border[0 0 0]/Dest[764 0 R/XYZ 0 613 0]>>endobj
+232 0 obj[226 0 R
+228 0 R
+230 0 R
+231 0 R]endobj
+233 0 obj<</S/Launch/F(#WRITELIST)>>endobj
+234 0 obj<</Subtype/Link/Rect[91.9 370.5 157.9 383.5]/Border[0 0 0]/A 233 0 R>>endobj
+235 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+236 0 obj<</Subtype/Link/Rect[184.4 357.3 285.8 370.3]/Border[0 0 0]/A 235 0 R>>endobj
+237 0 obj<</S/Launch/F(#GUESTOK)>>endobj
+238 0 obj<</Subtype/Link/Rect[160.6 330.9 228.6 343.9]/Border[0 0 0]/A 237 0 R>>endobj
+239 0 obj<</S/Launch/F(#MAPTOGUEST)>>endobj
+240 0 obj<</Subtype/Link/Rect[393.2 225.3 511.3 238.3]/Border[0 0 0]/A 239 0 R>>endobj
+241 0 obj[234 0 R
+236 0 R
+238 0 R
+240 0 R]endobj
+242 0 obj<</S/Launch/F(#PRINTERADMIN)>>endobj
+243 0 obj<</Subtype/Link/Rect[430.5 626.2 516.3 639.2]/Border[0 0 0]/A 242 0 R>>endobj
+244 0 obj[243 0 R]endobj
+245 0 obj<</S/Launch/F(#DEFAULTDEVMODE)>>endobj
+246 0 obj<</Subtype/Link/Rect[300.8 519.4 377.2 532.4]/Border[0 0 0]/A 245 0 R>>endobj
+247 0 obj<</S/Launch/F(rpcclient.1.html)>>endobj
+248 0 obj<</Subtype/Link/Rect[233.6 395.0 330.1 408.0]/Border[0 0 0]/A 247 0 R>>endobj
+249 0 obj[246 0 R
+248 0 R]endobj
+250 0 obj<</S/Launch/F(#SHOWADDPRINTERWIZARD)>>endobj
+251 0 obj<</Subtype/Link/Rect[108.0 625.0 299.4 638.0]/Border[0 0 0]/A 250 0 R>>endobj
+252 0 obj<</S/Launch/F(#ADDPRINTERCOMMAND)>>endobj
+253 0 obj<</Subtype/Link/Rect[453.9 598.6 526.5 611.6]/Border[0 0 0]/A 252 0 R>>endobj
+254 0 obj<</S/Launch/F(#ADDPRINTERCOMMAND)>>endobj
+255 0 obj<</Subtype/Link/Rect[72.0 585.4 118.2 598.4]/Border[0 0 0]/A 254 0 R>>endobj
+256 0 obj<</S/Launch/F(#DELETEPRINTERCOMMAND)>>endobj
+257 0 obj<</Subtype/Link/Rect[189.3 479.8 334.5 492.8]/Border[0 0 0]/A 256 0 R>>endobj
+258 0 obj<</S/Launch/F(#ENUMPORTSCOMMAND)>>endobj
+259 0 obj<</Subtype/Link/Rect[451.4 315.8 510.8 328.8]/Border[0 0 0]/A 258 0 R>>endobj
+260 0 obj<</S/Launch/F(#ENUMPORTSCOMMAND)>>endobj
+261 0 obj<</Subtype/Link/Rect[72.0 302.6 118.2 315.6]/Border[0 0 0]/A 260 0 R>>endobj
+262 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
+263 0 obj<</Subtype/Link/Rect[297.8 231.0 437.4 244.0]/Border[0 0 0]/A 262 0 R>>endobj
+264 0 obj[251 0 R
+253 0 R
+255 0 R
+257 0 R
+259 0 R
+261 0 R
+263 0 R]endobj
+265 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
+266 0 obj<</Subtype/Link/Rect[409.9 372.2 549.5 385.2]/Border[0 0 0]/A 265 0 R>>endobj
+267 0 obj[266 0 R]endobj
+268 0 obj<</S/URI/URI(http://www.cups.org/)>>endobj
+269 0 obj<</Subtype/Link/Rect[72.0 653.8 99.5 666.8]/Border[0 0 0]/A 268 0 R>>endobj
+270 0 obj[269 0 R]endobj
+271 0 obj<</S/URI/URI(http://wwwl.easysw.com/printpro/)>>endobj
+272 0 obj<</Subtype/Link/Rect[108.0 651.4 327.4 664.4]/Border[0 0 0]/A 271 0 R>>endobj
+273 0 obj<</S/URI/URI(http://gimp-print.sourceforge.net/)>>endobj
+274 0 obj<</Subtype/Link/Rect[121.4 585.4 374.1 598.4]/Border[0 0 0]/A 273 0 R>>endobj
+275 0 obj<</S/URI/URI(http://www.turboprint.com/)>>endobj
+276 0 obj<</Subtype/Link/Rect[108.0 545.8 288.0 558.8]/Border[0 0 0]/A 275 0 R>>endobj
+277 0 obj<</S/URI/URI(http://www-124.ibm.com/developerworks/oss/linux/projects/omni/)>>endobj
+278 0 obj<</Subtype/Link/Rect[108.0 519.4 444.5 532.4]/Border[0 0 0]/A 277 0 R>>endobj
+279 0 obj<</S/URI/URI(http://hpinkjet.sourceforge.net/)>>endobj
+280 0 obj<</Subtype/Link/Rect[108.0 466.6 282.5 479.6]/Border[0 0 0]/A 279 0 R>>endobj
+281 0 obj<</S/URI/URI(http://www.linuxprinting.org/)>>endobj
+282 0 obj<</Subtype/Link/Rect[108.0 440.2 343.6 453.2]/Border[0 0 0]/A 281 0 R>>endobj
+283 0 obj[272 0 R
+274 0 R
+276 0 R
+278 0 R
+280 0 R
+282 0 R]endobj
+284 0 obj<</S/Launch/F(smbpasswd.8.html)>>endobj
+285 0 obj<</Subtype/Link/Rect[218.7 455.8 284.9 468.8]/Border[0 0 0]/A 284 0 R>>endobj
+286 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+287 0 obj<</Subtype/Link/Rect[350.3 139.0 422.9 152.0]/Border[0 0 0]/A 286 0 R>>endobj
+288 0 obj<</S/Launch/F(#SECURITY)>>endobj
+289 0 obj<</Subtype/Link/Rect[169.1 99.4 235.1 112.4]/Border[0 0 0]/A 288 0 R>>endobj
+290 0 obj[285 0 R
+287 0 R
+289 0 R]endobj
+291 0 obj<</S/Launch/F(#WORKGROUP)>>endobj
+292 0 obj<</Subtype/Link/Rect[146.2 721.0 225.4 734.0]/Border[0 0 0]/A 291 0 R>>endobj
+293 0 obj<</S/Launch/F(#ENCRYPTPASSWORDS)>>endobj
+294 0 obj<</Subtype/Link/Rect[224.7 641.8 336.9 654.8]/Border[0 0 0]/A 293 0 R>>endobj
+295 0 obj<</S/Launch/F(#PASSWORDSERVER)>>endobj
+296 0 obj<</Subtype/Link/Rect[188.7 602.2 300.9 615.2]/Border[0 0 0]/A 295 0 R>>endobj
+297 0 obj<</S/Launch/F(#SECURITYEQUALSSERVER)>>endobj
+298 0 obj<</Subtype/Link/Rect[275.2 76.2 351.3 89.2]/Border[0 0 0]/A 297 0 R>>endobj
+299 0 obj[292 0 R
+294 0 R
+296 0 R
+298 0 R]endobj
+300 0 obj<</S/Launch/F(winbind.html)>>endobj
+301 0 obj<</Subtype/Link/Rect[151.1 694.6 219.5 707.6]/Border[0 0 0]/A 300 0 R>>endobj
+302 0 obj<</S/URI/URI(http://www.linuxworld.com)>>endobj
+303 0 obj<</Subtype/Link/Rect[438.0 377.8 495.1 390.8]/Border[0 0 0]/A 302 0 R>>endobj
+304 0 obj<</S/URI/URI(http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html)>>endobj
+305 0 obj<</Subtype/Link/Rect[72.0 364.6 186.6 377.6]/Border[0 0 0]/A 304 0 R>>endobj
+306 0 obj[301 0 R
+303 0 R
+305 0 R]endobj
+307 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+308 0 obj<</Subtype/Link/Rect[153.2 603.4 225.8 616.4]/Border[0 0 0]/A 307 0 R>>endobj
+309 0 obj<</S/Launch/F(ENCRYPTION.html)>>endobj
+310 0 obj<</Subtype/Link/Rect[303.1 603.4 389.9 616.4]/Border[0 0 0]/A 309 0 R>>endobj
+311 0 obj<</S/Launch/F(UNIX_INSTALL.html)>>endobj
+312 0 obj<</Subtype/Link/Rect[333.5 452.6 438.0 465.6]/Border[0 0 0]/A 311 0 R>>endobj
+313 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+314 0 obj<</Subtype/Link/Rect[440.4 439.4 541.8 452.4]/Border[0 0 0]/A 313 0 R>>endobj
+315 0 obj[308 0 R
+310 0 R
+312 0 R
+314 0 R]endobj
+316 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+317 0 obj<</Subtype/Link/Rect[465.5 662.6 546.8 675.6]/Border[0 0 0]/A 316 0 R>>endobj
+318 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+319 0 obj<</Subtype/Link/Rect[72.0 649.4 92.8 662.4]/Border[0 0 0]/A 318 0 R>>endobj
+320 0 obj<</S/Launch/F(#NETBIOSNAME)>>endobj
+321 0 obj<</Subtype/Link/Rect[95.0 575.6 159.8 586.6]/Border[0 0 0]/A 320 0 R>>endobj
+322 0 obj<</S/Launch/F(#WORKGROUP)>>endobj
+323 0 obj<</Subtype/Link/Rect[95.0 564.8 143.6 575.8]/Border[0 0 0]/A 322 0 R>>endobj
+324 0 obj<</S/Launch/F(#OSLEVEL)>>endobj
+325 0 obj<</Subtype/Link/Rect[95.0 532.4 138.2 543.4]/Border[0 0 0]/A 324 0 R>>endobj
+326 0 obj<</S/Launch/F(#PERFERREDMASTER)>>endobj
+327 0 obj<</Subtype/Link/Rect[95.0 521.6 181.4 532.6]/Border[0 0 0]/A 326 0 R>>endobj
+328 0 obj<</S/Launch/F(#DOMAINMASTER)>>endobj
+329 0 obj<</Subtype/Link/Rect[95.0 510.8 165.2 521.8]/Border[0 0 0]/A 328 0 R>>endobj
+330 0 obj<</S/Launch/F(#LOCALMASTER)>>endobj
+331 0 obj<</Subtype/Link/Rect[95.0 500.0 159.8 511.0]/Border[0 0 0]/A 330 0 R>>endobj
+332 0 obj<</S/Launch/F(#SECURITYEQUALSUSER)>>endobj
+333 0 obj<</Subtype/Link/Rect[95.0 467.6 138.2 478.6]/Border[0 0 0]/A 332 0 R>>endobj
+334 0 obj<</S/Launch/F(#ENCRYPTPASSWORDS)>>endobj
+335 0 obj<</Subtype/Link/Rect[95.0 435.2 186.8 446.2]/Border[0 0 0]/A 334 0 R>>endobj
+336 0 obj<</S/Launch/F(#DOMAINLOGONS)>>endobj
+337 0 obj<</Subtype/Link/Rect[95.0 402.8 165.2 413.8]/Border[0 0 0]/A 336 0 R>>endobj
+338 0 obj<</S/Launch/F(#LOGONPATH)>>endobj
+339 0 obj<</Subtype/Link/Rect[95.0 370.4 149.0 381.4]/Border[0 0 0]/A 338 0 R>>endobj
+340 0 obj<</S/Launch/F(#LOGONDRIVE)>>endobj
+341 0 obj<</Subtype/Link/Rect[95.0 327.2 154.4 338.2]/Border[0 0 0]/A 340 0 R>>endobj
+342 0 obj<</S/Launch/F(#LOGONHOME)>>endobj
+343 0 obj<</Subtype/Link/Rect[95.0 316.4 149.0 327.4]/Border[0 0 0]/A 342 0 R>>endobj
+344 0 obj<</S/Launch/F(#LOGONSCRIPT)>>endobj
+345 0 obj<</Subtype/Link/Rect[95.0 273.2 159.8 284.2]/Border[0 0 0]/A 344 0 R>>endobj
+346 0 obj<</S/Launch/F(#PATH)>>endobj
+347 0 obj<</Subtype/Link/Rect[95.0 230.0 116.6 241.0]/Border[0 0 0]/A 346 0 R>>endobj
+348 0 obj<</S/Launch/F(#READONLY)>>endobj
+349 0 obj<</Subtype/Link/Rect[95.0 219.2 143.6 230.2]/Border[0 0 0]/A 348 0 R>>endobj
+350 0 obj<</S/Launch/F(#WRITELIST)>>endobj
+351 0 obj<</Subtype/Link/Rect[95.0 208.4 149.0 219.4]/Border[0 0 0]/A 350 0 R>>endobj
+352 0 obj<</S/Launch/F(#PATH)>>endobj
+353 0 obj<</Subtype/Link/Rect[95.0 165.2 116.6 176.2]/Border[0 0 0]/A 352 0 R>>endobj
+354 0 obj<</S/Launch/F(#READONLY)>>endobj
+355 0 obj<</Subtype/Link/Rect[95.0 154.4 143.6 165.4]/Border[0 0 0]/A 354 0 R>>endobj
+356 0 obj<</S/Launch/F(#CREATEMASK)>>endobj
+357 0 obj<</Subtype/Link/Rect[95.0 143.6 154.4 154.6]/Border[0 0 0]/A 356 0 R>>endobj
+358 0 obj<</S/Launch/F(#DIRECTORYMASK)>>endobj
+359 0 obj<</Subtype/Link/Rect[95.0 132.8 170.6 143.8]/Border[0 0 0]/A 358 0 R>>endobj
+360 0 obj<</S/Launch/F(ENCRYPTION.html)>>endobj
+361 0 obj<</Subtype/Link/Rect[108.0 65.7 200.6 78.7]/Border[0 0 0]/A 360 0 R>>endobj
+362 0 obj[317 0 R
+319 0 R
+321 0 R
+323 0 R
+325 0 R
+327 0 R
+329 0 R
+331 0 R
+333 0 R
+335 0 R
+337 0 R
+339 0 R
+341 0 R
+343 0 R
+345 0 R
+347 0 R
+349 0 R
+351 0 R
+353 0 R
+355 0 R
+357 0 R
+359 0 R
+361 0 R]endobj
+363 0 obj<</S/Launch/F(#DOMAINADMINGROUP)>>endobj
+364 0 obj<</Subtype/Link/Rect[494.2 641.8 530.0 654.8]/Border[0 0 0]/A 363 0 R>>endobj
+365 0 obj<</S/Launch/F(#DOMAINADMINGROUP)>>endobj
+366 0 obj<</Subtype/Link/Rect[72.0 628.6 127.9 641.6]/Border[0 0 0]/A 365 0 R>>endobj
+367 0 obj[364 0 R
+366 0 R]endobj
+368 0 obj<</S/Launch/F(smbpasswd.8.html)>>endobj
+369 0 obj<</Subtype/Link/Rect[72.0 601.7 138.6 614.7]/Border[0 0 0]/A 368 0 R>>endobj
+370 0 obj<</S/Launch/F(#ADDUSERSCRIPT)>>endobj
+371 0 obj<</Subtype/Link/Rect[420.0 313.2 486.9 326.2]/Border[0 0 0]/A 370 0 R>>endobj
+372 0 obj[369 0 R
+371 0 R]endobj
+373 0 obj<</S/URI/URI(http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp)>>endobj
+374 0 obj<</Subtype/Link/Rect[139.8 202.5 387.6 215.5]/Border[0 0 0]/A 373 0 R>>endobj
+375 0 obj[374 0 R]endobj
+376 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE)>>endobj
+377 0 obj<</Subtype/Link/Rect[285.2 325.0 540.0 338.0]/Border[0 0 0]/A 376 0 R>>endobj
+378 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE)>>endobj
+379 0 obj<</Subtype/Link/Rect[230.8 285.4 505.8 298.4]/Border[0 0 0]/A 378 0 R>>endobj
+380 0 obj[377 0 R
+379 0 R]endobj
+381 0 obj<</S/URI/URI(http://www.tcpdump.org/)>>endobj
+382 0 obj<</Subtype/Link/Rect[349.4 562.6 455.4 575.6]/Border[0 0 0]/A 381 0 R>>endobj
+383 0 obj<</S/URI/URI(http://www.ethereal.com/)>>endobj
+384 0 obj<</Subtype/Link/Rect[424.5 549.4 536.6 562.4]/Border[0 0 0]/A 383 0 R>>endobj
+385 0 obj[382 0 R
+384 0 R]endobj
+386 0 obj<</S/URI/URI(http://samba.org)>>endobj
+387 0 obj<</Subtype/Link/Rect[233.5 681.4 308.1 694.4]/Border[0 0 0]/A 386 0 R>>endobj
+388 0 obj<</S/URI/URI(http://www.skippy.net/linux/smb-howto.html)>>endobj
+389 0 obj<</Subtype/Link/Rect[144.0 628.6 346.1 641.6]/Border[0 0 0]/A 388 0 R>>endobj
+390 0 obj<</S/URI/URI(http://bioserve.latrobe.edu.au/samba)>>endobj
+391 0 obj<</Subtype/Link/Rect[179.7 602.2 342.3 615.2]/Border[0 0 0]/A 390 0 R>>endobj
+392 0 obj<</S/URI/URI(http://samba.org/cifs/)>>endobj
+393 0 obj<</Subtype/Link/Rect[282.1 589.0 378.7 602.0]/Border[0 0 0]/A 392 0 R>>endobj
+394 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/ntdom/)>>endobj
+395 0 obj<</Subtype/Link/Rect[241.5 575.8 408.5 588.8]/Border[0 0 0]/A 394 0 R>>endobj
+396 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/developr/drg/CIFS/)>>endobj
+397 0 obj<</Subtype/Link/Rect[277.5 562.6 469.1 575.6]/Border[0 0 0]/A 396 0 R>>endobj
+398 0 obj<</S/URI/URI(http://samba.org)>>endobj
+399 0 obj<</Subtype/Link/Rect[358.2 509.8 432.8 522.8]/Border[0 0 0]/A 398 0 R>>endobj
+400 0 obj<</S/URI/URI(http://www.samba-tng.org/)>>endobj
+401 0 obj<</Subtype/Link/Rect[298.4 470.2 422.8 483.2]/Border[0 0 0]/A 400 0 R>>endobj
+402 0 obj[387 0 R
+389 0 R
+391 0 R
+393 0 R
+395 0 R
+397 0 R
+399 0 R
+401 0 R]endobj
+403 0 obj<</S/URI/URI(http://lists.samba.org/)>>endobj
+404 0 obj<</Subtype/Link/Rect[132.8 707.8 227.8 720.8]/Border[0 0 0]/A 403 0 R>>endobj
+405 0 obj<</S/URI/URI(http://lists.samba.org/mailman/roster/samba-ntdom)>>endobj
+406 0 obj<</Subtype/Link/Rect[306.3 694.6 328.0 707.6]/Border[0 0 0]/A 405 0 R>>endobj
+407 0 obj[404 0 R
+406 0 R]endobj
+408 0 obj<</S/Launch/F(Samba-PDC-HOWTO.html)>>endobj
+409 0 obj<</Subtype/Link/Rect[210.4 616.6 317.8 629.6]/Border[0 0 0]/A 408 0 R>>endobj
+410 0 obj[409 0 R]endobj
+411 0 obj<</S/Launch/F(smbpasswd.8.html)>>endobj
+412 0 obj<</Subtype/Link/Rect[239.2 172.6 308.6 185.6]/Border[0 0 0]/A 411 0 R>>endobj
+413 0 obj[412 0 R]endobj
+414 0 obj<</S/Launch/F(Samba-LDAP-HOWTO.html)>>endobj
+415 0 obj<</Subtype/Link/Rect[72.0 306.9 184.0 319.9]/Border[0 0 0]/A 414 0 R>>endobj
+416 0 obj[415 0 R]endobj
+417 0 obj<</S/URI/URI(http://www.openldap.org/)>>endobj
+418 0 obj<</Subtype/Link/Rect[169.5 563.8 285.9 576.8]/Border[0 0 0]/A 417 0 R>>endobj
+419 0 obj<</S/URI/URI(http://iplanet.netscape.com/directory)>>endobj
+420 0 obj<</Subtype/Link/Rect[223.9 550.6 387.9 563.6]/Border[0 0 0]/A 419 0 R>>endobj
+421 0 obj<</S/URI/URI(http://www.ora.com/)>>endobj
+422 0 obj<</Subtype/Link/Rect[112.6 524.2 202.0 537.2]/Border[0 0 0]/A 421 0 R>>endobj
+423 0 obj<</S/URI/URI(http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html)>>endobj
+424 0 obj<</Subtype/Link/Rect[125.1 458.2 267.5 471.2]/Border[0 0 0]/A 423 0 R>>endobj
+425 0 obj<</S/URI/URI(http://samba.idealx.org/)>>endobj
+426 0 obj<</Subtype/Link/Rect[243.7 445.0 287.3 458.0]/Border[0 0 0]/A 425 0 R>>endobj
+427 0 obj<</S/Launch/F(#ENCRYPTPASSWORDS)>>endobj
+428 0 obj<</Subtype/Link/Rect[212.8 360.2 332.5 373.2]/Border[0 0 0]/A 427 0 R>>endobj
+429 0 obj[418 0 R
+420 0 R
+422 0 R
+424 0 R
+426 0 R
+428 0 R]endobj
+430 0 obj<</S/URI/URI(http://www.padl.com/)>>endobj
+431 0 obj<</Subtype/Link/Rect[284.3 589.0 380.9 602.0]/Border[0 0 0]/A 430 0 R>>endobj
+432 0 obj<</S/Launch/F(samba-patches@samba.org)>>endobj
+433 0 obj<</Subtype/Link/Rect[332.3 477.8 458.0 490.8]/Border[0 0 0]/A 432 0 R>>endobj
+434 0 obj<</S/Launch/F(jerry@samba.org)>>endobj
+435 0 obj<</Subtype/Link/Rect[476.6 477.8 555.8 490.8]/Border[0 0 0]/A 434 0 R>>endobj
+436 0 obj<</S/Launch/F(jerry@samba.org)>>endobj
+437 0 obj<</Subtype/Link/Rect[301.4 248.5 380.6 261.5]/Border[0 0 0]/A 436 0 R>>endobj
+438 0 obj[431 0 R
+433 0 R
+435 0 R
+437 0 R]endobj
+439 0 obj<</S/Launch/F(#LDAPSSL)>>endobj
+440 0 obj<</Subtype/Link/Rect[108.0 590.1 141.3 603.1]/Border[0 0 0]/A 439 0 R>>endobj
+441 0 obj<</S/Launch/F(#LDAPSERVER)>>endobj
+442 0 obj<</Subtype/Link/Rect[108.0 576.9 156.6 589.9]/Border[0 0 0]/A 441 0 R>>endobj
+443 0 obj<</S/Launch/F(#LDAPADMINDN)>>endobj
+444 0 obj<</Subtype/Link/Rect[108.0 563.7 170.9 576.7]/Border[0 0 0]/A 443 0 R>>endobj
+445 0 obj<</S/Launch/F(#LDAPSUFFIX)>>endobj
+446 0 obj<</Subtype/Link/Rect[108.0 550.5 155.4 563.5]/Border[0 0 0]/A 445 0 R>>endobj
+447 0 obj<</S/Launch/F(#LDAPFILTER)>>endobj
+448 0 obj<</Subtype/Link/Rect[108.0 537.3 151.1 550.3]/Border[0 0 0]/A 447 0 R>>endobj
+449 0 obj<</S/Launch/F(#LDAPPORT)>>endobj
+450 0 obj<</Subtype/Link/Rect[108.0 524.1 147.4 537.1]/Border[0 0 0]/A 449 0 R>>endobj
+451 0 obj<</S/Launch/F(smb.conf.5.html)>>endobj
+452 0 obj<</Subtype/Link/Rect[186.9 497.7 243.1 510.7]/Border[0 0 0]/A 451 0 R>>endobj
+453 0 obj[440 0 R
+442 0 R
+444 0 R
+446 0 R
+448 0 R
+450 0 R
+452 0 R]endobj
+454 0 obj<</S/URI/URI(http://search.cpan.org/)>>endobj
+455 0 obj<</Subtype/Link/Rect[192.3 598.6 293.4 611.6]/Border[0 0 0]/A 454 0 R>>endobj
+456 0 obj<</S/URI/URI(http://perl-ldap.sf.net/)>>endobj
+457 0 obj<</Subtype/Link/Rect[108.0 585.4 206.5 598.4]/Border[0 0 0]/A 456 0 R>>endobj
+458 0 obj<</S/Launch/F(ENCRYPTION.html)>>endobj
+459 0 obj<</Subtype/Link/Rect[72.0 204.6 176.8 217.6]/Border[0 0 0]/A 458 0 R>>endobj
+460 0 obj[455 0 R
+457 0 R
+459 0 R]endobj
+461 0 obj<</S/Launch/F(Samba-PDC-HOWTO.html)>>endobj
+462 0 obj<</Subtype/Link/Rect[72.0 154.5 176.7 167.5]/Border[0 0 0]/A 461 0 R>>endobj
+463 0 obj[462 0 R]endobj
+464 0 obj<</S/URI/URI(mailto:jerry@samba.org)>>endobj
+465 0 obj<</Subtype/Link/Rect[302.7 691.0 381.8 704.0]/Border[0 0 0]/A 464 0 R>>endobj
+466 0 obj[465 0 R]endobj
+467 0 obj<</S/URI/URI(mailto:jtrostel@snapserver.com)>>endobj
+468 0 obj<</Subtype/Link/Rect[197.9 308.2 310.1 321.2]/Border[0 0 0]/A 467 0 R>>endobj
+469 0 obj[468 0 R]endobj
+470 0 obj<</S/URI/URI(http://samba.org/)>>endobj
+471 0 obj<</Subtype/Link/Rect[472.8 491.0 539.4 504.0]/Border[0 0 0]/A 470 0 R>>endobj
+472 0 obj<</S/URI/URI(http://samba.org/)>>endobj
+473 0 obj<</Subtype/Link/Rect[72.0 477.8 113.8 490.8]/Border[0 0 0]/A 472 0 R>>endobj
+474 0 obj[471 0 R
+473 0 R]endobj
+475 0 obj<</S/Launch/F(winbindd.8.html)>>endobj
+476 0 obj<</Subtype/Link/Rect[306.3 351.7 363.4 364.7]/Border[0 0 0]/A 475 0 R>>endobj
+477 0 obj<</S/Launch/F(#WINBINDSEPARATOR)>>endobj
+478 0 obj<</Subtype/Link/Rect[100.4 280.3 192.2 291.3]/Border[0 0 0]/A 477 0 R>>endobj
+479 0 obj<</S/Launch/F(#WINBINDUID)>>endobj
+480 0 obj<</Subtype/Link/Rect[100.4 258.7 159.8 269.7]/Border[0 0 0]/A 479 0 R>>endobj
+481 0 obj<</S/Launch/F(#WINBINDGID)>>endobj
+482 0 obj<</Subtype/Link/Rect[100.4 237.1 159.8 248.1]/Border[0 0 0]/A 481 0 R>>endobj
+483 0 obj<</S/Launch/F(#WINBINDENUMUSERS)>>endobj
+484 0 obj<</Subtype/Link/Rect[100.4 193.9 197.6 204.9]/Border[0 0 0]/A 483 0 R>>endobj
+485 0 obj<</S/Launch/F(#WINBINDENUMGROUP)>>endobj
+486 0 obj<</Subtype/Link/Rect[100.4 183.1 203.0 194.1]/Border[0 0 0]/A 485 0 R>>endobj
+487 0 obj<</S/Launch/F(#TEMPLATEHOMEDIR)>>endobj
+488 0 obj<</Subtype/Link/Rect[100.4 161.5 186.8 172.5]/Border[0 0 0]/A 487 0 R>>endobj
+489 0 obj<</S/Launch/F(#TEMPLATESHELL)>>endobj
+490 0 obj<</Subtype/Link/Rect[100.4 150.7 176.0 161.7]/Border[0 0 0]/A 489 0 R>>endobj
+491 0 obj[476 0 R
+478 0 R
+480 0 R
+482 0 R
+484 0 R
+486 0 R
+488 0 R
+490 0 R]endobj
+492 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/warp.html)>>endobj
+493 0 obj<</Subtype/Link/Rect[325.6 607.0 544.5 620.0]/Border[0 0 0]/A 492 0 R>>endobj
+494 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/)>>endobj
+495 0 obj<</Subtype/Link/Rect[72.0 254.6 319.2 267.6]/Border[0 0 0]/A 494 0 R>>endobj
+496 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/lanman.html)>>endobj
+497 0 obj<</Subtype/Link/Rect[340.6 254.6 538.7 267.6]/Border[0 0 0]/A 496 0 R>>endobj
+498 0 obj<</S/URI/URI(ftp://ftp.cdrom.com/pub/os2/network/ndis/)>>endobj
+499 0 obj<</Subtype/Link/Rect[173.1 129.3 363.5 142.3]/Border[0 0 0]/A 498 0 R>>endobj
+500 0 obj[493 0 R
+495 0 R
+497 0 R
+499 0 R]endobj
+501 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/fix.html)>>endobj
+502 0 obj<</Subtype/Link/Rect[220.2 661.0 429.3 674.0]/Border[0 0 0]/A 501 0 R>>endobj
+503 0 obj[502 0 R]endobj
+504 0 obj<</S/URI/URI(http://samba.org/samba/cvs.html)>>endobj
+505 0 obj<</Subtype/Link/Rect[354.3 577.0 500.7 590.0]/Border[0 0 0]/A 504 0 R>>endobj
+506 0 obj<</S/URI/URI(http://samba.org/cgi-bin/cvsweb)>>endobj
+507 0 obj<</Subtype/Link/Rect[135.9 381.0 283.2 394.0]/Border[0 0 0]/A 506 0 R>>endobj
+508 0 obj<</S/URI/URI(http://www.cyclic.com/)>>endobj
+509 0 obj<</Subtype/Link/Rect[391.6 269.8 498.2 282.8]/Border[0 0 0]/A 508 0 R>>endobj
+510 0 obj[505 0 R
+507 0 R
+509 0 R]endobj
+511 0 obj<</S/Launch/F(x1242.htm)>>endobj
+512 0 obj<</Subtype/Link/Rect[198.8 487.4 255.3 500.4]/Border[0 0 0]/A 511 0 R>>endobj
+513 0 obj[512 0 R]endobj
+514 0 obj<</Dests 515 0 R>>endobj
+515 0 obj<</Kids[516 0 R]>>endobj
+516 0 obj<</Limits[(aen1003)(winbind)]/Names[(aen1003)517 0 R(aen1022)518 0 R(aen1025)519 0 R(aen1046)520 0 R(aen1050)521 0 R(aen1062)522 0 R(aen1089)523 0 R(aen1134)524 0 R(aen119)525 0 R(aen1198)526 0 R(aen1203)527 0 R(aen1236)528 0 R(aen1242)529 0 R(aen1281)530 0 R(aen1324)531 0 R(aen1343)532 0 R(aen135)533 0 R(aen1378)534 0 R(aen1387)535 0 R(aen1402)536 0 R(aen144)537 0 R(aen1450)538 0 R(aen1494)539 0 R(aen160)540 0 R(aen1608)541 0 R(aen1634)542 0 R(aen1653)543 0 R(aen1661)544 0 R(aen1669)545 0 R(aen1677)546 0 R(aen1684)547 0 R(aen1720)548 0 R(aen1733)549 0 R(aen1736)550 0 R(aen174)551 0 R(aen1746)552 0 R(aen1782)553 0 R(aen1786)554 0 R(aen179)555 0 R(aen1794)556 0 R(aen1797)557 0 R(aen1800)558 0 R(aen1803)559 0 R(aen1807)560 0 R(aen183)561 0 R(aen1836)562 0 R(aen186)563 0 R(aen1867)564 0 R(aen1888)565 0 R(aen1919)566 0 R(aen1924)567 0 R(aen1945)568 0 R(aen1947)569 0 R(aen195)570 0 R(aen1964)571 0 R(aen199)572 0 R(aen1992)573 0 R(aen20)574 0 R(aen2008)575 0 R(aen2013)576 0 R(aen2033)577 0 R(aen208)578 0 R(aen2103)579 0 R(aen211)580 0 R(aen2111)581 0 R(aen2140)582 0 R(aen2144)583 0 R(aen2157)584 0 R(aen2164)585 0 R(aen2168)586 0 R(aen2173)587 0 R(aen2177)588 0 R(aen2193)589 0 R(aen2201)590 0 R(aen2205)591 0 R(aen2208)592 0 R(aen2212)593 0 R(aen2225)594 0 R(aen2241)595 0 R(aen225)596 0 R(aen2254)597 0 R(aen2267)598 0 R(aen2289)599 0 R(aen2306)600 0 R(aen2317)601 0 R(aen2358)602 0 R(aen2411)603 0 R(aen2419)604 0 R(aen2433)605 0 R(aen2435)606 0 R(aen2450)607 0 R(aen2459)608 0 R(aen2463)609 0 R(aen247)610 0 R(aen2479)611 0 R(aen2484)612 0 R(aen2487)613 0 R(aen2492)614 0 R(aen2520)615 0 R(aen263)616 0 R(aen279)617 0 R(aen28)618 0 R(aen290)619 0 R(aen298)620 0 R(aen310)621 0 R(aen322)622 0 R(aen327)623 0 R(aen335)624 0 R(aen340)625 0 R(aen343)626 0 R(aen355)627 0 R(aen365)628 0 R(aen393)629 0 R(aen4)630 0 R(aen401)631 0 R(aen418)632 0 R(aen425)633 0 R(aen430)634 0 R(aen435)635 0 R(aen456)636 0 R(aen500)637 0 R(aen507)638 0 R(aen527)639 0 R(aen56)640 0 R(aen562)641 0 R(aen582)642 0 R(aen591)643 0 R(aen60)644 0 R(aen602)645 0 R(aen622)646 0 R(aen637)647 0 R(aen651)648 0 R(aen658)649 0 R(aen680)650 0 R(aen74)651 0 R(aen744)652 0 R(aen765)653 0 R(aen787)654 0 R(aen798)655 0 R(aen8)656 0 R(aen80)657 0 R(aen833)658 0 R(aen851)659 0 R(aen862)660 0 R(aen873)661 0 R(aen898)662 0 R(aen90)663 0 R(aen906)664 0 R(aen911)665 0 R(aen921)666 0 R(aen924)667 0 R(aen928)668 0 R(aen950)669 0 R(aen983)670 0 R(aen999)671 0 R(body.html)672 0 R(cups)673 0 R(cvs-access)674 0 R(domain-security)675 0 R(install)676 0 R(integrate-ms-networks)677 0 R(migration)678 0 R(msdfs)679 0 R(os2)680 0 R(pam)681 0 R(printing)682 0 R(samba-bdc)683 0 R(samba-ldap-howto)684 0 R(samba-pdc)685 0 R(samba-project-documentation)686 0 R(unix-permissions)687 0 R(winbind)688 0 R]>>endobj
+517 0 obj<</D[766 0 R/XYZ 0 611 0]>>endobj
+518 0 obj<</D[766 0 R/XYZ 0 268 0]>>endobj
+519 0 obj<</D[768 0 R/XYZ 0 734 0]>>endobj
+520 0 obj<</D[768 0 R/XYZ 0 183 0]>>endobj
+521 0 obj<</D[770 0 R/XYZ 0 639 0]>>endobj
+522 0 obj<</D[772 0 R/XYZ 0 734 0]>>endobj
+523 0 obj<</D[772 0 R/XYZ 0 213 0]>>endobj
+524 0 obj<</D[778 0 R/XYZ 0 696 0]>>endobj
+525 0 obj<</D[704 0 R/XYZ 0 313 0]>>endobj
+526 0 obj<</D[780 0 R/XYZ 0 362 0]>>endobj
+527 0 obj<</D[780 0 R/XYZ 0 158 0]>>endobj
+528 0 obj<</D[784 0 R/XYZ 0 672 0]>>endobj
+529 0 obj<</D[784 0 R/XYZ 0 587 0]>>endobj
+530 0 obj<</D[786 0 R/XYZ 0 718 0]>>endobj
+531 0 obj<</D[788 0 R/XYZ 0 613 0]>>endobj
+532 0 obj<</D[788 0 R/XYZ 0 251 0]>>endobj
+533 0 obj<</D[706 0 R/XYZ 0 734 0]>>endobj
+534 0 obj<</D[790 0 R/XYZ 0 409 0]>>endobj
+535 0 obj<</D[790 0 R/XYZ 0 196 0]>>endobj
+536 0 obj<</D[792 0 R/XYZ 0 520 0]>>endobj
+537 0 obj<</D[706 0 R/XYZ 0 569 0]>>endobj
+538 0 obj<</D[794 0 R/XYZ 0 271 0]>>endobj
+539 0 obj<</D[796 0 R/XYZ 0 269 0]>>endobj
+540 0 obj<</D[706 0 R/XYZ 0 405 0]>>endobj
+541 0 obj<</D[802 0 R/XYZ 0 639 0]>>endobj
+542 0 obj<</D[804 0 R/XYZ 0 652 0]>>endobj
+543 0 obj<</D[804 0 R/XYZ 0 219 0]>>endobj
+544 0 obj<</D[806 0 R/XYZ 0 692 0]>>endobj
+545 0 obj<</D[806 0 R/XYZ 0 505 0]>>endobj
+546 0 obj<</D[806 0 R/XYZ 0 278 0]>>endobj
+547 0 obj<</D[806 0 R/XYZ 0 133 0]>>endobj
+548 0 obj<</D[810 0 R/XYZ 0 481 0]>>endobj
+549 0 obj<</D[812 0 R/XYZ 0 599 0]>>endobj
+550 0 obj<</D[812 0 R/XYZ 0 518 0]>>endobj
+551 0 obj<</D[706 0 R/XYZ 0 198 0]>>endobj
+552 0 obj<</D[812 0 R/XYZ 0 207 0]>>endobj
+553 0 obj<</D[818 0 R/XYZ 0 672 0]>>endobj
+554 0 obj<</D[818 0 R/XYZ 0 601 0]>>endobj
+555 0 obj<</D[708 0 R/XYZ 0 692 0]>>endobj
+556 0 obj<</D[818 0 R/XYZ 0 187 0]>>endobj
+557 0 obj<</D[820 0 R/XYZ 0 734 0]>>endobj
+558 0 obj<</D[820 0 R/XYZ 0 609 0]>>endobj
+559 0 obj<</D[820 0 R/XYZ 0 524 0]>>endobj
+560 0 obj<</D[820 0 R/XYZ 0 387 0]>>endobj
+561 0 obj<</D[708 0 R/XYZ 0 633 0]>>endobj
+562 0 obj<</D[822 0 R/XYZ 0 495 0]>>endobj
+563 0 obj<</D[708 0 R/XYZ 0 549 0]>>endobj
+564 0 obj<</D[824 0 R/XYZ 0 672 0]>>endobj
+565 0 obj<</D[824 0 R/XYZ 0 403 0]>>endobj
+566 0 obj<</D[826 0 R/XYZ 0 560 0]>>endobj
+567 0 obj<</D[826 0 R/XYZ 0 462 0]>>endobj
+568 0 obj<</D[828 0 R/XYZ 0 599 0]>>endobj
+569 0 obj<</D[828 0 R/XYZ 0 569 0]>>endobj
+570 0 obj<</D[708 0 R/XYZ 0 239 0]>>endobj
+571 0 obj<</D[830 0 R/XYZ 0 672 0]>>endobj
+572 0 obj<</D[708 0 R/XYZ 0 128 0]>>endobj
+573 0 obj<</D[832 0 R/XYZ 0 734 0]>>endobj
+574 0 obj<</D[700 0 R/XYZ 0 696 0]>>endobj
+575 0 obj<</D[832 0 R/XYZ 0 543 0]>>endobj
+576 0 obj<</D[832 0 R/XYZ 0 353 0]>>endobj
+577 0 obj<</D[834 0 R/XYZ 0 633 0]>>endobj
+578 0 obj<</D[710 0 R/XYZ 0 335 0]>>endobj
+579 0 obj<</D[836 0 R/XYZ 0 626 0]>>endobj
+580 0 obj<</D[710 0 R/XYZ 0 264 0]>>endobj
+581 0 obj<</D[838 0 R/XYZ 0 734 0]>>endobj
+582 0 obj<</D[840 0 R/XYZ 0 672 0]>>endobj
+583 0 obj<</D[840 0 R/XYZ 0 548 0]>>endobj
+584 0 obj<</D[840 0 R/XYZ 0 239 0]>>endobj
+585 0 obj<</D[842 0 R/XYZ 0 560 0]>>endobj
+586 0 obj<</D[842 0 R/XYZ 0 409 0]>>endobj
+587 0 obj<</D[842 0 R/XYZ 0 298 0]>>endobj
+588 0 obj<</D[844 0 R/XYZ 0 734 0]>>endobj
+589 0 obj<</D[844 0 R/XYZ 0 292 0]>>endobj
+590 0 obj<</D[846 0 R/XYZ 0 665 0]>>endobj
+591 0 obj<</D[846 0 R/XYZ 0 488 0]>>endobj
+592 0 obj<</D[846 0 R/XYZ 0 351 0]>>endobj
+593 0 obj<</D[846 0 R/XYZ 0 266 0]>>endobj
+594 0 obj<</D[848 0 R/XYZ 0 639 0]>>endobj
+595 0 obj<</D[848 0 R/XYZ 0 369 0]>>endobj
+596 0 obj<</D[712 0 R/XYZ 0 672 0]>>endobj
+597 0 obj<</D[848 0 R/XYZ 0 179 0]>>endobj
+598 0 obj<</D[850 0 R/XYZ 0 692 0]>>endobj
+599 0 obj<</D[850 0 R/XYZ 0 404 0]>>endobj
+600 0 obj<</D[850 0 R/XYZ 0 134 0]>>endobj
+601 0 obj<</D[852 0 R/XYZ 0 665 0]>>endobj
+602 0 obj<</D[854 0 R/XYZ 0 560 0]>>endobj
+603 0 obj<</D[856 0 R/XYZ 0 346 0]>>endobj
+604 0 obj<</D[856 0 R/XYZ 0 195 0]>>endobj
+605 0 obj<</D[858 0 R/XYZ 0 696 0]>>endobj
+606 0 obj<</D[858 0 R/XYZ 0 666 0]>>endobj
+607 0 obj<</D[858 0 R/XYZ 0 327 0]>>endobj
+608 0 obj<</D[860 0 R/XYZ 0 734 0]>>endobj
+609 0 obj<</D[860 0 R/XYZ 0 619 0]>>endobj
+610 0 obj<</D[712 0 R/XYZ 0 442 0]>>endobj
+611 0 obj<</D[862 0 R/XYZ 0 672 0]>>endobj
+612 0 obj<</D[862 0 R/XYZ 0 561 0]>>endobj
+613 0 obj<</D[862 0 R/XYZ 0 476 0]>>endobj
+614 0 obj<</D[862 0 R/XYZ 0 365 0]>>endobj
+615 0 obj<</D[864 0 R/XYZ 0 533 0]>>endobj
+616 0 obj<</D[712 0 R/XYZ 0 318 0]>>endobj
+617 0 obj<</D[714 0 R/XYZ 0 441 0]>>endobj
+618 0 obj<</D[700 0 R/XYZ 0 572 0]>>endobj
+619 0 obj<</D[714 0 R/XYZ 0 303 0]>>endobj
+620 0 obj<</D[714 0 R/XYZ 0 155 0]>>endobj
+621 0 obj<</D[716 0 R/XYZ 0 336 0]>>endobj
+622 0 obj<</D[718 0 R/XYZ 0 285 0]>>endobj
+623 0 obj<</D[720 0 R/XYZ 0 734 0]>>endobj
+624 0 obj<</D[722 0 R/XYZ 0 456 0]>>endobj
+625 0 obj<</D[722 0 R/XYZ 0 358 0]>>endobj
+626 0 obj<</D[722 0 R/XYZ 0 221 0]>>endobj
+627 0 obj<</D[724 0 R/XYZ 0 667 0]>>endobj
+628 0 obj<</D[724 0 R/XYZ 0 130 0]>>endobj
+629 0 obj<</D[728 0 R/XYZ 0 734 0]>>endobj
+630 0 obj<</D[690 0 R/XYZ 0 613 0]>>endobj
+631 0 obj<</D[728 0 R/XYZ 0 481 0]>>endobj
+632 0 obj<</D[728 0 R/XYZ 0 126 0]>>endobj
+633 0 obj<</D[730 0 R/XYZ 0 493 0]>>endobj
+634 0 obj<</D[730 0 R/XYZ 0 345 0]>>endobj
+635 0 obj<</D[730 0 R/XYZ 0 228 0]>>endobj
+636 0 obj<</D[732 0 R/XYZ 0 672 0]>>endobj
+637 0 obj<</D[734 0 R/XYZ 0 140 0]>>endobj
+638 0 obj<</D[736 0 R/XYZ 0 692 0]>>endobj
+639 0 obj<</D[738 0 R/XYZ 0 672 0]>>endobj
+640 0 obj<</D[700 0 R/XYZ 0 170 0]>>endobj
+641 0 obj<</D[740 0 R/XYZ 0 652 0]>>endobj
+642 0 obj<</D[742 0 R/XYZ 0 672 0]>>endobj
+643 0 obj<</D[742 0 R/XYZ 0 505 0]>>endobj
+644 0 obj<</D[702 0 R/XYZ 0 734 0]>>endobj
+645 0 obj<</D[742 0 R/XYZ 0 341 0]>>endobj
+646 0 obj<</D[744 0 R/XYZ 0 665 0]>>endobj
+647 0 obj<</D[744 0 R/XYZ 0 435 0]>>endobj
+648 0 obj<</D[744 0 R/XYZ 0 192 0]>>endobj
+649 0 obj<</D[746 0 R/XYZ 0 692 0]>>endobj
+650 0 obj<</D[746 0 R/XYZ 0 264 0]>>endobj
+651 0 obj<</D[702 0 R/XYZ 0 385 0]>>endobj
+652 0 obj<</D[750 0 R/XYZ 0 652 0]>>endobj
+653 0 obj<</D[752 0 R/XYZ 0 696 0]>>endobj
+654 0 obj<</D[752 0 R/XYZ 0 281 0]>>endobj
+655 0 obj<</D[754 0 R/XYZ 0 718 0]>>endobj
+656 0 obj<</D[690 0 R/XYZ 0 565 0]>>endobj
+657 0 obj<</D[702 0 R/XYZ 0 287 0]>>endobj
+658 0 obj<</D[756 0 R/XYZ 0 490 0]>>endobj
+659 0 obj<</D[758 0 R/XYZ 0 734 0]>>endobj
+660 0 obj<</D[758 0 R/XYZ 0 464 0]>>endobj
+661 0 obj<</D[760 0 R/XYZ 0 734 0]>>endobj
+662 0 obj<</D[760 0 R/XYZ 0 464 0]>>endobj
+663 0 obj<</D[702 0 R/XYZ 0 137 0]>>endobj
+664 0 obj<</D[760 0 R/XYZ 0 287 0]>>endobj
+665 0 obj<</D[760 0 R/XYZ 0 136 0]>>endobj
+666 0 obj<</D[762 0 R/XYZ 0 679 0]>>endobj
+667 0 obj<</D[762 0 R/XYZ 0 594 0]>>endobj
+668 0 obj<</D[762 0 R/XYZ 0 496 0]>>endobj
+669 0 obj<</D[764 0 R/XYZ 0 613 0]>>endobj
+670 0 obj<</D[764 0 R/XYZ 0 232 0]>>endobj
+671 0 obj<</D[766 0 R/XYZ 0 696 0]>>endobj
+672 0 obj<</D[700 0 R/XYZ 0 734 0]>>endobj
+673 0 obj<</D[766 0 R/XYZ 0 734 0]>>endobj
+674 0 obj<</D[862 0 R/XYZ 0 734 0]>>endobj
+675 0 obj<</D[778 0 R/XYZ 0 734 0]>>endobj
+676 0 obj<</D[700 0 R/XYZ 0 734 0]>>endobj
+677 0 obj<</D[712 0 R/XYZ 0 734 0]>>endobj
+678 0 obj<</D[764 0 R/XYZ 0 613 0]>>endobj
+679 0 obj<</D[738 0 R/XYZ 0 734 0]>>endobj
+680 0 obj<</D[858 0 R/XYZ 0 734 0]>>endobj
+681 0 obj<</D[732 0 R/XYZ 0 734 0]>>endobj
+682 0 obj<</D[752 0 R/XYZ 0 734 0]>>endobj
+683 0 obj<</D[818 0 R/XYZ 0 734 0]>>endobj
+684 0 obj<</D[824 0 R/XYZ 0 734 0]>>endobj
+685 0 obj<</D[784 0 R/XYZ 0 734 0]>>endobj
+686 0 obj<</D[690 0 R/XYZ 0 689 0]>>endobj
+687 0 obj<</D[742 0 R/XYZ 0 734 0]>>endobj
+688 0 obj<</D[840 0 R/XYZ 0 734 0]>>endobj
+689 0 obj<</Type/Pages/Count 88/Kids[690 0 R
+692 0 R
+694 0 R
+696 0 R
+698 0 R
+700 0 R
+702 0 R
+704 0 R
+706 0 R
+708 0 R
+710 0 R
+712 0 R
+714 0 R
+716 0 R
+718 0 R
+720 0 R
+722 0 R
+724 0 R
+726 0 R
+728 0 R
+730 0 R
+732 0 R
+734 0 R
+736 0 R
+738 0 R
+740 0 R
+742 0 R
+744 0 R
+746 0 R
+748 0 R
+750 0 R
+752 0 R
+754 0 R
+756 0 R
+758 0 R
+760 0 R
+762 0 R
+764 0 R
+766 0 R
+768 0 R
+770 0 R
+772 0 R
+774 0 R
+776 0 R
+778 0 R
+780 0 R
+782 0 R
+784 0 R
+786 0 R
+788 0 R
+790 0 R
+792 0 R
+794 0 R
+796 0 R
+798 0 R
+800 0 R
+802 0 R
+804 0 R
+806 0 R
+808 0 R
+810 0 R
+812 0 R
+814 0 R
+816 0 R
+818 0 R
+820 0 R
+822 0 R
+824 0 R
+826 0 R
+828 0 R
+830 0 R
+832 0 R
+834 0 R
+836 0 R
+838 0 R
+840 0 R
+842 0 R
+844 0 R
+846 0 R
+848 0 R
+850 0 R
+852 0 R
+854 0 R
+856 0 R
+858 0 R
+860 0 R
+862 0 R
+864 0 R
+]>>endobj
+690 0 obj<</Type/Page/Parent 689 0 R/Contents 691 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 19 0 R>>endobj
+691 0 obj<</Filter/FlateDecode/Length 592 >>stream
+xmRMsÚ0¼ó+ÞäDf‚ð†r*I[ÚÒÐâL/¹È¶
+ü©Es§’6(ò#¼«h³ˆÎ‡þ*Œ-eE>D„eOöî>Œ?½£À£d ÉqQ’;^¼É†›Åãý‚ÖJDfèƒÌÚJÔ†›BÖ·ÉÁµúè°­£©ò$ïzÁ«¾¤GMBØ’Eªâ™9ÄäûÆq+® =797â\u5CšÓ£¬iÑ(øëÍæÑtÄô°I0ƒØbH ¬àIö…¦TÊŸ„'§L–%æ€x’[úüô#yÂë<9I^¥œò×3’ü-™½ “àJ3úBFl±¨u‹
+endobj
+692 0 obj<</Type/Page/Parent 689 0 R/Contents 693 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 63 0 R>>endobj
+693 0 obj<</Filter/FlateDecode/Length 4565 >>stream
+xÍ[ÛrG}÷Wðm³U+™s!‡³/[¶¼Ùu•o)å}¥(ÊbÌ‹–¤ìäï÷
+_&–0ØQ%†ö¶ÖÙ¾è—í® :›8ëssg³Î¦vE_GÖIÆè v–0Øá@,,aQeÐi«ª Ú!š$U ¸*™Ó¾G0©œª’ÛEËÉÝ©*¸"±„Ád
+K³¡vXÆ`«cmMQȬ¨‚P4q¦™s³¢Î™¢©]ÑoD'‹¢}ØXÂ`‡…)ÚÛH #–°…A!XÆ`ëBŒä’Í Ã6BÆ@A˜!q¦·s³œ33¤vEY‰¢N23´Ò` ‹†7Ä ×-˜%,Þ ‘3Úš¢ƒ¡”a_†F(JÊT"Õ9‚‹^Ûb^GPT‘5 HÆ¢J!cæb˘:¬u1GŠõNAt6qÖ;çjgáCΡ³¢;6sœd ¶íû»òIÆÂÊz‚‹Ý ô:XƪëúwƒUóD[3fF#ᜉ3otŽ`vNçÌ9S»¢_‹s:)c˜Y,‚³` ‹ q†` ƒ©‚% E1)àœÎ2‹PŽb þ€Œ¶„Ábè¸WfBÄ\É|4(&ÎlæÁlBçÌ„©]2¡“É„™H2Ÿ,ÃHÍHæZ´%,~VK –0E´‡œe Æß53ôåa6ƒ‚0CâLoçf38gfHí’œLfȬ©,a1ƒÁ` ‹'52Ý‚%,fPu–1X$°Ü–1XLxa´%Œ4¹ìJf ^Ç’ƒdp\2ãE¯FhFˆp–1X,¶’úÔ‘0t' èÐÄðÔhAÄB™çÁ„Ë"BƒE¤ä¦Œmpj¬~V#—ÕÀ-Y”‘‹Å+C4Ô-HÆ`‡µè©r¤©‰ÅC „&GAˆM\+#Z;GP>YcÈ‚4¡ˆZL¨‚š8ÉòÑs'C¬&ÒÄMÄÄ‹²dëŸLSë’‚èRâdzA'K—Äýˆ% N4b–0ØF¶€Ô–°°Ò7fcB!僲Þ+Æ`ô¹W¦l)^›•UÊ&®À6.è¤5Ôu67T W ­@C'CLáŠX[µ£p2.6s˜=}ì¢åEáB¨ÎÞ Û'‡ÔT¶¾USèp£a‘€H%ˆi/cb/
+G2uo$c°ˆb5e ¶)½"˜1¬C2c°È¤f ƒm$Œ¶f\xšïg+ªŽìÔ "ŠIrœµ«Ptý®D»Ä!¿@;çBÍJ’þ ƒÅZ ySÆ`aìN[ÂbÀJLm ‹Ç7ÉŒÁb„½­©Z•æ’¡W
+DU¸j†pùJT . :„¹WqÒ„jÖ‰†*EAÍœJ . „Â~p['M(¾¤aJ…*¡™S)Á„P„ôÔIZ¶VñОp¡Î‰âB(Ʋ$Ò„"ŸðÊD©@„ª7„Û‰ûGPz:Â0ÉX>)'±„Áb°
+f ƒÕØAm ÃA' ©-cqÉ‹¢-cd E:k†Ð%%ùA© ¬›¸‘d×ÁCHF$c°™GÄ‹½ ¶á]}ŇJÑ¡ÄYœ#¡•$'ѱt¨Û{Sû$«»m© >™8„v(âAE‰¾:iBKÚW—
+Bhâ\b¸œ#¡(¥1iB Úÿ–
+BhâZ™˜Á¡mƒ4¡}ÚM–
+D¨Í…Ä!t£sE¨,šA2‹Ì«Ï,a°£RFË3†?#¥aÉŒe.H°Œ¶ŒÁÖ:b.™1X]‹¨-a°ÈÁ0S¢-aÌ#HÆìv–1X¼e–°äù#UoË,òÉŽdÉóe³ã;U><™C¾P¤…#cWÈ$c°˜
+CjÊX†GòÂø(c˜Is»`ƒ-%{!–0X„ÄšYÂ`1*f K “ÝIHf õQÖˆ1ØF†–ÚÆ
+TýQzØÿ»<’ ê~™ŽM{dƒÜx{3Õ‘å´Ù"‹ñRå!ög·ãS@äÛ£6µ~{Ð'Ô4'º;ì¤<Ê Å¾AžßÍæW³åQµ–r˜ìQžÏ–ãõÌl 1o”^¦>øŸÙÈÜ;¨Ž²@¹o‹4úØÁ¹G¤y‡ó6[Ü®ÖÛñRç Ê+ƒ²Mn¶I¾‡JFùøN‘í!yÍú(sTûæ8[OÇ[¨ÏÔäã!oØ,.ÓéšôÞdµ¼ž}¸[·³•N \µéyB^ÏæSëŒÝ¤6å1¥tîD6J]Ge™zß2$9&ü±ºÓx½vDN³‚|+ax•¨/q¼V{”ý<ÛÞ¨K
+S[ÄãÛñz¡"°Nåàý@¶Ê¦’Ý
+»Hè_ŸëtŠ¢JiÀÕê³­-ˆžc‹ô«g&bóäé6¶Ù%zçãÅ¥Ni¬ÉƒA*M„fßúW#½¦â¥êsʆÛ»)Û³Óå•u)v=ßÚïÛ^µ:A±½«Ê^Ùñ f¡
+Ný#¬I)ü†§;P{'q] 2ãË5鼕â`r}·D©tµ´dš™CG27é&ŸˆØA_Moç+-l£¸ õþT’– åñ÷Ї Aräô:òÐQSÈ{U¹Ë
+J ÈO–<ýGŠÚŽv·PE¥qK~<Õ™Õ{‡†_±žl¦“»õlkú#ñòàêÖ-ÉânÕ;d€#-Ï_­ÐU-:iÛÃCp½Òݧ1ïÖf:]̧ó
+.fyA@~†ø¨w7u—ûôg\·Ë›¸E†»÷øy¡üB
+—7õVi‡M¿áL¾÷b5¹[`
+¹n•\Ž#5ýV^ŸÉŒûçÅ“ÿ<ù?#A²endstream
+endobj
+694 0 obj<</Type/Page/Parent 689 0 R/Contents 695 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 107 0 R>>endobj
+695 0 obj<</Filter/FlateDecode/Length 4752 >>stream
+xÍ\]s[Ç‘}ׯ@¥öA©
+é‹{/¾¶¶d)N´µvqCz•ªx ‘
+'p=¶ãÓFHÅëA]Õ§3aƒ­›N[Å`G³Ó‰¶ vZu&¥ìlÔU1tÔTq›1ØŒÐ!”TS¨@¶šœÖB¦†u}:FñMÈ
+4í¢s\°ÑlŒ¾ò‚%à V8[¡à¢Ë¡wÂv1OL’G ©ìhÜeƒPÆT1—¬í «l[wYÁ`'#Cô¬zŽ°(Á*ÛV9›æGÓÃå%K€ÒÚ’nÖÀ‚Q‡C,yŠ©¦¶Ë
+;¥…I[ÁTDuÚ
+«ìxB5Ùì9aÅ`ñ9 XÁPDUÁÚ‚U ¶™vÚ*;©©Dï9)q< »%fn2æ˜Î „N¸¨Î ¤‚k*ÉIÅ`kúaƒ…’:mSýÜmÒV0Ù)Õã
+†‚ëa§gÅ\ºî¸IIØ"ÜãÉ´ „’2—LË9˜Ð°¢¨N* ÏQMC¶ d(Cˆ!3—ÆpN éd2·ÂaBÁ
+FÛqËE V0õWÑÈœMÓ…O¥;3·72Àé
+„©˜é:'C¢LÈÉÔé¥tj :ÍÜ°2_ç¤bJ2¤é:›º­1y¡ÚÌ qrÁ9©˜ÊåÙ$¬`ÊbƒF[Á`'-W;XÁTë¬M¸QsÙð Žœ ‚TŒAë–GXÁ`Û!V0Xœ-V0&<¤8ÑV1wý¯°‚Áb‡vXÁpW°3e“*p<ù¶h „*2—EwR±«"ؤŠÒ6‰¬`WE°I¹mÝYÅV0Ä”ƒT\¾h+ª€#Åò9Ë
+†Þáà•MÓÅWÜ¿6bº™šâ‚TÌ)ÑP„ vÌHSXÁ4…¦Ã¦)M“ ˆ)eJnÌð‹äbÈÊtä¤b°Ð/&¬`N—G¿°‚ÁN˜a +ÂXølf45ó4³j „0™C0'CÂbHo¨숧£°‚9][™h+,<˜C°‚!LÓRÃÎ*‹Í %+ìd
+GlR<†o·Æ@("sˆ^0#çbºH©lËH]XÁT`°iB jö8NÈâ»×ȸ9!ç¦ )É Ì M9¤7MC"FˆÍf t9DÏлs- ÇÎ! /2Z 2 W[É@ ˜¹äÓ'£[ØäV0Øñˆ¦¬`Øü5<ƒ³6¥§ŒçÊ ø”
+gaap1$6ÄÙ={aCÅ`q¾5¦!±MÝôj1dæÒÎ ¤WECÅÔãè`Ópsn\µiÆ• VsÆ©:XgˆN‘-@J'sB<@„Ì Ñ.„ š*+˜KÆ-mƒ­y¶›D¥Ü<\m ´›¹´7‚TŒ)¡q¼©b²cNIØÀ`±dX›`SXÚ§°‚!ŽåyÁ*fÀÅà*Xúás¡ñZ„•
+kQXÁÆ4ì“J `›Ñ@“9Æ–˜°“Š)# asÂôüÂ
+;žv{ ÖB—hk¦Œ<'LÝ ø„ ‡´cdʨÌ
+,Ó†iú¥eÚ^ÂÚös9J#3“-˜¢Žá=¤­`
+Ã`OXÁôôÍÁ*æfäFV0X,(›^¨
+Å`)ÔÊ
+ÆfE„7V1X¸•H1Ø)MŒ«xП5€`ƒÅœU¢´´ˆÁ<Ïa€–Ø´Ò™›Öœ¯sqhÐó'ê·‚EŠÁ"… Þ­b°ˆþ:¬`(ØvG´U ù¶U Û*ôqƒÅ’ª@Š¡þšáx´U %VU”b°Fáã*Æâ *1:«,ŒBÙ´t8á,r1S4@SL–™9sFCçrxz©˜*f¬b°CÛwÞ±b°8à œMÓŇ^&áqÑš£H––9‹ ƒÈé²`¤b°¨
+D1óþé‚}¯W¾ ž-Ë}^fV•¸·››Ê^Ã&ö_ØQiaïÀ Ør}²ëš‹}7ˆ6Ä(°{ÍûVËwÙ ¢7î ’ø)>[\Ïoß”/£‚0)ûS^7ÅܹÂM08û¦šfqïw¹¬ìÈU¾¿6oÀ`Ú×&«ñ±ëj·\ÜoWû_M‰°cŸÆåj~³yS”Þ´yy>JIu' <LGaõ¡Âþ¼yÇ™T¹²ö~„#9$| ½}ï*ûF„T!Nv„¨¾•ík>1ˆŽW×Ùîz¾M~'÷(¯ÇGiáÓ¾”u†ô!<(VùPc™X¯66ïn—ÛÝõêŽÊÃ&C®÷™›áÓdéûv–·Ê—OÓ8!>M>;ža*3·çËÕv¹Øo¶fи'h˶:ÜAØËyõÍö«}V7Ôý _t¶B9õ@)§=J-S?®ÃÕ¦£|ú¹.í«IušÅšuŒÇ¿™«Êô¢³ˆÝ{ VÍcEz•P–‰õÁÎ:åÓ0 ôÇÍåêê×⸱Rî‡û·à˜(®*›o錄Ƈu›ìqwGîñ¡ãy‰˜y;·Ð-†¶¾”ïVûk~ˆ[÷pÚ}ÐnH`¾µ`
+¾ê·÷ë׹䥕¥ÍuÝ ³m+”%‡áà÷:Ÿ—e?¸À}DQ‹·ºHqšêâÙåe1VL°œ \Ú±ÄoW¦¸NÝÖh)!®'#=ùö³³WT&Rõ¦ú””ºOÝÏ«÷ zYw­$¹ª™815ÑÍ5šN‘"=gŒË“HŠÏp6[œ…x¹neí»ÂeyqË£ò%̹‚H½¬ƒ—k³_“€a¨š.6››ÝÒŽ߀‡/«®„ÇgÖ«ë¹Mš ÷×+“¯«¢Wÿ®(^¢8s¤ÝÇú Èˆ+áÎŽ†]Yˆ¡vûàÉü™¦Óͬ7 ¥p6_ücþ&XýÙø±<ycÅ>Ñ<õøÈú$³Ý-·8Åͯà)æ¿6.)BâuR×G#?ZÑ^)qG0¿¹ñ@RîÏoV¸¸1Añ>¾ûe«>N‘‘ÛM·æQ5ëÇÕ›ˆˆYå.ÇPO‘ój»±KX|Cû]5n½sr#×=]F$‰¹KñÕÿh® j]‡av_±ë¬›¯ã7Du©ßç$/ùJ‰n·~}º@†ñËÓÑ/¿ç x´âû¹/Vý{ü
+ æñª":¾YßÁ¶^¯nrÕ¿™ú;& ¯ùpõq÷-¹œðÁ”Ø‹,ˆJýÀzþóÙ9õ—kqAøyIò–K>Êšš–“•;•ƒº(ž@&–æÛK VÅJ\bÛמA ¢8õо*Eì«úqŠ‘I%8ÆáIð›äC5”ü:k7Üx†bî²9¨ÚεSßÆèSÐG-Ý~©ˆ‰䚯á-Ê¡¤?ûuj~dž® ;OŽÖÿ2õ2_ßh¢³»C —UI••“d`q!‰À6v™œ¯8vÜOœð›xËŒ7Éi)¿ÛÎßýÎÚÃT‡ÅÛ[¯Å†5/ëµá·K\ŒÚiŽ´ž•ªç¥¤êÏqËs³™§š*ž”»,XVz -ú­<nË5ÞgƒÑíírÿn³µZ,~Š=ñ©žáQÄùb»º³£ßf~ëû——g¦4½âèÑcï”Ò
+zW•œ½0“Å£°™·à¶€ñþéž3}a!õ‚Ÿ(̾݅^3¢`' IØî¡ñ<”û^ðÆúvn·óÌ4<-9·`Õ蔜~yúêâ<î»ï1Ä^ëPÅðýÏWÍ®‹2ð[+jq}|¨‡*m÷v ‹·1öJÑç³0³b7\&ü OK¿} ¦±ª?B¼nÙ 5î#=lî·xµa[Mßô“zñÐfÿŽ=â§^~íVö‚ñéì+ΕúQ•;<ÑJ£©ëâþn7¿¼ÄQmÓÄi¾ÿÜNBHÔÊŸâСÍ÷>ƒ›¦õ.Q«>#aEÅ=Ø¿S^äù€¼Ü¬ç)>åÿ¼Ãƒ¹OYíVûhÚ<¢[+Ájàz°ìÈ»wÀnV·åXÒ«©ù-u "Íë)¾PEÅžÞ³åÁhÖ’Çï7†/a“‚Žr?¬ñ¡Zú'ÛW}|èhÁsc[Ý`I]ænp‘è±ÿ—ˆôá¶m*¹ÚÛb)àÛ‡B¿º¶)ܾ§>·¿Î⥘Ǥ¯qw“«;ð³díñ€Œë‹‡vQ˜Õ}È
+Y!¥Ý«~XèÏúFÒÔw?à)|z,ŠŸ{Άxm?ûÄkÄóg?~ÿlp¶ÝüÏw/6‹û5*=^âÿ©jšÁÉï£ðõÕŠ¢ÿñâÉ?ùOM'±endstream
+endobj
+696 0 obj<</Type/Page/Parent 689 0 R/Contents 697 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 153 0 R>>endobj
+697 0 obj<</Filter/FlateDecode/Length 4681 >>stream
+xÕ\ÛrG’}×WtÌî÷ú
+`^6dJšÕ†uY‘ÏÛ6EÌ
+TÖÜâ‘*-8€¼àÄMkŒsN ^Y7ØIÅ`»öLXÁ´•ZvV1تŒU ¶ Þ«,,Gß«–4ªOÇò^Å`Ë)ÌÅW¥,Þ;R–VØNjüw Ís¤*QಘŽ©ÄÌ ¤Ç\P&ƒE°‚ÁNG°+Š(»«lWbó}l°ˆŽò'a ¸0‘+«ŽÚϤbîºÉê¬`°cúŒŒ%U#.)U ¶¡µ
++,Do… â´¹rØ .Nä¦-•”9XnÉ ä¤b°MɽÉCƒmiÂ
+ !!Œ aµ âÌaš?ƸÔpoœ9´s¹\ÓP¨˜Ëå!åCƒ0´9Ts»Ò‚ ø‚"7ÓË3'“ZtsR1—[scòPÅ\¹[fÂʱ¹¢
+nŠÉ¬-·ÁËyjš«Àå
+ä’x¼9©˜/¥Ã+˜/mcƒÅ{tlXÒ˜^”–dÀ—¹¸„L*ÎKr6,)Ž ñ´É¬b, ¶ÙÂ
+;æ1$¬`°8!jeã± 5æ÷a;þ±1Í%@ˆc™ž“ŠÉN`ÁÊ:Æ’p"CÃybÅ`[eSØ UácóÌm3+ /ƒ*òXÅ<‘yž8kV€•Žcivc€š-µ\Pæ"³6Q2'9S 'ú+K8“ŠÁÂ~±Ò<­b°õpbÅÜ™’;ãcC»x¯²ŠÁv<5|¬bîL;H1X˜»J¤˜ûÆ á3+æÎ0À+xY4#ÆRgƒÅÉ®l0p(ÐÒræ`3p‡Ü¦N*‹%ÀçòÐ0-´g§ªÍcÀ§\Y6”4“6°žN‚Ãq`
+1¡ÿ"Ì2=« Pá7ô)çBÛ4'SMLq…LE0F +,¶¨UV0ÕÄôÍÇ*¦"xx+˜Š`Œq6(»bɳ)€+"rH/ë¢Îœ@,wÔò•™TLE0¼+lÓR+,,Odž墚ÉÅÒ¦+Ü€#ub\æbRèžIÅ\.+vaƒ­Kîª ¶› Ç
+†î;tQŠÁâDÐ÷Q¡ìäµ5r¦úÎ „ù²FpN ;bèvR1XÉ+8¨žšDµ$LvÂ=Ö1Xìõ`fÁTSJÔ
+†0ðyx[fƒE¡ «bPÕr
+Æ™‰9õµŠÃy;`aJ ƒ…é@ûyUŠÁZþ$¬`œ·(sÓL¦&ö5B¬GªÄó-
+ó_r1)RLšIÅ|%ÏKaƒEz5UV0 ‰a«,ÒqY1ÍŒ 2+˜†Äív6(¾aå¦m·WDäBTeR1ıfª°‚Á¢ÁÑ"ùà[8±b
+ËÀçlXR+)ÍÊ p¤m`¹p*dÓÚ©˜YhZÊCôÈ7¬,´i ø´‘+ÑÙ Cà“aZDZ²d6L‹ýÊÁ•›UÙÈ°ÚÈ1µ˜™TŒiáx©°Ž©@{Â
+k©³¶$–ñÌÌÌg 01ÐŽ/'ƒµlKXÁ`Ñ *­Y<C1öÔê:–'ÌfF Ö–9äVykàâ•èiâæ%T yN%lx%z9ÏaSZòœ
+cÚõ±‚) ó „±V2’¼ˆNáÓÂ) M&y~‡k„*vë BA ËÎ Œç·sv~§9Kk:©˜*`=(¬`Ú4‹>gƒ…ÌV0Ôq·íBŠÂ(k-6a3d3uV1Xä¼:³©~*å²ý;[Qd1FEflÌDjaûw™ppgÊ!9·Æ§³çA‘™àVO‘qe£Æí\¢‚³‹ƒÌÙ«°Ç¹Ò´sB‹°‘A¬`GO‘qÄW±8Ë”M‡þ}ŽEöï¼òÈXGœÎÚ*œ€ƒ‚Ã[Ø.ˆœ½ª
+µV8 R©åƒp(ãÈN”@p¸ôQÎ!8ä`cç6…S )Dšóû‹GŸ#áWX$š¸67ÅÅ¥]]ãçùw³w7}±¾*ÎÖ«]¿Úmÿãâç-9ê$;©8컳ëÙí®ßðº&æÃ$—ßÓSþ„!þ×ú1*Àqzb·OœNË:>…7^-Þßmz2è7™9Ÿ-ßÍø+2oºñy$16CVxÏÌV E¶Õ4ýÄG`_é‘7›År¶ù•¿¢Þtñ±§ëål±²_~òh*a³¾¹ "¢b™ŽâˆÓû¿¦æܟǃëÑÊdB
+}AuAa.Ê›M¿é¾[l» TÓq\íÛ~v¹X½ç”(«QÔàÇ-é‹=d;Aù§Uû}?›ÿóýf}·ºäºÛ¸!_lŸ3Q”
+¼êwÖ›òçAñÃú=7‰q{úOã7†´5§?9<ÌUIÏû]J¡y˹Ê€¬Œ·ëÙ2%[èæ8ñã6ú:'ÙUöEšä7¾JŠ@‰!iM,ã¼*yúú哯þ÷ìõ«‹·¯8ÝýbÞ_â¾yœŽ"ì/ÝäÐ÷ô« *—îêé>ÿfà,¿Ë3nt2&1¿OèÃß[‹óRîÖÁPOÐAþÍ‚W]¶WÕÃjÞ'ó A| ˜óçT±¬¥‚í „˜”)óvõ!³¼·ŠEÝœßj^&9—¶B[+fTä7V0ÓtsTvMôT0‡"=’|qh°í`yºïA7¢¥Dnð)³†[è8ÆT_ý¿)’ƒl(‘ÙÊb”Iýikä(ÀXÂV“Þ´ú£ÙÀÏ(‚W1õ<fhø<4¥7…XÈ‘Ã36aÐ}ö¢25?e׫pÀX¦Ï,¢Z*4üö,WÒØkN½' 9¥+.×!ÏC9å¾u ™Ÿp>nwùlEPò®/Ðsp3ãζ…64“»xUêqñ;-jž<vôƒû¹OÜ7?í_]Éu!v¢;04{ô½´óÓu¿29ЗÌ'ÜÂΘšŸ„ÇvøÍÓ3ŠÏrñ´êûËþÒ„b¶ýVeQÖU+Ú7ŽÐc©’ßœ…,x°^µuô.ô˜°«ÙilEÎí;ü®s™¦p‡SášöBsé3þ‘Œa¯o€­ õbÖÆq/áöªŸT Û>œ¤ø“©|ä¦WÚ:®ç™:X·ß®äHÓ ½ì·|¢–6ý-
+ÑYè)3W©û~Ì­¶Ëw·³íöÃáaÎú4hyV‹ÙÏ°Ž{‡vV„HFV!‚3šünFt†~lŠtç»õ&5µ7ø÷PpáJ eSîÇÒ‚ÃUÔ8'N±I³äEOnï-V¨é–©ñ5e6ÇcÉ–…<|Câ5áOŸ¼á´øÚÉ å§‹M?ÇúÃÅÊ8æ|÷(®³ÂF’© —'ø`Ø,*;Ý›»ÍízkÑE‡{&ÿ~òœÄlÀîMøâPŽ¼¯¹ •&•˜öåXòþ+£ƒ
+¥Ëpýçw··ëÍ®7¤:Ù,àpÙ¢ÎûÍ¿úÐCržË ýW]Ü5Ô4ŒkØÁæìsçóë~i˜-°Ü/:Ö{Ûߘm¯V"ãC ÷¶Eß>I*ætO€¿É°
+O;°ûÅ/âÎü.®Ÿ¡¸¨|P?ð»½Ã.µMb\Ü(?š>,v×Ô7ÎѼßÅ1ãøŒµ?thîCÊÁy…K´#çÕëÛ~•V‰lÙ¯Ú­o™ø@ç¸ÑL¢ì'k”æ0W}ض‰§>T£_ò¹.\U”üdeßCØÑâäÅ’'µžø9”%Ã
+¾\¡ÃšÅ}öËly{“®Ô=«üáé‹çôQøçË“gâ€Ú™;&êAÝ£²sf|ŠT­ÏHºp}RÙ_Q ’ÐÐ5Å÷•)G?ÃUaºáÇWNßÄц¦yÇî¤7ûý"$R„ü¸b3ÌÒ»Á= \vàös ò­«>ôEw#ÚSÇ÷_]
+ʱ§Žû´ü SŒì.äi|õâïÜu
+endobj
+698 0 obj<</Type/Page/Parent 689 0 R/Contents 699 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 177 0 R>>endobj
+699 0 obj<</Filter/FlateDecode/Length 2506 >>stream
+xÍYÉrÜF½ó+p¤"†–P8MÐôÈf„-Úbk4]šM‚§»!÷Bzþ~^fUe%ˆî15¡Åv„¤WµäžUýûIždø?Oš")ëd±:ÉÒ #òÇ›h$©M‹?WIÙ¦¹ËäúDÁURUi­8WI[¦…â\%y™HÁ6yjÔTWI‘ÛÑ\Á–õ˜UlU§ZYc°¶I+Í* =äÕèTƒ­ÚÑÊØ*,«ÔB…5Ÿ‰©PA¨©JKÿ!q
+’šrY…HÁÖf4ÕmY0IØ’AÜÒsy^Ò²BjŒemN¬ÂÐÆaaݦY‹Á°)ƒ¸©çl UÔÂ)ˆ-3K‹
+©1i¡%9#«0ت$Œ¬Â8nVŒ¶åãV-ÙÃ×9nàÚJˆœ‚t ~I·¨%¥"$,þªТ
+bbžA’H.<[Ø´Õ¬Â`@F±nÓš´$a%ñ\^ðD!ÝD‚¸IÅ Nô%t ¤›hhµ°#ƒ8Ñs9”©1i<^±
+ƒ­ Y·)§‹ [Q·žËóœŒ"¤›˜7Ê( âDÏ‘ v!)÷™6cõp²s€æ)ès_ä8÷…yÅY"§ $Ä~aZTc’¿†EãTÃ4 +É#pÈUX•?ä£Rþ1ÈâèÇù'pÔø‰S‡á¸Œ5&A •÷ ©“ ”«0X[Á·«0¢6/à"‘Õl•VÖlMù@ÍU,òNÐ YcJñõèTƒ-ÌHUƒ…¥ô™5‹`hÕ©4‹‚§µ¡1XKE+J¤ñ*18Õh_6<TDÉÈYšA4¼çœ¥…SP /¤7¼Ÿé Yçu†Ž¬ÂbøÈ:Ãû¹ÞÐÂj ã…UdkHfÅ*L†ç¸Šs†Šáp…š«1X”aĈÌÕ¬iÈ´‘U,¤GDVa° ;MdÛæã•&÷#m¸LQ6± ÑðžƒÆ¡Eá„y¸"ERc°\‘«0X¤n(QÖ˜ Oý b†yP¿¡&™«1X”=Wc°µmj®Â`Qìqe…¡â¬&Ó
+«1X¨XÏÕ,LŸJcbíH"ÁZ*:j_ŽZ„²eŠë:‰Æóœ Sá„Š3CiDHÁ´PSd[p’‰¬Â`Qy`žÈ* µgÄ*LÆ3—2Wc° õŠU¬K×q®ÂP"òÌ#¬Æ`«ŒÒ¦°TuË–îàèNã
+CRØ®Q+k f5«0XSç* ¶¡
+÷å<Q"ê¥[u€Á Fàr\x %þ’µD>J¥‰:N÷%ƒ8Ñs¶ yÂ)- Ä†Uh¢Æ` jtâTIƒtÝŒ¬“'‘ )к\ùÄÄŒúìHjìŽTjG ,–„êea·)4,]pÉ nê9¿‰˦‘u›†¹eI›
+˾[R‚=Ér%Úó»ÙÉËW-ü'™ÝqÓ•á
+Û˜dvËWz /Ngó›e— wÉÅ°ÞuëÝöÅì7̪` šuF½¦4íôâÃüã®ÛÐ7 °Èí)Œ“ÒFÞ®û»¾»å/‘ƒmã¿üi¸Ö¼ ´ÕÚÂßt»Ç®[Óç”:ËÖ¿ë×·Ã#o…jz   _Ïx?\¨Šðé|Í»¡ðYöíëËñ²ÔVáhûm¿¾§Qx”ÍÃtìtƒÍhüå+Ä/¤ùª…¨DagHŠRÆÒÒ}"¬ùz¾êxIh+·þ×Ýæ¡_ð8ªT#B]?ö»Å>º‡¶tŸ§_û¿¦¤#œQz‡G–YîïïÉWh™"H~¾ß}€ßô‹ù®Ø€µMóÒxü<Üî—38<&¯¿¼°A. C=ÌL{»uþŒ«p%–ó¾„ç¤Z$ùa3ì?²Ñ´3]~OCTmĿΗË!j-_i½G| 7Ƶ~*y5‘üM·Ý/wA¢Ú[&¹˜/>ø
+½«HI!t“EWkX•ø·YÎU›uu]BðæÞ¢Cs½ÑŲGxq^G{Ñ„–éÇ«w³+5¬<þö ZêèÒ6£C¨kâ“¥Ï~⓯ÎegDÃæ£íèêß‚páG1Y$Å4‹ÿ8<²Áp—Îb1_ÓB3öŽ—4wÈ}w˜,|½r ˜IÛ,T¾«ë—Î ðx
+Xòn¾áf*ï6Á3†õº[8×ÀÏ2²öÀ=^É[zþ¢†NÊYŹߜM5ZlNŸ4ª—Zˆ‹ÒùÚ É?^¡šÐŽ\ÏW7ó¿ÓèF2s´“òF(ñÀ0*¦d†iú¦f(Ÿhìýéz`£ÐÝEâ)ŒŒõþÅßèsÜ÷ltrÐ8“¿Ì[)©Ižò^*a0u‘þA;¨þÔeðݧá¬@?é> †i%=ß°7Ó‰år„Û„ÅëL¼2Í×ÿá3ê†| Oi×ÞØ}÷ÛíÞÝ7ðBo‡¸¤ð·¸ìˆoÔãûS¿’jц{ëC·¡jòþ-RÚ´¦wþŽ{¸\r÷[wó¥´,õü¸pÞŽWÀÂîS-O±Íé\gôÛÁÄû§wžCÞ;Ð
+¸JC3IA÷{)%†ìÇMw6Þ2Qíí¦‡ÊXãúJŒËüz9Ìùš[dÌÃæß¡©Ò©é+4›K)[§;ôÏÍÑL1ÕžŒ85ªÊ\º¤þ§…ÙéX…P¬¶úÙâ|±è¶ì/xʼnœs;nBC¹öÿz€h[ ·5ˆ¨¾‡žs,`¥ó¼øç5ëo¬íÿ£ ÑÊ¡Ø‚ÖVU¼€D#×ÃñÆ=Ù_õñœ4gM£naá™Gº¨Ïh£#ݹ`Búkl©Ž¥Ã†_žÈõƒi÷‹yAsÔRžIÖi¯rD¸èk1 @7Ý ¹„ÁÏãÕWxå9¢¢ Rg¼P“xÓàÄ[<¸$_!h¿l"r’^z•/×·—r ~³ö^ù¼ØÒåë_\sƒ*bñÆŽ}K®×ç?wžü²~C3”|?,öôx ¯6%5š”wš¬¥ÏûZﳓ_Oþ 0Ç" endstream
+endobj
+700 0 obj<</Type/Page/Parent 689 0 R/Contents 701 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 180 0 R>>endobj
+701 0 obj<</Filter/FlateDecode/Length 1061 >>stream
+x­VMoÛF½ëWLÓq‹õa˾ÙE“æÐuéqEÅ­È]vwE@|ßìR¶ì8Z† “û1oÞ›yã¿F9Mñ“ÓåŒæT´£i6Å—ûǧ÷£ÙÕ2Ëi¹œe+ji~u‘͇·†îd?-s<«K<gøuLU\Èy¶xn¾ú~»MÞ]ÑlJë
+˜..W´.#|)Î~ªUØQžÑ/vOÁÒãƒjR¦¤5û@w7¿ÞÞü¸þ3Þ“/Ò=ãyžÍpÓYžáè]àŽ¦×ô‰UI¡fj•¡NmÙ§s ÊóáÜìRN­O÷P©}pzÓ.i¯CBRaMPÚPcƒ'[Qï¹êÒ¦²¢ögÍM'¸·è`{z‡‹2úPÉ»
+ŽIK¶®UA[C
+%ÐYm„'d¼9D®ïT»Q´ç yøœêºëÉd¿ßg^–2ë¶)æÊÑCÅA¾üšn{Ý”’±Hx«rúÛ
+Z*EíÏ©Òuâz‡ƒ³[§Úr9ÐrFÙzVzÛ?eà ŠÆƒ)kTƒã"XwÈhëÉ׶oJR}°ÂCâ<Hm<Üu¢o"”‰öŽlÇg’?øÀí±*¨VŸ™zÓû^5d˜K/L¬ VPZ¾Ž‘TJäåµáû´zT¾Ì.ùOò¥ñXª4m=öÂ8í½W>‘ˆž™öRÞ¾ãBžíD}±¨&6jÓ°°Àü…‹^2ü0[µ{Z‘O€Å.+Ð&£L›¡02úh
+&ÞB£¾@½z´gÔ¦ítƒ•vÀhÜW CyDGz™>7ì{2ÚZPdŽ†”Ñ*ÏBq0ëäuô` ½ÍÇ0 ðå\`½ÿ_
+vã¾K7<ë»óÁwg×ÒÈ$#W·uA´>êãè .Λ¢¡'¶œüª‡ûVŠZ^禆ÓN-(rT:mvqDìƒnû&zcFï9D“.Ì|ˆ,ŸtÞ‰t.Š.g¤n1© Fx±;œãcŒm³`³:D‹…Ud’”¤2Œ»4£“Á [¸-'Ùr ¸Óöq*€¡xÛäÝêa(/iÌÿ›k«i¶Z-ÒÐÎàÏëÑï£
+endobj
+702 0 obj<</Type/Page/Parent 689 0 R/Contents 703 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+703 0 obj<</Filter/FlateDecode/Length 1533 >>stream
+x•WkoÛ6ýž_q×/u±F~?šaÚ.-‚­I׸è‚f(‰’ÙH¤KRIýïw.)Å®–X‚8NtyŸçœK=ÓßcZNhº ¬>%«í_l‰?F4ŸL“9ÍVK¼_®ðÖJ*`;Âéû—Öv:_ÜÛN`ß™ÒdÎ'£“ïŒGËdÙðj}4|ó‚Æ3ZHq±Â›<DÑ:Œ“YB—^nizB¯­^’ßHruJ™Ñ…*+¼2š
+UÉäÙú ÜÍh<ŽîŽ'K¸¬7é ü8Qo+ùÀQGJÏò[0qäš4WVfÞØ]÷0WÎ[•61¡3Ø”¥tžv¦ADÎjNbDÇãi2áàâMUíÈ™`˜ MNJÚ˜»ÑlÙ£Ò7¥„ Ëñ¶Vd^eõØ‹®qp+JÌÄXUux:”Ž¨“EÂä’É).é5Ž3x jº3M•S
+[S#²Ò%Uê†Ã)w»9¢ÜLLb:ÿy²ÂoD öësY™TTweU‡augìMiM³¥_éÝÕÛß·Æ“q²èÞ ÷ˆ78,®ÊÜÀŸ6?Ž Ë0£ÑüÎt㶤é*™Ä’î6*Û´=A1`La>鎄Þ-éNù Þ“È2Óhd¡ã¤½•ö9ÚÍ}”0Â$ñ¢,U¦ÄHµ¨%ÛeÜäI¨ø Ê^0ö`œÐõàÜÌ ¼‰
+rÒÃ}[ýO/E
+R±H©ˆ¸yõáâÓåÙùÛÄ󽸌¢\z¡*wý¬H Ÿû üÿá›y˨0t(í<úŸul -À¤6¾{N‚¢ ¤'r
+}<m˜³ãdÞJóì„Ö­
+ÚVdbûO<’A÷äc©
+Ú|æŸB{ë­±^€JÊ<$>2½•Ê¹JSðôl¿­ÝÄ{ŒD*rÁ]ÐUSZQC¾‹ý?m£]oŽ¿sxͳ À® ý!¡ÊˆØiyê‚£€úÖ°T·X6š¤µ<;é4»?Ö=z៣â Í\æ„;ÿc,dÎh‘by¥@ÀT­É@Ìý±-ÚÍO°F! ¬LÁ{æ!žÆ›ï[w?š+Œ¡nPu¶1
+endobj
+704 0 obj<</Type/Page/Parent 689 0 R/Contents 705 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+705 0 obj<</Filter/FlateDecode/Length 1363 >>stream
+xWÛRG}ç+ò¹‚V—•„à —íÄU1v@IÊU®JvGҘݙõÌ, ¿Ïé™]tAÄ&@-ôôåô9Ý£oGêã{@gCJ'”•Gýd:¥ÍÃ.ñ¦Oã´ŸœÑhz†×é8IÉJZÀ¶ÓÆv8%ãÆvûÆôÛÁd_Ñíh’ ZÛCnÓQr¾ïõõì¨÷nDƒÍ(c2=£Y2êÓ,ëø•r¯f_a4x4ê'Éf-ý\×uNÓ =ïù¬Š¶‡¶N•ª¶XÓÂXXŸõê¼¢µ©É­L]ä´w’„&©½]S¡nå÷k×zz6î•|ð$så9–¥h‡~…‚;=鳞By’½ØõÒA:9‰<'o‘–Žœ)%@ÑË!máÓ§sÆpŒÒ!u‡ãdŠß
+“‰¢çD9½¹Ò=WÎs
+βOÝ8ö_
+HÎ¥¿—RS­Õƒt ýnÌ- H%<l`[*Ÿ¶E>¢… MÆËZå2iþزóêãìíÝ aM àÎבjÌ3öÎL£¦)ÿ
+”†p%ÜN9š£ôQÃX¯ÑS•.è²kà"Á~Cµ‹ˆœ(í¥]|B¦òÊpo˜–A?lê*™©Å:
+‹·V¢Â¬»ö,&Óì Mž™¸Âàd@Zî• ŽÞª¢ˆ¹—EÑpýœØݼë»)†;/A2I† ÝxYÑxžÐe&háÕ¼ 
+Þ0<'*k0:\»w7õ’ ²{RÌÓùX²•G¼?4ÊmàÍ_×#@¹ÚJs†aaFÌZA†ò,¶n41~KÙnPeUH×swvÔ ÈÖOïÎí¶l¦\†¦ßð ëL8°‚b ѧÍÒLðicšÒd’&iÊú¼¹üðú’>YókˆÞ˜, XH=*ºÛžèžõq›ýÿ£a4å@#L8I¹ø·³£?Žþ¶3Úœendstream
+endobj
+706 0 obj<</Type/Page/Parent 689 0 R/Contents 707 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F3 6 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+707 0 obj<</Filter/FlateDecode/Length 1368 >>stream
+x­VÛnÛF}÷WLƒ•‹º9ºø¡…[Ç…Än*BPõaE®ÈÉ]†»´¬¿ï™]R±d§ ÚÚ°Mk¹3gfΙ™O'êã{@“!Æ'ý¨O¯ÏûјΧ<ñSIÚøƒÑdüòÁ`<‹Îoü´8é]ÏhpN‹ œŒ§xHú}ZÄA4‰hîdIã ZT;Ê•uJ§ä2I6•´$„ÊÅ:—d4íL]‘•Õƒ¬NaÀÁvw8íηáóAóù,½†cØbçJjGÝ·^5/uØlf¬Ó¢áè¼9êzÝá±ÁÈS—©ó„Réh-â{5™Í?!ŽèfÃPbô÷ŽcÔdM!]Æ!+KJǦªdìò‚tu1˜>u£hÈîo“¸'ø2Þç«&¡Xh¹5´–T[™3¸.iË/¶YD2iྡྷ·B¿Z¤x ɱ´êØ:ÎHØ#ßËÍ2]¶ˆÚ„4Å™1Ö{¯(—2€¸®”Û…09êBìh£4à1®¹(Ö´úTKëPe*…µ[S%ˆbc€V9Úª<ÉØ#8!.°6§½ë×mAi_íÃrv€BÃU
+:›Šé@.!hFȉÄDZwŽ$2Ùx›Ä­B¾kw
+íâc½}AdhöO–—'—ÒÁZëä Â/¸;Vð5t EQ¢Ã‡€À„ñ©C×Pª"¦­‡—›áùàpS!\Î|¨Û•ò⢶Y|Eoîõ¼»Û vZÒ7ø3ñg ñ§Ïˆ¿©L‘^ÝÍψÛ~+={ônþÏðþŒÍsºÆÑ”{ëݼ7<#éâ(ŠÄÒï†Õ*L­½ÈeïÑ@dúå°¾X­–7·WwËùjõCˆªOÓA4k”Æ@Aí)¹ ¾‚ö9Ïáù¹¶ÂÝýlbXe¥<¬ÿP^ºÁ ˜JcòÑ·ìûÊø=vLˆ\¾0†MÊ\®+áä¾V‚œè ‚ÖuŠ™RšÊ}sÈï3sýˆ–<„0½Ð„ujéÊä%zðá⳪ã]´i?ª¹UcdE:N…1Á^é{zµÍ m«0©¡ùnU ›½â¾ é†l¦|^: Æ5ï@C©€¶V˜nÙÙL~²:%Ç#‘õ†6Z`‘Øêc=£©ù=‰
+•fÙ<q1ïÇÕÍå/·wó›yä1Ç]_¾ßï&ع€†½XWc»ñx¨Å/˜–<Yü`4~{Òp´ÜÚ´2u‰rcîÛ6øۛ˫wož\ìÍ 4É‹PÇÒÚMÍÓaßÆɯ:¦¶€jýŠ¥œ<nÅ(GžlU2` š9Á{•Ñ’$(ŠÞi)Ã>áûWY,“èž vIÌežù}àÌúYã*–#ǽ\.êaÃïY¼3ø5PY‹U¦K–×›n¢¸È¾B½ëi3èc,ÕÓÇÍR9¿|÷Ó%ýZ™hê`b\XS÷wöŠ.t'ýwªÿº5ŸOûÑ›¸_‹ÏÙÅ›ÅÉû“¿
+endobj
+708 0 obj<</Type/Page/Parent 689 0 R/Contents 709 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+709 0 obj<</Filter/FlateDecode/Length 1419 >>stream
+xV]oÛ8|ϯXä¥.«–ã8N{p>z0º¾Z½\¼Ðm³‘HW¤œøßw–”[MÐC%¶HîìÌì.ÅÔÃOLç}:RZõ¢ ‡§xFçxöñ[JZ†½A4|íÅY|^{Ñ{¯ï¸¸ˆí —ÉчOŠcJ–@5S’õz”¤»µÔ´3-Õ¹µ¤Mi¹,hv{3žß•:£B’5xT›L8iÉ¿43iUHí„SFÓ}Ç”XV•©¤Ôdòþ=>ap¼ø}òã¨GÝø4ê#~GË'GYZl|TyŽðˆ£Ia•,#^þáÓŃ
+ õ GGpmt÷@ ŽíãEÔRfÍr¦ã–n¡Œ €ß‘-Qjô²×lØ@› fWöð@O´‚½(cá—0œc€ðÑ”@O™L‡êJMofÏ\Ù?ˆrÑÕÚGq$¸Ê™Ôät+·2?Ôœo%X8ÿ|ÉE¯ê)‘ËÔYœZ•%Šl%mµÙ˜ÒY:;¡,ƒ²«/_oNüsvûm~B·ãéçñ4>iñ¾î“@ZÓ$ö 1”a(ï!šRNCÒ#W^!žTQ/
+ÃÊÍóny·‚ºÒÊrËú¤àŒ°e‘ù³Wæ^wœÛ˜öV‘|OÐÞ¸¯þ§OÍB£;ú²äóC»yŽ
+í¯c
+í€íéöáÚI°“‰;d­U L^cvæ/7Ü4àc.ÂÆ­ë¹B…ZŒ0¹úÈ]*õ_´ëï®n¬Ó„)Á§‹³û÷mds)½
+MÝw°Xu%rHyJÁleÒ •ÿæÿ©qò#%/…º)ÚðÏJV,;7†G®…zøÀ×Ìl蔡c'W³“AX&º™'ì-‘‚öl§ˆ>¡ç¾6™
+#4—<C§èé²RícáF³À–ïuÔF·âú8vg,Ð,C¡±Ÿ«B,Pc"8|Q­<Ñoß Z6xbj–¥)èÛtòMЕW“fWú¥§½tñfÀyȨ
+1†6p3ÒN¼±âªEDß¹4ø2Ò Òú¾âù´i©6ŽŽÂã<Žè«èdЖוUêïa\7õ’g«µB¿a¼„Û
+endobj
+710 0 obj<</Type/Page/Parent 689 0 R/Contents 711 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+711 0 obj<</Filter/FlateDecode/Length 1584 >>stream
+xWmoÓHþÞ_1Ê—+Rk’4¤áZÚžÐåH8„TÝic¯ÉR{×ì®òïyfÖ©Aw'T‘4μ</3Ó¯Gã߄Χt6§¼>gc:ϳ9Íçx=Å×TÊÓ³gxû‹&ÏÆÙtøÁåêèéÍŒ&Z•H2_œÓª $i•¯6~âÖQÜ5:+©rù½±Ÿi»1ù†¬ÖEGkMö¥ó5Þ¯w¤hùæ’‚öÚg„PT"™@#¯sç‹>ÐèÉêËјN'g¨pU§¸ªªÜ6 L^m#§àÄø…Wö³æBÖ»ˆŠŒÅï\£-T:¥
+H` ΑxTh»£Ú:Œð ¥§ÐèÜ”F?¥G(%Á8
+mÓ8ƒÈ.åá}¢IFK +úf‚YWÒ{Ç
+ 7°Ì1º¤%À½U»Ÿ@„ãòPÇ…k«‚òÆ€‚C»Ð[Yù;>Pò[o Sñ"„˜M†™ïÅþeÈ·&n¸÷A?(èÀÚ[çï; Ø}`?`dJŽBD˜·^‡4}“gL@–D¥ª
+.ªü§*„æñe5TêUa¼ó{šì…Üw T^«{¨°ÛÜ$ü’†
+… Š§JL²ßCùÃmà£þ“˜»£n
+ÃØÀ¢Â¸G'68k@ Máìo±Ÿkû!ßôlvtywZ,z¯Xaáî $Ä#TÆ>2$K–BVÇÖ[Œ,܃ƒa€o‰yÕ@±W—Œ ñÑ&rÜþ1„l…©Ð­ø¼RøÁU‚/p ‡;_Æ(êäK†Yeþἆ• žD*h•—=ß|I@rƒŠ ÌC_«ñ<ŽˆýA¤r6M?àÃ~7SC§Êj׆ÞÕDn
+ºèG »U™ƒŒW×o?ýóööíõ ÉË÷×WÝËï_­®y»É¯_. Ñ’8X¹<ÊÑæÚT&vgÐ SkH¤›——bRys…åÈÏ>½yNœ>|%žb/É4É&ãlžÑ ÉT}À±gU­Åćwåé”ïÊc,¸,.ý‹¬×ô­~-¿{™¦³˜–‹ÜÌ*DÇã…·§Ã%
+˜é>œØŒ€-3Ú+¦¿)—:ÝG¡^g8 KÞ™Ô(Ü‘<®A¬2UøVÏ3ºEBO/á(\*xµÔñÿt‹3 ¦®Ùœ «K€Jsžåcykç}\9j‘ª†÷*ƒŽ¹Ïß¡=eOèÇ$ìèü€Ä%–
+endobj
+712 0 obj<</Type/Page/Parent 689 0 R/Contents 713 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+713 0 obj<</Filter/FlateDecode/Length 1319 >>stream
+x­V]sâ6}ϯ¸df1Øpx£éfº3ÝtÛ¥³/y¶Àjlɵä$üûž+Ä@;m§ÝÌ&`ÉGçžs?ôûMHsü„´Žh±¢´¼™sŠÃESœ¬ñ9ÂÿZÒÁ/DÉ/_.$ ̓þW}ļ7ƒe¿5ÆGòÝŽqpäð ÛgwØN»˜¬Ö í2¿Ž'éä>•“5hÐ'íä±Né#}þJß”ÎÌ«%-Ý«©Ÿ-½*—ßî~»™Ó4Š2ù*ʽà'|@ˆG|Àt¯FAÐö(uÖí‰) »=Ñšwì ©Lj§'r¹¤gy¢C£S§Œ•2Í…V¶´dˆy:CR‹}!=@&«ÂœJ@ò=‚àž”°$
+’o¢TZnxnO£nýQ”ØÖ ÇFJƒEÕÀ±_µz›ý¨tóF»û/³O_΋ªæ f
+Í`T6˜ü_‡`.a\ceæÂ×"°3L˜~‰ùƒy¥} ßY„Þ ˆ¦3ʱ½[‘É:/;/à »Ì. ¯6`°`cq}䈧•iS+w"S±Pgç¦FÔ‘Eó¨t€_VʲÖBÑ.w>‹0¾>î¾ÃA¢ÃŠ>OHØ+Û¶¤Î¦¢0Zâ¬úEÖ-ú<X$që‹èNh ÞlÏôÜÑ"x›Å¨Û!ÄÌ”.•²Ü÷°ÕûkÒ€êTƒõ ’ÝÀ‘±Á£¾oq¦«MQôØ#Êi‹?]¬‚U¸¢epO˜,ÛÇïÅ<–4M⾜‘->ã~ù›DF·(2Öiöp]ò]™÷f¶&L¤Ô@_¤/Dq¹²¬”·HÔmEÍÐH}×ÖLºt–ël{dÚí™®ƒ¤Óó)Z­}¢¿#øÅÁ,áëó%`fÿ‰Ùü8ÚZôÜ4ÿÇX}žFIÞùVìûSøf܆v­zr©Ü•YœBHQn™(§R*”õ­}j›ePÌÂ7nÎ$¾ˆXç;nõa/"ôÁeà/rŒºa„Ù‡Ÿ°û^˜T¬ Ÿÿ©­fÎ]Sð åq­k‡³Wǽy
+Á !R‡ÛÇ0Ì‘x£;UÞ¨’x2bLSÓÓ$~ºÅ„JUÉa7ÜlÏä©À ûüÊàÂÓ+Y+“=Ýú”&ŸcœkAØ™ÓOvå½`&nd-i³¬“ ¸Hιâ®1f‹Keê¨å¸F\¾H +G¬S\It[{Ï7‰ÜÌÅ&Œ6‹x³\]ÐýˆD8 æóЬµH%• J/-<WÆþl­5©òñ"–9©`@)N´G¥`J?!GéQl8K]Buájåñ'Gág€ÍU ÷*%F½ÑJ7>õ
+¹ Û¤`c­:úËR×þ“÷Kæ†-–Ü/þå%÷ýæ'|ïî&ýšÅü¸»ùùæ“5Šòendstream
+endobj
+714 0 obj<</Type/Page/Parent 689 0 R/Contents 715 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+715 0 obj<</Filter/FlateDecode/Length 1669 >>stream
+xWMoÛ8½çW Úæ@­ØŽc;ÝSÚlÛn¶u±—\h‰²ÙH¤KRIüï÷ )ʲâmšKÔ|½7oF?Ï&4ÆׄSºœS^Ÿ³1Í&ÓlJ³åOñm%•áÆt1Ëæ/o,—4ÎÒ»Á˜œ³E::Ë®:#ð—Ûéìôêpöà/Y ¶Û£SŽ§l‘¬¾_qtÃg4™ÐªD~óå‚VEp<¦U~.‘°kå…Ý“±T(—[é•Ñ|AiÒÂ7VftãÉo%ÕÆyZ §rªä£¬HTi韌} ÜÔu£U.øyG^<HG»Jä’§ôæÍêÇÙ˜F“KÔtUœ¾ù@¢(¬t|3£oJãdï*ž®ö'iS™5\í ö6ò- ]ÐFjiÃU+k¡à²Tϲ ‰½¸Û ëUÞTÂ"//m‰¸Þ†¤ØèZjO¦Ä“ôé.FuHÂIí
+ˆ«á󡛯w¸¶«ö)úé<›1Fÿm¥FÊCp\U879
+é¼B¢œ¥­pÀ¸4®Qã"Kœ£#p^|e\áðq‰éªŒWe¨DŸyÉ;4a#Q¸Ô,˜s­‡N7±yé+£Ð„(ïl:6(\‹Óµ5¢È@4VÁ?«¥ßÄÇ(!RGßoïèþü;sîVx±±¢¦døþ c~䜭„À£bw‘rÅOà[Ô¦k_'7¡wƒ4…r³É®_‹Œ¾´âÖ3΢‰>à¸êPXæáÎ $)¤|¬hFWû?ÙBG=éVк6e]cèSÛ–å»ãÿ‘‚¡Yi'ò uI3<ש@¡ï™ÉPÉ`¾'º|©+e‰>>”vÈÞbe§¿Õ
+¡q@ŠÒ4º´-xßµz¾ø[éæ™Ú>„ {@ÎHŒ8~ßÔMµ¬Íi60€Ô‚Ÿ<†¾Ã²×sàÝ°,3hµ==mj
+ à
+‹ÅpÈåVŠ V ¾´«Elc Ì»Nl†½ÂžÃîUPýŽY8à•ó¶ÉycÇØ]ź|ͦ¾œ¢FWÙ¿QbjÿEÇauy»Vºc*^6úÇê¦ò
+s5r3t”Ì.‚y˜Eu±×B†ÒƒØú'-žÝUR`§¶²ä oзvê0w:œÃ§²±8‰V¹0†~©Z³ÓÌÑÎA´óí btì9èÖ:EåÝa ÈqEꯅ-,^ÓZ!À¤_ÿ
+endobj
+716 0 obj<</Type/Page/Parent 689 0 R/Contents 717 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+717 0 obj<</Filter/FlateDecode/Length 1705 >>stream
+x¥WmS7þίØq>”LáüÆdÒÎ@R¦1ÐàL¾0Ó‘ïd[á,]$Æÿ¾ÏJw~¹â¦/0öÝj÷ÙG»ÏJߺÔÁo—ÎzÔPº8è$Ã!mþؾtè´ÓIÎèdx†ÏÝó³¤OVÒÆ,_ÿ©Œû6ˆÆ=,¨L_òÛã÷•ÛN?9¶—ã<·¯:tNã)u““~Àr:Ò8
+k¼IM^/YÇØco‹t‹ãïûw±ük÷»xÚW'Ôír;Ç~:î…¾BÜNASi<")Ð8fJHÍIZÈt.
+»jfs/AO¨V¢^Â"¸TyN"Ëè£Òå3¹²(ŒõA/ä³—šMÁ¶ \‡î¨(%åMé©ÎÛ2õ%§Å–qª΃ó4WHÙŘ GLrÉ®ÍÄ ¥·Û‰îé DÅ,ÝHy}{š3`—Y†2pÒ%464ãõ~®Ö}UÅ–:å>¨ŠÅüµ”Yð¬g؇ ü|§”„nF[å¾Á~Ê¢‡C5³}uZÕó!±Ec+5„›‡@;W|þJégØjÓ ‡¯‘J •¹çÍ„¹ÅÖŇ:×\MXíEÎxCº’¢#ÌÆÐR‡¦á›2´Kê œ1ph5ÂBú08P>~P\òq÷[QïZ@§KpÖD }Ú®³N¸±šxXšPõܼ·Â(íIùº&š¨Œsªª’‚‰zµ] 胙¬àã‡M¥ÔϹ`¸&s˱™,õ[Äç}Wº•Ibȳ_ÎôhbP#üÎ…>ª½Ô´nlýj"9nhÃöÕ9u¡)S{ŽûÐ>–—^ÒOâ™a{ä8*]U’ yËm%6àa—Tx챿m‰i¶2c%[11eTÎÐÍAik¼°œáÔ ¹ñ9àÿ£6KMOÂ*Sº¿¨çÃ!3
+«Ge"
+ý׊vø­´ͼ¢¯<+‚㳇FÌ N±9TM vCÁ¤<ú²ÈÅ®Rr ù,xâQ§ì9z<.ÇÍ‹é3óóˆµ;ðóF̵1—ªCƒ` â{¨Opä +qÌnA à'‘—Ì>š Ú*ÎÕ3ŸdŽç8‹.ªÃp$¯z;‰ÊC˜qq¡Ž‘éz"ÔT0i ôX ÿÌmmg(êÉåWEÙ 8K<)Ö<(
+sGV;¤o›ót ƒ©ÉsA…º *<#é|q…Å|a#®xpáØݸ`÷N“!.hçúÀÿY«o µæåNãÒîõšÑÅ»_¯oÞß\ŒÞ¿ít~¦ŸÂµò~_ÝNx[K­9[æ5)ËÉ‹ŽûìøƒÔÒª”F•3>LÈ.sððú_xí¸…¡).P×[÷_Q¹ýôÛ‡O·ŸïÞv'Œù—Ø®#œ\àýÒâ˜!m…±yÀþÀw’ Óße}¦³CM d«$Q]h}ˆÖbÂíQY¯üQk»·Ýt+‘w=”"{ks¥äf†mì…SQûjXºƒÓdpÚÅU¶“ôÎÃ฿]^Ð5_qV
+endobj
+718 0 obj<</Type/Page/Parent 689 0 R/Contents 719 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+719 0 obj<</Filter/FlateDecode/Length 2016 >>stream
+x•X]oÛ¸}ϯä)½¨ÛIììÅîI›Þ 6_»è>ô…–(‹$ª$eÇÿ~Ï”ì*@±· W&9gfÎœúûÑ„Æø™Ð|Jg3J«£qryIû³ÆÆ4›Ÿ%t~9Çûé9ÞI9ÖŽ±»‰k§ɼ[‹õÝRº˜&“áóëåÑé§1ýBËœ&ÉùÙ”f0r1»¤eæÓ2=¡Á¿/ÏþïùñóÓ¯“ìwúît*JºÖIC×Fo­4öÝòÛјF8ƒÃ~v†ä3nkl®¥£QIz–V—›xÊé§sšLâ(`Mç+Ž½ud Ý–­$ÕÚÉŒ\!‰²¤é®oT‰´Pµ´ÅZyŒ®ÊÞÖTÚ%a©t<&±Ò™Ð²P–ø·¦ üêœ9K¦ìLªkg𘜦凧ÓÛ',´F…Sº¶´-$âŽ5™âø`çO·;دHd•ªÅ§ mÀfþã©d“ äTºô´ÐÖYÒf`?.ùø° L8±VÂ$ÜŽîÀ¶°V§Jp@¶Ê$N‘eFZ›Ä§³äœ=z„á¼50l¨Ñªv¤sJKaT®RïÔ0Îï=J>†òs²>èwB¹*ªæôHbàF¦Úd–2Íy£ÆèÊäÀQ^Ü¥‘}#·k8B¹6U@å³}¿ /ªÎ@<`V²FÌ2ÙHXÓ¦¦uØŒÓüð ݨ”Ÿ‰av+±ól’2“YBW5ÉWQ5À}.Ç» ¬øt×pŽÞà ­`0{þVBÕ?K½RÆ$MB uw‚­h»}Žˆ›¼]A[G«sš¥ê5Ö•Z¿´ }=Ù(Ab`¿‹ñÊh‘¥`ö×w„­$붒`)8ì­¨}5ùÈb#ûºòŇ2ìõŸ_'éïˆ ŒÃ¿M#¿·5„*CbØ{°‘05x†EFº
+‘uÒaÓµÄøö±‘6¡/…ç%B:°]@ öÙ€38c a
+täÈ1iöéeÞÔÎ+¼ÏÇ[m^ÖF·Í1j–ŽCªaÁ @
+†@¥ ykùh¼xJ”¯$ÛBÂ#«Öµ/=^¡ó ‡¯JœáyBˆ¦­QnGÂ@ñœL°HZyÈMÈ,#e•C@vèy<ÜGäMm0ÂƨJ˜|><?
+Êl”ÑuÅÙô¸ Kž¨”fäôˆÿ¢<ÙCPuC}?aÙ¸ÚÓMÀ(WyU+Ô"Óh¢Žw®¿÷³–5XË¢k[P ûñ”ªBdP[šZ„Ⱦµ Á° è'b”¡^^jnh‹?®žoèþñãMâ×wÞ…
+2”¹¶“VÜüÑéÓû›Ê¶ÐÌ gtyàXï¿ïVA‡v¤_)ž3µîÑPh|^@àj£m|õK?/nž=þAŒ÷ñù1©dµo¹¿·Ê°1x‚ߘ@V(}pÜn×Ô…pØjDò *ž*°Ð¨nl…}–º‚ í3äzU/}¾¬Ðú;ix‡oÅ´EJ+°õítŠH>}'âÝÂK0ÝÇ=×è/àÀâþŠ$‹ù—“›B5ƒŒËq
+í6˜? K¾¥ Aºl}ÿ­$ÇDÙ
+­má;Çû ŠAU9Œ Ä$å™:N€Ñ?Àd( ¬±³#å²èà\ᱟ~ú…&sÜSFg˜¿yZœ&gÉ$Rçó7ý2}ìGvìšÎyÏRtPú½÷nk´¬šéY:˪ÍsP¤ç+
+NF9`¤Q™ý¥æ‡ìù …±íêFÄ}`Ô©JŽ4#–¥Ø!y*‘É‘B;ô8"b‰7‘ŒsthÇmšâ–ð„e*õˆµg`œï8a|Á•Âß.£>åó"ÔÉ
+50¬M|dH=´¡F¤ 0æ\´ ˆƒçc”ì¡Æ,ä Ò %…>Xèr|Kâ Âüçz>í°ª"ý@Øë•ÃýÖ‡¢_ˆj5œ˜x2؈’ïñ1öW«¸ã¨*—ñÊ8™áKË3šÏ’ñì‚•bqu}EOFû4~Ô)î 5Œ,uÔmÍÇøââ_¨Ñùü<™ã;1¯žŒù›åÑ_Gÿ
+endobj
+720 0 obj<</Type/Page/Parent 689 0 R/Contents 721 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+721 0 obj<</Filter/FlateDecode/Length 1744 >>stream
+xXaOãHýί(…/Œ™$0!ŒV'w‘ ÃïV²têØí¤»ÛÛmr¿þ^uÛ$pç™ÛF†ØÝÕU¯Þ«*ç£! ð3¤Ë))ŽýÉ„ö»Æ‡F¸\L.qý2÷'d%eG×–`àí‚åŸï®hxAQ»ã þHýóEÉɨÞõ)ÚHºøÛ·e´¤LåòSôûÑç» ö³Ñ%¶DåüsÂïÚÕ"Ïw”›DT2%¥éaIß•NÍÖÑ"¢ øf,pƒM„æmžÜ|ãïóÅ"ŠãåoËhöp>ŠãÛ§ù?fOË8žE7ï}8!¡S¾5 ³!|fw£+¡´£
+îÏiš¦V:Ç+ý­B$¥%iQHö U²§¥PÖ… ?8Õ`ðñh†„Ji3c „&«ëù·¥7ûÁ£Ê°¢ñ£e©ô (©Q¿Y=÷9 'óŠª]©’Fóì(WÏòkëÔƒ?ì_œèlô¥?Áoì¢æß1ݘrgÕzSQ|’ÄŸhxu5¡•XãLVá±-Û#‡ лͭãïƒ
+È-þ r¢(÷!/tà·Úyx÷'!éŽnrŽ®4øtž`^¤¥èæñóüN»J$Ïd[ê\MºvvÝ>û$½£Dƒ¿#“¤E‚/†ù™˜¢¬+i™®Óö[<ðÕ¯ìÍ@,B°vGncêHz–eEFƒ}àZª^T
+} ¡Zv&Áëî€0{ce.’ )æv¾Vð7¯ ¨òÜlßÒÐéxb,ÔPø¨ß²´U ¯hÐè´¹wÐÉRX¯{°AT”K ÔæJ¸Î¯Ä*œÔ;îQ²Áòö;mƒsk©¥õjð<CšR©M%=Ý@‹20®kN†‡ò5üÊèîD®$`‹?u&£Ó±wUQ•ZA[Umäv?]ЃÐb vú¯ Ã)/6ÆUÝn1mCÉ2Y&m(f!Çœ7ùZIí80_¸ú}”l§ã¾P?>Í~²âöÛÃ×_RS –þå'Kç‹›û_ogô »ÍrøÙ†ëÙ_ç‹Nï£ÙÓbýÌ“Ùâö]ǃW­Qn´Ñg¥Uºò4oiF®.Kc«øSWD]÷éÎ Œ­ ½kdŽî„Øæ?½qÚQaîyN‰
+U„ÃîD, õf-eF&*S¡¶ìåzý JJ*G³ý¡å•Å¨,¸æfèñéE%Àx%7âÅO ¡S!¦eæºÃ³ƒiQît›#gé„ßBMCÝ`HN§¤*n¸Zâ\'ÐS@‘;\Ò”D§}f/ås|—ñݤE·ð|+v®uH‰¼B»ZoøDOU°¥Ó>¸‰r¿Õ´ÝÈÀþ=/Ùú‹’èBž)KŸ¸ë«wüŸõ¤tŽíéîæmäB3¾Žº%M<÷l™ïÀ­áÙØ3e_µ|ʽ( ‰'ó ÈH‹ݼPú…}Ëôëâæl%XgŒÔ)àFÇñu¤ä„É-rõ/lj:E°
+;=¿­yüÏO*õuž/¡9”½%Ÿåü!Ʀ’ÑIÂDÛ¼FðØØy
+š²ǹЅÐ!SqÌ3Z!Qî]kíB´ÙAÚÊ5²pw©ð&€Æzô–Ž&ÿÌÌ ÎŽíÎng„’zƯÊãwC
+endobj
+722 0 obj<</Type/Page/Parent 689 0 R/Contents 723 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+723 0 obj<</Filter/FlateDecode/Length 1673 >>stream
+x•WmoÛ6þž_qH>ÌÅ’Ø)°yq7‰›ÅêŠZ¢c¶©Š’üû=GI~[¼¥MaÄ y¼{î¹çŽ?Ž|êâǧA@½KŠ³£®7Òæ£xÆ—.õ{Þõ‡ü\žO…¤96wq|ýÑn^¯ÝŒíVêWoÿÁ¿ò½Á¿O¼å .omû=rÆoÂ7\9ÿØ¥+
+çä{ý^@—pþârHaâ<îRw¨ùwBQÔ}Ñš´)E©Œ¦ÒÍe¬æ¯$h!_h)Ò
+!›ßµÑgy¡t©ô3Å Qˆ¸”…÷køí¨Kg>ÐÃ-ã‡Ö)\°Å45+6$_D–§’TšV¶,D)-‰4%3§r!­Ä†Rj ïì‡C&­“ß ¼‹¾w…ÿt±PÚ´ñÓÉãÓˆNî>=|в\™â;;D'øBÏ…©ò_,ÝݾÃ8®a›Ç"ϵÈ$9\ýþñú¢­_NÀ"%l&+‹¥,ÞsCÐc¹É«T[æêv¬©ŠXþ„mßa“šX¤¶XnÙrøl}ghd"Gd‡”ŽÓ*‘‡8´N'7£ßÇ“¿¯ïÃÑÓä:Þ8žÜÞ¾Ñ(j=Œ¢¼š¥*ÆJ¶0¶´ï;îrÿgG“»ÿ÷ðàÕcT3³d;’Ÿº¥–&ÇMŠ(6ºJƒ÷uõ‰ô ÕuÙzR¥%æ[c¶!Ç1 Ðq ÖúÞ‰+ŠƒÙ¢¼©Èï©3Áî;Ðvl²H(0Á¸A±Ð4“TY™tÚ’¢º :is*(–%Ÿ¦¯”
+ç }ûjK™±w•K¡R1KåÏ«ÓÄ”i¥ËÕjaàD퉥\ˆ°a½SA“eÁ´SŠxA©1ß«üô°“†¾K™óY†WWÙ ˆ@ëâÖ`”)­²*£T‘T–L¢\âLèøpX,®…Ä6 W2vÉRYFÃé;Ìo‘ìÍ™P ¸hØ·ƒ!H°Ë‰3¬30âóWä÷¹íœÕ}笸þƒŽ€Ö…úãÓ4œºlúücŸ|Ÿ wîᢱèrh+Ç ¦qé0§‡)}Q:1+K“úh±hKA½µPÛDOw6;·¢èËx2 £húuŽzAÝ=ÿ=M£h:UßøÐa·÷¼€ÝYW%'jüH×IRH‹
+BüÍ‹|8‰2^ÀÑ\¨Âz4Þ)
+š½Öùæî
+Ÿ­Ôí—>kõr~¯tõ²ð¹,ãóµúnCù)ãxÁ°2úÝM¦tÎÜÛlˆE.f*UåënXŒ ç  ßʲÊYÚDû‡¦Ÿ¯‘¨Ç›¹ˆ1¤g̸$äs å0<ˆ8qÝJôúG%Q~ìL=Áà<ûåŒf-\æ
+endobj
+724 0 obj<</Type/Page/Parent 689 0 R/Contents 725 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+725 0 obj<</Filter/FlateDecode/Length 1873 >>stream
+x­XMOãH½ó+J{b¤à|A`VÚ,ƒiçc«¹péظ»Û㶠ù÷ûªºíi/ "@ÜÝõõÞ«êü:™Ó ßsº\ÐrEiy2K®®èðRoñÏŒV—Ëä‚ί.ñ÷âÖš6X;Ãîþ¥[»¼:¬Åún)ÍgódÙÒ=¸y<™ÞÍè#=nhžœ/´‚•‹Õ=fröŒÓSŠ_;c=ù¶ª\ÝÐôÕ}xüy2£³9<ƆÑ:]¿èË^__“Áï™ÞÓ|ÎFςճťXÇ!»\Ãç°jWöóYoÏ8%ã©É5Ý'•eµöžÜFÞùqÿõ¼x’„Mi~Άáö¶ÙíEržÐg·£uívÞØ-mZ›6Æ!Ze3Êñ¨q”éªp{òZZàm3þ—ÏæD¬B"úƒZ9îA•kõÖg,^\²ñkd´QÎH­Ý‹žÐ—úalO¨Tin¬ö(âÖøÙD”¦¦¯º¹¹ÿö@V•xøtjü.ñÆò„6®&#:ç–É‚-r:Lª©ÙWšŒ%WéZq´OÈYöÕm«„® ï&¤Ær¦õ«J*u“»ŒÖ{Úå&Íá
+ÁNE‡Ã±#óz†ÓU¡à–gq•ˆ2žƒ#'<·®‘ùH £m3 õ¤ž­µ¶´5/xU4(öÈfDÅ~¾9ÿ¯/Ÿ¿=<>PáÜs[±;Úr9³ {`6t øp‡GpÞ-gìÍݤ‚1.í* ëÞJ©òšM×ÄmÝÐ_REñ>s€Ÿ§Æ#ü–¼Gñ>ɜ՜ûn¿ÂüT£MB\±¾6½û@5W³p©*@ìµÕÍ„Z[0ƒºÜ`ëQ¬-
+qZ{vïLÃ$ÒCdtv瑽œÑJ¥Ïºñ”*ˉ©]+­jòÖ‡í@kH¤ã°äº‘Jk‡JÇí1%¾³Øø¶­YÙ/ÑL#0¯ $Ÿ© Ñ1¹#·XZkÀù
+~—UæHX#Ó}wkr…êCÑ€"FYbBŸÄä|~6¿ ´€ü-äÀ·\"M}‰­hˆ‰‘] „­Œ1p³ÆUÓ²+a~èѢº6j@ðƒ‰ÈÚÜls J·UcJträ†FÖK‡^[ƒ§ QãRWâôàlÆ@’ÎZ«&/ñ®÷h<Š¨1yÿ”–‰.b|ÝXçA¦‘ Ж•IÂFZY:'´n™•^F :]}Ô‹2…Z›‚A/­kˆÀ(Ð#ÂÃ&Ñ<+VŒ—á¸6=txJ'>×vÏؘm¦ ¤hYC*žß‹ð=E^{Ò¢#@»¼I9ÜF¡ì{´æÑ!U2œÂü‚§#ÿsÁô
+I€ä Û¹`5è(ͦË
+hCf(TÈåQ0rG2¾ä,Ÿ³£-ú°2í²ú…ÆÌ>‰÷GÜ­å–y:Åp>Í!½žÝ?\?Oq¿!qΊtNïŽ^/’áðØw|¥Ý;±ÒqÖ›»ŒÅˡ׺” ꤷ‡;ÒÁ«þrøîîÃwÂR›ÖûŠ1T)ï¥V|K
+>º@Ÿ_ž'—øtbƆæK¶ÿéñäï“íÂkendstream
+endobj
+726 0 obj<</Type/Page/Parent 689 0 R/Contents 727 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F6 9 0 R/F8 10 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 187 0 R>>endobj
+727 0 obj<</Filter/FlateDecode/Length 1946 >>stream
+xXßoÛ8~÷_1Ø'ˆÛqlç€}h®ÍíM»wñ¢»@^h‰Ž¹‘H­HÅñýõ÷ÍH¤]5‡]´°-ŠœŸß|3ÌŸ£MñoF«9]-)¯FÓlŠ•ôñŸfÓy6¥ëÅ4[SE³Å2»éŸJz?ãíÍ:[ž½Å™5¤Åæ‰EÓ|¹È®h±^ñïEvM¦Ýh–-h¾Zá³¢õ<=ˆ~Z.!º"ì` üÀ¯N¦Ê¯^Ãõ*[EØ.òo7£Ë»Íf´ÙÁçåzE›B\Ò&?ŽUöœ©Œ>o>Ý¿Ìß‘kH•Îê þ•—Z5ôk cŸ<í°ìMU—šjåýÁ5m•×©6ìµ &WÁ8›ÑÏ8´wm‰÷ƨÒüWï6Œ¦4™]es2{è`žp–îo©n\p¹+e!i0^´A‹{Ñ°›­PþL§±d,ե§X #µÍ›ctqAÛ6ua {ë –@˜W•8
+ª=]e¯’~à¤ïŽ_!¡e9°…˺r…æ4'¼ Yæ}YžTbã™1R|;ÃØiM¶YG ¹§ïbà_ׄs*‰šQÃG„q§€!'œ)ÍKô€Â _Œ;ØU4®®;‘·*@Zµçl’0¨•Yv6¥ÊØ–a†§Îܨ8ò§'T¸D… «ʹá.¿`5(›¢1P€Jµ=2¾e&±Ž©’t.
+uŸï¡-wõqÈJÑôˆ+1ýÞäónÊȇðEŒò)錱 à8b_ÌGŠµ²~„™í:õÑ1•=áTZ¦ˆ³Ÿmô“¡»AOâÃEãœDÅ"(rAæ©ëDù Ýa³á,(Ð2ÃuÖõ$Ѫ’K="è<™” ™R+´C!“é\mtåðêÛ¢xÍå
+Ž(€„.˜"—dŠsdâ³À@)x°7Ö]E‚¢'ç
+2…VìEB2P|ÊCÒ”£Óù6ß÷Xû®ÉnŠ®r9¯)ÈXãÐ-ÝF&
+Ñ-ú»"âd8‰æ`í̹MdGªÚª{ Ò¾»Kµ$}}¨zär„£Ò¹ç¶Nã¬0+ž¹xJ—«!ûû£‘Ês¤óÝê\AaÜù픹nìÀ¼é¬*Lgñ‚CŸ³›ìL³AGnŒÑË»y?ö¤ˆ  ›âwšÆ'rI4÷ ©² tÑdHp?ÁÞÅ Ph¾âCç!h}pºRωL*óÊôÉÑIv¿U•-¡@&˜ý† '…û¼:õíTÈJß8AªOmâ¿Àï›ñ‹ÅòwâWµ>pñz-ÃÓm¥^MÕVdÛjËVïÎæG€ý¬¡ÃÞäû.m˘6x‹E·1<¦Žd9;*WfHfùØÆ&ôÎy`huK¨øÂtÀ’‘1N00OîãÇw rgDT È©Ï! ë®’ºa’k‚³=4Ízm=L@ÏŽᔇ±
+endobj
+728 0 obj<</Type/Page/Parent 689 0 R/Contents 729 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 192 0 R>>endobj
+729 0 obj<</Filter/FlateDecode/Length 1501 >>stream
+xÅWÛnÛF}÷W üä!-êîypâ¤5[i-#(PÀX‘+‰ÉUv—’õ÷=³»”LFE€¢¹ŠæìÌì™3gFßÏêáwB“> Æ”–g½x:¥ã?z…‡{ãx@ÃéŸ#|Ô’–°íáôáŸ`;õãQ°íÃ>˜žr;¦Ãqœ4¶-·þv6$ñ’~‘KNúñ8<ôÀiPÒ›à8Þ ØÐ=„W'2¼š.sHðýüìòÓ%Cš/ÈxŠ™»\æé®'1=Iwô5¯2µ3t?'aHT$j»–•ÍSasU‘‘z+õ/ógøD:‰÷õ'ðy1_ç†Ji×*£¼Úªb+ á8‰,Ëù¸!µt?Xª¢P»¼ZÑFh#RqïL¹ˆSU-i™òWªGW X úõGñÿ#"…_²Jõ~cá͘ҙ¡wô—4|¸GQ‚ª¿¶62­un÷0:Þç„]ã-XÁüü^Ú÷·³‡§
+I?©åÓ—›çm4¢&ɉKÖÁ"Á¿v§h'ö†<cX—{a·hR“ÒT)K‚jäÅ!Pìp)|È5ÎÚŠ"Ï‚uL³JòusãAìðÑrSììRéÒp£Õ¡3./°·ME:u.¥1bå
+¤UŠ‡·®6Ê¥é‚=×™"=©5òNU&ã½?UýÅ lª"ƒˆ>–üÀ5ÎWµöyá3e)R‹ÂRî¡PZ
+ÃôyåBÐ./
+¼Cléܸ[3A µªMÑæ‡c¾Gî©©e©¬lJ¾yÌú÷YºÔÖ®8È?–
+Ù¡ð§
+x¸¢À
+€LŽ”ìMÊà…J¿‘ªQ‘%báD*µ訪.Ì,´®Âuo7´°V–Ëè£Y-M]XnGDÔÄ®áÙt«ûÅpíüª¦ç™+µü^çL~w@¹p7²ÀK茫ü…DšªºòEgp`f\‡Wû¦€~œ.¯-·è(¤»b¦,öäÉ
+2U¯•--r˜ùÛ¼ÖÅÈ)1XË‚ØéN|“o¢Ö Øv™<p4S%
+endobj
+730 0 obj<</Type/Page/Parent 689 0 R/Contents 731 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+731 0 obj<</Filter/FlateDecode/Length 1303 >>stream
+xVkoÛ6ýž_q‘îCT”%9~të€ô¹MÒ-*Š¡Z¤cµ銒]ÿû>dÇnnÛ‘Éû<çÜûù$¡^ SÊFTÔ'6™Ðî­¹Ã?:OR6¦ádŒïI–²sj$Íqx€ëÛ·px8â€?œâB8ú-»Y:dY8:ÃÅf³ä|Ãw̦ƒ1›³Ù9<<`6™NYúu´<bÃÃçÏò“øÕ’„ò9ê6šŒ)®Ê‹3©Šf³l¥ %7f­A벪h&©3x:× Ý\>£¢*¥j‰wíŸeÁÛR+ösþñd@Q:‚ß\œå‹ÒP-Û…Tª•®VÒ¢´‡IÏ —a±ªôºTwðØpœ–¡V»ßL=c…Vsš—•|b­Ç¯4µ¡'l˜¥puÎ&ø„³GhYIn$J5—Moâ†×3No_<§ß¯ßç×T,8Òk¨âö½TbN€˜`¦µaK.P›s­Ñ
+¡¢ÛzzJÉC#ýi#‹®)Û ¡ÞÍ›BסWúN«‡íýB\Ñõ Ur%+[ò,£>dÙÈB×µTBŠ#®´ wŸâj8“&ldkõáêeþæúõõձܗ¼] “ØèZ®¼‘q©bÛËØlL+ë#>ÉiUÙ*l|©v˜úÎ*œ¢›¶Q®ys@ü‰8½Såò>‰…î€]%¥pH¶ ¸´ ·$/®ø‰ZK Ÿý/}È(ß—7ô¾TB¯ ]åq:€šÔ¸_*É(ßC·i›®h;ÀÈÕýsW6R8Æį¦[>F©å, C¡XÆFï
+Q
+v#þã¦wMßzÚÚ÷>e´‡.ºôÀ¢ àã 
+“áôöö§Þï±VGÿçÎ^'-žö¼YW®Kàãœú.au°ƒÇ1tÄè¹VEÕ̳o´ÃŽÖ3_ïÀG[íy%¿”³Jb2r¨7DJ/eùÌ0檇Ef;D/è¦#^i% à_ª]i2KY”` ÷c
+-µ’Ó ¤UBÖ=Ï÷t°ûFm¢4% Íô> `AW×ùVJ”lšº©ã) i»4,Õƒö8ñCZV‰
+Š¥ü
+ÖVfïev•Sïû…ß
+endobj
+732 0 obj<</Type/Page/Parent 689 0 R/Contents 733 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+733 0 obj<</Filter/FlateDecode/Length 1506 >>stream
+x•WÛnÛF}÷W àU€„%Ùrô!I›§HaõÍ€»"Wâ6䮲ËÊ×÷Ì’)šN]äÝÛ™33Ëo)Íð—ÒjN‹kʪ‹YrsC݇ÝáŸÍ—irEË›~§WË$%+i‹Ã3ººIVíÎr‘,êkÞ„îÓ4M?½¥ùŒÖ[˜¼^ÝÐ:ûXÉ& ±÷ÒÒ"¡FoÕ.X¥wôåýgÚK¹rÞªMð2'|¾Zÿs1£7ó%tL2©½ey¤Jh±Ã |E• ¯ŒæÃl:Åi6ýf‘&s\$iB·¢Ú:g[õÑ%¥ist¾âƒïI‡jïÌ–þÒê‘ÜÑyY9º›ÈÝ;º šnM)¬rw¯^“pteÉßpƒñ|¸ý¶¢Rð‘-ý¡tx|MÚ(xUªï’O6A¥‹Ú»/eØíĦ”ôþ,úlòPJ6ï^AqþHÞÐÞš•KàÔ«¾GP¢V:l6´œ
+ÞFUü-½€gÒD9¿Nb!q±År°KP%³Bhåª"” ˆ¡eæ#¯‘¤¬.¬­5|ZRй´å%<@ò¼4§çœTzk
+Ü
+V‚vpH9‚ÙØPÙRA;˜XXv6¤P"5NC¶T ‹Ö{-¦=î&½ª¿7G’¹òÜw”Î
+)ˆ2êoX"À®Ò «À¥Ÿ5:dèç5
+Xk’¢Úÿ |:Æ4uM3 ­ `Öê+Ú!ènö\®Ž6RFfô`:3U…~ÉQ9NæmçˆöäQȱ¡•)O΋ì«ã.{dà U­:¶œ: 0MÃmC‰STÓ(L`šÄ˜Ø" $ô»sܶc/g§{F2`´‘<Ø! v!zÍBWE&x„ɽÌ y3çÔèŽÕýþoלi)2‰ ›~šÑ[i²\Ì1l®’|c\þ b¾I“Yæe\ô2’¶el—–Øw8ä¿cÌ¿´Íu¨bð?×õž¦ÇåíÇËPzlá^"®Môè©ðeœ­%jûë™íÉ
+ûÿ–­é‡jjö»ª|*ù—›¬‘»1C«üj
+ÜÍOY­} ¸ÓwAŽh‘ú¡Ûg»e.ú)ŠUÆçÝ©-Vä*´¦#.Õ† ï$Äkì ó³ÆoDË¡’ûf ©“hyØEt__qtD nè6Ž¾݃°ºÕÚ®E_šÞÔ¨ùQ¹óôëî5í „_ßxðf=_»›F€{&oñëšÿdWyò6×~Ž¯×4;ëªû
+…‹54DUµøM÷·X&Ëø÷ÿ^0é%/•ËÕ2Y]ãu™‡ºbÛ¿¯/þ¼ø&ªmendstream
+endobj
+734 0 obj<</Type/Page/Parent 689 0 R/Contents 735 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 195 0 R>>endobj
+735 0 obj<</Filter/FlateDecode/Length 1634 >>stream
+xÕX]oÛ6}ϯ¸À0ÔbÙrœØ)°‡]‡ËÐ-Þ[–(‹­$ª¤dÇûõ;—”,YN:¯Ã€-âØ"/ïǹçúóEHSü†´˜ÑÕ EùÅ4X.©ûc6x3¥ëé4XÐ|¹Àÿ‹epMFR‚µSìºÅÛ§žÌf×x>_.ƒÛã=81˜6ûaˆ#+3ìjÍ÷—þòÃÅü&i~‹9…×ÓàÊ¿ÉèáâõêbòvNaH«Ý,´ŠÝASZE#»·•Ì©Öî´‰)•X +éÃèåê#¶" nëh"«hâÖÅþIkttIO-µ©ˆõ£ër°òÃKÚ©*¥*•”ë¸Îäñ!S‡WÁ ÁŒJ‘ÿfó5ûX=°C»TE)ÕVZgëAäkÑ…éŸFº¨„*üŠ{muRÑý›9É"2û²’ñ!G|@ïôTØTÚ€V©²]üo+m°M$ˆ4'Yª­™d:ÙIJS“Ò¨­¨ä¤‰ew’çg3àjã<»™´a_ŽmøªºAüüÁËR±*6¤‹.ƒL¨¼Ìd.‘ÊJaY‚÷º6ôk¡'?ª¢~$7N–zòå*zÒZ½U1»Þ“/æV‹ÞÌ‚š>dÈ© è]E‘(h-)Òy©2oÁ–2RÉž#C|r®[ÈÓxÌ÷\ó+Ð']r¬(“™º(Ø’së…õkÛêApKÔ¦6Íy5UV½…Û9Ѓ‚!‹¹Ïg“ùc«}ð}ó9»$+¥«Y¬£º+°pˆø -*I4ü¡·†æcedŒïI'&Èo¤XÙʨuÍé ZŸo™„Â`~5£1Xp‰Wôï7ß¾¿»‡Á”—qš˜óøs<CÅ|Â`¡x]ðŸ~ÏôF/¤ÙªÈe´ob`RÔ ”Þ‘Ÿk„·õ•P¡c™‰ýÐH麨Ú= å¯0>bÐþ3#ÚnÌœïI7x_…{EÞ¹9ezÇ`FËqž¿Pj4•ŠêL:íóX&¢ÎÐ} â˜É¸…D;˜ŽØ¼ÜÅëS*ÿWaä8ð+`t”òI¦Ö+£Ú¨jïz§‰„ŠùüÔŠüp$Q##Ï£ëLÛÎJkz`­³3­=ùÒδӄ˜Ç×¾Ô-Ëâí)ää£àQâI üìsä –ÍEŒGšGº[q˜xÝô•[¬ãù)£"rµmÓˆfŒ*9N 衆J€0hC‹g1‰ ,€‘áÎdƒÜ
+^ñ Ú‘“(bÚ¹ÕUZ[lAãðºÁ›m.ÑXÎx”Šbªm3†'üqßD{‰ž ¨ÿÌO$|ăê»NyMð§Õ?éJ¾r,ë
+ä=ÅA8•0½@e±UF¬Ðì:—ͤâ3¢¨M¤—˜.x_·V y¹Å•9OmŠªTTž B”²a€Vºë‚ &Ô1‚³Fd”@ð<¯™ŸóFV©Ž‰iÓr¸PÉ{ÐÛ8‚À3/Tt«î™6yì#uˆ…é¥V(³ˆsüÁ9'ïè@â¨F[£¨B¦fh†Ò%’ÝùžÍIÉÅ'¾ž0ûX'‰…fÕ|w
+endobj
+736 0 obj<</Type/Page/Parent 689 0 R/Contents 737 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 200 0 R>>endobj
+737 0 obj<</Filter/FlateDecode/Length 806 >>stream
+xTËnÛ:Ýû+fW¨=lɾ]8MÓUŠ¶ÐM6´DYl)R%©¸þûJrª¸wqa˜
+õ±ÁÇV×¢ =ÂíÖâÕØhÆ Xi˜†ôy÷Hﵪű7cœ‡la‰c莂Äs´,ùK EwØ,lI ôƒ#Ö¢lëŒ
+·!!˜j-¥> uôIj£Û+­)§†Ë.…½âçÜþÛ®øw²&ÙØÑ7ôO{Ö4žøä¾ ß'§‰+v|hÙö]§Ï"ä!bi1,ƒÀ0@ñ¯X>ݼªòB`-wÜ`Rzg´¼*öÔpLÄZQÚM…ÙF÷rbä¿‹e©{/$U‘åÖú·LAQƒøªA*ÍD^ÅkÖKGI
+m®@Ñ4Zõºó£õ4–’C?ŽÿÄk‰h{XDˆ£Ò ‰)|™
+Bìßõ„ô º Ì]!Ä3ybg;¥³/E\!C/ R÷ƒ«Òœ;Z­…–+Kïè|i· Ä7ö7¨o²ÕU/ýú1åy¾Ìv
+endobj
+738 0 obj<</Type/Page/Parent 689 0 R/Contents 739 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 207 0 R>>endobj
+739 0 obj<</Filter/FlateDecode/Length 1448 >>stream
+x­WÛŽÛ6}÷W Ї:€­µäk¤ÀnR7yŠv]EÝJ¢m&銔ÿ}Ï’ìU²(t°WâpîçÌì?ƒ˜&øi™ÐtAY9˜D¼é>~ÿ…ßÐ|>*i6fÍCAƒ›Ç’â8Žæ7‡ÉrÅ4[.p¿¤édÑ=ñÕÛgœÎæѲ‘ §«hE³E‚O>]Álxò§7Ï8]ÅON'Ñj…ÚjÏáP2KØÂj‰¿ãɾT’vƒ‡M?bÈß­_R2¡Í©Y,W´É}Fð&¾9ˆ£“Í"zg¬SzO‚>¨¬2Öì½UÖU*­Ìi­
+ùbói0¡q2ƒ’áãÅ:Y’«¤$£éQ”©`¶C‚í§12 áYGô^C]9e´ ’3乑L–,·9ȯ¬Rci;4½ÝÙí :Væ¤riám)…¶dvdåQTÂÇà ¥0{•‰‚NJžùxÿ!¯sÊU%3g*%½ð2ž/ÝA8ª­¬,´!¡•A|Ð%2WCÕñp±^ga2B¬V"ÿÖÔUÈßÑÒMõQ;EaΖvðÿ öY5‰l튓P…HU¡ÜeD¶4*²pRì%É/GÄ{#D%rJE!tÆÅ’.‹h µ¥A( ¥÷ŒDjjpgGpmeÎôŒ^Ëœ›¬.¥vþfÔˆ% ô¡¯ˆ²ÔJ°+…Pü`ÎP‰/‹ðØNׂþÐê •";(-i;ä°!0g'³BÁÄ ¥²"QÎÚ"˜ž{¾Ÿ¾rÆÔ"-$=~x§Â¢1ß®}fý…eFïÔ¾æt8:+wðÕ`åwë¤i·áxÌ'ãÒæ»^'ɹ´ýª3Ii­
+7B„]{ß´ å„ÌfBS*pŽNñ©hÒ ÚÈu¹/ *G©1z–z.…T~Ó#îëR2NUè­pÐ÷àÚ28ìðúSmqïGô§© ˜Q{-{j\Á âúUèºP Ÿ±pZÈ“|Þeï­¿øÔô:—#ºï´³ÐMúZ^:úð9°^¾Pú³mãå¶ö¿”©)TFáÔÃõh”vÜM f|Ml@…ü"Êc!Q¿ži{«¨©D—ÎOµö5þÉÇ÷ªa¼ÝúœÄýX›¢„„]ƒi µht¦4ä·UÛöt[œ©Y ‡áÀ®G™ÈÀ+AQ«Äg`ĺ/ÄU¬d0 < l²%–«
+ùÇuPh¿Ýt(ѯ˜WRôCÇÖOiì^FöávJ´+o63·Y%1ÃFgæ"ù(W»‹g¾
+kHy ~>ðÆ’‚Áðwõìbc“scÚÀ
+T¨R… Ì„½1`ý'¬"¼ù’8ò­.>BP!ç†ïc#)S…™ë3„K{€ ±òyçKC]«+x¦Óh93@¾sIo×å–#»Íe¶œEËþ›`¥É„ãýy3ømð/*‡Mendstream
+endobj
+740 0 obj<</Type/Page/Parent 689 0 R/Contents 741 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+741 0 obj<</Filter/FlateDecode/Length 684 >>stream
+xu”AsÚ0…ïüŠ½•ÌÄ6›cÒ”[;í„N/\„´ÄJ°äJ2ÿû>Ù&m™†¥Ý}ûí[~Í2Zà›Q‘ÓrM²ž-Ò­óeº¢UYà9ÇÏ1‡ƒYžæ×»ÙÝvEYF»#r­Ë‚vŠg± œoµ§SOžµ …ŠÉ÷õÁž´¤“6¯ž‚¥ÆjâC<6:ë^ÉW±§Þ¶Ô nIE>èIÔ‘Þì^f Jò5ÔîÔü‡gçÉz<úDt&yÒl‚') ÛÑÁÙÎóP—(8æ«)¡ÒÙ‘´ÇÇÇ2û½:ú”î¥dïµyUOµ³%€ vìDuÃáöó®Ò²"Ñ4,ΓҎe°N££©ÏQÜþ†‚xÅÛv?Þ¯é28Û8-¸@FÁW&h“»í†2 ‰ãH–ÙHg•føÒWØÇØ?3Ãà“<mþS@oØ ³ŠB ,Bé# jŸµm=tÖ¶5ñ½±&¨Q$iOµPŒ«ñCh„sÖ’¯tƒ¶ ‹!€|'úŒ¢p„³ª•1‰ánJ=Pƒiøc»¤Ÿ—““"-3ºLgŸ¯ ú·éáüÍ:ŸZç`”ˆ½bÇ<jÂ{ÁiôÀŽ¨ýÐ__Ça“5†æ+ÛžÁáÒÉvì¤ðü®¬ƒšÿWÊEëœ<ËÖéÐSÓºÆzö·c¯“‡z'ÂW‘Áˆ÷8<?^l=)«Äï 0Wº‰+t5€†]­alkÐ vÔÇ%D·Ö€†b¯Ÿ ¼§&{ÆEª­ÒÇÔõ&ëq•.^ïßÅpiô/å4µlY¦åfIY‘§e¤õtÿåáž¾9û‚å¡G+Ûcq&±$[ã?ª\RR,6ñþµÉWÅ*-Ö%ö
+endobj
+742 0 obj<</Type/Page/Parent 689 0 R/Contents 743 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 210 0 R>>endobj
+743 0 obj<</Filter/FlateDecode/Length 1702 >>stream
+x•WMoÛ8½ûW rrGÇN÷–I7@‘v·ÝC.´DGÜR¤JJñúßïR’e9)°(Ø5Ÿï½þMé ÿ¦´œÑù‚Òbt–œá—îÏçÑl±L>ÐüÃerIÍ.—ɲù¦éqÔÿ^ÐùtžL{Oûßñt±è,ñ»pCóåìÎaõŒføï$mƒóéôøÁÇÕèýíšÑjƒ¸ËKZe!\ü’Ž¯sQVÒÑEBßîïþ¦¯ÒÊ{e }T•'a2ú¡Lf·žîWïVÿŒÎèt6‡ñUšJïéÚšÊYMŸ•¯<`wSœ`w§çÓdƇ/’iBß•Ü*󌦹0Ïü%¸-;·žjÏ?W¹„Cò2­ªvçéÂ\¦„¶Ï»9M§»Ù’ŸÞË-)L<Šb-¸LÉ…ÒRxIʇGb­4,Óƺ^Š”j% 2¯,"‘|R92¢R/²‹ª
+Q†
+Åo™ÀVÚ’ûH8ŒšéHp‹tÑ\&Ñ*a`Ñw-Oñ5ýI[Uå¡òN=ç–¿®«Š³€vpãÑÏL9™¢±;fVë/˜JfAŸŽ¹¢A4 ¯~»¿¦RTyB?rôƒ;]HSSiKZ—Ž ÁÀ!Ål]“¿:‹bVJÈ>&°Ñz h‹ ‹3l¾E^Ûá“h혵T—!
+c]!tL jü Ufñ„‹«Ô’ÀÇ-(!SAD¯Äl±Qº©l ˆ¸Ÿ±Tïo÷é=öôíým‡Þ„®÷5AÜÁ8¸²³5Âc/™2c»üä¨p{I:ãGG¯êL±œ ϱ6 Í~Ùé|®ÊÁáãrµò 7-àB^©`JàØz¥s@PA#ž%]AÃÕÒsTeÀ&~E}X s©3æã+¢â({Ðe)…#•®ð9¾Ío*W}›0zE‹‡m®Òœ+`2ž1?¡ *=x1<Ɇ¼M™C P猈D >GÑ€’½^BÓ \CætS›”UH õ<p½%nŽÈ¼W©BbD/ÖèO>0[öÛ}Ññò*¦×ÃìA¹!˜Ü)Â\S%Òàè )Üø¶kƵù2žï·ˆ¨L¯Ã±SÁ@£8ê^Ë⤃óÉ
+úã°ÊœE³ œ<Þ<|¿yxz
+˜}f¡a;Oï‘÷^‚Üb9Œ6»± ³e0dõñîËc°ÜF•=z‘n2´Æá¼a+DRí/"á×m>$fW?îj\Jqäü†ËLúÔ©2îjk=© ÄöÅŸ9æ~QúÍ FXÖl‹lµ'Ÿn®QŠb]é§P
+ï·Öe” è26ʧwz}Ä•km—‹fÌöP‚¸¡ ‘Ì­˜¶Ý¿‹zõæ*ôûMf±‰1ÁbÙÚõgüúÒÓÎè=¿:¬ú}j…j¹ï~+ ½òÜ
+[d/‡à"S¾Ô*ÖN
+ÝŠmäÚìïû9 cÉ+*v8¾„M çV¼¥Åš7>ž1ÜØ›ýÊâ¬=Z¶9ñ„®p5áµ¥©f¶y˜ë|…d£›aQÆ» _ãö˜Á€‹mã8Õf®D*7µÅLÖv¿¥q‰AØfßz:Æ•ÄìkÎåþZpqÎ7°ëÿu9¦·.Äóå<Y..q†ÍÙŒ3»Yþý 3]endstream
+endobj
+744 0 obj<</Type/Page/Parent 689 0 R/Contents 745 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+745 0 obj<</Filter/FlateDecode/Length 1794 >>stream
+x•XMsÛ6½ûWìèbeF–%Y‘^:²cwÜI7R“|HÐBM,
+á×¹1³
+‡¦"h×[Å2w*ÙògƹÂ/ÜP“-p/á+¡Ó/×W€"Q2[)ÂZ¨SL±pb%,jà» ü­o[naäï /drG"JÉ–E¡{%+½…µ×Ò~"R[‰Á¾í‘UE!Ï9–¬  +€àÅb©Cöåjp¬VÉÞ5”p«sÙaTÇó&÷½H7]À|濾r_éÜöº ,CÓB@¶Õ ±JSî|eLVï¾%퀬¦Ûcx
+õFœÞF š AÃG§¢ƒgßy‰2Ö½­_ã!Ý°Éû½Ä´‹Å5߉•uà­
+ÈÉj[ ´Êý¬sk#%ÉTf@•)0¿úF'cvlŽt¼ÁŽêøå˜VÊÙÚ–7Ç:(¶‡ÉàAæ|þ!éÆY3ÌÚ4=¦zåÇ(y¨º¯³æfþþ
+«ÕéMÃ^½éd ”½út¼°Dä¨KéUŸ!اdwzY™¨—=™Xæ³X XhEÒÚƒ8«‰0*­ñœìÂ{YbÑåmcÍ‹é§ÂÌð¶±rÝ
+ÑネŒ9,ür¨¢2¡ýXóìá­#´ŠuAÛwú™n±ð™s‚%‚™A½¶·Ÿ°¸K€ÆÒiH³‚{cX 4ÆEªE\O—ƒ:.ÅSW;¾Ôõj¬KÂAÑ°ìIzèoÖ
+ª€È¤Èý4Ï=Þù Œäé‰dþ…Tƒ´µ“é¤h×â¹Þî–a9ˆ ¢È´¯õ ,àÖb ÖæH—ÆbitÃî5ý„’ã‹ ¿¥ÑªÃçoh,ÒgÍê"nþ¦Á4Á5Þ’QŽµò£³¾Ð>A ßd“!}Ü­Þ÷ÿ:Íêg1myc7µÝU‡l¸ë
+endobj
+746 0 obj<</Type/Page/Parent 689 0 R/Contents 747 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 215 0 R>>endobj
+747 0 obj<</Filter/FlateDecode/Length 1689 >>stream
+xWÁrÛ6½û+vt‰2cË–,ËNoNÝ´™$v«Ó|HPBL @šÖß÷í‚iÒ¾t<ÖP"°x»ûöíâçÑœÎð7§Ë¯(ÊŽÎfg´Zãsyu‰Ïþ¦D^,Î/^}³³æãûïGËÅœ—Íg Êhyy>»
+_Rºf®ð:£Åj¶¤?ó‹ë£ÓOKšÏi
+VjSîÄ_b¹rq“«Ž ”)ÿÈtˆñTì†MèæîžTY:´Â/äžQ0>HÇ–êQç  /ˆ"[å¥$n#OŸAR(§2 Œ"³hc•ƒ^QJ¾*
+ëÊaؘXºäóÃTª”Ç4Ó•Ì”ÊáÓžÐY!ûx»×Q…yA+ªMšR¢L:pI‚§òp^—ÒÉuiïéFçFÇ“!Ð ïÔ6P¾çý4JŒó€²®XÊm‰¢åêEtx|P<6è0Ã@SÔ(ÌÔÀ6RÇŒñHD“iˆ*íajÊ°g‹rDd®jçPu tXAaøNgŒ¸p6ÒqFª ˆÁŠMÌN‘~F˜K= ÍÃû­Y!2­ LâöÞV0““ÍÓý
+jIµN‡™‡8àHH*×Îð^$àE56wÊ¿ByÕÛF((Öž‡©F]¢Ø—cgŽ ‡Þ3)8ØOp%q6m~ûî6~BȃB "ÈzÅ{sªùO£¼Þ}f©(ÆP8p™ÃÙp‡å§(R°žås’Ûžo~‚ P‰Š7±žJ  @O}O} ¤¶ªñhd™G3J­#àý·ë±O#—’Tm!˜žbí#ˆšŽ˜ÔÁnI’¦¶ö \Ô.~É°Šå÷Wz•Í#-ûv
+EÖf(³F58µ¡Cd³ÂæðpHŸks#‰>нž¸É1MꉔÝäyBSâu‚カ=NÈb½L
+Ò®8boÕ[v^[ÛXìŲ;ÖîÀèÀ¾&xý4ŽŠGäc/)éá›á uèR<uå/*(LÊ£
+°ÏÖ§ÏíØ
+}JZ« Ÿ:ô
+®’F8_fkÚf`
+÷ñ«sÜŒq!Ž§÷×ß>^ÓŸÎþ@‹¢U´_.R¼ï¤]~ryöáÿ\:——ËÙåê
+Wq¶X²ÍßÖGý‚£4endstream
+endobj
+748 0 obj<</Type/Page/Parent 689 0 R/Contents 749 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F6 9 0 R/F8 10 0 R>>/XObject<<>>>>/Annots 224 0 R>>endobj
+749 0 obj<</Filter/FlateDecode/Length 1303 >>stream
+xµWKoÛ8¾ûWÌ-.*²lKî{H±Í¢‡.v7>öBSTÌVU’Šãýõ;CêA+^')°0`€"9of¾þ˜- Æß²–)ðjG1~þþþ}–lVÑÒ?BËdeݪ„ûY¸ÆÝuzº»N¢%¬Ó,Jèîf=¬ÜÝ`]ÁjµÂ»þ,í†kÜͲ“]oÕj³ñV-2´Ñ¯œä`zÓ%ê vƒ5î~HOvÉÏdG´8K¢´[ØÛÙÍÝ
+ Ø[ºÉ`›;´bØòy#t%‘ª6Ñ»í·Y ï“4Zá™ù'cDm%+Ëã5ü#´‚´d v/€ßÜ%๼ÕÒ¡bæ»ßë•ÎÝ7ü;ÂN€Õ‚Y‘3ÀÀ ªðrIhk„iüý´— µ²S‘h•: «h­^,1^h5ß³úA\«sPµð²™FÅ{eèУ ð·¦|.Hµ³R<5¥äÒ–G! 4L³JXg®;`•“mð+<²²äá ¸óÿ,L£LÖhõ(s1õNU ³r'KÂú íîYµcD1Fí°ÎS2plçŒw×Ð2Y[­ò–‹<‚­òP`@\
+¥¡3ÅŸ'‹ìŠ“ªDþ¤[ó O_®?f¯)ƒêIÎùèËúa0òPP{ªèòÀŽÆp¥ê«©‡ÿGUù
+s,p¹Ò¹ÐSëïäR n•>v´qHNÈyhXå8"Vøé’ÐÁìÌ…áZî¨ùìÔ£+ÅžKÄEú£4Ç”žjà„)0Ú1²Ë™HD%v¤b*áÒ5ßÅÎB?èX:Š»XÿmÏ+";È™|Ì9ãÜ`0âº;bx
+Ö–˜ ·¼ØPU$.룜&ñ—Á ¬¿çEë'v]<øƒGÄ.ÇFÔõœ·r×Ä–× Ýža¦!…tß ¨ñ¾srO(ÊuM†B^ÉZ"w1,aàø…ú¦ë*~œ1{ä êF²4SV0–jÝ oT­4² ÖJ)ª~×BiPr-Ûx`Ð4‘±3U‹NÕ8U(gSÛ E8kÐa¼íÔšNiÑ¢!\Ñ(U…òœè~–ÚMGHHu>‰Fw)Ü.äJ˜úÊú‘Ï©›[ÉÛ’én.qM–°£F{Mò=”¤¿P4#DC™õÓ;)¾¹ÃGT÷*†Sí"t¨ø:_}çOc<Mu=Sw˜˜FpYHN…B< ¿øKý» xNŒÌ„ü¿º9° Ïª3ÜC'§z˜ŽAu¾ òÜ,­^øX^½·Aø&·ÃAÛÅ·˜ ^÷#I×ùÞÙ~(ôM”>@ãÍlîYsûåã-ü©Õ7~S¼­ðqæzÁó¾?þ>‹?Ð3h­#øâævÊ
+endobj
+750 0 obj<</Type/Page/Parent 689 0 R/Contents 751 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+751 0 obj<</Filter/FlateDecode/Length 800 >>stream
+x­•OoÚ@Åï|ŠQND
+bȱÿ"EU“VqÔrYÖ ÞÄÞ¥»ë ¾}߬ 5$—JU ðì̛߼Yÿ¤4Æ_Jó M3’õ`œŒ)›L“Ís|žàß)Zųq–d§>æƒË› ¥)å+äÊsÊ Bžñ˜r9,´S2X·£Zø—óüy0¦Ñ$C¼®¬“Šz!¶Pry3;$<o„4^¤JdWJEáD­‚r©¼l<Ç”ˆNÚ\×”¢‹MÓ¶ðU2OèÖàŒA[C[ʘÌa
+zõRÐJWŠDN/› ÐÃf£Íú­FnzØAŒ'okµ×÷ùþ¡—b©ƒ§§¡odIÂÓ™‹˜jwötŽÎ‚2ïnÑF¹Z{}žsµjÊKí;é4™påZ Ä
+'²Û‰\pQCwyç¨aqÀ}8{‰ dd±tØDX¦¥ëiÛ²ïm<69DÁ¯˜Û[lmý§óv-i¿ˆ˜¡Xáz!lG`à}¼W‘îá*ùg¾=¬'w¶9AƒhªnÀ²y*uDw4ËOÂHU½™§è“·LÄõ9:òþø•ñ ®žÈBíÝ)ð+¼NöU9§‹B™è÷Ë›Eç¨4Ãkf1¥ÉuŠw _¢¾}ü@ß}Æ{ƒ>[ÙÔ
+‹Å·4÷7ÚÍÇ×ÿ®òÙ|–̳^È7ɸ̗|ðcðæ*>½endstream
+endobj
+752 0 obj<</Type/Page/Parent 689 0 R/Contents 753 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 232 0 R>>endobj
+753 0 obj<</Filter/FlateDecode/Length 1827 >>stream
+x•WËvÓHÝç+jÁ"9'–-ùÍ.<2à €Ía1aÑ–ÚV3’Z¨%'áëçV?GÎpHrZªÇ­[·JßNbá_Ló„Æ3JË“Q4ÂßœÌãhNÓx%TR2ZDcUÐê$žÌ¢M³hÁ§³eû+>…ÜK¢ Ÿ-ÆÑÒ_Φ‰}{ÎÏá·‘´u/Å3\Ns¸á÷p/—°Â·ðÄÂÝçÇÃ'ìßÝï™/4F.%M’lÚ ìègˆ~ñpöSƒ6Ói4u¡Í§
+ù›É tE k¤+²L1@¢ mWY¬D¡Ú{Ò{•ÁðæÞe-o)Äè½¢iÑeÒ<gÃh®A°ÊµÕ ¤ªÐ"c”-P(mÖ
+Þò°“Ÿq÷âúÍÍÙSð„ì
+Ïx í7Žéˆv½HSi ½Ô,½U$Cm_¾åÚúBÝôæ«L[ó”ëÿG9&ˆÞ£‡BÃ0¶°þ­“$ZÕ]áÐhóFw;§C‘Üëhi[nÐL´bU2KSƒu?ˆËW½9ø©ØÁªæD¼¤A
+û­SUHN§Ç®
+«vmZx
+ è¥ E³tòزL</£ˆ<â6)Ì(§q² ƒñ²äc«!y—«bD7÷=¿Ai—wAçQFÈ`ê0SÃ7Ó`<SǧdB„¨“¨îéV`Fi¤mcûÎpã% ½Àúu.ïI€Õ]«
+õ¡A¿@D S?éC|ÀAeð"€*
+}Ë]­èï°Óª´@¤%"
+Gðê”fñc¥òoYó6ˆ,:~:;µ°gpäS ¸ cë<ØzˆÀ©“ß× „Ud»
+7çx·©Ð˜[ˆ$óãi­”}öÂ68·@rdB`©„¾[u ƒá°ùú­€[EàÙ‡èEœy½wep5NïÞ3 Öëû)7û¦_«Sv.Ô°îJi ýÄÓ¦–©ÚºM6åneÉò¾Ü2
+tªlEý'ôÜG‚ a–qÐÇú­¤³ú”UË-ÚÂM„•É-Ðg9¾&–§
+endobj
+754 0 obj<</Type/Page/Parent 689 0 R/Contents 755 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 241 0 R>>endobj
+755 0 obj<</Filter/FlateDecode/Length 1867 >>stream
+xXaoÛ6ýž_qÄbÙ’mE^P`i»lÖ¬[<´C3 ´D[J$Q%¥¸öã÷Ž”lÙMŠ¹M,š<òîÝã»s>Ÿø4Æ?Ÿ.š„'coLa4÷¦4.ðàGKZa"ŠhÿK¯1Ãhì]´Ký(ôfÝâ1öõº_ü|âϽ9M&3¬(hì9Ýô†E³ƒ9ßàË$¼ ý0òÂvÄ–ý1fçc¬rkílo\PàO¼¨7ñVÁœƒ©?äYÓÞ³“±ç÷g{cž{ÁÁì~ŒÙY¸;‡wž>V;W šL§ÀÏìloŒYkÛ›í1q@½ÙÞ³óàp¶7.hêO‘‰½mŒYD4éÍr¦‘q›èi„YKŠ× &L?ÕàÅèzNþ”+0+DÂ"Z$– cZăР<ߣ7ZŠ:+×ô©ÒYYÿ÷Ùâádt=E&œå0¸€Ýà¦$¥©©VdšªRº¦:•ÔT¹ o Vd·ÀšDgOx[e¹4ç´U ©1Öø«r•­ø-ì
+2©À …Lv^xìƘ†àJÀÇ/p¯àSê43­`œ`ÏÆYIw¢XŠSƒÇZêRäX¨¬ŸÖËá×–²‚ýeM÷6aŠÃ1R?e±<:½1Ø}¹¥Y™¨¡Û… Õ.—¦
+¨§,Á-8+¥ñ€mÉhÝŸuá!.Âû ™T5yB…J²ÕvçŒÔˆÆKasxá0‘$vÅ:WK‘S%4°AĆD‰E1§UÚ5+•çjÃâ|Eæ°¿
+Y, K§Ir¬µjªžƒb¹ÇãÀ¾EØÑØajd½K'».uIÓEu`­•ª™O`YžÅYàÅ× —ºrúŒáÁzE?¶n·K!W¡ Üö¹À9%05Fr‹|dø:ŒÚŸóv¤Ö¤a¶}6œ¥á%#õâP-!U"Ì—6¹DN˘éXåð°‚„ µÛåœY[Òy“2y¨K†s£ÁÊ3SŸzDoR?:¶ƒãd¶¦–!IEfL¦J{C ñ¸£ÿA ‹‘õMĸ…X”p¯ÚÚ+c­8°Pá´§AϺÆÊ4cQ©Ê¡¥C»qw,„B)’_Ƴ»—ÿC=HAÇ›s>˜wÝ«ù°»Fö:µºêÖ ZÅì7;40§­rh¬)ŽËð]£„<!òIæ¼,w@ZèR9·+>–†Õy_Lš*tÑ·ro+8eSj ãÑtzÖ‰áý`vF2U‰5:#ÈG¡È¬Äc`ŽÿË:tü3Ç
+ÌFËÏM¦e!Á
+U*Î3Ü>´—t¡ã•-®&Ú-8i[綟3Í2BŵÒè>lþÁ*‹ZÛØ«‚˜dèÔb0CH’í
+¥ÀG®)::¶õWÅy…¦®çÄ— ˆ"Ë>Dë8U¨}—œv¿N`nåTÑ}ÚyÆVCÇ—’ËÇ¡ßö[
+endobj
+756 0 obj<</Type/Page/Parent 689 0 R/Contents 757 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 244 0 R>>endobj
+757 0 obj<</Filter/FlateDecode/Length 1971 >>stream
+x¥XkoâXýž_Q‹VjZ
+¯Øý°"¯Y¤„0@ÏhµÙƾÀ¶}_;4«ùñsª® †î©g;ê$ؾõ8uêT9¿^u¨¯ ºÔó)L®ÚÞpH§oÙÚäzÞ-õ‡üÞíã×LÑ϶qúø­zÖo{=yv€›ƒã£ä÷û¸Á—:¾7t×ÉoÝ·r‚Ÿ97U÷:ÿáªw;DH·£Ž×¥„úí>wŸbZ\Õ?㮘<Ýý#7tÛ!aŽxäãIÚEü­;lÊ]ÿ:bêû;Ü­lñ‰^ïëëwË«›§6h¹¦Ž×ïuÉ·þ–‘
+¢ˆJÕž¢L¿»»SÐ"HVmͯɤŠÌšò=š4Ò¹6©¥¤°9ˆ#ʳBý
+Ð0Ûyè–þ›»L§9îQ¢ÓsïMŠµÍ½ï ˜+Þ`|]ó"³êZ|FpVØJl®ã˜vÆZe-ßâ@™«»Ö±’»-V‘Î`ÁdWW*UA¾¥Ký„Úb—ˆÍU™{¾ P8asd·A†ãøFVI=?d*@ÙÒøðVŠÔ:(b—zË5Y«‹b ÙP‡×4TÄ,ÛrÅCåŒ8¾LýZ ¾èìgï)r¶Ö„Z>O䚬Nv sl6¢Î/¿–›C±
+«ÓMŬ·¦É¾§ªoè¯3“ÀLMú^û¦û™ÂX£Á<zÝ©”S…æÉ>_Ä2Uz³]¡º[c¢º“/*Ÿ¥Y Œ I|•Al0ðÈyãÀÁ–± XºT¯/œ¦Á»Þà™ª 3Ç_ëy^bH„GÿBqìÖèn«|Ò)ú>ˆ…ÑŒš¡d>ÈÅäH‚<Ü2ÓPƪ'O."
+Π]fv*ËY¬˜ýÁðýV‡[Ô‚ ÇÀ9Á©
+ƒ4ÅPÂxˆ´ÝÅÁAE-a¯$BÕªv§B½Ö€´b
+‚å“:µ9ôTE<_¡\vgL¬²‹€kéKìçþŒ¨è>ÀŒx¥II« #5ûœ×¼–Ó}¬CѤSÆMš
+qOýÓ<*‚@cYYÀ« v
+bk¸;ƒÖ•ÄDz}(óù†s[„Û‹ +ãûg¬8 ztÑûnyp²ãÚae¾|:­ÁÆ06²i„&IÐp9iAH.Æ
+endobj
+758 0 obj<</Type/Page/Parent 689 0 R/Contents 759 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 249 0 R>>endobj
+759 0 obj<</Filter/FlateDecode/Length 1596 >>stream
+xµWkOÛHýž_q…vU*c;!I‘ºRÐfU KÒ‡”ôÃÄžÛã± üû=wìIBR+uA„83sçœ{ïäßV@>~ê‡ÔéQ”µ|ÏÇ'›—Û­0xêº^—2
+{¡4O)MZ»Ïuü/ÜY…!êvNøuÐÇkˆ?-iÙ
+z׃KÞ
+º4]’Þ
+qHaDšI‘[iï8Ö±ââáÇ$PÀ“µf…UÁÂeãÏì¿1NyP>›á#€Ú|.ÿ=Ì@ °ºLPƒ;Zj•m*§©ãÑ•¸‡"+ô(
+Ž/ßw8¶åZʜ̟»ØÖžG¥·)ÀH$*Œ£­ YÃQYdÔ»+RIÎ$‰µ`ÏL"ÄPkOåØ‚b¬­öƒ&§=¿"Î’ü€æ‡ì
+3ÀϬT•¢’¡°ÅC¢*C#Zˆù[§ ×
+&"[(ÙÉ£´²Í
+Ühî]þƒLœJbÅŠåRT)t)2îÜ«íX!ïn`#nÓ~ÜŽX&ŠÍÖýf¤)-«<²ZX&È~Ê­q®›Þ±%×£¤¯ eÌiaø
+endobj
+760 0 obj<</Type/Page/Parent 689 0 R/Contents 761 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 264 0 R>>endobj
+761 0 obj<</Filter/FlateDecode/Length 1966 >>stream
+xW[oÛ8~ϯ8ÈS
+ÄŠå» ,éL»ÈbÚÉL=è<ä…–(›S‰ô”ì¯ß¨ PLo)Eò\¾ó ÿ¾ÈiŒß9-'4]PÑ\Œ³1¾œÿùý?ÓE6¦ùߨ¡Å$›u‹š>_ô– ­VÙª·×[6”ÏòlÑÛ쯱»Z¾¸Ú_74çg XiÝÉò…IÓUž­i¾˜B_C3Ü]v+¾Û_cw>Ëæ½]öq>CöÙ¤[ðÅ<_fSšÍf0ÏPWa··fƒ×Pú¼Û_c Í{»¬t6ó¿€aLüµ’ª‹ér K&«qP9›2¼qÅ*ùÚd±Œ^²­qqÞš3¤‰“Éó5G´AÀçWéZ>f×Þm.n>¬CÚT`Ëb…ÿ”$cÚWPžÍ3º-K¥wôIžèÞ*í¥utT‚ü^Ò¥KsrôiC·÷_Þlþ‚@¨Î£ÀÑd W”•hkMŸE³dªŠ¥ˆº¦CIn/¬t|PiY’Ò¥ÄAÚ•k¶YatõRÉŸdK.“mY–]ReêRZØ^;CòQ9Ï.(Í—Ç4ʧÀ–ù½rÝYÂÿ†•eòŽþOX˜ 2Ú@Ü¥“‚[ Û͉Œ®ŸHóq£É1€
+>‹KZnµNZÖ$¶µ$oȵE!«Ú—å£,Z/Ihúõ uçÐûLJ«üÂÍ£´o ÕïI”ÒpË
+¯Ž’Ýõü¨GUË
+䌎§ÄCñu©j¡¶ésŠzçå#êMôéeù»n$º(Ô=«“(
+Ój?äÏf/Ñ5¹fBns¨eÒ0›¢-縖²–p-ÁúJ0+
+ âB ë™VvèÙ¢~ƒç68àŽÑÏaaY`@HõË8 ôQ»„mÜ­Ú)‹[2ô\ ¬ žwa
+QÏún\pNíºdn0G)¤Á9,B_QÒVÔBÌop½ª&ƒÁaèêÍ“i‘  T„hôÎ4ŽqÚ8ÓHœÎèëm ãÚrL óUê¶ Ì¸ýJâžö
+IP êÁ,´òPØ¢y¡>FAÊØEƒC;©%¢Ô×Ýx&tŸalCîåø4vç»&°ÉÑquÒÇ©žÓ{ƒÔ9õ8ŠÔölÔQ•ÁŒ?>ÝýI ::Ç@N·ÄB¤¿;3ú
+…"tñF ½ñ7fµ¤Æ¸@¾åæÕÆ}eg!¦Ä°„õAÚa Ï+î w(s"4}ü<úýþ'ä3³=°“:ŽR¡…©³øĹáÍ JGS£ŸJiϼ( *¥Ò<†àš%Y!â±ØrØ?ÎF^{Íõˆà—0âÔ ¸¾š"yF_¸‚À·Û¿_É´Ïg¹¥×uÇ`Ê Ã2›ØŠX;[¶3hP@eö_W÷!±øDR «1«ÐÜX<ÇžsŸwxÁñÑ^®1êëùÍzñ J<ðã Š¯ï§èÄËÐð‚—wx¢æü’_Oi±\ðKåóíÇw·˜ "y~î§ KåxäWS-Çk>ÿžÛ³å,[.Vx½CÂ4gÁï7¿]ü¢wýendstream
+endobj
+762 0 obj<</Type/Page/Parent 689 0 R/Contents 763 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+763 0 obj<</Filter/FlateDecode/Length 1628 >>stream
+xWËrÛF¼ë+¦|¢*&Ì—HÊ7ù![?›.ç ËX’kXxͤòïéÙHAŒ«b«,
+Äbg¶»§gðýlHü i6¢ñ”Òâl h:¹Læ4™Ïð÷ÿ¤µ»q1½À剓)¯}tc>§A™ .k<Ifaép8H.ýö/–É´¿°þÙõ„†CZ®9¹é|FËÌ-Ð2í-Œ¾W™*7To%ÕZç–J™Jk…ÙÓZJu\pSTF•µ%÷! eFÝã£éØH›œ/¿=»NCÀþ,™38ˬw;šÎÈß鸛ýá8ñ‚C&¢$UÚZä9ë’Ò\ɲ¦ÝV¥[Ú©<'½ª…*I”Y\ÙIÈž3²Ðµ¤Ï¢X ^ËÑÔüªÊLï,}XÒÄ?NVœæô)bžG¹¤á„qíæÉð’ú“I2å£Lœ)¡—¹c”^y°¬‡h ³sÓ[‚ˆÊhæ€ôú€ÿ@NÊÒJî5°`
+mª+ÉÏÕ[ÜÈtÚ ÞmÏÈ5R¨5E“úGM"·ºƒ‹*Ó¼Éd¨ë­ÛÓ#˜)[µj'¬ŒBCӪğ…#êö<¡›’ìV›ú)
+Úø g•|J Ï÷H,µX zœÂ‘¨©{0Gßi½W‚ ú2&£·Ëå‚
+™nE©laz-Òm‡¨(ð‹ZE=0ÿm¤­
+ààÂ^ݪWÑë­nLzÇã³L}­<(’S)ki]®;Íúƒšy 4£v_ÖÎìÀ —r®JI irø™QUrþ•¾"èÍò÷߈«/£Ú”ïy-p.ˆ“Ç’hCW¿:v‚cpNarÛƒŠWþê
+SÁ5„%NàéqÁ7ç’£GÎèÉU…¥`ï`æ+ZæÛÌÃÒýÅ0™?q¥Ëøò‚à›x=PÿyJæÑÜaÃÓ€ŸlýöôxÃ'!ä±/Bà (WðVï˜:6)@Š !œ6šÍVÜK4d`í厓ø’
+4&t…£ÚºAA 3„ß:ç„ôe±â!˜C0ñlxÅ'ægS+(7S"×f’POGLjeÏÏ #—NÜïÂ<‘k}ÇNÖ‰;ÁÛœÝÃÙ
+xÄƼ&–y0±!¿ÎÇ4Í’éô‚íâóÕûWœì7”=½
+c¾Ã9z?>ÒŸ àYÿë•d2ûå/üÜxÄÛ½^žýqö/ƒ³!endstream
+endobj
+764 0 obj<</Type/Page/Parent 689 0 R/Contents 765 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 267 0 R>>endobj
+765 0 obj<</Filter/FlateDecode/Length 1738 >>stream
+x­WÛnÛF}÷WLßhÀ¢Eêž—ÂÎm
+·V‘ÅŠ\YŒI.Ã]YÖß÷Ì^$™V€(’8¦v9·sæÌèûEBCüIh–ÒhJy}1Œ‡4™â9ç3üžâ_'i͸zøñ×Ç‹Ñh/ˆ¦TÓx6‹'þ©¢{kh4\ÄSkh†WgC”.F¸Ì%S¸²¼¿3'“{ƒïœ5uî I¼yÚóqæÄú°ŸŸ35L‘©𤠔 ǯn—×PÔ„–kw:ŸÑ²°¥Ò2>ýöû—,»ßk#ë,{»í:Ù˜·ª1ªî¥ÁGî÷,»ëÊÏ²SMk—Ëo°=>ؤÓx ëÑ®¬*”ñIŠŠÌFúZ6…ÚiúcI¢Ú‰½¦­–g’?*ºòIvÔˆZÆ´Ü”šðW=’Ðg^ìä÷mÙÙ—…`HƒdÐáž*)´±†O|º.UCjmOZν_8ka ÅôIívwE÷¢^ *5ÊÐF<I~—S>qèƒábµÙˆªÚs²“kÕÉ+Ú¨墡½ÚrÒgr¦rÍ o.»U'E±§•” Œj“²øÕ{%†B!9%]ðµmÙ<À<LUe]a8e<,lÑpŠÁ}®m8óµhEþ(tÙäÕ¶´Rfs&ñÏ(`õ¦ Åäz1ïYÔ$pbý‘FP‡Äh]vÚÄŽK J@ æé`”8.Rö0¢/åCç’BFëNÕ$ˆBüÌY¦q?¿&%>úŠ5.Ž^ʵh±…!È7¢yeÑN¼VR‰Z©'Yd—ˆšž:ÎSu¨,3Nê+ªCx=ŽØHA
+,ÑÌ<tL+ÌFƒŠ  üã.i•Ö媒¤sÙxÖz}¾a§ÐÌC ~^[ÆÊr
+AÏXKÜâf‹:AoÛVuæŠßÙp¨”…%ÐJ¢´ç È2é%ÚŠŒÆÒ´SÝ£õ¦¹§$¹×‰Á,ž'Z6K§3r‚Øó~";ÆF<¢*ÅÓ´ê!êÓ ÕÖ j[€ðºÉUbñìóæ {¹p͹R«+›
+pvpÈßÇÄ5òaè¸ë—)E`y…ê}Ý€„º^$ ·5¶¸•Ê…AVtˆ¨ CmYà›4äÇå»[Û]kQVè(CVw‹NµH{‡;
+ŠãD rïÚà@nîJ¡µÊK¸/ØçàDÛŽpf—VÑ\JcD5 øÇ›=“±Qªr‰J³Õqs*+ˆÌNt`V®j°½\•Ui xÀ˦°z­³5w ÷ŸCæÙÀý·cÿåØ„'-zÿ‡›NùØ·ŠW$À&ǵ%$È*Ô¼óò³Q8YäC³õàšœì’™Sêšeƒ"ÔNÉlº–ÓA¹,d“ƒV1™¤Å«Âyf«GPB¥¨|h0hX°œfÛk vP?î,Û0€ªCôec†óâx‹:–­ßY§Jçìÿt
+Â3ª§ó®lÏt‡m,—ß±#ÐÙyU¾ÚŒ"F´·kó³wcºèåaFûÐcÜKÐÚÓ¾¹¾æñ„ÂéXƒ“9o2n¤¹f§ Í­gÑu 1r½?`{~È.Á*<Jh0Åã‘ݶnòÙ6¿8CA½iŠíu:ÇV6Åÿ¦ÊÙ¸!Çät÷¬@Ñâ\5¯ó„ê<q…f:Ðäy$¹eX¹lÃxá`±R¡•jbzçä´`¯'ê†×,',ò§õµÍzý!õ*w:R½Ô…aÉŠŽ¦û˜]ž«$–ë ºá¦_ÏdÝÿÖB£#ÈŸ4Ö¯AŠOS,aPP6¯aILwÇâ¹Ä1ÌíÒ$³hÒ1
+;ܪÎË_ÊÔ`G+‰ñÚQX°%„K¼*æO¹h…EYä‚
+°EE©…Ý¿ZŒ5íYBŽ°²h³k7q¹öØäüÌ=ì˜GeºN‡øëúY¤žÇלõ­ïtüeÑAL·¼«»ï8ø¢¡ZVI(šûtluœ *L"‹fiƒÂbŸ²k¿àÒ-hµï “^l+|UúÛ}™©1ˆà6V”½ªÌ}û$P‹á|D·ÄýÍ—ÛºëÔ7™´g¾åÍÛJ;‚h¸7³á‚ï3ïþÃæ?žãÄǶßhÄ&ß//þ¼øŽ÷²endstream
+endobj
+766 0 obj<</Type/Page/Parent 689 0 R/Contents 767 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 270 0 R>>endobj
+767 0 obj<</Filter/FlateDecode/Length 1768 >>stream
+x•WaoÛ6ýž_qËÌbY–“Ø)ÐmÚt–5[’uÃ2 ´DÙl$Q©8ù÷{GR¶£¦ÍÖ¢i+‰wïÞ?ïŒ)Æï1MšQZîÄQŒ'ë¿¿ã't4žE3*)™F‡á?]ºW‡³$:¢ƒÙŸ%øÓHÊñb6J÷£Y0$Mâ8š†OÇø÷¸ûøÑ–áãdrM¾Äi:^ƒ¬÷{}µ3:=¦$¦«ç9šÎè*sÇÀ“tp²µ• M#ºhTeUµ •²K:¹¾¸$UÑ¥(çô“è~ïê“Ãx¬ád%@L£ñ^~@ãqXžLy±ßÈ J®R]‚ ¶µKI׿žýIuÇʤ²’û´ZªtIKa(ÕÕªR™Q)ªª¥® Im­+ÊUc,ÙF‰‚DÑH‘=DÌ>¦áxâ9ÿ¬WòN6û¤¬CûÜ*+A"—+&‚¿…miºKq+ùÛLå¹lde)otIDRj$×6"SVé
+»v´{»šceiNËv(Ueщ®rµhqòù Ã—SÎ#<œ‹åºq)óÏ¿òÓ¹å —‘š £Ò°4ïÔÛªƒ‘¶­{Ò ]ˆ›Ì Ù•æoXJæ…çsØa®ãB/ùÍV>Ò¶6ÉHTÙ“ëSQÓKzbED–
+"ðš²F9eZšêGëÈ!¿.1
+K¯/ßôÝìÕòóÇœm£ R9™Uµ3o³Ôm‘Ñ\RŠR±((V‹ƒKLVJ¢ÊHçx¤šŒjÑØu]¨ÔÞDtÎÕaP/\"Êpþ¿#ðëȤªà×ÒSÞ5ì2úTØ|©¹ÔY8ž™NÛµèhtžE®”Îrº|uþúó¯Ô8jFb!TÅjÎIvÙ¯ú\º\<-2j òÊáq2{uqFV¨n¡l
+ƒÇ»y/"˜'ÇPÀ„%tʯõcžSžìÇ¡x—åŽë«ÞùÌ­¦ô
+ïP]„ ­3LƒÝÔÃxjQ¡mgß¡&]&å £¢ Œ•hPµÖˆñÂo‡œ†CÚ…î®mÒ9nGæÈ—?Ú`wÊ4õÆ`¨XU…=3„iù™ö¯à¢~Tò#4‚ÇîÚи$ç*-ÐX­3þඞ¯skn Þ“éS‹Î‚C°5¯\§á¡ãæ:4OtOÍ¢@ó)ÅÜPJø Ë.oÅáŒu£ïT&³}ªÐWïäšpèn½]»ðÌ ¦
++šE—RÙ8)1u Óß臠YÁTõ:œÌ\:ÈÐC œŠT¤x÷æŒB nïQã~€ùû¼SZÎ*\nr‘Ê›=dµ(¸;ÕhPLãƒOÃÛóS io«¥pw‰s4†SŒ
+XÀsJHÙÞ±¡—FZÊ¢öów8TåÏÀâ*4Aç¡øp ôs¯ì¾†®å}Í3#wé`øqos·l“Q´¥@®8d<Ä…Hò|ù‚Àƒêý#ð6(nHݵ Y©zm¦ÒX1/Ü$°Ý”‘í­DtµåF”
+endobj
+768 0 obj<</Type/Page/Parent 689 0 R/Contents 769 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+769 0 obj<</Filter/FlateDecode/Length 2145 >>stream
+x¥X]s¹|ׯ˜èåè?DI&eçI'Ÿ®”²}LD×åAU)p$×
+^?;“e1˜/Çróeq/Ê‹’Z‡Gë¾ÉÂúp_¸ª òï»…ŒFéÒU{í¼ðªÞˆ­ß,¿žœÉh:_aß×/ 庴+}¼KZ)UØÆ­F‹Å/¥}¬U¥.%X)L¥ëà¹åäöR¦Óòè|έc•—F»µ.‚9ˆZÍu­ÇQ‹²®Œöò08
+~áª:h'´ÙT¶öoÆ|ÝK¡j)lœ5¢Œ‘†/K©÷U¡»¼.€(·MàÒ±,·ÙÖ·XsÀ"»¯˜Àê a«e§êv­ŠÐ: ܪµl+HðÆÈ"ªñ,"¶*H…Ÿ2èÍÔyTÖ§°»ÆÖ@IìúÞ¼t²µ|º—?«{±N®›`}R…üq/þàƒÞeÓ;òúþæî.ÃI€TU³ÚÀÙ¼6@?BŸðÊÐ ‘yÓ¤Bâgñ©
+ÇÊâæ#cYüócï@¤ÜJ/k|LƒrRE´8¹Ž™F¿¹“²RÆn¼§jox‚ 99µõOFks8Öʪ Eìs›mF$£˜Ê‡ç0˜1–’ç•ç³1E”I‘ÂÃÈmÛQõ´¢PÈ–ø™Ÿ²vv_éŠó0ø¼ V¢ kpéáÍQm{áfõÿQØþ˜Ÿà ¶Sò¨W²r¨?rˆ*
+è@£eÔÐú‘ëwÅyζ›m.v’Øú‚^n!ü…¯T <ˆêSBU]˜Q¹ë–®¿ÖŠ_£yŒ‚³ß< Ð6Ùhâ–l¡Øv¥<V<÷ÌÜ[~§´R{Ë]ȼ±…ö8m Æ Ñv_œõ0 øTYVìK‰/ô „]tnZéNt»d9¹¹ŽåÚ˜Ÿá!
+Æ^ü3Ds;@!ŽN‡kÖzâ(Ø(b—'ý¾éF…’çMnÏŸ;ú4§þ÷¢müme
+h´R%m]ñ7Á”÷¾9¹-²XFóñÕT:½<œÏæ’^è”?G®ãàý¤s[GUÒ1V•¤6hҜΡ1¦Ù~åYÔlœ¬L:î¹7ì½!} IÄÑŸ±M/[ìâ4Ù cÝ`w´–<Š)mËKœö Àý/^{™$ì`”žÌºåóËßb'€@gkPH²NntêÔãi¦øW»ÂT›t/Ð<g;½ÃÈ‹ª$AÄ”I©×˜ƒé?¬QG¥ŸÖèâÝxƱ1q¶S?=
+¦ê­©J±Ža²;Ò’ÎS
+¯»ŽÎ¯ÆÓw2º˜¦¹v>~;î4-Kív:ŒÜGÊð~õçò]¥ëÙÅ^ WÂtk‹jõ:´ ">Àéh
+Ѧ±et`íã”ÓhËŠþ¨q ,ÈÒúŠLáRÐx’
+Ž†æ÷æ0ŒÊCžôŠXkÌ®1r
+"²ÙÜØpG„7 N„½£#õ3V蟤J”§‚íf1 ¤ÖqŠd®ÀaWÄì#ž¿F…n¾Õ@„è3€ºöFרZÁ Þ(z
+endobj
+770 0 obj<</Type/Page/Parent 689 0 R/Contents 771 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+771 0 obj<</Filter/FlateDecode/Length 1331 >>stream
+x•V]Oã8}çW\¡}M?iËH<J5H0dû±«ÕvÜÄi iœ±:ý÷sì$ménaÔPbû~œ{î¹þ~Ö¤~›ÔkQ»Káú¬á7¨Ûlø-êô{øÞÂGqŠ±ÐïÓþ¡–øË×mÿªÚÚià{¹F[W~³\ê_ûíÝ
+<úòQšéuýëÊJåðvzVu¨Ù¤iŒ»ýM#w´AÓЛi‘.‰¥4ˆä‚S µ™„Jd†"%Þ¸º$ž²EÂ#Ú³"Fw³`R ‚á%iÎךŒ$œc„½[â _²ÔІmí‚ÄËP®ùÅôå¬AµfxL#% ™לôJ*ƒˆAû4]ýG
+L£#ßI#fnì:òý*7Û÷Ü&Ê(äÊÀ…5‚/ÈѬ°`¤üR‚
+§ˆ……{ê lã‡ÀF¹¯²Rü{.×´–ðzÌPþˆÆƒ'¸^rml²°OÌ?WlC:“2AØçñ7„æSäÈÚE‡”ò¬*Ô–›#Çñ„àÚðè’XbV2_®lÚ w1çÑ‚…¯š)_ .¡¢kaÙéû¾5X]S³S°¸Önúøy=¿ëÓ¤@”ƒe§K¿`/E M"™«ÄaÔZ¶ <0®0}U6ˆGažiéõ¢X¨:Ç£ÜL›{z%²¬¢‘%s˜+Ç!çµÑB¦ Hú
+˜mšzÅÀ‹%É`oA$'±G¤ q‚;ÍÙrd‚½²»˜Þw%,+$å®u…¹¤­Ì)„¢2IäÆ:«˜„„üP¦ñ—"­][$b»E5HLÈßËD.XòO ”ʾ¦êÇbYPÜFuC[¾cÙñÖ]#Ü8LOYtÛB–QÊÖ-þåÞVÓﺠ*N† YÛ&¾¡Ê„RƒøNºdP²ª¿1Uw¼®k¶^°SÛJn4wp):µ-ˉ?Æd™£ ÿ¹Ð5H·îl’å®Ïª`Õ"‚È ’²jÏ÷ðþö à–ÀÒІOñå&,­ÝxòÀ;„?Hæ
+ÆÓqËÇEç„£‡»ço·•Ÿ}ÁÿÝ 3\BvD¿Ÿ…æâ)IËØlP[rŸòæTN9[R¡è¼`t)#ç¸G…¯lypÝÉr•Ù –»sî[½ì‡ò®WÞ
+ú%k›]\´ûmêB×Ú-Œ·È› žn6¨°•†2Ìí”`ãÙBP«ŽÔz ·ÿÿÜ&:½Žßëâ.oµ»ÖÞýôì÷³Ÿ÷}þendstream
+endobj
+772 0 obj<</Type/Page/Parent 689 0 R/Contents 773 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 283 0 R>>endobj
+773 0 obj<</Filter/FlateDecode/Length 2336 >>stream
+xXkoÛ:ýž_1È.аä·t?µ·MšÝ>¼u‚{›‹-Ñ6‰T))®÷×+nº(‚8‘HgÎœyùÛÉøÒ|Dã%ùÉ àÍãÇ—«“ñ,Ðl8‹'”ÓtúøÑò¤ó˜ÓÅ[ÂF^ë<æ4ÂÎîâäÓé@„'£xÔ<ñÉîsNãÁ(vVEŸépŸCŸóI<¦ðÀ';¸::‹rp‚-lÈlŠƒávqã|O;‹áàxÏøàÚLäAùÆ|\ SX—Óp<ˆç4‘'±²óŒ£sX… h]GÐcŽÿGøõšÖpÐù9Ô~ø {‹æ1GvN ƒl}ssìNìî_^ÐpB7kø}vŽRq÷€n’³y<iéjŸè’Üš~»],)õæAû’ú´X¼-_Þ|=é_Nh8 "¢Ñ"Î>[ª¶šŒ­´·º¢½«)Q–ÖƦdÝŽre÷ØâêRá Ž 뮺;Û™jËŒ§Äå…²Æñá âÊ»—= |û€¢á¸àV«*ìSeÊnjµÑeʺ(œ¯ŒÝPî
+¯ܪ2±ßÓÕ´ 4亇¡’ƒ84Áý, LEÍZz)|Ì©´Ç¹ø0fm²Çà ŠZn|ú|óî»æÐœI:èÀSy“Ü®ÿh3xÊ¡É>KÍz­='†6.ÈA}Ô›ÐíÄôû­É3ódUê>Ô«¶ˆ£$$O¯v¾¤i ~Á Á f%jSØÒiG¾\/ B1C 3ü¸Žw,=½7©UEy*täË9^®ë!÷£(i‚쑲éq=5ªBýAùF<£7Òß¹gCÝï¸ö(
+ÒgN¡Íäƾ#uPTˆÉµñåqË& úêfÑZ+Ä®FçÃÐa¼–A§ÕaüShÊa6½ ^ú58ßÂÂÂ4Ö[Ìà؈Ázû ­Xý;æ[x›ºv7©êGŽ
+ÿ+ø9¦×ijÂܛ텃<2 ÄK‡”›µG$8Ðâ
+ˆÅ<ØÄÉ40
+_7ÈHÖ×Uè8úE‘öŸ¡[«Oã™]ðWpÊxȧñ9þ¢ù÷ÎUk„Þ1Æ+|í€EÎÏÝ¢·GV1ví*üçz9Œæ­R";’ƒ‘|çƒÃ ØŠBõAE9ëõ·¸aüCI“¡™2‡¶…›B0ÐòõÇ7¯_=ÕæìÏj_pZEm¾(5FÇêÅ_OÍŽZãæb$O6mÔ¡,¶| 3mÓ@ôxæ’˜ ¢F-¼‘Df·…Aœažá*ÆôÁôÏô«,¨Ï!þè9Ól†Iv6e@Å@|ofÔ·.©yd–ŠÍ
+Dí‘h>
+endobj
+774 0 obj<</Type/Page/Parent 689 0 R/Contents 775 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R>>/XObject<<>>>>>>endobj
+775 0 obj<</Filter/FlateDecode/Length 2023 >>stream
+xíYksâFýî_qC’2Sez „Sþ€_µÞ²1k “ªaÊ%¤ÆV,©µdÆÿ~O·$X³;I%b—1tëÞ>}ŸÝ‡/:uð«SÏ Ó&/:èhŽC›—ä:d˜¶Ö#£×1µ>Y¦…ׄÑâàtT¬_ о´H×i²€fÛéÑÄWóšxÍQÂçî<|¡žÑÊSJ9 Æhõ覇‚x?5š
+Fé#£“ßÚ—F¡±ÙzÎÊ%š´t7b)K¤ª–’Kºg–Ì9”ð,]féq.Ö¡¾¦k–iPËèjþOüfÂyú£Z«I^¶®ï‹hN­gjMINR/xʼû«±Ñ1zR[‡Z:,%Å ?#WˆO|Zð$IØ—,H˜/¹žÇ„ {nøÈEJÏKãÁÍé@!ÛÑu—ű4„Ç£Èýc/ ìÕn¯u´—I§³ÙOÔç¡Äù³`^ÂÒCjyt=ùABMã7ÇþF ö³›´Å’ó°-wÙN£eÛô|ÝólÛìÙ^§x¸½½[m4:Ïå3ùG7a¹¼Ÿ0³hÎoO/Fã®v~}]ª¨Ží#<­Vcû ÿëz´³òTÃØa§à\8¦cÉÂõË8R·åŸfuiî¹"-‡L]3º]Š#W<àü¤"~OÍ}jMwð¿T]«QŽöUÞ“Ê5£è¥îÍÐþªÏyäñɧÉô·Öðbò™nÇ'Ÿ¦qðõ3YŸ|»ÑÜ%C34Ó• Ë°‘
+]ïY|®1Åpr?ž &Óñýíé¿/Î&÷ÃÁÍÅýÙíõõÕøêvH‘û$#<aÒŠ§ÌKyòB³Y¯5*Á©”Y!Û#”]±VVÏ4kê=³oi6=ÍÛbö.vê>0’pr1ñ.’}’¢
+¦šFÇéõ4«†nZ&ªoŽï;aäéU#Ÿ˜5»Êž+ÆèHŒÝwƒiZ BNÌšŽc8è4¯<Ò7¬B|ˆßÅ÷-˜WC«³o½”ÏÖ„×;Eëòv8k7—7ôQ)œ¯GÞ‘T…ÖÒÎï~]‹n†ö“U¥²X¶ÅÐ7eÏ/.Gw“;Cv‚bÝêÐ7e¯În‡×W§yyWËVF¾)9ßÜ+rëÏ¿üSÖ·ÚÑãïUÖ¥ëß­ïPòâ¡Âèõ!Õª¯kÝ×%DN8®mÕên»½¼YÔ׉ZÔ±"‘6èèºaÉâôªŒéº£8</†MÆoƒ¨Œ…mã˜R‡Â²{}Íü£PlJzaŠMM‘ÝM7œn=
+ÃÙ8êÝÀxÃÕ*TµÅÖ8úŠaÖÅ„nô-ë»;l¥œU!T‡a‡¾aà¤V¦n÷×=ïÿµÃº4Vl±¾cÛöº…Vú»n˜({n±þ7{k²ôŠËÈú*òÖ GíüŽ@Aìó• á„¾:vƒÛé{\=oÏÉ®SΫãÊæ‚ïx8½¾>¾|Tou­Á‹|:¡¿
+‡†4qc±`’ŽÉb{ÉË2Å{%"y¦n G$8ÍÙ
+üÆå~MÔl\2¡àGT
+Ò¬¼NX{{ݦºoìêÇ´ý˜ä£
+x›ëøÆ7MrĹþ ±¯v*iÅOŠ’úéséyTü8ä®OŠ4B×Y$<C·LØsÀ3Q>WT:7 x<ûPl n¨*XÀ<E¡äÑ`t¶.Š m¤‹†|•;_a€g!×?|’”“
+Ä#WŸMGãvN|Eƒ_2µÓ`¢ª‹F¾Ó#J‚‡Ç´½ÞøL¨ShòÒsƒô ÁxPã*¯ñš¦5g<Ž1¡>Ïš>Ãz~Ή*HEÝY^’p°œÊlKZPZÿ'yúˆØ=f+Ø$G—©\É÷òUusªleÁC_Fw ‚Õ‡ó ½ì, ® ëívs¹å'ŸÍƒ«/R¦}iobG¡Üg·“‹‚ší–o…€Íå6±¿
+é<FkLX("”ëHßô‘¤¿$ï«l¡køíJ›>ÂiõÜ™*%•ei„š¤;{ò9ñaJR7\ŽHZ(ã»Y
+¢, ¼µ ‹·ó"pÊ(+©®Î|U'Èsc©Ü ¸Ý ý}פE2¨%Õ–JÉË·Œ%¾$ž#ø~P{I°LË|ÂS%¹mBLKpëàÛ×Ip(v¶].ó%cÙ:r‹•SyËdòò8EÔ¡jæ&9}Ÿ Ò"½6;ˆQ±`LV”§ðµn÷´Žcâk°¬¶Šʼn¾'ø]¦Ç9÷²´·* n«iõ: òýfOëi4FÍ¿.­¢ –»EP›`2µM«gi=_mHÓ‘ª.&ÿ9ø/)£|pendstream
+endobj
+776 0 obj<</Type/Page/Parent 689 0 R/Contents 777 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>/XObject<<>>>>>>endobj
+777 0 obj<</Filter/FlateDecode/Length 191 >>stream
+x5ÎÁJ1à{žâ?ÖCÓ$»dÒck<Ñ i¶Ð&YŸß (ÃÀ0üß0ßBCqiÁ`ïBIKVŒŽx6Ü%aç Ï#´F˜™XGWp\)„¸ó¹¶)–å«áýÅcÞÖØ–¼Vùn ÝÔ–ºÆ°ÞM§×ó ¾ä[Š —·{ZÛg‡íÿÓ{RÇž'ISÞJLyÆ㇟p-ËO*x©Ý4J²Ž¿d3ûê)ˆ7ñ Ï=üendstream
+endobj
+778 0 obj<</Type/Page/Parent 689 0 R/Contents 779 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F3 6 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 290 0 R>>endobj
+779 0 obj<</Filter/FlateDecode/Length 1417 >>stream
+x•V]oã6|÷¯X ( 
+$—»"’´g·/u(‰¶t‘D—¤âøßw–”ü¡$@6œH$wgggwùo/¢>M‡4šPRöá
+kî—Ž±6µyífÑ»øzEÃ-V€7™Îh‘:Tx“Ÿ3±±RÓ,$#“ZçvGŸ(U¥È+Âw.ÊXÐ0|9[|w†¢±7ÔEᦂY…ô›Ê«¼Z“¨èaA·þø6·ÙÞÀÐS5†S>~mL]JÚ©š2ñ,IìO¼
+m¦U½ÎNà¶@÷jJ€ üm´²*QÅ9ï®|1xQVrKË
+ød2NŠn‰áŒ)ë¨ìÆø ¶çM«zHC»VÉuê5Ù^x”Üødš[§#joˆÛÑj\ú®q¨¯À§‘ÇÜ_E`ÆGÑ ¼fPÖöä–‡.rÜŒ¹-Ѓa‡ÑàHò ö•Õž¦O~¡@ªwÈ›Cý{]¨XÿðÛæ踾zÊ›˜8_œÜFà—Í°?’îÁQÜû›vŽ®ø¶ôCúñtN'3ÏØä—EïÞ.Þrendstream
+endobj
+780 0 obj<</Type/Page/Parent 689 0 R/Contents 781 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 299 0 R>>endobj
+781 0 obj<</Filter/FlateDecode/Length 1715 >>stream
+x­W]oÛ6}ϯ¸ËKÝ!QmÙñÇ€bÈÇ:XÒnqQ Ëh‰¶ÙJ¢JRqüïw.I9¶œ{š:‘IÞsÏ=¼úv2 >þ h’ÒpLYyÒOúøf÷ñǯ'“Q’Òx:NúTÒ`Ôß=t²ÿŒÕ‹a2Š{ýêEšLhÜ'S>;›&³øäW÷žKJÇ£ÃÕÁg/ÆøÃÙñ,¹ˆOþìÞ3Î.v{yuÿ«)û –xÙÑp8Äçh:ÁgŠÿFÒÒ/ ÒRè,¤ý!¢ |() ˜„ïëù®F³ÃµÝ#Ö&³dø|îj~òæ݈š/Q‚ñtBóÜ#ߧyÖ»“OŽ²µ¨V’ÜZÒëùìOãþm´ùº2º©émXjMõ¨P•$Uùc­
+½Åßdeæ”Æ—¹Šü§pèbçÿ<#ïyÞÛ3L7n÷i·OX8P–ðÃñU¢”¤—þï\—þ7’pý¢U¥ªU–öÎÿ©*ëHVÓZ<†<ka`ÉIÓÍXV™ÙÖŽja-bÌíad=dè8»ð58íímåÑF„†óð°Ô†¶º1ÔXi†&Ñ —Ê©L8ãpé V9Ï»9}¼¹î&óNU¢(¶g$òœz°[ê\-·¯Iti@ÀæQüÏõ;2ÏUDÈüëêæz§‡ðíf¾–6TŽó­*…Ù’¨rZˆì+Ë›éÊ] ݽ(‚6ª(H8'KÔ xñ‘9æb
+:õ^N½qN3ýJT¢‡ û•Ç趩®5¤&ì…ìF¹l8‘íi4Kèò%ãGœäàu…©¤Ì¹­–-Ú¦¢; òœ)¼Ë§(w»Î
+†ºb½YŠ¦phÉ猀çAxAÑ­c]·M]ksÔÒ]½ÿpﱸ›ÿvû8ð´Þk¥,À«lK-ß-WEo93{Š&h¡ˆš±ö3F÷"ökSúæñäi-˜8äÒ „ ëdmC°¹ç»Ø)UJ¾xL͈M,3;,}p:(1ßûLÈÖF¤ð±ìŽa¶ECåS&k?©¡äž†ìðô>Ì
+hZ±’æ”–F—<‹ŒÐ»¬ Áš»ØvHá-\bþÃŒuFgNãbý„ Ñu ñµ.ë·=¥ÛÛkÌ/·*3ÚꥣàaÆ®ÊêBb¤©‹RåA}óîEQ&ôy½ ³!ò@£ñD‡t*twÐ4zýç níüº¨ëÆøåÛ3¿;
+žFaÅMP½r€CJßy\0LzÃ¥…<w,}ªÔÓ󨸠Ԝàé
+endobj
+782 0 obj<</Type/Page/Parent 689 0 R/Contents 783 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R>>/XObject<<>>>>/Annots 306 0 R>>endobj
+783 0 obj<</Filter/FlateDecode/Length 1262 >>stream
+x}VMoã6½ûWÌÑÙ–Û)ÐC²ÙšlºÑ"=ôBK”ÅDª"e'ýõ}Cʶ¢v‹|Ò9oÞ{3ÿFsšákNë˜+J«Ñ,šá“Ó¯¯¿ŽÖWÑœV—WÑŠ*šÇ³hÙ­Jzõ×xº\G—½§‹Õ*šÑbGì]Æ œV¼Qh‡scÞü¨·Ä¾E´î=ë-+ÚÌ£«Þ³ÞhæK`>êãͯ€e¹Y#vŒŸFR>ºIFÓ»%Þ§$«Íš’Ì“0£$L[fÑOÉ÷ÑŒ.âòO²ñS)…•ØŸË†œ!WHzQz«tFµ¨ñanR¿+á”Ñ„oAöÝ:YñÑ:ÃORQ–ï$¬U;Mßïÿ Ve–ÎÙñ?Ît‘ç‹(æȈ’™ƒ¥Ç„nq‚ÒÔZÙt;ÓÖ6¢¤P–R“IÂ_±ªÛ M™ÜËÒÔ•ÔŽ¶Ði!- 1瓨 ?› ‚n[GU–´•T™½Ì8…FNçXcô¨Ĉl/´;É»2ú¢d deÚ6ʽ3NWt@M  ÆǨ´§q
+>azwÙÝøl„_:Nà ǪìÒ¼w¬gBV§Š
+2‚K…^¥¬<5P9 eWKXÃèu/{½;êÍe‹³JƒøL6D¯ÖŠ d WÙ‹w$œ«
+HTÚkr7~×+’
+Ô0Æ@›½åfò^åž
+°çÎÏO~¶C‡]£aæJs7E@h½:¾º+.|/í‡òî!會Š<´ë‹™ù7ôþ~ÞÈšã³'ú ‚vÒ±—¤ïÕ¤2noù¹Á§„mÓ"ø®{÷ùþ6œW*t“¨ƒv¾éŸOߢÁë—ĤK#ºFßv<úãÈws°…V"u4wùæ¤ÎÐ-;îòÖµ’¡› bW<`8©n¨ðB;oú*6u]*Lž™Œ}À#áÕ„´Aá=ú¦Õ[7ÆŽSæä+oŸAä€Ø¿º“•›l8ãÃìômŒöïºÜV¤¯¡Ïñ ì²;Tt
+ [zOg™M¨¯lñQetw$^—-žð= ÄDÁp]s”z¯£yÈ¢’…ƒÜ\TžžØƒLO#uz·:ÝPN·Ç/ÉçŸyÇùþ2¦¶P0+9èþ‡ü™I[?øhl¹j৺ÝÂWÅYï¹Er;ñ·Ò’~Sº}{1M™-é‡Z9yk|í€ÇÇûç),éõñ:½Ût°ç+\º6 Z¬7á
+õ|ýpsMOùŽV»L
+endobj
+784 0 obj<</Type/Page/Parent 689 0 R/Contents 785 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 315 0 R>>endobj
+785 0 obj<</Filter/FlateDecode/Length 1682 >>stream
+x¥W]sÓH|÷¯˜â圪X±eùëÞòGê bŽ{HÕÕZZ[ ’VìJ1þ÷׳+Ù²sTqPEÞ™žîžñ×Þˆ†ø3¢YHã)Åyo ñ›ý?þèÍGAH“é<ˆ(§ÑdÌ›§ŒzáxŒöoÃyxü¶óœÓx4 ³ˆB“É<˜R4Ÿáç¤u/œŽ‚ Eøø!ÇÓ)^ø'9v©DÃÈ%…_àžøm÷9§(šãîÛÎ3ÞNH÷pöjÙ»xµ pHË5P™Îæ´LøMÜ¿NEYIC‹€^ë-Uš®u±V›I?ˆ|%PAHÂ’8[~î iF8ß¿7*fG7:ªà3•ÑY& Šãð1Ž7
++)_$YN½JEåÎ
+<Ä:Ç]•Xe’¶ªJùBW"¢ÓJX7µÆ>׵ʤ%+Í“ŠñÂÙ|ð)EB©JîFþHrU(Ë@–ÂÚ­6 É"6»²Rºà –-SiqcµÕ€ºT±=‰ìÓ}J‰¯R’Ç|vøôÛLû“dzcìú
+(YÆÏ'Q¥ ÆHÏ>J*4ÁlPBF±(ÅJeªRÜrM"®œ’è“*½(KŠ`Çb:©ê -zì£èdz
+)-ª²lHæ$nWš¾BöBáÝ:ŽNÒT<¡r‚ྰ˜ý .+±mÊáL1þ§ñœ;k€ÅœèÖ‘ÖÎ<Üí…fвLoÁ‘CM]N¦ïnÿþçöîayùæMVyöG:©ÞfœË Yv³Öxüh d™íhåm¥d» è¥8²Ñ:ù,nA£'áƨœ=°À6žÏ©,‚¯‰!9*žlªë,qò¥`µSuW 'äxƨ‹#>pÕ¯âƳ`Κz §³ÆÞZOp/÷Š.3s‚bϽŷ†fœZFS&Ÿ$Ø-ãÚ u?ËÈÊ(ùäÃeðrV:G
+Í ì…À• °«º¦båçg<î=ýà;Nå"N±“0v£ KåióYc›íš‚M–cxTŽ`3uÏáäÈ@&‚Ÿ“ðOÀ“ÈJ¨ [}§Ìg7<Z;=?uÀs’UîKŒ9çð £¥W»„¨ÌœWl)c…ËmaX8dÞ„ÆU;wœNT¼U†l¹øzà÷¬±,ýN…3[•e`W܉è6,­ é‚ûˆ1¶ÆÿÌÙf©Ÿ7³‡Æ|;Äìýñï}'ëéÉw½h³éÜ·;sj/—½÷½Ò»Èendstream
+endobj
+786 0 obj<</Type/Page/Parent 689 0 R/Contents 787 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 362 0 R>>endobj
+787 0 obj<</Filter/FlateDecode/Length 1468 >>stream
+x•WIoÛV¾ûWÌ¥¨cD7‘Tƒ p'>Ôvc]Š8Š|’˜p ùdÅýõýf)R’›¢6,s8û>ú~æ_‡B—¼€’â̶l
+¢¹å“…xvñ×(Z1¤ûOμ¹gÍ(pC+ ‚|{n…”ÓýÙvæYÎ;‚ }+aÅLJ¹6£`±€"˜Ñ4k¶‰æ3Xb öÚÄd×jæÛb¼‰:€åœ;ÇË‚B$3ö8Šþ °\2À€‹‘éÀgC2œ‰PDŒ ¸`“
+c|œçŠP£P€gÛVƒ8D5C{¤°k‰B 8o&^„œKO€=λ"4rAb€9Ÿ+À€ó"ÃÇj]ö8™`}¾`ÀE¾ðI´\è úœgœ72pg Ë #À€³# ¨øç°Ç!¹2¦gÆxÉF#Ò.£`Ô›Åq ò¦Wsr|Z¬ÐBAAâ"•±i‘œÏ-Ï¢·U¹ÊÖÛ&+פ7ŠîãbÓ»ªˆ³’‘º©ò\5/_ϦW>òk¤MܲÎàXeM«©Õª&°$Š5 ‹iW5ßøɈ¼{÷–²–tEÛ2U`‰ËT4ÖqJã•*Qm7O,©-–Vë,º¦]–çl‚M‡«ªËJS¬µ*jÍB5Q?ꜭf7FB7
+½CóF=QŒç¢Â‡ÞÄàOÕ÷m¬UþDIõº”3¯œŠ¸<R\ÇkeÑUÕ€§|Te¦ÊD½<Ñ?*Z*URž•ß x—éʼnÞÆù !UmÒdµÎªÒêT¹j>~dÓ´¸$õ#.ê\‘I&¢$â¼·Ó¼îósN+˜E’ð¢ÿ[Ï:ç¢{<—&.FþC×çu^-ãüKg‚ÃS ¯ ?¯èMÜf µªAðO³à–)]L“ž¸Tz™UÈ#ÊØszÝì’h=¿»ýp{`g´SÅõ²nªmý<ëÍ姛ëËæ‰Q/Ÿ{[wÈÞ¦Úæ) K<¥¦ ¹æò*Aø‹Ûв©vp‹¥º/rõ¨¤êØÀgš‘µu£Vªá’1¢z£Ÿ”fDÙéþ/²±]Gžõ³U ÚV?íóAçÅ­¸…CxÙa_ üðâÔÅž¤WÆ|üü¬6yóTk¸[Çm‹T¥(+n,tÞ÷mÖ¨B•Ú”Û©¶NÀÀÞ«íö¬Öv[×U£ûôåÕº*Ÿ©».š3ö3¹;
+­æa «›j•åªýýÔv Ëõ¦7ú?¿Ü<<ôL€¶Œ{Ö £ûX4ýÚÒ¦*¥ˆZý˜J(KCÔUn¦Yب†L.yxmKÎB¬ÿÕδÉ÷í÷QÚ~$ÉøÂŒ}aØ´÷O=ik•d+LkUª3Áˆ3̤?ÏÅËã.0è  ‘hTŽE!yqñîöþâBÂË“œÇïgL‘ü½Œ2cSûs¬·wDÞYI‘ò‹£L¼-)Æv…ƒA>Ús£` vœZ0.‡é¶m¦ÒÀÓ–è4Ï–ÓÞfÉÄ‚L©*ó§ÞìÓ‰±C_+,ŽVÊàtŠ–:N‹LÓô
+Ç%ô/¹Èy”ù‘UŸûJ–pëO±eÑ‘S,ži©;¦#Y'–Õ…\ (æ¸ýÖGÁlûˆjhÂÐçÈ„oeÙf¸ˆÍ6[˜­/*ÁJÁæ¬VTWY©åÁÙ°ÁNûëÕ,üx‰€7º\C¨ÌnãKǤ_Ç2qÑ—ªŒ—¹JÍa Fªtœå-Rvßqe§\ÜYû#«oz»“æýÍÛOÝ-®oo¬.r¹¦WI·ë'¸êÏŸ7»Ýu.ÝhîáÒó-;âþò7—t×T_1ipÕ%[Óâëž8¸ÌíÈ£Ih£ˆÒÿ}ò÷¢0À÷föeE¾_œýyömìÂúendstream
+endobj
+788 0 obj<</Type/Page/Parent 689 0 R/Contents 789 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F3 6 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 367 0 R>>endobj
+789 0 obj<</Filter/FlateDecode/Length 1832 >>stream
+x­XÛrÛF}×Wt)©U%‚ñ¦}“äÕnRqâÄÜÚ‡ÕÖÖŠ°dÍýú==„)'[¶eôåôéÓ þ~1¡1þLh9¥Û¥åÅ8ãJûã·¿]̦ÓdJ‹ñ"YQI³ù*‡O}äûi~w›,p6]&óð:KšÏ“»Î™{lu “³Õ&¦øg$m½étòõÁÃúbô4£É„Ö[Žu±ZÒ:s¡ŽiÖ;IVšWi¨llM¶©*mjÊt)rE…~ÑÊ’P º^‚1äíŒ þ¥díÎÿí¢—Ù0Ò_LÃÝÃe²bÔÖÙàyºX[ñw8œÜ1ÜÐi#©F˜!¤RØÑnŒÞ#pBÚdøe« ý3W.SZäRÕTk$ŠÚ?ÒH‡cSëðÝcB
+)¬š[؃ìñU˜\7–~–õ^›ÏôÀ>sõ‚PÒ¦„QçZ!„´h2™Ñ>¯wx0·”å¶6ù¦q爬ç0“µÈ ›œÃhºHfoÀ4œ®’É çS@Ý[ú(Ê
+‰äsþÿ®ÞÒ‹ÑME¥¨*Îfƒô¤T-z?¯ý ®î½Èÿ¡ò/ñôyàrEºFŠ¢8ÐïMwÎoΰg ¤üRL%ü`“ËV"•Ï×7tÐ _jŠìx_êžk‘•°áC·å&IµÚR%Œ(‘¤¯®€ué«‚4SÄUs†—ï<ïÙ„½$[
+I"Mu£êX†;š
+à ÖÎ`‡€§u—ê¨ùzc=¦¢=Uí@æJ{ºGsÏ#p§Ìó5bêÊ÷üñ­‘ÐG
+ °€À¨¤R–|ÒÛžgSÜÈT Êyh ª´µœë%‡g¤Vï ­;^é^Ý[Ø=P=ÏèûXÞpwßæóáÝ#š\Ä#ÑdmAOpbIâZE~“/,Û‡„îC_ÀÌ íôž¹ {Ñüù=H&L’ Ñ-H‰ ò6Y<<ÆíÛ0° xÊb|Ž|n1÷a‡‰C? õžÛHB°ÛF ;dý<@Ûp»8°·ãØîô DÔ=–ù;¢@ ž¯¹o¢6„ (Ô¶Ù%B°¤DŸìpv°Åñþæü?‘jÄn+­2n7sZlêCàqã
+ìP:Mq0’u::›Z`ž×þFº‰o!&EA0(_ó°*°¹a(%½ìºy"û{ÐÛÞø›\ÚäùÚGxº }8éoï°"ú•Š…­Š°‰Ð^œŽ„x΋ÀW,[Q„¡¨UBÚ­+m¡QÖ·wνÌ64®ÊΖùÏíx—¿¨!˜3܇ËNHGÚMÊ)ySc˜óìct"
+=„µoç–ÏNëŠÍD “"Çbí«Ê×½Ð8v`Œ£â8øø#yIÅ›VŽÎPWn®mÇÙ70,ÅÛV4&N'8.]‰ŠÃY`c{tú'®,‘.s,ÒLÞ[& …Š?ºÒ!üþìãÙ
+EÀ™ÆšÖðªî Ìã; ½æÕþ4ÛÞ
+¿HÙ _h‚ía˜Ñ(“¯#Õ@ç†iÀô6Br; ÛÕg^mÜ7z:b6´4b»[QØðZŸîÐ>˜ù›èÅö½ÿËÈü
+/9g3ñÊMâê»èR8¸àœúÿÆ|pŠ}ð#¡À2àD£ˆ÷>·›`ýýþ’ðúäÔà†öZ]ÕÄWht;Šq™' _eÿ¨¹Z`PóäìbÚiÏrˆ Ö¬ O`eäɱÇÜŒ®2]U‡+¸å7'ïöÏ÷J'žO*òÏÜ™¹_LFO«@Éß1¬nñÓô÷ïîéƒÑŸ#6ïÎ+0ç7Œ·—ã»(BÿŸ—§Ùr–,+ÿõÁlÎÞþº¾øõâÀhxnendstream
+endobj
+790 0 obj<</Type/Page/Parent 689 0 R/Contents 791 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F3 6 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 372 0 R>>endobj
+791 0 obj<</Filter/FlateDecode/Length 1791 >>stream
+xWioÛFýî_1u[T,JÔAÒîÄIÝMXEQÔE±"WÒ¦ä.Ëòúëûfw)QŠœ…mYÜcÎ7o†ÿ\„4ÆOHñ„¦¥ÅÅ8H:|Tk<Œ)JfÁ”fIŒïá4ˆ©’´ÂÙ1nï?Þ~Ã+4"(ÿ"ÿÓýéa/x–D^p I¹4‹ÇØà¥0
+§Ïé?·ÃzÝ:Ÿ9+êÌÆ4I‚‰Õ‘LŽuœÛanýœ¨øÞ:'8hã3%ø:‰YKør@ܤÿŒ]kwo·÷\Ð,œ×½»‡Ùo>˜a<‡ïΈéá;—¥îlá©Á·‹‹Ñݘ®i±¢0˜M'H|Ì£„™Mô˜é 3e¹ûäæéf>žã/¼y±x‡{woPˆt£´üK«ôo-
+év½ÔÁÍ(“#ÝæùÍh©ôh%òÚ™Q²æ¡S=œÄÖ„E6x¹4òŠ:=îØ3Š:)J…¦¥$¡w”É:­TÙ¨GIl­LEÍFRš+©›+R ®èVÔ²Àó+S”m#«àXã¦M‘KX´wrïàA¯XÖ&Çõ|GE[7l«úQ6·ßýtïô›UO=5†½3[Æ|<3…P: ¾_~rÉ–ôõ{Á¢,¥Î·> ß‹b)h«òœ´i
+N”Š45­nlT`Ë$
+f‹ÍDã<2U%ëÒèLé5ýªÕùk´‚¥”šÒJŠFfWö‚–O Õ, &Àw·i·œ¹Ýu¤ìÄžC)5ºA¸X'¯nežÿÖf« ‹ù±c{›JQ×[Segè÷ÉŒ–ÔÖ^šÁÜ£³—„ºXÚûÙà yxáŽ`š¢:ã°Ö¶d#+ék,j¡Þ‹beLóñ±ªí5ÐPаð0õ·?€Âžà-ë}¶vÎà—ó€z$|V!×òíw¯ÉCXËmwtUHXK-+ÎòIÎV•)¬ø_"Òg1ã °‹}8C·˜Æ€^$`'€ï{•ç*ù¸zH…ÌÌÈwÇé†30êxŽŠŽ‚q4gQo„nEŽªµä䟔ÃÞ¿ð³ÍÆd»ˆ™ü§U"…pxž“s’àFCáoJgf‹˜/èçׯ ¤Ë{Y=ÊŠ`¥XËê2 ».”£¡þ¶•nl0:‘ iWl¬sØîg{õpÏ‘™ÈÀ±84£t#ôZºå®l®hgÚÊsá±Í9ïËœbpíÄU¥Á+¼` áþuUÑ‹úV5Οš9»Ïm½´ñQšÑ­dÍ2V}¢°ÅRVuÖž;–kŽ)™¶Ò\TkЮ\WK+„v* Ú)D£8T·° RÐ囹A
+A•‡Ö6żáð{Ì‚I@—?é!Šnx—ï.駌5Š7®›Ò‚ù˜^:¶^Žî:®ábÁ @°©#[Î3<J€;Äà ڊÝ,¸¾wÍi¬UQrH‘Â<·ô.}ó°{ˆû´]0ãi)¹+{Žª¢Ïv9Ÿµ®£Ü+¢˜àº×zÖRx‡rC·Aòž§+Æ“+Rnú¢mÐX•r¥Ÿ€e_¯LG­ v·µ#‡º-K Ùç(4,ïm@ÔWjÝ‚ó|æXˆÈ2‡#7~Á‚¼*‹µöm ,Àø‹r¸é2<ðýéÀ6®[ÿÑHÑ_$ÈáóÄT…ôcÚ²³Fz¤€~e´´Ûk!·’A
+endobj
+792 0 obj<</Type/Page/Parent 689 0 R/Contents 793 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+793 0 obj<</Filter/FlateDecode/Length 1743 >>stream
+x­W]oÛF|÷¯ØÌ-ɲ>òЖãT(j»±‚ €^NäQbLÞ1wdýûÎÞ‘
+¥ØE
+$ˆCvoggf—ŸOúÔÃï>t1¢(?é…=Nûᆓ1~௑”œ\/NÎo‡ÔïÓ"᳣ɘ1á|¯G‹(Öê(¥ŒéõâÎ"¬;œË2:/ðù6öŸ4Q’ª4»%Ú•QeÒr‡lÂjeC>ÛíQw0Âeq°ØH²6ÕŠžäŽtB%=Š|%HÄyªR[Q¦_$‰(Ò•*ñoiIàBªÈ슲ù¶OY–©ZsN†\ý‹pÀ¹Ümµ‰›$¹ˆ6©’TšÊrT=$¾Ò³Ñ6Í2ZIŠP C¢UYºI†jµ9ÊV±;”&”"z†ïÄ;’_Q‡áüvTƒÙºãÇTÅzkénqˆj³¹Çè…;˜æ~¹P•ÈÜ픃u£7i’F
+\FãÚH¦Ô‡$p‚IØŸB¤—=¯Òix2‰rôÁèU&s–zLoÑÆzY4ÊeulYÁ|RÌËTEYÃ-èìÕþ‡z0‡ë 6nÕâǵºï.ƒrW@.Ñòõÿ°ÀÚÆÚñà妾•(
+©b‡tk¤¼~¼áªXâU-®X£Ÿ†ð1Ù-Ãï¸ÄV«3¨¯‘´`Ú¡½"Rã{,ø^1¦Æk…n×Âãµù^[¹x‚3â|íæZEl‹1$ ;Ûjód©&‘Q™íBzÔû+ײ¿¡†ypDî —‡|7/›¡B_ÒbëŸ5
+X—2FÎÖeD×ÏÁBº7Mv>´Ý謾·G¦‰Ú®Ì´ÏÒ'äjµ&"?õЦJ¥Ÿ+IÞù ýâouÈëéÀ±­b:Þwû½ËpäÙ¹–¨@g1þƒÍ8Øžki¥
+—Arù}6ôÄê\bøi™aú¥„Èc}„m<%/[Ü»ƒíq¥5þåÖ0³Ä+Éó£fxéÇÈËš¼œ´VOç«<:\ÒL¯]i É2˜aFöúÓk 5üòMk\©Õ˜¹Cˆ’=’¤Q<’
+sÃíL"ábªë‹é©ä¿Hã¶ßƒÍ7Ò˜`sòè:—l+»ÆºC§ nçÕС‡ ;8o»<á@6ÉVYÉUc[w‘ŽšÒZµ©½‚{ƒÏ}DSšöÝho©Ît„ýßzƒiáóGµ¥†wñøñÐ6¢
+H›óùÇû÷¾{ÿá!ÄñCø¦räˆÆ3uȯ"/²ïÅ<­…Ë铃$òѾ)Ðæ«#å$ªké‡md¬5t 6¢ßÇÖˆÝÂ}•ÀNÌ,ŲUnŽ\Á6$¶¥ºã–_ÃÂq‡wï<³qÃ?Þ^ÝÐÊmÐ`°Œdgr;èè^QÜðÞ
+¶Ù£<‘68ïfkÚ£SF:ÔUµIשY³0rO
+endobj
+794 0 obj<</Type/Page/Parent 689 0 R/Contents 795 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 375 0 R>>endobj
+795 0 obj<</Filter/FlateDecode/Length 1972 >>stream
+xXÛnÛH}÷W3ˆØ­«uÉËÂÙÄ;ÆÀNÖV`,``Ð$[RÇ$[Ã&-ëï÷TuS¢•Éb}‘Ivw]NU*ú¯³! ð=¤ÙˆÆSJ‹³šÏéøQ­ñ\ h<«M—øMÔ%U†VØ<ÀñÃ6ãë#l˜Ìg|ß¿Ûzÿ¯³éLÍiˆÏK*h8©q¼Ëéá¬{Õéâíjç«Ð´èžíÜ4]BCÐÃ’»÷X…w­²Ú¹Çê|¨fݳ{¬.jØ]íÜ4^ªigõãò¬=¡á–+Æz:ŸÑ2ô´L{SÒ ÕÕžjGß-©ÞÊ\¡qyCkS˃Âx¯×†~YbµÐéÆ–†tšº¦¬iå*l²žRWl›ÚTd,¤Tcüûå÷³] ÇjͽÒÕd^­¯ ‡p„ï!âm’›_=ntýÎÓ®råúñðhª&|xÉJ¶•Ã΂§ºñ&£Æ쯟þ)â6úÅ–kÒäì=\W G³ݬhïÒH•ÆóHaýëQD¬c¸Î2ì‚S>­ì¶ûZd{T˜zã21­Œ®àxÊ ÂÜkòŒl™Ù”wÔð”lM`عêÙdê°Ï¥o` ;£¢³± ¶ì} àÃp¡=Ý"v•#¥®í‹É÷d‹•S ¢)ëʬÊFçØí6{øbÙÄÀ•à_†`W•Ië|/:/:PÝêgðÅj¸È‹öÕìÛ³1s~ E¾H¶Úû]F+‹@:IÏ„t‘hŽþ1¢Y†´`umŠ†øê’Lfkd^¥±ÊY‹G‡Øw´5µÍm½?Ï’÷Žžu5”º0œ“ü¬-;S¼ùò@²¶CM )ßýúŽôvkJ1Ñq<õÈ*Ó†®­”¶˜þäÓ¿ÒÓ{EKØ éœÄ |ƒ7‚&pJ„÷Mö#\º
+=ÉV¡JLäO‡b‘fÀ.𡨴ŒÂdýktlÉž^‡ . uCØ;@?¥«
+aÌÌ•æüľ³?3`ÛÊ–“´ÙZ}S¢'fÌJNRÉöÊe %‡®<8ç²XÙuÛ‚mßêEçÂÓc—™ºr9­rÍÙ–1‰‰×Š‹LR¨¬ï™]Oå£m…à{ Jÿz@ 3†j2!Á/ÕѶ)~E£Ò5¶B¶Æ/΀­©
+[+ïÞªºˆÂÆs5
+ÂbÓÞiP €ªŒL*‰NŸwºâ®„¼ªm"ôÍÄ~žÕ+‡ÞúÜûºbË£ˆÎƒU]NÙº0°°†ŸIÝeÉþôZgbóÌÅ(_dQhÌq û‰À¦´¯?
+„‘ápiLÆÎuÍäÔ9ç:?V ç(ê œ)ÄíAräV!Ù8¼‘PÓ–P171dÏÕ|zÉA}MgLŒÁÏVù\ üg Fa×BMÑs”òÕå6åƒYûkåX‹Œ‡Çªb^äµwÛ¤›`šj Ú/„†©„Áàß0®Ú]¬`þNý“1ðJý ù(r>CÕÉøHj¨4IƒÞÃ×è‚Ütª˜Õ± Ê‹ž"ĨéƒÛyp'Mðþ*újßo„o1J„:jYÙn)àE”
+endobj
+796 0 obj<</Type/Page/Parent 689 0 R/Contents 797 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 380 0 R>>endobj
+797 0 obj<</Filter/FlateDecode/Length 1843 >>stream
+x¥W]sÛº}÷¯Ø7)‹%YyéäÃn=4Rî½íð"A 7$À¤%ÿûžHšf2Ì4ë‹ÀîâìÙ³‹ÿ\…4ÃÿÖsZ¬(ίfÁ ¿t/_ÿv5Áœæ[üH9-W¼ûoí®Â›M°¡ùÍ,XòÓÅ¢ûÆOyÏ|9 V´Ü¬ù3þJIéÕûýÕônIaHû”=¯6kÚ'ÎñŒöñøq¶ýËÔ¤¥LèÍþO¬G ný¸0™LTÈ‹¼¦Øä¹ÑHr¿ªµ:&¡ØyVZW?YÐ}Eʘ~’ZI]Qe¨¨ñv’T ÛžÑÄa±OÆa”ªLZRz_ü6Šœ§(R:†u>©øÄÎÎ' 0ØÁAiQ>ÓYeeÆ|§Ô”ü §ZÃ…E0YB¿”gee0ˆæÑT’Df ö/‰*e\X…§ÑI%‰Ô£vã|…tá{øþ]éÄœ-=î ¸ªø™[øÇ>gSé8«dᬪ“ w'Ë'Kú"âï´ hÌHg¢’eôÆ…þbsé2˜t{©J{h=„µUúèqºi“LÖ{)àD‹\Òô2@òšT wÜ‘î~¬–¶X ¬¸üd«‹²q@ìV" ÀÁf&½D¿‚äzè¤GÄAlŽ|È kM¬€MB•Ì F©áMäYÈìÉÔÈïA’ôÐ`±
+c­:d`!dPgFp–ØiõÀ!“êsš"sÛµ‹ï(+à|ñL&íoô hÙÒ’þv „õÆqfbQ)£™[rü[–†Þ%¹ÒÊ"Ïîù?= • Ž—ãh¦´49=¨¸4Ö¤•s9½[5$èùƒÐLÕí ¶Ò&ª’ö¯¯QçĵԾ׶('†ãXšºhA9¬™,[žn/®Ò(€5½•0Ð'.F­°÷ }øˆ‚÷n[=êEE•1™¢RÚ慠"-+(…ÒQÔpåuÄcä· ôµkv*œË Å™¤Ã󀉩çã﨟¡
+9ƒðü¨A|°#rž:°«£€Œ1êb6¨ÚÆ…m¥$•6Ç/àË©A(¯ƒè›F’«ZƒíÙ3Ѓ–°³1Í£áD“|’(öB¹ˆO
+?;õª-œ;£GŽÙœükuOéc7£ŠÎ¦äJtžAY²õñ(->€ÿÇÙ­‹Äi4.¥HÞº]x†êìpL@'kQ«uÛ‹&† äç²8–âp@U:šOeO¹†çqÃóÉ:Ø„ø̽²ÍWë&›m%¸h?s~þwsæ*¸çÐètŒ„GYŽ\ÆF,н9â—vÛ+’´]ÂŽʵZNPý 3Ü;à¼6çk:õý2h¯|»Šúhr0ÉŽ®ÔRð\õö¢éT
+ÞRˆY+6A¸Å[¸Â< ¶lƒu@¿ó¬æÛêIfH­}]Z— È<²ñ)ñ— ýLÖÔeŒ*Am@æM™{öw(ðtŠJdªå¼Õ™±ä±>Ùkúz÷aäU>1qƒEn7
+õZ@¾9\dY¾ ƒVäñR±\¨˜¢+î'NÝÆ$˜k0ù à©‹õ(µ,®ïQ€h*¬Ê˜Š…+¾ž×C‰Ù7‚ÙÊa¿<„ ˆå¸%ŽÚØŠMúÒ¾w ¢£à;%òP{ÁOœRaÜ>"â¢4@Ñ#áÇrŸˆÃñ€H@3ÿIrš‰ú376?KÐczá4Ñ >ˆ#§~ÑÂs\",íª²2Ký݇cpq#Ìÿã7‡í@ ²ùS#úµæ8ª-d¬RÜ*8g#ð 7C“@Wt·,+k@è¹ñ:NaFwäîÌÝÈÛˆu7ä‡
+}?y g‹ÆS"SQg:1¢ g¸n„¸£pĘ>ŸØèM«ñ­Ì´S+—WZg”ËêF"I/}د V6Ïhw'aP8¨éÝ˽äÇ4in+­Ì)ÍÄ‘Sî×4¿¹Sc¯³܈]¿èúü¦™Âf€í‚npÏv³ÀîÝÃûwô¥4â:GûUʶ'á
+ëÍ‚&ëÙöUe¹^ëÕÆ÷¬å–ÍÜî¯þyõ_¸,òˆendstream
+endobj
+798 0 obj<</Type/Page/Parent 689 0 R/Contents 799 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F6 9 0 R/F8 10 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 385 0 R>>endobj
+799 0 obj<</Filter/FlateDecode/Length 1908 >>stream
+xÝX[oÛF~÷¯8/…œB¢®–ä¾,;iÆI·Ò6( —9’&&9ÌÌЊ±ÛÿÞïÌMèe±[±-^Îõû¾sFŸ/Æ4¿1-&4Sœ]Œ¢®4?~üöb²XD3ºš,¢9e4]N›O)­.¦W“芮Æ3\Íh6Ÿá©ð‰ï¾^_ ßÎh<¦õŽÌ— Z'ÞþˆÖñe"·åžT¾Ó&Né“;HÚª\%-‰<!‘¦úHϺ$§I8'âí“-âgM™ç*ߓͶ )ç_…ѱ´6¢ûüÕúÓňãi4ïKmiÎ ‰<¼_½Hˆ¾éýšŽÚ<Zç£ëÓNëh/÷ܺÅ3ñ(ùzÇc¬ó\Æœ]D?DÅÁÆΤ‘ºA"Sé¤Ïs¯ùN¢¨AH-Ñ™@E¶ú )K¶ÜíT¬dîhs)¥RX×'TíÜiÔ©LúÂ}‚ir°¸yÅö2—F°sê½³âM^fkSZ'“;ï×ö"Z¤‘bç¤éwSî¤É‘:üçž‘.dN§Äû>?Di$
+ë‹„ŸG•¦´åÜ_Ö¾n(’´¶Ì¸(î \Çãá ždÞsdÑA4MŸÉ´Á%†JR8CtéóJ÷`[éŽñíf
+=è\9¼  ?ŠˆPôLçÀé‹*ü&½Ovïä“LA7ÓX½½ë!#„ÛòI+ß@`
+RÖÝÞÕŒDGVø؃V®Ï¤«Õ¡œ'"¦
+ T¤ü¶×gë«ËMä*„ÂÛ†j"&äÌ/Jˆ‰EÎ*j8Q‹s‘ÖE”\ _$¨Š4;K¦ä9S6.uiúDn^ù°OP
+*Ù>O˜å¦C/|ø°æ{ÁÁµst•5—e á€E%Ì©ŽEÊÓ¥™Y¾5€M =nZïéø³å–#z Ñ;
+/„ÐñÊ…1L<X<i®Êäb@r
+,–ÁÅP¯O¼ƒ1Oä…uº‰“†? \~µúyµ~óðã‡ë¯6›Õ34!›N6›<LÀÍ×Ñ×áZ{.²£ækíU r„Yû³Bð& 2Å^Ðñ‰e µ²›MÇr#$ÕöʵľŽ=]˜gº{÷®F¿ÏRî3¥ÙPKy«eƒG`Ø ;Ä¢p%Ôð,ß‹ê
+5®N)uÿ<å‚:ÏÈFp[ô;¨çuØÿ½¶´ØÍVj*ptíb>TËHEs¿ÿðó-û-4ù˜ÿ?¨^%ôw"x»'ÿK–¿Ç2뻀˜Ýà¢
+endobj
+800 0 obj<</Type/Page/Parent 689 0 R/Contents 801 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 402 0 R>>endobj
+801 0 obj<</Filter/FlateDecode/Length 2177 >>stream
+x­XÛrä¸ }÷W`ŸìI¹Õ÷n{^R¾Ä³®Š'κw·¶â<PÕ͵DjEÊ=‡|{@É—öÎ$›™š)Û"E
+µóÙ(9á]¨íŸäìhÎÏ“¥èž.Y’<ÉîÉg°FÎ.XF|’Ý _e6‹UÓ¹ìÊ†W3iU0&‹“%­rdD«ìÈj“±…k*Œ³„ÿ·¥à(w6Æ'táêþÔT˜R{*W‘¢­kŒ]ÓG*2ÖU–"$y·úõ`0¢Áx
+£VùÑŠ»²t[>a<Ž—Æ2mtYmI?þðW,Ûœ45ضþ=Ëѹ"ä|ï*M® ;U¥Š¼ š6!Ôï‡CÏ+‰kÖ ýŒEõ¨¡£2Mã²Z5´s-}Çò†WYÇ`<NFÓ)"¢ï'óÅý®nûå-â ‹NÀ]êG]ººÒ6¼>{ø²–×Q/ÚMò0m½ Äû :Œk¨n\Zê*¡ë‚¼;&#"_ ØŸQ,P‘šGtðýävH7¼½nï”/ܸÇûNKDÃ]æB Ý4¦,{ÕÂÑEç—”jàm
+).×ùÑšO=X-7
+w7çäkù÷THÚãgR™¬qÞ°:»„h†y³2:ÿ“ƒé$Y.—4ž1
+,–ôÙ¾LNÆ ´å$-\´eŠ¼¦µF@€Å"1rª3(ì{æ8ÿç×Ä€pê³ ¬ˆ”å´UdÛ*ÅŸ¸­ÑœaùkQ }
+yˆŽçâ¸nMÎ/Z0Í›úwVnÕŽª´„ËçÊÀ£+[4ªÂ1‹í!ȬÃ8¯sä…ñQ7{Ȭ[Õ(>˦£$åmÆñY«&˜ ´ßP¡Uh9hÃëõ`*ЙE¯€¿º+°âÞ¥5üëYÛ˘d[`؆Ý]¹F¦ô)ó…š5=yÙaÔ—Ö-WJ\ÓKsƒÊ*AÊžbÓZÏŠÙyÏÕºAƒ%¿óAWR6šÖZ,íáÔZRB¿@GÝ)s©ß*-wâeñ*Y?Lò:‹¡ü†ê†PüÀV¶–꘡䘒¾«ãQcéëÒ¥ªü'„3øE±\ÌÈÇŒýzð®-©<7Ò”táßa‡~$¸K*R+¦æ£QtñÓÝS+Ãažƒº
+ÀŒÛV—ß`ªë—`„¶Fã[¸¶£a‚ʤw€ûy[²š4³ »° ¦kT!¾ ;¢¯Ë{±Ê=ŽÇ0ÕÝ;uù®Ç£óRB«˜møúðŠÅºîTѦEÓ÷ÜÌÇä?†qûèÁ”,LòF!8ð‘åM{€¢ Ö|SÊbYpÍ®›*ö'º7}R?ØÌ&|%úÒ`3[Èàó=Æý§±Æ1T_Ýu_µÌEÝ7”§¡é¤›&ÆÓ“äätJ‹~³þ»³›ó3ºmܯ\÷.;§Ég#hŒÏk£“) –£S~ÿ4Y‚й߉†dÒâ°“ÁKláoaËÅIüŽ3³˜¿¬þ~ð³íendstream
+endobj
+802 0 obj<</Type/Page/Parent 689 0 R/Contents 803 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 407 0 R>>endobj
+803 0 obj<</Filter/FlateDecode/Length 2098 >>stream
+xX]oÛÆ}ׯ˜‡ Ô$Z’eÙn‹ Ø­c¨\Kiòà—¹7¦¸ÊîR²þý=³2Ë´HóaXÜ™9sæÌPßãï„.¦t6§|3gc<9þxºÌÇÙ%Í/¦ø¹¡ÉùùñSM‹Áôl–Ñüü*›cuz>ÏÆñ¯âšOÆÙ”f—ø}ŠÿFR9¸YNßÏh2¡eɆç—´,¼Ý1-󓥦Jì$tk¨‰c½“•FoH›• PµjÖT+놴Öä𯒼*i[‹Üß@{Ù8¿¤i-醔ËÞ-¿Æ4šœÁ»eqrçWÎm>=åûlæmdÚ¬‡”×*áƒÁ!)Œ´Ž6ÊmH4[mŽ»øêÓ÷ç1¼Z´Û­6.<NQŸüèܨã݇kd-0è†m{·fôÁÐVšJl-Y)©’FÆX§ólƱ~¬¥°’
+Ýüäh«9i­XK›
+æÚž1òÜUMÄv¥õKð|þÆ®­Ìq”w)s[(aHŸ,Gäö‚Òê@O*¯„)hŸ[éËÂCÈr žxœ™æ‚öÚ¼¬n·„ ù*rWÞŠÎUl YA<ˈ5ÒñZ$‹1Ô…*ÁÙ B²gƒèV€ƒF­Z'VÀV´\bNåÂ'¦xÌ$Æia­\_=zJ •-<­5rF"÷„š"9–Ñumõð;ãÁ?TA8‚œWÎR.æüÚˆ†íá¢ÖJcIyjȶ~{ÙÖ@¥ã3X3‘p_Â!É8½“¦gýùäqW¼JhÄnȬ“
+×"zù
+¾¹Ÿ7 ÿ]ôÑøüs’ql¥ÛÜ2[/‚aC`A­;Xqá©匪Àï=ö(DeÛøúµr0]FKì8Š¬à_Xãë£c˜wbÑÔÈ R vÜ<}ø¼¸¼ãŠÎèÞQô o Å051Ù3W;Á©†¼WœO”00‹© Ié£}om‹ä$1Çv¯å(œL5³Ñ…¬}¡¡òÖ²0pm!ËI¢²˜ÜÈ
+‘(t"£E‘3Ûü€Q¬ìµHÉðÌ âS*ƒmº?º”‘[dS‹’¤¯zÐÙjÐØTXÚBr
+-m”Ýøái‹b£ðÈáàŠ¨g‘E’…gAC¶Š%ïùâG¾º¬k·ªx~ÇäÊ„¹Üá½AŸÂ®2‚µà0„º€h¹½”}^õT&3¾¢Å²ñCí$°8¦=
+Š¬€ONùÐqdce½0‡­Àó\mQ·¡ ¤„1îªy‘Áœ®ô¾«—^,}kBMÍm–§?F%¯5ÌP ; ëQù÷m¿âB„«è%ÀC?°~Ža5߈—8g&Ê":Uúž¦LdÏN‰NJj¿„£é”iÁÏ^nWÂü~6Ø3¡=À±±ìSArEarij˜·Á2¦‰Ø"‘ŸBÚ§Ñt±|1<²5m?Ð Ê£× èclÄÑ™R­[`Ô°·^B9÷Ž• yvªÄ«1e h>+GðSUì½H1qÂ4šS¬7?_ù‘+ÎœKTSì/ÇJåy0úwÿ±SÀiZŒó–mW€)º©Tà–ð‡ïŸ±ØÁGÏ/Ë -ÚÀ™›û‹ð>f·_'ù¹Mq¾Ò/×â MŠèp^i°-(BÐh îöÇ\ id.Q8€5(ßq‚ìšðo41º(Å¡qÂSqÐxVJn,•Ïø³¸}úóöɧ|„§¤”“Œ8f<ñ[ÜÖ°ê§ØõŒ
+¶.ÆW¼ÿ_¿Ï.fÙÅüßùàÔù”/»]þ7ø?ÿgî¤endstream
+endobj
+804 0 obj<</Type/Page/Parent 689 0 R/Contents 805 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+805 0 obj<</Filter/FlateDecode/Length 1990 >>stream
+xXmOãHþί¨å´ZF"&qB^N:­`€]¤æ†ìÍ”/»=Øî¬Û†É¿ß§ªÝ‰ãÉžtŠä¸»ëõ©§ªóÇɈ†øÑ,¤ñ”¢âd iŽƒ Mæ3<‡øTšY˜,&íÂŒ†Á¬³0›cy5šs÷ÞŸYaî=ï9*êÈÂháu„óá¡’£K¬Å-6_@±3ñÀÅÑå8ÉBϮјÃÁ^÷]<¶"ÊåÄ1幃ÅqGVD‡¼ïé¸^ž\ÜMh4¢eÂiÎg´Œ!w8Ò2:[¦š¢<ÓeMuªKŠLYꨶT~AÕÕO–RSh²©BúU“ÕªŠRm)1UwÛ¦2I–뀮,eØT¥%ÓÔç–_O†4ƒê϶¦¡H•d7:Ê’mWDW“%å”–
+êYñFÕi@wЪ¿©b“ësZáF¾éjµJ*¯VÁÎŒû„:šÙ§vÒͦ)ãs¶`+ß3–Z :ä0BNu˜= ˆ_áÍ`¼¦üjÙ‹_œÙ]“ÊÇ];g*½ÛÚFûQ׿™ƒÀøP÷íÏyuaÿøôxwÿKðéé7±ž6&Ï¢Œs"¸O :Cx·¸ˆ„àK¥U,Ú9êó3sŽ^Ü-hÏ„—4˜LœÏ‹`ŒúhÊ${i*Ug°ø¾´uÕDülÿNpäÝT¯$ÞXvbBd#dJì
+••gI¢+]FšÖ8¨CEŸn>ŠŠ¾delÞ--¾Qî¢#éf¬v €ouªjÖœ|Î>)kaJL_m7b+¶–¦F(þh2 FPü—jwQ[CƒY0g¦„ý«p:@ì}“ÅÌ÷†_<ܶef)6¢}c¬ÕÖR¡¢4+5!z¶&EÈVmÿ'­ƒ Yì}(+ÒDu(zVÅÚEó=ËsR¹5ÐM\]{ BÛj¿l}MÁ‹9ç-˜¥‚­Žš*«·T˜Ø•f¡l­+ZWH•®z9Œ.çÁtŠ¼€1‡ÓË6ýL'ü¡D¿#×PO¡^5HdrudࢠYæ!Ô€ÕÈglW)…3k†MÑD)Åz­jM”Àå×/¡ÌÚ« ½§Ë”HB\}˜WVç¡¥ÛðI°nŒ ¸¯+“ç8 ²‰
+6e`‚Ãc—[bv°“°ÒBðÉYx© à£ÍX¾¸’ºùЗÌ°P°È'
+ÖA×}¶ÆòÌÐè„Ôzª;Ë^©„« }HFk¸£ëh`^0ª…EQ •ž\kJ¼a~^}8gãZTôbLLY¬lê`M@ÿA·¶©iòP+t±–ºR21XZâXéè”M;­¹\ß?=wpF¹äM".=ãEÌ»-z½ÝÑ’›L„rqQs®$ÂmOð;ZRu~¿4™Mw­Ä‘^"×2AôH¹JòÁlQ{àšƒT± îPÜu`„¶=ZÍ;­U$tÂ[v´ã¹E2¸—ˆ¸PuÏ#têk•þ!Urš»'öÔXéy¼"Æ^‡«‘ þ`²ãZsPcÞƒ]–}Sys˜yìc!< rwçV©mmeÔ([ð€¶ÑH¾‹#€!4íôùö!…² Vgüít㻳3étõ^Kîõº©5fGg 3ªp‘g¯}ÀýвXüȬÎrë¬@ï“”:+x?ã]ùzo-‰Ä™êFÁ´ôO Üä|$=¯OwœpŠµع<ÁXZqó´ ¾µÒ7ßÇ¥·juæ_å<¦m¥¯y“Yc·LöœS•½¤õÏ«~ÇàÒ;@tA·6ß<eµ#Pë.ÏQ gÊ1ÖIVfî´nšàhÚW–‡I£„¶ŵíÙM"<ó·,¢òwµí€´“X
+endobj
+806 0 obj<</Type/Page/Parent 689 0 R/Contents 807 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+807 0 obj<</Filter/FlateDecode/Length 1591 >>stream
+x­WkÓHü¾¿¢/ÒŠEJ¼y?î ·ìqlœB{k{Â̘°ÿþªÇçÁãV§;t$ãéîêªêΗ³õñg@³!¦gý¨OÓé¯ãù ¯Cüo$¥øb>§ý‹ÙàMŸ&óE´hŽFÑ,œíãÚ(¼4gdz <èÚÑøá×Çó6…Év0DóÁ8šü*ÛAMÃÙ
+#šÀ_RªÍãåç³>õ
+!tJü¾²Ò<²´5:U¹´-3…R ’Ë„#[m·Ú8¾®=E8’¨4•øoPÑâ= âk‹8òåõ¢E 7œGcÎaÍ£a4ˆø\¢w–
+mdóx\d/D›ù¨ˆ¶Dg™Š*¯áuܽõUá_ÿü¦¾¹¹µK¥(d~￳¢X 4ÖgÆæïÚ¬¸ÇÒŸ»9ç;€ùªbÉI°qb#Á'³rº@wb‘#Âú¾†;Ó…´Œ¶:¢)ÝëŠ
+à•5 ãÂ9Y\]@„ø %mn,JèQye’8)¼+&:} ™¯
+´]K·“²„*7vݘWˆÑ¡›?—ü¼‘`¬ÄC¨wÐ*´ØCãÓe“,úÈçö*ìyDŽt8Üëòý/:Äc u;}¾ÈÇ×Û©ûÄu’ 4ÝzZdÂR©w¨¤êj°ŒL§SJw‚&/âgvÚÜYÂ;™ç]o<
+Vé´îÂ8a¬Kí
+?É¡¹=˜ËÕ}ÃY&è>ë}ÒuuLFS6*f] ­ÛÊ9æ:, Pjž²öஜ7heÀmî=OºwU9Ú å~c]"
+Ö46ß® ,£P% Š“»¼ng–ÌéóªÝ
+[€2˜h°X˲I£Ó~\¼‡£›~~ñÑèùÓ%›a³…Àå!*¨ +\"¥Î­XL_ɲêtOŠé<—öÎém§Kä¸Á豚س3­“ŽŸ¶PrÐ(Ï ær`Sºí·so
+endobj
+808 0 obj<</Type/Page/Parent 689 0 R/Contents 809 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>/XObject<<>>>>>>endobj
+809 0 obj<</Filter/FlateDecode/Length 1885 >>stream
+xWïoÛ6ýž¿âà/N[MÒü,0 iÚaÅš4[ÝC]´DÛ¬%Q#©:öÇïÝQ´u†a(¶Õ"ïÞ»wïŽÓþ9¦‹zvNyuðbrðô§S:>¦É¿œ_^Ф £ìèèˆ&ùáÚ”%ÕZ,µ^SXjú¸(íL•ŸÈ6ÁØÚÓ qÚk÷US®ðÍ´Ñ~0¢_ZèŸ~$U4¯½®½ ‡x2ùrpDããgÙ ²8¬í€LMÖÚqüJ™:à¢4&¨’J‚vž?’PyäT½!;—\gç¦Ô4·%nñYâä<;åÀ,—½¼ž|˜[‰áI9£åŸ‡žQ̵Óu®}F¯ç´±-­_rbºž[—kRäuàÈ{‡T%Ì×Cø8t¤Øe·×w#!¨Ð
+èoJ£ë
+ÎéKëCCïØ'H}Óh6a®ºWÕŒ}y‡mÆ+Ipzˆ.oƇ.ý´BúÒ<úÁøa¦•Ã…½Àð“=ŒœüVªeÁ“«
+s[뵆%§BÈ.Äë«
+endobj
+810 0 obj<</Type/Page/Parent 689 0 R/Contents 811 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+811 0 obj<</Filter/FlateDecode/Length 2056 >>stream
+x¥Xïoã6ýž¿b`àÐ,`+v~8qú)½ÜÞè¹ÆEpX/Z¢-®%Q%)»þïû†¤d[Y ®mÐÄ‘83oÞ{3Ìgãß Ý^ÒÕ”ÒòlœŒéúf’ÜÑõÝ-¾¿Ä—‘´:ûe~vñyJ“ ÍWüìôî–æáùñ˜æéùÛÃoÏOÏÿþ4ÿŽç®ãsç4¢¥\iœÉB:U­Éå’R]9Y9KzåΔ‘©ÓfO…²Nf¤*ÿù‹Ñ+UÈárZœ»\YÂ…ÚÈbONãlŽ7¦Ñä*¹D:çéýb±SU¦wv±¨ÃÛø®±ÒT¢”‹OCvÃg—¤|ì=åb+IT{Re­•#jÉ"#ä¢}.Ê »qº&m_/0NÄÖ ã¨”U“„‚åß”{Z`)6Œ ¥H7MÍr^$ŸT/¬
+šág+Ê¥@k2¹lÖ`¾äO]»ÿ®<&c å\°òLSA 5"9#RI‘'=6Ú4`Þ¥uÖ”^µ [©«Dþ)Ã…ÖÏV™4†—ìið•VK(d¯›hi*­OSTô<'0l+ÍéVDc>rý-JæYlŸ=TL|ÿà€Áéºs<®GŽöElàN'ù'Ÿü…¿¯AåcT,GÝ*8<
+u_'cîÙa\þÆ`
+OÛˆ)ð‚û-Ï|¢ïA‹6¢u¤‡2ë0Yš£’ØcØ|b)»„±êÙZ¦j¥€¢ËnÖ¹w•ñÕ&%¼1Tss’žµ“÷§ÅžÓ×b“4‹f=»Å¤T
+t[,r]Êà ]Í”M¡ȳWš ­^†¨.@Hò¨Y£2è ¨xf—BU_Á³1«+ nò`|õ¡¿‘ÍA^ ]® »Lƒ;ï•vïð>8È7o)ƒ°¹3¬yIÊÂù<Œ{G~,ý¿vÃ}£Þ@”Çùñá<íÛžÓÊèòcæß‚…a—éÚnà,‹]Å‹ >c:ˆ-\L,¡56JF°×K\6î[gÎŒÚÊó ïÚ\7EƤbk@ƒü~Ыúi°kðÛQªÝ»ˆçW#´ä{S…žtê¬ä® Íý*h-¥53TI1¶­Öí!Lˆ±•E
+´…ă
+[[BO®{`ðP×…ŠãáQ8VTÍZÅRsXs{5Ã÷Ûçêûêï _pOˆ«.Ü#¬º'ó x[Y¬Xñ.|ƒ¦[+ïvìñÛ­¨kìÂ~Qaß —Àt÷ô>‚e€`T7¦f¿FÄ´1X8ØTx_ÕÆimäXˆxR² ò™¯á²ðOÜíŒ.èET²ðÄÖõY‡Ý¿íâ9îGZÜ pá­mùOÏ[î‘[ØÎEDí
+’`õbƒÀÞÅÙ¤éã®Ó õXù³dFc¿Ãʯm
+þ~ÀfÕ ~ju@)¬yG Š‹?ñfí_ÄL ^ •øâ¡™Lø[/íѽøü,·‚\¼²QÁñ¦å``yüeP1äB‹Œ1ëRëê'ºT`ôªÚ$<m™óˆ‚pRŒÊcŽ½Þ/§‡§â<µ˜H|«Y©ucü’Å‘FG{.ü»ágiÏËs \ô)\C°Oôjzg–oÞC½ £Ëç LýO½’J¶!äÏ<À¶ou±•Yp‹Ïwqu›\M’ñÝþÈáoÒ¯_~y hô;3êQ§pYlH<î|“)þT‚ÇG·ã_{ÂâKP¡^zª¬3Úöž^㎶þo ¿óN„ Ý=ÿúö:¹Þá48ófÊ¡þ5?ûïÙ_µºÎ“endstream
+endobj
+812 0 obj<</Type/Page/Parent 689 0 R/Contents 813 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+813 0 obj<</Filter/FlateDecode/Length 1987 >>stream
+x}XkoÛ8ýž_qa`v[ V,Ƕì
+.Ý£pÌýsoxrâ„ûç|礩SãÉÏ|œ8q>Üó¦Âh„§ 'a0u½¨Âñ™sÎýO°sÿü”sgêÄÁb† ØÅ%¿ïØà[#:qÀ7Üãž«³‹/
+CZ¥LõlÑ*ÕÑhD«øݳç8£ñHÔO‹ˆ†$R++2"ßJÔ“4–b]UÒ”ºHdËsÒ…¤ÚàVªë"9'Q$ø£íb]¤ªÊerþ~õ×Ùˆ†áe0†Ãwv+,••NU& Å¢À ´‘”i‘È„ÒJç$¿°ý[u«†FÆu¥ìž>8·çp€Xª}i{nJaÌNW‰Áå½4Z¿3Rb#öLŸ—Ÿ¾ýçëêö~ØW»~Oº:rà]7.Zc=MxH•H`cÒi°×uµ\,€/ ”ôY9htÊaIº´J†v*ËHd™Þ¹ø–+ö3ì`†Dž|›¬&ÇŒçâùiq2ªx¢?®—”‹B<¹àÚ¦`ÎáÎnumùý^BŽLU€øY8o…®rD¶‡èþ®UC›=-WÔ(tq&E5´òܶÈÿ/h̹7€úFbÓVb¹4±Îs83ðKõbÃÑÁI«’+—j,2‡]{B¹°ˆÖ<¶®ÞTÖðü˜×Æ>²ÀbäëËgÜ\¯@ù9¤[AnÀ+VWûÖòy{ïîzéó¸ø²hŠgˆêŽç>§E0ÆÁ, ïªHôÎpÜN¶œü[Å͆êC’2ĥŒRcuIÐ ™RÆ*ÝócQ a·È%Ç™zFZˆ˜©ÏtìL8%óÏ6x¨ÐùÀMT)^ìÑë:KZOÞ:làf¬s ¹—"jp!._äwÉkÅoGÍÂD¼8ë¹õ7ÉÔe©+~BœŽÆ7¤´#œ£€¶¢bt¾¶-d#íNÊ‚¾/¦®!€€ïz™#ÏÄ´¡/GÁ”Œ‚ù¥kI_µe¹;CzPç^‘*\Ç‹-ô•áÀç25ÇÜCPŽçhr³`4›²Öo‚*žùoÃ\Ã8môSúÛ@Ý[ñ"™Jd&Ù²ZÔ7#½Ä%YÊõ{ö3 ƒ âìÄ rñ^*êÌó'°äd/küúm¹^ÿù[ÀBìâà› ª%/QúšâJ")ð› ¬cÖ~®sýeè™[¯Yf…Èeðõæa@*í*™²&Ñ@¿°0p]ȽãÛ]§Ûý /tç;X_ɾWˆqÕøbp\òUäeÔ~åx½nd>p5êèxÿ N¿Èå`ÒÁ‚þº‹Ì¹ëo\³èŸm¾9Ðàܶƒ[#à+h'
+GŽ
+ü°’¬¨,ÝÉ¢¦ º‘æ™»·q½«ðÓ¸ :||èÑûsvù Èwì°Y
+œ–· V¡z“Jì6"~6W¤1¡u“Ù¢¶cž.š¬Ì
+iù*ûK€‡ˆ{7Ôˆ†¡©ª ?ûYFñÕz½SEa!À½Á%èÿ ÓÀ×Ôáߌ´Þ¼(]àŒ]á
+XyRr»Â%:8Ï„E°èæþîúvùøé~¹úvÿ/ŸtÕ]nt.Í'ŽFgôzàÜÓݪ¿R¢qè§c;ÃŒQÌÏ};Àîš™u¬”aEÁx¾èΪÏ(Q–²HÔ+zê©ROªpQÔØ›Åïw½-è_´’Ui€F»¹ñT`s‡ìœqVó:ï Dsî“\¢ì0Qí¾Ñù¬Ý­~vËûÕgúAî+Ð 9 ŽñÊdåwvu±’Pp³‚©$³zùÃÅÏS.qó>%N•¿WõDâÔŒÏt˜DV
+ÁAbK÷–WºSxg<³5v{ñeÞ.d3|ÊÎ/iÍ‚ÙtÁ•òp}÷ñšW¼¿°š
+endobj
+814 0 obj<</Type/Page/Parent 689 0 R/Contents 815 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R>>/XObject<<>>>>>>endobj
+815 0 obj<</Filter/FlateDecode/Length 1766 >>stream
+xWÛnÛ8}ÏWÌKÑpçÒ$Íùu,rÙØAPÀ/´DÛl$QKRqµ_¿g†’£(Á¢(ZÉ™9sæÌðŸ­=ãßïÓÁ¥ÅÖùtk÷û!ííÑt/G'Ç4ÍhœŒÇcš¦Û+»¦‰*æŠRUR¥\0©©TÐdJ²ŽR§ùarsN™-”)=Í•×Ù’üJ9üRuXéûT0x›© x ùt¥ íÉâ³û2ý¹5¦½ƒdö·Ã
+ÖðžžL™Ùµ§Û)MÎn’vÙþQrÈËú_µ{Ñðûæìœ*ÏÙº'mØ)ªr8H “kReF•3e 7ζŸîþúóáîñžÖÖ=c¿¸k‡®Åõ³/=WÝp9ôòŒÐ¥`B¶ Îæ4Û¾¼»9»¾¥BsíFtïL¡\Ó­KãºÞ¾³{®Òçºz¿rö%¡)òª@Üž‚«5-àÜÝdwŸž”«h"!ŽèÒ, `¡{V£À ø“7…ÉÕ0ØÊÙ¬NƒÐ$» õʤ«¸0ˆTå¶\ÒÈ÷R8LßÔR¡Ê†*m+äY-‚v…ïò@µ7årDÞR®Ãg°¡`)͵rÂeÜðä+p¡éY&ßø  $àmnÛä!›+É¥ÓKãÙ@ÇÒˆíæ5'HHB;òrÖÜÍ´O ™¿¦4Á¨ÜüÙdJd¦ˆ¿9GŒ*ʤ8kÚkÒÿÔæEå0Àx?–æ]*]ØÒÃK!™«KAü†õ^IèòÅ8[8j†Ê懱
+4Ͳˆ—ƒ€ÚlgÙ±E¤ôBSáÛ)‡´û²ÜŠðN§o§³ÙÓõíít6û#.ê”z›2ãèÓDhý`mø4›Å‡ƒýÙŒËÆ,[¤ºÃ8%蹑<õOÁÛúÑʨ3Û"ùm_‡žêteßxú_ȉyÑ"Ÿh‹·„Ò7¶†X4´V( ¤õµ
+I‰×iíLh†4
+›é<ºèURd®§)èšïd£‚EŠìÍ ’ÕÂëü•7×PMyÓG#AÑ@\a¼çñbê¼z¤JµDGi2 {'Ø`Mƒ
+I÷ŒkÙ»’h‹AÐÔ·„ÚÖûFãÚ#ÉãRéú› =›L@P(0ך5À±$ ìÄ
+endobj
+816 0 obj<</Type/Page/Parent 689 0 R/Contents 817 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>/XObject<<>>>>>>endobj
+817 0 obj<</Filter/FlateDecode/Length 389 >>stream
+xm’Oo£0Äï|Š9¦‡¸@X {KúGêaw»[zëå՘றYÛiÕoß礭¢j…,<þÍŒÿ²9?š«rÊr‘£.W¢BÕ6¼.ùõ
+C¶í²óë
+Enà#uÛ ëÁò<G'3¹¡ž•Eï&Ò/ÚŒô¬ðëçn½žˆ7/›ÎFïŒQ‹ÛË‹‡3›Ы ==…8#IŽ§Ä³î)˱,V¢ä‹ŸeFû;«°%ùw?ÿ×g{ðy'”5·dB7*p
+endobj
+818 0 obj<</Type/Page/Parent 689 0 R/Contents 819 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 410 0 R>>endobj
+819 0 obj<</Filter/FlateDecode/Length 1579 >>stream
+xW]oÓJ}ϯ‰—"%nœ¤I@B¨ôÂÐK"õJÀÃÆÞ${k{]ïšàÏì®óá¶WQˆ½;gÎœ™<öbâOL³§”ä½a4Ä“ý¯oõâñ<šÐÅ<Ž¦”ÓhrÍçŒ|ž.f1žMæ3ü„¿•¤5^Ìç0Ôþª6l•FËèM8:›GíÙ§ál|1‹fOÍi2ÅÅŽ»«eïüö ìÓrŒ¦³9-S—ž$g×[QZYQ<Œè£Þ‘Õt™X†]‰ä¡.éFçB¯—ÿö†4MpýìZ¶ÒY†‹ªÀÉ»º’YC ‘¯í_¦GW9†w9†Á8ŽFlNãˆî*YÉÇZe%}“"Uņ½ßN(ŽÃ•ÑŒ/\ɵˆ®)Aª¨%€r78»U†ŸQŸÊL
+#)’ ÄkaÝ]‰ÎaËŠU&i§ì– ®Õ¦®àDÈ6û@}bw7× L*MR©•L½KéÓàíàã×ûå×Èš¯ƒ ùŽ"ë¦Òu‘¾å=ljLDÀï€hõž>…W¹H¶ªIñaNÕ…Ù¡,™ÞèØ<ÖÒXCëJç´ÓÕƒ±Â*]W·N–÷ªHõÎЗepÑýVòì ª7ËWÙ¿?Xîf zxÀÀ2A|«ãÒsë(AÄŸäC[…ˆ·Ö*g’ý"—îD)Œtÿ†lSúŠ0tUÁcDK„rB߶ {ŽVÀ¨Ì”4žÀYÒkävä+@«k»÷Ô'¼!ù[ä ˜{Zf"AÊÔæH ••^+œP¦“³±àpêqòG×u–‘Ë ž>~Ñ%ž:Jƒô¼–}¨§T€Ì ¼7lô hPÇ1´\›øâò³ã'·òò…¦Hœ{Âî4=€†xZ×êp7áæ) SÎ{K—èc•‹ªyz±“ÿ3´Ê×®Ž š9wõ‰ÜQÂг+¾áëÉ]ÈÍM¥
+®×jÄ)MÔ×ÓuNX9Cà\®¿„ÊXf"ºñ2É(tòµ
+Z´°:„[À™a¥6†is¤,-Àïø$cIôú6hÐñ‡>—ê—µµäÄ.ß%ûBèU(š
+b(ÂÐÒëµJ|4˜e‰É
+°‰!e*_]â¼{´ùvDƒWý"F£¥¨pmá„žMßdz%²ŸeäÜC«˜|ñèFçÆHû–­žßé à8šŒGP ¬8øšÑZk}cŸáÇÄ?¬ý<ßJzç£îPÈ4ôî;jäžIǶNKðâ1Y$USÚ}ƒ¸~Á"ÒymƒÌöçb‹ðãÓoA ÀÌL<EFØò|ÂÖ`(SX5}ߢæ§eô½ÖõÝO2[î‘ Ñj¸Æ@Ÿ5V·ƒà#–Xb²qÕÂi£ ë´w{<?Ø¥÷óËÅdÇvŠg ÚÞ Û½üKuêö7–1÷*’ÇZdjÍ“ò™½¤íTäÊå
+·¿}€ÿ¹wV—§#c@ €ë‚Vi+¹QNò¡/Ò^}úº Ï8î™Xîê«8ñó•ûO_@¾B0Œ×9°^¡•)tãßkv¦1A)dt˜=®|m®m;ëBaëÚææzbõlÞ¶;Ç[ ½ŠW^s±€° UÒ›¶ tü¶ÒØá8ô’°¡³0¢v<ëÀf)·xªÃ¶S4þ¶wÈ?¶)lh‡y
+endobj
+820 0 obj<</Type/Page/Parent 689 0 R/Contents 821 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 413 0 R>>endobj
+821 0 obj<</Filter/FlateDecode/Length 1930 >>stream
+xXÛnÛF}÷W Ї:€E‰’-Éy äKF*‚~Y‘+‰1¹«pI+ê×÷ÌìR¦™8 ŠÀñeɹœ9sfV_Žbà_L“!Æ”Gƒh@gÓA4¤Óé?ñUjZÉÁéùYtú½ƒÑÙ$š~ç
+`'Êà»ÛÜ®­éx.5l¸ÊE´°dlEv« 9ÔeVíics˜_Új#þÚu`㜡ӹNØûãÅÝÕÝk)=ⳫKJ6Öisÿªã÷;Á¶ªD˜(#š­*.%—˜m¶c€åÔ{ârÿî()uÊ¥V¹C<\&®IÇ7G¾ä°”Þ¿b2°Ýo":!å¸ÀÌ
+¶ÐÇáØ“±¼aE’Â-Áá«:J­è¤ß1XüúG³º n¢ø¥Vñ³ýgû÷¢zTY®–YýT®:¢xÉóðB‚§,\X<û»H ºÅ!Z½­xÌíóH»¦á£ã•Yh¶3?¤ÙY3ù€Nð§B4€å%˜³`f¡Df¸‚0C‡¿æX0÷à3–«,×Äý·Ø ddoËì#®ÿ~vùîæö:šß\ù'š¡zL™¨ãŠgé5/hГî`tÐÉHw•b–• ç Ï Ìu€àÊTEIÙàŠ{(j¼è… Yx-KI­!̱ž¤Œ_†û¶œ5ýÞñOÈyÍneÚ² ʘÂÍ”äâ‘ÇËÝÚJ#ZÌ“°KäHÁug²ç=ú
+Šä ­v"¨à± e¾2a–”nå#L¤é*üÍ)ð<¯W¯µo4¥KŒù¨J—ÝÒ¥ªRKÑÆÃù3£Í8ûÄ—:Q˜‡w¹µÎë—¨ƒæƒÞwi4¿¾üx½˜÷‘CßmÐ3ìêîýìæ¶YăÔåY†„K ÄÄ6ºZfÖÏéˆæ™A_ŠTÉ2å Ò‰™Ö&CÓŠŠÈª ³JúZ—aLrÞh÷]–ç´‚¤Hß2æ†Íà{‡}G”š‰,«Ó:ÐÅgtÖdO®XÊìIï§~£yZX~Q,mt¾ÅƒH*Pâ%TÞ÷Y'™²6]ÿ¢+êÍýÙSó K‹ÒóÞãYö&¥ä ”@%¬‡M/|gEdÓmªbnó¤×„u‡ñíƒ80G‘ì¶ÝඪDó*
+Ö¬æœúºJúž«"£ò»¿‹È&â§K³ªüÔ!_"À'Þ²:Ž€¢ßÔÃÓ‹=æ8$¡P©>!àۤŠèÇ0
+­èöfŽgdq S'¨©,üHÇ¿àrÞ¥üóCç~°.Þ=ÄrÁŠÄO'y†í
+«S§²€!ml½Þð^+ñKrÞqæw$Rè]•$ÚñM j
+ït¨!ˆžp¯ËöÃc¹©K(õŸW³,y¸Žà}ÚbðÈå«Õ&K`Üë8uUúÄ{™ÁèI0¬Ïù7óÍãEòMÎ=;™{~œVçvð\œíÙãPÛ}û4¾_`¿Ð–—ö&36´Äb¡Jö쾕!Í_±yàbùRêÍM½•ü4ôf<šFÓóÇC|Þ€ütøPÚÏ0ˆ?Áe÷¶-ò'ƒéˆz“Áùá*÷¿?Ä8œF“ñŽÀõ8f׋£¿Žþ¶Á„+endstream
+endobj
+822 0 obj<</Type/Page/Parent 689 0 R/Contents 823 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 416 0 R>>endobj
+823 0 obj<</Filter/FlateDecode/Length 1272 >>stream
+xVËNãHÝóWêAÂ&vž,Z£
+¡J‘çû³Å“>Ñ Œ‘±·K¥’/ÒReH•˜lë,qÂ$j#Wç¤ eîM0Q:]‡"y7‰ í2—úl±Ü
+kw«N6»WIj´Êþ³V!¿¾¸Mj‚I8(‡C®ì)O¨2h€
+âi]R0ŠÃ)›ÜfŠ 8oÚ>Àh­Kµ¢%Š";m~ZçSÚ#ÐÀÊJç2µ©Òõé’Ç…ÃALA<
+§ø‹tnr½ù_MS`?&þpŠÑå–>Ò|öõjvÌhÐ
+Y¡ö!Jšê‚6œú~÷mŽ9µž!®4m^æ² ^n,‚‰ oÒ]ÝÝÏ©šOæRáøe!…r p'©_²ª@,øQh,œÐ¬ß¥$Í”ä2$ð7(Ÿzú~¾§´Ö&9h^iN׶ßÉë™ó!ZÒ.Í’”[Tªì¹”m¾|Tn¤Ç€õäÆLV³§›Šd×Z9£óhUs½¤{µ†JŒ–™õÃQ…ôYï t÷ª,>b»Å´Îrù[¦ÙE„‰Y³zµ½eBµþÞ‘q¶RÙÌe/Àìά©—¦Vƒ*Åñ2Ç /D…XIßÄn} öžÍ§¶]Z²è TMòr…ƲùY‘3¥u$’Âðº4µ‡}:ã*}55ËÛæ;#b(H@[Žêñ¡ÏyÌ•Rs!ÜQ´Æ÷ ×N*ή$ˆb1¦×F g³;ÎX55A÷9‹Š“´%ŸËìEäR9{Îâ]póÌ=0³p`U­à·fýçòv™yôÏ—Þ;ÁJÏJIP¹×bÚ¡ÿqqwp…öø4¥Ër¨QŧQ-þ=2|:<õ¢§³·LëÕîX¾5: ŸzHÕ omz,xµdÎe·Ú¸w¹àö6SxZ™¯›±ý\rë*ëqÛË]·ßj7¬¯a]£ºt`¦hî°r¿W*·ß‚Ží„ô(9DÍCúxµþÔ*ÁØáš u^=ó¶’`Rnßñ„ácÝê#Ãxýùžf›”¶¤u™ÈF;ÅR`«¾â€ `· _‰­E·i®‹ï7Ü%¶ê_[BUKÃÓÍqlð S•Ï_¡z½³j»»9P©ÉäáÉ[C{1òìŸÏ¿0fP©Bßœ—!Í¥§l§ßiðåfö|¾ÿ¾¸÷è¾CòâvZWqßœâÞ9‡ýñˆUÓ+=4[ÿÀ!
+ÍNÊeú+
+' —`ÒÇeäÿHõp2 'cÜÙ}sÔO‹“?Nþ™íe¸endstream
+endobj
+824 0 obj<</Type/Page/Parent 689 0 R/Contents 825 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 429 0 R>>endobj
+825 0 obj<</Filter/FlateDecode/Length 2006 >>stream
+xW]sÚF}çWÜéKñ $ÀàÎôÁëÖ3IãÆ´é/‹´‚­%­º+óï{î®’tÚNƱ¥ý¸_çžsõ× ¦)þÅ´LhvMi9˜FS¼9ý÷á§ÁÍ2ZÐ"YE+*)‰gÑM÷TÐÓ ^Äü/¢k¬Îð;<ñê|Š×óÕM”`q5Å/ÿÀk½Ç’âLö³(¦y2sã›<ðOÎæ2Ž–4ù{´ˆfݯòÛÙroç«%þNðc$åƒÞ¬h–,ü¥«&ü“»´÷ŒK“x~^í?cu¶útµ÷ŒÕë)Ü=Ÿýa=˜ÜßP2¥uŽ\_/W´Î\Šñ&¾Ù‹º‘†â8¢§FUíèI”[ñ­¥ß¬4“w"Ý«J^­ÿLiœÌqzx›¦º­RU®M)¥+üM¢¢·w·t§ŒLqב±ñ§Øøx#z\
+U5øä·GzØU"UšÞ趖¢u^ý¿ê²Á_ÖTª’ÃtÂÝÎ}]ÒÃÝ·oÿð€·´“øM§áO%vÒ5¹ñÎÀn\Û"¹‚:îeÔå@z§9ø^5ÀÌÑ|¹ÚµÞƒˆà: 8’‚Ý´Äw"w(>‰_©\Ç |P:GqCù*J4˜°#Ð ÷ǸѺ°]‡„žÛþ‹Ù
+ÔÑŠìE {vèHǨ¬5:
+ë…‹Y•ªÙÎÑîf„7PBÕ–[¨³+›¥ÍÐiñÙÛf¯[‹PíæÊA沯sbÒršá Bë綶T¶X
+F[4ÌEH´2ô˜*ȃ!…EYæ•RŠÊÑVÏý`~ܵͶûf8ÃiíÐ\ÒSu†ˆ Ì–™+y/­Ü/·ÝЗ0­ÀÙƒã]o×8fÀ˜Xê
+äå†Ý®y``E™mQ|
+Ò5+ÅÈþgàl†n°V§
+ÄÈ4 C(…/èÕÓ5·›¼„}2¥
+ÕÏÊã´_SPGðçé#›s:ê6Ìß“ûUW'81[xòÿ·Ÿçô_>ÉçËy´¼^ù¯ëÇýãzðëàoÅ_c—endstream
+endobj
+826 0 obj<</Type/Page/Parent 689 0 R/Contents 827 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 438 0 R>>endobj
+827 0 obj<</Filter/FlateDecode/Length 1971 >>stream
+xX]sÛ¶}÷¯ØÉd®•™’(Y’ût+NÝk»®%OÚ¿@$$!& –
+ÝZ[:pa/VçqZ%ê'–൧&”)™[2KÄÏ•Z}å WV•$ãØT¹ƒtä!ó!¡ei2NÁg'fc)꽓Ø鯊¦M€ §¿ªÒǯs×hĘÑH>GÃQž&~q—‡#«8«lTG¹¸ÿD·£±è]î]æÀZ›<!íTF1üY ©p8Òv .¶5Ü|îg38ÐÃäŽ2“T©²‚n?=ÜÜ´€ŠR`O•êE)UÛh1 'u >’“é-ÍÌÒmVÏ­µsÅOÎf³…LR‹:Ïïýl6
+ªÞû4'
+"R¯N,õª*žxxc¨ñ‹\A;‹_¨-ûÌH±±)çü2uT/©¼sI¶Á3ú½žè š Âx•™Ï²=F2E\Ç\-5|e–,(6‰bœF‚Ém--ÌQ9%p+…-‰¯SÖák(t¶ó×Bå^³\@•ß§Uzâò.Ö¡vPd*¨µkS¥È)rÌd‚‚Ù˜ò%pýr6–…:·ø žh¢Ùôû,œèM*/(}ñ!… Wkh)CÊjÚ
+°BÜ,LfBÀæµ,ý¹¥~t³<Ñ¿5•Ï/r•3ºÞS‘* 98l+¨‡R1P†@ƒù
+ébèáÇÓB¶ëÿõw€šÙ¢/°n»öC| €È̤?ù¨ROv­ ÖÂÉ|¼¾¢¨ß8­~vù ôÌت,5uÁZÉU ª•åöÚ¸°oÇXÒ‚dôZß_ZêU¢º•í0ž:ÁÏ âØ„–÷ò '<·îcrõ´†=T¼2hA/5À‹&…Ħª×B•Ú·“Yð$Ž i§‘‚­Ï$ª"âBGöO²ë-­ƒEfñ=,NÑý–¬@»9q[ò¼Þ¹îÒ%W.ª¶¡/Ä¿QŒ‡çž[Xï‹ž@|F=´óP—÷“»t~¨òœfOÈ`A“§ßon'4öa*`ÑÄÿ¦gWt’VÛzþ½}wO³9hŽ*Ð[*q}~÷Ý}“?ˆ÷Å9¶¥Ùw{ì¾¥ÜÜ›äVZ7SŽ·™•Éçˆ7½ýžHo'ù]ËeØF/:~1»;H»’ùÕZæ+È ÜÞUÖíîÑÜu*Wö‡òmѯ¶÷L>oyRùÙøoküš–Ü&ñ4.u?0Ó@MiÂáî†'*C·Á)nПAb6Œ*° ‚t†ºøTšª¸™âAb2´D8Äx?kµ|Œ<Nj²fÝŒ º^~P!~ìÚsx˜˜¸¿)Ãÿ „{Ž½™‚c¹™ ÷?tX.™Æíz
+›+ÉC¨
+ÅVÅk†zªV›çNô‹TT‹Ð­™‰YЕe@<¡þê: g°ä˜ñi:{¢¸&M[-2f¸}Y° Ì’BÙ ’¬E6óÕlG¦Ô+ÉRynÆܺ—i9v|ôp6»ùp‡ÍT ÿ,·øÆcïúwSUÓë¾ítõCñê!^ÿ‰šÓ k-sßßC(œÏšÉ=åí’FY• LTæÏEåGoºáÉÏØ° †„£g2›*
+l3 ×,ÃâŃçŸP+\Ûµ²¹-¤Š½bLqU#ã!ô»J<˜{ÃJ33·çÊ-€dNƒQÛÃ]ô¸wx‹€m˜´Símº¿ùÝð½¹_Ð$
+0íǾƒ.™› R|júaÏØóOë¨ñØâšñØljg“¯,^ƒ¸Ð¦BŸGS ŽD€å¾Äî}OÐaoÞá,ÔÀšvšX4%V‚Óó»:7RYÖàô[²oÅ'ÁÇK ¸±cæᑇ)hÀИ\¯òÀŠ”Ô/U4›?>]ÍŸ'·GÎ!U¬äMÝ~;×㚦{Cü `ܧáèRà­œòlr÷aB¥áQ¦‡¯ƒlh»9Òu1,$­¿›í£ ñW
+endobj
+828 0 obj<</Type/Page/Parent 689 0 R/Contents 829 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+829 0 obj<</Filter/FlateDecode/Length 1418 >>stream
+xWÛnã6}ÏW °q
+i*­¶Ê~s½Ã­6±L(ÚûXþ(dîã+Í‹4Aí`<¦ìà®MsN#H <DšR‰Í$âX—¹#ÅV3á”ÎiÝûúpÿRHèId‘X_aÙûJ”AxÚìû¤ð ’±´V O˜†AÞÕÉβ‰›Ú Û,´U¯ÍV€n
+m¡t*Ù´¥^)›%pðp¨ Z}Ú(ĺðåÜÑO`ã­Ì
+#—2®ê¶Ö~ÚUG ûÿ ÷=ÖÂT·OÀ颳 “ dÈS8&µ¡½.1 ñ]tŸºé±8ïnÇ“Ñ\¡­cL¨ì
+̈²ïá) 4ôwa 6 ÿ8*ØÝÛ¾å=lY÷êÁˆäýé„„•Ž;?@ýj4œ`>ÝÉ4ÅèQ4¢wÊîë¼Á`Hc¶#xj—ØáÈÂ8ÝÙ åëɬJ$Ô›Z…ÔH¥ˆ¢¿12€ÃÔtÖ"šî±n©0Òöf›’A”³ÉѬQ cgÍb­eö`±h[öÜ-kÉ ´Dž—yŽ8™Z[œÁkÑ£¿â)«367|q˜Ã»e}B‡óY0Ÿ…4_Ì‚éµ2žn~ÿxC_Œæ¯ôIÇ%åa,„s|GZNh°ðz’ù¯¹gº˜‹9¾LñóñËêâÏ‹
+endobj
+830 0 obj<</Type/Page/Parent 689 0 R/Contents 831 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 453 0 R>>endobj
+831 0 obj<</Filter/FlateDecode/Length 1333 >>stream
+x¥W]s›F}ׯ¸cM+yÆ
+Vpw–5vžÆÓÙ™ÃÙ®•…žÀ±VÔ²ÆÎ íeogg»Vú¶K~/»8æ´
+5Î^Öøt|Ûï}šÃÙg+ ¶G~/kìæ.ër0‡³]+[®P¿—;/Ô[»æÐÛu²¥xg™ãèúzk’w–4'myî¶ùÖ¶.ºŽ/|Ý‚¡>v-_þ³ã¯6£ÙýœV´Ù‘c{ —ÐÇBÚ$†4sÚÄÓñ8-þê4y¨óˆKÒ?üËõæÓhN–DÐïÕöÿO-.Œ›öã_½å\Gü#MŒb£6»_‘ãiÐVƒÚZ¸=P8Ž nØô‹(vé¾–i±§G–GL£Ý{ä8ڸݥF½9`JD–‰£Ö,™d9¯¸TÄPKö•¥‹2NiA*ì^IÙ‰Žiu Æ§ÛúœZ–~je +ËŸœÒ‘)¸‰³:á‰1ïê·
+hKªÁAÞÝ­?P’JWBž(u–+ASM®OFßr};Ä
+
+Ìùÿ†bi;ˆÝnr^TLVTe
+l‰(&¶yl¯¿^e@ÞÛƒ¾½bu]ô’jÙÒÖQ)IÕT/ÀÕ§sÆß —!ˆâê;(MÔ[Z„«a€—m4‘ŸÍµÂ¾Œ¦²—c=«i©¹Ò4å~”a{^pÉ2¼[˜Ò0©YO =P¸éônŸ‡
+endobj
+832 0 obj<</Type/Page/Parent 689 0 R/Contents 833 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 460 0 R>>endobj
+833 0 obj<</Filter/FlateDecode/Length 1819 >>stream
+x•WkoÛ6ýž_qÑ/sX~Ûi€~ÈÝ:´i6h‰Ž˜J¢FRqýïw.Ž¢†À±õ ïëœs/ÿ¾˜Ñ3ÚÌi±¦¼¾˜fSÜ9ÿûýç‹Ù|š-hµ^dkªi>ŸeËxUÑöb±Î¦´ZMq³¦Ùb™­â?Ä>´š-³9-¯6ø=ÇÇH:ø‹ù"»zíÁlýΛÂ׆ÂoÖ»„¥é‹Ÿ~¿»˜|xG³%íh}……cJ»|4›e«l‘ÑǺÕÆ©æÞî±bWŒl½o…µÇ"ÜO;H6Î(iÃí%ÍfÁÀx¾QØä7eý®•&-¡ƒÑ5‰&šB–ýÚ¡©´çˆr¼»—{OJTÕ‰
+ÝHê,»+èNšŠlnT먵Œž¦m§4ž-h8¥|CÊÚê¥û#RM^u…,ðƒ\)‡.Êo¢n+i'Ÿ~¼¹› ÊÈÜis"}ð«·¢Þ ²º3¹¤©0jß9¥›Œ—ö<Û•åø¸£¦ZÀº‘wدFžmØOÙæ5¯*Çó5Ð…Ànª
+éÆ’Óœ©(¢À%GñìXÝYG¥x‚1z•*¨ÃG‡`+ ¤òd¬3Ú•0S/þ¶Fï+Y“:œËP‹¼T|„±ÃÑ4.Ô™íÇ<HóÀ§àŸwí *é³1ùG Œ7Ùð‹v?_ob"üósðÈõ=§~ŒGm¾2LTc #8ù©:·Ò]_s!©eÕºè*IÇRåeŒ{µÞ;Tiõ
+úÙ讵
+ ªx #φ„ —!vv:rôsàb}Ím¿“Ïd·n?2u+õ••©žöÉè}”`Ö%)÷’ã1ÕŽCÆ—…8±*”ÚÊç XëD¶ÎHÉáEž¬ª¶¹¼îç^ rõFwïC/‹ü}[,ZòopâÍÙz•æ¢ó’;©¡©ÿ½Ä‡œÑ¯ÈÁÀh®›ƒzè
+0\ºu¶ãæ,µ›H—O˜‚oAiŸPg–¥û·I¦S ?6QÊŒ |™gólqéñæƒê¡7ê(AD÷ –ÙV[õ-†¶–œW
+·®Å×a^; F$Õò{ø,÷QÑp¯ÑGï ’³¦ÛÝØ#&8”½ïãýè¡Ò{ N ò$5”*f¢?Hô™¼Éh+óÎ(wò¹ï3‚w}Ö·3‰!Úp25¼ÐZF«ë°Ê­¯ÞCŽ¥l€N›wÖw|Ï’d0í[;¡ÆƒÎm0êÒ:6œ~+½e&½tz_xÖAÓdÛU}Ç‘6()RîÎWgîsgí@0Íí³K×È&7§ÖžP`ŸMSÀ°ïa,+F=ÅNN†¦—ºâ«nÞúˆ²7c¯ZÏ#Á“’Çÿçû«ýdèZêZ©™$š ¸è%~lä,•Ââ†/vÚ ¿ÈoŽx¼AžüxÈ“ˆîÇ@"§áBÖY
+m]·¬çã_¾ü±û2þAWÚPª|¯9ìÞ‹“¯ÒAH½MWÖv2ˆÌÖ+²¶zC˜bƒpµÂ@ŸÙd!¢«}üøÈð{_ÄÝÀùûQÀû* âɽÇdž¥RîßƉ© ‚µÆqÀk0ÉÓbê" %êÍ ¨"H‘ÑLê8Á7ô¥• càŸŠÂnm,i?«0y²@
+endobj
+834 0 obj<</Type/Page/Parent 689 0 R/Contents 835 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 463 0 R>>endobj
+835 0 obj<</Filter/FlateDecode/Length 1704 >>stream
+xÅX[OÛH~çWч +âÆ $¡)” ([Ri³{’lO:3†æßïwfì8„Ð¥± AbÏå;ß¹ùëVH-ü†ÔkS§KQ¶Õ
+ú}ªÿè)¾´¨¶ƒíõ{ø¼× BÒ’&8ÛÂÓË?ÕÙV'è•gÛ8¿éè§÷ü0…áA°O…­=<â¿¥tµõv¸õúdh8yÝ~†±ÓÔ¢aÔÎ$©<æ…Nì‚æZF¢°‰Ê)1d_¸“¹¥\åMgIž«…Mî$FjC­2š }'Mò)Í…1÷JǸffÒßßÞlµ¨v‚6,hX(Žh²J/Π*9qYå,˜ñ©‰JSuÏßGg”äÄ’^Ÿ°ËìSäbpaâoTÎ6ÞTø\ìuÚÔlï}ü‡¯^‘`ÉNÉv‹99ç(ηID‘4f—Æ…¥Xæ zÁ†ÉÔÈÊ—%ùÃŒ”°V›Ã4»,ØÍmõqíâŸñÊ·£üðJdcAwW‡s©æ©Ü£Ãy*’üF¹ÏJO·é1Z7 ö'‡ÈÝ|}r@áûÝ,ï´
+`m’ñ—²BêF’ƒ^‹îg2wñò–IûdtI ­~
+Æ•rRSŠî%Ê$Hhaýµø!±íI*¦k)€ðyt™C`î’bp½ÐIƒ}Hnóµ0f ÞJkèïjrAƒ|Î0šT:V<2E4c¦Qƒ«ìhg—¾Œ(«·Æ3˜¯\9
+tUoå·y•Yå|“¡<5âĈq*ãÑί¡‘ª©Ê‡ˆõ#2œ–D¸i! mD#ËÒ9,ýñ‡)„æ7žÌŸ*ÁXãdò¢*o“èö¥u"ÍŽD~4ùôå°…ÒóÂØÖ:S™<Ö˜qȵ¢I‚äF>C©´\¸ÑXïg Ò2´i>ðùâ´·3ßÂðœK8'~9U°Ž•Œâ’¯ÊÍà?•ê˜‹ G Ìhûú ºíŒ«Éµ„p£4¨ìh^˜7* Orâle­Íµ,pÛåŽ×¾ »µÈ${Vê3ÙØ 0£Æþh.æ82ufP†N†cl‘Ëë)\õÌ'ªst9ãL¤“9F;{„?£SßÆ̧æRc¬Àñqq—îsUúÃwÍ?ºKÁÑù1þ¾»~·KJ¯E x;Ò$I%|PçZl5öåEšúëN &-S?ebF1—¶T†žâîf ±·c{Mñÿ‡8pd‡7B^C+<—K?K`ËGËḬ­~DÄh•
+ÑI9ÂÔ›¥«8Õøûx¯¨˜…긬aX,r› Qi tŸNŸ˜ÆžgÒ\cGÑ‹÷˜5ç§Ç0aýßQ\¨”BSS]tá%~d«Ðh¶ûAxP/nœž™¸Qî]‚oFÖ=;:šÊy<äíÐm~ýENaSsƒ1on—ÇGl”À K0`Óe‹eø×xì$4ñHóÃÇ/Ã.ÁciE‚åËÞŒ÷|…4Ÿ$ÓxnC¼ô`Ò±Ws¤r«ñÎGîM¥¡~1Qjêr™­+÷·ûó Çbu&Ð@/(ñK±#«‡„ß®Är"ŠÔ’¿ì¶ãÕsB]Ÿ¿VuÝà$Âe¸\÷³Ÿ1ÃUïz
+ü¾ˆ~¹{‡~Ð?èP·Û ºÝ}g®çot©¿x@ü¢"«Ö{ö¯âh«ß¡f¯…w@?÷æc¯‡j]¼ÈcÝ>Ë}7Üúkë_Bø|endstream
+endobj
+836 0 obj<</Type/Page/Parent 689 0 R/Contents 837 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+837 0 obj<</Filter/FlateDecode/Length 1182 >>stream
+x¥VÛnã6}÷W ð±,ê.yð5 즋¶hú@K´ÌD&]‰ZÇ-úïŠVì(Ù]okò-’3gÎ9CêÏßBÜ
+Kˆ"8\Š ÿØà†±ï§ß³H3Ù†ø0âx¶å¿Œ`FËÞ_öabb¹í„£y§?ó€˜/c…0Oë¥6Ì“î|ÅJT©‚/*ÅJ SŠ|¥’KaËÕ
+ÔŠAI× :LY L¨b|Y|¦yµ_)¤è¥lI«\¹mÁLæzĵÌÞeÏt½ÉÙ9в¬Ö æÃû«ùôò¬h BnaÁ˜€DŠ%Ï* oS¸›ŒŠSR¥ögþ¾¬.ä2“Vƒ]À¾~¸ÁOe¦5ÕwaKËËfà¸*Á,@)kººåzaií8Kž3 ~Y!J
+UÉ
+tQÎ,yÚ8%(Yó“Ê5åâ¼þm"9M‚îvŠð6`ö¼A0×…6Ü=<Ô¹-¸6¢ ô+MÇ‹´Àžy‰%b¥ZÎZAôH—³Š§u˜sY]l˜Ô"¥ÉE-½þ!‹ìL×ÁK£.ÂÓå§\É-ûÌŠsã ¼}È›J4‡h  ¦A´k@µ]@ô'Ó´¡2¯P=”FÉMNÔè^»MœçÆÕÛ‚+Vp
+•¯(|߉mÇvÉh:™Æ˜}8qGžë|âÙÞtÚZŠ(nh©î™ÂÈ6¾Ã˜8^kRÝès¾F˜vkÈ°<®Y~#®îÎ=QÈï
+endobj
+838 0 obj<</Type/Page/Parent 689 0 R/Contents 839 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 466 0 R>>endobj
+839 0 obj<</Filter/FlateDecode/Length 286 >>stream
+xmËNÃ0E÷þŠ»„EŒ§vº£å¹A-Ôk“¸%•Ó€ã
+ñ÷ŒÛÀ
+Yùqùd‚–„)¡4šž .èå/¼<°R n gš ôPbÎëé°Ézh¥(Vµ¡XÒŽ[¶´ìê~YÁn ¡k:´§Ì¶¹’KÁq3ô½?¤ñÒîI^Aʳ¼( É/ÖÁ»Ñ£w]€ Í$'ÄÎŶ;ìÞ»«W»B°÷1~_®s|ˆ;›¿Û¡9ž0ør#‚Ž­K¾%OF Rñ2#£ßß$Êë±Éy¨¥’ψxª…Ÿ+­§J¥¦¦kE9»7‹§åë8ìsŽÛ‰ëR7²±øÕFÌ3íŸ1T¦âF×43ú7"Ûî,{f?sendstream
+endobj
+840 0 obj<</Type/Page/Parent 689 0 R/Contents 841 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+841 0 obj<</Filter/FlateDecode/Length 1614 >>stream
+x¥WMoÛF½ûW rrP[±dG²{K‚0Ð8n­ =ä²"—âÖä.Ã%Å(¿¾ïí’M-ÚÂ_0¹;oÞ¼}=™Ë¾æ²ZÈåR’òäbv!¯ç7ø}u½Âï~j-Yx±¸¸™]O_¼]Ÿ¼z#‹ Yg°µ\]Ë:عÀ“äô]®ªF×2_Ìä“5™Ñ©üê¶ÎzÙè¦ÓÚÊgcS×y¹[¿\ÿyr!ç‹+˜8U6•Ow·HëÝòÔy„þæ8Cç—óÙ‚Çá`>“7ßÔ*iâ±+™Ïûc‹ÝÚFokÕgÅeÑ<ý|0Ií¼ËšQ0Òäµk·¹(iûÀ .¹bì<A&Õ5RRò"wÅ^`Ü/ú<æ—14ƒ; ¸­¶Úµ˪m˜•¶;S;[jÛxÉ\ C…ÃóÆ”z&ŸµTµöxóYöùœJ7FcHóô ×iÛY\a‚M®åA•5‰È·¦Ñ<P!¨Z•^“ï
+„…®>Íg7….VtŽÂhÞ
+E2e…wp;€;ñxDø÷ûw’¨¢ðgr_´Û­‚QyÓ"TÛ˜$^ÿàÒ¶Ð8Áâ0‰;U"]ïL‚¿i’œAÂŒëF5›8M]©
+: ÓÄÝuz§kPÍŸ¦, Ý€ :HZì¶!A¯™mhC?Ñ?°¤nLê”䃆–Búk•òüOqokýµ5”Û€¬v¹$ÊJ¡n²¸6n[ó=²¬­'yO<øtdŒ8{é!·²PéÔ°™C5¨™árðsÀE¡ÈÖZ‹/ÑÖèš!ÖŸ æñ‘›¦×’wëC£aæLZ‹×_½Oúaq¾š]sÎcü}Y,Wß’^Ôk,èëÄ›ÿï†ïû:J’+»%gçÿ±¾¸žÍoŽݦšâÈ}ªÖÊm=å=âÒ¹¶H{-Øsª„Rªƒ…Ã@õü&wmÆ#ÉOÛª89Ö8ÐæÐá‡Ê“ã½¥(¡…ÐIq@H£<ôžøðn$#‘¹Ti‰ÙÂUº….À2ÂI7°$¶ ýn¹Ñˆ‹æ¨£‡ Ö?”ƒ#ÝåýŒ£É·Šr2Ú"\$ò*
+endobj
+842 0 obj<</Type/Page/Parent 689 0 R/Contents 843 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+843 0 obj<</Filter/FlateDecode/Length 1655 >>stream
+x…WMsÓH½çWtq2U‰c;!GC–Z Yb
+¹´¤±4Dš3’µæ×ïëÉv”°@ÖLw¿~ïuûçÑœfø5§Ë]PZͦ3zw6ÇÏó«Kü\àS´œ]ͦ‹×>X\\¿~âz>½x¿::ýxNó9­Ö~quI«Œx6£U:ùê•ód 5…¢¯wŸ¾SÅi¡¢”ÃCC­Wt·’¿±É(w¶­Ép¥<±—ƒ[êl[fáÍ7†½Qoâeá­éÛÕ£ÌÏPÏ*›¬ä„\Ÿ¶3´Ö%nò7q¯c€€TFÉVbg¶b2‘d©2TÚÏ97J]²t­…å˜Ò÷“oÚd¶#¯¼×¨5ða„!ÝÅÅô¼O
+ßSo²ÙN“2/#®ë²OÑÇ¦\s¢KÝlÁòrƒðÂXÄñŠìY˜´pÖè_žš½ï¬Ë„MM§Àô˜%4¢£ôùà‘Šo,z 0^ô'r`RÚÂÇI/õÍ~|úsúñšæ ½xÅ œ)(`¾˜žMç¨]®ú
+åH‰‡¾r²_™H¡ / > $›3ª m”êñ¨à J1¤þÕ¾‘²qÂ"œAfí؃ViÓ¢ÆÐéžjðÄö  ºØ"=q1
+Å™ð'f*Ñ_Öp Žè–ùB‘Æ èšw*¶¥ã­+"ß)ô«†…ì`D¹‰Ú^°Ò’u,uèü:惩0Hì‡ÐÃLXŠˆÂ'‘ƒe8—©²
+m„€C–nuꬷë¦çZ¤1Z‹¬‚àEéA¾#X‡@^qg–¢rJAö"Õ]Ú‘…ò(’ô%s>¥¿1fI|“Ü$ø+²YáÆ®Ÿ"½%Á@á‚:—!Ș¸0Z¦´Ô
+-A,eBzƒôC³×¤·é  c7bÉTpêg ª„Ž°s ¦ZµûD,*WF‰ÂD
+z©b:U†ÛZZ ýì'D€•Ë‹É÷û¥--ÛLxä"–ÎC»Ž¥ƒØ8žr!Ä(bo
+µµ%îJñâ¼ÀÝ`¨P¨Ëíµ”•e3\ƒ`Ꭰ;½ß;]ÉNuWλmhÄàµnMب8Ìw*4ëX²Bì°Äb»ÕªÌ@7¦ÄfØ#×:=UáÁBàhÁuëj‹9;¦úà&ÀÇ­§Ð;lÔ  §L[± £TÀŒz
++dü'^´ISQAH 
+PŒªåDFœ,¾XÎZ˜{¼éƧôpºg™&Oô–²Ï­±£ iÁ&ÃÅíž)½ßRÜcÑ]x‚Û
+…X|6P m Æ$‰ßW0x‡ÚŽwnPq=ö¼àM«Ãy=×
+endobj
+844 0 obj<</Type/Page/Parent 689 0 R/Contents 845 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+845 0 obj<</Filter/FlateDecode/Length 1829 >>stream
+x•XMoÛF½ûW |r›¶lWrrsœÈÁ®[)hoÅŠ\JŒ—\fwiUùõ}3»”(ÊAPFdjw>ß¼yô·“ ]áß„f×t3¥¼>¹Ê®èzz“ÝÒíÝŒ?ãÇi*O>,N.?½£É--J\™ÞáCA8~uE‹ülrÝf×=©ZÓ\»×*Çÿ›*äë__qõ–&“xõâz†«g‹µ~ëô9YGOóù9Už•Z…„µ
+ü¤uÚëªU³¥/OŸÿ&Ûj§BÕ¬Èo}еÏès eŒÝxö~E“›ìš½Æ¸^ZWãŽmÈwùš”§µõ¡Aøþ¦+ƒû•òA4u^»ƒKÁÒR£2ÞšW]PélMEU–Ú!º±OÛ¹\#¨OHMÿ«êÖèsäæL+cÓØX÷‚gT­¶½õ”Ô{ñ ÚUˆÐ–T5v[Vßù`Dž76W†ä©TF÷ÔèÀžqh@Y9:”´ „”S¾oD4JYâ8Cº¨""h(·ï ÌÒÓç9*¨%ÊLèÇq•ñLÑǧ9'úŠð¡¾M#ƒŽfé«ë)`Ü#m>'Õ¶¦Êc}[gWNÕ5ƒ¦j‚v¥`#dhS5ËŠãµ{¼¯MÉ0AÕ¥Ÿ\õˆ¦GBÎ8V= ZK‚3©ÉÊÙ®6þJ>ñ­G¡
+®-ýs41¬m·ZsH[Ú`fÓ`pkÆŒÁS“ÞÀUëªZ²¶Mp6Ž–ÀÆ|ÅW.?b…üÎ.uÈ/ï…3ŒBôìx 0dRM†ˆ­Õ “Ðô­ÓË`G%*,¾5Ö¾t­Ôúú–ðCÆÓÿŽF2QîËf]'Á™ùZª\LóaÛj°áqÓR¨º8C‰ú$¸ÓV¡
+Åé¡ -
+T±õ1˜=>Ì‘ ü§5„}Ð59¯K´¸gÆ×ÅðÑ`mqj “ýÞ0t÷OxZwûœŸï*~äccÀ»Œ]á·Á¸öŒÙ÷Q*œ°[6‰y¦±Û¶¤•aïó–ë×,¯1½¼ ¢±ÖÁÈÖ3û(^
+ÌŽmý&À$†Ì°‚½lFÙñy¤iÔPÙ^ÜL¢lI{“ѳéV+µÄ€Ýwl>ôâQÆNöÅ~˜xvEßþ춺ñ–^»AÕ<=ß?&Í›4*Ã@-}p
+ÇúV‡Þ‘ǨJ|Àºê{T8AçëÆ»²¼¹ì¤g‹*êië}ŹB—åv¯cÇ.k €"¹ÞIß^F!§îÖê•+§s[·¨  þð8*Ž(V©zVvà»#—;:—ÚP«Ó娵yqŒJr,ÀE²Zn U~ˆìf”'‹W‹¨¹¬ 
+…awažK vT׬F¡˜ƒE_½ØŒ…¦Jú%"9íi©§ªÓxaŸ>Ä ërìr ¯é´¿¦àE®Â˺óœDÙǨ¢63¼Á·è˜å©`,_«f%P¬€&hKÇñ„À|ŒEGºQF¯}yÀØ
+endobj
+846 0 obj<</Type/Page/Parent 689 0 R/Contents 847 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 469 0 R>>endobj
+847 0 obj<</Filter/FlateDecode/Length 1838 >>stream
+x•WÛrÛ6}÷Wì››².‘ä§Ö‰›Ämsi¬Œûà™D€"l`
+Lqj¹Š†^À)/btn[›lÖ2½i
+2 €Ì’*`«} ^ƒã­f¸-»ƒP ±^Q®
+€;±–kê>þAÛ(ãAš¶¹Ú,»îa†ƒ`YmÅî?DäuB_CRôV¤9rapûC£•s„š†V÷;dWRŠÄ6Ê(Q@… Pî™E†{±°ö®©Ðc+
+a{µëKnuT ¾C¨äÓ\Á* ƒ‰Í^AÓ½úÞ(?Q<È7Z’Ö;V4iKñ¬]Ú9P |­®>ª£ý˨ØNÕ3pS‚¾\¼ }xâGEa1=·ºÎqj΀¾¢ðŒË£YΆ£€/³;m Ö<D¢ÏÅ·Å}"LÔŽÄœê^JÌc 5Æ$…²0¾° ê¬Çê¡Ò(Ýq@xGäpТ×å ˆ0ð›Új‡sbƒ°”°
+ ÊÕJa?ŠØ g=ŠIÜCyÒ<Äh0td-µOv D-ÄüD+ñXÀ’
+)7ö^̸Pìlôîå1þºDž¢Èöô¶á“x¹[nöcú#W둹 sçw›Z9´Š*è ÿò«7¢âe [€ " 1½×auc´¬Óm0¨ÿÔ¦yà%Íó
+æ@×O{—qG`ùC /tg‹ÖsŽÅ?!.@ŽVàñómêu2æBXè/¹?(KØ•#P±ï0ÄdPiäVÒ>d¤²€îÊØ’Ø壦b}ˆ;ï
+zÇ"ݼ:–JÁÒˆe¬òÉíʬ„¹H!캶T[~ áL†`$GºÿÄ1ÏÅŽ¯óöM„Wæ~¹ÎwäsÛ`…¸dÛ5^p¿<eìÉ?† =‡ûDÈRN^`?d+h”]7E{MË…*U
+)Ò¾ÄêÇì§Õ(dP?V}¦ »Ø
+Xû]x9rH`¯02ÐÊ1Á´Åãd‘,Ç4=ïš›É|Ѿ—í1^É˳)å˸ÀÅ´¿8{ ^ÐEÿ!ƦOÆs<¡—S:YœžýŸGÖl1Kó%Ød1c[¿­þ:ø£%9Ãendstream
+endobj
+848 0 obj<</Type/Page/Parent 689 0 R/Contents 849 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 474 0 R>>endobj
+849 0 obj<</Filter/FlateDecode/Length 2021 >>stream
+x•X]sÛº}÷¯ØN®2#Ñ¢¾ótëä&½žÔ±›¨ã‡ºÓHHBLº
+cZg‘e¦Ö•#£©ÚKú~uóኜ´OÒ&ïÖ?..?/¢õ˜F騮óÁýÞÛ›ºÈi#áZäJï`¯å&«K©«_ƒqãzëÉ
+½§0m×*IßÓh5  §“džLú&ÿ¨•õ¸— 3Æ\ÞAÄk/ž$ q¢Üʌު]T
+lj’¤Wþ}¸úø…®×ô¯»¿¼ô;ˆ:ׯ`NœzNGwW7Ã`Ýðj@‘=R}`X#“ÒàRVÙåA”IÞ7z
+³‘ù+ÏÓRd{¥eBkøGÇ}¿ÜMG¡+6A‹xÏÈWmñò2¾Ÿ£…Cn * c€Ö²ÒR<Ì!Ç^o^U¯QƒÑØ—‡;ËõF…ÊXÂÖ
+%ôÁ!4†ËXµSZä*î_üèDGÉ¡IÅØÉ
+ý[{%Ä´HÅ ç‘Žó¢²3ÌxŽ§Sž5\l•uU”+ ¨†Ç[鬨}kUº£Ò¥óœr!Kt×Q8ŒþCwÁÈÊ-@‹—zň.]=Ê H°ãÔ†¨KUÁæ$«a
+£4²¬3în¯æ¹9êÂ4Ê,ÉAÁ2 ~å ˆ¤¼xtPßI-­(@.‘?)¸®ÙT,Ã]
+s¤ßŒ‡!h,ß/6ªPê‚Y†Þh†Ñº:k¬ZnHðz”EÁÿ ÷±òaÜ@0»Ì{ЬyR9’ÚœšA±c« Y—@ÊCQïv¾¤¢Æm¸9 z º×ð –`÷Œ“$ ×$7$ªÎ½×óÚvâµFMó@Ì”‡ ¿ŒôÌávâû}¥ƒ‹ ÞèP@ÃÁjc…U‰=ô·y@z>EoÇâPMè3Xä¾Éüwh·‰/“çaK#¡3ùðŽÇΔR€PÌ.€ÌeÝ
+îR6 ˆ5 ð'ã°ÝLúáxIGLCôfNܳê5ÃO0$é¥;˾ÕÁ!¾Â21‰ÏÎ*… "È—1vŠpY;{‰u>hùçí^ üÑRèþQHW,Æ Þ“8=|lXc=N­àTÀ6òåP`õÁ@ØÔªðÐ‰ï €qÏ#-gúÑ…Tó°d0ýÎN5m2 Ñˆ·„®êÛ›ƒ_»æ“÷i#³êP±nŠ1¶íÄýVtµûœä©„K›±À`„
+¦R@®?Gÿ}í—TÒ† ö"²ï»)0#Ú(Âv㟠á}õzx6~Q…iÒ¾¶µ9z±éä·¯@˜ÜƒÇAiT· S’)uz¬A˜7°?hù\¡k±Zðb,¾ þCZ{ú›«$ÆîþЇ`ûU1à9äŸQ°Ó„>¶%`ÇãXm«ó4bëöñy.Ý9è€}ø‘Gt¼8ªÝ¾BŠ˜"a™¹ü<¦÷ü@Ã
+endobj
+850 0 obj<</Type/Page/Parent 689 0 R/Contents 851 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 491 0 R>>endobj
+851 0 obj<</Filter/FlateDecode/Length 1661 >>stream
+x•WmoÛ6þž_q@PÔEcÉ’_SlÒ·­Ãú²ÅÃ>,Ã@K´ÅV=QŠë¿çHQ–¤ÙÄ1ÅãÝñî¹çNÿœE4ÂoDó˜Æ3JŠ³Q0¢ÙlŒÏÉbŽÏ•¤56 :|T,F4^Œƒi+:žc/;‚ÚÀxÙù$¸¼«ÖKYùß~<‹ÇèG³`NÅ—Q0iW9]?àFY7.Ùƒh>ÅIës¼ÀÙxÂO ŠâQ·+Öä6ã±5ƒ».(¶‹ÃÞ("t{vÑíEÓîÂJ§ÁŒÜê°9Y؃Ñ8Bˆ"»:lÆ3D '£ LFvuØŒØwlŽ&|Ò®xóKû­ (KÝ èËåYøv‚³´\#µ³Åœ–©Mƈ–É`™)C;•ç´ÚS*×¢Éë R¥©ESWï_^aEÏ–Ÿ¡‡}`=ƒ°1U˜ëDä¡ÅJ¸mofе”Tg’
+ÃNKª“¦e-j¥KRkÚë†ÏhˆtÅpk°eMµ>1ot!w™D
+end@ïjë1‰ÜhZ5*O­©*WªLS’_eÒÔb•KeJ®¯)W«JTûÀùyÙ…ch³ËQ
+5¢[b,Ièp]ŸpiõüÖKŸ7é¼ãZfÒ 5ÁE€>©Ô
+°†—…¶Oj¡r^²ÓmrÒ›Áâ戬Ä7è€ï÷§˜}È'ƒv¶¡žk µn›‚*“¼IO)ÒC¹õäÏM®W"ÿ‹ ˜
+¶ÈTÀ[=2~íÀó¦½Ã„t ÍWi¡Jej
+endobj
+852 0 obj<</Type/Page/Parent 689 0 R/Contents 853 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+853 0 obj<</Filter/FlateDecode/Length 1203 >>stream
+xVmoÛ6þž_qëÄCmYò{ Cê$m´ÉÃ>Òm3•D¤âØßs”äZŽ—‰ßDòî¹»çžãßg…ø‹h: á„âì, Bš 'Á„F³)¾ð2’VX˜ÍèÛ›Yã–£‹ ª·N¦Á´ÙÒh ë…(
+ƒ‹jåÝ‚=Àçþ †ú·€Ñb(“Ù”‰_iwŒÖîÇŸOgýÛq½©CýÒš~ªc‘ö­È–¢¿TyßfËBX»M¨÷D×÷¯î>QÏÐÃõœzŸé*ÉT®¬3ÂiSÙíö“`·ÅFRat! àÚBçV’Óäð8ÖY&ò„ìF—iBKyIo~Ó*—‰_Nt&TN•åAƒ´‚Ñv×yCÛDN¿g/)K;]zÄ!õ¢a0`œux¹ÈdP™¹8fV ‚q0Ä‹0ŽÊÂ#ݪéJJ„ÌtN”“Ö‘r?´‘Âa“˜›g™»R¤é®Ëxh«Ò”¶"wœžL'jµó8 U ËîàÍÆF~‡(òã*–îHåÏú ‹¬aÿa"O¹ß¦±×P³–ôŠ¯>¾»ªÜtiY2tNT¡­UË´*G¤±ôTâË+ì2N!î•2ִЕ!¤çØ{•(²Ò<«XÚ.!€ÁÆV:M5À¯÷¼–˜«—U
+¿zŸÂ“L–_=\->üò¿_žâvÛæ`4 ¦áÍ&œ´Údµ:×ð¼×ÜCº;ÏH¤[±CV‰§Cª¸<(¬À§-ÁUŽ¹æ m¤¯£)ó)‚šƒßta©'$ýCk#‹=Ú`¸·ØÀåQû¡I“2–\áE®
+ë™|Ào¨‰k¾Ò¦"¢I>3RåqZ&H§°&.Â’°)ЗÙ(l»È]Pˆø‹XÃt¿rݯ= ¡µŽ¯D ÿå]+Úrá|³wÉ™—x-…Î$b÷(ƒYrç0àäGËåUsCK_ lâ4¡4+M½² ó
+XÝ"DùÕ—¨Kw>®V£2‚ƒ¤6ò¾ï× ž?Q0 zã`†O´×üæþí‹ÑÁf0 ›õei™¦ƒƒ•÷%TèÄó'×ɉç_ÌÒ­OXØ;–ž\ºÏ(ŸìßîÛº=õàú~ù¬tiY«ïh#ž%ñ H(ÛQ=¦Î×¹ou<«ÌígVÍ.Èk‹iÙa^Ÿ¿=?fÚ_˜
+±ÈáÁÍé`mC݆£fÛÚh̆Cº­ŒÎü!òêqÀ²ˆ|ɆL;/…§”³¿­¸®¢ «C=ªUÅëj€ûbû^<ªr½ÎùeÙWü•õ¹Î W¯š˜ëÜŒ—Ó›æ’ÇE¹D`$žòôod&ª Ï©õfRaè?ƒ}ïkô SïhÕ
+ÓŠ¯-Ý—¾FÓQ0àæÉ[§S¶p³8ûýì_Ï(€endstream
+endobj
+854 0 obj<</Type/Page/Parent 689 0 R/Contents 855 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
+855 0 obj<</Filter/FlateDecode/Length 1633 >>stream
+x•WkoÛ6ýž_q}¨Äò+~d@0¤íŠ XÐn50 Ë0Ðm³‘H”âúßï\R´%ÅI·¦q ‹ä}œsϽüçbDCüŒh>¦ÉŒÒâb˜ i:áóz1Çç¿VÒ/ :}Ø ðz8OFõÒÑ$™Çµ8s:Inξó™Óūdzd¶¼]²i8sü€…Á‡kh¹†³Åœ–™?¤eÚ[náU¥ÓRMo6²”º|C©Ð¤ÍžV’*'3* áUZ­såJGfM+Sn)7©ÈIèŒ>½Çë­óOkªKhiTnååòËÅúo zk“çf¯ô†RSØý=/|@ȵ«}„uÍK­1åwáí´~Ûcà*í„sû,¼<EyÜú‡©ÈmM•g>
+{u©Rá+—SŽZ”–P~O*•`Ø£”;¨‚È` UÈL€Iª÷©¤Ó2Ô8
+/
+Nú¶õp‰Ë\cÂðÛož&Öå.Ú¸ê@Èó ÀG,a ü‚Ç ë'ð
+¿°º£—µJB{á¤Í‚‚I-V\ù[‰N:
+!ë˜/Ä<´ªR+gºzã·TÙwr„ßÆ<ˆÞW…8³ÿ¡{aýYåKè7™ý„1€§G„íèøŠùƒ¢Mr¥­ÒÝí*
+<F=ËãÅ™PrØv¼òµ@º°ä(˧ŽÉÙ¨@?[E§ûª¨»ûYT¢Ùž]GÉõdŒaš,ð¯áº…´·7÷ãҹ߂¥¡²Ä~㨃ô-ï41??ëúSƒšÈ¹ñ=К1Šå‡+ŸN/õ"Ç°+1‚h[ñ$‘ÓL¡W¨”æôÇmœ%¦9Lrl܉œ[úÖÀR aâót•ö
+d¦[ã%FFYìrQúæ&0ki€ÓØ:ªÍw ûÁÞ 6S NåÇÝÀù¡æyÀ”œa/mr³‚u.—CÀïÔfŽr
+…î[fà•è¤Š’„îgëí-É^tj¹jxÄ—”pGát¼"g1k…VþSáV‘ù§VÇðRÏ8ï$è©ì[0j'o3©YÝryëËYðȃhÒÚ[H}
+Í‹ã&˥ذìªõZ¥Š©Iÿ¡É,ê~4›&³é÷ÓQr3óõýùîþí}²æ nGôÞ¤US}góýÑ 7ëÅ„úó!ò‘õê‹
+endobj
+856 0 obj<</Type/Page/Parent 689 0 R/Contents 857 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>>>endobj
+857 0 obj<</Filter/FlateDecode/Length 1478 >>stream
+xÍWKoÛF¾ûW \À¢DI¦¤=8I¨ 7VÑ
++r)mLî2»KËú÷ùfIZŒ,yjN$’³3ó=føñ$¦~cši’PZžŒ¢ùœöìF”Lã(¦óyÍè<‰d%å¸wDÓÅßMç3ü?ŽGýK“ñy4o/M<ß=„#£Qû§=`Ï¢q{[)N’hzìB2þýëåÉð݈´Ì)Ž¦“1%Hì<™Ó2 gŽh™žŠÚo¨ù±òc­¬Ì§a¡VC'ÓÚ*¿V¢¼s^¤÷‘3ä¤}P©üÝ휗å€#üºüp2¢Jæèßt#‹Â!êa„45µöœŠ«ó\¥J†OÏÓÚ*½R:ûbˆŸW™“Î)£9¯ :|7GœAƒÎ`< (¡Ë$nã×Üs:”>e¢lX˜µÒÍå.Ä)媔
+M+ü³z µ¶Ø‘G4'JI[±‹èÒ“6[*Œ¹wT¨{‰ëÊýÖףˀ) Ú| Léýî {ª}7¦_¢Öê‘ÉZ;y—+ëü]%œ;dÙ>Ü¢ù]ä×&@y¤SÿSös ·Æ²Cü¼~ý<Iõ@è5•‡bEÁš¥çþ‘íL![¾¤ÊK¤•9yF—$² "ƒºíœwR¥à©=Š??ôsÓÚz
+EjéH8è87ç¬jO¢
+bû'ÁèÙ†¯åMÉÊB¦2ÃÂÂÈ»•´1˜l‚ÀSà !k™Ý!ôd&!B³`tZX‚:¥¨*(
+>‘²ËÌÖÑõ’Þ_¾ ý}}ù/© ÜtX6<nÏ æbm°LnJ•ÂoveF™¬¤Æ} Lë£=ebРNä·Ý¨tCµæSQFºÅ#–ÖÖÔZ‚ýØI0wµ£Ž-¼æ”bÇÛP¦x¬ (Ê /igmõöKbãØ—ÑUK*oÆ«–Ñ^(ͶD«4dU6GÕ©±¶®<²Ež™tÞšÌZY¥Ýâ7‹æ1u}ýoœÌZSéŒ#\LQÂ4xÓ`Ûntm¥tsqE¥Éj䔌î·Xë”F ¢Ý$*ƒ½æGlæØäƒ1à;7_•ÏñGÒ*åÙW`}m?WÜj{eé`9Za7Ÿz>‰b<â ¦Ó¦FHbÑÞƼeŽ(‚9Ø5 ñŒ² è°Þˆ S“]îšmò¶qPºÝ*ŸnÎ覨×kÁý¸€v!p2´ä*tÒ1;òYSY%0
+®Tj3¹§÷7o°àêÄL “4p” „¨ï¤( ¼90&rm›£ß>̾§f¦Í:γ³q5EGÄ°Ò1»Á:IH …—¸: Çêá&ˆ¬W(ŽF–©qžûck,¨Tò°àpsÊîÖ€yKà8Á›î|BÉxÍaRÞ^\½¾ k>ÈÔÓ[“Ö%Ú*ægÝ#ƒÙ¯ÙéQœÎ¦Ñ /ªxCÍNg ~ðåÉ_'Ÿ
+endobj
+858 0 obj<</Type/Page/Parent 689 0 R/Contents 859 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>/XObject<<>>>>/Annots 500 0 R>>endobj
+859 0 obj<</Filter/FlateDecode/Length 1501 >>stream
+x¥V]oÛ6}ϯ¸ðKÀ¡,ÙñGaH‚d Ö|´öÖ ð %ѶZ‰tI*®_öÛw.%%©±µ– vD‘¼‡çž{.¿Å4ÀoL“„†cʪ£`äùãÃ/GÉùPŒé|’ˆU4Â÷yûTÒœçS2›Š„FÓ ÿ?«hÕ¼ˆgXZQ2š`BžxQ2žb¼yƖ㱘¼z;Ó) tvÍx(&˜ÕEÜD‰1þÄÃÌb` -´×Gi÷™Ž0ç
+tŒ'SZäŒd'W¹õÊ‚ ‡yBWe¡´§·§‹Oam<jÖž cu‘Ÿ`r,èæâ½ã):b¯v/ÞšeRÓ-eF¯Šu ÒæQB¥ÝÒ•ÑZežŒ}58"éH¶»ÅcÁ O²Ë
+3ç²JåÏ  Åq (™ð¼ ª Bd¦Ú–Ê+’Úíp$oÈo
+G_jå|atÀ”"¦Ö9áyãýöMeÒšRì
+íDý$….£¿J¥ê]ä8h´h±ñU)ZxÉX€üäRº"“e¹ïÓÞÔ¤•ÊЪ‰Ñàѽá5PßY·h±QtS” 2§G[€ë–òåÉñíå=*e—§ÍQ³ö¨g1e9#ê2Oè["ÂË3$%$gqõÝ>o§‘Y­<¹z»5Öÿ¿m¼w¯üåíÃœÌømõ(·?" F.¯»ýqÎ’©ˆg/ÝjçAk¡× é*¬óäwȦY+ŒXÚ~Þ¥Ò)2[e¥çénJ8µ’ÒRêÏÝT ¾nKYhä¨Ða-‹±ÍhG]%u-KA·«Fªei•Ì÷”*¥±4@SyŸÒÚ7i‡Øwi„ÜÚ×a{ð¾3ös€ÕÐߧhq€ƒ¨½¹*Q ‘Ú£C¢–Àu»ALú‰K¦EÞ›7çœ+_o{˜\æʪó"Ï;¿›6P£§\¹Ìé = A¦Ÿj$ •V•û‚ÑÈÏáAr“ÕTd-hî¥õt÷¸˜‹ë?®û„rÎ>sr~}õЃ´ñîâqÞ Ÿ§ö¸$Ø;8»¿^!>ü~ýáYˆ çøÑo2SºcA ®~ÆIøï>ñÄEjèøª¶–®‹0cM“ Ì–>,í~AçÔkEº®ReØ…Î $¹ð´²¦BÅ"q.‘Ü`F#6µ›wæ
+;ÓÇÛûy Žk¾³„° @>f‘pÞ8ð‡›+‚ U…6¥Yï—§N»š»ÁæßôöÒJî[?5”›.Ä4ÕÛ\Âà¹<^Ì’1§pÒ5ÓŠ?¬[Q©žTÉåJ}Ä©ÕH;•n%2ÉÒˆL¡“
+endobj
+860 0 obj<</Type/Page/Parent 689 0 R/Contents 861 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 503 0 R>>endobj
+861 0 obj<</Filter/FlateDecode/Length 1076 >>stream
+x­UQoÛ6~÷¯8ä)Ú²Û ÒIë¬)²4‹…Ã: ´DÙì(Q©x~Ùoßw””8.ú61$ñx÷ÝwßÝýÝ‹hˆ¿ˆf#O)É{C1ė矇Ÿ{Ñd.F4MÅrŸÎĸ}3´d{:Ÿ‰9Mæ3<ð_)ÊÂÁx<“ë¸7¸>£hBq†ØÓ9ÒrHqrE$Æ‚.áÅo~e±#ˤ«•£íFôy9Ñ×c>|R•Ó¶øúT;•’t$ßÄßzC:‰¦À§Ç‰Ñªð?ñ×Áõ„¢¨ 2šñé#»ÜÙšRK’î1}¹Y<’­Øã £kmKJ÷•.<½þèA9[W‰¢«ÊnªŽúTXZÊ|% ¯ ÜÆn©.E‡h >3Þ
+3ø×(UoŽÃ pWl|nÅÀÙ\ßjcد.S§*=­ 2ÒƒÓ–<²YƒZÐ'iœ ˜À#%¶.‘: š*”•]•»>¹HÁuY)ÎUk2?¨*dÞ–ê ¶]}S‰‡c”6­äzÄC¶Ìò£­þ*ŸËB
+Þò÷ù 4î+èdAe 4Hg"è#èFoh­<°¡ZÈ3­4RÅ÷ma¬Li‹H 8Cƒ–¸)äZWÎ÷)©h+nà $Òàÿýþáæ.þððåÀ•žuÿ&=u*Á– ÷¶Ü±ÂÚh-fÊ5:tgá™ï0ÆĈÅåŸWGyí<9ßVØ©RV€„jØ àPúBÈëÔk+½Ö…4„óÀܸê=Ö£Æ@)¶Çß ¦ƒËª„Y ÌíœWy§j̇P„›6
++ nS<ÕÎK@ãឦ<rRï†ÓŒcP”ñÀÚn4¦ë¾ãƒÌm§ä=ÎÚá8oû"šb'ÏÇØí“f ./¹ºÄ³<ƒéƒMê[Qz¬OöŽmÙ\8™ ÏžGêÿ±ioÿNf1›Î±ü1´ç^Ľ_{ÿ€‡­îendstream
+endobj
+862 0 obj<</Type/Page/Parent 689 0 R/Contents 863 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F1 4 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 510 0 R>>endobj
+863 0 obj<</Filter/FlateDecode/Length 1453 >>stream
+xV]oÛ6}ϯ¸ÈKS –cÙ±Ý<më–¶@ÑnÛ`@_hŠ²XK¢FRVýïw.)9®ÒbCàØÉûqι÷òŸ‹]ãoF«”æK’ÕÅur7§__¤ë4™ÓÍ"M®©¢EºNVýSI÷¼Ÿnæi’Òb½ÂoÞeåaa±X%‹ñÂrž¼¤ùbÌ¥³ŽÆ§ÁÜ|¾|jn>{™,)/’uˆ‚·Ä'>öÛæbz÷’ÒkÚäÈg¹ZÓ& ià¼zUˆÆ+K³EBo><l>ЯR*çè^T[AδV*’&SÏ7_/®i’.pþê ½ú|ÏïØú /ÙúdÎ1cæf ½­½5Y+½6uܺ Ù¬ßš®xct£eê JÓ¨ŒtM¢&ü¬IÕmM]©Ú'ô{¿Ã:jb÷ôåê•©ek-6ÐgeézG÷GçUõå9yÓ‡=›ÇÀ.e¡ä^×—8+Jgh_›]JSUÚ_âT­ºóÌ“Æ3Gaµi]ð½µ¢†1GÑn‰€â6#§¢6õ±¶ŽCô…B¦ÎÛà….cþ¾
+ ®ƒ¼1Vöí¤cóƒÂöNYs}
+·* h<§f™Œ­òB‡õ1pÖ+öÇ¡Ö‡úù„ÞÁ‘~úøŽnŸƒÜéÉV×\'^~V (‡3&qâ¿h ÅþÊ!œk™¹T[u˜"YêÐö‰;}
+- 7¨¨.5´ÒXƒZfPw!{esÉŽh9gÀ‡®Àv…Àºu0tâð·ºxÔáÌà0p4~À(ÜÏskª¡È¾‡s\—ànÇ·ïP¡Ns“ä¡Ï±æ†;Zhé^5؆·bRßDÕÀ©ŽsÑ9ÌHäúèHÏfiš#«0 0¾ó ¶¬Ûs=6C úa@.\<¢X]»E¯òm ‘˺—~$›~RQ-ªpÃÂUs2¨ù-®èÞ`yر t¬pVVaÏw¾:ðXvqF„ÐÔ„=Ô'¸„áö‡kZBO£óch_¿¼<½»9»¶õ׶<É趉ãðÏ¿œn·Ü>­AÙ¢çëP*Ó»ár0á[doå¡@]èò±½…Op®3ÜBœÞÍú®`:F5¼:%u“⌼И‡¼–K~ñƒ¬N Ìãæéݺ÷0Iop“]ESÿÿ‚ú!ʆ=/V‹dµ\G”×)¿úcsñ×Å¿ Éääendstream
+endobj
+864 0 obj<</Type/Page/Parent 689 0 R/Contents 865 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F2 5 0 R/F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>/XObject<<>>>>/Annots 513 0 R>>endobj
+865 0 obj<</Filter/FlateDecode/Length 655 >>stream
+xTÛn›@}÷WåÉ‘
+áf ~ªséå¡’Û ö%R´†“®³,qó÷ÝÅέ•…ìÌ™9gæð0 Ð/D!NQö³À°?E’gtÑ¥8js@¡Ç¿Ÿga”ú9’Eä'èæ±OOnfÅììÓaˆ¢6Øiž¡¨,B€¢œ—¼
+ËÝÀÕ#WKzþ8°~Ã|©šå=*)5J ûö´¸'¼dÂóxT=!Äy±mìÛ®C©8Ó U«x©¥zBɺŽW‚°„f­hE½åè(xÐÓÙ GUr
+©8nç­Ï}óåzueJS½0ö#SO³¦!HÓÿF1QnoO}Ø&ÊQ).tGe%Ý ;)ªZZ¤˜„¬ø#ï䮧 hŹo _r¹üy3ò’šT0 ‡Ü˜þ©øæ ãpàᤉ&iæžz­ÕLTTºv̈
+]K
+Èz*úž© õk9”–ÐÉÕ3›ìXCýÕöÄ {¾ÁÐj[¦”}OiŠ?ŒFr˜–oŠ9n6LDz+Þq6¸¹T–cG
+pTRð×JÔ²ëäÞèb
+m+ðó¾Øšÿ_?OáfõíbuÝEÿÚÅ«ñkˉ¢ð$Gì™™²DÏIÓ:Ñ&jvÍÊ- Íy$~fßuZÉžV[o]öÅœÌÇ]_º±,÷†ë¸«Œ7ÈqÞÚ½DÏÉð´Û‰wxŽìZ“Ëð2볯¢âÜi:íš©‘¹Ìµj{F†»’=­(.ÉjŠ¦ÁÕ\°òw£Ìê¸ì|ÊSúÀä1¢ÅÂaX™±VòžÜKHåhœÂt+…Éô ^œ›n%YâgiN_2z›Ç&øº˜}Ÿýlu‚endstream
+endobj
+866 0 obj<</Count 16/First 867 0 R/Last 1019 0 R>>endobj
+867 0 obj<</Parent 866 0 R/Title(Table of Contents)/Dest[692 0 R/XYZ 0 756 0]/Next 868 0 R>>endobj
+868 0 obj<</Parent 866 0 R/Count -19/First 869 0 R/Last 887 0 R/Title(Chapter 1. How to Install and Test SAMBA)/Dest[700 0 R/XYZ 0 786 0]/Prev 867 0 R/Next 888 0 R>>endobj
+869 0 obj<</Parent 868 0 R/Title(1.1. Step 0: Read the man pages)/Dest[700 0 R/XYZ 0 762 0]/Next 870 0 R>>endobj
+870 0 obj<</Parent 868 0 R/Title(1.2. Step 1: Building the Binaries)/Dest[700 0 R/XYZ 0 625 0]/Prev 869 0 R/Next 871 0 R>>endobj
+871 0 obj<</Parent 868 0 R/Title(1.3. Step 2: The all important step)/Dest[700 0 R/XYZ 0 223 0]/Prev 870 0 R/Next 872 0 R>>endobj
+872 0 obj<</Parent 868 0 R/Title(1.4. Step 3: Create the smb configuration file.)/Dest[702 0 R/XYZ 0 786 0]/Prev 871 0 R/Next 873 0 R>>endobj
+873 0 obj<</Parent 868 0 R/Title(1.5. Step 4: Test your config file with testparm)/Dest[702 0 R/XYZ 0 438 0]/Prev 872 0 R/Next 874 0 R>>endobj
+874 0 obj<</Parent 868 0 R/Title(1.6. Step 5: Starting the smbd and nmbd)/Dest[702 0 R/XYZ 0 340 0]/Prev 873 0 R/Next 875 0 R>>endobj
+875 0 obj<</Parent 868 0 R/Title(1.6.1. Step 5a: Starting from inetd.conf)/Dest[702 0 R/XYZ 0 189 0]/Prev 874 0 R/Next 876 0 R>>endobj
+876 0 obj<</Parent 868 0 R/Title(1.6.2. Step 5b. Alternative: starting it as a daemon)/Dest[704 0 R/XYZ 0 366 0]/Prev 875 0 R/Next 877 0 R>>endobj
+877 0 obj<</Parent 868 0 R/Title(1.7. Step 6: Try listing the shares available on your server)/Dest[706 0 R/XYZ 0 786 0]/Prev 876 0 R/Next 878 0 R>>endobj
+878 0 obj<</Parent 868 0 R/Title(1.8. Step 7: Try connecting with the unix client)/Dest[706 0 R/XYZ 0 622 0]/Prev 877 0 R/Next 879 0 R>>endobj
+879 0 obj<</Parent 868 0 R/Title(1.9. Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT, Win2k, OS/2, etc... client)/Dest[706 0 R/XYZ 0 458 0]/Prev 878 0 R/Next 880 0 R>>endobj
+880 0 obj<</Parent 868 0 R/Title(1.10. What If Things Don't Work?)/Dest[706 0 R/XYZ 0 251 0]/Prev 879 0 R/Next 881 0 R>>endobj
+881 0 obj<</Parent 868 0 R/Title(1.10.1. Diagnosing Problems)/Dest[708 0 R/XYZ 0 745 0]/Prev 880 0 R/Next 882 0 R>>endobj
+882 0 obj<</Parent 868 0 R/Title(1.10.2. Scope IDs)/Dest[708 0 R/XYZ 0 686 0]/Prev 881 0 R/Next 883 0 R>>endobj
+883 0 obj<</Parent 868 0 R/Title(1.10.3. Choosing the Protocol Level)/Dest[708 0 R/XYZ 0 601 0]/Prev 882 0 R/Next 884 0 R>>endobj
+884 0 obj<</Parent 868 0 R/Title(1.10.4. Printing from UNIX to a Client PC)/Dest[708 0 R/XYZ 0 292 0]/Prev 883 0 R/Next 885 0 R>>endobj
+885 0 obj<</Parent 868 0 R/Title(1.10.5. Locking)/Dest[708 0 R/XYZ 0 181 0]/Prev 884 0 R/Next 886 0 R>>endobj
+886 0 obj<</Parent 868 0 R/Title(1.10.6. Mapping Usernames)/Dest[710 0 R/XYZ 0 388 0]/Prev 885 0 R/Next 887 0 R>>endobj
+887 0 obj<</Parent 868 0 R/Title(1.10.7. Other Character Sets)/Dest[710 0 R/XYZ 0 317 0]/Prev 886 0 R>>endobj
+888 0 obj<</Parent 866 0 R/Count -18/First 889 0 R/Last 906 0 R/Title(Chapter 2. Integrating MS Windows networks with Samba)/Dest[712 0 R/XYZ 0 786 0]/Prev 868 0 R/Next 907 0 R>>endobj
+889 0 obj<</Parent 888 0 R/Title(2.1. Agenda)/Dest[712 0 R/XYZ 0 738 0]/Next 890 0 R>>endobj
+890 0 obj<</Parent 888 0 R/Title(2.2. Name Resolution in a pure Unix/Linux world)/Dest[712 0 R/XYZ 0 495 0]/Prev 889 0 R/Next 891 0 R>>endobj
+891 0 obj<</Parent 888 0 R/Title(2.2.1. /etc/hosts)/Dest[712 0 R/XYZ 0 371 0]/Prev 890 0 R/Next 892 0 R>>endobj
+892 0 obj<</Parent 888 0 R/Title(2.2.2. /etc/resolv.conf)/Dest[714 0 R/XYZ 0 494 0]/Prev 891 0 R/Next 893 0 R>>endobj
+893 0 obj<</Parent 888 0 R/Title(2.2.3. /etc/host.conf)/Dest[714 0 R/XYZ 0 356 0]/Prev 892 0 R/Next 894 0 R>>endobj
+894 0 obj<</Parent 888 0 R/Title(2.2.4. /etc/nsswitch.conf)/Dest[714 0 R/XYZ 0 207 0]/Prev 893 0 R/Next 895 0 R>>endobj
+895 0 obj<</Parent 888 0 R/Title(2.3. Name resolution as used within MS Windows networking)/Dest[716 0 R/XYZ 0 389 0]/Prev 894 0 R/Next 896 0 R>>endobj
+896 0 obj<</Parent 888 0 R/Title(2.3.1. The NetBIOS Name Cache)/Dest[718 0 R/XYZ 0 337 0]/Prev 895 0 R/Next 897 0 R>>endobj
+897 0 obj<</Parent 888 0 R/Title(2.3.2. The LMHOSTS file)/Dest[720 0 R/XYZ 0 786 0]/Prev 896 0 R/Next 898 0 R>>endobj
+898 0 obj<</Parent 888 0 R/Title(2.3.3. HOSTS file)/Dest[722 0 R/XYZ 0 509 0]/Prev 897 0 R/Next 899 0 R>>endobj
+899 0 obj<</Parent 888 0 R/Title(2.3.4. DNS Lookup)/Dest[722 0 R/XYZ 0 411 0]/Prev 898 0 R/Next 900 0 R>>endobj
+900 0 obj<</Parent 888 0 R/Title(2.3.5. WINS Lookup)/Dest[722 0 R/XYZ 0 273 0]/Prev 899 0 R/Next 901 0 R>>endobj
+901 0 obj<</Parent 888 0 R/Title(2.4. How browsing functions and how to deploy stable and dependable browsing using Samba)/Dest[724 0 R/XYZ 0 720 0]/Prev 900 0 R/Next 902 0 R>>endobj
+902 0 obj<</Parent 888 0 R/Title(2.5. MS Windows security options and how to configure Samba for seemless integration)/Dest[724 0 R/XYZ 0 183 0]/Prev 901 0 R/Next 903 0 R>>endobj
+903 0 obj<</Parent 888 0 R/Title(2.5.1. Use MS Windows NT as an authentication server)/Dest[728 0 R/XYZ 0 786 0]/Prev 902 0 R/Next 904 0 R>>endobj
+904 0 obj<</Parent 888 0 R/Title(2.5.2. Make Samba a member of an MS Windows NT security domain)/Dest[728 0 R/XYZ 0 534 0]/Prev 903 0 R/Next 905 0 R>>endobj
+905 0 obj<</Parent 888 0 R/Title(2.5.3. Configure Samba as an authentication server)/Dest[728 0 R/XYZ 0 179 0]/Prev 904 0 R/Next 906 0 R>>endobj
+906 0 obj<</Parent 888 0 R/Title(2.6. Conclusions)/Dest[730 0 R/XYZ 0 281 0]/Prev 905 0 R>>endobj
+907 0 obj<</Parent 866 0 R/Count -3/First 908 0 R/Last 910 0 R/Title(Chapter 3. Configuring PAM for distributed but centrally managed authentication)/Dest[732 0 R/XYZ 0 786 0]/Prev 888 0 R/Next 911 0 R>>endobj
+908 0 obj<</Parent 907 0 R/Title(3.1. Samba and PAM)/Dest[732 0 R/XYZ 0 738 0]/Next 909 0 R>>endobj
+909 0 obj<</Parent 907 0 R/Title(3.2. Distributed Authentication)/Dest[734 0 R/XYZ 0 193 0]/Prev 908 0 R/Next 910 0 R>>endobj
+910 0 obj<</Parent 907 0 R/Title(3.3. PAM Configuration in smb.conf)/Dest[736 0 R/XYZ 0 745 0]/Prev 909 0 R>>endobj
+911 0 obj<</Parent 866 0 R/Count -2/First 912 0 R/Last 913 0 R/Title(Chapter 4. Hosting a Microsoft Distributed File System tree on Samba)/Dest[738 0 R/XYZ 0 786 0]/Prev 907 0 R/Next 914 0 R>>endobj
+912 0 obj<</Parent 911 0 R/Title(4.1. Instructions)/Dest[738 0 R/XYZ 0 738 0]/Next 913 0 R>>endobj
+913 0 obj<</Parent 911 0 R/Title(4.1.1. Notes)/Dest[740 0 R/XYZ 0 705 0]/Prev 912 0 R>>endobj
+914 0 obj<</Parent 866 0 R/Count -9/First 915 0 R/Last 923 0 R/Title(Chapter 5. UNIX Permission Bits and Windows NT Access Control Lists)/Dest[742 0 R/XYZ 0 786 0]/Prev 911 0 R/Next 924 0 R>>endobj
+915 0 obj<</Parent 914 0 R/Title(5.1. Viewing and changing UNIX permissions using the NT security dialogs)/Dest[742 0 R/XYZ 0 738 0]/Next 916 0 R>>endobj
+916 0 obj<</Parent 914 0 R/Title(5.2. How to view file security on a Samba share)/Dest[742 0 R/XYZ 0 557 0]/Prev 915 0 R/Next 917 0 R>>endobj
+917 0 obj<</Parent 914 0 R/Title(5.3. Viewing file ownership)/Dest[742 0 R/XYZ 0 393 0]/Prev 916 0 R/Next 918 0 R>>endobj
+918 0 obj<</Parent 914 0 R/Title(5.4. Viewing file or directory permissions)/Dest[744 0 R/XYZ 0 718 0]/Prev 917 0 R/Next 919 0 R>>endobj
+919 0 obj<</Parent 914 0 R/Title(5.4.1. File Permissions)/Dest[744 0 R/XYZ 0 488 0]/Prev 918 0 R/Next 920 0 R>>endobj
+920 0 obj<</Parent 914 0 R/Title(5.4.2. Directory Permissions)/Dest[744 0 R/XYZ 0 245 0]/Prev 919 0 R/Next 921 0 R>>endobj
+921 0 obj<</Parent 914 0 R/Title(5.5. Modifying file or directory permissions)/Dest[746 0 R/XYZ 0 745 0]/Prev 920 0 R/Next 922 0 R>>endobj
+922 0 obj<</Parent 914 0 R/Title(5.6. Interaction with the standard Samba create mask parameters)/Dest[746 0 R/XYZ 0 317 0]/Prev 921 0 R/Next 923 0 R>>endobj
+923 0 obj<</Parent 914 0 R/Title(5.7. Interaction with the standard Samba file attribute mapping)/Dest[750 0 R/XYZ 0 705 0]/Prev 922 0 R>>endobj
+924 0 obj<</Parent 866 0 R/Count -15/First 925 0 R/Last 939 0 R/Title(Chapter 6. Printing Support in Samba 2.2.x)/Dest[752 0 R/XYZ 0 786 0]/Prev 914 0 R/Next 940 0 R>>endobj
+925 0 obj<</Parent 924 0 R/Title(6.1. Introduction)/Dest[752 0 R/XYZ 0 762 0]/Next 926 0 R>>endobj
+926 0 obj<</Parent 924 0 R/Title(6.2. Configuration)/Dest[752 0 R/XYZ 0 334 0]/Prev 925 0 R/Next 927 0 R>>endobj
+927 0 obj<</Parent 924 0 R/Title(6.2.1. Creating [print$])/Dest[754 0 R/XYZ 0 771 0]/Prev 926 0 R/Next 928 0 R>>endobj
+928 0 obj<</Parent 924 0 R/Title(6.2.2. Setting Drivers for Existing Printers)/Dest[756 0 R/XYZ 0 543 0]/Prev 927 0 R/Next 929 0 R>>endobj
+929 0 obj<</Parent 924 0 R/Title(6.2.3. DeviceModes and New Printers)/Dest[758 0 R/XYZ 0 786 0]/Prev 928 0 R/Next 930 0 R>>endobj
+930 0 obj<</Parent 924 0 R/Title(6.2.4. Support a large number of printers)/Dest[758 0 R/XYZ 0 517 0]/Prev 929 0 R/Next 931 0 R>>endobj
+931 0 obj<</Parent 924 0 R/Title(6.2.5. Adding New Printers via the Windows NT APW)/Dest[760 0 R/XYZ 0 786 0]/Prev 930 0 R/Next 932 0 R>>endobj
+932 0 obj<</Parent 924 0 R/Title(6.2.6. Samba and Printer Ports)/Dest[760 0 R/XYZ 0 517 0]/Prev 931 0 R/Next 933 0 R>>endobj
+933 0 obj<</Parent 924 0 R/Title(6.3. The Imprints Toolset)/Dest[760 0 R/XYZ 0 339 0]/Prev 932 0 R/Next 934 0 R>>endobj
+934 0 obj<</Parent 924 0 R/Title(6.3.1. What is Imprints?)/Dest[760 0 R/XYZ 0 189 0]/Prev 933 0 R/Next 935 0 R>>endobj
+935 0 obj<</Parent 924 0 R/Title(6.3.2. Creating Printer Driver Packages)/Dest[762 0 R/XYZ 0 731 0]/Prev 934 0 R/Next 936 0 R>>endobj
+936 0 obj<</Parent 924 0 R/Title(6.3.3. The Imprints server)/Dest[762 0 R/XYZ 0 647 0]/Prev 935 0 R/Next 937 0 R>>endobj
+937 0 obj<</Parent 924 0 R/Title(6.3.4. The Installation Client)/Dest[762 0 R/XYZ 0 549 0]/Prev 936 0 R/Next 938 0 R>>endobj
+938 0 obj<</Parent 924 0 R/Title(6.4. Migration to from Samba 2.0.x to 2.2.x)/Dest[764 0 R/XYZ 0 665 0]/Prev 937 0 R/Next 939 0 R>>endobj
+939 0 obj<</Parent 924 0 R/Title(6.4.1. Parameters in smb.conf\(5\) for Backwards Compatibility)/Dest[764 0 R/XYZ 0 285 0]/Prev 938 0 R>>endobj
+940 0 obj<</Parent 866 0 R/Count -8/First 941 0 R/Last 948 0 R/Title(Chapter 7. Printing with CUPS in Samba 2.2.x)/Dest[766 0 R/XYZ 0 786 0]/Prev 924 0 R/Next 949 0 R>>endobj
+941 0 obj<</Parent 940 0 R/Title(7.1. Printing with CUPS in Samba 2.2.x)/Dest[766 0 R/XYZ 0 762 0]/Next 942 0 R>>endobj
+942 0 obj<</Parent 940 0 R/Title(7.2. Configuring smb.conf for CUPS)/Dest[766 0 R/XYZ 0 664 0]/Prev 941 0 R/Next 943 0 R>>endobj
+943 0 obj<</Parent 940 0 R/Title(7.3. Using CUPS as a mere spooling print server -- "raw" printing with vendor drivers download)/Dest[766 0 R/XYZ 0 321 0]/Prev 942 0 R/Next 944 0 R>>endobj
+944 0 obj<</Parent 940 0 R/Title(7.4. CUPS as a network PostScript RIP -- CUPS drivers working on server, Adobe PostScript driver with CUPS-PPDs downloaded to clients)/Dest[768 0 R/XYZ 0 786 0]/Prev 943 0 R/Next 945 0 R>>endobj
+945 0 obj<</Parent 940 0 R/Title(7.5. Windows Terminal Servers \(WTS\) as CUPS clients)/Dest[768 0 R/XYZ 0 236 0]/Prev 944 0 R/Next 946 0 R>>endobj
+946 0 obj<</Parent 940 0 R/Title(7.6. Setting up CUPS for driver download)/Dest[770 0 R/XYZ 0 692 0]/Prev 945 0 R/Next 947 0 R>>endobj
+947 0 obj<</Parent 940 0 R/Title(7.7. Sources of CUPS drivers / PPDs)/Dest[772 0 R/XYZ 0 786 0]/Prev 946 0 R/Next 948 0 R>>endobj
+948 0 obj<</Parent 940 0 R/Title(7.7.1. cupsaddsmb)/Dest[772 0 R/XYZ 0 266 0]/Prev 947 0 R>>endobj
+949 0 obj<</Parent 866 0 R/Count -3/First 950 0 R/Last 952 0 R/Title(Chapter 8. security = domain in Samba 2.x)/Dest[778 0 R/XYZ 0 786 0]/Prev 940 0 R/Next 953 0 R>>endobj
+950 0 obj<</Parent 949 0 R/Title(8.1. Joining an NT Domain with Samba 2.2)/Dest[778 0 R/XYZ 0 762 0]/Next 951 0 R>>endobj
+951 0 obj<</Parent 949 0 R/Title(8.2. Samba and Windows 2000 Domains)/Dest[780 0 R/XYZ 0 415 0]/Prev 950 0 R/Next 952 0 R>>endobj
+952 0 obj<</Parent 949 0 R/Title(8.3. Why is this better than security = server?)/Dest[780 0 R/XYZ 0 211 0]/Prev 951 0 R>>endobj
+953 0 obj<</Parent 866 0 R/Count -14/First 954 0 R/Last 967 0 R/Title(Chapter 9. How to Configure Samba 2.2 as a Primary Domain Controller)/Dest[784 0 R/XYZ 0 786 0]/Prev 949 0 R/Next 968 0 R>>endobj
+954 0 obj<</Parent 953 0 R/Title(9.1. Prerequisite Reading)/Dest[784 0 R/XYZ 0 738 0]/Next 955 0 R>>endobj
+955 0 obj<</Parent 953 0 R/Title(9.2. Background)/Dest[784 0 R/XYZ 0 640 0]/Prev 954 0 R/Next 956 0 R>>endobj
+956 0 obj<</Parent 953 0 R/Title(9.3. Configuring the Samba Domain Controller)/Dest[786 0 R/XYZ 0 771 0]/Prev 955 0 R/Next 957 0 R>>endobj
+957 0 obj<</Parent 953 0 R/Title(9.4. Creating Machine Trust Accounts and Joining Clients to the Domain)/Dest[788 0 R/XYZ 0 665 0]/Prev 956 0 R/Next 958 0 R>>endobj
+958 0 obj<</Parent 953 0 R/Title(9.4.1. Manual Creation of Machine Trust Accounts)/Dest[788 0 R/XYZ 0 303 0]/Prev 957 0 R/Next 959 0 R>>endobj
+959 0 obj<</Parent 953 0 R/Title(9.4.2. "On-the-Fly" Creation of Machine Trust Accounts)/Dest[790 0 R/XYZ 0 461 0]/Prev 958 0 R/Next 960 0 R>>endobj
+960 0 obj<</Parent 953 0 R/Title(9.4.3. Joining the Client to the Domain)/Dest[790 0 R/XYZ 0 249 0]/Prev 959 0 R/Next 961 0 R>>endobj
+961 0 obj<</Parent 953 0 R/Title(9.5. Common Problems and Errors)/Dest[792 0 R/XYZ 0 573 0]/Prev 960 0 R/Next 962 0 R>>endobj
+962 0 obj<</Parent 953 0 R/Title(9.6. System Policies and Profiles)/Dest[794 0 R/XYZ 0 324 0]/Prev 961 0 R/Next 963 0 R>>endobj
+963 0 obj<</Parent 953 0 R/Title(9.7. What other help can I get?)/Dest[796 0 R/XYZ 0 322 0]/Prev 962 0 R/Next 964 0 R>>endobj
+964 0 obj<</Parent 953 0 R/Title(9.8. Domain Control for Windows 9x/ME)/Dest[802 0 R/XYZ 0 692 0]/Prev 963 0 R/Next 965 0 R>>endobj
+965 0 obj<</Parent 953 0 R/Title(9.8.1. Configuration Instructions: Network Logons)/Dest[804 0 R/XYZ 0 705 0]/Prev 964 0 R/Next 966 0 R>>endobj
+966 0 obj<</Parent 953 0 R/Title(9.8.2. Configuration Instructions: Setting up Roaming User Profiles)/Dest[804 0 R/XYZ 0 271 0]/Prev 965 0 R/Next 967 0 R>>endobj
+967 0 obj<</Parent 953 0 R/Title(9.9. DOMAIN_CONTROL.txt : Windows NT Domain Control & Samba)/Dest[812 0 R/XYZ 0 260 0]/Prev 966 0 R>>endobj
+968 0 obj<</Parent 866 0 R/Count -8/First 969 0 R/Last 976 0 R/Title(Chapter 10. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain)/Dest[818 0 R/XYZ 0 786 0]/Prev 953 0 R/Next 977 0 R>>endobj
+969 0 obj<</Parent 968 0 R/Title(10.1. Prerequisite Reading)/Dest[818 0 R/XYZ 0 738 0]/Next 970 0 R>>endobj
+970 0 obj<</Parent 968 0 R/Title(10.2. Background)/Dest[818 0 R/XYZ 0 653 0]/Prev 969 0 R/Next 971 0 R>>endobj
+971 0 obj<</Parent 968 0 R/Title(10.3. What qualifies a Domain Controller on the network?)/Dest[818 0 R/XYZ 0 239 0]/Prev 970 0 R/Next 972 0 R>>endobj
+972 0 obj<</Parent 968 0 R/Title(10.3.1. How does a Workstation find its domain controller?)/Dest[820 0 R/XYZ 0 786 0]/Prev 971 0 R/Next 973 0 R>>endobj
+973 0 obj<</Parent 968 0 R/Title(10.3.2. When is the PDC needed?)/Dest[820 0 R/XYZ 0 662 0]/Prev 972 0 R/Next 974 0 R>>endobj
+974 0 obj<</Parent 968 0 R/Title(10.4. Can Samba be a Backup Domain Controller?)/Dest[820 0 R/XYZ 0 577 0]/Prev 973 0 R/Next 975 0 R>>endobj
+975 0 obj<</Parent 968 0 R/Title(10.5. How do I set up a Samba BDC?)/Dest[820 0 R/XYZ 0 439 0]/Prev 974 0 R/Next 976 0 R>>endobj
+976 0 obj<</Parent 968 0 R/Title(10.5.1. How do I replicate the smbpasswd file?)/Dest[822 0 R/XYZ 0 547 0]/Prev 975 0 R>>endobj
+977 0 obj<</Parent 866 0 R/Count -13/First 978 0 R/Last 990 0 R/Title(Chapter 11. Storing Samba's User/Machine Account information in an LDAP Directory)/Dest[824 0 R/XYZ 0 786 0]/Prev 968 0 R/Next 991 0 R>>endobj
+978 0 obj<</Parent 977 0 R/Title(11.1. Purpose)/Dest[824 0 R/XYZ 0 738 0]/Next 979 0 R>>endobj
+979 0 obj<</Parent 977 0 R/Title(11.2. Introduction)/Dest[824 0 R/XYZ 0 455 0]/Prev 978 0 R/Next 980 0 R>>endobj
+980 0 obj<</Parent 977 0 R/Title(11.3. Supported LDAP Servers)/Dest[826 0 R/XYZ 0 613 0]/Prev 979 0 R/Next 981 0 R>>endobj
+981 0 obj<</Parent 977 0 R/Title(11.4. Schema and Relationship to the RFC 2307 posixAccount)/Dest[826 0 R/XYZ 0 515 0]/Prev 980 0 R/Next 982 0 R>>endobj
+982 0 obj<</Parent 977 0 R/Title(11.5. Configuring Samba with LDAP)/Dest[828 0 R/XYZ 0 652 0]/Prev 981 0 R/Next 983 0 R>>endobj
+983 0 obj<</Parent 977 0 R/Title(11.5.1. OpenLDAP configuration)/Dest[828 0 R/XYZ 0 635 0]/Prev 982 0 R/Next 984 0 R>>endobj
+984 0 obj<</Parent 977 0 R/Title(11.5.2. Configuring Samba)/Dest[830 0 R/XYZ 0 725 0]/Prev 983 0 R/Next 985 0 R>>endobj
+985 0 obj<</Parent 977 0 R/Title(11.5.3. Importing smbpasswd entries)/Dest[832 0 R/XYZ 0 786 0]/Prev 984 0 R/Next 986 0 R>>endobj
+986 0 obj<</Parent 977 0 R/Title(11.6. Accounts and Groups management)/Dest[832 0 R/XYZ 0 596 0]/Prev 985 0 R/Next 987 0 R>>endobj
+987 0 obj<</Parent 977 0 R/Title(11.7. Security and sambaAccount)/Dest[832 0 R/XYZ 0 405 0]/Prev 986 0 R/Next 988 0 R>>endobj
+988 0 obj<</Parent 977 0 R/Title(11.8. LDAP specials attributes for sambaAccounts)/Dest[834 0 R/XYZ 0 685 0]/Prev 987 0 R/Next 989 0 R>>endobj
+989 0 obj<</Parent 977 0 R/Title(11.9. Example LDIF Entries for a sambaAccount)/Dest[836 0 R/XYZ 0 679 0]/Prev 988 0 R/Next 990 0 R>>endobj
+990 0 obj<</Parent 977 0 R/Title(11.10. Comments)/Dest[838 0 R/XYZ 0 786 0]/Prev 989 0 R>>endobj
+991 0 obj<</Parent 866 0 R/Count -16/First 992 0 R/Last 1007 0 R/Title(Chapter 12. Unified Logons between Windows NT and UNIX using Winbind)/Dest[840 0 R/XYZ 0 786 0]/Prev 977 0 R/Next 1008 0 R>>endobj
+992 0 obj<</Parent 991 0 R/Title(12.1. Abstract)/Dest[840 0 R/XYZ 0 738 0]/Next 993 0 R>>endobj
+993 0 obj<</Parent 991 0 R/Title(12.2. Introduction)/Dest[840 0 R/XYZ 0 601 0]/Prev 992 0 R/Next 994 0 R>>endobj
+994 0 obj<</Parent 991 0 R/Title(12.3. What Winbind Provides)/Dest[840 0 R/XYZ 0 291 0]/Prev 993 0 R/Next 995 0 R>>endobj
+995 0 obj<</Parent 991 0 R/Title(12.3.1. Target Uses)/Dest[842 0 R/XYZ 0 613 0]/Prev 994 0 R/Next 996 0 R>>endobj
+996 0 obj<</Parent 991 0 R/Title(12.4. How Winbind Works)/Dest[842 0 R/XYZ 0 462 0]/Prev 995 0 R/Next 997 0 R>>endobj
+997 0 obj<</Parent 991 0 R/Title(12.4.1. Microsoft Remote Procedure Calls)/Dest[842 0 R/XYZ 0 351 0]/Prev 996 0 R/Next 998 0 R>>endobj
+998 0 obj<</Parent 991 0 R/Title(12.4.2. Name Service Switch)/Dest[844 0 R/XYZ 0 786 0]/Prev 997 0 R/Next 999 0 R>>endobj
+999 0 obj<</Parent 991 0 R/Title(12.4.3. Pluggable Authentication Modules)/Dest[844 0 R/XYZ 0 345 0]/Prev 998 0 R/Next 1000 0 R>>endobj
+1000 0 obj<</Parent 991 0 R/Title(12.4.4. User and Group ID Allocation)/Dest[846 0 R/XYZ 0 718 0]/Prev 999 0 R/Next 1001 0 R>>endobj
+1001 0 obj<</Parent 991 0 R/Title(12.4.5. Result Caching)/Dest[846 0 R/XYZ 0 541 0]/Prev 1000 0 R/Next 1002 0 R>>endobj
+1002 0 obj<</Parent 991 0 R/Title(12.5. Installation and Configuration)/Dest[846 0 R/XYZ 0 403 0]/Prev 1001 0 R/Next 1003 0 R>>endobj
+1003 0 obj<</Parent 991 0 R/Title(12.5.1. Introduction)/Dest[846 0 R/XYZ 0 319 0]/Prev 1002 0 R/Next 1004 0 R>>endobj
+1004 0 obj<</Parent 991 0 R/Title(12.5.2. Requirements)/Dest[848 0 R/XYZ 0 692 0]/Prev 1003 0 R/Next 1005 0 R>>endobj
+1005 0 obj<</Parent 991 0 R/Title(12.5.3. Testing Things Out)/Dest[848 0 R/XYZ 0 422 0]/Prev 1004 0 R/Next 1006 0 R>>endobj
+1006 0 obj<</Parent 991 0 R/Title(12.6. Limitations)/Dest[856 0 R/XYZ 0 399 0]/Prev 1005 0 R/Next 1007 0 R>>endobj
+1007 0 obj<</Parent 991 0 R/Title(12.7. Conclusion)/Dest[856 0 R/XYZ 0 248 0]/Prev 1006 0 R>>endobj
+1008 0 obj<</Parent 866 0 R/Count -5/First 1009 0 R/Last 1013 0 R/Title(Chapter 13. OS2 Client HOWTO)/Dest[858 0 R/XYZ 0 786 0]/Prev 991 0 R/Next 1014 0 R>>endobj
+1009 0 obj<</Parent 1008 0 R/Title(13.1. FAQs)/Dest[858 0 R/XYZ 0 762 0]/Next 1010 0 R>>endobj
+1010 0 obj<</Parent 1008 0 R/Title(13.1.1. How can I configure OS/2 Warp Connect or OS/2 Warp 4 as a client for Samba?)/Dest[858 0 R/XYZ 0 732 0]/Prev 1009 0 R/Next 1011 0 R>>endobj
+1011 0 obj<</Parent 1008 0 R/Title(13.1.2. How can I configure OS/2 Warp 3 \(not Connect\), OS/2 1.2, 1.3 or 2.x for Samba?)/Dest[858 0 R/XYZ 0 380 0]/Prev 1010 0 R/Next 1012 0 R>>endobj
+1012 0 obj<</Parent 1008 0 R/Title(13.1.3. Are there any other issues when OS/2 \(any version\) is used as a client?)/Dest[860 0 R/XYZ 0 786 0]/Prev 1011 0 R/Next 1013 0 R>>endobj
+1013 0 obj<</Parent 1008 0 R/Title(13.1.4. How do I get printer driver download working for OS/2 clients?)/Dest[860 0 R/XYZ 0 671 0]/Prev 1012 0 R>>endobj
+1014 0 obj<</Parent 866 0 R/Count -4/First 1015 0 R/Last 1018 0 R/Title(Chapter 14. HOWTO Access Samba source code via CVS)/Dest[862 0 R/XYZ 0 786 0]/Prev 1008 0 R/Next 1019 0 R>>endobj
+1015 0 obj<</Parent 1014 0 R/Title(14.1. Introduction)/Dest[862 0 R/XYZ 0 738 0]/Next 1016 0 R>>endobj
+1016 0 obj<</Parent 1014 0 R/Title(14.2. CVS Access to samba.org)/Dest[862 0 R/XYZ 0 614 0]/Prev 1015 0 R/Next 1017 0 R>>endobj
+1017 0 obj<</Parent 1014 0 R/Title(14.2.1. Access via CVSweb)/Dest[862 0 R/XYZ 0 529 0]/Prev 1016 0 R/Next 1018 0 R>>endobj
+1018 0 obj<</Parent 1014 0 R/Title(14.2.2. Access via cvs)/Dest[862 0 R/XYZ 0 418 0]/Prev 1017 0 R>>endobj
+1019 0 obj<</Parent 866 0 R/Title(Index)/Dest[864 0 R/XYZ 0 586 0]/Prev 1014 0 R>>endobj
+1020 0 obj<</Type/Catalog/Pages 689 0 R/PageLayout/SinglePage/Outlines 866 0 R/OpenAction[690 0 R/XYZ null null 0]/PageMode/UseOutlines/PageLabels<</Nums[0<</P(title)>>1<</S/r>>5<</S/D/St 1/P()>>11<</S/D/St 7/P()>>21<</S/D/St 17/P()>>24<</S/D/St 20/P()>>26<</S/D/St 22/P()>>31<</S/D/St 27/P()>>38<</S/D/St 34/P()>>44<</S/D/St 40/P()>>47<</S/D/St 43/P()>>64<</S/D/St 60/P()>>67<</S/D/St 63/P()>>75<</S/D/St 71/P()>>84<</S/D/St 80/P()>>86<</S/D/St 82/P()>>]>>>>endobj
+xref
+0 1021
+0000000000 65535 f
+0000000015 00000 n
+0000000248 00000 n
+0000001814 00000 n
+0000001888 00000 n
+0000001967 00000 n
+0000002049 00000 n
+0000002135 00000 n
+0000002213 00000 n
+0000002290 00000 n
+0000002369 00000 n
+0000002446 00000 n
+0000002528 00000 n
+0000002587 00000 n
+0000002639 00000 n
+0000002724 00000 n
+0000002777 00000 n
+0000002861 00000 n
+0000002927 00000 n
+0000003011 00000 n
+0000003048 00000 n
+0000003149 00000 n
+0000003251 00000 n
+0000003353 00000 n
+0000003455 00000 n
+0000003557 00000 n
+0000003659 00000 n
+0000003761 00000 n
+0000003863 00000 n
+0000003965 00000 n
+0000004067 00000 n
+0000004169 00000 n
+0000004271 00000 n
+0000004373 00000 n
+0000004475 00000 n
+0000004577 00000 n
+0000004679 00000 n
+0000004781 00000 n
+0000004883 00000 n
+0000004985 00000 n
+0000005087 00000 n
+0000005188 00000 n
+0000005290 00000 n
+0000005392 00000 n
+0000005494 00000 n
+0000005596 00000 n
+0000005698 00000 n
+0000005800 00000 n
+0000005902 00000 n
+0000006004 00000 n
+0000006106 00000 n
+0000006208 00000 n
+0000006310 00000 n
+0000006412 00000 n
+0000006514 00000 n
+0000006616 00000 n
+0000006718 00000 n
+0000006820 00000 n
+0000006922 00000 n
+0000007024 00000 n
+0000007125 00000 n
+0000007227 00000 n
+0000007329 00000 n
+0000007431 00000 n
+0000007748 00000 n
+0000007849 00000 n
+0000007951 00000 n
+0000008053 00000 n
+0000008154 00000 n
+0000008256 00000 n
+0000008358 00000 n
+0000008460 00000 n
+0000008562 00000 n
+0000008664 00000 n
+0000008766 00000 n
+0000008868 00000 n
+0000008970 00000 n
+0000009072 00000 n
+0000009173 00000 n
+0000009275 00000 n
+0000009377 00000 n
+0000009479 00000 n
+0000009581 00000 n
+0000009683 00000 n
+0000009785 00000 n
+0000009887 00000 n
+0000009989 00000 n
+0000010091 00000 n
+0000010193 00000 n
+0000010295 00000 n
+0000010397 00000 n
+0000010499 00000 n
+0000010601 00000 n
+0000010703 00000 n
+0000010804 00000 n
+0000010906 00000 n
+0000011008 00000 n
+0000011110 00000 n
+0000011212 00000 n
+0000011314 00000 n
+0000011416 00000 n
+0000011519 00000 n
+0000011622 00000 n
+0000011725 00000 n
+0000011827 00000 n
+0000011930 00000 n
+0000012032 00000 n
+0000012133 00000 n
+0000012458 00000 n
+0000012560 00000 n
+0000012663 00000 n
+0000012766 00000 n
+0000012869 00000 n
+0000012972 00000 n
+0000013075 00000 n
+0000013178 00000 n
+0000013281 00000 n
+0000013384 00000 n
+0000013487 00000 n
+0000013590 00000 n
+0000013693 00000 n
+0000013796 00000 n
+0000013899 00000 n
+0000014002 00000 n
+0000014104 00000 n
+0000014207 00000 n
+0000014310 00000 n
+0000014413 00000 n
+0000014516 00000 n
+0000014619 00000 n
+0000014722 00000 n
+0000014825 00000 n
+0000014928 00000 n
+0000015030 00000 n
+0000015133 00000 n
+0000015236 00000 n
+0000015339 00000 n
+0000015442 00000 n
+0000015545 00000 n
+0000015648 00000 n
+0000015751 00000 n
+0000015854 00000 n
+0000015957 00000 n
+0000016060 00000 n
+0000016163 00000 n
+0000016266 00000 n
+0000016369 00000 n
+0000016471 00000 n
+0000016574 00000 n
+0000016677 00000 n
+0000016780 00000 n
+0000016882 00000 n
+0000016983 00000 n
+0000017084 00000 n
+0000017461 00000 n
+0000017563 00000 n
+0000017666 00000 n
+0000017769 00000 n
+0000017872 00000 n
+0000017975 00000 n
+0000018078 00000 n
+0000018181 00000 n
+0000018284 00000 n
+0000018387 00000 n
+0000018490 00000 n
+0000018593 00000 n
+0000018695 00000 n
+0000018798 00000 n
+0000018901 00000 n
+0000019004 00000 n
+0000019107 00000 n
+0000019210 00000 n
+0000019312 00000 n
+0000019415 00000 n
+0000019518 00000 n
+0000019621 00000 n
+0000019724 00000 n
+0000019825 00000 n
+0000020026 00000 n
+0000020079 00000 n
+0000020166 00000 n
+0000020191 00000 n
+0000020239 00000 n
+0000020326 00000 n
+0000020373 00000 n
+0000020459 00000 n
+0000020506 00000 n
+0000020592 00000 n
+0000020633 00000 n
+0000020678 00000 n
+0000020765 00000 n
+0000020810 00000 n
+0000020896 00000 n
+0000020929 00000 n
+0000020984 00000 n
+0000021069 00000 n
+0000021094 00000 n
+0000021147 00000 n
+0000021234 00000 n
+0000021284 00000 n
+0000021371 00000 n
+0000021404 00000 n
+0000021523 00000 n
+0000021609 00000 n
+0000021652 00000 n
+0000021739 00000 n
+0000021782 00000 n
+0000021869 00000 n
+0000021910 00000 n
+0000021956 00000 n
+0000022043 00000 n
+0000022068 00000 n
+0000022114 00000 n
+0000022199 00000 n
+0000022245 00000 n
+0000022328 00000 n
+0000022361 00000 n
+0000022405 00000 n
+0000022492 00000 n
+0000022543 00000 n
+0000022630 00000 n
+0000022679 00000 n
+0000022766 00000 n
+0000022814 00000 n
+0000022900 00000 n
+0000022949 00000 n
+0000023012 00000 n
+0000023099 00000 n
+0000023157 00000 n
+0000023244 00000 n
+0000023338 00000 n
+0000023424 00000 n
+0000023525 00000 n
+0000023574 00000 n
+0000023617 00000 n
+0000023703 00000 n
+0000023751 00000 n
+0000023838 00000 n
+0000023879 00000 n
+0000023966 00000 n
+0000024010 00000 n
+0000024097 00000 n
+0000024146 00000 n
+0000024192 00000 n
+0000024279 00000 n
+0000024304 00000 n
+0000024352 00000 n
+0000024439 00000 n
+0000024488 00000 n
+0000024575 00000 n
+0000024608 00000 n
+0000024662 00000 n
+0000024749 00000 n
+0000024800 00000 n
+0000024887 00000 n
+0000024938 00000 n
+0000025024 00000 n
+0000025078 00000 n
+0000025165 00000 n
+0000025215 00000 n
+0000025302 00000 n
+0000025352 00000 n
+0000025438 00000 n
+0000025502 00000 n
+0000025589 00000 n
+0000025662 00000 n
+0000025726 00000 n
+0000025813 00000 n
+0000025838 00000 n
+0000025890 00000 n
+0000025975 00000 n
+0000026000 00000 n
+0000026064 00000 n
+0000026151 00000 n
+0000026217 00000 n
+0000026304 00000 n
+0000026362 00000 n
+0000026449 00000 n
+0000026543 00000 n
+0000026630 00000 n
+0000026694 00000 n
+0000026781 00000 n
+0000026842 00000 n
+0000026929 00000 n
+0000026994 00000 n
+0000027043 00000 n
+0000027130 00000 n
+0000027178 00000 n
+0000027265 00000 n
+0000027307 00000 n
+0000027393 00000 n
+0000027434 00000 n
+0000027477 00000 n
+0000027564 00000 n
+0000027614 00000 n
+0000027701 00000 n
+0000027749 00000 n
+0000027836 00000 n
+0000027890 00000 n
+0000027975 00000 n
+0000028024 00000 n
+0000028069 00000 n
+0000028156 00000 n
+0000028213 00000 n
+0000028300 00000 n
+0000028396 00000 n
+0000028482 00000 n
+0000028523 00000 n
+0000028571 00000 n
+0000028658 00000 n
+0000028706 00000 n
+0000028793 00000 n
+0000028843 00000 n
+0000028930 00000 n
+0000028978 00000 n
+0000029065 00000 n
+0000029114 00000 n
+0000029162 00000 n
+0000029249 00000 n
+0000029297 00000 n
+0000029382 00000 n
+0000029427 00000 n
+0000029513 00000 n
+0000029556 00000 n
+0000029642 00000 n
+0000029683 00000 n
+0000029769 00000 n
+0000029818 00000 n
+0000029904 00000 n
+0000029950 00000 n
+0000030036 00000 n
+0000030081 00000 n
+0000030167 00000 n
+0000030219 00000 n
+0000030305 00000 n
+0000030355 00000 n
+0000030441 00000 n
+0000030487 00000 n
+0000030573 00000 n
+0000030616 00000 n
+0000030702 00000 n
+0000030746 00000 n
+0000030832 00000 n
+0000030875 00000 n
+0000030961 00000 n
+0000031006 00000 n
+0000031092 00000 n
+0000031130 00000 n
+0000031216 00000 n
+0000031258 00000 n
+0000031344 00000 n
+0000031387 00000 n
+0000031473 00000 n
+0000031511 00000 n
+0000031597 00000 n
+0000031639 00000 n
+0000031725 00000 n
+0000031769 00000 n
+0000031855 00000 n
+0000031902 00000 n
+0000031988 00000 n
+0000032036 00000 n
+0000032121 00000 n
+0000032322 00000 n
+0000032372 00000 n
+0000032459 00000 n
+0000032509 00000 n
+0000032595 00000 n
+0000032628 00000 n
+0000032677 00000 n
+0000032763 00000 n
+0000032810 00000 n
+0000032897 00000 n
+0000032930 00000 n
+0000033045 00000 n
+0000033132 00000 n
+0000033157 00000 n
+0000033239 00000 n
+0000033326 00000 n
+0000033411 00000 n
+0000033498 00000 n
+0000033531 00000 n
+0000033586 00000 n
+0000033673 00000 n
+0000033729 00000 n
+0000033816 00000 n
+0000033849 00000 n
+0000033897 00000 n
+0000033984 00000 n
+0000034058 00000 n
+0000034145 00000 n
+0000034213 00000 n
+0000034300 00000 n
+0000034354 00000 n
+0000034441 00000 n
+0000034509 00000 n
+0000034596 00000 n
+0000034670 00000 n
+0000034757 00000 n
+0000034805 00000 n
+0000034892 00000 n
+0000034949 00000 n
+0000035036 00000 n
+0000035117 00000 n
+0000035172 00000 n
+0000035259 00000 n
+0000035340 00000 n
+0000035427 00000 n
+0000035460 00000 n
+0000035513 00000 n
+0000035600 00000 n
+0000035625 00000 n
+0000035674 00000 n
+0000035761 00000 n
+0000035786 00000 n
+0000035840 00000 n
+0000035926 00000 n
+0000035951 00000 n
+0000036007 00000 n
+0000036094 00000 n
+0000036163 00000 n
+0000036250 00000 n
+0000036301 00000 n
+0000036388 00000 n
+0000036475 00000 n
+0000036562 00000 n
+0000036618 00000 n
+0000036705 00000 n
+0000036755 00000 n
+0000036842 00000 n
+0000036907 00000 n
+0000036959 00000 n
+0000037046 00000 n
+0000037102 00000 n
+0000037189 00000 n
+0000037237 00000 n
+0000037324 00000 n
+0000037372 00000 n
+0000037459 00000 n
+0000037508 00000 n
+0000037549 00000 n
+0000037636 00000 n
+0000037680 00000 n
+0000037767 00000 n
+0000037812 00000 n
+0000037899 00000 n
+0000037943 00000 n
+0000038030 00000 n
+0000038074 00000 n
+0000038161 00000 n
+0000038203 00000 n
+0000038290 00000 n
+0000038338 00000 n
+0000038425 00000 n
+0000038498 00000 n
+0000038553 00000 n
+0000038640 00000 n
+0000038696 00000 n
+0000038783 00000 n
+0000038831 00000 n
+0000038917 00000 n
+0000038958 00000 n
+0000039011 00000 n
+0000039097 00000 n
+0000039122 00000 n
+0000039176 00000 n
+0000039263 00000 n
+0000039288 00000 n
+0000039350 00000 n
+0000039437 00000 n
+0000039462 00000 n
+0000039511 00000 n
+0000039598 00000 n
+0000039647 00000 n
+0000039733 00000 n
+0000039766 00000 n
+0000039814 00000 n
+0000039901 00000 n
+0000039951 00000 n
+0000040038 00000 n
+0000040082 00000 n
+0000040169 00000 n
+0000040213 00000 n
+0000040300 00000 n
+0000040350 00000 n
+0000040437 00000 n
+0000040487 00000 n
+0000040574 00000 n
+0000040623 00000 n
+0000040710 00000 n
+0000040757 00000 n
+0000040844 00000 n
+0000040925 00000 n
+0000041004 00000 n
+0000041091 00000 n
+0000041173 00000 n
+0000041259 00000 n
+0000041334 00000 n
+0000041421 00000 n
+0000041494 00000 n
+0000041581 00000 n
+0000041630 00000 n
+0000041708 00000 n
+0000041795 00000 n
+0000041820 00000 n
+0000041883 00000 n
+0000041970 00000 n
+0000042033 00000 n
+0000042120 00000 n
+0000042174 00000 n
+0000042261 00000 n
+0000042302 00000 n
+0000042344 00000 n
+0000042431 00000 n
+0000042456 00000 n
+0000042490 00000 n
+0000042524 00000 n
+0000045308 00000 n
+0000045351 00000 n
+0000045394 00000 n
+0000045437 00000 n
+0000045480 00000 n
+0000045523 00000 n
+0000045566 00000 n
+0000045609 00000 n
+0000045652 00000 n
+0000045695 00000 n
+0000045738 00000 n
+0000045781 00000 n
+0000045824 00000 n
+0000045867 00000 n
+0000045910 00000 n
+0000045953 00000 n
+0000045996 00000 n
+0000046039 00000 n
+0000046082 00000 n
+0000046125 00000 n
+0000046168 00000 n
+0000046211 00000 n
+0000046254 00000 n
+0000046297 00000 n
+0000046340 00000 n
+0000046383 00000 n
+0000046426 00000 n
+0000046469 00000 n
+0000046512 00000 n
+0000046555 00000 n
+0000046598 00000 n
+0000046641 00000 n
+0000046684 00000 n
+0000046727 00000 n
+0000046770 00000 n
+0000046813 00000 n
+0000046856 00000 n
+0000046899 00000 n
+0000046942 00000 n
+0000046985 00000 n
+0000047028 00000 n
+0000047071 00000 n
+0000047114 00000 n
+0000047157 00000 n
+0000047200 00000 n
+0000047243 00000 n
+0000047286 00000 n
+0000047329 00000 n
+0000047372 00000 n
+0000047415 00000 n
+0000047458 00000 n
+0000047501 00000 n
+0000047544 00000 n
+0000047587 00000 n
+0000047630 00000 n
+0000047673 00000 n
+0000047716 00000 n
+0000047759 00000 n
+0000047802 00000 n
+0000047845 00000 n
+0000047888 00000 n
+0000047931 00000 n
+0000047974 00000 n
+0000048017 00000 n
+0000048060 00000 n
+0000048103 00000 n
+0000048146 00000 n
+0000048189 00000 n
+0000048232 00000 n
+0000048275 00000 n
+0000048318 00000 n
+0000048361 00000 n
+0000048404 00000 n
+0000048447 00000 n
+0000048490 00000 n
+0000048533 00000 n
+0000048576 00000 n
+0000048619 00000 n
+0000048662 00000 n
+0000048705 00000 n
+0000048748 00000 n
+0000048791 00000 n
+0000048834 00000 n
+0000048877 00000 n
+0000048920 00000 n
+0000048963 00000 n
+0000049006 00000 n
+0000049049 00000 n
+0000049092 00000 n
+0000049135 00000 n
+0000049178 00000 n
+0000049221 00000 n
+0000049264 00000 n
+0000049307 00000 n
+0000049350 00000 n
+0000049393 00000 n
+0000049436 00000 n
+0000049479 00000 n
+0000049522 00000 n
+0000049565 00000 n
+0000049608 00000 n
+0000049651 00000 n
+0000049694 00000 n
+0000049737 00000 n
+0000049780 00000 n
+0000049823 00000 n
+0000049866 00000 n
+0000049909 00000 n
+0000049952 00000 n
+0000049995 00000 n
+0000050038 00000 n
+0000050081 00000 n
+0000050124 00000 n
+0000050167 00000 n
+0000050210 00000 n
+0000050253 00000 n
+0000050296 00000 n
+0000050339 00000 n
+0000050382 00000 n
+0000050425 00000 n
+0000050468 00000 n
+0000050511 00000 n
+0000050554 00000 n
+0000050597 00000 n
+0000050640 00000 n
+0000050683 00000 n
+0000050726 00000 n
+0000050769 00000 n
+0000050812 00000 n
+0000050855 00000 n
+0000050898 00000 n
+0000050941 00000 n
+0000050984 00000 n
+0000051027 00000 n
+0000051070 00000 n
+0000051113 00000 n
+0000051156 00000 n
+0000051199 00000 n
+0000051242 00000 n
+0000051285 00000 n
+0000051328 00000 n
+0000051371 00000 n
+0000051414 00000 n
+0000051457 00000 n
+0000051500 00000 n
+0000051543 00000 n
+0000051586 00000 n
+0000051629 00000 n
+0000051672 00000 n
+0000051715 00000 n
+0000051758 00000 n
+0000051801 00000 n
+0000051844 00000 n
+0000051887 00000 n
+0000051930 00000 n
+0000051973 00000 n
+0000052016 00000 n
+0000052059 00000 n
+0000052102 00000 n
+0000052145 00000 n
+0000052188 00000 n
+0000052231 00000 n
+0000052274 00000 n
+0000052317 00000 n
+0000052360 00000 n
+0000052403 00000 n
+0000052446 00000 n
+0000052489 00000 n
+0000052532 00000 n
+0000052575 00000 n
+0000052618 00000 n
+0000052661 00000 n
+0000052704 00000 n
+0000053455 00000 n
+0000053645 00000 n
+0000054311 00000 n
+0000054501 00000 n
+0000059140 00000 n
+0000059331 00000 n
+0000064157 00000 n
+0000064348 00000 n
+0000069103 00000 n
+0000069294 00000 n
+0000071874 00000 n
+0000072083 00000 n
+0000073218 00000 n
+0000073403 00000 n
+0000075010 00000 n
+0000075204 00000 n
+0000076641 00000 n
+0000076853 00000 n
+0000078295 00000 n
+0000078471 00000 n
+0000079964 00000 n
+0000080131 00000 n
+0000081789 00000 n
+0000081984 00000 n
+0000083377 00000 n
+0000083572 00000 n
+0000085315 00000 n
+0000085500 00000 n
+0000087279 00000 n
+0000087455 00000 n
+0000089545 00000 n
+0000089721 00000 n
+0000091539 00000 n
+0000091715 00000 n
+0000093462 00000 n
+0000093647 00000 n
+0000095594 00000 n
+0000095803 00000 n
+0000097823 00000 n
+0000098033 00000 n
+0000099608 00000 n
+0000099794 00000 n
+0000101171 00000 n
+0000101356 00000 n
+0000102936 00000 n
+0000103136 00000 n
+0000104844 00000 n
+0000105044 00000 n
+0000105924 00000 n
+0000106133 00000 n
+0000107655 00000 n
+0000107832 00000 n
+0000108590 00000 n
+0000108808 00000 n
+0000110584 00000 n
+0000110787 00000 n
+0000112655 00000 n
+0000112864 00000 n
+0000114627 00000 n
+0000114826 00000 n
+0000116203 00000 n
+0000116388 00000 n
+0000117262 00000 n
+0000117490 00000 n
+0000119391 00000 n
+0000119600 00000 n
+0000121541 00000 n
+0000121769 00000 n
+0000123814 00000 n
+0000124024 00000 n
+0000125694 00000 n
+0000125913 00000 n
+0000127953 00000 n
+0000128157 00000 n
+0000129859 00000 n
+0000130087 00000 n
+0000131899 00000 n
+0000132117 00000 n
+0000133959 00000 n
+0000134172 00000 n
+0000136391 00000 n
+0000136576 00000 n
+0000137981 00000 n
+0000138218 00000 n
+0000140628 00000 n
+0000140821 00000 n
+0000142918 00000 n
+0000143075 00000 n
+0000143340 00000 n
+0000143567 00000 n
+0000145058 00000 n
+0000145267 00000 n
+0000147056 00000 n
+0000147246 00000 n
+0000148582 00000 n
+0000148801 00000 n
+0000150557 00000 n
+0000150767 00000 n
+0000152309 00000 n
+0000152528 00000 n
+0000154434 00000 n
+0000154671 00000 n
+0000156536 00000 n
+0000156740 00000 n
+0000158557 00000 n
+0000158785 00000 n
+0000160831 00000 n
+0000161050 00000 n
+0000162967 00000 n
+0000163167 00000 n
+0000165149 00000 n
+0000165349 00000 n
+0000167600 00000 n
+0000167800 00000 n
+0000169972 00000 n
+0000170176 00000 n
+0000172240 00000 n
+0000172425 00000 n
+0000174090 00000 n
+0000174247 00000 n
+0000176206 00000 n
+0000176391 00000 n
+0000178521 00000 n
+0000178715 00000 n
+0000180776 00000 n
+0000180942 00000 n
+0000182782 00000 n
+0000182939 00000 n
+0000183402 00000 n
+0000183593 00000 n
+0000185246 00000 n
+0000185465 00000 n
+0000187469 00000 n
+0000187697 00000 n
+0000189043 00000 n
+0000189262 00000 n
+0000191342 00000 n
+0000191552 00000 n
+0000193597 00000 n
+0000193782 00000 n
+0000195274 00000 n
+0000195484 00000 n
+0000196891 00000 n
+0000197119 00000 n
+0000199012 00000 n
+0000199213 00000 n
+0000200991 00000 n
+0000201185 00000 n
+0000202441 00000 n
+0000202623 00000 n
+0000202983 00000 n
+0000203169 00000 n
+0000204857 00000 n
+0000205033 00000 n
+0000206762 00000 n
+0000206947 00000 n
+0000208850 00000 n
+0000209060 00000 n
+0000210972 00000 n
+0000211209 00000 n
+0000213304 00000 n
+0000213522 00000 n
+0000215257 00000 n
+0000215460 00000 n
+0000216737 00000 n
+0000216922 00000 n
+0000218629 00000 n
+0000218824 00000 n
+0000220376 00000 n
+0000220577 00000 n
+0000222152 00000 n
+0000222343 00000 n
+0000223493 00000 n
+0000223693 00000 n
+0000225220 00000 n
+0000225429 00000 n
+0000226158 00000 n
+0000226215 00000 n
+0000226314 00000 n
+0000226486 00000 n
+0000226599 00000 n
+0000226728 00000 n
+0000226858 00000 n
+0000227000 00000 n
+0000227143 00000 n
+0000227277 00000 n
+0000227412 00000 n
+0000227559 00000 n
+0000227714 00000 n
+0000227857 00000 n
+0000228038 00000 n
+0000228165 00000 n
+0000228287 00000 n
+0000228399 00000 n
+0000228529 00000 n
+0000228665 00000 n
+0000228775 00000 n
+0000228895 00000 n
+0000229005 00000 n
+0000229190 00000 n
+0000229283 00000 n
+0000229425 00000 n
+0000229537 00000 n
+0000229655 00000 n
+0000229771 00000 n
+0000229891 00000 n
+0000230043 00000 n
+0000230167 00000 n
+0000230285 00000 n
+0000230397 00000 n
+0000230509 00000 n
+0000230622 00000 n
+0000230805 00000 n
+0000230984 00000 n
+0000231131 00000 n
+0000231288 00000 n
+0000231433 00000 n
+0000231531 00000 n
+0000231741 00000 n
+0000231841 00000 n
+0000231967 00000 n
+0000232083 00000 n
+0000232282 00000 n
+0000232381 00000 n
+0000232475 00000 n
+0000232673 00000 n
+0000232827 00000 n
+0000232969 00000 n
+0000233091 00000 n
+0000233228 00000 n
+0000233346 00000 n
+0000233469 00000 n
+0000233608 00000 n
+0000233766 00000 n
+0000233911 00000 n
+0000234085 00000 n
+0000234184 00000 n
+0000234297 00000 n
+0000234416 00000 n
+0000234555 00000 n
+0000234685 00000 n
+0000234821 00000 n
+0000234965 00000 n
+0000235090 00000 n
+0000235210 00000 n
+0000235329 00000 n
+0000235463 00000 n
+0000235584 00000 n
+0000235709 00000 n
+0000235847 00000 n
+0000235991 00000 n
+0000236166 00000 n
+0000236286 00000 n
+0000236415 00000 n
+0000236604 00000 n
+0000236832 00000 n
+0000236980 00000 n
+0000237115 00000 n
+0000237245 00000 n
+0000237344 00000 n
+0000237516 00000 n
+0000237638 00000 n
+0000237768 00000 n
+0000237897 00000 n
+0000238097 00000 n
+0000238204 00000 n
+0000238314 00000 n
+0000238453 00000 n
+0000238618 00000 n
+0000238761 00000 n
+0000238910 00000 n
+0000239044 00000 n
+0000239170 00000 n
+0000239298 00000 n
+0000239424 00000 n
+0000239556 00000 n
+0000239700 00000 n
+0000239862 00000 n
+0000240003 00000 n
+0000240222 00000 n
+0000240330 00000 n
+0000240441 00000 n
+0000240592 00000 n
+0000240745 00000 n
+0000240871 00000 n
+0000241012 00000 n
+0000241141 00000 n
+0000241269 00000 n
+0000241482 00000 n
+0000241577 00000 n
+0000241690 00000 n
+0000241813 00000 n
+0000241966 00000 n
+0000242094 00000 n
+0000242219 00000 n
+0000242339 00000 n
+0000242469 00000 n
+0000242600 00000 n
+0000242726 00000 n
+0000242869 00000 n
+0000243009 00000 n
+0000243106 00000 n
+0000243308 00000 n
+0000243404 00000 n
+0000243517 00000 n
+0000243639 00000 n
+0000243753 00000 n
+0000243871 00000 n
+0000244006 00000 n
+0000244128 00000 n
+0000244264 00000 n
+0000244397 00000 n
+0000244517 00000 n
+0000244651 00000 n
+0000244769 00000 n
+0000244887 00000 n
+0000245011 00000 n
+0000245126 00000 n
+0000245226 00000 n
+0000245389 00000 n
+0000245484 00000 n
+0000245666 00000 n
+0000245853 00000 n
+0000246033 00000 n
+0000246188 00000 n
+0000246374 00000 n
+0000246477 00000 n
+0000246605 00000 n
+0000246729 00000 n
+0000246836 00000 n
+0000246925 00000 n
+trailer
+<</Size 1021/Root 1020 0 R/Info 1 0 R/ID[<a1f72d1f02ec5c904fa524f9b1183212><a1f72d1f02ec5c904fa524f9b1183212>]>>
+startxref
+247391
+%%EOF
diff --git a/docs/THANKS b/docs/THANKS
new file mode 100755
index 00000000000..789042f78e1
--- /dev/null
+++ b/docs/THANKS
@@ -0,0 +1,137 @@
+=====================================================================
+This file is for thanks to individuals or organisations who have
+helped with the development of Samba, other than by coding or bug
+reports. Their contributions are gratefully acknowledged.
+
+Please refer to the manual pages and change-log for a list of those
+who have contributed in the form of patches, bug fixes or other
+direct changes to the package.
+
+Contributions of any kind are welcomed. If you want to help then
+please contact Andrew.Tridgell@anu.edu.au, or via normal mail at
+
+ Andrew Tridgell
+ 3 Ballow Crescent
+ Macgregor, A.C.T
+ 2615 Australia
+=====================================================================
+
+
+Lee Fisher (leefi@microsoft.com)
+Charles Fox (cfox@microsoft.com)
+Dan Perry (danp@exchnge.microsoft.com)
+Paul Leach (paulle@microsoft.com)
+Isaac Heizer (isaache@microsoft.com)
+
+ These Microsoft people have been very helpful and supportive of
+ the development of Samba over some years.
+
+ Lee very kindly supplied me with a copy of the X/Open SMB
+ specs. These have been invaluable in getting the details of the
+ implementation right. They will become even more important as we move
+ towards a Lanman 2.1 compliant server. Lee has provided very
+ useful advice on several aspects of the server.
+ Lee has also provided me with copies of Windows NTAS 3.1, Visual C
+ and a developers CD-ROM. Being able to run NT at home is a
+ great help.
+
+ Charles has helped out in numerous ways with the provision of SMB
+ specifications and helpful advice. He has been following the
+ discussion of Samba on the mailing list and has stepped in
+ regularly to clarify points and to offer help.
+
+ Dan has put me in touch with NT developers to help sort out bugs and
+ compatability issues. He has also supplied me with a copy of the
+ NT browsing spec, which will help a lot in the development of the
+ Samba browser code.
+
+ Paul was responsible for Microsoft paying my flight to Seattle for the
+ first CIFS conference (see http://samba.org/cifs) and has been
+ generally helpful and cooperative as the SMB community moves towards
+ an Internet-ready specification. Isaac has regularly provided help on
+ the behaviour of NT networks.
+
+Bruce Perens (bruce@pixar.com)
+
+ In appreciation of his effort on Samba we have sent Andrew copies of
+ various Pixar computer-graphics software products. Pixar is best known
+ for its "Renderman" product, the 3-D renderer used by ILM to make special
+ effects for "Terminator II" and "Jurassic Park". We won the first Oscar
+ given to a computer graphic animated feature for our short film "Tin Toy".
+ Our retail products "Typestry" and "Showplace", incorporate the same
+ renderer used on the films, and are available on Windows and the
+ Macintosh.
+
+
+
+Henry Lee (hyl@microplex.co)
+
+ Henry sent me a M202 ethernet print server, making my little lan
+ one of the few home networks to have it's own print server!
+
+ ``Microplex Systems Ltd. is a manufacturer of local and wide area
+ network communications equipment based in beautiful Vancouver, British
+ Columbia, Canada. Microplex's first products were synchronous wide
+ area network devices used in the mainframe communication networks. In
+ August 1991 Microplex introduced its first LAN product, the M200 print
+ server, the first high performance print server under US$1,000.''
+
+
+Tom Haapanen (tomh@metrics.com)
+
+ Tom sent me two 16 bit SMC ethernet cards to replace my ancient 8
+ bit ones. The performance is much better!
+
+ Software Metrics Inc. is a small custom software development and
+ consulting firm located in Waterloo, Ontario, Canada. We work
+ with a variety of environments (such as Windows, Windows NT and
+ Unix), tools and application areas, and can provide assistance for
+ development work ranging from a few days to to multiple man-year
+ projects. You can find more information at http://www.metrics.com/.
+
+
+Steve Kennedy (steve@gbnet.net)
+
+ Steve sent me 16Mb of ram so that I could install/test
+ NT3.5. I previous had only 8Mb ram in my test machine, which
+ wasn't enough to install a properly functioning copy of
+ NTAS. Being able to directly test NT3.5 allowed me to solve
+ several long standing NT<->Samba problems. Thanks Steve!
+
+John Terpstra (jht@aquasoft.com.au)
+
+ Aquasoft are a specialist consulting company whose Samba-using
+ customers span the world.
+
+ Aquasoft have been avid supporters of the Samba project. As a
+ token of appreciation Aquasoft have donated a 486DX2/66 PC with
+ a 540MB EIDE drive and 20MB RAM.
+
+ John has helped to isolate quite a few little glitches over time
+ and has managed to implement some very interesting installations
+ of Samba.
+
+ The donation of the new PC will make it possible to more fully
+ diagnose and observe the behaviour of Samba in conjuction with
+ other SMB protocol utilising systems.
+
+
+Timothy F. Sipples (tsipple@vnet.IBM.COM)
+Steve Withers (swithers@vnet.IBM.COM)
+
+ Tim and Steve from IBM organised a copy of the OS/2 developers
+ connection CD set for me, and gave lots of help in getting
+ OS/2 Warp installed. I hope this will allow me to finally fix
+ up those annoying OS/2 related Samba bugs that I have been
+ receiving reports of.
+
+Keith Wilkins (wilki1k@nectech.co.uk)
+
+ Keith from NEC in England very generously supplied a PC to
+ Luke Leighton to help with his nmbd development work. At the
+ same time Keith offered to help me with some new hardware, and
+ he sent me a pentium motherboard with 32MB of ram
+ onboard. This was very helpful as it allowed me to upgrade
+ my aging server to be a very powerful system. Thanks!
+
+
diff --git a/docs/announce b/docs/announce
new file mode 100755
index 00000000000..f5716556ba0
--- /dev/null
+++ b/docs/announce
@@ -0,0 +1,150 @@
+ Announcing Samba version 2.2
+ ============================
+
+What is Samba?
+--------------
+
+Samba is a SMB file server that runs on Unix and other operating
+systems. It allows these operating systems (currently Unix, Netware,
+OS/2 and AmigaDOS) to act as a file and print server for SMB and CIFS
+clients. There are many Lan-Manager compatible clients such as
+LanManager for DOS, Windows for Workgroups, Windows NT, Windows 95,
+Linux smbfs, OS/2, Pathworks and more.
+
+The package also includes a SMB client for accessing other SMB servers,
+and an advanced netbios/WINS nameserver for browsing support.
+
+
+What can it do for me?
+----------------------
+
+If you have any PCs running SMB clients, such as a PC running Windows
+for Workgroups, then you can mount file space or printers on a Samba
+host, so that directories, files and printers on the host are
+available on the PC.
+
+If you have any SMB servers such as Windows NT Server, Warp Server or
+Pathworks you may be able to replace them by or supplement them with
+Samba. One of Samba's big strengths is integration, so you can use it
+to tie together your Unix (or VMS etc) hosts and PC clients. If you
+are tired of the insecurity, expense and instability of PCNFS then Samba
+may be for you.
+
+The client part of the package will also allow you to attach to other
+SMB-based servers (such as windows NT and windows for workgroups) so
+that you can copy files to and from your unix host. The client also
+allows you to access a SMB printer (such as one attached to an OS/2 or
+WfWg server) from Unix, using an entry in /etc/printcap, or by
+explicitly specifying the command used to print files.
+
+
+What are its features?
+------------------------
+
+Samba supports many features that are not supported in other SMB
+implementations (all of which are commercial). These include host as
+well as username/password security, a client, automatic home directory
+exporting, automatic printer exporting, dead connection timeouts,
+umask support, guest connections, name mangling and hidden and system
+attribute mapping. Look at the FAQs included with the package for
+a full list of features.
+
+
+What's new since 2.0?
+---------------------
+
+Lots of stuff. See the change log and man pages for details.
+In particular, please check the WHATSNEW.txt file in the root directory
+of each release. This file has current change/update information.
+
+
+Where can I get a client for my PC?
+-----------------------------------
+
+There is a free client for MS-DOS based PCs available from
+ftp.microsoft.com in the directory bussys/Clients/MSCLIENT/. Please
+read the licencing information before downloading. The add-on 32-bit
+TCP/IP Windows for Workgroups client is also very good. Windows 95/98/ME,
+Windows NT/2000 and OS/2 come with suitable clients by default.
+
+
+What network protocols are supported?
+-------------------------------------
+
+Currently only TCP/IP is supported. There has been some discussion
+about ports to other protocols but nothing is yet available.
+
+There is a free TCP/IP implementation for Windows for Workgroups
+available from ftp.microsoft.com (it's small, fast and quite reliable).
+
+
+How much does it cost?
+----------------------
+
+Samba software is free software. It is available under the
+GNU Public licence in source code form at no cost. Please read the
+file COPYING that comes with the package for more information.
+
+
+What operating systems does it support?
+---------------------------------------
+
+The code has been written to be as portable as possible. It has been
+"ported" to many unixes, which mostly required changing only a few
+lines of code. It has been run (to my knowledge) on at least these
+unixes:
+
+Linux, SunOS, Solaris, SVR4, Ultrix, OSF1, AIX, BSDI, NetBSD,
+Sequent, HP-UX, SGI, FreeBSD, NeXT, ISC, A/UX, SCO, Intergraph,
+Silicon Graphics Inc., Domain/OS and DGUX.
+
+Some of these have received more testing than others. If it doesn't
+work with your unix then it should be easy to fix. It has also been ported
+to Netware, OS/2 and the Amiga. A VMS port is available too. See the web site
+for more details.
+
+
+Who wrote it?
+-------------
+
+Many people on the internet have contributed to the development of
+Samba. The maintainer and original author is Andrew Tridgell, but
+large parts of the package were contributed by several people from all
+over the world. Please look at the file `change-log' for information
+on who did what bits.
+
+
+Where can I get it?
+-------------------
+
+The package is available via anonymous ftp from samba.org in
+the directory pub/samba/.
+
+
+What about SMBServer?
+---------------------
+
+Samba used to be known as SMBServer, until it was pointed out that
+Syntax, who make a commercial Unix SMB based server, have trademarked
+that name. The name was then changed to Samba. Also, in 1992 a very
+early incarnation of Samba was distributed as nbserver.
+
+If you see any copies of nbserver or smbserver on ftp sites please let
+me or the ftp archive maintainer know, as I want to get them deleted.
+
+
+Where can I get more info?
+---------------------------
+
+Please join the mailing list if you want to discuss the development or
+use of Samba. To join the mailing list, please read the instructions
+at http://lists.samba.org/
+
+There is also often quite a bit of discussion about Samba on the
+newsgroup comp.protocols.smb.
+
+A WWW site with lots of Samba info can be found at
+http://samba.org/samba/
+
+The Samba Team (Contact: samba@samba.org)
+March 2001
diff --git a/docs/docbook/Makefile.in b/docs/docbook/Makefile.in
new file mode 100755
index 00000000000..7e5bca566de
--- /dev/null
+++ b/docs/docbook/Makefile.in
@@ -0,0 +1,383 @@
+#################################################################
+# Makefile.in for Samba Documentation
+# Authors: James Moore <jmoore@php.net>
+# Gerald Carter <jerry@samba.org>
+#
+# Please see http://www.samba.org/samba/cvs.html
+# for information on getting the latest
+# source and documentation source files.
+#
+
+# Autoconf Variables
+SRCDIR = @srcdir@
+JADE = @JADE@
+NSGMLS = @NSGMLS@
+SGMLSPL=@SGMLSPL@
+HTMLDOC=@HTMLDOC@
+PERL=@PERL@
+#CATALOG = @CATALOG@
+MANDIR=../manpages
+HTMLDIR=../htmldocs
+
+#Stylesheets and Dependicies
+SGML_SHARE=@SGML_SHARE@
+#SGML_CATALOG_FILES=$(SGML_CATALOG_FILES):./dbsgml/catalog
+HTML_STYLESHEET = $(srcdir)/stylesheets/html.dsl
+HTML_DEPS = $(srcdir)/stylesheets/html-common.dsl $(srcdir)/stylesheets/common.dsl
+
+MANPAGES=$(MANDIR)/findsmb.1 $(MANDIR)/smbclient.1 \
+ $(MANDIR)/smbspool.8 $(MANDIR)/lmhosts.5 \
+ $(MANDIR)/smbcontrol.1 $(MANDIR)/smbstatus.1 \
+ $(MANDIR)/make_smbcodepage.1 $(MANDIR)/smbd.8 \
+ $(MANDIR)/smbtar.1 $(MANDIR)/nmbd.8 $(MANDIR)/smbmnt.8 \
+ $(MANDIR)/smbumount.8 $(MANDIR)/nmblookup.1 \
+ $(MANDIR)/smbmount.8 $(MANDIR)/swat.8 $(MANDIR)/rpcclient.1 \
+ $(MANDIR)/smbpasswd.5 $(MANDIR)/testparm.1 $(MANDIR)/samba.7 \
+ $(MANDIR)/smbpasswd.8 $(MANDIR)/testprns.1 \
+ $(MANDIR)/smb.conf.5 $(MANDIR)/wbinfo.1 $(MANDIR)/pdbedit.8 \
+ $(MANDIR)/smbcacls.1 $(MANDIR)/smbsh.1 $(MANDIR)/winbindd.8 \
+ $(MANDIR)/make_unicodemap.1
+
+SGMLMANSRC=manpages/findsmb.1.sgml manpages/smbclient.1.sgml \
+ manpages/smbspool.8.sgml manpages/lmhosts.5.sgml \
+ manpages/smbcontrol.1.sgml manpages/smbstatus.1.sgml \
+ manpages/make_smbcodepage.1.sgml manpages/smbd.8.sgml \
+ manpages/smbtar.1.sgml manpages/nmbd.8.sgml manpages/smbmnt.8.sgml \
+ manpages/smbumount.8.sgml manpages/nmblookup.1.sgml \
+ manpages/smbmount.8.sgml manpages/swat.8.sgml \
+ manpages/rpcclient.1.sgml manpages/smbpasswd.5.sgml \
+ manpages/testparm.1.sgml manpages/samba.7.sgml \
+ manpages/smbpasswd.8.sgml manpages/testprns.1.sgml \
+ manpages/smb.conf.5.sgml manpages/pdbedit.8.sgml \
+ manpages/wbinfo.1.sgml manpages/smbcacls.1.sgml \
+ manpages/smbsh.1.sgml manpages/winbindd.8.sgml \
+ manpages/make_unicodemap.1.sgml
+
+HOWTOSRC=projdoc/DOMAIN_MEMBER.sgml projdoc/NT_Security.sgml \
+ projdoc/msdfs_setup.sgml projdoc/printer_driver2.sgml \
+ projdoc/UNIX_INSTALL.sgml projdoc/winbind.sgml projdoc/OS2-Client-HOWTO.sgml \
+ projdoc/Samba-PDC-HOWTO.sgml projdoc/ENCRYPTION.sgml \
+ projdoc/CVS-Access.sgml projdoc/Integrating-with-Windows.sgml \
+ projdoc/PAM-Authentication-And-Samba.sgml projdoc/Samba-LDAP-HOWTO.sgml \
+ projdoc/Samba-BDC-HOWTO.sgml projdoc/cups.sgml
+
+
+
+######################################################################
+# Make instructions
+######################################################################
+all:
+ @echo "Possible options to the Makefile include:"
+ @echo " all-docs - Force a rebuild of all documentation"
+ @echo " HOWTO - Build all individual HOWTOs in html format"
+ @echo " proj-doc - Build the Samba-HOWTO-Collection.[pdf|html] file"
+ @echo " man - Rebuild html and nroff versions of man pages as necessary"
+ @echo " syntax - Check the SGML/DocBook syntax of all source files"
+
+all-docs: HOWTO proj-doc man-all man-html-all
+
+syntax: $(SGMLMANSRC) projdoc/samba-doc.sgml
+ @echo Checking syntax of all SGML/DocBook source files...
+ @(for i in $?; do \
+ echo "$$i..."; \
+ $(NSGMLS) -sv $$i 2>&1 | grep -v "DTDDECL catalog entries are not supported" ; \
+ done)
+
+
+
+man: $(MANPAGES)
+
+HOWTO: $(HOWTOSRC)
+ @echo Building HOWTO pages...
+ @(for i in $?; do \
+ htmlfile=`echo $$i | sed 's,.*/,,' | sed "s/\.sgml/\.html/g"`; \
+ echo "Making $$htmlfile"; \
+ cat $$i | $(PERL) scripts/make-article.pl > /tmp/`echo $$i | sed 's,.*/,,'`; \
+ $(JADE) -t sgml -V nochunks -d $(SGML_SHARE)/dsssl/docbook/html/docbook.dsl \
+ -f /tmp/jade.log /tmp/`echo $$i | sed 's,.*/,,'` > ../htmldocs/$$htmlfile; \
+ cat /tmp/jade.log | grep -v DTDDECL; \
+ /bin/rm -f /tmp/jade.log /tmp/`echo $$i | sed 's,.*/,,'`; \
+ done)
+
+
+## I'm using htmldoc here to produc the PDF output. If you want
+## Postscript output, you can run
+##
+## sgmltools -b ps projdoc/samba-doc.sgml
+##
+proj-doc:
+ echo Building Samba-HOWTO-Collections...
+ @$(PERL) scripts/collateindex.pl -N -o projdoc/index.sgml
+ @$(JADE) -t sgml -V html-index -d $(SGML_SHARE)/dsssl/docbook/html/docbook.dsl projdoc/samba-doc.sgml
+ @$(PERL) scripts/collateindex.pl -o projdoc/index.sgml HTML.index
+ @/bin/rm HTML.index *.htm
+ @$(JADE) -t sgml -i html -V nochunks -d stylesheets/ldp.dsl\#html projdoc/samba-doc.sgml > samba-doc.html
+ @(cd scripts; ./ldp_print ../samba-doc.html)
+ @mv -f samba-doc.pdf ../Samba-HOWTO-Collection.pdf
+ @/bin/mv -f samba-doc.html ../htmldocs/Samba-HOWTO-Collection.html
+
+proj-doc-ps:
+ sgmltools -b ps projdoc/samba-doc.sgml
+ mv projdoc/samba-doc.ps .
+
+
+## generate all HTML man pages
+man-html-all: $(SGMLMANSRC)
+ @echo Building HTML formatted man pages...
+ @(for i in $?; do \
+ htmlfile=`echo $$i | sed 's,.*/,,' | sed "s/\.sgml/\.html/g"`; \
+ echo "Making $$htmlfile"; \
+ $(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html -f /tmp/jade.log $$i > ../htmldocs/$$htmlfile; \
+ cat /tmp/jade.log | grep -v DTDDECL; \
+ /bin/rm -f /tmp/jade.log; \
+ done)
+
+## generate all man pages
+man-all: $(SGMLMANSRC)
+ @echo Building man pages...
+ @(for i in $?; do \
+ manfile=`echo $$i | sed 's,.*/,,' | sed "s/\.sgml//g"`; \
+ echo "Making $$manfile"; \
+ $(NSGMLS) -f /tmp/docbook2x.log $$i | $(SGMLSPL) \
+ $(SGML_SHARE)/docbook2X/docbook2man-spec.pl; \
+ cat /tmp/docbook2x.log | grep -v DTDDECL; \
+ /bin/rm -f /tmp/docbook2x.log; \
+ cat $$manfile | $(PERL) scripts/strip-links.pl > $(MANDIR)/$$manfile; \
+ /bin/rm -f $$manfile; \
+ done)
+
+
+
+
+##
+## these rules are for building individual files
+##
+$(MANDIR)/findsmb.1: manpages/findsmb.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbclient.1: manpages/smbclient.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbspool.8: manpages/smbspool.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/lmhosts.5: manpages/lmhosts.5.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbcontrol.1: manpages/smbcontrol.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbstatus.1: manpages/smbstatus.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/make_smbcodepage.1: manpages/make_smbcodepage.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/make_unicodemap.1: manpages/make_unicodemap.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbd.8: manpages/smbd.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbtar.1: manpages/smbtar.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/nmbd.8: manpages/nmbd.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbmnt.8: manpages/smbmnt.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbumount.8: manpages/smbumount.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/nmblookup.1: manpages/nmblookup.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbmount.8: manpages/smbmount.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/swat.8: manpages/swat.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/rpcclient.1: manpages/rpcclient.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbpasswd.5: manpages/smbpasswd.5.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/testparm.1: manpages/testparm.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/samba.7: manpages/samba.7.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbpasswd.8: manpages/smbpasswd.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/testprns.1: manpages/testprns.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smb.conf.5: manpages/smb.conf.5.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/wbinfo.1: manpages/wbinfo.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbcacls.1: manpages/smbcacls.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/smbsh.1 : manpages/smbsh.1.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+$(MANDIR)/winbindd.8: manpages/winbindd.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+
+$(MANDIR)/pdbedit.8: manpages/pdbedit.8.sgml
+ @echo "Making $@"
+ @$(NSGMLS) $< | $(SGMLSPL) $(SGML_SHARE)/docbook2X/docbook2man-spec.pl
+ @cat `echo $@ | sed 's,.*/,,'` | $(PERL) scripts/strip-links.pl > $@
+ @/bin/rm -f `echo $@ | sed 's,.*/,,'`
+ @echo "Making HTML version of $@"
+ @$(JADE) -t sgml -i html -V nochunks -d ./stylesheets/ldp.dsl\#html $< > $(HTMLDIR)/`echo $< | sed 's,.*/,,'| sed "s/\.sgml/\.html/g"`
+
+
+## Clean Rule
+clean:
+ /bin/rm -f manpage.*
diff --git a/docs/docbook/configure b/docs/docbook/configure
new file mode 100755
index 00000000000..73d54a817f6
--- /dev/null
+++ b/docs/docbook/configure
@@ -0,0 +1,1065 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-sgml-share=DIR change the default location of SGML stylesheets"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=global.ent
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+## check for the necesary install tools
+# Extract the first word of "openjade", so it can be a program name with args.
+set dummy openjade; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:532: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_JADE'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$JADE" in
+ /*)
+ ac_cv_path_JADE="$JADE" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_JADE="$JADE" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_JADE="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+JADE="$ac_cv_path_JADE"
+if test -n "$JADE"; then
+ echo "$ac_t""$JADE" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$JADE"; then
+ # Extract the first word of "jade", so it can be a program name with args.
+set dummy jade; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:569: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_JADE'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$JADE" in
+ /*)
+ ac_cv_path_JADE="$JADE" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_JADE="$JADE" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_JADE="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+JADE="$ac_cv_path_JADE"
+if test -n "$JADE"; then
+ echo "$ac_t""$JADE" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "nsgmls", so it can be a program name with args.
+set dummy nsgmls; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:604: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NSGMLS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$NSGMLS" in
+ /*)
+ ac_cv_path_NSGMLS="$NSGMLS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_NSGMLS="$NSGMLS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_NSGMLS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+NSGMLS="$ac_cv_path_NSGMLS"
+if test -n "$NSGMLS"; then
+ echo "$ac_t""$NSGMLS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ # Extract the first word of "onsgmls", so it can be a program name with args.
+set dummy onsgmls; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:640: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NSGMLS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$NSGMLS" in
+ /*)
+ ac_cv_path_NSGMLS="$NSGMLS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_NSGMLS="$NSGMLS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_NSGMLS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+NSGMLS="$ac_cv_path_NSGMLS"
+if test -n "$NSGMLS"; then
+ echo "$ac_t""$NSGMLS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+# Extract the first word of "htmldoc", so it can be a program name with args.
+set dummy htmldoc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:677: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_HTMLDOC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$HTMLDOC" in
+ /*)
+ ac_cv_path_HTMLDOC="$HTMLDOC" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_HTMLDOC="$HTMLDOC" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_HTMLDOC="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+HTMLDOC="$ac_cv_path_HTMLDOC"
+if test -n "$HTMLDOC"; then
+ echo "$ac_t""$HTMLDOC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "sgmlspl", so it can be a program name with args.
+set dummy sgmlspl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:712: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_SGMLSPL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$SGMLSPL" in
+ /*)
+ ac_cv_path_SGMLSPL="$SGMLSPL" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_SGMLSPL="$SGMLSPL" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_SGMLSPL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+SGMLSPL="$ac_cv_path_SGMLSPL"
+if test -n "$SGMLSPL"; then
+ echo "$ac_t""$SGMLSPL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:747: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$PERL" in
+ /*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_PERL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+PERL="$ac_cv_path_PERL"
+if test -n "$PERL"; then
+ echo "$ac_t""$PERL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+SGML_SHARE="/usr/local/share/sgml"
+
+# Check whether --with-sgml-share or --without-sgml-share was given.
+if test "${with_sgml_share+set}" = set; then
+ withval="$with_sgml_share"
+ case "$withval" in
+ no) SGML_SHARE=""
+ ;;
+ yes)
+ ;;
+ /*|\\*)
+ SGML_SHARE="$withval"
+ ;;
+ *)
+ SGML_SHARE="/$withval"
+ ;;
+esac
+
+fi
+
+# The Makefile requires docbook2X in the share/sgml directory
+if ! test -f $SGML_SHARE/docbook2X/docbook2man-spec.pl ; then
+ { echo "configure: error: "Unable to find dockbook2X. Make sure it is installed and that the sgml-share path is correct."" 1>&2; exit 1; }
+fi
+
+
+DOC_BUILD_DATE=`date '+%d-%m-%Y'`
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile stylesheets/ldp.dsl " | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@JADE@%$JADE%g
+s%@NSGMLS@%$NSGMLS%g
+s%@HTMLDOC@%$HTMLDOC%g
+s%@SGMLSPL@%$SGMLSPL%g
+s%@PERL@%$PERL%g
+s%@SGML_SHARE@%$SGML_SHARE%g
+s%@DOC_BUILD_DATE@%$DOC_BUILD_DATE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile stylesheets/ldp.dsl "}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/docs/docbook/configure.in b/docs/docbook/configure.in
new file mode 100755
index 00000000000..ad0613f2be8
--- /dev/null
+++ b/docs/docbook/configure.in
@@ -0,0 +1,49 @@
+AC_INIT(global.ent)
+
+## check for the necesary install tools
+## Openjade includes 'onsgmls' while
+## the older jade package includes 'nsgmls'
+AC_PATH_PROG(JADE,openjade)
+
+if test -z "$JADE"; then
+ AC_PATH_PROG(JADE,jade)
+ AC_PATH_PROG(NSGMLS, nsgmls)
+else
+ AC_PATH_PROG(NSGMLS, onsgmls)
+fi
+
+AC_PATH_PROG(HTMLDOC, htmldoc)
+AC_PATH_PROG(SGMLSPL, sgmlspl)
+AC_PATH_PROG(PERL, perl)
+
+dnl ----------------------------------------------------------------
+dnl --with-sgml-share
+SGML_SHARE="/usr/local/share/sgml"
+
+AC_ARG_WITH(sgml-share,
+[ --with-sgml-share=DIR change the default location of SGML stylesheets],
+[case "$withval" in
+ no) SGML_SHARE=""
+ ;;
+ yes)
+ ;;
+ /*|\\*)
+ SGML_SHARE="$withval"
+ ;;
+ *)
+ SGML_SHARE="/$withval"
+ ;;
+esac
+])dnl
+
+# The Makefile requires docbook2X in the share/sgml directory
+if [ ! test -f $SGML_SHARE/docbook2X/docbook2man-spec.pl ]; then
+ AC_MSG_ERROR("Unable to find dockbook2X. Make sure it is installed and that the sgml-share path is correct.")
+fi
+
+AC_SUBST(SGML_SHARE)dnl
+
+DOC_BUILD_DATE=`date '+%d-%m-%Y'`
+AC_SUBST(DOC_BUILD_DATE)
+
+AC_OUTPUT( Makefile stylesheets/ldp.dsl )
diff --git a/docs/docbook/dbsgml/40chg.txt b/docs/docbook/dbsgml/40chg.txt
new file mode 100755
index 00000000000..2d2467d9ebc
--- /dev/null
+++ b/docs/docbook/dbsgml/40chg.txt
@@ -0,0 +1,45 @@
+19 June 2000
+
+Changes from DocBook V3.1 to DocBook V4.1:
+
+Markup:
+
+- RFE 17: Added a common attribute 'Condition' for generic effectivity
+- RFE 38: The nav.class elements (ToC|LoT|Index|Glossary|Bibliography) are
+ now allowed at the beginning and end of components and sections
+- RFE 58: The 'optmult' and 'reqmult' attribute values have been
+ removed from Group
+- RFE 65: Added several class attribute values to Filename and SystemItem
+ at the request of the Linux community
+- RFE 73: Removed BookBiblio and SeriesInfo
+- RFE 81: Added SidebarInfo to Sidebar
+- RFE 87: Added 'xmlpi' and 'emptytag' as class values of SGMLTag
+- RFE 92: Added 'CO' to Synopsis and LiteralLayout
+- RFE 99: Added SimpleMsgEntry as an alternative to MsgEntry in order
+ to provide a simpler MsgSet construct
+- RFE 103: Added RevDescription as an alternative to RevRemark in
+ RevHistory; this allows longer descriptive text in a revision
+- RFE 104: Added 'Specification' to the list of document classes on Article
+- RFE 108: Allow admonitions in Answers
+- RFE 110: Allow a RevHistory on QandAEntry
+- RFE 115: Allow optional Title on OrderedList and ItemizedList
+- RFE 116: Added LineNumbering attribute to linespecific environments for
+ presentation of line numbers
+- Added a common attribute 'Security' for effectivity
+- Added synopsis markup for modern programming languages (e.g, object
+ oriented languages like Java, C++, and IDL)
+- Renamed DocInfo to PrefaceInfo, ChapterInfo, AppendixInfo, etc.
+- Comment was renamed Remark
+- InterfaceDefinition was removed
+
+Other:
+
+- RFE 88: Added PEs to include/ignore dbnotn.mod and dbcent.mod
+- RFE 102: Fixed some outstanding namecase problems
+- RFE 105: Added PNG notation
+- RFE 106: Removed some odd *.content PEs that interfered with
+ customization layers
+- RFE 109: Added FPI to content of dbgenent.mod (for consistency)
+- RFE 111: Added the Euro symbol
+- Fixed bug in cals-tbl.dtd; a model group was used for the element
+ declaration, but the attlist declaration used "Table" literally.
diff --git a/docs/docbook/dbsgml/41chg.txt b/docs/docbook/dbsgml/41chg.txt
new file mode 100755
index 00000000000..d2a91478878
--- /dev/null
+++ b/docs/docbook/dbsgml/41chg.txt
@@ -0,0 +1,7 @@
+19 June 2000
+
+Changes from DocBook V4.0 to DocBook V4.1:
+
+No user-visible changes; removed some 4.0 future use comments that had
+accidentally been left in the DTD and fixed a couple of incorrect FPIs.
+See 40chg.txt for a list of the significant changes.
diff --git a/docs/docbook/dbsgml/50issues.txt b/docs/docbook/dbsgml/50issues.txt
new file mode 100755
index 00000000000..31497420f0d
--- /dev/null
+++ b/docs/docbook/dbsgml/50issues.txt
@@ -0,0 +1,39 @@
+19 June 2000
+
+Backwards-incompatible changes to DocBook that are planned for V5.0:
+
+- DocBook V5.0 will be an XML DTD. This will require a wide range of
+ changes. As a result, DocBook V5.0 will more closely resemble
+ The XML version of DocBook V4.1 than the SGML version.
+
+- Parameter entity reorganization may greatly reduce many
+ content models. The goal of this effort is to remove a large
+ number of spurious elements that snuck into content models
+ during the first PE reorg, in practice these changes should have
+ very little "real world" impact.
+
+- The Coords attribute will be removed from AreaSet.
+
+- ArtHeader will be dropped from BiblioEntry
+
+- Contents attribute will be removed from BookInfo and SetInfo
+
+- The %indexdivcomponent.mix; will be restricted. Numbered figures
+ and other elements inappropriate for an Index or SetIndex will be
+ removed.
+
+- RevHistory will be removed from GlossTerm
+
+- Constant Class will be removed from SystemItem
+
+- Graphic and InlineGraphic will be removed
+
+- Tables will be restricted from full CALS to the OASIS Exchange model
+
+- An experimental XML Schema version of DocBook 5.0 will be
+ produced in parallel with the DTD version. It will be
+ backwards-incompatible in an unspecified number of ways. The
+ goal of the effort will be that most DocBook documents that
+ validate under the DTD will also validate under the Schema,
+ but the committee does not feel bound to guarantee this
+ condition.
diff --git a/docs/docbook/dbsgml/ChangeLog b/docs/docbook/dbsgml/ChangeLog
new file mode 100755
index 00000000000..c4673db15a9
--- /dev/null
+++ b/docs/docbook/dbsgml/ChangeLog
@@ -0,0 +1,85 @@
+2000-06-19 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt: Added notes about comment and interfacedefinition
+
+ * 41chg.txt: New file.
+
+ * 50issues.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, readme.txt:
+ Updated version numbers to 4.1
+
+ * dbhier.mod, dbpool.mod: Removed 4.0 future use comments
+
+ * docbook.cat: Fixed version number in comment
+
+ * docbook.dtd: DocBook V4.1 released.
+
+2000-05-18 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Removed references to beta6
+
+ * docbook.dtd: DocBook V4.0 released.
+
+2000-04-10 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Updated release date and version to 4.0beta6
+
+ * dbpool.mod: Added support for EBNF hook; fixed equation content bug
+
+2000-04-03 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt: Added note about renaming DocInfo to *Info.
+
+ * 40chg.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Updated version numbers
+
+2000-03-24 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Updated version numbers
+
+ * 50issues.txt: Added note about PE reorg
+
+ * dbefsyn.mod: Removed
+
+ * dbpool.mod: Removed ELEMENT from comments to ease text searching of the DTD.
+ Merged dbefsyn.mod into dbpool.mod
+ Added Modifier as an optional element at the end of MethodSynopsis
+ and MethodParam.
+
+2000-03-07 Norman Walsh <ndw@nwalsh.com>
+
+ * 40chg.txt, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Updated internal versions to beta3
+
+2000-03-03 Norman Walsh <ndw@nwalsh.com>
+
+ * dbpool.mod: Removed erroneous comment about inline synopses
+
+2000-03-02 Norman Walsh <ndw@nwalsh.com>
+
+ * 30chg.txt, 31chg.txt, 40issues.txt, 50issues.txt, announce.txt, cals-tbl.dtd, dbcent.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Version 3.1
+
+ * 30chg.txt, 40issues.txt, announce.txt, cals-tbl.dtd, dbgenent.mod, dbhier.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd:
+ branches: 1.1.1;
+ Initial revision
+
+ * 30chg.txt, 40issues.txt, announce.txt, cals-tbl.dtd, dbgenent.mod, dbhier.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd:
+ New file.
+
+ * 31chg.txt, 40chg.txt, 40issues.txt, 50issues.txt, cals-tbl.dtd, dbcent.mod, dbefsyn.mod, dbgenent.mod, dbhier.mod, dbnotn.mod, dbpool.mod, docbook.cat, docbook.dcl, docbook.dtd, readme.txt:
+ Version 4.0beta2
+
+ * 50issues.txt: Added warning about exchange table model
+
+ * dbefsyn.mod, dbpool.mod: Added ooclass, oointerface, and ooexception as wrappers for modifiers
+ and names in classsynopsis. Also allow them inline.
+
+ Fixed SGML PE parsing problem with hook PEs.
+
+ * dbhier.mod, dbpool.mod: Added hook PEs for future module extension
+
+ * dbpool.mod, docbook.dtd: Removed reference to sgml-features PE
+
diff --git a/docs/docbook/dbsgml/cals-tbl.dtd b/docs/docbook/dbsgml/cals-tbl.dtd
new file mode 100755
index 00000000000..78c7d5a3ae1
--- /dev/null
+++ b/docs/docbook/dbsgml/cals-tbl.dtd
@@ -0,0 +1,330 @@
+<!-- CALS TABLE MODEL DECLARATION MODULE -->
+
+<!-- This set of declarations defines the CALS Table Model as of the
+ date shown in the Formal Public Identifier (FPI) for this entity.
+
+ This set of declarations may be referred to using a public external
+ entity declaration and reference as shown in the following two lines:
+
+<!ENTITY % calstbls PUBLIC "-//USA-DOD//DTD Table Model 951010//EN">
+%calstbls;
+
+ If various parameter entities used within this set of declarations
+ are to be given non-default values, the appropriate declarations
+ should be given before calling in this package (i.e., before the
+ "%calstbls;" reference).
+
+ NOTE: This set of declarations assumes a NAMELEN of 32 as is used in
+ the standard CALS defined SGML declaration.
+-->
+
+<!-- This entity includes a set of element and attribute declarations
+ that partially defines the CALS table model. However, the model
+ is not well-defined without the accompanying natural language
+ description of the semantics (meanings) of these various elements,
+ attributes, and attribute values. The semantic writeup, available
+ as a separate entity, should be used in conjunction with this entity.
+-->
+
+<!-- In order to use the CALS table model, various parameter entity
+ declarations are required. A brief description is as follows:
+
+ ENTITY NAME WHERE USED WHAT IT IS
+
+ %bodyatt In ATTLIST of: Additional (non-table related)
+ table element(s) attributes on the overall
+ (wrapper) table element(s)
+
+ %secur In ATTLIST of: Additional (non-table related)
+ table element(s) attributes on all the listed
+ <tgroup> elements
+ <tbody>
+ table head and foot element(s)
+ <row>
+ <entrytbl>
+ <entry>
+
+ %yesorno In ATTLIST of: An attribute declared value
+ almost all elements for a "boolean" attribute
+
+ %titles In content model of: The "title" part of the model
+ table element(s) group for the table element(s)
+
+ %paracon In content model of: The "text" (data content) part
+ <entry> of the model group for <entry>
+
+ %tbl.table.name In declaration of: The name(s) of the "table"
+ table element(s) element(s)
+
+ %tbl.table-titles.mdl In content model of: The model group for the title
+ table elements(s) part of the content model for
+ table element(s)
+
+ %tbl.table-main.mdl In content model of: The model group for the main part
+ table elements(s) (not including titles) of the
+ content model for table element(s)
+
+ %tbl.table.mdl In content model of: The model group for the content
+ table elements(s) model for table element(s),
+ often (and by default) defined
+ in terms of %tbl.table-titles.mdl
+ and %tbl.table-main.mdl
+
+ %tbl.table.excep In content model of: The exceptions for the content
+ table element(s) model for table element(s)
+
+ %tbl.table.att In ATTLIST of: Additional attributes on the
+ table element(s) table element(s)
+
+ %tbl.tgroup.mdl In content model of: The model group for the content
+ <tgroup> model for <tgroup>
+
+ %tbl.tgroup.att In ATTLIST of: Additional attributes on the
+ <tgroup> <tgroup> and <entrytbl> elements
+ <entrytbl>
+
+ %tbl.hdft.name In declaration of: The name(s) of the table
+ head/foot element(s) head and foot element(s)
+
+ %tbl.hdft.mdl In content model of: The model group for the content
+ head/foot element(s) model for head/foot element(s)
+
+ %tbl.hdft.excep In content model of: The exceptions for the content
+ head/foot element(s) model for head/foot element(s)
+
+ %tbl.row.mdl In content model of: The model group for the content
+ <row> model for <row>
+
+ %tbl.row.excep In content model of: The exceptions for the content
+ <row> model for <row>
+
+ %tbl.entrytbl.mdl In content model of: The model group for the content
+ <entrytbl> model for <entrytbl>
+
+ %tbl.entrytbl.excep In content model of: The exceptions for the content
+ <entrytbl> model for <entrytbl>
+
+ %tbl.entry.mdl In content model of: The model group for the content
+ <entry> model for <entry>
+
+ %tbl.entry.excep In content model of: The exceptions for the content
+ <entry> model for <entry>
+
+ If any of these parameter entities are not declared before this set of
+ declarations is referenced, this set of declarations will make the
+ following default definitions for all of these have parameter entities.
+-->
+
+<!-- These definitions are not directly related to the table model, but are
+ used in the default CALS table model and are usually defined elsewhere
+ (and prior to the inclusion of this table module) in a CALS DTD. -->
+
+<!ENTITY % bodyatt "">
+<!ENTITY % secur "">
+<!ENTITY % yesorno 'NUMBER' -- no if zero(s),
+ yes if any other digits value -->
+<!ENTITY % titles 'title?'>
+<!ENTITY % paracon '#PCDATA' -- default for use in entry content -->
+
+<!--
+The parameter entities as defined below provide the CALS table model
+as published (as part of the Example DTD) in MIL-HDBK-28001.
+
+These following declarations provide the CALS-compliant default definitions
+for these entities. However, these entities can and should be redefined
+(by giving the appropriate parameter entity declaration(s) prior to the
+reference to this Table Model declaration set entity) to fit the needs
+of the current application.
+-->
+
+<!ENTITY % tbl.table.name "(table|chart)">
+<!ENTITY % tbl.table-titles.mdl "%titles,">
+<!ENTITY % tbl.table-main.mdl "(tgroup+|graphic+)">
+<!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;">
+<!ENTITY % tbl.table.excep "-(table|chart|figure)">
+<!ENTITY % tbl.table.att '
+ tabstyle NMTOKEN #IMPLIED
+ tocentry %yesorno; #IMPLIED
+ shortentry %yesorno; #IMPLIED
+ orient (port|land) #IMPLIED
+ pgwide %yesorno; #IMPLIED '>
+<!ENTITY % tbl.tgroup.mdl "colspec*,spanspec*,thead?,tfoot?,tbody">
+<!ENTITY % tbl.tgroup.att '
+ tgroupstyle NMTOKEN #IMPLIED '>
+<!ENTITY % tbl.hdft.name "(thead|tfoot)">
+<!ENTITY % tbl.hdft.mdl "colspec*,row+">
+<!ENTITY % tbl.hdft.excep "-(entrytbl)">
+<!ENTITY % tbl.row.mdl "(entry|entrytbl)+">
+<!ENTITY % tbl.row.excep "-(pgbrk)">
+<!ENTITY % tbl.entrytbl.mdl "colspec*,spanspec*,thead?,tbody">
+<!ENTITY % tbl.entrytbl.excep "-(entrytbl|pgbrk)">
+<!ENTITY % tbl.entry.mdl "(para|warning|caution|note|legend|%paracon;)*">
+<!ENTITY % tbl.entry.excep "-(pgbrk)">
+
+<!-- ===== Element and attribute declarations follow. ===== -->
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % tbl.table.name "(table|chart)"
+ ENTITY % tbl.table-titles.mdl "%titles,"
+ ENTITY % tbl.table-main.mdl "(tgroup+|graphic+)"
+ ENTITY % tbl.table.mdl "%tbl.table-titles; %tbl.table-main.mdl;"
+ ENTITY % tbl.table.excep "-(table|chart|figure)"
+ ENTITY % tbl.table.att '
+ tabstyle NMTOKEN #IMPLIED
+ tocentry %yesorno; #IMPLIED
+ shortentry %yesorno; #IMPLIED
+ orient (port|land) #IMPLIED
+ pgwide %yesorno; #IMPLIED '
+-->
+
+<!ELEMENT %tbl.table.name; - - (%tbl.table.mdl;) %tbl.table.excep; >
+
+<!ATTLIST %tbl.table.name;
+ frame (top|bottom|topbot|all|sides|none) #IMPLIED
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ %tbl.table.att;
+ %bodyatt;
+ %secur;
+>
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % tbl.tgroup.mdl "colspec*,spanspec*,thead?,tfoot?,tbody"
+ ENTITY % tbl.tgroup.att '
+ tgroupstyle NMTOKEN #IMPLIED '
+-->
+
+<!ELEMENT tgroup - O (%tbl.tgroup.mdl;) >
+
+<!ATTLIST tgroup
+ cols NUMBER #REQUIRED
+ %tbl.tgroup.att;
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ align (left|right|center|justify|char) #IMPLIED
+ char CDATA #IMPLIED
+ charoff NUTOKEN #IMPLIED
+ %secur;
+>
+
+<!ELEMENT colspec - O EMPTY >
+
+<!ATTLIST colspec
+ colnum NUMBER #IMPLIED
+ colname NMTOKEN #IMPLIED
+ colwidth CDATA #IMPLIED
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ align (left|right|center|justify|char) #IMPLIED
+ char CDATA #IMPLIED
+ charoff NUTOKEN #IMPLIED
+>
+
+<!ELEMENT spanspec - O EMPTY >
+
+<!ATTLIST spanspec
+ namest NMTOKEN #REQUIRED
+ nameend NMTOKEN #REQUIRED
+ spanname NMTOKEN #REQUIRED
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ align (left|right|center|justify|char) #IMPLIED
+ char CDATA #IMPLIED
+ charoff NUTOKEN #IMPLIED
+>
+
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % tbl.hdft.name "(thead|tfoot)"
+ ENTITY % tbl.hdft.mdl "colspec*,row+"
+ ENTITY % tbl.hdft.excep "-(entrytbl)"
+-->
+
+<!ELEMENT %tbl.hdft.name; - O (%tbl.hdft.mdl;) %tbl.hdft.excep;>
+
+<!ATTLIST %tbl.hdft.name;
+ valign (top|middle|bottom) #IMPLIED
+ %secur;
+>
+
+
+<!ELEMENT tbody - O (row+)>
+
+<!ATTLIST tbody
+ valign (top|middle|bottom) #IMPLIED
+ %secur;
+>
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % tbl.row.mdl "(entry|entrytbl)+"
+ ENTITY % tbl.row.excep "-(pgbrk)"
+-->
+
+<!ELEMENT row - O (%tbl.row.mdl;) %tbl.row.excep;>
+
+<!ATTLIST row
+ rowsep %yesorno; #IMPLIED
+ valign (top|middle|bottom) #IMPLIED
+ %secur;
+>
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % tbl.entrytbl.mdl "colspec*,spanspec*,thead?,tbody"
+ ENTITY % tbl.entrytbl.excep "-(entrytbl|pgbrk)"
+ ENTITY % tbl.tgroup.att '
+ tgroupstyle NMTOKEN #IMPLIED '
+-->
+
+<!ELEMENT entrytbl - - (%tbl.entrytbl.mdl) %tbl.entrytbl.excep; >
+
+<!ATTLIST entrytbl
+ cols NUMBER #REQUIRED
+ %tbl.tgroup.att;
+ colname NMTOKEN #IMPLIED
+ spanname NMTOKEN #IMPLIED
+ namest NMTOKEN #IMPLIED
+ nameend NMTOKEN #IMPLIED
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ align (left|right|center|justify|char) #IMPLIED
+ char CDATA #IMPLIED
+ charoff NUTOKEN #IMPLIED
+ %secur;
+>
+
+
+<!--
+ Default declarations previously defined in this entity and
+ referenced below include:
+ ENTITY % paracon "#PCDATA"
+ ENTITY % tbl.entry.mdl "(para|warning|caution|note|legend|%paracon;)*"
+ ENTITY % tbl.entry.excep "-(pgbrk)"
+-->
+
+<!ELEMENT entry - O (%tbl.entry.mdl;) %tbl.entry.excep; >
+
+<!ATTLIST entry
+ colname NMTOKEN #IMPLIED
+ namest NMTOKEN #IMPLIED
+ nameend NMTOKEN #IMPLIED
+ spanname NMTOKEN #IMPLIED
+ morerows NUMBER #IMPLIED
+ colsep %yesorno; #IMPLIED
+ rowsep %yesorno; #IMPLIED
+ align (left|right|center|justify|char) #IMPLIED
+ char CDATA #IMPLIED
+ charoff NUTOKEN #IMPLIED
+ rotate %yesorno; #IMPLIED
+ valign (top|middle|bottom) #IMPLIED
+ %secur;
+>
diff --git a/docs/docbook/dbsgml/catalog b/docs/docbook/dbsgml/catalog
new file mode 100755
index 00000000000..521e8201c8c
--- /dev/null
+++ b/docs/docbook/dbsgml/catalog
@@ -0,0 +1,63 @@
+ -- ...................................................................... --
+ -- Catalog data for DocBook V4.1 ........................................ --
+ -- File docbook.cat ..................................................... --
+
+ -- Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/.
+ --
+
+ -- This is the catalog data file for DocBook V4.1. It is provided as
+ a convenience in building your own catalog files. You need not use
+ the filenames listed here, and need not use the filename method of
+ identifying storage objects at all. See the documentation for
+ detailed information on the files associated with the DocBook DTD.
+ See SGML Open Technical Resolution 9401 for detailed information
+ on supplying and using catalog data.
+ --
+
+ -- ...................................................................... --
+ -- SGML declaration associated with DocBook ............................. --
+
+DTDDECL "-//OASIS//DTD DocBook V4.1//EN" "docbook.dcl"
+
+ -- ...................................................................... --
+ -- DocBook driver file .................................................. --
+
+PUBLIC "-//OASIS//DTD DocBook V4.1//EN" "docbook.dtd"
+
+ -- ...................................................................... --
+ -- DocBook modules ...................................................... --
+
+PUBLIC "-//USA-DOD//DTD Table Model 951010//EN" "cals-tbl.dtd"
+PUBLIC "-//OASIS//ELEMENTS DocBook Information Pool V4.1//EN" "dbpool.mod"
+PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.1//EN" "dbhier.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.1//EN" "dbgenent.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.1//EN" "dbnotn.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.1//EN" "dbcent.mod"
+
+ -- ...................................................................... --
+ -- ISO entity sets ...................................................... --
+
+PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN" "ent/ISOdia"
+PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN" "ent/ISOnum"
+PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN" "ent/ISOpub"
+PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN" "ent/ISOtech"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN" "ent/ISOlat1"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN" "ent/ISOlat2"
+PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN" "ent/ISOgrk1"
+PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN" "ent/ISOgrk2"
+PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN" "ent/ISOgrk3"
+PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN" "ent/ISOgrk4"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN" "ent/ISOamsa"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN" "ent/ISOamsb"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN" "ent/ISOamsc"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN" "ent/ISOamsn"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN" "ent/ISOamso"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN" "ent/ISOamsr"
+PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN" "ent/ISObox"
+PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN" "ent/ISOcyr1"
+PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN" "ent/ISOcyr2"
+
+ -- End of catalog data for DocBook V4.1 ................................. --
+ -- ...................................................................... --
diff --git a/docs/docbook/dbsgml/dbcent.mod b/docs/docbook/dbsgml/dbcent.mod
new file mode 100755
index 00000000000..3c213d8a53f
--- /dev/null
+++ b/docs/docbook/dbsgml/dbcent.mod
@@ -0,0 +1,181 @@
+<!-- ...................................................................... -->
+<!-- DocBook character entities module V4.1 ............................... -->
+<!-- File dbcent.mod ...................................................... -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ $Id: dbcent.mod,v 1.1.2.1 2001/02/28 19:05:00 jerry Exp $
+
+ Permission to use, copy, modify and distribute the DocBook DTD and
+ its accompanying documentation for any purpose and without fee is
+ hereby granted in perpetuity, provided that the above copyright
+ notice and this paragraph appear in all copies. The copyright
+ holders make no representation about the suitability of the DTD for
+ any purpose. It is provided "as is" without expressed or implied
+ warranty.
+
+ If you modify the DocBook DTD in any way, except for declaring and
+ referencing additional sets of general entities and declaring
+ additional notations, label your DTD as a variant of DocBook. See
+ the maintenance documentation for more information.
+
+ Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/docbook/.
+-->
+
+<!-- ...................................................................... -->
+
+<!-- This module contains the entity declarations for the standard ISO
+ entity sets used by DocBook.
+
+ In DTD driver files referring to this module, please use an entity
+ declaration that uses the public identifier shown below:
+
+ <!ENTITY % dbcent PUBLIC
+ "-//OASIS//ENTITIES DocBook Character Entities V4.1//EN">
+ %dbcent;
+
+ See the documentation for detailed information on the parameter
+ entity and module scheme used in DocBook, customizing DocBook and
+ planning for interchange, and changes made since the last release
+ of DocBook.
+-->
+
+<!-- ...................................................................... -->
+
+<!ENTITY % ISOamsa.module "INCLUDE">
+<![ %ISOamsa.module; [
+<!ENTITY % ISOamsa PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN">
+%ISOamsa;
+<!--end of ISOamsa.module-->]]>
+
+<!ENTITY % ISOamsb.module "INCLUDE">
+<![ %ISOamsb.module; [
+<!ENTITY % ISOamsb PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN">
+%ISOamsb;
+<!--end of ISOamsb.module-->]]>
+
+<!ENTITY % ISOamsc.module "INCLUDE">
+<![ %ISOamsc.module; [
+<!ENTITY % ISOamsc PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN">
+%ISOamsc;
+<!--end of ISOamsc.module-->]]>
+
+<!ENTITY % ISOamsn.module "INCLUDE">
+<![ %ISOamsn.module; [
+<!ENTITY % ISOamsn PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN">
+%ISOamsn;
+<!--end of ISOamsn.module-->]]>
+
+<!ENTITY % ISOamso.module "INCLUDE">
+<![ %ISOamso.module; [
+<!ENTITY % ISOamso PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN">
+%ISOamso;
+<!--end of ISOamso.module-->]]>
+
+<!ENTITY % ISOamsr.module "INCLUDE">
+<![ %ISOamsr.module; [
+<!ENTITY % ISOamsr PUBLIC
+"ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN">
+%ISOamsr;
+<!--end of ISOamsr.module-->]]>
+
+<!ENTITY % ISObox.module "INCLUDE">
+<![ %ISObox.module; [
+<!ENTITY % ISObox PUBLIC
+"ISO 8879:1986//ENTITIES Box and Line Drawing//EN">
+%ISObox;
+<!--end of ISObox.module-->]]>
+
+<!ENTITY % ISOcyr1.module "INCLUDE">
+<![ %ISOcyr1.module; [
+<!ENTITY % ISOcyr1 PUBLIC
+"ISO 8879:1986//ENTITIES Russian Cyrillic//EN">
+%ISOcyr1;
+<!--end of ISOcyr1.module-->]]>
+
+<!ENTITY % ISOcyr2.module "INCLUDE">
+<![ %ISOcyr2.module; [
+<!ENTITY % ISOcyr2 PUBLIC
+"ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN">
+%ISOcyr2;
+<!--end of ISOcyr2.module-->]]>
+
+<!ENTITY % ISOdia.module "INCLUDE">
+<![ %ISOdia.module; [
+<!ENTITY % ISOdia PUBLIC
+"ISO 8879:1986//ENTITIES Diacritical Marks//EN">
+%ISOdia;
+<!--end of ISOdia.module-->]]>
+
+<!ENTITY % ISOgrk1.module "INCLUDE">
+<![ %ISOgrk1.module; [
+<!ENTITY % ISOgrk1 PUBLIC
+"ISO 8879:1986//ENTITIES Greek Letters//EN">
+%ISOgrk1;
+<!--end of ISOgrk1.module-->]]>
+
+<!ENTITY % ISOgrk2.module "INCLUDE">
+<![ %ISOgrk2.module; [
+<!ENTITY % ISOgrk2 PUBLIC
+"ISO 8879:1986//ENTITIES Monotoniko Greek//EN">
+%ISOgrk2;
+<!--end of ISOgrk2.module-->]]>
+
+<!ENTITY % ISOgrk3.module "INCLUDE">
+<![ %ISOgrk3.module; [
+<!ENTITY % ISOgrk3 PUBLIC
+"ISO 8879:1986//ENTITIES Greek Symbols//EN">
+%ISOgrk3;
+<!--end of ISOgrk3.module-->]]>
+
+<!ENTITY % ISOgrk4.module "INCLUDE">
+<![ %ISOgrk4.module; [
+<!ENTITY % ISOgrk4 PUBLIC
+"ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN">
+%ISOgrk4;
+<!--end of ISOgrk4.module-->]]>
+
+<!ENTITY % ISOlat1.module "INCLUDE">
+<![ %ISOlat1.module; [
+<!ENTITY % ISOlat1 PUBLIC
+"ISO 8879:1986//ENTITIES Added Latin 1//EN">
+%ISOlat1;
+<!--end of ISOlat1.module-->]]>
+
+<!ENTITY % ISOlat2.module "INCLUDE">
+<![ %ISOlat2.module; [
+<!ENTITY % ISOlat2 PUBLIC
+"ISO 8879:1986//ENTITIES Added Latin 2//EN">
+%ISOlat2;
+<!--end of ISOlat2.module-->]]>
+
+<!ENTITY % ISOnum.module "INCLUDE">
+<![ %ISOnum.module; [
+<!ENTITY % ISOnum PUBLIC
+"ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN">
+%ISOnum;
+<!--end of ISOnum.module-->]]>
+
+<!ENTITY % ISOpub.module "INCLUDE">
+<![ %ISOpub.module; [
+<!ENTITY % ISOpub PUBLIC
+"ISO 8879:1986//ENTITIES Publishing//EN">
+%ISOpub;
+<!--end of ISOpub.module-->]]>
+
+<!ENTITY % ISOtech.module "INCLUDE">
+<![ %ISOtech.module; [
+<!ENTITY % ISOtech PUBLIC
+"ISO 8879:1986//ENTITIES General Technical//EN">
+%ISOtech;
+<!--end of ISOtech.module-->]]>
diff --git a/docs/docbook/dbsgml/dbgenent.mod b/docs/docbook/dbsgml/dbgenent.mod
new file mode 100755
index 00000000000..b60c5b27140
--- /dev/null
+++ b/docs/docbook/dbsgml/dbgenent.mod
@@ -0,0 +1,39 @@
+<!-- ...................................................................... -->
+<!-- DocBook additional general entities V4.1 ............................. -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ In DTD driver files referring to this module, please use an entity
+ declaration that uses the public identifier shown below:
+
+ <!ENTITY % dbgenent PUBLIC
+ "-//OASIS//ENTITIES DocBook Additional General Entities V4.1//EN"
+ %dbgenent;
+-->
+
+<!-- File dbgenent.mod .................................................... -->
+
+<!-- You can edit this file to add the following:
+
+ o General entity declarations of any kind. For example:
+
+ <!ENTITY happyface SDATA "insert-face"> (system-specific data)
+ <!ENTITY productname "WinWidget"> (small boilerplate)
+ <!ENTITY legal-notice SYSTEM "notice.sgm"> (large boilerplate)
+
+ o Notation declarations. For example:
+
+ <!NOTATION chicken-scratch SYSTEM>
+
+ o Declarations for and references to external parameter entities
+ containing collections of any of the above. For example:
+
+ <!ENTITY % all-titles PUBLIC "-//DocTools//ELEMENTS Book Titles//EN">
+ %all-titles;
+-->
+
+<!-- End of DocBook additional general entities V4.1 ...................... -->
+<!-- ...................................................................... -->
diff --git a/docs/docbook/dbsgml/dbhier.mod b/docs/docbook/dbsgml/dbhier.mod
new file mode 100755
index 00000000000..a7d9bdf6928
--- /dev/null
+++ b/docs/docbook/dbsgml/dbhier.mod
@@ -0,0 +1,2100 @@
+<!-- ...................................................................... -->
+<!-- DocBook document hierarchy module V4.1 ............................... -->
+<!-- File dbhier.mod ...................................................... -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ $Id: dbhier.mod,v 1.1.2.1 2001/02/28 19:05:00 jerry Exp $
+
+ Permission to use, copy, modify and distribute the DocBook DTD and
+ its accompanying documentation for any purpose and without fee is
+ hereby granted in perpetuity, provided that the above copyright
+ notice and this paragraph appear in all copies. The copyright
+ holders make no representation about the suitability of the DTD for
+ any purpose. It is provided "as is" without expressed or implied
+ warranty.
+
+ If you modify the DocBook DTD in any way, except for declaring and
+ referencing additional sets of general entities and declaring
+ additional notations, label your DTD as a variant of DocBook. See
+ the maintenance documentation for more information.
+
+ Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/docbook/.
+-->
+
+<!-- ...................................................................... -->
+
+<!-- This module contains the definitions for the overall document
+ hierarchies of DocBook documents. It covers computer documentation
+ manuals and manual fragments, as well as reference entries (such as
+ man pages) and technical journals or anthologies containing
+ articles.
+
+ This module depends on the DocBook information pool module. All
+ elements and entities referenced but not defined here are assumed
+ to be defined in the information pool module.
+
+ In DTD driver files referring to this module, please use an entity
+ declaration that uses the public identifier shown below:
+
+ <!ENTITY % dbhier PUBLIC
+ "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.1//EN">
+ %dbhier;
+
+ See the documentation for detailed information on the parameter
+ entity and module scheme used in DocBook, customizing DocBook and
+ planning for interchange, and changes made since the last release
+ of DocBook.
+-->
+
+<!-- ...................................................................... -->
+<!-- Entities for module inclusions ....................................... -->
+
+<!ENTITY % dbhier.redecl.module "IGNORE">
+<!ENTITY % dbhier.redecl2.module "IGNORE">
+
+<!-- ...................................................................... -->
+<!-- Entities for element classes ......................................... -->
+
+<!ENTITY % local.appendix.class "">
+<!ENTITY % appendix.class "Appendix %local.appendix.class;">
+
+<!ENTITY % local.article.class "">
+<!ENTITY % article.class "Article %local.article.class;">
+
+<!ENTITY % local.book.class "">
+<!ENTITY % book.class "Book %local.book.class;">
+
+<!ENTITY % local.chapter.class "">
+<!ENTITY % chapter.class "Chapter %local.chapter.class;">
+
+<!ENTITY % local.index.class "">
+<!ENTITY % index.class "Index|SetIndex %local.index.class;">
+
+<!ENTITY % local.refentry.class "">
+<!ENTITY % refentry.class "RefEntry %local.refentry.class;">
+
+<!ENTITY % local.nav.class "">
+<!ENTITY % nav.class "ToC|LoT|Index|Glossary|Bibliography
+ %local.nav.class;">
+
+<!-- Redeclaration placeholder ............................................ -->
+
+<!-- For redeclaring entities that are declared after this point while
+ retaining their references to the entities that are declared before
+ this point -->
+
+<![ %dbhier.redecl.module; [
+%rdbhier;
+<!--end of dbhier.redecl.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Entities for element mixtures ........................................ -->
+
+<!-- The DocBook TC may produce an official forms module for DocBook. -->
+<!-- This PE provides the hook by which it can be inserted into the DTD. -->
+<!ENTITY % forms.hook "">
+
+<!ENTITY % local.divcomponent.mix "">
+<!ENTITY % divcomponent.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |%compound.class;
+ |%genobj.class; |%descobj.class;
+ |%ndxterm.class;
+ %forms.hook;
+ %local.divcomponent.mix;">
+
+<!ENTITY % local.refcomponent.mix "">
+<!ENTITY % refcomponent.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |%compound.class;
+ |%genobj.class; |%descobj.class;
+ |%ndxterm.class;
+ %local.refcomponent.mix;">
+
+<!ENTITY % local.indexdivcomponent.mix "">
+<!ENTITY % indexdivcomponent.mix
+ "ItemizedList|OrderedList|VariableList|SimpleList
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |Anchor|Remark
+ |%link.char.class;
+ %local.indexdivcomponent.mix;">
+
+<!ENTITY % local.refname.char.mix "">
+<!ENTITY % refname.char.mix
+ "#PCDATA
+ |%tech.char.class;
+ %local.refname.char.mix;">
+
+<!ENTITY % local.partcontent.mix "">
+<!ENTITY % partcontent.mix
+ "%appendix.class;|%chapter.class;|%nav.class;|%article.class;
+ |Preface|%refentry.class;|Reference %local.partcontent.mix;">
+
+<!ENTITY % local.refinline.char.mix "">
+<!ENTITY % refinline.char.mix
+ "#PCDATA
+ |%xref.char.class; |%gen.char.class;
+ |%link.char.class; |%tech.char.class;
+ |%base.char.class; |%docinfo.char.class;
+ |%other.char.class;
+ |%ndxterm.class;
+ %local.refinline.char.mix;">
+
+<!ENTITY % local.refclass.char.mix "">
+<!ENTITY % refclass.char.mix
+ "#PCDATA
+ |Application
+ %local.refclass.char.mix;">
+
+<!-- Redeclaration placeholder 2 .......................................... -->
+
+<!-- For redeclaring entities that are declared after this point while
+ retaining their references to the entities that are declared before
+ this point -->
+
+<![ %dbhier.redecl2.module; [
+%rdbhier2;
+<!--end of dbhier.redecl2.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Entities for content models .......................................... -->
+
+<!ENTITY % div.title.content
+ "Title, Subtitle?, TitleAbbrev?">
+
+<!ENTITY % bookcomponent.title.content
+ "Title, Subtitle?, TitleAbbrev?">
+
+<!ENTITY % sect.title.content
+ "Title, Subtitle?, TitleAbbrev?">
+
+<!ENTITY % refsect.title.content
+ "Title, Subtitle?, TitleAbbrev?">
+
+<!ENTITY % bookcomponent.content
+ "((%divcomponent.mix;)+,
+ (Sect1*|(%refentry.class;)*|SimpleSect*|Section*))
+ | (Sect1+|(%refentry.class;)+|SimpleSect+|Section+)">
+
+<!-- ...................................................................... -->
+<!-- Set and SetInfo ...................................................... -->
+
+<!ENTITY % set.content.module "INCLUDE">
+<![ %set.content.module; [
+<!ENTITY % set.module "INCLUDE">
+<![ %set.module; [
+<!ENTITY % local.set.attrib "">
+<!ENTITY % set.role.attrib "%role.attrib;">
+
+<!ENTITY % set.element "INCLUDE">
+<![ %set.element; [
+<!ELEMENT Set - O ((%div.title.content;)?, SetInfo?, ToC?, (%book.class;)+,
+ SetIndex?) %ubiq.inclusion;>
+<!--end of set.element-->]]>
+
+<!ENTITY % set.attlist "INCLUDE">
+<![ %set.attlist; [
+<!ATTLIST Set
+ --
+ FPI: SGML formal public identifier
+ --
+ FPI CDATA #IMPLIED
+ %status.attrib;
+ %common.attrib;
+ %set.role.attrib;
+ %local.set.attrib;
+>
+<!--end of set.attlist-->]]>
+<!--end of set.module-->]]>
+
+<!ENTITY % setinfo.module "INCLUDE">
+<![ %setinfo.module; [
+<!ENTITY % local.setinfo.attrib "">
+<!ENTITY % setinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % setinfo.element "INCLUDE">
+<![ %setinfo.element; [
+<!ELEMENT SetInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec | SubjectSet
+ | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of setinfo.element-->]]>
+
+<!ENTITY % setinfo.attlist "INCLUDE">
+<![ %setinfo.attlist; [
+<!--FUTURE USE (V5.0):
+......................
+The Contents attribute will be removed from SetInfo
+......................
+-->
+<!ATTLIST SetInfo
+ --
+ Contents: IDs of the ToC, Books, and SetIndex that comprise
+ the set, in the order of their appearance
+ --
+ Contents IDREFS #IMPLIED
+ %common.attrib;
+ %setinfo.role.attrib;
+ %local.setinfo.attrib;
+>
+<!--end of setinfo.attlist-->]]>
+<!--end of setinfo.module-->]]>
+<!--end of set.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Book and BookInfo .................................................... -->
+
+<!ENTITY % book.content.module "INCLUDE">
+<![ %book.content.module; [
+<!ENTITY % book.module "INCLUDE">
+<![ %book.module; [
+
+<!ENTITY % local.book.attrib "">
+<!ENTITY % book.role.attrib "%role.attrib;">
+
+<!ENTITY % book.element "INCLUDE">
+<![ %book.element; [
+<!ELEMENT Book - O ((%div.title.content;)?, BookInfo?,
+ (Dedication | ToC | LoT
+ | Glossary | Bibliography | Preface
+ | %chapter.class; | Reference | Part
+ | %article.class;
+ | %appendix.class;
+ | %index.class;
+ | Colophon)*)
+ %ubiq.inclusion;>
+<!--end of book.element-->]]>
+
+<!ENTITY % book.attlist "INCLUDE">
+<![ %book.attlist; [
+<!ATTLIST Book
+ --
+ FPI: SGML formal public identifier
+ --
+ FPI CDATA #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %book.role.attrib;
+ %local.book.attrib;
+>
+<!--end of book.attlist-->]]>
+<!--end of book.module-->]]>
+
+<!ENTITY % bookinfo.module "INCLUDE">
+<![ %bookinfo.module; [
+<!ENTITY % local.bookinfo.attrib "">
+<!ENTITY % bookinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % bookinfo.element "INCLUDE">
+<![ %bookinfo.element; [
+<!ELEMENT BookInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec | SubjectSet
+ | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of bookinfo.element-->]]>
+
+<!ENTITY % bookinfo.attlist "INCLUDE">
+<![ %bookinfo.attlist; [
+<!--FUTURE USE (V5.0):
+......................
+The Contents attribute will be removed from BookInfo
+......................
+-->
+<!ATTLIST BookInfo
+ --
+ Contents: IDs of the ToC, LoTs, Prefaces, Parts, Chapters,
+ Appendixes, References, GLossary, Bibliography, and indexes
+ comprising the Book, in the order of their appearance
+ --
+ Contents IDREFS #IMPLIED
+ %common.attrib;
+ %bookinfo.role.attrib;
+ %local.bookinfo.attrib;
+>
+<!--end of bookinfo.attlist-->]]>
+<!--end of bookinfo.module-->]]>
+<!--end of book.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Dedication, ToC, and LoT ............................................. -->
+
+<!ENTITY % dedication.module "INCLUDE">
+<![ %dedication.module; [
+<!ENTITY % local.dedication.attrib "">
+<!ENTITY % dedication.role.attrib "%role.attrib;">
+
+<!ENTITY % dedication.element "INCLUDE">
+<![ %dedication.element; [
+<!ELEMENT Dedication - O ((%sect.title.content;)?, (%legalnotice.mix;)+)>
+<!--end of dedication.element-->]]>
+
+<!ENTITY % dedication.attlist "INCLUDE">
+<![ %dedication.attlist; [
+<!ATTLIST Dedication
+ %status.attrib;
+ %common.attrib;
+ %dedication.role.attrib;
+ %local.dedication.attrib;
+>
+<!--end of dedication.attlist-->]]>
+<!--end of dedication.module-->]]>
+
+<!ENTITY % colophon.module "INCLUDE">
+<![ %colophon.module; [
+<!ENTITY % local.colophon.attrib "">
+<!ENTITY % colophon.role.attrib "%role.attrib;">
+
+<!ENTITY % colophon.element "INCLUDE">
+<![ %colophon.element; [
+<!ELEMENT Colophon - O ((%sect.title.content;)?, (%textobject.mix;)+)>
+<!--end of colophon.element-->]]>
+
+<!ENTITY % colophon.attlist "INCLUDE">
+<![ %colophon.attlist; [
+<!ATTLIST Colophon
+ %status.attrib;
+ %common.attrib;
+ %colophon.role.attrib;
+ %local.colophon.attrib;>
+<!--end of colophon.attlist-->]]>
+<!--end of colophon.module-->]]>
+
+<!ENTITY % toc.content.module "INCLUDE">
+<![ %toc.content.module; [
+<!ENTITY % toc.module "INCLUDE">
+<![ %toc.module; [
+<!ENTITY % local.toc.attrib "">
+<!ENTITY % toc.role.attrib "%role.attrib;">
+
+<!ENTITY % toc.element "INCLUDE">
+<![ %toc.element; [
+<!ELEMENT ToC - O ((%bookcomponent.title.content;)?, ToCfront*,
+ (ToCpart | ToCchap)*, ToCback*)>
+<!--end of toc.element-->]]>
+
+<!ENTITY % toc.attlist "INCLUDE">
+<![ %toc.attlist; [
+<!ATTLIST ToC
+ %pagenum.attrib;
+ %common.attrib;
+ %toc.role.attrib;
+ %local.toc.attrib;
+>
+<!--end of toc.attlist-->]]>
+<!--end of toc.module-->]]>
+
+<!ENTITY % tocfront.module "INCLUDE">
+<![ %tocfront.module; [
+<!ENTITY % local.tocfront.attrib "">
+<!ENTITY % tocfront.role.attrib "%role.attrib;">
+
+<!ENTITY % tocfront.element "INCLUDE">
+<![ %tocfront.element; [
+<!ELEMENT ToCfront - O ((%para.char.mix;)+)>
+<!--end of tocfront.element-->]]>
+
+<!ENTITY % tocfront.attlist "INCLUDE">
+<![ %tocfront.attlist; [
+<!ATTLIST ToCfront
+ %label.attrib;
+ %linkend.attrib; --to element that this entry represents--
+ %pagenum.attrib;
+ %common.attrib;
+ %tocfront.role.attrib;
+ %local.tocfront.attrib;
+>
+<!--end of tocfront.attlist-->]]>
+<!--end of tocfront.module-->]]>
+
+<!ENTITY % tocentry.module "INCLUDE">
+<![ %tocentry.module; [
+<!ENTITY % local.tocentry.attrib "">
+<!ENTITY % tocentry.role.attrib "%role.attrib;">
+
+<!ENTITY % tocentry.element "INCLUDE">
+<![ %tocentry.element; [
+<!ELEMENT ToCentry - - ((%para.char.mix;)+)>
+<!--end of tocentry.element-->]]>
+
+<!ENTITY % tocentry.attlist "INCLUDE">
+<![ %tocentry.attlist; [
+<!ATTLIST ToCentry
+ %linkend.attrib; --to element that this entry represents--
+ %pagenum.attrib;
+ %common.attrib;
+ %tocentry.role.attrib;
+ %local.tocentry.attrib;
+>
+<!--end of tocentry.attlist-->]]>
+<!--end of tocentry.module-->]]>
+
+<!ENTITY % tocpart.module "INCLUDE">
+<![ %tocpart.module; [
+<!ENTITY % local.tocpart.attrib "">
+<!ENTITY % tocpart.role.attrib "%role.attrib;">
+
+<!ENTITY % tocpart.element "INCLUDE">
+<![ %tocpart.element; [
+<!ELEMENT ToCpart - O (ToCentry+, ToCchap*)>
+<!--end of tocpart.element-->]]>
+
+<!ENTITY % tocpart.attlist "INCLUDE">
+<![ %tocpart.attlist; [
+<!ATTLIST ToCpart
+ %common.attrib;
+ %tocpart.role.attrib;
+ %local.tocpart.attrib;
+>
+<!--end of tocpart.attlist-->]]>
+<!--end of tocpart.module-->]]>
+
+<!ENTITY % tocchap.module "INCLUDE">
+<![ %tocchap.module; [
+<!ENTITY % local.tocchap.attrib "">
+<!ENTITY % tocchap.role.attrib "%role.attrib;">
+
+<!ENTITY % tocchap.element "INCLUDE">
+<![ %tocchap.element; [
+<!ELEMENT ToCchap - O (ToCentry+, ToClevel1*)>
+<!--end of tocchap.element-->]]>
+
+<!ENTITY % tocchap.attlist "INCLUDE">
+<![ %tocchap.attlist; [
+<!ATTLIST ToCchap
+ %label.attrib;
+ %common.attrib;
+ %tocchap.role.attrib;
+ %local.tocchap.attrib;
+>
+<!--end of tocchap.attlist-->]]>
+<!--end of tocchap.module-->]]>
+
+<!ENTITY % toclevel1.module "INCLUDE">
+<![ %toclevel1.module; [
+<!ENTITY % local.toclevel1.attrib "">
+<!ENTITY % toclevel1.role.attrib "%role.attrib;">
+
+<!ENTITY % toclevel1.element "INCLUDE">
+<![ %toclevel1.element; [
+<!ELEMENT ToClevel1 - O (ToCentry+, ToClevel2*)>
+<!--end of toclevel1.element-->]]>
+
+<!ENTITY % toclevel1.attlist "INCLUDE">
+<![ %toclevel1.attlist; [
+<!ATTLIST ToClevel1
+ %common.attrib;
+ %toclevel1.role.attrib;
+ %local.toclevel1.attrib;
+>
+<!--end of toclevel1.attlist-->]]>
+<!--end of toclevel1.module-->]]>
+
+<!ENTITY % toclevel2.module "INCLUDE">
+<![ %toclevel2.module; [
+<!ENTITY % local.toclevel2.attrib "">
+<!ENTITY % toclevel2.role.attrib "%role.attrib;">
+
+<!ENTITY % toclevel2.element "INCLUDE">
+<![ %toclevel2.element; [
+<!ELEMENT ToClevel2 - O (ToCentry+, ToClevel3*)>
+<!--end of toclevel2.element-->]]>
+
+<!ENTITY % toclevel2.attlist "INCLUDE">
+<![ %toclevel2.attlist; [
+<!ATTLIST ToClevel2
+ %common.attrib;
+ %toclevel2.role.attrib;
+ %local.toclevel2.attrib;
+>
+<!--end of toclevel2.attlist-->]]>
+<!--end of toclevel2.module-->]]>
+
+<!ENTITY % toclevel3.module "INCLUDE">
+<![ %toclevel3.module; [
+<!ENTITY % local.toclevel3.attrib "">
+<!ENTITY % toclevel3.role.attrib "%role.attrib;">
+
+<!ENTITY % toclevel3.element "INCLUDE">
+<![ %toclevel3.element; [
+<!ELEMENT ToClevel3 - O (ToCentry+, ToClevel4*)>
+<!--end of toclevel3.element-->]]>
+
+<!ENTITY % toclevel3.attlist "INCLUDE">
+<![ %toclevel3.attlist; [
+<!ATTLIST ToClevel3
+ %common.attrib;
+ %toclevel3.role.attrib;
+ %local.toclevel3.attrib;
+>
+<!--end of toclevel3.attlist-->]]>
+<!--end of toclevel3.module-->]]>
+
+<!ENTITY % toclevel4.module "INCLUDE">
+<![ %toclevel4.module; [
+<!ENTITY % local.toclevel4.attrib "">
+<!ENTITY % toclevel4.role.attrib "%role.attrib;">
+
+<!ENTITY % toclevel4.element "INCLUDE">
+<![ %toclevel4.element; [
+<!ELEMENT ToClevel4 - O (ToCentry+, ToClevel5*)>
+<!--end of toclevel4.element-->]]>
+
+<!ENTITY % toclevel4.attlist "INCLUDE">
+<![ %toclevel4.attlist; [
+<!ATTLIST ToClevel4
+ %common.attrib;
+ %toclevel4.role.attrib;
+ %local.toclevel4.attrib;
+>
+<!--end of toclevel4.attlist-->]]>
+<!--end of toclevel4.module-->]]>
+
+<!ENTITY % toclevel5.module "INCLUDE">
+<![ %toclevel5.module; [
+<!ENTITY % local.toclevel5.attrib "">
+<!ENTITY % toclevel5.role.attrib "%role.attrib;">
+
+<!ENTITY % toclevel5.element "INCLUDE">
+<![ %toclevel5.element; [
+<!ELEMENT ToClevel5 - O (ToCentry+)>
+<!--end of toclevel5.element-->]]>
+
+<!ENTITY % toclevel5.attlist "INCLUDE">
+<![ %toclevel5.attlist; [
+<!ATTLIST ToClevel5
+ %common.attrib;
+ %toclevel5.role.attrib;
+ %local.toclevel5.attrib;
+>
+<!--end of toclevel5.attlist-->]]>
+<!--end of toclevel5.module-->]]>
+
+<!ENTITY % tocback.module "INCLUDE">
+<![ %tocback.module; [
+<!ENTITY % local.tocback.attrib "">
+<!ENTITY % tocback.role.attrib "%role.attrib;">
+
+<!ENTITY % tocback.element "INCLUDE">
+<![ %tocback.element; [
+<!ELEMENT ToCback - O ((%para.char.mix;)+)>
+<!--end of tocback.element-->]]>
+
+<!ENTITY % tocback.attlist "INCLUDE">
+<![ %tocback.attlist; [
+<!ATTLIST ToCback
+ %label.attrib;
+ %linkend.attrib; --to element that this entry represents--
+ %pagenum.attrib;
+ %common.attrib;
+ %tocback.role.attrib;
+ %local.tocback.attrib;
+>
+<!--end of tocback.attlist-->]]>
+<!--end of tocback.module-->]]>
+<!--end of toc.content.module-->]]>
+
+<!ENTITY % lot.content.module "INCLUDE">
+<![ %lot.content.module; [
+<!ENTITY % lot.module "INCLUDE">
+<![ %lot.module; [
+<!ENTITY % local.lot.attrib "">
+<!ENTITY % lot.role.attrib "%role.attrib;">
+
+<!ENTITY % lot.element "INCLUDE">
+<![ %lot.element; [
+<!ELEMENT LoT - O ((%bookcomponent.title.content;)?, LoTentry*)>
+<!--end of lot.element-->]]>
+
+<!ENTITY % lot.attlist "INCLUDE">
+<![ %lot.attlist; [
+<!ATTLIST LoT
+ %label.attrib;
+ %common.attrib;
+ %lot.role.attrib;
+ %local.lot.attrib;
+>
+<!--end of lot.attlist-->]]>
+<!--end of lot.module-->]]>
+
+<!ENTITY % lotentry.module "INCLUDE">
+<![ %lotentry.module; [
+<!ENTITY % local.lotentry.attrib "">
+<!ENTITY % lotentry.role.attrib "%role.attrib;">
+
+<!ENTITY % lotentry.element "INCLUDE">
+<![ %lotentry.element; [
+<!ELEMENT LoTentry - - ((%para.char.mix;)+ )>
+<!--end of lotentry.element-->]]>
+
+<!ENTITY % lotentry.attlist "INCLUDE">
+<![ %lotentry.attlist; [
+<!ATTLIST LoTentry
+ --
+ SrcCredit: Information about the source of the entry,
+ as for a list of illustrations
+ --
+ SrcCredit CDATA #IMPLIED
+ %pagenum.attrib;
+ %common.attrib;
+ %linkend.attrib; --to element that this entry represents--
+ %lotentry.role.attrib;
+ %local.lotentry.attrib;
+>
+<!--end of lotentry.attlist-->]]>
+<!--end of lotentry.module-->]]>
+<!--end of lot.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Appendix, Chapter, Part, Preface, Reference, PartIntro ............... -->
+
+<!ENTITY % appendix.module "INCLUDE">
+<![ %appendix.module; [
+<!ENTITY % local.appendix.attrib "">
+<!ENTITY % appendix.role.attrib "%role.attrib;">
+
+<!ENTITY % appendix.element "INCLUDE">
+<![ %appendix.element; [
+<!ELEMENT Appendix - O (AppendixInfo?,
+ (%bookcomponent.title.content;),
+ (%nav.class)*,
+ ToCchap?,
+ (%bookcomponent.content;),
+ (%nav.class)*)
+ %ubiq.inclusion;>
+<!--end of appendix.element-->]]>
+
+<!ENTITY % appendix.attlist "INCLUDE">
+<![ %appendix.attlist; [
+<!ATTLIST Appendix
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %appendix.role.attrib;
+ %local.appendix.attrib;
+>
+<!--end of appendix.attlist-->]]>
+<!--end of appendix.module-->]]>
+
+<!ENTITY % chapter.module "INCLUDE">
+<![ %chapter.module; [
+<!ENTITY % local.chapter.attrib "">
+<!ENTITY % chapter.role.attrib "%role.attrib;">
+
+<!ENTITY % chapter.element "INCLUDE">
+<![ %chapter.element; [
+<!ELEMENT Chapter - O (ChapterInfo?,
+ (%bookcomponent.title.content;),
+ (%nav.class)*,
+ ToCchap?,
+ (%bookcomponent.content;),
+ (%nav.class)*)
+ %ubiq.inclusion;>
+<!--end of chapter.element-->]]>
+
+<!ENTITY % chapter.attlist "INCLUDE">
+<![ %chapter.attlist; [
+<!ATTLIST Chapter
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %chapter.role.attrib;
+ %local.chapter.attrib;
+>
+<!--end of chapter.attlist-->]]>
+<!--end of chapter.module-->]]>
+
+<!ENTITY % part.module "INCLUDE">
+<![ %part.module; [
+
+<!-- Note that Part was to have its content model reduced in V4.1. This
+change will not be made after all. -->
+
+<!ENTITY % local.part.attrib "">
+<!ENTITY % part.role.attrib "%role.attrib;">
+
+<!ENTITY % part.element "INCLUDE">
+<![ %part.element; [
+<!ELEMENT Part - - (PartInfo?, (%bookcomponent.title.content;), PartIntro?,
+ (%partcontent.mix;)+) %ubiq.inclusion;>
+<!--end of part.element-->]]>
+
+<!ENTITY % part.attlist "INCLUDE">
+<![ %part.attlist; [
+<!ATTLIST Part
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %part.role.attrib;
+ %local.part.attrib;
+>
+<!--end of part.attlist-->]]>
+<!--ELEMENT PartIntro (defined below)-->
+<!--end of part.module-->]]>
+
+<!ENTITY % preface.module "INCLUDE">
+<![ %preface.module; [
+<!ENTITY % local.preface.attrib "">
+<!ENTITY % preface.role.attrib "%role.attrib;">
+
+<!ENTITY % preface.element "INCLUDE">
+<![ %preface.element; [
+<!ELEMENT Preface - O (PrefaceInfo?,
+ (%bookcomponent.title.content;),
+ (%nav.class)*,
+ ToCchap?,
+ (%bookcomponent.content;),
+ (%nav.class)*)
+ %ubiq.inclusion;>
+<!--end of preface.element-->]]>
+
+<!ENTITY % preface.attlist "INCLUDE">
+<![ %preface.attlist; [
+<!ATTLIST Preface
+ %status.attrib;
+ %common.attrib;
+ %preface.role.attrib;
+ %local.preface.attrib;
+>
+<!--end of preface.attlist-->]]>
+<!--end of preface.module-->]]>
+
+<!ENTITY % reference.module "INCLUDE">
+<![ %reference.module; [
+<!ENTITY % local.reference.attrib "">
+<!ENTITY % reference.role.attrib "%role.attrib;">
+
+<!ENTITY % reference.element "INCLUDE">
+<![ %reference.element; [
+<!ELEMENT Reference - O (ReferenceInfo?, (%bookcomponent.title.content;),
+ PartIntro?,
+ (%refentry.class;)+) %ubiq.inclusion;>
+<!--end of reference.element-->]]>
+
+<!ENTITY % reference.attlist "INCLUDE">
+<![ %reference.attlist; [
+<!ATTLIST Reference
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %reference.role.attrib;
+ %local.reference.attrib;
+>
+<!--end of reference.attlist-->]]>
+<!--ELEMENT PartIntro (defined below)-->
+<!--end of reference.module-->]]>
+
+<!ENTITY % partintro.module "INCLUDE">
+<![ %partintro.module; [
+<!ENTITY % local.partintro.attrib "">
+<!ENTITY % partintro.role.attrib "%role.attrib;">
+
+<!ENTITY % partintro.element "INCLUDE">
+<![ %partintro.element; [
+<!ELEMENT PartIntro - O ((%div.title.content;)?, (%bookcomponent.content;))
+ %ubiq.inclusion;>
+<!--end of partintro.element-->]]>
+
+<!ENTITY % partintro.attlist "INCLUDE">
+<![ %partintro.attlist; [
+<!ATTLIST PartIntro
+ %label.attrib;
+ %common.attrib;
+ %local.partintro.attrib;
+ %partintro.role.attrib;
+>
+<!--end of partintro.attlist-->]]>
+<!--end of partintro.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Other Info elements .................................................. -->
+
+<!ENTITY % appendixinfo.module "INCLUDE">
+<![ %appendixinfo.module; [
+<!ENTITY % local.appendixinfo.attrib "">
+<!ENTITY % appendixinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % appendixinfo.element "INCLUDE">
+<![ %appendixinfo.element; [
+<!ELEMENT AppendixInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of appendixinfo.element-->]]>
+
+<!ENTITY % appendixinfo.attlist "INCLUDE">
+<![ %appendixinfo.attlist; [
+<!ATTLIST AppendixInfo
+ %common.attrib;
+ %appendixinfo.role.attrib;
+ %local.appendixinfo.attrib;
+>
+<!--end of appendixinfo.attlist-->]]>
+<!--end of appendixinfo.module-->]]>
+
+
+<!ENTITY % bibliographyinfo.module "INCLUDE">
+<![ %bibliographyinfo.module; [
+<!ENTITY % local.bibliographyinfo.attrib "">
+<!ENTITY % bibliographyinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % bibliographyinfo.element "INCLUDE">
+<![ %bibliographyinfo.element; [
+<!ELEMENT BibliographyInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of bibliographyinfo.element-->]]>
+
+<!ENTITY % bibliographyinfo.attlist "INCLUDE">
+<![ %bibliographyinfo.attlist; [
+<!ATTLIST BibliographyInfo
+ %common.attrib;
+ %bibliographyinfo.role.attrib;
+ %local.bibliographyinfo.attrib;
+>
+<!--end of bibliographyinfo.attlist-->]]>
+<!--end of bibliographyinfo.module-->]]>
+
+<!ENTITY % chapterinfo.module "INCLUDE">
+<![ %chapterinfo.module; [
+<!ENTITY % local.chapterinfo.attrib "">
+<!ENTITY % chapterinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % chapterinfo.element "INCLUDE">
+<![ %chapterinfo.element; [
+<!ELEMENT ChapterInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of chapterinfo.element-->]]>
+
+<!ENTITY % chapterinfo.attlist "INCLUDE">
+<![ %chapterinfo.attlist; [
+<!ATTLIST ChapterInfo
+ %common.attrib;
+ %chapterinfo.role.attrib;
+ %local.chapterinfo.attrib;
+>
+<!--end of chapterinfo.attlist-->]]>
+<!--end of chapterinfo.module-->]]>
+
+<!ENTITY % glossaryinfo.module "INCLUDE">
+<![ %glossaryinfo.module; [
+<!ENTITY % local.glossaryinfo.attrib "">
+<!ENTITY % glossaryinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % glossaryinfo.element "INCLUDE">
+<![ %glossaryinfo.element; [
+<!ELEMENT GlossaryInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of glossaryinfo.element-->]]>
+
+<!ENTITY % glossaryinfo.attlist "INCLUDE">
+<![ %glossaryinfo.attlist; [
+<!ATTLIST GlossaryInfo
+ %common.attrib;
+ %glossaryinfo.role.attrib;
+ %local.glossaryinfo.attrib;
+>
+<!--end of glossaryinfo.attlist-->]]>
+<!--end of glossaryinfo.module-->]]>
+
+
+<!ENTITY % indexinfo.module "INCLUDE">
+<![ %indexinfo.module; [
+<!ENTITY % local.indexinfo.attrib "">
+<!ENTITY % indexinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % indexinfo.element "INCLUDE">
+<![ %indexinfo.element; [
+<!ELEMENT IndexInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of indexinfo.element-->]]>
+
+<!ENTITY % indexinfo.attlist "INCLUDE">
+<![ %indexinfo.attlist; [
+<!ATTLIST IndexInfo
+ %common.attrib;
+ %indexinfo.role.attrib;
+ %local.indexinfo.attrib;
+>
+<!--end of indexinfo.attlist-->]]>
+<!--end of indexinfo.module-->]]>
+
+<!ENTITY % partinfo.module "INCLUDE">
+<![ %partinfo.module; [
+<!ENTITY % local.partinfo.attrib "">
+<!ENTITY % partinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % partinfo.element "INCLUDE">
+<![ %partinfo.element; [
+<!ELEMENT PartInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of partinfo.element-->]]>
+
+<!ENTITY % partinfo.attlist "INCLUDE">
+<![ %partinfo.attlist; [
+<!ATTLIST PartInfo
+ %common.attrib;
+ %partinfo.role.attrib;
+ %local.partinfo.attrib;
+>
+<!--end of partinfo.attlist-->]]>
+<!--end of partinfo.module-->]]>
+
+
+<!ENTITY % prefaceinfo.module "INCLUDE">
+<![ %prefaceinfo.module; [
+<!ENTITY % local.prefaceinfo.attrib "">
+<!ENTITY % prefaceinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % prefaceinfo.element "INCLUDE">
+<![ %prefaceinfo.element; [
+<!ELEMENT PrefaceInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of prefaceinfo.element-->]]>
+
+<!ENTITY % prefaceinfo.attlist "INCLUDE">
+<![ %prefaceinfo.attlist; [
+<!ATTLIST PrefaceInfo
+ %common.attrib;
+ %prefaceinfo.role.attrib;
+ %local.prefaceinfo.attrib;
+>
+<!--end of prefaceinfo.attlist-->]]>
+<!--end of prefaceinfo.module-->]]>
+
+
+<!ENTITY % refentryinfo.module "INCLUDE">
+<![ %refentryinfo.module; [
+<!ENTITY % local.refentryinfo.attrib "">
+<!ENTITY % refentryinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % refentryinfo.element "INCLUDE">
+<![ %refentryinfo.element; [
+<!ELEMENT RefEntryInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of refentryinfo.element-->]]>
+
+<!ENTITY % refentryinfo.attlist "INCLUDE">
+<![ %refentryinfo.attlist; [
+<!ATTLIST RefEntryInfo
+ %common.attrib;
+ %refentryinfo.role.attrib;
+ %local.refentryinfo.attrib;
+>
+<!--end of refentryinfo.attlist-->]]>
+<!--end of refentryinfo.module-->]]>
+
+
+<!ENTITY % refsect1info.module "INCLUDE">
+<![ %refsect1info.module; [
+<!ENTITY % local.refsect1info.attrib "">
+<!ENTITY % refsect1info.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect1info.element "INCLUDE">
+<![ %refsect1info.element; [
+<!ELEMENT RefSect1Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of refsect1info.element-->]]>
+
+<!ENTITY % refsect1info.attlist "INCLUDE">
+<![ %refsect1info.attlist; [
+<!ATTLIST RefSect1Info
+ %common.attrib;
+ %refsect1info.role.attrib;
+ %local.refsect1info.attrib;
+>
+<!--end of refsect1info.attlist-->]]>
+<!--end of refsect1info.module-->]]>
+
+
+<!ENTITY % refsect2info.module "INCLUDE">
+<![ %refsect2info.module; [
+<!ENTITY % local.refsect2info.attrib "">
+<!ENTITY % refsect2info.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect2info.element "INCLUDE">
+<![ %refsect2info.element; [
+<!ELEMENT RefSect2Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of refsect2info.element-->]]>
+
+<!ENTITY % refsect2info.attlist "INCLUDE">
+<![ %refsect2info.attlist; [
+<!ATTLIST RefSect2Info
+ %common.attrib;
+ %refsect2info.role.attrib;
+ %local.refsect2info.attrib;
+>
+<!--end of refsect2info.attlist-->]]>
+<!--end of refsect2info.module-->]]>
+
+
+<!ENTITY % refsect3info.module "INCLUDE">
+<![ %refsect3info.module; [
+<!ENTITY % local.refsect3info.attrib "">
+<!ENTITY % refsect3info.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect3info.element "INCLUDE">
+<![ %refsect3info.element; [
+<!ELEMENT RefSect3Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of refsect3info.element-->]]>
+
+<!ENTITY % refsect3info.attlist "INCLUDE">
+<![ %refsect3info.attlist; [
+<!ATTLIST RefSect3Info
+ %common.attrib;
+ %refsect3info.role.attrib;
+ %local.refsect3info.attrib;
+>
+<!--end of refsect3info.attlist-->]]>
+<!--end of refsect3info.module-->]]>
+
+
+<!ENTITY % refsynopsisdivinfo.module "INCLUDE">
+<![ %refsynopsisdivinfo.module; [
+<!ENTITY % local.refsynopsisdivinfo.attrib "">
+<!ENTITY % refsynopsisdivinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % refsynopsisdivinfo.element "INCLUDE">
+<![ %refsynopsisdivinfo.element; [
+<!ELEMENT RefSynopsisDivInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of refsynopsisdivinfo.element-->]]>
+
+<!ENTITY % refsynopsisdivinfo.attlist "INCLUDE">
+<![ %refsynopsisdivinfo.attlist; [
+<!ATTLIST RefSynopsisDivInfo
+ %common.attrib;
+ %refsynopsisdivinfo.role.attrib;
+ %local.refsynopsisdivinfo.attrib;
+>
+<!--end of refsynopsisdivinfo.attlist-->]]>
+<!--end of refsynopsisdivinfo.module-->]]>
+
+
+<!ENTITY % referenceinfo.module "INCLUDE">
+<![ %referenceinfo.module; [
+<!ENTITY % local.referenceinfo.attrib "">
+<!ENTITY % referenceinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % referenceinfo.element "INCLUDE">
+<![ %referenceinfo.element; [
+<!ELEMENT ReferenceInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of referenceinfo.element-->]]>
+
+<!ENTITY % referenceinfo.attlist "INCLUDE">
+<![ %referenceinfo.attlist; [
+<!ATTLIST ReferenceInfo
+ %common.attrib;
+ %referenceinfo.role.attrib;
+ %local.referenceinfo.attrib;
+>
+<!--end of referenceinfo.attlist-->]]>
+<!--end of referenceinfo.module-->]]>
+
+
+<!ENTITY % sect1info.module "INCLUDE">
+<![ %sect1info.module; [
+<!ENTITY % local.sect1info.attrib "">
+<!ENTITY % sect1info.role.attrib "%role.attrib;">
+
+<!ENTITY % sect1info.element "INCLUDE">
+<![ %sect1info.element; [
+<!ELEMENT Sect1Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of sect1info.element-->]]>
+
+<!ENTITY % sect1info.attlist "INCLUDE">
+<![ %sect1info.attlist; [
+<!ATTLIST Sect1Info
+ %common.attrib;
+ %sect1info.role.attrib;
+ %local.sect1info.attrib;
+>
+<!--end of sect1info.attlist-->]]>
+<!--end of sect1info.module-->]]>
+
+
+<!ENTITY % sect2info.module "INCLUDE">
+<![ %sect2info.module; [
+<!ENTITY % local.sect2info.attrib "">
+<!ENTITY % sect2info.role.attrib "%role.attrib;">
+
+<!ENTITY % sect2info.element "INCLUDE">
+<![ %sect2info.element; [
+<!ELEMENT Sect2Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of sect2info.element-->]]>
+
+<!ENTITY % sect2info.attlist "INCLUDE">
+<![ %sect2info.attlist; [
+<!ATTLIST Sect2Info
+ %common.attrib;
+ %sect2info.role.attrib;
+ %local.sect2info.attrib;
+>
+<!--end of sect2info.attlist-->]]>
+<!--end of sect2info.module-->]]>
+
+
+<!ENTITY % sect3info.module "INCLUDE">
+<![ %sect3info.module; [
+<!ENTITY % local.sect3info.attrib "">
+<!ENTITY % sect3info.role.attrib "%role.attrib;">
+
+<!ENTITY % sect3info.element "INCLUDE">
+<![ %sect3info.element; [
+<!ELEMENT Sect3Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of sect3info.element-->]]>
+
+<!ENTITY % sect3info.attlist "INCLUDE">
+<![ %sect3info.attlist; [
+<!ATTLIST Sect3Info
+ %common.attrib;
+ %sect3info.role.attrib;
+ %local.sect3info.attrib;
+>
+<!--end of sect3info.attlist-->]]>
+<!--end of sect3info.module-->]]>
+
+
+<!ENTITY % sect4info.module "INCLUDE">
+<![ %sect4info.module; [
+<!ENTITY % local.sect4info.attrib "">
+<!ENTITY % sect4info.role.attrib "%role.attrib;">
+
+<!ENTITY % sect4info.element "INCLUDE">
+<![ %sect4info.element; [
+<!ELEMENT Sect4Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of sect4info.element-->]]>
+
+<!ENTITY % sect4info.attlist "INCLUDE">
+<![ %sect4info.attlist; [
+<!ATTLIST Sect4Info
+ %common.attrib;
+ %sect4info.role.attrib;
+ %local.sect4info.attrib;
+>
+<!--end of sect4info.attlist-->]]>
+<!--end of sect4info.module-->]]>
+
+
+<!ENTITY % sect5info.module "INCLUDE">
+<![ %sect5info.module; [
+<!ENTITY % local.sect5info.attrib "">
+<!ENTITY % sect5info.role.attrib "%role.attrib;">
+
+<!ENTITY % sect5info.element "INCLUDE">
+<![ %sect5info.element; [
+<!ELEMENT Sect5Info - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of sect5info.element-->]]>
+
+<!ENTITY % sect5info.attlist "INCLUDE">
+<![ %sect5info.attlist; [
+<!ATTLIST Sect5Info
+ %common.attrib;
+ %sect5info.role.attrib;
+ %local.sect5info.attrib;
+>
+<!--end of sect5info.attlist-->]]>
+<!--end of sect5info.module-->]]>
+
+
+<!ENTITY % setindexinfo.module "INCLUDE">
+<![ %setindexinfo.module; [
+<!ENTITY % local.setindexinfo.attrib "">
+<!ENTITY % setindexinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % setindexinfo.element "INCLUDE">
+<![ %setindexinfo.element; [
+<!ELEMENT SetIndexInfo - - ((Graphic | MediaObject
+ | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ %beginpage.exclusion;>
+<!--end of setindexinfo.element-->]]>
+
+<!ENTITY % setindexinfo.attlist "INCLUDE">
+<![ %setindexinfo.attlist; [
+<!ATTLIST SetIndexInfo
+ %common.attrib;
+ %setindexinfo.role.attrib;
+ %local.setindexinfo.attrib;
+>
+<!--end of setindexinfo.attlist-->]]>
+<!--end of setindexinfo.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Section (parallel to Sect*) ......................................... -->
+
+<!ENTITY % section.content.module "INCLUDE">
+<![ %section.content.module; [
+<!ENTITY % section.module "INCLUDE">
+<![ %section.module; [
+<!ENTITY % local.section.attrib "">
+<!ENTITY % section.role.attrib "%role.attrib;">
+
+<!ENTITY % section.element "INCLUDE">
+<![ %section.element; [
+<!ELEMENT Section - - (SectionInfo?,
+ (%sect.title.content;),
+ (%nav.class;)*,
+ (((%divcomponent.mix;)+,
+ ((%refentry.class;)*|Section*))
+ | (%refentry.class;)+|Section+),
+ (%nav.class;)*)
+ %ubiq.inclusion;>
+<!--end of section.element-->]]>
+
+<!ENTITY % section.attlist "INCLUDE">
+<![ %section.attlist; [
+<!ATTLIST Section
+ --
+ What did we decide about RenderAs?
+ Renderas (Sect1
+ |Sect2
+ |Sect3
+ |Sect4
+ |Sect5) #IMPLIED
+ --
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %section.role.attrib;
+ %local.section.attrib;
+>
+<!--end of section.attlist-->]]>
+<!--end of section.module-->]]>
+
+<!ENTITY % sectioninfo.module "INCLUDE">
+<![ %sectioninfo.module; [
+<!ENTITY % sectioninfo.role.attrib "%role.attrib;">
+<!ENTITY % local.sectioninfo.attrib "">
+
+<!ENTITY % sectioninfo.element "INCLUDE">
+<![ %sectioninfo.element; [
+<!ELEMENT SectionInfo - - ((Graphic | MediaObject | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ -(BeginPage)>
+<!--end of sectioninfo.element-->]]>
+
+<!ENTITY % sectioninfo.attlist "INCLUDE">
+<![ %sectioninfo.attlist; [
+<!ATTLIST SectionInfo
+ %common.attrib;
+ %sectioninfo.role.attrib;
+ %local.sectioninfo.attrib;
+>
+<!--end of sectioninfo.attlist-->]]>
+<!--end of sectioninfo.module-->]]>
+<!--end of section.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Sect1, Sect2, Sect3, Sect4, Sect5 .................................... -->
+
+<!ENTITY % sect1.module "INCLUDE">
+<![ %sect1.module; [
+<!ENTITY % local.sect1.attrib "">
+<!ENTITY % sect1.role.attrib "%role.attrib;">
+
+<!ENTITY % sect1.element "INCLUDE">
+<![ %sect1.element; [
+<!ELEMENT Sect1 - O (Sect1Info?, (%sect.title.content;), (%nav.class;)*,
+ (((%divcomponent.mix;)+,
+ ((%refentry.class;)* | Sect2* | SimpleSect*))
+ | (%refentry.class;)+ | Sect2+ | SimpleSect+), (%nav.class;)*)
+ %ubiq.inclusion;>
+<!--end of sect1.element-->]]>
+
+<!ENTITY % sect1.attlist "INCLUDE">
+<![ %sect1.attlist; [
+<!ATTLIST Sect1
+ --
+ Renderas: Indicates the format in which the heading should
+ appear
+ --
+ Renderas (Sect2
+ |Sect3
+ |Sect4
+ |Sect5) #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %sect1.role.attrib;
+ %local.sect1.attrib;
+>
+<!--end of sect1.attlist-->]]>
+<!--end of sect1.module-->]]>
+
+<!ENTITY % sect2.module "INCLUDE">
+<![ %sect2.module; [
+<!ENTITY % local.sect2.attrib "">
+<!ENTITY % sect2.role.attrib "%role.attrib;">
+
+<!ENTITY % sect2.element "INCLUDE">
+<![ %sect2.element; [
+<!ELEMENT Sect2 - O (Sect2Info?, (%sect.title.content;), (%nav.class;)*,
+ (((%divcomponent.mix;)+,
+ ((%refentry.class;)* | Sect3* | SimpleSect*))
+ | (%refentry.class;)+ | Sect3+ | SimpleSect+), (%nav.class;)*)>
+<!--end of sect2.element-->]]>
+
+<!ENTITY % sect2.attlist "INCLUDE">
+<![ %sect2.attlist; [
+<!ATTLIST Sect2
+ --
+ Renderas: Indicates the format in which the heading should
+ appear
+ --
+ Renderas (Sect1
+ |Sect3
+ |Sect4
+ |Sect5) #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %sect2.role.attrib;
+ %local.sect2.attrib;
+>
+<!--end of sect2.attlist-->]]>
+<!--end of sect2.module-->]]>
+
+<!ENTITY % sect3.module "INCLUDE">
+<![ %sect3.module; [
+<!ENTITY % local.sect3.attrib "">
+<!ENTITY % sect3.role.attrib "%role.attrib;">
+
+<!ENTITY % sect3.element "INCLUDE">
+<![ %sect3.element; [
+<!ELEMENT Sect3 - O (Sect3Info?, (%sect.title.content;), (%nav.class;)*,
+ (((%divcomponent.mix;)+,
+ ((%refentry.class;)* | Sect4* | SimpleSect*))
+ | (%refentry.class;)+ | Sect4+ | SimpleSect+), (%nav.class;)*)>
+<!--end of sect3.element-->]]>
+
+<!ENTITY % sect3.attlist "INCLUDE">
+<![ %sect3.attlist; [
+<!ATTLIST Sect3
+ --
+ Renderas: Indicates the format in which the heading should
+ appear
+ --
+ Renderas (Sect1
+ |Sect2
+ |Sect4
+ |Sect5) #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %sect3.role.attrib;
+ %local.sect3.attrib;
+>
+<!--end of sect3.attlist-->]]>
+<!--end of sect3.module-->]]>
+
+<!ENTITY % sect4.module "INCLUDE">
+<![ %sect4.module; [
+<!ENTITY % local.sect4.attrib "">
+<!ENTITY % sect4.role.attrib "%role.attrib;">
+
+<!ENTITY % sect4.element "INCLUDE">
+<![ %sect4.element; [
+<!ELEMENT Sect4 - O (Sect4Info?, (%sect.title.content;), (%nav.class;)*,
+ (((%divcomponent.mix;)+,
+ ((%refentry.class;)* | Sect5* | SimpleSect*))
+ | (%refentry.class;)+ | Sect5+ | SimpleSect+), (%nav.class;)*)>
+<!--end of sect4.element-->]]>
+
+<!ENTITY % sect4.attlist "INCLUDE">
+<![ %sect4.attlist; [
+<!ATTLIST Sect4
+ --
+ Renderas: Indicates the format in which the heading should
+ appear
+ --
+ Renderas (Sect1
+ |Sect2
+ |Sect3
+ |Sect5) #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %sect4.role.attrib;
+ %local.sect4.attrib;
+>
+<!--end of sect4.attlist-->]]>
+<!--end of sect4.module-->]]>
+
+<!ENTITY % sect5.module "INCLUDE">
+<![ %sect5.module; [
+<!ENTITY % local.sect5.attrib "">
+<!ENTITY % sect5.role.attrib "%role.attrib;">
+
+<!ENTITY % sect5.element "INCLUDE">
+<![ %sect5.element; [
+<!ELEMENT Sect5 - O (Sect5Info?, (%sect.title.content;), (%nav.class;)*,
+ (((%divcomponent.mix;)+, ((%refentry.class;)* | SimpleSect*))
+ | (%refentry.class;)+ | SimpleSect+), (%nav.class;)*)>
+<!--end of sect5.element-->]]>
+
+<!ENTITY % sect5.attlist "INCLUDE">
+<![ %sect5.attlist; [
+<!ATTLIST Sect5
+ --
+ Renderas: Indicates the format in which the heading should
+ appear
+ --
+ Renderas (Sect1
+ |Sect2
+ |Sect3
+ |Sect4) #IMPLIED
+ %label.attrib;
+ %status.attrib;
+ %common.attrib;
+ %sect5.role.attrib;
+ %local.sect5.attrib;
+>
+<!--end of sect5.attlist-->]]>
+<!--end of sect5.module-->]]>
+
+<!ENTITY % simplesect.module "INCLUDE">
+<![ %simplesect.module; [
+<!ENTITY % local.simplesect.attrib "">
+<!ENTITY % simplesect.role.attrib "%role.attrib;">
+
+<!ENTITY % simplesect.element "INCLUDE">
+<![ %simplesect.element; [
+<!ELEMENT SimpleSect - O ((%sect.title.content;), (%divcomponent.mix;)+)
+ %ubiq.inclusion;>
+<!--end of simplesect.element-->]]>
+
+<!ENTITY % simplesect.attlist "INCLUDE">
+<![ %simplesect.attlist; [
+<!ATTLIST SimpleSect
+ %common.attrib;
+ %simplesect.role.attrib;
+ %local.simplesect.attrib;
+>
+<!--end of simplesect.attlist-->]]>
+<!--end of simplesect.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Bibliography ......................................................... -->
+
+<!ENTITY % bibliography.content.module "INCLUDE">
+<![ %bibliography.content.module; [
+<!ENTITY % bibliography.module "INCLUDE">
+<![ %bibliography.module; [
+<!ENTITY % local.bibliography.attrib "">
+<!ENTITY % bibliography.role.attrib "%role.attrib;">
+
+<!ENTITY % bibliography.element "INCLUDE">
+<![ %bibliography.element; [
+<!ELEMENT Bibliography - O (BibliographyInfo?,
+ (%bookcomponent.title.content;)?,
+ (%component.mix;)*,
+ (BiblioDiv+ | (BiblioEntry|BiblioMixed)+))>
+<!--end of bibliography.element-->]]>
+
+<!ENTITY % bibliography.attlist "INCLUDE">
+<![ %bibliography.attlist; [
+<!ATTLIST Bibliography
+ %status.attrib;
+ %common.attrib;
+ %bibliography.role.attrib;
+ %local.bibliography.attrib;
+>
+<!--end of bibliography.attlist-->]]>
+<!--end of bibliography.module-->]]>
+
+<!ENTITY % bibliodiv.module "INCLUDE">
+<![ %bibliodiv.module; [
+<!ENTITY % local.bibliodiv.attrib "">
+<!ENTITY % bibliodiv.role.attrib "%role.attrib;">
+
+<!ENTITY % bibliodiv.element "INCLUDE">
+<![ %bibliodiv.element; [
+<!ELEMENT BiblioDiv - O ((%sect.title.content;)?, (%component.mix;)*,
+ (BiblioEntry|BiblioMixed)+)>
+<!--end of bibliodiv.element-->]]>
+
+<!ENTITY % bibliodiv.attlist "INCLUDE">
+<![ %bibliodiv.attlist; [
+<!ATTLIST BiblioDiv
+ %status.attrib;
+ %common.attrib;
+ %bibliodiv.role.attrib;
+ %local.bibliodiv.attrib;
+>
+<!--end of bibliodiv.attlist-->]]>
+<!--end of bibliodiv.module-->]]>
+<!--end of bibliography.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Glossary ............................................................. -->
+
+<!ENTITY % glossary.content.module "INCLUDE">
+<![ %glossary.content.module; [
+<!ENTITY % glossary.module "INCLUDE">
+<![ %glossary.module; [
+<!ENTITY % local.glossary.attrib "">
+<!ENTITY % glossary.role.attrib "%role.attrib;">
+
+<!ENTITY % glossary.element "INCLUDE">
+<![ %glossary.element; [
+<!ELEMENT Glossary - O (GlossaryInfo?,
+ (%bookcomponent.title.content;)?, (%component.mix;)*,
+ (GlossDiv+ | GlossEntry+), Bibliography?)>
+<!--end of glossary.element-->]]>
+
+<!ENTITY % glossary.attlist "INCLUDE">
+<![ %glossary.attlist; [
+<!ATTLIST Glossary
+ %status.attrib;
+ %common.attrib;
+ %glossary.role.attrib;
+ %local.glossary.attrib;
+>
+<!--end of glossary.attlist-->]]>
+<!--end of glossary.module-->]]>
+
+<!ENTITY % glossdiv.module "INCLUDE">
+<![ %glossdiv.module; [
+<!ENTITY % local.glossdiv.attrib "">
+<!ENTITY % glossdiv.role.attrib "%role.attrib;">
+
+<!ENTITY % glossdiv.element "INCLUDE">
+<![ %glossdiv.element; [
+<!ELEMENT GlossDiv - O ((%sect.title.content;), (%component.mix;)*,
+ GlossEntry+)>
+<!--end of glossdiv.element-->]]>
+
+<!ENTITY % glossdiv.attlist "INCLUDE">
+<![ %glossdiv.attlist; [
+<!ATTLIST GlossDiv
+ %status.attrib;
+ %common.attrib;
+ %glossdiv.role.attrib;
+ %local.glossdiv.attrib;
+>
+<!--end of glossdiv.attlist-->]]>
+<!--end of glossdiv.module-->]]>
+<!--end of glossary.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Index and SetIndex ................................................... -->
+
+<!ENTITY % index.content.module "INCLUDE">
+<![ %index.content.module; [
+<!ENTITY % index.module "INCLUDE">
+<![ %index.module; [
+<!ENTITY % local.index.attrib "">
+<!ENTITY % index.role.attrib "%role.attrib;">
+
+<!ENTITY % index.element "INCLUDE">
+<![ %index.element; [
+<!ELEMENT Index - O (IndexInfo?, (%bookcomponent.title.content;)?,
+ (%component.mix;)*, (IndexDiv* | IndexEntry*))
+ %ndxterm.exclusion;>
+<!--end of index.element-->]]>
+
+<!ENTITY % index.attlist "INCLUDE">
+<![ %index.attlist; [
+<!ATTLIST Index
+ %common.attrib;
+ %index.role.attrib;
+ %local.index.attrib;
+>
+<!--end of index.attlist-->]]>
+<!--end of index.module-->]]>
+
+<!ENTITY % setindex.module "INCLUDE">
+<![ %setindex.module; [
+<!ENTITY % local.setindex.attrib "">
+<!ENTITY % setindex.role.attrib "%role.attrib;">
+
+<!ENTITY % setindex.element "INCLUDE">
+<![ %setindex.element; [
+<!ELEMENT SetIndex - O (SetIndexInfo?, (%bookcomponent.title.content;)?,
+ (%component.mix;)*, (IndexDiv* | IndexEntry*))
+ %ndxterm.exclusion;>
+<!--end of setindex.element-->]]>
+
+<!ENTITY % setindex.attlist "INCLUDE">
+<![ %setindex.attlist; [
+<!ATTLIST SetIndex
+ %common.attrib;
+ %setindex.role.attrib;
+ %local.setindex.attrib;
+>
+<!--end of setindex.attlist-->]]>
+<!--end of setindex.module-->]]>
+
+<!ENTITY % indexdiv.module "INCLUDE">
+<![ %indexdiv.module; [
+
+<!-- SegmentedList in this content is useful for marking up permuted
+ indices. -->
+
+<!ENTITY % local.indexdiv.attrib "">
+<!ENTITY % indexdiv.role.attrib "%role.attrib;">
+
+<!ENTITY % indexdiv.element "INCLUDE">
+<![ %indexdiv.element; [
+<!ELEMENT IndexDiv - O ((%sect.title.content;)?, ((%indexdivcomponent.mix;)*,
+ (IndexEntry+ | SegmentedList)))>
+<!--end of indexdiv.element-->]]>
+
+<!ENTITY % indexdiv.attlist "INCLUDE">
+<![ %indexdiv.attlist; [
+<!ATTLIST IndexDiv
+ %common.attrib;
+ %indexdiv.role.attrib;
+ %local.indexdiv.attrib;
+>
+<!--end of indexdiv.attlist-->]]>
+<!--end of indexdiv.module-->]]>
+
+<!ENTITY % indexentry.module "INCLUDE">
+<![ %indexentry.module; [
+<!-- Index entries appear in the index, not the text. -->
+
+<!ENTITY % local.indexentry.attrib "">
+<!ENTITY % indexentry.role.attrib "%role.attrib;">
+
+<!ENTITY % indexentry.element "INCLUDE">
+<![ %indexentry.element; [
+<!ELEMENT IndexEntry - O (PrimaryIE, (SeeIE|SeeAlsoIE)*,
+ (SecondaryIE, (SeeIE|SeeAlsoIE|TertiaryIE)*)*)>
+<!--end of indexentry.element-->]]>
+
+<!ENTITY % indexentry.attlist "INCLUDE">
+<![ %indexentry.attlist; [
+<!ATTLIST IndexEntry
+ %common.attrib;
+ %indexentry.role.attrib;
+ %local.indexentry.attrib;
+>
+<!--end of indexentry.attlist-->]]>
+<!--end of indexentry.module-->]]>
+
+<!ENTITY % primsecterie.module "INCLUDE">
+<![ %primsecterie.module; [
+<!ENTITY % local.primsecterie.attrib "">
+<!ENTITY % primsecterie.role.attrib "%role.attrib;">
+
+<!ENTITY % primsecterie.elements "INCLUDE">
+<![ %primsecterie.elements; [
+<!ELEMENT (PrimaryIE | SecondaryIE | TertiaryIE) - O ((%ndxterm.char.mix;)+)>
+<!--end of primsecterie.elements-->]]>
+
+<!ENTITY % primsecterie.attlists "INCLUDE">
+<![ %primsecterie.attlists; [
+<!ATTLIST (PrimaryIE | SecondaryIE | TertiaryIE)
+ %linkends.attrib; --to IndexTerms that these entries represent--
+ %common.attrib;
+ %primsecterie.role.attrib;
+ %local.primsecterie.attrib;
+>
+<!--end of primsecterie.attlists-->]]>
+<!--end of primsecterie.module-->]]>
+
+<!ENTITY % seeie.module "INCLUDE">
+<![ %seeie.module; [
+<!ENTITY % local.seeie.attrib "">
+<!ENTITY % seeie.role.attrib "%role.attrib;">
+
+<!ENTITY % seeie.element "INCLUDE">
+<![ %seeie.element; [
+<!ELEMENT SeeIE - O ((%ndxterm.char.mix;)+)>
+<!--end of seeie.element-->]]>
+
+<!ENTITY % seeie.attlist "INCLUDE">
+<![ %seeie.attlist; [
+<!ATTLIST SeeIE
+ %linkend.attrib; --to IndexEntry to look up--
+ %common.attrib;
+ %seeie.role.attrib;
+ %local.seeie.attrib;
+>
+<!--end of seeie.attlist-->]]>
+<!--end of seeie.module-->]]>
+
+<!ENTITY % seealsoie.module "INCLUDE">
+<![ %seealsoie.module; [
+<!ENTITY % local.seealsoie.attrib "">
+<!ENTITY % seealsoie.role.attrib "%role.attrib;">
+
+<!ENTITY % seealsoie.element "INCLUDE">
+<![ %seealsoie.element; [
+<!ELEMENT SeeAlsoIE - O ((%ndxterm.char.mix;)+)>
+<!--end of seealsoie.element-->]]>
+
+<!ENTITY % seealsoie.attlist "INCLUDE">
+<![ %seealsoie.attlist; [
+<!ATTLIST SeeAlsoIE
+ %linkends.attrib; --to related IndexEntries--
+ %common.attrib;
+ %seealsoie.role.attrib;
+ %local.seealsoie.attrib;
+>
+<!--end of seealsoie.attlist-->]]>
+<!--end of seealsoie.module-->]]>
+<!--end of index.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- RefEntry ............................................................. -->
+
+<!ENTITY % refentry.content.module "INCLUDE">
+<![ %refentry.content.module; [
+<!ENTITY % refentry.module "INCLUDE">
+<![ %refentry.module; [
+<!ENTITY % local.refentry.attrib "">
+<!ENTITY % refentry.role.attrib "%role.attrib;">
+
+<!ENTITY % refentry.element "INCLUDE">
+<![ %refentry.element; [
+<!ELEMENT RefEntry - O (RefEntryInfo?, RefMeta?, (Remark|%link.char.class;)*,
+ RefNameDiv, RefSynopsisDiv?, RefSect1+) %ubiq.inclusion;>
+<!--end of refentry.element-->]]>
+
+<!ENTITY % refentry.attlist "INCLUDE">
+<![ %refentry.attlist; [
+<!ATTLIST RefEntry
+ %status.attrib;
+ %common.attrib;
+ %refentry.role.attrib;
+ %local.refentry.attrib;
+>
+<!--end of refentry.attlist-->]]>
+<!--end of refentry.module-->]]>
+
+<!ENTITY % refmeta.module "INCLUDE">
+<![ %refmeta.module; [
+<!ENTITY % local.refmeta.attrib "">
+<!ENTITY % refmeta.role.attrib "%role.attrib;">
+
+<!ENTITY % refmeta.element "INCLUDE">
+<![ %refmeta.element; [
+<!ELEMENT RefMeta - - (RefEntryTitle, ManVolNum?, RefMiscInfo*)
+ %beginpage.exclusion;>
+<!--end of refmeta.element-->]]>
+
+<!ENTITY % refmeta.attlist "INCLUDE">
+<![ %refmeta.attlist; [
+<!ATTLIST RefMeta
+ %common.attrib;
+ %refmeta.role.attrib;
+ %local.refmeta.attrib;
+>
+<!--end of refmeta.attlist-->]]>
+<!--end of refmeta.module-->]]>
+
+<!ENTITY % refmiscinfo.module "INCLUDE">
+<![ %refmiscinfo.module; [
+<!ENTITY % local.refmiscinfo.attrib "">
+<!ENTITY % refmiscinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % refmiscinfo.element "INCLUDE">
+<![ %refmiscinfo.element; [
+<!ELEMENT RefMiscInfo - - ((%docinfo.char.mix;)+)>
+<!--end of refmiscinfo.element-->]]>
+
+<!ENTITY % refmiscinfo.attlist "INCLUDE">
+<![ %refmiscinfo.attlist; [
+<!ATTLIST RefMiscInfo
+ --
+ Class: Freely assignable parameter; no default
+ --
+ Class CDATA #IMPLIED
+ %common.attrib;
+ %refmiscinfo.role.attrib;
+ %local.refmiscinfo.attrib;
+>
+<!--end of refmiscinfo.attlist-->]]>
+<!--end of refmiscinfo.module-->]]>
+
+<!ENTITY % refnamediv.module "INCLUDE">
+<![ %refnamediv.module; [
+<!ENTITY % local.refnamediv.attrib "">
+<!ENTITY % refnamediv.role.attrib "%role.attrib;">
+
+<!ENTITY % refnamediv.element "INCLUDE">
+<![ %refnamediv.element; [
+<!ELEMENT RefNameDiv - O (RefDescriptor?, RefName+, RefPurpose, RefClass*,
+ (Remark|%link.char.class;)*)>
+<!--end of refnamediv.element-->]]>
+
+<!ENTITY % refnamediv.attlist "INCLUDE">
+<![ %refnamediv.attlist; [
+<!ATTLIST RefNameDiv
+ %common.attrib;
+ %refnamediv.role.attrib;
+ %local.refnamediv.attrib;
+>
+<!--end of refnamediv.attlist-->]]>
+<!--end of refnamediv.module-->]]>
+
+<!ENTITY % refdescriptor.module "INCLUDE">
+<![ %refdescriptor.module; [
+<!ENTITY % local.refdescriptor.attrib "">
+<!ENTITY % refdescriptor.role.attrib "%role.attrib;">
+
+<!ENTITY % refdescriptor.element "INCLUDE">
+<![ %refdescriptor.element; [
+<!ELEMENT RefDescriptor - O ((%refname.char.mix;)+)>
+<!--end of refdescriptor.element-->]]>
+
+<!ENTITY % refdescriptor.attlist "INCLUDE">
+<![ %refdescriptor.attlist; [
+<!ATTLIST RefDescriptor
+ %common.attrib;
+ %refdescriptor.role.attrib;
+ %local.refdescriptor.attrib;
+>
+<!--end of refdescriptor.attlist-->]]>
+<!--end of refdescriptor.module-->]]>
+
+<!ENTITY % refname.module "INCLUDE">
+<![ %refname.module; [
+<!ENTITY % local.refname.attrib "">
+<!ENTITY % refname.role.attrib "%role.attrib;">
+
+<!ENTITY % refname.element "INCLUDE">
+<![ %refname.element; [
+<!ELEMENT RefName - O ((%refname.char.mix;)+)>
+<!--end of refname.element-->]]>
+
+<!ENTITY % refname.attlist "INCLUDE">
+<![ %refname.attlist; [
+<!ATTLIST RefName
+ %common.attrib;
+ %refname.role.attrib;
+ %local.refname.attrib;
+>
+<!--end of refname.attlist-->]]>
+<!--end of refname.module-->]]>
+
+<!ENTITY % refpurpose.module "INCLUDE">
+<![ %refpurpose.module; [
+<!ENTITY % local.refpurpose.attrib "">
+<!ENTITY % refpurpose.role.attrib "%role.attrib;">
+
+<!ENTITY % refpurpose.element "INCLUDE">
+<![ %refpurpose.element; [
+<!ELEMENT RefPurpose - O ((%refinline.char.mix;)+)>
+<!--end of refpurpose.element-->]]>
+
+<!ENTITY % refpurpose.attlist "INCLUDE">
+<![ %refpurpose.attlist; [
+<!ATTLIST RefPurpose
+ %common.attrib;
+ %refpurpose.role.attrib;
+ %local.refpurpose.attrib;
+>
+<!--end of refpurpose.attlist-->]]>
+<!--end of refpurpose.module-->]]>
+
+<!ENTITY % refclass.module "INCLUDE">
+<![ %refclass.module; [
+<!ENTITY % local.refclass.attrib "">
+<!ENTITY % refclass.role.attrib "%role.attrib;">
+
+<!ENTITY % refclass.element "INCLUDE">
+<![ %refclass.element; [
+<!ELEMENT RefClass - O ((%refclass.char.mix;)+)>
+<!--end of refclass.element-->]]>
+
+<!ENTITY % refclass.attlist "INCLUDE">
+<![ %refclass.attlist; [
+<!ATTLIST RefClass
+ %common.attrib;
+ %refclass.role.attrib;
+ %local.refclass.attrib;
+>
+<!--end of refclass.attlist-->]]>
+<!--end of refclass.module-->]]>
+
+<!ENTITY % refsynopsisdiv.module "INCLUDE">
+<![ %refsynopsisdiv.module; [
+<!ENTITY % local.refsynopsisdiv.attrib "">
+<!ENTITY % refsynopsisdiv.role.attrib "%role.attrib;">
+
+<!ENTITY % refsynopsisdiv.element "INCLUDE">
+<![ %refsynopsisdiv.element; [
+<!ELEMENT RefSynopsisDiv - O (RefSynopsisDivInfo?, (%refsect.title.content;)?,
+ (((%refcomponent.mix;)+, RefSect2*) | (RefSect2+)))>
+<!--end of refsynopsisdiv.element-->]]>
+
+<!ENTITY % refsynopsisdiv.attlist "INCLUDE">
+<![ %refsynopsisdiv.attlist; [
+<!ATTLIST RefSynopsisDiv
+ %common.attrib;
+ %refsynopsisdiv.role.attrib;
+ %local.refsynopsisdiv.attrib;
+>
+<!--end of refsynopsisdiv.attlist-->]]>
+<!--end of refsynopsisdiv.module-->]]>
+
+<!ENTITY % refsect1.module "INCLUDE">
+<![ %refsect1.module; [
+<!ENTITY % local.refsect1.attrib "">
+<!ENTITY % refsect1.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect1.element "INCLUDE">
+<![ %refsect1.element; [
+<!ELEMENT RefSect1 - O (RefSect1Info?, (%refsect.title.content;),
+ (((%refcomponent.mix;)+, RefSect2*) | RefSect2+))>
+<!--end of refsect1.element-->]]>
+
+<!ENTITY % refsect1.attlist "INCLUDE">
+<![ %refsect1.attlist; [
+<!ATTLIST RefSect1
+ %status.attrib;
+ %common.attrib;
+ %refsect1.role.attrib;
+ %local.refsect1.attrib;
+>
+<!--end of refsect1.attlist-->]]>
+<!--end of refsect1.module-->]]>
+
+<!ENTITY % refsect2.module "INCLUDE">
+<![ %refsect2.module; [
+<!ENTITY % local.refsect2.attrib "">
+<!ENTITY % refsect2.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect2.element "INCLUDE">
+<![ %refsect2.element; [
+<!ELEMENT RefSect2 - O (RefSect2Info?, (%refsect.title.content;),
+ (((%refcomponent.mix;)+, RefSect3*) | RefSect3+))>
+<!--end of refsect2.element-->]]>
+
+<!ENTITY % refsect2.attlist "INCLUDE">
+<![ %refsect2.attlist; [
+<!ATTLIST RefSect2
+ %status.attrib;
+ %common.attrib;
+ %refsect2.role.attrib;
+ %local.refsect2.attrib;
+>
+<!--end of refsect2.attlist-->]]>
+<!--end of refsect2.module-->]]>
+
+<!ENTITY % refsect3.module "INCLUDE">
+<![ %refsect3.module; [
+<!ENTITY % local.refsect3.attrib "">
+<!ENTITY % refsect3.role.attrib "%role.attrib;">
+
+<!ENTITY % refsect3.element "INCLUDE">
+<![ %refsect3.element; [
+<!ELEMENT RefSect3 - O (RefSect3Info?, (%refsect.title.content;),
+ (%refcomponent.mix;)+)>
+<!--end of refsect3.element-->]]>
+
+<!ENTITY % refsect3.attlist "INCLUDE">
+<![ %refsect3.attlist; [
+<!ATTLIST RefSect3
+ %status.attrib;
+ %common.attrib;
+ %refsect3.role.attrib;
+ %local.refsect3.attrib;
+>
+<!--end of refsect3.attlist-->]]>
+<!--end of refsect3.module-->]]>
+<!--end of refentry.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Article .............................................................. -->
+
+<!ENTITY % article.module "INCLUDE">
+<![ %article.module; [
+<!-- An Article is a chapter-level, stand-alone document that is often,
+ but need not be, collected into a Book. -->
+
+<!ENTITY % local.article.attrib "">
+<!ENTITY % article.role.attrib "%role.attrib;">
+
+<!ENTITY % article.element "INCLUDE">
+<![ %article.element; [
+<!ELEMENT Article - O ((%div.title.content;)?, ArticleInfo?, ToCchap?, LoT*,
+ (%bookcomponent.content;),
+ ((%nav.class;) | (%appendix.class;) | Ackno)*)
+ %ubiq.inclusion;>
+<!--end of article.element-->]]>
+
+<!ENTITY % article.attlist "INCLUDE">
+<![ %article.attlist; [
+<!ATTLIST Article
+ --
+ Class: Indicates the type of a particular article;
+ all articles have the same structure and general purpose.
+ No default.
+ --
+ Class (JournalArticle
+ |ProductSheet
+ |WhitePaper
+ |TechReport
+ |Specification
+ |FAQ) #IMPLIED
+ --
+ ParentBook: ID of the enclosing Book
+ --
+ ParentBook IDREF #IMPLIED
+ %status.attrib;
+ %common.attrib;
+ %article.role.attrib;
+ %local.article.attrib;
+>
+<!--end of article.attlist-->]]>
+<!--end of article.module-->]]>
+
+<!-- End of DocBook document hierarchy module V4.1 ........................ -->
+<!-- ...................................................................... -->
diff --git a/docs/docbook/dbsgml/dbnotn.mod b/docs/docbook/dbsgml/dbnotn.mod
new file mode 100755
index 00000000000..32d80dd91d5
--- /dev/null
+++ b/docs/docbook/dbsgml/dbnotn.mod
@@ -0,0 +1,97 @@
+<!-- ...................................................................... -->
+<!-- DocBook notations module V4.1 ........................................ -->
+<!-- File dbnotn.mod ...................................................... -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ $Id: dbnotn.mod,v 1.1.2.1 2001/02/28 19:05:00 jerry Exp $
+
+ Permission to use, copy, modify and distribute the DocBook DTD and
+ its accompanying documentation for any purpose and without fee is
+ hereby granted in perpetuity, provided that the above copyright
+ notice and this paragraph appear in all copies. The copyright
+ holders make no representation about the suitability of the DTD for
+ any purpose. It is provided "as is" without expressed or implied
+ warranty.
+
+ If you modify the DocBook DTD in any way, except for declaring and
+ referencing additional sets of general entities and declaring
+ additional notations, label your DTD as a variant of DocBook. See
+ the maintenance documentation for more information.
+
+ Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/docbook/.
+-->
+
+<!-- ...................................................................... -->
+
+<!-- This module contains the entity declarations for the standard
+ notations used by DocBook.
+
+ In DTD driver files referring to this module, please use an entity
+ declaration that uses the public identifier shown below:
+
+ <!ENTITY % dbnotn PUBLIC
+ "-//OASIS//ENTITIES DocBook Notations V4.1//EN">
+ %dbnotn;
+
+ See the documentation for detailed information on the parameter
+ entity and module scheme used in DocBook, customizing DocBook and
+ planning for interchange, and changes made since the last release
+ of DocBook.
+-->
+
+<!ENTITY % local.notation.class "">
+<!ENTITY % notation.class
+ "BMP| CGM-CHAR | CGM-BINARY | CGM-CLEAR | DITROFF | DVI
+ | EPS | EQN | FAX | GIF | GIF87a | GIF89a
+ | JPG | JPEG | IGES | PCX
+ | PIC | PNG | PS | SGML | TBL | TEX | TIFF | WMF | WPG
+ | linespecific
+ %local.notation.class;">
+
+<!NOTATION BMP PUBLIC
+"+//ISBN 0-7923-9432-1::Graphic Notation//NOTATION Microsoft Windows bitmap//EN">
+<!NOTATION CGM-CHAR PUBLIC "ISO 8632/2//NOTATION Character encoding//EN">
+<!NOTATION CGM-BINARY PUBLIC "ISO 8632/3//NOTATION Binary encoding//EN">
+<!NOTATION CGM-CLEAR PUBLIC "ISO 8632/4//NOTATION Clear text encoding//EN">
+<!NOTATION DITROFF SYSTEM "DITROFF">
+<!NOTATION DVI SYSTEM "DVI">
+<!NOTATION EPS PUBLIC
+"+//ISBN 0-201-18127-4::Adobe//NOTATION PostScript Language Ref. Manual//EN">
+<!-- EQN was SYSTEM "-//AT&T//NOTATION EQN-1//EN" -->
+<!NOTATION EQN SYSTEM>
+<!NOTATION FAX PUBLIC
+"-//USA-DOD//NOTATION CCITT Group 4 Facsimile Type 1 Untiled Raster//EN">
+<!NOTATION GIF SYSTEM "GIF">
+<!NOTATION GIF87a PUBLIC
+"-//CompuServe//NOTATION Graphics Interchange Format 87a//EN">
+
+<!NOTATION GIF89a PUBLIC
+"-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">
+<!NOTATION JPG SYSTEM "JPG">
+<!NOTATION JPEG SYSTEM "JPG">
+<!NOTATION IGES PUBLIC
+"-//USA-DOD//NOTATION (ASME/ANSI Y14.26M-1987) Initial Graphics Exchange Specification//EN">
+<!NOTATION PCX PUBLIC
+"+//ISBN 0-7923-9432-1::Graphic Notation//NOTATION ZSoft PCX bitmap//EN">
+<!-- PIC was SYSTEM "-//AT&T//NOTATION EQN-1//EN" -->
+<!NOTATION PIC SYSTEM>
+<!NOTATION PNG SYSTEM "http://www.w3.org/TR/REC-png">
+<!NOTATION PS SYSTEM "PS">
+<!NOTATION SGML PUBLIC
+"ISO 8879:1986//NOTATION Standard Generalized Markup Language//EN">
+<!-- TBL was SYSTEM "-//AT&T//NOTATION EQN-1//EN" -->
+<!NOTATION TBL SYSTEM>
+<!NOTATION TEX PUBLIC
+"+//ISBN 0-201-13448-9::Knuth//NOTATION The TeXbook//EN">
+<!NOTATION TIFF SYSTEM "TIFF">
+<!NOTATION WMF PUBLIC
+"+//ISBN 0-7923-9432-1::Graphic Notation//NOTATION Microsoft Windows Metafile//EN">
+<!NOTATION WPG SYSTEM "WPG" --WordPerfect Graphic format-->
+<!NOTATION linespecific SYSTEM
+"line ends and leading white space must be preserved in output">
diff --git a/docs/docbook/dbsgml/dbpool.mod b/docs/docbook/dbsgml/dbpool.mod
new file mode 100755
index 00000000000..14dfb6a7cb8
--- /dev/null
+++ b/docs/docbook/dbsgml/dbpool.mod
@@ -0,0 +1,7396 @@
+<!-- ...................................................................... -->
+<!-- DocBook information pool module V4.1 ................................. -->
+<!-- File dbpool.mod ...................................................... -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ $Id: dbpool.mod,v 1.1.2.1 2001/02/28 19:05:00 jerry Exp $
+
+ Permission to use, copy, modify and distribute the DocBook DTD and
+ its accompanying documentation for any purpose and without fee is
+ hereby granted in perpetuity, provided that the above copyright
+ notice and this paragraph appear in all copies. The copyright
+ holders make no representation about the suitability of the DTD for
+ any purpose. It is provided "as is" without expressed or implied
+ warranty.
+
+ If you modify the DocBook DTD in any way, except for declaring and
+ referencing additional sets of general entities and declaring
+ additional notations, label your DTD as a variant of DocBook. See
+ the maintenance documentation for more information.
+
+ Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/docbook/.
+-->
+
+<!-- ...................................................................... -->
+
+<!-- This module contains the definitions for the objects, inline
+ elements, and so on that are available to be used as the main
+ content of DocBook documents. Some elements are useful for general
+ publishing, and others are useful specifically for computer
+ documentation.
+
+ This module has the following dependencies on other modules:
+
+ o It assumes that a %notation.class; entity is defined by the
+ driver file or other high-level module. This entity is
+ referenced in the NOTATION attributes for the graphic-related and
+ ModeSpec elements.
+
+ o It assumes that an appropriately parameterized table module is
+ available for use with the table-related elements.
+
+ In DTD driver files referring to this module, please use an entity
+ declaration that uses the public identifier shown below:
+
+ <!ENTITY % dbpool PUBLIC
+ "-//OASIS//ELEMENTS DocBook Information Pool V4.1//EN">
+ %dbpool;
+
+ See the documentation for detailed information on the parameter
+ entity and module scheme used in DocBook, customizing DocBook and
+ planning for interchange, and changes made since the last release
+ of DocBook.
+-->
+
+<!-- ...................................................................... -->
+<!-- General-purpose semantics entities ................................... -->
+
+<!ENTITY % yesorno.attvals "NUMBER">
+
+<![IGNORE[
+<!ENTITY % yes.attval "1"> <!-- never actually used -->
+]]>
+
+<!ENTITY % no.attval "0">
+
+<!-- ...................................................................... -->
+<!-- Entities for module inclusions ....................................... -->
+
+<!ENTITY % dbpool.redecl.module "IGNORE">
+
+<!-- ...................................................................... -->
+<!-- Entities for element classes and mixtures ............................ -->
+
+<!-- Object-level classes ................................................. -->
+
+<!ENTITY % local.list.class "">
+<!ENTITY % list.class
+ "CalloutList|GlossList|ItemizedList|OrderedList|SegmentedList
+ |SimpleList|VariableList %local.list.class;">
+
+<!ENTITY % local.admon.class "">
+<!ENTITY % admon.class
+ "Caution|Important|Note|Tip|Warning %local.admon.class;">
+
+<!ENTITY % local.linespecific.class "">
+<!ENTITY % linespecific.class
+ "LiteralLayout|ProgramListing|ProgramListingCO|Screen
+ |ScreenCO|ScreenShot %local.linespecific.class;">
+
+<!ENTITY % local.method.synop.class "">
+<!ENTITY % method.synop.class
+ "ConstructorSynopsis
+ |DestructorSynopsis
+ |MethodSynopsis %local.method.synop.class;">
+
+<!ENTITY % local.synop.class "">
+<!ENTITY % synop.class
+ "Synopsis|CmdSynopsis|FuncSynopsis
+ |ClassSynopsis|FieldSynopsis
+ |%method.synop.class; %local.synop.class;">
+
+<!ENTITY % local.para.class "">
+<!ENTITY % para.class
+ "FormalPara|Para|SimPara %local.para.class;">
+
+<!ENTITY % local.informal.class "">
+<!ENTITY % informal.class
+ "Address|BlockQuote
+ |Graphic|GraphicCO|MediaObject|MediaObjectCO
+ |InformalEquation
+ |InformalExample
+ |InformalFigure
+ |InformalTable %local.informal.class;">
+
+<!ENTITY % local.formal.class "">
+<!ENTITY % formal.class
+ "Equation|Example|Figure|Table %local.formal.class;">
+
+<!-- The DocBook TC may produce an official EBNF module for DocBook. -->
+<!-- This PE provides the hook by which it can be inserted into the DTD. -->
+<!ENTITY % ebnf.block.hook "">
+
+<!ENTITY % local.compound.class "">
+<!ENTITY % compound.class
+ "MsgSet|Procedure|Sidebar|QandASet
+ %ebnf.block.hook;
+ %local.compound.class;">
+
+<!ENTITY % local.genobj.class "">
+<!ENTITY % genobj.class
+ "Anchor|BridgeHead|Remark|Highlights
+ %local.genobj.class;">
+
+<!ENTITY % local.descobj.class "">
+<!ENTITY % descobj.class
+ "Abstract|AuthorBlurb|Epigraph
+ %local.descobj.class;">
+
+<!-- Character-level classes .............................................. -->
+
+<!ENTITY % local.ndxterm.class "">
+<!ENTITY % ndxterm.class
+ "IndexTerm %local.ndxterm.class;">
+
+<!ENTITY % local.xref.char.class "">
+<!ENTITY % xref.char.class
+ "FootnoteRef|XRef %local.xref.char.class;">
+
+<!ENTITY % local.gen.char.class "">
+<!ENTITY % gen.char.class
+ "Abbrev|Acronym|Citation|CiteRefEntry|CiteTitle|Emphasis
+ |FirstTerm|ForeignPhrase|GlossTerm|Footnote|Phrase
+ |Quote|Trademark|WordAsWord %local.gen.char.class;">
+
+<!ENTITY % local.link.char.class "">
+<!ENTITY % link.char.class
+ "Link|OLink|ULink %local.link.char.class;">
+
+<!-- The DocBook TC may produce an official EBNF module for DocBook. -->
+<!-- This PE provides the hook by which it can be inserted into the DTD. -->
+<!ENTITY % ebnf.inline.hook "">
+
+<!ENTITY % local.tech.char.class "">
+<!ENTITY % tech.char.class
+ "Action|Application
+ |ClassName|MethodName|InterfaceName|ExceptionName
+ |OOClass|OOInterface|OOException
+ |Command|ComputerOutput
+ |Database|Email|EnVar|ErrorCode|ErrorName|ErrorType|Filename
+ |Function|GUIButton|GUIIcon|GUILabel|GUIMenu|GUIMenuItem
+ |GUISubmenu|Hardware|Interface|KeyCap
+ |KeyCode|KeyCombo|KeySym|Literal|Constant|Markup|MediaLabel
+ |MenuChoice|MouseButton|Option|Optional|Parameter
+ |Prompt|Property|Replaceable|ReturnValue|SGMLTag|StructField
+ |StructName|Symbol|SystemItem|Token|Type|UserInput|VarName
+ %ebnf.inline.hook;
+ %local.tech.char.class;">
+
+<!ENTITY % local.base.char.class "">
+<!ENTITY % base.char.class
+ "Anchor %local.base.char.class;">
+
+<!ENTITY % local.docinfo.char.class "">
+<!ENTITY % docinfo.char.class
+ "Author|AuthorInitials|CorpAuthor|ModeSpec|OtherCredit
+ |ProductName|ProductNumber|RevHistory
+ %local.docinfo.char.class;">
+
+<!ENTITY % local.other.char.class "">
+<!ENTITY % other.char.class
+ "Remark|Subscript|Superscript %local.other.char.class;">
+
+<!ENTITY % local.inlineobj.char.class "">
+<!ENTITY % inlineobj.char.class
+ "InlineGraphic|InlineMediaObject|InlineEquation %local.inlineobj.char.class;">
+
+<!-- Redeclaration placeholder ............................................ -->
+
+<!-- For redeclaring entities that are declared after this point while
+ retaining their references to the entities that are declared before
+ this point -->
+
+<![ %dbpool.redecl.module; [
+%rdbpool;
+<!--end of dbpool.redecl.module-->]]>
+
+<!-- Object-level mixtures ................................................ -->
+
+<!--
+ list admn line synp para infm form cmpd gen desc
+Component mixture X X X X X X X X X X
+Sidebar mixture X X X X X X X a X
+Footnote mixture X X X X X
+Example mixture X X X X X
+Highlights mixture X X X
+Paragraph mixture X X X X
+Admonition mixture X X X X X X b c
+Figure mixture X X X
+Table entry mixture X X X X d
+Glossary def mixture X X X X X e
+Legal notice mixture X X X X f
+
+a. Just Procedure; not Sidebar itself or MsgSet.
+b. No MsgSet.
+c. No Highlights.
+d. Just Graphic; no other informal objects.
+e. No Anchor, BridgeHead, or Highlights.
+f. Just BlockQuote; no other informal objects.
+-->
+
+<!ENTITY % local.component.mix "">
+<!ENTITY % component.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |%compound.class;
+ |%genobj.class; |%descobj.class;
+ |%ndxterm.class;
+ %local.component.mix;">
+
+<!ENTITY % local.sidebar.mix "">
+<!ENTITY % sidebar.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |Procedure
+ |%genobj.class;
+ |%ndxterm.class;
+ %local.sidebar.mix;">
+
+<!ENTITY % local.qandaset.mix "">
+<!ENTITY % qandaset.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |Procedure
+ |%genobj.class;
+ |%ndxterm.class;
+ %local.qandaset.mix;">
+
+<!ENTITY % local.revdescription.mix "">
+<!ENTITY % revdescription.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |Procedure
+ |%genobj.class;
+ |%ndxterm.class;
+ %local.revdescription.mix;">
+
+<!ENTITY % local.footnote.mix "">
+<!ENTITY % footnote.mix
+ "%list.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ %local.footnote.mix;">
+
+<!ENTITY % local.example.mix "">
+<!ENTITY % example.mix
+ "%list.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%ndxterm.class;
+ %local.example.mix;">
+
+<!ENTITY % local.highlights.mix "">
+<!ENTITY % highlights.mix
+ "%list.class; |%admon.class;
+ |%para.class;
+ |%ndxterm.class;
+ %local.highlights.mix;">
+
+<!-- %formal.class; is explicitly excluded from many contexts in which
+ paragraphs are used -->
+
+<!ENTITY % local.para.mix "">
+<!ENTITY % para.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class;
+ |%informal.class;
+ |%formal.class;
+ %local.para.mix;">
+
+<!ENTITY % local.admon.mix "">
+<!ENTITY % admon.mix
+ "%list.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class; |Procedure|Sidebar
+ |Anchor|BridgeHead|Remark
+ |%ndxterm.class;
+ %local.admon.mix;">
+
+<!ENTITY % local.figure.mix "">
+<!ENTITY % figure.mix
+ "%linespecific.class; |%synop.class;
+ |%informal.class;
+ |%ndxterm.class;
+ %local.figure.mix;">
+
+<!ENTITY % local.tabentry.mix "">
+<!ENTITY % tabentry.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class;
+ |%para.class; |Graphic|MediaObject
+ %local.tabentry.mix;">
+
+<!ENTITY % local.glossdef.mix "">
+<!ENTITY % glossdef.mix
+ "%list.class;
+ |%linespecific.class; |%synop.class;
+ |%para.class; |%informal.class;
+ |%formal.class;
+ |Remark
+ |%ndxterm.class;
+ %local.glossdef.mix;">
+
+<!ENTITY % local.legalnotice.mix "">
+<!ENTITY % legalnotice.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class;
+ |%para.class; |BlockQuote
+ |%ndxterm.class;
+ %local.legalnotice.mix;">
+
+<!ENTITY % local.textobject.mix "">
+<!ENTITY % textobject.mix
+ "%list.class; |%admon.class;
+ |%linespecific.class;
+ |%para.class; |BlockQuote
+ %local.textobject.mix;">
+
+<!ENTITY % local.mediaobject.mix "">
+<!ENTITY % mediaobject.mix
+ "VideoObject|AudioObject|ImageObject %local.mediaobject.mix">
+
+<!-- Character-level mixtures ............................................. -->
+
+<!ENTITY % local.ubiq.mix "">
+<!ENTITY % ubiq.mix
+ "%ndxterm.class;|BeginPage %local.ubiq.mix;">
+
+<!ENTITY % ubiq.exclusion "-(%ubiq.mix)">
+<!ENTITY % ubiq.inclusion "+(%ubiq.mix)">
+
+<!ENTITY % footnote.exclusion "-(Footnote|%formal.class;)">
+<!ENTITY % highlights.exclusion "-(%ubiq.mix;|%formal.class;)">
+<!ENTITY % admon.exclusion "-(%admon.class;)">
+<!ENTITY % formal.exclusion "-(%formal.class;)">
+<!ENTITY % acronym.exclusion "-(Acronym)">
+<!ENTITY % beginpage.exclusion "-(BeginPage)">
+<!ENTITY % ndxterm.exclusion "-(%ndxterm.class;)">
+<!ENTITY % blockquote.exclusion "-(Epigraph)">
+<!ENTITY % remark.exclusion "-(Remark|%ubiq.mix;)">
+<!ENTITY % glossterm.exclusion "-(GlossTerm)">
+<!ENTITY % links.exclusion "-(Link|OLink|ULink|XRef)">
+
+<!--
+ #PCD xref word link cptr base dnfo othr inob (synop)
+para.char.mix X X X X X X X X X
+title.char.mix X X X X X X X X X
+ndxterm.char.mix X X X X X X X X a
+cptr.char.mix X X X X X a
+smallcptr.char.mix X b a
+word.char.mix X c X X X a
+docinfo.char.mix X d X b X a
+
+a. Just InlineGraphic; no InlineEquation.
+b. Just Replaceable; no other computer terms.
+c. Just Emphasis and Trademark; no other word elements.
+d. Just Acronym, Emphasis, and Trademark; no other word elements.
+-->
+
+<!-- The DocBook TC may produce an official forms module for DocBook. -->
+<!-- This PE provides the hook by which it can be inserted into the DTD. -->
+<!ENTITY % forminlines.hook "">
+
+<!ENTITY % local.para.char.mix "">
+<!ENTITY % para.char.mix
+ "#PCDATA
+ |%xref.char.class; |%gen.char.class;
+ |%link.char.class; |%tech.char.class;
+ |%base.char.class; |%docinfo.char.class;
+ |%other.char.class; |%inlineobj.char.class;
+ |%synop.class;
+ |%ndxterm.class;
+ %forminlines.hook;
+ %local.para.char.mix;">
+
+<!ENTITY % local.title.char.mix "">
+<!ENTITY % title.char.mix
+ "#PCDATA
+ |%xref.char.class; |%gen.char.class;
+ |%link.char.class; |%tech.char.class;
+ |%base.char.class; |%docinfo.char.class;
+ |%other.char.class; |%inlineobj.char.class;
+ |%ndxterm.class;
+ %local.title.char.mix;">
+
+<!ENTITY % local.ndxterm.char.mix "">
+<!ENTITY % ndxterm.char.mix
+ "#PCDATA
+ |%xref.char.class; |%gen.char.class;
+ |%link.char.class; |%tech.char.class;
+ |%base.char.class; |%docinfo.char.class;
+ |%other.char.class; |InlineGraphic|InlineMediaObject
+ %local.ndxterm.char.mix;">
+
+<!ENTITY % local.cptr.char.mix "">
+<!ENTITY % cptr.char.mix
+ "#PCDATA
+ |%link.char.class; |%tech.char.class;
+ |%base.char.class;
+ |%other.char.class; |InlineGraphic|InlineMediaObject
+ |%ndxterm.class;
+ %local.cptr.char.mix;">
+
+<!ENTITY % local.smallcptr.char.mix "">
+<!ENTITY % smallcptr.char.mix
+ "#PCDATA
+ |Replaceable
+ |InlineGraphic|InlineMediaObject
+ |%ndxterm.class;
+ %local.smallcptr.char.mix;">
+
+<!ENTITY % local.word.char.mix "">
+<!ENTITY % word.char.mix
+ "#PCDATA
+ |Acronym|Emphasis|Trademark
+ |%link.char.class;
+ |%base.char.class;
+ |%other.char.class; |InlineGraphic|InlineMediaObject
+ |%ndxterm.class;
+ %local.word.char.mix;">
+
+<!ENTITY % local.docinfo.char.mix "">
+<!ENTITY % docinfo.char.mix
+ "#PCDATA
+ |%link.char.class;
+ |Emphasis|Trademark
+ |Replaceable
+ |%other.char.class; |InlineGraphic|InlineMediaObject
+ |%ndxterm.class;
+ %local.docinfo.char.mix;">
+<!--ENTITY % bibliocomponent.mix (see Bibliographic section, below)-->
+<!--ENTITY % person.ident.mix (see Bibliographic section, below)-->
+
+<!-- ...................................................................... -->
+<!-- Entities for content models .......................................... -->
+
+<!ENTITY % formalobject.title.content "Title, TitleAbbrev?">
+
+<!-- ...................................................................... -->
+<!-- Entities for attributes and attribute components ..................... -->
+
+<!-- Effectivity attributes ............................................... -->
+
+<!ENTITY % arch.attrib
+ --Arch: Computer or chip architecture to which element applies; no
+ default--
+ "Arch CDATA #IMPLIED">
+
+<!ENTITY % condition.attrib
+ --Condition: General-purpose effectivity attribute--
+ "Condition CDATA #IMPLIED">
+
+<!ENTITY % conformance.attrib
+ --Conformance: Standards conformance characteristics--
+ "Conformance NMTOKENS #IMPLIED">
+
+<!ENTITY % os.attrib
+ --OS: Operating system to which element applies; no default--
+ "OS CDATA #IMPLIED">
+
+<!ENTITY % revision.attrib
+ --Revision: Editorial revision to which element belongs; no default--
+ "Revision CDATA #IMPLIED">
+
+<!ENTITY % security.attrib
+ --Security: Security classification; no default--
+ "Security CDATA #IMPLIED">
+
+<!ENTITY % userlevel.attrib
+ --UserLevel: Level of user experience to which element applies; no
+ default--
+ "UserLevel CDATA #IMPLIED">
+
+<!ENTITY % vendor.attrib
+ --Vendor: Computer vendor to which element applies; no default--
+ "Vendor CDATA #IMPLIED">
+
+<!ENTITY % local.effectivity.attrib "">
+<!ENTITY % effectivity.attrib
+ "%arch.attrib;
+ %condition.attrib;
+ %conformance.attrib;
+ %os.attrib;
+ %revision.attrib;
+ %security.attrib;
+ %userlevel.attrib;
+ %vendor.attrib;
+ %local.effectivity.attrib;"
+>
+
+<!-- Common attributes .................................................... -->
+
+<!ENTITY % id.attrib
+ --Id: Unique identifier of element; no default--
+ "Id ID #IMPLIED">
+
+<!ENTITY % idreq.attrib
+ --Id: Unique identifier of element; a value must be supplied; no
+ default--
+ "Id ID #REQUIRED">
+
+<!ENTITY % lang.attrib
+ --Lang: Indicator of language in which element is written, for
+ translation, character set management, etc.; no default--
+ "Lang CDATA #IMPLIED">
+
+<!ENTITY % remap.attrib
+ --Remap: Previous role of element before conversion; no default--
+ "Remap CDATA #IMPLIED">
+
+<!ENTITY % role.attrib
+ --Role: New role of element in local environment; no default--
+ "Role CDATA #IMPLIED">
+
+<!ENTITY % xreflabel.attrib
+ --XRefLabel: Alternate labeling string for XRef text generation;
+ default is usually title or other appropriate label text already
+ contained in element--
+ "XRefLabel CDATA #IMPLIED">
+
+<!ENTITY % revisionflag.attrib
+ --RevisionFlag: Revision status of element; default is that element
+ wasn't revised--
+ "RevisionFlag (Changed
+ |Added
+ |Deleted
+ |Off) #IMPLIED">
+
+<!ENTITY % local.common.attrib "">
+<!ENTITY % common.attrib
+ "%id.attrib;
+ %lang.attrib;
+ %remap.attrib;
+ --Role is included explicitly on each element--
+ %xreflabel.attrib;
+ %revisionflag.attrib;
+ %effectivity.attrib;
+ %local.common.attrib;"
+>
+
+<!ENTITY % idreq.common.attrib
+ "%idreq.attrib;
+ %lang.attrib;
+ %remap.attrib;
+ --Role is included explicitly on each element--
+ %xreflabel.attrib;
+ %revisionflag.attrib;
+ %effectivity.attrib;
+ %local.common.attrib;"
+>
+
+<!-- Semi-common attributes and other attribute entities .................. -->
+
+<!ENTITY % local.graphics.attrib "">
+<!ENTITY % graphics.attrib
+ "
+ --EntityRef: Name of an external entity containing the content
+ of the graphic--
+ EntityRef ENTITY #IMPLIED
+
+ --FileRef: Filename, qualified by a pathname if desired,
+ designating the file containing the content of the graphic--
+ FileRef CDATA #IMPLIED
+
+ --Format: Notation of the element content, if any--
+ Format (%notation.class;)
+ #IMPLIED
+
+ --SrcCredit: Information about the source of the Graphic--
+ SrcCredit CDATA #IMPLIED
+
+ --Width: Same as CALS reprowid (desired width)--
+ Width NUTOKEN #IMPLIED
+
+ --Depth: Same as CALS reprodep (desired depth)--
+ Depth NUTOKEN #IMPLIED
+
+ --Align: Same as CALS hplace with 'none' removed; #IMPLIED means
+ application-specific--
+ Align (Left
+ |Right
+ |Center) #IMPLIED
+
+ --Scale: Conflation of CALS hscale and vscale--
+ Scale NUMBER #IMPLIED
+
+ --Scalefit: Same as CALS scalefit--
+ Scalefit %yesorno.attvals;
+ #IMPLIED
+ %local.graphics.attrib;"
+>
+
+<!ENTITY % local.keyaction.attrib "">
+<!ENTITY % keyaction.attrib
+ "
+ --Action: Key combination type; default is unspecified if one
+ child element, Simul if there is more than one; if value is
+ Other, the OtherAction attribute must have a nonempty value--
+ Action (Click
+ |Double-Click
+ |Press
+ |Seq
+ |Simul
+ |Other) #IMPLIED
+
+ --OtherAction: User-defined key combination type--
+ OtherAction CDATA #IMPLIED
+ %local.keyaction.attrib;"
+>
+
+<!ENTITY % label.attrib
+ --Label: Identifying number or string; default is usually the
+ appropriate number or string autogenerated by a formatter--
+ "Label CDATA #IMPLIED">
+
+<!ENTITY % linespecific.attrib
+ --Format: whether element is assumed to contain significant white
+ space--
+ "Format NOTATION
+ (linespecific) linespecific
+ LineNumbering (Numbered|Unnumbered) #IMPLIED">
+
+<!ENTITY % linkend.attrib
+ --Linkend: link to related information; no default--
+ "Linkend IDREF #IMPLIED">
+
+<!ENTITY % linkendreq.attrib
+ --Linkend: required link to related information--
+ "Linkend IDREF #REQUIRED">
+
+<!ENTITY % linkends.attrib
+ --Linkends: link to one or more sets of related information; no
+ default--
+ "Linkends IDREFS #IMPLIED">
+
+<![IGNORE[
+<!-- Declared for completeness, but never used -->
+<!ENTITY % linkendsreq.attrib
+ --Linkends: required link to one or more sets of related information--
+ "Linkends IDREFS #REQUIRED">
+]]>
+
+<!ENTITY % local.mark.attrib "">
+<!ENTITY % mark.attrib
+ "Mark CDATA #IMPLIED
+ %local.mark.attrib;"
+>
+
+<!ENTITY % moreinfo.attrib
+ --MoreInfo: whether element's content has an associated RefEntry--
+ "MoreInfo (RefEntry|None) None">
+
+<!ENTITY % pagenum.attrib
+ --Pagenum: number of page on which element appears; no default--
+ "Pagenum CDATA #IMPLIED">
+
+<!ENTITY % local.status.attrib "">
+<!ENTITY % status.attrib
+ --Status: Editorial or publication status of the element
+ it applies to, such as "in review" or "approved for distribution"--
+ "Status CDATA #IMPLIED
+ %local.status.attrib;"
+>
+
+<!ENTITY % width.attrib
+ --Width: width of the longest line in the element to which it
+ pertains, in number of characters--
+ "Width NUMBER #IMPLIED">
+
+<!-- ...................................................................... -->
+<!-- Title elements ....................................................... -->
+
+<!ENTITY % title.module "INCLUDE">
+<![ %title.module; [
+<!ENTITY % local.title.attrib "">
+<!ENTITY % title.role.attrib "%role.attrib;">
+
+<!ENTITY % title.element "INCLUDE">
+<![ %title.element; [
+<!ELEMENT Title - O ((%title.char.mix;)+)>
+<!--end of title.element-->]]>
+
+<!ENTITY % title.attlist "INCLUDE">
+<![ %title.attlist; [
+<!ATTLIST Title
+ %pagenum.attrib;
+ %common.attrib;
+ %title.role.attrib;
+ %local.title.attrib;
+>
+<!--end of title.attlist-->]]>
+<!--end of title.module-->]]>
+
+<!ENTITY % titleabbrev.module "INCLUDE">
+<![ %titleabbrev.module; [
+<!ENTITY % local.titleabbrev.attrib "">
+<!ENTITY % titleabbrev.role.attrib "%role.attrib;">
+
+<!ENTITY % titleabbrev.element "INCLUDE">
+<![ %titleabbrev.element; [
+<!ELEMENT TitleAbbrev - O ((%title.char.mix;)+)>
+<!--end of titleabbrev.element-->]]>
+
+<!ENTITY % titleabbrev.attlist "INCLUDE">
+<![ %titleabbrev.attlist; [
+<!ATTLIST TitleAbbrev
+ %common.attrib;
+ %titleabbrev.role.attrib;
+ %local.titleabbrev.attrib;
+>
+<!--end of titleabbrev.attlist-->]]>
+<!--end of titleabbrev.module-->]]>
+
+<!ENTITY % subtitle.module "INCLUDE">
+<![ %subtitle.module; [
+<!ENTITY % local.subtitle.attrib "">
+<!ENTITY % subtitle.role.attrib "%role.attrib;">
+
+<!ENTITY % subtitle.element "INCLUDE">
+<![ %subtitle.element; [
+<!ELEMENT Subtitle - O ((%title.char.mix;)+)>
+<!--end of subtitle.element-->]]>
+
+<!ENTITY % subtitle.attlist "INCLUDE">
+<![ %subtitle.attlist; [
+<!ATTLIST Subtitle
+ %common.attrib;
+ %subtitle.role.attrib;
+ %local.subtitle.attrib;
+>
+<!--end of subtitle.attlist-->]]>
+<!--end of subtitle.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Bibliographic entities and elements .................................. -->
+
+<!-- The bibliographic elements are typically used in the document
+ hierarchy. They do not appear in content models of information
+ pool elements. See also the document information elements,
+ below. -->
+
+<!ENTITY % local.person.ident.mix "">
+<!ENTITY % person.ident.mix
+ "Honorific|FirstName|Surname|Lineage|OtherName|Affiliation
+ |AuthorBlurb|Contrib %local.person.ident.mix;">
+
+<!ENTITY % local.bibliocomponent.mix "">
+<!ENTITY % bibliocomponent.mix
+ "Abbrev|Abstract|Address|ArtPageNums|Author
+ |AuthorGroup|AuthorInitials|BiblioMisc|BiblioSet
+ |Collab|ConfGroup|ContractNum|ContractSponsor
+ |Copyright|CorpAuthor|CorpName|Date|Edition
+ |Editor|InvPartNumber|ISBN|ISSN|IssueNum|OrgName
+ |OtherCredit|PageNums|PrintHistory|ProductName
+ |ProductNumber|PubDate|Publisher|PublisherName
+ |PubsNumber|ReleaseInfo|RevHistory|SeriesVolNums
+ |Subtitle|Title|TitleAbbrev|VolumeNum|CiteTitle
+ |%person.ident.mix;
+ |%ndxterm.class;
+ %local.bibliocomponent.mix;">
+
+<!ENTITY % biblioentry.module "INCLUDE">
+<![ %biblioentry.module; [
+<!ENTITY % local.biblioentry.attrib "">
+
+<!ENTITY % biblioentry.role.attrib "%role.attrib;">
+
+<!ENTITY % biblioentry.element "INCLUDE">
+<![ %biblioentry.element; [
+<!--FUTURE USE (V5.0):
+......................
+ArticleInfo will be droped from BiblioEntry
+......................
+-->
+<!ELEMENT BiblioEntry - O ((ArticleInfo
+ | (%bibliocomponent.mix;))+)
+ %ubiq.exclusion;>
+<!--end of biblioentry.element-->]]>
+
+<!ENTITY % biblioentry.attlist "INCLUDE">
+<![ %biblioentry.attlist; [
+<!ATTLIST BiblioEntry
+ %common.attrib;
+ %biblioentry.role.attrib;
+ %local.biblioentry.attrib;
+>
+<!--end of biblioentry.attlist-->]]>
+<!--end of biblioentry.module-->]]>
+
+<!ENTITY % bibliomixed.module "INCLUDE">
+<![ %bibliomixed.module; [
+<!ENTITY % local.bibliomixed.attrib "">
+<!ENTITY % bibliomixed.role.attrib "%role.attrib;">
+
+<!ENTITY % bibliomixed.element "INCLUDE">
+<![ %bibliomixed.element; [
+<!ELEMENT BiblioMixed - O ((%bibliocomponent.mix; | BiblioMSet | #PCDATA)+)
+ %ubiq.exclusion;>
+<!--end of bibliomixed.element-->]]>
+
+<!ENTITY % bibliomixed.attlist "INCLUDE">
+<![ %bibliomixed.attlist; [
+<!ATTLIST BiblioMixed
+ %common.attrib;
+ %bibliomixed.role.attrib;
+ %local.bibliomixed.attrib;
+>
+<!--end of bibliomixed.attlist-->]]>
+<!--end of bibliomixed.module-->]]>
+
+<!ENTITY % articleinfo.module "INCLUDE">
+<![ %articleinfo.module; [
+<!ENTITY % local.articleinfo.attrib "">
+<!ENTITY % articleinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % articleinfo.element "INCLUDE">
+<![ %articleinfo.element; [
+<!ELEMENT ArticleInfo - - ((Graphic | MediaObject | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ -(BeginPage)>
+<!--end of articleinfo.element-->]]>
+
+<!ENTITY % articleinfo.attlist "INCLUDE">
+<![ %articleinfo.attlist; [
+<!ATTLIST ArticleInfo
+ %common.attrib;
+ %articleinfo.role.attrib;
+ %local.articleinfo.attrib;
+>
+<!--end of articleinfo.attlist-->]]>
+<!--end of articleinfo.module-->]]>
+
+<!ENTITY % biblioset.module "INCLUDE">
+<![ %biblioset.module; [
+<!ENTITY % local.biblioset.attrib "">
+<!ENTITY % biblioset.role.attrib "%role.attrib;">
+
+<!ENTITY % biblioset.element "INCLUDE">
+<![ %biblioset.element; [
+<!ELEMENT BiblioSet - - ((%bibliocomponent.mix;)+) %ubiq.exclusion;>
+<!--end of biblioset.element-->]]>
+
+<!ENTITY % biblioset.attlist "INCLUDE">
+<![ %biblioset.attlist; [
+<!ATTLIST BiblioSet
+ --
+ Relation: Relationship of elements contained within BiblioSet
+ --
+ Relation CDATA #IMPLIED
+ %common.attrib;
+ %biblioset.role.attrib;
+ %local.biblioset.attrib;
+>
+<!--end of biblioset.attlist-->]]>
+<!--end of biblioset.module-->]]>
+
+<!ENTITY % bibliomset.module "INCLUDE">
+<![ %bibliomset.module; [
+<!ENTITY % bibliomset.role.attrib "%role.attrib;">
+<!ENTITY % local.bibliomset.attrib "">
+
+<!ENTITY % bibliomset.element "INCLUDE">
+<![ %bibliomset.element; [
+<!ELEMENT BiblioMSet - - ((%bibliocomponent.mix; | BiblioMSet | #PCDATA)+)
+ %ubiq.exclusion;>
+<!--end of bibliomset.element-->]]>
+
+<!ENTITY % bibliomset.attlist "INCLUDE">
+<![ %bibliomset.attlist; [
+<!ATTLIST BiblioMSet
+ --
+ Relation: Relationship of elements contained within BiblioMSet
+ --
+ Relation CDATA #IMPLIED
+ %bibliomset.role.attrib;
+ %common.attrib;
+ %local.bibliomset.attrib;
+>
+<!--end of bibliomset.attlist-->]]>
+<!--end of bibliomset.module-->]]>
+
+<!ENTITY % bibliomisc.module "INCLUDE">
+<![ %bibliomisc.module; [
+<!ENTITY % local.bibliomisc.attrib "">
+<!ENTITY % bibliomisc.role.attrib "%role.attrib;">
+
+<!ENTITY % bibliomisc.element "INCLUDE">
+<![ %bibliomisc.element; [
+<!ELEMENT BiblioMisc - - ((%para.char.mix;)+)>
+<!--end of bibliomisc.element-->]]>
+
+<!ENTITY % bibliomisc.attlist "INCLUDE">
+<![ %bibliomisc.attlist; [
+<!ATTLIST BiblioMisc
+ %common.attrib;
+ %bibliomisc.role.attrib;
+ %local.bibliomisc.attrib;
+>
+<!--end of bibliomisc.attlist-->]]>
+<!--end of bibliomisc.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Subject, Keyword, and ITermSet elements .............................. -->
+
+<!ENTITY % subjectset.content.module "INCLUDE">
+<![ %subjectset.content.module; [
+<!ENTITY % subjectset.module "INCLUDE">
+<![ %subjectset.module; [
+<!ENTITY % local.subjectset.attrib "">
+<!ENTITY % subjectset.role.attrib "%role.attrib;">
+
+<!ENTITY % subjectset.element "INCLUDE">
+<![ %subjectset.element; [
+<!ELEMENT SubjectSet - - (Subject+)>
+<!--end of subjectset.element-->]]>
+
+<!ENTITY % subjectset.attlist "INCLUDE">
+<![ %subjectset.attlist; [
+<!ATTLIST SubjectSet
+ --
+ Scheme: Controlled vocabulary employed in SubjectTerms
+ --
+ Scheme NAME #IMPLIED
+ %common.attrib;
+ %subjectset.role.attrib;
+ %local.subjectset.attrib;
+>
+<!--end of subjectset.attlist-->]]>
+<!--end of subjectset.module-->]]>
+
+<!ENTITY % subject.module "INCLUDE">
+<![ %subject.module; [
+<!ENTITY % local.subject.attrib "">
+<!ENTITY % subject.role.attrib "%role.attrib;">
+
+<!ENTITY % subject.element "INCLUDE">
+<![ %subject.element; [
+<!ELEMENT Subject - - (SubjectTerm+)>
+<!--end of subject.element-->]]>
+
+<!ENTITY % subject.attlist "INCLUDE">
+<![ %subject.attlist; [
+<!ATTLIST Subject
+ --
+ Weight: Ranking of this group of SubjectTerms relative
+ to others, 0 is low, no highest value specified
+ --
+ Weight NUMBER #IMPLIED
+ %common.attrib;
+ %subject.role.attrib;
+ %local.subject.attrib;
+>
+<!--end of subject.attlist-->]]>
+<!--end of subject.module-->]]>
+
+<!ENTITY % subjectterm.module "INCLUDE">
+<![ %subjectterm.module; [
+<!ENTITY % local.subjectterm.attrib "">
+<!ENTITY % subjectterm.role.attrib "%role.attrib;">
+
+<!ENTITY % subjectterm.element "INCLUDE">
+<![ %subjectterm.element; [
+<!ELEMENT SubjectTerm - - (#PCDATA)>
+<!--end of subjectterm.element-->]]>
+
+<!ENTITY % subjectterm.attlist "INCLUDE">
+<![ %subjectterm.attlist; [
+<!ATTLIST SubjectTerm
+ %common.attrib;
+ %subjectterm.role.attrib;
+ %local.subjectterm.attrib;
+>
+<!--end of subjectterm.attlist-->]]>
+<!--end of subjectterm.module-->]]>
+<!--end of subjectset.content.module-->]]>
+
+<!ENTITY % keywordset.content.module "INCLUDE">
+<![ %keywordset.content.module; [
+<!ENTITY % local.keywordset.attrib "">
+<!ENTITY % keywordset.module "INCLUDE">
+<![ %keywordset.module; [
+<!ENTITY % local.keywordset.attrib "">
+<!ENTITY % keywordset.role.attrib "%role.attrib;">
+
+<!ENTITY % keywordset.element "INCLUDE">
+<![ %keywordset.element; [
+<!ELEMENT KeywordSet - - (Keyword+)>
+<!--end of keywordset.element-->]]>
+
+<!ENTITY % keywordset.attlist "INCLUDE">
+<![ %keywordset.attlist; [
+<!ATTLIST KeywordSet
+ %common.attrib;
+ %keywordset.role.attrib;
+ %local.keywordset.attrib;
+>
+<!--end of keywordset.attlist-->]]>
+<!--end of keywordset.module-->]]>
+
+<!ENTITY % keyword.module "INCLUDE">
+<![ %keyword.module; [
+<!ENTITY % local.keyword.attrib "">
+<!ENTITY % keyword.role.attrib "%role.attrib;">
+
+<!ENTITY % keyword.element "INCLUDE">
+<![ %keyword.element; [
+<!ELEMENT Keyword - - (#PCDATA)>
+<!--end of keyword.element-->]]>
+
+<!ENTITY % keyword.attlist "INCLUDE">
+<![ %keyword.attlist; [
+<!ATTLIST Keyword
+ %common.attrib;
+ %keyword.role.attrib;
+ %local.keyword.attrib;
+>
+<!--end of keyword.attlist-->]]>
+<!--end of keyword.module-->]]>
+<!--end of keywordset.content.module-->]]>
+
+<!ENTITY % itermset.module "INCLUDE">
+<![ %itermset.module; [
+<!ENTITY % local.itermset.attrib "">
+<!ENTITY % itermset.role.attrib "%role.attrib;">
+
+<!ENTITY % itermset.element "INCLUDE">
+<![ %itermset.element; [
+<!ELEMENT ITermSet - - (IndexTerm+)>
+<!--end of itermset.element-->]]>
+
+<!ENTITY % itermset.attlist "INCLUDE">
+<![ %itermset.attlist; [
+<!ATTLIST ITermSet
+ %common.attrib;
+ %itermset.role.attrib;
+ %local.itermset.attrib;
+>
+<!--end of itermset.attlist-->]]>
+<!--end of itermset.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Compound (section-ish) elements ...................................... -->
+
+<!-- Message set ...................... -->
+
+<!ENTITY % msgset.content.module "INCLUDE">
+<![ %msgset.content.module; [
+<!ENTITY % msgset.module "INCLUDE">
+<![ %msgset.module; [
+<!ENTITY % local.msgset.attrib "">
+<!ENTITY % msgset.role.attrib "%role.attrib;">
+
+<!ENTITY % msgset.element "INCLUDE">
+<![ %msgset.element; [
+<!ELEMENT MsgSet - - ((%formalobject.title.content;)?, (MsgEntry+|SimpleMsgEntry+))>
+<!--end of msgset.element-->]]>
+
+<!ENTITY % msgset.attlist "INCLUDE">
+<![ %msgset.attlist; [
+<!ATTLIST MsgSet
+ %common.attrib;
+ %msgset.role.attrib;
+ %local.msgset.attrib;
+>
+<!--end of msgset.attlist-->]]>
+<!--end of msgset.module-->]]>
+
+<!ENTITY % msgentry.module "INCLUDE">
+<![ %msgentry.module; [
+<!ENTITY % local.msgentry.attrib "">
+<!ENTITY % msgentry.role.attrib "%role.attrib;">
+
+<!ENTITY % msgentry.element "INCLUDE">
+<![ %msgentry.element; [
+<!ELEMENT MsgEntry - O (Msg+, MsgInfo?, MsgExplan*)>
+<!--end of msgentry.element-->]]>
+
+<!ENTITY % msgentry.attlist "INCLUDE">
+<![ %msgentry.attlist; [
+<!ATTLIST MsgEntry
+ %common.attrib;
+ %msgentry.role.attrib;
+ %local.msgentry.attrib;
+>
+<!--end of msgentry.attlist-->]]>
+<!--end of msgentry.module-->]]>
+
+<!ENTITY % simplemsgentry.module "INCLUDE">
+<![ %simplemsgentry.module; [
+<!ENTITY % local.simplemsgentry.attrib "">
+<!ENTITY % simplemsgentry.role.attrib "%role.attrib;">
+
+<!ENTITY % simplemsgentry.element "INCLUDE">
+<![ %simplemsgentry.element; [
+<!ELEMENT SimpleMsgEntry - O (MsgText, MsgExplan)>
+<!--end of simplemsgentry.element-->]]>
+
+<!ENTITY % simplemsgentry.attlist "INCLUDE">
+<![ %simplemsgentry.attlist; [
+<!ATTLIST SimpleMsgEntry
+ %common.attrib;
+ %simplemsgentry.role.attrib;
+ %local.simplemsgentry.attrib;
+ Audience CDATA #IMPLIED
+ Level CDATA #IMPLIED
+ Origin CDATA #IMPLIED
+>
+<!--end of simplemsgentry.attlist-->]]>
+<!--end of simplemsgentry.module-->]]>
+
+<!ENTITY % msg.module "INCLUDE">
+<![ %msg.module; [
+<!ENTITY % local.msg.attrib "">
+<!ENTITY % msg.role.attrib "%role.attrib;">
+
+<!ENTITY % msg.element "INCLUDE">
+<![ %msg.element; [
+<!ELEMENT Msg - O (Title?, MsgMain, (MsgSub | MsgRel)*)>
+<!--end of msg.element-->]]>
+
+<!ENTITY % msg.attlist "INCLUDE">
+<![ %msg.attlist; [
+<!ATTLIST Msg
+ %common.attrib;
+ %msg.role.attrib;
+ %local.msg.attrib;
+>
+<!--end of msg.attlist-->]]>
+<!--end of msg.module-->]]>
+
+<!ENTITY % msgmain.module "INCLUDE">
+<![ %msgmain.module; [
+<!ENTITY % local.msgmain.attrib "">
+<!ENTITY % msgmain.role.attrib "%role.attrib;">
+
+<!ENTITY % msgmain.element "INCLUDE">
+<![ %msgmain.element; [
+<!ELEMENT MsgMain - - (Title?, MsgText)>
+<!--end of msgmain.element-->]]>
+
+<!ENTITY % msgmain.attlist "INCLUDE">
+<![ %msgmain.attlist; [
+<!ATTLIST MsgMain
+ %common.attrib;
+ %msgmain.role.attrib;
+ %local.msgmain.attrib;
+>
+<!--end of msgmain.attlist-->]]>
+<!--end of msgmain.module-->]]>
+
+<!ENTITY % msgsub.module "INCLUDE">
+<![ %msgsub.module; [
+<!ENTITY % local.msgsub.attrib "">
+<!ENTITY % msgsub.role.attrib "%role.attrib;">
+
+<!ENTITY % msgsub.element "INCLUDE">
+<![ %msgsub.element; [
+<!ELEMENT MsgSub - - (Title?, MsgText)>
+<!--end of msgsub.element-->]]>
+
+<!ENTITY % msgsub.attlist "INCLUDE">
+<![ %msgsub.attlist; [
+<!ATTLIST MsgSub
+ %common.attrib;
+ %msgsub.role.attrib;
+ %local.msgsub.attrib;
+>
+<!--end of msgsub.attlist-->]]>
+<!--end of msgsub.module-->]]>
+
+<!ENTITY % msgrel.module "INCLUDE">
+<![ %msgrel.module; [
+<!ENTITY % local.msgrel.attrib "">
+<!ENTITY % msgrel.role.attrib "%role.attrib;">
+
+<!ENTITY % msgrel.element "INCLUDE">
+<![ %msgrel.element; [
+<!ELEMENT MsgRel - - (Title?, MsgText)>
+<!--end of msgrel.element-->]]>
+
+<!ENTITY % msgrel.attlist "INCLUDE">
+<![ %msgrel.attlist; [
+<!ATTLIST MsgRel
+ %common.attrib;
+ %msgrel.role.attrib;
+ %local.msgrel.attrib;
+>
+<!--end of msgrel.attlist-->]]>
+<!--end of msgrel.module-->]]>
+
+<!-- MsgText (defined in the Inlines section, below)-->
+
+<!ENTITY % msginfo.module "INCLUDE">
+<![ %msginfo.module; [
+<!ENTITY % local.msginfo.attrib "">
+<!ENTITY % msginfo.role.attrib "%role.attrib;">
+
+<!ENTITY % msginfo.element "INCLUDE">
+<![ %msginfo.element; [
+<!ELEMENT MsgInfo - - ((MsgLevel | MsgOrig | MsgAud)*)>
+<!--end of msginfo.element-->]]>
+
+<!ENTITY % msginfo.attlist "INCLUDE">
+<![ %msginfo.attlist; [
+<!ATTLIST MsgInfo
+ %common.attrib;
+ %msginfo.role.attrib;
+ %local.msginfo.attrib;
+>
+<!--end of msginfo.attlist-->]]>
+<!--end of msginfo.module-->]]>
+
+<!ENTITY % msglevel.module "INCLUDE">
+<![ %msglevel.module; [
+<!ENTITY % local.msglevel.attrib "">
+<!ENTITY % msglevel.role.attrib "%role.attrib;">
+
+<!ENTITY % msglevel.element "INCLUDE">
+<![ %msglevel.element; [
+<!ELEMENT MsgLevel - - ((%smallcptr.char.mix;)+)>
+<!--end of msglevel.element-->]]>
+
+<!ENTITY % msglevel.attlist "INCLUDE">
+<![ %msglevel.attlist; [
+<!ATTLIST MsgLevel
+ %common.attrib;
+ %msglevel.role.attrib;
+ %local.msglevel.attrib;
+>
+<!--end of msglevel.attlist-->]]>
+<!--end of msglevel.module-->]]>
+
+<!ENTITY % msgorig.module "INCLUDE">
+<![ %msgorig.module; [
+<!ENTITY % local.msgorig.attrib "">
+<!ENTITY % msgorig.role.attrib "%role.attrib;">
+
+<!ENTITY % msgorig.element "INCLUDE">
+<![ %msgorig.element; [
+<!ELEMENT MsgOrig - - ((%smallcptr.char.mix;)+)>
+<!--end of msgorig.element-->]]>
+
+<!ENTITY % msgorig.attlist "INCLUDE">
+<![ %msgorig.attlist; [
+<!ATTLIST MsgOrig
+ %common.attrib;
+ %msgorig.role.attrib;
+ %local.msgorig.attrib;
+>
+<!--end of msgorig.attlist-->]]>
+<!--end of msgorig.module-->]]>
+
+<!ENTITY % msgaud.module "INCLUDE">
+<![ %msgaud.module; [
+<!ENTITY % local.msgaud.attrib "">
+<!ENTITY % msgaud.role.attrib "%role.attrib;">
+
+<!ENTITY % msgaud.element "INCLUDE">
+<![ %msgaud.element; [
+<!ELEMENT MsgAud - - ((%para.char.mix;)+)>
+<!--end of msgaud.element-->]]>
+
+<!ENTITY % msgaud.attlist "INCLUDE">
+<![ %msgaud.attlist; [
+<!ATTLIST MsgAud
+ %common.attrib;
+ %msgaud.role.attrib;
+ %local.msgaud.attrib;
+>
+<!--end of msgaud.attlist-->]]>
+<!--end of msgaud.module-->]]>
+
+<!ENTITY % msgexplan.module "INCLUDE">
+<![ %msgexplan.module; [
+<!ENTITY % local.msgexplan.attrib "">
+<!ENTITY % msgexplan.role.attrib "%role.attrib;">
+
+<!ENTITY % msgexplan.element "INCLUDE">
+<![ %msgexplan.element; [
+<!ELEMENT MsgExplan - - (Title?, (%component.mix;)+)>
+<!--end of msgexplan.element-->]]>
+
+<!ENTITY % msgexplan.attlist "INCLUDE">
+<![ %msgexplan.attlist; [
+<!ATTLIST MsgExplan
+ %common.attrib;
+ %msgexplan.role.attrib;
+ %local.msgexplan.attrib;
+>
+<!--end of msgexplan.attlist-->]]>
+<!--end of msgexplan.module-->]]>
+<!--end of msgset.content.module-->]]>
+
+<!-- QandASet ........................ -->
+<!ENTITY % qandset.content.module "INCLUDE">
+<![ %qandset.content.module; [
+<!ENTITY % qandset.module "INCLUDE">
+<![ %qandset.module; [
+<!ENTITY % local.qandset.attrib "">
+<!ENTITY % qandset.role.attrib "%role.attrib;">
+
+<!ENTITY % qandset.element "INCLUDE">
+<![ %qandset.element; [
+<!ELEMENT QandASet - - ((%formalobject.title.content;)?,
+ (%qandaset.mix;)*,
+ (QandADiv+|QandAEntry+))>
+<!--end of qandset.element-->]]>
+
+<!ENTITY % qandset.attlist "INCLUDE">
+<![ %qandset.attlist; [
+<!ATTLIST QandASet
+ DefaultLabel (qanda|number|none) #IMPLIED
+ %common.attrib;
+ %qandset.role.attrib;
+ %local.qandset.attrib;>
+<!--end of qandset.attlist-->]]>
+<!--end of qandset.module-->]]>
+
+<!ENTITY % qandadiv.module "INCLUDE">
+<![ %qandadiv.module; [
+<!ENTITY % local.qandadiv.attrib "">
+<!ENTITY % qandadiv.role.attrib "%role.attrib;">
+
+<!ENTITY % qandadiv.element "INCLUDE">
+<![ %qandadiv.element; [
+<!ELEMENT QandADiv - - ((%formalobject.title.content;)?,
+ (%qandaset.mix;)*,
+ (QandADiv+|QandAEntry+))>
+<!--end of qandadiv.element-->]]>
+
+<!ENTITY % qandadiv.attlist "INCLUDE">
+<![ %qandadiv.attlist; [
+<!ATTLIST QandADiv
+ %common.attrib;
+ %qandadiv.role.attrib;
+ %local.qandadiv.attrib;>
+<!--end of qandadiv.attlist-->]]>
+<!--end of qandadiv.module-->]]>
+
+<!ENTITY % qandaentry.module "INCLUDE">
+<![ %qandaentry.module; [
+<!ENTITY % local.qandaentry.attrib "">
+<!ENTITY % qandaentry.role.attrib "%role.attrib;">
+
+<!ENTITY % qandaentry.element "INCLUDE">
+<![ %qandaentry.element; [
+<!ELEMENT QandAEntry - - (RevHistory?, Question, Answer*)>
+<!--end of qandaentry.element-->]]>
+
+<!ENTITY % qandaentry.attlist "INCLUDE">
+<![ %qandaentry.attlist; [
+<!ATTLIST QandAEntry
+ %common.attrib;
+ %qandaentry.role.attrib;
+ %local.qandaentry.attrib;>
+<!--end of qandaentry.attlist-->]]>
+<!--end of qandaentry.module-->]]>
+
+<!ENTITY % question.module "INCLUDE">
+<![ %question.module; [
+<!ENTITY % local.question.attrib "">
+<!ENTITY % question.role.attrib "%role.attrib;">
+
+<!ENTITY % question.element "INCLUDE">
+<![ %question.element; [
+<!ELEMENT Question - - (Label?, (%qandaset.mix;)+)>
+<!--end of question.element-->]]>
+
+<!ENTITY % question.attlist "INCLUDE">
+<![ %question.attlist; [
+<!ATTLIST Question
+ %common.attrib;
+ %question.role.attrib;
+ %local.question.attrib;
+>
+<!--end of question.attlist-->]]>
+<!--end of question.module-->]]>
+
+<!ENTITY % answer.module "INCLUDE">
+<![ %answer.module; [
+<!ENTITY % local.answer.attrib "">
+<!ENTITY % answer.role.attrib "%role.attrib;">
+
+<!ENTITY % answer.element "INCLUDE">
+<![ %answer.element; [
+<!ELEMENT Answer - - (Label?, (%qandaset.mix;)*, QandAEntry*)>
+<!--end of answer.element-->]]>
+
+<!ENTITY % answer.attlist "INCLUDE">
+<![ %answer.attlist; [
+<!ATTLIST Answer
+ %common.attrib;
+ %answer.role.attrib;
+ %local.answer.attrib;
+>
+<!--end of answer.attlist-->]]>
+<!--end of answer.module-->]]>
+
+<!ENTITY % label.module "INCLUDE">
+<![ %label.module; [
+<!ENTITY % local.label.attrib "">
+<!ENTITY % label.role.attrib "%role.attrib;">
+
+<!ENTITY % label.element "INCLUDE">
+<![ %label.element; [
+<!ELEMENT Label - - (%word.char.mix;)*>
+<!--end of label.element-->]]>
+
+<!ENTITY % label.attlist "INCLUDE">
+<![ %label.attlist; [
+<!ATTLIST Label
+ %common.attrib;
+ %label.role.attrib;
+ %local.label.attrib;
+>
+<!--end of label.attlist-->]]>
+<!--end of label.module-->]]>
+<!--end of qandset.content.module-->]]>
+
+<!-- Procedure ........................ -->
+
+<!ENTITY % procedure.content.module "INCLUDE">
+<![ %procedure.content.module; [
+<!ENTITY % procedure.module "INCLUDE">
+<![ %procedure.module; [
+<!ENTITY % local.procedure.attrib "">
+<!ENTITY % procedure.role.attrib "%role.attrib;">
+
+<!ENTITY % procedure.element "INCLUDE">
+<![ %procedure.element; [
+<!ELEMENT Procedure - - ((%formalobject.title.content;)?,
+ (%component.mix;)*, Step+)>
+<!--end of procedure.element-->]]>
+
+<!ENTITY % procedure.attlist "INCLUDE">
+<![ %procedure.attlist; [
+<!ATTLIST Procedure
+ %common.attrib;
+ %procedure.role.attrib;
+ %local.procedure.attrib;
+>
+<!--end of procedure.attlist-->]]>
+<!--end of procedure.module-->]]>
+
+<!ENTITY % step.module "INCLUDE">
+<![ %step.module; [
+<!ENTITY % local.step.attrib "">
+<!ENTITY % step.role.attrib "%role.attrib;">
+
+<!ENTITY % step.element "INCLUDE">
+<![ %step.element; [
+<!ELEMENT Step - O (Title?, (((%component.mix;)+, (SubSteps,
+ (%component.mix;)*)?) | (SubSteps, (%component.mix;)*)))>
+<!--end of step.element-->]]>
+
+<!ENTITY % step.attlist "INCLUDE">
+<![ %step.attlist; [
+<!ATTLIST Step
+ --
+ Performance: Whether the Step must be performed
+ --
+ Performance (Optional
+ |Required) Required -- not #REQUIRED! --
+ %common.attrib;
+ %step.role.attrib;
+ %local.step.attrib;
+>
+<!--end of step.attlist-->]]>
+<!--end of step.module-->]]>
+
+<!ENTITY % substeps.module "INCLUDE">
+<![ %substeps.module; [
+<!ENTITY % local.substeps.attrib "">
+<!ENTITY % substeps.role.attrib "%role.attrib;">
+
+<!ENTITY % substeps.element "INCLUDE">
+<![ %substeps.element; [
+<!ELEMENT SubSteps - - (Step+)>
+<!--end of substeps.element-->]]>
+
+<!ENTITY % substeps.attlist "INCLUDE">
+<![ %substeps.attlist; [
+<!ATTLIST SubSteps
+ --
+ Performance: whether entire set of substeps must be performed
+ --
+ Performance (Optional
+ |Required) Required -- not #REQUIRED! --
+ %common.attrib;
+ %substeps.role.attrib;
+ %local.substeps.attrib;
+>
+<!--end of substeps.attlist-->]]>
+<!--end of substeps.module-->]]>
+<!--end of procedure.content.module-->]]>
+
+<!-- Sidebar .......................... -->
+
+<!ENTITY % sidebar.content.model "INCLUDE">
+<![ %sidebar.content.model; [
+
+<!ENTITY % sidebarinfo.module "INCLUDE">
+<![ %sidebarinfo.module; [
+<!ENTITY % local.sidebarinfo.attrib "">
+<!ENTITY % sidebarinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % sidebarinfo.element "INCLUDE">
+<![ %sidebarinfo.element; [
+<!ELEMENT SidebarInfo - - ((Graphic | MediaObject | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ -(BeginPage)>
+<!--end of sidebarinfo.element-->]]>
+
+<!ENTITY % sidebarinfo.attlist "INCLUDE">
+<![ %sidebarinfo.attlist; [
+<!ATTLIST SidebarInfo
+ %common.attrib;
+ %sidebarinfo.role.attrib;
+ %local.sidebarinfo.attrib;
+>
+<!--end of sidebarinfo.attlist-->]]>
+<!--end of sidebarinfo.module-->]]>
+
+<!ENTITY % sidebar.module "INCLUDE">
+<![ %sidebar.module; [
+<!ENTITY % local.sidebar.attrib "">
+<!ENTITY % sidebar.role.attrib "%role.attrib;">
+
+<!ENTITY % sidebar.element "INCLUDE">
+<![ %sidebar.element; [
+<!ELEMENT Sidebar - - (SidebarInfo?,
+ (%formalobject.title.content;)?, (%sidebar.mix;)+)>
+<!--end of sidebar.element-->]]>
+
+<!ENTITY % sidebar.attlist "INCLUDE">
+<![ %sidebar.attlist; [
+<!ATTLIST Sidebar
+ %common.attrib;
+ %sidebar.role.attrib;
+ %local.sidebar.attrib;
+>
+<!--end of sidebar.attlist-->]]>
+<!--end of sidebar.module-->]]>
+<!--end of sidebar.content.model-->]]>
+
+<!-- ...................................................................... -->
+<!-- Paragraph-related elements ........................................... -->
+
+<!ENTITY % abstract.module "INCLUDE">
+<![ %abstract.module; [
+<!ENTITY % local.abstract.attrib "">
+<!ENTITY % abstract.role.attrib "%role.attrib;">
+
+<!ENTITY % abstract.element "INCLUDE">
+<![ %abstract.element; [
+<!ELEMENT Abstract - - (Title?, (%para.class;)+)>
+<!--end of abstract.element-->]]>
+
+<!ENTITY % abstract.attlist "INCLUDE">
+<![ %abstract.attlist; [
+<!ATTLIST Abstract
+ %common.attrib;
+ %abstract.role.attrib;
+ %local.abstract.attrib;
+>
+<!--end of abstract.attlist-->]]>
+<!--end of abstract.module-->]]>
+
+<!ENTITY % authorblurb.module "INCLUDE">
+<![ %authorblurb.module; [
+<!ENTITY % local.authorblurb.attrib "">
+<!ENTITY % authorblurb.role.attrib "%role.attrib;">
+
+<!ENTITY % authorblurb.element "INCLUDE">
+<![ %authorblurb.element; [
+<!ELEMENT AuthorBlurb - - (Title?, (%para.class;)+)>
+<!--end of authorblurb.element-->]]>
+
+<!ENTITY % authorblurb.attlist "INCLUDE">
+<![ %authorblurb.attlist; [
+<!ATTLIST AuthorBlurb
+ %common.attrib;
+ %authorblurb.role.attrib;
+ %local.authorblurb.attrib;
+>
+<!--end of authorblurb.attlist-->]]>
+<!--end of authorblurb.module-->]]>
+
+<!ENTITY % blockquote.module "INCLUDE">
+<![ %blockquote.module; [
+<!ENTITY % local.blockquote.attrib "">
+<!ENTITY % blockquote.role.attrib "%role.attrib;">
+
+<!ENTITY % blockquote.element "INCLUDE">
+<![ %blockquote.element; [
+<!ELEMENT BlockQuote - - (Title?, Attribution?, (%component.mix;)+)
+ %blockquote.exclusion;>
+<!--end of blockquote.element-->]]>
+
+<!ENTITY % blockquote.attlist "INCLUDE">
+<![ %blockquote.attlist; [
+<!ATTLIST BlockQuote
+ %common.attrib;
+ %blockquote.role.attrib;
+ %local.blockquote.attrib;
+>
+<!--end of blockquote.attlist-->]]>
+<!--end of blockquote.module-->]]>
+
+<!ENTITY % attribution.module "INCLUDE">
+<![ %attribution.module; [
+<!ENTITY % local.attribution.attrib "">
+<!ENTITY % attribution.role.attrib "%role.attrib;">
+
+<!ENTITY % attribution.element "INCLUDE">
+<![ %attribution.element; [
+<!ELEMENT Attribution - O ((%para.char.mix;)+)>
+<!--end of attribution.element-->]]>
+
+<!ENTITY % attribution.attlist "INCLUDE">
+<![ %attribution.attlist; [
+<!ATTLIST Attribution
+ %common.attrib;
+ %attribution.role.attrib;
+ %local.attribution.attrib;
+>
+<!--end of attribution.attlist-->]]>
+<!--end of attribution.module-->]]>
+
+<!ENTITY % bridgehead.module "INCLUDE">
+<![ %bridgehead.module; [
+<!ENTITY % local.bridgehead.attrib "">
+<!ENTITY % bridgehead.role.attrib "%role.attrib;">
+
+<!ENTITY % bridgehead.element "INCLUDE">
+<![ %bridgehead.element; [
+<!ELEMENT BridgeHead - - ((%title.char.mix;)+)>
+<!--end of bridgehead.element-->]]>
+
+<!ENTITY % bridgehead.attlist "INCLUDE">
+<![ %bridgehead.attlist; [
+<!ATTLIST BridgeHead
+ --
+ Renderas: Indicates the format in which the BridgeHead
+ should appear
+ --
+ Renderas (Other
+ |Sect1
+ |Sect2
+ |Sect3
+ |Sect4
+ |Sect5) #IMPLIED
+ %common.attrib;
+ %bridgehead.role.attrib;
+ %local.bridgehead.attrib;
+>
+<!--end of bridgehead.attlist-->]]>
+<!--end of bridgehead.module-->]]>
+
+<!ENTITY % remark.module "INCLUDE">
+<![ %remark.module; [
+<!ENTITY % local.remark.attrib "">
+<!ENTITY % remark.role.attrib "%role.attrib;">
+
+<!ENTITY % remark.element "INCLUDE">
+<![ %remark.element; [
+<!ELEMENT Remark - - ((%para.char.mix;)+) %remark.exclusion;>
+<!--end of remark.element-->]]>
+
+<!ENTITY % remark.attlist "INCLUDE">
+<![ %remark.attlist; [
+<!ATTLIST Remark
+ %common.attrib;
+ %remark.role.attrib;
+ %local.remark.attrib;
+>
+<!--end of remark.attlist-->]]>
+<!--end of remark.module-->]]>
+
+<!ENTITY % epigraph.module "INCLUDE">
+<![ %epigraph.module; [
+<!ENTITY % local.epigraph.attrib "">
+<!ENTITY % epigraph.role.attrib "%role.attrib;">
+
+<!ENTITY % epigraph.element "INCLUDE">
+<![ %epigraph.element; [
+<!ELEMENT Epigraph - - (Attribution?, (%para.class;)+)>
+<!--end of epigraph.element-->]]>
+
+<!ENTITY % epigraph.attlist "INCLUDE">
+<![ %epigraph.attlist; [
+<!ATTLIST Epigraph
+ %common.attrib;
+ %epigraph.role.attrib;
+ %local.epigraph.attrib;
+>
+<!--end of epigraph.attlist-->]]>
+<!-- Attribution (defined above)-->
+<!--end of epigraph.module-->]]>
+
+<!ENTITY % footnote.module "INCLUDE">
+<![ %footnote.module; [
+<!ENTITY % local.footnote.attrib "">
+<!ENTITY % footnote.role.attrib "%role.attrib;">
+
+<!ENTITY % footnote.element "INCLUDE">
+<![ %footnote.element; [
+<!ELEMENT Footnote - - ((%footnote.mix;)+) %footnote.exclusion;>
+<!--end of footnote.element-->]]>
+
+<!ENTITY % footnote.attlist "INCLUDE">
+<![ %footnote.attlist; [
+<!ATTLIST Footnote
+ %label.attrib;
+ %common.attrib;
+ %footnote.role.attrib;
+ %local.footnote.attrib;
+>
+<!--end of footnote.attlist-->]]>
+<!--end of footnote.module-->]]>
+
+<!ENTITY % highlights.module "INCLUDE">
+<![ %highlights.module; [
+<!ENTITY % local.highlights.attrib "">
+<!ENTITY % highlights.role.attrib "%role.attrib;">
+
+<!ENTITY % highlights.element "INCLUDE">
+<![ %highlights.element; [
+<!ELEMENT Highlights - - ((%highlights.mix;)+) %highlights.exclusion;>
+<!--end of highlights.element-->]]>
+
+<!ENTITY % highlights.attlist "INCLUDE">
+<![ %highlights.attlist; [
+<!ATTLIST Highlights
+ %common.attrib;
+ %highlights.role.attrib;
+ %local.highlights.attrib;
+>
+<!--end of highlights.attlist-->]]>
+<!--end of highlights.module-->]]>
+
+<!ENTITY % formalpara.module "INCLUDE">
+<![ %formalpara.module; [
+<!ENTITY % local.formalpara.attrib "">
+<!ENTITY % formalpara.role.attrib "%role.attrib;">
+
+<!ENTITY % formalpara.element "INCLUDE">
+<![ %formalpara.element; [
+<!ELEMENT FormalPara - O (Title, (%ndxterm.class;)*, Para)>
+<!--end of formalpara.element-->]]>
+
+<!ENTITY % formalpara.attlist "INCLUDE">
+<![ %formalpara.attlist; [
+<!ATTLIST FormalPara
+ %common.attrib;
+ %formalpara.role.attrib;
+ %local.formalpara.attrib;
+>
+<!--end of formalpara.attlist-->]]>
+<!--end of formalpara.module-->]]>
+
+<!ENTITY % para.module "INCLUDE">
+<![ %para.module; [
+<!ENTITY % local.para.attrib "">
+<!ENTITY % para.role.attrib "%role.attrib;">
+
+<!ENTITY % para.element "INCLUDE">
+<![ %para.element; [
+<!ELEMENT Para - O ((%para.char.mix; | %para.mix;)+)>
+<!--end of para.element-->]]>
+
+<!ENTITY % para.attlist "INCLUDE">
+<![ %para.attlist; [
+<!ATTLIST Para
+ %common.attrib;
+ %para.role.attrib;
+ %local.para.attrib;
+>
+<!--end of para.attlist-->]]>
+<!--end of para.module-->]]>
+
+<!ENTITY % simpara.module "INCLUDE">
+<![ %simpara.module; [
+<!ENTITY % local.simpara.attrib "">
+<!ENTITY % simpara.role.attrib "%role.attrib;">
+
+<!ENTITY % simpara.element "INCLUDE">
+<![ %simpara.element; [
+<!ELEMENT SimPara - O ((%para.char.mix;)+)>
+<!--end of simpara.element-->]]>
+
+<!ENTITY % simpara.attlist "INCLUDE">
+<![ %simpara.attlist; [
+<!ATTLIST SimPara
+ %common.attrib;
+ %simpara.role.attrib;
+ %local.simpara.attrib;
+>
+<!--end of simpara.attlist-->]]>
+<!--end of simpara.module-->]]>
+
+<!ENTITY % admon.module "INCLUDE">
+<![ %admon.module; [
+<!ENTITY % local.admon.attrib "">
+<!ENTITY % admon.role.attrib "%role.attrib;">
+
+<!ENTITY % admon.elements "INCLUDE">
+<![ %admon.elements; [
+<!ELEMENT (%admon.class;) - - (Title?, (%admon.mix;)+) %admon.exclusion;>
+<!--end of admon.elements-->]]>
+
+<!ENTITY % admon.attlists "INCLUDE">
+<![ %admon.attlists; [
+<!ATTLIST (%admon.class;)
+ %common.attrib;
+ %admon.role.attrib;
+ %local.admon.attrib;
+>
+<!--end of admon.attlists-->]]>
+<!--end of admon.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Lists ................................................................ -->
+
+<!-- GlossList ........................ -->
+
+<!ENTITY % glosslist.module "INCLUDE">
+<![ %glosslist.module; [
+<!ENTITY % local.glosslist.attrib "">
+<!ENTITY % glosslist.role.attrib "%role.attrib;">
+
+<!ENTITY % glosslist.element "INCLUDE">
+<![ %glosslist.element; [
+<!ELEMENT GlossList - - (GlossEntry+)>
+<!--end of glosslist.element-->]]>
+
+<!ENTITY % glosslist.attlist "INCLUDE">
+<![ %glosslist.attlist; [
+<!ATTLIST GlossList
+ %common.attrib;
+ %glosslist.role.attrib;
+ %local.glosslist.attrib;
+>
+<!--end of glosslist.attlist-->]]>
+<!--end of glosslist.module-->]]>
+
+<!ENTITY % glossentry.content.module "INCLUDE">
+<![ %glossentry.content.module; [
+<!ENTITY % glossentry.module "INCLUDE">
+<![ %glossentry.module; [
+<!ENTITY % local.glossentry.attrib "">
+<!ENTITY % glossentry.role.attrib "%role.attrib;">
+
+<!ENTITY % glossentry.element "INCLUDE">
+<![ %glossentry.element; [
+<!ELEMENT GlossEntry - O (GlossTerm, Acronym?, Abbrev?,
+ (%ndxterm.class;)*,
+ RevHistory?, (GlossSee|GlossDef+))>
+<!--end of glossentry.element-->]]>
+
+<!ENTITY % glossentry.attlist "INCLUDE">
+<![ %glossentry.attlist; [
+<!ATTLIST GlossEntry
+ --
+ SortAs: String by which the GlossEntry is to be sorted
+ (alphabetized) in lieu of its proper content
+ --
+ SortAs CDATA #IMPLIED
+ %common.attrib;
+ %glossentry.role.attrib;
+ %local.glossentry.attrib;
+>
+<!--end of glossentry.attlist-->]]>
+<!--end of glossentry.module-->]]>
+
+<!-- GlossTerm (defined in the Inlines section, below)-->
+<!ENTITY % glossdef.module "INCLUDE">
+<![ %glossdef.module; [
+<!ENTITY % local.glossdef.attrib "">
+<!ENTITY % glossdef.role.attrib "%role.attrib;">
+
+<!ENTITY % glossdef.element "INCLUDE">
+<![ %glossdef.element; [
+<!ELEMENT GlossDef - O ((%glossdef.mix;)+, GlossSeeAlso*)>
+<!--end of glossdef.element-->]]>
+
+<!ENTITY % glossdef.attlist "INCLUDE">
+<![ %glossdef.attlist; [
+<!ATTLIST GlossDef
+ --
+ Subject: List of subjects; keywords for the definition
+ --
+ Subject CDATA #IMPLIED
+ %common.attrib;
+ %glossdef.role.attrib;
+ %local.glossdef.attrib;
+>
+<!--end of glossdef.attlist-->]]>
+<!--end of glossdef.module-->]]>
+
+<!ENTITY % glosssee.module "INCLUDE">
+<![ %glosssee.module; [
+<!ENTITY % local.glosssee.attrib "">
+<!ENTITY % glosssee.role.attrib "%role.attrib;">
+
+<!ENTITY % glosssee.element "INCLUDE">
+<![ %glosssee.element; [
+<!ELEMENT GlossSee - O ((%para.char.mix;)+)>
+<!--end of glosssee.element-->]]>
+
+<!ENTITY % glosssee.attlist "INCLUDE">
+<![ %glosssee.attlist; [
+<!ATTLIST GlossSee
+ --
+ OtherTerm: Reference to the GlossEntry whose GlossTerm
+ should be displayed at the point of the GlossSee
+ --
+ OtherTerm IDREF #CONREF
+ %common.attrib;
+ %glosssee.role.attrib;
+ %local.glosssee.attrib;
+>
+<!--end of glosssee.attlist-->]]>
+<!--end of glosssee.module-->]]>
+
+<!ENTITY % glossseealso.module "INCLUDE">
+<![ %glossseealso.module; [
+<!ENTITY % local.glossseealso.attrib "">
+<!ENTITY % glossseealso.role.attrib "%role.attrib;">
+
+<!ENTITY % glossseealso.element "INCLUDE">
+<![ %glossseealso.element; [
+<!ELEMENT GlossSeeAlso - O ((%para.char.mix;)+)>
+<!--end of glossseealso.element-->]]>
+
+<!ENTITY % glossseealso.attlist "INCLUDE">
+<![ %glossseealso.attlist; [
+<!ATTLIST GlossSeeAlso
+ --
+ OtherTerm: Reference to the GlossEntry whose GlossTerm
+ should be displayed at the point of the GlossSeeAlso
+ --
+ OtherTerm IDREF #CONREF
+ %common.attrib;
+ %glossseealso.role.attrib;
+ %local.glossseealso.attrib;
+>
+<!--end of glossseealso.attlist-->]]>
+<!--end of glossseealso.module-->]]>
+<!--end of glossentry.content.module-->]]>
+
+<!-- ItemizedList and OrderedList ..... -->
+
+<!ENTITY % itemizedlist.module "INCLUDE">
+<![ %itemizedlist.module; [
+<!ENTITY % local.itemizedlist.attrib "">
+<!ENTITY % itemizedlist.role.attrib "%role.attrib;">
+
+<!ENTITY % itemizedlist.element "INCLUDE">
+<![ %itemizedlist.element; [
+<!ELEMENT ItemizedList - - ((%formalobject.title.content;)?, ListItem+)>
+<!--end of itemizedlist.element-->]]>
+
+<!ENTITY % itemizedlist.attlist "INCLUDE">
+<![ %itemizedlist.attlist; [
+<!ATTLIST ItemizedList
+ --
+ Spacing: Whether the vertical space in the list should be
+ compressed
+ --
+ Spacing (Normal
+ |Compact) #IMPLIED
+ --
+ Mark: Keyword, e.g., bullet, dash, checkbox, none;
+ list of keywords and defaults are implementation specific
+ --
+ %mark.attrib;
+ %common.attrib;
+ %itemizedlist.role.attrib;
+ %local.itemizedlist.attrib;
+>
+<!--end of itemizedlist.attlist-->]]>
+<!--end of itemizedlist.module-->]]>
+
+<!ENTITY % orderedlist.module "INCLUDE">
+<![ %orderedlist.module; [
+<!ENTITY % local.orderedlist.attrib "">
+<!ENTITY % orderedlist.role.attrib "%role.attrib;">
+
+<!ENTITY % orderedlist.element "INCLUDE">
+<![ %orderedlist.element; [
+<!ELEMENT OrderedList - - ((%formalobject.title.content;)?, ListItem+)>
+<!--end of orderedlist.element-->]]>
+
+<!ENTITY % orderedlist.attlist "INCLUDE">
+<![ %orderedlist.attlist; [
+<!ATTLIST OrderedList
+ --
+ Numeration: Style of ListItem numbered; default is expected
+ to be Arabic
+ --
+ Numeration (Arabic
+ |Upperalpha
+ |Loweralpha
+ |Upperroman
+ |Lowerroman) #IMPLIED
+ --
+ InheritNum: Specifies for a nested list that the numbering
+ of ListItems should include the number of the item
+ within which they are nested (e.g., 1a and 1b within 1,
+ rather than a and b)--
+ InheritNum (Inherit
+ |Ignore) Ignore
+ --
+ Continuation: Where list numbering begins afresh (Restarts,
+ the default) or continues that of the immediately preceding
+ list (Continues)
+ --
+ Continuation (Continues
+ |Restarts) Restarts
+ --
+ Spacing: Whether the vertical space in the list should be
+ compressed
+ --
+ Spacing (Normal
+ |Compact) #IMPLIED
+ %common.attrib;
+ %orderedlist.role.attrib;
+ %local.orderedlist.attrib;
+>
+<!--end of orderedlist.attlist-->]]>
+<!--end of orderedlist.module-->]]>
+
+<!ENTITY % listitem.module "INCLUDE">
+<![ %listitem.module; [
+<!ENTITY % local.listitem.attrib "">
+<!ENTITY % listitem.role.attrib "%role.attrib;">
+
+<!ENTITY % listitem.element "INCLUDE">
+<![ %listitem.element; [
+<!ELEMENT ListItem - O ((%component.mix;)+)>
+<!--end of listitem.element-->]]>
+
+<!ENTITY % listitem.attlist "INCLUDE">
+<![ %listitem.attlist; [
+<!ATTLIST ListItem
+ --
+ Override: Indicates the mark to be used for this ListItem
+ instead of the default mark or the mark specified by
+ the Mark attribute on the enclosing ItemizedList
+ --
+ Override CDATA #IMPLIED
+ %common.attrib;
+ %listitem.role.attrib;
+ %local.listitem.attrib;
+>
+<!--end of listitem.attlist-->]]>
+<!--end of listitem.module-->]]>
+
+<!-- SegmentedList .................... -->
+<!ENTITY % segmentedlist.content.module "INCLUDE">
+<![ %segmentedlist.content.module; [
+<!ENTITY % segmentedlist.module "INCLUDE">
+<![ %segmentedlist.module; [
+<!ENTITY % local.segmentedlist.attrib "">
+<!ENTITY % segmentedlist.role.attrib "%role.attrib;">
+
+<!ENTITY % segmentedlist.element "INCLUDE">
+<![ %segmentedlist.element; [
+<!ELEMENT SegmentedList - - ((%formalobject.title.content;)?,
+ SegTitle, SegTitle+,
+ SegListItem+)>
+<!--end of segmentedlist.element-->]]>
+
+<!ENTITY % segmentedlist.attlist "INCLUDE">
+<![ %segmentedlist.attlist; [
+<!ATTLIST SegmentedList
+ %common.attrib;
+ %segmentedlist.role.attrib;
+ %local.segmentedlist.attrib;
+>
+<!--end of segmentedlist.attlist-->]]>
+<!--end of segmentedlist.module-->]]>
+
+<!ENTITY % segtitle.module "INCLUDE">
+<![ %segtitle.module; [
+<!ENTITY % local.segtitle.attrib "">
+<!ENTITY % segtitle.role.attrib "%role.attrib;">
+
+<!ENTITY % segtitle.element "INCLUDE">
+<![ %segtitle.element; [
+<!ELEMENT SegTitle - O ((%title.char.mix;)+)>
+<!--end of segtitle.element-->]]>
+
+<!ENTITY % segtitle.attlist "INCLUDE">
+<![ %segtitle.attlist; [
+<!ATTLIST SegTitle
+ %common.attrib;
+ %segtitle.role.attrib;
+ %local.segtitle.attrib;
+>
+<!--end of segtitle.attlist-->]]>
+<!--end of segtitle.module-->]]>
+
+<!ENTITY % seglistitem.module "INCLUDE">
+<![ %seglistitem.module; [
+<!ENTITY % local.seglistitem.attrib "">
+<!ENTITY % seglistitem.role.attrib "%role.attrib;">
+
+<!ENTITY % seglistitem.element "INCLUDE">
+<![ %seglistitem.element; [
+<!ELEMENT SegListItem - O (Seg, Seg+)>
+<!--end of seglistitem.element-->]]>
+
+<!ENTITY % seglistitem.attlist "INCLUDE">
+<![ %seglistitem.attlist; [
+<!ATTLIST SegListItem
+ %common.attrib;
+ %seglistitem.role.attrib;
+ %local.seglistitem.attrib;
+>
+<!--end of seglistitem.attlist-->]]>
+<!--end of seglistitem.module-->]]>
+
+<!ENTITY % seg.module "INCLUDE">
+<![ %seg.module; [
+<!ENTITY % local.seg.attrib "">
+<!ENTITY % seg.role.attrib "%role.attrib;">
+
+<!ENTITY % seg.element "INCLUDE">
+<![ %seg.element; [
+<!ELEMENT Seg - O ((%para.char.mix;)+)>
+<!--end of seg.element-->]]>
+
+<!ENTITY % seg.attlist "INCLUDE">
+<![ %seg.attlist; [
+<!ATTLIST Seg
+ %common.attrib;
+ %seg.role.attrib;
+ %local.seg.attrib;
+>
+<!--end of seg.attlist-->]]>
+<!--end of seg.module-->]]>
+<!--end of segmentedlist.content.module-->]]>
+
+<!-- SimpleList ....................... -->
+
+<!ENTITY % simplelist.content.module "INCLUDE">
+<![ %simplelist.content.module; [
+<!ENTITY % simplelist.module "INCLUDE">
+<![ %simplelist.module; [
+<!ENTITY % local.simplelist.attrib "">
+<!ENTITY % simplelist.role.attrib "%role.attrib;">
+
+<!ENTITY % simplelist.element "INCLUDE">
+<![ %simplelist.element; [
+<!ELEMENT SimpleList - - (Member+)>
+<!--end of simplelist.element-->]]>
+
+<!ENTITY % simplelist.attlist "INCLUDE">
+<![ %simplelist.attlist; [
+<!ATTLIST SimpleList
+ --
+ Columns: The number of columns the array should contain
+ --
+ Columns NUMBER #IMPLIED
+ --
+ Type: How the Members of the SimpleList should be
+ formatted: Inline (members separated with commas etc.
+ inline), Vert (top to bottom in n Columns), or Horiz (in
+ the direction of text flow) in n Columns. If Column
+ is 1 or implied, Type=Vert and Type=Horiz give the same
+ results.
+ --
+ Type (Inline
+ |Vert
+ |Horiz) Vert
+ %common.attrib;
+ %simplelist.role.attrib;
+ %local.simplelist.attrib;
+>
+<!--end of simplelist.attlist-->]]>
+<!--end of simplelist.module-->]]>
+
+<!ENTITY % member.module "INCLUDE">
+<![ %member.module; [
+<!ENTITY % local.member.attrib "">
+<!ENTITY % member.role.attrib "%role.attrib;">
+
+<!ENTITY % member.element "INCLUDE">
+<![ %member.element; [
+<!ELEMENT Member - O ((%para.char.mix;)+)>
+<!--end of member.element-->]]>
+
+<!ENTITY % member.attlist "INCLUDE">
+<![ %member.attlist; [
+<!ATTLIST Member
+ %common.attrib;
+ %member.role.attrib;
+ %local.member.attrib;
+>
+<!--end of member.attlist-->]]>
+<!--end of member.module-->]]>
+<!--end of simplelist.content.module-->]]>
+
+<!-- VariableList ..................... -->
+
+<!ENTITY % variablelist.content.module "INCLUDE">
+<![ %variablelist.content.module; [
+<!ENTITY % variablelist.module "INCLUDE">
+<![ %variablelist.module; [
+<!ENTITY % local.variablelist.attrib "">
+<!ENTITY % variablelist.role.attrib "%role.attrib;">
+
+<!ENTITY % variablelist.element "INCLUDE">
+<![ %variablelist.element; [
+<!ELEMENT VariableList - - ((%formalobject.title.content;)?, VarListEntry+)>
+<!--end of variablelist.element-->]]>
+
+<!ENTITY % variablelist.attlist "INCLUDE">
+<![ %variablelist.attlist; [
+<!ATTLIST VariableList
+ --
+ TermLength: Length beyond which the presentation engine
+ may consider the Term too long and select an alternate
+ presentation of the Term and, or, its associated ListItem.
+ --
+ TermLength CDATA #IMPLIED
+ %common.attrib;
+ %variablelist.role.attrib;
+ %local.variablelist.attrib;
+>
+<!--end of variablelist.attlist-->]]>
+<!--end of variablelist.module-->]]>
+
+<!ENTITY % varlistentry.module "INCLUDE">
+<![ %varlistentry.module; [
+<!ENTITY % local.varlistentry.attrib "">
+<!ENTITY % varlistentry.role.attrib "%role.attrib;">
+
+<!ENTITY % varlistentry.element "INCLUDE">
+<![ %varlistentry.element; [
+<!ELEMENT VarListEntry - O (Term+, ListItem)>
+<!--end of varlistentry.element-->]]>
+
+<!ENTITY % varlistentry.attlist "INCLUDE">
+<![ %varlistentry.attlist; [
+<!ATTLIST VarListEntry
+ %common.attrib;
+ %varlistentry.role.attrib;
+ %local.varlistentry.attrib;
+>
+<!--end of varlistentry.attlist-->]]>
+<!--end of varlistentry.module-->]]>
+
+<!ENTITY % term.module "INCLUDE">
+<![ %term.module; [
+<!ENTITY % local.term.attrib "">
+<!ENTITY % term.role.attrib "%role.attrib;">
+
+<!ENTITY % term.element "INCLUDE">
+<![ %term.element; [
+<!ELEMENT Term - O ((%para.char.mix;)+)>
+<!--end of term.element-->]]>
+
+<!ENTITY % term.attlist "INCLUDE">
+<![ %term.attlist; [
+<!ATTLIST Term
+ %common.attrib;
+ %term.role.attrib;
+ %local.term.attrib;
+>
+<!--end of term.attlist-->]]>
+<!--end of term.module-->]]>
+
+<!-- ListItem (defined above)-->
+<!--end of variablelist.content.module-->]]>
+
+<!-- CalloutList ...................... -->
+
+<!ENTITY % calloutlist.content.module "INCLUDE">
+<![ %calloutlist.content.module; [
+<!ENTITY % calloutlist.module "INCLUDE">
+<![ %calloutlist.module; [
+<!ENTITY % local.calloutlist.attrib "">
+<!ENTITY % calloutlist.role.attrib "%role.attrib;">
+
+<!ENTITY % calloutlist.element "INCLUDE">
+<![ %calloutlist.element; [
+<!ELEMENT CalloutList - - ((%formalobject.title.content;)?, Callout+)>
+<!--end of calloutlist.element-->]]>
+
+<!ENTITY % calloutlist.attlist "INCLUDE">
+<![ %calloutlist.attlist; [
+<!ATTLIST CalloutList
+ %common.attrib;
+ %calloutlist.role.attrib;
+ %local.calloutlist.attrib;
+>
+<!--end of calloutlist.attlist-->]]>
+<!--end of calloutlist.module-->]]>
+
+<!ENTITY % callout.module "INCLUDE">
+<![ %callout.module; [
+<!ENTITY % local.callout.attrib "">
+<!ENTITY % callout.role.attrib "%role.attrib;">
+
+<!ENTITY % callout.element "INCLUDE">
+<![ %callout.element; [
+<!ELEMENT Callout - O ((%component.mix;)+)>
+<!--end of callout.element-->]]>
+
+<!ENTITY % callout.attlist "INCLUDE">
+<![ %callout.attlist; [
+<!ATTLIST Callout
+ --
+ AreaRefs: IDs of one or more Areas or AreaSets described
+ by this Callout
+ --
+ AreaRefs IDREFS #REQUIRED
+ %common.attrib;
+ %callout.role.attrib;
+ %local.callout.attrib;
+>
+<!--end of callout.attlist-->]]>
+<!--end of callout.module-->]]>
+<!--end of calloutlist.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Objects .............................................................. -->
+
+<!-- Examples etc. .................... -->
+
+<!ENTITY % example.module "INCLUDE">
+<![ %example.module; [
+<!ENTITY % local.example.attrib "">
+<!ENTITY % example.role.attrib "%role.attrib;">
+
+<!ENTITY % example.element "INCLUDE">
+<![ %example.element; [
+<!ELEMENT Example - - ((%formalobject.title.content;), (%example.mix;)+)
+ %formal.exclusion;>
+<!--end of example.element-->]]>
+
+<!ENTITY % example.attlist "INCLUDE">
+<![ %example.attlist; [
+<!ATTLIST Example
+ %label.attrib;
+ %width.attrib;
+ %common.attrib;
+ %example.role.attrib;
+ %local.example.attrib;
+>
+<!--end of example.attlist-->]]>
+<!--end of example.module-->]]>
+
+<!ENTITY % informalexample.module "INCLUDE">
+<![ %informalexample.module; [
+<!ENTITY % local.informalexample.attrib "">
+<!ENTITY % informalexample.role.attrib "%role.attrib;">
+
+<!ENTITY % informalexample.element "INCLUDE">
+<![ %informalexample.element; [
+<!ELEMENT InformalExample - - ((%example.mix;)+)>
+<!--end of informalexample.element-->]]>
+
+<!ENTITY % informalexample.attlist "INCLUDE">
+<![ %informalexample.attlist; [
+<!ATTLIST InformalExample
+ %width.attrib;
+ %common.attrib;
+ %informalexample.role.attrib;
+ %local.informalexample.attrib;
+>
+<!--end of informalexample.attlist-->]]>
+<!--end of informalexample.module-->]]>
+
+<!ENTITY % programlistingco.module "INCLUDE">
+<![ %programlistingco.module; [
+<!ENTITY % local.programlistingco.attrib "">
+<!ENTITY % programlistingco.role.attrib "%role.attrib;">
+
+<!ENTITY % programlistingco.element "INCLUDE">
+<![ %programlistingco.element; [
+<!ELEMENT ProgramListingCO - - (AreaSpec, ProgramListing, CalloutList*)>
+<!--end of programlistingco.element-->]]>
+
+<!ENTITY % programlistingco.attlist "INCLUDE">
+<![ %programlistingco.attlist; [
+<!ATTLIST ProgramListingCO
+ %common.attrib;
+ %programlistingco.role.attrib;
+ %local.programlistingco.attrib;
+>
+<!--end of programlistingco.attlist-->]]>
+<!-- CalloutList (defined above in Lists)-->
+<!--end of programlistingco.module-->]]>
+
+<!ENTITY % areaspec.content.module "INCLUDE">
+<![ %areaspec.content.module; [
+<!ENTITY % areaspec.module "INCLUDE">
+<![ %areaspec.module; [
+<!ENTITY % local.areaspec.attrib "">
+<!ENTITY % areaspec.role.attrib "%role.attrib;">
+
+<!ENTITY % areaspec.element "INCLUDE">
+<![ %areaspec.element; [
+<!ELEMENT AreaSpec - - ((Area|AreaSet)+)>
+<!--end of areaspec.element-->]]>
+
+<!ENTITY % areaspec.attlist "INCLUDE">
+<![ %areaspec.attlist; [
+<!ATTLIST AreaSpec
+ --
+ Units: global unit of measure in which coordinates in
+ this spec are expressed:
+
+ - CALSPair "x1,y1 x2,y2": lower-left and upper-right
+ coordinates in a rectangle describing repro area in which
+ graphic is placed, where X and Y dimensions are each some
+ number 0..10000 (taken from CALS graphic attributes)
+
+ - LineColumn "line column": line number and column number
+ at which to start callout text in "linespecific" content
+
+ - LineRange "startline endline": whole lines from startline
+ to endline in "linespecific" content
+
+ - LineColumnPair "line1 col1 line2 col2": starting and ending
+ points of area in "linespecific" content that starts at
+ first position and ends at second position (including the
+ beginnings of any intervening lines)
+
+ - Other: directive to look at value of OtherUnits attribute
+ to get implementation-specific keyword
+
+ The default is implementation-specific; usually dependent on
+ the parent element (GraphicCO gets CALSPair, ProgramListingCO
+ and ScreenCO get LineColumn)
+ --
+ Units (CALSPair
+ |LineColumn
+ |LineRange
+ |LineColumnPair
+ |Other) #IMPLIED
+ --
+ OtherUnits: User-defined units
+ --
+ OtherUnits NAME #IMPLIED
+ %common.attrib;
+ %areaspec.role.attrib;
+ %local.areaspec.attrib;
+>
+<!--end of areaspec.attlist-->]]>
+<!--end of areaspec.module-->]]>
+
+<!ENTITY % area.module "INCLUDE">
+<![ %area.module; [
+<!ENTITY % local.area.attrib "">
+<!ENTITY % area.role.attrib "%role.attrib;">
+
+<!ENTITY % area.element "INCLUDE">
+<![ %area.element; [
+<!ELEMENT Area - O EMPTY>
+<!--end of area.element-->]]>
+
+<!ENTITY % area.attlist "INCLUDE">
+<![ %area.attlist; [
+<!ATTLIST Area
+ %label.attrib; --bug number/symbol override or initialization--
+ %linkends.attrib; --to any related information--
+ --
+ Units: unit of measure in which coordinates in this
+ area are expressed; inherits from AreaSet and AreaSpec
+ --
+ Units (CALSPair
+ |LineColumn
+ |LineRange
+ |LineColumnPair
+ |Other) #IMPLIED
+ --
+ OtherUnits: User-defined units
+ --
+ OtherUnits NAME #IMPLIED
+ Coords CDATA #REQUIRED
+ %idreq.common.attrib;
+ %area.role.attrib;
+ %local.area.attrib;
+>
+<!--end of area.attlist-->]]>
+<!--end of area.module-->]]>
+
+<!ENTITY % areaset.module "INCLUDE">
+<![ %areaset.module; [
+<!ENTITY % local.areaset.attrib "">
+<!ENTITY % areaset.role.attrib "%role.attrib;">
+
+<!ENTITY % areaset.element "INCLUDE">
+<![ %areaset.element; [
+<!ELEMENT AreaSet - - (Area+)>
+<!--end of areaset.element-->]]>
+
+<!ENTITY % areaset.attlist "INCLUDE">
+<![ %areaset.attlist; [
+<!--FUTURE USE (V5.0):
+......................
+Coord attribute will be removed from AreaSet
+......................
+-->
+<!ATTLIST AreaSet
+ %label.attrib; --bug number/symbol override or initialization--
+
+ --
+ Units: unit of measure in which coordinates in this
+ area are expressed; inherits from AreaSpec
+ --
+ Units (CALSPair
+ |LineColumn
+ |LineRange
+ |LineColumnPair
+ |Other) #IMPLIED
+ OtherUnits NAME #IMPLIED
+ Coords CDATA #REQUIRED
+ %idreq.common.attrib;
+ %areaset.role.attrib;
+ %local.areaset.attrib;
+>
+<!--end of areaset.attlist-->]]>
+<!--end of areaset.module-->]]>
+<!--end of areaspec.content.module-->]]>
+
+<!ENTITY % programlisting.module "INCLUDE">
+<![ %programlisting.module; [
+<!ENTITY % local.programlisting.attrib "">
+<!ENTITY % programlisting.role.attrib "%role.attrib;">
+
+<!ENTITY % programlisting.element "INCLUDE">
+<![ %programlisting.element; [
+<!ELEMENT ProgramListing - - ((CO | LineAnnotation | %para.char.mix;)+)>
+<!--end of programlisting.element-->]]>
+
+<!ENTITY % programlisting.attlist "INCLUDE">
+<![ %programlisting.attlist; [
+<!ATTLIST ProgramListing
+ %width.attrib;
+ %linespecific.attrib;
+ %common.attrib;
+ %programlisting.role.attrib;
+ %local.programlisting.attrib;
+>
+<!--end of programlisting.attlist-->]]>
+<!--end of programlisting.module-->]]>
+
+<!ENTITY % literallayout.module "INCLUDE">
+<![ %literallayout.module; [
+<!ENTITY % local.literallayout.attrib "">
+<!ENTITY % literallayout.role.attrib "%role.attrib;">
+
+<!ENTITY % literallayout.element "INCLUDE">
+<![ %literallayout.element; [
+<!ELEMENT LiteralLayout - - ((CO | LineAnnotation | %para.char.mix;)+)>
+<!--end of literallayout.element-->]]>
+
+<!ENTITY % literallayout.attlist "INCLUDE">
+<![ %literallayout.attlist; [
+<!ATTLIST LiteralLayout
+ %width.attrib;
+ %linespecific.attrib;
+ Class (Monospaced|Normal) "Normal"
+ %common.attrib;
+ %literallayout.role.attrib;
+ %local.literallayout.attrib;
+>
+<!--end of literallayout.attlist-->]]>
+<!-- LineAnnotation (defined in the Inlines section, below)-->
+<!--end of literallayout.module-->]]>
+
+<!ENTITY % screenco.module "INCLUDE">
+<![ %screenco.module; [
+<!ENTITY % local.screenco.attrib "">
+<!ENTITY % screenco.role.attrib "%role.attrib;">
+
+<!ENTITY % screenco.element "INCLUDE">
+<![ %screenco.element; [
+<!ELEMENT ScreenCO - - (AreaSpec, Screen, CalloutList*)>
+<!--end of screenco.element-->]]>
+
+<!ENTITY % screenco.attlist "INCLUDE">
+<![ %screenco.attlist; [
+<!ATTLIST ScreenCO
+ %common.attrib;
+ %screenco.role.attrib;
+ %local.screenco.attrib;
+>
+<!--end of screenco.attlist-->]]>
+<!-- AreaSpec (defined above)-->
+<!-- CalloutList (defined above in Lists)-->
+<!--end of screenco.module-->]]>
+
+<!ENTITY % screen.module "INCLUDE">
+<![ %screen.module; [
+<!ENTITY % local.screen.attrib "">
+<!ENTITY % screen.role.attrib "%role.attrib;">
+
+<!ENTITY % screen.element "INCLUDE">
+<![ %screen.element; [
+<!ELEMENT Screen - - ((CO | LineAnnotation | %para.char.mix;)+)>
+<!--end of screen.element-->]]>
+
+<!ENTITY % screen.attlist "INCLUDE">
+<![ %screen.attlist; [
+<!ATTLIST Screen
+ %width.attrib;
+ %linespecific.attrib;
+ %common.attrib;
+ %screen.role.attrib;
+ %local.screen.attrib;
+>
+<!--end of screen.attlist-->]]>
+<!--end of screen.module-->]]>
+
+<!ENTITY % screenshot.content.module "INCLUDE">
+<![ %screenshot.content.module; [
+<!ENTITY % screenshot.module "INCLUDE">
+<![ %screenshot.module; [
+<!ENTITY % local.screenshot.attrib "">
+<!ENTITY % screenshot.role.attrib "%role.attrib;">
+
+<!ENTITY % screenshot.element "INCLUDE">
+<![ %screenshot.element; [
+<!ELEMENT ScreenShot - - (ScreenInfo?,
+ (Graphic|GraphicCO
+ |MediaObject|MediaObjectCO))>
+<!--end of screenshot.element-->]]>
+
+<!ENTITY % screenshot.attlist "INCLUDE">
+<![ %screenshot.attlist; [
+<!ATTLIST ScreenShot
+ %common.attrib;
+ %screenshot.role.attrib;
+ %local.screenshot.attrib;
+>
+<!--end of screenshot.attlist-->]]>
+<!--end of screenshot.module-->]]>
+
+<!ENTITY % screeninfo.module "INCLUDE">
+<![ %screeninfo.module; [
+<!ENTITY % local.screeninfo.attrib "">
+<!ENTITY % screeninfo.role.attrib "%role.attrib;">
+
+<!ENTITY % screeninfo.element "INCLUDE">
+<![ %screeninfo.element; [
+<!ELEMENT ScreenInfo - O ((%para.char.mix;)+) %ubiq.exclusion;>
+<!--end of screeninfo.element-->]]>
+
+<!ENTITY % screeninfo.attlist "INCLUDE">
+<![ %screeninfo.attlist; [
+<!ATTLIST ScreenInfo
+ %common.attrib;
+ %screeninfo.role.attrib;
+ %local.screeninfo.attrib;
+>
+<!--end of screeninfo.attlist-->]]>
+<!--end of screeninfo.module-->]]>
+<!--end of screenshot.content.module-->]]>
+
+<!-- Figures etc. ..................... -->
+
+<!ENTITY % figure.module "INCLUDE">
+<![ %figure.module; [
+<!ENTITY % local.figure.attrib "">
+<!ENTITY % figure.role.attrib "%role.attrib;">
+
+<!ENTITY % figure.element "INCLUDE">
+<![ %figure.element; [
+<!ELEMENT Figure - - ((%formalobject.title.content;), (%figure.mix; |
+ %link.char.class;)+)>
+<!--end of figure.element-->]]>
+
+<!ENTITY % figure.attlist "INCLUDE">
+<![ %figure.attlist; [
+<!ATTLIST Figure
+ --
+ Float: Whether the Figure is supposed to be rendered
+ where convenient (yes (1) value) or at the place it occurs
+ in the text (no (0) value, the default)
+ --
+ Float %yesorno.attvals; %no.attval;
+ PgWide %yesorno.attvals; #IMPLIED
+ %label.attrib;
+ %common.attrib;
+ %figure.role.attrib;
+ %local.figure.attrib;
+>
+<!--end of figure.attlist-->]]>
+<!--end of figure.module-->]]>
+
+<!ENTITY % informalfigure.module "INCLUDE">
+<![ %informalfigure.module; [
+<!ENTITY % local.informalfigure.attrib "">
+<!ENTITY % informalfigure.role.attrib "%role.attrib;">
+
+<!ENTITY % informalfigure.element "INCLUDE">
+<![ %informalfigure.element; [
+<!ELEMENT InformalFigure - - ((%figure.mix; | %link.char.class;)+)>
+<!--end of informalfigure.element-->]]>
+
+<!ENTITY % informalfigure.attlist "INCLUDE">
+<![ %informalfigure.attlist; [
+<!ATTLIST InformalFigure
+ --
+ Float: Whether the Figure is supposed to be rendered
+ where convenient (yes (1) value) or at the place it occurs
+ in the text (no (0) value, the default)
+ --
+ Float %yesorno.attvals; %no.attval;
+ PgWide %yesorno.attvals; #IMPLIED
+ %label.attrib;
+ %common.attrib;
+ %informalfigure.role.attrib;
+ %local.informalfigure.attrib;
+>
+<!--end of informalfigure.attlist-->]]>
+<!--end of informalfigure.module-->]]>
+
+<!ENTITY % graphicco.module "INCLUDE">
+<![ %graphicco.module; [
+<!ENTITY % local.graphicco.attrib "">
+<!ENTITY % graphicco.role.attrib "%role.attrib;">
+
+<!ENTITY % graphicco.element "INCLUDE">
+<![ %graphicco.element; [
+<!ELEMENT GraphicCO - - (AreaSpec, Graphic, CalloutList*)>
+<!--end of graphicco.element-->]]>
+
+<!ENTITY % graphicco.attlist "INCLUDE">
+<![ %graphicco.attlist; [
+<!ATTLIST GraphicCO
+ %common.attrib;
+ %graphicco.role.attrib;
+ %local.graphicco.attrib;
+>
+<!--end of graphicco.attlist-->]]>
+<!-- AreaSpec (defined above in Examples)-->
+<!-- CalloutList (defined above in Lists)-->
+<!--end of graphicco.module-->]]>
+
+<!-- Graphical data can be the content of Graphic, or you can reference
+ an external file either as an entity (Entitref) or a filename
+ (Fileref). -->
+
+<!ENTITY % graphic.module "INCLUDE">
+<![ %graphic.module; [
+<!ENTITY % local.graphic.attrib "">
+<!ENTITY % graphic.role.attrib "%role.attrib;">
+
+<!ENTITY % graphic.element "INCLUDE">
+<![ %graphic.element; [
+<!ELEMENT Graphic - O EMPTY>
+<!--end of graphic.element-->]]>
+
+<!ENTITY % graphic.attlist "INCLUDE">
+<![ %graphic.attlist; [
+<!ATTLIST Graphic
+ %graphics.attrib;
+ %common.attrib;
+ %graphic.role.attrib;
+ %local.graphic.attrib;
+>
+<!--end of graphic.attlist-->]]>
+<!--end of graphic.module-->]]>
+
+<!ENTITY % inlinegraphic.module "INCLUDE">
+<![ %inlinegraphic.module; [
+<!ENTITY % local.inlinegraphic.attrib "">
+<!ENTITY % inlinegraphic.role.attrib "%role.attrib;">
+
+<!ENTITY % inlinegraphic.element "INCLUDE">
+<![ %inlinegraphic.element; [
+<!ELEMENT InlineGraphic - O EMPTY>
+<!--end of inlinegraphic.element-->]]>
+
+<!ENTITY % inlinegraphic.attlist "INCLUDE">
+<![ %inlinegraphic.attlist; [
+<!ATTLIST InlineGraphic
+ %graphics.attrib;
+ %common.attrib;
+ %inlinegraphic.role.attrib;
+ %local.inlinegraphic.attrib;
+>
+<!--end of inlinegraphic.attlist-->]]>
+<!--end of inlinegraphic.module-->]]>
+
+<!ENTITY % mediaobject.content.module "INCLUDE">
+<![ %mediaobject.content.module; [
+
+<!ENTITY % mediaobject.module "INCLUDE">
+<![ %mediaobject.module; [
+<!ENTITY % local.mediaobject.attrib "">
+<!ENTITY % mediaobject.role.attrib "%role.attrib;">
+
+<!ENTITY % mediaobject.element "INCLUDE">
+<![ %mediaobject.element; [
+<!ELEMENT MediaObject - - (ObjectInfo?,
+ (%mediaobject.mix;),
+ (%mediaobject.mix;|TextObject)*,
+ Caption?)>
+<!--end of mediaobject.element-->]]>
+
+<!ENTITY % mediaobject.attlist "INCLUDE">
+<![ %mediaobject.attlist; [
+<!ATTLIST MediaObject
+ %common.attrib;
+ %mediaobject.role.attrib;
+ %local.mediaobject.attrib;
+>
+<!--end of mediaobject.attlist-->]]>
+<!--end of mediaobject.module-->]]>
+
+<!ENTITY % inlinemediaobject.module "INCLUDE">
+<![ %inlinemediaobject.module; [
+<!ENTITY % local.inlinemediaobject.attrib "">
+<!ENTITY % inlinemediaobject.role.attrib "%role.attrib;">
+
+<!ENTITY % inlinemediaobject.element "INCLUDE">
+<![ %inlinemediaobject.element; [
+<!ELEMENT InlineMediaObject - - (ObjectInfo?,
+ (%mediaobject.mix;),
+ (%mediaobject.mix;|TextObject)*)>
+<!--end of inlinemediaobject.element-->]]>
+
+<!ENTITY % inlinemediaobject.attlist "INCLUDE">
+<![ %inlinemediaobject.attlist; [
+<!ATTLIST InlineMediaObject
+ %common.attrib;
+ %inlinemediaobject.role.attrib;
+ %local.inlinemediaobject.attrib;
+>
+<!--end of inlinemediaobject.attlist-->]]>
+<!--end of inlinemediaobject.module-->]]>
+
+<!ENTITY % videoobject.module "INCLUDE">
+<![ %videoobject.module; [
+<!ENTITY % local.videoobject.attrib "">
+<!ENTITY % videoobject.role.attrib "%role.attrib;">
+
+<!ENTITY % videoobject.element "INCLUDE">
+<![ %videoobject.element; [
+<!ELEMENT VideoObject - - (ObjectInfo?, VideoData)>
+<!--end of videoobject.element-->]]>
+
+<!ENTITY % videoobject.attlist "INCLUDE">
+<![ %videoobject.attlist; [
+<!ATTLIST VideoObject
+ %common.attrib;
+ %videoobject.role.attrib;
+ %local.videoobject.attrib;
+>
+<!--end of videoobject.attlist-->]]>
+<!--end of videoobject.module-->]]>
+
+<!ENTITY % audioobject.module "INCLUDE">
+<![ %audioobject.module; [
+<!ENTITY % local.audioobject.attrib "">
+<!ENTITY % audioobject.role.attrib "%role.attrib;">
+
+<!ENTITY % audioobject.element "INCLUDE">
+<![ %audioobject.element; [
+<!ELEMENT AudioObject - - (ObjectInfo?, AudioData)>
+<!--end of audioobject.element-->]]>
+
+<!ENTITY % audioobject.attlist "INCLUDE">
+<![ %audioobject.attlist; [
+<!ATTLIST AudioObject
+ %common.attrib;
+ %audioobject.role.attrib;
+ %local.audioobject.attrib;
+>
+<!--end of audioobject.attlist-->]]>
+<!--end of audioobject.module-->]]>
+
+<!ENTITY % imageobject.module "INCLUDE">
+<![ %imageobject.module; [
+<!ENTITY % local.imageobject.attrib "">
+<!ENTITY % imageobject.role.attrib "%role.attrib;">
+
+<!ENTITY % imageobject.element "INCLUDE">
+<![ %imageobject.element; [
+<!ELEMENT ImageObject - - (ObjectInfo?, ImageData)>
+<!--end of imageobject.element-->]]>
+
+<!ENTITY % imageobject.attlist "INCLUDE">
+<![ %imageobject.attlist; [
+<!ATTLIST ImageObject
+ %common.attrib;
+ %imageobject.role.attrib;
+ %local.imageobject.attrib;
+>
+<!--end of imageobject.attlist-->]]>
+<!--end of imageobject.module-->]]>
+
+<!ENTITY % textobject.module "INCLUDE">
+<![ %textobject.module; [
+<!ENTITY % local.textobject.attrib "">
+<!ENTITY % textobject.role.attrib "%role.attrib;">
+
+<!ENTITY % textobject.element "INCLUDE">
+<![ %textobject.element; [
+<!ELEMENT TextObject - - (ObjectInfo?, (Phrase|(%textobject.mix;)+))>
+<!--end of textobject.element-->]]>
+
+<!ENTITY % textobject.attlist "INCLUDE">
+<![ %textobject.attlist; [
+<!ATTLIST TextObject
+ %common.attrib;
+ %textobject.role.attrib;
+ %local.textobject.attrib;
+>
+<!--end of textobject.attlist-->]]>
+<!--end of textobject.module-->]]>
+
+<!ENTITY % objectinfo.module "INCLUDE">
+<![ %objectinfo.module; [
+<!ENTITY % local.objectinfo.attrib "">
+<!ENTITY % objectinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % objectinfo.element "INCLUDE">
+<![ %objectinfo.element; [
+<!ELEMENT ObjectInfo - - ((Graphic | MediaObject | LegalNotice | ModeSpec
+ | SubjectSet | KeywordSet | ITermSet | %bibliocomponent.mix;)+)
+ -(BeginPage)>
+<!--end of objectinfo.element-->]]>
+
+<!ENTITY % objectinfo.attlist "INCLUDE">
+<![ %objectinfo.attlist; [
+<!ATTLIST ObjectInfo
+ %common.attrib;
+ %objectinfo.role.attrib;
+ %local.objectinfo.attrib;
+>
+<!--end of objectinfo.attlist-->]]>
+<!--end of objectinfo.module-->]]>
+
+<!ENTITY % local.objectdata.attrib "">
+<!ENTITY % objectdata.attrib
+ "
+ --EntityRef: Name of an external entity containing the content
+ of the object data--
+ EntityRef ENTITY #IMPLIED
+
+ --FileRef: Filename, qualified by a pathname if desired,
+ designating the file containing the content of the object data--
+ FileRef CDATA #IMPLIED
+
+ --Format: Notation of the element content, if any--
+ Format (%notation.class;)
+ #IMPLIED
+
+ --SrcCredit: Information about the source of the image--
+ SrcCredit CDATA #IMPLIED
+
+ %local.objectdata.attrib;"
+>
+
+<!ENTITY % videodata.module "INCLUDE">
+<![ %videodata.module; [
+<!ENTITY % local.videodata.attrib "">
+<!ENTITY % videodata.role.attrib "%role.attrib;">
+
+<!ENTITY % videodata.element "INCLUDE">
+<![ %videodata.element; [
+<!ELEMENT VideoData - O EMPTY>
+<!--end of videodata.element-->]]>
+
+<!ENTITY % videodata.attlist "INCLUDE">
+<![ %videodata.attlist; [
+<!ATTLIST VideoData
+ %common.attrib;
+ %objectdata.attrib;
+
+ --Width: Same as CALS reprowid (desired width)--
+ Width NUTOKEN #IMPLIED
+
+ --Depth: Same as CALS reprodep (desired depth)--
+ Depth NUTOKEN #IMPLIED
+
+ --Align: Same as CALS hplace with 'none' removed; #IMPLIED means
+ application-specific--
+ Align (Left
+ |Right
+ |Center) #IMPLIED
+
+ --Scale: Conflation of CALS hscale and vscale--
+ Scale NUMBER #IMPLIED
+
+ --Scalefit: Same as CALS scalefit--
+ Scalefit %yesorno.attvals;
+ #IMPLIED
+
+ %videodata.role.attrib;
+ %local.videodata.attrib;
+>
+<!--end of videodata.attlist-->]]>
+<!--end of videodata.module-->]]>
+
+<!ENTITY % audiodata.module "INCLUDE">
+<![ %audiodata.module; [
+<!ENTITY % local.audiodata.attrib "">
+<!ENTITY % audiodata.role.attrib "%role.attrib;">
+
+<!ENTITY % audiodata.element "INCLUDE">
+<![ %audiodata.element; [
+<!ELEMENT AudioData - O EMPTY>
+<!--end of audiodata.element-->]]>
+
+<!ENTITY % audiodata.attlist "INCLUDE">
+<![ %audiodata.attlist; [
+<!ATTLIST AudioData
+ %common.attrib;
+ %objectdata.attrib;
+ %local.audiodata.attrib;
+ %audiodata.role.attrib;
+>
+<!--end of audiodata.attlist-->]]>
+<!--end of audiodata.module-->]]>
+
+<!ENTITY % imagedata.module "INCLUDE">
+<![ %imagedata.module; [
+<!ENTITY % local.imagedata.attrib "">
+<!ENTITY % imagedata.role.attrib "%role.attrib;">
+
+<!ENTITY % imagedata.element "INCLUDE">
+<![ %imagedata.element; [
+<!ELEMENT ImageData - O EMPTY>
+<!--end of imagedata.element-->]]>
+
+<!ENTITY % imagedata.attlist "INCLUDE">
+<![ %imagedata.attlist; [
+<!ATTLIST ImageData
+ %common.attrib;
+ %objectdata.attrib;
+
+ --Width: Same as CALS reprowid (desired width)--
+ Width NUTOKEN #IMPLIED
+
+ --Depth: Same as CALS reprodep (desired depth)--
+ Depth NUTOKEN #IMPLIED
+
+ --Align: Same as CALS hplace with 'none' removed; #IMPLIED means
+ application-specific--
+ Align (Left
+ |Right
+ |Center) #IMPLIED
+
+ --Scale: Conflation of CALS hscale and vscale--
+ Scale NUMBER #IMPLIED
+
+ --Scalefit: Same as CALS scalefit--
+ Scalefit %yesorno.attvals;
+ #IMPLIED
+
+ %local.imagedata.attrib;
+ %imagedata.role.attrib;
+>
+<!--end of imagedata.attlist-->]]>
+<!--end of imagedata.module-->]]>
+
+<!ENTITY % caption.module "INCLUDE">
+<![ %caption.module; [
+<!ENTITY % local.caption.attrib "">
+<!ENTITY % caption.role.attrib "%role.attrib;">
+
+<!ENTITY % caption.element "INCLUDE">
+<![ %caption.element; [
+<!ELEMENT Caption - - (%textobject.mix;)*>
+<!--end of caption.element-->]]>
+
+<!ENTITY % caption.attlist "INCLUDE">
+<![ %caption.attlist; [
+<!ATTLIST Caption
+ %common.attrib;
+ %local.caption.attrib;
+ %caption.role.attrib;
+>
+<!--end of caption.attlist-->]]>
+<!--end of caption.module-->]]>
+
+<!ENTITY % mediaobjectco.module "INCLUDE">
+<![ %mediaobjectco.module; [
+<!ENTITY % local.mediaobjectco.attrib "">
+<!ENTITY % mediaobjectco.role.attrib "%role.attrib;">
+
+<!ENTITY % mediaobjectco.element "INCLUDE">
+<![ %mediaobjectco.element; [
+<!ELEMENT MediaObjectCO - - (ObjectInfo?, ImageObjectCO,
+ (ImageObjectCO|TextObject)*)>
+<!--end of mediaobjectco.element-->]]>
+
+<!ENTITY % mediaobjectco.attlist "INCLUDE">
+<![ %mediaobjectco.attlist; [
+<!ATTLIST MediaObjectCO
+ %common.attrib;
+ %mediaobjectco.role.attrib;
+ %local.mediaobjectco.attrib;
+>
+<!--end of mediaobjectco.attlist-->]]>
+<!--end of mediaobjectco.module-->]]>
+
+<!ENTITY % imageobjectco.module "INCLUDE">
+<![ %imageobjectco.module; [
+<!ENTITY % local.imageobjectco.attrib "">
+<!ENTITY % imageobjectco.role.attrib "%role.attrib;">
+
+<!ENTITY % imageobjectco.element "INCLUDE">
+<![ %imageobjectco.element; [
+<!ELEMENT ImageObjectCO - - (AreaSpec, ImageObject, CalloutList*)>
+<!--end of imageobjectco.element-->]]>
+
+<!ENTITY % imageobjectco.attlist "INCLUDE">
+<![ %imageobjectco.attlist; [
+<!ATTLIST ImageObjectCO
+ %common.attrib;
+ %imageobjectco.role.attrib;
+ %local.imageobjectco.attrib;
+>
+<!--end of imageobjectco.attlist-->]]>
+<!--end of imageobjectco.module-->]]>
+<!--end of mediaobject.content.module-->]]>
+
+<!-- Equations ........................ -->
+
+<!-- This PE provides a mechanism for replacing equation content, -->
+<!-- perhaps adding a new or different model (e.g., MathML) -->
+<!ENTITY % equation.content "(Alt?, (Graphic+|MediaObject+))">
+<!ENTITY % inlineequation.content "(Alt?, (Graphic+|InlineMediaObject+))">
+
+<!ENTITY % equation.module "INCLUDE">
+<![ %equation.module; [
+<!ENTITY % local.equation.attrib "">
+<!ENTITY % equation.role.attrib "%role.attrib;">
+
+<!ENTITY % equation.element "INCLUDE">
+<![ %equation.element; [
+<!ELEMENT Equation - - ((%formalobject.title.content;)?, (InformalEquation |
+ %equation.content;))>
+<!--end of equation.element-->]]>
+
+<!ENTITY % equation.attlist "INCLUDE">
+<![ %equation.attlist; [
+<!ATTLIST Equation
+ %label.attrib;
+ %common.attrib;
+ %equation.role.attrib;
+ %local.equation.attrib;
+>
+<!--end of equation.attlist-->]]>
+<!--end of equation.module-->]]>
+
+<!ENTITY % informalequation.module "INCLUDE">
+<![ %informalequation.module; [
+<!ENTITY % local.informalequation.attrib "">
+<!ENTITY % informalequation.role.attrib "%role.attrib;">
+
+<!ENTITY % informalequation.element "INCLUDE">
+<![ %informalequation.element; [
+<!ELEMENT InformalEquation - - (%equation.content;)>
+<!--end of informalequation.element-->]]>
+
+<!ENTITY % informalequation.attlist "INCLUDE">
+<![ %informalequation.attlist; [
+<!ATTLIST InformalEquation
+ %common.attrib;
+ %informalequation.role.attrib;
+ %local.informalequation.attrib;
+>
+<!--end of informalequation.attlist-->]]>
+<!--end of informalequation.module-->]]>
+
+<!ENTITY % inlineequation.module "INCLUDE">
+<![ %inlineequation.module; [
+<!ENTITY % local.inlineequation.attrib "">
+<!ENTITY % inlineequation.role.attrib "%role.attrib;">
+
+<!ENTITY % inlineequation.element "INCLUDE">
+<![ %inlineequation.element; [
+<!ELEMENT InlineEquation - - (%inlineequation.content;)>
+<!--end of inlineequation.element-->]]>
+
+<!ENTITY % inlineequation.attlist "INCLUDE">
+<![ %inlineequation.attlist; [
+<!ATTLIST InlineEquation
+ %common.attrib;
+ %inlineequation.role.attrib;
+ %local.inlineequation.attrib;
+>
+<!--end of inlineequation.attlist-->]]>
+<!--end of inlineequation.module-->]]>
+
+<!ENTITY % alt.module "INCLUDE">
+<![ %alt.module; [
+<!ENTITY % local.alt.attrib "">
+<!ENTITY % alt.role.attrib "%role.attrib;">
+
+<!ENTITY % alt.element "INCLUDE">
+<![ %alt.element; [
+<!ELEMENT Alt - - (#PCDATA)>
+<!--end of alt.element-->]]>
+
+<!ENTITY % alt.attlist "INCLUDE">
+<![ %alt.attlist; [
+<!ATTLIST Alt
+ %common.attrib;
+ %alt.role.attrib;
+ %local.alt.attrib;
+>
+<!--end of alt.attlist-->]]>
+<!--end of alt.module-->]]>
+
+<!-- Tables ........................... -->
+
+<!ENTITY % table.module "INCLUDE">
+<![ %table.module; [
+
+<!ENTITY % tables.role.attrib "%role.attrib;">
+
+<!-- Add Label attribute to Table element (and InformalTable element). -->
+<!ENTITY % bodyatt "%label.attrib;">
+
+<!-- Add common attributes to Table, TGroup, TBody, THead, TFoot, Row,
+ EntryTbl, and Entry (and InformalTable element). -->
+<!ENTITY % secur
+ "%common.attrib;
+ %tables.role.attrib;">
+
+<!-- Remove Chart. -->
+<!ENTITY % tbl.table.name "Table">
+
+<!-- Content model for Table. -->
+<!ENTITY % tbl.table.mdl
+ "((%formalobject.title.content;),
+ (%ndxterm.class;)*,
+ (Graphic+|MediaObject+|tgroup+))">
+
+<!-- Exclude all DocBook tables and formal objects. -->
+<!ENTITY % tbl.table.excep "-(InformalTable|%formal.class;)">
+
+<!-- Remove pgbrk exception on Row. -->
+<!ENTITY % tbl.row.excep "">
+
+<!-- Allow either objects or inlines; beware of REs between elements. -->
+<!ENTITY % tbl.entry.mdl "((%tabentry.mix;)+ | (%para.char.mix;)+)">
+
+<!-- Remove pgbrk exception on Entry. -->
+<!ENTITY % tbl.entry.excep "">
+
+<!-- Remove pgbrk exception on EntryTbl, but leave exclusion of itself. -->
+<!ENTITY % tbl.entrytbl.excep "-(entrytbl)">
+
+<!-- Reference CALS table module. -->
+<!ENTITY % calstbls PUBLIC "-//USA-DOD//DTD Table Model 951010//EN">
+%calstbls;
+<!--end of table.module-->]]>
+
+<!ENTITY % informaltable.module "INCLUDE">
+<![ %informaltable.module; [
+
+<!-- Note that InformalTable is dependent on some of the entity
+ declarations that customize Table. -->
+
+<!ENTITY % local.informaltable.attrib "">
+
+<!ENTITY % informaltable.element "INCLUDE">
+<![ %informaltable.element; [
+<!ELEMENT InformalTable - - (Graphic+|MediaObject+|tgroup+) %tbl.table.excep;>
+<!--end of informaltable.element-->]]>
+
+<!ENTITY % informaltable.attlist "INCLUDE">
+<![ %informaltable.attlist; [
+<!ATTLIST InformalTable
+ --
+ Frame, Colsep, and Rowsep must be repeated because
+ they are not in entities in the table module.
+ --
+ Frame (Top
+ |Bottom
+ |Topbot
+ |All
+ |Sides
+ |None) #IMPLIED
+ Colsep %yesorno.attvals; #IMPLIED
+ Rowsep %yesorno.attvals; #IMPLIED
+ %tbl.table.att; -- includes TabStyle, ToCentry, ShortEntry,
+ Orient, PgWide --
+ %bodyatt; -- includes Label --
+ %secur; -- includes common attributes --
+ %local.informaltable.attrib;
+>
+<!--end of informaltable.attlist-->]]>
+<!--end of informaltable.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Synopses ............................................................. -->
+
+<!-- Synopsis ......................... -->
+
+<!ENTITY % synopsis.module "INCLUDE">
+<![ %synopsis.module; [
+<!ENTITY % local.synopsis.attrib "">
+<!ENTITY % synopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % synopsis.element "INCLUDE">
+<![ %synopsis.element; [
+<!ELEMENT Synopsis - - ((CO | LineAnnotation | %para.char.mix;
+ | Graphic | MediaObject)+)>
+<!--end of synopsis.element-->]]>
+
+<!ENTITY % synopsis.attlist "INCLUDE">
+<![ %synopsis.attlist; [
+<!ATTLIST Synopsis
+ %label.attrib;
+ %linespecific.attrib;
+ %common.attrib;
+ %synopsis.role.attrib;
+ %local.synopsis.attrib;
+>
+<!--end of synopsis.attlist-->]]>
+
+<!-- LineAnnotation (defined in the Inlines section, below)-->
+<!--end of synopsis.module-->]]>
+
+<!-- CmdSynopsis ...................... -->
+
+<!ENTITY % cmdsynopsis.content.module "INCLUDE">
+<![ %cmdsynopsis.content.module; [
+<!ENTITY % cmdsynopsis.module "INCLUDE">
+<![ %cmdsynopsis.module; [
+<!ENTITY % local.cmdsynopsis.attrib "">
+<!ENTITY % cmdsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % cmdsynopsis.element "INCLUDE">
+<![ %cmdsynopsis.element; [
+<!ELEMENT CmdSynopsis - - ((Command | Arg | Group | SBR)+, SynopFragment*)>
+<!--end of cmdsynopsis.element-->]]>
+
+<!ENTITY % cmdsynopsis.attlist "INCLUDE">
+<![ %cmdsynopsis.attlist; [
+<!ATTLIST CmdSynopsis
+ %label.attrib;
+ --
+ Sepchar: Character that should separate command and all
+ top-level arguments; alternate value might be e.g., &Delta;
+ --
+ Sepchar CDATA " "
+ --
+ CmdLength: Length beyond which the presentation engine
+ may consider a Command too long and select an alternate
+ presentation of the Command and, or, its associated
+ arguments.
+ --
+ CmdLength CDATA #IMPLIED
+ %common.attrib;
+ %cmdsynopsis.role.attrib;
+ %local.cmdsynopsis.attrib;
+>
+<!--end of cmdsynopsis.attlist-->]]>
+<!--end of cmdsynopsis.module-->]]>
+
+<!ENTITY % arg.module "INCLUDE">
+<![ %arg.module; [
+<!ENTITY % local.arg.attrib "">
+<!ENTITY % arg.role.attrib "%role.attrib;">
+
+<!ENTITY % arg.element "INCLUDE">
+<![ %arg.element; [
+<!ELEMENT Arg - - ((#PCDATA
+ | Arg
+ | Group
+ | Option
+ | SynopFragmentRef
+ | Replaceable
+ | SBR)+)>
+<!--end of arg.element-->]]>
+
+<!ENTITY % arg.attlist "INCLUDE">
+<![ %arg.attlist; [
+<!ATTLIST Arg
+ --
+ Choice: Whether Arg must be supplied: Opt (optional to
+ supply, e.g. [arg]; the default), Req (required to supply,
+ e.g. {arg}), or Plain (required to supply, e.g. arg)
+ --
+ Choice (Opt
+ |Req
+ |Plain) Opt
+ --
+ Rep: whether Arg is repeatable: Norepeat (e.g. arg without
+ ellipsis; the default), or Repeat (e.g. arg...)
+ --
+ Rep (Norepeat
+ |Repeat) Norepeat
+ %common.attrib;
+ %arg.role.attrib;
+ %local.arg.attrib;
+>
+<!--end of arg.attlist-->]]>
+<!--end of arg.module-->]]>
+
+<!ENTITY % group.module "INCLUDE">
+<![ %group.module; [
+
+<!ENTITY % local.group.attrib "">
+<!ENTITY % group.role.attrib "%role.attrib;">
+
+<!ENTITY % group.element "INCLUDE">
+<![ %group.element; [
+<!ELEMENT Group - - ((Arg | Group | Option | SynopFragmentRef
+ | Replaceable | SBR)+)>
+<!--end of group.element-->]]>
+
+<!ENTITY % group.attlist "INCLUDE">
+<![ %group.attlist; [
+<!ATTLIST Group
+ --
+ Choice: Whether Group must be supplied: Opt (optional to
+ supply, e.g. [g1|g2|g3]; the default), Req (required to
+ supply, e.g. {g1|g2|g3}), Plain (required to supply,
+ e.g. g1|g2|g3), OptMult (can supply zero or more, e.g.
+ [[g1|g2|g3]]), or ReqMult (must supply one or more, e.g.
+ {{g1|g2|g3}})
+ --
+ Choice (Opt
+ |Req
+ |Plain) Opt
+ --
+ Rep: whether Group is repeatable: Norepeat (e.g. group
+ without ellipsis; the default), or Repeat (e.g. group...)
+ --
+ Rep (Norepeat
+ |Repeat) Norepeat
+ %common.attrib;
+ %group.role.attrib;
+ %local.group.attrib;
+>
+<!--end of group.attlist-->]]>
+<!--end of group.module-->]]>
+
+<!ENTITY % sbr.module "INCLUDE">
+<![ %sbr.module; [
+<!ENTITY % local.sbr.attrib "">
+<!-- Synopsis break -->
+<!ENTITY % sbr.role.attrib "%role.attrib;">
+
+<!ENTITY % sbr.element "INCLUDE">
+<![ %sbr.element; [
+<!ELEMENT SBR - O EMPTY>
+<!--end of sbr.element-->]]>
+
+<!ENTITY % sbr.attlist "INCLUDE">
+<![ %sbr.attlist; [
+<!ATTLIST SBR
+ %common.attrib;
+ %sbr.role.attrib;
+ %local.sbr.attrib;
+>
+<!--end of sbr.attlist-->]]>
+<!--end of sbr.module-->]]>
+
+<!ENTITY % synopfragmentref.module "INCLUDE">
+<![ %synopfragmentref.module; [
+<!ENTITY % local.synopfragmentref.attrib "">
+<!ENTITY % synopfragmentref.role.attrib "%role.attrib;">
+
+<!ENTITY % synopfragmentref.element "INCLUDE">
+<![ %synopfragmentref.element; [
+<!ELEMENT SynopFragmentRef - - RCDATA >
+<!--end of synopfragmentref.element-->]]>
+
+<!ENTITY % synopfragmentref.attlist "INCLUDE">
+<![ %synopfragmentref.attlist; [
+<!ATTLIST SynopFragmentRef
+ %linkendreq.attrib; --to SynopFragment of complex synopsis
+ material for separate referencing--
+ %common.attrib;
+ %synopfragmentref.role.attrib;
+ %local.synopfragmentref.attrib;
+>
+<!--end of synopfragmentref.attlist-->]]>
+<!--end of synopfragmentref.module-->]]>
+
+<!ENTITY % synopfragment.module "INCLUDE">
+<![ %synopfragment.module; [
+<!ENTITY % local.synopfragment.attrib "">
+<!ENTITY % synopfragment.role.attrib "%role.attrib;">
+
+<!ENTITY % synopfragment.element "INCLUDE">
+<![ %synopfragment.element; [
+<!ELEMENT SynopFragment - - ((Arg | Group)+)>
+<!--end of synopfragment.element-->]]>
+
+<!ENTITY % synopfragment.attlist "INCLUDE">
+<![ %synopfragment.attlist; [
+<!ATTLIST SynopFragment
+ %idreq.common.attrib;
+ %synopfragment.role.attrib;
+ %local.synopfragment.attrib;
+>
+<!--end of synopfragment.attlist-->]]>
+<!--end of synopfragment.module-->]]>
+
+<!-- Command (defined in the Inlines section, below)-->
+<!-- Option (defined in the Inlines section, below)-->
+<!-- Replaceable (defined in the Inlines section, below)-->
+<!--end of cmdsynopsis.content.module-->]]>
+
+<!-- FuncSynopsis ..................... -->
+
+<!ENTITY % funcsynopsis.content.module "INCLUDE">
+<![ %funcsynopsis.content.module; [
+<!ENTITY % funcsynopsis.module "INCLUDE">
+<![ %funcsynopsis.module; [
+
+<!ENTITY % local.funcsynopsis.attrib "">
+<!ENTITY % funcsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % funcsynopsis.element "INCLUDE">
+<![ %funcsynopsis.element; [
+<!ELEMENT FuncSynopsis - - (FuncSynopsisInfo|FuncPrototype)+>
+<!--end of funcsynopsis.element-->]]>
+
+<!ENTITY % funcsynopsis.attlist "INCLUDE">
+<![ %funcsynopsis.attlist; [
+<!ATTLIST FuncSynopsis
+ %label.attrib;
+ %common.attrib;
+ %funcsynopsis.role.attrib;
+ %local.funcsynopsis.attrib;
+>
+<!--end of funcsynopsis.attlist-->]]>
+<!--end of funcsynopsis.module-->]]>
+
+<!ENTITY % funcsynopsisinfo.module "INCLUDE">
+<![ %funcsynopsisinfo.module; [
+<!ENTITY % local.funcsynopsisinfo.attrib "">
+<!ENTITY % funcsynopsisinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % funcsynopsisinfo.element "INCLUDE">
+<![ %funcsynopsisinfo.element; [
+<!ELEMENT FuncSynopsisInfo - O ((LineAnnotation | %cptr.char.mix;)* )>
+<!--end of funcsynopsisinfo.element-->]]>
+
+<!ENTITY % funcsynopsisinfo.attlist "INCLUDE">
+<![ %funcsynopsisinfo.attlist; [
+<!ATTLIST FuncSynopsisInfo
+ %linespecific.attrib;
+ %common.attrib;
+ %funcsynopsisinfo.role.attrib;
+ %local.funcsynopsisinfo.attrib;
+>
+<!--end of funcsynopsisinfo.attlist-->]]>
+<!--end of funcsynopsisinfo.module-->]]>
+
+<!ENTITY % funcprototype.module "INCLUDE">
+<![ %funcprototype.module; [
+<!ENTITY % local.funcprototype.attrib "">
+<!ENTITY % funcprototype.role.attrib "%role.attrib;">
+
+<!ENTITY % funcprototype.element "INCLUDE">
+<![ %funcprototype.element; [
+<!ELEMENT FuncPrototype - O (FuncDef, (Void | VarArgs | ParamDef+))>
+<!--end of funcprototype.element-->]]>
+
+<!ENTITY % funcprototype.attlist "INCLUDE">
+<![ %funcprototype.attlist; [
+<!ATTLIST FuncPrototype
+ %common.attrib;
+ %funcprototype.role.attrib;
+ %local.funcprototype.attrib;
+>
+<!--end of funcprototype.attlist-->]]>
+<!--end of funcprototype.module-->]]>
+
+<!ENTITY % funcdef.module "INCLUDE">
+<![ %funcdef.module; [
+<!ENTITY % local.funcdef.attrib "">
+<!ENTITY % funcdef.role.attrib "%role.attrib;">
+
+<!ENTITY % funcdef.element "INCLUDE">
+<![ %funcdef.element; [
+<!ELEMENT FuncDef - - ((#PCDATA
+ | Replaceable
+ | Function)*)>
+<!--end of funcdef.element-->]]>
+
+<!ENTITY % funcdef.attlist "INCLUDE">
+<![ %funcdef.attlist; [
+<!ATTLIST FuncDef
+ %common.attrib;
+ %funcdef.role.attrib;
+ %local.funcdef.attrib;
+>
+<!--end of funcdef.attlist-->]]>
+<!--end of funcdef.module-->]]>
+
+<!ENTITY % void.module "INCLUDE">
+<![ %void.module; [
+<!ENTITY % local.void.attrib "">
+<!ENTITY % void.role.attrib "%role.attrib;">
+
+<!ENTITY % void.element "INCLUDE">
+<![ %void.element; [
+<!ELEMENT Void - O EMPTY>
+<!--end of void.element-->]]>
+
+<!ENTITY % void.attlist "INCLUDE">
+<![ %void.attlist; [
+<!ATTLIST Void
+ %common.attrib;
+ %void.role.attrib;
+ %local.void.attrib;
+>
+<!--end of void.attlist-->]]>
+<!--end of void.module-->]]>
+
+<!ENTITY % varargs.module "INCLUDE">
+<![ %varargs.module; [
+<!ENTITY % local.varargs.attrib "">
+<!ENTITY % varargs.role.attrib "%role.attrib;">
+
+<!ENTITY % varargs.element "INCLUDE">
+<![ %varargs.element; [
+<!ELEMENT VarArgs - O EMPTY>
+<!--end of varargs.element-->]]>
+
+<!ENTITY % varargs.attlist "INCLUDE">
+<![ %varargs.attlist; [
+<!ATTLIST VarArgs
+ %common.attrib;
+ %varargs.role.attrib;
+ %local.varargs.attrib;
+>
+<!--end of varargs.attlist-->]]>
+<!--end of varargs.module-->]]>
+
+<!-- Processing assumes that only one Parameter will appear in a
+ ParamDef, and that FuncParams will be used at most once, for
+ providing information on the "inner parameters" for parameters that
+ are pointers to functions. -->
+
+<!ENTITY % paramdef.module "INCLUDE">
+<![ %paramdef.module; [
+<!ENTITY % local.paramdef.attrib "">
+<!ENTITY % paramdef.role.attrib "%role.attrib;">
+
+<!ENTITY % paramdef.element "INCLUDE">
+<![ %paramdef.element; [
+<!ELEMENT ParamDef - - ((#PCDATA
+ | Replaceable
+ | Parameter
+ | FuncParams)*)>
+<!--end of paramdef.element-->]]>
+
+<!ENTITY % paramdef.attlist "INCLUDE">
+<![ %paramdef.attlist; [
+<!ATTLIST ParamDef
+ %common.attrib;
+ %paramdef.role.attrib;
+ %local.paramdef.attrib;
+>
+<!--end of paramdef.attlist-->]]>
+<!--end of paramdef.module-->]]>
+
+<!ENTITY % funcparams.module "INCLUDE">
+<![ %funcparams.module; [
+<!ENTITY % local.funcparams.attrib "">
+<!ENTITY % funcparams.role.attrib "%role.attrib;">
+
+<!ENTITY % funcparams.element "INCLUDE">
+<![ %funcparams.element; [
+<!ELEMENT FuncParams - - ((%cptr.char.mix;)*)>
+<!--end of funcparams.element-->]]>
+
+<!ENTITY % funcparams.attlist "INCLUDE">
+<![ %funcparams.attlist; [
+<!ATTLIST FuncParams
+ %common.attrib;
+ %funcparams.role.attrib;
+ %local.funcparams.attrib;
+>
+<!--end of funcparams.attlist-->]]>
+<!--end of funcparams.module-->]]>
+
+<!-- LineAnnotation (defined in the Inlines section, below)-->
+<!-- Replaceable (defined in the Inlines section, below)-->
+<!-- Function (defined in the Inlines section, below)-->
+<!-- Parameter (defined in the Inlines section, below)-->
+<!--end of funcsynopsis.content.module-->]]>
+
+<!-- ClassSynopsis ..................... -->
+
+<!ENTITY % classsynopsis.content.module "INCLUDE">
+<![%classsynopsis.content.module;[
+
+<!ENTITY % classsynopsis.module "INCLUDE">
+<![%classsynopsis.module;[
+<!ENTITY % local.classsynopsis.attrib "">
+<!ENTITY % classsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % classsynopsis.element "INCLUDE">
+<![%classsynopsis.element;[
+<!ELEMENT ClassSynopsis - - ((OOClass|OOInterface|OOException)+,
+ (ClassSynopsisInfo
+ |FieldSynopsis|%method.synop.class;)*)>
+<!--end of classsynopsis.element-->]]>
+
+<!ENTITY % classsynopsis.attlist "INCLUDE">
+<![%classsynopsis.attlist;[
+<!ATTLIST ClassSynopsis
+ %common.attrib;
+ %classsynopsis.role.attrib;
+ %local.classsynopsis.attrib;
+ Language CDATA #IMPLIED
+ Class (Class|Interface) "Class"
+>
+<!--end of classsynopsis.attlist-->]]>
+<!--end of classsynopsis.module-->]]>
+
+<!ENTITY % classsynopsisinfo.module "INCLUDE">
+<![ %classsynopsisinfo.module; [
+<!ENTITY % local.classsynopsisinfo.attrib "">
+<!ENTITY % classsynopsisinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % classsynopsisinfo.element "INCLUDE">
+<![ %classsynopsisinfo.element; [
+<!ELEMENT ClassSynopsisInfo - O ((LineAnnotation | %cptr.char.mix;)* )>
+<!--end of classsynopsisinfo.element-->]]>
+
+<!ENTITY % classsynopsisinfo.attlist "INCLUDE">
+<![ %classsynopsisinfo.attlist; [
+<!ATTLIST ClassSynopsisInfo
+ %linespecific.attrib;
+ %common.attrib;
+ %classsynopsisinfo.role.attrib;
+ %local.classsynopsisinfo.attrib;
+>
+<!--end of classsynopsisinfo.attlist-->]]>
+<!--end of classsynopsisinfo.module-->]]>
+
+<!ENTITY % ooclass.module "INCLUDE">
+<![%ooclass.module;[
+<!ENTITY % local.ooclass.attrib "">
+<!ENTITY % ooclass.role.attrib "%role.attrib;">
+
+<!ENTITY % ooclass.element "INCLUDE">
+<![%ooclass.element;[
+<!ELEMENT OOClass - - (Modifier*, ClassName)>
+<!--end of ooclass.element-->]]>
+
+<!ENTITY % ooclass.attlist "INCLUDE">
+<![%ooclass.attlist;[
+<!ATTLIST OOClass
+ %common.attrib;
+ %ooclass.role.attrib;
+ %local.ooclass.attrib;
+>
+<!--end of ooclass.attlist-->]]>
+<!--end of ooclass.module-->]]>
+
+<!ENTITY % oointerface.module "INCLUDE">
+<![%oointerface.module;[
+<!ENTITY % local.oointerface.attrib "">
+<!ENTITY % oointerface.role.attrib "%role.attrib;">
+
+<!ENTITY % oointerface.element "INCLUDE">
+<![%oointerface.element;[
+<!ELEMENT OOInterface - - (Modifier*, InterfaceName)>
+<!--end of oointerface.element-->]]>
+
+<!ENTITY % oointerface.attlist "INCLUDE">
+<![%oointerface.attlist;[
+<!ATTLIST OOInterface
+ %common.attrib;
+ %oointerface.role.attrib;
+ %local.oointerface.attrib;
+>
+<!--end of oointerface.attlist-->]]>
+<!--end of oointerface.module-->]]>
+
+<!ENTITY % ooexception.module "INCLUDE">
+<![%ooexception.module;[
+<!ENTITY % local.ooexception.attrib "">
+<!ENTITY % ooexception.role.attrib "%role.attrib;">
+
+<!ENTITY % ooexception.element "INCLUDE">
+<![%ooexception.element;[
+<!ELEMENT OOException - - (Modifier*, ExceptionName)>
+<!--end of ooexception.element-->]]>
+
+<!ENTITY % ooexception.attlist "INCLUDE">
+<![%ooexception.attlist;[
+<!ATTLIST OOException
+ %common.attrib;
+ %ooexception.role.attrib;
+ %local.ooexception.attrib;
+>
+<!--end of ooexception.attlist-->]]>
+<!--end of ooexception.module-->]]>
+
+<!ENTITY % modifier.module "INCLUDE">
+<![%modifier.module;[
+<!ENTITY % local.modifier.attrib "">
+<!ENTITY % modifier.role.attrib "%role.attrib;">
+
+<!ENTITY % modifier.element "INCLUDE">
+<![%modifier.element;[
+<!ELEMENT Modifier - - (%smallcptr.char.mix;)*>
+<!--end of modifier.element-->]]>
+
+<!ENTITY % modifier.attlist "INCLUDE">
+<![%modifier.attlist;[
+<!ATTLIST Modifier
+ %common.attrib;
+ %modifier.role.attrib;
+ %local.modifier.attrib;
+>
+<!--end of modifier.attlist-->]]>
+<!--end of modifier.module-->]]>
+
+<!ENTITY % interfacename.module "INCLUDE">
+<![%interfacename.module;[
+<!ENTITY % local.interfacename.attrib "">
+<!ENTITY % interfacename.role.attrib "%role.attrib;">
+
+<!ENTITY % interfacename.element "INCLUDE">
+<![%interfacename.element;[
+<!ELEMENT InterfaceName - - (%smallcptr.char.mix;)*>
+<!--end of interfacename.element-->]]>
+
+<!ENTITY % interfacename.attlist "INCLUDE">
+<![%interfacename.attlist;[
+<!ATTLIST InterfaceName
+ %common.attrib;
+ %interfacename.role.attrib;
+ %local.interfacename.attrib;
+>
+<!--end of interfacename.attlist-->]]>
+<!--end of interfacename.module-->]]>
+
+<!ENTITY % exceptionname.module "INCLUDE">
+<![%exceptionname.module;[
+<!ENTITY % local.exceptionname.attrib "">
+<!ENTITY % exceptionname.role.attrib "%role.attrib;">
+
+<!ENTITY % exceptionname.element "INCLUDE">
+<![%exceptionname.element;[
+<!ELEMENT ExceptionName - - (%smallcptr.char.mix;)*>
+<!--end of exceptionname.element-->]]>
+
+<!ENTITY % exceptionname.attlist "INCLUDE">
+<![%exceptionname.attlist;[
+<!ATTLIST ExceptionName
+ %common.attrib;
+ %exceptionname.role.attrib;
+ %local.exceptionname.attrib;
+>
+<!--end of exceptionname.attlist-->]]>
+<!--end of exceptionname.module-->]]>
+
+<!ENTITY % fieldsynopsis.module "INCLUDE">
+<![%fieldsynopsis.module;[
+<!ENTITY % local.fieldsynopsis.attrib "">
+<!ENTITY % fieldsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % fieldsynopsis.element "INCLUDE">
+<![%fieldsynopsis.element;[
+<!ELEMENT FieldSynopsis - - (Modifier*, Type?, VarName, Initializer?)>
+<!--end of fieldsynopsis.element-->]]>
+
+<!ENTITY % fieldsynopsis.attlist "INCLUDE">
+<![%fieldsynopsis.attlist;[
+<!ATTLIST FieldSynopsis
+ %common.attrib;
+ %fieldsynopsis.role.attrib;
+ %local.fieldsynopsis.attrib;
+>
+<!--end of fieldsynopsis.attlist-->]]>
+<!--end of fieldsynopsis.module-->]]>
+
+<!ENTITY % initializer.module "INCLUDE">
+<![%initializer.module;[
+<!ENTITY % local.initializer.attrib "">
+<!ENTITY % initializer.role.attrib "%role.attrib;">
+
+<!ENTITY % initializer.element "INCLUDE">
+<![%initializer.element;[
+<!ELEMENT Initializer - - (%smallcptr.char.mix;)*>
+<!--end of initializer.element-->]]>
+
+<!ENTITY % initializer.attlist "INCLUDE">
+<![%initializer.attlist;[
+<!ATTLIST Initializer
+ %common.attrib;
+ %initializer.role.attrib;
+ %local.initializer.attrib;
+>
+<!--end of initializer.attlist-->]]>
+<!--end of initializer.module-->]]>
+
+<!ENTITY % constructorsynopsis.module "INCLUDE">
+<![%constructorsynopsis.module;[
+<!ENTITY % local.constructorsynopsis.attrib "">
+<!ENTITY % constructorsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % constructorsynopsis.element "INCLUDE">
+<![%constructorsynopsis.element;[
+<!ELEMENT ConstructorSynopsis - - (Modifier*,
+ MethodName?,
+ (MethodParam+|Void),
+ ExceptionName*)>
+<!--end of constructorsynopsis.element-->]]>
+
+<!ENTITY % constructorsynopsis.attlist "INCLUDE">
+<![%constructorsynopsis.attlist;[
+<!ATTLIST ConstructorSynopsis
+ %common.attrib;
+ %constructorsynopsis.role.attrib;
+ %local.constructorsynopsis.attrib;
+>
+<!--end of constructorsynopsis.attlist-->]]>
+<!--end of constructorsynopsis.module-->]]>
+
+<!ENTITY % destructorsynopsis.module "INCLUDE">
+<![%destructorsynopsis.module;[
+<!ENTITY % local.destructorsynopsis.attrib "">
+<!ENTITY % destructorsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % destructorsynopsis.element "INCLUDE">
+<![%destructorsynopsis.element;[
+<!ELEMENT DestructorSynopsis - - (Modifier*,
+ MethodName?,
+ (MethodParam+|Void),
+ ExceptionName*)>
+<!--end of destructorsynopsis.element-->]]>
+
+<!ENTITY % destructorsynopsis.attlist "INCLUDE">
+<![%destructorsynopsis.attlist;[
+<!ATTLIST DestructorSynopsis
+ %common.attrib;
+ %destructorsynopsis.role.attrib;
+ %local.destructorsynopsis.attrib;
+>
+<!--end of destructorsynopsis.attlist-->]]>
+<!--end of destructorsynopsis.module-->]]>
+
+<!ENTITY % methodsynopsis.module "INCLUDE">
+<![%methodsynopsis.module;[
+<!ENTITY % local.methodsynopsis.attrib "">
+<!ENTITY % methodsynopsis.role.attrib "%role.attrib;">
+
+<!ENTITY % methodsynopsis.element "INCLUDE">
+<![%methodsynopsis.element;[
+<!ELEMENT MethodSynopsis - - (Modifier*,
+ (Type|Void)?,
+ MethodName,
+ (MethodParam+|Void),
+ ExceptionName*,
+ Modifier*)>
+<!--end of methodsynopsis.element-->]]>
+
+<!ENTITY % methodsynopsis.attlist "INCLUDE">
+<![%methodsynopsis.attlist;[
+<!ATTLIST MethodSynopsis
+ %common.attrib;
+ %methodsynopsis.role.attrib;
+ %local.methodsynopsis.attrib;
+>
+<!--end of methodsynopsis.attlist-->]]>
+<!--end of methodsynopsis.module-->]]>
+
+<!ENTITY % methodname.module "INCLUDE">
+<![%methodname.module;[
+<!ENTITY % local.methodname.attrib "">
+<!ENTITY % methodname.role.attrib "%role.attrib;">
+
+<!ENTITY % methodname.element "INCLUDE">
+<![%methodname.element;[
+<!ELEMENT MethodName - - (%smallcptr.char.mix;)*>
+<!--end of methodname.element-->]]>
+
+<!ENTITY % methodname.attlist "INCLUDE">
+<![%methodname.attlist;[
+<!ATTLIST MethodName
+ %common.attrib;
+ %methodname.role.attrib;
+ %local.methodname.attrib;
+>
+<!--end of methodname.attlist-->]]>
+<!--end of methodname.module-->]]>
+
+<!ENTITY % methodparam.module "INCLUDE">
+<![%methodparam.module;[
+<!ENTITY % local.methodparam.attrib "">
+<!ENTITY % methodparam.role.attrib "%role.attrib;">
+
+<!ENTITY % methodparam.element "INCLUDE">
+<![%methodparam.element;[
+<!ELEMENT MethodParam - - (Modifier*,
+ Type?, ((Parameter,Initializer?)|FuncParams),
+ Modifier*)>
+<!--end of methodparam.element-->]]>
+
+<!ENTITY % methodparam.attlist "INCLUDE">
+<![%methodparam.attlist;[
+<!ATTLIST MethodParam
+ %common.attrib;
+ %methodparam.role.attrib;
+ %local.methodparam.attrib;
+ Choice (Opt
+ |Req
+ |Plain) "Req"
+ Rep (Norepeat
+ |Repeat) "Norepeat"
+>
+<!--end of methodparam.attlist-->]]>
+<!--end of methodparam.module-->]]>
+<!--end of classsynopsis.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Document information entities and elements ........................... -->
+
+<!-- The document information elements include some elements that are
+ currently used only in the document hierarchy module. They are
+ defined here so that they will be available for use in customized
+ document hierarchies. -->
+
+<!-- .................................. -->
+
+<!ENTITY % docinfo.content.module "INCLUDE">
+<![ %docinfo.content.module; [
+
+<!-- Ackno ............................ -->
+
+<!ENTITY % ackno.module "INCLUDE">
+<![ %ackno.module; [
+<!ENTITY % local.ackno.attrib "">
+<!ENTITY % ackno.role.attrib "%role.attrib;">
+
+<!ENTITY % ackno.element "INCLUDE">
+<![ %ackno.element; [
+<!ELEMENT Ackno - - ((%docinfo.char.mix;)+)>
+<!--end of ackno.element-->]]>
+
+<!ENTITY % ackno.attlist "INCLUDE">
+<![ %ackno.attlist; [
+<!ATTLIST Ackno
+ %common.attrib;
+ %ackno.role.attrib;
+ %local.ackno.attrib;
+>
+<!--end of ackno.attlist-->]]>
+<!--end of ackno.module-->]]>
+
+<!-- Address .......................... -->
+
+<!ENTITY % address.content.module "INCLUDE">
+<![ %address.content.module; [
+<!ENTITY % address.module "INCLUDE">
+<![ %address.module; [
+<!ENTITY % local.address.attrib "">
+<!ENTITY % address.role.attrib "%role.attrib;">
+
+<!ENTITY % address.element "INCLUDE">
+<![ %address.element; [
+<!ELEMENT Address - - (#PCDATA|%person.ident.mix;
+ |Street|POB|Postcode|City|State|Country|Phone
+ |Fax|Email|OtherAddr)*>
+<!--end of address.element-->]]>
+
+<!ENTITY % address.attlist "INCLUDE">
+<![ %address.attlist; [
+<!ATTLIST Address
+ %linespecific.attrib;
+ %common.attrib;
+ %address.role.attrib;
+ %local.address.attrib;
+>
+<!--end of address.attlist-->]]>
+<!--end of address.module-->]]>
+
+ <!ENTITY % street.module "INCLUDE">
+ <![ %street.module; [
+ <!ENTITY % local.street.attrib "">
+ <!ENTITY % street.role.attrib "%role.attrib;">
+
+<!ENTITY % street.element "INCLUDE">
+<![ %street.element; [
+<!ELEMENT Street - - ((%docinfo.char.mix;)+)>
+<!--end of street.element-->]]>
+
+<!ENTITY % street.attlist "INCLUDE">
+<![ %street.attlist; [
+<!ATTLIST Street
+ %common.attrib;
+ %street.role.attrib;
+ %local.street.attrib;
+>
+<!--end of street.attlist-->]]>
+ <!--end of street.module-->]]>
+
+ <!ENTITY % pob.module "INCLUDE">
+ <![ %pob.module; [
+ <!ENTITY % local.pob.attrib "">
+ <!ENTITY % pob.role.attrib "%role.attrib;">
+
+<!ENTITY % pob.element "INCLUDE">
+<![ %pob.element; [
+<!ELEMENT POB - - ((%docinfo.char.mix;)+)>
+<!--end of pob.element-->]]>
+
+<!ENTITY % pob.attlist "INCLUDE">
+<![ %pob.attlist; [
+<!ATTLIST POB
+ %common.attrib;
+ %pob.role.attrib;
+ %local.pob.attrib;
+>
+<!--end of pob.attlist-->]]>
+ <!--end of pob.module-->]]>
+
+ <!ENTITY % postcode.module "INCLUDE">
+ <![ %postcode.module; [
+ <!ENTITY % local.postcode.attrib "">
+ <!ENTITY % postcode.role.attrib "%role.attrib;">
+
+<!ENTITY % postcode.element "INCLUDE">
+<![ %postcode.element; [
+<!ELEMENT Postcode - - ((%docinfo.char.mix;)+)>
+<!--end of postcode.element-->]]>
+
+<!ENTITY % postcode.attlist "INCLUDE">
+<![ %postcode.attlist; [
+<!ATTLIST Postcode
+ %common.attrib;
+ %postcode.role.attrib;
+ %local.postcode.attrib;
+>
+<!--end of postcode.attlist-->]]>
+ <!--end of postcode.module-->]]>
+
+ <!ENTITY % city.module "INCLUDE">
+ <![ %city.module; [
+ <!ENTITY % local.city.attrib "">
+ <!ENTITY % city.role.attrib "%role.attrib;">
+
+<!ENTITY % city.element "INCLUDE">
+<![ %city.element; [
+<!ELEMENT City - - ((%docinfo.char.mix;)+)>
+<!--end of city.element-->]]>
+
+<!ENTITY % city.attlist "INCLUDE">
+<![ %city.attlist; [
+<!ATTLIST City
+ %common.attrib;
+ %city.role.attrib;
+ %local.city.attrib;
+>
+<!--end of city.attlist-->]]>
+ <!--end of city.module-->]]>
+
+ <!ENTITY % state.module "INCLUDE">
+ <![ %state.module; [
+ <!ENTITY % local.state.attrib "">
+ <!ENTITY % state.role.attrib "%role.attrib;">
+
+<!ENTITY % state.element "INCLUDE">
+<![ %state.element; [
+<!ELEMENT State - - ((%docinfo.char.mix;)+)>
+<!--end of state.element-->]]>
+
+<!ENTITY % state.attlist "INCLUDE">
+<![ %state.attlist; [
+<!ATTLIST State
+ %common.attrib;
+ %state.role.attrib;
+ %local.state.attrib;
+>
+<!--end of state.attlist-->]]>
+ <!--end of state.module-->]]>
+
+ <!ENTITY % country.module "INCLUDE">
+ <![ %country.module; [
+ <!ENTITY % local.country.attrib "">
+ <!ENTITY % country.role.attrib "%role.attrib;">
+
+<!ENTITY % country.element "INCLUDE">
+<![ %country.element; [
+<!ELEMENT Country - - ((%docinfo.char.mix;)+)>
+<!--end of country.element-->]]>
+
+<!ENTITY % country.attlist "INCLUDE">
+<![ %country.attlist; [
+<!ATTLIST Country
+ %common.attrib;
+ %country.role.attrib;
+ %local.country.attrib;
+>
+<!--end of country.attlist-->]]>
+ <!--end of country.module-->]]>
+
+ <!ENTITY % phone.module "INCLUDE">
+ <![ %phone.module; [
+ <!ENTITY % local.phone.attrib "">
+ <!ENTITY % phone.role.attrib "%role.attrib;">
+
+<!ENTITY % phone.element "INCLUDE">
+<![ %phone.element; [
+<!ELEMENT Phone - - ((%docinfo.char.mix;)+)>
+<!--end of phone.element-->]]>
+
+<!ENTITY % phone.attlist "INCLUDE">
+<![ %phone.attlist; [
+<!ATTLIST Phone
+ %common.attrib;
+ %phone.role.attrib;
+ %local.phone.attrib;
+>
+<!--end of phone.attlist-->]]>
+ <!--end of phone.module-->]]>
+
+ <!ENTITY % fax.module "INCLUDE">
+ <![ %fax.module; [
+ <!ENTITY % local.fax.attrib "">
+ <!ENTITY % fax.role.attrib "%role.attrib;">
+
+<!ENTITY % fax.element "INCLUDE">
+<![ %fax.element; [
+<!ELEMENT Fax - - ((%docinfo.char.mix;)+)>
+<!--end of fax.element-->]]>
+
+<!ENTITY % fax.attlist "INCLUDE">
+<![ %fax.attlist; [
+<!ATTLIST Fax
+ %common.attrib;
+ %fax.role.attrib;
+ %local.fax.attrib;
+>
+<!--end of fax.attlist-->]]>
+ <!--end of fax.module-->]]>
+
+ <!-- Email (defined in the Inlines section, below)-->
+
+ <!ENTITY % otheraddr.module "INCLUDE">
+ <![ %otheraddr.module; [
+ <!ENTITY % local.otheraddr.attrib "">
+ <!ENTITY % otheraddr.role.attrib "%role.attrib;">
+
+<!ENTITY % otheraddr.element "INCLUDE">
+<![ %otheraddr.element; [
+<!ELEMENT OtherAddr - - ((%docinfo.char.mix;)+)>
+<!--end of otheraddr.element-->]]>
+
+<!ENTITY % otheraddr.attlist "INCLUDE">
+<![ %otheraddr.attlist; [
+<!ATTLIST OtherAddr
+ %common.attrib;
+ %otheraddr.role.attrib;
+ %local.otheraddr.attrib;
+>
+<!--end of otheraddr.attlist-->]]>
+ <!--end of otheraddr.module-->]]>
+<!--end of address.content.module-->]]>
+
+<!-- Affiliation ...................... -->
+
+<!ENTITY % affiliation.content.module "INCLUDE">
+<![ %affiliation.content.module; [
+<!ENTITY % affiliation.module "INCLUDE">
+<![ %affiliation.module; [
+<!ENTITY % local.affiliation.attrib "">
+<!ENTITY % affiliation.role.attrib "%role.attrib;">
+
+<!ENTITY % affiliation.element "INCLUDE">
+<![ %affiliation.element; [
+<!ELEMENT Affiliation - - (ShortAffil?, JobTitle*, OrgName?, OrgDiv*,
+ Address*)>
+<!--end of affiliation.element-->]]>
+
+<!ENTITY % affiliation.attlist "INCLUDE">
+<![ %affiliation.attlist; [
+<!ATTLIST Affiliation
+ %common.attrib;
+ %affiliation.role.attrib;
+ %local.affiliation.attrib;
+>
+<!--end of affiliation.attlist-->]]>
+<!--end of affiliation.module-->]]>
+
+ <!ENTITY % shortaffil.module "INCLUDE">
+ <![ %shortaffil.module; [
+ <!ENTITY % local.shortaffil.attrib "">
+ <!ENTITY % shortaffil.role.attrib "%role.attrib;">
+
+<!ENTITY % shortaffil.element "INCLUDE">
+<![ %shortaffil.element; [
+<!ELEMENT ShortAffil - - ((%docinfo.char.mix;)+)>
+<!--end of shortaffil.element-->]]>
+
+<!ENTITY % shortaffil.attlist "INCLUDE">
+<![ %shortaffil.attlist; [
+<!ATTLIST ShortAffil
+ %common.attrib;
+ %shortaffil.role.attrib;
+ %local.shortaffil.attrib;
+>
+<!--end of shortaffil.attlist-->]]>
+ <!--end of shortaffil.module-->]]>
+
+ <!ENTITY % jobtitle.module "INCLUDE">
+ <![ %jobtitle.module; [
+ <!ENTITY % local.jobtitle.attrib "">
+ <!ENTITY % jobtitle.role.attrib "%role.attrib;">
+
+<!ENTITY % jobtitle.element "INCLUDE">
+<![ %jobtitle.element; [
+<!ELEMENT JobTitle - - ((%docinfo.char.mix;)+)>
+<!--end of jobtitle.element-->]]>
+
+<!ENTITY % jobtitle.attlist "INCLUDE">
+<![ %jobtitle.attlist; [
+<!ATTLIST JobTitle
+ %common.attrib;
+ %jobtitle.role.attrib;
+ %local.jobtitle.attrib;
+>
+<!--end of jobtitle.attlist-->]]>
+ <!--end of jobtitle.module-->]]>
+
+ <!-- OrgName (defined elsewhere in this section)-->
+
+ <!ENTITY % orgdiv.module "INCLUDE">
+ <![ %orgdiv.module; [
+ <!ENTITY % local.orgdiv.attrib "">
+ <!ENTITY % orgdiv.role.attrib "%role.attrib;">
+
+<!ENTITY % orgdiv.element "INCLUDE">
+<![ %orgdiv.element; [
+<!ELEMENT OrgDiv - - ((%docinfo.char.mix;)+)>
+<!--end of orgdiv.element-->]]>
+
+<!ENTITY % orgdiv.attlist "INCLUDE">
+<![ %orgdiv.attlist; [
+<!ATTLIST OrgDiv
+ %common.attrib;
+ %orgdiv.role.attrib;
+ %local.orgdiv.attrib;
+>
+<!--end of orgdiv.attlist-->]]>
+ <!--end of orgdiv.module-->]]>
+
+ <!-- Address (defined elsewhere in this section)-->
+<!--end of affiliation.content.module-->]]>
+
+<!-- ArtPageNums ...................... -->
+
+<!ENTITY % artpagenums.module "INCLUDE">
+<![ %artpagenums.module; [
+<!ENTITY % local.artpagenums.attrib "">
+<!ENTITY % argpagenums.role.attrib "%role.attrib;">
+
+<!ENTITY % artpagenums.element "INCLUDE">
+<![ %artpagenums.element; [
+<!ELEMENT ArtPageNums - - ((%docinfo.char.mix;)+)>
+<!--end of artpagenums.element-->]]>
+
+<!ENTITY % artpagenums.attlist "INCLUDE">
+<![ %artpagenums.attlist; [
+<!ATTLIST ArtPageNums
+ %common.attrib;
+ %argpagenums.role.attrib;
+ %local.artpagenums.attrib;
+>
+<!--end of artpagenums.attlist-->]]>
+<!--end of artpagenums.module-->]]>
+
+<!-- Author ........................... -->
+
+<!ENTITY % author.module "INCLUDE">
+<![ %author.module; [
+<!ENTITY % local.author.attrib "">
+<!ENTITY % author.role.attrib "%role.attrib;">
+
+<!ENTITY % author.element "INCLUDE">
+<![ %author.element; [
+<!ELEMENT Author - - ((%person.ident.mix;)+)>
+<!--end of author.element-->]]>
+
+<!ENTITY % author.attlist "INCLUDE">
+<![ %author.attlist; [
+<!ATTLIST Author
+ %common.attrib;
+ %author.role.attrib;
+ %local.author.attrib;
+>
+<!--end of author.attlist-->]]>
+<!--(see "Personal identity elements" for %person.ident.mix;)-->
+<!--end of author.module-->]]>
+
+<!-- AuthorGroup ...................... -->
+
+<!ENTITY % authorgroup.content.module "INCLUDE">
+<![ %authorgroup.content.module; [
+<!ENTITY % authorgroup.module "INCLUDE">
+<![ %authorgroup.module; [
+<!ENTITY % local.authorgroup.attrib "">
+<!ENTITY % authorgroup.role.attrib "%role.attrib;">
+
+<!ENTITY % authorgroup.element "INCLUDE">
+<![ %authorgroup.element; [
+<!ELEMENT AuthorGroup - - ((Author|Editor|Collab|CorpAuthor|OtherCredit)+)>
+<!--end of authorgroup.element-->]]>
+
+<!ENTITY % authorgroup.attlist "INCLUDE">
+<![ %authorgroup.attlist; [
+<!ATTLIST AuthorGroup
+ %common.attrib;
+ %authorgroup.role.attrib;
+ %local.authorgroup.attrib;
+>
+<!--end of authorgroup.attlist-->]]>
+<!--end of authorgroup.module-->]]>
+
+ <!-- Author (defined elsewhere in this section)-->
+ <!-- Editor (defined elsewhere in this section)-->
+
+ <!ENTITY % collab.content.module "INCLUDE">
+ <![ %collab.content.module; [
+ <!ENTITY % collab.module "INCLUDE">
+ <![ %collab.module; [
+ <!ENTITY % local.collab.attrib "">
+ <!ENTITY % collab.role.attrib "%role.attrib;">
+
+<!ENTITY % collab.element "INCLUDE">
+<![ %collab.element; [
+<!ELEMENT Collab - - (CollabName, Affiliation*)>
+<!--end of collab.element-->]]>
+
+<!ENTITY % collab.attlist "INCLUDE">
+<![ %collab.attlist; [
+<!ATTLIST Collab
+ %common.attrib;
+ %collab.role.attrib;
+ %local.collab.attrib;
+>
+<!--end of collab.attlist-->]]>
+ <!--end of collab.module-->]]>
+
+ <!ENTITY % collabname.module "INCLUDE">
+ <![ %collabname.module; [
+ <!ENTITY % local.collabname.attrib "">
+ <!ENTITY % collabname.role.attrib "%role.attrib;">
+
+<!ENTITY % collabname.element "INCLUDE">
+<![ %collabname.element; [
+<!ELEMENT CollabName - - ((%docinfo.char.mix;)+)>
+<!--end of collabname.element-->]]>
+
+<!ENTITY % collabname.attlist "INCLUDE">
+<![ %collabname.attlist; [
+<!ATTLIST CollabName
+ %common.attrib;
+ %collabname.role.attrib;
+ %local.collabname.attrib;
+>
+<!--end of collabname.attlist-->]]>
+ <!--end of collabname.module-->]]>
+
+ <!-- Affiliation (defined elsewhere in this section)-->
+ <!--end of collab.content.module-->]]>
+
+ <!-- CorpAuthor (defined elsewhere in this section)-->
+ <!-- OtherCredit (defined elsewhere in this section)-->
+
+<!--end of authorgroup.content.module-->]]>
+
+<!-- AuthorInitials ................... -->
+
+<!ENTITY % authorinitials.module "INCLUDE">
+<![ %authorinitials.module; [
+<!ENTITY % local.authorinitials.attrib "">
+<!ENTITY % authorinitials.role.attrib "%role.attrib;">
+
+<!ENTITY % authorinitials.element "INCLUDE">
+<![ %authorinitials.element; [
+<!ELEMENT AuthorInitials - - ((%docinfo.char.mix;)+)>
+<!--end of authorinitials.element-->]]>
+
+<!ENTITY % authorinitials.attlist "INCLUDE">
+<![ %authorinitials.attlist; [
+<!ATTLIST AuthorInitials
+ %common.attrib;
+ %authorinitials.role.attrib;
+ %local.authorinitials.attrib;
+>
+<!--end of authorinitials.attlist-->]]>
+<!--end of authorinitials.module-->]]>
+
+<!-- ConfGroup ........................ -->
+
+<!ENTITY % confgroup.content.module "INCLUDE">
+<![ %confgroup.content.module; [
+<!ENTITY % confgroup.module "INCLUDE">
+<![ %confgroup.module; [
+<!ENTITY % local.confgroup.attrib "">
+<!ENTITY % confgroup.role.attrib "%role.attrib;">
+
+<!ENTITY % confgroup.element "INCLUDE">
+<![ %confgroup.element; [
+<!ELEMENT ConfGroup - - ((ConfDates|ConfTitle|ConfNum|Address|ConfSponsor)*)>
+<!--end of confgroup.element-->]]>
+
+<!ENTITY % confgroup.attlist "INCLUDE">
+<![ %confgroup.attlist; [
+<!ATTLIST ConfGroup
+ %common.attrib;
+ %confgroup.role.attrib;
+ %local.confgroup.attrib;
+>
+<!--end of confgroup.attlist-->]]>
+<!--end of confgroup.module-->]]>
+
+ <!ENTITY % confdates.module "INCLUDE">
+ <![ %confdates.module; [
+ <!ENTITY % local.confdates.attrib "">
+ <!ENTITY % confdates.role.attrib "%role.attrib;">
+
+<!ENTITY % confdates.element "INCLUDE">
+<![ %confdates.element; [
+<!ELEMENT ConfDates - - ((%docinfo.char.mix;)+)>
+<!--end of confdates.element-->]]>
+
+<!ENTITY % confdates.attlist "INCLUDE">
+<![ %confdates.attlist; [
+<!ATTLIST ConfDates
+ %common.attrib;
+ %confdates.role.attrib;
+ %local.confdates.attrib;
+>
+<!--end of confdates.attlist-->]]>
+ <!--end of confdates.module-->]]>
+
+ <!ENTITY % conftitle.module "INCLUDE">
+ <![ %conftitle.module; [
+ <!ENTITY % local.conftitle.attrib "">
+ <!ENTITY % conftitle.role.attrib "%role.attrib;">
+
+<!ENTITY % conftitle.element "INCLUDE">
+<![ %conftitle.element; [
+<!ELEMENT ConfTitle - - ((%docinfo.char.mix;)+)>
+<!--end of conftitle.element-->]]>
+
+<!ENTITY % conftitle.attlist "INCLUDE">
+<![ %conftitle.attlist; [
+<!ATTLIST ConfTitle
+ %common.attrib;
+ %conftitle.role.attrib;
+ %local.conftitle.attrib;
+>
+<!--end of conftitle.attlist-->]]>
+ <!--end of conftitle.module-->]]>
+
+ <!ENTITY % confnum.module "INCLUDE">
+ <![ %confnum.module; [
+ <!ENTITY % local.confnum.attrib "">
+ <!ENTITY % confnum.role.attrib "%role.attrib;">
+
+<!ENTITY % confnum.element "INCLUDE">
+<![ %confnum.element; [
+<!ELEMENT ConfNum - - ((%docinfo.char.mix;)+)>
+<!--end of confnum.element-->]]>
+
+<!ENTITY % confnum.attlist "INCLUDE">
+<![ %confnum.attlist; [
+<!ATTLIST ConfNum
+ %common.attrib;
+ %confnum.role.attrib;
+ %local.confnum.attrib;
+>
+<!--end of confnum.attlist-->]]>
+ <!--end of confnum.module-->]]>
+
+ <!-- Address (defined elsewhere in this section)-->
+
+ <!ENTITY % confsponsor.module "INCLUDE">
+ <![ %confsponsor.module; [
+ <!ENTITY % local.confsponsor.attrib "">
+ <!ENTITY % confsponsor.role.attrib "%role.attrib;">
+
+<!ENTITY % confsponsor.element "INCLUDE">
+<![ %confsponsor.element; [
+<!ELEMENT ConfSponsor - - ((%docinfo.char.mix;)+)>
+<!--end of confsponsor.element-->]]>
+
+<!ENTITY % confsponsor.attlist "INCLUDE">
+<![ %confsponsor.attlist; [
+<!ATTLIST ConfSponsor
+ %common.attrib;
+ %confsponsor.role.attrib;
+ %local.confsponsor.attrib;
+>
+<!--end of confsponsor.attlist-->]]>
+ <!--end of confsponsor.module-->]]>
+<!--end of confgroup.content.module-->]]>
+
+<!-- ContractNum ...................... -->
+
+<!ENTITY % contractnum.module "INCLUDE">
+<![ %contractnum.module; [
+<!ENTITY % local.contractnum.attrib "">
+<!ENTITY % contractnum.role.attrib "%role.attrib;">
+
+<!ENTITY % contractnum.element "INCLUDE">
+<![ %contractnum.element; [
+<!ELEMENT ContractNum - - ((%docinfo.char.mix;)+)>
+<!--end of contractnum.element-->]]>
+
+<!ENTITY % contractnum.attlist "INCLUDE">
+<![ %contractnum.attlist; [
+<!ATTLIST ContractNum
+ %common.attrib;
+ %contractnum.role.attrib;
+ %local.contractnum.attrib;
+>
+<!--end of contractnum.attlist-->]]>
+<!--end of contractnum.module-->]]>
+
+<!-- ContractSponsor .................. -->
+
+<!ENTITY % contractsponsor.module "INCLUDE">
+<![ %contractsponsor.module; [
+<!ENTITY % local.contractsponsor.attrib "">
+<!ENTITY % contractsponsor.role.attrib "%role.attrib;">
+
+<!ENTITY % contractsponsor.element "INCLUDE">
+<![ %contractsponsor.element; [
+<!ELEMENT ContractSponsor - - ((%docinfo.char.mix;)+)>
+<!--end of contractsponsor.element-->]]>
+
+<!ENTITY % contractsponsor.attlist "INCLUDE">
+<![ %contractsponsor.attlist; [
+<!ATTLIST ContractSponsor
+ %common.attrib;
+ %contractsponsor.role.attrib;
+ %local.contractsponsor.attrib;
+>
+<!--end of contractsponsor.attlist-->]]>
+<!--end of contractsponsor.module-->]]>
+
+<!-- Copyright ........................ -->
+
+<!ENTITY % copyright.content.module "INCLUDE">
+<![ %copyright.content.module; [
+<!ENTITY % copyright.module "INCLUDE">
+<![ %copyright.module; [
+<!ENTITY % local.copyright.attrib "">
+<!ENTITY % copyright.role.attrib "%role.attrib;">
+
+<!ENTITY % copyright.element "INCLUDE">
+<![ %copyright.element; [
+<!ELEMENT Copyright - - (Year+, Holder*)>
+<!--end of copyright.element-->]]>
+
+<!ENTITY % copyright.attlist "INCLUDE">
+<![ %copyright.attlist; [
+<!ATTLIST Copyright
+ %common.attrib;
+ %copyright.role.attrib;
+ %local.copyright.attrib;
+>
+<!--end of copyright.attlist-->]]>
+<!--end of copyright.module-->]]>
+
+ <!ENTITY % year.module "INCLUDE">
+ <![ %year.module; [
+ <!ENTITY % local.year.attrib "">
+ <!ENTITY % year.role.attrib "%role.attrib;">
+
+<!ENTITY % year.element "INCLUDE">
+<![ %year.element; [
+<!ELEMENT Year - - ((%docinfo.char.mix;)+)>
+<!--end of year.element-->]]>
+
+<!ENTITY % year.attlist "INCLUDE">
+<![ %year.attlist; [
+<!ATTLIST Year
+ %common.attrib;
+ %year.role.attrib;
+ %local.year.attrib;
+>
+<!--end of year.attlist-->]]>
+ <!--end of year.module-->]]>
+
+ <!ENTITY % holder.module "INCLUDE">
+ <![ %holder.module; [
+ <!ENTITY % local.holder.attrib "">
+ <!ENTITY % holder.role.attrib "%role.attrib;">
+
+<!ENTITY % holder.element "INCLUDE">
+<![ %holder.element; [
+<!ELEMENT Holder - - ((%docinfo.char.mix;)+)>
+<!--end of holder.element-->]]>
+
+<!ENTITY % holder.attlist "INCLUDE">
+<![ %holder.attlist; [
+<!ATTLIST Holder
+ %common.attrib;
+ %holder.role.attrib;
+ %local.holder.attrib;
+>
+<!--end of holder.attlist-->]]>
+ <!--end of holder.module-->]]>
+<!--end of copyright.content.module-->]]>
+
+<!-- CorpAuthor ....................... -->
+
+<!ENTITY % corpauthor.module "INCLUDE">
+<![ %corpauthor.module; [
+<!ENTITY % local.corpauthor.attrib "">
+<!ENTITY % corpauthor.role.attrib "%role.attrib;">
+
+<!ENTITY % corpauthor.element "INCLUDE">
+<![ %corpauthor.element; [
+<!ELEMENT CorpAuthor - - ((%docinfo.char.mix;)+)>
+<!--end of corpauthor.element-->]]>
+
+<!ENTITY % corpauthor.attlist "INCLUDE">
+<![ %corpauthor.attlist; [
+<!ATTLIST CorpAuthor
+ %common.attrib;
+ %corpauthor.role.attrib;
+ %local.corpauthor.attrib;
+>
+<!--end of corpauthor.attlist-->]]>
+<!--end of corpauthor.module-->]]>
+
+<!-- CorpName ......................... -->
+
+<!ENTITY % corpname.module "INCLUDE">
+<![ %corpname.module; [
+<!ENTITY % local.corpname.attrib "">
+
+<!ENTITY % corpname.element "INCLUDE">
+<![ %corpname.element; [
+<!ELEMENT CorpName - - ((%docinfo.char.mix;)+)>
+<!--end of corpname.element-->]]>
+<!ENTITY % corpname.role.attrib "%role.attrib;">
+
+<!ENTITY % corpname.attlist "INCLUDE">
+<![ %corpname.attlist; [
+<!ATTLIST CorpName
+ %common.attrib;
+ %corpname.role.attrib;
+ %local.corpname.attrib;
+>
+<!--end of corpname.attlist-->]]>
+<!--end of corpname.module-->]]>
+
+<!-- Date ............................. -->
+
+<!ENTITY % date.module "INCLUDE">
+<![ %date.module; [
+<!ENTITY % local.date.attrib "">
+<!ENTITY % date.role.attrib "%role.attrib;">
+
+<!ENTITY % date.element "INCLUDE">
+<![ %date.element; [
+<!ELEMENT Date - - ((%docinfo.char.mix;)+)>
+<!--end of date.element-->]]>
+
+<!ENTITY % date.attlist "INCLUDE">
+<![ %date.attlist; [
+<!ATTLIST Date
+ %common.attrib;
+ %date.role.attrib;
+ %local.date.attrib;
+>
+<!--end of date.attlist-->]]>
+<!--end of date.module-->]]>
+
+<!-- Edition .......................... -->
+
+<!ENTITY % edition.module "INCLUDE">
+<![ %edition.module; [
+<!ENTITY % local.edition.attrib "">
+<!ENTITY % edition.role.attrib "%role.attrib;">
+
+<!ENTITY % edition.element "INCLUDE">
+<![ %edition.element; [
+<!ELEMENT Edition - - ((%docinfo.char.mix;)+)>
+<!--end of edition.element-->]]>
+
+<!ENTITY % edition.attlist "INCLUDE">
+<![ %edition.attlist; [
+<!ATTLIST Edition
+ %common.attrib;
+ %edition.role.attrib;
+ %local.edition.attrib;
+>
+<!--end of edition.attlist-->]]>
+<!--end of edition.module-->]]>
+
+<!-- Editor ........................... -->
+
+<!ENTITY % editor.module "INCLUDE">
+<![ %editor.module; [
+<!ENTITY % local.editor.attrib "">
+<!ENTITY % editor.role.attrib "%role.attrib;">
+
+<!ENTITY % editor.element "INCLUDE">
+<![ %editor.element; [
+<!ELEMENT Editor - - ((%person.ident.mix;)+)>
+<!--end of editor.element-->]]>
+
+<!ENTITY % editor.attlist "INCLUDE">
+<![ %editor.attlist; [
+<!ATTLIST Editor
+ %common.attrib;
+ %editor.role.attrib;
+ %local.editor.attrib;
+>
+<!--end of editor.attlist-->]]>
+ <!--(see "Personal identity elements" for %person.ident.mix;)-->
+<!--end of editor.module-->]]>
+
+<!-- ISBN ............................. -->
+
+<!ENTITY % isbn.module "INCLUDE">
+<![ %isbn.module; [
+<!ENTITY % local.isbn.attrib "">
+<!ENTITY % isbn.role.attrib "%role.attrib;">
+
+<!ENTITY % isbn.element "INCLUDE">
+<![ %isbn.element; [
+<!ELEMENT ISBN - - ((%docinfo.char.mix;)+)>
+<!--end of isbn.element-->]]>
+
+<!ENTITY % isbn.attlist "INCLUDE">
+<![ %isbn.attlist; [
+<!ATTLIST ISBN
+ %common.attrib;
+ %isbn.role.attrib;
+ %local.isbn.attrib;
+>
+<!--end of isbn.attlist-->]]>
+<!--end of isbn.module-->]]>
+
+<!-- ISSN ............................. -->
+
+<!ENTITY % issn.module "INCLUDE">
+<![ %issn.module; [
+<!ENTITY % local.issn.attrib "">
+<!ENTITY % issn.role.attrib "%role.attrib;">
+
+<!ENTITY % issn.element "INCLUDE">
+<![ %issn.element; [
+<!ELEMENT ISSN - - ((%docinfo.char.mix;)+)>
+<!--end of issn.element-->]]>
+
+<!ENTITY % issn.attlist "INCLUDE">
+<![ %issn.attlist; [
+<!ATTLIST ISSN
+ %common.attrib;
+ %issn.role.attrib;
+ %local.issn.attrib;
+>
+<!--end of issn.attlist-->]]>
+<!--end of issn.module-->]]>
+
+<!-- InvPartNumber .................... -->
+
+<!ENTITY % invpartnumber.module "INCLUDE">
+<![ %invpartnumber.module; [
+<!ENTITY % local.invpartnumber.attrib "">
+<!ENTITY % invpartnumber.role.attrib "%role.attrib;">
+
+<!ENTITY % invpartnumber.element "INCLUDE">
+<![ %invpartnumber.element; [
+<!ELEMENT InvPartNumber - - ((%docinfo.char.mix;)+)>
+<!--end of invpartnumber.element-->]]>
+
+<!ENTITY % invpartnumber.attlist "INCLUDE">
+<![ %invpartnumber.attlist; [
+<!ATTLIST InvPartNumber
+ %common.attrib;
+ %invpartnumber.role.attrib;
+ %local.invpartnumber.attrib;
+>
+<!--end of invpartnumber.attlist-->]]>
+<!--end of invpartnumber.module-->]]>
+
+<!-- IssueNum ......................... -->
+
+<!ENTITY % issuenum.module "INCLUDE">
+<![ %issuenum.module; [
+<!ENTITY % local.issuenum.attrib "">
+<!ENTITY % issuenum.role.attrib "%role.attrib;">
+
+<!ENTITY % issuenum.element "INCLUDE">
+<![ %issuenum.element; [
+<!ELEMENT IssueNum - - ((%docinfo.char.mix;)+)>
+<!--end of issuenum.element-->]]>
+
+<!ENTITY % issuenum.attlist "INCLUDE">
+<![ %issuenum.attlist; [
+<!ATTLIST IssueNum
+ %common.attrib;
+ %issuenum.role.attrib;
+ %local.issuenum.attrib;
+>
+<!--end of issuenum.attlist-->]]>
+<!--end of issuenum.module-->]]>
+
+<!-- LegalNotice ...................... -->
+
+<!ENTITY % legalnotice.module "INCLUDE">
+<![ %legalnotice.module; [
+<!ENTITY % local.legalnotice.attrib "">
+<!ENTITY % legalnotice.role.attrib "%role.attrib;">
+
+<!ENTITY % legalnotice.element "INCLUDE">
+<![ %legalnotice.element; [
+<!ELEMENT LegalNotice - - (Title?, (%legalnotice.mix;)+) %formal.exclusion;>
+<!--end of legalnotice.element-->]]>
+
+<!ENTITY % legalnotice.attlist "INCLUDE">
+<![ %legalnotice.attlist; [
+<!ATTLIST LegalNotice
+ %common.attrib;
+ %legalnotice.role.attrib;
+ %local.legalnotice.attrib;
+>
+<!--end of legalnotice.attlist-->]]>
+<!--end of legalnotice.module-->]]>
+
+<!-- ModeSpec ......................... -->
+
+<!ENTITY % modespec.module "INCLUDE">
+<![ %modespec.module; [
+<!ENTITY % local.modespec.attrib "">
+<!ENTITY % modespec.role.attrib "%role.attrib;">
+
+<!ENTITY % modespec.element "INCLUDE">
+<![ %modespec.element; [
+<!ELEMENT ModeSpec - - ((%docinfo.char.mix;)+) %ubiq.exclusion;>
+<!--end of modespec.element-->]]>
+
+<!ENTITY % modespec.attlist "INCLUDE">
+<![ %modespec.attlist; [
+<!ATTLIST ModeSpec
+ --
+ Application: Type of action required for completion
+ of the links to which the ModeSpec is relevant (e.g.,
+ retrieval query)
+ --
+ Application NOTATION
+ (%notation.class;) #IMPLIED
+ %common.attrib;
+ %modespec.role.attrib;
+ %local.modespec.attrib;
+>
+<!--end of modespec.attlist-->]]>
+<!--end of modespec.module-->]]>
+
+<!-- OrgName .......................... -->
+
+<!ENTITY % orgname.module "INCLUDE">
+<![ %orgname.module; [
+<!ENTITY % local.orgname.attrib "">
+<!ENTITY % orgname.role.attrib "%role.attrib;">
+
+<!ENTITY % orgname.element "INCLUDE">
+<![ %orgname.element; [
+<!ELEMENT OrgName - - ((%docinfo.char.mix;)+)>
+<!--end of orgname.element-->]]>
+
+<!ENTITY % orgname.attlist "INCLUDE">
+<![ %orgname.attlist; [
+<!ATTLIST OrgName
+ %common.attrib;
+ %orgname.role.attrib;
+ %local.orgname.attrib;
+>
+<!--end of orgname.attlist-->]]>
+<!--end of orgname.module-->]]>
+
+<!-- OtherCredit ...................... -->
+
+<!ENTITY % othercredit.module "INCLUDE">
+<![ %othercredit.module; [
+<!ENTITY % local.othercredit.attrib "">
+<!ENTITY % othercredit.role.attrib "%role.attrib;">
+
+<!ENTITY % othercredit.element "INCLUDE">
+<![ %othercredit.element; [
+<!ELEMENT OtherCredit - - ((%person.ident.mix;)+)>
+<!--end of othercredit.element-->]]>
+
+<!ENTITY % othercredit.attlist "INCLUDE">
+<![ %othercredit.attlist; [
+<!ATTLIST OtherCredit
+ %common.attrib;
+ %othercredit.role.attrib;
+ %local.othercredit.attrib;
+>
+<!--end of othercredit.attlist-->]]>
+ <!--(see "Personal identity elements" for %person.ident.mix;)-->
+<!--end of othercredit.module-->]]>
+
+<!-- PageNums ......................... -->
+
+<!ENTITY % pagenums.module "INCLUDE">
+<![ %pagenums.module; [
+<!ENTITY % local.pagenums.attrib "">
+<!ENTITY % pagenums.role.attrib "%role.attrib;">
+
+<!ENTITY % pagenums.element "INCLUDE">
+<![ %pagenums.element; [
+<!ELEMENT PageNums - - ((%docinfo.char.mix;)+)>
+<!--end of pagenums.element-->]]>
+
+<!ENTITY % pagenums.attlist "INCLUDE">
+<![ %pagenums.attlist; [
+<!ATTLIST PageNums
+ %common.attrib;
+ %pagenums.role.attrib;
+ %local.pagenums.attrib;
+>
+<!--end of pagenums.attlist-->]]>
+<!--end of pagenums.module-->]]>
+
+<!-- Personal identity elements ....... -->
+
+<!-- These elements are used only within Author, Editor, and
+OtherCredit. -->
+
+<!ENTITY % person.ident.module "INCLUDE">
+<![ %person.ident.module; [
+ <!ENTITY % contrib.module "INCLUDE">
+ <![ %contrib.module; [
+ <!ENTITY % local.contrib.attrib "">
+ <!ENTITY % contrib.role.attrib "%role.attrib;">
+
+<!ENTITY % contrib.element "INCLUDE">
+<![ %contrib.element; [
+<!ELEMENT Contrib - - ((%docinfo.char.mix;)+)>
+<!--end of contrib.element-->]]>
+
+<!ENTITY % contrib.attlist "INCLUDE">
+<![ %contrib.attlist; [
+<!ATTLIST Contrib
+ %common.attrib;
+ %contrib.role.attrib;
+ %local.contrib.attrib;
+>
+<!--end of contrib.attlist-->]]>
+ <!--end of contrib.module-->]]>
+
+ <!ENTITY % firstname.module "INCLUDE">
+ <![ %firstname.module; [
+ <!ENTITY % local.firstname.attrib "">
+ <!ENTITY % firstname.role.attrib "%role.attrib;">
+
+<!ENTITY % firstname.element "INCLUDE">
+<![ %firstname.element; [
+<!ELEMENT FirstName - - ((%docinfo.char.mix;)+)>
+<!--end of firstname.element-->]]>
+
+<!ENTITY % firstname.attlist "INCLUDE">
+<![ %firstname.attlist; [
+<!ATTLIST FirstName
+ %common.attrib;
+ %firstname.role.attrib;
+ %local.firstname.attrib;
+>
+<!--end of firstname.attlist-->]]>
+ <!--end of firstname.module-->]]>
+
+ <!ENTITY % honorific.module "INCLUDE">
+ <![ %honorific.module; [
+ <!ENTITY % local.honorific.attrib "">
+ <!ENTITY % honorific.role.attrib "%role.attrib;">
+
+<!ENTITY % honorific.element "INCLUDE">
+<![ %honorific.element; [
+<!ELEMENT Honorific - - ((%docinfo.char.mix;)+)>
+<!--end of honorific.element-->]]>
+
+<!ENTITY % honorific.attlist "INCLUDE">
+<![ %honorific.attlist; [
+<!ATTLIST Honorific
+ %common.attrib;
+ %honorific.role.attrib;
+ %local.honorific.attrib;
+>
+<!--end of honorific.attlist-->]]>
+ <!--end of honorific.module-->]]>
+
+ <!ENTITY % lineage.module "INCLUDE">
+ <![ %lineage.module; [
+ <!ENTITY % local.lineage.attrib "">
+ <!ENTITY % lineage.role.attrib "%role.attrib;">
+
+<!ENTITY % lineage.element "INCLUDE">
+<![ %lineage.element; [
+<!ELEMENT Lineage - - ((%docinfo.char.mix;)+)>
+<!--end of lineage.element-->]]>
+
+<!ENTITY % lineage.attlist "INCLUDE">
+<![ %lineage.attlist; [
+<!ATTLIST Lineage
+ %common.attrib;
+ %lineage.role.attrib;
+ %local.lineage.attrib;
+>
+<!--end of lineage.attlist-->]]>
+ <!--end of lineage.module-->]]>
+
+ <!ENTITY % othername.module "INCLUDE">
+ <![ %othername.module; [
+ <!ENTITY % local.othername.attrib "">
+ <!ENTITY % othername.role.attrib "%role.attrib;">
+
+<!ENTITY % othername.element "INCLUDE">
+<![ %othername.element; [
+<!ELEMENT OtherName - - ((%docinfo.char.mix;)+)>
+<!--end of othername.element-->]]>
+
+<!ENTITY % othername.attlist "INCLUDE">
+<![ %othername.attlist; [
+<!ATTLIST OtherName
+ %common.attrib;
+ %othername.role.attrib;
+ %local.othername.attrib;
+>
+<!--end of othername.attlist-->]]>
+ <!--end of othername.module-->]]>
+
+ <!ENTITY % surname.module "INCLUDE">
+ <![ %surname.module; [
+ <!ENTITY % local.surname.attrib "">
+ <!ENTITY % surname.role.attrib "%role.attrib;">
+
+<!ENTITY % surname.element "INCLUDE">
+<![ %surname.element; [
+<!ELEMENT Surname - - ((%docinfo.char.mix;)+)>
+<!--end of surname.element-->]]>
+
+<!ENTITY % surname.attlist "INCLUDE">
+<![ %surname.attlist; [
+<!ATTLIST Surname
+ %common.attrib;
+ %surname.role.attrib;
+ %local.surname.attrib;
+>
+<!--end of surname.attlist-->]]>
+ <!--end of surname.module-->]]>
+<!--end of person.ident.module-->]]>
+
+<!-- PrintHistory ..................... -->
+
+<!ENTITY % printhistory.module "INCLUDE">
+<![ %printhistory.module; [
+<!ENTITY % local.printhistory.attrib "">
+<!ENTITY % printhistory.role.attrib "%role.attrib;">
+
+<!ENTITY % printhistory.element "INCLUDE">
+<![ %printhistory.element; [
+<!ELEMENT PrintHistory - - ((%para.class;)+)>
+<!--end of printhistory.element-->]]>
+
+<!ENTITY % printhistory.attlist "INCLUDE">
+<![ %printhistory.attlist; [
+<!ATTLIST PrintHistory
+ %common.attrib;
+ %printhistory.role.attrib;
+ %local.printhistory.attrib;
+>
+<!--end of printhistory.attlist-->]]>
+<!--end of printhistory.module-->]]>
+
+<!-- ProductName ...................... -->
+
+<!ENTITY % productname.module "INCLUDE">
+<![ %productname.module; [
+<!ENTITY % local.productname.attrib "">
+<!ENTITY % productname.role.attrib "%role.attrib;">
+
+<!ENTITY % productname.element "INCLUDE">
+<![ %productname.element; [
+<!ELEMENT ProductName - - ((%para.char.mix;)+)>
+<!--end of productname.element-->]]>
+
+<!ENTITY % productname.attlist "INCLUDE">
+<![ %productname.attlist; [
+<!ATTLIST ProductName
+ --
+ Class: More precisely identifies the item the element names
+ --
+ Class (Service
+ |Trade
+ |Registered
+ |Copyright) Trade
+ %common.attrib;
+ %productname.role.attrib;
+ %local.productname.attrib;
+>
+<!--end of productname.attlist-->]]>
+<!--end of productname.module-->]]>
+
+<!-- ProductNumber .................... -->
+
+<!ENTITY % productnumber.module "INCLUDE">
+<![ %productnumber.module; [
+<!ENTITY % local.productnumber.attrib "">
+<!ENTITY % productnumber.role.attrib "%role.attrib;">
+
+<!ENTITY % productnumber.element "INCLUDE">
+<![ %productnumber.element; [
+<!ELEMENT ProductNumber - - ((%docinfo.char.mix;)+)>
+<!--end of productnumber.element-->]]>
+
+<!ENTITY % productnumber.attlist "INCLUDE">
+<![ %productnumber.attlist; [
+<!ATTLIST ProductNumber
+ %common.attrib;
+ %productnumber.role.attrib;
+ %local.productnumber.attrib;
+>
+<!--end of productnumber.attlist-->]]>
+<!--end of productnumber.module-->]]>
+
+<!-- PubDate .......................... -->
+
+<!ENTITY % pubdate.module "INCLUDE">
+<![ %pubdate.module; [
+<!ENTITY % local.pubdate.attrib "">
+<!ENTITY % pubdate.role.attrib "%role.attrib;">
+
+<!ENTITY % pubdate.element "INCLUDE">
+<![ %pubdate.element; [
+<!ELEMENT PubDate - - ((%docinfo.char.mix;)+)>
+<!--end of pubdate.element-->]]>
+
+<!ENTITY % pubdate.attlist "INCLUDE">
+<![ %pubdate.attlist; [
+<!ATTLIST PubDate
+ %common.attrib;
+ %pubdate.role.attrib;
+ %local.pubdate.attrib;
+>
+<!--end of pubdate.attlist-->]]>
+<!--end of pubdate.module-->]]>
+
+<!-- Publisher ........................ -->
+
+<!ENTITY % publisher.content.module "INCLUDE">
+<![ %publisher.content.module; [
+<!ENTITY % publisher.module "INCLUDE">
+<![ %publisher.module; [
+<!ENTITY % local.publisher.attrib "">
+<!ENTITY % publisher.role.attrib "%role.attrib;">
+
+<!ENTITY % publisher.element "INCLUDE">
+<![ %publisher.element; [
+<!ELEMENT Publisher - - (PublisherName, Address*)>
+<!--end of publisher.element-->]]>
+
+<!ENTITY % publisher.attlist "INCLUDE">
+<![ %publisher.attlist; [
+<!ATTLIST Publisher
+ %common.attrib;
+ %publisher.role.attrib;
+ %local.publisher.attrib;
+>
+<!--end of publisher.attlist-->]]>
+<!--end of publisher.module-->]]>
+
+ <!ENTITY % publishername.module "INCLUDE">
+ <![ %publishername.module; [
+ <!ENTITY % local.publishername.attrib "">
+ <!ENTITY % publishername.role.attrib "%role.attrib;">
+
+<!ENTITY % publishername.element "INCLUDE">
+<![ %publishername.element; [
+<!ELEMENT PublisherName - - ((%docinfo.char.mix;)+)>
+<!--end of publishername.element-->]]>
+
+<!ENTITY % publishername.attlist "INCLUDE">
+<![ %publishername.attlist; [
+<!ATTLIST PublisherName
+ %common.attrib;
+ %publishername.role.attrib;
+ %local.publishername.attrib;
+>
+<!--end of publishername.attlist-->]]>
+ <!--end of publishername.module-->]]>
+
+ <!-- Address (defined elsewhere in this section)-->
+<!--end of publisher.content.module-->]]>
+
+<!-- PubsNumber ....................... -->
+
+<!ENTITY % pubsnumber.module "INCLUDE">
+<![ %pubsnumber.module; [
+<!ENTITY % local.pubsnumber.attrib "">
+<!ENTITY % pubsnumber.role.attrib "%role.attrib;">
+
+<!ENTITY % pubsnumber.element "INCLUDE">
+<![ %pubsnumber.element; [
+<!ELEMENT PubsNumber - - ((%docinfo.char.mix;)+)>
+<!--end of pubsnumber.element-->]]>
+
+<!ENTITY % pubsnumber.attlist "INCLUDE">
+<![ %pubsnumber.attlist; [
+<!ATTLIST PubsNumber
+ %common.attrib;
+ %pubsnumber.role.attrib;
+ %local.pubsnumber.attrib;
+>
+<!--end of pubsnumber.attlist-->]]>
+<!--end of pubsnumber.module-->]]>
+
+<!-- ReleaseInfo ...................... -->
+
+<!ENTITY % releaseinfo.module "INCLUDE">
+<![ %releaseinfo.module; [
+<!ENTITY % local.releaseinfo.attrib "">
+<!ENTITY % releaseinfo.role.attrib "%role.attrib;">
+
+<!ENTITY % releaseinfo.element "INCLUDE">
+<![ %releaseinfo.element; [
+<!ELEMENT ReleaseInfo - - ((%docinfo.char.mix;)+)>
+<!--end of releaseinfo.element-->]]>
+
+<!ENTITY % releaseinfo.attlist "INCLUDE">
+<![ %releaseinfo.attlist; [
+<!ATTLIST ReleaseInfo
+ %common.attrib;
+ %releaseinfo.role.attrib;
+ %local.releaseinfo.attrib;
+>
+<!--end of releaseinfo.attlist-->]]>
+<!--end of releaseinfo.module-->]]>
+
+<!-- RevHistory ....................... -->
+
+<!ENTITY % revhistory.content.module "INCLUDE">
+<![ %revhistory.content.module; [
+<!ENTITY % revhistory.module "INCLUDE">
+<![ %revhistory.module; [
+<!ENTITY % local.revhistory.attrib "">
+<!ENTITY % revhistory.role.attrib "%role.attrib;">
+
+<!ENTITY % revhistory.element "INCLUDE">
+<![ %revhistory.element; [
+<!ELEMENT RevHistory - - (Revision+)>
+<!--end of revhistory.element-->]]>
+
+<!ENTITY % revhistory.attlist "INCLUDE">
+<![ %revhistory.attlist; [
+<!ATTLIST RevHistory
+ %common.attrib;
+ %revhistory.role.attrib;
+ %local.revhistory.attrib;
+>
+<!--end of revhistory.attlist-->]]>
+<!--end of revhistory.module-->]]>
+
+ <!ENTITY % revision.module "INCLUDE">
+ <![ %revision.module; [
+ <!ENTITY % local.revision.attrib "">
+ <!ENTITY % revision.role.attrib "%role.attrib;">
+
+<!ENTITY % revision.element "INCLUDE">
+<![ %revision.element; [
+<!ELEMENT Revision - - (RevNumber, Date, AuthorInitials*, (RevRemark|RevDescription)?)>
+<!--end of revision.element-->]]>
+
+<!ENTITY % revision.attlist "INCLUDE">
+<![ %revision.attlist; [
+<!ATTLIST Revision
+ %common.attrib;
+ %revision.role.attrib;
+ %local.revision.attrib;
+>
+<!--end of revision.attlist-->]]>
+ <!--end of revision.module-->]]>
+
+ <!ENTITY % revnumber.module "INCLUDE">
+ <![ %revnumber.module; [
+ <!ENTITY % local.revnumber.attrib "">
+ <!ENTITY % revnumber.role.attrib "%role.attrib;">
+
+<!ENTITY % revnumber.element "INCLUDE">
+<![ %revnumber.element; [
+<!ELEMENT RevNumber - - ((%docinfo.char.mix;)+)>
+<!--end of revnumber.element-->]]>
+
+<!ENTITY % revnumber.attlist "INCLUDE">
+<![ %revnumber.attlist; [
+<!ATTLIST RevNumber
+ %common.attrib;
+ %revnumber.role.attrib;
+ %local.revnumber.attrib;
+>
+<!--end of revnumber.attlist-->]]>
+<!--end of revnumber.module-->]]>
+
+<!-- Date (defined elsewhere in this section)-->
+<!-- AuthorInitials (defined elsewhere in this section)-->
+
+<!ENTITY % revremark.module "INCLUDE">
+<![ %revremark.module; [
+<!ENTITY % local.revremark.attrib "">
+<!ENTITY % revremark.role.attrib "%role.attrib;">
+
+<!ENTITY % revremark.element "INCLUDE">
+<![ %revremark.element; [
+<!ELEMENT RevRemark - - ((%docinfo.char.mix;)+)>
+<!--end of revremark.element-->]]>
+
+<!ENTITY % revremark.attlist "INCLUDE">
+<![ %revremark.attlist; [
+<!ATTLIST RevRemark
+ %common.attrib;
+ %revremark.role.attrib;
+ %local.revremark.attrib;
+>
+<!--end of revremark.attlist-->]]>
+<!--end of revremark.module-->]]>
+
+<!ENTITY % revdescription.module "INCLUDE">
+<![ %revdescription.module; [
+<!ENTITY % local.revdescription.attrib "">
+<!ENTITY % revdescription.role.attrib "%role.attrib;">
+
+<!ENTITY % revdescription.element "INCLUDE">
+<![ %revdescription.element; [
+<!ELEMENT RevDescription - - ((%revdescription.mix;)+)>
+<!--end of revdescription.element-->]]>
+
+<!ENTITY % revdescription.attlist "INCLUDE">
+<![ %revdescription.attlist; [
+<!ATTLIST RevDescription
+ %common.attrib;
+ %revdescription.role.attrib;
+ %local.revdescription.attrib;
+>
+<!--end of revdescription.attlist-->]]>
+<!--end of revdescription.module-->]]>
+<!--end of revhistory.content.module-->]]>
+
+<!-- SeriesVolNums .................... -->
+
+<!ENTITY % seriesvolnums.module "INCLUDE">
+<![ %seriesvolnums.module; [
+<!ENTITY % local.seriesvolnums.attrib "">
+<!ENTITY % seriesvolnums.role.attrib "%role.attrib;">
+
+<!ENTITY % seriesvolnums.element "INCLUDE">
+<![ %seriesvolnums.element; [
+<!ELEMENT SeriesVolNums - - ((%docinfo.char.mix;)+)>
+<!--end of seriesvolnums.element-->]]>
+
+<!ENTITY % seriesvolnums.attlist "INCLUDE">
+<![ %seriesvolnums.attlist; [
+<!ATTLIST SeriesVolNums
+ %common.attrib;
+ %seriesvolnums.role.attrib;
+ %local.seriesvolnums.attrib;
+>
+<!--end of seriesvolnums.attlist-->]]>
+<!--end of seriesvolnums.module-->]]>
+
+<!-- VolumeNum ........................ -->
+
+<!ENTITY % volumenum.module "INCLUDE">
+<![ %volumenum.module; [
+<!ENTITY % local.volumenum.attrib "">
+<!ENTITY % volumenum.role.attrib "%role.attrib;">
+
+<!ENTITY % volumenum.element "INCLUDE">
+<![ %volumenum.element; [
+<!ELEMENT VolumeNum - - ((%docinfo.char.mix;)+)>
+<!--end of volumenum.element-->]]>
+
+<!ENTITY % volumenum.attlist "INCLUDE">
+<![ %volumenum.attlist; [
+<!ATTLIST VolumeNum
+ %common.attrib;
+ %volumenum.role.attrib;
+ %local.volumenum.attrib;
+>
+<!--end of volumenum.attlist-->]]>
+<!--end of volumenum.module-->]]>
+
+<!-- .................................. -->
+
+<!--end of docinfo.content.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Inline, link, and ubiquitous elements ................................ -->
+
+<!-- Technical and computer terms ......................................... -->
+
+<!ENTITY % accel.module "INCLUDE">
+<![ %accel.module; [
+<!ENTITY % local.accel.attrib "">
+<!ENTITY % accel.role.attrib "%role.attrib;">
+
+<!ENTITY % accel.element "INCLUDE">
+<![ %accel.element; [
+<!ELEMENT Accel - - ((%smallcptr.char.mix;)+)>
+<!--end of accel.element-->]]>
+
+<!ENTITY % accel.attlist "INCLUDE">
+<![ %accel.attlist; [
+<!ATTLIST Accel
+ %common.attrib;
+ %accel.role.attrib;
+ %local.accel.attrib;
+>
+<!--end of accel.attlist-->]]>
+<!--end of accel.module-->]]>
+
+<!ENTITY % action.module "INCLUDE">
+<![ %action.module; [
+<!ENTITY % local.action.attrib "">
+<!ENTITY % action.role.attrib "%role.attrib;">
+
+<!ENTITY % action.element "INCLUDE">
+<![ %action.element; [
+<!ELEMENT Action - - ((%smallcptr.char.mix;)+)>
+<!--end of action.element-->]]>
+
+<!ENTITY % action.attlist "INCLUDE">
+<![ %action.attlist; [
+<!ATTLIST Action
+ %moreinfo.attrib;
+ %common.attrib;
+ %action.role.attrib;
+ %local.action.attrib;
+>
+<!--end of action.attlist-->]]>
+<!--end of action.module-->]]>
+
+<!ENTITY % application.module "INCLUDE">
+<![ %application.module; [
+<!ENTITY % local.application.attrib "">
+<!ENTITY % application.role.attrib "%role.attrib;">
+
+<!ENTITY % application.element "INCLUDE">
+<![ %application.element; [
+<!ELEMENT Application - - ((%para.char.mix;)+)>
+<!--end of application.element-->]]>
+
+<!ENTITY % application.attlist "INCLUDE">
+<![ %application.attlist; [
+<!ATTLIST Application
+ Class (Hardware
+ |Software) #IMPLIED
+ %moreinfo.attrib;
+ %common.attrib;
+ %application.role.attrib;
+ %local.application.attrib;
+>
+<!--end of application.attlist-->]]>
+<!--end of application.module-->]]>
+
+<!ENTITY % classname.module "INCLUDE">
+<![ %classname.module; [
+<!ENTITY % local.classname.attrib "">
+<!ENTITY % classname.role.attrib "%role.attrib;">
+
+<!ENTITY % classname.element "INCLUDE">
+<![ %classname.element; [
+<!ELEMENT ClassName - - ((%smallcptr.char.mix;)+)>
+<!--end of classname.element-->]]>
+
+<!ENTITY % classname.attlist "INCLUDE">
+<![ %classname.attlist; [
+<!ATTLIST ClassName
+ %common.attrib;
+ %classname.role.attrib;
+ %local.classname.attrib;
+>
+<!--end of classname.attlist-->]]>
+<!--end of classname.module-->]]>
+
+<!ENTITY % co.module "INCLUDE">
+<![ %co.module; [
+<!ENTITY % local.co.attrib "">
+<!-- CO is a callout area of the LineColumn unit type (a single character
+ position); the position is directly indicated by the location of CO. -->
+<!ENTITY % co.role.attrib "%role.attrib;">
+
+<!ENTITY % co.element "INCLUDE">
+<![ %co.element; [
+<!ELEMENT CO - O EMPTY>
+<!--end of co.element-->]]>
+
+<!ENTITY % co.attlist "INCLUDE">
+<![ %co.attlist; [
+<!ATTLIST CO
+ %label.attrib; --bug number/symbol override or initialization--
+ %linkends.attrib; --to any related information--
+ %idreq.common.attrib;
+ %co.role.attrib;
+ %local.co.attrib;
+>
+<!--end of co.attlist-->]]>
+<!--end of co.module-->]]>
+
+<!ENTITY % command.module "INCLUDE">
+<![ %command.module; [
+<!ENTITY % local.command.attrib "">
+<!ENTITY % command.role.attrib "%role.attrib;">
+
+<!ENTITY % command.element "INCLUDE">
+<![ %command.element; [
+<!ELEMENT Command - - ((%cptr.char.mix;)+)>
+<!--end of command.element-->]]>
+
+<!ENTITY % command.attlist "INCLUDE">
+<![ %command.attlist; [
+<!ATTLIST Command
+ %moreinfo.attrib;
+ %common.attrib;
+ %command.role.attrib;
+ %local.command.attrib;
+>
+<!--end of command.attlist-->]]>
+<!--end of command.module-->]]>
+
+<!ENTITY % computeroutput.module "INCLUDE">
+<![ %computeroutput.module; [
+<!ENTITY % local.computeroutput.attrib "">
+<!ENTITY % computeroutput.role.attrib "%role.attrib;">
+
+<!ENTITY % computeroutput.element "INCLUDE">
+<![ %computeroutput.element; [
+<!ELEMENT ComputerOutput - - ((%cptr.char.mix;)+)>
+<!--end of computeroutput.element-->]]>
+
+<!ENTITY % computeroutput.attlist "INCLUDE">
+<![ %computeroutput.attlist; [
+<!ATTLIST ComputerOutput
+ %moreinfo.attrib;
+ %common.attrib;
+ %computeroutput.role.attrib;
+ %local.computeroutput.attrib;
+>
+<!--end of computeroutput.attlist-->]]>
+<!--end of computeroutput.module-->]]>
+
+<!ENTITY % database.module "INCLUDE">
+<![ %database.module; [
+<!ENTITY % local.database.attrib "">
+<!ENTITY % database.role.attrib "%role.attrib;">
+
+<!ENTITY % database.element "INCLUDE">
+<![ %database.element; [
+<!ELEMENT Database - - ((%smallcptr.char.mix;)+)>
+<!--end of database.element-->]]>
+
+<!ENTITY % database.attlist "INCLUDE">
+<![ %database.attlist; [
+<!ATTLIST Database
+ --
+ Class: Type of database the element names; no default
+ --
+ Class (Name
+ |Table
+ |Field
+ |Key1
+ |Key2
+ |Record) #IMPLIED
+ %moreinfo.attrib;
+ %common.attrib;
+ %database.role.attrib;
+ %local.database.attrib;
+>
+<!--end of database.attlist-->]]>
+<!--end of database.module-->]]>
+
+<!ENTITY % email.module "INCLUDE">
+<![ %email.module; [
+<!ENTITY % local.email.attrib "">
+<!ENTITY % email.role.attrib "%role.attrib;">
+
+<!ENTITY % email.element "INCLUDE">
+<![ %email.element; [
+<!ELEMENT Email - - ((%docinfo.char.mix;)+)>
+<!--end of email.element-->]]>
+
+<!ENTITY % email.attlist "INCLUDE">
+<![ %email.attlist; [
+<!ATTLIST Email
+ %common.attrib;
+ %email.role.attrib;
+ %local.email.attrib;
+>
+<!--end of email.attlist-->]]>
+<!--end of email.module-->]]>
+
+<!ENTITY % envar.module "INCLUDE">
+<![ %envar.module; [
+<!ENTITY % local.envar.attrib "">
+<!ENTITY % envar.role.attrib "%role.attrib;">
+
+<!ENTITY % envar.element "INCLUDE">
+<![ %envar.element; [
+<!ELEMENT EnVar - - ((%smallcptr.char.mix;)+)>
+<!--end of envar.element-->]]>
+
+<!ENTITY % envar.attlist "INCLUDE">
+<![ %envar.attlist; [
+<!ATTLIST EnVar
+ %common.attrib;
+ %envar.role.attrib;
+ %local.envar.attrib;
+>
+<!--end of envar.attlist-->]]>
+<!--end of envar.module-->]]>
+
+
+<!ENTITY % errorcode.module "INCLUDE">
+<![ %errorcode.module; [
+<!ENTITY % local.errorcode.attrib "">
+<!ENTITY % errorcode.role.attrib "%role.attrib;">
+
+<!ENTITY % errorcode.element "INCLUDE">
+<![ %errorcode.element; [
+<!ELEMENT ErrorCode - - ((%smallcptr.char.mix;)+)>
+<!--end of errorcode.element-->]]>
+
+<!ENTITY % errorcode.attlist "INCLUDE">
+<![ %errorcode.attlist; [
+<!ATTLIST ErrorCode
+ %moreinfo.attrib;
+ %common.attrib;
+ %errorcode.role.attrib;
+ %local.errorcode.attrib;
+>
+<!--end of errorcode.attlist-->]]>
+<!--end of errorcode.module-->]]>
+
+<!ENTITY % errorname.module "INCLUDE">
+<![ %errorname.module; [
+<!ENTITY % local.errorname.attrib "">
+<!ENTITY % errorname.role.attrib "%role.attrib;">
+
+<!ENTITY % errorname.element "INCLUDE">
+<![ %errorname.element; [
+<!ELEMENT ErrorName - - ((%smallcptr.char.mix;)+)>
+<!--end of errorname.element-->]]>
+
+<!ENTITY % errorname.attlist "INCLUDE">
+<![ %errorname.attlist; [
+<!ATTLIST ErrorName
+ %common.attrib;
+ %errorname.role.attrib;
+ %local.errorname.attrib;
+>
+<!--end of errorname.attlist-->]]>
+<!--end of errorname.module-->]]>
+
+<!ENTITY % errortype.module "INCLUDE">
+<![ %errortype.module; [
+<!ENTITY % local.errortype.attrib "">
+<!ENTITY % errortype.role.attrib "%role.attrib;">
+
+<!ENTITY % errortype.element "INCLUDE">
+<![ %errortype.element; [
+<!ELEMENT ErrorType - - ((%smallcptr.char.mix;)+)>
+<!--end of errortype.element-->]]>
+
+<!ENTITY % errortype.attlist "INCLUDE">
+<![ %errortype.attlist; [
+<!ATTLIST ErrorType
+ %common.attrib;
+ %errortype.role.attrib;
+ %local.errortype.attrib;
+>
+<!--end of errortype.attlist-->]]>
+<!--end of errortype.module-->]]>
+
+<!ENTITY % filename.module "INCLUDE">
+<![ %filename.module; [
+<!ENTITY % local.filename.attrib "">
+<!ENTITY % filename.role.attrib "%role.attrib;">
+
+<!ENTITY % filename.element "INCLUDE">
+<![ %filename.element; [
+<!ELEMENT Filename - - ((%smallcptr.char.mix;)+)>
+<!--end of filename.element-->]]>
+
+<!ENTITY % filename.attlist "INCLUDE">
+<![ %filename.attlist; [
+<!ATTLIST Filename
+ --
+ Class: Type of filename the element names; no default
+ --
+ Class (HeaderFile
+ |DeviceFile
+ |Directory
+ |LibraryFile
+ |SymLink) #IMPLIED
+ --
+ Path: Search path (possibly system-specific) in which
+ file can be found
+ --
+ Path CDATA #IMPLIED
+ %moreinfo.attrib;
+ %common.attrib;
+ %filename.role.attrib;
+ %local.filename.attrib;
+>
+<!--end of filename.attlist-->]]>
+<!--end of filename.module-->]]>
+
+<!ENTITY % function.module "INCLUDE">
+<![ %function.module; [
+<!ENTITY % local.function.attrib "">
+<!ENTITY % function.role.attrib "%role.attrib;">
+
+<!ENTITY % function.element "INCLUDE">
+<![ %function.element; [
+<!ELEMENT Function - - ((%cptr.char.mix;)+)>
+<!--end of function.element-->]]>
+
+<!ENTITY % function.attlist "INCLUDE">
+<![ %function.attlist; [
+<!ATTLIST Function
+ %moreinfo.attrib;
+ %common.attrib;
+ %function.role.attrib;
+ %local.function.attrib;
+>
+<!--end of function.attlist-->]]>
+<!--end of function.module-->]]>
+
+<!ENTITY % guibutton.module "INCLUDE">
+<![ %guibutton.module; [
+<!ENTITY % local.guibutton.attrib "">
+<!ENTITY % guibutton.role.attrib "%role.attrib;">
+
+<!ENTITY % guibutton.element "INCLUDE">
+<![ %guibutton.element; [
+<!ELEMENT GUIButton - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guibutton.element-->]]>
+
+<!ENTITY % guibutton.attlist "INCLUDE">
+<![ %guibutton.attlist; [
+<!ATTLIST GUIButton
+ %moreinfo.attrib;
+ %common.attrib;
+ %guibutton.role.attrib;
+ %local.guibutton.attrib;
+>
+<!--end of guibutton.attlist-->]]>
+<!--end of guibutton.module-->]]>
+
+<!ENTITY % guiicon.module "INCLUDE">
+<![ %guiicon.module; [
+<!ENTITY % local.guiicon.attrib "">
+<!ENTITY % guiicon.role.attrib "%role.attrib;">
+
+<!ENTITY % guiicon.element "INCLUDE">
+<![ %guiicon.element; [
+<!ELEMENT GUIIcon - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guiicon.element-->]]>
+
+<!ENTITY % guiicon.attlist "INCLUDE">
+<![ %guiicon.attlist; [
+<!ATTLIST GUIIcon
+ %moreinfo.attrib;
+ %common.attrib;
+ %guiicon.role.attrib;
+ %local.guiicon.attrib;
+>
+<!--end of guiicon.attlist-->]]>
+<!--end of guiicon.module-->]]>
+
+<!ENTITY % guilabel.module "INCLUDE">
+<![ %guilabel.module; [
+<!ENTITY % local.guilabel.attrib "">
+<!ENTITY % guilabel.role.attrib "%role.attrib;">
+
+<!ENTITY % guilabel.element "INCLUDE">
+<![ %guilabel.element; [
+<!ELEMENT GUILabel - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guilabel.element-->]]>
+
+<!ENTITY % guilabel.attlist "INCLUDE">
+<![ %guilabel.attlist; [
+<!ATTLIST GUILabel
+ %moreinfo.attrib;
+ %common.attrib;
+ %guilabel.role.attrib;
+ %local.guilabel.attrib;
+>
+<!--end of guilabel.attlist-->]]>
+<!--end of guilabel.module-->]]>
+
+<!ENTITY % guimenu.module "INCLUDE">
+<![ %guimenu.module; [
+<!ENTITY % local.guimenu.attrib "">
+<!ENTITY % guimenu.role.attrib "%role.attrib;">
+
+<!ENTITY % guimenu.element "INCLUDE">
+<![ %guimenu.element; [
+<!ELEMENT GUIMenu - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guimenu.element-->]]>
+
+<!ENTITY % guimenu.attlist "INCLUDE">
+<![ %guimenu.attlist; [
+<!ATTLIST GUIMenu
+ %moreinfo.attrib;
+ %common.attrib;
+ %guimenu.role.attrib;
+ %local.guimenu.attrib;
+>
+<!--end of guimenu.attlist-->]]>
+<!--end of guimenu.module-->]]>
+
+<!ENTITY % guimenuitem.module "INCLUDE">
+<![ %guimenuitem.module; [
+<!ENTITY % local.guimenuitem.attrib "">
+<!ENTITY % guimenuitem.role.attrib "%role.attrib;">
+
+<!ENTITY % guimenuitem.element "INCLUDE">
+<![ %guimenuitem.element; [
+<!ELEMENT GUIMenuItem - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guimenuitem.element-->]]>
+
+<!ENTITY % guimenuitem.attlist "INCLUDE">
+<![ %guimenuitem.attlist; [
+<!ATTLIST GUIMenuItem
+ %moreinfo.attrib;
+ %common.attrib;
+ %guimenuitem.role.attrib;
+ %local.guimenuitem.attrib;
+>
+<!--end of guimenuitem.attlist-->]]>
+<!--end of guimenuitem.module-->]]>
+
+<!ENTITY % guisubmenu.module "INCLUDE">
+<![ %guisubmenu.module; [
+<!ENTITY % local.guisubmenu.attrib "">
+<!ENTITY % guisubmenu.role.attrib "%role.attrib;">
+
+<!ENTITY % guisubmenu.element "INCLUDE">
+<![ %guisubmenu.element; [
+<!ELEMENT GUISubmenu - - ((%smallcptr.char.mix;|Accel)+)>
+<!--end of guisubmenu.element-->]]>
+
+<!ENTITY % guisubmenu.attlist "INCLUDE">
+<![ %guisubmenu.attlist; [
+<!ATTLIST GUISubmenu
+ %moreinfo.attrib;
+ %common.attrib;
+ %guisubmenu.role.attrib;
+ %local.guisubmenu.attrib;
+>
+<!--end of guisubmenu.attlist-->]]>
+<!--end of guisubmenu.module-->]]>
+
+<!ENTITY % hardware.module "INCLUDE">
+<![ %hardware.module; [
+<!ENTITY % local.hardware.attrib "">
+<!ENTITY % hardware.role.attrib "%role.attrib;">
+
+<!ENTITY % hardware.element "INCLUDE">
+<![ %hardware.element; [
+<!ELEMENT Hardware - - ((%smallcptr.char.mix;)+)>
+<!--end of hardware.element-->]]>
+
+<!ENTITY % hardware.attlist "INCLUDE">
+<![ %hardware.attlist; [
+<!ATTLIST Hardware
+ %moreinfo.attrib;
+ %common.attrib;
+ %hardware.role.attrib;
+ %local.hardware.attrib;
+>
+<!--end of hardware.attlist-->]]>
+<!--end of hardware.module-->]]>
+
+<!ENTITY % interface.module "INCLUDE">
+<![ %interface.module; [
+<!ENTITY % local.interface.attrib "">
+<!ENTITY % interface.role.attrib "%role.attrib;">
+
+<!ENTITY % interface.element "INCLUDE">
+<![ %interface.element; [
+<!ELEMENT Interface - - (%smallcptr.char.mix;|Accel)*>
+<!--end of interface.element-->]]>
+
+<!ENTITY % interface.attlist "INCLUDE">
+<![ %interface.attlist; [
+<!ATTLIST Interface
+ %moreinfo.attrib;
+ %common.attrib;
+ %interface.role.attrib;
+ %local.interface.attrib;
+>
+<!--end of interface.attlist-->]]>
+<!--end of interface.module-->]]>
+
+<!ENTITY % keycap.module "INCLUDE">
+<![ %keycap.module; [
+<!ENTITY % local.keycap.attrib "">
+<!ENTITY % keycap.role.attrib "%role.attrib;">
+
+<!ENTITY % keycap.element "INCLUDE">
+<![ %keycap.element; [
+<!ELEMENT KeyCap - - (%smallcptr.char.mix;)*>
+<!--end of keycap.element-->]]>
+
+<!ENTITY % keycap.attlist "INCLUDE">
+<![ %keycap.attlist; [
+<!ATTLIST KeyCap
+ %moreinfo.attrib;
+ %common.attrib;
+ %keycap.role.attrib;
+ %local.keycap.attrib;
+>
+<!--end of keycap.attlist-->]]>
+<!--end of keycap.module-->]]>
+
+<!ENTITY % keycode.module "INCLUDE">
+<![ %keycode.module; [
+<!ENTITY % local.keycode.attrib "">
+<!ENTITY % keycode.role.attrib "%role.attrib;">
+
+<!ENTITY % keycode.element "INCLUDE">
+<![ %keycode.element; [
+<!ELEMENT KeyCode - - ((%smallcptr.char.mix;)+)>
+<!--end of keycode.element-->]]>
+
+<!ENTITY % keycode.attlist "INCLUDE">
+<![ %keycode.attlist; [
+<!ATTLIST KeyCode
+ %common.attrib;
+ %keycode.role.attrib;
+ %local.keycode.attrib;
+>
+<!--end of keycode.attlist-->]]>
+<!--end of keycode.module-->]]>
+
+<!ENTITY % keycombo.module "INCLUDE">
+<![ %keycombo.module; [
+<!ENTITY % local.keycombo.attrib "">
+<!ENTITY % keycombo.role.attrib "%role.attrib;">
+
+<!ENTITY % keycombo.element "INCLUDE">
+<![ %keycombo.element; [
+<!ELEMENT KeyCombo - - ((KeyCap|KeyCombo|KeySym|MouseButton)+)>
+<!--end of keycombo.element-->]]>
+
+<!ENTITY % keycombo.attlist "INCLUDE">
+<![ %keycombo.attlist; [
+<!ATTLIST KeyCombo
+ %keyaction.attrib;
+ %moreinfo.attrib;
+ %common.attrib;
+ %keycombo.role.attrib;
+ %local.keycombo.attrib;
+>
+<!--end of keycombo.attlist-->]]>
+<!--end of keycombo.module-->]]>
+
+<!ENTITY % keysym.module "INCLUDE">
+<![ %keysym.module; [
+<!ENTITY % local.keysym.attrib "">
+<!ENTITY % keysysm.role.attrib "%role.attrib;">
+
+<!ENTITY % keysym.element "INCLUDE">
+<![ %keysym.element; [
+<!ELEMENT KeySym - - ((%smallcptr.char.mix;)+)>
+<!--end of keysym.element-->]]>
+
+<!ENTITY % keysym.attlist "INCLUDE">
+<![ %keysym.attlist; [
+<!ATTLIST KeySym
+ %common.attrib;
+ %keysysm.role.attrib;
+ %local.keysym.attrib;
+>
+<!--end of keysym.attlist-->]]>
+<!--end of keysym.module-->]]>
+
+<!ENTITY % lineannotation.module "INCLUDE">
+<![ %lineannotation.module; [
+<!ENTITY % local.lineannotation.attrib "">
+<!ENTITY % lineannotation.role.attrib "%role.attrib;">
+
+<!ENTITY % lineannotation.element "INCLUDE">
+<![ %lineannotation.element; [
+<!ELEMENT LineAnnotation - - ((%para.char.mix;)+)>
+<!--end of lineannotation.element-->]]>
+
+<!ENTITY % lineannotation.attlist "INCLUDE">
+<![ %lineannotation.attlist; [
+<!ATTLIST LineAnnotation
+ %common.attrib;
+ %lineannotation.role.attrib;
+ %local.lineannotation.attrib;
+>
+<!--end of lineannotation.attlist-->]]>
+<!--end of lineannotation.module-->]]>
+
+<!ENTITY % literal.module "INCLUDE">
+<![ %literal.module; [
+<!ENTITY % local.literal.attrib "">
+<!ENTITY % literal.role.attrib "%role.attrib;">
+
+<!ENTITY % literal.element "INCLUDE">
+<![ %literal.element; [
+<!ELEMENT Literal - - (%cptr.char.mix;)*>
+<!--end of literal.element-->]]>
+
+<!ENTITY % literal.attlist "INCLUDE">
+<![ %literal.attlist; [
+<!ATTLIST Literal
+ %moreinfo.attrib;
+ %common.attrib;
+ %literal.role.attrib;
+ %local.literal.attrib;
+>
+<!--end of literal.attlist-->]]>
+<!--end of literal.module-->]]>
+
+<!ENTITY % constant.module "INCLUDE">
+<![ %constant.module; [
+<!ENTITY % local.constant.attrib "">
+<!ENTITY % constant.role.attrib "%role.attrib;">
+
+<!ENTITY % constant.element "INCLUDE">
+<![ %constant.element; [
+<!ELEMENT Constant - - (%smallcptr.char.mix;)*>
+<!--end of constant.element-->]]>
+
+<!ENTITY % constant.attlist "INCLUDE">
+<![ %constant.attlist; [
+<!ATTLIST Constant
+ %common.attrib;
+ %constant.role.attrib;
+ %local.constant.attrib;
+ Class (Limit) #IMPLIED
+>
+<!--end of constant.attlist-->]]>
+<!--end of constant.module-->]]>
+
+<!ENTITY % varname.module "INCLUDE">
+<![ %varname.module; [
+<!ENTITY % local.varname.attrib "">
+<!ENTITY % varname.role.attrib "%role.attrib;">
+
+<!ENTITY % varname.element "INCLUDE">
+<![ %varname.element; [
+<!ELEMENT VarName - - (%smallcptr.char.mix;)*>
+<!--end of varname.element-->]]>
+
+<!ENTITY % varname.attlist "INCLUDE">
+<![ %varname.attlist; [
+<!ATTLIST VarName
+ %common.attrib;
+ %varname.role.attrib;
+ %local.varname.attrib;
+>
+<!--end of varname.attlist-->]]>
+<!--end of varname.module-->]]>
+
+<!ENTITY % markup.module "INCLUDE">
+<![ %markup.module; [
+<!ENTITY % local.markup.attrib "">
+<!ENTITY % markup.role.attrib "%role.attrib;">
+
+<!ENTITY % markup.element "INCLUDE">
+<![ %markup.element; [
+<!ELEMENT Markup - - ((%smallcptr.char.mix;)+)>
+<!--end of markup.element-->]]>
+
+<!ENTITY % markup.attlist "INCLUDE">
+<![ %markup.attlist; [
+<!ATTLIST Markup
+ %common.attrib;
+ %markup.role.attrib;
+ %local.markup.attrib;
+>
+<!--end of markup.attlist-->]]>
+<!--end of markup.module-->]]>
+
+<!ENTITY % medialabel.module "INCLUDE">
+<![ %medialabel.module; [
+<!ENTITY % local.medialabel.attrib "">
+<!ENTITY % medialabel.role.attrib "%role.attrib;">
+
+<!ENTITY % medialabel.element "INCLUDE">
+<![ %medialabel.element; [
+<!ELEMENT MediaLabel - - ((%smallcptr.char.mix;)+)>
+<!--end of medialabel.element-->]]>
+
+<!ENTITY % medialabel.attlist "INCLUDE">
+<![ %medialabel.attlist; [
+<!ATTLIST MediaLabel
+ --
+ Class: Type of medium named by the element; no default
+ --
+ Class (Cartridge
+ |CDRom
+ |Disk
+ |Tape) #IMPLIED
+ %common.attrib;
+ %medialabel.role.attrib;
+ %local.medialabel.attrib;
+>
+<!--end of medialabel.attlist-->]]>
+<!--end of medialabel.module-->]]>
+
+<!ENTITY % menuchoice.content.module "INCLUDE">
+<![ %menuchoice.content.module; [
+<!ENTITY % menuchoice.module "INCLUDE">
+<![ %menuchoice.module; [
+<!ENTITY % local.menuchoice.attrib "">
+<!ENTITY % menuchoice.role.attrib "%role.attrib;">
+
+<!ENTITY % menuchoice.element "INCLUDE">
+<![ %menuchoice.element; [
+<!ELEMENT MenuChoice - - (Shortcut?, (GUIButton|GUIIcon|GUILabel
+ |GUIMenu|GUIMenuItem|GUISubmenu|Interface)+)>
+<!--end of menuchoice.element-->]]>
+
+<!ENTITY % menuchoice.attlist "INCLUDE">
+<![ %menuchoice.attlist; [
+<!ATTLIST MenuChoice
+ %moreinfo.attrib;
+ %common.attrib;
+ %menuchoice.role.attrib;
+ %local.menuchoice.attrib;
+>
+<!--end of menuchoice.attlist-->]]>
+<!--end of menuchoice.module-->]]>
+
+<!ENTITY % shortcut.module "INCLUDE">
+<![ %shortcut.module; [
+<!-- See also KeyCombo -->
+<!ENTITY % local.shortcut.attrib "">
+<!ENTITY % shortcut.role.attrib "%role.attrib;">
+
+<!ENTITY % shortcut.element "INCLUDE">
+<![ %shortcut.element; [
+<!ELEMENT Shortcut - - ((KeyCap|KeyCombo|KeySym|MouseButton)+)>
+<!--end of shortcut.element-->]]>
+
+<!ENTITY % shortcut.attlist "INCLUDE">
+<![ %shortcut.attlist; [
+<!ATTLIST Shortcut
+ %keyaction.attrib;
+ %moreinfo.attrib;
+ %common.attrib;
+ %shortcut.role.attrib;
+ %local.shortcut.attrib;
+>
+<!--end of shortcut.attlist-->]]>
+<!--end of shortcut.module-->]]>
+<!--end of menuchoice.content.module-->]]>
+
+<!ENTITY % mousebutton.module "INCLUDE">
+<![ %mousebutton.module; [
+<!ENTITY % local.mousebutton.attrib "">
+<!ENTITY % mousebutton.role.attrib "%role.attrib;">
+
+<!ENTITY % mousebutton.element "INCLUDE">
+<![ %mousebutton.element; [
+<!ELEMENT MouseButton - - ((%smallcptr.char.mix;)+)>
+<!--end of mousebutton.element-->]]>
+
+<!ENTITY % mousebutton.attlist "INCLUDE">
+<![ %mousebutton.attlist; [
+<!ATTLIST MouseButton
+ %moreinfo.attrib;
+ %common.attrib;
+ %mousebutton.role.attrib;
+ %local.mousebutton.attrib;
+>
+<!--end of mousebutton.attlist-->]]>
+<!--end of mousebutton.module-->]]>
+
+<!ENTITY % msgtext.module "INCLUDE">
+<![ %msgtext.module; [
+<!ENTITY % local.msgtext.attrib "">
+<!ENTITY % msgtext.role.attrib "%role.attrib;">
+
+<!ENTITY % msgtext.element "INCLUDE">
+<![ %msgtext.element; [
+<!--FUTURE USE (V5.0):
+......................
+The content model of MsgText will be reduced. It will be made
+the same as %example.mix; although it may not use that PE.
+......................
+-->
+<!ELEMENT MsgText - - ((%component.mix;)+)>
+<!--end of msgtext.element-->]]>
+
+<!ENTITY % msgtext.attlist "INCLUDE">
+<![ %msgtext.attlist; [
+<!ATTLIST MsgText
+ %common.attrib;
+ %msgtext.role.attrib;
+ %local.msgtext.attrib;
+>
+<!--end of msgtext.attlist-->]]>
+<!--end of msgtext.module-->]]>
+
+<!ENTITY % option.module "INCLUDE">
+<![ %option.module; [
+<!ENTITY % local.option.attrib "">
+<!ENTITY % option.role.attrib "%role.attrib;">
+
+<!ENTITY % option.element "INCLUDE">
+<![ %option.element; [
+<!ELEMENT Option - - (%smallcptr.char.mix;)*>
+<!--end of option.element-->]]>
+
+<!ENTITY % option.attlist "INCLUDE">
+<![ %option.attlist; [
+<!ATTLIST Option
+ %common.attrib;
+ %option.role.attrib;
+ %local.option.attrib;
+>
+<!--end of option.attlist-->]]>
+<!--end of option.module-->]]>
+
+<!ENTITY % optional.module "INCLUDE">
+<![ %optional.module; [
+<!ENTITY % local.optional.attrib "">
+<!ENTITY % optional.role.attrib "%role.attrib;">
+
+<!ENTITY % optional.element "INCLUDE">
+<![ %optional.element; [
+<!ELEMENT Optional - - ((%cptr.char.mix;)+)>
+<!--end of optional.element-->]]>
+
+<!ENTITY % optional.attlist "INCLUDE">
+<![ %optional.attlist; [
+<!ATTLIST Optional
+ %common.attrib;
+ %optional.role.attrib;
+ %local.optional.attrib;
+>
+<!--end of optional.attlist-->]]>
+<!--end of optional.module-->]]>
+
+<!ENTITY % parameter.module "INCLUDE">
+<![ %parameter.module; [
+<!ENTITY % local.parameter.attrib "">
+<!ENTITY % parameter.role.attrib "%role.attrib;">
+
+<!ENTITY % parameter.element "INCLUDE">
+<![ %parameter.element; [
+<!ELEMENT Parameter - - (%smallcptr.char.mix;)*>
+<!--end of parameter.element-->]]>
+
+<!ENTITY % parameter.attlist "INCLUDE">
+<![ %parameter.attlist; [
+<!ATTLIST Parameter
+ --
+ Class: Type of the Parameter; no default
+ --
+ Class (Command
+ |Function
+ |Option) #IMPLIED
+ %moreinfo.attrib;
+ %common.attrib;
+ %parameter.role.attrib;
+ %local.parameter.attrib;
+>
+<!--end of parameter.attlist-->]]>
+<!--end of parameter.module-->]]>
+
+<!ENTITY % prompt.module "INCLUDE">
+<![ %prompt.module; [
+<!ENTITY % local.prompt.attrib "">
+<!ENTITY % prompt.role.attrib "%role.attrib;">
+
+<!ENTITY % prompt.element "INCLUDE">
+<![ %prompt.element; [
+<!ELEMENT Prompt - - ((%smallcptr.char.mix;)+)>
+<!--end of prompt.element-->]]>
+
+<!ENTITY % prompt.attlist "INCLUDE">
+<![ %prompt.attlist; [
+<!ATTLIST Prompt
+ %moreinfo.attrib;
+ %common.attrib;
+ %prompt.role.attrib;
+ %local.prompt.attrib;
+>
+<!--end of prompt.attlist-->]]>
+<!--end of prompt.module-->]]>
+
+<!ENTITY % property.module "INCLUDE">
+<![ %property.module; [
+<!ENTITY % local.property.attrib "">
+<!ENTITY % property.role.attrib "%role.attrib;">
+
+<!ENTITY % property.element "INCLUDE">
+<![ %property.element; [
+<!ELEMENT Property - - (%smallcptr.char.mix;)*>
+<!--end of property.element-->]]>
+
+<!ENTITY % property.attlist "INCLUDE">
+<![ %property.attlist; [
+<!ATTLIST Property
+ %moreinfo.attrib;
+ %common.attrib;
+ %property.role.attrib;
+ %local.property.attrib;
+>
+<!--end of property.attlist-->]]>
+<!--end of property.module-->]]>
+
+<!ENTITY % replaceable.module "INCLUDE">
+<![ %replaceable.module; [
+<!ENTITY % local.replaceable.attrib "">
+<!ENTITY % replaceable.role.attrib "%role.attrib;">
+
+<!ENTITY % replaceable.element "INCLUDE">
+<![ %replaceable.element; [
+<!ELEMENT Replaceable - - ((#PCDATA
+ | %link.char.class;
+ | Optional
+ | %base.char.class;
+ | %other.char.class;
+ | InlineGraphic
+ | InlineMediaObject)+)>
+<!--end of replaceable.element-->]]>
+
+<!ENTITY % replaceable.attlist "INCLUDE">
+<![ %replaceable.attlist; [
+<!ATTLIST Replaceable
+ --
+ Class: Type of information the element represents; no
+ default
+ --
+ Class (Command
+ |Function
+ |Option
+ |Parameter) #IMPLIED
+ %common.attrib;
+ %replaceable.role.attrib;
+ %local.replaceable.attrib;
+>
+<!--end of replaceable.attlist-->]]>
+<!--end of replaceable.module-->]]>
+
+<!ENTITY % returnvalue.module "INCLUDE">
+<![ %returnvalue.module; [
+<!ENTITY % local.returnvalue.attrib "">
+<!ENTITY % returnvalue.role.attrib "%role.attrib;">
+
+<!ENTITY % returnvalue.element "INCLUDE">
+<![ %returnvalue.element; [
+<!ELEMENT ReturnValue - - ((%smallcptr.char.mix;)+)>
+<!--end of returnvalue.element-->]]>
+
+<!ENTITY % returnvalue.attlist "INCLUDE">
+<![ %returnvalue.attlist; [
+<!ATTLIST ReturnValue
+ %common.attrib;
+ %returnvalue.role.attrib;
+ %local.returnvalue.attrib;
+>
+<!--end of returnvalue.attlist-->]]>
+<!--end of returnvalue.module-->]]>
+
+<!ENTITY % sgmltag.module "INCLUDE">
+<![ %sgmltag.module; [
+<!ENTITY % local.sgmltag.attrib "">
+<!ENTITY % sgmltag.role.attrib "%role.attrib;">
+
+<!ENTITY % sgmltag.element "INCLUDE">
+<![ %sgmltag.element; [
+<!ELEMENT SGMLTag - - ((%smallcptr.char.mix;)+)>
+<!--end of sgmltag.element-->]]>
+
+<!ENTITY % sgmltag.attlist "INCLUDE">
+<![ %sgmltag.attlist; [
+<!ATTLIST SGMLTag
+ --
+ Class: Type of SGML construct the element names; no default
+ --
+ Class (Attribute
+ |AttValue
+ |Element
+ |EndTag
+ |EmptyTag
+ |GenEntity
+ |NumCharRef
+ |ParamEntity
+ |PI
+ |XMLPI
+ |StartTag
+ |SGMLComment) #IMPLIED
+ %common.attrib;
+ %sgmltag.role.attrib;
+ %local.sgmltag.attrib;
+>
+<!--end of sgmltag.attlist-->]]>
+<!--end of sgmltag.module-->]]>
+
+<!ENTITY % structfield.module "INCLUDE">
+<![ %structfield.module; [
+<!ENTITY % local.structfield.attrib "">
+<!ENTITY % structfield.role.attrib "%role.attrib;">
+
+<!ENTITY % structfield.element "INCLUDE">
+<![ %structfield.element; [
+<!ELEMENT StructField - - ((%smallcptr.char.mix;)+)>
+<!--end of structfield.element-->]]>
+
+<!ENTITY % structfield.attlist "INCLUDE">
+<![ %structfield.attlist; [
+<!ATTLIST StructField
+ %common.attrib;
+ %structfield.role.attrib;
+ %local.structfield.attrib;
+>
+<!--end of structfield.attlist-->]]>
+<!--end of structfield.module-->]]>
+
+<!ENTITY % structname.module "INCLUDE">
+<![ %structname.module; [
+<!ENTITY % local.structname.attrib "">
+<!ENTITY % structname.role.attrib "%role.attrib;">
+
+<!ENTITY % structname.element "INCLUDE">
+<![ %structname.element; [
+<!ELEMENT StructName - - ((%smallcptr.char.mix;)+)>
+<!--end of structname.element-->]]>
+
+<!ENTITY % structname.attlist "INCLUDE">
+<![ %structname.attlist; [
+<!ATTLIST StructName
+ %common.attrib;
+ %structname.role.attrib;
+ %local.structname.attrib;
+>
+<!--end of structname.attlist-->]]>
+<!--end of structname.module-->]]>
+
+<!ENTITY % symbol.module "INCLUDE">
+<![ %symbol.module; [
+<!ENTITY % local.symbol.attrib "">
+<!ENTITY % symbol.role.attrib "%role.attrib;">
+
+<!ENTITY % symbol.element "INCLUDE">
+<![ %symbol.element; [
+<!ELEMENT Symbol - - ((%smallcptr.char.mix;)+)>
+<!--end of symbol.element-->]]>
+
+<!ENTITY % symbol.attlist "INCLUDE">
+<![ %symbol.attlist; [
+<!ATTLIST Symbol
+ --
+ Class: Type of symbol; no default
+ --
+ Class (Limit) #IMPLIED
+ %common.attrib;
+ %symbol.role.attrib;
+ %local.symbol.attrib;
+>
+<!--end of symbol.attlist-->]]>
+<!--end of symbol.module-->]]>
+
+<!ENTITY % systemitem.module "INCLUDE">
+<![ %systemitem.module; [
+<!ENTITY % local.systemitem.attrib "">
+<!ENTITY % systemitem.role.attrib "%role.attrib;">
+
+<!ENTITY % systemitem.element "INCLUDE">
+<![ %systemitem.element; [
+<!ELEMENT SystemItem - - ((%smallcptr.char.mix; | Acronym)*)>
+<!--end of systemitem.element-->]]>
+
+<!ENTITY % systemitem.attlist "INCLUDE">
+<![ %systemitem.attlist; [
+<!ATTLIST SystemItem
+ --
+ Class: Type of system item the element names; no default
+ --
+ Class (Constant
+ |GroupName
+ |Library
+ |Macro
+ |OSname
+ |Resource
+ |SystemName
+ |UserName) #IMPLIED
+ %moreinfo.attrib;
+ %common.attrib;
+ %systemitem.role.attrib;
+ %local.systemitem.attrib;
+>
+<!--end of systemitem.attlist-->]]>
+<!--end of systemitem.module-->]]>
+
+
+<!ENTITY % token.module "INCLUDE">
+<![ %token.module; [
+<!ENTITY % local.token.attrib "">
+<!ENTITY % token.role.attrib "%role.attrib;">
+
+<!ENTITY % token.element "INCLUDE">
+<![ %token.element; [
+<!ELEMENT Token - - ((%smallcptr.char.mix;)+)>
+<!--end of token.element-->]]>
+
+<!ENTITY % token.attlist "INCLUDE">
+<![ %token.attlist; [
+<!ATTLIST Token
+ %common.attrib;
+ %token.role.attrib;
+ %local.token.attrib;
+>
+<!--end of token.attlist-->]]>
+<!--end of token.module-->]]>
+
+<!ENTITY % type.module "INCLUDE">
+<![ %type.module; [
+<!ENTITY % local.type.attrib "">
+<!ENTITY % type.role.attrib "%role.attrib;">
+
+<!ENTITY % type.element "INCLUDE">
+<![ %type.element; [
+<!ELEMENT Type - - ((%smallcptr.char.mix;)+)>
+<!--end of type.element-->]]>
+
+<!ENTITY % type.attlist "INCLUDE">
+<![ %type.attlist; [
+<!ATTLIST Type
+ %common.attrib;
+ %type.role.attrib;
+ %local.type.attrib;
+>
+<!--end of type.attlist-->]]>
+<!--end of type.module-->]]>
+
+<!ENTITY % userinput.module "INCLUDE">
+<![ %userinput.module; [
+<!ENTITY % local.userinput.attrib "">
+<!ENTITY % userinput.role.attrib "%role.attrib;">
+
+<!ENTITY % userinput.element "INCLUDE">
+<![ %userinput.element; [
+<!ELEMENT UserInput - - ((%cptr.char.mix;)+)>
+<!--end of userinput.element-->]]>
+
+<!ENTITY % userinput.attlist "INCLUDE">
+<![ %userinput.attlist; [
+<!ATTLIST UserInput
+ %moreinfo.attrib;
+ %common.attrib;
+ %userinput.role.attrib;
+ %local.userinput.attrib;
+>
+<!--end of userinput.attlist-->]]>
+<!--end of userinput.module-->]]>
+
+<!-- General words and phrases ............................................ -->
+
+<!ENTITY % abbrev.module "INCLUDE">
+<![ %abbrev.module; [
+<!ENTITY % local.abbrev.attrib "">
+<!ENTITY % abbrev.role.attrib "%role.attrib;">
+
+<!ENTITY % abbrev.element "INCLUDE">
+<![ %abbrev.element; [
+<!ELEMENT Abbrev - - ((%word.char.mix;)+)>
+<!--end of abbrev.element-->]]>
+
+<!ENTITY % abbrev.attlist "INCLUDE">
+<![ %abbrev.attlist; [
+<!ATTLIST Abbrev
+ %common.attrib;
+ %abbrev.role.attrib;
+ %local.abbrev.attrib;
+>
+<!--end of abbrev.attlist-->]]>
+<!--end of abbrev.module-->]]>
+
+<!ENTITY % acronym.module "INCLUDE">
+<![ %acronym.module; [
+<!ENTITY % local.acronym.attrib "">
+<!ENTITY % acronym.role.attrib "%role.attrib;">
+
+<!ENTITY % acronym.element "INCLUDE">
+<![ %acronym.element; [
+<!ELEMENT Acronym - - ((%word.char.mix;)+) %acronym.exclusion;>
+<!--end of acronym.element-->]]>
+
+<!ENTITY % acronym.attlist "INCLUDE">
+<![ %acronym.attlist; [
+<!ATTLIST Acronym
+ %common.attrib;
+ %acronym.role.attrib;
+ %local.acronym.attrib;
+>
+<!--end of acronym.attlist-->]]>
+<!--end of acronym.module-->]]>
+
+<!ENTITY % citation.module "INCLUDE">
+<![ %citation.module; [
+<!ENTITY % local.citation.attrib "">
+<!ENTITY % citation.role.attrib "%role.attrib;">
+
+<!ENTITY % citation.element "INCLUDE">
+<![ %citation.element; [
+<!ELEMENT Citation - - ((%para.char.mix;)+)>
+<!--end of citation.element-->]]>
+
+<!ENTITY % citation.attlist "INCLUDE">
+<![ %citation.attlist; [
+<!ATTLIST Citation
+ %common.attrib;
+ %citation.role.attrib;
+ %local.citation.attrib;
+>
+<!--end of citation.attlist-->]]>
+<!--end of citation.module-->]]>
+
+<!ENTITY % citerefentry.module "INCLUDE">
+<![ %citerefentry.module; [
+<!ENTITY % local.citerefentry.attrib "">
+<!ENTITY % citerefentry.role.attrib "%role.attrib;">
+
+<!ENTITY % citerefentry.element "INCLUDE">
+<![ %citerefentry.element; [
+<!ELEMENT CiteRefEntry - - (RefEntryTitle, ManVolNum?)>
+<!--end of citerefentry.element-->]]>
+
+<!ENTITY % citerefentry.attlist "INCLUDE">
+<![ %citerefentry.attlist; [
+<!ATTLIST CiteRefEntry
+ %common.attrib;
+ %citerefentry.role.attrib;
+ %local.citerefentry.attrib;
+>
+<!--end of citerefentry.attlist-->]]>
+<!--end of citerefentry.module-->]]>
+
+<!ENTITY % refentrytitle.module "INCLUDE">
+<![ %refentrytitle.module; [
+<!ENTITY % local.refentrytitle.attrib "">
+<!ENTITY % refentrytitle.role.attrib "%role.attrib;">
+
+<!ENTITY % refentrytitle.element "INCLUDE">
+<![ %refentrytitle.element; [
+<!ELEMENT RefEntryTitle - O ((%para.char.mix;)+)>
+<!--end of refentrytitle.element-->]]>
+
+<!ENTITY % refentrytitle.attlist "INCLUDE">
+<![ %refentrytitle.attlist; [
+<!ATTLIST RefEntryTitle
+ %common.attrib;
+ %refentrytitle.role.attrib;
+ %local.refentrytitle.attrib;
+>
+<!--end of refentrytitle.attlist-->]]>
+<!--end of refentrytitle.module-->]]>
+
+<!ENTITY % manvolnum.module "INCLUDE">
+<![ %manvolnum.module; [
+<!ENTITY % local.manvolnum.attrib "">
+<!ENTITY % namvolnum.role.attrib "%role.attrib;">
+
+<!ENTITY % manvolnum.element "INCLUDE">
+<![ %manvolnum.element; [
+<!ELEMENT ManVolNum - O ((%word.char.mix;)+)>
+<!--end of manvolnum.element-->]]>
+
+<!ENTITY % manvolnum.attlist "INCLUDE">
+<![ %manvolnum.attlist; [
+<!ATTLIST ManVolNum
+ %common.attrib;
+ %namvolnum.role.attrib;
+ %local.manvolnum.attrib;
+>
+<!--end of manvolnum.attlist-->]]>
+<!--end of manvolnum.module-->]]>
+
+<!ENTITY % citetitle.module "INCLUDE">
+<![ %citetitle.module; [
+<!ENTITY % local.citetitle.attrib "">
+<!ENTITY % citetitle.role.attrib "%role.attrib;">
+
+<!ENTITY % citetitle.element "INCLUDE">
+<![ %citetitle.element; [
+<!ELEMENT CiteTitle - - ((%para.char.mix;)+)>
+<!--end of citetitle.element-->]]>
+
+<!ENTITY % citetitle.attlist "INCLUDE">
+<![ %citetitle.attlist; [
+<!ATTLIST CiteTitle
+ --
+ Pubwork: Genre of published work cited; no default
+ --
+ Pubwork (Article
+ |Book
+ |Chapter
+ |Part
+ |RefEntry
+ |Section
+ |Journal
+ |Series
+ |Set
+ |Manuscript) #IMPLIED
+ %common.attrib;
+ %citetitle.role.attrib;
+ %local.citetitle.attrib;
+>
+<!--end of citetitle.attlist-->]]>
+<!--end of citetitle.module-->]]>
+
+<!ENTITY % emphasis.module "INCLUDE">
+<![ %emphasis.module; [
+<!ENTITY % local.emphasis.attrib "">
+<!ENTITY % emphasis.role.attrib "%role.attrib;">
+
+<!ENTITY % emphasis.element "INCLUDE">
+<![ %emphasis.element; [
+<!ELEMENT Emphasis - - ((%para.char.mix;)+)>
+<!--end of emphasis.element-->]]>
+
+<!ENTITY % emphasis.attlist "INCLUDE">
+<![ %emphasis.attlist; [
+<!ATTLIST Emphasis
+ %common.attrib;
+ %emphasis.role.attrib;
+ %local.emphasis.attrib;
+>
+<!--end of emphasis.attlist-->]]>
+<!--end of emphasis.module-->]]>
+
+<!ENTITY % firstterm.module "INCLUDE">
+<![ %firstterm.module; [
+<!ENTITY % local.firstterm.attrib "">
+<!ENTITY % firstterm.role.attrib "%role.attrib;">
+
+<!ENTITY % firstterm.element "INCLUDE">
+<![ %firstterm.element; [
+<!ELEMENT FirstTerm - - ((%word.char.mix;)+)>
+<!--end of firstterm.element-->]]>
+
+<!ENTITY % firstterm.attlist "INCLUDE">
+<![ %firstterm.attlist; [
+<!ATTLIST FirstTerm
+ %linkend.attrib; --to GlossEntry or other explanation--
+ %common.attrib;
+ %firstterm.role.attrib;
+ %local.firstterm.attrib;
+>
+<!--end of firstterm.attlist-->]]>
+<!--end of firstterm.module-->]]>
+
+<!ENTITY % foreignphrase.module "INCLUDE">
+<![ %foreignphrase.module; [
+<!ENTITY % local.foreignphrase.attrib "">
+<!ENTITY % foreignphrase.role.attrib "%role.attrib;">
+
+<!ENTITY % foreignphrase.element "INCLUDE">
+<![ %foreignphrase.element; [
+<!ELEMENT ForeignPhrase - - ((%para.char.mix;)+)>
+<!--end of foreignphrase.element-->]]>
+
+<!ENTITY % foreignphrase.attlist "INCLUDE">
+<![ %foreignphrase.attlist; [
+<!ATTLIST ForeignPhrase
+ %common.attrib;
+ %foreignphrase.role.attrib;
+ %local.foreignphrase.attrib;
+>
+<!--end of foreignphrase.attlist-->]]>
+<!--end of foreignphrase.module-->]]>
+
+<!ENTITY % glossterm.module "INCLUDE">
+<![ %glossterm.module; [
+<!ENTITY % local.glossterm.attrib "">
+<!ENTITY % glossterm.role.attrib "%role.attrib;">
+
+<!ENTITY % glossterm.element "INCLUDE">
+<![ %glossterm.element; [
+<!ELEMENT GlossTerm - O ((%para.char.mix;)+) %glossterm.exclusion;>
+<!--end of glossterm.element-->]]>
+
+<!ENTITY % glossterm.attlist "INCLUDE">
+<![ %glossterm.attlist; [
+<!ATTLIST GlossTerm
+ %linkend.attrib; --to GlossEntry if Glossterm used in text--
+ --
+ BaseForm: Provides the form of GlossTerm to be used
+ for indexing
+ --
+ BaseForm CDATA #IMPLIED
+ %common.attrib;
+ %glossterm.role.attrib;
+ %local.glossterm.attrib;
+>
+<!--end of glossterm.attlist-->]]>
+<!--end of glossterm.module-->]]>
+
+<!ENTITY % phrase.module "INCLUDE">
+<![ %phrase.module; [
+<!ENTITY % local.phrase.attrib "">
+<!ENTITY % phrase.role.attrib "%role.attrib;">
+
+<!ENTITY % phrase.element "INCLUDE">
+<![ %phrase.element; [
+<!ELEMENT Phrase - - ((%para.char.mix;)+)>
+<!--end of phrase.element-->]]>
+
+<!ENTITY % phrase.attlist "INCLUDE">
+<![ %phrase.attlist; [
+<!ATTLIST Phrase
+ %common.attrib;
+ %phrase.role.attrib;
+ %local.phrase.attrib;
+>
+<!--end of phrase.attlist-->]]>
+<!--end of phrase.module-->]]>
+
+<!ENTITY % quote.module "INCLUDE">
+<![ %quote.module; [
+<!ENTITY % local.quote.attrib "">
+<!ENTITY % quote.role.attrib "%role.attrib;">
+
+<!ENTITY % quote.element "INCLUDE">
+<![ %quote.element; [
+<!ELEMENT Quote - - ((%para.char.mix;)+)>
+<!--end of quote.element-->]]>
+
+<!ENTITY % quote.attlist "INCLUDE">
+<![ %quote.attlist; [
+<!ATTLIST Quote
+ %common.attrib;
+ %quote.role.attrib;
+ %local.quote.attrib;
+>
+<!--end of quote.attlist-->]]>
+<!--end of quote.module-->]]>
+
+<!ENTITY % ssscript.module "INCLUDE">
+<![ %ssscript.module; [
+<!ENTITY % local.ssscript.attrib "">
+<!ENTITY % ssscript.role.attrib "%role.attrib;">
+
+<!ENTITY % ssscript.elements "INCLUDE">
+<![ %ssscript.elements [
+<!ELEMENT (Subscript | Superscript) - - ((#PCDATA
+ | %link.char.class;
+ | Emphasis
+ | Replaceable
+ | Symbol
+ | InlineGraphic
+ | InlineMediaObject
+ | %base.char.class;
+ | %other.char.class;)+)
+ %ubiq.exclusion;>
+<!--end of ssscript.elements-->]]>
+
+<!ENTITY % ssscript.attlists "INCLUDE">
+<![ %ssscript.attlists; [
+<!ATTLIST (Subscript | Superscript)
+ %common.attrib;
+ %ssscript.role.attrib;
+ %local.ssscript.attrib;
+>
+<!--end of ssscript.attlists-->]]>
+<!--end of ssscript.module-->]]>
+
+<!ENTITY % trademark.module "INCLUDE">
+<![ %trademark.module; [
+<!ENTITY % local.trademark.attrib "">
+<!ENTITY % trademark.role.attrib "%role.attrib;">
+
+<!ENTITY % trademark.element "INCLUDE">
+<![ %trademark.element; [
+<!ELEMENT Trademark - - ((#PCDATA
+ | %link.char.class;
+ | %tech.char.class;
+ | %base.char.class;
+ | %other.char.class;
+ | InlineGraphic
+ | InlineMediaObject
+ | Emphasis)+)>
+<!--end of trademark.element-->]]>
+
+<!ENTITY % trademark.attlist "INCLUDE">
+<![ %trademark.attlist; [
+<!ATTLIST Trademark
+ --
+ Class: More precisely identifies the item the element names
+ --
+ Class (Service
+ |Trade
+ |Registered
+ |Copyright) Trade
+ %common.attrib;
+ %trademark.role.attrib;
+ %local.trademark.attrib;
+>
+<!--end of trademark.attlist-->]]>
+<!--end of trademark.module-->]]>
+
+<!ENTITY % wordasword.module "INCLUDE">
+<![ %wordasword.module; [
+<!ENTITY % local.wordasword.attrib "">
+<!ENTITY % wordasword.role.attrib "%role.attrib;">
+
+<!ENTITY % wordasword.element "INCLUDE">
+<![ %wordasword.element; [
+<!ELEMENT WordAsWord - - ((%word.char.mix;)+)>
+<!--end of wordasword.element-->]]>
+
+<!ENTITY % wordasword.attlist "INCLUDE">
+<![ %wordasword.attlist; [
+<!ATTLIST WordAsWord
+ %common.attrib;
+ %wordasword.role.attrib;
+ %local.wordasword.attrib;
+>
+<!--end of wordasword.attlist-->]]>
+<!--end of wordasword.module-->]]>
+
+<!-- Links and cross-references ........................................... -->
+
+<!ENTITY % link.module "INCLUDE">
+<![ %link.module; [
+<!ENTITY % local.link.attrib "">
+<!ENTITY % link.role.attrib "%role.attrib;">
+
+<!ENTITY % link.element "INCLUDE">
+<![ %link.element; [
+<!ELEMENT Link - - ((%para.char.mix;)+) %links.exclusion;>
+<!--end of link.element-->]]>
+
+<!ENTITY % link.attlist "INCLUDE">
+<![ %link.attlist; [
+<!ATTLIST Link
+ --
+ Endterm: ID of element containing text that is to be
+ fetched from elsewhere in the document to appear as
+ the content of this element
+ --
+ Endterm IDREF #IMPLIED
+ %linkendreq.attrib; --to linked-to object--
+ --
+ Type: Freely assignable parameter
+ --
+ Type CDATA #IMPLIED
+ %common.attrib;
+ %link.role.attrib;
+ %local.link.attrib;
+>
+<!--end of link.attlist-->]]>
+<!--end of link.module-->]]>
+
+<!ENTITY % olink.module "INCLUDE">
+<![ %olink.module; [
+<!ENTITY % local.olink.attrib "">
+<!ENTITY % olink.role.attrib "%role.attrib;">
+
+<!ENTITY % olink.element "INCLUDE">
+<![ %olink.element; [
+<!ELEMENT OLink - - ((%para.char.mix;)+) %links.exclusion;>
+<!--end of olink.element-->]]>
+
+<!ENTITY % olink.attlist "INCLUDE">
+<![ %olink.attlist; [
+<!ATTLIST OLink
+ --
+ TargetDocEnt: Name of an entity to be the target of the link
+ --
+ TargetDocEnt ENTITY #IMPLIED
+ --
+ LinkMode: ID of a ModeSpec containing instructions for
+ operating on the entity named by TargetDocEnt
+ --
+ LinkMode IDREF #IMPLIED
+ --
+ LocalInfo: Information that may be passed to ModeSpec
+ --
+ LocalInfo CDATA #IMPLIED
+ --
+ Type: Freely assignable parameter
+ --
+ Type CDATA #IMPLIED
+ %common.attrib;
+ %olink.role.attrib;
+ %local.olink.attrib;
+>
+<!--end of olink.attlist-->]]>
+<!--end of olink.module-->]]>
+
+<!ENTITY % ulink.module "INCLUDE">
+<![ %ulink.module; [
+<!ENTITY % local.ulink.attrib "">
+<!ENTITY % ulink.role.attrib "%role.attrib;">
+
+<!ENTITY % ulink.element "INCLUDE">
+<![ %ulink.element; [
+<!ELEMENT ULink - - ((%para.char.mix;)+) %links.exclusion;>
+<!--end of ulink.element-->]]>
+
+<!ENTITY % ulink.attlist "INCLUDE">
+<![ %ulink.attlist; [
+<!ATTLIST ULink
+ --
+ URL: uniform resource locator; the target of the ULink
+ --
+ URL CDATA #REQUIRED
+ --
+ Type: Freely assignable parameter
+ --
+ Type CDATA #IMPLIED
+ %common.attrib;
+ %ulink.role.attrib;
+ %local.ulink.attrib;
+>
+<!--end of ulink.attlist-->]]>
+<!--end of ulink.module-->]]>
+
+<!ENTITY % footnoteref.module "INCLUDE">
+<![ %footnoteref.module; [
+<!ENTITY % local.footnoteref.attrib "">
+<!ENTITY % footnoteref.role.attrib "%role.attrib;">
+
+<!ENTITY % footnoteref.element "INCLUDE">
+<![ %footnoteref.element; [
+<!ELEMENT FootnoteRef - O EMPTY>
+<!--end of footnoteref.element-->]]>
+
+<!ENTITY % footnoteref.attlist "INCLUDE">
+<![ %footnoteref.attlist; [
+<!ATTLIST FootnoteRef
+ %linkendreq.attrib; --to footnote content supplied elsewhere--
+ %label.attrib;
+ %common.attrib;
+ %footnoteref.role.attrib;
+ %local.footnoteref.attrib;
+>
+<!--end of footnoteref.attlist-->]]>
+<!--end of footnoteref.module-->]]>
+
+<!ENTITY % xref.module "INCLUDE">
+<![ %xref.module; [
+<!ENTITY % local.xref.attrib "">
+<!ENTITY % xref.role.attrib "%role.attrib;">
+
+<!ENTITY % xref.element "INCLUDE">
+<![ %xref.element; [
+<!ELEMENT XRef - O EMPTY>
+<!--end of xref.element-->]]>
+
+<!ENTITY % xref.attlist "INCLUDE">
+<![ %xref.attlist; [
+<!ATTLIST XRef
+ --
+ Endterm: ID of element containing text that is to be
+ fetched from elsewhere in the document to appear as
+ the content of this element
+ --
+ Endterm IDREF #IMPLIED
+ %linkendreq.attrib; --to linked-to object--
+ %common.attrib;
+ %xref.role.attrib;
+ %local.xref.attrib;
+>
+<!--end of xref.attlist-->]]>
+<!--end of xref.module-->]]>
+
+<!-- Ubiquitous elements .................................................. -->
+
+<!ENTITY % anchor.module "INCLUDE">
+<![ %anchor.module; [
+<!ENTITY % local.anchor.attrib "">
+<!ENTITY % anchor.role.attrib "%role.attrib;">
+
+<!ENTITY % anchor.element "INCLUDE">
+<![ %anchor.element; [
+<!ELEMENT Anchor - O EMPTY>
+<!--end of anchor.element-->]]>
+
+<!ENTITY % anchor.attlist "INCLUDE">
+<![ %anchor.attlist; [
+<!ATTLIST Anchor
+ %idreq.attrib; -- required --
+ %pagenum.attrib; --replaces Lang --
+ %remap.attrib;
+ %xreflabel.attrib;
+ %revisionflag.attrib;
+ %effectivity.attrib;
+ %anchor.role.attrib;
+ %local.anchor.attrib;
+>
+<!--end of anchor.attlist-->]]>
+<!--end of anchor.module-->]]>
+
+<!ENTITY % beginpage.module "INCLUDE">
+<![ %beginpage.module; [
+<!ENTITY % local.beginpage.attrib "">
+<!ENTITY % beginpage.role.attrib "%role.attrib;">
+
+<!ENTITY % beginpage.element "INCLUDE">
+<![ %beginpage.element; [
+<!ELEMENT BeginPage - O EMPTY>
+<!--end of beginpage.element-->]]>
+
+<!ENTITY % beginpage.attlist "INCLUDE">
+<![ %beginpage.attlist; [
+<!ATTLIST BeginPage
+ --
+ PageNum: Number of page that begins at this point
+ --
+ %pagenum.attrib;
+ %common.attrib;
+ %beginpage.role.attrib;
+ %local.beginpage.attrib;
+>
+<!--end of beginpage.attlist-->]]>
+<!--end of beginpage.module-->]]>
+
+<!-- IndexTerms appear in the text flow for generating or linking an
+ index. -->
+
+<!ENTITY % indexterm.content.module "INCLUDE">
+<![ %indexterm.content.module; [
+<!ENTITY % indexterm.module "INCLUDE">
+<![ %indexterm.module; [
+<!ENTITY % local.indexterm.attrib "">
+<!ENTITY % indexterm.role.attrib "%role.attrib;">
+
+<!ENTITY % indexterm.element "INCLUDE">
+<![ %indexterm.element; [
+<!ELEMENT IndexTerm - O (Primary, ((Secondary, ((Tertiary, (See|SeeAlso+)?)
+ | See | SeeAlso+)?) | See | SeeAlso+)?) %ubiq.exclusion;>
+<!--end of indexterm.element-->]]>
+
+<!ENTITY % indexterm.attlist "INCLUDE">
+<![ %indexterm.attlist; [
+<!ATTLIST IndexTerm
+ %pagenum.attrib;
+ --
+ Scope: Indicates which generated indices the IndexTerm
+ should appear in: Global (whole document set), Local (this
+ document only), or All (both)
+ --
+ Scope (All
+ |Global
+ |Local) #IMPLIED
+ --
+ Significance: Whether this IndexTerm is the most pertinent
+ of its series (Preferred) or not (Normal, the default)
+ --
+ Significance (Preferred
+ |Normal) Normal
+ --
+ Class: Indicates type of IndexTerm; default is Singular,
+ or EndOfRange if StartRef is supplied; StartOfRange value
+ must be supplied explicitly on starts of ranges
+ --
+ Class (Singular
+ |StartOfRange
+ |EndOfRange) #IMPLIED
+ --
+ StartRef: ID of the IndexTerm that starts the indexing
+ range ended by this IndexTerm
+ --
+ StartRef IDREF #CONREF
+ --
+ Zone: IDs of the elements to which the IndexTerm applies,
+ and indicates that the IndexTerm applies to those entire
+ elements rather than the point at which the IndexTerm
+ occurs
+ --
+ Zone IDREFS #IMPLIED
+ %common.attrib;
+ %indexterm.role.attrib;
+ %local.indexterm.attrib;
+>
+<!--end of indexterm.attlist-->]]>
+<!--end of indexterm.module-->]]>
+
+<!ENTITY % primsecter.module "INCLUDE">
+<![ %primsecter.module; [
+<!ENTITY % local.primsecter.attrib "">
+<!ENTITY % primsecter.role.attrib "%role.attrib;">
+
+<!ENTITY % primsecter.elements "INCLUDE">
+<![ %primsecter.elements; [
+<!ELEMENT (Primary | Secondary | Tertiary) - O ((%ndxterm.char.mix;)+)>
+<!--end of primsecter.elements-->]]>
+
+<!ENTITY % primsecter.attlists "INCLUDE">
+<![ %primsecter.attlists; [
+<!ENTITY % containing.attlist "INCLUDE">
+<![ %containing.attlist; [
+<!ATTLIST (Primary | Secondary | Tertiary)
+ --
+ SortAs: Alternate sort string for index sorting, e.g.,
+ "fourteen" for an element containing "14"
+ --
+ SortAs CDATA #IMPLIED
+ %common.attrib;
+ %primsecter.role.attrib;
+ %local.primsecter.attrib;
+>
+<!--end of containing.attlist-->]]>
+<!--end of primsecter.attlist-->]]>
+<!--end of primsecter.module-->]]>
+
+<!ENTITY % seeseealso.module "INCLUDE">
+<![ %seeseealso.module; [
+<!ENTITY % local.seeseealso.attrib "">
+<!ENTITY % seeseealso.role.attrib "%role.attrib;">
+
+<!ENTITY % seeseealso.elements "INCLUDE">
+<![ %seeseealso.elements [
+<!ELEMENT (See | SeeAlso) - O ((%ndxterm.char.mix;)+)>
+<!--end of seeseealso.elements-->]]>
+
+<!ENTITY % seeseealso.attlists "INCLUDE">
+<![ %seeseealso.attlists [
+<!ATTLIST (See | SeeAlso)
+ %common.attrib;
+ %seeseealso.role.attrib;
+ %local.seeseealso.attrib;
+>
+<!--end of seeseealso.attlists-->]]>
+<!--end of seeseealso.module-->]]>
+<!--end of indexterm.content.module-->]]>
+
+<!-- End of DocBook information pool module V4.1 .......................... -->
+<!-- ...................................................................... -->
diff --git a/docs/docbook/dbsgml/docbook.cat b/docs/docbook/dbsgml/docbook.cat
new file mode 100755
index 00000000000..0f285d0d751
--- /dev/null
+++ b/docs/docbook/dbsgml/docbook.cat
@@ -0,0 +1,63 @@
+ -- ...................................................................... --
+ -- Catalog data for DocBook V4.1 ........................................ --
+ -- File docbook.cat ..................................................... --
+
+ -- Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/.
+ --
+
+ -- This is the catalog data file for DocBook V4.1. It is provided as
+ a convenience in building your own catalog files. You need not use
+ the filenames listed here, and need not use the filename method of
+ identifying storage objects at all. See the documentation for
+ detailed information on the files associated with the DocBook DTD.
+ See SGML Open Technical Resolution 9401 for detailed information
+ on supplying and using catalog data.
+ --
+
+ -- ...................................................................... --
+ -- SGML declaration associated with DocBook ............................. --
+
+DTDDECL "-//OASIS//DTD DocBook V4.1//EN" "docbook.dcl"
+
+ -- ...................................................................... --
+ -- DocBook driver file .................................................. --
+
+PUBLIC "-//OASIS//DTD DocBook V4.1//EN" "docbook.dtd"
+
+ -- ...................................................................... --
+ -- DocBook modules ...................................................... --
+
+PUBLIC "-//USA-DOD//DTD Table Model 951010//EN" "cals-tbl.dtd"
+PUBLIC "-//OASIS//ELEMENTS DocBook Information Pool V4.1//EN" "dbpool.mod"
+PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.1//EN" "dbhier.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.1//EN" "dbgenent.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.1//EN" "dbnotn.mod"
+PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.1//EN" "dbcent.mod"
+
+ -- ...................................................................... --
+ -- ISO entity sets ...................................................... --
+
+PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN" "ISOdia"
+PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN" "ISOnum"
+PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN" "ISOpub"
+PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN" "ISOtech"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN" "ISOlat1"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN" "ISOlat2"
+PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN" "ISOgrk1"
+PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN" "ISOgrk2"
+PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN" "ISOgrk3"
+PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN" "ISOgrk4"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN" "ISOamsa"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN" "ISOamsb"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN" "ISOamsc"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN" "ISOamsn"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN" "ISOamso"
+PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN" "ISOamsr"
+PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN" "ISObox"
+PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN" "ISOcyr1"
+PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN" "ISOcyr2"
+
+ -- End of catalog data for DocBook V4.1 ................................. --
+ -- ...................................................................... --
diff --git a/docs/docbook/dbsgml/docbook.dcl b/docs/docbook/dbsgml/docbook.dcl
new file mode 100755
index 00000000000..c76de206cf4
--- /dev/null
+++ b/docs/docbook/dbsgml/docbook.dcl
@@ -0,0 +1,106 @@
+<!SGML "ISO 8879:1986"
+ -- ...................................................................... --
+ -- DocBook SGML declaration V4.1 ........................................ --
+ -- file docbook.dcl ..................................................... --
+
+CHARSET
+
+ BASESET
+ "ISO 646:1983//CHARSET International Reference Version (IRV)//ESC 2/5 4/0"
+ DESCSET
+ 0 9 UNUSED
+ 9 2 9
+ 11 2 UNUSED
+ 13 1 13
+ 14 18 UNUSED
+ 32 95 32
+ 127 1 UNUSED
+
+ BASESET
+ "ISO Registration Number 100//CHARSET ECMA-94 Right Part of Latin Alphabet Nr. 1//ESC 2/13 4/1"
+ DESCSET
+ 128 32 UNUSED
+ 160 96 32
+
+CAPACITY SGMLREF
+
+ TOTALCAP 99000000
+ ATTCAP 1000000
+ ATTCHCAP 1000000
+ AVGRPCAP 1000000
+ ELEMCAP 1000000
+ ENTCAP 1000000
+ ENTCHCAP 1000000
+ GRPCAP 1000000
+ IDCAP 32000000
+ IDREFCAP 32000000
+
+SCOPE DOCUMENT
+
+SYNTAX
+
+ SHUNCHAR CONTROLS 0 1 2 3 4 5 6 7 8 9
+ 10 11 12 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26 27 28 29
+ 30 31 127 128 129
+ 130 131 132 133 134 135 136 137 138 139
+ 140 141 142 143 144 145 146 147 148 149
+ 150 151 152 153 154 155 156 157 158 159
+
+ BASESET
+ "ISO 646:1983//CHARSET International Reference Version (IRV)//ESC 2/5 4/0"
+ DESCSET
+ 0 128 0
+
+ FUNCTION
+ RE 13
+ RS 10
+ SPACE 32
+ TAB SEPCHAR 9
+
+ NAMING
+ LCNMSTRT ""
+ UCNMSTRT ""
+ LCNMCHAR ".-_"
+ UCNMCHAR ".-_"
+ NAMECASE
+ GENERAL YES
+ ENTITY NO
+
+ DELIM
+ GENERAL SGMLREF
+ SHORTREF SGMLREF
+
+ NAMES SGMLREF
+
+ QUANTITY SGMLREF
+ ATTCNT 256
+ GRPCNT 253
+ GRPGTCNT 253
+ LITLEN 8092
+ NAMELEN 44
+ TAGLVL 100
+
+FEATURES
+
+ MINIMIZE
+ DATATAG NO
+ OMITTAG NO
+ RANK NO
+ SHORTTAG YES
+
+ LINK
+ SIMPLE NO
+ IMPLICIT NO
+ EXPLICIT NO
+
+ OTHER
+ CONCUR NO
+ SUBDOC NO
+ FORMAL YES
+
+APPINFO NONE
+
+ -- End of DocBook SGML declaration V4.1 ................................. --
+ -- ...................................................................... --
+>
diff --git a/docs/docbook/dbsgml/docbook.dtd b/docs/docbook/dbsgml/docbook.dtd
new file mode 100755
index 00000000000..59bff93816b
--- /dev/null
+++ b/docs/docbook/dbsgml/docbook.dtd
@@ -0,0 +1,117 @@
+<!-- ...................................................................... -->
+<!-- DocBook DTD V4.1 ..................................................... -->
+<!-- File docbook.dtd ..................................................... -->
+
+<!-- Copyright 1992-2000 HaL Computer Systems, Inc.,
+ O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
+ Corporation, and the Organization for the Advancement of
+ Structured Information Standards (OASIS).
+
+ $Id: docbook.dtd,v 1.1.2.1 2001/02/28 19:05:02 jerry Exp $
+
+ Permission to use, copy, modify and distribute the DocBook DTD and
+ its accompanying documentation for any purpose and without fee is
+ hereby granted in perpetuity, provided that the above copyright
+ notice and this paragraph appear in all copies. The copyright
+ holders make no representation about the suitability of the DTD for
+ any purpose. It is provided "as is" without expressed or implied
+ warranty.
+
+ If you modify the DocBook DTD in any way, except for declaring and
+ referencing additional sets of general entities and declaring
+ additional notations, label your DTD as a variant of DocBook. See
+ the maintenance documentation for more information.
+
+ Please direct all questions, bug reports, or suggestions for
+ changes to the docbook@lists.oasis-open.org mailing list. For more
+ information, see http://www.oasis-open.org/docbook/.
+-->
+
+<!-- ...................................................................... -->
+
+<!-- This is the driver file for V4.1 of the DocBook DTD.
+ Please use the following formal public identifier to identify it:
+
+ "-//OASIS//DTD DocBook V4.1//EN"
+
+ For example, if your document's top-level element is Book, and
+ you are using DocBook directly, use the FPI in the DOCTYPE
+ declaration:
+
+ <!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [...]>
+
+ Or, if you have a higher-level driver file that customizes DocBook,
+ use the FPI in the parameter entity declaration:
+
+ <!ENTITY % DocBookDTD PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+ %DocBookDTD;
+
+ The DocBook DTD is accompanied by an SGML declaration.
+
+ See the documentation for detailed information on the parameter
+ entity and module scheme used in DocBook, customizing DocBook and
+ planning for interchange, and changes made since the last release
+ of DocBook.
+-->
+
+<!-- ...................................................................... -->
+<!-- Notation declarations ................................................ -->
+
+<!ENTITY % dbnotn.module "INCLUDE">
+<![ %dbnotn.module; [
+<!ENTITY % dbnotn PUBLIC
+"-//OASIS//ENTITIES DocBook Notations V4.1//EN">
+%dbnotn;
+<!--end of dbnotn.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- ISO character entity sets ............................................ -->
+
+<!ENTITY % dbcent.module "INCLUDE">
+<![ %dbcent.module; [
+<!ENTITY euro SDATA "[euro ]"><!-- euro sign, U+20AC NEW -->
+<!ENTITY % dbcent PUBLIC
+"-//OASIS//ENTITIES DocBook Character Entities V4.1//EN">
+%dbcent;
+<!--end of dbcent.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- DTD modules .......................................................... -->
+
+<!-- Information pool .............. -->
+
+<!ENTITY % dbpool.module "INCLUDE">
+<![ %dbpool.module; [
+<!ENTITY % dbpool PUBLIC
+"-//OASIS//ELEMENTS DocBook Information Pool V4.1//EN">
+%dbpool;
+<!--end of dbpool.module-->]]>
+
+<!-- Redeclaration placeholder ..... -->
+
+<!ENTITY % intermod.redecl.module "IGNORE">
+<![ %intermod.redecl.module; [
+%rdbmods;
+<!--end of intermod.redecl.module-->]]>
+
+<!-- Document hierarchy ............ -->
+
+<!ENTITY % dbhier.module "INCLUDE">
+<![ %dbhier.module; [
+<!ENTITY % dbhier PUBLIC
+"-//OASIS//ELEMENTS DocBook Document Hierarchy V4.1//EN">
+%dbhier;
+<!--end of dbhier.module-->]]>
+
+<!-- ...................................................................... -->
+<!-- Other general entities ............................................... -->
+
+<!ENTITY % dbgenent.module "INCLUDE">
+<![ %dbgenent.module; [
+<!ENTITY % dbgenent PUBLIC
+"-//OASIS//ENTITIES DocBook Additional General Entities V4.1//EN">
+%dbgenent;
+<!--end of dbgenent.module-->]]>
+
+<!-- End of DocBook DTD V4.1 .............................................. -->
+<!-- ...................................................................... -->
diff --git a/docs/docbook/dbsgml/ent/ISOamsa b/docs/docbook/dbsgml/ent/ISOamsa
new file mode 100755
index 00000000000..b77154cb024
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamsa
@@ -0,0 +1,66 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamsa PUBLIC
+ "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN">
+ %ISOamsa;
+-->
+<!ENTITY cularr SDATA "[cularr]"--/curvearrowleft A: left curved arrow -->
+<!ENTITY curarr SDATA "[curarr]"--/curvearrowright A: rt curved arrow -->
+<!ENTITY dArr SDATA "[dArr ]"--/Downarrow A: down dbl arrow -->
+<!ENTITY darr2 SDATA "[darr2 ]"--/downdownarrows A: two down arrows -->
+<!ENTITY dharl SDATA "[dharl ]"--/downleftharpoon A: dn harpoon-left -->
+<!ENTITY dharr SDATA "[dharr ]"--/downrightharpoon A: down harpoon-rt -->
+<!ENTITY lAarr SDATA "[lAarr ]"--/Lleftarrow A: left triple arrow -->
+<!ENTITY Larr SDATA "[Larr ]"--/twoheadleftarrow A:-->
+<!ENTITY larr2 SDATA "[larr2 ]"--/leftleftarrows A: two left arrows -->
+<!ENTITY larrhk SDATA "[larrhk]"--/hookleftarrow A: left arrow-hooked -->
+<!ENTITY larrlp SDATA "[larrlp]"--/looparrowleft A: left arrow-looped -->
+<!ENTITY larrtl SDATA "[larrtl]"--/leftarrowtail A: left arrow-tailed -->
+<!ENTITY lhard SDATA "[lhard ]"--/leftharpoondown A: l harpoon-down -->
+<!ENTITY lharu SDATA "[lharu ]"--/leftharpoonup A: left harpoon-up -->
+<!ENTITY hArr SDATA "[hArr ]"--/Leftrightarrow A: l&r dbl arrow -->
+<!ENTITY harr SDATA "[harr ]"--/leftrightarrow A: l&r arrow -->
+<!ENTITY lrarr2 SDATA "[lrarr2]"--/leftrightarrows A: l arr over r arr -->
+<!ENTITY rlarr2 SDATA "[rlarr2]"--/rightleftarrows A: r arr over l arr -->
+<!ENTITY harrw SDATA "[harrw ]"--/leftrightsquigarrow A: l&r arr-wavy -->
+<!ENTITY rlhar2 SDATA "[rlhar2]"--/rightleftharpoons A: r harp over l -->
+<!ENTITY lrhar2 SDATA "[lrhar2]"--/leftrightharpoons A: l harp over r -->
+<!ENTITY lsh SDATA "[lsh ]"--/Lsh A:-->
+<!ENTITY map SDATA "[map ]"--/mapsto A:-->
+<!ENTITY mumap SDATA "[mumap ]"--/multimap A:-->
+<!ENTITY nearr SDATA "[nearr ]"--/nearrow A: NE pointing arrow -->
+<!ENTITY nlArr SDATA "[nlArr ]"--/nLeftarrow A: not implied by -->
+<!ENTITY nlarr SDATA "[nlarr ]"--/nleftarrow A: not left arrow -->
+<!ENTITY nhArr SDATA "[nhArr ]"--/nLeftrightarrow A: not l&r dbl arr -->
+<!ENTITY nharr SDATA "[nharr ]"--/nleftrightarrow A: not l&r arrow -->
+<!ENTITY nrarr SDATA "[nrarr ]"--/nrightarrow A: not right arrow -->
+<!ENTITY nrArr SDATA "[nrArr ]"--/nRightarrow A: not implies -->
+<!ENTITY nwarr SDATA "[nwarr ]"--/nwarrow A: NW pointing arrow -->
+<!ENTITY olarr SDATA "[olarr ]"--/circlearrowleft A: l arr in circle -->
+<!ENTITY orarr SDATA "[orarr ]"--/circlearrowright A: r arr in circle -->
+<!ENTITY rAarr SDATA "[rAarr ]"--/Rrightarrow A: right triple arrow -->
+<!ENTITY Rarr SDATA "[Rarr ]"--/twoheadrightarrow A:-->
+<!ENTITY rarr2 SDATA "[rarr2 ]"--/rightrightarrows A: two rt arrows -->
+<!ENTITY rarrhk SDATA "[rarrhk]"--/hookrightarrow A: rt arrow-hooked -->
+<!ENTITY rarrlp SDATA "[rarrlp]"--/looparrowright A: rt arrow-looped -->
+<!ENTITY rarrtl SDATA "[rarrtl]"--/rightarrowtail A: rt arrow-tailed -->
+<!ENTITY rarrw SDATA "[rarrw ]"--/squigarrowright A: rt arrow-wavy -->
+<!ENTITY rhard SDATA "[rhard ]"--/rightharpoondown A: rt harpoon-down -->
+<!ENTITY rharu SDATA "[rharu ]"--/rightharpoonup A: rt harpoon-up -->
+<!ENTITY rsh SDATA "[rsh ]"--/Rsh A:-->
+<!ENTITY drarr SDATA "[drarr ]"--/searrow A: downward rt arrow -->
+<!ENTITY dlarr SDATA "[dlarr ]"--/swarrow A: downward l arrow -->
+<!ENTITY uArr SDATA "[uArr ]"--/Uparrow A: up dbl arrow -->
+<!ENTITY uarr2 SDATA "[uarr2 ]"--/upuparrows A: two up arrows -->
+<!ENTITY vArr SDATA "[vArr ]"--/Updownarrow A: up&down dbl arrow -->
+<!ENTITY varr SDATA "[varr ]"--/updownarrow A: up&down arrow -->
+<!ENTITY uharl SDATA "[uharl ]"--/upleftharpoon A: up harpoon-left -->
+<!ENTITY uharr SDATA "[uharr ]"--/uprightharpoon A: up harp-r-->
+<!ENTITY xlArr SDATA "[xlArr ]"--/Longleftarrow A: long l dbl arrow -->
+<!ENTITY xhArr SDATA "[xhArr ]"--/Longleftrightarrow A: long l&r dbl arr-->
+<!ENTITY xharr SDATA "[xharr ]"--/longleftrightarrow A: long l&r arr -->
+<!ENTITY xrArr SDATA "[xrArr ]"--/Longrightarrow A: long rt dbl arr -->
diff --git a/docs/docbook/dbsgml/ent/ISOamsb b/docs/docbook/dbsgml/ent/ISOamsb
new file mode 100755
index 00000000000..43944a732fb
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamsb
@@ -0,0 +1,52 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamsb PUBLIC
+ "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN">
+ %ISOamsb;
+-->
+<!ENTITY amalg SDATA "[amalg ]"--/amalg B: amalgamation or coproduct-->
+<!ENTITY Barwed SDATA "[Barwed]"--/doublebarwedge B: log and, dbl bar-->
+<!ENTITY barwed SDATA "[barwed]"--/barwedge B: logical and, bar above-->
+<!ENTITY Cap SDATA "[Cap ]"--/Cap /doublecap B: dbl intersection-->
+<!ENTITY Cup SDATA "[Cup ]"--/Cup /doublecup B: dbl union-->
+<!ENTITY cuvee SDATA "[cuvee ]"--/curlyvee B: curly logical or-->
+<!ENTITY cuwed SDATA "[cuwed ]"--/curlywedge B: curly logical and-->
+<!ENTITY diam SDATA "[diam ]"--/diamond B: open diamond-->
+<!ENTITY divonx SDATA "[divonx]"--/divideontimes B: division on times-->
+<!ENTITY intcal SDATA "[intcal]"--/intercal B: intercal-->
+<!ENTITY lthree SDATA "[lthree]"--/leftthreetimes B:-->
+<!ENTITY ltimes SDATA "[ltimes]"--/ltimes B: times sign, left closed-->
+<!ENTITY minusb SDATA "[minusb]"--/boxminus B: minus sign in box-->
+<!ENTITY oast SDATA "[oast ]"--/circledast B: asterisk in circle-->
+<!ENTITY ocir SDATA "[ocir ]"--/circledcirc B: open dot in circle-->
+<!ENTITY odash SDATA "[odash ]"--/circleddash B: hyphen in circle-->
+<!ENTITY odot SDATA "[odot ]"--/odot B: middle dot in circle-->
+<!ENTITY ominus SDATA "[ominus]"--/ominus B: minus sign in circle-->
+<!ENTITY oplus SDATA "[oplus ]"--/oplus B: plus sign in circle-->
+<!ENTITY osol SDATA "[osol ]"--/oslash B: solidus in circle-->
+<!ENTITY otimes SDATA "[otimes]"--/otimes B: multiply sign in circle-->
+<!ENTITY plusb SDATA "[plusb ]"--/boxplus B: plus sign in box-->
+<!ENTITY plusdo SDATA "[plusdo]"--/dotplus B: plus sign, dot above-->
+<!ENTITY rthree SDATA "[rthree]"--/rightthreetimes B:-->
+<!ENTITY rtimes SDATA "[rtimes]"--/rtimes B: times sign, right closed-->
+<!ENTITY sdot SDATA "[sdot ]"--/cdot B: small middle dot-->
+<!ENTITY sdotb SDATA "[sdotb ]"--/dotsquare /boxdot B: small dot in box-->
+<!ENTITY setmn SDATA "[setmn ]"--/setminus B: reverse solidus-->
+<!ENTITY sqcap SDATA "[sqcap ]"--/sqcap B: square intersection-->
+<!ENTITY sqcup SDATA "[sqcup ]"--/sqcup B: square union-->
+<!ENTITY ssetmn SDATA "[ssetmn]"--/smallsetminus B: sm reverse solidus-->
+<!ENTITY sstarf SDATA "[sstarf]"--/star B: small star, filled-->
+<!ENTITY timesb SDATA "[timesb]"--/boxtimes B: multiply sign in box-->
+<!ENTITY top SDATA "[top ]"--/top B: inverted perpendicular-->
+<!ENTITY uplus SDATA "[uplus ]"--/uplus B: plus sign in union-->
+<!ENTITY wreath SDATA "[wreath]"--/wr B: wreath product-->
+<!ENTITY xcirc SDATA "[xcirc ]"--/bigcirc B: large circle-->
+<!ENTITY xdtri SDATA "[xdtri ]"--/bigtriangledown B: big dn tri, open-->
+<!ENTITY xutri SDATA "[xutri ]"--/bigtriangleup B: big up tri, open-->
+<!ENTITY coprod SDATA "[coprod]"--/coprod L: coproduct operator-->
+<!ENTITY prod SDATA "[prod ]"--/prod L: product operator-->
+<!ENTITY sum SDATA "[sum ]"--/sum L: summation operator-->
diff --git a/docs/docbook/dbsgml/ent/ISOamsc b/docs/docbook/dbsgml/ent/ISOamsc
new file mode 100755
index 00000000000..06222d58cf4
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamsc
@@ -0,0 +1,20 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamsc PUBLIC
+ "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN">
+ %ISOamsc;
+-->
+<!ENTITY rceil SDATA "[rceil ]"--/rceil C: right ceiling-->
+<!ENTITY rfloor SDATA "[rfloor]"--/rfloor C: right floor-->
+<!ENTITY rpargt SDATA "[rpargt]"--/rightparengtr C: right paren, gt-->
+<!ENTITY urcorn SDATA "[urcorn]"--/urcorner C: upper right corner-->
+<!ENTITY drcorn SDATA "[drcorn]"--/lrcorner C: downward right corner-->
+<!ENTITY lceil SDATA "[lceil ]"--/lceil O: left ceiling-->
+<!ENTITY lfloor SDATA "[lfloor]"--/lfloor O: left floor-->
+<!ENTITY lpargt SDATA "[lpargt]"--/leftparengtr O: left parenthesis, gt-->
+<!ENTITY ulcorn SDATA "[ulcorn]"--/ulcorner O: upper left corner-->
+<!ENTITY dlcorn SDATA "[dlcorn]"--/llcorner O: downward left corner-->
diff --git a/docs/docbook/dbsgml/ent/ISOamsn b/docs/docbook/dbsgml/ent/ISOamsn
new file mode 100755
index 00000000000..0c8327a3267
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamsn
@@ -0,0 +1,70 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamsn PUBLIC
+ "ISO 8879:1986//ENTITIES
+ Added Math Symbols: Negated Relations//EN">
+ %ISOamsn;
+-->
+<!ENTITY gnap SDATA "[gnap ]"--/gnapprox N: greater, not approximate-->
+<!ENTITY gne SDATA "[gne ]"--/gneq N: greater, not equals-->
+<!ENTITY gnE SDATA "[gnE ]"--/gneqq N: greater, not dbl equals-->
+<!ENTITY gnsim SDATA "[gnsim ]"--/gnsim N: greater, not similar-->
+<!ENTITY gvnE SDATA "[gvnE ]"--/gvertneqq N: gt, vert, not dbl eq-->
+<!ENTITY lnap SDATA "[lnap ]"--/lnapprox N: less, not approximate-->
+<!ENTITY lnE SDATA "[lnE ]"--/lneqq N: less, not double equals-->
+<!ENTITY lne SDATA "[lne ]"--/lneq N: less, not equals-->
+<!ENTITY lnsim SDATA "[lnsim ]"--/lnsim N: less, not similar-->
+<!ENTITY lvnE SDATA "[lvnE ]"--/lvertneqq N: less, vert, not dbl eq-->
+<!ENTITY nap SDATA "[nap ]"--/napprox N: not approximate-->
+<!ENTITY ncong SDATA "[ncong ]"--/ncong N: not congruent with-->
+<!ENTITY nequiv SDATA "[nequiv]"--/nequiv N: not identical with-->
+<!ENTITY ngE SDATA "[ngE ]"--/ngeqq N: not greater, dbl equals-->
+<!ENTITY nge SDATA "[nge ]"--/ngeq N: not greater-than-or-equal-->
+<!ENTITY nges SDATA "[nges ]"--/ngeqslant N: not gt-or-eq, slanted-->
+<!ENTITY ngt SDATA "[ngt ]"--/ngtr N: not greater-than-->
+<!ENTITY nle SDATA "[nle ]"--/nleq N: not less-than-or-equal-->
+<!ENTITY nlE SDATA "[nlE ]"--/nleqq N: not less, dbl equals-->
+<!ENTITY nles SDATA "[nles ]"--/nleqslant N: not less-or-eq, slant-->
+<!ENTITY nlt SDATA "[nlt ]"--/nless N: not less-than-->
+<!ENTITY nltri SDATA "[nltri ]"--/ntriangleleft N: not left triangle-->
+<!ENTITY nltrie SDATA "[nltrie]"--/ntrianglelefteq N: not l tri, eq-->
+<!ENTITY nmid SDATA "[nmid ]"--/nmid-->
+<!ENTITY npar SDATA "[npar ]"--/nparallel N: not parallel-->
+<!ENTITY npr SDATA "[npr ]"--/nprec N: not precedes-->
+<!ENTITY npre SDATA "[npre ]"--/npreceq N: not precedes, equals-->
+<!ENTITY nrtri SDATA "[nrtri ]"--/ntriangleright N: not rt triangle-->
+<!ENTITY nrtrie SDATA "[nrtrie]"--/ntrianglerighteq N: not r tri, eq-->
+<!ENTITY nsc SDATA "[nsc ]"--/nsucc N: not succeeds-->
+<!ENTITY nsce SDATA "[nsce ]"--/nsucceq N: not succeeds, equals-->
+<!ENTITY nsim SDATA "[nsim ]"--/nsim N: not similar-->
+<!ENTITY nsime SDATA "[nsime ]"--/nsimeq N: not similar, equals-->
+<!ENTITY nsmid SDATA "[nsmid ]"--/nshortmid-->
+<!ENTITY nspar SDATA "[nspar ]"--/nshortparallel N: not short par-->
+<!ENTITY nsub SDATA "[nsub ]"--/nsubset N: not subset-->
+<!ENTITY nsube SDATA "[nsube ]"--/nsubseteq N: not subset, equals-->
+<!ENTITY nsubE SDATA "[nsubE ]"--/nsubseteqq N: not subset, dbl eq-->
+<!ENTITY nsup SDATA "[nsup ]"--/nsupset N: not superset-->
+<!ENTITY nsupE SDATA "[nsupE ]"--/nsupseteqq N: not superset, dbl eq-->
+<!ENTITY nsupe SDATA "[nsupe ]"--/nsupseteq N: not superset, equals-->
+<!ENTITY nvdash SDATA "[nvdash]"--/nvdash N: not vertical, dash-->
+<!ENTITY nvDash SDATA "[nvDash]"--/nvDash N: not vertical, dbl dash-->
+<!ENTITY nVDash SDATA "[nVDash]"--/nVDash N: not dbl vert, dbl dash-->
+<!ENTITY nVdash SDATA "[nVdash]"--/nVdash N: not dbl vertical, dash-->
+<!ENTITY prnap SDATA "[prnap ]"--/precnapprox N: precedes, not approx-->
+<!ENTITY prnE SDATA "[prnE ]"--/precneqq N: precedes, not dbl eq-->
+<!ENTITY prnsim SDATA "[prnsim]"--/precnsim N: precedes, not similar-->
+<!ENTITY scnap SDATA "[scnap ]"--/succnapprox N: succeeds, not approx-->
+<!ENTITY scnE SDATA "[scnE ]"--/succneqq N: succeeds, not dbl eq-->
+<!ENTITY scnsim SDATA "[scnsim]"--/succnsim N: succeeds, not similar-->
+<!ENTITY subne SDATA "[subne ]"--/subsetneq N: subset, not equals-->
+<!ENTITY subnE SDATA "[subnE ]"--/subsetneqq N: subset, not dbl eq-->
+<!ENTITY supne SDATA "[supne ]"--/supsetneq N: superset, not equals-->
+<!ENTITY supnE SDATA "[supnE ]"--/supsetneqq N: superset, not dbl eq-->
+<!ENTITY vsubnE SDATA "[vsubnE]"--/subsetneqq N: subset not dbl eq, var-->
+<!ENTITY vsubne SDATA "[vsubne]"--/subsetneq N: subset, not eq, var-->
+<!ENTITY vsupne SDATA "[vsupne]"--/supsetneq N: superset, not eq, var-->
+<!ENTITY vsupnE SDATA "[vsupnE]"--/supsetneqq N: super not dbl eq, var-->
diff --git a/docs/docbook/dbsgml/ent/ISOamso b/docs/docbook/dbsgml/ent/ISOamso
new file mode 100755
index 00000000000..ad9b329e54d
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamso
@@ -0,0 +1,29 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamso PUBLIC
+ "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN">
+ %ISOamso;
+-->
+<!ENTITY ang SDATA "[ang ]"--/angle - angle-->
+<!ENTITY angmsd SDATA "[angmsd]"--/measuredangle - angle-measured-->
+<!ENTITY beth SDATA "[beth ]"--/beth - beth, Hebrew-->
+<!ENTITY bprime SDATA "[bprime]"--/backprime - reverse prime-->
+<!ENTITY comp SDATA "[comp ]"--/complement - complement sign-->
+<!ENTITY daleth SDATA "[daleth]"--/daleth - daleth, Hebrew-->
+<!ENTITY ell SDATA "[ell ]"--/ell - cursive small l-->
+<!ENTITY empty SDATA "[empty ]"--/emptyset /varnothing =small o, slash-->
+<!ENTITY gimel SDATA "[gimel ]"--/gimel - gimel, Hebrew-->
+<!ENTITY image SDATA "[image ]"--/Im - imaginary-->
+<!ENTITY inodot SDATA "[inodot]"--/imath =small i, no dot-->
+<!ENTITY jnodot SDATA "[jnodot]"--/jmath - small j, no dot-->
+<!ENTITY nexist SDATA "[nexist]"--/nexists - negated exists-->
+<!ENTITY oS SDATA "[oS ]"--/circledS - capital S in circle-->
+<!ENTITY planck SDATA "[planck]"--/hbar /hslash - Planck's over 2pi-->
+<!ENTITY real SDATA "[real ]"--/Re - real-->
+<!ENTITY sbsol SDATA "[sbsol ]"--/sbs - short reverse solidus-->
+<!ENTITY vprime SDATA "[vprime]"--/varprime - prime, variant-->
+<!ENTITY weierp SDATA "[weierp]"--/wp - Weierstrass p-->
diff --git a/docs/docbook/dbsgml/ent/ISOamsr b/docs/docbook/dbsgml/ent/ISOamsr
new file mode 100755
index 00000000000..3f26c345c04
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOamsr
@@ -0,0 +1,94 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOamsr PUBLIC
+ "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN">
+ %ISOamsr;
+-->
+<!ENTITY ape SDATA "[ape ]"--/approxeq R: approximate, equals-->
+<!ENTITY asymp SDATA "[asymp ]"--/asymp R: asymptotically equal to-->
+<!ENTITY bcong SDATA "[bcong ]"--/backcong R: reverse congruent-->
+<!ENTITY bepsi SDATA "[bepsi ]"--/backepsilon R: such that-->
+<!ENTITY bowtie SDATA "[bowtie]"--/bowtie R:-->
+<!ENTITY bsim SDATA "[bsim ]"--/backsim R: reverse similar-->
+<!ENTITY bsime SDATA "[bsime ]"--/backsimeq R: reverse similar, eq-->
+<!ENTITY bump SDATA "[bump ]"--/Bumpeq R: bumpy equals-->
+<!ENTITY bumpe SDATA "[bumpe ]"--/bumpeq R: bumpy equals, equals-->
+<!ENTITY cire SDATA "[cire ]"--/circeq R: circle, equals-->
+<!ENTITY colone SDATA "[colone]"--/coloneq R: colon, equals-->
+<!ENTITY cuepr SDATA "[cuepr ]"--/curlyeqprec R: curly eq, precedes-->
+<!ENTITY cuesc SDATA "[cuesc ]"--/curlyeqsucc R: curly eq, succeeds-->
+<!ENTITY cupre SDATA "[cupre ]"--/curlypreceq R: curly precedes, eq-->
+<!ENTITY dashv SDATA "[dashv ]"--/dashv R: dash, vertical-->
+<!ENTITY ecir SDATA "[ecir ]"--/eqcirc R: circle on equals sign-->
+<!ENTITY ecolon SDATA "[ecolon]"--/eqcolon R: equals, colon-->
+<!ENTITY eDot SDATA "[eDot ]"--/doteqdot /Doteq R: eq, even dots-->
+<!ENTITY esdot SDATA "[esdot ]"--/doteq R: equals, single dot above-->
+<!ENTITY efDot SDATA "[efDot ]"--/fallingdotseq R: eq, falling dots-->
+<!ENTITY egs SDATA "[egs ]"--/eqslantgtr R: equal-or-gtr, slanted-->
+<!ENTITY els SDATA "[els ]"--/eqslantless R: eq-or-less, slanted-->
+<!ENTITY erDot SDATA "[erDot ]"--/risingdotseq R: eq, rising dots-->
+<!ENTITY fork SDATA "[fork ]"--/pitchfork R: pitchfork-->
+<!ENTITY frown SDATA "[frown ]"--/frown R: down curve-->
+<!ENTITY gap SDATA "[gap ]"--/gtrapprox R: greater, approximate-->
+<!ENTITY gsdot SDATA "[gsdot ]"--/gtrdot R: greater than, single dot-->
+<!ENTITY gE SDATA "[gE ]"--/geqq R: greater, double equals-->
+<!ENTITY gel SDATA "[gel ]"--/gtreqless R: greater, equals, less-->
+<!ENTITY gEl SDATA "[gEl ]"--/gtreqqless R: gt, dbl equals, less-->
+<!ENTITY ges SDATA "[ges ]"--/geqslant R: gt-or-equal, slanted-->
+<!ENTITY Gg SDATA "[Gg ]"--/ggg /Gg /gggtr R: triple gtr-than-->
+<!ENTITY gl SDATA "[gl ]"--/gtrless R: greater, less-->
+<!ENTITY gsim SDATA "[gsim ]"--/gtrsim R: greater, similar-->
+<!ENTITY Gt SDATA "[Gt ]"--/gg R: dbl greater-than sign-->
+<!ENTITY lap SDATA "[lap ]"--/lessapprox R: less, approximate-->
+<!ENTITY ldot SDATA "[ldot ]"--/lessdot R: less than, with dot-->
+<!ENTITY lE SDATA "[lE ]"--/leqq R: less, double equals-->
+<!ENTITY lEg SDATA "[lEg ]"--/lesseqqgtr R: less, dbl eq, greater-->
+<!ENTITY leg SDATA "[leg ]"--/lesseqgtr R: less, eq, greater-->
+<!ENTITY les SDATA "[les ]"--/leqslant R: less-than-or-eq, slant-->
+<!ENTITY lg SDATA "[lg ]"--/lessgtr R: less, greater-->
+<!ENTITY Ll SDATA "[Ll ]"--/Ll /lll /llless R: triple less-than-->
+<!ENTITY lsim SDATA "[lsim ]"--/lesssim R: less, similar-->
+<!ENTITY Lt SDATA "[Lt ]"--/ll R: double less-than sign-->
+<!ENTITY ltrie SDATA "[ltrie ]"--/trianglelefteq R: left triangle, eq-->
+<!ENTITY mid SDATA "[mid ]"--/mid R:-->
+<!ENTITY models SDATA "[models]"--/models R:-->
+<!ENTITY pr SDATA "[pr ]"--/prec R: precedes-->
+<!ENTITY prap SDATA "[prap ]"--/precapprox R: precedes, approximate-->
+<!ENTITY pre SDATA "[pre ]"--/preceq R: precedes, equals-->
+<!ENTITY prsim SDATA "[prsim ]"--/precsim R: precedes, similar-->
+<!ENTITY rtrie SDATA "[rtrie ]"--/trianglerighteq R: right tri, eq-->
+<!ENTITY samalg SDATA "[samalg]"--/smallamalg R: small amalg-->
+<!ENTITY sc SDATA "[sc ]"--/succ R: succeeds-->
+<!ENTITY scap SDATA "[scap ]"--/succapprox R: succeeds, approximate-->
+<!ENTITY sccue SDATA "[sccue ]"--/succcurlyeq R: succeeds, curly eq-->
+<!ENTITY sce SDATA "[sce ]"--/succeq R: succeeds, equals-->
+<!ENTITY scsim SDATA "[scsim ]"--/succsim R: succeeds, similar-->
+<!ENTITY sfrown SDATA "[sfrown]"--/smallfrown R: small down curve-->
+<!ENTITY smid SDATA "[smid ]"--/shortmid R:-->
+<!ENTITY smile SDATA "[smile ]"--/smile R: up curve-->
+<!ENTITY spar SDATA "[spar ]"--/shortparallel R: short parallel-->
+<!ENTITY sqsub SDATA "[sqsub ]"--/sqsubset R: square subset-->
+<!ENTITY sqsube SDATA "[sqsube]"--/sqsubseteq R: square subset, equals-->
+<!ENTITY sqsup SDATA "[sqsup ]"--/sqsupset R: square superset-->
+<!ENTITY sqsupe SDATA "[sqsupe]"--/sqsupseteq R: square superset, eq-->
+<!ENTITY ssmile SDATA "[ssmile]"--/smallsmile R: small up curve-->
+<!ENTITY Sub SDATA "[Sub ]"--/Subset R: double subset-->
+<!ENTITY subE SDATA "[subE ]"--/subseteqq R: subset, dbl equals-->
+<!ENTITY Sup SDATA "[Sup ]"--/Supset R: dbl superset-->
+<!ENTITY supE SDATA "[supE ]"--/supseteqq R: superset, dbl equals-->
+<!ENTITY thkap SDATA "[thkap ]"--/thickapprox R: thick approximate-->
+<!ENTITY thksim SDATA "[thksim]"--/thicksim R: thick similar-->
+<!ENTITY trie SDATA "[trie ]"--/triangleq R: triangle, equals-->
+<!ENTITY twixt SDATA "[twixt ]"--/between R: between-->
+<!ENTITY vdash SDATA "[vdash ]"--/vdash R: vertical, dash-->
+<!ENTITY Vdash SDATA "[Vdash ]"--/Vdash R: dbl vertical, dash-->
+<!ENTITY vDash SDATA "[vDash ]"--/vDash R: vertical, dbl dash-->
+<!ENTITY veebar SDATA "[veebar]"--/veebar R: logical or, bar below-->
+<!ENTITY vltri SDATA "[vltri ]"--/vartriangleleft R: l tri, open, var-->
+<!ENTITY vprop SDATA "[vprop ]"--/varpropto R: proportional, variant-->
+<!ENTITY vrtri SDATA "[vrtri ]"--/vartriangleright R: r tri, open, var-->
+<!ENTITY Vvdash SDATA "[Vvdash]"--/Vvdash R: triple vertical, dash-->
diff --git a/docs/docbook/dbsgml/ent/ISObox b/docs/docbook/dbsgml/ent/ISObox
new file mode 100755
index 00000000000..643e926edaa
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISObox
@@ -0,0 +1,62 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISObox PUBLIC
+ "ISO 8879:1986//ENTITIES Box and Line Drawing//EN">
+ %ISObox;
+-->
+<!-- All names are in the form: box1234, where:
+ box = constants that identify a box drawing entity.
+ 1&2 = v, V, u, U, d, D, Ud, or uD, as follows:
+ v = vertical line for full height.
+ u = upper half of vertical line.
+ d = downward (lower) half of vertical line.
+ 3&4 = h, H, l, L, r, R, Lr, or lR, as follows:
+ h = horizontal line for full width.
+ l = left half of horizontal line.
+ r = right half of horizontal line.
+ In all cases, an upper-case letter means a double or heavy line.
+-->
+<!ENTITY boxh SDATA "[boxh ]"--horizontal line -->
+<!ENTITY boxv SDATA "[boxv ]"--vertical line-->
+<!ENTITY boxur SDATA "[boxur ]"--upper right quadrant-->
+<!ENTITY boxul SDATA "[boxul ]"--upper left quadrant-->
+<!ENTITY boxdl SDATA "[boxdl ]"--lower left quadrant-->
+<!ENTITY boxdr SDATA "[boxdr ]"--lower right quadrant-->
+<!ENTITY boxvr SDATA "[boxvr ]"--upper and lower right quadrants-->
+<!ENTITY boxhu SDATA "[boxhu ]"--upper left and right quadrants-->
+<!ENTITY boxvl SDATA "[boxvl ]"--upper and lower left quadrants-->
+<!ENTITY boxhd SDATA "[boxhd ]"--lower left and right quadrants-->
+<!ENTITY boxvh SDATA "[boxvh ]"--all four quadrants-->
+<!ENTITY boxvR SDATA "[boxvR ]"--upper and lower right quadrants-->
+<!ENTITY boxhU SDATA "[boxhU ]"--upper left and right quadrants-->
+<!ENTITY boxvL SDATA "[boxvL ]"--upper and lower left quadrants-->
+<!ENTITY boxhD SDATA "[boxhD ]"--lower left and right quadrants-->
+<!ENTITY boxvH SDATA "[boxvH ]"--all four quadrants-->
+<!ENTITY boxH SDATA "[boxH ]"--horizontal line-->
+<!ENTITY boxV SDATA "[boxV ]"--vertical line-->
+<!ENTITY boxUR SDATA "[boxUR ]"--upper right quadrant-->
+<!ENTITY boxUL SDATA "[boxUL ]"--upper left quadrant-->
+<!ENTITY boxDL SDATA "[boxDL ]"--lower left quadrant-->
+<!ENTITY boxDR SDATA "[boxDR ]"--lower right quadrant-->
+<!ENTITY boxVR SDATA "[boxVR ]"--upper and lower right quadrants-->
+<!ENTITY boxHU SDATA "[boxHU ]"--upper left and right quadrants-->
+<!ENTITY boxVL SDATA "[boxVL ]"--upper and lower left quadrants-->
+<!ENTITY boxHD SDATA "[boxHD ]"--lower left and right quadrants-->
+<!ENTITY boxVH SDATA "[boxVH ]"--all four quadrants-->
+<!ENTITY boxVr SDATA "[boxVr ]"--upper and lower right quadrants-->
+<!ENTITY boxHu SDATA "[boxHu ]"--upper left and right quadrants-->
+<!ENTITY boxVl SDATA "[boxVl ]"--upper and lower left quadrants-->
+<!ENTITY boxHd SDATA "[boxHd ]"--lower left and right quadrants-->
+<!ENTITY boxVh SDATA "[boxVh ]"--all four quadrants-->
+<!ENTITY boxuR SDATA "[boxuR ]"--upper right quadrant-->
+<!ENTITY boxUl SDATA "[boxUl ]"--upper left quadrant-->
+<!ENTITY boxdL SDATA "[boxdL ]"--lower left quadrant-->
+<!ENTITY boxDr SDATA "[boxDr ]"--lower right quadrant-->
+<!ENTITY boxUr SDATA "[boxUr ]"--upper right quadrant-->
+<!ENTITY boxuL SDATA "[boxuL ]"--upper left quadrant-->
+<!ENTITY boxDl SDATA "[boxDl ]"--lower left quadrant-->
+<!ENTITY boxdR SDATA "[boxdR ]"--lower right quadrant-->
diff --git a/docs/docbook/dbsgml/ent/ISOcyr1 b/docs/docbook/dbsgml/ent/ISOcyr1
new file mode 100755
index 00000000000..97b961b1f0b
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOcyr1
@@ -0,0 +1,77 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOcyr1 PUBLIC
+ "ISO 8879:1986//ENTITIES Russian Cyrillic//EN">
+ %ISOcyr1;
+-->
+<!ENTITY acy SDATA "[acy ]"--=small a, Cyrillic-->
+<!ENTITY Acy SDATA "[Acy ]"--=capital A, Cyrillic-->
+<!ENTITY bcy SDATA "[bcy ]"--=small be, Cyrillic-->
+<!ENTITY Bcy SDATA "[Bcy ]"--=capital BE, Cyrillic-->
+<!ENTITY vcy SDATA "[vcy ]"--=small ve, Cyrillic-->
+<!ENTITY Vcy SDATA "[Vcy ]"--=capital VE, Cyrillic-->
+<!ENTITY gcy SDATA "[gcy ]"--=small ghe, Cyrillic-->
+<!ENTITY Gcy SDATA "[Gcy ]"--=capital GHE, Cyrillic-->
+<!ENTITY dcy SDATA "[dcy ]"--=small de, Cyrillic-->
+<!ENTITY Dcy SDATA "[Dcy ]"--=capital DE, Cyrillic-->
+<!ENTITY iecy SDATA "[iecy ]"--=small ie, Cyrillic-->
+<!ENTITY IEcy SDATA "[IEcy ]"--=capital IE, Cyrillic-->
+<!ENTITY iocy SDATA "[iocy ]"--=small io, Russian-->
+<!ENTITY IOcy SDATA "[IOcy ]"--=capital IO, Russian-->
+<!ENTITY zhcy SDATA "[zhcy ]"--=small zhe, Cyrillic-->
+<!ENTITY ZHcy SDATA "[ZHcy ]"--=capital ZHE, Cyrillic-->
+<!ENTITY zcy SDATA "[zcy ]"--=small ze, Cyrillic-->
+<!ENTITY Zcy SDATA "[Zcy ]"--=capital ZE, Cyrillic-->
+<!ENTITY icy SDATA "[icy ]"--=small i, Cyrillic-->
+<!ENTITY Icy SDATA "[Icy ]"--=capital I, Cyrillic-->
+<!ENTITY jcy SDATA "[jcy ]"--=small short i, Cyrillic-->
+<!ENTITY Jcy SDATA "[Jcy ]"--=capital short I, Cyrillic-->
+<!ENTITY kcy SDATA "[kcy ]"--=small ka, Cyrillic-->
+<!ENTITY Kcy SDATA "[Kcy ]"--=capital KA, Cyrillic-->
+<!ENTITY lcy SDATA "[lcy ]"--=small el, Cyrillic-->
+<!ENTITY Lcy SDATA "[Lcy ]"--=capital EL, Cyrillic-->
+<!ENTITY mcy SDATA "[mcy ]"--=small em, Cyrillic-->
+<!ENTITY Mcy SDATA "[Mcy ]"--=capital EM, Cyrillic-->
+<!ENTITY ncy SDATA "[ncy ]"--=small en, Cyrillic-->
+<!ENTITY Ncy SDATA "[Ncy ]"--=capital EN, Cyrillic-->
+<!ENTITY ocy SDATA "[ocy ]"--=small o, Cyrillic-->
+<!ENTITY Ocy SDATA "[Ocy ]"--=capital O, Cyrillic-->
+<!ENTITY pcy SDATA "[pcy ]"--=small pe, Cyrillic-->
+<!ENTITY Pcy SDATA "[Pcy ]"--=capital PE, Cyrillic-->
+<!ENTITY rcy SDATA "[rcy ]"--=small er, Cyrillic-->
+<!ENTITY Rcy SDATA "[Rcy ]"--=capital ER, Cyrillic-->
+<!ENTITY scy SDATA "[scy ]"--=small es, Cyrillic-->
+<!ENTITY Scy SDATA "[Scy ]"--=capital ES, Cyrillic-->
+<!ENTITY tcy SDATA "[tcy ]"--=small te, Cyrillic-->
+<!ENTITY Tcy SDATA "[Tcy ]"--=capital TE, Cyrillic-->
+<!ENTITY ucy SDATA "[ucy ]"--=small u, Cyrillic-->
+<!ENTITY Ucy SDATA "[Ucy ]"--=capital U, Cyrillic-->
+<!ENTITY fcy SDATA "[fcy ]"--=small ef, Cyrillic-->
+<!ENTITY Fcy SDATA "[Fcy ]"--=capital EF, Cyrillic-->
+<!ENTITY khcy SDATA "[khcy ]"--=small ha, Cyrillic-->
+<!ENTITY KHcy SDATA "[KHcy ]"--=capital HA, Cyrillic-->
+<!ENTITY tscy SDATA "[tscy ]"--=small tse, Cyrillic-->
+<!ENTITY TScy SDATA "[TScy ]"--=capital TSE, Cyrillic-->
+<!ENTITY chcy SDATA "[chcy ]"--=small che, Cyrillic-->
+<!ENTITY CHcy SDATA "[CHcy ]"--=capital CHE, Cyrillic-->
+<!ENTITY shcy SDATA "[shcy ]"--=small sha, Cyrillic-->
+<!ENTITY SHcy SDATA "[SHcy ]"--=capital SHA, Cyrillic-->
+<!ENTITY shchcy SDATA "[shchcy]"--=small shcha, Cyrillic-->
+<!ENTITY SHCHcy SDATA "[SHCHcy]"--=capital SHCHA, Cyrillic-->
+<!ENTITY hardcy SDATA "[hardcy]"--=small hard sign, Cyrillic-->
+<!ENTITY HARDcy SDATA "[HARDcy]"--=capital HARD sign, Cyrillic-->
+<!ENTITY ycy SDATA "[ycy ]"--=small yeru, Cyrillic-->
+<!ENTITY Ycy SDATA "[Ycy ]"--=capital YERU, Cyrillic-->
+<!ENTITY softcy SDATA "[softcy]"--=small soft sign, Cyrillic-->
+<!ENTITY SOFTcy SDATA "[SOFTcy]"--=capital SOFT sign, Cyrillic-->
+<!ENTITY ecy SDATA "[ecy ]"--=small e, Cyrillic-->
+<!ENTITY Ecy SDATA "[Ecy ]"--=capital E, Cyrillic-->
+<!ENTITY yucy SDATA "[yucy ]"--=small yu, Cyrillic-->
+<!ENTITY YUcy SDATA "[YUcy ]"--=capital YU, Cyrillic-->
+<!ENTITY yacy SDATA "[yacy ]"--=small ya, Cyrillic-->
+<!ENTITY YAcy SDATA "[YAcy ]"--=capital YA, Cyrillic-->
+<!ENTITY numero SDATA "[numero]"--=numero sign-->
diff --git a/docs/docbook/dbsgml/ent/ISOcyr2 b/docs/docbook/dbsgml/ent/ISOcyr2
new file mode 100755
index 00000000000..480b01c1df4
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOcyr2
@@ -0,0 +1,36 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOcyr2 PUBLIC
+ "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN">
+ %ISOcyr2;
+-->
+<!ENTITY djcy SDATA "[djcy ]"--=small dje, Serbian-->
+<!ENTITY DJcy SDATA "[DJcy ]"--=capital DJE, Serbian-->
+<!ENTITY gjcy SDATA "[gjcy ]"--=small gje, Macedonian-->
+<!ENTITY GJcy SDATA "[GJcy ]"--=capital GJE Macedonian-->
+<!ENTITY jukcy SDATA "[jukcy ]"--=small je, Ukrainian-->
+<!ENTITY Jukcy SDATA "[Jukcy ]"--=capital JE, Ukrainian-->
+<!ENTITY dscy SDATA "[dscy ]"--=small dse, Macedonian-->
+<!ENTITY DScy SDATA "[DScy ]"--=capital DSE, Macedonian-->
+<!ENTITY iukcy SDATA "[iukcy ]"--=small i, Ukrainian-->
+<!ENTITY Iukcy SDATA "[Iukcy ]"--=capital I, Ukrainian-->
+<!ENTITY yicy SDATA "[yicy ]"--=small yi, Ukrainian-->
+<!ENTITY YIcy SDATA "[YIcy ]"--=capital YI, Ukrainian-->
+<!ENTITY jsercy SDATA "[jsercy]"--=small je, Serbian-->
+<!ENTITY Jsercy SDATA "[Jsercy]"--=capital JE, Serbian-->
+<!ENTITY ljcy SDATA "[ljcy ]"--=small lje, Serbian-->
+<!ENTITY LJcy SDATA "[LJcy ]"--=capital LJE, Serbian-->
+<!ENTITY njcy SDATA "[njcy ]"--=small nje, Serbian-->
+<!ENTITY NJcy SDATA "[NJcy ]"--=capital NJE, Serbian-->
+<!ENTITY tshcy SDATA "[tshcy ]"--=small tshe, Serbian-->
+<!ENTITY TSHcy SDATA "[TSHcy ]"--=capital TSHE, Serbian-->
+<!ENTITY kjcy SDATA "[kjcy ]"--=small kje Macedonian-->
+<!ENTITY KJcy SDATA "[KJcy ]"--=capital KJE, Macedonian-->
+<!ENTITY ubrcy SDATA "[ubrcy ]"--=small u, Byelorussian-->
+<!ENTITY Ubrcy SDATA "[Ubrcy ]"--=capital U, Byelorussian-->
+<!ENTITY dzcy SDATA "[dzcy ]"--=small dze, Serbian-->
+<!ENTITY DZcy SDATA "[DZcy ]"--=capital dze, Serbian-->
diff --git a/docs/docbook/dbsgml/ent/ISOdia b/docs/docbook/dbsgml/ent/ISOdia
new file mode 100755
index 00000000000..3b6f98d6baa
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOdia
@@ -0,0 +1,24 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOdia PUBLIC
+ "ISO 8879:1986//ENTITIES Diacritical Marks//EN">
+ %ISOdia;
+-->
+<!ENTITY acute SDATA "[acute ]"--=acute accent-->
+<!ENTITY breve SDATA "[breve ]"--=breve-->
+<!ENTITY caron SDATA "[caron ]"--=caron-->
+<!ENTITY cedil SDATA "[cedil ]"--=cedilla-->
+<!ENTITY circ SDATA "[circ ]"--=circumflex accent-->
+<!ENTITY dblac SDATA "[dblac ]"--=double acute accent-->
+<!ENTITY die SDATA "[die ]"--=dieresis-->
+<!ENTITY dot SDATA "[dot ]"--=dot above-->
+<!ENTITY grave SDATA "[grave ]"--=grave accent-->
+<!ENTITY macr SDATA "[macr ]"--=macron-->
+<!ENTITY ogon SDATA "[ogon ]"--=ogonek-->
+<!ENTITY ring SDATA "[ring ]"--=ring-->
+<!ENTITY tilde SDATA "[tilde ]"--=tilde-->
+<!ENTITY uml SDATA "[uml ]"--=umlaut mark-->
diff --git a/docs/docbook/dbsgml/ent/ISOgrk1 b/docs/docbook/dbsgml/ent/ISOgrk1
new file mode 100755
index 00000000000..dea16bf8ef9
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOgrk1
@@ -0,0 +1,59 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOgrk1 PUBLIC
+ "ISO 8879:1986//ENTITIES Greek Letters//EN">
+ %ISOgrk1;
+-->
+<!ENTITY agr SDATA "[agr ]"--=small alpha, Greek-->
+<!ENTITY Agr SDATA "[Agr ]"--=capital Alpha, Greek-->
+<!ENTITY bgr SDATA "[bgr ]"--=small beta, Greek-->
+<!ENTITY Bgr SDATA "[Bgr ]"--=capital Beta, Greek-->
+<!ENTITY ggr SDATA "[ggr ]"--=small gamma, Greek-->
+<!ENTITY Ggr SDATA "[Ggr ]"--=capital Gamma, Greek-->
+<!ENTITY dgr SDATA "[dgr ]"--=small delta, Greek-->
+<!ENTITY Dgr SDATA "[Dgr ]"--=capital Delta, Greek-->
+<!ENTITY egr SDATA "[egr ]"--=small epsilon, Greek-->
+<!ENTITY Egr SDATA "[Egr ]"--=capital Epsilon, Greek-->
+<!ENTITY zgr SDATA "[zgr ]"--=small zeta, Greek-->
+<!ENTITY Zgr SDATA "[Zgr ]"--=capital Zeta, Greek-->
+<!ENTITY eegr SDATA "[eegr ]"--=small eta, Greek-->
+<!ENTITY EEgr SDATA "[EEgr ]"--=capital Eta, Greek-->
+<!ENTITY thgr SDATA "[thgr ]"--=small theta, Greek-->
+<!ENTITY THgr SDATA "[THgr ]"--=capital Theta, Greek-->
+<!ENTITY igr SDATA "[igr ]"--=small iota, Greek-->
+<!ENTITY Igr SDATA "[Igr ]"--=capital Iota, Greek-->
+<!ENTITY kgr SDATA "[kgr ]"--=small kappa, Greek-->
+<!ENTITY Kgr SDATA "[Kgr ]"--=capital Kappa, Greek-->
+<!ENTITY lgr SDATA "[lgr ]"--=small lambda, Greek-->
+<!ENTITY Lgr SDATA "[Lgr ]"--=capital Lambda, Greek-->
+<!ENTITY mgr SDATA "[mgr ]"--=small mu, Greek-->
+<!ENTITY Mgr SDATA "[Mgr ]"--=capital Mu, Greek-->
+<!ENTITY ngr SDATA "[ngr ]"--=small nu, Greek-->
+<!ENTITY Ngr SDATA "[Ngr ]"--=capital Nu, Greek-->
+<!ENTITY xgr SDATA "[xgr ]"--=small xi, Greek-->
+<!ENTITY Xgr SDATA "[Xgr ]"--=capital Xi, Greek-->
+<!ENTITY ogr SDATA "[ogr ]"--=small omicron, Greek-->
+<!ENTITY Ogr SDATA "[Ogr ]"--=capital Omicron, Greek-->
+<!ENTITY pgr SDATA "[pgr ]"--=small pi, Greek-->
+<!ENTITY Pgr SDATA "[Pgr ]"--=capital Pi, Greek-->
+<!ENTITY rgr SDATA "[rgr ]"--=small rho, Greek-->
+<!ENTITY Rgr SDATA "[Rgr ]"--=capital Rho, Greek-->
+<!ENTITY sgr SDATA "[sgr ]"--=small sigma, Greek-->
+<!ENTITY Sgr SDATA "[Sgr ]"--=capital Sigma, Greek-->
+<!ENTITY sfgr SDATA "[sfgr ]"--=final small sigma, Greek-->
+<!ENTITY tgr SDATA "[tgr ]"--=small tau, Greek-->
+<!ENTITY Tgr SDATA "[Tgr ]"--=capital Tau, Greek-->
+<!ENTITY ugr SDATA "[ugr ]"--=small upsilon, Greek-->
+<!ENTITY Ugr SDATA "[Ugr ]"--=capital Upsilon, Greek-->
+<!ENTITY phgr SDATA "[phgr ]"--=small phi, Greek-->
+<!ENTITY PHgr SDATA "[PHgr ]"--=capital Phi, Greek-->
+<!ENTITY khgr SDATA "[khgr ]"--=small chi, Greek-->
+<!ENTITY KHgr SDATA "[KHgr ]"--=capital Chi, Greek-->
+<!ENTITY psgr SDATA "[psgr ]"--=small psi, Greek-->
+<!ENTITY PSgr SDATA "[PSgr ]"--=capital Psi, Greek-->
+<!ENTITY ohgr SDATA "[ohgr ]"--=small omega, Greek-->
+<!ENTITY OHgr SDATA "[OHgr ]"--=capital Omega, Greek-->
diff --git a/docs/docbook/dbsgml/ent/ISOgrk2 b/docs/docbook/dbsgml/ent/ISOgrk2
new file mode 100755
index 00000000000..657bb99935e
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOgrk2
@@ -0,0 +1,30 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOgrk2 PUBLIC
+ "ISO 8879:1986//ENTITIES Monotoniko Greek//EN">
+ %ISOgrk2;
+-->
+<!ENTITY aacgr SDATA "[aacgr ]"--=small alpha, accent, Greek-->
+<!ENTITY Aacgr SDATA "[Aacgr ]"--=capital Alpha, accent, Greek-->
+<!ENTITY eacgr SDATA "[eacgr ]"--=small epsilon, accent, Greek-->
+<!ENTITY Eacgr SDATA "[Eacgr ]"--=capital Epsilon, accent, Greek-->
+<!ENTITY eeacgr SDATA "[eeacgr]"--=small eta, accent, Greek-->
+<!ENTITY EEacgr SDATA "[EEacgr]"--=capital Eta, accent, Greek-->
+<!ENTITY idigr SDATA "[idigr ]"--=small iota, dieresis, Greek-->
+<!ENTITY Idigr SDATA "[Idigr ]"--=capital Iota, dieresis, Greek-->
+<!ENTITY iacgr SDATA "[iacgr ]"--=small iota, accent, Greek-->
+<!ENTITY Iacgr SDATA "[Iacgr ]"--=capital Iota, accent, Greek-->
+<!ENTITY idiagr SDATA "[idiagr]"--=small iota, dieresis, accent, Greek-->
+<!ENTITY oacgr SDATA "[oacgr ]"--=small omicron, accent, Greek-->
+<!ENTITY Oacgr SDATA "[Oacgr ]"--=capital Omicron, accent, Greek-->
+<!ENTITY udigr SDATA "[udigr ]"--=small upsilon, dieresis, Greek-->
+<!ENTITY Udigr SDATA "[Udigr ]"--=capital Upsilon, dieresis, Greek-->
+<!ENTITY uacgr SDATA "[uacgr ]"--=small upsilon, accent, Greek-->
+<!ENTITY Uacgr SDATA "[Uacgr ]"--=capital Upsilon, accent, Greek-->
+<!ENTITY udiagr SDATA "[udiagr]"--=small upsilon, dieresis, accent, Greek-->
+<!ENTITY ohacgr SDATA "[ohacgr]"--=small omega, accent, Greek-->
+<!ENTITY OHacgr SDATA "[OHacgr]"--=capital Omega, accent, Greek-->
diff --git a/docs/docbook/dbsgml/ent/ISOgrk3 b/docs/docbook/dbsgml/ent/ISOgrk3
new file mode 100755
index 00000000000..f76c3a084f3
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOgrk3
@@ -0,0 +1,53 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOgrk3 PUBLIC
+ "ISO 8879:1986//ENTITIES Greek Symbols//EN">
+ %ISOgrk3;
+-->
+<!ENTITY alpha SDATA "[alpha ]"--=small alpha, Greek-->
+<!ENTITY beta SDATA "[beta ]"--=small beta, Greek-->
+<!ENTITY gamma SDATA "[gamma ]"--=small gamma, Greek-->
+<!ENTITY Gamma SDATA "[Gamma ]"--=capital Gamma, Greek-->
+<!ENTITY gammad SDATA "[gammad]"--/digamma-->
+<!ENTITY delta SDATA "[delta ]"--=small delta, Greek-->
+<!ENTITY Delta SDATA "[Delta ]"--=capital Delta, Greek-->
+<!ENTITY epsi SDATA "[epsi ]"--=small epsilon, Greek-->
+<!ENTITY epsiv SDATA "[epsiv ]"--/varepsilon-->
+<!ENTITY epsis SDATA "[epsis ]"--/straightepsilon-->
+<!ENTITY zeta SDATA "[zeta ]"--=small zeta, Greek-->
+<!ENTITY eta SDATA "[eta ]"--=small eta, Greek-->
+<!ENTITY thetas SDATA "[thetas]"--straight theta-->
+<!ENTITY Theta SDATA "[Theta ]"--=capital Theta, Greek-->
+<!ENTITY thetav SDATA "[thetav]"--/vartheta - curly or open theta-->
+<!ENTITY iota SDATA "[iota ]"--=small iota, Greek-->
+<!ENTITY kappa SDATA "[kappa ]"--=small kappa, Greek-->
+<!ENTITY kappav SDATA "[kappav]"--/varkappa-->
+<!ENTITY lambda SDATA "[lambda]"--=small lambda, Greek-->
+<!ENTITY Lambda SDATA "[Lambda]"--=capital Lambda, Greek-->
+<!ENTITY mu SDATA "[mu ]"--=small mu, Greek-->
+<!ENTITY nu SDATA "[nu ]"--=small nu, Greek-->
+<!ENTITY xi SDATA "[xi ]"--=small xi, Greek-->
+<!ENTITY Xi SDATA "[Xi ]"--=capital Xi, Greek-->
+<!ENTITY pi SDATA "[pi ]"--=small pi, Greek-->
+<!ENTITY piv SDATA "[piv ]"--/varpi-->
+<!ENTITY Pi SDATA "[Pi ]"--=capital Pi, Greek-->
+<!ENTITY rho SDATA "[rho ]"--=small rho, Greek-->
+<!ENTITY rhov SDATA "[rhov ]"--/varrho-->
+<!ENTITY sigma SDATA "[sigma ]"--=small sigma, Greek-->
+<!ENTITY Sigma SDATA "[Sigma ]"--=capital Sigma, Greek-->
+<!ENTITY sigmav SDATA "[sigmav]"--/varsigma-->
+<!ENTITY tau SDATA "[tau ]"--=small tau, Greek-->
+<!ENTITY upsi SDATA "[upsi ]"--=small upsilon, Greek-->
+<!ENTITY Upsi SDATA "[Upsi ]"--=capital Upsilon, Greek-->
+<!ENTITY phis SDATA "[phis ]"--/straightphi - straight phi-->
+<!ENTITY Phi SDATA "[Phi ]"--=capital Phi, Greek-->
+<!ENTITY phiv SDATA "[phiv ]"--/varphi - curly or open phi-->
+<!ENTITY chi SDATA "[chi ]"--=small chi, Greek-->
+<!ENTITY psi SDATA "[psi ]"--=small psi, Greek-->
+<!ENTITY Psi SDATA "[Psi ]"--=capital Psi, Greek-->
+<!ENTITY omega SDATA "[omega ]"--=small omega, Greek-->
+<!ENTITY Omega SDATA "[Omega ]"--=capital Omega, Greek-->
diff --git a/docs/docbook/dbsgml/ent/ISOgrk4 b/docs/docbook/dbsgml/ent/ISOgrk4
new file mode 100755
index 00000000000..e4427a0cb54
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOgrk4
@@ -0,0 +1,53 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOgrk4 PUBLIC
+ "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN">
+ %ISOgrk4;
+-->
+<!ENTITY b.alpha SDATA "[b.alpha ]"--=small alpha, Greek-->
+<!ENTITY b.beta SDATA "[b.beta ]"--=small beta, Greek-->
+<!ENTITY b.gamma SDATA "[b.gamma ]"--=small gamma, Greek-->
+<!ENTITY b.Gamma SDATA "[b.Gamma ]"--=capital Gamma, Greek-->
+<!ENTITY b.gammad SDATA "[b.gammad]"--/digamma-->
+<!ENTITY b.delta SDATA "[b.delta ]"--=small delta, Greek-->
+<!ENTITY b.Delta SDATA "[b.Delta ]"--=capital Delta, Greek-->
+<!ENTITY b.epsi SDATA "[b.epsi ]"--=small epsilon, Greek-->
+<!ENTITY b.epsiv SDATA "[b.epsiv ]"--/varepsilon-->
+<!ENTITY b.epsis SDATA "[b.epsis ]"--/straightepsilon-->
+<!ENTITY b.zeta SDATA "[b.zeta ]"--=small zeta, Greek-->
+<!ENTITY b.eta SDATA "[b.eta ]"--=small eta, Greek-->
+<!ENTITY b.thetas SDATA "[b.thetas]"--straight theta-->
+<!ENTITY b.Theta SDATA "[b.Theta ]"--=capital Theta, Greek-->
+<!ENTITY b.thetav SDATA "[b.thetav]"--/vartheta - curly or open theta-->
+<!ENTITY b.iota SDATA "[b.iota ]"--=small iota, Greek-->
+<!ENTITY b.kappa SDATA "[b.kappa ]"--=small kappa, Greek-->
+<!ENTITY b.kappav SDATA "[b.kappav]"--/varkappa-->
+<!ENTITY b.lambda SDATA "[b.lambda]"--=small lambda, Greek-->
+<!ENTITY b.Lambda SDATA "[b.Lambda]"--=capital Lambda, Greek-->
+<!ENTITY b.mu SDATA "[b.mu ]"--=small mu, Greek-->
+<!ENTITY b.nu SDATA "[b.nu ]"--=small nu, Greek-->
+<!ENTITY b.xi SDATA "[b.xi ]"--=small xi, Greek-->
+<!ENTITY b.Xi SDATA "[b.Xi ]"--=capital Xi, Greek-->
+<!ENTITY b.pi SDATA "[b.pi ]"--=small pi, Greek-->
+<!ENTITY b.Pi SDATA "[b.Pi ]"--=capital Pi, Greek-->
+<!ENTITY b.piv SDATA "[b.piv ]"--/varpi-->
+<!ENTITY b.rho SDATA "[b.rho ]"--=small rho, Greek-->
+<!ENTITY b.rhov SDATA "[b.rhov ]"--/varrho-->
+<!ENTITY b.sigma SDATA "[b.sigma ]"--=small sigma, Greek-->
+<!ENTITY b.Sigma SDATA "[b.Sigma ]"--=capital Sigma, Greek-->
+<!ENTITY b.sigmav SDATA "[b.sigmav]"--/varsigma-->
+<!ENTITY b.tau SDATA "[b.tau ]"--=small tau, Greek-->
+<!ENTITY b.upsi SDATA "[b.upsi ]"--=small upsilon, Greek-->
+<!ENTITY b.Upsi SDATA "[b.Upsi ]"--=capital Upsilon, Greek-->
+<!ENTITY b.phis SDATA "[b.phis ]"--/straightphi - straight phi-->
+<!ENTITY b.Phi SDATA "[b.Phi ]"--=capital Phi, Greek-->
+<!ENTITY b.phiv SDATA "[b.phiv ]"--/varphi - curly or open phi-->
+<!ENTITY b.chi SDATA "[b.chi ]"--=small chi, Greek-->
+<!ENTITY b.psi SDATA "[b.psi ]"--=small psi, Greek-->
+<!ENTITY b.Psi SDATA "[b.Psi ]"--=capital Psi, Greek-->
+<!ENTITY b.omega SDATA "[b.omega ]"--=small omega, Greek-->
+<!ENTITY b.Omega SDATA "[b.Omega ]"--=capital Omega, Greek-->
diff --git a/docs/docbook/dbsgml/ent/ISOlat1 b/docs/docbook/dbsgml/ent/ISOlat1
new file mode 100755
index 00000000000..0d7d0a7d937
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOlat1
@@ -0,0 +1,72 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOlat1 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 1//EN">
+ %ISOlat1;
+-->
+<!ENTITY aacute SDATA "[aacute]"--=small a, acute accent-->
+<!ENTITY Aacute SDATA "[Aacute]"--=capital A, acute accent-->
+<!ENTITY acirc SDATA "[acirc ]"--=small a, circumflex accent-->
+<!ENTITY Acirc SDATA "[Acirc ]"--=capital A, circumflex accent-->
+<!ENTITY agrave SDATA "[agrave]"--=small a, grave accent-->
+<!ENTITY Agrave SDATA "[Agrave]"--=capital A, grave accent-->
+<!ENTITY aring SDATA "[aring ]"--=small a, ring-->
+<!ENTITY Aring SDATA "[Aring ]"--=capital A, ring-->
+<!ENTITY atilde SDATA "[atilde]"--=small a, tilde-->
+<!ENTITY Atilde SDATA "[Atilde]"--=capital A, tilde-->
+<!ENTITY auml SDATA "[auml ]"--=small a, dieresis or umlaut mark-->
+<!ENTITY Auml SDATA "[Auml ]"--=capital A, dieresis or umlaut mark-->
+<!ENTITY aelig SDATA "[aelig ]"--=small ae diphthong (ligature)-->
+<!ENTITY AElig SDATA "[AElig ]"--=capital AE diphthong (ligature)-->
+<!ENTITY ccedil SDATA "[ccedil]"--=small c, cedilla-->
+<!ENTITY Ccedil SDATA "[Ccedil]"--=capital C, cedilla-->
+<!ENTITY eth SDATA "[eth ]"--=small eth, Icelandic-->
+<!ENTITY ETH SDATA "[ETH ]"--=capital Eth, Icelandic-->
+<!ENTITY eacute SDATA "[eacute]"--=small e, acute accent-->
+<!ENTITY Eacute SDATA "[Eacute]"--=capital E, acute accent-->
+<!ENTITY ecirc SDATA "[ecirc ]"--=small e, circumflex accent-->
+<!ENTITY Ecirc SDATA "[Ecirc ]"--=capital E, circumflex accent-->
+<!ENTITY egrave SDATA "[egrave]"--=small e, grave accent-->
+<!ENTITY Egrave SDATA "[Egrave]"--=capital E, grave accent-->
+<!ENTITY euml SDATA "[euml ]"--=small e, dieresis or umlaut mark-->
+<!ENTITY Euml SDATA "[Euml ]"--=capital E, dieresis or umlaut mark-->
+<!ENTITY iacute SDATA "[iacute]"--=small i, acute accent-->
+<!ENTITY Iacute SDATA "[Iacute]"--=capital I, acute accent-->
+<!ENTITY icirc SDATA "[icirc ]"--=small i, circumflex accent-->
+<!ENTITY Icirc SDATA "[Icirc ]"--=capital I, circumflex accent-->
+<!ENTITY igrave SDATA "[igrave]"--=small i, grave accent-->
+<!ENTITY Igrave SDATA "[Igrave]"--=capital I, grave accent-->
+<!ENTITY iuml SDATA "[iuml ]"--=small i, dieresis or umlaut mark-->
+<!ENTITY Iuml SDATA "[Iuml ]"--=capital I, dieresis or umlaut mark-->
+<!ENTITY ntilde SDATA "[ntilde]"--=small n, tilde-->
+<!ENTITY Ntilde SDATA "[Ntilde]"--=capital N, tilde-->
+<!ENTITY oacute SDATA "[oacute]"--=small o, acute accent-->
+<!ENTITY Oacute SDATA "[Oacute]"--=capital O, acute accent-->
+<!ENTITY ocirc SDATA "[ocirc ]"--=small o, circumflex accent-->
+<!ENTITY Ocirc SDATA "[Ocirc ]"--=capital O, circumflex accent-->
+<!ENTITY ograve SDATA "[ograve]"--=small o, grave accent-->
+<!ENTITY Ograve SDATA "[Ograve]"--=capital O, grave accent-->
+<!ENTITY oslash SDATA "[oslash]"--=small o, slash-->
+<!ENTITY Oslash SDATA "[Oslash]"--=capital O, slash-->
+<!ENTITY otilde SDATA "[otilde]"--=small o, tilde-->
+<!ENTITY Otilde SDATA "[Otilde]"--=capital O, tilde-->
+<!ENTITY ouml SDATA "[ouml ]"--=small o, dieresis or umlaut mark-->
+<!ENTITY Ouml SDATA "[Ouml ]"--=capital O, dieresis or umlaut mark-->
+<!ENTITY szlig SDATA "[szlig ]"--=small sharp s, German (sz ligature)-->
+<!ENTITY thorn SDATA "[thorn ]"--=small thorn, Icelandic-->
+<!ENTITY THORN SDATA "[THORN ]"--=capital THORN, Icelandic-->
+<!ENTITY uacute SDATA "[uacute]"--=small u, acute accent-->
+<!ENTITY Uacute SDATA "[Uacute]"--=capital U, acute accent-->
+<!ENTITY ucirc SDATA "[ucirc ]"--=small u, circumflex accent-->
+<!ENTITY Ucirc SDATA "[Ucirc ]"--=capital U, circumflex accent-->
+<!ENTITY ugrave SDATA "[ugrave]"--=small u, grave accent-->
+<!ENTITY Ugrave SDATA "[Ugrave]"--=capital U, grave accent-->
+<!ENTITY uuml SDATA "[uuml ]"--=small u, dieresis or umlaut mark-->
+<!ENTITY Uuml SDATA "[Uuml ]"--=capital U, dieresis or umlaut mark-->
+<!ENTITY yacute SDATA "[yacute]"--=small y, acute accent-->
+<!ENTITY Yacute SDATA "[Yacute]"--=capital Y, acute accent-->
+<!ENTITY yuml SDATA "[yuml ]"--=small y, dieresis or umlaut mark-->
diff --git a/docs/docbook/dbsgml/ent/ISOlat2 b/docs/docbook/dbsgml/ent/ISOlat2
new file mode 100755
index 00000000000..4bcb3378328
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOlat2
@@ -0,0 +1,131 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOlat2 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 2//EN">
+ %ISOlat2;
+-->
+<!ENTITY abreve SDATA "[abreve]"--=small a, breve-->
+<!ENTITY Abreve SDATA "[Abreve]"--=capital A, breve-->
+<!ENTITY amacr SDATA "[amacr ]"--=small a, macron-->
+<!ENTITY Amacr SDATA "[Amacr ]"--=capital A, macron-->
+<!ENTITY aogon SDATA "[aogon ]"--=small a, ogonek-->
+<!ENTITY Aogon SDATA "[Aogon ]"--=capital A, ogonek-->
+<!ENTITY cacute SDATA "[cacute]"--=small c, acute accent-->
+<!ENTITY Cacute SDATA "[Cacute]"--=capital C, acute accent-->
+<!ENTITY ccaron SDATA "[ccaron]"--=small c, caron-->
+<!ENTITY Ccaron SDATA "[Ccaron]"--=capital C, caron-->
+<!ENTITY ccirc SDATA "[ccirc ]"--=small c, circumflex accent-->
+<!ENTITY Ccirc SDATA "[Ccirc ]"--=capital C, circumflex accent-->
+<!ENTITY cdot SDATA "[cdot ]"--=small c, dot above-->
+<!ENTITY Cdot SDATA "[Cdot ]"--=capital C, dot above-->
+<!ENTITY dcaron SDATA "[dcaron]"--=small d, caron-->
+<!ENTITY Dcaron SDATA "[Dcaron]"--=capital D, caron-->
+<!ENTITY dstrok SDATA "[dstrok]"--=small d, stroke-->
+<!ENTITY Dstrok SDATA "[Dstrok]"--=capital D, stroke-->
+<!ENTITY ecaron SDATA "[ecaron]"--=small e, caron-->
+<!ENTITY Ecaron SDATA "[Ecaron]"--=capital E, caron-->
+<!ENTITY edot SDATA "[edot ]"--=small e, dot above-->
+<!ENTITY Edot SDATA "[Edot ]"--=capital E, dot above-->
+<!ENTITY emacr SDATA "[emacr ]"--=small e, macron-->
+<!ENTITY Emacr SDATA "[Emacr ]"--=capital E, macron-->
+<!ENTITY eogon SDATA "[eogon ]"--=small e, ogonek-->
+<!ENTITY Eogon SDATA "[Eogon ]"--=capital E, ogonek-->
+<!ENTITY gacute SDATA "[gacute]"--=small g, acute accent-->
+<!ENTITY gbreve SDATA "[gbreve]"--=small g, breve-->
+<!ENTITY Gbreve SDATA "[Gbreve]"--=capital G, breve-->
+<!ENTITY Gcedil SDATA "[Gcedil]"--=capital G, cedilla-->
+<!ENTITY gcirc SDATA "[gcirc ]"--=small g, circumflex accent-->
+<!ENTITY Gcirc SDATA "[Gcirc ]"--=capital G, circumflex accent-->
+<!ENTITY gdot SDATA "[gdot ]"--=small g, dot above-->
+<!ENTITY Gdot SDATA "[Gdot ]"--=capital G, dot above-->
+<!ENTITY hcirc SDATA "[hcirc ]"--=small h, circumflex accent-->
+<!ENTITY Hcirc SDATA "[Hcirc ]"--=capital H, circumflex accent-->
+<!ENTITY hstrok SDATA "[hstrok]"--=small h, stroke-->
+<!ENTITY Hstrok SDATA "[Hstrok]"--=capital H, stroke-->
+<!ENTITY Idot SDATA "[Idot ]"--=capital I, dot above-->
+<!ENTITY Imacr SDATA "[Imacr ]"--=capital I, macron-->
+<!ENTITY imacr SDATA "[imacr ]"--=small i, macron-->
+<!ENTITY ijlig SDATA "[ijlig ]"--=small ij ligature-->
+<!ENTITY IJlig SDATA "[IJlig ]"--=capital IJ ligature-->
+<!ENTITY inodot SDATA "[inodot]"--=small i without dot-->
+<!ENTITY iogon SDATA "[iogon ]"--=small i, ogonek-->
+<!ENTITY Iogon SDATA "[Iogon ]"--=capital I, ogonek-->
+<!ENTITY itilde SDATA "[itilde]"--=small i, tilde-->
+<!ENTITY Itilde SDATA "[Itilde]"--=capital I, tilde-->
+<!ENTITY jcirc SDATA "[jcirc ]"--=small j, circumflex accent-->
+<!ENTITY Jcirc SDATA "[Jcirc ]"--=capital J, circumflex accent-->
+<!ENTITY kcedil SDATA "[kcedil]"--=small k, cedilla-->
+<!ENTITY Kcedil SDATA "[Kcedil]"--=capital K, cedilla-->
+<!ENTITY kgreen SDATA "[kgreen]"--=small k, Greenlandic-->
+<!ENTITY lacute SDATA "[lacute]"--=small l, acute accent-->
+<!ENTITY Lacute SDATA "[Lacute]"--=capital L, acute accent-->
+<!ENTITY lcaron SDATA "[lcaron]"--=small l, caron-->
+<!ENTITY Lcaron SDATA "[Lcaron]"--=capital L, caron-->
+<!ENTITY lcedil SDATA "[lcedil]"--=small l, cedilla-->
+<!ENTITY Lcedil SDATA "[Lcedil]"--=capital L, cedilla-->
+<!ENTITY lmidot SDATA "[lmidot]"--=small l, middle dot-->
+<!ENTITY Lmidot SDATA "[Lmidot]"--=capital L, middle dot-->
+<!ENTITY lstrok SDATA "[lstrok]"--=small l, stroke-->
+<!ENTITY Lstrok SDATA "[Lstrok]"--=capital L, stroke-->
+<!ENTITY nacute SDATA "[nacute]"--=small n, acute accent-->
+<!ENTITY Nacute SDATA "[Nacute]"--=capital N, acute accent-->
+<!ENTITY eng SDATA "[eng ]"--=small eng, Lapp-->
+<!ENTITY ENG SDATA "[ENG ]"--=capital ENG, Lapp-->
+<!ENTITY napos SDATA "[napos ]"--=small n, apostrophe-->
+<!ENTITY ncaron SDATA "[ncaron]"--=small n, caron-->
+<!ENTITY Ncaron SDATA "[Ncaron]"--=capital N, caron-->
+<!ENTITY ncedil SDATA "[ncedil]"--=small n, cedilla-->
+<!ENTITY Ncedil SDATA "[Ncedil]"--=capital N, cedilla-->
+<!ENTITY odblac SDATA "[odblac]"--=small o, double acute accent-->
+<!ENTITY Odblac SDATA "[Odblac]"--=capital O, double acute accent-->
+<!ENTITY Omacr SDATA "[Omacr ]"--=capital O, macron-->
+<!ENTITY omacr SDATA "[omacr ]"--=small o, macron-->
+<!ENTITY oelig SDATA "[oelig ]"--=small oe ligature-->
+<!ENTITY OElig SDATA "[OElig ]"--=capital OE ligature-->
+<!ENTITY racute SDATA "[racute]"--=small r, acute accent-->
+<!ENTITY Racute SDATA "[Racute]"--=capital R, acute accent-->
+<!ENTITY rcaron SDATA "[rcaron]"--=small r, caron-->
+<!ENTITY Rcaron SDATA "[Rcaron]"--=capital R, caron-->
+<!ENTITY rcedil SDATA "[rcedil]"--=small r, cedilla-->
+<!ENTITY Rcedil SDATA "[Rcedil]"--=capital R, cedilla-->
+<!ENTITY sacute SDATA "[sacute]"--=small s, acute accent-->
+<!ENTITY Sacute SDATA "[Sacute]"--=capital S, acute accent-->
+<!ENTITY scaron SDATA "[scaron]"--=small s, caron-->
+<!ENTITY Scaron SDATA "[Scaron]"--=capital S, caron-->
+<!ENTITY scedil SDATA "[scedil]"--=small s, cedilla-->
+<!ENTITY Scedil SDATA "[Scedil]"--=capital S, cedilla-->
+<!ENTITY scirc SDATA "[scirc ]"--=small s, circumflex accent-->
+<!ENTITY Scirc SDATA "[Scirc ]"--=capital S, circumflex accent-->
+<!ENTITY tcaron SDATA "[tcaron]"--=small t, caron-->
+<!ENTITY Tcaron SDATA "[Tcaron]"--=capital T, caron-->
+<!ENTITY tcedil SDATA "[tcedil]"--=small t, cedilla-->
+<!ENTITY Tcedil SDATA "[Tcedil]"--=capital T, cedilla-->
+<!ENTITY tstrok SDATA "[tstrok]"--=small t, stroke-->
+<!ENTITY Tstrok SDATA "[Tstrok]"--=capital T, stroke-->
+<!ENTITY ubreve SDATA "[ubreve]"--=small u, breve-->
+<!ENTITY Ubreve SDATA "[Ubreve]"--=capital U, breve-->
+<!ENTITY udblac SDATA "[udblac]"--=small u, double acute accent-->
+<!ENTITY Udblac SDATA "[Udblac]"--=capital U, double acute accent-->
+<!ENTITY umacr SDATA "[umacr ]"--=small u, macron-->
+<!ENTITY Umacr SDATA "[Umacr ]"--=capital U, macron-->
+<!ENTITY uogon SDATA "[uogon ]"--=small u, ogonek-->
+<!ENTITY Uogon SDATA "[Uogon ]"--=capital U, ogonek-->
+<!ENTITY uring SDATA "[uring ]"--=small u, ring-->
+<!ENTITY Uring SDATA "[Uring ]"--=capital U, ring-->
+<!ENTITY utilde SDATA "[utilde]"--=small u, tilde-->
+<!ENTITY Utilde SDATA "[Utilde]"--=capital U, tilde-->
+<!ENTITY wcirc SDATA "[wcirc ]"--=small w, circumflex accent-->
+<!ENTITY Wcirc SDATA "[Wcirc ]"--=capital W, circumflex accent-->
+<!ENTITY ycirc SDATA "[ycirc ]"--=small y, circumflex accent-->
+<!ENTITY Ycirc SDATA "[Ycirc ]"--=capital Y, circumflex accent-->
+<!ENTITY Yuml SDATA "[Yuml ]"--=capital Y, dieresis or umlaut mark-->
+<!ENTITY zacute SDATA "[zacute]"--=small z, acute accent-->
+<!ENTITY Zacute SDATA "[Zacute]"--=capital Z, acute accent-->
+<!ENTITY zcaron SDATA "[zcaron]"--=small z, caron-->
+<!ENTITY Zcaron SDATA "[Zcaron]"--=capital Z, caron-->
+<!ENTITY zdot SDATA "[zdot ]"--=small z, dot above-->
+<!ENTITY Zdot SDATA "[Zdot ]"--=capital Z, dot above-->
diff --git a/docs/docbook/dbsgml/ent/ISOnum b/docs/docbook/dbsgml/ent/ISOnum
new file mode 100755
index 00000000000..d7b41c33ae3
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOnum
@@ -0,0 +1,91 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOnum PUBLIC
+ "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN">
+ %ISOnum;
+-->
+<!ENTITY half SDATA "[half ]"--=fraction one-half-->
+<!ENTITY frac12 SDATA "[frac12]"--=fraction one-half-->
+<!ENTITY frac14 SDATA "[frac14]"--=fraction one-quarter-->
+<!ENTITY frac34 SDATA "[frac34]"--=fraction three-quarters-->
+<!ENTITY frac18 SDATA "[frac18]"--=fraction one-eighth-->
+<!ENTITY frac38 SDATA "[frac38]"--=fraction three-eighths-->
+<!ENTITY frac58 SDATA "[frac58]"--=fraction five-eighths-->
+<!ENTITY frac78 SDATA "[frac78]"--=fraction seven-eighths-->
+
+<!ENTITY sup1 SDATA "[sup1 ]"--=superscript one-->
+<!ENTITY sup2 SDATA "[sup2 ]"--=superscript two-->
+<!ENTITY sup3 SDATA "[sup3 ]"--=superscript three-->
+
+<!ENTITY plus SDATA "[plus ]"--=plus sign B:-- >
+<!ENTITY plusmn SDATA "[plusmn]"--/pm B: =plus-or-minus sign-->
+<!ENTITY lt SDATA "[lt ]"--=less-than sign R:-->
+<!ENTITY equals SDATA "[equals]"--=equals sign R:-->
+<!ENTITY gt SDATA "[gt ]"--=greater-than sign R:-->
+<!ENTITY divide SDATA "[divide]"--/div B: =divide sign-->
+<!ENTITY times SDATA "[times ]"--/times B: =multiply sign-->
+
+<!ENTITY curren SDATA "[curren]"--=general currency sign-->
+<!ENTITY pound SDATA "[pound ]"--=pound sign-->
+<!ENTITY dollar SDATA "[dollar]"--=dollar sign-->
+<!ENTITY cent SDATA "[cent ]"--=cent sign-->
+<!ENTITY yen SDATA "[yen ]"--/yen =yen sign-->
+
+<!ENTITY num SDATA "[num ]"--=number sign-->
+<!ENTITY percnt SDATA "[percnt]"--=percent sign-->
+<!ENTITY amp SDATA "[amp ]"--=ampersand-->
+<!ENTITY ast SDATA "[ast ]"--/ast B: =asterisk-->
+<!ENTITY commat SDATA "[commat]"--=commercial at-->
+<!ENTITY lsqb SDATA "[lsqb ]"--/lbrack O: =left square bracket-->
+<!ENTITY bsol SDATA "[bsol ]"--/backslash =reverse solidus-->
+<!ENTITY rsqb SDATA "[rsqb ]"--/rbrack C: =right square bracket-->
+<!ENTITY lcub SDATA "[lcub ]"--/lbrace O: =left curly bracket-->
+<!ENTITY horbar SDATA "[horbar]"--=horizontal bar-->
+<!ENTITY verbar SDATA "[verbar]"--/vert =vertical bar-->
+<!ENTITY rcub SDATA "[rcub ]"--/rbrace C: =right curly bracket-->
+<!ENTITY micro SDATA "[micro ]"--=micro sign-->
+<!ENTITY ohm SDATA "[ohm ]"--=ohm sign-->
+<!ENTITY deg SDATA "[deg ]"--=degree sign-->
+<!ENTITY ordm SDATA "[ordm ]"--=ordinal indicator, masculine-->
+<!ENTITY ordf SDATA "[ordf ]"--=ordinal indicator, feminine-->
+<!ENTITY sect SDATA "[sect ]"--=section sign-->
+<!ENTITY para SDATA "[para ]"--=pilcrow (paragraph sign)-->
+<!ENTITY middot SDATA "[middot]"--/centerdot B: =middle dot-->
+<!ENTITY larr SDATA "[larr ]"--/leftarrow /gets A: =leftward arrow-->
+<!ENTITY rarr SDATA "[rarr ]"--/rightarrow /to A: =rightward arrow-->
+<!ENTITY uarr SDATA "[uarr ]"--/uparrow A: =upward arrow-->
+<!ENTITY darr SDATA "[darr ]"--/downarrow A: =downward arrow-->
+<!ENTITY copy SDATA "[copy ]"--=copyright sign-->
+<!ENTITY reg SDATA "[reg ]"--/circledR =registered sign-->
+<!ENTITY trade SDATA "[trade ]"--=trade mark sign-->
+<!ENTITY brvbar SDATA "[brvbar]"--=broken (vertical) bar-->
+<!ENTITY not SDATA "[not ]"--/neg /lnot =not sign-->
+<!ENTITY sung SDATA "[sung ]"--=music note (sung text sign)-->
+
+<!ENTITY excl SDATA "[excl ]"--=exclamation mark-->
+<!ENTITY iexcl SDATA "[iexcl ]"--=inverted exclamation mark-->
+<!ENTITY quot SDATA "[quot ]"--=quotation mark-->
+<!ENTITY apos SDATA "[apos ]"--=apostrophe-->
+<!ENTITY lpar SDATA "[lpar ]"--O: =left parenthesis-->
+<!ENTITY rpar SDATA "[rpar ]"--C: =right parenthesis-->
+<!ENTITY comma SDATA "[comma ]"--P: =comma-->
+<!ENTITY lowbar SDATA "[lowbar]"--=low line-->
+<!ENTITY hyphen SDATA "[hyphen]"--=hyphen-->
+<!ENTITY period SDATA "[period]"--=full stop, period-->
+<!ENTITY sol SDATA "[sol ]"--=solidus-->
+<!ENTITY colon SDATA "[colon ]"--/colon P:-->
+<!ENTITY semi SDATA "[semi ]"--=semicolon P:-->
+<!ENTITY quest SDATA "[quest ]"--=question mark-->
+<!ENTITY iquest SDATA "[iquest]"--=inverted question mark-->
+<!ENTITY laquo SDATA "[laquo ]"--=angle quotation mark, left-->
+<!ENTITY raquo SDATA "[raquo ]"--=angle quotation mark, right-->
+<!ENTITY lsquo SDATA "[lsquo ]"--=single quotation mark, left-->
+<!ENTITY rsquo SDATA "[rsquo ]"--=single quotation mark, right-->
+<!ENTITY ldquo SDATA "[ldquo ]"--=double quotation mark, left-->
+<!ENTITY rdquo SDATA "[rdquo ]"--=double quotation mark, right-->
+<!ENTITY nbsp SDATA "[nbsp ]"--=no break (required) space-->
+<!ENTITY shy SDATA "[shy ]"--=soft hyphen-->
diff --git a/docs/docbook/dbsgml/ent/ISOpub b/docs/docbook/dbsgml/ent/ISOpub
new file mode 100755
index 00000000000..c184973cfdf
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOpub
@@ -0,0 +1,100 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOpub PUBLIC
+ "ISO 8879:1986//ENTITIES Publishing//EN">
+ %ISOpub;
+-->
+<!ENTITY emsp SDATA "[emsp ]"--=em space-->
+<!ENTITY ensp SDATA "[ensp ]"--=en space (1/2-em)-->
+<!ENTITY emsp13 SDATA "[emsp3 ]"--=1/3-em space-->
+<!ENTITY emsp14 SDATA "[emsp4 ]"--=1/4-em space-->
+<!ENTITY numsp SDATA "[numsp ]"--=digit space (width of a number)-->
+<!ENTITY puncsp SDATA "[puncsp]"--=punctuation space (width of comma)-->
+<!ENTITY thinsp SDATA "[thinsp]"--=thin space (1/6-em)-->
+<!ENTITY hairsp SDATA "[hairsp]"--=hair space-->
+<!ENTITY mdash SDATA "[mdash ]"--=em dash-->
+<!ENTITY ndash SDATA "[ndash ]"--=en dash-->
+<!ENTITY dash SDATA "[dash ]"--=hyphen (true graphic)-->
+<!ENTITY blank SDATA "[blank ]"--=significant blank symbol-->
+<!ENTITY hellip SDATA "[hellip]"--=ellipsis (horizontal)-->
+<!ENTITY nldr SDATA "[nldr ]"--=double baseline dot (en leader)-->
+<!ENTITY frac13 SDATA "[frac13]"--=fraction one-third-->
+<!ENTITY frac23 SDATA "[frac23]"--=fraction two-thirds-->
+<!ENTITY frac15 SDATA "[frac15]"--=fraction one-fifth-->
+<!ENTITY frac25 SDATA "[frac25]"--=fraction two-fifths-->
+<!ENTITY frac35 SDATA "[frac35]"--=fraction three-fifths-->
+<!ENTITY frac45 SDATA "[frac45]"--=fraction four-fifths-->
+<!ENTITY frac16 SDATA "[frac16]"--=fraction one-sixth-->
+<!ENTITY frac56 SDATA "[frac56]"--=fraction five-sixths-->
+<!ENTITY incare SDATA "[incare]"--=in-care-of symbol-->
+<!ENTITY block SDATA "[block ]"--=full block-->
+<!ENTITY uhblk SDATA "[uhblk ]"--=upper half block-->
+<!ENTITY lhblk SDATA "[lhblk ]"--=lower half block-->
+<!ENTITY blk14 SDATA "[blk14 ]"--=25% shaded block-->
+<!ENTITY blk12 SDATA "[blk12 ]"--=50% shaded block-->
+<!ENTITY blk34 SDATA "[blk34 ]"--=75% shaded block-->
+<!ENTITY marker SDATA "[marker]"--=histogram marker-->
+<!ENTITY cir SDATA "[cir ]"--/circ B: =circle, open-->
+<!ENTITY squ SDATA "[squ ]"--=square, open-->
+<!ENTITY rect SDATA "[rect ]"--=rectangle, open-->
+<!ENTITY utri SDATA "[utri ]"--/triangle =up triangle, open-->
+<!ENTITY dtri SDATA "[dtri ]"--/triangledown =down triangle, open-->
+<!ENTITY star SDATA "[star ]"--=star, open-->
+<!ENTITY bull SDATA "[bull ]"--/bullet B: =round bullet, filled-->
+<!ENTITY squf SDATA "[squf ]"--/blacksquare =sq bullet, filled-->
+<!ENTITY utrif SDATA "[utrif ]"--/blacktriangle =up tri, filled-->
+<!ENTITY dtrif SDATA "[dtrif ]"--/blacktriangledown =dn tri, filled-->
+<!ENTITY ltrif SDATA "[ltrif ]"--/blacktriangleleft R: =l tri, filled-->
+<!ENTITY rtrif SDATA "[rtrif ]"--/blacktriangleright R: =r tri, filled-->
+<!ENTITY clubs SDATA "[clubs ]"--/clubsuit =club suit symbol-->
+<!ENTITY diams SDATA "[diams ]"--/diamondsuit =diamond suit symbol-->
+<!ENTITY hearts SDATA "[hearts]"--/heartsuit =heart suit symbol-->
+<!ENTITY spades SDATA "[spades]"--/spadesuit =spades suit symbol-->
+<!ENTITY malt SDATA "[malt ]"--/maltese =maltese cross-->
+<!ENTITY dagger SDATA "[dagger]"--/dagger B: =dagger-->
+<!ENTITY Dagger SDATA "[Dagger]"--/ddagger B: =double dagger-->
+<!ENTITY check SDATA "[check ]"--/checkmark =tick, check mark-->
+<!ENTITY cross SDATA "[ballot]"--=ballot cross-->
+<!ENTITY sharp SDATA "[sharp ]"--/sharp =musical sharp-->
+<!ENTITY flat SDATA "[flat ]"--/flat =musical flat-->
+<!ENTITY male SDATA "[male ]"--=male symbol-->
+<!ENTITY female SDATA "[female]"--=female symbol-->
+<!ENTITY phone SDATA "[phone ]"--=telephone symbol-->
+<!ENTITY telrec SDATA "[telrec]"--=telephone recorder symbol-->
+<!ENTITY copysr SDATA "[copysr]"--=sound recording copyright sign-->
+<!ENTITY caret SDATA "[caret ]"--=caret (insertion mark)-->
+<!ENTITY lsquor SDATA "[lsquor]"--=rising single quote, left (low)-->
+<!ENTITY ldquor SDATA "[ldquor]"--=rising dbl quote, left (low)-->
+
+<!ENTITY fflig SDATA "[fflig ]"--small ff ligature-->
+<!ENTITY filig SDATA "[filig ]"--small fi ligature-->
+<!ENTITY fjlig SDATA "[fjlig ]"--small fj ligature-->
+<!ENTITY ffilig SDATA "[ffilig]"--small ffi ligature-->
+<!ENTITY ffllig SDATA "[ffllig]"--small ffl ligature-->
+<!ENTITY fllig SDATA "[fllig ]"--small fl ligature-->
+
+<!ENTITY mldr SDATA "[mldr ]"--em leader-->
+<!ENTITY rdquor SDATA "[rdquor]"--rising dbl quote, right (high)-->
+<!ENTITY rsquor SDATA "[rsquor]"--rising single quote, right (high)-->
+<!ENTITY vellip SDATA "[vellip]"--vertical ellipsis-->
+
+<!ENTITY hybull SDATA "[hybull]"--rectangle, filled (hyphen bullet)-->
+<!ENTITY loz SDATA "[loz ]"--/lozenge - lozenge or total mark-->
+<!ENTITY lozf SDATA "[lozf ]"--/blacklozenge - lozenge, filled-->
+<!ENTITY ltri SDATA "[ltri ]"--/triangleleft B: l triangle, open-->
+<!ENTITY rtri SDATA "[rtri ]"--/triangleright B: r triangle, open-->
+<!ENTITY starf SDATA "[starf ]"--/bigstar - star, filled-->
+
+<!ENTITY natur SDATA "[natur ]"--/natural - music natural-->
+<!ENTITY rx SDATA "[rx ]"--pharmaceutical prescription (Rx)-->
+<!ENTITY sext SDATA "[sext ]"--sextile (6-pointed star)-->
+
+<!ENTITY target SDATA "[target]"--register mark or target-->
+<!ENTITY dlcrop SDATA "[dlcrop]"--downward left crop mark -->
+<!ENTITY drcrop SDATA "[drcrop]"--downward right crop mark -->
+<!ENTITY ulcrop SDATA "[ulcrop]"--upward left crop mark -->
+<!ENTITY urcrop SDATA "[urcrop]"--upward right crop mark -->
diff --git a/docs/docbook/dbsgml/ent/ISOtech b/docs/docbook/dbsgml/ent/ISOtech
new file mode 100755
index 00000000000..cbda344869a
--- /dev/null
+++ b/docs/docbook/dbsgml/ent/ISOtech
@@ -0,0 +1,73 @@
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOtech PUBLIC
+ "ISO 8879:1986//ENTITIES General Technical//EN">
+ %ISOtech;
+-->
+<!ENTITY aleph SDATA "[aleph ]"--/aleph =aleph, Hebrew-->
+<!ENTITY and SDATA "[and ]"--/wedge /land B: =logical and-->
+<!ENTITY ang90 SDATA "[ang90 ]"--=right (90 degree) angle-->
+<!ENTITY angsph SDATA "[angsph]"--/sphericalangle =angle-spherical-->
+<!ENTITY ap SDATA "[ap ]"--/approx R: =approximate-->
+<!ENTITY becaus SDATA "[becaus]"--/because R: =because-->
+<!ENTITY bottom SDATA "[bottom]"--/bot B: =perpendicular-->
+<!ENTITY cap SDATA "[cap ]"--/cap B: =intersection-->
+<!ENTITY cong SDATA "[cong ]"--/cong R: =congruent with-->
+<!ENTITY conint SDATA "[conint]"--/oint L: =contour integral operator-->
+<!ENTITY cup SDATA "[cup ]"--/cup B: =union or logical sum-->
+<!ENTITY equiv SDATA "[equiv ]"--/equiv R: =identical with-->
+<!ENTITY exist SDATA "[exist ]"--/exists =at least one exists-->
+<!ENTITY forall SDATA "[forall]"--/forall =for all-->
+<!ENTITY fnof SDATA "[fnof ]"--=function of (italic small f)-->
+<!ENTITY ge SDATA "[ge ]"--/geq /ge R: =greater-than-or-equal-->
+<!ENTITY iff SDATA "[iff ]"--/iff =if and only if-->
+<!ENTITY infin SDATA "[infin ]"--/infty =infinity-->
+<!ENTITY int SDATA "[int ]"--/int L: =integral operator-->
+<!ENTITY isin SDATA "[isin ]"--/in R: =set membership-->
+<!ENTITY lang SDATA "[lang ]"--/langle O: =left angle bracket-->
+<!ENTITY lArr SDATA "[lArr ]"--/Leftarrow A: =is implied by-->
+<!ENTITY le SDATA "[le ]"--/leq /le R: =less-than-or-equal-->
+<!ENTITY minus SDATA "[minus ]"--B: =minus sign-->
+<!ENTITY mnplus SDATA "[mnplus]"--/mp B: =minus-or-plus sign-->
+<!ENTITY nabla SDATA "[nabla ]"--/nabla =del, Hamilton operator-->
+<!ENTITY ne SDATA "[ne ]"--/ne /neq R: =not equal-->
+<!ENTITY ni SDATA "[ni ]"--/ni /owns R: =contains-->
+<!ENTITY or SDATA "[or ]"--/vee /lor B: =logical or-->
+<!ENTITY par SDATA "[par ]"--/parallel R: =parallel-->
+<!ENTITY part SDATA "[part ]"--/partial =partial differential-->
+<!ENTITY permil SDATA "[permil]"--=per thousand-->
+<!ENTITY perp SDATA "[perp ]"--/perp R: =perpendicular-->
+<!ENTITY prime SDATA "[prime ]"--/prime =prime or minute-->
+<!ENTITY Prime SDATA "[Prime ]"--=double prime or second-->
+<!ENTITY prop SDATA "[prop ]"--/propto R: =is proportional to-->
+<!ENTITY radic SDATA "[radic ]"--/surd =radical-->
+<!ENTITY rang SDATA "[rang ]"--/rangle C: =right angle bracket-->
+<!ENTITY rArr SDATA "[rArr ]"--/Rightarrow A: =implies-->
+<!ENTITY sim SDATA "[sim ]"--/sim R: =similar-->
+<!ENTITY sime SDATA "[sime ]"--/simeq R: =similar, equals-->
+<!ENTITY square SDATA "[square]"--/square B: =square-->
+<!ENTITY sub SDATA "[sub ]"--/subset R: =subset or is implied by-->
+<!ENTITY sube SDATA "[sube ]"--/subseteq R: =subset, equals-->
+<!ENTITY sup SDATA "[sup ]"--/supset R: =superset or implies-->
+<!ENTITY supe SDATA "[supe ]"--/supseteq R: =superset, equals-->
+<!ENTITY there4 SDATA "[there4]"--/therefore R: =therefore-->
+<!ENTITY Verbar SDATA "[Verbar]"--/Vert =dbl vertical bar-->
+
+<!ENTITY angst SDATA "[angst ]"--Angstrom =capital A, ring-->
+<!ENTITY bernou SDATA "[bernou]"--Bernoulli function (script capital B)-->
+<!ENTITY compfn SDATA "[compfn]"--B: composite function (small circle)-->
+<!ENTITY Dot SDATA "[Dot ]"--=dieresis or umlaut mark-->
+<!ENTITY DotDot SDATA "[DotDot]"--four dots above-->
+<!ENTITY hamilt SDATA "[hamilt]"--Hamiltonian (script capital H)-->
+<!ENTITY lagran SDATA "[lagran]"--Lagrangian (script capital L)-->
+<!ENTITY lowast SDATA "[lowast]"--low asterisk-->
+<!ENTITY notin SDATA "[notin ]"--N: negated set membership-->
+<!ENTITY order SDATA "[order ]"--order of (script small o)-->
+<!ENTITY phmmat SDATA "[phmmat]"--physics M-matrix (script capital M)-->
+<!ENTITY tdot SDATA "[tdot ]"--three dots above-->
+<!ENTITY tprime SDATA "[tprime]"--triple prime-->
+<!ENTITY wedgeq SDATA "[wedgeq]"--R: corresponds to (wedge, equals)-->
diff --git a/docs/docbook/dbsgml/readme.txt b/docs/docbook/dbsgml/readme.txt
new file mode 100755
index 00000000000..52d3f9f4aaf
--- /dev/null
+++ b/docs/docbook/dbsgml/readme.txt
@@ -0,0 +1,12 @@
+README for DocBook V4.1
+
+This is DocBook V4.1, released 19 June 2000.
+
+See 40chg.txt for information about what has changed since DocBook 3.1.
+
+For more information about DocBook, please see
+
+ http://www.oasis-open.org/docbook/
+
+Please send all questions, comments, concerns, and bug reports to the
+DocBook mailing list: docbook@lists.oasis-open.org
diff --git a/docs/docbook/docbook.txt b/docs/docbook/docbook.txt
new file mode 100755
index 00000000000..388cd5cf9b7
--- /dev/null
+++ b/docs/docbook/docbook.txt
@@ -0,0 +1,136 @@
+!==
+!== docbook.txt for Samba 2.2.0 release
+!==
+!== Author: David Bannon, D.Bannon@latrobe.edu.au November, 2000
+!== Updates: Gerald (Jerry) Carter, jerry@samba.org, Feb. 2001
+
+What are DocBook documents doing in the Samba Distribution ?
+-----------------------------------------------------------
+
+We are planning to convert all of the samba docs to SGML/DocBook V4.1
+in order to make them easier to maintain and produce a nicer looking
+product.
+
+This short note (strange isn't it how it always starts out as a short note
+and becomes a long one ?) will explain very briefly how and why we are
+doing this.
+
+
+The format
+----------
+
+If you are new to sgml, regard an sgml file as 'source code'. You don't
+read it directly, use it to create other formats (like the txt and html
+included in ../txt and ../html).
+
+Docbook is a particular SGML style, particularly suited to producing
+technical manuals. In the two documents I have produced so far I have used
+DocBook 4.1, it seems that products like RedHat Linux is still include only
+version 3.1, the differences are minor. The Linux Documentation Project is
+using a modified version of 3.1 but are really geared up to make multi
+paged documents, something we want to avoid for logistic reasons.
+
+For more information on DocBook tags and format, see "DocBook: The
+Definitive Guide" by Walsh and Muellner, (c) O'Reilly Publishing.
+This book covers DocBook V3.1 and is available on-line
+at http://www.docbook.org/
+
+The Output
+----------
+
+The current Samba CVS tree contains the SGML/DocBook source files as well
+as the following autogenerated formats
+
+ * man pages
+ * HTML
+ * ASCII text (where appropriate)
+
+
+The Tools
+---------
+
+[
+ addendum: For a good general overview of installing the tools
+ needed for generating files from SGML/DocBook source, refer
+ to the DocBook-Install mini HOWTO at
+ http://www.ibiblio.org/pub/Linux/docs/HOWTO/mini/DocBook-Install
+
+ While the above link is to a Linux HOWTO, the tools can be installed
+ on almost any UNIX platform.
+
+ David's original notes follow below:
+]
+
+Any sgml document needs to be referred to a suitable style sheet
+(describing syntax) and other sheets that tell the translating programmes
+how to do the translations. The list of necessary 'included files is a
+bit messy but once installed is pretty easy.
+
+On one of my RedHat 6.2 systems I installed the following:
+* sgml-common (as an rpm)
+* docbook (as an rpm)
+* stylesheets (as an rpm)
+* jade (as an rpm)
+* Docbook 4.1 from http://docbook.org
+* DSSSL 157 from http://nwalsh.com/docbook/dsssl/
+
+There are several downloadable descriptions of the DocBook syntax at the
+web sites mentioned above. Note that a lot of the docs only talk about
+version 3.1 with 4.1 as an add-on.
+
+In either case you will need to include in the html/docbook.dsl and most
+likely a couple of defines to achieve a suitable output. I made a
+local dsl file that I called html.dsl that looks like this :
+
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY dbstyle SYSTEM "/usr/lib/sgml/dsssl-157/docbook/html/docbook.dsl"
+CDATA DSSSL>
+]>
+
+<style-sheet>
+<style-specification use="docbook">
+<style-specification-body>
+
+(define nochunks #t) ;; Dont make multiple pages
+(define rootchunk #t) ;; Do make a 'root' page
+(define %use-id-as-filename% #t) ;; Use book id as filename
+(define %html-ext% ".html") ;; give it a proper html extension
+
+</style-specification-body>
+</style-specification>
+<external-specification id="docbook" document="dbstyle">
+</style-sheet>
+
+Note the top block that refers to where the dsssl-157 style sheets are
+installed, if you don’t put them there make sure you edit the file.
+
+To use this stylesheet, have it in your working directory along with your
+sgml files. Jade does the actual conversion to html, call it like this :
+
+jade -t sgml -d html.dsl stuff.sgml
+
+To create the text version run the html through lynx :
+
+Lynx -dump -nolist stuff.html > stuff.txt
+
+These instructions are crude by might help someone get going. Please feel
+free to contact me if you have any questions or if you can correct any one
+of the many mistakes I must have made above.
+
+David
+
+==========================================================================
+
+This directory now contains a ./configure script and Makefile to
+support the automated building of man pages (including HTML versions).
+The DocBook V4.1 DTD and ISO entity files have also been included in CVS
+to make sure we are all working from the same plate.
+
+The SGML_CATALOG_FILES environment variable should be set as follows
+(this assumes you have a working local installation of jade and
+Norman's Walsh's DSSSL stylesheets):
+
+ export SGML_CATALOG_FILES=$SGML_CATALOG_FILES:./dbsgml/catalog
+
+
+--jerry
diff --git a/docs/docbook/faq/README.NOW b/docs/docbook/faq/README.NOW
new file mode 100755
index 00000000000..77f1659a89c
--- /dev/null
+++ b/docs/docbook/faq/README.NOW
@@ -0,0 +1,2 @@
+The files previously in this directory have been incorporated
+into the Samba-HOWTO-Collection
diff --git a/docs/docbook/global.ent b/docs/docbook/global.ent
new file mode 100755
index 00000000000..91286de98be
--- /dev/null
+++ b/docs/docbook/global.ent
@@ -0,0 +1,33 @@
+<!-- Global Entities File -->
+
+
+<!-- Email Address' -->
+<!ENTITY email.dbannon 'D.Bannon@latrobe.edu.au'>
+<!ENTITY email.jmoore 'jmoore@php.net'>
+<!ENTITY email.jerry 'jerry@samba.org'>
+<!ENTITY email.patches 'samba-patches@samba.org'>
+
+<!-- URL's -->
+<!ENTITY url.samba.cvsinfo 'http://pserver.samba.org/samba/cvs.html'>
+<!ENTITY url.pdc-howto.local 'samba-pdc-howto.html'>
+<!ENTITY url.samba-tng 'http://www.samba-tng.org'>
+<!ENTITY url.samba.doc 'http://bioserve.latrobe.edu.au/samba/'>
+<!ENTITY url.ultraedit 'http://www.ultraedit.com'>
+<!ENTITY url.vi-windows 'http://home.snafu.de/ramo/WinViEn.htm'>
+<!ENTITY url.pfe 'http://www.lancs.ac.uk/people/cpaap/pfe/'>
+<!ENTITY url.server-tools.win95 'ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE'>
+<!ENTITY url.server-tools.winnt 'ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE'>
+<!ENTITY url.tcpdump 'http://www.tcpdump.org/'>
+<!ENTITY url.samba 'http://samba.org'>
+<!ENTITY url.samba-ldap-howto 'http://www.unav.es/cti/ldap-smb-howto.html'>
+<!ENTITY url.samba-tng.home 'http://www.kneschke.de/projekte/samba_tng/'>
+<!ENTITY url.samba.mailinglist.ntdom 'http://lists.samba.org/mailman/roster/samba-ntdom'>
+<!ENTITY url.samba.cifs 'http://samba.org/cifs/'>
+<!ENTITY url.ntdomains-for-unix 'http://mailhost.cb1.com/~lkcl/ntdom/'>
+<!ENTITY url.samba.specs.old 'ftp://ftp.microsoft.com/developr/drg/CIFS/'>
+<!ENTITY url.rfc.1001 'http://ds.internic.net/rfc/rfc1001.txt'>
+<!ENTITY url.rfc.1002 'http://ds.internic.net/rfc/rfc1002.txt'>
+
+<!-- Misc -->
+<!ENTITY samba.pub.cvshost 'pserver.samba.org'>
+
diff --git a/docs/docbook/howto/README.NOW b/docs/docbook/howto/README.NOW
new file mode 100755
index 00000000000..77f1659a89c
--- /dev/null
+++ b/docs/docbook/howto/README.NOW
@@ -0,0 +1,2 @@
+The files previously in this directory have been incorporated
+into the Samba-HOWTO-Collection
diff --git a/docs/docbook/manpages/findsmb.1.sgml b/docs/docbook/manpages/findsmb.1.sgml
new file mode 100755
index 00000000000..d8f436c4a12
--- /dev/null
+++ b/docs/docbook/manpages/findsmb.1.sgml
@@ -0,0 +1,131 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="findsmb">
+
+<refmeta>
+ <refentrytitle>findsmb</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>findsmb</refname>
+ <refpurpose>list info about machines that respond to SMB
+ name queries on a subnet</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>findsmb</command>
+ <arg choice="opt">subnet broadcast address</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This perl script is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>findsmb</command> is a perl script that
+ prints out several pieces of information about machines
+ on a subnet that respond to SMB name query requests.
+ It uses <ulink url="nmblookup.1.html"><command>
+ nmblookup(1)</command></ulink> and <ulink url="smbclient.1.html">
+ <command>smbclient(1)</command></ulink> to obtain this information.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>subnet broadcast address</term>
+ <listitem><para>Without this option, <command>findsmb
+ </command> will probe the subnet of the machine where
+ <command>findsmb</command> is run. This value is passed
+ to <command>nmblookup</command> as part of the
+ <constant>-B</constant> option</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para>The output of <command>findsmb</command> lists the following
+ information for all machines that respond to the initial
+ <command>nmblookup</command> for any name: IP address, NetBIOS name,
+ Workgroup name, operating system, and SMB server version.</para>
+
+ <para>There will be a '+' in front of the workgroup name for
+ machines that are local master browsers for that workgroup. There
+ will be an '*' in front of the workgroup name for
+ machines that are the domain master browser for that workgroup.
+ Machines that are running Windows, Windows 95 or Windows 98 will
+ not show any information about the operating system or server
+ version.</para>
+
+ <para>The command must be run on a system without <ulink
+ url="nmbd.8.html"><command>nmbd</command></ulink> running.
+ If <command>nmbd</command> is running on the system, you will
+ only get the IP address and the DNS name of the machine. To
+ get proper responses from Windows 95 and Windows 98 machines,
+ the command must be run as root. </para>
+
+ <para>For example running <command>findsmb</command> on a machine
+ without <command>nmbd</command> running would yield output similar
+ to the following</para>
+
+ <screen><computeroutput>
+IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION
+---------------------------------------------------------------------
+192.168.35.10 MINESET-TEST1 [DMVENGR]
+192.168.35.55 LINUXBOX *[MYGROUP] [Unix] [Samba 2.0.6]
+192.168.35.56 HERBNT2 [HERB-NT]
+192.168.35.63 GANDALF [MVENGR] [Unix] [Samba 2.0.5a for IRIX]
+192.168.35.65 SAUNA [WORKGROUP] [Unix] [Samba 1.9.18p10]
+192.168.35.71 FROGSTAR [ENGR] [Unix] [Samba 2.0.0 for IRIX]
+192.168.35.78 HERBDHCP1 +[HERB]
+192.168.35.88 SCNT2 +[MVENGR] [Windows NT 4.0] [NT LAN Manager 4.0]
+192.168.35.93 FROGSTAR-PC [MVENGR] [Windows 5.0] [Windows 2000 LAN Manager]
+192.168.35.97 HERBNT1 *[HERB-NT] [Windows NT 4.0] [NT LAN Manager 4.0]
+ </computeroutput></screen>
+
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="nmbd.8.html"><command>nmbd(8)</command></ulink>,
+ <ulink url="smbclient.1.html"><command>smbclient(1)
+ </command></ulink>, and <ulink url="nmblookup.1.html">
+ <command>nmblookup(1)</command></ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/lmhosts.5.sgml b/docs/docbook/manpages/lmhosts.5.sgml
new file mode 100755
index 00000000000..7934c18e8ec
--- /dev/null
+++ b/docs/docbook/manpages/lmhosts.5.sgml
@@ -0,0 +1,114 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="lmhosts">
+
+<refmeta>
+ <refentrytitle>lmhosts</refentrytitle>
+ <manvolnum>5</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>lmhosts</refname>
+ <refpurpose>The Samba NetBIOS hosts file</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <para><filename>lmhosts</filename> is the <ulink url="samba.7.html">
+ Samba</ulink> NetBIOS name to IP address mapping file.</para>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This file is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><filename>lmhosts</filename> is the <emphasis>Samba
+ </emphasis> NetBIOS name to IP address mapping file. It
+ is very similar to the <filename>/etc/hosts</filename> file
+ format, except that the hostname component must correspond
+ to the NetBIOS naming format.</para>
+</refsect1>
+
+<refsect1>
+ <title>FILE FORMAT</title>
+ <para>It is an ASCII file containing one line for NetBIOS name.
+ The two fields on each line are separated from each other by
+ white space. Any entry beginning with '#' is ignored. Each line
+ in the lmhosts file contains the following information :</para>
+
+ <itemizedlist>
+ <listitem><para>IP Address - in dotted decimal format.</para>
+ </listitem>
+
+ <listitem><para>NetBIOS Name - This name format is a
+ maximum fifteen character host name, with an optional
+ trailing '#' character followed by the NetBIOS name type
+ as two hexadecimal digits.</para>
+
+ <para>If the trailing '#' is omitted then the given IP
+ address will be returned for all names that match the given
+ name, whatever the NetBIOS name type in the lookup.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>An example follows :</para>
+
+ <para><programlisting>
+#
+# Sample Samba lmhosts file.
+#
+192.9.200.1 TESTPC
+192.9.200.20 NTSERVER#20
+192.9.200.21 SAMBASERVER
+ </programlisting></para>
+
+ <para>Contains three IP to NetBIOS name mappings. The first
+ and third will be returned for any queries for the names "TESTPC"
+ and "SAMBASERVER" respectively, whatever the type component of
+ the NetBIOS name requested.</para>
+
+ <para>The second mapping will be returned only when the "0x20" name
+ type for a name "NTSERVER" is queried. Any other name type will not
+ be resolved.</para>
+
+ <para>The default location of the <filename>lmhosts</filename> file
+ is in the same directory as the <ulink url="smb.conf.5.html">
+ smb.conf(5)></ulink> file.</para>
+
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbclient.1.html"><command>smbclient(1)
+ </command></ulink>, <ulink url="smb.conf.5.html#NAMERESOLVEORDER">
+ smb.conf(5)</ulink>, and <ulink url="smbpasswd.8.html"><command>
+ smbpasswd(8)</command></ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/make_smbcodepage.1.sgml b/docs/docbook/manpages/make_smbcodepage.1.sgml
new file mode 100755
index 00000000000..a36f9b968c1
--- /dev/null
+++ b/docs/docbook/manpages/make_smbcodepage.1.sgml
@@ -0,0 +1,197 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="make-smbcodepage">
+
+<refmeta>
+ <refentrytitle>make_smbcodepage</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>make_smbcodepage</refname>
+ <refpurpose>construct a codepage file for Samba</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>make_smbcodepage</command>
+ <arg choice="req">c|d</arg>
+ <arg choice="req">codepage</arg>
+ <arg choice="req">inputfile</arg>
+ <arg choice="req">outputfile</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>make_smbcodepage</command> compiles or de-compiles
+ codepage files for use with the internationalization features
+ of Samba 2.2</para>
+</refsect1>
+
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>c|d</term>
+ <listitem><para>This tells <command>make_smbcodepage</command>
+ if it is compiling (<parameter>c</parameter>) a text format code
+ page file to binary, or (<parameter>d</parameter>) de-compiling
+ a binary codepage file to text. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>codepage</term>
+ <listitem><para>This is the codepage we are processing (a
+ number, e.g. 850). </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>inputfile</term>
+ <listitem><para>This is the input file to process. In
+ the <parameter>c</parameter> case this will be a text
+ codepage definition file such as the ones found in the Samba
+ <filename>source/codepages</filename> directory. In
+ the <parameter>d</parameter> case this will be the
+ binary format codepage definition file normally found in
+ the <filename>lib/codepages</filename> directory in the
+ Samba install directory path.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>outputfile</term>
+ <listitem><para>This is the output file to produce.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>Samba Codepage Files</title>
+
+ <para>A text Samba codepage definition file is a description
+ that tells Samba how to map from upper to lower case for
+ characters greater than ascii 127 in the specified DOS code page.
+ Note that for certain DOS codepages (437 for example) mapping
+ from lower to upper case may be non-symmetrical. For example, in
+ code page 437 lower case a acute maps to a plain upper case A
+ when going from lower to upper case, but plain upper case A maps
+ to plain lower case a when lower casing a character. </para>
+
+ <para>A binary Samba codepage definition file is a binary
+ representation of the same information, including a value that
+ specifies what codepage this file is describing. </para>
+
+ <para>As Samba does not yet use UNICODE (current for Samba version 2.2)
+ you must specify the client code page that your DOS and Windows
+ clients are using if you wish to have case insensitivity done
+ correctly for your particular language. The default codepage Samba
+ uses is 850 (Western European). Text codepage definition sample files
+ are provided in the Samba distribution for codepages 437 (USA), 737 (Greek),
+ 850 (Western European) 852 (MS-DOS Latin 2), 861 (Icelandic), 866 (Cyrillic),
+ 932 (Kanji SJIS), 936 (Simplified Chinese), 949 (Hangul) and 950 (Traditional
+ Chinese). Users are encouraged to write text codepage definition files for
+ their own code pages and donate them to samba@samba.org. All codepage files
+ in the Samba <filename>source/codepages</filename> directory are
+ compiled and installed when a <command>'make install'</command>
+ command is issued there. </para>
+
+ <para>The client codepage used by the <command>smbd</command> server
+ is configured using the <command>client code page</command> parameter
+ in the <command>smb.conf</command> file. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>Files</title>
+
+ <para><command>codepage_def.&lt;codepage&gt;</command></para>
+
+ <para>These are the input (text) codepage files provided in the
+ Samba <filename>source/codepages</filename> directory.</para>
+
+ <para>A text codepage definition file consists of multiple lines
+ containing four fields. These fields are:</para>
+
+ <itemizedlist>
+ <listitem><para><command>lower</command>: which is the
+ (hex) lower case character mapped on this line.</para>
+ </listitem>
+
+ <listitem><para><command>upper</command>: which is the (hex)
+ upper case character that the lower case character will map to.
+ </para></listitem>
+
+ <listitem><para><command>map upper to lower</command> which
+ is a boolean value (put either True or False here) which tells
+ Samba if it is to map the given upper case character to the
+ given lower case character when lower casing a filename.
+ </para></listitem>
+
+ <listitem><para><command>map lower to upper</command> which
+ is a boolean value (put either True or False here) which tells
+ Samba if it is to map the given lower case character to the
+ given upper case character when upper casing a filename.
+ </para></listitem>
+ </itemizedlist>
+
+
+ <para><command>codepage.&lt;codepage&gt;</command> - These are the
+ output (binary) codepage files produced and placed in the Samba
+ destination <filename>lib/codepage</filename> directory. </para>
+</refsect1>
+
+<refsect1>
+ <title>Installation</title>
+
+ <para>The location of the server and its support files is a
+ matter for individual system administrators. The following are
+ thus suggestions only. </para>
+
+ <para>It is recommended that the <command>make_smbcodepage
+ </command> program be installed under the <filename>/usr/local/samba
+ </filename> hierarchy, in a directory readable by all, writeable
+ only by root. The program itself should be executable by all. The
+ program should NOT be setuid or setgid! </para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/make_unicodemap.1.sgml b/docs/docbook/manpages/make_unicodemap.1.sgml
new file mode 100755
index 00000000000..5e7292341b0
--- /dev/null
+++ b/docs/docbook/manpages/make_unicodemap.1.sgml
@@ -0,0 +1,172 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="make-unicodemap">
+
+<refmeta>
+ <refentrytitle>make_unicodemap</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>make_unicodemap</refname>
+ <refpurpose>construct a unicode map file for Samba</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>make_unicodemap</command>
+ <arg choice="req">codepage</arg>
+ <arg choice="req">inputfile</arg>
+ <arg choice="req">outputfile</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>
+ This tool is part of the <ulink url="samba.7.html">Samba</ulink>
+ suite.
+ </para>
+
+ <para>
+ <command>make_unicodemap</command> compiles text unicode map
+ files into binary unicode map files for use with the
+ internationalization features of Samba 2.2.
+ </para>
+</refsect1>
+
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>codepage</term>
+ <listitem><para>This is the codepage or UNIX character
+ set we are processing (a number, e.g. 850).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>inputfile</term>
+ <listitem><para>This is the input file to process. This is a
+ text unicode map file such as the ones found in the Samba
+ <filename>source/codepages</filename> directory.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>outputfile</term>
+ <listitem><para>This is the binary output file to produce.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>Samba Unicode Map Files</title>
+
+ <para>
+ A text Samba unicode map file is a description that tells Samba
+ how to map characters from a specified DOS code page or UNIX character
+ set to 16 bit unicode.
+ </para>
+
+ <para>A binary Samba unicode map file is a binary representation
+ of the same information, including a value that specifies what
+ codepage or UNIX character set this file is describing.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>Files</title>
+
+ <para><filename>CP&lt;codepage&gt;.TXT</filename></para>
+
+ <para>
+ These are the input (text) unicode map files provided
+ in the Samba <filename>source/codepages</filename>
+ directory.
+ </para>
+
+ <para>
+ A text unicode map file consists of multiple lines
+ containing two fields. These fields are :
+ </para>
+
+ <itemizedlist>
+ <listitem><para><parameter>character</parameter> - which is
+ the (hex) character mapped on this line.
+ </para></listitem>
+
+ <listitem><para><parameter>unicode</parameter> - which
+ is the (hex) 16 bit unicode character that the character
+ will map to.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ <filename>unicode_map.&lt;codepage&gt;</filename> - These are
+ the output (binary) unicode map files produced and placed in
+ the Samba destination <filename>lib/codepage</filename>
+ directory.
+ </para>
+</refsect1>
+
+
+<refsect1>
+ <title>Installation</title>
+
+ <para>
+ The location of the server and its support files is a matter
+ for individual system administrators. The following are thus
+ suggestions only.
+ </para>
+
+ <para>
+ It is recommended that the <command>make_unicodemap</command>
+ program be installed under the
+ <filename>$prefix/samba</filename> hierarchy,
+ in a directory readable by all, writeable only by root. The
+ program itself should be executable by all. The program
+ should NOT be setuid or setgid!
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/nmbd.8.sgml b/docs/docbook/manpages/nmbd.8.sgml
new file mode 100755
index 00000000000..c9ddc89bcbb
--- /dev/null
+++ b/docs/docbook/manpages/nmbd.8.sgml
@@ -0,0 +1,372 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="nmbd">
+
+<refmeta>
+ <refentrytitle>nmbd</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>nmbd</refname>
+ <refpurpose>NetBIOS name server to provide NetBIOS
+ over IP naming services to clients</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>nmbd</command>
+ <arg choice="opt">-D</arg>
+ <arg choice="opt">-a</arg>
+ <arg choice="opt">-i</arg>
+ <arg choice="opt">-o</arg>
+ <arg choice="opt">-P</arg>
+ <arg choice="opt">-h</arg>
+ <arg choice="opt">-V</arg>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-H &lt;lmhosts file&gt;</arg>
+ <arg choice="opt">-l &lt;log directory&gt;</arg>
+ <arg choice="opt">-n &lt;primary netbios name&gt;</arg>
+ <arg choice="opt">-p &lt;port number&gt;</arg>
+ <arg choice="opt">-s &lt;configuration file&gt;</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+ <para>This program is part of the Samba suite.</para>
+
+ <para><command>nmbd</command> is a server that understands
+ and can reply to NetBIOS over IP name service requests, like
+ those produced by SMB/CIFS clients such as Windows 95/98/ME,
+ Windows NT, Windows 2000, and LanManager clients. It also
+ participates in the browsing protocols which make up the
+ Windows "Network Neighborhood" view.</para>
+
+ <para>SMB/CIFS clients, when they start up, may wish to
+ locate an SMB/CIFS server. That is, they wish to know what
+ IP number a specified host is using.</para>
+
+ <para>Amongst other services, <command>nmbd</command> will
+ listen for such requests, and if its own NetBIOS name is
+ specified it will respond with the IP number of the host it
+ is running on. Its "own NetBIOS name" is by
+ default the primary DNS name of the host it is running on,
+ but this can be overridden with the <emphasis>-n</emphasis>
+ option (see OPTIONS below). Thus <command>nmbd</command> will
+ reply to broadcast queries for its own name(s). Additional
+ names for <command>nmbd</command> to respond on can be set
+ via parameters in the <ulink url="smb.conf.5.html"><filename>
+ smb.conf(5)</filename></ulink> configuration file.</para>
+
+ <para><command>nmbd</command> can also be used as a WINS
+ (Windows Internet Name Server) server. What this basically means
+ is that it will act as a WINS database server, creating a
+ database from name registration requests that it receives and
+ replying to queries from clients for these names.</para>
+
+ <para>In addition, <command>nmbd</command> can act as a WINS
+ proxy, relaying broadcast queries from clients that do
+ not understand how to talk the WINS protocol to a WIN
+ server.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-D</term>
+ <listitem><para>If specified, this parameter causes
+ <command>nmbd</command> to operate as a daemon. That is,
+ it detaches itself and runs in the background, fielding
+ requests on the appropriate port. By default, <command>nmbd</command>
+ will operate as a daemon if launched from a command shell.
+ nmbd can also be operated from the <command>inetd</command>
+ meta-daemon, although this is not recommended.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-a</term>
+ <listitem><para>If this parameter is specified, each new
+ connection will append log messages to the log file.
+ This is the default.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i</term>
+ <listitem><para>If this parameter is specified it causes the
+ server to run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell. Setting this
+ parameter negates the implicit deamon mode when run from the
+ command line.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-o</term>
+ <listitem><para>If this parameter is specified, the
+ log files will be overwritten when opened. By default,
+ <command>smbd</command> will append entries to the log
+ files.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Prints the help information (usage)
+ for <command>nmbd</command>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-H &lt;filename&gt;</term>
+ <listitem><para>NetBIOS lmhosts file. The lmhosts
+ file is a list of NetBIOS names to IP addresses that
+ is loaded by the nmbd server and used via the name
+ resolution mechanism <ulink url="smb.conf.5.html#nameresolveorder">
+ name resolve order</ulink> described in <ulink
+ url="smb.conf.5.html"> <filename>smb.conf(5)</filename></ulink>
+ to resolve any NetBIOS name queries needed by the server. Note
+ that the contents of this file are <emphasis>NOT</emphasis>
+ used by <command>nmbd</command> to answer any name queries.
+ Adding a line to this file affects name NetBIOS resolution
+ from this host <emphasis>ONLY</emphasis>.</para>
+
+ <para>The default path to this file is compiled into
+ Samba as part of the build process. Common defaults
+ are <filename>/usr/local/samba/lib/lmhosts</filename>,
+ <filename>/usr/samba/lib/lmhosts</filename> or
+ <filename>/etc/lmhosts</filename>. See the <ulink url="lmhosts.5.html">
+ <filename>lmhosts(5)</filename></ulink> man page for details on the
+ contents of this file.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-V</term>
+ <listitem><para>Prints the version number for
+ <command>nmbd</command>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-d &lt;debug level&gt;</term>
+ <listitem><para>debuglevel is an integer
+ from 0 to 10. The default value if this parameter is
+ not specified is zero.</para>
+
+ <para>The higher this value, the more detail will
+ be logged to the log files about the activities of the
+ server. At level 0, only critical errors and serious
+ warnings will be logged. Level 1 is a reasonable level for
+ day to day running - it generates a small amount of
+ information about operations carried out.</para>
+
+ <para>Levels above 1 will generate considerable amounts
+ of log data, and should only be used when investigating
+ a problem. Levels above 3 are designed for use only by developers
+ and generate HUGE amounts of log data, most of which is extremely
+ cryptic.</para>
+
+ <para>Note that specifying this parameter here will override
+ the <ulink url="smb.conf.5.html#loglevel">log level</ulink>
+ parameter in the <ulink url="smb.conf.5.html"><filename>
+ smb.conf</filename></ulink> file.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l &lt;log directory&gt;</term>
+ <listitem><para>The -l parameter specifies a directory
+ into which the "log.nmbd" log file will be created
+ for operational data from the running
+ <command>nmbd</command> server. The default log directory is compiled into Samba
+ as part of the build process. Common defaults are <filename>
+ /usr/local/samba/var/log.nmb</filename>, <filename>
+ /usr/samba/var/log.nmb</filename> or
+ <filename>/var/log/log.nmb</filename>. <emphasis>Beware:</emphasis>
+ If the directory specified does not exist, <command>nmbd</command>
+ will log to the default debug log location defined at compile time.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-n &lt;primary NetBIOS name&gt;</term>
+ <listitem><para>This option allows you to override
+ the NetBIOS name that Samba uses for itself. This is identical
+ to setting the <ulink url="smb.conf.5.html#netbiosname">
+ NetBIOS name</ulink> parameter in the <ulink url="smb.conf.5.html">
+ <filename>smb.conf</filename></ulink> file. However, a command
+ line setting will take precedence over settings in
+ <filename>smb.conf</filename>.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-p &lt;UDP port number&gt;</term>
+ <listitem><para>UDP port number is a positive integer value.
+ This option changes the default UDP port number (normally 137)
+ that <command>nmbd</command> responds to name queries on. Don't
+ use this option unless you are an expert, in which case you
+ won't need help!</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s &lt;configuration file&gt;</term>
+ <listitem><para>The default configuration file name
+ is set at build time, typically as <filename>
+ /usr/local/samba/lib/smb.conf</filename>, but
+ this may be changed when Samba is autoconfigured.</para>
+
+ <para>The file specified contains the configuration details
+ required by the server. See <ulink url="smb.conf.5.html">
+ <filename>smb.conf(5)</filename></ulink> for more information.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/inetd.conf</filename></term>
+ <listitem><para>If the server is to be run by the
+ <command>inetd</command> meta-daemon, this file
+ must contain suitable startup information for the
+ meta-daemon. See the <ulink
+ url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink> document
+ for details.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/rc</filename></term>
+ <listitem><para>or whatever initialization script your
+ system uses).</para>
+
+ <para>If running the server as a daemon at startup,
+ this file will need to contain an appropriate startup
+ sequence for the server. See the <ulink
+ url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink> document
+ for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/services</filename></term>
+ <listitem><para>If running the server via the
+ meta-daemon <command>inetd</command>, this file
+ must contain a mapping of service name (e.g., netbios-ssn)
+ to service port (e.g., 139) and protocol type (e.g., tcp).
+ See the <ulink url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink>
+ document for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/usr/local/samba/lib/smb.conf</filename></term>
+ <listitem><para>This is the default location of the
+ <ulink url="smb.conf.5.html"><filename>smb.conf</filename></ulink>
+ server configuration file. Other common places that systems
+ install this file are <filename>/usr/samba/lib/smb.conf</filename>
+ and <filename>/etc/smb.conf</filename>.</para>
+
+ <para>When run as a WINS server (see the
+ <ulink url="smb.conf.5.html#WINSSUPPORT">wins support</ulink>
+ parameter in the <filename>smb.conf(5)</filename> man page),
+ <command>nmbd</command>
+ will store the WINS database in the file <filename>wins.dat</filename>
+ in the <filename>var/locks</filename> directory configured under
+ wherever Samba was configured to install itself.</para>
+
+ <para>If <command>nmbd</command> is acting as a <emphasis>
+ browse master</emphasis> (see the <ulink
+ url="smb.conf.5.html#LOCALMASTER">local master</ulink>
+ parameter in the <filename>smb.conf(5)</filename> man page,
+ <command>nmbd</command>
+ will store the browsing database in the file <filename>browse.dat
+ </filename> in the <filename>var/locks</filename> directory
+ configured under wherever Samba was configured to install itself.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>SIGNALS</title>
+
+ <para>To shut down an <command>nmbd</command> process it is recommended
+ that SIGKILL (-9) <emphasis>NOT</emphasis> be used, except as a last
+ resort, as this may leave the name database in an inconsistent state.
+ The correct way to terminate <command>nmbd</command> is to send it
+ a SIGTERM (-15) signal and wait for it to die on its own.</para>
+
+ <para><command>nmbd</command> will accept SIGHUP, which will cause
+ it to dump out its namelists into the file <filename>namelist.debug
+ </filename> in the <filename>/usr/local/samba/var/locks</filename>
+ directory (or the <filename>var/locks</filename> directory configured
+ under wherever Samba was configured to install itself). This will also
+ cause <command>nmbd</command> to dump out its server database in
+ the <filename>log.nmb</filename> file.</para>
+
+ <para>The debug log level of nmbd may be raised or lowered using
+ <ulink url="smbcontrol.1.html"><command>smbcontrol(1)</command>
+ </ulink> (SIGUSR[1|2] signals are no longer used in Samba 2.2). This is
+ to allow transient problems to be diagnosed, whilst still running
+ at a normally low log level.</para>
+</refsect1>
+
+<refsect1>
+ <title>TROUBLESHOOTING</title>
+
+ <para>
+ One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </para>
+</refsect1>
+
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><command>inetd(8)</command>, <ulink
+ url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html"><filename>smb.conf(5)</filename>
+ </ulink>, <ulink url="smbclient.1.html"><command>smbclient(1)
+ </command></ulink>, <ulink url="testparm.1.html"><command>
+ testparm(1)</command></ulink>, <ulink url="testprns.1.html">
+ <command>testprns(1)</command></ulink>, and the Internet RFC's
+ <filename>rfc1001.txt</filename>, <filename>rfc1002.txt</filename>.
+ In addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page <ulink url="http://samba.org/cifs/">
+ http://samba.org/cifs/</ulink>.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/nmblookup.1.sgml b/docs/docbook/manpages/nmblookup.1.sgml
new file mode 100755
index 00000000000..502262ac730
--- /dev/null
+++ b/docs/docbook/manpages/nmblookup.1.sgml
@@ -0,0 +1,257 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="nmblookup">
+
+<refmeta>
+ <refentrytitle>nmblookup</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>nmblookup</refname>
+ <refpurpose>NetBIOS over TCP/IP client used to lookup NetBIOS
+ names</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>nmblookup</command>
+ <arg choice="opt">-f</arg>
+ <arg choice="opt">-M</arg>
+ <arg choice="opt">-R</arg>
+ <arg choice="opt">-S</arg>
+ <arg choice="opt">-r</arg>
+ <arg choice="opt">-A</arg>
+ <arg choice="opt">-h</arg>
+ <arg choice="opt">-B &lt;broadcast address&gt;</arg>
+ <arg choice="opt">-U &lt;unicast address&gt;</arg>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="opt">-i &lt;NetBIOS scope&gt;</arg>
+ <arg choice="opt">-T</arg>
+ <arg choice="req">name</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>nmblookup</command> is used to query NetBIOS names
+ and map them to IP addresses in a network using NetBIOS over TCP/IP
+ queries. The options allow the name queries to be directed at a
+ particular IP broadcast area or to a particular machine. All queries
+ are done over UDP.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-f</term>
+ <listitem><para>Causes nmblookup to print out the flags
+ in the NMB packet headers. These flags will print out as
+ strings like Authoritative, Recursion_Desired, Recursion_available, etc.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>-M</term>
+ <listitem><para>Searches for a master browser by looking
+ up the NetBIOS name <replaceable>name</replaceable> with a
+ type of <constant>0x1d</constant>. If <replaceable>
+ name</replaceable> is "-" then it does a lookup on the special name
+ <constant>__MSBROWSE__</constant>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R</term>
+ <listitem><para>Set the recursion desired bit in the packet
+ to do a recursive lookup. This is used when sending a name
+ query to a machine running a WINS server and the user wishes
+ to query the names in the WINS server. If this bit is unset
+ the normal (broadcast responding) NetBIOS processing code
+ on a machine is used instead. See rfc1001, rfc1002 for details.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-S</term>
+ <listitem><para>Once the name query has returned an IP
+ address then do a node status query as well. A node status
+ query returns the NetBIOS names registered by a host.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-r</term>
+ <listitem><para>Try and bind to UDP port 137 to send and receive UDP
+ datagrams. The reason for this option is a bug in Windows 95
+ where it ignores the source port of the requesting packet
+ and only replies to UDP port 137. Unfortunately, on most UNIX
+ systems root privilege is needed to bind to this port, and
+ in addition, if the <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ daemon is running on this machine it also binds to this port.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-A</term>
+ <listitem><para>Interpret <replaceable>name</replaceable> as
+ an IP Address and do a node status query on this address.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Print a help (usage) message.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-B &lt;broadcast address&gt;</term>
+ <listitem><para>Send the query to the given broadcast address. Without
+ this option the default behavior of nmblookup is to send the
+ query to the broadcast address of the network interfaces as
+ either auto-detected or defined in the <ulink
+ url="smb.conf.5.html#INTERFACES"><parameter>interfaces</parameter>
+ </ulink> parameter of the <filename>smb.conf (5)</filename> file.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-U &lt;unicast address&gt;</term>
+ <listitem><para>Do a unicast query to the specified address or
+ host <replaceable>unicast address</replaceable>. This option
+ (along with the <parameter>-R</parameter> option) is needed to
+ query a WINS server.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-d &lt;debuglevel&gt;</term>
+ <listitem><para>debuglevel is an integer from 0 to 10.</para>
+
+ <para>The default value if this parameter is not specified
+ is zero.</para>
+
+ <para>The higher this value, the more detail will be logged
+ about the activities of <command>nmblookup</command>. At level
+ 0, only critical errors and serious warnings will be logged.</para>
+
+ <para>Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a problem.
+ Levels above 3 are designed for use only by developers and
+ generate HUGE amounts of data, most of which is extremely cryptic.</para>
+
+ <para>Note that specifying this parameter here will override
+ the <ulink url="smb.conf.5.html#LOGLEVEL"><parameter>
+ log level</parameter></ulink> parameter in the <filename>
+ smb.conf(5)</filename> file.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s &lt;smb.conf&gt;</term>
+ <listitem><para>This parameter specifies the pathname to
+ the Samba configuration file, <ulink url="smb.conf.5.html">
+ smb.conf(5)</ulink>. This file controls all aspects of
+ the Samba setup on the machine.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i &lt;scope&gt;</term>
+ <listitem><para>This specifies a NetBIOS scope that
+ <command>nmblookup</command> will use to communicate with when
+ generating NetBIOS names. For details on the use of NetBIOS
+ scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes are
+ <emphasis>very</emphasis> rarely used, only set this parameter
+ if you are the system administrator in charge of all the
+ NetBIOS systems you communicate with.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-T</term>
+ <listitem><para>This causes any IP addresses found in the
+ lookup to be looked up via a reverse DNS lookup into a
+ DNS name, and printed out before each</para>
+
+ <para><emphasis>IP address .... NetBIOS name</emphasis></para>
+
+ <para> pair that is the normal output.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>name</term>
+ <listitem><para>This is the NetBIOS name being queried. Depending
+ upon the previous options this may be a NetBIOS name or IP address.
+ If a NetBIOS name then the different name types may be specified
+ by appending '#&lt;type&gt' to the name. This name may also be
+ '*', which will return all registered names within a broadcast
+ area.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para><command>nmblookup</command> can be used to query
+ a WINS server (in the same way <command>nslookup</command> is
+ used to query DNS servers). To query a WINS server,
+ <command>nmblookup</command> must be called like this:</para>
+
+ <para><command>nmblookup -U server -R 'name'</command></para>
+
+ <para>For example, running :</para>
+
+ <para><command>nmblookup -U samba.org -R 'IRIX#1B'</command></para>
+
+ <para>would query the WINS server samba.org for the domain
+ master browser (1B name type) for the IRIX workgroup.</para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="nmbd.8.html"><command>nmbd(8)</command></ulink>,
+ <ulink url="samba.7.html">samba(7)</ulink>, and <ulink
+ url="smb.conf.5.html">smb.conf(5)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/pdbedit.8.sgml b/docs/docbook/manpages/pdbedit.8.sgml
new file mode 100755
index 00000000000..eeb1fb0d2c6
--- /dev/null
+++ b/docs/docbook/manpages/pdbedit.8.sgml
@@ -0,0 +1,290 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="pdbedit">
+
+<refmeta>
+ <refentrytitle>pdbedit</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>pdbedit</refname>
+ <refpurpose>manage the SAM database</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pdbedit</command>
+ <arg choice="opt">-l</arg>
+ <arg choice="opt">-v</arg>
+ <arg choice="opt">-w</arg>
+ <arg choice="opt">-u username</arg>
+ <arg choice="opt">-f fullname</arg>
+ <arg choice="opt">-h homedir</arg>
+ <arg choice="opt">-d drive</arg>
+ <arg choice="opt">-s script</arg>
+ <arg choice="opt">-p profile</arg>
+ <arg choice="opt">-a</arg>
+ <arg choice="opt">-m</arg>
+ <arg choice="opt">-x</arg>
+ <arg choice="opt">-i file</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>The pdbedit program is used to manage the users accounts
+ stored in the sam database and can be run only by root.</para>
+
+ <para>The pdbedit tool use the passdb modular interface and is
+ independent from the kind of users database used (currently there
+ are smbpasswd, ldap, nis+ and tdb based and more can be addedd
+ without changing the tool).</para>
+
+ <para>There are five main ways to use pdbedit: adding a user account,
+ removing a user account, modifing a user account, listing user
+ accounts, importing users accounts.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>-l</term>
+ <listitem><para>This option list all the user accounts
+ present in the users database.
+ This option prints a list of user/uid pairs separated by
+ the ':' character.</para>
+
+ <para>Example: <command>pdbedit -l</command></para>
+ <para><programlisting>
+ sorce:500:Simo Sorce
+ samba:45:Test User
+ </programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-v</term>
+ <listitem><para>This option sets the verbose listing format.
+ It will make pdbedit list the users in the database printing
+ out the account fields in a descriptive format.</para>
+
+ <para>Example: <command>pdbedit -l -v</command></para>
+ <para><programlisting>
+ ---------------
+ username: sorce
+ user ID/Group: 500/500
+ user RID/GRID: 2000/2001
+ Full Name: Simo Sorce
+ Home Directory: \\BERSERKER\sorce
+ HomeDir Drive: H:
+ Logon Script: \\BERSERKER\netlogon\sorce.bat
+ Profile Path: \\BERSERKER\profile
+ ---------------
+ username: samba
+ user ID/Group: 45/45
+ user RID/GRID: 1090/1091
+ Full Name: Test User
+ Home Directory: \\BERSERKER\samba
+ HomeDir Drive:
+ Logon Script:
+ Profile Path: \\BERSERKER\profile
+ </programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-w</term>
+ <listitem><para>This option sets the "smbpasswd" listing format.
+ It will make pdbedit list the users in the database printing
+ out the account fields in a format compatible with the
+ <filename>smbpasswd</filename> file format. (see the <ulink
+ url="smbpasswd.5.html"><filename>smbpasswd(5)</filename></ulink> for details)</para>
+
+ <para>Example: <command>pdbedit -l -w</command></para>
+ <para><programlisting>
+ sorce:500:508818B733CE64BEAAD3B435B51404EE:D2A2418EFC466A8A0F6B1DBB5C3DB80C:[UX ]:LCT-00000000:
+ samba:45:0F2B255F7B67A7A9AAD3B435B51404EE:BC281CE3F53B6A5146629CD4751D3490:[UX ]:LCT-3BFA1E8D:
+ </programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-u username</term>
+ <listitem><para>This option specifies that the username to be
+ used for the operation requested (listing, adding, removing)
+ It is <emphasis>required</emphasis> in add, remove and modify
+ operations and <emphasis>optional</emphasis> in list
+ operations.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-f fullname</term>
+ <listitem><para>This option can be used while adding or
+ modifing a user account. It will specify the user's full
+ name. </para>
+
+ <para>Example: <command>-f "Simo Sorce"</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-h homedir</term>
+ <listitem><para>This option can be used while adding or
+ modifing a user account. It will specify the user's home
+ directory network path.</para>
+
+ <para>Example: <command>-h "\\\\BERSERKER\\sorce"</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-d drive</term>
+ <listitem><para>This option can be used while adding or
+ modifing a user account. It will specify the windows drive
+ letter to be used to map the home directory.</para>
+
+ <para>Example: <command>-d "H:"</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-s script</term>
+ <listitem><para>This option can be used while adding or
+ modifing a user account. It will specify the user's logon
+ script path.</para>
+
+ <para>Example: <command>-s "\\\\BERSERKER\\netlogon\\sorce.bat"</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-p profile</term>
+ <listitem><para>This option can be used while adding or
+ modifing a user account. It will specify the user's profile
+ directory.</para>
+
+ <para>Example: <command>-p "\\\\BERSERKER\\netlogon"</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-a</term>
+ <listitem><para>This option is used to add a user into the
+ database. This command need the user name be specified with
+ the -u switch. When adding a new user pdbedit will also
+ ask for the password to be used</para>
+
+ <para>Example: <command>pdbedit -a -u sorce</command>
+ <programlisting>new password:
+ retype new password</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-m</term>
+ <listitem><para>This option may only be used in conjunction
+ with the <parameter>-a</parameter> option. It will make
+ pdbedit to add a machine trust account instead of a user
+ account (-u username will provide the machine name).</para>
+
+ <para>Example: <command>pdbedit -a -m -u w2k-wks</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-x</term>
+ <listitem><para>This option causes pdbedit to delete an account
+ from the database. It need the username be specified with the
+ -u switch.</para>
+
+ <para>Example: <command>pdbedit -x -u bob</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-i file</term>
+ <listitem><para>This command is used to import a smbpasswd
+ file into the database.</para>
+
+ <para>This option will ease migration from the plain smbpasswd
+ file database to more powerful backend databases like tdb and
+ ldap.</para>
+
+ <para>Example: <command>pdbedit -i /etc/smbpasswd.old</command>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>NOTES</title>
+
+ <para>This command may be used only by root.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbpasswd.8.html">smbpasswd(8)</ulink>,
+ <ulink url="samba.7.html">samba(7)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/rpcclient.1.sgml b/docs/docbook/manpages/rpcclient.1.sgml
new file mode 100755
index 00000000000..773455fb2bf
--- /dev/null
+++ b/docs/docbook/manpages/rpcclient.1.sgml
@@ -0,0 +1,420 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="rpcclient">
+
+<refmeta>
+ <refentrytitle>rpcclient</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>rpcclient</refname>
+ <refpurpose>tool for executing client side
+ MS-RPC functions</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>rpcclient</command>
+ <arg choice="opt">-A authfile</arg>
+ <arg choice="opt">-c &lt;command string&gt;</arg>
+ <arg choice="opt">-d debuglevel</arg>
+ <arg choice="opt">-h</arg>
+ <arg choice="opt">-l logfile</arg>
+ <arg choice="opt">-N</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="opt">-U username[%password]</arg>
+ <arg choice="opt">-W workgroup</arg>
+ <arg choice="opt">-N</arg>
+ <arg choice="req">server</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>rpcclient</command> is a utility initially developed
+ to test MS-RPC functionality in Samba itself. It has undergone
+ several stages of development and stability. Many system administrators
+ have now written scripts around it to manage Windows NT clients from
+ their UNIX workstation. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>server</term>
+ <listitem><para>NetBIOS name of Server to which to connect.
+ The server can be any SMB/CIFS server. The name is
+ resolved using the <ulink url="smb.conf.5.html#NAMERESOLVEORDER">
+ <parameter>name resolve order</parameter></ulink> line from
+ <filename>smb.conf(5)</filename>.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-A filename</term><listitem><para>This option allows
+ you to specify a file from which to read the username and
+ password used in the connection. The format of the file is
+ </para>
+
+ <para><programlisting>
+ username = &lt;value&gt;
+ password = &lt;value&gt;
+ domain = &lt;value&gt;
+ </programlisting></para>
+
+ <para>Make certain that the permissions on the file restrict
+ access from unwanted users. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-c 'command string'</term>
+ <listitem><para>execute semicolon separated commands (listed
+ below)) </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term>-d debuglevel</term>
+ <listitem><para>set the debuglevel. Debug level 0 is the lowest
+ and 100 being the highest. This should be set to 100 if you are
+ planning on submitting a bug report to the Samba team (see <filename>BUGS.txt</filename>).
+ </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Print a summary of command line options.
+ </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term>-l logbasename</term>
+ <listitem><para>File name for log/debug files. The extension
+ <constant>'.client'</constant> will be appended. The log file is never removed
+ by the client.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-N</term>
+ <listitem><para>instruct <command>rpcclient</command> not to ask
+ for a password. By default, <command>rpcclient</command> will prompt
+ for a password. See also the <parameter>-U</parameter> option.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-s smb.conf</term>
+ <listitem><para>Specifies the location of the all important
+ <filename>smb.conf</filename> file. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-U username[%password]</term>
+ <listitem><para>Sets the SMB username or username and password. </para>
+
+ <para>If %password is not specified, the user will be prompted. The
+ client will first check the <envar>USER</envar> environment variable, then the
+ <envar>LOGNAME</envar> variable and if either exists, the
+ string is uppercased. If these environmental variables are not
+ found, the username <constant>GUEST</constant> is used. </para>
+
+ <para>A third option is to use a credentials file which
+ contains the plaintext of the username and password. This
+ option is mainly provided for scripts where the admin doesn't
+ desire to pass the credentials on the command line or via environment
+ variables. If this method is used, make certain that the permissions
+ on the file restrict access from unwanted users. See the
+ <parameter>-A</parameter> for more details. </para>
+
+ <para>Be cautious about including passwords in scripts. Also, on
+ many systems the command line of a running process may be seen
+ via the <command>ps</command> command. To be safe always allow
+ <command>rpcclient</command> to prompt for a password and type
+ it in directly. </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term>-W domain</term>
+ <listitem><para>Set the SMB domain of the username. This
+ overrides the default domain which is the domain defined in
+ smb.conf. If the domain specified is the same as the server's NetBIOS name,
+ it causes the client to log on using the server's local SAM (as
+ opposed to the Domain SAM). </para></listitem>
+ </varlistentry>
+
+
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>COMMANDS</title>
+
+ <para><emphasis>LSARPC</emphasis></para>
+ <itemizedlist>
+ <listitem><para><command>lsaquery</command></para></listitem>
+
+ <listitem><para><command>lookupsids</command> - Resolve a list
+ of SIDs to usernames.
+ </para></listitem>
+
+ <listitem><para><command>lookupnames</command> - Resolve s list
+ of usernames to SIDs.
+ </para></listitem>
+
+ <listitem><para><command>enumtrusts</command></para></listitem>
+ </itemizedlist>
+ <para> </para>
+
+
+
+ <para><emphasis>SAMR</emphasis></para>
+ <itemizedlist>
+ <listitem><para><command>queryuser</command></para></listitem>
+ <listitem><para><command>querygroup</command></para></listitem>
+ <listitem><para><command>queryusergroups</command></para></listitem>
+ <listitem><para><command>querygroupmem</command></para></listitem>
+ <listitem><para><command>queryaliasmem</command></para></listitem>
+ <listitem><para><command>querydispinfo</command></para></listitem>
+ <listitem><para><command>querydominfo</command></para></listitem>
+ <listitem><para><command>enumdomgroups</command></para></listitem>
+ </itemizedlist>
+ <para> </para>
+
+
+
+ <para><emphasis>SPOOLSS</emphasis></para>
+
+ <itemizedlist>
+ <listitem><para><command>adddriver &lt;arch&gt &lt;config&gt;</command>
+ - Execute an AddPrinterDriver() RPC to install the printer driver
+ information on the server. Note that the driver files should
+ already exist in the directory returned by
+ <command>getdriverdir</command>. Possible values for
+ <parameter>arch</parameter> are the same as those for
+ the <command>getdriverdir</command> command.
+ The <parameter>config</parameter> parameter is defined as
+ follows: </para>
+
+ <para><programlisting>
+ Long Printer Name:\
+ Driver File Name:\
+ Data File Name:\
+ Config File Name:\
+ Help File Name:\
+ Language Monitor Name:\
+ Default Data Type:\
+ Comma Separated list of Files
+ </programlisting></para>
+
+ <para>Any empty fields should be enter as the string "NULL". </para>
+
+ <para>Samba does not need to support the concept of Print Monitors
+ since these only apply to local printers whose driver can make
+ use of a bi-directional link for communication. This field should
+ be "NULL". On a remote NT print server, the Print Monitor for a
+ driver must already be installed prior to adding the driver or
+ else the RPC will fail. </para></listitem>
+
+
+
+
+ <listitem><para><command>addprinter &lt;printername&gt;
+ &lt;sharename&gt; &lt;drivername&gt; &lt;port&gt;</command>
+ - Add a printer on the remote server. This printer
+ will be automatically shared. Be aware that the printer driver
+ must already be installed on the server (see <command>adddriver</command>)
+ and the <parameter>port</parameter>must be a valid port name (see
+ <command>enumports</command>.</para>
+ </listitem>
+
+
+ <listitem><para><command>deldriver</command> - Delete the
+ specified printer driver for all architectures. This
+ does not delete the actual driver files from the server,
+ only the entry from the server's list of drivers.
+ </para></listitem>
+
+ <listitem><para><command>enumdata</command> - Enumerate all
+ printer setting data stored on the server. On Windows NT clients,
+ these values are stored in the registry, while Samba servers
+ store them in the printers TDB. This command corresponds
+ to the MS Platform SDK GetPrinterData() function (* This
+ command is currently unimplemented).</para></listitem>
+
+
+
+ <listitem><para><command>enumjobs &lt;printer&gt;</command>
+ - List the jobs and status of a given printer.
+ This command corresponds to the MS Platform SDK EnumJobs()
+ function (* This command is currently unimplemented).</para></listitem>
+
+
+
+
+ <listitem><para><command>enumports [level]</command>
+ - Executes an EnumPorts() call using the specified
+ info level. Currently only info levels 1 and 2 are supported.
+ </para></listitem>
+
+
+
+ <listitem><para><command>enumdrivers [level]</command>
+ - Execute an EnumPrinterDrivers() call. This lists the various installed
+ printer drivers for all architectures. Refer to the MS Platform SDK
+ documentation for more details of the various flags and calling
+ options. Currently supported info levels are 1, 2, and 3.</para></listitem>
+
+
+
+ <listitem><para><command>enumprinters [level]</command>
+ - Execute an EnumPrinters() call. This lists the various installed
+ and share printers. Refer to the MS Platform SDK documentation for
+ more details of the various flags and calling options. Currently
+ supported info levels are 0, 1, and 2.</para></listitem>
+
+
+
+
+ <listitem><para><command>getdata &lt;printername&gt;</command>
+ - Retrieve the data for a given printer setting. See
+ the <command>enumdata</command> command for more information.
+ This command corresponds to the GetPrinterData() MS Platform
+ SDK function (* This command is currently unimplemented). </para></listitem>
+
+
+
+ <listitem><para><command>getdriver &lt;printername&gt;</command>
+ - Retrieve the printer driver information (such as driver file,
+ config file, dependent files, etc...) for
+ the given printer. This command corresponds to the GetPrinterDriver()
+ MS Platform SDK function. Currently info level 1, 2, and 3 are supported.
+ </para></listitem>
+
+
+ <listitem><para><command>getdriverdir &lt;arch&gt;</command>
+ - Execute a GetPrinterDriverDirectory()
+ RPC to retreive the SMB share name and subdirectory for
+ storing printer driver files for a given architecture. Possible
+ values for <parameter>arch</parameter> are "Windows 4.0"
+ (for Windows 95/98), "Windows NT x86", "Windows NT PowerPC", "Windows
+ Alpha_AXP", and "Windows NT R4000". </para></listitem>
+
+
+
+ <listitem><para><command>getprinter &lt;printername&gt;</command>
+ - Retrieve the current printer information. This command
+ corresponds to the GetPrinter() MS Platform SDK function.
+ </para></listitem>
+
+
+
+ <listitem><para><command>openprinter &lt;printername&gt;</command>
+ - Execute an OpenPrinterEx() and ClosePrinter() RPC
+ against a given printer. </para></listitem>
+
+
+ <listitem><para><command>setdriver &lt;printername&gt; &lt;drivername&gt;</command>
+ - Execute a SetPrinter() command to update the printer driver associated
+ with an installed printer. The printer driver must already be correctly
+ installed on the print server. </para>
+
+ <para>See also the <command>enumprinters</command> and
+ <command>enumdrivers</command> commands for obtaining a list of
+ of installed printers and drivers.</para></listitem>
+
+ </itemizedlist>
+
+
+ <para><emphasis>GENERAL OPTIONS</emphasis></para>
+
+ <itemizedlist>
+ <listitem><para><command>debuglevel</command> - Set the current debug level
+ used to log information.</para></listitem>
+
+ <listitem><para><command>help (?)</command> - Print a listing of all
+ known commands or extended help on a particular command.
+ </para></listitem>
+
+ <listitem><para><command>quit (exit)</command> - Exit <command>rpcclient
+ </command>.</para></listitem>
+ </itemizedlist>
+
+
+</refsect1>
+
+<refsect1>
+ <title>BUGS</title>
+
+ <para><command>rpcclient</command> is designed as a developer testing tool
+ and may not be robust in certain areas (such as command line parsing).
+ It has been known to generate a core dump upon failures when invalid
+ parameters where passed to the interpreter. </para>
+
+ <para>From Luke Leighton's original rpcclient man page:</para>
+
+ <para><emphasis>"WARNING!</emphasis> The MSRPC over SMB code has
+ been developed from examining Network traces. No documentation is
+ available from the original creators (Microsoft) on how MSRPC over
+ SMB works, or how the individual MSRPC services work. Microsoft's
+ implementation of these services has been demonstrated (and reported)
+ to be... a bit flaky in places. </para>
+
+ <para>The development of Samba's implementation is also a bit rough,
+ and as more of the services are understood, it can even result in
+ versions of <command>smbd(8)</command> and <command>rpcclient(1)</command>
+ that are incompatible for some commands or services. Additionally,
+ the developers are sending reports to Microsoft, and problems found
+ or reported to Microsoft are fixed in Service Packs, which may
+ result in incompatibilities." </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of the Samba
+ suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original rpcclient man page was written by Matthew
+ Geddes, Luke Kenneth Casson Leighton, and rewritten by Gerald Carter.
+ The conversion to DocBook for Samba 2.2 was done by Gerald
+ Carter.</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/samba.7.sgml b/docs/docbook/manpages/samba.7.sgml
new file mode 100755
index 00000000000..5d81d9d4468
--- /dev/null
+++ b/docs/docbook/manpages/samba.7.sgml
@@ -0,0 +1,213 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="samba">
+
+<refmeta>
+ <refentrytitle>samba</refentrytitle>
+ <manvolnum>7</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>SAMBA</refname>
+ <refpurpose>A Windows SMB/CIFS fileserver for UNIX</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis><command>Samba</command></cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>The Samba software suite is a collection of programs
+ that implements the Server Message Block (commonly abbreviated
+ as SMB) protocol for UNIX systems. This protocol is sometimes
+ also referred to as the Common Internet File System (CIFS),
+ LanManager or NetBIOS protocol.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><command>smbd</command></term>
+ <listitem><para>The <command>smbd </command>
+ daemon provides the file and print services to
+ SMB clients, such as Windows 95/98, Windows NT, Windows
+ for Workgroups or LanManager. The configuration file
+ for this daemon is described in <filename>smb.conf</filename>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>nmbd</command></term>
+ <listitem><para>The <command>nmbd</command>
+ daemon provides NetBIOS nameserving and browsing
+ support. The configuration file for this daemon
+ is described in <filename>smb.conf</filename></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>smbclient</command></term>
+ <listitem><para>The <command>smbclient</command>
+ program implements a simple ftp-like client. This
+ is useful for accessing SMB shares on other compatible
+ servers (such as Windows NT), and can also be used
+ to allow a UNIX box to print to a printer attached to
+ any SMB server (such as a PC running Windows NT).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>testparm</command></term>
+ <listitem><para>The <command>testparm</command>
+ utility is a simple syntax checker for Samba's
+ <filename>smb.conf</filename>configuration file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>testprns</command></term>
+ <listitem><para>The <command>testprns</command>
+ utility supports testing printer names defined
+ in your <filename>printcap></filename> file used
+ by Samba.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>smbstatus</command></term>
+ <listitem><para>The <command>smbstatus</command>
+ tool provides access to information about the
+ current connections to <command>smbd</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>nmblookup</command></term>
+ <listitem><para>The <command>nmblookup</command>
+ tools allows NetBIOS name queries to be made
+ from a UNIX host.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>make_smbcodepage</command></term>
+ <listitem><para>The <command>make_smbcodepage</command>
+ utility provides a means of creating SMB code page
+ definition files for your <command>smbd</command> server.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>smbpasswd</command></term>
+ <listitem><para>The <command>smbpasswd</command>
+ command is a tool for changing LanMan and Windows NT
+ password hashes on Samba and Windows NT servers.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>COMPONENTS</title>
+
+ <para>The Samba suite is made up of several components. Each
+ component is described in a separate manual page. It is strongly
+ recommended that you read the documentation that comes with Samba
+ and the manual pages of those components that you use. If the
+ manual pages aren't clear enough then please send a patch or
+ bug report to <ulink url="mailto:samba@samba.org">
+ samba@samba.org</ulink></para>
+
+
+
+</refsect1>
+
+<refsect1>
+ <title>AVAILABILITY</title>
+
+ <para>The Samba software suite is licensed under the
+ GNU Public License(GPL). A copy of that license should
+ have come with the package in the file COPYING. You are
+ encouraged to distribute copies of the Samba suite, but
+ please obey the terms of this license.</para>
+
+ <para>The latest version of the Samba suite can be
+ obtained via anonymous ftp from samba.org in the
+ directory pub/samba/. It is also available on several
+ mirror sites worldwide.</para>
+
+ <para>You may also find useful information about Samba
+ on the newsgroup <ulink url="news:comp.protocols.smb">
+ comp.protocol.smb</ulink> and the Samba mailing
+ list. Details on how to join the mailing list are given in
+ the README file that comes with Samba.</para>
+
+ <para>If you have access to a WWW viewer (such as Netscape
+ or Mosaic) then you will also find lots of useful information,
+ including back issues of the Samba mailing list, at
+ <ulink url="http://lists.samba.org/">http://lists.samba.org</ulink>.</para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of the
+ Samba suite. </para>
+</refsect1>
+
+<refsect1>
+ <title>CONTRIBUTIONS</title>
+
+ <para>If you wish to contribute to the Samba project,
+ then I suggest you join the Samba mailing list at
+ <ulink url="http://lists.samba.org/">http://lists.samba.org</ulink>.
+ </para>
+
+ <para>If you have patches to submit or bugs to report
+ then you may mail them directly to samba-patches@samba.org.
+ Note, however, that due to the enormous popularity of this
+ package the Samba Team may take some time to respond to mail. We
+ prefer patches in <command>diff -u</command> format.</para>
+</refsect1>
+
+<refsect1>
+ <title>CONTRIBUTORS</title>
+
+ <para>Contributors to the project are now too numerous
+ to mention here but all deserve the thanks of all Samba
+ users. To see a full list, look at <ulink
+ url="ftp://samba.org/pub/samba/alpha/change-log">
+ ftp://samba.org/pub/samba/alpha/change-log</ulink>
+ for the pre-CVS changes and at <ulink
+ url="ftp://samba.org/pub/samba/alpha/cvs.log">
+ ftp://samba.org/pub/samba/alpha/cvs.log</ulink>
+ for the contributors to Samba post-CVS. CVS is the Open Source
+ source code control system used by the Samba Team to develop
+ Samba. The project would have been unmanageable without it.</para>
+
+ <para>In addition, several commercial organizations now help
+ fund the Samba Team with money and equipment. For details see
+ the Samba Web pages at <ulink
+ url="http://samba.org/samba/samba-thanks.html">
+ http://samba.org/samba/samba-thanks.html</ulink>.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smb.conf.5.sgml b/docs/docbook/manpages/smb.conf.5.sgml
new file mode 100755
index 00000000000..73df2b7459f
--- /dev/null
+++ b/docs/docbook/manpages/smb.conf.5.sgml
@@ -0,0 +1,8856 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smb.conf">
+
+<refmeta>
+ <refentrytitle>smb.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smb.conf</refname>
+ <refpurpose>The configuration file for the Samba suite</refpurpose>
+</refnamediv>
+
+<refsect1>
+ <title>SYNOPSIS</title>
+
+ <para>The <filename>smb.conf</filename> file is a configuration
+ file for the Samba suite. <filename>smb.conf</filename> contains
+ runtime configuration information for the Samba programs. The
+ <filename>smb.conf</filename> file is designed to be configured and
+ administered by the <ulink url="swat.8.html"><command>swat(8)</command>
+ </ulink> program. The complete description of the file format and
+ possible parameters held within are here for reference purposes.</para>
+</refsect1>
+
+<refsect1>
+ <title id="FILEFORMATSECT">FILE FORMAT</title>
+
+ <para>The file consists of sections and parameters. A section
+ begins with the name of the section in square brackets and continues
+ until the next section begins. Sections contain parameters of the
+ form</para>
+
+ <para><replaceable>name</replaceable> = <replaceable>value
+ </replaceable></para>
+
+ <para>The file is line-based - that is, each newline-terminated
+ line represents either a comment, a section name or a parameter.</para>
+
+ <para>Section and parameter names are not case sensitive.</para>
+
+ <para>Only the first equals sign in a parameter is significant.
+ Whitespace before or after the first equals sign is discarded.
+ Leading, trailing and internal whitespace in section and parameter
+ names is irrelevant. Leading and trailing whitespace in a parameter
+ value is discarded. Internal whitespace within a parameter value
+ is retained verbatim.</para>
+
+ <para>Any line beginning with a semicolon (';') or a hash ('#')
+ character is ignored, as are lines containing only whitespace.</para>
+
+ <para>Any line ending in a '\' is continued
+ on the next line in the customary UNIX fashion.</para>
+
+ <para>The values following the equals sign in parameters are all
+ either a string (no quotes needed) or a boolean, which may be given
+ as yes/no, 0/1 or true/false. Case is not significant in boolean
+ values, but is preserved in string values. Some items such as
+ create modes are numeric.</para>
+</refsect1>
+
+<refsect1>
+ <title>SECTION DESCRIPTIONS</title>
+
+ <para>Each section in the configuration file (except for the
+ [global] section) describes a shared resource (known
+ as a "share"). The section name is the name of the
+ shared resource and the parameters within the section define
+ the shares attributes.</para>
+
+ <para>There are three special sections, [global],
+ [homes] and [printers], which are
+ described under <emphasis>special sections</emphasis>. The
+ following notes apply to ordinary section descriptions.</para>
+
+ <para>A share consists of a directory to which access is being
+ given plus a description of the access rights which are granted
+ to the user of the service. Some housekeeping options are
+ also specifiable.</para>
+
+ <para>Sections are either file share services (used by the
+ client as an extension of their native file systems) or
+ printable services (used by the client to access print services
+ on the host running the server).</para>
+
+ <para>Sections may be designated <emphasis>guest</emphasis> services,
+ in which case no password is required to access them. A specified
+ UNIX <emphasis>guest account</emphasis> is used to define access
+ privileges in this case.</para>
+
+ <para>Sections other than guest services will require a password
+ to access them. The client provides the username. As older clients
+ only provide passwords and not usernames, you may specify a list
+ of usernames to check against the password using the "user ="
+ option in the share definition. For modern clients such as
+ Windows 95/98/ME/NT/2000, this should not be necessary.</para>
+
+ <para>Note that the access rights granted by the server are
+ masked by the access rights granted to the specified or guest
+ UNIX user by the host system. The server does not grant more
+ access than the host system grants.</para>
+
+ <para>The following sample section defines a file space share.
+ The user has write access to the path <filename>/home/bar</filename>.
+ The share is accessed via the share name "foo":</para>
+
+ <screen>
+ <computeroutput>
+ [foo]
+ path = /home/bar
+ read only = no
+ </computeroutput>
+ </screen>
+
+ <para>The following sample section defines a printable share.
+ The share is readonly, but printable. That is, the only write
+ access permitted is via calls to open, write to and close a
+ spool file. The <emphasis>guest ok</emphasis> parameter means
+ access will be permitted as the default guest user (specified
+ elsewhere):</para>
+
+ <screen>
+ <computeroutput>
+ [aprinter]
+ path = /usr/spool/public
+ read only = yes
+ printable = yes
+ guest ok = yes
+ </computeroutput>
+ </screen>
+</refsect1>
+
+<refsect1>
+ <title>SPECIAL SECTIONS</title>
+
+ <refsect2>
+ <title>The [global] section</title>
+
+ <para>parameters in this section apply to the server
+ as a whole, or are defaults for sections which do not
+ specifically define certain items. See the notes
+ under PARAMETERS for more information.</para>
+ </refsect2>
+
+ <refsect2>
+ <title id="HOMESECT">The [homes] section</title>
+
+ <para>If a section called homes is included in the
+ configuration file, services connecting clients to their
+ home directories can be created on the fly by the server.</para>
+
+ <para>When the connection request is made, the existing
+ sections are scanned. If a match is found, it is used. If no
+ match is found, the requested section name is treated as a
+ user name and looked up in the local password file. If the
+ name exists and the correct password has been given, a share is
+ created by cloning the [homes] section.</para>
+
+ <para>Some modifications are then made to the newly
+ created share:</para>
+
+ <itemizedlist>
+ <listitem><para>The share name is changed from homes to
+ the located username.</para></listitem>
+
+ <listitem><para>If no path was given, the path is set to
+ the user's home directory.</para></listitem>
+ </itemizedlist>
+
+ <para>If you decide to use a <emphasis>path =</emphasis> line
+ in your [homes] section then you may find it useful
+ to use the %S macro. For example :</para>
+
+ <para><userinput>path = /data/pchome/%S</userinput></para>
+
+ <para>would be useful if you have different home directories
+ for your PCs than for UNIX access.</para>
+
+ <para>This is a fast and simple way to give a large number
+ of clients access to their home directories with a minimum
+ of fuss.</para>
+
+ <para>A similar process occurs if the requested section
+ name is "homes", except that the share name is not
+ changed to that of the requesting user. This method of using
+ the [homes] section works well if different users share
+ a client PC.</para>
+
+ <para>The [homes] section can specify all the parameters
+ a normal service section can specify, though some make more sense
+ than others. The following is a typical and suitable [homes]
+ section:</para>
+
+ <screen>
+ <computeroutput>
+ [homes]
+ read only = no
+ </computeroutput>
+ </screen>
+
+ <para>An important point is that if guest access is specified
+ in the [homes] section, all home directories will be
+ visible to all clients <emphasis>without a password</emphasis>.
+ In the very unlikely event that this is actually desirable, it
+ would be wise to also specify <emphasis>read only
+ access</emphasis>.</para>
+
+ <para>Note that the <emphasis>browseable</emphasis> flag for
+ auto home directories will be inherited from the global browseable
+ flag, not the [homes] browseable flag. This is useful as
+ it means setting <emphasis>browseable = no</emphasis> in
+ the [homes] section will hide the [homes] share but make
+ any auto home directories visible.</para>
+ </refsect2>
+
+ <refsect2>
+ <title id="PRINTERSSECT">The [printers] section</title>
+
+ <para>This section works like [homes],
+ but for printers.</para>
+
+ <para>If a [printers] section occurs in the
+ configuration file, users are able to connect to any printer
+ specified in the local host's printcap file.</para>
+
+ <para>When a connection request is made, the existing sections
+ are scanned. If a match is found, it is used. If no match is found,
+ but a [homes] section exists, it is used as described
+ above. Otherwise, the requested section name is treated as a
+ printer name and the appropriate printcap file is scanned to see
+ if the requested section name is a valid printer share name. If
+ a match is found, a new printer share is created by cloning
+ the [printers] section.</para>
+
+ <para>A few modifications are then made to the newly created
+ share:</para>
+
+ <itemizedlist>
+ <listitem><para>The share name is set to the located printer
+ name</para></listitem>
+
+ <listitem><para>If no printer name was given, the printer name
+ is set to the located printer name</para></listitem>
+
+ <listitem><para>If the share does not permit guest access and
+ no username was given, the username is set to the located
+ printer name.</para></listitem>
+ </itemizedlist>
+
+ <para>Note that the [printers] service MUST be
+ printable - if you specify otherwise, the server will refuse
+ to load the configuration file.</para>
+
+ <para>Typically the path specified would be that of a
+ world-writeable spool directory with the sticky bit set on
+ it. A typical [printers] entry would look like
+ this:</para>
+
+ <screen><computeroutput>
+ [printers]
+ path = /usr/spool/public
+ guest ok = yes
+ printable = yes
+ </computeroutput></screen>
+
+ <para>All aliases given for a printer in the printcap file
+ are legitimate printer names as far as the server is concerned.
+ If your printing subsystem doesn't work like that, you will have
+ to set up a pseudo-printcap. This is a file consisting of one or
+ more lines like this:</para>
+
+ <screen>
+ <computeroutput>
+ alias|alias|alias|alias...
+ </computeroutput>
+ </screen>
+
+ <para>Each alias should be an acceptable printer name for
+ your printing subsystem. In the [global] section, specify
+ the new file as your printcap. The server will then only recognize
+ names found in your pseudo-printcap, which of course can contain
+ whatever aliases you like. The same technique could be used
+ simply to limit access to a subset of your local printers.</para>
+
+ <para>An alias, by the way, is defined as any component of the
+ first entry of a printcap record. Records are separated by newlines,
+ components (if there are more than one) are separated by vertical
+ bar symbols ('|').</para>
+
+ <para>NOTE: On SYSV systems which use lpstat to determine what
+ printers are defined on the system you may be able to use
+ "printcap name = lpstat" to automatically obtain a list
+ of printers. See the "printcap name" option
+ for more details.</para>
+ </refsect2>
+</refsect1>
+
+<refsect1>
+ <title>PARAMETERS</title>
+
+ <para>parameters define the specific attributes of sections.</para>
+
+ <para>Some parameters are specific to the [global] section
+ (e.g., <emphasis>security</emphasis>). Some parameters are usable
+ in all sections (e.g., <emphasis>create mode</emphasis>). All others
+ are permissible only in normal sections. For the purposes of the
+ following descriptions the [homes] and [printers]
+ sections will be considered normal. The letter <emphasis>G</emphasis>
+ in parentheses indicates that a parameter is specific to the
+ [global] section. The letter <emphasis>S</emphasis>
+ indicates that a parameter can be specified in a service specific
+ section. Note that all <emphasis>S</emphasis> parameters can also be specified in
+ the [global] section - in which case they will define
+ the default behavior for all services.</para>
+
+ <para>parameters are arranged here in alphabetical order - this may
+ not create best bedfellows, but at least you can find them! Where
+ there are synonyms, the preferred synonym is described, others refer
+ to the preferred synonym.</para>
+</refsect1>
+
+<refsect1>
+ <title>VARIABLE SUBSTITUTIONS</title>
+
+ <para>Many of the strings that are settable in the config file
+ can take substitutions. For example the option "path =
+ /tmp/%u" would be interpreted as "path =
+ /tmp/john" if the user connected with the username john.</para>
+
+ <para>These substitutions are mostly noted in the descriptions below,
+ but there are some general substitutions which apply whenever they
+ might be relevant. These are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>%S</term>
+ <listitem><para>the name of the current service, if any.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%P</term>
+ <listitem><para>the root directory of the current service,
+ if any.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%u</term>
+ <listitem><para>user name of the current service, if any.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%g</term>
+ <listitem><para>primary group name of %u.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%U</term>
+ <listitem><para>session user name (the user name that the client
+ wanted, not necessarily the same as the one they got).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%G</term>
+ <listitem><para>primary group name of %U.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%H</term>
+ <listitem><para>the home directory of the user given
+ by %u.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%v</term>
+ <listitem><para>the Samba version.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%h</term>
+ <listitem><para>the Internet hostname that Samba is running
+ on.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%m</term>
+ <listitem><para>the NetBIOS name of the client machine
+ (very useful).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%L</term>
+ <listitem><para>the NetBIOS name of the server. This allows you
+ to change your config based on what the client calls you. Your
+ server can have a "dual personality".</para>
+
+ <para>Note that this paramater is not available when Samba listens
+ on port 445, as clients no longer send this information </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+ <term>%M</term>
+ <listitem><para>the Internet name of the client machine.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%N</term>
+ <listitem><para>the name of your NIS home directory server.
+ This is obtained from your NIS auto.map entry. If you have
+ not compiled Samba with the <emphasis>--with-automount</emphasis>
+ option then this value will be the same as %L.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%p</term>
+ <listitem><para>the path of the service's home directory,
+ obtained from your NIS auto.map entry. The NIS auto.map entry
+ is split up as "%N:%p".</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%R</term>
+ <listitem><para>the selected protocol level after
+ protocol negotiation. It can be one of CORE, COREPLUS,
+ LANMAN1, LANMAN2 or NT1.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%d</term>
+ <listitem><para>The process id of the current server
+ process.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%a</term>
+ <listitem><para>the architecture of the remote
+ machine. Only some are recognized, and those may not be
+ 100% reliable. It currently recognizes Samba, "WfWg", "Win95",
+ "WinNT", "Win2K", WinXP, and "Win2K3". Anything else will be known as
+ "UNKNOWN". If it gets it wrong then sending a level
+ 3 log to <ulink url="mailto:samba@samba.org">samba@samba.org
+ </ulink> should allow it to be fixed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%I</term>
+ <listitem><para>The IP address of the client machine.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%T</term>
+ <listitem><para>the current date and time.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%$(<replaceable>envvar</replaceable>)</term>
+ <listitem><para>The value of the environment variable
+ <replaceable>envar</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>There are some quite creative things that can be done
+ with these substitutions and other smb.conf options.</para
+</refsect1>
+
+<refsect1>
+ <title id="NAMEMANGLINGSECT">NAME MANGLING</title>
+
+ <para>Samba supports "name mangling" so that DOS and
+ Windows clients can use files that don't conform to the 8.3 format.
+ It can also be set to adjust the case of 8.3 format filenames.</para>
+
+ <para>There are several options that control the way mangling is
+ performed, and they are grouped here rather than listed separately.
+ For the defaults look at the output of the testparm program. </para>
+
+ <para>All of these options can be set separately for each service
+ (or globally, of course). </para>
+
+ <para>The options are: </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>mangling method</term>
+ <listitem><para> controls the algorithm used for the generating
+ the mangled names. Can take two different values, "hash" and
+ "hash2". "hash" is the default and is the algorithm that has been
+ used in Samba for many years. "hash2" is a newer and considered
+ a better algorithm (generates less collisions) in the names.
+ However, many Win32 applications store the
+ mangled names and so changing to the new algorithm must not be done
+ lightly as these applications may break unless reinstalled.
+ New installations of Samba may set the default to hash2.
+ Default <emphasis>hash</emphasis>.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>mangle case = yes/no</term>
+ <listitem><para> controls if names that have characters that
+ aren't of the "default" case are mangled. For example,
+ if this is yes then a name like "Mail" would be mangled.
+ Default <emphasis>no</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>case sensitive = yes/no</term>
+ <listitem><para>controls whether filenames are case sensitive. If
+ they aren't then Samba must do a filename search and match on passed
+ names. Default <emphasis>no</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>default case = upper/lower</term>
+ <listitem><para>controls what the default case is for new
+ filenames. Default <emphasis>lower</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preserve case = yes/no</term>
+ <listitem><para>controls if new files are created with the
+ case that the client passes, or if they are forced to be the
+ "default" case. Default <emphasis>yes</emphasis>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>short preserve case = yes/no</term>
+ <listitem><para>controls if new files which conform to 8.3 syntax,
+ that is all in upper case and of suitable length, are created
+ upper case, or if they are forced to be the "default"
+ case. This option can be use with "preserve case = yes"
+ to permit long filenames to retain their case, while short names
+ are lowercased. Default <emphasis>yes</emphasis>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>By default, Samba 2.2 has the same semantics as a Windows
+ NT server, in that it is case insensitive but case preserving.</para>
+
+</refsect1>
+
+<refsect1>
+ <title id="VALIDATIONSECT">NOTE ABOUT USERNAME/PASSWORD VALIDATION</title>
+
+ <para>There are a number of ways in which a user can connect
+ to a service. The server uses the following steps in determining
+ if it will allow a connection to a specified service. If all the
+ steps fail, then the connection request is rejected. However, if one of the
+ steps succeeds, then the following steps are not checked.</para>
+
+ <para>If the service is marked "guest only = yes" and the
+ server is running with share-level security ("security = share")
+ then steps 1 to 5 are skipped.</para>
+
+
+ <orderedlist numeration="Arabic">
+ <listitem><para>If the client has passed a username/password
+ pair and that username/password pair is validated by the UNIX
+ system's password programs then the connection is made as that
+ username. Note that this includes the
+ \\server\service%<replaceable>username</replaceable> method of passing
+ a username.</para></listitem>
+
+ <listitem><para>If the client has previously registered a username
+ with the system and now supplies a correct password for that
+ username then the connection is allowed.</para></listitem>
+
+ <listitem><para>The client's NetBIOS name and any previously
+ used user names are checked against the supplied password, if
+ they match then the connection is allowed as the corresponding
+ user.</para></listitem>
+
+ <listitem><para>If the client has previously validated a
+ username/password pair with the server and the client has passed
+ the validation token then that username is used. </para></listitem>
+
+ <listitem><para>If a "user = " field is given in the
+ <filename>smb.conf</filename> file for the service and the client
+ has supplied a password, and that password matches (according to
+ the UNIX system's password checking) with one of the usernames
+ from the "user =" field then the connection is made as
+ the username in the "user =" line. If one
+ of the username in the "user =" list begins with a
+ '@' then that name expands to a list of names in
+ the group of the same name.</para></listitem>
+
+ <listitem><para>If the service is a guest service then a
+ connection is made as the username given in the "guest
+ account =" for the service, irrespective of the
+ supplied password.</para></listitem>
+ </orderedlist>
+
+</refsect1>
+
+<refsect1>
+ <title>COMPLETE LIST OF GLOBAL PARAMETERS</title>
+
+ <para>Here is a list of all global parameters. See the section of
+ each parameter for details. Note that some are synonyms.</para>
+
+ <itemizedlist>
+ <listitem><para><link linkend="ACLCOMPATIBILITY"><parameter>acl compatibility</parameter></link></para></listitem>
+ <listitem><para><link linkend="ADDPRINTERCOMMAND"><parameter>add printer command</parameter></link></para></listitem>
+ <listitem><para><link linkend="ADDSHARECOMMAND"><parameter>add share command</parameter></link></para></listitem>
+ <listitem><para><link linkend="ADDUSERSCRIPT"><parameter>add user script</parameter></link></para></listitem>
+ <listitem><para><link linkend="ALLOWTRUSTEDDOMAINS"><parameter>allow trusted domains</parameter></link></para></listitem>
+ <listitem><para><link linkend="ANNOUNCEAS"><parameter>announce as</parameter></link></para></listitem>
+ <listitem><para><link linkend="ANNOUNCEVERSION"><parameter>announce version</parameter></link></para></listitem>
+ <listitem><para><link linkend="AUTOSERVICES"><parameter>auto services</parameter></link></para></listitem>
+ <listitem><para><link linkend="BINDINTERFACESONLY"><parameter>bind interfaces only</parameter></link></para></listitem>
+ <listitem><para><link linkend="BROWSELIST"><parameter>browse list</parameter></link></para></listitem>
+ <listitem><para><link linkend="CHANGENOTIFYTIMEOUT"><parameter>change notify timeout</parameter></link></para></listitem>
+ <listitem><para><link linkend="CHANGESHARECOMMAND"><parameter>change share command</parameter></link></para></listitem>
+ <listitem><para><link linkend="CHARACTERSET"><parameter>character set</parameter></link></para></listitem>
+ <listitem><para><link linkend="CLIENTCODEPAGE"><parameter>client code page</parameter></link></para></listitem>
+ <listitem><para><link linkend="CODEPAGEDIRECTORY"><parameter>code page directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="CODINGSYSTEM"><parameter>coding system</parameter></link></para></listitem>
+ <listitem><para><link linkend="CONFIGFILE"><parameter>config file</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEADTIME"><parameter>deadtime</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEBUGHIRESTIMESTAMP"><parameter>debug hires timestamp</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEBUGPID"><parameter>debug pid</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEBUGTIMESTAMP"><parameter>debug timestamp</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEBUGUID"><parameter>debug uid</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEBUGLEVEL"><parameter>debuglevel</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEFAULT"><parameter>default</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEFAULTSERVICE"><parameter>default service</parameter></link></para></listitem>
+ <listitem><para><link linkend="DELETEPRINTERCOMMAND"><parameter>delete printer command</parameter></link></para></listitem>
+ <listitem><para><link linkend="DELETESHARECOMMAND"><parameter>delete share command</parameter></link></para></listitem>
+ <listitem><para><link linkend="DELETEUSERSCRIPT"><parameter>delete user script</parameter></link></para></listitem>
+ <listitem><para><link linkend="DFREECOMMAND"><parameter>dfree command</parameter></link></para></listitem>
+ <listitem><para><link linkend="DISABLESPOOLSS"><parameter>disable spoolss</parameter></link></para></listitem>
+ <listitem><para><link linkend="DNSPROXY"><parameter>dns proxy</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOMAINADMINGROUP"><parameter>domain admin group</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOMAINGUESTGROUP"><parameter>domain guest group</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOMAINLOGONS"><parameter>domain logons</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOMAINMASTER"><parameter>domain master</parameter></link></para></listitem>
+ <listitem><para><link linkend="ENCRYPTPASSWORDS"><parameter>encrypt passwords</parameter></link></para></listitem>
+ <listitem><para><link linkend="ENHANCEDBROWSING"><parameter>enhanced browsing</parameter></link></para></listitem>
+ <listitem><para><link linkend="ENUMPORTSCOMMAND"><parameter>enumports command</parameter></link></para></listitem>
+ <listitem><para><link linkend="GETWDCACHE"><parameter>getwd cache</parameter></link></para></listitem>
+ <listitem><para><link linkend="HIDELOCALUSERS"><parameter>hide local users</parameter></link></para></listitem>
+ <listitem><para><link linkend="HIDEUNREADABLE"><parameter>hide unreadable</parameter></link></para></listitem>
+ <listitem><para><link linkend="HOMEDIRMAP"><parameter>homedir map</parameter></link></para></listitem>
+ <listitem><para><link linkend="HOSTMSDFS"><parameter>host msdfs</parameter></link></para></listitem>
+ <listitem><para><link linkend="HOSTSEQUIV"><parameter>hosts equiv</parameter></link></para></listitem>
+ <listitem><para><link linkend="INTERFACES"><parameter>interfaces</parameter></link></para></listitem>
+ <listitem><para><link linkend="KEEPALIVE"><parameter>keepalive</parameter></link></para></listitem>
+ <listitem><para><link linkend="KERNELOPLOCKS"><parameter>kernel oplocks</parameter></link></para></listitem>
+ <listitem><para><link linkend="LANMANAUTH"><parameter>lanman auth</parameter></link></para></listitem>
+ <listitem><para><link linkend="LARGEREADWRITE"><parameter>large readwrite</parameter></link></para></listitem>
+
+ <listitem><para><link linkend="LDAPADMINDN"><parameter>ldap admin dn</parameter></link></para></listitem>
+ <listitem><para><link linkend="LDAPFILTER"><parameter>ldap filter</parameter></link></para></listitem>
+ <listitem><para><link linkend="LDAPPORT"><parameter>ldap port</parameter></link></para></listitem>
+ <listitem><para><link linkend="LDAPSERVER"><parameter>ldap server</parameter></link></para></listitem>
+ <listitem><para><link linkend="LDAPSSL"><parameter>ldap ssl</parameter></link></para></listitem>
+ <listitem><para><link linkend="LDAPSUFFIX"><parameter>ldap suffix</parameter></link></para></listitem>
+
+ <listitem><para><link linkend="LMANNOUNCE"><parameter>lm announce</parameter></link></para></listitem>
+ <listitem><para><link linkend="LMINTERVAL"><parameter>lm interval</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOADPRINTERS"><parameter>load printers</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCALMASTER"><parameter>local master</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCKDIR"><parameter>lock dir</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCKDIRECTORY"><parameter>lock directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCKSPINCOUNT"><parameter>lock spin count</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCKSPINTIME"><parameter>lock spin time</parameter></link></para></listitem>
+ <listitem><para><link linkend="PIDDIRECTORY"><parameter>pid directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGFILE"><parameter>log file</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGLEVEL"><parameter>log level</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGONDRIVE"><parameter>logon drive</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGONHOME"><parameter>logon home</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGONPATH"><parameter>logon path</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOGONSCRIPT"><parameter>logon script</parameter></link></para></listitem>
+ <listitem><para><link linkend="LPQCACHETIME"><parameter>lpq cache time</parameter></link></para></listitem>
+ <listitem><para><link linkend="MACHINEPASSWORDTIMEOUT"><parameter>machine password timeout</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLEDSTACK"><parameter>mangled stack</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLINGMETHOD"><parameter>mangling method</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAPTOGUEST"><parameter>map to guest</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXDISKSIZE"><parameter>max disk size</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXLOGSIZE"><parameter>max log size</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXMUX"><parameter>max mux</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXOPENFILES"><parameter>max open files</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXPROTOCOL"><parameter>max protocol</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXSMBDPROCESSES"><parameter>max smbd processes</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXTTL"><parameter>max ttl</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXWINSTTL"><parameter>max wins ttl</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXXMIT"><parameter>max xmit</parameter></link></para></listitem>
+ <listitem><para><link linkend="MESSAGECOMMAND"><parameter>message command</parameter></link></para></listitem>
+ <listitem><para><link linkend="MINPASSWDLENGTH"><parameter>min passwd length</parameter></link></para></listitem>
+ <listitem><para><link linkend="MINPASSWORDLENGTH"><parameter>min password length</parameter></link></para></listitem>
+ <listitem><para><link linkend="MINPROTOCOL"><parameter>min protocol</parameter></link></para></listitem>
+ <listitem><para><link linkend="MINWINSTTL"><parameter>min wins ttl</parameter></link></para></listitem>
+ <listitem><para><link linkend="NAMERESOLVEORDER"><parameter>name resolve order</parameter></link></para></listitem>
+ <listitem><para><link linkend="NETBIOSALIASES"><parameter>netbios aliases</parameter></link></para></listitem>
+ <listitem><para><link linkend="NETBIOSNAME"><parameter>netbios name</parameter></link></para></listitem>
+ <listitem><para><link linkend="NETBIOSSCOPE"><parameter>netbios scope</parameter></link></para></listitem>
+ <listitem><para><link linkend="NISHOMEDIR"><parameter>nis homedir</parameter></link></para></listitem>
+ <listitem><para><link linkend="NTPIPESUPPORT"><parameter>nt pipe support</parameter></link></para></listitem>
+ <listitem><para><link linkend="NTSMBSUPPORT"><parameter>nt smb support</parameter></link></para></listitem>
+ <listitem><para><link linkend="NTSTATUSSUPPORT"><parameter>nt status support</parameter></link></para></listitem>
+ <listitem><para><link linkend="NULLPASSWORDS"><parameter>null passwords</parameter></link></para></listitem>
+ <listitem><para><link linkend="OBEYPAMRESTRICTIONS"><parameter>obey pam restrictions</parameter></link></para></listitem>
+ <listitem><para><link linkend="OPLOCKBREAKWAITTIME"><parameter>oplock break wait time</parameter></link></para></listitem>
+ <listitem><para><link linkend="OSLEVEL"><parameter>os level</parameter></link></para></listitem>
+ <listitem><para><link linkend="OS2DRIVERMAP"><parameter>os2 driver map</parameter></link></para></listitem>
+ <listitem><para><link linkend="PAMPASSWORDCHANGE"><parameter>pam password change</parameter></link></para></listitem>
+ <listitem><para><link linkend="PANICACTION"><parameter>panic action</parameter></link></para></listitem>
+ <listitem><para><link linkend="PASSWDCHAT"><parameter>passwd chat</parameter></link></para></listitem>
+ <listitem><para><link linkend="PASSWDCHATDEBUG"><parameter>passwd chat debug</parameter></link></para></listitem>
+ <listitem><para><link linkend="PASSWDPROGRAM"><parameter>passwd program</parameter></link></para></listitem>
+ <listitem><para><link linkend="PASSWORDLEVEL"><parameter>password level</parameter></link></para></listitem>
+ <listitem><para><link linkend="PASSWORDSERVER"><parameter>password server</parameter></link></para></listitem>
+ <listitem><para><link linkend="PREFEREDMASTER"><parameter>prefered master</parameter></link></para></listitem>
+ <listitem><para><link linkend="PREFERREDMASTER"><parameter>preferred master</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRELOAD"><parameter>preload</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTCAP"><parameter>printcap</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTCAPNAME"><parameter>printcap name</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTERDRIVERFILE"><parameter>printer driver file</parameter></link></para></listitem>
+ <listitem><para><link linkend="PROTOCOL"><parameter>protocol</parameter></link></para></listitem>
+ <listitem><para><link linkend="READBMPX"><parameter>read bmpx</parameter></link></para></listitem>
+ <listitem><para><link linkend="READRAW"><parameter>read raw</parameter></link></para></listitem>
+ <listitem><para><link linkend="READSIZE"><parameter>read size</parameter></link></para></listitem>
+ <listitem><para><link linkend="REMOTEANNOUNCE"><parameter>remote announce</parameter></link></para></listitem>
+ <listitem><para><link linkend="REMOTEBROWSESYNC"><parameter>remote browse sync</parameter></link></para></listitem>
+ <listitem><para><link linkend="RESTRICTANONYMOUS"><parameter>restrict anonymous</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOT"><parameter>root</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOTDIR"><parameter>root dir</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOTDIRECTORY"><parameter>root directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="SECURITY"><parameter>security</parameter></link></para></listitem>
+ <listitem><para><link linkend="SERVERSTRING"><parameter>server string</parameter></link></para></listitem>
+ <listitem><para><link linkend="SHOWADDPRINTERWIZARD"><parameter>show add printer wizard</parameter></link></para></listitem>
+ <listitem><para><link linkend="SMBPASSWDFILE"><parameter>smb passwd file</parameter></link></para></listitem>
+ <listitem><para><link linkend="SOCKETADDRESS"><parameter>socket address</parameter></link></para></listitem>
+ <listitem><para><link linkend="SOCKETOPTIONS"><parameter>socket options</parameter></link></para></listitem>
+ <listitem><para><link linkend="SOURCEENVIRONMENT"><parameter>source environment</parameter></link></para></listitem>
+
+ <listitem><para><link linkend="SSL"><parameter>ssl</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCACERTDIR"><parameter>ssl CA certDir</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCACERTFILE"><parameter>ssl CA certFile</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCIPHERS"><parameter>ssl ciphers</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCLIENTCERT"><parameter>ssl client cert</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCLIENTKEY"><parameter>ssl client key</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLCOMPATIBILITY"><parameter>ssl compatibility</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLEGDSOCKET"><parameter>ssl egd socket</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLENTROPYBYTES"><parameter>ssl entropy bytes</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLENTROPYFILE"><parameter>ssl entropy file</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLHOSTS"><parameter>ssl hosts</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLHOSTSRESIGN"><parameter>ssl hosts resign</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLREQUIRECLIENTCERT"><parameter>ssl require clientcert</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLREQUIRESERVERCERT"><parameter>ssl require servercert</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLSERVERCERT"><parameter>ssl server cert</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLSERVERKEY"><parameter>ssl server key</parameter></link></para></listitem>
+ <listitem><para><link linkend="SSLVERSION"><parameter>ssl version</parameter></link></para></listitem>
+
+ <listitem><para><link linkend="STATCACHE"><parameter>stat cache</parameter></link></para></listitem>
+ <listitem><para><link linkend="STATCACHESIZE"><parameter>stat cache size</parameter></link></para></listitem>
+ <listitem><para><link linkend="STRIPDOT"><parameter>strip dot</parameter></link></para></listitem>
+ <listitem><para><link linkend="SYSLOG"><parameter>syslog</parameter></link></para></listitem>
+ <listitem><para><link linkend="SYSLOGONLY"><parameter>syslog only</parameter></link></para></listitem>
+ <listitem><para><link linkend="TEMPLATEHOMEDIR"><parameter>template homedir</parameter></link></para></listitem>
+ <listitem><para><link linkend="TEMPLATESHELL"><parameter>template shell</parameter></link></para></listitem>
+ <listitem><para><link linkend="TIMEOFFSET"><parameter>time offset</parameter></link></para></listitem>
+ <listitem><para><link linkend="TIMESERVER"><parameter>time server</parameter></link></para></listitem>
+ <listitem><para><link linkend="TIMESTAMPLOGS"><parameter>timestamp logs</parameter></link></para></listitem>
+ <listitem><para><link linkend="TOTALPRINTJOBS"><parameter>total print jobs</parameter></link></para></listitem>
+ <listitem><para><link linkend="UNIXEXTENSIONS"><parameter>unix extensions</parameter></link></para></listitem>
+ <listitem><para><link linkend="UNIXPASSWORDSYNC"><parameter>unix password sync</parameter></link></para></listitem>
+ <listitem><para><link linkend="UPDATEENCRYPTED"><parameter>update encrypted</parameter></link></para></listitem>
+ <listitem><para><link linkend="USEMMAP"><parameter>use mmap</parameter></link></para></listitem>
+ <listitem><para><link linkend="USERHOSTS"><parameter>use rhosts</parameter></link></para></listitem>
+ <listitem><para><link linkend="USERNAMELEVEL"><parameter>username level</parameter></link></para></listitem>
+ <listitem><para><link linkend="USERNAMEMAP"><parameter>username map</parameter></link></para></listitem>
+ <listitem><para><link linkend="UTMP"><parameter>utmp</parameter></link></para></listitem>
+ <listitem><para><link linkend="UTMPDIRECTORY"><parameter>utmp directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="VALIDCHARS"><parameter>valid chars</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDCACHETIME"><parameter>winbind cache time</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDENUMUSERS"><parameter>winbind enum users</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDENUMGROUPS"><parameter>winbind enum groups</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDGID"><parameter>winbind gid</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDSEPARATOR"><parameter>winbind separator</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDUID"><parameter>winbind uid</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINBINDUSEDEFAULTDOMAIN"><parameter>winbind use default domain</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINSHOOK"><parameter>wins hook</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINSPROXY"><parameter>wins proxy</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINSSERVER"><parameter>wins server</parameter></link></para></listitem>
+ <listitem><para><link linkend="WINSSUPPORT"><parameter>wins support</parameter></link></para></listitem>
+ <listitem><para><link linkend="WORKGROUP"><parameter>workgroup</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITERAW"><parameter>write raw</parameter></link></para></listitem>
+ </itemizedlist>
+
+</refsect1>
+
+<refsect1>
+ <title>COMPLETE LIST OF SERVICE PARAMETERS</title>
+
+ <para>Here is a list of all service parameters. See the section on
+ each parameter for details. Note that some are synonyms.</para>
+
+ <itemizedlist>
+ <listitem><para><link linkend="ADMINUSERS"><parameter>admin users</parameter></link></para></listitem>
+ <listitem><para><link linkend="ALLOWHOSTS"><parameter>allow hosts</parameter></link></para></listitem>
+ <listitem><para><link linkend="AVAILABLE"><parameter>available</parameter></link></para></listitem>
+ <listitem><para><link linkend="BLOCKINGLOCKS"><parameter>blocking locks</parameter></link></para></listitem>
+ <listitem><para><link linkend="BLOCKSIZE"><parameter>block size</parameter></link></para></listitem>
+ <listitem><para><link linkend="BROWSABLE"><parameter>browsable</parameter></link></para></listitem>
+ <listitem><para><link linkend="BROWSEABLE"><parameter>browseable</parameter></link></para></listitem>
+ <listitem><para><link linkend="CASESENSITIVE"><parameter>case sensitive</parameter></link></para></listitem>
+ <listitem><para><link linkend="CASESIGNAMES"><parameter>casesignames</parameter></link></para></listitem>
+ <listitem><para><link linkend="COMMENT"><parameter>comment</parameter></link></para></listitem>
+ <listitem><para><link linkend="COPY"><parameter>copy</parameter></link></para></listitem>
+ <listitem><para><link linkend="CREATEMASK"><parameter>create mask</parameter></link></para></listitem>
+ <listitem><para><link linkend="CREATEMODE"><parameter>create mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="CSCPOLICY"><parameter>csc policy</parameter></link></para></listitem>
+
+ <listitem><para><link linkend="DEFAULTCASE"><parameter>default case</parameter></link></para></listitem>
+ <listitem><para><link linkend="DEFAULTDEVMODE"><parameter>default devmode</parameter></link></para></listitem>
+ <listitem><para><link linkend="DELETEREADONLY"><parameter>delete readonly</parameter></link></para></listitem>
+ <listitem><para><link linkend="DELETEVETOFILES"><parameter>delete veto files</parameter></link></para></listitem>
+ <listitem><para><link linkend="DENYHOSTS"><parameter>deny hosts</parameter></link></para></listitem>
+ <listitem><para><link linkend="DIRECTORY"><parameter>directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="DIRECTORYMASK"><parameter>directory mask</parameter></link></para></listitem>
+ <listitem><para><link linkend="DIRECTORYMODE"><parameter>directory mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="DIRECTORYSECURITYMASK"><parameter>directory security mask</parameter></link></para></listitem>
+ <listitem><para><link linkend="DONTDESCEND"><parameter>dont descend</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOSFILEMODE"><parameter>dos filemode</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOSFILETIMERESOLUTION"><parameter>dos filetime resolution</parameter></link></para></listitem>
+ <listitem><para><link linkend="DOSFILETIMES"><parameter>dos filetimes</parameter></link></para></listitem>
+ <listitem><para><link linkend="EXEC"><parameter>exec</parameter></link></para></listitem>
+ <listitem><para><link linkend="FAKEDIRECTORYCREATETIMES"><parameter>fake directory create times</parameter></link></para></listitem>
+ <listitem><para><link linkend="FAKEOPLOCKS"><parameter>fake oplocks</parameter></link></para></listitem>
+ <listitem><para><link linkend="FOLLOWSYMLINKS"><parameter>follow symlinks</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCECREATEMODE"><parameter>force create mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCEDIRECTORYMODE"><parameter>force directory mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCEDIRECTORYSECURITYMODE"><parameter>force directory security mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCEGROUP"><parameter>force group</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCESECURITYMODE"><parameter>force security mode</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCEUNKNOWNACLUSER"><parameter>force unknown acl user</parameter></link></para></listitem>
+ <listitem><para><link linkend="FORCEUSER"><parameter>force user</parameter></link></para></listitem>
+ <listitem><para><link linkend="FSTYPE"><parameter>fstype</parameter></link></para></listitem>
+ <listitem><para><link linkend="GROUP"><parameter>group</parameter></link></para></listitem>
+ <listitem><para><link linkend="GUESTACCOUNT"><parameter>guest account</parameter></link></para></listitem>
+ <listitem><para><link linkend="GUESTOK"><parameter>guest ok</parameter></link></para></listitem>
+ <listitem><para><link linkend="GUESTONLY"><parameter>guest only</parameter></link></para></listitem>
+ <listitem><para><link linkend="HIDEDOTFILES"><parameter>hide dot files</parameter></link></para></listitem>
+ <listitem><para><link linkend="HIDEFILES"><parameter>hide files</parameter></link></para></listitem>
+ <listitem><para><link linkend="HOSTSALLOW"><parameter>hosts allow</parameter></link></para></listitem>
+ <listitem><para><link linkend="HOSTSDENY"><parameter>hosts deny</parameter></link></para></listitem>
+ <listitem><para><link linkend="INCLUDE"><parameter>include</parameter></link></para></listitem>
+ <listitem><para><link linkend="INHERITACLS"><parameter>inherit acls</parameter></link></para></listitem>
+ <listitem><para><link linkend="INHERITPERMISSIONS"><parameter>inherit permissions</parameter></link></para></listitem>
+ <listitem><para><link linkend="INVALIDUSERS"><parameter>invalid users</parameter></link></para></listitem>
+ <listitem><para><link linkend="LEVEL2OPLOCKS"><parameter>level2 oplocks</parameter></link></para></listitem>
+ <listitem><para><link linkend="LOCKING"><parameter>locking</parameter></link></para></listitem>
+ <listitem><para><link linkend="LPPAUSECOMMAND"><parameter>lppause command</parameter></link></para></listitem>
+ <listitem><para><link linkend="LPQCOMMAND"><parameter>lpq command</parameter></link></para></listitem>
+ <listitem><para><link linkend="LPRESUMECOMMAND"><parameter>lpresume command</parameter></link></para></listitem>
+ <listitem><para><link linkend="LPRMCOMMAND"><parameter>lprm command</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAGICOUTPUT"><parameter>magic output</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAGICSCRIPT"><parameter>magic script</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLECASE"><parameter>mangle case</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLEDMAP"><parameter>mangled map</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLEDNAMES"><parameter>mangled names</parameter></link></para></listitem>
+ <listitem><para><link linkend="MANGLINGCHAR"><parameter>mangling char</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAPARCHIVE"><parameter>map archive</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAPHIDDEN"><parameter>map hidden</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAPSYSTEM"><parameter>map system</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXCONNECTIONS"><parameter>max connections</parameter></link></para></listitem>
+ <listitem><para><link linkend="MAXPRINTJOBS"><parameter>max print jobs</parameter></link></para></listitem>
+ <listitem><para><link linkend="MINPRINTSPACE"><parameter>min print space</parameter></link></para></listitem>
+ <listitem><para><link linkend="MSDFSROOT"><parameter>msdfs root</parameter></link></para></listitem>
+ <listitem><para><link linkend="NTACLSUPPORT"><parameter>nt acl support</parameter></link></para></listitem>
+ <listitem><para><link linkend="ONLYGUEST"><parameter>only guest</parameter></link></para></listitem>
+ <listitem><para><link linkend="ONLYUSER"><parameter>only user</parameter></link></para></listitem>
+ <listitem><para><link linkend="OPLOCKCONTENTIONLIMIT"><parameter>oplock contention limit</parameter></link></para></listitem>
+ <listitem><para><link linkend="OPLOCKS"><parameter>oplocks</parameter></link></para></listitem>
+ <listitem><para><link linkend="PATH"><parameter>path</parameter></link></para></listitem>
+ <listitem><para><link linkend="POSIXLOCKING"><parameter>posix locking</parameter></link></para></listitem>
+ <listitem><para><link linkend="POSTEXEC"><parameter>postexec</parameter></link></para></listitem>
+ <listitem><para><link linkend="POSTSCRIPT"><parameter>postscript</parameter></link></para></listitem>
+ <listitem><para><link linkend="PREEXEC"><parameter>preexec</parameter></link></para></listitem>
+ <listitem><para><link linkend="PREEXECCLOSE"><parameter>preexec close</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRESERVECASE"><parameter>preserve case</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTCOMMAND"><parameter>print command</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTOK"><parameter>print ok</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTABLE"><parameter>printable</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTER"><parameter>printer</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTERADMIN"><parameter>printer admin</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTERDRIVER"><parameter>printer driver</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTERDRIVERLOCATION"><parameter>printer driver location</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTERNAME"><parameter>printer name</parameter></link></para></listitem>
+ <listitem><para><link linkend="PRINTING"><parameter>printing</parameter></link></para></listitem>
+ <listitem><para><link linkend="PROFILEACLS"><parameter>profile acls</parameter></link></para></listitem>
+ <listitem><para><link linkend="PUBLIC"><parameter>public</parameter></link></para></listitem>
+ <listitem><para><link linkend="QUEUEPAUSECOMMAND"><parameter>queuepause command</parameter></link></para></listitem>
+ <listitem><para><link linkend="QUEUERESUMECOMMAND"><parameter>queueresume command</parameter></link></para></listitem>
+ <listitem><para><link linkend="READLIST"><parameter>read list</parameter></link></para></listitem>
+ <listitem><para><link linkend="READONLY"><parameter>read only</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOTPOSTEXEC"><parameter>root postexec</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOTPREEXEC"><parameter>root preexec</parameter></link></para></listitem>
+ <listitem><para><link linkend="ROOTPREEXECCLOSE"><parameter>root preexec close</parameter></link></para></listitem>
+ <listitem><para><link linkend="SECURITYMASK"><parameter>security mask</parameter></link></para></listitem>
+ <listitem><para><link linkend="SETDIRECTORY"><parameter>set directory</parameter></link></para></listitem>
+ <listitem><para><link linkend="SHAREMODES"><parameter>share modes</parameter></link></para></listitem>
+ <listitem><para><link linkend="SHORTPRESERVECASE"><parameter>short preserve case</parameter></link></para></listitem>
+ <listitem><para><link linkend="STATUS"><parameter>status</parameter></link></para></listitem>
+ <listitem><para><link linkend="STRICTALLOCATE"><parameter>strict allocate</parameter></link></para></listitem>
+ <listitem><para><link linkend="STRICTLOCKING"><parameter>strict locking</parameter></link></para></listitem>
+ <listitem><para><link linkend="STRICTSYNC"><parameter>strict sync</parameter></link></para></listitem>
+ <listitem><para><link linkend="SYNCALWAYS"><parameter>sync always</parameter></link></para></listitem>
+ <listitem><para><link linkend="USECLIENTDRIVER"><parameter>use client driver</parameter></link></para></listitem>
+ <listitem><para><link linkend="USESENDFILE"><parameter>use sendfile</parameter></link></para></listitem>
+ <listitem><para><link linkend="USER"><parameter>user</parameter></link></para></listitem>
+ <listitem><para><link linkend="USERNAME"><parameter>username</parameter></link></para></listitem>
+ <listitem><para><link linkend="USERS"><parameter>users</parameter></link></para></listitem>
+ <listitem><para><link linkend="VALIDUSERS"><parameter>valid users</parameter></link></para></listitem>
+ <listitem><para><link linkend="VETOFILES"><parameter>veto files</parameter></link></para></listitem>
+ <listitem><para><link linkend="VETOOPLOCKFILES"><parameter>veto oplock files</parameter></link></para></listitem>
+ <listitem><para><link linkend="VFSOBJECT"><parameter>vfs object</parameter></link></para></listitem>
+ <listitem><para><link linkend="VFSOPTIONS"><parameter>vfs options</parameter></link></para></listitem>
+ <listitem><para><link linkend="VOLUME"><parameter>volume</parameter></link></para></listitem>
+ <listitem><para><link linkend="WIDELINKS"><parameter>wide links</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITABLE"><parameter>writable</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITECACHESIZE"><parameter>write cache size</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITELIST"><parameter>write list</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITEOK"><parameter>write ok</parameter></link></para></listitem>
+ <listitem><para><link linkend="WRITEABLE"><parameter>writeable</parameter></link></para></listitem>
+ </itemizedlist>
+
+</refsect1>
+
+<refsect1>
+ <title>EXPLANATION OF EACH PARAMETER</title>
+
+ <variablelist>
+
+
+ <varlistentry>
+ <term><anchor id="ACLCOMPATIBILITY">acl compatibility (G)</term>
+ <listitem><para>New in Samba 2.2.8 and above, this string parameter tells
+ smbd if it should modify any Windows access control lists created
+ from POSIX access control lists to remove features which are not
+ supported by Windows 2000 but not supported by the Windows NT ACL edit.
+ control.</para>
+
+ <para>By default this parameter is set automatically by detecting the
+ client type and is set to "true" if the client is Windows NT.</para>
+
+ <para>Default: <emphasis>client detected</emphasis></para>
+ <para>Example: <command>acl compatibility = Win2k</command></para>
+ <para>Example: <command>acl compatibility = winnt</command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="ADDPRINTERCOMMAND">add printer command (G)</term>
+ <listitem><para>With the introduction of MS-RPC based printing
+ support for Windows NT/2000 clients in Samba 2.2, The MS Add
+ Printer Wizard (APW) icon is now also available in the
+ "Printers..." folder displayed a share listing. The APW
+ allows for printers to be add remotely to a Samba or Windows
+ NT/2000 print server.</para>
+
+ <para>For a Samba host this means that the printer must be
+ physically added to the underlying printing system. The <parameter>add
+ printer command</parameter> defines a script to be run which
+ will perform the necessary operations for adding the printer
+ to the print system and to add the appropriate service definition
+ to the <filename>smb.conf</filename> file in order that it can be
+ shared by <ulink url="smbd.8.html"><command>smbd(8)</command>
+ </ulink>.</para>
+
+ <para>The <parameter>add printer command</parameter> is
+ automatically invoked with the following parameter (in
+ order:</para>
+
+ <itemizedlist>
+ <listitem><para><parameter>printer name</parameter></para></listitem>
+ <listitem><para><parameter>share name</parameter></para></listitem>
+ <listitem><para><parameter>port name</parameter></para></listitem>
+ <listitem><para><parameter>driver name</parameter></para></listitem>
+ <listitem><para><parameter>location</parameter></para></listitem>
+ <listitem><para><parameter>Windows 9x driver location</parameter>
+ </para></listitem>
+ </itemizedlist>
+
+ <para>All parameters are filled in from the PRINTER_INFO_2 structure sent
+ by the Windows NT/2000 client with one exception. The "Windows 9x
+ driver location" parameter is included for backwards compatibility
+ only. The remaining fields in the structure are generated from answers
+ to the APW questions.</para>
+
+ <para>Once the <parameter>add printer command</parameter> has
+ been executed, <command>smbd</command> will reparse the <filename>
+ smb.conf</filename> to determine if the share defined by the APW
+ exists. If the sharename is still invalid, then <command>smbd
+ </command> will return an ACCESS_DENIED error to the client.</para>
+
+ <para>See also <link linkend="DELETEPRINTERCOMMAND"><parameter>
+ delete printer command</parameter></link>, <link
+ linkend="printing"><parameter>printing</parameter></link>,
+ <link linkend="SHOWADDPRINTERWIZARD"><parameter>show add
+ printer wizard</parameter></link></para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>addprinter command = /usr/bin/addprinter
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ADDSHARECOMMAND">add share command (G)</term>
+ <listitem><para>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <parameter>add share command</parameter> is used to define an
+ external program or script which will add a new service definition
+ to <filename>smb.conf</filename>. In order to successfully
+ execute the <parameter>add share command</parameter>, <command>smbd</command>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </para>
+
+ <para>
+ When executed, <command>smbd</command> will automatically invoke the
+ <parameter>add share command</parameter> with four parameters.
+ </para>
+
+ <itemizedlist>
+ <listitem><para><parameter>configFile</parameter> - the location
+ of the global <filename>smb.conf</filename> file.
+ </para></listitem>
+
+ <listitem><para><parameter>shareName</parameter> - the name of the new
+ share.
+ </para></listitem>
+
+ <listitem><para><parameter>pathName</parameter> - path to an **existing**
+ directory on disk.
+ </para></listitem>
+
+ <listitem><para><parameter>comment</parameter> - comment string to associate
+ with the new share.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ This parameter is only used for add file shares. To add printer shares,
+ see the <link linkend="ADDPRINTERCOMMAND"><parameter>add printer
+ command</parameter></link>.
+ </para>
+
+ <para>
+ See also <link linkend="CHANGESHARECOMMAND"><parameter>change share
+ command</parameter></link>, <link linkend="DELETESHARECOMMAND"><parameter>delete share
+ command</parameter></link>.
+ </para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>add share command = /usr/local/bin/addshare</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="ADDUSERSCRIPT">add user script (G)</term>
+ <listitem><para>This is the full pathname to a script that will
+ be run <emphasis>AS ROOT</emphasis> by <ulink url="smbd.8.html">smbd(8)
+ </ulink> under special circumstances described below.</para>
+
+ <para>Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server. For sites
+ that use Windows NT account databases as their primary user database
+ creating these users and keeping the user list in sync with the
+ Windows NT PDC is an onerous task. This option allows <ulink
+ url="smbd.8.html">smbd</ulink> to create the required UNIX users
+ <emphasis>ON DEMAND</emphasis> when a user accesses the Samba server.</para>
+
+ <para>In order to use this option, <ulink url="smbd.8.html">smbd</ulink>
+ must <emphasis>NOT</emphasis> be set to <parameter>security = share</parameter>
+ and <parameter>add user script</parameter>
+ must be set to a full pathname for a script that will create a UNIX
+ user given one argument of <parameter>%u</parameter>, which expands into
+ the UNIX user name to create.</para>
+
+ <para>When the Windows user attempts to access the Samba server,
+ at login (session setup in the SMB protocol) time, <ulink url="smbd.8.html">
+ smbd</ulink> contacts the <parameter>password server</parameter> and
+ attempts to authenticate the given user with the given password. If the
+ authentication succeeds then <command>smbd</command>
+ attempts to find a UNIX user in the UNIX password database to map the
+ Windows user into. If this lookup fails, and <parameter>add user script
+ </parameter> is set then <command>smbd</command> will
+ call the specified script <emphasis>AS ROOT</emphasis>, expanding
+ any <parameter>%u</parameter> argument to be the user name to create.</para>
+
+ <para>If this script successfully creates the user then <command>smbd
+ </command> will continue on as though the UNIX user
+ already existed. In this way, UNIX users are dynamically created to
+ match existing Windows NT accounts.</para>
+
+ <para>See also <link linkend="SECURITY"><parameter>
+ security</parameter></link>, <link linkend="PASSWORDSERVER">
+ <parameter>password server</parameter></link>,
+ <link linkend="DELETEUSERSCRIPT"><parameter>delete user
+ script</parameter></link>.</para>
+
+ <para>Default: <command>add user script = &lt;empty string&gt;
+ </command></para>
+
+ <para>Example: <command>add user script = /usr/local/samba/bin/add_user
+ %u</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="ADMINUSERS">admin users (S)</term>
+ <listitem><para>This is a list of users who will be granted
+ administrative privileges on the share. This means that they
+ will do all file operations as the super-user (root).</para>
+
+ <para>You should use this option very carefully, as any user in
+ this list will be able to do anything they like on the share,
+ irrespective of file permissions.</para>
+
+ <para>Default: <emphasis>no admin users</emphasis></para>
+
+ <para>Example: <command>admin users = jason</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ALLOWHOSTS">allow hosts (S)</term>
+ <listitem><para>Synonym for <link linkend="HOSTSALLOW">
+ <parameter>hosts allow</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ALLOWTRUSTEDDOMAINS">allow trusted domains (G)</term>
+ <listitem><para>This option only takes effect when the <link
+ linkend="SECURITY"><parameter>security</parameter></link> option is set to
+ <constant>server</constant> or <constant>domain</constant>.
+ If it is set to no, then attempts to connect to a resource from
+ a domain or workgroup other than the one which <ulink url="smbd.8.html">smbd</ulink> is running
+ in will fail, even if that domain is trusted by the remote server
+ doing the authentication.</para>
+
+ <para>This is useful if you only want your Samba server to
+ serve resources to users in the domain it is a member of. As
+ an example, suppose that there are two domains DOMA and DOMB. DOMB
+ is trusted by DOMA, which contains the Samba server. Under normal
+ circumstances, a user with an account in DOMB can then access the
+ resources of a UNIX account with the same account name on the
+ Samba server even if they do not have an account in DOMA. This
+ can make implementing a security boundary difficult.</para>
+
+ <para>Default: <command>allow trusted domains = yes</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ANNOUNCEAS">announce as (G)</term>
+ <listitem><para>This specifies what type of server
+ <ulink url="nmbd.8.html"><command>nmbd</command></ulink>
+ will announce itself as, to a network neighborhood browse
+ list. By default this is set to Windows NT. The valid options
+ are : "NT Server" (which can also be written as "NT"),
+ "NT Workstation", "Win95" or "WfW" meaning Windows NT Server,
+ Windows NT Workstation, Windows 95 and Windows for Workgroups
+ respectively. Do not change this parameter unless you have a
+ specific need to stop Samba appearing as an NT server as this
+ may prevent Samba servers from participating as browser servers
+ correctly.</para>
+
+ <para>Default: <command>announce as = NT Server</command></para>
+
+ <para>Example: <command>announce as = Win95</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ANNOUNCEVERSION">announce version (G)</term>
+ <listitem><para>This specifies the major and minor version numbers
+ that nmbd will use when announcing itself as a server. The default
+ is 4.9. Do not change this parameter unless you have a specific
+ need to set a Samba server to be a downlevel server.</para>
+
+ <para>Default: <command>announce version = 4.9</command></para>
+
+ <para>Example: <command>announce version = 2.0</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="AUTOSERVICES">auto services (G)</term>
+ <listitem><para>This is a synonym for the <link linkend="PRELOAD">
+ <parameter>preload</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="AVAILABLE">available (S)</term>
+ <listitem><para>This parameter lets you "turn off" a service. If
+ <parameter>available = no</parameter>, then <emphasis>ALL</emphasis>
+ attempts to connect to the service will fail. Such failures are
+ logged.</para>
+
+ <para>Default: <command>available = yes</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="BINDINTERFACESONLY">bind interfaces only (G)</term>
+ <listitem><para>This global parameter allows the Samba admin
+ to limit what interfaces on a machine will serve SMB requests. If
+ affects file service <ulink url="smbd.8.html">smbd(8)</ulink> and
+ name service <ulink url="nmbd.8.html">nmbd(8)</ulink> in slightly
+ different ways.</para>
+
+ <para>For name service it causes <command>nmbd</command> to bind
+ to ports 137 and 138 on the interfaces listed in the <link
+ linkend="INTERFACES">interfaces</link> parameter. <command>nmbd
+ </command> also binds to the "all addresses" interface (0.0.0.0)
+ on ports 137 and 138 for the purposes of reading broadcast messages.
+ If this option is not set then <command>nmbd</command> will service
+ name requests on all of these sockets. If <parameter>bind interfaces
+ only</parameter> is set then <command>nmbd</command> will check the
+ source address of any packets coming in on the broadcast sockets
+ and discard any that don't match the broadcast addresses of the
+ interfaces in the <parameter>interfaces</parameter> parameter list.
+ As unicast packets are received on the other sockets it allows
+ <command>nmbd</command> to refuse to serve names to machines that
+ send packets that arrive through any interfaces not listed in the
+ <parameter>interfaces</parameter> list. IP Source address spoofing
+ does defeat this simple check, however so it must not be used
+ seriously as a security feature for <command>nmbd</command>.</para>
+
+ <para>If <parameter>bind interfaces only</parameter> is set and the
+ <link linkend="INTERFACES">interfaces</link> parameter only contains
+ a virtual interface like for example <parameter>eth0:1</parameter>,
+ then you also need to set the <link linkend="SOCKETADDRESS">socket
+ address</link> parameter to its IP address. Otherwise <command>nmbd
+ </command> as a local master browser will not be able to communicate
+ with the domain master browser for browse list replication.</para>
+
+ <para>For file service it causes <ulink url="smbd.8.html">smbd(8)</ulink>
+ to bind only to the interface list given in the <link linkend="INTERFACES">
+ interfaces</link> parameter. This restricts the networks that
+ <command>smbd</command> will serve to packets coming in those
+ interfaces. Note that you should not use this parameter for machines
+ that are serving PPP or other intermittent or non-broadcast network
+ interfaces as it will not cope with non-permanent interfaces.</para>
+
+ <para>If <parameter>bind interfaces only</parameter> is set then
+ unless the network address <emphasis>127.0.0.1</emphasis> is added
+ to the <parameter>interfaces</parameter> parameter list <ulink
+ url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink>
+ and <ulink url="swat.8.html"><command>swat(8)</command></ulink> may
+ not work as expected due to the reasons covered below.</para>
+
+ <para>To change a users SMB password, the <command>smbpasswd</command>
+ by default connects to the <emphasis>localhost - 127.0.0.1</emphasis>
+ address as an SMB client to issue the password change request. If
+ <parameter>bind interfaces only</parameter> is set then unless the
+ network address <emphasis>127.0.0.1</emphasis> is added to the
+ <parameter>interfaces</parameter> parameter list then <command>
+ smbpasswd</command> will fail to connect in it's default mode.
+ <command>smbpasswd</command> can be forced to use the primary IP interface
+ of the local host by using its <ulink url="smbpasswd.8.html#minusr">
+ <parameter>-r <replaceable>remote machine</replaceable></parameter>
+ </ulink> parameter, with <replaceable>remote machine</replaceable> set
+ to the IP name of the primary interface of the local host.</para>
+
+ <para>The <command>swat</command> status page tries to connect with
+ <command>smbd</command> and <command>nmbd</command> at the address
+ <emphasis>127.0.0.1</emphasis> to determine if they are running.
+ Not adding <emphasis>127.0.0.1</emphasis> will cause <command>
+ smbd</command> and <command>nmbd</command> to always show
+ "not running" even if they really are. This can prevent <command>
+ swat</command> from starting/stopping/restarting <command>smbd</command>
+ and <command>nmbd</command>.</para>
+
+ <para>Default: <command>bind interfaces only = no</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="BLOCKSIZE">block size (S)</term>
+ <listitem><para>This parameter controls the behavior of <ulink
+ url="smbd.8.html">smbd(8)</ulink> when reporting disk free sizes.
+ By default, this reports a disk block size of 1024 bytes.</para>
+
+ <para>Changing this parameter may have some effect on the
+ efficiency of client writes, this is not yet confirmed. This
+ parameter was added to allow advanced administrators to change
+ it (usually to a higher value) and test the effect it has on
+ client write performance without re-compiling the code. As this
+ is an experimental option it may be removed in a future release.
+ </para>
+
+ <para>Changing this option does not change the disk free reporting
+ size, just the block size unit reported to the client.</para>
+
+ <para>Default: <command>block size = 1024</command></para>
+ <para>Example: <command>block size = 65536</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="BLOCKINGLOCKS">blocking locks (S)</term>
+ <listitem><para>This parameter controls the behavior of <ulink
+ url="smbd.8.html">smbd(8)</ulink> when given a request by a client
+ to obtain a byte range lock on a region of an open file, and the
+ request has a time limit associated with it.</para>
+
+ <para>If this parameter is set and the lock range requested
+ cannot be immediately satisfied, Samba 2.2 will internally
+ queue the lock request, and periodically attempt to obtain
+ the lock until the timeout period expires.</para>
+
+ <para>If this parameter is set to <constant>no</constant>, then
+ Samba 2.2 will behave as previous versions of Samba would and
+ will fail the lock request immediately if the lock range
+ cannot be obtained.</para>
+
+ <para>Default: <command>blocking locks = yes</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="BROWSABLE">browsable (S)</term>
+ <listitem><para>See the <link linkend="BROWSEABLE"><parameter>
+ browseable</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="BROWSELIST">browse list (G)</term>
+ <listitem><para>This controls whether <ulink url="smbd.8.html">
+ <command>smbd(8)</command></ulink> will serve a browse list to
+ a client doing a <command>NetServerEnum</command> call. Normally
+ set to <constant>yes</constant>. You should never need to change
+ this.</para>
+
+ <para>Default: <command>browse list = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="BROWSEABLE">browseable (S)</term>
+ <listitem><para>This controls whether this share is seen in
+ the list of available shares in a net view and in the browse list.</para>
+
+ <para>Default: <command>browseable = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CASESENSITIVE">case sensitive (S)</term>
+ <listitem><para>See the discussion in the section <link
+ linkend="NAMEMANGLINGSECT">NAME MANGLING</link>.</para>
+
+ <para>Default: <command>case sensitive = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CASESIGNAMES">casesignames (S)</term>
+ <listitem><para>Synonym for <link linkend="CASESENSITIVE">case
+ sensitive</link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CHANGENOTIFYTIMEOUT">change notify timeout (G)</term>
+ <listitem><para>This SMB allows a client to tell a server to
+ "watch" a particular directory for any changes and only reply to
+ the SMB request when a change has occurred. Such constant scanning of
+ a directory is expensive under UNIX, hence an <ulink url="smbd.8.html">
+ <command>smbd(8)</command></ulink> daemon only performs such a scan
+ on each requested directory once every <parameter>change notify
+ timeout</parameter> seconds.</para>
+
+ <para>Default: <command>change notify timeout = 60</command></para>
+ <para>Example: <command>change notify timeout = 300</command></para>
+
+ <para>Would change the scan time to every 5 minutes.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CHANGESHARECOMMAND">change share command (G)</term>
+ <listitem><para>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <parameter>change share command</parameter> is used to define an
+ external program or script which will modify an existing service definition
+ in <filename>smb.conf</filename>. In order to successfully
+ execute the <parameter>change share command</parameter>, <command>smbd</command>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </para>
+
+ <para>
+ When executed, <command>smbd</command> will automatically invoke the
+ <parameter>change share command</parameter> with four parameters.
+ </para>
+
+ <itemizedlist>
+ <listitem><para><parameter>configFile</parameter> - the location
+ of the global <filename>smb.conf</filename> file.
+ </para></listitem>
+
+ <listitem><para><parameter>shareName</parameter> - the name of the new
+ share.
+ </para></listitem>
+
+ <listitem><para><parameter>pathName</parameter> - path to an **existing**
+ directory on disk.
+ </para></listitem>
+
+ <listitem><para><parameter>comment</parameter> - comment string to associate
+ with the new share.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ This parameter is only used modify existing file shares definitions. To modify
+ printer shares, use the "Printers..." folder as seen when browsing the Samba host.
+ </para>
+
+ <para>
+ See also <link linkend="ADDSHARECOMMAND"><parameter>add share
+ command</parameter></link>, <link linkend="DELETESHARECOMMAND"><parameter>delete
+ share command</parameter></link>.
+ </para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>change share command = /usr/local/bin/addshare</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CHARACTERSET">character set (G)</term>
+ <listitem><para>This allows <ulink url="smbd.8.html">smbd</ulink> to map incoming filenames
+ from a DOS Code page (see the <link linkend="CLIENTCODEPAGE">client
+ code page</link> parameter) to several built in UNIX character sets.
+ The built in code page translations are:</para>
+
+ <itemizedlist>
+ <listitem><para><constant>ISO8859-1</constant> : Western European
+ UNIX character set. The parameter <parameter>client code page</parameter>
+ <emphasis>MUST</emphasis> be set to code page 850 if the
+ <parameter>character set</parameter> parameter is set to
+ <constant>ISO8859-1</constant> in order for the conversion to the
+ UNIX character set to be done correctly.</para></listitem>
+
+ <listitem><para><constant>ISO8859-2</constant> : Eastern European
+ UNIX character set. The parameter <parameter>client code page
+ </parameter> <emphasis>MUST</emphasis> be set to code page 852 if
+ the <parameter> character set</parameter> parameter is set
+ to <constant>ISO8859-2</constant> in order for the conversion
+ to the UNIX character set to be done correctly. </para></listitem>
+
+ <listitem><para><constant>ISO8859-5</constant> : Russian Cyrillic
+ UNIX character set. The parameter <parameter>client code page
+ </parameter> <emphasis>MUST</emphasis> be set to code page
+ 866 if the <parameter>character set </parameter> parameter is
+ set to <constant>ISO8859-5</constant> in order for the conversion
+ to the UNIX character set to be done correctly. </para></listitem>
+
+ <listitem><para><constant>ISO8859-7</constant> : Greek UNIX
+ character set. The parameter <parameter>client code page
+ </parameter> <emphasis>MUST</emphasis> be set to code page
+ 737 if the <parameter>character set</parameter> parameter is
+ set to <constant>ISO8859-7</constant> in order for the conversion
+ to the UNIX character set to be done correctly.</para></listitem>
+
+ <listitem><para><constant>KOI8-R</constant> : Alternate mapping
+ for Russian Cyrillic UNIX character set. The parameter
+ <parameter>client code page</parameter> <emphasis>MUST</emphasis>
+ be set to code page 866 if the <parameter>character set</parameter>
+ parameter is set to <constant>KOI8-R</constant> in order for the
+ conversion to the UNIX character set to be done correctly.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis>BUG</emphasis>. These MSDOS code page to UNIX character
+ set mappings should be dynamic, like the loading of MS DOS code pages,
+ not static.</para>
+
+ <para>Normally this parameter is not set, meaning no filename
+ translation is done.</para>
+
+ <para>Default: <command>character set = &lt;empty string&gt;</command></para>
+ <para>Example: <command>character set = ISO8859-1</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CLIENTCODEPAGE">client code page (G)</term>
+ <listitem><para>This parameter specifies the DOS code page
+ that the clients accessing Samba are using. To determine what code
+ page a Windows or DOS client is using, open a DOS command prompt
+ and type the command <command>chcp</command>. This will output
+ the code page. The default for USA MS-DOS, Windows 95, and
+ Windows NT releases is code page 437. The default for western
+ European releases of the above operating systems is code page 850.</para>
+
+ <para>This parameter tells <ulink url="smbd.8.html">smbd(8)</ulink>
+ which of the <filename>codepage.<replaceable>XXX</replaceable>
+ </filename> files to dynamically load on startup. These files,
+ described more fully in the manual page <ulink url="make_smbcodepage.1.html">
+ <command>make_smbcodepage(1)</command></ulink>, tell <command>
+ smbd</command> how to map lower to upper case characters to provide
+ the case insensitivity of filenames that Windows clients expect.</para>
+
+ <para>Samba currently ships with the following code page files :</para>
+
+ <itemizedlist>
+ <listitem><para>Code Page 437 - MS-DOS Latin US</para></listitem>
+ <listitem><para>Code Page 737 - Windows '95 Greek</para></listitem>
+ <listitem><para>Code Page 850 - MS-DOS Latin 1</para></listitem>
+ <listitem><para>Code Page 852 - MS-DOS Latin 2</para></listitem>
+ <listitem><para>Code Page 861 - MS-DOS Icelandic</para></listitem>
+ <listitem><para>Code Page 866 - MS-DOS Cyrillic</para></listitem>
+ <listitem><para>Code Page 932 - MS-DOS Japanese SJIS</para></listitem>
+ <listitem><para>Code Page 936 - MS-DOS Simplified Chinese</para></listitem>
+ <listitem><para>Code Page 949 - MS-DOS Korean Hangul</para></listitem>
+ <listitem><para>Code Page 950 - MS-DOS Traditional Chinese</para></listitem>
+ </itemizedlist>
+
+ <para>Thus this parameter may have any of the values 437, 737, 850, 852,
+ 861, 932, 936, 949, or 950. If you don't find the codepage you need,
+ read the comments in one of the other codepage files and the
+ <command>make_smbcodepage(1)</command> man page and write one. Please
+ remember to donate it back to the Samba user community.</para>
+
+ <para>This parameter co-operates with the <parameter>valid
+ chars</parameter> parameter in determining what characters are
+ valid in filenames and how capitalization is done. If you set both
+ this parameter and the <parameter>valid chars</parameter> parameter
+ the <parameter>client code page</parameter> parameter
+ <emphasis>MUST</emphasis> be set before the <parameter>valid
+ chars</parameter> parameter in the <filename>smb.conf</filename>
+ file. The <parameter>valid chars</parameter> string will then
+ augment the character settings in the <parameter>client code page</parameter>
+ parameter.</para>
+
+ <para>If not set, <parameter>client code page</parameter> defaults
+ to 850.</para>
+
+ <para>See also : <link linkend="VALIDCHARS"><parameter>valid
+ chars</parameter></link>, <link linkend="CODEPAGEDIRECTORY">
+ <parameter>code page directory</parameter></link></para>
+
+ <para>Default: <command>client code page = 850</command></para>
+ <para>Example: <command>client code page = 936</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="CODEPAGEDIRECTORY">code page directory (G)</term>
+ <listitem><para>Define the location of the various client code page
+ files.</para>
+
+ <para>See also <link linkend="CLIENTCODEPAGE"><parameter>client
+ code page</parameter></link></para>
+
+ <para>Default: <command>code page directory = ${prefix}/lib/codepages
+ </command></para>
+ <para>Example: <command>code page directory = /usr/share/samba/codepages
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="CODINGSYSTEM">coding system (G)</term>
+ <listitem><para>This parameter is used to determine how incoming
+ Shift-JIS Japanese characters are mapped from the incoming <link
+ linkend="CLIENTCODEPAGE"><parameter>client code page</parameter>
+ </link> used by the client, into file names in the UNIX filesystem.
+ Only useful if <parameter>client code page</parameter> is set to
+ 932 (Japanese Shift-JIS). The options are :</para>
+
+ <itemizedlist>
+ <listitem><para><constant>SJIS</constant> - Shift-JIS. Does no
+ conversion of the incoming filename.</para></listitem>
+
+ <listitem><para><constant>JIS8, J8BB, J8BH, J8@B,
+ J8@J, J8@H </constant> - Convert from incoming Shift-JIS to eight
+ bit JIS code with different shift-in, shift out codes.</para></listitem>
+
+ <listitem><para><constant>JIS7, J7BB, J7BH, J7@B, J7@J,
+ J7@H </constant> - Convert from incoming Shift-JIS to seven bit
+ JIS code with different shift-in, shift out codes.</para></listitem>
+
+ <listitem><para><constant>JUNET, JUBB, JUBH, JU@B, JU@J, JU@H </constant>
+ - Convert from incoming Shift-JIS to JUNET code with different shift-in,
+ shift out codes.</para></listitem>
+
+ <listitem><para><constant>EUC</constant> - Convert an incoming
+ Shift-JIS character to EUC code.</para></listitem>
+
+ <listitem><para><constant>HEX</constant> - Convert an incoming
+ Shift-JIS character to a 3 byte hex representation, i.e.
+ <constant>:AB</constant>.</para></listitem>
+
+ <listitem><para><constant>CAP</constant> - Convert an incoming
+ Shift-JIS character to the 3 byte hex representation used by
+ the Columbia AppleTalk Program (CAP), i.e. <constant>:AB</constant>.
+ This is used for compatibility between Samba and CAP.</para></listitem>
+ </itemizedlist>
+
+ <para>Default: <command>coding system = &lt;empty value&gt;</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="COMMENT">comment (S)</term>
+ <listitem><para>This is a text field that is seen next to a share
+ when a client does a queries the server, either via the network
+ neighborhood or via <command>net view</command> to list what shares
+ are available.</para>
+
+ <para>If you want to set the string that is displayed next to the
+ machine name then see the <link linkend="SERVERSTRING"><parameter>
+ server string</parameter></link> parameter.</para>
+
+ <para>Default: <emphasis>No comment string</emphasis></para>
+ <para>Example: <command>comment = Fred's Files</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CONFIGFILE">config file (G)</term>
+ <listitem><para>This allows you to override the config file
+ to use, instead of the default (usually <filename>smb.conf</filename>).
+ There is a chicken and egg problem here as this option is set
+ in the config file!</para>
+
+ <para>For this reason, if the name of the config file has changed
+ when the parameters are loaded then it will reload them from
+ the new config file.</para>
+
+ <para>This option takes the usual substitutions, which can
+ be very useful.</para>
+
+ <para>If the config file doesn't exist then it won't be loaded
+ (allowing you to special case the config files of just a few
+ clients).</para>
+
+ <para>Example: <command>config file = /usr/local/samba/lib/smb.conf.%m
+ </command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="COPY">copy (S)</term>
+ <listitem><para>This parameter allows you to "clone" service
+ entries. The specified service is simply duplicated under the
+ current service's name. Any parameters specified in the current
+ section will override those in the section being copied.</para>
+
+ <para>This feature lets you set up a 'template' service and
+ create similar services easily. Note that the service being
+ copied must occur earlier in the configuration file than the
+ service doing the copying.</para>
+
+ <para>Default: <emphasis>no value</emphasis></para>
+ <para>Example: <command>copy = otherservice</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CREATEMASK">create mask (S)</term>
+ <listitem><para>A synonym for this parameter is
+ <link linkend="CREATEMODE"><parameter>create mode</parameter>
+ </link>.</para>
+
+ <para>When a file is created, the necessary permissions are
+ calculated according to the mapping from DOS modes to UNIX
+ permissions, and the resulting UNIX mode is then bit-wise 'AND'ed
+ with this parameter. This parameter may be thought of as a bit-wise
+ MASK for the UNIX modes of a file. Any bit <emphasis>not</emphasis>
+ set here will be removed from the modes set on a file when it is
+ created.</para>
+
+ <para>The default value of this parameter removes the
+ 'group' and 'other' write and execute bits from the UNIX modes.</para>
+
+ <para>Following this Samba will bit-wise 'OR' the UNIX mode created
+ from this parameter with the value of the <link
+ linkend="FORCECREATEMODE"><parameter>force create mode</parameter></link>
+ parameter which is set to 000 by default.</para>
+
+ <para>This parameter does not affect directory modes. See the
+ parameter <link linkend="DIRECTORYMODE"><parameter>directory mode
+ </parameter></link> for details.</para>
+
+ <para>See also the <link linkend="FORCECREATEMODE"><parameter>force
+ create mode</parameter></link> parameter for forcing particular mode
+ bits to be set on created files. See also the <link linkend="DIRECTORYMODE">
+ <parameter>directory mode</parameter></link> parameter for masking
+ mode bits on created directories. See also the <link linkend="INHERITPERMISSIONS">
+ <parameter>inherit permissions</parameter></link> parameter.</para>
+
+ <para>Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+ a mask on access control lists also, they need to set the <link
+ linkend="SECURITYMASK"><parameter>security mask</parameter></link>.</para>
+
+ <para>Default: <command>create mask = 0744</command></para>
+ <para>Example: <command>create mask = 0775</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="CREATEMODE">create mode (S)</term>
+ <listitem><para>This is a synonym for <link linkend="CREATEMASK"><parameter>
+ create mask</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="CSCPOLICY">csc policy (S)</term>
+ <listitem><para>This stands for <emphasis>client-side caching
+ policy</emphasis>, and specifies how clients capable of offline
+ caching will cache the files in the share. The valid values
+ are: manual, documents, programs, disable.</para>
+
+ <para>These values correspond to those used on Windows
+ servers.</para>
+
+ <para>For example, shares containing roaming profiles can have
+ offline caching disabled using <command>csc policy = disable
+ </command>.</para>
+
+ <para>Default: <command>csc policy = manual</command></para>
+ <para>Example: <command>csc policy = programs</command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="DEADTIME">deadtime (G)</term>
+ <listitem><para>The value of the parameter (a decimal integer)
+ represents the number of minutes of inactivity before a connection
+ is considered dead, and it is disconnected. The deadtime only takes
+ effect if the number of open files is zero.</para>
+
+ <para>This is useful to stop a server's resources being
+ exhausted by a large number of inactive connections.</para>
+
+ <para>Most clients have an auto-reconnect feature when a
+ connection is broken so in most cases this parameter should be
+ transparent to users.</para>
+
+ <para>Using this parameter with a timeout of a few minutes
+ is recommended for most systems.</para>
+
+ <para>A deadtime of zero indicates that no auto-disconnection
+ should be performed.</para>
+
+ <para>Default: <command>deadtime = 0</command></para>
+ <para>Example: <command>deadtime = 15</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEBUGHIRESTIMESTAMP">debug hires timestamp (G)</term>
+ <listitem><para>Sometimes the timestamps in the log messages
+ are needed with a resolution of higher that seconds, this
+ boolean parameter adds microsecond resolution to the timestamp
+ message header when turned on.</para>
+
+ <para>Note that the parameter <link linkend="DEBUGTIMESTAMP"><parameter>
+ debug timestamp</parameter></link> must be on for this to have an
+ effect.</para>
+
+ <para>Default: <command>debug hires timestamp = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEBUGPID">debug pid (G)</term>
+ <listitem><para>When using only one log file for more then one
+ forked <ulink url="smbd.8.html">smbd</ulink>-process there may be hard to follow which process
+ outputs which message. This boolean parameter is adds the process-id
+ to the timestamp message headers in the logfile when turned on.</para>
+
+ <para>Note that the parameter <link linkend="DEBUGTIMESTAMP"><parameter>
+ debug timestamp</parameter></link> must be on for this to have an
+ effect.</para>
+
+ <para>Default: <command>debug pid = no</command></para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="DEBUGTIMESTAMP">debug timestamp (G)</term>
+ <listitem><para>Samba 2.2 debug log messages are timestamped
+ by default. If you are running at a high <link linkend="DEBUGLEVEL">
+ <parameter>debug level</parameter></link> these timestamps
+ can be distracting. This boolean parameter allows timestamping
+ to be turned off.</para>
+
+ <para>Default: <command>debug timestamp = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEBUGUID">debug uid (G)</term>
+ <listitem><para>Samba is sometimes run as root and sometime
+ run as the connected user, this boolean parameter inserts the
+ current euid, egid, uid and gid to the timestamp message headers
+ in the log file if turned on.</para>
+
+ <para>Note that the parameter <link linkend="DEBUGTIMESTAMP"><parameter>
+ debug timestamp</parameter></link> must be on for this to have an
+ effect.</para>
+
+ <para>Default: <command>debug uid = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEBUGLEVEL">debuglevel (G)</term>
+ <listitem><para>Synonym for <link linkend="LOGLEVEL"><parameter>
+ log level</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEFAULT">default (G)</term>
+ <listitem><para>A synonym for <link linkend="DEFAULTSERVICE"><parameter>
+ default service</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEFAULTCASE">default case (S)</term>
+ <listitem><para>See the section on <link linkend="NAMEMANGLINGSECT">
+ NAME MANGLING</link>. Also note the <link linkend="SHORTPRESERVECASE">
+ <parameter>short preserve case</parameter></link> parameter.</para>
+
+ <para>Default: <command>default case = lower</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEFAULTDEVMODE">default devmode (S)</term>
+ <listitem><para>This parameter is only applicable to <link
+ linkend="PRINTOK">printable</link> services. When smbd is serving
+ Printer Drivers to Windows NT/2k/XP clients, each printer on the Samba
+ server has a Device Mode which defines things such as paper size and
+ orientation and duplex settings. The device mode can only correctly be
+ generated by the printer driver itself (which can only be executed on a
+ Win32 platform). Because smbd is unable to execute the driver code
+ to generate the device mode, the default behavior is to set this field
+ to NULL.
+ </para>
+
+ <para>Most problems with serving printer drivers to Windows NT/2k/XP clients
+ can be traced to a problem with the generated device mode. Certain drivers
+ will do things such as crashing the client's Explorer.exe with a NULL devmode.
+ However, other printer drivers can cause the client's spooler service
+ (spoolsv.exe) to die if the devmode was not created by the driver itself
+ (i.e. smbd generates a default devmode).
+ </para>
+
+ <para>This parameter should be used with care and tested with the printer
+ driver in question. It is better to leave the device mode to NULL
+ and let the Windows client set the correct values. Because drivers do not
+ do this all the time, setting <command>default devmode = yes</command>
+ will instruct smbd to generate a default one.
+ </para>
+
+ <para>For more information on Windows NT/2k printing and Device Modes,
+ see the <ulink url="http://msdn.microsoft.com/">MSDN documentation</ulink>.
+ </para>
+
+ <para>Default: <command>default devmode = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DEFAULTSERVICE">default service (G)</term>
+ <listitem><para>This parameter specifies the name of a service
+ which will be connected to if the service actually requested cannot
+ be found. Note that the square brackets are <emphasis>NOT</emphasis>
+ given in the parameter value (see example below).</para>
+
+ <para>There is no default value for this parameter. If this
+ parameter is not given, attempting to connect to a nonexistent
+ service results in an error.</para>
+
+ <para>Typically the default service would be a <link linkend="GUESTOK">
+ <parameter>guest ok</parameter></link>, <link linkend="READONLY">
+ <parameter>read-only</parameter></link> service.</para>
+
+ <para>Also note that the apparent service name will be changed
+ to equal that of the requested service, this is very useful as it
+ allows you to use macros like <parameter>%S</parameter> to make
+ a wildcard service.</para>
+
+ <para>Note also that any "_" characters in the name of the service
+ used in the default service will get mapped to a "/". This allows for
+ interesting things.</para>
+
+
+ <para>Example:</para>
+
+ <para><programlisting>
+[global]
+ default service = pub
+
+[pub]
+ path = /%S
+ </programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DELETEPRINTERCOMMAND">delete printer command (G)</term>
+ <listitem><para>With the introduction of MS-RPC based printer
+ support for Windows NT/2000 clients in Samba 2.2, it is now
+ possible to delete printer at run time by issuing the
+ DeletePrinter() RPC call.</para>
+
+ <para>For a Samba host this means that the printer must be
+ physically deleted from underlying printing system. The <parameter>
+ deleteprinter command</parameter> defines a script to be run which
+ will perform the necessary operations for removing the printer
+ from the print system and from <filename>smb.conf</filename>.
+ </para>
+
+ <para>The <parameter>delete printer command</parameter> is
+ automatically called with only one parameter: <parameter>
+ "printer name"</parameter>.</para>
+
+
+ <para>Once the <parameter>delete printer command</parameter> has
+ been executed, <command>smbd</command> will reparse the <filename>
+ smb.conf</filename> to associated printer no longer exists.
+ If the sharename is still valid, then <command>smbd
+ </command> will return an ACCESS_DENIED error to the client.</para>
+
+ <para>See also <link linkend="ADDPRINTERCOMMAND"><parameter>
+ add printer command</parameter></link>, <link
+ linkend="printing"><parameter>printing</parameter></link>,
+ <link linkend="SHOWADDPRINTERWIZARD"><parameter>show add
+ printer wizard</parameter></link></para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>deleteprinter command = /usr/bin/removeprinter
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DELETEREADONLY">delete readonly (S)</term>
+ <listitem><para>This parameter allows readonly files to be deleted.
+ This is not normal DOS semantics, but is allowed by UNIX.</para>
+
+ <para>This option may be useful for running applications such
+ as rcs, where UNIX file ownership prevents changing file
+ permissions, and DOS semantics prevent deletion of a read only file.</para>
+
+ <para>Default: <command>delete readonly = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DELETESHARECOMMAND">delete share command (G)</term>
+ <listitem><para>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <parameter>delete share command</parameter> is used to define an
+ external program or script which will remove an existing service
+ definition from <filename>smb.conf</filename>. In order to successfully
+ execute the <parameter>delete share command</parameter>, <command>smbd</command>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </para>
+
+ <para>
+ When executed, <command>smbd</command> will automatically invoke the
+ <parameter>delete share command</parameter> with two parameters.
+ </para>
+
+ <itemizedlist>
+ <listitem><para><parameter>configFile</parameter> - the location
+ of the global <filename>smb.conf</filename> file.
+ </para></listitem>
+
+ <listitem><para><parameter>shareName</parameter> - the name of
+ the existing service.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ This parameter is only used to remove file shares. To delete printer shares,
+ see the <link linkend="DELETEPRINTERCOMMAND"><parameter>delete printer
+ command</parameter></link>.
+ </para>
+
+ <para>
+ See also <link linkend="ADDSHARECOMMAND"><parameter>add share
+ command</parameter></link>, <link linkend="CHANGESHARECOMMAND"><parameter>change
+ share command</parameter></link>.
+ </para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>delete share command = /usr/local/bin/delshare</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DELETEUSERSCRIPT">delete user script (G)</term>
+ <listitem><para>This is the full pathname to a script that will
+ be run <emphasis>AS ROOT</emphasis> by <ulink url="smbd.8.html">
+ <command>smbd(8)</command></ulink> under special circumstances
+ described below.</para>
+
+ <para>Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server. For sites
+ that use Windows NT account databases as their primary user database
+ creating these users and keeping the user list in sync with the
+ Windows NT PDC is an onerous task. This option allows <command>
+ smbd</command> to delete the required UNIX users <emphasis>ON
+ DEMAND</emphasis> when a user accesses the Samba server and the
+ Windows NT user no longer exists.</para>
+
+ <para>In order to use this option, <command>smbd</command> must be
+ set to <parameter>security = domain</parameter> or <parameter>security =
+ user</parameter> and <parameter>delete user script</parameter>
+ must be set to a full pathname for a script
+ that will delete a UNIX user given one argument of <parameter>%u</parameter>,
+ which expands into the UNIX user name to delete.</para>
+
+ <para>When the Windows user attempts to access the Samba server,
+ at <emphasis>login</emphasis> (session setup in the SMB protocol)
+ time, <command>smbd</command> contacts the <link linkend="PASSWORDSERVER">
+ <parameter>password server</parameter></link> and attempts to authenticate
+ the given user with the given password. If the authentication fails
+ with the specific Domain error code meaning that the user no longer
+ exists then <command>smbd</command> attempts to find a UNIX user in
+ the UNIX password database that matches the Windows user account. If
+ this lookup succeeds, and <parameter>delete user script</parameter> is
+ set then <command>smbd</command> will all the specified script
+ <emphasis>AS ROOT</emphasis>, expanding any <parameter>%u</parameter>
+ argument to be the user name to delete.</para>
+
+ <para>This script should delete the given UNIX username. In this way,
+ UNIX users are dynamically deleted to match existing Windows NT
+ accounts.</para>
+
+ <para>See also <link linkend="SECURITYEQUALSDOMAIN">security = domain</link>,
+ <link linkend="PASSWORDSERVER"><parameter>password server</parameter>
+ </link>, <link linkend="ADDUSERSCRIPT"><parameter>add user script</parameter>
+ </link>.</para>
+
+ <para>Default: <command>delete user script = &lt;empty string&gt;
+ </command></para>
+ <para>Example: <command>delete user script = /usr/local/samba/bin/del_user
+ %u</command></para></listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DELETEVETOFILES">delete veto files (S)</term>
+ <listitem><para>This option is used when Samba is attempting to
+ delete a directory that contains one or more vetoed directories
+ (see the <link linkend="VETOFILES"><parameter>veto files</parameter></link>
+ option). If this option is set to <constant>no</constant> (the default) then if a vetoed
+ directory contains any non-vetoed files or directories then the
+ directory delete will fail. This is usually what you want.</para>
+
+ <para>If this option is set to <constant>yes</constant>, then Samba
+ will attempt to recursively delete any files and directories within
+ the vetoed directory. This can be useful for integration with file
+ serving systems such as NetAtalk which create meta-files within
+ directories you might normally veto DOS/Windows users from seeing
+ (e.g. <filename>.AppleDouble</filename>)</para>
+
+ <para>Setting <command>delete veto files = yes</command> allows these
+ directories to be transparently deleted when the parent directory
+ is deleted (so long as the user has permissions to do so).</para>
+
+ <para>See also the <link linkend="VETOFILES"><parameter>veto
+ files</parameter></link> parameter.</para>
+
+ <para>Default: <command>delete veto files = no</command></para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DENYHOSTS">deny hosts (S)</term>
+ <listitem><para>Synonym for <link linkend="HOSTSDENY"><parameter>hosts
+ deny</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DFREECOMMAND">dfree command (G)</term>
+ <listitem><para>The <parameter>dfree command</parameter> setting should
+ only be used on systems where a problem occurs with the internal
+ disk space calculations. This has been known to happen with Ultrix,
+ but may occur with other operating systems. The symptom that was
+ seen was an error of "Abort Retry Ignore" at the end of each
+ directory listing.</para>
+
+ <para>This setting allows the replacement of the internal routines to
+ calculate the total disk space and amount available with an external
+ routine. The example below gives a possible script that might fulfill
+ this function.</para>
+
+ <para>The external program will be passed a single parameter indicating
+ a directory in the filesystem being queried. This will typically consist
+ of the string <filename>./</filename>. The script should return two
+ integers in ASCII. The first should be the total disk space in blocks,
+ and the second should be the number of available blocks. An optional
+ third return value can give the block size in bytes. The default
+ blocksize is 1024 bytes.</para>
+
+ <para>Note: Your script should <emphasis>NOT</emphasis> be setuid or
+ setgid and should be owned by (and writeable only by) root!</para>
+
+ <para>Default: <emphasis>By default internal routines for
+ determining the disk capacity and remaining space will be used.
+ </emphasis></para>
+
+ <para>Example: <command>dfree command = /usr/local/samba/bin/dfree
+ </command></para>
+
+ <para>Where the script dfree (which must be made executable) could be:</para>
+
+ <para><programlisting>
+ #!/bin/sh
+ df $1 | tail -1 | awk '{print $2" "$4}'
+ </programlisting></para>
+
+ <para>or perhaps (on Sys V based systems):</para>
+
+ <para><programlisting>
+ #!/bin/sh
+ /usr/bin/df -k $1 | tail -1 | awk '{print $3" "$5}'
+ </programlisting></para>
+
+ <para>Note that you may have to replace the command names
+ with full path names on some systems.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DIRECTORY">directory (S)</term>
+ <listitem><para>Synonym for <link linkend="PATH"><parameter>path
+ </parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DIRECTORYMASK">directory mask (S)</term>
+ <listitem><para>This parameter is the octal modes which are
+ used when converting DOS modes to UNIX modes when creating UNIX
+ directories.</para>
+
+ <para>When a directory is created, the necessary permissions are
+ calculated according to the mapping from DOS modes to UNIX permissions,
+ and the resulting UNIX mode is then bit-wise 'AND'ed with this
+ parameter. This parameter may be thought of as a bit-wise MASK for
+ the UNIX modes of a directory. Any bit <emphasis>not</emphasis> set
+ here will be removed from the modes set on a directory when it is
+ created.</para>
+
+ <para>The default value of this parameter removes the 'group'
+ and 'other' write bits from the UNIX mode, allowing only the
+ user who owns the directory to modify it.</para>
+
+ <para>Following this Samba will bit-wise 'OR' the UNIX mode
+ created from this parameter with the value of the <link
+ linkend="FORCEDIRECTORYMODE"><parameter>force directory mode
+ </parameter></link> parameter. This parameter is set to 000 by
+ default (i.e. no extra mode bits are added).</para>
+
+ <para>Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+ a mask on access control lists also, they need to set the <link
+ linkend="DIRECTORYSECURITYMASK"><parameter>directory security mask</parameter></link>.</para>
+
+ <para>See the <link linkend="FORCEDIRECTORYMODE"><parameter>force
+ directory mode</parameter></link> parameter to cause particular mode
+ bits to always be set on created directories.</para>
+
+ <para>See also the <link linkend="CREATEMODE"><parameter>create mode
+ </parameter></link> parameter for masking mode bits on created files,
+ and the <link linkend="DIRECTORYSECURITYMASK"><parameter>directory
+ security mask</parameter></link> parameter.</para>
+
+ <para>Also refer to the <link linkend="INHERITPERMISSIONS"><parameter>
+ inherit permissions</parameter></link> parameter.</para>
+
+ <para>Default: <command>directory mask = 0755</command></para>
+ <para>Example: <command>directory mask = 0775</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DIRECTORYMODE">directory mode (S)</term>
+ <listitem><para>Synonym for <link linkend="DIRECTORYMASK"><parameter>
+ directory mask</parameter></link></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DIRECTORYSECURITYMASK">directory security mask (S)</term>
+ <listitem><para>This parameter controls what UNIX permission bits
+ can be modified when a Windows NT client is manipulating the UNIX
+ permission on a directory using the native NT security dialog
+ box.</para>
+
+ <para>This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits not in
+ this mask from being modified. Essentially, zero bits in this
+ mask may be treated as a set of bits the user is not allowed
+ to change.</para>
+
+ <para>If not set explicitly this parameter is set to 0777
+ meaning a user is allowed to modify all the user/group/world
+ permissions on a directory.</para>
+
+ <para><emphasis>Note</emphasis> that users who can access the
+ Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ it as the default of <constant>0777</constant>.</para>
+
+ <para>See also the <link linkend="FORCEDIRECTORYSECURITYMODE"><parameter>
+ force directory security mode</parameter></link>, <link
+ linkend="SECURITYMASK"><parameter>security mask</parameter></link>,
+ <link linkend="FORCESECURITYMODE"><parameter>force security mode
+ </parameter></link> parameters.</para>
+
+ <para>Default: <command>directory security mask = 0777</command></para>
+ <para>Example: <command>directory security mask = 0700</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DISABLESPOOLSS">disable spoolss (G)</term>
+ <listitem><para>Enabling this parameter will disables Samba's support
+ for the SPOOLSS set of MS-RPC's and will yield identical behavior
+ as Samba 2.0.x. Windows NT/2000 clients will downgrade to using
+ Lanman style printing commands. Windows 9x/ME will be uneffected by
+ the parameter. However, this will also disable the ability to upload
+ printer drivers to a Samba server via the Windows NT Add Printer
+ Wizard or by using the NT printer properties dialog window. It will
+ also disable the capability of Windows NT/2000 clients to download
+ print drivers from the Samba host upon demand.
+ <emphasis>Be very careful about enabling this parameter.</emphasis>
+ </para>
+
+ <para>See also <link linkend="USECLIENTDRIVER">use client driver</link>
+ </para>
+
+ <para>Default : <command>disable spoolss = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DNSPROXY">dns proxy (G)</term>
+ <listitem><para>Specifies that <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ when acting as a WINS server and finding that a NetBIOS name has not
+ been registered, should treat the NetBIOS name word-for-word as a DNS
+ name and do a lookup with the DNS server for that name on behalf of
+ the name-querying client.</para>
+
+ <para>Note that the maximum length for a NetBIOS name is 15
+ characters, so the DNS name (or DNS alias) can likewise only be
+ 15 characters, maximum.</para>
+
+ <para><command>nmbd</command> spawns a second copy of itself to do the
+ DNS name lookup requests, as doing a name lookup is a blocking
+ action.</para>
+
+ <para>See also the parameter <link linkend="WINSSUPPORT"><parameter>
+ wins support</parameter></link>.</para>
+
+ <para>Default: <command>dns proxy = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DOMAINADMINGROUP">domain admin group (G)</term>
+ <listitem><para>This parameter is intended as a temporary solution
+ to enable users to be a member of the "Domain Admins" group when
+ a Samba host is acting as a PDC. A complete solution will be provided
+ by a system for mapping Windows NT/2000 groups onto UNIX groups.
+ Please note that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in standard
+ <filename>smb.conf</filename> notation.
+ </para>
+
+ <para>See also <link linkend="DOMAINGUESTGROUP"><parameter>domain
+ guest group</parameter></link>, <link linkend="DOMAINLOGONS"><parameter>domain
+ logons</parameter></link>
+ </para>
+
+ <para>Default: <emphasis>no domain administrators</emphasis></para>
+ <para>Example: <command>domain admin group = root @wheel</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DOMAINGUESTGROUP">domain guest group (G)</term>
+ <listitem><para>This parameter is intended as a temporary solution
+ to enable users to be a member of the "Domain Guests" group when
+ a Samba host is acting as a PDC. A complete solution will be provided
+ by a system for mapping Windows NT/2000 groups onto UNIX groups.
+ Please note that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in standard
+ <filename>smb.conf</filename> notation.
+ </para>
+
+ <para>See also <link linkend="DOMAINADMINGROUP"><parameter>domain
+ admin group</parameter></link>, <link linkend="DOMAINLOGONS"><parameter>domain
+ logons</parameter></link>
+ </para>
+
+ <para>Default: <emphasis>no domain guests</emphasis></para>
+ <para>Example: <command>domain guest group = nobody @guest</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="DOMAINLOGONS">domain logons (G)</term>
+ <listitem><para>If set to <constant>yes</constant>, the Samba server will serve
+ Windows 95/98 Domain logons for the <link linkend="WORKGROUP">
+ <parameter>workgroup</parameter></link> it is in. Samba 2.2 also
+ has limited capability to act as a domain controller for Windows
+ NT 4 Domains. For more details on setting up this feature see
+ the Samba-PDC-HOWTO included in the <filename>htmldocs/</filename>
+ directory shipped with the source code.</para>
+
+ <para>Default: <command>domain logons = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DOMAINMASTER">domain master (G)</term>
+ <listitem><para>Tell <ulink url="nmbd.8.html"><command>
+ nmbd(8)</command></ulink> to enable WAN-wide browse list
+ collation. Setting this option causes <command>nmbd</command> to
+ claim a special domain specific NetBIOS name that identifies
+ it as a domain master browser for its given <link linkend="WORKGROUP">
+ <parameter>workgroup</parameter></link>. Local master browsers
+ in the same <parameter>workgroup</parameter> on broadcast-isolated
+ subnets will give this <command>nmbd</command> their local browse lists,
+ and then ask <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>
+ for a complete copy of the browse list for the whole wide area
+ network. Browser clients will then contact their local master browser,
+ and will receive the domain-wide browse list, instead of just the list
+ for their broadcast-isolated subnet.</para>
+
+ <para>Note that Windows NT Primary Domain Controllers expect to be
+ able to claim this <parameter>workgroup</parameter> specific special
+ NetBIOS name that identifies them as domain master browsers for
+ that <parameter>workgroup</parameter> by default (i.e. there is no
+ way to prevent a Windows NT PDC from attempting to do this). This
+ means that if this parameter is set and <command>nmbd</command> claims
+ the special name for a <parameter>workgroup</parameter> before a Windows
+ NT PDC is able to do so then cross subnet browsing will behave
+ strangely and may fail.</para>
+
+ <para>If <link linkend="DOMAINLOGONS"><command>domain logons = yes</command>
+ </link>, then the default behavior is to enable the <parameter>domain
+ master</parameter> parameter. If <parameter>domain logons</parameter> is
+ not enabled (the default setting), then neither will <parameter>domain
+ master</parameter> be enabled by default.</para>
+
+ <para>Default: <command>domain master = auto</command></para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="DONTDESCEND">dont descend (S)</term>
+ <listitem><para>There are certain directories on some systems
+ (e.g., the <filename>/proc</filename> tree under Linux) that are either not
+ of interest to clients or are infinitely deep (recursive). This
+ parameter allows you to specify a comma-delimited list of directories
+ that the server should always show as empty.</para>
+
+ <para>Note that Samba can be very fussy about the exact format
+ of the "dont descend" entries. For example you may need <filename>
+ ./proc</filename> instead of just <filename>/proc</filename>.
+ Experimentation is the best policy :-) </para>
+
+ <para>Default: <emphasis>none (i.e., all directories are OK
+ to descend)</emphasis></para>
+ <para>Example: <command>dont descend = /proc,/dev</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DOSFILEMODE">dos filemode (S)</term>
+ <listitem><para> The default behavior in Samba is to provide
+ UNIX-like behavior where only the owner of a file/directory is
+ able to change the permissions on it. However, this behavior
+ is often confusing to DOS/Windows users. Enabling this parameter
+ allows a user who has write access to the file (by whatever
+ means) to modify the permissions on it. Note that a user
+ belonging to the group owning the file will not be allowed to
+ change permissions if the group is only granted read access.
+ Ownership of the file/directory is not changed, only the permissions
+ are modified.</para>
+
+ <para>Default: <command>dos filemode = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DOSFILETIMERESOLUTION">dos filetime resolution (S)</term>
+ <listitem><para>Under the DOS and Windows FAT filesystem, the finest
+ granularity on time resolution is two seconds. Setting this parameter
+ for a share causes Samba to round the reported time down to the
+ nearest two second boundary when a query call that requires one second
+ resolution is made to <ulink url="smbd.8.html"><command>smbd(8)</command>
+ </ulink>.</para>
+
+ <para>This option is mainly used as a compatibility option for Visual
+ C++ when used against Samba shares. If oplocks are enabled on a
+ share, Visual C++ uses two different time reading calls to check if a
+ file has changed since it was last read. One of these calls uses a
+ one-second granularity, the other uses a two second granularity. As
+ the two second call rounds any odd second down, then if the file has a
+ timestamp of an odd number of seconds then the two timestamps will not
+ match and Visual C++ will keep reporting the file has changed. Setting
+ this option causes the two timestamps to match, and Visual C++ is
+ happy.</para>
+
+ <para>Default: <command>dos filetime resolution = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="DOSFILETIMES">dos filetimes (S)</term>
+ <listitem><para>Under DOS and Windows, if a user can write to a
+ file they can change the timestamp on it. Under POSIX semantics,
+ only the owner of the file or root may change the timestamp. By
+ default, Samba runs with POSIX semantics and refuses to change the
+ timestamp on a file if the user <command>smbd</command> is acting
+ on behalf of is not the file owner. Setting this option to <constant>
+ yes</constant> allows DOS semantics and <ulink url="smbd.8.html">smbd</ulink> will change the file
+ timestamp as DOS requires.</para>
+
+ <para>Default: <command>dos filetimes = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ENCRYPTPASSWORDS">encrypt passwords (G)</term>
+ <listitem><para>This boolean controls whether encrypted passwords
+ will be negotiated with the client. Note that Windows NT 4.0 SP3 and
+ above and also Windows 98 will by default expect encrypted passwords
+ unless a registry entry is changed. To use encrypted passwords in
+ Samba see the file ENCRYPTION.txt in the Samba documentation
+ directory <filename>docs/</filename> shipped with the source code.</para>
+
+ <para>In order for encrypted passwords to work correctly
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink> must either
+ have access to a local <ulink url="smbpasswd.5.html"><filename>smbpasswd(5)
+ </filename></ulink> file (see the <ulink url="smbpasswd.8.html"><command>
+ smbpasswd(8)</command></ulink> program for information on how to set up
+ and maintain this file), or set the <link
+ linkend="SECURITY">security = [server|domain]</link> parameter which
+ causes <command>smbd</command> to authenticate against another
+ server.</para>
+
+ <para>Default: <command>encrypt passwords = no</command></para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="ENHANCEDBROWSING">enhanced browsing (G)</term>
+ <listitem><para>This option enables a couple of enhancements to
+ cross-subnet browse propagation that have been added in Samba
+ but which are not standard in Microsoft implementations.
+ </para>
+
+ <para>The first enhancement to browse propagation consists of a regular
+ wildcard query to a Samba WINS server for all Domain Master Browsers,
+ followed by a browse synchronization with each of the returned
+ DMBs. The second enhancement consists of a regular randomised browse
+ synchronization with all currently known DMBs.</para>
+
+ <para>You may wish to disable this option if you have a problem with empty
+ workgroups not disappearing from browse lists. Due to the restrictions
+ of the browse protocols these enhancements can cause a empty workgroup
+ to stay around forever which can be annoying.</para>
+
+ <para>In general you should leave this option enabled as it makes
+ cross-subnet browse propagation much more reliable.</para>
+
+ <para>Default: <command>enhanced browsing = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="ENUMPORTSCOMMAND">enumports command (G)</term>
+ <listitem><para>The concept of a "port" is fairly foreign
+ to UNIX hosts. Under Windows NT/2000 print servers, a port
+ is associated with a port monitor and generally takes the form of
+ a local port (i.e. LPT1:, COM1:, FILE:) or a remote port
+ (i.e. LPD Port Monitor, etc...). By default, Samba has only one
+ port defined--<constant>"Samba Printer Port"</constant>. Under
+ Windows NT/2000, all printers must have a valid port name.
+ If you wish to have a list of ports displayed (<command>smbd
+ </command> does not use a port name for anything) other than
+ the default <constant>"Samba Printer Port"</constant>, you
+ can define <parameter>enumports command</parameter> to point to
+ a program which should generate a list of ports, one per line,
+ to standard output. This listing will then be used in response
+ to the level 1 and 2 EnumPorts() RPC.</para>
+
+ <para>Default: <emphasis>no enumports command</emphasis></para>
+ <para>Example: <command>enumports command = /usr/bin/listports
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="EXEC">exec (S)</term>
+ <listitem><para>This is a synonym for <link linkend="PREEXEC">
+ <parameter>preexec</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FAKEDIRECTORYCREATETIMES">fake directory create times (S)</term>
+ <listitem><para>NTFS and Windows VFAT file systems keep a create
+ time for all files and directories. This is not the same as the
+ ctime - status change time - that Unix keeps, so Samba by default
+ reports the earliest of the various times Unix does keep. Setting
+ this parameter for a share causes Samba to always report midnight
+ 1-1-1980 as the create time for directories.</para>
+
+ <para>This option is mainly used as a compatibility option for
+ Visual C++ when used against Samba shares. Visual C++ generated
+ makefiles have the object directory as a dependency for each object
+ file, and a make rule to create the directory. Also, when NMAKE
+ compares timestamps it uses the creation time when examining a
+ directory. Thus the object directory will be created if it does not
+ exist, but once it does exist it will always have an earlier
+ timestamp than the object files it contains.</para>
+
+ <para>However, Unix time semantics mean that the create time
+ reported by Samba will be updated whenever a file is created or
+ or deleted in the directory. NMAKE finds all object files in
+ the object directory. The timestamp of the last one built is then
+ compared to the timestamp of the object directory. If the
+ directory's timestamp if newer, then all object files
+ will be rebuilt. Enabling this option
+ ensures directories always predate their contents and an NMAKE build
+ will proceed as expected.</para>
+
+ <para>Default: <command>fake directory create times = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FAKEOPLOCKS">fake oplocks (S)</term>
+ <listitem><para>Oplocks are the way that SMB clients get permission
+ from a server to locally cache file operations. If a server grants
+ an oplock (opportunistic lock) then the client is free to assume
+ that it is the only one accessing the file and it will aggressively
+ cache file data. With some oplock types the client may even cache
+ file open/close operations. This can give enormous performance benefits.
+ </para>
+
+ <para>When you set <command>fake oplocks = yes</command>, <ulink
+ url="smbd.8.html"><command>smbd(8)</command></ulink> will
+ always grant oplock requests no matter how many clients are using
+ the file.</para>
+
+ <para>It is generally much better to use the real <link
+ linkend="OPLOCKS"><parameter>oplocks</parameter></link> support rather
+ than this parameter.</para>
+
+ <para>If you enable this option on all read-only shares or
+ shares that you know will only be accessed from one client at a
+ time such as physically read-only media like CDROMs, you will see
+ a big performance improvement on many operations. If you enable
+ this option on shares where multiple clients may be accessing the
+ files read-write at the same time you can get data corruption. Use
+ this option carefully!</para>
+
+ <para>Default: <command>fake oplocks = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FOLLOWSYMLINKS">follow symlinks (S)</term>
+ <listitem><para>This parameter allows the Samba administrator
+ to stop <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>
+ from following symbolic links in a particular share. Setting this
+ parameter to <constant>no</constant> prevents any file or directory
+ that is a symbolic link from being followed (the user will get an
+ error). This option is very useful to stop users from adding a
+ symbolic link to <filename>/etc/passwd</filename> in their home
+ directory for instance. However it will slow filename lookups
+ down slightly.</para>
+
+ <para>This option is enabled (i.e. <command>smbd</command> will
+ follow symbolic links) by default.</para>
+
+ <para>Default: <command>follow symlinks = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCECREATEMODE">force create mode (S)</term>
+ <listitem><para>This parameter specifies a set of UNIX mode bit
+ permissions that will <emphasis>always</emphasis> be set on a
+ file created by Samba. This is done by bitwise 'OR'ing these bits onto
+ the mode bits of a file that is being created or having its
+ permissions changed. The default for this parameter is (in octal)
+ 000. The modes in this parameter are bitwise 'OR'ed onto the file
+ mode after the mask set in the <parameter>create mask</parameter>
+ parameter is applied.</para>
+
+ <para>See also the parameter <link linkend="CREATEMASK"><parameter>create
+ mask</parameter></link> for details on masking mode bits on files.</para>
+
+ <para>See also the <link linkend="INHERITPERMISSIONS"><parameter>inherit
+ permissions</parameter></link> parameter.</para>
+
+ <para>Default: <command>force create mode = 000</command></para>
+ <para>Example: <command>force create mode = 0755</command></para>
+
+ <para>would force all created files to have read and execute
+ permissions set for 'group' and 'other' as well as the
+ read/write/execute bits set for the 'user'.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCEDIRECTORYMODE">force directory mode (S)</term>
+ <listitem><para>This parameter specifies a set of UNIX mode bit
+ permissions that will <emphasis>always</emphasis> be set on a directory
+ created by Samba. This is done by bitwise 'OR'ing these bits onto the
+ mode bits of a directory that is being created. The default for this
+ parameter is (in octal) 0000 which will not add any extra permission
+ bits to a created directory. This operation is done after the mode
+ mask in the parameter <parameter>directory mask</parameter> is
+ applied.</para>
+
+ <para>See also the parameter <link linkend="DIRECTORYMASK"><parameter>
+ directory mask</parameter></link> for details on masking mode bits
+ on created directories.</para>
+
+ <para>See also the <link linkend="INHERITPERMISSIONS"><parameter>
+ inherit permissions</parameter></link> parameter.</para>
+
+ <para>Default: <command>force directory mode = 000</command></para>
+ <para>Example: <command>force directory mode = 0755</command></para>
+
+ <para>would force all created directories to have read and execute
+ permissions set for 'group' and 'other' as well as the
+ read/write/execute bits set for the 'user'.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCEDIRECTORYSECURITYMODE">force directory
+ security mode (S)</term>
+ <listitem><para>This parameter controls what UNIX permission bits
+ can be modified when a Windows NT client is manipulating the UNIX
+ permission on a directory using the native NT security dialog box.</para>
+
+ <para>This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this mask that
+ the user may have modified to be on. Essentially, one bits in this
+ mask may be treated as a set of bits that, when modifying security
+ on a directory, the user has always set to be 'on'.</para>
+
+ <para>If not set explicitly this parameter is 000, which
+ allows a user to modify all the user/group/world permissions on a
+ directory without restrictions.</para>
+
+ <para><emphasis>Note</emphasis> that users who can access the
+ Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ it set as 0000.</para>
+
+ <para>See also the <link linkend="DIRECTORYSECURITYMASK"><parameter>
+ directory security mask</parameter></link>, <link linkend="SECURITYMASK">
+ <parameter>security mask</parameter></link>,
+ <link linkend="FORCESECURITYMODE"><parameter>force security mode
+ </parameter></link> parameters.</para>
+
+ <para>Default: <command>force directory security mode = 0</command></para>
+ <para>Example: <command>force directory security mode = 700</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCEGROUP">force group (S)</term>
+ <listitem><para>This specifies a UNIX group name that will be
+ assigned as the default primary group for all users connecting
+ to this service. This is useful for sharing files by ensuring
+ that all access to files on service will use the named group for
+ their permissions checking. Thus, by assigning permissions for this
+ group to the files and directories within this service the Samba
+ administrator can restrict or allow sharing of these files.</para>
+
+ <para>In Samba 2.0.5 and above this parameter has extended
+ functionality in the following way. If the group name listed here
+ has a '+' character prepended to it then the current user accessing
+ the share only has the primary group default assigned to this group
+ if they are already assigned as a member of that group. This allows
+ an administrator to decide that only users who are already in a
+ particular group will create files with group ownership set to that
+ group. This gives a finer granularity of ownership assignment. For
+ example, the setting <filename>force group = +sys</filename> means
+ that only users who are already in group sys will have their default
+ primary group assigned to sys when accessing this Samba share. All
+ other users will retain their ordinary primary group.</para>
+
+ <para>If the <link linkend="FORCEUSER"><parameter>force user
+ </parameter></link> parameter is also set the group specified in
+ <parameter>force group</parameter> will override the primary group
+ set in <parameter>force user</parameter>.</para>
+
+ <para>See also <link linkend="FORCEUSER"><parameter>force
+ user</parameter></link>.</para>
+
+ <para>Default: <emphasis>no forced group</emphasis></para>
+ <para>Example: <command>force group = agroup</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCESECURITYMODE">force security mode (S)</term>
+ <listitem><para>This parameter controls what UNIX permission
+ bits can be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT security dialog
+ box.</para>
+
+ <para>This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this mask that
+ the user may have modified to be on. Essentially, one bits in this
+ mask may be treated as a set of bits that, when modifying security
+ on a file, the user has always set to be 'on'.</para>
+
+ <para>If not set explicitly this parameter is set to 0,
+ and allows a user to modify all the user/group/world permissions on a file,
+ with no restrictions.</para>
+
+ <para><emphasis>Note</emphasis> that users who can access
+ the Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ this set to 0000.</para>
+
+ <para>See also the <link linkend="FORCEDIRECTORYSECURITYMODE"><parameter>
+ force directory security mode</parameter></link>,
+ <link linkend="DIRECTORYSECURITYMASK"><parameter>directory security
+ mask</parameter></link>, <link linkend="SECURITYMASK"><parameter>
+ security mask</parameter></link> parameters.</para>
+
+ <para>Default: <command>force security mode = 0</command></para>
+ <para>Example: <command>force security mode = 700</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCEUNKNOWNACLUSER">force unknown acl user (S)</term>
+ <listitem><para>If this parameter is set, a Windows NT ACL that contains
+ an unknown SID (security descriptor, or representation of a user or group id)
+ as the owner or group owner of the file will be silently mapped into the
+ current UNIX uid or gid of the currently connected user.</para>
+
+ <para>This is designed to allow Windows NT clients to copy files and
+ folders containing ACLs that were created locally on the client machine
+ and contain users local to that machine only (no domain users) to be
+ copied to a Samba server (usually with XCOPY /O) and have the unknown
+ userid and groupid of the file owner map to the current connected user.
+ This can only be fixed correctly when winbindd allows arbitrary mapping
+ from any Windows NT SID to a UNIX uid or gid.</para>
+
+ <para>Try using this parameter when XCOPY /O gives an ACCESS_DENIED error.
+ </para>
+
+ <para>See also <link linkend="FORCEGROUP"><parameter>force group
+ </parameter></link></para>
+
+ <para>Default: <emphasis>False</emphasis></para>
+ <para>Example: <command>force unknown acl user = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FORCEUSER">force user (S)</term>
+ <listitem><para>This specifies a UNIX user name that will be
+ assigned as the default user for all users connecting to this service.
+ This is useful for sharing files. You should also use it carefully
+ as using it incorrectly can cause security problems.</para>
+
+ <para>This user name only gets used once a connection is established.
+ Thus clients still need to connect as a valid user and supply a
+ valid password. Once connected, all file operations will be performed
+ as the "forced user", no matter what username the client connected
+ as. This can be very useful.</para>
+
+ <para>In Samba 2.0.5 and above this parameter also causes the
+ primary group of the forced user to be used as the primary group
+ for all file activity. Prior to 2.0.5 the primary group was left
+ as the primary group of the connecting user (this was a bug).</para>
+
+ <para>See also <link linkend="FORCEGROUP"><parameter>force group
+ </parameter></link></para>
+
+ <para>Default: <emphasis>no forced user</emphasis></para>
+ <para>Example: <command>force user = auser</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="FSTYPE">fstype (S)</term>
+ <listitem><para>This parameter allows the administrator to
+ configure the string that specifies the type of filesystem a share
+ is using that is reported by <ulink url="smbd.8.html"><command>smbd(8)
+ </command></ulink> when a client queries the filesystem type
+ for a share. The default type is <constant>NTFS</constant> for
+ compatibility with Windows NT but this can be changed to other
+ strings such as <constant>Samba</constant> or <constant>FAT
+ </constant> if required.</para>
+
+ <para>Default: <command>fstype = NTFS</command></para>
+ <para>Example: <command>fstype = Samba</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="GETWDCACHE">getwd cache (G)</term>
+ <listitem><para>This is a tuning option. When this is enabled a
+ caching algorithm will be used to reduce the time taken for getwd()
+ calls. This can have a significant impact on performance, especially
+ when the <link linkend="WIDELINKS"><parameter>wide links</parameter>
+ </link>parameter is set to <constant>no</constant>.</para>
+
+ <para>Default: <command>getwd cache = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="GROUP">group (S)</term>
+ <listitem><para>Synonym for <link linkend="FORCEGROUP"><parameter>force
+ group</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="GUESTACCOUNT">guest account (S)</term>
+ <listitem><para>This is a username which will be used for access
+ to services which are specified as <link linkend="GUESTOK"><parameter>
+ guest ok</parameter></link> (see below). Whatever privileges this
+ user has will be available to any client connecting to the guest service.
+ Typically this user will exist in the password file, but will not
+ have a valid login. The user account "ftp" is often a good choice
+ for this parameter. If a username is specified in a given service,
+ the specified username overrides this one.</para>
+
+ <para>One some systems the default guest account "nobody" may not
+ be able to print. Use another account in this case. You should test
+ this by trying to log in as your guest user (perhaps by using the
+ <command>su -</command> command) and trying to print using the
+ system print command such as <command>lpr(1)</command> or <command>
+ lp(1)</command>.</para>
+
+ <para>Default: <emphasis>specified at compile time, usually
+ "nobody"</emphasis></para>
+
+ <para>Example: <command>guest account = ftp</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="GUESTOK">guest ok (S)</term>
+ <listitem><para>If this parameter is <constant>yes</constant> for
+ a service, then no password is required to connect to the service.
+ Privileges will be those of the <link linkend="GUESTACCOUNT"><parameter>
+ guest account</parameter></link>.</para>
+
+ <para>See the section below on <link linkend="SECURITY"><parameter>
+ security</parameter></link> for more information about this option.
+ </para>
+
+ <para>Default: <command>guest ok = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="GUESTONLY">guest only (S)</term>
+ <listitem><para>If this parameter is <constant>yes</constant> for
+ a service, then only guest connections to the service are permitted.
+ This parameter will have no effect if <link linkend="GUESTOK">
+ <parameter>guest ok</parameter></link> is not set for the service.</para>
+
+ <para>See the section below on <link linkend="SECURITY"><parameter>
+ security</parameter></link> for more information about this option.
+ </para>
+
+ <para>Default: <command>guest only = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HIDEDOTFILES">hide dot files (S)</term>
+ <listitem><para>This is a boolean parameter that controls whether
+ files starting with a dot appear as hidden files.</para>
+
+ <para>Default: <command>hide dot files = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HIDEFILES">hide files(S)</term>
+ <listitem><para>This is a list of files or directories that are not
+ visible but are accessible. The DOS 'hidden' attribute is applied
+ to any files or directories that match.</para>
+
+ <para>Each entry in the list must be separated by a '/',
+ which allows spaces to be included in the entry. '*'
+ and '?' can be used to specify multiple files or directories
+ as in DOS wildcards.</para>
+
+ <para>Each entry must be a Unix path, not a DOS path and must
+ not include the Unix directory separator '/'.</para>
+
+ <para>Note that the case sensitivity option is applicable
+ in hiding files.</para>
+
+ <para>Setting this parameter will affect the performance of Samba,
+ as it will be forced to check all files and directories for a match
+ as they are scanned.</para>
+
+ <para>See also <link linkend="HIDEDOTFILES"><parameter>hide
+ dot files</parameter></link>, <link linkend="VETOFILES"><parameter>
+ veto files</parameter></link> and <link linkend="CASESENSITIVE">
+ <parameter>case sensitive</parameter></link>.</para>
+
+ <para>Default: <emphasis>no file are hidden</emphasis></para>
+ <para>Example: <command>hide files =
+ /.*/DesktopFolderDB/TrashFor%m/resource.frk/</command></para>
+
+ <para>The above example is based on files that the Macintosh
+ SMB client (DAVE) available from <ulink url="http://www.thursby.com">
+ Thursby</ulink> creates for internal use, and also still hides
+ all files beginning with a dot.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HIDELOCALUSERS">hide local users(G)</term>
+ <listitem><para>This parameter toggles the hiding of local UNIX
+ users (root, wheel, floppy, etc) from remote clients.</para>
+
+ <para>Default: <command>hide local users = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HIDEUNREADABLE">hide unreadable (S)</term>
+ <listitem><para>This parameter prevents clients from seeing the
+ existance of files that cannot be read. Defaults to off.</para>
+
+ <para>Default: <command>hide unreadable = no</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HOMEDIRMAP">homedir map (G)</term>
+ <listitem><para>If<link linkend="NISHOMEDIR"><parameter>nis homedir
+ </parameter></link> is <constant>yes</constant>, and <ulink
+ url="smbd.8.html"><command>smbd(8)</command></ulink> is also acting
+ as a Win95/98 <parameter>logon server</parameter> then this parameter
+ specifies the NIS (or YP) map from which the server for the user's
+ home directory should be extracted. At present, only the Sun
+ auto.home map format is understood. The form of the map is:</para>
+
+ <para><command>username server:/some/file/system</command></para>
+
+ <para>and the program will extract the servername from before
+ the first ':'. There should probably be a better parsing system
+ that copes with different map formats and also Amd (another
+ automounter) maps.</para>
+
+ <para><emphasis>NOTE :</emphasis>A working NIS client is required on
+ the system for this option to work.</para>
+
+ <para>See also <link linkend="NISHOMEDIR"><parameter>nis homedir</parameter>
+ </link>, <link linkend="DOMAINLOGONS"><parameter>domain logons</parameter>
+ </link>.</para>
+
+ <para>Default: <command>homedir map = &lt;empty string&gt;</command></para>
+ <para>Example: <command>homedir map = amd.homedir</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="HOSTMSDFS">host msdfs (G)</term>
+ <listitem><para>This boolean parameter is only available
+ if Samba has been configured and compiled with the <command>
+ --with-msdfs</command> option. If set to <constant>yes</constant>,
+ Samba will act as a Dfs server, and allow Dfs-aware clients
+ to browse Dfs trees hosted on the server.</para>
+
+ <para>See also the <link linkend="MSDFSROOT"><parameter>
+ msdfs root</parameter></link> share level parameter. For
+ more information on setting up a Dfs tree on Samba,
+ refer to <ulink url="msdfs_setup.html">msdfs_setup.html</ulink>.
+ </para>
+
+ <para>Default: <command>host msdfs = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="HOSTSALLOW">hosts allow (S)</term>
+ <listitem><para>A synonym for this parameter is <parameter>allow
+ hosts</parameter>.</para>
+
+ <para>This parameter is a comma, space, or tab delimited
+ set of hosts which are permitted to access a service.</para>
+
+ <para>If specified in the [global] section then it will
+ apply to all services, regardless of whether the individual
+ service has a different setting.</para>
+
+ <para>You can specify the hosts by name or IP number. For
+ example, you could restrict access to only the hosts on a
+ Class C subnet with something like <command>allow hosts = 150.203.5.
+ </command>. The full syntax of the list is described in the man
+ page <filename>hosts_access(5)</filename>. Note that this man
+ page may not be present on your system, so a brief description will
+ be given here also.</para>
+
+ <para>Note that the localhost address 127.0.0.1 will always
+ be allowed access unless specifically denied by a <link
+ linkend="HOSTSDENY"><parameter>hosts deny</parameter></link> option.</para>
+
+ <para>You can also specify hosts by network/netmask pairs and
+ by netgroup names if your system supports netgroups. The
+ <emphasis>EXCEPT</emphasis> keyword can also be used to limit a
+ wildcard list. The following examples may provide some help:</para>
+
+ <para>Example 1: allow all IPs in 150.203.*.*; except one</para>
+
+ <para><command>hosts allow = 150.203. EXCEPT 150.203.6.66</command></para>
+
+ <para>Example 2: allow hosts that match the given network/netmask</para>
+
+ <para><command>hosts allow = 150.203.15.0/255.255.255.0</command></para>
+
+ <para>Example 3: allow a couple of hosts</para>
+
+ <para><command>hosts allow = lapland, arvidsjaur</command></para>
+
+ <para>Example 4: allow only hosts in NIS netgroup "foonet", but
+ deny access from one particular host</para>
+
+ <para><command>hosts allow = @foonet</command></para>
+
+ <para><command>hosts deny = pirate</command></para>
+
+ <para>Note that access still requires suitable user-level passwords.</para>
+
+ <para>See <ulink url="testparm.1.html"><command>testparm(1)</command>
+ </ulink> for a way of testing your host access to see if it does
+ what you expect.</para>
+
+ <para>Default: <emphasis>none (i.e., all hosts permitted access)
+ </emphasis></para>
+
+ <para>Example: <command>allow hosts = 150.203.5. myhost.mynet.edu.au
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HOSTSDENY">hosts deny (S)</term>
+ <listitem><para>The opposite of <parameter>hosts allow</parameter>
+ - hosts listed here are <emphasis>NOT</emphasis> permitted access to
+ services unless the specific services have their own lists to override
+ this one. Where the lists conflict, the <parameter>allow</parameter>
+ list takes precedence.</para>
+
+ <para>Default: <emphasis>none (i.e., no hosts specifically excluded)
+ </emphasis></para>
+
+ <para>Example: <command>hosts deny = 150.203.4. badhost.mynet.edu.au
+ </command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="HOSTSEQUIV">hosts equiv (G)</term>
+ <listitem><para>If this global parameter is a non-null string,
+ it specifies the name of a file to read for the names of hosts
+ and users who will be allowed access without specifying a password.
+ </para>
+
+ <para>This is not be confused with <link linkend="HOSTSALLOW">
+ <parameter>hosts allow</parameter></link> which is about hosts
+ access to services and is more useful for guest services. <parameter>
+ hosts equiv</parameter> may be useful for NT clients which will
+ not supply passwords to Samba.</para>
+
+ <para><emphasis>NOTE :</emphasis> The use of <parameter>hosts equiv
+ </parameter> can be a major security hole. This is because you are
+ trusting the PC to supply the correct username. It is very easy to
+ get a PC to supply a false username. I recommend that the
+ <parameter>hosts equiv</parameter> option be only used if you really
+ know what you are doing, or perhaps on a home network where you trust
+ your spouse and kids. And only if you <emphasis>really</emphasis> trust
+ them :-).</para>
+
+ <para>Default: <emphasis>no host equivalences</emphasis></para>
+ <para>Example: <command>hosts equiv = /etc/hosts.equiv</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="INCLUDE">include (G)</term>
+ <listitem><para>This allows you to include one config file
+ inside another. The file is included literally, as though typed
+ in place.</para>
+
+ <para>It takes the standard substitutions, except <parameter>%u
+ </parameter>, <parameter>%P</parameter> and <parameter>%S</parameter>.
+ </para>
+
+ <para>Default: <emphasis>no file included</emphasis></para>
+ <para>Example: <command>include = /usr/local/samba/lib/admin_smb.conf
+ </command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="INHERITACLS">inherit acls (S)</term>
+ <listitem><para>This parameter can be used to ensure
+ that if default acls exist on parent directories,
+ they are always honored when creating a subdirectory.
+ The default behavior is to use the mode specified
+ when creating the directory. Enabling this option
+ sets the mode to 0777, thus guaranteeing that
+ default directory acls are propagated.
+ </para>
+
+ <para>Default: <command>inherit acls = no</command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="INHERITPERMISSIONS">inherit permissions (S)</term>
+ <listitem><para>The permissions on new files and directories
+ are normally governed by <link linkend="CREATEMASK"><parameter>
+ create mask</parameter></link>, <link linkend="DIRECTORYMASK">
+ <parameter>directory mask</parameter></link>, <link
+ linkend="FORCECREATEMODE"><parameter>force create mode</parameter>
+ </link> and <link linkend="FORCEDIRECTORYMODE"><parameter>force
+ directory mode</parameter></link> but the boolean inherit
+ permissions parameter overrides this.</para>
+
+ <para>New directories inherit the mode of the parent directory,
+ including bits such as setgid.</para>
+
+ <para>New files inherit their read/write bits from the parent
+ directory. Their execute bits continue to be determined by
+ <link linkend="MAPARCHIVE"><parameter>map archive</parameter>
+ </link>, <link linkend="MAPHIDDEN"><parameter>map hidden</parameter>
+ </link> and <link linkend="MAPSYSTEM"><parameter>map system</parameter>
+ </link> as usual.</para>
+
+ <para>Note that the setuid bit is <emphasis>never</emphasis> set via
+ inheritance (the code explicitly prohibits this).</para>
+
+ <para>This can be particularly useful on large systems with
+ many users, perhaps several thousand, to allow a single [homes]
+ share to be used flexibly by each user.</para>
+
+ <para>See also <link linkend="CREATEMASK"><parameter>create mask
+ </parameter></link>, <link linkend="DIRECTORYMASK"><parameter>
+ directory mask</parameter></link>, <link linkend="FORCECREATEMODE">
+ <parameter>force create mode</parameter></link> and <link
+ linkend="FORCEDIRECTORYMODE"><parameter>force directory mode</parameter>
+ </link>.</para>
+
+ <para>Default: <command>inherit permissions = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="INTERFACES">interfaces (G)</term>
+ <listitem><para>This option allows you to override the default
+ network interfaces list that Samba will use for browsing, name
+ registration and other NBT traffic. By default Samba will query
+ the kernel for the list of all active interfaces and use any
+ interfaces except 127.0.0.1 that are broadcast capable.</para>
+
+ <para>The option takes a list of interface strings. Each string
+ can be in any of the following forms:</para>
+
+ <itemizedlist>
+ <listitem><para>a network interface name (such as eth0).
+ This may include shell-like wildcards so eth* will match
+ any interface starting with the substring "eth"</para></listitem>
+
+ <listitem><para>an IP address. In this case the netmask is
+ determined from the list of interfaces obtained from the
+ kernel</para></listitem>
+
+ <listitem><para>an IP/mask pair. </para></listitem>
+
+ <listitem><para>a broadcast/mask pair.</para></listitem>
+ </itemizedlist>
+
+ <para>The "mask" parameters can either be a bit length (such
+ as 24 for a C class network) or a full netmask in dotted
+ decimal form.</para>
+
+ <para>The "IP" parameters above can either be a full dotted
+ decimal IP address or a hostname which will be looked up via
+ the OS's normal hostname resolution mechanisms.</para>
+
+ <para>For example, the following line:</para>
+
+ <para><command>interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0
+ </command></para>
+
+ <para>would configure three network interfaces corresponding
+ to the eth0 device and IP addresses 192.168.2.10 and 192.168.3.10.
+ The netmasks of the latter two interfaces would be set to 255.255.255.0.</para>
+
+ <para>See also <link linkend="BINDINTERFACESONLY"><parameter>bind
+ interfaces only</parameter></link>.</para>
+
+ <para>Default: <emphasis>all active interfaces except 127.0.0.1
+ that are broadcast capable</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="INVALIDUSERS">invalid users (S)</term>
+ <listitem><para>This is a list of users that should not be allowed
+ to login to this service. This is really a <emphasis>paranoid</emphasis>
+ check to absolutely ensure an improper setting does not breach
+ your security.</para>
+
+ <para>A name starting with a '@' is interpreted as an NIS
+ netgroup first (if your system supports NIS), and then as a UNIX
+ group if the name was not found in the NIS netgroup database.</para>
+
+ <para>A name starting with '+' is interpreted only
+ by looking in the UNIX group database. A name starting with
+ '&' is interpreted only by looking in the NIS netgroup database
+ (this requires NIS to be working on your system). The characters
+ '+' and '&' may be used at the start of the name in either order
+ so the value <parameter>+&amp;group</parameter> means check the
+ UNIX group database, followed by the NIS netgroup database, and
+ the value <parameter>&+group</parameter> means check the NIS
+ netgroup database, followed by the UNIX group database (the
+ same as the '@' prefix).</para>
+
+ <para>The current servicename is substituted for <parameter>%S</parameter>.
+ This is useful in the [homes] section.</para>
+
+ <para>See also <link linkend="VALIDUSERS"><parameter>valid users
+ </parameter></link>.</para>
+
+ <para>Default: <emphasis>no invalid users</emphasis></para>
+ <para>Example: <command>invalid users = root fred admin @wheel
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="KEEPALIVE">keepalive (G)</term>
+ <listitem><para>The value of the parameter (an integer) represents
+ the number of seconds between <parameter>keepalive</parameter>
+ packets. If this parameter is zero, no keepalive packets will be
+ sent. Keepalive packets, if sent, allow the server to tell whether
+ a client is still present and responding.</para>
+
+ <para>Keepalives should, in general, not be needed if the socket
+ being used has the SO_KEEPALIVE attribute set on it (see <link
+ linkend="SOCKETOPTIONS"><parameter>socket options</parameter></link>).
+ Basically you should only use this option if you strike difficulties.</para>
+
+ <para>Default: <command>keepalive = 300</command></para>
+ <para>Example: <command>keepalive = 600</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="KERNELOPLOCKS">kernel oplocks (G)</term>
+ <listitem><para>For UNIXes that support kernel based <link
+ linkend="OPLOCKS"><parameter>oplocks</parameter></link>
+ (currently only IRIX and the Linux 2.4 kernel), this parameter
+ allows the use of them to be turned on or off.</para>
+
+ <para>Kernel oplocks support allows Samba <parameter>oplocks
+ </parameter> to be broken whenever a local UNIX process or NFS operation
+ accesses a file that <ulink url="smbd.8.html"><command>smbd(8)</command>
+ </ulink> has oplocked. This allows complete data consistency between
+ SMB/CIFS, NFS and local file access (and is a <emphasis>very</emphasis>
+ cool feature :-).</para>
+
+ <para>This parameter defaults to <constant>on</constant>, but is translated
+ to a no-op on systems that no not have the necessary kernel support.
+ You should never need to touch this parameter.</para>
+
+ <para>See also the <link linkend="OPLOCKS"><parameter>oplocks</parameter>
+ </link> and <link linkend="LEVEL2OPLOCKS"><parameter>level2 oplocks
+ </parameter></link> parameters.</para>
+
+ <para>Default: <command>kernel oplocks = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LANMANAUTH">lanman auth (G)</term>
+ <listitem><para>This parameter determines whether or not <ulink url="smbd.8.html">smbd</ulink> will
+ attempt to authenticate users using the LANMAN password hash.
+ If disabled, only clients which support NT password hashes (e.g. Windows
+ NT/2000 clients, smbclient, etc... but not Windows 95/98 or the MS DOS
+ network client) will be able to connect to the Samba host.</para>
+
+ <para>Default : <command>lanman auth = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LARGEREADWRITE">large readwrite (G)</term>
+ <listitem><para>This parameter determines whether or not <ulink url="smbd.8.html">smbd</ulink>
+ supports the new 64k streaming read and write varient SMB requests introduced
+ with Windows 2000. Note that due to Windows 2000 client redirector bugs
+ this requires Samba to be running on a 64-bit capable operating system such
+ as IRIX, Solaris or a Linux 2.4 kernel. Can improve performance by 10% with
+ Windows 2000 clients. Defaults to on. Windows NT 4.0 only supports
+ read version of this call, and ignores the write version.
+ </para>
+
+ <para>Default : <command>large readwrite = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPADMINDN">ldap admin dn (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+ <para>
+ The <parameter>ldap admin dn</parameter> defines the Distinguished
+ Name (DN) name used by Samba to contact the <link linkend="LDAPSERVER">ldap
+ server</link> when retreiving user account information. The <parameter>ldap
+ admin dn</parameter> is used in conjunction with the admin dn password
+ stored in the <filename>private/secrets.tdb</filename> file. See the
+ <ulink url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink> man
+ page for more information on how to accmplish this.
+ </para>
+
+
+ <para>Default : <emphasis>none</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPFILTER">ldap filter (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+ <para>
+ This parameter specifies the RFC 2254 compliant LDAP search filter.
+ The default is to match the login name with the <constant>uid</constant>
+ attribute for all entries matching the <constant>sambaAccount</constant>
+ objectclass. Note that this filter should only return one entry.
+ </para>
+
+
+ <para>Default : <command>ldap filter = (&(uid=%u)(objectclass=sambaAccount))</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPPORT">ldap port (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+ <para>
+ This option is used to control the tcp port number used to contact
+ the <link linkend="LDAPSERVER"><parameter>ldap server</parameter></link>.
+ The default is to use the stand LDAPS port 636.
+ </para>
+
+ <para>See Also: <link linkend="LDAPSSL">ldap ssl</link>
+ </para>
+
+ <para>Default : <command>ldap port = 636 ; if ldap ssl = on</command></para>
+ <para>Default : <command>ldap port = 389 ; if ldap ssl = off</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPSERVER">ldap server (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+ <para>
+ This parameter should contains the FQDN of the ldap directory
+ server which should be queried to locate user account information.
+ </para>
+
+
+
+ <para>Default : <command>ldap server = localhost</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPSSL">ldap ssl (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+ <para>
+ This option is used to define whether or not Samba should
+ use SSL when connecting to the <link linkend="LDAPSERVER"><parameter>ldap
+ server</parameter></link>. This is <emphasis>NOT</emphasis> related to
+ Samba SSL support which is enabled by specifying the
+ <command>--with-ssl</command> option to the <filename>configure</filename>
+ script (see <link linkend="SSL"><parameter>ssl</parameter></link>).
+ </para>
+
+ <para>
+ The <parameter>ldap ssl</parameter> can be set to one of three values:
+ (a) <constant>on</constant> - Always use SSL when contacting the
+ <parameter>ldap server</parameter>, (b) <constant>off</constant> -
+ Never use SSL when querying the directory, or (c) <constant>start_tls</constant>
+ - Use the LDAPv3 StartTLS extended operation
+ (RFC2830) for communicating with the directory server.
+ </para>
+
+
+ <para>Default : <command>ldap ssl = on</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LDAPSUFFIX">ldap suffix (G)</term>
+ <listitem><para>This parameter is only available if Samba has been
+ configure to include the <command>--with-ldapsam</command> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </para>
+
+
+
+ <para>Default : <emphasis>none</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LEVEL2OPLOCKS">level2 oplocks (S)</term>
+ <listitem><para>This parameter controls whether Samba supports
+ level2 (read-only) oplocks on a share.</para>
+
+ <para>Level2, or read-only oplocks allow Windows NT clients
+ that have an oplock on a file to downgrade from a read-write oplock
+ to a read-only oplock once a second client opens the file (instead
+ of releasing all oplocks on a second open, as in traditional,
+ exclusive oplocks). This allows all openers of the file that
+ support level2 oplocks to cache the file for read-ahead only (ie.
+ they may not cache writes or lock requests) and increases performance
+ for many accesses of files that are not commonly written (such as
+ application .EXE files).</para>
+
+ <para>Once one of the clients which have a read-only oplock
+ writes to the file all clients are notified (no reply is needed
+ or waited for) and told to break their oplocks to "none" and
+ delete any read-ahead caches.</para>
+
+ <para>It is recommended that this parameter be turned on
+ to speed access to shared executables.</para>
+
+ <para>For more discussions on level2 oplocks see the CIFS spec.</para>
+
+ <para>Currently, if <link linkend="KERNELOPLOCKS"><parameter>kernel
+ oplocks</parameter></link> are supported then level2 oplocks are
+ not granted (even if this parameter is set to <constant>yes</constant>).
+ Note also, the <link linkend="OPLOCKS"><parameter>oplocks</parameter>
+ </link> parameter must be set to <constant>yes</constant> on this share in order for
+ this parameter to have any effect.</para>
+
+ <para>See also the <link linkend="OPLOCKS"><parameter>oplocks</parameter>
+ </link> and <link linkend="OPLOCKS"><parameter>kernel oplocks</parameter>
+ </link> parameters.</para>
+
+ <para>Default: <command>level2 oplocks = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LMANNOUNCE">lm announce (G)</term>
+ <listitem><para>This parameter determines if <ulink url="nmbd.8.html">
+ <command>nmbd(8)</command></ulink> will produce Lanman announce
+ broadcasts that are needed by OS/2 clients in order for them to see
+ the Samba server in their browse list. This parameter can have three
+ values, <constant>yes</constant>, <constant>no</constant>, or
+ <constant>auto</constant>. The default is <constant>auto</constant>.
+ If set to <constant>no</constant> Samba will never produce these
+ broadcasts. If set to <constant>yes</constant> Samba will produce
+ Lanman announce broadcasts at a frequency set by the parameter
+ <parameter>lm interval</parameter>. If set to <constant>auto</constant>
+ Samba will not send Lanman announce broadcasts by default but will
+ listen for them. If it hears such a broadcast on the wire it will
+ then start sending them at a frequency set by the parameter
+ <parameter>lm interval</parameter>.</para>
+
+ <para>See also <link linkend="LMINTERVAL"><parameter>lm interval
+ </parameter></link>.</para>
+
+ <para>Default: <command>lm announce = auto</command></para>
+ <para>Example: <command>lm announce = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LMINTERVAL">lm interval (G)</term>
+ <listitem><para>If Samba is set to produce Lanman announce
+ broadcasts needed by OS/2 clients (see the <link linkend="LMANNOUNCE">
+ <parameter>lm announce</parameter></link> parameter) then this
+ parameter defines the frequency in seconds with which they will be
+ made. If this is set to zero then no Lanman announcements will be
+ made despite the setting of the <parameter>lm announce</parameter>
+ parameter.</para>
+
+ <para>See also <link linkend="LMANNOUNCE"><parameter>lm
+ announce</parameter></link>.</para>
+
+ <para>Default: <command>lm interval = 60</command></para>
+ <para>Example: <command>lm interval = 120</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOADPRINTERS">load printers (G)</term>
+ <listitem><para>A boolean variable that controls whether all
+ printers in the printcap will be loaded for browsing by default.
+ See the <link linkend="PRINTERSSECT">printers</link> section for
+ more details.</para>
+
+ <para>Default: <command>load printers = yes</command></para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCALMASTER">local master (G)</term>
+ <listitem><para>This option allows <ulink url="nmbd.8.html"><command>
+ nmbd(8)</command></ulink> to try and become a local master browser
+ on a subnet. If set to <constant>no</constant> then <command>
+ nmbd</command> will not attempt to become a local master browser
+ on a subnet and will also lose in all browsing elections. By
+ default this value is set to <constant>yes</constant>. Setting this value to <constant>yes</constant> doesn't
+ mean that Samba will <emphasis>become</emphasis> the local master
+ browser on a subnet, just that <command>nmbd</command> will <emphasis>
+ participate</emphasis> in elections for local master browser.</para>
+
+ <para>Setting this value to <constant>no</constant> will cause <command>nmbd</command>
+ <emphasis>never</emphasis> to become a local master browser.</para>
+
+ <para>Default: <command>local master = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCKDIR">lock dir (G)</term>
+ <listitem><para>Synonym for <link linkend="LOCKDIRECTORY"><parameter>
+ lock directory</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCKDIRECTORY">lock directory (G)</term>
+ <listitem><para>This option specifies the directory where lock
+ files will be placed. The lock files are used to implement the
+ <link linkend="MAXCONNECTIONS"><parameter>max connections</parameter>
+ </link> option.</para>
+
+ <para>Default: <command>lock directory = ${prefix}/var/locks</command></para>
+ <para>Example: <command>lock directory = /var/run/samba/locks</command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCKSPINCOUNT">lock spin count (G)</term>
+ <listitem><para>This parameter controls the number of times
+ that smbd should attempt to gain a byte range lock on the
+ behalf of a client request. Experiments have shown that
+ Windows 2k servers do not reply with a failure if the lock
+ could not be immediately granted, but try a few more times
+ in case the lock could later be aquired. This behavior
+ is used to support PC database formats such as MS Access
+ and FoxPro.
+ </para>
+
+ <para>Default: <command>lock spin count = 2</command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCKSPINTIME">lock spin time (G)</term>
+ <listitem><para>The time in microseconds that smbd should
+ pause before attempting to gain a failed lock. See
+ <link linkend="LOCKSPINCOUNT"><parameter>lock spin
+ count</parameter></link> for more details.
+ </para>
+
+ <para>Default: <command>lock spin time = 10</command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOCKING">locking (S)</term>
+ <listitem><para>This controls whether or not locking will be
+ performed by the server in response to lock requests from the
+ client.</para>
+
+ <para>If <command>locking = no</command>, all lock and unlock
+ requests will appear to succeed and all lock queries will report
+ that the file in question is available for locking.</para>
+
+ <para>If <command>locking = yes</command>, real locking will be performed
+ by the server.</para>
+
+ <para>This option <emphasis>may</emphasis> be useful for read-only
+ filesystems which <emphasis>may</emphasis> not need locking (such as
+ CDROM drives), although setting this parameter of <constant>no</constant>
+ is not really recommended even in this case.</para>
+
+ <para>Be careful about disabling locking either globally or in a
+ specific service, as lack of locking may result in data corruption.
+ You should never need to set this parameter.</para>
+
+ <para>Default: <command>locking = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOGFILE">log file (G)</term>
+ <listitem><para>This option allows you to override the name
+ of the Samba log file (also known as the debug file).</para>
+
+ <para>This option takes the standard substitutions, allowing
+ you to have separate log files for each user or machine.</para>
+
+ <para>Example: <command>log file = /usr/local/samba/var/log.%m
+ </command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOGLEVEL">log level (G)</term>
+ <listitem><para>The value of the parameter (an integer) allows
+ the debug level (logging level) to be specified in the
+ <filename>smb.conf</filename> file. This is to give greater
+ flexibility in the configuration of the system.</para>
+
+ <para>The default will be the log level specified on
+ the command line or level zero if none was specified.</para>
+
+ <para>Example: <command>log level = 3</command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOGONDRIVE">logon drive (G)</term>
+ <listitem><para>This parameter specifies the local path to
+ which the home directory will be connected (see <link
+ linkend="LOGONHOME"><parameter>logon home</parameter></link>)
+ and is only used by NT Workstations. </para>
+
+ <para>Note that this option is only useful if Samba is set up as a
+ logon server.</para>
+
+ <para>Default: <command>logon drive = z:</command></para>
+ <para>Example: <command>logon drive = h:</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOGONHOME">logon home (G)</term>
+ <listitem><para>This parameter specifies the home directory
+ location when a Win95/98 or NT Workstation logs into a Samba PDC.
+ It allows you to do </para>
+
+ <para><prompt>C:\> </prompt><userinput>NET USE H: /HOME</userinput>
+ </para>
+
+ <para>from a command prompt, for example.</para>
+
+ <para>This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or machine.</para>
+
+ <para>This parameter can be used with Win9X workstations to ensure
+ that roaming profiles are stored in a subdirectory of the user's
+ home directory. This is done in the following way:</para>
+
+ <para><command>logon home = \\%N\%U\profile</command></para>
+
+ <para>This tells Samba to return the above string, with
+ substitutions made when a client requests the info, generally
+ in a NetUserGetInfo request. Win9X clients truncate the info to
+ \\server\share when a user does <command>net use /home</command>
+ but use the whole string when dealing with profiles.</para>
+
+ <para>Note that in prior versions of Samba, the <link linkend="LOGONPATH">
+ <parameter>logon path</parameter></link> was returned rather than
+ <parameter>logon home</parameter>. This broke <command>net use
+ /home</command> but allowed profiles outside the home directory.
+ The current implementation is correct, and can be used for
+ profiles if you use the above trick.</para>
+
+ <para>This option is only useful if Samba is set up as a logon
+ server.</para>
+
+ <para>Default: <command>logon home = "\\%N\%U"</command></para>
+ <para>Example: <command>logon home = "\\remote_smb_server\%U"</command>
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="LOGONPATH">logon path (G)</term>
+ <listitem><para>This parameter specifies the home directory
+ where roaming profiles (NTuser.dat etc files for Windows NT) are
+ stored. Contrary to previous versions of these manual pages, it has
+ nothing to do with Win 9X roaming profiles. To find out how to
+ handle roaming profiles for Win 9X system, see the <link linkend="LOGONHOME">
+ <parameter>logon home</parameter></link> parameter.</para>
+
+ <para>This option takes the standard substitutions, allowing you
+ to have separate logon scripts for each user or machine. It also
+ specifies the directory from which the "Application Data",
+ (<filename>desktop</filename>, <filename>start menu</filename>,
+ <filename>network neighborhood</filename>, <filename>programs</filename>
+ and other folders, and their contents, are loaded and displayed on
+ your Windows NT client.</para>
+
+ <para>The share and the path must be readable by the user for
+ the preferences and directories to be loaded onto the Windows NT
+ client. The share must be writeable when the user logs in for the first
+ time, in order that the Windows NT client can create the NTuser.dat
+ and other directories.</para>
+
+ <para>Thereafter, the directories and any of the contents can,
+ if required, be made read-only. It is not advisable that the
+ NTuser.dat file be made read-only - rename it to NTuser.man to
+ achieve the desired effect (a <emphasis>MAN</emphasis>datory
+ profile). </para>
+
+ <para>Windows clients can sometimes maintain a connection to
+ the [homes] share, even though there is no user logged in.
+ Therefore, it is vital that the logon path does not include a
+ reference to the homes share (i.e. setting this parameter to
+ \%N\%U\profile_path will cause problems).</para>
+
+ <para>This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or machine.</para>
+
+ <para>Note that this option is only useful if Samba is set up
+ as a logon server.</para>
+
+ <para>Default: <command>logon path = \\%N\%U\profile</command></para>
+ <para>Example: <command>logon path = \\PROFILESERVER\PROFILE\%U</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LOGONSCRIPT">logon script (G)</term>
+ <listitem><para>This parameter specifies the batch file (.bat) or
+ NT command file (.cmd) to be downloaded and run on a machine when
+ a user successfully logs in. The file must contain the DOS
+ style CR/LF line endings. Using a DOS-style editor to create the
+ file is recommended.</para>
+
+ <para>The script must be a relative path to the [netlogon]
+ service. If the [netlogon] service specifies a <link linkend="PATH">
+ <parameter>path</parameter></link> of <filename>/usr/local/samba/netlogon
+ </filename>, and <command>logon script = STARTUP.BAT</command>, then
+ the file that will be downloaded is:</para>
+
+ <para><filename>/usr/local/samba/netlogon/STARTUP.BAT</filename></para>
+
+ <para>The contents of the batch file are entirely your choice. A
+ suggested command would be to add <command>NET TIME \\SERVER /SET
+ /YES</command>, to force every machine to synchronize clocks with
+ the same time server. Another use would be to add <command>NET USE
+ U: \\SERVER\UTILS</command> for commonly used utilities, or <command>
+ NET USE Q: \\SERVER\ISO9001_QA</command> for example.</para>
+
+ <para>Note that it is particularly important not to allow write
+ access to the [netlogon] share, or to grant users write permission
+ on the batch files in a secure environment, as this would allow
+ the batch files to be arbitrarily modified and security to be
+ breached.</para>
+
+ <para>This option takes the standard substitutions, allowing you
+ to have separate logon scripts for each user or machine.</para>
+
+ <para>This option is only useful if Samba is set up as a logon
+ server.</para>
+
+ <para>Default: <emphasis>no logon script defined</emphasis></para>
+ <para>Example: <command>logon script = scripts\%U.bat</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LPPAUSECOMMAND">lppause command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to stop printing or spooling
+ a specific print job.</para>
+
+ <para>This command should be a program or script which takes
+ a printer name and job number to pause the print job. One way
+ of implementing this is by using job priorities, where jobs
+ having a too low priority won't be sent to the printer.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. A <parameter>%j</parameter> is replaced with
+ the job number (an integer). On HPUX (see <parameter>printing=hpux
+ </parameter>), if the <parameter>-p%p</parameter> option is added
+ to the lpq command, the job will show up with the correct status, i.e.
+ if the job priority is lower than the set fence priority it will
+ have the PAUSED status, whereas if the priority is equal or higher it
+ will have the SPOOLED or PRINTING status.</para>
+
+ <para>Note that it is good practice to include the absolute path
+ in the lppause command as the PATH may not be available to the server.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: Currently no default value is given to
+ this string, unless the value of the <parameter>printing</parameter>
+ parameter is <constant>SYSV</constant>, in which case the default is :</para>
+
+ <para><command>lp -i %p-%j -H hold</command></para>
+
+ <para>or if the value of the <parameter>printing</parameter> parameter
+ is <constant>SOFTQ</constant>, then the default is:</para>
+
+ <para><command>qstat -s -j%j -h</command></para>
+
+ <para>Example for HPUX: <command>lppause command = /usr/bin/lpalt
+ %p-%j -p0</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LPQCACHETIME">lpq cache time (G)</term>
+ <listitem><para>This controls how long lpq info will be cached
+ for to prevent the <command>lpq</command> command being called too
+ often. A separate cache is kept for each variation of the <command>
+ lpq</command> command used by the system, so if you use different
+ <command>lpq</command> commands for different users then they won't
+ share cache information.</para>
+
+ <para>The cache files are stored in <filename>/tmp/lpq.xxxx</filename>
+ where xxxx is a hash of the <command>lpq</command> command in use.</para>
+
+ <para>The default is 10 seconds, meaning that the cached results
+ of a previous identical <command>lpq</command> command will be used
+ if the cached data is less than 10 seconds old. A large value may
+ be advisable if your <command>lpq</command> command is very slow.</para>
+
+ <para>A value of 0 will disable caching completely.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: <command>lpq cache time = 10</command></para>
+ <para>Example: <command>lpq cache time = 30</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LPQCOMMAND">lpq command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to obtain <command>lpq
+ </command>-style printer status information.</para>
+
+ <para>This command should be a program or script which
+ takes a printer name as its only parameter and outputs printer
+ status information.</para>
+
+ <para>Currently nine styles of printer status information
+ are supported; BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, CUPS, and SOFTQ.
+ This covers most UNIX systems. You control which type is expected
+ using the <parameter>printing =</parameter> option.</para>
+
+ <para>Some clients (notably Windows for Workgroups) may not
+ correctly send the connection number for the printer they are
+ requesting status information about. To get around this, the
+ server reports on the first printer service connected to by the
+ client. This only happens if the connection number sent is invalid.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the
+ command.</para>
+
+ <para>Note that it is good practice to include the absolute path
+ in the <parameter>lpq command</parameter> as the <envar>$PATH
+ </envar> may not be available to the server. When compiled with
+ the CUPS libraries, no <parameter>lpq command</parameter> is
+ needed because smbd will make a library call to obtain the
+ print queue listing.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: <emphasis>depends on the setting of <parameter>
+ printing</parameter></emphasis></para>
+
+ <para>Example: <command>lpq command = /usr/bin/lpq -P%p</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LPRESUMECOMMAND">lpresume command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to restart or continue
+ printing or spooling a specific print job.</para>
+
+ <para>This command should be a program or script which takes
+ a printer name and job number to resume the print job. See
+ also the <link linkend="LPPAUSECOMMAND"><parameter>lppause command
+ </parameter></link> parameter.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. A <parameter>%j</parameter> is replaced with
+ the job number (an integer).</para>
+
+ <para>Note that it is good practice to include the absolute path
+ in the <parameter>lpresume command</parameter> as the PATH may not
+ be available to the server.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: Currently no default value is given
+ to this string, unless the value of the <parameter>printing</parameter>
+ parameter is <constant>SYSV</constant>, in which case the default is :</para>
+
+ <para><command>lp -i %p-%j -H resume</command></para>
+
+ <para>or if the value of the <parameter>printing</parameter> parameter
+ is <constant>SOFTQ</constant>, then the default is:</para>
+
+ <para><command>qstat -s -j%j -r</command></para>
+
+ <para>Example for HPUX: <command>lpresume command = /usr/bin/lpalt
+ %p-%j -p2</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="LPRMCOMMAND">lprm command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to delete a print job.</para>
+
+ <para>This command should be a program or script which takes
+ a printer name and job number, and deletes the print job.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. A <parameter>%j</parameter> is replaced with
+ the job number (an integer).</para>
+
+ <para>Note that it is good practice to include the absolute
+ path in the <parameter>lprm command</parameter> as the PATH may not be
+ available to the server.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: <emphasis>depends on the setting of <parameter>printing
+ </parameter></emphasis></para>
+
+ <para>Example 1: <command>lprm command = /usr/bin/lprm -P%p %j
+ </command></para>
+ <para>Example 2: <command>lprm command = /usr/bin/cancel %p-%j
+ </command></para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MACHINEPASSWORDTIMEOUT">machine password timeout (G)</term>
+ <listitem><para>If a Samba server is a member of a Windows
+ NT Domain (see the <link linkend="SECURITYEQUALSDOMAIN">security = domain</link>)
+ parameter) then periodically a running <ulink url="smbd.8.html">
+ smbd(8)</ulink> process will try and change the MACHINE ACCOUNT
+ PASSWORD stored in the TDB called <filename>private/secrets.tdb
+ </filename>. This parameter specifies how often this password
+ will be changed, in seconds. The default is one week (expressed in
+ seconds), the same as a Windows NT Domain member server.</para>
+
+ <para>See also <ulink url="smbpasswd.8.html"><command>smbpasswd(8)
+ </command></ulink>, and the <link linkend="SECURITYEQUALSDOMAIN">
+ security = domain</link>) parameter.</para>
+
+ <para>Default: <command>machine password timeout = 604800</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MAGICOUTPUT">magic output (S)</term>
+ <listitem><para>This parameter specifies the name of a file
+ which will contain output created by a magic script (see the
+ <link linkend="MAGICSCRIPT"><parameter>magic script</parameter></link>
+ parameter below).</para>
+
+ <para>Warning: If two clients use the same <parameter>magic script
+ </parameter> in the same directory the output file content
+ is undefined.</para>
+
+ <para>Default: <command>magic output = &lt;magic script name&gt;.out
+ </command></para>
+
+ <para>Example: <command>magic output = myfile.txt</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAGICSCRIPT">magic script (S)</term>
+ <listitem><para>This parameter specifies the name of a file which,
+ if opened, will be executed by the server when the file is closed.
+ This allows a UNIX script to be sent to the Samba host and
+ executed on behalf of the connected user.</para>
+
+ <para>Scripts executed in this way will be deleted upon
+ completion assuming that the user has the appropriate level
+ of privilege and the file permissions allow the deletion.</para>
+
+ <para>If the script generates output, output will be sent to
+ the file specified by the <link linkend="MAGICOUTPUT"><parameter>
+ magic output</parameter></link> parameter (see above).</para>
+
+ <para>Note that some shells are unable to interpret scripts
+ containing CR/LF instead of CR as
+ the end-of-line marker. Magic scripts must be executable
+ <emphasis>as is</emphasis> on the host, which for some hosts and
+ some shells will require filtering at the DOS end.</para>
+
+ <para>Magic scripts are <emphasis>EXPERIMENTAL</emphasis> and
+ should <emphasis>NOT</emphasis> be relied upon.</para>
+
+ <para>Default: <emphasis>None. Magic scripts disabled.</emphasis></para>
+ <para>Example: <command>magic script = user.csh</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MANGLECASE">mangle case (S)</term>
+ <listitem><para>See the section on <link linkend="NAMEMANGLINGSECT">
+ NAME MANGLING</link></para>
+
+ <para>Default: <command>mangle case = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MANGLEDMAP">mangled map (S)</term>
+ <listitem><para>This is for those who want to directly map UNIX
+ file names which cannot be represented on Windows/DOS. The mangling
+ of names is not always what is needed. In particular you may have
+ documents with file extensions that differ between DOS and UNIX.
+ For example, under UNIX it is common to use <filename>.html</filename>
+ for HTML files, whereas under Windows/DOS <filename>.htm</filename>
+ is more commonly used.</para>
+
+ <para>So to map <filename>html</filename> to <filename>htm</filename>
+ you would use:</para>
+
+ <para><command>mangled map = (*.html *.htm)</command></para>
+
+ <para>One very useful case is to remove the annoying <filename>;1
+ </filename> off the ends of filenames on some CDROMs (only visible
+ under some UNIXes). To do this use a map of (*;1 *;).</para>
+
+ <para>Default: <emphasis>no mangled map</emphasis></para>
+ <para>Example: <command>mangled map = (*;1 *;)</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MANGLEDNAMES">mangled names (S)</term>
+ <listitem><para>This controls whether non-DOS names under UNIX
+ should be mapped to DOS-compatible names ("mangled") and made visible,
+ or whether non-DOS names should simply be ignored.</para>
+
+ <para>See the section on <link linkend="NAMEMANGLINGSECT">
+ NAME MANGLING</link> for details on how to control the mangling process.</para>
+
+ <para>If mangling algorithm "hash" is used then the mangling algorithm is as follows:</para>
+
+ <itemizedlist>
+ <listitem><para>The first (up to) five alphanumeric characters
+ before the rightmost dot of the filename are preserved, forced
+ to upper case, and appear as the first (up to) five characters
+ of the mangled name.</para></listitem>
+
+ <listitem><para>A tilde "~" is appended to the first part of the mangled
+ name, followed by a two-character unique sequence, based on the
+ original root name (i.e., the original filename minus its final
+ extension). The final extension is included in the hash calculation
+ only if it contains any upper case characters or is longer than three
+ characters.</para>
+
+ <para>Note that the character to use may be specified using
+ the <link linkend="MANGLINGCHAR"><parameter>mangling char</parameter>
+ </link> option, if you don't like '~'.</para></listitem>
+
+ <listitem><para>The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and appear as the
+ extension of the mangled name. The final extension is defined as that
+ part of the original filename after the rightmost dot. If there are no
+ dots in the filename, the mangled name will have no extension (except
+ in the case of "hidden files" - see below).</para></listitem>
+
+ <listitem><para>Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will be created as
+ for other filenames, but with the leading dot removed and "___" as
+ its extension regardless of actual original extension (that's three
+ underscores).</para></listitem>
+ </itemizedlist>
+
+ <para>The two-digit hash value consists of upper case
+ alphanumeric characters.</para>
+
+ <para>This algorithm can cause name collisions only if files
+ in a directory share the same first five alphanumeric characters.
+ The probability of such a clash is 1/1300.</para>
+
+ <para>If mangling algorithm "hash2" is used then the mangling algorithm is as follows:</para>
+
+ <itemizedlist>
+ <listitem><para>The first alphanumeric character
+ before the rightmost dot of the filename is preserved, forced
+ to upper case, and appears as the first character of the mangled name.
+ </para></listitem>
+
+ <listitem><para>A base63 hash of 5 characters is generated and the
+ first 4 characters of that hash are appended to the first character.
+ </para></listitem>
+
+ <listitem><para>A tilde "~" is appended to the first part of the mangled
+ name, followed by the final character of the base36 hash of the name.
+ </para>
+
+ <para>Note that the character to use may be specified using
+ the <link linkend="MANGLINGCHAR"><parameter>mangling char</parameter>
+ </link> option, if you don't like '~'.</para></listitem>
+
+ <listitem><para>The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and appear as the
+ extension of the mangled name. The final extension is defined as that
+ part of the original filename after the rightmost dot. If there are no
+ dots in the filename, the mangled name will have no extension (except
+ in the case of "hidden files" - see below).</para></listitem>
+
+ <listitem><para>Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will be created as
+ for other filenames, but with the leading dot removed and "___" as
+ its extension regardless of actual original extension (that's three
+ underscores).</para></listitem>
+ </itemizedlist>
+
+ <para>The name mangling (if enabled) allows a file to be
+ copied between UNIX directories from Windows/DOS while retaining
+ the long UNIX filename. UNIX files can be renamed to a new extension
+ from Windows/DOS and will retain the same basename. Mangled names
+ do not change between sessions.</para>
+
+ <para>Default: <command>mangled names = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MANGLEDSTACK">mangled stack (G)</term>
+ <listitem><para>This parameter controls the number of mangled names
+ that should be cached in the Samba server <ulink url="smbd.8.html">
+ smbd(8)</ulink>.</para>
+
+ <para>This stack is a list of recently mangled base names
+ (extensions are only maintained if they are longer than 3 characters
+ or contains upper case characters).</para>
+
+ <para>The larger this value, the more likely it is that mangled
+ names can be successfully converted to correct long UNIX names.
+ However, large stack sizes will slow most directory accesses. Smaller
+ stacks save memory in the server (each stack element costs 256 bytes).
+ </para>
+
+ <para>It is not possible to absolutely guarantee correct long
+ filenames, so be prepared for some surprises!</para>
+
+ <para>Default: <command>mangled stack = 50</command></para>
+ <para>Example: <command>mangled stack = 100</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MANGLINGCHAR">mangling char (S)</term>
+ <listitem><para>This controls what character is used as
+ the <emphasis>magic</emphasis> character in <link
+ linkend="NAMEMANGLINGSECT">name mangling</link>. The default is a '~'
+ but this may interfere with some software. Use this option to set
+ it to whatever you prefer.</para>
+
+ <para>Default: <command>mangling char = ~</command></para>
+ <para>Example: <command>mangling char = ^</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MANGLINGMETHOD">mangling mathod(G)</term>
+ <listitem><para> controls the algorithm used for the generating
+ the mangled names. Can take two different values, "hash" and
+ "hash2". "hash" is the default and is the algorithm that has been
+ used in Samba for many years. "hash2" is a newer and considered
+ a better algorithm (generates less collisions) in the names.
+ However, many Win32 applications store the mangled names and so
+ changing to the new algorithm must not be done
+ lightly as these applications may break unless reinstalled.
+ New installations of Samba may set the default to hash2.</para>
+ <para>Default: <command>mangling method = hash</command></para>
+ <para>Example: <command>mangling method = hash2</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAPARCHIVE">map archive (S)</term>
+ <listitem><para>This controls whether the DOS archive attribute
+ should be mapped to the UNIX owner execute bit. The DOS archive bit
+ is set when a file has been modified since its last backup. One
+ motivation for this option it to keep Samba/your PC from making
+ any file it touches from becoming executable under UNIX. This can
+ be quite annoying for shared source code, documents, etc...</para>
+
+ <para>Note that this requires the <parameter>create mask</parameter>
+ parameter to be set such that owner execute bit is not masked out
+ (i.e. it must include 100). See the parameter <link linkend="CREATEMASK">
+ <parameter>create mask</parameter></link> for details.</para>
+
+ <para>Default: <command>map archive = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAPHIDDEN">map hidden (S)</term>
+ <listitem><para>This controls whether DOS style hidden files
+ should be mapped to the UNIX world execute bit.</para>
+
+ <para>Note that this requires the <parameter>create mask</parameter>
+ to be set such that the world execute bit is not masked out (i.e.
+ it must include 001). See the parameter <link linkend="CREATEMASK">
+ <parameter>create mask</parameter></link> for details.</para>
+
+ <para>Default: <command>map hidden = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MAPSYSTEM">map system (S)</term>
+ <listitem><para>This controls whether DOS style system files
+ should be mapped to the UNIX group execute bit.</para>
+
+ <para>Note that this requires the <parameter>create mask</parameter>
+ to be set such that the group execute bit is not masked out (i.e.
+ it must include 010). See the parameter <link linkend="CREATEMASK">
+ <parameter>create mask</parameter></link> for details.</para>
+
+ <para>Default: <command>map system = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MAPTOGUEST">map to guest (G)</term>
+ <listitem><para>This parameter is only useful in <link linkend="SECURITY">
+ security</link> modes other than <parameter>security = share</parameter>
+ - i.e. <constant>user</constant>, <constant>server</constant>,
+ and <constant>domain</constant>.</para>
+
+ <para>This parameter can take three different values, which tell
+ <ulink url="smbd.8.html">smbd(8)</ulink> what to do with user
+ login requests that don't match a valid UNIX user in some way.</para>
+
+ <para>The three settings are :</para>
+
+ <itemizedlist>
+ <listitem><para><constant>Never</constant> - Means user login
+ requests with an invalid password are rejected. This is the
+ default.</para></listitem>
+
+ <listitem><para><constant>Bad User</constant> - Means user
+ logins with an invalid password are rejected, unless the username
+ does not exist, in which case it is treated as a guest login and
+ mapped into the <link linkend="GUESTACCOUNT"><parameter>
+ guest account</parameter></link>.</para></listitem>
+
+ <listitem><para><constant>Bad Password</constant> - Means user logins
+ with an invalid password are treated as a guest login and mapped
+ into the <link linkend="GUESTACCOUNT">guest account</link>. Note that
+ this can cause problems as it means that any user incorrectly typing
+ their password will be silently logged on as "guest" - and
+ will not know the reason they cannot access files they think
+ they should - there will have been no message given to them
+ that they got their password wrong. Helpdesk services will
+ <emphasis>hate</emphasis> you if you set the <parameter>map to
+ guest</parameter> parameter this way :-).</para></listitem>
+ </itemizedlist>
+
+ <para>Note that this parameter is needed to set up "Guest"
+ share services when using <parameter>security</parameter> modes other than
+ share. This is because in these modes the name of the resource being
+ requested is <emphasis>not</emphasis> sent to the server until after
+ the server has successfully authenticated the client so the server
+ cannot make authentication decisions at the correct time (connection
+ to the share) for "Guest" shares.</para>
+
+ <para>For people familiar with the older Samba releases, this
+ parameter maps to the old compile-time setting of the <constant>
+ GUEST_SESSSETUP</constant> value in local.h.</para>
+
+ <para>Default: <command>map to guest = Never</command></para>
+ <para>Example: <command>map to guest = Bad User</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXCONNECTIONS">max connections (S)</term>
+ <listitem><para>This option allows the number of simultaneous
+ connections to a service to be limited. If <parameter>max connections
+ </parameter> is greater than 0 then connections will be refused if
+ this number of connections to the service are already open. A value
+ of zero mean an unlimited number of connections may be made.</para>
+
+ <para>Record lock files are used to implement this feature. The
+ lock files will be stored in the directory specified by the <link
+ linkend="LOCKDIRECTORY"><parameter>lock directory</parameter></link>
+ option.</para>
+
+ <para>Default: <command>max connections = 0</command></para>
+ <para>Example: <command>max connections = 10</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXDISKSIZE">max disk size (G)</term>
+ <listitem><para>This option allows you to put an upper limit
+ on the apparent size of disks. If you set this option to 100
+ then all shares will appear to be not larger than 100 MB in
+ size.</para>
+
+ <para>Note that this option does not limit the amount of
+ data you can put on the disk. In the above case you could still
+ store much more than 100 MB on the disk, but if a client ever asks
+ for the amount of free disk space or the total disk size then the
+ result will be bounded by the amount specified in <parameter>max
+ disk size</parameter>.</para>
+
+ <para>This option is primarily useful to work around bugs
+ in some pieces of software that can't handle very large disks,
+ particularly disks over 1GB in size.</para>
+
+ <para>A <parameter>max disk size</parameter> of 0 means no limit.</para>
+
+ <para>Default: <command>max disk size = 0</command></para>
+ <para>Example: <command>max disk size = 1000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXLOGSIZE">max log size (G)</term>
+ <listitem><para>This option (an integer in kilobytes) specifies
+ the max size the log file should grow to. Samba periodically checks
+ the size and if it is exceeded it will rename the file, adding
+ a <filename>.old</filename> extension.</para>
+
+ <para>A size of 0 means no limit.</para>
+
+ <para>Default: <command>max log size = 5000</command></para>
+ <para>Example: <command>max log size = 1000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXMUX">max mux (G)</term>
+ <listitem><para>This option controls the maximum number of
+ outstanding simultaneous SMB operations that Samba tells the client
+ it will allow. You should never need to set this parameter.</para>
+
+ <para>Default: <command>max mux = 50</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXOPENFILES">max open files (G)</term>
+ <listitem><para>This parameter limits the maximum number of
+ open files that one <ulink url="smbd.8.html">smbd(8)</ulink> file
+ serving process may have open for a client at any one time. The
+ default for this parameter is set very high (10,000) as Samba uses
+ only one bit per unopened file.</para>
+
+ <para>The limit of the number of open files is usually set
+ by the UNIX per-process file descriptor limit rather than
+ this parameter so you should never need to touch this parameter.</para>
+
+ <para>Default: <command>max open files = 10000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXPRINTJOBS">max print jobs (S)</term>
+ <listitem><para>This parameter limits the maximum number of
+ jobs allowable in a Samba printer queue at any given moment.
+ If this number is exceeded, <ulink url="smbd.8.html"><command>
+ smbd(8)</command></ulink> will remote "Out of Space" to the client.
+ See all <link linkend="TOTALPRINTJOBS"><parameter>total
+ print jobs</parameter></link>.
+ </para>
+
+ <para>Default: <command>max print jobs = 1000</command></para>
+ <para>Example: <command>max print jobs = 5000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="MAXPROTOCOL">max protocol (G)</term>
+ <listitem><para>The value of the parameter (a string) is the highest
+ protocol level that will be supported by the server.</para>
+
+ <para>Possible values are :</para>
+ <itemizedlist>
+ <listitem><para><constant>CORE</constant>: Earliest version. No
+ concept of user names.</para></listitem>
+
+ <listitem><para><constant>COREPLUS</constant>: Slight improvements on
+ CORE for efficiency.</para></listitem>
+
+ <listitem><para><constant>LANMAN1</constant>: First <emphasis>
+ modern</emphasis> version of the protocol. Long filename
+ support.</para></listitem>
+
+ <listitem><para><constant>LANMAN2</constant>: Updates to Lanman1 protocol.
+ </para></listitem>
+
+ <listitem><para><constant>NT1</constant>: Current up to date version of
+ the protocol. Used by Windows NT. Known as CIFS.</para></listitem>
+ </itemizedlist>
+
+ <para>Normally this option should not be set as the automatic
+ negotiation phase in the SMB protocol takes care of choosing
+ the appropriate protocol.</para>
+
+ <para>See also <link linkend="MINPROTOCOL"><parameter>min
+ protocol</parameter></link></para>
+
+ <para>Default: <command>max protocol = NT1</command></para>
+ <para>Example: <command>max protocol = LANMAN1</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXSMBDPROCESSES">max smbd processes (G)</term>
+ <listitem><para>This parameter limits the maximum number of
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>
+ processes concurrently running on a system and is intended
+ as a stopgap to prevent degrading service to clients in the event
+ that the server has insufficient resources to handle more than this
+ number of connections. Remember that under normal operating
+ conditions, each user will have an <ulink url="smbd.8.html">smbd</ulink> associated with him or her
+ to handle connections to all shares from a given host.
+ </para>
+
+ <para>Default: <command>max smbd processes = 0</command> ## no limit</para>
+ <para>Example: <command>max smbd processes = 1000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXTTL">max ttl (G)</term>
+ <listitem><para>This option tells <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ what the default 'time to live' of NetBIOS names should be (in seconds)
+ when <command>nmbd</command> is requesting a name using either a
+ broadcast packet or from a WINS server. You should never need to
+ change this parameter. The default is 3 days.</para>
+
+ <para>Default: <command>max ttl = 259200</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXWINSTTL">max wins ttl (G)</term>
+ <listitem><para>This option tells <ulink url="nmbd.8.html">nmbd(8)
+ </ulink> when acting as a WINS server (<link linkend="WINSSUPPORT">
+ <parameter>wins support = yes</parameter></link>) what the maximum
+ 'time to live' of NetBIOS names that <command>nmbd</command>
+ will grant will be (in seconds). You should never need to change this
+ parameter. The default is 6 days (518400 seconds).</para>
+
+ <para>See also the <link linkend="MINWINSTTL"><parameter>min
+ wins ttl</parameter></link> parameter.</para>
+
+ <para>Default: <command>max wins ttl = 518400</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MAXXMIT">max xmit (G)</term>
+ <listitem><para>This option controls the maximum packet size
+ that will be negotiated by Samba. The default in Samba 2.2.6 is
+ now 16644 (changed from 65535 in earlier releases) which matches
+ Windows 2000. This allows better performance with Windows NT clients.
+ The maximum is 65535. In some cases you may find you get better performance
+ with a smaller value. A value below 2048 is likely to cause problems.
+ </para>
+
+ <para>Default: <command>max xmit = 16644</command></para>
+ <para>Example: <command>max xmit = 8192</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MESSAGECOMMAND">message command (G)</term>
+ <listitem><para>This specifies what command to run when the
+ server receives a WinPopup style message.</para>
+
+ <para>This would normally be a command that would
+ deliver the message somehow. How this is to be done is
+ up to your imagination.</para>
+
+ <para>An example is:</para>
+
+ <para><command>message command = csh -c 'xedit %s;rm %s' &</command>
+ </para>
+
+ <para>This delivers the message using <command>xedit</command>, then
+ removes it afterwards. <emphasis>NOTE THAT IT IS VERY IMPORTANT
+ THAT THIS COMMAND RETURN IMMEDIATELY</emphasis>. That's why I
+ have the '&' on the end. If it doesn't return immediately then
+ your PCs may freeze when sending messages (they should recover
+ after 30 seconds, hopefully).</para>
+
+ <para>All messages are delivered as the global guest user.
+ The command takes the standard substitutions, although <parameter>
+ %u</parameter> won't work (<parameter>%U</parameter> may be better
+ in this case).</para>
+
+ <para>Apart from the standard substitutions, some additional
+ ones apply. In particular:</para>
+
+ <itemizedlist>
+ <listitem><para><parameter>%s</parameter> = the filename containing
+ the message.</para></listitem>
+
+ <listitem><para><parameter>%t</parameter> = the destination that
+ the message was sent to (probably the server name).</para></listitem>
+
+ <listitem><para><parameter>%f</parameter> = who the message
+ is from.</para></listitem>
+ </itemizedlist>
+
+ <para>You could make this command send mail, or whatever else
+ takes your fancy. Please let us know of any really interesting
+ ideas you have.</para>
+
+
+ <para>Here's a way of sending the messages as mail to root:</para>
+
+ <para><command>message command = /bin/mail -s 'message from %f on
+ %m' root &lt; %s; rm %s</command></para>
+
+ <para>If you don't have a message command then the message
+ won't be delivered and Samba will tell the sender there was
+ an error. Unfortunately WfWg totally ignores the error code
+ and carries on regardless, saying that the message was delivered.
+ </para>
+
+ <para>If you want to silently delete it then try:</para>
+
+ <para><command>message command = rm %s</command></para>
+
+ <para>Default: <emphasis>no message command</emphasis></para>
+ <para>Example: <command>message command = csh -c 'xedit %s;
+ rm %s' &</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MINPASSWDLENGTH">min passwd length (G)</term>
+ <listitem><para>Synonym for <link linkend="MINPASSWORDLENGTH">
+ <parameter>min password length</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MINPASSWORDLENGTH">min password length (G)</term>
+ <listitem><para>This option sets the minimum length in characters
+ of a plaintext password that <command>smbd</command> will accept when performing
+ UNIX password changing.</para>
+
+ <para>See also <link linkend="UNIXPASSWORDSYNC"><parameter>unix
+ password sync</parameter></link>, <link linkend="PASSWDPROGRAM">
+ <parameter>passwd program</parameter></link> and <link
+ linkend="PASSWDCHATDEBUG"><parameter>passwd chat debug</parameter>
+ </link>.</para>
+
+ <para>Default: <command>min password length = 5</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="MINPRINTSPACE">min print space (S)</term>
+ <listitem><para>This sets the minimum amount of free disk
+ space that must be available before a user will be able to spool
+ a print job. It is specified in kilobytes. The default is 0, which
+ means a user can always spool a print job.</para>
+
+ <para>See also the <link linkend="PRINTING"><parameter>printing
+ </parameter></link> parameter.</para>
+
+ <para>Default: <command>min print space = 0</command></para>
+ <para>Example: <command>min print space = 2000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MINPROTOCOL">min protocol (G)</term>
+ <listitem><para>The value of the parameter (a string) is the
+ lowest SMB protocol dialect than Samba will support. Please refer
+ to the <link linkend="MAXPROTOCOL"><parameter>max protocol</parameter></link>
+ parameter for a list of valid protocol names and a brief description
+ of each. You may also wish to refer to the C source code in
+ <filename>source/smbd/negprot.c</filename> for a listing of known protocol
+ dialects supported by clients.</para>
+
+ <para>If you are viewing this parameter as a security measure, you should
+ also refer to the <link linkend="LANMANAUTH"><parameter>lanman
+ auth</parameter></link> parameter. Otherwise, you should never need
+ to change this parameter.</para>
+
+ <para>Default : <command>min protocol = CORE</command></para>
+ <para>Example : <command>min protocol = NT1</command> # disable DOS
+ clients</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MINWINSTTL">min wins ttl (G)</term>
+ <listitem><para>This option tells <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ when acting as a WINS server (<link linkend="WINSSUPPORT"><parameter>
+ wins support = yes</parameter></link>) what the minimum 'time to live'
+ of NetBIOS names that <command>nmbd</command> will grant will be (in
+ seconds). You should never need to change this parameter. The default
+ is 6 hours (21600 seconds).</para>
+
+ <para>Default: <command>min wins ttl = 21600</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="MSDFSROOT">msdfs root (S)</term>
+ <listitem><para>This boolean parameter is only available if
+ Samba is configured and compiled with the <command>
+ --with-msdfs</command> option. If set to <constant>yes</constant>,
+ Samba treats the share as a Dfs root and allows clients to browse
+ the distributed file system tree rooted at the share directory.
+ Dfs links are specified in the share directory by symbolic
+ links of the form <filename>msdfs:serverA\shareA,serverB\shareB
+ </filename> and so on. For more information on setting up a Dfs tree
+ on Samba, refer to <ulink url="msdfs_setup.html">msdfs_setup.html
+ </ulink>.</para>
+
+ <para>See also <link linkend="HOSTMSDFS"><parameter>host msdfs
+ </parameter></link></para>
+
+ <para>Default: <command>msdfs root = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="NAMERESOLVEORDER">name resolve order (G)</term>
+ <listitem><para>This option is used by the programs in the Samba
+ suite to determine what naming services to use and in what order
+ to resolve host names to IP addresses. The option takes a space
+ separated string of name resolution options.</para>
+
+ <para>The options are :"lmhosts", "host", "wins" and "bcast". They
+ cause names to be resolved as follows :</para>
+
+ <itemizedlist>
+ <listitem><para><constant>lmhosts</constant> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <ulink
+ url="lmhosts.5.html">lmhosts(5)</ulink> for details) then
+ any name type matches for lookup.</para></listitem>
+
+ <listitem><para><constant>host</constant> : Do a standard host
+ name to IP address resolution, using the system <filename>/etc/hosts
+ </filename>, NIS, or DNS lookups. This method of name resolution
+ is operating system depended for instance on IRIX or Solaris this
+ may be controlled by the <filename>/etc/nsswitch.conf</filename>
+ file. Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</para></listitem>
+
+ <listitem><para><constant>wins</constant> : Query a name with
+ the IP address listed in the <link linkend="WINSSERVER"><parameter>
+ wins server</parameter></link> parameter. If no WINS server has
+ been specified this method will be ignored.</para></listitem>
+
+ <listitem><para><constant>bcast</constant> : Do a broadcast on
+ each of the known local interfaces listed in the <link
+ linkend="INTERFACES"><parameter>interfaces</parameter></link>
+ parameter. This is the least reliable of the name resolution
+ methods as it depends on the target host being on a locally
+ connected subnet.</para></listitem>
+ </itemizedlist>
+
+ <para>Default: <command>name resolve order = lmhosts host wins bcast
+ </command></para>
+ <para>Example: <command>name resolve order = lmhosts bcast host
+ </command></para>
+
+ <para>This will cause the local lmhosts file to be examined
+ first, followed by a broadcast attempt, followed by a normal
+ system hostname lookup.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="NETBIOSALIASES">netbios aliases (G)</term>
+ <listitem><para>This is a list of NetBIOS names that <ulink
+ url="nmbd.8.html">nmbd(8)</ulink> will advertise as additional
+ names by which the Samba server is known. This allows one machine
+ to appear in browse lists under multiple names. If a machine is
+ acting as a browse server or logon server none
+ of these names will be advertised as either browse server or logon
+ servers, only the primary name of the machine will be advertised
+ with these capabilities.</para>
+
+ <para>See also <link linkend="NETBIOSNAME"><parameter>netbios
+ name</parameter></link>.</para>
+
+ <para>Default: <emphasis>empty string (no additional names)</emphasis></para>
+ <para>Example: <command>netbios aliases = TEST TEST1 TEST2</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NETBIOSNAME">netbios name (G)</term>
+ <listitem><para>This sets the NetBIOS name by which a Samba
+ server is known. By default it is the same as the first component
+ of the host's DNS name. If a machine is a browse server or
+ logon server this name (or the first component
+ of the hosts DNS name) will be the name that these services are
+ advertised under.</para>
+
+ <para>See also <link linkend="NETBIOSALIASES"><parameter>netbios
+ aliases</parameter></link>.</para>
+
+ <para>Default: <emphasis>machine DNS name</emphasis></para>
+ <para>Example: <command>netbios name = MYNAME</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NETBIOSSCOPE">netbios scope (G)</term>
+ <listitem><para>This sets the NetBIOS scope that Samba will
+ operate under. This should not be set unless every machine
+ on your LAN also sets this value.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="NISHOMEDIR">nis homedir (G)</term>
+ <listitem><para>Get the home share server from a NIS map. For
+ UNIX systems that use an automounter, the user's home directory
+ will often be mounted on a workstation on demand from a remote
+ server. </para>
+
+ <para>When the Samba logon server is not the actual home directory
+ server, but is mounting the home directories via NFS then two
+ network hops would be required to access the users home directory
+ if the logon server told the client to use itself as the SMB server
+ for home directories (one over SMB and one over NFS). This can
+ be very slow.</para>
+
+ <para>This option allows Samba to return the home share as
+ being on a different server to the logon server and as
+ long as a Samba daemon is running on the home directory server,
+ it will be mounted on the Samba client directly from the directory
+ server. When Samba is returning the home share to the client, it
+ will consult the NIS map specified in <link linkend="HOMEDIRMAP">
+ <parameter>homedir map</parameter></link> and return the server
+ listed there.</para>
+
+ <para>Note that for this option to work there must be a working
+ NIS system and the Samba server with this option must also
+ be a logon server.</para>
+
+ <para>Default: <command>nis homedir = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NTACLSUPPORT">nt acl support (S)</term>
+ <listitem><para>This boolean parameter controls whether
+ <ulink url="smbd.8.html">smbd(8)</ulink> will attempt to map
+ UNIX permissions into Windows NT access control lists.
+ This parameter was formally a global parameter in releases
+ prior to 2.2.2.</para>
+
+ <para>Default: <command>nt acl support = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NTPIPESUPPORT">nt pipe support (G)</term>
+ <listitem><para>This boolean parameter controls whether
+ <ulink url="smbd.8.html">smbd(8)</ulink> will allow Windows NT
+ clients to connect to the NT SMB specific <constant>IPC$</constant>
+ pipes. This is a developer debugging option and can be left
+ alone.</para>
+
+ <para>Default: <command>nt pipe support = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NTSMBSUPPORT">nt smb support (G)</term>
+ <listitem><para>This boolean parameter controls whether <ulink
+ url="smbd.8.html">smbd(8)</ulink> will negotiate NT specific SMB
+ support with Windows NT/2k/XP clients. Although this is a developer
+ debugging option and should be left alone, benchmarking has discovered
+ that Windows NT clients give faster performance with this option
+ set to <constant>no</constant>. This is still being investigated.
+ If this option is set to <constant>no</constant> then Samba offers
+ exactly the same SMB calls that versions prior to Samba 2.0 offered.
+ This information may be of use if any users are having problems
+ with NT SMB support.</para>
+
+ <para>You should not need to ever disable this parameter.</para>
+
+ <para>Default: <command>nt smb support = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NTSTATUSSUPPORT">nt status support (G)</term>
+ <listitem><para>This boolean parameter controls whether <ulink
+ url="smbd.8.html">smbd(8)</ulink> will negotiate NT specific status
+ support with Windows NT/2k/XP clients. This is a developer
+ debugging option and should be left alone.
+ If this option is set to <constant>no</constant> then Samba offers
+ exactly the same DOS error codes that versions prior to Samba 2.2.3
+ reported.</para>
+
+ <para>You should not need to ever disable this parameter.</para>
+
+ <para>Default: <command>nt status support = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="NULLPASSWORDS">null passwords (G)</term>
+ <listitem><para>Allow or disallow client access to accounts
+ that have null passwords. </para>
+
+ <para>See also <ulink url="smbpasswd.5.html">smbpasswd (5)</ulink>.</para>
+
+ <para>Default: <command>null passwords = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="OBEYPAMRESTRICTIONS">obey pam restrictions (G)</term>
+ <listitem><para>When Samba 2.2 is configured to enable PAM support
+ (i.e. --with-pam), this parameter will control whether or not Samba
+ should obey PAM's account and session management directives. The
+ default behavior is to use PAM for clear text authentication only
+ and to ignore any account or session management. Note that Samba
+ always ignores PAM for authentication in the case of <link
+ linkend="ENCRYPTPASSWORDS"><parameter>encrypt passwords = yes</parameter>
+ </link>. The reason is that PAM modules cannot support the challenge/response
+ authentication mechanism needed in the presence of SMB password encryption.
+ </para>
+
+ <para>Default: <command>obey pam restrictions = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="ONLYUSER">only user (S)</term>
+ <listitem><para>This is a boolean option that controls whether
+ connections with usernames not in the <parameter>user</parameter>
+ list will be allowed. By default this option is disabled so that a
+ client can supply a username to be used by the server. Enabling
+ this parameter will force the server to only use the login
+ names from the <parameter>user</parameter> list and is only really
+ useful in <link linkend="SECURITYEQUALSSHARE">share level</link>
+ security.</para>
+
+ <para>Note that this also means Samba won't try to deduce
+ usernames from the service name. This can be annoying for
+ the [homes] section. To get around this you could use <command>user =
+ %S</command> which means your <parameter>user</parameter> list
+ will be just the service name, which for home directories is the
+ name of the user.</para>
+
+ <para>See also the <link linkend="USER"><parameter>user</parameter>
+ </link> parameter.</para>
+
+ <para>Default: <command>only user = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="ONLYGUEST">only guest (S)</term>
+ <listitem><para>A synonym for <link linkend="GUESTONLY"><parameter>
+ guest only</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="OPLOCKBREAKWAITTIME">oplock break wait time (G)</term>
+ <listitem><para>This is a tuning parameter added due to bugs in
+ both Windows 9x and WinNT. If Samba responds to a client too
+ quickly when that client issues an SMB that can cause an oplock
+ break request, then the network client can fail and not respond
+ to the break request. This tuning parameter (which is set in milliseconds)
+ is the amount of time Samba will wait before sending an oplock break
+ request to such (broken) clients.</para>
+
+ <para><emphasis>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+ AND UNDERSTOOD THE SAMBA OPLOCK CODE</emphasis>.</para>
+
+ <para>Default: <command>oplock break wait time = 0</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="OPLOCKCONTENTIONLIMIT">oplock contention limit (S)</term>
+ <listitem><para>This is a <emphasis>very</emphasis> advanced
+ <ulink url="smbd.8.html">smbd(8)</ulink> tuning option to
+ improve the efficiency of the granting of oplocks under multiple
+ client contention for the same file.</para>
+
+ <para>In brief it specifies a number, which causes <ulink url="smbd.8.html">smbd</ulink> not to
+ grant an oplock even when requested if the approximate number of
+ clients contending for an oplock on the same file goes over this
+ limit. This causes <command>smbd</command> to behave in a similar
+ way to Windows NT.</para>
+
+ <para><emphasis>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+ AND UNDERSTOOD THE SAMBA OPLOCK CODE</emphasis>.</para>
+
+ <para>Default: <command>oplock contention limit = 2</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="OPLOCKS">oplocks (S)</term>
+ <listitem><para>This boolean option tells <command>smbd</command> whether to
+ issue oplocks (opportunistic locks) to file open requests on this
+ share. The oplock code can dramatically (approx. 30% or more) improve
+ the speed of access to files on Samba servers. It allows the clients
+ to aggressively cache files locally and you may want to disable this
+ option for unreliable network environments (it is turned on by
+ default in Windows NT Servers). For more information see the file
+ <filename>Speed.txt</filename> in the Samba <filename>docs/</filename>
+ directory.</para>
+
+ <para>Oplocks may be selectively turned off on certain files with a
+ share. See the <link linkend="VETOOPLOCKFILES"><parameter>
+ veto oplock files</parameter></link> parameter. On some systems
+ oplocks are recognized by the underlying operating system. This
+ allows data synchronization between all access to oplocked files,
+ whether it be via Samba or NFS or a local UNIX process. See the
+ <parameter>kernel oplocks</parameter> parameter for details.</para>
+
+ <para>See also the <link linkend="KERNELOPLOCKS"><parameter>kernel
+ oplocks</parameter></link> and <link linkend="LEVEL2OPLOCKS"><parameter>
+ level2 oplocks</parameter></link> parameters.</para>
+
+ <para>Default: <command>oplocks = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="OSLEVEL">os level (G)</term>
+ <listitem><para>This integer value controls what level Samba
+ advertises itself as for browse elections. The value of this
+ parameter determines whether <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ has a chance of becoming a local master browser for the <parameter>
+ WORKGROUP</parameter> in the local broadcast area.</para>
+
+ <para><emphasis>Note :</emphasis>By default, Samba will win
+ a local master browsing election over all Microsoft operating
+ systems except a Windows NT 4.0/2000 Domain Controller. This
+ means that a misconfigured Samba host can effectively isolate
+ a subnet for browsing purposes. See <filename>BROWSING.txt
+ </filename> in the Samba <filename>docs/</filename> directory
+ for details.</para>
+
+ <para>Default: <command>os level = 20</command></para>
+ <para>Example: <command>os level = 65 </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="OS2DRIVERMAP">os2 driver map (G)</term>
+ <listitem><para>The parameter is used to define the absolute
+ path to a file containing a mapping of Windows NT printer driver
+ names to OS/2 printer driver names. The format is:</para>
+
+ <para>&lt;nt driver name&gt; = &lt;os2 driver
+ name&gt;.&lt;device name&gt;</para>
+
+ <para>For example, a valid entry using the HP LaserJet 5
+ printer driver would appear as <command>HP LaserJet 5L = LASERJET.HP
+ LaserJet 5L</command>.</para>
+
+ <para>The need for the file is due to the printer driver namespace
+ problem described in the <ulink url="printer_driver2.html">Samba
+ Printing HOWTO</ulink>. For more details on OS/2 clients, please
+ refer to the <ulink url="OS2-Client-HOWTO.html">OS2-Client-HOWTO
+ </ulink> containing in the Samba documentation.</para>
+
+ <para>Default: <command>os2 driver map = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PAMPASSWORDCHANGE">pam password change (G)</term>
+ <listitem><para>With the addition of better PAM support in Samba 2.2,
+ this parameter, it is possible to use PAM's password change control
+ flag for Samba. If enabled, then PAM will be used for password
+ changes when requested by an SMB client instead of the program listed in
+ <link linkend="PASSWDPROGRAM"><parameter>passwd program</parameter></link>.
+ It should be possible to enable this without changing your
+ <link linkend="PASSWDCHAT"><parameter>passwd chat</parameter></link>
+ parameter for most setups.
+ </para>
+
+ <para>Default: <command>pam password change = no</command></para>
+
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PANICACTION">panic action (G)</term>
+ <listitem><para>This is a Samba developer option that allows a
+ system command to be called when either <ulink url="smbd.8.html">
+ smbd(8)</ulink> or <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ crashes. This is usually used to draw attention to the fact that
+ a problem occurred.</para>
+
+ <para>Default: <command>panic action = &lt;empty string&gt;</command></para>
+ <para>Example: <command>panic action = "/bin/sleep 90000"</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PASSWDCHAT">passwd chat (G)</term>
+ <listitem><para>This string controls the <emphasis>"chat"</emphasis>
+ conversation that takes places between <ulink
+ url="smbd.8.html">smbd</ulink> and the local password changing
+ program to change the user's password. The string describes a
+ sequence of response-receive pairs that <ulink url="smbd.8.html">
+ smbd(8)</ulink> uses to determine what to send to the
+ <link linkend="PASSWDPROGRAM"><parameter>passwd program</parameter>
+ </link> and what to expect back. If the expected output is not
+ received then the password is not changed.</para>
+
+ <para>This chat sequence is often quite site specific, depending
+ on what local methods are used for password control (such as NIS
+ etc).</para>
+ <para>Note that this parameter only is only used if the <link
+ linkend="UNIXPASSWORDSYNC"><parameter>unix
+ password sync</parameter></link> parameter is set to <constant>yes</constant>. This
+ sequence is then called <emphasis>AS ROOT</emphasis> when the SMB password
+ in the smbpasswd file is being changed, without access to the old
+ password cleartext. This means that root must be able to reset the user's password
+ without knowing the text of the previous password. In the presence of NIS/YP,
+ this means that the <link linkend="PASSWDPROGRAM">passwd program</link> must be
+ executed on the NIS master.
+ </para>
+
+
+ <para>The string can contain the macro <parameter>%n</parameter> which is substituted
+ for the new password. The chat sequence can also contain the standard
+ macros <constant>\n</constant>, <constant>\r</constant>, <constant>
+ \t</constant> and <constant>\s</constant> to give line-feed,
+ carriage-return, tab and space. The chat sequence string can also contain
+ a '*' which matches any sequence of characters.
+ Double quotes can be used to collect strings with spaces
+ in them into a single string.</para>
+
+ <para>If the send string in any part of the chat sequence
+ is a full stop ".", then no string is sent. Similarly,
+ if the expect string is a full stop then no string is expected.</para>
+
+ <para>If the <link linkend="PAMPASSWORDCHANGE"><parameter>pam
+ password change</parameter></link> parameter is set to <constant>yes</constant>, the chat pairs
+ may be matched in any order, and success is determined by the PAM result,
+ not any particular output. The \n macro is ignored for PAM conversions.
+ </para>
+
+ <para>See also <link linkend="UNIXPASSWORDSYNC"><parameter>unix password
+ sync</parameter></link>, <link linkend="PASSWDPROGRAM"><parameter>
+ passwd program</parameter></link> ,<link linkend="PASSWDCHATDEBUG">
+ <parameter>passwd chat debug</parameter></link> and <link linkend="PAMPASSWORDCHANGE">
+ <parameter>pam password change</parameter></link>.</para>
+
+ <para>Default: <command>passwd chat = *new*password* %n\n
+ *new*password* %n\n *changed*</command></para>
+ <para>Example: <command>passwd chat = "*Enter OLD password*" %o\n
+ "*Enter NEW password*" %n\n "*Reenter NEW password*" %n\n "*Password
+ changed*"</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PASSWDCHATDEBUG">passwd chat debug (G)</term>
+ <listitem><para>This boolean specifies if the passwd chat script
+ parameter is run in <emphasis>debug</emphasis> mode. In this mode the
+ strings passed to and received from the passwd chat are printed
+ in the <ulink url="smbd.8.html">smbd(8)</ulink> log with a
+ <link linkend="DEBUGLEVEL"><parameter>debug level</parameter></link>
+ of 100. This is a dangerous option as it will allow plaintext passwords
+ to be seen in the <command>smbd</command> log. It is available to help
+ Samba admins debug their <parameter>passwd chat</parameter> scripts
+ when calling the <parameter>passwd program</parameter> and should
+ be turned off after this has been done. This option has no effect if the
+ <link linkend="PAMPASSWORDCHANGE"><parameter>pam password change</parameter></link>
+ paramter is set. This parameter is off by default.</para>
+
+
+ <para>See also <link linkend="PASSWDCHAT"><parameter>passwd chat</parameter>
+ </link>, <link linkend="PAMPASSWORDCHANGE"><parameter>pam password change</parameter>
+ </link>, <link linkend="PASSWDPROGRAM"><parameter>passwd program</parameter>
+ </link>.</para>
+
+ <para>Default: <command>passwd chat debug = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PASSWDPROGRAM">passwd program (G)</term>
+ <listitem><para>The name of a program that can be used to set
+ UNIX user passwords. Any occurrences of <parameter>%u</parameter>
+ will be replaced with the user name. The user name is checked for
+ existence before calling the password changing program.</para>
+
+ <para>Also note that many passwd programs insist in <emphasis>reasonable
+ </emphasis> passwords, such as a minimum length, or the inclusion
+ of mixed case chars and digits. This can pose a problem as some clients
+ (such as Windows for Workgroups) uppercase the password before sending
+ it.</para>
+
+ <para><emphasis>Note</emphasis> that if the <parameter>unix
+ password sync</parameter> parameter is set to <constant>yes
+ </constant> then this program is called <emphasis>AS ROOT</emphasis>
+ before the SMB password in the <ulink url="smbpasswd.5.html">smbpasswd(5)
+ </ulink> file is changed. If this UNIX password change fails, then
+ <command>smbd</command> will fail to change the SMB password also
+ (this is by design).</para>
+
+ <para>If the <parameter>unix password sync</parameter> parameter
+ is set this parameter <emphasis>MUST USE ABSOLUTE PATHS</emphasis>
+ for <emphasis>ALL</emphasis> programs called, and must be examined
+ for security implications. Note that by default <parameter>unix
+ password sync</parameter> is set to <constant>no</constant>.</para>
+
+ <para>See also <link linkend="UNIXPASSWORDSYNC"><parameter>unix
+ password sync</parameter></link>.</para>
+
+ <para>Default: <command>passwd program = /bin/passwd</command></para>
+ <para>Example: <command>passwd program = /sbin/npasswd %u</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PASSWORDLEVEL">password level (G)</term>
+ <listitem><para>Some client/server combinations have difficulty
+ with mixed-case passwords. One offending client is Windows for
+ Workgroups, which for some reason forces passwords to upper
+ case when using the LANMAN1 protocol, but leaves them alone when
+ using COREPLUS! Another problem child is the Windows 95/98
+ family of operating systems. These clients upper case clear
+ text passwords even when NT LM 0.12 selected by the protocol
+ negotiation request/response.</para>
+
+ <para>This parameter defines the maximum number of characters
+ that may be upper case in passwords.</para>
+
+ <para>For example, say the password given was "FRED". If <parameter>
+ password level</parameter> is set to 1, the following combinations
+ would be tried if "FRED" failed:</para>
+
+ <para>"Fred", "fred", "fRed", "frEd","freD"</para>
+
+ <para>If <parameter>password level</parameter> was set to 2,
+ the following combinations would also be tried: </para>
+
+ <para>"FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ..</para>
+
+ <para>And so on.</para>
+
+ <para>The higher value this parameter is set to the more likely
+ it is that a mixed case password will be matched against a single
+ case password. However, you should be aware that use of this
+ parameter reduces security and increases the time taken to
+ process a new connection.</para>
+
+ <para>A value of zero will cause only two attempts to be
+ made - the password as is and the password in all-lower case.</para>
+
+ <para>Default: <command>password level = 0</command></para>
+ <para>Example: <command>password level = 4</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PASSWORDSERVER">password server (G)</term>
+ <listitem><para>By specifying the name of another SMB server (such
+ as a WinNT box) with this option, and using <command>security = domain
+ </command> or <command>security = server</command> you can get Samba
+ to do all its username/password validation via a remote server.</para>
+
+ <para>This option sets the name of the password server to use.
+ It must be a NetBIOS name, so if the machine's NetBIOS name is
+ different from its Internet name then you may have to add its NetBIOS
+ name to the lmhosts file which is stored in the same directory
+ as the <filename>smb.conf</filename> file.</para>
+
+ <para>The name of the password server is looked up using the
+ parameter <link linkend="NAMERESOLVEORDER"><parameter>name
+ resolve order</parameter></link> and so may resolved
+ by any method and order described in that parameter.</para>
+
+ <para>The password server much be a machine capable of using
+ the "LM1.2X002" or the "NT LM 0.12" protocol, and it must be in
+ user level security mode.</para>
+
+ <para><emphasis>NOTE:</emphasis> Using a password server
+ means your UNIX box (running Samba) is only as secure as your
+ password server. <emphasis>DO NOT CHOOSE A PASSWORD SERVER THAT
+ YOU DON'T COMPLETELY TRUST</emphasis>.</para>
+
+ <para>Never point a Samba server at itself for password
+ serving. This will cause a loop and could lock up your Samba
+ server!</para>
+
+ <para>The name of the password server takes the standard
+ substitutions, but probably the only useful one is <parameter>%m
+ </parameter>, which means the Samba server will use the incoming
+ client as the password server. If you use this then you better
+ trust your clients, and you had better restrict them with hosts allow!</para>
+
+ <para>If the <parameter>security</parameter> parameter is set to
+ <constant>domain</constant>, then the list of machines in this
+ option must be a list of Primary or Backup Domain controllers for the
+ Domain or the character '*', as the Samba server is effectively
+ in that domain, and will use cryptographically authenticated RPC calls
+ to authenticate the user logging on. The advantage of using <command>
+ security = domain</command> is that if you list several hosts in the
+ <parameter>password server</parameter> option then <command>smbd
+ </command> will try each in turn till it finds one that responds. This
+ is useful in case your primary server goes down.</para>
+
+ <para>If the <parameter>password server</parameter> option is set
+ to the character '*', then Samba will attempt to auto-locate the
+ Primary or Backup Domain controllers to authenticate against by
+ doing a query for the name <constant>WORKGROUP&lt;1C&gt;</constant>
+ and then contacting each server returned in the list of IP
+ addresses from the name resolution source. </para>
+
+ <para>If the <parameter>security</parameter> parameter is
+ set to <constant>server</constant>, then there are different
+ restrictions that <command>security = domain</command> doesn't
+ suffer from:</para>
+
+ <itemizedlist>
+ <listitem><para>You may list several password servers in
+ the <parameter>password server</parameter> parameter, however if an
+ <command>smbd</command> makes a connection to a password server,
+ and then the password server fails, no more users will be able
+ to be authenticated from this <command>smbd</command>. This is a
+ restriction of the SMB/CIFS protocol when in <command>security = server
+ </command> mode and cannot be fixed in Samba.</para></listitem>
+
+ <listitem><para>If you are using a Windows NT server as your
+ password server then you will have to ensure that your users
+ are able to login from the Samba server, as when in <command>
+ security = server</command> mode the network logon will appear to
+ come from there rather than from the users workstation.</para></listitem>
+ </itemizedlist>
+
+ <para>See also the <link linkend="SECURITY"><parameter>security
+ </parameter></link> parameter.</para>
+
+ <para>Default: <command>password server = &lt;empty string&gt;</command>
+ </para>
+ <para>Example: <command>password server = NT-PDC, NT-BDC1, NT-BDC2
+ </command></para>
+ <para>Example: <command>password server = *</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PATH">path (S)</term>
+ <listitem><para>This parameter specifies a directory to which
+ the user of the service is to be given access. In the case of
+ printable services, this is where print data will spool prior to
+ being submitted to the host for printing.</para>
+
+ <para>For a printable service offering guest access, the service
+ should be readonly and the path should be world-writeable and
+ have the sticky bit set. This is not mandatory of course, but
+ you probably won't get the results you expect if you do
+ otherwise.</para>
+
+ <para>Any occurrences of <parameter>%u</parameter> in the path
+ will be replaced with the UNIX username that the client is using
+ on this connection. Any occurrences of <parameter>%m</parameter>
+ will be replaced by the NetBIOS name of the machine they are
+ connecting from. These replacements are very useful for setting
+ up pseudo home directories for users.</para>
+
+ <para>Note that this path will be based on <link linkend="ROOTDIR">
+ <parameter>root dir</parameter></link> if one was specified.</para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ <para>Example: <command>path = /home/fred</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PIDDIRECTORY">pid directory (G)</term>
+ <listitem><para>This option specifies the directory where pid
+ files will be placed. </para>
+
+ <para>Default: <command>pid directory = ${prefix}/var/locks</command></para>
+ <para>Example: <command>pid directory = /var/run/</command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="POSIXLOCKING">posix locking (S)</term>
+ <listitem><para>The <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>
+ daemon maintains an database of file locks obtained by SMB clients.
+ The default behavior is to map this internal database to POSIX
+ locks. This means that file locks obtained by SMB clients are
+ consistent with those seen by POSIX compliant applications accessing
+ the files via a non-SMB method (e.g. NFS or local file access).
+ You should never need to disable this parameter.</para>
+
+ <para>Default: <command>posix locking = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="POSTEXEC">postexec (S)</term>
+ <listitem><para>This option specifies a command to be run
+ whenever the service is disconnected. It takes the usual
+ substitutions. The command may be run as the root on some
+ systems.</para>
+
+ <para>An interesting example may be to unmount server
+ resources:</para>
+
+ <para><command>postexec = /etc/umount /cdrom</command></para>
+
+ <para>See also <link linkend="PREEXEC"><parameter>preexec</parameter>
+ </link>.</para>
+
+ <para>Default: <emphasis>none (no command executed)</emphasis>
+ </para>
+
+ <para>Example: <command>postexec = echo \"%u disconnected from %S
+ from %m (%I)\" &gt;&gt; /tmp/log</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="POSTSCRIPT">postscript (S)</term>
+ <listitem><para>This parameter forces a printer to interpret
+ the print files as PostScript. This is done by adding a <constant>%!
+ </constant> to the start of print output.</para>
+
+ <para>This is most useful when you have lots of PCs that persist
+ in putting a control-D at the start of print jobs, which then
+ confuses your printer.</para>
+
+ <para>Default: <command>postscript = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PREEXEC">preexec (S)</term>
+ <listitem><para>This option specifies a command to be run whenever
+ the service is connected to. It takes the usual substitutions.</para>
+
+ <para>An interesting example is to send the users a welcome
+ message every time they log in. Maybe a message of the day? Here
+ is an example:</para>
+
+ <para><command>preexec = csh -c 'echo \"Welcome to %S!\" |
+ /usr/local/samba/bin/smbclient -M %m -I %I' & </command></para>
+
+ <para>Of course, this could get annoying after a while :-)</para>
+
+ <para>See also <link linkend="PREEXECCLOSE"><parameter>preexec close
+ </parameter</link> and <link linkend="POSTEXEC"><parameter>postexec
+ </parameter></link>.</para>
+
+ <para>Default: <emphasis>none (no command executed)</emphasis></para>
+ <para>Example: <command>preexec = echo \"%u connected to %S from %m
+ (%I)\" &gt;&gt; /tmp/log</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PREEXECCLOSE">preexec close (S)</term>
+ <listitem><para>This boolean option controls whether a non-zero
+ return code from <link linkend="PREEXEC"><parameter>preexec
+ </parameter></link> should close the service being connected to.</para>
+
+ <para>Default: <command>preexec close = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PREFERREDMASTER">preferred master (G)</term>
+ <listitem><para>This boolean parameter controls if <ulink
+ url="nmbd.8.html">nmbd(8)</ulink> is a preferred master browser
+ for its workgroup.</para>
+
+ <para>If this is set to <constant>yes</constant>, on startup, <command>nmbd</command>
+ will force an election, and it will have a slight advantage in
+ winning the election. It is recommended that this parameter is
+ used in conjunction with <command><link linkend="DOMAINMASTER"><parameter>
+ domain master</parameter></link> = yes</command>, so that <command>
+ nmbd</command> can guarantee becoming a domain master.</para>
+
+ <para>Use this option with caution, because if there are several
+ hosts (whether Samba servers, Windows 95 or NT) that are preferred
+ master browsers on the same subnet, they will each periodically
+ and continuously attempt to become the local master browser.
+ This will result in unnecessary broadcast traffic and reduced browsing
+ capabilities.</para>
+
+ <para>See also <link linkend="OSLEVEL"><parameter>os level</parameter>
+ </link>.</para>
+
+ <para>Default: <command>preferred master = auto</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PREFEREDMASTER">prefered master (G)</term>
+ <listitem><para>Synonym for <link linkend="PREFERREDMASTER"><parameter>
+ preferred master</parameter></link> for people who cannot spell :-).</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRELOAD">preload</term>
+ <listitem><para>This is a list of services that you want to be
+ automatically added to the browse lists. This is most useful
+ for homes and printers services that would otherwise not be
+ visible.</para>
+
+ <para>Note that if you just want all printers in your
+ printcap file loaded then the <link linkend="LOADPRINTERS">
+ <parameter>load printers</parameter></link> option is easier.</para>
+
+ <para>Default: <emphasis>no preloaded services</emphasis></para>
+
+ <para>Example: <command>preload = fred lp colorlp</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PRESERVECASE">preserve case (S)</term>
+ <listitem><para> This controls if new filenames are created
+ with the case that the client passes, or if they are forced to
+ be the <link linkend="DEFAULTCASE"><parameter>default case
+ </parameter></link>.</para>
+
+ <para>Default: <command>preserve case = yes</command></para>
+
+ <para>See the section on <link linkend="NAMEMANGLINGSECT">NAME
+ MANGLING</link> for a fuller discussion.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTCOMMAND">print command (S)</term>
+ <listitem><para>After a print job has finished spooling to
+ a service, this command will be used via a <command>system()</command>
+ call to process the spool file. Typically the command specified will
+ submit the spool file to the host's printing subsystem, but there
+ is no requirement that this be the case. The server will not remove
+ the spool file, so whatever command you specify should remove the
+ spool file when it has been processed, otherwise you will need to
+ manually remove old spool files.</para>
+
+ <para>The print command is simply a text string. It will be used
+ verbatim after macro substitutions have been made:</para>
+
+ <para>s, %p - the path to the spool
+ file name</para>
+
+ <para>%p - the appropriate printer
+ name</para>
+
+ <para>%J - the job
+ name as transmitted by the client.</para>
+
+ <para>%c - The number of printed pages
+ of the spooled job (if known).</para>
+
+ <para>%z - the size of the spooled
+ print job (in bytes)</para>
+
+ <para>The print command <emphasis>MUST</emphasis> contain at least
+ one occurrence of <parameter>%s</parameter> or <parameter>%f
+ </parameter> - the <parameter>%p</parameter> is optional. At the time
+ a job is submitted, if no printer name is supplied the <parameter>%p
+ </parameter> will be silently removed from the printer command.</para>
+
+ <para>If specified in the [global] section, the print command given
+ will be used for any printable service that does not have its own
+ print command specified.</para>
+
+ <para>If there is neither a specified print command for a
+ printable service nor a global print command, spool files will
+ be created but not processed and (most importantly) not removed.</para>
+
+ <para>Note that printing may fail on some UNIXes from the
+ <constant>nobody</constant> account. If this happens then create
+ an alternative guest account that can print and set the <link
+ linkend="GUESTACCOUNT"><parameter>guest account</parameter></link>
+ in the [global] section.</para>
+
+ <para>You can form quite complex print commands by realizing
+ that they are just passed to a shell. For example the following
+ will log a print job, print the file, then remove it. Note that
+ ';' is the usual separator for command in shell scripts.</para>
+
+ <para><command>print command = echo Printing %s &gt;&gt;
+ /tmp/print.log; lpr -P %p %s; rm %s</command></para>
+
+ <para>You may have to vary this command considerably depending
+ on how you normally print files on your system. The default for
+ the parameter varies depending on the setting of the <link linkend="PRINTING">
+ <parameter>printing</parameter></link> parameter.</para>
+
+ <para>Default: For <command>printing = BSD, AIX, QNX, LPRNG
+ or PLP :</command></para>
+ <para><command>print command = lpr -r -P%p %s</command></para>
+
+ <para>For <command>printing = SYSV or HPUX :</command></para>
+ <para><command>print command = lp -c -d%p %s; rm %s</command></para>
+
+ <para>For <command>printing = SOFTQ :</command></para>
+ <para><command>print command = lp -d%p -s %s; rm %s</command></para>
+
+ <para>For printing = CUPS : If SAMBA is compiled against
+ libcups, then <link linkend="PRINTING">printcap = cups</link>
+ uses the CUPS API to
+ submit jobs, etc. Otherwise it maps to the System V
+ commands with the -oraw option for printing, i.e. it
+ uses <command>lp -c -d%p -oraw; rm %s</command>.
+ With <command>printing = cups</command>,
+ and if SAMBA is compiled against libcups, any manually
+ set print command will be ignored.</para>
+
+
+ <para>Example: <command>print command = /usr/local/samba/bin/myprintscript
+ %p %s</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTOK">print ok (S)</term>
+ <listitem><para>Synonym for <link linkend="PRINTABLE">
+ <parameter>printable</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTABLE">printable (S)</term>
+ <listitem><para>If this parameter is <constant>yes</constant>, then
+ clients may open, write to and submit spool files on the directory
+ specified for the service. </para>
+
+ <para>Note that a printable service will ALWAYS allow writing
+ to the service path (user privileges permitting) via the spooling
+ of print data. The <link linkend="READONLY"><parameter>read only
+ </parameter></link> parameter controls only non-printing access to
+ the resource.</para>
+
+ <para>Default: <command>printable = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTCAP">printcap (G)</term>
+ <listitem><para>Synonym for <link linkend="PRINTCAPNAME"><parameter>
+ printcap name</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTCAPNAME">printcap name (G)</term>
+ <listitem><para>This parameter may be used to override the
+ compiled-in default printcap name used by the server (usually <filename>
+ /etc/printcap</filename>). See the discussion of the <link
+ linkend="PRINTERSSECT">[printers]</link> section above for reasons
+ why you might want to do this.</para>
+
+ <para>To use the CUPS printing interface set <command>printcap name = cups
+ </command>. This should be supplemented by an addtional setting
+ <link linkend="PRINTING">printing = cups</link> in the [global]
+ section. <command>printcap name = cups</command> will use the
+ "dummy" printcap created by CUPS, as specified in your CUPS
+ configuration file.
+ </para>
+
+ <para>On System V systems that use <command>lpstat</command> to
+ list available printers you can use <command>printcap name = lpstat
+ </command> to automatically obtain lists of available printers. This
+ is the default for systems that define SYSV at configure time in
+ Samba (this includes most System V based systems). If <parameter>
+ printcap name</parameter> is set to <command>lpstat</command> on
+ these systems then Samba will launch <command>lpstat -v</command> and
+ attempt to parse the output to obtain a printer list.</para>
+
+ <para>A minimal printcap file would look something like this:</para>
+
+ <para><programlisting>
+ print1|My Printer 1
+ print2|My Printer 2
+ print3|My Printer 3
+ print4|My Printer 4
+ print5|My Printer 5
+ </programlisting></para>
+
+ <para>where the '|' separates aliases of a printer. The fact
+ that the second alias has a space in it gives a hint to Samba
+ that it's a comment.</para>
+
+ <para><emphasis>NOTE</emphasis>: Under AIX the default printcap
+ name is <filename>/etc/qconfig</filename>. Samba will assume the
+ file is in AIX <filename>qconfig</filename> format if the string
+ <filename>qconfig</filename> appears in the printcap filename.</para>
+
+ <para>Default: <command>printcap name = /etc/printcap</command></para>
+ <para>Example: <command>printcap name = /etc/myprintcap</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTERADMIN">printer admin (S)</term>
+ <listitem><para>This is a list of users that can do anything to
+ printers via the remote administration interfaces offered by MS-RPC
+ (usually using a NT workstation). Note that the root user always
+ has admin rights.</para>
+
+ <para>Default: <command>printer admin = &lt;empty string&gt;</command>
+ </para>
+ <para>Example: <command>printer admin = admin, @staff</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTERDRIVER">printer driver (S)</term>
+ <listitem><para><emphasis>Note :</emphasis>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <ulink url="printer_driver2.html">Samba 2.2. Printing
+ HOWTO</ulink> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </para>
+
+ <para>This option allows you to control the string
+ that clients receive when they ask the server for the printer driver
+ associated with a printer. If you are using Windows95 or Windows NT
+ then you can use this to automate the setup of printers on your
+ system.</para>
+
+ <para>You need to set this parameter to the exact string (case
+ sensitive) that describes the appropriate printer driver for your
+ system. If you don't know the exact string to use then you should
+ first try with no <link linkend="PRINTERDRIVER"><parameter>
+ printer driver</parameter></link> option set and the client will
+ give you a list of printer drivers. The appropriate strings are
+ shown in a scroll box after you have chosen the printer manufacturer.</para>
+
+ <para>See also <link linkend="PRINTERDRIVERFILE"><parameter>printer
+ driver file</parameter></link>.</para>
+
+ <para>Example: <command>printer driver = HP LaserJet 4L</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTERDRIVERFILE">printer driver file (G)</term>
+ <listitem><para><emphasis>Note :</emphasis>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <ulink url="printer_driver2.html">Samba 2.2. Printing
+ HOWTO</ulink> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </para>
+
+ <para>This parameter tells Samba where the printer driver
+ definition file, used when serving drivers to Windows 95 clients, is
+ to be found. If this is not set, the default is :</para>
+
+ <para><filename><replaceable>SAMBA_INSTALL_DIRECTORY</replaceable>
+ /lib/printers.def</filename></para>
+
+ <para>This file is created from Windows 95 <filename>msprint.inf
+ </filename> files found on the Windows 95 client system. For more
+ details on setting up serving of printer drivers to Windows 95
+ clients, see the outdated documentation file in the <filename>docs/</filename>
+ directory, <filename>PRINTER_DRIVER.txt</filename>.</para>
+
+ <para>See also <link linkend="PRINTERDRIVERLOCATION"><parameter>
+ printer driver location</parameter></link>.</para>
+
+ <para>Default: <emphasis>None (set in compile).</emphasis></para>
+
+ <para>Example: <command>printer driver file =
+ /usr/local/samba/printers/drivers.def</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTERDRIVERLOCATION">printer driver location (S)</term>
+ <listitem><para><emphasis>Note :</emphasis>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <ulink url="printer_driver2.html">Samba 2.2. Printing
+ HOWTO</ulink> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </para>
+
+ <para>This parameter tells clients of a particular printer
+ share where to find the printer driver files for the automatic
+ installation of drivers for Windows 95 machines. If Samba is set up
+ to serve printer drivers to Windows 95 machines, this should be set to</para>
+
+ <para><command>\\MACHINE\PRINTER$</command></para>
+
+ <para>Where MACHINE is the NetBIOS name of your Samba server,
+ and PRINTER$ is a share you set up for serving printer driver
+ files. For more details on setting this up see the outdated documentation
+ file in the <filename>docs/</filename> directory, <filename>
+ PRINTER_DRIVER.txt</filename>.</para>
+
+ <para>See also <link linkend="PRINTERDRIVERFILE"><parameter>
+ printer driver file</parameter></link>.</para>
+
+ <para>Default: <command>none</command></para>
+ <para>Example: <command>printer driver location = \\MACHINE\PRINTER$
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTERNAME">printer name (S)</term>
+ <listitem><para>This parameter specifies the name of the printer
+ to which print jobs spooled through a printable service will be sent.</para>
+
+ <para>If specified in the [global] section, the printer
+ name given will be used for any printable service that does
+ not have its own printer name specified.</para>
+
+ <para>Default: <emphasis>none (but may be <constant>lp</constant>
+ on many systems)</emphasis></para>
+
+ <para>Example: <command>printer name = laserwriter</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="PRINTER">printer (S)</term>
+ <listitem><para>Synonym for <link linkend="PRINTERNAME"><parameter>
+ printer name</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="PRINTING">printing (S)</term>
+ <listitem><para>This parameters controls how printer status
+ information is interpreted on your system. It also affects the
+ default values for the <parameter>print command</parameter>,
+ <parameter>lpq command</parameter>, <parameter>lppause command
+ </parameter>, <parameter>lpresume command</parameter>, and
+ <parameter>lprm command</parameter> if specified in the
+ [global] section.</para>
+
+ <para>Currently nine printing styles are supported. They are
+ <constant>BSD</constant>, <constant>AIX</constant>,
+ <constant>LPRNG</constant>, <constant>PLP</constant>,
+ <constant>SYSV</constant>, <constant>HPUX</constant>,
+ <constant>QNX</constant>, <constant>SOFTQ</constant>,
+ and <constant>CUPS</constant>.</para>
+
+ <para>To see what the defaults are for the other print
+ commands when using the various options use the <ulink
+ url="testparm.1.html">testparm(1)</ulink> program.</para>
+
+ <para>This option can be set on a per printer basis</para>
+
+ <para>See also the discussion in the <link linkend="PRINTERSSECT">
+ [printers]</link> section.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PROFILEACLS">profile acls (S)</term>
+ <listitem><para>
+ This boolean parameter was added to fix the problems that people have been
+ having with storing user profiles on Samba shares from Windows 2000 or
+ Windows XP clients. New versions of Windows 2000 or Windows XP service
+ packs do security ACL checking on the owner and ability to write of the
+ profile directory stored on a local workstation when copied from a Samba
+ share. When not in domain mode with winbindd then the security info copied
+ onto the local workstation has no meaning to the logged in user (SID) on
+ that workstation so the profile storing fails. Adding this parameter
+ onto a share used for profile storage changes two things about the
+ returned Windows ACL. Firstly it changes the owner and group owner
+ of all reported files and directories to be BUILTIN\Administrators,
+ BUILTIN\Users respectively (SIDs S-1-5-32-544, S-1-5-32-545). Secondly
+ it adds an ACE entry of "Full Control" to the SID BUILTIN\Users to
+ every returned ACL. This will allow any Windows 2000 or XP workstation
+ user to access the profile. Note that if you have multiple users logging
+ on to a workstation then in order to prevent them from being able to access
+ each others profiles you must remove the "Bypass traverse checking" advanced
+ user right. This will prevent access to other users profile directories as
+ the top level profile directory (named after the user) is created by the
+ workstation profile code and has an ACL restricting entry to the directory
+ tree to the owning user.</para>
+ <para>If you didn't understand the above text, you probably should not set
+ this parameter :-).</para>
+ <para>Default <command>profile acls = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PROTOCOL">protocol (G)</term>
+ <listitem><para>Synonym for <link linkend="MAXPROTOCOL">
+ <parameter>max protocol</parameter></link>.</para></listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="PUBLIC">public (S)</term>
+ <listitem><para>Synonym for <link linkend="GUESTOK"><parameter>guest
+ ok</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="QUEUEPAUSECOMMAND">queuepause command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to pause the printer queue.</para>
+
+ <para>This command should be a program or script which takes
+ a printer name as its only parameter and stops the printer queue,
+ such that no longer jobs are submitted to the printer.</para>
+
+ <para>This command is not supported by Windows for Workgroups,
+ but can be issued from the Printers window under Windows 95
+ and NT.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the command.
+ </para>
+
+ <para>Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to the
+ server.</para>
+
+ <para>Default: <emphasis>depends on the setting of <parameter>printing
+ </parameter></emphasis></para>
+ <para>Example: <command>queuepause command = disable %p</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="QUEUERESUMECOMMAND">queueresume command (S)</term>
+ <listitem><para>This parameter specifies the command to be
+ executed on the server host in order to resume the printer queue. It
+ is the command to undo the behavior that is caused by the
+ previous parameter (<link linkend="QUEUEPAUSECOMMAND"><parameter>
+ queuepause command</parameter></link>).</para>
+
+ <para>This command should be a program or script which takes
+ a printer name as its only parameter and resumes the printer queue,
+ such that queued jobs are resubmitted to the printer.</para>
+
+ <para>This command is not supported by Windows for Workgroups,
+ but can be issued from the Printers window under Windows 95
+ and NT.</para>
+
+ <para>If a <parameter>%p</parameter> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the
+ command.</para>
+
+ <para>Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to the
+ server.</para>
+
+ <para>Default: <emphasis>depends on the setting of <link
+ linkend="PRINTING"><parameter>printing</parameter></link></emphasis>
+ </para>
+
+ <para>Example: <command>queuepause command = enable %p
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="READBMPX">read bmpx (G)</term>
+ <listitem><para>This boolean parameter controls whether <ulink
+ url="smbd.8.html">smbd(8)</ulink> will support the "Read
+ Block Multiplex" SMB. This is now rarely used and defaults to
+ <constant>no</constant>. You should never need to set this
+ parameter.</para>
+
+ <para>Default: <command>read bmpx = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="READLIST">read list (S)</term>
+ <listitem><para>This is a list of users that are given read-only
+ access to a service. If the connecting user is in this list then
+ they will not be given write access, no matter what the <link
+ linkend="READONLY"><parameter>read only</parameter></link>
+ option is set to. The list can include group names using the
+ syntax described in the <link linkend="INVALIDUSERS"><parameter>
+ invalid users</parameter></link> parameter.</para>
+
+ <para>See also the <link linkend="WRITELIST"><parameter>
+ write list</parameter></link> parameter and the <link
+ linkend="INVALIDUSERS"><parameter>invalid users</parameter>
+ </link> parameter.</para>
+
+ <para>Default: <command>read list = &lt;empty string&gt;</command></para>
+ <para>Example: <command>read list = mary, @students</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="READONLY">read only (S)</term>
+ <listitem><para>An inverted synonym is <link linkend="WRITEABLE">
+ <parameter>writeable</parameter></link>.</para>
+
+ <para>If this parameter is <constant>yes</constant>, then users
+ of a service may not create or modify files in the service's
+ directory.</para>
+
+ <para>Note that a printable service (<command>printable = yes</command>)
+ will <emphasis>ALWAYS</emphasis> allow writing to the directory
+ (user privileges permitting), but only via spooling operations.</para>
+
+ <para>Default: <command>read only = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="READRAW">read raw (G)</term>
+ <listitem><para>This parameter controls whether or not the server
+ will support the raw read SMB requests when transferring data
+ to clients.</para>
+
+ <para>If enabled, raw reads allow reads of 65535 bytes in
+ one packet. This typically provides a major performance benefit.
+ </para>
+
+ <para>However, some clients either negotiate the allowable
+ block size incorrectly or are incapable of supporting larger block
+ sizes, and for these clients you may need to disable raw reads.</para>
+
+ <para>In general this parameter should be viewed as a system tuning
+ tool and left severely alone. See also <link linkend="WRITERAW">
+ <parameter>write raw</parameter></link>.</para>
+
+ <para>Default: <command>read raw = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="READSIZE">read size (G)</term>
+ <listitem><para>The option <parameter>read size</parameter>
+ affects the overlap of disk reads/writes with network reads/writes.
+ If the amount of data being transferred in several of the SMB
+ commands (currently SMBwrite, SMBwriteX and SMBreadbraw) is larger
+ than this value then the server begins writing the data before it
+ has received the whole packet from the network, or in the case of
+ SMBreadbraw, it begins writing to the network before all the data
+ has been read from disk.</para>
+
+ <para>This overlapping works best when the speeds of disk and
+ network access are similar, having very little effect when the
+ speed of one is much greater than the other.</para>
+
+ <para>The default value is 16384, but very little experimentation
+ has been done yet to determine the optimal value, and it is likely
+ that the best value will vary greatly between systems anyway.
+ A value over 65536 is pointless and will cause you to allocate
+ memory unnecessarily.</para>
+
+ <para>Default: <command>read size = 16384</command></para>
+ <para>Example: <command>read size = 8192</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="REMOTEANNOUNCE">remote announce (G)</term>
+ <listitem><para>This option allows you to setup <ulink
+ url="nmbd.8.html">nmbd(8)</ulink> to periodically announce itself
+ to arbitrary IP addresses with an arbitrary workgroup name.</para>
+
+ <para>This is useful if you want your Samba server to appear
+ in a remote workgroup for which the normal browse propagation
+ rules don't work. The remote workgroup can be anywhere that you
+ can send IP packets to.</para>
+
+ <para>For example:</para>
+
+ <para><command>remote announce = 192.168.2.255/SERVERS
+ 192.168.4.255/STAFF</command></para>
+
+ <para>the above line would cause <command>nmbd</command> to announce itself
+ to the two given IP addresses using the given workgroup names.
+ If you leave out the workgroup name then the one given in
+ the <link linkend="WORKGROUP"><parameter>workgroup</parameter></link>
+ parameter is used instead.</para>
+
+ <para>The IP addresses you choose would normally be the broadcast
+ addresses of the remote networks, but can also be the IP addresses
+ of known browse masters if your network config is that stable.</para>
+
+ <para>See the documentation file <filename>BROWSING.txt</filename>
+ in the <filename>docs/</filename> directory.</para>
+
+ <para>Default: <command>remote announce = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="REMOTEBROWSESYNC">remote browse sync (G)</term>
+ <listitem><para>This option allows you to setup <ulink
+ url="nmbd.8.html">nmbd(8)</ulink> to periodically request
+ synchronization of browse lists with the master browser of a Samba
+ server that is on a remote segment. This option will allow you to
+ gain browse lists for multiple workgroups across routed networks. This
+ is done in a manner that does not work with any non-Samba servers.</para>
+
+ <para>This is useful if you want your Samba server and all local
+ clients to appear in a remote workgroup for which the normal browse
+ propagation rules don't work. The remote workgroup can be anywhere
+ that you can send IP packets to.</para>
+
+ <para>For example:</para>
+
+ <para><command>remote browse sync = 192.168.2.255 192.168.4.255
+ </command></para>
+
+ <para>the above line would cause <command>nmbd</command> to request
+ the master browser on the specified subnets or addresses to
+ synchronize their browse lists with the local server.</para>
+
+ <para>The IP addresses you choose would normally be the broadcast
+ addresses of the remote networks, but can also be the IP addresses
+ of known browse masters if your network config is that stable. If
+ a machine IP address is given Samba makes NO attempt to validate
+ that the remote machine is available, is listening, nor that it
+ is in fact the browse master on its segment.</para>
+
+ <para>Default: <command>remote browse sync = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="RESTRICTANONYMOUS">restrict anonymous (G)</term>
+ <listitem><para>This is a boolean parameter. If it is <constant>yes</constant>, then
+ anonymous access to the server will be restricted, namely in the
+ case where the server is expecting the client to send a username,
+ but it doesn't. Setting it to <constant>yes</constant> will force these anonymous
+ connections to be denied, and the client will be required to always
+ supply a username and password when connecting. Use of this parameter
+ is only recommended for homogeneous NT client environments.</para>
+
+ <para>This parameter makes the use of macro expansions that rely
+ on the username (%U, %G, etc) consistent. NT 4.0
+ likes to use anonymous connections when refreshing the share list,
+ and this is a way to work around that.</para>
+
+ <para>When restrict anonymous is <constant>yes</constant>, all anonymous connections
+ are denied no matter what they are for. This can effect the ability
+ of a machine to access the Samba Primary Domain Controller to revalidate
+ its machine account after someone else has logged on the client
+ interactively. The NT client will display a message saying that
+ the machine's account in the domain doesn't exist or the password is
+ bad. The best way to deal with this is to reboot NT client machines
+ between interactive logons, using "Shutdown and Restart", rather
+ than "Close all programs and logon as a different user".</para>
+
+ <para>Default: <command>restrict anonymous = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ROOT">root (G)</term>
+ <listitem><para>Synonym for <link linkend="ROOTDIRECTORY">
+ <parameter>root directory"</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ROOTDIR">root dir (G)</term>
+ <listitem><para>Synonym for <link linkend="ROOTDIRECTORY">
+ <parameter>root directory"</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="ROOTDIRECTORY">root directory (G)</term>
+ <listitem><para>The server will <command>chroot()</command> (i.e.
+ Change its root directory) to this directory on startup. This is
+ not strictly necessary for secure operation. Even without it the
+ server will deny access to files not in one of the service entries.
+ It may also check for, and deny access to, soft links to other
+ parts of the filesystem, or attempts to use ".." in file names
+ to access other directories (depending on the setting of the <link
+ linkend="WIDELINKS"><parameter>wide links</parameter></link>
+ parameter).</para>
+
+ <para>Adding a <parameter>root directory</parameter> entry other
+ than "/" adds an extra level of security, but at a price. It
+ absolutely ensures that no access is given to files not in the
+ sub-tree specified in the <parameter>root directory</parameter>
+ option, <emphasis>including</emphasis> some files needed for
+ complete operation of the server. To maintain full operability
+ of the server you will need to mirror some system files
+ into the <parameter>root directory</parameter> tree. In particular
+ you will need to mirror <filename>/etc/passwd</filename> (or a
+ subset of it), and any binaries or configuration files needed for
+ printing (if required). The set of files that must be mirrored is
+ operating system dependent.</para>
+
+ <para>Default: <command>root directory = /</command></para>
+ <para>Example: <command>root directory = /homes/smb</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ROOTPOSTEXEC">root postexec (S)</term>
+ <listitem><para>This is the same as the <parameter>postexec</parameter>
+ parameter except that the command is run as root. This
+ is useful for unmounting filesystems
+ (such as CDROMs) after a connection is closed.</para>
+
+ <para>See also <link linkend="POSTEXEC"><parameter>
+ postexec</parameter></link>.</para>
+
+ <para>Default: <command>root postexec = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="ROOTPREEXEC">root preexec (S)</term>
+ <listitem><para>This is the same as the <parameter>preexec</parameter>
+ parameter except that the command is run as root. This
+ is useful for mounting filesystems (such as CDROMs) when a
+ connection is opened.</para>
+
+ <para>See also <link linkend="PREEXEC"><parameter>
+ preexec</parameter></link> and <link linkend="PREEXECCLOSE">
+ <parameter>preexec close</parameter></link>.</para>
+
+ <para>Default: <command>root preexec = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="ROOTPREEXECCLOSE">root preexec close (S)</term>
+ <listitem><para>This is the same as the <parameter>preexec close
+ </parameter> parameter except that the command is run as root.</para>
+
+ <para>See also <link linkend="PREEXEC"><parameter>
+ preexec</parameter></link> and <link linkend="PREEXECCLOSE">
+ <parameter>preexec close</parameter></link>.</para>
+
+ <para>Default: <command>root preexec close = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SECURITY">security (G)</term>
+ <listitem><para>This option affects how clients respond to
+ Samba and is one of the most important settings in the <filename>
+ smb.conf</filename> file.</para>
+
+ <para>The option sets the "security mode bit" in replies to
+ protocol negotiations with <ulink url="smbd.8.html">smbd(8)
+ </ulink> to turn share level security on or off. Clients decide
+ based on this bit whether (and how) to transfer user and password
+ information to the server.</para>
+
+
+ <para>The default is <command>security = user</command>, as this is
+ the most common setting needed when talking to Windows 98 and
+ Windows NT.</para>
+
+ <para>The alternatives are <command>security = share</command>,
+ <command>security = server</command> or <command>security = domain
+ </command>.</para>
+
+ <para>In versions of Samba prior to 2.0.0, the default was
+ <command>security = share</command> mainly because that was
+ the only option at one stage.</para>
+
+ <para>There is a bug in WfWg that has relevance to this
+ setting. When in user or server level security a WfWg client
+ will totally ignore the password you type in the "connect
+ drive" dialog box. This makes it very difficult (if not impossible)
+ to connect to a Samba service as anyone except the user that
+ you are logged into WfWg as.</para>
+
+ <para>If your PCs use usernames that are the same as their
+ usernames on the UNIX machine then you will want to use
+ <command>security = user</command>. If you mostly use usernames
+ that don't exist on the UNIX box then use <command>security =
+ share</command>.</para>
+
+ <para>You should also use <command>security = share</command> if you
+ want to mainly setup shares without a password (guest shares). This
+ is commonly used for a shared printer server. It is more difficult
+ to setup guest shares with <command>security = user</command>, see
+ the <link linkend="MAPTOGUEST"><parameter>map to guest</parameter>
+ </link>parameter for details.</para>
+
+ <para>It is possible to use <command>smbd</command> in a <emphasis>
+ hybrid mode</emphasis> where it is offers both user and share
+ level security under different <link linkend="NETBIOSALIASES">
+ <parameter>NetBIOS aliases</parameter></link>. </para>
+
+ <para>The different settings will now be explained.</para>
+
+
+ <para><anchor id="SECURITYEQUALSSHARE"><emphasis>SECURITY = SHARE
+ </emphasis></para>
+
+ <para>When clients connect to a share level security server they
+ need not log onto the server with a valid username and password before
+ attempting to connect to a shared resource (although modern clients
+ such as Windows 95/98 and Windows NT will send a logon request with
+ a username but no password when talking to a <command>security = share
+ </command> server). Instead, the clients send authentication information
+ (passwords) on a per-share basis, at the time they attempt to connect
+ to that share.</para>
+
+ <para>Note that <command>smbd</command> <emphasis>ALWAYS</emphasis>
+ uses a valid UNIX user to act on behalf of the client, even in
+ <command>security = share</command> level security.</para>
+
+ <para>As clients are not required to send a username to the server
+ in share level security, <command>smbd</command> uses several
+ techniques to determine the correct UNIX user to use on behalf
+ of the client.</para>
+
+ <para>A list of possible UNIX usernames to match with the given
+ client password is constructed using the following methods :</para>
+
+ <itemizedlist>
+ <listitem><para>If the <link linkend="GUESTONLY"><parameter>guest
+ only</parameter></link> parameter is set, then all the other
+ stages are missed and only the <link linkend="GUESTACCOUNT">
+ <parameter>guest account</parameter></link> username is checked.
+ </para></listitem>
+
+ <listitem><para>Is a username is sent with the share connection
+ request, then this username (after mapping - see <link
+ linkend="USERNAMEMAP"><parameter>username map</parameter></link>),
+ is added as a potential username.</para></listitem>
+
+ <listitem><para>If the client did a previous <emphasis>logon
+ </emphasis> request (the SessionSetup SMB call) then the
+ username sent in this SMB will be added as a potential username.
+ </para></listitem>
+
+ <listitem><para>The name of the service the client requested is
+ added as a potential username.</para></listitem>
+
+ <listitem><para>The NetBIOS name of the client is added to
+ the list as a potential username.</para></listitem>
+
+ <listitem><para>Any users on the <link linkend="USER"><parameter>
+ user</parameter></link> list are added as potential usernames.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>If the <parameter>guest only</parameter> parameter is
+ not set, then this list is then tried with the supplied password.
+ The first user for whom the password matches will be used as the
+ UNIX user.</para>
+
+ <para>If the <parameter>guest only</parameter> parameter is
+ set, or no username can be determined then if the share is marked
+ as available to the <parameter>guest account</parameter>, then this
+ guest user will be used, otherwise access is denied.</para>
+
+ <para>Note that it can be <emphasis>very</emphasis> confusing
+ in share-level security as to which UNIX username will eventually
+ be used in granting access.</para>
+
+ <para>See also the section <link linkend="VALIDATIONSECT">
+ NOTE ABOUT USERNAME/PASSWORD VALIDATION</link>.</para>
+
+ <para><anchor id="SECURITYEQUALSUSER"><emphasis>SECURITY = USER
+ </emphasis></para>
+
+ <para>This is the default security setting in Samba 2.2.
+ With user-level security a client must first "log-on" with a
+ valid username and password (which can be mapped using the <link
+ linkend="USERNAMEMAP"><parameter>username map</parameter></link>
+ parameter). Encrypted passwords (see the <link linkend="ENCRYPTPASSWORDS">
+ <parameter>encrypted passwords</parameter></link> parameter) can also
+ be used in this security mode. Parameters such as <link linkend="USER">
+ <parameter>user</parameter></link> and <link linkend="GUESTONLY">
+ <parameter>guest only</parameter></link> if set are then applied and
+ may change the UNIX user to use on this connection, but only after
+ the user has been successfully authenticated.</para>
+
+ <para><emphasis>Note</emphasis> that the name of the resource being
+ requested is <emphasis>not</emphasis> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <link
+ linkend="GUESTACCOUNT"><parameter>guest account</parameter></link>.
+ See the <link linkend="MAPTOGUEST"><parameter>map to guest</parameter>
+ </link> parameter for details on doing this.</para>
+
+ <para>See also the section <link linkend="VALIDATIONSECT">
+ NOTE ABOUT USERNAME/PASSWORD VALIDATION</link>.</para>
+
+ <para><anchor id="SECURITYEQUALSSERVER"><emphasis>SECURITY = SERVER
+ </emphasis></para>
+
+ <para>In this mode Samba will try to validate the username/password
+ by passing it to another SMB server, such as an NT box. If this
+ fails it will revert to <command>security = user</command>, but note
+ that if encrypted passwords have been negotiated then Samba cannot
+ revert back to checking the UNIX password file, it must have a valid
+ <filename>smbpasswd</filename> file to check users against. See the
+ documentation file in the <filename>docs/</filename> directory
+ <filename>ENCRYPTION.txt</filename> for details on how to set this
+ up.</para>
+
+ <para><emphasis>Note</emphasis> that from the client's point of
+ view <command>security = server</command> is the same as <command>
+ security = user</command>. It only affects how the server deals
+ with the authentication, it does not in any way affect what the
+ client sees.</para>
+
+ <para><emphasis>Note</emphasis> that the name of the resource being
+ requested is <emphasis>not</emphasis> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <link
+ linkend="GUESTACCOUNT"><parameter>guest account</parameter></link>.
+ See the <link linkend="MAPTOGUEST"><parameter>map to guest</parameter>
+ </link> parameter for details on doing this.</para>
+
+ <para>See also the section <link linkend="VALIDATIONSECT">
+ NOTE ABOUT USERNAME/PASSWORD VALIDATION</link>.</para>
+
+ <para>See also the <link linkend="PASSWORDSERVER"><parameter>password
+ server</parameter></link> parameter and the <link
+ linkend="ENCRYPTPASSWORDS"><parameter>encrypted passwords</parameter>
+ </link> parameter.</para>
+
+ <para><anchor id="SECURITYEQUALSDOMAIN"><emphasis>SECURITY = DOMAIN
+ </emphasis></para>
+
+ <para>This mode will only work correctly if <ulink
+ url="smbpasswd.8.html">smbpasswd(8)</ulink> has been used to add this
+ machine into a Windows NT Domain. It expects the <link
+ linkend="ENCRYPTPASSWORDS"><parameter>encrypted passwords</parameter>
+ </link> parameter to be set to <constant>yes</constant>. In this
+ mode Samba will try to validate the username/password by passing
+ it to a Windows NT Primary or Backup Domain Controller, in exactly
+ the same way that a Windows NT Server would do.</para>
+
+ <para><emphasis>Note</emphasis> that a valid UNIX user must still
+ exist as well as the account on the Domain Controller to allow
+ Samba to have a valid UNIX account to map file access to.</para>
+
+ <para><emphasis>Note</emphasis> that from the client's point
+ of view <command>security = domain</command> is the same as <command>security = user
+ </command>. It only affects how the server deals with the authentication,
+ it does not in any way affect what the client sees.</para>
+
+ <para><emphasis>Note</emphasis> that the name of the resource being
+ requested is <emphasis>not</emphasis> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <link
+ linkend="GUESTACCOUNT"><parameter>guest account</parameter></link>.
+ See the <link linkend="MAPTOGUEST"><parameter>map to guest</parameter>
+ </link> parameter for details on doing this.</para>
+
+ <para><emphasis>BUG:</emphasis> There is currently a bug in the
+ implementation of <command>security = domain</command> with respect
+ to multi-byte character set usernames. The communication with a
+ Domain Controller must be done in UNICODE and Samba currently
+ does not widen multi-byte user names to UNICODE correctly, thus
+ a multi-byte username will not be recognized correctly at the
+ Domain Controller. This issue will be addressed in a future release.</para>
+
+ <para>See also the section <link linkend="VALIDATIONSECT">
+ NOTE ABOUT USERNAME/PASSWORD VALIDATION</link>.</para>
+
+ <para>See also the <link linkend="PASSWORDSERVER"><parameter>password
+ server</parameter></link> parameter and the <link
+ linkend="ENCRYPTPASSWORDS"><parameter>encrypted passwords</parameter>
+ </link> parameter.</para>
+
+ <para>Default: <command>security = USER</command></para>
+ <para>Example: <command>security = DOMAIN</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SECURITYMASK">security mask (S)</term>
+ <listitem><para>This parameter controls what UNIX permission
+ bits can be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT security
+ dialog box.</para>
+
+ <para>This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits not in
+ this mask from being modified. Essentially, zero bits in this
+ mask may be treated as a set of bits the user is not allowed
+ to change.</para>
+
+ <para>If not set explicitly this parameter is 0777, allowing
+ a user to modify all the user/group/world permissions on a file.
+ </para>
+
+ <para><emphasis>Note</emphasis> that users who can access the
+ Samba server through other means can easily bypass this
+ restriction, so it is primarily useful for standalone
+ "appliance" systems. Administrators of most normal systems will
+ probably want to leave it set to <constant>0777</constant>.</para>
+
+ <para>See also the <link linkend="FORCEDIRECTORYSECURITYMODE">
+ <parameter>force directory security mode</parameter></link>,
+ <link linkend="DIRECTORYSECURITYMASK"><parameter>directory
+ security mask</parameter></link>, <link linkend="FORCESECURITYMODE">
+ <parameter>force security mode</parameter></link> parameters.</para>
+
+ <para>Default: <command>security mask = 0777</command></para>
+ <para>Example: <command>security mask = 0770</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SERVERSTRING">server string (G)</term>
+ <listitem><para>This controls what string will show up in the
+ printer comment box in print manager and next to the IPC connection
+ in <command>net view</command>. It can be any string that you wish
+ to show to your users.</para>
+
+ <para>It also sets what will appear in browse lists next
+ to the machine name.</para>
+
+ <para>A <parameter>%v</parameter> will be replaced with the Samba
+ version number.</para>
+
+ <para>A <parameter>%h</parameter> will be replaced with the
+ hostname.</para>
+
+ <para>Default: <command>server string = Samba %v</command></para>
+
+ <para>Example: <command>server string = University of GNUs Samba
+ Server</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SETDIRECTORY">set directory (S)</term>
+ <listitem><para>If <command>set directory = no</command>, then
+ users of the service may not use the setdir command to change
+ directory.</para>
+
+ <para>The <command>setdir</command> command is only implemented
+ in the Digital Pathworks client. See the Pathworks documentation
+ for details.</para>
+
+ <para>Default: <command>set directory = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SHAREMODES">share modes (S)</term>
+ <listitem><para>This enables or disables the honoring of
+ the <parameter>share modes</parameter> during a file open. These
+ modes are used by clients to gain exclusive read or write access
+ to a file.</para>
+
+ <para>These open modes are not directly supported by UNIX, so
+ they are simulated using shared memory, or lock files if your
+ UNIX doesn't support shared memory (almost all do).</para>
+
+ <para>The share modes that are enabled by this option are
+ <constant>DENY_DOS</constant>, <constant>DENY_ALL</constant>,
+ <constant>DENY_READ</constant>, <constant>DENY_WRITE</constant>,
+ <constant>DENY_NONE</constant> and <constant>DENY_FCB</constant>.
+ </para>
+
+ <para>This option gives full share compatibility and enabled
+ by default.</para>
+
+ <para>You should <emphasis>NEVER</emphasis> turn this parameter
+ off as many Windows applications will break if you do so.</para>
+
+ <para>Default: <command>share modes = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SHORTPRESERVECASE">short preserve case (S)</term>
+ <listitem><para>This boolean parameter controls if new files
+ which conform to 8.3 syntax, that is all in upper case and of
+ suitable length, are created upper case, or if they are forced
+ to be the <link linkend="DEFAULTCASE"><parameter>default case
+ </parameter></link>. This option can be use with <link
+ linkend="PRESERVECASE"><command>preserve case = yes</command>
+ </link> to permit long filenames to retain their case, while short
+ names are lowered. </para>
+
+ <para>See the section on <link linkend="NAMEMANGLINGSECT">
+ NAME MANGLING</link>.</para>
+
+ <para>Default: <command>short preserve case = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SHOWADDPRINTERWIZARD">show add printer wizard (G)</term>
+ <listitem><para>With the introduction of MS-RPC based printing support
+ for Windows NT/2000 client in Samba 2.2, a "Printers..." folder will
+ appear on Samba hosts in the share listing. Normally this folder will
+ contain an icon for the MS Add Printer Wizard (APW). However, it is
+ possible to disable this feature regardless of the level of privilege
+ of the connected user.</para>
+
+ <para>Under normal circumstances, the Windows NT/2000 client will
+ open a handle on the printer server with OpenPrinterEx() asking for
+ Administrator privileges. If the user does not have administrative
+ access on the print server (i.e is not root or a member of the
+ <parameter>printer admin</parameter> group), the OpenPrinterEx()
+ call fails and the client makes another open call with a request for
+ a lower privilege level. This should succeed, however the APW
+ icon will not be displayed.</para>
+
+ <para>Disabling the <parameter>show add printer wizard</parameter>
+ parameter will always cause the OpenPrinterEx() on the server
+ to fail. Thus the APW icon will never be displayed. <emphasis>
+ Note :</emphasis>This does not prevent the same user from having
+ administrative privilege on an individual printer.</para>
+
+ <para>See also <link linkend="ADDPRINTERCOMMAND"><parameter>addprinter
+ command</parameter></link>, <link linkend="DELETEPRINTERCOMMAND">
+ <parameter>deleteprinter command</parameter></link>, <link
+ linkend="PRINTERADMIN"><parameter>printer admin</parameter></link></para>
+
+ <para>Default :<command>show add printer wizard = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="SMBPASSWDFILE">smb passwd file (G)</term>
+ <listitem><para>This option sets the path to the encrypted
+ smbpasswd file. By default the path to the smbpasswd file
+ is compiled into Samba.</para>
+
+ <para>Default: <command>smb passwd file = ${prefix}/private/smbpasswd
+ </command></para>
+
+ <para>Example: <command>smb passwd file = /etc/samba/smbpasswd
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="SOCKETADDRESS">socket address (G)</term>
+ <listitem><para>This option allows you to control what
+ address Samba will listen for connections on. This is used to
+ support multiple virtual interfaces on the one server, each
+ with a different configuration.</para>
+
+ <para>By default Samba will accept connections on any
+ address.</para>
+
+ <para>Example: <command>socket address = 192.168.2.20</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SOCKETOPTIONS">socket options (G)</term>
+ <listitem><para>This option allows you to set socket options
+ to be used when talking with the client.</para>
+
+ <para>Socket options are controls on the networking layer
+ of the operating systems which allow the connection to be
+ tuned.</para>
+
+ <para>This option will typically be used to tune your Samba
+ server for optimal performance for your local network. There is
+ no way that Samba can know what the optimal parameters are for
+ your net, so you must experiment and choose them yourself. We
+ strongly suggest you read the appropriate documentation for your
+ operating system first (perhaps <command>man setsockopt</command>
+ will help).</para>
+
+ <para>You may find that on some systems Samba will say
+ "Unknown socket option" when you supply an option. This means you
+ either incorrectly typed it or you need to add an include file
+ to includes.h for your OS. If the latter is the case please
+ send the patch to <ulink url="mailto:samba@samba.org">
+ samba@samba.org</ulink>.</para>
+
+ <para>Any of the supported socket options may be combined
+ in any way you like, as long as your OS allows it.</para>
+
+ <para>This is the list of socket options currently settable
+ using this option:</para>
+
+ <itemizedlist>
+ <listitem><para>SO_KEEPALIVE</para></listitem>
+ <listitem><para>SO_REUSEADDR</para></listitem>
+ <listitem><para>SO_BROADCAST</para></listitem>
+ <listitem><para>TCP_NODELAY</para></listitem>
+ <listitem><para>IPTOS_LOWDELAY</para></listitem>
+ <listitem><para>IPTOS_THROUGHPUT</para></listitem>
+ <listitem><para>SO_SNDBUF *</para></listitem>
+ <listitem><para>SO_RCVBUF *</para></listitem>
+ <listitem><para>SO_SNDLOWAT *</para></listitem>
+ <listitem><para>SO_RCVLOWAT *</para></listitem>
+ </itemizedlist>
+
+ <para>Those marked with a <emphasis>'*'</emphasis> take an integer
+ argument. The others can optionally take a 1 or 0 argument to enable
+ or disable the option, by default they will be enabled if you
+ don't specify 1 or 0.</para>
+
+ <para>To specify an argument use the syntax SOME_OPTION = VALUE
+ for example <command>SO_SNDBUF = 8192</command>. Note that you must
+ not have any spaces before or after the = sign.</para>
+
+ <para>If you are on a local network then a sensible option
+ might be</para>
+ <para><command>socket options = IPTOS_LOWDELAY</command></para>
+
+ <para>If you have a local network then you could try:</para>
+ <para><command>socket options = IPTOS_LOWDELAY TCP_NODELAY</command></para>
+
+ <para>If you are on a wide area network then perhaps try
+ setting IPTOS_THROUGHPUT. </para>
+
+ <para>Note that several of the options may cause your Samba
+ server to fail completely. Use these options with caution!</para>
+
+ <para>Default: <command>socket options = TCP_NODELAY</command></para>
+ <para>Example: <command>socket options = IPTOS_LOWDELAY</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="SOURCEENVIRONMENT">source environment (G)</term>
+ <listitem><para>This parameter causes Samba to set environment
+ variables as per the content of the file named.</para>
+
+ <para>If the value of this parameter starts with a "|" character
+ then Samba will treat that value as a pipe command to open and
+ will set the environment variables from the output of the pipe.</para>
+
+ <para>The contents of the file or the output of the pipe should
+ be formatted as the output of the standard Unix <command>env(1)
+ </command> command. This is of the form :</para>
+ <para>Example environment entry:</para>
+ <para><command>SAMBA_NETBIOS_NAME = myhostname</command></para>
+
+ <para>Default: <emphasis>No default value</emphasis></para>
+ <para>Examples: <command>source environment = |/etc/smb.conf.sh
+ </command></para>
+
+ <para>Example: <command>source environment =
+ /usr/local/smb_env_vars</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSL">ssl (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This variable enables or disables the entire SSL mode. If
+ it is set to <constant>no</constant>, the SSL-enabled Samba behaves
+ exactly like the non-SSL Samba. If set to <constant>yes</constant>,
+ it depends on the variables <link linkend="SSLHOSTS"><parameter>
+ ssl hosts</parameter></link> and <link linkend="SSLHOSTSRESIGN">
+ <parameter>ssl hosts resign</parameter></link> whether an SSL
+ connection will be required.</para>
+
+ <para>Default: <command>ssl = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLCACERTDIR">ssl CA certDir (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This variable defines where to look up the Certification
+ Authorities. The given directory should contain one file for
+ each CA that Samba will trust. The file name must be the hash
+ value over the "Distinguished Name" of the CA. How this directory
+ is set up is explained later in this document. All files within the
+ directory that don't fit into this naming scheme are ignored. You
+ don't need this variable if you don't verify client certificates.</para>
+
+ <para>Default: <command>ssl CA certDir = /usr/local/ssl/certs
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLCACERTFILE">ssl CA certFile (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This variable is a second way to define the trusted CAs.
+ The certificates of the trusted CAs are collected in one big
+ file and this variable points to the file. You will probably
+ only use one of the two ways to define your CAs. The first choice is
+ preferable if you have many CAs or want to be flexible, the second
+ is preferable if you only have one CA and want to keep things
+ simple (you won't need to create the hashed file names). You
+ don't need this variable if you don't verify client certificates.</para>
+
+ <para>Default: <command>ssl CA certFile = /usr/local/ssl/certs/trustedCAs.pem
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLCIPHERS">ssl ciphers (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This variable defines the ciphers that should be offered
+ during SSL negotiation. You should not set this variable unless
+ you know what you are doing.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLCLIENTCERT">ssl client cert (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>The certificate in this file is used by <ulink url="smbclient.1.html">
+ <command>smbclient(1)</command></ulink> if it exists. It's needed
+ if the server requires a client certificate.</para>
+
+ <para>Default: <command>ssl client cert = /usr/local/ssl/certs/smbclient.pem
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLCLIENTKEY">ssl client key (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This is the private key for <ulink url="smbclient.1.html">
+ <command>smbclient(1)</command></ulink>. It's only needed if the
+ client should have a certificate. </para>
+
+ <para>Default: <command>ssl client key = /usr/local/ssl/private/smbclient.pem
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLCOMPATIBILITY">ssl compatibility (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This variable defines whether OpenSSL should be configured
+ for bug compatibility with other SSL implementations. This is
+ probably not desirable because currently no clients with SSL
+ implementations other than OpenSSL exist.</para>
+
+ <para>Default: <command>ssl compatibility = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLEGDSOCKET">ssl egd socket (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>
+ This option is used to define the location of the communiation socket of
+ an EGD or PRNGD daemon, from which entropy can be retrieved. This option
+ can be used instead of or together with the <link
+ linkend="SSLENTROPYFILE"><parameter>ssl entropy file</parameter></link>
+ directive. 255 bytes of entropy will be retrieved from the daemon.
+ </para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLENTROPYBYTES">ssl entropy bytes (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>
+ This parameter is used to define the number of bytes which should
+ be read from the <link linkend="SSLENTROPYFILE"><parameter>ssl entropy
+ file</parameter></link> If a -1 is specified, the entire file will
+ be read.
+ </para>
+
+ <para>Default: <command>ssl entropy bytes = 255</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLENTROPYFILE">ssl entropy file (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>
+ This parameter is used to specify a file from which processes will
+ read "random bytes" on startup. In order to seed the internal pseudo
+ random number generator, entropy must be provided. On system with a
+ <filename>/dev/urandom</filename> device file, the processes
+ will retrieve its entropy from the kernel. On systems without kernel
+ entropy support, a file can be supplied that will be read on startup
+ and that will be used to seed the PRNG.
+ </para>
+
+ <para>Default: <emphasis>none</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLHOSTS">ssl hosts (G)</term>
+ <listitem><para>See <link linkend="SSLHOSTSRESIGN"><parameter>
+ ssl hosts resign</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLHOSTSRESIGN">ssl hosts resign (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>These two variables define whether Samba will go
+ into SSL mode or not. If none of them is defined, Samba will
+ allow only SSL connections. If the <link linkend="SSLHOSTS">
+ <parameter>ssl hosts</parameter></link> variable lists
+ hosts (by IP-address, IP-address range, net group or name),
+ only these hosts will be forced into SSL mode. If the <parameter>
+ ssl hosts resign</parameter> variable lists hosts, only these
+ hosts will <emphasis>NOT</emphasis> be forced into SSL mode. The syntax for these two
+ variables is the same as for the <link linkend="HOSTSALLOW"><parameter>
+ hosts allow</parameter></link> and <link linkend="HOSTSDENY">
+ <parameter>hosts deny</parameter></link> pair of variables, only
+ that the subject of the decision is different: It's not the access
+ right but whether SSL is used or not. </para>
+
+ <para>The example below requires SSL connections from all hosts
+ outside the local net (which is 192.168.*.*).</para>
+
+ <para>Default: <command>ssl hosts = &lt;empty string&gt;</command></para>
+ <para><command>ssl hosts resign = &lt;empty string&gt;</command></para>
+
+ <para>Example: <command>ssl hosts resign = 192.168.</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLREQUIRECLIENTCERT">ssl require clientcert (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>If this variable is set to <constant>yes</constant>, the
+ server will not tolerate connections from clients that don't
+ have a valid certificate. The directory/file given in <link
+ linkend="SSLCACERTDIR"><parameter>ssl CA certDir</parameter>
+ </link> and <link linkend="SSLCACERTFILE"><parameter>ssl CA certFile
+ </parameter></link> will be used to look up the CAs that issued
+ the client's certificate. If the certificate can't be verified
+ positively, the connection will be terminated. If this variable
+ is set to <constant>no</constant>, clients don't need certificates.
+ Contrary to web applications you really <emphasis>should</emphasis>
+ require client certificates. In the web environment the client's
+ data is sensitive (credit card numbers) and the server must prove
+ to be trustworthy. In a file server environment the server's data
+ will be sensitive and the clients must prove to be trustworthy.</para>
+
+ <para>Default: <command>ssl require clientcert = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SSLREQUIRESERVERCERT">ssl require servercert (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>If this variable is set to <constant>yes</constant>, the
+ <ulink url="smbclient.1.html"><command>smbclient(1)</command>
+ </ulink> will request a certificate from the server. Same as
+ <link linkend="SSLREQUIRECLIENTCERT"><parameter>ssl require
+ clientcert</parameter></link> for the server.</para>
+
+ <para>Default: <command>ssl require servercert = no</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="SSLSERVERCERT">ssl server cert (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This is the file containing the server's certificate.
+ The server <emphasis>must</emphasis> have a certificate. The
+ file may also contain the server's private key. See later for
+ how certificates and private keys are created.</para>
+
+ <para>Default: <command>ssl server cert = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLSERVERKEY">ssl server key (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This file contains the private key of the server. If
+ this variable is not defined, the key is looked up in the
+ certificate file (it may be appended to the certificate).
+ The server <emphasis>must</emphasis> have a private key
+ and the certificate <emphasis>must</emphasis>
+ match this private key.</para>
+
+ <para>Default: <command>ssl server key = &lt;empty string&gt;
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="SSLVERSION">ssl version (G)</term>
+ <listitem><para>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <command>--with-ssl</command> was
+ given at configure time.</para>
+
+ <para>This enumeration variable defines the versions of the
+ SSL protocol that will be used. <constant>ssl2or3</constant> allows
+ dynamic negotiation of SSL v2 or v3, <constant>ssl2</constant> results
+ in SSL v2, <constant>ssl3</constant> results in SSL v3 and
+ <constant>tls1</constant> results in TLS v1. TLS (Transport Layer
+ Security) is the new standard for SSL.</para>
+
+ <para>Default: <command>ssl version = "ssl2or3"</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="STATCACHE">stat cache (G)</term>
+ <listitem><para>This parameter determines if <ulink
+ url="smbd.8.html">smbd(8)</ulink> will use a cache in order to
+ speed up case insensitive name mappings. You should never need
+ to change this parameter.</para>
+
+ <para>Default: <command>stat cache = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="STATCACHESIZE">stat cache size (G)</term>
+ <listitem><para>This parameter determines the number of
+ entries in the <parameter>stat cache</parameter>. You should
+ never need to change this parameter.</para>
+
+ <para>Default: <command>stat cache size = 50</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="STATUS">status (G)</term>
+ <listitem><para>This enables or disables logging of connections
+ to a status file that <ulink url="smbstatus.1.html">smbstatus(1)</ulink>
+ can read.</para>
+
+ <para>With this disabled <command>smbstatus</command> won't be able
+ to tell you what connections are active. You should never need to
+ change this parameter.</para>
+
+ <para>Default: <command>status = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="STRICTALLOCATE">strict allocate (S)</term>
+ <listitem><para>This is a boolean that controls the handling of
+ disk space allocation in the server. When this is set to <constant>yes</constant>
+ the server will change from UNIX behaviour of not committing real
+ disk storage blocks when a file is extended to the Windows behaviour
+ of actually forcing the disk system to allocate real storage blocks
+ when a file is created or extended to be a given size. In UNIX
+ terminology this means that Samba will stop creating sparse files.
+ This can be slow on some systems.</para>
+
+ <para>When strict allocate is <constant>no</constant> the server does sparse
+ disk block allocation when a file is extended.</para>
+
+ <para>Setting this to <constant>yes</constant> can help Samba return
+ out of quota messages on systems that are restricting the disk quota
+ of users.</para>
+
+ <para>Default: <command>strict allocate = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="STRICTLOCKING">strict locking (S)</term>
+ <listitem><para>This is a boolean that controls the handling of
+ file locking in the server. When this is set to <constant>yes</constant>
+ the server will check every read and write access for file locks, and
+ deny access if locks exist. This can be slow on some systems.</para>
+
+ <para>When strict locking is <constant>no</constant> the server does file
+ lock checks only when the client explicitly asks for them.</para>
+
+ <para>Well-behaved clients always ask for lock checks when it
+ is important, so in the vast majority of cases <command>strict
+ locking = no</command> is preferable.</para>
+
+ <para>Default: <command>strict locking = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="STRICTSYNC">strict sync (S)</term>
+ <listitem><para>Many Windows applications (including the Windows
+ 98 explorer shell) seem to confuse flushing buffer contents to
+ disk with doing a sync to disk. Under UNIX, a sync call forces
+ the process to be suspended until the kernel has ensured that
+ all outstanding data in kernel disk buffers has been safely stored
+ onto stable storage. This is very slow and should only be done
+ rarely. Setting this parameter to <constant>no</constant> (the
+ default) means that <ulink url="smbd.8.html">smbd</ulink> ignores the Windows applications requests for
+ a sync call. There is only a possibility of losing data if the
+ operating system itself that Samba is running on crashes, so there is
+ little danger in this default setting. In addition, this fixes many
+ performance problems that people have reported with the new Windows98
+ explorer shell file copies.</para>
+
+ <para>See also the <link linkend="SYNCALWAYS"><parameter>sync
+ always></parameter></link> parameter.</para>
+
+ <para>Default: <command>strict sync = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="STRIPDOT">strip dot (G)</term>
+ <listitem><para>This parameter is now unused in Samba (2.2.5 and above).
+ It used strip trailing dots off UNIX filenames but was not correctly implmented.
+ In Samba 2.2.5 and above UNIX filenames ending in a dot are invalid Windows long
+ filenames (as they are in Windows NT and above) and are mangled to 8.3 before
+ being returned to a client.</para>
+
+ <para>Default: <command>strip dot = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SYNCALWAYS">sync always (S)</term>
+ <listitem><para>This is a boolean parameter that controls
+ whether writes will always be written to stable storage before
+ the write call returns. If this is <constant>no</constant> then the server will be
+ guided by the client's request in each write call (clients can
+ set a bit indicating that a particular write should be synchronous).
+ If this is <constant>yes</constant> then every write will be followed by a <command>fsync()
+ </command> call to ensure the data is written to disk. Note that
+ the <parameter>strict sync</parameter> parameter must be set to
+ <constant>yes</constant> in order for this parameter to have
+ any affect.</para>
+
+ <para>See also the <link linkend="STRICTSYNC"><parameter>strict
+ sync</parameter></link> parameter.</para>
+
+ <para>Default: <command>sync always = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SYSLOG">syslog (G)</term>
+ <listitem><para>This parameter maps how Samba debug messages
+ are logged onto the system syslog logging levels. Samba debug
+ level zero maps onto syslog <constant>LOG_ERR</constant>, debug
+ level one maps onto <constant>LOG_WARNING</constant>, debug level
+ two maps onto <constant>LOG_NOTICE</constant>, debug level three
+ maps onto LOG_INFO. All higher levels are mapped to <constant>
+ LOG_DEBUG</constant>.</para>
+
+ <para>This parameter sets the threshold for sending messages
+ to syslog. Only messages with debug level less than this value
+ will be sent to syslog.</para>
+
+ <para>Default: <command>syslog = 1</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="SYSLOGONLY">syslog only (G)</term>
+ <listitem><para>If this parameter is set then Samba debug
+ messages are logged into the system syslog only, and not to
+ the debug log files.</para>
+
+ <para>Default: <command>syslog only = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="TEMPLATEHOMEDIR">template homedir (G)</term>
+ <listitem><para>When filling out the user information for a Windows NT
+ user, the <ulink url="winbindd.8.html">winbindd(8)</ulink> daemon
+ uses this parameter to fill in the home directory for that user.
+ If the string <parameter>%D</parameter> is present it is substituted
+ with the user's Windows NT domain name. If the string <parameter>%U
+ </parameter> is present it is substituted with the user's Windows
+ NT user name.</para>
+
+ <para>Default: <command>template homedir = /home/%D/%U</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="TEMPLATESHELL">template shell (G)</term>
+ <listitem><para>When filling out the user information for a Windows NT
+ user, the <ulink url="winbindd.8.html">winbindd(8)</ulink> daemon
+ uses this parameter to fill in the login shell for that user.</para>
+
+ <para>Default: <command>template shell = /bin/false</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="TIMEOFFSET">time offset (G)</term>
+ <listitem><para>This parameter is a setting in minutes to add
+ to the normal GMT to local time conversion. This is useful if
+ you are serving a lot of PCs that have incorrect daylight
+ saving time handling.</para>
+
+ <para>Default: <command>time offset = 0</command></para>
+ <para>Example: <command>time offset = 60</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="TIMESERVER">time server (G)</term>
+ <listitem><para>This parameter determines if <ulink url="nmbd.8.html">
+ nmbd(8)</ulink> advertises itself as a time server to Windows
+ clients.</para>
+
+ <para>Default: <command>time server = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="TIMESTAMPLOGS">timestamp logs (G)</term>
+ <listitem><para>Synonym for <link linkend="DEBUGTIMESTAMP"><parameter>
+ debug timestamp</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="TOTALPRINTJOBS">total print jobs (G)</term>
+ <listitem><para>This parameter accepts an integer value which defines
+ a limit on the maximum number of print jobs that will be accepted
+ system wide at any given time. If a print job is submitted
+ by a client which will exceed this number, then <ulink url="smbd.8.html">smbd</ulink> will return an
+ error indicating that no space is available on the server. The
+ default value of 0 means that no such limit exists. This parameter
+ can be used to prevent a server from exceeding its capacity and is
+ designed as a printing throttle. See also
+ <link linkend="MAXPRINTJOBS"><parameter>max print jobs</parameter</link>.
+ </para>
+
+ <para>Default: <command>total print jobs = 0</command></para>
+ <para>Example: <command>total print jobs = 5000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="UNIXEXTENSIONS">unix extensions(G)</term>
+ <listitem><para>This boolean parameter controls whether Samba
+ implments the CIFS UNIX extensions, as defined by HP.
+ These extensions enable Samba to better serve UNIX CIFS clients
+ by supporting features such as symbolic links, hard links, etc...
+ These extensions require a similarly enabled client, and are of
+ no current use to Windows clients.</para>
+
+ <para>Default: <command>unix extensions = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="UNIXPASSWORDSYNC">unix password sync (G)</term>
+ <listitem><para>This boolean parameter controls whether Samba
+ attempts to synchronize the UNIX password with the SMB password
+ when the encrypted SMB password in the smbpasswd file is changed.
+ If this is set to <constant>yes</constant> the program specified in the <parameter>passwd
+ program</parameter>parameter is called <emphasis>AS ROOT</emphasis> -
+ to allow the new UNIX password to be set without access to the
+ old UNIX password (as the SMB password change code has no
+ access to the old password cleartext, only the new).</para>
+
+ <para>See also <link linkend="PASSWDPROGRAM"><parameter>passwd
+ program</parameter></link>, <link linkend="PASSWDCHAT"><parameter>
+ passwd chat</parameter></link>.</para>
+
+ <para>Default: <command>unix password sync = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="UPDATEENCRYPTED">update encrypted (G)</term>
+ <listitem><para>This boolean parameter allows a user logging
+ on with a plaintext password to have their encrypted (hashed)
+ password in the smbpasswd file to be updated automatically as
+ they log on. This option allows a site to migrate from plaintext
+ password authentication (users authenticate with plaintext
+ password over the wire, and are checked against a UNIX account
+ database) to encrypted password authentication (the SMB
+ challenge/response authentication mechanism) without forcing
+ all users to re-enter their passwords via smbpasswd at the time the
+ change is made. This is a convenience option to allow the change over
+ to encrypted passwords to be made over a longer period. Once all users
+ have encrypted representations of their passwords in the smbpasswd
+ file this parameter should be set to <constant>no</constant>.</para>
+
+ <para>In order for this parameter to work correctly the <link
+ linkend="ENCRYPTPASSWORDS"><parameter>encrypt passwords</parameter>
+ </link> parameter must be set to <constant>no</constant> when
+ this parameter is set to <constant>yes</constant>.</para>
+
+ <para>Note that even when this parameter is set a user
+ authenticating to <command>smbd</command> must still enter a valid
+ password in order to connect correctly, and to update their hashed
+ (smbpasswd) passwords.</para>
+
+ <para>Default: <command>update encrypted = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="USECLIENTDRIVER">use client driver (S)</term>
+ <listitem><para>This parameter applies only to Windows NT/2000
+ clients. It has no affect on Windows 95/98/ME clients. When
+ serving a printer to Windows NT/2000 clients without first installing
+ a valid printer driver on the Samba host, the client will be required
+ to install a local printer driver. From this point on, the client
+ will treat the print as a local printer and not a network printer
+ connection. This is much the same behavior that will occur
+ when <command>disable spoolss = yes</command>. </para>
+
+ <para>The differentiating
+ factor is that under normal circumstances, the NT/2000 client will
+ attempt to open the network printer using MS-RPC. The problem is that
+ because the client considers the printer to be local, it will attempt
+ to issue the OpenPrinterEx() call requesting access rights associated
+ with the logged on user. If the user possesses local administator rights
+ but not root privilegde on the Samba host (often the case), the OpenPrinterEx()
+ call will fail. The result is that the client will now display an "Access
+ Denied; Unable to connect" message in the printer queue window (even though
+ jobs may successfully be printed). </para>
+
+ <para>If this parameter is enabled for a printer, then any attempt
+ to open the printer with the PRINTER_ACCESS_ADMINISTER right is mapped
+ to PRINTER_ACCESS_USE instead. Thus allowing the OpenPrinterEx()
+ call to succeed. <emphasis>This parameter MUST not be able enabled
+ on a print share which has valid print driver installed on the Samba
+ server.</emphasis></para>
+
+ <para>See also <link linkend="DISABLESPOOLSS">disable spoolss</link>
+ </para>
+
+ <para>Default: <command>use client driver = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="USEMMAP">use mmap (G)</term>
+ <listitem><para>This global parameter determines if the tdb internals of Samba can
+ depend on mmap working correctly on the running system. Samba requires a coherent
+ mmap/read-write system memory cache. Currently only HPUX does not have such a
+ coherent cache, and so this parameter is set to <constant>no</constant> by
+ default on HPUX. On all other systems this parameter should be left alone. This
+ parameter is provided to help the Samba developers track down problems with
+ the tdb internal code.
+ </para>
+
+ <para>Default: <command>use mmap = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="USERHOSTS">use rhosts (G)</term>
+ <listitem><para>If this global parameter is <constant>yes</constant>, it specifies
+ that the UNIX user's <filename>.rhosts</filename> file in their home directory
+ will be read to find the names of hosts and users who will be allowed
+ access without specifying a password.</para>
+
+ <para><emphasis>NOTE:</emphasis> The use of <parameter>use rhosts
+ </parameter> can be a major security hole. This is because you are
+ trusting the PC to supply the correct username. It is very easy to
+ get a PC to supply a false username. I recommend that the <parameter>
+ use rhosts</parameter> option be only used if you really know what
+ you are doing.</para>
+
+ <para>Default: <command>use rhosts = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="USER">user (S)</term>
+ <listitem><para>Synonym for <link linkend="USERNAME"><parameter>
+ username</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="USERS">users (S)</term>
+ <listitem><para>Synonym for <link linkend="USERNAME"><parameter>
+ username</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="USERNAME">username (S)</term>
+ <listitem><para>Multiple users may be specified in a comma-delimited
+ list, in which case the supplied password will be tested against
+ each username in turn (left to right).</para>
+
+ <para>The <parameter>username</parameter> line is needed only when
+ the PC is unable to supply its own username. This is the case
+ for the COREPLUS protocol or where your users have different WfWg
+ usernames to UNIX usernames. In both these cases you may also be
+ better using the \\server\share%user syntax instead.</para>
+
+ <para>The <parameter>username</parameter> line is not a great
+ solution in many cases as it means Samba will try to validate
+ the supplied password against each of the usernames in the
+ <parameter>username</parameter> line in turn. This is slow and
+ a bad idea for lots of users in case of duplicate passwords.
+ You may get timeouts or security breaches using this parameter
+ unwisely.</para>
+
+ <para>Samba relies on the underlying UNIX security. This
+ parameter does not restrict who can login, it just offers hints
+ to the Samba server as to what usernames might correspond to the
+ supplied password. Users can login as whoever they please and
+ they will be able to do no more damage than if they started a
+ telnet session. The daemon runs as the user that they log in as,
+ so they cannot do anything that user cannot do.</para>
+
+ <para>To restrict a service to a particular set of users you
+ can use the <link linkend="VALIDUSERS"><parameter>valid users
+ </parameter></link> parameter.</para>
+
+ <para>If any of the usernames begin with a '@' then the name
+ will be looked up first in the NIS netgroups list (if Samba
+ is compiled with netgroup support), followed by a lookup in
+ the UNIX groups database and will expand to a list of all users
+ in the group of that name.</para>
+
+ <para>If any of the usernames begin with a '+' then the name
+ will be looked up only in the UNIX groups database and will
+ expand to a list of all users in the group of that name.</para>
+
+ <para>If any of the usernames begin with a '&'then the name
+ will be looked up only in the NIS netgroups database (if Samba
+ is compiled with netgroup support) and will expand to a list
+ of all users in the netgroup group of that name.</para>
+
+ <para>Note that searching though a groups database can take
+ quite some time, and some clients may time out during the
+ search.</para>
+
+ <para>See the section <link linkend="VALIDATIONSECT">NOTE ABOUT
+ USERNAME/PASSWORD VALIDATION</link> for more information on how
+ this parameter determines access to the services.</para>
+
+ <para>Default: <command>The guest account if a guest service,
+ else &lt;empty string&gt;.</command></para>
+
+ <para>Examples:<command>username = fred, mary, jack, jane,
+ @users, @pcgroup</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="USERNAMELEVEL">username level (G)</term>
+ <listitem><para>This option helps Samba to try and 'guess' at
+ the real UNIX username, as many DOS clients send an all-uppercase
+ username. By default Samba tries all lowercase, followed by the
+ username with the first letter capitalized, and fails if the
+ username is not found on the UNIX machine.</para>
+
+ <para>If this parameter is set to non-zero the behavior changes.
+ This parameter is a number that specifies the number of uppercase
+ combinations to try while trying to determine the UNIX user name. The
+ higher the number the more combinations will be tried, but the slower
+ the discovery of usernames will be. Use this parameter when you have
+ strange usernames on your UNIX machine, such as <constant>AstrangeUser
+ </constant>.</para>
+
+ <para>Default: <command>username level = 0</command></para>
+ <para>Example: <command>username level = 5</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="USERNAMEMAP">username map (G)</term>
+ <listitem><para>This option allows you to specify a file containing
+ a mapping of usernames from the clients to the server. This can be
+ used for several purposes. The most common is to map usernames
+ that users use on DOS or Windows machines to those that the UNIX
+ box uses. The other is to map multiple users to a single username
+ so that they can more easily share files.</para>
+
+ <para>The map file is parsed line by line. Each line should
+ contain a single UNIX username on the left then a '=' followed
+ by a list of usernames on the right. The list of usernames on the
+ right may contain names of the form @group in which case they
+ will match any UNIX username in that group. The special client
+ name '*' is a wildcard and matches any name. Each line of the
+ map file may be up to 1023 characters long.</para>
+
+ <para>The file is processed on each line by taking the
+ supplied username and comparing it with each username on the right
+ hand side of the '=' signs. If the supplied name matches any of
+ the names on the right hand side then it is replaced with the name
+ on the left. Processing then continues with the next line.</para>
+
+ <para>If any line begins with a '#' or a ';' then it is
+ ignored</para>
+
+ <para>If any line begins with an '!' then the processing
+ will stop after that line if a mapping was done by the line.
+ Otherwise mapping continues with every line being processed.
+ Using '!' is most useful when you have a wildcard mapping line
+ later in the file.</para>
+
+ <para>For example to map from the name <constant>admin</constant>
+ or <constant>administrator</constant> to the UNIX name <constant>
+ root</constant> you would use:</para>
+
+ <para><command>root = admin administrator</command></para>
+
+ <para>Or to map anyone in the UNIX group <constant>system</constant>
+ to the UNIX name <constant>sys</constant> you would use:</para>
+
+ <para><command>sys = @system</command></para>
+
+ <para>You can have as many mappings as you like in a username
+ map file.</para>
+
+
+ <para>If your system supports the NIS NETGROUP option then
+ the netgroup database is checked before the <filename>/etc/group
+ </filename> database for matching groups.</para>
+
+ <para>You can map Windows usernames that have spaces in them
+ by using double quotes around the name. For example:</para>
+
+ <para><command>tridge = "Andrew Tridgell"</command></para>
+
+ <para>would map the windows username "Andrew Tridgell" to the
+ unix username "tridge".</para>
+
+ <para>The following example would map mary and fred to the
+ unix user sys, and map the rest to guest. Note the use of the
+ '!' to tell Samba to stop processing if it gets a match on
+ that line.</para>
+
+ <para><programlisting>
+ !sys = mary fred
+ guest = *
+ </programlisting></para>
+
+ <para>Note that the remapping is applied to all occurrences
+ of usernames. Thus if you connect to \\server\fred and <constant>
+ fred</constant> is remapped to <constant>mary</constant> then you
+ will actually be connecting to \\server\mary and will need to
+ supply a password suitable for <constant>mary</constant> not
+ <constant>fred</constant>. The only exception to this is the
+ username passed to the <link linkend="PASSWORDSERVER"><parameter>
+ password server</parameter></link> (if you have one). The password
+ server will receive whatever username the client supplies without
+ modification.</para>
+
+ <para>Also note that no reverse mapping is done. The main effect
+ this has is with printing. Users who have been mapped may have
+ trouble deleting print jobs as PrintManager under WfWg will think
+ they don't own the print job.</para>
+
+ <para>Default: <emphasis>no username map</emphasis></para>
+ <para>Example: <command>username map = /usr/local/samba/lib/users.map
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="USESENDFILE">use sendfile (S)</term>
+ <listitem><para>If this parameter is <constant>yes</constant>, and Samba
+ was built with the --with-sendfile-support option, and the underlying operating
+ system supports sendfile system call, then some SMB read calls (mainly ReadAndX
+ and ReadRaw) will use the more efficient sendfile system call for files that
+ are exclusively oplocked. This may make more efficient use of the system CPU's
+ and cause Samba to be faster. This is off by default as it's effects are unknown
+ as yet.
+ </para>
+
+ <para>Default: <command>use sendfile = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="UTMP">utmp (G)</term>
+ <listitem><para>This boolean parameter is only available if
+ Samba has been configured and compiled with the option <command>
+ --with-utmp</command>. If set to <constant>yes</constant> then Samba will attempt
+ to add utmp or utmpx records (depending on the UNIX system) whenever a
+ connection is made to a Samba server. Sites may use this to record the
+ user connecting to a Samba share.</para>
+
+ <para>See also the <link linkend="UTMPDIRECTORY"><parameter>
+ utmp directory</parameter></link> parameter.</para>
+
+ <para>Default: <command>utmp = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="UTMPDIRECTORY">utmp directory(G)</term>
+ <listitem><para>This parameter is only available if Samba has
+ been configured and compiled with the option <command>
+ --with-utmp</command>. It specifies a directory pathname that is
+ used to store the utmp or utmpx files (depending on the UNIX system) that
+ record user connections to a Samba server. See also the <link linkend="UTMP">
+ <parameter>utmp</parameter></link> parameter. By default this is
+ not set, meaning the system will use whatever utmp file the
+ native system is set to use (usually
+ <filename>/var/run/utmp</filename> on Linux).</para>
+
+ <para>Default: <emphasis>no utmp directory</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="VALIDCHARS">valid chars (G)</term>
+ <listitem><para>The option allows you to specify additional
+ characters that should be considered valid by the server in
+ filenames. This is particularly useful for national character
+ sets, such as adding u-umlaut or a-ring.</para>
+
+ <para>The option takes a list of characters in either integer
+ or character form with spaces between them. If you give two
+ characters with a colon between them then it will be taken as
+ an lowercase:uppercase pair.</para>
+
+ <para>If you have an editor capable of entering the characters
+ into the config file then it is probably easiest to use this
+ method. Otherwise you can specify the characters in octal,
+ decimal or hexadecimal form using the usual C notation.</para>
+
+ <para>For example to add the single character 'Z' to the charset
+ (which is a pointless thing to do as it's already there) you could
+ do one of the following</para>
+
+ <para><programlisting>
+ valid chars = Z
+ valid chars = z:Z
+ valid chars = 0132:0172
+ </programlisting></para>
+
+ <para>The last two examples above actually add two characters,
+ and alter the uppercase and lowercase mappings appropriately.</para>
+
+ <para>Note that you <emphasis>MUST</emphasis> specify this parameter
+ after the <parameter>client code page</parameter> parameter if you
+ have both set. If <parameter>client code page</parameter> is set after
+ the <parameter>valid chars</parameter> parameter the <parameter>valid
+ chars</parameter> settings will be overwritten.</para>
+
+ <para>See also the <link linkend="CLIENTCODEPAGE"><parameter>client
+ code page</parameter></link> parameter.</para>
+
+ <para>Default: <emphasis>Samba defaults to using a reasonable set
+ of valid characters for English systems</emphasis></para>
+
+ <para>Example: <command>valid chars = 0345:0305 0366:0326 0344:0304
+ </command></para>
+
+ <para>The above example allows filenames to have the Swedish
+ characters in them.</para>
+
+ <para><emphasis>NOTE:</emphasis> It is actually quite difficult to
+ correctly produce a <parameter>valid chars</parameter> line for
+ a particular system. To automate the process <ulink
+ url="mailto:tino@augsburg.net">tino@augsburg.net</ulink> has written
+ a package called <command>validchars</command> which will automatically
+ produce a complete <parameter>valid chars</parameter> line for
+ a given client system. Look in the <filename>examples/validchars/
+ </filename> subdirectory of your Samba source code distribution
+ for this package.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="VALIDUSERS">valid users (S)</term>
+ <listitem><para>This is a list of users that should be allowed
+ to login to this service. Names starting with '@', '+' and '&'
+ are interpreted using the same rules as described in the
+ <parameter>invalid users</parameter> parameter.</para>
+
+ <para>If this is empty (the default) then any user can login.
+ If a username is in both this list and the <parameter>invalid
+ users</parameter> list then access is denied for that user.</para>
+
+ <para>The current servicename is substituted for <parameter>%S
+ </parameter>. This is useful in the [homes] section.</para>
+
+ <para>See also <link linkend="INVALIDUSERS"><parameter>invalid users
+ </parameter></link></para>
+
+ <para>Default: <emphasis>No valid users list (anyone can login)
+ </emphasis></para>
+
+ <para>Example: <command>valid users = greg, @pcusers</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="VETOFILES">veto files(S)</term>
+ <listitem><para>This is a list of files and directories that
+ are neither visible nor accessible. Each entry in the list must
+ be separated by a '/', which allows spaces to be included
+ in the entry. '*' and '?' can be used to specify multiple files
+ or directories as in DOS wildcards.</para>
+
+ <para>Each entry must be a unix path, not a DOS path and
+ must <emphasis>not</emphasis> include the unix directory
+ separator '/'.</para>
+
+ <para>Note that the <parameter>case sensitive</parameter> option
+ is applicable in vetoing files.</para>
+
+ <para>One feature of the veto files parameter that it
+ is important to be aware of is Samba's behaviour when
+ trying to delete a directory. If a directory that is
+ to be deleted contains nothing but veto files this
+ deletion will <emphasis>fail</emphasis> unless you also set
+ the <parameter>delete veto files</parameter> parameter to
+ <parameter>yes</parameter>.</para>
+
+ <para>Setting this parameter will affect the performance
+ of Samba, as it will be forced to check all files and directories
+ for a match as they are scanned.</para>
+
+ <para>See also <link linkend="HIDEFILES"><parameter>hide files
+ </parameter></link> and <link linkend="CASESENSITIVE"><parameter>
+ case sensitive</parameter></link>.</para>
+
+ <para>Default: <emphasis>No files or directories are vetoed.
+ </emphasis></para>
+
+<para>Examples:<programlisting>
+; Veto any files containing the word Security,
+; any ending in .tmp, and any directory containing the
+; word root.
+veto files = /*Security*/*.tmp/*root*/
+
+; Veto the Apple specific files that a NetAtalk server
+; creates.
+veto files = /.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="VETOOPLOCKFILES">veto oplock files (S)</term>
+ <listitem><para>This parameter is only valid when the <link
+ linkend="OPLOCKS"><parameter>oplocks</parameter></link>
+ parameter is turned on for a share. It allows the Samba administrator
+ to selectively turn off the granting of oplocks on selected files that
+ match a wildcarded list, similar to the wildcarded list used in the
+ <link linkend="VETOFILES"><parameter>veto files</parameter></link>
+ parameter.</para>
+
+ <para>Default: <emphasis>No files are vetoed for oplock
+ grants</emphasis></para>
+
+ <para>You might want to do this on files that you know will
+ be heavily contended for by clients. A good example of this
+ is in the NetBench SMB benchmark program, which causes heavy
+ client contention for files ending in <filename>.SEM</filename>.
+ To cause Samba not to grant oplocks on these files you would use
+ the line (either in the [global] section or in the section for
+ the particular NetBench share :</para>
+
+ <para>Example: <command>veto oplock files = /*.SEM/
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="VFSOBJECT">vfs object (S)</term>
+ <listitem><para>This parameter specifies a shared object file that
+ is used for Samba VFS I/O operations. By default, normal
+ disk I/O operations are used but these can be overloaded
+ with a VFS object. The Samba VFS layer is new to Samba 2.2 and
+ must be enabled at compile time with --with-vfs.</para>
+
+ <para>Default : <emphasis>no value</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="VFSOPTIONS">vfs options (S)</term>
+ <listitem><para>This parameter allows parameters to be passed
+ to the vfs layer at initialization time. The Samba VFS layer
+ is new to Samba 2.2 and must be enabled at compile time
+ with --with-vfs. See also <link linkend="VFSOBJECT"><parameter>
+ vfs object</parameter></link>.</para>
+
+ <para>Default : <emphasis>no value</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="VOLUME">volume (S)</term>
+ <listitem><para> This allows you to override the volume label
+ returned for a share. Useful for CDROMs with installation programs
+ that insist on a particular volume label.</para>
+
+ <para>Default: <emphasis>the name of the share</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WIDELINKS">wide links (S)</term>
+ <listitem><para>This parameter controls whether or not links
+ in the UNIX file system may be followed by the server. Links
+ that point to areas within the directory tree exported by the
+ server are always allowed; this parameter controls access only
+ to areas that are outside the directory tree being exported.</para>
+
+ <para>Note that setting this parameter can have a negative
+ effect on your server performance due to the extra system calls
+ that Samba has to do in order to perform the link checks.</para>
+
+ <para>Default: <command>wide links = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WINBINDCACHETIME">winbind cache time (G)</term>
+ <listitem><para>This parameter specifies the number of seconds the
+ <ulink url="winbindd.8.html">winbindd(8)</ulink> daemon will cache
+ user and group information before querying a Windows NT server
+ again.</para>
+
+ <para>Default: <command>winbind cache type = 15</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="WINBINDENUMUSERS">winbind enum users (G)</term>
+ <listitem><para>On large installations using
+ <ulink url="winbindd.8.html">winbindd(8)</ulink> it may be
+ necessary to suppress the enumeration of users through the
+ <command> setpwent()</command>,
+ <command>getpwent()</command> and
+ <command>endpwent()</command> group of system calls. If
+ the <parameter>winbind enum users</parameter> parameter is
+ <constant>no</constant>, calls to the <command>getpwent</command> system call
+ will not return any data. </para>
+
+ <para><emphasis>Warning:</emphasis> Turning off user
+ enumeration may cause some programs to behave oddly. For
+ example, the finger program relies on having access to the
+ full user list when searching for matching
+ usernames. </para>
+
+ <para>Default: <command>winbind enum users = yes </command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="WINBINDENUMGROUPS">winbind enum groups (G)</term>
+ <listitem><para>On large installations using
+ <ulink url="winbindd.8.html">winbindd(8)</ulink> it may be
+ necessary to suppress the enumeration of groups through the
+ <command> setgrent()</command>,
+ <command>getgrent()</command> and
+ <command>endgrent()</command> group of system calls. If
+ the <parameter>winbind enum groups</parameter> parameter is
+ <constant>no</constant>, calls to the <command>getgrent()</command> system
+ call will not return any data. </para>
+
+ <para><emphasis>Warning:</emphasis> Turning off group
+ enumeration may cause some programs to behave oddly.
+ </para>
+
+ <para>Default: <command>winbind enum groups = yes </command>
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="WINBINDGID">winbind gid (G)</term>
+ <listitem><para>The winbind gid parameter specifies the range of group
+ ids that are allocated by the <ulink url="winbindd.8.html">
+ winbindd(8)</ulink> daemon. This range of group ids should have no
+ existing local or NIS groups within it as strange conflicts can
+ occur otherwise.</para>
+
+ <para>Default: <command>winbind gid = &lt;empty string&gt;
+ </command></para>
+
+ <para>Example: <command>winbind gid = 10000-20000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="WINBINDSEPARATOR">winbind separator (G)</term>
+ <listitem><para>This parameter allows an admin to define the character
+ used when listing a username of the form of <replaceable>DOMAIN
+ </replaceable>\<replaceable>user</replaceable>. This parameter
+ is only applicable when using the <filename>pam_winbind.so</filename>
+ and <filename>nss_winbind.so</filename> modules for UNIX services.
+ </para>
+
+ <para>Please note that setting this parameter to + causes problems
+ with group membership at least on glibc systems, as the character +
+ is used as a special character for NIS in /etc/group.</para>
+
+ <para>Default: <command>winbind separator = '\'</command></para>
+ <para>Example: <command>winbind separator = +</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WINBINDUID">winbind uid (G)</term>
+ <listitem><para>The winbind gid parameter specifies the range of group
+ ids that are allocated by the <ulink url="winbindd.8.html">
+ winbindd(8)</ulink> daemon. This range of ids should have no
+ existing local or NIS users within it as strange conflicts can
+ occur otherwise.</para>
+
+ <para>Default: <command>winbind uid = &lt;empty string&gt;
+ </command></para>
+
+ <para>Example: <command>winbind uid = 10000-20000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>winbind use default domain</term>
+
+ <term><anchor id="WINBINDUSEDEFAULTDOMAIN">winbind use default domain</term>
+ <listitem><para>This parameter specifies whether the <ulink url="winbindd.8.html">
+ winbindd(8)</ulink>
+ daemon should operate on users without domain component in their username.
+ Users without a domain component are treated as is part of the winbindd server's
+ own domain. While this does not benifit Windows users, it makes SSH, FTP and e-mail
+ function in a way much closer to the way they would in a native unix system.</para>
+
+ <para>Default: <command>winbind use default domain = &lt;no&gt;
+ </command></para>
+ <para>Example: <command>winbind use default domain = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><anchor id="WINSHOOK">wins hook (G)</term>
+ <listitem><para>When Samba is running as a WINS server this
+ allows you to call an external program for all changes to the
+ WINS database. The primary use for this option is to allow the
+ dynamic update of external name resolution databases such as
+ dynamic DNS.</para>
+
+ <para>The wins hook parameter specifies the name of a script
+ or executable that will be called as follows:</para>
+
+ <para><command>wins_hook operation name nametype ttl IP_list
+ </command></para>
+
+ <itemizedlist>
+ <listitem><para>The first argument is the operation and is one
+ of "add", "delete", or "refresh". In most cases the operation can
+ be ignored as the rest of the parameters provide sufficient
+ information. Note that "refresh" may sometimes be called when the
+ name has not previously been added, in that case it should be treated
+ as an add.</para></listitem>
+
+ <listitem><para>The second argument is the NetBIOS name. If the
+ name is not a legal name then the wins hook is not called.
+ Legal names contain only letters, digits, hyphens, underscores
+ and periods.</para></listitem>
+
+ <listitem><para>The third argument is the NetBIOS name
+ type as a 2 digit hexadecimal number. </para></listitem>
+
+ <listitem><para>The fourth argument is the TTL (time to live)
+ for the name in seconds.</para></listitem>
+
+ <listitem><para>The fifth and subsequent arguments are the IP
+ addresses currently registered for that name. If this list is
+ empty then the name should be deleted.</para></listitem>
+ </itemizedlist>
+
+ <para>An example script that calls the BIND dynamic DNS update
+ program <command>nsupdate</command> is provided in the examples
+ directory of the Samba source code. </para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WINSPROXY">wins proxy (G)</term>
+ <listitem><para>This is a boolean that controls if <ulink
+ url="nmbd.8.html">nmbd(8)</ulink> will respond to broadcast name
+ queries on behalf of other hosts. You may need to set this
+ to <constant>yes</constant> for some older clients.</para>
+
+ <para>Default: <command>wins proxy = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WINSSERVER">wins server (G)</term>
+ <listitem><para>This specifies the IP address (or DNS name: IP
+ address for preference) of the WINS server that <ulink url="nmbd.8.html">
+ nmbd(8)</ulink> should register with. If you have a WINS server on
+ your network then you should set this to the WINS server's IP.</para>
+
+ <para>You should point this at your WINS server if you have a
+ multi-subnetted network.</para>
+
+ <para><emphasis>NOTE</emphasis>. You need to set up Samba to point
+ to a WINS server if you have multiple subnets and wish cross-subnet
+ browsing to work correctly.</para>
+
+ <para>See the documentation file <filename>BROWSING.txt</filename>
+ in the docs/ directory of your Samba source distribution.</para>
+
+ <para>Default: <emphasis>not enabled</emphasis></para>
+ <para>Example: <command>wins server = 192.9.200.1</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WINSSUPPORT">wins support (G)</term>
+ <listitem><para>This boolean controls if the <ulink url="nmbd.8.html">
+ nmbd(8)</ulink> process in Samba will act as a WINS server. You should
+ not set this to <constant>yes</constant> unless you have a multi-subnetted network and
+ you wish a particular <command>nmbd</command> to be your WINS server.
+ Note that you should <emphasis>NEVER</emphasis> set this to <constant>yes</constant>
+ on more than one machine in your network.</para>
+
+ <para>Default: <command>wins support = no</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WORKGROUP">workgroup (G)</term>
+ <listitem><para>This controls what workgroup your server will
+ appear to be in when queried by clients. Note that this parameter
+ also controls the Domain name used with the <link
+ linkend="SECURITYEQUALSDOMAIN"><command>security = domain</command></link>
+ setting.</para>
+
+ <para>Default: <emphasis>set at compile time to WORKGROUP</emphasis></para>
+ <para>Example: <command>workgroup = MYGROUP</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITABLE">writable (S)</term>
+ <listitem><para>Synonym for <link linkend="WRITEABLE"><parameter>
+ writeable</parameter></link> for people who can't spell :-).</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITECACHESIZE">write cache size (S)</term>
+ <listitem><para>If this integer parameter is set to non-zero value,
+ Samba will create an in-memory cache for each oplocked file
+ (it does <emphasis>not</emphasis> do this for
+ non-oplocked files). All writes that the client does not request
+ to be flushed directly to disk will be stored in this cache if possible.
+ The cache is flushed onto disk when a write comes in whose offset
+ would not fit into the cache or when the file is closed by the client.
+ Reads for the file are also served from this cache if the data is stored
+ within it.</para>
+
+ <para>This cache allows Samba to batch client writes into a more
+ efficient write size for RAID disks (i.e. writes may be tuned to
+ be the RAID stripe size) and can improve performance on systems
+ where the disk subsystem is a bottleneck but there is free
+ memory for userspace programs.</para>
+
+ <para>The integer parameter specifies the size of this cache
+ (per oplocked file) in bytes.</para>
+
+ <para>Default: <command>write cache size = 0</command></para>
+ <para>Example: <command>write cache size = 262144</command></para>
+
+ <para>for a 256k cache size per file.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITELIST">write list (S)</term>
+ <listitem><para>This is a list of users that are given read-write
+ access to a service. If the connecting user is in this list then
+ they will be given write access, no matter what the <link
+ linkend="READONLY"><parameter>read only</parameter></link>
+ option is set to. The list can include group names using the
+ @group syntax.</para>
+
+ <para>Note that if a user is in both the read list and the
+ write list then they will be given write access.</para>
+
+ <para>See also the <link linkend="READLIST"><parameter>read list
+ </parameter></link> option.</para>
+
+ <para>Default: <command>write list = &lt;empty string&gt;
+ </command></para>
+
+ <para>Example: <command>write list = admin, root, @staff
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITEOK">write ok (S)</term>
+ <listitem><para>Inverted synonym for <link linkend="READONLY"><parameter>
+ read only</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITERAW">write raw (G)</term>
+ <listitem><para>This parameter controls whether or not the server
+ will support raw write SMB's when transferring data from clients.
+ You should never need to change this parameter.</para>
+
+ <para>Default: <command>write raw = yes</command></para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term><anchor id="WRITEABLE">writeable (S)</term>
+ <listitem><para>Inverted synonym for <link linkend="READONLY"><parameter>
+ read only</parameter></link>.</para>
+ </listitem>
+ </varlistentry>
+
+
+ </variablelist>
+
+</refsect1>
+
+<refsect1>
+ <title>WARNINGS</title>
+
+ <para>Although the configuration file permits service names
+ to contain spaces, your client software may not. Spaces will
+ be ignored in comparisons anyway, so it shouldn't be a
+ problem - but be aware of the possibility.</para>
+
+ <para>On a similar note, many clients - especially DOS clients -
+ limit service names to eight characters. <ulink url="smbd.8.html">smbd(8)
+ </ulink> has no such limitation, but attempts to connect from such
+ clients will fail if they truncate the service names. For this reason
+ you should probably keep your service names down to eight characters
+ in length.</para>
+
+ <para>Use of the [homes] and [printers] special sections make life
+ for an administrator easy, but the various combinations of default
+ attributes can be tricky. Take extreme care when designing these
+ sections. In particular, ensure that the permissions on spool
+ directories are correct.</para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="samba.7.html">samba(7)</ulink>,
+ <ulink url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink>,
+ <ulink url="swat.8.html"><command>swat(8)</command></ulink>,
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="nmbd.8.html"><command>nmbd(8)</command></ulink>,
+ <ulink url="smbclient.1.html"><command>smbclient(1)</command></ulink>,
+ <ulink url="nmblookup.1.html"><command>nmblookup(1)</command></ulink>,
+ <ulink url="testparm.1.html"><command>testparm(1)</command></ulink>,
+ <ulink url="testprns.1.html"><command>testprns(1)</command></ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbcacls.1.sgml b/docs/docbook/manpages/smbcacls.1.sgml
new file mode 100755
index 00000000000..69aa9674928
--- /dev/null
+++ b/docs/docbook/manpages/smbcacls.1.sgml
@@ -0,0 +1,255 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbcacls">
+
+<refmeta>
+ <refentrytitle>smbcacls</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbcacls</refname>
+ <refpurpose>Set or get ACLs on an NT file or directory names</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbcacls</command>
+ <arg choice="req">//server/share</arg>
+ <arg choice="req">filename</arg>
+ <arg choice="opt">-U username</arg>
+ <arg choice="opt">-A acls</arg>
+ <arg choice="opt">-M acls</arg>
+ <arg choice="opt">-D acls</arg>
+ <arg choice="opt">-S acls</arg>
+ <arg choice="opt">-C name</arg>
+ <arg choice="opt">-G name</arg>
+ <arg choice="opt">-n</arg>
+ <arg choice="opt">-h</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>The <command>smbcacls</command> program manipulates NT Access Control Lists
+ (ACLs) on SMB file shares. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <para>The following options are available to the <command>smbcacls</command> program.
+ The format of ACLs is described in the section ACL FORMAT </para>
+
+
+ <variablelist>
+ <varlistentry>
+ <term>-A acls</term>
+ <listitem><para>Add the ACLs specified to the ACL list. Existing
+ access control entries are unchanged. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-M acls</term>
+ <listitem><para>Modify the mask value (permissions) for the ACLs
+ specified on the command line. An error will be printed for each
+ ACL specified that was not already present in the ACL list
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-D acls</term>
+ <listitem><para>Delete any ACLs specified on the command line.
+ An error will be printed for each ACL specified that was not
+ already present in the ACL list. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-S acls</term>
+ <listitem><para>This command sets the ACLs on the file with
+ only the ones specified on the command line. All other ACLs are
+ erased. Note that the ACL specified must contain at least a revision,
+ type, owner and group for the call to succeed. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-U username</term>
+ <listitem><para>Specifies a username used to connect to the
+ specified service. The username may be of the form "username" in
+ which case the user is prompted to enter in a password and the
+ workgroup specified in the <filename>smb.conf</filename> file is
+ used, or "username%password" or "DOMAIN\username%password" and the
+ password and workgroup names are used as provided. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-C name</term>
+ <listitem><para>The owner of a file or directory can be changed
+ to the name given using the <parameter>-C</parameter> option.
+ The name can be a sid in the form S-1-x-y-z or a name resolved
+ against the server specified in the first argument. </para>
+
+ <para>This command is a shortcut for -M OWNER:name.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-G name</term>
+ <listitem><para>The group owner of a file or directory can
+ be changed to the name given using the <parameter>-G</parameter>
+ option. The name can be a sid in the form S-1-x-y-z or a name
+ resolved against the server specified n the first argument.
+ </para>
+
+ <para>This command is a shortcut for -M GROUP:name.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-n</term>
+ <listitem><para>This option displays all ACL information in numeric
+ format. The default is to convert SIDs to names and ACE types
+ and masks to a readable string format. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Print usage information on the <command>smbcacls
+ </command> program.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>ACL FORMAT</title>
+
+ <para>The format of an ACL is one or more ACL entries separated by
+ either commas or newlines. An ACL entry is one of the following: </para>
+
+ <para><programlisting>
+REVISION:&lt;revision number&gt;
+OWNER:&lt;sid or name&gt;
+GROUP:&lt;sid or name&gt;
+ACL:&lt;sid or name&gt;:&lt;type&gt;/&lt;flags&gt;/&lt;mask&gt;
+ </programlisting></para>
+
+
+ <para>The revision of the ACL specifies the internal Windows
+ NT ACL revision for the security descriptor.
+ If not specified it defaults to 1. Using values other than 1 may
+ cause strange behaviour. </para>
+
+ <para>The owner and group specify the owner and group sids for the
+ object. If a SID in the format CWS-1-x-y-z is specified this is used,
+ otherwise the name specified is resolved using the server on which
+ the file or directory resides. </para>
+
+ <para>ACLs specify permissions granted to the SID. This SID again
+ can be specified in CWS-1-x-y-z format or as a name in which case
+ it is resolved against the server on which the file or directory
+ resides. The type, flags and mask values determine the type of
+ access granted to the SID. </para>
+
+ <para>The type can be either 0 or 1 corresponding to ALLOWED or
+ DENIED access to the SID. The flags values are generally
+ zero for file ACLs and either 9 or 2 for directory ACLs. Some
+ common flags are: </para>
+
+ <itemizedlist>
+ <listitem><para>#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1</para></listitem>
+ <listitem><para>#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2</para></listitem>
+ <listitem><para>#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4
+ </para></listitem>
+ <listitem><para>#define SEC_ACE_FLAG_INHERIT_ONLY 0x8</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>At present flags can only be specified as decimal or
+ hexadecimal values.</para>
+
+ <para>The mask is a value which expresses the access right
+ granted to the SID. It can be given as a decimal or hexadecimal value,
+ or by using one of the following text strings which map to the NT
+ file permissions of the same name. </para>
+
+ <itemizedlist>
+ <listitem><para><emphasis>R</emphasis> - Allow read access </para></listitem>
+ <listitem><para><emphasis>W</emphasis> - Allow write access</para></listitem>
+ <listitem><para><emphasis>X</emphasis> - Execute permission on the object</para></listitem>
+ <listitem><para><emphasis>D</emphasis> - Delete the object</para></listitem>
+ <listitem><para><emphasis>P</emphasis> - Change permissions</para></listitem>
+ <listitem><para><emphasis>O</emphasis> - Take ownership</para></listitem>
+ </itemizedlist>
+
+
+ <para>The following combined permissions can be specified:</para>
+
+
+ <itemizedlist>
+ <listitem><para><emphasis>READ</emphasis> - Equivalent to 'RX'
+ permissions</para></listitem>
+ <listitem><para><emphasis>CHANGE</emphasis> - Equivalent to 'RXWD' permissions
+ </para></listitem>
+ <listitem><para><emphasis>FULL</emphasis> - Equivalent to 'RWXDPO'
+ permissions</para></listitem>
+ </itemizedlist>
+ </refsect1>
+
+<refsect1>
+ <title>EXIT STATUS</title>
+
+ <para>The <command>smbcacls</command> program sets the exit status
+ depending on the success or otherwise of the operations performed.
+ The exit status may be one of the following values. </para>
+
+ <para>If the operation succeeded, smbcacls returns and exit
+ status of 0. If <command>smbcacls</command> couldn't connect to the specified server,
+ or there was an error getting or setting the ACLs, an exit status
+ of 1 is returned. If there was an error parsing any command line
+ arguments, an exit status of 2 is returned. </para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para><command>smbcacls</command> was written by Andrew Tridgell
+ and Tim Potter.</para>
+
+ <para>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbclient.1.sgml b/docs/docbook/manpages/smbclient.1.sgml
new file mode 100755
index 00000000000..31031dafc46
--- /dev/null
+++ b/docs/docbook/manpages/smbclient.1.sgml
@@ -0,0 +1,1088 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbclient">
+
+<refmeta>
+ <refentrytitle>smbclient</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbclient</refname>
+ <refpurpose>ftp-like client to access SMB/CIFS resources
+ on servers</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbclient</command>
+ <arg choice="req">servicename</arg>
+ <arg choice="opt">password</arg>
+ <arg choice="opt">-b &lt;buffer size&gt;</arg>
+ <arg choice="opt">-d debuglevel</arg>
+ <arg choice="opt">-D Directory</arg>
+ <arg choice="opt">-U username</arg>
+ <arg choice="opt">-W workgroup</arg>
+ <arg choice="opt">-M &lt;netbios name&gt;</arg>
+ <arg choice="opt">-m maxprotocol</arg>
+ <arg choice="opt">-A authfile</arg>
+ <arg choice="opt">-N</arg>
+ <arg choice="opt">-l logfile</arg>
+ <arg choice="opt">-L &lt;netbios name&gt;</arg>
+ <arg choice="opt">-I destinationIP</arg>
+ <arg choice="opt">-E &lt;terminal code&gt;</arg>
+ <arg choice="opt">-c &lt;command string&gt;</arg>
+ <arg choice="opt">-i scope</arg>
+ <arg choice="opt">-O &lt;socket options&gt;</arg>
+ <arg choice="opt">-p port</arg>
+ <arg choice="opt">-R &lt;name resolve order&gt;</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="opt">-T&lt;c|x&gt;IXFqgbNan</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>smbclient</command> is a client that can
+ 'talk' to an SMB/CIFS server. It offers an interface
+ similar to that of the ftp program (see <command>ftp(1)</command>).
+ Operations include things like getting files from the server
+ to the local machine, putting files from the local machine to
+ the server, retrieving directory information from the server
+ and so on. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>servicename</term>
+ <listitem><para>servicename is the name of the service
+ you want to use on the server. A service name takes the form
+ <filename>//server/service</filename> where <parameter>server
+ </parameter> is the NetBIOS name of the SMB/CIFS server
+ offering the desired service and <parameter>service</parameter>
+ is the name of the service offered. Thus to connect to
+ the service "printer" on the SMB/CIFS server "smbserver",
+ you would use the servicename <filename>//smbserver/printer
+ </filename></para>
+
+ <para>Note that the server name required is NOT necessarily
+ the IP (DNS) host name of the server ! The name required is
+ a NetBIOS server name, which may or may not be the
+ same as the IP hostname of the machine running the server.
+ </para>
+
+ <para>The server name is looked up according to either
+ the <parameter>-R</parameter> parameter to <command>smbclient</command> or
+ using the name resolve order parameter in the <filename>smb.conf</filename> file,
+ allowing an administrator to change the order and methods
+ by which server names are looked up. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>password</term>
+ <listitem><para>The password required to access the specified
+ service on the specified server. If this parameter is
+ supplied, the <parameter>-N</parameter> option (suppress
+ password prompt) is assumed. </para>
+
+ <para>There is no default password. If no password is supplied
+ on the command line (either by using this parameter or adding
+ a password to the <parameter>-U</parameter> option (see
+ below)) and the <parameter>-N</parameter> option is not
+ specified, the client will prompt for a password, even if
+ the desired service does not require one. (If no password is
+ required, simply press ENTER to provide a null password.)
+ </para>
+
+ <para>Note: Some servers (including OS/2 and Windows for
+ Workgroups) insist on an uppercase password. Lowercase
+ or mixed case passwords may be rejected by these servers.
+ </para>
+
+ <para>Be cautious about including passwords in scripts.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s smb.conf</term>
+ <listitem><para>Specifies the location of the all important
+ <filename>smb.conf</filename> file. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O socket options</term>
+ <listitem><para>TCP socket options to set on the client
+ socket. See the socket options parameter in the <filename>
+ smb.conf (5)</filename> manpage for the list of valid
+ options. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-R &lt;name resolve order&gt;</term>
+ <listitem><para>This option is used by the programs in the Samba
+ suite to determine what naming services and in what order to resolve
+ host names to IP addresses. The option takes a space-separated
+ string of different name resolution options.</para>
+
+ <para>The options are :"lmhosts", "host", "wins" and "bcast". They
+ cause names to be resolved as follows :</para>
+
+ <itemizedlist>
+ <listitem><para><constant>lmhosts</constant> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <ulink
+ url="lmhosts.5.html">lmhosts(5)</ulink> for details) then
+ any name type matches for lookup.</para></listitem>
+
+ <listitem><para><constant>host</constant> : Do a standard host
+ name to IP address resolution, using the system <filename>/etc/hosts
+ </filename>, NIS, or DNS lookups. This method of name resolution
+ is operating system dependent, for instance on IRIX or Solaris this
+ may be controlled by the <filename>/etc/nsswitch.conf</filename>
+ file). Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</para></listitem>
+
+ <listitem><para><constant>wins</constant> : Query a name with
+ the IP address listed in the <parameter>wins server</parameter>
+ parameter. If no WINS server has
+ been specified this method will be ignored.</para></listitem>
+
+ <listitem><para><constant>bcast</constant> : Do a broadcast on
+ each of the known local interfaces listed in the
+ <parameter>interfaces</parameter>
+ parameter. This is the least reliable of the name resolution
+ methods as it depends on the target host being on a locally
+ connected subnet.</para></listitem>
+ </itemizedlist>
+
+ <para>If this parameter is not set then the name resolve order
+ defined in the <filename>smb.conf</filename> file parameter
+ (name resolve order) will be used. </para>
+
+ <para>The default order is lmhosts, host, wins, bcast and without
+ this parameter or any entry in the <parameter>name resolve order
+ </parameter> parameter of the <filename>smb.conf</filename> file the name resolution
+ methods will be attempted in this order. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-M NetBIOS name</term>
+ <listitem><para>This options allows you to send messages, using
+ the "WinPopup" protocol, to another computer. Once a connection is
+ established you then type your message, pressing ^D (control-D) to
+ end. </para>
+
+ <para>If the receiving computer is running WinPopup the user will
+ receive the message and probably a beep. If they are not running
+ WinPopup the message will be lost, and no error message will
+ occur. </para>
+
+ <para>The message is also automatically truncated if the message
+ is over 1600 bytes, as this is the limit of the protocol.
+ </para>
+
+ <para>One useful trick is to cat the message through
+ <command>smbclient</command>. For example: <command>
+ cat mymessage.txt | smbclient -M FRED </command> will
+ send the message in the file <filename>mymessage.txt</filename>
+ to the machine FRED. </para>
+
+ <para>You may also find the <parameter>-U</parameter> and
+ <parameter>-I</parameter> options useful, as they allow you to
+ control the FROM and TO parts of the message. </para>
+
+ <para>See the message command parameter in the <filename>
+ smb.conf(5)</filename> for a description of how to handle incoming
+ WinPopup messages in Samba. </para>
+
+ <para><emphasis>Note</emphasis>: Copy WinPopup into the startup group
+ on your WfWg PCs if you want them to always be able to receive
+ messages. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i scope</term>
+ <listitem><para>This specifies a NetBIOS scope that smbclient will
+ use to communicate with when generating NetBIOS names. For details
+ on the use of NetBIOS scopes, see <filename>rfc1001.txt</filename>
+ and <filename>rfc1002.txt</filename>.
+ NetBIOS scopes are <emphasis>very</emphasis> rarely used, only set
+ this parameter if you are the system administrator in charge of all
+ the NetBIOS systems you communicate with. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-N</term>
+ <listitem><para>If specified, this parameter suppresses the normal
+ password prompt from the client to the user. This is useful when
+ accessing a service that does not require a password. </para>
+
+ <para>Unless a password is specified on the command line or
+ this parameter is specified, the client will request a
+ password.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-n NetBIOS name</term>
+ <listitem><para>By default, the client will use the local
+ machine's hostname (in uppercase) as its NetBIOS name. This parameter
+ allows you to override the host name and use whatever NetBIOS
+ name you wish. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-d debuglevel</term>
+ <listitem><para><replaceable>debuglevel</replaceable> is an integer from 0 to 10, or
+ the letter 'A'. </para>
+
+ <para>The default value if this parameter is not specified
+ is zero. </para>
+
+ <para>The higher this value, the more detail will be logged to
+ the log files about the activities of the
+ client. At level 0, only critical errors and serious warnings will
+ be logged. Level 1 is a reasonable level for day to day running -
+ it generates a small amount of information about operations
+ carried out. </para>
+
+ <para>Levels above 1 will generate considerable amounts of log
+ data, and should only be used when investigating a problem.
+ Levels above 3 are designed for use only by developers and
+ generate HUGE amounts of log data, most of which is extremely
+ cryptic. If <replaceable>debuglevel</replaceable> is set to the letter 'A', then <emphasis>all
+ </emphasis> debug messages will be printed. This setting
+ is for developers only (and people who <emphasis>really</emphasis> want
+ to know how the code works internally). </para>
+
+ <para>Note that specifying this parameter here will override
+ the log level parameter in the <filename>smb.conf (5)</filename>
+ file. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-p port</term>
+ <listitem><para>This number is the TCP port number that will be used
+ when making connections to the server. The standard (well-known)
+ TCP port number for an SMB/CIFS server is 139, which is the
+ default. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-l logfilename</term>
+ <listitem><para>If specified, <replaceable>logfilename</replaceable> specifies a base filename
+ into which operational data from the running client will be
+ logged. </para>
+
+ <para>The default base name is specified at compile time.</para>
+
+ <para>The base name is used to generate actual log file names.
+ For example, if the name specified was "log", the debug file
+ would be <filename>log.client</filename>.</para>
+
+ <para>The log file generated is never removed by the client.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-h</term><listitem>
+ <para>Print the usage message for the client. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-I IP-address</term>
+ <listitem><para><replaceable>IP address</replaceable> is the address of the server to connect to.
+ It should be specified in standard "a.b.c.d" notation. </para>
+
+ <para>Normally the client would attempt to locate a named
+ SMB/CIFS server by looking it up via the NetBIOS name resolution
+ mechanism described above in the <parameter>name resolve order</parameter>
+ parameter above. Using this parameter will force the client
+ to assume that the server is on the machine with the specified IP
+ address and the NetBIOS name component of the resource being
+ connected to will be ignored. </para>
+
+ <para>There is no default for this parameter. If not supplied,
+ it will be determined automatically by the client as described
+ above. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-E</term>
+ <listitem><para>This parameter causes the client to write messages
+ to the standard error stream (stderr) rather than to the standard
+ output stream. </para>
+
+ <para>By default, the client writes messages to standard output
+ - typically the user's tty. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-U username[%pass]</term>
+ <listitem><para>Sets the SMB username or username and password.
+ If %pass is not specified, The user will be prompted. The client
+ will first check the <envar>USER</envar> environment variable, then the
+ <envar>LOGNAME</envar> variable and if either exists, the
+ string is uppercased. Anything in these variables following a '%'
+ sign will be treated as the password. If these environment
+ variables are not found, the username <constant>GUEST</constant>
+ is used. </para>
+
+ <para>If the password is not included in these environment
+ variables (using the %pass syntax), <command>smbclient</command> will look for
+ a <envar>PASSWD</envar> environment variable from which
+ to read the password. </para>
+
+ <para>A third option is to use a credentials file which
+ contains the plaintext of the domain name, username and password. This
+ option is mainly provided for scripts where the admin doesn't
+ wish to pass the credentials on the command line or via environment
+ variables. If this method is used, make certain that the permissions
+ on the file restrict access from unwanted users. See the
+ <parameter>-A</parameter> for more details. </para>
+
+ <para>Be cautious about including passwords in scripts or in
+ the <envar>PASSWD</envar> environment variable. Also, on
+ many systems the command line of a running process may be seen
+ via the <command>ps</command> command to be safe always allow
+ <command>smbclient</command> to prompt for a password and type
+ it in directly. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-A filename</term><listitem><para>This option allows
+ you to specify a file from which to read the username, domain name, and
+ password used in the connection. The format of the file is
+ </para>
+
+ <para><programlisting>
+username = &lt;value&gt;
+password = &lt;value&gt;
+domain = &lt;value&gt;
+ </programlisting></para>
+
+
+ <para>If the domain parameter is missing the current workgroup name
+ is used instead. Make certain that the permissions on the file restrict
+ access from unwanted users. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-L</term>
+ <listitem><para>This option allows you to look at what services
+ are available on a server. You use it as <command>smbclient -L
+ host</command> and a list should appear. The <parameter>-I
+ </parameter> option may be useful if your NetBIOS names don't
+ match your TCP/IP DNS host names or if you are trying to reach a
+ host on another network. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-t terminal code</term>
+ <listitem><para>This option tells <command>smbclient</command> how to interpret
+ filenames coming from the remote server. Usually Asian language
+ multibyte UNIX implementations use different character sets than
+ SMB/CIFS servers (<emphasis>EUC</emphasis> instead of <emphasis>
+ SJIS</emphasis> for example). Setting this parameter will let
+ <command>smbclient</command> convert between the UNIX filenames and
+ the SMB filenames correctly. This option has not been seriously tested
+ and may have some problems. </para>
+
+ <para>The terminal codes include CWsjis, CWeuc, CWjis7, CWjis8,
+ CWjunet, CWhex, CWcap. This is not a complete list, check the Samba
+ source code for the complete list. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-b buffersize</term>
+ <listitem><para>This option changes the transmit/send buffer
+ size when getting or putting a file from/to the server. The default
+ is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
+ observed to speed up file transfers to and from a Win9x server.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-W WORKGROUP</term>
+ <listitem><para>Override the default workgroup (domain) specified
+ in the workgroup parameter of the <filename>smb.conf</filename>
+ file for this connection. This may be needed to connect to some
+ servers. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-T tar options</term>
+ <listitem><para>smbclient may be used to create <command>tar(1)
+ </command> compatible backups of all the files on an SMB/CIFS
+ share. The secondary tar flags that can be given to this option
+ are : </para>
+
+ <itemizedlist>
+ <listitem><para><parameter>c</parameter> - Create a tar file on UNIX.
+ Must be followed by the name of a tar file, tape device
+ or "-" for standard output. If using standard output you must
+ turn the log level to its lowest value -d0 to avoid corrupting
+ your tar file. This flag is mutually exclusive with the
+ <parameter>x</parameter> flag. </para></listitem>
+
+ <listitem><para><parameter>x</parameter> - Extract (restore) a local
+ tar file back to a share. Unless the -D option is given, the tar
+ files will be restored from the top level of the share. Must be
+ followed by the name of the tar file, device or "-" for standard
+ input. Mutually exclusive with the <parameter>c</parameter> flag.
+ Restored files have their creation times (mtime) set to the
+ date saved in the tar file. Directories currently do not get
+ their creation dates restored properly. </para></listitem>
+
+ <listitem><para><parameter>I</parameter> - Include files and directories.
+ Is the default behavior when filenames are specified above. Causes
+ tar files to be included in an extract or create (and therefore
+ everything else to be excluded). See example below. Filename globbing
+ works in one of two ways. See r below. </para></listitem>
+
+ <listitem><para><parameter>X</parameter> - Exclude files and directories.
+ Causes tar files to be excluded from an extract or create. See
+ example below. Filename globbing works in one of two ways now.
+ See <parameter>r</parameter> below. </para></listitem>
+
+ <listitem><para><parameter>b</parameter> - Blocksize. Must be followed
+ by a valid (greater than zero) blocksize. Causes tar file to be
+ written out in blocksize*TBLOCK (usually 512 byte) blocks.
+ </para></listitem>
+
+ <listitem><para><parameter>g</parameter> - Incremental. Only back up
+ files that have the archive bit set. Useful only with the
+ <parameter>c</parameter> flag. </para></listitem>
+
+ <listitem><para><parameter>q</parameter> - Quiet. Keeps tar from printing
+ diagnostics as it works. This is the same as tarmode quiet.
+ </para></listitem>
+
+ <listitem><para><parameter>r</parameter> - Regular expression include
+ or exclude. Uses regular expression matching for
+ excluding or excluding files if compiled with HAVE_REGEX_H.
+ However this mode can be very slow. If not compiled with
+ HAVE_REGEX_H, does a limited wildcard match on '*' and '?'.
+ </para></listitem>
+
+ <listitem><para><parameter>N</parameter> - Newer than. Must be followed
+ by the name of a file whose date is compared against files found
+ on the share during a create. Only files newer than the file
+ specified are backed up to the tar file. Useful only with the
+ <parameter>c</parameter> flag. </para></listitem>
+
+ <listitem><para><parameter>a</parameter> - Set archive bit. Causes the
+ archive bit to be reset when a file is backed up. Useful with the
+ <parameter>g</parameter> and <parameter>c</parameter> flags.
+ </para></listitem>
+ </itemizedlist>
+
+ <para><emphasis>Tar Long File Names</emphasis></para>
+
+ <para><command>smbclient</command>'s tar option now supports long
+ file names both on backup and restore. However, the full path
+ name of the file must be less than 1024 bytes. Also, when
+ a tar archive is created, <command>smbclient</command>'s tar option places all
+ files in the archive with relative names, not absolute names.
+ </para>
+
+ <para><emphasis>Tar Filenames</emphasis></para>
+
+ <para>All file names can be given as DOS path names (with '\'
+ as the component separator) or as UNIX path names (with '/' as
+ the component separator). </para>
+
+ <para><emphasis>Examples</emphasis></para>
+
+ <para>Restore from tar file <filename>backup.tar</filename> into myshare on mypc
+ (no password on share). </para>
+
+ <para><command>smbclient //mypc/yshare "" -N -Tx backup.tar
+ </command></para>
+
+ <para>Restore everything except <filename>users/docs</filename>
+ </para>
+
+ <para><command>smbclient //mypc/myshare "" -N -TXx backup.tar
+ users/docs</command></para>
+
+ <para>Create a tar file of the files beneath <filename>
+ users/docs</filename>. </para>
+
+ <para><command>smbclient //mypc/myshare "" -N -Tc
+ backup.tar users/docs </command></para>
+
+ <para>Create the same tar file as above, but now use
+ a DOS path name. </para>
+
+ <para><command>smbclient //mypc/myshare "" -N -tc backup.tar
+ users\edocs </command></para>
+
+ <para>Create a tar file of all the files and directories in
+ the share. </para>
+
+ <para><command>smbclient //mypc/myshare "" -N -Tc backup.tar *
+ </command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-D initial directory</term>
+ <listitem><para>Change to initial directory before starting. Probably
+ only of any use with the tar -T option. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-c command string</term>
+ <listitem><para>command string is a semicolon-separated list of
+ commands to be executed instead of prompting from stdin. <parameter>
+ -N</parameter> is implied by <parameter>-c</parameter>.</para>
+
+ <para>This is particularly useful in scripts and for printing stdin
+ to the server, e.g. <command>-c 'print -'</command>. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>OPERATIONS</title>
+
+ <para>Once the client is running, the user is presented with
+ a prompt : </para>
+
+ <para><prompt>smb:\&gt; </prompt></para>
+
+ <para>The backslash ("\") indicates the current working directory
+ on the server, and will change if the current working directory
+ is changed. </para>
+
+ <para>The prompt indicates that the client is ready and waiting to
+ carry out a user command. Each command is a single word, optionally
+ followed by parameters specific to that command. Command and parameters
+ are space-delimited unless these notes specifically
+ state otherwise. All commands are case-insensitive. Parameters to
+ commands may or may not be case sensitive, depending on the command.
+ </para>
+
+ <para>You can specify file names which have spaces in them by quoting
+ the name with double quotes, for example "a long file name". </para>
+
+ <para>Parameters shown in square brackets (e.g., "[parameter]") are
+ optional. If not given, the command will use suitable defaults. Parameters
+ shown in angle brackets (e.g., "&lt;parameter&gt;") are required.
+ </para>
+
+
+ <para>Note that all commands operating on the server are actually
+ performed by issuing a request to the server. Thus the behavior may
+ vary from server to server, depending on how the server was implemented.
+ </para>
+
+ <para>The commands available are given here in alphabetical order. </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>? [command]</term>
+ <listitem><para>If <replaceable>command</replaceable> is specified, the ? command will display
+ a brief informative message about the specified command. If no
+ command is specified, a list of available commands will
+ be displayed. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>! [shell command]</term>
+ <listitem><para>If <replaceable>shell command</replaceable> is specified, the !
+ command will execute a shell locally and run the specified shell
+ command. If no command is specified, a local shell will be run.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>altname file</term>
+ <listitem><para>The client will request that the server return
+ the "alternate" name (the 8.3 name) for a file or directory.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>cancel jobid0 [jobid1] ... [jobidN]</term>
+ <listitem><para>The client will request that the server cancel
+ the printjobs identified by the given numeric print job ids.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>chmod file mode in octal</term>
+ <listitem><para>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ change the UNIX permissions to the given octal mode, in standard UNIX format.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>chown file uid gid</term>
+ <listitem><para>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ change the UNIX user and group ownership to the given decimal values. Note there is
+ currently no way to remotely look up the UNIX uid and gid values for a given name.
+ This may be addressed in future versions of the CIFS UNIX extensions.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>cd [directory name]</term>
+ <listitem><para>If "directory name" is specified, the current
+ working directory on the server will be changed to the directory
+ specified. This operation will fail if for any reason the specified
+ directory is inaccessible. </para>
+
+ <para>If no directory name is specified, the current working
+ directory on the server will be reported. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>del &lt;mask&gt;</term>
+ <listitem><para>The client will request that the server attempt
+ to delete all files matching <replaceable>mask</replaceable> from the current working
+ directory on the server. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>dir &lt;mask&gt;</term>
+ <listitem><para>A list of the files matching <replaceable>mask</replaceable> in the current
+ working directory on the server will be retrieved from the server
+ and displayed. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>exit</term>
+ <listitem><para>Terminate the connection with the server and exit
+ from the program. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>get &lt;remote file name&gt; [local file name]</term>
+ <listitem><para>Copy the file called <filename>remote file name</filename> from
+ the server to the machine running the client. If specified, name
+ the local copy <filename>local file name</filename>. Note that all transfers in
+ <command>smbclient</command> are binary. See also the
+ lowercase command. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>help [command]</term>
+ <listitem><para>See the ? command above. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>lcd [directory name]</term>
+ <listitem><para>If <replaceable>directory name</replaceable> is specified, the current
+ working directory on the local machine will be changed to
+ the directory specified. This operation will fail if for any
+ reason the specified directory is inaccessible. </para>
+
+ <para>If no directory name is specified, the name of the
+ current working directory on the local machine will be reported.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>link source destination</term>
+ <listitem><para>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ create a hard link between the source and destination files. The source file
+ must not exist.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>lowercase</term>
+ <listitem><para>Toggle lowercasing of filenames for the get and
+ mget commands. </para>
+
+ <para>When lowercasing is toggled ON, local filenames are converted
+ to lowercase when using the get and mget commands. This is
+ often useful when copying (say) MSDOS files from a server, because
+ lowercase filenames are the norm on UNIX systems. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>ls &lt;mask&gt;</term>
+ <listitem><para>See the dir command above. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>mask &lt;mask&gt;</term>
+ <listitem><para>This command allows the user to set up a mask
+ which will be used during recursive operation of the mget and
+ mput commands. </para>
+
+ <para>The masks specified to the mget and mput commands act as
+ filters for directories rather than files when recursion is
+ toggled ON. </para>
+
+ <para>The mask specified with the mask command is necessary
+ to filter files within those directories. For example, if the
+ mask specified in an mget command is "source*" and the mask
+ specified with the mask command is "*.c" and recursion is
+ toggled ON, the mget command will retrieve all files matching
+ "*.c" in all directories below and including all directories
+ matching "source*" in the current working directory. </para>
+
+ <para>Note that the value for mask defaults to blank (equivalent
+ to "*") and remains so until the mask command is used to change it.
+ It retains the most recently specified value indefinitely. To
+ avoid unexpected results it would be wise to change the value of
+ mask back to "*" after using the mget or mput commands. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>md &lt;directory name&gt;</term>
+ <listitem><para>See the mkdir command. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>mget &lt;mask&gt;</term>
+ <listitem><para>Copy all files matching <replaceable>mask</replaceable> from the server to
+ the machine running the client. </para>
+
+ <para>Note that <replaceable>mask</replaceable> is interpreted differently during recursive
+ operation and non-recursive operation - refer to the recurse and
+ mask commands for more information. Note that all transfers in
+ <command>smbclient</command> are binary. See also the lowercase command. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>mkdir &lt;directory name&gt;</term>
+ <listitem><para>Create a new directory on the server (user access
+ privileges permitting) with the specified name. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>mput &lt;mask&gt;</term>
+ <listitem><para>Copy all files matching <replaceable>mask</replaceable> in the current working
+ directory on the local machine to the current working directory on
+ the server. </para>
+
+ <para>Note that <replaceable>mask</replaceable> is interpreted differently during recursive
+ operation and non-recursive operation - refer to the recurse and mask
+ commands for more information. Note that all transfers in <command>smbclient</command>
+ are binary. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>print &lt;file name&gt;</term>
+ <listitem><para>Print the specified file from the local machine
+ through a printable service on the server. </para>
+
+ <para>See also the printmode command.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>printmode &lt;graphics or text&gt;</term>
+ <listitem><para>Set the print mode to suit either binary data
+ (such as graphical information) or text. Subsequent print
+ commands will use the currently set print mode. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>prompt</term>
+ <listitem><para>Toggle prompting for filenames during operation
+ of the mget and mput commands. </para>
+
+ <para>When toggled ON, the user will be prompted to confirm
+ the transfer of each file during these commands. When toggled
+ OFF, all specified files will be transferred without prompting.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>put &lt;local file name&gt; [remote file name]</term>
+ <listitem><para>Copy the file called <filename>local file name</filename> from the
+ machine running the client to the server. If specified,
+ name the remote copy <filename>remote file name</filename>. Note that all transfers
+ in <command>smbclient</command> are binary. See also the lowercase command.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>queue</term>
+ <listitem><para>Displays the print queue, showing the job id,
+ name, size and current status. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>quit</term>
+ <listitem><para>See the exit command. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>rd &lt;directory name&gt;</term>
+ <listitem><para>See the rmdir command. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>recurse</term>
+ <listitem><para>Toggle directory recursion for the commands mget
+ and mput. </para>
+
+ <para>When toggled ON, these commands will process all directories
+ in the source directory (i.e., the directory they are copying
+ from ) and will recurse into any that match the mask specified
+ to the command. Only files that match the mask specified using
+ the mask command will be retrieved. See also the mask command.
+ </para>
+
+ <para>When recursion is toggled OFF, only files from the current
+ working directory on the source machine that match the mask specified
+ to the mget or mput commands will be copied, and any mask specified
+ using the mask command will be ignored. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>rm &lt;mask&gt;</term>
+ <listitem><para>Remove all files matching <replaceable>mask</replaceable> from the current
+ working directory on the server. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>rmdir &lt;directory name&gt;</term>
+ <listitem><para>Remove the specified directory (user access
+ privileges permitting) from the server. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>setmode &lt;filename&gt; &lt;perm=[+|\-]rsha&gt;</term>
+ <listitem><para>A version of the DOS attrib command to set
+ file permissions. For example: </para>
+
+ <para><command>setmode myfile +r </command></para>
+
+ <para>would make myfile read only. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>symlink source destination</term>
+ <listitem><para>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ create a symbolic hard link between the source and destination files. The source file
+ must not exist. Note that the server will not create a link to any path that lies
+ outside the currently connected share. This is enforced by the Samba server.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>tar &lt;c|x&gt;[IXbgNa]</term>
+ <listitem><para>Performs a tar operation - see the <parameter>-T
+ </parameter> command line option above. Behavior may be affected
+ by the tarmode command (see below). Using g (incremental) and N
+ (newer) will affect tarmode settings. Note that using the "-" option
+ with tar x may not work - use the command line option instead.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>blocksize &lt;blocksize&gt;</term>
+ <listitem><para>Blocksize. Must be followed by a valid (greater
+ than zero) blocksize. Causes tar file to be written out in
+ <replaceable>blocksize</replaceable>*TBLOCK (usually 512 byte) blocks. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>tarmode &lt;full|inc|reset|noreset&gt;</term>
+ <listitem><para>Changes tar's behavior with regard to archive
+ bits. In full mode, tar will back up everything regardless of the
+ archive bit setting (this is the default mode). In incremental mode,
+ tar will only back up files with the archive bit set. In reset mode,
+ tar will reset the archive bit on all files it backs up (implies
+ read/write share). </para></listitem>
+ </varlistentry>
+
+
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>NOTES</title>
+
+ <para>Some servers are fussy about the case of supplied usernames,
+ passwords, share names (AKA service names) and machine names.
+ If you fail to connect try giving all parameters in uppercase.
+ </para>
+
+ <para>It is often necessary to use the -n option when connecting
+ to some types of servers. For example OS/2 LanManager insists
+ on a valid NetBIOS name being used, so you need to supply a valid
+ name that would be known to the server.</para>
+
+ <para>smbclient supports long file names where the server
+ supports the LANMAN2 protocol or above. </para>
+</refsect1>
+
+<refsect1>
+ <title>ENVIRONMENT VARIABLES</title>
+
+ <para>The variable <envar>USER</envar> may contain the
+ username of the person using the client. This information is
+ used only if the protocol level is high enough to support
+ session-level passwords.</para>
+
+
+ <para>The variable <envar>PASSWD</envar> may contain
+ the password of the person using the client. This information is
+ used only if the protocol level is high enough to support
+ session-level passwords. </para>
+
+ <para>The variable <envar>LIBSMB_PROG</envar> may contain
+ the path, executed with system(), which the client should connect
+ to instead of connecting to a server. This functionality is primarily
+ intended as a development aid, and works best when using a LMHOSTS
+ file</para>
+</refsect1>
+
+
+<refsect1>
+ <title>INSTALLATION</title>
+
+ <para>The location of the client program is a matter for
+ individual system administrators. The following are thus
+ suggestions only. </para>
+
+ <para>It is recommended that the smbclient software be installed
+ in the <filename>/usr/local/samba/bin/</filename> or <filename>
+ /usr/samba/bin/</filename> directory, this directory readable
+ by all, writeable only by root. The client program itself should
+ be executable by all. The client should <emphasis>NOT</emphasis> be
+ setuid or setgid! </para>
+
+ <para>The client log files should be put in a directory readable
+ and writeable only by the user. </para>
+
+ <para>To test the client, you will need to know the name of a
+ running SMB/CIFS server. It is possible to run <command>smbd(8)
+ </command> as an ordinary user - running that server as a daemon
+ on a user-accessible port (typically any port number over 1024)
+ would provide a suitable test server. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>DIAGNOSTICS</title>
+
+ <para>Most diagnostics issued by the client are logged in a
+ specified log file. The log file name is specified at compile time,
+ but may be overridden on the command line. </para>
+
+ <para>The number and nature of diagnostics available depends
+ on the debug level used by the client. If you have problems,
+ set the debug level to 3 and peruse the log files. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbcontrol.1.sgml b/docs/docbook/manpages/smbcontrol.1.sgml
new file mode 100755
index 00000000000..d56a560b09f
--- /dev/null
+++ b/docs/docbook/manpages/smbcontrol.1.sgml
@@ -0,0 +1,189 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbcontrol">
+
+<refmeta>
+ <refentrytitle>smbcontrol</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbcontrol</refname>
+ <refpurpose>send messages to smbd, nmbd or winbindd processes</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbcontrol</command>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="req">-i</arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>smbcontrol</command>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="req">destination</arg>
+ <arg choice="req">message-type</arg>
+ <arg choice="opt">parameter</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>smbcontrol</command> is a very small program, which
+ sends messages to an <ulink url="smbd.8.html">smbd(8)</ulink>,
+ an <ulink url="nmbd.8.html">nmbd(8)</ulink>
+ or a <ulink url="winbindd.8.html">winbindd(8)</ulink>
+ daemon running on the system.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-d &lt;debuglevel&gt;</term>
+ <listitem><para>debuglevel is an integer from 0 to 10.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s &lt;smb.conf&gt;</term>
+ <listitem><para>This parameter specifies the pathname to
+ the Samba configuration file, <ulink url="smb.conf.5.html">
+ smb.conf(5)</ulink>. This file controls all aspects of
+ the Samba setup on the machine.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i</term>
+ <listitem><para>Run interactively. Individual commands
+ of the form destination message-type parameters can be entered
+ on STDIN. An empty command line or a "q" will quit the
+ program.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>destination</term>
+ <listitem><para>One of <parameter>nmbd</parameter>
+ <parameter>smbd</parameter> or a process ID.</para>
+
+ <para>The <parameter>smbd</parameter> destination causes the
+ message to "broadcast" to all smbd daemons.</para>
+
+ <para>The <parameter>nmbd</parameter> destination causes the
+ message to be sent to the nmbd daemon specified in the
+ <filename>nmbd.pid</filename> file.</para>
+
+ <para>If a single process ID is given, the message is sent
+ to only that process.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>message-type</term>
+ <listitem><para>One of: <constant>close-share</constant>,
+ <constant>debug</constant>,
+ <constant>force-election</constant>, <constant>ping
+ </constant>, <constant>profile</constant>, <constant>
+ debuglevel</constant>, <constant>profilelevel</constant>,
+ or <constant>printer-notify</constant>.</para>
+
+ <para>The <constant>close-share</constant> message-type sends a
+ message to smbd which will then close the client connections to
+ the named share. Note that this doesn't affect client connections
+ to any other shares. This message-type takes an argument of the
+ share name for which client connections will be closed, or the
+ "*" character which will close all currently open shares.
+ This may be useful if you made changes to the access controls on the share.
+ This message can only be sent to <constant>smbd</constant>.</para>
+
+ <para>The <constant>debug</constant> message-type allows
+ the debug level to be set to the value specified by the
+ parameter. This can be sent to any of the destinations.</para>
+
+ <para>The <constant>force-election</constant> message-type can only be
+ sent to the <constant>nmbd</constant> destination. This message
+ causes the <command>nmbd</command> daemon to force a new browse
+ master election.</para>
+
+ <para>The <constant>ping</constant> message-type sends the
+ number of "ping" messages specified by the parameter and waits
+ for the same number of reply "pong" messages. This can be sent to
+ any of the destinations.</para>
+
+ <para>The <constant>profile</constant> message-type sends a
+ message to an smbd to change the profile settings based on the
+ parameter. The parameter can be "on" to turn on profile stats
+ collection, "off" to turn off profile stats collection, "count"
+ to enable only collection of count stats (time stats are
+ disabled), and "flush" to zero the current profile stats. This can
+ be sent to any smbd or nmbd destinations.</para>
+
+ <para>The <constant>debuglevel</constant> message-type sends
+ a "request debug level" message. The current debug level setting
+ is returned by a "debuglevel" message. This can be
+ sent to any of the destinations.</para>
+
+ <para>The <constant>profilelevel</constant> message-type sends
+ a "request profile level" message. The current profile level
+ setting is returned by a "profilelevel" message. This can be sent
+ to any smbd or nmbd destinations.</para>
+
+ <para>The <constant>printer-notify</constant> message-type sends a
+ message to smbd which in turn sends a printer notify message to
+ any Windows NT clients connected to a printer. This message-type
+ takes an argument of the printer name to send notify messages to.
+ This message can only be sent to <constant>smbd</constant>.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>parameters</term>
+ <listitem><para>any parameters required for the message-type</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="nmbd.8.html"><command>nmbd(8)</command></ulink>,
+ and <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbd.8.sgml b/docs/docbook/manpages/smbd.8.sgml
new file mode 100755
index 00000000000..2afc86a6c83
--- /dev/null
+++ b/docs/docbook/manpages/smbd.8.sgml
@@ -0,0 +1,429 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbd">
+
+<refmeta>
+ <refentrytitle>smbd</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbd</refname>
+ <refpurpose>server to provide SMB/CIFS services to clients</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbd</command>
+ <arg choice="opt">-D</arg>
+ <arg choice="opt">-a</arg>
+ <arg choice="opt">-i</arg>
+ <arg choice="opt">-o</arg>
+ <arg choice="opt">-P</arg>
+ <arg choice="opt">-h</arg>
+ <arg choice="opt">-V</arg>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-l &lt;log directory&gt;</arg>
+ <arg choice="opt">-p &lt;port number&gt;</arg>
+ <arg choice="opt">-O &lt;socket option&gt;</arg>
+ <arg choice="opt">-s &lt;configuration file&gt;</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+ <para>This program is part of the Samba suite.</para>
+
+ <para><command>smbd</command> is the server daemon that
+ provides filesharing and printing services to Windows clients.
+ The server provides filespace and printer services to
+ clients using the SMB (or CIFS) protocol. This is compatible
+ with the LanManager protocol, and can service LanManager
+ clients. These include MSCLIENT 3.0 for DOS, Windows for
+ Workgroups, Windows 95/98/ME, Windows NT, Windows 2000,
+ OS/2, DAVE for Macintosh, and smbfs for Linux.</para>
+
+ <para>An extensive description of the services that the
+ server can provide is given in the man page for the
+ configuration file controlling the attributes of those
+ services (see <ulink url="smb.conf.5.html"><filename>smb.conf(5)
+ </filename></ulink>. This man page will not describe the
+ services, but will concentrate on the administrative aspects
+ of running the server.</para>
+
+ <para>Please note that there are significant security
+ implications to running this server, and the <ulink
+ url="smb.conf.5.html"><filename>smb.conf(5)</filename></ulink>
+ manpage should be regarded as mandatory reading before
+ proceeding with installation.</para>
+
+ <para>A session is created whenever a client requests one.
+ Each client gets a copy of the server for each session. This
+ copy then services all connections made by the client during
+ that session. When all connections from its client are closed,
+ the copy of the server for that client terminates.</para>
+
+ <para>The configuration file, and any files that it includes,
+ are automatically reloaded every minute, if they change. You
+ can force a reload by sending a SIGHUP to the server. Reloading
+ the configuration file will not affect connections to any service
+ that is already established. Either the user will have to
+ disconnect from the service, or <command>smbd</command> killed and restarted.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-D</term>
+ <listitem><para>If specified, this parameter causes
+ the server to operate as a daemon. That is, it detaches
+ itself and runs in the background, fielding requests
+ on the appropriate port. Operating the server as a
+ daemon is the recommended way of running <command>smbd</command> for
+ servers that provide more than casual use file and
+ print services. This switch is assumed if <command>smbd
+ </command> is executed on the command line of a shell.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-a</term>
+ <listitem><para>If this parameter is specified, each new
+ connection will append log messages to the log file.
+ This is the default.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i</term>
+ <listitem><para>If this parameter is specified it causes the
+ server to run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell. Setting this
+ parameter negates the implicit deamon mode when run from the
+ command line.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-o</term>
+ <listitem><para>If this parameter is specified, the
+ log files will be overwritten when opened. By default,
+ <command>smbd</command> will append entries to the log
+ files.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-P</term>
+ <listitem><para>Passive option. Causes <command>smbd</command> not to
+ send any network traffic out. Used for debugging by
+ the developers only.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Prints the help information (usage)
+ for <command>smbd</command>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v</term>
+ <listitem><para>Prints the version number for
+ <command>smbd</command>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-d &lt;debug level&gt;</term>
+ <listitem><para><replaceable>debuglevel</replaceable> is an integer
+ from 0 to 10. The default value if this parameter is
+ not specified is zero.</para>
+
+ <para>The higher this value, the more detail will be
+ logged to the log files about the activities of the
+ server. At level 0, only critical errors and serious
+ warnings will be logged. Level 1 is a reasonable level for
+ day to day running - it generates a small amount of
+ information about operations carried out.</para>
+
+ <para>Levels above 1 will generate considerable
+ amounts of log data, and should only be used when
+ investigating a problem. Levels above 3 are designed for
+ use only by developers and generate HUGE amounts of log
+ data, most of which is extremely cryptic.</para>
+
+ <para>Note that specifying this parameter here will
+ override the <ulink url="smb.conf.5.html#loglevel">log
+ level</ulink> parameter in the <ulink url="smb.conf.5.html">
+ <filename>smb.conf(5)</filename></ulink> file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l &lt;log directory&gt;</term>
+ <listitem><para>If specified,
+ <replaceable>log directory</replaceable>
+ specifies a log directory into which the "log.smbd" log
+ file will be created for informational and debug
+ messages from the running server. The log
+ file generated is never removed by the server although
+ its size may be controlled by the <ulink
+ url="smb.conf.5.html#maxlogsize">max log size</ulink>
+ option in the <ulink url="smb.conf.5.html"><filename>
+ smb.conf(5)</filename></ulink> file. <emphasis>Beware:</emphasis>
+ If the directory specified does not exist, <command>smbd</command>
+ will log to the default debug log location defined at compile time.
+ </para>
+
+ <para>The default log directory is specified at
+ compile time.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O &lt;socket options&gt;</term>
+ <listitem><para>See the <ulink
+ url="smb.conf.5.html#socketoptions">socket options</ulink>
+ parameter in the <ulink url="smb.conf.5.html"><filename>smb.conf(5)
+ </filename></ulink> file for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p &lt;port number&gt;</term>
+ <listitem><para><replaceable>port number</replaceable> is a positive integer
+ value. The default value if this parameter is not
+ specified is 139.</para>
+
+ <para>This number is the port number that will be
+ used when making connections to the server from client
+ software. The standard (well-known) port number for the
+ SMB over TCP is 139, hence the default. If you wish to
+ run the server as an ordinary user rather than
+ as root, most systems will require you to use a port
+ number greater than 1024 - ask your system administrator
+ for help if you are in this situation.</para>
+
+ <para>In order for the server to be useful by most
+ clients, should you configure it on a port other
+ than 139, you will require port redirection services
+ on port 139, details of which are outlined in rfc1002.txt
+ section 4.3.5.</para>
+
+ <para>This parameter is not normally specified except
+ in the above situation.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s &lt;configuration file&gt;</term>
+ <listitem><para>The file specified contains the
+ configuration details required by the server. The
+ information in this file includes server-specific
+ information such as what printcap file to use, as well
+ as descriptions of all the services that the server is
+ to provide. See <ulink url="smb.conf.5.html"><filename>
+ smb.conf(5)</filename></ulink> for more information.
+ The default configuration file name is determined at
+ compile time.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/inetd.conf</filename></term>
+ <listitem><para>If the server is to be run by the
+ <command>inetd</command> meta-daemon, this file
+ must contain suitable startup information for the
+ meta-daemon. See the <ulink url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink>
+ document for details.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/rc</filename></term>
+ <listitem><para>or whatever initialization script your
+ system uses).</para>
+
+ <para>If running the server as a daemon at startup,
+ this file will need to contain an appropriate startup
+ sequence for the server. See the <ulink url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink>
+ document for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/services</filename></term>
+ <listitem><para>If running the server via the
+ meta-daemon <command>inetd</command>, this file
+ must contain a mapping of service name (e.g., netbios-ssn)
+ to service port (e.g., 139) and protocol type (e.g., tcp).
+ See the <ulink url="UNIX_INSTALL.html">UNIX_INSTALL.html</ulink>
+ document for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/usr/local/samba/lib/smb.conf</filename></term>
+ <listitem><para>This is the default location of the
+ <ulink url="smb.conf.5.html"><filename>smb.conf</filename></ulink>
+ server configuration file. Other common places that systems
+ install this file are <filename>/usr/samba/lib/smb.conf</filename>
+ and <filename>/etc/smb.conf</filename>.</para>
+
+ <para>This file describes all the services the server
+ is to make available to clients. See <ulink url="smb.conf.5.html">
+ <filename>smb.conf(5)</filename></ulink> for more information.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>LIMITATIONS</title>
+ <para>On some systems <command>smbd</command> cannot change uid back
+ to root after a setuid() call. Such systems are called
+ trapdoor uid systems. If you have such a system,
+ you will be unable to connect from a client (such as a PC) as
+ two different users at once. Attempts to connect the
+ second user will result in access denied or
+ similar.</para>
+</refsect1>
+
+<refsect1>
+ <title>ENVIRONMENT VARIABLES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PRINTER</envar></term>
+ <listitem><para>If no printer name is specified to
+ printable services, most systems will use the value of
+ this variable (or <constant>lp</constant> if this variable is
+ not defined) as the name of the printer to use. This
+ is not specific to the server, however.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>PAM INTERACTION</title>
+ <para>Samba uses PAM for authentication (when presented with a plaintext
+ password), for account checking (is this account disabled?) and for
+ session management. The degree too which samba supports PAM is restricted
+ by the limitations of the SMB protocol and the
+ <ulink url="smb.conf.5.html#OBEYPAMRESRICTIONS">obey pam restricions</ulink>
+ smb.conf paramater. When this is set, the following restrictions apply:
+ </para>
+
+ <itemizedlist>
+ <listitem><para><emphasis>Account Validation</emphasis>: All acccesses to a
+ samba server are checked
+ against PAM to see if the account is vaild, not disabled and is permitted to
+ login at this time. This also applies to encrypted logins.
+ </para></listitem>
+
+ <listitem><para><emphasis>Session Management</emphasis>: When not using share
+ level secuirty, users must pass PAM's session checks before access
+ is granted. Note however, that this is bypassed in share level secuirty.
+ Note also that some older pam configuration files may need a line
+ added for session support.
+ </para></listitem>
+ </itemizedlist>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>TROUBLESHOOTING</title>
+
+ <para>
+ One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </para>
+
+ <para>Most diagnostics issued by the server are logged
+ in a specified log file. The log file name is specified
+ at compile time, but may be overridden on the command line.</para>
+
+ <para>The number and nature of diagnostics available depends
+ on the debug level used by the server. If you have problems, set
+ the debug level to 3 and peruse the log files.</para>
+
+ <para>Most messages are reasonably self-explanatory. Unfortunately,
+ at the time this man page was created, there are too many diagnostics
+ available in the source code to warrant describing each and every
+ diagnostic. At this stage your best bet is still to grep the
+ source code and inspect the conditions that gave rise to the
+ diagnostics you are seeing.</para>
+</refsect1>
+
+<refsect1>
+ <title>SIGNALS</title>
+
+ <para>Sending the <command>smbd</command> a SIGHUP will cause it to
+ reload its <filename>smb.conf</filename> configuration
+ file within a short period of time.</para>
+
+ <para>To shut down a user's <command>smbd</command> process it is recommended
+ that <command>SIGKILL (-9)</command> <emphasis>NOT</emphasis>
+ be used, except as a last resort, as this may leave the shared
+ memory area in an inconsistent state. The safe way to terminate
+ an <command>smbd</command> is to send it a SIGTERM (-15) signal and wait for
+ it to die on its own.</para>
+
+ <para>The debug log level of <command>smbd</command> may be raised
+ or lowered using <ulink url="smbcontrol.1.html"><command>smbcontrol(1)
+ </command></ulink> program (SIGUSR[1|2] signals are no longer used in
+ Samba 2.2). This is to allow transient problems to be diagnosed,
+ whilst still running at a normally low log level.</para>
+
+ <para>Note that as the signal handlers send a debug write,
+ they are not re-entrant in <command>smbd</command>. This you should wait until
+ <command>smbd</command> is in a state of waiting for an incoming SMB before
+ issuing them. It is possible to make the signal handlers safe
+ by un-blocking the signals before the select call and re-blocking
+ them after, however this would affect performance.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para>hosts_access(5), <command>inetd(8)</command>,
+ <ulink url="nmbd.8.html"><command>nmbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html"><filename>smb.conf(5)</filename>
+ </ulink>, <ulink url="smbclient.1.html"><command>smbclient(1)
+ </command></ulink>, <ulink url="testparm.1.html"><command>
+ testparm(1)</command></ulink>, <ulink url="testprns.1.html">
+ <command>testprns(1)</command></ulink>, and the Internet RFC's
+ <filename>rfc1001.txt</filename>, <filename>rfc1002.txt</filename>.
+ In addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page <ulink url="http://samba.org/cifs/">
+ http://samba.org/cifs/</ulink>.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbmnt.8.sgml b/docs/docbook/manpages/smbmnt.8.sgml
new file mode 100755
index 00000000000..55b66d5d25b
--- /dev/null
+++ b/docs/docbook/manpages/smbmnt.8.sgml
@@ -0,0 +1,113 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbmnt">
+
+<refmeta>
+ <refentrytitle>smbmnt</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbmnt</refname>
+ <refpurpose>helper utility for mounting SMB filesystems</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbmnt</command>
+ <arg choice="req">mount-point</arg>
+ <arg choice="opt">-s &lt;share&gt;</arg>
+ <arg choice="opt">-r</arg>
+ <arg choice="opt">-u &lt;uid&gt;</arg>
+ <arg choice="opt">-g &lt;gid&gt;</arg>
+ <arg choice="opt">-f &lt;mask&gt;</arg>
+ <arg choice="opt">-d &lt;mask&gt;</arg>
+ <arg choice="opt">-o &lt;options&gt;</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para><command>smbmnt</command> is a helper application used
+ by the smbmount program to do the actual mounting of SMB shares.
+ <command>smbmnt</command> can be installed setuid root if you want
+ normal users to be able to mount their SMB shares.</para>
+
+ <para>A setuid smbmnt will only allow mounts on directories owned
+ by the user, and that the user has write permission on.</para>
+
+ <para>The <command>smbmnt</command> program is normally invoked
+ by <ulink url="smbmount.8.html"><command>smbmount(8)</command>
+ </ulink>. It should not be invoked directly by users. </para>
+
+ <para>smbmount searches the normal PATH for smbmnt. You must ensure
+ that the smbmnt version in your path matches the smbmount used.</para>
+
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-r</term>
+ <listitem><para>mount the filesystem read-only
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-u uid</term>
+ <listitem><para>specify the uid that the files will
+ be owned by </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-g gid</term>
+ <listitem><para>specify the gid that the files will be
+ owned by </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f mask</term>
+ <listitem><para>specify the octal file mask applied
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-d mask</term>
+ <listitem><para>specify the octal directory mask
+ applied </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-o options</term>
+ <listitem><para>
+ list of options that are passed as-is to smbfs, if this
+ command is run on a 2.4 or higher Linux kernel.
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</para>
+
+ <para>The current maintainer of smbfs and the userspace
+ tools <command>smbmount</command>, <command>smbumount</command>,
+ and <command>smbmnt</command> is <ulink
+ url="mailto:urban@teststation.com">Urban Widmark</ulink>.
+ The <ulink url="mailto:samba@samba.org">SAMBA Mailing list</ulink>
+ is the preferred place to ask questions regarding these programs.
+ </para>
+
+ <para>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbmount.8.sgml b/docs/docbook/manpages/smbmount.8.sgml
new file mode 100755
index 00000000000..ec4dbbaff1f
--- /dev/null
+++ b/docs/docbook/manpages/smbmount.8.sgml
@@ -0,0 +1,327 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbmount">
+
+<refmeta>
+ <refentrytitle>smbmount</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbmount</refname>
+ <refpurpose>mount an smbfs filesystem</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbmount</command>
+ <arg choice="req">service</arg>
+ <arg choice="req">mount-point</arg>
+ <arg choice="opt">-o options</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para><command>smbmount</command> mounts a Linux SMB filesystem. It
+ is usually invoked as <command>mount.smbfs</command> by
+ the <command>mount(8)</command> command when using the
+ "-t smbfs" option. This command only works in Linux, and the kernel must
+ support the smbfs filesystem. </para>
+
+ <para>Options to <command>smbmount</command> are specified as a comma-separated
+ list of key=value pairs. It is possible to send options other
+ than those listed here, assuming that smbfs supports them. If
+ you get mount failures, check your kernel log for errors on
+ unknown options.</para>
+
+ <para><command>smbmount</command> is a daemon. After mounting it keeps running until
+ the mounted smbfs is umounted. It will log things that happen
+ when in daemon mode using the "machine name" smbmount, so
+ typically this output will end up in <filename>log.smbmount</filename>. The
+ <command>smbmount</command> process may also be called mount.smbfs.</para>
+
+ <para><emphasis>NOTE:</emphasis> <command>smbmount</command>
+ calls <command>smbmnt(8)</command> to do the actual mount. You
+ must make sure that <command>smbmnt</command> is in the path so
+ that it can be found. </para>
+
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>username=&lt;arg&gt;</term>
+ <listitem><para>specifies the username to connect as. If
+ this is not given, then the environment variable <envar>
+ USER</envar> is used. This option can also take the
+ form "user%password" or "user/workgroup" or
+ "user/workgroup%password" to allow the password and workgroup
+ to be specified as part of the username.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>password=&lt;arg&gt;</term>
+ <listitem><para>specifies the SMB password. If this
+ option is not given then the environment variable
+ <envar>PASSWD</envar> is used. If it can find
+ no password <command>smbmount</command> will prompt
+ for a passeword, unless the guest option is
+ given. </para>
+
+ <para>
+ Note that password which contain the arguement delimiter
+ character (i.e. a comma ',') will failed to be parsed correctly
+ on the command line. However, the same password defined
+ in the PASSWD environment variable or a credentials file (see
+ below) will be read correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>credentials=&lt;filename&gt;</term>
+ <listitem><para>specifies a file that contains a username
+ and/or password. The format of the file is:</para>
+
+ <para>
+ <programlisting>
+ username = &lt;value&gt;
+ password = &lt;value&gt;
+ </programlisting>
+ </para>
+
+ <para>This is preferred over having passwords in plaintext in a
+ shared file, such as <filename>/etc/fstab</filename>. Be sure to protect any
+ credentials file properly.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>netbiosname=&lt;arg&gt;</term>
+ <listitem><para>sets the source NetBIOS name. It defaults
+ to the local hostname. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>uid=&lt;arg&gt;</term>
+ <listitem><para>sets the uid that will own all files on
+ the mounted filesystem.
+ It may be specified as either a username or a numeric uid.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>gid=&lt;arg&gt;</term>
+ <listitem><para>sets the gid that will own all files on
+ the mounted filesystem.
+ It may be specified as either a groupname or a numeric
+ gid. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>port=&lt;arg&gt;</term>
+ <listitem><para>sets the remote SMB port number. The default
+ is 139. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>fmask=&lt;arg&gt;</term>
+ <listitem><para>sets the file mask. This determines the
+ permissions that remote files have in the local filesystem.
+ The default is based on the current umask. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>dmask=&lt;arg&gt;</term>
+ <listitem><para>sets the directory mask. This determines the
+ permissions that remote directories have in the local filesystem.
+ The default is based on the current umask. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>debug=&lt;arg&gt;</term>
+ <listitem><para>sets the debug level. This is useful for
+ tracking down SMB connection problems. A suggested value to
+ start with is 4. If set too high there will be a lot of
+ output, possibly hiding the useful output.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>ip=&lt;arg&gt;</term>
+ <listitem><para>sets the destination host or IP address.
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>workgroup=&lt;arg&gt;</term>
+ <listitem><para>sets the workgroup on the destination </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>sockopt=&lt;arg&gt;</term>
+ <listitem><para>sets the TCP socket options. See the <ulink
+ url="smb.conf.5.html#SOCKETOPTIONS"><filename>smb.conf
+ </filename></ulink> <parameter>socket options</parameter> option.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>scope=&lt;arg&gt;</term>
+ <listitem><para>sets the NetBIOS scope </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>guest</term>
+ <listitem><para>don't prompt for a password </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>ro</term>
+ <listitem><para>mount read-only </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>rw</term><listitem><para>mount read-write </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>iocharset=&lt;arg&gt;</term>
+ <listitem><para>
+ sets the charset used by the Linux side for codepage
+ to charset translations (NLS). Argument should be the
+ name of a charset, like iso8859-1. (Note: only kernel
+ 2.4.0 or later)
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>codepage=&lt;arg&gt;</term>
+ <listitem><para>
+ sets the codepage the server uses. See the iocharset
+ option. Example value cp850. (Note: only kernel 2.4.0
+ or later)
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ttl=&lt;arg&gt;</term>
+ <listitem><para>
+ how long a directory listing is cached in milliseconds
+ (also affects visibility of file size and date
+ changes). A higher value means that changes on the
+ server take longer to be noticed but it can give
+ better performance on large directories, especially
+ over long distances. Default is 1000ms but something
+ like 10000ms (10 seconds) is probably more reasonable
+ in many cases.
+ (Note: only kernel 2.4.2 or later)
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+
+
+</refsect1>
+
+<refsect1>
+ <title>ENVIRONMENT VARIABLES</title>
+
+ <para>The variable <envar>USER</envar> may contain the username of the
+ person using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords. The variable can be used to set both username and
+ password by using the format username%password.</para>
+
+ <para>The variable <envar>PASSWD</envar> may contain the password of the
+ person using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords.</para>
+
+ <para>The variable <envar>PASSWD_FILE</envar> may contain the pathname
+ of a file to read the password from. A single line of input is
+ read and used as the password.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>BUGS</title>
+
+ <para>Passwords and other options containing , can not be handled.
+ For passwords an alternative way of passing them is in a credentials
+ file or in the PASSWD environment.</para>
+
+ <para>The credentials file does not handle usernames or passwords with
+ leading space.</para>
+
+ <para>One smbfs bug is important enough to mention here, even if it
+ is a bit misplaced:</para>
+
+ <itemizedlist>
+
+ <listitem><para>Mounts sometimes stop working. This is usually
+ caused by smbmount terminating. Since smbfs needs smbmount to
+ reconnect when the server disconnects, the mount will eventually go
+ dead. An umount/mount normally fixes this. At least 2 ways to
+ trigger this bug are known.</para></listitem>
+
+ </itemizedlist>
+
+ <para>Note that the typical response to a bug report is suggestion
+ to try the latest version first. So please try doing that first,
+ and always include which versions you use of relevant software
+ when reporting bugs (minimum: samba, kernel, distribution)</para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>SEE ALSO</title>
+
+ <para>Documentation/filesystems/smbfs.txt in the linux kernel
+ source tree may contain additional options and information.</para>
+
+ <para>FreeBSD also has a smbfs, but it is not related to smbmount</para>
+
+ <para>For Solaris, HP-UX and others you may want to look at
+ <ulink url="smbsh.1.html"><command>smbsh(1)</command></ulink> or at other
+ solutions, such as sharity or perhaps replacing the SMB server with
+ a NFS server.</para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</para>
+
+ <para>The current maintainer of smbfs and the userspace
+ tools <command>smbmount</command>, <command>smbumount</command>,
+ and <command>smbmnt</command> is <ulink
+ url="mailto:urban@teststation.com">Urban Widmark</ulink>.
+ The <ulink url="mailto:samba@samba.org">SAMBA Mailing list</ulink>
+ is the preferred place to ask questions regarding these programs.
+ </para>
+
+ <para>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbpasswd.5.sgml b/docs/docbook/manpages/smbpasswd.5.sgml
new file mode 100755
index 00000000000..c207074a9b1
--- /dev/null
+++ b/docs/docbook/manpages/smbpasswd.5.sgml
@@ -0,0 +1,204 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbpasswd">
+
+<refmeta>
+ <refentrytitle>smbpasswd</refentrytitle>
+ <manvolnum>5</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbpasswd</refname>
+ <refpurpose>The Samba encrypted password file</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <para><filename>smbpasswd</filename></para>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>smbpasswd is the Samba encrypted password file. It contains
+ the username, Unix user id and the SMB hashed passwords of the
+ user, as well as account flag information and the time the
+ password was last changed. This file format has been evolving with
+ Samba and has had several different formats in the past. </para>
+</refsect1>
+
+<refsect1>
+ <title>FILE FORMAT</title>
+
+ <para>The format of the smbpasswd file used by Samba 2.2
+ is very similar to the familiar Unix <filename>passwd(5)</filename>
+ file. It is an ASCII file containing one line for each user. Each field
+ within each line is separated from the next by a colon. Any entry
+ beginning with '#' is ignored. The smbpasswd file contains the
+ following information for each user: </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>name</term>
+ <listitem><para> This is the user name. It must be a name that
+ already exists in the standard UNIX passwd file. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>uid</term>
+ <listitem><para>This is the UNIX uid. It must match the uid
+ field for the same user entry in the standard UNIX passwd file.
+ If this does not match then Samba will refuse to recognize
+ this smbpasswd file entry as being valid for a user.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>Lanman Password Hash</term>
+ <listitem><para>This is the LANMAN hash of the user's password,
+ encoded as 32 hex digits. The LANMAN hash is created by DES
+ encrypting a well known string with the user's password as the
+ DES key. This is the same password used by Windows 95/98 machines.
+ Note that this password hash is regarded as weak as it is
+ vulnerable to dictionary attacks and if two users choose the
+ same password this entry will be identical (i.e. the password
+ is not "salted" as the UNIX password is). If the user has a
+ null password this field will contain the characters "NO PASSWORD"
+ as the start of the hex string. If the hex string is equal to
+ 32 'X' characters then the user's account is marked as
+ <constant>disabled</constant> and the user will not be able to
+ log onto the Samba server. </para>
+
+ <para><emphasis>WARNING !!</emphasis> Note that, due to
+ the challenge-response nature of the SMB/CIFS authentication
+ protocol, anyone with a knowledge of this password hash will
+ be able to impersonate the user on the network. For this
+ reason these hashes are known as <emphasis>plain text
+ equivalents</emphasis> and must <emphasis>NOT</emphasis> be made
+ available to anyone but the root user. To protect these passwords
+ the smbpasswd file is placed in a directory with read and
+ traverse access only to the root user and the smbpasswd file
+ itself must be set to be read/write only by root, with no
+ other access. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>NT Password Hash</term>
+ <listitem><para>This is the Windows NT hash of the user's
+ password, encoded as 32 hex digits. The Windows NT hash is
+ created by taking the user's password as represented in
+ 16-bit, little-endian UNICODE and then applying the MD4
+ (internet rfc1321) hashing algorithm to it. </para>
+
+ <para>This password hash is considered more secure than
+ the LANMAN Password Hash as it preserves the case of the
+ password and uses a much higher quality hashing algorithm.
+ However, it is still the case that if two users choose the same
+ password this entry will be identical (i.e. the password is
+ not "salted" as the UNIX password is). </para>
+
+ <para><emphasis>WARNING !!</emphasis>. Note that, due to
+ the challenge-response nature of the SMB/CIFS authentication
+ protocol, anyone with a knowledge of this password hash will
+ be able to impersonate the user on the network. For this
+ reason these hashes are known as <emphasis>plain text
+ equivalents</emphasis> and must <emphasis>NOT</emphasis> be made
+ available to anyone but the root user. To protect these passwords
+ the smbpasswd file is placed in a directory with read and
+ traverse access only to the root user and the smbpasswd file
+ itself must be set to be read/write only by root, with no
+ other access. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>Account Flags</term>
+ <listitem><para>This section contains flags that describe
+ the attributes of the users account. In the Samba 2.2 release
+ this field is bracketed by '[' and ']' characters and is always
+ 13 characters in length (including the '[' and ']' characters).
+ The contents of this field may be any of the characters.
+ </para>
+
+ <itemizedlist>
+ <listitem><para><emphasis>U</emphasis> - This means
+ this is a "User" account, i.e. an ordinary user. Only User
+ and Workstation Trust accounts are currently supported
+ in the smbpasswd file. </para></listitem>
+
+ <listitem><para><emphasis>N</emphasis> - This means the
+ account has no password (the passwords in the fields LANMAN
+ Password Hash and NT Password Hash are ignored). Note that this
+ will only allow users to log on with no password if the <parameter>
+ null passwords</parameter> parameter is set in the <ulink
+ url="smb.conf.5.html#NULLPASSWORDS"><filename>smb.conf(5)
+ </filename></ulink> config file. </para></listitem>
+
+ <listitem><para><emphasis>D</emphasis> - This means the account
+ is disabled and no SMB/CIFS logins will be allowed for
+ this user. </para></listitem>
+
+ <listitem><para><emphasis>W</emphasis> - This means this account
+ is a "Workstation Trust" account. This kind of account is used
+ in the Samba PDC code stream to allow Windows NT Workstations
+ and Servers to join a Domain hosted by a Samba PDC. </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Other flags may be added as the code is extended in future.
+ The rest of this field space is filled in with spaces. </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>Last Change Time</term>
+ <listitem><para>This field consists of the time the account was
+ last modified. It consists of the characters 'LCT-' (standing for
+ "Last Change Time") followed by a numeric encoding of the UNIX time
+ in seconds since the epoch (1970) that the last change was made.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>All other colon separated fields are ignored at this time.</para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink>,
+ <ulink url="samba.7.html">samba(7)</ulink>, and
+ the Internet RFC1321 for details on the MD4 algorithm.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbpasswd.8.sgml b/docs/docbook/manpages/smbpasswd.8.sgml
new file mode 100755
index 00000000000..40693e627bd
--- /dev/null
+++ b/docs/docbook/manpages/smbpasswd.8.sgml
@@ -0,0 +1,514 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbpasswd">
+
+<refmeta>
+ <refentrytitle>smbpasswd</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbpasswd</refname>
+ <refpurpose>change a user's SMB password</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <para>When run by root:</para>
+ <cmdsynopsis>
+ <command>smbpasswd</command>
+ <arg choice="opt">options</arg>
+ <arg choice="opt">username</arg>
+ <arg choice="opt">password</arg>
+ </cmdsynopsis>
+ <para>otherwise:</para>
+ <cmdsynopsis>
+ <command>smbpasswd</command>
+ <arg choice="opt">options</arg>
+ <arg choice="opt">password</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>The smbpasswd program has several different
+ functions, depending on whether it is run by the <emphasis>root</emphasis>
+ user or not. When run as a normal user it allows the user to change
+ the password used for their SMB sessions on any machines that store
+ SMB passwords. </para>
+
+ <para>By default (when run with no arguments) it will attempt to
+ change the current user's SMB password on the local machine. This is
+ similar to the way the <command>passwd(1)</command> program works.
+ <command>smbpasswd</command> differs from how the passwd program works
+ however in that it is not <emphasis>setuid root</emphasis> but works in
+ a client-server mode and communicates with a locally running
+ <command>smbd(8)</command>. As a consequence in order for this to
+ succeed the smbd daemon must be running on the local machine. On a
+ UNIX machine the encrypted SMB passwords are usually stored in
+ the <filename>smbpasswd(5)</filename> file. </para>
+
+ <para>When run by an ordinary user with no options. smbpasswd
+ will prompt them for their old SMB password and then ask them
+ for their new password twice, to ensure that the new password
+ was typed correctly. No passwords will be echoed on the screen
+ whilst being typed. If you have a blank SMB password (specified by
+ the string "NO PASSWORD" in the smbpasswd file) then just press
+ the &lt;Enter&gt; key when asked for your old password. </para>
+
+ <para>smbpasswd can also be used by a normal user to change their
+ SMB password on remote machines, such as Windows NT Primary Domain
+ Controllers. See the (-r) and -U options below. </para>
+
+ <para>When run by root, smbpasswd allows new users to be added
+ and deleted in the smbpasswd file, as well as allows changes to
+ the attributes of the user in this file to be made. When run by root,
+ <command>smbpasswd</command> accesses the local smbpasswd file
+ directly, thus enabling changes to be made even if smbd is not
+ running. </para>
+
+ <para><command>smbpasswd</command> can also be used to retrieve
+ the SIDs related to previous incarnations of this server on the
+ same machine, as well as set the SID of this domain. This is needed
+ in those cases when the admin changes the NetBIOS or DNS name of
+ the server without realizing that doing so will change the SID of
+ the server as well. See the -W and -X options below. </para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>-L</term>
+ <listitem><para>Run the smbpasswd command in local mode. This
+ allows a non-root user to specify the root-only options. This
+ is used mostly in test environments where a non-root user needs
+ to make changes to the local <filename>smbpasswd</filename> file.
+ The <filename>smbpasswd</filename> file must have read/write
+ permissions for the user running the command.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>This option prints the help string for
+ <command>smbpasswd</command>. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-c smb.conf file</term>
+ <listitem><para>This option specifies that the configuration
+ file specified should be used instead of the default value
+ specified at compile time. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-D debuglevel</term>
+ <listitem><para><replaceable>debuglevel</replaceable> is an integer
+ from 0 to 10. The default value if this parameter is not specified
+ is zero. </para>
+
+ <para>The higher this value, the more detail will be logged to the
+ log files about the activities of smbpasswd. At level 0, only
+ critical errors and serious warnings will be logged. </para>
+
+ <para>Levels above 1 will generate considerable amounts of log
+ data, and should only be used when investigating a problem. Levels
+ above 3 are designed for use only by developers and generate
+ HUGE amounts of log data, most of which is extremely cryptic.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-r remote machine name</term>
+ <listitem><para>This option allows a user to specify what machine
+ they wish to change their password on. Without this parameter
+ smbpasswd defaults to the local host. The <replaceable>remote
+ machine name</replaceable> is the NetBIOS name of the SMB/CIFS
+ server to contact to attempt the password change. This name is
+ resolved into an IP address using the standard name resolution
+ mechanism in all programs of the Samba suite. See the <parameter>-R
+ name resolve order</parameter> parameter for details on changing
+ this resolving mechanism. </para>
+
+ <para>The username whose password is changed is that of the
+ current UNIX logged on user. See the <parameter>-U username</parameter>
+ parameter for details on changing the password for a different
+ username. </para>
+
+ <para>Note that if changing a Windows NT Domain password the
+ remote machine specified must be the Primary Domain Controller for
+ the domain (Backup Domain Controllers only have a read-only
+ copy of the user account database and will not allow the password
+ change).</para>
+
+ <para><emphasis>Note</emphasis> that Windows 95/98 do not have
+ a real password database so it is not possible to change passwords
+ specifying a Win95/98 machine as remote machine target. </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-s</term>
+ <listitem><para>This option causes smbpasswd to be silent (i.e.
+ not issue prompts) and to read its old and new passwords from
+ standard input, rather than from <filename>/dev/tty</filename>
+ (like the <command>passwd(1)</command> program does). This option
+ is to aid people writing scripts to drive smbpasswd</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-S</term>
+ <listitem><para>This option causes <command>smbpasswd</command>
+ to query a domain controller of the domain specified
+ by the <ulink url="smb.conf.5.html#WORKGROUP">workgroup</ulink>
+ parameter in <filename>smb.conf</filename> and store the
+ domain SID in the <filename>secrets.tdb</filename> file
+ as its own machine SID. This is only useful when configuring
+ a Samba PDC and Samba BDC, or when migrating from a Windows PDC
+ to a Samba PDC. </para>
+
+ <para>The <parameter>-r</parameter> options can be used
+ as well to indicate a specific domain controller which should
+ be contacted. In this case, the domain SID obtained is the
+ one for the domain to which the remote machine belongs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-t</term>
+ <listitem><para>This option is used to force smbpasswd to
+ change the current password assigned to the machine trust account
+ when operating in domain security mode. This is really meant to
+ be used on systems that only run <ulink url="winbindd.8.html"<command>winbindd</command></ulink>.
+ Under server installations, <ulink url="smbd.8.html"><command>smbd</command></ulink>
+ handle the password updates automatically.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-T</term>
+ <listitem><para>The <parameter>-T</parameter> option may be used to
+ force samba to use a previously created trust account by allowing
+ the trust account hash to be set in the secrets database only.
+ This way, an application can change the trust account password
+ and call "smbpasswd -T" so that Samba can continue to work.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-U username[%pass]</term>
+ <listitem><para>This option may only be used in conjunction
+ with the <parameter>-r</parameter> option. When changing
+ a password on a remote machine it allows the user to specify
+ the user name on that machine whose password will be changed. It
+ is present to allow users who have different user names on
+ different systems to change these passwords. The optional
+ %pass may be used to specify to old password.</para>
+
+ <para>In particular, this parameter specifies the username
+ used to create the machine account when invoked with -j</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term> -W S-1-5-21-x-y-z</term>
+ <listitem><para>This option forces the SID S-1-5-21-x-y-z to
+ be the server and domain SID for the current Samba server. It
+ does this by updating the appropriate keys in the secrets
+ file. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term> -X server|domain</term>
+ <listitem><para>This option allows the admin to retrieve the
+ SID associated with a former servername or domain name that
+ this Samba server might have used. It does this by retrieving
+ the appropriate entry from the secrets file.</para>
+ </listitem>
+ </varlistentry>
+
+<varlistentry>
+<term><command>NOTE:</command></term>
+<listitem><para>
+<command>The following options are available only when the smbpasswd command is
+run as root or in local mode.</command>
+</para></listitem>
+</varlistentry>
+
+ <varlistentry>
+ <term>-a</term>
+ <listitem><para>This option specifies that the username
+ following should be added to the local smbpasswd file, with the
+ new password typed. This
+ option is ignored if the username specified already exists in
+ the smbpasswd file and it is treated like a regular change
+ password command. Note that the user to be added must already exist
+ in the system password file (usually <filename>/etc/passwd</filename>)
+ else the request to add the user will fail. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-d</term>
+ <listitem><para>This option specifies that the username following
+ should be <constant>disabled</constant> in the local smbpasswd
+ file. This is done by writing a <constant>'D'</constant> flag
+ into the account control space in the smbpasswd file. Once this
+ is done all attempts to authenticate via SMB using this username
+ will fail. </para>
+
+ <para>If the smbpasswd file is in the 'old' format (pre-Samba 2.0
+ format) there is no space in the user's password entry to write
+ this information and so the user is disabled by writing 'X' characters
+ into the password space in the smbpasswd file. See <command>smbpasswd(5)
+ </command> for details on the 'old' and new password file formats.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-e</term>
+ <listitem><para>This option specifies that the username following
+ should be <constant>enabled</constant> in the local smbpasswd file,
+ if the account was previously disabled. If the account was not
+ disabled this option has no effect. Once the account is enabled then
+ the user will be able to authenticate via SMB once again. </para>
+
+ <para>If the smbpasswd file is in the 'old' format, then <command>
+ smbpasswd</command> will prompt for a new password for this user,
+ otherwise the account will be enabled by removing the <constant>'D'
+ </constant> flag from account control space in the <filename>
+ smbpasswd</filename> file. See <command>smbpasswd (5)</command> for
+ details on the 'old' and new password file formats. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-m</term>
+ <listitem><para>This option tells smbpasswd that the account
+ being changed is a MACHINE account. Currently this is used
+ when Samba is being used as an NT Primary Domain Controller.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-n</term>
+ <listitem><para>This option specifies that the username following
+ should have their password set to null (i.e. a blank password) in
+ the local smbpasswd file. This is done by writing the string "NO
+ PASSWORD" as the first part of the first password stored in the
+ smbpasswd file. </para>
+
+ <para>Note that to allow users to logon to a Samba server once
+ the password has been set to "NO PASSWORD" in the smbpasswd
+ file the administrator must set the following parameter in the [global]
+ section of the <filename>smb.conf</filename> file : </para>
+
+ <para><command>null passwords = yes</command></para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-w password</term>
+ <listitem><para>This parameter is only available is Samba
+ has been configured to use the experimental
+ <command>--with-ldapsam</command> option. The <parameter>-w</parameter>
+ switch is used to specify the password to be used with the
+ <ulink url="smb.conf.5.html#LDAPADMINDN"><parameter>ldap admin
+ dn</parameter></ulink>. Note that the password is stored in
+ the <filename>private/secrets.tdb</filename> and is keyed off
+ of the admin's DN. This means that if the value of <parameter>ldap
+ admin dn</parameter> ever changes, the password will need to be
+ manually updated as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-x</term>
+ <listitem><para>This option specifies that the username
+ following should be deleted from the local smbpasswd file.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-j DOMAIN</term>
+ <listitem><para>This option is used to add a Samba server
+ into a Windows NT Domain, as a Domain member capable of authenticating
+ user accounts to any Domain Controller in the same way as a Windows
+ NT Server. See the <command>security = domain</command> option in
+ the <filename>smb.conf(5)</filename> man page. </para>
+
+ <para>This command can work both with and without the -U parameter. </para>
+
+ <para>When invoked with -U, that username (and optional password) are
+ used to contact the PDC (which must be specified with -r) to both
+ create a machine account, and to set a password on it.</para>
+
+ <para>Alternately, if -U is omitted, Samba will contact its PDC
+ and attempt to change the password on a pre-existing account. </para>
+
+ <para>In order to be used in this way, the Administrator for
+ the Windows NT Domain must have used the program "Server Manager
+ for Domains" to add the primary NetBIOS name of the Samba server
+ as a member of the Domain. </para>
+
+ <para>After this has been done, to join the Domain invoke <command>
+ smbpasswd</command> with this parameter. smbpasswd will then
+ look up the Primary Domain Controller for the Domain (found in
+ the <filename>smb.conf</filename> file in the parameter
+ <parameter>password server</parameter> and change the machine account
+ password used to create the secure Domain communication. </para>
+
+ <para>Either way, this password is then stored by smbpasswd in a TDB,
+ writeable only by root, called <filename>secrets.tdb</filename> </para>
+
+ <para>Once this operation has been performed the <filename>
+ smb.conf</filename> file may be updated to set the <command>
+ security = domain</command> option and all future logins
+ to the Samba server will be authenticated to the Windows NT
+ PDC. </para>
+
+ <para>Note that even though the authentication is being
+ done to the PDC all users accessing the Samba server must still
+ have a valid UNIX account on that machine.
+ The <command>winbindd(8)</command> daemon can be used
+ to create UNIX accounts for NT users.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-R name resolve order</term>
+ <listitem><para>This option allows the user of smbpasswd to determine
+ what name resolution services to use when looking up the NetBIOS
+ name of the host being connected to. </para>
+
+ <para>The options are :"lmhosts", "host", "wins" and "bcast". They cause
+ names to be resolved as follows : </para>
+ <itemizedlist>
+ <listitem><para><constant>lmhosts</constant> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <ulink
+ url="lmhosts.5.html">lmhosts(5)</ulink> for details) then
+ any name type matches for lookup.</para></listitem>
+
+ <listitem><para><constant>host</constant> : Do a standard host
+ name to IP address resolution, using the system <filename>/etc/hosts
+ </filename>, NIS, or DNS lookups. This method of name resolution
+ is operating system dependent. For instance, on IRIX or Solaris this
+ may be controlled by the <filename>/etc/nsswitch.conf</filename>
+ file). Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</para></listitem>
+
+ <listitem><para><constant>wins</constant> : Query a name with
+ the IP address listed in the <parameter>wins server</parameter>
+ parameter. If no WINS server has been specified this method
+ will be ignored.</para></listitem>
+
+ <listitem><para><constant>bcast</constant> : Do a broadcast on
+ each of the known local interfaces listed in the
+ <parameter>interfaces</parameter> parameter. This is the least
+ reliable of the name resolution methods as it depends on the
+ target host being on a locally connected subnet.</para></listitem>
+ </itemizedlist>
+
+ <para>The default order is <command>lmhosts, host, wins, bcast</command>
+ and without this parameter or any entry in the
+ <filename>smb.conf</filename> file the name resolution methods will
+ be attempted in this order. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>username</term>
+ <listitem><para>This specifies the username for all of the
+ <emphasis>root only</emphasis> options to operate on. Only root
+ can specify this parameter as only root has the permission needed
+ to modify attributes directly in the local smbpasswd file.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>password</term>
+ <listitem><para>This specifies the new password. If this parameter
+ is specified you will not be prompted for the new password.
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>NOTES</title>
+
+ <para>Since <command>smbpasswd</command> works in client-server
+ mode communicating with a local smbd for a non-root user then
+ the smbd daemon must be running for this to work. A common problem
+ is to add a restriction to the hosts that may access the <command>
+ smbd</command> running on the local machine by specifying a
+ <parameter>allow hosts</parameter> or <parameter>deny hosts</parameter>
+ entry in the <filename>smb.conf</filename> file and neglecting to
+ allow "localhost" access to the smbd. </para>
+
+ <para>In addition, the smbpasswd command is only useful if Samba
+ has been set up to use encrypted passwords. See the file
+ <filename>ENCRYPTION.txt</filename> in the docs directory for details
+ on how to do this. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbpasswd.5.html"><filename>smbpasswd(5)</filename></ulink>,
+ <ulink url="samba.7.html">samba(7)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbsh.1.sgml b/docs/docbook/manpages/smbsh.1.sgml
new file mode 100755
index 00000000000..82efb334ba7
--- /dev/null
+++ b/docs/docbook/manpages/smbsh.1.sgml
@@ -0,0 +1,235 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbsh">
+
+<refmeta>
+ <refentrytitle>smbsh</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbsh</refname>
+ <refpurpose>Allows access to Windows NT filesystem
+ using UNIX commands</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbsh</command>
+ <arg choice="opt">-W workgroup</arg>
+ <arg choice="opt">-U username</arg>
+ <arg choice="opt">-P prefix</arg>
+ <arg choice="opt">-R &lt;name resolve order&gt;</arg>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-l logfile</arg>
+ <arg choice="opt">-L libdir</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>smbsh</command> allows you to access an NT filesystem
+ using UNIX commands such as <command>ls</command>, <command>
+ egrep</command>, and <command>rcp</command>. You must use a
+ shell that is dynamically linked in order for <command>smbsh</command>
+ to work correctly.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-W WORKGROUP</term>
+ <listitem><para>Override the default workgroup specified in the
+ workgroup parameter of the <filename>smb.conf</filename> file
+ for this session. This may be needed to connect to some
+ servers. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-U username[%pass]</term>
+ <listitem><para>Sets the SMB username or username and password.
+ If this option is not specified, the user will be prompted for
+ both the username and the password. If %pass is not specified,
+ the user will be prompted for the password.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-P prefix</term><listitem><para>This option allows
+ the user to set the directory prefix for SMB access. The
+ default value if this option is not specified is
+ <emphasis>smb</emphasis>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R &lt;name resolve order&gt;</term>
+ <listitem><para>This option is used to determine what naming
+ services and in what order to resolve
+ host names to IP addresses. The option takes a space-separated
+ string of different name resolution options.</para>
+
+ <para>The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :</para>
+
+ <itemizedlist>
+ <listitem><para><constant>lmhosts</constant> :
+ Lookup an IP address in the Samba lmhosts file. If the
+ line in lmhosts has no name type attached to the
+ NetBIOS name
+ (see the <ulink url="lmhosts.5.html">lmhosts(5)</ulink>
+ for details) then any name type matches for lookup.
+ </para></listitem>
+
+ <listitem><para><constant>host</constant> :
+ Do a standard host name to IP address resolution, using
+ the system <filename>/etc/hosts</filename>, NIS, or DNS
+ lookups. This method of name resolution is operating
+ system dependent, for instance on IRIX or Solaris this
+ may be controlled by the <filename>/etc/nsswitch.conf
+ </filename> file). Note that this method is only used
+ if the NetBIOS name type being queried is the 0x20
+ (server) name type, otherwise it is ignored.
+ </para></listitem>
+
+ <listitem><para><constant>wins</constant> :
+ Query a name with the IP address listed in the
+ <parameter>wins server</parameter> parameter. If no
+ WINS server has been specified this method will be
+ ignored.
+ </para></listitem>
+
+ <listitem><para><constant>bcast</constant> :
+ Do a broadcast on each of the known local interfaces
+ listed in the <parameter>interfaces</parameter>
+ parameter. This is the least reliable of the name
+ resolution methods as it depends on the target host
+ being on a locally connected subnet.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>If this parameter is not set then the name resolve order
+ defined in the <filename>smb.conf</filename> file parameter
+ (name resolve order) will be used. </para>
+
+ <para>The default order is lmhosts, host, wins, bcast. Without
+ this parameter or any entry in the <parameter>name resolve order
+ </parameter> parameter of the <filename>smb.conf</filename>
+ file, the name resolution methods will be attempted in this
+ order. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-d &lt;debug level&gt;</term>
+ <listitem><para>debug level is an integer from 0 to 10.</para>
+
+ <para>The default value if this parameter is not specified
+ is zero.</para>
+
+ <para>The higher this value, the more detail will be logged
+ about the activities of <command>nmblookup</command>. At level
+ 0, only critical errors and serious warnings will be logged.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l logfilename</term>
+ <listitem><para>If specified causes all debug messages to be
+ written to the file specified by <replaceable>logfilename
+ </replaceable>. If not specified then all messages will be
+ written to<replaceable>stderr</replaceable>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-L libdir</term>
+ <listitem><para>This parameter specifies the location of the
+ shared libraries used by <command>smbsh</command>. The default
+ value is specified at compile time.
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para>To use the <command>smbsh</command> command, execute <command>
+ smbsh</command> from the prompt and enter the username and password
+ that authenticates you to the machine running the Windows NT
+ operating system.</para>
+
+ <para><programlisting>
+ <prompt>system% </prompt><userinput>smbsh</userinput>
+ <prompt>Username: </prompt><userinput>user</userinput>
+ <prompt>Password: </prompt><userinput>XXXXXXX</userinput>
+ </programlisting></para>
+
+
+ <para>Any dynamically linked command you execute from
+ this shell will access the <filename>/smb</filename> directory
+ using the smb protocol. For example, the command <command>ls /smb
+ </command> will show a list of workgroups. The command
+ <command>ls /smb/MYGROUP </command> will show all the machines in
+ the workgroup MYGROUP. The command
+ <command>ls /smb/MYGROUP/&lt;machine-name&gt;</command> will show the share
+ names for that machine. You could then, for example, use the <command>
+ cd</command> command to change directories, <command>vi</command> to
+ edit files, and <command>rcp</command> to copy files.</para>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>BUGS</title>
+
+ <para><command>smbsh</command> works by intercepting the standard
+ libc calls with the dynamically loaded versions in <filename>
+ smbwrapper.o</filename>. Not all calls have been "wrapped", so
+ some programs may not function correctly under <command>smbsh
+ </command>.</para>
+
+ <para>Programs which are not dynamically linked cannot make
+ use of <command>smbsh</command>'s functionality. Most versions
+ of UNIX have a <command>file</command> command that will
+ describe how a program was linked.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbspool.8.sgml b/docs/docbook/manpages/smbspool.8.sgml
new file mode 100755
index 00000000000..d5c9c0a1148
--- /dev/null
+++ b/docs/docbook/manpages/smbspool.8.sgml
@@ -0,0 +1,131 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbspool">
+
+<refmeta>
+ <refentrytitle>smbspool</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbspool</refname>
+ <refpurpose>send print file to an SMB printer</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbspool</command>
+ <arg>job</arg>
+ <arg>user</arg>
+ <arg>title</arg>
+ <arg>copies</arg>
+ <arg>options</arg>
+ <arg>filename</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>smbspool is a very small print spooling program that
+ sends a print file to an SMB printer. The command-line arguments
+ are position-dependent for compatibility with the Common UNIX
+ Printing System, but you can use smbspool with any printing system
+ or from a program or script.</para>
+
+ <para><emphasis>DEVICE URI</emphasis></para>
+
+ <para>smbspool specifies the destination using a Uniform Resource
+ Identifier ("URI") with a method of "smb". This string can take
+ a number of forms:</para>
+
+ <itemizedlist>
+ <listitem><para>smb://server/printer</para></listitem>
+ <listitem><para>smb://workgroup/server/printer</para></listitem>
+ <listitem><para>smb://username:password@server/printer</para>
+ </listitem>
+ <listitem><para>smb://username:password@workgroup/server/printer
+ </para></listitem>
+ </itemizedlist>
+
+ <para>smbspool tries to get the URI from argv[0]. If argv[0]
+ contains the name of the program then it looks in the <envar>
+ DEVICE_URI</envar> environment variable.</para>
+
+ <para>Programs using the <command>exec(2)</command> functions can
+ pass the URI in argv[0], while shell scripts must set the
+ <envar>DEVICE_URI</envar> environment variable prior to
+ running smbspool.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <itemizedlist>
+ <listitem><para>The job argument (argv[1]) contains the
+ job ID number and is presently not used by smbspool.
+ </para></listitem>
+
+ <listitem><para>The user argument (argv[2]) contains the
+ print user's name and is presently not used by smbspool.
+ </para></listitem>
+
+ <listitem><para>The title argument (argv[3]) contains the
+ job title string and is passed as the remote file name
+ when sending the print job.</para></listitem>
+
+ <listitem><para>The copies argument (argv[4]) contains
+ the number of copies to be printed of the named file. If
+ no filename is provided than this argument is not used by
+ smbspool.</para></listitem>
+
+ <listitem><para>The options argument (argv[5]) contains
+ the print options in a single string and is presently
+ not used by smbspool.</para></listitem>
+
+ <listitem><para>The filename argument (argv[6]) contains the
+ name of the file to print. If this argument is not specified
+ then the print file is read from the standard input.</para>
+ </listitem>
+ </itemizedlist>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ and <ulink url="samba.7.html">samba(7)</ulink>.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para><command>smbspool</command> was written by Michael Sweet
+ at Easy Software Products.</para>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbstatus.1.sgml b/docs/docbook/manpages/smbstatus.1.sgml
new file mode 100755
index 00000000000..c2f638b88ef
--- /dev/null
+++ b/docs/docbook/manpages/smbstatus.1.sgml
@@ -0,0 +1,137 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbstatus">
+
+<refmeta>
+ <refentrytitle>smbstatus</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbstatus</refname>
+ <refpurpose>report on current Samba connections</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbstatus</command>
+ <arg choice="opt">-P</arg>
+ <arg choice="opt">-b</arg>
+ <arg choice="opt">-d</arg>
+ <arg choice="opt">-L</arg>
+ <arg choice="opt">-p</arg>
+ <arg choice="opt">-S</arg>
+ <arg choice="opt">-s &lt;configuration file&gt;</arg>
+ <arg choice="opt">-u &lt;username&gt;</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>smbstatus</command> is a very simple program to
+ list the current Samba connections.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P</term>
+ <listitem><para>If samba has been compiled with the
+ profiling option, print only the contents of the profiling
+ shared memory area.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-b</term>
+ <listitem><para>gives brief output.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-d</term>
+ <listitem><para>gives verbose output.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-L</term>
+ <listitem><para>causes smbstatus to only list locks.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-p</term>
+ <listitem><para>print a list of <ulink url="smbd.8.html">
+ <command>smbd(8)</command></ulink> processes and exit.
+ Useful for scripting.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-S</term>
+ <listitem><para>causes smbstatus to only list shares.</para>
+ </listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-s &lt;configuration file&gt;</term>
+ <listitem><para>The default configuration file name is
+ determined at compile time. The file specified contains the
+ configuration details required by the server. See <ulink
+ url="smb.conf.5.html"><filename>smb.conf(5)</filename>
+ </ulink> for more information.</para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-u &lt;username&gt;</term>
+ <listitem><para>selects information relevant to
+ <parameter>username</parameter> only.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink> and
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>.</para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbtar.1.sgml b/docs/docbook/manpages/smbtar.1.sgml
new file mode 100755
index 00000000000..4e2ee5fff0a
--- /dev/null
+++ b/docs/docbook/manpages/smbtar.1.sgml
@@ -0,0 +1,226 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbtar">
+
+<refmeta>
+ <refentrytitle>smbtar</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbtar</refname>
+ <refpurpose>shell script for backing up SMB/CIFS shares
+ directly to UNIX tape drives</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbtar</command>
+ <arg choice="req">-s server</arg>
+ <arg choice="opt">-p password</arg>
+ <arg choice="opt">-x services</arg>
+ <arg choice="opt">-X</arg>
+ <arg choice="opt">-d directory</arg>
+ <arg choice="opt">-u user</arg>
+ <arg choice="opt">-t tape</arg>
+ <arg choice="opt">-t tape</arg>
+ <arg choice="opt">-b blocksize</arg>
+ <arg choice="opt">-N filename</arg>
+ <arg choice="opt">-i</arg>
+ <arg choice="opt">-r</arg>
+ <arg choice="opt">-l loglevel</arg>
+ <arg choice="opt">-v</arg>
+ <arg choice="req">filenames</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>smbtar</command> is a very small shell script on top
+ of <ulink url="smbclient.1.html"><command>smbclient(1)</command></ulink>
+ which dumps SMB shares directly to tape. </para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-s server</term>
+ <listitem><para>The SMB/CIFS server that the share resides
+ upon.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-x service</term>
+ <listitem><para>The share name on the server to connect to.
+ The default is "backup".</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-X</term>
+ <listitem><para>Exclude mode. Exclude filenames... from tar
+ create or restore. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-d directory</term>
+ <listitem><para>Change to initial <parameter>directory
+ </parameter> before restoring / backing up files. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-v</term>
+ <listitem><para>Verbose mode.</para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-p password</term>
+ <listitem><para>The password to use to access a share.
+ Default: none </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-u user</term>
+ <listitem><para>The user id to connect as. Default:
+ UNIX login name. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-t tape</term>
+ <listitem><para>Tape device. May be regular file or tape
+ device. Default: <parameter>$TAPE</parameter> environmental
+ variable; if not set, a file called <filename>tar.out
+ </filename>. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-b blocksize</term>
+ <listitem><para>Blocking factor. Defaults to 20. See
+ <command>tar(1)</command> for a fuller explanation. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-N filename</term>
+ <listitem><para>Backup only files newer than filename. Could
+ be used (for example) on a log file to implement incremental
+ backups. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-i</term>
+ <listitem><para>Incremental mode; tar files are only backed
+ up if they have the archive bit set. The archive bit is reset
+ after each file is read. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-r</term>
+ <listitem><para>Restore. Files are restored to the share
+ from the tar file. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-l log level</term>
+ <listitem><para>Log (debug) level. Corresponds to the
+ <parameter>-d</parameter> flag of <command>smbclient(1)
+ </command>. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>ENVIRONMENT VARIABLES</title>
+
+ <para>The <parameter>$TAPE</parameter> variable specifies the
+ default tape device to write to. May be overridden
+ with the -t option. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>BUGS</title>
+
+ <para>The <command>smbtar</command> script has different
+ options from ordinary tar and tar called from smbclient. </para>
+
+</refsect1>
+
+<refsect1>
+ <title>CAVEATS</title>
+
+ <para>Sites that are more careful about security may not like
+ the way the script handles PC passwords. Backup and restore work
+ on entire shares, should work on file lists. smbtar works best
+ with GNU tar and may not work well with other versions. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>DIAGNOSTICS</title>
+
+ <para>See the <emphasis>DIAGNOSTICS</emphasis> section for the
+ <ulink url="smbclient.1.html"><command>smbclient(1)</command>
+ </ulink> command.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smbclient.1.html"><command>smbclient(1)</command></ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>,
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para><ulink url="mailto:poultenr@logica.co.uk">Ricky Poulten</ulink>
+ wrote the tar extension and this man page. The <command>smbtar</command>
+ script was heavily rewritten and improved by <ulink
+ url="mailto:Martin.Kraemer@mch.sni.de">Martin Kraemer</ulink>. Many
+ thanks to everyone who suggested extensions, improvements, bug
+ fixes, etc. The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter.</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/smbumount.8.sgml b/docs/docbook/manpages/smbumount.8.sgml
new file mode 100755
index 00000000000..d6a1b65b578
--- /dev/null
+++ b/docs/docbook/manpages/smbumount.8.sgml
@@ -0,0 +1,73 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="smbumount">
+
+<refmeta>
+ <refentrytitle>smbumount</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>smbumount</refname>
+ <refpurpose>smbfs umount for normal users</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>smbumount</command>
+ <arg choice="req">mount-point</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>With this program, normal users can unmount smb-filesystems,
+ provided that it is suid root. <command>smbumount</command> has
+ been written to give normal Linux users more control over their
+ resources. It is safe to install this program suid root, because only
+ the user who has mounted a filesystem is allowed to unmount it again.
+ For root it is not necessary to use smbumount. The normal umount
+ program works perfectly well, but it would certainly be problematic
+ to make umount setuid root.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>mount-point</term>
+ <listitem><para>The directory to unmount.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>SEE ALSO</title>
+
+ <para><ulink url="smbmount.8.html"><command>smbmount(8)</command>
+ </ulink></para>
+</refsect1>
+
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</para>
+
+ <para>The current maintainer of smbfs and the userspace
+ tools <command>smbmount</command>, <command>smbumount</command>,
+ and <command>smbmnt</command> is <ulink
+ url="mailto:urban@teststation.com">Urban Widmark</ulink>.
+ The <ulink url="mailto:samba@samba.org">SAMBA Mailing list</ulink>
+ is the preferred place to ask questions regarding these programs.
+ </para>
+
+ <para>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/swat.8.sgml b/docs/docbook/manpages/swat.8.sgml
new file mode 100755
index 00000000000..b67f53777dd
--- /dev/null
+++ b/docs/docbook/manpages/swat.8.sgml
@@ -0,0 +1,265 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="swat">
+
+<refmeta>
+ <refentrytitle>swat</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>swat</refname>
+ <refpurpose>Samba Web Administration Tool</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>swat</command>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ <arg choice="opt">-a</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+
+ <para><command>swat</command> allows a Samba administrator to
+ configure the complex <ulink url="smb.conf.5.html"><filename>
+ smb.conf(5)</filename></ulink> file via a Web browser. In addition,
+ a <command>swat</command> configuration page has help links
+ to all the configurable options in the <filename>smb.conf</filename> file allowing an
+ administrator to easily look up the effects of any change. </para>
+
+ <para><command>swat</command> is run from <command>inetd</command> </para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-s smb configuration file</term>
+ <listitem><para>The default configuration file path is
+ determined at compile time. The file specified contains
+ the configuration details required by the <command>smbd
+ </command> server. This is the file that <command>swat</command> will modify.
+ The information in this file includes server-specific
+ information such as what printcap file to use, as well as
+ descriptions of all the services that the server is to provide.
+ See <filename>smb.conf</filename> for more information.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-a</term>
+ <listitem><para>This option disables authentication and puts
+ <command>swat</command> in demo mode. In that mode anyone will be able to modify
+ the <filename>smb.conf</filename> file. </para>
+
+ <para><emphasis>Do NOT enable this option on a production
+ server. </emphasis></para></listitem>
+ </varlistentry>
+ </variablelist>
+
+</refsect1>
+
+<refsect1>
+
+ <title>INSTALLATION</title>
+
+ <para>After you compile SWAT you need to run <command>make install
+ </command> to install the <command>swat</command> binary
+ and the various help files and images. A default install would put
+ these in: </para>
+
+ <itemizedlist>
+ <listitem><para>/usr/local/samba/bin/swat</para></listitem>
+ <listitem><para>/usr/local/samba/swat/images/*</para></listitem>
+ <listitem><para>/usr/local/samba/swat/help/*</para></listitem>
+ </itemizedlist>
+
+ <refsect2>
+ <title>Inetd Installation</title>
+
+ <para>You need to edit your <filename>/etc/inetd.conf
+ </filename> and <filename>/etc/services</filename>
+ to enable SWAT to be launched via <command>inetd</command>.</para>
+
+ <para>In <filename>/etc/services</filename> you need to
+ add a line like this: </para>
+
+ <para><command>swat 901/tcp</command></para>
+
+ <para>Note for NIS/YP users - you may need to rebuild the
+ NIS service maps rather than alter your local <filename>
+ /etc/services</filename> file. </para>
+
+ <para>the choice of port number isn't really important
+ except that it should be less than 1024 and not currently
+ used (using a number above 1024 presents an obscure security
+ hole depending on the implementation details of your
+ <command>inetd</command> daemon). </para>
+
+ <para>In <filename>/etc/inetd.conf</filename> you should
+ add a line like this: </para>
+
+ <para><command>swat stream tcp nowait.400 root
+ /usr/local/samba/bin/swat swat</command></para>
+
+ <para>One you have edited <filename>/etc/services</filename>
+ and <filename>/etc/inetd.conf</filename> you need to send a
+ HUP signal to inetd. To do this use <command>kill -1 PID
+ </command> where PID is the process ID of the inetd daemon. </para>
+
+ </refsect2>
+
+
+ <refsect2>
+ <title>Xinetd Installation</title>
+
+ <para>Newer Linux systems ship with a more secure implementation
+ of the inetd meta-daemon. The <command>xinetd</command> daemon
+ can read configuration inf9ormation from a single file (i.e.
+ <filename>/etc/xinetd.conf</filename>) or from a collection
+ of service control files in the <filename>xinetd.d/</filename> directory.
+ These directions assume the latter configuration.
+ </para>
+
+ <para>
+ The following file should be created as <filename>/etc/xientd.d/swat</filename>.
+ It is then be neccessary cause the meta-daemon to reload its configuration files.
+ Refer to the xinetd man page for details on how to accomplish this.
+ </para>
+
+<para><programlisting>
+## /etc/xinetd.d/swat
+service swat
+{
+ port = 901
+ socket_type = stream
+ wait = no
+ only_from = localhost
+ user = root
+ server = /usr/local/samba/bin/swat
+ log_on_failure += USERID
+ disable = No
+}
+</programlisting></para>
+
+ </refsect2>
+
+
+ <refsect2>
+ <title>Launching</title>
+
+ <para>To launch SWAT just run your favorite web browser and
+ point it at "http://localhost:901/".</para>
+
+ <para>Note that you can attach to SWAT from any IP connected
+ machine but connecting from a remote machine leaves your
+ connection open to password sniffing as passwords will be sent
+ in the clear over the wire. </para>
+ </refsect2>
+
+</refsect1>
+
+<refsect1>
+ <title>TROUBLESHOOTING</title>
+
+ <para>
+ One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/inetd.conf</filename></term>
+ <listitem><para>This file must contain suitable startup
+ information for the meta-daemon.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/xinetd.d/swat</filename></term>
+ <listitem><para>This file must contain suitable startup
+ information for the <command>xinetd</command> meta-daemon.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/services</filename></term>
+ <listitem><para>This file must contain a mapping of service name
+ (e.g., swat) to service port (e.g., 901) and protocol type
+ (e.g., tcp). </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/usr/local/samba/lib/smb.conf</filename></term>
+ <listitem><para>This is the default location of the <filename>smb.conf(5)
+ </filename> server configuration file that swat edits. Other
+ common places that systems install this file are <filename>
+ /usr/samba/lib/smb.conf</filename> and <filename>/etc/smb.conf
+ </filename>. This file describes all the services the server
+ is to make available to clients. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>WARNINGS</title>
+
+ <para><command>swat</command> will rewrite your <filename>smb.conf
+ </filename> file. It will rearrange the entries and delete all
+ comments, <parameter>include=</parameter> and <parameter>copy="
+ </parameter> options. If you have a carefully crafted <filename>
+ smb.conf</filename> then back it up or don't use swat! </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><command>inetd(5)</command>,
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink>, <command>xinetd(8)</command>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/testparm.1.sgml b/docs/docbook/manpages/testparm.1.sgml
new file mode 100755
index 00000000000..9128d8f4c51
--- /dev/null
+++ b/docs/docbook/manpages/testparm.1.sgml
@@ -0,0 +1,173 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="testparm">
+
+<refmeta>
+ <refentrytitle>testparm</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>testparm</refname>
+ <refpurpose>check an smb.conf configuration file for
+ internal correctness</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>testparm</command>
+ <arg choice="opt">-s</arg>
+ <arg choice="opt">-h</arg>
+ <arg choice="opt">-x</arg>
+ <arg choice="opt">-L &lt;servername&gt;</arg>
+ <arg choice="req">config filename</arg>
+ <arg choice="opt">hostname hostIP</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>testparm</command> is a very simple test program
+ to check an <command>smbd</command> configuration file for
+ internal correctness. If this program reports no problems, you
+ can use the configuration file with confidence that <command>smbd
+ </command> will successfully load the configuration file.</para>
+
+
+ <para>Note that this is <emphasis>NOT</emphasis> a guarantee that
+ the services specified in the configuration file will be
+ available or will operate as expected. </para>
+
+ <para>If the optional host name and host IP address are
+ specified on the command line, this test program will run through
+ the service entries reporting whether the specified host
+ has access to each service. </para>
+
+ <para>If <command>testparm</command> finds an error in the <filename>
+ smb.conf</filename> file it returns an exit code of 1 to the calling
+ program, else it returns an exit code of 0. This allows shell scripts
+ to test the output from <command>testparm</command>.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-s</term>
+ <listitem><para>Without this option, <command>testparm</command>
+ will prompt for a carriage return after printing the service
+ names and before dumping the service definitions.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem><para>Print usage message </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-x</term>
+ <listitem><para>Print only parameters that have non-default values</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-L servername</term>
+ <listitem><para>Sets the value of the %L macro to <replaceable>servername</replaceable>.
+ This is useful for testing include files specified with the
+ %L macro. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>configfilename</term>
+ <listitem><para>This is the name of the configuration file
+ to check. If this parameter is not present then the
+ default <filename>smb.conf</filename> file will be checked.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>hostname</term>
+ <listitem><para>If this parameter and the following are
+ specified, then <command>testparm</command> will examine the <parameter>hosts
+ allow</parameter> and <parameter>hosts deny</parameter>
+ parameters in the <filename>smb.conf</filename> file to
+ determine if the hostname with this IP address would be
+ allowed access to the <command>smbd</command> server. If
+ this parameter is supplied, the hostIP parameter must also
+ be supplied.</para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>hostIP</term>
+ <listitem><para>This is the IP address of the host specified
+ in the previous parameter. This address must be supplied
+ if the hostname parameter is supplied. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>smb.conf</filename></term>
+ <listitem><para>This is usually the name of the configuration
+ file used by <command>smbd</command>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>DIAGNOSTICS</title>
+
+ <para>The program will issue a message saying whether the
+ configuration file loaded OK or not. This message may be preceded by
+ errors and warnings if the file did not load. If the file was
+ loaded OK, the program then dumps all known service details
+ to stdout. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="smb.conf.5.html"><filename>smb.conf(5)</filename></ulink>,
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
+
diff --git a/docs/docbook/manpages/testprns.1.sgml b/docs/docbook/manpages/testprns.1.sgml
new file mode 100755
index 00000000000..cd99494a9af
--- /dev/null
+++ b/docs/docbook/manpages/testprns.1.sgml
@@ -0,0 +1,143 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="testprns">
+
+<refmeta>
+ <refentrytitle>testprns</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>testprns</refname>
+ <refpurpose>check printer name for validity with smbd</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>testprns</command>
+ <arg choice="req">printername</arg>
+ <arg choice="opt">printcapname</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>testprns</command> is a very simple test program
+ to determine whether a given printer name is valid for use in
+ a service to be provided by <ulink url="smbd.8.html"><command>
+ smbd(8)</command></ulink>. </para>
+
+ <para>"Valid" in this context means "can be found in the
+ printcap specified". This program is very stupid - so stupid in
+ fact that it would be wisest to always specify the printcap file
+ to use. </para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>printername</term>
+ <listitem><para>The printer name to validate.</para>
+
+ <para>Printer names are taken from the first field in each
+ record in the printcap file, single printer names and sets
+ of aliases separated by vertical bars ("|") are recognized.
+ Note that no validation or checking of the printcap syntax is
+ done beyond that required to extract the printer name. It may
+ be that the print spooling system is more forgiving or less
+ forgiving than <command>testprns</command>. However, if
+ <command>testprns</command> finds the printer then
+ <command>smbd</command> should do so as well. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>printcapname</term>
+ <listitem><para>This is the name of the printcap file within
+ which to search for the given printer name. </para>
+
+ <para>If no printcap name is specified <command>testprns
+ </command> will attempt to scan the printcap file name
+ specified at compile time. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/printcap</filename></term>
+ <listitem><para>This is usually the default printcap
+ file to scan. See <filename>printcap (5)</filename>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>DIAGNOSTICS</title>
+
+ <para>If a printer is found to be valid, the message
+ "Printer name &lt;printername&gt; is valid" will be
+ displayed. </para>
+
+ <para>If a printer is found to be invalid, the message
+ "Printer name &lt;printername&gt; is not valid" will be
+ displayed. </para>
+
+ <para>All messages that would normally be logged during
+ operation of the Samba daemons are logged by this program to the
+ file <filename>test.log</filename> in the current directory. The
+ program runs at debuglevel 3, so quite extensive logging
+ information is written. The log should be checked carefully
+ for errors and warnings. </para>
+
+ <para>Other messages are self-explanatory. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><filename>printcap(5)</filename>,
+ <ulink url="smbd.8.html"><command>smbd(8)</command></ulink>,
+ <ulink url="smbclient.1.html"><command>smbclient(1)</command></ulink>
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <ulink url="ftp://ftp.icce.rug.nl/pub/unix/">
+ ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</para>
+</refsect1>
+
+</refentry>
+
diff --git a/docs/docbook/manpages/wbinfo.1.sgml b/docs/docbook/manpages/wbinfo.1.sgml
new file mode 100755
index 00000000000..f1461b07b9c
--- /dev/null
+++ b/docs/docbook/manpages/wbinfo.1.sgml
@@ -0,0 +1,238 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="wbinfo">
+
+<refmeta>
+ <refentrytitle>wbinfo</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>wbinfo</refname>
+ <refpurpose>Query information from winbind daemon</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>wbinfo</command>
+ <arg choice="opt">-u</arg>
+ <arg choice="opt">-g</arg>
+ <arg choice="opt">-h name</arg>
+ <arg choice="opt">-i ip</arg>
+ <arg choice="opt">-n name</arg>
+ <arg choice="opt">-s sid</arg>
+ <arg choice="opt">-U uid</arg>
+ <arg choice="opt">-G gid</arg>
+ <arg choice="opt">-S sid</arg>
+ <arg choice="opt">-Y sid</arg>
+ <arg choice="opt">-t</arg>
+ <arg choice="opt">-m</arg>
+ <arg choice="opt">-r user</arg>
+ <arg choice="opt">-a user%password</arg>
+ <arg choice="opt">-A user%password</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This tool is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para>The <command>wbinfo</command> program queries and returns information
+ created and used by the <ulink url="winbindd.8.html"><command>
+ winbindd(8)</command></ulink> daemon. </para>
+
+ <para>The <command>winbindd(8)</command> daemon must be configured
+ and running for the <command>wbinfo</command> program to be able
+ to return information.</para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-u</term>
+ <listitem><para>This option will list all users available
+ in the Windows NT domain for which the <command>winbindd(8)
+ </command> daemon is operating in. Users in all trusted domains
+ will also be listed. Note that this operation does not assign
+ user ids to any users that have not already been seen by
+ <command>winbindd(8)</command>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-g</term>
+ <listitem><para>This option will list all groups available
+ in the Windows NT domain for which the <command>winbindd(8)
+ </command> daemon is operating in. Groups in all trusted domains
+ will also be listed. Note that this operation does not assign
+ group ids to any groups that have not already been seen by
+ <command>winbindd(8)</command>. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-h name</term>
+ <listitem><para>The <parameter>-h</parameter> option
+ queries <command>winbindd(8)</command> to query the WINS
+ server for the IP address associated with the NetBIOS name
+ specified by the <parameter>name</parameter> parameter.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-i ip</term>
+ <listitem><para>The <parameter>-i</parameter> option
+ queries <command>winbindd(8)</command> to send a node status
+ request to get the NetBIOS name associated with the IP address
+ specified by the <parameter>ip</parameter> parameter.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-n name</term>
+ <listitem><para>The <parameter>-n</parameter> option
+ queries <command>winbindd(8)</command> for the SID
+ associated with the name specified. Domain names can be specified
+ before the user name by using the winbind separator character.
+ For example CWDOM1/Administrator refers to the Administrator
+ user in the domain CWDOM1. If no domain is specified then the
+ domain used is the one specified in the <filename>smb.conf</filename>
+ <parameter>workgroup</parameter> parameter. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-s sid</term>
+ <listitem><para>Use <parameter>-s</parameter> to resolve
+ a SID to a name. This is the inverse of the <parameter>-n
+ </parameter> option above. SIDs must be specified as ASCII strings
+ in the traditional Microsoft format. For example,
+ S-1-5-21-1455342024-3071081365-2475485837-500. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-U uid</term>
+ <listitem><para>Try to convert a UNIX user id to a Windows NT
+ SID. If the uid specified does not refer to one within
+ the winbind uid range then the operation will fail. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-G gid</term>
+ <listitem><para>Try to convert a UNIX group id to a Windows
+ NT SID. If the gid specified does not refer to one within
+ the winbind gid range then the operation will fail. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-S sid</term>
+ <listitem><para>Convert a SID to a UNIX user id. If the SID
+ does not correspond to a UNIX user mapped by <command>
+ winbindd(8)</command> then the operation will fail. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-Y sid</term>
+ <listitem><para>Convert a SID to a UNIX group id. If the SID
+ does not correspond to a UNIX group mapped by <command>
+ winbindd(8)</command> then the operation will fail. </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>-t</term>
+ <listitem><para>Verify that the workstation trust account
+ created when the Samba server is added to the Windows NT
+ domain is working. </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-m</term>
+ <listitem><para>Produce a list of domains trusted by the
+ Windows NT server <command>winbindd(8)</command> contacts
+ when resolving names. This list does not include the Windows
+ NT domain the server is a Primary Domain Controller for.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-r username</term>
+ <listitem><para>Try to obtain the list of UNIX group ids
+ to which the user belongs. This only works for users
+ defined on a Domain Controller.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-a username%password</term>
+ <listitem><para>Attempt to authenticate a user via winbindd.
+ This checks both authenticaion methods and reports its results.
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>-A username%password</term>
+ <listitem><para>Store username and password used by winbindd
+ during session setup to a domain controller. This enables
+ winbindd to operate in a Windows 2000 domain with Restrict
+ Anonymous turned on (a.k.a. Permissions compatiable with
+ Windows 2000 servers only).
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>EXIT STATUS</title>
+
+ <para>The wbinfo program returns 0 if the operation
+ succeeded, or 1 if the operation failed. If the <command>winbindd(8)
+ </command> daemon is not working <command>wbinfo</command> will always return
+ failure. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><ulink url="winbindd.8.html"><command>winbindd(8)</command>
+ </ulink></para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para><command>wbinfo</command> and <command>winbindd</command>
+ were written by Tim Potter.</para>
+
+ <para>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/manpages/winbindd.8.sgml b/docs/docbook/manpages/winbindd.8.sgml
new file mode 100755
index 00000000000..e257b6c3fb8
--- /dev/null
+++ b/docs/docbook/manpages/winbindd.8.sgml
@@ -0,0 +1,515 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<refentry id="winbindd">
+
+<refmeta>
+ <refentrytitle>winbindd</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>winbindd</refname>
+ <refpurpose>Name Service Switch daemon for resolving names
+ from NT servers</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>winbindd</command>
+ <arg choice="opt">-i</arg>
+ <arg choice="opt">-d &lt;debug level&gt;</arg>
+ <arg choice="opt">-s &lt;smb config file&gt;</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This program is part of the <ulink url="samba.7.html">
+ Samba</ulink> suite.</para>
+
+ <para><command>winbindd</command> is a daemon that provides
+ a service for the Name Service Switch capability that is present
+ in most modern C libraries. The Name Service Switch allows user
+ and system information to be obtained from different databases
+ services such as NIS or DNS. The exact behaviour can be configured
+ throught the <filename>/etc/nsswitch.conf</filename> file.
+ Users and groups are allocated as they are resolved to a range
+ of user and group ids specified by the administrator of the
+ Samba system.</para>
+
+ <para>The service provided by <command>winbindd</command> is called `winbind' and
+ can be used to resolve user and group information from a
+ Windows NT server. The service can also provide authentication
+ services via an associated PAM module. </para>
+
+ <para>
+ The <filename>pam_winbind</filename> module in the 2.2.2 release only
+ supports the <parameter>auth</parameter> and <parameter>account</parameter>
+ module-types. The latter is simply
+ performs a getpwnam() to verify that the system can obtain a uid for the
+ user. If the <filename>libnss_winbind</filename> library has been correctly
+ installed, this should always suceed.
+ </para>
+
+ <para>The following nsswitch databases are implemented by
+ the winbindd service: </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>hosts</term>
+ <listitem><para>User information traditionally stored in
+ the <filename>hosts(5)</filename> file and used by
+ <command>gethostbyname(3)</command> functions. Names are
+ resolved through the WINS server or by broadcast.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>passwd</term>
+ <listitem><para>User information traditionally stored in
+ the <filename>passwd(5)</filename> file and used by
+ <command>getpwent(3)</command> functions. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>group</term>
+ <listitem><para>Group information traditionally stored in
+ the <filename>group(5)</filename> file and used by
+ <command>getgrent(3)</command> functions. </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>For example, the following simple configuration in the
+ <filename>/etc/nsswitch.conf</filename> file can be used to initially
+ resolve user and group information from <filename>/etc/passwd
+ </filename> and <filename>/etc/group</filename> and then from the
+ Windows NT server. </para>
+
+ <para><programlisting>
+passwd: files winbind
+group: files winbind
+ </programlisting></para>
+
+ <para>The following simple configuration in the
+ <filename>/etc/nsswitch.conf</filename> file can be used to initially
+ resolve hostnames from <filename>/etc/hosts</filename> and then from the
+ WINS server.</para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-d debuglevel</term>
+ <listitem><para>Sets the debuglevel to an integer between
+ 0 and 100. 0 is for no debugging and 100 is for reams and
+ reams. To submit a bug report to the Samba Team, use debug
+ level 100 (see BUGS.txt). </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i</term>
+ <listitem><para>Tells <command>winbindd</command> to not
+ become a daemon and detach from the current terminal. This
+ option is used by developers when interactive debugging
+ of <command>winbindd</command> is required. </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>NAME AND ID RESOLUTION</title>
+
+ <para>Users and groups on a Windows NT server are assigned
+ a relative id (rid) which is unique for the domain when the
+ user or group is created. To convert the Windows NT user or group
+ into a unix user or group, a mapping between rids and unix user
+ and group ids is required. This is one of the jobs that <command>
+ winbindd</command> performs. </para>
+
+ <para>As winbindd users and groups are resolved from a server, user
+ and group ids are allocated from a specified range. This
+ is done on a first come, first served basis, although all existing
+ users and groups will be mapped as soon as a client performs a user
+ or group enumeration command. The allocated unix ids are stored
+ in a database file under the Samba lock directory and will be
+ remembered. </para>
+
+ <para>WARNING: The rid to unix id database is the only location
+ where the user and group mappings are stored by winbindd. If this
+ file is deleted or corrupted, there is no way for winbindd to
+ determine which user and group ids correspond to Windows NT user
+ and group rids. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>CONFIGURATION</title>
+
+ <para>Configuration of the <command>winbindd</command> daemon
+ is done through configuration parameters in the <filename>smb.conf(5)
+ </filename> file. All parameters should be specified in the
+ [global] section of smb.conf. </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>winbind separator</term>
+ <listitem><para>The winbind separator option allows you
+ to specify how NT domain names and user names are combined
+ into unix user names when presented to users. By default,
+ <command>winbindd</command> will use the traditional '\'
+ separator so that the unix user names look like
+ DOMAIN\username. In some cases this separator character may
+ cause problems as the '\' character has special meaning in
+ unix shells. In that case you can use the winbind separator
+ option to specify an alternative separator character. Good
+ alternatives may be '/' (although that conflicts
+ with the unix directory separator) or a '+ 'character.
+ The '+' character appears to be the best choice for 100%
+ compatibility with existing unix utilities, but may be an
+ aesthetically bad choice depending on your taste. </para>
+
+ <para>Default: <command>winbind separator = \ </command>
+ </para>
+ <para>Example: <command>winbind separator = + </command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>winbind uid</term>
+ <listitem><para>The winbind uid parameter specifies the
+ range of user ids that are allocated by the winbindd daemon.
+ This range of ids should have no existing local or NIS users
+ within it as strange conflicts can occur otherwise. </para>
+
+ <para>Default: <command>winbind uid = &lt;empty string&gt;
+ </command></para>
+ <para>Example: <command>winbind uid = 10000-20000</command></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>winbind gid</term>
+ <listitem><para>The winbind gid parameter specifies the
+ range of group ids that are allocated by the winbindd daemon.
+ This range of group ids should have no existing local or NIS
+ groups within it as strange conflicts can occur otherwise.</para>
+
+ <para>Default: <command>winbind gid = &lt;empty string&gt;
+ </command></para>
+ <para>Example: <command>winbind gid = 10000-20000
+ </command> </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>winbind cache time</term>
+ <listitem><para>This parameter specifies the number of
+ seconds the winbindd daemon will cache user and group information
+ before querying a Windows NT server again. When a item in the
+ cache is older than this time winbindd will ask the domain
+ controller for the sequence number of the server's account database.
+ If the sequence number has not changed then the cached item is
+ marked as valid for a further <parameter>winbind cache time
+ </parameter> seconds. Otherwise the item is fetched from the
+ server. This means that as long as the account database is not
+ actively changing winbindd will only have to send one sequence
+ number query packet every <parameter>winbind cache time
+ </parameter> seconds. </para>
+
+ <para>Default: <command>winbind cache time = 15</command>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>winbind enum users</term>
+ <listitem><para>On large installations it may be necessary
+ to suppress the enumeration of users through the <command>
+ setpwent()</command>, <command>getpwent()</command> and
+ <command>endpwent()</command> group of system calls. If
+ the <parameter>winbind enum users</parameter> parameter is false,
+ calls to the <command>getpwent</command> system call will not
+ return any data. </para>
+
+ <para><emphasis>Warning:</emphasis> Turning off user enumeration
+ may cause some programs to behave oddly. For example, the <command>finger</command>
+ program relies on having access to the full user list when
+ searching for matching usernames. </para>
+
+ <para>Default: <command>winbind enum users = yes </command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>winbind enum groups</term>
+ <listitem><para>On large installations it may be necessary
+ to suppress the enumeration of groups through the <command>
+ setgrent()</command>, <command>getgrent()</command> and
+ <command>endgrent()</command> group of system calls. If
+ the <parameter>winbind enum groups</parameter> parameter is
+ false, calls to the <command>getgrent()</command> system
+ call will not return any data. </para>
+
+ <para><emphasis>Warning:</emphasis> Turning off group
+ enumeration may cause some programs to behave oddly.
+ </para>
+
+ <para>Default: <command>winbind enum groups = no </command>
+ </para></listitem>
+ </varlistentry>
+
+
+
+ <varlistentry>
+ <term>template homedir</term>
+ <listitem><para>When filling out the user information
+ for a Windows NT user, the <command>winbindd</command> daemon
+ uses this parameter to fill in the home directory for that user.
+ If the string <parameter>%D</parameter> is present it is
+ substituted with the user's Windows NT domain name. If the
+ string <parameter>%U</parameter> is present it is substituted
+ with the user's Windows NT user name. </para>
+
+ <para>Default: <command>template homedir = /home/%D/%U </command>
+ </para></listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>template shell</term>
+ <listitem><para>When filling out the user information for
+ a Windows NT user, the <command>winbindd</command> daemon
+ uses this parameter to fill in the shell for that user.
+ </para>
+
+ <para>Default: <command>template shell = /bin/false </command>
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>EXAMPLE SETUP</title>
+
+ <para>To setup winbindd for user and group lookups plus
+ authentication from a domain controller use something like the
+ following setup. This was tested on a RedHat 6.2 Linux box. </para>
+
+ <para>In <filename>/etc/nsswitch.conf</filename> put the
+ following:</para>
+
+ <para><programlisting>
+passwd: files winbind
+group: files winbind
+ </programlisting></para>
+
+ <para>In <filename>/etc/pam.d/*</filename> replace the
+ <parameter>auth</parameter> lines with something like this: </para>
+
+
+ <para><programlisting>
+auth required /lib/security/pam_securetty.so
+auth required /lib/security/pam_nologin.so
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_pwdb.so use_first_pass shadow nullok
+ </programlisting></para>
+
+
+ <para>Note in particular the use of the <parameter>sufficient</parameter>
+ keyword and the <parameter>use_first_pass</parameter> keyword. </para>
+
+ <para>Now replace the account lines with this: </para>
+
+ <para><command>account required /lib/security/pam_winbind.so
+ </command></para>
+
+ <para>The next step is to join the domain. To do that use the
+ <command>smbpasswd</command> program like this: </para>
+
+ <para><command>smbpasswd -j DOMAIN -r PDC -U
+ Administrator</command></para>
+
+ <para>The username after the <parameter>-U</parameter> can be any
+ Domain user that has administrator privileges on the machine.
+ Substitute your domain name for "DOMAIN" and the name of your PDC
+ for "PDC".</para>
+
+ <para>Next copy <filename>libnss_winbind.so</filename> to
+ <filename>/lib</filename> and <filename>pam_winbind.so</filename>
+ to <filename>/lib/security</filename>. A symbolic link needs to be
+ made from <filename>/lib/libnss_winbind.so</filename> to
+ <filename>/lib/libnss_winbind.so.2</filename>. If you are using an
+ older version of glibc then the target of the link should be
+ <filename>/lib/libnss_winbind.so.1</filename>.</para>
+
+ <para>Finally, setup a <filename>smb.conf</filename> containing directives like the
+ following: </para>
+
+ <para><programlisting>
+[global]
+ winbind separator = +
+ winbind cache time = 10
+ template shell = /bin/bash
+ template homedir = /home/%D/%U
+ winbind uid = 10000-20000
+ winbind gid = 10000-20000
+ workgroup = DOMAIN
+ security = domain
+ password server = *
+ </programlisting></para>
+
+
+ <para>Now start winbindd and you should find that your user and
+ group database is expanded to include your NT users and groups,
+ and that you can login to your unix box as a domain user, using
+ the DOMAIN+user syntax for the username. You may wish to use the
+ commands <command>getent passwd</command> and <command>getent group
+ </command> to confirm the correct operation of winbindd.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>NOTES</title>
+
+ <para>The following notes are useful when configuring and
+ running <command>winbindd</command>: </para>
+
+ <para><command>nmbd</command> must be running on the local machine
+ for <command>winbindd</command> to work. <command>winbindd</command>
+ queries the list of trusted domains for the Windows NT server
+ on startup and when a SIGHUP is received. Thus, for a running <command>
+ winbindd</command> to become aware of new trust relationships between
+ servers, it must be sent a SIGHUP signal. </para>
+
+ <para>Client processes resolving names through the <command>winbindd</command>
+ nsswitch module read an environment variable named <envar>
+ $WINBINDD_DOMAIN</envar>. If this variable contains a comma separated
+ list of Windows NT domain names, then winbindd will only resolve users
+ and groups within those Windows NT domains. </para>
+
+ <para>PAM is really easy to misconfigure. Make sure you know what
+ you are doing when modifying PAM configuration files. It is possible
+ to set up PAM such that you can no longer log into your system. </para>
+
+ <para>If more than one UNIX machine is running <command>winbindd</command>,
+ then in general the user and groups ids allocated by winbindd will not
+ be the same. The user and group ids will only be valid for the local
+ machine.</para>
+
+ <para>If the the Windows NT RID to UNIX user and group id mapping
+ file is damaged or destroyed then the mappings will be lost. </para>
+</refsect1>
+
+
+<refsect1>
+ <title>SIGNALS</title>
+
+ <para>The following signals can be used to manipulate the
+ <command>winbindd</command> daemon. </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>SIGHUP</term>
+ <listitem><para>Reload the <filename>smb.conf(5)</filename>
+ file and apply any parameter changes to the running
+ version of winbindd. This signal also clears any cached
+ user and group information. The list of other domains trusted
+ by winbindd is also reloaded. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SIGUSR1</term>
+ <listitem><para>The SIGUSR1 signal will cause <command>
+ winbindd</command> to write status information to the winbind
+ log file including information about the number of user and
+ group ids allocated by <command>winbindd</command>.</para>
+
+ <para>Log files are stored in the filename specified by the
+ log file parameter.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/nsswitch.conf(5)</filename></term>
+ <listitem><para>Name service switch configuration file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>/tmp/.winbindd/pipe</term>
+ <listitem><para>The UNIX pipe over which clients communicate with
+ the <command>winbindd</command> program. For security reasons, the
+ winbind client will only attempt to connect to the winbindd daemon
+ if both the <filename>/tmp/.winbindd</filename> directory
+ and <filename>/tmp/.winbindd/pipe</filename> file are owned by
+ root. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>/lib/libnss_winbind.so.X</term>
+ <listitem><para>Implementation of name service switch library.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$LOCKDIR/winbindd_idmap.tdb</term>
+ <listitem><para>Storage for the Windows NT rid to UNIX user/group
+ id mapping. The lock directory is specified when Samba is initially
+ compiled using the <parameter>--with-lockdir</parameter> option.
+ This directory is by default <filename>/usr/local/samba/var/locks
+ </filename>. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$LOCKDIR/winbindd_cache.tdb</term>
+ <listitem><para>Storage for cached user and group information.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 2.2 of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+
+ <para><filename>nsswitch.conf(5)</filename>,
+ <ulink url="samba.7.html">samba(7)</ulink>,
+ <ulink url="wbinfo.1.html">wbinfo(1)</ulink>,
+ <ulink url="smb.conf.5.html">smb.conf(5)</ulink></para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+ <para><command>wbinfo</command> and <command>winbindd</command>
+ were written by Tim Potter.</para>
+
+ <para>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</para>
+</refsect1>
+
+</refentry>
diff --git a/docs/docbook/projdoc/CVS-Access.sgml b/docs/docbook/projdoc/CVS-Access.sgml
new file mode 100755
index 00000000000..98ef925f20f
--- /dev/null
+++ b/docs/docbook/projdoc/CVS-Access.sgml
@@ -0,0 +1,157 @@
+<chapter id="cvs-access">
+
+
+<chapterinfo>
+ <author>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (22 May 2001) </pubdate>
+</chapterinfo>
+
+<title>HOWTO Access Samba source code via CVS</title>
+
+<sect1>
+<title>Introduction</title>
+
+<para>
+Samba is developed in an open environment. Developers use CVS
+(Concurrent Versioning System) to "checkin" (also known as
+"commit") new source code. Samba's various CVS branches can
+be accessed via anonymous CVS using the instructions
+detailed in this chapter.
+</para>
+
+<para>
+This document is a modified version of the instructions found at
+<ulink url="http://samba.org/samba/cvs.html">http://samba.org/samba/cvs.html</ulink>
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>CVS Access to samba.org</title>
+
+<para>
+The machine samba.org runs a publicly accessible CVS
+repository for access to the source code of several packages,
+including samba, rsync and jitterbug. There are two main ways of
+accessing the CVS server on this host.
+</para>
+
+<sect2>
+<title>Access via CVSweb</title>
+
+<para>
+You can access the source code via your
+favourite WWW browser. This allows you to access the contents of
+individual files in the repository and also to look at the revision
+history and commit logs of individual files. You can also ask for a diff
+listing between any two versions on the repository.
+</para>
+
+<para>
+Use the URL : <ulink
+url="http://samba.org/cgi-bin/cvsweb">http://samba.org/cgi-bin/cvsweb</ulink>
+</para>
+</sect2>
+
+<sect2>
+<title>Access via cvs</title>
+
+<para>
+You can also access the source code via a
+normal cvs client. This gives you much more control over you can
+do with the repository and allows you to checkout whole source trees
+and keep them up to date via normal cvs commands. This is the
+preferred method of access if you are a developer and not
+just a casual browser.
+</para>
+
+<para>
+To download the latest cvs source code, point your
+browser at the URL : <ulink url="http://www.cyclic.com/">http://www.cyclic.com/</ulink>.
+and click on the 'How to get cvs' link. CVS is free software under
+the GNU GPL (as is Samba). Note that there are several graphical CVS clients
+which provide a graphical interface to the sometimes mundane CVS commands.
+Links to theses clients are also available from http://www.cyclic.com.
+</para>
+
+<para>
+To gain access via anonymous cvs use the following steps.
+For this example it is assumed that you want a copy of the
+samba source code. For the other source code repositories
+on this system just substitute the correct package name
+</para>
+
+<orderedlist>
+<listitem>
+ <para>
+ Install a recent copy of cvs. All you really need is a
+ copy of the cvs client binary.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ Run the command
+ </para>
+
+ <para>
+ <command>cvs -d :pserver:cvs@samba.org:/cvsroot login</command>
+ </para>
+
+ <para>
+ When it asks you for a password type <userinput>cvs</userinput>.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ Run the command
+ </para>
+
+ <para>
+ <command>cvs -d :pserver:cvs@samba.org:/cvsroot co samba</command>
+ </para>
+
+ <para>
+ This will create a directory called samba containing the
+ latest samba source code (i.e. the HEAD tagged cvs branch). This
+ currently corresponds to the 3.0 development tree.
+ </para>
+
+ <para>
+ CVS branches other HEAD can be obtained by using the <parameter>-r</parameter>
+ and defining a tag name. A list of branch tag names can be found on the
+ "Development" page of the samba web site. A common request is to obtain the
+ latest 2.2 release code. This could be done by using the following command.
+ </para>
+
+ <para>
+ <command>cvs -d :pserver:cvs@samba.org:/cvsroot co -r SAMBA_2_2 samba</command>
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ Whenever you want to merge in the latest code changes use
+ the following command from within the samba directory:
+ </para>
+
+ <para>
+ <command>cvs update -d -P</command>
+ </para>
+</listitem>
+</orderedlist>
+
+</sect2>
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/DOMAIN_MEMBER.sgml b/docs/docbook/projdoc/DOMAIN_MEMBER.sgml
new file mode 100755
index 00000000000..6d0b36eafcc
--- /dev/null
+++ b/docs/docbook/projdoc/DOMAIN_MEMBER.sgml
@@ -0,0 +1,224 @@
+<chapter id="domain-security">
+
+<chapterinfo>
+ <author>
+ <firstname>Jeremy</firstname><surname>Allison</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>samba@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Jerry</firstname><surname>Carter</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>jerry@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>16 Apr 2001</pubdate>
+</chapterinfo>
+
+
+<title>security = domain in Samba 2.x</title>
+
+<sect1>
+
+ <title>Joining an NT Domain with Samba 2.2</title>
+
+ <para>Assume you have a Samba 2.x server with a NetBIOS name of
+ <constant>SERV1</constant> and are joining an NT domain called
+ <constant>DOM</constant>, which has a PDC with a NetBIOS name
+ of <constant>DOMPDC</constant> and two backup domain controllers
+ with NetBIOS names <constant>DOMBDC1</constant> and <constant>DOMBDC2
+ </constant>.</para>
+
+ <para>In order to join the domain, first stop all Samba daemons
+ and run the command:</para>
+
+ <para><prompt>root# </prompt><userinput>smbpasswd -j DOM -r DOMPDC
+ -U<replaceable>Administrator%password</replaceable></userinput></para>
+
+ <para>as we are joining the domain DOM and the PDC for that domain
+ (the only machine that has write access to the domain SAM database)
+ is DOMPDC. The <replaceable>Administrator%password</replaceable> is
+ the login name and password for an account which has the necessary
+ privilege to add machines to the domain. If this is successful
+ you will see the message:</para>
+
+ <para><computeroutput>smbpasswd: Joined domain DOM.</computeroutput>
+ </para>
+
+ <para>in your terminal window. See the <ulink url="smbpasswd.8.html">
+ smbpasswd(8)</ulink> man page for more details.</para>
+
+ <para>There is existing development code to join a domain
+ without having to create the machine trust account on the PDC
+ beforehand. This code will hopefully be available soon
+ in release branches as well.</para>
+
+ <para>This command goes through the machine account password
+ change protocol, then writes the new (random) machine account
+ password for this Samba server into a file in the same directory
+ in which an smbpasswd file would be stored - normally :</para>
+
+ <para><filename>/usr/local/samba/private</filename></para>
+
+ <para>In Samba 2.0.x, the filename looks like this:</para>
+
+ <para><filename><replaceable>&lt;NT DOMAIN NAME&gt;</replaceable>.<replaceable>&lt;Samba
+ Server Name&gt;</replaceable>.mac</filename></para>
+
+ <para>The <filename>.mac</filename> suffix stands for machine account
+ password file. So in our example above, the file would be called:</para>
+
+ <para><filename>DOM.SERV1.mac</filename></para>
+
+ <para>In Samba 2.2, this file has been replaced with a TDB
+ (Trivial Database) file named <filename>secrets.tdb</filename>.
+ </para>
+
+
+ <para>This file is created and owned by root and is not
+ readable by any other user. It is the key to the domain-level
+ security for your system, and should be treated as carefully
+ as a shadow password file.</para>
+
+ <para>Now, before restarting the Samba daemons you must
+ edit your <ulink url="smb.conf.5.html"><filename>smb.conf(5)</filename>
+ </ulink> file to tell Samba it should now use domain security.</para>
+
+ <para>Change (or add) your <ulink url="smb.conf.5.html#SECURITY">
+ <parameter>security =</parameter></ulink> line in the [global] section
+ of your smb.conf to read:</para>
+
+ <para><command>security = domain</command></para>
+
+ <para>Next change the <ulink url="smb.conf.5.html#WORKGROUP"><parameter>
+ workgroup =</parameter></ulink> line in the [global] section to read: </para>
+
+ <para><command>workgroup = DOM</command></para>
+
+ <para>as this is the name of the domain we are joining. </para>
+
+ <para>You must also have the parameter <ulink url="smb.conf.5.html#ENCRYPTPASSWORDS">
+ <parameter>encrypt passwords</parameter></ulink> set to <constant>yes
+ </constant> in order for your users to authenticate to the NT PDC.</para>
+
+ <para>Finally, add (or modify) a <ulink url="smb.conf.5.html#PASSWORDSERVER">
+ <parameter>password server =</parameter></ulink> line in the [global]
+ section to read: </para>
+
+ <para><command>password server = DOMPDC DOMBDC1 DOMBDC2</command></para>
+
+ <para>These are the primary and backup domain controllers Samba
+ will attempt to contact in order to authenticate users. Samba will
+ try to contact each of these servers in order, so you may want to
+ rearrange this list in order to spread out the authentication load
+ among domain controllers.</para>
+
+ <para>Alternatively, if you want smbd to automatically determine
+ the list of Domain controllers to use for authentication, you may
+ set this line to be :</para>
+
+ <para><command>password server = *</command></para>
+
+ <para>This method, which was introduced in Samba 2.0.6,
+ allows Samba to use exactly the same mechanism that NT does. This
+ method either broadcasts or uses a WINS database in order to
+ find domain controllers to authenticate against.</para>
+
+ <para>Finally, restart your Samba daemons and get ready for
+ clients to begin using domain security!</para>
+</sect1>
+
+<sect1>
+<title>Samba and Windows 2000 Domains</title>
+
+<para>
+Many people have asked regarding the state of Samba's ability to participate in
+a Windows 2000 Domain. Samba 2.2 is able to act as a member server of a Windows
+2000 domain operating in mixed or native mode.
+</para>
+
+<para>
+There is much confusion between the circumstances that require a "mixed" mode
+Win2k DC and a when this host can be switched to "native" mode. A "mixed" mode
+Win2k domain controller is only needed if Windows NT BDCs must exist in the same
+domain. By default, a Win2k DC in "native" mode will still support
+NetBIOS and NTLMv1 for authentication of legacy clients such as Windows 9x and
+NT 4.0. Samba has the same requirements as a Windows NT 4.0 member server.
+</para>
+
+<para>
+The steps for adding a Samba 2.2 host to a Win2k domain are the same as those
+for adding a Samba server to a Windows NT 4.0 domain. The only exception is that
+the "Server Manager" from NT 4 has been replaced by the "Active Directory Users and
+Computers" MMC (Microsoft Management Console) plugin.
+</para>
+
+</sect1>
+
+
+<sect1>
+ <title>Why is this better than security = server?</title>
+
+ <para>Currently, domain security in Samba doesn't free you from
+ having to create local Unix users to represent the users attaching
+ to your server. This means that if domain user <constant>DOM\fred
+ </constant> attaches to your domain security Samba server, there needs
+ to be a local Unix user fred to represent that user in the Unix
+ filesystem. This is very similar to the older Samba security mode
+ <ulink url="smb.conf.5.html#SECURITYEQUALSSERVER">security = server</ulink>,
+ where Samba would pass through the authentication request to a Windows
+ NT server in the same way as a Windows 95 or Windows 98 server would.
+ </para>
+
+ <para>Please refer to the <ulink url="winbind.html">Winbind
+ paper</ulink> for information on a system to automatically
+ assign UNIX uids and gids to Windows NT Domain users and groups.
+ This code is available in development branches only at the moment,
+ but will be moved to release branches soon.</para>
+
+ <para>The advantage to domain-level security is that the
+ authentication in domain-level security is passed down the authenticated
+ RPC channel in exactly the same way that an NT server would do it. This
+ means Samba servers now participate in domain trust relationships in
+ exactly the same way NT servers do (i.e., you can add Samba servers into
+ a resource domain and have the authentication passed on from a resource
+ domain PDC to an account domain PDC.</para>
+
+ <para>In addition, with <command>security = server</command> every Samba
+ daemon on a server has to keep a connection open to the
+ authenticating server for as long as that daemon lasts. This can drain
+ the connection resources on a Microsoft NT server and cause it to run
+ out of available connections. With <command>security = domain</command>,
+ however, the Samba daemons connect to the PDC/BDC only for as long
+ as is necessary to authenticate the user, and then drop the connection,
+ thus conserving PDC connection resources.</para>
+
+ <para>And finally, acting in the same manner as an NT server
+ authenticating to a PDC means that as part of the authentication
+ reply, the Samba server gets the user identification information such
+ as the user SID, the list of NT groups the user belongs to, etc. All
+ this information will allow Samba to be extended in the future into
+ a mode the developers currently call appliance mode. In this mode,
+ no local Unix users will be necessary, and Samba will generate Unix
+ uids and gids from the information passed back from the PDC when a
+ user is authenticated, making a Samba server truly plug and play
+ in an NT domain environment. Watch for this code soon.</para>
+
+ <para><emphasis>NOTE:</emphasis> Much of the text of this document
+ was first published in the Web magazine <ulink url="http://www.linuxworld.com">
+ LinuxWorld</ulink> as the article <ulink
+ url="http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html">Doing
+ the NIS/NT Samba</ulink>.</para>
+
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/ENCRYPTION.sgml b/docs/docbook/projdoc/ENCRYPTION.sgml
new file mode 100755
index 00000000000..6a26dbeffac
--- /dev/null
+++ b/docs/docbook/projdoc/ENCRYPTION.sgml
@@ -0,0 +1,378 @@
+<chapter id="pwencrypt">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Jeremy</firstname><surname>Allison</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>samba@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>19 Apr 1999</pubdate>
+</chapterinfo>
+
+<title>LanMan and NT Password Encryption in Samba 2.x</title>
+
+
+<sect1>
+ <title>Introduction</title>
+
+ <para>With the development of LanManager and Windows NT
+ compatible password encryption for Samba, it is now able
+ to validate user connections in exactly the same way as
+ a LanManager or Windows NT server.</para>
+
+ <para>This document describes how the SMB password encryption
+ algorithm works and what issues there are in choosing whether
+ you want to use it. You should read it carefully, especially
+ the part about security and the "PROS and CONS" section.</para>
+
+</sect1>
+
+<sect1>
+ <title>How does it work?</title>
+
+ <para>LanManager encryption is somewhat similar to UNIX
+ password encryption. The server uses a file containing a
+ hashed value of a user's password. This is created by taking
+ the user's plaintext password, capitalising it, and either
+ truncating to 14 bytes or padding to 14 bytes with null bytes.
+ This 14 byte value is used as two 56 bit DES keys to encrypt
+ a 'magic' eight byte value, forming a 16 byte value which is
+ stored by the server and client. Let this value be known as
+ the "hashed password".</para>
+
+ <para>Windows NT encryption is a higher quality mechanism,
+ consisting of doing an MD4 hash on a Unicode version of the user's
+ password. This also produces a 16 byte hash value that is
+ non-reversible.</para>
+
+ <para>When a client (LanManager, Windows for WorkGroups, Windows
+ 95 or Windows NT) wishes to mount a Samba drive (or use a Samba
+ resource), it first requests a connection and negotiates the
+ protocol that the client and server will use. In the reply to this
+ request the Samba server generates and appends an 8 byte, random
+ value - this is stored in the Samba server after the reply is sent
+ and is known as the "challenge". The challenge is different for
+ every client connection.</para>
+
+ <para>The client then uses the hashed password (16 byte values
+ described above), appended with 5 null bytes, as three 56 bit
+ DES keys, each of which is used to encrypt the challenge 8 byte
+ value, forming a 24 byte value known as the "response".</para>
+
+ <para>In the SMB call SMBsessionsetupX (when user level security
+ is selected) or the call SMBtconX (when share level security is
+ selected), the 24 byte response is returned by the client to the
+ Samba server. For Windows NT protocol levels the above calculation
+ is done on both hashes of the user's password and both responses are
+ returned in the SMB call, giving two 24 byte values.</para>
+
+ <para>The Samba server then reproduces the above calculation, using
+ its own stored value of the 16 byte hashed password (read from the
+ <filename>smbpasswd</filename> file - described later) and the challenge
+ value that it kept from the negotiate protocol reply. It then checks
+ to see if the 24 byte value it calculates matches the 24 byte value
+ returned to it from the client.</para>
+
+ <para>If these values match exactly, then the client knew the
+ correct password (or the 16 byte hashed value - see security note
+ below) and is thus allowed access. If not, then the client did not
+ know the correct password and is denied access.</para>
+
+ <para>Note that the Samba server never knows or stores the cleartext
+ of the user's password - just the 16 byte hashed values derived from
+ it. Also note that the cleartext password or 16 byte hashed values
+ are never transmitted over the network - thus increasing security.</para>
+</sect1>
+
+<sect1>
+ <title>Important Notes About Security</title>
+
+ <para>The unix and SMB password encryption techniques seem similar
+ on the surface. This similarity is, however, only skin deep. The unix
+ scheme typically sends clear text passwords over the network when
+ logging in. This is bad. The SMB encryption scheme never sends the
+ cleartext password over the network but it does store the 16 byte
+ hashed values on disk. This is also bad. Why? Because the 16 byte hashed
+ values are a "password equivalent". You cannot derive the user's
+ password from them, but they could potentially be used in a modified
+ client to gain access to a server. This would require considerable
+ technical knowledge on behalf of the attacker but is perfectly possible.
+ You should thus treat the smbpasswd file as though it contained the
+ cleartext passwords of all your users. Its contents must be kept
+ secret, and the file should be protected accordingly.</para>
+
+ <para>Ideally we would like a password scheme which neither requires
+ plain text passwords on the net or on disk. Unfortunately this
+ is not available as Samba is stuck with being compatible with
+ other SMB systems (WinNT, WfWg, Win95 etc). </para>
+
+ <warning>
+ <para>Note that Windows NT 4.0 Service pack 3 changed the
+ default for permissible authentication so that plaintext
+ passwords are <emphasis>never</emphasis> sent over the wire.
+ The solution to this is either to switch to encrypted passwords
+ with Samba or edit the Windows NT registry to re-enable plaintext
+ passwords. See the document WinNT.txt for details on how to do
+ this.</para>
+
+ <para>Other Microsoft operating systems which also exhibit
+ this behavior includes</para>
+
+ <itemizedlist>
+ <listitem><para>MS DOS Network client 3.0 with
+ the basic network redirector installed</para></listitem>
+
+ <listitem><para>Windows 95 with the network redirector
+ update installed</para></listitem>
+
+ <listitem><para>Windows 98 [se]</para></listitem>
+
+ <listitem><para>Windows 2000</para></listitem>
+ </itemizedlist>
+
+ <para><emphasis>Note :</emphasis>All current release of
+ Microsoft SMB/CIFS clients support authentication via the
+ SMB Challenge/Response mechanism described here. Enabling
+ clear text authentication does not disable the ability
+ of the client to participate in encrypted authentication.</para>
+ </warning>
+
+ <sect2>
+ <title>Advantages of SMB Encryption</title>
+
+ <itemizedlist>
+ <listitem><para>plain text passwords are not passed across
+ the network. Someone using a network sniffer cannot just
+ record passwords going to the SMB server.</para>
+ </listitem>
+
+ <listitem><para>WinNT doesn't like talking to a server
+ that isn't using SMB encrypted passwords. It will refuse
+ to browse the server if the server is also in user level
+ security mode. It will insist on prompting the user for the
+ password on each connection, which is very annoying. The
+ only things you can do to stop this is to use SMB encryption.
+ </para></listitem>
+ </itemizedlist>
+ </sect2>
+
+
+ <sect2>
+ <title>Advantages of non-encrypted passwords</title>
+
+ <itemizedlist>
+ <listitem><para>plain text passwords are not kept
+ on disk. </para></listitem>
+
+ <listitem><para>uses same password file as other unix
+ services such as login and ftp</para></listitem>
+
+ <listitem><para>you are probably already using other
+ services (such as telnet and ftp) which send plain text
+ passwords over the net, so sending them for SMB isn't
+ such a big deal.</para></listitem>
+ </itemizedlist>
+ </sect2>
+</sect1>
+
+
+<sect1>
+ <title><anchor id="SMBPASSWDFILEFORMAT">The smbpasswd file</title>
+
+ <para>In order for Samba to participate in the above protocol
+ it must be able to look up the 16 byte hashed values given a user name.
+ Unfortunately, as the UNIX password value is also a one way hash
+ function (ie. it is impossible to retrieve the cleartext of the user's
+ password given the UNIX hash of it), a separate password file
+ containing this 16 byte value must be kept. To minimise problems with
+ these two password files, getting out of sync, the UNIX <filename>
+ /etc/passwd</filename> and the <filename>smbpasswd</filename> file,
+ a utility, <command>mksmbpasswd.sh</command>, is provided to generate
+ a smbpasswd file from a UNIX <filename>/etc/passwd</filename> file.
+ </para
+
+
+ <para>To generate the smbpasswd file from your <filename>/etc/passwd
+ </filename> file use the following command :</para>
+
+ <para><prompt>$ </prompt><userinput>cat /etc/passwd | mksmbpasswd.sh
+ &gt; /usr/local/samba/private/smbpasswd</userinput></para>
+
+ <para>If you are running on a system that uses NIS, use</para>
+
+ <para><prompt>$ </prompt><userinput>ypcat passwd | mksmbpasswd.sh
+ &gt; /usr/local/samba/private/smbpasswd</userinput></para>
+
+ <para>The <command>mksmbpasswd.sh</command> program is found in
+ the Samba source directory. By default, the smbpasswd file is
+ stored in :</para>
+
+ <para><filename>/usr/local/samba/private/smbpasswd</filename></para>
+
+ <para>The owner of the <filename>/usr/local/samba/private/</filename>
+ directory should be set to root, and the permissions on it should
+ be set to 0500 (<command>chmod 500 /usr/local/samba/private</command>).
+ </para>
+
+ <para>Likewise, the smbpasswd file inside the private directory should
+ be owned by root and the permissions on is should be set to 0600
+ (<command>chmod 600 smbpasswd</command>).</para>
+
+
+ <para>The format of the smbpasswd file is (The line has been
+ wrapped here. It should appear as one entry per line in
+ your smbpasswd file.)</para>
+
+ <para><programlisting>
+username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
+ [Account type]:LCT-&lt;last-change-time&gt;:Long name
+ </programlisting></para>
+
+ <para>Although only the <replaceable>username</replaceable>,
+ <replaceable>uid</replaceable>, <replaceable>
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</replaceable>,
+ [<replaceable>Account type</replaceable>] and <replaceable>
+ last-change-time</replaceable> sections are significant
+ and are looked at in the Samba code.</para>
+
+ <para>It is <emphasis>VITALLY</emphasis> important that there by 32
+ 'X' characters between the two ':' characters in the XXX sections -
+ the smbpasswd and Samba code will fail to validate any entries that
+ do not have 32 characters between ':' characters. The first XXX
+ section is for the Lanman password hash, the second is for the
+ Windows NT version.</para>
+
+ <para>When the password file is created all users have password entries
+ consisting of 32 'X' characters. By default this disallows any access
+ as this user. When a user has a password set, the 'X' characters change
+ to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
+ representation of the 16 byte hashed value of a user's password.</para>
+
+ <para>To set a user to have no password (not recommended), edit the file
+ using vi, and replace the first 11 characters with the ascii text
+ <constant>"NO PASSWORD"</constant> (minus the quotes).</para>
+
+ <para>For example, to clear the password for user bob, his smbpasswd file
+ entry would look like :</para>
+
+ <para><programlisting>
+ bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:Bob's full name:/bobhome:/bobshell
+ </programlisting></para>
+
+ <para>If you are allowing users to use the smbpasswd command to set
+ their own passwords, you may want to give users NO PASSWORD initially
+ so they do not have to enter a previous password when changing to their
+ new password (not recommended). In order for you to allow this the
+ <command>smbpasswd</command> program must be able to connect to the
+ <command>smbd</command> daemon as that user with no password. Enable this
+ by adding the line :</para>
+
+ <para><command>null passwords = yes</command></para>
+
+ <para>to the [global] section of the smb.conf file (this is why
+ the above scenario is not recommended). Preferably, allocate your
+ users a default password to begin with, so you do not have
+ to enable this on your server.</para>
+
+ <para><emphasis>Note : </emphasis>This file should be protected very
+ carefully. Anyone with access to this file can (with enough knowledge of
+ the protocols) gain access to your SMB server. The file is thus more
+ sensitive than a normal unix <filename>/etc/passwd</filename> file.</para>
+</sect1>
+
+
+<sect1>
+ <title>The smbpasswd Command</title>
+
+ <para>The smbpasswd command maintains the two 32 byte password fields
+ in the smbpasswd file. If you wish to make it similar to the unix
+ <command>passwd</command> or <command>yppasswd</command> programs,
+ install it in <filename>/usr/local/samba/bin/</filename> (or your
+ main Samba binary directory).</para>
+
+ <para>Note that as of Samba 1.9.18p4 this program <emphasis>MUST NOT
+ BE INSTALLED</emphasis> setuid root (the new <command>smbpasswd</command>
+ code enforces this restriction so it cannot be run this way by
+ accident).</para>
+
+ <para><command>smbpasswd</command> now works in a client-server mode
+ where it contacts the local smbd to change the user's password on its
+ behalf. This has enormous benefits - as follows.</para>
+
+ <itemizedlist>
+ <listitem><para>smbpasswd no longer has to be setuid root -
+ an enormous range of potential security problems is
+ eliminated.</para></listitem>
+
+ <listitem><para><command>smbpasswd</command> now has the capability
+ to change passwords on Windows NT servers (this only works when
+ the request is sent to the NT Primary Domain Controller if you
+ are changing an NT Domain user's password).</para></listitem>
+ </itemizedlist>
+
+ <para>To run smbpasswd as a normal user just type :</para>
+
+ <para><prompt>$ </prompt><userinput>smbpasswd</userinput></para>
+ <para><prompt>Old SMB password: </prompt><userinput>&lt;type old value here -
+ or hit return if there was no old password&gt;</userinput></para>
+ <para><prompt>New SMB Password: </prompt><userinput>&lt;type new value&gt;
+ </userinput></para>
+ <para><prompt>Repeat New SMB Password: </prompt><userinput>&lt;re-type new value
+ </userinput></para>
+
+ <para>If the old value does not match the current value stored for
+ that user, or the two new values do not match each other, then the
+ password will not be changed.</para>
+
+ <para>If invoked by an ordinary user it will only allow the user
+ to change his or her own Samba password.</para>
+
+ <para>If run by the root user smbpasswd may take an optional
+ argument, specifying the user name whose SMB password you wish to
+ change. Note that when run as root smbpasswd does not prompt for
+ or check the old password value, thus allowing root to set passwords
+ for users who have forgotten their passwords.</para>
+
+ <para><command>smbpasswd</command> is designed to work in the same way
+ and be familiar to UNIX users who use the <command>passwd</command> or
+ <command>yppasswd</command> commands.</para>
+
+ <para>For more details on using <command>smbpasswd</command> refer
+ to the man page which will always be the definitive reference.</para>
+</sect1>
+
+
+<sect1>
+ <title>Setting up Samba to support LanManager Encryption</title>
+
+ <para>This is a very brief description on how to setup samba to
+ support password encryption. </para>
+
+ <orderedlist numeration="Arabic">
+ <listitem><para>compile and install samba as usual</para>
+ </listitem>
+
+ <listitem><para>enable encrypted passwords in <filename>
+ smb.conf</filename> by adding the line <command>encrypt
+ passwords = yes</command> in the [global] section</para>
+ </listitem>
+
+ <listitem><para>create the initial <filename>smbpasswd</filename>
+ password file in the place you specified in the Makefile
+ (--prefix=&lt;dir&gt;). See the notes under the <link
+ linkend="SMBPASSWDFILEFORMAT">The smbpasswd File</link>
+ section earlier in the document for details.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Note that you can test things using smbclient.</para>
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/Integrating-with-Windows.sgml b/docs/docbook/projdoc/Integrating-with-Windows.sgml
new file mode 100755
index 00000000000..ceaece313ad
--- /dev/null
+++ b/docs/docbook/projdoc/Integrating-with-Windows.sgml
@@ -0,0 +1,935 @@
+<chapter id="integrate-ms-networks">
+
+
+<chapterinfo>
+ <author>
+ <firstname>John</firstname><surname>Terpstra</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>jht@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (Jan 01 2001) </pubdate>
+</chapterinfo>
+
+<title>Integrating MS Windows networks with Samba</title>
+
+<sect1>
+<title>Agenda</title>
+
+<para>
+To identify the key functional mechanisms of MS Windows networking
+to enable the deployment of Samba as a means of extending and/or
+replacing MS Windows NT/2000 technology.
+</para>
+
+<para>
+We will examine:
+</para>
+
+<orderedlist>
+ <listitem><para>Name resolution in a pure Unix/Linux TCP/IP
+ environment
+ </para></listitem>
+
+ <listitem><para>Name resolution as used within MS Windows
+ networking
+ </para></listitem>
+
+ <listitem><para>How browsing functions and how to deploy stable
+ and dependable browsing using Samba
+ </para></listitem>
+
+ <listitem><para>MS Windows security options and how to
+ configure Samba for seemless integration
+ </para></listitem>
+
+ <listitem><para>Configuration of Samba as:</para>
+ <orderedlist>
+ <listitem><para>A stand-alone server</para></listitem>
+ <listitem><para>An MS Windows NT 3.x/4.0 security domain member
+ </para></listitem>
+ <listitem><para>An alternative to an MS Windows NT 3.x/4.0 Domain Controller
+ </para></listitem>
+ </orderedlist>
+ </listitem>
+</orderedlist>
+
+</sect1>
+
+
+<sect1>
+<title>Name Resolution in a pure Unix/Linux world</title>
+
+<para>
+The key configuration files covered in this section are:
+</para>
+
+<itemizedlist>
+ <listitem><para><filename>/etc/hosts</filename></para></listitem>
+ <listitem><para><filename>/etc/resolv.conf</filename></para></listitem>
+ <listitem><para><filename>/etc/host.conf</filename></para></listitem>
+ <listitem><para><filename>/etc/nsswitch.conf</filename></para></listitem>
+</itemizedlist>
+
+<sect2>
+<title><filename>/etc/hosts</filename></title>
+
+<para>
+Contains a static list of IP Addresses and names.
+eg:
+</para>
+<para><programlisting>
+ 127.0.0.1 localhost localhost.localdomain
+ 192.168.1.1 bigbox.caldera.com bigbox alias4box
+</programlisting></para>
+
+<para>
+The purpose of <filename>/etc/hosts</filename> is to provide a
+name resolution mechanism so that uses do not need to remember
+IP addresses.
+</para>
+
+
+<para>
+Network packets that are sent over the physical network transport
+layer communicate not via IP addresses but rather using the Media
+Access Control address, or MAC address. IP Addresses are currently
+32 bits in length and are typically presented as four (4) decimal
+numbers that are separated by a dot (or period). eg: 168.192.1.1
+</para>
+
+<para>
+MAC Addresses use 48 bits (or 6 bytes) and are typically represented
+as two digit hexadecimal numbers separated by colons. eg:
+40:8e:0a:12:34:56
+</para>
+
+<para>
+Every network interfrace must have an MAC address. Associated with
+a MAC address there may be one or more IP addresses. There is NO
+relationship between an IP address and a MAC address, all such assignments
+are arbitary or discretionary in nature. At the most basic level all
+network communications takes place using MAC addressing. Since MAC
+addresses must be globally unique, and generally remains fixed for
+any particular interface, the assignment of an IP address makes sense
+from a network management perspective. More than one IP address can
+be assigned per MAC address. One address must be the primary IP address,
+this is the address that will be returned in the ARP reply.
+</para>
+
+<para>
+When a user or a process wants to communicate with another machine
+the protocol implementation ensures that the "machine name" or "host
+name" is resolved to an IP address in a manner that is controlled
+by the TCP/IP configuration control files. The file
+<filename>/etc/hosts</filename> is one such file.
+</para>
+
+<para>
+When the IP address of the destination interface has been
+determined a protocol called ARP/RARP is used to identify
+the MAC address of the target interface. ARP stands for Address
+Resolution Protocol, and is a broadcast oriented method that
+uses UDP (User Datagram Protocol) to send a request to all
+interfaces on the local network segment using the all 1's MAC
+address. Network interfaces are programmed to respond to two
+MAC addresses only; their own unique address and the address
+ff:ff:ff:ff:ff:ff. The reply packet from an ARP request will
+contain the MAC address and the primary IP address for each
+interface.
+</para>
+
+<para>
+The <filename>/etc/hosts</filename> file is foundational to all
+Unix/Linux TCP/IP installations and as a minumum will contain
+the localhost and local network interface IP addresses and the
+primary names by which they are known within the local machine.
+This file helps to prime the pump so that a basic level of name
+resolution can exist before any other method of name resolution
+becomes available.
+</para>
+
+</sect2>
+
+
+<sect2>
+<title><filename>/etc/resolv.conf</filename></title>
+
+<para>
+This file tells the name resolution libraries:
+</para>
+
+<itemizedlist>
+ <listitem><para>The name of the domain to which the machine
+ belongs
+ </para></listitem>
+
+ <listitem><para>The name(s) of any domains that should be
+ automatically searched when trying to resolve unqualified
+ host names to their IP address
+ </para></listitem>
+
+ <listitem><para>The name or IP address of available Domain
+ Name Servers that may be asked to perform name to address
+ translation lookups
+ </para></listitem>
+</itemizedlist>
+
+</sect2>
+
+
+<sect2>
+<title><filename>/etc/host.conf</filename></title>
+
+
+<para>
+<filename>/etc/host.conf</filename> is the primary means by
+which the setting in /etc/resolv.conf may be affected. It is a
+critical configuration file. This file controls the order by
+which name resolution may procede. The typical structure is:
+</para>
+
+<para><programlisting>
+ order hosts,bind
+ multi on
+</programlisting></para>
+
+<para>
+then both addresses should be returned. Please refer to the
+man page for host.conf for further details.
+</para>
+
+
+</sect2>
+
+
+
+<sect2>
+<title><filename>/etc/nsswitch.conf</filename></title>
+
+<para>
+This file controls the actual name resolution targets. The
+file typically has resolver object specifications as follows:
+</para>
+
+
+<para><programlisting>
+ # /etc/nsswitch.conf
+ #
+ # Name Service Switch configuration file.
+ #
+
+ passwd: compat
+ # Alternative entries for password authentication are:
+ # passwd: compat files nis ldap winbind
+ shadow: compat
+ group: compat
+
+ hosts: files nis dns
+ # Alternative entries for host name resolution are:
+ # hosts: files dns nis nis+ hesoid db compat ldap wins
+ networks: nis files dns
+
+ ethers: nis files
+ protocols: nis files
+ rpc: nis files
+ services: nis files
+</programlisting></para>
+
+<para>
+Of course, each of these mechanisms requires that the appropriate
+facilities and/or services are correctly configured.
+</para>
+
+<para>
+It should be noted that unless a network request/message must be
+sent, TCP/IP networks are silent. All TCP/IP communications assumes a
+principal of speaking only when necessary.
+</para>
+
+<para>
+Samba version 2.2.0 will add Linux support for extensions to
+the name service switch infrastructure so that linux clients will
+be able to obtain resolution of MS Windows NetBIOS names to IP
+Addresses. To gain this functionality Samba needs to be compiled
+with appropriate arguments to the make command (ie: <command>make
+nsswitch/libnss_wins.so</command>). The resulting library should
+then be installed in the <filename>/lib</filename> directory and
+the "wins" parameter needs to be added to the "hosts:" line in
+the <filename>/etc/nsswitch.conf</filename> file. At this point it
+will be possible to ping any MS Windows machine by it's NetBIOS
+machine name, so long as that machine is within the workgroup to
+which both the samba machine and the MS Windows machine belong.
+</para>
+
+</sect2>
+</sect1>
+
+
+<sect1>
+<title>Name resolution as used within MS Windows networking</title>
+
+<para>
+MS Windows networking is predicated about the name each machine
+is given. This name is known variously (and inconsistently) as
+the "computer name", "machine name", "networking name", "netbios name",
+"SMB name". All terms mean the same thing with the exception of
+"netbios name" which can apply also to the name of the workgroup or the
+domain name. The terms "workgroup" and "domain" are really just a
+simply name with which the machine is associated. All NetBIOS names
+are exactly 16 characters in length. The 16th character is reserved.
+It is used to store a one byte value that indicates service level
+information for the NetBIOS name that is registered. A NetBIOS machine
+name is therefore registered for each service type that is provided by
+the client/server.
+</para>
+
+<para>
+The following are typical NetBIOS name/service type registrations:
+</para>
+
+<para><programlisting>
+ Unique NetBIOS Names:
+ MACHINENAME<00> = Server Service is running on MACHINENAME
+ MACHINENAME<03> = Generic Machine Name (NetBIOS name)
+ MACHINENAME<20> = LanMan Server service is running on MACHINENAME
+ WORKGROUP<1b> = Domain Master Browser
+
+ Group Names:
+ WORKGROUP<03> = Generic Name registered by all members of WORKGROUP
+ WORKGROUP<1c> = Domain Controllers / Netlogon Servers
+ WORKGROUP<1d> = Local Master Browsers
+ WORKGROUP<1e> = Internet Name Resolvers
+</programlisting></para>
+
+<para>
+It should be noted that all NetBIOS machines register their own
+names as per the above. This is in vast contrast to TCP/IP
+installations where traditionally the system administrator will
+determine in the /etc/hosts or in the DNS database what names
+are associated with each IP address.
+</para>
+
+<para>
+One further point of clarification should be noted, the <filename>/etc/hosts</filename>
+file and the DNS records do not provide the NetBIOS name type information
+that MS Windows clients depend on to locate the type of service that may
+be needed. An example of this is what happens when an MS Windows client
+wants to locate a domain logon server. It find this service and the IP
+address of a server that provides it by performing a lookup (via a
+NetBIOS broadcast) for enumeration of all machines that have
+registered the name type *<1c>. A logon request is then sent to each
+IP address that is returned in the enumerated list of IP addresses. Which
+ever machine first replies then ends up providing the logon services.
+</para>
+
+<para>
+The name "workgroup" or "domain" really can be confusing since these
+have the added significance of indicating what is the security
+architecture of the MS Windows network. The term "workgroup" indicates
+that the primary nature of the network environment is that of a
+peer-to-peer design. In a WORKGROUP all machines are responsible for
+their own security, and generally such security is limited to use of
+just a password (known as SHARE MODE security). In most situations
+with peer-to-peer networking the users who control their own machines
+will simply opt to have no security at all. It is possible to have
+USER MODE security in a WORKGROUP environment, thus requiring use
+of a user name and a matching password.
+</para>
+
+<para>
+MS Windows networking is thus predetermined to use machine names
+for all local and remote machine message passing. The protocol used is
+called Server Message Block (SMB) and this is implemented using
+the NetBIOS protocol (Network Basic Input Output System). NetBIOS can
+be encapsulated using LLC (Logical Link Control) protocol - in which case
+the resulting protocol is called NetBEUI (Network Basic Extended User
+Interface). NetBIOS can also be run over IPX (Internetworking Packet
+Exchange) protocol as used by Novell NetWare, and it can be run
+over TCP/IP protocols - in which case the resulting protocol is called
+NBT or NetBT, the NetBIOS over TCP/IP.
+</para>
+
+<para>
+MS Windows machines use a complex array of name resolution mechanisms.
+Since we are primarily concerned with TCP/IP this demonstration is
+limited to this area.
+</para>
+
+<sect2>
+<title>The NetBIOS Name Cache</title>
+
+<para>
+All MS Windows machines employ an in memory buffer in which is
+stored the NetBIOS names and IP addresses for all external
+machines that that machine has communicated with over the
+past 10-15 minutes. It is more efficient to obtain an IP address
+for a machine from the local cache than it is to go through all the
+configured name resolution mechanisms.
+</para>
+
+<para>
+If a machine whose name is in the local name cache has been shut
+down before the name had been expired and flushed from the cache, then
+an attempt to exchange a message with that machine will be subject
+to time-out delays. i.e.: Its name is in the cache, so a name resolution
+lookup will succeed, but the machine can not respond. This can be
+frustrating for users - but it is a characteristic of the protocol.
+</para>
+
+<para>
+The MS Windows utility that allows examination of the NetBIOS
+name cache is called "nbtstat". The Samba equivalent of this
+is called "nmblookup".
+</para>
+
+</sect2>
+
+<sect2>
+<title>The LMHOSTS file</title>
+
+<para>
+This file is usually located in MS Windows NT 4.0 or
+2000 in <filename>C:\WINNT\SYSTEM32\DRIVERS\ETC</filename> and contains
+the IP Address and the machine name in matched pairs. The
+<filename>LMHOSTS</filename> file performs NetBIOS name
+to IP address mapping oriented.
+</para>
+
+<para>
+It typically looks like:
+</para>
+
+<para><programlisting>
+ # Copyright (c) 1998 Microsoft Corp.
+ #
+ # This is a sample LMHOSTS file used by the Microsoft Wins Client (NetBIOS
+ # over TCP/IP) stack for Windows98
+ #
+ # This file contains the mappings of IP addresses to NT computernames
+ # (NetBIOS) names. Each entry should be kept on an individual line.
+ # The IP address should be placed in the first column followed by the
+ # corresponding computername. The address and the comptername
+ # should be separated by at least one space or tab. The "#" character
+ # is generally used to denote the start of a comment (see the exceptions
+ # below).
+ #
+ # This file is compatible with Microsoft LAN Manager 2.x TCP/IP lmhosts
+ # files and offers the following extensions:
+ #
+ # #PRE
+ # #DOM:&lt;domain&gt;
+ # #INCLUDE &lt;filename&gt;
+ # #BEGIN_ALTERNATE
+ # #END_ALTERNATE
+ # \0xnn (non-printing character support)
+ #
+ # Following any entry in the file with the characters "#PRE" will cause
+ # the entry to be preloaded into the name cache. By default, entries are
+ # not preloaded, but are parsed only after dynamic name resolution fails.
+ #
+ # Following an entry with the "#DOM:&lt;domain&gt;" tag will associate the
+ # entry with the domain specified by &lt;domain&gt;. This affects how the
+ # browser and logon services behave in TCP/IP environments. To preload
+ # the host name associated with #DOM entry, it is necessary to also add a
+ # #PRE to the line. The &lt;domain&gt; is always preloaded although it will not
+ # be shown when the name cache is viewed.
+ #
+ # Specifying "#INCLUDE &lt;filename&gt;" will force the RFC NetBIOS (NBT)
+ # software to seek the specified &lt;filename&gt; and parse it as if it were
+ # local. &lt;filename&gt; is generally a UNC-based name, allowing a
+ # centralized lmhosts file to be maintained on a server.
+ # It is ALWAYS necessary to provide a mapping for the IP address of the
+ # server prior to the #INCLUDE. This mapping must use the #PRE directive.
+ # In addtion the share "public" in the example below must be in the
+ # LanManServer list of "NullSessionShares" in order for client machines to
+ # be able to read the lmhosts file successfully. This key is under
+ # \machine\system\currentcontrolset\services\lanmanserver\parameters\nullsessionshares
+ # in the registry. Simply add "public" to the list found there.
+ #
+ # The #BEGIN_ and #END_ALTERNATE keywords allow multiple #INCLUDE
+ # statements to be grouped together. Any single successful include
+ # will cause the group to succeed.
+ #
+ # Finally, non-printing characters can be embedded in mappings by
+ # first surrounding the NetBIOS name in quotations, then using the
+ # \0xnn notation to specify a hex value for a non-printing character.
+ #
+ # The following example illustrates all of these extensions:
+ #
+ # 102.54.94.97 rhino #PRE #DOM:networking #net group's DC
+ # 102.54.94.102 "appname \0x14" #special app server
+ # 102.54.94.123 popular #PRE #source server
+ # 102.54.94.117 localsrv #PRE #needed for the include
+ #
+ # #BEGIN_ALTERNATE
+ # #INCLUDE \\localsrv\public\lmhosts
+ # #INCLUDE \\rhino\public\lmhosts
+ # #END_ALTERNATE
+ #
+ # In the above example, the "appname" server contains a special
+ # character in its name, the "popular" and "localsrv" server names are
+ # preloaded, and the "rhino" server name is specified so it can be used
+ # to later #INCLUDE a centrally maintained lmhosts file if the "localsrv"
+ # system is unavailable.
+ #
+ # Note that the whole file is parsed including comments on each lookup,
+ # so keeping the number of comments to a minimum will improve performance.
+ # Therefore it is not advisable to simply add lmhosts file entries onto the
+ # end of this file.
+</programlisting></para>
+
+</sect2>
+
+<sect2>
+<title>HOSTS file</title>
+
+<para>
+This file is usually located in MS Windows NT 4.0 or 2000 in
+<filename>C:\WINNT\SYSTEM32\DRIVERS\ETC</filename> and contains
+the IP Address and the IP hostname in matched pairs. It can be
+used by the name resolution infrastructure in MS Windows, depending
+on how the TCP/IP environment is configured. This file is in
+every way the equivalent of the Unix/Linux <filename>/etc/hosts</filename> file.
+</para>
+</sect2>
+
+
+<sect2>
+<title>DNS Lookup</title>
+
+<para>
+This capability is configured in the TCP/IP setup area in the network
+configuration facility. If enabled an elaborate name resolution sequence
+is followed the precise nature of which isdependant on what the NetBIOS
+Node Type parameter is configured to. A Node Type of 0 means use
+NetBIOS broadcast (over UDP broadcast) is first used if the name
+that is the subject of a name lookup is not found in the NetBIOS name
+cache. If that fails then DNS, HOSTS and LMHOSTS are checked. If set to
+Node Type 8, then a NetBIOS Unicast (over UDP Unicast) is sent to the
+WINS Server to obtain a lookup before DNS, HOSTS, LMHOSTS, or broadcast
+lookup is used.
+</para>
+
+</sect2>
+
+<sect2>
+<title>WINS Lookup</title>
+
+<para>
+A WINS (Windows Internet Name Server) service is the equivaent of the
+rfc1001/1002 specified NBNS (NetBIOS Name Server). A WINS server stores
+the names and IP addresses that are registered by a Windows client
+if the TCP/IP setup has been given at least one WINS Server IP Address.
+</para>
+
+<para>
+To configure Samba to be a WINS server the following parameter needs
+to be added to the <filename>smb.conf</filename> file:
+</para>
+
+<para><programlisting>
+ wins support = Yes
+</programlisting></para>
+
+<para>
+To configure Samba to use a WINS server the following parameters are
+needed in the smb.conf file:
+</para>
+
+<para><programlisting>
+ wins support = No
+ wins server = xxx.xxx.xxx.xxx
+</programlisting></para>
+
+<para>
+where <replaceable>xxx.xxx.xxx.xxx</replaceable> is the IP address
+of the WINS server.
+</para>
+
+</sect2>
+</sect1>
+
+
+<sect1>
+<title>How browsing functions and how to deploy stable and
+dependable browsing using Samba</title>
+
+
+<para>
+As stated above, MS Windows machines register their NetBIOS names
+(i.e.: the machine name for each service type in operation) on start
+up. Also, as stated above, the exact method by which this name registration
+takes place is determined by whether or not the MS Windows client/server
+has been given a WINS server address, whether or not LMHOSTS lookup
+is enabled, or if DNS for NetBIOS name resolution is enabled, etc.
+</para>
+
+<para>
+In the case where there is no WINS server all name registrations as
+well as name lookups are done by UDP broadcast. This isolates name
+resolution to the local subnet, unless LMHOSTS is used to list all
+names and IP addresses. In such situations Samba provides a means by
+which the samba server name may be forcibly injected into the browse
+list of a remote MS Windows network (using the "remote announce" parameter).
+</para>
+
+<para>
+Where a WINS server is used, the MS Windows client will use UDP
+unicast to register with the WINS server. Such packets can be routed
+and thus WINS allows name resolution to function across routed networks.
+</para>
+
+<para>
+During the startup process an election will take place to create a
+local master browser if one does not already exist. On each NetBIOS network
+one machine will be elected to function as the domain master browser. This
+domain browsing has nothing to do with MS security domain control.
+Instead, the domain master browser serves the role of contacting each local
+master browser (found by asking WINS or from LMHOSTS) and exchanging browse
+list contents. This way every master browser will eventually obtain a complete
+list of all machines that are on the network. Every 11-15 minutes an election
+is held to determine which machine will be the master browser. By the nature of
+the election criteria used, the machine with the highest uptime, or the
+most senior protocol version, or other criteria, will win the election
+as domain master browser.
+</para>
+
+<para>
+Clients wishing to browse the network make use of this list, but also depend
+on the availability of correct name resolution to the respective IP
+address/addresses.
+</para>
+
+<para>
+Any configuration that breaks name resolution and/or browsing intrinsics
+will annoy users because they will have to put up with protracted
+inability to use the network services.
+</para>
+
+<para>
+Samba supports a feature that allows forced synchonisation
+of browse lists across routed networks using the "remote
+browse sync" parameter in the smb.conf file. This causes Samba
+to contact the local master browser on a remote network and
+to request browse list synchronisation. This effectively bridges
+two networks that are separated by routers. The two remote
+networks may use either broadcast based name resolution or WINS
+based name resolution, but it should be noted that the "remote
+browse sync" parameter provides browse list synchronisation - and
+that is distinct from name to address resolution, in other
+words, for cross subnet browsing to function correctly it is
+essential that a name to address resolution mechanism be provided.
+This mechanism could be via DNS, <filename>/etc/hosts</filename>,
+and so on.
+</para>
+
+</sect1>
+
+<sect1>
+<title>MS Windows security options and how to configure
+Samba for seemless integration</title>
+
+<para>
+MS Windows clients may use encrypted passwords as part of a
+challenge/response authentication model (a.k.a. NTLMv1) or
+alone, or clear text strings for simple password based
+authentication. It should be realized that with the SMB
+protocol the password is passed over the network either
+in plain text or encrypted, but not both in the same
+authentication requets.
+</para>
+
+<para>
+When encrypted passwords are used a password that has been
+entered by the user is encrypted in two ways:
+</para>
+
+<itemizedlist>
+ <listitem><para>An MD4 hash of the UNICODE of the password
+ string. This is known as the NT hash.
+ </para></listitem>
+
+ <listitem><para>The password is converted to upper case,
+ and then padded or trucated to 14 bytes. This string is
+ then appended with 5 bytes of NULL characters and split to
+ form two 56 bit DES keys to encrypt a "magic" 8 byte value.
+ The resulting 16 bytes for the LanMan hash.
+ </para></listitem>
+</itemizedlist>
+
+<para>
+You should refer to the <ulink url="ENCRYPTION.html">
+Password Encryption</ulink> chapter in this HOWTO collection
+for more details on the inner workings
+</para>
+
+<para>
+MS Windows 95 pre-service pack 1, MS Windows NT versions 3.x
+and version 4.0 pre-service pack 3 will use either mode of
+password authentication. All versions of MS Windows that follow
+these versions no longer support plain text passwords by default.
+</para>
+
+<para>
+MS Windows clients have a habit of dropping network mappings that
+have been idle for 10 minutes or longer. When the user attempts to
+use the mapped drive connection that has been dropped, the client
+re-establishes the connection using
+a cached copy of the password.
+</para>
+
+<para>
+When Microsoft changed the default password mode, they dropped support for
+caching of the plain text password. This means that when the registry
+parameter is changed to re-enable use of plain text passwords it appears to
+work, but when a dropped mapping attempts to revalidate it will fail if
+the remote authentication server does not support encrypted passwords.
+This means that it is definitely not a good idea to re-enable plain text
+password support in such clients.
+</para>
+
+<para>
+The following parameters can be used to work around the
+issue of Windows 9x client upper casing usernames and
+password before transmitting them to the SMB server
+when using clear text authentication.
+</para>
+
+<para><programlisting>
+ <ulink url="smb.conf.5.html#PASSWORDLEVEL">passsword level</ulink> = <replaceable>integer</replaceable>
+ <ulink url="smb.conf.5.html#USERNAMELEVEL">username level</ulink> = <replaceable>integer</replaceable>
+</programlisting></para>
+
+<para>
+By default Samba will lower case the username before attempting
+to lookup the user in the database of local system accounts.
+Because UNIX usernames conventionally only contain lower case
+character, the <parameter>username level</parameter> parameter
+is rarely even needed.
+</para>
+
+<para>
+However, password on UNIX systems often make use of mixed case
+characters. This means that in order for a user on a Windows 9x
+client to connect to a Samba server using clear text authentication,
+the <parameter>password level</parameter> must be set to the maximum
+number of upper case letter which <emphasis>could</emphasis> appear
+is a password. Note that is the server OS uses the traditional
+DES version of crypt(), then a <parameter>password level</parameter>
+of 8 will result in case insensitive passwords as seen from Windows
+users. This will also result in longer login times as Samba
+hash to compute the permutations of the password string and
+try them one by one until a match is located (or all combinations fail).
+</para>
+
+<para>
+The best option to adopt is to enable support for encrypted passwords
+where ever Samba is used. There are three configuration possibilities
+for support of encrypted passwords:
+</para>
+
+
+<sect2>
+<title>Use MS Windows NT as an authentication server</title>
+
+<para>
+This method involves the additions of the following parameters
+in the smb.conf file:
+</para>
+
+<para><programlisting>
+ encrypt passwords = Yes
+ security = server
+ password server = "NetBIOS_name_of_PDC"
+</programlisting></para>
+
+
+<para>
+There are two ways of identifying whether or not a username and
+password pair was valid or not. One uses the reply information provided
+as part of the authentication messaging process, the other uses
+just and error code.
+</para>
+
+<para>
+The down-side of this mode of configuration is the fact that
+for security reasons Samba will send the password server a bogus
+username and a bogus password and if the remote server fails to
+reject the username and password pair then an alternative mode
+of identification of validation is used. Where a site uses password
+lock out after a certain number of failed authentication attempts
+this will result in user lockouts.
+</para>
+
+<para>
+Use of this mode of authentication does require there to be
+a standard Unix account for the user, this account can be blocked
+to prevent logons by other than MS Windows clients.
+</para>
+
+</sect2>
+
+<sect2>
+<title>Make Samba a member of an MS Windows NT security domain</title>
+
+<para>
+This method involves additon of the following paramters in the smb.conf file:
+</para>
+
+<para><programlisting>
+ encrypt passwords = Yes
+ security = domain
+ workgroup = "name of NT domain"
+ password server = *
+</programlisting></para>
+
+<para>
+The use of the "*" argument to "password server" will cause samba
+to locate the domain controller in a way analogous to the way
+this is done within MS Windows NT.
+</para>
+
+<para>
+In order for this method to work the Samba server needs to join the
+MS Windows NT security domain. This is done as follows:
+</para>
+
+<itemizedlist>
+ <listitem><para>On the MS Windows NT domain controller using
+ the Server Manager add a machine account for the Samba server.
+ </para></listitem>
+
+ <listitem><para>Next, on the Linux system execute:
+ <command>smbpasswd -r PDC_NAME -j DOMAIN_NAME</command>
+ </para></listitem>
+</itemizedlist>
+
+<para>
+Use of this mode of authentication does require there to be
+a standard Unix account for the user in order to assign
+a uid once the account has been authenticated by the remote
+Windows DC. This account can be blocked to prevent logons by
+other than MS Windows clients by things such as setting an invalid
+shell in the <filename>/etc/passwd</filename> entry.
+</para>
+
+<para>
+An alternative to assigning UIDs to Windows users on a
+Samba member server is presented in the <ulink
+url="winbind.html">Winbind Overview</ulink> chapter in
+this HOWTO collection.
+</para>
+
+
+</sect2>
+
+
+<sect2>
+<title>Configure Samba as an authentication server</title>
+
+<para>
+This mode of authentication demands that there be on the
+Unix/Linux system both a Unix style account as well as an
+smbpasswd entry for the user. The Unix system account can be
+locked if required as only the encrypted password will be
+used for SMB client authentication.
+</para>
+
+<para>
+This method involves addition of the following parameters to
+the smb.conf file:
+</para>
+
+<para><programlisting>
+## please refer to the Samba PDC HOWTO chapter later in
+## this collection for more details
+[global]
+ encrypt passwords = Yes
+ security = user
+ domain logons = Yes
+ ; an OS level of 33 or more is recommended
+ os level = 33
+
+[NETLOGON]
+ path = /somewhare/in/file/system
+ read only = yes
+</programlisting></para>
+
+<para>
+in order for this method to work a Unix system account needs
+to be created for each user, as well as for each MS Windows NT/2000
+machine. The following structure is required.
+</para>
+
+<sect3>
+<title>Users</title>
+
+<para>
+A user account that may provide a home directory should be
+created. The following Linux system commands are typical of
+the procedure for creating an account.
+</para>
+
+<para><programlisting>
+ # useradd -s /bin/bash -d /home/"userid" -m "userid"
+ # passwd "userid"
+ Enter Password: &lt;pw&gt;
+
+ # smbpasswd -a "userid"
+ Enter Password: &lt;pw&gt;
+</programlisting></para>
+</sect3>
+
+<sect3>
+<title>MS Windows NT Machine Accounts</title>
+
+<para>
+These are required only when Samba is used as a domain
+controller. Refer to the Samba-PDC-HOWTO for more details.
+</para>
+
+<para><programlisting>
+ # useradd -s /bin/false -d /dev/null "machine_name"\$
+ # passwd -l "machine_name"\$
+ # smbpasswd -a -m "machine_name"
+</programlisting></para>
+</sect3>
+</sect2>
+</sect1>
+
+
+<sect1>
+<title>Conclusions</title>
+
+<para>
+Samba provides a flexible means to operate as...
+</para>
+
+<itemizedlist>
+ <listitem><para>A Stand-alone server - No special action is needed
+ other than to create user accounts. Stand-alone servers do NOT
+ provide network logon services, meaning that machines that use this
+ server do NOT perform a domain logon but instead make use only of
+ the MS Windows logon which is local to the MS Windows
+ workstation/server.
+ </para></listitem>
+
+ <listitem><para>An MS Windows NT 3.x/4.0 security domain member.
+ </para></listitem>
+
+
+ <listitem><para>An alternative to an MS Windows NT 3.x/4.0
+ Domain Controller.
+ </para></listitem>
+
+</itemizedlist>
+
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/NT_Security.sgml b/docs/docbook/projdoc/NT_Security.sgml
new file mode 100755
index 00000000000..2259dae029e
--- /dev/null
+++ b/docs/docbook/projdoc/NT_Security.sgml
@@ -0,0 +1,358 @@
+<chapter id="unix-permissions">
+
+<chapterinfo>
+ <author>
+ <firstname>Jeremy</firstname><surname>Allison</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>samba@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>12 Apr 1999</pubdate>
+</chapterinfo>
+
+
+<title>UNIX Permission Bits and Windows NT Access Control Lists</title>
+
+<sect1>
+ <title>Viewing and changing UNIX permissions using the NT
+ security dialogs</title>
+
+
+ <para>New in the Samba 2.0.4 release is the ability for Windows
+ NT clients to use their native security settings dialog box to
+ view and modify the underlying UNIX permissions.</para>
+
+ <para>Note that this ability is careful not to compromise
+ the security of the UNIX host Samba is running on, and
+ still obeys all the file permission rules that a Samba
+ administrator can set.</para>
+
+ <para>In Samba 2.0.4 and above the default value of the
+ parameter <ulink url="smb.conf.5.html#NTACLSUPPORT"><parameter>
+ nt acl support</parameter></ulink> has been changed from
+ <constant>false</constant> to <constant>true</constant>, so
+ manipulation of permissions is turned on by default.</para>
+</sect1>
+
+<sect1>
+ <title>How to view file security on a Samba share</title>
+
+ <para>From an NT 4.0 client, single-click with the right
+ mouse button on any file or directory in a Samba mounted
+ drive letter or UNC path. When the menu pops-up, click
+ on the <emphasis>Properties</emphasis> entry at the bottom of
+ the menu. This brings up the normal file properties dialog
+ box, but with Samba 2.0.4 this will have a new tab along the top
+ marked <emphasis>Security</emphasis>. Click on this tab and you
+ will see three buttons, <emphasis>Permissions</emphasis>,
+ <emphasis>Auditing</emphasis>, and <emphasis>Ownership</emphasis>.
+ The <emphasis>Auditing</emphasis> button will cause either
+ an error message <errorname>A requested privilege is not held
+ by the client</errorname> to appear if the user is not the
+ NT Administrator, or a dialog which is intended to allow an
+ Administrator to add auditing requirements to a file if the
+ user is logged on as the NT Administrator. This dialog is
+ non-functional with a Samba share at this time, as the only
+ useful button, the <command>Add</command> button will not currently
+ allow a list of users to be seen.</para>
+
+</sect1>
+
+<sect1>
+ <title>Viewing file ownership</title>
+
+ <para>Clicking on the <command>"Ownership"</command> button
+ brings up a dialog box telling you who owns the given file. The
+ owner name will be of the form :</para>
+
+ <para><command>"SERVER\user (Long name)"</command></para>
+
+ <para>Where <replaceable>SERVER</replaceable> is the NetBIOS name of
+ the Samba server, <replaceable>user</replaceable> is the user name of
+ the UNIX user who owns the file, and <replaceable>(Long name)</replaceable>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database). Click on the <command>Close
+ </command> button to remove this dialog.</para>
+
+ <para>If the parameter <parameter>nt acl support</parameter>
+ is set to <constant>false</constant> then the file owner will
+ be shown as the NT user <command>"Everyone"</command>.</para>
+
+ <para>The <command>Take Ownership</command> button will not allow
+ you to change the ownership of this file to yourself (clicking on
+ it will display a dialog box complaining that the user you are
+ currently logged onto the NT client cannot be found). The reason
+ for this is that changing the ownership of a file is a privileged
+ operation in UNIX, available only to the <emphasis>root</emphasis>
+ user. As clicking on this button causes NT to attempt to change
+ the ownership of a file to the current user logged into the NT
+ client this will not work with Samba at this time.</para>
+
+ <para>There is an NT chown command that will work with Samba
+ and allow a user with Administrator privilege connected
+ to a Samba 2.0.4 server as root to change the ownership of
+ files on both a local NTFS filesystem or remote mounted NTFS
+ or Samba drive. This is available as part of the <emphasis>Seclib
+ </emphasis> NT security library written by Jeremy Allison of
+ the Samba Team, available from the main Samba ftp site.</para>
+
+</sect1>
+
+<sect1>
+ <title>Viewing file or directory permissions</title>
+
+ <para>The third button is the <command>"Permissions"</command>
+ button. Clicking on this brings up a dialog box that shows both
+ the permissions and the UNIX owner of the file or directory.
+ The owner is displayed in the form :</para>
+
+ <para><command>"SERVER\user (Long name)"</command></para>
+
+ <para>Where <replaceable>SERVER</replaceable> is the NetBIOS name of
+ the Samba server, <replaceable>user</replaceable> is the user name of
+ the UNIX user who owns the file, and <replaceable>(Long name)</replaceable>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database).</para>
+
+ <para>If the parameter <parameter>nt acl support</parameter>
+ is set to <constant>false</constant> then the file owner will
+ be shown as the NT user <command>"Everyone"</command> and the
+ permissions will be shown as NT "Full Control".</para>
+
+
+ <para>The permissions field is displayed differently for files
+ and directories, so I'll describe the way file permissions
+ are displayed first.</para>
+
+ <sect2>
+ <title>File Permissions</title>
+
+ <para>The standard UNIX user/group/world triple and
+ the corresponding "read", "write", "execute" permissions
+ triples are mapped by Samba into a three element NT ACL
+ with the 'r', 'w', and 'x' bits mapped into the corresponding
+ NT permissions. The UNIX world permissions are mapped into
+ the global NT group <command>Everyone</command>, followed
+ by the list of permissions allowed for UNIX world. The UNIX
+ owner and group permissions are displayed as an NT
+ <command>user</command> icon and an NT <command>local
+ group</command> icon respectively followed by the list
+ of permissions allowed for the UNIX user and group.</para>
+
+ <para>As many UNIX permission sets don't map into common
+ NT names such as <command>"read"</command>, <command>
+ "change"</command> or <command>"full control"</command> then
+ usually the permissions will be prefixed by the words <command>
+ "Special Access"</command> in the NT display list.</para>
+
+ <para>But what happens if the file has no permissions allowed
+ for a particular UNIX user group or world component ? In order
+ to allow "no permissions" to be seen and modified then Samba
+ overloads the NT <command>"Take Ownership"</command> ACL attribute
+ (which has no meaning in UNIX) and reports a component with
+ no permissions as having the NT <command>"O"</command> bit set.
+ This was chosen of course to make it look like a zero, meaning
+ zero permissions. More details on the decision behind this will
+ be given below.</para>
+ </sect2>
+
+ <sect2>
+ <title>Directory Permissions</title>
+
+ <para>Directories on an NT NTFS file system have two
+ different sets of permissions. The first set of permissions
+ is the ACL set on the directory itself, this is usually displayed
+ in the first set of parentheses in the normal <command>"RW"</command>
+ NT style. This first set of permissions is created by Samba in
+ exactly the same way as normal file permissions are, described
+ above, and is displayed in the same way.</para>
+
+ <para>The second set of directory permissions has no real meaning
+ in the UNIX permissions world and represents the <command>
+ "inherited"</command> permissions that any file created within
+ this directory would inherit.</para>
+
+ <para>Samba synthesises these inherited permissions for NT by
+ returning as an NT ACL the UNIX permission mode that a new file
+ created by Samba on this share would receive.</para>
+ </sect2>
+</sect1>
+
+<sect1>
+ <title>Modifying file or directory permissions</title>
+
+ <para>Modifying file and directory permissions is as simple
+ as changing the displayed permissions in the dialog box, and
+ clicking the <command>OK</command> button. However, there are
+ limitations that a user needs to be aware of, and also interactions
+ with the standard Samba permission masks and mapping of DOS
+ attributes that need to also be taken into account.</para>
+
+ <para>If the parameter <parameter>nt acl support</parameter>
+ is set to <constant>false</constant> then any attempt to set
+ security permissions will fail with an <command>"Access Denied"
+ </command> message.</para>
+
+ <para>The first thing to note is that the <command>"Add"</command>
+ button will not return a list of users in Samba 2.0.4 (it will give
+ an error message of <command>"The remote procedure call failed
+ and did not execute"</command>). This means that you can only
+ manipulate the current user/group/world permissions listed in
+ the dialog box. This actually works quite well as these are the
+ only permissions that UNIX actually has.</para>
+
+ <para>If a permission triple (either user, group, or world)
+ is removed from the list of permissions in the NT dialog box,
+ then when the <command>"OK"</command> button is pressed it will
+ be applied as "no permissions" on the UNIX side. If you then
+ view the permissions again the "no permissions" entry will appear
+ as the NT <command>"O"</command> flag, as described above. This
+ allows you to add permissions back to a file or directory once
+ you have removed them from a triple component.</para>
+
+ <para>As UNIX supports only the "r", "w" and "x" bits of
+ an NT ACL then if other NT security attributes such as "Delete
+ access" are selected then they will be ignored when applied on
+ the Samba server.</para>
+
+ <para>When setting permissions on a directory the second
+ set of permissions (in the second set of parentheses) is
+ by default applied to all files within that directory. If this
+ is not what you want you must uncheck the <command>"Replace
+ permissions on existing files"</command> checkbox in the NT
+ dialog before clicking <command>"OK"</command>.</para>
+
+ <para>If you wish to remove all permissions from a
+ user/group/world component then you may either highlight the
+ component and click the <command>"Remove"</command> button,
+ or set the component to only have the special <command>"Take
+ Ownership"</command> permission (displayed as <command>"O"
+ </command>) highlighted.</para>
+</sect1>
+
+<sect1>
+ <title>Interaction with the standard Samba create mask
+ parameters</title>
+
+ <para>Note that with Samba 2.0.5 there are four new parameters
+ to control this interaction. These are :</para>
+
+ <para><parameter>security mask</parameter></para>
+ <para><parameter>force security mode</parameter></para>
+ <para><parameter>directory security mask</parameter></para>
+ <para><parameter>force directory security mode</parameter></para>
+
+ <para>Once a user clicks <command>"OK"</command> to apply the
+ permissions Samba maps the given permissions into a user/group/world
+ r/w/x triple set, and then will check the changed permissions for a
+ file against the bits set in the <ulink url="smb.conf.5.html#SECURITYMASK">
+ <parameter>security mask</parameter></ulink> parameter. Any bits that
+ were changed that are not set to '1' in this parameter are left alone
+ in the file permissions.</para>
+
+ <para>Essentially, zero bits in the <parameter>security mask</parameter>
+ mask may be treated as a set of bits the user is <emphasis>not</emphasis>
+ allowed to change, and one bits are those the user is allowed to change.
+ </para>
+
+ <para>If not set explicitly this parameter is set to the same value as
+ the <ulink url="smb.conf.5.html#CREATEMASK"><parameter>create mask
+ </parameter></ulink> parameter to provide compatibility with Samba 2.0.4
+ where this permission change facility was introduced. To allow a user to
+ modify all the user/group/world permissions on a file, set this parameter
+ to 0777.</para>
+
+ <para>Next Samba checks the changed permissions for a file against
+ the bits set in the <ulink url="smb.conf.5.html#FORCESECURITYMODE">
+ <parameter>force security mode</parameter></ulink> parameter. Any bits
+ that were changed that correspond to bits set to '1' in this parameter
+ are forced to be set.</para>
+
+ <para>Essentially, bits set in the <parameter>force security mode
+ </parameter> parameter may be treated as a set of bits that, when
+ modifying security on a file, the user has always set to be 'on'.</para>
+
+ <para>If not set explicitly this parameter is set to the same value
+ as the <ulink url="smb.conf.5.html#FORCECREATEMODE"><parameter>force
+ create mode</parameter></ulink> parameter to provide compatibility
+ with Samba 2.0.4 where the permission change facility was introduced.
+ To allow a user to modify all the user/group/world permissions on a file
+ with no restrictions set this parameter to 000.</para>
+
+ <para>The <parameter>security mask</parameter> and <parameter>force
+ security mode</parameter> parameters are applied to the change
+ request in that order.</para>
+
+ <para>For a directory Samba will perform the same operations as
+ described above for a file except using the parameter <parameter>
+ directory security mask</parameter> instead of <parameter>security
+ mask</parameter>, and <parameter>force directory security mode
+ </parameter> parameter instead of <parameter>force security mode
+ </parameter>.</para>
+
+ <para>The <parameter>directory security mask</parameter> parameter
+ by default is set to the same value as the <parameter>directory mask
+ </parameter> parameter and the <parameter>force directory security
+ mode</parameter> parameter by default is set to the same value as
+ the <parameter>force directory mode</parameter> parameter to provide
+ compatibility with Samba 2.0.4 where the permission change facility
+ was introduced.</para>
+
+ <para>In this way Samba enforces the permission restrictions that
+ an administrator can set on a Samba share, whilst still allowing users
+ to modify the permission bits within that restriction.</para>
+
+ <para>If you want to set up a share that allows users full control
+ in modifying the permission bits on their files and directories and
+ doesn't force any particular bits to be set 'on', then set the following
+ parameters in the <ulink url="smb.conf.5.html"><filename>smb.conf(5)
+ </filename></ulink> file in that share specific section :</para>
+
+ <para><parameter>security mask = 0777</parameter></para>
+ <para><parameter>force security mode = 0</parameter></para>
+ <para><parameter>directory security mask = 0777</parameter></para>
+ <para><parameter>force directory security mode = 0</parameter></para>
+
+ <para>As described, in Samba 2.0.4 the parameters :</para>
+
+ <para><parameter>create mask</parameter></para>
+ <para><parameter>force create mode</parameter></para>
+ <para><parameter>directory mask</parameter></para>
+ <para><parameter>force directory mode</parameter></para>
+
+ <para>were used instead of the parameters discussed here.</para>
+</sect1>
+
+<sect1>
+ <title>Interaction with the standard Samba file attribute
+ mapping</title>
+
+ <para>Samba maps some of the DOS attribute bits (such as "read
+ only") into the UNIX permissions of a file. This means there can
+ be a conflict between the permission bits set via the security
+ dialog and the permission bits set by the file attribute mapping.
+ </para>
+
+ <para>One way this can show up is if a file has no UNIX read access
+ for the owner it will show up as "read only" in the standard
+ file attributes tabbed dialog. Unfortunately this dialog is
+ the same one that contains the security info in another tab.</para>
+
+ <para>What this can mean is that if the owner changes the permissions
+ to allow themselves read access using the security dialog, clicks
+ <command>"OK"</command> to get back to the standard attributes tab
+ dialog, and then clicks <command>"OK"</command> on that dialog, then
+ NT will set the file permissions back to read-only (as that is what
+ the attributes still say in the dialog). This means that after setting
+ permissions and clicking <command>"OK"</command> to get back to the
+ attributes dialog you should always hit <command>"Cancel"</command>
+ rather than <command>"OK"</command> to ensure that your changes
+ are not overridden.</para>
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/OS2-Client-HOWTO.sgml b/docs/docbook/projdoc/OS2-Client-HOWTO.sgml
new file mode 100755
index 00000000000..ca7ad6a754e
--- /dev/null
+++ b/docs/docbook/projdoc/OS2-Client-HOWTO.sgml
@@ -0,0 +1,142 @@
+<chapter id="os2">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Jim</firstname><surname>McDonough</surname>
+ <affiliation>
+ <orgname>IBM</orgname>
+ <address>
+ <email>jerry@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>5 Mar 2001</pubdate>
+</chapterinfo>
+
+<title>OS2 Client HOWTO</title>
+
+<sect1>
+ <title>FAQs</title>
+
+ <sect2>
+ <title>How can I configure OS/2 Warp Connect or
+ OS/2 Warp 4 as a client for Samba?</title>
+
+ <para>A more complete answer to this question can be
+ found on <ulink url="http://carol.wins.uva.nl/~leeuw/samba/warp.html">
+ http://carol.wins.uva.nl/~leeuw/samba/warp.html</ulink>.</para>
+
+ <para>Basically, you need three components:</para>
+
+ <itemizedlist>
+ <listitem><para>The File and Print Client ('IBM Peer')
+ </para></listitem>
+ <listitem><para>TCP/IP ('Internet support')
+ </para></listitem>
+ <listitem><para>The "NetBIOS over TCP/IP" driver ('TCPBEUI')
+ </para></listitem>
+ </itemizedlist>
+
+ <para>Installing the first two together with the base operating
+ system on a blank system is explained in the Warp manual. If Warp
+ has already been installed, but you now want to install the
+ networking support, use the "Selective Install for Networking"
+ object in the "System Setup" folder.</para>
+
+ <para>Adding the "NetBIOS over TCP/IP" driver is not described
+ in the manual and just barely in the online documentation. Start
+ MPTS.EXE, click on OK, click on "Configure LAPS" and click
+ on "IBM OS/2 NETBIOS OVER TCP/IP" in 'Protocols'. This line
+ is then moved to 'Current Configuration'. Select that line,
+ click on "Change number" and increase it from 0 to 1. Save this
+ configuration.</para>
+
+ <para>If the Samba server(s) is not on your local subnet, you
+ can optionally add IP names and addresses of these servers
+ to the "Names List", or specify a WINS server ('NetBIOS
+ Nameserver' in IBM and RFC terminology). For Warp Connect you
+ may need to download an update for 'IBM Peer' to bring it on
+ the same level as Warp 4. See the webpage mentioned above.</para>
+ </sect2>
+
+ <sect2>
+ <title>How can I configure OS/2 Warp 3 (not Connect),
+ OS/2 1.2, 1.3 or 2.x for Samba?</title>
+
+ <para>You can use the free Microsoft LAN Manager 2.2c Client
+ for OS/2 from
+ <ulink url="ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/">
+ ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/</ulink>.
+ See <ulink url="http://carol.wins.uva.nl/~leeuw/lanman.html">
+ http://carol.wins.uva.nl/~leeuw/lanman.html</ulink> for
+ more information on how to install and use this client. In
+ a nutshell, edit the file \OS2VER in the root directory of
+ the OS/2 boot partition and add the lines:</para>
+
+ <para><programlisting>
+ 20=setup.exe
+ 20=netwksta.sys
+ 20=netvdd.sys
+ </programlisting></para>
+
+ <para>before you install the client. Also, don't use the
+ included NE2000 driver because it is buggy. Try the NE2000
+ or NS2000 driver from
+ <ulink url="ftp://ftp.cdrom.com/pub/os2/network/ndis/">
+ ftp://ftp.cdrom.com/pub/os2/network/ndis/</ulink> instead.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Are there any other issues when OS/2 (any version)
+ is used as a client?</title>
+
+ <para>When you do a NET VIEW or use the "File and Print
+ Client Resource Browser", no Samba servers show up. This can
+ be fixed by a patch from <ulink
+ url="http://carol.wins.uva.nl/~leeuw/samba/fix.html">
+ http://carol.wins.uva.nl/~leeuw/samba/fix.html</ulink>.
+ The patch will be included in a later version of Samba. It also
+ fixes a couple of other problems, such as preserving long
+ filenames when objects are dragged from the Workplace Shell
+ to the Samba server. </para>
+ </sect2>
+
+ <sect2>
+ <title>How do I get printer driver download working
+ for OS/2 clients?</title>
+
+ <para>First, create a share called [PRINTDRV] that is
+ world-readable. Copy your OS/2 driver files there. Note
+ that the .EA_ files must still be separate, so you will need
+ to use the original install files, and not copy an installed
+ driver from an OS/2 system.</para>
+
+ <para>Install the NT driver first for that printer. Then,
+ add to your smb.conf a parameter, "os2 driver map =
+ <replaceable>filename</replaceable>". Then, in the file
+ specified by <replaceable>filename</replaceable>, map the
+ name of the NT driver name to the OS/2 driver name as
+ follows:</para>
+
+ <para>&lt;nt driver name&gt; = &lt;os2 driver
+ name&gt;.&lt;device name&gt;, e.g.:
+ HP LaserJet 5L = LASERJET.HP LaserJet 5L</para>
+
+ <para>You can have multiple drivers mapped in this file.</para>
+
+ <para>If you only specify the OS/2 driver name, and not the
+ device name, the first attempt to download the driver will
+ actually download the files, but the OS/2 client will tell
+ you the driver is not available. On the second attempt, it
+ will work. This is fixed simply by adding the device name
+ to the mapping, after which it will work on the first attempt.
+ </para>
+ </sect2>
+</sect1>
+
+</chapter>
+
diff --git a/docs/docbook/projdoc/PAM-Authentication-And-Samba.sgml b/docs/docbook/projdoc/PAM-Authentication-And-Samba.sgml
new file mode 100755
index 00000000000..594516640de
--- /dev/null
+++ b/docs/docbook/projdoc/PAM-Authentication-And-Samba.sgml
@@ -0,0 +1,215 @@
+<chapter id="pam">
+
+
+<chapterinfo>
+ <author>
+ <firstname>John</firstname><surname>Terpstra</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>jht@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (Jun 21 2001) </pubdate>
+</chapterinfo>
+
+<title>Configuring PAM for distributed but centrally
+managed authentication</title>
+
+<sect1>
+<title>Samba and PAM</title>
+
+<para>
+A number of Unix systems (eg: Sun Solaris), as well as the
+xxxxBSD family and Linux, now utilize the Pluggable Authentication
+Modules (PAM) facility to provide all authentication,
+authorization and resource control services. Prior to the
+introduction of PAM, a decision to use an alternative to
+the system password database (<filename>/etc/passwd</filename>)
+would require the provision of alternatives for all programs that provide
+security services. Such a choice would involve provision of
+alternatives to such programs as: <command>login</command>,
+<command>passwd</command>, <command>chown</command>, etc.
+</para>
+
+<para>
+PAM provides a mechanism that disconnects these security programs
+from the underlying authentication/authorization infrastructure.
+PAM is configured either through one file <filename>/etc/pam.conf</filename> (Solaris),
+or by editing individual files that are located in <filename>/etc/pam.d</filename>.
+</para>
+
+<para>
+The following is an example <filename>/etc/pam.d/login</filename> configuration file.
+This example had all options been uncommented is probably not usable
+as it stacks many conditions before allowing successful completion
+of the login process. Essentially all conditions can be disabled
+by commenting them out except the calls to <filename>pam_pwdb.so</filename>.
+</para>
+
+<para><programlisting>
+#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_securetty.so
+auth required pam_nologin.so
+# auth required pam_dialup.so
+# auth optional pam_mail.so
+auth required pam_pwdb.so shadow md5
+# account requisite pam_time.so
+account required pam_pwdb.so
+session required pam_pwdb.so
+# session optional pam_lastlog.so
+# password required pam_cracklib.so retry=3
+password required pam_pwdb.so shadow md5
+</programlisting></para>
+
+<para>
+PAM allows use of replacable modules. Those available on a
+sample system include:
+</para>
+
+<para><programlisting>
+$ /bin/ls /lib/security
+pam_access.so pam_ftp.so pam_limits.so
+pam_ncp_auth.so pam_rhosts_auth.so pam_stress.so
+pam_cracklib.so pam_group.so pam_listfile.so
+pam_nologin.so pam_rootok.so pam_tally.so
+pam_deny.so pam_issue.so pam_mail.so
+pam_permit.so pam_securetty.so pam_time.so
+pam_dialup.so pam_lastlog.so pam_mkhomedir.so
+pam_pwdb.so pam_shells.so pam_unix.so
+pam_env.so pam_ldap.so pam_motd.so
+pam_radius.so pam_smbpass.so pam_unix_acct.so
+pam_wheel.so pam_unix_auth.so pam_unix_passwd.so
+pam_userdb.so pam_warn.so pam_unix_session.so
+</programlisting></para>
+
+<para>
+The following example for the login program replaces the use of
+the <filename>pam_pwdb.so</filename> module which uses the system
+password database (<filename>/etc/passwd</filename>,
+<filename>/etc/shadow</filename>, <filename>/etc/group</filename>) with
+the module <filename>pam_smbpass.so</filename> which uses the Samba
+database which contains the Microsoft MD4 encrypted password
+hashes. This database is stored in either
+<filename>/usr/local/samba/private/smbpasswd</filename>,
+<filename>/etc/samba/smbpasswd</filename>, or in
+<filename>/etc/samba.d/smbpasswd</filename>, depending on the
+Samba implementation for your Unix/Linux system. The
+<filename>pam_smbpass.so</filename> module is provided by
+Samba version 2.2.1 or later. It can be compiled by specifying the
+<command>--with-pam_smbpass</command> options when running Samba's
+<filename>configure</filename> script. For more information
+on the <filename>pam_smbpass</filename> module, see the documentation
+in the <filename>source/pam_smbpass</filename> directory of the Samba
+source distribution.
+</para>
+
+<para><programlisting>
+#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_smbpass.so nodelay
+account required pam_smbpass.so nodelay
+session required pam_smbpass.so nodelay
+password required pam_smbpass.so nodelay
+</programlisting></para>
+
+<para>
+The following is the PAM configuration file for a particular
+Linux system. The default condition uses <filename>pam_pwdb.so</filename>.
+</para>
+
+<para><programlisting>
+#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_pwdb.so nullok nodelay shadow audit
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_pwdb.so shadow md5
+</programlisting></para>
+
+<para>
+In the following example the decision has been made to use the
+smbpasswd database even for basic samba authentication. Such a
+decision could also be made for the passwd program and would
+thus allow the smbpasswd passwords to be changed using the passwd
+program.
+</para>
+
+<para><programlisting>
+#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_smbpass.so nodelay
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_smbpass.so nodelay smbconf=/etc/samba.d/smb.conf
+</programlisting></para>
+
+<para>
+Note: PAM allows stacking of authentication mechanisms. It is
+also possible to pass information obtained within on PAM module through
+to the next module in the PAM stack. Please refer to the documentation for
+your particular system implementation for details regarding the specific
+capabilities of PAM in this environment. Some Linux implmentations also
+provide the <filename>pam_stack.so</filename> module that allows all
+authentication to be configured in a single central file. The
+<filename>pam_stack.so</filename> method has some very devoted followers
+on the basis that it allows for easier administration. As with all issues in
+life though, every decision makes trade-offs, so you may want examine the
+PAM documentation for further helpful information.
+</para>
+
+</sect1>
+
+<sect1>
+<title>Distributed Authentication</title>
+
+<para>
+The astute administrator will realize from this that the
+combination of <filename>pam_smbpass.so</filename>,
+<command>winbindd</command>, and <command>rsync</command> (see
+<ulink url="http://rsync.samba.org/">http://rsync.samba.org/</ulink>)
+will allow the establishment of a centrally managed, distributed
+user/password database that can also be used by all
+PAM (eg: Linux) aware programs and applications. This arrangement
+can have particularly potent advantages compared with the
+use of Microsoft Active Directory Service (ADS) in so far as
+reduction of wide area network authentication traffic.
+</para>
+
+</sect1>
+
+<sect1>
+<title>PAM Configuration in smb.conf</title>
+
+<para>
+There is an option in smb.conf called <ulink
+url="smb.conf.5.html#OBEYPAMRESTRICTIONS">obey pam restrictions</ulink>.
+The following is from the on-line help for this option in SWAT;
+</para>
+
+<para>
+When Samba 2.2 is configure to enable PAM support (i.e.
+<constant>--with-pam</constant>), this parameter will
+control whether or not Samba should obey PAM's account
+and session management directives. The default behavior
+is to use PAM for clear text authentication only and to
+ignore any account or session management. Note that Samba always
+ignores PAM for authentication in the case of
+<ulink url="smb.conf.5.html#ENCRYPTPASSWORDS">encrypt passwords = yes</ulink>.
+The reason is that PAM modules cannot support the challenge/response
+authentication mechanism needed in the presence of SMB
+password encryption.
+</para>
+
+<para>Default: <command>obey pam restrictions = no</command></para>
+
+</sect1>
+</chapter>
diff --git a/docs/docbook/projdoc/Samba-BDC-HOWTO.sgml b/docs/docbook/projdoc/Samba-BDC-HOWTO.sgml
new file mode 100755
index 00000000000..02926265ab1
--- /dev/null
+++ b/docs/docbook/projdoc/Samba-BDC-HOWTO.sgml
@@ -0,0 +1,262 @@
+<chapter id="samba-bdc">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Volker</firstname><surname>Lendecke</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address><email>Volker.Lendecke@SerNet.DE</email></address>
+ </affiliation>
+ </author>
+ <pubdate> (26 Apr 2001) </pubdate>
+</chapterinfo>
+
+<title>
+How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain
+</title>
+
+<sect1>
+<title>Prerequisite Reading</title>
+
+<para>
+Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring a Samba PDC
+as described in the <ulink url="Samba-PDC-HOWTO.html">Samba-PDC-HOWTO</ulink>.
+</para>
+
+
+</sect1>
+
+<sect1>
+
+<title>Background</title>
+
+<para>
+What is a Domain Controller? It is a machine that is able to answer
+logon requests from workstations in a Windows NT Domain. Whenever a
+user logs into a Windows NT Workstation, the workstation connects to a
+Domain Controller and asks him whether the username and password the
+user typed in is correct. The Domain Controller replies with a lot of
+information about the user, for example the place where the users
+profile is stored, the users full name of the user. All this
+information is stored in the NT user database, the so-called SAM.
+</para>
+
+<para>
+There are two kinds of Domain Controller in a NT 4 compatible Domain:
+A Primary Domain Controller (PDC) and one or more Backup Domain
+Controllers (BDC). The PDC contains the master copy of the
+SAM. Whenever the SAM has to change, for example when a user changes
+his password, this change has to be done on the PDC. A Backup Domain
+Controller is a machine that maintains a read-only copy of the
+SAM. This way it is able to reply to logon requests and authenticate
+users in case the PDC is not available. During this time no changes to
+the SAM are possible. Whenever changes to the SAM are done on the PDC,
+all BDC receive the changes from the PDC.
+</para>
+
+<para>
+Since version 2.2 Samba officially supports domain logons for all
+current Windows Clients, including Windows 2000 and XP. This text
+assumes the domain to be named SAMBA. To be able to act as a PDC, some
+parameters in the [global]-section of the smb.conf have to be set:
+</para>
+
+<para><programlisting>
+[global]
+ workgroup = SAMBA
+ domain master = yes
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....
+</programlisting></para>
+
+<para>
+Several other things like a [homes] and a [netlogon] share also may be
+set along with settings for the profile path, the users home drive and
+others. This will not be covered in this document.
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>What qualifies a Domain Controller on the network?</title>
+
+<para>
+Every machine that is a Domain Controller for the domain SAMBA has to
+register the NetBIOS group name SAMBA#1c with the WINS server and/or
+by broadcast on the local network. The PDC also registers the unique
+NetBIOS name SAMBA#1b with the WINS server. The name type #1b is
+normally reserved for the domain master browser, a role that has
+nothing to do with anything related to authentication, but the
+Microsoft Domain implementation requires the domain master browser to
+be on the same machine as the PDC.
+</para>
+
+
+<sect2>
+<title>How does a Workstation find its domain controller?</title>
+
+<para>
+A NT workstation in the domain SAMBA that wants a local user to be
+authenticated has to find the domain controller for SAMBA. It does
+this by doing a NetBIOS name query for the group name SAMBA#1c. It
+assumes that each of the machines it gets back from the queries is a
+domain controller and can answer logon requests. To not open security
+holes both the workstation and the selected (TODO: How is the DC
+chosen) domain controller authenticate each other. After that the
+workstation sends the user's credentials (his name and password) to
+the domain controller, asking for approval.
+</para>
+
+</sect2>
+
+
+<sect2>
+<title>When is the PDC needed?</title>
+
+<para>
+Whenever a user wants to change his password, this has to be done on
+the PDC. To find the PDC, the workstation does a NetBIOS name query
+for SAMBA#1b, assuming this machine maintains the master copy of the
+SAM. The workstation contacts the PDC, both mutually authenticate and
+the password change is done.
+</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1>
+<title>Can Samba be a Backup Domain Controller?</title>
+
+<para>
+With version 2.2, no. The native NT SAM replication protocols have
+not yet been fully implemented. The Samba Team is working on
+understanding and implementing the protocols, but this work has not
+been finished for version 2.2.
+</para>
+
+<para>
+Can I get the benefits of a BDC with Samba? Yes. The main reason for
+implementing a BDC is availability. If the PDC is a Samba machine,
+a second Samba machine can be set up to
+service logon requests whenever the PDC is down.
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>How do I set up a Samba BDC?</title>
+
+<para>
+Several things have to be done:
+</para>
+
+<itemizedlist>
+
+ <listitem><para>
+ The file <filename>private/MACHINE.SID</filename> identifies the domain. When a samba
+ server is first started, it is created on the fly and must never be
+ changed again. This file has to be the same on the PDC and the BDC,
+ so the MACHINE.SID has to be copied from the PDC to the BDC. Note that in the
+ latest Samba 2.2.x releases, the machine SID (and therefore domain SID) is stored
+ in the <filename>private/secrets.tdb</filename> database. This file cannot just
+ be copied because Samba looks under the key <constant>SECRETS/SID/<replaceable>DOMAIN</replaceable></constant>.
+ where <replaceable>DOMAIN</replaceable> is the machine's netbios name. Since this name has
+ to be unique for each SAMBA server, this lookup will fail. </para>
+ <para>
+ A new option has been added to the <command>smbpasswd(8)</command>
+ command to help ease this problem. When running <command>smbpasswd -S</command> as the root user,
+ the domain SID will be retrieved from a domain controller matching the value of the
+ <parameter>workgroup</parameter> parameter in <filename>smb.conf</filename> and stored as the
+ new Samba server's machine SID. See the <ulink url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink>
+ man page for more details on this functionality.
+ </para></listitem>
+
+ <listitem><para>
+ The Unix user database has to be synchronized from the PDC to the
+ BDC. This means that both the /etc/passwd and /etc/group have to be
+ replicated from the PDC to the BDC. This can be done manually
+ whenever changes are made, or the PDC is set up as a NIS master
+ server and the BDC as a NIS slave server. To set up the BDC as a
+ mere NIS client would not be enough, as the BDC would not be able to
+ access its user database in case of a PDC failure. LDAP is also a
+ potential vehicle for sharing this information.
+ </para></listitem>
+
+ <listitem><para>
+ The Samba password database in the file <filename>private/smbpasswd</filename>
+ has to be replicated from the PDC to the BDC. This is a bit tricky, see the
+ next section.
+ </para></listitem>
+
+ <listitem><para>
+ Any netlogon share has to be replicated from the PDC to the
+ BDC. This can be done manually whenever login scripts are changed,
+ or it can be done automatically together with the smbpasswd
+ synchronization.
+ </para></listitem>
+
+</itemizedlist>
+
+<para>
+Finally, the BDC has to be found by the workstations. This can be done
+by setting
+</para>
+
+<para><programlisting>
+[global]
+ workgroup = SAMBA
+ domain master = no
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....
+</programlisting></para>
+
+<para>
+in the [global]-section of the smb.conf of the BDC. This makes the BDC
+only register the name SAMBA#1c with the WINS server. This is no
+problem as the name SAMBA#1c is a NetBIOS group name that is meant to
+be registered by more than one machine. The parameter 'domain master =
+no' forces the BDC not to register SAMBA#1b which as a unique NetBIOS
+name is reserved for the Primary Domain Controller.
+</para>
+
+<sect2>
+<title>How do I replicate the smbpasswd file?</title>
+
+<para>
+Replication of the smbpasswd file is sensitive. It has to be done
+whenever changes to the SAM are made. Every user's password change
+(including machine trust account password changes) is done in the
+smbpasswd file and has to be replicated to the BDC. So
+replicating the smbpasswd file very often is necessary.
+</para>
+
+<para>
+As the smbpasswd file contains plain text password equivalents, it
+must not be sent unencrypted over the wire. The best way to set up
+smbpasswd replication from the PDC to the BDC is to use the utility
+<command>rsync(1)</command>. <command>rsync</command> can use
+<command>ssh(1)</command> as a transport. <command>ssh</command> itself
+can be set up to accept <emphasis>only</emphasis> <command>rsync</command> transfer without requiring the user to
+type a password. Refer to the man pages for these two tools for more details.
+</para>
+
+<para>
+Another solution with high potential is to use Samba's <parameter>--with-ldapsam</parameter>
+for sharing and/or replicating the list of <constant>sambaAccount</constant> entries.
+This can all be done over SSL to ensure security. See the <ulink url="Samba-LDAP-HOWTO.html">Samba-LDAP-HOWTO</ulink>
+for more details.
+</para>
+
+</sect2>
+</sect1>
+</chapter>
diff --git a/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml b/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml
new file mode 100755
index 00000000000..6b153af6feb
--- /dev/null
+++ b/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml
@@ -0,0 +1,640 @@
+<chapter id="samba-ldap-howto">
+
+<chapterinfo>
+ <author>
+ <firstname>Gerald (Jerry)></firstname><surname>Carter</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address><email>jerry@samba.org</email></address>
+ </affiliation>
+ <firstname>Olivier (lem)></firstname><surname>Lemaire</surname>
+ <affiliation>
+ <orgname>IDEALX</orgname>
+ <address><email>olem@IDEALX.org</email></address>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (16 Jun 2002) </pubdate>
+</chapterinfo>
+
+<title>Storing Samba's User/Machine Account information in an LDAP Directory</title>
+
+<sect1>
+<title>Purpose</title>
+
+<para>
+This document describes how to use an LDAP directory for storing Samba user
+account information traditionally stored in the smbpasswd(5) file. It is
+assumed that the reader already has a basic understanding of LDAP concepts
+and has a working directory server already installed. For more information
+on LDAP architectures and Directories, please refer to the following sites.
+</para>
+
+<itemizedlist>
+ <listitem><para>OpenLDAP - <ulink url="http://www.openldap.org/">http://www.openldap.org/</ulink></para></listitem>
+ <listitem><para>iPlanet Directory Server - <ulink url="http://iplanet.netscape.com/directory">http://iplanet.netscape.com/directory</ulink></para></listitem>
+</itemizedlist>
+
+<para>
+Note that <ulink url="http://www.ora.com/">O'Reilly Publishing</ulink> is working on
+a guide to LDAP for System Administrators which has a planned release date of
+late 2002.
+</para>
+
+<para>
+Two additional Samba resources which may prove to be helpful are
+</para>
+
+<itemizedlist>
+ <listitem><para>The <ulink url="http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html">Samba-PDC-LDAP-HOWTO</ulink>
+ maintained by Ignacio Coupeau.</para></listitem>
+
+ <listitem><para>The NT migration scripts from <ulink url="http://samba.idealx.org/">IDEALX</ulink> that are
+ geared to manage users and group in such a Samba-LDAP Domain Controller configuration. These scripts can
+ be found in the Samba 2.2.5 release in the <filename>examples/LDAP/smbldap-tools/</filename> directory.
+ </para></listitem>
+</itemizedlist>
+
+</sect1>
+
+
+<sect1>
+<title>Introduction</title>
+
+<para>
+Traditionally, when configuring <ulink url="smb.conf.5.html#ENCRYPTPASSWORDS">"encrypt
+passwords = yes"</ulink> in Samba's <filename>smb.conf</filename> file, user account
+information such as username, LM/NT password hashes, password change times, and account
+flags have been stored in the <filename>smbpasswd(5)</filename> file. There are several
+disadvantages to this approach for sites with very large numbers of users (counted
+in the thousands).
+</para>
+
+<itemizedlist>
+<listitem><para>
+The first is that all lookups must be performed sequentially. Given that
+there are approximately two lookups per domain logon (one for a normal
+session connection such as when mapping a network drive or printer), this
+is a performance bottleneck for large sites. What is needed is an indexed approach
+such as is used in databases.
+</para></listitem>
+
+<listitem><para>
+The second problem is that administrators who desired to replicate a
+smbpasswd file to more than one Samba server were left to use external
+tools such as <command>rsync(1)</command> and <command>ssh(1)</command>
+and wrote custom, in-house scripts.
+</para></listitem>
+
+<listitem><para>
+And finally, the amount of information which is stored in an
+smbpasswd entry leaves no room for additional attributes such as
+a home directory, password expiration time, or even a Relative
+Identified (RID).
+</para></listitem>
+</itemizedlist>
+
+<para>
+As a result of these defeciencies, a more robust means of storing user attributes
+used by <command>smbd</command> was developed. The API which defines access to user accounts
+is commonly referred to as the samdb interface (previously this was called the passdb
+API, and is still so named in the CVS trees). In Samba 2.2.3, enabling support
+for a samdb backend (e.g. <parameter>--with-ldapsam</parameter> or
+<parameter>--with-tdbsam</parameter>) requires compile time support.
+</para>
+
+<para>
+When compiling Samba to include the <parameter>--with-ldapsam</parameter> autoconf
+option, <command>smbd</command> (and associated tools) will store and lookup user accounts in
+an LDAP directory. In reality, this is very easy to understand. If you are
+comfortable with using an smbpasswd file, simply replace "smbpasswd" with
+"LDAP directory" in all the documentation.
+</para>
+
+<para>
+There are a few points to stress about what the <parameter>--with-ldapsam</parameter>
+does not provide. The LDAP support referred to in the this documentation does not
+include:
+</para>
+
+<itemizedlist>
+ <listitem><para>A means of retrieving user account information from
+ an Windows 2000 Active Directory server.</para></listitem>
+ <listitem><para>A means of replacing /etc/passwd.</para></listitem>
+</itemizedlist>
+
+<para>
+The second item can be accomplished by using LDAP NSS and PAM modules. LGPL
+versions of these libraries can be obtained from PADL Software
+(<ulink url="http://www.padl.com/">http://www.padl.com/</ulink>). However,
+the details of configuring these packages are beyond the scope of this document.
+</para>
+
+</sect1>
+
+<sect1>
+<title>Supported LDAP Servers</title>
+
+<para>
+The LDAP samdb code in 2.2.3 has been developed and tested using the OpenLDAP
+2.0 server and client libraries. The same code should be able to work with
+Netscape's Directory Server and client SDK. However, due to lack of testing
+so far, there are bound to be compile errors and bugs. These should not be
+hard to fix. If you are so inclined, please be sure to forward all patches to
+<ulink url="samba-patches@samba.org">samba-patches@samba.org</ulink> and
+<ulink url="jerry@samba.org">jerry@samba.org</ulink>.
+</para>
+
+</sect1>
+
+
+
+
+<sect1>
+<title>Schema and Relationship to the RFC 2307 posixAccount</title>
+
+
+<para>
+Samba 2.2.3 includes the necessary schema file for OpenLDAP 2.0 in
+<filename>examples/LDAP/samba.schema</filename>. (Note that this schema
+file has been modified since the experimental support initially included
+in 2.2.2). The sambaAccount objectclass is given here:
+</para>
+
+<para><programlisting>
+objectclass ( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILARY
+ DESC 'Samba Account'
+ MUST ( uid $ rid )
+ MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ description $ userWorkstations $ primaryGroupID $ domain ))
+</programlisting></para>
+
+<para>
+The <filename>samba.schema</filename> file has been formatted for OpenLDAP 2.0 & 2.1. The OID's are
+owned by the Samba Team and as such is legal to be openly published.
+If you translate the schema to be used with Netscape DS, please
+submit the modified schema file as a patch to <ulink url="jerry@samba.org">jerry@samba.org</ulink>
+</para>
+
+<para>
+Since the original release, schema files for
+</para>
+
+<itemizedlist>
+ <listitem><para>IBM's SecureWay Server</para></listitem>
+ <listitem><para>Netscape Directory Server version 4.x and 5.x</para></listitem>
+</itemizedlist>
+
+<para>
+have been submitted and included in the Samba source distribution. I cannot
+personally comment on the integration of these commercial directory servers since
+I have not had the oppotinuity to work with them.
+</para>
+
+<para>
+Just as the smbpasswd file is mean to store information which supplements a
+user's <filename>/etc/passwd</filename> entry, so is the sambaAccount object
+meant to supplement the UNIX user account information. A sambaAccount is now an
+<constant>AUXILARY</constant> objectclass so it can be stored alongside
+a posixAccount or person objectclass in the directory. Note that there are
+several fields (e.g. uid) which overlap with the posixAccount objectclass
+outlined in RFC2307. This is by design. The move from a STRUCTURAL objectclass
+to an AUXILIARY one was compliance with the LDAP data model which states that
+an entry can contain only one STRUCTURAL objectclass per entry. This is now
+enforced by the OpenLDAP 2.1 server.
+</para>
+
+
+<para>
+In order to store all user account information (UNIX and Samba) in the directory,
+it is necessary to use the sambaAccount and posixAccount objectclasses in
+combination. However, <command>smbd</command> will still obtain the user's UNIX account
+information via the standard C library calls (e.g. getpwnam(), et. al.).
+This means that the Samba server must also have the LDAP NSS library installed
+and functioning correctly. This division of information makes it possible to
+store all Samba account information in LDAP, but still maintain UNIX account
+information in NIS while the network is transitioning to a full LDAP infrastructure.
+</para>
+</sect1>
+
+<sect1>
+<title>Configuring Samba with LDAP</title>
+
+
+<sect2>
+<title>OpenLDAP configuration</title>
+
+<para>
+To include support for the sambaAccount object in an OpenLDAP directory
+server, first copy the samba.schema file to slapd's configuration directory.
+</para>
+
+<para>
+<prompt>root# </prompt><command>cp samba.schema /etc/openldap/schema/</command>
+</para>
+
+<para>
+Next, include the <filename>samba.schema</filename> file in <filename>slapd.conf</filename>.
+The sambaAccount object contains two attributes which depend upon other schema
+files. The 'uid' attribute is defined in <filename>cosine.schema</filename> and
+the 'displayName' attribute is defined in the <filename>inetorgperson.schema</filename>
+file. Both of these must be included before the <filename>samba.schema</filename> file.
+</para>
+
+<para><programlisting>
+## /etc/openldap/slapd.conf
+
+## schema files (core.schema is required by default)
+include /etc/openldap/schema/core.schema
+
+## needed for sambaAccount
+include /etc/openldap/schema/cosine.schema
+include /etc/openldap/schema/inetorgperson.schema
+include /etc/openldap/schema/samba.schema
+
+## uncomment this line if you want to support the RFC2307 (NIS) schema
+## include /etc/openldap/schema/nis.schema
+
+....
+</programlisting></para>
+
+<para>
+It is recommended that you maintain some indices on some of the most usefull attributes,
+like in the following example, to speed up searches made on sambaAccount objectclasses
+(and possibly posixAccount and posixGroup as well).
+</para>
+<para><programlisting>
+# Indices to maintain
+## required by OpenLDAP 2.0
+index objectclass eq
+
+## support pbb_getsampwnam()
+index uid pres,eq
+## support pdb_getsampwrid()
+index rid eq
+
+## uncomment these if you are storing posixAccount and
+## posixGroup entries in the directory as well
+##index uidNumber eq
+##index gidNumber eq
+##index cn eq
+##index memberUid eq
+</programlisting></para>
+</sect2>
+
+
+<sect2>
+<title>Configuring Samba</title>
+<!--lem: <title>smb.conf LDAP parameters</title> -->
+
+<para>
+The following parameters are available in smb.conf only with <parameter>--with-ldapsam</parameter>
+was included with compiling Samba.
+</para>
+
+<itemizedlist>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPSSL">ldap ssl</ulink></para></listitem>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPSERVER">ldap server</ulink></para></listitem>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPADMINDN">ldap admin dn</ulink></para></listitem>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPSUFFIX">ldap suffix</ulink></para></listitem>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPFILTER">ldap filter</ulink></para></listitem>
+ <listitem><para><ulink url="smb.conf.5.html#LDAPPORT">ldap port</ulink></para></listitem>
+</itemizedlist>
+
+<para>
+These are described in the <ulink url="smb.conf.5.html">smb.conf(5)</ulink> man
+page and so will not be repeated here. However, a sample smb.conf file for
+use with an LDAP directory could appear as
+</para>
+
+<para><programlisting>
+## /usr/local/samba/lib/smb.conf
+[global]
+ security = user
+ encrypt passwords = yes
+
+ netbios name = TASHTEGO
+ workgroup = NARNIA
+
+ # ldap related parameters
+
+ # define the DN to use when binding to the directory servers
+ # The password for this DN is not stored in smb.conf. Rather it
+ # must be set by using 'smbpasswd -w <replaceable>secretpw</replaceable>' to store the
+ # passphrase in the secrets.tdb file. If the "ldap admin dn" values
+ # changes, this password will need to be reset.
+ ldap admin dn = "cn=Samba Manager,ou=people,dc=samba,dc=org"
+
+ # specify the LDAP server's hostname (defaults to locahost)
+ ldap server = ahab.samba.org
+
+ # Define the SSL option when connecting to the directory
+ # ('off', 'start tls', or 'on' (default))
+ ldap ssl = start tls
+
+ # define the port to use in the LDAP session (defaults to 636 when
+ # "ldap ssl = on")
+ ldap port = 389
+
+ # specify the base DN to use when searching the directory
+ ldap suffix = "ou=people,dc=samba,dc=org"
+
+ # generally the default ldap search filter is ok
+ # ldap filter = "(&(uid=%u)(objectclass=sambaAccount))"
+</programlisting></para>
+
+
+</sect2>
+
+
+<sect2>
+<title>Importing <filename>smbpasswd</filename> entries</title>
+
+<para>
+Import existing user entries from an <filename>smbpasswd</filename> can be trivially done using
+a Perl script named <filename>import_smbpasswd.pl</filename> included in the
+<filename>examples/LDAP/</filename> directory of the Samba source distribution. There are
+two main requirements of this script:
+</para>
+
+<itemizedlist>
+ <listitem><para>All users to be imported to the directory must have a valid uid on the
+ local system. This can be a problem if using a machinej different from the Samba server
+ to import the file.</para></listitem>
+
+ <listitem><para>The local system must have a working installation of the Net::LDAP perl
+ module which can be obtained from with <ulink url="http://search.cpan.org/">http://search.cpan.org/</ulink>
+ by searching for <filename>perl-ldap</filename> or directly from <ulink
+ url="http://perl-ldap.sf.net/">http://perl-ldap.sf.net/</ulink>.
+ </para></listitem>
+</itemizedlist>
+
+<para>
+Please refer to the documentation in the same directory as the script for more details.
+</para>
+
+</sect2>
+</sect1>
+
+
+
+<sect1>
+<title>Accounts and Groups management</title>
+
+<para>
+As users accounts are managed thru the sambaAccount objectclass, you should
+modify you existing administration tools to deal with sambaAccount attributes.
+</para>
+
+<para>
+Machines accounts are managed with the sambaAccount objectclass, just
+like users accounts. However, it's up to you to stored thoses accounts
+in a different tree of you LDAP namespace: you should use
+"ou=Groups,dc=plainjoe,dc=org" to store groups and
+"ou=People,dc=plainjoe,dc=org" to store users. Just configure your
+NSS and PAM accordingly (usually, in the /etc/ldap.conf configuration
+file).
+</para>
+
+<para>
+In Samba release 2.2.3, the group management system is based on posix
+groups. This meand that Samba make usage of the posixGroup objectclass.
+For now, there is no NT-like group system management (global and local
+groups).
+</para>
+
+</sect1>
+
+<sect1>
+<title>Security and sambaAccount</title>
+
+
+<para>
+There are two important points to remember when discussing the security
+of sambaAccount entries in the directory.
+</para>
+
+<itemizedlist>
+ <listitem><para><emphasis>Never</emphasis> retrieve the lmPassword or
+ ntPassword attribute values over an unencrypted LDAP session.</para></listitem>
+ <listitem><para><emphasis>Never</emphasis> allow non-admin users to
+ view the lmPassword or ntPassword attribute values.</para></listitem>
+</itemizedlist>
+
+<para>
+These password hashes are clear text equivalents and can be used to impersonate
+the user without deriving the original clear text strings. For more information
+on the details of LM/NT password hashes, refer to the <ulink
+url="ENCRYPTION.html">ENCRYPTION chapter</ulink> of the Samba-HOWTO-Collection.
+</para>
+
+<para>
+To remedy the first security issue, the "ldap ssl" smb.conf parameter defaults
+to require an encrypted session (<command>ldap ssl = on</command>) using
+the default port of 636
+when contacting the directory server. When using an OpenLDAP 2.0 server, it
+is possible to use the use the StartTLS LDAP extended operation in the place of
+LDAPS. In either case, you are strongly discouraged to disable this security
+(<command>ldap ssl = off</command>).
+</para>
+
+<para>
+Note that the LDAPS protocol is deprecated in favor of the LDAPv3 StartTLS
+extended operation. However, the OpenLDAP library still provides support for
+the older method of securing communication between clients and servers.
+</para>
+
+<para>
+The second security precaution is to prevent non-administrative users from
+harvesting password hashes from the directory. This can be done using the
+following ACL in <filename>slapd.conf</filename>:
+</para>
+
+<para><programlisting>
+## allow the "ldap admin dn" access, but deny everyone else
+access to attrs=lmPassword,ntPassword
+ by dn="cn=Samba Admin,ou=people,dc=plainjoe,dc=org" write
+ by * none
+</programlisting></para>
+
+
+</sect1>
+
+
+
+<sect1>
+<title>LDAP specials attributes for sambaAccounts</title>
+
+<para>
+The sambaAccount objectclass is composed of the following attributes:
+</para>
+
+<itemizedlist>
+
+ <listitem><para><constant>lmPassword</constant>: the LANMAN password 16-byte hash stored as a character
+ representation of a hexidecimal string.</para></listitem>
+
+ <listitem><para><constant>ntPassword</constant>: the NT password hash 16-byte stored as a character
+ representation of a hexidecimal string.</para></listitem>
+
+ <listitem><para><constant>pwdLastSet</constant>: The integer time in seconds since 1970 when the
+ <constant>lmPassword</constant> and <constant>ntPassword</constant> attributes were last set.
+ </para></listitem>
+
+ <listitem><para><constant>acctFlags</constant>: string of 11 characters surrounded by square brackets []
+ representing account flags such as U (user), W(workstation), X(no password expiration), and
+ D(disabled).</para></listitem>
+
+ <listitem><para><constant>logonTime</constant>: Integer value currently unused</para></listitem>
+
+ <listitem><para><constant>logoffTime</constant>: Integer value currently unused</para></listitem>
+
+ <listitem><para><constant>kickoffTime</constant>: Integer value currently unused</para></listitem>
+
+ <listitem><para><constant>pwdCanChange</constant>: Integer value currently unused</para></listitem>
+
+ <listitem><para><constant>pwdMustChange</constant>: Integer value currently unused</para></listitem>
+
+ <listitem><para><constant>homeDrive</constant>: specifies the drive letter to which to map the
+ UNC path specified by homeDirectory. The drive letter must be specified in the form "X:"
+ where X is the letter of the drive to map. Refer to the "logon drive" parameter in the
+ smb.conf(5) man page for more information.</para></listitem>
+
+ <listitem><para><constant>scriptPath</constant>: The scriptPath property specifies the path of
+ the user's logon script, .CMD, .EXE, or .BAT file. The string can be null. The path
+ is relative to the netlogon share. Refer to the "logon script" parameter in the
+ smb.conf(5) man page for more information.</para></listitem>
+
+ <listitem><para><constant>profilePath</constant>: specifies a path to the user's profile.
+ This value can be a null string, a local absolute path, or a UNC path. Refer to the
+ "logon path" parameter in the smb.conf(5) man page for more information.</para></listitem>
+
+ <listitem><para><constant>smbHome</constant>: The homeDirectory property specifies the path of
+ the home directory for the user. The string can be null. If homeDrive is set and specifies
+ a drive letter, homeDirectory should be a UNC path. The path must be a network
+ UNC path of the form \\server\share\directory. This value can be a null string.
+ Refer to the "logon home" parameter in the smb.conf(5) man page for more information.
+ </para></listitem>
+
+ <listitem><para><constant>userWorkstation</constant>: character string value currently unused.
+ </para></listitem>
+
+ <listitem><para><constant>rid</constant>: the integer representation of the user's relative identifier
+ (RID).</para></listitem>
+
+ <listitem><para><constant>primaryGroupID</constant>: the relative identifier (RID) of the primary group
+ of the user.</para></listitem>
+
+</itemizedlist>
+
+<para>
+The majority of these parameters are only used when Samba is acting as a PDC of
+a domain (refer to the <ulink url="Samba-PDC-HOWTO.html">Samba-PDC-HOWTO</ulink> for details on
+how to configure Samba as a Primary Domain Controller). The following four attributes
+are only stored with the sambaAccount entry if the values are non-default values:
+</para>
+
+<itemizedlist>
+ <listitem><para>smbHome</para></listitem>
+ <listitem><para>scriptPath</para></listitem>
+ <listitem><para>logonPath</para></listitem>
+ <listitem><para>homeDrive</para></listitem>
+</itemizedlist>
+
+<para>
+These attributes are only stored with the sambaAccount entry if
+the values are non-default values. For example, assume TASHTEGO has now been
+configured as a PDC and that <command>logon home = \\%L\%u</command> was defined in
+its <filename>smb.conf</filename> file. When a user named "becky" logons to the domain,
+the <parameter>logon home</parameter> string is expanded to \\TASHTEGO\becky.
+If the smbHome attribute exists in the entry "uid=becky,ou=people,dc=samba,dc=org",
+this value is used. However, if this attribute does not exist, then the value
+of the <parameter>logon home</parameter> parameter is used in its place. Samba
+will only write the attribute value to the directory entry is the value is
+something other than the default (e.g. \\MOBY\becky).
+</para>
+
+
+</sect1>
+
+
+
+<sect1>
+<title>Example LDIF Entries for a sambaAccount</title>
+
+
+<para>
+The following is a working LDIF with the inclusion of the posixAccount objectclass:
+</para>
+
+<para><programlisting>
+dn: uid=guest2, ou=people,dc=plainjoe,dc=org
+ntPassword: 878D8014606CDA29677A44EFA1353FC7
+pwdMustChange: 2147483647
+primaryGroupID: 1201
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+pwdLastSet: 1010179124
+logonTime: 0
+objectClass: sambaAccount
+uid: guest2
+kickoffTime: 2147483647
+acctFlags: [UX ]
+logoffTime: 2147483647
+rid: 19006
+pwdCanChange: 0
+</programlisting></para>
+
+<para>
+The following is an LDIF entry for using both the sambaAccount and
+posixAccount objectclasses:
+</para>
+
+<para><programlisting>
+dn: uid=gcarter, ou=people,dc=plainjoe,dc=org
+logonTime: 0
+displayName: Gerald Carter
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+primaryGroupID: 1201
+objectClass: posixAccount
+objectClass: sambaAccount
+acctFlags: [UX ]
+userPassword: {crypt}BpM2ej8Rkzogo
+uid: gcarter
+uidNumber: 9000
+cn: Gerald Carter
+loginShell: /bin/bash
+logoffTime: 2147483647
+gidNumber: 100
+kickoffTime: 2147483647
+pwdLastSet: 1010179230
+rid: 19000
+homeDirectory: /home/tashtego/gcarter
+pwdCanChange: 0
+pwdMustChange: 2147483647
+ntPassword: 878D8014606CDA29677A44EFA1353FC7
+</programlisting></para>
+
+
+</sect1>
+
+
+
+<sect1>
+<title>Comments</title>
+
+
+<para>
+Please mail all comments regarding this HOWTO to <ulink
+url="mailto:jerry@samba.org">jerry@samba.org</ulink>. This documents was
+last updated to reflect the Samba 2.2.5 release.
+
+</para>
+
+
+</sect1>
+
+
+</chapter>
diff --git a/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml b/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml
new file mode 100755
index 00000000000..475b66598c2
--- /dev/null
+++ b/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml
@@ -0,0 +1,1828 @@
+<chapter id="samba-pdc">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Gerald (Jerry)</firstname><surname>Carter</surname>
+ <affiliation>
+ <orgname>VA Linux Systems/Samba Team</orgname>
+ <address><email>jerry@samba.org</email></address>
+ </affiliation>
+ <firstname>David</firstname><surname>Bannon</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address><email>dbannon@samba.org</email></address>
+ </affiliation>
+
+ </author>
+ <pubdate> (26 Apr 2001) </pubdate>
+</chapterinfo>
+
+<title>
+How to Configure Samba 2.2 as a Primary Domain Controller
+</title>
+
+
+<!-- **********************************************************
+
+ Prerequisite Reading
+
+*************************************************************** -->
+<sect1>
+<title>Prerequisite Reading</title>
+
+<para>
+Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring basic files services
+in smb.conf and how to enable and administer password
+encryption in Samba. Theses two topics are covered in the
+<ulink url="smb.conf.5.html"><filename>smb.conf(5)</filename></ulink>
+manpage and the <ulink url="ENCRYPTION.html">Encryption chapter</ulink>
+of this HOWTO Collection.
+</para>
+
+
+</sect1>
+
+
+
+<!-- **********************************************************
+
+ Background Information
+
+*************************************************************** -->
+<sect1>
+<title>
+Background
+</title>
+
+<note>
+<para>
+<emphasis>Author's Note:</emphasis> This document is a combination
+of David Bannon's "Samba 2.2 PDC HOWTO" and "Samba NT Domain FAQ".
+Both documents are superseded by this one.
+</para>
+</note>
+
+<para>
+Versions of Samba prior to release 2.2 had marginal capabilities to act
+as a Windows NT 4.0 Primary Domain Controller
+<indexterm><primary>Primary Domain Controller</primary></indexterm>
+(PDC). With Samba 2.2.0, we are proud to announce official support for
+Windows NT 4.0-style domain logons from Windows NT 4.0 and Windows
+2000 clients. This article outlines the steps
+necessary for configuring Samba as a PDC. It is necessary to have a
+working Samba server prior to implementing the PDC functionality. If
+you have not followed the steps outlined in <ulink
+url="UNIX_INSTALL.html"> UNIX_INSTALL.html</ulink>, please make sure
+that your server is configured correctly before proceeding. Another
+good resource in the <ulink url="smb.conf.5.html">smb.conf(5) man
+page</ulink>. The following functionality should work in 2.2:
+</para>
+
+<itemizedlist>
+ <listitem><para>
+ domain logons for Windows NT 4.0/2000 clients.
+ </para></listitem>
+
+ <listitem><para>
+ placing a Windows 9x client in user level security
+ </para></listitem>
+
+ <listitem><para>
+ retrieving a list of users and groups from a Samba PDC to
+ Windows 9x/NT/2000 clients
+ </para></listitem>
+
+ <listitem><para>
+ roving (roaming) user profiles
+ </para></listitem>
+
+ <listitem><para>
+ Windows NT 4.0-style system policies
+ </para></listitem>
+</itemizedlist>
+
+
+<para>
+The following pieces of functionality are not included in the 2.2 release:
+</para>
+
+<itemizedlist>
+ <listitem><para>
+ Windows NT 4 domain trusts
+ </para></listitem>
+
+ <listitem><para>
+ SAM replication with Windows NT 4.0 Domain Controllers
+ (i.e. a Samba PDC and a Windows NT BDC or vice versa)
+ </para></listitem>
+
+ <listitem><para>
+ Adding users via the User Manager for Domains
+ </para></listitem>
+
+ <listitem><para>
+ Acting as a Windows 2000 Domain Controller (i.e. Kerberos and
+ Active Directory)
+ </para></listitem>
+</itemizedlist>
+
+<para>
+Please note that Windows 9x clients are not true members of a domain
+for reasons outlined in this article. Therefore the protocol for
+support Windows 9x-style domain logons is completely different
+from NT4 domain logons and has been officially supported for some
+time.
+</para>
+
+
+<para>
+Implementing a Samba PDC can basically be divided into 2 broad
+steps.
+</para>
+
+<orderedlist numeration="Arabic">
+ <listitem><para>
+ Configuring the Samba PDC
+ </para></listitem>
+
+ <listitem><para>
+ Creating machine trust accounts and joining clients
+ to the domain
+ </para></listitem>
+</orderedlist>
+
+<para>
+There are other minor details such as user profiles, system
+policies, etc... However, these are not necessarily specific
+to a Samba PDC as much as they are related to Windows NT networking
+concepts. They will be mentioned only briefly here.
+</para>
+
+</sect1>
+
+
+<!-- **********************************************************
+
+ Configuring the Samba PDC
+
+*************************************************************** -->
+
+<sect1>
+<title>Configuring the Samba Domain Controller</title>
+
+<para>
+The first step in creating a working Samba PDC is to
+understand the parameters necessary in smb.conf. I will not
+attempt to re-explain the parameters here as they are more that
+adequately covered in <ulink url="smb.conf.5.html"> the smb.conf
+man page</ulink>. For convenience, the parameters have been
+linked with the actual smb.conf description.
+</para>
+
+<para>
+Here is an example <filename>smb.conf</filename> for acting as a PDC:
+</para>
+
+<para><programlisting>
+[global]
+ ; Basic server settings
+ <ulink url="smb.conf.5.html#NETBIOSNAME">netbios name</ulink> = <replaceable>POGO</replaceable>
+ <ulink url="smb.conf.5.html#WORKGROUP">workgroup</ulink> = <replaceable>NARNIA</replaceable>
+
+ ; we should act as the domain and local master browser
+ <ulink url="smb.conf.5.html#OSLEVEL">os level</ulink> = 64
+ <ulink url="smb.conf.5.html#PERFERREDMASTER">preferred master</ulink> = yes
+ <ulink url="smb.conf.5.html#DOMAINMASTER">domain master</ulink> = yes
+ <ulink url="smb.conf.5.html#LOCALMASTER">local master</ulink> = yes
+
+ ; security settings (must user security = user)
+ <ulink url="smb.conf.5.html#SECURITYEQUALSUSER">security</ulink> = user
+
+ ; encrypted passwords are a requirement for a PDC
+ <ulink url="smb.conf.5.html#ENCRYPTPASSWORDS">encrypt passwords</ulink> = yes
+
+ ; support domain logons
+ <ulink url="smb.conf.5.html#DOMAINLOGONS">domain logons</ulink> = yes
+
+ ; where to store user profiles?
+ <ulink url="smb.conf.5.html#LOGONPATH">logon path</ulink> = \\%N\profiles\%u
+
+ ; where is a user's home directory and where should it
+ ; be mounted at?
+ <ulink url="smb.conf.5.html#LOGONDRIVE">logon drive</ulink> = H:
+ <ulink url="smb.conf.5.html#LOGONHOME">logon home</ulink> = \\homeserver\%u
+
+ ; specify a generic logon script for all users
+ ; this is a relative **DOS** path to the [netlogon] share
+ <ulink url="smb.conf.5.html#LOGONSCRIPT">logon script</ulink> = logon.cmd
+
+; necessary share for domain controller
+[netlogon]
+ <ulink url="smb.conf.5.html#PATH">path</ulink> = /usr/local/samba/lib/netlogon
+ <ulink url="smb.conf.5.html#READONLY">read only</ulink> = yes
+ <ulink url="smb.conf.5.html#WRITELIST">write list</ulink> = <replaceable>ntadmin</replaceable>
+
+; share for storing user profiles
+[profiles]
+ <ulink url="smb.conf.5.html#PATH">path</ulink> = /export/smb/ntprofile
+ <ulink url="smb.conf.5.html#READONLY">read only</ulink> = no
+ <ulink url="smb.conf.5.html#CREATEMASK">create mask</ulink> = 0600
+ <ulink url="smb.conf.5.html#DIRECTORYMASK">directory mask</ulink> = 0700
+</programlisting></para>
+
+<para>
+There are a couple of points to emphasize in the above configuration.
+</para>
+
+<itemizedlist>
+ <listitem><para>
+ Encrypted passwords must be enabled. For more details on how
+ to do this, refer to <ulink url="ENCRYPTION.html">ENCRYPTION.html</ulink>.
+ </para></listitem>
+
+ <listitem><para>
+ The server must support domain logons and a
+ <filename>[netlogon]</filename> share
+ </para></listitem>
+
+ <listitem><para>
+ The server must be the domain master browser in order for Windows
+ client to locate the server as a DC. Please refer to the various
+ Network Browsing documentation included with this distribution for
+ details.
+ </para></listitem>
+</itemizedlist>
+
+<para>
+As Samba 2.2 does not offer a complete implementation of group mapping
+between Windows NT groups and Unix groups (this is really quite
+complicated to explain in a short space), you should refer to the
+<ulink url="smb.conf.5.html#DOMAINADMINGROUP">domain admin
+group</ulink> smb.conf parameter for information of creating "Domain
+Admins" style accounts.
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>Creating Machine Trust Accounts and Joining Clients to the
+Domain</title>
+
+<para>
+A machine trust account is a Samba account that is used to
+authenticate a client machine (rather than a user) to the Samba
+server. In Windows terminology, this is known as a "Computer
+Account."</para>
+
+<para>
+The password of a machine trust account acts as the shared secret for
+secure communication with the Domain Controller. This is a security
+feature to prevent an unauthorized machine with the same NetBIOS name
+from joining the domain and gaining access to domain user/group
+accounts. Windows NT and 2000 clients use machine trust accounts, but
+Windows 9x clients do not. Hence, a Windows 9x client is never a true
+member of a domain because it does not possess a machine trust
+account, and thus has no shared secret with the domain controller.
+</para>
+
+<para>A Windows PDC stores each machine trust account in the Windows
+Registry. A Samba PDC, however, stores each machine trust account
+in two parts, as follows:
+
+<itemizedlist>
+ <listitem><para>A Samba account, stored in the same location as user
+ LanMan and NT password hashes (currently
+ <filename>smbpasswd</filename>). The Samba account
+ possesses and uses only the NT password hash.</para></listitem>
+
+ <listitem><para>A corresponding Unix account, typically stored in
+ <filename>/etc/passwd</filename>. (Future releases will alleviate the need to
+ create <filename>/etc/passwd</filename> entries.) </para></listitem>
+</itemizedlist>
+</para>
+
+<para>
+There are two ways to create machine trust accounts:
+</para>
+
+<itemizedlist>
+ <listitem><para> Manual creation. Both the Samba and corresponding
+ Unix account are created by hand.</para></listitem>
+
+ <listitem><para> "On-the-fly" creation. The Samba machine trust
+ account is automatically created by Samba at the time the client
+ is joined to the domain. (For security, this is the
+ recommended method.) The corresponding Unix account may be
+ created automatically or manually. </para>
+ </listitem>
+
+</itemizedlist>
+
+<sect2>
+<title>Manual Creation of Machine Trust Accounts</title>
+
+<para>
+The first step in manually creating a machine trust account is to
+manually create the corresponding Unix account in
+<filename>/etc/passwd</filename>. This can be done using
+<command>vipw</command> or other 'add user' command that is normally
+used to create new Unix accounts. The following is an example for a
+Linux based Samba server:
+</para>
+
+<para>
+ <prompt>root# </prompt><command>/usr/sbin/useradd -g 100 -d /dev/null -c <replaceable>"machine
+nickname"</replaceable> -s /bin/false <replaceable>machine_name</replaceable>$ </command>
+</para>
+<para>
+<prompt>root# </prompt><command>passwd -l <replaceable>machine_name</replaceable>$</command>
+</para>
+
+<para>
+The <filename>/etc/passwd</filename> entry will list the machine name
+with a "$" appended, won't have a password, will have a null shell and no
+home directory. For example a machine named 'doppy' would have an
+<filename>/etc/passwd</filename> entry like this:
+</para>
+
+<para><programlisting>
+doppy$:x:505:501:<replaceable>machine_nickname</replaceable>:/dev/null:/bin/false
+</programlisting></para>
+
+<para>
+Above, <replaceable>machine_nickname</replaceable> can be any
+descriptive name for the client, i.e., BasementComputer.
+<replaceable>machine_name</replaceable> absolutely must be the NetBIOS
+name of the client to be joined to the domain. The "$" must be
+appended to the NetBIOS name of the client or Samba will not recognize
+this as a machine trust account.
+</para>
+
+
+<para>
+Now that the corresponding Unix account has been created, the next step is to create
+the Samba account for the client containing the well-known initial
+machine trust account password. This can be done using the <ulink
+url="smbpasswd.8.html"><command>smbpasswd(8)</command></ulink> command
+as shown here:
+</para>
+
+<para>
+<prompt>root# </prompt><command>smbpasswd -a -m <replaceable>machine_name</replaceable></command>
+</para>
+
+<para>
+where <replaceable>machine_name</replaceable> is the machine's NetBIOS
+name. The RID of the new machine account is generated from the UID of
+the corresponding Unix account.
+</para>
+
+<warning>
+ <title>Join the client to the domain immediately</title>
+
+ <para>
+ Manually creating a machine trust account using this method is the
+ equivalent of creating a machine trust account on a Windows NT PDC using
+ the "Server Manager". From the time at which the account is created
+ to the time which the client joins the domain and changes the password,
+ your domain is vulnerable to an intruder joining your domain using a
+ a machine with the same NetBIOS name. A PDC inherently trusts
+ members of the domain and will serve out a large degree of user
+ information to such clients. You have been warned!
+ </para>
+</warning>
+</sect2>
+
+
+<sect2>
+<title>"On-the-Fly" Creation of Machine Trust Accounts</title>
+
+<para>
+The second (and recommended) way of creating machine trust accounts is
+simply to allow the Samba server to create them as needed when the client
+is joined to the domain. </para>
+
+<para>Since each Samba machine trust account requires a corresponding
+Unix account, a method for automatically creating the
+Unix account is usually supplied; this requires configuration of the
+<ulink url="smb.conf.5.html#ADDUSERSCRIPT">add user script</ulink>
+option in <filename>smb.conf</filename>. This
+method is not required, however; corresponding Unix accounts may also
+be created manually.
+</para>
+
+
+<para>Below is an example for a RedHat 6.2 Linux system.
+</para>
+
+<para><programlisting>
+[global]
+ # <...remainder of parameters...>
+ add user script = /usr/sbin/useradd -d /dev/null -g 100 -s /bin/false -M %u
+</programlisting></para>
+
+</sect2>
+
+
+<sect2><title>Joining the Client to the Domain</title>
+
+<para>
+The procedure for joining a client to the domain varies with the
+version of Windows.
+</para>
+
+<itemizedlist>
+<listitem><para><emphasis>Windows 2000</emphasis></para>
+
+ <para> When the user elects to join the client to a domain, Windows prompts for
+ an account and password that is privileged to join the domain. A
+ Samba administrative account (i.e., a Samba account that has root
+ privileges on the Samba server) must be entered here; the
+ operation will fail if an ordinary user account is given.
+ The password for this account should be
+ set to a different password than the associated
+ <filename>/etc/passwd</filename> entry, for security
+ reasons. </para>
+
+ <para>The session key of the Samba administrative account acts as an
+ encryption key for setting the password of the machine trust
+ account. The machine trust account will be created on-the-fly, or
+ updated if it already exists.</para>
+</listitem>
+
+<listitem><para><emphasis>Windows NT</emphasis></para>
+
+ <para> If the machine trust account was created manually, on the
+ Identification Changes menu enter the domain name, but do not
+ check the box "Create a Computer Account in the Domain." In this case,
+ the existing machine trust account is used to join the machine to
+ the domain.</para>
+
+ <para> If the machine trust account is to be created
+ on-the-fly, on the Identification Changes menu enter the domain
+ name, and check the box "Create a Computer Account in the Domain." In
+ this case, joining the domain proceeds as above for Windows 2000
+ (i.e., you must supply a Samba administrative account when
+ prompted).</para>
+</listitem>
+</itemizedlist>
+
+</sect2>
+</sect1>
+<!-- **********************************************************
+
+ Common Problems
+
+*************************************************************** -->
+
+<sect1>
+<title>Common Problems and Errors</title>
+
+<para>
+</para>
+<itemizedlist>
+<listitem>
+ <para>
+ <emphasis>I cannot include a '$' in a machine name.</emphasis>
+ </para>
+
+ <para>
+ A 'machine name' in (typically) <filename>/etc/passwd</>
+ of the machine name with a '$' appended. FreeBSD (and other BSD
+ systems?) won't create a user with a '$' in their name.
+ </para>
+
+ <para>
+ The problem is only in the program used to make the entry, once
+ made, it works perfectly. So create a user without the '$' and
+ use <command>vipw</> to edit the entry, adding the '$'. Or create
+ the whole entry with vipw if you like, make sure you use a
+ unique User ID !
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>I get told "You already have a connection to the Domain...."
+ or "Cannot join domain, the credentials supplied conflict with an
+ existing set.." when creating a machine trust account.</emphasis>
+ </para>
+
+ <para>
+ This happens if you try to create a machine trust account from the
+ machine itself and already have a connection (e.g. mapped drive)
+ to a share (or IPC$) on the Samba PDC. The following command
+ will remove all network drive connections:
+ </para>
+
+ <para>
+ <prompt>C:\WINNT\></prompt> <command>net use * /d</command>
+ </para>
+
+ <para>
+ Further, if the machine is a already a 'member of a workgroup' that
+ is the same name as the domain you are joining (bad idea) you will
+ get this message. Change the workgroup name to something else, it
+ does not matter what, reboot, and try again.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>The system can not log you on (C000019B)....</emphasis>
+ </para>
+
+ <para>I joined the domain successfully but after upgrading
+ to a newer version of the Samba code I get the message, "The system
+ can not log you on (C000019B), Please try a gain or consult your
+ system administrator" when attempting to logon.
+ </para>
+
+ <para>
+ This occurs when the domain SID stored in
+ <filename>private/WORKGROUP.SID</filename> is
+ changed. For example, you remove the file and <command>smbd</command> automatically
+ creates a new one. Or you are swapping back and forth between
+ versions 2.0.7, TNG and the HEAD branch code (not recommended). The
+ only way to correct the problem is to restore the original domain
+ SID or remove the domain client from the domain and rejoin.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>The machine trust account for this computer either does not
+ exist or is not accessible.</emphasis>
+ </para>
+
+ <para>
+ When I try to join the domain I get the message "The machine account
+ for this computer either does not exist or is not accessible". What's
+ wrong?
+ </para>
+
+ <para>
+ This problem is caused by the PDC not having a suitable machine trust account.
+ If you are using the <parameter>add user script</parameter> method to create
+ accounts then this would indicate that it has not worked. Ensure the domain
+ admin user system is working.
+ </para>
+
+ <para>
+ Alternatively if you are creating account entries manually then they
+ have not been created correctly. Make sure that you have the entry
+ correct for the machine trust account in smbpasswd file on the Samba PDC.
+ If you added the account using an editor rather than using the smbpasswd
+ utility, make sure that the account name is the machine NetBIOS name
+ with a '$' appended to it ( i.e. computer_name$ ). There must be an entry
+ in both /etc/passwd and the smbpasswd file. Some people have reported
+ that inconsistent subnet masks between the Samba server and the NT
+ client have caused this problem. Make sure that these are consistent
+ for both client and server.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>When I attempt to login to a Samba Domain from a NT4/W2K workstation,
+ I get a message about my account being disabled.</emphasis>
+ </para>
+
+ <para>
+ This problem is caused by a PAM related bug in Samba 2.2.0. This bug is
+ fixed in 2.2.1. Other symptoms could be unaccessible shares on
+ NT/W2K member servers in the domain or the following error in your smbd.log:
+ passdb/pampass.c:pam_account(268) PAM: UNKNOWN ERROR for User: %user%
+ </para>
+
+ <para>
+ At first be ensure to enable the useraccounts with <command>smbpasswd -e
+ %user%</command>, this is normally done, when you create an account.
+ </para>
+
+ <para>
+ In order to work around this problem in 2.2.0, configure the
+ <parameter>account</parameter> control flag in
+ <filename>/etc/pam.d/samba</filename> file as follows:
+ </para>
+
+ <para><programlisting>
+ account required pam_permit.so
+ </programlisting></para>
+
+ <para>
+ If you want to remain backward compatibility to samba 2.0.x use
+ <filename>pam_permit.so</filename>, it's also possible to use
+ <filename>pam_pwdb.so</filename>. There are some bugs if you try to
+ use <filename>pam_unix.so</filename>, if you need this, be ensure to use
+ the most recent version of this file.
+ </para>
+</listitem>
+</itemizedlist>
+
+</sect1>
+
+
+
+<!-- **********************************************************
+
+ Policies and Profiles
+
+*************************************************************** -->
+
+<sect1>
+<title>
+System Policies and Profiles
+</title>
+
+<para>
+Much of the information necessary to implement System Policies and
+Roving User Profiles in a Samba domain is the same as that for
+implementing these same items in a Windows NT 4.0 domain.
+You should read the white paper <ulink url="http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp">Implementing
+Profiles and Policies in Windows NT 4.0</ulink> available from Microsoft.
+</para>
+
+<para>
+Here are some additional details:
+</para>
+
+<itemizedlist>
+
+<listitem>
+ <para>
+ <emphasis>What about Windows NT Policy Editor?</emphasis>
+ </para>
+
+ <para>
+ To create or edit <filename>ntconfig.pol</filename> you must use
+ the NT Server Policy Editor, <command>poledit.exe</command> which
+ is included with NT Server but <emphasis>not NT Workstation</emphasis>.
+ There is a Policy Editor on a NTws
+ but it is not suitable for creating <emphasis>Domain Policies</emphasis>.
+ Further, although the Windows 95
+ Policy Editor can be installed on an NT Workstation/Server, it will not
+ work with NT policies because the registry key that are set by the policy templates.
+ However, the files from the NT Server will run happily enough on an NTws.
+ You need <filename>poledit.exe, common.adm</> and <filename>winnt.adm</>. It is convenient
+ to put the two *.adm files in <filename>c:\winnt\inf</> which is where
+ the binary will look for them unless told otherwise. Note also that that
+ directory is 'hidden'.
+ </para>
+
+ <para>
+ The Windows NT policy editor is also included with the Service Pack 3 (and
+ later) for Windows NT 4.0. Extract the files using <command>servicepackname /x</command>,
+ i.e. that's <command>Nt4sp6ai.exe /x</command> for service pack 6a. The policy editor,
+ <command>poledit.exe</command> and the associated template files (*.adm) should
+ be extracted as well. It is also possible to downloaded the policy template
+ files for Office97 and get a copy of the policy editor. Another possible
+ location is with the Zero Administration Kit available for download from Microsoft.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ <emphasis>Can Win95 do Policies?</emphasis>
+ </para>
+
+ <para>
+ Install the group policy handler for Win9x to pick up group
+ policies. Look on the Win98 CD in <filename>\tools\reskit\netadmin\poledit</filename>.
+ Install group policies on a Win9x client by double-clicking
+ <filename>grouppol.inf</filename>. Log off and on again a couple of
+ times and see if Win98 picks up group policies. Unfortunately this needs
+ to be done on every Win9x machine that uses group policies....
+ </para>
+
+ <para>
+ If group policies don't work one reports suggests getting the updated
+ (read: working) grouppol.dll for Windows 9x. The group list is grabbed
+ from /etc/group.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ <emphasis>How do I get 'User Manager' and 'Server Manager'</emphasis>
+ </para>
+
+ <para>
+ Since I don't need to buy an NT Server CD now, how do I get
+ the 'User Manager for Domains', the 'Server Manager'?
+ </para>
+
+ <para>
+ Microsoft distributes a version of these tools called nexus for
+ installation on Windows 95 systems. The tools set includes
+ </para>
+
+ <itemizedlist>
+ <listitem><para>Server Manager</para></listitem>
+
+ <listitem><para>User Manager for Domains</para></listitem>
+
+ <listitem><para>Event Viewer</para></listitem>
+ </itemizedlist>
+
+ <para>
+ Click here to download the archived file <ulink
+ url="ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE">ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE</ulink>
+ </para>
+
+ <para>
+ The Windows NT 4.0 version of the 'User Manager for
+ Domains' and 'Server Manager' are available from Microsoft via ftp
+ from <ulink url="ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE">ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE</ulink>
+ </para>
+</listitem>
+</itemizedlist>
+
+</sect1>
+
+
+
+<!-- **********************************************************
+
+ Getting Help
+
+*************************************************************** -->
+
+
+<sect1>
+<title>What other help can I get? </title>
+
+<para>
+There are many sources of information available in the form
+of mailing lists, RFC's and documentation. The docs that come
+with the samba distribution contain very good explanations of
+general SMB topics such as browsing.</para>
+
+<itemizedlist>
+<listitem>
+ <para>
+ <emphasis>What are some diagnostics tools I can use to debug the domain logon
+ process and where can I find them?</emphasis>
+ </para>
+
+ <para>
+ One of the best diagnostic tools for debugging problems is Samba itself.
+ You can use the -d option for both smbd and nmbd to specify what
+ 'debug level' at which to run. See the man pages on smbd, nmbd and
+ smb.conf for more information on debugging options. The debug
+ level can range from 1 (the default) to 10 (100 for debugging passwords).
+ </para>
+
+ <para>
+ Another helpful method of debugging is to compile samba using the
+ <command>gcc -g </command> flag. This will include debug
+ information in the binaries and allow you to attach gdb to the
+ running smbd / nmbd process. In order to attach gdb to an smbd
+ process for an NT workstation, first get the workstation to make the
+ connection. Pressing ctrl-alt-delete and going down to the domain box
+ is sufficient (at least, on the first time you join the domain) to
+ generate a 'LsaEnumTrustedDomains'. Thereafter, the workstation
+ maintains an open connection, and therefore there will be an smbd
+ process running (assuming that you haven't set a really short smbd
+ idle timeout) So, in between pressing ctrl alt delete, and actually
+ typing in your password, you can gdb attach and continue.
+ </para>
+
+ <para>
+ Some useful samba commands worth investigating:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>testparam | more</para></listitem>
+ <listitem><para>smbclient -L //{netbios name of server}</para></listitem>
+ </itemizedlist>
+
+ <para>
+ An SMB enabled version of tcpdump is available from
+ <ulink url="http://www.tcpdump.org/">http://www.tcpdup.org/</ulink>.
+ Ethereal, another good packet sniffer for Unix and Win32
+ hosts, can be downloaded from <ulink
+ url="http://www.ethereal.com/">http://www.ethereal.com</ulink>.
+ </para>
+
+ <para>
+ For tracing things on the Microsoft Windows NT, Network Monitor
+ (aka. netmon) is available on the Microsoft Developer Network CD's,
+ the Windows NT Server install CD and the SMS CD's. The version of
+ netmon that ships with SMS allows for dumping packets between any two
+ computers (i.e. placing the network interface in promiscuous mode).
+ The version on the NT Server install CD will only allow monitoring
+ of network traffic directed to the local NT box and broadcasts on the
+ local subnet. Be aware that Ethereal can read and write netmon
+ formatted files.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ <emphasis>How do I install 'Network Monitor' on an NT Workstation
+ or a Windows 9x box?</emphasis>
+ </para>
+
+ <para>
+ Installing netmon on an NT workstation requires a couple
+ of steps. The following are for installing Netmon V4.00.349, which comes
+ with Microsoft Windows NT Server 4.0, on Microsoft Windows NT
+ Workstation 4.0. The process should be similar for other version of
+ Windows NT / Netmon. You will need both the Microsoft Windows
+ NT Server 4.0 Install CD and the Workstation 4.0 Install CD.
+ </para>
+
+ <para>
+ Initially you will need to install 'Network Monitor Tools and Agent'
+ on the NT Server. To do this
+ </para>
+
+ <itemizedlist>
+ <listitem><para>Goto Start - Settings - Control Panel -
+ Network - Services - Add </para></listitem>
+
+ <listitem><para>Select the 'Network Monitor Tools and Agent' and
+ click on 'OK'.</para></listitem>
+
+ <listitem><para>Click 'OK' on the Network Control Panel.
+ </para></listitem>
+
+ <listitem><para>Insert the Windows NT Server 4.0 install CD
+ when prompted.</para></listitem>
+ </itemizedlist>
+
+ <para>
+ At this point the Netmon files should exist in
+ <filename>%SYSTEMROOT%\System32\netmon\*.*</filename>.
+ Two subdirectories exist as well, <filename>parsers\</filename>
+ which contains the necessary DLL's for parsing the netmon packet
+ dump, and <filename>captures\</filename>.
+ </para>
+
+ <para>
+ In order to install the Netmon tools on an NT Workstation, you will
+ first need to install the 'Network Monitor Agent' from the Workstation
+ install CD.
+ </para>
+
+ <itemizedlist>
+ <listitem><para>Goto Start - Settings - Control Panel -
+ Network - Services - Add</para></listitem>
+
+ <listitem><para>Select the 'Network Monitor Agent' and click
+ on 'OK'.</para></listitem>
+
+ <listitem><para>Click 'OK' on the Network Control Panel.
+ </para></listitem>
+
+ <listitem><para>Insert the Windows NT Workstation 4.0 install
+ CD when prompted.</para></listitem>
+ </itemizedlist>
+
+
+ <para>
+ Now copy the files from the NT Server in %SYSTEMROOT%\System32\netmon\*.*
+ to %SYSTEMROOT%\System32\netmon\*.* on the Workstation and set
+ permissions as you deem appropriate for your site. You will need
+ administrative rights on the NT box to run netmon.
+ </para>
+
+ <para>
+ To install Netmon on a Windows 9x box install the network monitor agent
+ from the Windows 9x CD (\admin\nettools\netmon). There is a readme
+ file located with the netmon driver files on the CD if you need
+ information on how to do this. Copy the files from a working
+ Netmon installation.
+ </para>
+</listitem>
+
+
+
+
+<listitem>
+ <para>
+ The following is a list if helpful URLs and other links:
+ </para>
+
+ <itemizedlist>
+
+ <listitem><para>Home of Samba site <ulink url="http://samba.org">
+ http://samba.org</ulink>. We have a mirror near you !</para></listitem>
+
+ <listitem><para> The <emphasis>Development</emphasis> document
+ on the Samba mirrors might mention your problem. If so,
+ it might mean that the developers are working on it.</para></listitem>
+
+ <listitem><para>See how Scott Merrill simulates a BDC behavior at
+ <ulink url="http://www.skippy.net/linux/smb-howto.html">
+ http://www.skippy.net/linux/smb-howto.html</>. </para></listitem>
+
+ <listitem><para>Although 2.0.7 has almost had its day as a PDC, David Bannon will
+ keep the 2.0.7 PDC pages at <ulink url="http://bioserve.latrobe.edu.au/samba">
+ http://bioserve.latrobe.edu.au/samba</ulink> going for a while yet.</para></listitem>
+
+ <listitem><para>Misc links to CIFS information
+ <ulink url="http://samba.org/cifs/">http://samba.org/cifs/</ulink></para></listitem>
+
+ <listitem><para>NT Domains for Unix <ulink url="http://mailhost.cb1.com/~lkcl/ntdom/">
+ http://mailhost.cb1.com/~lkcl/ntdom/</ulink></para></listitem>
+
+ <listitem><para>FTP site for older SMB specs:
+ <ulink url="ftp://ftp.microsoft.com/developr/drg/CIFS/">
+ ftp://ftp.microsoft.com/developr/drg/CIFS/</ulink></para></listitem>
+
+ </itemizedlist>
+</listitem>
+</itemizedlist>
+
+
+<itemizedlist>
+<listitem>
+ <para>
+ <emphasis>How do I get help from the mailing lists?</emphasis>
+ </para>
+
+ <para>
+ There are a number of Samba related mailing lists. Go to <ulink
+ url="http://samba.org">http://samba.org</ulink>, click on your nearest mirror
+ and then click on <command>Support</> and then click on <command>
+ Samba related mailing lists</>.
+ </para>
+
+ <para>
+ For questions relating to Samba TNG go to
+ <ulink url="http://www.samba-tng.org/">http://www.samba-tng.org/</ulink>
+ It has been requested that you don't post questions about Samba-TNG to the
+ main stream Samba lists.</para>
+
+ <para>
+ If you post a message to one of the lists please observe the following guide lines :
+ </para>
+
+ <itemizedlist>
+
+ <listitem><para> Always remember that the developers are volunteers, they are
+ not paid and they never guarantee to produce a particular feature at
+ a particular time. Any time lines are 'best guess' and nothing more.
+ </para></listitem>
+
+ <listitem><para> Always mention what version of samba you are using and what
+ operating system its running under. You should probably list the
+ relevant sections of your smb.conf file, at least the options
+ in [global] that affect PDC support.</para></listitem>
+
+ <listitem><para>In addition to the version, if you obtained Samba via
+ CVS mention the date when you last checked it out.</para></listitem>
+
+ <listitem><para> Try and make your question clear and brief, lots of long,
+ convoluted questions get deleted before they are completely read !
+ Don't post html encoded messages (if you can select colour or font
+ size its html).</para></listitem>
+
+ <listitem><para> If you run one of those nifty 'I'm on holidays' things when
+ you are away, make sure its configured to not answer mailing lists.
+ </para></listitem>
+
+ <listitem><para> Don't cross post. Work out which is the best list to post to
+ and see what happens, i.e. don't post to both samba-ntdom and samba-technical.
+ Many people active on the lists subscribe to more
+ than one list and get annoyed to see the same message two or more times.
+ Often someone will see a message and thinking it would be better dealt
+ with on another, will forward it on for you.</para></listitem>
+
+ <listitem><para>You might include <emphasis>partial</emphasis>
+ log files written at a debug level set to as much as 20.
+ Please don't send the entire log but enough to give the context of the
+ error messages.</para></listitem>
+
+ <listitem><para>(Possibly) If you have a complete netmon trace ( from the opening of
+ the pipe to the error ) you can send the *.CAP file as well.</para></listitem>
+
+ <listitem><para>Please think carefully before attaching a document to an email.
+ Consider pasting the relevant parts into the body of the message. The samba
+ mailing lists go to a huge number of people, do they all need a copy of your
+ smb.conf in their attach directory?</para></listitem>
+
+ </itemizedlist>
+</listitem>
+
+
+<listitem>
+ <para>
+ <emphasis>How do I get off the mailing lists?</emphasis>
+ </para>
+
+ <para>To have your name removed from a samba mailing list, go to the
+ same place you went to to get on it. Go to <ulink
+ url="http://lists.samba.org/">http://lists.samba.org</ulink>,
+ click on your nearest mirror and then click on <command>Support</> and
+ then click on <command> Samba related mailing lists</>. Or perhaps see
+ <ulink url="http://lists.samba.org/mailman/roster/samba-ntdom">here</ulink>
+ </para>
+
+ <para>
+ Please don't post messages to the list asking to be removed, you will just
+ be referred to the above address (unless that process failed in some way...)
+ </para>
+</listitem>
+</itemizedlist>
+
+</sect1>
+
+
+<!-- **********************************************************
+
+ Windows 9x domain control
+
+*************************************************************** -->
+<sect1>
+<title>Domain Control for Windows 9x/ME</title>
+
+<note>
+<para>
+The following section contains much of the original
+DOMAIN.txt file previously included with Samba. Much of
+the material is based on what went into the book <emphasis>Special
+Edition, Using Samba</emphasis>, by Richard Sharpe.
+</para>
+</note>
+
+<para>
+A domain and a workgroup are exactly the same thing in terms of network
+browsing. The difference is that a distributable authentication
+database is associated with a domain, for secure login access to a
+network. Also, different access rights can be granted to users if they
+successfully authenticate against a domain logon server (NT server and
+other systems based on NT server support this, as does at least Samba TNG now).
+</para>
+
+<para>
+The SMB client logging on to a domain has an expectation that every other
+server in the domain should accept the same authentication information.
+Network browsing functionality of domains and workgroups is
+identical and is explained in BROWSING.txt. It should be noted, that browsing
+is totally orthogonal to logon support.
+</para>
+
+<para>
+Issues related to the single-logon network model are discussed in this
+section. Samba supports domain logons, network logon scripts, and user
+profiles for MS Windows for workgroups and MS Windows 9X/ME clients
+which will be the focus of this section.
+</para>
+
+
+<para>
+When an SMB client in a domain wishes to logon it broadcast requests for a
+logon server. The first one to reply gets the job, and validates its
+password using whatever mechanism the Samba administrator has installed.
+It is possible (but very stupid) to create a domain where the user
+database is not shared between servers, i.e. they are effectively workgroup
+servers advertising themselves as participating in a domain. This
+demonstrates how authentication is quite different from but closely
+involved with domains.
+</para>
+
+
+<para>
+Using these features you can make your clients verify their logon via
+the Samba server; make clients run a batch file when they logon to
+the network and download their preferences, desktop and start menu.
+</para>
+
+<para>
+Before launching into the configuration instructions, it is
+worthwhile lookingat how a Windows 9x/ME client performs a logon:
+</para>
+
+<orderedlist>
+<listitem>
+ <para>
+ The client broadcasts (to the IP broadcast address of the subnet it is in)
+ a NetLogon request. This is sent to the NetBIOS name DOMAIN<1c> at the
+ NetBIOS layer. The client chooses the first response it receives, which
+ contains the NetBIOS name of the logon server to use in the format of
+ \\SERVER.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then connects to that server, logs on (does an SMBsessetupX) and
+ then connects to the IPC$ share (using an SMBtconX).
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then does a NetWkstaUserLogon request, which retrieves the name
+ of the user's logon script.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then connects to the NetLogon share and searches for this
+ and if it is found and can be read, is retrieved and executed by the client.
+ After this, the client disconnects from the NetLogon share.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then sends a NetUserGetInfo request to the server, to retrieve
+ the user's home share, which is used to search for profiles. Since the
+ response to the NetUserGetInfo request does not contain much more
+ the user's home share, profiles for Win9X clients MUST reside in the user
+ home directory.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then connects to the user's home share and searches for the
+ user's profile. As it turns out, you can specify the user's home share as
+ a sharename and path. For example, \\server\fred\.profile.
+ If the profiles are found, they are implemented.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ The client then disconnects from the user's home share, and reconnects to
+ the NetLogon share and looks for CONFIG.POL, the policies file. If this is
+ found, it is read and implemented.
+ </para>
+</listitem>
+</orderedlist>
+
+
+<sect2>
+<title>Configuration Instructions: Network Logons</title>
+
+<para>
+The main difference between a PDC and a Windows 9x logon
+server configuration is that
+</para>
+
+<itemizedlist>
+
+<listitem><para>
+Password encryption is not required for a Windows 9x logon server.
+</para></listitem>
+
+<listitem><para>
+Windows 9x/ME clients do not possess machine trust accounts.
+</para></listitem>
+
+</itemizedlist>
+
+<para>
+Therefore, a Samba PDC will also act as a Windows 9x logon
+server.
+</para>
+
+
+<warning>
+<title>security mode and master browsers</title>
+
+<para>
+There are a few comments to make in order to tie up some
+loose ends. There has been much debate over the issue of whether
+or not it is ok to configure Samba as a Domain Controller in security
+modes other than <constant>USER</constant>. The only security mode
+which will not work due to technical reasons is <constant>SHARE</constant>
+mode security. <constant>DOMAIN</constant> and <constant>SERVER</constant>
+mode security is really just a variation on SMB user level security.
+</para>
+
+<para>
+Actually, this issue is also closely tied to the debate on whether
+or not Samba must be the domain master browser for its workgroup
+when operating as a DC. While it may technically be possible
+to configure a server as such (after all, browsing and domain logons
+are two distinctly different functions), it is not a good idea to
+so. You should remember that the DC must register the DOMAIN#1b NetBIOS
+name. This is the name used by Windows clients to locate the DC.
+Windows clients do not distinguish between the DC and the DMB.
+For this reason, it is very wise to configure the Samba DC as the DMB.
+</para>
+
+<para>
+Now back to the issue of configuring a Samba DC to use a mode other
+than "security = user". If a Samba host is configured to use
+another SMB server or DC in order to validate user connection
+requests, then it is a fact that some other machine on the network
+(the "password server") knows more about user than the Samba host.
+99% of the time, this other host is a domain controller. Now
+in order to operate in domain mode security, the "workgroup" parameter
+must be set to the name of the Windows NT domain (which already
+has a domain controller, right?)
+</para>
+
+<para>
+Therefore configuring a Samba box as a DC for a domain that
+already by definition has a PDC is asking for trouble.
+Therefore, you should always configure the Samba DC to be the DMB
+for its domain.
+</para>
+</warning>
+
+</sect2>
+
+
+<sect2>
+<title>Configuration Instructions: Setting up Roaming User Profiles</title>
+
+<warning>
+<para>
+<emphasis>NOTE!</emphasis> Roaming profiles support is different
+for Win9X and WinNT.
+</para>
+</warning>
+
+<para>
+Before discussing how to configure roaming profiles, it is useful to see how
+Win9X and WinNT clients implement these features.
+</para>
+
+<para>
+Win9X clients send a NetUserGetInfo request to the server to get the user's
+profiles location. However, the response does not have room for a separate
+profiles location field, only the user's home share. This means that Win9X
+profiles are restricted to being in the user's home directory.
+</para>
+
+
+<para>
+WinNT clients send a NetSAMLogon RPC request, which contains many fields,
+including a separate field for the location of the user's profiles.
+This means that support for profiles is different for Win9X and WinNT.
+</para>
+
+
+
+<sect3>
+<title>Windows NT Configuration</title>
+
+<para>
+To support WinNT clients, in the [global] section of smb.conf set the
+following (for example):
+</para>
+
+<para><programlisting>
+logon path = \\profileserver\profileshare\profilepath\%U\moreprofilepath
+</programlisting></para>
+
+<para>
+The default for this option is \\%N\%U\profile, namely
+\\sambaserver\username\profile. The \\N%\%U service is created
+automatically by the [homes] service.
+If you are using a samba server for the profiles, you _must_ make the
+share specified in the logon path browseable.
+</para>
+
+<note>
+<para>
+[lkcl 26aug96 - we have discovered a problem where Windows clients can
+maintain a connection to the [homes] share in between logins. The
+[homes] share must NOT therefore be used in a profile path.]
+</para>
+</note>
+
+</sect3>
+
+
+<sect3>
+<title>Windows 9X Configuration</title>
+
+<para>
+To support Win9X clients, you must use the "logon home" parameter. Samba has
+now been fixed so that "net use/home" now works as well, and it, too, relies
+on the "logon home" parameter.
+</para>
+
+<para>
+By using the logon home parameter, you are restricted to putting Win9X
+profiles in the user's home directory. But wait! There is a trick you
+can use. If you set the following in the [global] section of your
+smb.conf file:
+</para>
+
+<para><programlisting>
+logon home = \\%L\%U\.profiles
+</programlisting></para>
+
+<para>
+then your Win9X clients will dutifully put their clients in a subdirectory
+of your home directory called .profiles (thus making them hidden).
+</para>
+
+<para>
+Not only that, but 'net use/home' will also work, because of a feature in
+Win9X. It removes any directory stuff off the end of the home directory area
+and only uses the server and share portion. That is, it looks like you
+specified \\%L\%U for "logon home".
+</para>
+
+
+</sect3>
+
+
+<sect3>
+<title>Win9X and WinNT Configuration</title>
+
+<para>
+You can support profiles for both Win9X and WinNT clients by setting both the
+"logon home" and "logon path" parameters. For example:
+</para>
+
+<para><programlisting>
+logon home = \\%L\%U\.profiles
+logon path = \\%L\profiles\%U
+</programlisting></para>
+
+<note>
+<para>
+I have not checked what 'net use /home' does on NT when "logon home" is
+set as above.
+</para>
+</note>
+</sect3>
+
+
+
+<sect3>
+<title>Windows 9X Profile Setup</title>
+
+<para>
+When a user first logs in on Windows 9X, the file user.DAT is created,
+as are folders "Start Menu", "Desktop", "Programs" and "Nethood".
+These directories and their contents will be merged with the local
+versions stored in c:\windows\profiles\username on subsequent logins,
+taking the most recent from each. You will need to use the [global]
+options "preserve case = yes", "short preserve case = yes" and
+"case sensitive = no" in order to maintain capital letters in shortcuts
+in any of the profile folders.
+</para>
+
+
+<para>
+The user.DAT file contains all the user's preferences. If you wish to
+enforce a set of preferences, rename their user.DAT file to user.MAN,
+and deny them write access to this file.
+</para>
+
+<orderedlist>
+<listitem>
+ <para>
+ On the Windows 95 machine, go to Control Panel | Passwords and
+ select the User Profiles tab. Select the required level of
+ roaming preferences. Press OK, but do _not_ allow the computer
+ to reboot.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ On the Windows 95 machine, go to Control Panel | Network |
+ Client for Microsoft Networks | Preferences. Select 'Log on to
+ NT Domain'. Then, ensure that the Primary Logon is 'Client for
+ Microsoft Networks'. Press OK, and this time allow the computer
+ to reboot.
+ </para>
+</listitem>
+
+</orderedlist>
+
+<para>
+Under Windows 95, Profiles are downloaded from the Primary Logon.
+If you have the Primary Logon as 'Client for Novell Networks', then
+the profiles and logon script will be downloaded from your Novell
+Server. If you have the Primary Logon as 'Windows Logon', then the
+profiles will be loaded from the local machine - a bit against the
+concept of roaming profiles, if you ask me.
+</para>
+
+<para>
+You will now find that the Microsoft Networks Login box contains
+[user, password, domain] instead of just [user, password]. Type in
+the samba server's domain name (or any other domain known to exist,
+but bear in mind that the user will be authenticated against this
+domain and profiles downloaded from it, if that domain logon server
+supports it), user name and user's password.
+</para>
+
+<para>
+Once the user has been successfully validated, the Windows 95 machine
+will inform you that 'The user has not logged on before' and asks you
+if you wish to save the user's preferences? Select 'yes'.
+</para>
+
+<para>
+Once the Windows 95 client comes up with the desktop, you should be able
+to examine the contents of the directory specified in the "logon path"
+on the samba server and verify that the "Desktop", "Start Menu",
+"Programs" and "Nethood" folders have been created.
+</para>
+
+<para>
+These folders will be cached locally on the client, and updated when
+the user logs off (if you haven't made them read-only by then :-).
+You will find that if the user creates further folders or short-cuts,
+that the client will merge the profile contents downloaded with the
+contents of the profile directory already on the local client, taking
+the newest folders and short-cuts from each set.
+</para>
+
+<para>
+If you have made the folders / files read-only on the samba server,
+then you will get errors from the w95 machine on logon and logout, as
+it attempts to merge the local and the remote profile. Basically, if
+you have any errors reported by the w95 machine, check the Unix file
+permissions and ownership rights on the profile directory contents,
+on the samba server.
+</para>
+
+<para>
+If you have problems creating user profiles, you can reset the user's
+local desktop cache, as shown below. When this user then next logs in,
+they will be told that they are logging in "for the first time".
+</para>
+
+<orderedlist>
+<listitem>
+ <para>
+ instead of logging in under the [user, password, domain] dialog,
+ press escape.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ run the regedit.exe program, and look in:
+ </para>
+
+ <para>
+ HKEY_LOCAL_MACHINE\Windows\CurrentVersion\ProfileList
+ </para>
+
+ <para>
+ you will find an entry, for each user, of ProfilePath. Note the
+ contents of this key (likely to be c:\windows\profiles\username),
+ then delete the key ProfilePath for the required user.
+ </para>
+
+ <para>
+ [Exit the registry editor].
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>WARNING</emphasis> - before deleting the contents of the
+ directory listed in
+ the ProfilePath (this is likely to be c:\windows\profiles\username),
+ ask them if they have any important files stored on their desktop
+ or in their start menu. delete the contents of the directory
+ ProfilePath (making a backup if any of the files are needed).
+ </para>
+
+ <para>
+ This will have the effect of removing the local (read-only hidden
+ system file) user.DAT in their profile directory, as well as the
+ local "desktop", "nethood", "start menu" and "programs" folders.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ search for the user's .PWL password-caching file in the c:\windows
+ directory, and delete it.
+ </para>
+</listitem>
+
+
+<listitem>
+ <para>
+ log off the windows 95 client.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ check the contents of the profile path (see "logon path" described
+ above), and delete the user.DAT or user.MAN file for the user,
+ making a backup if required.
+ </para>
+</listitem>
+
+</orderedlist>
+
+<para>
+If all else fails, increase samba's debug log levels to between 3 and 10,
+and / or run a packet trace program such as tcpdump or netmon.exe, and
+look for any error reports.
+</para>
+
+<para>
+If you have access to an NT server, then first set up roaming profiles
+and / or netlogons on the NT server. Make a packet trace, or examine
+the example packet traces provided with NT server, and see what the
+differences are with the equivalent samba trace.
+</para>
+
+</sect3>
+
+
+<sect3>
+<title>Windows NT Workstation 4.0</title>
+
+<para>
+When a user first logs in to a Windows NT Workstation, the profile
+NTuser.DAT is created. The profile location can be now specified
+through the "logon path" parameter.
+</para>
+
+<note>
+<para>
+[lkcl 10aug97 - i tried setting the path to
+\\samba-server\homes\profile, and discovered that this fails because
+a background process maintains the connection to the [homes] share
+which does _not_ close down in between user logins. you have to
+have \\samba-server\%L\profile, where user is the username created
+from the [homes] share].
+</para>
+</note>
+
+<para>
+There is a parameter that is now available for use with NT Profiles:
+"logon drive". This should be set to "h:" or any other drive, and
+should be used in conjunction with the new "logon home" parameter.
+</para>
+
+<para>
+The entry for the NT 4.0 profile is a _directory_ not a file. The NT
+help on profiles mentions that a directory is also created with a .PDS
+extension. The user, while logging in, must have write permission to
+create the full profile path (and the folder with the .PDS extension)
+[lkcl 10aug97 - i found that the creation of the .PDS directory failed,
+and had to create these manually for each user, with a shell script.
+also, i presume, but have not tested, that the full profile path must
+be browseable just as it is for w95, due to the manner in which they
+attempt to create the full profile path: test existence of each path
+component; create path component].
+</para>
+
+<para>
+In the profile directory, NT creates more folders than 95. It creates
+"Application Data" and others, as well as "Desktop", "Nethood",
+"Start Menu" and "Programs". The profile itself is stored in a file
+NTuser.DAT. Nothing appears to be stored in the .PDS directory, and
+its purpose is currently unknown.
+</para>
+
+<para>
+You can use the System Control Panel to copy a local profile onto
+a samba server (see NT Help on profiles: it is also capable of firing
+up the correct location in the System Control Panel for you). The
+NT Help file also mentions that renaming NTuser.DAT to NTuser.MAN
+turns a profile into a mandatory one.
+</para>
+
+<note>
+<para>
+[lkcl 10aug97 - i notice that NT Workstation tells me that it is
+downloading a profile from a slow link. whether this is actually the
+case, or whether there is some configuration issue, as yet unknown,
+that makes NT Workstation _think_ that the link is a slow one is a
+matter to be resolved].
+</para>
+
+<para>
+[lkcl 20aug97 - after samba digest correspondence, one user found, and
+another confirmed, that profiles cannot be loaded from a samba server
+unless "security = user" and "encrypt passwords = yes" (see the file
+ENCRYPTION.txt) or "security = server" and "password server = ip.address.
+of.yourNTserver" are used. Either of these options will allow the NT
+workstation to access the samba server using LAN manager encrypted
+passwords, without the user intervention normally required by NT
+workstation for clear-text passwords].
+</para>
+
+<para>
+[lkcl 25aug97 - more comments received about NT profiles: the case of
+the profile _matters_. the file _must_ be called NTuser.DAT or, for
+a mandatory profile, NTuser.MAN].
+</para>
+</note>
+
+</sect3>
+
+
+<sect3>
+<title>Windows NT Server</title>
+
+<para>
+There is nothing to stop you specifying any path that you like for the
+location of users' profiles. Therefore, you could specify that the
+profile be stored on a samba server, or any other SMB server, as long as
+that SMB server supports encrypted passwords.
+</para>
+
+</sect3>
+
+
+<sect3>
+<title>Sharing Profiles between W95 and NT Workstation 4.0</title>
+
+<warning>
+<title>Potentially outdated or incorrect material follows</title>
+<para>
+I think this is all bogus, but have not deleted it. (Richard Sharpe)
+</para>
+</warning>
+
+<para>
+The default logon path is \\%N\U%. NT Workstation will attempt to create
+a directory "\\samba-server\username.PDS" if you specify the logon path
+as "\\samba-server\username" with the NT User Manager. Therefore, you
+will need to specify (for example) "\\samba-server\username\profile".
+NT 4.0 will attempt to create "\\samba-server\username\profile.PDS", which
+is more likely to succeed.
+</para>
+
+<para>
+If you then want to share the same Start Menu / Desktop with W95, you will
+need to specify "logon path = \\samba-server\username\profile" [lkcl 10aug97
+this has its drawbacks: i created a shortcut to telnet.exe, which attempts
+to run from the c:\winnt\system32 directory. this directory is obviously
+unlikely to exist on a Win95-only host].
+</para>
+
+<para>
+
+If you have this set up correctly, you will find separate user.DAT and
+NTuser.DAT files in the same profile directory.
+</para>
+
+<note>
+<para>
+[lkcl 25aug97 - there are some issues to resolve with downloading of
+NT profiles, probably to do with time/date stamps. i have found that
+NTuser.DAT is never updated on the workstation after the first time that
+it is copied to the local workstation profile directory. this is in
+contrast to w95, where it _does_ transfer / update profiles correctly].
+</para>
+</note>
+
+</sect3>
+
+</sect2>
+</sect1>
+
+
+<!-- **********************************************************
+
+ Appendix - DOMAIN_CONTROL.txt
+
+*************************************************************** -->
+
+<sect1>
+<title>
+DOMAIN_CONTROL.txt : Windows NT Domain Control & Samba
+</title>
+
+<warning>
+ <title>Possibly Outdated Material</title>
+
+ <para>
+ This appendix was originally authored by John H Terpstra of
+ the Samba Team and is included here for posterity.
+ </para>
+</warning>
+
+
+<para>
+<emphasis>NOTE :</emphasis>
+The term "Domain Controller" and those related to it refer to one specific
+method of authentication that can underly an SMB domain. Domain Controllers
+prior to Windows NT Server 3.1 were sold by various companies and based on
+private extensions to the LAN Manager 2.1 protocol. Windows NT introduced
+Microsoft-specific ways of distributing the user authentication database.
+See DOMAIN.txt for examples of how Samba can participate in or create
+SMB domains based on shared authentication database schemes other than the
+Windows NT SAM.
+</para>
+
+<para>
+Windows NT Server can be installed as either a plain file and print server
+(WORKGROUP workstation or server) or as a server that participates in Domain
+Control (DOMAIN member, Primary Domain controller or Backup Domain controller).
+The same is true for OS/2 Warp Server, Digital Pathworks and other similar
+products, all of which can participate in Domain Control along with Windows NT.
+</para>
+
+<para>
+To many people these terms can be confusing, so let's try to clear the air.
+</para>
+
+<para>
+Every Windows NT system (workstation or server) has a registry database.
+The registry contains entries that describe the initialization information
+for all services (the equivalent of Unix Daemons) that run within the Windows
+NT environment. The registry also contains entries that tell application
+software where to find dynamically loadable libraries that they depend upon.
+In fact, the registry contains entries that describes everything that anything
+may need to know to interact with the rest of the system.
+</para>
+
+<para>
+The registry files can be located on any Windows NT machine by opening a
+command prompt and typing:
+</para>
+
+<para>
+<prompt>C:\WINNT\></prompt> dir %SystemRoot%\System32\config
+</para>
+
+<para>
+The environment variable %SystemRoot% value can be obtained by typing:
+</para>
+
+<para>
+<prompt>C:\WINNT></prompt>echo %SystemRoot%
+</para>
+
+<para>
+The active parts of the registry that you may want to be familiar with are
+the files called: default, system, software, sam and security.
+</para>
+
+<para>
+In a domain environment, Microsoft Windows NT domain controllers participate
+in replication of the SAM and SECURITY files so that all controllers within
+the domain have an exactly identical copy of each.
+</para>
+
+<para>
+The Microsoft Windows NT system is structured within a security model that
+says that all applications and services must authenticate themselves before
+they can obtain permission from the security manager to do what they set out
+to do.
+</para>
+
+<para>
+The Windows NT User database also resides within the registry. This part of
+the registry contains the user's security identifier, home directory, group
+memberships, desktop profile, and so on.
+</para>
+
+<para>
+Every Windows NT system (workstation as well as server) will have its own
+registry. Windows NT Servers that participate in Domain Security control
+have a database that they share in common - thus they do NOT own an
+independent full registry database of their own, as do Workstations and
+plain Servers.
+</para>
+
+<para>
+The User database is called the SAM (Security Access Manager) database and
+is used for all user authentication as well as for authentication of inter-
+process authentication (i.e. to ensure that the service action a user has
+requested is permitted within the limits of that user's privileges).
+</para>
+
+<para>
+The Samba team have produced a utility that can dump the Windows NT SAM into
+smbpasswd format: see ENCRYPTION.txt for information on smbpasswd and
+/pub/samba/pwdump on your nearest Samba mirror for the utility. This
+facility is useful but cannot be easily used to implement SAM replication
+to Samba systems.
+</para>
+
+<para>
+Windows for Workgroups, Windows 95, and Windows NT Workstations and Servers
+can participate in a Domain security system that is controlled by Windows NT
+servers that have been correctly configured. Almost every domain will have
+ONE Primary Domain Controller (PDC). It is desirable that each domain will
+have at least one Backup Domain Controller (BDC).
+</para>
+
+<para>
+The PDC and BDCs then participate in replication of the SAM database so that
+each Domain Controlling participant will have an up to date SAM component
+within its registry.
+</para>
+
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/projdoc/UNIX_INSTALL.sgml b/docs/docbook/projdoc/UNIX_INSTALL.sgml
new file mode 100755
index 00000000000..39c0213d79e
--- /dev/null
+++ b/docs/docbook/projdoc/UNIX_INSTALL.sgml
@@ -0,0 +1,445 @@
+<chapter id="install">
+
+<title>How to Install and Test SAMBA</title>
+
+<sect1>
+ <title>Step 0: Read the man pages</title>
+
+ <para>The man pages distributed with SAMBA contain
+ lots of useful info that will help to get you started.
+ If you don't know how to read man pages then try
+ something like:</para>
+
+ <para><prompt>$ </prompt><userinput>nroff -man smbd.8 | more
+ </userinput></para>
+
+ <para>Other sources of information are pointed to
+ by the Samba web site,<ulink url="http://www.samba.org/">
+ http://www.samba.org</ulink></para>
+</sect1>
+
+<sect1>
+ <title>Step 1: Building the Binaries</title>
+
+ <para>To do this, first run the program <command>./configure
+ </command> in the source directory. This should automatically
+ configure Samba for your operating system. If you have unusual
+ needs then you may wish to run</para>
+
+ <para><prompt>root# </prompt><userinput>./configure --help
+ </userinput></para>
+
+ <para>first to see what special options you can enable.
+ Then executing</para>
+
+ <para><prompt>root# </prompt><userinput>make</userinput></para>
+
+ <para>will create the binaries. Once it's successfully
+ compiled you can use </para>
+
+ <para><prompt>root# </prompt><userinput>make install</userinput></para>
+
+ <para>to install the binaries and manual pages. You can
+ separately install the binaries and/or man pages using</para>
+
+ <para><prompt>root# </prompt><userinput>make installbin
+ </userinput></para>
+
+ <para>and</para>
+
+ <para><prompt>root# </prompt><userinput>make installman
+ </userinput></para>
+
+ <para>Note that if you are upgrading for a previous version
+ of Samba you might like to know that the old versions of
+ the binaries will be renamed with a ".old" extension. You
+ can go back to the previous version with</para>
+
+ <para><prompt>root# </prompt><userinput>make revert
+ </userinput></para>
+
+ <para>if you find this version a disaster!</para>
+</sect1>
+
+<sect1>
+ <title>Step 2: The all important step</title>
+
+ <para>At this stage you must fetch yourself a
+ coffee or other drink you find stimulating. Getting the rest
+ of the install right can sometimes be tricky, so you will
+ probably need it.</para>
+
+ <para>If you have installed samba before then you can skip
+ this step.</para>
+</sect1>
+
+<sect1>
+ <title>Step 3: Create the smb configuration file. </title>
+
+ <para>There are sample configuration files in the examples
+ subdirectory in the distribution. I suggest you read them
+ carefully so you can see how the options go together in
+ practice. See the man page for all the options.</para>
+
+ <para>The simplest useful configuration file would be
+ something like this:</para>
+
+ <para><programlisting>
+ [global]
+ workgroup = MYGROUP
+
+ [homes]
+ guest ok = no
+ read only = no
+ </programlisting</para>
+
+ <para>which would allow connections by anyone with an
+ account on the server, using either their login name or
+ "homes" as the service name. (Note that I also set the
+ workgroup that Samba is part of. See BROWSING.txt for details)</para>
+
+ <para>Note that <command>make install</command> will not install
+ a <filename>smb.conf</filename> file. You need to create it
+ yourself. </para>
+
+ <para>Make sure you put the smb.conf file in the same place
+ you specified in the<filename>Makefile</filename> (the default is to
+ look for it in <filename>/usr/local/samba/lib/</filename>).</para>
+
+ <para>For more information about security settings for the
+ [homes] share please refer to the document UNIX_SECURITY.txt.</para>
+</sect1>
+
+<sect1>
+ <title>Step 4: Test your config file with
+ <command>testparm</command></title>
+
+ <para>It's important that you test the validity of your
+ <filename>smb.conf</filename> file using the testparm program.
+ If testparm runs OK then it will list the loaded services. If
+ not it will give an error message.</para>
+
+ <para>Make sure it runs OK and that the services look
+ reasonable before proceeding. </para>
+
+</sect1>
+
+<sect1>
+ <title>Step 5: Starting the smbd and nmbd</title>
+
+ <para>You must choose to start smbd and nmbd either
+ as daemons or from <command>inetd</command>. Don't try
+ to do both! Either you can put them in <filename>
+ inetd.conf</filename> and have them started on demand
+ by <command>inetd</command>, or you can start them as
+ daemons either from the command line or in <filename>
+ /etc/rc.local</filename>. See the man pages for details
+ on the command line options. Take particular care to read
+ the bit about what user you need to be in order to start
+ Samba. In many cases you must be root.</para>
+
+ <para>The main advantage of starting <command>smbd</command>
+ and <command>nmbd</command> using the recommended daemon method
+ is that they will respond slightly more quickly to an initial connection
+ request.</para>
+
+ <sect2>
+ <title>Step 5a: Starting from inetd.conf</title>
+
+ <para>NOTE; The following will be different if
+ you use NIS or NIS+ to distributed services maps.</para>
+
+ <para>Look at your <filename>/etc/services</filename>.
+ What is defined at port 139/tcp. If nothing is defined
+ then add a line like this:</para>
+
+ <para><userinput>netbios-ssn 139/tcp</userinput></para>
+
+ <para>similarly for 137/udp you should have an entry like:</para>
+
+ <para><userinput>netbios-ns 137/udp</userinput></para>
+
+ <para>Next edit your <filename>/etc/inetd.conf</filename>
+ and add two lines something like this:</para>
+
+ <para><programlisting>
+ netbios-ssn stream tcp nowait root /usr/local/samba/bin/smbd smbd
+ netbios-ns dgram udp wait root /usr/local/samba/bin/nmbd nmbd
+ </programlisting></para>
+
+ <para>The exact syntax of <filename>/etc/inetd.conf</filename>
+ varies between unixes. Look at the other entries in inetd.conf
+ for a guide.</para>
+
+ <para>NOTE: Some unixes already have entries like netbios_ns
+ (note the underscore) in <filename>/etc/services</filename>.
+ You must either edit <filename>/etc/services</filename> or
+ <filename>/etc/inetd.conf</filename> to make them consistent.</para>
+
+ <para>NOTE: On many systems you may need to use the
+ "interfaces" option in smb.conf to specify the IP address
+ and netmask of your interfaces. Run <command>ifconfig</command>
+ as root if you don't know what the broadcast is for your
+ net. <command>nmbd</command> tries to determine it at run
+ time, but fails on some unixes. See the section on "testing nmbd"
+ for a method of finding if you need to do this.</para>
+
+ <para>!!!WARNING!!! Many unixes only accept around 5
+ parameters on the command line in <filename>inetd.conf</filename>.
+ This means you shouldn't use spaces between the options and
+ arguments, or you should use a script, and start the script
+ from <command>inetd</command>.</para>
+
+ <para>Restart <command>inetd</command>, perhaps just send
+ it a HUP. If you have installed an earlier version of <command>
+ nmbd</command> then you may need to kill nmbd as well.</para>
+ </sect2>
+
+ <sect2>
+ <title>Step 5b. Alternative: starting it as a daemon</title>
+
+ <para>To start the server as a daemon you should create
+ a script something like this one, perhaps calling
+ it <filename>startsmb</filename>.</para>
+
+ <para><programlisting>
+ #!/bin/sh
+ /usr/local/samba/bin/smbd -D
+ /usr/local/samba/bin/nmbd -D
+ </programlisting></para>
+
+ <para>then make it executable with <command>chmod
+ +x startsmb</command></para>
+
+ <para>You can then run <command>startsmb</command> by
+ hand or execute it from <filename>/etc/rc.local</filename>
+ </para>
+
+ <para>To kill it send a kill signal to the processes
+ <command>nmbd</command> and <command>smbd</command>.</para>
+
+ <para>NOTE: If you use the SVR4 style init system then
+ you may like to look at the <filename>examples/svr4-startup</filename>
+ script to make Samba fit into that system.</para>
+ </sect2>
+</sect1>
+
+<sect1>
+ <title>Step 6: Try listing the shares available on your
+ server</title>
+
+ <para><prompt>$ </prompt><userinput>smbclient -L
+ <replaceable>yourhostname</replaceable></userinput></para>
+
+ <para>You should get back a list of shares available on
+ your server. If you don't then something is incorrectly setup.
+ Note that this method can also be used to see what shares
+ are available on other LanManager clients (such as WfWg).</para>
+
+ <para>If you choose user level security then you may find
+ that Samba requests a password before it will list the shares.
+ See the <command>smbclient</command> man page for details. (you
+ can force it to list the shares without a password by
+ adding the option -U% to the command line. This will not work
+ with non-Samba servers)</para>
+</sect1>
+
+<sect1>
+ <title>Step 7: Try connecting with the unix client</title>
+
+ <para><prompt>$ </prompt><userinput>smbclient <replaceable>
+ //yourhostname/aservice</replaceable></userinput></para>
+
+ <para>Typically the <replaceable>yourhostname</replaceable>
+ would be the name of the host where you installed <command>
+ smbd</command>. The <replaceable>aservice</replaceable> is
+ any service you have defined in the <filename>smb.conf</filename>
+ file. Try your user name if you just have a [homes] section
+ in <filename>smb.conf</filename>.</para>
+
+ <para>For example if your unix host is bambi and your login
+ name is fred you would type:</para>
+
+ <para><prompt>$ </prompt><userinput>smbclient //bambi/fred
+ </userinput></para>
+</sect1>
+
+<sect1>
+ <title>Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT,
+ Win2k, OS/2, etc... client</title>
+
+ <para>Try mounting disks. eg:</para>
+
+ <para><prompt>C:\WINDOWS\> </prompt><userinput>net use d: \\servername\service
+ </userinput></para>
+
+ <para>Try printing. eg:</para>
+
+ <para><prompt>C:\WINDOWS\> </prompt><userinput>net use lpt1:
+ \\servername\spoolservice</userinput></para>
+
+ <para><prompt>C:\WINDOWS\> </prompt><userinput>print filename
+ </userinput></para>
+
+ <para>Celebrate, or send me a bug report!</para>
+</sect1>
+
+<sect1>
+ <title>What If Things Don't Work?</title>
+
+ <para>If nothing works and you start to think "who wrote
+ this pile of trash" then I suggest you do step 2 again (and
+ again) till you calm down.</para>
+
+ <para>Then you might read the file DIAGNOSIS.txt and the
+ FAQ. If you are still stuck then try the mailing list or
+ newsgroup (look in the README for details). Samba has been
+ successfully installed at thousands of sites worldwide, so maybe
+ someone else has hit your problem and has overcome it. You could
+ also use the WWW site to scan back issues of the samba-digest.</para>
+
+ <para>When you fix the problem PLEASE send me some updates to the
+ documentation (or source code) so that the next person will find it
+ easier. </para>
+
+ <sect2>
+ <title>Diagnosing Problems</title>
+
+ <para>If you have installation problems then go to
+ <filename>DIAGNOSIS.txt</filename> to try to find the
+ problem.</para>
+ </sect2>
+
+ <sect2>
+ <title>Scope IDs</title>
+
+ <para>By default Samba uses a blank scope ID. This means
+ all your windows boxes must also have a blank scope ID.
+ If you really want to use a non-blank scope ID then you will
+ need to use the 'netbios scope' smb.conf option.
+ All your PCs will need to have the same setting for
+ this to work. I do not recommend scope IDs.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>Choosing the Protocol Level</title>
+
+ <para>The SMB protocol has many dialects. Currently
+ Samba supports 5, called CORE, COREPLUS, LANMAN1,
+ LANMAN2 and NT1.</para>
+
+ <para>You can choose what maximum protocol to support
+ in the <filename>smb.conf</filename> file. The default is
+ NT1 and that is the best for the vast majority of sites.</para>
+
+ <para>In older versions of Samba you may have found it
+ necessary to use COREPLUS. The limitations that led to
+ this have mostly been fixed. It is now less likely that you
+ will want to use less than LANMAN1. The only remaining advantage
+ of COREPLUS is that for some obscure reason WfWg preserves
+ the case of passwords in this protocol, whereas under LANMAN1,
+ LANMAN2 or NT1 it uppercases all passwords before sending them,
+ forcing you to use the "password level=" option in some cases.</para>
+
+ <para>The main advantage of LANMAN2 and NT1 is support for
+ long filenames with some clients (eg: smbclient, Windows NT
+ or Win95). </para>
+
+ <para>See the smb.conf(5) manual page for more details.</para>
+
+ <para>Note: To support print queue reporting you may find
+ that you have to use TCP/IP as the default protocol under
+ WfWg. For some reason if you leave Netbeui as the default
+ it may break the print queue reporting on some systems.
+ It is presumably a WfWg bug.</para>
+ </sect2>
+
+ <sect2>
+ <title>Printing from UNIX to a Client PC</title>
+
+ <para>To use a printer that is available via a smb-based
+ server from a unix host you will need to compile the
+ smbclient program. You then need to install the script
+ "smbprint". Read the instruction in smbprint for more details.
+ </para>
+
+ <para>There is also a SYSV style script that does much
+ the same thing called smbprint.sysv. It contains instructions.</para>
+ </sect2>
+
+ <sect2>
+ <title>Locking</title>
+
+ <para>One area which sometimes causes trouble is locking.</para>
+
+ <para>There are two types of locking which need to be
+ performed by a SMB server. The first is "record locking"
+ which allows a client to lock a range of bytes in a open file.
+ The second is the "deny modes" that are specified when a file
+ is open.</para>
+
+ <para>Record locking semantics under Unix is very
+ different from record locking under Windows. Versions
+ of Samba before 2.2 have tried to use the native
+ fcntl() unix system call to implement proper record
+ locking between different Samba clients. This can not
+ be fully correct due to several reasons. The simplest
+ is the fact that a Windows client is allowed to lock a
+ byte range up to 2^32 or 2^64, depending on the client
+ OS. The unix locking only supports byte ranges up to
+ 2^31. So it is not possible to correctly satisfy a
+ lock request above 2^31. There are many more
+ differences, too many to be listed here.</para>
+
+ <para>Samba 2.2 and above implements record locking
+ completely independent of the underlying unix
+ system. If a byte range lock that the client requests
+ happens to fall into the range 0-2^31, Samba hands
+ this request down to the Unix system. All other locks
+ can not be seen by unix anyway.</para>
+
+ <para>Strictly a SMB server should check for locks before
+ every read and write call on a file. Unfortunately with the
+ way fcntl() works this can be slow and may overstress the
+ rpc.lockd. It is also almost always unnecessary as clients
+ are supposed to independently make locking calls before reads
+ and writes anyway if locking is important to them. By default
+ Samba only makes locking calls when explicitly asked
+ to by a client, but if you set "strict locking = yes" then it will
+ make lock checking calls on every read and write. </para>
+
+ <para>You can also disable by range locking completely
+ using "locking = no". This is useful for those shares that
+ don't support locking or don't need it (such as cdroms). In
+ this case Samba fakes the return codes of locking calls to
+ tell clients that everything is OK.</para>
+
+ <para>The second class of locking is the "deny modes". These
+ are set by an application when it opens a file to determine
+ what types of access should be allowed simultaneously with
+ its open. A client may ask for DENY_NONE, DENY_READ, DENY_WRITE
+ or DENY_ALL. There are also special compatibility modes called
+ DENY_FCB and DENY_DOS.</para>
+ </sect2>
+
+ <sect2>
+ <title>Mapping Usernames</title>
+
+ <para>If you have different usernames on the PCs and
+ the unix server then take a look at the "username map" option.
+ See the smb.conf man page for details.</para>
+ </sect2>
+
+ <sect2>
+ <title>Other Character Sets</title>
+
+ <para>If you have problems using filenames with accented
+ characters in them (like the German, French or Scandinavian
+ character sets) then I recommend you look at the "valid chars"
+ option in smb.conf and also take a look at the validchars
+ package in the examples directory.</para>
+ </sect2>
+
+</sect1>
+</chapter>
diff --git a/docs/docbook/projdoc/cups.sgml b/docs/docbook/projdoc/cups.sgml
new file mode 100755
index 00000000000..57a12843a84
--- /dev/null
+++ b/docs/docbook/projdoc/cups.sgml
@@ -0,0 +1,445 @@
+<chapter id="cups">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Kurt</firstname><surname>Pfeifle</surname>
+ <affiliation>
+ <address>
+ <email>kpfeifle@danka.de</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (24 May 2002) </pubdate>
+</chapterinfo>
+
+<title>Printing with CUPS in Samba 2.2.x</title>
+
+
+<sect1>
+<title>Printing with CUPS in Samba 2.2.x</title>
+
+<para>
+<ulink url="http://www.cups.org/">CUPS</ulink> is a newcomer in
+the UNIX printing scene, which has convinced many people upon first trial
+already. However, it has quite a few new features, which make it different
+from other, more traditional printing systems.
+</para>
+</sect1>
+
+
+<sect1>
+<title>Configuring <filename>smb.conf</filename> for CUPS</title>
+
+<para>
+Printing with CUPS in the most basic <filename>smb.conf</filename>
+setup in Samba 2.2.x only needs two settings: <command>printing = cups</command> and
+<command>printcap = cups</command>. While CUPS itself doesn't need a printcap
+anymore, the <filename>cupsd.conf</filename> configuration file knows two directives
+(example: <command>Printcap /etc/printcap</command> and <command>PrintcapFormat
+BSD</command>), which control if such a file should be created for the
+convenience of third party applications. Make sure it is set! For details see
+<command>man cupsd.conf</command> and other CUPS-related documentation.
+</para>
+
+<para>
+If SAMBA is compiled against libcups, then <command>printcap =
+cups</command> uses the CUPS API to list printers, submit jobs, etc. Otherwise it
+maps to the System V commands with an additional <parameter>-oraw</parameter>
+option for printing. On a Linux system, you can use the <command>ldd</command> command to
+find out details (ldd may not be present on other OS platforms, or its
+function may be embodied by a different command):
+</para>
+
+<para>
+<programlisting>transmeta:/home/kurt # ldd `which smbd`
+ libssl.so.0.9.6 => /usr/lib/libssl.so.0.9.6 (0x4002d000)
+ libcrypto.so.0.9.6 => /usr/lib/libcrypto.so.0.9.6 (0x4005a000)
+ libcups.so.2 => /usr/lib/libcups.so.2 (0x40123000)
+ libdl.so.2 => /lib/libdl.so.2 (0x401e8000)
+ libnsl.so.1 => /lib/libnsl.so.1 (0x401ec000)
+ libpam.so.0 => /lib/libpam.so.0 (0x40202000)
+ libc.so.6 => /lib/libc.so.6 (0x4020b000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x40000000)
+</programlisting></para>
+
+<para>
+The line "libcups.so.2 =&gt; /usr/lib/libcups.so.2
+(0x40123000)" shows there is CUPS support compiled into this version of
+Samba. If this is the case, and <command>printing = cups</command> is set, then any
+otherwise manually set print command in smb.conf is ignored.
+</para>
+</sect1>
+
+
+
+
+<sect1>
+<title>Using CUPS as a mere spooling print server -- "raw"
+printing with vendor drivers download</title>
+
+<para>
+You can setup Samba and your Windows clients to use the
+CUPS print subsystem just as you would with any of the more traditional print
+subsystems: that means the use of vendor provided, native Windows printer
+drivers for each target printer. If you setup the [print$] share to
+download these drivers to the clients, their GDI system (Graphical Device
+Interface) will output the Wndows EMF (Enhanced MetaFile) and
+convert it -- with the help of the printer driver -- locally into the format
+the printer is expecting. Samba and the CUPS print subsystem will have to
+treat these files as raw print files -- they are already in the
+shape to be digestable for the printer. This is the same traditional setup
+for Unix print servers handling Windows client jobs. It does not take much
+CPU power to handle this kind of task efficiently.
+</para>
+</sect1>
+
+
+
+
+<sect1>
+<title>CUPS as a network PostScript RIP -- CUPS drivers working on server, Adobe
+PostScript driver with CUPS-PPDs downloaded to clients</title>
+
+
+<para>
+CUPS is perfectly able to use PPD files (PostScript
+Printer Descriptions). PPDs can control all print device options. They
+are usually provided by the manufacturer -- if you own a PostSript printer,
+that is. PPD files are always a component of PostScript printer drivers on MS
+Windows or Apple Mac OS systems. They are ASCII files containing
+user-selectable print options, mapped to appropriate PostScript, PCL or PJL
+commands for the target printer. Printer driver GUI dialogs translate these
+options "on-the-fly" into buttons and drop-down lists for the user to
+select.
+</para>
+
+<para>
+CUPS can load, without any conversions, the PPD file from
+any Windows (NT is recommended) PostScript driver and handle the options.
+There is a web browser interface to the print options (select
+http://localhost:631/printers/ and click on one "Configure Printer" button
+to see it), a commandline interface (see <command>man lpoptions</command> or
+try if you have <command>lphelp</command> on your system) plus some different GUI frontends on Linux
+UNIX, which can present PPD options to the users. PPD options are normally
+meant to become evaluated by the PostScript RIP on the real PostScript
+printer.
+</para>
+
+<para>
+CUPS doesn't stop at "real" PostScript printers in its
+usage of PPDs. The CUPS developers have extended the PPD concept, to also
+describe available device and driver options for non-PostScript printers
+through CUPS-PPDs.
+</para>
+
+<para>
+This is logical, as CUPS includes a fully featured
+PostScript interpreter (RIP). This RIP is based on Ghostscript. It can
+process all received PostScript (and additionally many other file formats)
+from clients. All CUPS-PPDs geared to non-PostScript printers contain an
+additional line, starting with the keyword <parameter>*cupsFilter</parameter>.
+This line
+tells the CUPS print system which printer-specific filter to use for the
+interpretation of the accompanying PostScript. Thus CUPS lets all its
+printers appear as PostScript devices to its clients, because it can act as a
+PostScript RIP for those printers, processing the received PostScript code
+into a proper raster print format.
+</para>
+
+<para>
+CUPS-PPDs can also be used on Windows-Clients, on top of a
+PostScript driver (recommended is the Adobe one).
+</para>
+
+<para>
+This feature enables CUPS to do a few tricks no other
+spooler can do:
+</para>
+
+<itemizedlist>
+ <listitem><para>act as a networked PostScript RIP (Raster Image Processor), handling
+ printfiles from all client platforms in a uniform way;</para></listitem>
+ <listitem><para>act as a central accounting and billing server, as all files are passed
+ through the <command>pstops</command> Filter and are therefor logged in
+ the CUPS <filename>page&lowbar;log</filename>. - <emphasis>NOTE: </emphasis>this
+ can not happen with "raw" print jobs, which always remain unfiltered
+ per definition;</para></listitem>
+ <listitem><para>enable clients to consolidate on a single PostScript driver, even for
+ many different target printers.</para></listitem>
+</itemizedlist>
+</sect1>
+
+
+
+<sect1>
+<title>Windows Terminal Servers (WTS) as CUPS clients</title>
+
+<para>
+This setup may be of special interest to people
+experiencing major problems in WTS environments. WTS need often a multitude
+of non-PostScript drivers installed to run their clients' variety of
+different printer models. This often imposes the price of much increased
+instability. In many cases, in an attempt to overcome this problem, site
+administrators have resorted to restrict the allowed drivers installed on
+their WTS to one generic PCL- and one PostScript driver. This however
+restricts the clients in the amount of printer options available for them --
+often they can't get out more then simplex prints from one standard paper
+tray, while their devices could do much better, if driven by a different
+driver!
+</para>
+
+<para>
+Using an Adobe PostScript driver, enabled with a CUPS-PPD,
+seems to be a very elegant way to overcome all these shortcomings. The
+PostScript driver is not known to cause major stability problems on WTS (even
+if used with many different PPDs). The clients will be able to (again) chose
+paper trays, duplex printing and other settings. However, there is a certain
+price for this too: a CUPS server acting as a PostScript RIP for its clients
+requires more CPU and RAM than just to act as a "raw spooling" device. Plus,
+this setup is not yet widely tested, although the first feedbacks look very
+promising...
+</para>
+</sect1>
+
+
+<sect1>
+<title>Setting up CUPS for driver download</title>
+
+<para>
+The <command>cupsadsmb</command> utility (shipped with all current
+CUPS versions) makes the sharing of any (or all) installed CUPS printers very
+easy. Prior to using it, you need the following settings in smb.conf:
+</para>
+
+<para><programlisting>[global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+</programlisting></para>
+
+<para>
+For licensing reasons the necessary files of the Adobe
+Postscript driver can not be distributed with either Samba or CUPS. You need
+to download them yourself from the Adobe website. Once extracted, create a
+<filename>drivers</filename> directory in the CUPS data directory (usually
+<filename>/usr/share/cups/</filename>). Copy the Adobe files using
+UPPERCASE filenames, to this directory as follows:
+</para>
+
+<para><programlisting>
+ ADFONTS.MFM
+ ADOBEPS4.DRV
+ ADOBEPS4.HLP
+ ADOBEPS5.DLL
+ ADOBEPSU.DLL
+ ADOBEPSU.HLP
+ DEFPRTR2.PPD
+ ICONLIB.DLL
+</programlisting></para>
+
+<para>
+Users of the ESP Print Pro software are able to install
+their "Samba Drivers" package for this purpose with no problem.
+</para>
+</sect1>
+
+
+
+<sect1>
+<title>Sources of CUPS drivers / PPDs</title>
+
+<para>
+On the internet you can find now many thousand CUPS-PPD
+files (with their companion filters), in many national languages,
+supporting more than 1.000 non-PostScript models.
+</para>
+
+<itemizedlist>
+ <listitem><para><ulink url="http://wwwl.easysw.com/printpro/">ESP PrintPro
+ (http://wwwl.easysw.com/printpro/)</ulink>
+ (commercial, non-Free) is packaged with more than 3.000 PPDs, ready for
+ successful usage "out of the box" on Linux, IBM-AIX, HP-UX, Sun-Solaris,
+ SGI-IRIX, Compaq Tru64, Digital Unix and some more commercial Unices (it
+ is written by the CUPS developers themselves and its sales help finance
+ the further development of CUPS, as they feed their creators)</para></listitem>
+ <listitem><para>the <ulink
+ url="http://gimp-print.sourceforge.net/">Gimp-Print-Project
+ (http://gimp-print.sourceforge.net/)</ulink>
+ (GPL, Free Software) provides around 120 PPDs (supporting nearly 300
+ printers, many driven to photo quality output), to be used alongside the
+ Gimp-Print CUPS filters;</para></listitem>
+ <listitem><para><ulink url="http://www.turboprint.com/">TurboPrint
+ (http://www.turboprint.com/)</ulink>
+ (Shareware, non-Freee) supports roughly the same amount of printers in
+ excellent quality;</para></listitem>
+ <listitem><para><ulink
+ url="http://www-124.ibm.com/developerworks/oss/linux/projects/omni/">OMNI
+ (http://www-124.ibm.com/developerworks/oss/linux/projects/omni/)</ulink>
+ (LPGL, Free) is a package made by IBM, now containing support for more
+ than 400 printers, stemming from the inheritance of IBM OS/2 KnowHow
+ ported over to Linux (CUPS support is in a Beta-stage at present);</para></listitem>
+ <listitem><para><ulink url="http://hpinkjet.sourceforge.net/">HPIJS
+ (http://hpinkjet.sourceforge.net/)</ulink>
+ (BSD-style licnes, Free) supports around 120 of HP's own printers and is
+ also providing excellent print quality now;</para></listitem>
+ <listitem><para><ulink
+ url="http://www.linuxprinting.org/">Foomatic/cupsomatic (http://www.linuxprinting.org/)</ulink>
+ (LPGL, Free) from Linuxprinting.org are providing PPDs for practically every
+ Ghostscript filter known to the world, now usable with CUPS.</para></listitem>
+</itemizedlist>
+
+<para>
+<emphasis>NOTE: </emphasis>the cupsomatic trick from Linuxprinting.org is
+working different from the other drivers. While the other drivers take the
+generic CUPS raster (produced by CUPS' own pstoraster PostScript RIP) as
+their input, cupsomatic "kidnaps" the PostScript inside CUPS, before
+RIP-ping, deviates it to an external Ghostscript installation (which now
+becomes the RIP) and gives it back to a CUPS backend once Ghostscript is
+finished. -- CUPS versions from 1.1.15 and later will provide their pstoraster
+PostScript RIP function again inside a system-wide Ghostscript
+installation rather than in "their own" pstoraster filter. (This
+CUPS-enabling Ghostscript version may be installed either as a
+patch to GNU or AFPL Ghostscript, or as a complete ESP Ghostscript package).
+However, this will not change the cupsomatic approach of guiding the printjob
+along a different path through the filtering system than the standard CUPS
+way...
+</para>
+
+<para>
+Once you installed a printer inside CUPS with one of the
+recommended methods (the lpadmin command, the web browser interface or one of
+the available GUI wizards), you can use <command>cupsaddsmb</command> to share the
+printer via Samba. <command>cupsaddsmb</command> prepares the driver files for
+comfortable client download and installation upon their first contact with
+this printer share.
+</para>
+
+
+
+<sect2>
+<title><command>cupsaddsmb</command></title>
+
+
+<para>
+The <command>cupsaddsmb</command> command copies the needed files
+for convenient Windows client installations from the previously prepared CUPS
+data directory to your [print$] share. Additionally, the PPD
+associated with this printer is copied from <filename>/etc/cups/ppd/</filename> to
+[print$].
+</para>
+
+<para><programlisting>
+<prompt>root# </prompt> <command>cupsaddsmb -U root infotec_IS2027</command>
+Password for root required to access localhost via SAMBA: <userinput>[type in password 'secret']</userinput>
+</programlisting></para>
+
+<para>
+To share all printers and drivers, use the <parameter>-a</parameter>
+parameter instead of a printer name.
+</para>
+
+
+<para>
+Probably you want to see what's going on. Use the
+<parameter>-v</parameter> parameter to get a more verbose output:
+</para>
+
+<para><programlisting>
+<prompt>root# </prompt> cupsaddsmb -v -U root infotec_IS2027
+ Password for root required to access localhost via SAMBA:
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir W32X86;put /var/spool/cups/tmp/3cd1cc66376c0 W32X86/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;put /usr/share/cups/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;put /usr/share/cups/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \W32X86
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \W32X86/infotec_IS2027.PPD (17394.6 kb/s) (average 17395.2 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS5.DLL as \W32X86/ADOBEPS5.DLL (10877.4 kb/s) (average 11343.0 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.DLL as \W32X86/ADOBEPSU.DLL (5095.2 kb/s) (average 9260.4 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.HLP as \W32X86/ADOBEPSU.HLP (8828.7 kb/s) (average 9247.1 kb/s)
+
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir WIN40;put /var/spool/cups/tmp/3cd1cc66376c0 WIN40/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;put /usr/share/cups/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;put /usr/share/cups/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;put /usr/share/cups/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;put /usr/share/cups/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;put /usr/share/cups/drivers/PSMON.DLL WIN40/PSMON.DLL;'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \WIN40
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \WIN40/infotec_IS2027.PPD (26091.5 kb/s) (average 26092.8 kb/s)
+ putting file /usr/share/cups/drivers/ADFONTS.MFM as \WIN40/ADFONTS.MFM (11241.6 kb/s) (average 11812.9 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.DRV as \WIN40/ADOBEPS4.DRV (16640.6 kb/s) (average 14679.3 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.HLP as \WIN40/ADOBEPS4.HLP (11285.6 kb/s) (average 14281.5 kb/s)
+ putting file /usr/share/cups/drivers/DEFPRTR2.PPD as \WIN40/DEFPRTR2.PPD (823.5 kb/s) (average 12944.0 kb/s)
+ putting file /usr/share/cups/drivers/ICONLIB.DLL as \WIN40/ICONLIB.DLL (19226.2 kb/s) (average 13169.7 kb/s)
+ putting file /usr/share/cups/drivers/PSMON.DLL as \WIN40/PSMON.DLL (18666.1 kb/s) (average 13266.7 kb/s)
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"'
+ cmd = adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"'
+ cmd = adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'setdriver infotec_IS2027 infotec_IS2027'
+ cmd = setdriver infotec_IS2027 infotec_IS2027
+ Succesfully set infotec_IS2027 to driver infotec_IS2027.
+
+ <prompt>root# </prompt>
+</programlisting></para>
+
+<para>
+If you look closely, you'll discover your root password
+was transfered unencrypted over the wire, so beware! Also, if you look
+further her, you'll discover error messages like
+<constant>NT_STATUS_OBJECT_NAME_COLLISION</constant> in between. They occur, because
+the directories <filename>WIN40</filename> and <filename>W32X86</filename> already
+existed in the [print$] driver download share (from a previous driver
+installation). They are harmless here.
+</para>
+
+<para>
+Now your printer is prepared for the clients to use. From
+a client, browse to the CUPS/Samba server, open the "Printers"
+share, right-click on this printer and select "Install..." or
+"Connect..." (depending on the Windows version you use). Now their
+should be a new printer in your client's local "Printers" folder,
+named (in my case) "infotec_IS2027 on kdebitshop"
+</para>
+
+<para>
+<emphasis>NOTE: </emphasis>
+<command>cupsaddsmb</command> will only reliably work i
+with CUPS version 1.1.15 or higher
+and Samba from 2.2.4. If it doesn't work, or if the automatic printer
+driver download to the clients doesn't succeed, you can still manually
+install the CUPS printer PPD on top of the Adobe PostScript driver on
+clients and then point the client's printer queue to the Samba printer
+share for connection, should you desire to use the CUPS networked
+PostScript RIP functions.
+</para>
+</sect2>
+</sect1>
+
+
+</chapter>
diff --git a/docs/docbook/projdoc/msdfs_setup.sgml b/docs/docbook/projdoc/msdfs_setup.sgml
new file mode 100755
index 00000000000..35c9d40840a
--- /dev/null
+++ b/docs/docbook/projdoc/msdfs_setup.sgml
@@ -0,0 +1,117 @@
+<chapter id="msdfs">
+
+<chapterinfo>
+ <author>
+ <firstname>Shirish</firstname><surname>Kalele</surname>
+ <affiliation>
+ <orgname>Samba Team & Veritas Software</orgname>
+ <address>
+ <email>samba@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>12 Jul 200</pubdate>
+</chapterinfo>
+
+
+<title>Hosting a Microsoft Distributed File System tree on Samba</title>
+
+<sect1>
+
+ <title>Instructions</title>
+
+ <para>The Distributed File System (or Dfs) provides a means of
+ separating the logical view of files and directories that users
+ see from the actual physical locations of these resources on the
+ network. It allows for higher availability, smoother storage expansion,
+ load balancing etc. For more information about Dfs, refer to <ulink
+ url="http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp">
+ Microsoft documentation</ulink>. </para>
+
+ <para>This document explains how to host a Dfs tree on a Unix
+ machine (for Dfs-aware clients to browse) using Samba.</para>
+
+ <para>To enable SMB-based DFS for Samba, configure it with the
+ <parameter>--with-msdfs</parameter> option. Once built, a
+ Samba server can be made a Dfs server by setting the global
+ boolean <ulink url="smb.conf.5.html#HOSTMSDFS"><parameter>
+ host msdfs</parameter></ulink> parameter in the <filename>smb.conf
+ </filename> file. You designate a share as a Dfs root using the share
+ level boolean <ulink url="smb.conf.5.html#MSDFSROOT"><parameter>
+ msdfs root</parameter></ulink> parameter. A Dfs root directory on
+ Samba hosts Dfs links in the form of symbolic links that point
+ to other servers. For example, a symbolic link
+ <filename>junction-&gt;msdfs:storage1\share1</filename> in
+ the share directory acts as the Dfs junction. When Dfs-aware
+ clients attempt to access the junction link, they are redirected
+ to the storage location (in this case, \\storage1\share1).</para>
+
+ <para>Dfs trees on Samba work with all Dfs-aware clients ranging
+ from Windows 95 to 2000.</para>
+
+ <para>Here's an example of setting up a Dfs tree on a Samba
+ server.</para>
+
+ <para><programlisting>
+# The smb.conf file:
+[global]
+ netbios name = SAMBA
+ host msdfs = yes
+
+[dfs]
+ path = /export/dfsroot
+ msdfs root = yes
+ </programlisting></para>
+
+
+ <para>In the /export/dfsroot directory we set up our dfs links to
+ other servers on the network.</para>
+
+ <para><prompt>root# </prompt><userinput>cd /export/dfsroot</userinput></para>
+ <para><prompt>root# </prompt><userinput>chown root /export/dfsroot</userinput></para>
+ <para><prompt>root# </prompt><userinput>chmod 755 /export/dfsroot</userinput></para>
+ <para><prompt>root# </prompt><userinput>ln -s msdfs:storageA\\shareA linka</userinput></para>
+ <para><prompt>root# </prompt><userinput>ln -s msdfs:serverB\\share,serverC\\share linkb</userinput></para>
+
+
+ <para>You should set up the permissions and ownership of
+ the directory acting as the Dfs root such that only designated
+ users can create, delete or modify the msdfs links. Also note
+ that symlink names should be all lowercase. This limitation exists
+ to have Samba avoid trying all the case combinations to get at
+ the link name. Finally set up the symbolic links to point to the
+ network shares you want, and start Samba.</para>
+
+ <para>Users on Dfs-aware clients can now browse the Dfs tree
+ on the Samba server at \\samba\dfs. Accessing
+ links linka or linkb (which appear as directories to the client)
+ takes users directly to the appropriate shares on the network.</para>
+
+ <sect2>
+ <title>Notes</title>
+
+ <itemizedlist>
+ <listitem><para>Windows clients need to be rebooted
+ if a previously mounted non-dfs share is made a dfs
+ root or vice versa. A better way is to introduce a
+ new share and make it the dfs root.</para>
+ </listitem>
+
+ <listitem><para>Currently there's a restriction that msdfs
+ symlink names should all be lowercase.</para>
+ </listitem>
+
+ <listitem><para>For security purposes, the directory
+ acting as the root of the Dfs tree should have ownership
+ and permissions set so that only designated users can
+ modify the symbolic links in the directory.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+</sect1>
+
+
+
+</chapter>
diff --git a/docs/docbook/projdoc/printer_driver2.sgml b/docs/docbook/projdoc/printer_driver2.sgml
new file mode 100755
index 00000000000..2afba6b5968
--- /dev/null
+++ b/docs/docbook/projdoc/printer_driver2.sgml
@@ -0,0 +1,676 @@
+<chapter id="printing">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Gerald (Jerry)</firstname><surname>Carter</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address>
+ <email>jerry@samba.org</email>
+ </address>
+ </affiliation>
+ </author>
+
+
+ <pubdate> (3 May 2001) </pubdate>
+</chapterinfo>
+
+<title>Printing Support in Samba 2.2.x</title>
+
+<sect1>
+<title>Introduction</title>
+
+<para>Beginning with the 2.2.0 release, Samba supports
+the native Windows NT printing mechanisms implemented via
+MS-RPC (i.e. the SPOOLSS named pipe). Previous versions of
+Samba only supported LanMan printing calls.</para>
+
+<para>The additional functionality provided by the new
+SPOOLSS support includes:</para>
+
+<itemizedlist>
+ <listitem><para>Support for downloading printer driver
+ files to Windows 95/98/NT/2000 clients upon demand.
+ </para></listitem>
+
+ <listitem><para>Uploading of printer drivers via the
+ Windows NT Add Printer Wizard (APW) or the
+ Imprints tool set (refer to <ulink
+ url="http://imprints.sourceforge.net">http://imprints.sourceforge.net</ulink>).
+ </para></listitem>
+
+ <listitem><para>Support for the native MS-RPC printing
+ calls such as StartDocPrinter, EnumJobs(), etc... (See
+ the MSDN documentation at <ulink
+ url="http://msdn.microsoft.com/">http://msdn.microsoft.com/</ulink>
+ for more information on the Win32 printing API)
+ </para></listitem>
+
+ <listitem><para>Support for NT Access Control Lists (ACL)
+ on printer objects</para></listitem>
+
+ <listitem><para>Improved support for printer queue manipulation
+ through the use of an internal databases for spooled job
+ information</para></listitem>
+</itemizedlist>
+
+<para>
+There has been some initial confusion about what all this means
+and whether or not it is a requirement for printer drivers to be
+installed on a Samba host in order to support printing from Windows
+clients. A bug existed in Samba 2.2.0 which made Windows NT/2000 clients
+require that the Samba server possess a valid driver for the printer.
+This is fixed in Samba 2.2.1 and once again, Windows NT/2000 clients
+can use the local APW for installing drivers to be used with a Samba
+served printer. This is the same behavior exhibited by Windows 9x clients.
+As a side note, Samba does not use these drivers in any way to process
+spooled files. They are utilized entirely by the clients.
+</para>
+
+<para>
+The following MS KB article, may be of some help if you are dealing with
+Windows 2000 clients: <emphasis>How to Add Printers with No User
+Interaction in Windows 2000</emphasis>
+</para>
+
+<para>
+<ulink url="http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP">http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP</ulink>
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>Configuration</title>
+
+<warning>
+<title>[print$] vs. [printer$]</title>
+
+<para>
+Previous versions of Samba recommended using a share named [printer$].
+This name was taken from the printer$ service created by Windows 9x
+clients when a printer was shared. Windows 9x printer servers always have
+a printer$ service which provides read-only access via no
+password in order to support printer driver downloads.
+</para>
+
+<para>
+However, the initial implementation allowed for a
+parameter named <parameter>printer driver location</parameter>
+to be used on a per share basis to specify the location of
+the driver files associated with that printer. Another
+parameter named <parameter>printer driver</parameter> provided
+a means of defining the printer driver name to be sent to
+the client.
+</para>
+
+<para>
+These parameters, including <parameter>printer driver
+file</parameter> parameter, are being deprecated and should not
+be used in new installations. For more information on this change,
+you should refer to the <link linkend="MIGRATION">Migration section</link>
+of this document.
+</para>
+</warning>
+
+<sect2>
+<title>Creating [print$]</title>
+
+<para>
+In order to support the uploading of printer driver
+files, you must first configure a file share named [print$].
+The name of this share is hard coded in Samba's internals so
+the name is very important (print$ is the service used by
+Windows NT print servers to provide support for printer driver
+download).
+</para>
+
+<para>You should modify the server's smb.conf file to add the global
+parameters and to create the
+following file share (of course, some of the parameter values,
+such as 'path' are arbitrary and should be replaced with
+appropriate values for your site):</para>
+
+<para><programlisting>
+[global]
+ ; members of the ntadmin group should be able
+ ; to add drivers and set printer properties
+ ; root is implicitly a 'printer admin'
+ printer admin = @ntadmin
+
+[print$]
+ path = /usr/local/samba/printers
+ guest ok = yes
+ browseable = yes
+ read only = yes
+ ; since this share is configured as read only, then we need
+ ; a 'write list'. Check the file system permissions to make
+ ; sure this account can copy files to the share. If this
+ ; is setup to a non-root account, then it should also exist
+ ; as a 'printer admin'
+ write list = @ntadmin,root
+</programlisting></para>
+
+<para>The <ulink url="smb.conf.5.html#WRITELIST"><parameter>
+write list</parameter></ulink> is used to allow administrative
+level user accounts to have write access in order to update files
+on the share. See the <ulink url="smb.conf.5.html">smb.conf(5)
+man page</ulink> for more information on configuring file shares.</para>
+
+<para>The requirement for <ulink url="smb.conf.5.html#GUESTOK"><command>guest
+ok = yes</command></ulink> depends upon how your
+site is configured. If users will be guaranteed to have
+an account on the Samba host, then this is a non-issue.</para>
+
+<note>
+<title>Author's Note</title>
+
+<para>
+The non-issue is that if all your Windows NT users are guaranteed to be
+authenticated by the Samba server (such as a domain member server and the NT
+user has already been validated by the Domain Controller in
+order to logon to the Windows NT console), then guest access
+is not necessary. Of course, in a workgroup environment where
+you just want to be able to print without worrying about
+silly accounts and security, then configure the share for
+guest access. You'll probably want to add <ulink
+url="smb.conf.5.html#MAPTOGUEST"><command>map to guest = Bad User
+</command></ulink> in the [global] section as well. Make sure
+you understand what this parameter does before using it
+though. --jerry
+</para>
+</note>
+
+<para>In order for a Windows NT print server to support
+the downloading of driver files by multiple client architectures,
+it must create subdirectories within the [print$] service
+which correspond to each of the supported client architectures.
+Samba follows this model as well.</para>
+
+<para>Next create the directory tree below the [print$] share
+for each architecture you wish to support.</para>
+
+<para><programlisting>
+[print$]-----
+ |-W32X86 ; "Windows NT x86"
+ |-WIN40 ; "Windows 95/98"
+ |-W32ALPHA ; "Windows NT Alpha_AXP"
+ |-W32MIPS ; "Windows NT R4000"
+ |-W32PPC ; "Windows NT PowerPC"
+</programlisting></para>
+
+<warning>
+<title>ATTENTION! REQUIRED PERMISSIONS</title>
+
+<para>
+In order to currently add a new driver to you Samba host,
+one of two conditions must hold true:
+</para>
+
+<itemizedlist>
+ <listitem><para>The account used to connect to the Samba host
+ must have a uid of 0 (i.e. a root account)</para></listitem>
+
+ <listitem><para>The account used to connect to the Samba host
+ must be a member of the <ulink
+ url="smb.conf.5.html#PRINTERADMIN"><parameter>printer
+ admin</parameter></ulink> list.</para></listitem>
+</itemizedlist>
+
+<para>
+Of course, the connected account must still possess access
+to add files to the subdirectories beneath [print$]. Remember
+that all file shares are set to 'read only' by default.
+</para>
+</warning>
+
+
+<para>
+Once you have created the required [print$] service and
+associated subdirectories, simply log onto the Samba server using
+a root (or <parameter>printer admin</parameter>) account
+from a Windows NT 4.0/2k client. Open "Network Neighbourhood" or
+"My Network Places" and browse for the Samba host. Once you have located
+the server, navigate to the "Printers..." folder.
+You should see an initial listing of printers
+that matches the printer shares defined on your Samba host.
+</para>
+</sect2>
+
+<sect2>
+<title>Setting Drivers for Existing Printers</title>
+
+<para>The initial listing of printers in the Samba host's
+Printers folder will have no real printer driver assigned
+to them. By default, in Samba 2.2.0 this driver name was set to
+<emphasis>NO PRINTER DRIVER AVAILABLE FOR THIS PRINTER</emphasis>.
+Later versions changed this to a NULL string to allow the use
+tof the local Add Printer Wizard on NT/2000 clients.
+Attempting to view the printer properties for a printer
+which has this default driver assigned will result in
+the error message:</para>
+
+<para>
+<emphasis>Device settings cannot be displayed. The driver
+for the specified printer is not installed, only spooler
+properties will be displayed. Do you want to install the
+driver now?</emphasis>
+</para>
+
+<para>
+Click <emphasis>No</emphasis> in the error dialog and you will be presented with
+the printer properties window. The way assign a driver to a
+printer is to either
+</para>
+
+<itemizedlist>
+ <listitem><para>Use the "New Driver..." button to install
+ a new printer driver, or</para></listitem>
+
+ <listitem><para>Select a driver from the popup list of
+ installed drivers. Initially this list will be empty.</para>
+ </listitem>
+</itemizedlist>
+
+<para>If you wish to install printer drivers for client
+operating systems other than "Windows NT x86", you will need
+to use the "Sharing" tab of the printer properties dialog.</para>
+
+<para>Assuming you have connected with a root account, you
+will also be able modify other printer properties such as
+ACLs and device settings using this dialog box.</para>
+
+<para>A few closing comments for this section, it is possible
+on a Windows NT print server to have printers
+listed in the Printers folder which are not shared. Samba does
+not make this distinction. By definition, the only printers of
+which Samba is aware are those which are specified as shares in
+<filename>smb.conf</filename>.</para>
+
+<para>Another interesting side note is that Windows NT clients do
+not use the SMB printer share, but rather can print directly
+to any printer on another Windows NT host using MS-RPC. This
+of course assumes that the printing client has the necessary
+privileges on the remote host serving the printer. The default
+permissions assigned by Windows NT to a printer gives the "Print"
+permissions to the "Everyone" well-known group.
+</para>
+
+</sect2>
+
+<sect2>
+<title>DeviceModes and New Printers</title>
+
+<para>
+In order for a printer to be truly usbla eby a Windows NT/2k/XP client,
+it must posses:
+</para>
+
+<itemizedlist>
+ <listitem><para>a valid Device Mode generated by the driver for the printer, and</para></listitem>
+ <listitem><para>a complete set of PrinterDriverData generated by the driver.</para></listitem>
+</itemizedlist>
+
+<para>
+If either one of these is incomplete, the clients can produce less than optimal
+output at best or in the worst cases, unreadable garbage or nothing at all.
+Fortunately, most driver generate the printer driver that is needed.
+However, the client must be tickled to generate a valid Device Mode and set it on the
+server. The easist means of doing so is to simply set the page orientation on
+the server's printer using the native Windows NT/2k printer properties page from
+a Window clients. Make sure to apply changes between swapping the page orientation
+to cause the change to actually take place. Be aware that this can only be done
+by a "printer admin" (the reason should be obvious I hope).
+</para>
+
+<para>
+Samba also includes a service level parameter name <ulink url="smb.conf.5.html#DEFAULTDEVMODE">default
+devmode</ulink> for generating a default device mode for a printer. Some driver
+will function fine with this default set of properties. Others may crash the client's
+spooler service. Use this parameter with caution. It is always better to have the client
+generate a valid device mode for the printer and store it on the server for you.
+</para>
+
+</sect2>
+
+
+<sect2>
+<title>Support a large number of printers</title>
+
+<para>One issue that has arisen during the development
+phase of Samba 2.2 is the need to support driver downloads for
+100's of printers. Using the Windows NT APW is somewhat
+awkward to say the list. If more than one printer are using the
+same driver, the <ulink url="rpcclient.1.html"><command>rpcclient's
+setdriver</command></ulink> command can be used to set the driver
+associated with an installed driver. The following is example
+of how this could be accomplished:</para>
+
+<para><programlisting>
+<prompt>$ </prompt>rpcclient pogo -U root%secret -c "enumdrivers"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+
+[Windows NT x86]
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4000 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 2100 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4Si/4SiMX PS]
+
+<prompt>$ </prompt>rpcclient pogo -U root%secret -c "enumprinters"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+ flags:[0x800000]
+ name:[\\POGO\hp-print]
+ description:[POGO\\POGO\hp-print,NO DRIVER AVAILABLE FOR THIS PRINTER,]
+ comment:[]
+
+<prompt>$ </prompt>rpcclient pogo -U root%secret \
+<prompt>&gt; </prompt> -c "setdriver hp-print \"HP LaserJet 4000 Series PS\""
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+Successfully set hp-print to driver HP LaserJet 4000 Series PS.
+</programlisting></para>
+</sect2>
+
+
+
+<sect2>
+<title>Adding New Printers via the Windows NT APW</title>
+
+<para>
+By default, Samba offers all printer shares defined in <filename>smb.conf</filename>
+in the "Printers..." folder. Also existing in this folder is the Windows NT
+Add Printer Wizard icon. The APW will be show only if
+</para>
+
+<itemizedlist>
+ <listitem><para>The connected user is able to successfully
+ execute an OpenPrinterEx(\\server) with administrative
+ privileges (i.e. root or <parameter>printer admin</parameter>).
+ </para></listitem>
+
+ <listitem><para><ulink url="smb.conf.5.html#SHOWADDPRINTERWIZARD"><parameter>show
+ add printer wizard = yes</parameter></ulink> (the default).
+ </para></listitem>
+</itemizedlist>
+
+<para>
+In order to be able to use the APW to successfully add a printer to a Samba
+server, the <ulink url="smb.conf.5.html#ADDPRINTERCOMMAND"><parameter>add
+printer command</parameter></ulink> must have a defined value. The program
+hook must successfully add the printer to the system (i.e.
+<filename>/etc/printcap</filename> or appropriate files) and
+<filename>smb.conf</filename> if necessary.
+</para>
+
+<para>
+When using the APW from a client, if the named printer share does
+not exist, <command>smbd</command> will execute the <parameter>add printer
+command</parameter> and reparse to the <filename>smb.conf</filename>
+to attempt to locate the new printer share. If the share is still not defined,
+an error of "Access Denied" is returned to the client. Note that the
+<parameter>add printer program</parameter> is executed under the context
+of the connected user, not necessarily a root account.
+</para>
+
+<para>
+There is a complementing <ulink url="smb.conf.5.html#DELETEPRINTERCOMMAND"><parameter>delete
+printer command</parameter></ulink> for removing entries from the "Printers..."
+folder.
+</para>
+
+</sect2>
+
+
+<sect2>
+<title>Samba and Printer Ports</title>
+
+<para>
+Windows NT/2000 print servers associate a port with each printer. These normally
+take the form of LPT1:, COM1:, FILE:, etc... Samba must also support the
+concept of ports associated with a printer. By default, only one printer port,
+named "Samba Printer Port", exists on a system. Samba does not really a port in
+order to print, rather it is a requirement of Windows clients.
+</para>
+
+<para>
+Note that Samba does not support the concept of "Printer Pooling" internally
+either. This is when a logical printer is assigned to multiple ports as
+a form of load balancing or fail over.
+</para>
+
+<para>
+If you require that multiple ports be defined for some reason,
+<filename>smb.conf</filename> possesses a <ulink
+url="smb.conf.5.html#ENUMPORTSCOMMAND"><parameter>enumports
+command</parameter></ulink> which can be used to define an external program
+that generates a listing of ports on a system.
+</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1>
+ <title>The Imprints Toolset</title>
+
+ <para>The Imprints tool set provides a UNIX equivalent of the
+ Windows NT Add Printer Wizard. For complete information, please
+ refer to the Imprints web site at <ulink url="http://imprints.sourceforge.net/">
+ http://imprints.sourceforge.net/</ulink> as well as the documentation
+ included with the imprints source distribution. This section will
+ only provide a brief introduction to the features of Imprints.</para>
+
+ <para>As of June 16, 2002 (quite a bit earlier actually), the Imprints
+ project is in need of a new maintainer. The most important skill
+ is decent perl coding and an interest in MS-RPC based printing using Samba.
+ If you wich to volunteer, please coordinate your efforts on the samba-technical
+ mailing list.
+ </para>
+
+
+ <sect2>
+ <title>What is Imprints?</title>
+
+ <para>Imprints is a collection of tools for supporting the goals
+ of</para>
+
+ <itemizedlist>
+ <listitem><para>Providing a central repository information
+ regarding Windows NT and 95/98 printer driver packages</para>
+ </listitem>
+
+ <listitem><para>Providing the tools necessary for creating
+ the Imprints printer driver packages.</para></listitem>
+
+ <listitem><para>Providing an installation client which
+ will obtain and install printer drivers on remote Samba
+ and Windows NT 4 print servers.</para></listitem>
+ </itemizedlist>
+
+ </sect2>
+
+
+ <sect2>
+ <title>Creating Printer Driver Packages</title>
+
+ <para>The process of creating printer driver packages is beyond
+ the scope of this document (refer to Imprints.txt also included
+ with the Samba distribution for more information). In short,
+ an Imprints driver package is a gzipped tarball containing the
+ driver files, related INF files, and a control file needed by the
+ installation client.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>The Imprints server</title>
+
+ <para>The Imprints server is really a database server that
+ may be queried via standard HTTP mechanisms. Each printer
+ entry in the database has an associated URL for the actual
+ downloading of the package. Each package is digitally signed
+ via GnuPG which can be used to verify that package downloaded
+ is actually the one referred in the Imprints database. It is
+ <emphasis>not</emphasis> recommended that this security check
+ be disabled.</para>
+ </sect2>
+
+ <sect2>
+ <title>The Installation Client</title>
+
+ <para>More information regarding the Imprints installation client
+ is available in the <filename>Imprints-Client-HOWTO.ps</filename>
+ file included with the imprints source package.</para>
+
+ <para>The Imprints installation client comes in two forms.</para>
+
+ <itemizedlist>
+ <listitem><para>a set of command line Perl scripts</para>
+ </listitem>
+
+ <listitem><para>a GTK+ based graphical interface to
+ the command line perl scripts</para></listitem>
+ </itemizedlist>
+
+ <para>The installation client (in both forms) provides a means
+ of querying the Imprints database server for a matching
+ list of known printer model names as well as a means to
+ download and install the drivers on remote Samba and Windows
+ NT print servers.</para>
+
+ <para>The basic installation process is in four steps and
+ perl code is wrapped around <command>smbclient</command>
+ and <command>rpcclient</command>.</para>
+
+<para><programlisting>
+foreach (supported architecture for a given driver)
+{
+ 1. rpcclient: Get the appropriate upload directory
+ on the remote server
+ 2. smbclient: Upload the driver files
+ 3. rpcclient: Issues an AddPrinterDriver() MS-RPC
+}
+
+4. rpcclient: Issue an AddPrinterEx() MS-RPC to actually
+ create the printer
+</programlisting></para>
+
+ <para>One of the problems encountered when implementing
+ the Imprints tool set was the name space issues between
+ various supported client architectures. For example, Windows
+ NT includes a driver named "Apple LaserWriter II NTX v51.8"
+ and Windows 95 calls its version of this driver "Apple
+ LaserWriter II NTX"</para>
+
+ <para>The problem is how to know what client drivers have
+ been uploaded for a printer. As astute reader will remember
+ that the Windows NT Printer Properties dialog only includes
+ space for one printer driver name. A quick look in the
+ Windows NT 4.0 system registry at</para>
+
+ <para><filename>HKLM\System\CurrentControlSet\Control\Print\Environment
+ </filename></para>
+
+ <para>will reveal that Windows NT always uses the NT driver
+ name. This is ok as Windows NT always requires that at least
+ the Windows NT version of the printer driver is present.
+ However, Samba does not have the requirement internally.
+ Therefore, how can you use the NT driver name if is has not
+ already been installed?</para>
+
+ <para>The way of sidestepping this limitation is to require
+ that all Imprints printer driver packages include both the Intel
+ Windows NT and 95/98 printer drivers and that NT driver is
+ installed first.</para>
+ </sect2>
+
+</sect1>
+
+
+<sect1>
+<title><anchor id="MIGRATION">Migration to from Samba 2.0.x to 2.2.x</title>
+
+<para>
+Given that printer driver management has changed (we hope improved) in
+2.2 over prior releases, migration from an existing setup to 2.2 can
+follow several paths. Here are the possible scenarios for
+migration:
+</para>
+
+<itemizedlist>
+ <listitem><para>If you do not desire the new Windows NT
+ print driver support, nothing needs to be done.
+ All existing parameters work the same.</para></listitem>
+
+ <listitem><para>If you want to take advantage of NT printer
+ driver support but do not want to migrate the
+ 9x drivers to the new setup, the leave the existing
+ <filename>printers.def</filename> file. When smbd attempts
+ to locate a
+ 9x driver for the printer in the TDB and fails it
+ will drop down to using the printers.def (and all
+ associated parameters). The <command>make_printerdef</command>
+ tool will also remain for backwards compatibility but will
+ be removed in the next major release.</para></listitem>
+
+ <listitem><para>If you install a Windows 9x driver for a printer
+ on your Samba host (in the printing TDB), this information will
+ take precedence and the three old printing parameters
+ will be ignored (including print driver location).</para></listitem>
+
+ <listitem><para>If you want to migrate an existing <filename>printers.def</filename>
+ file into the new setup, the current only solution is to use the Windows
+ NT APW to install the NT drivers and the 9x drivers. This can be scripted
+ using <command>smbclient</command> and <command>rpcclient</command>. See the
+ Imprints installation client at <ulink
+ url="http://imprints.sourceforge.net/">http://imprints.sourceforge.net/</ulink>
+ for an example.
+ </para></listitem>
+</itemizedlist>
+
+
+<warning>
+<title>Achtung!</title>
+
+<para>
+The following <filename>smb.conf</filename> parameters are considered to
+be deprecated and will be removed soon. Do not use them in new
+installations
+</para>
+
+<itemizedlist>
+ <listitem><para><parameter>printer driver file (G)</parameter>
+ </para></listitem>
+
+ <listitem><para><parameter>printer driver (S)</parameter>
+ </para></listitem>
+
+ <listitem><para><parameter>printer driver location (S)</parameter>
+ </para></listitem>
+</itemizedlist>
+</warning>
+
+
+<sect2>
+<title>Parameters in <filename>smb.conf(5)</filename> for Backwards Compatibility</title>
+
+<para>
+The have been two new parameters add in Samba 2.2.2 to for
+better support of Samba 2.0.x backwards capability (<parameter>disable
+spoolss</parameter>) and for using local printers drivers on Windows
+NT/2000 clients (<parameter>use client driver</parameter>). Both of
+these options are described in the smb.coinf(5) man page and are
+disabled by default. Use them with caution.
+</para>
+</sect2>
+
+
+</sect1>
+
+
+</chapter>
diff --git a/docs/docbook/projdoc/samba-doc.sgml b/docs/docbook/projdoc/samba-doc.sgml
new file mode 100755
index 00000000000..671ff453176
--- /dev/null
+++ b/docs/docbook/projdoc/samba-doc.sgml
@@ -0,0 +1,79 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+<!ENTITY UNIX-INSTALL SYSTEM "UNIX_INSTALL.sgml">
+<!ENTITY ENCRYPTION SYSTEM "ENCRYPTION.sgml">
+<!ENTITY MS-Dfs-Setup SYSTEM "msdfs_setup.sgml">
+<!ENTITY PRINTER-DRIVER2 SYSTEM "printer_driver2.sgml">
+<!ENTITY CUPS SYSTEM "cups.sgml">
+<!ENTITY DOMAIN-MEMBER SYSTEM "DOMAIN_MEMBER.sgml">
+<!ENTITY WINBIND SYSTEM "winbind.sgml">
+<!ENTITY NT-Security SYSTEM "NT_Security.sgml">
+<!ENTITY OS2-Client SYSTEM "OS2-Client-HOWTO.sgml">
+<!ENTITY Samba-PDC-HOWTO SYSTEM "Samba-PDC-HOWTO.sgml">
+<!ENTITY Samba-BDC-HOWTO SYSTEM "Samba-BDC-HOWTO.sgml">
+<!ENTITY CVS-Access SYSTEM "CVS-Access.sgml">
+<!ENTITY IntegratingWithWindows SYSTEM "Integrating-with-Windows.sgml">
+<!ENTITY Samba-PAM SYSTEM "PAM-Authentication-And-Samba.sgml">
+<!ENTITY Samba-LDAP SYSTEM "Samba-LDAP-HOWTO.sgml">
+<!ENTITY INDEX-FILE SYSTEM "index.sgml">
+]>
+
+<book id="Samba-Project-Documentation">
+
+<title>SAMBA Project Documentation</title>
+
+<bookinfo>
+ <author>
+ <surname>SAMBA Team</surname>
+ </author>
+ <address><email>samba@samba.org</email></address>
+</bookinfo>
+
+<dedication>
+<title>Abstract</title>
+
+<para>
+<emphasis>Last Update</emphasis> : Mon Apr 1 08:47:26 CST 2002
+</para>
+
+<para>
+This book is a collection of HOWTOs added to Samba documentation over the years.
+I try to ensure that all are current, but sometimes the is a larger job
+than one person can maintain. The most recent version of this document
+can be found at <ulink url="http://www.samba.org/">http://www.samba.org/</ulink>
+on the "Documentation" page. Please send updates to <ulink
+url="mailto:jerry@samba.org">jerry@samba.org</ulink>.
+</para>
+
+<para>
+This documentation is distributed under the GNU General Public License (GPL)
+version 2. A copy of the license is included with the Samba source
+distribution. A copy can be found on-line at <ulink
+url="http://www.fsf.org/licenses/gpl.txt">http://www.fsf.org/licenses/gpl.txt</ulink>
+</para>
+
+<para>
+Cheers, jerry
+</para>
+
+</dedication>
+
+<!-- Chapters -->
+&UNIX-INSTALL;
+&IntegratingWithWindows;
+&Samba-PAM;
+&MS-Dfs-Setup;
+&NT-Security;
+&PRINTER-DRIVER2;
+&CUPS;
+&DOMAIN-MEMBER;
+&Samba-PDC-HOWTO;
+&Samba-BDC-HOWTO;
+&Samba-LDAP;
+&WINBIND;
+&OS2-Client;
+&CVS-Access;
+
+<!-- Autogenerated Index -->
+&INDEX-FILE;
+
+</book>
diff --git a/docs/docbook/projdoc/winbind.sgml b/docs/docbook/projdoc/winbind.sgml
new file mode 100755
index 00000000000..52f608fc276
--- /dev/null
+++ b/docs/docbook/projdoc/winbind.sgml
@@ -0,0 +1,842 @@
+<chapter id="winbind">
+
+
+<chapterinfo>
+ <author>
+ <firstname>Tim</firstname><surname>Potter</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address><email>tpot@linuxcare.com.au</email></address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Andrew</firstname><surname>Trigdell</surname>
+ <affiliation>
+ <orgname>Samba Team</orgname>
+ <address><email>tridge@linuxcare.com.au</email></address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>John</firstname><surname>Trostel</surname>
+ <affiliation>
+ <orgname>Snapserver</orgname>
+ <address><email>jtrostel@snapserver.com</email></address>
+ </affiliation>
+ </author>
+
+
+ <pubdate>16 Oct 2000</pubdate>
+</chapterinfo>
+
+<title>Unified Logons between Windows NT and UNIX using Winbind</title>
+
+<sect1>
+ <title>Abstract</title>
+
+ <para>Integration of UNIX and Microsoft Windows NT through
+ a unified logon has been considered a "holy grail" in heterogeneous
+ computing environments for a long time. We present
+ <emphasis>winbind</emphasis>, a component of the Samba suite
+ of programs as a solution to the unified logon problem. Winbind
+ uses a UNIX implementation
+ of Microsoft RPC calls, Pluggable Authentication Modules, and the Name
+ Service Switch to allow Windows NT domain users to appear and operate
+ as UNIX users on a UNIX machine. This paper describes the winbind
+ system, explaining the functionality it provides, how it is configured,
+ and how it works internally.</para>
+</sect1>
+
+
+<sect1>
+ <title>Introduction</title>
+
+ <para>It is well known that UNIX and Microsoft Windows NT have
+ different models for representing user and group information and
+ use different technologies for implementing them. This fact has
+ made it difficult to integrate the two systems in a satisfactory
+ manner.</para>
+
+ <para>One common solution in use today has been to create
+ identically named user accounts on both the UNIX and Windows systems
+ and use the Samba suite of programs to provide file and print services
+ between the two. This solution is far from perfect however, as
+ adding and deleting users on both sets of machines becomes a chore
+ and two sets of passwords are required both of which
+ can lead to synchronization problems between the UNIX and Windows
+ systems and confusion for users.</para>
+
+ <para>We divide the unified logon problem for UNIX machines into
+ three smaller problems:</para>
+
+ <itemizedlist>
+ <listitem><para>Obtaining Windows NT user and group information
+ </para></listitem>
+
+ <listitem><para>Authenticating Windows NT users
+ </para></listitem>
+
+ <listitem><para>Password changing for Windows NT users
+ </para></listitem>
+ </itemizedlist>
+
+
+ <para>Ideally, a prospective solution to the unified logon problem
+ would satisfy all the above components without duplication of
+ information on the UNIX machines and without creating additional
+ tasks for the system administrator when maintaining users and
+ groups on either system. The winbind system provides a simple
+ and elegant solution to all three components of the unified logon
+ problem.</para>
+</sect1>
+
+
+<sect1>
+ <title>What Winbind Provides</title>
+
+ <para>Winbind unifies UNIX and Windows NT account management by
+ allowing a UNIX box to become a full member of a NT domain. Once
+ this is done the UNIX box will see NT users and groups as if
+ they were native UNIX users and groups, allowing the NT domain
+ to be used in much the same manner that NIS+ is used within
+ UNIX-only environments.</para>
+
+ <para>The end result is that whenever any
+ program on the UNIX machine asks the operating system to lookup
+ a user or group name, the query will be resolved by asking the
+ NT domain controller for the specified domain to do the lookup.
+ Because Winbind hooks into the operating system at a low level
+ (via the NSS name resolution modules in the C library) this
+ redirection to the NT domain controller is completely
+ transparent.</para>
+
+ <para>Users on the UNIX machine can then use NT user and group
+ names as they would use "native" UNIX names. They can chown files
+ so that they are owned by NT domain users or even login to the
+ UNIX machine and run a UNIX X-Window session as a domain user.</para>
+
+ <para>The only obvious indication that Winbind is being used is
+ that user and group names take the form DOMAIN\user and
+ DOMAIN\group. This is necessary as it allows Winbind to determine
+ that redirection to a domain controller is wanted for a particular
+ lookup and which trusted domain is being referenced.</para>
+
+ <para>Additionally, Winbind provides an authentication service
+ that hooks into the Pluggable Authentication Modules (PAM) system
+ to provide authentication via a NT domain to any PAM enabled
+ applications. This capability solves the problem of synchronizing
+ passwords between systems since all passwords are stored in a single
+ location (on the domain controller).</para>
+
+ <sect2>
+ <title>Target Uses</title>
+
+ <para>Winbind is targeted at organizations that have an
+ existing NT based domain infrastructure into which they wish
+ to put UNIX workstations or servers. Winbind will allow these
+ organizations to deploy UNIX workstations without having to
+ maintain a separate account infrastructure. This greatly
+ simplifies the administrative overhead of deploying UNIX
+ workstations into a NT based organization.</para>
+
+ <para>Another interesting way in which we expect Winbind to
+ be used is as a central part of UNIX based appliances. Appliances
+ that provide file and print services to Microsoft based networks
+ will be able to use Winbind to provide seamless integration of
+ the appliance into the domain.</para>
+ </sect2>
+</sect1>
+
+
+
+<sect1>
+ <title>How Winbind Works</title>
+
+ <para>The winbind system is designed around a client/server
+ architecture. A long running <command>winbindd</command> daemon
+ listens on a UNIX domain socket waiting for requests
+ to arrive. These requests are generated by the NSS and PAM
+ clients and processed sequentially.</para>
+
+ <para>The technologies used to implement winbind are described
+ in detail below.</para>
+
+ <sect2>
+ <title>Microsoft Remote Procedure Calls</title>
+
+ <para>Over the last two years, efforts have been underway
+ by various Samba Team members to decode various aspects of
+ the Microsoft Remote Procedure Call (MSRPC) system. This
+ system is used for most network related operations between
+ Windows NT machines including remote management, user authentication
+ and print spooling. Although initially this work was done
+ to aid the implementation of Primary Domain Controller (PDC)
+ functionality in Samba, it has also yielded a body of code which
+ can be used for other purposes.</para>
+
+ <para>Winbind uses various MSRPC calls to enumerate domain users
+ and groups and to obtain detailed information about individual
+ users or groups. Other MSRPC calls can be used to authenticate
+ NT domain users and to change user passwords. By directly querying
+ a Windows PDC for user and group information, winbind maps the
+ NT account information onto UNIX user and group names.</para>
+ </sect2>
+
+ <sect2>
+ <title>Name Service Switch</title>
+
+ <para>The Name Service Switch, or NSS, is a feature that is
+ present in many UNIX operating systems. It allows system
+ information such as hostnames, mail aliases and user information
+ to be resolved from different sources. For example, a standalone
+ UNIX workstation may resolve system information from a series of
+ flat files stored on the local filesystem. A networked workstation
+ may first attempt to resolve system information from local files,
+ and then consult a NIS database for user information or a DNS server
+ for hostname information.</para>
+
+ <para>The NSS application programming interface allows winbind
+ to present itself as a source of system information when
+ resolving UNIX usernames and groups. Winbind uses this interface,
+ and information obtained from a Windows NT server using MSRPC
+ calls to provide a new source of account enumeration. Using standard
+ UNIX library calls, one can enumerate the users and groups on
+ a UNIX machine running winbind and see all users and groups in
+ a NT domain plus any trusted domain as though they were local
+ users and groups.</para>
+
+ <para>The primary control file for NSS is
+ <filename>/etc/nsswitch.conf</filename>.
+ When a UNIX application makes a request to do a lookup
+ the C library looks in <filename>/etc/nsswitch.conf</filename>
+ for a line which matches the service type being requested, for
+ example the "passwd" service type is used when user or group names
+ are looked up. This config line species which implementations
+ of that service should be tried and in what order. If the passwd
+ config line is:</para>
+
+ <para><command>passwd: files example</command></para>
+
+ <para>then the C library will first load a module called
+ <filename>/lib/libnss_files.so</filename> followed by
+ the module <filename>/lib/libnss_example.so</filename>. The
+ C library will dynamically load each of these modules in turn
+ and call resolver functions within the modules to try to resolve
+ the request. Once the request is resolved the C library returns the
+ result to the application.</para>
+
+ <para>This NSS interface provides a very easy way for Winbind
+ to hook into the operating system. All that needs to be done
+ is to put <filename>libnss_winbind.so</filename> in <filename>/lib/</filename>
+ then add "winbind" into <filename>/etc/nsswitch.conf</filename> at
+ the appropriate place. The C library will then call Winbind to
+ resolve user and group names.</para>
+ </sect2>
+
+ <sect2>
+ <title>Pluggable Authentication Modules</title>
+
+ <para>Pluggable Authentication Modules, also known as PAM,
+ is a system for abstracting authentication and authorization
+ technologies. With a PAM module it is possible to specify different
+ authentication methods for different system applications without
+ having to recompile these applications. PAM is also useful
+ for implementing a particular policy for authorization. For example,
+ a system administrator may only allow console logins from users
+ stored in the local password file but only allow users resolved from
+ a NIS database to log in over the network.</para>
+
+ <para>Winbind uses the authentication management and password
+ management PAM interface to integrate Windows NT users into a
+ UNIX system. This allows Windows NT users to log in to a UNIX
+ machine and be authenticated against a suitable Primary Domain
+ Controller. These users can also change their passwords and have
+ this change take effect directly on the Primary Domain Controller.
+ </para>
+
+ <para>PAM is configured by providing control files in the directory
+ <filename>/etc/pam.d/</filename> for each of the services that
+ require authentication. When an authentication request is made
+ by an application the PAM code in the C library looks up this
+ control file to determine what modules to load to do the
+ authentication check and in what order. This interface makes adding
+ a new authentication service for Winbind very easy, all that needs
+ to be done is that the <filename>pam_winbind.so</filename> module
+ is copied to <filename>/lib/security/</filename> and the PAM
+ control files for relevant services are updated to allow
+ authentication via winbind. See the PAM documentation
+ for more details.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>User and Group ID Allocation</title>
+
+ <para>When a user or group is created under Windows NT
+ is it allocated a numerical relative identifier (RID). This is
+ slightly different to UNIX which has a range of numbers that are
+ used to identify users, and the same range in which to identify
+ groups. It is winbind's job to convert RIDs to UNIX id numbers and
+ vice versa. When winbind is configured it is given part of the UNIX
+ user id space and a part of the UNIX group id space in which to
+ store Windows NT users and groups. If a Windows NT user is
+ resolved for the first time, it is allocated the next UNIX id from
+ the range. The same process applies for Windows NT groups. Over
+ time, winbind will have mapped all Windows NT users and groups
+ to UNIX user ids and group ids.</para>
+
+ <para>The results of this mapping are stored persistently in
+ an ID mapping database held in a tdb database). This ensures that
+ RIDs are mapped to UNIX IDs in a consistent way.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>Result Caching</title>
+
+ <para>An active system can generate a lot of user and group
+ name lookups. To reduce the network cost of these lookups winbind
+ uses a caching scheme based on the SAM sequence number supplied
+ by NT domain controllers. User or group information returned
+ by a PDC is cached by winbind along with a sequence number also
+ returned by the PDC. This sequence number is incremented by
+ Windows NT whenever any user or group information is modified. If
+ a cached entry has expired, the sequence number is requested from
+ the PDC and compared against the sequence number of the cached entry.
+ If the sequence numbers do not match, then the cached information
+ is discarded and up to date information is requested directly
+ from the PDC.</para>
+ </sect2>
+</sect1>
+
+
+<sect1>
+ <title>Installation and Configuration</title>
+
+<para>
+Many thanks to John Trostel <ulink
+url="mailto:jtrostel@snapserver.com">jtrostel@snapserver.com</ulink>
+for providing the original Linux version of this HOWTO which
+describes how to get winbind services up and running
+to control access and authenticate users on your Linux box using
+the winbind services which are included with the SAMBA 2.2.2 and later
+releases.
+</para>
+
+
+
+
+<sect2>
+<title>Introduction</title>
+
+<para>
+This HOWTO describes the procedures used to get winbind up and
+running on a RedHat 7.1 system. Winbind is capable of providing access
+and authentication control for Windows Domain users through an NT
+or Win2K PDC for 'regular' services, such as telnet and ftp, as
+well providing dynamic uid/gid allocation for Samba.
+</para>
+
+<para>
+This HOWTO has been written from a 'RedHat-centric' perspective, so if
+you are using another distribution (or operating system), you may have
+to modify the instructions somewhat to fit the way your distribution works.
+</para>
+
+
+<itemizedlist>
+<listitem>
+ <para>
+ <emphasis>Why should I to this?</emphasis>
+ </para>
+
+ <para>This allows the SAMBA administrator to rely on the
+ authentication mechanisms on the NT/Win2K PDC for the authentication
+ of domain members. NT/Win2K users no longer need to have separate
+ accounts on the SAMBA server.
+ </para>
+</listitem>
+
+<listitem>
+ <para>
+ <emphasis>Who should be reading this document?</emphasis>
+ </para>
+
+ <para>
+ This HOWTO is designed for system administrators. If you are
+ implementing SAMBA on a file server and wish to (fairly easily)
+ integrate existing NT/Win2K users from your PDC onto the
+ SAMBA server, this HOWTO is for you.
+ </para>
+</listitem>
+</itemizedlist>
+</sect2>
+
+
+<sect2>
+<title>Requirements</title>
+
+<para>
+If you have a samba configuration file that you are currently
+using... <emphasis>BACK IT UP!</emphasis> If your system already uses PAM,
+<emphasis>back up the <filename>/etc/pam.d</filename> (or <filename>/etc/pam.conf</filename>)
+directory contents!</emphasis> If you haven't already made a boot disk,
+<emphasis>MAKE ONE NOW!</emphasis>
+</para>
+
+<para>
+Messing with the pam configuration files can make it nearly impossible
+to log in to your machine. That's why you want to be able to boot back
+into your machine in single user mode and restore your
+<filename>/etc/pam.d</filename> (or <filename>pam.conmf</filename>) back to
+the original state they were in if
+you get frustrated with the way things are going.
+</para>
+
+<para>
+The first SAMBA release to inclue a stable winbindd daemon was 2.2.2. Please refer to the
+<ulink url="http://samba.org/">main SAMBA web page</ulink> or,
+better yet, your closest SAMBA mirror site for instructions on
+downloading the source code. it is generally advised to obtain the lates
+Samba release as bugs are constantly being fixed.
+</para>
+
+<para>
+To allow Domain users the ability to access SAMBA shares and
+files, as well as potentially other services provided by your
+SAMBA machine, PAM (pluggable authentication modules) must
+be setup properly on your machine. In order to compile the
+winbind modules, you must have at the PAM libraries and header files resident
+on your system. For recent RedHat systems (7.x, for instance), that
+means installing both <filename>pam</filename> and <filename>pam-devel</filename> RPM.
+The former is installed by default on all Linux systems of which the author is aware.
+</para>
+
+</sect2>
+
+
+<sect2>
+<title>Testing Things Out</title>
+
+<para>
+Before starting, kill off all the SAMBA related daemons running on your server. Kill off
+all <command>smbd</command>, <command>nmbd</command>, and <command>winbindd</command> processes that may
+be running (<command>winbindd</command> will only be running if you have ao previous Winbind
+installation...but why would you be reading tis if that were the case?). To use PAM, you will
+want to make sure that you have the standard PAM package (for RedHat) which supplies the <filename>/etc/pam.d</filename>
+directory structure, including the pam modules are used by pam-aware
+services, several pam libraries, and the <filename>/usr/doc</filename>
+and <filename>/usr/man</filename> entries for pam. Samba will require
+the pam-devel package if you plan to build the <filename>pam_winbind.so</filename> library or
+include the <command>--with-pam</command> option to the configure script.
+This package includes the header files needed to compile pam-aware applications.
+</para>
+
+<para>
+[I have no idea which Solaris packages are quired for PAM libraries and
+development files. If you know, please mail me the information and I will include
+it in the next revision of this HOWTO. --jerry@samba.org]
+</para>
+
+<sect3>
+<title>Configure and Compile SAMBA</title>
+
+<para>
+The configuration and compilation of SAMBA is straightforward.
+</para>
+
+<para><programlisting>
+<prompt>root#</prompt> <command>./configure --with-winbind</command>
+<prompt>root#</prompt> <command>make</command>
+<prompt>root#</prompt> <command>make install</command>
+</programlisting></para>
+
+
+<para>
+This will, by default, install SAMBA in <filename>/usr/local/samba</filename>.
+See the main SAMBA documentation if you want to install SAMBA somewhere else.
+It will also build the winbindd executable and NSS library.
+</para>
+
+</sect3>
+
+<sect3>
+<title>Configure <filename>nsswitch.conf</filename> and the
+winbind libraries</title>
+
+<para>
+The libraries needed to run the <command>winbindd</command> daemon
+through nsswitch need to be copied to their proper locations.
+</para>
+
+<para>
+<prompt>root#</prompt> <command>cp nsswitch/libnss_winbind.so /lib</command>
+<prompt>root#</prompt> <command>chmod 755 /lib/libnss_winbind.so</command>
+</para>
+
+<para>
+It necessary to make the following symbolic link:
+</para>
+
+<para>
+<prompt>root#</prompt> <command>ln -s /lib/libnss_winbind.so /lib/libnss_winbind.so.2</command>
+</para>
+
+<para>
+The <filename>.2</filename> extension is due to the version of glibc used on your Linux host.
+for most modern systems, the file extension is correct. However, some other operating systems,
+Solaris 7/8 being the most common, the destination filename should be replaced with
+<filename>/lib/nss_winbind.so.1</filename>
+</para>
+
+<para>
+Now, as root edit <filename>/etc/nsswitch.conf</filename> to
+allow user and group entries to be visible from the <command>winbindd</command>
+daemon. After editing, the file look appear:
+</para>
+
+<para><programlisting>
+ passwd: files winbind
+ shadow: files
+ group: files winbind
+</programlisting></para>
+
+</sect3>
+
+
+<sect3>
+<title>Configure <filename>smb.conf</filename></title>
+
+<para>
+Several parameters are needed in the smb.conf file to control
+the behavior of <command>winbindd</command>. Configure
+<filename>smb.conf</filename> These are described in more detail in
+the <ulink url="winbindd.8.html">winbindd(8)</ulink> man page. My
+<filename>smb.conf</filename> file was modified to
+include the following entries in the [global] section:
+</para>
+
+<para><programlisting>
+[global]
+ <...>
+ # separate domain and username with '+', like DOMAIN+username
+ <ulink url="winbindd.8.html#WINBINDSEPARATOR">winbind separator</ulink> = +
+ # use uids from 10000 to 20000 for domain users
+ <ulink url="winbindd.8.html#WINBINDUID">winbind uid</ulink> = 10000-20000
+ # use gids from 10000 to 20000 for domain groups
+ <ulink url="winbindd.8.html#WINBINDGID">winbind gid</ulink> = 10000-20000
+ # allow enumeration of winbind users and groups
+ # might need to disable these next two for performance
+ # reasons on the winbindd host
+ <ulink url="winbindd.8.html#WINBINDENUMUSERS">winbind enum users</ulink> = yes
+ <ulink url="winbindd.8.html#WINBINDENUMGROUP">winbind enum groups</ulink> = yes
+ # give winbind users a real shell (only needed if they have telnet/sshd/etc... access)
+ <ulink url="winbindd.8.html#TEMPLATEHOMEDIR">template homedir</ulink> = /home/winnt/%D/%U
+ <ulink url="winbindd.8.html#TEMPLATESHELL">template shell</ulink> = /bin/bash
+</programlisting></para>
+
+</sect3>
+
+
+<sect3>
+<title>Join the SAMBA server to the PDC domain</title>
+
+<para>
+Enter the following command to make the SAMBA server join the
+PDC domain, where <replaceable>DOMAIN</replaceable> is the name of
+your Windows domain and <replaceable>Administrator</replaceable> is
+a domain user who has administrative privileges in the domain.
+</para>
+
+
+<para>
+<prompt>root#</prompt> <command>/usr/local/samba/bin/smbpasswd -j DOMAIN -r PDC -U Administrator</command>
+</para>
+
+
+<para>
+The proper response to the command should be: "Joined the domain
+<replaceable>DOMAIN</replaceable>" where <replaceable>DOMAIN</replaceable>
+is your DOMAIN name.
+</para>
+
+</sect3>
+
+
+<sect3>
+<title>Start up the winbindd daemon and test it!</title>
+
+<para>
+Eventually, you will want to modify your smb startup script to
+automatically invoke the winbindd daemon when the other parts of
+SAMBA start, but it is possible to test out just the winbind
+portion first. To start up winbind services, enter the following
+command as root:
+</para>
+
+<para>
+<prompt>root#</prompt> <command>export PATH=$PATH:/usr/local/samba/bin</command>
+<prompt>root#</prompt> <command>winbindd</command>
+</para>
+
+<para>
+I'm always paranoid and like to make sure the daemon
+is really running...
+</para>
+
+<para>
+<prompt>root#</prompt> <command>ps -ae | grep winbindd</command>
+</para>
+<para>
+This command should produce output like this, if the daemon is running
+</para>
+<para>
+3025 ? 00:00:00 winbindd
+</para>
+
+<para>
+Note that a sample RedHat init script for starting winbindd is included in
+the SAMBA sourse distribution as <filename>packaging/RedHat/winbind.init</filename>.
+</para>
+
+<para>
+Now... for the real test, try to get some information about the
+users on your PDC
+</para>
+
+<para>
+<prompt>root#</prompt> <command>wbinfo -u</command>
+</para>
+
+<para>
+This should echo back a list of users on your Windows users on
+your PDC. For example, I get the following response:
+</para>
+
+<para><programlisting>
+CEO+Administrator
+CEO+burdell
+CEO+Guest
+CEO+jt-ad
+CEO+krbtgt
+CEO+TsInternetUser
+</programlisting></para>
+
+<para>
+Obviously, I have named my domain 'CEO' and my <parameter>winbind
+separator</parameter> is '+'.
+</para>
+
+<para>
+You can do the same sort of thing to get group information from
+the PDC:
+</para>
+
+<para><programlisting>
+<prompt>root#</prompt> <command>/usr/local/samba/bin/wbinfo -g</command>
+CEO+Domain Admins
+CEO+Domain Users
+CEO+Domain Guests
+CEO+Domain Computers
+CEO+Domain Controllers
+CEO+Cert Publishers
+CEO+Schema Admins
+CEO+Enterprise Admins
+CEO+Group Policy Creator Owners
+</programlisting></para>
+
+<para>
+The function 'getent' can now be used to get unified
+lists of both local and PDC users and groups.
+Try the following command:
+</para>
+
+<para>
+<prompt>root#</prompt> <command>getent passwd</command>
+</para>
+
+<para>
+You should get a list that looks like your <filename>/etc/passwd</filename>
+list followed by the domain users with their new uids, gids, home
+directories and default shells. If you do not, verify that the permissions on the
+libnss_winbind.so library are <filename>rwxr-xr-x</filename>.
+</para>
+
+<para>
+The same thing can be done for groups with the command
+</para>
+
+<para>
+<prompt>root#</prompt> <command>getent group</command>
+</para>
+
+</sect3>
+
+
+
+<sect3>
+<title>Configure Winbind and PAM</title>
+
+<para>
+At this point we are assured that <command>winbindd</command> and <command>smbd</command>
+are working together. If you want to use winbind to provide authentication for other
+services, keep reading. The pam configuration files need to be altered in
+this step. (Did you remember to make backups of your original
+<filename>/etc/pam.d</filename> (or <filename>/etc/pam.conf</filename>) file[s]? If not, do it now.)
+</para>
+
+<para>
+You will need a PAM module to use <command>winbindd</command> with these other services. This
+module will be compiled in the <filename>../source/nsswitch</filename> directory
+by invoking the command
+</para>
+
+<para>
+<prompt>root#</prompt> <command>make nsswitch/pam_winbind.so</command>
+</para>
+
+<para>
+from the <filename>../source</filename> directory. The
+<filename>pam_winbind.so</filename> file should be copied to the location of
+your other pam security modules. On Linux and Solaris systems, this is the
+<filename>/lib/security</filename> directory.
+</para>
+
+<para>
+<prompt>root#</prompt> <command>cp nsswitch/pam_winbind.so /lib/security</command>
+<prompt>root#</prompt> <command>chmod 755 /lib/security/pam_winbind.so</command>
+</para>
+
+<para>
+Other services, such as the normal login on the console (or a terminal
+session), telnet logins, and ftp service, can be modified to allow the use of winbind
+as an authentication service. In order to enable these
+services, you may first need to change the entries in
+<filename>/etc/xinetd.d</filename> (or <filename>/etc/inetd.conf</filename>).
+RedHat 7.1 uses the new xinetd.d structure, in this case you need
+to change the lines in <filename>/etc/xinetd.d/telnet</filename>
+and <filename>/etc/xinetd.d/wu-ftp</filename> from
+</para>
+
+<para><programlisting>
+enable = no
+</programlisting></para>
+
+<para>
+to
+</para>
+
+<para><programlisting>
+enable = yes
+</programlisting></para>
+
+<para>
+For ftp services to work properly, you will also need to either
+have individual directories for the domain users already present on
+the server, or change the home directory template to a general
+directory for all domain users. These can be easily set using
+the <filename>smb.conf</filename> global entry
+<command>template homedir</command>.
+</para>
+
+<para>
+The <filename>/etc/pam.d/ftp</filename> file can be changed
+to allow winbind ftp access in a manner similar to the
+samba file. My <filename>/etc/pam.d/ftp</filename> file was
+changed to look like this:
+</para>
+
+<para><programlisting>
+auth required /lib/security/pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_shells.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth
+</programlisting></para>
+
+<para>
+The <filename>/etc/pam.d/login</filename> file can be changed nearly the
+same way. It now looks like this:
+</para>
+
+<para><programlisting>
+auth required /lib/security/pam_securetty.so
+auth sufficient /lib/security/pam_winbind.so
+auth sufficient /lib/security/pam_unix.so use_first_pass
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_nologin.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+password required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth
+session optional /lib/security/pam_console.so
+</programlisting></para>
+
+<para>
+In this case, I added the <command>auth sufficient /lib/security/pam_winbind.so</command>
+lines as before, but also added the <command>required pam_securetty.so</command>
+above it, to disallow root logins over the network. I also added a
+<command>sufficient /lib/security/pam_unix.so use_first_pass</command>
+line after the <command>winbind.so</command> line to get rid of annoying
+double prompts for passwords.
+</para>
+
+
+<para>
+Note that a Solaris <filename>/etc/pam.conf</filename> confiruation file looks
+very similar to this except thaty the service name is included as the first entry
+per line. An example for the login service is given here.
+</para>
+
+<para><programlisting>
+## excerpt from /etc/pam.conf on a Solaris 8 system
+login auth required /lib/security/pam_winbind.so
+login auth required /lib/security/$ISA/pam_unix.so.1 try_first_pass
+login auth required /lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
+</programlisting></para>
+
+
+
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1>
+ <title>Limitations</title>
+
+ <para>Winbind has a number of limitations in its current
+ released version that we hope to overcome in future
+ releases:</para>
+
+ <itemizedlist>
+ <listitem><para>The mappings of Windows NT RIDs to UNIX ids
+ is not made algorithmically and depends on the order in which
+ unmapped users or groups are seen by winbind. It may be difficult
+ to recover the mappings of rid to UNIX id mapping if the file
+ containing this information is corrupted or destroyed.</para>
+ </listitem>
+
+ <listitem><para>Currently the winbind PAM module does not take
+ into account possible workstation and logon time restrictions
+ that may be been set for Windows NT users.</para></listitem>
+ </itemizedlist>
+</sect1>
+
+
+<sect1>
+ <title>Conclusion</title>
+
+ <para>The winbind system, through the use of the Name Service
+ Switch, Pluggable Authentication Modules, and appropriate
+ Microsoft RPC calls have allowed us to provide seamless
+ integration of Microsoft Windows NT domain users on a
+ UNIX system. The result is a great reduction in the administrative
+ cost of running a mixed UNIX and NT network.</para>
+
+</sect1>
+
+</chapter>
diff --git a/docs/docbook/scripts/README.ldp_print b/docs/docbook/scripts/README.ldp_print
new file mode 100755
index 00000000000..8d61a855343
--- /dev/null
+++ b/docs/docbook/scripts/README.ldp_print
@@ -0,0 +1,60 @@
+
+######################################################################
+ ldp_print - print tool/script for DocBook SGML/XML documents
+######################################################################
+
+This process/script is used in the production environment for the
+LDP. It relies on the HTMLDOC software package (GPL'ed) which can be
+obtained from the Easy Software Products (c) web site:
+
+ http://www.easysw.com/htmldoc/
+
+This process creates a PDF variant from the single-file HTML
+representation of a DocBook SGML (or XML) instance. The simple
+wrapper script (ldp_print) assumes that the file was created using
+{open}jade in a manner similar to:
+
+ jade -t sgml -i html -V nochunks -d $style $fname > $fname.html
+
+Give the script the filename as an argument. It will then parse the
+file into 'title.html' and 'body.html' and send each to htmldoc (as
+the corresponding title page and body of the document).
+
+
+CAVEATS
+=======
+
+o Assumes perl is in /usr/bin; adjust if necessary
+
+o You may need to specify where the htmldoc executable resides.
+ The script assumes it's within your $PATH.
+
+o If you want Postscript as an output variant, uncomment the
+ appropriate lines (see below).
+
+o Relies on output from a DocBook instance created via DSSSL/{open}jade!
+
+o Cleans up (removes) the intermediate files it creates (but not the
+ PDF or Postscript files, obviously!)
+
+o Works silently; PDF (PostScript) will be created in the same directory
+ as was specified for the input (single-file HTML) file.
+
+o Provided without warranty or support!
+
+o I ran into a problem with htmldoc v1.8.8 which required a source
+ code change (I was getting a core dump from the htmldoc process).
+ Here is the change required:
+
+ htmldoc/ps-pdf.cxx :
+ 3662,3665d3661
+ < /* gjf = 11Oct2000 */
+ < if( temprow == NULL )
+ < break;
+ <
+
+
+====
+gferg (at) sgi.com / Ferg
+11 Jan 2000
+
diff --git a/docs/docbook/scripts/collateindex.pl b/docs/docbook/scripts/collateindex.pl
new file mode 100755
index 00000000000..fd757edb320
--- /dev/null
+++ b/docs/docbook/scripts/collateindex.pl
@@ -0,0 +1,595 @@
+# -*- Perl -*-
+#
+
+use Getopt::Std;
+
+$usage = "Usage: $0 <opts> file
+Where <opts> are:
+ -p Link to points in the document. The default is to link
+ to the closest containing section.
+ -g Group terms with IndexDiv based on the first letter
+ of the term (or its sortas attribute).
+ (This probably doesn't handle i10n particularly well)
+ -s name Name the IndexDiv that contains symbols. The default
+ is 'Symbols'. Meaningless if -g is not used.
+ -t name Title for the index.
+ -P file Read a preamble from file. The content of file will
+ be inserted before the <index> tag.
+ -i id The ID for the <index> tag.
+ -o file Output to file. Defaults to stdout.
+ -S scope Scope of the index, must be 'all', 'local', or 'global'.
+ If unspecified, 'all' is assumed.
+ -I scope The implied scope, must be 'all', 'local', or 'global'.
+ IndexTerms which do not specify a scope will have the
+ implied scope. If unspecified, 'all' is assumed.
+ -x Make a SetIndex.
+ -f Force the output file to be written, even if it appears
+ to have been edited by hand.
+ -N New index (generates an empty index file).
+ file The file containing index data generated by Jade
+ with the DocBook HTML Stylesheet.\n";
+
+die $usage if ! getopts('Dfgi:NpP:s:o:S:I:t:x');
+
+$linkpoints = $opt_p;
+$lettergroups = $opt_g;
+$symbolsname = $opt_s || "Symbols";
+$title = $opt_t;
+$preamble = $opt_P;
+$outfile = $opt_o || '-';
+$indexid = $opt_i;
+$scope = uc($opt_S) || 'ALL';
+$impliedscope = uc($opt_I) || 'ALL';
+$setindex = $opt_x;
+$forceoutput = $opt_f;
+$newindex = $opt_N;
+$debug = $opt_D;
+
+$indextag = $setindex ? 'setindex' : 'index';
+
+if ($newindex) {
+ safe_open(*OUT, $outfile);
+ if ($indexid) {
+ print OUT "<$indextag id='$indexid'>\n\n";
+ } else {
+ print OUT "<$indextag>\n\n";
+ }
+
+ print OUT "<!-- This file was produced by collateindex.pl. -->\n";
+ print OUT "<!-- Remove this comment if you edit this file by hand! -->\n";
+
+ print OUT "</$indextag>\n";
+ exit 0;
+}
+
+$dat = shift @ARGV || die $usage;
+die "$0: cannot find $dat.\n" if ! -f $dat;
+
+%legal_scopes = ('ALL' => 1, 'LOCAL' => 1, 'GLOBAL' => 1);
+if ($scope && !$legal_scopes{$scope}) {
+ die "Invalid scope.\n$usage\n";
+}
+if ($impliedscope && !$legal_scopes{$impliedscope}) {
+ die "Invalid implied scope.\n$usage\n";
+}
+
+@term = ();
+%id = ();
+
+$termcount = 0;
+
+print STDERR "Processing $dat...\n";
+
+# Read the index file, creating an array of objects. Each object
+# represents and indexterm and has fields for the content of the
+# indexterm
+
+open (F, $dat);
+while (<F>) {
+ chop;
+
+ if (/^\/indexterm/i) {
+ push (@term, $idx);
+ next;
+ }
+
+ if (/^indexterm (.*)$/i) {
+ $termcount++;
+ $idx = {};
+ $idx->{'zone'} = {};
+ $idx->{'href'} = $1;
+ $idx->{'count'} = $termcount;
+ $idx->{'scope'} = $impliedscope;
+ next;
+ }
+
+ if (/^indexpoint (.*)$/i) {
+ $idx->{'hrefpoint'} = $1;
+ next;
+ }
+
+ if (/^title (.*)$/i) {
+ $idx->{'title'} = $1;
+ next;
+ }
+
+ if (/^primary[\[ ](.*)$/i) {
+ if (/^primary\[(.*?)\] (.*)$/i) {
+ $idx->{'psortas'} = $1;
+ $idx->{'primary'} = $2;
+ } else {
+ $idx->{'psortas'} = $1;
+ $idx->{'primary'} = $1;
+ }
+ next;
+ }
+
+ if (/^secondary[\[ ](.*)$/i) {
+ if (/^secondary\[(.*?)\] (.*)$/i) {
+ $idx->{'ssortas'} = $1;
+ $idx->{'secondary'} = $2;
+ } else {
+ $idx->{'ssortas'} = $1;
+ $idx->{'secondary'} = $1;
+ }
+ next;
+ }
+
+ if (/^tertiary[\[ ](.*)$/i) {
+ if (/^tertiary\[(.*?)\] (.*)$/i) {
+ $idx->{'tsortas'} = $1;
+ $idx->{'tertiary'} = $2;
+ } else {
+ $idx->{'tsortas'} = $1;
+ $idx->{'tertiary'} = $1;
+ }
+ next;
+ }
+
+ if (/^see (.*)$/i) {
+ $idx->{'see'} = $1;
+ next;
+ }
+
+ if (/^seealso (.*)$/i) {
+ $idx->{'seealso'} = $1;
+ next;
+ }
+
+ if (/^significance (.*)$/i) {
+ $idx->{'significance'} = $1;
+ next;
+ }
+
+ if (/^class (.*)$/i) {
+ $idx->{'class'} = $1;
+ next;
+ }
+
+ if (/^scope (.*)$/i) {
+ $idx->{'scope'} = uc($1);
+ next;
+ }
+
+ if (/^startref (.*)$/i) {
+ $idx->{'startref'} = $1;
+ next;
+ }
+
+ if (/^id (.*)$/i) {
+ $idx->{'id'} = $1;
+ $id{$1} = $idx;
+ next;
+ }
+
+ if (/^zone (.*)$/i) {
+ my($href) = $1;
+ $_ = scalar(<F>);
+ chop;
+ die "Bad zone: $_\n" if !/^title (.*)$/i;
+ $idx->{'zone'}->{$href} = $1;
+ next;
+ }
+
+ die "Unrecognized: $_\n";
+}
+close (F);
+
+print STDERR "$termcount entries loaded...\n";
+
+# Fixup the startrefs...
+# In DocBook, STARTREF is a #CONREF attribute; support this by copying
+# all of the fields from the indexterm with the id specified by STARTREF
+# to the indexterm that has the STARTREF.
+foreach $idx (@term) {
+ my($ididx, $field);
+ if ($idx->{'startref'}) {
+ $ididx = $id{$idx->{'startref'}};
+ foreach $field ('primary', 'secondary', 'tertiary', 'see', 'seealso',
+ 'psortas', 'ssortas', 'tsortas', 'significance',
+ 'class', 'scope') {
+ $idx->{$field} = $ididx->{$field};
+ }
+ }
+}
+
+# Sort the index terms
+@term = sort termsort @term;
+
+# Move all of the non-alphabetic entries to the front of the index.
+@term = sortsymbols(@term);
+
+safe_open(*OUT, $outfile);
+
+# Write the index...
+if ($indexid) {
+ print OUT "<$indextag id='$indexid'>\n\n";
+} else {
+ print OUT "<$indextag>\n\n";
+}
+
+print OUT "<!-- This file was produced by collateindex.pl. -->\n";
+print OUT "<!-- Remove this comment if you edit this file by hand! -->\n";
+
+print OUT "<!-- ULINK is abused here.
+
+ The URL attribute holds the URL that points from the index entry
+ back to the appropriate place in the output produced by the HTML
+ stylesheet. (It's much easier to calculate this URL in the first
+ pass.)
+
+ The Role attribute holds the ID (either real or manufactured) of
+ the corresponding INDEXTERM. This is used by the print backends
+ to produce page numbers.
+
+ The entries below are sorted and collated into the correct order.
+ Duplicates may be removed in the HTML backend, but in the print
+ backends, it is impossible to suppress duplicate pages or coalesce
+ sequences of pages into a range.
+-->\n\n";
+
+print OUT "<title>$title</title>\n\n" if $title;
+
+$last = {}; # the last indexterm we processed
+$first = 1; # this is the first one
+$group = ""; # we're not in a group yet
+$lastout = ""; # we've not put anything out yet
+
+foreach $idx (@term) {
+ next if $idx->{'startref'}; # no way to represent spans...
+ next if ($idx->{'scope'} eq 'LOCAL') && ($scope eq 'GLOBAL');
+ next if ($idx->{'scope'} eq 'GLOBAL') && ($scope eq 'LOCAL');
+ next if &same($idx, $last); # suppress duplicates
+
+ $termcount--;
+
+ # If primary changes, output a whole new index term, otherwise just
+ # output another secondary or tertiary, as appropriate. We know from
+ # sorting that the terms will always be in the right order.
+ if (!&tsame($last, $idx, 'primary')) {
+ print "DIFF PRIM\n" if $debug;
+ &end_entry() if not $first;
+
+ if ($lettergroups) {
+ # If we're grouping, make the right indexdivs
+ $letter = $idx->{'psortas'};
+ $letter = $idx->{'primary'} if !$letter;
+ $letter = uc(substr($letter, 0, 1));
+
+ # symbols are a special case
+ if (($letter lt 'A') || ($letter gt 'Z')) {
+ if (($group eq '')
+ || (($group ge 'A') && ($group le 'Z'))) {
+ print OUT "</indexdiv>\n" if !$first;
+ print OUT "<indexdiv><title>$symbolsname</title>\n\n";
+ $group = $letter;
+ }
+ } elsif (($group eq '') || ($group ne $letter)) {
+ print OUT "</indexdiv>\n" if !$first;
+ print OUT "<indexdiv><title>$letter</title>\n\n";
+ $group = $letter;
+ }
+ }
+
+ $first = 0; # there can only be on first ;-)
+
+ print OUT "<indexentry>\n";
+ print OUT " <primaryie>", $idx->{'primary'};
+ $lastout = "primaryie";
+
+ if ($idx->{'secondary'}) {
+ print OUT "\n </primaryie>\n";
+ print OUT " <secondaryie>", $idx->{'secondary'};
+ $lastout = "secondaryie";
+ };
+
+ if ($idx->{'tertiary'}) {
+ print OUT "\n </secondaryie>\n";
+ print OUT " <tertiaryie>", $idx->{'tertiary'};
+ $lastout = "tertiaryie";
+ }
+ } elsif (!&tsame($last, $idx, 'secondary')) {
+ print "DIFF SEC\n" if $debug;
+
+ print OUT "\n </$lastout>\n" if $lastout;
+
+ print OUT " <secondaryie>", $idx->{'secondary'};
+ $lastout = "secondaryie";
+ if ($idx->{'tertiary'}) {
+ print OUT "\n </secondaryie>\n";
+ print OUT " <tertiaryie>", $idx->{'tertiary'};
+ $lastout = "tertiaryie";
+ }
+ } elsif (!&tsame($last, $idx, 'tertiary')) {
+ print "DIFF TERT\n" if $debug;
+
+ print OUT "\n </$lastout>\n" if $lastout;
+
+ if ($idx->{'tertiary'}) {
+ print OUT " <tertiaryie>", $idx->{'tertiary'};
+ $lastout = "tertiaryie";
+ }
+ }
+
+ &print_term($idx);
+
+ $last = $idx;
+}
+
+# Termcount is > 0 iff some entries were skipped.
+print STDERR "$termcount entries ignored...\n";
+
+&end_entry();
+
+print OUT "</indexdiv>\n" if $lettergroups;
+print OUT "</$indextag>\n";
+
+close (OUT);
+
+print STDERR "Done.\n";
+
+sub same {
+ my($a) = shift;
+ my($b) = shift;
+
+ my($aP) = $a->{'psortas'} || $a->{'primary'};
+ my($aS) = $a->{'ssortas'} || $a->{'secondary'};
+ my($aT) = $a->{'tsortas'} || $a->{'tertiary'};
+
+ my($bP) = $b->{'psortas'} || $b->{'primary'};
+ my($bS) = $b->{'ssortas'} || $b->{'secondary'};
+ my($bT) = $b->{'tsortas'} || $b->{'tertiary'};
+
+ my($same);
+
+ $aP =~ s/^\s*//; $aP =~ s/\s*$//; $aP = uc($aP);
+ $aS =~ s/^\s*//; $aS =~ s/\s*$//; $aS = uc($aS);
+ $aT =~ s/^\s*//; $aT =~ s/\s*$//; $aT = uc($aT);
+ $bP =~ s/^\s*//; $bP =~ s/\s*$//; $bP = uc($bP);
+ $bS =~ s/^\s*//; $bS =~ s/\s*$//; $bS = uc($bS);
+ $bT =~ s/^\s*//; $bT =~ s/\s*$//; $bT = uc($bT);
+
+# print "[$aP]=[$bP]\n";
+# print "[$aS]=[$bS]\n";
+# print "[$aT]=[$bT]\n";
+
+ # Two index terms are the same if:
+ # 1. the primary, secondary, and tertiary entries are the same
+ # (or have the same SORTAS)
+ # AND
+ # 2. They occur in the same titled section
+ # AND
+ # 3. They point to the same place
+ #
+ # Notes: Scope is used to suppress some entries, but can't be used
+ # for comparing duplicates.
+ # Interpretation of "the same place" depends on whether or
+ # not $linkpoints is true.
+
+ $same = (($aP eq $bP)
+ && ($aS eq $bS)
+ && ($aT eq $bT)
+ && ($a->{'title'} eq $b->{'title'})
+ && ($a->{'href'} eq $b->{'href'}));
+
+ # If we're linking to points, they're only the same if they link
+ # to exactly the same spot. (surely this is redundant?)
+ $same = $same && ($a->{'hrefpoint'} eq $b->{'hrefpoint'})
+ if $linkpoints;
+
+ $same;
+}
+
+sub tsame {
+ # Unlike same(), tsame only compares a single term
+ my($a) = shift;
+ my($b) = shift;
+ my($term) = shift;
+ my($sterm) = substr($term, 0, 1) . "sortas";
+ my($A, $B);
+
+ $A = $a->{$sterm} || $a->{$term};
+ $B = $b->{$sterm} || $b->{$term};
+
+ $A =~ s/^\s*//; $A =~ s/\s*$//; $A = uc($A);
+ $B =~ s/^\s*//; $B =~ s/\s*$//; $B = uc($B);
+
+ return $A eq $B;
+}
+
+sub end_entry {
+ # End any open elements...
+ print OUT "\n </$lastout>\n" if $lastout;
+ print OUT "</indexentry>\n\n";
+ $lastout = "";
+}
+
+sub print_term {
+ # Print out the links for an indexterm. There can be more than
+ # one if the term has a ZONE that points to more than one place.
+ # (do we do the right thing in that case?)
+ my($idx) = shift;
+ my($key, $indent, @hrefs);
+ my(%href) = ();
+ my(%phref) = ();
+
+ $indent = " ";
+
+ if ($idx->{'see'}) {
+ # it'd be nice to make this a link...
+ if ($lastout) {
+ print OUT "\n </$lastout>\n";
+ $lastout = "";
+ }
+ print OUT $indent, "<seeie>", $idx->{'see'}, "</seeie>\n";
+ return;
+ }
+
+ if ($idx->{'seealso'}) {
+ # it'd be nice to make this a link...
+ if ($lastout) {
+ print OUT "\n </$lastout>\n";
+ $lastout = "";
+ }
+ print OUT $indent, "<seealsoie>", $idx->{'seealso'}, "</seealsoie>\n";
+ return;
+ }
+
+ if (keys %{$idx->{'zone'}}) {
+ foreach $key (keys %{$idx->{'zone'}}) {
+ $href{$key} = $idx->{'zone'}->{$key};
+ $phref{$key} = $idx->{'zone'}->{$key};
+ }
+ } else {
+ $href{$idx->{'href'}} = $idx->{'title'};
+ $phref{$idx->{'href'}} = $idx->{'hrefpoint'};
+ }
+
+ # We can't use <LINK> because we don't know the ID of the term in the
+ # original source (and, in fact, it might not have one).
+ print OUT ",\n";
+ @hrefs = keys %href;
+ while (@hrefs) {
+ my($linkend) = "";
+ my($role) = "";
+ $key = shift @hrefs;
+ if ($linkpoints) {
+ $linkend = $phref{$key};
+ } else {
+ $linkend = $key;
+ }
+
+ $role = $linkend;
+ $role = $1 if $role =~ /\#(.*)$/;
+
+ print OUT $indent;
+ print OUT "<ulink url=\"$linkend\" role=\"$role\">";
+ print OUT "<emphasis>" if ($idx->{'significance'} eq 'PREFERRED');
+ print OUT $href{$key};
+ print OUT "</emphasis>" if ($idx->{'significance'} eq 'PREFERRED');
+ print OUT "</ulink>";
+ }
+}
+
+sub termsort {
+ my($aP) = $a->{'psortas'} || $a->{'primary'};
+ my($aS) = $a->{'ssortas'} || $a->{'secondary'};
+ my($aT) = $a->{'tsortas'} || $a->{'tertiary'};
+ my($ap) = $a->{'count'};
+
+ my($bP) = $b->{'psortas'} || $b->{'primary'};
+ my($bS) = $b->{'ssortas'} || $b->{'secondary'};
+ my($bT) = $b->{'tsortas'} || $b->{'tertiary'};
+ my($bp) = $b->{'count'};
+
+ $aP =~ s/^\s*//; $aP =~ s/\s*$//; $aP = uc($aP);
+ $aS =~ s/^\s*//; $aS =~ s/\s*$//; $aS = uc($aS);
+ $aT =~ s/^\s*//; $aT =~ s/\s*$//; $aT = uc($aT);
+ $bP =~ s/^\s*//; $bP =~ s/\s*$//; $bP = uc($bP);
+ $bS =~ s/^\s*//; $bS =~ s/\s*$//; $bS = uc($bS);
+ $bT =~ s/^\s*//; $bT =~ s/\s*$//; $bT = uc($bT);
+
+ if ($aP eq $bP) {
+ if ($aS eq $bS) {
+ if ($aT eq $bT) {
+ # make sure seealso's always sort to the bottom
+ return 1 if ($a->{'seealso'});
+ return -1 if ($b->{'seealso'});
+ # if everything else is the same, keep these elements
+ # in document order (so the index links are in the right
+ # order)
+ return $ap <=> $bp;
+ } else {
+ return $aT cmp $bT;
+ }
+ } else {
+ return $aS cmp $bS;
+ }
+ } else {
+ return $aP cmp $bP;
+ }
+}
+
+sub sortsymbols {
+ my(@term) = @_;
+ my(@new) = ();
+ my(@sym) = ();
+ my($letter);
+ my($idx);
+
+ # Move the non-letter things to the front. Should digits be thier
+ # own group? Maybe...
+ foreach $idx (@term) {
+ $letter = $idx->{'psortas'};
+ $letter = $idx->{'primary'} if !$letter;
+ $letter = uc(substr($letter, 0, 1));
+
+ if (($letter lt 'A') || ($letter gt 'Z')) {
+ push (@sym, $idx);
+ } else {
+ push (@new, $idx);
+ }
+ }
+
+ return (@sym, @new);
+}
+
+sub safe_open {
+ local(*OUT) = shift;
+ local(*F, $_);
+
+ if (($outfile ne '-') && (!$forceoutput)) {
+ my($handedit) = 1;
+ if (open (OUT, $outfile)) {
+ while (<OUT>) {
+ if (/<!-- Remove this comment if you edit this file by hand! -->/){
+ $handedit = 0;
+ last;
+ }
+ }
+ close (OUT);
+ } else {
+ $handedit = 0;
+ }
+
+ if ($handedit) {
+ print "\n$outfile appears to have been edited by hand; use -f or\n";
+ print " change the output file.\n";
+ exit 1;
+ }
+ }
+
+ open (OUT, ">$outfile") || die "$usage\nCannot write to $outfile.\n";
+
+ if ($preamble) {
+ # Copy the preamble
+ if (open(F, $preamble)) {
+ while (<F>) {
+ print OUT $_;
+ }
+ close(F);
+ } else {
+ warn "$0: cannot open preamble $preamble.\n";
+ }
+ }
+}
diff --git a/docs/docbook/scripts/fix_print_html.lib b/docs/docbook/scripts/fix_print_html.lib
new file mode 100755
index 00000000000..e8a9aaa4c77
--- /dev/null
+++ b/docs/docbook/scripts/fix_print_html.lib
@@ -0,0 +1,172 @@
+#
+# fix_print_html.lib
+#
+# Dan Scott / <dan.scott (at) acm.org>
+# Ferg / <gferg (at) sgi.com>
+#
+# Used to prepare single-file HTML variant for PDF/Postscript creation
+# thru htmldoc.
+#
+# log:
+# 16Oct2000 - initial entry <gferg (at) sgi.com>
+# 03Apr2001 - fix for <preface>
+#
+#
+
+sub fix_print_html {
+
+ my($in,$out,$ttl) = @_;
+
+ open(IN_FILE, "< $in") || do {
+ print "fix_print_html: cannot open $in: $!\n";
+ return 0;
+ };
+
+ my($buf,$ttl_buf) = '';
+ my($indx) = -1;
+ my($is_article) = 0;
+ while(<IN_FILE>) {
+
+ if( $indx == 1 ) {
+
+ # ignore everything until we see the chapter or sect
+ #
+ if( $_ =~ /CLASS="CHAP/i || $_ =~ /CLASS="PREF/i ) {
+
+ $buf .= $_;
+ $indx++;
+
+ } elsif( $_ =~ /CLASS="SECT/ || $_ =~ /CLASS="sect/ ) {
+
+ $buf .= $_;
+ $indx++;
+ $is_article = 1;
+
+ } else {
+ next;
+ }
+
+ } elsif( $indx == 0 ) {
+
+ # write out the title page file
+ #
+ if( $_ =~ /CLASS="TOC"/ ) {
+
+ $ttl_buf .= "></DIV>\n</BODY>\n</HTML>\n";
+ $ttl_buf =~ s/<\/H1\n/<\/H1\n><P><BR><BR\n/ms;
+
+ open(TOC_FILE, "> $ttl") || do {
+ print "fix_print_html: cannot open $ttl: $!\n";
+ close(IN_FILE);
+ return 0;
+ };
+ print TOC_FILE $ttl_buf;
+ close(TOC_FILE);
+ $ttl_buf = '';
+ $indx++;
+
+ } else {
+ $ttl_buf .= $_;
+ }
+
+ } elsif( $indx < 0 ) {
+
+ # up to this point, both buffers get the line
+ #
+ if( $_ =~ /CLASS="TITLEPAGE"/ ) {
+
+ $ttl_buf .= $_ . ">\n<P>\n<BR><BR><BR><BR>\n<\/P\n";
+ $indx++;
+
+ } else {
+ $buf .= $_;
+ $ttl_buf .= $_;
+ }
+
+ } else {
+
+ $buf .= $_;
+ }
+ }
+ close(IN_FILE);
+
+ open(OUT_FILE, "> $out") || do {
+ print "fix_print_html: cannot open $out: $!\n";
+ return 0;
+ };
+
+
+ # make these corrections and write out the file
+ #
+
+ $buf =~ s/(\n><LI\n)><P\n(.*?)<\/P\n>/$1$2\n/gms;
+ $buf =~ s/(\n><LI\n><DIV\nCLASS="FORMALPARA"\n)><P\n(.*?)<\/P\n>/$1$2\n/gms;
+ $buf =~ s/(\n><LI\nSTYLE="[^\"]+"\n)><P\n(.*?)<\/P\n>/$1$2\n/gms;
+ if( $is_article == 0 ) {
+ $buf =~ s/(\nCLASS="SECT[TION\d]+"\n>)<H1\n(.*?)<\/H1/$1<H2\n$2<\/H2/gims;
+ $buf =~ s/(\nCLASS="SECT[TION\d]+"\n><HR>)<H1\n(.*?)<\/H1/$1<H2\n$2<\/H2/gims;
+ }
+ $buf =~ s/<H1(\nCLASS="INDEXDIV"\n)(.*?)<\/H1/<H2$1$2<\/H2/gims;
+ if( ($indx = rindex($buf, "<H1\n><A\nNAME=\"DOC-INDEX\"")) > -1 ) {
+ $buf = substr($buf, 0, $indx);
+ $buf .= "\n<\/BODY>\n<\/HTML>\n\n";
+ } elsif( ($indx = rindex($buf, "<H1\n><A\nNAME=\"doc-index\"")) > -1 ) {
+ $buf = substr($buf, 0, $indx);
+ $buf .= "\n<\/BODY>\n<\/HTML>\n\n";
+ }
+ $buf =~ s/\&\#13;//g;
+ $buf =~ s/\&\#60;/\&lt;/g;
+ $buf =~ s/\&\#62;/\&gt;/g;
+ $buf =~ s/\&\#8211;/\-/g;
+ $buf =~ s/WIDTH=\"\d\"//g;
+ $buf =~ s/><[\/]*TBODY//g;
+ $buf =~ s/><[\/]*THEAD//g;
+ $buf =~ s/TYPE=\"1\"\n//gim;
+
+ if( $is_article == 0 ) {
+
+ # for books...decrement the headers by 1 and then re-set the
+ # chapter level only to H1...
+ #
+ my($cnt,$j) = 0;
+ for($cnt=5; $cnt > 0; $cnt--) {
+ $j = $cnt + 1;
+ $buf =~ s/<H${cnt}/<H${j}/g;
+ $buf =~ s/<\/H${cnt}/<\/H${j}/g;
+ }
+
+ my(@l) = split(/\n/, $buf);
+ for( $cnt=0; $cnt < (@l + 0); $cnt++ ) {
+
+ if( $j == 1 ) {
+ if( $l[$cnt] =~ /<DIV/ ) {
+ $j = 0;
+ next;
+ }
+ $l[$cnt] =~ s/<H2/<H1/g;
+ $l[$cnt] =~ s/<\/H2/<\/H1/g;
+ }
+ if( $l[$cnt] =~ /^CLASS=\"CHAP/i
+ ||
+ $l[$cnt] =~ /^CLASS=\"PREF/i ) {
+ $j = 1;
+ }
+ }
+
+ $buf = join("\n", @l);
+
+ }
+ $buf =~ s/><DIV\nCLASS="\w+"\n//gms;
+ $buf =~ s/><\/DIV\n//gms;
+ $buf =~ s/(><LI\n)><P\n(.*?)<\/P\n>(<\/LI\n)/$1$2$3/gms;
+
+ print OUT_FILE $buf;
+ close(OUT_FILE);
+
+ return 1;
+}
+
+# Return true from package include
+#
+1;
+
diff --git a/docs/docbook/scripts/ldp_print b/docs/docbook/scripts/ldp_print
new file mode 100755
index 00000000000..70bb801def4
--- /dev/null
+++ b/docs/docbook/scripts/ldp_print
@@ -0,0 +1,71 @@
+#!/usr/bin/perl -w
+#
+# usage: ldp_print <single_file.html>
+#
+# Creates a PDF variant of a single-file HTML representation of a
+# DocBook SGML (or XML) instance. This simple wrapper assumes that
+# the file was created using {open}jade in a manner similar to:
+#
+# jade -t sgml -i html -V nochunks -d $style $fname > $fname.html
+#
+# Give this script the filename as an argument. It will then parse
+# the file into 'title.html' and 'body.html' and send each to
+# htmldoc (as the corresponding title page and body of the document).
+#
+#
+# CAVEATS:
+#
+# Assumes perl is in /usr/bin; adjust if necessary
+#
+# You may need to specify where the htmldoc executable resides.
+# The script assumes it's within your $PATH.
+#
+# If you want Postscript as an output variant, uncomment the
+# appropriate lines (see below).
+#
+# Relies on output from a DocBook instance created via DSSSL/{open}jade!
+#
+# Cleans up (removes) the intermediate files it creates (but not the
+# PDF or Postscript files, obviously!)
+#
+# Works silently; PDF (PostScript) will be created in the same directory
+# as was specified for the input (single-file HTML) file.
+#
+# Provided without warranty or support!
+#
+# gferg@sgi.com / Ferg (used as part of the LDP production env)
+#
+
+use strict;
+push(@INC, "./");
+require 'fix_print_html.lib';
+
+if( $ARGV[0] eq '' || !(-r $ARGV[0]) ) {
+ die "\nusage: ldp_print <single_file.html>\n\n";
+}
+
+my($fname_wo_ext) = $ARGV[0];
+$fname_wo_ext =~ s/\.[\w]+$//;
+
+
+# create new files from single HTML file to use for print
+#
+&fix_print_html($ARGV[0], 'body.html', 'title.html');
+
+my($cmd) = "htmldoc --size universal -t pdf -f ${fname_wo_ext}.pdf " .
+ "--firstpage p1 --titlefile title.html body.html";
+
+# For postscript output; append onto the above cmd string:
+#
+# "; htmldoc --size universal -t ps -f -f ${fname_wo_ext}.ps " .
+# "--firstpage p1 --titlefile title.html body.html";
+#
+system($cmd);
+die "\nldp_print: could not create ${fname_wo_ext}.pdf ($!)\n" if ($?);
+
+# cleanup
+#
+system("rm -f body.html title.html");
+
+exit(0);
+
diff --git a/docs/docbook/scripts/make-article.pl b/docs/docbook/scripts/make-article.pl
new file mode 100755
index 00000000000..d1f8c668326
--- /dev/null
+++ b/docs/docbook/scripts/make-article.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+
+$ignore = 0;
+
+print "<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.1//EN\">\n";
+
+while (<STDIN>) {
+
+ $_ =~ s/<chapter/<article/g;
+ $_ =~ s/<\/chapter/<\/article/g;
+
+ if ( $_ =~ '<articleinfo>') {
+ $ignore = 1;
+ }
+
+ if ( $_ =~ '</articleinfo>') {
+ $ignore = 0;
+ $_ = "";
+ }
+
+
+ if (! $ignore) { print "$_"; }
+
+
+}
diff --git a/docs/docbook/scripts/strip-links.pl b/docs/docbook/scripts/strip-links.pl
new file mode 100755
index 00000000000..66bc101e086
--- /dev/null
+++ b/docs/docbook/scripts/strip-links.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+## small script to strip the <URL:...> tags from
+## manpages generated from docbook2man. we'll leave
+## the <URL:ftp://...> and <URL:mailto:...> links for now
+
+while (<STDIN>) {
+
+ chomp ($_);
+ $_ =~ s/\s*<URL:.*html.*>\s+/ /g;
+ $_ =~ s/\s*<URL:.*html.*>\S//g;
+ $_ =~ s/\s*<URL:.*html.*>$//g;
+ print "$_\n";
+
+}
+exit 0;
diff --git a/docs/docbook/stylesheets/ldp.dsl.in b/docs/docbook/stylesheets/ldp.dsl.in
new file mode 100755
index 00000000000..d6e06f4b6d1
--- /dev/null
+++ b/docs/docbook/stylesheets/ldp.dsl.in
@@ -0,0 +1,256 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY % html "IGNORE">
+<![%html;[
+<!ENTITY % print "IGNORE">
+<!ENTITY docbook.dsl SYSTEM "@SGML_SHARE@/dsssl/docbook/html/docbook.dsl" CDATA dsssl>
+]]>
+<!ENTITY % print "INCLUDE">
+<![%print;[
+<!ENTITY docbook.dsl SYSTEM "@SGML_SHARE@/dsssl/docbook/print/docbook.dsl" CDATA dsssl>
+]]>
+]>
+
+<style-sheet>
+
+<style-specification id="print" use="docbook">
+<style-specification-body>
+
+;; ==============================
+;; customize the print stylesheet
+;; ==============================
+
+(declare-characteristic preserve-sdata?
+ ;; this is necessary because right now jadetex does not understand
+ ;; symbolic entities, whereas things work well with numeric entities.
+ "UNREGISTERED::James Clark//Characteristic::preserve-sdata?"
+ #f)
+
+(define %generate-article-toc%
+ ;; Should a Table of Contents be produced for Articles?
+ #t)
+
+(define (toc-depth nd)
+ 2)
+
+(define %generate-article-titlepage-on-separate-page%
+ ;; Should the article title page be on a separate page?
+ #t)
+
+(define %section-autolabel%
+ ;; Are sections enumerated?
+ #t)
+
+(define %footnote-ulinks%
+ ;; Generate footnotes for ULinks?
+ #f)
+
+(define %bop-footnotes%
+ ;; Make "bottom-of-page" footnotes?
+ #f)
+
+(define %body-start-indent%
+ ;; Default indent of body text
+ 0pi)
+
+(define %para-indent-firstpara%
+ ;; First line start-indent for the first paragraph
+ 0pt)
+
+(define %para-indent%
+ ;; First line start-indent for paragraphs (other than the first)
+ 0pt)
+
+(define %block-start-indent%
+ ;; Extra start-indent for block-elements
+ 0pt)
+
+(define formal-object-float
+ ;; Do formal objects float?
+ #t)
+
+(define %hyphenation%
+ ;; Allow automatic hyphenation?
+ #t)
+
+(define %admon-graphics%
+ ;; Use graphics in admonitions?
+ #f)
+
+</style-specification-body>
+</style-specification>
+
+
+<!--
+;; ===================================================
+;; customize the html stylesheet; borrowed from Cygnus
+;; at http://sourceware.cygnus.com/ (cygnus-both.dsl)
+;; ===================================================
+-->
+
+<style-specification id="html" use="docbook">
+<style-specification-body>
+
+(declare-characteristic preserve-sdata?
+ ;; this is necessary because right now jadetex does not understand
+ ;; symbolic entities, whereas things work well with numeric entities.
+ "UNREGISTERED::James Clark//Characteristic::preserve-sdata?"
+ #f)
+
+(define %generate-legalnotice-link%
+ ;; put the legal notice in a separate file
+ #t)
+
+(define %admon-graphics-path%
+ ;; use graphics in admonitions, set their
+ "../images/")
+
+(define %admon-graphics%
+ #f)
+
+(define %funcsynopsis-decoration%
+ ;; make funcsynopsis look pretty
+ #t)
+
+(define %html-ext%
+ ;; when producing HTML files, use this extension
+ ".html")
+
+(define %generate-book-toc%
+ ;; Should a Table of Contents be produced for books?
+ #t)
+
+(define %generate-article-toc%
+ ;; Should a Table of Contents be produced for articles?
+ #t)
+
+(define %generate-part-toc%
+ ;; Should a Table of Contents be produced for parts?
+ #t)
+
+(define %generate-book-titlepage%
+ ;; produce a title page for books
+ #t)
+
+(define %generate-article-titlepage%
+ ;; produce a title page for articles
+ #t)
+
+(define (chunk-skip-first-element-list)
+ ;; forces the Table of Contents on separate page
+ '())
+
+(define (list-element-list)
+ ;; fixes bug in Table of Contents generation
+ '())
+
+(define %root-filename%
+ ;; The filename of the root HTML document (e.g, "index").
+ "index")
+
+(define %shade-verbatim%
+ ;; verbatim sections will be shaded if t(rue)
+ #t)
+
+(define %use-id-as-filename%
+ ;; Use ID attributes as name for component HTML files?
+ #t)
+
+(define %graphic-extensions%
+ ;; graphic extensions allowed
+ '("gif" "png" "jpg" "jpeg" "tif" "tiff" "eps" "epsf" ))
+
+(define %graphic-default-extension%
+ "gif")
+
+(define %section-autolabel%
+ ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.)
+ #t)
+
+(define (toc-depth nd)
+ ;; more depth (2 levels) to toc; instead of flat hierarchy
+ ;; 2)
+ 4)
+
+(element emphasis
+ ;; make role=strong equate to bold for emphasis tag
+ (if (equal? (attribute-string "role") "strong")
+ (make element gi: "STRONG" (process-children))
+ (make element gi: "EM" (process-children))))
+
+(define (book-titlepage-recto-elements)
+ ;; elements on a book's titlepage
+ ;; note: added revhistory to the default list
+ (list (normalize "title")
+ (normalize "subtitle")
+ (normalize "graphic")
+ (normalize "mediaobject")
+ (normalize "corpauthor")
+ (normalize "authorgroup")
+ (normalize "author")
+ (normalize "editor")
+ (normalize "copyright")
+ (normalize "revhistory")
+ (normalize "abstract")
+ (normalize "legalnotice")))
+
+(define (article-titlepage-recto-elements)
+ ;; elements on an article's titlepage
+ ;; note: added othercredit to the default list
+ (list (normalize "title")
+ (normalize "subtitle")
+ (normalize "authorgroup")
+ (normalize "author")
+ (normalize "othercredit")
+ (normalize "releaseinfo")
+ (normalize "copyright")
+ (normalize "pubdate")
+ (normalize "revhistory")
+ (normalize "abstract")))
+
+(mode article-titlepage-recto-mode
+
+ (element contrib
+ ;; print out with othercredit information; for translators, etc.
+ (make sequence
+ (make element gi: "SPAN"
+ attributes: (list (list "CLASS" (gi)))
+ (process-children))))
+
+ (element othercredit
+ ;; print out othercredit information; for translators, etc.
+ (let ((author-name (author-string))
+ (author-contrib (select-elements (children (current-node))
+ (normalize "contrib"))))
+ (make element gi: "P"
+ attributes: (list (list "CLASS" (gi)))
+ (make element gi: "B"
+ (literal author-name)
+ (literal " - "))
+ (process-node-list author-contrib))))
+)
+
+(define (article-title nd)
+ (let* ((artchild (children nd))
+ (artheader (select-elements artchild (normalize "artheader")))
+ (artinfo (select-elements artchild (normalize "articleinfo")))
+ (ahdr (if (node-list-empty? artheader)
+ artinfo
+ artheader))
+ (ahtitles (select-elements (children ahdr)
+ (normalize "title")))
+ (artitles (select-elements artchild (normalize "title")))
+ (titles (if (node-list-empty? artitles)
+ ahtitles
+ artitles)))
+ (if (node-list-empty? titles)
+ ""
+ (node-list-first titles))))
+
+
+</style-specification-body>
+</style-specification>
+
+<external-specification id="docbook" document="docbook.dsl">
+
+</style-sheet>
+
diff --git a/docs/faq/README b/docs/faq/README
new file mode 100755
index 00000000000..f4f0e8ab69a
--- /dev/null
+++ b/docs/faq/README
@@ -0,0 +1,8 @@
+This directory contains the old Samba FAQ.
+It is now horribly outdated and unmaintained.
+It is being left here in case there is some
+useful information within.
+
+
+--jerry@samba.org
+
diff --git a/docs/faq/Samba-Server-FAQ-1.html b/docs/faq/Samba-Server-FAQ-1.html
new file mode 100755
index 00000000000..0bf7f046109
--- /dev/null
+++ b/docs/faq/Samba-Server-FAQ-1.html
@@ -0,0 +1,77 @@
+<HTML>
+<HEAD>
+<TITLE> Samba Server FAQ: What is Samba?</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="Samba-Server-FAQ-2.html">Next</A>
+<A HREF="Samba-Server-FAQ.html#toc1">Table of Contents</A>
+<HR>
+<H2><A NAME="s1">1. What is Samba?</A></H2>
+
+<P>
+<A NAME="WhatIsSamba"></A>
+</P>
+<P>See the
+<A HREF="Samba-meta-FAQ.html#introduction">meta FAQ introduction</A> if you don't have any idea what Samba does.</P>
+<P>Samba has many features that are not supported in other CIFS and SMB
+implementations, all of which are commercial. It approaches some
+problems from a different angle.</P>
+<P>Some of its features include:
+<UL>
+<LI>extremely dynamic runtime configuration</LI>
+<LI>host as well as username/password security</LI>
+<LI>scriptable SMB client</LI>
+<LI>automatic home directory exporting</LI>
+<LI>automatic printer exporting</LI>
+<LI>intelligent dead connection timeouts</LI>
+<LI>guest connections</LI>
+</UL>
+</P>
+<P>Look at the
+<A HREF="samba-man-index.html">manual pages</A> included with the package for a full list of
+features. The components of the suite are (in summary):</P>
+<P>
+<DL>
+
+<DT><B>smbd</B><DD><P>the SMB server. This handles actual connections from clients,
+doing all the interfacing with the
+<A HREF="Samba-meta-FAQ.html#DomainModeSecurity">authentication database</A> for file, permission and username work.</P>
+
+<DT><B>nmbd</B><DD><P>the NetBIOS name server, which helps clients locate servers,
+maintaining the
+<A HREF="Samba-meta-FAQ.html#BrowseAndDomainDefs">authentication database</A> doing the browsing work and managing
+domains as this capability is being built into Samba.</P>
+
+<DT><B>smbclient</B><DD><P>the scriptable commandline SMB client program.
+Useful for automated work, printer filters and testing purposes. It is
+more CIFS-compliant than most commercial implementations. Note that this
+is not a filesystem. The Samba team does not supply a network filesystem
+driver, although the smbfs filesystem for Linux is derived from
+smbclient code.</P>
+
+<DT><B>smbrun</B><DD><P>a little 'glue' program to help the server run
+external programs.</P>
+
+<DT><B>testprns</B><DD><P>a program to test server access to printers</P>
+
+<DT><B>testparms</B><DD><P>a program to test the Samba configuration file
+for correctness</P>
+
+<DT><B>smb.conf</B><DD><P>the Samba configuration file</P>
+
+<DT><B>examples</B><DD><P>many examples have been put together for the different
+operating systems that Samba supports.</P>
+
+<DT><B>Documentation!</B><DD><P>DON'T neglect to read it - you will save a great
+deal of time!</P>
+
+</DL>
+</P>
+
+<HR>
+Previous
+<A HREF="Samba-Server-FAQ-2.html">Next</A>
+<A HREF="Samba-Server-FAQ.html#toc1">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-Server-FAQ-2.html b/docs/faq/Samba-Server-FAQ-2.html
new file mode 100755
index 00000000000..37a39833990
--- /dev/null
+++ b/docs/faq/Samba-Server-FAQ-2.html
@@ -0,0 +1,500 @@
+<HTML>
+<HEAD>
+<TITLE> Samba Server FAQ: How do I get the CIFS, SMB and NetBIOS protocols?</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-Server-FAQ-1.html">Previous</A>
+Next
+<A HREF="Samba-Server-FAQ.html#toc2">Table of Contents</A>
+<HR>
+<H2><A NAME="s2">2. How do I get the CIFS, SMB and NetBIOS protocols?</A></H2>
+
+<P>
+<A NAME="ServerProtocols"></A>
+</P>
+<P>See the
+<A HREF="Samba-meta-FAQ.html#CifsSmb">meta FAQ on CIFS and SMB</A> if you don't have any idea what these protocols are.</P>
+<P>CIFS and SMB are implemented by the main Samba fileserving daemon, smbd.
+<F>.....</F></P>
+<P>nmbd speaks a limited amount of CIFS (...) but is mostly concerned with
+NetBIOS. NetBIOS is <F>....</F></P>
+<P>RFC1001, RFC1002 <F>...</F></P>
+<P>So, provided you have got Samba correctly installed and running you have
+all three of these protocols. Some operating systems already come with
+stacks for all or some of these, such as SCO Unix, OS/2 and <F>...</F> In this
+case you must <F>...</F></P>
+
+<H2><A NAME="ss2.1">2.1 What server operating systems are supported?</A></H2>
+
+<P>
+<A NAME="PortInfo"></A>
+</P>
+<P>At the last count, Samba runs on about 40 operating systems! This
+section looks at general questions about running Samba on the different
+platforms. Issues specific to particular operating systems are dealt
+with in elsewhere in this document.</P>
+<P>Many of the ports have been done by people outside the Samba team keen
+to get the advantages of Samba. The Samba team is currently trying to
+bring as many of these ports as possible into the main source tree and
+integrate the documentation. Samba is an integration tool, and so it has
+been made as easy as possible to port. The platforms most widely used
+and thus best tested are Linux and SunOS.</P>
+<P>This migration has not been completed yet. This means that some
+documentation is on web sites <F>...</F></P>
+<P>There are two main families of Samba ports, Unix and other. The Unix
+ports cover anything that remotely resembles Unix and includes some
+extremely old products as well as best-sellers, tiny PCs to massive
+multiprocessor machines supporting hundreds of thousands of users. Samba
+has been run on more than 30 Unix and Unix-like operating systems.</P>
+
+<H3>Running Samba on a Unix or Unix-like system</H3>
+
+<P>
+<A NAME="OnUnix"></A>
+</P>
+<P>
+<A HREF="../UNIX-SMB.txt">../UNIX-SMB.txt</A> describes some of the issues that confront a
+SMB implementation on unix, and how Samba copes with them. They may help
+people who are looking at unix<->PC interoperability.</P>
+<P>There is great variation between Unix implementations, especially those
+not adhering to the Common Unix Specification agreed to in 1996. Things
+that can be quite tricky are <F>.....</F></P>
+<P>There are also some considerable advantages conferred on Samba running
+under Unix compared to, say, Windows NT or LAN Server. Unix has <F>...</F></P>
+<P>At time of writing, the Makefile claimed support for:
+<UL>
+<LI> A/UX 3.0</LI>
+<LI> AIX</LI>
+<LI> Altos Series 386/1000</LI>
+<LI> Amiga</LI>
+<LI> Apollo Domain/OS sr10.3</LI>
+<LI> BSDI </LI>
+<LI> B.O.S. (Bull Operating System)</LI>
+<LI> Cray, Unicos 8.0</LI>
+<LI> Convex</LI>
+<LI> DGUX. </LI>
+<LI> DNIX.</LI>
+<LI> FreeBSD</LI>
+<LI> HP-UX</LI>
+<LI> Intergraph. </LI>
+<LI> Linux with/without shadow passwords and quota</LI>
+<LI> LYNX 2.3.0</LI>
+<LI> MachTen (a unix like system for Macintoshes)</LI>
+<LI> Motorola 88xxx/9xx range of machines</LI>
+<LI> NetBSD</LI>
+<LI> NEXTSTEP Release 2.X, 3.0 and greater (including OPENSTEP for Mach).</LI>
+<LI> OS/2 using EMX 0.9b</LI>
+<LI> OSF1</LI>
+<LI> QNX 4.22</LI>
+<LI> RiscIX. </LI>
+<LI> RISCOs 5.0B</LI>
+<LI> SEQUENT. </LI>
+<LI> SCO (including: 3.2v2, European dist., OpenServer 5)</LI>
+<LI> SGI.</LI>
+<LI> SMP_DC.OSx v1.1-94c079 on Pyramid S series</LI>
+<LI> SONY NEWS, NEWS-OS (4.2.x and 6.1.x)</LI>
+<LI> SUNOS 4</LI>
+<LI> SUNOS 5.2, 5.3, and 5.4 (Solaris 2.2, 2.3, and '2.4 and later')</LI>
+<LI> Sunsoft ISC SVR3V4</LI>
+<LI> SVR4</LI>
+<LI> System V with some berkely extensions (Motorola 88k R32V3.2).</LI>
+<LI> ULTRIX.</LI>
+<LI> UNIXWARE</LI>
+<LI> UXP/DS</LI>
+</UL>
+</P>
+
+
+<H3>Running Samba on systems unlike Unix</H3>
+
+<P>
+<A NAME="OnUnlikeUnix"></A>
+</P>
+<P>More recently Samba has been ported to a number of operating systems
+which can provide a BSD Unix-like implementation of TCP/IP sockets.
+These include OS/2, Netware, VMS, StratOS, Amiga and MVS. BeOS,
+Windows NT and several others are being worked on but not yet available
+for use.</P>
+<P>Home pages for these ports are:</P>
+<P><F>... </F></P>
+
+
+<H2><A NAME="ss2.2">2.2 Exporting server resources with Samba</A></H2>
+
+<P>
+<A NAME="Exporting"></A>
+</P>
+<P>Files, printers, CD ROMs and other local devices. Network devices,
+including networked filesystems and remote printer queues. Other devices
+such as <F>....</F></P>
+<P>1.4) Configuring SHARES
+1.4.1) Homes service
+1.4.2) Public services
+1.4.3) Application serving
+1.4.4) Team sharing a Samba resource</P>
+<P>1.5) Printer configuration
+1.5.1) Berkeley LPR/LPD systems
+1.5.2) ATT SysV lp systems
+1.5.3) Using a private printcap file
+1.5.4) Use of the smbprint utility
+1.5.5) Printing from Windows to Unix
+1.5.6) Printing from Unix to Windows</P>
+
+
+<H2><A NAME="ss2.3">2.3 Name Resolution and Browsing</A></H2>
+
+<P>
+<A NAME="NameBrowsing"></A>
+</P>
+<P>See also
+<A HREF="../BROWSING.txt">../BROWSING.txt</A></P>
+<P>1.6) Name resolution issues
+1.6.1) LMHOSTS file and when to use it
+1.6.2) configuring WINS (support, server, proxy)
+1.6.3) configuring DNS proxy</P>
+<P>1.7) Problem Diagnosis
+1.8) What NOT to do!!!!</P>
+<P>3.2) Browse list managment
+3.3) Name resolution mangement</P>
+
+
+
+<H2><A NAME="ss2.4">2.4 Handling SMB Encryption</A></H2>
+
+<P>
+<A NAME="SMBEncryptionSteps"></A>
+</P>
+<P>SMB encryption is ...</P>
+<P>...in
+<A HREF="../ENCRYPTION.txt">../ENCRYPTION.txt</A> there is...</P>
+<P>Samba compiled with libdes - enabling encrypted passwords</P>
+
+
+<H3>Laws in different countries affecting Samba</H3>
+
+<P>
+<A NAME="CryptoLaws"></A>
+</P>
+
+<H3>Relationship between encryption and Domain Authentication</H3>
+
+
+
+
+<H2><A NAME="ss2.5">2.5 Files and record locking</A> 3.1.1) Old DOS clients 3.1.2) Opportunistic locking and the consequences 3.1.3) Files caching under Windows for Workgroups, Win95 and NT Some of the foregoing links into Client-FAQ</H2>
+
+
+<H2><A NAME="ss2.6">2.6 Managing Samba Log files</A></H2>
+
+<P>
+<A NAME="LogFiles"></A>
+</P>
+
+
+<H2><A NAME="ss2.7">2.7 I can't see the Samba server in any browse lists!</A></H2>
+
+<P>
+<A NAME="no_browse"></A>
+
+See
+<A HREF="ftp://samba.org/pub/samba/BROWSING.txt">BROWSING.txt</A>
+for more information on browsing. Browsing.txt can also be found
+in the docs directory of the Samba source.</P>
+<P>If your GUI client does not permit you to select non-browsable
+servers, you may need to do so on the command line. For example, under
+Lan Manager you might connect to the above service as disk drive M:
+thusly:
+<BLOCKQUOTE><CODE>
+<PRE>
+ net use M: \\mary\fred
+</PRE>
+</CODE></BLOCKQUOTE>
+
+The details of how to do this and the specific syntax varies from
+client to client - check your client's documentation.</P>
+
+
+<H2><A NAME="ss2.8">2.8 Some files that I KNOW are on the server doesn't show up when I view the files from my client! </A></H2>
+
+<P>
+<A NAME="missing_files"></A>
+
+See the next question.</P>
+
+
+<H2><A NAME="ss2.9">2.9 Some files on the server show up with really wierd filenames when I view the files from my client! </A></H2>
+
+<P>
+<A NAME="strange_filenames"></A>
+
+If you check what files are not showing up, you will note that they
+are files which contain upper case letters or which are otherwise not
+DOS-compatible (ie, they are not legal DOS filenames for some reason).</P>
+<P>The Samba server can be configured either to ignore such files
+completely, or to present them to the client in "mangled" form. If you
+are not seeing the files at all, the Samba server has most likely been
+configured to ignore them. Consult the man page smb.conf(5) for
+details of how to change this - the parameter you need to set is
+"mangled names = yes".</P>
+
+
+<H2><A NAME="ss2.10">2.10 My client reports "cannot locate specified computer" or similar</A></H2>
+
+<P>
+<A NAME="cant_see_server"></A>
+
+This indicates one of three things: You supplied an incorrect server
+name, the underlying TCP/IP layer is not working correctly, or the
+name you specified cannot be resolved.</P>
+<P>After carefully checking that the name you typed is the name you
+should have typed, try doing things like pinging a host or telnetting
+to somewhere on your network to see if TCP/IP is functioning OK. If it
+is, the problem is most likely name resolution.</P>
+<P>If your client has a facility to do so, hardcode a mapping between the
+hosts IP and the name you want to use. For example, with Man Manager
+or Windows for Workgroups you would put a suitable entry in the file
+LMHOSTS. If this works, the problem is in the communication between
+your client and the netbios name server. If it does not work, then
+there is something fundamental wrong with your naming and the solution
+is beyond the scope of this document.</P>
+<P>If you do not have any server on your subnet supplying netbios name
+resolution, hardcoded mappings are your only option. If you DO have a
+netbios name server running (such as the Samba suite's nmbd program),
+the problem probably lies in the way it is set up. Refer to Section
+Two of this FAQ for more ideas.</P>
+<P>By the way, remember to REMOVE the hardcoded mapping before further
+tests :-) </P>
+
+
+<H2><A NAME="ss2.11">2.11 My client reports "cannot locate specified share name" or similar</A></H2>
+
+<P>
+<A NAME="cant_see_share"></A>
+
+This message indicates that your client CAN locate the specified
+server, which is a good start, but that it cannot find a service of
+the name you gave.</P>
+<P>The first step is to check the exact name of the service you are
+trying to connect to (consult your system administrator). Assuming it
+exists and you specified it correctly (read your client's doco on how
+to specify a service name correctly), read on:</P>
+<P>
+<UL>
+<LI> Many clients cannot accept or use service names longer than eight characters.</LI>
+<LI> Many clients cannot accept or use service names containing spaces.</LI>
+<LI> Some servers (not Samba though) are case sensitive with service names.</LI>
+<LI> Some clients force service names into upper case.</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss2.12">2.12 My client reports "cannot find domain controller", "cannot log on to the network" or similar </A></H2>
+
+<P>
+<A NAME="cant_see_net"></A>
+
+Nothing is wrong - Samba does not implement the primary domain name
+controller stuff for several reasons, including the fact that the
+whole concept of a primary domain controller and "logging in to a
+network" doesn't fit well with clients possibly running on multiuser
+machines (such as users of smbclient under Unix). Having said that,
+several developers are working hard on building it in to the next
+major version of Samba. If you can contribute, send a message to
+<A HREF="mailto:samba@samba.org">samba@samba.org</A> !</P>
+<P>Seeing this message should not affect your ability to mount redirected
+disks and printers, which is really what all this is about.</P>
+<P>For many clients (including Windows for Workgroups and Lan Manager),
+setting the domain to STANDALONE at least gets rid of the message.</P>
+
+
+<H2><A NAME="ss2.13">2.13 Printing doesn't work :-(</A></H2>
+
+<P>
+<A NAME="no_printing"></A>
+ </P>
+<P>Make sure that the specified print command for the service you are
+connecting to is correct and that it has a fully-qualified path (eg.,
+use "/usr/bin/lpr" rather than just "lpr", if you happen to be using
+Unix).</P>
+<P>Make sure that the spool directory specified for the service is
+writable by the user connected to the service. </P>
+<P>Make sure that the user specified in the service is permitted to use
+the printer.</P>
+<P>Check the debug log produced by smbd. Search for the printer name and
+see if the log turns up any clues. Note that error messages to do with
+a service ipc$ are meaningless - they relate to the way the client
+attempts to retrieve status information when using the LANMAN1
+protocol.</P>
+<P>If using WfWg then you need to set the default protocol to TCP/IP, not
+Netbeui. This is a WfWg bug.</P>
+<P>If using the Lanman1 protocol (the default) then try switching to
+coreplus. Also not that print status error messages don't mean
+printing won't work. The print status is received by a different
+mechanism.</P>
+
+
+<H2><A NAME="ss2.14">2.14 My programs install on the server OK, but refuse to work properly</A></H2>
+
+<P>
+<A NAME="programs_wont_run"></A>
+
+There are numerous possible reasons for this, but one MAJOR
+possibility is that your software uses locking. Make sure you are
+using Samba 1.6.11 or later. It may also be possible to work around
+the problem by setting "locking=no" in the Samba configuration file
+for the service the software is installed on. This should be regarded
+as a strictly temporary solution.</P>
+<P>In earlier Samba versions there were some difficulties with the very
+latest Microsoft products, particularly Excel 5 and Word for Windows
+6. These should have all been solved. If not then please let Andrew
+Tridgell know via email at
+<A HREF="mailto:sambas@samba.org">samba@samba.org</A>.</P>
+
+
+<H2><A NAME="ss2.15">2.15 My "server string" doesn't seem to be recognised</A></H2>
+
+<P>
+<A NAME="bad_server_string"></A>
+
+OR My client reports the default setting, eg. "Samba 1.9.15p4", instead
+of what I have changed it to in the smb.conf file.</P>
+<P>You need to use the -C option in nmbd. The "server string" affects
+what smbd puts out and -C affects what nmbd puts out.</P>
+<P>Current versions of Samba (1.9.16 +) have combined these options into
+the "server string" field of smb.conf, -C for nmbd is now obsolete.</P>
+
+
+<H2><A NAME="ss2.16">2.16 My client reports "This server is not configured to list shared resources" </A></H2>
+
+<P>
+<A NAME="cant_list_shares"></A>
+
+Your guest account is probably invalid for some reason. Samba uses the
+guest account for browsing in smbd. Check that your guest account is
+valid.</P>
+<P>See also 'guest account' in smb.conf man page.</P>
+
+
+<H2><A NAME="ss2.17">2.17 Issues specific to Unix and Unix-like systems</A></H2>
+
+<P>
+<A NAME="UnixIssues"></A>
+</P>
+
+<H3>Printing doesn't work with my Unix Samba server</H3>
+
+<P>
+<A NAME="no_printing"></A>
+ </P>
+<P>The user "nobody" often has problems with printing, even if it worked
+with an earlier version of Samba. Try creating another guest user other
+than "nobody".</P>
+
+<H3>Log message "you appear to have a trapdoor uid system" </H3>
+
+<P>
+<A NAME="trapdoor_uid"></A>
+
+This can have several causes. It might be because you are using a uid
+or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+hole. Check carefully in your /etc/passwd file and make sure that no
+user has uid 65535 or -1. Especially check the "nobody" user, as many
+broken systems are shipped with nobody setup with a uid of 65535.</P>
+<P>It might also mean that your OS has a trapdoor uid/gid system :-)</P>
+<P>This means that once a process changes effective uid from root to
+another user it can't go back to root. Unfortunately Samba relies on
+being able to change effective uid from root to non-root and back
+again to implement its security policy. If your OS has a trapdoor uid
+system this won't work, and several things in Samba may break. Less
+things will break if you use user or server level security instead of
+the default share level security, but you may still strike
+problems.</P>
+<P>The problems don't give rise to any security holes, so don't panic,
+but it does mean some of Samba's capabilities will be unavailable.
+In particular you will not be able to connect to the Samba server as
+two different uids at once. This may happen if you try to print as a
+"guest" while accessing a share as a normal user. It may also affect
+your ability to list the available shares as this is normally done as
+the guest user.</P>
+<P>Complain to your OS vendor and ask them to fix their system.</P>
+<P>Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+it casts to -1 as a uid, and the setreuid() system call ignores (with
+no error) uid changes to -1. This means any daemon attempting to run
+as uid 65535 will actually run as root. This is not good!</P>
+
+
+<H2><A NAME="ss2.18">2.18 Issues specific to IBM OS/2 systems</A></H2>
+
+<P>
+<A NAME="OS2Issues"></A>
+</P>
+<P>
+<A HREF="http://carol.wins.uva.nl/~leeuw/samba/samba2.html">Samba for OS/2</A></P>
+
+
+<H2><A NAME="ss2.19">2.19 Issues specific to IBM MVS systems</A></H2>
+
+<P>
+<A NAME="MVSIssues"></A>
+</P>
+<P>
+<A HREF="ftp://ftp.mks.com/pub/samba/">Samba for OS/390 MVS</A></P>
+
+
+<H2><A NAME="ss2.20">2.20 Issues specific to Digital VMS systems</A></H2>
+
+<P>
+<A NAME="VMSIssues"></A>
+</P>
+
+
+<H2><A NAME="ss2.21">2.21 Issues specific to Amiga systems</A></H2>
+
+<P>
+<A NAME="AmigaIssues"></A>
+</P>
+<P>
+<A HREF="http://www.gbar.dtu.dk/~c948374/Amiga/Samba/">Samba for Amiga</A></P>
+<P>There is a mailing list for Samba on the Amiga.</P>
+<P>Subscribing.</P>
+<P>Send an email to rask-samba-request@kampsax.dtu.dk with the word subscribe
+in the message. The list server will use the address in the Reply-To: or
+From: header field, in that order.</P>
+<P>Unsubscribing.</P>
+<P>Send an email to rask-samba-request@kampsax.dtu.dk with the word
+unsubscribe in the message. The list server will use the address in the
+Reply-To: or From: header field, in that order. If you are unsure which
+address you are subscribed with, look at the headers. You should see a
+"From " (no colon) or Return-Path: header looking something like</P>
+<P>rask-samba-owner-myname=my.domain@kampsax.dtu.dk</P>
+<P>where myname=my.domain gives you the address myname@my.domain. This also
+means that I will always be able to find out which address is causing
+bounces, for example.
+List archive.</P>
+<P>Messages sent to the list are archived in HTML. See the mailing list home
+page at
+<A HREF="http://www.gbar.dtu.dk/~c948374/Amiga/Samba/mailinglist/">http://www.gbar.dtu.dk/~c948374/Amiga/Samba/mailinglist/</A></P>
+
+
+<H2><A NAME="ss2.22">2.22 Issues specific to Novell IntraNetware systems</A></H2>
+
+<P>
+<A NAME="NetwareIssues"></A>
+</P>
+
+
+<H2><A NAME="ss2.23">2.23 Issues specific to Stratus VOS systems</A></H2>
+
+<P>
+<A NAME="NetwareIssues"></A>
+</P>
+<P>
+<A HREF="ftp://ftp.stratus.com/pub/vos/tools/">Samba for Stratus VOS</A></P>
+
+
+<HR>
+<A HREF="Samba-Server-FAQ-1.html">Previous</A>
+Next
+<A HREF="Samba-Server-FAQ.html#toc2">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-Server-FAQ.html b/docs/faq/Samba-Server-FAQ.html
new file mode 100755
index 00000000000..2abfe50db6b
--- /dev/null
+++ b/docs/faq/Samba-Server-FAQ.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<HTML>
+<HEAD>
+<TITLE> Samba Server FAQ</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="Samba-Server-FAQ-1.html">Next</A>
+Table of Contents
+<HR>
+<H1> Samba Server FAQ</H1>
+
+<H2>Dan Shearer & Paul Blackman, <CODE>ictinus@samba.org</CODE></H2>v 0.3, 7 Oct '97
+<P><HR><EM> This is the <EM>Server</EM> Frequently Asked Questions (FAQ)
+document for Samba, the free and very popular SMB and CIFS server
+product. A general
+<A HREF="Samba-meta-FAQ.html">meta FAQ</A>
+exists and also a companion
+<A HREF="Samba-Client-FAQ.html">Client FAQ</A>, together with more detailed HOWTO documents on
+topics to do with Samba software. This is current to Samba version
+1.9.17. Please send any corrections to the author. </EM><HR></P>
+<P>
+<H2><A NAME="toc1">1.</A> <A HREF="Samba-Server-FAQ-1.html">What is Samba?</A></H2>
+
+<P>
+<H2><A NAME="toc2">2.</A> <A HREF="Samba-Server-FAQ-2.html">How do I get the CIFS, SMB and NetBIOS protocols?</A></H2>
+<UL>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.1">2.1 What server operating systems are supported?</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.2">2.2 Exporting server resources with Samba</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.3">2.3 Name Resolution and Browsing</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.4">2.4 Handling SMB Encryption</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.5">2.5 Files and record locking</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.6">2.6 Managing Samba Log files</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.7">2.7 I can't see the Samba server in any browse lists!</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.8">2.8 Some files that I KNOW are on the server doesn't show up when I view the files from my client! </A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.9">2.9 Some files on the server show up with really wierd filenames when I view the files from my client! </A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.10">2.10 My client reports "cannot locate specified computer" or similar</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.11">2.11 My client reports "cannot locate specified share name" or similar</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.12">2.12 My client reports "cannot find domain controller", "cannot log on to the network" or similar </A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.13">2.13 Printing doesn't work :-(</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.14">2.14 My programs install on the server OK, but refuse to work properly</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.15">2.15 My "server string" doesn't seem to be recognised</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.16">2.16 My client reports "This server is not configured to list shared resources" </A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.17">2.17 Issues specific to Unix and Unix-like systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.18">2.18 Issues specific to IBM OS/2 systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.19">2.19 Issues specific to IBM MVS systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.20">2.20 Issues specific to Digital VMS systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.21">2.21 Issues specific to Amiga systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.22">2.22 Issues specific to Novell IntraNetware systems</A>
+<LI><A HREF="Samba-Server-FAQ-2.html#ss2.23">2.23 Issues specific to Stratus VOS systems</A>
+</UL>
+
+
+<HR>
+Previous
+<A HREF="Samba-Server-FAQ-1.html">Next</A>
+Table of Contents
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-Server-FAQ.sgml b/docs/faq/Samba-Server-FAQ.sgml
new file mode 100755
index 00000000000..da6b50f99e2
--- /dev/null
+++ b/docs/faq/Samba-Server-FAQ.sgml
@@ -0,0 +1,492 @@
+<!doctype linuxdoc system> <!-- -*- SGML -*- -->
+<!--
+ v 0.1 23 Aug 1997 Dan Shearer
+ Original Samba-Client-FAQ.sgml from Paul's sambafaq.sgml
+ v 0.2 25 Aug 1997 Dan
+ v 0.3 7 Oct 1997 Paul, changed email address from ictinus@lake... to ictinus@samba.anu
+-->
+
+
+<article>
+
+<title> Samba Server FAQ
+
+<author>Dan Shearer & Paul Blackman, <tt>ictinus@samba.org</tt>
+
+<date>v 0.3, 7 Oct '97
+
+<abstract> This is the <em>Server</em> Frequently Asked Questions (FAQ)
+document for Samba, the free and very popular SMB and CIFS server
+product. A general <url url="Samba-meta-FAQ.html" name="meta FAQ">
+exists and also a companion <url url="Samba-Client-FAQ.html"
+name="Client FAQ">, together with more detailed HOWTO documents on
+topics to do with Samba software. This is current to Samba version
+1.9.17. Please send any corrections to the author.
+
+</abstract>
+
+<toc>
+
+<sect>What is Samba?<p><label id="WhatIsSamba">
+
+See the <url url="Samba-meta-FAQ.html#introduction" name="meta FAQ
+introduction"> if you don't have any idea what Samba does.
+
+Samba has many features that are not supported in other CIFS and SMB
+implementations, all of which are commercial. It approaches some
+problems from a different angle.
+
+Some of its features include:
+<itemize>
+<item>extremely dynamic runtime configuration
+<item>host as well as username/password security
+<item>scriptable SMB client
+<item>automatic home directory exporting
+<item>automatic printer exporting
+<item>intelligent dead connection timeouts
+<item>guest connections
+</itemize>
+
+Look at the <url url="samba-man-index.html" name="manual pages"> included with the package for a full list of
+features. The components of the suite are (in summary):
+
+<descrip>
+
+<tag/smbd/ the SMB server. This handles actual connections from clients,
+doing all the interfacing with the <url
+url="Samba-meta-FAQ.html#DomainModeSecurity" name="authentication
+database"> for file, permission and username work.
+
+<tag/nmbd/ the NetBIOS name server, which helps clients locate servers,
+maintaining the <url url="Samba-meta-FAQ.html#BrowseAndDomainDefs"
+name="authentication database"> doing the browsing work and managing
+domains as this capability is being built into Samba.
+
+<tag/smbclient/ the scriptable commandline SMB client program.
+Useful for automated work, printer filters and testing purposes. It is
+more CIFS-compliant than most commercial implementations. Note that this
+is not a filesystem. The Samba team does not supply a network filesystem
+driver, although the smbfs filesystem for Linux is derived from
+smbclient code.
+
+<tag/smbrun/ a little 'glue' program to help the server run
+external programs.
+
+<tag/testprns/ a program to test server access to printers
+
+<tag/testparms/ a program to test the Samba configuration file
+for correctness
+
+<tag/smb.conf/ the Samba configuration file
+
+<tag/examples/ many examples have been put together for the different
+operating systems that Samba supports.
+
+<tag/Documentation!/ DON'T neglect to read it - you will save a great
+deal of time!
+
+</descrip>
+
+<sect>How do I get the CIFS, SMB and NetBIOS protocols?<p><label id="ServerProtocols">
+
+See the <url url="Samba-meta-FAQ.html#CifsSmb" name="meta FAQ
+on CIFS and SMB"> if you don't have any idea what these protocols are.
+
+CIFS and SMB are implemented by the main Samba fileserving daemon, smbd.
+[.....]
+
+nmbd speaks a limited amount of CIFS (...) but is mostly concerned with
+NetBIOS. NetBIOS is [....]
+
+RFC1001, RFC1002 [...]
+
+So, provided you have got Samba correctly installed and running you have
+all three of these protocols. Some operating systems already come with
+stacks for all or some of these, such as SCO Unix, OS/2 and [...] In this
+case you must [...]
+
+<sect1>What server operating systems are supported?<p><label id="PortInfo">
+
+At the last count, Samba runs on about 40 operating systems! This
+section looks at general questions about running Samba on the different
+platforms. Issues specific to particular operating systems are dealt
+with in elsewhere in this document.
+
+Many of the ports have been done by people outside the Samba team keen
+to get the advantages of Samba. The Samba team is currently trying to
+bring as many of these ports as possible into the main source tree and
+integrate the documentation. Samba is an integration tool, and so it has
+been made as easy as possible to port. The platforms most widely used
+and thus best tested are Linux and SunOS.
+
+This migration has not been completed yet. This means that some
+documentation is on web sites [...]
+
+There are two main families of Samba ports, Unix and other. The Unix
+ports cover anything that remotely resembles Unix and includes some
+extremely old products as well as best-sellers, tiny PCs to massive
+multiprocessor machines supporting hundreds of thousands of users. Samba
+has been run on more than 30 Unix and Unix-like operating systems.
+
+<sect2>Running Samba on a Unix or Unix-like system<p><label id="OnUnix">
+
+<url url="../UNIX-SMB.txt"> describes some of the issues that confront a
+SMB implementation on unix, and how Samba copes with them. They may help
+people who are looking at unix<->PC interoperability.
+
+There is great variation between Unix implementations, especially those
+not adhering to the Common Unix Specification agreed to in 1996. Things
+that can be quite tricky are [.....]
+
+There are also some considerable advantages conferred on Samba running
+under Unix compared to, say, Windows NT or LAN Server. Unix has [...]
+
+At time of writing, the Makefile claimed support for:
+<itemize>
+<item> A/UX 3.0
+<item> AIX
+<item> Altos Series 386/1000
+<item> Amiga
+<item> Apollo Domain/OS sr10.3
+<item> BSDI
+<item> B.O.S. (Bull Operating System)
+<item> Cray, Unicos 8.0
+<item> Convex
+<item> DGUX.
+<item> DNIX.
+<item> FreeBSD
+<item> HP-UX
+<item> Intergraph.
+<item> Linux with/without shadow passwords and quota
+<item> LYNX 2.3.0
+<item> MachTen (a unix like system for Macintoshes)
+<item> Motorola 88xxx/9xx range of machines
+<item> NetBSD
+<item> NEXTSTEP Release 2.X, 3.0 and greater (including OPENSTEP for Mach).
+<item> OS/2 using EMX 0.9b
+<item> OSF1
+<item> QNX 4.22
+<item> RiscIX.
+<item> RISCOs 5.0B
+<item> SEQUENT.
+<item> SCO (including: 3.2v2, European dist., OpenServer 5)
+<item> SGI.
+<item> SMP_DC.OSx v1.1-94c079 on Pyramid S series
+<item> SONY NEWS, NEWS-OS (4.2.x and 6.1.x)
+<item> SUNOS 4
+<item> SUNOS 5.2, 5.3, and 5.4 (Solaris 2.2, 2.3, and '2.4 and later')
+<item> Sunsoft ISC SVR3V4
+<item> SVR4
+<item> System V with some berkely extensions (Motorola 88k R32V3.2).
+<item> ULTRIX.
+<item> UNIXWARE
+<item> UXP/DS
+</itemize>
+
+
+<sect2>Running Samba on systems unlike Unix<p><label id="OnUnlikeUnix">
+
+More recently Samba has been ported to a number of operating systems
+which can provide a BSD Unix-like implementation of TCP/IP sockets.
+These include OS/2, Netware, VMS, StratOS, Amiga and MVS. BeOS,
+Windows NT and several others are being worked on but not yet available
+for use.
+
+Home pages for these ports are:
+
+[... ]
+
+<sect1>Exporting server resources with Samba<p><label id="Exporting">
+
+Files, printers, CD ROMs and other local devices. Network devices,
+including networked filesystems and remote printer queues. Other devices
+such as [....]
+
+ 1.4) Configuring SHARES
+ 1.4.1) Homes service
+ 1.4.2) Public services
+ 1.4.3) Application serving
+ 1.4.4) Team sharing a Samba resource
+
+ 1.5) Printer configuration
+ 1.5.1) Berkeley LPR/LPD systems
+ 1.5.2) ATT SysV lp systems
+ 1.5.3) Using a private printcap file
+ 1.5.4) Use of the smbprint utility
+ 1.5.5) Printing from Windows to Unix
+ 1.5.6) Printing from Unix to Windows
+
+<sect1>Name Resolution and Browsing<p><label id="NameBrowsing">
+
+See also <url url="../BROWSING.txt">
+
+ 1.6) Name resolution issues
+ 1.6.1) LMHOSTS file and when to use it
+ 1.6.2) configuring WINS (support, server, proxy)
+ 1.6.3) configuring DNS proxy
+
+ 1.7) Problem Diagnosis
+ 1.8) What NOT to do!!!!
+
+ 3.2) Browse list managment
+ 3.3) Name resolution mangement
+
+
+<sect1>Handling SMB Encryption<p><label id="SMBEncryptionSteps">
+
+SMB encryption is ...
+
+...in <url url="../ENCRYPTION.txt"> there is...
+
+Samba compiled with libdes - enabling encrypted passwords
+
+
+<sect2>Laws in different countries affecting Samba<p><label id="CryptoLaws">
+
+<sect2>Relationship between encryption and Domain Authentication<p>
+
+<sect1> Files and record locking
+
+ 3.1.1) Old DOS clients
+ 3.1.2) Opportunistic locking and the consequences
+ 3.1.3) Files caching under Windows for Workgroups, Win95 and NT
+
+ Some of the foregoing links into Client-FAQ
+
+<sect1>Managing Samba Log files<p><label id="LogFiles">
+
+<sect1>I can't see the Samba server in any browse lists!<p><label id="no_browse">
+ See <url url="ftp://samba.org/pub/samba/BROWSING.txt" name="BROWSING.txt">
+ for more information on browsing. Browsing.txt can also be found
+ in the docs directory of the Samba source.
+
+If your GUI client does not permit you to select non-browsable
+servers, you may need to do so on the command line. For example, under
+Lan Manager you might connect to the above service as disk drive M:
+thusly:
+<tscreen><verb>
+ net use M: \\mary\fred
+</verb></tscreen>
+The details of how to do this and the specific syntax varies from
+client to client - check your client's documentation.
+
+<sect1>Some files that I KNOW are on the server doesn't show up when I view the files from my client! <p> <label id="missing_files">
+See the next question.
+
+<sect1>Some files on the server show up with really wierd filenames when I view the files from my client! <p> <label id="strange_filenames">
+If you check what files are not showing up, you will note that they
+are files which contain upper case letters or which are otherwise not
+DOS-compatible (ie, they are not legal DOS filenames for some reason).
+
+The Samba server can be configured either to ignore such files
+completely, or to present them to the client in "mangled" form. If you
+are not seeing the files at all, the Samba server has most likely been
+configured to ignore them. Consult the man page smb.conf(5) for
+details of how to change this - the parameter you need to set is
+"mangled names = yes".
+
+<sect1>My client reports "cannot locate specified computer" or similar<p><label id="cant_see_server">
+This indicates one of three things: You supplied an incorrect server
+name, the underlying TCP/IP layer is not working correctly, or the
+name you specified cannot be resolved.
+
+After carefully checking that the name you typed is the name you
+should have typed, try doing things like pinging a host or telnetting
+to somewhere on your network to see if TCP/IP is functioning OK. If it
+is, the problem is most likely name resolution.
+
+If your client has a facility to do so, hardcode a mapping between the
+hosts IP and the name you want to use. For example, with Man Manager
+or Windows for Workgroups you would put a suitable entry in the file
+LMHOSTS. If this works, the problem is in the communication between
+your client and the netbios name server. If it does not work, then
+there is something fundamental wrong with your naming and the solution
+is beyond the scope of this document.
+
+If you do not have any server on your subnet supplying netbios name
+resolution, hardcoded mappings are your only option. If you DO have a
+netbios name server running (such as the Samba suite's nmbd program),
+the problem probably lies in the way it is set up. Refer to Section
+Two of this FAQ for more ideas.
+
+By the way, remember to REMOVE the hardcoded mapping before further
+tests :-)
+
+<sect1>My client reports "cannot locate specified share name" or similar<p> <label id="cant_see_share">
+This message indicates that your client CAN locate the specified
+server, which is a good start, but that it cannot find a service of
+the name you gave.
+
+The first step is to check the exact name of the service you are
+trying to connect to (consult your system administrator). Assuming it
+exists and you specified it correctly (read your client's doco on how
+to specify a service name correctly), read on:
+
+<itemize>
+<item> Many clients cannot accept or use service names longer than eight characters.
+<item> Many clients cannot accept or use service names containing spaces.
+<item> Some servers (not Samba though) are case sensitive with service names.
+<item> Some clients force service names into upper case.
+</itemize>
+
+<sect1>My client reports "cannot find domain controller", "cannot log on to the network" or similar <p> <label id="cant_see_net">
+Nothing is wrong - Samba does not implement the primary domain name
+controller stuff for several reasons, including the fact that the
+whole concept of a primary domain controller and "logging in to a
+network" doesn't fit well with clients possibly running on multiuser
+machines (such as users of smbclient under Unix). Having said that,
+several developers are working hard on building it in to the next
+major version of Samba. If you can contribute, send a message to
+<htmlurl url="mailto:samba@samba.org" name="samba@samba.org"> !
+
+Seeing this message should not affect your ability to mount redirected
+disks and printers, which is really what all this is about.
+
+For many clients (including Windows for Workgroups and Lan Manager),
+setting the domain to STANDALONE at least gets rid of the message.
+
+<sect1>Printing doesn't work :-(<p> <label id="no_printing">
+
+Make sure that the specified print command for the service you are
+connecting to is correct and that it has a fully-qualified path (eg.,
+use "/usr/bin/lpr" rather than just "lpr", if you happen to be using
+Unix).
+
+Make sure that the spool directory specified for the service is
+writable by the user connected to the service.
+
+Make sure that the user specified in the service is permitted to use
+the printer.
+
+Check the debug log produced by smbd. Search for the printer name and
+see if the log turns up any clues. Note that error messages to do with
+a service ipc$ are meaningless - they relate to the way the client
+attempts to retrieve status information when using the LANMAN1
+protocol.
+
+If using WfWg then you need to set the default protocol to TCP/IP, not
+Netbeui. This is a WfWg bug.
+
+If using the Lanman1 protocol (the default) then try switching to
+coreplus. Also not that print status error messages don't mean
+printing won't work. The print status is received by a different
+mechanism.
+
+<sect1>My programs install on the server OK, but refuse to work properly<p><label id="programs_wont_run">
+There are numerous possible reasons for this, but one MAJOR
+possibility is that your software uses locking. Make sure you are
+using Samba 1.6.11 or later. It may also be possible to work around
+the problem by setting "locking=no" in the Samba configuration file
+for the service the software is installed on. This should be regarded
+as a strictly temporary solution.
+
+In earlier Samba versions there were some difficulties with the very
+latest Microsoft products, particularly Excel 5 and Word for Windows
+6. These should have all been solved. If not then please let Andrew
+Tridgell know via email at <htmlurl url="mailto:samba@samba.org" name="samba@samba.org">.
+
+<sect1>My "server string" doesn't seem to be recognised<p><label id="bad_server_string">
+OR My client reports the default setting, eg. "Samba 1.9.15p4", instead
+of what I have changed it to in the smb.conf file.
+
+You need to use the -C option in nmbd. The "server string" affects
+what smbd puts out and -C affects what nmbd puts out.
+
+Current versions of Samba (1.9.16 +) have combined these options into
+the "server string" field of smb.conf, -C for nmbd is now obsolete.
+
+<sect1>My client reports "This server is not configured to list shared resources" <p> <label id="cant_list_shares">
+Your guest account is probably invalid for some reason. Samba uses the
+guest account for browsing in smbd. Check that your guest account is
+valid.
+
+See also 'guest account' in smb.conf man page.
+
+<sect1>Issues specific to Unix and Unix-like systems<p><label id="UnixIssues">
+
+<sect2>Printing doesn't work with my Unix Samba server<p> <label id="no_printing">
+
+The user "nobody" often has problems with printing, even if it worked
+with an earlier version of Samba. Try creating another guest user other
+than "nobody".
+
+<sect2>Log message "you appear to have a trapdoor uid system" <p><label id="trapdoor_uid">
+This can have several causes. It might be because you are using a uid
+or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+hole. Check carefully in your /etc/passwd file and make sure that no
+user has uid 65535 or -1. Especially check the "nobody" user, as many
+broken systems are shipped with nobody setup with a uid of 65535.
+
+It might also mean that your OS has a trapdoor uid/gid system :-)
+
+This means that once a process changes effective uid from root to
+another user it can't go back to root. Unfortunately Samba relies on
+being able to change effective uid from root to non-root and back
+again to implement its security policy. If your OS has a trapdoor uid
+system this won't work, and several things in Samba may break. Less
+things will break if you use user or server level security instead of
+the default share level security, but you may still strike
+problems.
+
+The problems don't give rise to any security holes, so don't panic,
+but it does mean some of Samba's capabilities will be unavailable.
+In particular you will not be able to connect to the Samba server as
+two different uids at once. This may happen if you try to print as a
+"guest" while accessing a share as a normal user. It may also affect
+your ability to list the available shares as this is normally done as
+the guest user.
+
+Complain to your OS vendor and ask them to fix their system.
+
+Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+it casts to -1 as a uid, and the setreuid() system call ignores (with
+no error) uid changes to -1. This means any daemon attempting to run
+as uid 65535 will actually run as root. This is not good!
+
+<sect1>Issues specific to IBM OS/2 systems<p><label id="OS2Issues">
+
+<url url="http://carol.wins.uva.nl/~leeuw/samba/samba2.html" name="Samba for OS/2">
+
+<sect1>Issues specific to IBM MVS systems<p><label id="MVSIssues">
+
+<url url="ftp://ftp.mks.com/pub/samba/" name="Samba for OS/390 MVS">
+
+<sect1>Issues specific to Digital VMS systems<p><label id="VMSIssues">
+
+<sect1>Issues specific to Amiga systems<p><label id="AmigaIssues">
+
+<url url="http://www.gbar.dtu.dk/~c948374/Amiga/Samba/" name="Samba for Amiga">
+
+There is a mailing list for Samba on the Amiga.
+
+ Subscribing.
+
+ Send an email to rask-samba-request@kampsax.dtu.dk with the word subscribe
+in the message. The list server will use the address in the Reply-To: or
+From: header field, in that order.
+
+ Unsubscribing.
+
+ Send an email to rask-samba-request@kampsax.dtu.dk with the word
+unsubscribe in the message. The list server will use the address in the
+Reply-To: or From: header field, in that order. If you are unsure which
+address you are subscribed with, look at the headers. You should see a
+"From " (no colon) or Return-Path: header looking something like
+
+ rask-samba-owner-myname=my.domain@kampsax.dtu.dk
+
+where myname=my.domain gives you the address myname@my.domain. This also
+means that I will always be able to find out which address is causing
+bounces, for example.
+ List archive.
+
+ Messages sent to the list are archived in HTML. See the mailing list home
+page at <URL url="http://www.gbar.dtu.dk/~c948374/Amiga/Samba/mailinglist/">
+
+<sect1>Issues specific to Novell IntraNetware systems<p><label id="NetwareIssues">
+
+<sect1>Issues specific to Stratos VOS systems<p><label id="NetwareIssues">
+
+<url url="ftp://ftp.stratus.com/pub/vos/tools/" name="Samba for Stratus VOS">
+
+</article>
diff --git a/docs/faq/Samba-meta-FAQ-1.html b/docs/faq/Samba-meta-FAQ-1.html
new file mode 100755
index 00000000000..7258a32f1e2
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-1.html
@@ -0,0 +1,160 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: Quick Reference Guides to Samba Documentation</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="Samba-meta-FAQ-2.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc1">Table of Contents</A>
+<HR>
+<H2><A NAME="s1">1. Quick Reference Guides to Samba Documentation</A></H2>
+
+<P>
+<A NAME="quickref"></A>
+</P>
+<P>We are endeavouring to provide links here to every major class of
+information about Samba or things related to Samba. We cannot list every
+document, but we are aiming for all documents to be at most two
+referrals from those listed here. This needs constant maintaining, so
+please send the author your feedback.</P>
+
+<H2><A NAME="ss1.1">1.1 Samba for the Impatient</A></H2>
+
+<P>
+<A NAME="impatient"></A>
+</P>
+<P>You know you should read the documentation but can't wait to start? What
+you need to do then is follow the instructions in the following
+documents in the order given. This should be enough to get a fairly
+simple site going quickly. If you have any problems, refer back to this
+meta-FAQ and follow the links to find more reading material.</P>
+<P>
+<DL>
+<P>
+<A NAME="ImpGet"></A>
+</P>
+<DT><B>Getting Samba:</B><DD><P>The fastest way to get Samba
+going is and install it is to have an operating system for which the
+Samba team has put together an installation package. To see if your OS
+is included have a look at the directory
+/pub/samba/Binary_Packages/"OS_Vendor" on your nearest
+<A HREF="../MIRRORS">mirror site</A>. If it is included follow the
+installation instructions in the README file there and then do some
+<A HREF="#ImpTest">basic testing</A>. If you are not so fortunate, follow the normal
+<A HREF="Samba-meta-FAQ-2.html#WhereFrom">download instructions</A> and then continue with
+<A HREF="#ImpInst">building and installing Samba</A>.</P>
+<P>
+<A NAME="ImpInst"></A>
+</P>
+<DT><B>Building and Installing Samba:</B><DD><P>At the moment
+there are two kinds of Samba server installs besides the prepackaged
+binaries mentioned in the previous step. You need to decide if you have a
+<A HREF="../UNIX_INSTALL.txt">Unix or close relative</A> or
+<A HREF="Samba-Server-FAQ.html#PortInfo">other supported operating system</A>.</P>
+<P>
+<A NAME="ImpTest"></A>
+</P>
+<DT><B>Basic Testing:</B><DD><P>Try to connect using the
+supplied smbclient command-line program. You need to know the IP
+hostname of your server. A service name must be defined in smb.conf, as
+given in the examples (under many operating systems if there is a
+<F>homes</F> service you can just use a valid username.) Then type
+<CODE>smbclient \\hostname\servicename</CODE>
+Under most Unixes you will need to put the parameters within quotation
+marks. If this works, try connecting from one of the SMB clients you
+were planning to use with Samba.</P>
+<P>
+<A NAME="ImpDebug"></A>
+</P>
+<DT><B>Debug sequence:</B><DD><P>If you think you have completed the
+previous step and things aren't working properly work through
+<A HREF="../DIAGNOSIS.txt">the diagnosis recipe.</A></P>
+<P>
+<A NAME="ImpExp"></A>
+</P>
+<DT><B>Exporting files to SMB clients:</B><DD><P>You should read the manual pages
+for smb.conf, but here is a
+<A HREF="Samba-Server-FAQ.html#Exporting">quick answer guide.</A></P>
+<P>
+<A NAME="ImpControl"></A>
+</P>
+<DT><B>Controlling user access:</B><DD><P>the quickest and dirtiest way of sharing
+resources is to use
+<A HREF="Samba-meta-FAQ-4.html#ShareModeSecurity">share level security.</A> If you want to spend more time and have a proper username
+and password database you must read the paragraph on
+<A HREF="Samba-meta-FAQ-4.html#DomainModeSecurity">domain mode security.</A> If you want
+encryption (eg you are using Windows NT clients) follow the
+<A HREF="Samba-Server-FAQ.html#SMBEncryptionSteps">SMB encryption instructions.</A></P>
+<P>
+<A NAME="ImpBrowse"></A>
+</P>
+<DT><B>Browsing:</B><DD><P>if you are happy to type in "\\samba-server\sharename"
+at the client end then do not read any further. Otherwise you need to
+understand the
+browsing terminology</A>
+and read
+<A HREF="Samba-Server-FAQ.html#NameBrowsing">Samba-Server-FAQ.html#NameBrowsing</A>. </P>
+<P>
+<A NAME="ImpPrint"></A>
+</P>
+<DT><B>Printing:</B><DD><P>See the
+<A HREF="Samba-Server-FAQ.html#Printing">printing quick answer guide.</A></P>
+
+</DL>
+</P>
+<P>If you have got everything working to this point, you can expect Samba
+to be stable and secure: these are its greatest strengths. However Samba
+has a great deal to offer and to go further you must do some more
+reading. Speed and security optimisations, printer accounting, network
+logons, roving profiles, browsing across multiple subnets and so on are
+all covered either in this document or in those it refers to.</P>
+
+
+<H2><A NAME="ss1.2">1.2 All Samba Documentation</A></H2>
+
+<P>
+<A NAME="AllDocs"></A>
+</P>
+<P>
+<UL>
+<LI> Meta-FAQ. This is the mother of all documents, and is the one you
+are reading now. The latest version is always at
+<A HREF="http://samba.org/[.....]">http://samba.org/[.....]</A> but there is probably a much
+nearer
+<A HREF="../MIRRORS">mirror site</A> which you should use
+instead.
+</LI>
+<LI>
+<A HREF="Samba-Server-FAQ.html">Samba-Server-FAQ.html</A> is the best starting point for
+information about server-side issues. Includes configuration tips and
+pointers for Samba on particular operating systems (with 40 to choose
+from...)
+</LI>
+<LI>
+<A HREF="Samba-Client-FAQ.html">Samba-Client-FAQ.html</A> is the best starting point for
+information about client-side issues, includes a list of all clients
+that are known to work with Samba.
+</LI>
+<LI>
+<A HREF="samba-man-index.html">manual pages</A> contains
+descriptions of and links to all the Samba manual pages, in Unix man and
+postscript format.
+</LI>
+<LI>
+<A HREF="samba-txt-index.html">samba-txt-index.html</A> has descriptions of and links to
+a large number of text files have been contributed to samba covering
+many topics. These are gradually being absorbed into the FAQs and HOWTOs
+but in the meantime you might find helpful answers here.
+</LI>
+<LI>
+</LI>
+</UL>
+</P>
+
+
+<HR>
+Previous
+<A HREF="Samba-meta-FAQ-2.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc1">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ-2.html b/docs/faq/Samba-meta-FAQ-2.html
new file mode 100755
index 00000000000..1e36332d426
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-2.html
@@ -0,0 +1,384 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: General Information</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-meta-FAQ-1.html">Previous</A>
+<A HREF="Samba-meta-FAQ-3.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc2">Table of Contents</A>
+<HR>
+<H2><A NAME="s2">2. General Information</A></H2>
+
+<P>
+<A NAME="general_info"></A>
+</P>
+<P>All about Samba - what it is, how to get it, related sources of
+information, how to understand the numbering scheme, pizza
+details.</P>
+
+<H2><A NAME="ss2.1">2.1 What is Samba?</A></H2>
+
+<P>
+<A NAME="introduction"></A>
+</P>
+<P>Samba is a suite of programs which work together to allow clients to
+access to a server's filespace and printers via the SMB (Server Message
+Block) and CIFS (Common Internet Filesystem) protocols. Initially
+written for Unix, Samba now also runs on Netware, OS/2, VMS, StratOS and
+Amigas. Ports to BeOS and other operating systems are underway. Samba
+gives the capability for these operating systems to behave much like a
+LAN Server, Windows NT Server or Pathworks machine, only with added
+functionality and flexibility designed to make life easier for
+administrators. </P>
+<P>This means that using Samba you can share a server's disks and printers
+to many sorts of network clients, including Lan Manager, Windows for
+Workgroups, Windows NT, Linux, OS/2, and AIX. There is also a generic
+client program supplied as part of the Samba suite which gives a user on
+the server an ftp-like interface to access filespace and printers on any
+other SMB/CIFS servers.</P>
+<P>SMB has been implemented over many protocols, including XNS, NBT, IPX,
+NetBEUI and TCP/IP. Samba only uses TCP/IP. This is not likely to change
+although there have been some requests for NetBEUI support.</P>
+<P>Many users report that compared to other SMB implementations Samba is
+more stable, faster, and compatible with more clients. Administrators of
+some large installations say that Samba is the only SMB server available
+which will scale to many tens of thousands of users without crashing.
+The easy way to test these claims is to download it and try it for
+yourself!</P>
+<P>The suite is supplied with full source code under the
+<A HREF="../COPYING">GNU Public License</A>. The GPL means that you can
+use Samba for whatever purpose you wish (including changing the source
+or selling it for money) but under all circumstances the source code
+must be made freely available. A copy of the GPL must always be included
+in any copy of the package.</P>
+<P>The primary creator of the Samba suite is Andrew Tridgell. Later
+versions incorporate much effort by many net.helpers. The man pages
+and this FAQ were originally written by Karl Auer.</P>
+
+
+<H2><A NAME="ss2.2">2.2 What is the current version of Samba?</A></H2>
+
+<P>
+<A NAME="current_version"></A>
+</P>
+<P>At time of writing, the current version was 1.9.17. If you want to be
+sure check the bottom of the change-log file.
+<A HREF="ftp://samba.org/pub/samba/alpha/change-log">ftp://samba.org/pub/samba/alpha/change-log</A></P>
+<P>For more information see
+<A HREF="#version_nums">What do the version numbers mean?</A></P>
+
+
+<H2><A NAME="ss2.3">2.3 Where can I get it? </A></H2>
+
+<P>
+<A NAME="WhereFrom"></A>
+</P>
+<P>The Samba suite is available via anonymous ftp from samba.org and
+many
+<A HREF="../MIRRORS">mirror</A> sites. You will get much
+faster performance if you use a mirror site. The latest and greatest
+versions of the suite are in the directory:</P>
+<P>/pub/samba/</P>
+<P>Development (read "alpha") versions, which are NOT necessarily stable
+and which do NOT necessarily have accurate documentation, are available
+in the directory:</P>
+<P>/pub/samba/alpha</P>
+<P>Note that binaries are NOT included in any of the above. Samba is
+distributed ONLY in source form, though binaries may be available from
+other sites. Most Linux distributions, for example, do contain Samba
+binaries for that platform. The VMS, OS/2, Netware and Amiga and other
+ports typically have binaries made available.</P>
+<P>A special case is vendor-provided binary packages. Samba binaries and
+default configuration files are put into packages for a specific
+operating system. RedHat Linux and Sun Solaris (Sparc and x86) is
+already included, and others such as OS/2 may follow. All packages are
+in the directory:</P>
+<P>/pub/samba/Binary_Packages/"OS_Vendor"</P>
+
+
+<H2><A NAME="ss2.4">2.4 What do the version numbers mean?</A></H2>
+
+<P>
+<A NAME="version_nums"></A>
+</P>
+<P>It is not recommended that you run a version of Samba with the word
+"alpha" in its name unless you know what you are doing and are willing
+to do some debugging. Many, many people just get the latest
+recommended stable release version and are happy. If you are brave, by
+all means take the plunge and help with the testing and development -
+but don't install it on your departmental server. Samba is typically
+very stable and safe, and this is mostly due to the policy of many
+public releases.</P>
+<P>How the scheme works:</P>
+<P>
+<OL>
+<LI>When major changes are made the version number is increased. For
+example, the transition from 1.9.16 to 1.9.17. However, this version
+number will not appear immediately and people should continue to use
+1.9.15 for production systems (see next point.)
+</LI>
+<LI>Just after major changes are made the software is considered
+unstable, and a series of alpha releases are distributed, for example
+1.9.16alpha1. These are for testing by those who know what they are
+doing. The "alpha" in the filename will hopefully scare off those who
+are just looking for the latest version to install.
+</LI>
+<LI>When Andrew thinks that the alphas have stabilised to the point
+where he would recommend new users install it, he renames it to the
+same version number without the alpha, for example 1.9.17.
+</LI>
+<LI>Inevitably bugs are found in the "stable" releases and minor patch
+levels are released which give us the pXX series, for example 1.9.17p2.
+</LI>
+</OL>
+</P>
+<P>So the progression goes:</P>
+<P>
+<PRE>
+ 1.9.16p10 (production)
+ 1.9.16p11 (production)
+ 1.9.17alpha1 (test sites only)
+ :
+ 1.9.17alpha20 (test sites only)
+ 1.9.17 (production)
+ 1.9.17p1 (production)
+</PRE>
+</P>
+<P>The above system means that whenever someone looks at the samba ftp
+site they will be able to grab the highest numbered release without an
+alpha in the name and be sure of getting the current recommended
+version.</P>
+
+
+<H2><A NAME="ss2.5">2.5 Where can I go for further information?</A></H2>
+
+<P>
+<A NAME="more"></A>
+</P>
+<P>There are a number of places to look for more information on Samba,
+including:</P>
+<P>
+<UL>
+<LI>Two mailing lists devoted to discussion of Samba-related matters.
+See below for subscription information.
+</LI>
+<LI>The newsgroup comp.protocols.smb, which has a great deal of
+discussion about Samba.
+</LI>
+<LI>The WWW site 'SAMBA Web Pages' at
+<A HREF="http://samba.org/samba/">http://samba.org/samba/</A> includes:
+
+<UL>
+<LI>Links to man pages and documentation, including this FAQ</LI>
+<LI>A comprehensive survey of Samba users</LI>
+<LI>A searchable hypertext archive of the Samba mailing list</LI>
+<LI>Links to Samba source code, binaries, and mirrors of both</LI>
+<LI>This FAQ and the rest in its family</LI>
+</UL>
+
+</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss2.6">2.6 How do I subscribe to the Samba Mailing Lists?</A></H2>
+
+<P>
+<A NAME="mailinglist"></A>
+</P>
+<P>Send email to
+<A HREF="mailto:listproc@samba.org">listproc@samba.org</A>. Make sure the subject line is blank,
+and include the following two lines in the body of the message:</P>
+<P>
+<BLOCKQUOTE><CODE>
+<PRE>
+subscribe samba Firstname Lastname
+subscribe samba-announce Firstname Lastname
+</PRE>
+</CODE></BLOCKQUOTE>
+</P>
+<P>Obviously you should substitute YOUR first name for "Firstname" and
+YOUR last name for "Lastname"! Try not to send any signature, it
+sometimes confuses the list processor.</P>
+<P>The samba list is a digest list - every eight hours or so it sends a
+single message containing all the messages that have been received by
+the list since the last time and sends a copy of this message to all
+subscribers. There are thousands of people on this list.</P>
+<P>If you stop being interested in Samba, please send another email to
+<A HREF="mailto:listproc@samba.org">listproc@samba.org</A>. Make sure the subject line is blank, and
+include the following two lines in the body of the message:</P>
+<P>
+<BLOCKQUOTE><CODE>
+<PRE>
+unsubscribe samba
+unsubscribe samba-announce
+</PRE>
+</CODE></BLOCKQUOTE>
+</P>
+<P>The <B>From:</B> line in your message <EM>MUST</EM> be the same
+address you used when you subscribed.</P>
+
+
+<H2><A NAME="ss2.7">2.7 Something's gone wrong - what should I do?</A></H2>
+
+<P>
+<A NAME="wrong"></A>
+</P>
+<P><B><F>#</F> *** IMPORTANT! *** <F>#</F></B></P>
+
+<P>DO NOT post messages on mailing lists or in newsgroups until you have
+carried out the first three steps given here!</P>
+<P>
+<OL>
+<LI> See if there are any likely looking entries in this FAQ!
+If you have just installed Samba, have you run through the checklist in
+<A HREF="ftp://samba.org/pub/samba/DIAGNOSIS.txt">DIAGNOSIS.txt</A>? It can save you a lot of time and effort.
+DIAGNOSIS.txt can also be found in the docs directory of the Samba
+distribution.
+</LI>
+<LI> Read the man pages for smbd, nmbd and smb.conf, looking for
+topics that relate to what you are trying to do.
+</LI>
+<LI> If there is no obvious solution to hand, try to get a look at
+the log files for smbd and/or nmbd for the period during which you
+were having problems. You may need to reconfigure the servers to
+provide more extensive debugging information - usually level 2 or
+level 3 provide ample debugging info. Inspect these logs closely,
+looking particularly for the string "Error:".
+</LI>
+<LI> If you need urgent help and are willing to pay for it see
+<A HREF="#PaidSupport">Paid Support</A>.
+</LI>
+</OL>
+</P>
+<P>If you still haven't got anywhere, ask the mailing list or newsgroup. In
+general nobody minds answering questions provided you have followed the
+preceding steps. It might be a good idea to scan the archives of the
+mailing list, which are available through the Samba web site described
+in the previous section. When you post be sure to include a good
+description of your environment and your problem.</P>
+<P>If you successfully solve a problem, please mail the FAQ maintainer a
+succinct description of the symptom, the problem and the solution, so
+that an explanation can be incorporated into the next version.</P>
+
+
+<H2><A NAME="ss2.8">2.8 How do I submit patches or bug reports?</A></H2>
+
+
+<P>If you make changes to the source code, <EM>please</EM> submit these patches
+so that everyone else gets the benefit of your work. This is one of
+the most important aspects to the maintainence of Samba. Send all
+patches to
+<A HREF="mailto:samba@samba.org">samba@samba.org</A>. Do not send patches to Andrew Tridgell or any
+other individual, they may be lost if you do.</P>
+<P>Patch format
+------------</P>
+<P>If you are sending a patch to fix a problem then please don't just use
+standard diff format. As an example, samba@samba.org received this patch from
+someone:</P>
+<P>382a
+#endif
+..
+381a
+#if !defined(NEWS61)</P>
+<P>How are we supposed to work out what this does and where it goes? These
+sort of patches only work if we both have identical files in the first
+place. The Samba sources are constantly changing at the hands of multiple
+developers, so it doesn't work.</P>
+<P>Please use either context diffs or (even better) unified diffs. You
+get these using "diff -c4" or "diff -u". If you don't have a diff that
+can generate these then please send manualy commented patches to I
+know what is being changed and where. Most patches are applied by hand so
+the info must be clear.</P>
+<P>This is a basic guideline that will assist us with assessing your problem
+more efficiently :</P>
+<P>Machine Arch:
+Machine OS:
+OS Version:
+Kernel:</P>
+<P>Compiler:
+Libc Version:</P>
+<P>Samba Version:</P>
+<P>Network Layout (description):</P>
+<P>What else is on machine (services, etc):</P>
+<P>Some extras :</P>
+<P>
+<UL>
+<LI> what you did and what happened
+</LI>
+<LI> relevant parts of a debugging output file with debuglevel higher.
+If you can't find the relevant parts, please ask before mailing
+huge files.
+</LI>
+<LI> anything else you think is useful to trace down the bug
+</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss2.9">2.9 What if I have an URGENT message for the developers?</A></H2>
+
+
+<P>If you have spotted something very serious and believe that it is
+important to contact the developers quickly send a message to
+samba-urgent@samba.org. This will be processed more quickly than
+mail to samba@samba.org. Please think carefully before using this address. An
+example of its use might be to report a security hole.</P>
+<P>Examples of things <EM>not</EM> to send to samba-urgent include problems
+getting Samba to work at all and bugs that cannot potentially cause damage.</P>
+
+
+<H2><A NAME="ss2.10">2.10 What if I need paid-for support?</A></H2>
+
+<P>
+<A NAME="PaidSupport"></A>
+</P>
+<P>Samba has a large network of consultants who provide Samba support on a
+commercial basis. The list is included in the package in
+<A HREF="../Support.txt">../Support.txt</A>, and the latest version will always be on the main
+samba ftp site. Any company in the world can request that the samba team
+include their details in Support.txt so we can give no guarantee of
+their services.</P>
+
+
+<H2><A NAME="ss2.11">2.11 Pizza supply details</A></H2>
+
+<P>
+<A NAME="pizza"></A>
+
+Those who have registered in the Samba survey as "Pizza Factory" will
+already know this, but the rest may need some help. Andrew doesn't ask
+for payment, but he does appreciate it when people give him
+pizza. This calls for a little organisation when the pizza donor is
+twenty thousand kilometres away, but it has been done.</P>
+<P>
+<OL>
+<LI> Ring up your local branch of an international pizza chain
+and see if they honour their vouchers internationally. Pizza Hut do,
+which is how the entire Canberra Linux Users Group got to eat pizza
+one night, courtesy of someone in the US.
+</LI>
+<LI>Ring up a local pizza shop in Canberra and quote a credit
+card number for a certain amount, and tell them that Andrew will be
+collecting it (don't forget to tell him.) One kind soul from Germany
+did this.
+</LI>
+<LI>Purchase a pizza voucher from your local pizza shop that has
+no international affiliations and send it to Andrew. It is completely
+useless but he can hang it on the wall next to the one he already has
+from Germany :-)
+</LI>
+<LI>Air freight him a pizza with your favourite regional
+flavours. It will probably get stuck in customs or torn apart by
+hungry sniffer dogs but it will have been a noble gesture.
+</LI>
+</OL>
+</P>
+
+
+<HR>
+<A HREF="Samba-meta-FAQ-1.html">Previous</A>
+<A HREF="Samba-meta-FAQ-3.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc2">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ-3.html b/docs/faq/Samba-meta-FAQ-3.html
new file mode 100755
index 00000000000..8ebb38a3345
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-3.html
@@ -0,0 +1,101 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: About the CIFS and SMB Protocols</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-meta-FAQ-2.html">Previous</A>
+<A HREF="Samba-meta-FAQ-4.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc3">Table of Contents</A>
+<HR>
+<H2><A NAME="s3">3. About the CIFS and SMB Protocols</A></H2>
+
+<P>
+<A NAME="CifsSmb"></A>
+</P>
+
+<H2><A NAME="ss3.1">3.1 What is the Server Message Block (SMB) Protocol?</A></H2>
+
+<P>SMB is a filesharing protocol that has had several maintainers and
+contributors over the years including Xerox, 3Com and most recently
+Microsoft. Names for this protocol include LAN Manager and Microsoft
+Networking. Parts of the specification has been made public at several
+versions including in an X/Open document, as listed at
+<A HREF="ftp://ftp.microsoft.com/developr/drg/CIFS/">ftp://ftp.microsoft.com/developr/drg/CIFS/</A>. No specification
+releases were made between 1992 and 1996, and during that period
+Microsoft became the SMB implementor with the largest market share.
+Microsoft developed the specification further for its products but for
+various reasons connected with developer's workload rather than market
+strategy did not make the changes public. This culminated with the
+"Windows NT 0.12" version released with NT 3.5 in 1995 which had significant
+improvements and bugs. Because Microsoft client systems are so popular,
+it is fair to say that what Microsoft with Windows affects all suppliers
+of SMB server products.</P>
+<P>From 1994 Andrew Tridgell began doing some serious work on his
+Smbserver (now Samba) product and with some helpers started to
+implement more and more of these protocols. Samba began to take
+a significant share of the SMB server market.</P>
+
+
+<H2><A NAME="ss3.2">3.2 What is the Common Internet Filesystem (CIFS)?</A></H2>
+
+<P>The initial pressure for Microsoft to document their current SMB
+implementation came from the Samba team, who kept coming across things
+on the wire that Microsoft either didn't know about or hadn't documented
+anywhere (even in the sourcecode to Windows NT.) Then Sun Microsystems
+came out with their WebNFS initiative, designed to replace FTP for file
+transfers on the Internet. There are many drawbacks to WebNFS (including
+its scope - it aims to replace HTTP as well!) but the concept was
+attractive. FTP is not very clever, and why should it be harder to get
+files from across the world than across the room? </P>
+<P>Some hasty revisions were made and an Internet Draft for the Common
+Internet Filesystem (CIFS) was released. Note that CIFS is not an
+Internet standard and is a very long way from becoming one, BUT the
+protocol specification is in the public domain and ongoing discussions
+concerning the spec take place on a public mailing list according to the
+rules of the Internet Engineering Task Force. For more information and
+pointers see
+<A HREF="http://samba.org/cifs/">http://samba.org/cifs/</A></P>
+<P>The following is taken from
+<A HREF="http://www.microsoft.com/intdev/cifs/">http://www.microsoft.com/intdev/cifs/</A></P>
+<P>
+<PRE>
+ CIFS defines a standard remote file system access protocol for use
+ over the Internet, enabling groups of users to work together and
+ share documents across the Internet or within their corporate
+ intranets. CIFS is an open, cross-platform technology based on the
+ native file-sharing protocols built into Microsoft® Windows® and
+ other popular PC operating systems, and supported on dozens of
+ other platforms, including UNIX®. With CIFS, millions of computer
+ users can open and share remote files on the Internet without having
+ to install new software or change the way they work.&quot;
+</PRE>
+</P>
+<P>If you consider CIFS as a backwardsly-compatible refinement of SMB that
+will work reasonably efficiently over the Internet you won't be too far
+wrong.</P>
+<P>The net effect is that Microsoft is now documenting large parts of their
+Windows NT fileserver protocols. The security concepts embodied in
+Windows NT are part of the specification, which is why Samba
+documentation often talks in terms of Windows NT. However there is no
+reason why a site shouldn't conduct all its file and printer sharing
+with CIFS and yet have no Microsoft products at all.</P>
+
+
+<H2><A NAME="ss3.3">3.3 What is Browsing? </A></H2>
+
+<P>The term "Browsing" causes a lot of confusion. It is the part of the
+SMB/CIFS protocol which allows for resource discovery. For example, in
+the Windows NT Explorer it is possible to see a "Network Neighbourhood"
+of computers in the same SMB workgroup. Clicking on the name of one of
+these machines brings up a list of file and printer resources for
+connecting to. In this way you can cruise the network, seeing what
+things are available. How this scales to the Internet is a subject for
+debate. Look at the CIFS list archives to see what the experts think.</P>
+
+
+<HR>
+<A HREF="Samba-meta-FAQ-2.html">Previous</A>
+<A HREF="Samba-meta-FAQ-4.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc3">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ-4.html b/docs/faq/Samba-meta-FAQ-4.html
new file mode 100755
index 00000000000..73a9eea8471
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-4.html
@@ -0,0 +1,215 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: Designing A SMB and CIFS Network</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-meta-FAQ-3.html">Previous</A>
+<A HREF="Samba-meta-FAQ-5.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc4">Table of Contents</A>
+<HR>
+<H2><A NAME="s4">4. Designing A SMB and CIFS Network</A></H2>
+
+
+<P>The big issues for installing any network of LAN or WAN file and print
+servers are </P>
+<P>
+<UL>
+<LI>How and where usernames, passwords and other security information
+is stored
+</LI>
+<LI>What method can be used for locating the resources that users have
+permission to use
+</LI>
+<LI>What protocols the clients can converse with
+</LI>
+</UL>
+ </P>
+<P>If you buy Netware, Windows NT or just about any other LAN fileserver
+product you are expected to lock yourself into the product's preferred
+answers to these questions. This tendancy is restrictive and often very
+expensive for a site where there is only one kind of client or server,
+and for sites with a mixture of operating systems it often makes it
+impossible to share resources between some sets of users.</P>
+<P>The Samba philosophy is to make things as easy as possible for
+administators, which means allowing as many combinations of clients,
+servers, operating systems and protocols as possible.</P>
+
+<H2><A NAME="ss4.1">4.1 Workgroups, Domains, Authentication and Browsing</A></H2>
+
+
+<P>From the point of view of networking implementation, Domains and
+Workgroups are <EM>exactly</EM> the same, except for the client logon
+sequence. Some kind of distributed authentication database is associated
+with a domain (there are quite a few choices) and this adds so much
+flexibility that many people think of a domain as a completely different
+entity to a workgroup. From Samba's point of view a client connecting to
+a service presents an authentication token, and it if it is valid they
+have access. Samba does not care what mechanism was used to generate
+that token in the first place.</P>
+<P>The SMB client logging on to a domain has an expectation that every other
+server in the domain should accept the same authentication information.
+However the network browsing functionality of domains and workgroups is
+identical and is explained in
+<A HREF="../BROWSING.txt">../BROWSING.txt</A>.</P>
+<P>There are some implementation differences: Windows 95 can be a member of
+both a workgroup and a domain, but Windows NT cannot. Windows 95 also
+has the concept of an "alternative workgroup". Samba can only be a
+member of a single workgroup or domain, although this is due to change
+with a future version when nmbd will be split into two daemons, one for
+WINS and the other for browsing (
+<A HREF="../NetBIOS.txt">../NetBIOS.txt</A> explains
+what WINS is.)</P>
+
+<H3>Defining the Terms</H3>
+
+<P>
+<A NAME="BrowseAndDomainDefs"></A>
+</P>
+<P>
+<DL>
+
+<DT><B>Workgroup</B><DD><P>means a collection of machines that maintain a common
+browsing database containing information about their shared resources.
+They do not necessarily have any security information in common (if they
+do, it gets called a Domain.) The browsing database is dynamic, modified
+as servers come and go on the network and as resources are added or
+deleted. The term "browsing" refers to a user accessing the database via
+whatever interface the client provides, eg the OS/2 Workplace Shell or
+Windows 95 Explorer. SMB servers agree between themselves as to which
+ones will maintain the browsing database. Workgroups can be anywhere on
+a connected TCP/IP network, including on different subnets or even on
+the Interet. This is a very tricky part of SMB to implement.</P>
+
+<DT><B>Master Browsers</B><DD><P>are machines which holds the master browsing
+database for a workgroup or domain. There are two kinds of Master Browser:</P>
+<P>
+<UL>
+<LI> Domain Master Browser, which holds the master browsing
+information for an entire domain, which may well cross multiple TCP/IP
+subnets.
+</LI>
+<LI> Local Master Browser, which holds the master browsing database
+for a particular subnet and communicates with the Domain Master Browser
+to get information on other subnets.
+</LI>
+</UL>
+</P>
+<P>Subnets are differentiated because browsing is based on broadcasts, and
+broadcasts do not pass through routers. Subnets are not routed: while it
+is possible to have more than one subnet on a single network segment
+this is regarded as very bad practice.</P>
+<P>Master Browsers (both Domain and Local) are elected dynamically
+according to an algorithm which is supposed to take into account the
+machine's ability to sustain the browsing load. Samba can be configured
+to always act as a master browser, ie it always wins elections under all
+circumstances, even against systems such as a Windows NT Primary Domain
+Controller which themselves expect to win. </P>
+<P>There are also Backup Browsers which are promoted to Master Browsers in
+the event of a Master Browser disappearing from the network.</P>
+<P>Alternative terms include confusing variations such as "Browse Master",
+and "Master Browser" which we are trying to eliminate from the Samba
+documentation. </P>
+
+<DT><B>Domain Controller</B><DD><P>is a term which comes from the Microsoft and IBM
+etc implementation of the LAN Manager protocols. It is tied to
+authentication. There are other ways of doing domain authentication, but
+the Windows NT method has a large market share. The general issues are
+discussed in
+<A HREF="../DOMAIN.txt">../DOMAIN.txt</A> and a Windows NT-specific
+discussion is in
+<A HREF="../DOMAIN_CONTROL.txt">../DOMAIN_CONTROL.txt</A>.</P>
+
+</DL>
+</P>
+
+<H3>Sharelevel (Workgroup) Security Services</H3>
+
+<P>
+<A NAME="ShareModeSecurity"></A>
+</P>
+<P>With the Samba setting "security = SHARE", all shared resources
+information about what password is associated with them but only hints
+as to what usernames might be valid (the hint can be 'all users', in
+which case any username will work. This is usually a bad idea, but
+reflects both the initial implementations of SMB in the mid-80s and
+its reincarnation with Windows for Workgroups in 1992. The idea behind
+workgroup security was that small independant groups of people could
+share information on an ad-hoc basis without there being an
+authentication infrastructure present or requiring them to do more than
+fill in a dialogue box.</P>
+
+<H3>Authentication Domain Mode Services</H3>
+
+<P>
+<A NAME="DomainModeSecurity"></A>
+</P>
+<P>With the Samba settings "security = USER" or "security = SERVER"
+accesses to all resources are checked for username/password pair matches
+in a more rigorous manner. To the client, this has the effect of
+emulating a Microsoft Domain. The client is not concerned whether or not
+Samba looks up a Windows NT SAM or does it in some other way.</P>
+
+
+<H2><A NAME="ss4.2">4.2 Authentication Schemes</A></H2>
+
+
+<P>In the simple case authentication information is stored on a single
+server and the user types a password on connecting for the first time.
+However client operating systems often require a password before they
+can be used at all, and in addition users usually want access to more
+than one server. Asking users to remember many different passwords in
+different contexts just does not work. Some kind of distributed
+authentication database is needed. It must cope with password changes
+and provide for assigning groups of users the same level of access
+permissions. This is why Samba installations often choose to implement a
+Domain model straight away.</P>
+<P>Authentication decisions are some of the biggest in designing a network.
+Are you going to use a scheme native to the client operating system,
+native to the server operating system, or newly installed on both? A
+list of options relevant to Samba (ie that make sense in the context of
+the SMB protocol) follows. Any experiences with other setups would be
+appreciated. <F>refer to server FAQ for "passwd chat" passwd program
+password server etc etc...</F></P>
+
+<H3>NIS</H3>
+
+
+<P>For Windows 95, Windows for Workgroups and most other clients Samba can
+be a domain controller and share the password database via NIS
+transparently. Windows NT is different.
+<A HREF="http://www.dcs.qmw.ac.uk/~williams">Free NIS NT client</A></P>
+
+<H3>Kerberos</H3>
+
+
+<P>Kerberos for US users only:
+<A HREF="http://www.cygnus.com/product/unifying-security.html">Kerberos overview</A>
+<A HREF="http://www.cygnus.com/product/kerbnet-download.html">Download Kerberos</A></P>
+
+<H3>FTP</H3>
+
+
+<P>Other NT w/s logon hack via NT</P>
+
+<H3>Default Server Method</H3>
+
+
+
+<H3>Client-side Database Only</H3>
+
+
+
+
+<H2><A NAME="ss4.3">4.3 Post-Authentication: Netlogon, Logon Scripts, Profiles</A></H2>
+
+
+<P>See
+<A HREF="../DOMAIN.txt">../DOMAIN.txt</A></P>
+
+
+<HR>
+<A HREF="Samba-meta-FAQ-3.html">Previous</A>
+<A HREF="Samba-meta-FAQ-5.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc4">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ-5.html b/docs/faq/Samba-meta-FAQ-5.html
new file mode 100755
index 00000000000..ad528b0a975
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-5.html
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: Cross-Protocol File Sharing</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-meta-FAQ-4.html">Previous</A>
+<A HREF="Samba-meta-FAQ-6.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc5">Table of Contents</A>
+<HR>
+<H2><A NAME="s5">5. Cross-Protocol File Sharing</A></H2>
+
+
+<P>Samba is an important tool for...</P>
+<P>It is possible to...</P>
+<P>File protocol gateways...</P>
+<P>"Setting up a Linux File Server" http://vetrec.mit.edu/people/narf/linux.html</P>
+<P>Two free implementations of Appletalk for Unix are Netatalk,
+<A HREF="http://www.umich.edu/~rsug/netatalk/">http://www.umich.edu/~rsug/netatalk/</A>, and CAP,
+<A HREF="http://www.cs.mu.oz.au/appletalk/atalk.html">http://www.cs.mu.oz.au/appletalk/atalk.html</A>. What Samba offers MS
+Windows users, these packages offer to Macs. For more info on these
+packages, Samba, and Linux (and other UNIX-based systems) see
+<A HREF="http://www.eats.com/linux_mac_win.html">http://www.eats.com/linux_mac_win.html</A> 3.5) Sniffing your nework</P>
+
+
+<HR>
+<A HREF="Samba-meta-FAQ-4.html">Previous</A>
+<A HREF="Samba-meta-FAQ-6.html">Next</A>
+<A HREF="Samba-meta-FAQ.html#toc5">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ-6.html b/docs/faq/Samba-meta-FAQ-6.html
new file mode 100755
index 00000000000..f8cd7817d69
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ-6.html
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ: Miscellaneous</TITLE>
+</HEAD>
+<BODY>
+<A HREF="Samba-meta-FAQ-5.html">Previous</A>
+Next
+<A HREF="Samba-meta-FAQ.html#toc6">Table of Contents</A>
+<HR>
+<H2><A NAME="s6">6. Miscellaneous</A></H2>
+
+<P>
+<A NAME="miscellaneous"></A>
+</P>
+<H2><A NAME="ss6.1">6.1 Is Samba Year 2000 compliant?</A></H2>
+
+<P>
+<A NAME="Year2000Compliant"></A>
+
+The CIFS protocol that Samba implements
+negotiates times in various formats, all of which
+are able to cope with dates beyond 2000.</P>
+
+
+<HR>
+<A HREF="Samba-meta-FAQ-5.html">Previous</A>
+Next
+<A HREF="Samba-meta-FAQ.html#toc6">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ.html b/docs/faq/Samba-meta-FAQ.html
new file mode 100755
index 00000000000..38f094bf339
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ.html
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<HTML>
+<HEAD>
+<TITLE> Samba meta FAQ</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="Samba-meta-FAQ-1.html">Next</A>
+Table of Contents
+<HR>
+<H1> Samba meta FAQ</H1>
+
+<H2>Dan Shearer & Paul Blackman, <CODE>ictinus@samba.org</CODE></H2>v 0.3, 7 Oct '97
+<P><HR><EM> This is the meta-Frequently Asked Questions (FAQ) document
+for Samba, the free and very popular SMB and CIFS server product. It
+contains overview information for the Samba suite of programs, a
+quick-start guide, and pointers to all other Samba documentation. Other
+FAQs exist for specific client and server issues, and HOWTO documents
+for more extended topics to do with Samba software. Current to version
+Samba 1.9.17. Please send any corrections to the author. </EM><HR></P>
+<P>
+<H2><A NAME="toc1">1.</A> <A HREF="Samba-meta-FAQ-1.html">Quick Reference Guides to Samba Documentation</A></H2>
+<UL>
+<LI><A HREF="Samba-meta-FAQ-1.html#ss1.1">1.1 Samba for the Impatient</A>
+<LI><A HREF="Samba-meta-FAQ-1.html#ss1.2">1.2 All Samba Documentation</A>
+</UL>
+
+<P>
+<H2><A NAME="toc2">2.</A> <A HREF="Samba-meta-FAQ-2.html">General Information</A></H2>
+<UL>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.1">2.1 What is Samba?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.2">2.2 What is the current version of Samba?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.3">2.3 Where can I get it? </A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.4">2.4 What do the version numbers mean?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.5">2.5 Where can I go for further information?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.6">2.6 How do I subscribe to the Samba Mailing Lists?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.7">2.7 Something's gone wrong - what should I do?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.8">2.8 How do I submit patches or bug reports?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.9">2.9 What if I have an URGENT message for the developers?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.10">2.10 What if I need paid-for support?</A>
+<LI><A HREF="Samba-meta-FAQ-2.html#ss2.11">2.11 Pizza supply details</A>
+</UL>
+
+<P>
+<H2><A NAME="toc3">3.</A> <A HREF="Samba-meta-FAQ-3.html">About the CIFS and SMB Protocols</A></H2>
+<UL>
+<LI><A HREF="Samba-meta-FAQ-3.html#ss3.1">3.1 What is the Server Message Block (SMB) Protocol?</A>
+<LI><A HREF="Samba-meta-FAQ-3.html#ss3.2">3.2 What is the Common Internet Filesystem (CIFS)?</A>
+<LI><A HREF="Samba-meta-FAQ-3.html#ss3.3">3.3 What is Browsing? </A>
+</UL>
+
+<P>
+<H2><A NAME="toc4">4.</A> <A HREF="Samba-meta-FAQ-4.html">Designing A SMB and CIFS Network</A></H2>
+<UL>
+<LI><A HREF="Samba-meta-FAQ-4.html#ss4.1">4.1 Workgroups, Domains, Authentication and Browsing</A>
+<LI><A HREF="Samba-meta-FAQ-4.html#ss4.2">4.2 Authentication Schemes</A>
+<LI><A HREF="Samba-meta-FAQ-4.html#ss4.3">4.3 Post-Authentication: Netlogon, Logon Scripts, Profiles</A>
+</UL>
+
+<P>
+<H2><A NAME="toc5">5.</A> <A HREF="Samba-meta-FAQ-5.html">Cross-Protocol File Sharing</A></H2>
+
+<P>
+<H2><A NAME="toc6">6.</A> <A HREF="Samba-meta-FAQ-6.html">Miscellaneous</A></H2>
+<UL>
+<LI><A HREF="Samba-meta-FAQ-6.html#ss6.1">6.1 Is Samba Year 2000 compliant?</A>
+</UL>
+
+
+<HR>
+Previous
+<A HREF="Samba-meta-FAQ-1.html">Next</A>
+Table of Contents
+</BODY>
+</HTML>
diff --git a/docs/faq/Samba-meta-FAQ.sgml b/docs/faq/Samba-meta-FAQ.sgml
new file mode 100755
index 00000000000..377d81663d7
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ.sgml
@@ -0,0 +1,771 @@
+<!doctype linuxdoc system> <!-- -*- SGML -*- -->
+<!--
+ v 0.1 23 Aug 1997 Dan Shearer
+ Original Samba-meta-FAQ.sgml from Paul's sambafaq.sgml
+ v 0.2 25 Aug 1997 Dan
+ v 0.3 7 Oct 1997 Paul
+ Changed samba.canberra refs to samba.anu.../samba/
+-->
+
+<article>
+
+<title> Samba meta FAQ
+
+<author>Dan Shearer & Paul Blackman, <tt>ictinus@samba.org</tt>
+
+<date>v 0.3, 7 Oct '97
+
+<abstract> This is the meta-Frequently Asked Questions (FAQ) document
+for Samba, the free and very popular SMB and CIFS server product. It
+contains overview information for the Samba suite of programs, a
+quick-start guide, and pointers to all other Samba documentation. Other
+FAQs exist for specific client and server issues, and HOWTO documents
+for more extended topics to do with Samba software. Current to version
+Samba 1.9.17. Please send any corrections to the author.
+</abstract>
+
+<toc>
+
+<sect> Quick Reference Guides to Samba Documentation<p><label id=quickref>
+
+We are endeavouring to provide links here to every major class of
+information about Samba or things related to Samba. We cannot list every
+document, but we are aiming for all documents to be at most two
+referrals from those listed here. This needs constant maintaining, so
+please send the author your feedback.
+
+<sect1> Samba for the Impatient<p><label id="impatient">
+
+You know you should read the documentation but can't wait to start? What
+you need to do then is follow the instructions in the following
+documents in the order given. This should be enough to get a fairly
+simple site going quickly. If you have any problems, refer back to this
+meta-FAQ and follow the links to find more reading material.
+
+<descrip>
+
+<label id="ImpGet"><tag/Getting Samba:/ The fastest way to get Samba
+going is and install it is to have an operating system for which the
+Samba team has put together an installation package. To see if your OS
+is included have a look at the directory
+/pub/samba/Binary_Packages/"OS_Vendor" on your nearest <url
+url="../MIRRORS" name="mirror site">. If it is included follow the
+installation instructions in the README file there and then do some <ref id="ImpTest"
+name="basic testing">. If you are not so fortunate, follow the normal <ref
+id="WhereFrom" name="download instructions"> and then continue with <ref
+id="ImpInst" name="building and installing Samba">.
+
+<label id="ImpInst"><tag/Building and Installing Samba:/ At the moment
+there are two kinds of Samba server installs besides the prepackaged
+binaries mentioned in the previous step. You need to decide if you have a <url url="../UNIX_INSTALL.txt"
+name="Unix or close relative"> or <url
+url="Samba-Server-FAQ.html#PortInfo" name="other supported operating system">.
+
+<label id="ImpTest"><tag/Basic Testing:/ Try to connect using the
+supplied smbclient command-line program. You need to know the IP
+hostname of your server. A service name must be defined in smb.conf, as
+given in the examples (under many operating systems if there is a
+[homes] service you can just use a valid username.) Then type
+<tt>
+ smbclient \\hostname\servicename
+</tt>
+Under most Unixes you will need to put the parameters within quotation
+marks. If this works, try connecting from one of the SMB clients you
+were planning to use with Samba.
+
+<label id="ImpDebug"><tag/Debug sequence:/ If you think you have completed the
+previous step and things aren't working properly work through
+<url url="../DIAGNOSIS.txt" name="the diagnosis recipe.">
+
+<label id="ImpExp"><tag/Exporting files to SMB clients:/ You should read the manual pages
+for smb.conf, but here is a <url url="Samba-Server-FAQ.html#Exporting"
+name="quick answer guide.">
+
+<label id="ImpControl"><tag/Controlling user access:/ the quickest and dirtiest way of sharing
+resources is to use <ref id="ShareModeSecurity" name="share level
+security."> If you want to spend more time and have a proper username
+and password database you must read the paragraph on <ref
+id="DomainModeSecurity" name="domain mode security."> If you want
+encryption (eg you are using Windows NT clients) follow the <url
+url="Samba-Server-FAQ.html#SMBEncryptionSteps" name="SMB encryption
+instructions.">
+
+<label id="ImpBrowse"><tag/Browsing:/ if you are happy to type in "\\samba-server\sharename"
+at the client end then do not read any further. Otherwise you need to
+understand the <ref id="BrowsingDefinitions" name="browsing terminology">
+and read <url url="Samba-Server-FAQ.html#NameBrowsing">.
+
+<label id="ImpPrint"><tag/Printing:/ See the <url url="Samba-Server-FAQ.html#Printing"
+name="printing quick answer guide.">
+
+</descrip>
+
+If you have got everything working to this point, you can expect Samba
+to be stable and secure: these are its greatest strengths. However Samba
+has a great deal to offer and to go further you must do some more
+reading. Speed and security optimisations, printer accounting, network
+logons, roving profiles, browsing across multiple subnets and so on are
+all covered either in this document or in those it refers to.
+
+<sect1> All Samba Documentation<p><label id=AllDocs>
+
+<itemize>
+
+<item> Meta-FAQ. This is the mother of all documents, and is the one you
+are reading now. The latest version is always at <url
+url="http://samba.org/[.....]"> but there is probably a much
+nearer <url url="../MIRRORS" name="mirror site"> which you should use
+instead.
+
+<item> <url url="Samba-Server-FAQ.html"> is the best starting point for
+information about server-side issues. Includes configuration tips and
+pointers for Samba on particular operating systems (with 40 to choose
+from...)
+
+<item> <url url="Samba-Client-FAQ.html"> is the best starting point for
+information about client-side issues, includes a list of all clients
+that are known to work with Samba.
+
+<item> <url url="samba-man-index.html" name="manual pages"> contains
+descriptions of and links to all the Samba manual pages, in Unix man and
+postscript format.
+
+<item> <url url="samba-txt-index.html"> has descriptions of and links to
+a large number of text files have been contributed to samba covering
+many topics. These are gradually being absorbed into the FAQs and HOWTOs
+but in the meantime you might find helpful answers here.
+
+<item>
+
+</itemize>
+
+<sect> General Information<p><label id="general_info">
+
+All about Samba - what it is, how to get it, related sources of
+information, how to understand the numbering scheme, pizza
+details.
+
+<sect1> What is Samba?<p><label id="introduction">
+
+Samba is a suite of programs which work together to allow clients to
+access to a server's filespace and printers via the SMB (Server Message
+Block) and CIFS (Common Internet Filesystem) protocols. Initially
+written for Unix, Samba now also runs on Netware, OS/2, VMS, StratOS and
+Amigas. Ports to BeOS and other operating systems are underway. Samba
+gives the capability for these operating systems to behave much like a
+LAN Server, Windows NT Server or Pathworks machine, only with added
+functionality and flexibility designed to make life easier for
+administrators.
+
+This means that using Samba you can share a server's disks and printers
+to many sorts of network clients, including Lan Manager, Windows for
+Workgroups, Windows NT, Linux, OS/2, and AIX. There is also a generic
+client program supplied as part of the Samba suite which gives a user on
+the server an ftp-like interface to access filespace and printers on any
+other SMB/CIFS servers.
+
+SMB has been implemented over many protocols, including XNS, NBT, IPX,
+NetBEUI and TCP/IP. Samba only uses TCP/IP. This is not likely to change
+although there have been some requests for NetBEUI support.
+
+Many users report that compared to other SMB implementations Samba is
+more stable, faster, and compatible with more clients. Administrators of
+some large installations say that Samba is the only SMB server available
+which will scale to many tens of thousands of users without crashing.
+The easy way to test these claims is to download it and try it for
+yourself!
+
+The suite is supplied with full source code under the <url
+url="../COPYING" name="GNU Public License">. The GPL means that you can
+use Samba for whatever purpose you wish (including changing the source
+or selling it for money) but under all circumstances the source code
+must be made freely available. A copy of the GPL must always be included
+in any copy of the package.
+
+The primary creator of the Samba suite is Andrew Tridgell. Later
+versions incorporate much effort by many net.helpers. The man pages
+and this FAQ were originally written by Karl Auer.
+
+<sect1> What is the current version of Samba?<p><label id="current_version">
+
+At time of writing, the current version was 1.9.17. If you want to be
+sure check the bottom of the change-log file. <url url="ftp://samba.org/pub/samba/alpha/change-log">
+
+For more information see <ref id="version_nums" name="What do the version numbers mean?">
+
+<sect1> Where can I get it? <p><label id="WhereFrom">
+
+The Samba suite is available via anonymous ftp from samba.org and
+many <url url="../MIRRORS" name="mirror"> sites. You will get much
+faster performance if you use a mirror site. The latest and greatest
+versions of the suite are in the directory:
+
+/pub/samba/
+
+Development (read "alpha") versions, which are NOT necessarily stable
+and which do NOT necessarily have accurate documentation, are available
+in the directory:
+
+/pub/samba/alpha
+
+Note that binaries are NOT included in any of the above. Samba is
+distributed ONLY in source form, though binaries may be available from
+other sites. Most Linux distributions, for example, do contain Samba
+binaries for that platform. The VMS, OS/2, Netware and Amiga and other
+ports typically have binaries made available.
+
+A special case is vendor-provided binary packages. Samba binaries and
+default configuration files are put into packages for a specific
+operating system. RedHat Linux and Sun Solaris (Sparc and x86) is
+already included, and others such as OS/2 may follow. All packages are
+in the directory:
+
+/pub/samba/Binary_Packages/"OS_Vendor"
+
+<sect1>What do the version numbers mean?<p><label id="version_nums">
+
+It is not recommended that you run a version of Samba with the word
+"alpha" in its name unless you know what you are doing and are willing
+to do some debugging. Many, many people just get the latest
+recommended stable release version and are happy. If you are brave, by
+all means take the plunge and help with the testing and development -
+but don't install it on your departmental server. Samba is typically
+very stable and safe, and this is mostly due to the policy of many
+public releases.
+
+How the scheme works:
+
+<enum>
+
+<item>When major changes are made the version number is increased. For
+example, the transition from 1.9.16 to 1.9.17. However, this version
+number will not appear immediately and people should continue to use
+1.9.15 for production systems (see next point.)
+
+<item>Just after major changes are made the software is considered
+unstable, and a series of alpha releases are distributed, for example
+1.9.16alpha1. These are for testing by those who know what they are
+doing. The "alpha" in the filename will hopefully scare off those who
+are just looking for the latest version to install.
+
+<item>When Andrew thinks that the alphas have stabilised to the point
+where he would recommend new users install it, he renames it to the
+same version number without the alpha, for example 1.9.17.
+
+<item>Inevitably bugs are found in the "stable" releases and minor patch
+levels are released which give us the pXX series, for example 1.9.17p2.
+
+</enum>
+
+So the progression goes:
+
+<verb>
+ 1.9.16p10 (production)
+ 1.9.16p11 (production)
+ 1.9.17alpha1 (test sites only)
+ :
+ 1.9.17alpha20 (test sites only)
+ 1.9.17 (production)
+ 1.9.17p1 (production)
+</verb>
+
+The above system means that whenever someone looks at the samba ftp
+site they will be able to grab the highest numbered release without an
+alpha in the name and be sure of getting the current recommended
+version.
+
+<sect1> Where can I go for further information?<p><label id="more">
+
+There are a number of places to look for more information on Samba,
+including:
+
+<itemize>
+
+<item>Two mailing lists devoted to discussion of Samba-related matters.
+See below for subscription information.
+
+<item>The newsgroup comp.protocols.smb, which has a great deal of
+discussion about Samba.
+
+<item>The WWW site 'SAMBA Web Pages' at <url
+url="http://samba.org/samba/"> includes:
+
+ <itemize>
+ <item>Links to man pages and documentation, including this FAQ
+ <item>A comprehensive survey of Samba users
+ <item>A searchable hypertext archive of the Samba mailing list
+ <item>Links to Samba source code, binaries, and mirrors of both
+ <item>This FAQ and the rest in its family
+ </itemize>
+
+</itemize>
+
+<sect1>How do I subscribe to the Samba Mailing Lists?<p><label id="mailinglist">
+
+Send email to <htmlurl url="mailto:listproc@samba.org"
+name="listproc@samba.org">. Make sure the subject line is blank,
+and include the following two lines in the body of the message:
+
+<tscreen><verb>
+subscribe samba Firstname Lastname
+subscribe samba-announce Firstname Lastname
+</verb></tscreen>
+
+Obviously you should substitute YOUR first name for "Firstname" and
+YOUR last name for "Lastname"! Try not to send any signature, it
+sometimes confuses the list processor.
+
+The samba list is a digest list - every eight hours or so it sends a
+single message containing all the messages that have been received by
+the list since the last time and sends a copy of this message to all
+subscribers. There are thousands of people on this list.
+
+If you stop being interested in Samba, please send another email to
+<htmlurl url="mailto:listproc@samba.org" name="listproc@samba.org">. Make sure the subject line is blank, and
+include the following two lines in the body of the message:
+
+<tscreen><verb>
+unsubscribe samba
+unsubscribe samba-announce
+</verb></tscreen>
+
+The <bf>From:</bf> line in your message <em>MUST</em> be the same
+address you used when you subscribed.
+
+<sect1> Something's gone wrong - what should I do?<p><label id="wrong">
+
+<bf>[#] *** IMPORTANT! *** [#]</bf>
+<p>
+
+DO NOT post messages on mailing lists or in newsgroups until you have
+carried out the first three steps given here!
+
+<enum> <item> See if there are any likely looking entries in this FAQ!
+If you have just installed Samba, have you run through the checklist in
+<url url="ftp://samba.org/pub/samba/DIAGNOSIS.txt"
+name="DIAGNOSIS.txt">? It can save you a lot of time and effort.
+DIAGNOSIS.txt can also be found in the docs directory of the Samba
+distribution.
+
+<item> Read the man pages for smbd, nmbd and smb.conf, looking for
+topics that relate to what you are trying to do.
+
+<item> If there is no obvious solution to hand, try to get a look at
+the log files for smbd and/or nmbd for the period during which you
+were having problems. You may need to reconfigure the servers to
+provide more extensive debugging information - usually level 2 or
+level 3 provide ample debugging info. Inspect these logs closely,
+looking particularly for the string "Error:".
+
+<item> If you need urgent help and are willing to pay for it see
+<ref id="PaidSupport" name="Paid Support">.
+
+</enum>
+
+If you still haven't got anywhere, ask the mailing list or newsgroup. In
+general nobody minds answering questions provided you have followed the
+preceding steps. It might be a good idea to scan the archives of the
+mailing list, which are available through the Samba web site described
+in the previous section. When you post be sure to include a good
+description of your environment and your problem.
+
+If you successfully solve a problem, please mail the FAQ maintainer a
+succinct description of the symptom, the problem and the solution, so
+that an explanation can be incorporated into the next version.
+
+<sect1> How do I submit patches or bug reports?<p>
+
+If you make changes to the source code, <em>please</em> submit these patches
+so that everyone else gets the benefit of your work. This is one of
+the most important aspects to the maintainence of Samba. Send all
+patches to <htmlurl url="mailto:samba@samba.org" name="samba@samba.org">. Do not send patches to Andrew Tridgell or any
+other individual, they may be lost if you do.
+
+Patch format
+------------
+
+If you are sending a patch to fix a problem then please don't just use
+standard diff format. As an example, samba@samba.org received this patch from
+someone:
+
+382a
+#endif
+..
+381a
+#if !defined(NEWS61)
+
+How are we supposed to work out what this does and where it goes? These
+sort of patches only work if we both have identical files in the first
+place. The Samba sources are constantly changing at the hands of multiple
+developers, so it doesn't work.
+
+Please use either context diffs or (even better) unified diffs. You
+get these using "diff -c4" or "diff -u". If you don't have a diff that
+can generate these then please send manualy commented patches to I
+know what is being changed and where. Most patches are applied by hand so
+the info must be clear.
+
+This is a basic guideline that will assist us with assessing your problem
+more efficiently :
+
+Machine Arch:
+Machine OS:
+OS Version:
+Kernel:
+
+Compiler:
+Libc Version:
+
+Samba Version:
+
+Network Layout (description):
+
+What else is on machine (services, etc):
+
+Some extras :
+
+<itemize>
+
+<item> what you did and what happened
+
+<item> relevant parts of a debugging output file with debuglevel higher.
+ If you can't find the relevant parts, please ask before mailing
+ huge files.
+
+<item> anything else you think is useful to trace down the bug
+
+</itemize>
+
+<sect1> What if I have an URGENT message for the developers?<p>
+
+If you have spotted something very serious and believe that it is
+important to contact the developers quickly send a message to
+samba-urgent@samba.org. This will be processed more quickly than
+mail to samba@samba.org. Please think carefully before using this address. An
+example of its use might be to report a security hole.
+
+Examples of things <em>not</em> to send to samba-urgent include problems
+getting Samba to work at all and bugs that cannot potentially cause damage.
+
+<sect1> What if I need paid-for support?<p><label id=PaidSupport>
+
+Samba has a large network of consultants who provide Samba support on a
+commercial basis. The list is included in the package in <url
+url="../Support.txt">, and the latest version will always be on the main
+samba ftp site. Any company in the world can request that the samba team
+include their details in Support.txt so we can give no guarantee of
+their services.
+
+<sect1> Pizza supply details<p><label id="pizza">
+Those who have registered in the Samba survey as "Pizza Factory" will
+already know this, but the rest may need some help. Andrew doesn't ask
+for payment, but he does appreciate it when people give him
+pizza. This calls for a little organisation when the pizza donor is
+twenty thousand kilometres away, but it has been done.
+
+<enum>
+<item> Ring up your local branch of an international pizza chain
+and see if they honour their vouchers internationally. Pizza Hut do,
+which is how the entire Canberra Linux Users Group got to eat pizza
+one night, courtesy of someone in the US.
+
+<item>Ring up a local pizza shop in Canberra and quote a credit
+card number for a certain amount, and tell them that Andrew will be
+collecting it (don't forget to tell him.) One kind soul from Germany
+did this.
+
+<item>Purchase a pizza voucher from your local pizza shop that has
+no international affiliations and send it to Andrew. It is completely
+useless but he can hang it on the wall next to the one he already has
+from Germany :-)
+
+<item>Air freight him a pizza with your favourite regional
+flavours. It will probably get stuck in customs or torn apart by
+hungry sniffer dogs but it will have been a noble gesture.
+
+</enum>
+
+<sect>About the CIFS and SMB Protocols<p><label id="CifsSmb">
+
+<sect1> What is the Server Message Block (SMB) Protocol?<p>
+SMB is a filesharing protocol that has had several maintainers and
+contributors over the years including Xerox, 3Com and most recently
+Microsoft. Names for this protocol include LAN Manager and Microsoft
+Networking. Parts of the specification has been made public at several
+versions including in an X/Open document, as listed at
+<url url="ftp://ftp.microsoft.com/developr/drg/CIFS/">. No specification
+releases were made between 1992 and 1996, and during that period
+Microsoft became the SMB implementor with the largest market share.
+Microsoft developed the specification further for its products but for
+various reasons connected with developer's workload rather than market
+strategy did not make the changes public. This culminated with the
+"Windows NT 0.12" version released with NT 3.5 in 1995 which had significant
+improvements and bugs. Because Microsoft client systems are so popular,
+it is fair to say that what Microsoft with Windows affects all suppliers
+of SMB server products.
+
+From 1994 Andrew Tridgell began doing some serious work on his
+Smbserver (now Samba) product and with some helpers started to
+implement more and more of these protocols. Samba began to take
+a significant share of the SMB server market.
+
+<sect1> What is the Common Internet Filesystem (CIFS)?<p>
+The initial pressure for Microsoft to document their current SMB
+implementation came from the Samba team, who kept coming across things
+on the wire that Microsoft either didn't know about or hadn't documented
+anywhere (even in the sourcecode to Windows NT.) Then Sun Microsystems
+came out with their WebNFS initiative, designed to replace FTP for file
+transfers on the Internet. There are many drawbacks to WebNFS (including
+its scope - it aims to replace HTTP as well!) but the concept was
+attractive. FTP is not very clever, and why should it be harder to get
+files from across the world than across the room?
+
+Some hasty revisions were made and an Internet Draft for the Common
+Internet Filesystem (CIFS) was released. Note that CIFS is not an
+Internet standard and is a very long way from becoming one, BUT the
+protocol specification is in the public domain and ongoing discussions
+concerning the spec take place on a public mailing list according to the
+rules of the Internet Engineering Task Force. For more information and
+pointers see <url url="http://samba.org/cifs/">
+
+The following is taken from <url url="http://www.microsoft.com/intdev/cifs/">
+
+<verb>
+ CIFS defines a standard remote file system access protocol for use
+ over the Internet, enabling groups of users to work together and
+ share documents across the Internet or within their corporate
+ intranets. CIFS is an open, cross-platform technology based on the
+ native file-sharing protocols built into Microsoft® Windows® and
+ other popular PC operating systems, and supported on dozens of
+ other platforms, including UNIX®. With CIFS, millions of computer
+ users can open and share remote files on the Internet without having
+ to install new software or change the way they work."
+</verb>
+
+If you consider CIFS as a backwardsly-compatible refinement of SMB that
+will work reasonably efficiently over the Internet you won't be too far
+wrong.
+
+The net effect is that Microsoft is now documenting large parts of their
+Windows NT fileserver protocols. The security concepts embodied in
+Windows NT are part of the specification, which is why Samba
+documentation often talks in terms of Windows NT. However there is no
+reason why a site shouldn't conduct all its file and printer sharing
+with CIFS and yet have no Microsoft products at all.
+
+<sect1> What is Browsing? <p>
+The term "Browsing" causes a lot of confusion. It is the part of the
+SMB/CIFS protocol which allows for resource discovery. For example, in
+the Windows NT Explorer it is possible to see a "Network Neighbourhood"
+of computers in the same SMB workgroup. Clicking on the name of one of
+these machines brings up a list of file and printer resources for
+connecting to. In this way you can cruise the network, seeing what
+things are available. How this scales to the Internet is a subject for
+debate. Look at the CIFS list archives to see what the experts think.
+
+<sect>Designing A SMB and CIFS Network<p>
+
+The big issues for installing any network of LAN or WAN file and print
+servers are
+
+<itemize>
+
+<item>How and where usernames, passwords and other security information
+is stored
+
+<item>What method can be used for locating the resources that users have
+permission to use
+
+<item>What protocols the clients can converse with
+
+</itemize>
+
+If you buy Netware, Windows NT or just about any other LAN fileserver
+product you are expected to lock yourself into the product's preferred
+answers to these questions. This tendancy is restrictive and often very
+expensive for a site where there is only one kind of client or server,
+and for sites with a mixture of operating systems it often makes it
+impossible to share resources between some sets of users.
+
+The Samba philosophy is to make things as easy as possible for
+administators, which means allowing as many combinations of clients,
+servers, operating systems and protocols as possible.
+
+<sect1>Workgroups, Domains, Authentication and Browsing<p>
+
+From the point of view of networking implementation, Domains and
+Workgroups are <em>exactly</em> the same, except for the client logon
+sequence. Some kind of distributed authentication database is associated
+with a domain (there are quite a few choices) and this adds so much
+flexibility that many people think of a domain as a completely different
+entity to a workgroup. From Samba's point of view a client connecting to
+a service presents an authentication token, and it if it is valid they
+have access. Samba does not care what mechanism was used to generate
+that token in the first place.
+
+The SMB client logging on to a domain has an expectation that every other
+server in the domain should accept the same authentication information.
+However the network browsing functionality of domains and workgroups is
+identical and is explained in <url url="../BROWSING.txt">.
+
+There are some implementation differences: Windows 95 can be a member of
+both a workgroup and a domain, but Windows NT cannot. Windows 95 also
+has the concept of an "alternative workgroup". Samba can only be a
+member of a single workgroup or domain, although this is due to change
+with a future version when nmbd will be split into two daemons, one for
+WINS and the other for browsing (<url url="../NetBIOS.txt"> explains
+what WINS is.)
+
+<sect2> Defining the Terms<p><label id="BrowseAndDomainDefs">
+
+<descrip>
+
+<tag/Workgroup/ means a collection of machines that maintain a common
+browsing database containing information about their shared resources.
+They do not necessarily have any security information in common (if they
+do, it gets called a Domain.) The browsing database is dynamic, modified
+as servers come and go on the network and as resources are added or
+deleted. The term "browsing" refers to a user accessing the database via
+whatever interface the client provides, eg the OS/2 Workplace Shell or
+Windows 95 Explorer. SMB servers agree between themselves as to which
+ones will maintain the browsing database. Workgroups can be anywhere on
+a connected TCP/IP network, including on different subnets or even on
+the Interet. This is a very tricky part of SMB to implement.
+
+<tag/Master Browsers/ are machines which holds the master browsing
+database for a workgroup or domain. There are two kinds of Master Browser:
+
+<itemize>
+
+<item> Domain Master Browser, which holds the master browsing
+information for an entire domain, which may well cross multiple TCP/IP
+subnets.
+
+<item> Local Master Browser, which holds the master browsing database
+for a particular subnet and communicates with the Domain Master Browser
+to get information on other subnets.
+
+</itemize>
+
+Subnets are differentiated because browsing is based on broadcasts, and
+broadcasts do not pass through routers. Subnets are not routed: while it
+is possible to have more than one subnet on a single network segment
+this is regarded as very bad practice.
+
+Master Browsers (both Domain and Local) are elected dynamically
+according to an algorithm which is supposed to take into account the
+machine's ability to sustain the browsing load. Samba can be configured
+to always act as a master browser, ie it always wins elections under all
+circumstances, even against systems such as a Windows NT Primary Domain
+Controller which themselves expect to win.
+
+There are also Backup Browsers which are promoted to Master Browsers in
+the event of a Master Browser disappearing from the network.
+
+Alternative terms include confusing variations such as "Browse Master",
+and "Master Browser" which we are trying to eliminate from the Samba
+documentation.
+
+<tag/Domain Controller/ is a term which comes from the Microsoft and IBM
+etc implementation of the LAN Manager protocols. It is tied to
+authentication. There are other ways of doing domain authentication, but
+the Windows NT method has a large market share. The general issues are
+discussed in <url url="../DOMAIN.txt"> and a Windows NT-specific
+discussion is in <url url="../DOMAIN_CONTROL.txt">.
+
+</descrip>
+
+<sect2>Sharelevel (Workgroup) Security Services<p><label id="ShareModeSecurity">
+
+With the Samba setting "security = SHARE", all shared resources
+information about what password is associated with them but only hints
+as to what usernames might be valid (the hint can be 'all users', in
+which case any username will work. This is usually a bad idea, but
+reflects both the initial implementations of SMB in the mid-80s and
+its reincarnation with Windows for Workgroups in 1992. The idea behind
+workgroup security was that small independant groups of people could
+share information on an ad-hoc basis without there being an
+authentication infrastructure present or requiring them to do more than
+fill in a dialogue box.
+
+<sect2>Authentication Domain Mode Services<p><label id="DomainModeSecurity">
+
+With the Samba settings "security = USER" or "security = SERVER"
+accesses to all resources are checked for username/password pair matches
+in a more rigorous manner. To the client, this has the effect of
+emulating a Microsoft Domain. The client is not concerned whether or not
+Samba looks up a Windows NT SAM or does it in some other way.
+
+<sect1>Authentication Schemes<p>
+
+In the simple case authentication information is stored on a single
+server and the user types a password on connecting for the first time.
+However client operating systems often require a password before they
+can be used at all, and in addition users usually want access to more
+than one server. Asking users to remember many different passwords in
+different contexts just does not work. Some kind of distributed
+authentication database is needed. It must cope with password changes
+and provide for assigning groups of users the same level of access
+permissions. This is why Samba installations often choose to implement a
+Domain model straight away.
+
+Authentication decisions are some of the biggest in designing a network.
+Are you going to use a scheme native to the client operating system,
+native to the server operating system, or newly installed on both? A
+list of options relevant to Samba (ie that make sense in the context of
+the SMB protocol) follows. Any experiences with other setups would be
+appreciated. [refer to server FAQ for "passwd chat" passwd program
+password server etc etc...]
+
+<sect2>NIS<p>
+
+For Windows 95, Windows for Workgroups and most other clients Samba can
+be a domain controller and share the password database via NIS
+transparently. Windows NT is different.
+<url url="http://www.dcs.qmw.ac.uk/~williams" name="Free NIS NT client">
+
+<sect2>Kerberos<p>
+
+Kerberos for US users only:
+<url url="http://www.cygnus.com/product/unifying-security.html"
+name="Kerberos overview">
+<url url="http://www.cygnus.com/product/kerbnet-download.html"
+name="Download Kerberos">
+
+<sect2>FTP<p>
+
+Other NT w/s logon hack via NT
+
+<sect2>Default Server Method<p>
+
+<sect2>Client-side Database Only<p>
+
+<sect1>Post-Authentication: Netlogon, Logon Scripts, Profiles<p>
+
+See <url url="../DOMAIN.txt">
+
+<sect>Cross-Protocol File Sharing<p>
+
+Samba is an important tool for...
+
+It is possible to...
+
+File protocol gateways...
+
+"Setting up a Linux File Server" http://vetrec.mit.edu/people/narf/linux.html
+
+Two free implementations of Appletalk for Unix are Netatalk, <url
+url="http://www.umich.edu/~rsug/netatalk/">, and CAP, <url
+url="http://www.cs.mu.oz.au/appletalk/atalk.html">. What Samba offers MS
+Windows users, these packages offer to Macs. For more info on these
+packages, Samba, and Linux (and other UNIX-based systems) see <url
+url="http://www.eats.com/linux_mac_win.html"> 3.5) Sniffing your nework
+
+
+<sect>Miscellaneous<p><label id="miscellaneous">
+<sect1>Is Samba Year 2000 compliant?<p><label id="Year2000Compliant">
+The CIFS protocol that Samba implements
+negotiates times in various formats, all of which
+are able to cope with dates beyond 2000.
+
+</article>
diff --git a/docs/faq/Samba-meta-FAQ.txt b/docs/faq/Samba-meta-FAQ.txt
new file mode 100755
index 00000000000..01fc8d6ccf1
--- /dev/null
+++ b/docs/faq/Samba-meta-FAQ.txt
@@ -0,0 +1,924 @@
+ Samba meta FAQ
+ Dan Shearer & Paul Blackman, ictinus@samba.org
+ v 0.3, 7 Oct '97
+
+ This is the meta-Frequently Asked Questions (FAQ) document for Samba,
+ the free and very popular SMB and CIFS server product. It contains
+ overview information for the Samba suite of programs, a quick-start
+ guide, and pointers to all other Samba documentation. Other FAQs exist
+ for specific client and server issues, and HOWTO documents for more
+ extended topics to do with Samba software. Current to version Samba
+ 1.9.17. Please send any corrections to the author.
+ ______________________________________________________________________
+
+ Table of Contents:
+
+ 1. Quick Reference Guides to Samba Documentation
+
+ 1.1. Samba for the Impatient
+
+ 1.2. All Samba Documentation
+
+ 2. General Information
+
+ 2.1. What is Samba?
+
+ 2.2. What is the current version of Samba?
+
+ 2.3. Where can I get it?
+
+ 2.4. What do the version numbers mean?
+
+ 2.5. Where can I go for further information?
+
+ 2.6. How do I subscribe to the Samba Mailing Lists?
+
+ 2.7. Something's gone wrong - what should I do?
+
+ 2.8. How do I submit patches or bug reports?
+
+ 2.9. What if I have an URGENT message for the developers?
+
+ 2.10. What if I need paid-for support?
+
+ 2.11. Pizza supply details
+
+ 3. About the CIFS and SMB Protocols
+
+ 3.1. What is the Server Message Block (SMB) Protocol?
+
+ 3.2. What is the Common Internet Filesystem (CIFS)?
+
+ 3.3. What is Browsing?
+
+ 4. Designing A SMB and CIFS Network
+
+ 4.1. Workgroups, Domains, Authentication and Browsing
+
+ 4.1.1. Defining the Terms
+
+ 4.1.2. Sharelevel (Workgroup) Security Services
+
+ 4.1.3. Authentication Domain Mode Services
+
+ 4.2. Authentication Schemes
+
+
+ 4.2.1. NIS
+
+ 4.2.2. Kerberos
+
+ 4.2.3. FTP
+
+ 4.2.4. Default Server Method
+
+ 4.2.5. Client-side Database Only
+
+ 4.3. Post-Authentication: Netlogon, Logon Scripts, Profiles
+
+ 5. Cross-Protocol File Sharing
+
+ 6. Miscellaneous
+
+ 6.1. Is Samba Year 2000 compliant?
+ ______________________________________________________________________
+
+ 11.. QQuuiicckk RReeffeerreennccee GGuuiiddeess ttoo SSaammbbaa DDooccuummeennttaattiioonn
+
+
+ We are endeavouring to provide links here to every major class of
+ information about Samba or things related to Samba. We cannot list
+ every document, but we are aiming for all documents to be at most two
+ referrals from those listed here. This needs constant maintaining, so
+ please send the author your feedback.
+
+
+ 11..11.. SSaammbbaa ffoorr tthhee IImmppaattiieenntt
+
+
+ You know you should read the documentation but can't wait to start?
+ What you need to do then is follow the instructions in the following
+ documents in the order given. This should be enough to get a fairly
+ simple site going quickly. If you have any problems, refer back to
+ this meta-FAQ and follow the links to find more reading material.
+
+
+
+ GGeettttiinngg SSaammbbaa::
+ The fastest way to get Samba going is and install it is to have
+ an operating system for which the Samba team has put together an
+ installation package. To see if your OS is included have a look
+ at the directory /pub/samba/Binary_Packages/"OS_Vendor" on your
+ nearest mirror site <../MIRRORS>. If it is included follow the
+ installation instructions in the README file there and then do
+ some ``basic testing''. If you are not so fortunate, follow the
+ normal ``download instructions'' and then continue with
+ ``building and installing Samba''.
+
+
+ BBuuiillddiinngg aanndd IInnssttaalllliinngg SSaammbbaa::
+ At the moment there are two kinds of Samba server installs
+ besides the prepackaged binaries mentioned in the previous step.
+ You need to decide if you have a Unix or close relative
+ <../UNIX_INSTALL.txt> or other supported operating system
+ <Samba-Server-FAQ.html#PortInfo>.
+
+
+ BBaassiicc TTeessttiinngg::
+ Try to connect using the supplied smbclient command-line
+ program. You need to know the IP hostname of your server. A
+ service name must be defined in smb.conf, as given in the
+ examples (under many operating systems if there is a homes
+ service you can just use a valid username.) Then type smbclient
+ \hostnamevicename Under most Unixes you will need to put the
+ parameters within quotation marks. If this works, try connecting
+ from one of the SMB clients you were planning to use with Samba.
+
+
+ DDeebbuugg sseeqquueennccee::
+ If you think you have completed the previous step and things
+ aren't working properly work through the diagnosis recipe.
+ <../DIAGNOSIS.txt>
+
+
+ EExxppoorrttiinngg ffiilleess ttoo SSMMBB cclliieennttss::
+ You should read the manual pages for smb.conf, but here is a
+ quick answer guide. <Samba-Server-FAQ.html#Exporting>
+
+
+ CCoonnttrroolllliinngg uusseerr aacccceessss::
+ the quickest and dirtiest way of sharing resources is to use
+ ``share level security.'' If you want to spend more time and
+ have a proper username and password database you must read the
+ paragraph on ``domain mode security.'' If you want encryption
+ (eg you are using Windows NT clients) follow the SMB encryption
+ instructions. <Samba-Server-FAQ.html#SMBEncryptionSteps>
+
+
+ BBrroowwssiinngg::
+ if you are happy to type in "\samba-serverrename" at the client
+ end then do not read any further. Otherwise you need to
+ understand the ``browsing terminology'' and read <Samba-Server-
+ FAQ.html#NameBrowsing>.
+
+
+ PPrriinnttiinngg::
+ See the printing quick answer guide. <Samba-Server-
+ FAQ.html#Printing>
+
+
+ If you have got everything working to this point, you can expect Samba
+ to be stable and secure: these are its greatest strengths. However
+ Samba has a great deal to offer and to go further you must do some
+ more reading. Speed and security optimisations, printer accounting,
+ network logons, roving profiles, browsing across multiple subnets and
+ so on are all covered either in this document or in those it refers
+ to.
+
+
+ 11..22.. AAllll SSaammbbaa DDooccuummeennttaattiioonn
+
+
+
+ +o Meta-FAQ. This is the mother of all documents, and is the one you
+ are reading now. The latest version is always at
+ <http://samba.org/[.....]> but there is probably a much
+ nearer mirror site <../MIRRORS> which you should use instead.
+
+ +o <Samba-Server-FAQ.html> is the best starting point for information
+ about server-side issues. Includes configuration tips and pointers
+ for Samba on particular operating systems (with 40 to choose
+ from...)
+
+ +o <Samba-Client-FAQ.html> is the best starting point for information
+ about client-side issues, includes a list of all clients that are
+ known to work with Samba.
+
+ +o manual pages <samba-man-index.html> contains descriptions of and
+ links to all the Samba manual pages, in Unix man and postscript
+ format.
+
+ +o <samba-txt-index.html> has descriptions of and links to a large
+ number of text files have been contributed to samba covering many
+ topics. These are gradually being absorbed into the FAQs and HOWTOs
+ but in the meantime you might find helpful answers here.
+
+ +o
+
+
+ 22.. GGeenneerraall IInnffoorrmmaattiioonn
+
+
+ All about Samba - what it is, how to get it, related sources of
+ information, how to understand the numbering scheme, pizza details.
+
+
+ 22..11.. WWhhaatt iiss SSaammbbaa??
+
+
+ Samba is a suite of programs which work together to allow clients to
+ access to a server's filespace and printers via the SMB (Server
+ Message Block) and CIFS (Common Internet Filesystem) protocols.
+ Initially written for Unix, Samba now also runs on Netware, OS/2, VMS,
+ StratOS and Amigas. Ports to BeOS and other operating systems are
+ underway. Samba gives the capability for these operating systems to
+ behave much like a LAN Server, Windows NT Server or Pathworks machine,
+ only with added functionality and flexibility designed to make life
+ easier for administrators.
+
+ This means that using Samba you can share a server's disks and
+ printers to many sorts of network clients, including Lan Manager,
+ Windows for Workgroups, Windows NT, Linux, OS/2, and AIX. There is
+ also a generic client program supplied as part of the Samba suite
+ which gives a user on the server an ftp-like interface to access
+ filespace and printers on any other SMB/CIFS servers.
+
+ SMB has been implemented over many protocols, including XNS, NBT, IPX,
+ NetBEUI and TCP/IP. Samba only uses TCP/IP. This is not likely to
+ change although there have been some requests for NetBEUI support.
+
+ Many users report that compared to other SMB implementations Samba is
+ more stable, faster, and compatible with more clients. Administrators
+ of some large installations say that Samba is the only SMB server
+ available which will scale to many tens of thousands of users without
+ crashing. The easy way to test these claims is to download it and try
+ it for yourself!
+
+ The suite is supplied with full source code under the GNU Public
+ License <../COPYING>. The GPL means that you can use Samba for
+ whatever purpose you wish (including changing the source or selling it
+ for money) but under all circumstances the source code must be made
+ freely available. A copy of the GPL must always be included in any
+ copy of the package.
+
+ The primary creator of the Samba suite is Andrew Tridgell. Later
+ versions incorporate much effort by many net.helpers. The man pages
+ and this FAQ were originally written by Karl Auer.
+
+
+ 22..22.. WWhhaatt iiss tthhee ccuurrrreenntt vveerrssiioonn ooff SSaammbbaa??
+
+
+ At time of writing, the current version was 1.9.17. If you want to be
+ sure check the bottom of the change-log file.
+ <ftp://samba.org/pub/samba/alpha/change-log>
+ For more information see ``What do the version numbers mean?''
+
+
+ 22..33.. WWhheerree ccaann II ggeett iitt??
+
+
+ The Samba suite is available via anonymous ftp from samba.org
+ and many mirror <../MIRRORS> sites. You will get much faster
+ performance if you use a mirror site. The latest and greatest versions
+ of the suite are in the directory:
+
+ /pub/samba/
+
+ Development (read "alpha") versions, which are NOT necessarily stable
+ and which do NOT necessarily have accurate documentation, are
+ available in the directory:
+
+ /pub/samba/alpha
+
+ Note that binaries are NOT included in any of the above. Samba is
+ distributed ONLY in source form, though binaries may be available from
+ other sites. Most Linux distributions, for example, do contain Samba
+ binaries for that platform. The VMS, OS/2, Netware and Amiga and other
+ ports typically have binaries made available.
+
+ A special case is vendor-provided binary packages. Samba binaries and
+ default configuration files are put into packages for a specific
+ operating system. RedHat Linux and Sun Solaris (Sparc and x86) is
+ already included, and others such as OS/2 may follow. All packages are
+ in the directory:
+
+ /pub/samba/Binary_Packages/"OS_Vendor"
+
+
+ 22..44.. WWhhaatt ddoo tthhee vveerrssiioonn nnuummbbeerrss mmeeaann??
+
+
+ It is not recommended that you run a version of Samba with the word
+ "alpha" in its name unless you know what you are doing and are willing
+ to do some debugging. Many, many people just get the latest
+ recommended stable release version and are happy. If you are brave, by
+ all means take the plunge and help with the testing and development -
+ but don't install it on your departmental server. Samba is typically
+ very stable and safe, and this is mostly due to the policy of many
+ public releases.
+
+ How the scheme works:
+
+
+ 1. When major changes are made the version number is increased. For
+ example, the transition from 1.9.16 to 1.9.17. However, this
+ version number will not appear immediately and people should
+ continue to use 1.9.15 for production systems (see next point.)
+
+ 2. Just after major changes are made the software is considered
+ unstable, and a series of alpha releases are distributed, for
+ example 1.9.16alpha1. These are for testing by those who know what
+ they are doing. The "alpha" in the filename will hopefully scare
+ off those who are just looking for the latest version to install.
+
+ 3. When Andrew thinks that the alphas have stabilised to the point
+ where he would recommend new users install it, he renames it to the
+ same version number without the alpha, for example 1.9.17.
+
+ 4. Inevitably bugs are found in the "stable" releases and minor patch
+ levels are released which give us the pXX series, for example
+ 1.9.17p2.
+
+ So the progression goes:
+
+
+ 1.9.16p10 (production)
+ 1.9.16p11 (production)
+ 1.9.17alpha1 (test sites only)
+ :
+ 1.9.17alpha20 (test sites only)
+ 1.9.17 (production)
+ 1.9.17p1 (production)
+
+
+
+ The above system means that whenever someone looks at the samba ftp
+ site they will be able to grab the highest numbered release without an
+ alpha in the name and be sure of getting the current recommended
+ version.
+
+
+ 22..55.. WWhheerree ccaann II ggoo ffoorr ffuurrtthheerr iinnffoorrmmaattiioonn??
+
+
+ There are a number of places to look for more information on Samba,
+ including:
+
+
+ +o Two mailing lists devoted to discussion of Samba-related matters.
+ See below for subscription information.
+
+ +o The newsgroup comp.protocols.smb, which has a great deal of
+ discussion about Samba.
+
+ +o The WWW site 'SAMBA Web Pages' at <http://samba.org/samba/>
+ includes:
+
+
+ +o Links to man pages and documentation, including this FAQ
+
+ +o A comprehensive survey of Samba users
+
+ +o A searchable hypertext archive of the Samba mailing list
+
+ +o Links to Samba source code, binaries, and mirrors of both
+
+ +o This FAQ and the rest in its family
+
+
+
+ 22..66.. HHooww ddoo II ssuubbssccrriibbee ttoo tthhee SSaammbbaa MMaaiilliinngg LLiissttss??
+
+
+ Send email to listproc@samba.org. Make sure the subject line is
+ blank, and include the following two lines in the body of the message:
+
+
+
+ subscribe samba Firstname Lastname
+ subscribe samba-announce Firstname Lastname
+
+
+
+
+ Obviously you should substitute YOUR first name for "Firstname" and
+ YOUR last name for "Lastname"! Try not to send any signature, it
+ sometimes confuses the list processor.
+
+ The samba list is a digest list - every eight hours or so it sends a
+ single message containing all the messages that have been received by
+ the list since the last time and sends a copy of this message to all
+ subscribers. There are thousands of people on this list.
+
+ If you stop being interested in Samba, please send another email to
+ listproc@samba.org. Make sure the subject line is blank, and
+ include the following two lines in the body of the message:
+
+
+
+ unsubscribe samba
+ unsubscribe samba-announce
+
+
+
+
+ The FFrroomm:: line in your message _M_U_S_T be the same address you used when
+ you subscribed.
+
+
+ 22..77.. SSoommeetthhiinngg''ss ggoonnee wwrroonngg -- wwhhaatt sshhoouulldd II ddoo??
+
+
+ ## ****** IIMMPPOORRTTAANNTT!! ****** ##
+
+
+ DO NOT post messages on mailing lists or in newsgroups until you have
+ carried out the first three steps given here!
+
+
+ 1. See if there are any likely looking entries in this FAQ! If you
+ have just installed Samba, have you run through the checklist in
+ DIAGNOSIS.txt <ftp://samba.org/pub/samba/DIAGNOSIS.txt>? It
+ can save you a lot of time and effort. DIAGNOSIS.txt can also be
+ found in the docs directory of the Samba distribution.
+
+ 2. Read the man pages for smbd, nmbd and smb.conf, looking for topics
+ that relate to what you are trying to do.
+
+ 3. If there is no obvious solution to hand, try to get a look at the
+ log files for smbd and/or nmbd for the period during which you were
+ having problems. You may need to reconfigure the servers to provide
+ more extensive debugging information - usually level 2 or level 3
+ provide ample debugging info. Inspect these logs closely, looking
+ particularly for the string "Error:".
+
+ 4. If you need urgent help and are willing to pay for it see ``Paid
+ Support''.
+
+ If you still haven't got anywhere, ask the mailing list or newsgroup.
+ In general nobody minds answering questions provided you have followed
+ the preceding steps. It might be a good idea to scan the archives of
+ the mailing list, which are available through the Samba web site
+ described in the previous section. When you post be sure to include a
+ good description of your environment and your problem.
+
+ If you successfully solve a problem, please mail the FAQ maintainer a
+ succinct description of the symptom, the problem and the solution, so
+ that an explanation can be incorporated into the next version.
+
+
+
+
+ 22..88.. HHooww ddoo II ssuubbmmiitt ppaattcchheess oorr bbuugg rreeppoorrttss??
+
+
+ If you make changes to the source code, _p_l_e_a_s_e submit these patches so
+ that everyone else gets the benefit of your work. This is one of the
+ most important aspects to the maintainence of Samba. Send all patches
+ to samba@samba.org. Do not send patches to Andrew Tridgell
+ or any other individual, they may be lost if you do.
+
+ Patch format ------------
+
+ If you are sending a patch to fix a problem then please don't just use
+ standard diff format. As an example, samba@samba.org received this patch
+ from someone:
+
+ 382a #endif 381a #if !defined(NEWS61)
+
+ How are we supposed to work out what this does and where it goes?
+ These sort of patches only work if we both have identical files in the
+ first place. The Samba sources are constantly changing at the hands of
+ multiple developers, so it doesn't work.
+
+ Please use either context diffs or (even better) unified diffs. You
+ get these using "diff -c4" or "diff -u". If you don't have a diff that
+ can generate these then please send manualy commented patches to I
+ know what is being changed and where. Most patches are applied by hand
+ so the info must be clear.
+
+ This is a basic guideline that will assist us with assessing your
+ problem more efficiently :
+
+ Machine Arch: Machine OS: OS Version: Kernel:
+
+ Compiler: Libc Version:
+
+ Samba Version:
+
+ Network Layout (description):
+
+ What else is on machine (services, etc):
+
+ Some extras :
+
+
+ +o what you did and what happened
+
+ +o relevant parts of a debugging output file with debuglevel higher.
+ If you can't find the relevant parts, please ask before mailing
+ huge files.
+
+ +o anything else you think is useful to trace down the bug
+
+
+ 22..99.. WWhhaatt iiff II hhaavvee aann UURRGGEENNTT mmeessssaaggee ffoorr tthhee ddeevveellooppeerrss??
+
+
+ If you have spotted something very serious and believe that it is
+ important to contact the developers quickly send a message to samba-
+ urgent@samba.org. This will be processed more quickly than mail
+ to samba@samba.org. Please think carefully before using this address. An
+ example of its use might be to report a security hole.
+
+ Examples of things _n_o_t to send to samba-urgent include problems
+ getting Samba to work at all and bugs that cannot potentially cause
+ damage.
+
+ 22..1100.. WWhhaatt iiff II nneeeedd ppaaiidd--ffoorr ssuuppppoorrtt??
+
+
+ Samba has a large network of consultants who provide Samba support on
+ a commercial basis. The list is included in the package in
+ <../Support.txt>, and the latest version will always be on the main
+ samba ftp site. Any company in the world can request that the samba
+ team include their details in Support.txt so we can give no guarantee
+ of their services.
+
+
+ 22..1111.. PPiizzzzaa ssuuppppllyy ddeettaaiillss
+
+
+ Those who have registered in the Samba survey as "Pizza Factory" will
+ already know this, but the rest may need some help. Andrew doesn't ask
+ for payment, but he does appreciate it when people give him pizza.
+ This calls for a little organisation when the pizza donor is twenty
+ thousand kilometres away, but it has been done.
+
+
+ 1. Ring up your local branch of an international pizza chain and see
+ if they honour their vouchers internationally. Pizza Hut do, which
+ is how the entire Canberra Linux Users Group got to eat pizza one
+ night, courtesy of someone in the US.
+
+ 2. Ring up a local pizza shop in Canberra and quote a credit card
+ number for a certain amount, and tell them that Andrew will be
+ collecting it (don't forget to tell him.) One kind soul from
+ Germany did this.
+
+ 3. Purchase a pizza voucher from your local pizza shop that has no
+ international affiliations and send it to Andrew. It is completely
+ useless but he can hang it on the wall next to the one he already
+ has from Germany :-)
+
+ 4. Air freight him a pizza with your favourite regional flavours. It
+ will probably get stuck in customs or torn apart by hungry sniffer
+ dogs but it will have been a noble gesture.
+
+
+ 33.. AAbboouutt tthhee CCIIFFSS aanndd SSMMBB PPrroottooccoollss
+
+
+
+ 33..11.. WWhhaatt iiss tthhee SSeerrvveerr MMeessssaaggee BBlloocckk ((SSMMBB)) PPrroottooccooll??
+
+ SMB is a filesharing protocol that has had several maintainers and
+ contributors over the years including Xerox, 3Com and most recently
+ Microsoft. Names for this protocol include LAN Manager and Microsoft
+ Networking. Parts of the specification has been made public at several
+ versions including in an X/Open document, as listed at
+ <ftp://ftp.microsoft.com/developr/drg/CIFS/>. No specification
+ releases were made between 1992 and 1996, and during that period
+ Microsoft became the SMB implementor with the largest market share.
+ Microsoft developed the specification further for its products but for
+ various reasons connected with developer's workload rather than market
+ strategy did not make the changes public. This culminated with the
+ "Windows NT 0.12" version released with NT 3.5 in 1995 which had
+ significant improvements and bugs. Because Microsoft client systems
+ are so popular, it is fair to say that what Microsoft with Windows
+ affects all suppliers of SMB server products.
+
+ From 1994 Andrew Tridgell began doing some serious work on his
+ Smbserver (now Samba) product and with some helpers started to
+ implement more and more of these protocols. Samba began to take a
+ significant share of the SMB server market.
+
+
+ 33..22.. WWhhaatt iiss tthhee CCoommmmoonn IInntteerrnneett FFiilleessyysstteemm ((CCIIFFSS))??
+
+ The initial pressure for Microsoft to document their current SMB
+ implementation came from the Samba team, who kept coming across things
+ on the wire that Microsoft either didn't know about or hadn't
+ documented anywhere (even in the sourcecode to Windows NT.) Then Sun
+ Microsystems came out with their WebNFS initiative, designed to
+ replace FTP for file transfers on the Internet. There are many
+ drawbacks to WebNFS (including its scope - it aims to replace HTTP as
+ well!) but the concept was attractive. FTP is not very clever, and why
+ should it be harder to get files from across the world than across the
+ room?
+
+ Some hasty revisions were made and an Internet Draft for the Common
+ Internet Filesystem (CIFS) was released. Note that CIFS is not an
+ Internet standard and is a very long way from becoming one, BUT the
+ protocol specification is in the public domain and ongoing discussions
+ concerning the spec take place on a public mailing list according to
+ the rules of the Internet Engineering Task Force. For more information
+ and pointers see <http://samba.org/cifs/>
+
+ The following is taken from <http://www.microsoft.com/intdev/cifs/>
+
+
+ CIFS defines a standard remote file system access protocol for use
+ over the Internet, enabling groups of users to work together and
+ share documents across the Internet or within their corporate
+ intranets. CIFS is an open, cross-platform technology based on the
+ native file-sharing protocols built into Microsoft Windows and
+ other popular PC operating systems, and supported on dozens of
+ other platforms, including UNIX. With CIFS, millions of computer
+ users can open and share remote files on the Internet without having
+ to install new software or change the way they work."
+
+
+
+ If you consider CIFS as a backwardsly-compatible refinement of SMB
+ that will work reasonably efficiently over the Internet you won't be
+ too far wrong.
+
+ The net effect is that Microsoft is now documenting large parts of
+ their Windows NT fileserver protocols. The security concepts embodied
+ in Windows NT are part of the specification, which is why Samba
+ documentation often talks in terms of Windows NT. However there is no
+ reason why a site shouldn't conduct all its file and printer sharing
+ with CIFS and yet have no Microsoft products at all.
+
+
+ 33..33.. WWhhaatt iiss BBrroowwssiinngg??
+
+ The term "Browsing" causes a lot of confusion. It is the part of the
+ SMB/CIFS protocol which allows for resource discovery. For example, in
+ the Windows NT Explorer it is possible to see a "Network
+ Neighbourhood" of computers in the same SMB workgroup. Clicking on the
+ name of one of these machines brings up a list of file and printer
+ resources for connecting to. In this way you can cruise the network,
+ seeing what things are available. How this scales to the Internet is a
+ subject for debate. Look at the CIFS list archives to see what the
+ experts think.
+
+
+
+
+ 44.. DDeessiiggnniinngg AA SSMMBB aanndd CCIIFFSS NNeettwwoorrkk
+
+
+ The big issues for installing any network of LAN or WAN file and print
+ servers are
+
+
+ +o How and where usernames, passwords and other security information
+ is stored
+
+ +o What method can be used for locating the resources that users have
+ permission to use
+
+ +o What protocols the clients can converse with
+
+
+ If you buy Netware, Windows NT or just about any other LAN fileserver
+ product you are expected to lock yourself into the product's preferred
+ answers to these questions. This tendancy is restrictive and often
+ very expensive for a site where there is only one kind of client or
+ server, and for sites with a mixture of operating systems it often
+ makes it impossible to share resources between some sets of users.
+
+ The Samba philosophy is to make things as easy as possible for
+ administators, which means allowing as many combinations of clients,
+ servers, operating systems and protocols as possible.
+
+
+ 44..11.. WWoorrkkggrroouuppss,, DDoommaaiinnss,, AAuutthheennttiiccaattiioonn aanndd BBrroowwssiinngg
+
+
+ From the point of view of networking implementation, Domains and
+ Workgroups are _e_x_a_c_t_l_y the same, except for the client logon sequence.
+ Some kind of distributed authentication database is associated with a
+ domain (there are quite a few choices) and this adds so much
+ flexibility that many people think of a domain as a completely
+ different entity to a workgroup. From Samba's point of view a client
+ connecting to a service presents an authentication token, and it if it
+ is valid they have access. Samba does not care what mechanism was used
+ to generate that token in the first place.
+
+ The SMB client logging on to a domain has an expectation that every
+ other server in the domain should accept the same authentication
+ information. However the network browsing functionality of domains
+ and workgroups is identical and is explained in <../BROWSING.txt>.
+
+ There are some implementation differences: Windows 95 can be a member
+ of both a workgroup and a domain, but Windows NT cannot. Windows 95
+ also has the concept of an "alternative workgroup". Samba can only be
+ a member of a single workgroup or domain, although this is due to
+ change with a future version when nmbd will be split into two daemons,
+ one for WINS and the other for browsing ( <../NetBIOS.txt> explains
+ what WINS is.)
+
+
+ 44..11..11.. DDeeffiinniinngg tthhee TTeerrmmss
+
+
+
+
+ WWoorrkkggrroouupp
+ means a collection of machines that maintain a common browsing
+ database containing information about their shared resources.
+ They do not necessarily have any security information in common
+ (if they do, it gets called a Domain.) The browsing database is
+ dynamic, modified as servers come and go on the network and as
+ resources are added or deleted. The term "browsing" refers to a
+ user accessing the database via whatever interface the client
+ provides, eg the OS/2 Workplace Shell or Windows 95 Explorer.
+ SMB servers agree between themselves as to which ones will
+ maintain the browsing database. Workgroups can be anywhere on a
+ connected TCP/IP network, including on different subnets or even
+ on the Interet. This is a very tricky part of SMB to implement.
+
+
+ MMaasstteerr BBrroowwsseerrss
+ are machines which holds the master browsing database for a
+ workgroup or domain. There are two kinds of Master Browser:
+
+
+ +o Domain Master Browser, which holds the master browsing
+ information for an entire domain, which may well cross multiple
+ TCP/IP subnets.
+
+ +o Local Master Browser, which holds the master browsing database
+ for a particular subnet and communicates with the Domain Master
+ Browser to get information on other subnets.
+
+ Subnets are differentiated because browsing is based on
+ broadcasts, and broadcasts do not pass through routers. Subnets
+ are not routed: while it is possible to have more than one
+ subnet on a single network segment this is regarded as very bad
+ practice.
+
+ Master Browsers (both Domain and Local) are elected dynamically
+ according to an algorithm which is supposed to take into account
+ the machine's ability to sustain the browsing load. Samba can be
+ configured to always act as a master browser, ie it always wins
+ elections under all circumstances, even against systems such as
+ a Windows NT Primary Domain Controller which themselves expect
+ to win.
+
+ There are also Backup Browsers which are promoted to Master
+ Browsers in the event of a Master Browser disappearing from the
+ network.
+
+ Alternative terms include confusing variations such as "Browse
+ Master", and "Master Browser" which we are trying to eliminate
+ from the Samba documentation.
+
+
+ DDoommaaiinn CCoonnttrroolllleerr
+ is a term which comes from the Microsoft and IBM etc
+ implementation of the LAN Manager protocols. It is tied to
+ authentication. There are other ways of doing domain
+ authentication, but the Windows NT method has a large market
+ share. The general issues are discussed in <../DOMAIN.txt> and
+ a Windows NT-specific discussion is in <../DOMAIN_CONTROL.txt>.
+
+
+
+ 44..11..22.. SShhaarreelleevveell ((WWoorrkkggrroouupp)) SSeeccuurriittyy SSeerrvviicceess
+
+
+ With the Samba setting "security = SHARE", all shared resources
+ information about what password is associated with them but only hints
+ as to what usernames might be valid (the hint can be 'all users', in
+ which case any username will work. This is usually a bad idea, but
+ reflects both the initial implementations of SMB in the mid-80s and
+ its reincarnation with Windows for Workgroups in 1992. The idea behind
+ workgroup security was that small independant groups of people could
+ share information on an ad-hoc basis without there being an
+ authentication infrastructure present or requiring them to do more
+ than fill in a dialogue box.
+
+
+ 44..11..33.. AAuutthheennttiiccaattiioonn DDoommaaiinn MMooddee SSeerrvviicceess
+
+
+ With the Samba settings "security = USER" or "security = SERVER"
+ accesses to all resources are checked for username/password pair
+ matches in a more rigorous manner. To the client, this has the effect
+ of emulating a Microsoft Domain. The client is not concerned whether
+ or not Samba looks up a Windows NT SAM or does it in some other way.
+
+
+ 44..22.. AAuutthheennttiiccaattiioonn SScchheemmeess
+
+
+ In the simple case authentication information is stored on a single
+ server and the user types a password on connecting for the first time.
+ However client operating systems often require a password before they
+ can be used at all, and in addition users usually want access to more
+ than one server. Asking users to remember many different passwords in
+ different contexts just does not work. Some kind of distributed
+ authentication database is needed. It must cope with password changes
+ and provide for assigning groups of users the same level of access
+ permissions. This is why Samba installations often choose to implement
+ a Domain model straight away.
+
+ Authentication decisions are some of the biggest in designing a
+ network. Are you going to use a scheme native to the client operating
+ system, native to the server operating system, or newly installed on
+ both? A list of options relevant to Samba (ie that make sense in the
+ context of the SMB protocol) follows. Any experiences with other
+ setups would be appreciated. refer to server FAQ for "passwd chat"
+ passwd program password server etc etc...
+
+
+ 44..22..11.. NNIISS
+
+
+ For Windows 95, Windows for Workgroups and most other clients Samba
+ can be a domain controller and share the password database via NIS
+ transparently. Windows NT is different. Free NIS NT client
+ <http://www.dcs.qmw.ac.uk/~williams>
+
+
+ 44..22..22.. KKeerrbbeerrooss
+
+
+ Kerberos for US users only: Kerberos overview
+ <http://www.cygnus.com/product/unifying-security.html> Download
+ Kerberos <http://www.cygnus.com/product/kerbnet-download.html>
+
+
+ 44..22..33.. FFTTPP
+
+
+ Other NT w/s logon hack via NT
+
+
+ 44..22..44.. DDeeffaauulltt SSeerrvveerr MMeetthhoodd
+
+
+
+
+
+ 44..22..55.. CClliieenntt--ssiiddee DDaattaabbaassee OOnnllyy
+
+
+
+ 44..33.. PPoosstt--AAuutthheennttiiccaattiioonn:: NNeettllooggoonn,, LLooggoonn SSccrriippttss,, PPrrooffiilleess
+
+
+ See <../DOMAIN.txt>
+
+
+ 55.. CCrroossss--PPrroottooccooll FFiillee SShhaarriinngg
+
+
+ Samba is an important tool for...
+
+ It is possible to...
+
+ File protocol gateways...
+
+ "Setting up a Linux File Server"
+ http://vetrec.mit.edu/people/narf/linux.html
+
+ Two free implementations of Appletalk for Unix are Netatalk,
+ <http://www.umich.edu/~rsug/netatalk/>, and CAP,
+ <http://www.cs.mu.oz.au/appletalk/atalk.html>. What Samba offers MS
+ Windows users, these packages offer to Macs. For more info on these
+ packages, Samba, and Linux (and other UNIX-based systems) see
+ <http://www.eats.com/linux_mac_win.html> 3.5) Sniffing your nework
+
+
+
+ 66.. MMiisscceellllaanneeoouuss
+
+
+ 66..11.. IIss SSaammbbaa YYeeaarr 22000000 ccoommpplliiaanntt??
+
+
+ The CIFS protocol that Samba implements negotiates times in various
+ formats, all of which are able to cope with dates beyond 2000.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/faq/sambafaq-1.html b/docs/faq/sambafaq-1.html
new file mode 100755
index 00000000000..dde07840999
--- /dev/null
+++ b/docs/faq/sambafaq-1.html
@@ -0,0 +1,392 @@
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ: General Information</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="sambafaq-2.html">Next</A>
+<A HREF="sambafaq.html#toc1">Table of Contents</A>
+<HR>
+<H2><A NAME="s1">1. General Information</A></H2>
+
+<P>
+<A NAME="general_info"></A>
+</P>
+<P>All about Samba - what it is, how to get it, related sources of
+information, how to understand the version numbering scheme, pizza
+details</P>
+
+<H2><A NAME="ss1.1">1.1 What is Samba? </A></H2>
+
+<P>
+<A NAME="introduction"></A>
+
+Samba is a suite of programs which work together to allow clients to
+access to a server's filespace and printers via the SMB (Server
+Message Block) protocol. Initially written for Unix, Samba now also
+runs on Netware, OS/2 and VMS.</P>
+<P>In practice, this means that you can redirect disks and printers to
+Unix disks and printers from Lan Manager clients, Windows for
+Workgroups 3.11 clients, Windows NT clients, Linux clients and OS/2
+clients. There is also a generic Unix client program supplied as part
+of the suite which allows Unix users to use an ftp-like interface to
+access filespace and printers on any other SMB servers. This gives the
+capability for these operating systems to behave much like a LAN
+Server or Windows NT Server machine, only with added functionality and
+flexibility designed to make life easier for administrators.</P>
+<P>The components of the suite are (in summary):</P>
+<P>
+<UL>
+<LI><B>smbd</B>, the SMB server. This handles actual connections from clients, doing all the file, permission and username work</LI>
+<LI><B>nmbd</B>, the Netbios name server, which helps clients locate servers, doing the browsing work and managing domains as this capability is being built into Samba</LI>
+<LI><B>smbclient</B>, the Unix-hosted client program</LI>
+<LI><B>smbrun</B>, a little 'glue' program to help the server run external programs</LI>
+<LI><B>testprns</B>, a program to test server access to printers</LI>
+<LI><B>testparms</B>, a program to test the Samba configuration file for correctness</LI>
+<LI><B>smb.conf</B>, the Samba configuration file</LI>
+<LI><B>smbprint</B>, a sample script to allow a Unix host to use smbclient to print to an SMB server</LI>
+<LI><B>Documentation!</B> DON'T neglect to read it - you will save a great deal of time!</LI>
+</UL>
+</P>
+<P>The suite is supplied with full source (of course!) and is GPLed.</P>
+<P>The primary creator of the Samba suite is Andrew Tridgell. Later
+versions incorporate much effort by many net.helpers. The man pages
+and this FAQ were originally written by Karl Auer.</P>
+
+
+<H2><A NAME="ss1.2">1.2 What is the current version of Samba? </A></H2>
+
+<P>
+<A NAME="current_version"></A>
+
+At time of writing, the current version was 1.9.17. If you want to be
+sure check the bottom of the change-log file.
+<A HREF="ftp://samba.org/pub/samba/alpha/change-log">ftp://samba.org/pub/samba/alpha/change-log</A></P>
+<P>For more information see
+<A HREF="#version_nums">What do the version numbers mean?</A></P>
+
+
+<H2><A NAME="ss1.3">1.3 Where can I get it? </A></H2>
+
+<P>
+<A NAME="where"></A>
+
+The Samba suite is available via anonymous ftp from
+samba.org. The latest and greatest versions of the suite are in
+the directory:</P>
+<P>/pub/samba/</P>
+<P>Development (read "alpha") versions, which are NOT necessarily stable
+and which do NOT necessarily have accurate documentation, are
+available in the directory:</P>
+<P>/pub/samba/alpha</P>
+<P>Note that binaries are NOT included in any of the above. Samba is
+distributed ONLY in source form, though binaries may be available from
+other sites. Recent versions of some Linux distributions, for example,
+do contain Samba binaries for that platform.</P>
+
+
+<H2><A NAME="ss1.4">1.4 What do the version numbers mean? </A></H2>
+
+<P>
+<A NAME="version_nums"></A>
+
+It is not recommended that you run a version of Samba with the word
+"alpha" in its name unless you know what you are doing and are willing
+to do some debugging. Many, many people just get the latest
+recommended stable release version and are happy. If you are brave, by
+all means take the plunge and help with the testing and development -
+but don't install it on your departmental server. Samba is typically
+very stable and safe, and this is mostly due to the policy of many
+public releases.</P>
+<P>How the scheme works:
+<OL>
+<LI>When major changes are made the version number is increased. For
+example, the transition from 1.9.15 to 1.9.16. However, this version
+number will not appear immediately and people should continue to use
+1.9.15 for production systems (see next point.)
+</LI>
+<LI>Just after major changes are made the software is considered
+unstable, and a series of alpha releases are distributed, for example
+1.9.16alpha1. These are for testing by those who know what they are
+doing. The "alpha" in the filename will hopefully scare off those who
+are just looking for the latest version to install.
+</LI>
+<LI>When Andrew thinks that the alphas have stabilised to the point
+where he would recommend new users install it, he renames it to the
+same version number without the alpha, for example 1.9.16.
+</LI>
+<LI>Inevitably bugs are found in the "stable" releases and minor patch
+levels are released which give us the pXX series, for example 1.9.16p2.</LI>
+</OL>
+
+So the progression goes:
+<PRE>
+ 1.9.15p7 (production)
+ 1.9.15p8 (production)
+ 1.9.16alpha1 (test sites only)
+ :
+ 1.9.16alpha20 (test sites only)
+ 1.9.16 (production)
+ 1.9.16p1 (production)
+</PRE>
+
+The above system means that whenever someone looks at the samba ftp
+site they will be able to grab the highest numbered release without an
+alpha in the name and be sure of getting the current recommended
+version.</P>
+
+
+<H2><A NAME="ss1.5">1.5 What platforms are supported? </A></H2>
+
+<P>
+<A NAME="platforms"></A>
+
+Many different platforms have run Samba successfully. The platforms
+most widely used and thus best tested are Linux and SunOS.</P>
+<P>At time of writing, the Makefile claimed support for:
+<UL>
+<LI> A/UX 3.0</LI>
+<LI> AIX</LI>
+<LI> Altos Series 386/1000</LI>
+<LI> Amiga</LI>
+<LI> Apollo Domain/OS sr10.3</LI>
+<LI> BSDI </LI>
+<LI> B.O.S. (Bull Operating System)</LI>
+<LI> Cray, Unicos 8.0</LI>
+<LI> Convex</LI>
+<LI> DGUX. </LI>
+<LI> DNIX.</LI>
+<LI> FreeBSD</LI>
+<LI> HP-UX</LI>
+<LI> Intergraph. </LI>
+<LI> Linux with/without shadow passwords and quota</LI>
+<LI> LYNX 2.3.0</LI>
+<LI> MachTen (a unix like system for Macintoshes)</LI>
+<LI> Motorola 88xxx/9xx range of machines</LI>
+<LI> NetBSD</LI>
+<LI> NEXTSTEP Release 2.X, 3.0 and greater (including OPENSTEP for Mach).</LI>
+<LI> OS/2 using EMX 0.9b</LI>
+<LI> OSF1</LI>
+<LI> QNX 4.22</LI>
+<LI> RiscIX. </LI>
+<LI> RISCOs 5.0B</LI>
+<LI> SEQUENT. </LI>
+<LI> SCO (including: 3.2v2, European dist., OpenServer 5)</LI>
+<LI> SGI.</LI>
+<LI> SMP_DC.OSx v1.1-94c079 on Pyramid S series</LI>
+<LI> SONY NEWS, NEWS-OS (4.2.x and 6.1.x)</LI>
+<LI> SUNOS 4</LI>
+<LI> SUNOS 5.2, 5.3, and 5.4 (Solaris 2.2, 2.3, and '2.4 and later')</LI>
+<LI> Sunsoft ISC SVR3V4</LI>
+<LI> SVR4</LI>
+<LI> System V with some berkely extensions (Motorola 88k R32V3.2).</LI>
+<LI> ULTRIX.</LI>
+<LI> UNIXWARE</LI>
+<LI> UXP/DS</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss1.6">1.6 How can I find out more about Samba? </A></H2>
+
+<P>
+<A NAME="more"></A>
+
+There are a number of places to look for more information on Samba, including:
+<UL>
+<LI>Two mailing lists devoted to discussion of Samba-related matters. </LI>
+<LI>The newsgroup, comp.protocols.smb, which has a great deal of discussion on Samba. </LI>
+<LI>The WWW site 'SAMBA Web Pages' at
+<A HREF="http://samba.edu.au/samba/">http://samba.edu.au/samba/</A> includes:
+<UL>
+<LI>Links to man pages and documentation, including this FAQ</LI>
+<LI>A comprehensive survey of Samba users.</LI>
+<LI>A searchable hypertext archive of the Samba mailing list.</LI>
+<LI>Links to Samba source code, binaries, and mirrors of both.</LI>
+</UL>
+</LI>
+<LI>The long list of topic documentation. These files can be found in the 'docs' directory of the Samba source, or at
+<A HREF="ftp://samba.org/pub/samba/docs/">ftp://samba.org/pub/samba/docs/</A>
+<UL>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Application_Serving.txt">Application_Serving.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/BROWSING.txt">BROWSING.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/BUGS.txt">BUGS.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/DIAGNOSIS.txt">DIAGNOSIS.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/DNIX.txt">DNIX.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/DOMAIN.txt">DOMAIN.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/DOMAIN_CONTROL.txt">CONTROL.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/ENCRYPTION.txt">ENCRYPTION.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Faxing.txt">Faxing.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/GOTCHAS.txt">GOTCHAS.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/HINTS.txt">HINTS.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/INSTALL.sambatar">INSTALL.sambatar</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/INSTALL.txt">INSTALL.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/MIRRORS">MIRRORS</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/NetBIOS.txt">NetBIOS.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/OS2.txt">OS2.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/PROJECTS">PROJECTS</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Passwords.txt">Passwords.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Printing.txt">Printing.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/README.DCEDFS">README.DCEDFS</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/README.OS2">README.OS2</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/README.jis">README.jis</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/README.sambatar">README.sambatar</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/SCO.txt">SCO.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/SMBTAR.notes">SMBTAR.notes</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Speed.txt">Speed.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Support.txt">Support.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/THANKS">THANKS</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Tracing.txt">Tracing.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/UNIX-SMB.txt">SMB.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/Warp.txt">Warp.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/WinNT.txt">WinNT.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/history">history</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/security_level.txt">level.txt</A></LI>
+<LI>
+<A HREF="ftp://samba.org/pub/samba/docs/wfw_slip.htm">slip.htm</A></LI>
+</UL>
+</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss1.7">1.7 How do I subscribe to the Samba Mailing Lists?</A></H2>
+
+<P>
+<A NAME="mailinglist"></A>
+
+Send email to
+<A HREF="mailto:listproc@samba.org">listproc@samba.org</A>. Make sure the subject line is
+blank, and include the following two lines in the body of the message:
+<BLOCKQUOTE><CODE>
+<PRE>
+subscribe samba Firstname Lastname
+subscribe samba-announce Firstname Lastname
+</PRE>
+</CODE></BLOCKQUOTE>
+
+Obviously you should substitute YOUR first name for "Firstname" and
+YOUR last name for "Lastname"! Try not to send any signature stuff, it
+sometimes confuses the list processor.</P>
+<P>The samba list is a digest list - every eight hours or so it
+regurgitates a single message containing all the messages that have
+been received by the list since the last time and sends a copy of this
+message to all subscribers.</P>
+<P>If you stop being interested in Samba, please send another email to
+<A HREF="mailto:listproc@samba.org">listproc@samba.org</A>. Make sure the subject line is blank, and
+include the following two lines in the body of the message:
+<BLOCKQUOTE><CODE>
+<PRE>
+unsubscribe samba
+unsubscribe samba-announce
+</PRE>
+</CODE></BLOCKQUOTE>
+
+The <B>From:</B> line in your message <EM>MUST</EM> be the same address you used when
+you subscribed.</P>
+
+
+<H2><A NAME="ss1.8">1.8 Something's gone wrong - what should I do? </A></H2>
+
+<P>
+<A NAME="wrong"></A>
+
+<B><F>#</F> *** IMPORTANT! *** <F>#</F></B></P>
+<P>DO NOT post messages on mailing lists or in newsgroups until you have
+carried out the first three steps given here!</P>
+<P>Firstly, see if there are any likely looking entries in this FAQ! If
+you have just installed Samba, have you run through the checklist in
+<A HREF="ftp://samba.org/pub/samba/DIAGNOSIS.txt">DIAGNOSIS.txt</A>? It can save you a lot of time and effort.
+DIAGNOSIS.txt can also be found in the docs directory of the Samba distribution.</P>
+<P>Secondly, read the man pages for smbd, nmbd and smb.conf, looking for
+topics that relate to what you are trying to do.</P>
+<P>Thirdly, if there is no obvious solution to hand, try to get a look at
+the log files for smbd and/or nmbd for the period during which you
+were having problems. You may need to reconfigure the servers to
+provide more extensive debugging information - usually level 2 or
+level 3 provide ample debugging info. Inspect these logs closely,
+looking particularly for the string "Error:".</P>
+<P>Fourthly, if you still haven't got anywhere, ask the mailing list or
+newsgroup. In general nobody minds answering questions provided you
+have followed the preceding steps. It might be a good idea to scan the
+archives of the mailing list, which are available through the Samba
+web site described in the previous
+section.</P>
+<P>If you successfully solve a problem, please mail the FAQ maintainer a
+succinct description of the symptom, the problem and the solution, so
+I can incorporate it in the next version.</P>
+<P>If you make changes to the source code, _please_ submit these patches
+so that everyone else gets the benefit of your work. This is one of
+the most important aspects to the maintainence of Samba. Send all
+patches to
+<A HREF="mailto:samba@samba.org">samba@samba.org</A>. Do not send patches to Andrew Tridgell or any
+other individual, they may be lost if you do.</P>
+
+
+<H2><A NAME="ss1.9">1.9 Pizza supply details </A></H2>
+
+<P>
+<A NAME="pizza"></A>
+
+Those who have registered in the Samba survey as "Pizza Factory" will
+already know this, but the rest may need some help. Andrew doesn't ask
+for payment, but he does appreciate it when people give him
+pizza. This calls for a little organisation when the pizza donor is
+twenty thousand kilometres away, but it has been done.</P>
+<P>Method 1: Ring up your local branch of an international pizza chain
+and see if they honour their vouchers internationally. Pizza Hut do,
+which is how the entire Canberra Linux Users Group got to eat pizza
+one night, courtesy of someone in the US</P>
+<P>Method 2: Ring up a local pizza shop in Canberra and quote a credit
+card number for a certain amount, and tell them that Andrew will be
+collecting it (don't forget to tell him.) One kind soul from Germany
+did this.</P>
+<P>Method 3: Purchase a pizza voucher from your local pizza shop that has
+no international affiliations and send it to Andrew. It is completely
+useless but he can hang it on the wall next to the one he already has
+from Germany :-)</P>
+<P>Method 4: Air freight him a pizza with your favourite regional
+flavours. It will probably get stuck in customs or torn apart by
+hungry sniffer dogs but it will have been a noble gesture.</P>
+
+
+<HR>
+Previous
+<A HREF="sambafaq-2.html">Next</A>
+<A HREF="sambafaq.html#toc1">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq-2.html b/docs/faq/sambafaq-2.html
new file mode 100755
index 00000000000..8978bc331ca
--- /dev/null
+++ b/docs/faq/sambafaq-2.html
@@ -0,0 +1,236 @@
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ: Compiling and installing Samba on a Unix host</TITLE>
+</HEAD>
+<BODY>
+<A HREF="sambafaq-1.html">Previous</A>
+<A HREF="sambafaq-3.html">Next</A>
+<A HREF="sambafaq.html#toc2">Table of Contents</A>
+<HR>
+<H2><A NAME="s2">2. Compiling and installing Samba on a Unix host</A></H2>
+
+<P>
+<A NAME="unix_install"></A>
+</P>
+
+<H2><A NAME="ss2.1">2.1 I can't see the Samba server in any browse lists!</A></H2>
+
+<P>
+<A NAME="no_browse"></A>
+
+See BROWSING.txt for more information on browsing. BROWSING.txt can
+be found in the docs directory of the Samba source.</P> <P>If your GUI
+client does not permit you to select non-browsable servers, you may
+need to do so on the command line. For example, under Lan Manager you
+might connect to the above service as disk drive M: thusly:
+<BLOCKQUOTE><CODE>
+<PRE>
+ net use M: \\mary\fred
+</PRE>
+</CODE></BLOCKQUOTE>
+
+The details of how to do this and the specific syntax varies from
+client to client - check your client's documentation.</P>
+
+
+<H2><A NAME="ss2.2">2.2 Some files that I KNOW are on the server doesn't show up when I view the files from my client! </A></H2>
+
+<P>
+<A NAME="missing_files"></A>
+
+See the next question.</P>
+
+<H2><A NAME="ss2.3">2.3 Some files on the server show up with really wierd filenames when I view the files from my client! </A></H2>
+
+<P>
+<A NAME="strange_filenames"></A>
+
+If you check what files are not showing up, you will note that they
+are files which contain upper case letters or which are otherwise not
+DOS-compatible (ie, they are not legal DOS filenames for some reason).</P>
+<P>The Samba server can be configured either to ignore such files
+completely, or to present them to the client in "mangled" form. If you
+are not seeing the files at all, the Samba server has most likely been
+configured to ignore them. Consult the man page smb.conf(5) for
+details of how to change this - the parameter you need to set is
+"mangled names = yes".</P>
+
+
+<H2><A NAME="ss2.4">2.4 My client reports "cannot locate specified computer" or similar</A></H2>
+
+<P>
+<A NAME="cant_see_server"></A>
+
+This indicates one of three things: You supplied an incorrect server
+name, the underlying TCP/IP layer is not working correctly, or the
+name you specified cannot be resolved.</P>
+<P>After carefully checking that the name you typed is the name you
+should have typed, try doing things like pinging a host or telnetting
+to somewhere on your network to see if TCP/IP is functioning OK. If it
+is, the problem is most likely name resolution.</P>
+<P>If your client has a facility to do so, hardcode a mapping between the
+hosts IP and the name you want to use. For example, with Man Manager
+or Windows for Workgroups you would put a suitable entry in the file
+LMHOSTS. If this works, the problem is in the communication between
+your client and the netbios name server. If it does not work, then
+there is something fundamental wrong with your naming and the solution
+is beyond the scope of this document.</P>
+<P>If you do not have any server on your subnet supplying netbios name
+resolution, hardcoded mappings are your only option. If you DO have a
+netbios name server running (such as the Samba suite's nmbd program),
+the problem probably lies in the way it is set up. Refer to Section
+Two of this FAQ for more ideas.</P>
+<P>By the way, remember to REMOVE the hardcoded mapping before further
+tests :-) </P>
+
+
+<H2><A NAME="ss2.5">2.5 My client reports "cannot locate specified share name" or similar</A></H2>
+
+<P>
+<A NAME="cant_see_share"></A>
+
+This message indicates that your client CAN locate the specified
+server, which is a good start, but that it cannot find a service of
+the name you gave.</P>
+<P>The first step is to check the exact name of the service you are
+trying to connect to (consult your system administrator). Assuming it
+exists and you specified it correctly (read your client's doco on how
+to specify a service name correctly), read on:</P>
+<P>
+<UL>
+<LI> Many clients cannot accept or use service names longer than eight characters.</LI>
+<LI> Many clients cannot accept or use service names containing spaces.</LI>
+<LI> Some servers (not Samba though) are case sensitive with service names.</LI>
+<LI> Some clients force service names into upper case.</LI>
+</UL>
+</P>
+
+
+<H2><A NAME="ss2.6">2.6 My client reports "cannot find domain controller", "cannot log on to the network" or similar </A></H2>
+
+<P>
+<A NAME="cant_see_net"></A>
+
+Nothing is wrong - Samba does not implement the primary domain name
+controller stuff for several reasons, including the fact that the
+whole concept of a primary domain controller and "logging in to a
+network" doesn't fit well with clients possibly running on multiuser
+machines (such as users of smbclient under Unix). Having said that,
+several developers are working hard on building it in to the next
+major version of Samba. If you can contribute, send a message to
+<A HREF="mailto:samba@samba.org">samba@samba.org</A> !</P>
+<P>Seeing this message should not affect your ability to mount redirected
+disks and printers, which is really what all this is about.</P>
+<P>For many clients (including Windows for Workgroups and Lan Manager),
+setting the domain to STANDALONE at least gets rid of the message.</P>
+
+
+<H2><A NAME="ss2.7">2.7 Printing doesn't work :-(</A></H2>
+
+<P>
+<A NAME="no_printing"></A>
+
+Make sure that the specified print command for the service you are
+connecting to is correct and that it has a fully-qualified path (eg.,
+use "/usr/bin/lpr" rather than just "lpr").</P>
+<P>Make sure that the spool directory specified for the service is
+writable by the user connected to the service. In particular the user
+"nobody" often has problems with printing, even if it worked with an
+earlier version of Samba. Try creating another guest user other than
+"nobody".</P>
+<P>Make sure that the user specified in the service is permitted to use
+the printer.</P>
+<P>Check the debug log produced by smbd. Search for the printer name and
+see if the log turns up any clues. Note that error messages to do with
+a service ipc$ are meaningless - they relate to the way the client
+attempts to retrieve status information when using the LANMAN1
+protocol.</P>
+<P>If using WfWg then you need to set the default protocol to TCP/IP, not
+Netbeui. This is a WfWg bug.</P>
+<P>If using the Lanman1 protocol (the default) then try switching to
+coreplus. Also not that print status error messages don't mean
+printing won't work. The print status is received by a different
+mechanism.</P>
+
+
+<H2><A NAME="ss2.8">2.8 My programs install on the server OK, but refuse to work properly</A></H2>
+
+<P>
+<A NAME="programs_wont_run"></A>
+
+There are numerous possible reasons for this, but one MAJOR
+possibility is that your software uses locking. Make sure you are
+using Samba 1.6.11 or later. It may also be possible to work around
+the problem by setting "locking=no" in the Samba configuration file
+for the service the software is installed on. This should be regarded
+as a strictly temporary solution.</P>
+<P>In earlier Samba versions there were some difficulties with the very
+latest Microsoft products, particularly Excel 5 and Word for Windows
+6. These should have all been solved. If not then please let Andrew
+Tridgell know via email at
+<A HREF="mailto:samba@samba.org">samba@samba.org</A>.</P>
+
+
+<H2><A NAME="ss2.9">2.9 My "server string" doesn't seem to be recognised</A></H2>
+
+<P>
+<A NAME="bad_server_string"></A>
+
+OR My client reports the default setting, eg. "Samba 1.9.15p4", instead
+of what I have changed it to in the smb.conf file.</P>
+<P>You need to use the -C option in nmbd. The "server string" affects
+what smbd puts out and -C affects what nmbd puts out.</P>
+<P>Current versions of Samba (1.9.16 +) have combined these options into
+the "server string" field of smb.conf, -C for nmbd is now obsolete.</P>
+
+
+<H2><A NAME="ss2.10">2.10 My client reports "This server is not configured to list shared resources" </A></H2>
+
+<P>
+<A NAME="cant_list_shares"></A>
+
+Your guest account is probably invalid for some reason. Samba uses the
+guest account for browsing in smbd. Check that your guest account is
+valid.</P>
+<P>See also 'guest account' in smb.conf man page.</P>
+
+
+<H2><A NAME="ss2.11">2.11 Log message "you appear to have a trapdoor uid system" </A></H2>
+
+<P>
+<A NAME="trapdoor_uid"></A>
+
+This can have several causes. It might be because you are using a uid
+or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+hole. Check carefully in your /etc/passwd file and make sure that no
+user has uid 65535 or -1. Especially check the "nobody" user, as many
+broken systems are shipped with nobody setup with a uid of 65535.</P>
+<P>It might also mean that your OS has a trapdoor uid/gid system :-)</P>
+<P>This means that once a process changes effective uid from root to
+another user it can't go back to root. Unfortunately Samba relies on
+being able to change effective uid from root to non-root and back
+again to implement its security policy. If your OS has a trapdoor uid
+system this won't work, and several things in Samba may break. Less
+things will break if you use user or server level security instead of
+the default share level security, but you may still strike
+problems.</P>
+<P>The problems don't give rise to any security holes, so don't panic,
+but it does mean some of Samba's capabilities will be unavailable.
+In particular you will not be able to connect to the Samba server as
+two different uids at once. This may happen if you try to print as a
+"guest" while accessing a share as a normal user. It may also affect
+your ability to list the available shares as this is normally done as
+the guest user.</P>
+<P>Complain to your OS vendor and ask them to fix their system.</P>
+<P>Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+it casts to -1 as a uid, and the setreuid() system call ignores (with
+no error) uid changes to -1. This means any daemon attempting to run
+as uid 65535 will actually run as root. This is not good!</P>
+
+
+<HR>
+<A HREF="sambafaq-1.html">Previous</A>
+<A HREF="sambafaq-3.html">Next</A>
+<A HREF="sambafaq.html#toc2">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq-3.html b/docs/faq/sambafaq-3.html
new file mode 100755
index 00000000000..d7e0c7abd21
--- /dev/null
+++ b/docs/faq/sambafaq-3.html
@@ -0,0 +1,322 @@
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ: Common client questions</TITLE>
+</HEAD>
+<BODY>
+<A HREF="sambafaq-2.html">Previous</A>
+<A HREF="sambafaq-4.html">Next</A>
+<A HREF="sambafaq.html#toc3">Table of Contents</A>
+<HR>
+<H2><A NAME="s3">3. Common client questions</A></H2>
+
+<P>
+<A NAME="client_questions"></A>
+</P>
+
+<H2><A NAME="ss3.1">3.1 Are there any Macintosh clients for Samba?</A></H2>
+
+<P>
+<A NAME="mac_clients"></A>
+
+Yes! Thursby now have a CIFS Client / Server called DAVE - see
+<A HREF="http://www.thursby.com/">http://www.thursby.com/</A>.
+They test it against Windows 95, Windows NT and samba for compatibility issues.
+At the time of writing, DAVE was at version 1.0.1. The 1.0.0 to 1.0.1 update is available
+as a free download from the Thursby web site (the speed of finder copies has
+been greatly enhanced, and there are bug-fixes included).</P>
+<P>Alternatives - There are two free implementations of AppleTalk for
+several kinds of UNIX machnes, and several more commercial ones.
+These products allow you to run file services and print services
+natively to Macintosh users, with no additional support required on
+the Macintosh. The two free omplementations are Netatalk,
+<A HREF="http://www.umich.edu/~rsug/netatalk/">http://www.umich.edu/~rsug/netatalk/</A>, and CAP,
+<A HREF="http://www.cs.mu.oz.au/appletalk/atalk.html">http://www.cs.mu.oz.au/appletalk/atalk.html</A>. What Samba offers
+MS Windows users, these packages offer to Macs. For more info on
+these packages, Samba, and Linux (and other UNIX-based systems)
+see
+<A HREF="http://www.eats.com/linux_mac_win.html">http://www.eats.com/linux_mac_win.html</A></P>
+
+
+<H2><A NAME="ss3.2">3.2 "Session request failed (131,130)" error</A></H2>
+
+<P>
+<A NAME="sess_req_fail"></A>
+
+The following answer is provided by John E. Miller:</P>
+<P>I'll assume that you're able to ping back and forth between the
+machines by IP address and name, and that you're using some security
+model where you're confident that you've got user IDs and passwords
+right. The logging options (-d3 or greater) can help a lot with that.
+DNS and WINS configuration can also impact connectivity as well.</P>
+<P>Now, on to 'scope id's. Somewhere in your Win95 TCP/IP network
+configuration (I'm too much of an NT bigot to know where it's located
+in the Win95 setup, but I'll have to learn someday since I teach for a
+Microsoft Solution Provider Authorized Tech Education Center - what an
+acronym...) <F>Note: It's under Control Panel | Network | TCP/IP | WINS
+Configuration</F> there's a little text entry field called something like
+'Scope ID'.</P>
+<P>This field essentially creates 'invisible' sub-workgroups on the same
+wire. Boxes can only see other boxes whose Scope IDs are set to the
+exact same value - it's sometimes used by OEMs to configure their
+boxes to browse only other boxes from the same vendor and, in most
+environments, this field should be left blank. If you, in fact, have
+something in this box that EXACT value (case-sensitive!) needs to be
+provided to smbclient and nmbd as the -i (lowercase) parameter. So, if
+your Scope ID is configured as the string 'SomeStr' in Win95 then
+you'd have to use smbclient -iSomeStr <F>otherparms</F> in connecting to
+it.</P>
+
+
+<H2><A NAME="ss3.3">3.3 How do I synchronise my PC's clock with my Samba server? </A></H2>
+
+<P>
+<A NAME="synchronise_clock"></A>
+
+To syncronize your PC's clock with your Samba server:
+<UL>
+<LI> Copy timesync.pif to your windows directory</LI>
+<LI> timesync.pif can be found at:
+<A HREF="http://samba.org/samba/binaries/miscellaneous/timesync.pif">http://samba.org/samba/binaries/miscellaneous/timesync.pif</A></LI>
+<LI> Add timesync.pif to your 'Start Up' group/folder</LI>
+<LI> Open the properties dialog box for the program/icon</LI>
+<LI> Make sure the 'Run Minimized' option is set in program 'Properties'</LI>
+<LI> Change the command line section that reads <F>\\sambahost</F> to reflect the name of your server.</LI>
+<LI> Close the properties dialog box by choosing 'OK'</LI>
+</UL>
+
+Each time you start your computer (or login for Win95) your PC will
+synchronize its clock with your Samba server.</P>
+<P>Alternativley, if you clients support Domain Logons, you can setup Domain Logons with Samba
+- see:
+<A HREF="ftp://samba.org/pub/samba/docs/BROWSING.txt">BROWSING.txt</A> *** for more information.</P>
+<P>Then add
+<BLOCKQUOTE><CODE>
+<PRE>
+NET TIME \\%L /SET /YES
+</PRE>
+</CODE></BLOCKQUOTE>
+
+as one of the lines in the logon script.</P>
+
+<H2><A NAME="ss3.4">3.4 Problems with WinDD, NTrigue, WinCenterPro etc</A></H2>
+
+<P>
+<A NAME="multiple_session_clients"></A>
+</P>
+<P>All of the above programs are applications that sit on an NT box and
+allow multiple users to access the NT GUI applications from remote
+workstations (often over X).</P>
+<P>What has this got to do with Samba? The problem comes when these users
+use filemanager to mount shares from a Samba server. The most common
+symptom is that the first user to connect get correct file permissions
+and has a nice day, but subsequent connections get logged in as the
+same user as the first person to login. They find that they cannot
+access files in their own home directory, but that they can access
+files in the first users home directory (maybe not such a nice day
+after all?)</P>
+<P>Why does this happen? The above products all share a common heritage
+(and code base I believe). They all open just a single TCP based SMB
+connection to the Samba server, and requests from all users are piped
+over this connection. This is unfortunate, but not fatal.</P>
+<P>It means that if you run your Samba server in share level security
+(the default) then things will definately break as described
+above. The share level SMB security model has no provision for
+multiple user IDs on the one SMB connection. See
+<A HREF="ftp://samba.org/pub/samba/docs/security_level.txt">security_level.txt</A> in
+the docs for more info on share/user/server level security.</P>
+<P>If you run in user or server level security then you have a chance,
+but only if you have a recent version of Samba (at least 1.9.15p6). In
+older versions bugs in Samba meant you still would have had problems.</P>
+<P>If you have a trapdoor uid system in your OS then it will never work
+properly. Samba needs to be able to switch uids on the connection and
+it can't if your OS has a trapdoor uid system. You'll know this
+because Samba will note it in your logs.</P>
+<P>Also note that you should not use the magic "homes" share name with
+products like these, as otherwise all users will end up with the same
+home directory. Use <F>\\server\username</F> instead.</P>
+
+
+<H2><A NAME="ss3.5">3.5 Problem with printers under NT</A></H2>
+
+<P>
+<A NAME="nt_printers"></A>
+
+This info from Stefan Hergeth
+hergeth@f7axp1.informatik.fh-muenchen.de may be useful:</P>
+<P>A network-printer (with ethernetcard) is connected to the NT-Clients
+via our UNIX-Fileserver (SAMBA-Server), like the configuration told by
+Matthew Harrell harrell@leech.nrl.navy.mil (see WinNT.txt)
+<OL>
+<LI>If a user has choosen this printer as the default printer in his
+NT-Session and this printer is not connected to the network
+(e.g. switched off) than this user has a problem with the SAMBA-
+connection of his filesystems. It's very slow.
+</LI>
+<LI>If the printer is connected to the network everything works fine.
+</LI>
+<LI>When the smbd ist started with debug level 3, you can see that the
+NT spooling system try to connect to the printer many times. If the
+printer ist not connected to the network this request fails and the
+NT spooler is wasting a lot of time to connect to the printer service.
+This seems to be the reason for the slow network connection.
+</LI>
+<LI>Maybe it's possible to change this behaviour by setting different
+printer properties in the Print-Manager-Menu of NT, but i didn't try it yet.</LI>
+</OL>
+</P>
+
+
+<H2><A NAME="ss3.6">3.6 Why are my file's timestamps off by an hour, or by a few hours?</A></H2>
+
+<P>
+<A NAME="dst_bugs"></A>
+
+This is from Paul Eggert eggert@twinsun.com.</P>
+<P>Most likely it's a problem with your time zone settings.</P>
+<P>Internally, Samba maintains time in traditional Unix format,
+namely, the number of seconds since 1970-01-01 00:00:00 Universal Time
+(or ``GMT''), not counting leap seconds.</P>
+<P>On the server side, Samba uses the Unix TZ variable to convert
+internal timestamps to and from local time. So on the server side, there are
+two things to get right.
+<OL>
+<LI>The Unix system clock must have the correct Universal time.
+Use the shell command "sh -c 'TZ=UTC0 date'" to check this.
+</LI>
+<LI>The TZ environment variable must be set on the server
+before Samba is invoked. The details of this depend on the
+server OS, but typically you must edit a file whose name is
+/etc/TIMEZONE or /etc/default/init, or run the command `zic -l'.
+</LI>
+<LI>TZ must have the correct value.
+<OL>
+<LI>If possible, use geographical time zone settings
+(e.g. TZ='America/Los_Angeles' or perhaps
+TZ=':US/Pacific'). These are supported by most
+popular Unix OSes, are easier to get right, and are
+more accurate for historical timestamps. If your
+operating system has out-of-date tables, you should be
+able to update them from the public domain time zone
+tables at
+<A HREF="ftp://elsie.nci.nih.gov/pub/">ftp://elsie.nci.nih.gov/pub/</A>.
+</LI>
+<LI>If your system does not support geographical timezone
+settings, you must use a Posix-style TZ strings, e.g.
+TZ='PST8PDT,M4.1.0/2,M10.5.0/2' for US Pacific time.
+Posix TZ strings can take the following form (with optional
+items in brackets):
+<PRE>
+ StdOffset[Dst[Offset],Date/Time,Date/Time]
+</PRE>
+
+where:
+<UL>
+<LI> `Std' is the standard time designation (e.g. `PST').
+</LI>
+<LI> `Offset' is the number of hours behind UTC (e.g. `8').
+Prepend a `-' if you are ahead of UTC, and
+append `:30' if you are at a half-hour offset.
+Omit all the remaining items if you do not use
+daylight-saving time.
+</LI>
+<LI> `Dst' is the daylight-saving time designation
+(e.g. `PDT').
+
+The optional second `Offset' is the number of
+hours that daylight-saving time is behind UTC.
+The default is 1 hour ahead of standard time.
+</LI>
+<LI> `Date/Time,Date/Time' specify when daylight-saving
+time starts and ends. The format for a date is
+`Mm.n.d', which specifies the dth day (0 is Sunday)
+of the nth week of the mth month, where week 5 means
+the last such day in the month. The format for a
+time is <F>h</F>h<F>:mm[:ss</F>], using a 24-hour clock.</LI>
+</UL>
+
+Other Posix string formats are allowed but you don't want
+to know about them.</LI>
+</OL>
+</LI>
+</OL>
+
+On the client side, you must make sure that your client's clock and
+time zone is also set appropriately. <F>[I don't know how to do this.</F>]
+Samba traditionally has had many problems dealing with time zones, due
+to the bizarre ways that Microsoft network protocols handle time
+zones. A common symptom is for file timestamps to be off by an hour.
+To work around the problem, try disconnecting from your Samba server
+and then reconnecting to it; or upgrade your Samba server to
+1.9.16alpha10 or later.</P>
+
+
+<H2><A NAME="ss3.7">3.7 How do I set the printer driver name correctly? </A></H2>
+
+<P>
+<A NAME="printer_driver_name"></A>
+
+Question:
+On NT, I opened "Printer Manager" and "Connect to Printer".
+Enter <F>"\\ptdi270\ps1"</F> in the box of printer. I got the
+following error message:
+<BLOCKQUOTE><CODE>
+<PRE>
+ You do not have sufficient access to your machine
+ to connect to the selected printer, since a driver
+ needs to be installed locally.
+</PRE>
+</CODE></BLOCKQUOTE>
+
+Answer:</P>
+<P>In the more recent versions of Samba you can now set the "printer
+driver" in smb.conf. This tells the client what driver to use. For
+example:
+<BLOCKQUOTE><CODE>
+<PRE>
+ printer driver = HP LaserJet 4L
+</PRE>
+</CODE></BLOCKQUOTE>
+
+with this, NT knows to use the right driver. You have to get this string
+exactly right.</P>
+<P>To find the exact string to use, you need to get to the dialog box in
+your client where you select which printer driver to install. The
+correct strings for all the different printers are shown in a listbox
+in that dialog box.</P>
+<P>You could also try setting the driver to NULL like this:
+<BLOCKQUOTE><CODE>
+<PRE>
+ printer driver = NULL
+</PRE>
+</CODE></BLOCKQUOTE>
+
+this is effectively what older versions of Samba did, so if that
+worked for you then give it a go. If this does work then let us know via
+<A HREF="mailto:samba@samba.org">samba@samba.org</A>,
+and we'll make it the default. Currently the default is a 0 length
+string.</P>
+
+
+<H2><A NAME="ss3.8">3.8 I've applied NT 4.0 SP3, and now I can't access Samba shares, Why?</A></H2>
+
+<P>
+<A NAME="NT_SP3_FIX"></A>
+
+As of SP3, Microsoft has decided that they will no longer default to
+passing clear text passwords over the network. To enable access to
+Samba shares from NT 4.0 SP3, you must do <B>ONE</B> of two things:
+<OL>
+<LI> Set the Samba configuration option 'security = user' and implement all of the stuff detailed in
+<A HREF="ftp://samba.org/pub/samba/docs/ENCRYPTION.txt">ENCRYPTION.txt</A>.</LI>
+<LI> Follow Microsoft's directions for setting your NT box to allow plain text passwords. see
+<A HREF="http://www.microsoft.com/kb/articles/q166/7/30.htm">Knowledge Base Article Q166730</A></LI>
+</OL>
+</P>
+
+
+<HR>
+<A HREF="sambafaq-2.html">Previous</A>
+<A HREF="sambafaq-4.html">Next</A>
+<A HREF="sambafaq.html#toc3">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq-4.html b/docs/faq/sambafaq-4.html
new file mode 100755
index 00000000000..94d5c419906
--- /dev/null
+++ b/docs/faq/sambafaq-4.html
@@ -0,0 +1,37 @@
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ: Specific client application problems</TITLE>
+</HEAD>
+<BODY>
+<A HREF="sambafaq-3.html">Previous</A>
+<A HREF="sambafaq-5.html">Next</A>
+<A HREF="sambafaq.html#toc4">Table of Contents</A>
+<HR>
+<H2><A NAME="s4">4. Specific client application problems</A></H2>
+
+<P>
+<A NAME="client_problems"></A>
+</P>
+
+<H2><A NAME="ss4.1">4.1 MS Office Setup reports "Cannot change properties of '\MSOFFICE\SETUP.INI'"</A></H2>
+
+<P>
+<A NAME="cant_change_properties"></A>
+
+When installing MS Office on a Samba drive for which you have admin
+user permissions, ie. admin users = username, you will find the
+setup program unable to complete the installation.</P>
+<P>To get around this problem, do the installation without admin user
+permissions The problem is that MS Office Setup checks that a file is
+rdonly by trying to open it for writing.</P>
+<P>Admin users can always open a file for writing, as they run as root.
+You just have to install as a non-admin user and then use "chown -R"
+to fix the owner.</P>
+
+
+<HR>
+<A HREF="sambafaq-3.html">Previous</A>
+<A HREF="sambafaq-5.html">Next</A>
+<A HREF="sambafaq.html#toc4">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq-5.html b/docs/faq/sambafaq-5.html
new file mode 100755
index 00000000000..0a6e9d08f03
--- /dev/null
+++ b/docs/faq/sambafaq-5.html
@@ -0,0 +1,30 @@
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ: Miscellaneous</TITLE>
+</HEAD>
+<BODY>
+<A HREF="sambafaq-4.html">Previous</A>
+Next
+<A HREF="sambafaq.html#toc5">Table of Contents</A>
+<HR>
+<H2><A NAME="s5">5. Miscellaneous</A></H2>
+
+<P>
+<A NAME="miscellaneous"></A>
+</P>
+<H2><A NAME="ss5.1">5.1 Is Samba Year 2000 compliant?</A></H2>
+
+<P>
+<A NAME="Year2000Compliant"></A>
+
+The CIFS protocol that Samba implements
+negotiates times in various formats, all of which
+are able to cope with dates beyond 2000.</P>
+
+
+<HR>
+<A HREF="sambafaq-4.html">Previous</A>
+Next
+<A HREF="sambafaq.html#toc5">Table of Contents</A>
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq.html b/docs/faq/sambafaq.html
new file mode 100755
index 00000000000..2c703885cdf
--- /dev/null
+++ b/docs/faq/sambafaq.html
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<HTML>
+<HEAD>
+<TITLE> Samba FAQ</TITLE>
+</HEAD>
+<BODY>
+Previous
+<A HREF="sambafaq-1.html">Next</A>
+Table of Contents
+<HR>
+<H1> Samba FAQ</H1>
+
+<H2>Paul Blackman, <CODE>ictinus@samba.org</CODE></H2>v 0.8, June '97
+<P><HR><EM> This is the Frequently Asked Questions (FAQ) document for
+Samba, the free and very popular SMB server product. An SMB server
+allows file and printer connections from clients such as Windows,
+OS/2, Linux and others. Current to version 1.9.17. Please send any
+corrections to the author.</EM><HR></P>
+<P>
+<H2><A NAME="toc1">1.</A> <A HREF="sambafaq-1.html">General Information</A></H2>
+<UL>
+<LI><A HREF="sambafaq-1.html#ss1.1">1.1 What is Samba? </A>
+<LI><A HREF="sambafaq-1.html#ss1.2">1.2 What is the current version of Samba? </A>
+<LI><A HREF="sambafaq-1.html#ss1.3">1.3 Where can I get it? </A>
+<LI><A HREF="sambafaq-1.html#ss1.4">1.4 What do the version numbers mean? </A>
+<LI><A HREF="sambafaq-1.html#ss1.5">1.5 What platforms are supported? </A>
+<LI><A HREF="sambafaq-1.html#ss1.6">1.6 How can I find out more about Samba? </A>
+<LI><A HREF="sambafaq-1.html#ss1.7">1.7 How do I subscribe to the Samba Mailing Lists?</A>
+<LI><A HREF="sambafaq-1.html#ss1.8">1.8 Something's gone wrong - what should I do? </A>
+<LI><A HREF="sambafaq-1.html#ss1.9">1.9 Pizza supply details </A>
+</UL>
+
+<P>
+<H2><A NAME="toc2">2.</A> <A HREF="sambafaq-2.html">Compiling and installing Samba on a Unix host</A></H2>
+<UL>
+<LI><A HREF="sambafaq-2.html#ss2.1">2.1 I can't see the Samba server in any browse lists!</A>
+<LI><A HREF="sambafaq-2.html#ss2.2">2.2 Some files that I KNOW are on the server doesn't show up when I view the files from my client! </A>
+<LI><A HREF="sambafaq-2.html#ss2.3">2.3 Some files on the server show up with really wierd filenames when I view the files from my client! </A>
+<LI><A HREF="sambafaq-2.html#ss2.4">2.4 My client reports "cannot locate specified computer" or similar</A>
+<LI><A HREF="sambafaq-2.html#ss2.5">2.5 My client reports "cannot locate specified share name" or similar</A>
+<LI><A HREF="sambafaq-2.html#ss2.6">2.6 My client reports "cannot find domain controller", "cannot log on to the network" or similar </A>
+<LI><A HREF="sambafaq-2.html#ss2.7">2.7 Printing doesn't work :-(</A>
+<LI><A HREF="sambafaq-2.html#ss2.8">2.8 My programs install on the server OK, but refuse to work properly</A>
+<LI><A HREF="sambafaq-2.html#ss2.9">2.9 My "server string" doesn't seem to be recognised</A>
+<LI><A HREF="sambafaq-2.html#ss2.10">2.10 My client reports "This server is not configured to list shared resources" </A>
+<LI><A HREF="sambafaq-2.html#ss2.11">2.11 Log message "you appear to have a trapdoor uid system" </A>
+</UL>
+
+<P>
+<H2><A NAME="toc3">3.</A> <A HREF="sambafaq-3.html">Common client questions</A></H2>
+<UL>
+<LI><A HREF="sambafaq-3.html#ss3.1">3.1 Are there any Macintosh clients for Samba?</A>
+<LI><A HREF="sambafaq-3.html#ss3.2">3.2 "Session request failed (131,130)" error</A>
+<LI><A HREF="sambafaq-3.html#ss3.3">3.3 How do I synchronise my PC's clock with my Samba server? </A>
+<LI><A HREF="sambafaq-3.html#ss3.4">3.4 Problems with WinDD, NTrigue, WinCenterPro etc</A>
+<LI><A HREF="sambafaq-3.html#ss3.5">3.5 Problem with printers under NT</A>
+<LI><A HREF="sambafaq-3.html#ss3.6">3.6 Why are my file's timestamps off by an hour, or by a few hours?</A>
+<LI><A HREF="sambafaq-3.html#ss3.7">3.7 How do I set the printer driver name correctly? </A>
+<LI><A HREF="sambafaq-3.html#ss3.8">3.8 I've applied NT 4.0 SP3, and now I can't access Samba shares, Why?</A>
+</UL>
+
+<P>
+<H2><A NAME="toc4">4.</A> <A HREF="sambafaq-4.html">Specific client application problems</A></H2>
+<UL>
+<LI><A HREF="sambafaq-4.html#ss4.1">4.1 MS Office Setup reports "Cannot change properties of '\MSOFFICE\SETUP.INI'"</A>
+</UL>
+
+<P>
+<H2><A NAME="toc5">5.</A> <A HREF="sambafaq-5.html">Miscellaneous</A></H2>
+<UL>
+<LI><A HREF="sambafaq-5.html#ss5.1">5.1 Is Samba Year 2000 compliant?</A>
+</UL>
+
+
+<HR>
+Previous
+<A HREF="sambafaq-1.html">Next</A>
+Table of Contents
+</BODY>
+</HTML>
diff --git a/docs/faq/sambafaq.sgml b/docs/faq/sambafaq.sgml
new file mode 100755
index 00000000000..333ac55f673
--- /dev/null
+++ b/docs/faq/sambafaq.sgml
@@ -0,0 +1,792 @@
+<!doctype linuxdoc system> <!-- -*- SGML -*- -->
+<!--
+ v 0.5 18 Oct 1996 Dan Shearer Dan.Shearer@unisa.edu.au
+ First linuxdoc-sgml version, outline only
+ v 0.6 25 Oct 1996 Dan
+ Filled in from current text faq
+ v 0.7 1 June 1997 Paul
+ Replicated changes in txt faq to sgml faq
+ 9 June 1997 Paul
+ Lots of changes, added doco list, updated compatible systems list
+ added NT SP3 entry, added Year 2000 entry, Getting ready for 1.9.17
+ v 0.8 7th Oct 97 Paul
+ changed samba.canberra entries to samba.anu.../samba/
+-->
+
+<article>
+
+<title> Samba FAQ
+
+<author>Paul Blackman, <tt>ictinus@samba.org</tt>
+
+<date>v 0.8, June '97
+
+<abstract> This is the Frequently Asked Questions (FAQ) document for
+Samba, the free and very popular SMB server product. An SMB server
+allows file and printer connections from clients such as Windows,
+OS/2, Linux and others. Current to version 1.9.17. Please send any
+corrections to the author.
+</abstract>
+
+<toc>
+
+<sect> General Information<p> <label id="general_info">
+
+All about Samba - what it is, how to get it, related sources of
+information, how to understand the version numbering scheme, pizza
+details
+
+<sect1> What is Samba? <p> <label id="introduction">
+Samba is a suite of programs which work together to allow clients to
+access to a server's filespace and printers via the SMB (Server
+Message Block) protocol. Initially written for Unix, Samba now also
+runs on Netware, OS/2 and VMS.
+
+In practice, this means that you can redirect disks and printers to
+Unix disks and printers from Lan Manager clients, Windows for
+Workgroups 3.11 clients, Windows NT clients, Linux clients and OS/2
+clients. There is also a generic Unix client program supplied as part
+of the suite which allows Unix users to use an ftp-like interface to
+access filespace and printers on any other SMB servers. This gives the
+capability for these operating systems to behave much like a LAN
+Server or Windows NT Server machine, only with added functionality and
+flexibility designed to make life easier for administrators.
+
+The components of the suite are (in summary):
+
+<itemize>
+<item><bf>smbd</bf>, the SMB server. This handles actual connections from clients, doing all the file, permission and username work
+<item><bf>nmbd</bf>, the Netbios name server, which helps clients locate servers, doing the browsing work and managing domains as this capability is being built into Samba
+<item><bf>smbclient</bf>, the Unix-hosted client program
+<item><bf>smbrun</bf>, a little 'glue' program to help the server run external programs
+<item><bf>testprns</bf>, a program to test server access to printers
+<item><bf>testparms</bf>, a program to test the Samba configuration file for correctness
+<item><bf>smb.conf</bf>, the Samba configuration file
+<item><bf>smbprint</bf>, a sample script to allow a Unix host to use smbclient to print to an SMB server
+<item><bf>Documentation!</bf> DON'T neglect to read it - you will save a great deal of time!
+</itemize>
+
+The suite is supplied with full source (of course!) and is GPLed.
+
+The primary creator of the Samba suite is Andrew Tridgell. Later
+versions incorporate much effort by many net.helpers. The man pages
+and this FAQ were originally written by Karl Auer.
+
+<sect1> What is the current version of Samba? <p><label id="current_version">
+At time of writing, the current version was 1.9.17. If you want to be
+sure check the bottom of the change-log file. <url url="ftp://samba.org/pub/samba/alpha/change-log">
+
+For more information see <ref id="version_nums" name="What do the
+version numbers mean?">
+
+<sect1> Where can I get it? <p> <label id="where">
+The Samba suite is available via anonymous ftp from
+samba.org. The latest and greatest versions of the suite are in
+the directory:
+
+/pub/samba/
+
+Development (read "alpha") versions, which are NOT necessarily stable
+and which do NOT necessarily have accurate documentation, are
+available in the directory:
+
+/pub/samba/alpha
+
+Note that binaries are NOT included in any of the above. Samba is
+distributed ONLY in source form, though binaries may be available from
+other sites. Recent versions of some Linux distributions, for example,
+do contain Samba binaries for that platform.
+
+<sect1> What do the version numbers mean? <p> <label id="version_nums">
+It is not recommended that you run a version of Samba with the word
+"alpha" in its name unless you know what you are doing and are willing
+to do some debugging. Many, many people just get the latest
+recommended stable release version and are happy. If you are brave, by
+all means take the plunge and help with the testing and development -
+but don't install it on your departmental server. Samba is typically
+very stable and safe, and this is mostly due to the policy of many
+public releases.
+
+How the scheme works:
+<enum>
+<item>When major changes are made the version number is increased. For
+example, the transition from 1.9.15 to 1.9.16. However, this version
+number will not appear immediately and people should continue to use
+1.9.15 for production systems (see next point.)
+
+<item>Just after major changes are made the software is considered
+unstable, and a series of alpha releases are distributed, for example
+1.9.16alpha1. These are for testing by those who know what they are
+doing. The "alpha" in the filename will hopefully scare off those who
+are just looking for the latest version to install.
+
+<item>When Andrew thinks that the alphas have stabilised to the point
+where he would recommend new users install it, he renames it to the
+same version number without the alpha, for example 1.9.16.
+
+<item>Inevitably bugs are found in the "stable" releases and minor patch
+levels are released which give us the pXX series, for example 1.9.16p2.
+</enum>
+So the progression goes:
+<verb>
+ 1.9.15p7 (production)
+ 1.9.15p8 (production)
+ 1.9.16alpha1 (test sites only)
+ :
+ 1.9.16alpha20 (test sites only)
+ 1.9.16 (production)
+ 1.9.16p1 (production)
+</verb>
+The above system means that whenever someone looks at the samba ftp
+site they will be able to grab the highest numbered release without an
+alpha in the name and be sure of getting the current recommended
+version.
+
+<sect1> What platforms are supported? <p> <label id="platforms">
+Many different platforms have run Samba successfully. The platforms
+most widely used and thus best tested are Linux and SunOS.
+
+At time of writing, the Makefile claimed support for:
+<itemize>
+<item> A/UX 3.0
+<item> AIX
+<item> Altos Series 386/1000
+<item> Amiga
+<item> Apollo Domain/OS sr10.3
+<item> BSDI
+<item> B.O.S. (Bull Operating System)
+<item> Cray, Unicos 8.0
+<item> Convex
+<item> DGUX.
+<item> DNIX.
+<item> FreeBSD
+<item> HP-UX
+<item> Intergraph.
+<item> Linux with/without shadow passwords and quota
+<item> LYNX 2.3.0
+<item> MachTen (a unix like system for Macintoshes)
+<item> Motorola 88xxx/9xx range of machines
+<item> NetBSD
+<item> NEXTSTEP Release 2.X, 3.0 and greater (including OPENSTEP for Mach).
+<item> OS/2 using EMX 0.9b
+<item> OSF1
+<item> QNX 4.22
+<item> RiscIX.
+<item> RISCOs 5.0B
+<item> SEQUENT.
+<item> SCO (including: 3.2v2, European dist., OpenServer 5)
+<item> SGI.
+<item> SMP_DC.OSx v1.1-94c079 on Pyramid S series
+<item> SONY NEWS, NEWS-OS (4.2.x and 6.1.x)
+<item> SUNOS 4
+<item> SUNOS 5.2, 5.3, and 5.4 (Solaris 2.2, 2.3, and '2.4 and later')
+<item> Sunsoft ISC SVR3V4
+<item> SVR4
+<item> System V with some berkely extensions (Motorola 88k R32V3.2).
+<item> ULTRIX.
+<item> UNIXWARE
+<item> UXP/DS
+</itemize>
+
+<sect1> How can I find out more about Samba? <p> <label id="more">
+There are a number of places to look for more information on Samba, including:
+<itemize>
+<item>Two mailing lists devoted to discussion of Samba-related matters.
+<item>The newsgroup, comp.protocols.smb, which has a great deal of discussion on Samba.
+<item>The WWW site 'SAMBA Web Pages' at <url url="http://samba.edu.au/samba/"> includes:
+ <itemize>
+ <item>Links to man pages and documentation, including this FAQ
+ <item>A comprehensive survey of Samba users.
+ <item>A searchable hypertext archive of the Samba mailing list.
+ <item>Links to Samba source code, binaries, and mirrors of both.
+ </itemize>
+<item>The long list of topic documentation. These files can be found in the 'docs' directory of the Samba source, or at <url url="ftp://samba.org/pub/samba/docs/">
+ <itemize>
+ <item><url url="ftp://samba.org/pub/samba/docs/Application_Serving.txt" name="Application_Serving.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/BROWSING.txt" name="BROWSING.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/BUGS.txt" name="BUGS.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/DIAGNOSIS.txt" name="DIAGNOSIS.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/DNIX.txt" name="DNIX.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/DOMAIN.txt" name="DOMAIN.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/DOMAIN_CONTROL.txt" name="CONTROL.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/ENCRYPTION.txt" name="ENCRYPTION.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/Faxing.txt" name="Faxing.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/GOTCHAS.txt" name="GOTCHAS.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/HINTS.txt" name="HINTS.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/INSTALL.sambatar" name="INSTALL.sambatar">
+ <item><url url="ftp://samba.org/pub/samba/docs/INSTALL.txt" name="INSTALL.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/MIRRORS" name="MIRRORS">
+ <item><url url="ftp://samba.org/pub/samba/docs/NetBIOS.txt" name="NetBIOS.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/OS2.txt" name="OS2.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/PROJECTS" name="PROJECTS">
+ <item><url url="ftp://samba.org/pub/samba/docs/Passwords.txt" name="Passwords.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/Printing.txt" name="Printing.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/README.DCEDFS" name="README.DCEDFS">
+ <item><url url="ftp://samba.org/pub/samba/docs/README.OS2" name="README.OS2">
+ <item><url url="ftp://samba.org/pub/samba/docs/README.jis" name="README.jis">
+ <item><url url="ftp://samba.org/pub/samba/docs/README.sambatar" name="README.sambatar">
+ <item><url url="ftp://samba.org/pub/samba/docs/SCO.txt" name="SCO.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/SMBTAR.notes" name="SMBTAR.notes">
+ <item><url url="ftp://samba.org/pub/samba/docs/Speed.txt" name="Speed.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/Support.txt" name="Support.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/THANKS" name="THANKS">
+ <item><url url="ftp://samba.org/pub/samba/docs/Tracing.txt" name="Tracing.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/UNIX-SMB.txt" name="SMB.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/Warp.txt" name="Warp.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/WinNT.txt" name="WinNT.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/history" name="history">
+ <item><url url="ftp://samba.org/pub/samba/docs/security_level.txt" name="level.txt">
+ <item><url url="ftp://samba.org/pub/samba/docs/wfw_slip.htm" name="slip.htm">
+ </itemize>
+</itemize>
+
+<sect1>How do I subscribe to the Samba Mailing Lists?<p><label id="mailinglist">
+Send email to <htmlurl url="mailto:listproc@samba.org" name="listproc@samba.org">. Make sure the subject line is
+blank, and include the following two lines in the body of the message:
+<tscreen><verb>
+subscribe samba Firstname Lastname
+subscribe samba-announce Firstname Lastname
+</verb></tscreen>
+Obviously you should substitute YOUR first name for "Firstname" and
+YOUR last name for "Lastname"! Try not to send any signature stuff, it
+sometimes confuses the list processor.
+
+The samba list is a digest list - every eight hours or so it
+regurgitates a single message containing all the messages that have
+been received by the list since the last time and sends a copy of this
+message to all subscribers.
+
+If you stop being interested in Samba, please send another email to
+<htmlurl url="mailto:listproc@samba.org" name="listproc@samba.org">. Make sure the subject line is blank, and
+include the following two lines in the body of the message:
+<tscreen><verb>
+unsubscribe samba
+unsubscribe samba-announce
+</verb></tscreen>
+The <bf>From:</bf> line in your message <em>MUST</em> be the same address you used when
+you subscribed.
+
+<sect1> Something's gone wrong - what should I do? <p> <label id="wrong">
+<bf>[#] *** IMPORTANT! *** [#]</bf>
+<p>DO NOT post messages on mailing lists or in newsgroups until you have
+carried out the first three steps given here!
+
+Firstly, see if there are any likely looking entries in this FAQ! If
+you have just installed Samba, have you run through the checklist in
+<url url="ftp://samba.org/pub/samba/DIAGNOSIS.txt" name="DIAGNOSIS.txt">? It can save you a lot of time and effort.
+DIAGNOSIS.txt can also be found in the docs directory of the Samba distribution.
+
+Secondly, read the man pages for smbd, nmbd and smb.conf, looking for
+topics that relate to what you are trying to do.
+
+Thirdly, if there is no obvious solution to hand, try to get a look at
+the log files for smbd and/or nmbd for the period during which you
+were having problems. You may need to reconfigure the servers to
+provide more extensive debugging information - usually level 2 or
+level 3 provide ample debugging info. Inspect these logs closely,
+looking particularly for the string "Error:".
+
+Fourthly, if you still haven't got anywhere, ask the mailing list or
+newsgroup. In general nobody minds answering questions provided you
+have followed the preceding steps. It might be a good idea to scan the
+archives of the mailing list, which are available through the Samba
+web site described in the previous
+section.
+
+If you successfully solve a problem, please mail the FAQ maintainer a
+succinct description of the symptom, the problem and the solution, so
+I can incorporate it in the next version.
+
+If you make changes to the source code, _please_ submit these patches
+so that everyone else gets the benefit of your work. This is one of
+the most important aspects to the maintainence of Samba. Send all
+patches to <htmlurl url="mailto:samba-patches@samba.org" name="samba-patches@samba.org">. Do not send patches to Andrew Tridgell or any
+other individual, they may be lost if you do.
+
+<sect1> Pizza supply details <p> <label id="pizza">
+Those who have registered in the Samba survey as "Pizza Factory" will
+already know this, but the rest may need some help. Andrew doesn't ask
+for payment, but he does appreciate it when people give him
+pizza. This calls for a little organisation when the pizza donor is
+twenty thousand kilometres away, but it has been done.
+
+Method 1: Ring up your local branch of an international pizza chain
+and see if they honour their vouchers internationally. Pizza Hut do,
+which is how the entire Canberra Linux Users Group got to eat pizza
+one night, courtesy of someone in the US
+
+Method 2: Ring up a local pizza shop in Canberra and quote a credit
+card number for a certain amount, and tell them that Andrew will be
+collecting it (don't forget to tell him.) One kind soul from Germany
+did this.
+
+Method 3: Purchase a pizza voucher from your local pizza shop that has
+no international affiliations and send it to Andrew. It is completely
+useless but he can hang it on the wall next to the one he already has
+from Germany :-)
+
+Method 4: Air freight him a pizza with your favourite regional
+flavours. It will probably get stuck in customs or torn apart by
+hungry sniffer dogs but it will have been a noble gesture.
+
+<sect>Compiling and installing Samba on a Unix host<p><label id="unix_install">
+
+<sect1>I can't see the Samba server in any browse lists!<p><label id="no_browse">
+ See <url url="ftp://samba.org/pub/samba/BROWSING.txt" name="BROWSING.txt">
+ for more information on browsing. Browsing.txt can also be found
+ in the docs directory of the Samba source.
+
+If your GUI client does not permit you to select non-browsable
+servers, you may need to do so on the command line. For example, under
+Lan Manager you might connect to the above service as disk drive M:
+thusly:
+<tscreen><verb>
+ net use M: \\mary\fred
+</verb></tscreen>
+The details of how to do this and the specific syntax varies from
+client to client - check your client's documentation.
+
+<sect1>Some files that I KNOW are on the server doesn't show up when I view the files from my client! <p> <label id="missing_files">
+See the next question.
+<sect1>Some files on the server show up with really wierd filenames when I view the files from my client! <p> <label id="strange_filenames">
+If you check what files are not showing up, you will note that they
+are files which contain upper case letters or which are otherwise not
+DOS-compatible (ie, they are not legal DOS filenames for some reason).
+
+The Samba server can be configured either to ignore such files
+completely, or to present them to the client in "mangled" form. If you
+are not seeing the files at all, the Samba server has most likely been
+configured to ignore them. Consult the man page smb.conf(5) for
+details of how to change this - the parameter you need to set is
+"mangled names = yes".
+
+<sect1>My client reports "cannot locate specified computer" or similar<p><label id="cant_see_server">
+This indicates one of three things: You supplied an incorrect server
+name, the underlying TCP/IP layer is not working correctly, or the
+name you specified cannot be resolved.
+
+After carefully checking that the name you typed is the name you
+should have typed, try doing things like pinging a host or telnetting
+to somewhere on your network to see if TCP/IP is functioning OK. If it
+is, the problem is most likely name resolution.
+
+If your client has a facility to do so, hardcode a mapping between the
+hosts IP and the name you want to use. For example, with Man Manager
+or Windows for Workgroups you would put a suitable entry in the file
+LMHOSTS. If this works, the problem is in the communication between
+your client and the netbios name server. If it does not work, then
+there is something fundamental wrong with your naming and the solution
+is beyond the scope of this document.
+
+If you do not have any server on your subnet supplying netbios name
+resolution, hardcoded mappings are your only option. If you DO have a
+netbios name server running (such as the Samba suite's nmbd program),
+the problem probably lies in the way it is set up. Refer to Section
+Two of this FAQ for more ideas.
+
+By the way, remember to REMOVE the hardcoded mapping before further
+tests :-)
+
+<sect1>My client reports "cannot locate specified share name" or similar<p> <label id="cant_see_share">
+This message indicates that your client CAN locate the specified
+server, which is a good start, but that it cannot find a service of
+the name you gave.
+
+The first step is to check the exact name of the service you are
+trying to connect to (consult your system administrator). Assuming it
+exists and you specified it correctly (read your client's doco on how
+to specify a service name correctly), read on:
+
+<itemize>
+<item> Many clients cannot accept or use service names longer than eight characters.
+<item> Many clients cannot accept or use service names containing spaces.
+<item> Some servers (not Samba though) are case sensitive with service names.
+<item> Some clients force service names into upper case.
+</itemize>
+
+<sect1>My client reports "cannot find domain controller", "cannot log on to the network" or similar <p> <label id="cant_see_net">
+Nothing is wrong - Samba does not implement the primary domain name
+controller stuff for several reasons, including the fact that the
+whole concept of a primary domain controller and "logging in to a
+network" doesn't fit well with clients possibly running on multiuser
+machines (such as users of smbclient under Unix). Having said that,
+several developers are working hard on building it in to the next
+major version of Samba. If you can contribute, send a message to
+<htmlurl url="mailto:samba@samba.org" name="samba@samba.org"> !
+
+Seeing this message should not affect your ability to mount redirected
+disks and printers, which is really what all this is about.
+
+For many clients (including Windows for Workgroups and Lan Manager),
+setting the domain to STANDALONE at least gets rid of the message.
+
+<sect1>Printing doesn't work :-(<p> <label id="no_printing">
+Make sure that the specified print command for the service you are
+connecting to is correct and that it has a fully-qualified path (eg.,
+use "/usr/bin/lpr" rather than just "lpr").
+
+Make sure that the spool directory specified for the service is
+writable by the user connected to the service. In particular the user
+"nobody" often has problems with printing, even if it worked with an
+earlier version of Samba. Try creating another guest user other than
+"nobody".
+
+Make sure that the user specified in the service is permitted to use
+the printer.
+
+Check the debug log produced by smbd. Search for the printer name and
+see if the log turns up any clues. Note that error messages to do with
+a service ipc$ are meaningless - they relate to the way the client
+attempts to retrieve status information when using the LANMAN1
+protocol.
+
+If using WfWg then you need to set the default protocol to TCP/IP, not
+Netbeui. This is a WfWg bug.
+
+If using the Lanman1 protocol (the default) then try switching to
+coreplus. Also not that print status error messages don't mean
+printing won't work. The print status is received by a different
+mechanism.
+
+<sect1>My programs install on the server OK, but refuse to work properly<p><label id="programs_wont_run">
+There are numerous possible reasons for this, but one MAJOR
+possibility is that your software uses locking. Make sure you are
+using Samba 1.6.11 or later. It may also be possible to work around
+the problem by setting "locking=no" in the Samba configuration file
+for the service the software is installed on. This should be regarded
+as a strictly temporary solution.
+
+In earlier Samba versions there were some difficulties with the very
+latest Microsoft products, particularly Excel 5 and Word for Windows
+6. These should have all been solved. If not then please let Andrew
+Tridgell know via email at <htmlurl url="mailto:samba@samba.org" name="samba@samba.org">.
+
+<sect1>My "server string" doesn't seem to be recognised<p><label id="bad_server_string">
+OR My client reports the default setting, eg. "Samba 1.9.15p4", instead
+of what I have changed it to in the smb.conf file.
+
+You need to use the -C option in nmbd. The "server string" affects
+what smbd puts out and -C affects what nmbd puts out.
+
+Current versions of Samba (1.9.16 +) have combined these options into
+the "server string" field of smb.conf, -C for nmbd is now obsolete.
+
+<sect1>My client reports "This server is not configured to list shared resources" <p> <label id="cant_list_shares">
+Your guest account is probably invalid for some reason. Samba uses the
+guest account for browsing in smbd. Check that your guest account is
+valid.
+
+See also 'guest account' in smb.conf man page.
+
+<sect1>Log message "you appear to have a trapdoor uid system" <p><label id="trapdoor_uid">
+This can have several causes. It might be because you are using a uid
+or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+hole. Check carefully in your /etc/passwd file and make sure that no
+user has uid 65535 or -1. Especially check the "nobody" user, as many
+broken systems are shipped with nobody setup with a uid of 65535.
+
+It might also mean that your OS has a trapdoor uid/gid system :-)
+
+This means that once a process changes effective uid from root to
+another user it can't go back to root. Unfortunately Samba relies on
+being able to change effective uid from root to non-root and back
+again to implement its security policy. If your OS has a trapdoor uid
+system this won't work, and several things in Samba may break. Less
+things will break if you use user or server level security instead of
+the default share level security, but you may still strike
+problems.
+
+The problems don't give rise to any security holes, so don't panic,
+but it does mean some of Samba's capabilities will be unavailable.
+In particular you will not be able to connect to the Samba server as
+two different uids at once. This may happen if you try to print as a
+"guest" while accessing a share as a normal user. It may also affect
+your ability to list the available shares as this is normally done as
+the guest user.
+
+Complain to your OS vendor and ask them to fix their system.
+
+Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+it casts to -1 as a uid, and the setreuid() system call ignores (with
+no error) uid changes to -1. This means any daemon attempting to run
+as uid 65535 will actually run as root. This is not good!
+
+<sect>Common client questions<p> <label id="client_questions">
+
+<sect1>Are there any Macintosh clients for Samba?<p> <label id="mac_clients">
+Yes! Thursby now have a CIFS Client / Server called DAVE - see <url url="http://www.thursby.com/">.
+They test it against Windows 95, Windows NT and samba for compatibility issues.
+At the time of writing, DAVE was at version 1.0.1. The 1.0.0 to 1.0.1 update is available
+as a free download from the Thursby web site (the speed of finder copies has
+been greatly enhanced, and there are bug-fixes included).
+
+Alternatives - There are two free implementations of AppleTalk for
+several kinds of UNIX machnes, and several more commercial ones.
+These products allow you to run file services and print services
+natively to Macintosh users, with no additional support required on
+the Macintosh. The two free omplementations are Netatalk,
+<url url="http://www.umich.edu/~rsug/netatalk/">, and CAP,
+<url url="http://www.cs.mu.oz.au/appletalk/atalk.html">. What Samba offers
+MS Windows users, these packages offer to Macs. For more info on
+these packages, Samba, and Linux (and other UNIX-based systems)
+see <url url="http://www.eats.com/linux_mac_win.html">
+
+<sect1>"Session request failed (131,130)" error<p> <label id="sess_req_fail">
+The following answer is provided by John E. Miller:
+
+I'll assume that you're able to ping back and forth between the
+machines by IP address and name, and that you're using some security
+model where you're confident that you've got user IDs and passwords
+right. The logging options (-d3 or greater) can help a lot with that.
+DNS and WINS configuration can also impact connectivity as well.
+
+Now, on to 'scope id's. Somewhere in your Win95 TCP/IP network
+configuration (I'm too much of an NT bigot to know where it's located
+in the Win95 setup, but I'll have to learn someday since I teach for a
+Microsoft Solution Provider Authorized Tech Education Center - what an
+acronym...) [Note: It's under Control Panel | Network | TCP/IP | WINS
+Configuration] there's a little text entry field called something like
+'Scope ID'.
+
+This field essentially creates 'invisible' sub-workgroups on the same
+wire. Boxes can only see other boxes whose Scope IDs are set to the
+exact same value - it's sometimes used by OEMs to configure their
+boxes to browse only other boxes from the same vendor and, in most
+environments, this field should be left blank. If you, in fact, have
+something in this box that EXACT value (case-sensitive!) needs to be
+provided to smbclient and nmbd as the -i (lowercase) parameter. So, if
+your Scope ID is configured as the string 'SomeStr' in Win95 then
+you'd have to use smbclient -iSomeStr [otherparms] in connecting to
+it.
+
+<sect1>How do I synchronise my PC's clock with my Samba server? <p><label id="synchronise_clock">
+To syncronize your PC's clock with your Samba server:
+<itemize>
+<item> Copy timesync.pif to your windows directory
+ <item> timesync.pif can be found at:
+ <url
+url="http://samba.org/samba/binaries/miscellaneous/timesync.pif">
+<item> Add timesync.pif to your 'Start Up' group/folder
+<item> Open the properties dialog box for the program/icon
+<item> Make sure the 'Run Minimized' option is set in program 'Properties'
+<iteM> Change the command line section that reads [\\sambahost] to reflect the name of your server.
+<item> Close the properties dialog box by choosing 'OK'
+</itemize>
+Each time you start your computer (or login for Win95) your PC will
+synchronize its clock with your Samba server.
+
+Alternativley, if you clients support Domain Logons, you can setup Domain Logons with Samba
+ - see: <url url="ftp://samba.org/pub/samba/docs/BROWSING.txt" name="BROWSING.txt"> *** for more information.
+<p>Then add
+<tscreen><verb>
+NET TIME \\%L /SET /YES
+</verb></tscreen>
+as one of the lines in the logon script.
+<sect1>Problems with WinDD, NTrigue, WinCenterPro etc<p>
+<label id="multiple_session_clients">
+
+All of the above programs are applications that sit on an NT box and
+allow multiple users to access the NT GUI applications from remote
+workstations (often over X).
+
+What has this got to do with Samba? The problem comes when these users
+use filemanager to mount shares from a Samba server. The most common
+symptom is that the first user to connect get correct file permissions
+and has a nice day, but subsequent connections get logged in as the
+same user as the first person to login. They find that they cannot
+access files in their own home directory, but that they can access
+files in the first users home directory (maybe not such a nice day
+after all?)
+
+Why does this happen? The above products all share a common heritage
+(and code base I believe). They all open just a single TCP based SMB
+connection to the Samba server, and requests from all users are piped
+over this connection. This is unfortunate, but not fatal.
+
+It means that if you run your Samba server in share level security
+(the default) then things will definately break as described
+above. The share level SMB security model has no provision for
+multiple user IDs on the one SMB connection. See <url url="ftp://samba.org/pub/samba/docs/security_level.txt" name="security_level.txt"> in
+the docs for more info on share/user/server level security.
+
+If you run in user or server level security then you have a chance,
+but only if you have a recent version of Samba (at least 1.9.15p6). In
+older versions bugs in Samba meant you still would have had problems.
+
+If you have a trapdoor uid system in your OS then it will never work
+properly. Samba needs to be able to switch uids on the connection and
+it can't if your OS has a trapdoor uid system. You'll know this
+because Samba will note it in your logs.
+
+Also note that you should not use the magic "homes" share name with
+products like these, as otherwise all users will end up with the same
+home directory. Use [\\server\username] instead.
+
+<sect1>Problem with printers under NT<p> <label id="nt_printers">
+This info from Stefan Hergeth
+hergeth@f7axp1.informatik.fh-muenchen.de may be useful:
+
+ A network-printer (with ethernetcard) is connected to the NT-Clients
+via our UNIX-Fileserver (SAMBA-Server), like the configuration told by
+ Matthew Harrell harrell@leech.nrl.navy.mil (see WinNT.txt)
+<enum>
+<item>If a user has choosen this printer as the default printer in his
+ NT-Session and this printer is not connected to the network
+ (e.g. switched off) than this user has a problem with the SAMBA-
+ connection of his filesystems. It's very slow.
+
+<item>If the printer is connected to the network everything works fine.
+
+<item>When the smbd ist started with debug level 3, you can see that the
+ NT spooling system try to connect to the printer many times. If the
+ printer ist not connected to the network this request fails and the
+ NT spooler is wasting a lot of time to connect to the printer service.
+ This seems to be the reason for the slow network connection.
+
+<item>Maybe it's possible to change this behaviour by setting different
+ printer properties in the Print-Manager-Menu of NT, but i didn't try it yet.
+</enum>
+
+<sect1>Why are my file's timestamps off by an hour, or by a few hours?<p><label id="dst_bugs">
+This is from Paul Eggert eggert@twinsun.com.
+
+Most likely it's a problem with your time zone settings.
+
+Internally, Samba maintains time in traditional Unix format,
+namely, the number of seconds since 1970-01-01 00:00:00 Universal Time
+(or ``GMT''), not counting leap seconds.
+
+On the server side, Samba uses the Unix TZ variable to convert
+internal timestamps to and from local time. So on the server side, there are
+two things to get right.
+<enum>
+<item>The Unix system clock must have the correct Universal time.
+ Use the shell command "sh -c 'TZ=UTC0 date'" to check this.
+
+<item>The TZ environment variable must be set on the server
+ before Samba is invoked. The details of this depend on the
+ server OS, but typically you must edit a file whose name is
+ /etc/TIMEZONE or /etc/default/init, or run the command `zic -l'.
+
+<item>TZ must have the correct value.
+<enum>
+ <item>If possible, use geographical time zone settings
+ (e.g. TZ='America/Los_Angeles' or perhaps
+ TZ=':US/Pacific'). These are supported by most
+ popular Unix OSes, are easier to get right, and are
+ more accurate for historical timestamps. If your
+ operating system has out-of-date tables, you should be
+ able to update them from the public domain time zone
+ tables at <url url="ftp://elsie.nci.nih.gov/pub/">.
+
+ <item>If your system does not support geographical timezone
+ settings, you must use a Posix-style TZ strings, e.g.
+ TZ='PST8PDT,M4.1.0/2,M10.5.0/2' for US Pacific time.
+ Posix TZ strings can take the following form (with optional
+ items in brackets):
+<verb>
+ StdOffset[Dst[Offset],Date/Time,Date/Time]
+</verb>
+ where:
+<itemize>
+<item> `Std' is the standard time designation (e.g. `PST').
+
+<item> `Offset' is the number of hours behind UTC (e.g. `8').
+ Prepend a `-' if you are ahead of UTC, and
+ append `:30' if you are at a half-hour offset.
+ Omit all the remaining items if you do not use
+ daylight-saving time.
+
+<item> `Dst' is the daylight-saving time designation
+ (e.g. `PDT').
+
+ The optional second `Offset' is the number of
+ hours that daylight-saving time is behind UTC.
+ The default is 1 hour ahead of standard time.
+
+<item> `Date/Time,Date/Time' specify when daylight-saving
+ time starts and ends. The format for a date is
+ `Mm.n.d', which specifies the dth day (0 is Sunday)
+ of the nth week of the mth month, where week 5 means
+ the last such day in the month. The format for a
+ time is [h]h[:mm[:ss]], using a 24-hour clock.
+</itemize>
+ Other Posix string formats are allowed but you don't want
+ to know about them.
+</enum>
+</enum>
+On the client side, you must make sure that your client's clock and
+time zone is also set appropriately. [[I don't know how to do this.]]
+Samba traditionally has had many problems dealing with time zones, due
+to the bizarre ways that Microsoft network protocols handle time
+zones. A common symptom is for file timestamps to be off by an hour.
+To work around the problem, try disconnecting from your Samba server
+and then reconnecting to it; or upgrade your Samba server to
+1.9.16alpha10 or later.
+
+<sect1> How do I set the printer driver name correctly? <p><label id="printer_driver_name">
+Question:
+ On NT, I opened "Printer Manager" and "Connect to Printer".
+ Enter ["\\ptdi270\ps1"] in the box of printer. I got the
+ following error message:
+<tscreen><verb>
+ You do not have sufficient access to your machine
+ to connect to the selected printer, since a driver
+ needs to be installed locally.
+</verb></tscreen>
+Answer:
+
+In the more recent versions of Samba you can now set the "printer
+driver" in smb.conf. This tells the client what driver to use. For
+example:
+<tscreen><verb>
+ printer driver = HP LaserJet 4L
+</verb></tscreen>
+with this, NT knows to use the right driver. You have to get this string
+exactly right.
+
+To find the exact string to use, you need to get to the dialog box in
+your client where you select which printer driver to install. The
+correct strings for all the different printers are shown in a listbox
+in that dialog box.
+
+You could also try setting the driver to NULL like this:
+<tscreen><verb>
+ printer driver = NULL
+</verb></tscreen>
+this is effectively what older versions of Samba did, so if that
+worked for you then give it a go. If this does work then let us know via <htmlurl url="mailto:samba@samba.org" name="samba@samba.org">,
+and we'll make it the default. Currently the default is a 0 length
+string.
+
+<sect1>I've applied NT 4.0 SP3, and now I can't access Samba shares, Why?<p><label id="NT_SP3_FIX">
+As of SP3, Microsoft has decided that they will no longer default to
+passing clear text passwords over the network. To enable access to
+Samba shares from NT 4.0 SP3, you must do <bf>ONE</bf> of two things:
+<enum>
+<item> Set the Samba configuration option 'security = user' and implement all of the stuff detailed in <url url="ftp://samba.org/pub/samba/docs/ENCRYPTION.txt" name="ENCRYPTION.txt">.
+<item> Follow Microsoft's directions for setting your NT box to allow plain text passwords. see <url url="http://www.microsoft.com/kb/articles/q166/7/30.htm" name="Knowledge Base Article Q166730">
+</enum>
+
+<sect>Specific client application problems<p> <label id="client_problems">
+
+<sect1>MS Office Setup reports "Cannot change properties of '\MSOFFICE\SETUP.INI'"<p> <label id="cant_change_properties">
+When installing MS Office on a Samba drive for which you have admin
+user permissions, ie. admin users = username, you will find the
+setup program unable to complete the installation.
+
+To get around this problem, do the installation without admin user
+permissions The problem is that MS Office Setup checks that a file is
+rdonly by trying to open it for writing.
+
+Admin users can always open a file for writing, as they run as root.
+You just have to install as a non-admin user and then use "chown -R"
+to fix the owner.
+
+<sect>Miscellaneous<p> <label id="miscellaneous">
+<sect1>Is Samba Year 2000 compliant?<p><label id="Year2000Compliant">
+The CIFS protocol that Samba implements
+negotiates times in various formats, all of which
+are able to cope with dates beyond 2000.
+
+</article>
diff --git a/docs/faq/sambafaq.txt b/docs/faq/sambafaq.txt
new file mode 100755
index 00000000000..e629e8ad878
--- /dev/null
+++ b/docs/faq/sambafaq.txt
@@ -0,0 +1,1122 @@
+ Samba FAQ
+ Paul Blackman, ictinus@samba.org
+ v 0.8, June '97
+
+ This is the Frequently Asked Questions (FAQ) document for Samba, the
+ free and very popular SMB server product. An SMB server allows file
+ and printer connections from clients such as Windows, OS/2, Linux and
+ others. Current to version 1.9.17. Please send any corrections to the
+ author.
+ ______________________________________________________________________
+
+ Table of Contents:
+
+ 1. General Information
+
+ 1.1. What is Samba?
+
+ 1.2. What is the current version of Samba?
+
+ 1.3. Where can I get it?
+
+ 1.4. What do the version numbers mean?
+
+ 1.5. What platforms are supported?
+
+ 1.6. How can I find out more about Samba?
+
+ 1.7. How do I subscribe to the Samba Mailing Lists?
+
+ 1.8. Something's gone wrong - what should I do?
+
+ 1.9. Pizza supply details
+
+ 2. Compiling and installing Samba on a Unix host
+
+ 2.1. I can't see the Samba server in any browse lists!
+
+ 2.2. Some files that I KNOW are on the server doesn't show up when
+ I view the files from my client!
+
+ 2.3. Some files on the server show up with really wierd filenames
+ when I view the files from my client!
+
+ 2.4. My client reports "cannot locate specified computer" or
+ similar
+
+ 2.5. My client reports "cannot locate specified share name" or
+ similar
+
+ 2.6. My client reports "cannot find domain controller", "cannot log
+ on to the network" or similar
+
+ 2.7. Printing doesn't work :-(
+
+ 2.8. My programs install on the server OK, but refuse to work
+ properly
+
+ 2.9. My "server string" doesn't seem to be recognised
+
+ 2.10. My client reports "This server is not configured to list
+ shared resources"
+
+ 2.11. Log message "you appear to have a trapdoor uid system"
+
+ 3. Common client questions
+
+ 3.1. Are there any Macintosh clients for Samba?
+
+ 3.2. "Session request failed (131,130)" error
+
+ 3.3. How do I synchronise my PC's clock with my Samba server?
+
+ 3.4. Problems with WinDD, NTrigue, WinCenterPro etc
+
+ 3.5. Problem with printers under NT
+
+ 3.6. Why are my file's timestamps off by an hour, or by a few
+ hours?
+
+ 3.7. How do I set the printer driver name correctly?
+
+ 3.8. I've applied NT 4.0 SP3, and now I can't access Samba shares,
+ Why?
+
+ 4. Specific client application problems
+
+ 4.1. MS Office Setup reports "Cannot change properties of
+ 'MSOFFICEUP.INI'"
+
+ 5. Miscellaneous
+
+ 5.1. Is Samba Year 2000 compliant?
+ ______________________________________________________________________
+
+ 11.. GGeenneerraall IInnffoorrmmaattiioonn
+
+
+
+ All about Samba - what it is, how to get it, related sources of
+ information, how to understand the version numbering scheme, pizza
+ details
+
+
+ 11..11.. WWhhaatt iiss SSaammbbaa??
+
+
+ Samba is a suite of programs which work together to allow clients to
+ access to a server's filespace and printers via the SMB (Server
+ Message Block) protocol. Initially written for Unix, Samba now also
+ runs on Netware, OS/2 and VMS.
+
+ In practice, this means that you can redirect disks and printers to
+ Unix disks and printers from Lan Manager clients, Windows for
+ Workgroups 3.11 clients, Windows NT clients, Linux clients and OS/2
+ clients. There is also a generic Unix client program supplied as part
+ of the suite which allows Unix users to use an ftp-like interface to
+ access filespace and printers on any other SMB servers. This gives the
+ capability for these operating systems to behave much like a LAN
+ Server or Windows NT Server machine, only with added functionality and
+ flexibility designed to make life easier for administrators.
+
+ The components of the suite are (in summary):
+
+
+ +o ssmmbbdd, the SMB server. This handles actual connections from clients,
+ doing all the file, permission and username work
+
+ +o nnmmbbdd, the Netbios name server, which helps clients locate servers,
+ doing the browsing work and managing domains as this capability is
+ being built into Samba
+
+
+ +o ssmmbbcclliieenntt, the Unix-hosted client program
+
+ +o ssmmbbrruunn, a little 'glue' program to help the server run external
+ programs
+
+ +o tteessttpprrnnss, a program to test server access to printers
+
+ +o tteessttppaarrmmss, a program to test the Samba configuration file for
+ correctness
+
+ +o ssmmbb..ccoonnff, the Samba configuration file
+
+ +o ssmmbbpprriinntt, a sample script to allow a Unix host to use smbclient to
+ print to an SMB server
+
+ +o DDooccuummeennttaattiioonn!! DON'T neglect to read it - you will save a great
+ deal of time!
+
+ The suite is supplied with full source (of course!) and is GPLed.
+
+ The primary creator of the Samba suite is Andrew Tridgell. Later
+ versions incorporate much effort by many net.helpers. The man pages
+ and this FAQ were originally written by Karl Auer.
+
+
+ 11..22.. WWhhaatt iiss tthhee ccuurrrreenntt vveerrssiioonn ooff SSaammbbaa??
+
+
+ At time of writing, the current version was 1.9.17. If you want to be
+ sure check the bottom of the change-log file.
+ <ftp://samba.org/pub/samba/alpha/change-log>
+
+ For more information see ``What do the version numbers mean?''
+
+
+ 11..33.. WWhheerree ccaann II ggeett iitt??
+
+
+ The Samba suite is available via anonymous ftp from samba.org.
+ The latest and greatest versions of the suite are in the directory:
+
+ /pub/samba/
+
+ Development (read "alpha") versions, which are NOT necessarily stable
+ and which do NOT necessarily have accurate documentation, are
+ available in the directory:
+
+ /pub/samba/alpha
+
+ Note that binaries are NOT included in any of the above. Samba is
+ distributed ONLY in source form, though binaries may be available from
+ other sites. Recent versions of some Linux distributions, for example,
+ do contain Samba binaries for that platform.
+
+
+ 11..44.. WWhhaatt ddoo tthhee vveerrssiioonn nnuummbbeerrss mmeeaann??
+
+
+ It is not recommended that you run a version of Samba with the word
+ "alpha" in its name unless you know what you are doing and are willing
+ to do some debugging. Many, many people just get the latest
+ recommended stable release version and are happy. If you are brave, by
+ all means take the plunge and help with the testing and development -
+ but don't install it on your departmental server. Samba is typically
+ very stable and safe, and this is mostly due to the policy of many
+ public releases.
+ How the scheme works:
+
+ 1. When major changes are made the version number is increased. For
+ example, the transition from 1.9.15 to 1.9.16. However, this
+ version number will not appear immediately and people should
+ continue to use 1.9.15 for production systems (see next point.)
+
+ 2. Just after major changes are made the software is considered
+ unstable, and a series of alpha releases are distributed, for
+ example 1.9.16alpha1. These are for testing by those who know what
+ they are doing. The "alpha" in the filename will hopefully scare
+ off those who are just looking for the latest version to install.
+
+ 3. When Andrew thinks that the alphas have stabilised to the point
+ where he would recommend new users install it, he renames it to the
+ same version number without the alpha, for example 1.9.16.
+
+ 4. Inevitably bugs are found in the "stable" releases and minor patch
+ levels are released which give us the pXX series, for example
+ 1.9.16p2.
+
+ So the progression goes:
+
+ 1.9.15p7 (production)
+ 1.9.15p8 (production)
+ 1.9.16alpha1 (test sites only)
+ :
+ 1.9.16alpha20 (test sites only)
+ 1.9.16 (production)
+ 1.9.16p1 (production)
+
+
+ The above system means that whenever someone looks at the samba ftp
+ site they will be able to grab the highest numbered release without an
+ alpha in the name and be sure of getting the current recommended ver-
+ sion.
+
+
+ 11..55.. WWhhaatt ppllaattffoorrmmss aarree ssuuppppoorrtteedd??
+
+
+ Many different platforms have run Samba successfully. The platforms
+ most widely used and thus best tested are Linux and SunOS.
+
+ At time of writing, the Makefile claimed support for:
+
+ +o A/UX 3.0
+
+ +o AIX
+
+ +o Altos Series 386/1000
+
+ +o Amiga
+
+ +o Apollo Domain/OS sr10.3
+
+ +o BSDI
+
+ +o B.O.S. (Bull Operating System)
+
+ +o Cray, Unicos 8.0
+
+ +o Convex
+
+ +o DGUX.
+
+ +o DNIX.
+
+ +o FreeBSD
+
+ +o HP-UX
+
+ +o Intergraph.
+
+ +o Linux with/without shadow passwords and quota
+
+ +o LYNX 2.3.0
+
+ +o MachTen (a unix like system for Macintoshes)
+
+ +o Motorola 88xxx/9xx range of machines
+
+ +o NetBSD
+
+ +o NEXTSTEP Release 2.X, 3.0 and greater (including OPENSTEP for
+ Mach).
+
+ +o OS/2 using EMX 0.9b
+
+ +o OSF1
+
+ +o QNX 4.22
+
+ +o RiscIX.
+
+ +o RISCOs 5.0B
+
+ +o SEQUENT.
+
+ +o SCO (including: 3.2v2, European dist., OpenServer 5)
+
+ +o SGI.
+
+ +o SMP_DC.OSx v1.1-94c079 on Pyramid S series
+
+ +o SONY NEWS, NEWS-OS (4.2.x and 6.1.x)
+
+ +o SUNOS 4
+
+ +o SUNOS 5.2, 5.3, and 5.4 (Solaris 2.2, 2.3, and '2.4 and later')
+
+ +o Sunsoft ISC SVR3V4
+
+ +o SVR4
+
+ +o System V with some berkely extensions (Motorola 88k R32V3.2).
+
+ +o ULTRIX.
+
+ +o UNIXWARE
+
+ +o UXP/DS
+
+
+ 11..66.. HHooww ccaann II ffiinndd oouutt mmoorree aabboouutt SSaammbbaa??
+
+
+ There are a number of places to look for more information on Samba,
+ including:
+
+ +o Two mailing lists devoted to discussion of Samba-related matters.
+
+ +o The newsgroup, comp.protocols.smb, which has a great deal of
+ discussion on Samba.
+
+ +o The WWW site 'SAMBA Web Pages' at <http://samba.edu.au/samba/>
+ includes:
+
+ +o Links to man pages and documentation, including this FAQ
+
+ +o A comprehensive survey of Samba users.
+
+ +o A searchable hypertext archive of the Samba mailing list.
+
+ +o Links to Samba source code, binaries, and mirrors of both.
+
+ +o The long list of topic documentation. These files can be found in
+ the 'docs' directory of the Samba source, or at
+ <ftp://samba.org/pub/samba/docs/>
+
+ +o Application_Serving.txt
+ <ftp://samba.org/pub/samba/docs/Application_Serving.txt>
+
+ +o BROWSING.txt <ftp://samba.org/pub/samba/docs/BROWSING.txt>
+
+ +o BUGS.txt <ftp://samba.org/pub/samba/docs/BUGS.txt>
+
+ +o DIAGNOSIS.txt <ftp://samba.org/pub/samba/docs/DIAGNOSIS.txt>
+
+ +o DNIX.txt <ftp://samba.org/pub/samba/docs/DNIX.txt>
+
+ +o DOMAIN.txt <ftp://samba.org/pub/samba/docs/DOMAIN.txt>
+
+ +o CONTROL.txt
+ <ftp://samba.org/pub/samba/docs/DOMAIN_CONTROL.txt>
+
+ +o ENCRYPTION.txt
+ <ftp://samba.org/pub/samba/docs/ENCRYPTION.txt>
+
+ +o Faxing.txt <ftp://samba.org/pub/samba/docs/Faxing.txt>
+
+ +o GOTCHAS.txt <ftp://samba.org/pub/samba/docs/GOTCHAS.txt>
+
+ +o HINTS.txt <ftp://samba.org/pub/samba/docs/HINTS.txt>
+
+ +o INSTALL.sambatar
+ <ftp://samba.org/pub/samba/docs/INSTALL.sambatar>
+
+ +o INSTALL.txt <ftp://samba.org/pub/samba/docs/INSTALL.txt>
+
+ +o MIRRORS <ftp://samba.org/pub/samba/docs/MIRRORS>
+
+ +o NetBIOS.txt <ftp://samba.org/pub/samba/docs/NetBIOS.txt>
+
+ +o OS2.txt <ftp://samba.org/pub/samba/docs/OS2.txt>
+
+ +o PROJECTS <ftp://samba.org/pub/samba/docs/PROJECTS>
+
+ +o Passwords.txt <ftp://samba.org/pub/samba/docs/Passwords.txt>
+
+ +o Printing.txt <ftp://samba.org/pub/samba/docs/Printing.txt>
+
+ +o README.DCEDFS <ftp://samba.org/pub/samba/docs/README.DCEDFS>
+
+ +o README.OS2 <ftp://samba.org/pub/samba/docs/README.OS2>
+
+ +o README.jis <ftp://samba.org/pub/samba/docs/README.jis>
+
+ +o README.sambatar
+ <ftp://samba.org/pub/samba/docs/README.sambatar>
+
+ +o SCO.txt <ftp://samba.org/pub/samba/docs/SCO.txt>
+
+ +o SMBTAR.notes <ftp://samba.org/pub/samba/docs/SMBTAR.notes>
+
+ +o Speed.txt <ftp://samba.org/pub/samba/docs/Speed.txt>
+
+ +o Support.txt <ftp://samba.org/pub/samba/docs/Support.txt>
+
+ +o THANKS <ftp://samba.org/pub/samba/docs/THANKS>
+
+ +o Tracing.txt <ftp://samba.org/pub/samba/docs/Tracing.txt>
+
+ +o SMB.txt <ftp://samba.org/pub/samba/docs/UNIX-SMB.txt>
+
+ +o Warp.txt <ftp://samba.org/pub/samba/docs/Warp.txt>
+
+ +o WinNT.txt <ftp://samba.org/pub/samba/docs/WinNT.txt>
+
+ +o history <ftp://samba.org/pub/samba/docs/history>
+
+ +o level.txt
+ <ftp://samba.org/pub/samba/docs/security_level.txt>
+
+ +o slip.htm <ftp://samba.org/pub/samba/docs/wfw_slip.htm>
+
+
+ 11..77.. HHooww ddoo II ssuubbssccrriibbee ttoo tthhee SSaammbbaa MMaaiilliinngg LLiissttss??
+
+
+ Send email to listproc@samba.org. Make sure the subject line is
+ blank, and include the following two lines in the body of the message:
+
+
+ subscribe samba Firstname Lastname
+ subscribe samba-announce Firstname Lastname
+
+
+
+
+ Obviously you should substitute YOUR first name for "Firstname" and
+ YOUR last name for "Lastname"! Try not to send any signature stuff, it
+ sometimes confuses the list processor.
+
+ The samba list is a digest list - every eight hours or so it
+ regurgitates a single message containing all the messages that have
+ been received by the list since the last time and sends a copy of this
+ message to all subscribers.
+
+ If you stop being interested in Samba, please send another email to
+ listproc@samba.org. Make sure the subject line is blank, and
+ include the following two lines in the body of the message:
+
+
+ unsubscribe samba
+ unsubscribe samba-announce
+
+
+
+
+ The FFrroomm:: line in your message _M_U_S_T be the same address you used when
+ you subscribed.
+
+
+ 11..88.. SSoommeetthhiinngg''ss ggoonnee wwrroonngg -- wwhhaatt sshhoouulldd II ddoo??
+
+
+ ## ****** IIMMPPOORRTTAANNTT!! ****** ##
+
+ DO NOT post messages on mailing lists or in newsgroups until you have
+ carried out the first three steps given here!
+
+ Firstly, see if there are any likely looking entries in this FAQ! If
+ you have just installed Samba, have you run through the checklist in
+ DIAGNOSIS.txt <ftp://samba.org/pub/samba/DIAGNOSIS.txt>? It can
+ save you a lot of time and effort. DIAGNOSIS.txt can also be found in
+ the docs directory of the Samba distribution.
+
+ Secondly, read the man pages for smbd, nmbd and smb.conf, looking for
+ topics that relate to what you are trying to do.
+
+ Thirdly, if there is no obvious solution to hand, try to get a look at
+ the log files for smbd and/or nmbd for the period during which you
+ were having problems. You may need to reconfigure the servers to
+ provide more extensive debugging information - usually level 2 or
+ level 3 provide ample debugging info. Inspect these logs closely,
+ looking particularly for the string "Error:".
+
+ Fourthly, if you still haven't got anywhere, ask the mailing list or
+ newsgroup. In general nobody minds answering questions provided you
+ have followed the preceding steps. It might be a good idea to scan the
+ archives of the mailing list, which are available through the Samba
+ web site described in the previous section.
+
+ If you successfully solve a problem, please mail the FAQ maintainer a
+ succinct description of the symptom, the problem and the solution, so
+ I can incorporate it in the next version.
+
+ If you make changes to the source code, _please_ submit these patches
+ so that everyone else gets the benefit of your work. This is one of
+ the most important aspects to the maintainence of Samba. Send all
+ patches to samba@samba.org. Do not send patches to Andrew
+ Tridgell or any other individual, they may be lost if you do.
+
+
+ 11..99.. PPiizzzzaa ssuuppppllyy ddeettaaiillss
+
+
+ Those who have registered in the Samba survey as "Pizza Factory" will
+ already know this, but the rest may need some help. Andrew doesn't ask
+ for payment, but he does appreciate it when people give him pizza.
+ This calls for a little organisation when the pizza donor is twenty
+ thousand kilometres away, but it has been done.
+
+ Method 1: Ring up your local branch of an international pizza chain
+ and see if they honour their vouchers internationally. Pizza Hut do,
+ which is how the entire Canberra Linux Users Group got to eat pizza
+ one night, courtesy of someone in the US
+
+ Method 2: Ring up a local pizza shop in Canberra and quote a credit
+ card number for a certain amount, and tell them that Andrew will be
+ collecting it (don't forget to tell him.) One kind soul from Germany
+ did this.
+
+ Method 3: Purchase a pizza voucher from your local pizza shop that has
+ no international affiliations and send it to Andrew. It is completely
+ useless but he can hang it on the wall next to the one he already has
+ from Germany :-)
+
+
+ Method 4: Air freight him a pizza with your favourite regional
+ flavours. It will probably get stuck in customs or torn apart by
+ hungry sniffer dogs but it will have been a noble gesture.
+
+
+ 22.. CCoommppiilliinngg aanndd iinnssttaalllliinngg SSaammbbaa oonn aa UUnniixx hhoosstt
+
+
+
+ 22..11.. II ccaann''tt sseeee tthhee SSaammbbaa sseerrvveerr iinn aannyy bbrroowwssee lliissttss!!
+
+
+ See BROWSING.txt <ftp://samba.org/pub/samba/BROWSING.txt> for
+ more information on browsing. Browsing.txt can also be found in the
+ docs directory of the Samba source.
+
+ If your GUI client does not permit you to select non-browsable
+ servers, you may need to do so on the command line. For example, under
+ Lan Manager you might connect to the above service as disk drive M:
+ thusly:
+
+
+ net use M: \\mary\fred
+
+
+
+
+ The details of how to do this and the specific syntax varies from
+ client to client - check your client's documentation.
+
+
+ 22..22.. SSoommee ffiilleess tthhaatt II KKNNOOWW aarree oonn tthhee sseerrvveerr ddooeessnn''tt sshhooww uupp wwhheenn II
+ vviieeww tthhee ffiilleess ffrroomm mmyy cclliieenntt!!
+
+
+ See the next question.
+
+ 22..33.. SSoommee ffiilleess oonn tthhee sseerrvveerr sshhooww uupp wwiitthh rreeaallllyy wwiieerrdd ffiilleennaammeess
+ wwhheenn II vviieeww tthhee ffiilleess ffrroomm mmyy cclliieenntt!!
+
+
+ If you check what files are not showing up, you will note that they
+ are files which contain upper case letters or which are otherwise not
+ DOS-compatible (ie, they are not legal DOS filenames for some reason).
+
+ The Samba server can be configured either to ignore such files
+ completely, or to present them to the client in "mangled" form. If you
+ are not seeing the files at all, the Samba server has most likely been
+ configured to ignore them. Consult the man page smb.conf(5) for
+ details of how to change this - the parameter you need to set is
+ "mangled names = yes".
+
+
+ 22..44.. MMyy cclliieenntt rreeppoorrttss ""ccaannnnoott llooccaattee ssppeecciiffiieedd ccoommppuutteerr"" oorr ssiimmiillaarr
+
+
+ This indicates one of three things: You supplied an incorrect server
+ name, the underlying TCP/IP layer is not working correctly, or the
+ name you specified cannot be resolved.
+
+ After carefully checking that the name you typed is the name you
+ should have typed, try doing things like pinging a host or telnetting
+ to somewhere on your network to see if TCP/IP is functioning OK. If it
+ is, the problem is most likely name resolution.
+
+
+ If your client has a facility to do so, hardcode a mapping between the
+ hosts IP and the name you want to use. For example, with Man Manager
+ or Windows for Workgroups you would put a suitable entry in the file
+ LMHOSTS. If this works, the problem is in the communication between
+ your client and the netbios name server. If it does not work, then
+ there is something fundamental wrong with your naming and the solution
+ is beyond the scope of this document.
+
+ If you do not have any server on your subnet supplying netbios name
+ resolution, hardcoded mappings are your only option. If you DO have a
+ netbios name server running (such as the Samba suite's nmbd program),
+ the problem probably lies in the way it is set up. Refer to Section
+ Two of this FAQ for more ideas.
+
+ By the way, remember to REMOVE the hardcoded mapping before further
+ tests :-)
+
+
+ 22..55.. MMyy cclliieenntt rreeppoorrttss ""ccaannnnoott llooccaattee ssppeecciiffiieedd sshhaarree nnaammee"" oorr ssiimmii--
+ llaarr
+
+
+ This message indicates that your client CAN locate the specified
+ server, which is a good start, but that it cannot find a service of
+ the name you gave.
+
+ The first step is to check the exact name of the service you are
+ trying to connect to (consult your system administrator). Assuming it
+ exists and you specified it correctly (read your client's doco on how
+ to specify a service name correctly), read on:
+
+
+ +o Many clients cannot accept or use service names longer than eight
+ characters.
+
+ +o Many clients cannot accept or use service names containing spaces.
+
+ +o Some servers (not Samba though) are case sensitive with service
+ names.
+
+ +o Some clients force service names into upper case.
+
+
+ 22..66.. MMyy cclliieenntt rreeppoorrttss ""ccaannnnoott ffiinndd ddoommaaiinn ccoonnttrroolllleerr"",, ""ccaannnnoott lloogg
+ oonn ttoo tthhee nneettwwoorrkk"" oorr ssiimmiillaarr
+
+
+ Nothing is wrong - Samba does not implement the primary domain name
+ controller stuff for several reasons, including the fact that the
+ whole concept of a primary domain controller and "logging in to a
+ network" doesn't fit well with clients possibly running on multiuser
+ machines (such as users of smbclient under Unix). Having said that,
+ several developers are working hard on building it in to the next
+ major version of Samba. If you can contribute, send a message to
+ samba@samba.org !
+
+ Seeing this message should not affect your ability to mount redirected
+ disks and printers, which is really what all this is about.
+
+ For many clients (including Windows for Workgroups and Lan Manager),
+ setting the domain to STANDALONE at least gets rid of the message.
+
+
+
+
+
+ 22..77.. PPrriinnttiinngg ddooeessnn''tt wwoorrkk ::--((
+
+
+ Make sure that the specified print command for the service you are
+ connecting to is correct and that it has a fully-qualified path (eg.,
+ use "/usr/bin/lpr" rather than just "lpr").
+
+ Make sure that the spool directory specified for the service is
+ writable by the user connected to the service. In particular the user
+ "nobody" often has problems with printing, even if it worked with an
+ earlier version of Samba. Try creating another guest user other than
+ "nobody".
+
+ Make sure that the user specified in the service is permitted to use
+ the printer.
+
+ Check the debug log produced by smbd. Search for the printer name and
+ see if the log turns up any clues. Note that error messages to do with
+ a service ipc$ are meaningless - they relate to the way the client
+ attempts to retrieve status information when using the LANMAN1
+ protocol.
+
+ If using WfWg then you need to set the default protocol to TCP/IP, not
+ Netbeui. This is a WfWg bug.
+
+ If using the Lanman1 protocol (the default) then try switching to
+ coreplus. Also not that print status error messages don't mean
+ printing won't work. The print status is received by a different
+ mechanism.
+
+
+ 22..88.. MMyy pprrooggrraammss iinnssttaallll oonn tthhee sseerrvveerr OOKK,, bbuutt rreeffuussee ttoo wwoorrkk pprroopp--
+ eerrllyy
+
+
+ There are numerous possible reasons for this, but one MAJOR
+ possibility is that your software uses locking. Make sure you are
+ using Samba 1.6.11 or later. It may also be possible to work around
+ the problem by setting "locking=no" in the Samba configuration file
+ for the service the software is installed on. This should be regarded
+ as a strictly temporary solution.
+
+ In earlier Samba versions there were some difficulties with the very
+ latest Microsoft products, particularly Excel 5 and Word for Windows
+ 6. These should have all been solved. If not then please let Andrew
+ Tridgell know via email at samba@samba.org.
+
+
+ 22..99.. MMyy ""sseerrvveerr ssttrriinngg"" ddooeessnn''tt sseeeemm ttoo bbee rreeccooggnniisseedd
+
+
+ OR My client reports the default setting, eg. "Samba 1.9.15p4",
+ instead of what I have changed it to in the smb.conf file.
+
+ You need to use the -C option in nmbd. The "server string" affects
+ what smbd puts out and -C affects what nmbd puts out.
+
+ Current versions of Samba (1.9.16 +) have combined these options into
+ the "server string" field of smb.conf, -C for nmbd is now obsolete.
+
+
+ 22..1100.. MMyy cclliieenntt rreeppoorrttss ""TThhiiss sseerrvveerr iiss nnoott ccoonnffiigguurreedd ttoo lliisstt sshhaarreedd
+ rreessoouurrcceess""
+
+
+ Your guest account is probably invalid for some reason. Samba uses the
+ guest account for browsing in smbd. Check that your guest account is
+ valid.
+
+ See also 'guest account' in smb.conf man page.
+
+
+ 22..1111.. LLoogg mmeessssaaggee ""yyoouu aappppeeaarr ttoo hhaavvee aa ttrraappddoooorr uuiidd ssyysstteemm""
+
+
+ This can have several causes. It might be because you are using a uid
+ or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+ hole. Check carefully in your /etc/passwd file and make sure that no
+ user has uid 65535 or -1. Especially check the "nobody" user, as many
+ broken systems are shipped with nobody setup with a uid of 65535.
+
+ It might also mean that your OS has a trapdoor uid/gid system :-)
+
+ This means that once a process changes effective uid from root to
+ another user it can't go back to root. Unfortunately Samba relies on
+ being able to change effective uid from root to non-root and back
+ again to implement its security policy. If your OS has a trapdoor uid
+ system this won't work, and several things in Samba may break. Less
+ things will break if you use user or server level security instead of
+ the default share level security, but you may still strike problems.
+
+ The problems don't give rise to any security holes, so don't panic,
+ but it does mean some of Samba's capabilities will be unavailable. In
+ particular you will not be able to connect to the Samba server as two
+ different uids at once. This may happen if you try to print as a
+ "guest" while accessing a share as a normal user. It may also affect
+ your ability to list the available shares as this is normally done as
+ the guest user.
+
+ Complain to your OS vendor and ask them to fix their system.
+
+ Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+ it casts to -1 as a uid, and the setreuid() system call ignores (with
+ no error) uid changes to -1. This means any daemon attempting to run
+ as uid 65535 will actually run as root. This is not good!
+
+
+ 33.. CCoommmmoonn cclliieenntt qquueessttiioonnss
+
+
+
+
+ 33..11.. AArree tthheerree aannyy MMaacciinnttoosshh cclliieennttss ffoorr SSaammbbaa??
+
+
+ Yes! Thursby now have a CIFS Client / Server called DAVE - see
+ <http://www.thursby.com/>. They test it against Windows 95, Windows
+ NT and samba for compatibility issues. At the time of writing, DAVE
+ was at version 1.0.1. The 1.0.0 to 1.0.1 update is available as a free
+ download from the Thursby web site (the speed of finder copies has
+ been greatly enhanced, and there are bug-fixes included).
+
+ Alternatives - There are two free implementations of AppleTalk for
+ several kinds of UNIX machnes, and several more commercial ones.
+ These products allow you to run file services and print services
+ natively to Macintosh users, with no additional support required on
+ the Macintosh. The two free omplementations are Netatalk,
+ <http://www.umich.edu/~rsug/netatalk/>, and CAP,
+ <http://www.cs.mu.oz.au/appletalk/atalk.html>. What Samba offers MS
+ Windows users, these packages offer to Macs. For more info on these
+ packages, Samba, and Linux (and other UNIX-based systems) see
+ <http://www.eats.com/linux_mac_win.html>
+ 33..22.. SSeessssiioonn rreeqquueesstt ffaaiilleedd ((113311,,113300))"" eerrrroorr
+
+
+ The following answer is provided by John E. Miller:
+
+ I'll assume that you're able to ping back and forth between the
+ machines by IP address and name, and that you're using some security
+ model where you're confident that you've got user IDs and passwords
+ right. The logging options (-d3 or greater) can help a lot with that.
+ DNS and WINS configuration can also impact connectivity as well.
+
+ Now, on to 'scope id's. Somewhere in your Win95 TCP/IP network
+ configuration (I'm too much of an NT bigot to know where it's located
+ in the Win95 setup, but I'll have to learn someday since I teach for a
+ Microsoft Solution Provider Authorized Tech Education Center - what an
+ acronym...) Note: It's under Control Panel | Network | TCP/IP | WINS
+ Configuration there's a little text entry field called something like
+
+ This field essentially creates 'invisible' sub-workgroups on the same
+ wire. Boxes can only see other boxes whose Scope IDs are set to the
+ exact same value - it's sometimes used by OEMs to configure their
+ boxes to browse only other boxes from the same vendor and, in most
+ environments, this field should be left blank. If you, in fact, have
+ something in this box that EXACT value (case-sensitive!) needs to be
+ provided to smbclient and nmbd as the -i (lowercase) parameter. So, if
+ your Scope ID is configured as the string 'SomeStr' in Win95 then
+ you'd have to use smbclient -iSomeStr otherparms in connecting to it.
+
+
+ 33..33.. HHooww ddoo II ssyynncchhrroonniissee mmyy PPCC''ss cclloocckk wwiitthh mmyy SSaammbbaa sseerrvveerr??
+
+
+ To syncronize your PC's clock with your Samba server:
+
+ +o Copy timesync.pif to your windows directory
+
+ +o timesync.pif can be found at:
+ <http://samba.org/samba/binaries/miscellaneous/timesync.pif>
+
+ +o Add timesync.pif to your 'Start Up' group/folder
+
+ +o Open the properties dialog box for the program/icon
+
+ +o Make sure the 'Run Minimized' option is set in program 'Properties'
+
+ +o Change the command line section that reads \sambahost to reflect
+ the name of your server.
+
+ +o Close the properties dialog box by choosing 'OK'
+
+ Each time you start your computer (or login for Win95) your PC will
+ synchronize its clock with your Samba server.
+
+ Alternativley, if you clients support Domain Logons, you can setup
+ Domain Logons with Samba - see: BROWSING.txt
+ <ftp://samba.org/pub/samba/docs/BROWSING.txt> *** for more
+ information.
+
+ Then add
+
+
+ NET TIME \\%L /SET /YES
+
+
+
+
+ as one of the lines in the logon script.
+
+ 33..44.. PPrroobblleemmss wwiitthh WWiinnDDDD,, NNTTrriigguuee,, WWiinnCCeenntteerrPPrroo eettcc
+
+
+ All of the above programs are applications that sit on an NT box and
+ allow multiple users to access the NT GUI applications from remote
+ workstations (often over X).
+
+ What has this got to do with Samba? The problem comes when these users
+ use filemanager to mount shares from a Samba server. The most common
+ symptom is that the first user to connect get correct file permissions
+ and has a nice day, but subsequent connections get logged in as the
+ same user as the first person to login. They find that they cannot
+ access files in their own home directory, but that they can access
+ files in the first users home directory (maybe not such a nice day
+ after all?)
+
+ Why does this happen? The above products all share a common heritage
+ (and code base I believe). They all open just a single TCP based SMB
+ connection to the Samba server, and requests from all users are piped
+ over this connection. This is unfortunate, but not fatal.
+
+ It means that if you run your Samba server in share level security
+ (the default) then things will definately break as described above.
+ The share level SMB security model has no provision for multiple user
+ IDs on the one SMB connection. See security_level.txt
+ <ftp://samba.org/pub/samba/docs/security_level.txt> in the docs
+ for more info on share/user/server level security.
+
+ If you run in user or server level security then you have a chance,
+ but only if you have a recent version of Samba (at least 1.9.15p6). In
+ older versions bugs in Samba meant you still would have had problems.
+
+ If you have a trapdoor uid system in your OS then it will never work
+ properly. Samba needs to be able to switch uids on the connection and
+ it can't if your OS has a trapdoor uid system. You'll know this
+ because Samba will note it in your logs.
+
+ Also note that you should not use the magic "homes" share name with
+ products like these, as otherwise all users will end up with the same
+ home directory. Use \serversername instead.
+
+
+ 33..55.. PPrroobblleemm wwiitthh pprriinntteerrss uunnddeerr NNTT
+
+
+ This info from Stefan Hergeth hergeth@f7axp1.informatik.fh-muenchen.de
+ may be useful:
+
+ A network-printer (with ethernetcard) is connected to the NT-Clients
+ via our UNIX-Fileserver (SAMBA-Server), like the configuration told by
+ Matthew Harrell harrell@leech.nrl.navy.mil (see WinNT.txt)
+
+ 1. If a user has choosen this printer as the default printer in his
+ NT-Session and this printer is not connected to the network (e.g.
+ switched off) than this user has a problem with the SAMBA-
+ connection of his filesystems. It's very slow.
+
+ 2. If the printer is connected to the network everything works fine.
+
+ 3. When the smbd ist started with debug level 3, you can see that the
+ NT spooling system try to connect to the printer many times. If the
+ printer ist not connected to the network this request fails and the
+ NT spooler is wasting a lot of time to connect to the printer
+ service. This seems to be the reason for the slow network
+ connection.
+
+ 4. Maybe it's possible to change this behaviour by setting different
+ printer properties in the Print-Manager-Menu of NT, but i didn't
+ try it yet.
+
+
+ 33..66.. WWhhyy aarree mmyy ffiillee''ss ttiimmeessttaammppss ooffff bbyy aann hhoouurr,, oorr bbyy aa ffeeww hhoouurrss??
+
+
+ This is from Paul Eggert eggert@twinsun.com.
+
+ Most likely it's a problem with your time zone settings.
+
+ Internally, Samba maintains time in traditional Unix format, namely,
+ the number of seconds since 1970-01-01 00:00:00 Universal Time (or
+ ``GMT''), not counting leap seconds.
+
+ On the server side, Samba uses the Unix TZ variable to convert
+ internal timestamps to and from local time. So on the server side,
+ there are two things to get right.
+
+ 1. The Unix system clock must have the correct Universal time. Use
+ the shell command "sh -c 'TZ=UTC0 date'" to check this.
+
+ 2. The TZ environment variable must be set on the server before Samba
+ is invoked. The details of this depend on the server OS, but
+ typically you must edit a file whose name is /etc/TIMEZONE or
+ /etc/default/init, or run the command `zic -l'.
+
+ 3. TZ must have the correct value.
+
+ a. If possible, use geographical time zone settings (e.g.
+ TZ='America/Los_Angeles' or perhaps TZ=':US/Pacific'). These
+ are supported by most popular Unix OSes, are easier to get
+ right, and are more accurate for historical timestamps. If your
+ operating system has out-of-date tables, you should be able to
+ update them from the public domain time zone tables at
+ <ftp://elsie.nci.nih.gov/pub/>.
+
+ b. If your system does not support geographical timezone settings,
+ you must use a Posix-style TZ strings, e.g.
+ TZ='PST8PDT,M4.1.0/2,M10.5.0/2' for US Pacific time. Posix TZ
+ strings can take the following form (with optional items in
+ brackets):
+
+ StdOffset[Dst[Offset],Date/Time,Date/Time]
+
+
+ where:
+
+ +o `Std' is the standard time designation (e.g. `PST').
+
+ +o `Offset' is the number of hours behind UTC (e.g. `8'). Prepend
+ a `-' if you are ahead of UTC, and append `:30' if you are at a
+ half-hour offset. Omit all the remaining items if you do not
+ use daylight-saving time.
+
+ +o `Dst' is the daylight-saving time designation (e.g. `PDT').
+
+ The optional second `Offset' is the number of hours that
+ daylight-saving time is behind UTC. The default is 1 hour ahead
+ of standard time.
+
+ +o `Date/Time,Date/Time' specify when daylight-saving time starts
+ and ends. The format for a date is `Mm.n.d', which specifies
+ the dth day (0 is Sunday) of the nth week of the mth month,
+ where week 5 means the last such day in the month. The format
+ for a time is hh:mm[:ss], using a 24-hour clock.
+
+ Other Posix string formats are allowed but you don't want to
+ know about them.
+
+ On the client side, you must make sure that your client's clock and
+ time zone is also set appropriately. [I don't know how to do
+ this.] Samba traditionally has had many problems dealing with time
+ zones, due to the bizarre ways that Microsoft network protocols
+ handle time zones. A common symptom is for file timestamps to be
+ off by an hour. To work around the problem, try disconnecting from
+ your Samba server and then reconnecting to it; or upgrade your
+ Samba server to 1.9.16alpha10 or later.
+
+
+ 33..77.. HHooww ddoo II sseett tthhee pprriinntteerr ddrriivveerr nnaammee ccoorrrreeccttllyy??
+
+
+ Question: On NT, I opened "Printer Manager" and "Connect to Printer".
+ Enter "\ptdi270s1"
+ in the box of printer. I got the following error message:
+
+
+ You do not have sufficient access to your machine
+ to connect to the selected printer, since a driver
+ needs to be installed locally.
+
+
+
+
+ Answer:
+
+ In the more recent versions of Samba you can now set the "printer
+ driver" in smb.conf. This tells the client what driver to use. For
+ example:
+
+
+ printer driver = HP LaserJet 4L
+
+
+
+
+ with this, NT knows to use the right driver. You have to get this
+ string exactly right.
+
+ To find the exact string to use, you need to get to the dialog box in
+ your client where you select which printer driver to install. The
+ correct strings for all the different printers are shown in a listbox
+ in that dialog box.
+
+ You could also try setting the driver to NULL like this:
+
+
+ printer driver = NULL
+
+
+
+
+ this is effectively what older versions of Samba did, so if that
+ worked for you then give it a go. If this does work then let us know
+ via samba@samba.org, and we'll make it the default. Cur-
+ rently the default is a 0 length string.
+
+
+ 33..88.. II''vvee aapppplliieedd NNTT 44..00 SSPP33,, aanndd nnooww II ccaann''tt aacccceessss SSaammbbaa sshhaarreess,,
+ WWhhyy??
+
+
+ As of SP3, Microsoft has decided that they will no longer default to
+ passing clear text passwords over the network. To enable access to
+ Samba shares from NT 4.0 SP3, you must do OONNEE of two things:
+
+ 1. Set the Samba configuration option 'security = user' and implement
+ all of the stuff detailed in ENCRYPTION.txt
+ <ftp://samba.org/pub/samba/docs/ENCRYPTION.txt>.
+
+ 2. Follow Microsoft's directions for setting your NT box to allow
+ plain text passwords. see Knowledge Base Article Q166730
+ <http://www.microsoft.com/kb/articles/q166/7/30.htm>
+
+
+ 44.. SSppeecciiffiicc cclliieenntt aapppplliiccaattiioonn pprroobblleemmss
+
+
+
+
+ 44..11.. MMSS OOffffiiccee SSeettuupp rreeppoorrttss ""CCaannnnoott cchhaannggee pprrooppeerrttiieess ooff ''MMSSOOFF--
+ FFIICCEEUUPP..IINNII''""
+
+
+ When installing MS Office on a Samba drive for which you have admin
+ user permissions, ie. admin users = username, you will find the setup
+ program unable to complete the installation.
+
+ To get around this problem, do the installation without admin user
+ permissions The problem is that MS Office Setup checks that a file is
+ rdonly by trying to open it for writing.
+
+ Admin users can always open a file for writing, as they run as root.
+ You just have to install as a non-admin user and then use "chown -R"
+ to fix the owner.
+
+
+ 55.. MMiisscceellllaanneeoouuss
+
+
+
+ 55..11.. IIss SSaammbbaa YYeeaarr 22000000 ccoommpplliiaanntt??
+
+
+ The CIFS protocol that Samba implements negotiates times in various
+ formats, all of which are able to cope with dates beyond 2000.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/history b/docs/history
new file mode 100755
index 00000000000..7bcbe3564ad
--- /dev/null
+++ b/docs/history
@@ -0,0 +1,218 @@
+Contributor: Andrew Tridgell and the Samba Team
+Date: June 27, 1997
+Satus: Always out of date! (Would not be the same without it!)
+
+Subject: A bit of history and a bit of fun
+============================================================================
+
+This is a short history of this project. It's not supposed to be
+comprehensive, just enough so that new users can get a feel for where
+this project has come from and maybe where it's going to.
+
+The whole thing really started in December 1991. I was (and still am)
+a PhD student in the Computer Sciences Laboratory at the Australian
+National University, in Canberra, Australia. We had just got a
+beta copy of eXcursion from Digital, and I was testing it on my PC. At
+this stage I was a MS-DOS user, dabbling in windows.
+
+eXcursion ran (at the time) only with Dec's `Pathworks' network for
+DOS. I had up till then been using PC-NFS to connect to our local sun
+workstations, and was reasonably happy with it. In order to run
+pathworks I had to stop using PC-NFS and try using pathworks to mount
+disk space. Unfortunately pathworks was only available for digital
+workstations running VMS or Ultrix so I couldn't mount from the suns
+anymore.
+
+I had access to a a decstation 3100 running Ultrix that I used to
+administer, and I got the crazy notion that the protocol that
+pathworks used to talk to ultrix couldn't be that hard, and maybe I
+could work it out. I had never written a network program before, and
+certainly didn't know what a socket was.
+
+In a few days, after looking at some example code for sockets, I
+discovered it was pretty easy to write a program to "spy" on the file
+sharing protocol. I wrote and installed this program (the sockspy.c
+program supplied with this package) and captured everything that the
+pathworks client said to the pathworks server.
+
+I then tried writing short C programs (using Turbo C under DOS) to do
+simple file operations on the network drive (open, read, cd etc) and
+looked at the packets that the server and client exchanged. From this
+I worked out what some of the bytes in the packets meant, and started
+to write my own program to do the same thing on a sun.
+
+After a day or so more I had my first successes and actually managed
+to get a connection and to read a file. From there it was all
+downhill, and a week later I was happily (if a little unreliably)
+mounting disk space from a sun to my PC running pathworks. The server
+code had a lot of `magic' values in it, which seemed to be always
+present with the ultrix server. It was not till 2 years later that I
+found out what all these values meant.
+
+Anyway, I thought other people might be interested in what I had done,
+so I asked a few people at uni, and noone seemed much interested. I
+also spoke to a person at Digital in Canberra (the person who had
+organised a beta test of eXcursion) and asked if I could distribute
+what I'd done, or was it illegal. It was then that I first heard the
+word "netbios" when he told me that he thought it was all covered by a
+spec of some sort (the netbios spec) and thus what I'd done was not
+only legal, but silly.
+
+I found the netbios spec after asking around a bit (the RFC1001 and
+RFC1002 specs) and found they looked nothing like what I'd written, so
+I thought maybe the Digital person was mistaken. I didn't realise RFCs
+referred to the name negotiation and packet encapsulation over TCP/IP,
+and what I'd written was really a SMB implementation.
+
+Anyway, he encouraged me to release it so I put out "Server 0.1" in
+January 1992. I got quite a good response from people wanting to use
+pathworks with non-digital unix workstations, and I soon fixed a few
+bugs, and released "Server 0.5" closely followed by "Server 1.0". All
+three releases came out within about a month of each other.
+
+At this point I got an X Terminal on my desk, and I no longer needed eXcursion
+and I prompty forgot about the whole project, apart from a few people
+who e-mailed me occasionally about it.
+
+Nearly two years then passed with just occasional e-mails asking about
+new versions and bugs. I even added a note to the ftp site asking for
+a volunteer to take over the code as I no longer used it. No one
+volunteered.
+
+During this time I did hear from a couple of people who said it should
+be possible to use my code with Lanmanager, but I never got any
+definite confirmation.
+
+One e-mail I got about the code did, however, make an impression. It
+was from Dan Shearer at the university of South Australia, and he said
+this:
+
+
+ I heard a hint about a free Pathworks server for Unix in the
+ Net channel of the Linux list. After quite a bit of chasing
+ (and lots of interested followups from other Linux people) I
+ got hold of a release news article from you, posted in Jan 92,
+ from someone in the UK.
+
+ Can you tell me what the latest status is? I think you might
+ suddenly find a whole lot of interested hackers in the Linux
+ world at least, which is a place where things tend to happen
+ fast (and even some reliable code gets written, BION!)
+
+I asked him what Linux was, and he told me it was a free Unix for PCs.
+This was in November 1992 and a few months later I was a Linux
+convert! I still didn't need a pathworks server though, so I didn't do
+the port, but I think Dan did.
+
+At about this time I got an e-mail from Digital, from a person working
+on the Alpha software distribution. He asked if I would mind if they
+included my server with the "contributed" cd-rom. This was a bit of a
+shock to me as I never expected Dec to ask me if they could use my
+code! I wrote back saying it was OK, but never heard from him again. I
+don't know if it went on the cd-rom.
+
+Anyway, the next big event was in December 1993, when Dan again sent
+me an e-mail saying my server had "raised its ugly head" on
+comp.protocols.tcpip.ibmpc. I had a quick look on the group, and was
+surprised to see that there were people interested in this thing.
+
+At this time a person from our computer center offered me a couple of
+cheap ethernet cards (3c505s for $15 each) and coincidentially someone
+announced on one of the Linux channels that he had written a 3c505
+driver for Linux. I bought the cards, hacked the driver a little and
+setup a home network between my wifes PC and my Linux box. I then
+needed some way to connect the two, and I didn't own PC-NFS at home,
+so I thought maybe my server could be useful. On the newsgroup among
+the discussions of my server someone had mentioned that there was a
+free client that might work with my server that Microsoft had put up
+for ftp. I downloaded it and found to my surprise that it worked first
+time with my `pathworks' server!
+
+Well, I then did a bit of hacking, asked around a bit and found (I
+think from Dan) that the spec I needed was for the "SMB" protocol, and
+that it was available via ftp. I grabbed it and started removing all
+those ugly constants from the code, now that all was explained.
+
+On December 1st 1993 I announced the start of the "Netbios for Unix"
+project, seeding the mailing list with all the people who had e-mailed
+me over the years asking about the server.
+
+About 35 versions (and two months) later I wrote a short history of
+the project, which you have just read. There are now over a hundred
+people on the mailing list, and lots of people report that they use
+the code and like it. In a few days I will be announcing the release
+of version 1.6 to some of the more popular (and relevant) newsgroups.
+
+
+Andrew Tridgell
+6th February 1994
+
+---------------------
+
+It is now May 1995 and there are about 1400 people on the mailing
+list. I got downloads from the main Samba ftp site from around 5000
+unique hosts in a two month period. There are several mirror
+sites as well. The current version number is 1.9.13.
+
+---------------------
+
+
+---------------------
+It's now March 1996 and version 1.9.16alpha1 has just been
+released. There have been lots of changes recently with master browser
+support and the ability to do domain logons etc. Samba has also been
+ported to OS/2, the amiga and NetWare. There are now 3000 people on
+the samba mailing list.
+---------------------
+
+
+---------------------
+It's now June 1997 and samba-1.9.17 is due out soon. My how time passes!
+Please refer to the WHATSNEW.txt for an update on new features. Just when
+you think you understand what is happening the ground rules change - this
+is a real world after all. Since the heady days of March 1996 there has
+been a concerted effort within the SMB protocol using community to document
+and standardize the protocols. The CIFS initiative has helped a long way
+towards creating a better understood and more interoperable environment.
+The Samba Team has grown in number and have been very active in the standards
+formation and documentation process.
+
+The net effect has been that we have had to do a lot of work to bring Samba
+into line with new features and capabilities in the SMB protocols.
+
+The past year has been a productive one with the following releases:
+ 1.9.16, 1.9.16p2, 1.9.16p6, 1.9.16p9, 1.9.16p10, 1.9.16p11
+
+There are some who believe that 1.9.15p8 was the best release and others
+who would not want to be without the latest. Whatever your perception we
+hope that 1.9.17 will close the gap and convince you all that the long
+wait and the rolling changes really were worth it. Here is functionality
+and a level of code maturity that ..., well - you can be the judge!
+
+Happy SMB networking!
+Samba Team
+
+ps: The bugs are ours, so please report any you find.
+---------------------
+
+---------------------
+It's now October 1998. We just got back from the 3rd CIFS conference
+in SanJose. The Samba Team was the biggest contingent there.
+
+Samba 2.0 should be shipping in the next few weeks with much better
+domain controller support, GUI configuration, a new user space SMB
+filesystem and lots of other neat stuff. I've also noticed that a
+search of job ads in DejaNews turned up 3900 that mention Samba. Looks
+like we've created a small industry.
+
+I've been asked again where the name Samba came from. I might as well
+put it down here for everyone to read. The code in Samba was first
+called just "server", it then got renamed "smbserver" when I
+discovered that the protocol is called SMB. Then in April 1994 I got
+an email from Syntax, the makers of "TotalNet advanced Server", a
+commercial SMB server. They told me that they had a trademark on the
+name SMBserver and I would have to change the name. I ran an egrep for
+words containing S, M, and B on /usr/dict/words and the name Samba
+looked like the best choice. Strangely enough when I repeat that now I
+notice that Samba isn't in /usr/dict/words on my system anymore!
+---------------------
diff --git a/docs/htmldocs/CVS-Access.html b/docs/htmldocs/CVS-Access.html
new file mode 100755
index 00000000000..1329433f1a1
--- /dev/null
+++ b/docs/htmldocs/CVS-Access.html
@@ -0,0 +1,193 @@
+<HTML
+><HEAD
+><TITLE
+>HOWTO Access Samba source code via CVS</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="CVS-ACCESS"
+>HOWTO Access Samba source code via CVS</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Introduction</A
+></H1
+><P
+>Samba is developed in an open environment. Developers use CVS
+(Concurrent Versioning System) to "checkin" (also known as
+"commit") new source code. Samba's various CVS branches can
+be accessed via anonymous CVS using the instructions
+detailed in this chapter.</P
+><P
+>This document is a modified version of the instructions found at
+<A
+HREF="http://samba.org/samba/cvs.html"
+TARGET="_top"
+>http://samba.org/samba/cvs.html</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN8"
+>CVS Access to samba.org</A
+></H1
+><P
+>The machine samba.org runs a publicly accessible CVS
+repository for access to the source code of several packages,
+including samba, rsync and jitterbug. There are two main ways of
+accessing the CVS server on this host.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN11"
+>Access via CVSweb</A
+></H2
+><P
+>You can access the source code via your
+favourite WWW browser. This allows you to access the contents of
+individual files in the repository and also to look at the revision
+history and commit logs of individual files. You can also ask for a diff
+listing between any two versions on the repository.</P
+><P
+>Use the URL : <A
+HREF="http://samba.org/cgi-bin/cvsweb"
+TARGET="_top"
+>http://samba.org/cgi-bin/cvsweb</A
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN16"
+>Access via cvs</A
+></H2
+><P
+>You can also access the source code via a
+normal cvs client. This gives you much more control over you can
+do with the repository and allows you to checkout whole source trees
+and keep them up to date via normal cvs commands. This is the
+preferred method of access if you are a developer and not
+just a casual browser.</P
+><P
+>To download the latest cvs source code, point your
+browser at the URL : <A
+HREF="http://www.cyclic.com/"
+TARGET="_top"
+>http://www.cyclic.com/</A
+>.
+and click on the 'How to get cvs' link. CVS is free software under
+the GNU GPL (as is Samba). Note that there are several graphical CVS clients
+which provide a graphical interface to the sometimes mundane CVS commands.
+Links to theses clients are also available from http://www.cyclic.com.</P
+><P
+>To gain access via anonymous cvs use the following steps.
+For this example it is assumed that you want a copy of the
+samba source code. For the other source code repositories
+on this system just substitute the correct package name</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> Install a recent copy of cvs. All you really need is a
+ copy of the cvs client binary.
+ </P
+></LI
+><LI
+><P
+> Run the command
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot login</B
+>
+ </P
+><P
+> When it asks you for a password type <TT
+CLASS="USERINPUT"
+><B
+>cvs</B
+></TT
+>.
+ </P
+></LI
+><LI
+><P
+> Run the command
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot co samba</B
+>
+ </P
+><P
+> This will create a directory called samba containing the
+ latest samba source code (i.e. the HEAD tagged cvs branch). This
+ currently corresponds to the 3.0 development tree.
+ </P
+><P
+> CVS branches other HEAD can be obtained by using the <TT
+CLASS="PARAMETER"
+><I
+>-r</I
+></TT
+>
+ and defining a tag name. A list of branch tag names can be found on the
+ "Development" page of the samba web site. A common request is to obtain the
+ latest 2.2 release code. This could be done by using the following command.
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot co -r SAMBA_2_2 samba</B
+>
+ </P
+></LI
+><LI
+><P
+> Whenever you want to merge in the latest code changes use
+ the following command from within the samba directory:
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs update -d -P</B
+>
+ </P
+></LI
+></OL
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/DOMAIN_MEMBER.html b/docs/htmldocs/DOMAIN_MEMBER.html
new file mode 100755
index 00000000000..b7ef4c9a61b
--- /dev/null
+++ b/docs/htmldocs/DOMAIN_MEMBER.html
@@ -0,0 +1,372 @@
+<HTML
+><HEAD
+><TITLE
+>security = domain in Samba 2.x</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="DOMAIN-SECURITY"
+>security = domain in Samba 2.x</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Joining an NT Domain with Samba 2.2</A
+></H1
+><P
+>Assume you have a Samba 2.x server with a NetBIOS name of
+ <TT
+CLASS="CONSTANT"
+>SERV1</TT
+> and are joining an NT domain called
+ <TT
+CLASS="CONSTANT"
+>DOM</TT
+>, which has a PDC with a NetBIOS name
+ of <TT
+CLASS="CONSTANT"
+>DOMPDC</TT
+> and two backup domain controllers
+ with NetBIOS names <TT
+CLASS="CONSTANT"
+>DOMBDC1</TT
+> and <TT
+CLASS="CONSTANT"
+>DOMBDC2
+ </TT
+>.</P
+><P
+>In order to join the domain, first stop all Samba daemons
+ and run the command:</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbpasswd -j DOM -r DOMPDC
+ -U<TT
+CLASS="REPLACEABLE"
+><I
+>Administrator%password</I
+></TT
+></B
+></TT
+></P
+><P
+>as we are joining the domain DOM and the PDC for that domain
+ (the only machine that has write access to the domain SAM database)
+ is DOMPDC. The <TT
+CLASS="REPLACEABLE"
+><I
+>Administrator%password</I
+></TT
+> is
+ the login name and password for an account which has the necessary
+ privilege to add machines to the domain. If this is successful
+ you will see the message:</P
+><P
+><TT
+CLASS="COMPUTEROUTPUT"
+>smbpasswd: Joined domain DOM.</TT
+>
+ </P
+><P
+>in your terminal window. See the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+> smbpasswd(8)</A
+> man page for more details.</P
+><P
+>There is existing development code to join a domain
+ without having to create the machine trust account on the PDC
+ beforehand. This code will hopefully be available soon
+ in release branches as well.</P
+><P
+>This command goes through the machine account password
+ change protocol, then writes the new (random) machine account
+ password for this Samba server into a file in the same directory
+ in which an smbpasswd file would be stored - normally :</P
+><P
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/private</TT
+></P
+><P
+>In Samba 2.0.x, the filename looks like this:</P
+><P
+><TT
+CLASS="FILENAME"
+><TT
+CLASS="REPLACEABLE"
+><I
+>&lt;NT DOMAIN NAME&gt;</I
+></TT
+>.<TT
+CLASS="REPLACEABLE"
+><I
+>&lt;Samba
+ Server Name&gt;</I
+></TT
+>.mac</TT
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>.mac</TT
+> suffix stands for machine account
+ password file. So in our example above, the file would be called:</P
+><P
+><TT
+CLASS="FILENAME"
+>DOM.SERV1.mac</TT
+></P
+><P
+>In Samba 2.2, this file has been replaced with a TDB
+ (Trivial Database) file named <TT
+CLASS="FILENAME"
+>secrets.tdb</TT
+>.
+ </P
+><P
+>This file is created and owned by root and is not
+ readable by any other user. It is the key to the domain-level
+ security for your system, and should be treated as carefully
+ as a shadow password file.</P
+><P
+>Now, before restarting the Samba daemons you must
+ edit your <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ </A
+> file to tell Samba it should now use domain security.</P
+><P
+>Change (or add) your <A
+HREF="smb.conf.5.html#SECURITY"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>security =</I
+></TT
+></A
+> line in the [global] section
+ of your smb.conf to read:</P
+><P
+><B
+CLASS="COMMAND"
+>security = domain</B
+></P
+><P
+>Next change the <A
+HREF="smb.conf.5.html#WORKGROUP"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> workgroup =</I
+></TT
+></A
+> line in the [global] section to read: </P
+><P
+><B
+CLASS="COMMAND"
+>workgroup = DOM</B
+></P
+><P
+>as this is the name of the domain we are joining. </P
+><P
+>You must also have the parameter <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>encrypt passwords</I
+></TT
+></A
+> set to <TT
+CLASS="CONSTANT"
+>yes
+ </TT
+> in order for your users to authenticate to the NT PDC.</P
+><P
+>Finally, add (or modify) a <A
+HREF="smb.conf.5.html#PASSWORDSERVER"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>password server =</I
+></TT
+></A
+> line in the [global]
+ section to read: </P
+><P
+><B
+CLASS="COMMAND"
+>password server = DOMPDC DOMBDC1 DOMBDC2</B
+></P
+><P
+>These are the primary and backup domain controllers Samba
+ will attempt to contact in order to authenticate users. Samba will
+ try to contact each of these servers in order, so you may want to
+ rearrange this list in order to spread out the authentication load
+ among domain controllers.</P
+><P
+>Alternatively, if you want smbd to automatically determine
+ the list of Domain controllers to use for authentication, you may
+ set this line to be :</P
+><P
+><B
+CLASS="COMMAND"
+>password server = *</B
+></P
+><P
+>This method, which was introduced in Samba 2.0.6,
+ allows Samba to use exactly the same mechanism that NT does. This
+ method either broadcasts or uses a WINS database in order to
+ find domain controllers to authenticate against.</P
+><P
+>Finally, restart your Samba daemons and get ready for
+ clients to begin using domain security!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN67"
+>Samba and Windows 2000 Domains</A
+></H1
+><P
+>Many people have asked regarding the state of Samba's ability to participate in
+a Windows 2000 Domain. Samba 2.2 is able to act as a member server of a Windows
+2000 domain operating in mixed or native mode.</P
+><P
+>There is much confusion between the circumstances that require a "mixed" mode
+Win2k DC and a when this host can be switched to "native" mode. A "mixed" mode
+Win2k domain controller is only needed if Windows NT BDCs must exist in the same
+domain. By default, a Win2k DC in "native" mode will still support
+NetBIOS and NTLMv1 for authentication of legacy clients such as Windows 9x and
+NT 4.0. Samba has the same requirements as a Windows NT 4.0 member server.</P
+><P
+>The steps for adding a Samba 2.2 host to a Win2k domain are the same as those
+for adding a Samba server to a Windows NT 4.0 domain. The only exception is that
+the "Server Manager" from NT 4 has been replaced by the "Active Directory Users and
+Computers" MMC (Microsoft Management Console) plugin.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN72"
+>Why is this better than security = server?</A
+></H1
+><P
+>Currently, domain security in Samba doesn't free you from
+ having to create local Unix users to represent the users attaching
+ to your server. This means that if domain user <TT
+CLASS="CONSTANT"
+>DOM\fred
+ </TT
+> attaches to your domain security Samba server, there needs
+ to be a local Unix user fred to represent that user in the Unix
+ filesystem. This is very similar to the older Samba security mode
+ <A
+HREF="smb.conf.5.html#SECURITYEQUALSSERVER"
+TARGET="_top"
+>security = server</A
+>,
+ where Samba would pass through the authentication request to a Windows
+ NT server in the same way as a Windows 95 or Windows 98 server would.
+ </P
+><P
+>Please refer to the <A
+HREF="winbind.html"
+TARGET="_top"
+>Winbind
+ paper</A
+> for information on a system to automatically
+ assign UNIX uids and gids to Windows NT Domain users and groups.
+ This code is available in development branches only at the moment,
+ but will be moved to release branches soon.</P
+><P
+>The advantage to domain-level security is that the
+ authentication in domain-level security is passed down the authenticated
+ RPC channel in exactly the same way that an NT server would do it. This
+ means Samba servers now participate in domain trust relationships in
+ exactly the same way NT servers do (i.e., you can add Samba servers into
+ a resource domain and have the authentication passed on from a resource
+ domain PDC to an account domain PDC.</P
+><P
+>In addition, with <B
+CLASS="COMMAND"
+>security = server</B
+> every Samba
+ daemon on a server has to keep a connection open to the
+ authenticating server for as long as that daemon lasts. This can drain
+ the connection resources on a Microsoft NT server and cause it to run
+ out of available connections. With <B
+CLASS="COMMAND"
+>security = domain</B
+>,
+ however, the Samba daemons connect to the PDC/BDC only for as long
+ as is necessary to authenticate the user, and then drop the connection,
+ thus conserving PDC connection resources.</P
+><P
+>And finally, acting in the same manner as an NT server
+ authenticating to a PDC means that as part of the authentication
+ reply, the Samba server gets the user identification information such
+ as the user SID, the list of NT groups the user belongs to, etc. All
+ this information will allow Samba to be extended in the future into
+ a mode the developers currently call appliance mode. In this mode,
+ no local Unix users will be necessary, and Samba will generate Unix
+ uids and gids from the information passed back from the PDC when a
+ user is authenticated, making a Samba server truly plug and play
+ in an NT domain environment. Watch for this code soon.</P
+><P
+><I
+CLASS="EMPHASIS"
+>NOTE:</I
+> Much of the text of this document
+ was first published in the Web magazine <A
+HREF="http://www.linuxworld.com"
+TARGET="_top"
+>
+ LinuxWorld</A
+> as the article <A
+HREF="http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html"
+TARGET="_top"
+>Doing
+ the NIS/NT Samba</A
+>.</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/ENCRYPTION.html b/docs/htmldocs/ENCRYPTION.html
new file mode 100755
index 00000000000..e4d3ef5fed2
--- /dev/null
+++ b/docs/htmldocs/ENCRYPTION.html
@@ -0,0 +1,656 @@
+<HTML
+><HEAD
+><TITLE
+>LanMan and NT Password Encryption in Samba 2.x</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="PWENCRYPT"
+>LanMan and NT Password Encryption in Samba 2.x</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Introduction</A
+></H1
+><P
+>With the development of LanManager and Windows NT
+ compatible password encryption for Samba, it is now able
+ to validate user connections in exactly the same way as
+ a LanManager or Windows NT server.</P
+><P
+>This document describes how the SMB password encryption
+ algorithm works and what issues there are in choosing whether
+ you want to use it. You should read it carefully, especially
+ the part about security and the "PROS and CONS" section.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN7"
+>How does it work?</A
+></H1
+><P
+>LanManager encryption is somewhat similar to UNIX
+ password encryption. The server uses a file containing a
+ hashed value of a user's password. This is created by taking
+ the user's plaintext password, capitalising it, and either
+ truncating to 14 bytes or padding to 14 bytes with null bytes.
+ This 14 byte value is used as two 56 bit DES keys to encrypt
+ a 'magic' eight byte value, forming a 16 byte value which is
+ stored by the server and client. Let this value be known as
+ the "hashed password".</P
+><P
+>Windows NT encryption is a higher quality mechanism,
+ consisting of doing an MD4 hash on a Unicode version of the user's
+ password. This also produces a 16 byte hash value that is
+ non-reversible.</P
+><P
+>When a client (LanManager, Windows for WorkGroups, Windows
+ 95 or Windows NT) wishes to mount a Samba drive (or use a Samba
+ resource), it first requests a connection and negotiates the
+ protocol that the client and server will use. In the reply to this
+ request the Samba server generates and appends an 8 byte, random
+ value - this is stored in the Samba server after the reply is sent
+ and is known as the "challenge". The challenge is different for
+ every client connection.</P
+><P
+>The client then uses the hashed password (16 byte values
+ described above), appended with 5 null bytes, as three 56 bit
+ DES keys, each of which is used to encrypt the challenge 8 byte
+ value, forming a 24 byte value known as the "response".</P
+><P
+>In the SMB call SMBsessionsetupX (when user level security
+ is selected) or the call SMBtconX (when share level security is
+ selected), the 24 byte response is returned by the client to the
+ Samba server. For Windows NT protocol levels the above calculation
+ is done on both hashes of the user's password and both responses are
+ returned in the SMB call, giving two 24 byte values.</P
+><P
+>The Samba server then reproduces the above calculation, using
+ its own stored value of the 16 byte hashed password (read from the
+ <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file - described later) and the challenge
+ value that it kept from the negotiate protocol reply. It then checks
+ to see if the 24 byte value it calculates matches the 24 byte value
+ returned to it from the client.</P
+><P
+>If these values match exactly, then the client knew the
+ correct password (or the 16 byte hashed value - see security note
+ below) and is thus allowed access. If not, then the client did not
+ know the correct password and is denied access.</P
+><P
+>Note that the Samba server never knows or stores the cleartext
+ of the user's password - just the 16 byte hashed values derived from
+ it. Also note that the cleartext password or 16 byte hashed values
+ are never transmitted over the network - thus increasing security.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN18"
+>Important Notes About Security</A
+></H1
+><P
+>The unix and SMB password encryption techniques seem similar
+ on the surface. This similarity is, however, only skin deep. The unix
+ scheme typically sends clear text passwords over the network when
+ logging in. This is bad. The SMB encryption scheme never sends the
+ cleartext password over the network but it does store the 16 byte
+ hashed values on disk. This is also bad. Why? Because the 16 byte hashed
+ values are a "password equivalent". You cannot derive the user's
+ password from them, but they could potentially be used in a modified
+ client to gain access to a server. This would require considerable
+ technical knowledge on behalf of the attacker but is perfectly possible.
+ You should thus treat the smbpasswd file as though it contained the
+ cleartext passwords of all your users. Its contents must be kept
+ secret, and the file should be protected accordingly.</P
+><P
+>Ideally we would like a password scheme which neither requires
+ plain text passwords on the net or on disk. Unfortunately this
+ is not available as Samba is stuck with being compatible with
+ other SMB systems (WinNT, WfWg, Win95 etc). </P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Warning</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>Note that Windows NT 4.0 Service pack 3 changed the
+ default for permissible authentication so that plaintext
+ passwords are <I
+CLASS="EMPHASIS"
+>never</I
+> sent over the wire.
+ The solution to this is either to switch to encrypted passwords
+ with Samba or edit the Windows NT registry to re-enable plaintext
+ passwords. See the document WinNT.txt for details on how to do
+ this.</P
+><P
+>Other Microsoft operating systems which also exhibit
+ this behavior includes</P
+><P
+></P
+><UL
+><LI
+><P
+>MS DOS Network client 3.0 with
+ the basic network redirector installed</P
+></LI
+><LI
+><P
+>Windows 95 with the network redirector
+ update installed</P
+></LI
+><LI
+><P
+>Windows 98 [se]</P
+></LI
+><LI
+><P
+>Windows 2000</P
+></LI
+></UL
+><P
+><I
+CLASS="EMPHASIS"
+>Note :</I
+>All current release of
+ Microsoft SMB/CIFS clients support authentication via the
+ SMB Challenge/Response mechanism described here. Enabling
+ clear text authentication does not disable the ability
+ of the client to participate in encrypted authentication.</P
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN37"
+>Advantages of SMB Encryption</A
+></H2
+><P
+></P
+><UL
+><LI
+><P
+>plain text passwords are not passed across
+ the network. Someone using a network sniffer cannot just
+ record passwords going to the SMB server.</P
+></LI
+><LI
+><P
+>WinNT doesn't like talking to a server
+ that isn't using SMB encrypted passwords. It will refuse
+ to browse the server if the server is also in user level
+ security mode. It will insist on prompting the user for the
+ password on each connection, which is very annoying. The
+ only things you can do to stop this is to use SMB encryption.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN44"
+>Advantages of non-encrypted passwords</A
+></H2
+><P
+></P
+><UL
+><LI
+><P
+>plain text passwords are not kept
+ on disk. </P
+></LI
+><LI
+><P
+>uses same password file as other unix
+ services such as login and ftp</P
+></LI
+><LI
+><P
+>you are probably already using other
+ services (such as telnet and ftp) which send plain text
+ passwords over the net, so sending them for SMB isn't
+ such a big deal.</P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN53"
+><A
+NAME="SMBPASSWDFILEFORMAT"
+></A
+>The smbpasswd file</A
+></H1
+><P
+>In order for Samba to participate in the above protocol
+ it must be able to look up the 16 byte hashed values given a user name.
+ Unfortunately, as the UNIX password value is also a one way hash
+ function (ie. it is impossible to retrieve the cleartext of the user's
+ password given the UNIX hash of it), a separate password file
+ containing this 16 byte value must be kept. To minimise problems with
+ these two password files, getting out of sync, the UNIX <TT
+CLASS="FILENAME"
+> /etc/passwd</TT
+> and the <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file,
+ a utility, <B
+CLASS="COMMAND"
+>mksmbpasswd.sh</B
+>, is provided to generate
+ a smbpasswd file from a UNIX <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> file.
+ </P
+><P
+>To generate the smbpasswd file from your <TT
+CLASS="FILENAME"
+>/etc/passwd
+ </TT
+> file use the following command :</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>cat /etc/passwd | mksmbpasswd.sh
+ &gt; /usr/local/samba/private/smbpasswd</B
+></TT
+></P
+><P
+>If you are running on a system that uses NIS, use</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>ypcat passwd | mksmbpasswd.sh
+ &gt; /usr/local/samba/private/smbpasswd</B
+></TT
+></P
+><P
+>The <B
+CLASS="COMMAND"
+>mksmbpasswd.sh</B
+> program is found in
+ the Samba source directory. By default, the smbpasswd file is
+ stored in :</P
+><P
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/private/smbpasswd</TT
+></P
+><P
+>The owner of the <TT
+CLASS="FILENAME"
+>/usr/local/samba/private/</TT
+>
+ directory should be set to root, and the permissions on it should
+ be set to 0500 (<B
+CLASS="COMMAND"
+>chmod 500 /usr/local/samba/private</B
+>).
+ </P
+><P
+>Likewise, the smbpasswd file inside the private directory should
+ be owned by root and the permissions on is should be set to 0600
+ (<B
+CLASS="COMMAND"
+>chmod 600 smbpasswd</B
+>).</P
+><P
+>The format of the smbpasswd file is (The line has been
+ wrapped here. It should appear as one entry per line in
+ your smbpasswd file.)</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
+ [Account type]:LCT-&lt;last-change-time&gt;:Long name
+ </PRE
+></P
+><P
+>Although only the <TT
+CLASS="REPLACEABLE"
+><I
+>username</I
+></TT
+>,
+ <TT
+CLASS="REPLACEABLE"
+><I
+>uid</I
+></TT
+>, <TT
+CLASS="REPLACEABLE"
+><I
+> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</I
+></TT
+>,
+ [<TT
+CLASS="REPLACEABLE"
+><I
+>Account type</I
+></TT
+>] and <TT
+CLASS="REPLACEABLE"
+><I
+> last-change-time</I
+></TT
+> sections are significant
+ and are looked at in the Samba code.</P
+><P
+>It is <I
+CLASS="EMPHASIS"
+>VITALLY</I
+> important that there by 32
+ 'X' characters between the two ':' characters in the XXX sections -
+ the smbpasswd and Samba code will fail to validate any entries that
+ do not have 32 characters between ':' characters. The first XXX
+ section is for the Lanman password hash, the second is for the
+ Windows NT version.</P
+><P
+>When the password file is created all users have password entries
+ consisting of 32 'X' characters. By default this disallows any access
+ as this user. When a user has a password set, the 'X' characters change
+ to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
+ representation of the 16 byte hashed value of a user's password.</P
+><P
+>To set a user to have no password (not recommended), edit the file
+ using vi, and replace the first 11 characters with the ascii text
+ <TT
+CLASS="CONSTANT"
+>"NO PASSWORD"</TT
+> (minus the quotes).</P
+><P
+>For example, to clear the password for user bob, his smbpasswd file
+ entry would look like :</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:Bob's full name:/bobhome:/bobshell
+ </PRE
+></P
+><P
+>If you are allowing users to use the smbpasswd command to set
+ their own passwords, you may want to give users NO PASSWORD initially
+ so they do not have to enter a previous password when changing to their
+ new password (not recommended). In order for you to allow this the
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+> program must be able to connect to the
+ <B
+CLASS="COMMAND"
+>smbd</B
+> daemon as that user with no password. Enable this
+ by adding the line :</P
+><P
+><B
+CLASS="COMMAND"
+>null passwords = yes</B
+></P
+><P
+>to the [global] section of the smb.conf file (this is why
+ the above scenario is not recommended). Preferably, allocate your
+ users a default password to begin with, so you do not have
+ to enable this on your server.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note : </I
+>This file should be protected very
+ carefully. Anyone with access to this file can (with enough knowledge of
+ the protocols) gain access to your SMB server. The file is thus more
+ sensitive than a normal unix <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> file.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN105"
+>The smbpasswd Command</A
+></H1
+><P
+>The smbpasswd command maintains the two 32 byte password fields
+ in the smbpasswd file. If you wish to make it similar to the unix
+ <B
+CLASS="COMMAND"
+>passwd</B
+> or <B
+CLASS="COMMAND"
+>yppasswd</B
+> programs,
+ install it in <TT
+CLASS="FILENAME"
+>/usr/local/samba/bin/</TT
+> (or your
+ main Samba binary directory).</P
+><P
+>Note that as of Samba 1.9.18p4 this program <I
+CLASS="EMPHASIS"
+>MUST NOT
+ BE INSTALLED</I
+> setuid root (the new <B
+CLASS="COMMAND"
+>smbpasswd</B
+>
+ code enforces this restriction so it cannot be run this way by
+ accident).</P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> now works in a client-server mode
+ where it contacts the local smbd to change the user's password on its
+ behalf. This has enormous benefits - as follows.</P
+><P
+></P
+><UL
+><LI
+><P
+>smbpasswd no longer has to be setuid root -
+ an enormous range of potential security problems is
+ eliminated.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> now has the capability
+ to change passwords on Windows NT servers (this only works when
+ the request is sent to the NT Primary Domain Controller if you
+ are changing an NT Domain user's password).</P
+></LI
+></UL
+><P
+>To run smbpasswd as a normal user just type :</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbpasswd</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>Old SMB password: </TT
+><TT
+CLASS="USERINPUT"
+><B
+>&lt;type old value here -
+ or hit return if there was no old password&gt;</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>New SMB Password: </TT
+><TT
+CLASS="USERINPUT"
+><B
+>&lt;type new value&gt;
+ </B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>Repeat New SMB Password: </TT
+><TT
+CLASS="USERINPUT"
+><B
+>&lt;re-type new value
+ </B
+></TT
+></P
+><P
+>If the old value does not match the current value stored for
+ that user, or the two new values do not match each other, then the
+ password will not be changed.</P
+><P
+>If invoked by an ordinary user it will only allow the user
+ to change his or her own Samba password.</P
+><P
+>If run by the root user smbpasswd may take an optional
+ argument, specifying the user name whose SMB password you wish to
+ change. Note that when run as root smbpasswd does not prompt for
+ or check the old password value, thus allowing root to set passwords
+ for users who have forgotten their passwords.</P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> is designed to work in the same way
+ and be familiar to UNIX users who use the <B
+CLASS="COMMAND"
+>passwd</B
+> or
+ <B
+CLASS="COMMAND"
+>yppasswd</B
+> commands.</P
+><P
+>For more details on using <B
+CLASS="COMMAND"
+>smbpasswd</B
+> refer
+ to the man page which will always be the definitive reference.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN144"
+>Setting up Samba to support LanManager Encryption</A
+></H1
+><P
+>This is a very brief description on how to setup samba to
+ support password encryption. </P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>compile and install samba as usual</P
+></LI
+><LI
+><P
+>enable encrypted passwords in <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> by adding the line <B
+CLASS="COMMAND"
+>encrypt
+ passwords = yes</B
+> in the [global] section</P
+></LI
+><LI
+><P
+>create the initial <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+>
+ password file in the place you specified in the Makefile
+ (--prefix=&lt;dir&gt;). See the notes under the <A
+HREF="#SMBPASSWDFILEFORMAT"
+>The smbpasswd File</A
+>
+ section earlier in the document for details.</P
+></LI
+></OL
+><P
+>Note that you can test things using smbclient.</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/Integrating-with-Windows.html b/docs/htmldocs/Integrating-with-Windows.html
new file mode 100755
index 00000000000..fd2bd7fdaf6
--- /dev/null
+++ b/docs/htmldocs/Integrating-with-Windows.html
@@ -0,0 +1,1072 @@
+<HTML
+><HEAD
+><TITLE
+>Integrating MS Windows networks with Samba</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="INTEGRATE-MS-NETWORKS"
+>Integrating MS Windows networks with Samba</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Agenda</A
+></H1
+><P
+>To identify the key functional mechanisms of MS Windows networking
+to enable the deployment of Samba as a means of extending and/or
+replacing MS Windows NT/2000 technology.</P
+><P
+>We will examine:</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>Name resolution in a pure Unix/Linux TCP/IP
+ environment
+ </P
+></LI
+><LI
+><P
+>Name resolution as used within MS Windows
+ networking
+ </P
+></LI
+><LI
+><P
+>How browsing functions and how to deploy stable
+ and dependable browsing using Samba
+ </P
+></LI
+><LI
+><P
+>MS Windows security options and how to
+ configure Samba for seemless integration
+ </P
+></LI
+><LI
+><P
+>Configuration of Samba as:</P
+><P
+></P
+><OL
+TYPE="a"
+><LI
+><P
+>A stand-alone server</P
+></LI
+><LI
+><P
+>An MS Windows NT 3.x/4.0 security domain member
+ </P
+></LI
+><LI
+><P
+>An alternative to an MS Windows NT 3.x/4.0 Domain Controller
+ </P
+></LI
+></OL
+></LI
+></OL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN25"
+>Name Resolution in a pure Unix/Linux world</A
+></H1
+><P
+>The key configuration files covered in this section are:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+></P
+></LI
+></UL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN41"
+><TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+></A
+></H2
+><P
+>Contains a static list of IP Addresses and names.
+eg:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> 127.0.0.1 localhost localhost.localdomain
+ 192.168.1.1 bigbox.caldera.com bigbox alias4box</PRE
+></P
+><P
+>The purpose of <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> is to provide a
+name resolution mechanism so that uses do not need to remember
+IP addresses.</P
+><P
+>Network packets that are sent over the physical network transport
+layer communicate not via IP addresses but rather using the Media
+Access Control address, or MAC address. IP Addresses are currently
+32 bits in length and are typically presented as four (4) decimal
+numbers that are separated by a dot (or period). eg: 168.192.1.1</P
+><P
+>MAC Addresses use 48 bits (or 6 bytes) and are typically represented
+as two digit hexadecimal numbers separated by colons. eg:
+40:8e:0a:12:34:56</P
+><P
+>Every network interfrace must have an MAC address. Associated with
+a MAC address there may be one or more IP addresses. There is NO
+relationship between an IP address and a MAC address, all such assignments
+are arbitary or discretionary in nature. At the most basic level all
+network communications takes place using MAC addressing. Since MAC
+addresses must be globally unique, and generally remains fixed for
+any particular interface, the assignment of an IP address makes sense
+from a network management perspective. More than one IP address can
+be assigned per MAC address. One address must be the primary IP address,
+this is the address that will be returned in the ARP reply.</P
+><P
+>When a user or a process wants to communicate with another machine
+the protocol implementation ensures that the "machine name" or "host
+name" is resolved to an IP address in a manner that is controlled
+by the TCP/IP configuration control files. The file
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> is one such file.</P
+><P
+>When the IP address of the destination interface has been
+determined a protocol called ARP/RARP is used to identify
+the MAC address of the target interface. ARP stands for Address
+Resolution Protocol, and is a broadcast oriented method that
+uses UDP (User Datagram Protocol) to send a request to all
+interfaces on the local network segment using the all 1's MAC
+address. Network interfaces are programmed to respond to two
+MAC addresses only; their own unique address and the address
+ff:ff:ff:ff:ff:ff. The reply packet from an ARP request will
+contain the MAC address and the primary IP address for each
+interface.</P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> file is foundational to all
+Unix/Linux TCP/IP installations and as a minumum will contain
+the localhost and local network interface IP addresses and the
+primary names by which they are known within the local machine.
+This file helps to prime the pump so that a basic level of name
+resolution can exist before any other method of name resolution
+becomes available.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN57"
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></A
+></H2
+><P
+>This file tells the name resolution libraries:</P
+><P
+></P
+><UL
+><LI
+><P
+>The name of the domain to which the machine
+ belongs
+ </P
+></LI
+><LI
+><P
+>The name(s) of any domains that should be
+ automatically searched when trying to resolve unqualified
+ host names to their IP address
+ </P
+></LI
+><LI
+><P
+>The name or IP address of available Domain
+ Name Servers that may be asked to perform name to address
+ translation lookups
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN68"
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+></A
+></H2
+><P
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+> is the primary means by
+which the setting in /etc/resolv.conf may be affected. It is a
+critical configuration file. This file controls the order by
+which name resolution may procede. The typical structure is:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> order hosts,bind
+ multi on</PRE
+></P
+><P
+>then both addresses should be returned. Please refer to the
+man page for host.conf for further details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN76"
+><TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+></A
+></H2
+><P
+>This file controls the actual name resolution targets. The
+file typically has resolver object specifications as follows:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> # /etc/nsswitch.conf
+ #
+ # Name Service Switch configuration file.
+ #
+
+ passwd: compat
+ # Alternative entries for password authentication are:
+ # passwd: compat files nis ldap winbind
+ shadow: compat
+ group: compat
+
+ hosts: files nis dns
+ # Alternative entries for host name resolution are:
+ # hosts: files dns nis nis+ hesoid db compat ldap wins
+ networks: nis files dns
+
+ ethers: nis files
+ protocols: nis files
+ rpc: nis files
+ services: nis files</PRE
+></P
+><P
+>Of course, each of these mechanisms requires that the appropriate
+facilities and/or services are correctly configured.</P
+><P
+>It should be noted that unless a network request/message must be
+sent, TCP/IP networks are silent. All TCP/IP communications assumes a
+principal of speaking only when necessary.</P
+><P
+>Samba version 2.2.0 will add Linux support for extensions to
+the name service switch infrastructure so that linux clients will
+be able to obtain resolution of MS Windows NetBIOS names to IP
+Addresses. To gain this functionality Samba needs to be compiled
+with appropriate arguments to the make command (ie: <B
+CLASS="COMMAND"
+>make
+nsswitch/libnss_wins.so</B
+>). The resulting library should
+then be installed in the <TT
+CLASS="FILENAME"
+>/lib</TT
+> directory and
+the "wins" parameter needs to be added to the "hosts:" line in
+the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file. At this point it
+will be possible to ping any MS Windows machine by it's NetBIOS
+machine name, so long as that machine is within the workgroup to
+which both the samba machine and the MS Windows machine belong.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN88"
+>Name resolution as used within MS Windows networking</A
+></H1
+><P
+>MS Windows networking is predicated about the name each machine
+is given. This name is known variously (and inconsistently) as
+the "computer name", "machine name", "networking name", "netbios name",
+"SMB name". All terms mean the same thing with the exception of
+"netbios name" which can apply also to the name of the workgroup or the
+domain name. The terms "workgroup" and "domain" are really just a
+simply name with which the machine is associated. All NetBIOS names
+are exactly 16 characters in length. The 16th character is reserved.
+It is used to store a one byte value that indicates service level
+information for the NetBIOS name that is registered. A NetBIOS machine
+name is therefore registered for each service type that is provided by
+the client/server.</P
+><P
+>The following are typical NetBIOS name/service type registrations:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> Unique NetBIOS Names:
+ MACHINENAME&#60;00&#62; = Server Service is running on MACHINENAME
+ MACHINENAME&#60;03&#62; = Generic Machine Name (NetBIOS name)
+ MACHINENAME&#60;20&#62; = LanMan Server service is running on MACHINENAME
+ WORKGROUP&#60;1b&#62; = Domain Master Browser
+
+ Group Names:
+ WORKGROUP&#60;03&#62; = Generic Name registered by all members of WORKGROUP
+ WORKGROUP&#60;1c&#62; = Domain Controllers / Netlogon Servers
+ WORKGROUP&#60;1d&#62; = Local Master Browsers
+ WORKGROUP&#60;1e&#62; = Internet Name Resolvers</PRE
+></P
+><P
+>It should be noted that all NetBIOS machines register their own
+names as per the above. This is in vast contrast to TCP/IP
+installations where traditionally the system administrator will
+determine in the /etc/hosts or in the DNS database what names
+are associated with each IP address.</P
+><P
+>One further point of clarification should be noted, the <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+file and the DNS records do not provide the NetBIOS name type information
+that MS Windows clients depend on to locate the type of service that may
+be needed. An example of this is what happens when an MS Windows client
+wants to locate a domain logon server. It find this service and the IP
+address of a server that provides it by performing a lookup (via a
+NetBIOS broadcast) for enumeration of all machines that have
+registered the name type *&#60;1c&#62;. A logon request is then sent to each
+IP address that is returned in the enumerated list of IP addresses. Which
+ever machine first replies then ends up providing the logon services.</P
+><P
+>The name "workgroup" or "domain" really can be confusing since these
+have the added significance of indicating what is the security
+architecture of the MS Windows network. The term "workgroup" indicates
+that the primary nature of the network environment is that of a
+peer-to-peer design. In a WORKGROUP all machines are responsible for
+their own security, and generally such security is limited to use of
+just a password (known as SHARE MODE security). In most situations
+with peer-to-peer networking the users who control their own machines
+will simply opt to have no security at all. It is possible to have
+USER MODE security in a WORKGROUP environment, thus requiring use
+of a user name and a matching password.</P
+><P
+>MS Windows networking is thus predetermined to use machine names
+for all local and remote machine message passing. The protocol used is
+called Server Message Block (SMB) and this is implemented using
+the NetBIOS protocol (Network Basic Input Output System). NetBIOS can
+be encapsulated using LLC (Logical Link Control) protocol - in which case
+the resulting protocol is called NetBEUI (Network Basic Extended User
+Interface). NetBIOS can also be run over IPX (Internetworking Packet
+Exchange) protocol as used by Novell NetWare, and it can be run
+over TCP/IP protocols - in which case the resulting protocol is called
+NBT or NetBT, the NetBIOS over TCP/IP.</P
+><P
+>MS Windows machines use a complex array of name resolution mechanisms.
+Since we are primarily concerned with TCP/IP this demonstration is
+limited to this area.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN100"
+>The NetBIOS Name Cache</A
+></H2
+><P
+>All MS Windows machines employ an in memory buffer in which is
+stored the NetBIOS names and IP addresses for all external
+machines that that machine has communicated with over the
+past 10-15 minutes. It is more efficient to obtain an IP address
+for a machine from the local cache than it is to go through all the
+configured name resolution mechanisms.</P
+><P
+>If a machine whose name is in the local name cache has been shut
+down before the name had been expired and flushed from the cache, then
+an attempt to exchange a message with that machine will be subject
+to time-out delays. i.e.: Its name is in the cache, so a name resolution
+lookup will succeed, but the machine can not respond. This can be
+frustrating for users - but it is a characteristic of the protocol.</P
+><P
+>The MS Windows utility that allows examination of the NetBIOS
+name cache is called "nbtstat". The Samba equivalent of this
+is called "nmblookup".</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN105"
+>The LMHOSTS file</A
+></H2
+><P
+>This file is usually located in MS Windows NT 4.0 or
+2000 in <TT
+CLASS="FILENAME"
+>C:\WINNT\SYSTEM32\DRIVERS\ETC</TT
+> and contains
+the IP Address and the machine name in matched pairs. The
+<TT
+CLASS="FILENAME"
+>LMHOSTS</TT
+> file performs NetBIOS name
+to IP address mapping oriented.</P
+><P
+>It typically looks like:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> # Copyright (c) 1998 Microsoft Corp.
+ #
+ # This is a sample LMHOSTS file used by the Microsoft Wins Client (NetBIOS
+ # over TCP/IP) stack for Windows98
+ #
+ # This file contains the mappings of IP addresses to NT computernames
+ # (NetBIOS) names. Each entry should be kept on an individual line.
+ # The IP address should be placed in the first column followed by the
+ # corresponding computername. The address and the comptername
+ # should be separated by at least one space or tab. The "#" character
+ # is generally used to denote the start of a comment (see the exceptions
+ # below).
+ #
+ # This file is compatible with Microsoft LAN Manager 2.x TCP/IP lmhosts
+ # files and offers the following extensions:
+ #
+ # #PRE
+ # #DOM:&lt;domain&gt;
+ # #INCLUDE &lt;filename&gt;
+ # #BEGIN_ALTERNATE
+ # #END_ALTERNATE
+ # \0xnn (non-printing character support)
+ #
+ # Following any entry in the file with the characters "#PRE" will cause
+ # the entry to be preloaded into the name cache. By default, entries are
+ # not preloaded, but are parsed only after dynamic name resolution fails.
+ #
+ # Following an entry with the "#DOM:&lt;domain&gt;" tag will associate the
+ # entry with the domain specified by &lt;domain&gt;. This affects how the
+ # browser and logon services behave in TCP/IP environments. To preload
+ # the host name associated with #DOM entry, it is necessary to also add a
+ # #PRE to the line. The &lt;domain&gt; is always preloaded although it will not
+ # be shown when the name cache is viewed.
+ #
+ # Specifying "#INCLUDE &lt;filename&gt;" will force the RFC NetBIOS (NBT)
+ # software to seek the specified &lt;filename&gt; and parse it as if it were
+ # local. &lt;filename&gt; is generally a UNC-based name, allowing a
+ # centralized lmhosts file to be maintained on a server.
+ # It is ALWAYS necessary to provide a mapping for the IP address of the
+ # server prior to the #INCLUDE. This mapping must use the #PRE directive.
+ # In addtion the share "public" in the example below must be in the
+ # LanManServer list of "NullSessionShares" in order for client machines to
+ # be able to read the lmhosts file successfully. This key is under
+ # \machine\system\currentcontrolset\services\lanmanserver\parameters\nullsessionshares
+ # in the registry. Simply add "public" to the list found there.
+ #
+ # The #BEGIN_ and #END_ALTERNATE keywords allow multiple #INCLUDE
+ # statements to be grouped together. Any single successful include
+ # will cause the group to succeed.
+ #
+ # Finally, non-printing characters can be embedded in mappings by
+ # first surrounding the NetBIOS name in quotations, then using the
+ # \0xnn notation to specify a hex value for a non-printing character.
+ #
+ # The following example illustrates all of these extensions:
+ #
+ # 102.54.94.97 rhino #PRE #DOM:networking #net group's DC
+ # 102.54.94.102 "appname \0x14" #special app server
+ # 102.54.94.123 popular #PRE #source server
+ # 102.54.94.117 localsrv #PRE #needed for the include
+ #
+ # #BEGIN_ALTERNATE
+ # #INCLUDE \\localsrv\public\lmhosts
+ # #INCLUDE \\rhino\public\lmhosts
+ # #END_ALTERNATE
+ #
+ # In the above example, the "appname" server contains a special
+ # character in its name, the "popular" and "localsrv" server names are
+ # preloaded, and the "rhino" server name is specified so it can be used
+ # to later #INCLUDE a centrally maintained lmhosts file if the "localsrv"
+ # system is unavailable.
+ #
+ # Note that the whole file is parsed including comments on each lookup,
+ # so keeping the number of comments to a minimum will improve performance.
+ # Therefore it is not advisable to simply add lmhosts file entries onto the
+ # end of this file.</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN113"
+>HOSTS file</A
+></H2
+><P
+>This file is usually located in MS Windows NT 4.0 or 2000 in
+<TT
+CLASS="FILENAME"
+>C:\WINNT\SYSTEM32\DRIVERS\ETC</TT
+> and contains
+the IP Address and the IP hostname in matched pairs. It can be
+used by the name resolution infrastructure in MS Windows, depending
+on how the TCP/IP environment is configured. This file is in
+every way the equivalent of the Unix/Linux <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> file.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN118"
+>DNS Lookup</A
+></H2
+><P
+>This capability is configured in the TCP/IP setup area in the network
+configuration facility. If enabled an elaborate name resolution sequence
+is followed the precise nature of which isdependant on what the NetBIOS
+Node Type parameter is configured to. A Node Type of 0 means use
+NetBIOS broadcast (over UDP broadcast) is first used if the name
+that is the subject of a name lookup is not found in the NetBIOS name
+cache. If that fails then DNS, HOSTS and LMHOSTS are checked. If set to
+Node Type 8, then a NetBIOS Unicast (over UDP Unicast) is sent to the
+WINS Server to obtain a lookup before DNS, HOSTS, LMHOSTS, or broadcast
+lookup is used.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN121"
+>WINS Lookup</A
+></H2
+><P
+>A WINS (Windows Internet Name Server) service is the equivaent of the
+rfc1001/1002 specified NBNS (NetBIOS Name Server). A WINS server stores
+the names and IP addresses that are registered by a Windows client
+if the TCP/IP setup has been given at least one WINS Server IP Address.</P
+><P
+>To configure Samba to be a WINS server the following parameter needs
+to be added to the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> wins support = Yes</PRE
+></P
+><P
+>To configure Samba to use a WINS server the following parameters are
+needed in the smb.conf file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> wins support = No
+ wins server = xxx.xxx.xxx.xxx</PRE
+></P
+><P
+>where <TT
+CLASS="REPLACEABLE"
+><I
+>xxx.xxx.xxx.xxx</I
+></TT
+> is the IP address
+of the WINS server.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN133"
+>How browsing functions and how to deploy stable and
+dependable browsing using Samba</A
+></H1
+><P
+>As stated above, MS Windows machines register their NetBIOS names
+(i.e.: the machine name for each service type in operation) on start
+up. Also, as stated above, the exact method by which this name registration
+takes place is determined by whether or not the MS Windows client/server
+has been given a WINS server address, whether or not LMHOSTS lookup
+is enabled, or if DNS for NetBIOS name resolution is enabled, etc.</P
+><P
+>In the case where there is no WINS server all name registrations as
+well as name lookups are done by UDP broadcast. This isolates name
+resolution to the local subnet, unless LMHOSTS is used to list all
+names and IP addresses. In such situations Samba provides a means by
+which the samba server name may be forcibly injected into the browse
+list of a remote MS Windows network (using the "remote announce" parameter).</P
+><P
+>Where a WINS server is used, the MS Windows client will use UDP
+unicast to register with the WINS server. Such packets can be routed
+and thus WINS allows name resolution to function across routed networks.</P
+><P
+>During the startup process an election will take place to create a
+local master browser if one does not already exist. On each NetBIOS network
+one machine will be elected to function as the domain master browser. This
+domain browsing has nothing to do with MS security domain control.
+Instead, the domain master browser serves the role of contacting each local
+master browser (found by asking WINS or from LMHOSTS) and exchanging browse
+list contents. This way every master browser will eventually obtain a complete
+list of all machines that are on the network. Every 11-15 minutes an election
+is held to determine which machine will be the master browser. By the nature of
+the election criteria used, the machine with the highest uptime, or the
+most senior protocol version, or other criteria, will win the election
+as domain master browser.</P
+><P
+>Clients wishing to browse the network make use of this list, but also depend
+on the availability of correct name resolution to the respective IP
+address/addresses. </P
+><P
+>Any configuration that breaks name resolution and/or browsing intrinsics
+will annoy users because they will have to put up with protracted
+inability to use the network services.</P
+><P
+>Samba supports a feature that allows forced synchonisation
+of browse lists across routed networks using the "remote
+browse sync" parameter in the smb.conf file. This causes Samba
+to contact the local master browser on a remote network and
+to request browse list synchronisation. This effectively bridges
+two networks that are separated by routers. The two remote
+networks may use either broadcast based name resolution or WINS
+based name resolution, but it should be noted that the "remote
+browse sync" parameter provides browse list synchronisation - and
+that is distinct from name to address resolution, in other
+words, for cross subnet browsing to function correctly it is
+essential that a name to address resolution mechanism be provided.
+This mechanism could be via DNS, <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>,
+and so on.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN143"
+>MS Windows security options and how to configure
+Samba for seemless integration</A
+></H1
+><P
+>MS Windows clients may use encrypted passwords as part of a
+challenege/response authentication model (a.k.a. NTLMv1) or
+alone, or clear text strings for simple password based
+authentication. It should be realized that with the SMB
+protocol the password is passed over the network either
+in plain text or encrypted, but not both in the same
+authentication requets.</P
+><P
+>When encrypted passwords are used a password that has been
+entered by the user is encrypted in two ways:</P
+><P
+></P
+><UL
+><LI
+><P
+>An MD4 hash of the UNICODE of the password
+ string. This is known as the NT hash.
+ </P
+></LI
+><LI
+><P
+>The password is converted to upper case,
+ and then padded or trucated to 14 bytes. This string is
+ then appended with 5 bytes of NULL characters and split to
+ form two 56 bit DES keys to encrypt a "magic" 8 byte value.
+ The resulting 16 bytes for the LanMan hash.
+ </P
+></LI
+></UL
+><P
+>You should refer to the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>Password Encryption</A
+> chapter in this HOWTO collection
+for more details on the inner workings</P
+><P
+>MS Windows 95 pre-service pack 1, MS Windows NT versions 3.x
+and version 4.0 pre-service pack 3 will use either mode of
+password authentication. All versions of MS Windows that follow
+these versions no longer support plain text passwords by default.</P
+><P
+>MS Windows clients have a habit of dropping network mappings that
+have been idle for 10 minutes or longer. When the user attempts to
+use the mapped drive connection that has been dropped, the client
+re-establishes the connection using
+a cached copy of the password.</P
+><P
+>When Microsoft changed the default password mode, they dropped support for
+caching of the plain text password. This means that when the registry
+parameter is changed to re-enable use of plain text passwords it appears to
+work, but when a dropped mapping attempts to revalidate it will fail if
+the remote authentication server does not support encrypted passwords.
+This means that it is definitely not a good idea to re-enable plain text
+password support in such clients.</P
+><P
+>The following parameters can be used to work around the
+issue of Windows 9x client upper casing usernames and
+password before transmitting them to the SMB server
+when using clear text authentication.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> <A
+HREF="smb.conf.5.html#PASSWORDLEVEL"
+TARGET="_top"
+>passsword level</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>integer</I
+></TT
+>
+ <A
+HREF="smb.conf.5.html#USERNAMELEVEL"
+TARGET="_top"
+>username level</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>integer</I
+></TT
+></PRE
+></P
+><P
+>By default Samba will lower case the username before attempting
+to lookup the user in the database of local system accounts.
+Because UNIX usernames conventionally only contain lower case
+character, the <TT
+CLASS="PARAMETER"
+><I
+>username level</I
+></TT
+> parameter
+is rarely even needed.</P
+><P
+>However, password on UNIX systems often make use of mixed case
+characters. This means that in order for a user on a Windows 9x
+client to connect to a Samba server using clear text authentication,
+the <TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+> must be set to the maximum
+number of upper case letter which <I
+CLASS="EMPHASIS"
+>could</I
+> appear
+is a password. Note that is the server OS uses the traditional
+DES version of crypt(), then a <TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+>
+of 8 will result in case insensitive passwords as seen from Windows
+users. This will also result in longer login times as Samba
+hash to compute the permutations of the password string and
+try them one by one until a match is located (or all combinations fail).</P
+><P
+>The best option to adopt is to enable support for encrypted passwords
+where ever Samba is used. There are three configuration possibilities
+for support of encrypted passwords:</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN171"
+>Use MS Windows NT as an authentication server</A
+></H2
+><P
+>This method involves the additions of the following parameters
+in the smb.conf file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> encrypt passwords = Yes
+ security = server
+ password server = "NetBIOS_name_of_PDC"</PRE
+></P
+><P
+>There are two ways of identifying whether or not a username and
+password pair was valid or not. One uses the reply information provided
+as part of the authentication messaging process, the other uses
+just and error code.</P
+><P
+>The down-side of this mode of configuration is the fact that
+for security reasons Samba will send the password server a bogus
+username and a bogus password and if the remote server fails to
+reject the username and password pair then an alternative mode
+of identification of validation is used. Where a site uses password
+lock out after a certain number of failed authentication attempts
+this will result in user lockouts.</P
+><P
+>Use of this mode of authentication does require there to be
+a standard Unix account for the user, this account can be blocked
+to prevent logons by other than MS Windows clients.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN179"
+>Make Samba a member of an MS Windows NT security domain</A
+></H2
+><P
+>This method involves additon of the following paramters in the smb.conf file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> encrypt passwords = Yes
+ security = domain
+ workgroup = "name of NT domain"
+ password server = *</PRE
+></P
+><P
+>The use of the "*" argument to "password server" will cause samba
+to locate the domain controller in a way analogous to the way
+this is done within MS Windows NT.</P
+><P
+>In order for this method to work the Samba server needs to join the
+MS Windows NT security domain. This is done as follows:</P
+><P
+></P
+><UL
+><LI
+><P
+>On the MS Windows NT domain controller using
+ the Server Manager add a machine account for the Samba server.
+ </P
+></LI
+><LI
+><P
+>Next, on the Linux system execute:
+ <B
+CLASS="COMMAND"
+>smbpasswd -r PDC_NAME -j DOMAIN_NAME</B
+>
+ </P
+></LI
+></UL
+><P
+>Use of this mode of authentication does require there to be
+a standard Unix account for the user in order to assign
+a uid once the account has been authenticated by the remote
+Windows DC. This account can be blocked to prevent logons by
+other than MS Windows clients by things such as setting an invalid
+shell in the <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry.</P
+><P
+>An alternative to assigning UIDs to Windows users on a
+Samba member server is presented in the <A
+HREF="winbind.html"
+TARGET="_top"
+>Winbind Overview</A
+> chapter in
+this HOWTO collection.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN196"
+>Configure Samba as an authentication server</A
+></H2
+><P
+>This mode of authentication demands that there be on the
+Unix/Linux system both a Unix style account as well as an
+smbpasswd entry for the user. The Unix system account can be
+locked if required as only the encrypted password will be
+used for SMB client authentication.</P
+><P
+>This method involves addition of the following parameters to
+the smb.conf file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>## please refer to the Samba PDC HOWTO chapter later in
+## this collection for more details
+[global]
+ encrypt passwords = Yes
+ security = user
+ domain logons = Yes
+ ; an OS level of 33 or more is recommended
+ os level = 33
+
+[NETLOGON]
+ path = /somewhare/in/file/system
+ read only = yes</PRE
+></P
+><P
+>in order for this method to work a Unix system account needs
+to be created for each user, as well as for each MS Windows NT/2000
+machine. The following structure is required.</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN203"
+>Users</A
+></H3
+><P
+>A user account that may provide a home directory should be
+created. The following Linux system commands are typical of
+the procedure for creating an account.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> # useradd -s /bin/bash -d /home/"userid" -m "userid"
+ # passwd "userid"
+ Enter Password: &lt;pw&gt;
+
+ # smbpasswd -a "userid"
+ Enter Password: &lt;pw&gt;</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN208"
+>MS Windows NT Machine Accounts</A
+></H3
+><P
+>These are required only when Samba is used as a domain
+controller. Refer to the Samba-PDC-HOWTO for more details.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> # useradd -s /bin/false -d /dev/null "machine_name"\$
+ # passwd -l "machine_name"\$
+ # smbpasswd -a -m "machine_name"</PRE
+></P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN213"
+>Conclusions</A
+></H1
+><P
+>Samba provides a flexible means to operate as...</P
+><P
+></P
+><UL
+><LI
+><P
+>A Stand-alone server - No special action is needed
+ other than to create user accounts. Stand-alone servers do NOT
+ provide network logon services, meaning that machines that use this
+ server do NOT perform a domain logon but instead make use only of
+ the MS Windows logon which is local to the MS Windows
+ workstation/server.
+ </P
+></LI
+><LI
+><P
+>An MS Windows NT 3.x/4.0 security domain member.
+ </P
+></LI
+><LI
+><P
+>An alternative to an MS Windows NT 3.x/4.0
+ Domain Controller.
+ </P
+></LI
+></UL
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/NT_Security.html b/docs/htmldocs/NT_Security.html
new file mode 100755
index 00000000000..ab8797563e3
--- /dev/null
+++ b/docs/htmldocs/NT_Security.html
@@ -0,0 +1,783 @@
+<HTML
+><HEAD
+><TITLE
+>UNIX Permission Bits and Windows NT Access Control Lists</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="UNIX-PERMISSIONS"
+>UNIX Permission Bits and Windows NT Access Control Lists</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Viewing and changing UNIX permissions using the NT
+ security dialogs</A
+></H1
+><P
+>New in the Samba 2.0.4 release is the ability for Windows
+ NT clients to use their native security settings dialog box to
+ view and modify the underlying UNIX permissions.</P
+><P
+>Note that this ability is careful not to compromise
+ the security of the UNIX host Samba is running on, and
+ still obeys all the file permission rules that a Samba
+ administrator can set.</P
+><P
+>In Samba 2.0.4 and above the default value of the
+ parameter <A
+HREF="smb.conf.5.html#NTACLSUPPORT"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> nt acl support</I
+></TT
+></A
+> has been changed from
+ <TT
+CLASS="CONSTANT"
+>false</TT
+> to <TT
+CLASS="CONSTANT"
+>true</TT
+>, so
+ manipulation of permissions is turned on by default.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN12"
+>How to view file security on a Samba share</A
+></H1
+><P
+>From an NT 4.0 client, single-click with the right
+ mouse button on any file or directory in a Samba mounted
+ drive letter or UNC path. When the menu pops-up, click
+ on the <I
+CLASS="EMPHASIS"
+>Properties</I
+> entry at the bottom of
+ the menu. This brings up the normal file properties dialog
+ box, but with Samba 2.0.4 this will have a new tab along the top
+ marked <I
+CLASS="EMPHASIS"
+>Security</I
+>. Click on this tab and you
+ will see three buttons, <I
+CLASS="EMPHASIS"
+>Permissions</I
+>,
+ <I
+CLASS="EMPHASIS"
+>Auditing</I
+>, and <I
+CLASS="EMPHASIS"
+>Ownership</I
+>.
+ The <I
+CLASS="EMPHASIS"
+>Auditing</I
+> button will cause either
+ an error message <SPAN
+CLASS="ERRORNAME"
+>A requested privilege is not held
+ by the client</SPAN
+> to appear if the user is not the
+ NT Administrator, or a dialog which is intended to allow an
+ Administrator to add auditing requirements to a file if the
+ user is logged on as the NT Administrator. This dialog is
+ non-functional with a Samba share at this time, as the only
+ useful button, the <B
+CLASS="COMMAND"
+>Add</B
+> button will not currently
+ allow a list of users to be seen.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN23"
+>Viewing file ownership</A
+></H1
+><P
+>Clicking on the <B
+CLASS="COMMAND"
+>"Ownership"</B
+> button
+ brings up a dialog box telling you who owns the given file. The
+ owner name will be of the form :</P
+><P
+><B
+CLASS="COMMAND"
+>"SERVER\user (Long name)"</B
+></P
+><P
+>Where <TT
+CLASS="REPLACEABLE"
+><I
+>SERVER</I
+></TT
+> is the NetBIOS name of
+ the Samba server, <TT
+CLASS="REPLACEABLE"
+><I
+>user</I
+></TT
+> is the user name of
+ the UNIX user who owns the file, and <TT
+CLASS="REPLACEABLE"
+><I
+>(Long name)</I
+></TT
+>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database). Click on the <B
+CLASS="COMMAND"
+>Close
+ </B
+> button to remove this dialog.</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then the file owner will
+ be shown as the NT user <B
+CLASS="COMMAND"
+>"Everyone"</B
+>.</P
+><P
+>The <B
+CLASS="COMMAND"
+>Take Ownership</B
+> button will not allow
+ you to change the ownership of this file to yourself (clicking on
+ it will display a dialog box complaining that the user you are
+ currently logged onto the NT client cannot be found). The reason
+ for this is that changing the ownership of a file is a privileged
+ operation in UNIX, available only to the <I
+CLASS="EMPHASIS"
+>root</I
+>
+ user. As clicking on this button causes NT to attempt to change
+ the ownership of a file to the current user logged into the NT
+ client this will not work with Samba at this time.</P
+><P
+>There is an NT chown command that will work with Samba
+ and allow a user with Administrator privilege connected
+ to a Samba 2.0.4 server as root to change the ownership of
+ files on both a local NTFS filesystem or remote mounted NTFS
+ or Samba drive. This is available as part of the <I
+CLASS="EMPHASIS"
+>Seclib
+ </I
+> NT security library written by Jeremy Allison of
+ the Samba Team, available from the main Samba ftp site.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN43"
+>Viewing file or directory permissions</A
+></H1
+><P
+>The third button is the <B
+CLASS="COMMAND"
+>"Permissions"</B
+>
+ button. Clicking on this brings up a dialog box that shows both
+ the permissions and the UNIX owner of the file or directory.
+ The owner is displayed in the form :</P
+><P
+><B
+CLASS="COMMAND"
+>"SERVER\user (Long name)"</B
+></P
+><P
+>Where <TT
+CLASS="REPLACEABLE"
+><I
+>SERVER</I
+></TT
+> is the NetBIOS name of
+ the Samba server, <TT
+CLASS="REPLACEABLE"
+><I
+>user</I
+></TT
+> is the user name of
+ the UNIX user who owns the file, and <TT
+CLASS="REPLACEABLE"
+><I
+>(Long name)</I
+></TT
+>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database).</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then the file owner will
+ be shown as the NT user <B
+CLASS="COMMAND"
+>"Everyone"</B
+> and the
+ permissions will be shown as NT "Full Control".</P
+><P
+>The permissions field is displayed differently for files
+ and directories, so I'll describe the way file permissions
+ are displayed first.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN58"
+>File Permissions</A
+></H2
+><P
+>The standard UNIX user/group/world triple and
+ the corresponding "read", "write", "execute" permissions
+ triples are mapped by Samba into a three element NT ACL
+ with the 'r', 'w', and 'x' bits mapped into the corresponding
+ NT permissions. The UNIX world permissions are mapped into
+ the global NT group <B
+CLASS="COMMAND"
+>Everyone</B
+>, followed
+ by the list of permissions allowed for UNIX world. The UNIX
+ owner and group permissions are displayed as an NT
+ <B
+CLASS="COMMAND"
+>user</B
+> icon and an NT <B
+CLASS="COMMAND"
+>local
+ group</B
+> icon respectively followed by the list
+ of permissions allowed for the UNIX user and group.</P
+><P
+>As many UNIX permission sets don't map into common
+ NT names such as <B
+CLASS="COMMAND"
+>"read"</B
+>, <B
+CLASS="COMMAND"
+> "change"</B
+> or <B
+CLASS="COMMAND"
+>"full control"</B
+> then
+ usually the permissions will be prefixed by the words <B
+CLASS="COMMAND"
+> "Special Access"</B
+> in the NT display list.</P
+><P
+>But what happens if the file has no permissions allowed
+ for a particular UNIX user group or world component ? In order
+ to allow "no permissions" to be seen and modified then Samba
+ overloads the NT <B
+CLASS="COMMAND"
+>"Take Ownership"</B
+> ACL attribute
+ (which has no meaning in UNIX) and reports a component with
+ no permissions as having the NT <B
+CLASS="COMMAND"
+>"O"</B
+> bit set.
+ This was chosen of course to make it look like a zero, meaning
+ zero permissions. More details on the decision behind this will
+ be given below.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN72"
+>Directory Permissions</A
+></H2
+><P
+>Directories on an NT NTFS file system have two
+ different sets of permissions. The first set of permissions
+ is the ACL set on the directory itself, this is usually displayed
+ in the first set of parentheses in the normal <B
+CLASS="COMMAND"
+>"RW"</B
+>
+ NT style. This first set of permissions is created by Samba in
+ exactly the same way as normal file permissions are, described
+ above, and is displayed in the same way.</P
+><P
+>The second set of directory permissions has no real meaning
+ in the UNIX permissions world and represents the <B
+CLASS="COMMAND"
+> "inherited"</B
+> permissions that any file created within
+ this directory would inherit.</P
+><P
+>Samba synthesises these inherited permissions for NT by
+ returning as an NT ACL the UNIX permission mode that a new file
+ created by Samba on this share would receive.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN79"
+>Modifying file or directory permissions</A
+></H1
+><P
+>Modifying file and directory permissions is as simple
+ as changing the displayed permissions in the dialog box, and
+ clicking the <B
+CLASS="COMMAND"
+>OK</B
+> button. However, there are
+ limitations that a user needs to be aware of, and also interactions
+ with the standard Samba permission masks and mapping of DOS
+ attributes that need to also be taken into account.</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then any attempt to set
+ security permissions will fail with an <B
+CLASS="COMMAND"
+>"Access Denied"
+ </B
+> message.</P
+><P
+>The first thing to note is that the <B
+CLASS="COMMAND"
+>"Add"</B
+>
+ button will not return a list of users in Samba 2.0.4 (it will give
+ an error message of <B
+CLASS="COMMAND"
+>"The remote procedure call failed
+ and did not execute"</B
+>). This means that you can only
+ manipulate the current user/group/world permissions listed in
+ the dialog box. This actually works quite well as these are the
+ only permissions that UNIX actually has.</P
+><P
+>If a permission triple (either user, group, or world)
+ is removed from the list of permissions in the NT dialog box,
+ then when the <B
+CLASS="COMMAND"
+>"OK"</B
+> button is pressed it will
+ be applied as "no permissions" on the UNIX side. If you then
+ view the permissions again the "no permissions" entry will appear
+ as the NT <B
+CLASS="COMMAND"
+>"O"</B
+> flag, as described above. This
+ allows you to add permissions back to a file or directory once
+ you have removed them from a triple component.</P
+><P
+>As UNIX supports only the "r", "w" and "x" bits of
+ an NT ACL then if other NT security attributes such as "Delete
+ access" are selected then they will be ignored when applied on
+ the Samba server.</P
+><P
+>When setting permissions on a directory the second
+ set of permissions (in the second set of parentheses) is
+ by default applied to all files within that directory. If this
+ is not what you want you must uncheck the <B
+CLASS="COMMAND"
+>"Replace
+ permissions on existing files"</B
+> checkbox in the NT
+ dialog before clicking <B
+CLASS="COMMAND"
+>"OK"</B
+>.</P
+><P
+>If you wish to remove all permissions from a
+ user/group/world component then you may either highlight the
+ component and click the <B
+CLASS="COMMAND"
+>"Remove"</B
+> button,
+ or set the component to only have the special <B
+CLASS="COMMAND"
+>"Take
+ Ownership"</B
+> permission (displayed as <B
+CLASS="COMMAND"
+>"O"
+ </B
+>) highlighted.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN101"
+>Interaction with the standard Samba create mask
+ parameters</A
+></H1
+><P
+>Note that with Samba 2.0.5 there are four new parameters
+ to control this interaction. These are :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory security mode</I
+></TT
+></P
+><P
+>Once a user clicks <B
+CLASS="COMMAND"
+>"OK"</B
+> to apply the
+ permissions Samba maps the given permissions into a user/group/world
+ r/w/x triple set, and then will check the changed permissions for a
+ file against the bits set in the <A
+HREF="smb.conf.5.html#SECURITYMASK"
+TARGET="_top"
+>
+ <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+> parameter. Any bits that
+ were changed that are not set to '1' in this parameter are left alone
+ in the file permissions.</P
+><P
+>Essentially, zero bits in the <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+>
+ mask may be treated as a set of bits the user is <I
+CLASS="EMPHASIS"
+>not</I
+>
+ allowed to change, and one bits are those the user is allowed to change.
+ </P
+><P
+>If not set explicitly this parameter is set to the same value as
+ the <A
+HREF="smb.conf.5.html#CREATEMASK"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>create mask
+ </I
+></TT
+></A
+> parameter to provide compatibility with Samba 2.0.4
+ where this permission change facility was introduced. To allow a user to
+ modify all the user/group/world permissions on a file, set this parameter
+ to 0777.</P
+><P
+>Next Samba checks the changed permissions for a file against
+ the bits set in the <A
+HREF="smb.conf.5.html#FORCESECURITYMODE"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></A
+> parameter. Any bits
+ that were changed that correspond to bits set to '1' in this parameter
+ are forced to be set.</P
+><P
+>Essentially, bits set in the <TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+> parameter may be treated as a set of bits that, when
+ modifying security on a file, the user has always set to be 'on'.</P
+><P
+>If not set explicitly this parameter is set to the same value
+ as the <A
+HREF="smb.conf.5.html#FORCECREATEMODE"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ create mode</I
+></TT
+></A
+> parameter to provide compatibility
+ with Samba 2.0.4 where the permission change facility was introduced.
+ To allow a user to modify all the user/group/world permissions on a file
+ with no restrictions set this parameter to 000.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>force
+ security mode</I
+></TT
+> parameters are applied to the change
+ request in that order.</P
+><P
+>For a directory Samba will perform the same operations as
+ described above for a file except using the parameter <TT
+CLASS="PARAMETER"
+><I
+> directory security mask</I
+></TT
+> instead of <TT
+CLASS="PARAMETER"
+><I
+>security
+ mask</I
+></TT
+>, and <TT
+CLASS="PARAMETER"
+><I
+>force directory security mode
+ </I
+></TT
+> parameter instead of <TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+>.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+> parameter
+ by default is set to the same value as the <TT
+CLASS="PARAMETER"
+><I
+>directory mask
+ </I
+></TT
+> parameter and the <TT
+CLASS="PARAMETER"
+><I
+>force directory security
+ mode</I
+></TT
+> parameter by default is set to the same value as
+ the <TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+> parameter to provide
+ compatibility with Samba 2.0.4 where the permission change facility
+ was introduced.</P
+><P
+>In this way Samba enforces the permission restrictions that
+ an administrator can set on a Samba share, whilst still allowing users
+ to modify the permission bits within that restriction.</P
+><P
+>If you want to set up a share that allows users full control
+ in modifying the permission bits on their files and directories and
+ doesn't force any particular bits to be set 'on', then set the following
+ parameters in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+></A
+> file in that share specific section :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>security mask = 0777</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode = 0</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask = 0777</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory security mode = 0</I
+></TT
+></P
+><P
+>As described, in Samba 2.0.4 the parameters :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+></P
+><P
+>were used instead of the parameters discussed here.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN165"
+>Interaction with the standard Samba file attribute
+ mapping</A
+></H1
+><P
+>Samba maps some of the DOS attribute bits (such as "read
+ only") into the UNIX permissions of a file. This means there can
+ be a conflict between the permission bits set via the security
+ dialog and the permission bits set by the file attribute mapping.
+ </P
+><P
+>One way this can show up is if a file has no UNIX read access
+ for the owner it will show up as "read only" in the standard
+ file attributes tabbed dialog. Unfortunately this dialog is
+ the same one that contains the security info in another tab.</P
+><P
+>What this can mean is that if the owner changes the permissions
+ to allow themselves read access using the security dialog, clicks
+ <B
+CLASS="COMMAND"
+>"OK"</B
+> to get back to the standard attributes tab
+ dialog, and then clicks <B
+CLASS="COMMAND"
+>"OK"</B
+> on that dialog, then
+ NT will set the file permissions back to read-only (as that is what
+ the attributes still say in the dialog). This means that after setting
+ permissions and clicking <B
+CLASS="COMMAND"
+>"OK"</B
+> to get back to the
+ attributes dialog you should always hit <B
+CLASS="COMMAND"
+>"Cancel"</B
+>
+ rather than <B
+CLASS="COMMAND"
+>"OK"</B
+> to ensure that your changes
+ are not overridden.</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/OS2-Client-HOWTO.html b/docs/htmldocs/OS2-Client-HOWTO.html
new file mode 100755
index 00000000000..90f62306e82
--- /dev/null
+++ b/docs/htmldocs/OS2-Client-HOWTO.html
@@ -0,0 +1,210 @@
+<HTML
+><HEAD
+><TITLE
+>OS2 Client HOWTO</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="OS2"
+>OS2 Client HOWTO</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>FAQs</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN5"
+>How can I configure OS/2 Warp Connect or
+ OS/2 Warp 4 as a client for Samba?</A
+></H2
+><P
+>A more complete answer to this question can be
+ found on <A
+HREF="http://carol.wins.uva.nl/~leeuw/samba/warp.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/samba/warp.html</A
+>.</P
+><P
+>Basically, you need three components:</P
+><P
+></P
+><UL
+><LI
+><P
+>The File and Print Client ('IBM Peer')
+ </P
+></LI
+><LI
+><P
+>TCP/IP ('Internet support')
+ </P
+></LI
+><LI
+><P
+>The "NetBIOS over TCP/IP" driver ('TCPBEUI')
+ </P
+></LI
+></UL
+><P
+>Installing the first two together with the base operating
+ system on a blank system is explained in the Warp manual. If Warp
+ has already been installed, but you now want to install the
+ networking support, use the "Selective Install for Networking"
+ object in the "System Setup" folder.</P
+><P
+>Adding the "NetBIOS over TCP/IP" driver is not described
+ in the manual and just barely in the online documentation. Start
+ MPTS.EXE, click on OK, click on "Configure LAPS" and click
+ on "IBM OS/2 NETBIOS OVER TCP/IP" in 'Protocols'. This line
+ is then moved to 'Current Configuration'. Select that line,
+ click on "Change number" and increase it from 0 to 1. Save this
+ configuration.</P
+><P
+>If the Samba server(s) is not on your local subnet, you
+ can optionally add IP names and addresses of these servers
+ to the "Names List", or specify a WINS server ('NetBIOS
+ Nameserver' in IBM and RFC terminology). For Warp Connect you
+ may need to download an update for 'IBM Peer' to bring it on
+ the same level as Warp 4. See the webpage mentioned above.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN20"
+>How can I configure OS/2 Warp 3 (not Connect),
+ OS/2 1.2, 1.3 or 2.x for Samba?</A
+></H2
+><P
+>You can use the free Microsoft LAN Manager 2.2c Client
+ for OS/2 from
+ <A
+HREF="ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/"
+TARGET="_top"
+> ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/</A
+>.
+ See <A
+HREF="http://carol.wins.uva.nl/~leeuw/lanman.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/lanman.html</A
+> for
+ more information on how to install and use this client. In
+ a nutshell, edit the file \OS2VER in the root directory of
+ the OS/2 boot partition and add the lines:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> 20=setup.exe
+ 20=netwksta.sys
+ 20=netvdd.sys
+ </PRE
+></P
+><P
+>before you install the client. Also, don't use the
+ included NE2000 driver because it is buggy. Try the NE2000
+ or NS2000 driver from
+ <A
+HREF="ftp://ftp.cdrom.com/pub/os2/network/ndis/"
+TARGET="_top"
+> ftp://ftp.cdrom.com/pub/os2/network/ndis/</A
+> instead.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN29"
+>Are there any other issues when OS/2 (any version)
+ is used as a client?</A
+></H2
+><P
+>When you do a NET VIEW or use the "File and Print
+ Client Resource Browser", no Samba servers show up. This can
+ be fixed by a patch from <A
+HREF="http://carol.wins.uva.nl/~leeuw/samba/fix.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/samba/fix.html</A
+>.
+ The patch will be included in a later version of Samba. It also
+ fixes a couple of other problems, such as preserving long
+ filenames when objects are dragged from the Workplace Shell
+ to the Samba server. </P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN33"
+>How do I get printer driver download working
+ for OS/2 clients?</A
+></H2
+><P
+>First, create a share called [PRINTDRV] that is
+ world-readable. Copy your OS/2 driver files there. Note
+ that the .EA_ files must still be separate, so you will need
+ to use the original install files, and not copy an installed
+ driver from an OS/2 system.</P
+><P
+>Install the NT driver first for that printer. Then,
+ add to your smb.conf a parameter, "os2 driver map =
+ <TT
+CLASS="REPLACEABLE"
+><I
+>filename</I
+></TT
+>". Then, in the file
+ specified by <TT
+CLASS="REPLACEABLE"
+><I
+>filename</I
+></TT
+>, map the
+ name of the NT driver name to the OS/2 driver name as
+ follows:</P
+><P
+>&lt;nt driver name&gt; = &lt;os2 driver
+ name&gt;.&lt;device name&gt;, e.g.:
+ HP LaserJet 5L = LASERJET.HP LaserJet 5L</P
+><P
+>You can have multiple drivers mapped in this file.</P
+><P
+>If you only specify the OS/2 driver name, and not the
+ device name, the first attempt to download the driver will
+ actually download the files, but the OS/2 client will tell
+ you the driver is not available. On the second attempt, it
+ will work. This is fixed simply by adding the device name
+ to the mapping, after which it will work on the first attempt.
+ </P
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/PAM-Authentication-And-Samba.html b/docs/htmldocs/PAM-Authentication-And-Samba.html
new file mode 100755
index 00000000000..6dc815b87bf
--- /dev/null
+++ b/docs/htmldocs/PAM-Authentication-And-Samba.html
@@ -0,0 +1,318 @@
+<HTML
+><HEAD
+><TITLE
+>Configuring PAM for distributed but centrally
+managed authentication</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="PAM"
+>Configuring PAM for distributed but centrally
+managed authentication</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Samba and PAM</A
+></H1
+><P
+>A number of Unix systems (eg: Sun Solaris), as well as the
+xxxxBSD family and Linux, now utilize the Pluggable Authentication
+Modules (PAM) facility to provide all authentication,
+authorization and resource control services. Prior to the
+introduction of PAM, a decision to use an alternative to
+the system password database (<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>)
+would require the provision of alternatives for all programs that provide
+security services. Such a choice would involve provision of
+alternatives to such programs as: <B
+CLASS="COMMAND"
+>login</B
+>,
+<B
+CLASS="COMMAND"
+>passwd</B
+>, <B
+CLASS="COMMAND"
+>chown</B
+>, etc.</P
+><P
+>PAM provides a mechanism that disconnects these security programs
+from the underlying authentication/authorization infrastructure.
+PAM is configured either through one file <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+> (Solaris),
+or by editing individual files that are located in <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+>.</P
+><P
+>The following is an example <TT
+CLASS="FILENAME"
+>/etc/pam.d/login</TT
+> configuration file.
+This example had all options been uncommented is probably not usable
+as it stacks many conditions before allowing successful completion
+of the login process. Essentially all conditions can be disabled
+by commenting them out except the calls to <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_securetty.so
+auth required pam_nologin.so
+# auth required pam_dialup.so
+# auth optional pam_mail.so
+auth required pam_pwdb.so shadow md5
+# account requisite pam_time.so
+account required pam_pwdb.so
+session required pam_pwdb.so
+# session optional pam_lastlog.so
+# password required pam_cracklib.so retry=3
+password required pam_pwdb.so shadow md5</PRE
+></P
+><P
+>PAM allows use of replacable modules. Those available on a
+sample system include:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>$ /bin/ls /lib/security
+pam_access.so pam_ftp.so pam_limits.so
+pam_ncp_auth.so pam_rhosts_auth.so pam_stress.so
+pam_cracklib.so pam_group.so pam_listfile.so
+pam_nologin.so pam_rootok.so pam_tally.so
+pam_deny.so pam_issue.so pam_mail.so
+pam_permit.so pam_securetty.so pam_time.so
+pam_dialup.so pam_lastlog.so pam_mkhomedir.so
+pam_pwdb.so pam_shells.so pam_unix.so
+pam_env.so pam_ldap.so pam_motd.so
+pam_radius.so pam_smbpass.so pam_unix_acct.so
+pam_wheel.so pam_unix_auth.so pam_unix_passwd.so
+pam_userdb.so pam_warn.so pam_unix_session.so</PRE
+></P
+><P
+>The following example for the login program replaces the use of
+the <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+> module which uses the system
+password database (<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>,
+<TT
+CLASS="FILENAME"
+>/etc/shadow</TT
+>, <TT
+CLASS="FILENAME"
+>/etc/group</TT
+>) with
+the module <TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+> which uses the Samba
+database which contains the Microsoft MD4 encrypted password
+hashes. This database is stored in either
+<TT
+CLASS="FILENAME"
+>/usr/local/samba/private/smbpasswd</TT
+>,
+<TT
+CLASS="FILENAME"
+>/etc/samba/smbpasswd</TT
+>, or in
+<TT
+CLASS="FILENAME"
+>/etc/samba.d/smbpasswd</TT
+>, depending on the
+Samba implementation for your Unix/Linux system. The
+<TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+> module is provided by
+Samba version 2.2.1 or later. It can be compiled by specifying the
+<B
+CLASS="COMMAND"
+>--with-pam_smbpass</B
+> options when running Samba's
+<TT
+CLASS="FILENAME"
+>configure</TT
+> script. For more information
+on the <TT
+CLASS="FILENAME"
+>pam_smbpass</TT
+> module, see the documentation
+in the <TT
+CLASS="FILENAME"
+>source/pam_smbpass</TT
+> directory of the Samba
+source distribution.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_smbpass.so nodelay
+account required pam_smbpass.so nodelay
+session required pam_smbpass.so nodelay
+password required pam_smbpass.so nodelay</PRE
+></P
+><P
+>The following is the PAM configuration file for a particular
+Linux system. The default condition uses <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_pwdb.so nullok nodelay shadow audit
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_pwdb.so shadow md5</PRE
+></P
+><P
+>In the following example the decision has been made to use the
+smbpasswd database even for basic samba authentication. Such a
+decision could also be made for the passwd program and would
+thus allow the smbpasswd passwords to be changed using the passwd
+program.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_smbpass.so nodelay
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_smbpass.so nodelay smbconf=/etc/samba.d/smb.conf</PRE
+></P
+><P
+>Note: PAM allows stacking of authentication mechanisms. It is
+also possible to pass information obtained within on PAM module through
+to the next module in the PAM stack. Please refer to the documentation for
+your particular system implementation for details regarding the specific
+capabilities of PAM in this environment. Some Linux implmentations also
+provide the <TT
+CLASS="FILENAME"
+>pam_stack.so</TT
+> module that allows all
+authentication to be configured in a single central file. The
+<TT
+CLASS="FILENAME"
+>pam_stack.so</TT
+> method has some very devoted followers
+on the basis that it allows for easier administration. As with all issues in
+life though, every decision makes trade-offs, so you may want examine the
+PAM documentation for further helpful information.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN47"
+>Distributed Authentication</A
+></H1
+><P
+>The astute administrator will realize from this that the
+combination of <TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+>,
+<B
+CLASS="COMMAND"
+>winbindd</B
+>, and <B
+CLASS="COMMAND"
+>rsync</B
+> (see
+<A
+HREF="http://rsync.samba.org/"
+TARGET="_top"
+>http://rsync.samba.org/</A
+>)
+will allow the establishment of a centrally managed, distributed
+user/password database that can also be used by all
+PAM (eg: Linux) aware programs and applications. This arrangement
+can have particularly potent advantages compared with the
+use of Microsoft Active Directory Service (ADS) in so far as
+reduction of wide area network authentication traffic.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN54"
+>PAM Configuration in smb.conf</A
+></H1
+><P
+>There is an option in smb.conf called <A
+HREF="smb.conf.5.html#OBEYPAMRESTRICTIONS"
+TARGET="_top"
+>obey pam restrictions</A
+>.
+The following is from the on-line help for this option in SWAT;</P
+><P
+>When Samba 2.2 is configure to enable PAM support (i.e.
+<TT
+CLASS="CONSTANT"
+>--with-pam</TT
+>), this parameter will
+control whether or not Samba should obey PAM's account
+and session management directives. The default behavior
+is to use PAM for clear text authentication only and to
+ignore any account or session management. Note that Samba always
+ignores PAM for authentication in the case of
+<A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>encrypt passwords = yes</A
+>.
+The reason is that PAM modules cannot support the challenge/response
+authentication mechanism needed in the presence of SMB
+password encryption. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>obey pam restrictions = no</B
+></P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/Samba-BDC-HOWTO.html b/docs/htmldocs/Samba-BDC-HOWTO.html
new file mode 100755
index 00000000000..46c3541c8df
--- /dev/null
+++ b/docs/htmldocs/Samba-BDC-HOWTO.html
@@ -0,0 +1,350 @@
+<HTML
+><HEAD
+><TITLE
+>How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="SAMBA-BDC"
+>How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Prerequisite Reading</A
+></H1
+><P
+>Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring a Samba PDC
+as described in the <A
+HREF="Samba-PDC-HOWTO.html"
+TARGET="_top"
+>Samba-PDC-HOWTO</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN7"
+>Background</A
+></H1
+><P
+>What is a Domain Controller? It is a machine that is able to answer
+logon requests from workstations in a Windows NT Domain. Whenever a
+user logs into a Windows NT Workstation, the workstation connects to a
+Domain Controller and asks him whether the username and password the
+user typed in is correct. The Domain Controller replies with a lot of
+information about the user, for example the place where the users
+profile is stored, the users full name of the user. All this
+information is stored in the NT user database, the so-called SAM.</P
+><P
+>There are two kinds of Domain Controller in a NT 4 compatible Domain:
+A Primary Domain Controller (PDC) and one or more Backup Domain
+Controllers (BDC). The PDC contains the master copy of the
+SAM. Whenever the SAM has to change, for example when a user changes
+his password, this change has to be done on the PDC. A Backup Domain
+Controller is a machine that maintains a read-only copy of the
+SAM. This way it is able to reply to logon requests and authenticate
+users in case the PDC is not available. During this time no changes to
+the SAM are possible. Whenever changes to the SAM are done on the PDC,
+all BDC receive the changes from the PDC.</P
+><P
+>Since version 2.2 Samba officially supports domain logons for all
+current Windows Clients, including Windows 2000 and XP. This text
+assumes the domain to be named SAMBA. To be able to act as a PDC, some
+parameters in the [global]-section of the smb.conf have to be set:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ workgroup = SAMBA
+ domain master = yes
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....</PRE
+></P
+><P
+>Several other things like a [homes] and a [netlogon] share also may be
+set along with settings for the profile path, the users home drive and
+others. This will not be covered in this document.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN15"
+>What qualifies a Domain Controller on the network?</A
+></H1
+><P
+>Every machine that is a Domain Controller for the domain SAMBA has to
+register the NetBIOS group name SAMBA#1c with the WINS server and/or
+by broadcast on the local network. The PDC also registers the unique
+NetBIOS name SAMBA#1b with the WINS server. The name type #1b is
+normally reserved for the domain master browser, a role that has
+nothing to do with anything related to authentication, but the
+Microsoft Domain implementation requires the domain master browser to
+be on the same machine as the PDC.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN18"
+>How does a Workstation find its domain controller?</A
+></H2
+><P
+>A NT workstation in the domain SAMBA that wants a local user to be
+authenticated has to find the domain controller for SAMBA. It does
+this by doing a NetBIOS name query for the group name SAMBA#1c. It
+assumes that each of the machines it gets back from the queries is a
+domain controller and can answer logon requests. To not open security
+holes both the workstation and the selected (TODO: How is the DC
+chosen) domain controller authenticate each other. After that the
+workstation sends the user's credentials (his name and password) to
+the domain controller, asking for approval.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN21"
+>When is the PDC needed?</A
+></H2
+><P
+>Whenever a user wants to change his password, this has to be done on
+the PDC. To find the PDC, the workstation does a NetBIOS name query
+for SAMBA#1b, assuming this machine maintains the master copy of the
+SAM. The workstation contacts the PDC, both mutually authenticate and
+the password change is done.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN24"
+>Can Samba be a Backup Domain Controller?</A
+></H1
+><P
+>With version 2.2, no. The native NT SAM replication protocols have
+not yet been fully implemented. The Samba Team is working on
+understanding and implementing the protocols, but this work has not
+been finished for version 2.2.</P
+><P
+>Can I get the benefits of a BDC with Samba? Yes. The main reason for
+implementing a BDC is availability. If the PDC is a Samba machine,
+a second Samba machine can be set up to
+service logon requests whenever the PDC is down.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN28"
+>How do I set up a Samba BDC?</A
+></H1
+><P
+>Several things have to be done:</P
+><P
+></P
+><UL
+><LI
+><P
+> The file <TT
+CLASS="FILENAME"
+>private/MACHINE.SID</TT
+> identifies the domain. When a samba
+ server is first started, it is created on the fly and must never be
+ changed again. This file has to be the same on the PDC and the BDC,
+ so the MACHINE.SID has to be copied from the PDC to the BDC. Note that in the
+ latest Samba 2.2.x releases, the machine SID (and therefore domain SID) is stored
+ in the <TT
+CLASS="FILENAME"
+>private/secrets.tdb</TT
+> database. This file cannot just
+ be copied because Samba looks under the key <TT
+CLASS="CONSTANT"
+>SECRETS/SID/<TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+></TT
+>.
+ where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+> is the machine's netbios name. Since this name has
+ to be unique for each SAMBA server, this lookup will fail. </P
+><P
+> A new option has been added to the <B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+>
+ command to help ease this problem. When running <B
+CLASS="COMMAND"
+>smbpasswd -S</B
+> as the root user,
+ the domain SID will be retrieved from a domain controller matching the value of the
+ <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> parameter in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> and stored as the
+ new Samba server's machine SID. See the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+>
+ man page for more details on this functionality.
+ </P
+></LI
+><LI
+><P
+> The Unix user database has to be synchronized from the PDC to the
+ BDC. This means that both the /etc/passwd and /etc/group have to be
+ replicated from the PDC to the BDC. This can be done manually
+ whenever changes are made, or the PDC is set up as a NIS master
+ server and the BDC as a NIS slave server. To set up the BDC as a
+ mere NIS client would not be enough, as the BDC would not be able to
+ access its user database in case of a PDC failure. LDAP is also a
+ potential vehicle for sharing this information.
+ </P
+></LI
+><LI
+><P
+> The Samba password database in the file <TT
+CLASS="FILENAME"
+>private/smbpasswd</TT
+>
+ has to be replicated from the PDC to the BDC. This is a bit tricky, see the
+ next section.
+ </P
+></LI
+><LI
+><P
+> Any netlogon share has to be replicated from the PDC to the
+ BDC. This can be done manually whenever login scripts are changed,
+ or it can be done automatically together with the smbpasswd
+ synchronization.
+ </P
+></LI
+></UL
+><P
+>Finally, the BDC has to be found by the workstations. This can be done
+by setting</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ workgroup = SAMBA
+ domain master = no
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....</PRE
+></P
+><P
+>in the [global]-section of the smb.conf of the BDC. This makes the BDC
+only register the name SAMBA#1c with the WINS server. This is no
+problem as the name SAMBA#1c is a NetBIOS group name that is meant to
+be registered by more than one machine. The parameter 'domain master =
+no' forces the BDC not to register SAMBA#1b which as a unique NetBIOS
+name is reserved for the Primary Domain Controller.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN57"
+>How do I replicate the smbpasswd file?</A
+></H2
+><P
+>Replication of the smbpasswd file is sensitive. It has to be done
+whenever changes to the SAM are made. Every user's password change
+(including machine trust account password changes) is done in the
+smbpasswd file and has to be replicated to the BDC. So
+replicating the smbpasswd file very often is necessary.</P
+><P
+>As the smbpasswd file contains plain text password equivalents, it
+must not be sent unencrypted over the wire. The best way to set up
+smbpasswd replication from the PDC to the BDC is to use the utility
+<B
+CLASS="COMMAND"
+>rsync(1)</B
+>. <B
+CLASS="COMMAND"
+>rsync</B
+> can use
+<B
+CLASS="COMMAND"
+>ssh(1)</B
+> as a transport. <B
+CLASS="COMMAND"
+>ssh</B
+> itself
+can be set up to accept <I
+CLASS="EMPHASIS"
+>only</I
+> <B
+CLASS="COMMAND"
+>rsync</B
+> transfer without requiring the user to
+type a password. Refer to the man pages for these two tools for more details.</P
+><P
+>Another solution with high potential is to use Samba's <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+for sharing and/or replicating the list of <TT
+CLASS="CONSTANT"
+>sambaAccount</TT
+> entries.
+This can all be done over SSL to ensure security. See the <A
+HREF="Samba-LDAP-HOWTO.html"
+TARGET="_top"
+>Samba-LDAP-HOWTO</A
+>
+for more details.</P
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/Samba-HOWTO-Collection.html b/docs/htmldocs/Samba-HOWTO-Collection.html
new file mode 100755
index 00000000000..c12167cf989
--- /dev/null
+++ b/docs/htmldocs/Samba-HOWTO-Collection.html
@@ -0,0 +1,11776 @@
+<HTML
+><HEAD
+><TITLE
+>SAMBA Project Documentation</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="BOOK"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="BOOK"
+><A
+NAME="SAMBA-PROJECT-DOCUMENTATION"
+></A
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="SAMBA-PROJECT-DOCUMENTATION"
+>SAMBA Project Documentation</A
+></H1
+><H3
+CLASS="AUTHOR"
+><A
+NAME="AEN4"
+>SAMBA Team</A
+></H3
+><HR></DIV
+><HR><H1
+><A
+NAME="AEN8"
+>Abstract</A
+></H1
+><P
+><EM
+>Last Update</EM
+> : Mon Apr 1 08:47:26 CST 2002</P
+><P
+>This book is a collection of HOWTOs added to Samba documentation over the years.
+I try to ensure that all are current, but sometimes the is a larger job
+than one person can maintain. The most recent version of this document
+can be found at <A
+HREF="http://www.samba.org/"
+TARGET="_top"
+>http://www.samba.org/</A
+>
+on the "Documentation" page. Please send updates to <A
+HREF="mailto:jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+>.</P
+><P
+>This documentation is distributed under the GNU General Public License (GPL)
+version 2. A copy of the license is included with the Samba source
+distribution. A copy can be found on-line at <A
+HREF="http://www.fsf.org/licenses/gpl.txt"
+TARGET="_top"
+>http://www.fsf.org/licenses/gpl.txt</A
+></P
+><P
+>Cheers, jerry</P
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="#INSTALL"
+>How to Install and Test SAMBA</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="#AEN20"
+>Step 0: Read the man pages</A
+></DT
+><DT
+>1.2. <A
+HREF="#AEN28"
+>Step 1: Building the Binaries</A
+></DT
+><DT
+>1.3. <A
+HREF="#AEN56"
+>Step 2: The all important step</A
+></DT
+><DT
+>1.4. <A
+HREF="#AEN60"
+>Step 3: Create the smb configuration file.</A
+></DT
+><DT
+>1.5. <A
+HREF="#AEN74"
+>Step 4: Test your config file with
+ <B
+CLASS="COMMAND"
+>testparm</B
+></A
+></DT
+><DT
+>1.6. <A
+HREF="#AEN80"
+>Step 5: Starting the smbd and nmbd</A
+></DT
+><DD
+><DL
+><DT
+>1.6.1. <A
+HREF="#AEN90"
+>Step 5a: Starting from inetd.conf</A
+></DT
+><DT
+>1.6.2. <A
+HREF="#AEN119"
+>Step 5b. Alternative: starting it as a daemon</A
+></DT
+></DL
+></DD
+><DT
+>1.7. <A
+HREF="#AEN135"
+>Step 6: Try listing the shares available on your
+ server</A
+></DT
+><DT
+>1.8. <A
+HREF="#AEN144"
+>Step 7: Try connecting with the unix client</A
+></DT
+><DT
+>1.9. <A
+HREF="#AEN160"
+>Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT,
+ Win2k, OS/2, etc... client</A
+></DT
+><DT
+>1.10. <A
+HREF="#AEN174"
+>What If Things Don't Work?</A
+></DT
+><DD
+><DL
+><DT
+>1.10.1. <A
+HREF="#AEN179"
+>Diagnosing Problems</A
+></DT
+><DT
+>1.10.2. <A
+HREF="#AEN183"
+>Scope IDs</A
+></DT
+><DT
+>1.10.3. <A
+HREF="#AEN186"
+>Choosing the Protocol Level</A
+></DT
+><DT
+>1.10.4. <A
+HREF="#AEN195"
+>Printing from UNIX to a Client PC</A
+></DT
+><DT
+>1.10.5. <A
+HREF="#AEN199"
+>Locking</A
+></DT
+><DT
+>1.10.6. <A
+HREF="#AEN208"
+>Mapping Usernames</A
+></DT
+><DT
+>1.10.7. <A
+HREF="#AEN211"
+>Other Character Sets</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>2. <A
+HREF="#INTEGRATE-MS-NETWORKS"
+>Integrating MS Windows networks with Samba</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="#AEN225"
+>Agenda</A
+></DT
+><DT
+>2.2. <A
+HREF="#AEN247"
+>Name Resolution in a pure Unix/Linux world</A
+></DT
+><DD
+><DL
+><DT
+>2.2.1. <A
+HREF="#AEN263"
+><TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+></A
+></DT
+><DT
+>2.2.2. <A
+HREF="#AEN279"
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></A
+></DT
+><DT
+>2.2.3. <A
+HREF="#AEN290"
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+></A
+></DT
+><DT
+>2.2.4. <A
+HREF="#AEN298"
+><TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+></A
+></DT
+></DL
+></DD
+><DT
+>2.3. <A
+HREF="#AEN310"
+>Name resolution as used within MS Windows networking</A
+></DT
+><DD
+><DL
+><DT
+>2.3.1. <A
+HREF="#AEN322"
+>The NetBIOS Name Cache</A
+></DT
+><DT
+>2.3.2. <A
+HREF="#AEN327"
+>The LMHOSTS file</A
+></DT
+><DT
+>2.3.3. <A
+HREF="#AEN335"
+>HOSTS file</A
+></DT
+><DT
+>2.3.4. <A
+HREF="#AEN340"
+>DNS Lookup</A
+></DT
+><DT
+>2.3.5. <A
+HREF="#AEN343"
+>WINS Lookup</A
+></DT
+></DL
+></DD
+><DT
+>2.4. <A
+HREF="#AEN355"
+>How browsing functions and how to deploy stable and
+dependable browsing using Samba</A
+></DT
+><DT
+>2.5. <A
+HREF="#AEN365"
+>MS Windows security options and how to configure
+Samba for seemless integration</A
+></DT
+><DD
+><DL
+><DT
+>2.5.1. <A
+HREF="#AEN393"
+>Use MS Windows NT as an authentication server</A
+></DT
+><DT
+>2.5.2. <A
+HREF="#AEN401"
+>Make Samba a member of an MS Windows NT security domain</A
+></DT
+><DT
+>2.5.3. <A
+HREF="#AEN418"
+>Configure Samba as an authentication server</A
+></DT
+><DD
+><DL
+><DT
+>2.5.3.1. <A
+HREF="#AEN425"
+>Users</A
+></DT
+><DT
+>2.5.3.2. <A
+HREF="#AEN430"
+>MS Windows NT Machine Accounts</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>2.6. <A
+HREF="#AEN435"
+>Conclusions</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="#PAM"
+>Configuring PAM for distributed but centrally
+managed authentication</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="#AEN456"
+>Samba and PAM</A
+></DT
+><DT
+>3.2. <A
+HREF="#AEN500"
+>Distributed Authentication</A
+></DT
+><DT
+>3.3. <A
+HREF="#AEN507"
+>PAM Configuration in smb.conf</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="#MSDFS"
+>Hosting a Microsoft Distributed File System tree on Samba</A
+></DT
+><DD
+><DL
+><DT
+>4.1. <A
+HREF="#AEN527"
+>Instructions</A
+></DT
+><DD
+><DL
+><DT
+>4.1.1. <A
+HREF="#AEN562"
+>Notes</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>5. <A
+HREF="#UNIX-PERMISSIONS"
+>UNIX Permission Bits and Windows NT Access Control Lists</A
+></DT
+><DD
+><DL
+><DT
+>5.1. <A
+HREF="#AEN582"
+>Viewing and changing UNIX permissions using the NT
+ security dialogs</A
+></DT
+><DT
+>5.2. <A
+HREF="#AEN591"
+>How to view file security on a Samba share</A
+></DT
+><DT
+>5.3. <A
+HREF="#AEN602"
+>Viewing file ownership</A
+></DT
+><DT
+>5.4. <A
+HREF="#AEN622"
+>Viewing file or directory permissions</A
+></DT
+><DD
+><DL
+><DT
+>5.4.1. <A
+HREF="#AEN637"
+>File Permissions</A
+></DT
+><DT
+>5.4.2. <A
+HREF="#AEN651"
+>Directory Permissions</A
+></DT
+></DL
+></DD
+><DT
+>5.5. <A
+HREF="#AEN658"
+>Modifying file or directory permissions</A
+></DT
+><DT
+>5.6. <A
+HREF="#AEN680"
+>Interaction with the standard Samba create mask
+ parameters</A
+></DT
+><DT
+>5.7. <A
+HREF="#AEN744"
+>Interaction with the standard Samba file attribute
+ mapping</A
+></DT
+></DL
+></DD
+><DT
+>6. <A
+HREF="#PRINTING"
+>Printing Support in Samba 2.2.x</A
+></DT
+><DD
+><DL
+><DT
+>6.1. <A
+HREF="#AEN765"
+>Introduction</A
+></DT
+><DT
+>6.2. <A
+HREF="#AEN787"
+>Configuration</A
+></DT
+><DD
+><DL
+><DT
+>6.2.1. <A
+HREF="#AEN798"
+>Creating [print$]</A
+></DT
+><DT
+>6.2.2. <A
+HREF="#AEN833"
+>Setting Drivers for Existing Printers</A
+></DT
+><DT
+>6.2.3. <A
+HREF="#AEN851"
+>DeviceModes and New Printers</A
+></DT
+><DT
+>6.2.4. <A
+HREF="#AEN862"
+>Support a large number of printers</A
+></DT
+><DT
+>6.2.5. <A
+HREF="#AEN873"
+>Adding New Printers via the Windows NT APW</A
+></DT
+><DT
+>6.2.6. <A
+HREF="#AEN898"
+>Samba and Printer Ports</A
+></DT
+></DL
+></DD
+><DT
+>6.3. <A
+HREF="#AEN906"
+>The Imprints Toolset</A
+></DT
+><DD
+><DL
+><DT
+>6.3.1. <A
+HREF="#AEN911"
+>What is Imprints?</A
+></DT
+><DT
+>6.3.2. <A
+HREF="#AEN921"
+>Creating Printer Driver Packages</A
+></DT
+><DT
+>6.3.3. <A
+HREF="#AEN924"
+>The Imprints server</A
+></DT
+><DT
+>6.3.4. <A
+HREF="#AEN928"
+>The Installation Client</A
+></DT
+></DL
+></DD
+><DT
+>6.4. <A
+HREF="#AEN950"
+><A
+NAME="MIGRATION"
+></A
+>Migration to from Samba 2.0.x to 2.2.x</A
+></DT
+><DD
+><DL
+><DT
+>6.4.1. <A
+HREF="#AEN983"
+>Parameters in <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> for Backwards Compatibility</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>7. <A
+HREF="#CUPS"
+>Printing with CUPS in Samba 2.2.x</A
+></DT
+><DD
+><DL
+><DT
+>7.1. <A
+HREF="#AEN999"
+>Printing with CUPS in Samba 2.2.x</A
+></DT
+><DT
+>7.2. <A
+HREF="#AEN1003"
+>Configuring <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for CUPS</A
+></DT
+><DT
+>7.3. <A
+HREF="#AEN1022"
+>Using CUPS as a mere spooling print server -- "raw"
+printing with vendor drivers download</A
+></DT
+><DT
+>7.4. <A
+HREF="#AEN1025"
+>CUPS as a network PostScript RIP -- CUPS drivers working on server, Adobe
+PostScript driver with CUPS-PPDs downloaded to clients</A
+></DT
+><DT
+>7.5. <A
+HREF="#AEN1046"
+>Windows Terminal Servers (WTS) as CUPS clients</A
+></DT
+><DT
+>7.6. <A
+HREF="#AEN1050"
+>Setting up CUPS for driver download</A
+></DT
+><DT
+>7.7. <A
+HREF="#AEN1062"
+>Sources of CUPS drivers / PPDs</A
+></DT
+><DD
+><DL
+><DT
+>7.7.1. <A
+HREF="#AEN1089"
+><B
+CLASS="COMMAND"
+>cupsaddsmb</B
+></A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>8. <A
+HREF="#DOMAIN-SECURITY"
+>security = domain in Samba 2.x</A
+></DT
+><DD
+><DL
+><DT
+>8.1. <A
+HREF="#AEN1134"
+>Joining an NT Domain with Samba 2.2</A
+></DT
+><DT
+>8.2. <A
+HREF="#AEN1198"
+>Samba and Windows 2000 Domains</A
+></DT
+><DT
+>8.3. <A
+HREF="#AEN1203"
+>Why is this better than security = server?</A
+></DT
+></DL
+></DD
+><DT
+>9. <A
+HREF="#SAMBA-PDC"
+>How to Configure Samba 2.2 as a Primary Domain Controller</A
+></DT
+><DD
+><DL
+><DT
+>9.1. <A
+HREF="#AEN1236"
+>Prerequisite Reading</A
+></DT
+><DT
+>9.2. <A
+HREF="#AEN1242"
+>Background</A
+></DT
+><DT
+>9.3. <A
+HREF="#AEN1281"
+>Configuring the Samba Domain Controller</A
+></DT
+><DT
+>9.4. <A
+HREF="#AEN1324"
+>Creating Machine Trust Accounts and Joining Clients to the
+Domain</A
+></DT
+><DD
+><DL
+><DT
+>9.4.1. <A
+HREF="#AEN1343"
+>Manual Creation of Machine Trust Accounts</A
+></DT
+><DT
+>9.4.2. <A
+HREF="#AEN1378"
+>"On-the-Fly" Creation of Machine Trust Accounts</A
+></DT
+><DT
+>9.4.3. <A
+HREF="#AEN1387"
+>Joining the Client to the Domain</A
+></DT
+></DL
+></DD
+><DT
+>9.5. <A
+HREF="#AEN1402"
+>Common Problems and Errors</A
+></DT
+><DT
+>9.6. <A
+HREF="#AEN1450"
+>System Policies and Profiles</A
+></DT
+><DT
+>9.7. <A
+HREF="#AEN1494"
+>What other help can I get?</A
+></DT
+><DT
+>9.8. <A
+HREF="#AEN1608"
+>Domain Control for Windows 9x/ME</A
+></DT
+><DD
+><DL
+><DT
+>9.8.1. <A
+HREF="#AEN1634"
+>Configuration Instructions: Network Logons</A
+></DT
+><DT
+>9.8.2. <A
+HREF="#AEN1653"
+>Configuration Instructions: Setting up Roaming User Profiles</A
+></DT
+><DD
+><DL
+><DT
+>9.8.2.1. <A
+HREF="#AEN1661"
+>Windows NT Configuration</A
+></DT
+><DT
+>9.8.2.2. <A
+HREF="#AEN1669"
+>Windows 9X Configuration</A
+></DT
+><DT
+>9.8.2.3. <A
+HREF="#AEN1677"
+>Win9X and WinNT Configuration</A
+></DT
+><DT
+>9.8.2.4. <A
+HREF="#AEN1684"
+>Windows 9X Profile Setup</A
+></DT
+><DT
+>9.8.2.5. <A
+HREF="#AEN1720"
+>Windows NT Workstation 4.0</A
+></DT
+><DT
+>9.8.2.6. <A
+HREF="#AEN1733"
+>Windows NT Server</A
+></DT
+><DT
+>9.8.2.7. <A
+HREF="#AEN1736"
+>Sharing Profiles between W95 and NT Workstation 4.0</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>9.9. <A
+HREF="#AEN1746"
+>DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
+></DT
+></DL
+></DD
+><DT
+>10. <A
+HREF="#SAMBA-BDC"
+>How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
+></DT
+><DD
+><DL
+><DT
+>10.1. <A
+HREF="#AEN1782"
+>Prerequisite Reading</A
+></DT
+><DT
+>10.2. <A
+HREF="#AEN1786"
+>Background</A
+></DT
+><DT
+>10.3. <A
+HREF="#AEN1794"
+>What qualifies a Domain Controller on the network?</A
+></DT
+><DD
+><DL
+><DT
+>10.3.1. <A
+HREF="#AEN1797"
+>How does a Workstation find its domain controller?</A
+></DT
+><DT
+>10.3.2. <A
+HREF="#AEN1800"
+>When is the PDC needed?</A
+></DT
+></DL
+></DD
+><DT
+>10.4. <A
+HREF="#AEN1803"
+>Can Samba be a Backup Domain Controller?</A
+></DT
+><DT
+>10.5. <A
+HREF="#AEN1807"
+>How do I set up a Samba BDC?</A
+></DT
+><DD
+><DL
+><DT
+>10.5.1. <A
+HREF="#AEN1836"
+>How do I replicate the smbpasswd file?</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>11. <A
+HREF="#SAMBA-LDAP-HOWTO"
+>Storing Samba's User/Machine Account information in an LDAP Directory</A
+></DT
+><DD
+><DL
+><DT
+>11.1. <A
+HREF="#AEN1867"
+>Purpose</A
+></DT
+><DT
+>11.2. <A
+HREF="#AEN1888"
+>Introduction</A
+></DT
+><DT
+>11.3. <A
+HREF="#AEN1919"
+>Supported LDAP Servers</A
+></DT
+><DT
+>11.4. <A
+HREF="#AEN1924"
+>Schema and Relationship to the RFC 2307 posixAccount</A
+></DT
+><DT
+>11.5. <A
+HREF="#AEN1945"
+>Configuring Samba with LDAP</A
+></DT
+><DD
+><DL
+><DT
+>11.5.1. <A
+HREF="#AEN1947"
+>OpenLDAP configuration</A
+></DT
+><DT
+>11.5.2. <A
+HREF="#AEN1964"
+>Configuring Samba</A
+></DT
+><DT
+>11.5.3. <A
+HREF="#AEN1992"
+>Importing <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> entries</A
+></DT
+></DL
+></DD
+><DT
+>11.6. <A
+HREF="#AEN2008"
+>Accounts and Groups management</A
+></DT
+><DT
+>11.7. <A
+HREF="#AEN2013"
+>Security and sambaAccount</A
+></DT
+><DT
+>11.8. <A
+HREF="#AEN2033"
+>LDAP specials attributes for sambaAccounts</A
+></DT
+><DT
+>11.9. <A
+HREF="#AEN2103"
+>Example LDIF Entries for a sambaAccount</A
+></DT
+><DT
+>11.10. <A
+HREF="#AEN2111"
+>Comments</A
+></DT
+></DL
+></DD
+><DT
+>12. <A
+HREF="#WINBIND"
+>Unified Logons between Windows NT and UNIX using Winbind</A
+></DT
+><DD
+><DL
+><DT
+>12.1. <A
+HREF="#AEN2140"
+>Abstract</A
+></DT
+><DT
+>12.2. <A
+HREF="#AEN2144"
+>Introduction</A
+></DT
+><DT
+>12.3. <A
+HREF="#AEN2157"
+>What Winbind Provides</A
+></DT
+><DD
+><DL
+><DT
+>12.3.1. <A
+HREF="#AEN2164"
+>Target Uses</A
+></DT
+></DL
+></DD
+><DT
+>12.4. <A
+HREF="#AEN2168"
+>How Winbind Works</A
+></DT
+><DD
+><DL
+><DT
+>12.4.1. <A
+HREF="#AEN2173"
+>Microsoft Remote Procedure Calls</A
+></DT
+><DT
+>12.4.2. <A
+HREF="#AEN2177"
+>Name Service Switch</A
+></DT
+><DT
+>12.4.3. <A
+HREF="#AEN2193"
+>Pluggable Authentication Modules</A
+></DT
+><DT
+>12.4.4. <A
+HREF="#AEN2201"
+>User and Group ID Allocation</A
+></DT
+><DT
+>12.4.5. <A
+HREF="#AEN2205"
+>Result Caching</A
+></DT
+></DL
+></DD
+><DT
+>12.5. <A
+HREF="#AEN2208"
+>Installation and Configuration</A
+></DT
+><DD
+><DL
+><DT
+>12.5.1. <A
+HREF="#AEN2212"
+>Introduction</A
+></DT
+><DT
+>12.5.2. <A
+HREF="#AEN2225"
+>Requirements</A
+></DT
+><DT
+>12.5.3. <A
+HREF="#AEN2241"
+>Testing Things Out</A
+></DT
+><DD
+><DL
+><DT
+>12.5.3.1. <A
+HREF="#AEN2254"
+>Configure and Compile SAMBA</A
+></DT
+><DT
+>12.5.3.2. <A
+HREF="#AEN2267"
+>Configure <TT
+CLASS="FILENAME"
+>nsswitch.conf</TT
+> and the
+winbind libraries</A
+></DT
+><DT
+>12.5.3.3. <A
+HREF="#AEN2289"
+>Configure <TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+></DT
+><DT
+>12.5.3.4. <A
+HREF="#AEN2306"
+>Join the SAMBA server to the PDC domain</A
+></DT
+><DT
+>12.5.3.5. <A
+HREF="#AEN2317"
+>Start up the winbindd daemon and test it!</A
+></DT
+><DT
+>12.5.3.6. <A
+HREF="#AEN2358"
+>Configure Winbind and PAM</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>12.6. <A
+HREF="#AEN2411"
+>Limitations</A
+></DT
+><DT
+>12.7. <A
+HREF="#AEN2419"
+>Conclusion</A
+></DT
+></DL
+></DD
+><DT
+>13. <A
+HREF="#OS2"
+>OS2 Client HOWTO</A
+></DT
+><DD
+><DL
+><DT
+>13.1. <A
+HREF="#AEN2433"
+>FAQs</A
+></DT
+><DD
+><DL
+><DT
+>13.1.1. <A
+HREF="#AEN2435"
+>How can I configure OS/2 Warp Connect or
+ OS/2 Warp 4 as a client for Samba?</A
+></DT
+><DT
+>13.1.2. <A
+HREF="#AEN2450"
+>How can I configure OS/2 Warp 3 (not Connect),
+ OS/2 1.2, 1.3 or 2.x for Samba?</A
+></DT
+><DT
+>13.1.3. <A
+HREF="#AEN2459"
+>Are there any other issues when OS/2 (any version)
+ is used as a client?</A
+></DT
+><DT
+>13.1.4. <A
+HREF="#AEN2463"
+>How do I get printer driver download working
+ for OS/2 clients?</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>14. <A
+HREF="#CVS-ACCESS"
+>HOWTO Access Samba source code via CVS</A
+></DT
+><DD
+><DL
+><DT
+>14.1. <A
+HREF="#AEN2479"
+>Introduction</A
+></DT
+><DT
+>14.2. <A
+HREF="#AEN2484"
+>CVS Access to samba.org</A
+></DT
+><DD
+><DL
+><DT
+>14.2.1. <A
+HREF="#AEN2487"
+>Access via CVSweb</A
+></DT
+><DT
+>14.2.2. <A
+HREF="#AEN2492"
+>Access via cvs</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+><A
+HREF="#AEN2520"
+>Index</A
+></DT
+></DL
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="INSTALL"
+>Chapter 1. How to Install and Test SAMBA</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN20"
+>1.1. Step 0: Read the man pages</A
+></H1
+><P
+>The man pages distributed with SAMBA contain
+ lots of useful info that will help to get you started.
+ If you don't know how to read man pages then try
+ something like:</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>nroff -man smbd.8 | more
+ </B
+></TT
+></P
+><P
+>Other sources of information are pointed to
+ by the Samba web site,<A
+HREF="http://www.samba.org/"
+TARGET="_top"
+> http://www.samba.org</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN28"
+>1.2. Step 1: Building the Binaries</A
+></H1
+><P
+>To do this, first run the program <B
+CLASS="COMMAND"
+>./configure
+ </B
+> in the source directory. This should automatically
+ configure Samba for your operating system. If you have unusual
+ needs then you may wish to run</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>./configure --help
+ </B
+></TT
+></P
+><P
+>first to see what special options you can enable.
+ Then executing</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make</B
+></TT
+></P
+><P
+>will create the binaries. Once it's successfully
+ compiled you can use </P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make install</B
+></TT
+></P
+><P
+>to install the binaries and manual pages. You can
+ separately install the binaries and/or man pages using</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make installbin
+ </B
+></TT
+></P
+><P
+>and</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make installman
+ </B
+></TT
+></P
+><P
+>Note that if you are upgrading for a previous version
+ of Samba you might like to know that the old versions of
+ the binaries will be renamed with a ".old" extension. You
+ can go back to the previous version with</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make revert
+ </B
+></TT
+></P
+><P
+>if you find this version a disaster!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN56"
+>1.3. Step 2: The all important step</A
+></H1
+><P
+>At this stage you must fetch yourself a
+ coffee or other drink you find stimulating. Getting the rest
+ of the install right can sometimes be tricky, so you will
+ probably need it.</P
+><P
+>If you have installed samba before then you can skip
+ this step.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN60"
+>1.4. Step 3: Create the smb configuration file.</A
+></H1
+><P
+>There are sample configuration files in the examples
+ subdirectory in the distribution. I suggest you read them
+ carefully so you can see how the options go together in
+ practice. See the man page for all the options.</P
+><P
+>The simplest useful configuration file would be
+ something like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> [global]
+ workgroup = MYGROUP
+
+ [homes]
+ guest ok = no
+ read only = no
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>which would allow connections by anyone with an
+ account on the server, using either their login name or
+ "homes" as the service name. (Note that I also set the
+ workgroup that Samba is part of. See BROWSING.txt for details)</P
+><P
+>Note that <B
+CLASS="COMMAND"
+>make install</B
+> will not install
+ a <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. You need to create it
+ yourself. </P
+><P
+>Make sure you put the smb.conf file in the same place
+ you specified in the<TT
+CLASS="FILENAME"
+>Makefile</TT
+> (the default is to
+ look for it in <TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/</TT
+>).</P
+><P
+>For more information about security settings for the
+ [homes] share please refer to the document UNIX_SECURITY.txt.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN74"
+>1.5. Step 4: Test your config file with
+ <B
+CLASS="COMMAND"
+>testparm</B
+></A
+></H1
+><P
+>It's important that you test the validity of your
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file using the testparm program.
+ If testparm runs OK then it will list the loaded services. If
+ not it will give an error message.</P
+><P
+>Make sure it runs OK and that the services look
+ reasonable before proceeding. </P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN80"
+>1.6. Step 5: Starting the smbd and nmbd</A
+></H1
+><P
+>You must choose to start smbd and nmbd either
+ as daemons or from <B
+CLASS="COMMAND"
+>inetd</B
+>. Don't try
+ to do both! Either you can put them in <TT
+CLASS="FILENAME"
+> inetd.conf</TT
+> and have them started on demand
+ by <B
+CLASS="COMMAND"
+>inetd</B
+>, or you can start them as
+ daemons either from the command line or in <TT
+CLASS="FILENAME"
+> /etc/rc.local</TT
+>. See the man pages for details
+ on the command line options. Take particular care to read
+ the bit about what user you need to be in order to start
+ Samba. In many cases you must be root.</P
+><P
+>The main advantage of starting <B
+CLASS="COMMAND"
+>smbd</B
+>
+ and <B
+CLASS="COMMAND"
+>nmbd</B
+> using the recommended daemon method
+ is that they will respond slightly more quickly to an initial connection
+ request.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN90"
+>1.6.1. Step 5a: Starting from inetd.conf</A
+></H2
+><P
+>NOTE; The following will be different if
+ you use NIS or NIS+ to distributed services maps.</P
+><P
+>Look at your <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.
+ What is defined at port 139/tcp. If nothing is defined
+ then add a line like this:</P
+><P
+><TT
+CLASS="USERINPUT"
+><B
+>netbios-ssn 139/tcp</B
+></TT
+></P
+><P
+>similarly for 137/udp you should have an entry like:</P
+><P
+><TT
+CLASS="USERINPUT"
+><B
+>netbios-ns 137/udp</B
+></TT
+></P
+><P
+>Next edit your <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>
+ and add two lines something like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> netbios-ssn stream tcp nowait root /usr/local/samba/bin/smbd smbd
+ netbios-ns dgram udp wait root /usr/local/samba/bin/nmbd nmbd
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The exact syntax of <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>
+ varies between unixes. Look at the other entries in inetd.conf
+ for a guide.</P
+><P
+>NOTE: Some unixes already have entries like netbios_ns
+ (note the underscore) in <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.
+ You must either edit <TT
+CLASS="FILENAME"
+>/etc/services</TT
+> or
+ <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+> to make them consistent.</P
+><P
+>NOTE: On many systems you may need to use the
+ "interfaces" option in smb.conf to specify the IP address
+ and netmask of your interfaces. Run <B
+CLASS="COMMAND"
+>ifconfig</B
+>
+ as root if you don't know what the broadcast is for your
+ net. <B
+CLASS="COMMAND"
+>nmbd</B
+> tries to determine it at run
+ time, but fails on some unixes. See the section on "testing nmbd"
+ for a method of finding if you need to do this.</P
+><P
+>!!!WARNING!!! Many unixes only accept around 5
+ parameters on the command line in <TT
+CLASS="FILENAME"
+>inetd.conf</TT
+>.
+ This means you shouldn't use spaces between the options and
+ arguments, or you should use a script, and start the script
+ from <B
+CLASS="COMMAND"
+>inetd</B
+>.</P
+><P
+>Restart <B
+CLASS="COMMAND"
+>inetd</B
+>, perhaps just send
+ it a HUP. If you have installed an earlier version of <B
+CLASS="COMMAND"
+> nmbd</B
+> then you may need to kill nmbd as well.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN119"
+>1.6.2. Step 5b. Alternative: starting it as a daemon</A
+></H2
+><P
+>To start the server as a daemon you should create
+ a script something like this one, perhaps calling
+ it <TT
+CLASS="FILENAME"
+>startsmb</TT
+>.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> #!/bin/sh
+ /usr/local/samba/bin/smbd -D
+ /usr/local/samba/bin/nmbd -D
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>then make it executable with <B
+CLASS="COMMAND"
+>chmod
+ +x startsmb</B
+></P
+><P
+>You can then run <B
+CLASS="COMMAND"
+>startsmb</B
+> by
+ hand or execute it from <TT
+CLASS="FILENAME"
+>/etc/rc.local</TT
+>
+ </P
+><P
+>To kill it send a kill signal to the processes
+ <B
+CLASS="COMMAND"
+>nmbd</B
+> and <B
+CLASS="COMMAND"
+>smbd</B
+>.</P
+><P
+>NOTE: If you use the SVR4 style init system then
+ you may like to look at the <TT
+CLASS="FILENAME"
+>examples/svr4-startup</TT
+>
+ script to make Samba fit into that system.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN135"
+>1.7. Step 6: Try listing the shares available on your
+ server</A
+></H1
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient -L
+ <TT
+CLASS="REPLACEABLE"
+><I
+>yourhostname</I
+></TT
+></B
+></TT
+></P
+><P
+>You should get back a list of shares available on
+ your server. If you don't then something is incorrectly setup.
+ Note that this method can also be used to see what shares
+ are available on other LanManager clients (such as WfWg).</P
+><P
+>If you choose user level security then you may find
+ that Samba requests a password before it will list the shares.
+ See the <B
+CLASS="COMMAND"
+>smbclient</B
+> man page for details. (you
+ can force it to list the shares without a password by
+ adding the option -U% to the command line. This will not work
+ with non-Samba servers)</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN144"
+>1.8. Step 7: Try connecting with the unix client</A
+></H1
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient <TT
+CLASS="REPLACEABLE"
+><I
+> //yourhostname/aservice</I
+></TT
+></B
+></TT
+></P
+><P
+>Typically the <TT
+CLASS="REPLACEABLE"
+><I
+>yourhostname</I
+></TT
+>
+ would be the name of the host where you installed <B
+CLASS="COMMAND"
+> smbd</B
+>. The <TT
+CLASS="REPLACEABLE"
+><I
+>aservice</I
+></TT
+> is
+ any service you have defined in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ file. Try your user name if you just have a [homes] section
+ in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.</P
+><P
+>For example if your unix host is bambi and your login
+ name is fred you would type:</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient //bambi/fred
+ </B
+></TT
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN160"
+>1.9. Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT,
+ Win2k, OS/2, etc... client</A
+></H1
+><P
+>Try mounting disks. eg:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>net use d: \\servername\service
+ </B
+></TT
+></P
+><P
+>Try printing. eg:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>net use lpt1:
+ \\servername\spoolservice</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>print filename
+ </B
+></TT
+></P
+><P
+>Celebrate, or send me a bug report!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN174"
+>1.10. What If Things Don't Work?</A
+></H1
+><P
+>If nothing works and you start to think "who wrote
+ this pile of trash" then I suggest you do step 2 again (and
+ again) till you calm down.</P
+><P
+>Then you might read the file DIAGNOSIS.txt and the
+ FAQ. If you are still stuck then try the mailing list or
+ newsgroup (look in the README for details). Samba has been
+ successfully installed at thousands of sites worldwide, so maybe
+ someone else has hit your problem and has overcome it. You could
+ also use the WWW site to scan back issues of the samba-digest.</P
+><P
+>When you fix the problem PLEASE send me some updates to the
+ documentation (or source code) so that the next person will find it
+ easier. </P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN179"
+>1.10.1. Diagnosing Problems</A
+></H2
+><P
+>If you have installation problems then go to
+ <TT
+CLASS="FILENAME"
+>DIAGNOSIS.txt</TT
+> to try to find the
+ problem.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN183"
+>1.10.2. Scope IDs</A
+></H2
+><P
+>By default Samba uses a blank scope ID. This means
+ all your windows boxes must also have a blank scope ID.
+ If you really want to use a non-blank scope ID then you will
+ need to use the 'netbios scope' smb.conf option.
+ All your PCs will need to have the same setting for
+ this to work. I do not recommend scope IDs.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN186"
+>1.10.3. Choosing the Protocol Level</A
+></H2
+><P
+>The SMB protocol has many dialects. Currently
+ Samba supports 5, called CORE, COREPLUS, LANMAN1,
+ LANMAN2 and NT1.</P
+><P
+>You can choose what maximum protocol to support
+ in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. The default is
+ NT1 and that is the best for the vast majority of sites.</P
+><P
+>In older versions of Samba you may have found it
+ necessary to use COREPLUS. The limitations that led to
+ this have mostly been fixed. It is now less likely that you
+ will want to use less than LANMAN1. The only remaining advantage
+ of COREPLUS is that for some obscure reason WfWg preserves
+ the case of passwords in this protocol, whereas under LANMAN1,
+ LANMAN2 or NT1 it uppercases all passwords before sending them,
+ forcing you to use the "password level=" option in some cases.</P
+><P
+>The main advantage of LANMAN2 and NT1 is support for
+ long filenames with some clients (eg: smbclient, Windows NT
+ or Win95). </P
+><P
+>See the smb.conf(5) manual page for more details.</P
+><P
+>Note: To support print queue reporting you may find
+ that you have to use TCP/IP as the default protocol under
+ WfWg. For some reason if you leave Netbeui as the default
+ it may break the print queue reporting on some systems.
+ It is presumably a WfWg bug.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN195"
+>1.10.4. Printing from UNIX to a Client PC</A
+></H2
+><P
+>To use a printer that is available via a smb-based
+ server from a unix host you will need to compile the
+ smbclient program. You then need to install the script
+ "smbprint". Read the instruction in smbprint for more details.
+ </P
+><P
+>There is also a SYSV style script that does much
+ the same thing called smbprint.sysv. It contains instructions.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN199"
+>1.10.5. Locking</A
+></H2
+><P
+>One area which sometimes causes trouble is locking.</P
+><P
+>There are two types of locking which need to be
+ performed by a SMB server. The first is "record locking"
+ which allows a client to lock a range of bytes in a open file.
+ The second is the "deny modes" that are specified when a file
+ is open.</P
+><P
+>Record locking semantics under Unix is very
+ different from record locking under Windows. Versions
+ of Samba before 2.2 have tried to use the native
+ fcntl() unix system call to implement proper record
+ locking between different Samba clients. This can not
+ be fully correct due to several reasons. The simplest
+ is the fact that a Windows client is allowed to lock a
+ byte range up to 2^32 or 2^64, depending on the client
+ OS. The unix locking only supports byte ranges up to
+ 2^31. So it is not possible to correctly satisfy a
+ lock request above 2^31. There are many more
+ differences, too many to be listed here.</P
+><P
+>Samba 2.2 and above implements record locking
+ completely independent of the underlying unix
+ system. If a byte range lock that the client requests
+ happens to fall into the range 0-2^31, Samba hands
+ this request down to the Unix system. All other locks
+ can not be seen by unix anyway.</P
+><P
+>Strictly a SMB server should check for locks before
+ every read and write call on a file. Unfortunately with the
+ way fcntl() works this can be slow and may overstress the
+ rpc.lockd. It is also almost always unnecessary as clients
+ are supposed to independently make locking calls before reads
+ and writes anyway if locking is important to them. By default
+ Samba only makes locking calls when explicitly asked
+ to by a client, but if you set "strict locking = yes" then it will
+ make lock checking calls on every read and write. </P
+><P
+>You can also disable by range locking completely
+ using "locking = no". This is useful for those shares that
+ don't support locking or don't need it (such as cdroms). In
+ this case Samba fakes the return codes of locking calls to
+ tell clients that everything is OK.</P
+><P
+>The second class of locking is the "deny modes". These
+ are set by an application when it opens a file to determine
+ what types of access should be allowed simultaneously with
+ its open. A client may ask for DENY_NONE, DENY_READ, DENY_WRITE
+ or DENY_ALL. There are also special compatibility modes called
+ DENY_FCB and DENY_DOS.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN208"
+>1.10.6. Mapping Usernames</A
+></H2
+><P
+>If you have different usernames on the PCs and
+ the unix server then take a look at the "username map" option.
+ See the smb.conf man page for details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN211"
+>1.10.7. Other Character Sets</A
+></H2
+><P
+>If you have problems using filenames with accented
+ characters in them (like the German, French or Scandinavian
+ character sets) then I recommend you look at the "valid chars"
+ option in smb.conf and also take a look at the validchars
+ package in the examples directory.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="INTEGRATE-MS-NETWORKS"
+>Chapter 2. Integrating MS Windows networks with Samba</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN225"
+>2.1. Agenda</A
+></H1
+><P
+>To identify the key functional mechanisms of MS Windows networking
+to enable the deployment of Samba as a means of extending and/or
+replacing MS Windows NT/2000 technology.</P
+><P
+>We will examine:</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>Name resolution in a pure Unix/Linux TCP/IP
+ environment
+ </P
+></LI
+><LI
+><P
+>Name resolution as used within MS Windows
+ networking
+ </P
+></LI
+><LI
+><P
+>How browsing functions and how to deploy stable
+ and dependable browsing using Samba
+ </P
+></LI
+><LI
+><P
+>MS Windows security options and how to
+ configure Samba for seemless integration
+ </P
+></LI
+><LI
+><P
+>Configuration of Samba as:</P
+><P
+></P
+><OL
+TYPE="a"
+><LI
+><P
+>A stand-alone server</P
+></LI
+><LI
+><P
+>An MS Windows NT 3.x/4.0 security domain member
+ </P
+></LI
+><LI
+><P
+>An alternative to an MS Windows NT 3.x/4.0 Domain Controller
+ </P
+></LI
+></OL
+></LI
+></OL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN247"
+>2.2. Name Resolution in a pure Unix/Linux world</A
+></H1
+><P
+>The key configuration files covered in this section are:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+></P
+></LI
+></UL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN263"
+>2.2.1. <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+></A
+></H2
+><P
+>Contains a static list of IP Addresses and names.
+eg:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> 127.0.0.1 localhost localhost.localdomain
+ 192.168.1.1 bigbox.caldera.com bigbox alias4box</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The purpose of <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> is to provide a
+name resolution mechanism so that uses do not need to remember
+IP addresses.</P
+><P
+>Network packets that are sent over the physical network transport
+layer communicate not via IP addresses but rather using the Media
+Access Control address, or MAC address. IP Addresses are currently
+32 bits in length and are typically presented as four (4) decimal
+numbers that are separated by a dot (or period). eg: 168.192.1.1</P
+><P
+>MAC Addresses use 48 bits (or 6 bytes) and are typically represented
+as two digit hexadecimal numbers separated by colons. eg:
+40:8e:0a:12:34:56</P
+><P
+>Every network interfrace must have an MAC address. Associated with
+a MAC address there may be one or more IP addresses. There is NO
+relationship between an IP address and a MAC address, all such assignments
+are arbitary or discretionary in nature. At the most basic level all
+network communications takes place using MAC addressing. Since MAC
+addresses must be globally unique, and generally remains fixed for
+any particular interface, the assignment of an IP address makes sense
+from a network management perspective. More than one IP address can
+be assigned per MAC address. One address must be the primary IP address,
+this is the address that will be returned in the ARP reply.</P
+><P
+>When a user or a process wants to communicate with another machine
+the protocol implementation ensures that the "machine name" or "host
+name" is resolved to an IP address in a manner that is controlled
+by the TCP/IP configuration control files. The file
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> is one such file.</P
+><P
+>When the IP address of the destination interface has been
+determined a protocol called ARP/RARP is used to identify
+the MAC address of the target interface. ARP stands for Address
+Resolution Protocol, and is a broadcast oriented method that
+uses UDP (User Datagram Protocol) to send a request to all
+interfaces on the local network segment using the all 1's MAC
+address. Network interfaces are programmed to respond to two
+MAC addresses only; their own unique address and the address
+ff:ff:ff:ff:ff:ff. The reply packet from an ARP request will
+contain the MAC address and the primary IP address for each
+interface.</P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> file is foundational to all
+Unix/Linux TCP/IP installations and as a minumum will contain
+the localhost and local network interface IP addresses and the
+primary names by which they are known within the local machine.
+This file helps to prime the pump so that a basic level of name
+resolution can exist before any other method of name resolution
+becomes available.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN279"
+>2.2.2. <TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></A
+></H2
+><P
+>This file tells the name resolution libraries:</P
+><P
+></P
+><UL
+><LI
+><P
+>The name of the domain to which the machine
+ belongs
+ </P
+></LI
+><LI
+><P
+>The name(s) of any domains that should be
+ automatically searched when trying to resolve unqualified
+ host names to their IP address
+ </P
+></LI
+><LI
+><P
+>The name or IP address of available Domain
+ Name Servers that may be asked to perform name to address
+ translation lookups
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN290"
+>2.2.3. <TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+></A
+></H2
+><P
+><TT
+CLASS="FILENAME"
+>/etc/host.conf</TT
+> is the primary means by
+which the setting in /etc/resolv.conf may be affected. It is a
+critical configuration file. This file controls the order by
+which name resolution may procede. The typical structure is:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> order hosts,bind
+ multi on</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>then both addresses should be returned. Please refer to the
+man page for host.conf for further details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN298"
+>2.2.4. <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+></A
+></H2
+><P
+>This file controls the actual name resolution targets. The
+file typically has resolver object specifications as follows:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> # /etc/nsswitch.conf
+ #
+ # Name Service Switch configuration file.
+ #
+
+ passwd: compat
+ # Alternative entries for password authentication are:
+ # passwd: compat files nis ldap winbind
+ shadow: compat
+ group: compat
+
+ hosts: files nis dns
+ # Alternative entries for host name resolution are:
+ # hosts: files dns nis nis+ hesoid db compat ldap wins
+ networks: nis files dns
+
+ ethers: nis files
+ protocols: nis files
+ rpc: nis files
+ services: nis files</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Of course, each of these mechanisms requires that the appropriate
+facilities and/or services are correctly configured.</P
+><P
+>It should be noted that unless a network request/message must be
+sent, TCP/IP networks are silent. All TCP/IP communications assumes a
+principal of speaking only when necessary.</P
+><P
+>Samba version 2.2.0 will add Linux support for extensions to
+the name service switch infrastructure so that linux clients will
+be able to obtain resolution of MS Windows NetBIOS names to IP
+Addresses. To gain this functionality Samba needs to be compiled
+with appropriate arguments to the make command (ie: <B
+CLASS="COMMAND"
+>make
+nsswitch/libnss_wins.so</B
+>). The resulting library should
+then be installed in the <TT
+CLASS="FILENAME"
+>/lib</TT
+> directory and
+the "wins" parameter needs to be added to the "hosts:" line in
+the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file. At this point it
+will be possible to ping any MS Windows machine by it's NetBIOS
+machine name, so long as that machine is within the workgroup to
+which both the samba machine and the MS Windows machine belong.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN310"
+>2.3. Name resolution as used within MS Windows networking</A
+></H1
+><P
+>MS Windows networking is predicated about the name each machine
+is given. This name is known variously (and inconsistently) as
+the "computer name", "machine name", "networking name", "netbios name",
+"SMB name". All terms mean the same thing with the exception of
+"netbios name" which can apply also to the name of the workgroup or the
+domain name. The terms "workgroup" and "domain" are really just a
+simply name with which the machine is associated. All NetBIOS names
+are exactly 16 characters in length. The 16th character is reserved.
+It is used to store a one byte value that indicates service level
+information for the NetBIOS name that is registered. A NetBIOS machine
+name is therefore registered for each service type that is provided by
+the client/server.</P
+><P
+>The following are typical NetBIOS name/service type registrations:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> Unique NetBIOS Names:
+ MACHINENAME&#60;00&#62; = Server Service is running on MACHINENAME
+ MACHINENAME&#60;03&#62; = Generic Machine Name (NetBIOS name)
+ MACHINENAME&#60;20&#62; = LanMan Server service is running on MACHINENAME
+ WORKGROUP&#60;1b&#62; = Domain Master Browser
+
+ Group Names:
+ WORKGROUP&#60;03&#62; = Generic Name registered by all members of WORKGROUP
+ WORKGROUP&#60;1c&#62; = Domain Controllers / Netlogon Servers
+ WORKGROUP&#60;1d&#62; = Local Master Browsers
+ WORKGROUP&#60;1e&#62; = Internet Name Resolvers</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>It should be noted that all NetBIOS machines register their own
+names as per the above. This is in vast contrast to TCP/IP
+installations where traditionally the system administrator will
+determine in the /etc/hosts or in the DNS database what names
+are associated with each IP address.</P
+><P
+>One further point of clarification should be noted, the <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+file and the DNS records do not provide the NetBIOS name type information
+that MS Windows clients depend on to locate the type of service that may
+be needed. An example of this is what happens when an MS Windows client
+wants to locate a domain logon server. It find this service and the IP
+address of a server that provides it by performing a lookup (via a
+NetBIOS broadcast) for enumeration of all machines that have
+registered the name type *&#60;1c&#62;. A logon request is then sent to each
+IP address that is returned in the enumerated list of IP addresses. Which
+ever machine first replies then ends up providing the logon services.</P
+><P
+>The name "workgroup" or "domain" really can be confusing since these
+have the added significance of indicating what is the security
+architecture of the MS Windows network. The term "workgroup" indicates
+that the primary nature of the network environment is that of a
+peer-to-peer design. In a WORKGROUP all machines are responsible for
+their own security, and generally such security is limited to use of
+just a password (known as SHARE MODE security). In most situations
+with peer-to-peer networking the users who control their own machines
+will simply opt to have no security at all. It is possible to have
+USER MODE security in a WORKGROUP environment, thus requiring use
+of a user name and a matching password.</P
+><P
+>MS Windows networking is thus predetermined to use machine names
+for all local and remote machine message passing. The protocol used is
+called Server Message Block (SMB) and this is implemented using
+the NetBIOS protocol (Network Basic Input Output System). NetBIOS can
+be encapsulated using LLC (Logical Link Control) protocol - in which case
+the resulting protocol is called NetBEUI (Network Basic Extended User
+Interface). NetBIOS can also be run over IPX (Internetworking Packet
+Exchange) protocol as used by Novell NetWare, and it can be run
+over TCP/IP protocols - in which case the resulting protocol is called
+NBT or NetBT, the NetBIOS over TCP/IP.</P
+><P
+>MS Windows machines use a complex array of name resolution mechanisms.
+Since we are primarily concerned with TCP/IP this demonstration is
+limited to this area.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN322"
+>2.3.1. The NetBIOS Name Cache</A
+></H2
+><P
+>All MS Windows machines employ an in memory buffer in which is
+stored the NetBIOS names and IP addresses for all external
+machines that that machine has communicated with over the
+past 10-15 minutes. It is more efficient to obtain an IP address
+for a machine from the local cache than it is to go through all the
+configured name resolution mechanisms.</P
+><P
+>If a machine whose name is in the local name cache has been shut
+down before the name had been expired and flushed from the cache, then
+an attempt to exchange a message with that machine will be subject
+to time-out delays. i.e.: Its name is in the cache, so a name resolution
+lookup will succeed, but the machine can not respond. This can be
+frustrating for users - but it is a characteristic of the protocol.</P
+><P
+>The MS Windows utility that allows examination of the NetBIOS
+name cache is called "nbtstat". The Samba equivalent of this
+is called "nmblookup".</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN327"
+>2.3.2. The LMHOSTS file</A
+></H2
+><P
+>This file is usually located in MS Windows NT 4.0 or
+2000 in <TT
+CLASS="FILENAME"
+>C:\WINNT\SYSTEM32\DRIVERS\ETC</TT
+> and contains
+the IP Address and the machine name in matched pairs. The
+<TT
+CLASS="FILENAME"
+>LMHOSTS</TT
+> file performs NetBIOS name
+to IP address mapping oriented.</P
+><P
+>It typically looks like:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> # Copyright (c) 1998 Microsoft Corp.
+ #
+ # This is a sample LMHOSTS file used by the Microsoft Wins Client (NetBIOS
+ # over TCP/IP) stack for Windows98
+ #
+ # This file contains the mappings of IP addresses to NT computernames
+ # (NetBIOS) names. Each entry should be kept on an individual line.
+ # The IP address should be placed in the first column followed by the
+ # corresponding computername. The address and the comptername
+ # should be separated by at least one space or tab. The "#" character
+ # is generally used to denote the start of a comment (see the exceptions
+ # below).
+ #
+ # This file is compatible with Microsoft LAN Manager 2.x TCP/IP lmhosts
+ # files and offers the following extensions:
+ #
+ # #PRE
+ # #DOM:&#60;domain&#62;
+ # #INCLUDE &#60;filename&#62;
+ # #BEGIN_ALTERNATE
+ # #END_ALTERNATE
+ # \0xnn (non-printing character support)
+ #
+ # Following any entry in the file with the characters "#PRE" will cause
+ # the entry to be preloaded into the name cache. By default, entries are
+ # not preloaded, but are parsed only after dynamic name resolution fails.
+ #
+ # Following an entry with the "#DOM:&#60;domain&#62;" tag will associate the
+ # entry with the domain specified by &#60;domain&#62;. This affects how the
+ # browser and logon services behave in TCP/IP environments. To preload
+ # the host name associated with #DOM entry, it is necessary to also add a
+ # #PRE to the line. The &#60;domain&#62; is always preloaded although it will not
+ # be shown when the name cache is viewed.
+ #
+ # Specifying "#INCLUDE &#60;filename&#62;" will force the RFC NetBIOS (NBT)
+ # software to seek the specified &#60;filename&#62; and parse it as if it were
+ # local. &#60;filename&#62; is generally a UNC-based name, allowing a
+ # centralized lmhosts file to be maintained on a server.
+ # It is ALWAYS necessary to provide a mapping for the IP address of the
+ # server prior to the #INCLUDE. This mapping must use the #PRE directive.
+ # In addtion the share "public" in the example below must be in the
+ # LanManServer list of "NullSessionShares" in order for client machines to
+ # be able to read the lmhosts file successfully. This key is under
+ # \machine\system\currentcontrolset\services\lanmanserver\parameters\nullsessionshares
+ # in the registry. Simply add "public" to the list found there.
+ #
+ # The #BEGIN_ and #END_ALTERNATE keywords allow multiple #INCLUDE
+ # statements to be grouped together. Any single successful include
+ # will cause the group to succeed.
+ #
+ # Finally, non-printing characters can be embedded in mappings by
+ # first surrounding the NetBIOS name in quotations, then using the
+ # \0xnn notation to specify a hex value for a non-printing character.
+ #
+ # The following example illustrates all of these extensions:
+ #
+ # 102.54.94.97 rhino #PRE #DOM:networking #net group's DC
+ # 102.54.94.102 "appname \0x14" #special app server
+ # 102.54.94.123 popular #PRE #source server
+ # 102.54.94.117 localsrv #PRE #needed for the include
+ #
+ # #BEGIN_ALTERNATE
+ # #INCLUDE \\localsrv\public\lmhosts
+ # #INCLUDE \\rhino\public\lmhosts
+ # #END_ALTERNATE
+ #
+ # In the above example, the "appname" server contains a special
+ # character in its name, the "popular" and "localsrv" server names are
+ # preloaded, and the "rhino" server name is specified so it can be used
+ # to later #INCLUDE a centrally maintained lmhosts file if the "localsrv"
+ # system is unavailable.
+ #
+ # Note that the whole file is parsed including comments on each lookup,
+ # so keeping the number of comments to a minimum will improve performance.
+ # Therefore it is not advisable to simply add lmhosts file entries onto the
+ # end of this file.</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN335"
+>2.3.3. HOSTS file</A
+></H2
+><P
+>This file is usually located in MS Windows NT 4.0 or 2000 in
+<TT
+CLASS="FILENAME"
+>C:\WINNT\SYSTEM32\DRIVERS\ETC</TT
+> and contains
+the IP Address and the IP hostname in matched pairs. It can be
+used by the name resolution infrastructure in MS Windows, depending
+on how the TCP/IP environment is configured. This file is in
+every way the equivalent of the Unix/Linux <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> file.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN340"
+>2.3.4. DNS Lookup</A
+></H2
+><P
+>This capability is configured in the TCP/IP setup area in the network
+configuration facility. If enabled an elaborate name resolution sequence
+is followed the precise nature of which isdependant on what the NetBIOS
+Node Type parameter is configured to. A Node Type of 0 means use
+NetBIOS broadcast (over UDP broadcast) is first used if the name
+that is the subject of a name lookup is not found in the NetBIOS name
+cache. If that fails then DNS, HOSTS and LMHOSTS are checked. If set to
+Node Type 8, then a NetBIOS Unicast (over UDP Unicast) is sent to the
+WINS Server to obtain a lookup before DNS, HOSTS, LMHOSTS, or broadcast
+lookup is used.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN343"
+>2.3.5. WINS Lookup</A
+></H2
+><P
+>A WINS (Windows Internet Name Server) service is the equivaent of the
+rfc1001/1002 specified NBNS (NetBIOS Name Server). A WINS server stores
+the names and IP addresses that are registered by a Windows client
+if the TCP/IP setup has been given at least one WINS Server IP Address.</P
+><P
+>To configure Samba to be a WINS server the following parameter needs
+to be added to the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> wins support = Yes</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>To configure Samba to use a WINS server the following parameters are
+needed in the smb.conf file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> wins support = No
+ wins server = xxx.xxx.xxx.xxx</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>where <TT
+CLASS="REPLACEABLE"
+><I
+>xxx.xxx.xxx.xxx</I
+></TT
+> is the IP address
+of the WINS server.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN355"
+>2.4. How browsing functions and how to deploy stable and
+dependable browsing using Samba</A
+></H1
+><P
+>As stated above, MS Windows machines register their NetBIOS names
+(i.e.: the machine name for each service type in operation) on start
+up. Also, as stated above, the exact method by which this name registration
+takes place is determined by whether or not the MS Windows client/server
+has been given a WINS server address, whether or not LMHOSTS lookup
+is enabled, or if DNS for NetBIOS name resolution is enabled, etc.</P
+><P
+>In the case where there is no WINS server all name registrations as
+well as name lookups are done by UDP broadcast. This isolates name
+resolution to the local subnet, unless LMHOSTS is used to list all
+names and IP addresses. In such situations Samba provides a means by
+which the samba server name may be forcibly injected into the browse
+list of a remote MS Windows network (using the "remote announce" parameter).</P
+><P
+>Where a WINS server is used, the MS Windows client will use UDP
+unicast to register with the WINS server. Such packets can be routed
+and thus WINS allows name resolution to function across routed networks.</P
+><P
+>During the startup process an election will take place to create a
+local master browser if one does not already exist. On each NetBIOS network
+one machine will be elected to function as the domain master browser. This
+domain browsing has nothing to do with MS security domain control.
+Instead, the domain master browser serves the role of contacting each local
+master browser (found by asking WINS or from LMHOSTS) and exchanging browse
+list contents. This way every master browser will eventually obtain a complete
+list of all machines that are on the network. Every 11-15 minutes an election
+is held to determine which machine will be the master browser. By the nature of
+the election criteria used, the machine with the highest uptime, or the
+most senior protocol version, or other criteria, will win the election
+as domain master browser.</P
+><P
+>Clients wishing to browse the network make use of this list, but also depend
+on the availability of correct name resolution to the respective IP
+address/addresses. </P
+><P
+>Any configuration that breaks name resolution and/or browsing intrinsics
+will annoy users because they will have to put up with protracted
+inability to use the network services.</P
+><P
+>Samba supports a feature that allows forced synchonisation
+of browse lists across routed networks using the "remote
+browse sync" parameter in the smb.conf file. This causes Samba
+to contact the local master browser on a remote network and
+to request browse list synchronisation. This effectively bridges
+two networks that are separated by routers. The two remote
+networks may use either broadcast based name resolution or WINS
+based name resolution, but it should be noted that the "remote
+browse sync" parameter provides browse list synchronisation - and
+that is distinct from name to address resolution, in other
+words, for cross subnet browsing to function correctly it is
+essential that a name to address resolution mechanism be provided.
+This mechanism could be via DNS, <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>,
+and so on.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN365"
+>2.5. MS Windows security options and how to configure
+Samba for seemless integration</A
+></H1
+><P
+>MS Windows clients may use encrypted passwords as part of a
+challenege/response authentication model (a.k.a. NTLMv1) or
+alone, or clear text strings for simple password based
+authentication. It should be realized that with the SMB
+protocol the password is passed over the network either
+in plain text or encrypted, but not both in the same
+authentication requets.</P
+><P
+>When encrypted passwords are used a password that has been
+entered by the user is encrypted in two ways:</P
+><P
+></P
+><UL
+><LI
+><P
+>An MD4 hash of the UNICODE of the password
+ string. This is known as the NT hash.
+ </P
+></LI
+><LI
+><P
+>The password is converted to upper case,
+ and then padded or trucated to 14 bytes. This string is
+ then appended with 5 bytes of NULL characters and split to
+ form two 56 bit DES keys to encrypt a "magic" 8 byte value.
+ The resulting 16 bytes for the LanMan hash.
+ </P
+></LI
+></UL
+><P
+>You should refer to the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>Password Encryption</A
+> chapter in this HOWTO collection
+for more details on the inner workings</P
+><P
+>MS Windows 95 pre-service pack 1, MS Windows NT versions 3.x
+and version 4.0 pre-service pack 3 will use either mode of
+password authentication. All versions of MS Windows that follow
+these versions no longer support plain text passwords by default.</P
+><P
+>MS Windows clients have a habit of dropping network mappings that
+have been idle for 10 minutes or longer. When the user attempts to
+use the mapped drive connection that has been dropped, the client
+re-establishes the connection using
+a cached copy of the password.</P
+><P
+>When Microsoft changed the default password mode, they dropped support for
+caching of the plain text password. This means that when the registry
+parameter is changed to re-enable use of plain text passwords it appears to
+work, but when a dropped mapping attempts to revalidate it will fail if
+the remote authentication server does not support encrypted passwords.
+This means that it is definitely not a good idea to re-enable plain text
+password support in such clients.</P
+><P
+>The following parameters can be used to work around the
+issue of Windows 9x client upper casing usernames and
+password before transmitting them to the SMB server
+when using clear text authentication.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> <A
+HREF="smb.conf.5.html#PASSWORDLEVEL"
+TARGET="_top"
+>passsword level</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>integer</I
+></TT
+>
+ <A
+HREF="smb.conf.5.html#USERNAMELEVEL"
+TARGET="_top"
+>username level</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>integer</I
+></TT
+></PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>By default Samba will lower case the username before attempting
+to lookup the user in the database of local system accounts.
+Because UNIX usernames conventionally only contain lower case
+character, the <TT
+CLASS="PARAMETER"
+><I
+>username level</I
+></TT
+> parameter
+is rarely even needed.</P
+><P
+>However, password on UNIX systems often make use of mixed case
+characters. This means that in order for a user on a Windows 9x
+client to connect to a Samba server using clear text authentication,
+the <TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+> must be set to the maximum
+number of upper case letter which <EM
+>could</EM
+> appear
+is a password. Note that is the server OS uses the traditional
+DES version of crypt(), then a <TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+>
+of 8 will result in case insensitive passwords as seen from Windows
+users. This will also result in longer login times as Samba
+hash to compute the permutations of the password string and
+try them one by one until a match is located (or all combinations fail).</P
+><P
+>The best option to adopt is to enable support for encrypted passwords
+where ever Samba is used. There are three configuration possibilities
+for support of encrypted passwords:</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN393"
+>2.5.1. Use MS Windows NT as an authentication server</A
+></H2
+><P
+>This method involves the additions of the following parameters
+in the smb.conf file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> encrypt passwords = Yes
+ security = server
+ password server = "NetBIOS_name_of_PDC"</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>There are two ways of identifying whether or not a username and
+password pair was valid or not. One uses the reply information provided
+as part of the authentication messaging process, the other uses
+just and error code.</P
+><P
+>The down-side of this mode of configuration is the fact that
+for security reasons Samba will send the password server a bogus
+username and a bogus password and if the remote server fails to
+reject the username and password pair then an alternative mode
+of identification of validation is used. Where a site uses password
+lock out after a certain number of failed authentication attempts
+this will result in user lockouts.</P
+><P
+>Use of this mode of authentication does require there to be
+a standard Unix account for the user, this account can be blocked
+to prevent logons by other than MS Windows clients.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN401"
+>2.5.2. Make Samba a member of an MS Windows NT security domain</A
+></H2
+><P
+>This method involves additon of the following paramters in the smb.conf file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> encrypt passwords = Yes
+ security = domain
+ workgroup = "name of NT domain"
+ password server = *</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The use of the "*" argument to "password server" will cause samba
+to locate the domain controller in a way analogous to the way
+this is done within MS Windows NT.</P
+><P
+>In order for this method to work the Samba server needs to join the
+MS Windows NT security domain. This is done as follows:</P
+><P
+></P
+><UL
+><LI
+><P
+>On the MS Windows NT domain controller using
+ the Server Manager add a machine account for the Samba server.
+ </P
+></LI
+><LI
+><P
+>Next, on the Linux system execute:
+ <B
+CLASS="COMMAND"
+>smbpasswd -r PDC_NAME -j DOMAIN_NAME</B
+>
+ </P
+></LI
+></UL
+><P
+>Use of this mode of authentication does require there to be
+a standard Unix account for the user in order to assign
+a uid once the account has been authenticated by the remote
+Windows DC. This account can be blocked to prevent logons by
+other than MS Windows clients by things such as setting an invalid
+shell in the <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry.</P
+><P
+>An alternative to assigning UIDs to Windows users on a
+Samba member server is presented in the <A
+HREF="winbind.html"
+TARGET="_top"
+>Winbind Overview</A
+> chapter in
+this HOWTO collection.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN418"
+>2.5.3. Configure Samba as an authentication server</A
+></H2
+><P
+>This mode of authentication demands that there be on the
+Unix/Linux system both a Unix style account as well as an
+smbpasswd entry for the user. The Unix system account can be
+locked if required as only the encrypted password will be
+used for SMB client authentication.</P
+><P
+>This method involves addition of the following parameters to
+the smb.conf file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## please refer to the Samba PDC HOWTO chapter later in
+## this collection for more details
+[global]
+ encrypt passwords = Yes
+ security = user
+ domain logons = Yes
+ ; an OS level of 33 or more is recommended
+ os level = 33
+
+[NETLOGON]
+ path = /somewhare/in/file/system
+ read only = yes</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>in order for this method to work a Unix system account needs
+to be created for each user, as well as for each MS Windows NT/2000
+machine. The following structure is required.</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN425"
+>2.5.3.1. Users</A
+></H3
+><P
+>A user account that may provide a home directory should be
+created. The following Linux system commands are typical of
+the procedure for creating an account.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> # useradd -s /bin/bash -d /home/"userid" -m "userid"
+ # passwd "userid"
+ Enter Password: &#60;pw&#62;
+
+ # smbpasswd -a "userid"
+ Enter Password: &#60;pw&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN430"
+>2.5.3.2. MS Windows NT Machine Accounts</A
+></H3
+><P
+>These are required only when Samba is used as a domain
+controller. Refer to the Samba-PDC-HOWTO for more details.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> # useradd -s /bin/false -d /dev/null "machine_name"\$
+ # passwd -l "machine_name"\$
+ # smbpasswd -a -m "machine_name"</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN435"
+>2.6. Conclusions</A
+></H1
+><P
+>Samba provides a flexible means to operate as...</P
+><P
+></P
+><UL
+><LI
+><P
+>A Stand-alone server - No special action is needed
+ other than to create user accounts. Stand-alone servers do NOT
+ provide network logon services, meaning that machines that use this
+ server do NOT perform a domain logon but instead make use only of
+ the MS Windows logon which is local to the MS Windows
+ workstation/server.
+ </P
+></LI
+><LI
+><P
+>An MS Windows NT 3.x/4.0 security domain member.
+ </P
+></LI
+><LI
+><P
+>An alternative to an MS Windows NT 3.x/4.0
+ Domain Controller.
+ </P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="PAM"
+>Chapter 3. Configuring PAM for distributed but centrally
+managed authentication</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN456"
+>3.1. Samba and PAM</A
+></H1
+><P
+>A number of Unix systems (eg: Sun Solaris), as well as the
+xxxxBSD family and Linux, now utilize the Pluggable Authentication
+Modules (PAM) facility to provide all authentication,
+authorization and resource control services. Prior to the
+introduction of PAM, a decision to use an alternative to
+the system password database (<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>)
+would require the provision of alternatives for all programs that provide
+security services. Such a choice would involve provision of
+alternatives to such programs as: <B
+CLASS="COMMAND"
+>login</B
+>,
+<B
+CLASS="COMMAND"
+>passwd</B
+>, <B
+CLASS="COMMAND"
+>chown</B
+>, etc.</P
+><P
+>PAM provides a mechanism that disconnects these security programs
+from the underlying authentication/authorization infrastructure.
+PAM is configured either through one file <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+> (Solaris),
+or by editing individual files that are located in <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+>.</P
+><P
+>The following is an example <TT
+CLASS="FILENAME"
+>/etc/pam.d/login</TT
+> configuration file.
+This example had all options been uncommented is probably not usable
+as it stacks many conditions before allowing successful completion
+of the login process. Essentially all conditions can be disabled
+by commenting them out except the calls to <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_securetty.so
+auth required pam_nologin.so
+# auth required pam_dialup.so
+# auth optional pam_mail.so
+auth required pam_pwdb.so shadow md5
+# account requisite pam_time.so
+account required pam_pwdb.so
+session required pam_pwdb.so
+# session optional pam_lastlog.so
+# password required pam_cracklib.so retry=3
+password required pam_pwdb.so shadow md5</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>PAM allows use of replacable modules. Those available on a
+sample system include:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>$ /bin/ls /lib/security
+pam_access.so pam_ftp.so pam_limits.so
+pam_ncp_auth.so pam_rhosts_auth.so pam_stress.so
+pam_cracklib.so pam_group.so pam_listfile.so
+pam_nologin.so pam_rootok.so pam_tally.so
+pam_deny.so pam_issue.so pam_mail.so
+pam_permit.so pam_securetty.so pam_time.so
+pam_dialup.so pam_lastlog.so pam_mkhomedir.so
+pam_pwdb.so pam_shells.so pam_unix.so
+pam_env.so pam_ldap.so pam_motd.so
+pam_radius.so pam_smbpass.so pam_unix_acct.so
+pam_wheel.so pam_unix_auth.so pam_unix_passwd.so
+pam_userdb.so pam_warn.so pam_unix_session.so</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The following example for the login program replaces the use of
+the <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+> module which uses the system
+password database (<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>,
+<TT
+CLASS="FILENAME"
+>/etc/shadow</TT
+>, <TT
+CLASS="FILENAME"
+>/etc/group</TT
+>) with
+the module <TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+> which uses the Samba
+database which contains the Microsoft MD4 encrypted password
+hashes. This database is stored in either
+<TT
+CLASS="FILENAME"
+>/usr/local/samba/private/smbpasswd</TT
+>,
+<TT
+CLASS="FILENAME"
+>/etc/samba/smbpasswd</TT
+>, or in
+<TT
+CLASS="FILENAME"
+>/etc/samba.d/smbpasswd</TT
+>, depending on the
+Samba implementation for your Unix/Linux system. The
+<TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+> module is provided by
+Samba version 2.2.1 or later. It can be compiled by specifying the
+<B
+CLASS="COMMAND"
+>--with-pam_smbpass</B
+> options when running Samba's
+<TT
+CLASS="FILENAME"
+>configure</TT
+> script. For more information
+on the <TT
+CLASS="FILENAME"
+>pam_smbpass</TT
+> module, see the documentation
+in the <TT
+CLASS="FILENAME"
+>source/pam_smbpass</TT
+> directory of the Samba
+source distribution.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `login' service
+#
+auth required pam_smbpass.so nodelay
+account required pam_smbpass.so nodelay
+session required pam_smbpass.so nodelay
+password required pam_smbpass.so nodelay</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The following is the PAM configuration file for a particular
+Linux system. The default condition uses <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_pwdb.so nullok nodelay shadow audit
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_pwdb.so shadow md5</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>In the following example the decision has been made to use the
+smbpasswd database even for basic samba authentication. Such a
+decision could also be made for the passwd program and would
+thus allow the smbpasswd passwords to be changed using the passwd
+program.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#%PAM-1.0
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_smbpass.so nodelay
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_smbpass.so nodelay smbconf=/etc/samba.d/smb.conf</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Note: PAM allows stacking of authentication mechanisms. It is
+also possible to pass information obtained within on PAM module through
+to the next module in the PAM stack. Please refer to the documentation for
+your particular system implementation for details regarding the specific
+capabilities of PAM in this environment. Some Linux implmentations also
+provide the <TT
+CLASS="FILENAME"
+>pam_stack.so</TT
+> module that allows all
+authentication to be configured in a single central file. The
+<TT
+CLASS="FILENAME"
+>pam_stack.so</TT
+> method has some very devoted followers
+on the basis that it allows for easier administration. As with all issues in
+life though, every decision makes trade-offs, so you may want examine the
+PAM documentation for further helpful information.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN500"
+>3.2. Distributed Authentication</A
+></H1
+><P
+>The astute administrator will realize from this that the
+combination of <TT
+CLASS="FILENAME"
+>pam_smbpass.so</TT
+>,
+<B
+CLASS="COMMAND"
+>winbindd</B
+>, and <B
+CLASS="COMMAND"
+>rsync</B
+> (see
+<A
+HREF="http://rsync.samba.org/"
+TARGET="_top"
+>http://rsync.samba.org/</A
+>)
+will allow the establishment of a centrally managed, distributed
+user/password database that can also be used by all
+PAM (eg: Linux) aware programs and applications. This arrangement
+can have particularly potent advantages compared with the
+use of Microsoft Active Directory Service (ADS) in so far as
+reduction of wide area network authentication traffic.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN507"
+>3.3. PAM Configuration in smb.conf</A
+></H1
+><P
+>There is an option in smb.conf called <A
+HREF="smb.conf.5.html#OBEYPAMRESTRICTIONS"
+TARGET="_top"
+>obey pam restrictions</A
+>.
+The following is from the on-line help for this option in SWAT;</P
+><P
+>When Samba 2.2 is configure to enable PAM support (i.e.
+<TT
+CLASS="CONSTANT"
+>--with-pam</TT
+>), this parameter will
+control whether or not Samba should obey PAM's account
+and session management directives. The default behavior
+is to use PAM for clear text authentication only and to
+ignore any account or session management. Note that Samba always
+ignores PAM for authentication in the case of
+<A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>encrypt passwords = yes</A
+>.
+The reason is that PAM modules cannot support the challenge/response
+authentication mechanism needed in the presence of SMB
+password encryption. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>obey pam restrictions = no</B
+></P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="MSDFS"
+>Chapter 4. Hosting a Microsoft Distributed File System tree on Samba</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN527"
+>4.1. Instructions</A
+></H1
+><P
+>The Distributed File System (or Dfs) provides a means of
+ separating the logical view of files and directories that users
+ see from the actual physical locations of these resources on the
+ network. It allows for higher availability, smoother storage expansion,
+ load balancing etc. For more information about Dfs, refer to <A
+HREF="http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp"
+TARGET="_top"
+> Microsoft documentation</A
+>. </P
+><P
+>This document explains how to host a Dfs tree on a Unix
+ machine (for Dfs-aware clients to browse) using Samba.</P
+><P
+>To enable SMB-based DFS for Samba, configure it with the
+ <TT
+CLASS="PARAMETER"
+><I
+>--with-msdfs</I
+></TT
+> option. Once built, a
+ Samba server can be made a Dfs server by setting the global
+ boolean <A
+HREF="smb.conf.5.html#HOSTMSDFS"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> host msdfs</I
+></TT
+></A
+> parameter in the <TT
+CLASS="FILENAME"
+>smb.conf
+ </TT
+> file. You designate a share as a Dfs root using the share
+ level boolean <A
+HREF="smb.conf.5.html#MSDFSROOT"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> msdfs root</I
+></TT
+></A
+> parameter. A Dfs root directory on
+ Samba hosts Dfs links in the form of symbolic links that point
+ to other servers. For example, a symbolic link
+ <TT
+CLASS="FILENAME"
+>junction-&#62;msdfs:storage1\share1</TT
+> in
+ the share directory acts as the Dfs junction. When Dfs-aware
+ clients attempt to access the junction link, they are redirected
+ to the storage location (in this case, \\storage1\share1).</P
+><P
+>Dfs trees on Samba work with all Dfs-aware clients ranging
+ from Windows 95 to 2000.</P
+><P
+>Here's an example of setting up a Dfs tree on a Samba
+ server.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+># The smb.conf file:
+[global]
+ netbios name = SAMBA
+ host msdfs = yes
+
+[dfs]
+ path = /export/dfsroot
+ msdfs root = yes
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>In the /export/dfsroot directory we set up our dfs links to
+ other servers on the network.</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>cd /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>chown root /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>chmod 755 /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>ln -s msdfs:storageA\\shareA linka</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>ln -s msdfs:serverB\\share,serverC\\share linkb</B
+></TT
+></P
+><P
+>You should set up the permissions and ownership of
+ the directory acting as the Dfs root such that only designated
+ users can create, delete or modify the msdfs links. Also note
+ that symlink names should be all lowercase. This limitation exists
+ to have Samba avoid trying all the case combinations to get at
+ the link name. Finally set up the symbolic links to point to the
+ network shares you want, and start Samba.</P
+><P
+>Users on Dfs-aware clients can now browse the Dfs tree
+ on the Samba server at \\samba\dfs. Accessing
+ links linka or linkb (which appear as directories to the client)
+ takes users directly to the appropriate shares on the network.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN562"
+>4.1.1. Notes</A
+></H2
+><P
+></P
+><UL
+><LI
+><P
+>Windows clients need to be rebooted
+ if a previously mounted non-dfs share is made a dfs
+ root or vice versa. A better way is to introduce a
+ new share and make it the dfs root.</P
+></LI
+><LI
+><P
+>Currently there's a restriction that msdfs
+ symlink names should all be lowercase.</P
+></LI
+><LI
+><P
+>For security purposes, the directory
+ acting as the root of the Dfs tree should have ownership
+ and permissions set so that only designated users can
+ modify the symbolic links in the directory.</P
+></LI
+></UL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="UNIX-PERMISSIONS"
+>Chapter 5. UNIX Permission Bits and Windows NT Access Control Lists</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN582"
+>5.1. Viewing and changing UNIX permissions using the NT
+ security dialogs</A
+></H1
+><P
+>New in the Samba 2.0.4 release is the ability for Windows
+ NT clients to use their native security settings dialog box to
+ view and modify the underlying UNIX permissions.</P
+><P
+>Note that this ability is careful not to compromise
+ the security of the UNIX host Samba is running on, and
+ still obeys all the file permission rules that a Samba
+ administrator can set.</P
+><P
+>In Samba 2.0.4 and above the default value of the
+ parameter <A
+HREF="smb.conf.5.html#NTACLSUPPORT"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> nt acl support</I
+></TT
+></A
+> has been changed from
+ <TT
+CLASS="CONSTANT"
+>false</TT
+> to <TT
+CLASS="CONSTANT"
+>true</TT
+>, so
+ manipulation of permissions is turned on by default.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN591"
+>5.2. How to view file security on a Samba share</A
+></H1
+><P
+>From an NT 4.0 client, single-click with the right
+ mouse button on any file or directory in a Samba mounted
+ drive letter or UNC path. When the menu pops-up, click
+ on the <EM
+>Properties</EM
+> entry at the bottom of
+ the menu. This brings up the normal file properties dialog
+ box, but with Samba 2.0.4 this will have a new tab along the top
+ marked <EM
+>Security</EM
+>. Click on this tab and you
+ will see three buttons, <EM
+>Permissions</EM
+>,
+ <EM
+>Auditing</EM
+>, and <EM
+>Ownership</EM
+>.
+ The <EM
+>Auditing</EM
+> button will cause either
+ an error message <SPAN
+CLASS="ERRORNAME"
+>A requested privilege is not held
+ by the client</SPAN
+> to appear if the user is not the
+ NT Administrator, or a dialog which is intended to allow an
+ Administrator to add auditing requirements to a file if the
+ user is logged on as the NT Administrator. This dialog is
+ non-functional with a Samba share at this time, as the only
+ useful button, the <B
+CLASS="COMMAND"
+>Add</B
+> button will not currently
+ allow a list of users to be seen.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN602"
+>5.3. Viewing file ownership</A
+></H1
+><P
+>Clicking on the <B
+CLASS="COMMAND"
+>"Ownership"</B
+> button
+ brings up a dialog box telling you who owns the given file. The
+ owner name will be of the form :</P
+><P
+><B
+CLASS="COMMAND"
+>"SERVER\user (Long name)"</B
+></P
+><P
+>Where <TT
+CLASS="REPLACEABLE"
+><I
+>SERVER</I
+></TT
+> is the NetBIOS name of
+ the Samba server, <TT
+CLASS="REPLACEABLE"
+><I
+>user</I
+></TT
+> is the user name of
+ the UNIX user who owns the file, and <TT
+CLASS="REPLACEABLE"
+><I
+>(Long name)</I
+></TT
+>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database). Click on the <B
+CLASS="COMMAND"
+>Close
+ </B
+> button to remove this dialog.</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then the file owner will
+ be shown as the NT user <B
+CLASS="COMMAND"
+>"Everyone"</B
+>.</P
+><P
+>The <B
+CLASS="COMMAND"
+>Take Ownership</B
+> button will not allow
+ you to change the ownership of this file to yourself (clicking on
+ it will display a dialog box complaining that the user you are
+ currently logged onto the NT client cannot be found). The reason
+ for this is that changing the ownership of a file is a privileged
+ operation in UNIX, available only to the <EM
+>root</EM
+>
+ user. As clicking on this button causes NT to attempt to change
+ the ownership of a file to the current user logged into the NT
+ client this will not work with Samba at this time.</P
+><P
+>There is an NT chown command that will work with Samba
+ and allow a user with Administrator privilege connected
+ to a Samba 2.0.4 server as root to change the ownership of
+ files on both a local NTFS filesystem or remote mounted NTFS
+ or Samba drive. This is available as part of the <EM
+>Seclib
+ </EM
+> NT security library written by Jeremy Allison of
+ the Samba Team, available from the main Samba ftp site.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN622"
+>5.4. Viewing file or directory permissions</A
+></H1
+><P
+>The third button is the <B
+CLASS="COMMAND"
+>"Permissions"</B
+>
+ button. Clicking on this brings up a dialog box that shows both
+ the permissions and the UNIX owner of the file or directory.
+ The owner is displayed in the form :</P
+><P
+><B
+CLASS="COMMAND"
+>"SERVER\user (Long name)"</B
+></P
+><P
+>Where <TT
+CLASS="REPLACEABLE"
+><I
+>SERVER</I
+></TT
+> is the NetBIOS name of
+ the Samba server, <TT
+CLASS="REPLACEABLE"
+><I
+>user</I
+></TT
+> is the user name of
+ the UNIX user who owns the file, and <TT
+CLASS="REPLACEABLE"
+><I
+>(Long name)</I
+></TT
+>
+ is the descriptive string identifying the user (normally found in the
+ GECOS field of the UNIX password database).</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then the file owner will
+ be shown as the NT user <B
+CLASS="COMMAND"
+>"Everyone"</B
+> and the
+ permissions will be shown as NT "Full Control".</P
+><P
+>The permissions field is displayed differently for files
+ and directories, so I'll describe the way file permissions
+ are displayed first.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN637"
+>5.4.1. File Permissions</A
+></H2
+><P
+>The standard UNIX user/group/world triple and
+ the corresponding "read", "write", "execute" permissions
+ triples are mapped by Samba into a three element NT ACL
+ with the 'r', 'w', and 'x' bits mapped into the corresponding
+ NT permissions. The UNIX world permissions are mapped into
+ the global NT group <B
+CLASS="COMMAND"
+>Everyone</B
+>, followed
+ by the list of permissions allowed for UNIX world. The UNIX
+ owner and group permissions are displayed as an NT
+ <B
+CLASS="COMMAND"
+>user</B
+> icon and an NT <B
+CLASS="COMMAND"
+>local
+ group</B
+> icon respectively followed by the list
+ of permissions allowed for the UNIX user and group.</P
+><P
+>As many UNIX permission sets don't map into common
+ NT names such as <B
+CLASS="COMMAND"
+>"read"</B
+>, <B
+CLASS="COMMAND"
+> "change"</B
+> or <B
+CLASS="COMMAND"
+>"full control"</B
+> then
+ usually the permissions will be prefixed by the words <B
+CLASS="COMMAND"
+> "Special Access"</B
+> in the NT display list.</P
+><P
+>But what happens if the file has no permissions allowed
+ for a particular UNIX user group or world component ? In order
+ to allow "no permissions" to be seen and modified then Samba
+ overloads the NT <B
+CLASS="COMMAND"
+>"Take Ownership"</B
+> ACL attribute
+ (which has no meaning in UNIX) and reports a component with
+ no permissions as having the NT <B
+CLASS="COMMAND"
+>"O"</B
+> bit set.
+ This was chosen of course to make it look like a zero, meaning
+ zero permissions. More details on the decision behind this will
+ be given below.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN651"
+>5.4.2. Directory Permissions</A
+></H2
+><P
+>Directories on an NT NTFS file system have two
+ different sets of permissions. The first set of permissions
+ is the ACL set on the directory itself, this is usually displayed
+ in the first set of parentheses in the normal <B
+CLASS="COMMAND"
+>"RW"</B
+>
+ NT style. This first set of permissions is created by Samba in
+ exactly the same way as normal file permissions are, described
+ above, and is displayed in the same way.</P
+><P
+>The second set of directory permissions has no real meaning
+ in the UNIX permissions world and represents the <B
+CLASS="COMMAND"
+> "inherited"</B
+> permissions that any file created within
+ this directory would inherit.</P
+><P
+>Samba synthesises these inherited permissions for NT by
+ returning as an NT ACL the UNIX permission mode that a new file
+ created by Samba on this share would receive.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN658"
+>5.5. Modifying file or directory permissions</A
+></H1
+><P
+>Modifying file and directory permissions is as simple
+ as changing the displayed permissions in the dialog box, and
+ clicking the <B
+CLASS="COMMAND"
+>OK</B
+> button. However, there are
+ limitations that a user needs to be aware of, and also interactions
+ with the standard Samba permission masks and mapping of DOS
+ attributes that need to also be taken into account.</P
+><P
+>If the parameter <TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+>
+ is set to <TT
+CLASS="CONSTANT"
+>false</TT
+> then any attempt to set
+ security permissions will fail with an <B
+CLASS="COMMAND"
+>"Access Denied"
+ </B
+> message.</P
+><P
+>The first thing to note is that the <B
+CLASS="COMMAND"
+>"Add"</B
+>
+ button will not return a list of users in Samba 2.0.4 (it will give
+ an error message of <B
+CLASS="COMMAND"
+>"The remote procedure call failed
+ and did not execute"</B
+>). This means that you can only
+ manipulate the current user/group/world permissions listed in
+ the dialog box. This actually works quite well as these are the
+ only permissions that UNIX actually has.</P
+><P
+>If a permission triple (either user, group, or world)
+ is removed from the list of permissions in the NT dialog box,
+ then when the <B
+CLASS="COMMAND"
+>"OK"</B
+> button is pressed it will
+ be applied as "no permissions" on the UNIX side. If you then
+ view the permissions again the "no permissions" entry will appear
+ as the NT <B
+CLASS="COMMAND"
+>"O"</B
+> flag, as described above. This
+ allows you to add permissions back to a file or directory once
+ you have removed them from a triple component.</P
+><P
+>As UNIX supports only the "r", "w" and "x" bits of
+ an NT ACL then if other NT security attributes such as "Delete
+ access" are selected then they will be ignored when applied on
+ the Samba server.</P
+><P
+>When setting permissions on a directory the second
+ set of permissions (in the second set of parentheses) is
+ by default applied to all files within that directory. If this
+ is not what you want you must uncheck the <B
+CLASS="COMMAND"
+>"Replace
+ permissions on existing files"</B
+> checkbox in the NT
+ dialog before clicking <B
+CLASS="COMMAND"
+>"OK"</B
+>.</P
+><P
+>If you wish to remove all permissions from a
+ user/group/world component then you may either highlight the
+ component and click the <B
+CLASS="COMMAND"
+>"Remove"</B
+> button,
+ or set the component to only have the special <B
+CLASS="COMMAND"
+>"Take
+ Ownership"</B
+> permission (displayed as <B
+CLASS="COMMAND"
+>"O"
+ </B
+>) highlighted.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN680"
+>5.6. Interaction with the standard Samba create mask
+ parameters</A
+></H1
+><P
+>Note that with Samba 2.0.5 there are four new parameters
+ to control this interaction. These are :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory security mode</I
+></TT
+></P
+><P
+>Once a user clicks <B
+CLASS="COMMAND"
+>"OK"</B
+> to apply the
+ permissions Samba maps the given permissions into a user/group/world
+ r/w/x triple set, and then will check the changed permissions for a
+ file against the bits set in the <A
+HREF="smb.conf.5.html#SECURITYMASK"
+TARGET="_top"
+>
+ <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+> parameter. Any bits that
+ were changed that are not set to '1' in this parameter are left alone
+ in the file permissions.</P
+><P
+>Essentially, zero bits in the <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+>
+ mask may be treated as a set of bits the user is <EM
+>not</EM
+>
+ allowed to change, and one bits are those the user is allowed to change.
+ </P
+><P
+>If not set explicitly this parameter is set to the same value as
+ the <A
+HREF="smb.conf.5.html#CREATEMASK"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>create mask
+ </I
+></TT
+></A
+> parameter to provide compatibility with Samba 2.0.4
+ where this permission change facility was introduced. To allow a user to
+ modify all the user/group/world permissions on a file, set this parameter
+ to 0777.</P
+><P
+>Next Samba checks the changed permissions for a file against
+ the bits set in the <A
+HREF="smb.conf.5.html#FORCESECURITYMODE"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></A
+> parameter. Any bits
+ that were changed that correspond to bits set to '1' in this parameter
+ are forced to be set.</P
+><P
+>Essentially, bits set in the <TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+> parameter may be treated as a set of bits that, when
+ modifying security on a file, the user has always set to be 'on'.</P
+><P
+>If not set explicitly this parameter is set to the same value
+ as the <A
+HREF="smb.conf.5.html#FORCECREATEMODE"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ create mode</I
+></TT
+></A
+> parameter to provide compatibility
+ with Samba 2.0.4 where the permission change facility was introduced.
+ To allow a user to modify all the user/group/world permissions on a file
+ with no restrictions set this parameter to 000.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>force
+ security mode</I
+></TT
+> parameters are applied to the change
+ request in that order.</P
+><P
+>For a directory Samba will perform the same operations as
+ described above for a file except using the parameter <TT
+CLASS="PARAMETER"
+><I
+> directory security mask</I
+></TT
+> instead of <TT
+CLASS="PARAMETER"
+><I
+>security
+ mask</I
+></TT
+>, and <TT
+CLASS="PARAMETER"
+><I
+>force directory security mode
+ </I
+></TT
+> parameter instead of <TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+>.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+> parameter
+ by default is set to the same value as the <TT
+CLASS="PARAMETER"
+><I
+>directory mask
+ </I
+></TT
+> parameter and the <TT
+CLASS="PARAMETER"
+><I
+>force directory security
+ mode</I
+></TT
+> parameter by default is set to the same value as
+ the <TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+> parameter to provide
+ compatibility with Samba 2.0.4 where the permission change facility
+ was introduced.</P
+><P
+>In this way Samba enforces the permission restrictions that
+ an administrator can set on a Samba share, whilst still allowing users
+ to modify the permission bits within that restriction.</P
+><P
+>If you want to set up a share that allows users full control
+ in modifying the permission bits on their files and directories and
+ doesn't force any particular bits to be set 'on', then set the following
+ parameters in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+></A
+> file in that share specific section :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>security mask = 0777</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode = 0</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask = 0777</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory security mode = 0</I
+></TT
+></P
+><P
+>As described, in Samba 2.0.4 the parameters :</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>directory mask</I
+></TT
+></P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+></P
+><P
+>were used instead of the parameters discussed here.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN744"
+>5.7. Interaction with the standard Samba file attribute
+ mapping</A
+></H1
+><P
+>Samba maps some of the DOS attribute bits (such as "read
+ only") into the UNIX permissions of a file. This means there can
+ be a conflict between the permission bits set via the security
+ dialog and the permission bits set by the file attribute mapping.
+ </P
+><P
+>One way this can show up is if a file has no UNIX read access
+ for the owner it will show up as "read only" in the standard
+ file attributes tabbed dialog. Unfortunately this dialog is
+ the same one that contains the security info in another tab.</P
+><P
+>What this can mean is that if the owner changes the permissions
+ to allow themselves read access using the security dialog, clicks
+ <B
+CLASS="COMMAND"
+>"OK"</B
+> to get back to the standard attributes tab
+ dialog, and then clicks <B
+CLASS="COMMAND"
+>"OK"</B
+> on that dialog, then
+ NT will set the file permissions back to read-only (as that is what
+ the attributes still say in the dialog). This means that after setting
+ permissions and clicking <B
+CLASS="COMMAND"
+>"OK"</B
+> to get back to the
+ attributes dialog you should always hit <B
+CLASS="COMMAND"
+>"Cancel"</B
+>
+ rather than <B
+CLASS="COMMAND"
+>"OK"</B
+> to ensure that your changes
+ are not overridden.</P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="PRINTING"
+>Chapter 6. Printing Support in Samba 2.2.x</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN765"
+>6.1. Introduction</A
+></H1
+><P
+>Beginning with the 2.2.0 release, Samba supports
+the native Windows NT printing mechanisms implemented via
+MS-RPC (i.e. the SPOOLSS named pipe). Previous versions of
+Samba only supported LanMan printing calls.</P
+><P
+>The additional functionality provided by the new
+SPOOLSS support includes:</P
+><P
+></P
+><UL
+><LI
+><P
+>Support for downloading printer driver
+ files to Windows 95/98/NT/2000 clients upon demand.
+ </P
+></LI
+><LI
+><P
+>Uploading of printer drivers via the
+ Windows NT Add Printer Wizard (APW) or the
+ Imprints tool set (refer to <A
+HREF="http://imprints.sourceforge.net"
+TARGET="_top"
+>http://imprints.sourceforge.net</A
+>).
+ </P
+></LI
+><LI
+><P
+>Support for the native MS-RPC printing
+ calls such as StartDocPrinter, EnumJobs(), etc... (See
+ the MSDN documentation at <A
+HREF="http://msdn.microsoft.com/"
+TARGET="_top"
+>http://msdn.microsoft.com/</A
+>
+ for more information on the Win32 printing API)
+ </P
+></LI
+><LI
+><P
+>Support for NT Access Control Lists (ACL)
+ on printer objects</P
+></LI
+><LI
+><P
+>Improved support for printer queue manipulation
+ through the use of an internal databases for spooled job
+ information</P
+></LI
+></UL
+><P
+>There has been some initial confusion about what all this means
+and whether or not it is a requirement for printer drivers to be
+installed on a Samba host in order to support printing from Windows
+clients. A bug existed in Samba 2.2.0 which made Windows NT/2000 clients
+require that the Samba server possess a valid driver for the printer.
+This is fixed in Samba 2.2.1 and once again, Windows NT/2000 clients
+can use the local APW for installing drivers to be used with a Samba
+served printer. This is the same behavior exhibited by Windows 9x clients.
+As a side note, Samba does not use these drivers in any way to process
+spooled files. They are utilized entirely by the clients.</P
+><P
+>The following MS KB article, may be of some help if you are dealing with
+Windows 2000 clients: <EM
+>How to Add Printers with No User
+Interaction in Windows 2000</EM
+></P
+><P
+><A
+HREF="http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP"
+TARGET="_top"
+>http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN787"
+>6.2. Configuration</A
+></H1
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>[print$] vs. [printer$]</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>Previous versions of Samba recommended using a share named [printer$].
+This name was taken from the printer$ service created by Windows 9x
+clients when a printer was shared. Windows 9x printer servers always have
+a printer$ service which provides read-only access via no
+password in order to support printer driver downloads.</P
+><P
+>However, the initial implementation allowed for a
+parameter named <TT
+CLASS="PARAMETER"
+><I
+>printer driver location</I
+></TT
+>
+to be used on a per share basis to specify the location of
+the driver files associated with that printer. Another
+parameter named <TT
+CLASS="PARAMETER"
+><I
+>printer driver</I
+></TT
+> provided
+a means of defining the printer driver name to be sent to
+the client.</P
+><P
+>These parameters, including <TT
+CLASS="PARAMETER"
+><I
+>printer driver
+file</I
+></TT
+> parameter, are being deprecated and should not
+be used in new installations. For more information on this change,
+you should refer to the <A
+HREF="#MIGRATION"
+>Migration section</A
+>
+of this document.</P
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN798"
+>6.2.1. Creating [print$]</A
+></H2
+><P
+>In order to support the uploading of printer driver
+files, you must first configure a file share named [print$].
+The name of this share is hard coded in Samba's internals so
+the name is very important (print$ is the service used by
+Windows NT print servers to provide support for printer driver
+download).</P
+><P
+>You should modify the server's smb.conf file to add the global
+parameters and to create the
+following file share (of course, some of the parameter values,
+such as 'path' are arbitrary and should be replaced with
+appropriate values for your site):</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ ; members of the ntadmin group should be able
+ ; to add drivers and set printer properties
+ ; root is implicitly a 'printer admin'
+ printer admin = @ntadmin
+
+[print$]
+ path = /usr/local/samba/printers
+ guest ok = yes
+ browseable = yes
+ read only = yes
+ ; since this share is configured as read only, then we need
+ ; a 'write list'. Check the file system permissions to make
+ ; sure this account can copy files to the share. If this
+ ; is setup to a non-root account, then it should also exist
+ ; as a 'printer admin'
+ write list = @ntadmin,root</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The <A
+HREF="smb.conf.5.html#WRITELIST"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>write list</I
+></TT
+></A
+> is used to allow administrative
+level user accounts to have write access in order to update files
+on the share. See the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)
+man page</A
+> for more information on configuring file shares.</P
+><P
+>The requirement for <A
+HREF="smb.conf.5.html#GUESTOK"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>guest
+ok = yes</B
+></A
+> depends upon how your
+site is configured. If users will be guaranteed to have
+an account on the Samba host, then this is a non-issue.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Author's Note: </B
+>The non-issue is that if all your Windows NT users are guaranteed to be
+authenticated by the Samba server (such as a domain member server and the NT
+user has already been validated by the Domain Controller in
+order to logon to the Windows NT console), then guest access
+is not necessary. Of course, in a workgroup environment where
+you just want to be able to print without worrying about
+silly accounts and security, then configure the share for
+guest access. You'll probably want to add <A
+HREF="smb.conf.5.html#MAPTOGUEST"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>map to guest = Bad User</B
+></A
+> in the [global] section as well. Make sure
+you understand what this parameter does before using it
+though. --jerry</P
+></BLOCKQUOTE
+></DIV
+><P
+>In order for a Windows NT print server to support
+the downloading of driver files by multiple client architectures,
+it must create subdirectories within the [print$] service
+which correspond to each of the supported client architectures.
+Samba follows this model as well.</P
+><P
+>Next create the directory tree below the [print$] share
+for each architecture you wish to support.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[print$]-----
+ |-W32X86 ; "Windows NT x86"
+ |-WIN40 ; "Windows 95/98"
+ |-W32ALPHA ; "Windows NT Alpha_AXP"
+ |-W32MIPS ; "Windows NT R4000"
+ |-W32PPC ; "Windows NT PowerPC"</PRE
+></TD
+></TR
+></TABLE
+></P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>ATTENTION! REQUIRED PERMISSIONS</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>In order to currently add a new driver to you Samba host,
+one of two conditions must hold true:</P
+><P
+></P
+><UL
+><LI
+><P
+>The account used to connect to the Samba host
+ must have a uid of 0 (i.e. a root account)</P
+></LI
+><LI
+><P
+>The account used to connect to the Samba host
+ must be a member of the <A
+HREF="smb.conf.5.html#PRINTERADMIN"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>printer
+ admin</I
+></TT
+></A
+> list.</P
+></LI
+></UL
+><P
+>Of course, the connected account must still possess access
+to add files to the subdirectories beneath [print$]. Remember
+that all file shares are set to 'read only' by default.</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>Once you have created the required [print$] service and
+associated subdirectories, simply log onto the Samba server using
+a root (or <TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+>) account
+from a Windows NT 4.0/2k client. Open "Network Neighbourhood" or
+"My Network Places" and browse for the Samba host. Once you have located
+the server, navigate to the "Printers..." folder.
+You should see an initial listing of printers
+that matches the printer shares defined on your Samba host.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN833"
+>6.2.2. Setting Drivers for Existing Printers</A
+></H2
+><P
+>The initial listing of printers in the Samba host's
+Printers folder will have no real printer driver assigned
+to them. By default, in Samba 2.2.0 this driver name was set to
+<EM
+>NO PRINTER DRIVER AVAILABLE FOR THIS PRINTER</EM
+>.
+Later versions changed this to a NULL string to allow the use
+tof the local Add Printer Wizard on NT/2000 clients.
+Attempting to view the printer properties for a printer
+which has this default driver assigned will result in
+the error message:</P
+><P
+><EM
+>Device settings cannot be displayed. The driver
+for the specified printer is not installed, only spooler
+properties will be displayed. Do you want to install the
+driver now?</EM
+></P
+><P
+>Click <EM
+>No</EM
+> in the error dialog and you will be presented with
+the printer properties window. The way assign a driver to a
+printer is to either</P
+><P
+></P
+><UL
+><LI
+><P
+>Use the "New Driver..." button to install
+ a new printer driver, or</P
+></LI
+><LI
+><P
+>Select a driver from the popup list of
+ installed drivers. Initially this list will be empty.</P
+></LI
+></UL
+><P
+>If you wish to install printer drivers for client
+operating systems other than "Windows NT x86", you will need
+to use the "Sharing" tab of the printer properties dialog.</P
+><P
+>Assuming you have connected with a root account, you
+will also be able modify other printer properties such as
+ACLs and device settings using this dialog box.</P
+><P
+>A few closing comments for this section, it is possible
+on a Windows NT print server to have printers
+listed in the Printers folder which are not shared. Samba does
+not make this distinction. By definition, the only printers of
+which Samba is aware are those which are specified as shares in
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.</P
+><P
+>Another interesting side note is that Windows NT clients do
+not use the SMB printer share, but rather can print directly
+to any printer on another Windows NT host using MS-RPC. This
+of course assumes that the printing client has the necessary
+privileges on the remote host serving the printer. The default
+permissions assigned by Windows NT to a printer gives the "Print"
+permissions to the "Everyone" well-known group.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN851"
+>6.2.3. DeviceModes and New Printers</A
+></H2
+><P
+>In order for a printer to be truly usbla eby a Windows NT/2k/XP client,
+it must posses:</P
+><P
+></P
+><UL
+><LI
+><P
+>a valid Device Mode generated by the driver for the printer, and</P
+></LI
+><LI
+><P
+>a complete set of PrinterDriverData generated by the driver.</P
+></LI
+></UL
+><P
+>If either one of these is incomplete, the clients can produce less than optimal
+output at best or in the worst cases, unreadable garbage or nothing at all.
+Fortunately, most driver generate the printer driver that is needed.
+However, the client must be tickled to generate a valid Device Mode and set it on the
+server. The easist means of doing so is to simply set the page orientation on
+the server's printer using the native Windows NT/2k printer properties page from
+a Window clients. Make sure to apply changes between swapping the page orientation
+to cause the change to actually take place. Be aware that this can only be done
+by a "printer admin" (the reason should be obvious I hope).</P
+><P
+>Samba also includes a service level parameter name <A
+HREF="smb.conf.5.html#DEFAULTDEVMODE"
+TARGET="_top"
+>default
+devmode</A
+> for generating a default device mode for a printer. Some driver
+will function fine with this default set of properties. Others may crash the client's
+spooler service. Use this parameter with caution. It is always better to have the client
+generate a valid device mode for the printer and store it on the server for you.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN862"
+>6.2.4. Support a large number of printers</A
+></H2
+><P
+>One issue that has arisen during the development
+phase of Samba 2.2 is the need to support driver downloads for
+100's of printers. Using the Windows NT APW is somewhat
+awkward to say the list. If more than one printer are using the
+same driver, the <A
+HREF="rpcclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>rpcclient's
+setdriver</B
+></A
+> command can be used to set the driver
+associated with an installed driver. The following is example
+of how this could be accomplished:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret -c "enumdrivers"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+
+[Windows NT x86]
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4000 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 2100 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4Si/4SiMX PS]
+
+<TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret -c "enumprinters"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+ flags:[0x800000]
+ name:[\\POGO\hp-print]
+ description:[POGO\\POGO\hp-print,NO DRIVER AVAILABLE FOR THIS PRINTER,]
+ comment:[]
+
+<TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret \
+<TT
+CLASS="PROMPT"
+>&#62; </TT
+> -c "setdriver hp-print \"HP LaserJet 4000 Series PS\""
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+Successfully set hp-print to driver HP LaserJet 4000 Series PS.</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN873"
+>6.2.5. Adding New Printers via the Windows NT APW</A
+></H2
+><P
+>By default, Samba offers all printer shares defined in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+in the "Printers..." folder. Also existing in this folder is the Windows NT
+Add Printer Wizard icon. The APW will be show only if</P
+><P
+></P
+><UL
+><LI
+><P
+>The connected user is able to successfully
+ execute an OpenPrinterEx(\\server) with administrative
+ privileges (i.e. root or <TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+>).
+ </P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#SHOWADDPRINTERWIZARD"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>show
+ add printer wizard = yes</I
+></TT
+></A
+> (the default).
+ </P
+></LI
+></UL
+><P
+>In order to be able to use the APW to successfully add a printer to a Samba
+server, the <A
+HREF="smb.conf.5.html#ADDPRINTERCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>add
+printer command</I
+></TT
+></A
+> must have a defined value. The program
+hook must successfully add the printer to the system (i.e.
+<TT
+CLASS="FILENAME"
+>/etc/printcap</TT
+> or appropriate files) and
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> if necessary.</P
+><P
+>When using the APW from a client, if the named printer share does
+not exist, <B
+CLASS="COMMAND"
+>smbd</B
+> will execute the <TT
+CLASS="PARAMETER"
+><I
+>add printer
+command</I
+></TT
+> and reparse to the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+to attempt to locate the new printer share. If the share is still not defined,
+an error of "Access Denied" is returned to the client. Note that the
+<TT
+CLASS="PARAMETER"
+><I
+>add printer program</I
+></TT
+> is executed under the context
+of the connected user, not necessarily a root account.</P
+><P
+>There is a complementing <A
+HREF="smb.conf.5.html#DELETEPRINTERCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>delete
+printer command</I
+></TT
+></A
+> for removing entries from the "Printers..."
+folder.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN898"
+>6.2.6. Samba and Printer Ports</A
+></H2
+><P
+>Windows NT/2000 print servers associate a port with each printer. These normally
+take the form of LPT1:, COM1:, FILE:, etc... Samba must also support the
+concept of ports associated with a printer. By default, only one printer port,
+named "Samba Printer Port", exists on a system. Samba does not really a port in
+order to print, rather it is a requirement of Windows clients. </P
+><P
+>Note that Samba does not support the concept of "Printer Pooling" internally
+either. This is when a logical printer is assigned to multiple ports as
+a form of load balancing or fail over.</P
+><P
+>If you require that multiple ports be defined for some reason,
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> possesses a <A
+HREF="smb.conf.5.html#ENUMPORTSCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>enumports
+command</I
+></TT
+></A
+> which can be used to define an external program
+that generates a listing of ports on a system.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN906"
+>6.3. The Imprints Toolset</A
+></H1
+><P
+>The Imprints tool set provides a UNIX equivalent of the
+ Windows NT Add Printer Wizard. For complete information, please
+ refer to the Imprints web site at <A
+HREF="http://imprints.sourceforge.net/"
+TARGET="_top"
+> http://imprints.sourceforge.net/</A
+> as well as the documentation
+ included with the imprints source distribution. This section will
+ only provide a brief introduction to the features of Imprints.</P
+><P
+>As of June 16, 2002 (quite a bit earlier actually), the Imprints
+ project is in need of a new maintainer. The most important skill
+ is decent perl coding and an interest in MS-RPC based printing using Samba.
+ If you wich to volunteer, please coordinate your efforts on the samba-technical
+ mailing list.
+ </P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN911"
+>6.3.1. What is Imprints?</A
+></H2
+><P
+>Imprints is a collection of tools for supporting the goals
+ of</P
+><P
+></P
+><UL
+><LI
+><P
+>Providing a central repository information
+ regarding Windows NT and 95/98 printer driver packages</P
+></LI
+><LI
+><P
+>Providing the tools necessary for creating
+ the Imprints printer driver packages.</P
+></LI
+><LI
+><P
+>Providing an installation client which
+ will obtain and install printer drivers on remote Samba
+ and Windows NT 4 print servers.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN921"
+>6.3.2. Creating Printer Driver Packages</A
+></H2
+><P
+>The process of creating printer driver packages is beyond
+ the scope of this document (refer to Imprints.txt also included
+ with the Samba distribution for more information). In short,
+ an Imprints driver package is a gzipped tarball containing the
+ driver files, related INF files, and a control file needed by the
+ installation client.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN924"
+>6.3.3. The Imprints server</A
+></H2
+><P
+>The Imprints server is really a database server that
+ may be queried via standard HTTP mechanisms. Each printer
+ entry in the database has an associated URL for the actual
+ downloading of the package. Each package is digitally signed
+ via GnuPG which can be used to verify that package downloaded
+ is actually the one referred in the Imprints database. It is
+ <EM
+>not</EM
+> recommended that this security check
+ be disabled.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN928"
+>6.3.4. The Installation Client</A
+></H2
+><P
+>More information regarding the Imprints installation client
+ is available in the <TT
+CLASS="FILENAME"
+>Imprints-Client-HOWTO.ps</TT
+>
+ file included with the imprints source package.</P
+><P
+>The Imprints installation client comes in two forms.</P
+><P
+></P
+><UL
+><LI
+><P
+>a set of command line Perl scripts</P
+></LI
+><LI
+><P
+>a GTK+ based graphical interface to
+ the command line perl scripts</P
+></LI
+></UL
+><P
+>The installation client (in both forms) provides a means
+ of querying the Imprints database server for a matching
+ list of known printer model names as well as a means to
+ download and install the drivers on remote Samba and Windows
+ NT print servers.</P
+><P
+>The basic installation process is in four steps and
+ perl code is wrapped around <B
+CLASS="COMMAND"
+>smbclient</B
+>
+ and <B
+CLASS="COMMAND"
+>rpcclient</B
+>.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>
+foreach (supported architecture for a given driver)
+{
+ 1. rpcclient: Get the appropriate upload directory
+ on the remote server
+ 2. smbclient: Upload the driver files
+ 3. rpcclient: Issues an AddPrinterDriver() MS-RPC
+}
+
+4. rpcclient: Issue an AddPrinterEx() MS-RPC to actually
+ create the printer</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>One of the problems encountered when implementing
+ the Imprints tool set was the name space issues between
+ various supported client architectures. For example, Windows
+ NT includes a driver named "Apple LaserWriter II NTX v51.8"
+ and Windows 95 calls its version of this driver "Apple
+ LaserWriter II NTX"</P
+><P
+>The problem is how to know what client drivers have
+ been uploaded for a printer. As astute reader will remember
+ that the Windows NT Printer Properties dialog only includes
+ space for one printer driver name. A quick look in the
+ Windows NT 4.0 system registry at</P
+><P
+><TT
+CLASS="FILENAME"
+>HKLM\System\CurrentControlSet\Control\Print\Environment
+ </TT
+></P
+><P
+>will reveal that Windows NT always uses the NT driver
+ name. This is ok as Windows NT always requires that at least
+ the Windows NT version of the printer driver is present.
+ However, Samba does not have the requirement internally.
+ Therefore, how can you use the NT driver name if is has not
+ already been installed?</P
+><P
+>The way of sidestepping this limitation is to require
+ that all Imprints printer driver packages include both the Intel
+ Windows NT and 95/98 printer drivers and that NT driver is
+ installed first.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN950"
+>6.4. <A
+NAME="MIGRATION"
+></A
+>Migration to from Samba 2.0.x to 2.2.x</A
+></H1
+><P
+>Given that printer driver management has changed (we hope improved) in
+2.2 over prior releases, migration from an existing setup to 2.2 can
+follow several paths. Here are the possible scenarios for
+migration:</P
+><P
+></P
+><UL
+><LI
+><P
+>If you do not desire the new Windows NT
+ print driver support, nothing needs to be done.
+ All existing parameters work the same.</P
+></LI
+><LI
+><P
+>If you want to take advantage of NT printer
+ driver support but do not want to migrate the
+ 9x drivers to the new setup, the leave the existing
+ <TT
+CLASS="FILENAME"
+>printers.def</TT
+> file. When smbd attempts
+ to locate a
+ 9x driver for the printer in the TDB and fails it
+ will drop down to using the printers.def (and all
+ associated parameters). The <B
+CLASS="COMMAND"
+>make_printerdef</B
+>
+ tool will also remain for backwards compatibility but will
+ be removed in the next major release.</P
+></LI
+><LI
+><P
+>If you install a Windows 9x driver for a printer
+ on your Samba host (in the printing TDB), this information will
+ take precedence and the three old printing parameters
+ will be ignored (including print driver location).</P
+></LI
+><LI
+><P
+>If you want to migrate an existing <TT
+CLASS="FILENAME"
+>printers.def</TT
+>
+ file into the new setup, the current only solution is to use the Windows
+ NT APW to install the NT drivers and the 9x drivers. This can be scripted
+ using <B
+CLASS="COMMAND"
+>smbclient</B
+> and <B
+CLASS="COMMAND"
+>rpcclient</B
+>. See the
+ Imprints installation client at <A
+HREF="http://imprints.sourceforge.net/"
+TARGET="_top"
+>http://imprints.sourceforge.net/</A
+>
+ for an example.
+ </P
+></LI
+></UL
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Achtung!</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>The following <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> parameters are considered to
+be deprecated and will be removed soon. Do not use them in new
+installations</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver file (G)</I
+></TT
+>
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver (S)</I
+></TT
+>
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver location (S)</I
+></TT
+>
+ </P
+></LI
+></UL
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN983"
+>6.4.1. Parameters in <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> for Backwards Compatibility</A
+></H2
+><P
+>The have been two new parameters add in Samba 2.2.2 to for
+better support of Samba 2.0.x backwards capability (<TT
+CLASS="PARAMETER"
+><I
+>disable
+spoolss</I
+></TT
+>) and for using local printers drivers on Windows
+NT/2000 clients (<TT
+CLASS="PARAMETER"
+><I
+>use client driver</I
+></TT
+>). Both of
+these options are described in the smb.coinf(5) man page and are
+disabled by default. Use them with caution.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="CUPS"
+>Chapter 7. Printing with CUPS in Samba 2.2.x</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN999"
+>7.1. Printing with CUPS in Samba 2.2.x</A
+></H1
+><P
+><A
+HREF="http://www.cups.org/"
+TARGET="_top"
+>CUPS</A
+> is a newcomer in
+the UNIX printing scene, which has convinced many people upon first trial
+already. However, it has quite a few new features, which make it different
+from other, more traditional printing systems.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1003"
+>7.2. Configuring <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for CUPS</A
+></H1
+><P
+>Printing with CUPS in the most basic <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+setup in Samba 2.2.x only needs two settings: <B
+CLASS="COMMAND"
+>printing = cups</B
+> and
+<B
+CLASS="COMMAND"
+>printcap = cups</B
+>. While CUPS itself doesn't need a printcap
+anymore, the <TT
+CLASS="FILENAME"
+>cupsd.conf</TT
+> configuration file knows two directives
+(example: <B
+CLASS="COMMAND"
+>Printcap /etc/printcap</B
+> and <B
+CLASS="COMMAND"
+>PrintcapFormat
+BSD</B
+>), which control if such a file should be created for the
+convenience of third party applications. Make sure it is set! For details see
+<B
+CLASS="COMMAND"
+>man cupsd.conf</B
+> and other CUPS-related documentation.</P
+><P
+>If SAMBA is compiled against libcups, then <B
+CLASS="COMMAND"
+>printcap =
+cups</B
+> uses the CUPS API to list printers, submit jobs, etc. Otherwise it
+maps to the System V commands with an additional <TT
+CLASS="PARAMETER"
+><I
+>-oraw</I
+></TT
+>
+option for printing. On a Linux system, you can use the <B
+CLASS="COMMAND"
+>ldd</B
+> command to
+find out details (ldd may not be present on other OS platforms, or its
+function may be embodied by a different command):</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>transmeta:/home/kurt # ldd `which smbd`
+ libssl.so.0.9.6 =&#62; /usr/lib/libssl.so.0.9.6 (0x4002d000)
+ libcrypto.so.0.9.6 =&#62; /usr/lib/libcrypto.so.0.9.6 (0x4005a000)
+ libcups.so.2 =&#62; /usr/lib/libcups.so.2 (0x40123000)
+ libdl.so.2 =&#62; /lib/libdl.so.2 (0x401e8000)
+ libnsl.so.1 =&#62; /lib/libnsl.so.1 (0x401ec000)
+ libpam.so.0 =&#62; /lib/libpam.so.0 (0x40202000)
+ libc.so.6 =&#62; /lib/libc.so.6 (0x4020b000)
+ /lib/ld-linux.so.2 =&#62; /lib/ld-linux.so.2 (0x40000000)</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The line "libcups.so.2 =&#62; /usr/lib/libcups.so.2
+(0x40123000)" shows there is CUPS support compiled into this version of
+Samba. If this is the case, and <B
+CLASS="COMMAND"
+>printing = cups</B
+> is set, then any
+otherwise manually set print command in smb.conf is ignored.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1022"
+>7.3. Using CUPS as a mere spooling print server -- "raw"
+printing with vendor drivers download</A
+></H1
+><P
+>You can setup Samba and your Windows clients to use the
+CUPS print subsystem just as you would with any of the more traditional print
+subsystems: that means the use of vendor provided, native Windows printer
+drivers for each target printer. If you setup the [print$] share to
+download these drivers to the clients, their GDI system (Graphical Device
+Interface) will output the Wndows EMF (Enhanced MetaFile) and
+convert it -- with the help of the printer driver -- locally into the format
+the printer is expecting. Samba and the CUPS print subsystem will have to
+treat these files as raw print files -- they are already in the
+shape to be digestable for the printer. This is the same traditional setup
+for Unix print servers handling Windows client jobs. It does not take much
+CPU power to handle this kind of task efficiently.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1025"
+>7.4. CUPS as a network PostScript RIP -- CUPS drivers working on server, Adobe
+PostScript driver with CUPS-PPDs downloaded to clients</A
+></H1
+><P
+>CUPS is perfectly able to use PPD files (PostScript
+Printer Descriptions). PPDs can control all print device options. They
+are usually provided by the manufacturer -- if you own a PostSript printer,
+that is. PPD files are always a component of PostScript printer drivers on MS
+Windows or Apple Mac OS systems. They are ASCII files containing
+user-selectable print options, mapped to appropriate PostScript, PCL or PJL
+commands for the target printer. Printer driver GUI dialogs translate these
+options "on-the-fly" into buttons and drop-down lists for the user to
+select.</P
+><P
+>CUPS can load, without any conversions, the PPD file from
+any Windows (NT is recommended) PostScript driver and handle the options.
+There is a web browser interface to the print options (select
+http://localhost:631/printers/ and click on one "Configure Printer" button
+to see it), a commandline interface (see <B
+CLASS="COMMAND"
+>man lpoptions</B
+> or
+try if you have <B
+CLASS="COMMAND"
+>lphelp</B
+> on your system) plus some different GUI frontends on Linux
+UNIX, which can present PPD options to the users. PPD options are normally
+meant to become evaluated by the PostScript RIP on the real PostScript
+printer.</P
+><P
+>CUPS doesn't stop at "real" PostScript printers in its
+usage of PPDs. The CUPS developers have extended the PPD concept, to also
+describe available device and driver options for non-PostScript printers
+through CUPS-PPDs.</P
+><P
+>This is logical, as CUPS includes a fully featured
+PostScript interpreter (RIP). This RIP is based on Ghostscript. It can
+process all received PostScript (and additionally many other file formats)
+from clients. All CUPS-PPDs geared to non-PostScript printers contain an
+additional line, starting with the keyword <TT
+CLASS="PARAMETER"
+><I
+>*cupsFilter</I
+></TT
+>.
+This line
+tells the CUPS print system which printer-specific filter to use for the
+interpretation of the accompanying PostScript. Thus CUPS lets all its
+printers appear as PostScript devices to its clients, because it can act as a
+PostScript RIP for those printers, processing the received PostScript code
+into a proper raster print format.</P
+><P
+>CUPS-PPDs can also be used on Windows-Clients, on top of a
+PostScript driver (recommended is the Adobe one).</P
+><P
+>This feature enables CUPS to do a few tricks no other
+spooler can do:</P
+><P
+></P
+><UL
+><LI
+><P
+>act as a networked PostScript RIP (Raster Image Processor), handling
+ printfiles from all client platforms in a uniform way;</P
+></LI
+><LI
+><P
+>act as a central accounting and billing server, as all files are passed
+ through the <B
+CLASS="COMMAND"
+>pstops</B
+> Filter and are therefor logged in
+ the CUPS <TT
+CLASS="FILENAME"
+>page_log</TT
+>. - <EM
+>NOTE: </EM
+>this
+ can not happen with "raw" print jobs, which always remain unfiltered
+ per definition;</P
+></LI
+><LI
+><P
+>enable clients to consolidate on a single PostScript driver, even for
+ many different target printers.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1046"
+>7.5. Windows Terminal Servers (WTS) as CUPS clients</A
+></H1
+><P
+>This setup may be of special interest to people
+experiencing major problems in WTS environments. WTS need often a multitude
+of non-PostScript drivers installed to run their clients' variety of
+different printer models. This often imposes the price of much increased
+instability. In many cases, in an attempt to overcome this problem, site
+administrators have resorted to restrict the allowed drivers installed on
+their WTS to one generic PCL- and one PostScript driver. This however
+restricts the clients in the amount of printer options available for them --
+often they can't get out more then simplex prints from one standard paper
+tray, while their devices could do much better, if driven by a different
+driver!</P
+><P
+>Using an Adobe PostScript driver, enabled with a CUPS-PPD,
+seems to be a very elegant way to overcome all these shortcomings. The
+PostScript driver is not known to cause major stability problems on WTS (even
+if used with many different PPDs). The clients will be able to (again) chose
+paper trays, duplex printing and other settings. However, there is a certain
+price for this too: a CUPS server acting as a PostScript RIP for its clients
+requires more CPU and RAM than just to act as a "raw spooling" device. Plus,
+this setup is not yet widely tested, although the first feedbacks look very
+promising...</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1050"
+>7.6. Setting up CUPS for driver download</A
+></H1
+><P
+>The <B
+CLASS="COMMAND"
+>cupsadsmb</B
+> utility (shipped with all current
+CUPS versions) makes the sharing of any (or all) installed CUPS printers very
+easy. Prior to using it, you need the following settings in smb.conf:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>For licensing reasons the necessary files of the Adobe
+Postscript driver can not be distributed with either Samba or CUPS. You need
+to download them yourself from the Adobe website. Once extracted, create a
+<TT
+CLASS="FILENAME"
+>drivers</TT
+> directory in the CUPS data directory (usually
+<TT
+CLASS="FILENAME"
+>/usr/share/cups/</TT
+>). Copy the Adobe files using
+UPPERCASE filenames, to this directory as follows:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> ADFONTS.MFM
+ ADOBEPS4.DRV
+ ADOBEPS4.HLP
+ ADOBEPS5.DLL
+ ADOBEPSU.DLL
+ ADOBEPSU.HLP
+ DEFPRTR2.PPD
+ ICONLIB.DLL</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Users of the ESP Print Pro software are able to install
+their "Samba Drivers" package for this purpose with no problem.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1062"
+>7.7. Sources of CUPS drivers / PPDs</A
+></H1
+><P
+>On the internet you can find now many thousand CUPS-PPD
+files (with their companion filters), in many national languages,
+supporting more than 1.000 non-PostScript models.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="http://wwwl.easysw.com/printpro/"
+TARGET="_top"
+>ESP PrintPro
+ (http://wwwl.easysw.com/printpro/)</A
+>
+ (commercial, non-Free) is packaged with more than 3.000 PPDs, ready for
+ successful usage "out of the box" on Linux, IBM-AIX, HP-UX, Sun-Solaris,
+ SGI-IRIX, Compaq Tru64, Digital Unix and some more commercial Unices (it
+ is written by the CUPS developers themselves and its sales help finance
+ the further development of CUPS, as they feed their creators)</P
+></LI
+><LI
+><P
+>the <A
+HREF="http://gimp-print.sourceforge.net/"
+TARGET="_top"
+>Gimp-Print-Project
+ (http://gimp-print.sourceforge.net/)</A
+>
+ (GPL, Free Software) provides around 120 PPDs (supporting nearly 300
+ printers, many driven to photo quality output), to be used alongside the
+ Gimp-Print CUPS filters;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www.turboprint.com/"
+TARGET="_top"
+>TurboPrint
+ (http://www.turboprint.com/)</A
+>
+ (Shareware, non-Freee) supports roughly the same amount of printers in
+ excellent quality;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www-124.ibm.com/developerworks/oss/linux/projects/omni/"
+TARGET="_top"
+>OMNI
+ (http://www-124.ibm.com/developerworks/oss/linux/projects/omni/)</A
+>
+ (LPGL, Free) is a package made by IBM, now containing support for more
+ than 400 printers, stemming from the inheritance of IBM OS/2 KnowHow
+ ported over to Linux (CUPS support is in a Beta-stage at present);</P
+></LI
+><LI
+><P
+><A
+HREF="http://hpinkjet.sourceforge.net/"
+TARGET="_top"
+>HPIJS
+ (http://hpinkjet.sourceforge.net/)</A
+>
+ (BSD-style licnes, Free) supports around 120 of HP's own printers and is
+ also providing excellent print quality now;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www.linuxprinting.org/"
+TARGET="_top"
+>Foomatic/cupsomatic (http://www.linuxprinting.org/)</A
+>
+ (LPGL, Free) from Linuxprinting.org are providing PPDs for practically every
+ Ghostscript filter known to the world, now usable with CUPS.</P
+></LI
+></UL
+><P
+><EM
+>NOTE: </EM
+>the cupsomatic trick from Linuxprinting.org is
+working different from the other drivers. While the other drivers take the
+generic CUPS raster (produced by CUPS' own pstoraster PostScript RIP) as
+their input, cupsomatic "kidnaps" the PostScript inside CUPS, before
+RIP-ping, deviates it to an external Ghostscript installation (which now
+becomes the RIP) and gives it back to a CUPS backend once Ghostscript is
+finished. -- CUPS versions from 1.1.15 and later will provide their pstoraster
+PostScript RIP function again inside a system-wide Ghostscript
+installation rather than in "their own" pstoraster filter. (This
+CUPS-enabling Ghostscript version may be installed either as a
+patch to GNU or AFPL Ghostscript, or as a complete ESP Ghostscript package).
+However, this will not change the cupsomatic approach of guiding the printjob
+along a different path through the filtering system than the standard CUPS
+way...</P
+><P
+>Once you installed a printer inside CUPS with one of the
+recommended methods (the lpadmin command, the web browser interface or one of
+the available GUI wizards), you can use <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> to share the
+printer via Samba. <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> prepares the driver files for
+comfortable client download and installation upon their first contact with
+this printer share.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1089"
+>7.7.1. <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+></A
+></H2
+><P
+>The <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> command copies the needed files
+for convenient Windows client installations from the previously prepared CUPS
+data directory to your [print$] share. Additionally, the PPD
+associated with this printer is copied from <TT
+CLASS="FILENAME"
+>/etc/cups/ppd/</TT
+> to
+[print$].</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root# </TT
+> <B
+CLASS="COMMAND"
+>cupsaddsmb -U root infotec_IS2027</B
+>
+Password for root required to access localhost via SAMBA: <TT
+CLASS="USERINPUT"
+><B
+>[type in password 'secret']</B
+></TT
+></PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>To share all printers and drivers, use the <TT
+CLASS="PARAMETER"
+><I
+>-a</I
+></TT
+>
+parameter instead of a printer name.</P
+><P
+>Probably you want to see what's going on. Use the
+<TT
+CLASS="PARAMETER"
+><I
+>-v</I
+></TT
+> parameter to get a more verbose output:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root# </TT
+> cupsaddsmb -v -U root infotec_IS2027
+ Password for root required to access localhost via SAMBA:
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir W32X86;put /var/spool/cups/tmp/3cd1cc66376c0 W32X86/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;put /usr/share/cups/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;put /usr/share/cups/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \W32X86
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \W32X86/infotec_IS2027.PPD (17394.6 kb/s) (average 17395.2 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS5.DLL as \W32X86/ADOBEPS5.DLL (10877.4 kb/s) (average 11343.0 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.DLL as \W32X86/ADOBEPSU.DLL (5095.2 kb/s) (average 9260.4 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.HLP as \W32X86/ADOBEPSU.HLP (8828.7 kb/s) (average 9247.1 kb/s)
+
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir WIN40;put /var/spool/cups/tmp/3cd1cc66376c0 WIN40/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;put /usr/share/cups/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;put /usr/share/cups/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;put /usr/share/cups/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;put /usr/share/cups/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;put /usr/share/cups/drivers/PSMON.DLL WIN40/PSMON.DLL;'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \WIN40
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \WIN40/infotec_IS2027.PPD (26091.5 kb/s) (average 26092.8 kb/s)
+ putting file /usr/share/cups/drivers/ADFONTS.MFM as \WIN40/ADFONTS.MFM (11241.6 kb/s) (average 11812.9 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.DRV as \WIN40/ADOBEPS4.DRV (16640.6 kb/s) (average 14679.3 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.HLP as \WIN40/ADOBEPS4.HLP (11285.6 kb/s) (average 14281.5 kb/s)
+ putting file /usr/share/cups/drivers/DEFPRTR2.PPD as \WIN40/DEFPRTR2.PPD (823.5 kb/s) (average 12944.0 kb/s)
+ putting file /usr/share/cups/drivers/ICONLIB.DLL as \WIN40/ICONLIB.DLL (19226.2 kb/s) (average 13169.7 kb/s)
+ putting file /usr/share/cups/drivers/PSMON.DLL as \WIN40/PSMON.DLL (18666.1 kb/s) (average 13266.7 kb/s)
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"'
+ cmd = adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"'
+ cmd = adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'setdriver infotec_IS2027 infotec_IS2027'
+ cmd = setdriver infotec_IS2027 infotec_IS2027
+ Succesfully set infotec_IS2027 to driver infotec_IS2027.
+
+ <TT
+CLASS="PROMPT"
+>root# </TT
+></PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>If you look closely, you'll discover your root password
+was transfered unencrypted over the wire, so beware! Also, if you look
+further her, you'll discover error messages like
+<TT
+CLASS="CONSTANT"
+>NT_STATUS_OBJECT_NAME_COLLISION</TT
+> in between. They occur, because
+the directories <TT
+CLASS="FILENAME"
+>WIN40</TT
+> and <TT
+CLASS="FILENAME"
+>W32X86</TT
+> already
+existed in the [print$] driver download share (from a previous driver
+installation). They are harmless here.</P
+><P
+>Now your printer is prepared for the clients to use. From
+a client, browse to the CUPS/Samba server, open the "Printers"
+share, right-click on this printer and select "Install..." or
+"Connect..." (depending on the Windows version you use). Now their
+should be a new printer in your client's local "Printers" folder,
+named (in my case) "infotec_IS2027 on kdebitshop"</P
+><P
+><EM
+>NOTE: </EM
+>
+<B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> will only reliably work i
+with CUPS version 1.1.15 or higher
+and Samba from 2.2.4. If it doesn't work, or if the automatic printer
+driver download to the clients doesn't succeed, you can still manually
+install the CUPS printer PPD on top of the Adobe PostScript driver on
+clients and then point the client's printer queue to the Samba printer
+share for connection, should you desire to use the CUPS networked
+PostScript RIP functions.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="DOMAIN-SECURITY"
+>Chapter 8. security = domain in Samba 2.x</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN1134"
+>8.1. Joining an NT Domain with Samba 2.2</A
+></H1
+><P
+>Assume you have a Samba 2.x server with a NetBIOS name of
+ <TT
+CLASS="CONSTANT"
+>SERV1</TT
+> and are joining an NT domain called
+ <TT
+CLASS="CONSTANT"
+>DOM</TT
+>, which has a PDC with a NetBIOS name
+ of <TT
+CLASS="CONSTANT"
+>DOMPDC</TT
+> and two backup domain controllers
+ with NetBIOS names <TT
+CLASS="CONSTANT"
+>DOMBDC1</TT
+> and <TT
+CLASS="CONSTANT"
+>DOMBDC2
+ </TT
+>.</P
+><P
+>In order to join the domain, first stop all Samba daemons
+ and run the command:</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbpasswd -j DOM -r DOMPDC
+ -U<TT
+CLASS="REPLACEABLE"
+><I
+>Administrator%password</I
+></TT
+></B
+></TT
+></P
+><P
+>as we are joining the domain DOM and the PDC for that domain
+ (the only machine that has write access to the domain SAM database)
+ is DOMPDC. The <TT
+CLASS="REPLACEABLE"
+><I
+>Administrator%password</I
+></TT
+> is
+ the login name and password for an account which has the necessary
+ privilege to add machines to the domain. If this is successful
+ you will see the message:</P
+><P
+><TT
+CLASS="COMPUTEROUTPUT"
+>smbpasswd: Joined domain DOM.</TT
+>
+ </P
+><P
+>in your terminal window. See the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+> smbpasswd(8)</A
+> man page for more details.</P
+><P
+>There is existing development code to join a domain
+ without having to create the machine trust account on the PDC
+ beforehand. This code will hopefully be available soon
+ in release branches as well.</P
+><P
+>This command goes through the machine account password
+ change protocol, then writes the new (random) machine account
+ password for this Samba server into a file in the same directory
+ in which an smbpasswd file would be stored - normally :</P
+><P
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/private</TT
+></P
+><P
+>In Samba 2.0.x, the filename looks like this:</P
+><P
+><TT
+CLASS="FILENAME"
+><TT
+CLASS="REPLACEABLE"
+><I
+>&#60;NT DOMAIN NAME&#62;</I
+></TT
+>.<TT
+CLASS="REPLACEABLE"
+><I
+>&#60;Samba
+ Server Name&#62;</I
+></TT
+>.mac</TT
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>.mac</TT
+> suffix stands for machine account
+ password file. So in our example above, the file would be called:</P
+><P
+><TT
+CLASS="FILENAME"
+>DOM.SERV1.mac</TT
+></P
+><P
+>In Samba 2.2, this file has been replaced with a TDB
+ (Trivial Database) file named <TT
+CLASS="FILENAME"
+>secrets.tdb</TT
+>.
+ </P
+><P
+>This file is created and owned by root and is not
+ readable by any other user. It is the key to the domain-level
+ security for your system, and should be treated as carefully
+ as a shadow password file.</P
+><P
+>Now, before restarting the Samba daemons you must
+ edit your <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ </A
+> file to tell Samba it should now use domain security.</P
+><P
+>Change (or add) your <A
+HREF="smb.conf.5.html#SECURITY"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>security =</I
+></TT
+></A
+> line in the [global] section
+ of your smb.conf to read:</P
+><P
+><B
+CLASS="COMMAND"
+>security = domain</B
+></P
+><P
+>Next change the <A
+HREF="smb.conf.5.html#WORKGROUP"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> workgroup =</I
+></TT
+></A
+> line in the [global] section to read: </P
+><P
+><B
+CLASS="COMMAND"
+>workgroup = DOM</B
+></P
+><P
+>as this is the name of the domain we are joining. </P
+><P
+>You must also have the parameter <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>encrypt passwords</I
+></TT
+></A
+> set to <TT
+CLASS="CONSTANT"
+>yes
+ </TT
+> in order for your users to authenticate to the NT PDC.</P
+><P
+>Finally, add (or modify) a <A
+HREF="smb.conf.5.html#PASSWORDSERVER"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>password server =</I
+></TT
+></A
+> line in the [global]
+ section to read: </P
+><P
+><B
+CLASS="COMMAND"
+>password server = DOMPDC DOMBDC1 DOMBDC2</B
+></P
+><P
+>These are the primary and backup domain controllers Samba
+ will attempt to contact in order to authenticate users. Samba will
+ try to contact each of these servers in order, so you may want to
+ rearrange this list in order to spread out the authentication load
+ among domain controllers.</P
+><P
+>Alternatively, if you want smbd to automatically determine
+ the list of Domain controllers to use for authentication, you may
+ set this line to be :</P
+><P
+><B
+CLASS="COMMAND"
+>password server = *</B
+></P
+><P
+>This method, which was introduced in Samba 2.0.6,
+ allows Samba to use exactly the same mechanism that NT does. This
+ method either broadcasts or uses a WINS database in order to
+ find domain controllers to authenticate against.</P
+><P
+>Finally, restart your Samba daemons and get ready for
+ clients to begin using domain security!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1198"
+>8.2. Samba and Windows 2000 Domains</A
+></H1
+><P
+>Many people have asked regarding the state of Samba's ability to participate in
+a Windows 2000 Domain. Samba 2.2 is able to act as a member server of a Windows
+2000 domain operating in mixed or native mode.</P
+><P
+>There is much confusion between the circumstances that require a "mixed" mode
+Win2k DC and a when this host can be switched to "native" mode. A "mixed" mode
+Win2k domain controller is only needed if Windows NT BDCs must exist in the same
+domain. By default, a Win2k DC in "native" mode will still support
+NetBIOS and NTLMv1 for authentication of legacy clients such as Windows 9x and
+NT 4.0. Samba has the same requirements as a Windows NT 4.0 member server.</P
+><P
+>The steps for adding a Samba 2.2 host to a Win2k domain are the same as those
+for adding a Samba server to a Windows NT 4.0 domain. The only exception is that
+the "Server Manager" from NT 4 has been replaced by the "Active Directory Users and
+Computers" MMC (Microsoft Management Console) plugin.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1203"
+>8.3. Why is this better than security = server?</A
+></H1
+><P
+>Currently, domain security in Samba doesn't free you from
+ having to create local Unix users to represent the users attaching
+ to your server. This means that if domain user <TT
+CLASS="CONSTANT"
+>DOM\fred
+ </TT
+> attaches to your domain security Samba server, there needs
+ to be a local Unix user fred to represent that user in the Unix
+ filesystem. This is very similar to the older Samba security mode
+ <A
+HREF="smb.conf.5.html#SECURITYEQUALSSERVER"
+TARGET="_top"
+>security = server</A
+>,
+ where Samba would pass through the authentication request to a Windows
+ NT server in the same way as a Windows 95 or Windows 98 server would.
+ </P
+><P
+>Please refer to the <A
+HREF="winbind.html"
+TARGET="_top"
+>Winbind
+ paper</A
+> for information on a system to automatically
+ assign UNIX uids and gids to Windows NT Domain users and groups.
+ This code is available in development branches only at the moment,
+ but will be moved to release branches soon.</P
+><P
+>The advantage to domain-level security is that the
+ authentication in domain-level security is passed down the authenticated
+ RPC channel in exactly the same way that an NT server would do it. This
+ means Samba servers now participate in domain trust relationships in
+ exactly the same way NT servers do (i.e., you can add Samba servers into
+ a resource domain and have the authentication passed on from a resource
+ domain PDC to an account domain PDC.</P
+><P
+>In addition, with <B
+CLASS="COMMAND"
+>security = server</B
+> every Samba
+ daemon on a server has to keep a connection open to the
+ authenticating server for as long as that daemon lasts. This can drain
+ the connection resources on a Microsoft NT server and cause it to run
+ out of available connections. With <B
+CLASS="COMMAND"
+>security = domain</B
+>,
+ however, the Samba daemons connect to the PDC/BDC only for as long
+ as is necessary to authenticate the user, and then drop the connection,
+ thus conserving PDC connection resources.</P
+><P
+>And finally, acting in the same manner as an NT server
+ authenticating to a PDC means that as part of the authentication
+ reply, the Samba server gets the user identification information such
+ as the user SID, the list of NT groups the user belongs to, etc. All
+ this information will allow Samba to be extended in the future into
+ a mode the developers currently call appliance mode. In this mode,
+ no local Unix users will be necessary, and Samba will generate Unix
+ uids and gids from the information passed back from the PDC when a
+ user is authenticated, making a Samba server truly plug and play
+ in an NT domain environment. Watch for this code soon.</P
+><P
+><EM
+>NOTE:</EM
+> Much of the text of this document
+ was first published in the Web magazine <A
+HREF="http://www.linuxworld.com"
+TARGET="_top"
+>
+ LinuxWorld</A
+> as the article <A
+HREF="http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html"
+TARGET="_top"
+>Doing
+ the NIS/NT Samba</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="SAMBA-PDC"
+>Chapter 9. How to Configure Samba 2.2 as a Primary Domain Controller</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN1236"
+>9.1. Prerequisite Reading</A
+></H1
+><P
+>Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring basic files services
+in smb.conf and how to enable and administer password
+encryption in Samba. Theses two topics are covered in the
+<A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+>
+manpage and the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>Encryption chapter</A
+>
+of this HOWTO Collection.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1242"
+>9.2. Background</A
+></H1
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+><EM
+>Author's Note:</EM
+> This document is a combination
+of David Bannon's "Samba 2.2 PDC HOWTO" and "Samba NT Domain FAQ".
+Both documents are superseded by this one.</P
+></BLOCKQUOTE
+></DIV
+><P
+>Versions of Samba prior to release 2.2 had marginal capabilities to act
+as a Windows NT 4.0 Primary Domain Controller
+
+(PDC). With Samba 2.2.0, we are proud to announce official support for
+Windows NT 4.0-style domain logons from Windows NT 4.0 and Windows
+2000 clients. This article outlines the steps
+necessary for configuring Samba as a PDC. It is necessary to have a
+working Samba server prior to implementing the PDC functionality. If
+you have not followed the steps outlined in <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+> UNIX_INSTALL.html</A
+>, please make sure
+that your server is configured correctly before proceeding. Another
+good resource in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5) man
+page</A
+>. The following functionality should work in 2.2:</P
+><P
+></P
+><UL
+><LI
+><P
+> domain logons for Windows NT 4.0/2000 clients.
+ </P
+></LI
+><LI
+><P
+> placing a Windows 9x client in user level security
+ </P
+></LI
+><LI
+><P
+> retrieving a list of users and groups from a Samba PDC to
+ Windows 9x/NT/2000 clients
+ </P
+></LI
+><LI
+><P
+> roving (roaming) user profiles
+ </P
+></LI
+><LI
+><P
+> Windows NT 4.0-style system policies
+ </P
+></LI
+></UL
+><P
+>The following pieces of functionality are not included in the 2.2 release:</P
+><P
+></P
+><UL
+><LI
+><P
+> Windows NT 4 domain trusts
+ </P
+></LI
+><LI
+><P
+> SAM replication with Windows NT 4.0 Domain Controllers
+ (i.e. a Samba PDC and a Windows NT BDC or vice versa)
+ </P
+></LI
+><LI
+><P
+> Adding users via the User Manager for Domains
+ </P
+></LI
+><LI
+><P
+> Acting as a Windows 2000 Domain Controller (i.e. Kerberos and
+ Active Directory)
+ </P
+></LI
+></UL
+><P
+>Please note that Windows 9x clients are not true members of a domain
+for reasons outlined in this article. Therefore the protocol for
+support Windows 9x-style domain logons is completely different
+from NT4 domain logons and has been officially supported for some
+time.</P
+><P
+>Implementing a Samba PDC can basically be divided into 2 broad
+steps.</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> Configuring the Samba PDC
+ </P
+></LI
+><LI
+><P
+> Creating machine trust accounts and joining clients
+ to the domain
+ </P
+></LI
+></OL
+><P
+>There are other minor details such as user profiles, system
+policies, etc... However, these are not necessarily specific
+to a Samba PDC as much as they are related to Windows NT networking
+concepts. They will be mentioned only briefly here.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1281"
+>9.3. Configuring the Samba Domain Controller</A
+></H1
+><P
+>The first step in creating a working Samba PDC is to
+understand the parameters necessary in smb.conf. I will not
+attempt to re-explain the parameters here as they are more that
+adequately covered in <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> the smb.conf
+man page</A
+>. For convenience, the parameters have been
+linked with the actual smb.conf description.</P
+><P
+>Here is an example <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for acting as a PDC:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ ; Basic server settings
+ <A
+HREF="smb.conf.5.html#NETBIOSNAME"
+TARGET="_top"
+>netbios name</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>POGO</I
+></TT
+>
+ <A
+HREF="smb.conf.5.html#WORKGROUP"
+TARGET="_top"
+>workgroup</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>NARNIA</I
+></TT
+>
+
+ ; we should act as the domain and local master browser
+ <A
+HREF="smb.conf.5.html#OSLEVEL"
+TARGET="_top"
+>os level</A
+> = 64
+ <A
+HREF="smb.conf.5.html#PERFERREDMASTER"
+TARGET="_top"
+>preferred master</A
+> = yes
+ <A
+HREF="smb.conf.5.html#DOMAINMASTER"
+TARGET="_top"
+>domain master</A
+> = yes
+ <A
+HREF="smb.conf.5.html#LOCALMASTER"
+TARGET="_top"
+>local master</A
+> = yes
+
+ ; security settings (must user security = user)
+ <A
+HREF="smb.conf.5.html#SECURITYEQUALSUSER"
+TARGET="_top"
+>security</A
+> = user
+
+ ; encrypted passwords are a requirement for a PDC
+ <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>encrypt passwords</A
+> = yes
+
+ ; support domain logons
+ <A
+HREF="smb.conf.5.html#DOMAINLOGONS"
+TARGET="_top"
+>domain logons</A
+> = yes
+
+ ; where to store user profiles?
+ <A
+HREF="smb.conf.5.html#LOGONPATH"
+TARGET="_top"
+>logon path</A
+> = \\%N\profiles\%u
+
+ ; where is a user's home directory and where should it
+ ; be mounted at?
+ <A
+HREF="smb.conf.5.html#LOGONDRIVE"
+TARGET="_top"
+>logon drive</A
+> = H:
+ <A
+HREF="smb.conf.5.html#LOGONHOME"
+TARGET="_top"
+>logon home</A
+> = \\homeserver\%u
+
+ ; specify a generic logon script for all users
+ ; this is a relative **DOS** path to the [netlogon] share
+ <A
+HREF="smb.conf.5.html#LOGONSCRIPT"
+TARGET="_top"
+>logon script</A
+> = logon.cmd
+
+; necessary share for domain controller
+[netlogon]
+ <A
+HREF="smb.conf.5.html#PATH"
+TARGET="_top"
+>path</A
+> = /usr/local/samba/lib/netlogon
+ <A
+HREF="smb.conf.5.html#READONLY"
+TARGET="_top"
+>read only</A
+> = yes
+ <A
+HREF="smb.conf.5.html#WRITELIST"
+TARGET="_top"
+>write list</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>ntadmin</I
+></TT
+>
+
+; share for storing user profiles
+[profiles]
+ <A
+HREF="smb.conf.5.html#PATH"
+TARGET="_top"
+>path</A
+> = /export/smb/ntprofile
+ <A
+HREF="smb.conf.5.html#READONLY"
+TARGET="_top"
+>read only</A
+> = no
+ <A
+HREF="smb.conf.5.html#CREATEMASK"
+TARGET="_top"
+>create mask</A
+> = 0600
+ <A
+HREF="smb.conf.5.html#DIRECTORYMASK"
+TARGET="_top"
+>directory mask</A
+> = 0700</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>There are a couple of points to emphasize in the above configuration.</P
+><P
+></P
+><UL
+><LI
+><P
+> Encrypted passwords must be enabled. For more details on how
+ to do this, refer to <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>ENCRYPTION.html</A
+>.
+ </P
+></LI
+><LI
+><P
+> The server must support domain logons and a
+ <TT
+CLASS="FILENAME"
+>[netlogon]</TT
+> share
+ </P
+></LI
+><LI
+><P
+> The server must be the domain master browser in order for Windows
+ client to locate the server as a DC. Please refer to the various
+ Network Browsing documentation included with this distribution for
+ details.
+ </P
+></LI
+></UL
+><P
+>As Samba 2.2 does not offer a complete implementation of group mapping
+between Windows NT groups and Unix groups (this is really quite
+complicated to explain in a short space), you should refer to the
+<A
+HREF="smb.conf.5.html#DOMAINADMINGROUP"
+TARGET="_top"
+>domain admin
+group</A
+> smb.conf parameter for information of creating "Domain
+Admins" style accounts.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1324"
+>9.4. Creating Machine Trust Accounts and Joining Clients to the
+Domain</A
+></H1
+><P
+>A machine trust account is a Samba account that is used to
+authenticate a client machine (rather than a user) to the Samba
+server. In Windows terminology, this is known as a "Computer
+Account."</P
+><P
+>The password of a machine trust account acts as the shared secret for
+secure communication with the Domain Controller. This is a security
+feature to prevent an unauthorized machine with the same NetBIOS name
+from joining the domain and gaining access to domain user/group
+accounts. Windows NT and 2000 clients use machine trust accounts, but
+Windows 9x clients do not. Hence, a Windows 9x client is never a true
+member of a domain because it does not possess a machine trust
+account, and thus has no shared secret with the domain controller.</P
+><P
+>A Windows PDC stores each machine trust account in the Windows
+Registry. A Samba PDC, however, stores each machine trust account
+in two parts, as follows:
+
+<P
+></P
+><UL
+><LI
+><P
+>A Samba account, stored in the same location as user
+ LanMan and NT password hashes (currently
+ <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+>). The Samba account
+ possesses and uses only the NT password hash.</P
+></LI
+><LI
+><P
+>A corresponding Unix account, typically stored in
+ <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>. (Future releases will alleviate the need to
+ create <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entries.) </P
+></LI
+></UL
+></P
+><P
+>There are two ways to create machine trust accounts:</P
+><P
+></P
+><UL
+><LI
+><P
+> Manual creation. Both the Samba and corresponding
+ Unix account are created by hand.</P
+></LI
+><LI
+><P
+> "On-the-fly" creation. The Samba machine trust
+ account is automatically created by Samba at the time the client
+ is joined to the domain. (For security, this is the
+ recommended method.) The corresponding Unix account may be
+ created automatically or manually. </P
+></LI
+></UL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1343"
+>9.4.1. Manual Creation of Machine Trust Accounts</A
+></H2
+><P
+>The first step in manually creating a machine trust account is to
+manually create the corresponding Unix account in
+<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>. This can be done using
+<B
+CLASS="COMMAND"
+>vipw</B
+> or other 'add user' command that is normally
+used to create new Unix accounts. The following is an example for a
+Linux based Samba server:</P
+><P
+> <TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>/usr/sbin/useradd -g 100 -d /dev/null -c <TT
+CLASS="REPLACEABLE"
+><I
+>"machine
+nickname"</I
+></TT
+> -s /bin/false <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+>$ </B
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>passwd -l <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+>$</B
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry will list the machine name
+with a "$" appended, won't have a password, will have a null shell and no
+home directory. For example a machine named 'doppy' would have an
+<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>doppy$:x:505:501:<TT
+CLASS="REPLACEABLE"
+><I
+>machine_nickname</I
+></TT
+>:/dev/null:/bin/false</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Above, <TT
+CLASS="REPLACEABLE"
+><I
+>machine_nickname</I
+></TT
+> can be any
+descriptive name for the client, i.e., BasementComputer.
+<TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+> absolutely must be the NetBIOS
+name of the client to be joined to the domain. The "$" must be
+appended to the NetBIOS name of the client or Samba will not recognize
+this as a machine trust account.</P
+><P
+>Now that the corresponding Unix account has been created, the next step is to create
+the Samba account for the client containing the well-known initial
+machine trust account password. This can be done using the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+> command
+as shown here:</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>smbpasswd -a -m <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+></B
+></P
+><P
+>where <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+> is the machine's NetBIOS
+name. The RID of the new machine account is generated from the UID of
+the corresponding Unix account.</P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Join the client to the domain immediately</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+> Manually creating a machine trust account using this method is the
+ equivalent of creating a machine trust account on a Windows NT PDC using
+ the "Server Manager". From the time at which the account is created
+ to the time which the client joins the domain and changes the password,
+ your domain is vulnerable to an intruder joining your domain using a
+ a machine with the same NetBIOS name. A PDC inherently trusts
+ members of the domain and will serve out a large degree of user
+ information to such clients. You have been warned!
+ </P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1378"
+>9.4.2. "On-the-Fly" Creation of Machine Trust Accounts</A
+></H2
+><P
+>The second (and recommended) way of creating machine trust accounts is
+simply to allow the Samba server to create them as needed when the client
+is joined to the domain. </P
+><P
+>Since each Samba machine trust account requires a corresponding
+Unix account, a method for automatically creating the
+Unix account is usually supplied; this requires configuration of the
+<A
+HREF="smb.conf.5.html#ADDUSERSCRIPT"
+TARGET="_top"
+>add user script</A
+>
+option in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>. This
+method is not required, however; corresponding Unix accounts may also
+be created manually.</P
+><P
+>Below is an example for a RedHat 6.2 Linux system.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ # &#60;...remainder of parameters...&#62;
+ add user script = /usr/sbin/useradd -d /dev/null -g 100 -s /bin/false -M %u </PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1387"
+>9.4.3. Joining the Client to the Domain</A
+></H2
+><P
+>The procedure for joining a client to the domain varies with the
+version of Windows.</P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>Windows 2000</EM
+></P
+><P
+> When the user elects to join the client to a domain, Windows prompts for
+ an account and password that is privileged to join the domain. A
+ Samba administrative account (i.e., a Samba account that has root
+ privileges on the Samba server) must be entered here; the
+ operation will fail if an ordinary user account is given.
+ The password for this account should be
+ set to a different password than the associated
+ <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry, for security
+ reasons. </P
+><P
+>The session key of the Samba administrative account acts as an
+ encryption key for setting the password of the machine trust
+ account. The machine trust account will be created on-the-fly, or
+ updated if it already exists.</P
+></LI
+><LI
+><P
+><EM
+>Windows NT</EM
+></P
+><P
+> If the machine trust account was created manually, on the
+ Identification Changes menu enter the domain name, but do not
+ check the box "Create a Computer Account in the Domain." In this case,
+ the existing machine trust account is used to join the machine to
+ the domain.</P
+><P
+> If the machine trust account is to be created
+ on-the-fly, on the Identification Changes menu enter the domain
+ name, and check the box "Create a Computer Account in the Domain." In
+ this case, joining the domain proceeds as above for Windows 2000
+ (i.e., you must supply a Samba administrative account when
+ prompted).</P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1402"
+>9.5. Common Problems and Errors</A
+></H1
+><P
+></P
+><P
+></P
+><UL
+><LI
+><P
+> <EM
+>I cannot include a '$' in a machine name.</EM
+>
+ </P
+><P
+> A 'machine name' in (typically) <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>
+ of the machine name with a '$' appended. FreeBSD (and other BSD
+ systems?) won't create a user with a '$' in their name.
+ </P
+><P
+> The problem is only in the program used to make the entry, once
+ made, it works perfectly. So create a user without the '$' and
+ use <B
+CLASS="COMMAND"
+>vipw</B
+> to edit the entry, adding the '$'. Or create
+ the whole entry with vipw if you like, make sure you use a
+ unique User ID !
+ </P
+></LI
+><LI
+><P
+> <EM
+>I get told "You already have a connection to the Domain...."
+ or "Cannot join domain, the credentials supplied conflict with an
+ existing set.." when creating a machine trust account.</EM
+>
+ </P
+><P
+> This happens if you try to create a machine trust account from the
+ machine itself and already have a connection (e.g. mapped drive)
+ to a share (or IPC$) on the Samba PDC. The following command
+ will remove all network drive connections:
+ </P
+><P
+> <TT
+CLASS="PROMPT"
+>C:\WINNT\&#62;</TT
+> <B
+CLASS="COMMAND"
+>net use * /d</B
+>
+ </P
+><P
+> Further, if the machine is a already a 'member of a workgroup' that
+ is the same name as the domain you are joining (bad idea) you will
+ get this message. Change the workgroup name to something else, it
+ does not matter what, reboot, and try again.
+ </P
+></LI
+><LI
+><P
+> <EM
+>The system can not log you on (C000019B)....</EM
+>
+ </P
+><P
+>I joined the domain successfully but after upgrading
+ to a newer version of the Samba code I get the message, "The system
+ can not log you on (C000019B), Please try a gain or consult your
+ system administrator" when attempting to logon.
+ </P
+><P
+> This occurs when the domain SID stored in
+ <TT
+CLASS="FILENAME"
+>private/WORKGROUP.SID</TT
+> is
+ changed. For example, you remove the file and <B
+CLASS="COMMAND"
+>smbd</B
+> automatically
+ creates a new one. Or you are swapping back and forth between
+ versions 2.0.7, TNG and the HEAD branch code (not recommended). The
+ only way to correct the problem is to restore the original domain
+ SID or remove the domain client from the domain and rejoin.
+ </P
+></LI
+><LI
+><P
+> <EM
+>The machine trust account for this computer either does not
+ exist or is not accessible.</EM
+>
+ </P
+><P
+> When I try to join the domain I get the message "The machine account
+ for this computer either does not exist or is not accessible". What's
+ wrong?
+ </P
+><P
+> This problem is caused by the PDC not having a suitable machine trust account.
+ If you are using the <TT
+CLASS="PARAMETER"
+><I
+>add user script</I
+></TT
+> method to create
+ accounts then this would indicate that it has not worked. Ensure the domain
+ admin user system is working.
+ </P
+><P
+> Alternatively if you are creating account entries manually then they
+ have not been created correctly. Make sure that you have the entry
+ correct for the machine trust account in smbpasswd file on the Samba PDC.
+ If you added the account using an editor rather than using the smbpasswd
+ utility, make sure that the account name is the machine NetBIOS name
+ with a '$' appended to it ( i.e. computer_name$ ). There must be an entry
+ in both /etc/passwd and the smbpasswd file. Some people have reported
+ that inconsistent subnet masks between the Samba server and the NT
+ client have caused this problem. Make sure that these are consistent
+ for both client and server.
+ </P
+></LI
+><LI
+><P
+> <EM
+>When I attempt to login to a Samba Domain from a NT4/W2K workstation,
+ I get a message about my account being disabled.</EM
+>
+ </P
+><P
+> This problem is caused by a PAM related bug in Samba 2.2.0. This bug is
+ fixed in 2.2.1. Other symptoms could be unaccessible shares on
+ NT/W2K member servers in the domain or the following error in your smbd.log:
+ passdb/pampass.c:pam_account(268) PAM: UNKNOWN ERROR for User: %user%
+ </P
+><P
+> At first be ensure to enable the useraccounts with <B
+CLASS="COMMAND"
+>smbpasswd -e
+ %user%</B
+>, this is normally done, when you create an account.
+ </P
+><P
+> In order to work around this problem in 2.2.0, configure the
+ <TT
+CLASS="PARAMETER"
+><I
+>account</I
+></TT
+> control flag in
+ <TT
+CLASS="FILENAME"
+>/etc/pam.d/samba</TT
+> file as follows:
+ </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> account required pam_permit.so
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> If you want to remain backward compatibility to samba 2.0.x use
+ <TT
+CLASS="FILENAME"
+>pam_permit.so</TT
+>, it's also possible to use
+ <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>. There are some bugs if you try to
+ use <TT
+CLASS="FILENAME"
+>pam_unix.so</TT
+>, if you need this, be ensure to use
+ the most recent version of this file.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1450"
+>9.6. System Policies and Profiles</A
+></H1
+><P
+>Much of the information necessary to implement System Policies and
+Roving User Profiles in a Samba domain is the same as that for
+implementing these same items in a Windows NT 4.0 domain.
+You should read the white paper <A
+HREF="http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp"
+TARGET="_top"
+>Implementing
+Profiles and Policies in Windows NT 4.0</A
+> available from Microsoft.</P
+><P
+>Here are some additional details:</P
+><P
+></P
+><UL
+><LI
+><P
+> <EM
+>What about Windows NT Policy Editor?</EM
+>
+ </P
+><P
+> To create or edit <TT
+CLASS="FILENAME"
+>ntconfig.pol</TT
+> you must use
+ the NT Server Policy Editor, <B
+CLASS="COMMAND"
+>poledit.exe</B
+> which
+ is included with NT Server but <EM
+>not NT Workstation</EM
+>.
+ There is a Policy Editor on a NTws
+ but it is not suitable for creating <EM
+>Domain Policies</EM
+>.
+ Further, although the Windows 95
+ Policy Editor can be installed on an NT Workstation/Server, it will not
+ work with NT policies because the registry key that are set by the policy templates.
+ However, the files from the NT Server will run happily enough on an NTws.
+ You need <TT
+CLASS="FILENAME"
+>poledit.exe, common.adm</TT
+> and <TT
+CLASS="FILENAME"
+>winnt.adm</TT
+>. It is convenient
+ to put the two *.adm files in <TT
+CLASS="FILENAME"
+>c:\winnt\inf</TT
+> which is where
+ the binary will look for them unless told otherwise. Note also that that
+ directory is 'hidden'.
+ </P
+><P
+> The Windows NT policy editor is also included with the Service Pack 3 (and
+ later) for Windows NT 4.0. Extract the files using <B
+CLASS="COMMAND"
+>servicepackname /x</B
+>,
+ i.e. that's <B
+CLASS="COMMAND"
+>Nt4sp6ai.exe /x</B
+> for service pack 6a. The policy editor,
+ <B
+CLASS="COMMAND"
+>poledit.exe</B
+> and the associated template files (*.adm) should
+ be extracted as well. It is also possible to downloaded the policy template
+ files for Office97 and get a copy of the policy editor. Another possible
+ location is with the Zero Administration Kit available for download from Microsoft.
+ </P
+></LI
+><LI
+><P
+> <EM
+>Can Win95 do Policies?</EM
+>
+ </P
+><P
+> Install the group policy handler for Win9x to pick up group
+ policies. Look on the Win98 CD in <TT
+CLASS="FILENAME"
+>\tools\reskit\netadmin\poledit</TT
+>.
+ Install group policies on a Win9x client by double-clicking
+ <TT
+CLASS="FILENAME"
+>grouppol.inf</TT
+>. Log off and on again a couple of
+ times and see if Win98 picks up group policies. Unfortunately this needs
+ to be done on every Win9x machine that uses group policies....
+ </P
+><P
+> If group policies don't work one reports suggests getting the updated
+ (read: working) grouppol.dll for Windows 9x. The group list is grabbed
+ from /etc/group.
+ </P
+></LI
+><LI
+><P
+> <EM
+>How do I get 'User Manager' and 'Server Manager'</EM
+>
+ </P
+><P
+> Since I don't need to buy an NT Server CD now, how do I get
+ the 'User Manager for Domains', the 'Server Manager'?
+ </P
+><P
+> Microsoft distributes a version of these tools called nexus for
+ installation on Windows 95 systems. The tools set includes
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Server Manager</P
+></LI
+><LI
+><P
+>User Manager for Domains</P
+></LI
+><LI
+><P
+>Event Viewer</P
+></LI
+></UL
+><P
+> Click here to download the archived file <A
+HREF="ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE"
+TARGET="_top"
+>ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE</A
+>
+ </P
+><P
+> The Windows NT 4.0 version of the 'User Manager for
+ Domains' and 'Server Manager' are available from Microsoft via ftp
+ from <A
+HREF="ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE"
+TARGET="_top"
+>ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE</A
+>
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1494"
+>9.7. What other help can I get?</A
+></H1
+><P
+>There are many sources of information available in the form
+of mailing lists, RFC's and documentation. The docs that come
+with the samba distribution contain very good explanations of
+general SMB topics such as browsing.</P
+><P
+></P
+><UL
+><LI
+><P
+> <EM
+>What are some diagnostics tools I can use to debug the domain logon
+ process and where can I find them?</EM
+>
+ </P
+><P
+> One of the best diagnostic tools for debugging problems is Samba itself.
+ You can use the -d option for both smbd and nmbd to specify what
+ 'debug level' at which to run. See the man pages on smbd, nmbd and
+ smb.conf for more information on debugging options. The debug
+ level can range from 1 (the default) to 10 (100 for debugging passwords).
+ </P
+><P
+> Another helpful method of debugging is to compile samba using the
+ <B
+CLASS="COMMAND"
+>gcc -g </B
+> flag. This will include debug
+ information in the binaries and allow you to attach gdb to the
+ running smbd / nmbd process. In order to attach gdb to an smbd
+ process for an NT workstation, first get the workstation to make the
+ connection. Pressing ctrl-alt-delete and going down to the domain box
+ is sufficient (at least, on the first time you join the domain) to
+ generate a 'LsaEnumTrustedDomains'. Thereafter, the workstation
+ maintains an open connection, and therefore there will be an smbd
+ process running (assuming that you haven't set a really short smbd
+ idle timeout) So, in between pressing ctrl alt delete, and actually
+ typing in your password, you can gdb attach and continue.
+ </P
+><P
+> Some useful samba commands worth investigating:
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>testparam | more</P
+></LI
+><LI
+><P
+>smbclient -L //{netbios name of server}</P
+></LI
+></UL
+><P
+> An SMB enabled version of tcpdump is available from
+ <A
+HREF="http://www.tcpdump.org/"
+TARGET="_top"
+>http://www.tcpdup.org/</A
+>.
+ Ethereal, another good packet sniffer for Unix and Win32
+ hosts, can be downloaded from <A
+HREF="http://www.ethereal.com/"
+TARGET="_top"
+>http://www.ethereal.com</A
+>.
+ </P
+><P
+> For tracing things on the Microsoft Windows NT, Network Monitor
+ (aka. netmon) is available on the Microsoft Developer Network CD's,
+ the Windows NT Server install CD and the SMS CD's. The version of
+ netmon that ships with SMS allows for dumping packets between any two
+ computers (i.e. placing the network interface in promiscuous mode).
+ The version on the NT Server install CD will only allow monitoring
+ of network traffic directed to the local NT box and broadcasts on the
+ local subnet. Be aware that Ethereal can read and write netmon
+ formatted files.
+ </P
+></LI
+><LI
+><P
+> <EM
+>How do I install 'Network Monitor' on an NT Workstation
+ or a Windows 9x box?</EM
+>
+ </P
+><P
+> Installing netmon on an NT workstation requires a couple
+ of steps. The following are for installing Netmon V4.00.349, which comes
+ with Microsoft Windows NT Server 4.0, on Microsoft Windows NT
+ Workstation 4.0. The process should be similar for other version of
+ Windows NT / Netmon. You will need both the Microsoft Windows
+ NT Server 4.0 Install CD and the Workstation 4.0 Install CD.
+ </P
+><P
+> Initially you will need to install 'Network Monitor Tools and Agent'
+ on the NT Server. To do this
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Goto Start - Settings - Control Panel -
+ Network - Services - Add </P
+></LI
+><LI
+><P
+>Select the 'Network Monitor Tools and Agent' and
+ click on 'OK'.</P
+></LI
+><LI
+><P
+>Click 'OK' on the Network Control Panel.
+ </P
+></LI
+><LI
+><P
+>Insert the Windows NT Server 4.0 install CD
+ when prompted.</P
+></LI
+></UL
+><P
+> At this point the Netmon files should exist in
+ <TT
+CLASS="FILENAME"
+>%SYSTEMROOT%\System32\netmon\*.*</TT
+>.
+ Two subdirectories exist as well, <TT
+CLASS="FILENAME"
+>parsers\</TT
+>
+ which contains the necessary DLL's for parsing the netmon packet
+ dump, and <TT
+CLASS="FILENAME"
+>captures\</TT
+>.
+ </P
+><P
+> In order to install the Netmon tools on an NT Workstation, you will
+ first need to install the 'Network Monitor Agent' from the Workstation
+ install CD.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Goto Start - Settings - Control Panel -
+ Network - Services - Add</P
+></LI
+><LI
+><P
+>Select the 'Network Monitor Agent' and click
+ on 'OK'.</P
+></LI
+><LI
+><P
+>Click 'OK' on the Network Control Panel.
+ </P
+></LI
+><LI
+><P
+>Insert the Windows NT Workstation 4.0 install
+ CD when prompted.</P
+></LI
+></UL
+><P
+> Now copy the files from the NT Server in %SYSTEMROOT%\System32\netmon\*.*
+ to %SYSTEMROOT%\System32\netmon\*.* on the Workstation and set
+ permissions as you deem appropriate for your site. You will need
+ administrative rights on the NT box to run netmon.
+ </P
+><P
+> To install Netmon on a Windows 9x box install the network monitor agent
+ from the Windows 9x CD (\admin\nettools\netmon). There is a readme
+ file located with the netmon driver files on the CD if you need
+ information on how to do this. Copy the files from a working
+ Netmon installation.
+ </P
+></LI
+><LI
+><P
+> The following is a list if helpful URLs and other links:
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Home of Samba site <A
+HREF="http://samba.org"
+TARGET="_top"
+> http://samba.org</A
+>. We have a mirror near you !</P
+></LI
+><LI
+><P
+> The <EM
+>Development</EM
+> document
+ on the Samba mirrors might mention your problem. If so,
+ it might mean that the developers are working on it.</P
+></LI
+><LI
+><P
+>See how Scott Merrill simulates a BDC behavior at
+ <A
+HREF="http://www.skippy.net/linux/smb-howto.html"
+TARGET="_top"
+> http://www.skippy.net/linux/smb-howto.html</A
+>. </P
+></LI
+><LI
+><P
+>Although 2.0.7 has almost had its day as a PDC, David Bannon will
+ keep the 2.0.7 PDC pages at <A
+HREF="http://bioserve.latrobe.edu.au/samba"
+TARGET="_top"
+> http://bioserve.latrobe.edu.au/samba</A
+> going for a while yet.</P
+></LI
+><LI
+><P
+>Misc links to CIFS information
+ <A
+HREF="http://samba.org/cifs/"
+TARGET="_top"
+>http://samba.org/cifs/</A
+></P
+></LI
+><LI
+><P
+>NT Domains for Unix <A
+HREF="http://mailhost.cb1.com/~lkcl/ntdom/"
+TARGET="_top"
+> http://mailhost.cb1.com/~lkcl/ntdom/</A
+></P
+></LI
+><LI
+><P
+>FTP site for older SMB specs:
+ <A
+HREF="ftp://ftp.microsoft.com/developr/drg/CIFS/"
+TARGET="_top"
+> ftp://ftp.microsoft.com/developr/drg/CIFS/</A
+></P
+></LI
+></UL
+></LI
+></UL
+><P
+></P
+><UL
+><LI
+><P
+> <EM
+>How do I get help from the mailing lists?</EM
+>
+ </P
+><P
+> There are a number of Samba related mailing lists. Go to <A
+HREF="http://samba.org"
+TARGET="_top"
+>http://samba.org</A
+>, click on your nearest mirror
+ and then click on <B
+CLASS="COMMAND"
+>Support</B
+> and then click on <B
+CLASS="COMMAND"
+> Samba related mailing lists</B
+>.
+ </P
+><P
+> For questions relating to Samba TNG go to
+ <A
+HREF="http://www.samba-tng.org/"
+TARGET="_top"
+>http://www.samba-tng.org/</A
+>
+ It has been requested that you don't post questions about Samba-TNG to the
+ main stream Samba lists.</P
+><P
+> If you post a message to one of the lists please observe the following guide lines :
+ </P
+><P
+></P
+><UL
+><LI
+><P
+> Always remember that the developers are volunteers, they are
+ not paid and they never guarantee to produce a particular feature at
+ a particular time. Any time lines are 'best guess' and nothing more.
+ </P
+></LI
+><LI
+><P
+> Always mention what version of samba you are using and what
+ operating system its running under. You should probably list the
+ relevant sections of your smb.conf file, at least the options
+ in [global] that affect PDC support.</P
+></LI
+><LI
+><P
+>In addition to the version, if you obtained Samba via
+ CVS mention the date when you last checked it out.</P
+></LI
+><LI
+><P
+> Try and make your question clear and brief, lots of long,
+ convoluted questions get deleted before they are completely read !
+ Don't post html encoded messages (if you can select colour or font
+ size its html).</P
+></LI
+><LI
+><P
+> If you run one of those nifty 'I'm on holidays' things when
+ you are away, make sure its configured to not answer mailing lists.
+ </P
+></LI
+><LI
+><P
+> Don't cross post. Work out which is the best list to post to
+ and see what happens, i.e. don't post to both samba-ntdom and samba-technical.
+ Many people active on the lists subscribe to more
+ than one list and get annoyed to see the same message two or more times.
+ Often someone will see a message and thinking it would be better dealt
+ with on another, will forward it on for you.</P
+></LI
+><LI
+><P
+>You might include <EM
+>partial</EM
+>
+ log files written at a debug level set to as much as 20.
+ Please don't send the entire log but enough to give the context of the
+ error messages.</P
+></LI
+><LI
+><P
+>(Possibly) If you have a complete netmon trace ( from the opening of
+ the pipe to the error ) you can send the *.CAP file as well.</P
+></LI
+><LI
+><P
+>Please think carefully before attaching a document to an email.
+ Consider pasting the relevant parts into the body of the message. The samba
+ mailing lists go to a huge number of people, do they all need a copy of your
+ smb.conf in their attach directory?</P
+></LI
+></UL
+></LI
+><LI
+><P
+> <EM
+>How do I get off the mailing lists?</EM
+>
+ </P
+><P
+>To have your name removed from a samba mailing list, go to the
+ same place you went to to get on it. Go to <A
+HREF="http://lists.samba.org/"
+TARGET="_top"
+>http://lists.samba.org</A
+>,
+ click on your nearest mirror and then click on <B
+CLASS="COMMAND"
+>Support</B
+> and
+ then click on <B
+CLASS="COMMAND"
+> Samba related mailing lists</B
+>. Or perhaps see
+ <A
+HREF="http://lists.samba.org/mailman/roster/samba-ntdom"
+TARGET="_top"
+>here</A
+>
+ </P
+><P
+> Please don't post messages to the list asking to be removed, you will just
+ be referred to the above address (unless that process failed in some way...)
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1608"
+>9.8. Domain Control for Windows 9x/ME</A
+></H1
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>The following section contains much of the original
+DOMAIN.txt file previously included with Samba. Much of
+the material is based on what went into the book <EM
+>Special
+Edition, Using Samba</EM
+>, by Richard Sharpe.</P
+></BLOCKQUOTE
+></DIV
+><P
+>A domain and a workgroup are exactly the same thing in terms of network
+browsing. The difference is that a distributable authentication
+database is associated with a domain, for secure login access to a
+network. Also, different access rights can be granted to users if they
+successfully authenticate against a domain logon server (NT server and
+other systems based on NT server support this, as does at least Samba TNG now).</P
+><P
+>The SMB client logging on to a domain has an expectation that every other
+server in the domain should accept the same authentication information.
+Network browsing functionality of domains and workgroups is
+identical and is explained in BROWSING.txt. It should be noted, that browsing
+is totally orthogonal to logon support.</P
+><P
+>Issues related to the single-logon network model are discussed in this
+section. Samba supports domain logons, network logon scripts, and user
+profiles for MS Windows for workgroups and MS Windows 9X/ME clients
+which will be the focus of this section.</P
+><P
+>When an SMB client in a domain wishes to logon it broadcast requests for a
+logon server. The first one to reply gets the job, and validates its
+password using whatever mechanism the Samba administrator has installed.
+It is possible (but very stupid) to create a domain where the user
+database is not shared between servers, i.e. they are effectively workgroup
+servers advertising themselves as participating in a domain. This
+demonstrates how authentication is quite different from but closely
+involved with domains.</P
+><P
+>Using these features you can make your clients verify their logon via
+the Samba server; make clients run a batch file when they logon to
+the network and download their preferences, desktop and start menu.</P
+><P
+>Before launching into the configuration instructions, it is
+worthwhile lookingat how a Windows 9x/ME client performs a logon:</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> The client broadcasts (to the IP broadcast address of the subnet it is in)
+ a NetLogon request. This is sent to the NetBIOS name DOMAIN&#60;1c&#62; at the
+ NetBIOS layer. The client chooses the first response it receives, which
+ contains the NetBIOS name of the logon server to use in the format of
+ \\SERVER.
+ </P
+></LI
+><LI
+><P
+> The client then connects to that server, logs on (does an SMBsessetupX) and
+ then connects to the IPC$ share (using an SMBtconX).
+ </P
+></LI
+><LI
+><P
+> The client then does a NetWkstaUserLogon request, which retrieves the name
+ of the user's logon script.
+ </P
+></LI
+><LI
+><P
+> The client then connects to the NetLogon share and searches for this
+ and if it is found and can be read, is retrieved and executed by the client.
+ After this, the client disconnects from the NetLogon share.
+ </P
+></LI
+><LI
+><P
+> The client then sends a NetUserGetInfo request to the server, to retrieve
+ the user's home share, which is used to search for profiles. Since the
+ response to the NetUserGetInfo request does not contain much more
+ the user's home share, profiles for Win9X clients MUST reside in the user
+ home directory.
+ </P
+></LI
+><LI
+><P
+> The client then connects to the user's home share and searches for the
+ user's profile. As it turns out, you can specify the user's home share as
+ a sharename and path. For example, \\server\fred\.profile.
+ If the profiles are found, they are implemented.
+ </P
+></LI
+><LI
+><P
+> The client then disconnects from the user's home share, and reconnects to
+ the NetLogon share and looks for CONFIG.POL, the policies file. If this is
+ found, it is read and implemented.
+ </P
+></LI
+></OL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1634"
+>9.8.1. Configuration Instructions: Network Logons</A
+></H2
+><P
+>The main difference between a PDC and a Windows 9x logon
+server configuration is that</P
+><P
+></P
+><UL
+><LI
+><P
+>Password encryption is not required for a Windows 9x logon server.</P
+></LI
+><LI
+><P
+>Windows 9x/ME clients do not possess machine trust accounts.</P
+></LI
+></UL
+><P
+>Therefore, a Samba PDC will also act as a Windows 9x logon
+server.</P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>security mode and master browsers</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>There are a few comments to make in order to tie up some
+loose ends. There has been much debate over the issue of whether
+or not it is ok to configure Samba as a Domain Controller in security
+modes other than <TT
+CLASS="CONSTANT"
+>USER</TT
+>. The only security mode
+which will not work due to technical reasons is <TT
+CLASS="CONSTANT"
+>SHARE</TT
+>
+mode security. <TT
+CLASS="CONSTANT"
+>DOMAIN</TT
+> and <TT
+CLASS="CONSTANT"
+>SERVER</TT
+>
+mode security is really just a variation on SMB user level security.</P
+><P
+>Actually, this issue is also closely tied to the debate on whether
+or not Samba must be the domain master browser for its workgroup
+when operating as a DC. While it may technically be possible
+to configure a server as such (after all, browsing and domain logons
+are two distinctly different functions), it is not a good idea to
+so. You should remember that the DC must register the DOMAIN#1b NetBIOS
+name. This is the name used by Windows clients to locate the DC.
+Windows clients do not distinguish between the DC and the DMB.
+For this reason, it is very wise to configure the Samba DC as the DMB.</P
+><P
+>Now back to the issue of configuring a Samba DC to use a mode other
+than "security = user". If a Samba host is configured to use
+another SMB server or DC in order to validate user connection
+requests, then it is a fact that some other machine on the network
+(the "password server") knows more about user than the Samba host.
+99% of the time, this other host is a domain controller. Now
+in order to operate in domain mode security, the "workgroup" parameter
+must be set to the name of the Windows NT domain (which already
+has a domain controller, right?)</P
+><P
+>Therefore configuring a Samba box as a DC for a domain that
+already by definition has a PDC is asking for trouble.
+Therefore, you should always configure the Samba DC to be the DMB
+for its domain.</P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1653"
+>9.8.2. Configuration Instructions: Setting up Roaming User Profiles</A
+></H2
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Warning</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+><EM
+>NOTE!</EM
+> Roaming profiles support is different
+for Win9X and WinNT.</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>Before discussing how to configure roaming profiles, it is useful to see how
+Win9X and WinNT clients implement these features.</P
+><P
+>Win9X clients send a NetUserGetInfo request to the server to get the user's
+profiles location. However, the response does not have room for a separate
+profiles location field, only the user's home share. This means that Win9X
+profiles are restricted to being in the user's home directory.</P
+><P
+>WinNT clients send a NetSAMLogon RPC request, which contains many fields,
+including a separate field for the location of the user's profiles.
+This means that support for profiles is different for Win9X and WinNT.</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1661"
+>9.8.2.1. Windows NT Configuration</A
+></H3
+><P
+>To support WinNT clients, in the [global] section of smb.conf set the
+following (for example):</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>logon path = \\profileserver\profileshare\profilepath\%U\moreprofilepath</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The default for this option is \\%N\%U\profile, namely
+\\sambaserver\username\profile. The \\N%\%U service is created
+automatically by the [homes] service.
+If you are using a samba server for the profiles, you _must_ make the
+share specified in the logon path browseable. </P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 26aug96 - we have discovered a problem where Windows clients can
+maintain a connection to the [homes] share in between logins. The
+[homes] share must NOT therefore be used in a profile path.]</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1669"
+>9.8.2.2. Windows 9X Configuration</A
+></H3
+><P
+>To support Win9X clients, you must use the "logon home" parameter. Samba has
+now been fixed so that "net use/home" now works as well, and it, too, relies
+on the "logon home" parameter.</P
+><P
+>By using the logon home parameter, you are restricted to putting Win9X
+profiles in the user's home directory. But wait! There is a trick you
+can use. If you set the following in the [global] section of your
+smb.conf file:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>logon home = \\%L\%U\.profiles</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>then your Win9X clients will dutifully put their clients in a subdirectory
+of your home directory called .profiles (thus making them hidden).</P
+><P
+>Not only that, but 'net use/home' will also work, because of a feature in
+Win9X. It removes any directory stuff off the end of the home directory area
+and only uses the server and share portion. That is, it looks like you
+specified \\%L\%U for "logon home".</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1677"
+>9.8.2.3. Win9X and WinNT Configuration</A
+></H3
+><P
+>You can support profiles for both Win9X and WinNT clients by setting both the
+"logon home" and "logon path" parameters. For example:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>logon home = \\%L\%U\.profiles
+logon path = \\%L\profiles\%U</PRE
+></TD
+></TR
+></TABLE
+></P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>I have not checked what 'net use /home' does on NT when "logon home" is
+set as above.</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1684"
+>9.8.2.4. Windows 9X Profile Setup</A
+></H3
+><P
+>When a user first logs in on Windows 9X, the file user.DAT is created,
+as are folders "Start Menu", "Desktop", "Programs" and "Nethood".
+These directories and their contents will be merged with the local
+versions stored in c:\windows\profiles\username on subsequent logins,
+taking the most recent from each. You will need to use the [global]
+options "preserve case = yes", "short preserve case = yes" and
+"case sensitive = no" in order to maintain capital letters in shortcuts
+in any of the profile folders.</P
+><P
+>The user.DAT file contains all the user's preferences. If you wish to
+enforce a set of preferences, rename their user.DAT file to user.MAN,
+and deny them write access to this file.</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> On the Windows 95 machine, go to Control Panel | Passwords and
+ select the User Profiles tab. Select the required level of
+ roaming preferences. Press OK, but do _not_ allow the computer
+ to reboot.
+ </P
+></LI
+><LI
+><P
+> On the Windows 95 machine, go to Control Panel | Network |
+ Client for Microsoft Networks | Preferences. Select 'Log on to
+ NT Domain'. Then, ensure that the Primary Logon is 'Client for
+ Microsoft Networks'. Press OK, and this time allow the computer
+ to reboot.
+ </P
+></LI
+></OL
+><P
+>Under Windows 95, Profiles are downloaded from the Primary Logon.
+If you have the Primary Logon as 'Client for Novell Networks', then
+the profiles and logon script will be downloaded from your Novell
+Server. If you have the Primary Logon as 'Windows Logon', then the
+profiles will be loaded from the local machine - a bit against the
+concept of roaming profiles, if you ask me.</P
+><P
+>You will now find that the Microsoft Networks Login box contains
+[user, password, domain] instead of just [user, password]. Type in
+the samba server's domain name (or any other domain known to exist,
+but bear in mind that the user will be authenticated against this
+domain and profiles downloaded from it, if that domain logon server
+supports it), user name and user's password.</P
+><P
+>Once the user has been successfully validated, the Windows 95 machine
+will inform you that 'The user has not logged on before' and asks you
+if you wish to save the user's preferences? Select 'yes'.</P
+><P
+>Once the Windows 95 client comes up with the desktop, you should be able
+to examine the contents of the directory specified in the "logon path"
+on the samba server and verify that the "Desktop", "Start Menu",
+"Programs" and "Nethood" folders have been created.</P
+><P
+>These folders will be cached locally on the client, and updated when
+the user logs off (if you haven't made them read-only by then :-).
+You will find that if the user creates further folders or short-cuts,
+that the client will merge the profile contents downloaded with the
+contents of the profile directory already on the local client, taking
+the newest folders and short-cuts from each set.</P
+><P
+>If you have made the folders / files read-only on the samba server,
+then you will get errors from the w95 machine on logon and logout, as
+it attempts to merge the local and the remote profile. Basically, if
+you have any errors reported by the w95 machine, check the Unix file
+permissions and ownership rights on the profile directory contents,
+on the samba server.</P
+><P
+>If you have problems creating user profiles, you can reset the user's
+local desktop cache, as shown below. When this user then next logs in,
+they will be told that they are logging in "for the first time".</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> instead of logging in under the [user, password, domain] dialog,
+ press escape.
+ </P
+></LI
+><LI
+><P
+> run the regedit.exe program, and look in:
+ </P
+><P
+> HKEY_LOCAL_MACHINE\Windows\CurrentVersion\ProfileList
+ </P
+><P
+> you will find an entry, for each user, of ProfilePath. Note the
+ contents of this key (likely to be c:\windows\profiles\username),
+ then delete the key ProfilePath for the required user.
+ </P
+><P
+> [Exit the registry editor].
+ </P
+></LI
+><LI
+><P
+> <EM
+>WARNING</EM
+> - before deleting the contents of the
+ directory listed in
+ the ProfilePath (this is likely to be c:\windows\profiles\username),
+ ask them if they have any important files stored on their desktop
+ or in their start menu. delete the contents of the directory
+ ProfilePath (making a backup if any of the files are needed).
+ </P
+><P
+> This will have the effect of removing the local (read-only hidden
+ system file) user.DAT in their profile directory, as well as the
+ local "desktop", "nethood", "start menu" and "programs" folders.
+ </P
+></LI
+><LI
+><P
+> search for the user's .PWL password-caching file in the c:\windows
+ directory, and delete it.
+ </P
+></LI
+><LI
+><P
+> log off the windows 95 client.
+ </P
+></LI
+><LI
+><P
+> check the contents of the profile path (see "logon path" described
+ above), and delete the user.DAT or user.MAN file for the user,
+ making a backup if required.
+ </P
+></LI
+></OL
+><P
+>If all else fails, increase samba's debug log levels to between 3 and 10,
+and / or run a packet trace program such as tcpdump or netmon.exe, and
+look for any error reports.</P
+><P
+>If you have access to an NT server, then first set up roaming profiles
+and / or netlogons on the NT server. Make a packet trace, or examine
+the example packet traces provided with NT server, and see what the
+differences are with the equivalent samba trace.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1720"
+>9.8.2.5. Windows NT Workstation 4.0</A
+></H3
+><P
+>When a user first logs in to a Windows NT Workstation, the profile
+NTuser.DAT is created. The profile location can be now specified
+through the "logon path" parameter. </P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 10aug97 - i tried setting the path to
+\\samba-server\homes\profile, and discovered that this fails because
+a background process maintains the connection to the [homes] share
+which does _not_ close down in between user logins. you have to
+have \\samba-server\%L\profile, where user is the username created
+from the [homes] share].</P
+></BLOCKQUOTE
+></DIV
+><P
+>There is a parameter that is now available for use with NT Profiles:
+"logon drive". This should be set to "h:" or any other drive, and
+should be used in conjunction with the new "logon home" parameter.</P
+><P
+>The entry for the NT 4.0 profile is a _directory_ not a file. The NT
+help on profiles mentions that a directory is also created with a .PDS
+extension. The user, while logging in, must have write permission to
+create the full profile path (and the folder with the .PDS extension)
+[lkcl 10aug97 - i found that the creation of the .PDS directory failed,
+and had to create these manually for each user, with a shell script.
+also, i presume, but have not tested, that the full profile path must
+be browseable just as it is for w95, due to the manner in which they
+attempt to create the full profile path: test existence of each path
+component; create path component].</P
+><P
+>In the profile directory, NT creates more folders than 95. It creates
+"Application Data" and others, as well as "Desktop", "Nethood",
+"Start Menu" and "Programs". The profile itself is stored in a file
+NTuser.DAT. Nothing appears to be stored in the .PDS directory, and
+its purpose is currently unknown.</P
+><P
+>You can use the System Control Panel to copy a local profile onto
+a samba server (see NT Help on profiles: it is also capable of firing
+up the correct location in the System Control Panel for you). The
+NT Help file also mentions that renaming NTuser.DAT to NTuser.MAN
+turns a profile into a mandatory one.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 10aug97 - i notice that NT Workstation tells me that it is
+downloading a profile from a slow link. whether this is actually the
+case, or whether there is some configuration issue, as yet unknown,
+that makes NT Workstation _think_ that the link is a slow one is a
+matter to be resolved].</P
+><P
+>[lkcl 20aug97 - after samba digest correspondence, one user found, and
+another confirmed, that profiles cannot be loaded from a samba server
+unless "security = user" and "encrypt passwords = yes" (see the file
+ENCRYPTION.txt) or "security = server" and "password server = ip.address.
+of.yourNTserver" are used. Either of these options will allow the NT
+workstation to access the samba server using LAN manager encrypted
+passwords, without the user intervention normally required by NT
+workstation for clear-text passwords].</P
+><P
+>[lkcl 25aug97 - more comments received about NT profiles: the case of
+the profile _matters_. the file _must_ be called NTuser.DAT or, for
+a mandatory profile, NTuser.MAN].</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1733"
+>9.8.2.6. Windows NT Server</A
+></H3
+><P
+>There is nothing to stop you specifying any path that you like for the
+location of users' profiles. Therefore, you could specify that the
+profile be stored on a samba server, or any other SMB server, as long as
+that SMB server supports encrypted passwords.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN1736"
+>9.8.2.7. Sharing Profiles between W95 and NT Workstation 4.0</A
+></H3
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Potentially outdated or incorrect material follows</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>I think this is all bogus, but have not deleted it. (Richard Sharpe)</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>The default logon path is \\%N\U%. NT Workstation will attempt to create
+a directory "\\samba-server\username.PDS" if you specify the logon path
+as "\\samba-server\username" with the NT User Manager. Therefore, you
+will need to specify (for example) "\\samba-server\username\profile".
+NT 4.0 will attempt to create "\\samba-server\username\profile.PDS", which
+is more likely to succeed.</P
+><P
+>If you then want to share the same Start Menu / Desktop with W95, you will
+need to specify "logon path = \\samba-server\username\profile" [lkcl 10aug97
+this has its drawbacks: i created a shortcut to telnet.exe, which attempts
+to run from the c:\winnt\system32 directory. this directory is obviously
+unlikely to exist on a Win95-only host].</P
+><P
+>&#13;If you have this set up correctly, you will find separate user.DAT and
+NTuser.DAT files in the same profile directory.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 25aug97 - there are some issues to resolve with downloading of
+NT profiles, probably to do with time/date stamps. i have found that
+NTuser.DAT is never updated on the workstation after the first time that
+it is copied to the local workstation profile directory. this is in
+contrast to w95, where it _does_ transfer / update profiles correctly].</P
+></BLOCKQUOTE
+></DIV
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1746"
+>9.9. DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
+></H1
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Possibly Outdated Material</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+> This appendix was originally authored by John H Terpstra of
+ the Samba Team and is included here for posterity.
+ </P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+><EM
+>NOTE :</EM
+>
+The term "Domain Controller" and those related to it refer to one specific
+method of authentication that can underly an SMB domain. Domain Controllers
+prior to Windows NT Server 3.1 were sold by various companies and based on
+private extensions to the LAN Manager 2.1 protocol. Windows NT introduced
+Microsoft-specific ways of distributing the user authentication database.
+See DOMAIN.txt for examples of how Samba can participate in or create
+SMB domains based on shared authentication database schemes other than the
+Windows NT SAM.</P
+><P
+>Windows NT Server can be installed as either a plain file and print server
+(WORKGROUP workstation or server) or as a server that participates in Domain
+Control (DOMAIN member, Primary Domain controller or Backup Domain controller).
+The same is true for OS/2 Warp Server, Digital Pathworks and other similar
+products, all of which can participate in Domain Control along with Windows NT.</P
+><P
+>To many people these terms can be confusing, so let's try to clear the air.</P
+><P
+>Every Windows NT system (workstation or server) has a registry database.
+The registry contains entries that describe the initialization information
+for all services (the equivalent of Unix Daemons) that run within the Windows
+NT environment. The registry also contains entries that tell application
+software where to find dynamically loadable libraries that they depend upon.
+In fact, the registry contains entries that describes everything that anything
+may need to know to interact with the rest of the system.</P
+><P
+>The registry files can be located on any Windows NT machine by opening a
+command prompt and typing:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINNT\&#62;</TT
+> dir %SystemRoot%\System32\config</P
+><P
+>The environment variable %SystemRoot% value can be obtained by typing:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINNT&#62;</TT
+>echo %SystemRoot%</P
+><P
+>The active parts of the registry that you may want to be familiar with are
+the files called: default, system, software, sam and security.</P
+><P
+>In a domain environment, Microsoft Windows NT domain controllers participate
+in replication of the SAM and SECURITY files so that all controllers within
+the domain have an exactly identical copy of each.</P
+><P
+>The Microsoft Windows NT system is structured within a security model that
+says that all applications and services must authenticate themselves before
+they can obtain permission from the security manager to do what they set out
+to do.</P
+><P
+>The Windows NT User database also resides within the registry. This part of
+the registry contains the user's security identifier, home directory, group
+memberships, desktop profile, and so on.</P
+><P
+>Every Windows NT system (workstation as well as server) will have its own
+registry. Windows NT Servers that participate in Domain Security control
+have a database that they share in common - thus they do NOT own an
+independent full registry database of their own, as do Workstations and
+plain Servers.</P
+><P
+>The User database is called the SAM (Security Access Manager) database and
+is used for all user authentication as well as for authentication of inter-
+process authentication (i.e. to ensure that the service action a user has
+requested is permitted within the limits of that user's privileges).</P
+><P
+>The Samba team have produced a utility that can dump the Windows NT SAM into
+smbpasswd format: see ENCRYPTION.txt for information on smbpasswd and
+/pub/samba/pwdump on your nearest Samba mirror for the utility. This
+facility is useful but cannot be easily used to implement SAM replication
+to Samba systems.</P
+><P
+>Windows for Workgroups, Windows 95, and Windows NT Workstations and Servers
+can participate in a Domain security system that is controlled by Windows NT
+servers that have been correctly configured. Almost every domain will have
+ONE Primary Domain Controller (PDC). It is desirable that each domain will
+have at least one Backup Domain Controller (BDC).</P
+><P
+>The PDC and BDCs then participate in replication of the SAM database so that
+each Domain Controlling participant will have an up to date SAM component
+within its registry.</P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="SAMBA-BDC"
+>Chapter 10. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN1782"
+>10.1. Prerequisite Reading</A
+></H1
+><P
+>Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring a Samba PDC
+as described in the <A
+HREF="Samba-PDC-HOWTO.html"
+TARGET="_top"
+>Samba-PDC-HOWTO</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1786"
+>10.2. Background</A
+></H1
+><P
+>What is a Domain Controller? It is a machine that is able to answer
+logon requests from workstations in a Windows NT Domain. Whenever a
+user logs into a Windows NT Workstation, the workstation connects to a
+Domain Controller and asks him whether the username and password the
+user typed in is correct. The Domain Controller replies with a lot of
+information about the user, for example the place where the users
+profile is stored, the users full name of the user. All this
+information is stored in the NT user database, the so-called SAM.</P
+><P
+>There are two kinds of Domain Controller in a NT 4 compatible Domain:
+A Primary Domain Controller (PDC) and one or more Backup Domain
+Controllers (BDC). The PDC contains the master copy of the
+SAM. Whenever the SAM has to change, for example when a user changes
+his password, this change has to be done on the PDC. A Backup Domain
+Controller is a machine that maintains a read-only copy of the
+SAM. This way it is able to reply to logon requests and authenticate
+users in case the PDC is not available. During this time no changes to
+the SAM are possible. Whenever changes to the SAM are done on the PDC,
+all BDC receive the changes from the PDC.</P
+><P
+>Since version 2.2 Samba officially supports domain logons for all
+current Windows Clients, including Windows 2000 and XP. This text
+assumes the domain to be named SAMBA. To be able to act as a PDC, some
+parameters in the [global]-section of the smb.conf have to be set:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ workgroup = SAMBA
+ domain master = yes
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Several other things like a [homes] and a [netlogon] share also may be
+set along with settings for the profile path, the users home drive and
+others. This will not be covered in this document.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1794"
+>10.3. What qualifies a Domain Controller on the network?</A
+></H1
+><P
+>Every machine that is a Domain Controller for the domain SAMBA has to
+register the NetBIOS group name SAMBA#1c with the WINS server and/or
+by broadcast on the local network. The PDC also registers the unique
+NetBIOS name SAMBA#1b with the WINS server. The name type #1b is
+normally reserved for the domain master browser, a role that has
+nothing to do with anything related to authentication, but the
+Microsoft Domain implementation requires the domain master browser to
+be on the same machine as the PDC.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1797"
+>10.3.1. How does a Workstation find its domain controller?</A
+></H2
+><P
+>A NT workstation in the domain SAMBA that wants a local user to be
+authenticated has to find the domain controller for SAMBA. It does
+this by doing a NetBIOS name query for the group name SAMBA#1c. It
+assumes that each of the machines it gets back from the queries is a
+domain controller and can answer logon requests. To not open security
+holes both the workstation and the selected (TODO: How is the DC
+chosen) domain controller authenticate each other. After that the
+workstation sends the user's credentials (his name and password) to
+the domain controller, asking for approval.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1800"
+>10.3.2. When is the PDC needed?</A
+></H2
+><P
+>Whenever a user wants to change his password, this has to be done on
+the PDC. To find the PDC, the workstation does a NetBIOS name query
+for SAMBA#1b, assuming this machine maintains the master copy of the
+SAM. The workstation contacts the PDC, both mutually authenticate and
+the password change is done.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1803"
+>10.4. Can Samba be a Backup Domain Controller?</A
+></H1
+><P
+>With version 2.2, no. The native NT SAM replication protocols have
+not yet been fully implemented. The Samba Team is working on
+understanding and implementing the protocols, but this work has not
+been finished for version 2.2.</P
+><P
+>Can I get the benefits of a BDC with Samba? Yes. The main reason for
+implementing a BDC is availability. If the PDC is a Samba machine,
+a second Samba machine can be set up to
+service logon requests whenever the PDC is down.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1807"
+>10.5. How do I set up a Samba BDC?</A
+></H1
+><P
+>Several things have to be done:</P
+><P
+></P
+><UL
+><LI
+><P
+> The file <TT
+CLASS="FILENAME"
+>private/MACHINE.SID</TT
+> identifies the domain. When a samba
+ server is first started, it is created on the fly and must never be
+ changed again. This file has to be the same on the PDC and the BDC,
+ so the MACHINE.SID has to be copied from the PDC to the BDC. Note that in the
+ latest Samba 2.2.x releases, the machine SID (and therefore domain SID) is stored
+ in the <TT
+CLASS="FILENAME"
+>private/secrets.tdb</TT
+> database. This file cannot just
+ be copied because Samba looks under the key <TT
+CLASS="CONSTANT"
+>SECRETS/SID/<TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+></TT
+>.
+ where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+> is the machine's netbios name. Since this name has
+ to be unique for each SAMBA server, this lookup will fail. </P
+><P
+> A new option has been added to the <B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+>
+ command to help ease this problem. When running <B
+CLASS="COMMAND"
+>smbpasswd -S</B
+> as the root user,
+ the domain SID will be retrieved from a domain controller matching the value of the
+ <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> parameter in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> and stored as the
+ new Samba server's machine SID. See the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+>
+ man page for more details on this functionality.
+ </P
+></LI
+><LI
+><P
+> The Unix user database has to be synchronized from the PDC to the
+ BDC. This means that both the /etc/passwd and /etc/group have to be
+ replicated from the PDC to the BDC. This can be done manually
+ whenever changes are made, or the PDC is set up as a NIS master
+ server and the BDC as a NIS slave server. To set up the BDC as a
+ mere NIS client would not be enough, as the BDC would not be able to
+ access its user database in case of a PDC failure. LDAP is also a
+ potential vehicle for sharing this information.
+ </P
+></LI
+><LI
+><P
+> The Samba password database in the file <TT
+CLASS="FILENAME"
+>private/smbpasswd</TT
+>
+ has to be replicated from the PDC to the BDC. This is a bit tricky, see the
+ next section.
+ </P
+></LI
+><LI
+><P
+> Any netlogon share has to be replicated from the PDC to the
+ BDC. This can be done manually whenever login scripts are changed,
+ or it can be done automatically together with the smbpasswd
+ synchronization.
+ </P
+></LI
+></UL
+><P
+>Finally, the BDC has to be found by the workstations. This can be done
+by setting</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ workgroup = SAMBA
+ domain master = no
+ domain logons = yes
+ encrypt passwords = yes
+ security = user
+ ....</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>in the [global]-section of the smb.conf of the BDC. This makes the BDC
+only register the name SAMBA#1c with the WINS server. This is no
+problem as the name SAMBA#1c is a NetBIOS group name that is meant to
+be registered by more than one machine. The parameter 'domain master =
+no' forces the BDC not to register SAMBA#1b which as a unique NetBIOS
+name is reserved for the Primary Domain Controller.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1836"
+>10.5.1. How do I replicate the smbpasswd file?</A
+></H2
+><P
+>Replication of the smbpasswd file is sensitive. It has to be done
+whenever changes to the SAM are made. Every user's password change
+(including machine trust account password changes) is done in the
+smbpasswd file and has to be replicated to the BDC. So
+replicating the smbpasswd file very often is necessary.</P
+><P
+>As the smbpasswd file contains plain text password equivalents, it
+must not be sent unencrypted over the wire. The best way to set up
+smbpasswd replication from the PDC to the BDC is to use the utility
+<B
+CLASS="COMMAND"
+>rsync(1)</B
+>. <B
+CLASS="COMMAND"
+>rsync</B
+> can use
+<B
+CLASS="COMMAND"
+>ssh(1)</B
+> as a transport. <B
+CLASS="COMMAND"
+>ssh</B
+> itself
+can be set up to accept <EM
+>only</EM
+> <B
+CLASS="COMMAND"
+>rsync</B
+> transfer without requiring the user to
+type a password. Refer to the man pages for these two tools for more details.</P
+><P
+>Another solution with high potential is to use Samba's <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+for sharing and/or replicating the list of <TT
+CLASS="CONSTANT"
+>sambaAccount</TT
+> entries.
+This can all be done over SSL to ensure security. See the <A
+HREF="Samba-LDAP-HOWTO.html"
+TARGET="_top"
+>Samba-LDAP-HOWTO</A
+>
+for more details.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="SAMBA-LDAP-HOWTO"
+>Chapter 11. Storing Samba's User/Machine Account information in an LDAP Directory</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN1867"
+>11.1. Purpose</A
+></H1
+><P
+>This document describes how to use an LDAP directory for storing Samba user
+account information traditionally stored in the smbpasswd(5) file. It is
+assumed that the reader already has a basic understanding of LDAP concepts
+and has a working directory server already installed. For more information
+on LDAP architectures and Directories, please refer to the following sites.</P
+><P
+></P
+><UL
+><LI
+><P
+>OpenLDAP - <A
+HREF="http://www.openldap.org/"
+TARGET="_top"
+>http://www.openldap.org/</A
+></P
+></LI
+><LI
+><P
+>iPlanet Directory Server - <A
+HREF="http://iplanet.netscape.com/directory"
+TARGET="_top"
+>http://iplanet.netscape.com/directory</A
+></P
+></LI
+></UL
+><P
+>Note that <A
+HREF="http://www.ora.com/"
+TARGET="_top"
+>O'Reilly Publishing</A
+> is working on
+a guide to LDAP for System Administrators which has a planned release date of
+late 2002.</P
+><P
+>Two additional Samba resources which may prove to be helpful are</P
+><P
+></P
+><UL
+><LI
+><P
+>The <A
+HREF="http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html"
+TARGET="_top"
+>Samba-PDC-LDAP-HOWTO</A
+>
+ maintained by Ignacio Coupeau.</P
+></LI
+><LI
+><P
+>The NT migration scripts from <A
+HREF="http://samba.idealx.org/"
+TARGET="_top"
+>IDEALX</A
+> that are
+ geared to manage users and group in such a Samba-LDAP Domain Controller configuration. These scripts can
+ be found in the Samba 2.2.5 release in the <TT
+CLASS="FILENAME"
+>examples/LDAP/smbldap-tools/</TT
+> directory.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1888"
+>11.2. Introduction</A
+></H1
+><P
+>Traditionally, when configuring <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>"encrypt
+passwords = yes"</A
+> in Samba's <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file, user account
+information such as username, LM/NT password hashes, password change times, and account
+flags have been stored in the <TT
+CLASS="FILENAME"
+>smbpasswd(5)</TT
+> file. There are several
+disadvantages to this approach for sites with very large numbers of users (counted
+in the thousands).</P
+><P
+></P
+><UL
+><LI
+><P
+>The first is that all lookups must be performed sequentially. Given that
+there are approximately two lookups per domain logon (one for a normal
+session connection such as when mapping a network drive or printer), this
+is a performance bottleneck for large sites. What is needed is an indexed approach
+such as is used in databases.</P
+></LI
+><LI
+><P
+>The second problem is that administrators who desired to replicate a
+smbpasswd file to more than one Samba server were left to use external
+tools such as <B
+CLASS="COMMAND"
+>rsync(1)</B
+> and <B
+CLASS="COMMAND"
+>ssh(1)</B
+>
+and wrote custom, in-house scripts.</P
+></LI
+><LI
+><P
+>And finally, the amount of information which is stored in an
+smbpasswd entry leaves no room for additional attributes such as
+a home directory, password expiration time, or even a Relative
+Identified (RID).</P
+></LI
+></UL
+><P
+>As a result of these defeciencies, a more robust means of storing user attributes
+used by <B
+CLASS="COMMAND"
+>smbd</B
+> was developed. The API which defines access to user accounts
+is commonly referred to as the samdb interface (previously this was called the passdb
+API, and is still so named in the CVS trees). In Samba 2.2.3, enabling support
+for a samdb backend (e.g. <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+> or
+<TT
+CLASS="PARAMETER"
+><I
+>--with-tdbsam</I
+></TT
+>) requires compile time support.</P
+><P
+>When compiling Samba to include the <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+> autoconf
+option, <B
+CLASS="COMMAND"
+>smbd</B
+> (and associated tools) will store and lookup user accounts in
+an LDAP directory. In reality, this is very easy to understand. If you are
+comfortable with using an smbpasswd file, simply replace "smbpasswd" with
+"LDAP directory" in all the documentation.</P
+><P
+>There are a few points to stress about what the <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+does not provide. The LDAP support referred to in the this documentation does not
+include:</P
+><P
+></P
+><UL
+><LI
+><P
+>A means of retrieving user account information from
+ an Windows 2000 Active Directory server.</P
+></LI
+><LI
+><P
+>A means of replacing /etc/passwd.</P
+></LI
+></UL
+><P
+>The second item can be accomplished by using LDAP NSS and PAM modules. LGPL
+versions of these libraries can be obtained from PADL Software
+(<A
+HREF="http://www.padl.com/"
+TARGET="_top"
+>http://www.padl.com/</A
+>). However,
+the details of configuring these packages are beyond the scope of this document.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1919"
+>11.3. Supported LDAP Servers</A
+></H1
+><P
+>The LDAP samdb code in 2.2.3 has been developed and tested using the OpenLDAP
+2.0 server and client libraries. The same code should be able to work with
+Netscape's Directory Server and client SDK. However, due to lack of testing
+so far, there are bound to be compile errors and bugs. These should not be
+hard to fix. If you are so inclined, please be sure to forward all patches to
+<A
+HREF="samba-patches@samba.org"
+TARGET="_top"
+>samba-patches@samba.org</A
+> and
+<A
+HREF="jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1924"
+>11.4. Schema and Relationship to the RFC 2307 posixAccount</A
+></H1
+><P
+>Samba 2.2.3 includes the necessary schema file for OpenLDAP 2.0 in
+<TT
+CLASS="FILENAME"
+>examples/LDAP/samba.schema</TT
+>. (Note that this schema
+file has been modified since the experimental support initially included
+in 2.2.2). The sambaAccount objectclass is given here:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>objectclass ( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILARY
+ DESC 'Samba Account'
+ MUST ( uid $ rid )
+ MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ description $ userWorkstations $ primaryGroupID $ domain ))</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file has been formatted for OpenLDAP 2.0 &#38; 2.1. The OID's are
+owned by the Samba Team and as such is legal to be openly published.
+If you translate the schema to be used with Netscape DS, please
+submit the modified schema file as a patch to <A
+HREF="jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+></P
+><P
+>Since the original release, schema files for</P
+><P
+></P
+><UL
+><LI
+><P
+>IBM's SecureWay Server</P
+></LI
+><LI
+><P
+>Netscape Directory Server version 4.x and 5.x</P
+></LI
+></UL
+><P
+>have been submitted and included in the Samba source distribution. I cannot
+personally comment on the integration of these commercial directory servers since
+I have not had the oppotinuity to work with them.</P
+><P
+>Just as the smbpasswd file is mean to store information which supplements a
+user's <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry, so is the sambaAccount object
+meant to supplement the UNIX user account information. A sambaAccount is now an
+<TT
+CLASS="CONSTANT"
+>AUXILARY</TT
+> objectclass so it can be stored alongside
+a posixAccount or person objectclass in the directory. Note that there are
+several fields (e.g. uid) which overlap with the posixAccount objectclass
+outlined in RFC2307. This is by design. The move from a STRUCTURAL objectclass
+to an AUXILIARY one was compliance with the LDAP data model which states that
+an entry can contain only one STRUCTURAL objectclass per entry. This is now
+enforced by the OpenLDAP 2.1 server.</P
+><P
+>In order to store all user account information (UNIX and Samba) in the directory,
+it is necessary to use the sambaAccount and posixAccount objectclasses in
+combination. However, <B
+CLASS="COMMAND"
+>smbd</B
+> will still obtain the user's UNIX account
+information via the standard C library calls (e.g. getpwnam(), et. al.).
+This means that the Samba server must also have the LDAP NSS library installed
+and functioning correctly. This division of information makes it possible to
+store all Samba account information in LDAP, but still maintain UNIX account
+information in NIS while the network is transitioning to a full LDAP infrastructure.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN1945"
+>11.5. Configuring Samba with LDAP</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1947"
+>11.5.1. OpenLDAP configuration</A
+></H2
+><P
+>To include support for the sambaAccount object in an OpenLDAP directory
+server, first copy the samba.schema file to slapd's configuration directory.</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>cp samba.schema /etc/openldap/schema/</B
+></P
+><P
+>Next, include the <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file in <TT
+CLASS="FILENAME"
+>slapd.conf</TT
+>.
+The sambaAccount object contains two attributes which depend upon other schema
+files. The 'uid' attribute is defined in <TT
+CLASS="FILENAME"
+>cosine.schema</TT
+> and
+the 'displayName' attribute is defined in the <TT
+CLASS="FILENAME"
+>inetorgperson.schema</TT
+>
+file. Both of these must be included before the <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## /etc/openldap/slapd.conf
+
+## schema files (core.schema is required by default)
+include /etc/openldap/schema/core.schema
+
+## needed for sambaAccount
+include /etc/openldap/schema/cosine.schema
+include /etc/openldap/schema/inetorgperson.schema
+include /etc/openldap/schema/samba.schema
+
+## uncomment this line if you want to support the RFC2307 (NIS) schema
+## include /etc/openldap/schema/nis.schema
+
+....</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>It is recommended that you maintain some indices on some of the most usefull attributes,
+like in the following example, to speed up searches made on sambaAccount objectclasses
+(and possibly posixAccount and posixGroup as well).</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+># Indices to maintain
+## required by OpenLDAP 2.0
+index objectclass eq
+
+## support pbb_getsampwnam()
+index uid pres,eq
+## support pdb_getsampwrid()
+index rid eq
+
+## uncomment these if you are storing posixAccount and
+## posixGroup entries in the directory as well
+##index uidNumber eq
+##index gidNumber eq
+##index cn eq
+##index memberUid eq</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1964"
+>11.5.2. Configuring Samba</A
+></H2
+><P
+>The following parameters are available in smb.conf only with <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+was included with compiling Samba.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSSL"
+TARGET="_top"
+>ldap ssl</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSERVER"
+TARGET="_top"
+>ldap server</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPADMINDN"
+TARGET="_top"
+>ldap admin dn</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSUFFIX"
+TARGET="_top"
+>ldap suffix</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPFILTER"
+TARGET="_top"
+>ldap filter</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPPORT"
+TARGET="_top"
+>ldap port</A
+></P
+></LI
+></UL
+><P
+>These are described in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+> man
+page and so will not be repeated here. However, a sample smb.conf file for
+use with an LDAP directory could appear as</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## /usr/local/samba/lib/smb.conf
+[global]
+ security = user
+ encrypt passwords = yes
+
+ netbios name = TASHTEGO
+ workgroup = NARNIA
+
+ # ldap related parameters
+
+ # define the DN to use when binding to the directory servers
+ # The password for this DN is not stored in smb.conf. Rather it
+ # must be set by using 'smbpasswd -w <TT
+CLASS="REPLACEABLE"
+><I
+>secretpw</I
+></TT
+>' to store the
+ # passphrase in the secrets.tdb file. If the "ldap admin dn" values
+ # changes, this password will need to be reset.
+ ldap admin dn = "cn=Samba Manager,ou=people,dc=samba,dc=org"
+
+ # specify the LDAP server's hostname (defaults to locahost)
+ ldap server = ahab.samba.org
+
+ # Define the SSL option when connecting to the directory
+ # ('off', 'start tls', or 'on' (default))
+ ldap ssl = start tls
+
+ # define the port to use in the LDAP session (defaults to 636 when
+ # "ldap ssl = on")
+ ldap port = 389
+
+ # specify the base DN to use when searching the directory
+ ldap suffix = "ou=people,dc=samba,dc=org"
+
+ # generally the default ldap search filter is ok
+ # ldap filter = "(&#38;(uid=%u)(objectclass=sambaAccount))"</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN1992"
+>11.5.3. Importing <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> entries</A
+></H2
+><P
+>Import existing user entries from an <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> can be trivially done using
+a Perl script named <TT
+CLASS="FILENAME"
+>import_smbpasswd.pl</TT
+> included in the
+<TT
+CLASS="FILENAME"
+>examples/LDAP/</TT
+> directory of the Samba source distribution. There are
+two main requirements of this script:</P
+><P
+></P
+><UL
+><LI
+><P
+>All users to be imported to the directory must have a valid uid on the
+ local system. This can be a problem if using a machinej different from the Samba server
+ to import the file.</P
+></LI
+><LI
+><P
+>The local system must have a working installation of the Net::LDAP perl
+ module which can be obtained from with <A
+HREF="http://search.cpan.org/"
+TARGET="_top"
+>http://search.cpan.org/</A
+>
+ by searching for <TT
+CLASS="FILENAME"
+>perl-ldap</TT
+> or directly from <A
+HREF="http://perl-ldap.sf.net/"
+TARGET="_top"
+>http://perl-ldap.sf.net/</A
+>.
+ </P
+></LI
+></UL
+><P
+>Please refer to the documentation in the same directory as the script for more details.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2008"
+>11.6. Accounts and Groups management</A
+></H1
+><P
+>As users accounts are managed thru the sambaAccount objectclass, you should
+modify you existing administration tools to deal with sambaAccount attributes.</P
+><P
+>Machines accounts are managed with the sambaAccount objectclass, just
+like users accounts. However, it's up to you to stored thoses accounts
+in a different tree of you LDAP namespace: you should use
+"ou=Groups,dc=plainjoe,dc=org" to store groups and
+"ou=People,dc=plainjoe,dc=org" to store users. Just configure your
+NSS and PAM accordingly (usually, in the /etc/ldap.conf configuration
+file).</P
+><P
+>In Samba release 2.2.3, the group management system is based on posix
+groups. This meand that Samba make usage of the posixGroup objectclass.
+For now, there is no NT-like group system management (global and local
+groups).</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2013"
+>11.7. Security and sambaAccount</A
+></H1
+><P
+>There are two important points to remember when discussing the security
+of sambaAccount entries in the directory.</P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>Never</EM
+> retrieve the lmPassword or
+ ntPassword attribute values over an unencrypted LDAP session.</P
+></LI
+><LI
+><P
+><EM
+>Never</EM
+> allow non-admin users to
+ view the lmPassword or ntPassword attribute values.</P
+></LI
+></UL
+><P
+>These password hashes are clear text equivalents and can be used to impersonate
+the user without deriving the original clear text strings. For more information
+on the details of LM/NT password hashes, refer to the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>ENCRYPTION chapter</A
+> of the Samba-HOWTO-Collection.</P
+><P
+>To remedy the first security issue, the "ldap ssl" smb.conf parameter defaults
+to require an encrypted session (<B
+CLASS="COMMAND"
+>ldap ssl = on</B
+>) using
+the default port of 636
+when contacting the directory server. When using an OpenLDAP 2.0 server, it
+is possible to use the use the StartTLS LDAP extended operation in the place of
+LDAPS. In either case, you are strongly discouraged to disable this security
+(<B
+CLASS="COMMAND"
+>ldap ssl = off</B
+>).</P
+><P
+>Note that the LDAPS protocol is deprecated in favor of the LDAPv3 StartTLS
+extended operation. However, the OpenLDAP library still provides support for
+the older method of securing communication between clients and servers.</P
+><P
+>The second security precaution is to prevent non-administrative users from
+harvesting password hashes from the directory. This can be done using the
+following ACL in <TT
+CLASS="FILENAME"
+>slapd.conf</TT
+>:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## allow the "ldap admin dn" access, but deny everyone else
+access to attrs=lmPassword,ntPassword
+ by dn="cn=Samba Admin,ou=people,dc=plainjoe,dc=org" write
+ by * none</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2033"
+>11.8. LDAP specials attributes for sambaAccounts</A
+></H1
+><P
+>The sambaAccount objectclass is composed of the following attributes:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmPassword</TT
+>: the LANMAN password 16-byte hash stored as a character
+ representation of a hexidecimal string.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ntPassword</TT
+>: the NT password hash 16-byte stored as a character
+ representation of a hexidecimal string.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdLastSet</TT
+>: The integer time in seconds since 1970 when the
+ <TT
+CLASS="CONSTANT"
+>lmPassword</TT
+> and <TT
+CLASS="CONSTANT"
+>ntPassword</TT
+> attributes were last set.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>acctFlags</TT
+>: string of 11 characters surrounded by square brackets []
+ representing account flags such as U (user), W(workstation), X(no password expiration), and
+ D(disabled).</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>logonTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>logoffTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>kickoffTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdCanChange</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdMustChange</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>homeDrive</TT
+>: specifies the drive letter to which to map the
+ UNC path specified by homeDirectory. The drive letter must be specified in the form "X:"
+ where X is the letter of the drive to map. Refer to the "logon drive" parameter in the
+ smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>scriptPath</TT
+>: The scriptPath property specifies the path of
+ the user's logon script, .CMD, .EXE, or .BAT file. The string can be null. The path
+ is relative to the netlogon share. Refer to the "logon script" parameter in the
+ smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>profilePath</TT
+>: specifies a path to the user's profile.
+ This value can be a null string, a local absolute path, or a UNC path. Refer to the
+ "logon path" parameter in the smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>smbHome</TT
+>: The homeDirectory property specifies the path of
+ the home directory for the user. The string can be null. If homeDrive is set and specifies
+ a drive letter, homeDirectory should be a UNC path. The path must be a network
+ UNC path of the form \\server\share\directory. This value can be a null string.
+ Refer to the "logon home" parameter in the smb.conf(5) man page for more information.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>userWorkstation</TT
+>: character string value currently unused.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>rid</TT
+>: the integer representation of the user's relative identifier
+ (RID).</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>primaryGroupID</TT
+>: the relative identifier (RID) of the primary group
+ of the user.</P
+></LI
+></UL
+><P
+>The majority of these parameters are only used when Samba is acting as a PDC of
+a domain (refer to the <A
+HREF="Samba-PDC-HOWTO.html"
+TARGET="_top"
+>Samba-PDC-HOWTO</A
+> for details on
+how to configure Samba as a Primary Domain Controller). The following four attributes
+are only stored with the sambaAccount entry if the values are non-default values:</P
+><P
+></P
+><UL
+><LI
+><P
+>smbHome</P
+></LI
+><LI
+><P
+>scriptPath</P
+></LI
+><LI
+><P
+>logonPath</P
+></LI
+><LI
+><P
+>homeDrive</P
+></LI
+></UL
+><P
+>These attributes are only stored with the sambaAccount entry if
+the values are non-default values. For example, assume TASHTEGO has now been
+configured as a PDC and that <B
+CLASS="COMMAND"
+>logon home = \\%L\%u</B
+> was defined in
+its <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. When a user named "becky" logons to the domain,
+the <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+> string is expanded to \\TASHTEGO\becky.
+If the smbHome attribute exists in the entry "uid=becky,ou=people,dc=samba,dc=org",
+this value is used. However, if this attribute does not exist, then the value
+of the <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+> parameter is used in its place. Samba
+will only write the attribute value to the directory entry is the value is
+something other than the default (e.g. \\MOBY\becky).</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2103"
+>11.9. Example LDIF Entries for a sambaAccount</A
+></H1
+><P
+>The following is a working LDIF with the inclusion of the posixAccount objectclass:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>dn: uid=guest2, ou=people,dc=plainjoe,dc=org
+ntPassword: 878D8014606CDA29677A44EFA1353FC7
+pwdMustChange: 2147483647
+primaryGroupID: 1201
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+pwdLastSet: 1010179124
+logonTime: 0
+objectClass: sambaAccount
+uid: guest2
+kickoffTime: 2147483647
+acctFlags: [UX ]
+logoffTime: 2147483647
+rid: 19006
+pwdCanChange: 0</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The following is an LDIF entry for using both the sambaAccount and
+posixAccount objectclasses:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>dn: uid=gcarter, ou=people,dc=plainjoe,dc=org
+logonTime: 0
+displayName: Gerald Carter
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+primaryGroupID: 1201
+objectClass: posixAccount
+objectClass: sambaAccount
+acctFlags: [UX ]
+userPassword: {crypt}BpM2ej8Rkzogo
+uid: gcarter
+uidNumber: 9000
+cn: Gerald Carter
+loginShell: /bin/bash
+logoffTime: 2147483647
+gidNumber: 100
+kickoffTime: 2147483647
+pwdLastSet: 1010179230
+rid: 19000
+homeDirectory: /home/tashtego/gcarter
+pwdCanChange: 0
+pwdMustChange: 2147483647
+ntPassword: 878D8014606CDA29677A44EFA1353FC7</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2111"
+>11.10. Comments</A
+></H1
+><P
+>Please mail all comments regarding this HOWTO to <A
+HREF="mailto:jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+>. This documents was
+last updated to reflect the Samba 2.2.5 release.&#13;</P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="WINBIND"
+>Chapter 12. Unified Logons between Windows NT and UNIX using Winbind</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN2140"
+>12.1. Abstract</A
+></H1
+><P
+>Integration of UNIX and Microsoft Windows NT through
+ a unified logon has been considered a "holy grail" in heterogeneous
+ computing environments for a long time. We present
+ <EM
+>winbind</EM
+>, a component of the Samba suite
+ of programs as a solution to the unified logon problem. Winbind
+ uses a UNIX implementation
+ of Microsoft RPC calls, Pluggable Authentication Modules, and the Name
+ Service Switch to allow Windows NT domain users to appear and operate
+ as UNIX users on a UNIX machine. This paper describes the winbind
+ system, explaining the functionality it provides, how it is configured,
+ and how it works internally.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2144"
+>12.2. Introduction</A
+></H1
+><P
+>It is well known that UNIX and Microsoft Windows NT have
+ different models for representing user and group information and
+ use different technologies for implementing them. This fact has
+ made it difficult to integrate the two systems in a satisfactory
+ manner.</P
+><P
+>One common solution in use today has been to create
+ identically named user accounts on both the UNIX and Windows systems
+ and use the Samba suite of programs to provide file and print services
+ between the two. This solution is far from perfect however, as
+ adding and deleting users on both sets of machines becomes a chore
+ and two sets of passwords are required both of which
+ can lead to synchronization problems between the UNIX and Windows
+ systems and confusion for users.</P
+><P
+>We divide the unified logon problem for UNIX machines into
+ three smaller problems:</P
+><P
+></P
+><UL
+><LI
+><P
+>Obtaining Windows NT user and group information
+ </P
+></LI
+><LI
+><P
+>Authenticating Windows NT users
+ </P
+></LI
+><LI
+><P
+>Password changing for Windows NT users
+ </P
+></LI
+></UL
+><P
+>Ideally, a prospective solution to the unified logon problem
+ would satisfy all the above components without duplication of
+ information on the UNIX machines and without creating additional
+ tasks for the system administrator when maintaining users and
+ groups on either system. The winbind system provides a simple
+ and elegant solution to all three components of the unified logon
+ problem.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2157"
+>12.3. What Winbind Provides</A
+></H1
+><P
+>Winbind unifies UNIX and Windows NT account management by
+ allowing a UNIX box to become a full member of a NT domain. Once
+ this is done the UNIX box will see NT users and groups as if
+ they were native UNIX users and groups, allowing the NT domain
+ to be used in much the same manner that NIS+ is used within
+ UNIX-only environments.</P
+><P
+>The end result is that whenever any
+ program on the UNIX machine asks the operating system to lookup
+ a user or group name, the query will be resolved by asking the
+ NT domain controller for the specified domain to do the lookup.
+ Because Winbind hooks into the operating system at a low level
+ (via the NSS name resolution modules in the C library) this
+ redirection to the NT domain controller is completely
+ transparent.</P
+><P
+>Users on the UNIX machine can then use NT user and group
+ names as they would use "native" UNIX names. They can chown files
+ so that they are owned by NT domain users or even login to the
+ UNIX machine and run a UNIX X-Window session as a domain user.</P
+><P
+>The only obvious indication that Winbind is being used is
+ that user and group names take the form DOMAIN\user and
+ DOMAIN\group. This is necessary as it allows Winbind to determine
+ that redirection to a domain controller is wanted for a particular
+ lookup and which trusted domain is being referenced.</P
+><P
+>Additionally, Winbind provides an authentication service
+ that hooks into the Pluggable Authentication Modules (PAM) system
+ to provide authentication via a NT domain to any PAM enabled
+ applications. This capability solves the problem of synchronizing
+ passwords between systems since all passwords are stored in a single
+ location (on the domain controller).</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2164"
+>12.3.1. Target Uses</A
+></H2
+><P
+>Winbind is targeted at organizations that have an
+ existing NT based domain infrastructure into which they wish
+ to put UNIX workstations or servers. Winbind will allow these
+ organizations to deploy UNIX workstations without having to
+ maintain a separate account infrastructure. This greatly
+ simplifies the administrative overhead of deploying UNIX
+ workstations into a NT based organization.</P
+><P
+>Another interesting way in which we expect Winbind to
+ be used is as a central part of UNIX based appliances. Appliances
+ that provide file and print services to Microsoft based networks
+ will be able to use Winbind to provide seamless integration of
+ the appliance into the domain.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2168"
+>12.4. How Winbind Works</A
+></H1
+><P
+>The winbind system is designed around a client/server
+ architecture. A long running <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+ listens on a UNIX domain socket waiting for requests
+ to arrive. These requests are generated by the NSS and PAM
+ clients and processed sequentially.</P
+><P
+>The technologies used to implement winbind are described
+ in detail below.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2173"
+>12.4.1. Microsoft Remote Procedure Calls</A
+></H2
+><P
+>Over the last two years, efforts have been underway
+ by various Samba Team members to decode various aspects of
+ the Microsoft Remote Procedure Call (MSRPC) system. This
+ system is used for most network related operations between
+ Windows NT machines including remote management, user authentication
+ and print spooling. Although initially this work was done
+ to aid the implementation of Primary Domain Controller (PDC)
+ functionality in Samba, it has also yielded a body of code which
+ can be used for other purposes.</P
+><P
+>Winbind uses various MSRPC calls to enumerate domain users
+ and groups and to obtain detailed information about individual
+ users or groups. Other MSRPC calls can be used to authenticate
+ NT domain users and to change user passwords. By directly querying
+ a Windows PDC for user and group information, winbind maps the
+ NT account information onto UNIX user and group names.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2177"
+>12.4.2. Name Service Switch</A
+></H2
+><P
+>The Name Service Switch, or NSS, is a feature that is
+ present in many UNIX operating systems. It allows system
+ information such as hostnames, mail aliases and user information
+ to be resolved from different sources. For example, a standalone
+ UNIX workstation may resolve system information from a series of
+ flat files stored on the local filesystem. A networked workstation
+ may first attempt to resolve system information from local files,
+ and then consult a NIS database for user information or a DNS server
+ for hostname information.</P
+><P
+>The NSS application programming interface allows winbind
+ to present itself as a source of system information when
+ resolving UNIX usernames and groups. Winbind uses this interface,
+ and information obtained from a Windows NT server using MSRPC
+ calls to provide a new source of account enumeration. Using standard
+ UNIX library calls, one can enumerate the users and groups on
+ a UNIX machine running winbind and see all users and groups in
+ a NT domain plus any trusted domain as though they were local
+ users and groups.</P
+><P
+>The primary control file for NSS is
+ <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>.
+ When a UNIX application makes a request to do a lookup
+ the C library looks in <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>
+ for a line which matches the service type being requested, for
+ example the "passwd" service type is used when user or group names
+ are looked up. This config line species which implementations
+ of that service should be tried and in what order. If the passwd
+ config line is:</P
+><P
+><B
+CLASS="COMMAND"
+>passwd: files example</B
+></P
+><P
+>then the C library will first load a module called
+ <TT
+CLASS="FILENAME"
+>/lib/libnss_files.so</TT
+> followed by
+ the module <TT
+CLASS="FILENAME"
+>/lib/libnss_example.so</TT
+>. The
+ C library will dynamically load each of these modules in turn
+ and call resolver functions within the modules to try to resolve
+ the request. Once the request is resolved the C library returns the
+ result to the application.</P
+><P
+>This NSS interface provides a very easy way for Winbind
+ to hook into the operating system. All that needs to be done
+ is to put <TT
+CLASS="FILENAME"
+>libnss_winbind.so</TT
+> in <TT
+CLASS="FILENAME"
+>/lib/</TT
+>
+ then add "winbind" into <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> at
+ the appropriate place. The C library will then call Winbind to
+ resolve user and group names.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2193"
+>12.4.3. Pluggable Authentication Modules</A
+></H2
+><P
+>Pluggable Authentication Modules, also known as PAM,
+ is a system for abstracting authentication and authorization
+ technologies. With a PAM module it is possible to specify different
+ authentication methods for different system applications without
+ having to recompile these applications. PAM is also useful
+ for implementing a particular policy for authorization. For example,
+ a system administrator may only allow console logins from users
+ stored in the local password file but only allow users resolved from
+ a NIS database to log in over the network.</P
+><P
+>Winbind uses the authentication management and password
+ management PAM interface to integrate Windows NT users into a
+ UNIX system. This allows Windows NT users to log in to a UNIX
+ machine and be authenticated against a suitable Primary Domain
+ Controller. These users can also change their passwords and have
+ this change take effect directly on the Primary Domain Controller.
+ </P
+><P
+>PAM is configured by providing control files in the directory
+ <TT
+CLASS="FILENAME"
+>/etc/pam.d/</TT
+> for each of the services that
+ require authentication. When an authentication request is made
+ by an application the PAM code in the C library looks up this
+ control file to determine what modules to load to do the
+ authentication check and in what order. This interface makes adding
+ a new authentication service for Winbind very easy, all that needs
+ to be done is that the <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> module
+ is copied to <TT
+CLASS="FILENAME"
+>/lib/security/</TT
+> and the PAM
+ control files for relevant services are updated to allow
+ authentication via winbind. See the PAM documentation
+ for more details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2201"
+>12.4.4. User and Group ID Allocation</A
+></H2
+><P
+>When a user or group is created under Windows NT
+ is it allocated a numerical relative identifier (RID). This is
+ slightly different to UNIX which has a range of numbers that are
+ used to identify users, and the same range in which to identify
+ groups. It is winbind's job to convert RIDs to UNIX id numbers and
+ vice versa. When winbind is configured it is given part of the UNIX
+ user id space and a part of the UNIX group id space in which to
+ store Windows NT users and groups. If a Windows NT user is
+ resolved for the first time, it is allocated the next UNIX id from
+ the range. The same process applies for Windows NT groups. Over
+ time, winbind will have mapped all Windows NT users and groups
+ to UNIX user ids and group ids.</P
+><P
+>The results of this mapping are stored persistently in
+ an ID mapping database held in a tdb database). This ensures that
+ RIDs are mapped to UNIX IDs in a consistent way.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2205"
+>12.4.5. Result Caching</A
+></H2
+><P
+>An active system can generate a lot of user and group
+ name lookups. To reduce the network cost of these lookups winbind
+ uses a caching scheme based on the SAM sequence number supplied
+ by NT domain controllers. User or group information returned
+ by a PDC is cached by winbind along with a sequence number also
+ returned by the PDC. This sequence number is incremented by
+ Windows NT whenever any user or group information is modified. If
+ a cached entry has expired, the sequence number is requested from
+ the PDC and compared against the sequence number of the cached entry.
+ If the sequence numbers do not match, then the cached information
+ is discarded and up to date information is requested directly
+ from the PDC.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2208"
+>12.5. Installation and Configuration</A
+></H1
+><P
+>Many thanks to John Trostel <A
+HREF="mailto:jtrostel@snapserver.com"
+TARGET="_top"
+>jtrostel@snapserver.com</A
+>
+for providing the original Linux version of this HOWTO which
+describes how to get winbind services up and running
+to control access and authenticate users on your Linux box using
+the winbind services which are included with the SAMBA 2.2.2 and later
+releases.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2212"
+>12.5.1. Introduction</A
+></H2
+><P
+>This HOWTO describes the procedures used to get winbind up and
+running on a RedHat 7.1 system. Winbind is capable of providing access
+and authentication control for Windows Domain users through an NT
+or Win2K PDC for 'regular' services, such as telnet and ftp, as
+well providing dynamic uid/gid allocation for Samba.</P
+><P
+>This HOWTO has been written from a 'RedHat-centric' perspective, so if
+you are using another distribution (or operating system), you may have
+to modify the instructions somewhat to fit the way your distribution works.</P
+><P
+></P
+><UL
+><LI
+><P
+> <EM
+>Why should I to this?</EM
+>
+ </P
+><P
+>This allows the SAMBA administrator to rely on the
+ authentication mechanisms on the NT/Win2K PDC for the authentication
+ of domain members. NT/Win2K users no longer need to have separate
+ accounts on the SAMBA server.
+ </P
+></LI
+><LI
+><P
+> <EM
+>Who should be reading this document?</EM
+>
+ </P
+><P
+> This HOWTO is designed for system administrators. If you are
+ implementing SAMBA on a file server and wish to (fairly easily)
+ integrate existing NT/Win2K users from your PDC onto the
+ SAMBA server, this HOWTO is for you.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2225"
+>12.5.2. Requirements</A
+></H2
+><P
+>If you have a samba configuration file that you are currently
+using... <EM
+>BACK IT UP!</EM
+> If your system already uses PAM,
+<EM
+>back up the <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+>)
+directory contents!</EM
+> If you haven't already made a boot disk,
+<EM
+>MAKE ONE NOW!</EM
+></P
+><P
+>Messing with the pam configuration files can make it nearly impossible
+to log in to your machine. That's why you want to be able to boot back
+into your machine in single user mode and restore your
+<TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>pam.conmf</TT
+>) back to
+the original state they were in if
+you get frustrated with the way things are going.</P
+><P
+>The first SAMBA release to inclue a stable winbindd daemon was 2.2.2. Please refer to the
+<A
+HREF="http://samba.org/"
+TARGET="_top"
+>main SAMBA web page</A
+> or,
+better yet, your closest SAMBA mirror site for instructions on
+downloading the source code. it is generally advised to obtain the lates
+Samba release as bugs are constantly being fixed.</P
+><P
+>To allow Domain users the ability to access SAMBA shares and
+files, as well as potentially other services provided by your
+SAMBA machine, PAM (pluggable authentication modules) must
+be setup properly on your machine. In order to compile the
+winbind modules, you must have at the PAM libraries and header files resident
+on your system. For recent RedHat systems (7.x, for instance), that
+means installing both <TT
+CLASS="FILENAME"
+>pam</TT
+> and <TT
+CLASS="FILENAME"
+>pam-devel</TT
+> RPM.
+The former is installed by default on all Linux systems of which the author is aware.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2241"
+>12.5.3. Testing Things Out</A
+></H2
+><P
+>Before starting, kill off all the SAMBA related daemons running on your server. Kill off
+all <B
+CLASS="COMMAND"
+>smbd</B
+>, <B
+CLASS="COMMAND"
+>nmbd</B
+>, and <B
+CLASS="COMMAND"
+>winbindd</B
+> processes that may
+be running (<B
+CLASS="COMMAND"
+>winbindd</B
+> will only be running if you have ao previous Winbind
+installation...but why would you be reading tis if that were the case?). To use PAM, you will
+want to make sure that you have the standard PAM package (for RedHat) which supplies the <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+>
+directory structure, including the pam modules are used by pam-aware
+services, several pam libraries, and the <TT
+CLASS="FILENAME"
+>/usr/doc</TT
+>
+and <TT
+CLASS="FILENAME"
+>/usr/man</TT
+> entries for pam. Samba will require
+the pam-devel package if you plan to build the <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> library or
+include the <B
+CLASS="COMMAND"
+>--with-pam</B
+> option to the configure script.
+This package includes the header files needed to compile pam-aware applications.</P
+><P
+>[I have no idea which Solaris packages are quired for PAM libraries and
+development files. If you know, please mail me the information and I will include
+it in the next revision of this HOWTO. --jerry@samba.org]</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2254"
+>12.5.3.1. Configure and Compile SAMBA</A
+></H3
+><P
+>The configuration and compilation of SAMBA is straightforward.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>./configure --with-winbind</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make install</B
+></PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>This will, by default, install SAMBA in <TT
+CLASS="FILENAME"
+>/usr/local/samba</TT
+>.
+See the main SAMBA documentation if you want to install SAMBA somewhere else.
+It will also build the winbindd executable and NSS library.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2267"
+>12.5.3.2. Configure <TT
+CLASS="FILENAME"
+>nsswitch.conf</TT
+> and the
+winbind libraries</A
+></H3
+><P
+>The libraries needed to run the <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+through nsswitch need to be copied to their proper locations.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>cp nsswitch/libnss_winbind.so /lib</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>chmod 755 /lib/libnss_winbind.so</B
+></P
+><P
+>It necessary to make the following symbolic link:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>ln -s /lib/libnss_winbind.so /lib/libnss_winbind.so.2</B
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>.2</TT
+> extension is due to the version of glibc used on your Linux host.
+for most modern systems, the file extension is correct. However, some other operating systems,
+Solaris 7/8 being the most common, the destination filename should be replaced with
+<TT
+CLASS="FILENAME"
+>/lib/nss_winbind.so.1</TT
+></P
+><P
+>Now, as root edit <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> to
+allow user and group entries to be visible from the <B
+CLASS="COMMAND"
+>winbindd</B
+>
+daemon. After editing, the file look appear:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> passwd: files winbind
+ shadow: files
+ group: files winbind</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2289"
+>12.5.3.3. Configure <TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+></H3
+><P
+>Several parameters are needed in the smb.conf file to control
+the behavior of <B
+CLASS="COMMAND"
+>winbindd</B
+>. Configure
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> These are described in more detail in
+the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> man page. My
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file was modified to
+include the following entries in the [global] section:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ &#60;...&#62;
+ # separate domain and username with '+', like DOMAIN+username
+ <A
+HREF="winbindd.8.html#WINBINDSEPARATOR"
+TARGET="_top"
+>winbind separator</A
+> = +
+ # use uids from 10000 to 20000 for domain users
+ <A
+HREF="winbindd.8.html#WINBINDUID"
+TARGET="_top"
+>winbind uid</A
+> = 10000-20000
+ # use gids from 10000 to 20000 for domain groups
+ <A
+HREF="winbindd.8.html#WINBINDGID"
+TARGET="_top"
+>winbind gid</A
+> = 10000-20000
+ # allow enumeration of winbind users and groups
+ # might need to disable these next two for performance
+ # reasons on the winbindd host
+ <A
+HREF="winbindd.8.html#WINBINDENUMUSERS"
+TARGET="_top"
+>winbind enum users</A
+> = yes
+ <A
+HREF="winbindd.8.html#WINBINDENUMGROUP"
+TARGET="_top"
+>winbind enum groups</A
+> = yes
+ # give winbind users a real shell (only needed if they have telnet/sshd/etc... access)
+ <A
+HREF="winbindd.8.html#TEMPLATEHOMEDIR"
+TARGET="_top"
+>template homedir</A
+> = /home/winnt/%D/%U
+ <A
+HREF="winbindd.8.html#TEMPLATESHELL"
+TARGET="_top"
+>template shell</A
+> = /bin/bash</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2306"
+>12.5.3.4. Join the SAMBA server to the PDC domain</A
+></H3
+><P
+>Enter the following command to make the SAMBA server join the
+PDC domain, where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+> is the name of
+your Windows domain and <TT
+CLASS="REPLACEABLE"
+><I
+>Administrator</I
+></TT
+> is
+a domain user who has administrative privileges in the domain.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/usr/local/samba/bin/smbpasswd -j DOMAIN -r PDC -U Administrator</B
+></P
+><P
+>The proper response to the command should be: "Joined the domain
+<TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+>" where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+>
+is your DOMAIN name.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2317"
+>12.5.3.5. Start up the winbindd daemon and test it!</A
+></H3
+><P
+>Eventually, you will want to modify your smb startup script to
+automatically invoke the winbindd daemon when the other parts of
+SAMBA start, but it is possible to test out just the winbind
+portion first. To start up winbind services, enter the following
+command as root:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>export PATH=$PATH:/usr/local/samba/bin</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>winbindd</B
+></P
+><P
+>I'm always paranoid and like to make sure the daemon
+is really running...</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>ps -ae | grep winbindd</B
+></P
+><P
+>This command should produce output like this, if the daemon is running</P
+><P
+>3025 ? 00:00:00 winbindd</P
+><P
+>Note that a sample RedHat init script for starting winbindd is included in
+the SAMBA sourse distribution as <TT
+CLASS="FILENAME"
+>packaging/RedHat/winbind.init</TT
+>.</P
+><P
+>Now... for the real test, try to get some information about the
+users on your PDC</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>wbinfo -u</B
+></P
+><P
+>This should echo back a list of users on your Windows users on
+your PDC. For example, I get the following response:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>CEO+Administrator
+CEO+burdell
+CEO+Guest
+CEO+jt-ad
+CEO+krbtgt
+CEO+TsInternetUser</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Obviously, I have named my domain 'CEO' and my <TT
+CLASS="PARAMETER"
+><I
+>winbind
+separator</I
+></TT
+> is '+'.</P
+><P
+>You can do the same sort of thing to get group information from
+the PDC:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/usr/local/samba/bin/wbinfo -g</B
+>
+CEO+Domain Admins
+CEO+Domain Users
+CEO+Domain Guests
+CEO+Domain Computers
+CEO+Domain Controllers
+CEO+Cert Publishers
+CEO+Schema Admins
+CEO+Enterprise Admins
+CEO+Group Policy Creator Owners</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The function 'getent' can now be used to get unified
+lists of both local and PDC users and groups.
+Try the following command:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>getent passwd</B
+></P
+><P
+>You should get a list that looks like your <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>
+list followed by the domain users with their new uids, gids, home
+directories and default shells. If you do not, verify that the permissions on the
+libnss_winbind.so library are <TT
+CLASS="FILENAME"
+>rwxr-xr-x</TT
+>.</P
+><P
+>The same thing can be done for groups with the command</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>getent group</B
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2358"
+>12.5.3.6. Configure Winbind and PAM</A
+></H3
+><P
+>At this point we are assured that <B
+CLASS="COMMAND"
+>winbindd</B
+> and <B
+CLASS="COMMAND"
+>smbd</B
+>
+are working together. If you want to use winbind to provide authentication for other
+services, keep reading. The pam configuration files need to be altered in
+this step. (Did you remember to make backups of your original
+<TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+>) file[s]? If not, do it now.)</P
+><P
+>You will need a PAM module to use <B
+CLASS="COMMAND"
+>winbindd</B
+> with these other services. This
+module will be compiled in the <TT
+CLASS="FILENAME"
+>../source/nsswitch</TT
+> directory
+by invoking the command</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make nsswitch/pam_winbind.so</B
+></P
+><P
+>from the <TT
+CLASS="FILENAME"
+>../source</TT
+> directory. The
+<TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> file should be copied to the location of
+your other pam security modules. On Linux and Solaris systems, this is the
+<TT
+CLASS="FILENAME"
+>/lib/security</TT
+> directory.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>cp nsswitch/pam_winbind.so /lib/security</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>chmod 755 /lib/security/pam_winbind.so</B
+></P
+><P
+>Other services, such as the normal login on the console (or a terminal
+session), telnet logins, and ftp service, can be modified to allow the use of winbind
+as an authentication service. In order to enable these
+services, you may first need to change the entries in
+<TT
+CLASS="FILENAME"
+>/etc/xinetd.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>).
+RedHat 7.1 uses the new xinetd.d structure, in this case you need
+to change the lines in <TT
+CLASS="FILENAME"
+>/etc/xinetd.d/telnet</TT
+>
+and <TT
+CLASS="FILENAME"
+>/etc/xinetd.d/wu-ftp</TT
+> from</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>enable = no</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>to</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>enable = yes</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>For ftp services to work properly, you will also need to either
+have individual directories for the domain users already present on
+the server, or change the home directory template to a general
+directory for all domain users. These can be easily set using
+the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> global entry
+<B
+CLASS="COMMAND"
+>template homedir</B
+>.</P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/pam.d/ftp</TT
+> file can be changed
+to allow winbind ftp access in a manner similar to the
+samba file. My <TT
+CLASS="FILENAME"
+>/etc/pam.d/ftp</TT
+> file was
+changed to look like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>auth required /lib/security/pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_shells.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/pam.d/login</TT
+> file can be changed nearly the
+same way. It now looks like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>auth required /lib/security/pam_securetty.so
+auth sufficient /lib/security/pam_winbind.so
+auth sufficient /lib/security/pam_unix.so use_first_pass
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_nologin.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+password required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth
+session optional /lib/security/pam_console.so</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>In this case, I added the <B
+CLASS="COMMAND"
+>auth sufficient /lib/security/pam_winbind.so</B
+>
+lines as before, but also added the <B
+CLASS="COMMAND"
+>required pam_securetty.so</B
+>
+above it, to disallow root logins over the network. I also added a
+<B
+CLASS="COMMAND"
+>sufficient /lib/security/pam_unix.so use_first_pass</B
+>
+line after the <B
+CLASS="COMMAND"
+>winbind.so</B
+> line to get rid of annoying
+double prompts for passwords.</P
+><P
+>Note that a Solaris <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+> confiruation file looks
+very similar to this except thaty the service name is included as the first entry
+per line. An example for the login service is given here.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## excerpt from /etc/pam.conf on a Solaris 8 system
+login auth required /lib/security/pam_winbind.so
+login auth required /lib/security/$ISA/pam_unix.so.1 try_first_pass
+login auth required /lib/security/$ISA/pam_dial_auth.so.1 try_first_pass</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2411"
+>12.6. Limitations</A
+></H1
+><P
+>Winbind has a number of limitations in its current
+ released version that we hope to overcome in future
+ releases:</P
+><P
+></P
+><UL
+><LI
+><P
+>The mappings of Windows NT RIDs to UNIX ids
+ is not made algorithmically and depends on the order in which
+ unmapped users or groups are seen by winbind. It may be difficult
+ to recover the mappings of rid to UNIX id mapping if the file
+ containing this information is corrupted or destroyed.</P
+></LI
+><LI
+><P
+>Currently the winbind PAM module does not take
+ into account possible workstation and logon time restrictions
+ that may be been set for Windows NT users.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2419"
+>12.7. Conclusion</A
+></H1
+><P
+>The winbind system, through the use of the Name Service
+ Switch, Pluggable Authentication Modules, and appropriate
+ Microsoft RPC calls have allowed us to provide seamless
+ integration of Microsoft Windows NT domain users on a
+ UNIX system. The result is a great reduction in the administrative
+ cost of running a mixed UNIX and NT network.</P
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="OS2"
+>Chapter 13. OS2 Client HOWTO</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN2433"
+>13.1. FAQs</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN2435"
+>13.1.1. How can I configure OS/2 Warp Connect or
+ OS/2 Warp 4 as a client for Samba?</A
+></H2
+><P
+>A more complete answer to this question can be
+ found on <A
+HREF="http://carol.wins.uva.nl/~leeuw/samba/warp.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/samba/warp.html</A
+>.</P
+><P
+>Basically, you need three components:</P
+><P
+></P
+><UL
+><LI
+><P
+>The File and Print Client ('IBM Peer')
+ </P
+></LI
+><LI
+><P
+>TCP/IP ('Internet support')
+ </P
+></LI
+><LI
+><P
+>The "NetBIOS over TCP/IP" driver ('TCPBEUI')
+ </P
+></LI
+></UL
+><P
+>Installing the first two together with the base operating
+ system on a blank system is explained in the Warp manual. If Warp
+ has already been installed, but you now want to install the
+ networking support, use the "Selective Install for Networking"
+ object in the "System Setup" folder.</P
+><P
+>Adding the "NetBIOS over TCP/IP" driver is not described
+ in the manual and just barely in the online documentation. Start
+ MPTS.EXE, click on OK, click on "Configure LAPS" and click
+ on "IBM OS/2 NETBIOS OVER TCP/IP" in 'Protocols'. This line
+ is then moved to 'Current Configuration'. Select that line,
+ click on "Change number" and increase it from 0 to 1. Save this
+ configuration.</P
+><P
+>If the Samba server(s) is not on your local subnet, you
+ can optionally add IP names and addresses of these servers
+ to the "Names List", or specify a WINS server ('NetBIOS
+ Nameserver' in IBM and RFC terminology). For Warp Connect you
+ may need to download an update for 'IBM Peer' to bring it on
+ the same level as Warp 4. See the webpage mentioned above.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2450"
+>13.1.2. How can I configure OS/2 Warp 3 (not Connect),
+ OS/2 1.2, 1.3 or 2.x for Samba?</A
+></H2
+><P
+>You can use the free Microsoft LAN Manager 2.2c Client
+ for OS/2 from
+ <A
+HREF="ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/"
+TARGET="_top"
+> ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/</A
+>.
+ See <A
+HREF="http://carol.wins.uva.nl/~leeuw/lanman.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/lanman.html</A
+> for
+ more information on how to install and use this client. In
+ a nutshell, edit the file \OS2VER in the root directory of
+ the OS/2 boot partition and add the lines:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> 20=setup.exe
+ 20=netwksta.sys
+ 20=netvdd.sys
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>before you install the client. Also, don't use the
+ included NE2000 driver because it is buggy. Try the NE2000
+ or NS2000 driver from
+ <A
+HREF="ftp://ftp.cdrom.com/pub/os2/network/ndis/"
+TARGET="_top"
+> ftp://ftp.cdrom.com/pub/os2/network/ndis/</A
+> instead.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2459"
+>13.1.3. Are there any other issues when OS/2 (any version)
+ is used as a client?</A
+></H2
+><P
+>When you do a NET VIEW or use the "File and Print
+ Client Resource Browser", no Samba servers show up. This can
+ be fixed by a patch from <A
+HREF="http://carol.wins.uva.nl/~leeuw/samba/fix.html"
+TARGET="_top"
+> http://carol.wins.uva.nl/~leeuw/samba/fix.html</A
+>.
+ The patch will be included in a later version of Samba. It also
+ fixes a couple of other problems, such as preserving long
+ filenames when objects are dragged from the Workplace Shell
+ to the Samba server. </P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2463"
+>13.1.4. How do I get printer driver download working
+ for OS/2 clients?</A
+></H2
+><P
+>First, create a share called [PRINTDRV] that is
+ world-readable. Copy your OS/2 driver files there. Note
+ that the .EA_ files must still be separate, so you will need
+ to use the original install files, and not copy an installed
+ driver from an OS/2 system.</P
+><P
+>Install the NT driver first for that printer. Then,
+ add to your smb.conf a parameter, "os2 driver map =
+ <TT
+CLASS="REPLACEABLE"
+><I
+>filename</I
+></TT
+>". Then, in the file
+ specified by <TT
+CLASS="REPLACEABLE"
+><I
+>filename</I
+></TT
+>, map the
+ name of the NT driver name to the OS/2 driver name as
+ follows:</P
+><P
+>&#60;nt driver name&#62; = &#60;os2 driver
+ name&#62;.&#60;device name&#62;, e.g.:
+ HP LaserJet 5L = LASERJET.HP LaserJet 5L</P
+><P
+>You can have multiple drivers mapped in this file.</P
+><P
+>If you only specify the OS/2 driver name, and not the
+ device name, the first attempt to download the driver will
+ actually download the files, but the OS/2 client will tell
+ you the driver is not available. On the second attempt, it
+ will work. This is fixed simply by adding the device name
+ to the mapping, after which it will work on the first attempt.
+ </P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="CHAPTER"
+><HR><H1
+><A
+NAME="CVS-ACCESS"
+>Chapter 14. HOWTO Access Samba source code via CVS</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN2479"
+>14.1. Introduction</A
+></H1
+><P
+>Samba is developed in an open environment. Developers use CVS
+(Concurrent Versioning System) to "checkin" (also known as
+"commit") new source code. Samba's various CVS branches can
+be accessed via anonymous CVS using the instructions
+detailed in this chapter.</P
+><P
+>This document is a modified version of the instructions found at
+<A
+HREF="http://samba.org/samba/cvs.html"
+TARGET="_top"
+>http://samba.org/samba/cvs.html</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN2484"
+>14.2. CVS Access to samba.org</A
+></H1
+><P
+>The machine samba.org runs a publicly accessible CVS
+repository for access to the source code of several packages,
+including samba, rsync and jitterbug. There are two main ways of
+accessing the CVS server on this host.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2487"
+>14.2.1. Access via CVSweb</A
+></H2
+><P
+>You can access the source code via your
+favourite WWW browser. This allows you to access the contents of
+individual files in the repository and also to look at the revision
+history and commit logs of individual files. You can also ask for a diff
+listing between any two versions on the repository.</P
+><P
+>Use the URL : <A
+HREF="http://samba.org/cgi-bin/cvsweb"
+TARGET="_top"
+>http://samba.org/cgi-bin/cvsweb</A
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2492"
+>14.2.2. Access via cvs</A
+></H2
+><P
+>You can also access the source code via a
+normal cvs client. This gives you much more control over you can
+do with the repository and allows you to checkout whole source trees
+and keep them up to date via normal cvs commands. This is the
+preferred method of access if you are a developer and not
+just a casual browser.</P
+><P
+>To download the latest cvs source code, point your
+browser at the URL : <A
+HREF="http://www.cyclic.com/"
+TARGET="_top"
+>http://www.cyclic.com/</A
+>.
+and click on the 'How to get cvs' link. CVS is free software under
+the GNU GPL (as is Samba). Note that there are several graphical CVS clients
+which provide a graphical interface to the sometimes mundane CVS commands.
+Links to theses clients are also available from http://www.cyclic.com.</P
+><P
+>To gain access via anonymous cvs use the following steps.
+For this example it is assumed that you want a copy of the
+samba source code. For the other source code repositories
+on this system just substitute the correct package name</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> Install a recent copy of cvs. All you really need is a
+ copy of the cvs client binary.
+ </P
+></LI
+><LI
+><P
+> Run the command
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot login</B
+>
+ </P
+><P
+> When it asks you for a password type <TT
+CLASS="USERINPUT"
+><B
+>cvs</B
+></TT
+>.
+ </P
+></LI
+><LI
+><P
+> Run the command
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot co samba</B
+>
+ </P
+><P
+> This will create a directory called samba containing the
+ latest samba source code (i.e. the HEAD tagged cvs branch). This
+ currently corresponds to the 3.0 development tree.
+ </P
+><P
+> CVS branches other HEAD can be obtained by using the <TT
+CLASS="PARAMETER"
+><I
+>-r</I
+></TT
+>
+ and defining a tag name. A list of branch tag names can be found on the
+ "Development" page of the samba web site. A common request is to obtain the
+ latest 2.2 release code. This could be done by using the following command.
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs -d :pserver:cvs@samba.org:/cvsroot co -r SAMBA_2_2 samba</B
+>
+ </P
+></LI
+><LI
+><P
+> Whenever you want to merge in the latest code changes use
+ the following command from within the samba directory:
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>cvs update -d -P</B
+>
+ </P
+></LI
+></OL
+></DIV
+></DIV
+></DIV
+><HR><H1
+><A
+NAME="AEN2520"
+>Index</A
+></H1
+><DL
+><DT
+>Primary Domain Controller,
+ <A
+HREF="x1242.htm"
+>Background</A
+>
+ </DT
+></DL
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/Samba-LDAP-HOWTO.html b/docs/htmldocs/Samba-LDAP-HOWTO.html
new file mode 100755
index 00000000000..7fbfbf5247b
--- /dev/null
+++ b/docs/htmldocs/Samba-LDAP-HOWTO.html
@@ -0,0 +1,985 @@
+<HTML
+><HEAD
+><TITLE
+>Storing Samba's User/Machine Account information in an LDAP Directory</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="SAMBA-LDAP-HOWTO"
+>Storing Samba's User/Machine Account information in an LDAP Directory</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Purpose</A
+></H1
+><P
+>This document describes how to use an LDAP directory for storing Samba user
+account information traditionally stored in the smbpasswd(5) file. It is
+assumed that the reader already has a basic understanding of LDAP concepts
+and has a working directory server already installed. For more information
+on LDAP architectures and Directories, please refer to the following sites.</P
+><P
+></P
+><UL
+><LI
+><P
+>OpenLDAP - <A
+HREF="http://www.openldap.org/"
+TARGET="_top"
+>http://www.openldap.org/</A
+></P
+></LI
+><LI
+><P
+>iPlanet Directory Server - <A
+HREF="http://iplanet.netscape.com/directory"
+TARGET="_top"
+>http://iplanet.netscape.com/directory</A
+></P
+></LI
+></UL
+><P
+>Note that <A
+HREF="http://www.ora.com/"
+TARGET="_top"
+>O'Reilly Publishing</A
+> is working on
+a guide to LDAP for System Administrators which has a planned release date of
+late 2002.</P
+><P
+>Two additional Samba resources which may prove to be helpful are</P
+><P
+></P
+><UL
+><LI
+><P
+>The <A
+HREF="http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html"
+TARGET="_top"
+>Samba-PDC-LDAP-HOWTO</A
+>
+ maintained by Ignacio Coupeau.</P
+></LI
+><LI
+><P
+>The NT migration scripts from <A
+HREF="http://samba.idealx.org/"
+TARGET="_top"
+>IDEALX</A
+> that are
+ geared to manage users and group in such a Samba-LDAP Domain Controller configuration. These scripts can
+ be found in the Samba 2.2.5 release in the <TT
+CLASS="FILENAME"
+>examples/LDAP/smbldap-tools/</TT
+> directory.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN24"
+>Introduction</A
+></H1
+><P
+>Traditionally, when configuring <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>"encrypt
+passwords = yes"</A
+> in Samba's <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file, user account
+information such as username, LM/NT password hashes, password change times, and account
+flags have been stored in the <TT
+CLASS="FILENAME"
+>smbpasswd(5)</TT
+> file. There are several
+disadvantages to this approach for sites with very large numbers of users (counted
+in the thousands).</P
+><P
+></P
+><UL
+><LI
+><P
+>The first is that all lookups must be performed sequentially. Given that
+there are approximately two lookups per domain logon (one for a normal
+session connection such as when mapping a network drive or printer), this
+is a performance bottleneck for large sites. What is needed is an indexed approach
+such as is used in databases.</P
+></LI
+><LI
+><P
+>The second problem is that administrators who desired to replicate a
+smbpasswd file to more than one Samba server were left to use external
+tools such as <B
+CLASS="COMMAND"
+>rsync(1)</B
+> and <B
+CLASS="COMMAND"
+>ssh(1)</B
+>
+and wrote custom, in-house scripts.</P
+></LI
+><LI
+><P
+>And finally, the amount of information which is stored in an
+smbpasswd entry leaves no room for additional attributes such as
+a home directory, password expiration time, or even a Relative
+Identified (RID).</P
+></LI
+></UL
+><P
+>As a result of these defeciencies, a more robust means of storing user attributes
+used by <B
+CLASS="COMMAND"
+>smbd</B
+> was developed. The API which defines access to user accounts
+is commonly referred to as the samdb interface (previously this was called the passdb
+API, and is still so named in the CVS trees). In Samba 2.2.3, enabling support
+for a samdb backend (e.g. <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+> or
+<TT
+CLASS="PARAMETER"
+><I
+>--with-tdbsam</I
+></TT
+>) requires compile time support.</P
+><P
+>When compiling Samba to include the <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+> autoconf
+option, <B
+CLASS="COMMAND"
+>smbd</B
+> (and associated tools) will store and lookup user accounts in
+an LDAP directory. In reality, this is very easy to understand. If you are
+comfortable with using an smbpasswd file, simply replace "smbpasswd" with
+"LDAP directory" in all the documentation.</P
+><P
+>There are a few points to stress about what the <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+does not provide. The LDAP support referred to in the this documentation does not
+include:</P
+><P
+></P
+><UL
+><LI
+><P
+>A means of retrieving user account information from
+ an Windows 2000 Active Directory server.</P
+></LI
+><LI
+><P
+>A means of replacing /etc/passwd.</P
+></LI
+></UL
+><P
+>The second item can be accomplished by using LDAP NSS and PAM modules. LGPL
+versions of these libraries can be obtained from PADL Software
+(<A
+HREF="http://www.padl.com/"
+TARGET="_top"
+>http://www.padl.com/</A
+>). However,
+the details of configuring these packages are beyond the scope of this document.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN55"
+>Supported LDAP Servers</A
+></H1
+><P
+>The LDAP samdb code in 2.2.3 has been developed and tested using the OpenLDAP
+2.0 server and client libraries. The same code should be able to work with
+Netscape's Directory Server and client SDK. However, due to lack of testing
+so far, there are bound to be compile errors and bugs. These should not be
+hard to fix. If you are so inclined, please be sure to forward all patches to
+<A
+HREF="samba-patches@samba.org"
+TARGET="_top"
+>samba-patches@samba.org</A
+> and
+<A
+HREF="jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN60"
+>Schema and Relationship to the RFC 2307 posixAccount</A
+></H1
+><P
+>Samba 2.2.3 includes the necessary schema file for OpenLDAP 2.0 in
+<TT
+CLASS="FILENAME"
+>examples/LDAP/samba.schema</TT
+>. (Note that this schema
+file has been modified since the experimental support initially included
+in 2.2.2). The sambaAccount objectclass is given here:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>objectclass ( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILARY
+ DESC 'Samba Account'
+ MUST ( uid $ rid )
+ MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ description $ userWorkstations $ primaryGroupID $ domain ))</PRE
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file has been formatted for OpenLDAP 2.0 &#38; 2.1. The OID's are
+owned by the Samba Team and as such is legal to be openly published.
+If you translate the schema to be used with Netscape DS, please
+submit the modified schema file as a patch to <A
+HREF="jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+></P
+><P
+>Since the original release, schema files for</P
+><P
+></P
+><UL
+><LI
+><P
+>IBM's SecureWay Server</P
+></LI
+><LI
+><P
+>Netscape Directory Server version 4.x and 5.x</P
+></LI
+></UL
+><P
+>have been submitted and included in the Samba source distribution. I cannot
+personally comment on the integration of these commercial directory servers since
+I have not had the oppotinuity to work with them.</P
+><P
+>Just as the smbpasswd file is mean to store information which supplements a
+user's <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry, so is the sambaAccount object
+meant to supplement the UNIX user account information. A sambaAccount is now an
+<TT
+CLASS="CONSTANT"
+>AUXILARY</TT
+> objectclass so it can be stored alongside
+a posixAccount or person objectclass in the directory. Note that there are
+several fields (e.g. uid) which overlap with the posixAccount objectclass
+outlined in RFC2307. This is by design. The move from a STRUCTURAL objectclass
+to an AUXILIARY one was compliance with the LDAP data model which states that
+an entry can contain only one STRUCTURAL objectclass per entry. This is now
+enforced by the OpenLDAP 2.1 server.</P
+><P
+>In order to store all user account information (UNIX and Samba) in the directory,
+it is necessary to use the sambaAccount and posixAccount objectclasses in
+combination. However, <B
+CLASS="COMMAND"
+>smbd</B
+> will still obtain the user's UNIX account
+information via the standard C library calls (e.g. getpwnam(), et. al.).
+This means that the Samba server must also have the LDAP NSS library installed
+and functioning correctly. This division of information makes it possible to
+store all Samba account information in LDAP, but still maintain UNIX account
+information in NIS while the network is transitioning to a full LDAP infrastructure.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN81"
+>Configuring Samba with LDAP</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN83"
+>OpenLDAP configuration</A
+></H2
+><P
+>To include support for the sambaAccount object in an OpenLDAP directory
+server, first copy the samba.schema file to slapd's configuration directory.</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>cp samba.schema /etc/openldap/schema/</B
+></P
+><P
+>Next, include the <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file in <TT
+CLASS="FILENAME"
+>slapd.conf</TT
+>.
+The sambaAccount object contains two attributes which depend upon other schema
+files. The 'uid' attribute is defined in <TT
+CLASS="FILENAME"
+>cosine.schema</TT
+> and
+the 'displayName' attribute is defined in the <TT
+CLASS="FILENAME"
+>inetorgperson.schema</TT
+>
+file. Both of these must be included before the <TT
+CLASS="FILENAME"
+>samba.schema</TT
+> file.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>## /etc/openldap/slapd.conf
+
+## schema files (core.schema is required by default)
+include /etc/openldap/schema/core.schema
+
+## needed for sambaAccount
+include /etc/openldap/schema/cosine.schema
+include /etc/openldap/schema/inetorgperson.schema
+include /etc/openldap/schema/samba.schema
+
+## uncomment this line if you want to support the RFC2307 (NIS) schema
+## include /etc/openldap/schema/nis.schema
+
+....</PRE
+></P
+><P
+>It is recommended that you maintain some indices on some of the most usefull attributes,
+like in the following example, to speed up searches made on sambaAccount objectclasses
+(and possibly posixAccount and posixGroup as well).</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+># Indices to maintain
+## required by OpenLDAP 2.0
+index objectclass eq
+
+## support pbb_getsampwnam()
+index uid pres,eq
+## support pdb_getsampwrid()
+index rid eq
+
+## uncomment these if you are storing posixAccount and
+## posixGroup entries in the directory as well
+##index uidNumber eq
+##index gidNumber eq
+##index cn eq
+##index memberUid eq</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN100"
+>Configuring Samba</A
+></H2
+><P
+>The following parameters are available in smb.conf only with <TT
+CLASS="PARAMETER"
+><I
+>--with-ldapsam</I
+></TT
+>
+was included with compiling Samba.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSSL"
+TARGET="_top"
+>ldap ssl</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSERVER"
+TARGET="_top"
+>ldap server</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPADMINDN"
+TARGET="_top"
+>ldap admin dn</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPSUFFIX"
+TARGET="_top"
+>ldap suffix</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPFILTER"
+TARGET="_top"
+>ldap filter</A
+></P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#LDAPPORT"
+TARGET="_top"
+>ldap port</A
+></P
+></LI
+></UL
+><P
+>These are described in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+> man
+page and so will not be repeated here. However, a sample smb.conf file for
+use with an LDAP directory could appear as</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>## /usr/local/samba/lib/smb.conf
+[global]
+ security = user
+ encrypt passwords = yes
+
+ netbios name = TASHTEGO
+ workgroup = NARNIA
+
+ # ldap related parameters
+
+ # define the DN to use when binding to the directory servers
+ # The password for this DN is not stored in smb.conf. Rather it
+ # must be set by using 'smbpasswd -w <TT
+CLASS="REPLACEABLE"
+><I
+>secretpw</I
+></TT
+>' to store the
+ # passphrase in the secrets.tdb file. If the "ldap admin dn" values
+ # changes, this password will need to be reset.
+ ldap admin dn = "cn=Samba Manager,ou=people,dc=samba,dc=org"
+
+ # specify the LDAP server's hostname (defaults to locahost)
+ ldap server = ahab.samba.org
+
+ # Define the SSL option when connecting to the directory
+ # ('off', 'start tls', or 'on' (default))
+ ldap ssl = start tls
+
+ # define the port to use in the LDAP session (defaults to 636 when
+ # "ldap ssl = on")
+ ldap port = 389
+
+ # specify the base DN to use when searching the directory
+ ldap suffix = "ou=people,dc=samba,dc=org"
+
+ # generally the default ldap search filter is ok
+ # ldap filter = "(&#38;(uid=%u)(objectclass=sambaAccount))"</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN128"
+>Importing <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> entries</A
+></H2
+><P
+>Import existing user entries from an <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> can be trivially done using
+a Perl script named <TT
+CLASS="FILENAME"
+>import_smbpasswd.pl</TT
+> included in the
+<TT
+CLASS="FILENAME"
+>examples/LDAP/</TT
+> directory of the Samba source distribution. There are
+two main requirements of this script:</P
+><P
+></P
+><UL
+><LI
+><P
+>All users to be imported to the directory must have a valid uid on the
+ local system. This can be a problem if using a machinej different from the Samba server
+ to import the file.</P
+></LI
+><LI
+><P
+>The local system must have a working installation of the Net::LDAP perl
+ module which can be obtained from with <A
+HREF="http://search.cpan.org/"
+TARGET="_top"
+>http://search.cpan.org/</A
+>
+ by searching for <TT
+CLASS="FILENAME"
+>perl-ldap</TT
+> or directly from <A
+HREF="http://perl-ldap.sf.net/"
+TARGET="_top"
+>http://perl-ldap.sf.net/</A
+>.
+ </P
+></LI
+></UL
+><P
+>Please refer to the documentation in the same directory as the script for more details.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN144"
+>Accounts and Groups management</A
+></H1
+><P
+>As users accounts are managed thru the sambaAccount objectclass, you should
+modify you existing administration tools to deal with sambaAccount attributes.</P
+><P
+>Machines accounts are managed with the sambaAccount objectclass, just
+like users accounts. However, it's up to you to stored thoses accounts
+in a different tree of you LDAP namespace: you should use
+"ou=Groups,dc=plainjoe,dc=org" to store groups and
+"ou=People,dc=plainjoe,dc=org" to store users. Just configure your
+NSS and PAM accordingly (usually, in the /etc/ldap.conf configuration
+file).</P
+><P
+>In Samba release 2.2.3, the group management system is based on posix
+groups. This meand that Samba make usage of the posixGroup objectclass.
+For now, there is no NT-like group system management (global and local
+groups).</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN149"
+>Security and sambaAccount</A
+></H1
+><P
+>There are two important points to remember when discussing the security
+of sambaAccount entries in the directory.</P
+><P
+></P
+><UL
+><LI
+><P
+><I
+CLASS="EMPHASIS"
+>Never</I
+> retrieve the lmPassword or
+ ntPassword attribute values over an unencrypted LDAP session.</P
+></LI
+><LI
+><P
+><I
+CLASS="EMPHASIS"
+>Never</I
+> allow non-admin users to
+ view the lmPassword or ntPassword attribute values.</P
+></LI
+></UL
+><P
+>These password hashes are clear text equivalents and can be used to impersonate
+the user without deriving the original clear text strings. For more information
+on the details of LM/NT password hashes, refer to the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>ENCRYPTION chapter</A
+> of the Samba-HOWTO-Collection.</P
+><P
+>To remedy the first security issue, the "ldap ssl" smb.conf parameter defaults
+to require an encrypted session (<B
+CLASS="COMMAND"
+>ldap ssl = on</B
+>) using
+the default port of 636
+when contacting the directory server. When using an OpenLDAP 2.0 server, it
+is possible to use the use the StartTLS LDAP extended operation in the place of
+LDAPS. In either case, you are strongly discouraged to disable this security
+(<B
+CLASS="COMMAND"
+>ldap ssl = off</B
+>).</P
+><P
+>Note that the LDAPS protocol is deprecated in favor of the LDAPv3 StartTLS
+extended operation. However, the OpenLDAP library still provides support for
+the older method of securing communication between clients and servers.</P
+><P
+>The second security precaution is to prevent non-administrative users from
+harvesting password hashes from the directory. This can be done using the
+following ACL in <TT
+CLASS="FILENAME"
+>slapd.conf</TT
+>:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>## allow the "ldap admin dn" access, but deny everyone else
+access to attrs=lmPassword,ntPassword
+ by dn="cn=Samba Admin,ou=people,dc=plainjoe,dc=org" write
+ by * none</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN169"
+>LDAP specials attributes for sambaAccounts</A
+></H1
+><P
+>The sambaAccount objectclass is composed of the following attributes:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmPassword</TT
+>: the LANMAN password 16-byte hash stored as a character
+ representation of a hexidecimal string.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ntPassword</TT
+>: the NT password hash 16-byte stored as a character
+ representation of a hexidecimal string.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdLastSet</TT
+>: The integer time in seconds since 1970 when the
+ <TT
+CLASS="CONSTANT"
+>lmPassword</TT
+> and <TT
+CLASS="CONSTANT"
+>ntPassword</TT
+> attributes were last set.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>acctFlags</TT
+>: string of 11 characters surrounded by square brackets []
+ representing account flags such as U (user), W(workstation), X(no password expiration), and
+ D(disabled).</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>logonTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>logoffTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>kickoffTime</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdCanChange</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>pwdMustChange</TT
+>: Integer value currently unused</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>homeDrive</TT
+>: specifies the drive letter to which to map the
+ UNC path specified by homeDirectory. The drive letter must be specified in the form "X:"
+ where X is the letter of the drive to map. Refer to the "logon drive" parameter in the
+ smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>scriptPath</TT
+>: The scriptPath property specifies the path of
+ the user's logon script, .CMD, .EXE, or .BAT file. The string can be null. The path
+ is relative to the netlogon share. Refer to the "logon script" parameter in the
+ smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>profilePath</TT
+>: specifies a path to the user's profile.
+ This value can be a null string, a local absolute path, or a UNC path. Refer to the
+ "logon path" parameter in the smb.conf(5) man page for more information.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>smbHome</TT
+>: The homeDirectory property specifies the path of
+ the home directory for the user. The string can be null. If homeDrive is set and specifies
+ a drive letter, homeDirectory should be a UNC path. The path must be a network
+ UNC path of the form \\server\share\directory. This value can be a null string.
+ Refer to the "logon home" parameter in the smb.conf(5) man page for more information.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>userWorkstation</TT
+>: character string value currently unused.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>rid</TT
+>: the integer representation of the user's relative identifier
+ (RID).</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>primaryGroupID</TT
+>: the relative identifier (RID) of the primary group
+ of the user.</P
+></LI
+></UL
+><P
+>The majority of these parameters are only used when Samba is acting as a PDC of
+a domain (refer to the <A
+HREF="Samba-PDC-HOWTO.html"
+TARGET="_top"
+>Samba-PDC-HOWTO</A
+> for details on
+how to configure Samba as a Primary Domain Controller). The following four attributes
+are only stored with the sambaAccount entry if the values are non-default values:</P
+><P
+></P
+><UL
+><LI
+><P
+>smbHome</P
+></LI
+><LI
+><P
+>scriptPath</P
+></LI
+><LI
+><P
+>logonPath</P
+></LI
+><LI
+><P
+>homeDrive</P
+></LI
+></UL
+><P
+>These attributes are only stored with the sambaAccount entry if
+the values are non-default values. For example, assume TASHTEGO has now been
+configured as a PDC and that <B
+CLASS="COMMAND"
+>logon home = \\%L\%u</B
+> was defined in
+its <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. When a user named "becky" logons to the domain,
+the <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+> string is expanded to \\TASHTEGO\becky.
+If the smbHome attribute exists in the entry "uid=becky,ou=people,dc=samba,dc=org",
+this value is used. However, if this attribute does not exist, then the value
+of the <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+> parameter is used in its place. Samba
+will only write the attribute value to the directory entry is the value is
+something other than the default (e.g. \\MOBY\becky).</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN239"
+>Example LDIF Entries for a sambaAccount</A
+></H1
+><P
+>The following is a working LDIF with the inclusion of the posixAccount objectclass:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>dn: uid=guest2, ou=people,dc=plainjoe,dc=org
+ntPassword: 878D8014606CDA29677A44EFA1353FC7
+pwdMustChange: 2147483647
+primaryGroupID: 1201
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+pwdLastSet: 1010179124
+logonTime: 0
+objectClass: sambaAccount
+uid: guest2
+kickoffTime: 2147483647
+acctFlags: [UX ]
+logoffTime: 2147483647
+rid: 19006
+pwdCanChange: 0</PRE
+></P
+><P
+>The following is an LDIF entry for using both the sambaAccount and
+posixAccount objectclasses:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>dn: uid=gcarter, ou=people,dc=plainjoe,dc=org
+logonTime: 0
+displayName: Gerald Carter
+lmPassword: 552902031BEDE9EFAAD3B435B51404EE
+primaryGroupID: 1201
+objectClass: posixAccount
+objectClass: sambaAccount
+acctFlags: [UX ]
+userPassword: {crypt}BpM2ej8Rkzogo
+uid: gcarter
+uidNumber: 9000
+cn: Gerald Carter
+loginShell: /bin/bash
+logoffTime: 2147483647
+gidNumber: 100
+kickoffTime: 2147483647
+pwdLastSet: 1010179230
+rid: 19000
+homeDirectory: /home/tashtego/gcarter
+pwdCanChange: 0
+pwdMustChange: 2147483647
+ntPassword: 878D8014606CDA29677A44EFA1353FC7</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN247"
+>Comments</A
+></H1
+><P
+>Please mail all comments regarding this HOWTO to <A
+HREF="mailto:jerry@samba.org"
+TARGET="_top"
+>jerry@samba.org</A
+>. This documents was
+last updated to reflect the Samba 2.2.5 release.&#13;</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/Samba-PDC-HOWTO.html b/docs/htmldocs/Samba-PDC-HOWTO.html
new file mode 100755
index 00000000000..58f3989b4f0
--- /dev/null
+++ b/docs/htmldocs/Samba-PDC-HOWTO.html
@@ -0,0 +1,2284 @@
+<HTML
+><HEAD
+><TITLE
+>How to Configure Samba 2.2 as a Primary Domain Controller</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="SAMBA-PDC"
+>How to Configure Samba 2.2 as a Primary Domain Controller</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Prerequisite Reading</A
+></H1
+><P
+>Before you continue reading in this chapter, please make sure
+that you are comfortable with configuring basic files services
+in smb.conf and how to enable and administer password
+encryption in Samba. Theses two topics are covered in the
+<A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+>
+manpage and the <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>Encryption chapter</A
+>
+of this HOWTO Collection.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN9"
+>Background</A
+></H1
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+><I
+CLASS="EMPHASIS"
+>Author's Note:</I
+> This document is a combination
+of David Bannon's "Samba 2.2 PDC HOWTO" and "Samba NT Domain FAQ".
+Both documents are superseded by this one.</P
+></BLOCKQUOTE
+></DIV
+><P
+>Versions of Samba prior to release 2.2 had marginal capabilities to act
+as a Windows NT 4.0 Primary Domain Controller
+
+(PDC). With Samba 2.2.0, we are proud to announce official support for
+Windows NT 4.0-style domain logons from Windows NT 4.0 and Windows
+2000 clients. This article outlines the steps
+necessary for configuring Samba as a PDC. It is necessary to have a
+working Samba server prior to implementing the PDC functionality. If
+you have not followed the steps outlined in <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+> UNIX_INSTALL.html</A
+>, please make sure
+that your server is configured correctly before proceeding. Another
+good resource in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5) man
+page</A
+>. The following functionality should work in 2.2:</P
+><P
+></P
+><UL
+><LI
+><P
+> domain logons for Windows NT 4.0/2000 clients.
+ </P
+></LI
+><LI
+><P
+> placing a Windows 9x client in user level security
+ </P
+></LI
+><LI
+><P
+> retrieving a list of users and groups from a Samba PDC to
+ Windows 9x/NT/2000 clients
+ </P
+></LI
+><LI
+><P
+> roving (roaming) user profiles
+ </P
+></LI
+><LI
+><P
+> Windows NT 4.0-style system policies
+ </P
+></LI
+></UL
+><P
+>The following pieces of functionality are not included in the 2.2 release:</P
+><P
+></P
+><UL
+><LI
+><P
+> Windows NT 4 domain trusts
+ </P
+></LI
+><LI
+><P
+> SAM replication with Windows NT 4.0 Domain Controllers
+ (i.e. a Samba PDC and a Windows NT BDC or vice versa)
+ </P
+></LI
+><LI
+><P
+> Adding users via the User Manager for Domains
+ </P
+></LI
+><LI
+><P
+> Acting as a Windows 2000 Domain Controller (i.e. Kerberos and
+ Active Directory)
+ </P
+></LI
+></UL
+><P
+>Please note that Windows 9x clients are not true members of a domain
+for reasons outlined in this article. Therefore the protocol for
+support Windows 9x-style domain logons is completely different
+from NT4 domain logons and has been officially supported for some
+time.</P
+><P
+>Implementing a Samba PDC can basically be divided into 2 broad
+steps.</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> Configuring the Samba PDC
+ </P
+></LI
+><LI
+><P
+> Creating machine trust accounts and joining clients
+ to the domain
+ </P
+></LI
+></OL
+><P
+>There are other minor details such as user profiles, system
+policies, etc... However, these are not necessarily specific
+to a Samba PDC as much as they are related to Windows NT networking
+concepts. They will be mentioned only briefly here.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN48"
+>Configuring the Samba Domain Controller</A
+></H1
+><P
+>The first step in creating a working Samba PDC is to
+understand the parameters necessary in smb.conf. I will not
+attempt to re-explain the parameters here as they are more that
+adequately covered in <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> the smb.conf
+man page</A
+>. For convenience, the parameters have been
+linked with the actual smb.conf description.</P
+><P
+>Here is an example <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for acting as a PDC:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ ; Basic server settings
+ <A
+HREF="smb.conf.5.html#NETBIOSNAME"
+TARGET="_top"
+>netbios name</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>POGO</I
+></TT
+>
+ <A
+HREF="smb.conf.5.html#WORKGROUP"
+TARGET="_top"
+>workgroup</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>NARNIA</I
+></TT
+>
+
+ ; we should act as the domain and local master browser
+ <A
+HREF="smb.conf.5.html#OSLEVEL"
+TARGET="_top"
+>os level</A
+> = 64
+ <A
+HREF="smb.conf.5.html#PERFERREDMASTER"
+TARGET="_top"
+>preferred master</A
+> = yes
+ <A
+HREF="smb.conf.5.html#DOMAINMASTER"
+TARGET="_top"
+>domain master</A
+> = yes
+ <A
+HREF="smb.conf.5.html#LOCALMASTER"
+TARGET="_top"
+>local master</A
+> = yes
+
+ ; security settings (must user security = user)
+ <A
+HREF="smb.conf.5.html#SECURITYEQUALSUSER"
+TARGET="_top"
+>security</A
+> = user
+
+ ; encrypted passwords are a requirement for a PDC
+ <A
+HREF="smb.conf.5.html#ENCRYPTPASSWORDS"
+TARGET="_top"
+>encrypt passwords</A
+> = yes
+
+ ; support domain logons
+ <A
+HREF="smb.conf.5.html#DOMAINLOGONS"
+TARGET="_top"
+>domain logons</A
+> = yes
+
+ ; where to store user profiles?
+ <A
+HREF="smb.conf.5.html#LOGONPATH"
+TARGET="_top"
+>logon path</A
+> = \\%N\profiles\%u
+
+ ; where is a user's home directory and where should it
+ ; be mounted at?
+ <A
+HREF="smb.conf.5.html#LOGONDRIVE"
+TARGET="_top"
+>logon drive</A
+> = H:
+ <A
+HREF="smb.conf.5.html#LOGONHOME"
+TARGET="_top"
+>logon home</A
+> = \\homeserver\%u
+
+ ; specify a generic logon script for all users
+ ; this is a relative **DOS** path to the [netlogon] share
+ <A
+HREF="smb.conf.5.html#LOGONSCRIPT"
+TARGET="_top"
+>logon script</A
+> = logon.cmd
+
+; necessary share for domain controller
+[netlogon]
+ <A
+HREF="smb.conf.5.html#PATH"
+TARGET="_top"
+>path</A
+> = /usr/local/samba/lib/netlogon
+ <A
+HREF="smb.conf.5.html#READONLY"
+TARGET="_top"
+>read only</A
+> = yes
+ <A
+HREF="smb.conf.5.html#WRITELIST"
+TARGET="_top"
+>write list</A
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>ntadmin</I
+></TT
+>
+
+; share for storing user profiles
+[profiles]
+ <A
+HREF="smb.conf.5.html#PATH"
+TARGET="_top"
+>path</A
+> = /export/smb/ntprofile
+ <A
+HREF="smb.conf.5.html#READONLY"
+TARGET="_top"
+>read only</A
+> = no
+ <A
+HREF="smb.conf.5.html#CREATEMASK"
+TARGET="_top"
+>create mask</A
+> = 0600
+ <A
+HREF="smb.conf.5.html#DIRECTORYMASK"
+TARGET="_top"
+>directory mask</A
+> = 0700</PRE
+></P
+><P
+>There are a couple of points to emphasize in the above configuration.</P
+><P
+></P
+><UL
+><LI
+><P
+> Encrypted passwords must be enabled. For more details on how
+ to do this, refer to <A
+HREF="ENCRYPTION.html"
+TARGET="_top"
+>ENCRYPTION.html</A
+>.
+ </P
+></LI
+><LI
+><P
+> The server must support domain logons and a
+ <TT
+CLASS="FILENAME"
+>[netlogon]</TT
+> share
+ </P
+></LI
+><LI
+><P
+> The server must be the domain master browser in order for Windows
+ client to locate the server as a DC. Please refer to the various
+ Network Browsing documentation included with this distribution for
+ details.
+ </P
+></LI
+></UL
+><P
+>As Samba 2.2 does not offer a complete implementation of group mapping
+between Windows NT groups and Unix groups (this is really quite
+complicated to explain in a short space), you should refer to the
+<A
+HREF="smb.conf.5.html#DOMAINADMINGROUP"
+TARGET="_top"
+>domain admin
+group</A
+> smb.conf parameter for information of creating "Domain
+Admins" style accounts.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN91"
+>Creating Machine Trust Accounts and Joining Clients to the
+Domain</A
+></H1
+><P
+>A machine trust account is a Samba account that is used to
+authenticate a client machine (rather than a user) to the Samba
+server. In Windows terminology, this is known as a "Computer
+Account."</P
+><P
+>The password of a machine trust account acts as the shared secret for
+secure communication with the Domain Controller. This is a security
+feature to prevent an unauthorized machine with the same NetBIOS name
+from joining the domain and gaining access to domain user/group
+accounts. Windows NT and 2000 clients use machine trust accounts, but
+Windows 9x clients do not. Hence, a Windows 9x client is never a true
+member of a domain because it does not possess a machine trust
+account, and thus has no shared secret with the domain controller.</P
+><P
+>A Windows PDC stores each machine trust account in the Windows
+Registry. A Samba PDC, however, stores each machine trust account
+in two parts, as follows:
+
+<P
+></P
+><UL
+><LI
+><P
+>A Samba account, stored in the same location as user
+ LanMan and NT password hashes (currently
+ <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+>). The Samba account
+ possesses and uses only the NT password hash.</P
+></LI
+><LI
+><P
+>A corresponding Unix account, typically stored in
+ <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>. (Future releases will alleviate the need to
+ create <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entries.) </P
+></LI
+></UL
+></P
+><P
+>There are two ways to create machine trust accounts:</P
+><P
+></P
+><UL
+><LI
+><P
+> Manual creation. Both the Samba and corresponding
+ Unix account are created by hand.</P
+></LI
+><LI
+><P
+> "On-the-fly" creation. The Samba machine trust
+ account is automatically created by Samba at the time the client
+ is joined to the domain. (For security, this is the
+ recommended method.) The corresponding Unix account may be
+ created automatically or manually. </P
+></LI
+></UL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN110"
+>Manual Creation of Machine Trust Accounts</A
+></H2
+><P
+>The first step in manually creating a machine trust account is to
+manually create the corresponding Unix account in
+<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>. This can be done using
+<B
+CLASS="COMMAND"
+>vipw</B
+> or other 'add user' command that is normally
+used to create new Unix accounts. The following is an example for a
+Linux based Samba server:</P
+><P
+> <TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>/usr/sbin/useradd -g 100 -d /dev/null -c <TT
+CLASS="REPLACEABLE"
+><I
+>"machine
+nickname"</I
+></TT
+> -s /bin/false <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+>$ </B
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>passwd -l <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+>$</B
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry will list the machine name
+with a "$" appended, won't have a password, will have a null shell and no
+home directory. For example a machine named 'doppy' would have an
+<TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry like this:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>doppy$:x:505:501:<TT
+CLASS="REPLACEABLE"
+><I
+>machine_nickname</I
+></TT
+>:/dev/null:/bin/false</PRE
+></P
+><P
+>Above, <TT
+CLASS="REPLACEABLE"
+><I
+>machine_nickname</I
+></TT
+> can be any
+descriptive name for the client, i.e., BasementComputer.
+<TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+> absolutely must be the NetBIOS
+name of the client to be joined to the domain. The "$" must be
+appended to the NetBIOS name of the client or Samba will not recognize
+this as a machine trust account.</P
+><P
+>Now that the corresponding Unix account has been created, the next step is to create
+the Samba account for the client containing the well-known initial
+machine trust account password. This can be done using the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+> command
+as shown here:</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><B
+CLASS="COMMAND"
+>smbpasswd -a -m <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+></B
+></P
+><P
+>where <TT
+CLASS="REPLACEABLE"
+><I
+>machine_name</I
+></TT
+> is the machine's NetBIOS
+name. The RID of the new machine account is generated from the UID of
+the corresponding Unix account.</P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Join the client to the domain immediately</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+> Manually creating a machine trust account using this method is the
+ equivalent of creating a machine trust account on a Windows NT PDC using
+ the "Server Manager". From the time at which the account is created
+ to the time which the client joins the domain and changes the password,
+ your domain is vulnerable to an intruder joining your domain using a
+ a machine with the same NetBIOS name. A PDC inherently trusts
+ members of the domain and will serve out a large degree of user
+ information to such clients. You have been warned!
+ </P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN145"
+>"On-the-Fly" Creation of Machine Trust Accounts</A
+></H2
+><P
+>The second (and recommended) way of creating machine trust accounts is
+simply to allow the Samba server to create them as needed when the client
+is joined to the domain. </P
+><P
+>Since each Samba machine trust account requires a corresponding
+Unix account, a method for automatically creating the
+Unix account is usually supplied; this requires configuration of the
+<A
+HREF="smb.conf.5.html#ADDUSERSCRIPT"
+TARGET="_top"
+>add user script</A
+>
+option in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>. This
+method is not required, however; corresponding Unix accounts may also
+be created manually.</P
+><P
+>Below is an example for a RedHat 6.2 Linux system.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ # &#60;...remainder of parameters...&#62;
+ add user script = /usr/sbin/useradd -d /dev/null -g 100 -s /bin/false -M %u </PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN154"
+>Joining the Client to the Domain</A
+></H2
+><P
+>The procedure for joining a client to the domain varies with the
+version of Windows.</P
+><P
+></P
+><UL
+><LI
+><P
+><I
+CLASS="EMPHASIS"
+>Windows 2000</I
+></P
+><P
+> When the user elects to join the client to a domain, Windows prompts for
+ an account and password that is privileged to join the domain. A
+ Samba administrative account (i.e., a Samba account that has root
+ privileges on the Samba server) must be entered here; the
+ operation will fail if an ordinary user account is given.
+ The password for this account should be
+ set to a different password than the associated
+ <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> entry, for security
+ reasons. </P
+><P
+>The session key of the Samba administrative account acts as an
+ encryption key for setting the password of the machine trust
+ account. The machine trust account will be created on-the-fly, or
+ updated if it already exists.</P
+></LI
+><LI
+><P
+><I
+CLASS="EMPHASIS"
+>Windows NT</I
+></P
+><P
+> If the machine trust account was created manually, on the
+ Identification Changes menu enter the domain name, but do not
+ check the box "Create a Computer Account in the Domain." In this case,
+ the existing machine trust account is used to join the machine to
+ the domain.</P
+><P
+> If the machine trust account is to be created
+ on-the-fly, on the Identification Changes menu enter the domain
+ name, and check the box "Create a Computer Account in the Domain." In
+ this case, joining the domain proceeds as above for Windows 2000
+ (i.e., you must supply a Samba administrative account when
+ prompted).</P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN169"
+>Common Problems and Errors</A
+></H1
+><P
+></P
+><P
+></P
+><UL
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>I cannot include a '$' in a machine name.</I
+>
+ </P
+><P
+> A 'machine name' in (typically) <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>
+ of the machine name with a '$' appended. FreeBSD (and other BSD
+ systems?) won't create a user with a '$' in their name.
+ </P
+><P
+> The problem is only in the program used to make the entry, once
+ made, it works perfectly. So create a user without the '$' and
+ use <B
+CLASS="COMMAND"
+>vipw</B
+> to edit the entry, adding the '$'. Or create
+ the whole entry with vipw if you like, make sure you use a
+ unique User ID !
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>I get told "You already have a connection to the Domain...."
+ or "Cannot join domain, the credentials supplied conflict with an
+ existing set.." when creating a machine trust account.</I
+>
+ </P
+><P
+> This happens if you try to create a machine trust account from the
+ machine itself and already have a connection (e.g. mapped drive)
+ to a share (or IPC$) on the Samba PDC. The following command
+ will remove all network drive connections:
+ </P
+><P
+> <TT
+CLASS="PROMPT"
+>C:\WINNT\&#62;</TT
+> <B
+CLASS="COMMAND"
+>net use * /d</B
+>
+ </P
+><P
+> Further, if the machine is a already a 'member of a workgroup' that
+ is the same name as the domain you are joining (bad idea) you will
+ get this message. Change the workgroup name to something else, it
+ does not matter what, reboot, and try again.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>The system can not log you on (C000019B)....</I
+>
+ </P
+><P
+>I joined the domain successfully but after upgrading
+ to a newer version of the Samba code I get the message, "The system
+ can not log you on (C000019B), Please try a gain or consult your
+ system administrator" when attempting to logon.
+ </P
+><P
+> This occurs when the domain SID stored in
+ <TT
+CLASS="FILENAME"
+>private/WORKGROUP.SID</TT
+> is
+ changed. For example, you remove the file and <B
+CLASS="COMMAND"
+>smbd</B
+> automatically
+ creates a new one. Or you are swapping back and forth between
+ versions 2.0.7, TNG and the HEAD branch code (not recommended). The
+ only way to correct the problem is to restore the original domain
+ SID or remove the domain client from the domain and rejoin.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>The machine trust account for this computer either does not
+ exist or is not accessible.</I
+>
+ </P
+><P
+> When I try to join the domain I get the message "The machine account
+ for this computer either does not exist or is not accessible". What's
+ wrong?
+ </P
+><P
+> This problem is caused by the PDC not having a suitable machine trust account.
+ If you are using the <TT
+CLASS="PARAMETER"
+><I
+>add user script</I
+></TT
+> method to create
+ accounts then this would indicate that it has not worked. Ensure the domain
+ admin user system is working.
+ </P
+><P
+> Alternatively if you are creating account entries manually then they
+ have not been created correctly. Make sure that you have the entry
+ correct for the machine trust account in smbpasswd file on the Samba PDC.
+ If you added the account using an editor rather than using the smbpasswd
+ utility, make sure that the account name is the machine NetBIOS name
+ with a '$' appended to it ( i.e. computer_name$ ). There must be an entry
+ in both /etc/passwd and the smbpasswd file. Some people have reported
+ that inconsistent subnet masks between the Samba server and the NT
+ client have caused this problem. Make sure that these are consistent
+ for both client and server.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>When I attempt to login to a Samba Domain from a NT4/W2K workstation,
+ I get a message about my account being disabled.</I
+>
+ </P
+><P
+> This problem is caused by a PAM related bug in Samba 2.2.0. This bug is
+ fixed in 2.2.1. Other symptoms could be unaccessible shares on
+ NT/W2K member servers in the domain or the following error in your smbd.log:
+ passdb/pampass.c:pam_account(268) PAM: UNKNOWN ERROR for User: %user%
+ </P
+><P
+> At first be ensure to enable the useraccounts with <B
+CLASS="COMMAND"
+>smbpasswd -e
+ %user%</B
+>, this is normally done, when you create an account.
+ </P
+><P
+> In order to work around this problem in 2.2.0, configure the
+ <TT
+CLASS="PARAMETER"
+><I
+>account</I
+></TT
+> control flag in
+ <TT
+CLASS="FILENAME"
+>/etc/pam.d/samba</TT
+> file as follows:
+ </P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> account required pam_permit.so
+ </PRE
+></P
+><P
+> If you want to remain backward compatibility to samba 2.0.x use
+ <TT
+CLASS="FILENAME"
+>pam_permit.so</TT
+>, it's also possible to use
+ <TT
+CLASS="FILENAME"
+>pam_pwdb.so</TT
+>. There are some bugs if you try to
+ use <TT
+CLASS="FILENAME"
+>pam_unix.so</TT
+>, if you need this, be ensure to use
+ the most recent version of this file.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN217"
+>System Policies and Profiles</A
+></H1
+><P
+>Much of the information necessary to implement System Policies and
+Roving User Profiles in a Samba domain is the same as that for
+implementing these same items in a Windows NT 4.0 domain.
+You should read the white paper <A
+HREF="http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp"
+TARGET="_top"
+>Implementing
+Profiles and Policies in Windows NT 4.0</A
+> available from Microsoft.</P
+><P
+>Here are some additional details:</P
+><P
+></P
+><UL
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>What about Windows NT Policy Editor?</I
+>
+ </P
+><P
+> To create or edit <TT
+CLASS="FILENAME"
+>ntconfig.pol</TT
+> you must use
+ the NT Server Policy Editor, <B
+CLASS="COMMAND"
+>poledit.exe</B
+> which
+ is included with NT Server but <I
+CLASS="EMPHASIS"
+>not NT Workstation</I
+>.
+ There is a Policy Editor on a NTws
+ but it is not suitable for creating <I
+CLASS="EMPHASIS"
+>Domain Policies</I
+>.
+ Further, although the Windows 95
+ Policy Editor can be installed on an NT Workstation/Server, it will not
+ work with NT policies because the registry key that are set by the policy templates.
+ However, the files from the NT Server will run happily enough on an NTws.
+ You need <TT
+CLASS="FILENAME"
+>poledit.exe, common.adm</TT
+> and <TT
+CLASS="FILENAME"
+>winnt.adm</TT
+>. It is convenient
+ to put the two *.adm files in <TT
+CLASS="FILENAME"
+>c:\winnt\inf</TT
+> which is where
+ the binary will look for them unless told otherwise. Note also that that
+ directory is 'hidden'.
+ </P
+><P
+> The Windows NT policy editor is also included with the Service Pack 3 (and
+ later) for Windows NT 4.0. Extract the files using <B
+CLASS="COMMAND"
+>servicepackname /x</B
+>,
+ i.e. that's <B
+CLASS="COMMAND"
+>Nt4sp6ai.exe /x</B
+> for service pack 6a. The policy editor,
+ <B
+CLASS="COMMAND"
+>poledit.exe</B
+> and the associated template files (*.adm) should
+ be extracted as well. It is also possible to downloaded the policy template
+ files for Office97 and get a copy of the policy editor. Another possible
+ location is with the Zero Administration Kit available for download from Microsoft.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>Can Win95 do Policies?</I
+>
+ </P
+><P
+> Install the group policy handler for Win9x to pick up group
+ policies. Look on the Win98 CD in <TT
+CLASS="FILENAME"
+>\tools\reskit\netadmin\poledit</TT
+>.
+ Install group policies on a Win9x client by double-clicking
+ <TT
+CLASS="FILENAME"
+>grouppol.inf</TT
+>. Log off and on again a couple of
+ times and see if Win98 picks up group policies. Unfortunately this needs
+ to be done on every Win9x machine that uses group policies....
+ </P
+><P
+> If group policies don't work one reports suggests getting the updated
+ (read: working) grouppol.dll for Windows 9x. The group list is grabbed
+ from /etc/group.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>How do I get 'User Manager' and 'Server Manager'</I
+>
+ </P
+><P
+> Since I don't need to buy an NT Server CD now, how do I get
+ the 'User Manager for Domains', the 'Server Manager'?
+ </P
+><P
+> Microsoft distributes a version of these tools called nexus for
+ installation on Windows 95 systems. The tools set includes
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Server Manager</P
+></LI
+><LI
+><P
+>User Manager for Domains</P
+></LI
+><LI
+><P
+>Event Viewer</P
+></LI
+></UL
+><P
+> Click here to download the archived file <A
+HREF="ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE"
+TARGET="_top"
+>ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE</A
+>
+ </P
+><P
+> The Windows NT 4.0 version of the 'User Manager for
+ Domains' and 'Server Manager' are available from Microsoft via ftp
+ from <A
+HREF="ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE"
+TARGET="_top"
+>ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE</A
+>
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN261"
+>What other help can I get?</A
+></H1
+><P
+>There are many sources of information available in the form
+of mailing lists, RFC's and documentation. The docs that come
+with the samba distribution contain very good explanations of
+general SMB topics such as browsing.</P
+><P
+></P
+><UL
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>What are some diagnostics tools I can use to debug the domain logon
+ process and where can I find them?</I
+>
+ </P
+><P
+> One of the best diagnostic tools for debugging problems is Samba itself.
+ You can use the -d option for both smbd and nmbd to specify what
+ 'debug level' at which to run. See the man pages on smbd, nmbd and
+ smb.conf for more information on debugging options. The debug
+ level can range from 1 (the default) to 10 (100 for debugging passwords).
+ </P
+><P
+> Another helpful method of debugging is to compile samba using the
+ <B
+CLASS="COMMAND"
+>gcc -g </B
+> flag. This will include debug
+ information in the binaries and allow you to attach gdb to the
+ running smbd / nmbd process. In order to attach gdb to an smbd
+ process for an NT workstation, first get the workstation to make the
+ connection. Pressing ctrl-alt-delete and going down to the domain box
+ is sufficient (at least, on the first time you join the domain) to
+ generate a 'LsaEnumTrustedDomains'. Thereafter, the workstation
+ maintains an open connection, and therefore there will be an smbd
+ process running (assuming that you haven't set a really short smbd
+ idle timeout) So, in between pressing ctrl alt delete, and actually
+ typing in your password, you can gdb attach and continue.
+ </P
+><P
+> Some useful samba commands worth investigating:
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>testparam | more</P
+></LI
+><LI
+><P
+>smbclient -L //{netbios name of server}</P
+></LI
+></UL
+><P
+> An SMB enabled version of tcpdump is available from
+ <A
+HREF="http://www.tcpdump.org/"
+TARGET="_top"
+>http://www.tcpdup.org/</A
+>.
+ Ethereal, another good packet sniffer for Unix and Win32
+ hosts, can be downloaded from <A
+HREF="http://www.ethereal.com/"
+TARGET="_top"
+>http://www.ethereal.com</A
+>.
+ </P
+><P
+> For tracing things on the Microsoft Windows NT, Network Monitor
+ (aka. netmon) is available on the Microsoft Developer Network CD's,
+ the Windows NT Server install CD and the SMS CD's. The version of
+ netmon that ships with SMS allows for dumping packets between any two
+ computers (i.e. placing the network interface in promiscuous mode).
+ The version on the NT Server install CD will only allow monitoring
+ of network traffic directed to the local NT box and broadcasts on the
+ local subnet. Be aware that Ethereal can read and write netmon
+ formatted files.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>How do I install 'Network Monitor' on an NT Workstation
+ or a Windows 9x box?</I
+>
+ </P
+><P
+> Installing netmon on an NT workstation requires a couple
+ of steps. The following are for installing Netmon V4.00.349, which comes
+ with Microsoft Windows NT Server 4.0, on Microsoft Windows NT
+ Workstation 4.0. The process should be similar for other version of
+ Windows NT / Netmon. You will need both the Microsoft Windows
+ NT Server 4.0 Install CD and the Workstation 4.0 Install CD.
+ </P
+><P
+> Initially you will need to install 'Network Monitor Tools and Agent'
+ on the NT Server. To do this
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Goto Start - Settings - Control Panel -
+ Network - Services - Add </P
+></LI
+><LI
+><P
+>Select the 'Network Monitor Tools and Agent' and
+ click on 'OK'.</P
+></LI
+><LI
+><P
+>Click 'OK' on the Network Control Panel.
+ </P
+></LI
+><LI
+><P
+>Insert the Windows NT Server 4.0 install CD
+ when prompted.</P
+></LI
+></UL
+><P
+> At this point the Netmon files should exist in
+ <TT
+CLASS="FILENAME"
+>%SYSTEMROOT%\System32\netmon\*.*</TT
+>.
+ Two subdirectories exist as well, <TT
+CLASS="FILENAME"
+>parsers\</TT
+>
+ which contains the necessary DLL's for parsing the netmon packet
+ dump, and <TT
+CLASS="FILENAME"
+>captures\</TT
+>.
+ </P
+><P
+> In order to install the Netmon tools on an NT Workstation, you will
+ first need to install the 'Network Monitor Agent' from the Workstation
+ install CD.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Goto Start - Settings - Control Panel -
+ Network - Services - Add</P
+></LI
+><LI
+><P
+>Select the 'Network Monitor Agent' and click
+ on 'OK'.</P
+></LI
+><LI
+><P
+>Click 'OK' on the Network Control Panel.
+ </P
+></LI
+><LI
+><P
+>Insert the Windows NT Workstation 4.0 install
+ CD when prompted.</P
+></LI
+></UL
+><P
+> Now copy the files from the NT Server in %SYSTEMROOT%\System32\netmon\*.*
+ to %SYSTEMROOT%\System32\netmon\*.* on the Workstation and set
+ permissions as you deem appropriate for your site. You will need
+ administrative rights on the NT box to run netmon.
+ </P
+><P
+> To install Netmon on a Windows 9x box install the network monitor agent
+ from the Windows 9x CD (\admin\nettools\netmon). There is a readme
+ file located with the netmon driver files on the CD if you need
+ information on how to do this. Copy the files from a working
+ Netmon installation.
+ </P
+></LI
+><LI
+><P
+> The following is a list if helpful URLs and other links:
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Home of Samba site <A
+HREF="http://samba.org"
+TARGET="_top"
+> http://samba.org</A
+>. We have a mirror near you !</P
+></LI
+><LI
+><P
+> The <I
+CLASS="EMPHASIS"
+>Development</I
+> document
+ on the Samba mirrors might mention your problem. If so,
+ it might mean that the developers are working on it.</P
+></LI
+><LI
+><P
+>See how Scott Merrill simulates a BDC behavior at
+ <A
+HREF="http://www.skippy.net/linux/smb-howto.html"
+TARGET="_top"
+> http://www.skippy.net/linux/smb-howto.html</A
+>. </P
+></LI
+><LI
+><P
+>Although 2.0.7 has almost had its day as a PDC, David Bannon will
+ keep the 2.0.7 PDC pages at <A
+HREF="http://bioserve.latrobe.edu.au/samba"
+TARGET="_top"
+> http://bioserve.latrobe.edu.au/samba</A
+> going for a while yet.</P
+></LI
+><LI
+><P
+>Misc links to CIFS information
+ <A
+HREF="http://samba.org/cifs/"
+TARGET="_top"
+>http://samba.org/cifs/</A
+></P
+></LI
+><LI
+><P
+>NT Domains for Unix <A
+HREF="http://mailhost.cb1.com/~lkcl/ntdom/"
+TARGET="_top"
+> http://mailhost.cb1.com/~lkcl/ntdom/</A
+></P
+></LI
+><LI
+><P
+>FTP site for older SMB specs:
+ <A
+HREF="ftp://ftp.microsoft.com/developr/drg/CIFS/"
+TARGET="_top"
+> ftp://ftp.microsoft.com/developr/drg/CIFS/</A
+></P
+></LI
+></UL
+></LI
+></UL
+><P
+></P
+><UL
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>How do I get help from the mailing lists?</I
+>
+ </P
+><P
+> There are a number of Samba related mailing lists. Go to <A
+HREF="http://samba.org"
+TARGET="_top"
+>http://samba.org</A
+>, click on your nearest mirror
+ and then click on <B
+CLASS="COMMAND"
+>Support</B
+> and then click on <B
+CLASS="COMMAND"
+> Samba related mailing lists</B
+>.
+ </P
+><P
+> For questions relating to Samba TNG go to
+ <A
+HREF="http://www.samba-tng.org/"
+TARGET="_top"
+>http://www.samba-tng.org/</A
+>
+ It has been requested that you don't post questions about Samba-TNG to the
+ main stream Samba lists.</P
+><P
+> If you post a message to one of the lists please observe the following guide lines :
+ </P
+><P
+></P
+><UL
+><LI
+><P
+> Always remember that the developers are volunteers, they are
+ not paid and they never guarantee to produce a particular feature at
+ a particular time. Any time lines are 'best guess' and nothing more.
+ </P
+></LI
+><LI
+><P
+> Always mention what version of samba you are using and what
+ operating system its running under. You should probably list the
+ relevant sections of your smb.conf file, at least the options
+ in [global] that affect PDC support.</P
+></LI
+><LI
+><P
+>In addition to the version, if you obtained Samba via
+ CVS mention the date when you last checked it out.</P
+></LI
+><LI
+><P
+> Try and make your question clear and brief, lots of long,
+ convoluted questions get deleted before they are completely read !
+ Don't post html encoded messages (if you can select colour or font
+ size its html).</P
+></LI
+><LI
+><P
+> If you run one of those nifty 'I'm on holidays' things when
+ you are away, make sure its configured to not answer mailing lists.
+ </P
+></LI
+><LI
+><P
+> Don't cross post. Work out which is the best list to post to
+ and see what happens, i.e. don't post to both samba-ntdom and samba-technical.
+ Many people active on the lists subscribe to more
+ than one list and get annoyed to see the same message two or more times.
+ Often someone will see a message and thinking it would be better dealt
+ with on another, will forward it on for you.</P
+></LI
+><LI
+><P
+>You might include <I
+CLASS="EMPHASIS"
+>partial</I
+>
+ log files written at a debug level set to as much as 20.
+ Please don't send the entire log but enough to give the context of the
+ error messages.</P
+></LI
+><LI
+><P
+>(Possibly) If you have a complete netmon trace ( from the opening of
+ the pipe to the error ) you can send the *.CAP file as well.</P
+></LI
+><LI
+><P
+>Please think carefully before attaching a document to an email.
+ Consider pasting the relevant parts into the body of the message. The samba
+ mailing lists go to a huge number of people, do they all need a copy of your
+ smb.conf in their attach directory?</P
+></LI
+></UL
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>How do I get off the mailing lists?</I
+>
+ </P
+><P
+>To have your name removed from a samba mailing list, go to the
+ same place you went to to get on it. Go to <A
+HREF="http://lists.samba.org/"
+TARGET="_top"
+>http://lists.samba.org</A
+>,
+ click on your nearest mirror and then click on <B
+CLASS="COMMAND"
+>Support</B
+> and
+ then click on <B
+CLASS="COMMAND"
+> Samba related mailing lists</B
+>. Or perhaps see
+ <A
+HREF="http://lists.samba.org/mailman/roster/samba-ntdom"
+TARGET="_top"
+>here</A
+>
+ </P
+><P
+> Please don't post messages to the list asking to be removed, you will just
+ be referred to the above address (unless that process failed in some way...)
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN375"
+>Domain Control for Windows 9x/ME</A
+></H1
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>The following section contains much of the original
+DOMAIN.txt file previously included with Samba. Much of
+the material is based on what went into the book <I
+CLASS="EMPHASIS"
+>Special
+Edition, Using Samba</I
+>, by Richard Sharpe.</P
+></BLOCKQUOTE
+></DIV
+><P
+>A domain and a workgroup are exactly the same thing in terms of network
+browsing. The difference is that a distributable authentication
+database is associated with a domain, for secure login access to a
+network. Also, different access rights can be granted to users if they
+successfully authenticate against a domain logon server (NT server and
+other systems based on NT server support this, as does at least Samba TNG now).</P
+><P
+>The SMB client logging on to a domain has an expectation that every other
+server in the domain should accept the same authentication information.
+Network browsing functionality of domains and workgroups is
+identical and is explained in BROWSING.txt. It should be noted, that browsing
+is totally orthogonal to logon support.</P
+><P
+>Issues related to the single-logon network model are discussed in this
+section. Samba supports domain logons, network logon scripts, and user
+profiles for MS Windows for workgroups and MS Windows 9X/ME clients
+which will be the focus of this section.</P
+><P
+>When an SMB client in a domain wishes to logon it broadcast requests for a
+logon server. The first one to reply gets the job, and validates its
+password using whatever mechanism the Samba administrator has installed.
+It is possible (but very stupid) to create a domain where the user
+database is not shared between servers, i.e. they are effectively workgroup
+servers advertising themselves as participating in a domain. This
+demonstrates how authentication is quite different from but closely
+involved with domains.</P
+><P
+>Using these features you can make your clients verify their logon via
+the Samba server; make clients run a batch file when they logon to
+the network and download their preferences, desktop and start menu.</P
+><P
+>Before launching into the configuration instructions, it is
+worthwhile lookingat how a Windows 9x/ME client performs a logon:</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> The client broadcasts (to the IP broadcast address of the subnet it is in)
+ a NetLogon request. This is sent to the NetBIOS name DOMAIN&#60;1c&#62; at the
+ NetBIOS layer. The client chooses the first response it receives, which
+ contains the NetBIOS name of the logon server to use in the format of
+ \\SERVER.
+ </P
+></LI
+><LI
+><P
+> The client then connects to that server, logs on (does an SMBsessetupX) and
+ then connects to the IPC$ share (using an SMBtconX).
+ </P
+></LI
+><LI
+><P
+> The client then does a NetWkstaUserLogon request, which retrieves the name
+ of the user's logon script.
+ </P
+></LI
+><LI
+><P
+> The client then connects to the NetLogon share and searches for this
+ and if it is found and can be read, is retrieved and executed by the client.
+ After this, the client disconnects from the NetLogon share.
+ </P
+></LI
+><LI
+><P
+> The client then sends a NetUserGetInfo request to the server, to retrieve
+ the user's home share, which is used to search for profiles. Since the
+ response to the NetUserGetInfo request does not contain much more
+ the user's home share, profiles for Win9X clients MUST reside in the user
+ home directory.
+ </P
+></LI
+><LI
+><P
+> The client then connects to the user's home share and searches for the
+ user's profile. As it turns out, you can specify the user's home share as
+ a sharename and path. For example, \\server\fred\.profile.
+ If the profiles are found, they are implemented.
+ </P
+></LI
+><LI
+><P
+> The client then disconnects from the user's home share, and reconnects to
+ the NetLogon share and looks for CONFIG.POL, the policies file. If this is
+ found, it is read and implemented.
+ </P
+></LI
+></OL
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN401"
+>Configuration Instructions: Network Logons</A
+></H2
+><P
+>The main difference between a PDC and a Windows 9x logon
+server configuration is that</P
+><P
+></P
+><UL
+><LI
+><P
+>Password encryption is not required for a Windows 9x logon server.</P
+></LI
+><LI
+><P
+>Windows 9x/ME clients do not possess machine trust accounts.</P
+></LI
+></UL
+><P
+>Therefore, a Samba PDC will also act as a Windows 9x logon
+server.</P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>security mode and master browsers</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>There are a few comments to make in order to tie up some
+loose ends. There has been much debate over the issue of whether
+or not it is ok to configure Samba as a Domain Controller in security
+modes other than <TT
+CLASS="CONSTANT"
+>USER</TT
+>. The only security mode
+which will not work due to technical reasons is <TT
+CLASS="CONSTANT"
+>SHARE</TT
+>
+mode security. <TT
+CLASS="CONSTANT"
+>DOMAIN</TT
+> and <TT
+CLASS="CONSTANT"
+>SERVER</TT
+>
+mode security is really just a variation on SMB user level security.</P
+><P
+>Actually, this issue is also closely tied to the debate on whether
+or not Samba must be the domain master browser for its workgroup
+when operating as a DC. While it may technically be possible
+to configure a server as such (after all, browsing and domain logons
+are two distinctly different functions), it is not a good idea to
+so. You should remember that the DC must register the DOMAIN#1b NetBIOS
+name. This is the name used by Windows clients to locate the DC.
+Windows clients do not distinguish between the DC and the DMB.
+For this reason, it is very wise to configure the Samba DC as the DMB.</P
+><P
+>Now back to the issue of configuring a Samba DC to use a mode other
+than "security = user". If a Samba host is configured to use
+another SMB server or DC in order to validate user connection
+requests, then it is a fact that some other machine on the network
+(the "password server") knows more about user than the Samba host.
+99% of the time, this other host is a domain controller. Now
+in order to operate in domain mode security, the "workgroup" parameter
+must be set to the name of the Windows NT domain (which already
+has a domain controller, right?)</P
+><P
+>Therefore configuring a Samba box as a DC for a domain that
+already by definition has a PDC is asking for trouble.
+Therefore, you should always configure the Samba DC to be the DMB
+for its domain.</P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN420"
+>Configuration Instructions: Setting up Roaming User Profiles</A
+></H2
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Warning</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+><I
+CLASS="EMPHASIS"
+>NOTE!</I
+> Roaming profiles support is different
+for Win9X and WinNT.</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>Before discussing how to configure roaming profiles, it is useful to see how
+Win9X and WinNT clients implement these features.</P
+><P
+>Win9X clients send a NetUserGetInfo request to the server to get the user's
+profiles location. However, the response does not have room for a separate
+profiles location field, only the user's home share. This means that Win9X
+profiles are restricted to being in the user's home directory.</P
+><P
+>WinNT clients send a NetSAMLogon RPC request, which contains many fields,
+including a separate field for the location of the user's profiles.
+This means that support for profiles is different for Win9X and WinNT.</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN428"
+>Windows NT Configuration</A
+></H3
+><P
+>To support WinNT clients, in the [global] section of smb.conf set the
+following (for example):</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>logon path = \\profileserver\profileshare\profilepath\%U\moreprofilepath</PRE
+></P
+><P
+>The default for this option is \\%N\%U\profile, namely
+\\sambaserver\username\profile. The \\N%\%U service is created
+automatically by the [homes] service.
+If you are using a samba server for the profiles, you _must_ make the
+share specified in the logon path browseable. </P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 26aug96 - we have discovered a problem where Windows clients can
+maintain a connection to the [homes] share in between logins. The
+[homes] share must NOT therefore be used in a profile path.]</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN436"
+>Windows 9X Configuration</A
+></H3
+><P
+>To support Win9X clients, you must use the "logon home" parameter. Samba has
+now been fixed so that "net use/home" now works as well, and it, too, relies
+on the "logon home" parameter.</P
+><P
+>By using the logon home parameter, you are restricted to putting Win9X
+profiles in the user's home directory. But wait! There is a trick you
+can use. If you set the following in the [global] section of your
+smb.conf file:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>logon home = \\%L\%U\.profiles</PRE
+></P
+><P
+>then your Win9X clients will dutifully put their clients in a subdirectory
+of your home directory called .profiles (thus making them hidden).</P
+><P
+>Not only that, but 'net use/home' will also work, because of a feature in
+Win9X. It removes any directory stuff off the end of the home directory area
+and only uses the server and share portion. That is, it looks like you
+specified \\%L\%U for "logon home".</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN444"
+>Win9X and WinNT Configuration</A
+></H3
+><P
+>You can support profiles for both Win9X and WinNT clients by setting both the
+"logon home" and "logon path" parameters. For example:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>logon home = \\%L\%U\.profiles
+logon path = \\%L\profiles\%U</PRE
+></P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>I have not checked what 'net use /home' does on NT when "logon home" is
+set as above.</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN451"
+>Windows 9X Profile Setup</A
+></H3
+><P
+>When a user first logs in on Windows 9X, the file user.DAT is created,
+as are folders "Start Menu", "Desktop", "Programs" and "Nethood".
+These directories and their contents will be merged with the local
+versions stored in c:\windows\profiles\username on subsequent logins,
+taking the most recent from each. You will need to use the [global]
+options "preserve case = yes", "short preserve case = yes" and
+"case sensitive = no" in order to maintain capital letters in shortcuts
+in any of the profile folders.</P
+><P
+>The user.DAT file contains all the user's preferences. If you wish to
+enforce a set of preferences, rename their user.DAT file to user.MAN,
+and deny them write access to this file.</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> On the Windows 95 machine, go to Control Panel | Passwords and
+ select the User Profiles tab. Select the required level of
+ roaming preferences. Press OK, but do _not_ allow the computer
+ to reboot.
+ </P
+></LI
+><LI
+><P
+> On the Windows 95 machine, go to Control Panel | Network |
+ Client for Microsoft Networks | Preferences. Select 'Log on to
+ NT Domain'. Then, ensure that the Primary Logon is 'Client for
+ Microsoft Networks'. Press OK, and this time allow the computer
+ to reboot.
+ </P
+></LI
+></OL
+><P
+>Under Windows 95, Profiles are downloaded from the Primary Logon.
+If you have the Primary Logon as 'Client for Novell Networks', then
+the profiles and logon script will be downloaded from your Novell
+Server. If you have the Primary Logon as 'Windows Logon', then the
+profiles will be loaded from the local machine - a bit against the
+concept of roaming profiles, if you ask me.</P
+><P
+>You will now find that the Microsoft Networks Login box contains
+[user, password, domain] instead of just [user, password]. Type in
+the samba server's domain name (or any other domain known to exist,
+but bear in mind that the user will be authenticated against this
+domain and profiles downloaded from it, if that domain logon server
+supports it), user name and user's password.</P
+><P
+>Once the user has been successfully validated, the Windows 95 machine
+will inform you that 'The user has not logged on before' and asks you
+if you wish to save the user's preferences? Select 'yes'.</P
+><P
+>Once the Windows 95 client comes up with the desktop, you should be able
+to examine the contents of the directory specified in the "logon path"
+on the samba server and verify that the "Desktop", "Start Menu",
+"Programs" and "Nethood" folders have been created.</P
+><P
+>These folders will be cached locally on the client, and updated when
+the user logs off (if you haven't made them read-only by then :-).
+You will find that if the user creates further folders or short-cuts,
+that the client will merge the profile contents downloaded with the
+contents of the profile directory already on the local client, taking
+the newest folders and short-cuts from each set.</P
+><P
+>If you have made the folders / files read-only on the samba server,
+then you will get errors from the w95 machine on logon and logout, as
+it attempts to merge the local and the remote profile. Basically, if
+you have any errors reported by the w95 machine, check the Unix file
+permissions and ownership rights on the profile directory contents,
+on the samba server.</P
+><P
+>If you have problems creating user profiles, you can reset the user's
+local desktop cache, as shown below. When this user then next logs in,
+they will be told that they are logging in "for the first time".</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+> instead of logging in under the [user, password, domain] dialog,
+ press escape.
+ </P
+></LI
+><LI
+><P
+> run the regedit.exe program, and look in:
+ </P
+><P
+> HKEY_LOCAL_MACHINE\Windows\CurrentVersion\ProfileList
+ </P
+><P
+> you will find an entry, for each user, of ProfilePath. Note the
+ contents of this key (likely to be c:\windows\profiles\username),
+ then delete the key ProfilePath for the required user.
+ </P
+><P
+> [Exit the registry editor].
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>WARNING</I
+> - before deleting the contents of the
+ directory listed in
+ the ProfilePath (this is likely to be c:\windows\profiles\username),
+ ask them if they have any important files stored on their desktop
+ or in their start menu. delete the contents of the directory
+ ProfilePath (making a backup if any of the files are needed).
+ </P
+><P
+> This will have the effect of removing the local (read-only hidden
+ system file) user.DAT in their profile directory, as well as the
+ local "desktop", "nethood", "start menu" and "programs" folders.
+ </P
+></LI
+><LI
+><P
+> search for the user's .PWL password-caching file in the c:\windows
+ directory, and delete it.
+ </P
+></LI
+><LI
+><P
+> log off the windows 95 client.
+ </P
+></LI
+><LI
+><P
+> check the contents of the profile path (see "logon path" described
+ above), and delete the user.DAT or user.MAN file for the user,
+ making a backup if required.
+ </P
+></LI
+></OL
+><P
+>If all else fails, increase samba's debug log levels to between 3 and 10,
+and / or run a packet trace program such as tcpdump or netmon.exe, and
+look for any error reports.</P
+><P
+>If you have access to an NT server, then first set up roaming profiles
+and / or netlogons on the NT server. Make a packet trace, or examine
+the example packet traces provided with NT server, and see what the
+differences are with the equivalent samba trace.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN487"
+>Windows NT Workstation 4.0</A
+></H3
+><P
+>When a user first logs in to a Windows NT Workstation, the profile
+NTuser.DAT is created. The profile location can be now specified
+through the "logon path" parameter. </P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 10aug97 - i tried setting the path to
+\\samba-server\homes\profile, and discovered that this fails because
+a background process maintains the connection to the [homes] share
+which does _not_ close down in between user logins. you have to
+have \\samba-server\%L\profile, where user is the username created
+from the [homes] share].</P
+></BLOCKQUOTE
+></DIV
+><P
+>There is a parameter that is now available for use with NT Profiles:
+"logon drive". This should be set to "h:" or any other drive, and
+should be used in conjunction with the new "logon home" parameter.</P
+><P
+>The entry for the NT 4.0 profile is a _directory_ not a file. The NT
+help on profiles mentions that a directory is also created with a .PDS
+extension. The user, while logging in, must have write permission to
+create the full profile path (and the folder with the .PDS extension)
+[lkcl 10aug97 - i found that the creation of the .PDS directory failed,
+and had to create these manually for each user, with a shell script.
+also, i presume, but have not tested, that the full profile path must
+be browseable just as it is for w95, due to the manner in which they
+attempt to create the full profile path: test existence of each path
+component; create path component].</P
+><P
+>In the profile directory, NT creates more folders than 95. It creates
+"Application Data" and others, as well as "Desktop", "Nethood",
+"Start Menu" and "Programs". The profile itself is stored in a file
+NTuser.DAT. Nothing appears to be stored in the .PDS directory, and
+its purpose is currently unknown.</P
+><P
+>You can use the System Control Panel to copy a local profile onto
+a samba server (see NT Help on profiles: it is also capable of firing
+up the correct location in the System Control Panel for you). The
+NT Help file also mentions that renaming NTuser.DAT to NTuser.MAN
+turns a profile into a mandatory one.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 10aug97 - i notice that NT Workstation tells me that it is
+downloading a profile from a slow link. whether this is actually the
+case, or whether there is some configuration issue, as yet unknown,
+that makes NT Workstation _think_ that the link is a slow one is a
+matter to be resolved].</P
+><P
+>[lkcl 20aug97 - after samba digest correspondence, one user found, and
+another confirmed, that profiles cannot be loaded from a samba server
+unless "security = user" and "encrypt passwords = yes" (see the file
+ENCRYPTION.txt) or "security = server" and "password server = ip.address.
+of.yourNTserver" are used. Either of these options will allow the NT
+workstation to access the samba server using LAN manager encrypted
+passwords, without the user intervention normally required by NT
+workstation for clear-text passwords].</P
+><P
+>[lkcl 25aug97 - more comments received about NT profiles: the case of
+the profile _matters_. the file _must_ be called NTuser.DAT or, for
+a mandatory profile, NTuser.MAN].</P
+></BLOCKQUOTE
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN500"
+>Windows NT Server</A
+></H3
+><P
+>There is nothing to stop you specifying any path that you like for the
+location of users' profiles. Therefore, you could specify that the
+profile be stored on a samba server, or any other SMB server, as long as
+that SMB server supports encrypted passwords.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN503"
+>Sharing Profiles between W95 and NT Workstation 4.0</A
+></H3
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Potentially outdated or incorrect material follows</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>I think this is all bogus, but have not deleted it. (Richard Sharpe)</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>The default logon path is \\%N\U%. NT Workstation will attempt to create
+a directory "\\samba-server\username.PDS" if you specify the logon path
+as "\\samba-server\username" with the NT User Manager. Therefore, you
+will need to specify (for example) "\\samba-server\username\profile".
+NT 4.0 will attempt to create "\\samba-server\username\profile.PDS", which
+is more likely to succeed.</P
+><P
+>If you then want to share the same Start Menu / Desktop with W95, you will
+need to specify "logon path = \\samba-server\username\profile" [lkcl 10aug97
+this has its drawbacks: i created a shortcut to telnet.exe, which attempts
+to run from the c:\winnt\system32 directory. this directory is obviously
+unlikely to exist on a Win95-only host].</P
+><P
+>&#13;If you have this set up correctly, you will find separate user.DAT and
+NTuser.DAT files in the same profile directory.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Note: </B
+>[lkcl 25aug97 - there are some issues to resolve with downloading of
+NT profiles, probably to do with time/date stamps. i have found that
+NTuser.DAT is never updated on the workstation after the first time that
+it is copied to the local workstation profile directory. this is in
+contrast to w95, where it _does_ transfer / update profiles correctly].</P
+></BLOCKQUOTE
+></DIV
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN513"
+>DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
+></H1
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Possibly Outdated Material</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+> This appendix was originally authored by John H Terpstra of
+ the Samba Team and is included here for posterity.
+ </P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+><I
+CLASS="EMPHASIS"
+>NOTE :</I
+>
+The term "Domain Controller" and those related to it refer to one specific
+method of authentication that can underly an SMB domain. Domain Controllers
+prior to Windows NT Server 3.1 were sold by various companies and based on
+private extensions to the LAN Manager 2.1 protocol. Windows NT introduced
+Microsoft-specific ways of distributing the user authentication database.
+See DOMAIN.txt for examples of how Samba can participate in or create
+SMB domains based on shared authentication database schemes other than the
+Windows NT SAM.</P
+><P
+>Windows NT Server can be installed as either a plain file and print server
+(WORKGROUP workstation or server) or as a server that participates in Domain
+Control (DOMAIN member, Primary Domain controller or Backup Domain controller).
+The same is true for OS/2 Warp Server, Digital Pathworks and other similar
+products, all of which can participate in Domain Control along with Windows NT.</P
+><P
+>To many people these terms can be confusing, so let's try to clear the air.</P
+><P
+>Every Windows NT system (workstation or server) has a registry database.
+The registry contains entries that describe the initialization information
+for all services (the equivalent of Unix Daemons) that run within the Windows
+NT environment. The registry also contains entries that tell application
+software where to find dynamically loadable libraries that they depend upon.
+In fact, the registry contains entries that describes everything that anything
+may need to know to interact with the rest of the system.</P
+><P
+>The registry files can be located on any Windows NT machine by opening a
+command prompt and typing:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINNT\&#62;</TT
+> dir %SystemRoot%\System32\config</P
+><P
+>The environment variable %SystemRoot% value can be obtained by typing:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINNT&#62;</TT
+>echo %SystemRoot%</P
+><P
+>The active parts of the registry that you may want to be familiar with are
+the files called: default, system, software, sam and security.</P
+><P
+>In a domain environment, Microsoft Windows NT domain controllers participate
+in replication of the SAM and SECURITY files so that all controllers within
+the domain have an exactly identical copy of each.</P
+><P
+>The Microsoft Windows NT system is structured within a security model that
+says that all applications and services must authenticate themselves before
+they can obtain permission from the security manager to do what they set out
+to do.</P
+><P
+>The Windows NT User database also resides within the registry. This part of
+the registry contains the user's security identifier, home directory, group
+memberships, desktop profile, and so on.</P
+><P
+>Every Windows NT system (workstation as well as server) will have its own
+registry. Windows NT Servers that participate in Domain Security control
+have a database that they share in common - thus they do NOT own an
+independent full registry database of their own, as do Workstations and
+plain Servers.</P
+><P
+>The User database is called the SAM (Security Access Manager) database and
+is used for all user authentication as well as for authentication of inter-
+process authentication (i.e. to ensure that the service action a user has
+requested is permitted within the limits of that user's privileges).</P
+><P
+>The Samba team have produced a utility that can dump the Windows NT SAM into
+smbpasswd format: see ENCRYPTION.txt for information on smbpasswd and
+/pub/samba/pwdump on your nearest Samba mirror for the utility. This
+facility is useful but cannot be easily used to implement SAM replication
+to Samba systems.</P
+><P
+>Windows for Workgroups, Windows 95, and Windows NT Workstations and Servers
+can participate in a Domain security system that is controlled by Windows NT
+servers that have been correctly configured. Almost every domain will have
+ONE Primary Domain Controller (PDC). It is desirable that each domain will
+have at least one Backup Domain Controller (BDC).</P
+><P
+>The PDC and BDCs then participate in replication of the SAM database so that
+each Domain Controlling participant will have an up to date SAM component
+within its registry.</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/UNIX_INSTALL.html b/docs/htmldocs/UNIX_INSTALL.html
new file mode 100755
index 00000000000..e3c1934adaa
--- /dev/null
+++ b/docs/htmldocs/UNIX_INSTALL.html
@@ -0,0 +1,814 @@
+<HTML
+><HEAD
+><TITLE
+>How to Install and Test SAMBA</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="INSTALL"
+>How to Install and Test SAMBA</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Step 0: Read the man pages</A
+></H1
+><P
+>The man pages distributed with SAMBA contain
+ lots of useful info that will help to get you started.
+ If you don't know how to read man pages then try
+ something like:</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>nroff -man smbd.8 | more
+ </B
+></TT
+></P
+><P
+>Other sources of information are pointed to
+ by the Samba web site,<A
+HREF="http://www.samba.org/"
+TARGET="_top"
+> http://www.samba.org</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN11"
+>Step 1: Building the Binaries</A
+></H1
+><P
+>To do this, first run the program <B
+CLASS="COMMAND"
+>./configure
+ </B
+> in the source directory. This should automatically
+ configure Samba for your operating system. If you have unusual
+ needs then you may wish to run</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>./configure --help
+ </B
+></TT
+></P
+><P
+>first to see what special options you can enable.
+ Then executing</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make</B
+></TT
+></P
+><P
+>will create the binaries. Once it's successfully
+ compiled you can use </P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make install</B
+></TT
+></P
+><P
+>to install the binaries and manual pages. You can
+ separately install the binaries and/or man pages using</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make installbin
+ </B
+></TT
+></P
+><P
+>and</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make installman
+ </B
+></TT
+></P
+><P
+>Note that if you are upgrading for a previous version
+ of Samba you might like to know that the old versions of
+ the binaries will be renamed with a ".old" extension. You
+ can go back to the previous version with</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>make revert
+ </B
+></TT
+></P
+><P
+>if you find this version a disaster!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN39"
+>Step 2: The all important step</A
+></H1
+><P
+>At this stage you must fetch yourself a
+ coffee or other drink you find stimulating. Getting the rest
+ of the install right can sometimes be tricky, so you will
+ probably need it.</P
+><P
+>If you have installed samba before then you can skip
+ this step.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN43"
+>Step 3: Create the smb configuration file.</A
+></H1
+><P
+>There are sample configuration files in the examples
+ subdirectory in the distribution. I suggest you read them
+ carefully so you can see how the options go together in
+ practice. See the man page for all the options.</P
+><P
+>The simplest useful configuration file would be
+ something like this:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> [global]
+ workgroup = MYGROUP
+
+ [homes]
+ guest ok = no
+ read only = no
+ </PRE
+></P
+><P
+>which would allow connections by anyone with an
+ account on the server, using either their login name or
+ "homes" as the service name. (Note that I also set the
+ workgroup that Samba is part of. See BROWSING.txt for details)</P
+><P
+>Note that <B
+CLASS="COMMAND"
+>make install</B
+> will not install
+ a <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. You need to create it
+ yourself. </P
+><P
+>Make sure you put the smb.conf file in the same place
+ you specified in the<TT
+CLASS="FILENAME"
+>Makefile</TT
+> (the default is to
+ look for it in <TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/</TT
+>).</P
+><P
+>For more information about security settings for the
+ [homes] share please refer to the document UNIX_SECURITY.txt.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN57"
+>Step 4: Test your config file with
+ <B
+CLASS="COMMAND"
+>testparm</B
+></A
+></H1
+><P
+>It's important that you test the validity of your
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file using the testparm program.
+ If testparm runs OK then it will list the loaded services. If
+ not it will give an error message.</P
+><P
+>Make sure it runs OK and that the services look
+ reasonable before proceeding. </P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN63"
+>Step 5: Starting the smbd and nmbd</A
+></H1
+><P
+>You must choose to start smbd and nmbd either
+ as daemons or from <B
+CLASS="COMMAND"
+>inetd</B
+>. Don't try
+ to do both! Either you can put them in <TT
+CLASS="FILENAME"
+> inetd.conf</TT
+> and have them started on demand
+ by <B
+CLASS="COMMAND"
+>inetd</B
+>, or you can start them as
+ daemons either from the command line or in <TT
+CLASS="FILENAME"
+> /etc/rc.local</TT
+>. See the man pages for details
+ on the command line options. Take particular care to read
+ the bit about what user you need to be in order to start
+ Samba. In many cases you must be root.</P
+><P
+>The main advantage of starting <B
+CLASS="COMMAND"
+>smbd</B
+>
+ and <B
+CLASS="COMMAND"
+>nmbd</B
+> using the recommended daemon method
+ is that they will respond slightly more quickly to an initial connection
+ request.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN73"
+>Step 5a: Starting from inetd.conf</A
+></H2
+><P
+>NOTE; The following will be different if
+ you use NIS or NIS+ to distributed services maps.</P
+><P
+>Look at your <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.
+ What is defined at port 139/tcp. If nothing is defined
+ then add a line like this:</P
+><P
+><TT
+CLASS="USERINPUT"
+><B
+>netbios-ssn 139/tcp</B
+></TT
+></P
+><P
+>similarly for 137/udp you should have an entry like:</P
+><P
+><TT
+CLASS="USERINPUT"
+><B
+>netbios-ns 137/udp</B
+></TT
+></P
+><P
+>Next edit your <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>
+ and add two lines something like this:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> netbios-ssn stream tcp nowait root /usr/local/samba/bin/smbd smbd
+ netbios-ns dgram udp wait root /usr/local/samba/bin/nmbd nmbd
+ </PRE
+></P
+><P
+>The exact syntax of <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>
+ varies between unixes. Look at the other entries in inetd.conf
+ for a guide.</P
+><P
+>NOTE: Some unixes already have entries like netbios_ns
+ (note the underscore) in <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.
+ You must either edit <TT
+CLASS="FILENAME"
+>/etc/services</TT
+> or
+ <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+> to make them consistent.</P
+><P
+>NOTE: On many systems you may need to use the
+ "interfaces" option in smb.conf to specify the IP address
+ and netmask of your interfaces. Run <B
+CLASS="COMMAND"
+>ifconfig</B
+>
+ as root if you don't know what the broadcast is for your
+ net. <B
+CLASS="COMMAND"
+>nmbd</B
+> tries to determine it at run
+ time, but fails on some unixes. See the section on "testing nmbd"
+ for a method of finding if you need to do this.</P
+><P
+>!!!WARNING!!! Many unixes only accept around 5
+ parameters on the command line in <TT
+CLASS="FILENAME"
+>inetd.conf</TT
+>.
+ This means you shouldn't use spaces between the options and
+ arguments, or you should use a script, and start the script
+ from <B
+CLASS="COMMAND"
+>inetd</B
+>.</P
+><P
+>Restart <B
+CLASS="COMMAND"
+>inetd</B
+>, perhaps just send
+ it a HUP. If you have installed an earlier version of <B
+CLASS="COMMAND"
+> nmbd</B
+> then you may need to kill nmbd as well.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN102"
+>Step 5b. Alternative: starting it as a daemon</A
+></H2
+><P
+>To start the server as a daemon you should create
+ a script something like this one, perhaps calling
+ it <TT
+CLASS="FILENAME"
+>startsmb</TT
+>.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> #!/bin/sh
+ /usr/local/samba/bin/smbd -D
+ /usr/local/samba/bin/nmbd -D
+ </PRE
+></P
+><P
+>then make it executable with <B
+CLASS="COMMAND"
+>chmod
+ +x startsmb</B
+></P
+><P
+>You can then run <B
+CLASS="COMMAND"
+>startsmb</B
+> by
+ hand or execute it from <TT
+CLASS="FILENAME"
+>/etc/rc.local</TT
+>
+ </P
+><P
+>To kill it send a kill signal to the processes
+ <B
+CLASS="COMMAND"
+>nmbd</B
+> and <B
+CLASS="COMMAND"
+>smbd</B
+>.</P
+><P
+>NOTE: If you use the SVR4 style init system then
+ you may like to look at the <TT
+CLASS="FILENAME"
+>examples/svr4-startup</TT
+>
+ script to make Samba fit into that system.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN118"
+>Step 6: Try listing the shares available on your
+ server</A
+></H1
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient -L
+ <TT
+CLASS="REPLACEABLE"
+><I
+>yourhostname</I
+></TT
+></B
+></TT
+></P
+><P
+>You should get back a list of shares available on
+ your server. If you don't then something is incorrectly setup.
+ Note that this method can also be used to see what shares
+ are available on other LanManager clients (such as WfWg).</P
+><P
+>If you choose user level security then you may find
+ that Samba requests a password before it will list the shares.
+ See the <B
+CLASS="COMMAND"
+>smbclient</B
+> man page for details. (you
+ can force it to list the shares without a password by
+ adding the option -U% to the command line. This will not work
+ with non-Samba servers)</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN127"
+>Step 7: Try connecting with the unix client</A
+></H1
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient <TT
+CLASS="REPLACEABLE"
+><I
+> //yourhostname/aservice</I
+></TT
+></B
+></TT
+></P
+><P
+>Typically the <TT
+CLASS="REPLACEABLE"
+><I
+>yourhostname</I
+></TT
+>
+ would be the name of the host where you installed <B
+CLASS="COMMAND"
+> smbd</B
+>. The <TT
+CLASS="REPLACEABLE"
+><I
+>aservice</I
+></TT
+> is
+ any service you have defined in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ file. Try your user name if you just have a [homes] section
+ in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.</P
+><P
+>For example if your unix host is bambi and your login
+ name is fred you would type:</P
+><P
+><TT
+CLASS="PROMPT"
+>$ </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbclient //bambi/fred
+ </B
+></TT
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN143"
+>Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT,
+ Win2k, OS/2, etc... client</A
+></H1
+><P
+>Try mounting disks. eg:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>net use d: \\servername\service
+ </B
+></TT
+></P
+><P
+>Try printing. eg:</P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>net use lpt1:
+ \\servername\spoolservice</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>C:\WINDOWS\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>print filename
+ </B
+></TT
+></P
+><P
+>Celebrate, or send me a bug report!</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN157"
+>What If Things Don't Work?</A
+></H1
+><P
+>If nothing works and you start to think "who wrote
+ this pile of trash" then I suggest you do step 2 again (and
+ again) till you calm down.</P
+><P
+>Then you might read the file DIAGNOSIS.txt and the
+ FAQ. If you are still stuck then try the mailing list or
+ newsgroup (look in the README for details). Samba has been
+ successfully installed at thousands of sites worldwide, so maybe
+ someone else has hit your problem and has overcome it. You could
+ also use the WWW site to scan back issues of the samba-digest.</P
+><P
+>When you fix the problem PLEASE send me some updates to the
+ documentation (or source code) so that the next person will find it
+ easier. </P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN162"
+>Diagnosing Problems</A
+></H2
+><P
+>If you have installation problems then go to
+ <TT
+CLASS="FILENAME"
+>DIAGNOSIS.txt</TT
+> to try to find the
+ problem.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN166"
+>Scope IDs</A
+></H2
+><P
+>By default Samba uses a blank scope ID. This means
+ all your windows boxes must also have a blank scope ID.
+ If you really want to use a non-blank scope ID then you will
+ need to use the 'netbios scope' smb.conf option.
+ All your PCs will need to have the same setting for
+ this to work. I do not recommend scope IDs.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN169"
+>Choosing the Protocol Level</A
+></H2
+><P
+>The SMB protocol has many dialects. Currently
+ Samba supports 5, called CORE, COREPLUS, LANMAN1,
+ LANMAN2 and NT1.</P
+><P
+>You can choose what maximum protocol to support
+ in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. The default is
+ NT1 and that is the best for the vast majority of sites.</P
+><P
+>In older versions of Samba you may have found it
+ necessary to use COREPLUS. The limitations that led to
+ this have mostly been fixed. It is now less likely that you
+ will want to use less than LANMAN1. The only remaining advantage
+ of COREPLUS is that for some obscure reason WfWg preserves
+ the case of passwords in this protocol, whereas under LANMAN1,
+ LANMAN2 or NT1 it uppercases all passwords before sending them,
+ forcing you to use the "password level=" option in some cases.</P
+><P
+>The main advantage of LANMAN2 and NT1 is support for
+ long filenames with some clients (eg: smbclient, Windows NT
+ or Win95). </P
+><P
+>See the smb.conf(5) manual page for more details.</P
+><P
+>Note: To support print queue reporting you may find
+ that you have to use TCP/IP as the default protocol under
+ WfWg. For some reason if you leave Netbeui as the default
+ it may break the print queue reporting on some systems.
+ It is presumably a WfWg bug.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN178"
+>Printing from UNIX to a Client PC</A
+></H2
+><P
+>To use a printer that is available via a smb-based
+ server from a unix host you will need to compile the
+ smbclient program. You then need to install the script
+ "smbprint". Read the instruction in smbprint for more details.
+ </P
+><P
+>There is also a SYSV style script that does much
+ the same thing called smbprint.sysv. It contains instructions.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN182"
+>Locking</A
+></H2
+><P
+>One area which sometimes causes trouble is locking.</P
+><P
+>There are two types of locking which need to be
+ performed by a SMB server. The first is "record locking"
+ which allows a client to lock a range of bytes in a open file.
+ The second is the "deny modes" that are specified when a file
+ is open.</P
+><P
+>Record locking semantics under Unix is very
+ different from record locking under Windows. Versions
+ of Samba before 2.2 have tried to use the native
+ fcntl() unix system call to implement proper record
+ locking between different Samba clients. This can not
+ be fully correct due to several reasons. The simplest
+ is the fact that a Windows client is allowed to lock a
+ byte range up to 2^32 or 2^64, depending on the client
+ OS. The unix locking only supports byte ranges up to
+ 2^31. So it is not possible to correctly satisfy a
+ lock request above 2^31. There are many more
+ differences, too many to be listed here.</P
+><P
+>Samba 2.2 and above implements record locking
+ completely independent of the underlying unix
+ system. If a byte range lock that the client requests
+ happens to fall into the range 0-2^31, Samba hands
+ this request down to the Unix system. All other locks
+ can not be seen by unix anyway.</P
+><P
+>Strictly a SMB server should check for locks before
+ every read and write call on a file. Unfortunately with the
+ way fcntl() works this can be slow and may overstress the
+ rpc.lockd. It is also almost always unnecessary as clients
+ are supposed to independently make locking calls before reads
+ and writes anyway if locking is important to them. By default
+ Samba only makes locking calls when explicitly asked
+ to by a client, but if you set "strict locking = yes" then it will
+ make lock checking calls on every read and write. </P
+><P
+>You can also disable by range locking completely
+ using "locking = no". This is useful for those shares that
+ don't support locking or don't need it (such as cdroms). In
+ this case Samba fakes the return codes of locking calls to
+ tell clients that everything is OK.</P
+><P
+>The second class of locking is the "deny modes". These
+ are set by an application when it opens a file to determine
+ what types of access should be allowed simultaneously with
+ its open. A client may ask for DENY_NONE, DENY_READ, DENY_WRITE
+ or DENY_ALL. There are also special compatibility modes called
+ DENY_FCB and DENY_DOS.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN191"
+>Mapping Usernames</A
+></H2
+><P
+>If you have different usernames on the PCs and
+ the unix server then take a look at the "username map" option.
+ See the smb.conf man page for details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN194"
+>Other Character Sets</A
+></H2
+><P
+>If you have problems using filenames with accented
+ characters in them (like the German, French or Scandinavian
+ character sets) then I recommend you look at the "valid chars"
+ option in smb.conf and also take a look at the validchars
+ package in the examples directory.</P
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/cups.html b/docs/htmldocs/cups.html
new file mode 100755
index 00000000000..c4191e25524
--- /dev/null
+++ b/docs/htmldocs/cups.html
@@ -0,0 +1,612 @@
+<HTML
+><HEAD
+><TITLE
+>Printing with CUPS in Samba 2.2.x</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="CUPS"
+>Printing with CUPS in Samba 2.2.x</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Printing with CUPS in Samba 2.2.x</A
+></H1
+><P
+><A
+HREF="http://www.cups.org/"
+TARGET="_top"
+>CUPS</A
+> is a newcomer in
+the UNIX printing scene, which has convinced many people upon first trial
+already. However, it has quite a few new features, which make it different
+from other, more traditional printing systems.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN7"
+>Configuring <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for CUPS</A
+></H1
+><P
+>Printing with CUPS in the most basic <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+setup in Samba 2.2.x only needs two settings: <B
+CLASS="COMMAND"
+>printing = cups</B
+> and
+<B
+CLASS="COMMAND"
+>printcap = cups</B
+>. While CUPS itself doesn't need a printcap
+anymore, the <TT
+CLASS="FILENAME"
+>cupsd.conf</TT
+> configuration file knows two directives
+(example: <B
+CLASS="COMMAND"
+>Printcap /etc/printcap</B
+> and <B
+CLASS="COMMAND"
+>PrintcapFormat
+BSD</B
+>), which control if such a file should be created for the
+convenience of third party applications. Make sure it is set! For details see
+<B
+CLASS="COMMAND"
+>man cupsd.conf</B
+> and other CUPS-related documentation.</P
+><P
+>If SAMBA is compiled against libcups, then <B
+CLASS="COMMAND"
+>printcap =
+cups</B
+> uses the CUPS API to list printers, submit jobs, etc. Otherwise it
+maps to the System V commands with an additional <TT
+CLASS="PARAMETER"
+><I
+>-oraw</I
+></TT
+>
+option for printing. On a Linux system, you can use the <B
+CLASS="COMMAND"
+>ldd</B
+> command to
+find out details (ldd may not be present on other OS platforms, or its
+function may be embodied by a different command):</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>transmeta:/home/kurt # ldd `which smbd`
+ libssl.so.0.9.6 =&#62; /usr/lib/libssl.so.0.9.6 (0x4002d000)
+ libcrypto.so.0.9.6 =&#62; /usr/lib/libcrypto.so.0.9.6 (0x4005a000)
+ libcups.so.2 =&#62; /usr/lib/libcups.so.2 (0x40123000)
+ libdl.so.2 =&#62; /lib/libdl.so.2 (0x401e8000)
+ libnsl.so.1 =&#62; /lib/libnsl.so.1 (0x401ec000)
+ libpam.so.0 =&#62; /lib/libpam.so.0 (0x40202000)
+ libc.so.6 =&#62; /lib/libc.so.6 (0x4020b000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x40000000)</PRE
+></P
+><P
+>The line "libcups.so.2 =&gt; /usr/lib/libcups.so.2
+(0x40123000)" shows there is CUPS support compiled into this version of
+Samba. If this is the case, and <B
+CLASS="COMMAND"
+>printing = cups</B
+> is set, then any
+otherwise manually set print command in smb.conf is ignored.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN26"
+>Using CUPS as a mere spooling print server -- "raw"
+printing with vendor drivers download</A
+></H1
+><P
+>You can setup Samba and your Windows clients to use the
+CUPS print subsystem just as you would with any of the more traditional print
+subsystems: that means the use of vendor provided, native Windows printer
+drivers for each target printer. If you setup the [print$] share to
+download these drivers to the clients, their GDI system (Graphical Device
+Interface) will output the Wndows EMF (Enhanced MetaFile) and
+convert it -- with the help of the printer driver -- locally into the format
+the printer is expecting. Samba and the CUPS print subsystem will have to
+treat these files as raw print files -- they are already in the
+shape to be digestable for the printer. This is the same traditional setup
+for Unix print servers handling Windows client jobs. It does not take much
+CPU power to handle this kind of task efficiently.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN29"
+>CUPS as a network PostScript RIP -- CUPS drivers working on server, Adobe
+PostScript driver with CUPS-PPDs downloaded to clients</A
+></H1
+><P
+>CUPS is perfectly able to use PPD files (PostScript
+Printer Descriptions). PPDs can control all print device options. They
+are usually provided by the manufacturer -- if you own a PostSript printer,
+that is. PPD files are always a component of PostScript printer drivers on MS
+Windows or Apple Mac OS systems. They are ASCII files containing
+user-selectable print options, mapped to appropriate PostScript, PCL or PJL
+commands for the target printer. Printer driver GUI dialogs translate these
+options "on-the-fly" into buttons and drop-down lists for the user to
+select.</P
+><P
+>CUPS can load, without any conversions, the PPD file from
+any Windows (NT is recommended) PostScript driver and handle the options.
+There is a web browser interface to the print options (select
+http://localhost:631/printers/ and click on one "Configure Printer" button
+to see it), a commandline interface (see <B
+CLASS="COMMAND"
+>man lpoptions</B
+> or
+try if you have <B
+CLASS="COMMAND"
+>lphelp</B
+> on your system) plus some different GUI frontends on Linux
+UNIX, which can present PPD options to the users. PPD options are normally
+meant to become evaluated by the PostScript RIP on the real PostScript
+printer.</P
+><P
+>CUPS doesn't stop at "real" PostScript printers in its
+usage of PPDs. The CUPS developers have extended the PPD concept, to also
+describe available device and driver options for non-PostScript printers
+through CUPS-PPDs.</P
+><P
+>This is logical, as CUPS includes a fully featured
+PostScript interpreter (RIP). This RIP is based on Ghostscript. It can
+process all received PostScript (and additionally many other file formats)
+from clients. All CUPS-PPDs geared to non-PostScript printers contain an
+additional line, starting with the keyword <TT
+CLASS="PARAMETER"
+><I
+>*cupsFilter</I
+></TT
+>.
+This line
+tells the CUPS print system which printer-specific filter to use for the
+interpretation of the accompanying PostScript. Thus CUPS lets all its
+printers appear as PostScript devices to its clients, because it can act as a
+PostScript RIP for those printers, processing the received PostScript code
+into a proper raster print format.</P
+><P
+>CUPS-PPDs can also be used on Windows-Clients, on top of a
+PostScript driver (recommended is the Adobe one).</P
+><P
+>This feature enables CUPS to do a few tricks no other
+spooler can do:</P
+><P
+></P
+><UL
+><LI
+><P
+>act as a networked PostScript RIP (Raster Image Processor), handling
+ printfiles from all client platforms in a uniform way;</P
+></LI
+><LI
+><P
+>act as a central accounting and billing server, as all files are passed
+ through the <B
+CLASS="COMMAND"
+>pstops</B
+> Filter and are therefor logged in
+ the CUPS <TT
+CLASS="FILENAME"
+>page&lowbar;log</TT
+>. - <I
+CLASS="EMPHASIS"
+>NOTE: </I
+>this
+ can not happen with "raw" print jobs, which always remain unfiltered
+ per definition;</P
+></LI
+><LI
+><P
+>enable clients to consolidate on a single PostScript driver, even for
+ many different target printers.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN50"
+>Windows Terminal Servers (WTS) as CUPS clients</A
+></H1
+><P
+>This setup may be of special interest to people
+experiencing major problems in WTS environments. WTS need often a multitude
+of non-PostScript drivers installed to run their clients' variety of
+different printer models. This often imposes the price of much increased
+instability. In many cases, in an attempt to overcome this problem, site
+administrators have resorted to restrict the allowed drivers installed on
+their WTS to one generic PCL- and one PostScript driver. This however
+restricts the clients in the amount of printer options available for them --
+often they can't get out more then simplex prints from one standard paper
+tray, while their devices could do much better, if driven by a different
+driver!</P
+><P
+>Using an Adobe PostScript driver, enabled with a CUPS-PPD,
+seems to be a very elegant way to overcome all these shortcomings. The
+PostScript driver is not known to cause major stability problems on WTS (even
+if used with many different PPDs). The clients will be able to (again) chose
+paper trays, duplex printing and other settings. However, there is a certain
+price for this too: a CUPS server acting as a PostScript RIP for its clients
+requires more CPU and RAM than just to act as a "raw spooling" device. Plus,
+this setup is not yet widely tested, although the first feedbacks look very
+promising...</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN54"
+>Setting up CUPS for driver download</A
+></H1
+><P
+>The <B
+CLASS="COMMAND"
+>cupsadsmb</B
+> utility (shipped with all current
+CUPS versions) makes the sharing of any (or all) installed CUPS printers very
+easy. Prior to using it, you need the following settings in smb.conf:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root</PRE
+></P
+><P
+>For licensing reasons the necessary files of the Adobe
+Postscript driver can not be distributed with either Samba or CUPS. You need
+to download them yourself from the Adobe website. Once extracted, create a
+<TT
+CLASS="FILENAME"
+>drivers</TT
+> directory in the CUPS data directory (usually
+<TT
+CLASS="FILENAME"
+>/usr/share/cups/</TT
+>). Copy the Adobe files using
+UPPERCASE filenames, to this directory as follows:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> ADFONTS.MFM
+ ADOBEPS4.DRV
+ ADOBEPS4.HLP
+ ADOBEPS5.DLL
+ ADOBEPSU.DLL
+ ADOBEPSU.HLP
+ DEFPRTR2.PPD
+ ICONLIB.DLL</PRE
+></P
+><P
+>Users of the ESP Print Pro software are able to install
+their "Samba Drivers" package for this purpose with no problem.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN66"
+>Sources of CUPS drivers / PPDs</A
+></H1
+><P
+>On the internet you can find now many thousand CUPS-PPD
+files (with their companion filters), in many national languages,
+supporting more than 1.000 non-PostScript models.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="http://wwwl.easysw.com/printpro/"
+TARGET="_top"
+>ESP PrintPro
+ (http://wwwl.easysw.com/printpro/)</A
+>
+ (commercial, non-Free) is packaged with more than 3.000 PPDs, ready for
+ successful usage "out of the box" on Linux, IBM-AIX, HP-UX, Sun-Solaris,
+ SGI-IRIX, Compaq Tru64, Digital Unix and some more commercial Unices (it
+ is written by the CUPS developers themselves and its sales help finance
+ the further development of CUPS, as they feed their creators)</P
+></LI
+><LI
+><P
+>the <A
+HREF="http://gimp-print.sourceforge.net/"
+TARGET="_top"
+>Gimp-Print-Project
+ (http://gimp-print.sourceforge.net/)</A
+>
+ (GPL, Free Software) provides around 120 PPDs (supporting nearly 300
+ printers, many driven to photo quality output), to be used alongside the
+ Gimp-Print CUPS filters;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www.turboprint.com/"
+TARGET="_top"
+>TurboPrint
+ (http://www.turboprint.com/)</A
+>
+ (Shareware, non-Freee) supports roughly the same amount of printers in
+ excellent quality;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www-124.ibm.com/developerworks/oss/linux/projects/omni/"
+TARGET="_top"
+>OMNI
+ (http://www-124.ibm.com/developerworks/oss/linux/projects/omni/)</A
+>
+ (LPGL, Free) is a package made by IBM, now containing support for more
+ than 400 printers, stemming from the inheritance of IBM OS/2 KnowHow
+ ported over to Linux (CUPS support is in a Beta-stage at present);</P
+></LI
+><LI
+><P
+><A
+HREF="http://hpinkjet.sourceforge.net/"
+TARGET="_top"
+>HPIJS
+ (http://hpinkjet.sourceforge.net/)</A
+>
+ (BSD-style licnes, Free) supports around 120 of HP's own printers and is
+ also providing excellent print quality now;</P
+></LI
+><LI
+><P
+><A
+HREF="http://www.linuxprinting.org/"
+TARGET="_top"
+>Foomatic/cupsomatic (http://www.linuxprinting.org/)</A
+>
+ (LPGL, Free) from Linuxprinting.org are providing PPDs for practically every
+ Ghostscript filter known to the world, now usable with CUPS.</P
+></LI
+></UL
+><P
+><I
+CLASS="EMPHASIS"
+>NOTE: </I
+>the cupsomatic trick from Linuxprinting.org is
+working different from the other drivers. While the other drivers take the
+generic CUPS raster (produced by CUPS' own pstoraster PostScript RIP) as
+their input, cupsomatic "kidnaps" the PostScript inside CUPS, before
+RIP-ping, deviates it to an external Ghostscript installation (which now
+becomes the RIP) and gives it back to a CUPS backend once Ghostscript is
+finished. -- CUPS versions from 1.1.15 and later will provide their pstoraster
+PostScript RIP function again inside a system-wide Ghostscript
+installation rather than in "their own" pstoraster filter. (This
+CUPS-enabling Ghostscript version may be installed either as a
+patch to GNU or AFPL Ghostscript, or as a complete ESP Ghostscript package).
+However, this will not change the cupsomatic approach of guiding the printjob
+along a different path through the filtering system than the standard CUPS
+way...</P
+><P
+>Once you installed a printer inside CUPS with one of the
+recommended methods (the lpadmin command, the web browser interface or one of
+the available GUI wizards), you can use <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> to share the
+printer via Samba. <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> prepares the driver files for
+comfortable client download and installation upon their first contact with
+this printer share.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN93"
+><B
+CLASS="COMMAND"
+>cupsaddsmb</B
+></A
+></H2
+><P
+>The <B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> command copies the needed files
+for convenient Windows client installations from the previously prepared CUPS
+data directory to your [print$] share. Additionally, the PPD
+associated with this printer is copied from <TT
+CLASS="FILENAME"
+>/etc/cups/ppd/</TT
+> to
+[print$].</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root# </TT
+> <B
+CLASS="COMMAND"
+>cupsaddsmb -U root infotec_IS2027</B
+>
+Password for root required to access localhost via SAMBA: <TT
+CLASS="USERINPUT"
+><B
+>[type in password 'secret']</B
+></TT
+></PRE
+></P
+><P
+>To share all printers and drivers, use the <TT
+CLASS="PARAMETER"
+><I
+>-a</I
+></TT
+>
+parameter instead of a printer name.</P
+><P
+>Probably you want to see what's going on. Use the
+<TT
+CLASS="PARAMETER"
+><I
+>-v</I
+></TT
+> parameter to get a more verbose output:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root# </TT
+> cupsaddsmb -v -U root infotec_IS2027
+ Password for root required to access localhost via SAMBA:
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir W32X86;put /var/spool/cups/tmp/3cd1cc66376c0 W32X86/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;put /usr/share/cups/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;put /usr/share/cups/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \W32X86
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \W32X86/infotec_IS2027.PPD (17394.6 kb/s) (average 17395.2 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS5.DLL as \W32X86/ADOBEPS5.DLL (10877.4 kb/s) (average 11343.0 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.DLL as \W32X86/ADOBEPSU.DLL (5095.2 kb/s) (average 9260.4 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPSU.HLP as \W32X86/ADOBEPSU.HLP (8828.7 kb/s) (average 9247.1 kb/s)
+
+ Running command: smbclient //localhost/print\$ -N -U'root%secret' -c 'mkdir WIN40;put /var/spool/cups/tmp/3cd1cc66376c0 WIN40/infotec_IS2027.PPD;put /usr/share/cups/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;put /usr/share/cups/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;put /usr/share/cups/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;put /usr/share/cups/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;put /usr/share/cups/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;put /usr/share/cups/drivers/PSMON.DLL WIN40/PSMON.DLL;'
+ added interface ip=10.160.16.45 bcast=10.160.31.255 nmask=255.255.240.0
+ added interface ip=192.168.182.1 bcast=192.168.182.255 nmask=255.255.255.0
+ added interface ip=172.16.200.1 bcast=172.16.200.255 nmask=255.255.255.0
+ Domain=[TUX-NET] OS=[Unix] Server=[Samba 2.2.3a.200204262025cvs]
+ NT_STATUS_OBJECT_NAME_COLLISION making remote directory \WIN40
+ putting file /var/spool/cups/tmp/3cd1cc66376c0 as \WIN40/infotec_IS2027.PPD (26091.5 kb/s) (average 26092.8 kb/s)
+ putting file /usr/share/cups/drivers/ADFONTS.MFM as \WIN40/ADFONTS.MFM (11241.6 kb/s) (average 11812.9 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.DRV as \WIN40/ADOBEPS4.DRV (16640.6 kb/s) (average 14679.3 kb/s)
+ putting file /usr/share/cups/drivers/ADOBEPS4.HLP as \WIN40/ADOBEPS4.HLP (11285.6 kb/s) (average 14281.5 kb/s)
+ putting file /usr/share/cups/drivers/DEFPRTR2.PPD as \WIN40/DEFPRTR2.PPD (823.5 kb/s) (average 12944.0 kb/s)
+ putting file /usr/share/cups/drivers/ICONLIB.DLL as \WIN40/ICONLIB.DLL (19226.2 kb/s) (average 13169.7 kb/s)
+ putting file /usr/share/cups/drivers/PSMON.DLL as \WIN40/PSMON.DLL (18666.1 kb/s) (average 13266.7 kb/s)
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"'
+ cmd = adddriver "Windows NT x86" "infotec_IS2027:ADOBEPS5.DLL:infotec_IS2027.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"'
+ cmd = adddriver "Windows 4.0" "infotec_IS2027:ADOBEPS4.DRV:infotec_IS2027.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL"
+ Printer Driver infotec_IS2027 successfully installed.
+
+ Running command: rpcclient localhost -N -U'root%secret' -c 'setdriver infotec_IS2027 infotec_IS2027'
+ cmd = setdriver infotec_IS2027 infotec_IS2027
+ Succesfully set infotec_IS2027 to driver infotec_IS2027.
+
+ <TT
+CLASS="PROMPT"
+>root# </TT
+></PRE
+></P
+><P
+>If you look closely, you'll discover your root password
+was transfered unencrypted over the wire, so beware! Also, if you look
+further her, you'll discover error messages like
+<TT
+CLASS="CONSTANT"
+>NT_STATUS_OBJECT_NAME_COLLISION</TT
+> in between. They occur, because
+the directories <TT
+CLASS="FILENAME"
+>WIN40</TT
+> and <TT
+CLASS="FILENAME"
+>W32X86</TT
+> already
+existed in the [print$] driver download share (from a previous driver
+installation). They are harmless here.</P
+><P
+>Now your printer is prepared for the clients to use. From
+a client, browse to the CUPS/Samba server, open the "Printers"
+share, right-click on this printer and select "Install..." or
+"Connect..." (depending on the Windows version you use). Now their
+should be a new printer in your client's local "Printers" folder,
+named (in my case) "infotec_IS2027 on kdebitshop"</P
+><P
+><I
+CLASS="EMPHASIS"
+>NOTE: </I
+>
+<B
+CLASS="COMMAND"
+>cupsaddsmb</B
+> will only reliably work i
+with CUPS version 1.1.15 or higher
+and Samba from 2.2.4. If it doesn't work, or if the automatic printer
+driver download to the clients doesn't succeed, you can still manually
+install the CUPS printer PPD on top of the Adobe PostScript driver on
+clients and then point the client's printer queue to the Samba printer
+share for connection, should you desire to use the CUPS networked
+PostScript RIP functions.</P
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/findsmb.1.html b/docs/htmldocs/findsmb.1.html
new file mode 100755
index 00000000000..2f246d666d8
--- /dev/null
+++ b/docs/htmldocs/findsmb.1.html
@@ -0,0 +1,267 @@
+<HTML
+><HEAD
+><TITLE
+>findsmb</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="FINDSMB"
+>findsmb</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>findsmb&nbsp;--&nbsp;list info about machines that respond to SMB
+ name queries on a subnet</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>findsmb</B
+> [subnet broadcast address]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN12"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This perl script is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>findsmb</B
+> is a perl script that
+ prints out several pieces of information about machines
+ on a subnet that respond to SMB name query requests.
+ It uses <A
+HREF="nmblookup.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> nmblookup(1)</B
+></A
+> and <A
+HREF="smbclient.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+> to obtain this information.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN22"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>subnet broadcast address</DT
+><DD
+><P
+>Without this option, <B
+CLASS="COMMAND"
+>findsmb
+ </B
+> will probe the subnet of the machine where
+ <B
+CLASS="COMMAND"
+>findsmb</B
+> is run. This value is passed
+ to <B
+CLASS="COMMAND"
+>nmblookup</B
+> as part of the
+ <TT
+CLASS="CONSTANT"
+>-B</TT
+> option</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN33"
+></A
+><H2
+>EXAMPLES</H2
+><P
+>The output of <B
+CLASS="COMMAND"
+>findsmb</B
+> lists the following
+ information for all machines that respond to the initial
+ <B
+CLASS="COMMAND"
+>nmblookup</B
+> for any name: IP address, NetBIOS name,
+ Workgroup name, operating system, and SMB server version.</P
+><P
+>There will be a '+' in front of the workgroup name for
+ machines that are local master browsers for that workgroup. There
+ will be an '*' in front of the workgroup name for
+ machines that are the domain master browser for that workgroup.
+ Machines that are running Windows, Windows 95 or Windows 98 will
+ not show any information about the operating system or server
+ version.</P
+><P
+>The command must be run on a system without <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd</B
+></A
+> running.
+ If <B
+CLASS="COMMAND"
+>nmbd</B
+> is running on the system, you will
+ only get the IP address and the DNS name of the machine. To
+ get proper responses from Windows 95 and Windows 98 machines,
+ the command must be run as root. </P
+><P
+>For example running <B
+CLASS="COMMAND"
+>findsmb</B
+> on a machine
+ without <B
+CLASS="COMMAND"
+>nmbd</B
+> running would yield output similar
+ to the following</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+><TT
+CLASS="COMPUTEROUTPUT"
+>IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION
+---------------------------------------------------------------------
+192.168.35.10 MINESET-TEST1 [DMVENGR]
+192.168.35.55 LINUXBOX *[MYGROUP] [Unix] [Samba 2.0.6]
+192.168.35.56 HERBNT2 [HERB-NT]
+192.168.35.63 GANDALF [MVENGR] [Unix] [Samba 2.0.5a for IRIX]
+192.168.35.65 SAUNA [WORKGROUP] [Unix] [Samba 1.9.18p10]
+192.168.35.71 FROGSTAR [ENGR] [Unix] [Samba 2.0.0 for IRIX]
+192.168.35.78 HERBDHCP1 +[HERB]
+192.168.35.88 SCNT2 +[MVENGR] [Windows NT 4.0] [NT LAN Manager 4.0]
+192.168.35.93 FROGSTAR-PC [MVENGR] [Windows 5.0] [Windows 2000 LAN Manager]
+192.168.35.97 HERBNT1 *[HERB-NT] [Windows NT 4.0] [NT LAN Manager 4.0]
+ </TT
+></PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN48"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN51"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+>,
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)
+ </B
+></A
+>, and <A
+HREF="nmblookup.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>nmblookup(1)</B
+></A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN60"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/lmhosts.5.html b/docs/htmldocs/lmhosts.5.html
new file mode 100755
index 00000000000..13b162ce44f
--- /dev/null
+++ b/docs/htmldocs/lmhosts.5.html
@@ -0,0 +1,214 @@
+<HTML
+><HEAD
+><TITLE
+>lmhosts</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="LMHOSTS"
+>lmhosts</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>lmhosts&nbsp;--&nbsp;The Samba NetBIOS hosts file</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><TT
+CLASS="FILENAME"
+>lmhosts</TT
+> is the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> NetBIOS name to IP address mapping file.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN12"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This file is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><TT
+CLASS="FILENAME"
+>lmhosts</TT
+> is the <EM
+>Samba
+ </EM
+> NetBIOS name to IP address mapping file. It
+ is very similar to the <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> file
+ format, except that the hostname component must correspond
+ to the NetBIOS naming format.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN20"
+></A
+><H2
+>FILE FORMAT</H2
+><P
+>It is an ASCII file containing one line for NetBIOS name.
+ The two fields on each line are separated from each other by
+ white space. Any entry beginning with '#' is ignored. Each line
+ in the lmhosts file contains the following information :</P
+><P
+></P
+><UL
+><LI
+><P
+>IP Address - in dotted decimal format.</P
+></LI
+><LI
+><P
+>NetBIOS Name - This name format is a
+ maximum fifteen character host name, with an optional
+ trailing '#' character followed by the NetBIOS name type
+ as two hexadecimal digits.</P
+><P
+>If the trailing '#' is omitted then the given IP
+ address will be returned for all names that match the given
+ name, whatever the NetBIOS name type in the lookup.</P
+></LI
+></UL
+><P
+>An example follows :</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#
+# Sample Samba lmhosts file.
+#
+192.9.200.1 TESTPC
+192.9.200.20 NTSERVER#20
+192.9.200.21 SAMBASERVER
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Contains three IP to NetBIOS name mappings. The first
+ and third will be returned for any queries for the names "TESTPC"
+ and "SAMBASERVER" respectively, whatever the type component of
+ the NetBIOS name requested.</P
+><P
+>The second mapping will be returned only when the "0x20" name
+ type for a name "NTSERVER" is queried. Any other name type will not
+ be resolved.</P
+><P
+>The default location of the <TT
+CLASS="FILENAME"
+>lmhosts</TT
+> file
+ is in the same directory as the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>
+ smb.conf(5)&#62;</A
+> file.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN37"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)
+ </B
+></A
+>, <A
+HREF="smb.conf.5.html#NAMERESOLVEORDER"
+TARGET="_top"
+> smb.conf(5)</A
+>, and <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> smbpasswd(8)</B
+></A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN48"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/make_smbcodepage.1.html b/docs/htmldocs/make_smbcodepage.1.html
new file mode 100755
index 00000000000..8e792e31221
--- /dev/null
+++ b/docs/htmldocs/make_smbcodepage.1.html
@@ -0,0 +1,354 @@
+<HTML
+><HEAD
+><TITLE
+>make_smbcodepage</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="MAKE-SMBCODEPAGE"
+>make_smbcodepage</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>make_smbcodepage&nbsp;--&nbsp;construct a codepage file for Samba</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>make_smbcodepage</B
+> {c|d} {codepage} {inputfile} {outputfile}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN15"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>make_smbcodepage</B
+> compiles or de-compiles
+ codepage files for use with the internationalization features
+ of Samba 2.2</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN21"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>c|d</DT
+><DD
+><P
+>This tells <B
+CLASS="COMMAND"
+>make_smbcodepage</B
+>
+ if it is compiling (<TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+>) a text format code
+ page file to binary, or (<TT
+CLASS="PARAMETER"
+><I
+>d</I
+></TT
+>) de-compiling
+ a binary codepage file to text. </P
+></DD
+><DT
+>codepage</DT
+><DD
+><P
+>This is the codepage we are processing (a
+ number, e.g. 850). </P
+></DD
+><DT
+>inputfile</DT
+><DD
+><P
+>This is the input file to process. In
+ the <TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> case this will be a text
+ codepage definition file such as the ones found in the Samba
+ <TT
+CLASS="FILENAME"
+>source/codepages</TT
+> directory. In
+ the <TT
+CLASS="PARAMETER"
+><I
+>d</I
+></TT
+> case this will be the
+ binary format codepage definition file normally found in
+ the <TT
+CLASS="FILENAME"
+>lib/codepages</TT
+> directory in the
+ Samba install directory path.</P
+></DD
+><DT
+>outputfile</DT
+><DD
+><P
+>This is the output file to produce.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN47"
+></A
+><H2
+>Samba Codepage Files</H2
+><P
+>A text Samba codepage definition file is a description
+ that tells Samba how to map from upper to lower case for
+ characters greater than ascii 127 in the specified DOS code page.
+ Note that for certain DOS codepages (437 for example) mapping
+ from lower to upper case may be non-symmetrical. For example, in
+ code page 437 lower case a acute maps to a plain upper case A
+ when going from lower to upper case, but plain upper case A maps
+ to plain lower case a when lower casing a character. </P
+><P
+>A binary Samba codepage definition file is a binary
+ representation of the same information, including a value that
+ specifies what codepage this file is describing. </P
+><P
+>As Samba does not yet use UNICODE (current for Samba version 2.2)
+ you must specify the client code page that your DOS and Windows
+ clients are using if you wish to have case insensitivity done
+ correctly for your particular language. The default codepage Samba
+ uses is 850 (Western European). Text codepage definition sample files
+ are provided in the Samba distribution for codepages 437 (USA), 737 (Greek),
+ 850 (Western European) 852 (MS-DOS Latin 2), 861 (Icelandic), 866 (Cyrillic),
+ 932 (Kanji SJIS), 936 (Simplified Chinese), 949 (Hangul) and 950 (Traditional
+ Chinese). Users are encouraged to write text codepage definition files for
+ their own code pages and donate them to samba@samba.org. All codepage files
+ in the Samba <TT
+CLASS="FILENAME"
+>source/codepages</TT
+> directory are
+ compiled and installed when a <B
+CLASS="COMMAND"
+>'make install'</B
+>
+ command is issued there. </P
+><P
+>The client codepage used by the <B
+CLASS="COMMAND"
+>smbd</B
+> server
+ is configured using the <B
+CLASS="COMMAND"
+>client code page</B
+> parameter
+ in the <B
+CLASS="COMMAND"
+>smb.conf</B
+> file. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN58"
+></A
+><H2
+>Files</H2
+><P
+><B
+CLASS="COMMAND"
+>codepage_def.&#60;codepage&#62;</B
+></P
+><P
+>These are the input (text) codepage files provided in the
+ Samba <TT
+CLASS="FILENAME"
+>source/codepages</TT
+> directory.</P
+><P
+>A text codepage definition file consists of multiple lines
+ containing four fields. These fields are:</P
+><P
+></P
+><UL
+><LI
+><P
+><B
+CLASS="COMMAND"
+>lower</B
+>: which is the
+ (hex) lower case character mapped on this line.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>upper</B
+>: which is the (hex)
+ upper case character that the lower case character will map to.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>map upper to lower</B
+> which
+ is a boolean value (put either True or False here) which tells
+ Samba if it is to map the given upper case character to the
+ given lower case character when lower casing a filename.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>map lower to upper</B
+> which
+ is a boolean value (put either True or False here) which tells
+ Samba if it is to map the given lower case character to the
+ given upper case character when upper casing a filename.
+ </P
+></LI
+></UL
+><P
+><B
+CLASS="COMMAND"
+>codepage.&#60;codepage&#62;</B
+> - These are the
+ output (binary) codepage files produced and placed in the Samba
+ destination <TT
+CLASS="FILENAME"
+>lib/codepage</TT
+> directory. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN81"
+></A
+><H2
+>Installation</H2
+><P
+>The location of the server and its support files is a
+ matter for individual system administrators. The following are
+ thus suggestions only. </P
+><P
+>It is recommended that the <B
+CLASS="COMMAND"
+>make_smbcodepage
+ </B
+> program be installed under the <TT
+CLASS="FILENAME"
+>/usr/local/samba
+ </TT
+> hierarchy, in a directory readable by all, writeable
+ only by root. The program itself should be executable by all. The
+ program should NOT be setuid or setgid! </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN87"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN90"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN96"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/make_unicodemap.1.html b/docs/htmldocs/make_unicodemap.1.html
new file mode 100755
index 00000000000..b8b768ce40d
--- /dev/null
+++ b/docs/htmldocs/make_unicodemap.1.html
@@ -0,0 +1,276 @@
+<HTML
+><HEAD
+><TITLE
+>make_unicodemap</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="MAKE-UNICODEMAP"
+>make_unicodemap</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>make_unicodemap&nbsp;--&nbsp;construct a unicode map file for Samba</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>make_unicodemap</B
+> {codepage} {inputfile} {outputfile}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN14"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+> This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+>Samba</A
+>
+ suite.
+ </P
+><P
+> <B
+CLASS="COMMAND"
+>make_unicodemap</B
+> compiles text unicode map
+ files into binary unicode map files for use with the
+ internationalization features of Samba 2.2.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN20"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>codepage</DT
+><DD
+><P
+>This is the codepage or UNIX character
+ set we are processing (a number, e.g. 850).
+ </P
+></DD
+><DT
+>inputfile</DT
+><DD
+><P
+>This is the input file to process. This is a
+ text unicode map file such as the ones found in the Samba
+ <TT
+CLASS="FILENAME"
+>source/codepages</TT
+> directory.
+ </P
+></DD
+><DT
+>outputfile</DT
+><DD
+><P
+>This is the binary output file to produce.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN36"
+></A
+><H2
+>Samba Unicode Map Files</H2
+><P
+> A text Samba unicode map file is a description that tells Samba
+ how to map characters from a specified DOS code page or UNIX character
+ set to 16 bit unicode.
+ </P
+><P
+>A binary Samba unicode map file is a binary representation
+ of the same information, including a value that specifies what
+ codepage or UNIX character set this file is describing.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>Files</H2
+><P
+><TT
+CLASS="FILENAME"
+>CP&#60;codepage&#62;.TXT</TT
+></P
+><P
+> These are the input (text) unicode map files provided
+ in the Samba <TT
+CLASS="FILENAME"
+>source/codepages</TT
+>
+ directory.
+ </P
+><P
+> A text unicode map file consists of multiple lines
+ containing two fields. These fields are :
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>character</I
+></TT
+> - which is
+ the (hex) character mapped on this line.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>unicode</I
+></TT
+> - which
+ is the (hex) 16 bit unicode character that the character
+ will map to.
+ </P
+></LI
+></UL
+><P
+> <TT
+CLASS="FILENAME"
+>unicode_map.&#60;codepage&#62;</TT
+> - These are
+ the output (binary) unicode map files produced and placed in
+ the Samba destination <TT
+CLASS="FILENAME"
+>lib/codepage</TT
+>
+ directory.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>Installation</H2
+><P
+> The location of the server and its support files is a matter
+ for individual system administrators. The following are thus
+ suggestions only.
+ </P
+><P
+> It is recommended that the <B
+CLASS="COMMAND"
+>make_unicodemap</B
+>
+ program be installed under the
+ <TT
+CLASS="FILENAME"
+>$prefix/samba</TT
+> hierarchy,
+ in a directory readable by all, writeable only by root. The
+ program itself should be executable by all. The program
+ should NOT be setuid or setgid!
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN63"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN66"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN72"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/msdfs_setup.html b/docs/htmldocs/msdfs_setup.html
new file mode 100755
index 00000000000..36b9911baec
--- /dev/null
+++ b/docs/htmldocs/msdfs_setup.html
@@ -0,0 +1,210 @@
+<HTML
+><HEAD
+><TITLE
+>Hosting a Microsoft Distributed File System tree on Samba</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="MSDFS"
+>Hosting a Microsoft Distributed File System tree on Samba</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Instructions</A
+></H1
+><P
+>The Distributed File System (or Dfs) provides a means of
+ separating the logical view of files and directories that users
+ see from the actual physical locations of these resources on the
+ network. It allows for higher availability, smoother storage expansion,
+ load balancing etc. For more information about Dfs, refer to <A
+HREF="http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp"
+TARGET="_top"
+> Microsoft documentation</A
+>. </P
+><P
+>This document explains how to host a Dfs tree on a Unix
+ machine (for Dfs-aware clients to browse) using Samba.</P
+><P
+>To enable SMB-based DFS for Samba, configure it with the
+ <TT
+CLASS="PARAMETER"
+><I
+>--with-msdfs</I
+></TT
+> option. Once built, a
+ Samba server can be made a Dfs server by setting the global
+ boolean <A
+HREF="smb.conf.5.html#HOSTMSDFS"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> host msdfs</I
+></TT
+></A
+> parameter in the <TT
+CLASS="FILENAME"
+>smb.conf
+ </TT
+> file. You designate a share as a Dfs root using the share
+ level boolean <A
+HREF="smb.conf.5.html#MSDFSROOT"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> msdfs root</I
+></TT
+></A
+> parameter. A Dfs root directory on
+ Samba hosts Dfs links in the form of symbolic links that point
+ to other servers. For example, a symbolic link
+ <TT
+CLASS="FILENAME"
+>junction-&gt;msdfs:storage1\share1</TT
+> in
+ the share directory acts as the Dfs junction. When Dfs-aware
+ clients attempt to access the junction link, they are redirected
+ to the storage location (in this case, \\storage1\share1).</P
+><P
+>Dfs trees on Samba work with all Dfs-aware clients ranging
+ from Windows 95 to 2000.</P
+><P
+>Here's an example of setting up a Dfs tree on a Samba
+ server.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+># The smb.conf file:
+[global]
+ netbios name = SAMBA
+ host msdfs = yes
+
+[dfs]
+ path = /export/dfsroot
+ msdfs root = yes
+ </PRE
+></P
+><P
+>In the /export/dfsroot directory we set up our dfs links to
+ other servers on the network.</P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>cd /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>chown root /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>chmod 755 /export/dfsroot</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>ln -s msdfs:storageA\\shareA linka</B
+></TT
+></P
+><P
+><TT
+CLASS="PROMPT"
+>root# </TT
+><TT
+CLASS="USERINPUT"
+><B
+>ln -s msdfs:serverB\\share,serverC\\share linkb</B
+></TT
+></P
+><P
+>You should set up the permissions and ownership of
+ the directory acting as the Dfs root such that only designated
+ users can create, delete or modify the msdfs links. Also note
+ that symlink names should be all lowercase. This limitation exists
+ to have Samba avoid trying all the case combinations to get at
+ the link name. Finally set up the symbolic links to point to the
+ network shares you want, and start Samba.</P
+><P
+>Users on Dfs-aware clients can now browse the Dfs tree
+ on the Samba server at \\samba\dfs. Accessing
+ links linka or linkb (which appear as directories to the client)
+ takes users directly to the appropriate shares on the network.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN38"
+>Notes</A
+></H2
+><P
+></P
+><UL
+><LI
+><P
+>Windows clients need to be rebooted
+ if a previously mounted non-dfs share is made a dfs
+ root or vice versa. A better way is to introduce a
+ new share and make it the dfs root.</P
+></LI
+><LI
+><P
+>Currently there's a restriction that msdfs
+ symlink names should all be lowercase.</P
+></LI
+><LI
+><P
+>For security purposes, the directory
+ acting as the root of the Dfs tree should have ownership
+ and permissions set so that only designated users can
+ modify the symbolic links in the directory.</P
+></LI
+></UL
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/nmbd.8.html b/docs/htmldocs/nmbd.8.html
new file mode 100755
index 00000000000..828ebb13a42
--- /dev/null
+++ b/docs/htmldocs/nmbd.8.html
@@ -0,0 +1,717 @@
+<HTML
+><HEAD
+><TITLE
+>nmbd</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="NMBD"
+>nmbd</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>nmbd&nbsp;--&nbsp;NetBIOS name server to provide NetBIOS
+ over IP naming services to clients</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> [-D] [-a] [-i] [-o] [-P] [-h] [-V] [-d &#60;debug level&#62;] [-H &#60;lmhosts file&#62;] [-l &#60;log directory&#62;] [-n &#60;primary netbios name&#62;] [-p &#60;port number&#62;] [-s &#60;configuration file&#62;]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN24"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This program is part of the Samba suite.</P
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> is a server that understands
+ and can reply to NetBIOS over IP name service requests, like
+ those produced by SMB/CIFS clients such as Windows 95/98/ME,
+ Windows NT, Windows 2000, and LanManager clients. It also
+ participates in the browsing protocols which make up the
+ Windows "Network Neighborhood" view.</P
+><P
+>SMB/CIFS clients, when they start up, may wish to
+ locate an SMB/CIFS server. That is, they wish to know what
+ IP number a specified host is using.</P
+><P
+>Amongst other services, <B
+CLASS="COMMAND"
+>nmbd</B
+> will
+ listen for such requests, and if its own NetBIOS name is
+ specified it will respond with the IP number of the host it
+ is running on. Its "own NetBIOS name" is by
+ default the primary DNS name of the host it is running on,
+ but this can be overridden with the <EM
+>-n</EM
+>
+ option (see OPTIONS below). Thus <B
+CLASS="COMMAND"
+>nmbd</B
+> will
+ reply to broadcast queries for its own name(s). Additional
+ names for <B
+CLASS="COMMAND"
+>nmbd</B
+> to respond on can be set
+ via parameters in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+></A
+> configuration file.</P
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> can also be used as a WINS
+ (Windows Internet Name Server) server. What this basically means
+ is that it will act as a WINS database server, creating a
+ database from name registration requests that it receives and
+ replying to queries from clients for these names.</P
+><P
+>In addition, <B
+CLASS="COMMAND"
+>nmbd</B
+> can act as a WINS
+ proxy, relaying broadcast queries from clients that do
+ not understand how to talk the WINS protocol to a WIN
+ server.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN41"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-D</DT
+><DD
+><P
+>If specified, this parameter causes
+ <B
+CLASS="COMMAND"
+>nmbd</B
+> to operate as a daemon. That is,
+ it detaches itself and runs in the background, fielding
+ requests on the appropriate port. By default, <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will operate as a daemon if launched from a command shell.
+ nmbd can also be operated from the <B
+CLASS="COMMAND"
+>inetd</B
+>
+ meta-daemon, although this is not recommended.
+ </P
+></DD
+><DT
+>-a</DT
+><DD
+><P
+>If this parameter is specified, each new
+ connection will append log messages to the log file.
+ This is the default.</P
+></DD
+><DT
+>-i</DT
+><DD
+><P
+>If this parameter is specified it causes the
+ server to run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell. Setting this
+ parameter negates the implicit deamon mode when run from the
+ command line.
+ </P
+></DD
+><DT
+>-o</DT
+><DD
+><P
+>If this parameter is specified, the
+ log files will be overwritten when opened. By default,
+ <B
+CLASS="COMMAND"
+>smbd</B
+> will append entries to the log
+ files.</P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Prints the help information (usage)
+ for <B
+CLASS="COMMAND"
+>nmbd</B
+>.</P
+></DD
+><DT
+>-H &#60;filename&#62;</DT
+><DD
+><P
+>NetBIOS lmhosts file. The lmhosts
+ file is a list of NetBIOS names to IP addresses that
+ is loaded by the nmbd server and used via the name
+ resolution mechanism <A
+HREF="smb.conf.5.html#nameresolveorder"
+TARGET="_top"
+> name resolve order</A
+> described in <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+>
+ to resolve any NetBIOS name queries needed by the server. Note
+ that the contents of this file are <EM
+>NOT</EM
+>
+ used by <B
+CLASS="COMMAND"
+>nmbd</B
+> to answer any name queries.
+ Adding a line to this file affects name NetBIOS resolution
+ from this host <EM
+>ONLY</EM
+>.</P
+><P
+>The default path to this file is compiled into
+ Samba as part of the build process. Common defaults
+ are <TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/lmhosts</TT
+>,
+ <TT
+CLASS="FILENAME"
+>/usr/samba/lib/lmhosts</TT
+> or
+ <TT
+CLASS="FILENAME"
+>/etc/lmhosts</TT
+>. See the <A
+HREF="lmhosts.5.html"
+TARGET="_top"
+> <TT
+CLASS="FILENAME"
+>lmhosts(5)</TT
+></A
+> man page for details on the
+ contents of this file.</P
+></DD
+><DT
+>-V</DT
+><DD
+><P
+>Prints the version number for
+ <B
+CLASS="COMMAND"
+>nmbd</B
+>.</P
+></DD
+><DT
+>-d &#60;debug level&#62;</DT
+><DD
+><P
+>debuglevel is an integer
+ from 0 to 10. The default value if this parameter is
+ not specified is zero.</P
+><P
+>The higher this value, the more detail will
+ be logged to the log files about the activities of the
+ server. At level 0, only critical errors and serious
+ warnings will be logged. Level 1 is a reasonable level for
+ day to day running - it generates a small amount of
+ information about operations carried out.</P
+><P
+>Levels above 1 will generate considerable amounts
+ of log data, and should only be used when investigating
+ a problem. Levels above 3 are designed for use only by developers
+ and generate HUGE amounts of log data, most of which is extremely
+ cryptic.</P
+><P
+>Note that specifying this parameter here will override
+ the <A
+HREF="smb.conf.5.html#loglevel"
+TARGET="_top"
+>log level</A
+>
+ parameter in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+> smb.conf</TT
+></A
+> file.</P
+></DD
+><DT
+>-l &#60;log directory&#62;</DT
+><DD
+><P
+>The -l parameter specifies a directory
+ into which the "log.nmbd" log file will be created
+ for operational data from the running
+ <B
+CLASS="COMMAND"
+>nmbd</B
+> server. The default log directory is compiled into Samba
+ as part of the build process. Common defaults are <TT
+CLASS="FILENAME"
+> /usr/local/samba/var/log.nmb</TT
+>, <TT
+CLASS="FILENAME"
+> /usr/samba/var/log.nmb</TT
+> or
+ <TT
+CLASS="FILENAME"
+>/var/log/log.nmb</TT
+>. <EM
+>Beware:</EM
+>
+ If the directory specified does not exist, <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will log to the default debug log location defined at compile time.
+ </P
+></DD
+><DT
+>-n &#60;primary NetBIOS name&#62;</DT
+><DD
+><P
+>This option allows you to override
+ the NetBIOS name that Samba uses for itself. This is identical
+ to setting the <A
+HREF="smb.conf.5.html#netbiosname"
+TARGET="_top"
+> NetBIOS name</A
+> parameter in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+> file. However, a command
+ line setting will take precedence over settings in
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.</P
+></DD
+><DT
+>-p &#60;UDP port number&#62;</DT
+><DD
+><P
+>UDP port number is a positive integer value.
+ This option changes the default UDP port number (normally 137)
+ that <B
+CLASS="COMMAND"
+>nmbd</B
+> responds to name queries on. Don't
+ use this option unless you are an expert, in which case you
+ won't need help!</P
+></DD
+><DT
+>-s &#60;configuration file&#62;</DT
+><DD
+><P
+>The default configuration file name
+ is set at build time, typically as <TT
+CLASS="FILENAME"
+> /usr/local/samba/lib/smb.conf</TT
+>, but
+ this may be changed when Samba is autoconfigured.</P
+><P
+>The file specified contains the configuration details
+ required by the server. See <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+> for more information.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN131"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+></DT
+><DD
+><P
+>If the server is to be run by the
+ <B
+CLASS="COMMAND"
+>inetd</B
+> meta-daemon, this file
+ must contain suitable startup information for the
+ meta-daemon. See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+> document
+ for details.
+ </P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/rc</TT
+></DT
+><DD
+><P
+>or whatever initialization script your
+ system uses).</P
+><P
+>If running the server as a daemon at startup,
+ this file will need to contain an appropriate startup
+ sequence for the server. See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+> document
+ for details.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/services</TT
+></DT
+><DD
+><P
+>If running the server via the
+ meta-daemon <B
+CLASS="COMMAND"
+>inetd</B
+>, this file
+ must contain a mapping of service name (e.g., netbios-ssn)
+ to service port (e.g., 139) and protocol type (e.g., tcp).
+ See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+>
+ document for details.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/smb.conf</TT
+></DT
+><DD
+><P
+>This is the default location of the
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+>
+ server configuration file. Other common places that systems
+ install this file are <TT
+CLASS="FILENAME"
+>/usr/samba/lib/smb.conf</TT
+>
+ and <TT
+CLASS="FILENAME"
+>/etc/smb.conf</TT
+>.</P
+><P
+>When run as a WINS server (see the
+ <A
+HREF="smb.conf.5.html#WINSSUPPORT"
+TARGET="_top"
+>wins support</A
+>
+ parameter in the <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> man page),
+ <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will store the WINS database in the file <TT
+CLASS="FILENAME"
+>wins.dat</TT
+>
+ in the <TT
+CLASS="FILENAME"
+>var/locks</TT
+> directory configured under
+ wherever Samba was configured to install itself.</P
+><P
+>If <B
+CLASS="COMMAND"
+>nmbd</B
+> is acting as a <EM
+> browse master</EM
+> (see the <A
+HREF="smb.conf.5.html#LOCALMASTER"
+TARGET="_top"
+>local master</A
+>
+ parameter in the <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> man page,
+ <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will store the browsing database in the file <TT
+CLASS="FILENAME"
+>browse.dat
+ </TT
+> in the <TT
+CLASS="FILENAME"
+>var/locks</TT
+> directory
+ configured under wherever Samba was configured to install itself.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN178"
+></A
+><H2
+>SIGNALS</H2
+><P
+>To shut down an <B
+CLASS="COMMAND"
+>nmbd</B
+> process it is recommended
+ that SIGKILL (-9) <EM
+>NOT</EM
+> be used, except as a last
+ resort, as this may leave the name database in an inconsistent state.
+ The correct way to terminate <B
+CLASS="COMMAND"
+>nmbd</B
+> is to send it
+ a SIGTERM (-15) signal and wait for it to die on its own.</P
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> will accept SIGHUP, which will cause
+ it to dump out its namelists into the file <TT
+CLASS="FILENAME"
+>namelist.debug
+ </TT
+> in the <TT
+CLASS="FILENAME"
+>/usr/local/samba/var/locks</TT
+>
+ directory (or the <TT
+CLASS="FILENAME"
+>var/locks</TT
+> directory configured
+ under wherever Samba was configured to install itself). This will also
+ cause <B
+CLASS="COMMAND"
+>nmbd</B
+> to dump out its server database in
+ the <TT
+CLASS="FILENAME"
+>log.nmb</TT
+> file.</P
+><P
+>The debug log level of nmbd may be raised or lowered using
+ <A
+HREF="smbcontrol.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbcontrol(1)</B
+>
+ </A
+> (SIGUSR[1|2] signals are no longer used in Samba 2.2). This is
+ to allow transient problems to be diagnosed, whilst still running
+ at a normally low log level.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN194"
+></A
+><H2
+>TROUBLESHOOTING</H2
+><P
+> One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN197"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN200"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><B
+CLASS="COMMAND"
+>inetd(8)</B
+>, <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ </A
+>, <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)
+ </B
+></A
+>, <A
+HREF="testparm.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> testparm(1)</B
+></A
+>, <A
+HREF="testprns.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>testprns(1)</B
+></A
+>, and the Internet RFC's
+ <TT
+CLASS="FILENAME"
+>rfc1001.txt</TT
+>, <TT
+CLASS="FILENAME"
+>rfc1002.txt</TT
+>.
+ In addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page <A
+HREF="http://samba.org/cifs/"
+TARGET="_top"
+>
+ http://samba.org/cifs/</A
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN217"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/nmblookup.1.html b/docs/htmldocs/nmblookup.1.html
new file mode 100755
index 00000000000..22cc35526cc
--- /dev/null
+++ b/docs/htmldocs/nmblookup.1.html
@@ -0,0 +1,403 @@
+<HTML
+><HEAD
+><TITLE
+>nmblookup</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="NMBLOOKUP"
+>nmblookup</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>nmblookup&nbsp;--&nbsp;NetBIOS over TCP/IP client used to lookup NetBIOS
+ names</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>nmblookup</B
+> [-f] [-M] [-R] [-S] [-r] [-A] [-h] [-B &#60;broadcast address&#62;] [-U &#60;unicast address&#62;] [-d &#60;debug level&#62;] [-s &#60;smb config file&#62;] [-i &#60;NetBIOS scope&#62;] [-T] {name}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN25"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>nmblookup</B
+> is used to query NetBIOS names
+ and map them to IP addresses in a network using NetBIOS over TCP/IP
+ queries. The options allow the name queries to be directed at a
+ particular IP broadcast area or to a particular machine. All queries
+ are done over UDP.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN31"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-f</DT
+><DD
+><P
+>Causes nmblookup to print out the flags
+ in the NMB packet headers. These flags will print out as
+ strings like Authoritative, Recursion_Desired, Recursion_available, etc.
+ </P
+></DD
+><DT
+>-M</DT
+><DD
+><P
+>Searches for a master browser by looking
+ up the NetBIOS name <TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+> with a
+ type of <TT
+CLASS="CONSTANT"
+>0x1d</TT
+>. If <TT
+CLASS="REPLACEABLE"
+><I
+> name</I
+></TT
+> is "-" then it does a lookup on the special name
+ <TT
+CLASS="CONSTANT"
+>__MSBROWSE__</TT
+>.</P
+></DD
+><DT
+>-R</DT
+><DD
+><P
+>Set the recursion desired bit in the packet
+ to do a recursive lookup. This is used when sending a name
+ query to a machine running a WINS server and the user wishes
+ to query the names in the WINS server. If this bit is unset
+ the normal (broadcast responding) NetBIOS processing code
+ on a machine is used instead. See rfc1001, rfc1002 for details.
+ </P
+></DD
+><DT
+>-S</DT
+><DD
+><P
+>Once the name query has returned an IP
+ address then do a node status query as well. A node status
+ query returns the NetBIOS names registered by a host.
+ </P
+></DD
+><DT
+>-r</DT
+><DD
+><P
+>Try and bind to UDP port 137 to send and receive UDP
+ datagrams. The reason for this option is a bug in Windows 95
+ where it ignores the source port of the requesting packet
+ and only replies to UDP port 137. Unfortunately, on most UNIX
+ systems root privilege is needed to bind to this port, and
+ in addition, if the <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ daemon is running on this machine it also binds to this port.
+ </P
+></DD
+><DT
+>-A</DT
+><DD
+><P
+>Interpret <TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+> as
+ an IP Address and do a node status query on this address.</P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Print a help (usage) message.</P
+></DD
+><DT
+>-B &#60;broadcast address&#62;</DT
+><DD
+><P
+>Send the query to the given broadcast address. Without
+ this option the default behavior of nmblookup is to send the
+ query to the broadcast address of the network interfaces as
+ either auto-detected or defined in the <A
+HREF="smb.conf.5.html#INTERFACES"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+>
+ </A
+> parameter of the <TT
+CLASS="FILENAME"
+>smb.conf (5)</TT
+> file.
+ </P
+></DD
+><DT
+>-U &#60;unicast address&#62;</DT
+><DD
+><P
+>Do a unicast query to the specified address or
+ host <TT
+CLASS="REPLACEABLE"
+><I
+>unicast address</I
+></TT
+>. This option
+ (along with the <TT
+CLASS="PARAMETER"
+><I
+>-R</I
+></TT
+> option) is needed to
+ query a WINS server.</P
+></DD
+><DT
+>-d &#60;debuglevel&#62;</DT
+><DD
+><P
+>debuglevel is an integer from 0 to 10.</P
+><P
+>The default value if this parameter is not specified
+ is zero.</P
+><P
+>The higher this value, the more detail will be logged
+ about the activities of <B
+CLASS="COMMAND"
+>nmblookup</B
+>. At level
+ 0, only critical errors and serious warnings will be logged.</P
+><P
+>Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a problem.
+ Levels above 3 are designed for use only by developers and
+ generate HUGE amounts of data, most of which is extremely cryptic.</P
+><P
+>Note that specifying this parameter here will override
+ the <A
+HREF="smb.conf.5.html#LOGLEVEL"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+> log level</I
+></TT
+></A
+> parameter in the <TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+> file.</P
+></DD
+><DT
+>-s &#60;smb.conf&#62;</DT
+><DD
+><P
+>This parameter specifies the pathname to
+ the Samba configuration file, <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> smb.conf(5)</A
+>. This file controls all aspects of
+ the Samba setup on the machine.</P
+></DD
+><DT
+>-i &#60;scope&#62;</DT
+><DD
+><P
+>This specifies a NetBIOS scope that
+ <B
+CLASS="COMMAND"
+>nmblookup</B
+> will use to communicate with when
+ generating NetBIOS names. For details on the use of NetBIOS
+ scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes are
+ <EM
+>very</EM
+> rarely used, only set this parameter
+ if you are the system administrator in charge of all the
+ NetBIOS systems you communicate with.</P
+></DD
+><DT
+>-T</DT
+><DD
+><P
+>This causes any IP addresses found in the
+ lookup to be looked up via a reverse DNS lookup into a
+ DNS name, and printed out before each</P
+><P
+><EM
+>IP address .... NetBIOS name</EM
+></P
+><P
+> pair that is the normal output.</P
+></DD
+><DT
+>name</DT
+><DD
+><P
+>This is the NetBIOS name being queried. Depending
+ upon the previous options this may be a NetBIOS name or IP address.
+ If a NetBIOS name then the different name types may be specified
+ by appending '#&#60;type&#62;' to the name. This name may also be
+ '*', which will return all registered names within a broadcast
+ area.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN115"
+></A
+><H2
+>EXAMPLES</H2
+><P
+><B
+CLASS="COMMAND"
+>nmblookup</B
+> can be used to query
+ a WINS server (in the same way <B
+CLASS="COMMAND"
+>nslookup</B
+> is
+ used to query DNS servers). To query a WINS server,
+ <B
+CLASS="COMMAND"
+>nmblookup</B
+> must be called like this:</P
+><P
+><B
+CLASS="COMMAND"
+>nmblookup -U server -R 'name'</B
+></P
+><P
+>For example, running :</P
+><P
+><B
+CLASS="COMMAND"
+>nmblookup -U samba.org -R 'IRIX#1B'</B
+></P
+><P
+>would query the WINS server samba.org for the domain
+ master browser (1B name type) for the IRIX workgroup.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN127"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+>,
+ <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>, and <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN137"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/pdbedit.8.html b/docs/htmldocs/pdbedit.8.html
new file mode 100755
index 00000000000..9609664af05
--- /dev/null
+++ b/docs/htmldocs/pdbedit.8.html
@@ -0,0 +1,426 @@
+<HTML
+><HEAD
+><TITLE
+>pdbedit</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="PDBEDIT"
+>pdbedit</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>pdbedit&nbsp;--&nbsp;manage the SAM database</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>pdbedit</B
+> [-l] [-v] [-w] [-u username] [-f fullname] [-h homedir] [-d drive] [-s script] [-p profile] [-a] [-m] [-x] [-i file]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN24"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>The pdbedit program is used to manage the users accounts
+ stored in the sam database and can be run only by root.</P
+><P
+>The pdbedit tool use the passdb modular interface and is
+ independent from the kind of users database used (currently there
+ are smbpasswd, ldap, nis+ and tdb based and more can be addedd
+ without changing the tool).</P
+><P
+>There are five main ways to use pdbedit: adding a user account,
+ removing a user account, modifing a user account, listing user
+ accounts, importing users accounts.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN31"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-l</DT
+><DD
+><P
+>This option list all the user accounts
+ present in the users database.
+ This option prints a list of user/uid pairs separated by
+ the ':' character.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -l</B
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> sorce:500:Simo Sorce
+ samba:45:Test User
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+><DT
+>-v</DT
+><DD
+><P
+>This option sets the verbose listing format.
+ It will make pdbedit list the users in the database printing
+ out the account fields in a descriptive format.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -l -v</B
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> ---------------
+ username: sorce
+ user ID/Group: 500/500
+ user RID/GRID: 2000/2001
+ Full Name: Simo Sorce
+ Home Directory: \\BERSERKER\sorce
+ HomeDir Drive: H:
+ Logon Script: \\BERSERKER\netlogon\sorce.bat
+ Profile Path: \\BERSERKER\profile
+ ---------------
+ username: samba
+ user ID/Group: 45/45
+ user RID/GRID: 1090/1091
+ Full Name: Test User
+ Home Directory: \\BERSERKER\samba
+ HomeDir Drive:
+ Logon Script:
+ Profile Path: \\BERSERKER\profile
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+><DT
+>-w</DT
+><DD
+><P
+>This option sets the "smbpasswd" listing format.
+ It will make pdbedit list the users in the database printing
+ out the account fields in a format compatible with the
+ <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file format. (see the <A
+HREF="smbpasswd.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smbpasswd(5)</TT
+></A
+> for details)</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -l -w</B
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> sorce:500:508818B733CE64BEAAD3B435B51404EE:D2A2418EFC466A8A0F6B1DBB5C3DB80C:[UX ]:LCT-00000000:
+ samba:45:0F2B255F7B67A7A9AAD3B435B51404EE:BC281CE3F53B6A5146629CD4751D3490:[UX ]:LCT-3BFA1E8D:
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+><DT
+>-u username</DT
+><DD
+><P
+>This option specifies that the username to be
+ used for the operation requested (listing, adding, removing)
+ It is <EM
+>required</EM
+> in add, remove and modify
+ operations and <EM
+>optional</EM
+> in list
+ operations.</P
+></DD
+><DT
+>-f fullname</DT
+><DD
+><P
+>This option can be used while adding or
+ modifing a user account. It will specify the user's full
+ name. </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>-f "Simo Sorce"</B
+></P
+></DD
+><DT
+>-h homedir</DT
+><DD
+><P
+>This option can be used while adding or
+ modifing a user account. It will specify the user's home
+ directory network path.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>-h "\\\\BERSERKER\\sorce"</B
+>
+ </P
+></DD
+><DT
+>-d drive</DT
+><DD
+><P
+>This option can be used while adding or
+ modifing a user account. It will specify the windows drive
+ letter to be used to map the home directory.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>-d "H:"</B
+>
+ </P
+></DD
+><DT
+>-s script</DT
+><DD
+><P
+>This option can be used while adding or
+ modifing a user account. It will specify the user's logon
+ script path.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>-s "\\\\BERSERKER\\netlogon\\sorce.bat"</B
+>
+ </P
+></DD
+><DT
+>-p profile</DT
+><DD
+><P
+>This option can be used while adding or
+ modifing a user account. It will specify the user's profile
+ directory.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>-p "\\\\BERSERKER\\netlogon"</B
+>
+ </P
+></DD
+><DT
+>-a</DT
+><DD
+><P
+>This option is used to add a user into the
+ database. This command need the user name be specified with
+ the -u switch. When adding a new user pdbedit will also
+ ask for the password to be used</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -a -u sorce</B
+>
+ <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>new password:
+ retype new password</PRE
+></TD
+></TR
+></TABLE
+>
+ </P
+></DD
+><DT
+>-m</DT
+><DD
+><P
+>This option may only be used in conjunction
+ with the <TT
+CLASS="PARAMETER"
+><I
+>-a</I
+></TT
+> option. It will make
+ pdbedit to add a machine trust account instead of a user
+ account (-u username will provide the machine name).</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -a -m -u w2k-wks</B
+>
+ </P
+></DD
+><DT
+>-x</DT
+><DD
+><P
+>This option causes pdbedit to delete an account
+ from the database. It need the username be specified with the
+ -u switch.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -x -u bob</B
+></P
+></DD
+><DT
+>-i file</DT
+><DD
+><P
+>This command is used to import a smbpasswd
+ file into the database.</P
+><P
+>This option will ease migration from the plain smbpasswd
+ file database to more powerful backend databases like tdb and
+ ldap.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pdbedit -i /etc/smbpasswd.old</B
+>
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN124"
+></A
+><H2
+>NOTES</H2
+><P
+>This command may be used only by root.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN127"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+>smbpasswd(8)</A
+>,
+ <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN135"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/printer_driver2.html b/docs/htmldocs/printer_driver2.html
new file mode 100755
index 00000000000..38a7e280668
--- /dev/null
+++ b/docs/htmldocs/printer_driver2.html
@@ -0,0 +1,1052 @@
+<HTML
+><HEAD
+><TITLE
+>Printing Support in Samba 2.2.x</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="PRINTING"
+>Printing Support in Samba 2.2.x</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Introduction</A
+></H1
+><P
+>Beginning with the 2.2.0 release, Samba supports
+the native Windows NT printing mechanisms implemented via
+MS-RPC (i.e. the SPOOLSS named pipe). Previous versions of
+Samba only supported LanMan printing calls.</P
+><P
+>The additional functionality provided by the new
+SPOOLSS support includes:</P
+><P
+></P
+><UL
+><LI
+><P
+>Support for downloading printer driver
+ files to Windows 95/98/NT/2000 clients upon demand.
+ </P
+></LI
+><LI
+><P
+>Uploading of printer drivers via the
+ Windows NT Add Printer Wizard (APW) or the
+ Imprints tool set (refer to <A
+HREF="http://imprints.sourceforge.net"
+TARGET="_top"
+>http://imprints.sourceforge.net</A
+>).
+ </P
+></LI
+><LI
+><P
+>Support for the native MS-RPC printing
+ calls such as StartDocPrinter, EnumJobs(), etc... (See
+ the MSDN documentation at <A
+HREF="http://msdn.microsoft.com/"
+TARGET="_top"
+>http://msdn.microsoft.com/</A
+>
+ for more information on the Win32 printing API)
+ </P
+></LI
+><LI
+><P
+>Support for NT Access Control Lists (ACL)
+ on printer objects</P
+></LI
+><LI
+><P
+>Improved support for printer queue manipulation
+ through the use of an internal databases for spooled job
+ information</P
+></LI
+></UL
+><P
+>There has been some initial confusion about what all this means
+and whether or not it is a requirement for printer drivers to be
+installed on a Samba host in order to support printing from Windows
+clients. A bug existed in Samba 2.2.0 which made Windows NT/2000 clients
+require that the Samba server possess a valid driver for the printer.
+This is fixed in Samba 2.2.1 and once again, Windows NT/2000 clients
+can use the local APW for installing drivers to be used with a Samba
+served printer. This is the same behavior exhibited by Windows 9x clients.
+As a side note, Samba does not use these drivers in any way to process
+spooled files. They are utilized entirely by the clients.</P
+><P
+>The following MS KB article, may be of some help if you are dealing with
+Windows 2000 clients: <I
+CLASS="EMPHASIS"
+>How to Add Printers with No User
+Interaction in Windows 2000</I
+></P
+><P
+><A
+HREF="http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP"
+TARGET="_top"
+>http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP</A
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN25"
+>Configuration</A
+></H1
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>[print$] vs. [printer$]</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>Previous versions of Samba recommended using a share named [printer$].
+This name was taken from the printer$ service created by Windows 9x
+clients when a printer was shared. Windows 9x printer servers always have
+a printer$ service which provides read-only access via no
+password in order to support printer driver downloads.</P
+><P
+>However, the initial implementation allowed for a
+parameter named <TT
+CLASS="PARAMETER"
+><I
+>printer driver location</I
+></TT
+>
+to be used on a per share basis to specify the location of
+the driver files associated with that printer. Another
+parameter named <TT
+CLASS="PARAMETER"
+><I
+>printer driver</I
+></TT
+> provided
+a means of defining the printer driver name to be sent to
+the client.</P
+><P
+>These parameters, including <TT
+CLASS="PARAMETER"
+><I
+>printer driver
+file</I
+></TT
+> parameter, are being deprecated and should not
+be used in new installations. For more information on this change,
+you should refer to the <A
+HREF="#MIGRATION"
+>Migration section</A
+>
+of this document.</P
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN36"
+>Creating [print$]</A
+></H2
+><P
+>In order to support the uploading of printer driver
+files, you must first configure a file share named [print$].
+The name of this share is hard coded in Samba's internals so
+the name is very important (print$ is the service used by
+Windows NT print servers to provide support for printer driver
+download).</P
+><P
+>You should modify the server's smb.conf file to add the global
+parameters and to create the
+following file share (of course, some of the parameter values,
+such as 'path' are arbitrary and should be replaced with
+appropriate values for your site):</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ ; members of the ntadmin group should be able
+ ; to add drivers and set printer properties
+ ; root is implicitly a 'printer admin'
+ printer admin = @ntadmin
+
+[print$]
+ path = /usr/local/samba/printers
+ guest ok = yes
+ browseable = yes
+ read only = yes
+ ; since this share is configured as read only, then we need
+ ; a 'write list'. Check the file system permissions to make
+ ; sure this account can copy files to the share. If this
+ ; is setup to a non-root account, then it should also exist
+ ; as a 'printer admin'
+ write list = @ntadmin,root</PRE
+></P
+><P
+>The <A
+HREF="smb.conf.5.html#WRITELIST"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>write list</I
+></TT
+></A
+> is used to allow administrative
+level user accounts to have write access in order to update files
+on the share. See the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)
+man page</A
+> for more information on configuring file shares.</P
+><P
+>The requirement for <A
+HREF="smb.conf.5.html#GUESTOK"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>guest
+ok = yes</B
+></A
+> depends upon how your
+site is configured. If users will be guaranteed to have
+an account on the Samba host, then this is a non-issue.</P
+><DIV
+CLASS="NOTE"
+><BLOCKQUOTE
+CLASS="NOTE"
+><P
+><B
+>Author's Note: </B
+>The non-issue is that if all your Windows NT users are guaranteed to be
+authenticated by the Samba server (such as a domain member server and the NT
+user has already been validated by the Domain Controller in
+order to logon to the Windows NT console), then guest access
+is not necessary. Of course, in a workgroup environment where
+you just want to be able to print without worrying about
+silly accounts and security, then configure the share for
+guest access. You'll probably want to add <A
+HREF="smb.conf.5.html#MAPTOGUEST"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>map to guest = Bad User</B
+></A
+> in the [global] section as well. Make sure
+you understand what this parameter does before using it
+though. --jerry</P
+></BLOCKQUOTE
+></DIV
+><P
+>In order for a Windows NT print server to support
+the downloading of driver files by multiple client architectures,
+it must create subdirectories within the [print$] service
+which correspond to each of the supported client architectures.
+Samba follows this model as well.</P
+><P
+>Next create the directory tree below the [print$] share
+for each architecture you wish to support.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[print$]-----
+ |-W32X86 ; "Windows NT x86"
+ |-WIN40 ; "Windows 95/98"
+ |-W32ALPHA ; "Windows NT Alpha_AXP"
+ |-W32MIPS ; "Windows NT R4000"
+ |-W32PPC ; "Windows NT PowerPC"</PRE
+></P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>ATTENTION! REQUIRED PERMISSIONS</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>In order to currently add a new driver to you Samba host,
+one of two conditions must hold true:</P
+><P
+></P
+><UL
+><LI
+><P
+>The account used to connect to the Samba host
+ must have a uid of 0 (i.e. a root account)</P
+></LI
+><LI
+><P
+>The account used to connect to the Samba host
+ must be a member of the <A
+HREF="smb.conf.5.html#PRINTERADMIN"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>printer
+ admin</I
+></TT
+></A
+> list.</P
+></LI
+></UL
+><P
+>Of course, the connected account must still possess access
+to add files to the subdirectories beneath [print$]. Remember
+that all file shares are set to 'read only' by default.</P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>Once you have created the required [print$] service and
+associated subdirectories, simply log onto the Samba server using
+a root (or <TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+>) account
+from a Windows NT 4.0/2k client. Open "Network Neighbourhood" or
+"My Network Places" and browse for the Samba host. Once you have located
+the server, navigate to the "Printers..." folder.
+You should see an initial listing of printers
+that matches the printer shares defined on your Samba host.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN71"
+>Setting Drivers for Existing Printers</A
+></H2
+><P
+>The initial listing of printers in the Samba host's
+Printers folder will have no real printer driver assigned
+to them. By default, in Samba 2.2.0 this driver name was set to
+<I
+CLASS="EMPHASIS"
+>NO PRINTER DRIVER AVAILABLE FOR THIS PRINTER</I
+>.
+Later versions changed this to a NULL string to allow the use
+tof the local Add Printer Wizard on NT/2000 clients.
+Attempting to view the printer properties for a printer
+which has this default driver assigned will result in
+the error message:</P
+><P
+><I
+CLASS="EMPHASIS"
+>Device settings cannot be displayed. The driver
+for the specified printer is not installed, only spooler
+properties will be displayed. Do you want to install the
+driver now?</I
+></P
+><P
+>Click <I
+CLASS="EMPHASIS"
+>No</I
+> in the error dialog and you will be presented with
+the printer properties window. The way assign a driver to a
+printer is to either</P
+><P
+></P
+><UL
+><LI
+><P
+>Use the "New Driver..." button to install
+ a new printer driver, or</P
+></LI
+><LI
+><P
+>Select a driver from the popup list of
+ installed drivers. Initially this list will be empty.</P
+></LI
+></UL
+><P
+>If you wish to install printer drivers for client
+operating systems other than "Windows NT x86", you will need
+to use the "Sharing" tab of the printer properties dialog.</P
+><P
+>Assuming you have connected with a root account, you
+will also be able modify other printer properties such as
+ACLs and device settings using this dialog box.</P
+><P
+>A few closing comments for this section, it is possible
+on a Windows NT print server to have printers
+listed in the Printers folder which are not shared. Samba does
+not make this distinction. By definition, the only printers of
+which Samba is aware are those which are specified as shares in
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.</P
+><P
+>Another interesting side note is that Windows NT clients do
+not use the SMB printer share, but rather can print directly
+to any printer on another Windows NT host using MS-RPC. This
+of course assumes that the printing client has the necessary
+privileges on the remote host serving the printer. The default
+permissions assigned by Windows NT to a printer gives the "Print"
+permissions to the "Everyone" well-known group.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN89"
+>DeviceModes and New Printers</A
+></H2
+><P
+>In order for a printer to be truly usbla eby a Windows NT/2k/XP client,
+it must posses:</P
+><P
+></P
+><UL
+><LI
+><P
+>a valid Device Mode generated by the driver for the printer, and</P
+></LI
+><LI
+><P
+>a complete set of PrinterDriverData generated by the driver.</P
+></LI
+></UL
+><P
+>If either one of these is incomplete, the clients can produce less than optimal
+output at best or in the worst cases, unreadable garbage or nothing at all.
+Fortunately, most driver generate the printer driver that is needed.
+However, the client must be tickled to generate a valid Device Mode and set it on the
+server. The easist means of doing so is to simply set the page orientation on
+the server's printer using the native Windows NT/2k printer properties page from
+a Window clients. Make sure to apply changes between swapping the page orientation
+to cause the change to actually take place. Be aware that this can only be done
+by a "printer admin" (the reason should be obvious I hope).</P
+><P
+>Samba also includes a service level parameter name <A
+HREF="smb.conf.5.html#DEFAULTDEVMODE"
+TARGET="_top"
+>default
+devmode</A
+> for generating a default device mode for a printer. Some driver
+will function fine with this default set of properties. Others may crash the client's
+spooler service. Use this parameter with caution. It is always better to have the client
+generate a valid device mode for the printer and store it on the server for you.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN100"
+>Support a large number of printers</A
+></H2
+><P
+>One issue that has arisen during the development
+phase of Samba 2.2 is the need to support driver downloads for
+100's of printers. Using the Windows NT APW is somewhat
+awkward to say the list. If more than one printer are using the
+same driver, the <A
+HREF="rpcclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>rpcclient's
+setdriver</B
+></A
+> command can be used to set the driver
+associated with an installed driver. The following is example
+of how this could be accomplished:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret -c "enumdrivers"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+
+[Windows NT x86]
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4000 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 2100 Series PS]
+
+Printer Driver Info 1:
+ Driver Name: [HP LaserJet 4Si/4SiMX PS]
+
+<TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret -c "enumprinters"
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+ flags:[0x800000]
+ name:[\\POGO\hp-print]
+ description:[POGO\\POGO\hp-print,NO DRIVER AVAILABLE FOR THIS PRINTER,]
+ comment:[]
+
+<TT
+CLASS="PROMPT"
+>$ </TT
+>rpcclient pogo -U root%secret \
+<TT
+CLASS="PROMPT"
+>&gt; </TT
+> -c "setdriver hp-print \"HP LaserJet 4000 Series PS\""
+Domain=[NARNIA] OS=[Unix] Server=[Samba 2.2.0-alpha3]
+Successfully set hp-print to driver HP LaserJet 4000 Series PS.</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN111"
+>Adding New Printers via the Windows NT APW</A
+></H2
+><P
+>By default, Samba offers all printer shares defined in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+in the "Printers..." folder. Also existing in this folder is the Windows NT
+Add Printer Wizard icon. The APW will be show only if</P
+><P
+></P
+><UL
+><LI
+><P
+>The connected user is able to successfully
+ execute an OpenPrinterEx(\\server) with administrative
+ privileges (i.e. root or <TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+>).
+ </P
+></LI
+><LI
+><P
+><A
+HREF="smb.conf.5.html#SHOWADDPRINTERWIZARD"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>show
+ add printer wizard = yes</I
+></TT
+></A
+> (the default).
+ </P
+></LI
+></UL
+><P
+>In order to be able to use the APW to successfully add a printer to a Samba
+server, the <A
+HREF="smb.conf.5.html#ADDPRINTERCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>add
+printer command</I
+></TT
+></A
+> must have a defined value. The program
+hook must successfully add the printer to the system (i.e.
+<TT
+CLASS="FILENAME"
+>/etc/printcap</TT
+> or appropriate files) and
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> if necessary.</P
+><P
+>When using the APW from a client, if the named printer share does
+not exist, <B
+CLASS="COMMAND"
+>smbd</B
+> will execute the <TT
+CLASS="PARAMETER"
+><I
+>add printer
+command</I
+></TT
+> and reparse to the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+to attempt to locate the new printer share. If the share is still not defined,
+an error of "Access Denied" is returned to the client. Note that the
+<TT
+CLASS="PARAMETER"
+><I
+>add printer program</I
+></TT
+> is executed under the context
+of the connected user, not necessarily a root account.</P
+><P
+>There is a complementing <A
+HREF="smb.conf.5.html#DELETEPRINTERCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>delete
+printer command</I
+></TT
+></A
+> for removing entries from the "Printers..."
+folder.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN136"
+>Samba and Printer Ports</A
+></H2
+><P
+>Windows NT/2000 print servers associate a port with each printer. These normally
+take the form of LPT1:, COM1:, FILE:, etc... Samba must also support the
+concept of ports associated with a printer. By default, only one printer port,
+named "Samba Printer Port", exists on a system. Samba does not really a port in
+order to print, rather it is a requirement of Windows clients. </P
+><P
+>Note that Samba does not support the concept of "Printer Pooling" internally
+either. This is when a logical printer is assigned to multiple ports as
+a form of load balancing or fail over.</P
+><P
+>If you require that multiple ports be defined for some reason,
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> possesses a <A
+HREF="smb.conf.5.html#ENUMPORTSCOMMAND"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>enumports
+command</I
+></TT
+></A
+> which can be used to define an external program
+that generates a listing of ports on a system.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN144"
+>The Imprints Toolset</A
+></H1
+><P
+>The Imprints tool set provides a UNIX equivalent of the
+ Windows NT Add Printer Wizard. For complete information, please
+ refer to the Imprints web site at <A
+HREF="http://imprints.sourceforge.net/"
+TARGET="_top"
+> http://imprints.sourceforge.net/</A
+> as well as the documentation
+ included with the imprints source distribution. This section will
+ only provide a brief introduction to the features of Imprints.</P
+><P
+>As of June 16, 2002 (quite a bit earlier actually), the Imprints
+ project is in need of a new maintainer. The most important skill
+ is decent perl coding and an interest in MS-RPC based printing using Samba.
+ If you wich to volunteer, please coordinate your efforts on the samba-technical
+ mailing list.
+ </P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN149"
+>What is Imprints?</A
+></H2
+><P
+>Imprints is a collection of tools for supporting the goals
+ of</P
+><P
+></P
+><UL
+><LI
+><P
+>Providing a central repository information
+ regarding Windows NT and 95/98 printer driver packages</P
+></LI
+><LI
+><P
+>Providing the tools necessary for creating
+ the Imprints printer driver packages.</P
+></LI
+><LI
+><P
+>Providing an installation client which
+ will obtain and install printer drivers on remote Samba
+ and Windows NT 4 print servers.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN159"
+>Creating Printer Driver Packages</A
+></H2
+><P
+>The process of creating printer driver packages is beyond
+ the scope of this document (refer to Imprints.txt also included
+ with the Samba distribution for more information). In short,
+ an Imprints driver package is a gzipped tarball containing the
+ driver files, related INF files, and a control file needed by the
+ installation client.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN162"
+>The Imprints server</A
+></H2
+><P
+>The Imprints server is really a database server that
+ may be queried via standard HTTP mechanisms. Each printer
+ entry in the database has an associated URL for the actual
+ downloading of the package. Each package is digitally signed
+ via GnuPG which can be used to verify that package downloaded
+ is actually the one referred in the Imprints database. It is
+ <I
+CLASS="EMPHASIS"
+>not</I
+> recommended that this security check
+ be disabled.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN166"
+>The Installation Client</A
+></H2
+><P
+>More information regarding the Imprints installation client
+ is available in the <TT
+CLASS="FILENAME"
+>Imprints-Client-HOWTO.ps</TT
+>
+ file included with the imprints source package.</P
+><P
+>The Imprints installation client comes in two forms.</P
+><P
+></P
+><UL
+><LI
+><P
+>a set of command line Perl scripts</P
+></LI
+><LI
+><P
+>a GTK+ based graphical interface to
+ the command line perl scripts</P
+></LI
+></UL
+><P
+>The installation client (in both forms) provides a means
+ of querying the Imprints database server for a matching
+ list of known printer model names as well as a means to
+ download and install the drivers on remote Samba and Windows
+ NT print servers.</P
+><P
+>The basic installation process is in four steps and
+ perl code is wrapped around <B
+CLASS="COMMAND"
+>smbclient</B
+>
+ and <B
+CLASS="COMMAND"
+>rpcclient</B
+>.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>
+foreach (supported architecture for a given driver)
+{
+ 1. rpcclient: Get the appropriate upload directory
+ on the remote server
+ 2. smbclient: Upload the driver files
+ 3. rpcclient: Issues an AddPrinterDriver() MS-RPC
+}
+
+4. rpcclient: Issue an AddPrinterEx() MS-RPC to actually
+ create the printer</PRE
+></P
+><P
+>One of the problems encountered when implementing
+ the Imprints tool set was the name space issues between
+ various supported client architectures. For example, Windows
+ NT includes a driver named "Apple LaserWriter II NTX v51.8"
+ and Windows 95 calls its version of this driver "Apple
+ LaserWriter II NTX"</P
+><P
+>The problem is how to know what client drivers have
+ been uploaded for a printer. As astute reader will remember
+ that the Windows NT Printer Properties dialog only includes
+ space for one printer driver name. A quick look in the
+ Windows NT 4.0 system registry at</P
+><P
+><TT
+CLASS="FILENAME"
+>HKLM\System\CurrentControlSet\Control\Print\Environment
+ </TT
+></P
+><P
+>will reveal that Windows NT always uses the NT driver
+ name. This is ok as Windows NT always requires that at least
+ the Windows NT version of the printer driver is present.
+ However, Samba does not have the requirement internally.
+ Therefore, how can you use the NT driver name if is has not
+ already been installed?</P
+><P
+>The way of sidestepping this limitation is to require
+ that all Imprints printer driver packages include both the Intel
+ Windows NT and 95/98 printer drivers and that NT driver is
+ installed first.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN188"
+><A
+NAME="MIGRATION"
+></A
+>Migration to from Samba 2.0.x to 2.2.x</A
+></H1
+><P
+>Given that printer driver management has changed (we hope improved) in
+2.2 over prior releases, migration from an existing setup to 2.2 can
+follow several paths. Here are the possible scenarios for
+migration:</P
+><P
+></P
+><UL
+><LI
+><P
+>If you do not desire the new Windows NT
+ print driver support, nothing needs to be done.
+ All existing parameters work the same.</P
+></LI
+><LI
+><P
+>If you want to take advantage of NT printer
+ driver support but do not want to migrate the
+ 9x drivers to the new setup, the leave the existing
+ <TT
+CLASS="FILENAME"
+>printers.def</TT
+> file. When smbd attempts
+ to locate a
+ 9x driver for the printer in the TDB and fails it
+ will drop down to using the printers.def (and all
+ associated parameters). The <B
+CLASS="COMMAND"
+>make_printerdef</B
+>
+ tool will also remain for backwards compatibility but will
+ be removed in the next major release.</P
+></LI
+><LI
+><P
+>If you install a Windows 9x driver for a printer
+ on your Samba host (in the printing TDB), this information will
+ take precedence and the three old printing parameters
+ will be ignored (including print driver location).</P
+></LI
+><LI
+><P
+>If you want to migrate an existing <TT
+CLASS="FILENAME"
+>printers.def</TT
+>
+ file into the new setup, the current only solution is to use the Windows
+ NT APW to install the NT drivers and the 9x drivers. This can be scripted
+ using <B
+CLASS="COMMAND"
+>smbclient</B
+> and <B
+CLASS="COMMAND"
+>rpcclient</B
+>. See the
+ Imprints installation client at <A
+HREF="http://imprints.sourceforge.net/"
+TARGET="_top"
+>http://imprints.sourceforge.net/</A
+>
+ for an example.
+ </P
+></LI
+></UL
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Achtung!</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>The following <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> parameters are considered to
+be deprecated and will be removed soon. Do not use them in new
+installations</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver file (G)</I
+></TT
+>
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver (S)</I
+></TT
+>
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver location (S)</I
+></TT
+>
+ </P
+></LI
+></UL
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN221"
+>Parameters in <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> for Backwards Compatibility</A
+></H2
+><P
+>The have been two new parameters add in Samba 2.2.2 to for
+better support of Samba 2.0.x backwards capability (<TT
+CLASS="PARAMETER"
+><I
+>disable
+spoolss</I
+></TT
+>) and for using local printers drivers on Windows
+NT/2000 clients (<TT
+CLASS="PARAMETER"
+><I
+>use client driver</I
+></TT
+>). Both of
+these options are described in the smb.coinf(5) man page and are
+disabled by default. Use them with caution.</P
+></DIV
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/rpcclient.1.html b/docs/htmldocs/rpcclient.1.html
new file mode 100755
index 00000000000..d18966fa238
--- /dev/null
+++ b/docs/htmldocs/rpcclient.1.html
@@ -0,0 +1,719 @@
+<HTML
+><HEAD
+><TITLE
+>rpcclient</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="RPCCLIENT"
+>rpcclient</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>rpcclient&nbsp;--&nbsp;tool for executing client side
+ MS-RPC functions</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>rpcclient</B
+> [-A authfile] [-c &#60;command string&#62;] [-d debuglevel] [-h] [-l logfile] [-N] [-s &#60;smb config file&#62;] [-U username[%password]] [-W workgroup] [-N] {server}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN22"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>rpcclient</B
+> is a utility initially developed
+ to test MS-RPC functionality in Samba itself. It has undergone
+ several stages of development and stability. Many system administrators
+ have now written scripts around it to manage Windows NT clients from
+ their UNIX workstation. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN28"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>server</DT
+><DD
+><P
+>NetBIOS name of Server to which to connect.
+ The server can be any SMB/CIFS server. The name is
+ resolved using the <A
+HREF="smb.conf.5.html#NAMERESOLVEORDER"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>name resolve order</I
+></TT
+></A
+> line from
+ <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>.</P
+></DD
+><DT
+>-A filename</DT
+><DD
+><P
+>This option allows
+ you to specify a file from which to read the username and
+ password used in the connection. The format of the file is
+ </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> username = &#60;value&#62;
+ password = &#60;value&#62;
+ domain = &#60;value&#62;
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Make certain that the permissions on the file restrict
+ access from unwanted users. </P
+></DD
+><DT
+>-c 'command string'</DT
+><DD
+><P
+>execute semicolon separated commands (listed
+ below)) </P
+></DD
+><DT
+>-d debuglevel</DT
+><DD
+><P
+>set the debuglevel. Debug level 0 is the lowest
+ and 100 being the highest. This should be set to 100 if you are
+ planning on submitting a bug report to the Samba team (see <TT
+CLASS="FILENAME"
+>BUGS.txt</TT
+>).
+ </P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Print a summary of command line options.
+ </P
+></DD
+><DT
+>-l logbasename</DT
+><DD
+><P
+>File name for log/debug files. The extension
+ <TT
+CLASS="CONSTANT"
+>'.client'</TT
+> will be appended. The log file is never removed
+ by the client.
+ </P
+></DD
+><DT
+>-N</DT
+><DD
+><P
+>instruct <B
+CLASS="COMMAND"
+>rpcclient</B
+> not to ask
+ for a password. By default, <B
+CLASS="COMMAND"
+>rpcclient</B
+> will prompt
+ for a password. See also the <TT
+CLASS="PARAMETER"
+><I
+>-U</I
+></TT
+> option.</P
+></DD
+><DT
+>-s smb.conf</DT
+><DD
+><P
+>Specifies the location of the all important
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. </P
+></DD
+><DT
+>-U username[%password]</DT
+><DD
+><P
+>Sets the SMB username or username and password. </P
+><P
+>If %password is not specified, the user will be prompted. The
+ client will first check the <TT
+CLASS="ENVAR"
+>USER</TT
+> environment variable, then the
+ <TT
+CLASS="ENVAR"
+>LOGNAME</TT
+> variable and if either exists, the
+ string is uppercased. If these environmental variables are not
+ found, the username <TT
+CLASS="CONSTANT"
+>GUEST</TT
+> is used. </P
+><P
+>A third option is to use a credentials file which
+ contains the plaintext of the username and password. This
+ option is mainly provided for scripts where the admin doesn't
+ desire to pass the credentials on the command line or via environment
+ variables. If this method is used, make certain that the permissions
+ on the file restrict access from unwanted users. See the
+ <TT
+CLASS="PARAMETER"
+><I
+>-A</I
+></TT
+> for more details. </P
+><P
+>Be cautious about including passwords in scripts. Also, on
+ many systems the command line of a running process may be seen
+ via the <B
+CLASS="COMMAND"
+>ps</B
+> command. To be safe always allow
+ <B
+CLASS="COMMAND"
+>rpcclient</B
+> to prompt for a password and type
+ it in directly. </P
+></DD
+><DT
+>-W domain</DT
+><DD
+><P
+>Set the SMB domain of the username. This
+ overrides the default domain which is the domain defined in
+ smb.conf. If the domain specified is the same as the server's NetBIOS name,
+ it causes the client to log on using the server's local SAM (as
+ opposed to the Domain SAM). </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN92"
+></A
+><H2
+>COMMANDS</H2
+><P
+><EM
+>LSARPC</EM
+></P
+><P
+></P
+><UL
+><LI
+><P
+><B
+CLASS="COMMAND"
+>lsaquery</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>lookupsids</B
+> - Resolve a list
+ of SIDs to usernames.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>lookupnames</B
+> - Resolve s list
+ of usernames to SIDs.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumtrusts</B
+></P
+></LI
+></UL
+><P
+> </P
+><P
+><EM
+>SAMR</EM
+></P
+><P
+></P
+><UL
+><LI
+><P
+><B
+CLASS="COMMAND"
+>queryuser</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>querygroup</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>queryusergroups</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>querygroupmem</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>queryaliasmem</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>querydispinfo</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>querydominfo</B
+></P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumdomgroups</B
+></P
+></LI
+></UL
+><P
+> </P
+><P
+><EM
+>SPOOLSS</EM
+></P
+><P
+></P
+><UL
+><LI
+><P
+><B
+CLASS="COMMAND"
+>adddriver &#60;arch&#62; &#60;config&#62;</B
+>
+ - Execute an AddPrinterDriver() RPC to install the printer driver
+ information on the server. Note that the driver files should
+ already exist in the directory returned by
+ <B
+CLASS="COMMAND"
+>getdriverdir</B
+>. Possible values for
+ <TT
+CLASS="PARAMETER"
+><I
+>arch</I
+></TT
+> are the same as those for
+ the <B
+CLASS="COMMAND"
+>getdriverdir</B
+> command.
+ The <TT
+CLASS="PARAMETER"
+><I
+>config</I
+></TT
+> parameter is defined as
+ follows: </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> Long Printer Name:\
+ Driver File Name:\
+ Data File Name:\
+ Config File Name:\
+ Help File Name:\
+ Language Monitor Name:\
+ Default Data Type:\
+ Comma Separated list of Files
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Any empty fields should be enter as the string "NULL". </P
+><P
+>Samba does not need to support the concept of Print Monitors
+ since these only apply to local printers whose driver can make
+ use of a bi-directional link for communication. This field should
+ be "NULL". On a remote NT print server, the Print Monitor for a
+ driver must already be installed prior to adding the driver or
+ else the RPC will fail. </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>addprinter &#60;printername&#62;
+ &#60;sharename&#62; &#60;drivername&#62; &#60;port&#62;</B
+>
+ - Add a printer on the remote server. This printer
+ will be automatically shared. Be aware that the printer driver
+ must already be installed on the server (see <B
+CLASS="COMMAND"
+>adddriver</B
+>)
+ and the <TT
+CLASS="PARAMETER"
+><I
+>port</I
+></TT
+>must be a valid port name (see
+ <B
+CLASS="COMMAND"
+>enumports</B
+>.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>deldriver</B
+> - Delete the
+ specified printer driver for all architectures. This
+ does not delete the actual driver files from the server,
+ only the entry from the server's list of drivers.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumdata</B
+> - Enumerate all
+ printer setting data stored on the server. On Windows NT clients,
+ these values are stored in the registry, while Samba servers
+ store them in the printers TDB. This command corresponds
+ to the MS Platform SDK GetPrinterData() function (* This
+ command is currently unimplemented).</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumjobs &#60;printer&#62;</B
+>
+ - List the jobs and status of a given printer.
+ This command corresponds to the MS Platform SDK EnumJobs()
+ function (* This command is currently unimplemented).</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumports [level]</B
+>
+ - Executes an EnumPorts() call using the specified
+ info level. Currently only info levels 1 and 2 are supported.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumdrivers [level]</B
+>
+ - Execute an EnumPrinterDrivers() call. This lists the various installed
+ printer drivers for all architectures. Refer to the MS Platform SDK
+ documentation for more details of the various flags and calling
+ options. Currently supported info levels are 1, 2, and 3.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>enumprinters [level]</B
+>
+ - Execute an EnumPrinters() call. This lists the various installed
+ and share printers. Refer to the MS Platform SDK documentation for
+ more details of the various flags and calling options. Currently
+ supported info levels are 0, 1, and 2.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>getdata &#60;printername&#62;</B
+>
+ - Retrieve the data for a given printer setting. See
+ the <B
+CLASS="COMMAND"
+>enumdata</B
+> command for more information.
+ This command corresponds to the GetPrinterData() MS Platform
+ SDK function (* This command is currently unimplemented). </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>getdriver &#60;printername&#62;</B
+>
+ - Retrieve the printer driver information (such as driver file,
+ config file, dependent files, etc...) for
+ the given printer. This command corresponds to the GetPrinterDriver()
+ MS Platform SDK function. Currently info level 1, 2, and 3 are supported.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>getdriverdir &#60;arch&#62;</B
+>
+ - Execute a GetPrinterDriverDirectory()
+ RPC to retreive the SMB share name and subdirectory for
+ storing printer driver files for a given architecture. Possible
+ values for <TT
+CLASS="PARAMETER"
+><I
+>arch</I
+></TT
+> are "Windows 4.0"
+ (for Windows 95/98), "Windows NT x86", "Windows NT PowerPC", "Windows
+ Alpha_AXP", and "Windows NT R4000". </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>getprinter &#60;printername&#62;</B
+>
+ - Retrieve the current printer information. This command
+ corresponds to the GetPrinter() MS Platform SDK function.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>openprinter &#60;printername&#62;</B
+>
+ - Execute an OpenPrinterEx() and ClosePrinter() RPC
+ against a given printer. </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>setdriver &#60;printername&#62; &#60;drivername&#62;</B
+>
+ - Execute a SetPrinter() command to update the printer driver associated
+ with an installed printer. The printer driver must already be correctly
+ installed on the print server. </P
+><P
+>See also the <B
+CLASS="COMMAND"
+>enumprinters</B
+> and
+ <B
+CLASS="COMMAND"
+>enumdrivers</B
+> commands for obtaining a list of
+ of installed printers and drivers.</P
+></LI
+></UL
+><P
+><EM
+>GENERAL OPTIONS</EM
+></P
+><P
+></P
+><UL
+><LI
+><P
+><B
+CLASS="COMMAND"
+>debuglevel</B
+> - Set the current debug level
+ used to log information.</P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>help (?)</B
+> - Print a listing of all
+ known commands or extended help on a particular command.
+ </P
+></LI
+><LI
+><P
+><B
+CLASS="COMMAND"
+>quit (exit)</B
+> - Exit <B
+CLASS="COMMAND"
+>rpcclient
+ </B
+>.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN212"
+></A
+><H2
+>BUGS</H2
+><P
+><B
+CLASS="COMMAND"
+>rpcclient</B
+> is designed as a developer testing tool
+ and may not be robust in certain areas (such as command line parsing).
+ It has been known to generate a core dump upon failures when invalid
+ parameters where passed to the interpreter. </P
+><P
+>From Luke Leighton's original rpcclient man page:</P
+><P
+><EM
+>"WARNING!</EM
+> The MSRPC over SMB code has
+ been developed from examining Network traces. No documentation is
+ available from the original creators (Microsoft) on how MSRPC over
+ SMB works, or how the individual MSRPC services work. Microsoft's
+ implementation of these services has been demonstrated (and reported)
+ to be... a bit flaky in places. </P
+><P
+>The development of Samba's implementation is also a bit rough,
+ and as more of the services are understood, it can even result in
+ versions of <B
+CLASS="COMMAND"
+>smbd(8)</B
+> and <B
+CLASS="COMMAND"
+>rpcclient(1)</B
+>
+ that are incompatible for some commands or services. Additionally,
+ the developers are sending reports to Microsoft, and problems found
+ or reported to Microsoft are fixed in Service Packs, which may
+ result in incompatibilities." </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN222"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of the Samba
+ suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN225"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original rpcclient man page was written by Matthew
+ Geddes, Luke Kenneth Casson Leighton, and rewritten by Gerald Carter.
+ The conversion to DocBook for Samba 2.2 was done by Gerald
+ Carter.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/samba.7.html b/docs/htmldocs/samba.7.html
new file mode 100755
index 00000000000..6fb9eac5784
--- /dev/null
+++ b/docs/htmldocs/samba.7.html
@@ -0,0 +1,365 @@
+<HTML
+><HEAD
+><TITLE
+>samba</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SAMBA"
+>samba</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>SAMBA&nbsp;--&nbsp;A Windows SMB/CIFS fileserver for UNIX</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>Samba</B
+> </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN11"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>The Samba software suite is a collection of programs
+ that implements the Server Message Block (commonly abbreviated
+ as SMB) protocol for UNIX systems. This protocol is sometimes
+ also referred to as the Common Internet File System (CIFS),
+ LanManager or NetBIOS protocol.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><B
+CLASS="COMMAND"
+>smbd</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>smbd </B
+>
+ daemon provides the file and print services to
+ SMB clients, such as Windows 95/98, Windows NT, Windows
+ for Workgroups or LanManager. The configuration file
+ for this daemon is described in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ </P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>nmbd</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ daemon provides NetBIOS nameserving and browsing
+ support. The configuration file for this daemon
+ is described in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+></P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>smbclient</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>smbclient</B
+>
+ program implements a simple ftp-like client. This
+ is useful for accessing SMB shares on other compatible
+ servers (such as Windows NT), and can also be used
+ to allow a UNIX box to print to a printer attached to
+ any SMB server (such as a PC running Windows NT).</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>testparm</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>testparm</B
+>
+ utility is a simple syntax checker for Samba's
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>configuration file.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>testprns</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>testprns</B
+>
+ utility supports testing printer names defined
+ in your <TT
+CLASS="FILENAME"
+>printcap&#62;</TT
+> file used
+ by Samba.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>smbstatus</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>smbstatus</B
+>
+ tool provides access to information about the
+ current connections to <B
+CLASS="COMMAND"
+>smbd</B
+>.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>nmblookup</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>nmblookup</B
+>
+ tools allows NetBIOS name queries to be made
+ from a UNIX host.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>make_smbcodepage</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>make_smbcodepage</B
+>
+ utility provides a means of creating SMB code page
+ definition files for your <B
+CLASS="COMMAND"
+>smbd</B
+> server.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+></DT
+><DD
+><P
+>The <B
+CLASS="COMMAND"
+>smbpasswd</B
+>
+ command is a tool for changing LanMan and Windows NT
+ password hashes on Samba and Windows NT servers.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN75"
+></A
+><H2
+>COMPONENTS</H2
+><P
+>The Samba suite is made up of several components. Each
+ component is described in a separate manual page. It is strongly
+ recommended that you read the documentation that comes with Samba
+ and the manual pages of those components that you use. If the
+ manual pages aren't clear enough then please send a patch or
+ bug report to <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+> samba@samba.org</A
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN79"
+></A
+><H2
+>AVAILABILITY</H2
+><P
+>The Samba software suite is licensed under the
+ GNU Public License(GPL). A copy of that license should
+ have come with the package in the file COPYING. You are
+ encouraged to distribute copies of the Samba suite, but
+ please obey the terms of this license.</P
+><P
+>The latest version of the Samba suite can be
+ obtained via anonymous ftp from samba.org in the
+ directory pub/samba/. It is also available on several
+ mirror sites worldwide.</P
+><P
+>You may also find useful information about Samba
+ on the newsgroup <A
+HREF="news:comp.protocols.smb"
+TARGET="_top"
+> comp.protocol.smb</A
+> and the Samba mailing
+ list. Details on how to join the mailing list are given in
+ the README file that comes with Samba.</P
+><P
+>If you have access to a WWW viewer (such as Netscape
+ or Mosaic) then you will also find lots of useful information,
+ including back issues of the Samba mailing list, at
+ <A
+HREF="http://lists.samba.org/"
+TARGET="_top"
+>http://lists.samba.org</A
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN87"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of the
+ Samba suite. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN90"
+></A
+><H2
+>CONTRIBUTIONS</H2
+><P
+>If you wish to contribute to the Samba project,
+ then I suggest you join the Samba mailing list at
+ <A
+HREF="http://lists.samba.org/"
+TARGET="_top"
+>http://lists.samba.org</A
+>.
+ </P
+><P
+>If you have patches to submit or bugs to report
+ then you may mail them directly to samba-patches@samba.org.
+ Note, however, that due to the enormous popularity of this
+ package the Samba Team may take some time to respond to mail. We
+ prefer patches in <B
+CLASS="COMMAND"
+>diff -u</B
+> format.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN96"
+></A
+><H2
+>CONTRIBUTORS</H2
+><P
+>Contributors to the project are now too numerous
+ to mention here but all deserve the thanks of all Samba
+ users. To see a full list, look at <A
+HREF="ftp://samba.org/pub/samba/alpha/change-log"
+TARGET="_top"
+> ftp://samba.org/pub/samba/alpha/change-log</A
+>
+ for the pre-CVS changes and at <A
+HREF="ftp://samba.org/pub/samba/alpha/cvs.log"
+TARGET="_top"
+> ftp://samba.org/pub/samba/alpha/cvs.log</A
+>
+ for the contributors to Samba post-CVS. CVS is the Open Source
+ source code control system used by the Samba Team to develop
+ Samba. The project would have been unmanageable without it.</P
+><P
+>In addition, several commercial organizations now help
+ fund the Samba Team with money and equipment. For details see
+ the Samba Web pages at <A
+HREF="http://samba.org/samba/samba-thanks.html"
+TARGET="_top"
+> http://samba.org/samba/samba-thanks.html</A
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN103"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smb.conf.5.html b/docs/htmldocs/smb.conf.5.html
new file mode 100755
index 00000000000..97d06b131b7
--- /dev/null
+++ b/docs/htmldocs/smb.conf.5.html
@@ -0,0 +1,19921 @@
+<HTML
+><HEAD
+><TITLE
+>smb.conf</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMB.CONF"
+>smb.conf</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smb.conf&nbsp;--&nbsp;The configuration file for the Samba suite</DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN8"
+></A
+><H2
+>SYNOPSIS</H2
+><P
+>The <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file is a configuration
+ file for the Samba suite. <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> contains
+ runtime configuration information for the Samba programs. The
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file is designed to be configured and
+ administered by the <A
+HREF="swat.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>swat(8)</B
+>
+ </A
+> program. The complete description of the file format and
+ possible parameters held within are here for reference purposes.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN16"
+></A
+><H2
+>FILE FORMAT</H2
+><P
+>The file consists of sections and parameters. A section
+ begins with the name of the section in square brackets and continues
+ until the next section begins. Sections contain parameters of the
+ form</P
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+> = <TT
+CLASS="REPLACEABLE"
+><I
+>value
+ </I
+></TT
+></P
+><P
+>The file is line-based - that is, each newline-terminated
+ line represents either a comment, a section name or a parameter.</P
+><P
+>Section and parameter names are not case sensitive.</P
+><P
+>Only the first equals sign in a parameter is significant.
+ Whitespace before or after the first equals sign is discarded.
+ Leading, trailing and internal whitespace in section and parameter
+ names is irrelevant. Leading and trailing whitespace in a parameter
+ value is discarded. Internal whitespace within a parameter value
+ is retained verbatim.</P
+><P
+>Any line beginning with a semicolon (';') or a hash ('#')
+ character is ignored, as are lines containing only whitespace.</P
+><P
+>Any line ending in a '\' is continued
+ on the next line in the customary UNIX fashion.</P
+><P
+>The values following the equals sign in parameters are all
+ either a string (no quotes needed) or a boolean, which may be given
+ as yes/no, 0/1 or true/false. Case is not significant in boolean
+ values, but is preserved in string values. Some items such as
+ create modes are numeric.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN28"
+></A
+><H2
+>SECTION DESCRIPTIONS</H2
+><P
+>Each section in the configuration file (except for the
+ [global] section) describes a shared resource (known
+ as a "share"). The section name is the name of the
+ shared resource and the parameters within the section define
+ the shares attributes.</P
+><P
+>There are three special sections, [global],
+ [homes] and [printers], which are
+ described under <EM
+>special sections</EM
+>. The
+ following notes apply to ordinary section descriptions.</P
+><P
+>A share consists of a directory to which access is being
+ given plus a description of the access rights which are granted
+ to the user of the service. Some housekeeping options are
+ also specifiable.</P
+><P
+>Sections are either file share services (used by the
+ client as an extension of their native file systems) or
+ printable services (used by the client to access print services
+ on the host running the server).</P
+><P
+>Sections may be designated <EM
+>guest</EM
+> services,
+ in which case no password is required to access them. A specified
+ UNIX <EM
+>guest account</EM
+> is used to define access
+ privileges in this case.</P
+><P
+>Sections other than guest services will require a password
+ to access them. The client provides the username. As older clients
+ only provide passwords and not usernames, you may specify a list
+ of usernames to check against the password using the "user ="
+ option in the share definition. For modern clients such as
+ Windows 95/98/ME/NT/2000, this should not be necessary.</P
+><P
+>Note that the access rights granted by the server are
+ masked by the access rights granted to the specified or guest
+ UNIX user by the host system. The server does not grant more
+ access than the host system grants.</P
+><P
+>The following sample section defines a file space share.
+ The user has write access to the path <TT
+CLASS="FILENAME"
+>/home/bar</TT
+>.
+ The share is accessed via the share name "foo":</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> <TT
+CLASS="COMPUTEROUTPUT"
+> [foo]
+ path = /home/bar
+ read only = no
+ </TT
+>
+ </PRE
+></TD
+></TR
+></TABLE
+><P
+>The following sample section defines a printable share.
+ The share is readonly, but printable. That is, the only write
+ access permitted is via calls to open, write to and close a
+ spool file. The <EM
+>guest ok</EM
+> parameter means
+ access will be permitted as the default guest user (specified
+ elsewhere):</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> <TT
+CLASS="COMPUTEROUTPUT"
+> [aprinter]
+ path = /usr/spool/public
+ read only = yes
+ printable = yes
+ guest ok = yes
+ </TT
+>
+ </PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN48"
+></A
+><H2
+>SPECIAL SECTIONS</H2
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN50"
+></A
+><H3
+>The [global] section</H3
+><P
+>parameters in this section apply to the server
+ as a whole, or are defaults for sections which do not
+ specifically define certain items. See the notes
+ under PARAMETERS for more information.</P
+></DIV
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN53"
+></A
+><H3
+>The [homes] section</H3
+><P
+>If a section called homes is included in the
+ configuration file, services connecting clients to their
+ home directories can be created on the fly by the server.</P
+><P
+>When the connection request is made, the existing
+ sections are scanned. If a match is found, it is used. If no
+ match is found, the requested section name is treated as a
+ user name and looked up in the local password file. If the
+ name exists and the correct password has been given, a share is
+ created by cloning the [homes] section.</P
+><P
+>Some modifications are then made to the newly
+ created share:</P
+><P
+></P
+><UL
+><LI
+><P
+>The share name is changed from homes to
+ the located username.</P
+></LI
+><LI
+><P
+>If no path was given, the path is set to
+ the user's home directory.</P
+></LI
+></UL
+><P
+>If you decide to use a <EM
+>path =</EM
+> line
+ in your [homes] section then you may find it useful
+ to use the %S macro. For example :</P
+><P
+><TT
+CLASS="USERINPUT"
+><B
+>path = /data/pchome/%S</B
+></TT
+></P
+><P
+>would be useful if you have different home directories
+ for your PCs than for UNIX access.</P
+><P
+>This is a fast and simple way to give a large number
+ of clients access to their home directories with a minimum
+ of fuss.</P
+><P
+>A similar process occurs if the requested section
+ name is "homes", except that the share name is not
+ changed to that of the requesting user. This method of using
+ the [homes] section works well if different users share
+ a client PC.</P
+><P
+>The [homes] section can specify all the parameters
+ a normal service section can specify, though some make more sense
+ than others. The following is a typical and suitable [homes]
+ section:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> <TT
+CLASS="COMPUTEROUTPUT"
+> [homes]
+ read only = no
+ </TT
+>
+ </PRE
+></TD
+></TR
+></TABLE
+><P
+>An important point is that if guest access is specified
+ in the [homes] section, all home directories will be
+ visible to all clients <EM
+>without a password</EM
+>.
+ In the very unlikely event that this is actually desirable, it
+ would be wise to also specify <EM
+>read only
+ access</EM
+>.</P
+><P
+>Note that the <EM
+>browseable</EM
+> flag for
+ auto home directories will be inherited from the global browseable
+ flag, not the [homes] browseable flag. This is useful as
+ it means setting <EM
+>browseable = no</EM
+> in
+ the [homes] section will hide the [homes] share but make
+ any auto home directories visible.</P
+></DIV
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN79"
+></A
+><H3
+>The [printers] section</H3
+><P
+>This section works like [homes],
+ but for printers.</P
+><P
+>If a [printers] section occurs in the
+ configuration file, users are able to connect to any printer
+ specified in the local host's printcap file.</P
+><P
+>When a connection request is made, the existing sections
+ are scanned. If a match is found, it is used. If no match is found,
+ but a [homes] section exists, it is used as described
+ above. Otherwise, the requested section name is treated as a
+ printer name and the appropriate printcap file is scanned to see
+ if the requested section name is a valid printer share name. If
+ a match is found, a new printer share is created by cloning
+ the [printers] section.</P
+><P
+>A few modifications are then made to the newly created
+ share:</P
+><P
+></P
+><UL
+><LI
+><P
+>The share name is set to the located printer
+ name</P
+></LI
+><LI
+><P
+>If no printer name was given, the printer name
+ is set to the located printer name</P
+></LI
+><LI
+><P
+>If the share does not permit guest access and
+ no username was given, the username is set to the located
+ printer name.</P
+></LI
+></UL
+><P
+>Note that the [printers] service MUST be
+ printable - if you specify otherwise, the server will refuse
+ to load the configuration file.</P
+><P
+>Typically the path specified would be that of a
+ world-writeable spool directory with the sticky bit set on
+ it. A typical [printers] entry would look like
+ this:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+><TT
+CLASS="COMPUTEROUTPUT"
+> [printers]
+ path = /usr/spool/public
+ guest ok = yes
+ printable = yes
+ </TT
+></PRE
+></TD
+></TR
+></TABLE
+><P
+>All aliases given for a printer in the printcap file
+ are legitimate printer names as far as the server is concerned.
+ If your printing subsystem doesn't work like that, you will have
+ to set up a pseudo-printcap. This is a file consisting of one or
+ more lines like this:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> <TT
+CLASS="COMPUTEROUTPUT"
+> alias|alias|alias|alias...
+ </TT
+>
+ </PRE
+></TD
+></TR
+></TABLE
+><P
+>Each alias should be an acceptable printer name for
+ your printing subsystem. In the [global] section, specify
+ the new file as your printcap. The server will then only recognize
+ names found in your pseudo-printcap, which of course can contain
+ whatever aliases you like. The same technique could be used
+ simply to limit access to a subset of your local printers.</P
+><P
+>An alias, by the way, is defined as any component of the
+ first entry of a printcap record. Records are separated by newlines,
+ components (if there are more than one) are separated by vertical
+ bar symbols ('|').</P
+><P
+>NOTE: On SYSV systems which use lpstat to determine what
+ printers are defined on the system you may be able to use
+ "printcap name = lpstat" to automatically obtain a list
+ of printers. See the "printcap name" option
+ for more details.</P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN102"
+></A
+><H2
+>PARAMETERS</H2
+><P
+>parameters define the specific attributes of sections.</P
+><P
+>Some parameters are specific to the [global] section
+ (e.g., <EM
+>security</EM
+>). Some parameters are usable
+ in all sections (e.g., <EM
+>create mode</EM
+>). All others
+ are permissible only in normal sections. For the purposes of the
+ following descriptions the [homes] and [printers]
+ sections will be considered normal. The letter <EM
+>G</EM
+>
+ in parentheses indicates that a parameter is specific to the
+ [global] section. The letter <EM
+>S</EM
+>
+ indicates that a parameter can be specified in a service specific
+ section. Note that all <EM
+>S</EM
+> parameters can also be specified in
+ the [global] section - in which case they will define
+ the default behavior for all services.</P
+><P
+>parameters are arranged here in alphabetical order - this may
+ not create best bedfellows, but at least you can find them! Where
+ there are synonyms, the preferred synonym is described, others refer
+ to the preferred synonym.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN112"
+></A
+><H2
+>VARIABLE SUBSTITUTIONS</H2
+><P
+>Many of the strings that are settable in the config file
+ can take substitutions. For example the option "path =
+ /tmp/%u" would be interpreted as "path =
+ /tmp/john" if the user connected with the username john.</P
+><P
+>These substitutions are mostly noted in the descriptions below,
+ but there are some general substitutions which apply whenever they
+ might be relevant. These are:</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>%S</DT
+><DD
+><P
+>the name of the current service, if any.</P
+></DD
+><DT
+>%P</DT
+><DD
+><P
+>the root directory of the current service,
+ if any.</P
+></DD
+><DT
+>%u</DT
+><DD
+><P
+>user name of the current service, if any.</P
+></DD
+><DT
+>%g</DT
+><DD
+><P
+>primary group name of %u.</P
+></DD
+><DT
+>%U</DT
+><DD
+><P
+>session user name (the user name that the client
+ wanted, not necessarily the same as the one they got).</P
+></DD
+><DT
+>%G</DT
+><DD
+><P
+>primary group name of %U.</P
+></DD
+><DT
+>%H</DT
+><DD
+><P
+>the home directory of the user given
+ by %u.</P
+></DD
+><DT
+>%v</DT
+><DD
+><P
+>the Samba version.</P
+></DD
+><DT
+>%h</DT
+><DD
+><P
+>the Internet hostname that Samba is running
+ on.</P
+></DD
+><DT
+>%m</DT
+><DD
+><P
+>the NetBIOS name of the client machine
+ (very useful).</P
+></DD
+><DT
+>%L</DT
+><DD
+><P
+>the NetBIOS name of the server. This allows you
+ to change your config based on what the client calls you. Your
+ server can have a "dual personality".</P
+><P
+>Note that this paramater is not available when Samba listens
+ on port 445, as clients no longer send this information </P
+></DD
+><DT
+>%M</DT
+><DD
+><P
+>the Internet name of the client machine.
+ </P
+></DD
+><DT
+>%N</DT
+><DD
+><P
+>the name of your NIS home directory server.
+ This is obtained from your NIS auto.map entry. If you have
+ not compiled Samba with the <EM
+>--with-automount</EM
+>
+ option then this value will be the same as %L.</P
+></DD
+><DT
+>%p</DT
+><DD
+><P
+>the path of the service's home directory,
+ obtained from your NIS auto.map entry. The NIS auto.map entry
+ is split up as "%N:%p".</P
+></DD
+><DT
+>%R</DT
+><DD
+><P
+>the selected protocol level after
+ protocol negotiation. It can be one of CORE, COREPLUS,
+ LANMAN1, LANMAN2 or NT1.</P
+></DD
+><DT
+>%d</DT
+><DD
+><P
+>The process id of the current server
+ process.</P
+></DD
+><DT
+>%a</DT
+><DD
+><P
+>the architecture of the remote
+ machine. Only some are recognized, and those may not be
+ 100% reliable. It currently recognizes Samba, "WfWg", "Win95",
+ "WinNT", "Win2K", WinXP, and "Win2K3". Anything else will be known as
+ "UNKNOWN". If it gets it wrong then sending a level
+ 3 log to <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+>samba@samba.org
+ </A
+> should allow it to be fixed.</P
+></DD
+><DT
+>%I</DT
+><DD
+><P
+>The IP address of the client machine.</P
+></DD
+><DT
+>%T</DT
+><DD
+><P
+>the current date and time.</P
+></DD
+><DT
+>%$(<TT
+CLASS="REPLACEABLE"
+><I
+>envvar</I
+></TT
+>)</DT
+><DD
+><P
+>The value of the environment variable
+ <TT
+CLASS="REPLACEABLE"
+><I
+>envar</I
+></TT
+>.</P
+></DD
+></DL
+></DIV
+><P
+>There are some quite creative things that can be done
+ with these substitutions and other smb.conf options.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN203"
+></A
+><H2
+>NAME MANGLING</H2
+><P
+>Samba supports "name mangling" so that DOS and
+ Windows clients can use files that don't conform to the 8.3 format.
+ It can also be set to adjust the case of 8.3 format filenames.</P
+><P
+>There are several options that control the way mangling is
+ performed, and they are grouped here rather than listed separately.
+ For the defaults look at the output of the testparm program. </P
+><P
+>All of these options can be set separately for each service
+ (or globally, of course). </P
+><P
+>The options are: </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>mangling method</DT
+><DD
+><P
+> controls the algorithm used for the generating
+ the mangled names. Can take two different values, "hash" and
+ "hash2". "hash" is the default and is the algorithm that has been
+ used in Samba for many years. "hash2" is a newer and considered
+ a better algorithm (generates less collisions) in the names.
+ However, many Win32 applications store the
+ mangled names and so changing to the new algorithm must not be done
+ lightly as these applications may break unless reinstalled.
+ New installations of Samba may set the default to hash2.
+ Default <EM
+>hash</EM
+>.</P
+></DD
+><DT
+>mangle case = yes/no</DT
+><DD
+><P
+> controls if names that have characters that
+ aren't of the "default" case are mangled. For example,
+ if this is yes then a name like "Mail" would be mangled.
+ Default <EM
+>no</EM
+>.</P
+></DD
+><DT
+>case sensitive = yes/no</DT
+><DD
+><P
+>controls whether filenames are case sensitive. If
+ they aren't then Samba must do a filename search and match on passed
+ names. Default <EM
+>no</EM
+>.</P
+></DD
+><DT
+>default case = upper/lower</DT
+><DD
+><P
+>controls what the default case is for new
+ filenames. Default <EM
+>lower</EM
+>.</P
+></DD
+><DT
+>preserve case = yes/no</DT
+><DD
+><P
+>controls if new files are created with the
+ case that the client passes, or if they are forced to be the
+ "default" case. Default <EM
+>yes</EM
+>.
+ </P
+></DD
+><DT
+>short preserve case = yes/no</DT
+><DD
+><P
+>controls if new files which conform to 8.3 syntax,
+ that is all in upper case and of suitable length, are created
+ upper case, or if they are forced to be the "default"
+ case. This option can be use with "preserve case = yes"
+ to permit long filenames to retain their case, while short names
+ are lowercased. Default <EM
+>yes</EM
+>.</P
+></DD
+></DL
+></DIV
+><P
+>By default, Samba 2.2 has the same semantics as a Windows
+ NT server, in that it is case insensitive but case preserving.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN241"
+></A
+><H2
+>NOTE ABOUT USERNAME/PASSWORD VALIDATION</H2
+><P
+>There are a number of ways in which a user can connect
+ to a service. The server uses the following steps in determining
+ if it will allow a connection to a specified service. If all the
+ steps fail, then the connection request is rejected. However, if one of the
+ steps succeeds, then the following steps are not checked.</P
+><P
+>If the service is marked "guest only = yes" and the
+ server is running with share-level security ("security = share")
+ then steps 1 to 5 are skipped.</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>If the client has passed a username/password
+ pair and that username/password pair is validated by the UNIX
+ system's password programs then the connection is made as that
+ username. Note that this includes the
+ \\server\service%<TT
+CLASS="REPLACEABLE"
+><I
+>username</I
+></TT
+> method of passing
+ a username.</P
+></LI
+><LI
+><P
+>If the client has previously registered a username
+ with the system and now supplies a correct password for that
+ username then the connection is allowed.</P
+></LI
+><LI
+><P
+>The client's NetBIOS name and any previously
+ used user names are checked against the supplied password, if
+ they match then the connection is allowed as the corresponding
+ user.</P
+></LI
+><LI
+><P
+>If the client has previously validated a
+ username/password pair with the server and the client has passed
+ the validation token then that username is used. </P
+></LI
+><LI
+><P
+>If a "user = " field is given in the
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file for the service and the client
+ has supplied a password, and that password matches (according to
+ the UNIX system's password checking) with one of the usernames
+ from the "user =" field then the connection is made as
+ the username in the "user =" line. If one
+ of the username in the "user =" list begins with a
+ '@' then that name expands to a list of names in
+ the group of the same name.</P
+></LI
+><LI
+><P
+>If the service is a guest service then a
+ connection is made as the username given in the "guest
+ account =" for the service, irrespective of the
+ supplied password.</P
+></LI
+></OL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN260"
+></A
+><H2
+>COMPLETE LIST OF GLOBAL PARAMETERS</H2
+><P
+>Here is a list of all global parameters. See the section of
+ each parameter for details. Note that some are synonyms.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="#ACLCOMPATIBILITY"
+><TT
+CLASS="PARAMETER"
+><I
+>acl compatibility</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ADDPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>add printer command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ADDSHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>add share command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ADDUSERSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>add user script</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ALLOWTRUSTEDDOMAINS"
+><TT
+CLASS="PARAMETER"
+><I
+>allow trusted domains</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ANNOUNCEAS"
+><TT
+CLASS="PARAMETER"
+><I
+>announce as</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ANNOUNCEVERSION"
+><TT
+CLASS="PARAMETER"
+><I
+>announce version</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#AUTOSERVICES"
+><TT
+CLASS="PARAMETER"
+><I
+>auto services</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BINDINTERFACESONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>bind interfaces only</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BROWSELIST"
+><TT
+CLASS="PARAMETER"
+><I
+>browse list</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CHANGENOTIFYTIMEOUT"
+><TT
+CLASS="PARAMETER"
+><I
+>change notify timeout</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CHANGESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>change share command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CHARACTERSET"
+><TT
+CLASS="PARAMETER"
+><I
+>character set</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CLIENTCODEPAGE"
+><TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CODEPAGEDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>code page directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CODINGSYSTEM"
+><TT
+CLASS="PARAMETER"
+><I
+>coding system</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CONFIGFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>config file</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEADTIME"
+><TT
+CLASS="PARAMETER"
+><I
+>deadtime</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEBUGHIRESTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+>debug hires timestamp</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEBUGPID"
+><TT
+CLASS="PARAMETER"
+><I
+>debug pid</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEBUGTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+>debug timestamp</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEBUGUID"
+><TT
+CLASS="PARAMETER"
+><I
+>debug uid</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEBUGLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>debuglevel</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEFAULT"
+><TT
+CLASS="PARAMETER"
+><I
+>default</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEFAULTSERVICE"
+><TT
+CLASS="PARAMETER"
+><I
+>default service</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DELETEPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>delete printer command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DELETESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>delete share command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DELETEUSERSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>delete user script</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DFREECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>dfree command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DISABLESPOOLSS"
+><TT
+CLASS="PARAMETER"
+><I
+>disable spoolss</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DNSPROXY"
+><TT
+CLASS="PARAMETER"
+><I
+>dns proxy</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOMAINADMINGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>domain admin group</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOMAINGUESTGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>domain guest group</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOMAINLOGONS"
+><TT
+CLASS="PARAMETER"
+><I
+>domain logons</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOMAINMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+>domain master</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypt passwords</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ENHANCEDBROWSING"
+><TT
+CLASS="PARAMETER"
+><I
+>enhanced browsing</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ENUMPORTSCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>enumports command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#GETWDCACHE"
+><TT
+CLASS="PARAMETER"
+><I
+>getwd cache</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HIDELOCALUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>hide local users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HIDEUNREADABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>hide unreadable</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HOMEDIRMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>homedir map</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HOSTMSDFS"
+><TT
+CLASS="PARAMETER"
+><I
+>host msdfs</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HOSTSEQUIV"
+><TT
+CLASS="PARAMETER"
+><I
+>hosts equiv</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#INTERFACES"
+><TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#KEEPALIVE"
+><TT
+CLASS="PARAMETER"
+><I
+>keepalive</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#KERNELOPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>kernel oplocks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LANMANAUTH"
+><TT
+CLASS="PARAMETER"
+><I
+>lanman auth</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LARGEREADWRITE"
+><TT
+CLASS="PARAMETER"
+><I
+>large readwrite</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPADMINDN"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap admin dn</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPFILTER"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap filter</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap port</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap server</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPSSL"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap ssl</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LDAPSUFFIX"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap suffix</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LMANNOUNCE"
+><TT
+CLASS="PARAMETER"
+><I
+>lm announce</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LMINTERVAL"
+><TT
+CLASS="PARAMETER"
+><I
+>lm interval</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOADPRINTERS"
+><TT
+CLASS="PARAMETER"
+><I
+>load printers</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCALMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+>local master</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCKDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>lock dir</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCKDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>lock directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCKSPINCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>lock spin count</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCKSPINTIME"
+><TT
+CLASS="PARAMETER"
+><I
+>lock spin time</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PIDDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>pid directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>log file</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>log level</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGONDRIVE"
+><TT
+CLASS="PARAMETER"
+><I
+>logon drive</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGONHOME"
+><TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGONPATH"
+><TT
+CLASS="PARAMETER"
+><I
+>logon path</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOGONSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>logon script</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LPQCACHETIME"
+><TT
+CLASS="PARAMETER"
+><I
+>lpq cache time</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MACHINEPASSWORDTIMEOUT"
+><TT
+CLASS="PARAMETER"
+><I
+>machine password timeout</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLEDSTACK"
+><TT
+CLASS="PARAMETER"
+><I
+>mangled stack</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLINGMETHOD"
+><TT
+CLASS="PARAMETER"
+><I
+>mangling method</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAPTOGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>map to guest</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXDISKSIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>max disk size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXLOGSIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>max log size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXMUX"
+><TT
+CLASS="PARAMETER"
+><I
+>max mux</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXOPENFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>max open files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXPROTOCOL"
+><TT
+CLASS="PARAMETER"
+><I
+>max protocol</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXSMBDPROCESSES"
+><TT
+CLASS="PARAMETER"
+><I
+>max smbd processes</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXTTL"
+><TT
+CLASS="PARAMETER"
+><I
+>max ttl</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXWINSTTL"
+><TT
+CLASS="PARAMETER"
+><I
+>max wins ttl</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXXMIT"
+><TT
+CLASS="PARAMETER"
+><I
+>max xmit</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MESSAGECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>message command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MINPASSWDLENGTH"
+><TT
+CLASS="PARAMETER"
+><I
+>min passwd length</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MINPASSWORDLENGTH"
+><TT
+CLASS="PARAMETER"
+><I
+>min password length</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MINPROTOCOL"
+><TT
+CLASS="PARAMETER"
+><I
+>min protocol</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MINWINSTTL"
+><TT
+CLASS="PARAMETER"
+><I
+>min wins ttl</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NAMERESOLVEORDER"
+><TT
+CLASS="PARAMETER"
+><I
+>name resolve order</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NETBIOSALIASES"
+><TT
+CLASS="PARAMETER"
+><I
+>netbios aliases</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NETBIOSNAME"
+><TT
+CLASS="PARAMETER"
+><I
+>netbios name</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NETBIOSSCOPE"
+><TT
+CLASS="PARAMETER"
+><I
+>netbios scope</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NISHOMEDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>nis homedir</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NTPIPESUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>nt pipe support</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NTSMBSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>nt smb support</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NTSTATUSSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>nt status support</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NULLPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>null passwords</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OBEYPAMRESTRICTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>obey pam restrictions</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OPLOCKBREAKWAITTIME"
+><TT
+CLASS="PARAMETER"
+><I
+>oplock break wait time</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OSLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>os level</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OS2DRIVERMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>os2 driver map</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PAMPASSWORDCHANGE"
+><TT
+CLASS="PARAMETER"
+><I
+>pam password change</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PANICACTION"
+><TT
+CLASS="PARAMETER"
+><I
+>panic action</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PASSWDCHAT"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd chat</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PASSWDCHATDEBUG"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd chat debug</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PASSWORDLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PASSWORDSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PREFEREDMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+>prefered master</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PREFERREDMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+>preferred master</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRELOAD"
+><TT
+CLASS="PARAMETER"
+><I
+>preload</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTCAP"
+><TT
+CLASS="PARAMETER"
+><I
+>printcap</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTCAPNAME"
+><TT
+CLASS="PARAMETER"
+><I
+>printcap name</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTERDRIVERFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver file</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PROTOCOL"
+><TT
+CLASS="PARAMETER"
+><I
+>protocol</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#READBMPX"
+><TT
+CLASS="PARAMETER"
+><I
+>read bmpx</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#READRAW"
+><TT
+CLASS="PARAMETER"
+><I
+>read raw</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#READSIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>read size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#REMOTEANNOUNCE"
+><TT
+CLASS="PARAMETER"
+><I
+>remote announce</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#REMOTEBROWSESYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>remote browse sync</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#RESTRICTANONYMOUS"
+><TT
+CLASS="PARAMETER"
+><I
+>restrict anonymous</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOT"
+><TT
+CLASS="PARAMETER"
+><I
+>root</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOTDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>root dir</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOTDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>root directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+>security</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SERVERSTRING"
+><TT
+CLASS="PARAMETER"
+><I
+>server string</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SHOWADDPRINTERWIZARD"
+><TT
+CLASS="PARAMETER"
+><I
+>show add printer wizard</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SMBPASSWDFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>smb passwd file</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SOCKETADDRESS"
+><TT
+CLASS="PARAMETER"
+><I
+>socket address</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SOCKETOPTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>socket options</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SOURCEENVIRONMENT"
+><TT
+CLASS="PARAMETER"
+><I
+>source environment</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSL"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCACERTDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl CA certDir</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCACERTFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl CA certFile</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCIPHERS"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl ciphers</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCLIENTCERT"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl client cert</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCLIENTKEY"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl client key</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLCOMPATIBILITY"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl compatibility</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLEGDSOCKET"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl egd socket</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLENTROPYBYTES"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl entropy bytes</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLENTROPYFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl entropy file</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLHOSTS"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl hosts</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLHOSTSRESIGN"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl hosts resign</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLREQUIRECLIENTCERT"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl require clientcert</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLREQUIRESERVERCERT"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl require servercert</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLSERVERCERT"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl server cert</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLSERVERKEY"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl server key</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SSLVERSION"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl version</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STATCACHE"
+><TT
+CLASS="PARAMETER"
+><I
+>stat cache</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STATCACHESIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>stat cache size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STRIPDOT"
+><TT
+CLASS="PARAMETER"
+><I
+>strip dot</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SYSLOG"
+><TT
+CLASS="PARAMETER"
+><I
+>syslog</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SYSLOGONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>syslog only</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TEMPLATEHOMEDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>template homedir</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TEMPLATESHELL"
+><TT
+CLASS="PARAMETER"
+><I
+>template shell</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TIMEOFFSET"
+><TT
+CLASS="PARAMETER"
+><I
+>time offset</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TIMESERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>time server</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TIMESTAMPLOGS"
+><TT
+CLASS="PARAMETER"
+><I
+>timestamp logs</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#TOTALPRINTJOBS"
+><TT
+CLASS="PARAMETER"
+><I
+>total print jobs</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#UNIXEXTENSIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>unix extensions</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#UNIXPASSWORDSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>unix password sync</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#UPDATEENCRYPTED"
+><TT
+CLASS="PARAMETER"
+><I
+>update encrypted</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USEMMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>use mmap</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USERHOSTS"
+><TT
+CLASS="PARAMETER"
+><I
+>use rhosts</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USERNAMELEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>username level</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USERNAMEMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>username map</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#UTMP"
+><TT
+CLASS="PARAMETER"
+><I
+>utmp</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#UTMPDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>utmp directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VALIDCHARS"
+><TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDCACHETIME"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind cache time</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDENUMUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind enum users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDENUMGROUPS"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind enum groups</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDGID"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind gid</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDSEPARATOR"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind separator</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDUID"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind uid</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINBINDUSEDEFAULTDOMAIN"
+><TT
+CLASS="PARAMETER"
+><I
+>winbind use default domain</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINSHOOK"
+><TT
+CLASS="PARAMETER"
+><I
+>wins hook</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINSPROXY"
+><TT
+CLASS="PARAMETER"
+><I
+>wins proxy</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINSSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>wins server</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WINSSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>wins support</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WORKGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITERAW"
+><TT
+CLASS="PARAMETER"
+><I
+>write raw</I
+></TT
+></A
+></P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN996"
+></A
+><H2
+>COMPLETE LIST OF SERVICE PARAMETERS</H2
+><P
+>Here is a list of all service parameters. See the section on
+ each parameter for details. Note that some are synonyms.</P
+><P
+></P
+><UL
+><LI
+><P
+><A
+HREF="#ADMINUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>admin users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ALLOWHOSTS"
+><TT
+CLASS="PARAMETER"
+><I
+>allow hosts</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#AVAILABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>available</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BLOCKINGLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>blocking locks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BLOCKSIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>block size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BROWSABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>browsable</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#BROWSEABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>browseable</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CASESENSITIVE"
+><TT
+CLASS="PARAMETER"
+><I
+>case sensitive</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CASESIGNAMES"
+><TT
+CLASS="PARAMETER"
+><I
+>casesignames</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#COMMENT"
+><TT
+CLASS="PARAMETER"
+><I
+>comment</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#COPY"
+><TT
+CLASS="PARAMETER"
+><I
+>copy</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CREATEMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>create mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#CSCPOLICY"
+><TT
+CLASS="PARAMETER"
+><I
+>csc policy</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEFAULTCASE"
+><TT
+CLASS="PARAMETER"
+><I
+>default case</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DEFAULTDEVMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>default devmode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DELETEREADONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>delete readonly</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DELETEVETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>delete veto files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DENYHOSTS"
+><TT
+CLASS="PARAMETER"
+><I
+>deny hosts</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DIRECTORYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory mask</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>directory mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DONTDESCEND"
+><TT
+CLASS="PARAMETER"
+><I
+>dont descend</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOSFILEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>dos filemode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOSFILETIMERESOLUTION"
+><TT
+CLASS="PARAMETER"
+><I
+>dos filetime resolution</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#DOSFILETIMES"
+><TT
+CLASS="PARAMETER"
+><I
+>dos filetimes</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#EXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>exec</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FAKEDIRECTORYCREATETIMES"
+><TT
+CLASS="PARAMETER"
+><I
+>fake directory create times</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FAKEOPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>fake oplocks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FOLLOWSYMLINKS"
+><TT
+CLASS="PARAMETER"
+><I
+>follow symlinks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCECREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCEDIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCEDIRECTORYSECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force directory security mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCEGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>force group</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCESECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCEUNKNOWNACLUSER"
+><TT
+CLASS="PARAMETER"
+><I
+>force unknown acl user</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FORCEUSER"
+><TT
+CLASS="PARAMETER"
+><I
+>force user</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#FSTYPE"
+><TT
+CLASS="PARAMETER"
+><I
+>fstype</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#GROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>group</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#GUESTOK"
+><TT
+CLASS="PARAMETER"
+><I
+>guest ok</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#GUESTONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>guest only</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HIDEDOTFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>hide dot files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HIDEFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>hide files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HOSTSALLOW"
+><TT
+CLASS="PARAMETER"
+><I
+>hosts allow</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#HOSTSDENY"
+><TT
+CLASS="PARAMETER"
+><I
+>hosts deny</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#INCLUDE"
+><TT
+CLASS="PARAMETER"
+><I
+>include</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#INHERITACLS"
+><TT
+CLASS="PARAMETER"
+><I
+>inherit acls</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#INHERITPERMISSIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>inherit permissions</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#INVALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>invalid users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LEVEL2OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>level2 oplocks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LOCKING"
+><TT
+CLASS="PARAMETER"
+><I
+>locking</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LPPAUSECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>lppause command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LPQCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>lpq command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LPRESUMECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>lpresume command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#LPRMCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>lprm command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAGICOUTPUT"
+><TT
+CLASS="PARAMETER"
+><I
+>magic output</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAGICSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>magic script</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLECASE"
+><TT
+CLASS="PARAMETER"
+><I
+>mangle case</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLEDMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>mangled map</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLEDNAMES"
+><TT
+CLASS="PARAMETER"
+><I
+>mangled names</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MANGLINGCHAR"
+><TT
+CLASS="PARAMETER"
+><I
+>mangling char</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAPARCHIVE"
+><TT
+CLASS="PARAMETER"
+><I
+>map archive</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAPHIDDEN"
+><TT
+CLASS="PARAMETER"
+><I
+>map hidden</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAPSYSTEM"
+><TT
+CLASS="PARAMETER"
+><I
+>map system</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXCONNECTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>max connections</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MAXPRINTJOBS"
+><TT
+CLASS="PARAMETER"
+><I
+>max print jobs</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MINPRINTSPACE"
+><TT
+CLASS="PARAMETER"
+><I
+>min print space</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#MSDFSROOT"
+><TT
+CLASS="PARAMETER"
+><I
+>msdfs root</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#NTACLSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+>nt acl support</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ONLYGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>only guest</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ONLYUSER"
+><TT
+CLASS="PARAMETER"
+><I
+>only user</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OPLOCKCONTENTIONLIMIT"
+><TT
+CLASS="PARAMETER"
+><I
+>oplock contention limit</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PATH"
+><TT
+CLASS="PARAMETER"
+><I
+>path</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#POSIXLOCKING"
+><TT
+CLASS="PARAMETER"
+><I
+>posix locking</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#POSTEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>postexec</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#POSTSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>postscript</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>preexec</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PREEXECCLOSE"
+><TT
+CLASS="PARAMETER"
+><I
+>preexec close</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRESERVECASE"
+><TT
+CLASS="PARAMETER"
+><I
+>preserve case</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>print command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTOK"
+><TT
+CLASS="PARAMETER"
+><I
+>print ok</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>printable</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTER"
+><TT
+CLASS="PARAMETER"
+><I
+>printer</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTERADMIN"
+><TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTERDRIVER"
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTERDRIVERLOCATION"
+><TT
+CLASS="PARAMETER"
+><I
+>printer driver location</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTERNAME"
+><TT
+CLASS="PARAMETER"
+><I
+>printer name</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PROFILEACLS"
+><TT
+CLASS="PARAMETER"
+><I
+>profile acls</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#PUBLIC"
+><TT
+CLASS="PARAMETER"
+><I
+>public</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#QUEUEPAUSECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>queuepause command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#QUEUERESUMECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>queueresume command</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#READLIST"
+><TT
+CLASS="PARAMETER"
+><I
+>read list</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>read only</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOTPOSTEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>root postexec</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOTPREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>root preexec</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#ROOTPREEXECCLOSE"
+><TT
+CLASS="PARAMETER"
+><I
+>root preexec close</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SETDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>set directory</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SHAREMODES"
+><TT
+CLASS="PARAMETER"
+><I
+>share modes</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SHORTPRESERVECASE"
+><TT
+CLASS="PARAMETER"
+><I
+>short preserve case</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STATUS"
+><TT
+CLASS="PARAMETER"
+><I
+>status</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STRICTALLOCATE"
+><TT
+CLASS="PARAMETER"
+><I
+>strict allocate</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STRICTLOCKING"
+><TT
+CLASS="PARAMETER"
+><I
+>strict locking</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#STRICTSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>strict sync</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#SYNCALWAYS"
+><TT
+CLASS="PARAMETER"
+><I
+>sync always</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USECLIENTDRIVER"
+><TT
+CLASS="PARAMETER"
+><I
+>use client driver</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USESENDFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>use sendfile</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USER"
+><TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USERNAME"
+><TT
+CLASS="PARAMETER"
+><I
+>username</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#USERS"
+><TT
+CLASS="PARAMETER"
+><I
+>users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>valid users</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>veto files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VETOOPLOCKFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>veto oplock files</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VFSOBJECT"
+><TT
+CLASS="PARAMETER"
+><I
+>vfs object</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VFSOPTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>vfs options</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#VOLUME"
+><TT
+CLASS="PARAMETER"
+><I
+>volume</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WIDELINKS"
+><TT
+CLASS="PARAMETER"
+><I
+>wide links</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>writable</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITECACHESIZE"
+><TT
+CLASS="PARAMETER"
+><I
+>write cache size</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITELIST"
+><TT
+CLASS="PARAMETER"
+><I
+>write list</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITEOK"
+><TT
+CLASS="PARAMETER"
+><I
+>write ok</I
+></TT
+></A
+></P
+></LI
+><LI
+><P
+><A
+HREF="#WRITEABLE"
+><TT
+CLASS="PARAMETER"
+><I
+>writeable</I
+></TT
+></A
+></P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN1504"
+></A
+><H2
+>EXPLANATION OF EACH PARAMETER</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><A
+NAME="ACLCOMPATIBILITY"
+></A
+>acl compatibility (G)</DT
+><DD
+><P
+>New in Samba 2.2.8 and above, this string parameter tells
+ smbd if it should modify any Windows access control lists created
+ from POSIX access control lists to remove features which are not
+ supported by Windows 2000 but not supported by the Windows NT ACL edit.
+ control.</P
+><P
+>By default this parameter is set automatically by detecting the
+ client type and is set to "true" if the client is Windows NT.</P
+><P
+>Default: <EM
+>client detected</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>acl compatibility = Win2k</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>acl compatibility = winnt</B
+></P
+></DD
+><DT
+><A
+NAME="ADDPRINTERCOMMAND"
+></A
+>add printer command (G)</DT
+><DD
+><P
+>With the introduction of MS-RPC based printing
+ support for Windows NT/2000 clients in Samba 2.2, The MS Add
+ Printer Wizard (APW) icon is now also available in the
+ "Printers..." folder displayed a share listing. The APW
+ allows for printers to be add remotely to a Samba or Windows
+ NT/2000 print server.</P
+><P
+>For a Samba host this means that the printer must be
+ physically added to the underlying printing system. The <TT
+CLASS="PARAMETER"
+><I
+>add
+ printer command</I
+></TT
+> defines a script to be run which
+ will perform the necessary operations for adding the printer
+ to the print system and to add the appropriate service definition
+ to the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file in order that it can be
+ shared by <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+>
+ </A
+>.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>add printer command</I
+></TT
+> is
+ automatically invoked with the following parameter (in
+ order:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>printer name</I
+></TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>share name</I
+></TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>port name</I
+></TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>driver name</I
+></TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>location</I
+></TT
+></P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>Windows 9x driver location</I
+></TT
+>
+ </P
+></LI
+></UL
+><P
+>All parameters are filled in from the PRINTER_INFO_2 structure sent
+ by the Windows NT/2000 client with one exception. The "Windows 9x
+ driver location" parameter is included for backwards compatibility
+ only. The remaining fields in the structure are generated from answers
+ to the APW questions.</P
+><P
+>Once the <TT
+CLASS="PARAMETER"
+><I
+>add printer command</I
+></TT
+> has
+ been executed, <B
+CLASS="COMMAND"
+>smbd</B
+> will reparse the <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> to determine if the share defined by the APW
+ exists. If the sharename is still invalid, then <B
+CLASS="COMMAND"
+>smbd
+ </B
+> will return an ACCESS_DENIED error to the client.</P
+><P
+>See also <A
+HREF="#DELETEPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+> delete printer command</I
+></TT
+></A
+>, <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+></A
+>,
+ <A
+HREF="#SHOWADDPRINTERWIZARD"
+><TT
+CLASS="PARAMETER"
+><I
+>show add
+ printer wizard</I
+></TT
+></A
+></P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>addprinter command = /usr/bin/addprinter
+ </B
+></P
+></DD
+><DT
+><A
+NAME="ADDSHARECOMMAND"
+></A
+>add share command (G)</DT
+><DD
+><P
+>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <TT
+CLASS="PARAMETER"
+><I
+>add share command</I
+></TT
+> is used to define an
+ external program or script which will add a new service definition
+ to <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>. In order to successfully
+ execute the <TT
+CLASS="PARAMETER"
+><I
+>add share command</I
+></TT
+>, <B
+CLASS="COMMAND"
+>smbd</B
+>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </P
+><P
+> When executed, <B
+CLASS="COMMAND"
+>smbd</B
+> will automatically invoke the
+ <TT
+CLASS="PARAMETER"
+><I
+>add share command</I
+></TT
+> with four parameters.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>configFile</I
+></TT
+> - the location
+ of the global <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>shareName</I
+></TT
+> - the name of the new
+ share.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>pathName</I
+></TT
+> - path to an **existing**
+ directory on disk.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>comment</I
+></TT
+> - comment string to associate
+ with the new share.
+ </P
+></LI
+></UL
+><P
+> This parameter is only used for add file shares. To add printer shares,
+ see the <A
+HREF="#ADDPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>add printer
+ command</I
+></TT
+></A
+>.
+ </P
+><P
+> See also <A
+HREF="#CHANGESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>change share
+ command</I
+></TT
+></A
+>, <A
+HREF="#DELETESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>delete share
+ command</I
+></TT
+></A
+>.
+ </P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>add share command = /usr/local/bin/addshare</B
+></P
+></DD
+><DT
+><A
+NAME="ADDUSERSCRIPT"
+></A
+>add user script (G)</DT
+><DD
+><P
+>This is the full pathname to a script that will
+ be run <EM
+>AS ROOT</EM
+> by <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)
+ </A
+> under special circumstances described below.</P
+><P
+>Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server. For sites
+ that use Windows NT account databases as their primary user database
+ creating these users and keeping the user list in sync with the
+ Windows NT PDC is an onerous task. This option allows <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> to create the required UNIX users
+ <EM
+>ON DEMAND</EM
+> when a user accesses the Samba server.</P
+><P
+>In order to use this option, <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+>
+ must <EM
+>NOT</EM
+> be set to <TT
+CLASS="PARAMETER"
+><I
+>security = share</I
+></TT
+>
+ and <TT
+CLASS="PARAMETER"
+><I
+>add user script</I
+></TT
+>
+ must be set to a full pathname for a script that will create a UNIX
+ user given one argument of <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+>, which expands into
+ the UNIX user name to create.</P
+><P
+>When the Windows user attempts to access the Samba server,
+ at login (session setup in the SMB protocol) time, <A
+HREF="smbd.8.html"
+TARGET="_top"
+> smbd</A
+> contacts the <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+> and
+ attempts to authenticate the given user with the given password. If the
+ authentication succeeds then <B
+CLASS="COMMAND"
+>smbd</B
+>
+ attempts to find a UNIX user in the UNIX password database to map the
+ Windows user into. If this lookup fails, and <TT
+CLASS="PARAMETER"
+><I
+>add user script
+ </I
+></TT
+> is set then <B
+CLASS="COMMAND"
+>smbd</B
+> will
+ call the specified script <EM
+>AS ROOT</EM
+>, expanding
+ any <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+> argument to be the user name to create.</P
+><P
+>If this script successfully creates the user then <B
+CLASS="COMMAND"
+>smbd
+ </B
+> will continue on as though the UNIX user
+ already existed. In this way, UNIX users are dynamically created to
+ match existing Windows NT accounts.</P
+><P
+>See also <A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+> security</I
+></TT
+></A
+>, <A
+HREF="#PASSWORDSERVER"
+> <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+></A
+>,
+ <A
+HREF="#DELETEUSERSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>delete user
+ script</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>add user script = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>add user script = /usr/local/samba/bin/add_user
+ %u</B
+></P
+></DD
+><DT
+><A
+NAME="ADMINUSERS"
+></A
+>admin users (S)</DT
+><DD
+><P
+>This is a list of users who will be granted
+ administrative privileges on the share. This means that they
+ will do all file operations as the super-user (root).</P
+><P
+>You should use this option very carefully, as any user in
+ this list will be able to do anything they like on the share,
+ irrespective of file permissions.</P
+><P
+>Default: <EM
+>no admin users</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>admin users = jason</B
+></P
+></DD
+><DT
+><A
+NAME="ALLOWHOSTS"
+></A
+>allow hosts (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#HOSTSALLOW"
+> <TT
+CLASS="PARAMETER"
+><I
+>hosts allow</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="ALLOWTRUSTEDDOMAINS"
+></A
+>allow trusted domains (G)</DT
+><DD
+><P
+>This option only takes effect when the <A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+>security</I
+></TT
+></A
+> option is set to
+ <TT
+CLASS="CONSTANT"
+>server</TT
+> or <TT
+CLASS="CONSTANT"
+>domain</TT
+>.
+ If it is set to no, then attempts to connect to a resource from
+ a domain or workgroup other than the one which <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> is running
+ in will fail, even if that domain is trusted by the remote server
+ doing the authentication.</P
+><P
+>This is useful if you only want your Samba server to
+ serve resources to users in the domain it is a member of. As
+ an example, suppose that there are two domains DOMA and DOMB. DOMB
+ is trusted by DOMA, which contains the Samba server. Under normal
+ circumstances, a user with an account in DOMB can then access the
+ resources of a UNIX account with the same account name on the
+ Samba server even if they do not have an account in DOMA. This
+ can make implementing a security boundary difficult.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>allow trusted domains = yes</B
+></P
+></DD
+><DT
+><A
+NAME="ANNOUNCEAS"
+></A
+>announce as (G)</DT
+><DD
+><P
+>This specifies what type of server
+ <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd</B
+></A
+>
+ will announce itself as, to a network neighborhood browse
+ list. By default this is set to Windows NT. The valid options
+ are : "NT Server" (which can also be written as "NT"),
+ "NT Workstation", "Win95" or "WfW" meaning Windows NT Server,
+ Windows NT Workstation, Windows 95 and Windows for Workgroups
+ respectively. Do not change this parameter unless you have a
+ specific need to stop Samba appearing as an NT server as this
+ may prevent Samba servers from participating as browser servers
+ correctly.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>announce as = NT Server</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>announce as = Win95</B
+></P
+></DD
+><DT
+><A
+NAME="ANNOUNCEVERSION"
+></A
+>announce version (G)</DT
+><DD
+><P
+>This specifies the major and minor version numbers
+ that nmbd will use when announcing itself as a server. The default
+ is 4.9. Do not change this parameter unless you have a specific
+ need to set a Samba server to be a downlevel server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>announce version = 4.9</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>announce version = 2.0</B
+></P
+></DD
+><DT
+><A
+NAME="AUTOSERVICES"
+></A
+>auto services (G)</DT
+><DD
+><P
+>This is a synonym for the <A
+HREF="#PRELOAD"
+> <TT
+CLASS="PARAMETER"
+><I
+>preload</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="AVAILABLE"
+></A
+>available (S)</DT
+><DD
+><P
+>This parameter lets you "turn off" a service. If
+ <TT
+CLASS="PARAMETER"
+><I
+>available = no</I
+></TT
+>, then <EM
+>ALL</EM
+>
+ attempts to connect to the service will fail. Such failures are
+ logged.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>available = yes</B
+></P
+></DD
+><DT
+><A
+NAME="BINDINTERFACESONLY"
+></A
+>bind interfaces only (G)</DT
+><DD
+><P
+>This global parameter allows the Samba admin
+ to limit what interfaces on a machine will serve SMB requests. If
+ affects file service <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> and
+ name service <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> in slightly
+ different ways.</P
+><P
+>For name service it causes <B
+CLASS="COMMAND"
+>nmbd</B
+> to bind
+ to ports 137 and 138 on the interfaces listed in the <A
+HREF="#INTERFACES"
+>interfaces</A
+> parameter. <B
+CLASS="COMMAND"
+>nmbd
+ </B
+> also binds to the "all addresses" interface (0.0.0.0)
+ on ports 137 and 138 for the purposes of reading broadcast messages.
+ If this option is not set then <B
+CLASS="COMMAND"
+>nmbd</B
+> will service
+ name requests on all of these sockets. If <TT
+CLASS="PARAMETER"
+><I
+>bind interfaces
+ only</I
+></TT
+> is set then <B
+CLASS="COMMAND"
+>nmbd</B
+> will check the
+ source address of any packets coming in on the broadcast sockets
+ and discard any that don't match the broadcast addresses of the
+ interfaces in the <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+> parameter list.
+ As unicast packets are received on the other sockets it allows
+ <B
+CLASS="COMMAND"
+>nmbd</B
+> to refuse to serve names to machines that
+ send packets that arrive through any interfaces not listed in the
+ <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+> list. IP Source address spoofing
+ does defeat this simple check, however so it must not be used
+ seriously as a security feature for <B
+CLASS="COMMAND"
+>nmbd</B
+>.</P
+><P
+>For file service it causes <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+>
+ to bind only to the interface list given in the <A
+HREF="#INTERFACES"
+> interfaces</A
+> parameter. This restricts the networks that
+ <B
+CLASS="COMMAND"
+>smbd</B
+> will serve to packets coming in those
+ interfaces. Note that you should not use this parameter for machines
+ that are serving PPP or other intermittent or non-broadcast network
+ interfaces as it will not cope with non-permanent interfaces.</P
+><P
+>If <TT
+CLASS="PARAMETER"
+><I
+>bind interfaces only</I
+></TT
+> is set then
+ unless the network address <EM
+>127.0.0.1</EM
+> is added
+ to the <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+> parameter list <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+>
+ and <A
+HREF="swat.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>swat(8)</B
+></A
+> may
+ not work as expected due to the reasons covered below.</P
+><P
+>To change a users SMB password, the <B
+CLASS="COMMAND"
+>smbpasswd</B
+>
+ by default connects to the <EM
+>localhost - 127.0.0.1</EM
+>
+ address as an SMB client to issue the password change request. If
+ <TT
+CLASS="PARAMETER"
+><I
+>bind interfaces only</I
+></TT
+> is set then unless the
+ network address <EM
+>127.0.0.1</EM
+> is added to the
+ <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+> parameter list then <B
+CLASS="COMMAND"
+> smbpasswd</B
+> will fail to connect in it's default mode.
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+> can be forced to use the primary IP interface
+ of the local host by using its <A
+HREF="smbpasswd.8.html#minusr"
+TARGET="_top"
+> <TT
+CLASS="PARAMETER"
+><I
+>-r <TT
+CLASS="REPLACEABLE"
+><I
+>remote machine</I
+></TT
+></I
+></TT
+>
+ </A
+> parameter, with <TT
+CLASS="REPLACEABLE"
+><I
+>remote machine</I
+></TT
+> set
+ to the IP name of the primary interface of the local host.</P
+><P
+>The <B
+CLASS="COMMAND"
+>swat</B
+> status page tries to connect with
+ <B
+CLASS="COMMAND"
+>smbd</B
+> and <B
+CLASS="COMMAND"
+>nmbd</B
+> at the address
+ <EM
+>127.0.0.1</EM
+> to determine if they are running.
+ Not adding <EM
+>127.0.0.1</EM
+> will cause <B
+CLASS="COMMAND"
+> smbd</B
+> and <B
+CLASS="COMMAND"
+>nmbd</B
+> to always show
+ "not running" even if they really are. This can prevent <B
+CLASS="COMMAND"
+> swat</B
+> from starting/stopping/restarting <B
+CLASS="COMMAND"
+>smbd</B
+>
+ and <B
+CLASS="COMMAND"
+>nmbd</B
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>bind interfaces only = no</B
+></P
+></DD
+><DT
+><A
+NAME="BLOCKSIZE"
+></A
+>block size (S)</DT
+><DD
+><P
+>This parameter controls the behavior of <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> when reporting disk free sizes.
+ By default, this reports a disk block size of 1024 bytes.</P
+><P
+>Changing this parameter may have some effect on the
+ efficiency of client writes, this is not yet confirmed. This
+ parameter was added to allow advanced administrators to change
+ it (usually to a higher value) and test the effect it has on
+ client write performance without re-compiling the code. As this
+ is an experimental option it may be removed in a future release.
+ </P
+><P
+>Changing this option does not change the disk free reporting
+ size, just the block size unit reported to the client.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>block size = 1024</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>block size = 65536</B
+></P
+></DD
+><DT
+><A
+NAME="BLOCKINGLOCKS"
+></A
+>blocking locks (S)</DT
+><DD
+><P
+>This parameter controls the behavior of <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> when given a request by a client
+ to obtain a byte range lock on a region of an open file, and the
+ request has a time limit associated with it.</P
+><P
+>If this parameter is set and the lock range requested
+ cannot be immediately satisfied, Samba 2.2 will internally
+ queue the lock request, and periodically attempt to obtain
+ the lock until the timeout period expires.</P
+><P
+>If this parameter is set to <TT
+CLASS="CONSTANT"
+>no</TT
+>, then
+ Samba 2.2 will behave as previous versions of Samba would and
+ will fail the lock request immediately if the lock range
+ cannot be obtained.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>blocking locks = yes</B
+></P
+></DD
+><DT
+><A
+NAME="BROWSABLE"
+></A
+>browsable (S)</DT
+><DD
+><P
+>See the <A
+HREF="#BROWSEABLE"
+><TT
+CLASS="PARAMETER"
+><I
+> browseable</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="BROWSELIST"
+></A
+>browse list (G)</DT
+><DD
+><P
+>This controls whether <A
+HREF="smbd.8.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> will serve a browse list to
+ a client doing a <B
+CLASS="COMMAND"
+>NetServerEnum</B
+> call. Normally
+ set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>. You should never need to change
+ this.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>browse list = yes</B
+></P
+></DD
+><DT
+><A
+NAME="BROWSEABLE"
+></A
+>browseable (S)</DT
+><DD
+><P
+>This controls whether this share is seen in
+ the list of available shares in a net view and in the browse list.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>browseable = yes</B
+></P
+></DD
+><DT
+><A
+NAME="CASESENSITIVE"
+></A
+>case sensitive (S)</DT
+><DD
+><P
+>See the discussion in the section <A
+HREF="#AEN203"
+>NAME MANGLING</A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>case sensitive = no</B
+></P
+></DD
+><DT
+><A
+NAME="CASESIGNAMES"
+></A
+>casesignames (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#CASESENSITIVE"
+>case
+ sensitive</A
+>.</P
+></DD
+><DT
+><A
+NAME="CHANGENOTIFYTIMEOUT"
+></A
+>change notify timeout (G)</DT
+><DD
+><P
+>This SMB allows a client to tell a server to
+ "watch" a particular directory for any changes and only reply to
+ the SMB request when a change has occurred. Such constant scanning of
+ a directory is expensive under UNIX, hence an <A
+HREF="smbd.8.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> daemon only performs such a scan
+ on each requested directory once every <TT
+CLASS="PARAMETER"
+><I
+>change notify
+ timeout</I
+></TT
+> seconds.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>change notify timeout = 60</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>change notify timeout = 300</B
+></P
+><P
+>Would change the scan time to every 5 minutes.</P
+></DD
+><DT
+><A
+NAME="CHANGESHARECOMMAND"
+></A
+>change share command (G)</DT
+><DD
+><P
+>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <TT
+CLASS="PARAMETER"
+><I
+>change share command</I
+></TT
+> is used to define an
+ external program or script which will modify an existing service definition
+ in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>. In order to successfully
+ execute the <TT
+CLASS="PARAMETER"
+><I
+>change share command</I
+></TT
+>, <B
+CLASS="COMMAND"
+>smbd</B
+>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </P
+><P
+> When executed, <B
+CLASS="COMMAND"
+>smbd</B
+> will automatically invoke the
+ <TT
+CLASS="PARAMETER"
+><I
+>change share command</I
+></TT
+> with four parameters.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>configFile</I
+></TT
+> - the location
+ of the global <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>shareName</I
+></TT
+> - the name of the new
+ share.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>pathName</I
+></TT
+> - path to an **existing**
+ directory on disk.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>comment</I
+></TT
+> - comment string to associate
+ with the new share.
+ </P
+></LI
+></UL
+><P
+> This parameter is only used modify existing file shares definitions. To modify
+ printer shares, use the "Printers..." folder as seen when browsing the Samba host.
+ </P
+><P
+> See also <A
+HREF="#ADDSHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>add share
+ command</I
+></TT
+></A
+>, <A
+HREF="#DELETESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>delete
+ share command</I
+></TT
+></A
+>.
+ </P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>change share command = /usr/local/bin/addshare</B
+></P
+></DD
+><DT
+><A
+NAME="CHARACTERSET"
+></A
+>character set (G)</DT
+><DD
+><P
+>This allows <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> to map incoming filenames
+ from a DOS Code page (see the <A
+HREF="#CLIENTCODEPAGE"
+>client
+ code page</A
+> parameter) to several built in UNIX character sets.
+ The built in code page translations are:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ISO8859-1</TT
+> : Western European
+ UNIX character set. The parameter <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+>
+ <EM
+>MUST</EM
+> be set to code page 850 if the
+ <TT
+CLASS="PARAMETER"
+><I
+>character set</I
+></TT
+> parameter is set to
+ <TT
+CLASS="CONSTANT"
+>ISO8859-1</TT
+> in order for the conversion to the
+ UNIX character set to be done correctly.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ISO8859-2</TT
+> : Eastern European
+ UNIX character set. The parameter <TT
+CLASS="PARAMETER"
+><I
+>client code page
+ </I
+></TT
+> <EM
+>MUST</EM
+> be set to code page 852 if
+ the <TT
+CLASS="PARAMETER"
+><I
+> character set</I
+></TT
+> parameter is set
+ to <TT
+CLASS="CONSTANT"
+>ISO8859-2</TT
+> in order for the conversion
+ to the UNIX character set to be done correctly. </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ISO8859-5</TT
+> : Russian Cyrillic
+ UNIX character set. The parameter <TT
+CLASS="PARAMETER"
+><I
+>client code page
+ </I
+></TT
+> <EM
+>MUST</EM
+> be set to code page
+ 866 if the <TT
+CLASS="PARAMETER"
+><I
+>character set </I
+></TT
+> parameter is
+ set to <TT
+CLASS="CONSTANT"
+>ISO8859-5</TT
+> in order for the conversion
+ to the UNIX character set to be done correctly. </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>ISO8859-7</TT
+> : Greek UNIX
+ character set. The parameter <TT
+CLASS="PARAMETER"
+><I
+>client code page
+ </I
+></TT
+> <EM
+>MUST</EM
+> be set to code page
+ 737 if the <TT
+CLASS="PARAMETER"
+><I
+>character set</I
+></TT
+> parameter is
+ set to <TT
+CLASS="CONSTANT"
+>ISO8859-7</TT
+> in order for the conversion
+ to the UNIX character set to be done correctly.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>KOI8-R</TT
+> : Alternate mapping
+ for Russian Cyrillic UNIX character set. The parameter
+ <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> <EM
+>MUST</EM
+>
+ be set to code page 866 if the <TT
+CLASS="PARAMETER"
+><I
+>character set</I
+></TT
+>
+ parameter is set to <TT
+CLASS="CONSTANT"
+>KOI8-R</TT
+> in order for the
+ conversion to the UNIX character set to be done correctly.</P
+></LI
+></UL
+><P
+><EM
+>BUG</EM
+>. These MSDOS code page to UNIX character
+ set mappings should be dynamic, like the loading of MS DOS code pages,
+ not static.</P
+><P
+>Normally this parameter is not set, meaning no filename
+ translation is done.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>character set = &#60;empty string&#62;</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>character set = ISO8859-1</B
+></P
+></DD
+><DT
+><A
+NAME="CLIENTCODEPAGE"
+></A
+>client code page (G)</DT
+><DD
+><P
+>This parameter specifies the DOS code page
+ that the clients accessing Samba are using. To determine what code
+ page a Windows or DOS client is using, open a DOS command prompt
+ and type the command <B
+CLASS="COMMAND"
+>chcp</B
+>. This will output
+ the code page. The default for USA MS-DOS, Windows 95, and
+ Windows NT releases is code page 437. The default for western
+ European releases of the above operating systems is code page 850.</P
+><P
+>This parameter tells <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+>
+ which of the <TT
+CLASS="FILENAME"
+>codepage.<TT
+CLASS="REPLACEABLE"
+><I
+>XXX</I
+></TT
+>
+ </TT
+> files to dynamically load on startup. These files,
+ described more fully in the manual page <A
+HREF="make_smbcodepage.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>make_smbcodepage(1)</B
+></A
+>, tell <B
+CLASS="COMMAND"
+> smbd</B
+> how to map lower to upper case characters to provide
+ the case insensitivity of filenames that Windows clients expect.</P
+><P
+>Samba currently ships with the following code page files :</P
+><P
+></P
+><UL
+><LI
+><P
+>Code Page 437 - MS-DOS Latin US</P
+></LI
+><LI
+><P
+>Code Page 737 - Windows '95 Greek</P
+></LI
+><LI
+><P
+>Code Page 850 - MS-DOS Latin 1</P
+></LI
+><LI
+><P
+>Code Page 852 - MS-DOS Latin 2</P
+></LI
+><LI
+><P
+>Code Page 861 - MS-DOS Icelandic</P
+></LI
+><LI
+><P
+>Code Page 866 - MS-DOS Cyrillic</P
+></LI
+><LI
+><P
+>Code Page 932 - MS-DOS Japanese SJIS</P
+></LI
+><LI
+><P
+>Code Page 936 - MS-DOS Simplified Chinese</P
+></LI
+><LI
+><P
+>Code Page 949 - MS-DOS Korean Hangul</P
+></LI
+><LI
+><P
+>Code Page 950 - MS-DOS Traditional Chinese</P
+></LI
+></UL
+><P
+>Thus this parameter may have any of the values 437, 737, 850, 852,
+ 861, 932, 936, 949, or 950. If you don't find the codepage you need,
+ read the comments in one of the other codepage files and the
+ <B
+CLASS="COMMAND"
+>make_smbcodepage(1)</B
+> man page and write one. Please
+ remember to donate it back to the Samba user community.</P
+><P
+>This parameter co-operates with the <TT
+CLASS="PARAMETER"
+><I
+>valid
+ chars</I
+></TT
+> parameter in determining what characters are
+ valid in filenames and how capitalization is done. If you set both
+ this parameter and the <TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+> parameter
+ the <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> parameter
+ <EM
+>MUST</EM
+> be set before the <TT
+CLASS="PARAMETER"
+><I
+>valid
+ chars</I
+></TT
+> parameter in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ file. The <TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+> string will then
+ augment the character settings in the <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+>
+ parameter.</P
+><P
+>If not set, <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> defaults
+ to 850.</P
+><P
+>See also : <A
+HREF="#VALIDCHARS"
+><TT
+CLASS="PARAMETER"
+><I
+>valid
+ chars</I
+></TT
+></A
+>, <A
+HREF="#CODEPAGEDIRECTORY"
+> <TT
+CLASS="PARAMETER"
+><I
+>code page directory</I
+></TT
+></A
+></P
+><P
+>Default: <B
+CLASS="COMMAND"
+>client code page = 850</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>client code page = 936</B
+></P
+></DD
+><DT
+><A
+NAME="CODEPAGEDIRECTORY"
+></A
+>code page directory (G)</DT
+><DD
+><P
+>Define the location of the various client code page
+ files.</P
+><P
+>See also <A
+HREF="#CLIENTCODEPAGE"
+><TT
+CLASS="PARAMETER"
+><I
+>client
+ code page</I
+></TT
+></A
+></P
+><P
+>Default: <B
+CLASS="COMMAND"
+>code page directory = ${prefix}/lib/codepages
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>code page directory = /usr/share/samba/codepages
+ </B
+></P
+></DD
+><DT
+><A
+NAME="CODINGSYSTEM"
+></A
+>coding system (G)</DT
+><DD
+><P
+>This parameter is used to determine how incoming
+ Shift-JIS Japanese characters are mapped from the incoming <A
+HREF="#CLIENTCODEPAGE"
+><TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+>
+ </A
+> used by the client, into file names in the UNIX filesystem.
+ Only useful if <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> is set to
+ 932 (Japanese Shift-JIS). The options are :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>SJIS</TT
+> - Shift-JIS. Does no
+ conversion of the incoming filename.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>JIS8, J8BB, J8BH, J8@B,
+ J8@J, J8@H </TT
+> - Convert from incoming Shift-JIS to eight
+ bit JIS code with different shift-in, shift out codes.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>JIS7, J7BB, J7BH, J7@B, J7@J,
+ J7@H </TT
+> - Convert from incoming Shift-JIS to seven bit
+ JIS code with different shift-in, shift out codes.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>JUNET, JUBB, JUBH, JU@B, JU@J, JU@H </TT
+>
+ - Convert from incoming Shift-JIS to JUNET code with different shift-in,
+ shift out codes.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>EUC</TT
+> - Convert an incoming
+ Shift-JIS character to EUC code.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>HEX</TT
+> - Convert an incoming
+ Shift-JIS character to a 3 byte hex representation, i.e.
+ <TT
+CLASS="CONSTANT"
+>:AB</TT
+>.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>CAP</TT
+> - Convert an incoming
+ Shift-JIS character to the 3 byte hex representation used by
+ the Columbia AppleTalk Program (CAP), i.e. <TT
+CLASS="CONSTANT"
+>:AB</TT
+>.
+ This is used for compatibility between Samba and CAP.</P
+></LI
+></UL
+><P
+>Default: <B
+CLASS="COMMAND"
+>coding system = &#60;empty value&#62;</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="COMMENT"
+></A
+>comment (S)</DT
+><DD
+><P
+>This is a text field that is seen next to a share
+ when a client does a queries the server, either via the network
+ neighborhood or via <B
+CLASS="COMMAND"
+>net view</B
+> to list what shares
+ are available.</P
+><P
+>If you want to set the string that is displayed next to the
+ machine name then see the <A
+HREF="#SERVERSTRING"
+><TT
+CLASS="PARAMETER"
+><I
+> server string</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <EM
+>No comment string</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>comment = Fred's Files</B
+></P
+></DD
+><DT
+><A
+NAME="CONFIGFILE"
+></A
+>config file (G)</DT
+><DD
+><P
+>This allows you to override the config file
+ to use, instead of the default (usually <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>).
+ There is a chicken and egg problem here as this option is set
+ in the config file!</P
+><P
+>For this reason, if the name of the config file has changed
+ when the parameters are loaded then it will reload them from
+ the new config file.</P
+><P
+>This option takes the usual substitutions, which can
+ be very useful.</P
+><P
+>If the config file doesn't exist then it won't be loaded
+ (allowing you to special case the config files of just a few
+ clients).</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>config file = /usr/local/samba/lib/smb.conf.%m
+ </B
+></P
+></DD
+><DT
+><A
+NAME="COPY"
+></A
+>copy (S)</DT
+><DD
+><P
+>This parameter allows you to "clone" service
+ entries. The specified service is simply duplicated under the
+ current service's name. Any parameters specified in the current
+ section will override those in the section being copied.</P
+><P
+>This feature lets you set up a 'template' service and
+ create similar services easily. Note that the service being
+ copied must occur earlier in the configuration file than the
+ service doing the copying.</P
+><P
+>Default: <EM
+>no value</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>copy = otherservice</B
+></P
+></DD
+><DT
+><A
+NAME="CREATEMASK"
+></A
+>create mask (S)</DT
+><DD
+><P
+>A synonym for this parameter is
+ <A
+HREF="#CREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>create mode</I
+></TT
+>
+ </A
+>.</P
+><P
+>When a file is created, the necessary permissions are
+ calculated according to the mapping from DOS modes to UNIX
+ permissions, and the resulting UNIX mode is then bit-wise 'AND'ed
+ with this parameter. This parameter may be thought of as a bit-wise
+ MASK for the UNIX modes of a file. Any bit <EM
+>not</EM
+>
+ set here will be removed from the modes set on a file when it is
+ created.</P
+><P
+>The default value of this parameter removes the
+ 'group' and 'other' write and execute bits from the UNIX modes.</P
+><P
+>Following this Samba will bit-wise 'OR' the UNIX mode created
+ from this parameter with the value of the <A
+HREF="#FORCECREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+></A
+>
+ parameter which is set to 000 by default.</P
+><P
+>This parameter does not affect directory modes. See the
+ parameter <A
+HREF="#DIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>directory mode
+ </I
+></TT
+></A
+> for details.</P
+><P
+>See also the <A
+HREF="#FORCECREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ create mode</I
+></TT
+></A
+> parameter for forcing particular mode
+ bits to be set on created files. See also the <A
+HREF="#DIRECTORYMODE"
+> <TT
+CLASS="PARAMETER"
+><I
+>directory mode</I
+></TT
+></A
+> parameter for masking
+ mode bits on created directories. See also the <A
+HREF="#INHERITPERMISSIONS"
+> <TT
+CLASS="PARAMETER"
+><I
+>inherit permissions</I
+></TT
+></A
+> parameter.</P
+><P
+>Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+ a mask on access control lists also, they need to set the <A
+HREF="#SECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>create mask = 0744</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>create mask = 0775</B
+></P
+></DD
+><DT
+><A
+NAME="CREATEMODE"
+></A
+>create mode (S)</DT
+><DD
+><P
+>This is a synonym for <A
+HREF="#CREATEMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> create mask</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="CSCPOLICY"
+></A
+>csc policy (S)</DT
+><DD
+><P
+>This stands for <EM
+>client-side caching
+ policy</EM
+>, and specifies how clients capable of offline
+ caching will cache the files in the share. The valid values
+ are: manual, documents, programs, disable.</P
+><P
+>These values correspond to those used on Windows
+ servers.</P
+><P
+>For example, shares containing roaming profiles can have
+ offline caching disabled using <B
+CLASS="COMMAND"
+>csc policy = disable
+ </B
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>csc policy = manual</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>csc policy = programs</B
+></P
+></DD
+><DT
+><A
+NAME="DEADTIME"
+></A
+>deadtime (G)</DT
+><DD
+><P
+>The value of the parameter (a decimal integer)
+ represents the number of minutes of inactivity before a connection
+ is considered dead, and it is disconnected. The deadtime only takes
+ effect if the number of open files is zero.</P
+><P
+>This is useful to stop a server's resources being
+ exhausted by a large number of inactive connections.</P
+><P
+>Most clients have an auto-reconnect feature when a
+ connection is broken so in most cases this parameter should be
+ transparent to users.</P
+><P
+>Using this parameter with a timeout of a few minutes
+ is recommended for most systems.</P
+><P
+>A deadtime of zero indicates that no auto-disconnection
+ should be performed.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>deadtime = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>deadtime = 15</B
+></P
+></DD
+><DT
+><A
+NAME="DEBUGHIRESTIMESTAMP"
+></A
+>debug hires timestamp (G)</DT
+><DD
+><P
+>Sometimes the timestamps in the log messages
+ are needed with a resolution of higher that seconds, this
+ boolean parameter adds microsecond resolution to the timestamp
+ message header when turned on.</P
+><P
+>Note that the parameter <A
+HREF="#DEBUGTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+> debug timestamp</I
+></TT
+></A
+> must be on for this to have an
+ effect.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>debug hires timestamp = no</B
+></P
+></DD
+><DT
+><A
+NAME="DEBUGPID"
+></A
+>debug pid (G)</DT
+><DD
+><P
+>When using only one log file for more then one
+ forked <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+>-process there may be hard to follow which process
+ outputs which message. This boolean parameter is adds the process-id
+ to the timestamp message headers in the logfile when turned on.</P
+><P
+>Note that the parameter <A
+HREF="#DEBUGTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+> debug timestamp</I
+></TT
+></A
+> must be on for this to have an
+ effect.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>debug pid = no</B
+></P
+></DD
+><DT
+><A
+NAME="DEBUGTIMESTAMP"
+></A
+>debug timestamp (G)</DT
+><DD
+><P
+>Samba 2.2 debug log messages are timestamped
+ by default. If you are running at a high <A
+HREF="#DEBUGLEVEL"
+> <TT
+CLASS="PARAMETER"
+><I
+>debug level</I
+></TT
+></A
+> these timestamps
+ can be distracting. This boolean parameter allows timestamping
+ to be turned off.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>debug timestamp = yes</B
+></P
+></DD
+><DT
+><A
+NAME="DEBUGUID"
+></A
+>debug uid (G)</DT
+><DD
+><P
+>Samba is sometimes run as root and sometime
+ run as the connected user, this boolean parameter inserts the
+ current euid, egid, uid and gid to the timestamp message headers
+ in the log file if turned on.</P
+><P
+>Note that the parameter <A
+HREF="#DEBUGTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+> debug timestamp</I
+></TT
+></A
+> must be on for this to have an
+ effect.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>debug uid = no</B
+></P
+></DD
+><DT
+><A
+NAME="DEBUGLEVEL"
+></A
+>debuglevel (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#LOGLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+> log level</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="DEFAULT"
+></A
+>default (G)</DT
+><DD
+><P
+>A synonym for <A
+HREF="#DEFAULTSERVICE"
+><TT
+CLASS="PARAMETER"
+><I
+> default service</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="DEFAULTCASE"
+></A
+>default case (S)</DT
+><DD
+><P
+>See the section on <A
+HREF="#AEN203"
+> NAME MANGLING</A
+>. Also note the <A
+HREF="#SHORTPRESERVECASE"
+> <TT
+CLASS="PARAMETER"
+><I
+>short preserve case</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>default case = lower</B
+></P
+></DD
+><DT
+><A
+NAME="DEFAULTDEVMODE"
+></A
+>default devmode (S)</DT
+><DD
+><P
+>This parameter is only applicable to <A
+HREF="#PRINTOK"
+>printable</A
+> services. When smbd is serving
+ Printer Drivers to Windows NT/2k/XP clients, each printer on the Samba
+ server has a Device Mode which defines things such as paper size and
+ orientation and duplex settings. The device mode can only correctly be
+ generated by the printer driver itself (which can only be executed on a
+ Win32 platform). Because smbd is unable to execute the driver code
+ to generate the device mode, the default behavior is to set this field
+ to NULL.
+ </P
+><P
+>Most problems with serving printer drivers to Windows NT/2k/XP clients
+ can be traced to a problem with the generated device mode. Certain drivers
+ will do things such as crashing the client's Explorer.exe with a NULL devmode.
+ However, other printer drivers can cause the client's spooler service
+ (spoolsv.exe) to die if the devmode was not created by the driver itself
+ (i.e. smbd generates a default devmode).
+ </P
+><P
+>This parameter should be used with care and tested with the printer
+ driver in question. It is better to leave the device mode to NULL
+ and let the Windows client set the correct values. Because drivers do not
+ do this all the time, setting <B
+CLASS="COMMAND"
+>default devmode = yes</B
+>
+ will instruct smbd to generate a default one.
+ </P
+><P
+>For more information on Windows NT/2k printing and Device Modes,
+ see the <A
+HREF="http://msdn.microsoft.com/"
+TARGET="_top"
+>MSDN documentation</A
+>.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>default devmode = no</B
+></P
+></DD
+><DT
+><A
+NAME="DEFAULTSERVICE"
+></A
+>default service (G)</DT
+><DD
+><P
+>This parameter specifies the name of a service
+ which will be connected to if the service actually requested cannot
+ be found. Note that the square brackets are <EM
+>NOT</EM
+>
+ given in the parameter value (see example below).</P
+><P
+>There is no default value for this parameter. If this
+ parameter is not given, attempting to connect to a nonexistent
+ service results in an error.</P
+><P
+>Typically the default service would be a <A
+HREF="#GUESTOK"
+> <TT
+CLASS="PARAMETER"
+><I
+>guest ok</I
+></TT
+></A
+>, <A
+HREF="#READONLY"
+> <TT
+CLASS="PARAMETER"
+><I
+>read-only</I
+></TT
+></A
+> service.</P
+><P
+>Also note that the apparent service name will be changed
+ to equal that of the requested service, this is very useful as it
+ allows you to use macros like <TT
+CLASS="PARAMETER"
+><I
+>%S</I
+></TT
+> to make
+ a wildcard service.</P
+><P
+>Note also that any "_" characters in the name of the service
+ used in the default service will get mapped to a "/". This allows for
+ interesting things.</P
+><P
+>Example:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ default service = pub
+
+[pub]
+ path = /%S
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+><DT
+><A
+NAME="DELETEPRINTERCOMMAND"
+></A
+>delete printer command (G)</DT
+><DD
+><P
+>With the introduction of MS-RPC based printer
+ support for Windows NT/2000 clients in Samba 2.2, it is now
+ possible to delete printer at run time by issuing the
+ DeletePrinter() RPC call.</P
+><P
+>For a Samba host this means that the printer must be
+ physically deleted from underlying printing system. The <TT
+CLASS="PARAMETER"
+><I
+> deleteprinter command</I
+></TT
+> defines a script to be run which
+ will perform the necessary operations for removing the printer
+ from the print system and from <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>.
+ </P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>delete printer command</I
+></TT
+> is
+ automatically called with only one parameter: <TT
+CLASS="PARAMETER"
+><I
+> "printer name"</I
+></TT
+>.</P
+><P
+>Once the <TT
+CLASS="PARAMETER"
+><I
+>delete printer command</I
+></TT
+> has
+ been executed, <B
+CLASS="COMMAND"
+>smbd</B
+> will reparse the <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> to associated printer no longer exists.
+ If the sharename is still valid, then <B
+CLASS="COMMAND"
+>smbd
+ </B
+> will return an ACCESS_DENIED error to the client.</P
+><P
+>See also <A
+HREF="#ADDPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+> add printer command</I
+></TT
+></A
+>, <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+></A
+>,
+ <A
+HREF="#SHOWADDPRINTERWIZARD"
+><TT
+CLASS="PARAMETER"
+><I
+>show add
+ printer wizard</I
+></TT
+></A
+></P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>deleteprinter command = /usr/bin/removeprinter
+ </B
+></P
+></DD
+><DT
+><A
+NAME="DELETEREADONLY"
+></A
+>delete readonly (S)</DT
+><DD
+><P
+>This parameter allows readonly files to be deleted.
+ This is not normal DOS semantics, but is allowed by UNIX.</P
+><P
+>This option may be useful for running applications such
+ as rcs, where UNIX file ownership prevents changing file
+ permissions, and DOS semantics prevent deletion of a read only file.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>delete readonly = no</B
+></P
+></DD
+><DT
+><A
+NAME="DELETESHARECOMMAND"
+></A
+>delete share command (G)</DT
+><DD
+><P
+>Samba 2.2.0 introduced the ability to dynamically
+ add and delete shares via the Windows NT 4.0 Server Manager. The
+ <TT
+CLASS="PARAMETER"
+><I
+>delete share command</I
+></TT
+> is used to define an
+ external program or script which will remove an existing service
+ definition from <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>. In order to successfully
+ execute the <TT
+CLASS="PARAMETER"
+><I
+>delete share command</I
+></TT
+>, <B
+CLASS="COMMAND"
+>smbd</B
+>
+ requires that the administrator be connected using a root account (i.e.
+ uid == 0).
+ </P
+><P
+> When executed, <B
+CLASS="COMMAND"
+>smbd</B
+> will automatically invoke the
+ <TT
+CLASS="PARAMETER"
+><I
+>delete share command</I
+></TT
+> with two parameters.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>configFile</I
+></TT
+> - the location
+ of the global <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>shareName</I
+></TT
+> - the name of
+ the existing service.
+ </P
+></LI
+></UL
+><P
+> This parameter is only used to remove file shares. To delete printer shares,
+ see the <A
+HREF="#DELETEPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>delete printer
+ command</I
+></TT
+></A
+>.
+ </P
+><P
+> See also <A
+HREF="#ADDSHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>add share
+ command</I
+></TT
+></A
+>, <A
+HREF="#CHANGESHARECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>change
+ share command</I
+></TT
+></A
+>.
+ </P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>delete share command = /usr/local/bin/delshare</B
+></P
+></DD
+><DT
+><A
+NAME="DELETEUSERSCRIPT"
+></A
+>delete user script (G)</DT
+><DD
+><P
+>This is the full pathname to a script that will
+ be run <EM
+>AS ROOT</EM
+> by <A
+HREF="smbd.8.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> under special circumstances
+ described below.</P
+><P
+>Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server. For sites
+ that use Windows NT account databases as their primary user database
+ creating these users and keeping the user list in sync with the
+ Windows NT PDC is an onerous task. This option allows <B
+CLASS="COMMAND"
+> smbd</B
+> to delete the required UNIX users <EM
+>ON
+ DEMAND</EM
+> when a user accesses the Samba server and the
+ Windows NT user no longer exists.</P
+><P
+>In order to use this option, <B
+CLASS="COMMAND"
+>smbd</B
+> must be
+ set to <TT
+CLASS="PARAMETER"
+><I
+>security = domain</I
+></TT
+> or <TT
+CLASS="PARAMETER"
+><I
+>security =
+ user</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>delete user script</I
+></TT
+>
+ must be set to a full pathname for a script
+ that will delete a UNIX user given one argument of <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+>,
+ which expands into the UNIX user name to delete.</P
+><P
+>When the Windows user attempts to access the Samba server,
+ at <EM
+>login</EM
+> (session setup in the SMB protocol)
+ time, <B
+CLASS="COMMAND"
+>smbd</B
+> contacts the <A
+HREF="#PASSWORDSERVER"
+> <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+></A
+> and attempts to authenticate
+ the given user with the given password. If the authentication fails
+ with the specific Domain error code meaning that the user no longer
+ exists then <B
+CLASS="COMMAND"
+>smbd</B
+> attempts to find a UNIX user in
+ the UNIX password database that matches the Windows user account. If
+ this lookup succeeds, and <TT
+CLASS="PARAMETER"
+><I
+>delete user script</I
+></TT
+> is
+ set then <B
+CLASS="COMMAND"
+>smbd</B
+> will all the specified script
+ <EM
+>AS ROOT</EM
+>, expanding any <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+>
+ argument to be the user name to delete.</P
+><P
+>This script should delete the given UNIX username. In this way,
+ UNIX users are dynamically deleted to match existing Windows NT
+ accounts.</P
+><P
+>See also <A
+HREF="#SECURITYEQUALSDOMAIN"
+>security = domain</A
+>,
+ <A
+HREF="#PASSWORDSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+>
+ </A
+>, <A
+HREF="#ADDUSERSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>add user script</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>delete user script = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>delete user script = /usr/local/samba/bin/del_user
+ %u</B
+></P
+></DD
+><DT
+><A
+NAME="DELETEVETOFILES"
+></A
+>delete veto files (S)</DT
+><DD
+><P
+>This option is used when Samba is attempting to
+ delete a directory that contains one or more vetoed directories
+ (see the <A
+HREF="#VETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>veto files</I
+></TT
+></A
+>
+ option). If this option is set to <TT
+CLASS="CONSTANT"
+>no</TT
+> (the default) then if a vetoed
+ directory contains any non-vetoed files or directories then the
+ directory delete will fail. This is usually what you want.</P
+><P
+>If this option is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, then Samba
+ will attempt to recursively delete any files and directories within
+ the vetoed directory. This can be useful for integration with file
+ serving systems such as NetAtalk which create meta-files within
+ directories you might normally veto DOS/Windows users from seeing
+ (e.g. <TT
+CLASS="FILENAME"
+>.AppleDouble</TT
+>)</P
+><P
+>Setting <B
+CLASS="COMMAND"
+>delete veto files = yes</B
+> allows these
+ directories to be transparently deleted when the parent directory
+ is deleted (so long as the user has permissions to do so).</P
+><P
+>See also the <A
+HREF="#VETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>veto
+ files</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>delete veto files = no</B
+></P
+></DD
+><DT
+><A
+NAME="DENYHOSTS"
+></A
+>deny hosts (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#HOSTSDENY"
+><TT
+CLASS="PARAMETER"
+><I
+>hosts
+ deny</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="DFREECOMMAND"
+></A
+>dfree command (G)</DT
+><DD
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>dfree command</I
+></TT
+> setting should
+ only be used on systems where a problem occurs with the internal
+ disk space calculations. This has been known to happen with Ultrix,
+ but may occur with other operating systems. The symptom that was
+ seen was an error of "Abort Retry Ignore" at the end of each
+ directory listing.</P
+><P
+>This setting allows the replacement of the internal routines to
+ calculate the total disk space and amount available with an external
+ routine. The example below gives a possible script that might fulfill
+ this function.</P
+><P
+>The external program will be passed a single parameter indicating
+ a directory in the filesystem being queried. This will typically consist
+ of the string <TT
+CLASS="FILENAME"
+>./</TT
+>. The script should return two
+ integers in ASCII. The first should be the total disk space in blocks,
+ and the second should be the number of available blocks. An optional
+ third return value can give the block size in bytes. The default
+ blocksize is 1024 bytes.</P
+><P
+>Note: Your script should <EM
+>NOT</EM
+> be setuid or
+ setgid and should be owned by (and writeable only by) root!</P
+><P
+>Default: <EM
+>By default internal routines for
+ determining the disk capacity and remaining space will be used.
+ </EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>dfree command = /usr/local/samba/bin/dfree
+ </B
+></P
+><P
+>Where the script dfree (which must be made executable) could be:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>
+ #!/bin/sh
+ df $1 | tail -1 | awk '{print $2" "$4}'
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>or perhaps (on Sys V based systems):</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>
+ #!/bin/sh
+ /usr/bin/df -k $1 | tail -1 | awk '{print $3" "$5}'
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Note that you may have to replace the command names
+ with full path names on some systems.</P
+></DD
+><DT
+><A
+NAME="DIRECTORY"
+></A
+>directory (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#PATH"
+><TT
+CLASS="PARAMETER"
+><I
+>path
+ </I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="DIRECTORYMASK"
+></A
+>directory mask (S)</DT
+><DD
+><P
+>This parameter is the octal modes which are
+ used when converting DOS modes to UNIX modes when creating UNIX
+ directories.</P
+><P
+>When a directory is created, the necessary permissions are
+ calculated according to the mapping from DOS modes to UNIX permissions,
+ and the resulting UNIX mode is then bit-wise 'AND'ed with this
+ parameter. This parameter may be thought of as a bit-wise MASK for
+ the UNIX modes of a directory. Any bit <EM
+>not</EM
+> set
+ here will be removed from the modes set on a directory when it is
+ created.</P
+><P
+>The default value of this parameter removes the 'group'
+ and 'other' write bits from the UNIX mode, allowing only the
+ user who owns the directory to modify it.</P
+><P
+>Following this Samba will bit-wise 'OR' the UNIX mode
+ created from this parameter with the value of the <A
+HREF="#FORCEDIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force directory mode
+ </I
+></TT
+></A
+> parameter. This parameter is set to 000 by
+ default (i.e. no extra mode bits are added).</P
+><P
+>Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+ a mask on access control lists also, they need to set the <A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory security mask</I
+></TT
+></A
+>.</P
+><P
+>See the <A
+HREF="#FORCEDIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ directory mode</I
+></TT
+></A
+> parameter to cause particular mode
+ bits to always be set on created directories.</P
+><P
+>See also the <A
+HREF="#CREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>create mode
+ </I
+></TT
+></A
+> parameter for masking mode bits on created files,
+ and the <A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory
+ security mask</I
+></TT
+></A
+> parameter.</P
+><P
+>Also refer to the <A
+HREF="#INHERITPERMISSIONS"
+><TT
+CLASS="PARAMETER"
+><I
+> inherit permissions</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>directory mask = 0755</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>directory mask = 0775</B
+></P
+></DD
+><DT
+><A
+NAME="DIRECTORYMODE"
+></A
+>directory mode (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#DIRECTORYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> directory mask</I
+></TT
+></A
+></P
+></DD
+><DT
+><A
+NAME="DIRECTORYSECURITYMASK"
+></A
+>directory security mask (S)</DT
+><DD
+><P
+>This parameter controls what UNIX permission bits
+ can be modified when a Windows NT client is manipulating the UNIX
+ permission on a directory using the native NT security dialog
+ box.</P
+><P
+>This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits not in
+ this mask from being modified. Essentially, zero bits in this
+ mask may be treated as a set of bits the user is not allowed
+ to change.</P
+><P
+>If not set explicitly this parameter is set to 0777
+ meaning a user is allowed to modify all the user/group/world
+ permissions on a directory.</P
+><P
+><EM
+>Note</EM
+> that users who can access the
+ Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ it as the default of <TT
+CLASS="CONSTANT"
+>0777</TT
+>.</P
+><P
+>See also the <A
+HREF="#FORCEDIRECTORYSECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+> force directory security mode</I
+></TT
+></A
+>, <A
+HREF="#SECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+>,
+ <A
+HREF="#FORCESECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>directory security mask = 0777</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>directory security mask = 0700</B
+></P
+></DD
+><DT
+><A
+NAME="DISABLESPOOLSS"
+></A
+>disable spoolss (G)</DT
+><DD
+><P
+>Enabling this parameter will disables Samba's support
+ for the SPOOLSS set of MS-RPC's and will yield identical behavior
+ as Samba 2.0.x. Windows NT/2000 clients will downgrade to using
+ Lanman style printing commands. Windows 9x/ME will be uneffected by
+ the parameter. However, this will also disable the ability to upload
+ printer drivers to a Samba server via the Windows NT Add Printer
+ Wizard or by using the NT printer properties dialog window. It will
+ also disable the capability of Windows NT/2000 clients to download
+ print drivers from the Samba host upon demand.
+ <EM
+>Be very careful about enabling this parameter.</EM
+>
+ </P
+><P
+>See also <A
+HREF="#USECLIENTDRIVER"
+>use client driver</A
+>
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>disable spoolss = no</B
+></P
+></DD
+><DT
+><A
+NAME="DNSPROXY"
+></A
+>dns proxy (G)</DT
+><DD
+><P
+>Specifies that <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ when acting as a WINS server and finding that a NetBIOS name has not
+ been registered, should treat the NetBIOS name word-for-word as a DNS
+ name and do a lookup with the DNS server for that name on behalf of
+ the name-querying client.</P
+><P
+>Note that the maximum length for a NetBIOS name is 15
+ characters, so the DNS name (or DNS alias) can likewise only be
+ 15 characters, maximum.</P
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> spawns a second copy of itself to do the
+ DNS name lookup requests, as doing a name lookup is a blocking
+ action.</P
+><P
+>See also the parameter <A
+HREF="#WINSSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+> wins support</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>dns proxy = yes</B
+></P
+></DD
+><DT
+><A
+NAME="DOMAINADMINGROUP"
+></A
+>domain admin group (G)</DT
+><DD
+><P
+>This parameter is intended as a temporary solution
+ to enable users to be a member of the "Domain Admins" group when
+ a Samba host is acting as a PDC. A complete solution will be provided
+ by a system for mapping Windows NT/2000 groups onto UNIX groups.
+ Please note that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in standard
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> notation.
+ </P
+><P
+>See also <A
+HREF="#DOMAINGUESTGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>domain
+ guest group</I
+></TT
+></A
+>, <A
+HREF="#DOMAINLOGONS"
+><TT
+CLASS="PARAMETER"
+><I
+>domain
+ logons</I
+></TT
+></A
+>
+ </P
+><P
+>Default: <EM
+>no domain administrators</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>domain admin group = root @wheel</B
+></P
+></DD
+><DT
+><A
+NAME="DOMAINGUESTGROUP"
+></A
+>domain guest group (G)</DT
+><DD
+><P
+>This parameter is intended as a temporary solution
+ to enable users to be a member of the "Domain Guests" group when
+ a Samba host is acting as a PDC. A complete solution will be provided
+ by a system for mapping Windows NT/2000 groups onto UNIX groups.
+ Please note that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in standard
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> notation.
+ </P
+><P
+>See also <A
+HREF="#DOMAINADMINGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>domain
+ admin group</I
+></TT
+></A
+>, <A
+HREF="#DOMAINLOGONS"
+><TT
+CLASS="PARAMETER"
+><I
+>domain
+ logons</I
+></TT
+></A
+>
+ </P
+><P
+>Default: <EM
+>no domain guests</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>domain guest group = nobody @guest</B
+></P
+></DD
+><DT
+><A
+NAME="DOMAINLOGONS"
+></A
+>domain logons (G)</DT
+><DD
+><P
+>If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, the Samba server will serve
+ Windows 95/98 Domain logons for the <A
+HREF="#WORKGROUP"
+> <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+></A
+> it is in. Samba 2.2 also
+ has limited capability to act as a domain controller for Windows
+ NT 4 Domains. For more details on setting up this feature see
+ the Samba-PDC-HOWTO included in the <TT
+CLASS="FILENAME"
+>htmldocs/</TT
+>
+ directory shipped with the source code.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>domain logons = no</B
+></P
+></DD
+><DT
+><A
+NAME="DOMAINMASTER"
+></A
+>domain master (G)</DT
+><DD
+><P
+>Tell <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> nmbd(8)</B
+></A
+> to enable WAN-wide browse list
+ collation. Setting this option causes <B
+CLASS="COMMAND"
+>nmbd</B
+> to
+ claim a special domain specific NetBIOS name that identifies
+ it as a domain master browser for its given <A
+HREF="#WORKGROUP"
+> <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+></A
+>. Local master browsers
+ in the same <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> on broadcast-isolated
+ subnets will give this <B
+CLASS="COMMAND"
+>nmbd</B
+> their local browse lists,
+ and then ask <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>
+ for a complete copy of the browse list for the whole wide area
+ network. Browser clients will then contact their local master browser,
+ and will receive the domain-wide browse list, instead of just the list
+ for their broadcast-isolated subnet.</P
+><P
+>Note that Windows NT Primary Domain Controllers expect to be
+ able to claim this <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> specific special
+ NetBIOS name that identifies them as domain master browsers for
+ that <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> by default (i.e. there is no
+ way to prevent a Windows NT PDC from attempting to do this). This
+ means that if this parameter is set and <B
+CLASS="COMMAND"
+>nmbd</B
+> claims
+ the special name for a <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> before a Windows
+ NT PDC is able to do so then cross subnet browsing will behave
+ strangely and may fail.</P
+><P
+>If <A
+HREF="#DOMAINLOGONS"
+><B
+CLASS="COMMAND"
+>domain logons = yes</B
+>
+ </A
+>, then the default behavior is to enable the <TT
+CLASS="PARAMETER"
+><I
+>domain
+ master</I
+></TT
+> parameter. If <TT
+CLASS="PARAMETER"
+><I
+>domain logons</I
+></TT
+> is
+ not enabled (the default setting), then neither will <TT
+CLASS="PARAMETER"
+><I
+>domain
+ master</I
+></TT
+> be enabled by default.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>domain master = auto</B
+></P
+></DD
+><DT
+><A
+NAME="DONTDESCEND"
+></A
+>dont descend (S)</DT
+><DD
+><P
+>There are certain directories on some systems
+ (e.g., the <TT
+CLASS="FILENAME"
+>/proc</TT
+> tree under Linux) that are either not
+ of interest to clients or are infinitely deep (recursive). This
+ parameter allows you to specify a comma-delimited list of directories
+ that the server should always show as empty.</P
+><P
+>Note that Samba can be very fussy about the exact format
+ of the "dont descend" entries. For example you may need <TT
+CLASS="FILENAME"
+> ./proc</TT
+> instead of just <TT
+CLASS="FILENAME"
+>/proc</TT
+>.
+ Experimentation is the best policy :-) </P
+><P
+>Default: <EM
+>none (i.e., all directories are OK
+ to descend)</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>dont descend = /proc,/dev</B
+></P
+></DD
+><DT
+><A
+NAME="DOSFILEMODE"
+></A
+>dos filemode (S)</DT
+><DD
+><P
+> The default behavior in Samba is to provide
+ UNIX-like behavior where only the owner of a file/directory is
+ able to change the permissions on it. However, this behavior
+ is often confusing to DOS/Windows users. Enabling this parameter
+ allows a user who has write access to the file (by whatever
+ means) to modify the permissions on it. Note that a user
+ belonging to the group owning the file will not be allowed to
+ change permissions if the group is only granted read access.
+ Ownership of the file/directory is not changed, only the permissions
+ are modified.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>dos filemode = no</B
+></P
+></DD
+><DT
+><A
+NAME="DOSFILETIMERESOLUTION"
+></A
+>dos filetime resolution (S)</DT
+><DD
+><P
+>Under the DOS and Windows FAT filesystem, the finest
+ granularity on time resolution is two seconds. Setting this parameter
+ for a share causes Samba to round the reported time down to the
+ nearest two second boundary when a query call that requires one second
+ resolution is made to <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+>
+ </A
+>.</P
+><P
+>This option is mainly used as a compatibility option for Visual
+ C++ when used against Samba shares. If oplocks are enabled on a
+ share, Visual C++ uses two different time reading calls to check if a
+ file has changed since it was last read. One of these calls uses a
+ one-second granularity, the other uses a two second granularity. As
+ the two second call rounds any odd second down, then if the file has a
+ timestamp of an odd number of seconds then the two timestamps will not
+ match and Visual C++ will keep reporting the file has changed. Setting
+ this option causes the two timestamps to match, and Visual C++ is
+ happy.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>dos filetime resolution = no</B
+></P
+></DD
+><DT
+><A
+NAME="DOSFILETIMES"
+></A
+>dos filetimes (S)</DT
+><DD
+><P
+>Under DOS and Windows, if a user can write to a
+ file they can change the timestamp on it. Under POSIX semantics,
+ only the owner of the file or root may change the timestamp. By
+ default, Samba runs with POSIX semantics and refuses to change the
+ timestamp on a file if the user <B
+CLASS="COMMAND"
+>smbd</B
+> is acting
+ on behalf of is not the file owner. Setting this option to <TT
+CLASS="CONSTANT"
+> yes</TT
+> allows DOS semantics and <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> will change the file
+ timestamp as DOS requires.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>dos filetimes = no</B
+></P
+></DD
+><DT
+><A
+NAME="ENCRYPTPASSWORDS"
+></A
+>encrypt passwords (G)</DT
+><DD
+><P
+>This boolean controls whether encrypted passwords
+ will be negotiated with the client. Note that Windows NT 4.0 SP3 and
+ above and also Windows 98 will by default expect encrypted passwords
+ unless a registry entry is changed. To use encrypted passwords in
+ Samba see the file ENCRYPTION.txt in the Samba documentation
+ directory <TT
+CLASS="FILENAME"
+>docs/</TT
+> shipped with the source code.</P
+><P
+>In order for encrypted passwords to work correctly
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> must either
+ have access to a local <A
+HREF="smbpasswd.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smbpasswd(5)
+ </TT
+></A
+> file (see the <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> smbpasswd(8)</B
+></A
+> program for information on how to set up
+ and maintain this file), or set the <A
+HREF="#SECURITY"
+>security = [server|domain]</A
+> parameter which
+ causes <B
+CLASS="COMMAND"
+>smbd</B
+> to authenticate against another
+ server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>encrypt passwords = no</B
+></P
+></DD
+><DT
+><A
+NAME="ENHANCEDBROWSING"
+></A
+>enhanced browsing (G)</DT
+><DD
+><P
+>This option enables a couple of enhancements to
+ cross-subnet browse propagation that have been added in Samba
+ but which are not standard in Microsoft implementations.
+ </P
+><P
+>The first enhancement to browse propagation consists of a regular
+ wildcard query to a Samba WINS server for all Domain Master Browsers,
+ followed by a browse synchronization with each of the returned
+ DMBs. The second enhancement consists of a regular randomised browse
+ synchronization with all currently known DMBs.</P
+><P
+>You may wish to disable this option if you have a problem with empty
+ workgroups not disappearing from browse lists. Due to the restrictions
+ of the browse protocols these enhancements can cause a empty workgroup
+ to stay around forever which can be annoying.</P
+><P
+>In general you should leave this option enabled as it makes
+ cross-subnet browse propagation much more reliable.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>enhanced browsing = yes</B
+></P
+></DD
+><DT
+><A
+NAME="ENUMPORTSCOMMAND"
+></A
+>enumports command (G)</DT
+><DD
+><P
+>The concept of a "port" is fairly foreign
+ to UNIX hosts. Under Windows NT/2000 print servers, a port
+ is associated with a port monitor and generally takes the form of
+ a local port (i.e. LPT1:, COM1:, FILE:) or a remote port
+ (i.e. LPD Port Monitor, etc...). By default, Samba has only one
+ port defined--<TT
+CLASS="CONSTANT"
+>"Samba Printer Port"</TT
+>. Under
+ Windows NT/2000, all printers must have a valid port name.
+ If you wish to have a list of ports displayed (<B
+CLASS="COMMAND"
+>smbd
+ </B
+> does not use a port name for anything) other than
+ the default <TT
+CLASS="CONSTANT"
+>"Samba Printer Port"</TT
+>, you
+ can define <TT
+CLASS="PARAMETER"
+><I
+>enumports command</I
+></TT
+> to point to
+ a program which should generate a list of ports, one per line,
+ to standard output. This listing will then be used in response
+ to the level 1 and 2 EnumPorts() RPC.</P
+><P
+>Default: <EM
+>no enumports command</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>enumports command = /usr/bin/listports
+ </B
+></P
+></DD
+><DT
+><A
+NAME="EXEC"
+></A
+>exec (S)</DT
+><DD
+><P
+>This is a synonym for <A
+HREF="#PREEXEC"
+> <TT
+CLASS="PARAMETER"
+><I
+>preexec</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="FAKEDIRECTORYCREATETIMES"
+></A
+>fake directory create times (S)</DT
+><DD
+><P
+>NTFS and Windows VFAT file systems keep a create
+ time for all files and directories. This is not the same as the
+ ctime - status change time - that Unix keeps, so Samba by default
+ reports the earliest of the various times Unix does keep. Setting
+ this parameter for a share causes Samba to always report midnight
+ 1-1-1980 as the create time for directories.</P
+><P
+>This option is mainly used as a compatibility option for
+ Visual C++ when used against Samba shares. Visual C++ generated
+ makefiles have the object directory as a dependency for each object
+ file, and a make rule to create the directory. Also, when NMAKE
+ compares timestamps it uses the creation time when examining a
+ directory. Thus the object directory will be created if it does not
+ exist, but once it does exist it will always have an earlier
+ timestamp than the object files it contains.</P
+><P
+>However, Unix time semantics mean that the create time
+ reported by Samba will be updated whenever a file is created or
+ or deleted in the directory. NMAKE finds all object files in
+ the object directory. The timestamp of the last one built is then
+ compared to the timestamp of the object directory. If the
+ directory's timestamp if newer, then all object files
+ will be rebuilt. Enabling this option
+ ensures directories always predate their contents and an NMAKE build
+ will proceed as expected.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>fake directory create times = no</B
+></P
+></DD
+><DT
+><A
+NAME="FAKEOPLOCKS"
+></A
+>fake oplocks (S)</DT
+><DD
+><P
+>Oplocks are the way that SMB clients get permission
+ from a server to locally cache file operations. If a server grants
+ an oplock (opportunistic lock) then the client is free to assume
+ that it is the only one accessing the file and it will aggressively
+ cache file data. With some oplock types the client may even cache
+ file open/close operations. This can give enormous performance benefits.
+ </P
+><P
+>When you set <B
+CLASS="COMMAND"
+>fake oplocks = yes</B
+>, <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> will
+ always grant oplock requests no matter how many clients are using
+ the file.</P
+><P
+>It is generally much better to use the real <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+></A
+> support rather
+ than this parameter.</P
+><P
+>If you enable this option on all read-only shares or
+ shares that you know will only be accessed from one client at a
+ time such as physically read-only media like CDROMs, you will see
+ a big performance improvement on many operations. If you enable
+ this option on shares where multiple clients may be accessing the
+ files read-write at the same time you can get data corruption. Use
+ this option carefully!</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>fake oplocks = no</B
+></P
+></DD
+><DT
+><A
+NAME="FOLLOWSYMLINKS"
+></A
+>follow symlinks (S)</DT
+><DD
+><P
+>This parameter allows the Samba administrator
+ to stop <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>
+ from following symbolic links in a particular share. Setting this
+ parameter to <TT
+CLASS="CONSTANT"
+>no</TT
+> prevents any file or directory
+ that is a symbolic link from being followed (the user will get an
+ error). This option is very useful to stop users from adding a
+ symbolic link to <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> in their home
+ directory for instance. However it will slow filename lookups
+ down slightly.</P
+><P
+>This option is enabled (i.e. <B
+CLASS="COMMAND"
+>smbd</B
+> will
+ follow symbolic links) by default.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>follow symlinks = yes</B
+></P
+></DD
+><DT
+><A
+NAME="FORCECREATEMODE"
+></A
+>force create mode (S)</DT
+><DD
+><P
+>This parameter specifies a set of UNIX mode bit
+ permissions that will <EM
+>always</EM
+> be set on a
+ file created by Samba. This is done by bitwise 'OR'ing these bits onto
+ the mode bits of a file that is being created or having its
+ permissions changed. The default for this parameter is (in octal)
+ 000. The modes in this parameter are bitwise 'OR'ed onto the file
+ mode after the mask set in the <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+>
+ parameter is applied.</P
+><P
+>See also the parameter <A
+HREF="#CREATEMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>create
+ mask</I
+></TT
+></A
+> for details on masking mode bits on files.</P
+><P
+>See also the <A
+HREF="#INHERITPERMISSIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>inherit
+ permissions</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>force create mode = 000</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force create mode = 0755</B
+></P
+><P
+>would force all created files to have read and execute
+ permissions set for 'group' and 'other' as well as the
+ read/write/execute bits set for the 'user'.</P
+></DD
+><DT
+><A
+NAME="FORCEDIRECTORYMODE"
+></A
+>force directory mode (S)</DT
+><DD
+><P
+>This parameter specifies a set of UNIX mode bit
+ permissions that will <EM
+>always</EM
+> be set on a directory
+ created by Samba. This is done by bitwise 'OR'ing these bits onto the
+ mode bits of a directory that is being created. The default for this
+ parameter is (in octal) 0000 which will not add any extra permission
+ bits to a created directory. This operation is done after the mode
+ mask in the parameter <TT
+CLASS="PARAMETER"
+><I
+>directory mask</I
+></TT
+> is
+ applied.</P
+><P
+>See also the parameter <A
+HREF="#DIRECTORYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> directory mask</I
+></TT
+></A
+> for details on masking mode bits
+ on created directories.</P
+><P
+>See also the <A
+HREF="#INHERITPERMISSIONS"
+><TT
+CLASS="PARAMETER"
+><I
+> inherit permissions</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>force directory mode = 000</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force directory mode = 0755</B
+></P
+><P
+>would force all created directories to have read and execute
+ permissions set for 'group' and 'other' as well as the
+ read/write/execute bits set for the 'user'.</P
+></DD
+><DT
+><A
+NAME="FORCEDIRECTORYSECURITYMODE"
+></A
+>force directory
+ security mode (S)</DT
+><DD
+><P
+>This parameter controls what UNIX permission bits
+ can be modified when a Windows NT client is manipulating the UNIX
+ permission on a directory using the native NT security dialog box.</P
+><P
+>This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this mask that
+ the user may have modified to be on. Essentially, one bits in this
+ mask may be treated as a set of bits that, when modifying security
+ on a directory, the user has always set to be 'on'.</P
+><P
+>If not set explicitly this parameter is 000, which
+ allows a user to modify all the user/group/world permissions on a
+ directory without restrictions.</P
+><P
+><EM
+>Note</EM
+> that users who can access the
+ Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ it set as 0000.</P
+><P
+>See also the <A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> directory security mask</I
+></TT
+></A
+>, <A
+HREF="#SECURITYMASK"
+> <TT
+CLASS="PARAMETER"
+><I
+>security mask</I
+></TT
+></A
+>,
+ <A
+HREF="#FORCESECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force security mode
+ </I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>force directory security mode = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force directory security mode = 700</B
+></P
+></DD
+><DT
+><A
+NAME="FORCEGROUP"
+></A
+>force group (S)</DT
+><DD
+><P
+>This specifies a UNIX group name that will be
+ assigned as the default primary group for all users connecting
+ to this service. This is useful for sharing files by ensuring
+ that all access to files on service will use the named group for
+ their permissions checking. Thus, by assigning permissions for this
+ group to the files and directories within this service the Samba
+ administrator can restrict or allow sharing of these files.</P
+><P
+>In Samba 2.0.5 and above this parameter has extended
+ functionality in the following way. If the group name listed here
+ has a '+' character prepended to it then the current user accessing
+ the share only has the primary group default assigned to this group
+ if they are already assigned as a member of that group. This allows
+ an administrator to decide that only users who are already in a
+ particular group will create files with group ownership set to that
+ group. This gives a finer granularity of ownership assignment. For
+ example, the setting <TT
+CLASS="FILENAME"
+>force group = +sys</TT
+> means
+ that only users who are already in group sys will have their default
+ primary group assigned to sys when accessing this Samba share. All
+ other users will retain their ordinary primary group.</P
+><P
+>If the <A
+HREF="#FORCEUSER"
+><TT
+CLASS="PARAMETER"
+><I
+>force user
+ </I
+></TT
+></A
+> parameter is also set the group specified in
+ <TT
+CLASS="PARAMETER"
+><I
+>force group</I
+></TT
+> will override the primary group
+ set in <TT
+CLASS="PARAMETER"
+><I
+>force user</I
+></TT
+>.</P
+><P
+>See also <A
+HREF="#FORCEUSER"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ user</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>no forced group</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force group = agroup</B
+></P
+></DD
+><DT
+><A
+NAME="FORCESECURITYMODE"
+></A
+>force security mode (S)</DT
+><DD
+><P
+>This parameter controls what UNIX permission
+ bits can be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT security dialog
+ box.</P
+><P
+>This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this mask that
+ the user may have modified to be on. Essentially, one bits in this
+ mask may be treated as a set of bits that, when modifying security
+ on a file, the user has always set to be 'on'.</P
+><P
+>If not set explicitly this parameter is set to 0,
+ and allows a user to modify all the user/group/world permissions on a file,
+ with no restrictions.</P
+><P
+><EM
+>Note</EM
+> that users who can access
+ the Samba server through other means can easily bypass this restriction,
+ so it is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably want to leave
+ this set to 0000.</P
+><P
+>See also the <A
+HREF="#FORCEDIRECTORYSECURITYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+> force directory security mode</I
+></TT
+></A
+>,
+ <A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory security
+ mask</I
+></TT
+></A
+>, <A
+HREF="#SECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> security mask</I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>force security mode = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force security mode = 700</B
+></P
+></DD
+><DT
+><A
+NAME="FORCEUNKNOWNACLUSER"
+></A
+>force unknown acl user (S)</DT
+><DD
+><P
+>If this parameter is set, a Windows NT ACL that contains
+ an unknown SID (security descriptor, or representation of a user or group id)
+ as the owner or group owner of the file will be silently mapped into the
+ current UNIX uid or gid of the currently connected user.</P
+><P
+>This is designed to allow Windows NT clients to copy files and
+ folders containing ACLs that were created locally on the client machine
+ and contain users local to that machine only (no domain users) to be
+ copied to a Samba server (usually with XCOPY /O) and have the unknown
+ userid and groupid of the file owner map to the current connected user.
+ This can only be fixed correctly when winbindd allows arbitrary mapping
+ from any Windows NT SID to a UNIX uid or gid.</P
+><P
+>Try using this parameter when XCOPY /O gives an ACCESS_DENIED error.
+ </P
+><P
+>See also <A
+HREF="#FORCEGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>force group
+ </I
+></TT
+></A
+></P
+><P
+>Default: <EM
+>False</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force unknown acl user = yes</B
+></P
+></DD
+><DT
+><A
+NAME="FORCEUSER"
+></A
+>force user (S)</DT
+><DD
+><P
+>This specifies a UNIX user name that will be
+ assigned as the default user for all users connecting to this service.
+ This is useful for sharing files. You should also use it carefully
+ as using it incorrectly can cause security problems.</P
+><P
+>This user name only gets used once a connection is established.
+ Thus clients still need to connect as a valid user and supply a
+ valid password. Once connected, all file operations will be performed
+ as the "forced user", no matter what username the client connected
+ as. This can be very useful.</P
+><P
+>In Samba 2.0.5 and above this parameter also causes the
+ primary group of the forced user to be used as the primary group
+ for all file activity. Prior to 2.0.5 the primary group was left
+ as the primary group of the connecting user (this was a bug).</P
+><P
+>See also <A
+HREF="#FORCEGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>force group
+ </I
+></TT
+></A
+></P
+><P
+>Default: <EM
+>no forced user</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>force user = auser</B
+></P
+></DD
+><DT
+><A
+NAME="FSTYPE"
+></A
+>fstype (S)</DT
+><DD
+><P
+>This parameter allows the administrator to
+ configure the string that specifies the type of filesystem a share
+ is using that is reported by <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)
+ </B
+></A
+> when a client queries the filesystem type
+ for a share. The default type is <TT
+CLASS="CONSTANT"
+>NTFS</TT
+> for
+ compatibility with Windows NT but this can be changed to other
+ strings such as <TT
+CLASS="CONSTANT"
+>Samba</TT
+> or <TT
+CLASS="CONSTANT"
+>FAT
+ </TT
+> if required.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>fstype = NTFS</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>fstype = Samba</B
+></P
+></DD
+><DT
+><A
+NAME="GETWDCACHE"
+></A
+>getwd cache (G)</DT
+><DD
+><P
+>This is a tuning option. When this is enabled a
+ caching algorithm will be used to reduce the time taken for getwd()
+ calls. This can have a significant impact on performance, especially
+ when the <A
+HREF="#WIDELINKS"
+><TT
+CLASS="PARAMETER"
+><I
+>wide links</I
+></TT
+>
+ </A
+>parameter is set to <TT
+CLASS="CONSTANT"
+>no</TT
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>getwd cache = yes</B
+></P
+></DD
+><DT
+><A
+NAME="GROUP"
+></A
+>group (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#FORCEGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ group</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="GUESTACCOUNT"
+></A
+>guest account (S)</DT
+><DD
+><P
+>This is a username which will be used for access
+ to services which are specified as <A
+HREF="#GUESTOK"
+><TT
+CLASS="PARAMETER"
+><I
+> guest ok</I
+></TT
+></A
+> (see below). Whatever privileges this
+ user has will be available to any client connecting to the guest service.
+ Typically this user will exist in the password file, but will not
+ have a valid login. The user account "ftp" is often a good choice
+ for this parameter. If a username is specified in a given service,
+ the specified username overrides this one.</P
+><P
+>One some systems the default guest account "nobody" may not
+ be able to print. Use another account in this case. You should test
+ this by trying to log in as your guest user (perhaps by using the
+ <B
+CLASS="COMMAND"
+>su -</B
+> command) and trying to print using the
+ system print command such as <B
+CLASS="COMMAND"
+>lpr(1)</B
+> or <B
+CLASS="COMMAND"
+> lp(1)</B
+>.</P
+><P
+>Default: <EM
+>specified at compile time, usually
+ "nobody"</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>guest account = ftp</B
+></P
+></DD
+><DT
+><A
+NAME="GUESTOK"
+></A
+>guest ok (S)</DT
+><DD
+><P
+>If this parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+> for
+ a service, then no password is required to connect to the service.
+ Privileges will be those of the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+> guest account</I
+></TT
+></A
+>.</P
+><P
+>See the section below on <A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+> security</I
+></TT
+></A
+> for more information about this option.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>guest ok = no</B
+></P
+></DD
+><DT
+><A
+NAME="GUESTONLY"
+></A
+>guest only (S)</DT
+><DD
+><P
+>If this parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+> for
+ a service, then only guest connections to the service are permitted.
+ This parameter will have no effect if <A
+HREF="#GUESTOK"
+> <TT
+CLASS="PARAMETER"
+><I
+>guest ok</I
+></TT
+></A
+> is not set for the service.</P
+><P
+>See the section below on <A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+> security</I
+></TT
+></A
+> for more information about this option.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>guest only = no</B
+></P
+></DD
+><DT
+><A
+NAME="HIDEDOTFILES"
+></A
+>hide dot files (S)</DT
+><DD
+><P
+>This is a boolean parameter that controls whether
+ files starting with a dot appear as hidden files.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>hide dot files = yes</B
+></P
+></DD
+><DT
+><A
+NAME="HIDEFILES"
+></A
+>hide files(S)</DT
+><DD
+><P
+>This is a list of files or directories that are not
+ visible but are accessible. The DOS 'hidden' attribute is applied
+ to any files or directories that match.</P
+><P
+>Each entry in the list must be separated by a '/',
+ which allows spaces to be included in the entry. '*'
+ and '?' can be used to specify multiple files or directories
+ as in DOS wildcards.</P
+><P
+>Each entry must be a Unix path, not a DOS path and must
+ not include the Unix directory separator '/'.</P
+><P
+>Note that the case sensitivity option is applicable
+ in hiding files.</P
+><P
+>Setting this parameter will affect the performance of Samba,
+ as it will be forced to check all files and directories for a match
+ as they are scanned.</P
+><P
+>See also <A
+HREF="#HIDEDOTFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>hide
+ dot files</I
+></TT
+></A
+>, <A
+HREF="#VETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+> veto files</I
+></TT
+></A
+> and <A
+HREF="#CASESENSITIVE"
+> <TT
+CLASS="PARAMETER"
+><I
+>case sensitive</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>no file are hidden</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>hide files =
+ /.*/DesktopFolderDB/TrashFor%m/resource.frk/</B
+></P
+><P
+>The above example is based on files that the Macintosh
+ SMB client (DAVE) available from <A
+HREF="http://www.thursby.com"
+TARGET="_top"
+>
+ Thursby</A
+> creates for internal use, and also still hides
+ all files beginning with a dot.</P
+></DD
+><DT
+><A
+NAME="HIDELOCALUSERS"
+></A
+>hide local users(G)</DT
+><DD
+><P
+>This parameter toggles the hiding of local UNIX
+ users (root, wheel, floppy, etc) from remote clients.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>hide local users = no</B
+></P
+></DD
+><DT
+><A
+NAME="HIDEUNREADABLE"
+></A
+>hide unreadable (S)</DT
+><DD
+><P
+>This parameter prevents clients from seeing the
+ existance of files that cannot be read. Defaults to off.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>hide unreadable = no</B
+></P
+></DD
+><DT
+><A
+NAME="HOMEDIRMAP"
+></A
+>homedir map (G)</DT
+><DD
+><P
+>If<A
+HREF="#NISHOMEDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>nis homedir
+ </I
+></TT
+></A
+> is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, and <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> is also acting
+ as a Win95/98 <TT
+CLASS="PARAMETER"
+><I
+>logon server</I
+></TT
+> then this parameter
+ specifies the NIS (or YP) map from which the server for the user's
+ home directory should be extracted. At present, only the Sun
+ auto.home map format is understood. The form of the map is:</P
+><P
+><B
+CLASS="COMMAND"
+>username server:/some/file/system</B
+></P
+><P
+>and the program will extract the servername from before
+ the first ':'. There should probably be a better parsing system
+ that copes with different map formats and also Amd (another
+ automounter) maps.</P
+><P
+><EM
+>NOTE :</EM
+>A working NIS client is required on
+ the system for this option to work.</P
+><P
+>See also <A
+HREF="#NISHOMEDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>nis homedir</I
+></TT
+>
+ </A
+>, <A
+HREF="#DOMAINLOGONS"
+><TT
+CLASS="PARAMETER"
+><I
+>domain logons</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>homedir map = &#60;empty string&#62;</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>homedir map = amd.homedir</B
+></P
+></DD
+><DT
+><A
+NAME="HOSTMSDFS"
+></A
+>host msdfs (G)</DT
+><DD
+><P
+>This boolean parameter is only available
+ if Samba has been configured and compiled with the <B
+CLASS="COMMAND"
+> --with-msdfs</B
+> option. If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>,
+ Samba will act as a Dfs server, and allow Dfs-aware clients
+ to browse Dfs trees hosted on the server.</P
+><P
+>See also the <A
+HREF="#MSDFSROOT"
+><TT
+CLASS="PARAMETER"
+><I
+> msdfs root</I
+></TT
+></A
+> share level parameter. For
+ more information on setting up a Dfs tree on Samba,
+ refer to <A
+HREF="msdfs_setup.html"
+TARGET="_top"
+>msdfs_setup.html</A
+>.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>host msdfs = no</B
+></P
+></DD
+><DT
+><A
+NAME="HOSTSALLOW"
+></A
+>hosts allow (S)</DT
+><DD
+><P
+>A synonym for this parameter is <TT
+CLASS="PARAMETER"
+><I
+>allow
+ hosts</I
+></TT
+>.</P
+><P
+>This parameter is a comma, space, or tab delimited
+ set of hosts which are permitted to access a service.</P
+><P
+>If specified in the [global] section then it will
+ apply to all services, regardless of whether the individual
+ service has a different setting.</P
+><P
+>You can specify the hosts by name or IP number. For
+ example, you could restrict access to only the hosts on a
+ Class C subnet with something like <B
+CLASS="COMMAND"
+>allow hosts = 150.203.5.
+ </B
+>. The full syntax of the list is described in the man
+ page <TT
+CLASS="FILENAME"
+>hosts_access(5)</TT
+>. Note that this man
+ page may not be present on your system, so a brief description will
+ be given here also.</P
+><P
+>Note that the localhost address 127.0.0.1 will always
+ be allowed access unless specifically denied by a <A
+HREF="#HOSTSDENY"
+><TT
+CLASS="PARAMETER"
+><I
+>hosts deny</I
+></TT
+></A
+> option.</P
+><P
+>You can also specify hosts by network/netmask pairs and
+ by netgroup names if your system supports netgroups. The
+ <EM
+>EXCEPT</EM
+> keyword can also be used to limit a
+ wildcard list. The following examples may provide some help:</P
+><P
+>Example 1: allow all IPs in 150.203.*.*; except one</P
+><P
+><B
+CLASS="COMMAND"
+>hosts allow = 150.203. EXCEPT 150.203.6.66</B
+></P
+><P
+>Example 2: allow hosts that match the given network/netmask</P
+><P
+><B
+CLASS="COMMAND"
+>hosts allow = 150.203.15.0/255.255.255.0</B
+></P
+><P
+>Example 3: allow a couple of hosts</P
+><P
+><B
+CLASS="COMMAND"
+>hosts allow = lapland, arvidsjaur</B
+></P
+><P
+>Example 4: allow only hosts in NIS netgroup "foonet", but
+ deny access from one particular host</P
+><P
+><B
+CLASS="COMMAND"
+>hosts allow = @foonet</B
+></P
+><P
+><B
+CLASS="COMMAND"
+>hosts deny = pirate</B
+></P
+><P
+>Note that access still requires suitable user-level passwords.</P
+><P
+>See <A
+HREF="testparm.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>testparm(1)</B
+>
+ </A
+> for a way of testing your host access to see if it does
+ what you expect.</P
+><P
+>Default: <EM
+>none (i.e., all hosts permitted access)
+ </EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>allow hosts = 150.203.5. myhost.mynet.edu.au
+ </B
+></P
+></DD
+><DT
+><A
+NAME="HOSTSDENY"
+></A
+>hosts deny (S)</DT
+><DD
+><P
+>The opposite of <TT
+CLASS="PARAMETER"
+><I
+>hosts allow</I
+></TT
+>
+ - hosts listed here are <EM
+>NOT</EM
+> permitted access to
+ services unless the specific services have their own lists to override
+ this one. Where the lists conflict, the <TT
+CLASS="PARAMETER"
+><I
+>allow</I
+></TT
+>
+ list takes precedence.</P
+><P
+>Default: <EM
+>none (i.e., no hosts specifically excluded)
+ </EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>hosts deny = 150.203.4. badhost.mynet.edu.au
+ </B
+></P
+></DD
+><DT
+><A
+NAME="HOSTSEQUIV"
+></A
+>hosts equiv (G)</DT
+><DD
+><P
+>If this global parameter is a non-null string,
+ it specifies the name of a file to read for the names of hosts
+ and users who will be allowed access without specifying a password.
+ </P
+><P
+>This is not be confused with <A
+HREF="#HOSTSALLOW"
+> <TT
+CLASS="PARAMETER"
+><I
+>hosts allow</I
+></TT
+></A
+> which is about hosts
+ access to services and is more useful for guest services. <TT
+CLASS="PARAMETER"
+><I
+> hosts equiv</I
+></TT
+> may be useful for NT clients which will
+ not supply passwords to Samba.</P
+><P
+><EM
+>NOTE :</EM
+> The use of <TT
+CLASS="PARAMETER"
+><I
+>hosts equiv
+ </I
+></TT
+> can be a major security hole. This is because you are
+ trusting the PC to supply the correct username. It is very easy to
+ get a PC to supply a false username. I recommend that the
+ <TT
+CLASS="PARAMETER"
+><I
+>hosts equiv</I
+></TT
+> option be only used if you really
+ know what you are doing, or perhaps on a home network where you trust
+ your spouse and kids. And only if you <EM
+>really</EM
+> trust
+ them :-).</P
+><P
+>Default: <EM
+>no host equivalences</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>hosts equiv = /etc/hosts.equiv</B
+></P
+></DD
+><DT
+><A
+NAME="INCLUDE"
+></A
+>include (G)</DT
+><DD
+><P
+>This allows you to include one config file
+ inside another. The file is included literally, as though typed
+ in place.</P
+><P
+>It takes the standard substitutions, except <TT
+CLASS="PARAMETER"
+><I
+>%u
+ </I
+></TT
+>, <TT
+CLASS="PARAMETER"
+><I
+>%P</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>%S</I
+></TT
+>.
+ </P
+><P
+>Default: <EM
+>no file included</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>include = /usr/local/samba/lib/admin_smb.conf
+ </B
+></P
+></DD
+><DT
+><A
+NAME="INHERITACLS"
+></A
+>inherit acls (S)</DT
+><DD
+><P
+>This parameter can be used to ensure
+ that if default acls exist on parent directories,
+ they are always honored when creating a subdirectory.
+ The default behavior is to use the mode specified
+ when creating the directory. Enabling this option
+ sets the mode to 0777, thus guaranteeing that
+ default directory acls are propagated.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>inherit acls = no</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="INHERITPERMISSIONS"
+></A
+>inherit permissions (S)</DT
+><DD
+><P
+>The permissions on new files and directories
+ are normally governed by <A
+HREF="#CREATEMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> create mask</I
+></TT
+></A
+>, <A
+HREF="#DIRECTORYMASK"
+> <TT
+CLASS="PARAMETER"
+><I
+>directory mask</I
+></TT
+></A
+>, <A
+HREF="#FORCECREATEMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+>
+ </A
+> and <A
+HREF="#FORCEDIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force
+ directory mode</I
+></TT
+></A
+> but the boolean inherit
+ permissions parameter overrides this.</P
+><P
+>New directories inherit the mode of the parent directory,
+ including bits such as setgid.</P
+><P
+>New files inherit their read/write bits from the parent
+ directory. Their execute bits continue to be determined by
+ <A
+HREF="#MAPARCHIVE"
+><TT
+CLASS="PARAMETER"
+><I
+>map archive</I
+></TT
+>
+ </A
+>, <A
+HREF="#MAPHIDDEN"
+><TT
+CLASS="PARAMETER"
+><I
+>map hidden</I
+></TT
+>
+ </A
+> and <A
+HREF="#MAPSYSTEM"
+><TT
+CLASS="PARAMETER"
+><I
+>map system</I
+></TT
+>
+ </A
+> as usual.</P
+><P
+>Note that the setuid bit is <EM
+>never</EM
+> set via
+ inheritance (the code explicitly prohibits this).</P
+><P
+>This can be particularly useful on large systems with
+ many users, perhaps several thousand, to allow a single [homes]
+ share to be used flexibly by each user.</P
+><P
+>See also <A
+HREF="#CREATEMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>create mask
+ </I
+></TT
+></A
+>, <A
+HREF="#DIRECTORYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+> directory mask</I
+></TT
+></A
+>, <A
+HREF="#FORCECREATEMODE"
+> <TT
+CLASS="PARAMETER"
+><I
+>force create mode</I
+></TT
+></A
+> and <A
+HREF="#FORCEDIRECTORYMODE"
+><TT
+CLASS="PARAMETER"
+><I
+>force directory mode</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>inherit permissions = no</B
+></P
+></DD
+><DT
+><A
+NAME="INTERFACES"
+></A
+>interfaces (G)</DT
+><DD
+><P
+>This option allows you to override the default
+ network interfaces list that Samba will use for browsing, name
+ registration and other NBT traffic. By default Samba will query
+ the kernel for the list of all active interfaces and use any
+ interfaces except 127.0.0.1 that are broadcast capable.</P
+><P
+>The option takes a list of interface strings. Each string
+ can be in any of the following forms:</P
+><P
+></P
+><UL
+><LI
+><P
+>a network interface name (such as eth0).
+ This may include shell-like wildcards so eth* will match
+ any interface starting with the substring "eth"</P
+></LI
+><LI
+><P
+>an IP address. In this case the netmask is
+ determined from the list of interfaces obtained from the
+ kernel</P
+></LI
+><LI
+><P
+>an IP/mask pair. </P
+></LI
+><LI
+><P
+>a broadcast/mask pair.</P
+></LI
+></UL
+><P
+>The "mask" parameters can either be a bit length (such
+ as 24 for a C class network) or a full netmask in dotted
+ decimal form.</P
+><P
+>The "IP" parameters above can either be a full dotted
+ decimal IP address or a hostname which will be looked up via
+ the OS's normal hostname resolution mechanisms.</P
+><P
+>For example, the following line:</P
+><P
+><B
+CLASS="COMMAND"
+>interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0
+ </B
+></P
+><P
+>would configure three network interfaces corresponding
+ to the eth0 device and IP addresses 192.168.2.10 and 192.168.3.10.
+ The netmasks of the latter two interfaces would be set to 255.255.255.0.</P
+><P
+>See also <A
+HREF="#BINDINTERFACESONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>bind
+ interfaces only</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>all active interfaces except 127.0.0.1
+ that are broadcast capable</EM
+></P
+></DD
+><DT
+><A
+NAME="INVALIDUSERS"
+></A
+>invalid users (S)</DT
+><DD
+><P
+>This is a list of users that should not be allowed
+ to login to this service. This is really a <EM
+>paranoid</EM
+>
+ check to absolutely ensure an improper setting does not breach
+ your security.</P
+><P
+>A name starting with a '@' is interpreted as an NIS
+ netgroup first (if your system supports NIS), and then as a UNIX
+ group if the name was not found in the NIS netgroup database.</P
+><P
+>A name starting with '+' is interpreted only
+ by looking in the UNIX group database. A name starting with
+ '&#38;' is interpreted only by looking in the NIS netgroup database
+ (this requires NIS to be working on your system). The characters
+ '+' and '&#38;' may be used at the start of the name in either order
+ so the value <TT
+CLASS="PARAMETER"
+><I
+>+&#38;group</I
+></TT
+> means check the
+ UNIX group database, followed by the NIS netgroup database, and
+ the value <TT
+CLASS="PARAMETER"
+><I
+>&#38;+group</I
+></TT
+> means check the NIS
+ netgroup database, followed by the UNIX group database (the
+ same as the '@' prefix).</P
+><P
+>The current servicename is substituted for <TT
+CLASS="PARAMETER"
+><I
+>%S</I
+></TT
+>.
+ This is useful in the [homes] section.</P
+><P
+>See also <A
+HREF="#VALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>valid users
+ </I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>no invalid users</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>invalid users = root fred admin @wheel
+ </B
+></P
+></DD
+><DT
+><A
+NAME="KEEPALIVE"
+></A
+>keepalive (G)</DT
+><DD
+><P
+>The value of the parameter (an integer) represents
+ the number of seconds between <TT
+CLASS="PARAMETER"
+><I
+>keepalive</I
+></TT
+>
+ packets. If this parameter is zero, no keepalive packets will be
+ sent. Keepalive packets, if sent, allow the server to tell whether
+ a client is still present and responding.</P
+><P
+>Keepalives should, in general, not be needed if the socket
+ being used has the SO_KEEPALIVE attribute set on it (see <A
+HREF="#SOCKETOPTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>socket options</I
+></TT
+></A
+>).
+ Basically you should only use this option if you strike difficulties.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>keepalive = 300</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>keepalive = 600</B
+></P
+></DD
+><DT
+><A
+NAME="KERNELOPLOCKS"
+></A
+>kernel oplocks (G)</DT
+><DD
+><P
+>For UNIXes that support kernel based <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+></A
+>
+ (currently only IRIX and the Linux 2.4 kernel), this parameter
+ allows the use of them to be turned on or off.</P
+><P
+>Kernel oplocks support allows Samba <TT
+CLASS="PARAMETER"
+><I
+>oplocks
+ </I
+></TT
+> to be broken whenever a local UNIX process or NFS operation
+ accesses a file that <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+>
+ </A
+> has oplocked. This allows complete data consistency between
+ SMB/CIFS, NFS and local file access (and is a <EM
+>very</EM
+>
+ cool feature :-).</P
+><P
+>This parameter defaults to <TT
+CLASS="CONSTANT"
+>on</TT
+>, but is translated
+ to a no-op on systems that no not have the necessary kernel support.
+ You should never need to touch this parameter.</P
+><P
+>See also the <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+>
+ </A
+> and <A
+HREF="#LEVEL2OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>level2 oplocks
+ </I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>kernel oplocks = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LANMANAUTH"
+></A
+>lanman auth (G)</DT
+><DD
+><P
+>This parameter determines whether or not <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> will
+ attempt to authenticate users using the LANMAN password hash.
+ If disabled, only clients which support NT password hashes (e.g. Windows
+ NT/2000 clients, smbclient, etc... but not Windows 95/98 or the MS DOS
+ network client) will be able to connect to the Samba host.</P
+><P
+>Default : <B
+CLASS="COMMAND"
+>lanman auth = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LARGEREADWRITE"
+></A
+>large readwrite (G)</DT
+><DD
+><P
+>This parameter determines whether or not <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+>
+ supports the new 64k streaming read and write varient SMB requests introduced
+ with Windows 2000. Note that due to Windows 2000 client redirector bugs
+ this requires Samba to be running on a 64-bit capable operating system such
+ as IRIX, Solaris or a Linux 2.4 kernel. Can improve performance by 10% with
+ Windows 2000 clients. Defaults to on. Windows NT 4.0 only supports
+ read version of this call, and ignores the write version.
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>large readwrite = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LDAPADMINDN"
+></A
+>ldap admin dn (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+> The <TT
+CLASS="PARAMETER"
+><I
+>ldap admin dn</I
+></TT
+> defines the Distinguished
+ Name (DN) name used by Samba to contact the <A
+HREF="#LDAPSERVER"
+>ldap
+ server</A
+> when retreiving user account information. The <TT
+CLASS="PARAMETER"
+><I
+>ldap
+ admin dn</I
+></TT
+> is used in conjunction with the admin dn password
+ stored in the <TT
+CLASS="FILENAME"
+>private/secrets.tdb</TT
+> file. See the
+ <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+> man
+ page for more information on how to accmplish this.
+ </P
+><P
+>Default : <EM
+>none</EM
+></P
+></DD
+><DT
+><A
+NAME="LDAPFILTER"
+></A
+>ldap filter (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+> This parameter specifies the RFC 2254 compliant LDAP search filter.
+ The default is to match the login name with the <TT
+CLASS="CONSTANT"
+>uid</TT
+>
+ attribute for all entries matching the <TT
+CLASS="CONSTANT"
+>sambaAccount</TT
+>
+ objectclass. Note that this filter should only return one entry.
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>ldap filter = (&#38;(uid=%u)(objectclass=sambaAccount))</B
+></P
+></DD
+><DT
+><A
+NAME="LDAPPORT"
+></A
+>ldap port (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+> This option is used to control the tcp port number used to contact
+ the <A
+HREF="#LDAPSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap server</I
+></TT
+></A
+>.
+ The default is to use the stand LDAPS port 636.
+ </P
+><P
+>See Also: <A
+HREF="#LDAPSSL"
+>ldap ssl</A
+>
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>ldap port = 636 ; if ldap ssl = on</B
+></P
+><P
+>Default : <B
+CLASS="COMMAND"
+>ldap port = 389 ; if ldap ssl = off</B
+></P
+></DD
+><DT
+><A
+NAME="LDAPSERVER"
+></A
+>ldap server (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+> This parameter should contains the FQDN of the ldap directory
+ server which should be queried to locate user account information.
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>ldap server = localhost</B
+></P
+></DD
+><DT
+><A
+NAME="LDAPSSL"
+></A
+>ldap ssl (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+> This option is used to define whether or not Samba should
+ use SSL when connecting to the <A
+HREF="#LDAPSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap
+ server</I
+></TT
+></A
+>. This is <EM
+>NOT</EM
+> related to
+ Samba SSL support which is enabled by specifying the
+ <B
+CLASS="COMMAND"
+>--with-ssl</B
+> option to the <TT
+CLASS="FILENAME"
+>configure</TT
+>
+ script (see <A
+HREF="#SSL"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl</I
+></TT
+></A
+>).
+ </P
+><P
+> The <TT
+CLASS="PARAMETER"
+><I
+>ldap ssl</I
+></TT
+> can be set to one of three values:
+ (a) <TT
+CLASS="CONSTANT"
+>on</TT
+> - Always use SSL when contacting the
+ <TT
+CLASS="PARAMETER"
+><I
+>ldap server</I
+></TT
+>, (b) <TT
+CLASS="CONSTANT"
+>off</TT
+> -
+ Never use SSL when querying the directory, or (c) <TT
+CLASS="CONSTANT"
+>start_tls</TT
+>
+ - Use the LDAPv3 StartTLS extended operation
+ (RFC2830) for communicating with the directory server.
+ </P
+><P
+>Default : <B
+CLASS="COMMAND"
+>ldap ssl = on</B
+></P
+></DD
+><DT
+><A
+NAME="LDAPSUFFIX"
+></A
+>ldap suffix (G)</DT
+><DD
+><P
+>This parameter is only available if Samba has been
+ configure to include the <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option
+ at compile time. This option should be considered experimental and
+ under active development.
+ </P
+><P
+>Default : <EM
+>none</EM
+></P
+></DD
+><DT
+><A
+NAME="LEVEL2OPLOCKS"
+></A
+>level2 oplocks (S)</DT
+><DD
+><P
+>This parameter controls whether Samba supports
+ level2 (read-only) oplocks on a share.</P
+><P
+>Level2, or read-only oplocks allow Windows NT clients
+ that have an oplock on a file to downgrade from a read-write oplock
+ to a read-only oplock once a second client opens the file (instead
+ of releasing all oplocks on a second open, as in traditional,
+ exclusive oplocks). This allows all openers of the file that
+ support level2 oplocks to cache the file for read-ahead only (ie.
+ they may not cache writes or lock requests) and increases performance
+ for many accesses of files that are not commonly written (such as
+ application .EXE files).</P
+><P
+>Once one of the clients which have a read-only oplock
+ writes to the file all clients are notified (no reply is needed
+ or waited for) and told to break their oplocks to "none" and
+ delete any read-ahead caches.</P
+><P
+>It is recommended that this parameter be turned on
+ to speed access to shared executables.</P
+><P
+>For more discussions on level2 oplocks see the CIFS spec.</P
+><P
+>Currently, if <A
+HREF="#KERNELOPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>kernel
+ oplocks</I
+></TT
+></A
+> are supported then level2 oplocks are
+ not granted (even if this parameter is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>).
+ Note also, the <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+>
+ </A
+> parameter must be set to <TT
+CLASS="CONSTANT"
+>yes</TT
+> on this share in order for
+ this parameter to have any effect.</P
+><P
+>See also the <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+>
+ </A
+> and <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>kernel oplocks</I
+></TT
+>
+ </A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>level2 oplocks = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LMANNOUNCE"
+></A
+>lm announce (G)</DT
+><DD
+><P
+>This parameter determines if <A
+HREF="nmbd.8.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+> will produce Lanman announce
+ broadcasts that are needed by OS/2 clients in order for them to see
+ the Samba server in their browse list. This parameter can have three
+ values, <TT
+CLASS="CONSTANT"
+>yes</TT
+>, <TT
+CLASS="CONSTANT"
+>no</TT
+>, or
+ <TT
+CLASS="CONSTANT"
+>auto</TT
+>. The default is <TT
+CLASS="CONSTANT"
+>auto</TT
+>.
+ If set to <TT
+CLASS="CONSTANT"
+>no</TT
+> Samba will never produce these
+ broadcasts. If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+> Samba will produce
+ Lanman announce broadcasts at a frequency set by the parameter
+ <TT
+CLASS="PARAMETER"
+><I
+>lm interval</I
+></TT
+>. If set to <TT
+CLASS="CONSTANT"
+>auto</TT
+>
+ Samba will not send Lanman announce broadcasts by default but will
+ listen for them. If it hears such a broadcast on the wire it will
+ then start sending them at a frequency set by the parameter
+ <TT
+CLASS="PARAMETER"
+><I
+>lm interval</I
+></TT
+>.</P
+><P
+>See also <A
+HREF="#LMINTERVAL"
+><TT
+CLASS="PARAMETER"
+><I
+>lm interval
+ </I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lm announce = auto</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>lm announce = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LMINTERVAL"
+></A
+>lm interval (G)</DT
+><DD
+><P
+>If Samba is set to produce Lanman announce
+ broadcasts needed by OS/2 clients (see the <A
+HREF="#LMANNOUNCE"
+> <TT
+CLASS="PARAMETER"
+><I
+>lm announce</I
+></TT
+></A
+> parameter) then this
+ parameter defines the frequency in seconds with which they will be
+ made. If this is set to zero then no Lanman announcements will be
+ made despite the setting of the <TT
+CLASS="PARAMETER"
+><I
+>lm announce</I
+></TT
+>
+ parameter.</P
+><P
+>See also <A
+HREF="#LMANNOUNCE"
+><TT
+CLASS="PARAMETER"
+><I
+>lm
+ announce</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lm interval = 60</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>lm interval = 120</B
+></P
+></DD
+><DT
+><A
+NAME="LOADPRINTERS"
+></A
+>load printers (G)</DT
+><DD
+><P
+>A boolean variable that controls whether all
+ printers in the printcap will be loaded for browsing by default.
+ See the <A
+HREF="#AEN79"
+>printers</A
+> section for
+ more details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>load printers = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LOCALMASTER"
+></A
+>local master (G)</DT
+><DD
+><P
+>This option allows <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> nmbd(8)</B
+></A
+> to try and become a local master browser
+ on a subnet. If set to <TT
+CLASS="CONSTANT"
+>no</TT
+> then <B
+CLASS="COMMAND"
+> nmbd</B
+> will not attempt to become a local master browser
+ on a subnet and will also lose in all browsing elections. By
+ default this value is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>. Setting this value to <TT
+CLASS="CONSTANT"
+>yes</TT
+> doesn't
+ mean that Samba will <EM
+>become</EM
+> the local master
+ browser on a subnet, just that <B
+CLASS="COMMAND"
+>nmbd</B
+> will <EM
+> participate</EM
+> in elections for local master browser.</P
+><P
+>Setting this value to <TT
+CLASS="CONSTANT"
+>no</TT
+> will cause <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ <EM
+>never</EM
+> to become a local master browser.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>local master = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LOCKDIR"
+></A
+>lock dir (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#LOCKDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+> lock directory</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="LOCKDIRECTORY"
+></A
+>lock directory (G)</DT
+><DD
+><P
+>This option specifies the directory where lock
+ files will be placed. The lock files are used to implement the
+ <A
+HREF="#MAXCONNECTIONS"
+><TT
+CLASS="PARAMETER"
+><I
+>max connections</I
+></TT
+>
+ </A
+> option.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lock directory = ${prefix}/var/locks</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>lock directory = /var/run/samba/locks</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="LOCKSPINCOUNT"
+></A
+>lock spin count (G)</DT
+><DD
+><P
+>This parameter controls the number of times
+ that smbd should attempt to gain a byte range lock on the
+ behalf of a client request. Experiments have shown that
+ Windows 2k servers do not reply with a failure if the lock
+ could not be immediately granted, but try a few more times
+ in case the lock could later be aquired. This behavior
+ is used to support PC database formats such as MS Access
+ and FoxPro.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lock spin count = 2</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="LOCKSPINTIME"
+></A
+>lock spin time (G)</DT
+><DD
+><P
+>The time in microseconds that smbd should
+ pause before attempting to gain a failed lock. See
+ <A
+HREF="#LOCKSPINCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>lock spin
+ count</I
+></TT
+></A
+> for more details.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lock spin time = 10</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="LOCKING"
+></A
+>locking (S)</DT
+><DD
+><P
+>This controls whether or not locking will be
+ performed by the server in response to lock requests from the
+ client.</P
+><P
+>If <B
+CLASS="COMMAND"
+>locking = no</B
+>, all lock and unlock
+ requests will appear to succeed and all lock queries will report
+ that the file in question is available for locking.</P
+><P
+>If <B
+CLASS="COMMAND"
+>locking = yes</B
+>, real locking will be performed
+ by the server.</P
+><P
+>This option <EM
+>may</EM
+> be useful for read-only
+ filesystems which <EM
+>may</EM
+> not need locking (such as
+ CDROM drives), although setting this parameter of <TT
+CLASS="CONSTANT"
+>no</TT
+>
+ is not really recommended even in this case.</P
+><P
+>Be careful about disabling locking either globally or in a
+ specific service, as lack of locking may result in data corruption.
+ You should never need to set this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>locking = yes</B
+></P
+></DD
+><DT
+><A
+NAME="LOGFILE"
+></A
+>log file (G)</DT
+><DD
+><P
+>This option allows you to override the name
+ of the Samba log file (also known as the debug file).</P
+><P
+>This option takes the standard substitutions, allowing
+ you to have separate log files for each user or machine.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>log file = /usr/local/samba/var/log.%m
+ </B
+></P
+></DD
+><DT
+><A
+NAME="LOGLEVEL"
+></A
+>log level (G)</DT
+><DD
+><P
+>The value of the parameter (an integer) allows
+ the debug level (logging level) to be specified in the
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. This is to give greater
+ flexibility in the configuration of the system.</P
+><P
+>The default will be the log level specified on
+ the command line or level zero if none was specified.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>log level = 3</B
+></P
+></DD
+><DT
+><A
+NAME="LOGONDRIVE"
+></A
+>logon drive (G)</DT
+><DD
+><P
+>This parameter specifies the local path to
+ which the home directory will be connected (see <A
+HREF="#LOGONHOME"
+><TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+></A
+>)
+ and is only used by NT Workstations. </P
+><P
+>Note that this option is only useful if Samba is set up as a
+ logon server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>logon drive = z:</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>logon drive = h:</B
+></P
+></DD
+><DT
+><A
+NAME="LOGONHOME"
+></A
+>logon home (G)</DT
+><DD
+><P
+>This parameter specifies the home directory
+ location when a Win95/98 or NT Workstation logs into a Samba PDC.
+ It allows you to do </P
+><P
+><TT
+CLASS="PROMPT"
+>C:\&#62; </TT
+><TT
+CLASS="USERINPUT"
+><B
+>NET USE H: /HOME</B
+></TT
+>
+ </P
+><P
+>from a command prompt, for example.</P
+><P
+>This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or machine.</P
+><P
+>This parameter can be used with Win9X workstations to ensure
+ that roaming profiles are stored in a subdirectory of the user's
+ home directory. This is done in the following way:</P
+><P
+><B
+CLASS="COMMAND"
+>logon home = \\%N\%U\profile</B
+></P
+><P
+>This tells Samba to return the above string, with
+ substitutions made when a client requests the info, generally
+ in a NetUserGetInfo request. Win9X clients truncate the info to
+ \\server\share when a user does <B
+CLASS="COMMAND"
+>net use /home</B
+>
+ but use the whole string when dealing with profiles.</P
+><P
+>Note that in prior versions of Samba, the <A
+HREF="#LOGONPATH"
+> <TT
+CLASS="PARAMETER"
+><I
+>logon path</I
+></TT
+></A
+> was returned rather than
+ <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+>. This broke <B
+CLASS="COMMAND"
+>net use
+ /home</B
+> but allowed profiles outside the home directory.
+ The current implementation is correct, and can be used for
+ profiles if you use the above trick.</P
+><P
+>This option is only useful if Samba is set up as a logon
+ server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>logon home = "\\%N\%U"</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>logon home = "\\remote_smb_server\%U"</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="LOGONPATH"
+></A
+>logon path (G)</DT
+><DD
+><P
+>This parameter specifies the home directory
+ where roaming profiles (NTuser.dat etc files for Windows NT) are
+ stored. Contrary to previous versions of these manual pages, it has
+ nothing to do with Win 9X roaming profiles. To find out how to
+ handle roaming profiles for Win 9X system, see the <A
+HREF="#LOGONHOME"
+> <TT
+CLASS="PARAMETER"
+><I
+>logon home</I
+></TT
+></A
+> parameter.</P
+><P
+>This option takes the standard substitutions, allowing you
+ to have separate logon scripts for each user or machine. It also
+ specifies the directory from which the "Application Data",
+ (<TT
+CLASS="FILENAME"
+>desktop</TT
+>, <TT
+CLASS="FILENAME"
+>start menu</TT
+>,
+ <TT
+CLASS="FILENAME"
+>network neighborhood</TT
+>, <TT
+CLASS="FILENAME"
+>programs</TT
+>
+ and other folders, and their contents, are loaded and displayed on
+ your Windows NT client.</P
+><P
+>The share and the path must be readable by the user for
+ the preferences and directories to be loaded onto the Windows NT
+ client. The share must be writeable when the user logs in for the first
+ time, in order that the Windows NT client can create the NTuser.dat
+ and other directories.</P
+><P
+>Thereafter, the directories and any of the contents can,
+ if required, be made read-only. It is not advisable that the
+ NTuser.dat file be made read-only - rename it to NTuser.man to
+ achieve the desired effect (a <EM
+>MAN</EM
+>datory
+ profile). </P
+><P
+>Windows clients can sometimes maintain a connection to
+ the [homes] share, even though there is no user logged in.
+ Therefore, it is vital that the logon path does not include a
+ reference to the homes share (i.e. setting this parameter to
+ \%N\%U\profile_path will cause problems).</P
+><P
+>This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or machine.</P
+><P
+>Note that this option is only useful if Samba is set up
+ as a logon server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>logon path = \\%N\%U\profile</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>logon path = \\PROFILESERVER\PROFILE\%U</B
+></P
+></DD
+><DT
+><A
+NAME="LOGONSCRIPT"
+></A
+>logon script (G)</DT
+><DD
+><P
+>This parameter specifies the batch file (.bat) or
+ NT command file (.cmd) to be downloaded and run on a machine when
+ a user successfully logs in. The file must contain the DOS
+ style CR/LF line endings. Using a DOS-style editor to create the
+ file is recommended.</P
+><P
+>The script must be a relative path to the [netlogon]
+ service. If the [netlogon] service specifies a <A
+HREF="#PATH"
+> <TT
+CLASS="PARAMETER"
+><I
+>path</I
+></TT
+></A
+> of <TT
+CLASS="FILENAME"
+>/usr/local/samba/netlogon
+ </TT
+>, and <B
+CLASS="COMMAND"
+>logon script = STARTUP.BAT</B
+>, then
+ the file that will be downloaded is:</P
+><P
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/netlogon/STARTUP.BAT</TT
+></P
+><P
+>The contents of the batch file are entirely your choice. A
+ suggested command would be to add <B
+CLASS="COMMAND"
+>NET TIME \\SERVER /SET
+ /YES</B
+>, to force every machine to synchronize clocks with
+ the same time server. Another use would be to add <B
+CLASS="COMMAND"
+>NET USE
+ U: \\SERVER\UTILS</B
+> for commonly used utilities, or <B
+CLASS="COMMAND"
+> NET USE Q: \\SERVER\ISO9001_QA</B
+> for example.</P
+><P
+>Note that it is particularly important not to allow write
+ access to the [netlogon] share, or to grant users write permission
+ on the batch files in a secure environment, as this would allow
+ the batch files to be arbitrarily modified and security to be
+ breached.</P
+><P
+>This option takes the standard substitutions, allowing you
+ to have separate logon scripts for each user or machine.</P
+><P
+>This option is only useful if Samba is set up as a logon
+ server.</P
+><P
+>Default: <EM
+>no logon script defined</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>logon script = scripts\%U.bat</B
+></P
+></DD
+><DT
+><A
+NAME="LPPAUSECOMMAND"
+></A
+>lppause command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to stop printing or spooling
+ a specific print job.</P
+><P
+>This command should be a program or script which takes
+ a printer name and job number to pause the print job. One way
+ of implementing this is by using job priorities, where jobs
+ having a too low priority won't be sent to the printer.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. A <TT
+CLASS="PARAMETER"
+><I
+>%j</I
+></TT
+> is replaced with
+ the job number (an integer). On HPUX (see <TT
+CLASS="PARAMETER"
+><I
+>printing=hpux
+ </I
+></TT
+>), if the <TT
+CLASS="PARAMETER"
+><I
+>-p%p</I
+></TT
+> option is added
+ to the lpq command, the job will show up with the correct status, i.e.
+ if the job priority is lower than the set fence priority it will
+ have the PAUSED status, whereas if the priority is equal or higher it
+ will have the SPOOLED or PRINTING status.</P
+><P
+>Note that it is good practice to include the absolute path
+ in the lppause command as the PATH may not be available to the server.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: Currently no default value is given to
+ this string, unless the value of the <TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+>
+ parameter is <TT
+CLASS="CONSTANT"
+>SYSV</TT
+>, in which case the default is :</P
+><P
+><B
+CLASS="COMMAND"
+>lp -i %p-%j -H hold</B
+></P
+><P
+>or if the value of the <TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+> parameter
+ is <TT
+CLASS="CONSTANT"
+>SOFTQ</TT
+>, then the default is:</P
+><P
+><B
+CLASS="COMMAND"
+>qstat -s -j%j -h</B
+></P
+><P
+>Example for HPUX: <B
+CLASS="COMMAND"
+>lppause command = /usr/bin/lpalt
+ %p-%j -p0</B
+></P
+></DD
+><DT
+><A
+NAME="LPQCACHETIME"
+></A
+>lpq cache time (G)</DT
+><DD
+><P
+>This controls how long lpq info will be cached
+ for to prevent the <B
+CLASS="COMMAND"
+>lpq</B
+> command being called too
+ often. A separate cache is kept for each variation of the <B
+CLASS="COMMAND"
+> lpq</B
+> command used by the system, so if you use different
+ <B
+CLASS="COMMAND"
+>lpq</B
+> commands for different users then they won't
+ share cache information.</P
+><P
+>The cache files are stored in <TT
+CLASS="FILENAME"
+>/tmp/lpq.xxxx</TT
+>
+ where xxxx is a hash of the <B
+CLASS="COMMAND"
+>lpq</B
+> command in use.</P
+><P
+>The default is 10 seconds, meaning that the cached results
+ of a previous identical <B
+CLASS="COMMAND"
+>lpq</B
+> command will be used
+ if the cached data is less than 10 seconds old. A large value may
+ be advisable if your <B
+CLASS="COMMAND"
+>lpq</B
+> command is very slow.</P
+><P
+>A value of 0 will disable caching completely.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>lpq cache time = 10</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>lpq cache time = 30</B
+></P
+></DD
+><DT
+><A
+NAME="LPQCOMMAND"
+></A
+>lpq command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to obtain <B
+CLASS="COMMAND"
+>lpq
+ </B
+>-style printer status information.</P
+><P
+>This command should be a program or script which
+ takes a printer name as its only parameter and outputs printer
+ status information.</P
+><P
+>Currently nine styles of printer status information
+ are supported; BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, CUPS, and SOFTQ.
+ This covers most UNIX systems. You control which type is expected
+ using the <TT
+CLASS="PARAMETER"
+><I
+>printing =</I
+></TT
+> option.</P
+><P
+>Some clients (notably Windows for Workgroups) may not
+ correctly send the connection number for the printer they are
+ requesting status information about. To get around this, the
+ server reports on the first printer service connected to by the
+ client. This only happens if the connection number sent is invalid.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the
+ command.</P
+><P
+>Note that it is good practice to include the absolute path
+ in the <TT
+CLASS="PARAMETER"
+><I
+>lpq command</I
+></TT
+> as the <TT
+CLASS="ENVAR"
+>$PATH
+ </TT
+> may not be available to the server. When compiled with
+ the CUPS libraries, no <TT
+CLASS="PARAMETER"
+><I
+>lpq command</I
+></TT
+> is
+ needed because smbd will make a library call to obtain the
+ print queue listing.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <EM
+>depends on the setting of <TT
+CLASS="PARAMETER"
+><I
+> printing</I
+></TT
+></EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>lpq command = /usr/bin/lpq -P%p</B
+></P
+></DD
+><DT
+><A
+NAME="LPRESUMECOMMAND"
+></A
+>lpresume command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to restart or continue
+ printing or spooling a specific print job.</P
+><P
+>This command should be a program or script which takes
+ a printer name and job number to resume the print job. See
+ also the <A
+HREF="#LPPAUSECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>lppause command
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. A <TT
+CLASS="PARAMETER"
+><I
+>%j</I
+></TT
+> is replaced with
+ the job number (an integer).</P
+><P
+>Note that it is good practice to include the absolute path
+ in the <TT
+CLASS="PARAMETER"
+><I
+>lpresume command</I
+></TT
+> as the PATH may not
+ be available to the server.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: Currently no default value is given
+ to this string, unless the value of the <TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+>
+ parameter is <TT
+CLASS="CONSTANT"
+>SYSV</TT
+>, in which case the default is :</P
+><P
+><B
+CLASS="COMMAND"
+>lp -i %p-%j -H resume</B
+></P
+><P
+>or if the value of the <TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+> parameter
+ is <TT
+CLASS="CONSTANT"
+>SOFTQ</TT
+>, then the default is:</P
+><P
+><B
+CLASS="COMMAND"
+>qstat -s -j%j -r</B
+></P
+><P
+>Example for HPUX: <B
+CLASS="COMMAND"
+>lpresume command = /usr/bin/lpalt
+ %p-%j -p2</B
+></P
+></DD
+><DT
+><A
+NAME="LPRMCOMMAND"
+></A
+>lprm command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to delete a print job.</P
+><P
+>This command should be a program or script which takes
+ a printer name and job number, and deletes the print job.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. A <TT
+CLASS="PARAMETER"
+><I
+>%j</I
+></TT
+> is replaced with
+ the job number (an integer).</P
+><P
+>Note that it is good practice to include the absolute
+ path in the <TT
+CLASS="PARAMETER"
+><I
+>lprm command</I
+></TT
+> as the PATH may not be
+ available to the server.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <EM
+>depends on the setting of <TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></EM
+></P
+><P
+>Example 1: <B
+CLASS="COMMAND"
+>lprm command = /usr/bin/lprm -P%p %j
+ </B
+></P
+><P
+>Example 2: <B
+CLASS="COMMAND"
+>lprm command = /usr/bin/cancel %p-%j
+ </B
+></P
+></DD
+><DT
+><A
+NAME="MACHINEPASSWORDTIMEOUT"
+></A
+>machine password timeout (G)</DT
+><DD
+><P
+>If a Samba server is a member of a Windows
+ NT Domain (see the <A
+HREF="#SECURITYEQUALSDOMAIN"
+>security = domain</A
+>)
+ parameter) then periodically a running <A
+HREF="smbd.8.html"
+TARGET="_top"
+> smbd(8)</A
+> process will try and change the MACHINE ACCOUNT
+ PASSWORD stored in the TDB called <TT
+CLASS="FILENAME"
+>private/secrets.tdb
+ </TT
+>. This parameter specifies how often this password
+ will be changed, in seconds. The default is one week (expressed in
+ seconds), the same as a Windows NT Domain member server.</P
+><P
+>See also <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)
+ </B
+></A
+>, and the <A
+HREF="#SECURITYEQUALSDOMAIN"
+> security = domain</A
+>) parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>machine password timeout = 604800</B
+></P
+></DD
+><DT
+><A
+NAME="MAGICOUTPUT"
+></A
+>magic output (S)</DT
+><DD
+><P
+>This parameter specifies the name of a file
+ which will contain output created by a magic script (see the
+ <A
+HREF="#MAGICSCRIPT"
+><TT
+CLASS="PARAMETER"
+><I
+>magic script</I
+></TT
+></A
+>
+ parameter below).</P
+><P
+>Warning: If two clients use the same <TT
+CLASS="PARAMETER"
+><I
+>magic script
+ </I
+></TT
+> in the same directory the output file content
+ is undefined.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>magic output = &#60;magic script name&#62;.out
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>magic output = myfile.txt</B
+></P
+></DD
+><DT
+><A
+NAME="MAGICSCRIPT"
+></A
+>magic script (S)</DT
+><DD
+><P
+>This parameter specifies the name of a file which,
+ if opened, will be executed by the server when the file is closed.
+ This allows a UNIX script to be sent to the Samba host and
+ executed on behalf of the connected user.</P
+><P
+>Scripts executed in this way will be deleted upon
+ completion assuming that the user has the appropriate level
+ of privilege and the file permissions allow the deletion.</P
+><P
+>If the script generates output, output will be sent to
+ the file specified by the <A
+HREF="#MAGICOUTPUT"
+><TT
+CLASS="PARAMETER"
+><I
+> magic output</I
+></TT
+></A
+> parameter (see above).</P
+><P
+>Note that some shells are unable to interpret scripts
+ containing CR/LF instead of CR as
+ the end-of-line marker. Magic scripts must be executable
+ <EM
+>as is</EM
+> on the host, which for some hosts and
+ some shells will require filtering at the DOS end.</P
+><P
+>Magic scripts are <EM
+>EXPERIMENTAL</EM
+> and
+ should <EM
+>NOT</EM
+> be relied upon.</P
+><P
+>Default: <EM
+>None. Magic scripts disabled.</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>magic script = user.csh</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLECASE"
+></A
+>mangle case (S)</DT
+><DD
+><P
+>See the section on <A
+HREF="#AEN203"
+> NAME MANGLING</A
+></P
+><P
+>Default: <B
+CLASS="COMMAND"
+>mangle case = no</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLEDMAP"
+></A
+>mangled map (S)</DT
+><DD
+><P
+>This is for those who want to directly map UNIX
+ file names which cannot be represented on Windows/DOS. The mangling
+ of names is not always what is needed. In particular you may have
+ documents with file extensions that differ between DOS and UNIX.
+ For example, under UNIX it is common to use <TT
+CLASS="FILENAME"
+>.html</TT
+>
+ for HTML files, whereas under Windows/DOS <TT
+CLASS="FILENAME"
+>.htm</TT
+>
+ is more commonly used.</P
+><P
+>So to map <TT
+CLASS="FILENAME"
+>html</TT
+> to <TT
+CLASS="FILENAME"
+>htm</TT
+>
+ you would use:</P
+><P
+><B
+CLASS="COMMAND"
+>mangled map = (*.html *.htm)</B
+></P
+><P
+>One very useful case is to remove the annoying <TT
+CLASS="FILENAME"
+>;1
+ </TT
+> off the ends of filenames on some CDROMs (only visible
+ under some UNIXes). To do this use a map of (*;1 *;).</P
+><P
+>Default: <EM
+>no mangled map</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>mangled map = (*;1 *;)</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLEDNAMES"
+></A
+>mangled names (S)</DT
+><DD
+><P
+>This controls whether non-DOS names under UNIX
+ should be mapped to DOS-compatible names ("mangled") and made visible,
+ or whether non-DOS names should simply be ignored.</P
+><P
+>See the section on <A
+HREF="#AEN203"
+> NAME MANGLING</A
+> for details on how to control the mangling process.</P
+><P
+>If mangling algorithm "hash" is used then the mangling algorithm is as follows:</P
+><P
+></P
+><UL
+><LI
+><P
+>The first (up to) five alphanumeric characters
+ before the rightmost dot of the filename are preserved, forced
+ to upper case, and appear as the first (up to) five characters
+ of the mangled name.</P
+></LI
+><LI
+><P
+>A tilde "~" is appended to the first part of the mangled
+ name, followed by a two-character unique sequence, based on the
+ original root name (i.e., the original filename minus its final
+ extension). The final extension is included in the hash calculation
+ only if it contains any upper case characters or is longer than three
+ characters.</P
+><P
+>Note that the character to use may be specified using
+ the <A
+HREF="#MANGLINGCHAR"
+><TT
+CLASS="PARAMETER"
+><I
+>mangling char</I
+></TT
+>
+ </A
+> option, if you don't like '~'.</P
+></LI
+><LI
+><P
+>The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and appear as the
+ extension of the mangled name. The final extension is defined as that
+ part of the original filename after the rightmost dot. If there are no
+ dots in the filename, the mangled name will have no extension (except
+ in the case of "hidden files" - see below).</P
+></LI
+><LI
+><P
+>Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will be created as
+ for other filenames, but with the leading dot removed and "___" as
+ its extension regardless of actual original extension (that's three
+ underscores).</P
+></LI
+></UL
+><P
+>The two-digit hash value consists of upper case
+ alphanumeric characters.</P
+><P
+>This algorithm can cause name collisions only if files
+ in a directory share the same first five alphanumeric characters.
+ The probability of such a clash is 1/1300.</P
+><P
+>If mangling algorithm "hash2" is used then the mangling algorithm is as follows:</P
+><P
+></P
+><UL
+><LI
+><P
+>The first alphanumeric character
+ before the rightmost dot of the filename is preserved, forced
+ to upper case, and appears as the first character of the mangled name.
+ </P
+></LI
+><LI
+><P
+>A base63 hash of 5 characters is generated and the
+ first 4 characters of that hash are appended to the first character.
+ </P
+></LI
+><LI
+><P
+>A tilde "~" is appended to the first part of the mangled
+ name, followed by the final character of the base36 hash of the name.
+ </P
+><P
+>Note that the character to use may be specified using
+ the <A
+HREF="#MANGLINGCHAR"
+><TT
+CLASS="PARAMETER"
+><I
+>mangling char</I
+></TT
+>
+ </A
+> option, if you don't like '~'.</P
+></LI
+><LI
+><P
+>The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and appear as the
+ extension of the mangled name. The final extension is defined as that
+ part of the original filename after the rightmost dot. If there are no
+ dots in the filename, the mangled name will have no extension (except
+ in the case of "hidden files" - see below).</P
+></LI
+><LI
+><P
+>Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will be created as
+ for other filenames, but with the leading dot removed and "___" as
+ its extension regardless of actual original extension (that's three
+ underscores).</P
+></LI
+></UL
+><P
+>The name mangling (if enabled) allows a file to be
+ copied between UNIX directories from Windows/DOS while retaining
+ the long UNIX filename. UNIX files can be renamed to a new extension
+ from Windows/DOS and will retain the same basename. Mangled names
+ do not change between sessions.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>mangled names = yes</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLEDSTACK"
+></A
+>mangled stack (G)</DT
+><DD
+><P
+>This parameter controls the number of mangled names
+ that should be cached in the Samba server <A
+HREF="smbd.8.html"
+TARGET="_top"
+> smbd(8)</A
+>.</P
+><P
+>This stack is a list of recently mangled base names
+ (extensions are only maintained if they are longer than 3 characters
+ or contains upper case characters).</P
+><P
+>The larger this value, the more likely it is that mangled
+ names can be successfully converted to correct long UNIX names.
+ However, large stack sizes will slow most directory accesses. Smaller
+ stacks save memory in the server (each stack element costs 256 bytes).
+ </P
+><P
+>It is not possible to absolutely guarantee correct long
+ filenames, so be prepared for some surprises!</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>mangled stack = 50</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>mangled stack = 100</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLINGCHAR"
+></A
+>mangling char (S)</DT
+><DD
+><P
+>This controls what character is used as
+ the <EM
+>magic</EM
+> character in <A
+HREF="#AEN203"
+>name mangling</A
+>. The default is a '~'
+ but this may interfere with some software. Use this option to set
+ it to whatever you prefer.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>mangling char = ~</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>mangling char = ^</B
+></P
+></DD
+><DT
+><A
+NAME="MANGLINGMETHOD"
+></A
+>mangling mathod(G)</DT
+><DD
+><P
+> controls the algorithm used for the generating
+ the mangled names. Can take two different values, "hash" and
+ "hash2". "hash" is the default and is the algorithm that has been
+ used in Samba for many years. "hash2" is a newer and considered
+ a better algorithm (generates less collisions) in the names.
+ However, many Win32 applications store the mangled names and so
+ changing to the new algorithm must not be done
+ lightly as these applications may break unless reinstalled.
+ New installations of Samba may set the default to hash2.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>mangling method = hash</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>mangling method = hash2</B
+></P
+></DD
+><DT
+><A
+NAME="MAPARCHIVE"
+></A
+>map archive (S)</DT
+><DD
+><P
+>This controls whether the DOS archive attribute
+ should be mapped to the UNIX owner execute bit. The DOS archive bit
+ is set when a file has been modified since its last backup. One
+ motivation for this option it to keep Samba/your PC from making
+ any file it touches from becoming executable under UNIX. This can
+ be quite annoying for shared source code, documents, etc...</P
+><P
+>Note that this requires the <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+>
+ parameter to be set such that owner execute bit is not masked out
+ (i.e. it must include 100). See the parameter <A
+HREF="#CREATEMASK"
+> <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></A
+> for details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>map archive = yes</B
+></P
+></DD
+><DT
+><A
+NAME="MAPHIDDEN"
+></A
+>map hidden (S)</DT
+><DD
+><P
+>This controls whether DOS style hidden files
+ should be mapped to the UNIX world execute bit.</P
+><P
+>Note that this requires the <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+>
+ to be set such that the world execute bit is not masked out (i.e.
+ it must include 001). See the parameter <A
+HREF="#CREATEMASK"
+> <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></A
+> for details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>map hidden = no</B
+></P
+></DD
+><DT
+><A
+NAME="MAPSYSTEM"
+></A
+>map system (S)</DT
+><DD
+><P
+>This controls whether DOS style system files
+ should be mapped to the UNIX group execute bit.</P
+><P
+>Note that this requires the <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+>
+ to be set such that the group execute bit is not masked out (i.e.
+ it must include 010). See the parameter <A
+HREF="#CREATEMASK"
+> <TT
+CLASS="PARAMETER"
+><I
+>create mask</I
+></TT
+></A
+> for details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>map system = no</B
+></P
+></DD
+><DT
+><A
+NAME="MAPTOGUEST"
+></A
+>map to guest (G)</DT
+><DD
+><P
+>This parameter is only useful in <A
+HREF="#SECURITY"
+> security</A
+> modes other than <TT
+CLASS="PARAMETER"
+><I
+>security = share</I
+></TT
+>
+ - i.e. <TT
+CLASS="CONSTANT"
+>user</TT
+>, <TT
+CLASS="CONSTANT"
+>server</TT
+>,
+ and <TT
+CLASS="CONSTANT"
+>domain</TT
+>.</P
+><P
+>This parameter can take three different values, which tell
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> what to do with user
+ login requests that don't match a valid UNIX user in some way.</P
+><P
+>The three settings are :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>Never</TT
+> - Means user login
+ requests with an invalid password are rejected. This is the
+ default.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>Bad User</TT
+> - Means user
+ logins with an invalid password are rejected, unless the username
+ does not exist, in which case it is treated as a guest login and
+ mapped into the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+> guest account</I
+></TT
+></A
+>.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>Bad Password</TT
+> - Means user logins
+ with an invalid password are treated as a guest login and mapped
+ into the <A
+HREF="#GUESTACCOUNT"
+>guest account</A
+>. Note that
+ this can cause problems as it means that any user incorrectly typing
+ their password will be silently logged on as "guest" - and
+ will not know the reason they cannot access files they think
+ they should - there will have been no message given to them
+ that they got their password wrong. Helpdesk services will
+ <EM
+>hate</EM
+> you if you set the <TT
+CLASS="PARAMETER"
+><I
+>map to
+ guest</I
+></TT
+> parameter this way :-).</P
+></LI
+></UL
+><P
+>Note that this parameter is needed to set up "Guest"
+ share services when using <TT
+CLASS="PARAMETER"
+><I
+>security</I
+></TT
+> modes other than
+ share. This is because in these modes the name of the resource being
+ requested is <EM
+>not</EM
+> sent to the server until after
+ the server has successfully authenticated the client so the server
+ cannot make authentication decisions at the correct time (connection
+ to the share) for "Guest" shares.</P
+><P
+>For people familiar with the older Samba releases, this
+ parameter maps to the old compile-time setting of the <TT
+CLASS="CONSTANT"
+> GUEST_SESSSETUP</TT
+> value in local.h.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>map to guest = Never</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>map to guest = Bad User</B
+></P
+></DD
+><DT
+><A
+NAME="MAXCONNECTIONS"
+></A
+>max connections (S)</DT
+><DD
+><P
+>This option allows the number of simultaneous
+ connections to a service to be limited. If <TT
+CLASS="PARAMETER"
+><I
+>max connections
+ </I
+></TT
+> is greater than 0 then connections will be refused if
+ this number of connections to the service are already open. A value
+ of zero mean an unlimited number of connections may be made.</P
+><P
+>Record lock files are used to implement this feature. The
+ lock files will be stored in the directory specified by the <A
+HREF="#LOCKDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+>lock directory</I
+></TT
+></A
+>
+ option.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max connections = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max connections = 10</B
+></P
+></DD
+><DT
+><A
+NAME="MAXDISKSIZE"
+></A
+>max disk size (G)</DT
+><DD
+><P
+>This option allows you to put an upper limit
+ on the apparent size of disks. If you set this option to 100
+ then all shares will appear to be not larger than 100 MB in
+ size.</P
+><P
+>Note that this option does not limit the amount of
+ data you can put on the disk. In the above case you could still
+ store much more than 100 MB on the disk, but if a client ever asks
+ for the amount of free disk space or the total disk size then the
+ result will be bounded by the amount specified in <TT
+CLASS="PARAMETER"
+><I
+>max
+ disk size</I
+></TT
+>.</P
+><P
+>This option is primarily useful to work around bugs
+ in some pieces of software that can't handle very large disks,
+ particularly disks over 1GB in size.</P
+><P
+>A <TT
+CLASS="PARAMETER"
+><I
+>max disk size</I
+></TT
+> of 0 means no limit.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max disk size = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max disk size = 1000</B
+></P
+></DD
+><DT
+><A
+NAME="MAXLOGSIZE"
+></A
+>max log size (G)</DT
+><DD
+><P
+>This option (an integer in kilobytes) specifies
+ the max size the log file should grow to. Samba periodically checks
+ the size and if it is exceeded it will rename the file, adding
+ a <TT
+CLASS="FILENAME"
+>.old</TT
+> extension.</P
+><P
+>A size of 0 means no limit.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max log size = 5000</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max log size = 1000</B
+></P
+></DD
+><DT
+><A
+NAME="MAXMUX"
+></A
+>max mux (G)</DT
+><DD
+><P
+>This option controls the maximum number of
+ outstanding simultaneous SMB operations that Samba tells the client
+ it will allow. You should never need to set this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max mux = 50</B
+></P
+></DD
+><DT
+><A
+NAME="MAXOPENFILES"
+></A
+>max open files (G)</DT
+><DD
+><P
+>This parameter limits the maximum number of
+ open files that one <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> file
+ serving process may have open for a client at any one time. The
+ default for this parameter is set very high (10,000) as Samba uses
+ only one bit per unopened file.</P
+><P
+>The limit of the number of open files is usually set
+ by the UNIX per-process file descriptor limit rather than
+ this parameter so you should never need to touch this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max open files = 10000</B
+></P
+></DD
+><DT
+><A
+NAME="MAXPRINTJOBS"
+></A
+>max print jobs (S)</DT
+><DD
+><P
+>This parameter limits the maximum number of
+ jobs allowable in a Samba printer queue at any given moment.
+ If this number is exceeded, <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> smbd(8)</B
+></A
+> will remote "Out of Space" to the client.
+ See all <A
+HREF="#TOTALPRINTJOBS"
+><TT
+CLASS="PARAMETER"
+><I
+>total
+ print jobs</I
+></TT
+></A
+>.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max print jobs = 1000</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max print jobs = 5000</B
+></P
+></DD
+><DT
+><A
+NAME="MAXPROTOCOL"
+></A
+>max protocol (G)</DT
+><DD
+><P
+>The value of the parameter (a string) is the highest
+ protocol level that will be supported by the server.</P
+><P
+>Possible values are :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>CORE</TT
+>: Earliest version. No
+ concept of user names.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>COREPLUS</TT
+>: Slight improvements on
+ CORE for efficiency.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>LANMAN1</TT
+>: First <EM
+> modern</EM
+> version of the protocol. Long filename
+ support.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>LANMAN2</TT
+>: Updates to Lanman1 protocol.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>NT1</TT
+>: Current up to date version of
+ the protocol. Used by Windows NT. Known as CIFS.</P
+></LI
+></UL
+><P
+>Normally this option should not be set as the automatic
+ negotiation phase in the SMB protocol takes care of choosing
+ the appropriate protocol.</P
+><P
+>See also <A
+HREF="#MINPROTOCOL"
+><TT
+CLASS="PARAMETER"
+><I
+>min
+ protocol</I
+></TT
+></A
+></P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max protocol = NT1</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max protocol = LANMAN1</B
+></P
+></DD
+><DT
+><A
+NAME="MAXSMBDPROCESSES"
+></A
+>max smbd processes (G)</DT
+><DD
+><P
+>This parameter limits the maximum number of
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>
+ processes concurrently running on a system and is intended
+ as a stopgap to prevent degrading service to clients in the event
+ that the server has insufficient resources to handle more than this
+ number of connections. Remember that under normal operating
+ conditions, each user will have an <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> associated with him or her
+ to handle connections to all shares from a given host.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max smbd processes = 0</B
+> ## no limit</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max smbd processes = 1000</B
+></P
+></DD
+><DT
+><A
+NAME="MAXTTL"
+></A
+>max ttl (G)</DT
+><DD
+><P
+>This option tells <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ what the default 'time to live' of NetBIOS names should be (in seconds)
+ when <B
+CLASS="COMMAND"
+>nmbd</B
+> is requesting a name using either a
+ broadcast packet or from a WINS server. You should never need to
+ change this parameter. The default is 3 days.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max ttl = 259200</B
+></P
+></DD
+><DT
+><A
+NAME="MAXWINSTTL"
+></A
+>max wins ttl (G)</DT
+><DD
+><P
+>This option tells <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)
+ </A
+> when acting as a WINS server (<A
+HREF="#WINSSUPPORT"
+> <TT
+CLASS="PARAMETER"
+><I
+>wins support = yes</I
+></TT
+></A
+>) what the maximum
+ 'time to live' of NetBIOS names that <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will grant will be (in seconds). You should never need to change this
+ parameter. The default is 6 days (518400 seconds).</P
+><P
+>See also the <A
+HREF="#MINWINSTTL"
+><TT
+CLASS="PARAMETER"
+><I
+>min
+ wins ttl</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max wins ttl = 518400</B
+></P
+></DD
+><DT
+><A
+NAME="MAXXMIT"
+></A
+>max xmit (G)</DT
+><DD
+><P
+>This option controls the maximum packet size
+ that will be negotiated by Samba. The default in Samba 2.2.6 is
+ now 16644 (changed from 65535 in earlier releases) which matches
+ Windows 2000. This allows better performance with Windows NT clients.
+ The maximum is 65535. In some cases you may find you get better performance
+ with a smaller value. A value below 2048 is likely to cause problems.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>max xmit = 16644</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>max xmit = 8192</B
+></P
+></DD
+><DT
+><A
+NAME="MESSAGECOMMAND"
+></A
+>message command (G)</DT
+><DD
+><P
+>This specifies what command to run when the
+ server receives a WinPopup style message.</P
+><P
+>This would normally be a command that would
+ deliver the message somehow. How this is to be done is
+ up to your imagination.</P
+><P
+>An example is:</P
+><P
+><B
+CLASS="COMMAND"
+>message command = csh -c 'xedit %s;rm %s' &#38;</B
+>
+ </P
+><P
+>This delivers the message using <B
+CLASS="COMMAND"
+>xedit</B
+>, then
+ removes it afterwards. <EM
+>NOTE THAT IT IS VERY IMPORTANT
+ THAT THIS COMMAND RETURN IMMEDIATELY</EM
+>. That's why I
+ have the '&#38;' on the end. If it doesn't return immediately then
+ your PCs may freeze when sending messages (they should recover
+ after 30 seconds, hopefully).</P
+><P
+>All messages are delivered as the global guest user.
+ The command takes the standard substitutions, although <TT
+CLASS="PARAMETER"
+><I
+> %u</I
+></TT
+> won't work (<TT
+CLASS="PARAMETER"
+><I
+>%U</I
+></TT
+> may be better
+ in this case).</P
+><P
+>Apart from the standard substitutions, some additional
+ ones apply. In particular:</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>%s</I
+></TT
+> = the filename containing
+ the message.</P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>%t</I
+></TT
+> = the destination that
+ the message was sent to (probably the server name).</P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>%f</I
+></TT
+> = who the message
+ is from.</P
+></LI
+></UL
+><P
+>You could make this command send mail, or whatever else
+ takes your fancy. Please let us know of any really interesting
+ ideas you have.</P
+><P
+>Here's a way of sending the messages as mail to root:</P
+><P
+><B
+CLASS="COMMAND"
+>message command = /bin/mail -s 'message from %f on
+ %m' root &#60; %s; rm %s</B
+></P
+><P
+>If you don't have a message command then the message
+ won't be delivered and Samba will tell the sender there was
+ an error. Unfortunately WfWg totally ignores the error code
+ and carries on regardless, saying that the message was delivered.
+ </P
+><P
+>If you want to silently delete it then try:</P
+><P
+><B
+CLASS="COMMAND"
+>message command = rm %s</B
+></P
+><P
+>Default: <EM
+>no message command</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>message command = csh -c 'xedit %s;
+ rm %s' &#38;</B
+></P
+></DD
+><DT
+><A
+NAME="MINPASSWDLENGTH"
+></A
+>min passwd length (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#MINPASSWORDLENGTH"
+> <TT
+CLASS="PARAMETER"
+><I
+>min password length</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="MINPASSWORDLENGTH"
+></A
+>min password length (G)</DT
+><DD
+><P
+>This option sets the minimum length in characters
+ of a plaintext password that <B
+CLASS="COMMAND"
+>smbd</B
+> will accept when performing
+ UNIX password changing.</P
+><P
+>See also <A
+HREF="#UNIXPASSWORDSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>unix
+ password sync</I
+></TT
+></A
+>, <A
+HREF="#PASSWDPROGRAM"
+> <TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+></A
+> and <A
+HREF="#PASSWDCHATDEBUG"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd chat debug</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>min password length = 5</B
+></P
+></DD
+><DT
+><A
+NAME="MINPRINTSPACE"
+></A
+>min print space (S)</DT
+><DD
+><P
+>This sets the minimum amount of free disk
+ space that must be available before a user will be able to spool
+ a print job. It is specified in kilobytes. The default is 0, which
+ means a user can always spool a print job.</P
+><P
+>See also the <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>min print space = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>min print space = 2000</B
+></P
+></DD
+><DT
+><A
+NAME="MINPROTOCOL"
+></A
+>min protocol (G)</DT
+><DD
+><P
+>The value of the parameter (a string) is the
+ lowest SMB protocol dialect than Samba will support. Please refer
+ to the <A
+HREF="#MAXPROTOCOL"
+><TT
+CLASS="PARAMETER"
+><I
+>max protocol</I
+></TT
+></A
+>
+ parameter for a list of valid protocol names and a brief description
+ of each. You may also wish to refer to the C source code in
+ <TT
+CLASS="FILENAME"
+>source/smbd/negprot.c</TT
+> for a listing of known protocol
+ dialects supported by clients.</P
+><P
+>If you are viewing this parameter as a security measure, you should
+ also refer to the <A
+HREF="#LANMANAUTH"
+><TT
+CLASS="PARAMETER"
+><I
+>lanman
+ auth</I
+></TT
+></A
+> parameter. Otherwise, you should never need
+ to change this parameter.</P
+><P
+>Default : <B
+CLASS="COMMAND"
+>min protocol = CORE</B
+></P
+><P
+>Example : <B
+CLASS="COMMAND"
+>min protocol = NT1</B
+> # disable DOS
+ clients</P
+></DD
+><DT
+><A
+NAME="MINWINSTTL"
+></A
+>min wins ttl (G)</DT
+><DD
+><P
+>This option tells <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ when acting as a WINS server (<A
+HREF="#WINSSUPPORT"
+><TT
+CLASS="PARAMETER"
+><I
+> wins support = yes</I
+></TT
+></A
+>) what the minimum 'time to live'
+ of NetBIOS names that <B
+CLASS="COMMAND"
+>nmbd</B
+> will grant will be (in
+ seconds). You should never need to change this parameter. The default
+ is 6 hours (21600 seconds).</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>min wins ttl = 21600</B
+></P
+></DD
+><DT
+><A
+NAME="MSDFSROOT"
+></A
+>msdfs root (S)</DT
+><DD
+><P
+>This boolean parameter is only available if
+ Samba is configured and compiled with the <B
+CLASS="COMMAND"
+> --with-msdfs</B
+> option. If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>,
+ Samba treats the share as a Dfs root and allows clients to browse
+ the distributed file system tree rooted at the share directory.
+ Dfs links are specified in the share directory by symbolic
+ links of the form <TT
+CLASS="FILENAME"
+>msdfs:serverA\shareA,serverB\shareB
+ </TT
+> and so on. For more information on setting up a Dfs tree
+ on Samba, refer to <A
+HREF="msdfs_setup.html"
+TARGET="_top"
+>msdfs_setup.html
+ </A
+>.</P
+><P
+>See also <A
+HREF="#HOSTMSDFS"
+><TT
+CLASS="PARAMETER"
+><I
+>host msdfs
+ </I
+></TT
+></A
+></P
+><P
+>Default: <B
+CLASS="COMMAND"
+>msdfs root = no</B
+></P
+></DD
+><DT
+><A
+NAME="NAMERESOLVEORDER"
+></A
+>name resolve order (G)</DT
+><DD
+><P
+>This option is used by the programs in the Samba
+ suite to determine what naming services to use and in what order
+ to resolve host names to IP addresses. The option takes a space
+ separated string of name resolution options.</P
+><P
+>The options are :"lmhosts", "host", "wins" and "bcast". They
+ cause names to be resolved as follows :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmhosts</TT
+> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <A
+HREF="lmhosts.5.html"
+TARGET="_top"
+>lmhosts(5)</A
+> for details) then
+ any name type matches for lookup.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>host</TT
+> : Do a standard host
+ name to IP address resolution, using the system <TT
+CLASS="FILENAME"
+>/etc/hosts
+ </TT
+>, NIS, or DNS lookups. This method of name resolution
+ is operating system depended for instance on IRIX or Solaris this
+ may be controlled by the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>
+ file. Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>wins</TT
+> : Query a name with
+ the IP address listed in the <A
+HREF="#WINSSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+> wins server</I
+></TT
+></A
+> parameter. If no WINS server has
+ been specified this method will be ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>bcast</TT
+> : Do a broadcast on
+ each of the known local interfaces listed in the <A
+HREF="#INTERFACES"
+><TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+></A
+>
+ parameter. This is the least reliable of the name resolution
+ methods as it depends on the target host being on a locally
+ connected subnet.</P
+></LI
+></UL
+><P
+>Default: <B
+CLASS="COMMAND"
+>name resolve order = lmhosts host wins bcast
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>name resolve order = lmhosts bcast host
+ </B
+></P
+><P
+>This will cause the local lmhosts file to be examined
+ first, followed by a broadcast attempt, followed by a normal
+ system hostname lookup.</P
+></DD
+><DT
+><A
+NAME="NETBIOSALIASES"
+></A
+>netbios aliases (G)</DT
+><DD
+><P
+>This is a list of NetBIOS names that <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> will advertise as additional
+ names by which the Samba server is known. This allows one machine
+ to appear in browse lists under multiple names. If a machine is
+ acting as a browse server or logon server none
+ of these names will be advertised as either browse server or logon
+ servers, only the primary name of the machine will be advertised
+ with these capabilities.</P
+><P
+>See also <A
+HREF="#NETBIOSNAME"
+><TT
+CLASS="PARAMETER"
+><I
+>netbios
+ name</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>empty string (no additional names)</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>netbios aliases = TEST TEST1 TEST2</B
+></P
+></DD
+><DT
+><A
+NAME="NETBIOSNAME"
+></A
+>netbios name (G)</DT
+><DD
+><P
+>This sets the NetBIOS name by which a Samba
+ server is known. By default it is the same as the first component
+ of the host's DNS name. If a machine is a browse server or
+ logon server this name (or the first component
+ of the hosts DNS name) will be the name that these services are
+ advertised under.</P
+><P
+>See also <A
+HREF="#NETBIOSALIASES"
+><TT
+CLASS="PARAMETER"
+><I
+>netbios
+ aliases</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>machine DNS name</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>netbios name = MYNAME</B
+></P
+></DD
+><DT
+><A
+NAME="NETBIOSSCOPE"
+></A
+>netbios scope (G)</DT
+><DD
+><P
+>This sets the NetBIOS scope that Samba will
+ operate under. This should not be set unless every machine
+ on your LAN also sets this value.</P
+></DD
+><DT
+><A
+NAME="NISHOMEDIR"
+></A
+>nis homedir (G)</DT
+><DD
+><P
+>Get the home share server from a NIS map. For
+ UNIX systems that use an automounter, the user's home directory
+ will often be mounted on a workstation on demand from a remote
+ server. </P
+><P
+>When the Samba logon server is not the actual home directory
+ server, but is mounting the home directories via NFS then two
+ network hops would be required to access the users home directory
+ if the logon server told the client to use itself as the SMB server
+ for home directories (one over SMB and one over NFS). This can
+ be very slow.</P
+><P
+>This option allows Samba to return the home share as
+ being on a different server to the logon server and as
+ long as a Samba daemon is running on the home directory server,
+ it will be mounted on the Samba client directly from the directory
+ server. When Samba is returning the home share to the client, it
+ will consult the NIS map specified in <A
+HREF="#HOMEDIRMAP"
+> <TT
+CLASS="PARAMETER"
+><I
+>homedir map</I
+></TT
+></A
+> and return the server
+ listed there.</P
+><P
+>Note that for this option to work there must be a working
+ NIS system and the Samba server with this option must also
+ be a logon server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>nis homedir = no</B
+></P
+></DD
+><DT
+><A
+NAME="NTACLSUPPORT"
+></A
+>nt acl support (S)</DT
+><DD
+><P
+>This boolean parameter controls whether
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will attempt to map
+ UNIX permissions into Windows NT access control lists.
+ This parameter was formally a global parameter in releases
+ prior to 2.2.2.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>nt acl support = yes</B
+></P
+></DD
+><DT
+><A
+NAME="NTPIPESUPPORT"
+></A
+>nt pipe support (G)</DT
+><DD
+><P
+>This boolean parameter controls whether
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will allow Windows NT
+ clients to connect to the NT SMB specific <TT
+CLASS="CONSTANT"
+>IPC$</TT
+>
+ pipes. This is a developer debugging option and can be left
+ alone.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>nt pipe support = yes</B
+></P
+></DD
+><DT
+><A
+NAME="NTSMBSUPPORT"
+></A
+>nt smb support (G)</DT
+><DD
+><P
+>This boolean parameter controls whether <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will negotiate NT specific SMB
+ support with Windows NT/2k/XP clients. Although this is a developer
+ debugging option and should be left alone, benchmarking has discovered
+ that Windows NT clients give faster performance with this option
+ set to <TT
+CLASS="CONSTANT"
+>no</TT
+>. This is still being investigated.
+ If this option is set to <TT
+CLASS="CONSTANT"
+>no</TT
+> then Samba offers
+ exactly the same SMB calls that versions prior to Samba 2.0 offered.
+ This information may be of use if any users are having problems
+ with NT SMB support.</P
+><P
+>You should not need to ever disable this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>nt smb support = yes</B
+></P
+></DD
+><DT
+><A
+NAME="NTSTATUSSUPPORT"
+></A
+>nt status support (G)</DT
+><DD
+><P
+>This boolean parameter controls whether <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will negotiate NT specific status
+ support with Windows NT/2k/XP clients. This is a developer
+ debugging option and should be left alone.
+ If this option is set to <TT
+CLASS="CONSTANT"
+>no</TT
+> then Samba offers
+ exactly the same DOS error codes that versions prior to Samba 2.2.3
+ reported.</P
+><P
+>You should not need to ever disable this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>nt status support = yes</B
+></P
+></DD
+><DT
+><A
+NAME="NULLPASSWORDS"
+></A
+>null passwords (G)</DT
+><DD
+><P
+>Allow or disallow client access to accounts
+ that have null passwords. </P
+><P
+>See also <A
+HREF="smbpasswd.5.html"
+TARGET="_top"
+>smbpasswd (5)</A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>null passwords = no</B
+></P
+></DD
+><DT
+><A
+NAME="OBEYPAMRESTRICTIONS"
+></A
+>obey pam restrictions (G)</DT
+><DD
+><P
+>When Samba 2.2 is configured to enable PAM support
+ (i.e. --with-pam), this parameter will control whether or not Samba
+ should obey PAM's account and session management directives. The
+ default behavior is to use PAM for clear text authentication only
+ and to ignore any account or session management. Note that Samba
+ always ignores PAM for authentication in the case of <A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypt passwords = yes</I
+></TT
+>
+ </A
+>. The reason is that PAM modules cannot support the challenge/response
+ authentication mechanism needed in the presence of SMB password encryption.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>obey pam restrictions = no</B
+></P
+></DD
+><DT
+><A
+NAME="ONLYUSER"
+></A
+>only user (S)</DT
+><DD
+><P
+>This is a boolean option that controls whether
+ connections with usernames not in the <TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+>
+ list will be allowed. By default this option is disabled so that a
+ client can supply a username to be used by the server. Enabling
+ this parameter will force the server to only use the login
+ names from the <TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+> list and is only really
+ useful in <A
+HREF="#SECURITYEQUALSSHARE"
+>share level</A
+>
+ security.</P
+><P
+>Note that this also means Samba won't try to deduce
+ usernames from the service name. This can be annoying for
+ the [homes] section. To get around this you could use <B
+CLASS="COMMAND"
+>user =
+ %S</B
+> which means your <TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+> list
+ will be just the service name, which for home directories is the
+ name of the user.</P
+><P
+>See also the <A
+HREF="#USER"
+><TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+>
+ </A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>only user = no</B
+></P
+></DD
+><DT
+><A
+NAME="ONLYGUEST"
+></A
+>only guest (S)</DT
+><DD
+><P
+>A synonym for <A
+HREF="#GUESTONLY"
+><TT
+CLASS="PARAMETER"
+><I
+> guest only</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="OPLOCKBREAKWAITTIME"
+></A
+>oplock break wait time (G)</DT
+><DD
+><P
+>This is a tuning parameter added due to bugs in
+ both Windows 9x and WinNT. If Samba responds to a client too
+ quickly when that client issues an SMB that can cause an oplock
+ break request, then the network client can fail and not respond
+ to the break request. This tuning parameter (which is set in milliseconds)
+ is the amount of time Samba will wait before sending an oplock break
+ request to such (broken) clients.</P
+><P
+><EM
+>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+ AND UNDERSTOOD THE SAMBA OPLOCK CODE</EM
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>oplock break wait time = 0</B
+></P
+></DD
+><DT
+><A
+NAME="OPLOCKCONTENTIONLIMIT"
+></A
+>oplock contention limit (S)</DT
+><DD
+><P
+>This is a <EM
+>very</EM
+> advanced
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> tuning option to
+ improve the efficiency of the granting of oplocks under multiple
+ client contention for the same file.</P
+><P
+>In brief it specifies a number, which causes <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> not to
+ grant an oplock even when requested if the approximate number of
+ clients contending for an oplock on the same file goes over this
+ limit. This causes <B
+CLASS="COMMAND"
+>smbd</B
+> to behave in a similar
+ way to Windows NT.</P
+><P
+><EM
+>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+ AND UNDERSTOOD THE SAMBA OPLOCK CODE</EM
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>oplock contention limit = 2</B
+></P
+></DD
+><DT
+><A
+NAME="OPLOCKS"
+></A
+>oplocks (S)</DT
+><DD
+><P
+>This boolean option tells <B
+CLASS="COMMAND"
+>smbd</B
+> whether to
+ issue oplocks (opportunistic locks) to file open requests on this
+ share. The oplock code can dramatically (approx. 30% or more) improve
+ the speed of access to files on Samba servers. It allows the clients
+ to aggressively cache files locally and you may want to disable this
+ option for unreliable network environments (it is turned on by
+ default in Windows NT Servers). For more information see the file
+ <TT
+CLASS="FILENAME"
+>Speed.txt</TT
+> in the Samba <TT
+CLASS="FILENAME"
+>docs/</TT
+>
+ directory.</P
+><P
+>Oplocks may be selectively turned off on certain files with a
+ share. See the <A
+HREF="#VETOOPLOCKFILES"
+><TT
+CLASS="PARAMETER"
+><I
+> veto oplock files</I
+></TT
+></A
+> parameter. On some systems
+ oplocks are recognized by the underlying operating system. This
+ allows data synchronization between all access to oplocked files,
+ whether it be via Samba or NFS or a local UNIX process. See the
+ <TT
+CLASS="PARAMETER"
+><I
+>kernel oplocks</I
+></TT
+> parameter for details.</P
+><P
+>See also the <A
+HREF="#KERNELOPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>kernel
+ oplocks</I
+></TT
+></A
+> and <A
+HREF="#LEVEL2OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+> level2 oplocks</I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>oplocks = yes</B
+></P
+></DD
+><DT
+><A
+NAME="OSLEVEL"
+></A
+>os level (G)</DT
+><DD
+><P
+>This integer value controls what level Samba
+ advertises itself as for browse elections. The value of this
+ parameter determines whether <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ has a chance of becoming a local master browser for the <TT
+CLASS="PARAMETER"
+><I
+> WORKGROUP</I
+></TT
+> in the local broadcast area.</P
+><P
+><EM
+>Note :</EM
+>By default, Samba will win
+ a local master browsing election over all Microsoft operating
+ systems except a Windows NT 4.0/2000 Domain Controller. This
+ means that a misconfigured Samba host can effectively isolate
+ a subnet for browsing purposes. See <TT
+CLASS="FILENAME"
+>BROWSING.txt
+ </TT
+> in the Samba <TT
+CLASS="FILENAME"
+>docs/</TT
+> directory
+ for details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>os level = 20</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>os level = 65 </B
+></P
+></DD
+><DT
+><A
+NAME="OS2DRIVERMAP"
+></A
+>os2 driver map (G)</DT
+><DD
+><P
+>The parameter is used to define the absolute
+ path to a file containing a mapping of Windows NT printer driver
+ names to OS/2 printer driver names. The format is:</P
+><P
+>&#60;nt driver name&#62; = &#60;os2 driver
+ name&#62;.&#60;device name&#62;</P
+><P
+>For example, a valid entry using the HP LaserJet 5
+ printer driver would appear as <B
+CLASS="COMMAND"
+>HP LaserJet 5L = LASERJET.HP
+ LaserJet 5L</B
+>.</P
+><P
+>The need for the file is due to the printer driver namespace
+ problem described in the <A
+HREF="printer_driver2.html"
+TARGET="_top"
+>Samba
+ Printing HOWTO</A
+>. For more details on OS/2 clients, please
+ refer to the <A
+HREF="OS2-Client-HOWTO.html"
+TARGET="_top"
+>OS2-Client-HOWTO
+ </A
+> containing in the Samba documentation.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>os2 driver map = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="PAMPASSWORDCHANGE"
+></A
+>pam password change (G)</DT
+><DD
+><P
+>With the addition of better PAM support in Samba 2.2,
+ this parameter, it is possible to use PAM's password change control
+ flag for Samba. If enabled, then PAM will be used for password
+ changes when requested by an SMB client instead of the program listed in
+ <A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+></A
+>.
+ It should be possible to enable this without changing your
+ <A
+HREF="#PASSWDCHAT"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd chat</I
+></TT
+></A
+>
+ parameter for most setups.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>pam password change = no</B
+></P
+></DD
+><DT
+><A
+NAME="PANICACTION"
+></A
+>panic action (G)</DT
+><DD
+><P
+>This is a Samba developer option that allows a
+ system command to be called when either <A
+HREF="smbd.8.html"
+TARGET="_top"
+> smbd(8)</A
+> or <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ crashes. This is usually used to draw attention to the fact that
+ a problem occurred.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>panic action = &#60;empty string&#62;</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>panic action = "/bin/sleep 90000"</B
+></P
+></DD
+><DT
+><A
+NAME="PASSWDCHAT"
+></A
+>passwd chat (G)</DT
+><DD
+><P
+>This string controls the <EM
+>"chat"</EM
+>
+ conversation that takes places between <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> and the local password changing
+ program to change the user's password. The string describes a
+ sequence of response-receive pairs that <A
+HREF="smbd.8.html"
+TARGET="_top"
+> smbd(8)</A
+> uses to determine what to send to the
+ <A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+>
+ </A
+> and what to expect back. If the expected output is not
+ received then the password is not changed.</P
+><P
+>This chat sequence is often quite site specific, depending
+ on what local methods are used for password control (such as NIS
+ etc).</P
+><P
+>Note that this parameter only is only used if the <A
+HREF="#UNIXPASSWORDSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>unix
+ password sync</I
+></TT
+></A
+> parameter is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>. This
+ sequence is then called <EM
+>AS ROOT</EM
+> when the SMB password
+ in the smbpasswd file is being changed, without access to the old
+ password cleartext. This means that root must be able to reset the user's password
+ without knowing the text of the previous password. In the presence of NIS/YP,
+ this means that the <A
+HREF="#PASSWDPROGRAM"
+>passwd program</A
+> must be
+ executed on the NIS master.
+ </P
+><P
+>The string can contain the macro <TT
+CLASS="PARAMETER"
+><I
+>%n</I
+></TT
+> which is substituted
+ for the new password. The chat sequence can also contain the standard
+ macros <TT
+CLASS="CONSTANT"
+>\n</TT
+>, <TT
+CLASS="CONSTANT"
+>\r</TT
+>, <TT
+CLASS="CONSTANT"
+> \t</TT
+> and <TT
+CLASS="CONSTANT"
+>\s</TT
+> to give line-feed,
+ carriage-return, tab and space. The chat sequence string can also contain
+ a '*' which matches any sequence of characters.
+ Double quotes can be used to collect strings with spaces
+ in them into a single string.</P
+><P
+>If the send string in any part of the chat sequence
+ is a full stop ".", then no string is sent. Similarly,
+ if the expect string is a full stop then no string is expected.</P
+><P
+>If the <A
+HREF="#PAMPASSWORDCHANGE"
+><TT
+CLASS="PARAMETER"
+><I
+>pam
+ password change</I
+></TT
+></A
+> parameter is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, the chat pairs
+ may be matched in any order, and success is determined by the PAM result,
+ not any particular output. The \n macro is ignored for PAM conversions.
+ </P
+><P
+>See also <A
+HREF="#UNIXPASSWORDSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>unix password
+ sync</I
+></TT
+></A
+>, <A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+> passwd program</I
+></TT
+></A
+> ,<A
+HREF="#PASSWDCHATDEBUG"
+> <TT
+CLASS="PARAMETER"
+><I
+>passwd chat debug</I
+></TT
+></A
+> and <A
+HREF="#PAMPASSWORDCHANGE"
+> <TT
+CLASS="PARAMETER"
+><I
+>pam password change</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>passwd chat = *new*password* %n\n
+ *new*password* %n\n *changed*</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>passwd chat = "*Enter OLD password*" %o\n
+ "*Enter NEW password*" %n\n "*Reenter NEW password*" %n\n "*Password
+ changed*"</B
+></P
+></DD
+><DT
+><A
+NAME="PASSWDCHATDEBUG"
+></A
+>passwd chat debug (G)</DT
+><DD
+><P
+>This boolean specifies if the passwd chat script
+ parameter is run in <EM
+>debug</EM
+> mode. In this mode the
+ strings passed to and received from the passwd chat are printed
+ in the <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> log with a
+ <A
+HREF="#DEBUGLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>debug level</I
+></TT
+></A
+>
+ of 100. This is a dangerous option as it will allow plaintext passwords
+ to be seen in the <B
+CLASS="COMMAND"
+>smbd</B
+> log. It is available to help
+ Samba admins debug their <TT
+CLASS="PARAMETER"
+><I
+>passwd chat</I
+></TT
+> scripts
+ when calling the <TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+> and should
+ be turned off after this has been done. This option has no effect if the
+ <A
+HREF="#PAMPASSWORDCHANGE"
+><TT
+CLASS="PARAMETER"
+><I
+>pam password change</I
+></TT
+></A
+>
+ paramter is set. This parameter is off by default.</P
+><P
+>See also <A
+HREF="#PASSWDCHAT"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd chat</I
+></TT
+>
+ </A
+>, <A
+HREF="#PAMPASSWORDCHANGE"
+><TT
+CLASS="PARAMETER"
+><I
+>pam password change</I
+></TT
+>
+ </A
+>, <A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd program</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>passwd chat debug = no</B
+></P
+></DD
+><DT
+><A
+NAME="PASSWDPROGRAM"
+></A
+>passwd program (G)</DT
+><DD
+><P
+>The name of a program that can be used to set
+ UNIX user passwords. Any occurrences of <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+>
+ will be replaced with the user name. The user name is checked for
+ existence before calling the password changing program.</P
+><P
+>Also note that many passwd programs insist in <EM
+>reasonable
+ </EM
+> passwords, such as a minimum length, or the inclusion
+ of mixed case chars and digits. This can pose a problem as some clients
+ (such as Windows for Workgroups) uppercase the password before sending
+ it.</P
+><P
+><EM
+>Note</EM
+> that if the <TT
+CLASS="PARAMETER"
+><I
+>unix
+ password sync</I
+></TT
+> parameter is set to <TT
+CLASS="CONSTANT"
+>yes
+ </TT
+> then this program is called <EM
+>AS ROOT</EM
+>
+ before the SMB password in the <A
+HREF="smbpasswd.5.html"
+TARGET="_top"
+>smbpasswd(5)
+ </A
+> file is changed. If this UNIX password change fails, then
+ <B
+CLASS="COMMAND"
+>smbd</B
+> will fail to change the SMB password also
+ (this is by design).</P
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>unix password sync</I
+></TT
+> parameter
+ is set this parameter <EM
+>MUST USE ABSOLUTE PATHS</EM
+>
+ for <EM
+>ALL</EM
+> programs called, and must be examined
+ for security implications. Note that by default <TT
+CLASS="PARAMETER"
+><I
+>unix
+ password sync</I
+></TT
+> is set to <TT
+CLASS="CONSTANT"
+>no</TT
+>.</P
+><P
+>See also <A
+HREF="#UNIXPASSWORDSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>unix
+ password sync</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>passwd program = /bin/passwd</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>passwd program = /sbin/npasswd %u</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="PASSWORDLEVEL"
+></A
+>password level (G)</DT
+><DD
+><P
+>Some client/server combinations have difficulty
+ with mixed-case passwords. One offending client is Windows for
+ Workgroups, which for some reason forces passwords to upper
+ case when using the LANMAN1 protocol, but leaves them alone when
+ using COREPLUS! Another problem child is the Windows 95/98
+ family of operating systems. These clients upper case clear
+ text passwords even when NT LM 0.12 selected by the protocol
+ negotiation request/response.</P
+><P
+>This parameter defines the maximum number of characters
+ that may be upper case in passwords.</P
+><P
+>For example, say the password given was "FRED". If <TT
+CLASS="PARAMETER"
+><I
+> password level</I
+></TT
+> is set to 1, the following combinations
+ would be tried if "FRED" failed:</P
+><P
+>"Fred", "fred", "fRed", "frEd","freD"</P
+><P
+>If <TT
+CLASS="PARAMETER"
+><I
+>password level</I
+></TT
+> was set to 2,
+ the following combinations would also be tried: </P
+><P
+>"FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ..</P
+><P
+>And so on.</P
+><P
+>The higher value this parameter is set to the more likely
+ it is that a mixed case password will be matched against a single
+ case password. However, you should be aware that use of this
+ parameter reduces security and increases the time taken to
+ process a new connection.</P
+><P
+>A value of zero will cause only two attempts to be
+ made - the password as is and the password in all-lower case.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>password level = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>password level = 4</B
+></P
+></DD
+><DT
+><A
+NAME="PASSWORDSERVER"
+></A
+>password server (G)</DT
+><DD
+><P
+>By specifying the name of another SMB server (such
+ as a WinNT box) with this option, and using <B
+CLASS="COMMAND"
+>security = domain
+ </B
+> or <B
+CLASS="COMMAND"
+>security = server</B
+> you can get Samba
+ to do all its username/password validation via a remote server.</P
+><P
+>This option sets the name of the password server to use.
+ It must be a NetBIOS name, so if the machine's NetBIOS name is
+ different from its Internet name then you may have to add its NetBIOS
+ name to the lmhosts file which is stored in the same directory
+ as the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file.</P
+><P
+>The name of the password server is looked up using the
+ parameter <A
+HREF="#NAMERESOLVEORDER"
+><TT
+CLASS="PARAMETER"
+><I
+>name
+ resolve order</I
+></TT
+></A
+> and so may resolved
+ by any method and order described in that parameter.</P
+><P
+>The password server much be a machine capable of using
+ the "LM1.2X002" or the "NT LM 0.12" protocol, and it must be in
+ user level security mode.</P
+><P
+><EM
+>NOTE:</EM
+> Using a password server
+ means your UNIX box (running Samba) is only as secure as your
+ password server. <EM
+>DO NOT CHOOSE A PASSWORD SERVER THAT
+ YOU DON'T COMPLETELY TRUST</EM
+>.</P
+><P
+>Never point a Samba server at itself for password
+ serving. This will cause a loop and could lock up your Samba
+ server!</P
+><P
+>The name of the password server takes the standard
+ substitutions, but probably the only useful one is <TT
+CLASS="PARAMETER"
+><I
+>%m
+ </I
+></TT
+>, which means the Samba server will use the incoming
+ client as the password server. If you use this then you better
+ trust your clients, and you had better restrict them with hosts allow!</P
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>security</I
+></TT
+> parameter is set to
+ <TT
+CLASS="CONSTANT"
+>domain</TT
+>, then the list of machines in this
+ option must be a list of Primary or Backup Domain controllers for the
+ Domain or the character '*', as the Samba server is effectively
+ in that domain, and will use cryptographically authenticated RPC calls
+ to authenticate the user logging on. The advantage of using <B
+CLASS="COMMAND"
+> security = domain</B
+> is that if you list several hosts in the
+ <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+> option then <B
+CLASS="COMMAND"
+>smbd
+ </B
+> will try each in turn till it finds one that responds. This
+ is useful in case your primary server goes down.</P
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+> option is set
+ to the character '*', then Samba will attempt to auto-locate the
+ Primary or Backup Domain controllers to authenticate against by
+ doing a query for the name <TT
+CLASS="CONSTANT"
+>WORKGROUP&#60;1C&#62;</TT
+>
+ and then contacting each server returned in the list of IP
+ addresses from the name resolution source. </P
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>security</I
+></TT
+> parameter is
+ set to <TT
+CLASS="CONSTANT"
+>server</TT
+>, then there are different
+ restrictions that <B
+CLASS="COMMAND"
+>security = domain</B
+> doesn't
+ suffer from:</P
+><P
+></P
+><UL
+><LI
+><P
+>You may list several password servers in
+ the <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+> parameter, however if an
+ <B
+CLASS="COMMAND"
+>smbd</B
+> makes a connection to a password server,
+ and then the password server fails, no more users will be able
+ to be authenticated from this <B
+CLASS="COMMAND"
+>smbd</B
+>. This is a
+ restriction of the SMB/CIFS protocol when in <B
+CLASS="COMMAND"
+>security = server
+ </B
+> mode and cannot be fixed in Samba.</P
+></LI
+><LI
+><P
+>If you are using a Windows NT server as your
+ password server then you will have to ensure that your users
+ are able to login from the Samba server, as when in <B
+CLASS="COMMAND"
+> security = server</B
+> mode the network logon will appear to
+ come from there rather than from the users workstation.</P
+></LI
+></UL
+><P
+>See also the <A
+HREF="#SECURITY"
+><TT
+CLASS="PARAMETER"
+><I
+>security
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>password server = &#60;empty string&#62;</B
+>
+ </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>password server = NT-PDC, NT-BDC1, NT-BDC2
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>password server = *</B
+></P
+></DD
+><DT
+><A
+NAME="PATH"
+></A
+>path (S)</DT
+><DD
+><P
+>This parameter specifies a directory to which
+ the user of the service is to be given access. In the case of
+ printable services, this is where print data will spool prior to
+ being submitted to the host for printing.</P
+><P
+>For a printable service offering guest access, the service
+ should be readonly and the path should be world-writeable and
+ have the sticky bit set. This is not mandatory of course, but
+ you probably won't get the results you expect if you do
+ otherwise.</P
+><P
+>Any occurrences of <TT
+CLASS="PARAMETER"
+><I
+>%u</I
+></TT
+> in the path
+ will be replaced with the UNIX username that the client is using
+ on this connection. Any occurrences of <TT
+CLASS="PARAMETER"
+><I
+>%m</I
+></TT
+>
+ will be replaced by the NetBIOS name of the machine they are
+ connecting from. These replacements are very useful for setting
+ up pseudo home directories for users.</P
+><P
+>Note that this path will be based on <A
+HREF="#ROOTDIR"
+> <TT
+CLASS="PARAMETER"
+><I
+>root dir</I
+></TT
+></A
+> if one was specified.</P
+><P
+>Default: <EM
+>none</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>path = /home/fred</B
+></P
+></DD
+><DT
+><A
+NAME="PIDDIRECTORY"
+></A
+>pid directory (G)</DT
+><DD
+><P
+>This option specifies the directory where pid
+ files will be placed. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>pid directory = ${prefix}/var/locks</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>pid directory = /var/run/</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="POSIXLOCKING"
+></A
+>posix locking (S)</DT
+><DD
+><P
+>The <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>
+ daemon maintains an database of file locks obtained by SMB clients.
+ The default behavior is to map this internal database to POSIX
+ locks. This means that file locks obtained by SMB clients are
+ consistent with those seen by POSIX compliant applications accessing
+ the files via a non-SMB method (e.g. NFS or local file access).
+ You should never need to disable this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>posix locking = yes</B
+></P
+></DD
+><DT
+><A
+NAME="POSTEXEC"
+></A
+>postexec (S)</DT
+><DD
+><P
+>This option specifies a command to be run
+ whenever the service is disconnected. It takes the usual
+ substitutions. The command may be run as the root on some
+ systems.</P
+><P
+>An interesting example may be to unmount server
+ resources:</P
+><P
+><B
+CLASS="COMMAND"
+>postexec = /etc/umount /cdrom</B
+></P
+><P
+>See also <A
+HREF="#PREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>preexec</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <EM
+>none (no command executed)</EM
+>
+ </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>postexec = echo \"%u disconnected from %S
+ from %m (%I)\" &#62;&#62; /tmp/log</B
+></P
+></DD
+><DT
+><A
+NAME="POSTSCRIPT"
+></A
+>postscript (S)</DT
+><DD
+><P
+>This parameter forces a printer to interpret
+ the print files as PostScript. This is done by adding a <TT
+CLASS="CONSTANT"
+>%!
+ </TT
+> to the start of print output.</P
+><P
+>This is most useful when you have lots of PCs that persist
+ in putting a control-D at the start of print jobs, which then
+ confuses your printer.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>postscript = no</B
+></P
+></DD
+><DT
+><A
+NAME="PREEXEC"
+></A
+>preexec (S)</DT
+><DD
+><P
+>This option specifies a command to be run whenever
+ the service is connected to. It takes the usual substitutions.</P
+><P
+>An interesting example is to send the users a welcome
+ message every time they log in. Maybe a message of the day? Here
+ is an example:</P
+><P
+><B
+CLASS="COMMAND"
+>preexec = csh -c 'echo \"Welcome to %S!\" |
+ /usr/local/samba/bin/smbclient -M %m -I %I' &#38; </B
+></P
+><P
+>Of course, this could get annoying after a while :-)</P
+><P
+>See also <A
+HREF="#PREEXECCLOSE"
+><TT
+CLASS="PARAMETER"
+><I
+>preexec close
+ </I
+></TT
+></A
+> and <A
+HREF="#POSTEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>postexec
+ </I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>none (no command executed)</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>preexec = echo \"%u connected to %S from %m
+ (%I)\" &#62;&#62; /tmp/log</B
+></P
+></DD
+><DT
+><A
+NAME="PREEXECCLOSE"
+></A
+>preexec close (S)</DT
+><DD
+><P
+>This boolean option controls whether a non-zero
+ return code from <A
+HREF="#PREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+>preexec
+ </I
+></TT
+></A
+> should close the service being connected to.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>preexec close = no</B
+></P
+></DD
+><DT
+><A
+NAME="PREFERREDMASTER"
+></A
+>preferred master (G)</DT
+><DD
+><P
+>This boolean parameter controls if <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> is a preferred master browser
+ for its workgroup.</P
+><P
+>If this is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, on startup, <B
+CLASS="COMMAND"
+>nmbd</B
+>
+ will force an election, and it will have a slight advantage in
+ winning the election. It is recommended that this parameter is
+ used in conjunction with <B
+CLASS="COMMAND"
+><A
+HREF="#DOMAINMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+> domain master</I
+></TT
+></A
+> = yes</B
+>, so that <B
+CLASS="COMMAND"
+> nmbd</B
+> can guarantee becoming a domain master.</P
+><P
+>Use this option with caution, because if there are several
+ hosts (whether Samba servers, Windows 95 or NT) that are preferred
+ master browsers on the same subnet, they will each periodically
+ and continuously attempt to become the local master browser.
+ This will result in unnecessary broadcast traffic and reduced browsing
+ capabilities.</P
+><P
+>See also <A
+HREF="#OSLEVEL"
+><TT
+CLASS="PARAMETER"
+><I
+>os level</I
+></TT
+>
+ </A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>preferred master = auto</B
+></P
+></DD
+><DT
+><A
+NAME="PREFEREDMASTER"
+></A
+>prefered master (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#PREFERREDMASTER"
+><TT
+CLASS="PARAMETER"
+><I
+> preferred master</I
+></TT
+></A
+> for people who cannot spell :-).</P
+></DD
+><DT
+><A
+NAME="PRELOAD"
+></A
+>preload</DT
+><DD
+><P
+>This is a list of services that you want to be
+ automatically added to the browse lists. This is most useful
+ for homes and printers services that would otherwise not be
+ visible.</P
+><P
+>Note that if you just want all printers in your
+ printcap file loaded then the <A
+HREF="#LOADPRINTERS"
+> <TT
+CLASS="PARAMETER"
+><I
+>load printers</I
+></TT
+></A
+> option is easier.</P
+><P
+>Default: <EM
+>no preloaded services</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>preload = fred lp colorlp</B
+></P
+></DD
+><DT
+><A
+NAME="PRESERVECASE"
+></A
+>preserve case (S)</DT
+><DD
+><P
+> This controls if new filenames are created
+ with the case that the client passes, or if they are forced to
+ be the <A
+HREF="#DEFAULTCASE"
+><TT
+CLASS="PARAMETER"
+><I
+>default case
+ </I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>preserve case = yes</B
+></P
+><P
+>See the section on <A
+HREF="#AEN203"
+>NAME
+ MANGLING</A
+> for a fuller discussion.</P
+></DD
+><DT
+><A
+NAME="PRINTCOMMAND"
+></A
+>print command (S)</DT
+><DD
+><P
+>After a print job has finished spooling to
+ a service, this command will be used via a <B
+CLASS="COMMAND"
+>system()</B
+>
+ call to process the spool file. Typically the command specified will
+ submit the spool file to the host's printing subsystem, but there
+ is no requirement that this be the case. The server will not remove
+ the spool file, so whatever command you specify should remove the
+ spool file when it has been processed, otherwise you will need to
+ manually remove old spool files.</P
+><P
+>The print command is simply a text string. It will be used
+ verbatim after macro substitutions have been made:</P
+><P
+>s, %p - the path to the spool
+ file name</P
+><P
+>%p - the appropriate printer
+ name</P
+><P
+>%J - the job
+ name as transmitted by the client.</P
+><P
+>%c - The number of printed pages
+ of the spooled job (if known).</P
+><P
+>%z - the size of the spooled
+ print job (in bytes)</P
+><P
+>The print command <EM
+>MUST</EM
+> contain at least
+ one occurrence of <TT
+CLASS="PARAMETER"
+><I
+>%s</I
+></TT
+> or <TT
+CLASS="PARAMETER"
+><I
+>%f
+ </I
+></TT
+> - the <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is optional. At the time
+ a job is submitted, if no printer name is supplied the <TT
+CLASS="PARAMETER"
+><I
+>%p
+ </I
+></TT
+> will be silently removed from the printer command.</P
+><P
+>If specified in the [global] section, the print command given
+ will be used for any printable service that does not have its own
+ print command specified.</P
+><P
+>If there is neither a specified print command for a
+ printable service nor a global print command, spool files will
+ be created but not processed and (most importantly) not removed.</P
+><P
+>Note that printing may fail on some UNIXes from the
+ <TT
+CLASS="CONSTANT"
+>nobody</TT
+> account. If this happens then create
+ an alternative guest account that can print and set the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+>
+ in the [global] section.</P
+><P
+>You can form quite complex print commands by realizing
+ that they are just passed to a shell. For example the following
+ will log a print job, print the file, then remove it. Note that
+ ';' is the usual separator for command in shell scripts.</P
+><P
+><B
+CLASS="COMMAND"
+>print command = echo Printing %s &#62;&#62;
+ /tmp/print.log; lpr -P %p %s; rm %s</B
+></P
+><P
+>You may have to vary this command considerably depending
+ on how you normally print files on your system. The default for
+ the parameter varies depending on the setting of the <A
+HREF="#PRINTING"
+> <TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: For <B
+CLASS="COMMAND"
+>printing = BSD, AIX, QNX, LPRNG
+ or PLP :</B
+></P
+><P
+><B
+CLASS="COMMAND"
+>print command = lpr -r -P%p %s</B
+></P
+><P
+>For <B
+CLASS="COMMAND"
+>printing = SYSV or HPUX :</B
+></P
+><P
+><B
+CLASS="COMMAND"
+>print command = lp -c -d%p %s; rm %s</B
+></P
+><P
+>For <B
+CLASS="COMMAND"
+>printing = SOFTQ :</B
+></P
+><P
+><B
+CLASS="COMMAND"
+>print command = lp -d%p -s %s; rm %s</B
+></P
+><P
+>For printing = CUPS : If SAMBA is compiled against
+ libcups, then <A
+HREF="#PRINTING"
+>printcap = cups</A
+>
+ uses the CUPS API to
+ submit jobs, etc. Otherwise it maps to the System V
+ commands with the -oraw option for printing, i.e. it
+ uses <B
+CLASS="COMMAND"
+>lp -c -d%p -oraw; rm %s</B
+>.
+ With <B
+CLASS="COMMAND"
+>printing = cups</B
+>,
+ and if SAMBA is compiled against libcups, any manually
+ set print command will be ignored.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>print command = /usr/local/samba/bin/myprintscript
+ %p %s</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTOK"
+></A
+>print ok (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#PRINTABLE"
+> <TT
+CLASS="PARAMETER"
+><I
+>printable</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="PRINTABLE"
+></A
+>printable (S)</DT
+><DD
+><P
+>If this parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, then
+ clients may open, write to and submit spool files on the directory
+ specified for the service. </P
+><P
+>Note that a printable service will ALWAYS allow writing
+ to the service path (user privileges permitting) via the spooling
+ of print data. The <A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>read only
+ </I
+></TT
+></A
+> parameter controls only non-printing access to
+ the resource.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>printable = no</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTCAP"
+></A
+>printcap (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#PRINTCAPNAME"
+><TT
+CLASS="PARAMETER"
+><I
+> printcap name</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="PRINTCAPNAME"
+></A
+>printcap name (G)</DT
+><DD
+><P
+>This parameter may be used to override the
+ compiled-in default printcap name used by the server (usually <TT
+CLASS="FILENAME"
+> /etc/printcap</TT
+>). See the discussion of the <A
+HREF="#AEN79"
+>[printers]</A
+> section above for reasons
+ why you might want to do this.</P
+><P
+>To use the CUPS printing interface set <B
+CLASS="COMMAND"
+>printcap name = cups
+ </B
+>. This should be supplemented by an addtional setting
+ <A
+HREF="#PRINTING"
+>printing = cups</A
+> in the [global]
+ section. <B
+CLASS="COMMAND"
+>printcap name = cups</B
+> will use the
+ "dummy" printcap created by CUPS, as specified in your CUPS
+ configuration file.
+ </P
+><P
+>On System V systems that use <B
+CLASS="COMMAND"
+>lpstat</B
+> to
+ list available printers you can use <B
+CLASS="COMMAND"
+>printcap name = lpstat
+ </B
+> to automatically obtain lists of available printers. This
+ is the default for systems that define SYSV at configure time in
+ Samba (this includes most System V based systems). If <TT
+CLASS="PARAMETER"
+><I
+> printcap name</I
+></TT
+> is set to <B
+CLASS="COMMAND"
+>lpstat</B
+> on
+ these systems then Samba will launch <B
+CLASS="COMMAND"
+>lpstat -v</B
+> and
+ attempt to parse the output to obtain a printer list.</P
+><P
+>A minimal printcap file would look something like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> print1|My Printer 1
+ print2|My Printer 2
+ print3|My Printer 3
+ print4|My Printer 4
+ print5|My Printer 5
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>where the '|' separates aliases of a printer. The fact
+ that the second alias has a space in it gives a hint to Samba
+ that it's a comment.</P
+><P
+><EM
+>NOTE</EM
+>: Under AIX the default printcap
+ name is <TT
+CLASS="FILENAME"
+>/etc/qconfig</TT
+>. Samba will assume the
+ file is in AIX <TT
+CLASS="FILENAME"
+>qconfig</TT
+> format if the string
+ <TT
+CLASS="FILENAME"
+>qconfig</TT
+> appears in the printcap filename.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>printcap name = /etc/printcap</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printcap name = /etc/myprintcap</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTERADMIN"
+></A
+>printer admin (S)</DT
+><DD
+><P
+>This is a list of users that can do anything to
+ printers via the remote administration interfaces offered by MS-RPC
+ (usually using a NT workstation). Note that the root user always
+ has admin rights.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>printer admin = &#60;empty string&#62;</B
+>
+ </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printer admin = admin, @staff</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTERDRIVER"
+></A
+>printer driver (S)</DT
+><DD
+><P
+><EM
+>Note :</EM
+>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <A
+HREF="printer_driver2.html"
+TARGET="_top"
+>Samba 2.2. Printing
+ HOWTO</A
+> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </P
+><P
+>This option allows you to control the string
+ that clients receive when they ask the server for the printer driver
+ associated with a printer. If you are using Windows95 or Windows NT
+ then you can use this to automate the setup of printers on your
+ system.</P
+><P
+>You need to set this parameter to the exact string (case
+ sensitive) that describes the appropriate printer driver for your
+ system. If you don't know the exact string to use then you should
+ first try with no <A
+HREF="#PRINTERDRIVER"
+><TT
+CLASS="PARAMETER"
+><I
+> printer driver</I
+></TT
+></A
+> option set and the client will
+ give you a list of printer drivers. The appropriate strings are
+ shown in a scroll box after you have chosen the printer manufacturer.</P
+><P
+>See also <A
+HREF="#PRINTERDRIVERFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>printer
+ driver file</I
+></TT
+></A
+>.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printer driver = HP LaserJet 4L</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTERDRIVERFILE"
+></A
+>printer driver file (G)</DT
+><DD
+><P
+><EM
+>Note :</EM
+>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <A
+HREF="printer_driver2.html"
+TARGET="_top"
+>Samba 2.2. Printing
+ HOWTO</A
+> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </P
+><P
+>This parameter tells Samba where the printer driver
+ definition file, used when serving drivers to Windows 95 clients, is
+ to be found. If this is not set, the default is :</P
+><P
+><TT
+CLASS="FILENAME"
+><TT
+CLASS="REPLACEABLE"
+><I
+>SAMBA_INSTALL_DIRECTORY</I
+></TT
+>
+ /lib/printers.def</TT
+></P
+><P
+>This file is created from Windows 95 <TT
+CLASS="FILENAME"
+>msprint.inf
+ </TT
+> files found on the Windows 95 client system. For more
+ details on setting up serving of printer drivers to Windows 95
+ clients, see the outdated documentation file in the <TT
+CLASS="FILENAME"
+>docs/</TT
+>
+ directory, <TT
+CLASS="FILENAME"
+>PRINTER_DRIVER.txt</TT
+>.</P
+><P
+>See also <A
+HREF="#PRINTERDRIVERLOCATION"
+><TT
+CLASS="PARAMETER"
+><I
+> printer driver location</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>None (set in compile).</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printer driver file =
+ /usr/local/samba/printers/drivers.def</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTERDRIVERLOCATION"
+></A
+>printer driver location (S)</DT
+><DD
+><P
+><EM
+>Note :</EM
+>This is a deprecated
+ parameter and will be removed in the next major release
+ following version 2.2. Please see the instructions in
+ the <A
+HREF="printer_driver2.html"
+TARGET="_top"
+>Samba 2.2. Printing
+ HOWTO</A
+> for more information
+ on the new method of loading printer drivers onto a Samba server.
+ </P
+><P
+>This parameter tells clients of a particular printer
+ share where to find the printer driver files for the automatic
+ installation of drivers for Windows 95 machines. If Samba is set up
+ to serve printer drivers to Windows 95 machines, this should be set to</P
+><P
+><B
+CLASS="COMMAND"
+>\\MACHINE\PRINTER$</B
+></P
+><P
+>Where MACHINE is the NetBIOS name of your Samba server,
+ and PRINTER$ is a share you set up for serving printer driver
+ files. For more details on setting this up see the outdated documentation
+ file in the <TT
+CLASS="FILENAME"
+>docs/</TT
+> directory, <TT
+CLASS="FILENAME"
+> PRINTER_DRIVER.txt</TT
+>.</P
+><P
+>See also <A
+HREF="#PRINTERDRIVERFILE"
+><TT
+CLASS="PARAMETER"
+><I
+> printer driver file</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>none</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printer driver location = \\MACHINE\PRINTER$
+ </B
+></P
+></DD
+><DT
+><A
+NAME="PRINTERNAME"
+></A
+>printer name (S)</DT
+><DD
+><P
+>This parameter specifies the name of the printer
+ to which print jobs spooled through a printable service will be sent.</P
+><P
+>If specified in the [global] section, the printer
+ name given will be used for any printable service that does
+ not have its own printer name specified.</P
+><P
+>Default: <EM
+>none (but may be <TT
+CLASS="CONSTANT"
+>lp</TT
+>
+ on many systems)</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>printer name = laserwriter</B
+></P
+></DD
+><DT
+><A
+NAME="PRINTER"
+></A
+>printer (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#PRINTERNAME"
+><TT
+CLASS="PARAMETER"
+><I
+> printer name</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="PRINTING"
+></A
+>printing (S)</DT
+><DD
+><P
+>This parameters controls how printer status
+ information is interpreted on your system. It also affects the
+ default values for the <TT
+CLASS="PARAMETER"
+><I
+>print command</I
+></TT
+>,
+ <TT
+CLASS="PARAMETER"
+><I
+>lpq command</I
+></TT
+>, <TT
+CLASS="PARAMETER"
+><I
+>lppause command
+ </I
+></TT
+>, <TT
+CLASS="PARAMETER"
+><I
+>lpresume command</I
+></TT
+>, and
+ <TT
+CLASS="PARAMETER"
+><I
+>lprm command</I
+></TT
+> if specified in the
+ [global] section.</P
+><P
+>Currently nine printing styles are supported. They are
+ <TT
+CLASS="CONSTANT"
+>BSD</TT
+>, <TT
+CLASS="CONSTANT"
+>AIX</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>LPRNG</TT
+>, <TT
+CLASS="CONSTANT"
+>PLP</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>SYSV</TT
+>, <TT
+CLASS="CONSTANT"
+>HPUX</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>QNX</TT
+>, <TT
+CLASS="CONSTANT"
+>SOFTQ</TT
+>,
+ and <TT
+CLASS="CONSTANT"
+>CUPS</TT
+>.</P
+><P
+>To see what the defaults are for the other print
+ commands when using the various options use the <A
+HREF="testparm.1.html"
+TARGET="_top"
+>testparm(1)</A
+> program.</P
+><P
+>This option can be set on a per printer basis</P
+><P
+>See also the discussion in the <A
+HREF="#AEN79"
+> [printers]</A
+> section.</P
+></DD
+><DT
+><A
+NAME="PROFILEACLS"
+></A
+>profile acls (S)</DT
+><DD
+><P
+> This boolean parameter was added to fix the problems that people have been
+ having with storing user profiles on Samba shares from Windows 2000 or
+ Windows XP clients. New versions of Windows 2000 or Windows XP service
+ packs do security ACL checking on the owner and ability to write of the
+ profile directory stored on a local workstation when copied from a Samba
+ share. When not in domain mode with winbindd then the security info copied
+ onto the local workstation has no meaning to the logged in user (SID) on
+ that workstation so the profile storing fails. Adding this parameter
+ onto a share used for profile storage changes two things about the
+ returned Windows ACL. Firstly it changes the owner and group owner
+ of all reported files and directories to be BUILTIN\Administrators,
+ BUILTIN\Users respectively (SIDs S-1-5-32-544, S-1-5-32-545). Secondly
+ it adds an ACE entry of "Full Control" to the SID BUILTIN\Users to
+ every returned ACL. This will allow any Windows 2000 or XP workstation
+ user to access the profile. Note that if you have multiple users logging
+ on to a workstation then in order to prevent them from being able to access
+ each others profiles you must remove the "Bypass traverse checking" advanced
+ user right. This will prevent access to other users profile directories as
+ the top level profile directory (named after the user) is created by the
+ workstation profile code and has an ACL restricting entry to the directory
+ tree to the owning user.</P
+><P
+>If you didn't understand the above text, you probably should not set
+ this parameter :-).</P
+><P
+>Default <B
+CLASS="COMMAND"
+>profile acls = no</B
+></P
+></DD
+><DT
+><A
+NAME="PROTOCOL"
+></A
+>protocol (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#MAXPROTOCOL"
+> <TT
+CLASS="PARAMETER"
+><I
+>max protocol</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="PUBLIC"
+></A
+>public (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#GUESTOK"
+><TT
+CLASS="PARAMETER"
+><I
+>guest
+ ok</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="QUEUEPAUSECOMMAND"
+></A
+>queuepause command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to pause the printer queue.</P
+><P
+>This command should be a program or script which takes
+ a printer name as its only parameter and stops the printer queue,
+ such that no longer jobs are submitted to the printer.</P
+><P
+>This command is not supported by Windows for Workgroups,
+ but can be issued from the Printers window under Windows 95
+ and NT.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the command.
+ </P
+><P
+>Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to the
+ server.</P
+><P
+>Default: <EM
+>depends on the setting of <TT
+CLASS="PARAMETER"
+><I
+>printing
+ </I
+></TT
+></EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>queuepause command = disable %p</B
+></P
+></DD
+><DT
+><A
+NAME="QUEUERESUMECOMMAND"
+></A
+>queueresume command (S)</DT
+><DD
+><P
+>This parameter specifies the command to be
+ executed on the server host in order to resume the printer queue. It
+ is the command to undo the behavior that is caused by the
+ previous parameter (<A
+HREF="#QUEUEPAUSECOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+> queuepause command</I
+></TT
+></A
+>).</P
+><P
+>This command should be a program or script which takes
+ a printer name as its only parameter and resumes the printer queue,
+ such that queued jobs are resubmitted to the printer.</P
+><P
+>This command is not supported by Windows for Workgroups,
+ but can be issued from the Printers window under Windows 95
+ and NT.</P
+><P
+>If a <TT
+CLASS="PARAMETER"
+><I
+>%p</I
+></TT
+> is given then the printer name
+ is put in its place. Otherwise it is placed at the end of the
+ command.</P
+><P
+>Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to the
+ server.</P
+><P
+>Default: <EM
+>depends on the setting of <A
+HREF="#PRINTING"
+><TT
+CLASS="PARAMETER"
+><I
+>printing</I
+></TT
+></A
+></EM
+>
+ </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>queuepause command = enable %p
+ </B
+></P
+></DD
+><DT
+><A
+NAME="READBMPX"
+></A
+>read bmpx (G)</DT
+><DD
+><P
+>This boolean parameter controls whether <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will support the "Read
+ Block Multiplex" SMB. This is now rarely used and defaults to
+ <TT
+CLASS="CONSTANT"
+>no</TT
+>. You should never need to set this
+ parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>read bmpx = no</B
+></P
+></DD
+><DT
+><A
+NAME="READLIST"
+></A
+>read list (S)</DT
+><DD
+><P
+>This is a list of users that are given read-only
+ access to a service. If the connecting user is in this list then
+ they will not be given write access, no matter what the <A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>read only</I
+></TT
+></A
+>
+ option is set to. The list can include group names using the
+ syntax described in the <A
+HREF="#INVALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+> invalid users</I
+></TT
+></A
+> parameter.</P
+><P
+>See also the <A
+HREF="#WRITELIST"
+><TT
+CLASS="PARAMETER"
+><I
+> write list</I
+></TT
+></A
+> parameter and the <A
+HREF="#INVALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>invalid users</I
+></TT
+>
+ </A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>read list = &#60;empty string&#62;</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>read list = mary, @students</B
+></P
+></DD
+><DT
+><A
+NAME="READONLY"
+></A
+>read only (S)</DT
+><DD
+><P
+>An inverted synonym is <A
+HREF="#WRITEABLE"
+> <TT
+CLASS="PARAMETER"
+><I
+>writeable</I
+></TT
+></A
+>.</P
+><P
+>If this parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, then users
+ of a service may not create or modify files in the service's
+ directory.</P
+><P
+>Note that a printable service (<B
+CLASS="COMMAND"
+>printable = yes</B
+>)
+ will <EM
+>ALWAYS</EM
+> allow writing to the directory
+ (user privileges permitting), but only via spooling operations.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>read only = yes</B
+></P
+></DD
+><DT
+><A
+NAME="READRAW"
+></A
+>read raw (G)</DT
+><DD
+><P
+>This parameter controls whether or not the server
+ will support the raw read SMB requests when transferring data
+ to clients.</P
+><P
+>If enabled, raw reads allow reads of 65535 bytes in
+ one packet. This typically provides a major performance benefit.
+ </P
+><P
+>However, some clients either negotiate the allowable
+ block size incorrectly or are incapable of supporting larger block
+ sizes, and for these clients you may need to disable raw reads.</P
+><P
+>In general this parameter should be viewed as a system tuning
+ tool and left severely alone. See also <A
+HREF="#WRITERAW"
+> <TT
+CLASS="PARAMETER"
+><I
+>write raw</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>read raw = yes</B
+></P
+></DD
+><DT
+><A
+NAME="READSIZE"
+></A
+>read size (G)</DT
+><DD
+><P
+>The option <TT
+CLASS="PARAMETER"
+><I
+>read size</I
+></TT
+>
+ affects the overlap of disk reads/writes with network reads/writes.
+ If the amount of data being transferred in several of the SMB
+ commands (currently SMBwrite, SMBwriteX and SMBreadbraw) is larger
+ than this value then the server begins writing the data before it
+ has received the whole packet from the network, or in the case of
+ SMBreadbraw, it begins writing to the network before all the data
+ has been read from disk.</P
+><P
+>This overlapping works best when the speeds of disk and
+ network access are similar, having very little effect when the
+ speed of one is much greater than the other.</P
+><P
+>The default value is 16384, but very little experimentation
+ has been done yet to determine the optimal value, and it is likely
+ that the best value will vary greatly between systems anyway.
+ A value over 65536 is pointless and will cause you to allocate
+ memory unnecessarily.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>read size = 16384</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>read size = 8192</B
+></P
+></DD
+><DT
+><A
+NAME="REMOTEANNOUNCE"
+></A
+>remote announce (G)</DT
+><DD
+><P
+>This option allows you to setup <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> to periodically announce itself
+ to arbitrary IP addresses with an arbitrary workgroup name.</P
+><P
+>This is useful if you want your Samba server to appear
+ in a remote workgroup for which the normal browse propagation
+ rules don't work. The remote workgroup can be anywhere that you
+ can send IP packets to.</P
+><P
+>For example:</P
+><P
+><B
+CLASS="COMMAND"
+>remote announce = 192.168.2.255/SERVERS
+ 192.168.4.255/STAFF</B
+></P
+><P
+>the above line would cause <B
+CLASS="COMMAND"
+>nmbd</B
+> to announce itself
+ to the two given IP addresses using the given workgroup names.
+ If you leave out the workgroup name then the one given in
+ the <A
+HREF="#WORKGROUP"
+><TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+></A
+>
+ parameter is used instead.</P
+><P
+>The IP addresses you choose would normally be the broadcast
+ addresses of the remote networks, but can also be the IP addresses
+ of known browse masters if your network config is that stable.</P
+><P
+>See the documentation file <TT
+CLASS="FILENAME"
+>BROWSING.txt</TT
+>
+ in the <TT
+CLASS="FILENAME"
+>docs/</TT
+> directory.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>remote announce = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="REMOTEBROWSESYNC"
+></A
+>remote browse sync (G)</DT
+><DD
+><P
+>This option allows you to setup <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> to periodically request
+ synchronization of browse lists with the master browser of a Samba
+ server that is on a remote segment. This option will allow you to
+ gain browse lists for multiple workgroups across routed networks. This
+ is done in a manner that does not work with any non-Samba servers.</P
+><P
+>This is useful if you want your Samba server and all local
+ clients to appear in a remote workgroup for which the normal browse
+ propagation rules don't work. The remote workgroup can be anywhere
+ that you can send IP packets to.</P
+><P
+>For example:</P
+><P
+><B
+CLASS="COMMAND"
+>remote browse sync = 192.168.2.255 192.168.4.255
+ </B
+></P
+><P
+>the above line would cause <B
+CLASS="COMMAND"
+>nmbd</B
+> to request
+ the master browser on the specified subnets or addresses to
+ synchronize their browse lists with the local server.</P
+><P
+>The IP addresses you choose would normally be the broadcast
+ addresses of the remote networks, but can also be the IP addresses
+ of known browse masters if your network config is that stable. If
+ a machine IP address is given Samba makes NO attempt to validate
+ that the remote machine is available, is listening, nor that it
+ is in fact the browse master on its segment.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>remote browse sync = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="RESTRICTANONYMOUS"
+></A
+>restrict anonymous (G)</DT
+><DD
+><P
+>This is a boolean parameter. If it is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, then
+ anonymous access to the server will be restricted, namely in the
+ case where the server is expecting the client to send a username,
+ but it doesn't. Setting it to <TT
+CLASS="CONSTANT"
+>yes</TT
+> will force these anonymous
+ connections to be denied, and the client will be required to always
+ supply a username and password when connecting. Use of this parameter
+ is only recommended for homogeneous NT client environments.</P
+><P
+>This parameter makes the use of macro expansions that rely
+ on the username (%U, %G, etc) consistent. NT 4.0
+ likes to use anonymous connections when refreshing the share list,
+ and this is a way to work around that.</P
+><P
+>When restrict anonymous is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, all anonymous connections
+ are denied no matter what they are for. This can effect the ability
+ of a machine to access the Samba Primary Domain Controller to revalidate
+ its machine account after someone else has logged on the client
+ interactively. The NT client will display a message saying that
+ the machine's account in the domain doesn't exist or the password is
+ bad. The best way to deal with this is to reboot NT client machines
+ between interactive logons, using "Shutdown and Restart", rather
+ than "Close all programs and logon as a different user".</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>restrict anonymous = no</B
+></P
+></DD
+><DT
+><A
+NAME="ROOT"
+></A
+>root (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#ROOTDIRECTORY"
+> <TT
+CLASS="PARAMETER"
+><I
+>root directory"</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="ROOTDIR"
+></A
+>root dir (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#ROOTDIRECTORY"
+> <TT
+CLASS="PARAMETER"
+><I
+>root directory"</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="ROOTDIRECTORY"
+></A
+>root directory (G)</DT
+><DD
+><P
+>The server will <B
+CLASS="COMMAND"
+>chroot()</B
+> (i.e.
+ Change its root directory) to this directory on startup. This is
+ not strictly necessary for secure operation. Even without it the
+ server will deny access to files not in one of the service entries.
+ It may also check for, and deny access to, soft links to other
+ parts of the filesystem, or attempts to use ".." in file names
+ to access other directories (depending on the setting of the <A
+HREF="#WIDELINKS"
+><TT
+CLASS="PARAMETER"
+><I
+>wide links</I
+></TT
+></A
+>
+ parameter).</P
+><P
+>Adding a <TT
+CLASS="PARAMETER"
+><I
+>root directory</I
+></TT
+> entry other
+ than "/" adds an extra level of security, but at a price. It
+ absolutely ensures that no access is given to files not in the
+ sub-tree specified in the <TT
+CLASS="PARAMETER"
+><I
+>root directory</I
+></TT
+>
+ option, <EM
+>including</EM
+> some files needed for
+ complete operation of the server. To maintain full operability
+ of the server you will need to mirror some system files
+ into the <TT
+CLASS="PARAMETER"
+><I
+>root directory</I
+></TT
+> tree. In particular
+ you will need to mirror <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+> (or a
+ subset of it), and any binaries or configuration files needed for
+ printing (if required). The set of files that must be mirrored is
+ operating system dependent.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>root directory = /</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>root directory = /homes/smb</B
+></P
+></DD
+><DT
+><A
+NAME="ROOTPOSTEXEC"
+></A
+>root postexec (S)</DT
+><DD
+><P
+>This is the same as the <TT
+CLASS="PARAMETER"
+><I
+>postexec</I
+></TT
+>
+ parameter except that the command is run as root. This
+ is useful for unmounting filesystems
+ (such as CDROMs) after a connection is closed.</P
+><P
+>See also <A
+HREF="#POSTEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+> postexec</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>root postexec = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="ROOTPREEXEC"
+></A
+>root preexec (S)</DT
+><DD
+><P
+>This is the same as the <TT
+CLASS="PARAMETER"
+><I
+>preexec</I
+></TT
+>
+ parameter except that the command is run as root. This
+ is useful for mounting filesystems (such as CDROMs) when a
+ connection is opened.</P
+><P
+>See also <A
+HREF="#PREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+> preexec</I
+></TT
+></A
+> and <A
+HREF="#PREEXECCLOSE"
+> <TT
+CLASS="PARAMETER"
+><I
+>preexec close</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>root preexec = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="ROOTPREEXECCLOSE"
+></A
+>root preexec close (S)</DT
+><DD
+><P
+>This is the same as the <TT
+CLASS="PARAMETER"
+><I
+>preexec close
+ </I
+></TT
+> parameter except that the command is run as root.</P
+><P
+>See also <A
+HREF="#PREEXEC"
+><TT
+CLASS="PARAMETER"
+><I
+> preexec</I
+></TT
+></A
+> and <A
+HREF="#PREEXECCLOSE"
+> <TT
+CLASS="PARAMETER"
+><I
+>preexec close</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>root preexec close = no</B
+></P
+></DD
+><DT
+><A
+NAME="SECURITY"
+></A
+>security (G)</DT
+><DD
+><P
+>This option affects how clients respond to
+ Samba and is one of the most important settings in the <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> file.</P
+><P
+>The option sets the "security mode bit" in replies to
+ protocol negotiations with <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)
+ </A
+> to turn share level security on or off. Clients decide
+ based on this bit whether (and how) to transfer user and password
+ information to the server.</P
+><P
+>The default is <B
+CLASS="COMMAND"
+>security = user</B
+>, as this is
+ the most common setting needed when talking to Windows 98 and
+ Windows NT.</P
+><P
+>The alternatives are <B
+CLASS="COMMAND"
+>security = share</B
+>,
+ <B
+CLASS="COMMAND"
+>security = server</B
+> or <B
+CLASS="COMMAND"
+>security = domain
+ </B
+>.</P
+><P
+>In versions of Samba prior to 2.0.0, the default was
+ <B
+CLASS="COMMAND"
+>security = share</B
+> mainly because that was
+ the only option at one stage.</P
+><P
+>There is a bug in WfWg that has relevance to this
+ setting. When in user or server level security a WfWg client
+ will totally ignore the password you type in the "connect
+ drive" dialog box. This makes it very difficult (if not impossible)
+ to connect to a Samba service as anyone except the user that
+ you are logged into WfWg as.</P
+><P
+>If your PCs use usernames that are the same as their
+ usernames on the UNIX machine then you will want to use
+ <B
+CLASS="COMMAND"
+>security = user</B
+>. If you mostly use usernames
+ that don't exist on the UNIX box then use <B
+CLASS="COMMAND"
+>security =
+ share</B
+>.</P
+><P
+>You should also use <B
+CLASS="COMMAND"
+>security = share</B
+> if you
+ want to mainly setup shares without a password (guest shares). This
+ is commonly used for a shared printer server. It is more difficult
+ to setup guest shares with <B
+CLASS="COMMAND"
+>security = user</B
+>, see
+ the <A
+HREF="#MAPTOGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>map to guest</I
+></TT
+>
+ </A
+>parameter for details.</P
+><P
+>It is possible to use <B
+CLASS="COMMAND"
+>smbd</B
+> in a <EM
+> hybrid mode</EM
+> where it is offers both user and share
+ level security under different <A
+HREF="#NETBIOSALIASES"
+> <TT
+CLASS="PARAMETER"
+><I
+>NetBIOS aliases</I
+></TT
+></A
+>. </P
+><P
+>The different settings will now be explained.</P
+><P
+><A
+NAME="SECURITYEQUALSSHARE"
+></A
+><EM
+>SECURITY = SHARE
+ </EM
+></P
+><P
+>When clients connect to a share level security server they
+ need not log onto the server with a valid username and password before
+ attempting to connect to a shared resource (although modern clients
+ such as Windows 95/98 and Windows NT will send a logon request with
+ a username but no password when talking to a <B
+CLASS="COMMAND"
+>security = share
+ </B
+> server). Instead, the clients send authentication information
+ (passwords) on a per-share basis, at the time they attempt to connect
+ to that share.</P
+><P
+>Note that <B
+CLASS="COMMAND"
+>smbd</B
+> <EM
+>ALWAYS</EM
+>
+ uses a valid UNIX user to act on behalf of the client, even in
+ <B
+CLASS="COMMAND"
+>security = share</B
+> level security.</P
+><P
+>As clients are not required to send a username to the server
+ in share level security, <B
+CLASS="COMMAND"
+>smbd</B
+> uses several
+ techniques to determine the correct UNIX user to use on behalf
+ of the client.</P
+><P
+>A list of possible UNIX usernames to match with the given
+ client password is constructed using the following methods :</P
+><P
+></P
+><UL
+><LI
+><P
+>If the <A
+HREF="#GUESTONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>guest
+ only</I
+></TT
+></A
+> parameter is set, then all the other
+ stages are missed and only the <A
+HREF="#GUESTACCOUNT"
+> <TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+> username is checked.
+ </P
+></LI
+><LI
+><P
+>Is a username is sent with the share connection
+ request, then this username (after mapping - see <A
+HREF="#USERNAMEMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>username map</I
+></TT
+></A
+>),
+ is added as a potential username.</P
+></LI
+><LI
+><P
+>If the client did a previous <EM
+>logon
+ </EM
+> request (the SessionSetup SMB call) then the
+ username sent in this SMB will be added as a potential username.
+ </P
+></LI
+><LI
+><P
+>The name of the service the client requested is
+ added as a potential username.</P
+></LI
+><LI
+><P
+>The NetBIOS name of the client is added to
+ the list as a potential username.</P
+></LI
+><LI
+><P
+>Any users on the <A
+HREF="#USER"
+><TT
+CLASS="PARAMETER"
+><I
+> user</I
+></TT
+></A
+> list are added as potential usernames.
+ </P
+></LI
+></UL
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>guest only</I
+></TT
+> parameter is
+ not set, then this list is then tried with the supplied password.
+ The first user for whom the password matches will be used as the
+ UNIX user.</P
+><P
+>If the <TT
+CLASS="PARAMETER"
+><I
+>guest only</I
+></TT
+> parameter is
+ set, or no username can be determined then if the share is marked
+ as available to the <TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+>, then this
+ guest user will be used, otherwise access is denied.</P
+><P
+>Note that it can be <EM
+>very</EM
+> confusing
+ in share-level security as to which UNIX username will eventually
+ be used in granting access.</P
+><P
+>See also the section <A
+HREF="#AEN241"
+> NOTE ABOUT USERNAME/PASSWORD VALIDATION</A
+>.</P
+><P
+><A
+NAME="SECURITYEQUALSUSER"
+></A
+><EM
+>SECURITY = USER
+ </EM
+></P
+><P
+>This is the default security setting in Samba 2.2.
+ With user-level security a client must first "log-on" with a
+ valid username and password (which can be mapped using the <A
+HREF="#USERNAMEMAP"
+><TT
+CLASS="PARAMETER"
+><I
+>username map</I
+></TT
+></A
+>
+ parameter). Encrypted passwords (see the <A
+HREF="#ENCRYPTPASSWORDS"
+> <TT
+CLASS="PARAMETER"
+><I
+>encrypted passwords</I
+></TT
+></A
+> parameter) can also
+ be used in this security mode. Parameters such as <A
+HREF="#USER"
+> <TT
+CLASS="PARAMETER"
+><I
+>user</I
+></TT
+></A
+> and <A
+HREF="#GUESTONLY"
+> <TT
+CLASS="PARAMETER"
+><I
+>guest only</I
+></TT
+></A
+> if set are then applied and
+ may change the UNIX user to use on this connection, but only after
+ the user has been successfully authenticated.</P
+><P
+><EM
+>Note</EM
+> that the name of the resource being
+ requested is <EM
+>not</EM
+> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+>.
+ See the <A
+HREF="#MAPTOGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>map to guest</I
+></TT
+>
+ </A
+> parameter for details on doing this.</P
+><P
+>See also the section <A
+HREF="#AEN241"
+> NOTE ABOUT USERNAME/PASSWORD VALIDATION</A
+>.</P
+><P
+><A
+NAME="SECURITYEQUALSSERVER"
+></A
+><EM
+>SECURITY = SERVER
+ </EM
+></P
+><P
+>In this mode Samba will try to validate the username/password
+ by passing it to another SMB server, such as an NT box. If this
+ fails it will revert to <B
+CLASS="COMMAND"
+>security = user</B
+>, but note
+ that if encrypted passwords have been negotiated then Samba cannot
+ revert back to checking the UNIX password file, it must have a valid
+ <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file to check users against. See the
+ documentation file in the <TT
+CLASS="FILENAME"
+>docs/</TT
+> directory
+ <TT
+CLASS="FILENAME"
+>ENCRYPTION.txt</TT
+> for details on how to set this
+ up.</P
+><P
+><EM
+>Note</EM
+> that from the client's point of
+ view <B
+CLASS="COMMAND"
+>security = server</B
+> is the same as <B
+CLASS="COMMAND"
+> security = user</B
+>. It only affects how the server deals
+ with the authentication, it does not in any way affect what the
+ client sees.</P
+><P
+><EM
+>Note</EM
+> that the name of the resource being
+ requested is <EM
+>not</EM
+> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+>.
+ See the <A
+HREF="#MAPTOGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>map to guest</I
+></TT
+>
+ </A
+> parameter for details on doing this.</P
+><P
+>See also the section <A
+HREF="#AEN241"
+> NOTE ABOUT USERNAME/PASSWORD VALIDATION</A
+>.</P
+><P
+>See also the <A
+HREF="#PASSWORDSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>password
+ server</I
+></TT
+></A
+> parameter and the <A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypted passwords</I
+></TT
+>
+ </A
+> parameter.</P
+><P
+><A
+NAME="SECURITYEQUALSDOMAIN"
+></A
+><EM
+>SECURITY = DOMAIN
+ </EM
+></P
+><P
+>This mode will only work correctly if <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+>smbpasswd(8)</A
+> has been used to add this
+ machine into a Windows NT Domain. It expects the <A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypted passwords</I
+></TT
+>
+ </A
+> parameter to be set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>. In this
+ mode Samba will try to validate the username/password by passing
+ it to a Windows NT Primary or Backup Domain Controller, in exactly
+ the same way that a Windows NT Server would do.</P
+><P
+><EM
+>Note</EM
+> that a valid UNIX user must still
+ exist as well as the account on the Domain Controller to allow
+ Samba to have a valid UNIX account to map file access to.</P
+><P
+><EM
+>Note</EM
+> that from the client's point
+ of view <B
+CLASS="COMMAND"
+>security = domain</B
+> is the same as <B
+CLASS="COMMAND"
+>security = user
+ </B
+>. It only affects how the server deals with the authentication,
+ it does not in any way affect what the client sees.</P
+><P
+><EM
+>Note</EM
+> that the name of the resource being
+ requested is <EM
+>not</EM
+> sent to the server until after
+ the server has successfully authenticated the client. This is why
+ guest shares don't work in user level security without allowing
+ the server to automatically map unknown users into the <A
+HREF="#GUESTACCOUNT"
+><TT
+CLASS="PARAMETER"
+><I
+>guest account</I
+></TT
+></A
+>.
+ See the <A
+HREF="#MAPTOGUEST"
+><TT
+CLASS="PARAMETER"
+><I
+>map to guest</I
+></TT
+>
+ </A
+> parameter for details on doing this.</P
+><P
+><EM
+>BUG:</EM
+> There is currently a bug in the
+ implementation of <B
+CLASS="COMMAND"
+>security = domain</B
+> with respect
+ to multi-byte character set usernames. The communication with a
+ Domain Controller must be done in UNICODE and Samba currently
+ does not widen multi-byte user names to UNICODE correctly, thus
+ a multi-byte username will not be recognized correctly at the
+ Domain Controller. This issue will be addressed in a future release.</P
+><P
+>See also the section <A
+HREF="#AEN241"
+> NOTE ABOUT USERNAME/PASSWORD VALIDATION</A
+>.</P
+><P
+>See also the <A
+HREF="#PASSWORDSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+>password
+ server</I
+></TT
+></A
+> parameter and the <A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypted passwords</I
+></TT
+>
+ </A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>security = USER</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>security = DOMAIN</B
+></P
+></DD
+><DT
+><A
+NAME="SECURITYMASK"
+></A
+>security mask (S)</DT
+><DD
+><P
+>This parameter controls what UNIX permission
+ bits can be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT security
+ dialog box.</P
+><P
+>This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits not in
+ this mask from being modified. Essentially, zero bits in this
+ mask may be treated as a set of bits the user is not allowed
+ to change.</P
+><P
+>If not set explicitly this parameter is 0777, allowing
+ a user to modify all the user/group/world permissions on a file.
+ </P
+><P
+><EM
+>Note</EM
+> that users who can access the
+ Samba server through other means can easily bypass this
+ restriction, so it is primarily useful for standalone
+ "appliance" systems. Administrators of most normal systems will
+ probably want to leave it set to <TT
+CLASS="CONSTANT"
+>0777</TT
+>.</P
+><P
+>See also the <A
+HREF="#FORCEDIRECTORYSECURITYMODE"
+> <TT
+CLASS="PARAMETER"
+><I
+>force directory security mode</I
+></TT
+></A
+>,
+ <A
+HREF="#DIRECTORYSECURITYMASK"
+><TT
+CLASS="PARAMETER"
+><I
+>directory
+ security mask</I
+></TT
+></A
+>, <A
+HREF="#FORCESECURITYMODE"
+> <TT
+CLASS="PARAMETER"
+><I
+>force security mode</I
+></TT
+></A
+> parameters.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>security mask = 0777</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>security mask = 0770</B
+></P
+></DD
+><DT
+><A
+NAME="SERVERSTRING"
+></A
+>server string (G)</DT
+><DD
+><P
+>This controls what string will show up in the
+ printer comment box in print manager and next to the IPC connection
+ in <B
+CLASS="COMMAND"
+>net view</B
+>. It can be any string that you wish
+ to show to your users.</P
+><P
+>It also sets what will appear in browse lists next
+ to the machine name.</P
+><P
+>A <TT
+CLASS="PARAMETER"
+><I
+>%v</I
+></TT
+> will be replaced with the Samba
+ version number.</P
+><P
+>A <TT
+CLASS="PARAMETER"
+><I
+>%h</I
+></TT
+> will be replaced with the
+ hostname.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>server string = Samba %v</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>server string = University of GNUs Samba
+ Server</B
+></P
+></DD
+><DT
+><A
+NAME="SETDIRECTORY"
+></A
+>set directory (S)</DT
+><DD
+><P
+>If <B
+CLASS="COMMAND"
+>set directory = no</B
+>, then
+ users of the service may not use the setdir command to change
+ directory.</P
+><P
+>The <B
+CLASS="COMMAND"
+>setdir</B
+> command is only implemented
+ in the Digital Pathworks client. See the Pathworks documentation
+ for details.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>set directory = no</B
+></P
+></DD
+><DT
+><A
+NAME="SHAREMODES"
+></A
+>share modes (S)</DT
+><DD
+><P
+>This enables or disables the honoring of
+ the <TT
+CLASS="PARAMETER"
+><I
+>share modes</I
+></TT
+> during a file open. These
+ modes are used by clients to gain exclusive read or write access
+ to a file.</P
+><P
+>These open modes are not directly supported by UNIX, so
+ they are simulated using shared memory, or lock files if your
+ UNIX doesn't support shared memory (almost all do).</P
+><P
+>The share modes that are enabled by this option are
+ <TT
+CLASS="CONSTANT"
+>DENY_DOS</TT
+>, <TT
+CLASS="CONSTANT"
+>DENY_ALL</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>DENY_READ</TT
+>, <TT
+CLASS="CONSTANT"
+>DENY_WRITE</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>DENY_NONE</TT
+> and <TT
+CLASS="CONSTANT"
+>DENY_FCB</TT
+>.
+ </P
+><P
+>This option gives full share compatibility and enabled
+ by default.</P
+><P
+>You should <EM
+>NEVER</EM
+> turn this parameter
+ off as many Windows applications will break if you do so.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>share modes = yes</B
+></P
+></DD
+><DT
+><A
+NAME="SHORTPRESERVECASE"
+></A
+>short preserve case (S)</DT
+><DD
+><P
+>This boolean parameter controls if new files
+ which conform to 8.3 syntax, that is all in upper case and of
+ suitable length, are created upper case, or if they are forced
+ to be the <A
+HREF="#DEFAULTCASE"
+><TT
+CLASS="PARAMETER"
+><I
+>default case
+ </I
+></TT
+></A
+>. This option can be use with <A
+HREF="#PRESERVECASE"
+><B
+CLASS="COMMAND"
+>preserve case = yes</B
+>
+ </A
+> to permit long filenames to retain their case, while short
+ names are lowered. </P
+><P
+>See the section on <A
+HREF="#AEN203"
+> NAME MANGLING</A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>short preserve case = yes</B
+></P
+></DD
+><DT
+><A
+NAME="SHOWADDPRINTERWIZARD"
+></A
+>show add printer wizard (G)</DT
+><DD
+><P
+>With the introduction of MS-RPC based printing support
+ for Windows NT/2000 client in Samba 2.2, a "Printers..." folder will
+ appear on Samba hosts in the share listing. Normally this folder will
+ contain an icon for the MS Add Printer Wizard (APW). However, it is
+ possible to disable this feature regardless of the level of privilege
+ of the connected user.</P
+><P
+>Under normal circumstances, the Windows NT/2000 client will
+ open a handle on the printer server with OpenPrinterEx() asking for
+ Administrator privileges. If the user does not have administrative
+ access on the print server (i.e is not root or a member of the
+ <TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+> group), the OpenPrinterEx()
+ call fails and the client makes another open call with a request for
+ a lower privilege level. This should succeed, however the APW
+ icon will not be displayed.</P
+><P
+>Disabling the <TT
+CLASS="PARAMETER"
+><I
+>show add printer wizard</I
+></TT
+>
+ parameter will always cause the OpenPrinterEx() on the server
+ to fail. Thus the APW icon will never be displayed. <EM
+> Note :</EM
+>This does not prevent the same user from having
+ administrative privilege on an individual printer.</P
+><P
+>See also <A
+HREF="#ADDPRINTERCOMMAND"
+><TT
+CLASS="PARAMETER"
+><I
+>addprinter
+ command</I
+></TT
+></A
+>, <A
+HREF="#DELETEPRINTERCOMMAND"
+> <TT
+CLASS="PARAMETER"
+><I
+>deleteprinter command</I
+></TT
+></A
+>, <A
+HREF="#PRINTERADMIN"
+><TT
+CLASS="PARAMETER"
+><I
+>printer admin</I
+></TT
+></A
+></P
+><P
+>Default :<B
+CLASS="COMMAND"
+>show add printer wizard = yes</B
+></P
+></DD
+><DT
+><A
+NAME="SMBPASSWDFILE"
+></A
+>smb passwd file (G)</DT
+><DD
+><P
+>This option sets the path to the encrypted
+ smbpasswd file. By default the path to the smbpasswd file
+ is compiled into Samba.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>smb passwd file = ${prefix}/private/smbpasswd
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>smb passwd file = /etc/samba/smbpasswd
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SOCKETADDRESS"
+></A
+>socket address (G)</DT
+><DD
+><P
+>This option allows you to control what
+ address Samba will listen for connections on. This is used to
+ support multiple virtual interfaces on the one server, each
+ with a different configuration.</P
+><P
+>By default Samba will accept connections on any
+ address.</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>socket address = 192.168.2.20</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="SOCKETOPTIONS"
+></A
+>socket options (G)</DT
+><DD
+><P
+>This option allows you to set socket options
+ to be used when talking with the client.</P
+><P
+>Socket options are controls on the networking layer
+ of the operating systems which allow the connection to be
+ tuned.</P
+><P
+>This option will typically be used to tune your Samba
+ server for optimal performance for your local network. There is
+ no way that Samba can know what the optimal parameters are for
+ your net, so you must experiment and choose them yourself. We
+ strongly suggest you read the appropriate documentation for your
+ operating system first (perhaps <B
+CLASS="COMMAND"
+>man setsockopt</B
+>
+ will help).</P
+><P
+>You may find that on some systems Samba will say
+ "Unknown socket option" when you supply an option. This means you
+ either incorrectly typed it or you need to add an include file
+ to includes.h for your OS. If the latter is the case please
+ send the patch to <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+> samba@samba.org</A
+>.</P
+><P
+>Any of the supported socket options may be combined
+ in any way you like, as long as your OS allows it.</P
+><P
+>This is the list of socket options currently settable
+ using this option:</P
+><P
+></P
+><UL
+><LI
+><P
+>SO_KEEPALIVE</P
+></LI
+><LI
+><P
+>SO_REUSEADDR</P
+></LI
+><LI
+><P
+>SO_BROADCAST</P
+></LI
+><LI
+><P
+>TCP_NODELAY</P
+></LI
+><LI
+><P
+>IPTOS_LOWDELAY</P
+></LI
+><LI
+><P
+>IPTOS_THROUGHPUT</P
+></LI
+><LI
+><P
+>SO_SNDBUF *</P
+></LI
+><LI
+><P
+>SO_RCVBUF *</P
+></LI
+><LI
+><P
+>SO_SNDLOWAT *</P
+></LI
+><LI
+><P
+>SO_RCVLOWAT *</P
+></LI
+></UL
+><P
+>Those marked with a <EM
+>'*'</EM
+> take an integer
+ argument. The others can optionally take a 1 or 0 argument to enable
+ or disable the option, by default they will be enabled if you
+ don't specify 1 or 0.</P
+><P
+>To specify an argument use the syntax SOME_OPTION = VALUE
+ for example <B
+CLASS="COMMAND"
+>SO_SNDBUF = 8192</B
+>. Note that you must
+ not have any spaces before or after the = sign.</P
+><P
+>If you are on a local network then a sensible option
+ might be</P
+><P
+><B
+CLASS="COMMAND"
+>socket options = IPTOS_LOWDELAY</B
+></P
+><P
+>If you have a local network then you could try:</P
+><P
+><B
+CLASS="COMMAND"
+>socket options = IPTOS_LOWDELAY TCP_NODELAY</B
+></P
+><P
+>If you are on a wide area network then perhaps try
+ setting IPTOS_THROUGHPUT. </P
+><P
+>Note that several of the options may cause your Samba
+ server to fail completely. Use these options with caution!</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>socket options = TCP_NODELAY</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>socket options = IPTOS_LOWDELAY</B
+></P
+></DD
+><DT
+><A
+NAME="SOURCEENVIRONMENT"
+></A
+>source environment (G)</DT
+><DD
+><P
+>This parameter causes Samba to set environment
+ variables as per the content of the file named.</P
+><P
+>If the value of this parameter starts with a "|" character
+ then Samba will treat that value as a pipe command to open and
+ will set the environment variables from the output of the pipe.</P
+><P
+>The contents of the file or the output of the pipe should
+ be formatted as the output of the standard Unix <B
+CLASS="COMMAND"
+>env(1)
+ </B
+> command. This is of the form :</P
+><P
+>Example environment entry:</P
+><P
+><B
+CLASS="COMMAND"
+>SAMBA_NETBIOS_NAME = myhostname</B
+></P
+><P
+>Default: <EM
+>No default value</EM
+></P
+><P
+>Examples: <B
+CLASS="COMMAND"
+>source environment = |/etc/smb.conf.sh
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>source environment =
+ /usr/local/smb_env_vars</B
+></P
+></DD
+><DT
+><A
+NAME="SSL"
+></A
+>ssl (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This variable enables or disables the entire SSL mode. If
+ it is set to <TT
+CLASS="CONSTANT"
+>no</TT
+>, the SSL-enabled Samba behaves
+ exactly like the non-SSL Samba. If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>,
+ it depends on the variables <A
+HREF="#SSLHOSTS"
+><TT
+CLASS="PARAMETER"
+><I
+> ssl hosts</I
+></TT
+></A
+> and <A
+HREF="#SSLHOSTSRESIGN"
+> <TT
+CLASS="PARAMETER"
+><I
+>ssl hosts resign</I
+></TT
+></A
+> whether an SSL
+ connection will be required.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl = no</B
+></P
+></DD
+><DT
+><A
+NAME="SSLCACERTDIR"
+></A
+>ssl CA certDir (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This variable defines where to look up the Certification
+ Authorities. The given directory should contain one file for
+ each CA that Samba will trust. The file name must be the hash
+ value over the "Distinguished Name" of the CA. How this directory
+ is set up is explained later in this document. All files within the
+ directory that don't fit into this naming scheme are ignored. You
+ don't need this variable if you don't verify client certificates.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl CA certDir = /usr/local/ssl/certs
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLCACERTFILE"
+></A
+>ssl CA certFile (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This variable is a second way to define the trusted CAs.
+ The certificates of the trusted CAs are collected in one big
+ file and this variable points to the file. You will probably
+ only use one of the two ways to define your CAs. The first choice is
+ preferable if you have many CAs or want to be flexible, the second
+ is preferable if you only have one CA and want to keep things
+ simple (you won't need to create the hashed file names). You
+ don't need this variable if you don't verify client certificates.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl CA certFile = /usr/local/ssl/certs/trustedCAs.pem
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLCIPHERS"
+></A
+>ssl ciphers (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This variable defines the ciphers that should be offered
+ during SSL negotiation. You should not set this variable unless
+ you know what you are doing.</P
+></DD
+><DT
+><A
+NAME="SSLCLIENTCERT"
+></A
+>ssl client cert (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>The certificate in this file is used by <A
+HREF="smbclient.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+> if it exists. It's needed
+ if the server requires a client certificate.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl client cert = /usr/local/ssl/certs/smbclient.pem
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLCLIENTKEY"
+></A
+>ssl client key (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This is the private key for <A
+HREF="smbclient.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+>. It's only needed if the
+ client should have a certificate. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl client key = /usr/local/ssl/private/smbclient.pem
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLCOMPATIBILITY"
+></A
+>ssl compatibility (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This variable defines whether OpenSSL should be configured
+ for bug compatibility with other SSL implementations. This is
+ probably not desirable because currently no clients with SSL
+ implementations other than OpenSSL exist.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl compatibility = no</B
+></P
+></DD
+><DT
+><A
+NAME="SSLEGDSOCKET"
+></A
+>ssl egd socket (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+> This option is used to define the location of the communiation socket of
+ an EGD or PRNGD daemon, from which entropy can be retrieved. This option
+ can be used instead of or together with the <A
+HREF="#SSLENTROPYFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl entropy file</I
+></TT
+></A
+>
+ directive. 255 bytes of entropy will be retrieved from the daemon.
+ </P
+><P
+>Default: <EM
+>none</EM
+></P
+></DD
+><DT
+><A
+NAME="SSLENTROPYBYTES"
+></A
+>ssl entropy bytes (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+> This parameter is used to define the number of bytes which should
+ be read from the <A
+HREF="#SSLENTROPYFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl entropy
+ file</I
+></TT
+></A
+> If a -1 is specified, the entire file will
+ be read.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl entropy bytes = 255</B
+></P
+></DD
+><DT
+><A
+NAME="SSLENTROPYFILE"
+></A
+>ssl entropy file (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+> This parameter is used to specify a file from which processes will
+ read "random bytes" on startup. In order to seed the internal pseudo
+ random number generator, entropy must be provided. On system with a
+ <TT
+CLASS="FILENAME"
+>/dev/urandom</TT
+> device file, the processes
+ will retrieve its entropy from the kernel. On systems without kernel
+ entropy support, a file can be supplied that will be read on startup
+ and that will be used to seed the PRNG.
+ </P
+><P
+>Default: <EM
+>none</EM
+></P
+></DD
+><DT
+><A
+NAME="SSLHOSTS"
+></A
+>ssl hosts (G)</DT
+><DD
+><P
+>See <A
+HREF="#SSLHOSTSRESIGN"
+><TT
+CLASS="PARAMETER"
+><I
+> ssl hosts resign</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="SSLHOSTSRESIGN"
+></A
+>ssl hosts resign (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>These two variables define whether Samba will go
+ into SSL mode or not. If none of them is defined, Samba will
+ allow only SSL connections. If the <A
+HREF="#SSLHOSTS"
+> <TT
+CLASS="PARAMETER"
+><I
+>ssl hosts</I
+></TT
+></A
+> variable lists
+ hosts (by IP-address, IP-address range, net group or name),
+ only these hosts will be forced into SSL mode. If the <TT
+CLASS="PARAMETER"
+><I
+> ssl hosts resign</I
+></TT
+> variable lists hosts, only these
+ hosts will <EM
+>NOT</EM
+> be forced into SSL mode. The syntax for these two
+ variables is the same as for the <A
+HREF="#HOSTSALLOW"
+><TT
+CLASS="PARAMETER"
+><I
+> hosts allow</I
+></TT
+></A
+> and <A
+HREF="#HOSTSDENY"
+> <TT
+CLASS="PARAMETER"
+><I
+>hosts deny</I
+></TT
+></A
+> pair of variables, only
+ that the subject of the decision is different: It's not the access
+ right but whether SSL is used or not. </P
+><P
+>The example below requires SSL connections from all hosts
+ outside the local net (which is 192.168.*.*).</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl hosts = &#60;empty string&#62;</B
+></P
+><P
+><B
+CLASS="COMMAND"
+>ssl hosts resign = &#60;empty string&#62;</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>ssl hosts resign = 192.168.</B
+></P
+></DD
+><DT
+><A
+NAME="SSLREQUIRECLIENTCERT"
+></A
+>ssl require clientcert (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>If this variable is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, the
+ server will not tolerate connections from clients that don't
+ have a valid certificate. The directory/file given in <A
+HREF="#SSLCACERTDIR"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl CA certDir</I
+></TT
+>
+ </A
+> and <A
+HREF="#SSLCACERTFILE"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl CA certFile
+ </I
+></TT
+></A
+> will be used to look up the CAs that issued
+ the client's certificate. If the certificate can't be verified
+ positively, the connection will be terminated. If this variable
+ is set to <TT
+CLASS="CONSTANT"
+>no</TT
+>, clients don't need certificates.
+ Contrary to web applications you really <EM
+>should</EM
+>
+ require client certificates. In the web environment the client's
+ data is sensitive (credit card numbers) and the server must prove
+ to be trustworthy. In a file server environment the server's data
+ will be sensitive and the clients must prove to be trustworthy.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl require clientcert = no</B
+></P
+></DD
+><DT
+><A
+NAME="SSLREQUIRESERVERCERT"
+></A
+>ssl require servercert (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>If this variable is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>, the
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+>
+ </A
+> will request a certificate from the server. Same as
+ <A
+HREF="#SSLREQUIRECLIENTCERT"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl require
+ clientcert</I
+></TT
+></A
+> for the server.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl require servercert = no</B
+>
+ </P
+></DD
+><DT
+><A
+NAME="SSLSERVERCERT"
+></A
+>ssl server cert (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This is the file containing the server's certificate.
+ The server <EM
+>must</EM
+> have a certificate. The
+ file may also contain the server's private key. See later for
+ how certificates and private keys are created.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl server cert = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLSERVERKEY"
+></A
+>ssl server key (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This file contains the private key of the server. If
+ this variable is not defined, the key is looked up in the
+ certificate file (it may be appended to the certificate).
+ The server <EM
+>must</EM
+> have a private key
+ and the certificate <EM
+>must</EM
+>
+ match this private key.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl server key = &#60;empty string&#62;
+ </B
+></P
+></DD
+><DT
+><A
+NAME="SSLVERSION"
+></A
+>ssl version (G)</DT
+><DD
+><P
+>This variable is part of SSL-enabled Samba. This
+ is only available if the SSL libraries have been compiled on your
+ system and the configure option <B
+CLASS="COMMAND"
+>--with-ssl</B
+> was
+ given at configure time.</P
+><P
+>This enumeration variable defines the versions of the
+ SSL protocol that will be used. <TT
+CLASS="CONSTANT"
+>ssl2or3</TT
+> allows
+ dynamic negotiation of SSL v2 or v3, <TT
+CLASS="CONSTANT"
+>ssl2</TT
+> results
+ in SSL v2, <TT
+CLASS="CONSTANT"
+>ssl3</TT
+> results in SSL v3 and
+ <TT
+CLASS="CONSTANT"
+>tls1</TT
+> results in TLS v1. TLS (Transport Layer
+ Security) is the new standard for SSL.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>ssl version = "ssl2or3"</B
+></P
+></DD
+><DT
+><A
+NAME="STATCACHE"
+></A
+>stat cache (G)</DT
+><DD
+><P
+>This parameter determines if <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+> will use a cache in order to
+ speed up case insensitive name mappings. You should never need
+ to change this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>stat cache = yes</B
+></P
+></DD
+><DT
+><A
+NAME="STATCACHESIZE"
+></A
+>stat cache size (G)</DT
+><DD
+><P
+>This parameter determines the number of
+ entries in the <TT
+CLASS="PARAMETER"
+><I
+>stat cache</I
+></TT
+>. You should
+ never need to change this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>stat cache size = 50</B
+></P
+></DD
+><DT
+><A
+NAME="STATUS"
+></A
+>status (G)</DT
+><DD
+><P
+>This enables or disables logging of connections
+ to a status file that <A
+HREF="smbstatus.1.html"
+TARGET="_top"
+>smbstatus(1)</A
+>
+ can read.</P
+><P
+>With this disabled <B
+CLASS="COMMAND"
+>smbstatus</B
+> won't be able
+ to tell you what connections are active. You should never need to
+ change this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>status = yes</B
+></P
+></DD
+><DT
+><A
+NAME="STRICTALLOCATE"
+></A
+>strict allocate (S)</DT
+><DD
+><P
+>This is a boolean that controls the handling of
+ disk space allocation in the server. When this is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>
+ the server will change from UNIX behaviour of not committing real
+ disk storage blocks when a file is extended to the Windows behaviour
+ of actually forcing the disk system to allocate real storage blocks
+ when a file is created or extended to be a given size. In UNIX
+ terminology this means that Samba will stop creating sparse files.
+ This can be slow on some systems.</P
+><P
+>When strict allocate is <TT
+CLASS="CONSTANT"
+>no</TT
+> the server does sparse
+ disk block allocation when a file is extended.</P
+><P
+>Setting this to <TT
+CLASS="CONSTANT"
+>yes</TT
+> can help Samba return
+ out of quota messages on systems that are restricting the disk quota
+ of users.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>strict allocate = no</B
+></P
+></DD
+><DT
+><A
+NAME="STRICTLOCKING"
+></A
+>strict locking (S)</DT
+><DD
+><P
+>This is a boolean that controls the handling of
+ file locking in the server. When this is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>
+ the server will check every read and write access for file locks, and
+ deny access if locks exist. This can be slow on some systems.</P
+><P
+>When strict locking is <TT
+CLASS="CONSTANT"
+>no</TT
+> the server does file
+ lock checks only when the client explicitly asks for them.</P
+><P
+>Well-behaved clients always ask for lock checks when it
+ is important, so in the vast majority of cases <B
+CLASS="COMMAND"
+>strict
+ locking = no</B
+> is preferable.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>strict locking = no</B
+></P
+></DD
+><DT
+><A
+NAME="STRICTSYNC"
+></A
+>strict sync (S)</DT
+><DD
+><P
+>Many Windows applications (including the Windows
+ 98 explorer shell) seem to confuse flushing buffer contents to
+ disk with doing a sync to disk. Under UNIX, a sync call forces
+ the process to be suspended until the kernel has ensured that
+ all outstanding data in kernel disk buffers has been safely stored
+ onto stable storage. This is very slow and should only be done
+ rarely. Setting this parameter to <TT
+CLASS="CONSTANT"
+>no</TT
+> (the
+ default) means that <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> ignores the Windows applications requests for
+ a sync call. There is only a possibility of losing data if the
+ operating system itself that Samba is running on crashes, so there is
+ little danger in this default setting. In addition, this fixes many
+ performance problems that people have reported with the new Windows98
+ explorer shell file copies.</P
+><P
+>See also the <A
+HREF="#SYNCALWAYS"
+><TT
+CLASS="PARAMETER"
+><I
+>sync
+ always&#62;</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>strict sync = no</B
+></P
+></DD
+><DT
+><A
+NAME="STRIPDOT"
+></A
+>strip dot (G)</DT
+><DD
+><P
+>This parameter is now unused in Samba (2.2.5 and above).
+ It used strip trailing dots off UNIX filenames but was not correctly implmented.
+ In Samba 2.2.5 and above UNIX filenames ending in a dot are invalid Windows long
+ filenames (as they are in Windows NT and above) and are mangled to 8.3 before
+ being returned to a client.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>strip dot = no</B
+></P
+></DD
+><DT
+><A
+NAME="SYNCALWAYS"
+></A
+>sync always (S)</DT
+><DD
+><P
+>This is a boolean parameter that controls
+ whether writes will always be written to stable storage before
+ the write call returns. If this is <TT
+CLASS="CONSTANT"
+>no</TT
+> then the server will be
+ guided by the client's request in each write call (clients can
+ set a bit indicating that a particular write should be synchronous).
+ If this is <TT
+CLASS="CONSTANT"
+>yes</TT
+> then every write will be followed by a <B
+CLASS="COMMAND"
+>fsync()
+ </B
+> call to ensure the data is written to disk. Note that
+ the <TT
+CLASS="PARAMETER"
+><I
+>strict sync</I
+></TT
+> parameter must be set to
+ <TT
+CLASS="CONSTANT"
+>yes</TT
+> in order for this parameter to have
+ any affect.</P
+><P
+>See also the <A
+HREF="#STRICTSYNC"
+><TT
+CLASS="PARAMETER"
+><I
+>strict
+ sync</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>sync always = no</B
+></P
+></DD
+><DT
+><A
+NAME="SYSLOG"
+></A
+>syslog (G)</DT
+><DD
+><P
+>This parameter maps how Samba debug messages
+ are logged onto the system syslog logging levels. Samba debug
+ level zero maps onto syslog <TT
+CLASS="CONSTANT"
+>LOG_ERR</TT
+>, debug
+ level one maps onto <TT
+CLASS="CONSTANT"
+>LOG_WARNING</TT
+>, debug level
+ two maps onto <TT
+CLASS="CONSTANT"
+>LOG_NOTICE</TT
+>, debug level three
+ maps onto LOG_INFO. All higher levels are mapped to <TT
+CLASS="CONSTANT"
+> LOG_DEBUG</TT
+>.</P
+><P
+>This parameter sets the threshold for sending messages
+ to syslog. Only messages with debug level less than this value
+ will be sent to syslog.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>syslog = 1</B
+></P
+></DD
+><DT
+><A
+NAME="SYSLOGONLY"
+></A
+>syslog only (G)</DT
+><DD
+><P
+>If this parameter is set then Samba debug
+ messages are logged into the system syslog only, and not to
+ the debug log files.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>syslog only = no</B
+></P
+></DD
+><DT
+><A
+NAME="TEMPLATEHOMEDIR"
+></A
+>template homedir (G)</DT
+><DD
+><P
+>When filling out the user information for a Windows NT
+ user, the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> daemon
+ uses this parameter to fill in the home directory for that user.
+ If the string <TT
+CLASS="PARAMETER"
+><I
+>%D</I
+></TT
+> is present it is substituted
+ with the user's Windows NT domain name. If the string <TT
+CLASS="PARAMETER"
+><I
+>%U
+ </I
+></TT
+> is present it is substituted with the user's Windows
+ NT user name.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>template homedir = /home/%D/%U</B
+></P
+></DD
+><DT
+><A
+NAME="TEMPLATESHELL"
+></A
+>template shell (G)</DT
+><DD
+><P
+>When filling out the user information for a Windows NT
+ user, the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> daemon
+ uses this parameter to fill in the login shell for that user.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>template shell = /bin/false</B
+></P
+></DD
+><DT
+><A
+NAME="TIMEOFFSET"
+></A
+>time offset (G)</DT
+><DD
+><P
+>This parameter is a setting in minutes to add
+ to the normal GMT to local time conversion. This is useful if
+ you are serving a lot of PCs that have incorrect daylight
+ saving time handling.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>time offset = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>time offset = 60</B
+></P
+></DD
+><DT
+><A
+NAME="TIMESERVER"
+></A
+>time server (G)</DT
+><DD
+><P
+>This parameter determines if <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>
+ nmbd(8)</A
+> advertises itself as a time server to Windows
+ clients.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>time server = no</B
+></P
+></DD
+><DT
+><A
+NAME="TIMESTAMPLOGS"
+></A
+>timestamp logs (G)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#DEBUGTIMESTAMP"
+><TT
+CLASS="PARAMETER"
+><I
+> debug timestamp</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="TOTALPRINTJOBS"
+></A
+>total print jobs (G)</DT
+><DD
+><P
+>This parameter accepts an integer value which defines
+ a limit on the maximum number of print jobs that will be accepted
+ system wide at any given time. If a print job is submitted
+ by a client which will exceed this number, then <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd</A
+> will return an
+ error indicating that no space is available on the server. The
+ default value of 0 means that no such limit exists. This parameter
+ can be used to prevent a server from exceeding its capacity and is
+ designed as a printing throttle. See also
+ <A
+HREF="#MAXPRINTJOBS"
+><TT
+CLASS="PARAMETER"
+><I
+>max print jobs</I
+></TT
+></A
+>.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>total print jobs = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>total print jobs = 5000</B
+></P
+></DD
+><DT
+><A
+NAME="UNIXEXTENSIONS"
+></A
+>unix extensions(G)</DT
+><DD
+><P
+>This boolean parameter controls whether Samba
+ implments the CIFS UNIX extensions, as defined by HP.
+ These extensions enable Samba to better serve UNIX CIFS clients
+ by supporting features such as symbolic links, hard links, etc...
+ These extensions require a similarly enabled client, and are of
+ no current use to Windows clients.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>unix extensions = no</B
+></P
+></DD
+><DT
+><A
+NAME="UNIXPASSWORDSYNC"
+></A
+>unix password sync (G)</DT
+><DD
+><P
+>This boolean parameter controls whether Samba
+ attempts to synchronize the UNIX password with the SMB password
+ when the encrypted SMB password in the smbpasswd file is changed.
+ If this is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+> the program specified in the <TT
+CLASS="PARAMETER"
+><I
+>passwd
+ program</I
+></TT
+>parameter is called <EM
+>AS ROOT</EM
+> -
+ to allow the new UNIX password to be set without access to the
+ old UNIX password (as the SMB password change code has no
+ access to the old password cleartext, only the new).</P
+><P
+>See also <A
+HREF="#PASSWDPROGRAM"
+><TT
+CLASS="PARAMETER"
+><I
+>passwd
+ program</I
+></TT
+></A
+>, <A
+HREF="#PASSWDCHAT"
+><TT
+CLASS="PARAMETER"
+><I
+> passwd chat</I
+></TT
+></A
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>unix password sync = no</B
+></P
+></DD
+><DT
+><A
+NAME="UPDATEENCRYPTED"
+></A
+>update encrypted (G)</DT
+><DD
+><P
+>This boolean parameter allows a user logging
+ on with a plaintext password to have their encrypted (hashed)
+ password in the smbpasswd file to be updated automatically as
+ they log on. This option allows a site to migrate from plaintext
+ password authentication (users authenticate with plaintext
+ password over the wire, and are checked against a UNIX account
+ database) to encrypted password authentication (the SMB
+ challenge/response authentication mechanism) without forcing
+ all users to re-enter their passwords via smbpasswd at the time the
+ change is made. This is a convenience option to allow the change over
+ to encrypted passwords to be made over a longer period. Once all users
+ have encrypted representations of their passwords in the smbpasswd
+ file this parameter should be set to <TT
+CLASS="CONSTANT"
+>no</TT
+>.</P
+><P
+>In order for this parameter to work correctly the <A
+HREF="#ENCRYPTPASSWORDS"
+><TT
+CLASS="PARAMETER"
+><I
+>encrypt passwords</I
+></TT
+>
+ </A
+> parameter must be set to <TT
+CLASS="CONSTANT"
+>no</TT
+> when
+ this parameter is set to <TT
+CLASS="CONSTANT"
+>yes</TT
+>.</P
+><P
+>Note that even when this parameter is set a user
+ authenticating to <B
+CLASS="COMMAND"
+>smbd</B
+> must still enter a valid
+ password in order to connect correctly, and to update their hashed
+ (smbpasswd) passwords.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>update encrypted = no</B
+></P
+></DD
+><DT
+><A
+NAME="USECLIENTDRIVER"
+></A
+>use client driver (S)</DT
+><DD
+><P
+>This parameter applies only to Windows NT/2000
+ clients. It has no affect on Windows 95/98/ME clients. When
+ serving a printer to Windows NT/2000 clients without first installing
+ a valid printer driver on the Samba host, the client will be required
+ to install a local printer driver. From this point on, the client
+ will treat the print as a local printer and not a network printer
+ connection. This is much the same behavior that will occur
+ when <B
+CLASS="COMMAND"
+>disable spoolss = yes</B
+>. </P
+><P
+>The differentiating
+ factor is that under normal circumstances, the NT/2000 client will
+ attempt to open the network printer using MS-RPC. The problem is that
+ because the client considers the printer to be local, it will attempt
+ to issue the OpenPrinterEx() call requesting access rights associated
+ with the logged on user. If the user possesses local administator rights
+ but not root privilegde on the Samba host (often the case), the OpenPrinterEx()
+ call will fail. The result is that the client will now display an "Access
+ Denied; Unable to connect" message in the printer queue window (even though
+ jobs may successfully be printed). </P
+><P
+>If this parameter is enabled for a printer, then any attempt
+ to open the printer with the PRINTER_ACCESS_ADMINISTER right is mapped
+ to PRINTER_ACCESS_USE instead. Thus allowing the OpenPrinterEx()
+ call to succeed. <EM
+>This parameter MUST not be able enabled
+ on a print share which has valid print driver installed on the Samba
+ server.</EM
+></P
+><P
+>See also <A
+HREF="#DISABLESPOOLSS"
+>disable spoolss</A
+>
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>use client driver = no</B
+></P
+></DD
+><DT
+><A
+NAME="USEMMAP"
+></A
+>use mmap (G)</DT
+><DD
+><P
+>This global parameter determines if the tdb internals of Samba can
+ depend on mmap working correctly on the running system. Samba requires a coherent
+ mmap/read-write system memory cache. Currently only HPUX does not have such a
+ coherent cache, and so this parameter is set to <TT
+CLASS="CONSTANT"
+>no</TT
+> by
+ default on HPUX. On all other systems this parameter should be left alone. This
+ parameter is provided to help the Samba developers track down problems with
+ the tdb internal code.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>use mmap = yes</B
+></P
+></DD
+><DT
+><A
+NAME="USERHOSTS"
+></A
+>use rhosts (G)</DT
+><DD
+><P
+>If this global parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, it specifies
+ that the UNIX user's <TT
+CLASS="FILENAME"
+>.rhosts</TT
+> file in their home directory
+ will be read to find the names of hosts and users who will be allowed
+ access without specifying a password.</P
+><P
+><EM
+>NOTE:</EM
+> The use of <TT
+CLASS="PARAMETER"
+><I
+>use rhosts
+ </I
+></TT
+> can be a major security hole. This is because you are
+ trusting the PC to supply the correct username. It is very easy to
+ get a PC to supply a false username. I recommend that the <TT
+CLASS="PARAMETER"
+><I
+> use rhosts</I
+></TT
+> option be only used if you really know what
+ you are doing.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>use rhosts = no</B
+></P
+></DD
+><DT
+><A
+NAME="USER"
+></A
+>user (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#USERNAME"
+><TT
+CLASS="PARAMETER"
+><I
+> username</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="USERS"
+></A
+>users (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#USERNAME"
+><TT
+CLASS="PARAMETER"
+><I
+> username</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="USERNAME"
+></A
+>username (S)</DT
+><DD
+><P
+>Multiple users may be specified in a comma-delimited
+ list, in which case the supplied password will be tested against
+ each username in turn (left to right).</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>username</I
+></TT
+> line is needed only when
+ the PC is unable to supply its own username. This is the case
+ for the COREPLUS protocol or where your users have different WfWg
+ usernames to UNIX usernames. In both these cases you may also be
+ better using the \\server\share%user syntax instead.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>username</I
+></TT
+> line is not a great
+ solution in many cases as it means Samba will try to validate
+ the supplied password against each of the usernames in the
+ <TT
+CLASS="PARAMETER"
+><I
+>username</I
+></TT
+> line in turn. This is slow and
+ a bad idea for lots of users in case of duplicate passwords.
+ You may get timeouts or security breaches using this parameter
+ unwisely.</P
+><P
+>Samba relies on the underlying UNIX security. This
+ parameter does not restrict who can login, it just offers hints
+ to the Samba server as to what usernames might correspond to the
+ supplied password. Users can login as whoever they please and
+ they will be able to do no more damage than if they started a
+ telnet session. The daemon runs as the user that they log in as,
+ so they cannot do anything that user cannot do.</P
+><P
+>To restrict a service to a particular set of users you
+ can use the <A
+HREF="#VALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>valid users
+ </I
+></TT
+></A
+> parameter.</P
+><P
+>If any of the usernames begin with a '@' then the name
+ will be looked up first in the NIS netgroups list (if Samba
+ is compiled with netgroup support), followed by a lookup in
+ the UNIX groups database and will expand to a list of all users
+ in the group of that name.</P
+><P
+>If any of the usernames begin with a '+' then the name
+ will be looked up only in the UNIX groups database and will
+ expand to a list of all users in the group of that name.</P
+><P
+>If any of the usernames begin with a '&#38;'then the name
+ will be looked up only in the NIS netgroups database (if Samba
+ is compiled with netgroup support) and will expand to a list
+ of all users in the netgroup group of that name.</P
+><P
+>Note that searching though a groups database can take
+ quite some time, and some clients may time out during the
+ search.</P
+><P
+>See the section <A
+HREF="#AEN241"
+>NOTE ABOUT
+ USERNAME/PASSWORD VALIDATION</A
+> for more information on how
+ this parameter determines access to the services.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>The guest account if a guest service,
+ else &#60;empty string&#62;.</B
+></P
+><P
+>Examples:<B
+CLASS="COMMAND"
+>username = fred, mary, jack, jane,
+ @users, @pcgroup</B
+></P
+></DD
+><DT
+><A
+NAME="USERNAMELEVEL"
+></A
+>username level (G)</DT
+><DD
+><P
+>This option helps Samba to try and 'guess' at
+ the real UNIX username, as many DOS clients send an all-uppercase
+ username. By default Samba tries all lowercase, followed by the
+ username with the first letter capitalized, and fails if the
+ username is not found on the UNIX machine.</P
+><P
+>If this parameter is set to non-zero the behavior changes.
+ This parameter is a number that specifies the number of uppercase
+ combinations to try while trying to determine the UNIX user name. The
+ higher the number the more combinations will be tried, but the slower
+ the discovery of usernames will be. Use this parameter when you have
+ strange usernames on your UNIX machine, such as <TT
+CLASS="CONSTANT"
+>AstrangeUser
+ </TT
+>.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>username level = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>username level = 5</B
+></P
+></DD
+><DT
+><A
+NAME="USERNAMEMAP"
+></A
+>username map (G)</DT
+><DD
+><P
+>This option allows you to specify a file containing
+ a mapping of usernames from the clients to the server. This can be
+ used for several purposes. The most common is to map usernames
+ that users use on DOS or Windows machines to those that the UNIX
+ box uses. The other is to map multiple users to a single username
+ so that they can more easily share files.</P
+><P
+>The map file is parsed line by line. Each line should
+ contain a single UNIX username on the left then a '=' followed
+ by a list of usernames on the right. The list of usernames on the
+ right may contain names of the form @group in which case they
+ will match any UNIX username in that group. The special client
+ name '*' is a wildcard and matches any name. Each line of the
+ map file may be up to 1023 characters long.</P
+><P
+>The file is processed on each line by taking the
+ supplied username and comparing it with each username on the right
+ hand side of the '=' signs. If the supplied name matches any of
+ the names on the right hand side then it is replaced with the name
+ on the left. Processing then continues with the next line.</P
+><P
+>If any line begins with a '#' or a ';' then it is
+ ignored</P
+><P
+>If any line begins with an '!' then the processing
+ will stop after that line if a mapping was done by the line.
+ Otherwise mapping continues with every line being processed.
+ Using '!' is most useful when you have a wildcard mapping line
+ later in the file.</P
+><P
+>For example to map from the name <TT
+CLASS="CONSTANT"
+>admin</TT
+>
+ or <TT
+CLASS="CONSTANT"
+>administrator</TT
+> to the UNIX name <TT
+CLASS="CONSTANT"
+> root</TT
+> you would use:</P
+><P
+><B
+CLASS="COMMAND"
+>root = admin administrator</B
+></P
+><P
+>Or to map anyone in the UNIX group <TT
+CLASS="CONSTANT"
+>system</TT
+>
+ to the UNIX name <TT
+CLASS="CONSTANT"
+>sys</TT
+> you would use:</P
+><P
+><B
+CLASS="COMMAND"
+>sys = @system</B
+></P
+><P
+>You can have as many mappings as you like in a username
+ map file.</P
+><P
+>If your system supports the NIS NETGROUP option then
+ the netgroup database is checked before the <TT
+CLASS="FILENAME"
+>/etc/group
+ </TT
+> database for matching groups.</P
+><P
+>You can map Windows usernames that have spaces in them
+ by using double quotes around the name. For example:</P
+><P
+><B
+CLASS="COMMAND"
+>tridge = "Andrew Tridgell"</B
+></P
+><P
+>would map the windows username "Andrew Tridgell" to the
+ unix username "tridge".</P
+><P
+>The following example would map mary and fred to the
+ unix user sys, and map the rest to guest. Note the use of the
+ '!' to tell Samba to stop processing if it gets a match on
+ that line.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> !sys = mary fred
+ guest = *
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Note that the remapping is applied to all occurrences
+ of usernames. Thus if you connect to \\server\fred and <TT
+CLASS="CONSTANT"
+> fred</TT
+> is remapped to <TT
+CLASS="CONSTANT"
+>mary</TT
+> then you
+ will actually be connecting to \\server\mary and will need to
+ supply a password suitable for <TT
+CLASS="CONSTANT"
+>mary</TT
+> not
+ <TT
+CLASS="CONSTANT"
+>fred</TT
+>. The only exception to this is the
+ username passed to the <A
+HREF="#PASSWORDSERVER"
+><TT
+CLASS="PARAMETER"
+><I
+> password server</I
+></TT
+></A
+> (if you have one). The password
+ server will receive whatever username the client supplies without
+ modification.</P
+><P
+>Also note that no reverse mapping is done. The main effect
+ this has is with printing. Users who have been mapped may have
+ trouble deleting print jobs as PrintManager under WfWg will think
+ they don't own the print job.</P
+><P
+>Default: <EM
+>no username map</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>username map = /usr/local/samba/lib/users.map
+ </B
+></P
+></DD
+><DT
+><A
+NAME="USESENDFILE"
+></A
+>use sendfile (S)</DT
+><DD
+><P
+>If this parameter is <TT
+CLASS="CONSTANT"
+>yes</TT
+>, and Samba
+ was built with the --with-sendfile-support option, and the underlying operating
+ system supports sendfile system call, then some SMB read calls (mainly ReadAndX
+ and ReadRaw) will use the more efficient sendfile system call for files that
+ are exclusively oplocked. This may make more efficient use of the system CPU's
+ and cause Samba to be faster. This is off by default as it's effects are unknown
+ as yet.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>use sendfile = no</B
+></P
+></DD
+><DT
+><A
+NAME="UTMP"
+></A
+>utmp (G)</DT
+><DD
+><P
+>This boolean parameter is only available if
+ Samba has been configured and compiled with the option <B
+CLASS="COMMAND"
+> --with-utmp</B
+>. If set to <TT
+CLASS="CONSTANT"
+>yes</TT
+> then Samba will attempt
+ to add utmp or utmpx records (depending on the UNIX system) whenever a
+ connection is made to a Samba server. Sites may use this to record the
+ user connecting to a Samba share.</P
+><P
+>See also the <A
+HREF="#UTMPDIRECTORY"
+><TT
+CLASS="PARAMETER"
+><I
+> utmp directory</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>utmp = no</B
+></P
+></DD
+><DT
+><A
+NAME="UTMPDIRECTORY"
+></A
+>utmp directory(G)</DT
+><DD
+><P
+>This parameter is only available if Samba has
+ been configured and compiled with the option <B
+CLASS="COMMAND"
+> --with-utmp</B
+>. It specifies a directory pathname that is
+ used to store the utmp or utmpx files (depending on the UNIX system) that
+ record user connections to a Samba server. See also the <A
+HREF="#UTMP"
+> <TT
+CLASS="PARAMETER"
+><I
+>utmp</I
+></TT
+></A
+> parameter. By default this is
+ not set, meaning the system will use whatever utmp file the
+ native system is set to use (usually
+ <TT
+CLASS="FILENAME"
+>/var/run/utmp</TT
+> on Linux).</P
+><P
+>Default: <EM
+>no utmp directory</EM
+></P
+></DD
+><DT
+><A
+NAME="VALIDCHARS"
+></A
+>valid chars (G)</DT
+><DD
+><P
+>The option allows you to specify additional
+ characters that should be considered valid by the server in
+ filenames. This is particularly useful for national character
+ sets, such as adding u-umlaut or a-ring.</P
+><P
+>The option takes a list of characters in either integer
+ or character form with spaces between them. If you give two
+ characters with a colon between them then it will be taken as
+ an lowercase:uppercase pair.</P
+><P
+>If you have an editor capable of entering the characters
+ into the config file then it is probably easiest to use this
+ method. Otherwise you can specify the characters in octal,
+ decimal or hexadecimal form using the usual C notation.</P
+><P
+>For example to add the single character 'Z' to the charset
+ (which is a pointless thing to do as it's already there) you could
+ do one of the following</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> valid chars = Z
+ valid chars = z:Z
+ valid chars = 0132:0172
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The last two examples above actually add two characters,
+ and alter the uppercase and lowercase mappings appropriately.</P
+><P
+>Note that you <EM
+>MUST</EM
+> specify this parameter
+ after the <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> parameter if you
+ have both set. If <TT
+CLASS="PARAMETER"
+><I
+>client code page</I
+></TT
+> is set after
+ the <TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+> parameter the <TT
+CLASS="PARAMETER"
+><I
+>valid
+ chars</I
+></TT
+> settings will be overwritten.</P
+><P
+>See also the <A
+HREF="#CLIENTCODEPAGE"
+><TT
+CLASS="PARAMETER"
+><I
+>client
+ code page</I
+></TT
+></A
+> parameter.</P
+><P
+>Default: <EM
+>Samba defaults to using a reasonable set
+ of valid characters for English systems</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>valid chars = 0345:0305 0366:0326 0344:0304
+ </B
+></P
+><P
+>The above example allows filenames to have the Swedish
+ characters in them.</P
+><P
+><EM
+>NOTE:</EM
+> It is actually quite difficult to
+ correctly produce a <TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+> line for
+ a particular system. To automate the process <A
+HREF="mailto:tino@augsburg.net"
+TARGET="_top"
+>tino@augsburg.net</A
+> has written
+ a package called <B
+CLASS="COMMAND"
+>validchars</B
+> which will automatically
+ produce a complete <TT
+CLASS="PARAMETER"
+><I
+>valid chars</I
+></TT
+> line for
+ a given client system. Look in the <TT
+CLASS="FILENAME"
+>examples/validchars/
+ </TT
+> subdirectory of your Samba source code distribution
+ for this package.</P
+></DD
+><DT
+><A
+NAME="VALIDUSERS"
+></A
+>valid users (S)</DT
+><DD
+><P
+>This is a list of users that should be allowed
+ to login to this service. Names starting with '@', '+' and '&#38;'
+ are interpreted using the same rules as described in the
+ <TT
+CLASS="PARAMETER"
+><I
+>invalid users</I
+></TT
+> parameter.</P
+><P
+>If this is empty (the default) then any user can login.
+ If a username is in both this list and the <TT
+CLASS="PARAMETER"
+><I
+>invalid
+ users</I
+></TT
+> list then access is denied for that user.</P
+><P
+>The current servicename is substituted for <TT
+CLASS="PARAMETER"
+><I
+>%S
+ </I
+></TT
+>. This is useful in the [homes] section.</P
+><P
+>See also <A
+HREF="#INVALIDUSERS"
+><TT
+CLASS="PARAMETER"
+><I
+>invalid users
+ </I
+></TT
+></A
+></P
+><P
+>Default: <EM
+>No valid users list (anyone can login)
+ </EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>valid users = greg, @pcusers</B
+></P
+></DD
+><DT
+><A
+NAME="VETOFILES"
+></A
+>veto files(S)</DT
+><DD
+><P
+>This is a list of files and directories that
+ are neither visible nor accessible. Each entry in the list must
+ be separated by a '/', which allows spaces to be included
+ in the entry. '*' and '?' can be used to specify multiple files
+ or directories as in DOS wildcards.</P
+><P
+>Each entry must be a unix path, not a DOS path and
+ must <EM
+>not</EM
+> include the unix directory
+ separator '/'.</P
+><P
+>Note that the <TT
+CLASS="PARAMETER"
+><I
+>case sensitive</I
+></TT
+> option
+ is applicable in vetoing files.</P
+><P
+>One feature of the veto files parameter that it
+ is important to be aware of is Samba's behaviour when
+ trying to delete a directory. If a directory that is
+ to be deleted contains nothing but veto files this
+ deletion will <EM
+>fail</EM
+> unless you also set
+ the <TT
+CLASS="PARAMETER"
+><I
+>delete veto files</I
+></TT
+> parameter to
+ <TT
+CLASS="PARAMETER"
+><I
+>yes</I
+></TT
+>.</P
+><P
+>Setting this parameter will affect the performance
+ of Samba, as it will be forced to check all files and directories
+ for a match as they are scanned.</P
+><P
+>See also <A
+HREF="#HIDEFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>hide files
+ </I
+></TT
+></A
+> and <A
+HREF="#CASESENSITIVE"
+><TT
+CLASS="PARAMETER"
+><I
+> case sensitive</I
+></TT
+></A
+>.</P
+><P
+>Default: <EM
+>No files or directories are vetoed.
+ </EM
+></P
+><P
+>Examples:<TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>; Veto any files containing the word Security,
+; any ending in .tmp, and any directory containing the
+; word root.
+veto files = /*Security*/*.tmp/*root*/
+
+; Veto the Apple specific files that a NetAtalk server
+; creates.
+veto files = /.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/</PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+><DT
+><A
+NAME="VETOOPLOCKFILES"
+></A
+>veto oplock files (S)</DT
+><DD
+><P
+>This parameter is only valid when the <A
+HREF="#OPLOCKS"
+><TT
+CLASS="PARAMETER"
+><I
+>oplocks</I
+></TT
+></A
+>
+ parameter is turned on for a share. It allows the Samba administrator
+ to selectively turn off the granting of oplocks on selected files that
+ match a wildcarded list, similar to the wildcarded list used in the
+ <A
+HREF="#VETOFILES"
+><TT
+CLASS="PARAMETER"
+><I
+>veto files</I
+></TT
+></A
+>
+ parameter.</P
+><P
+>Default: <EM
+>No files are vetoed for oplock
+ grants</EM
+></P
+><P
+>You might want to do this on files that you know will
+ be heavily contended for by clients. A good example of this
+ is in the NetBench SMB benchmark program, which causes heavy
+ client contention for files ending in <TT
+CLASS="FILENAME"
+>.SEM</TT
+>.
+ To cause Samba not to grant oplocks on these files you would use
+ the line (either in the [global] section or in the section for
+ the particular NetBench share :</P
+><P
+>Example: <B
+CLASS="COMMAND"
+>veto oplock files = /*.SEM/
+ </B
+></P
+></DD
+><DT
+><A
+NAME="VFSOBJECT"
+></A
+>vfs object (S)</DT
+><DD
+><P
+>This parameter specifies a shared object file that
+ is used for Samba VFS I/O operations. By default, normal
+ disk I/O operations are used but these can be overloaded
+ with a VFS object. The Samba VFS layer is new to Samba 2.2 and
+ must be enabled at compile time with --with-vfs.</P
+><P
+>Default : <EM
+>no value</EM
+></P
+></DD
+><DT
+><A
+NAME="VFSOPTIONS"
+></A
+>vfs options (S)</DT
+><DD
+><P
+>This parameter allows parameters to be passed
+ to the vfs layer at initialization time. The Samba VFS layer
+ is new to Samba 2.2 and must be enabled at compile time
+ with --with-vfs. See also <A
+HREF="#VFSOBJECT"
+><TT
+CLASS="PARAMETER"
+><I
+> vfs object</I
+></TT
+></A
+>.</P
+><P
+>Default : <EM
+>no value</EM
+></P
+></DD
+><DT
+><A
+NAME="VOLUME"
+></A
+>volume (S)</DT
+><DD
+><P
+> This allows you to override the volume label
+ returned for a share. Useful for CDROMs with installation programs
+ that insist on a particular volume label.</P
+><P
+>Default: <EM
+>the name of the share</EM
+></P
+></DD
+><DT
+><A
+NAME="WIDELINKS"
+></A
+>wide links (S)</DT
+><DD
+><P
+>This parameter controls whether or not links
+ in the UNIX file system may be followed by the server. Links
+ that point to areas within the directory tree exported by the
+ server are always allowed; this parameter controls access only
+ to areas that are outside the directory tree being exported.</P
+><P
+>Note that setting this parameter can have a negative
+ effect on your server performance due to the extra system calls
+ that Samba has to do in order to perform the link checks.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>wide links = yes</B
+></P
+></DD
+><DT
+><A
+NAME="WINBINDCACHETIME"
+></A
+>winbind cache time (G)</DT
+><DD
+><P
+>This parameter specifies the number of seconds the
+ <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> daemon will cache
+ user and group information before querying a Windows NT server
+ again.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind cache type = 15</B
+></P
+></DD
+><DT
+><A
+NAME="WINBINDENUMUSERS"
+></A
+>winbind enum users (G)</DT
+><DD
+><P
+>On large installations using
+ <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> it may be
+ necessary to suppress the enumeration of users through the
+ <B
+CLASS="COMMAND"
+> setpwent()</B
+>,
+ <B
+CLASS="COMMAND"
+>getpwent()</B
+> and
+ <B
+CLASS="COMMAND"
+>endpwent()</B
+> group of system calls. If
+ the <TT
+CLASS="PARAMETER"
+><I
+>winbind enum users</I
+></TT
+> parameter is
+ <TT
+CLASS="CONSTANT"
+>no</TT
+>, calls to the <B
+CLASS="COMMAND"
+>getpwent</B
+> system call
+ will not return any data. </P
+><P
+><EM
+>Warning:</EM
+> Turning off user
+ enumeration may cause some programs to behave oddly. For
+ example, the finger program relies on having access to the
+ full user list when searching for matching
+ usernames. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind enum users = yes </B
+></P
+></DD
+><DT
+><A
+NAME="WINBINDENUMGROUPS"
+></A
+>winbind enum groups (G)</DT
+><DD
+><P
+>On large installations using
+ <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> it may be
+ necessary to suppress the enumeration of groups through the
+ <B
+CLASS="COMMAND"
+> setgrent()</B
+>,
+ <B
+CLASS="COMMAND"
+>getgrent()</B
+> and
+ <B
+CLASS="COMMAND"
+>endgrent()</B
+> group of system calls. If
+ the <TT
+CLASS="PARAMETER"
+><I
+>winbind enum groups</I
+></TT
+> parameter is
+ <TT
+CLASS="CONSTANT"
+>no</TT
+>, calls to the <B
+CLASS="COMMAND"
+>getgrent()</B
+> system
+ call will not return any data. </P
+><P
+><EM
+>Warning:</EM
+> Turning off group
+ enumeration may cause some programs to behave oddly.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind enum groups = yes </B
+>
+ </P
+></DD
+><DT
+><A
+NAME="WINBINDGID"
+></A
+>winbind gid (G)</DT
+><DD
+><P
+>The winbind gid parameter specifies the range of group
+ ids that are allocated by the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+> winbindd(8)</A
+> daemon. This range of group ids should have no
+ existing local or NIS groups within it as strange conflicts can
+ occur otherwise.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind gid = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind gid = 10000-20000</B
+></P
+></DD
+><DT
+><A
+NAME="WINBINDSEPARATOR"
+></A
+>winbind separator (G)</DT
+><DD
+><P
+>This parameter allows an admin to define the character
+ used when listing a username of the form of <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN
+ </I
+></TT
+>\<TT
+CLASS="REPLACEABLE"
+><I
+>user</I
+></TT
+>. This parameter
+ is only applicable when using the <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+>
+ and <TT
+CLASS="FILENAME"
+>nss_winbind.so</TT
+> modules for UNIX services.
+ </P
+><P
+>Please note that setting this parameter to + causes problems
+ with group membership at least on glibc systems, as the character +
+ is used as a special character for NIS in /etc/group.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind separator = '\'</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind separator = +</B
+></P
+></DD
+><DT
+><A
+NAME="WINBINDUID"
+></A
+>winbind uid (G)</DT
+><DD
+><P
+>The winbind gid parameter specifies the range of group
+ ids that are allocated by the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+> winbindd(8)</A
+> daemon. This range of ids should have no
+ existing local or NIS users within it as strange conflicts can
+ occur otherwise.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind uid = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind uid = 10000-20000</B
+></P
+></DD
+><DT
+>winbind use default domain, <A
+NAME="WINBINDUSEDEFAULTDOMAIN"
+></A
+>winbind use default domain</DT
+><DD
+><P
+>This parameter specifies whether the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+> winbindd(8)</A
+>
+ daemon should operate on users without domain component in their username.
+ Users without a domain component are treated as is part of the winbindd server's
+ own domain. While this does not benifit Windows users, it makes SSH, FTP and e-mail
+ function in a way much closer to the way they would in a native unix system.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind use default domain = &#60;no&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind use default domain = yes</B
+></P
+></DD
+><DT
+><A
+NAME="WINSHOOK"
+></A
+>wins hook (G)</DT
+><DD
+><P
+>When Samba is running as a WINS server this
+ allows you to call an external program for all changes to the
+ WINS database. The primary use for this option is to allow the
+ dynamic update of external name resolution databases such as
+ dynamic DNS.</P
+><P
+>The wins hook parameter specifies the name of a script
+ or executable that will be called as follows:</P
+><P
+><B
+CLASS="COMMAND"
+>wins_hook operation name nametype ttl IP_list
+ </B
+></P
+><P
+></P
+><UL
+><LI
+><P
+>The first argument is the operation and is one
+ of "add", "delete", or "refresh". In most cases the operation can
+ be ignored as the rest of the parameters provide sufficient
+ information. Note that "refresh" may sometimes be called when the
+ name has not previously been added, in that case it should be treated
+ as an add.</P
+></LI
+><LI
+><P
+>The second argument is the NetBIOS name. If the
+ name is not a legal name then the wins hook is not called.
+ Legal names contain only letters, digits, hyphens, underscores
+ and periods.</P
+></LI
+><LI
+><P
+>The third argument is the NetBIOS name
+ type as a 2 digit hexadecimal number. </P
+></LI
+><LI
+><P
+>The fourth argument is the TTL (time to live)
+ for the name in seconds.</P
+></LI
+><LI
+><P
+>The fifth and subsequent arguments are the IP
+ addresses currently registered for that name. If this list is
+ empty then the name should be deleted.</P
+></LI
+></UL
+><P
+>An example script that calls the BIND dynamic DNS update
+ program <B
+CLASS="COMMAND"
+>nsupdate</B
+> is provided in the examples
+ directory of the Samba source code. </P
+></DD
+><DT
+><A
+NAME="WINSPROXY"
+></A
+>wins proxy (G)</DT
+><DD
+><P
+>This is a boolean that controls if <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+> will respond to broadcast name
+ queries on behalf of other hosts. You may need to set this
+ to <TT
+CLASS="CONSTANT"
+>yes</TT
+> for some older clients.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>wins proxy = no</B
+></P
+></DD
+><DT
+><A
+NAME="WINSSERVER"
+></A
+>wins server (G)</DT
+><DD
+><P
+>This specifies the IP address (or DNS name: IP
+ address for preference) of the WINS server that <A
+HREF="nmbd.8.html"
+TARGET="_top"
+> nmbd(8)</A
+> should register with. If you have a WINS server on
+ your network then you should set this to the WINS server's IP.</P
+><P
+>You should point this at your WINS server if you have a
+ multi-subnetted network.</P
+><P
+><EM
+>NOTE</EM
+>. You need to set up Samba to point
+ to a WINS server if you have multiple subnets and wish cross-subnet
+ browsing to work correctly.</P
+><P
+>See the documentation file <TT
+CLASS="FILENAME"
+>BROWSING.txt</TT
+>
+ in the docs/ directory of your Samba source distribution.</P
+><P
+>Default: <EM
+>not enabled</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>wins server = 192.9.200.1</B
+></P
+></DD
+><DT
+><A
+NAME="WINSSUPPORT"
+></A
+>wins support (G)</DT
+><DD
+><P
+>This boolean controls if the <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>
+ nmbd(8)</A
+> process in Samba will act as a WINS server. You should
+ not set this to <TT
+CLASS="CONSTANT"
+>yes</TT
+> unless you have a multi-subnetted network and
+ you wish a particular <B
+CLASS="COMMAND"
+>nmbd</B
+> to be your WINS server.
+ Note that you should <EM
+>NEVER</EM
+> set this to <TT
+CLASS="CONSTANT"
+>yes</TT
+>
+ on more than one machine in your network.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>wins support = no</B
+></P
+></DD
+><DT
+><A
+NAME="WORKGROUP"
+></A
+>workgroup (G)</DT
+><DD
+><P
+>This controls what workgroup your server will
+ appear to be in when queried by clients. Note that this parameter
+ also controls the Domain name used with the <A
+HREF="#SECURITYEQUALSDOMAIN"
+><B
+CLASS="COMMAND"
+>security = domain</B
+></A
+>
+ setting.</P
+><P
+>Default: <EM
+>set at compile time to WORKGROUP</EM
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>workgroup = MYGROUP</B
+></P
+></DD
+><DT
+><A
+NAME="WRITABLE"
+></A
+>writable (S)</DT
+><DD
+><P
+>Synonym for <A
+HREF="#WRITEABLE"
+><TT
+CLASS="PARAMETER"
+><I
+> writeable</I
+></TT
+></A
+> for people who can't spell :-).</P
+></DD
+><DT
+><A
+NAME="WRITECACHESIZE"
+></A
+>write cache size (S)</DT
+><DD
+><P
+>If this integer parameter is set to non-zero value,
+ Samba will create an in-memory cache for each oplocked file
+ (it does <EM
+>not</EM
+> do this for
+ non-oplocked files). All writes that the client does not request
+ to be flushed directly to disk will be stored in this cache if possible.
+ The cache is flushed onto disk when a write comes in whose offset
+ would not fit into the cache or when the file is closed by the client.
+ Reads for the file are also served from this cache if the data is stored
+ within it.</P
+><P
+>This cache allows Samba to batch client writes into a more
+ efficient write size for RAID disks (i.e. writes may be tuned to
+ be the RAID stripe size) and can improve performance on systems
+ where the disk subsystem is a bottleneck but there is free
+ memory for userspace programs.</P
+><P
+>The integer parameter specifies the size of this cache
+ (per oplocked file) in bytes.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>write cache size = 0</B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>write cache size = 262144</B
+></P
+><P
+>for a 256k cache size per file.</P
+></DD
+><DT
+><A
+NAME="WRITELIST"
+></A
+>write list (S)</DT
+><DD
+><P
+>This is a list of users that are given read-write
+ access to a service. If the connecting user is in this list then
+ they will be given write access, no matter what the <A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+>read only</I
+></TT
+></A
+>
+ option is set to. The list can include group names using the
+ @group syntax.</P
+><P
+>Note that if a user is in both the read list and the
+ write list then they will be given write access.</P
+><P
+>See also the <A
+HREF="#READLIST"
+><TT
+CLASS="PARAMETER"
+><I
+>read list
+ </I
+></TT
+></A
+> option.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>write list = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>write list = admin, root, @staff
+ </B
+></P
+></DD
+><DT
+><A
+NAME="WRITEOK"
+></A
+>write ok (S)</DT
+><DD
+><P
+>Inverted synonym for <A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+> read only</I
+></TT
+></A
+>.</P
+></DD
+><DT
+><A
+NAME="WRITERAW"
+></A
+>write raw (G)</DT
+><DD
+><P
+>This parameter controls whether or not the server
+ will support raw write SMB's when transferring data from clients.
+ You should never need to change this parameter.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>write raw = yes</B
+></P
+></DD
+><DT
+><A
+NAME="WRITEABLE"
+></A
+>writeable (S)</DT
+><DD
+><P
+>Inverted synonym for <A
+HREF="#READONLY"
+><TT
+CLASS="PARAMETER"
+><I
+> read only</I
+></TT
+></A
+>.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN6251"
+></A
+><H2
+>WARNINGS</H2
+><P
+>Although the configuration file permits service names
+ to contain spaces, your client software may not. Spaces will
+ be ignored in comparisons anyway, so it shouldn't be a
+ problem - but be aware of the possibility.</P
+><P
+>On a similar note, many clients - especially DOS clients -
+ limit service names to eight characters. <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)
+ </A
+> has no such limitation, but attempts to connect from such
+ clients will fail if they truncate the service names. For this reason
+ you should probably keep your service names down to eight characters
+ in length.</P
+><P
+>Use of the [homes] and [printers] special sections make life
+ for an administrator easy, but the various combinations of default
+ attributes can be tricky. Take extreme care when designing these
+ sections. In particular, ensure that the permissions on spool
+ directories are correct.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN6257"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN6260"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>,
+ <A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+>,
+ <A
+HREF="swat.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>swat(8)</B
+></A
+>,
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+>,
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+>,
+ <A
+HREF="nmblookup.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmblookup(1)</B
+></A
+>,
+ <A
+HREF="testparm.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>testparm(1)</B
+></A
+>,
+ <A
+HREF="testprns.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>testprns(1)</B
+></A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN6280"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbcacls.1.html b/docs/htmldocs/smbcacls.1.html
new file mode 100755
index 00000000000..637720fa6ba
--- /dev/null
+++ b/docs/htmldocs/smbcacls.1.html
@@ -0,0 +1,387 @@
+<HTML
+><HEAD
+><TITLE
+>smbcacls</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBCACLS"
+>smbcacls</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbcacls&nbsp;--&nbsp;Set or get ACLs on an NT file or directory names</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbcacls</B
+> {//server/share} {filename} [-U username] [-A acls] [-M acls] [-D acls] [-S acls] [-C name] [-G name] [-n] [-h]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN22"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>The <B
+CLASS="COMMAND"
+>smbcacls</B
+> program manipulates NT Access Control Lists
+ (ACLs) on SMB file shares. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN28"
+></A
+><H2
+>OPTIONS</H2
+><P
+>The following options are available to the <B
+CLASS="COMMAND"
+>smbcacls</B
+> program.
+ The format of ACLs is described in the section ACL FORMAT </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-A acls</DT
+><DD
+><P
+>Add the ACLs specified to the ACL list. Existing
+ access control entries are unchanged. </P
+></DD
+><DT
+>-M acls</DT
+><DD
+><P
+>Modify the mask value (permissions) for the ACLs
+ specified on the command line. An error will be printed for each
+ ACL specified that was not already present in the ACL list
+ </P
+></DD
+><DT
+>-D acls</DT
+><DD
+><P
+>Delete any ACLs specified on the command line.
+ An error will be printed for each ACL specified that was not
+ already present in the ACL list. </P
+></DD
+><DT
+>-S acls</DT
+><DD
+><P
+>This command sets the ACLs on the file with
+ only the ones specified on the command line. All other ACLs are
+ erased. Note that the ACL specified must contain at least a revision,
+ type, owner and group for the call to succeed. </P
+></DD
+><DT
+>-U username</DT
+><DD
+><P
+>Specifies a username used to connect to the
+ specified service. The username may be of the form "username" in
+ which case the user is prompted to enter in a password and the
+ workgroup specified in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file is
+ used, or "username%password" or "DOMAIN\username%password" and the
+ password and workgroup names are used as provided. </P
+></DD
+><DT
+>-C name</DT
+><DD
+><P
+>The owner of a file or directory can be changed
+ to the name given using the <TT
+CLASS="PARAMETER"
+><I
+>-C</I
+></TT
+> option.
+ The name can be a sid in the form S-1-x-y-z or a name resolved
+ against the server specified in the first argument. </P
+><P
+>This command is a shortcut for -M OWNER:name.
+ </P
+></DD
+><DT
+>-G name</DT
+><DD
+><P
+>The group owner of a file or directory can
+ be changed to the name given using the <TT
+CLASS="PARAMETER"
+><I
+>-G</I
+></TT
+>
+ option. The name can be a sid in the form S-1-x-y-z or a name
+ resolved against the server specified n the first argument.
+ </P
+><P
+>This command is a shortcut for -M GROUP:name.</P
+></DD
+><DT
+>-n</DT
+><DD
+><P
+>This option displays all ACL information in numeric
+ format. The default is to convert SIDs to names and ACE types
+ and masks to a readable string format. </P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Print usage information on the <B
+CLASS="COMMAND"
+>smbcacls
+ </B
+> program.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN75"
+></A
+><H2
+>ACL FORMAT</H2
+><P
+>The format of an ACL is one or more ACL entries separated by
+ either commas or newlines. An ACL entry is one of the following: </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>
+REVISION:&#60;revision number&#62;
+OWNER:&#60;sid or name&#62;
+GROUP:&#60;sid or name&#62;
+ACL:&#60;sid or name&#62;:&#60;type&#62;/&#60;flags&#62;/&#60;mask&#62;
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The revision of the ACL specifies the internal Windows
+ NT ACL revision for the security descriptor.
+ If not specified it defaults to 1. Using values other than 1 may
+ cause strange behaviour. </P
+><P
+>The owner and group specify the owner and group sids for the
+ object. If a SID in the format CWS-1-x-y-z is specified this is used,
+ otherwise the name specified is resolved using the server on which
+ the file or directory resides. </P
+><P
+>ACLs specify permissions granted to the SID. This SID again
+ can be specified in CWS-1-x-y-z format or as a name in which case
+ it is resolved against the server on which the file or directory
+ resides. The type, flags and mask values determine the type of
+ access granted to the SID. </P
+><P
+>The type can be either 0 or 1 corresponding to ALLOWED or
+ DENIED access to the SID. The flags values are generally
+ zero for file ACLs and either 9 or 2 for directory ACLs. Some
+ common flags are: </P
+><P
+></P
+><UL
+><LI
+><P
+>#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1</P
+></LI
+><LI
+><P
+>#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2</P
+></LI
+><LI
+><P
+>#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4
+ </P
+></LI
+><LI
+><P
+>#define SEC_ACE_FLAG_INHERIT_ONLY 0x8</P
+></LI
+></UL
+><P
+>At present flags can only be specified as decimal or
+ hexadecimal values.</P
+><P
+>The mask is a value which expresses the access right
+ granted to the SID. It can be given as a decimal or hexadecimal value,
+ or by using one of the following text strings which map to the NT
+ file permissions of the same name. </P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>R</EM
+> - Allow read access </P
+></LI
+><LI
+><P
+><EM
+>W</EM
+> - Allow write access</P
+></LI
+><LI
+><P
+><EM
+>X</EM
+> - Execute permission on the object</P
+></LI
+><LI
+><P
+><EM
+>D</EM
+> - Delete the object</P
+></LI
+><LI
+><P
+><EM
+>P</EM
+> - Change permissions</P
+></LI
+><LI
+><P
+><EM
+>O</EM
+> - Take ownership</P
+></LI
+></UL
+><P
+>The following combined permissions can be specified:</P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>READ</EM
+> - Equivalent to 'RX'
+ permissions</P
+></LI
+><LI
+><P
+><EM
+>CHANGE</EM
+> - Equivalent to 'RXWD' permissions
+ </P
+></LI
+><LI
+><P
+><EM
+>FULL</EM
+> - Equivalent to 'RWXDPO'
+ permissions</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN125"
+></A
+><H2
+>EXIT STATUS</H2
+><P
+>The <B
+CLASS="COMMAND"
+>smbcacls</B
+> program sets the exit status
+ depending on the success or otherwise of the operations performed.
+ The exit status may be one of the following values. </P
+><P
+>If the operation succeeded, smbcacls returns and exit
+ status of 0. If <B
+CLASS="COMMAND"
+>smbcacls</B
+> couldn't connect to the specified server,
+ or there was an error getting or setting the ACLs, an exit status
+ of 1 is returned. If there was an error parsing any command line
+ arguments, an exit status of 2 is returned. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN131"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN134"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+><B
+CLASS="COMMAND"
+>smbcacls</B
+> was written by Andrew Tridgell
+ and Tim Potter.</P
+><P
+>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbclient.1.html b/docs/htmldocs/smbclient.1.html
new file mode 100755
index 00000000000..4c770f9eb21
--- /dev/null
+++ b/docs/htmldocs/smbclient.1.html
@@ -0,0 +1,1613 @@
+<HTML
+><HEAD
+><TITLE
+>smbclient</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBCLIENT"
+>smbclient</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbclient&nbsp;--&nbsp;ftp-like client to access SMB/CIFS resources
+ on servers</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbclient</B
+> {servicename} [password] [-b &#60;buffer size&#62;] [-d debuglevel] [-D Directory] [-U username] [-W workgroup] [-M &#60;netbios name&#62;] [-m maxprotocol] [-A authfile] [-N] [-l logfile] [-L &#60;netbios name&#62;] [-I destinationIP] [-E &#60;terminal code&#62;] [-c &#60;command string&#62;] [-i scope] [-O &#60;socket options&#62;] [-p port] [-R &#60;name resolve order&#62;] [-s &#60;smb config file&#62;] [-T&#60;c|x&#62;IXFqgbNan]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN33"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbclient</B
+> is a client that can
+ 'talk' to an SMB/CIFS server. It offers an interface
+ similar to that of the ftp program (see <B
+CLASS="COMMAND"
+>ftp(1)</B
+>).
+ Operations include things like getting files from the server
+ to the local machine, putting files from the local machine to
+ the server, retrieving directory information from the server
+ and so on. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>servicename</DT
+><DD
+><P
+>servicename is the name of the service
+ you want to use on the server. A service name takes the form
+ <TT
+CLASS="FILENAME"
+>//server/service</TT
+> where <TT
+CLASS="PARAMETER"
+><I
+>server
+ </I
+></TT
+> is the NetBIOS name of the SMB/CIFS server
+ offering the desired service and <TT
+CLASS="PARAMETER"
+><I
+>service</I
+></TT
+>
+ is the name of the service offered. Thus to connect to
+ the service "printer" on the SMB/CIFS server "smbserver",
+ you would use the servicename <TT
+CLASS="FILENAME"
+>//smbserver/printer
+ </TT
+></P
+><P
+>Note that the server name required is NOT necessarily
+ the IP (DNS) host name of the server ! The name required is
+ a NetBIOS server name, which may or may not be the
+ same as the IP hostname of the machine running the server.
+ </P
+><P
+>The server name is looked up according to either
+ the <TT
+CLASS="PARAMETER"
+><I
+>-R</I
+></TT
+> parameter to <B
+CLASS="COMMAND"
+>smbclient</B
+> or
+ using the name resolve order parameter in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file,
+ allowing an administrator to change the order and methods
+ by which server names are looked up. </P
+></DD
+><DT
+>password</DT
+><DD
+><P
+>The password required to access the specified
+ service on the specified server. If this parameter is
+ supplied, the <TT
+CLASS="PARAMETER"
+><I
+>-N</I
+></TT
+> option (suppress
+ password prompt) is assumed. </P
+><P
+>There is no default password. If no password is supplied
+ on the command line (either by using this parameter or adding
+ a password to the <TT
+CLASS="PARAMETER"
+><I
+>-U</I
+></TT
+> option (see
+ below)) and the <TT
+CLASS="PARAMETER"
+><I
+>-N</I
+></TT
+> option is not
+ specified, the client will prompt for a password, even if
+ the desired service does not require one. (If no password is
+ required, simply press ENTER to provide a null password.)
+ </P
+><P
+>Note: Some servers (including OS/2 and Windows for
+ Workgroups) insist on an uppercase password. Lowercase
+ or mixed case passwords may be rejected by these servers.
+ </P
+><P
+>Be cautious about including passwords in scripts.
+ </P
+></DD
+><DT
+>-s smb.conf</DT
+><DD
+><P
+>Specifies the location of the all important
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. </P
+></DD
+><DT
+>-O socket options</DT
+><DD
+><P
+>TCP socket options to set on the client
+ socket. See the socket options parameter in the <TT
+CLASS="FILENAME"
+> smb.conf (5)</TT
+> manpage for the list of valid
+ options. </P
+></DD
+><DT
+>-R &#60;name resolve order&#62;</DT
+><DD
+><P
+>This option is used by the programs in the Samba
+ suite to determine what naming services and in what order to resolve
+ host names to IP addresses. The option takes a space-separated
+ string of different name resolution options.</P
+><P
+>The options are :"lmhosts", "host", "wins" and "bcast". They
+ cause names to be resolved as follows :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmhosts</TT
+> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <A
+HREF="lmhosts.5.html"
+TARGET="_top"
+>lmhosts(5)</A
+> for details) then
+ any name type matches for lookup.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>host</TT
+> : Do a standard host
+ name to IP address resolution, using the system <TT
+CLASS="FILENAME"
+>/etc/hosts
+ </TT
+>, NIS, or DNS lookups. This method of name resolution
+ is operating system dependent, for instance on IRIX or Solaris this
+ may be controlled by the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>
+ file). Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>wins</TT
+> : Query a name with
+ the IP address listed in the <TT
+CLASS="PARAMETER"
+><I
+>wins server</I
+></TT
+>
+ parameter. If no WINS server has
+ been specified this method will be ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>bcast</TT
+> : Do a broadcast on
+ each of the known local interfaces listed in the
+ <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+>
+ parameter. This is the least reliable of the name resolution
+ methods as it depends on the target host being on a locally
+ connected subnet.</P
+></LI
+></UL
+><P
+>If this parameter is not set then the name resolve order
+ defined in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file parameter
+ (name resolve order) will be used. </P
+><P
+>The default order is lmhosts, host, wins, bcast and without
+ this parameter or any entry in the <TT
+CLASS="PARAMETER"
+><I
+>name resolve order
+ </I
+></TT
+> parameter of the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file the name resolution
+ methods will be attempted in this order. </P
+></DD
+><DT
+>-M NetBIOS name</DT
+><DD
+><P
+>This options allows you to send messages, using
+ the "WinPopup" protocol, to another computer. Once a connection is
+ established you then type your message, pressing ^D (control-D) to
+ end. </P
+><P
+>If the receiving computer is running WinPopup the user will
+ receive the message and probably a beep. If they are not running
+ WinPopup the message will be lost, and no error message will
+ occur. </P
+><P
+>The message is also automatically truncated if the message
+ is over 1600 bytes, as this is the limit of the protocol.
+ </P
+><P
+>One useful trick is to cat the message through
+ <B
+CLASS="COMMAND"
+>smbclient</B
+>. For example: <B
+CLASS="COMMAND"
+> cat mymessage.txt | smbclient -M FRED </B
+> will
+ send the message in the file <TT
+CLASS="FILENAME"
+>mymessage.txt</TT
+>
+ to the machine FRED. </P
+><P
+>You may also find the <TT
+CLASS="PARAMETER"
+><I
+>-U</I
+></TT
+> and
+ <TT
+CLASS="PARAMETER"
+><I
+>-I</I
+></TT
+> options useful, as they allow you to
+ control the FROM and TO parts of the message. </P
+><P
+>See the message command parameter in the <TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+> for a description of how to handle incoming
+ WinPopup messages in Samba. </P
+><P
+><EM
+>Note</EM
+>: Copy WinPopup into the startup group
+ on your WfWg PCs if you want them to always be able to receive
+ messages. </P
+></DD
+><DT
+>-i scope</DT
+><DD
+><P
+>This specifies a NetBIOS scope that smbclient will
+ use to communicate with when generating NetBIOS names. For details
+ on the use of NetBIOS scopes, see <TT
+CLASS="FILENAME"
+>rfc1001.txt</TT
+>
+ and <TT
+CLASS="FILENAME"
+>rfc1002.txt</TT
+>.
+ NetBIOS scopes are <EM
+>very</EM
+> rarely used, only set
+ this parameter if you are the system administrator in charge of all
+ the NetBIOS systems you communicate with. </P
+></DD
+><DT
+>-N</DT
+><DD
+><P
+>If specified, this parameter suppresses the normal
+ password prompt from the client to the user. This is useful when
+ accessing a service that does not require a password. </P
+><P
+>Unless a password is specified on the command line or
+ this parameter is specified, the client will request a
+ password.</P
+></DD
+><DT
+>-n NetBIOS name</DT
+><DD
+><P
+>By default, the client will use the local
+ machine's hostname (in uppercase) as its NetBIOS name. This parameter
+ allows you to override the host name and use whatever NetBIOS
+ name you wish. </P
+></DD
+><DT
+>-d debuglevel</DT
+><DD
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>debuglevel</I
+></TT
+> is an integer from 0 to 10, or
+ the letter 'A'. </P
+><P
+>The default value if this parameter is not specified
+ is zero. </P
+><P
+>The higher this value, the more detail will be logged to
+ the log files about the activities of the
+ client. At level 0, only critical errors and serious warnings will
+ be logged. Level 1 is a reasonable level for day to day running -
+ it generates a small amount of information about operations
+ carried out. </P
+><P
+>Levels above 1 will generate considerable amounts of log
+ data, and should only be used when investigating a problem.
+ Levels above 3 are designed for use only by developers and
+ generate HUGE amounts of log data, most of which is extremely
+ cryptic. If <TT
+CLASS="REPLACEABLE"
+><I
+>debuglevel</I
+></TT
+> is set to the letter 'A', then <EM
+>all
+ </EM
+> debug messages will be printed. This setting
+ is for developers only (and people who <EM
+>really</EM
+> want
+ to know how the code works internally). </P
+><P
+>Note that specifying this parameter here will override
+ the log level parameter in the <TT
+CLASS="FILENAME"
+>smb.conf (5)</TT
+>
+ file. </P
+></DD
+><DT
+>-p port</DT
+><DD
+><P
+>This number is the TCP port number that will be used
+ when making connections to the server. The standard (well-known)
+ TCP port number for an SMB/CIFS server is 139, which is the
+ default. </P
+></DD
+><DT
+>-l logfilename</DT
+><DD
+><P
+>If specified, <TT
+CLASS="REPLACEABLE"
+><I
+>logfilename</I
+></TT
+> specifies a base filename
+ into which operational data from the running client will be
+ logged. </P
+><P
+>The default base name is specified at compile time.</P
+><P
+>The base name is used to generate actual log file names.
+ For example, if the name specified was "log", the debug file
+ would be <TT
+CLASS="FILENAME"
+>log.client</TT
+>.</P
+><P
+>The log file generated is never removed by the client.
+ </P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Print the usage message for the client. </P
+></DD
+><DT
+>-I IP-address</DT
+><DD
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>IP address</I
+></TT
+> is the address of the server to connect to.
+ It should be specified in standard "a.b.c.d" notation. </P
+><P
+>Normally the client would attempt to locate a named
+ SMB/CIFS server by looking it up via the NetBIOS name resolution
+ mechanism described above in the <TT
+CLASS="PARAMETER"
+><I
+>name resolve order</I
+></TT
+>
+ parameter above. Using this parameter will force the client
+ to assume that the server is on the machine with the specified IP
+ address and the NetBIOS name component of the resource being
+ connected to will be ignored. </P
+><P
+>There is no default for this parameter. If not supplied,
+ it will be determined automatically by the client as described
+ above. </P
+></DD
+><DT
+>-E</DT
+><DD
+><P
+>This parameter causes the client to write messages
+ to the standard error stream (stderr) rather than to the standard
+ output stream. </P
+><P
+>By default, the client writes messages to standard output
+ - typically the user's tty. </P
+></DD
+><DT
+>-U username[%pass]</DT
+><DD
+><P
+>Sets the SMB username or username and password.
+ If %pass is not specified, The user will be prompted. The client
+ will first check the <TT
+CLASS="ENVAR"
+>USER</TT
+> environment variable, then the
+ <TT
+CLASS="ENVAR"
+>LOGNAME</TT
+> variable and if either exists, the
+ string is uppercased. Anything in these variables following a '%'
+ sign will be treated as the password. If these environment
+ variables are not found, the username <TT
+CLASS="CONSTANT"
+>GUEST</TT
+>
+ is used. </P
+><P
+>If the password is not included in these environment
+ variables (using the %pass syntax), <B
+CLASS="COMMAND"
+>smbclient</B
+> will look for
+ a <TT
+CLASS="ENVAR"
+>PASSWD</TT
+> environment variable from which
+ to read the password. </P
+><P
+>A third option is to use a credentials file which
+ contains the plaintext of the domain name, username and password. This
+ option is mainly provided for scripts where the admin doesn't
+ wish to pass the credentials on the command line or via environment
+ variables. If this method is used, make certain that the permissions
+ on the file restrict access from unwanted users. See the
+ <TT
+CLASS="PARAMETER"
+><I
+>-A</I
+></TT
+> for more details. </P
+><P
+>Be cautious about including passwords in scripts or in
+ the <TT
+CLASS="ENVAR"
+>PASSWD</TT
+> environment variable. Also, on
+ many systems the command line of a running process may be seen
+ via the <B
+CLASS="COMMAND"
+>ps</B
+> command to be safe always allow
+ <B
+CLASS="COMMAND"
+>smbclient</B
+> to prompt for a password and type
+ it in directly. </P
+></DD
+><DT
+>-A filename</DT
+><DD
+><P
+>This option allows
+ you to specify a file from which to read the username, domain name, and
+ password used in the connection. The format of the file is
+ </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>username = &#60;value&#62;
+password = &#60;value&#62;
+domain = &#60;value&#62;
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>If the domain parameter is missing the current workgroup name
+ is used instead. Make certain that the permissions on the file restrict
+ access from unwanted users. </P
+></DD
+><DT
+>-L</DT
+><DD
+><P
+>This option allows you to look at what services
+ are available on a server. You use it as <B
+CLASS="COMMAND"
+>smbclient -L
+ host</B
+> and a list should appear. The <TT
+CLASS="PARAMETER"
+><I
+>-I
+ </I
+></TT
+> option may be useful if your NetBIOS names don't
+ match your TCP/IP DNS host names or if you are trying to reach a
+ host on another network. </P
+></DD
+><DT
+>-t terminal code</DT
+><DD
+><P
+>This option tells <B
+CLASS="COMMAND"
+>smbclient</B
+> how to interpret
+ filenames coming from the remote server. Usually Asian language
+ multibyte UNIX implementations use different character sets than
+ SMB/CIFS servers (<EM
+>EUC</EM
+> instead of <EM
+> SJIS</EM
+> for example). Setting this parameter will let
+ <B
+CLASS="COMMAND"
+>smbclient</B
+> convert between the UNIX filenames and
+ the SMB filenames correctly. This option has not been seriously tested
+ and may have some problems. </P
+><P
+>The terminal codes include CWsjis, CWeuc, CWjis7, CWjis8,
+ CWjunet, CWhex, CWcap. This is not a complete list, check the Samba
+ source code for the complete list. </P
+></DD
+><DT
+>-b buffersize</DT
+><DD
+><P
+>This option changes the transmit/send buffer
+ size when getting or putting a file from/to the server. The default
+ is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
+ observed to speed up file transfers to and from a Win9x server.
+ </P
+></DD
+><DT
+>-W WORKGROUP</DT
+><DD
+><P
+>Override the default workgroup (domain) specified
+ in the workgroup parameter of the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ file for this connection. This may be needed to connect to some
+ servers. </P
+></DD
+><DT
+>-T tar options</DT
+><DD
+><P
+>smbclient may be used to create <B
+CLASS="COMMAND"
+>tar(1)
+ </B
+> compatible backups of all the files on an SMB/CIFS
+ share. The secondary tar flags that can be given to this option
+ are : </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> - Create a tar file on UNIX.
+ Must be followed by the name of a tar file, tape device
+ or "-" for standard output. If using standard output you must
+ turn the log level to its lowest value -d0 to avoid corrupting
+ your tar file. This flag is mutually exclusive with the
+ <TT
+CLASS="PARAMETER"
+><I
+>x</I
+></TT
+> flag. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>x</I
+></TT
+> - Extract (restore) a local
+ tar file back to a share. Unless the -D option is given, the tar
+ files will be restored from the top level of the share. Must be
+ followed by the name of the tar file, device or "-" for standard
+ input. Mutually exclusive with the <TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> flag.
+ Restored files have their creation times (mtime) set to the
+ date saved in the tar file. Directories currently do not get
+ their creation dates restored properly. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>I</I
+></TT
+> - Include files and directories.
+ Is the default behavior when filenames are specified above. Causes
+ tar files to be included in an extract or create (and therefore
+ everything else to be excluded). See example below. Filename globbing
+ works in one of two ways. See r below. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>X</I
+></TT
+> - Exclude files and directories.
+ Causes tar files to be excluded from an extract or create. See
+ example below. Filename globbing works in one of two ways now.
+ See <TT
+CLASS="PARAMETER"
+><I
+>r</I
+></TT
+> below. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+> - Blocksize. Must be followed
+ by a valid (greater than zero) blocksize. Causes tar file to be
+ written out in blocksize*TBLOCK (usually 512 byte) blocks.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>g</I
+></TT
+> - Incremental. Only back up
+ files that have the archive bit set. Useful only with the
+ <TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> flag. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>q</I
+></TT
+> - Quiet. Keeps tar from printing
+ diagnostics as it works. This is the same as tarmode quiet.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>r</I
+></TT
+> - Regular expression include
+ or exclude. Uses regular expression matching for
+ excluding or excluding files if compiled with HAVE_REGEX_H.
+ However this mode can be very slow. If not compiled with
+ HAVE_REGEX_H, does a limited wildcard match on '*' and '?'.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>N</I
+></TT
+> - Newer than. Must be followed
+ by the name of a file whose date is compared against files found
+ on the share during a create. Only files newer than the file
+ specified are backed up to the tar file. Useful only with the
+ <TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> flag. </P
+></LI
+><LI
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>a</I
+></TT
+> - Set archive bit. Causes the
+ archive bit to be reset when a file is backed up. Useful with the
+ <TT
+CLASS="PARAMETER"
+><I
+>g</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>c</I
+></TT
+> flags.
+ </P
+></LI
+></UL
+><P
+><EM
+>Tar Long File Names</EM
+></P
+><P
+><B
+CLASS="COMMAND"
+>smbclient</B
+>'s tar option now supports long
+ file names both on backup and restore. However, the full path
+ name of the file must be less than 1024 bytes. Also, when
+ a tar archive is created, <B
+CLASS="COMMAND"
+>smbclient</B
+>'s tar option places all
+ files in the archive with relative names, not absolute names.
+ </P
+><P
+><EM
+>Tar Filenames</EM
+></P
+><P
+>All file names can be given as DOS path names (with '\'
+ as the component separator) or as UNIX path names (with '/' as
+ the component separator). </P
+><P
+><EM
+>Examples</EM
+></P
+><P
+>Restore from tar file <TT
+CLASS="FILENAME"
+>backup.tar</TT
+> into myshare on mypc
+ (no password on share). </P
+><P
+><B
+CLASS="COMMAND"
+>smbclient //mypc/yshare "" -N -Tx backup.tar
+ </B
+></P
+><P
+>Restore everything except <TT
+CLASS="FILENAME"
+>users/docs</TT
+>
+ </P
+><P
+><B
+CLASS="COMMAND"
+>smbclient //mypc/myshare "" -N -TXx backup.tar
+ users/docs</B
+></P
+><P
+>Create a tar file of the files beneath <TT
+CLASS="FILENAME"
+> users/docs</TT
+>. </P
+><P
+><B
+CLASS="COMMAND"
+>smbclient //mypc/myshare "" -N -Tc
+ backup.tar users/docs </B
+></P
+><P
+>Create the same tar file as above, but now use
+ a DOS path name. </P
+><P
+><B
+CLASS="COMMAND"
+>smbclient //mypc/myshare "" -N -tc backup.tar
+ users\edocs </B
+></P
+><P
+>Create a tar file of all the files and directories in
+ the share. </P
+><P
+><B
+CLASS="COMMAND"
+>smbclient //mypc/myshare "" -N -Tc backup.tar *
+ </B
+></P
+></DD
+><DT
+>-D initial directory</DT
+><DD
+><P
+>Change to initial directory before starting. Probably
+ only of any use with the tar -T option. </P
+></DD
+><DT
+>-c command string</DT
+><DD
+><P
+>command string is a semicolon-separated list of
+ commands to be executed instead of prompting from stdin. <TT
+CLASS="PARAMETER"
+><I
+> -N</I
+></TT
+> is implied by <TT
+CLASS="PARAMETER"
+><I
+>-c</I
+></TT
+>.</P
+><P
+>This is particularly useful in scripts and for printing stdin
+ to the server, e.g. <B
+CLASS="COMMAND"
+>-c 'print -'</B
+>. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN310"
+></A
+><H2
+>OPERATIONS</H2
+><P
+>Once the client is running, the user is presented with
+ a prompt : </P
+><P
+><TT
+CLASS="PROMPT"
+>smb:\&#62; </TT
+></P
+><P
+>The backslash ("\") indicates the current working directory
+ on the server, and will change if the current working directory
+ is changed. </P
+><P
+>The prompt indicates that the client is ready and waiting to
+ carry out a user command. Each command is a single word, optionally
+ followed by parameters specific to that command. Command and parameters
+ are space-delimited unless these notes specifically
+ state otherwise. All commands are case-insensitive. Parameters to
+ commands may or may not be case sensitive, depending on the command.
+ </P
+><P
+>You can specify file names which have spaces in them by quoting
+ the name with double quotes, for example "a long file name". </P
+><P
+>Parameters shown in square brackets (e.g., "[parameter]") are
+ optional. If not given, the command will use suitable defaults. Parameters
+ shown in angle brackets (e.g., "&#60;parameter&#62;") are required.
+ </P
+><P
+>Note that all commands operating on the server are actually
+ performed by issuing a request to the server. Thus the behavior may
+ vary from server to server, depending on how the server was implemented.
+ </P
+><P
+>The commands available are given here in alphabetical order. </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>? [command]</DT
+><DD
+><P
+>If <TT
+CLASS="REPLACEABLE"
+><I
+>command</I
+></TT
+> is specified, the ? command will display
+ a brief informative message about the specified command. If no
+ command is specified, a list of available commands will
+ be displayed. </P
+></DD
+><DT
+>! [shell command]</DT
+><DD
+><P
+>If <TT
+CLASS="REPLACEABLE"
+><I
+>shell command</I
+></TT
+> is specified, the !
+ command will execute a shell locally and run the specified shell
+ command. If no command is specified, a local shell will be run.
+ </P
+></DD
+><DT
+>altname file</DT
+><DD
+><P
+>The client will request that the server return
+ the "alternate" name (the 8.3 name) for a file or directory.
+ </P
+></DD
+><DT
+>cancel jobid0 [jobid1] ... [jobidN]</DT
+><DD
+><P
+>The client will request that the server cancel
+ the printjobs identified by the given numeric print job ids.
+ </P
+></DD
+><DT
+>chmod file mode in octal</DT
+><DD
+><P
+>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ change the UNIX permissions to the given octal mode, in standard UNIX format.
+ </P
+></DD
+><DT
+>chown file uid gid</DT
+><DD
+><P
+>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ change the UNIX user and group ownership to the given decimal values. Note there is
+ currently no way to remotely look up the UNIX uid and gid values for a given name.
+ This may be addressed in future versions of the CIFS UNIX extensions.
+ </P
+></DD
+><DT
+>cd [directory name]</DT
+><DD
+><P
+>If "directory name" is specified, the current
+ working directory on the server will be changed to the directory
+ specified. This operation will fail if for any reason the specified
+ directory is inaccessible. </P
+><P
+>If no directory name is specified, the current working
+ directory on the server will be reported. </P
+></DD
+><DT
+>del &#60;mask&#62;</DT
+><DD
+><P
+>The client will request that the server attempt
+ to delete all files matching <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> from the current working
+ directory on the server. </P
+></DD
+><DT
+>dir &#60;mask&#62;</DT
+><DD
+><P
+>A list of the files matching <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> in the current
+ working directory on the server will be retrieved from the server
+ and displayed. </P
+></DD
+><DT
+>exit</DT
+><DD
+><P
+>Terminate the connection with the server and exit
+ from the program. </P
+></DD
+><DT
+>get &#60;remote file name&#62; [local file name]</DT
+><DD
+><P
+>Copy the file called <TT
+CLASS="FILENAME"
+>remote file name</TT
+> from
+ the server to the machine running the client. If specified, name
+ the local copy <TT
+CLASS="FILENAME"
+>local file name</TT
+>. Note that all transfers in
+ <B
+CLASS="COMMAND"
+>smbclient</B
+> are binary. See also the
+ lowercase command. </P
+></DD
+><DT
+>help [command]</DT
+><DD
+><P
+>See the ? command above. </P
+></DD
+><DT
+>lcd [directory name]</DT
+><DD
+><P
+>If <TT
+CLASS="REPLACEABLE"
+><I
+>directory name</I
+></TT
+> is specified, the current
+ working directory on the local machine will be changed to
+ the directory specified. This operation will fail if for any
+ reason the specified directory is inaccessible. </P
+><P
+>If no directory name is specified, the name of the
+ current working directory on the local machine will be reported.
+ </P
+></DD
+><DT
+>link source destination</DT
+><DD
+><P
+>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ create a hard link between the source and destination files. The source file
+ must not exist.
+ </P
+></DD
+><DT
+>lowercase</DT
+><DD
+><P
+>Toggle lowercasing of filenames for the get and
+ mget commands. </P
+><P
+>When lowercasing is toggled ON, local filenames are converted
+ to lowercase when using the get and mget commands. This is
+ often useful when copying (say) MSDOS files from a server, because
+ lowercase filenames are the norm on UNIX systems. </P
+></DD
+><DT
+>ls &#60;mask&#62;</DT
+><DD
+><P
+>See the dir command above. </P
+></DD
+><DT
+>mask &#60;mask&#62;</DT
+><DD
+><P
+>This command allows the user to set up a mask
+ which will be used during recursive operation of the mget and
+ mput commands. </P
+><P
+>The masks specified to the mget and mput commands act as
+ filters for directories rather than files when recursion is
+ toggled ON. </P
+><P
+>The mask specified with the mask command is necessary
+ to filter files within those directories. For example, if the
+ mask specified in an mget command is "source*" and the mask
+ specified with the mask command is "*.c" and recursion is
+ toggled ON, the mget command will retrieve all files matching
+ "*.c" in all directories below and including all directories
+ matching "source*" in the current working directory. </P
+><P
+>Note that the value for mask defaults to blank (equivalent
+ to "*") and remains so until the mask command is used to change it.
+ It retains the most recently specified value indefinitely. To
+ avoid unexpected results it would be wise to change the value of
+ mask back to "*" after using the mget or mput commands. </P
+></DD
+><DT
+>md &#60;directory name&#62;</DT
+><DD
+><P
+>See the mkdir command. </P
+></DD
+><DT
+>mget &#60;mask&#62;</DT
+><DD
+><P
+>Copy all files matching <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> from the server to
+ the machine running the client. </P
+><P
+>Note that <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> is interpreted differently during recursive
+ operation and non-recursive operation - refer to the recurse and
+ mask commands for more information. Note that all transfers in
+ <B
+CLASS="COMMAND"
+>smbclient</B
+> are binary. See also the lowercase command. </P
+></DD
+><DT
+>mkdir &#60;directory name&#62;</DT
+><DD
+><P
+>Create a new directory on the server (user access
+ privileges permitting) with the specified name. </P
+></DD
+><DT
+>mput &#60;mask&#62;</DT
+><DD
+><P
+>Copy all files matching <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> in the current working
+ directory on the local machine to the current working directory on
+ the server. </P
+><P
+>Note that <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> is interpreted differently during recursive
+ operation and non-recursive operation - refer to the recurse and mask
+ commands for more information. Note that all transfers in <B
+CLASS="COMMAND"
+>smbclient</B
+>
+ are binary. </P
+></DD
+><DT
+>print &#60;file name&#62;</DT
+><DD
+><P
+>Print the specified file from the local machine
+ through a printable service on the server. </P
+><P
+>See also the printmode command.</P
+></DD
+><DT
+>printmode &#60;graphics or text&#62;</DT
+><DD
+><P
+>Set the print mode to suit either binary data
+ (such as graphical information) or text. Subsequent print
+ commands will use the currently set print mode. </P
+></DD
+><DT
+>prompt</DT
+><DD
+><P
+>Toggle prompting for filenames during operation
+ of the mget and mput commands. </P
+><P
+>When toggled ON, the user will be prompted to confirm
+ the transfer of each file during these commands. When toggled
+ OFF, all specified files will be transferred without prompting.
+ </P
+></DD
+><DT
+>put &#60;local file name&#62; [remote file name]</DT
+><DD
+><P
+>Copy the file called <TT
+CLASS="FILENAME"
+>local file name</TT
+> from the
+ machine running the client to the server. If specified,
+ name the remote copy <TT
+CLASS="FILENAME"
+>remote file name</TT
+>. Note that all transfers
+ in <B
+CLASS="COMMAND"
+>smbclient</B
+> are binary. See also the lowercase command.
+ </P
+></DD
+><DT
+>queue</DT
+><DD
+><P
+>Displays the print queue, showing the job id,
+ name, size and current status. </P
+></DD
+><DT
+>quit</DT
+><DD
+><P
+>See the exit command. </P
+></DD
+><DT
+>rd &#60;directory name&#62;</DT
+><DD
+><P
+>See the rmdir command. </P
+></DD
+><DT
+>recurse</DT
+><DD
+><P
+>Toggle directory recursion for the commands mget
+ and mput. </P
+><P
+>When toggled ON, these commands will process all directories
+ in the source directory (i.e., the directory they are copying
+ from ) and will recurse into any that match the mask specified
+ to the command. Only files that match the mask specified using
+ the mask command will be retrieved. See also the mask command.
+ </P
+><P
+>When recursion is toggled OFF, only files from the current
+ working directory on the source machine that match the mask specified
+ to the mget or mput commands will be copied, and any mask specified
+ using the mask command will be ignored. </P
+></DD
+><DT
+>rm &#60;mask&#62;</DT
+><DD
+><P
+>Remove all files matching <TT
+CLASS="REPLACEABLE"
+><I
+>mask</I
+></TT
+> from the current
+ working directory on the server. </P
+></DD
+><DT
+>rmdir &#60;directory name&#62;</DT
+><DD
+><P
+>Remove the specified directory (user access
+ privileges permitting) from the server. </P
+></DD
+><DT
+>setmode &#60;filename&#62; &#60;perm=[+|\-]rsha&#62;</DT
+><DD
+><P
+>A version of the DOS attrib command to set
+ file permissions. For example: </P
+><P
+><B
+CLASS="COMMAND"
+>setmode myfile +r </B
+></P
+><P
+>would make myfile read only. </P
+></DD
+><DT
+>symlink source destination</DT
+><DD
+><P
+>This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not. The client requests that the server
+ create a symbolic hard link between the source and destination files. The source file
+ must not exist. Note that the server will not create a link to any path that lies
+ outside the currently connected share. This is enforced by the Samba server.
+ </P
+></DD
+><DT
+>tar &#60;c|x&#62;[IXbgNa]</DT
+><DD
+><P
+>Performs a tar operation - see the <TT
+CLASS="PARAMETER"
+><I
+>-T
+ </I
+></TT
+> command line option above. Behavior may be affected
+ by the tarmode command (see below). Using g (incremental) and N
+ (newer) will affect tarmode settings. Note that using the "-" option
+ with tar x may not work - use the command line option instead.
+ </P
+></DD
+><DT
+>blocksize &#60;blocksize&#62;</DT
+><DD
+><P
+>Blocksize. Must be followed by a valid (greater
+ than zero) blocksize. Causes tar file to be written out in
+ <TT
+CLASS="REPLACEABLE"
+><I
+>blocksize</I
+></TT
+>*TBLOCK (usually 512 byte) blocks. </P
+></DD
+><DT
+>tarmode &#60;full|inc|reset|noreset&#62;</DT
+><DD
+><P
+>Changes tar's behavior with regard to archive
+ bits. In full mode, tar will back up everything regardless of the
+ archive bit setting (this is the default mode). In incremental mode,
+ tar will only back up files with the archive bit set. In reset mode,
+ tar will reset the archive bit on all files it backs up (implies
+ read/write share). </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN501"
+></A
+><H2
+>NOTES</H2
+><P
+>Some servers are fussy about the case of supplied usernames,
+ passwords, share names (AKA service names) and machine names.
+ If you fail to connect try giving all parameters in uppercase.
+ </P
+><P
+>It is often necessary to use the -n option when connecting
+ to some types of servers. For example OS/2 LanManager insists
+ on a valid NetBIOS name being used, so you need to supply a valid
+ name that would be known to the server.</P
+><P
+>smbclient supports long file names where the server
+ supports the LANMAN2 protocol or above. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN506"
+></A
+><H2
+>ENVIRONMENT VARIABLES</H2
+><P
+>The variable <TT
+CLASS="ENVAR"
+>USER</TT
+> may contain the
+ username of the person using the client. This information is
+ used only if the protocol level is high enough to support
+ session-level passwords.</P
+><P
+>The variable <TT
+CLASS="ENVAR"
+>PASSWD</TT
+> may contain
+ the password of the person using the client. This information is
+ used only if the protocol level is high enough to support
+ session-level passwords. </P
+><P
+>The variable <TT
+CLASS="ENVAR"
+>LIBSMB_PROG</TT
+> may contain
+ the path, executed with system(), which the client should connect
+ to instead of connecting to a server. This functionality is primarily
+ intended as a development aid, and works best when using a LMHOSTS
+ file</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN514"
+></A
+><H2
+>INSTALLATION</H2
+><P
+>The location of the client program is a matter for
+ individual system administrators. The following are thus
+ suggestions only. </P
+><P
+>It is recommended that the smbclient software be installed
+ in the <TT
+CLASS="FILENAME"
+>/usr/local/samba/bin/</TT
+> or <TT
+CLASS="FILENAME"
+> /usr/samba/bin/</TT
+> directory, this directory readable
+ by all, writeable only by root. The client program itself should
+ be executable by all. The client should <EM
+>NOT</EM
+> be
+ setuid or setgid! </P
+><P
+>The client log files should be put in a directory readable
+ and writeable only by the user. </P
+><P
+>To test the client, you will need to know the name of a
+ running SMB/CIFS server. It is possible to run <B
+CLASS="COMMAND"
+>smbd(8)
+ </B
+> as an ordinary user - running that server as a daemon
+ on a user-accessible port (typically any port number over 1024)
+ would provide a suitable test server. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN524"
+></A
+><H2
+>DIAGNOSTICS</H2
+><P
+>Most diagnostics issued by the client are logged in a
+ specified log file. The log file name is specified at compile time,
+ but may be overridden on the command line. </P
+><P
+>The number and nature of diagnostics available depends
+ on the debug level used by the client. If you have problems,
+ set the debug level to 3 and peruse the log files. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN528"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN531"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbcontrol.1.html b/docs/htmldocs/smbcontrol.1.html
new file mode 100755
index 00000000000..8e0f326125f
--- /dev/null
+++ b/docs/htmldocs/smbcontrol.1.html
@@ -0,0 +1,349 @@
+<HTML
+><HEAD
+><TITLE
+>smbcontrol</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBCONTROL"
+>smbcontrol</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbcontrol&nbsp;--&nbsp;send messages to smbd, nmbd or winbindd processes</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbcontrol</B
+> [-d &#60;debug level&#62;] [-s &#60;smb config file&#62;] {-i}</P
+><P
+><B
+CLASS="COMMAND"
+>smbcontrol</B
+> [-d &#60;debug level&#62;] [-s &#60;smb config file&#62;] {destination} {message-type} [parameter]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN21"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbcontrol</B
+> is a very small program, which
+ sends messages to an <A
+HREF="smbd.8.html"
+TARGET="_top"
+>smbd(8)</A
+>,
+ an <A
+HREF="nmbd.8.html"
+TARGET="_top"
+>nmbd(8)</A
+>
+ or a <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+>
+ daemon running on the system.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN30"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-d &#60;debuglevel&#62;</DT
+><DD
+><P
+>debuglevel is an integer from 0 to 10.</P
+></DD
+><DT
+>-s &#60;smb.conf&#62;</DT
+><DD
+><P
+>This parameter specifies the pathname to
+ the Samba configuration file, <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> smb.conf(5)</A
+>. This file controls all aspects of
+ the Samba setup on the machine.</P
+></DD
+><DT
+>-i</DT
+><DD
+><P
+>Run interactively. Individual commands
+ of the form destination message-type parameters can be entered
+ on STDIN. An empty command line or a "q" will quit the
+ program.</P
+></DD
+><DT
+>destination</DT
+><DD
+><P
+>One of <TT
+CLASS="PARAMETER"
+><I
+>nmbd</I
+></TT
+>
+ <TT
+CLASS="PARAMETER"
+><I
+>smbd</I
+></TT
+> or a process ID.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>smbd</I
+></TT
+> destination causes the
+ message to "broadcast" to all smbd daemons.</P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>nmbd</I
+></TT
+> destination causes the
+ message to be sent to the nmbd daemon specified in the
+ <TT
+CLASS="FILENAME"
+>nmbd.pid</TT
+> file.</P
+><P
+>If a single process ID is given, the message is sent
+ to only that process.</P
+></DD
+><DT
+>message-type</DT
+><DD
+><P
+>One of: <TT
+CLASS="CONSTANT"
+>close-share</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>debug</TT
+>,
+ <TT
+CLASS="CONSTANT"
+>force-election</TT
+>, <TT
+CLASS="CONSTANT"
+>ping
+ </TT
+>, <TT
+CLASS="CONSTANT"
+>profile</TT
+>, <TT
+CLASS="CONSTANT"
+> debuglevel</TT
+>, <TT
+CLASS="CONSTANT"
+>profilelevel</TT
+>,
+ or <TT
+CLASS="CONSTANT"
+>printer-notify</TT
+>.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>close-share</TT
+> message-type sends a
+ message to smbd which will then close the client connections to
+ the named share. Note that this doesn't affect client connections
+ to any other shares. This message-type takes an argument of the
+ share name for which client connections will be closed, or the
+ "*" character which will close all currently open shares.
+ This may be useful if you made changes to the access controls on the share.
+ This message can only be sent to <TT
+CLASS="CONSTANT"
+>smbd</TT
+>.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>debug</TT
+> message-type allows
+ the debug level to be set to the value specified by the
+ parameter. This can be sent to any of the destinations.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>force-election</TT
+> message-type can only be
+ sent to the <TT
+CLASS="CONSTANT"
+>nmbd</TT
+> destination. This message
+ causes the <B
+CLASS="COMMAND"
+>nmbd</B
+> daemon to force a new browse
+ master election.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>ping</TT
+> message-type sends the
+ number of "ping" messages specified by the parameter and waits
+ for the same number of reply "pong" messages. This can be sent to
+ any of the destinations.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>profile</TT
+> message-type sends a
+ message to an smbd to change the profile settings based on the
+ parameter. The parameter can be "on" to turn on profile stats
+ collection, "off" to turn off profile stats collection, "count"
+ to enable only collection of count stats (time stats are
+ disabled), and "flush" to zero the current profile stats. This can
+ be sent to any smbd or nmbd destinations.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>debuglevel</TT
+> message-type sends
+ a "request debug level" message. The current debug level setting
+ is returned by a "debuglevel" message. This can be
+ sent to any of the destinations.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>profilelevel</TT
+> message-type sends
+ a "request profile level" message. The current profile level
+ setting is returned by a "profilelevel" message. This can be sent
+ to any smbd or nmbd destinations.</P
+><P
+>The <TT
+CLASS="CONSTANT"
+>printer-notify</TT
+> message-type sends a
+ message to smbd which in turn sends a printer notify message to
+ any Windows NT clients connected to a printer. This message-type
+ takes an argument of the printer name to send notify messages to.
+ This message can only be sent to <TT
+CLASS="CONSTANT"
+>smbd</TT
+>.</P
+></DD
+><DT
+>parameters</DT
+><DD
+><P
+>any parameters required for the message-type</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN94"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN97"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+>,
+ and <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN104"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbd.8.html b/docs/htmldocs/smbd.8.html
new file mode 100755
index 00000000000..e1ea92b986a
--- /dev/null
+++ b/docs/htmldocs/smbd.8.html
@@ -0,0 +1,761 @@
+<HTML
+><HEAD
+><TITLE
+>smbd</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBD"
+>smbd</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbd&nbsp;--&nbsp;server to provide SMB/CIFS services to clients</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbd</B
+> [-D] [-a] [-i] [-o] [-P] [-h] [-V] [-d &#60;debug level&#62;] [-l &#60;log directory&#62;] [-p &#60;port number&#62;] [-O &#60;socket option&#62;] [-s &#60;configuration file&#62;]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN23"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This program is part of the Samba suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbd</B
+> is the server daemon that
+ provides filesharing and printing services to Windows clients.
+ The server provides filespace and printer services to
+ clients using the SMB (or CIFS) protocol. This is compatible
+ with the LanManager protocol, and can service LanManager
+ clients. These include MSCLIENT 3.0 for DOS, Windows for
+ Workgroups, Windows 95/98/ME, Windows NT, Windows 2000,
+ OS/2, DAVE for Macintosh, and smbfs for Linux.</P
+><P
+>An extensive description of the services that the
+ server can provide is given in the man page for the
+ configuration file controlling the attributes of those
+ services (see <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+></A
+>. This man page will not describe the
+ services, but will concentrate on the administrative aspects
+ of running the server.</P
+><P
+>Please note that there are significant security
+ implications to running this server, and the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+>
+ manpage should be regarded as mandatory reading before
+ proceeding with installation.</P
+><P
+>A session is created whenever a client requests one.
+ Each client gets a copy of the server for each session. This
+ copy then services all connections made by the client during
+ that session. When all connections from its client are closed,
+ the copy of the server for that client terminates.</P
+><P
+>The configuration file, and any files that it includes,
+ are automatically reloaded every minute, if they change. You
+ can force a reload by sending a SIGHUP to the server. Reloading
+ the configuration file will not affect connections to any service
+ that is already established. Either the user will have to
+ disconnect from the service, or <B
+CLASS="COMMAND"
+>smbd</B
+> killed and restarted.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN37"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-D</DT
+><DD
+><P
+>If specified, this parameter causes
+ the server to operate as a daemon. That is, it detaches
+ itself and runs in the background, fielding requests
+ on the appropriate port. Operating the server as a
+ daemon is the recommended way of running <B
+CLASS="COMMAND"
+>smbd</B
+> for
+ servers that provide more than casual use file and
+ print services. This switch is assumed if <B
+CLASS="COMMAND"
+>smbd
+ </B
+> is executed on the command line of a shell.
+ </P
+></DD
+><DT
+>-a</DT
+><DD
+><P
+>If this parameter is specified, each new
+ connection will append log messages to the log file.
+ This is the default.</P
+></DD
+><DT
+>-i</DT
+><DD
+><P
+>If this parameter is specified it causes the
+ server to run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell. Setting this
+ parameter negates the implicit deamon mode when run from the
+ command line.
+ </P
+></DD
+><DT
+>-o</DT
+><DD
+><P
+>If this parameter is specified, the
+ log files will be overwritten when opened. By default,
+ <B
+CLASS="COMMAND"
+>smbd</B
+> will append entries to the log
+ files.</P
+></DD
+><DT
+>-P</DT
+><DD
+><P
+>Passive option. Causes <B
+CLASS="COMMAND"
+>smbd</B
+> not to
+ send any network traffic out. Used for debugging by
+ the developers only.</P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Prints the help information (usage)
+ for <B
+CLASS="COMMAND"
+>smbd</B
+>.</P
+></DD
+><DT
+>-v</DT
+><DD
+><P
+>Prints the version number for
+ <B
+CLASS="COMMAND"
+>smbd</B
+>.</P
+></DD
+><DT
+>-d &#60;debug level&#62;</DT
+><DD
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>debuglevel</I
+></TT
+> is an integer
+ from 0 to 10. The default value if this parameter is
+ not specified is zero.</P
+><P
+>The higher this value, the more detail will be
+ logged to the log files about the activities of the
+ server. At level 0, only critical errors and serious
+ warnings will be logged. Level 1 is a reasonable level for
+ day to day running - it generates a small amount of
+ information about operations carried out.</P
+><P
+>Levels above 1 will generate considerable
+ amounts of log data, and should only be used when
+ investigating a problem. Levels above 3 are designed for
+ use only by developers and generate HUGE amounts of log
+ data, most of which is extremely cryptic.</P
+><P
+>Note that specifying this parameter here will
+ override the <A
+HREF="smb.conf.5.html#loglevel"
+TARGET="_top"
+>log
+ level</A
+> parameter in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+> file.</P
+></DD
+><DT
+>-l &#60;log directory&#62;</DT
+><DD
+><P
+>If specified,
+ <TT
+CLASS="REPLACEABLE"
+><I
+>log directory</I
+></TT
+>
+ specifies a log directory into which the "log.smbd" log
+ file will be created for informational and debug
+ messages from the running server. The log
+ file generated is never removed by the server although
+ its size may be controlled by the <A
+HREF="smb.conf.5.html#maxlogsize"
+TARGET="_top"
+>max log size</A
+>
+ option in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+></A
+> file. <EM
+>Beware:</EM
+>
+ If the directory specified does not exist, <B
+CLASS="COMMAND"
+>smbd</B
+>
+ will log to the default debug log location defined at compile time.
+ </P
+><P
+>The default log directory is specified at
+ compile time.</P
+></DD
+><DT
+>-O &#60;socket options&#62;</DT
+><DD
+><P
+>See the <A
+HREF="smb.conf.5.html#socketoptions"
+TARGET="_top"
+>socket options</A
+>
+ parameter in the <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+></A
+> file for details.</P
+></DD
+><DT
+>-p &#60;port number&#62;</DT
+><DD
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>port number</I
+></TT
+> is a positive integer
+ value. The default value if this parameter is not
+ specified is 139.</P
+><P
+>This number is the port number that will be
+ used when making connections to the server from client
+ software. The standard (well-known) port number for the
+ SMB over TCP is 139, hence the default. If you wish to
+ run the server as an ordinary user rather than
+ as root, most systems will require you to use a port
+ number greater than 1024 - ask your system administrator
+ for help if you are in this situation.</P
+><P
+>In order for the server to be useful by most
+ clients, should you configure it on a port other
+ than 139, you will require port redirection services
+ on port 139, details of which are outlined in rfc1002.txt
+ section 4.3.5.</P
+><P
+>This parameter is not normally specified except
+ in the above situation.</P
+></DD
+><DT
+>-s &#60;configuration file&#62;</DT
+><DD
+><P
+>The file specified contains the
+ configuration details required by the server. The
+ information in this file includes server-specific
+ information such as what printcap file to use, as well
+ as descriptions of all the services that the server is
+ to provide. See <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+></A
+> for more information.
+ The default configuration file name is determined at
+ compile time.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN117"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+></DT
+><DD
+><P
+>If the server is to be run by the
+ <B
+CLASS="COMMAND"
+>inetd</B
+> meta-daemon, this file
+ must contain suitable startup information for the
+ meta-daemon. See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+>
+ document for details.
+ </P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/rc</TT
+></DT
+><DD
+><P
+>or whatever initialization script your
+ system uses).</P
+><P
+>If running the server as a daemon at startup,
+ this file will need to contain an appropriate startup
+ sequence for the server. See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+>
+ document for details.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/services</TT
+></DT
+><DD
+><P
+>If running the server via the
+ meta-daemon <B
+CLASS="COMMAND"
+>inetd</B
+>, this file
+ must contain a mapping of service name (e.g., netbios-ssn)
+ to service port (e.g., 139) and protocol type (e.g., tcp).
+ See the <A
+HREF="UNIX_INSTALL.html"
+TARGET="_top"
+>UNIX_INSTALL.html</A
+>
+ document for details.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/smb.conf</TT
+></DT
+><DD
+><P
+>This is the default location of the
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+>
+ server configuration file. Other common places that systems
+ install this file are <TT
+CLASS="FILENAME"
+>/usr/samba/lib/smb.conf</TT
+>
+ and <TT
+CLASS="FILENAME"
+>/etc/smb.conf</TT
+>.</P
+><P
+>This file describes all the services the server
+ is to make available to clients. See <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+> <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+> for more information.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN153"
+></A
+><H2
+>LIMITATIONS</H2
+><P
+>On some systems <B
+CLASS="COMMAND"
+>smbd</B
+> cannot change uid back
+ to root after a setuid() call. Such systems are called
+ trapdoor uid systems. If you have such a system,
+ you will be unable to connect from a client (such as a PC) as
+ two different users at once. Attempts to connect the
+ second user will result in access denied or
+ similar.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN157"
+></A
+><H2
+>ENVIRONMENT VARIABLES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="ENVAR"
+>PRINTER</TT
+></DT
+><DD
+><P
+>If no printer name is specified to
+ printable services, most systems will use the value of
+ this variable (or <TT
+CLASS="CONSTANT"
+>lp</TT
+> if this variable is
+ not defined) as the name of the printer to use. This
+ is not specific to the server, however.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN166"
+></A
+><H2
+>PAM INTERACTION</H2
+><P
+>Samba uses PAM for authentication (when presented with a plaintext
+ password), for account checking (is this account disabled?) and for
+ session management. The degree too which samba supports PAM is restricted
+ by the limitations of the SMB protocol and the
+ <A
+HREF="smb.conf.5.html#OBEYPAMRESRICTIONS"
+TARGET="_top"
+>obey pam restricions</A
+>
+ smb.conf paramater. When this is set, the following restrictions apply:
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>Account Validation</EM
+>: All acccesses to a
+ samba server are checked
+ against PAM to see if the account is vaild, not disabled and is permitted to
+ login at this time. This also applies to encrypted logins.
+ </P
+></LI
+><LI
+><P
+><EM
+>Session Management</EM
+>: When not using share
+ level secuirty, users must pass PAM's session checks before access
+ is granted. Note however, that this is bypassed in share level secuirty.
+ Note also that some older pam configuration files may need a line
+ added for session support.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN177"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN180"
+></A
+><H2
+>TROUBLESHOOTING</H2
+><P
+> One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </P
+><P
+>Most diagnostics issued by the server are logged
+ in a specified log file. The log file name is specified
+ at compile time, but may be overridden on the command line.</P
+><P
+>The number and nature of diagnostics available depends
+ on the debug level used by the server. If you have problems, set
+ the debug level to 3 and peruse the log files.</P
+><P
+>Most messages are reasonably self-explanatory. Unfortunately,
+ at the time this man page was created, there are too many diagnostics
+ available in the source code to warrant describing each and every
+ diagnostic. At this stage your best bet is still to grep the
+ source code and inspect the conditions that gave rise to the
+ diagnostics you are seeing.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN186"
+></A
+><H2
+>SIGNALS</H2
+><P
+>Sending the <B
+CLASS="COMMAND"
+>smbd</B
+> a SIGHUP will cause it to
+ reload its <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> configuration
+ file within a short period of time.</P
+><P
+>To shut down a user's <B
+CLASS="COMMAND"
+>smbd</B
+> process it is recommended
+ that <B
+CLASS="COMMAND"
+>SIGKILL (-9)</B
+> <EM
+>NOT</EM
+>
+ be used, except as a last resort, as this may leave the shared
+ memory area in an inconsistent state. The safe way to terminate
+ an <B
+CLASS="COMMAND"
+>smbd</B
+> is to send it a SIGTERM (-15) signal and wait for
+ it to die on its own.</P
+><P
+>The debug log level of <B
+CLASS="COMMAND"
+>smbd</B
+> may be raised
+ or lowered using <A
+HREF="smbcontrol.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbcontrol(1)
+ </B
+></A
+> program (SIGUSR[1|2] signals are no longer used in
+ Samba 2.2). This is to allow transient problems to be diagnosed,
+ whilst still running at a normally low log level.</P
+><P
+>Note that as the signal handlers send a debug write,
+ they are not re-entrant in <B
+CLASS="COMMAND"
+>smbd</B
+>. This you should wait until
+ <B
+CLASS="COMMAND"
+>smbd</B
+> is in a state of waiting for an incoming SMB before
+ issuing them. It is possible to make the signal handlers safe
+ by un-blocking the signals before the select call and re-blocking
+ them after, however this would affect performance.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN203"
+></A
+><H2
+>SEE ALSO</H2
+><P
+>hosts_access(5), <B
+CLASS="COMMAND"
+>inetd(8)</B
+>,
+ <A
+HREF="nmbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>nmbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ </A
+>, <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)
+ </B
+></A
+>, <A
+HREF="testparm.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> testparm(1)</B
+></A
+>, <A
+HREF="testprns.1.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>testprns(1)</B
+></A
+>, and the Internet RFC's
+ <TT
+CLASS="FILENAME"
+>rfc1001.txt</TT
+>, <TT
+CLASS="FILENAME"
+>rfc1002.txt</TT
+>.
+ In addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page <A
+HREF="http://samba.org/cifs/"
+TARGET="_top"
+>
+ http://samba.org/cifs/</A
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN220"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbmnt.8.html b/docs/htmldocs/smbmnt.8.html
new file mode 100755
index 00000000000..a7d10b6e191
--- /dev/null
+++ b/docs/htmldocs/smbmnt.8.html
@@ -0,0 +1,178 @@
+<HTML
+><HEAD
+><TITLE
+>smbmnt</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBMNT"
+>smbmnt</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbmnt&nbsp;--&nbsp;helper utility for mounting SMB filesystems</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbmnt</B
+> {mount-point} [-s &#60;share&#62;] [-r] [-u &#60;uid&#62;] [-g &#60;gid&#62;] [-f &#60;mask&#62;] [-d &#60;mask&#62;] [-o &#60;options&#62;]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN19"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><B
+CLASS="COMMAND"
+>smbmnt</B
+> is a helper application used
+ by the smbmount program to do the actual mounting of SMB shares.
+ <B
+CLASS="COMMAND"
+>smbmnt</B
+> can be installed setuid root if you want
+ normal users to be able to mount their SMB shares.</P
+><P
+>A setuid smbmnt will only allow mounts on directories owned
+ by the user, and that the user has write permission on.</P
+><P
+>The <B
+CLASS="COMMAND"
+>smbmnt</B
+> program is normally invoked
+ by <A
+HREF="smbmount.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbmount(8)</B
+>
+ </A
+>. It should not be invoked directly by users. </P
+><P
+>smbmount searches the normal PATH for smbmnt. You must ensure
+ that the smbmnt version in your path matches the smbmount used.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN30"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-r</DT
+><DD
+><P
+>mount the filesystem read-only
+ </P
+></DD
+><DT
+>-u uid</DT
+><DD
+><P
+>specify the uid that the files will
+ be owned by </P
+></DD
+><DT
+>-g gid</DT
+><DD
+><P
+>specify the gid that the files will be
+ owned by </P
+></DD
+><DT
+>-f mask</DT
+><DD
+><P
+>specify the octal file mask applied
+ </P
+></DD
+><DT
+>-d mask</DT
+><DD
+><P
+>specify the octal directory mask
+ applied </P
+></DD
+><DT
+>-o options</DT
+><DD
+><P
+> list of options that are passed as-is to smbfs, if this
+ command is run on a 2.4 or higher Linux kernel.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>AUTHOR</H2
+><P
+>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</P
+><P
+>The current maintainer of smbfs and the userspace
+ tools <B
+CLASS="COMMAND"
+>smbmount</B
+>, <B
+CLASS="COMMAND"
+>smbumount</B
+>,
+ and <B
+CLASS="COMMAND"
+>smbmnt</B
+> is <A
+HREF="mailto:urban@teststation.com"
+TARGET="_top"
+>Urban Widmark</A
+>.
+ The <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+>SAMBA Mailing list</A
+>
+ is the preferred place to ask questions regarding these programs.
+ </P
+><P
+>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbmount.8.html b/docs/htmldocs/smbmount.8.html
new file mode 100755
index 00000000000..9d620f1397f
--- /dev/null
+++ b/docs/htmldocs/smbmount.8.html
@@ -0,0 +1,468 @@
+<HTML
+><HEAD
+><TITLE
+>smbmount</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBMOUNT"
+>smbmount</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbmount&nbsp;--&nbsp;mount an smbfs filesystem</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbmount</B
+> {service} {mount-point} [-o options]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN14"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><B
+CLASS="COMMAND"
+>smbmount</B
+> mounts a Linux SMB filesystem. It
+ is usually invoked as <B
+CLASS="COMMAND"
+>mount.smbfs</B
+> by
+ the <B
+CLASS="COMMAND"
+>mount(8)</B
+> command when using the
+ "-t smbfs" option. This command only works in Linux, and the kernel must
+ support the smbfs filesystem. </P
+><P
+>Options to <B
+CLASS="COMMAND"
+>smbmount</B
+> are specified as a comma-separated
+ list of key=value pairs. It is possible to send options other
+ than those listed here, assuming that smbfs supports them. If
+ you get mount failures, check your kernel log for errors on
+ unknown options.</P
+><P
+><B
+CLASS="COMMAND"
+>smbmount</B
+> is a daemon. After mounting it keeps running until
+ the mounted smbfs is umounted. It will log things that happen
+ when in daemon mode using the "machine name" smbmount, so
+ typically this output will end up in <TT
+CLASS="FILENAME"
+>log.smbmount</TT
+>. The
+ <B
+CLASS="COMMAND"
+>smbmount</B
+> process may also be called mount.smbfs.</P
+><P
+><EM
+>NOTE:</EM
+> <B
+CLASS="COMMAND"
+>smbmount</B
+>
+ calls <B
+CLASS="COMMAND"
+>smbmnt(8)</B
+> to do the actual mount. You
+ must make sure that <B
+CLASS="COMMAND"
+>smbmnt</B
+> is in the path so
+ that it can be found. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN31"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>username=&#60;arg&#62;</DT
+><DD
+><P
+>specifies the username to connect as. If
+ this is not given, then the environment variable <TT
+CLASS="ENVAR"
+> USER</TT
+> is used. This option can also take the
+ form "user%password" or "user/workgroup" or
+ "user/workgroup%password" to allow the password and workgroup
+ to be specified as part of the username.</P
+></DD
+><DT
+>password=&#60;arg&#62;</DT
+><DD
+><P
+>specifies the SMB password. If this
+ option is not given then the environment variable
+ <TT
+CLASS="ENVAR"
+>PASSWD</TT
+> is used. If it can find
+ no password <B
+CLASS="COMMAND"
+>smbmount</B
+> will prompt
+ for a passeword, unless the guest option is
+ given. </P
+><P
+> Note that password which contain the arguement delimiter
+ character (i.e. a comma ',') will failed to be parsed correctly
+ on the command line. However, the same password defined
+ in the PASSWD environment variable or a credentials file (see
+ below) will be read correctly.
+ </P
+></DD
+><DT
+>credentials=&#60;filename&#62;</DT
+><DD
+><P
+>specifies a file that contains a username
+ and/or password. The format of the file is:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> username = &#60;value&#62;
+ password = &#60;value&#62;
+ </PRE
+></TD
+></TR
+></TABLE
+>
+ </P
+><P
+>This is preferred over having passwords in plaintext in a
+ shared file, such as <TT
+CLASS="FILENAME"
+>/etc/fstab</TT
+>. Be sure to protect any
+ credentials file properly.
+ </P
+></DD
+><DT
+>netbiosname=&#60;arg&#62;</DT
+><DD
+><P
+>sets the source NetBIOS name. It defaults
+ to the local hostname. </P
+></DD
+><DT
+>uid=&#60;arg&#62;</DT
+><DD
+><P
+>sets the uid that will own all files on
+ the mounted filesystem.
+ It may be specified as either a username or a numeric uid.
+ </P
+></DD
+><DT
+>gid=&#60;arg&#62;</DT
+><DD
+><P
+>sets the gid that will own all files on
+ the mounted filesystem.
+ It may be specified as either a groupname or a numeric
+ gid. </P
+></DD
+><DT
+>port=&#60;arg&#62;</DT
+><DD
+><P
+>sets the remote SMB port number. The default
+ is 139. </P
+></DD
+><DT
+>fmask=&#60;arg&#62;</DT
+><DD
+><P
+>sets the file mask. This determines the
+ permissions that remote files have in the local filesystem.
+ The default is based on the current umask. </P
+></DD
+><DT
+>dmask=&#60;arg&#62;</DT
+><DD
+><P
+>sets the directory mask. This determines the
+ permissions that remote directories have in the local filesystem.
+ The default is based on the current umask. </P
+></DD
+><DT
+>debug=&#60;arg&#62;</DT
+><DD
+><P
+>sets the debug level. This is useful for
+ tracking down SMB connection problems. A suggested value to
+ start with is 4. If set too high there will be a lot of
+ output, possibly hiding the useful output.</P
+></DD
+><DT
+>ip=&#60;arg&#62;</DT
+><DD
+><P
+>sets the destination host or IP address.
+ </P
+></DD
+><DT
+>workgroup=&#60;arg&#62;</DT
+><DD
+><P
+>sets the workgroup on the destination </P
+></DD
+><DT
+>sockopt=&#60;arg&#62;</DT
+><DD
+><P
+>sets the TCP socket options. See the <A
+HREF="smb.conf.5.html#SOCKETOPTIONS"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf
+ </TT
+></A
+> <TT
+CLASS="PARAMETER"
+><I
+>socket options</I
+></TT
+> option.
+ </P
+></DD
+><DT
+>scope=&#60;arg&#62;</DT
+><DD
+><P
+>sets the NetBIOS scope </P
+></DD
+><DT
+>guest</DT
+><DD
+><P
+>don't prompt for a password </P
+></DD
+><DT
+>ro</DT
+><DD
+><P
+>mount read-only </P
+></DD
+><DT
+>rw</DT
+><DD
+><P
+>mount read-write </P
+></DD
+><DT
+>iocharset=&#60;arg&#62;</DT
+><DD
+><P
+> sets the charset used by the Linux side for codepage
+ to charset translations (NLS). Argument should be the
+ name of a charset, like iso8859-1. (Note: only kernel
+ 2.4.0 or later)
+ </P
+></DD
+><DT
+>codepage=&#60;arg&#62;</DT
+><DD
+><P
+> sets the codepage the server uses. See the iocharset
+ option. Example value cp850. (Note: only kernel 2.4.0
+ or later)
+ </P
+></DD
+><DT
+>ttl=&#60;arg&#62;</DT
+><DD
+><P
+> how long a directory listing is cached in milliseconds
+ (also affects visibility of file size and date
+ changes). A higher value means that changes on the
+ server take longer to be noticed but it can give
+ better performance on large directories, especially
+ over long distances. Default is 1000ms but something
+ like 10000ms (10 seconds) is probably more reasonable
+ in many cases.
+ (Note: only kernel 2.4.2 or later)
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN125"
+></A
+><H2
+>ENVIRONMENT VARIABLES</H2
+><P
+>The variable <TT
+CLASS="ENVAR"
+>USER</TT
+> may contain the username of the
+ person using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords. The variable can be used to set both username and
+ password by using the format username%password.</P
+><P
+>The variable <TT
+CLASS="ENVAR"
+>PASSWD</TT
+> may contain the password of the
+ person using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords.</P
+><P
+>The variable <TT
+CLASS="ENVAR"
+>PASSWD_FILE</TT
+> may contain the pathname
+ of a file to read the password from. A single line of input is
+ read and used as the password.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN133"
+></A
+><H2
+>BUGS</H2
+><P
+>Passwords and other options containing , can not be handled.
+ For passwords an alternative way of passing them is in a credentials
+ file or in the PASSWD environment.</P
+><P
+>The credentials file does not handle usernames or passwords with
+ leading space.</P
+><P
+>One smbfs bug is important enough to mention here, even if it
+ is a bit misplaced:</P
+><P
+></P
+><UL
+><LI
+><P
+>Mounts sometimes stop working. This is usually
+ caused by smbmount terminating. Since smbfs needs smbmount to
+ reconnect when the server disconnects, the mount will eventually go
+ dead. An umount/mount normally fixes this. At least 2 ways to
+ trigger this bug are known.</P
+></LI
+></UL
+><P
+>Note that the typical response to a bug report is suggestion
+ to try the latest version first. So please try doing that first,
+ and always include which versions you use of relevant software
+ when reporting bugs (minimum: samba, kernel, distribution)</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN142"
+></A
+><H2
+>SEE ALSO</H2
+><P
+>Documentation/filesystems/smbfs.txt in the linux kernel
+ source tree may contain additional options and information.</P
+><P
+>FreeBSD also has a smbfs, but it is not related to smbmount</P
+><P
+>For Solaris, HP-UX and others you may want to look at
+ <A
+HREF="smbsh.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbsh(1)</B
+></A
+> or at other
+ solutions, such as sharity or perhaps replacing the SMB server with
+ a NFS server.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN149"
+></A
+><H2
+>AUTHOR</H2
+><P
+>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</P
+><P
+>The current maintainer of smbfs and the userspace
+ tools <B
+CLASS="COMMAND"
+>smbmount</B
+>, <B
+CLASS="COMMAND"
+>smbumount</B
+>,
+ and <B
+CLASS="COMMAND"
+>smbmnt</B
+> is <A
+HREF="mailto:urban@teststation.com"
+TARGET="_top"
+>Urban Widmark</A
+>.
+ The <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+>SAMBA Mailing list</A
+>
+ is the preferred place to ask questions regarding these programs.
+ </P
+><P
+>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbpasswd.5.html b/docs/htmldocs/smbpasswd.5.html
new file mode 100755
index 00000000000..229350542e6
--- /dev/null
+++ b/docs/htmldocs/smbpasswd.5.html
@@ -0,0 +1,316 @@
+<HTML
+><HEAD
+><TITLE
+>smbpasswd</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBPASSWD"
+>smbpasswd</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbpasswd&nbsp;--&nbsp;The Samba encrypted password file</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><TT
+CLASS="FILENAME"
+>smbpasswd</TT
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN11"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>smbpasswd is the Samba encrypted password file. It contains
+ the username, Unix user id and the SMB hashed passwords of the
+ user, as well as account flag information and the time the
+ password was last changed. This file format has been evolving with
+ Samba and has had several different formats in the past. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN16"
+></A
+><H2
+>FILE FORMAT</H2
+><P
+>The format of the smbpasswd file used by Samba 2.2
+ is very similar to the familiar Unix <TT
+CLASS="FILENAME"
+>passwd(5)</TT
+>
+ file. It is an ASCII file containing one line for each user. Each field
+ within each line is separated from the next by a colon. Any entry
+ beginning with '#' is ignored. The smbpasswd file contains the
+ following information for each user: </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>name</DT
+><DD
+><P
+> This is the user name. It must be a name that
+ already exists in the standard UNIX passwd file. </P
+></DD
+><DT
+>uid</DT
+><DD
+><P
+>This is the UNIX uid. It must match the uid
+ field for the same user entry in the standard UNIX passwd file.
+ If this does not match then Samba will refuse to recognize
+ this smbpasswd file entry as being valid for a user.
+ </P
+></DD
+><DT
+>Lanman Password Hash</DT
+><DD
+><P
+>This is the LANMAN hash of the user's password,
+ encoded as 32 hex digits. The LANMAN hash is created by DES
+ encrypting a well known string with the user's password as the
+ DES key. This is the same password used by Windows 95/98 machines.
+ Note that this password hash is regarded as weak as it is
+ vulnerable to dictionary attacks and if two users choose the
+ same password this entry will be identical (i.e. the password
+ is not "salted" as the UNIX password is). If the user has a
+ null password this field will contain the characters "NO PASSWORD"
+ as the start of the hex string. If the hex string is equal to
+ 32 'X' characters then the user's account is marked as
+ <TT
+CLASS="CONSTANT"
+>disabled</TT
+> and the user will not be able to
+ log onto the Samba server. </P
+><P
+><EM
+>WARNING !!</EM
+> Note that, due to
+ the challenge-response nature of the SMB/CIFS authentication
+ protocol, anyone with a knowledge of this password hash will
+ be able to impersonate the user on the network. For this
+ reason these hashes are known as <EM
+>plain text
+ equivalents</EM
+> and must <EM
+>NOT</EM
+> be made
+ available to anyone but the root user. To protect these passwords
+ the smbpasswd file is placed in a directory with read and
+ traverse access only to the root user and the smbpasswd file
+ itself must be set to be read/write only by root, with no
+ other access. </P
+></DD
+><DT
+>NT Password Hash</DT
+><DD
+><P
+>This is the Windows NT hash of the user's
+ password, encoded as 32 hex digits. The Windows NT hash is
+ created by taking the user's password as represented in
+ 16-bit, little-endian UNICODE and then applying the MD4
+ (internet rfc1321) hashing algorithm to it. </P
+><P
+>This password hash is considered more secure than
+ the LANMAN Password Hash as it preserves the case of the
+ password and uses a much higher quality hashing algorithm.
+ However, it is still the case that if two users choose the same
+ password this entry will be identical (i.e. the password is
+ not "salted" as the UNIX password is). </P
+><P
+><EM
+>WARNING !!</EM
+>. Note that, due to
+ the challenge-response nature of the SMB/CIFS authentication
+ protocol, anyone with a knowledge of this password hash will
+ be able to impersonate the user on the network. For this
+ reason these hashes are known as <EM
+>plain text
+ equivalents</EM
+> and must <EM
+>NOT</EM
+> be made
+ available to anyone but the root user. To protect these passwords
+ the smbpasswd file is placed in a directory with read and
+ traverse access only to the root user and the smbpasswd file
+ itself must be set to be read/write only by root, with no
+ other access. </P
+></DD
+><DT
+>Account Flags</DT
+><DD
+><P
+>This section contains flags that describe
+ the attributes of the users account. In the Samba 2.2 release
+ this field is bracketed by '[' and ']' characters and is always
+ 13 characters in length (including the '[' and ']' characters).
+ The contents of this field may be any of the characters.
+ </P
+><P
+></P
+><UL
+><LI
+><P
+><EM
+>U</EM
+> - This means
+ this is a "User" account, i.e. an ordinary user. Only User
+ and Workstation Trust accounts are currently supported
+ in the smbpasswd file. </P
+></LI
+><LI
+><P
+><EM
+>N</EM
+> - This means the
+ account has no password (the passwords in the fields LANMAN
+ Password Hash and NT Password Hash are ignored). Note that this
+ will only allow users to log on with no password if the <TT
+CLASS="PARAMETER"
+><I
+> null passwords</I
+></TT
+> parameter is set in the <A
+HREF="smb.conf.5.html#NULLPASSWORDS"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+></A
+> config file. </P
+></LI
+><LI
+><P
+><EM
+>D</EM
+> - This means the account
+ is disabled and no SMB/CIFS logins will be allowed for
+ this user. </P
+></LI
+><LI
+><P
+><EM
+>W</EM
+> - This means this account
+ is a "Workstation Trust" account. This kind of account is used
+ in the Samba PDC code stream to allow Windows NT Workstations
+ and Servers to join a Domain hosted by a Samba PDC. </P
+></LI
+></UL
+><P
+>Other flags may be added as the code is extended in future.
+ The rest of this field space is filled in with spaces. </P
+></DD
+><DT
+>Last Change Time</DT
+><DD
+><P
+>This field consists of the time the account was
+ last modified. It consists of the characters 'LCT-' (standing for
+ "Last Change Time") followed by a numeric encoding of the UNIX time
+ in seconds since the epoch (1970) that the last change was made.
+ </P
+></DD
+></DL
+></DIV
+><P
+>All other colon separated fields are ignored at this time.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN73"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN76"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbpasswd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbpasswd(8)</B
+></A
+>,
+ <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>, and
+ the Internet RFC1321 for details on the MD4 algorithm.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN82"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbpasswd.8.html b/docs/htmldocs/smbpasswd.8.html
new file mode 100755
index 00000000000..0fb0b86b289
--- /dev/null
+++ b/docs/htmldocs/smbpasswd.8.html
@@ -0,0 +1,831 @@
+<HTML
+><HEAD
+><TITLE
+>smbpasswd</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBPASSWD"
+>smbpasswd</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbpasswd&nbsp;--&nbsp;change a user's SMB password</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+>When run by root:</P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> [options] [username] [password]</P
+><P
+>otherwise:</P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> [options] [password]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN20"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>The smbpasswd program has several different
+ functions, depending on whether it is run by the <EM
+>root</EM
+>
+ user or not. When run as a normal user it allows the user to change
+ the password used for their SMB sessions on any machines that store
+ SMB passwords. </P
+><P
+>By default (when run with no arguments) it will attempt to
+ change the current user's SMB password on the local machine. This is
+ similar to the way the <B
+CLASS="COMMAND"
+>passwd(1)</B
+> program works.
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+> differs from how the passwd program works
+ however in that it is not <EM
+>setuid root</EM
+> but works in
+ a client-server mode and communicates with a locally running
+ <B
+CLASS="COMMAND"
+>smbd(8)</B
+>. As a consequence in order for this to
+ succeed the smbd daemon must be running on the local machine. On a
+ UNIX machine the encrypted SMB passwords are usually stored in
+ the <TT
+CLASS="FILENAME"
+>smbpasswd(5)</TT
+> file. </P
+><P
+>When run by an ordinary user with no options. smbpasswd
+ will prompt them for their old SMB password and then ask them
+ for their new password twice, to ensure that the new password
+ was typed correctly. No passwords will be echoed on the screen
+ whilst being typed. If you have a blank SMB password (specified by
+ the string "NO PASSWORD" in the smbpasswd file) then just press
+ the &#60;Enter&#62; key when asked for your old password. </P
+><P
+>smbpasswd can also be used by a normal user to change their
+ SMB password on remote machines, such as Windows NT Primary Domain
+ Controllers. See the (-r) and -U options below. </P
+><P
+>When run by root, smbpasswd allows new users to be added
+ and deleted in the smbpasswd file, as well as allows changes to
+ the attributes of the user in this file to be made. When run by root,
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+> accesses the local smbpasswd file
+ directly, thus enabling changes to be made even if smbd is not
+ running. </P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd</B
+> can also be used to retrieve
+ the SIDs related to previous incarnations of this server on the
+ same machine, as well as set the SID of this domain. This is needed
+ in those cases when the admin changes the NetBIOS or DNS name of
+ the server without realizing that doing so will change the SID of
+ the server as well. See the -W and -X options below. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN38"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-L</DT
+><DD
+><P
+>Run the smbpasswd command in local mode. This
+ allows a non-root user to specify the root-only options. This
+ is used mostly in test environments where a non-root user needs
+ to make changes to the local <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file.
+ The <TT
+CLASS="FILENAME"
+>smbpasswd</TT
+> file must have read/write
+ permissions for the user running the command.</P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>This option prints the help string for
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+>. </P
+></DD
+><DT
+>-c smb.conf file</DT
+><DD
+><P
+>This option specifies that the configuration
+ file specified should be used instead of the default value
+ specified at compile time. </P
+></DD
+><DT
+>-D debuglevel</DT
+><DD
+><P
+><TT
+CLASS="REPLACEABLE"
+><I
+>debuglevel</I
+></TT
+> is an integer
+ from 0 to 10. The default value if this parameter is not specified
+ is zero. </P
+><P
+>The higher this value, the more detail will be logged to the
+ log files about the activities of smbpasswd. At level 0, only
+ critical errors and serious warnings will be logged. </P
+><P
+>Levels above 1 will generate considerable amounts of log
+ data, and should only be used when investigating a problem. Levels
+ above 3 are designed for use only by developers and generate
+ HUGE amounts of log data, most of which is extremely cryptic.
+ </P
+></DD
+><DT
+>-r remote machine name</DT
+><DD
+><P
+>This option allows a user to specify what machine
+ they wish to change their password on. Without this parameter
+ smbpasswd defaults to the local host. The <TT
+CLASS="REPLACEABLE"
+><I
+>remote
+ machine name</I
+></TT
+> is the NetBIOS name of the SMB/CIFS
+ server to contact to attempt the password change. This name is
+ resolved into an IP address using the standard name resolution
+ mechanism in all programs of the Samba suite. See the <TT
+CLASS="PARAMETER"
+><I
+>-R
+ name resolve order</I
+></TT
+> parameter for details on changing
+ this resolving mechanism. </P
+><P
+>The username whose password is changed is that of the
+ current UNIX logged on user. See the <TT
+CLASS="PARAMETER"
+><I
+>-U username</I
+></TT
+>
+ parameter for details on changing the password for a different
+ username. </P
+><P
+>Note that if changing a Windows NT Domain password the
+ remote machine specified must be the Primary Domain Controller for
+ the domain (Backup Domain Controllers only have a read-only
+ copy of the user account database and will not allow the password
+ change).</P
+><P
+><EM
+>Note</EM
+> that Windows 95/98 do not have
+ a real password database so it is not possible to change passwords
+ specifying a Win95/98 machine as remote machine target. </P
+></DD
+><DT
+>-s</DT
+><DD
+><P
+>This option causes smbpasswd to be silent (i.e.
+ not issue prompts) and to read its old and new passwords from
+ standard input, rather than from <TT
+CLASS="FILENAME"
+>/dev/tty</TT
+>
+ (like the <B
+CLASS="COMMAND"
+>passwd(1)</B
+> program does). This option
+ is to aid people writing scripts to drive smbpasswd</P
+></DD
+><DT
+>-S</DT
+><DD
+><P
+>This option causes <B
+CLASS="COMMAND"
+>smbpasswd</B
+>
+ to query a domain controller of the domain specified
+ by the <A
+HREF="smb.conf.5.html#WORKGROUP"
+TARGET="_top"
+>workgroup</A
+>
+ parameter in <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> and store the
+ domain SID in the <TT
+CLASS="FILENAME"
+>secrets.tdb</TT
+> file
+ as its own machine SID. This is only useful when configuring
+ a Samba PDC and Samba BDC, or when migrating from a Windows PDC
+ to a Samba PDC. </P
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>-r</I
+></TT
+> options can be used
+ as well to indicate a specific domain controller which should
+ be contacted. In this case, the domain SID obtained is the
+ one for the domain to which the remote machine belongs.
+ </P
+></DD
+><DT
+>-t</DT
+><DD
+><P
+>This option is used to force smbpasswd to
+ change the current password assigned to the machine trust account
+ when operating in domain security mode. This is really meant to
+ be used on systems that only run <A
+HREF="winbindd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>winbindd</B
+></A
+>.
+ Under server installations, <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd</B
+></A
+>
+ handle the password updates automatically.</P
+></DD
+><DT
+>-T</DT
+><DD
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>-T</I
+></TT
+> option may be used to
+ force samba to use a previously created trust account by allowing
+ the trust account hash to be set in the secrets database only.
+ This way, an application can change the trust account password
+ and call "smbpasswd -T" so that Samba can continue to work.</P
+></DD
+><DT
+>-U username[%pass]</DT
+><DD
+><P
+>This option may only be used in conjunction
+ with the <TT
+CLASS="PARAMETER"
+><I
+>-r</I
+></TT
+> option. When changing
+ a password on a remote machine it allows the user to specify
+ the user name on that machine whose password will be changed. It
+ is present to allow users who have different user names on
+ different systems to change these passwords. The optional
+ %pass may be used to specify to old password.</P
+><P
+>In particular, this parameter specifies the username
+ used to create the machine account when invoked with -j</P
+></DD
+><DT
+>-W S-1-5-21-x-y-z</DT
+><DD
+><P
+>This option forces the SID S-1-5-21-x-y-z to
+ be the server and domain SID for the current Samba server. It
+ does this by updating the appropriate keys in the secrets
+ file. </P
+></DD
+><DT
+>-X server|domain</DT
+><DD
+><P
+>This option allows the admin to retrieve the
+ SID associated with a former servername or domain name that
+ this Samba server might have used. It does this by retrieving
+ the appropriate entry from the secrets file.</P
+></DD
+><DT
+><B
+CLASS="COMMAND"
+>NOTE:</B
+></DT
+><DD
+><P
+><B
+CLASS="COMMAND"
+>The following options are available only when the smbpasswd command is
+run as root or in local mode.</B
+></P
+></DD
+><DT
+>-a</DT
+><DD
+><P
+>This option specifies that the username
+ following should be added to the local smbpasswd file, with the
+ new password typed. This
+ option is ignored if the username specified already exists in
+ the smbpasswd file and it is treated like a regular change
+ password command. Note that the user to be added must already exist
+ in the system password file (usually <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>)
+ else the request to add the user will fail. </P
+></DD
+><DT
+>-d</DT
+><DD
+><P
+>This option specifies that the username following
+ should be <TT
+CLASS="CONSTANT"
+>disabled</TT
+> in the local smbpasswd
+ file. This is done by writing a <TT
+CLASS="CONSTANT"
+>'D'</TT
+> flag
+ into the account control space in the smbpasswd file. Once this
+ is done all attempts to authenticate via SMB using this username
+ will fail. </P
+><P
+>If the smbpasswd file is in the 'old' format (pre-Samba 2.0
+ format) there is no space in the user's password entry to write
+ this information and so the user is disabled by writing 'X' characters
+ into the password space in the smbpasswd file. See <B
+CLASS="COMMAND"
+>smbpasswd(5)
+ </B
+> for details on the 'old' and new password file formats.
+ </P
+></DD
+><DT
+>-e</DT
+><DD
+><P
+>This option specifies that the username following
+ should be <TT
+CLASS="CONSTANT"
+>enabled</TT
+> in the local smbpasswd file,
+ if the account was previously disabled. If the account was not
+ disabled this option has no effect. Once the account is enabled then
+ the user will be able to authenticate via SMB once again. </P
+><P
+>If the smbpasswd file is in the 'old' format, then <B
+CLASS="COMMAND"
+> smbpasswd</B
+> will prompt for a new password for this user,
+ otherwise the account will be enabled by removing the <TT
+CLASS="CONSTANT"
+>'D'
+ </TT
+> flag from account control space in the <TT
+CLASS="FILENAME"
+> smbpasswd</TT
+> file. See <B
+CLASS="COMMAND"
+>smbpasswd (5)</B
+> for
+ details on the 'old' and new password file formats. </P
+></DD
+><DT
+>-m</DT
+><DD
+><P
+>This option tells smbpasswd that the account
+ being changed is a MACHINE account. Currently this is used
+ when Samba is being used as an NT Primary Domain Controller.</P
+></DD
+><DT
+>-n</DT
+><DD
+><P
+>This option specifies that the username following
+ should have their password set to null (i.e. a blank password) in
+ the local smbpasswd file. This is done by writing the string "NO
+ PASSWORD" as the first part of the first password stored in the
+ smbpasswd file. </P
+><P
+>Note that to allow users to logon to a Samba server once
+ the password has been set to "NO PASSWORD" in the smbpasswd
+ file the administrator must set the following parameter in the [global]
+ section of the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file : </P
+><P
+><B
+CLASS="COMMAND"
+>null passwords = yes</B
+></P
+></DD
+><DT
+>-w password</DT
+><DD
+><P
+>This parameter is only available is Samba
+ has been configured to use the experimental
+ <B
+CLASS="COMMAND"
+>--with-ldapsam</B
+> option. The <TT
+CLASS="PARAMETER"
+><I
+>-w</I
+></TT
+>
+ switch is used to specify the password to be used with the
+ <A
+HREF="smb.conf.5.html#LDAPADMINDN"
+TARGET="_top"
+><TT
+CLASS="PARAMETER"
+><I
+>ldap admin
+ dn</I
+></TT
+></A
+>. Note that the password is stored in
+ the <TT
+CLASS="FILENAME"
+>private/secrets.tdb</TT
+> and is keyed off
+ of the admin's DN. This means that if the value of <TT
+CLASS="PARAMETER"
+><I
+>ldap
+ admin dn</I
+></TT
+> ever changes, the password will need to be
+ manually updated as well.
+ </P
+></DD
+><DT
+>-x</DT
+><DD
+><P
+>This option specifies that the username
+ following should be deleted from the local smbpasswd file.
+ </P
+></DD
+><DT
+>-j DOMAIN</DT
+><DD
+><P
+>This option is used to add a Samba server
+ into a Windows NT Domain, as a Domain member capable of authenticating
+ user accounts to any Domain Controller in the same way as a Windows
+ NT Server. See the <B
+CLASS="COMMAND"
+>security = domain</B
+> option in
+ the <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+> man page. </P
+><P
+>This command can work both with and without the -U parameter. </P
+><P
+>When invoked with -U, that username (and optional password) are
+ used to contact the PDC (which must be specified with -r) to both
+ create a machine account, and to set a password on it.</P
+><P
+>Alternately, if -U is omitted, Samba will contact its PDC
+ and attempt to change the password on a pre-existing account. </P
+><P
+>In order to be used in this way, the Administrator for
+ the Windows NT Domain must have used the program "Server Manager
+ for Domains" to add the primary NetBIOS name of the Samba server
+ as a member of the Domain. </P
+><P
+>After this has been done, to join the Domain invoke <B
+CLASS="COMMAND"
+> smbpasswd</B
+> with this parameter. smbpasswd will then
+ look up the Primary Domain Controller for the Domain (found in
+ the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file in the parameter
+ <TT
+CLASS="PARAMETER"
+><I
+>password server</I
+></TT
+> and change the machine account
+ password used to create the secure Domain communication. </P
+><P
+>Either way, this password is then stored by smbpasswd in a TDB,
+ writeable only by root, called <TT
+CLASS="FILENAME"
+>secrets.tdb</TT
+> </P
+><P
+>Once this operation has been performed the <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> file may be updated to set the <B
+CLASS="COMMAND"
+> security = domain</B
+> option and all future logins
+ to the Samba server will be authenticated to the Windows NT
+ PDC. </P
+><P
+>Note that even though the authentication is being
+ done to the PDC all users accessing the Samba server must still
+ have a valid UNIX account on that machine.
+ The <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> daemon can be used
+ to create UNIX accounts for NT users.</P
+></DD
+><DT
+>-R name resolve order</DT
+><DD
+><P
+>This option allows the user of smbpasswd to determine
+ what name resolution services to use when looking up the NetBIOS
+ name of the host being connected to. </P
+><P
+>The options are :"lmhosts", "host", "wins" and "bcast". They cause
+ names to be resolved as follows : </P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmhosts</TT
+> : Lookup an IP
+ address in the Samba lmhosts file. If the line in lmhosts has
+ no name type attached to the NetBIOS name (see the <A
+HREF="lmhosts.5.html"
+TARGET="_top"
+>lmhosts(5)</A
+> for details) then
+ any name type matches for lookup.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>host</TT
+> : Do a standard host
+ name to IP address resolution, using the system <TT
+CLASS="FILENAME"
+>/etc/hosts
+ </TT
+>, NIS, or DNS lookups. This method of name resolution
+ is operating system dependent. For instance, on IRIX or Solaris this
+ may be controlled by the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>
+ file). Note that this method is only used if the NetBIOS name
+ type being queried is the 0x20 (server) name type, otherwise
+ it is ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>wins</TT
+> : Query a name with
+ the IP address listed in the <TT
+CLASS="PARAMETER"
+><I
+>wins server</I
+></TT
+>
+ parameter. If no WINS server has been specified this method
+ will be ignored.</P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>bcast</TT
+> : Do a broadcast on
+ each of the known local interfaces listed in the
+ <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+> parameter. This is the least
+ reliable of the name resolution methods as it depends on the
+ target host being on a locally connected subnet.</P
+></LI
+></UL
+><P
+>The default order is <B
+CLASS="COMMAND"
+>lmhosts, host, wins, bcast</B
+>
+ and without this parameter or any entry in the
+ <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file the name resolution methods will
+ be attempted in this order. </P
+></DD
+><DT
+>username</DT
+><DD
+><P
+>This specifies the username for all of the
+ <EM
+>root only</EM
+> options to operate on. Only root
+ can specify this parameter as only root has the permission needed
+ to modify attributes directly in the local smbpasswd file.
+ </P
+></DD
+><DT
+>password</DT
+><DD
+><P
+>This specifies the new password. If this parameter
+ is specified you will not be prompted for the new password.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN228"
+></A
+><H2
+>NOTES</H2
+><P
+>Since <B
+CLASS="COMMAND"
+>smbpasswd</B
+> works in client-server
+ mode communicating with a local smbd for a non-root user then
+ the smbd daemon must be running for this to work. A common problem
+ is to add a restriction to the hosts that may access the <B
+CLASS="COMMAND"
+> smbd</B
+> running on the local machine by specifying a
+ <TT
+CLASS="PARAMETER"
+><I
+>allow hosts</I
+></TT
+> or <TT
+CLASS="PARAMETER"
+><I
+>deny hosts</I
+></TT
+>
+ entry in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file and neglecting to
+ allow "localhost" access to the smbd. </P
+><P
+>In addition, the smbpasswd command is only useful if Samba
+ has been set up to use encrypted passwords. See the file
+ <TT
+CLASS="FILENAME"
+>ENCRYPTION.txt</TT
+> in the docs directory for details
+ on how to do this. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN238"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN241"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbpasswd.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smbpasswd(5)</TT
+></A
+>,
+ <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN247"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbsh.1.html b/docs/htmldocs/smbsh.1.html
new file mode 100755
index 00000000000..ba2cc7b4928
--- /dev/null
+++ b/docs/htmldocs/smbsh.1.html
@@ -0,0 +1,468 @@
+<HTML
+><HEAD
+><TITLE
+>smbsh</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBSH"
+>smbsh</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbsh&nbsp;--&nbsp;Allows access to Windows NT filesystem
+ using UNIX commands</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbsh</B
+> [-W workgroup] [-U username] [-P prefix] [-R &#60;name resolve order&#62;] [-d &#60;debug level&#62;] [-l logfile] [-L libdir]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN18"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbsh</B
+> allows you to access an NT filesystem
+ using UNIX commands such as <B
+CLASS="COMMAND"
+>ls</B
+>, <B
+CLASS="COMMAND"
+> egrep</B
+>, and <B
+CLASS="COMMAND"
+>rcp</B
+>. You must use a
+ shell that is dynamically linked in order for <B
+CLASS="COMMAND"
+>smbsh</B
+>
+ to work correctly.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN28"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-W WORKGROUP</DT
+><DD
+><P
+>Override the default workgroup specified in the
+ workgroup parameter of the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file
+ for this session. This may be needed to connect to some
+ servers. </P
+></DD
+><DT
+>-U username[%pass]</DT
+><DD
+><P
+>Sets the SMB username or username and password.
+ If this option is not specified, the user will be prompted for
+ both the username and the password. If %pass is not specified,
+ the user will be prompted for the password.
+ </P
+></DD
+><DT
+>-P prefix</DT
+><DD
+><P
+>This option allows
+ the user to set the directory prefix for SMB access. The
+ default value if this option is not specified is
+ <EM
+>smb</EM
+>.
+ </P
+></DD
+><DT
+>-R &#60;name resolve order&#62;</DT
+><DD
+><P
+>This option is used to determine what naming
+ services and in what order to resolve
+ host names to IP addresses. The option takes a space-separated
+ string of different name resolution options.</P
+><P
+>The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :</P
+><P
+></P
+><UL
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>lmhosts</TT
+> :
+ Lookup an IP address in the Samba lmhosts file. If the
+ line in lmhosts has no name type attached to the
+ NetBIOS name
+ (see the <A
+HREF="lmhosts.5.html"
+TARGET="_top"
+>lmhosts(5)</A
+>
+ for details) then any name type matches for lookup.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>host</TT
+> :
+ Do a standard host name to IP address resolution, using
+ the system <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>, NIS, or DNS
+ lookups. This method of name resolution is operating
+ system dependent, for instance on IRIX or Solaris this
+ may be controlled by the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf
+ </TT
+> file). Note that this method is only used
+ if the NetBIOS name type being queried is the 0x20
+ (server) name type, otherwise it is ignored.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>wins</TT
+> :
+ Query a name with the IP address listed in the
+ <TT
+CLASS="PARAMETER"
+><I
+>wins server</I
+></TT
+> parameter. If no
+ WINS server has been specified this method will be
+ ignored.
+ </P
+></LI
+><LI
+><P
+><TT
+CLASS="CONSTANT"
+>bcast</TT
+> :
+ Do a broadcast on each of the known local interfaces
+ listed in the <TT
+CLASS="PARAMETER"
+><I
+>interfaces</I
+></TT
+>
+ parameter. This is the least reliable of the name
+ resolution methods as it depends on the target host
+ being on a locally connected subnet.
+ </P
+></LI
+></UL
+><P
+>If this parameter is not set then the name resolve order
+ defined in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file parameter
+ (name resolve order) will be used. </P
+><P
+>The default order is lmhosts, host, wins, bcast. Without
+ this parameter or any entry in the <TT
+CLASS="PARAMETER"
+><I
+>name resolve order
+ </I
+></TT
+> parameter of the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ file, the name resolution methods will be attempted in this
+ order. </P
+></DD
+><DT
+>-d &#60;debug level&#62;</DT
+><DD
+><P
+>debug level is an integer from 0 to 10.</P
+><P
+>The default value if this parameter is not specified
+ is zero.</P
+><P
+>The higher this value, the more detail will be logged
+ about the activities of <B
+CLASS="COMMAND"
+>nmblookup</B
+>. At level
+ 0, only critical errors and serious warnings will be logged.
+ </P
+></DD
+><DT
+>-l logfilename</DT
+><DD
+><P
+>If specified causes all debug messages to be
+ written to the file specified by <TT
+CLASS="REPLACEABLE"
+><I
+>logfilename
+ </I
+></TT
+>. If not specified then all messages will be
+ written to<TT
+CLASS="REPLACEABLE"
+><I
+>stderr</I
+></TT
+>.
+ </P
+></DD
+><DT
+>-L libdir</DT
+><DD
+><P
+>This parameter specifies the location of the
+ shared libraries used by <B
+CLASS="COMMAND"
+>smbsh</B
+>. The default
+ value is specified at compile time.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN91"
+></A
+><H2
+>EXAMPLES</H2
+><P
+>To use the <B
+CLASS="COMMAND"
+>smbsh</B
+> command, execute <B
+CLASS="COMMAND"
+> smbsh</B
+> from the prompt and enter the username and password
+ that authenticates you to the machine running the Windows NT
+ operating system.</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> <TT
+CLASS="PROMPT"
+>system% </TT
+><TT
+CLASS="USERINPUT"
+><B
+>smbsh</B
+></TT
+>
+ <TT
+CLASS="PROMPT"
+>Username: </TT
+><TT
+CLASS="USERINPUT"
+><B
+>user</B
+></TT
+>
+ <TT
+CLASS="PROMPT"
+>Password: </TT
+><TT
+CLASS="USERINPUT"
+><B
+>XXXXXXX</B
+></TT
+>
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Any dynamically linked command you execute from
+ this shell will access the <TT
+CLASS="FILENAME"
+>/smb</TT
+> directory
+ using the smb protocol. For example, the command <B
+CLASS="COMMAND"
+>ls /smb
+ </B
+> will show a list of workgroups. The command
+ <B
+CLASS="COMMAND"
+>ls /smb/MYGROUP </B
+> will show all the machines in
+ the workgroup MYGROUP. The command
+ <B
+CLASS="COMMAND"
+>ls /smb/MYGROUP/&#60;machine-name&#62;</B
+> will show the share
+ names for that machine. You could then, for example, use the <B
+CLASS="COMMAND"
+> cd</B
+> command to change directories, <B
+CLASS="COMMAND"
+>vi</B
+> to
+ edit files, and <B
+CLASS="COMMAND"
+>rcp</B
+> to copy files.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN112"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN115"
+></A
+><H2
+>BUGS</H2
+><P
+><B
+CLASS="COMMAND"
+>smbsh</B
+> works by intercepting the standard
+ libc calls with the dynamically loaded versions in <TT
+CLASS="FILENAME"
+> smbwrapper.o</TT
+>. Not all calls have been "wrapped", so
+ some programs may not function correctly under <B
+CLASS="COMMAND"
+>smbsh
+ </B
+>.</P
+><P
+>Programs which are not dynamically linked cannot make
+ use of <B
+CLASS="COMMAND"
+>smbsh</B
+>'s functionality. Most versions
+ of UNIX have a <B
+CLASS="COMMAND"
+>file</B
+> command that will
+ describe how a program was linked.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN124"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbspool.8.html b/docs/htmldocs/smbspool.8.html
new file mode 100755
index 00000000000..254abe9a9de
--- /dev/null
+++ b/docs/htmldocs/smbspool.8.html
@@ -0,0 +1,222 @@
+<HTML
+><HEAD
+><TITLE
+>smbspool</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBSPOOL"
+>smbspool</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbspool&nbsp;--&nbsp;send print file to an SMB printer</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbspool</B
+> [job] [user] [title] [copies] [options] [filename]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN17"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>smbspool is a very small print spooling program that
+ sends a print file to an SMB printer. The command-line arguments
+ are position-dependent for compatibility with the Common UNIX
+ Printing System, but you can use smbspool with any printing system
+ or from a program or script.</P
+><P
+><EM
+>DEVICE URI</EM
+></P
+><P
+>smbspool specifies the destination using a Uniform Resource
+ Identifier ("URI") with a method of "smb". This string can take
+ a number of forms:</P
+><P
+></P
+><UL
+><LI
+><P
+>smb://server/printer</P
+></LI
+><LI
+><P
+>smb://workgroup/server/printer</P
+></LI
+><LI
+><P
+>smb://username:password@server/printer</P
+></LI
+><LI
+><P
+>smb://username:password@workgroup/server/printer
+ </P
+></LI
+></UL
+><P
+>smbspool tries to get the URI from argv[0]. If argv[0]
+ contains the name of the program then it looks in the <TT
+CLASS="ENVAR"
+> DEVICE_URI</TT
+> environment variable.</P
+><P
+>Programs using the <B
+CLASS="COMMAND"
+>exec(2)</B
+> functions can
+ pass the URI in argv[0], while shell scripts must set the
+ <TT
+CLASS="ENVAR"
+>DEVICE_URI</TT
+> environment variable prior to
+ running smbspool.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN39"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><UL
+><LI
+><P
+>The job argument (argv[1]) contains the
+ job ID number and is presently not used by smbspool.
+ </P
+></LI
+><LI
+><P
+>The user argument (argv[2]) contains the
+ print user's name and is presently not used by smbspool.
+ </P
+></LI
+><LI
+><P
+>The title argument (argv[3]) contains the
+ job title string and is passed as the remote file name
+ when sending the print job.</P
+></LI
+><LI
+><P
+>The copies argument (argv[4]) contains
+ the number of copies to be printed of the named file. If
+ no filename is provided than this argument is not used by
+ smbspool.</P
+></LI
+><LI
+><P
+>The options argument (argv[5]) contains
+ the print options in a single string and is presently
+ not used by smbspool.</P
+></LI
+><LI
+><P
+>The filename argument (argv[6]) contains the
+ name of the file to print. If this argument is not specified
+ then the print file is read from the standard input.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN54"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ and <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN63"
+></A
+><H2
+>AUTHOR</H2
+><P
+><B
+CLASS="COMMAND"
+>smbspool</B
+> was written by Michael Sweet
+ at Easy Software Products.</P
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbstatus.1.html b/docs/htmldocs/smbstatus.1.html
new file mode 100755
index 00000000000..1d3dc9f952a
--- /dev/null
+++ b/docs/htmldocs/smbstatus.1.html
@@ -0,0 +1,209 @@
+<HTML
+><HEAD
+><TITLE
+>smbstatus</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBSTATUS"
+>smbstatus</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbstatus&nbsp;--&nbsp;report on current Samba connections</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbstatus</B
+> [-P] [-b] [-d] [-L] [-p] [-S] [-s &#60;configuration file&#62;] [-u &#60;username&#62;]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN19"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbstatus</B
+> is a very simple program to
+ list the current Samba connections.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN25"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-P</DT
+><DD
+><P
+>If samba has been compiled with the
+ profiling option, print only the contents of the profiling
+ shared memory area.</P
+></DD
+><DT
+>-b</DT
+><DD
+><P
+>gives brief output.</P
+></DD
+><DT
+>-d</DT
+><DD
+><P
+>gives verbose output.</P
+></DD
+><DT
+>-L</DT
+><DD
+><P
+>causes smbstatus to only list locks.</P
+></DD
+><DT
+>-p</DT
+><DD
+><P
+>print a list of <A
+HREF="smbd.8.html"
+TARGET="_top"
+> <B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> processes and exit.
+ Useful for scripting.</P
+></DD
+><DT
+>-S</DT
+><DD
+><P
+>causes smbstatus to only list shares.</P
+></DD
+><DT
+>-s &#60;configuration file&#62;</DT
+><DD
+><P
+>The default configuration file name is
+ determined at compile time. The file specified contains the
+ configuration details required by the server. See <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ </A
+> for more information.</P
+></DD
+><DT
+>-u &#60;username&#62;</DT
+><DD
+><P
+>selects information relevant to
+ <TT
+CLASS="PARAMETER"
+><I
+>username</I
+></TT
+> only.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN65"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN68"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+> and
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN74"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbtar.1.html b/docs/htmldocs/smbtar.1.html
new file mode 100755
index 00000000000..47c41a015a9
--- /dev/null
+++ b/docs/htmldocs/smbtar.1.html
@@ -0,0 +1,351 @@
+<HTML
+><HEAD
+><TITLE
+>smbtar</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBTAR"
+>smbtar</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbtar&nbsp;--&nbsp;shell script for backing up SMB/CIFS shares
+ directly to UNIX tape drives</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbtar</B
+> {-s server} [-p password] [-x services] [-X] [-d directory] [-u user] [-t tape] [-t tape] [-b blocksize] [-N filename] [-i] [-r] [-l loglevel] [-v] {filenames}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN26"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>smbtar</B
+> is a very small shell script on top
+ of <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+>
+ which dumps SMB shares directly to tape. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN34"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-s server</DT
+><DD
+><P
+>The SMB/CIFS server that the share resides
+ upon.</P
+></DD
+><DT
+>-x service</DT
+><DD
+><P
+>The share name on the server to connect to.
+ The default is "backup".</P
+></DD
+><DT
+>-X</DT
+><DD
+><P
+>Exclude mode. Exclude filenames... from tar
+ create or restore. </P
+></DD
+><DT
+>-d directory</DT
+><DD
+><P
+>Change to initial <TT
+CLASS="PARAMETER"
+><I
+>directory
+ </I
+></TT
+> before restoring / backing up files. </P
+></DD
+><DT
+>-v</DT
+><DD
+><P
+>Verbose mode.</P
+></DD
+><DT
+>-p password</DT
+><DD
+><P
+>The password to use to access a share.
+ Default: none </P
+></DD
+><DT
+>-u user</DT
+><DD
+><P
+>The user id to connect as. Default:
+ UNIX login name. </P
+></DD
+><DT
+>-t tape</DT
+><DD
+><P
+>Tape device. May be regular file or tape
+ device. Default: <TT
+CLASS="PARAMETER"
+><I
+>$TAPE</I
+></TT
+> environmental
+ variable; if not set, a file called <TT
+CLASS="FILENAME"
+>tar.out
+ </TT
+>. </P
+></DD
+><DT
+>-b blocksize</DT
+><DD
+><P
+>Blocking factor. Defaults to 20. See
+ <B
+CLASS="COMMAND"
+>tar(1)</B
+> for a fuller explanation. </P
+></DD
+><DT
+>-N filename</DT
+><DD
+><P
+>Backup only files newer than filename. Could
+ be used (for example) on a log file to implement incremental
+ backups. </P
+></DD
+><DT
+>-i</DT
+><DD
+><P
+>Incremental mode; tar files are only backed
+ up if they have the archive bit set. The archive bit is reset
+ after each file is read. </P
+></DD
+><DT
+>-r</DT
+><DD
+><P
+>Restore. Files are restored to the share
+ from the tar file. </P
+></DD
+><DT
+>-l log level</DT
+><DD
+><P
+>Log (debug) level. Corresponds to the
+ <TT
+CLASS="PARAMETER"
+><I
+>-d</I
+></TT
+> flag of <B
+CLASS="COMMAND"
+>smbclient(1)
+ </B
+>. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN95"
+></A
+><H2
+>ENVIRONMENT VARIABLES</H2
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>$TAPE</I
+></TT
+> variable specifies the
+ default tape device to write to. May be overridden
+ with the -t option. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN99"
+></A
+><H2
+>BUGS</H2
+><P
+>The <B
+CLASS="COMMAND"
+>smbtar</B
+> script has different
+ options from ordinary tar and tar called from smbclient. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN103"
+></A
+><H2
+>CAVEATS</H2
+><P
+>Sites that are more careful about security may not like
+ the way the script handles PC passwords. Backup and restore work
+ on entire shares, should work on file lists. smbtar works best
+ with GNU tar and may not work well with other versions. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN106"
+></A
+><H2
+>DIAGNOSTICS</H2
+><P
+>See the <EM
+>DIAGNOSTICS</EM
+> section for the
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+>
+ </A
+> command.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN112"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN115"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>,
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN123"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+><A
+HREF="mailto:poultenr@logica.co.uk"
+TARGET="_top"
+>Ricky Poulten</A
+>
+ wrote the tar extension and this man page. The <B
+CLASS="COMMAND"
+>smbtar</B
+>
+ script was heavily rewritten and improved by <A
+HREF="mailto:Martin.Kraemer@mch.sni.de"
+TARGET="_top"
+>Martin Kraemer</A
+>. Many
+ thanks to everyone who suggested extensions, improvements, bug
+ fixes, etc. The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/smbumount.8.html b/docs/htmldocs/smbumount.8.html
new file mode 100755
index 00000000000..68929fd5f91
--- /dev/null
+++ b/docs/htmldocs/smbumount.8.html
@@ -0,0 +1,140 @@
+<HTML
+><HEAD
+><TITLE
+>smbumount</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SMBUMOUNT"
+>smbumount</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>smbumount&nbsp;--&nbsp;smbfs umount for normal users</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>smbumount</B
+> {mount-point}</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN12"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>With this program, normal users can unmount smb-filesystems,
+ provided that it is suid root. <B
+CLASS="COMMAND"
+>smbumount</B
+> has
+ been written to give normal Linux users more control over their
+ resources. It is safe to install this program suid root, because only
+ the user who has mounted a filesystem is allowed to unmount it again.
+ For root it is not necessary to use smbumount. The normal umount
+ program works perfectly well, but it would certainly be problematic
+ to make umount setuid root.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN16"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>mount-point</DT
+><DD
+><P
+>The directory to unmount.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN23"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smbmount.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbmount(8)</B
+>
+ </A
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN28"
+></A
+><H2
+>AUTHOR</H2
+><P
+>Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+ and others.</P
+><P
+>The current maintainer of smbfs and the userspace
+ tools <B
+CLASS="COMMAND"
+>smbmount</B
+>, <B
+CLASS="COMMAND"
+>smbumount</B
+>,
+ and <B
+CLASS="COMMAND"
+>smbmnt</B
+> is <A
+HREF="mailto:urban@teststation.com"
+TARGET="_top"
+>Urban Widmark</A
+>.
+ The <A
+HREF="mailto:samba@samba.org"
+TARGET="_top"
+>SAMBA Mailing list</A
+>
+ is the preferred place to ask questions regarding these programs.
+ </P
+><P
+>The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/swat.8.html b/docs/htmldocs/swat.8.html
new file mode 100755
index 00000000000..374a1423463
--- /dev/null
+++ b/docs/htmldocs/swat.8.html
@@ -0,0 +1,511 @@
+<HTML
+><HEAD
+><TITLE
+>swat</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="SWAT"
+>swat</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>swat&nbsp;--&nbsp;Samba Web Administration Tool</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>swat</B
+> [-s &#60;smb config file&#62;] [-a]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN13"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>swat</B
+> allows a Samba administrator to
+ configure the complex <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+> smb.conf(5)</TT
+></A
+> file via a Web browser. In addition,
+ a <B
+CLASS="COMMAND"
+>swat</B
+> configuration page has help links
+ to all the configurable options in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file allowing an
+ administrator to easily look up the effects of any change. </P
+><P
+><B
+CLASS="COMMAND"
+>swat</B
+> is run from <B
+CLASS="COMMAND"
+>inetd</B
+> </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN26"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-s smb configuration file</DT
+><DD
+><P
+>The default configuration file path is
+ determined at compile time. The file specified contains
+ the configuration details required by the <B
+CLASS="COMMAND"
+>smbd
+ </B
+> server. This is the file that <B
+CLASS="COMMAND"
+>swat</B
+> will modify.
+ The information in this file includes server-specific
+ information such as what printcap file to use, as well as
+ descriptions of all the services that the server is to provide.
+ See <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> for more information.
+ </P
+></DD
+><DT
+>-a</DT
+><DD
+><P
+>This option disables authentication and puts
+ <B
+CLASS="COMMAND"
+>swat</B
+> in demo mode. In that mode anyone will be able to modify
+ the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file. </P
+><P
+><EM
+>Do NOT enable this option on a production
+ server. </EM
+></P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN44"
+></A
+><H2
+>INSTALLATION</H2
+><P
+>After you compile SWAT you need to run <B
+CLASS="COMMAND"
+>make install
+ </B
+> to install the <B
+CLASS="COMMAND"
+>swat</B
+> binary
+ and the various help files and images. A default install would put
+ these in: </P
+><P
+></P
+><UL
+><LI
+><P
+>/usr/local/samba/bin/swat</P
+></LI
+><LI
+><P
+>/usr/local/samba/swat/images/*</P
+></LI
+><LI
+><P
+>/usr/local/samba/swat/help/*</P
+></LI
+></UL
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN56"
+></A
+><H3
+>Inetd Installation</H3
+><P
+>You need to edit your <TT
+CLASS="FILENAME"
+>/etc/inetd.conf
+ </TT
+> and <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>
+ to enable SWAT to be launched via <B
+CLASS="COMMAND"
+>inetd</B
+>.</P
+><P
+>In <TT
+CLASS="FILENAME"
+>/etc/services</TT
+> you need to
+ add a line like this: </P
+><P
+><B
+CLASS="COMMAND"
+>swat 901/tcp</B
+></P
+><P
+>Note for NIS/YP users - you may need to rebuild the
+ NIS service maps rather than alter your local <TT
+CLASS="FILENAME"
+> /etc/services</TT
+> file. </P
+><P
+>the choice of port number isn't really important
+ except that it should be less than 1024 and not currently
+ used (using a number above 1024 presents an obscure security
+ hole depending on the implementation details of your
+ <B
+CLASS="COMMAND"
+>inetd</B
+> daemon). </P
+><P
+>In <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+> you should
+ add a line like this: </P
+><P
+><B
+CLASS="COMMAND"
+>swat stream tcp nowait.400 root
+ /usr/local/samba/bin/swat swat</B
+></P
+><P
+>One you have edited <TT
+CLASS="FILENAME"
+>/etc/services</TT
+>
+ and <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+> you need to send a
+ HUP signal to inetd. To do this use <B
+CLASS="COMMAND"
+>kill -1 PID
+ </B
+> where PID is the process ID of the inetd daemon. </P
+></DIV
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN78"
+></A
+><H3
+>Xinetd Installation</H3
+><P
+>Newer Linux systems ship with a more secure implementation
+ of the inetd meta-daemon. The <B
+CLASS="COMMAND"
+>xinetd</B
+> daemon
+ can read configuration inf9ormation from a single file (i.e.
+ <TT
+CLASS="FILENAME"
+>/etc/xinetd.conf</TT
+>) or from a collection
+ of service control files in the <TT
+CLASS="FILENAME"
+>xinetd.d/</TT
+> directory.
+ These directions assume the latter configuration.
+ </P
+><P
+> The following file should be created as <TT
+CLASS="FILENAME"
+>/etc/xientd.d/swat</TT
+>.
+ It is then be neccessary cause the meta-daemon to reload its configuration files.
+ Refer to the xinetd man page for details on how to accomplish this.
+ </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>## /etc/xinetd.d/swat
+service swat
+{
+ port = 901
+ socket_type = stream
+ wait = no
+ only_from = localhost
+ user = root
+ server = /usr/local/samba/bin/swat
+ log_on_failure += USERID
+ disable = No
+}</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="REFSECT2"
+><A
+NAME="AEN88"
+></A
+><H3
+>Launching</H3
+><P
+>To launch SWAT just run your favorite web browser and
+ point it at "http://localhost:901/".</P
+><P
+>Note that you can attach to SWAT from any IP connected
+ machine but connecting from a remote machine leaves your
+ connection open to password sniffing as passwords will be sent
+ in the clear over the wire. </P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN92"
+></A
+><H2
+>TROUBLESHOOTING</H2
+><P
+> One of the common causes of difficulty when installing Samba and SWAT
+ is the existsnece of some type of firewall or port filtering software
+ on the Samba server. Make sure that the appropriate ports
+ outlined in this man page are available on the server and are not currently
+ being blocked by some type of security software such as iptables or
+ "port sentry". For more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN95"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+></DT
+><DD
+><P
+>This file must contain suitable startup
+ information for the meta-daemon.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/xinetd.d/swat</TT
+></DT
+><DD
+><P
+>This file must contain suitable startup
+ information for the <B
+CLASS="COMMAND"
+>xinetd</B
+> meta-daemon.</P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/services</TT
+></DT
+><DD
+><P
+>This file must contain a mapping of service name
+ (e.g., swat) to service port (e.g., 901) and protocol type
+ (e.g., tcp). </P
+></DD
+><DT
+><TT
+CLASS="FILENAME"
+>/usr/local/samba/lib/smb.conf</TT
+></DT
+><DD
+><P
+>This is the default location of the <TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+> server configuration file that swat edits. Other
+ common places that systems install this file are <TT
+CLASS="FILENAME"
+> /usr/samba/lib/smb.conf</TT
+> and <TT
+CLASS="FILENAME"
+>/etc/smb.conf
+ </TT
+>. This file describes all the services the server
+ is to make available to clients. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN122"
+></A
+><H2
+>WARNINGS</H2
+><P
+><B
+CLASS="COMMAND"
+>swat</B
+> will rewrite your <TT
+CLASS="FILENAME"
+>smb.conf
+ </TT
+> file. It will rearrange the entries and delete all
+ comments, <TT
+CLASS="PARAMETER"
+><I
+>include=</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>copy="
+ </I
+></TT
+> options. If you have a carefully crafted <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> then back it up or don't use swat! </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN133"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><B
+CLASS="COMMAND"
+>inetd(5)</B
+>,
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+>, <B
+CLASS="COMMAND"
+>xinetd(8)</B
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN141"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/testparm.1.html b/docs/htmldocs/testparm.1.html
new file mode 100755
index 00000000000..3ed7e6d8238
--- /dev/null
+++ b/docs/htmldocs/testparm.1.html
@@ -0,0 +1,304 @@
+<HTML
+><HEAD
+><TITLE
+>testparm</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="TESTPARM"
+>testparm</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>testparm&nbsp;--&nbsp;check an smb.conf configuration file for
+ internal correctness</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>testparm</B
+> [-s] [-h] [-x] [-L &#60;servername&#62;] {config filename} [hostname hostIP]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN17"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>testparm</B
+> is a very simple test program
+ to check an <B
+CLASS="COMMAND"
+>smbd</B
+> configuration file for
+ internal correctness. If this program reports no problems, you
+ can use the configuration file with confidence that <B
+CLASS="COMMAND"
+>smbd
+ </B
+> will successfully load the configuration file.</P
+><P
+>Note that this is <EM
+>NOT</EM
+> a guarantee that
+ the services specified in the configuration file will be
+ available or will operate as expected. </P
+><P
+>If the optional host name and host IP address are
+ specified on the command line, this test program will run through
+ the service entries reporting whether the specified host
+ has access to each service. </P
+><P
+>If <B
+CLASS="COMMAND"
+>testparm</B
+> finds an error in the <TT
+CLASS="FILENAME"
+> smb.conf</TT
+> file it returns an exit code of 1 to the calling
+ program, else it returns an exit code of 0. This allows shell scripts
+ to test the output from <B
+CLASS="COMMAND"
+>testparm</B
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN32"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-s</DT
+><DD
+><P
+>Without this option, <B
+CLASS="COMMAND"
+>testparm</B
+>
+ will prompt for a carriage return after printing the service
+ names and before dumping the service definitions.</P
+></DD
+><DT
+>-h</DT
+><DD
+><P
+>Print usage message </P
+></DD
+><DT
+>-x</DT
+><DD
+><P
+>Print only parameters that have non-default values</P
+></DD
+><DT
+>-L servername</DT
+><DD
+><P
+>Sets the value of the %L macro to <TT
+CLASS="REPLACEABLE"
+><I
+>servername</I
+></TT
+>.
+ This is useful for testing include files specified with the
+ %L macro. </P
+></DD
+><DT
+>configfilename</DT
+><DD
+><P
+>This is the name of the configuration file
+ to check. If this parameter is not present then the
+ default <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file will be checked.
+ </P
+></DD
+><DT
+>hostname</DT
+><DD
+><P
+>If this parameter and the following are
+ specified, then <B
+CLASS="COMMAND"
+>testparm</B
+> will examine the <TT
+CLASS="PARAMETER"
+><I
+>hosts
+ allow</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>hosts deny</I
+></TT
+>
+ parameters in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file to
+ determine if the hostname with this IP address would be
+ allowed access to the <B
+CLASS="COMMAND"
+>smbd</B
+> server. If
+ this parameter is supplied, the hostIP parameter must also
+ be supplied.</P
+></DD
+><DT
+>hostIP</DT
+><DD
+><P
+>This is the IP address of the host specified
+ in the previous parameter. This address must be supplied
+ if the hostname parameter is supplied. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN71"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>smb.conf</TT
+></DT
+><DD
+><P
+>This is usually the name of the configuration
+ file used by <B
+CLASS="COMMAND"
+>smbd</B
+>.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN80"
+></A
+><H2
+>DIAGNOSTICS</H2
+><P
+>The program will issue a message saying whether the
+ configuration file loaded OK or not. This message may be preceded by
+ errors and warnings if the file did not load. If the file was
+ loaded OK, the program then dumps all known service details
+ to stdout. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN83"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN86"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="smb.conf.5.html"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+></A
+>,
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN93"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/testprns.1.html b/docs/htmldocs/testprns.1.html
new file mode 100755
index 00000000000..4929415da02
--- /dev/null
+++ b/docs/htmldocs/testprns.1.html
@@ -0,0 +1,252 @@
+<HTML
+><HEAD
+><TITLE
+>testprns</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="TESTPRNS"
+>testprns</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>testprns&nbsp;--&nbsp;check printer name for validity with smbd</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>testprns</B
+> {printername} [printcapname]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN13"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>testprns</B
+> is a very simple test program
+ to determine whether a given printer name is valid for use in
+ a service to be provided by <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> smbd(8)</B
+></A
+>. </P
+><P
+>"Valid" in this context means "can be found in the
+ printcap specified". This program is very stupid - so stupid in
+ fact that it would be wisest to always specify the printcap file
+ to use. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN22"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>printername</DT
+><DD
+><P
+>The printer name to validate.</P
+><P
+>Printer names are taken from the first field in each
+ record in the printcap file, single printer names and sets
+ of aliases separated by vertical bars ("|") are recognized.
+ Note that no validation or checking of the printcap syntax is
+ done beyond that required to extract the printer name. It may
+ be that the print spooling system is more forgiving or less
+ forgiving than <B
+CLASS="COMMAND"
+>testprns</B
+>. However, if
+ <B
+CLASS="COMMAND"
+>testprns</B
+> finds the printer then
+ <B
+CLASS="COMMAND"
+>smbd</B
+> should do so as well. </P
+></DD
+><DT
+>printcapname</DT
+><DD
+><P
+>This is the name of the printcap file within
+ which to search for the given printer name. </P
+><P
+>If no printcap name is specified <B
+CLASS="COMMAND"
+>testprns
+ </B
+> will attempt to scan the printcap file name
+ specified at compile time. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN39"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/printcap</TT
+></DT
+><DD
+><P
+>This is usually the default printcap
+ file to scan. See <TT
+CLASS="FILENAME"
+>printcap (5)</TT
+>.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN48"
+></A
+><H2
+>DIAGNOSTICS</H2
+><P
+>If a printer is found to be valid, the message
+ "Printer name &#60;printername&#62; is valid" will be
+ displayed. </P
+><P
+>If a printer is found to be invalid, the message
+ "Printer name &#60;printername&#62; is not valid" will be
+ displayed. </P
+><P
+>All messages that would normally be logged during
+ operation of the Samba daemons are logged by this program to the
+ file <TT
+CLASS="FILENAME"
+>test.log</TT
+> in the current directory. The
+ program runs at debuglevel 3, so quite extensive logging
+ information is written. The log should be checked carefully
+ for errors and warnings. </P
+><P
+>Other messages are self-explanatory. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN55"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN58"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><TT
+CLASS="FILENAME"
+>printcap(5)</TT
+>,
+ <A
+HREF="smbd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbd(8)</B
+></A
+>,
+ <A
+HREF="smbclient.1.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>smbclient(1)</B
+></A
+>
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN66"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+>The original Samba man pages were written by Karl Auer.
+ The man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ <A
+HREF="ftp://ftp.icce.rug.nl/pub/unix/"
+TARGET="_top"
+> ftp://ftp.icce.rug.nl/pub/unix/</A
+>) and updated for the Samba 2.0
+ release by Jeremy Allison. The conversion to DocBook for
+ Samba 2.2 was done by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/using_samba/appa_01.html b/docs/htmldocs/using_samba/appa_01.html
new file mode 100755
index 00000000000..30080dffbf6
--- /dev/null
+++ b/docs/htmldocs/using_samba/appa_01.html
@@ -0,0 +1,153 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix A] Configuring Samba with SSL</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:36Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_03.html" TITLE="9.3 Extra Resources">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.3 Extra Resources" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix A</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_02.html" TITLE="A.2 Requirements">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.2 Requirements" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="appendix">
+<A CLASS="title" NAME="appa-73322">
+A. Configuring Samba with SSL</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#appa-pgfId-986440" TITLE="A.1 About Certificates">
+About Certificates</a><br>
+<A CLASS="sect1" HREF="appa_02.html" TITLE="A.2 Requirements">
+Requirements</a><br>
+<A CLASS="sect1" HREF="appa_03.html" TITLE="A.3 Installing SSLeay">
+Installing SSLeay</a><br>
+<A CLASS="sect1" HREF="appa_04.html" TITLE="A.4 Setting Up SSL Proxy">
+Setting Up SSL Proxy</a><br>
+<A CLASS="sect1" HREF="appa_05.html" TITLE="A.5 SSL Configuration Options">
+SSL Configuration Options</a></p><P>
+</p></div><P CLASS="para">This appendix describes how to set up Samba to use secure connections between the Samba server and its clients. The protocol used here is Netscape's Secure Sockets Layer (SSL). For this example, we will establish a secure connection between a Samba server and a Windows NT workstation. </p><P CLASS="para">
+Before we begin, we will assume that you are familiar with the fundamentals of public-key cryptography and X.509 certificates. If not, we highly recommend Bruce Schneier's <I CLASS="filename">
+Applied Cryptography, 2nd Edition</i> (Wiley) as the premiere source for learning the many secret faces of cryptography.</p><P CLASS="para">
+If you would like more information on Samba and SSL, be sure to look at the document <I CLASS="filename">
+SSLeay.txt</i> in the <I CLASS="filename">
+docs/textdocs</i> directory of the Samba distribution, which is the basis for this appendix.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appa-pgfId-986440">
+A.1 About Certificates</a></h2><P CLASS="para">
+Here are a few quick questions and answers from the <I CLASS="filename">
+SSLeay.txt</i> file in the Samba documentation, regarding the benefits of SSL and certificates. This text was written by Christian Starkjohann for the Samba projects. </p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-990471">
+A.1.1 What is a Certificate?</a></h3><P CLASS="para">
+A certifcate is issued by an issuer, usually a <EM CLASS="emphasis">
+Certification Authority</em> (CA), who confirms something by issuing the certificate. The subject of this confirmation depends on the CA's policy. CAs for secure web servers (used for shopping malls, etc.) usually attest only that the given public key belongs the given domain name. Company-wide CAs might attest that you are an employee of the company, that you have permissions to use a server, and so on. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-990473">
+A.1.2 What is an X.509 certificate, technically?</a></h3><P CLASS="para">
+Technically, the certificate is a block of data signed by the certificate issuer (the CA). The relevant fields are:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990475">
+</a>Unique identifier (name) of the certificate issuer</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990476">
+</a>Time range during which the certificate is valid</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990477">
+</a>Unique identifier (name) of the certified object</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990478">
+</a>Public key of the certified object</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990479">
+</a>The issuer's signature over all the above</p></li></ul><P CLASS="para">
+If this certificate is to be verified, the verifier must have a table of the names and public keys of trusted CAs. For simplicity, these tables should list certificates issued by the respective CAs for themselves (self-signed certificates).</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-990481">
+A.1.3 What are the implications of this certificate structure?</a></h3><P CLASS="para">
+Four implications follow:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990485">
+</a>Because the certificate contains the subjects's public key, the certificate and the private key together are all that is needed to encrypt and decrypt.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990489">
+</a>To verify certificates, you need the certificates of all CAs you trust. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990490">
+</a>The simplest form of a dummy-certificate is one that is signed by the subject.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-990491">
+</a>A CA is needed. The client can't simply issue local certificates for servers it trusts because the server determines which certificate it presents. </p></li></ul></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_03.html" TITLE="9.3 Extra Resources">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.3 Extra Resources" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_02.html" TITLE="A.2 Requirements">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.2 Requirements" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+9.3 Extra Resources</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+A.2 Requirements</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appa_02.html b/docs/htmldocs/using_samba/appa_02.html
new file mode 100755
index 00000000000..e69b2fd9128
--- /dev/null
+++ b/docs/htmldocs/using_samba/appa_02.html
@@ -0,0 +1,100 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix A] A.2 Requirements</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:37Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_01.html" TITLE="A.1 About Certificates">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.1 About Certificates" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+Appendix A<br>
+Configuring Samba with SSL</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_03.html" TITLE="A.3 Installing SSLeay">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.3 Installing SSLeay" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appa-pgfId-990469">
+A.2 Requirements</a></h2><P CLASS="para">To set up SSL connections, you will need to download two programs in addition to Samba:</p><DL CLASS="variablelist">
+<DT CLASS="term">SSLeay</dt><DD CLASS="listitem">
+<P CLASS="para">
+Eric Young's implementation of the Secure Socket's Layer (SSL) protocol as a series of Unix programming libraries</p></dd><DT CLASS="term">SSL Proxy</dt><DD CLASS="listitem">
+<P CLASS="para">
+A freeware SSL application from Objective Development, which can be used to proxy a secure link on Unix or Windows NT platforms</p></dd></dl><P CLASS="para">
+These two products assist with the server and client side of the encrypted SSL connection. The SSLeay libraries are compiled and installed directly on the Unix system. SSL Proxy, on the other hand, can be downloaded and compiled (or downloaded in binary format) and located on the client side. If you intend to have a Windows NT client or a Samba client on the other end of the SSL connection, you will not require a special setup.</p><P CLASS="para">
+SSL Proxy, however, does not work on Windows 95/98 machines. Therefore, if you want to have a secure connection between a Samba server and Windows 95/98 client, you will need to place either a Unix server or a Windows NT machine on the same subnet with the Windows 9<EM CLASS="emphasis">
+x</em> clients and route all network connections through the SSL-Proxy-enabled machine. See <A CLASS="xref" HREF="appa_02.html#appa-89929">
+Figure A.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="appa-89929">
+Figure A.1: Two possible ways of proxying Windows 95/98 clients</a></h4><IMG CLASS="graphic" SRC="figs/sam.aa01.gif" ALT="Figure A.1"><P CLASS="para">
+For the purposes of this chapter, we will create a simple SSL connection between the Samba server and a Windows NT client. This configuration can be used to set up more complex networks at the administrator's discretion.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_01.html" TITLE="A.1 About Certificates">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.1 About Certificates" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_03.html" TITLE="A.3 Installing SSLeay">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.3 Installing SSLeay" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+A.1 About Certificates</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+A.3 Installing SSLeay</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appa_03.html b/docs/htmldocs/using_samba/appa_03.html
new file mode 100755
index 00000000000..f8cdb139315
--- /dev/null
+++ b/docs/htmldocs/using_samba/appa_03.html
@@ -0,0 +1,325 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix A] A.3 Installing SSLeay</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:37Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_02.html" TITLE="A.2 Requirements">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.2 Requirements" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+Appendix A<br>
+Configuring Samba with SSL</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_04.html" TITLE="A.4 Setting Up SSL Proxy">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.4 Setting Up SSL Proxy" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appa-pgfId-985777">
+A.3 Installing SSLeay</a></h2><P CLASS="para">
+Samba uses the SSLeay package, written by Eric Young, to provide Secure Sockets Layer support on the server side. Because of U.S. export law, however, the SSLeay package cannot be shipped with Samba distributions that are based in the United States. For that reason, the Samba creators decided to leave it as a separate package entirely. You can download the SSLeay distribution from any of the following sites:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-985779">
+</a><A CLASS="systemitem.url" HREF="ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/">
+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/</a></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-985781">
+</a><A CLASS="systemitem.url" HREF="ftp://ftp.uni-mainz.de/pub/internet/security/ssl">
+ftp://ftp.uni-mainz.de/pub/internet/security/ssl</a></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-985782">
+</a><A CLASS="systemitem.url" HREF="ftp://ftp.cert.dfn.de/pub/tools/crypt/sslapps">
+ftp://ftp.cert.dfn.de/pub/tools/crypt/sslapps</a></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-985783">
+</a><A CLASS="systemitem.url" HREF="ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.psy.uq.oz.au">
+ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.psy.uq.oz.au</a></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-985784">
+</a><A CLASS="systemitem.url" HREF="ftp://ftp.sunet.se/ftp/pub/security/tools/crypt/ssleay">
+ftp://ftp.sunet.se/ftp/pub/security/tools/crypt/ssleay</a></p></li></ul><P CLASS="para">
+The latest version as of this printing is 0.9.0b. Download it to the same server as the Samba distribution, then uncompress and untar it. You should be left with a directory entitled <I CLASS="filename">
+SSLeay-0.9.0b</i>. After changing to that directory, you will need to configure and build the SSL encryption package in the same way that you did with Samba.</p><P CLASS="para">
+SSLeay uses a Perl-based <I CLASS="filename">
+configure</i> script. This script modifies the Makefile that constructs the utilities and libraries of the SSLeay package. However, the default script is hardcoded to find Perl at <I CLASS="filename">
+/usr/local/bin/perl</i>. You may need to change the <I CLASS="filename">
+configure</i> script to point to the location of the Perl executable file on your Unix system. For example, you can type the following to locate the Perl executable:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>which perl</b></code>
+/usr/bin/perl</pre><P CLASS="para">
+Then modify the first line of the <I CLASS="filename">
+configure</i> script to force it to use the correct Perl executable. For example, on our Red Hat Linux system:</p><PRE CLASS="programlisting">
+#!/usr/bin/perl
+#
+# see PROBLEMS for instructions on what sort of things to do
+# when tracking a bug -tjh
+...</pre><P CLASS="para">
+After that, you need to run the <I CLASS="filename">
+configure</i> script by specifying a target platform for the distribution. This target platform can be any of the following:</p><PRE CLASS="programlisting">
+BC-16 BC-32 FreeBSD NetBSD-m86
+NetBSD-sparc NetBSD-x86 SINIX-N VC-MSDOS
+VC-NT VC-W31-16 VC-W31-32 VC-WIN16
+VC-WIN32 aix-cc aix-gcc alpha-cc
+alpha-gcc alpha400-cc cc cray-t90-cc
+debug debug-irix-cc debug-linux-elf dgux-R3-gcc
+dgux-R4-gcc dgux-R4-x86-gcc dist gcc
+hpux-cc hpux-gcc hpux-kr-cc irix-cc
+irix-gcc linux-aout linux-elf ncr-scde
+nextstep purify sco5-cc solaris-sparc-cc
+solaris-sparc-gcc solaris-sparc-sc4 solaris-usparc-sc4 solaris-x86-gcc
+sunos-cc sunos-gcc unixware-2.0 unixware</pre><P CLASS="para">
+For our system, we would enter the following:</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>./Configure linux-elf</b></code>
+CC =gcc
+CFLAG =-DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer
+EX_LIBS =
+BN_MULW =asm/bn86-elf.o
+DES_ENC =asm/dx86-elf.o asm/yx86-elf.o
+BF_ENC =asm/bx86-elf.o
+CAST_ENC =asm/cx86-elf.o
+RC4_ENC =asm/rx86-elf.o
+RC5_ENC =asm/r586-elf.o
+MD5_OBJ_ASM =asm/mx86-elf.o
+SHA1_OBJ_ASM =asm/sx86-elf.o
+RMD160_OBJ_ASM=asm/rm86-elf.o
+THIRTY_TWO_BIT mode
+DES_PTR used
+DES_RISC1 used
+DES_UNROLL used
+BN_LLONG mode
+RC4_INDEX mode </pre><P CLASS="para">
+After the package has been configured, you can build it by typing <CODE CLASS="literal">
+make</code>. If the build did not successfully complete, consult the documentation that comes with the distribution or the FAQ at <a href="http://www.cryptsoft.com/ssleay/"><I CLASS="filename">http://www.cryptsoft.com/ssleay/</i></a> for more information on what may have happened. If the build did complete, type <CODE CLASS="literal">
+make</code> <CODE CLASS="literal">
+install</code> to install the libraries on the system. Note that the makefile installs the package in <I CLASS="filename">
+/usr/local/ssl</i> by default. If you decide to install it in another directory, remember the directory when configuring Samba to use SSL.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-985829">
+A.3.1 Configuring SSLeay for Your System</a></h3><P CLASS="para">
+The first thing you need to do is to set the <CODE CLASS="literal">
+PATH</code> environment variable on your system to include the <I CLASS="filename">
+/bin</i> directory of the SSL distribution. This can be done with the following statement:</p><PRE CLASS="programlisting">
+PATH=$PATH:/usr/local/ssl/bin</pre><P CLASS="para">
+That's the easy part. Following that, you will need to create a random series of characters that will be used to prime SSLeay's random number generator. The random number generator will be used to create key pairs for both the clients and the server. You can create this random series by filling a text file of a long series of random characters. For example, you can use your favorite editor to create a text file with random characters, or use this command and enter arbitrary characters at the standard input:</p><PRE CLASS="programlisting">
+cat &gt;/tmp/private.txt</pre><P CLASS="para">
+The Samba documentation recommends that you type characters for longer than a minute before interrupting the input stream by hitting Control-D. Try not to type only the characters that are under your fingers on the keyboard; throw in some symbols and numbers as well. Once you've completed the random file, you can prime the random number generator with the following command:</p><PRE CLASS="programlisting">
+# ssleay genrsa -rand /tmp/private.txt &gt;/dev/null
+2451 semi-random bytes loaded
+Generating RSA private key, 512 bit long modulus
+..+++++
+.................................+++++
+e is 65537 (0x10001)</pre><P CLASS="para">
+You can safely ignore the output of this command. After it has completed, remove the series of characters used to create the key because this could be used to recreate any private keys that were generated from this random number generator:</p><PRE CLASS="programlisting">
+rm -f /tmp/private.txt</pre><P CLASS="para">
+The result of this command is the hidden file .<EM CLASS="emphasis">
+rnd</em>, which is stored in your home directory. SSLeay will use this file when creating key pairs in the future.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-985843">
+A.3.2 Configuring Samba to use SSL</a></h3><P CLASS="para">At this point, you can compile Samba to use SSL. Recall that in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>, we said you have to first run the configure script, which initializes the makefile, before you compile Samba. In order to use SSL with Samba, you will need to reconfigure the makefile:</p><PRE CLASS="programlisting">
+./configure --with-ssl</pre><P CLASS="para">
+After that, you can compile Samba with the following commands:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>make clean</b></code>
+# <CODE CLASS="userinput"><B>make all</b></code></pre><P CLASS="para">
+If you encounter an error that says the <I CLASS="filename">
+smbd</i> executable is missing the file <I CLASS="filename">
+ssl.h</i>, you probably didn't install SSLeay in the default directory. Use the configure option <CODE CLASS="literal">
+--with-sslinc</code> to point to the base directory of the SSL distribution&nbsp;- in this case, the directory that contains <EM CLASS="emphasis">
+include/ssl.h</em>.</p><P CLASS="para">
+On the other hand, if you have a clean compile, you're ready to move on to the next step: creating certificates.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-62097">
+A.3.3 Becoming a Certificate Authority</a></h3><P CLASS="para">
+<I CLASS="firstterm">
+</i>The SSL protocol requires the use of X.509 certificates in the protocol handshake to ensure that either one or both parties involved in the communication are indeed who they say they are. Certificates in real life, such as those use for SSL connections on public web sites, can cost in the arena of $300 a year. This is because the certificate must have a digital signature placed on it by a <I CLASS="firstterm">
+certificate authority</i>. A certificate authority is an entity that vouches for the authenticity of a digital certificate by signing it with its own private key. This way, anyone who wishes to check the authenticity of the certificate can simply use the certificate authority's public key to check the signature.</p><P CLASS="para">
+You are allowed to use a public certificate authority with SSLeay. However, you don't have to. Instead, SSLeay will allow you to declare yourself a trusted certificate authority&nbsp;- specifying which clients you choose to trust and which clients you do not. In order to do this, you will need to perform several tasks with the SSLeay distribution.</p><P CLASS="para">
+The first thing you need to do is specify a secure location where the certificates of the clients and potentially the server will be stored. We have chosen <I CLASS="filename">
+/etc/certificates</i> as our default. Execute the following commands as <CODE CLASS="literal">
+root</code>: </p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>cd /etc</b></code>
+# <CODE CLASS="userinput"><B>mkdir certificates</b></code>
+# <CODE CLASS="userinput"><B>chmod 700 certificates</b></code></pre><P CLASS="para">
+Note that we shut out all access to users other than <CODE CLASS="literal">
+root</code> for this directory. This is very important.</p><P CLASS="para">
+Next, you need to set up the SSLeay scripts and configuration files to use the certificates stored in this directory. In order to do this, first modify the <I CLASS="filename">
+CA.sh</i> script located at <EM CLASS="emphasis">
+/usr/local/ssl/bin/CA.sh</em> to specify the location of the directory you just created. Find the line that contains the following entry:</p><PRE CLASS="programlisting">
+CATOP=./demoCA</pre><P CLASS="para">
+Then change it to:</p><PRE CLASS="programlisting">
+CATOP=/etc/certificates</pre><P CLASS="para">
+Next, you need to modify the <EM CLASS="emphasis">
+/usr/local/ssl/lib/ssleay.cnf</em> file to specify the same directory. Find the entry:</p><PRE CLASS="programlisting">
+[ CA_default ]
+dir = ./demoCA # Where everything is kept</pre><P CLASS="para">
+Then change it to:</p><PRE CLASS="programlisting">
+[ CA_default ]
+dir = /etc/certificates # Where everything is kept</pre><P CLASS="para">
+Next, run the certificate authority setup script, <I CLASS="filename">
+CA.sh</i>, in order to create the certificates. Be sure to do this as the same user that you used to prime the random number generator above:</p><PRE CLASS="programlisting">
+/usr/local/ssl/bin/CA.sh -newca
+mkdir: cannot make directory '/etc/certificates': File exists
+CA certificate filename (or enter to create)</pre><P CLASS="para">
+Press the Enter key to create a certificate for the CA. You should then see:</p><PRE CLASS="programlisting">
+Making CA certificate ...
+Using configuration from /usr/local/ssl/lib/ssleay.cnf
+Generating a 1024 bit RSA private key
+.............................+++++
+.....................+++++
+writing new private key to /etc/certificates/private/cakey.pem
+Enter PEM pass phrase:</pre><P CLASS="para">
+Enter a new pass phrase for your certificate. You will need to enter it twice correctly before SSLeay will accept it:</p><PRE CLASS="programlisting">
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:</pre><P CLASS="para">
+Be sure to remember this pass phrase. You will need it to sign the client certificates in the future. Once SSLeay has accepted the pass phrase, it will continue on with a series of questions for each of the fields in the X509 certificate:</p><PRE CLASS="programlisting">
+You are about to be asked to enter information that will be
+incorporated into your certificate request.
+What you are about to enter is what is called a Distinguished
+Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.</pre><P CLASS="para">
+Fill out the remainder of the fields with information about your organization. For example, our certificate looks like this:</p><PRE CLASS="programlisting">
+Country Name (2 letter code) [AU]:<CODE CLASS="userinput">
+<B>
+US</b></code>
+State or Province Name (full name) [Some-State]:<CODE CLASS="userinput">
+<B>
+California</b></code>
+Locality Name (eg, city) []:<CODE CLASS="userinput">
+<B>
+Sebastopol</b></code>
+Organization Name (eg, company) []:<CODE CLASS="userinput">
+<B>
+O'Reilly</b></code>
+Organizational Unit Name (eg, section) []:<CODE CLASS="userinput">
+<B>
+Books</b></code>
+Common Name (eg, YOUR name) []:<CODE CLASS="userinput">
+<B>
+John Doe</b></code>
+Email Address []:<CODE CLASS="userinput">
+<B>
+doe@ora.com</b></code></pre><P CLASS="para">
+After that, SSLeay will be configured as a certificate authority and can be used to sign certificates for client machines that will be connecting to the Samba server.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986381">
+A.3.4 Creating Certificates for Clients</a></h3><P CLASS="para">
+It's simple to create a certificate for a client machine. First, you need to generate a public/private key pair for each entity, create a certificate request file, and then use <EM CLASS="emphasis">
+SSLeay</em> to sign the file as a trusted authority.</p><P CLASS="para">
+For our example client <CODE CLASS="literal">
+phoenix</code>, this boils down to three SSLeay commands. The first generates a key pair for the client and places it in the file <I CLASS="filename">
+phoenix.key</i>. The private key will be encrypted, in this case using triple DES. Enter a pass phrase when requested below&nbsp;- you'll need it for the next step:</p><PRE CLASS="programlisting">
+# ssleay genrsa -des3 1024 &gt;phoenix.key
+1112 semi-random bytes loaded
+Generating RSA private key, 1024 bit long modulus
+........................................+++++
+.............+++++
+e is 65537 (0x10001)
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:</pre><P CLASS="para">
+After that command has completed, type in the following command:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>ssleay req -new -key phoenix.key -out phoenix-csr</b></code>
+Enter PEM pass phrase:</pre><P CLASS="para">
+Enter the pass phrase for the client certificate you just created (not the certificate authority). At this point, you will need to answer the questionnaire again, this time for the client machine. In addition, you must type in a challenge password and an optional company name&nbsp;- those do not matter here. When the command completes, you will have a certificate request in the file <EM CLASS="emphasis">
+phoenix-csr.</em></p><P CLASS="para">
+Then, you must sign the certificate request as the trusted certificate authority. Type in the following command:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>ssleay ca -days 1000 -inflies phoenix-csr &gt;phoenix.pem</b></code></pre><P CLASS="para">
+This command will prompt you to enter the PEM pass phrase of the <EM CLASS="emphasis">
+certificate authority</em>. Be sure that you do not enter the PEM pass phrase of the client certificate that you just created. After entering the correct pass phrase, you should see the following:</p><PRE CLASS="programlisting">
+Check that the request matches the signature
+Signature ok
+The Subjects Distinguished Name is as follows:
+...</pre><P CLASS="para">
+This will be followed by the information that you just entered for the client certificate. If there is an error in the fields, the program will notify you. On the other hand, if everything is fine, SSLeay will confirm that it should sign the certificate and commit it to the database. This adds a record of the certificate to the <I CLASS="filename">
+/etc/certificates/newcerts</i> directory.</p><P CLASS="para">
+The operative files at the end of this exercise are the <EM CLASS="emphasis">
+phoenix.key</em> and <EM CLASS="emphasis">
+phoenix.pem </em>files, which reside in the current directory. These files will be passed off to the client with whom the SSL-enabled Samba server will interact, and will be used by SSL Proxy.<I CLASS="firstterm">
+</i></p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986754">A.3.5 Configuring the Samba Server</a></h3><P CLASS="para">
+The next step is to modify the Samba configuration file to include the following setup options. These options assume that you created the certificates directory for the certificate authority at <I CLASS="filename">
+/etc/certificates </i>:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl server cert = /etc/certificates/cacert.pem
+ ssl server key = /etc/certificates/private/cakey.pem
+ ssl CA certDir = /etc/certificates</pre><P CLASS="para">
+At this point, you will need to kill the Samba daemons and restart them manually:</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>nmbd -D</b></code>
+# <CODE CLASS="userinput"><B>smbd -D</b></code>
+Enter PEM pass phrase:</pre><P CLASS="para">
+You will need to enter the PEM pass phrase of the certificate authority to start up the Samba daemons. Note that this may present a problem in terms of starting the program using ordinary means. However, you can get around this using advanced scripting languages, such as Expect or Python.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986870">
+A.3.6 Testing with smbclient</a></h3><P CLASS="para">
+A good way to test whether Samba is working properly is to use the<EM CLASS="emphasis">
+ smbclient</em> program. On the Samba server, enter the following command, substituting the appropriate share and user for a connection:</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>smbclient //hydra/data -U tom</b></code></pre><P CLASS="para">
+You should see several debugging statements followed by a line indicating the negotiated cipher, such as:</p><PRE CLASS="programlisting">
+SSL: negotiated cipher: DES-CBC3-SHA</pre><P CLASS="para">
+After that, you can enter your password and connect to the share normally. If this works, you can be sure that Samba is correctly supporting SSL connections. Now, on to the client setup. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_02.html" TITLE="A.2 Requirements">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.2 Requirements" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_04.html" TITLE="A.4 Setting Up SSL Proxy">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.4 Setting Up SSL Proxy" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+A.2 Requirements</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+A.4 Setting Up SSL Proxy</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appa_04.html b/docs/htmldocs/using_samba/appa_04.html
new file mode 100755
index 00000000000..d4f99e29511
--- /dev/null
+++ b/docs/htmldocs/using_samba/appa_04.html
@@ -0,0 +1,135 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix A] A.4 Setting Up SSL Proxy</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:41Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_03.html" TITLE="A.3 Installing SSLeay">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.3 Installing SSLeay" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+Appendix A<br>
+Configuring Samba with SSL</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_05.html" TITLE="A.5 SSL Configuration Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.5 SSL Configuration Options" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appa-pgfId-986788">
+A.4 Setting Up SSL Proxy</a></h2><P CLASS="para">
+The SSL Proxy program is available as a standalone binary or as source code. You can download it from <A CLASS="systemitem.url" HREF="http://obdev.at/Products/sslproxy.html">
+http://obdev.at/Products/sslproxy.html</a>.</p><P CLASS="para">
+Once it is downloaded, you can configure and compile it like Samba. We will configure it on a Windows NT system. However, setting it up for a Unix system involves a nearly identical series of steps. Be sure that you are the superuser (administrator) for the next series of steps.</p><P CLASS="para">
+If you downloaded the binary for Windows NT, you should have the following files in a directory:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-986793">
+</a><I CLASS="filename">
+cygwinb19.dll</i></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-986794">
+</a><I CLASS="filename">
+README.TXT</i></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-986795">
+</a><I CLASS="filename">
+sslproxy.exe</i></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appa-pgfId-986796">
+</a><I CLASS="filename">
+dummyCert.pem</i></p></li></ul><P CLASS="para">
+The only one that you will be interested in is the SSL Proxy executable. Copy over the <EM CLASS="emphasis">
+phoenix.pem</em> and <EM CLASS="emphasis">
+phoenix.key</em> files that you generated earlier for the client to the same directory as the SSL proxy executable. Make sure that the directory is secure from the prying eyes of other users.</p><P CLASS="para">
+The next step is to ensure that the Windows NT machine can resolve the NetBIOS name of the Samba server. This means that you should either have a WINS server up and running (the Samba server can perform this task with the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+support</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option) or have it listed in the appropriate <EM CLASS="emphasis">
+hosts</em> file of the system. See <a href="ch07_01.html"><b>Chapter 7, <CITE CLASS="chapter">Printing and Name Resolution</cite></b></a>, for more information on WINS server.[<A CLASS="footnote" HREF="#appa-pgfId-986801">1</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="appa-pgfId-986801">[1]</a> If you are running SSL Proxy on a Unix server, you should ensure that the DNS name of the Samba server can be resolved.</p></div></blockquote><P CLASS="para">
+Finally, start up SSL Proxy with the following command. Here, we assume that <CODE CLASS="literal">
+hydra</code> is the name of the Samba server:</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>C:\SSLProxy&gt;sslproxy -l 139 -R hydra -r 139 -n -c phoenix.pem -k phoenix.key</b></code></pre><P CLASS="para">
+This tells SSL Proxy to listen for connections to port 139 and relay those requests to port 139 on the NetBIOS machine <CODE CLASS="literal">
+hydra</code>. It also instructs SSL Proxy to use the <I CLASS="filename">
+phoenix.pem</i> and <I CLASS="filename">
+phoenix.key</i> files to generate the certificate and keys necessary to initiate the SSL connection. SSL Proxy responds with:</p><PRE CLASS="programlisting">
+Enter PEM pass phrase:</pre><P CLASS="para">
+Enter the PEM pass phrase of the client keypair that you generated, <EM CLASS="emphasis">
+not</em> the certificate authority. You should then see the following output:</p><PRE CLASS="programlisting">
+SSL: No verify locations, trying default
+proxy ready, listening for connections</pre><P CLASS="para">
+That should take care of the client. You can place this command in a startup sequence on either Unix or Windows NT if you want this functionality available at all times. Be sure to set any clients you have connecting to the NT server (including the NT server itself) to point to this server instead of the Samba server.</p><P CLASS="para">
+After you've completed setting this up, try to connect using clients that proxy through the NT server. You should find that it works almost transparently.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_03.html" TITLE="A.3 Installing SSLeay">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.3 Installing SSLeay" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_05.html" TITLE="A.5 SSL Configuration Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A.5 SSL Configuration Options" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+A.3 Installing SSLeay</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+A.5 SSL Configuration Options</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appa_05.html b/docs/htmldocs/using_samba/appa_05.html
new file mode 100755
index 00000000000..2048040ec97
--- /dev/null
+++ b/docs/htmldocs/using_samba/appa_05.html
@@ -0,0 +1,460 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix A] A.5 SSL Configuration Options</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:44Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_04.html" TITLE="A.4 Setting Up SSL Proxy">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.4 Setting Up SSL Proxy" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+Appendix A<br>
+Configuring Samba with SSL</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appb_01.html" TITLE="B. Samba Performance Tuning">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B. Samba Performance Tuning" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appa-pgfId-985845">
+A.5 SSL Configuration Options</a></h2><P CLASS="para">
+<A CLASS="xref" HREF="appa_05.html#appa-61150">Table A.1</a> summarizes the configuration options introduced in the previous section for using SSL. Note that all of these options are global in scope; in other words, they must appear in the <CODE CLASS="literal">
+[global]</code> section of the configuration file. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appa-61150">
+Table A.1: SSL Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether SSL mode is enabled with Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl hosts</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of addresses)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of hosts that must always connect using SSL.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl hosts resign</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of addresses)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of hosts that never connect using SS.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl CA certDir</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the directory where the certificates are stored.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl CA certFile</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a file that contains all of the certificates for Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl server cert</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the location of the server's certificate.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl server key</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the location of the server's private key.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl client cert</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the location of the client's certificate.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl client key</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the location of the client's private key.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl require clientcert</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether Samba should require each client to have a certificate.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl require servercert</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether the server itself should have a certificate.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl ciphers</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+String </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the cipher suite to use during protocol negotiation.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl version</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl2or3</code>, <CODE CLASS="literal">
+ssl3</code>, or <CODE CLASS="literal">
+tls1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the version of SSL to use.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl2or3</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ssl compatibility</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether compatibility with other implementations of SSL should be activated.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986013">
+A.5.1 ssl</a></h3><P CLASS="para">
+This global option configures Samba to use SSL for communication between itself and clients. The default value of this option is <CODE CLASS="literal">
+no</code>. You can reset it as follows:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes</pre><P CLASS="para">
+Note that in order to use this option, you must have a proxy for Windows 95/98 clients, such as in the model presented earlier in this chapter.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986018">
+A.5.2 ssl hosts</a></h3><P CLASS="para">
+This option specifies the hosts that will be forced into using SSL. The syntax for specifying hosts and addresses is the same as the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> configuration options. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.</pre><P CLASS="para">
+This example specifies that all hosts that fall into the 192.168.220 subnet must use SSL connections with the client. This type of structure is useful if you know that various connections will be made by a subnet that lies across an untrusted network, such as the Internet. If neither this option nor the <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+resign</code> option has been specified, and <CODE CLASS="literal">
+ssl</code> is set to <CODE CLASS="literal">
+yes</code>, Samba will allow only SSL connections from all clients.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986024">
+A.5.3 ssl hosts resign</a></h3><P CLASS="para">
+This option specifies the hosts that will <EM CLASS="emphasis">
+not</em> be forced into SSL mode. The syntax for specifying hosts and addresses is the same as the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> configuration options. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts resign = 160.2.310. 160.2.320.</pre><P CLASS="para">
+This example specifies that all hosts that fall into the 160.2.310 or 160.2.320 subnets will not use SSL connections with the client. If neither this option nor the <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+hosts</code> option has been specified, and <CODE CLASS="literal">
+ssl</code> is set to <CODE CLASS="literal">
+yes</code>, Samba will allow only SSL connections from all clients.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986030">
+A.5.4 ssl CA certDir</a></h3><P CLASS="para">
+This option specifies the directory containing the certificate authority's certificates that Samba will use to authenticate clients. There must be one file in this directory for each certificate authority, named as specified earlier in this chapter. Any other files in this directory are ignored. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certDir = /usr/local/samba/cert</pre><P CLASS="para">
+There is no default for this option. You can alternatively use the option <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+CA</code> <CODE CLASS="literal">
+certFile</code> if you wish to place all the certificate authority information in the same file.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986037">
+A.5.5 ssl CA certFile</a></h3><P CLASS="para">
+This option specifies a file that contains the certificate authority's certificates that Samba will use to authenticate clients. This option differs from <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+CA</code> <CODE CLASS="literal">
+certDir</code> in that there is only one file used for all the certificate authorities. An example of its usage follows:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile</pre><P CLASS="para">
+There is no default for this option. You can also use the option <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+CA</code> <CODE CLASS="literal">
+certDir</code> if you wish to have a separate file for each certificate authority that Samba trusts.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986044">
+A.5.6 ssl server cert</a></h3><P CLASS="para">
+This option specifies the location of the server's certificate. This option is mandatory; the server must have a certificate in order to use SSL. For example: </p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile
+ ssl server cert = /usr/local/samba/private/server.pem</pre><P CLASS="para">
+There is no default for this option. Note that the certificate may contain the private key for the server.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986052">
+A.5.7 ssl server key</a></h3><P CLASS="para">
+This option specifies the location of the server's private key. You should ensure that the location of the file cannot be accessed by anyone other than <CODE CLASS="literal">
+root</code>. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile
+ ssl server key = /usr/local/samba/private/samba.pem</pre><P CLASS="para">
+There is no default for this option. Note that the private key may be contained in the certificate for the server. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986060">
+A.5.8 ssl client cert</a></h3><P CLASS="para">
+This option specifies the location of the client's certificate. The certificate may be requested by the Samba server with the <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+require</code> <CODE CLASS="literal">
+clientcert</code> option; the certificate is also used by <I CLASS="filename">
+smbclient</i>. For example: </p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile
+ ssl server cert = /usr/local/ssl/private/server.pem
+ ssl client cert= /usr/local/ssl/private/clientcert.pem</pre><P CLASS="para">
+There is no default for this option. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986069">
+A.5.9 ssl client key</a></h3><P CLASS="para">
+This option specifies the location of the client's private key. You should ensure that the location of the file cannot be accessed by anyone other than <CODE CLASS="literal">
+root</code>. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certDir = /usr/local/samba/cert/
+ ssl server key = /usr/local/ssl/private/samba.pem
+ ssl client key = /usr/local/ssl/private/clients.pem</pre><P CLASS="para">
+There is no default for this option. This option is only needed if the client has a certificate. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986078">
+A.5.10 ssl require clientcert</a></h3><P CLASS="para">
+This option specifies whether the client is required to have a certificate. The certificates listed with either the <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+CA</code> <CODE CLASS="literal">
+certDir</code> or the <CODE CLASS="literal">
+ssl</code> <CODE CLASS="literal">
+CA</code> <CODE CLASS="literal">
+certFile</code> will be searched to confirm that the client has a valid certificate and is authorized to connect to the Samba server. The value of this option is a simple boolean. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile
+ ssl require clientcert = yes</pre><P CLASS="para">
+We recommend that you require certificates from all clients that could be connecting to the Samba server. The default value for this option is <CODE CLASS="literal">
+no</code>.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-990571">
+A.5.11 ssl require servercert</a></h3><P CLASS="para">
+This option specifies whether the server is required to have a certificate. Again, this will be used by the <I CLASS="filename">
+smbclient</i> program. The value of this option is a simple boolean. For example:</p><PRE CLASS="programlisting">
+[global]
+ ssl = yes
+ ssl hosts = 192.168.220.
+ ssl CA certFile = /usr/local/samba/cert/certFile
+ ssl require clientcert = yes
+ ssl require servercert = yes</pre><P CLASS="para">
+Although we recommend that you require certificates from all clients that could be connecting to the Samba server, a server certificate is not required. It is, however, recommended. The default value for this option is <CODE CLASS="literal">
+no</code>.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986095">
+A.5.12 ssl ciphers</a></h3><P CLASS="para">
+This option sets the ciphers on which SSL will decide during the negotiation phase of the SSL connection. Samba can use any of the following ciphers:</p><PRE CLASS="programlisting">
+DEFAULT
+DES-CFB-M1
+NULL-MD5
+RC4-MD5
+EXP-RC4-MD5
+RC2-CBC-MD5
+EXP-RC2-CBC-MD5
+IDEA-CBC-MD5
+DES-CBC-MD5
+DES-CBC-SHA
+DES-CBC3-MD5
+DES-CBC3-SHA
+RC4-64-MD5
+NULL</pre><P CLASS="para">
+It is best not to set this option unless you are familiar with the SSL protocol and want to mandate a specific cipher suite.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-986097">
+A.5.13 ssl version</a></h3><P CLASS="para">
+This global option specifies the version of SSL that Samba will use when handling encrypted connections. The default value is <CODE CLASS="literal">
+ssl2or3</code>, which specifies that either version 2 or 3 of the SSL protocol can be used, depending on which version is negotiated in the handshake between the server and the client. However, if you want Samba to use only a specific version of the protocol, you can specify the following:</p><PRE CLASS="programlisting">
+[global]
+ ssl version = ssl3</pre><P CLASS="para">
+Again, it is best not to set this option unless you are familiar with the SSL protocol and want to mandate a specific version.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appa-pgfId-990580">
+A.5.14 ssl compatibility</a></h3><P CLASS="para">
+This global option specifies whether Samba should be configured to use other versions of SSL. However, because no other versions exist at this writing, the issue is moot and the variable should always be left at the default.</p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_04.html" TITLE="A.4 Setting Up SSL Proxy">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.4 Setting Up SSL Proxy" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appb_01.html" TITLE="B. Samba Performance Tuning">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B. Samba Performance Tuning" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">A.4 Setting Up SSL Proxy</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+B. Samba Performance Tuning</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appb_01.html b/docs/htmldocs/using_samba/appb_01.html
new file mode 100755
index 00000000000..4e1ec529af7
--- /dev/null
+++ b/docs/htmldocs/using_samba/appb_01.html
@@ -0,0 +1,162 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix B] Samba Performance Tuning</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:42:02Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_05.html" TITLE="A.5 SSL Configuration Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.5 SSL Configuration Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix B</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_02.html" TITLE="B.2 Samba Tuning">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B.2 Samba Tuning" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="appendix">
+<A CLASS="title" NAME="appb-66714">
+B. Samba Performance Tuning</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#appb-47134" TITLE="B.1 A Simple Benchmark">
+A Simple Benchmark</a><br>
+<A CLASS="sect1" HREF="appb_02.html" TITLE="B.2 Samba Tuning">
+Samba Tuning</a><br>
+<A CLASS="sect1" HREF="appb_03.html" TITLE="B.3 Sizing Samba Servers">
+Sizing Samba Servers</a></p><P>
+</p></div><P CLASS="para">This appendix discusses various ways of performance tuning and system sizing with Samba. <I CLASS="firstterm">
+Performance tuning</i> is the art of finding bottlenecks and adjusting to eliminate them. <EM CLASS="emphasis">
+Sizing</em> is the practice of eliminating bottlenecks by spending money to avoid having them in the first place. Normally, you won't have to worry about either with Samba. On a completely untuned server, Samba will happily support a small community of users. However, on a properly tuned server, Samba will support at least twice as many users. This chapter is devoted to outlining various performance-tuning and sizing techniques that you can use if you want to stretch your Samba server to the limit.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appb-47134">
+B.1 A Simple Benchmark</a></h2><P CLASS="para">How do you know if you're getting reasonable performance? A simple benchmark is to compare Samba with FTP. <A CLASS="xref" HREF="appb_01.html#appb-73167">
+Table B.1</a> shows the throughput, in kilobytes per second, of a pair of servers: a medium-size Sun SPARC Ultra and a small Linux Pentium server. Numbers are reported in kilobytes per second (KB/s). </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-73167">
+Table B.1: Sample Benchmark Benchmarks </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Command</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+FTP</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Untuned Samba</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Tuned Samba</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sparc get</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1014.5</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+645.3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+866.7</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sparc put</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+379.8 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+386.1</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+329.5</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Pentium get</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+973.27</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+N/A</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+725</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Pentium put</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1014.5</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+N/A</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1100</p></td></tr></tbody></table><P CLASS="para">
+If you run the same tests on your server, you probably won't see the same numbers. However, you <EM CLASS="emphasis">
+should </em>see similar ratios of Samba to FTP, probably in the range of 68 to 80 percent. It's not a good idea to base <EM CLASS="emphasis">
+all</em> of Samba's throughput against FTP. The golden rule to remember is this: if Samba is much slower than FTP, it's time to tune it.</p><P CLASS="para">
+You might think that an equivalent test would be to compare Samba to NFS. In reality, however, it's much less useful to compare their speeds. Depending entirely on whose version of NFS you have and how well it's tuned, Samba can be slower or faster than NFS. We usually find that Samba is faster, but watch out; NFS uses a different algorithm from Samba, so tuning options that are optimal for NFS may be detrimental for Samba. If you run Samba on a well-tuned NFS server, Samba may perform rather badly.</p><P CLASS="para">
+A more popular benchmark is Ziff-Davis' <EM CLASS="emphasis">
+NetBench, </em>a simulation of many users on client machines running word processors and accessing data on the SMB server. It's not a prefect measure (each NetBench client does about ten times the work of a normal user on our site), but it is a fair comparison of similar servers. In tests performed by Jeremy Allison in November 1998, Samba 2.0 on a SGI multiprocessor outperformed NT Server 4.0 (Patch Level 2) on an equivalent high-end Compaq. This was confirmed and strengthened by a Sm@rt Reseller test of NT and Linux on identical hardware in February 1999. </p><P CLASS="para">
+In April 1999, the Mindcraft test lab released a report about a test showing that Samba on a four-processor Linux machine was significantly slower than native file serving on the same machine running Windows NT. While the original report was slammed by the Open Source community because it was commissioned by Microsoft and tuned the systems to favor Windows NT, a subsequent test was fairer and generally admitted to reveal some areas where Linux needed to improve its performance, especially on multiprocessors. Little was said about Samba itself. Samba is known to scale well on multiprocessors, and exceeds 440MB/s on a four-processor SGI O200, beating Mindcraft's 310MB/s.</p><P CLASS="para">
+Relative performance will probably change as NT and PC hardware get faster, of course, but Samba is improving as well. For example, Samba 1.9.18 was faster only with more than 35 clients. Samba 2.0, however, is faster regardless of the number of clients. In short, Samba is very competitive with the best networking software in the industry, and is only getting better. </p><P CLASS="para">
+As we went to press, Andrew Tridgell released the alpha-test version suite of benchmarking programs for Samba and SMB networks. Expect even more work on performance from the Samba team in the future.</p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appa_05.html" TITLE="A.5 SSL Configuration Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: A.5 SSL Configuration Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_02.html" TITLE="B.2 Samba Tuning">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B.2 Samba Tuning" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+A.5 SSL Configuration Options</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+B.2 Samba Tuning</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appb_02.html b/docs/htmldocs/using_samba/appb_02.html
new file mode 100755
index 00000000000..4d2ce9ae3aa
--- /dev/null
+++ b/docs/htmldocs/using_samba/appb_02.html
@@ -0,0 +1,342 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix B] B.2 Samba Tuning</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:42:03Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_01.html" TITLE="B.1 A Simple Benchmark">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.1 A Simple Benchmark" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appb_01.html" TITLE="B. Samba Performance Tuning">
+Appendix B<br>
+Samba Performance Tuning</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_03.html" TITLE="B.3 Sizing Samba Servers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B.3 Sizing Samba Servers" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appb-50295">
+B.2 Samba Tuning</a></h2><P CLASS="para">That being said, let's discuss how you can take an already fast networking package and make it even faster.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948325">
+B.2.1 Benchmarking</a></h3><P CLASS="para">Benchmarking is an arcane and somewhat black art, but the level of expertise needed for simple performance tuning is fairly low. Since the Samba server's goal in life is to transfer files, we will examine only throughput, not response time to particular events, under the benchmarking microscope. After all, it's relatively easy to measure file transfer speed, and Samba doesn't suffer too badly from response-time problems that would require more sophisticated techniques. </p><P CLASS="para">
+Our basic strategy for this work will be:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948328">
+</a>Find a reasonably-sized file to copy and a program that reports on copy speeds, such as <I CLASS="filename">
+smbclient</i>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948329">
+</a>Find a quiet (or typical) time to do the test.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948330">
+</a>Pre-run each test a few times to preload buffers.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948331">
+</a>Run tests several times and watch for unusual results.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948332">
+</a>Record each run in detail.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-948333">
+</a>Compare the average of the valid runs to expected values.</p></li></ul><P CLASS="para">
+After establishing a baseline using this method, we can adjust a single parameter and do the measurements all over again. An empty table for your tests is provided at the end of this chapter.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948336">
+B.2.2 Things to Tweak</a></h3><P CLASS="para">
+There are literally thousands of Samba setting combinations that you can use in search of that perfect server. Those of us with lives outside of system administration, however, can narrow down the number of options to those listed in this section, which are the most likely to affect overall throughput. They are presented roughly in order of impact.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948339">
+B.2.2.1 Log level</a></h4><P CLASS="para">This is an obvious one. Increasing the logging level (<CODE CLASS="literal">log</code> <CODE CLASS="literal">
+level</code> or <CODE CLASS="literal">
+debug</code> <CODE CLASS="literal">
+level</code> configuration options) is a good way to debug a problem, unless you happen to be searching for a performance problem! As mentioned in <a href="ch04_01.html"><b>Chapter 4, <CITE CLASS="chapter">Disk Shares</cite></b></a>, Samba produces a ton of debugging messages at level 3 and above, and writing them to disk or syslog is a slow operation. In our <I CLASS="filename">
+smbclient/ftp</i> tests, raising the log level from 0 to 3 cut the untuned <CODE CLASS="literal">
+get</code> <CODE CLASS="literal">
+speed</code> from 645.3 to 622.2KB/s, or roughly 5 percent. Higher log levels were even worse.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948342">
+B.2.2.2 Socket options</a></h4><P CLASS="para">
+The next thing to look at are the <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+options</code> configuration options. These are really host system tuning options, but they're set on a per-connection basis, and can be reset by Samba on the sockets it employs by adding <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+options</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+option</code> to the <CODE CLASS="literal">
+[global]</code> section of your <I CLASS="filename">
+smb.conf </i>file. Not all of these options are supported by all vendors; check your vendor's manual pages on <I CLASS="function">
+setsockopt </i>(1) or <I CLASS="function">
+socket </i>(5) for details.</p><P CLASS="para">
+The main options are:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<CODE CLASS="literal">
+TCP_NODELAY</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Have the server send as many packets as necessary to keep delay low. This is used on telnet connections to give good response time, and is used&nbsp;- somewhat counter-intuitively&nbsp;- to get good speed even when doing small requests or when acknowledgments are delayed (as seems to occur with Microsoft TCP/IP). This is worth a 30-50 percent speedup by itself. Incidentally, in Samba 2.0.4, <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+options</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+TCP_NODELAY</code> became the default value for that option.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+IPTOS_LOWDELAY</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+This is another option that trades off throughput for lower delay, but which affects routers and other systems, not the server. All the IPTOS options are new; they're not supported by all operating systems and routers. If they are supported, set <CODE CLASS="literal">
+IPTOS_LOWDELAY</code> whenever you set <CODE CLASS="literal">
+TCP_NODELAY</code>.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+SO_SNDBUF</code> <CODE CLASS="literal">
+and</code> <CODE CLASS="literal">
+SO_RCVBUF</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+The send and receive buffers can often be the reset to a value higher than that of the operating system. This yields a marginal increase of speed (until it reaches a point of diminishing returns). </p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+SO_KEEPALIVE</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+This initiates a periodic (four-hour) check to see if the client has disappeared. Expired connections are addressed somewhat better with Samba's <CODE CLASS="literal">
+keepalive</code> and <CODE CLASS="literal">
+dead</code> <CODE CLASS="literal">
+time</code> options. All three eventually arrange to close dead connections, returning unused memory and process-table entries to the operating system.</p></dd></dl><P CLASS="para">
+There are several other socket options you might look at, (e.g., <CODE CLASS="literal">
+SO_SNDLOWAT</code>), but they vary in availability from vendor to vendor. You probably want to look at <CITE CLASS="citetitle">
+TCP/IP Illustrated</cite> if you're interested in exploring more of these options for performance tuning with Samba.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948370">
+B.2.2.3 read raw and write raw</a></h4><P CLASS="para">These are important performance configuration options; they enable Samba to use large reads and writes to the network, of up to 64KB in a single SMB request. They also require the largest SMB packet structures, <CODE CLASS="literal">
+SMBreadraw</code> and <CODE CLASS="literal">
+SMBwriteraw</code>, from which the options take their names. Note that this is not the same as a Unix <EM CLASS="emphasis">
+raw read</em>. This Unix term usually refers to reading disks without using the files system, quite a different sense from the one described here for Samba.</p><P CLASS="para">
+In the past, some client programs failed if you tried to use <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+raw</code>. As far as we know, no client suffers from this problem any more. Read and write raw default to <CODE CLASS="literal">
+yes</code>, and should be left on unless you find you have one of the buggy clients.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948374">
+B.2.2.4 Opportunistic locking</a></h4><P CLASS="para">Opportunistic locks, or <EM CLASS="emphasis">
+oplocks</em>, allow clients to cache files locally, improving performance on the order of 30 percent. This option is now enabled by default. For read-only files, the <CODE CLASS="literal">
+fake</code> <CODE CLASS="literal">
+oplocks</code> provides the same functionality without actually doing any caching. If you have files that cannot be cached, <EM CLASS="emphasis">
+oplocks</em> can be turned off.</p><P CLASS="para">
+Database files should never be cached, nor should any files that are updated both on the server and the client and whose changes must be immediately visible. For these files, the <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+oplock</code> <CODE CLASS="literal">
+files</code> option allows you to specify a list of individual files or a pattern containing wildcards to avoid caching. <EM CLASS="emphasis">
+oplocks</em> can be turned off on a share-by-share basis if you have large groups of files you don't want cached on clients. See <a href="ch05_01.html"><b>Chapter 5, <CITE CLASS="chapter">Browsing and Advanced Disk Shares</cite></b></a>, for more information on opportunistic locks.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948378">
+B.2.2.5 IP packet size (MTU)</a></h4><P CLASS="para">Networks generally set a limit to the size of an individual transmission or packet This is called the Maximum Segment Size, or if the packet header size is included, the Maximum Transport Unit (MTU). This MTU is not set by Samba, but Samba needs to use a <CODE CLASS="literal">
+max</code> <CODE CLASS="literal">
+xmit</code> (write size) bigger than the MTU, or throughput will be reduced. This is discussed in further detail in the following note. The MTU is normally preset to 1500 bytes on an Ethernet and 4098 bytes on FDDI. In general, having it too low cuts throughput, and having it too high causes a sudden performance dropoff due to fragmentation and retransmissions.</p><P CLASS="para">
+If you are communicating over a router, some systems will assume the router is a serial link (e.g., a T1) and set the MTU to more or less 536 bytes. Windows 95 makes this mistake, which causes nearby clients to perform well, but clients on the other side of the router to be noticeably slower. If the client makes the opposite error and uses a large MTU on a link which demands a small one, the packets will be broken up into fragments. This slows transfers slightly, and any networking errors will cause multiple fragments to be retransmitted, which slows Samba significantly. Fortunately, you can modify the Windows MTU size to prevent either error. To understand this in more detail, see "The Windows 95 Networking Frequently Asked Questions (FAQ)" at <A CLASS="systemitem.url" HREF="http://www.stanford.edu/~llurch/win95netbugs/faq.html">
+http://www.stanford.edu/~llurch/win95netbugs/faq.html</a>, which explains how to override the Windows MTU and Window Size.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-19919">
+<a name="b226"></a>
+B.2.2.6 The TCP receive window</a></h4><P CLASS="para">TCP/IP works by breaking down data into small packets that can be transmitted from one machine to another. When each packet is transmitted, it contains a checksum that allows the receiver to check the packet data for potential errors in transmission. Theoretically, when a packet is received and verified, an acknowledgment packet should be sent back to the sender that essentially says, "Everything arrived intact: please continue."</p><P CLASS="para">
+In order to keep things moving, however, TCP accepts a range (window) of packets that allows a sender to keep transmitting without having to wait for an acknowledgment of every single packet. (It can then bundle a group of acknowledgments and transmit them back to the sender at the same time.) In other words, this receive window is the number of bytes that the sender can transmit before it has to stop and wait for a receiver's acknowledgment. Like the MTU, it is automatically set based on the type of connection. Having the window too small causes a lot of unnecessary waiting for acknowledgment messages. Various operating systems set moderate buffer sizes on a per-socket basis to keep one program from hogging all the memory.</p><P CLASS="para">
+The buffer sizes are assigned in bytes, such as <CODE CLASS="literal">
+SO_SNDBUF=8192</code> in the <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+options</code> line. Thus, an example <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+options</code> configuration option is: </p><PRE CLASS="programlisting">
+<CODE CLASS="literal">socket</code> <CODE CLASS="literal">options</code> <CODE CLASS="literal">=</code> <CODE CLASS="literal">SO_SNDBUF=8192</code> </pre><P CLASS="para">
+Normally, one tries to set these socket options higher than the default: 4098 in SunOS 4.1.3 and SVR4, and 8192-16384 in AIX, Solaris, and BSD. 16384 has been suggested as a good starting point: in a non-Samba test mentioned in Stevens' book, it yielded a 40 percent improvement. You'll need to experiment, because performance will fall off again if you set the sizes too high. This is illustrated in <A CLASS="xref" HREF="appb_02.html#appb-34738">
+Figure B.1</a>, a test done on a particular Linux system. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="appb-34738">
+Figure B.1: SO_SNDBUF size and performance</a></h4><IMG CLASS="graphic" SRC="figs/sam.ab01.gif" ALT="Figure B.1"><P CLASS="para">
+Setting the socket options <CODE CLASS="literal">
+O_SNDBUF</code> and <CODE CLASS="literal">
+SO_RCVBUF</code> to less than the default is inadvisable. Setting them higher improves performance, up to a network-specific limit. However, once you exceed that limit, performance will abruptly level off.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-960372">
+B.2.2.7 max xmit</a></h4><P CLASS="para">In Samba, the option that is directly related with the MTU and window size is <CODE CLASS="literal">
+max</code> <CODE CLASS="literal">
+xmit</code>. This option sets the largest block of data Samba will try to write at any one time. It's sometimes known as the <I CLASS="firstterm">
+write size</i>, although that is not the name of the Samba configuration option.</p><P CLASS="para">
+Because the percentage of each block required for overhead falls as the blocks get larger, max xmit is conventionally set as large as possible. It defaults to the protocol's upper limit, which is 64 kilobytes. The smallest value that doesn't cause significant slowdowns is 2048. If it is set low enough, it will limit the largest packet size that Samba will be able to negotiate. This can be used to simulate a small MTU if you need to test an unreliable network connection. However, such a test should not be used in production for reducing the effective MTU.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948396">
+B.2.2.8 read size</a></h4><P CLASS="para">If <CODE CLASS="literal">
+max</code> <CODE CLASS="literal">
+xmit</code> is commonly called the write size, you'd expect <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+size</code> to be the maximum amount of data that Samba would want to read from the client via the network. Actually, it's not. In fact, it's an option to trigger <I CLASS="firstterm">
+write ahead</i>. This means that if Samba gets behind reading from the disk and writing to the network (or vice versa) by the specified amount, it will start overlapping network writes with disk reads (or vice versa).</p><P CLASS="para">
+The read size doesn't have a big performance effect on Unix, unless you set its value quite small. At that point, it causes a detectable slowdown. For this reason, it defaults to 2048 and can't be set lower than 1024.</p></div><DIV CLASS="sect3">
+
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-950907">
+B.2.2.9 read prediction </a></h4>
+
+<P CLASS="para">Besides being counterintuitive, this option is also
+obsolete. It enables Samba to read ahead on files opened read only by the
+clients. The option is disabled in Samba 2.0 (and late 1.9) because it
+interferes with opportunistic locking.</p>
+
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-950907-add1">
+B.2.2.10 write cache size </a></h4>
+
+<P CLASS="para">
+This parameter was introduced in Samba 2.0.7 to allow tuning the
+write-size of RAID disks, as well as allowing general caching of
+writes on machines with lots of memory but slow disks.</p>
+
+<p> It specifies in bytes the size of a per-file write cache that
+Samba will create for an oplocked file. This can improve performance
+significantly by causing writes to be done in large
+chunk sizes. </p>
+
+<p> Up to 10 write caches can be active simultaneously per smbd, each of
+the specified size, allocated to the first 10 oplocked files. As with
+other filesystem caches, crashing before the data is written can corrupt
+files. </P>
+
+<p> Setting <CODE CLASS="literal"> sync always </CODE> will override the
+write caching, and setting <CODE CLASS="literal">strict sync</CODE> will
+allow Windows clients to override it. Alas, Windows Explorer defaults
+to setting the sync bit, so setting <CODE CLASS="literal">strict sync</CODE>
+can be a big performance hit.</p>
+
+<p> As it's new, we haven't many reports on the performance increase, and
+merely suspect it will be considerable.</p>
+</div></div><DIV CLASS="sect2">
+
+
+
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948407">
+B.2.3 Other Samba Options</a></h3><P CLASS="para">The following Samba options will affect performance if they're set incorrectly, much like the debug level. They're mentioned here so you will know what to look out for:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<CODE CLASS="literal">hide files</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Providing a pattern to identify files hidden by the Windows client <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> will result in any file matching the pattern being passed to the client with the DOS hidden attribute set. It requires a pattern match per file when listing directories, and slows the server noticeably.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+lpq cache time</code></dt><DD CLASS="listitem">
+<P CLASS="para">If your <CODE CLASS="literal">
+lpq</code> (printer queue contents) command takes a long time to complete, you should increase <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+cache</code> <CODE CLASS="literal">
+time</code> to a value higher than the actual time required for <CODE CLASS="literal">
+lpq</code> to execute, so as to keep Samba from starting a new query when one's already running. The default is 10 seconds, which is reasonable.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+strict locking</code></dt><DD CLASS="listitem">
+<P CLASS="para">Setting the <CODE CLASS="literal">
+strict</code> <CODE CLASS="literal">
+locking</code> option causes Samba to check for locks on every access, not just when asked to by the client. The option is primarily a bug-avoidance feature, and can prevent ill-behaved DOS and Windows applications from corrupting shared files. However, it is slow and should typically be avoided.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+strict sync</code></dt><DD CLASS="listitem">
+<P CLASS="para">Setting <CODE CLASS="literal">
+strict</code> <CODE CLASS="literal">
+sync</code> will cause Samba to write each packet to disk and wait for the write to complete whenever the client sets the sync bit in a packet. Windows 98 Explorer sets the bit in all packets transmitted, so if you turn this on, anyone with Windows 98 will think Samba servers are horribly slow.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+sync always</code></dt><DD CLASS="listitem">
+<P CLASS="para">Setting <CODE CLASS="literal">
+sync</code> <CODE CLASS="literal">
+always</code> causes Samba to flush every write to disk. This is good if your server crashes constantly, but the performance costs are immense. SMB servers normally use oplocks and automatic reconnection to avoid the ill effects of crashes, so setting this option is not normally necessary.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">wide links</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Turning off <CODE CLASS="literal">
+wide</code> <CODE CLASS="literal">
+links</code> prevents Samba from following symbolic links in one file share to files that are not in the share. It is turned on by default, since following links in Unix is not a security problem. Turning it off requires extra processing on every file open. If you do turn off wide links, be sure to turn on <CODE CLASS="literal">
+getwd</code> <CODE CLASS="literal">
+cache</code> to cache some of the required data.</p><P CLASS="para">
+There is also a <CODE CLASS="literal">
+follow</code> <CODE CLASS="literal">
+symlinks</code> option that can be turned off to prevent following any symbolic links at all. However, this option does not pose a performance problem.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">getwd cache</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+This option caches the path to the current directory, avoiding long tree-walks to discover it. It's a nice performance improvement on a printer server or if you've turned off <CODE CLASS="literal">
+wide</code> <CODE CLASS="literal">
+links</code>.</p></dd></dl></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948430">
+B.2.4 Our Recommendations </a></h3><P CLASS="para">Here's an <I CLASS="filename">
+smb.conf</i> file that incorporates the recommended performance enhancements so far. Comments have been added on the right side.</p><PRE CLASS="programlisting">
+[global]
+ log level = 1 # Default is 0
+ socket options = TCP_NODELAY IPTOS_LOWDELAY
+ read raw = yes # Default
+ write raw = yes # Default
+ oplocks = yes # Default
+ max xmit = 65535 # Default
+ dead time = 15 # Default is 0
+ getwd cache = yes
+ lpq cache = 30
+[okplace]
+ veto oplock files = this/that/theotherfile
+[badplace]
+ oplocks = no</pre></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_01.html" TITLE="B.1 A Simple Benchmark">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.1 A Simple Benchmark" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_03.html" TITLE="B.3 Sizing Samba Servers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: B.3 Sizing Samba Servers" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+B.1 A Simple Benchmark</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+B.3 Sizing Samba Servers</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appb_03.html b/docs/htmldocs/using_samba/appb_03.html
new file mode 100755
index 00000000000..115be4daa37
--- /dev/null
+++ b/docs/htmldocs/using_samba/appb_03.html
@@ -0,0 +1,876 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix B] B.3 Sizing Samba Servers</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:42:12Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_02.html" TITLE="B.2 Samba Tuning">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.2 Samba Tuning" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="appendix" REL="up" HREF="appb_01.html" TITLE="B. Samba Performance Tuning">
+Appendix B<br>
+Samba Performance Tuning</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appc_01.html" TITLE="C. Samba Configuration Option Quick Reference">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: C. Samba Configuration Option Quick Reference" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="appb-22511">
+B.3 Sizing Samba Servers</a></h2><P CLASS="para">Sizing is a way to prevent bottlenecks before they occur. The preferred way to do this is to know how many requests per second or how many kilobytes per second the clients will need, and ensure that all the components of the server provide at least that many.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948449">
+B.3.1 The Bottlenecks</a></h3><P CLASS="para">The three primary bottlenecks you should worry about are CPU, disk I/O, and the network. For most machines, CPUs are rarely a bottleneck. A single Sun SPARC 10 CPU can start (and complete) between 700 and 800 I/O operations a second, giving approximately 5,600 to 6,400KB/s of throughput when the data averages around 8KBs (a common buffer size). A single Intel Pentium 133 can do less only because of somewhat slower cache and bus interfaces, not due to lack of CPU power. Purpose-designed Pentium servers, like some Compaq servers, will be able to start 700 operations per CPUs, on up to four CPUs.</p><P CLASS="para">
+Too little memory, on the other hand, can easily be a bottleneck; each Samba process will use between 600 and 800KB on Intel Linux, and more on RISC CPUs. Having less will cause an increase in virtual memory paging and therefore a performance hit. On Solaris, where it has been measured, <EM CLASS="emphasis">
+smbd</em> will use 2.6 MB for program and shared libraries, plus 768KB for each connected client. <EM CLASS="emphasis">
+nmbd</em> occupies 2.1 MB, plus 496KB extra for its (single) auxiliary process.</p><P CLASS="para">
+Hard disks will always bottleneck at a specific number of I/O operations per second: for example, each 7200 RPM SCSI disk is capable of performing 70 operations per second, for a throughput of 560KB/s; a 4800 RPM disk will perform fewer than 50, for a throughput of 360KB/s. A single IDE disk will do still fewer. If the disks are independent, or striped together in a RAID 1 configuration, they will each peak out at 400 to 560KB/s and will scale linearly as you add more. Note that this is true only of RAID 1. RAID levels other than 1 (striping) add extra overhead. </p><P CLASS="para">
+Ethernets (and other networks) are obvious bottleneck: a 10 Mb/s (mega<EM CLASS="emphasis">
+bits</em>/second) Ethernet will handle around 1100KB/s (kilo<EM CLASS="emphasis">
+bytes</em>/s) using 1500-byte packets A 100 Mb/s Fast Ethernet will bottleneck below 65,000KB/s with the same packet size. FDDI, at 155 Mb/s will top out at approximately 6,250KB/s, but gives good service at even 100 percent load and transmits much larger packets (4KB).</p><P CLASS="para">
+ATM should be much better, but as of the writing of this book it was too new to live up to its potential; it seems to deliver around 7,125 Mb/s using 9KB packets. </p><P CLASS="para">
+Of course, there can be other bottlenecks: more than one IDE disk per controller is not good, as are more than three 3600 SCSI-I disks per slow/narrow controller, or more than three 7200 SCSI-II disks per SCSI-II fast/wide controller. RAID 5 is also slow, as it requires twice as many writes as independent disks or RAID 1.</p><P CLASS="para">
+After the second set of Ethernets and the second disk controller, start worrying about bus bandwidth, especially if you are using ISA/EISA buses.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948459">
+B.3.2 Reducing Bottlenecks </a></h3><P CLASS="para">From the information above we can work out a model that will tell us the maximum capability of a given machine. The data is mostly taken from Brian Wong's <CITE CLASS="citetitle">
+Configuration and Capacity Planning for Solaris Servers</cite>,<CITE CLASS="citetitle">
+[<A CLASS="footnote" HREF="#appb-pgfId-951214">1</a>]</cite> so there is a slight Sun bias to our examples.</p><P CLASS="para">
+A word of warning: this is not a complete model. Don't assume that this model will predict every bottleneck or even be within 10 percent in its estimates. A model to predict performance instead of one to warn you of bottlenecks would be much more complex and would contain rules like "not more than three disks per SCSI chain". (A good book on real models is Raj Jain's <CITE CLASS="citetitle">
+The Art of Computer Systems Performance Analysis</cite>.[<A CLASS="footnote" HREF="#appb-pgfId-951230">2</a>]) With that warning, we present the system in <A CLASS="xref" HREF="appb_03.html#appb-98866">
+Figure B.2</a>. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="appb-pgfId-951230">[2]</a> See Jain. Raj, <EM CLASS="emphasis">
+The Art of Computer Systems Performance Analysis</em>, New York, NY (John Wiley and Sons), 1991, ISBN 0-47-150336-3.</p></div></blockquote><H4 CLASS="figure">
+<A CLASS="title" NAME="appb-98866">
+Figure B.2: Data flow through a Samba server, with possible bottlenecks</a></h4><IMG CLASS="graphic" SRC="figs/sam.ab02.gif" ALT="Figure B.2"><P CLASS="para">
+The flow of data should be obvious. For example, on a read, data flows from the disk, across the bus, through or past the CPU, and to the network interface card (NIC). It is then broken up into packets and sent across the network. Our strategy here is to follow the data through the system and see what bottlenecks will choke it off. Believe it or not, it's rather easy to make a set of tables that list the maximum performance of common disks, CPUs, and network cards on a system. So that's exactly what we're going to do.</p><P CLASS="para">
+Let's take a concrete example: a Linux Pentium 133 MHz machine with a single 7200 RPM data disk, a PCI bus, and a 10-Mb/s Ethernet card. This is a perfectly reasonable server. We start with <A CLASS="xref" HREF="appb_03.html#appb-78077">
+Table B.2</a>, which describes the hard drive&nbsp;- the first potential bottleneck in the system. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-78077">
+Table B.2: Disk Throughput </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Disk RPM</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+I/O Operations/second</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+KB/second</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+7200</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+70</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+560</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4800</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+60</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+480</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3600</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+40</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+320</p></td></tr></tbody></table><P CLASS="para">
+Disk throughput is the number of kilobytes of data that a disk can transfer per second. It is computed from the number of 8KB I/O operations per second a disk can perform, which in turn is strongly influenced by disk RPM and bit density. In effect, the question is: how much data can pass below the drive heads in one second? With a single 7200 RPM disk, the example server will give us 70 I/O operations per second at roughly 560KB/s.</p><P CLASS="para">
+The second possible bottleneck is the CPU. The data doesn't actually flow through the CPU on any modern machines, so we have to compute throughput somewhat indirectly.</p><P CLASS="para">
+The CPU has to issue I/O requests and handle the interrupts coming back, then transfer the data across the bus to the network card. From much past experimentation, we know that the overhead that dominates the processing is consistently in the filesystem code, so we can ignore the other software being run. We compute the throughput by just multiplying the (measured) number of file I/O operations per second that a CPU can process by the same 8K average request size. This gives us the results shown in <A CLASS="xref" HREF="appb_03.html#appb-42029">
+Table B.3</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-42029">
+Table B.3: CPU Throughput </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+CPU</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+I/O Operations/second</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+KB/second</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Intel Pentium 133</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+700</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+5,600</p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Dual Pentium 133</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1,200</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+9,600</p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sun SPARC II</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+660</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+5,280</p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sun SPARC 10</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+750</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6,000</p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sun Ultra 200</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2,650</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+21,200</p>
+</td></tr></tbody></table><P CLASS="para">
+Now we put the disk and the CPU together: in the Linux example, we have a single 7200 RPM disk, which can give us 560KB/s, and a CPU capable of starting 700 I/O operations, which could give us 5600KB/s. So far, as you would expect, our bottleneck is clearly going to be the hard disk.</p><P CLASS="para">
+The last potential bottleneck is the network. If the network speed is below 100 Mb/s, the bottleneck will be the network speed. After that, the design of the network card is more likely to slow us down. <A CLASS="xref" HREF="appb_03.html#appb-67604">
+Table B.4</a> shows us the average throughput of many types of data networks. Although network speed is conventionally measured in bits per second, <A CLASS="xref" HREF="appb_03.html#appb-67604">
+Table B.4</a> lists bytes per second to make comparison with the disk and CPU (<A CLASS="xref" HREF="appb_03.html#appb-78077">Table B.2</a> and <A CLASS="xref" HREF="appb_03.html#appb-42029">
+Table B.3</a>) easier.</p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-67604">
+Table B.4: Network Throughput </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Type</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+KB/second</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ ISDN </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 16 </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ T1 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 197 </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ Ethernet 10m </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 1,113 </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ Token ring </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 1,500 </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ FDDI </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 6,250 </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ Ethernet 100m </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 6,500[<A CLASS="footnote" HREF="#appb-pgfId-960131">3</a>]</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ ATM 155 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ 7,125a </p></td></tr></tbody></table><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="appb-pgfId-960131">[3]</a> These will increase. For example, Crays, Sun Ultras, and DEC/Compaq Alphas already have bettered these figures.</p></div></blockquote><P CLASS="para">
+In the running example, we have a bottleneck at 560KB/s due to the disk. <A CLASS="xref" HREF="appb_03.html#appb-67604">
+Table B.4</a> shows us that a standard 10 megabit per second Ethernet (1,113KB/s) is far faster than the disk. Therefore, the hard disk is still the limiting factor. (This scenario, by the way, is very common.) Just by looking at the tables, we can predict that small servers won't have CPU problems, and that large ones with multiple CPUs will support striping and multiple Ethernets long before they start running out of CPU power. This, in fact, is exactly what happens.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948657">
+B.3.3 Practical Examples</a></h3><P CLASS="para">
+An example from <EM CLASS="emphasis">
+Configuration and Capacity Planning for Solaris Servers</em> (Wong) shows that a dual-processor SPARCstation 20/712 with four Ethernets and six 2.1 GB disks will spend all its time waiting for the disks to return some data. If it was loaded with disks (Brian Wong suggests as many as 34 of them), it would still be held below 1,200KB/s by the Ethernet cards. To get the performance the machine is capable of, we would need to configure multiple Ethernets, 100 Mbps Fast Ethernet, or 155 Mbps FDDI. </p><P CLASS="para">
+The progression you'd work through to get that conclusion looks something like <A CLASS="xref" HREF="appb_03.html#appb-26613">
+Table B.5</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-26613">
+Table B.5: Tuning a Medium-Sized Server </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Machine</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Disk Throughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+CPU Throughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Throughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Actual Throughput</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Dual SPARC 10, 1 disk </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+560</em></p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6000 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1,113 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+560 </p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Add 5 more disks </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3,360 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6000</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+1,113 </em></p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1,113 </p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Add 3 more Ethernets </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+3,360 </em></p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+16000</p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4,452 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3,360 </p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Change to using a 20-disk array </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+11,200 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6000 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+4,452</em> </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4,452 </p>
+</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Use dual 100 Mbps ether </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+11,200 </em></p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6000 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+13,000 </p>
+</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+11,200</p>
+</td></tr></tbody></table><P CLASS="para">
+Initially, the bottleneck is the disk with only 560 MB/s of throughput available. Our solution is to add five more disks. This gives us more throughput on the disks than on the Ethernet, so then the Ethernet becomes the problem. Consequently, as we continue to expand, we go back and forth several times between these two. As you add disks, CPUs, and network cards, the bottleneck moves. Essentially, the strategy is to add more equipment to try to avoid each bottleneck until you reach your target performance, or (unfortunately) you either can't add any more or run out of money.</p><P CLASS="para">
+Our experience bears out this kind of calculation; a large SPARC 10 file server that one author maintained was quite capable of saturating an Ethernet plus about a third of an FDDI ring when using two processors. It did nearly as well with a single processor, albeit with a fast operating system and judicious over-optimization.</p><P CLASS="para">
+The same process applies to other brands of purpose-designed servers. We found the same rules applied to DECstation 2100s as to the newest Alphas or Compaqs, old MIPS 3350s and new SGI O2s. In general, a machine offering multi-CPU server configurations will have enough bus bandwidth and CPU power to reliably bottleneck on hard disk I/O when doing file service. As one would hope, considering the cost!</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-pgfId-948730">
+B.3.4 How Many Clients can Samba Handle?</a></h3><P CLASS="para">
+Well, that depends entirely on how much data each user consumes. A small server with three SCSI-1 disks, which can serve about 960KB/s of data, will support between 36 and 80 clients in an ordinary office environment where they are typically loading, and saving equal-sized spreadsheets or word processing documents (36 clients × 2.3 transfers/second × 12k file 1 MB/s).</p><P CLASS="para">
+On the same server in a development environment with programmers running a fairly heavy edit-compile-test cycle, one can easily see requests for 1 MB/s, limiting the server to 25 or fewer clients. To take this a bit further, an imaging system whose clients each require 10 MB/s will perform poorly no matter how big a server is if they're all on a 10 MB/s Ethernet. And so on. </p><P CLASS="para">
+If you don't know how much data an average user consumes, you can size your Samba servers by patterning them after existing NFS, Netware, or LAN Manager servers. You should be especially careful that the new servers have as many disks and disk controllers as the ones you've copied. This technique is appropriately called "punt and hope."</p><P CLASS="para">
+If you know how many clients an existing server can support, you're in <EM CLASS="emphasis">
+much</em> better shape. You can analyze the server to see what its maximum capacity is and use that to estimate how much data they must be demanding. For example, if serving home directories to 30 PCs from a PC server with two IDE disks is just too slow, and 25 clients is about right, then you can safely assume you're bottlenecked on Ethernet I/O (approximately 375KB) rather than disk I/O (up to 640KB). If so, you can then conclude that the clients are demanding 15 (that is, 375/25)KB/s on average.</p><P CLASS="para">
+Supporting a new lab of 75 clients will mean you'll need 1,125KB/s, spread over multiple (preferably three) Ethernets, and a server with at least three 7200 RPM disks and a CPU capable of keeping up. These requirements can be met by a Pentium 133 or above with the bus architecture to drive them all at full speed (e.g., PCI).</p><P CLASS="para">
+A custom-built PC server or a multiprocessor-capable workstation like a Sun Sparc, a DEC/Compaq Alpha, an SGI, or the like, would scale up easier, as would a machine with fast Ethernet, plus a switching hub to drive the client machines on individual 10 MB/s Ethernets.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="appb-pgfId-948739">
+B.3.4.1 How to guess</a></h4><P CLASS="para">
+If you have no idea at all what you need, the best thing is to try to guess based on someone else's experience. Each individual client machine can average from less than 1 I/O per second (normal PC or Mac used for sales/accounting) to as much as 4 (fast workstation using large applications). A fast workstation running a compiler can happily average 3-4 MB/s in data transfer requests, and an imaging system can demand even more. </p><P CLASS="para">
+Our recommendation? Spy on someone with a similar configuration and try to estimate their bandwidth requirements from their bottlenecks and the volume of the screams from their users. We also recommend Brian Wong's <CITE CLASS="citetitle">
+Configuration and Capacity Planning for Solaris Servers</cite>. While he uses Sun Solaris foremost in his examples, his bottlenecks are disks and network cards, which are common among all the major vendors. His tables for FTP servers also come very close to what we calculated for Samba servers, and make a good starting point.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="appb-90359">B.3.5 Measurement Forms</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="appb_03.html#appb-82208">Table B.6</a> and <A CLASS="xref" HREF="appb_03.html#appb-34846">
+Table B.7</a> are empty tables that you can use for copying and recording data. The bottleneck calculation in the previous example can be done in a spreadsheet, or manually with Table B-8. If Samba is as good as or better than FTP, and if there aren't any individual test runs that are much different from the average, you have a well-configured system. If loopback isn't much faster than anything else, you have a problem with your TCP/IP software. If both FTP and Samba are slow, you probably have a problem with your networking: a faulty Ethernet card will produce this, as will accidentally setting an Ethernet card to half-duplex when it's not connected to a half-duplex hub. Remember that CPU and disk speeds are commonly measured in bytes, network speeds in bits. </p><P CLASS="para">
+We've included columns for both bytes and bits in the tables. In the last column, we compare results to 10 Mb/s because that's the speed of a traditional Ethernet. <EM CLASS="emphasis">
+ </em></p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-82208">
+Table B.6: Ethernet Interface to Same Host: FTP </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Run No</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Size in Bytes</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Time (sec) </p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bytes/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bits/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+% of 10 Mb/s</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+5</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Average:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deviation:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr></tbody></table><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-34846">
+Table B.7: Ethernet Interface to Same Host: FTP </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Run No</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Size in Bytes</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Time, sec </p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bytes/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bits/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+% of 10 Mb/s</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+5</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Average:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deviation:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr></tbody></table><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-51003">
+Table B.8: Bottleneck Calculation Table</a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+CPU</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+CPUThroughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Number of Disks</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Disk Throughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Number of Networks</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Throughput</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Total Throughput</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr></tbody></table><P CLASS="para">
+In <A CLASS="xref" HREF="appb_03.html#appb-51003">
+Table B.8</a>:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-960325">
+</a>CPU throughput = (KB/second from Figure 6-5) × (number of CPUs)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-960301">
+</a>Disk throughput = (KB/second from Figure 6-4) × (number of disks)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-960305">
+</a>Network throughput = (KB/second from Figure 6-6) × (number of networks)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="appb-pgfId-960306">
+</a>Total throughput = min (Disk, CPU, and Network throughput)</p></li></ul><P CLASS="para">
+A typical test, in this case for an FTP <CODE CLASS="literal">
+get</code>, would be entered as in Table B-9: <EM CLASS="emphasis">
+ </em> </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appb-37370">
+Table B.9: Ethernet Interface to Same Host: FTP </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Run No</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Size in Bytes</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Time, sec </p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bytes/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Bits/sec</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+% of 10 Mb/s</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1812898</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+761580</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+767820</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.4</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+747420</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+760020</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+5</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+772700</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Average:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2.32</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+777310</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+6218480</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+62</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deviation:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+0.04</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr></tbody></table><P CLASS="para">
+The Sparc example we used earlier would look like Table B-10. <EM CLASS="emphasis">
+ </em> </p><P CLASS="para">
+</p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_02.html" TITLE="B.2 Samba Tuning">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.2 Samba Tuning" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appc_01.html" TITLE="C. Samba Configuration Option Quick Reference">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: C. Samba Configuration Option Quick Reference" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+B.2 Samba Tuning</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+C. Samba Configuration Option Quick Reference</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appc_01.html b/docs/htmldocs/using_samba/appc_01.html
new file mode 100755
index 00000000000..cd9d1ede353
--- /dev/null
+++ b/docs/htmldocs/using_samba/appc_01.html
@@ -0,0 +1,3497 @@
+<HTML>
+<HEAD>
+<TITLE>[Appendix C] Samba Configuration Option Quick Reference</title>
+</head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_03.html" TITLE="B.3 Sizing Samba Servers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.3 Sizing Samba Servers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix C</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="D. Downloading Samba with CVS">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: D. Downloading Samba with CVS" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="appendix">
+<A CLASS="title" NAME="appc-23653">
+C. Samba Configuration Option Quick Reference</a></h1><P CLASS="para">The following pages list each of the Samba configuration options. If an option is applicable only to the global section, "[global]" will appear before its name. Any lists mentioned are space separated, except where noted. A glossary of terms follows the options.</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>admin users = user list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: user list</p>
+
+<P CLASS="para">
+List of users who will be granted root permissions on the share by Samba.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>allow hosts = host list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: any</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+hosts allow</code>. List of machines that may connect to a share.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>alternate permissions = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Obsolete. Has no effect in Samba 2. Files will be shown as read-only if the owner can't write them. In Samba 1.9 and earlier, setting this option would set the DOS filesystem read-only attribute on any file the user couldn't read. This in turn required the <CODE CLASS="literal">
+delete readonly</code> option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] announce as = system type</i></b>
+<P CLASS="refpurpose">Default: NT</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NT, Win95, WfW</p>
+
+<P CLASS="para">
+Have Samba announce itself as something other than an NT server. Discouraged because it interferes with serving browse lists.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] announce version = number.number</i></b>
+<P CLASS="refpurpose">Default: 4.2</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: any</p>
+
+<P CLASS="para">
+Instructs Samba to announce itself as an older version SMB server. Discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] auto services = share list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: any shares</p>
+
+<P CLASS="para">
+List of shares that will always appear in browse lists. A synonym is <CODE CLASS="literal">
+preload</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>available = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to NO, denies access to a share. Doesn't affect browsing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] bind interfaces only = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, shares and browsing will be provided only on interfaces in an interfaces list (see <CODE CLASS="literal">
+interfaces</code>). New in Samba 1.9.18. If you set this option to YES, be sure to add 127.0.0.1 to the interfaces list to allow <EM CLASS="emphasis">
+smbpasswd</em> to connect to the local machine to change passwords. This is a convienence option; it does not improve security.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>browsable = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allows a share to be announced in browse lists.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>blocking locks = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, honors byte range lock requests with time limits for queuing the request and retrying it until the time period expires. New in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] browse list = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Turns on/off <CODE CLASS="literal">
+browse</code> <CODE CLASS="literal">
+list</code> from this server. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] case sensitive = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, uses exactly the case the client supplied when trying to resolve a filename. If NO, matches either upper- or lowercase name. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] case sig names = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+case sensitive</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] change notify timeout = number</i></b>
+<P CLASS="refpurpose">Default: 60</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: positive number</p>
+
+<P CLASS="para">
+Sets the number of seconds between checks when a client asks for notification of changes in a directory. Introduced in Samba 2.0 to limit the performance cost of the checks. Avoid lowering.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>character set = name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: ISO8859-1, ISO8859-2, ISO8859-5, KOI8-R</p>
+
+<P CLASS="para">
+If set, translates from DOS code pages to the Western European (ISO8859-1), Eastern European (ISO8859-2), Russian Cyrillic (ISO8859-5), or Alternate Russian (KOI8-R) character set. The <CODE CLASS="literal">
+client code page</code> must be set to 850.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>client code page = name</i></b>
+<P CLASS="refpurpose">Default: 437 (US MS-DOS)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: See <a href="ch08_03.html#ch08-20815"><b>Table 8.4</b></a></p>
+
+<P CLASS="para">
+Sets the DOS code page explicitly, overriding any previous <CODE CLASS="literal">
+valid chars</code> settings. Examples of values are 850 for European, 437 is the US standard, and 932 for Japanese Shift-JIS. Introduced in Samba 1.9.19.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>coding system = code</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: euc, cap, hex, hexN, sjis, j8bb, j8bj, jis8, j8bh, j8@b, j8@j, j8@h, j7bb, j7bj, jis7, j7bh, j7@b, j7@j, j7@h, jubb, jubj, junet, jubh, ju@b, ju@j, ju@h</p>
+
+<P CLASS="para">
+Sets the coding system used, notably for Kanji. This is employed for filenames and should correspond to the code page in use. The <CODE CLASS="literal">
+client code page</code> option must be set to 932 (Japanese Shift-JIS). Introduced in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>comment = text</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: a text string or NULL</p>
+
+<P CLASS="para">
+Sets the comment that appears beside a share in a NET VIEW or the details list of a Microsoft directory window. See also the <CODE CLASS="literal">
+server string</code> configuration option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] config file = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Selects an additional Samba configuration file to read instead of the current one. Used to relocate the configuration file, or used with %-variables to select custom configuration files for some users or machines. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>copy = section name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: existing section's name</p>
+
+<P CLASS="para">
+Copies the configuration of a previously seen share into the share where it appears. Used with %-variables to select custom configurations for machines, architectures and users. The copied section must be earlier in the configuration file. Copied options are of lesser priority than those explicitly listed in the section.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>create mask = octal value</i></b>
+<P CLASS="refpurpose">Default: 0744</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal permission bits, 0-0777</p>
+
+<P CLASS="para">
+Also called <CODE CLASS="literal">
+create mode</code>. Sets the maximum allowable permissions for new files (e.g., 0755). See also <CODE CLASS="literal">
+directory mask</code>. To require certain permissions to be set, see <CODE CLASS="literal">
+force create mask/force directory mask</code>. This option stopped affecting directories in Samba 1.9.17, and the default value changed in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>create mode = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0744</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal permission bits, 0-0777</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+create mask</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] deadtime = minutes</i></b>
+<P CLASS="refpurpose">Default: 0 </p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: minutes</p>
+
+<P CLASS="para">
+The time in minutes before an unused connection will be terminated. Zero means forever. Used to keep clients from tying up server resources forever. If used, clients will have to auto-reconnect after minutes of inactivity. See also <CODE CLASS="literal">
+keepalive</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] debug level = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets the logging level used. Values of 3 or more slow Samba noticeably. A synonym is <CODE CLASS="literal">
+log level</code>. Recommended value: 1.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] debug timestamp = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Timestamps all log messages. Can be turned off when it's not useful (e.g., in debugging). New in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] default = name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: share name</p>
+
+<P CLASS="para">
+Also called <CODE CLASS="literal">
+default service</code>. The name of a service (share) to provide if someone requests a service they don't have permission to use or which doesn't exist. As of Samba 1.9.14, the path will be set from the name the client specified, with any "_" characters changed to "/" characters, allowing access to any directory on the Samba server. Use is strongly discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>default case = case</i></b>
+<P CLASS="refpurpose">Default: LOWER</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: LOWER, UPPER</p>
+
+<P CLASS="para">
+Sets the case in which to store new filenames. LOWER indicates mixed case, UPPER indicates uppercase letters.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] default service = share name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: share name</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+default</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>delete readonly = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NO, YES</p>
+
+<P CLASS="para">
+Allow delete requests to remove read-only files. This is not allowed in DOS/Windows, but is normal in Unix, which has separate directory permissions. Used with programs like RCS, or with the older <CODE CLASS="literal">
+alternate permissions</code> option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>delete veto files = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NO, YES</p>
+
+<P CLASS="para">
+Allow delete requests for a directory containing files or subdirectories the user can't see due to the <CODE CLASS="literal">
+veto files</code> option. If set to NO, the directory will not be deleted and will still contain invisible files.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>deny hosts = host list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: host list</p>
+
+<P CLASS="para">
+A synonym is <CODE CLASS="literal">
+hosts deny</code>. Specifies a list of machines from which to refuse connections or shares.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] dfree command = command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: shell command</p>
+
+<P CLASS="para">
+A command to run on the server to return disk free space. Not needed unless the OS command does not work properly.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>directory = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+path</code>. A directory provided by a file share, or used by a printer share. Set automatically in the <CODE CLASS="literal">
+[homes]</code> share to user's home directory, otherwise defaults to<I CLASS="filename">
+ /tmp</i>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>directory mask = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0755</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Also called <CODE CLASS="literal">
+directory mode</code>. Sets the maximum allowable permissions for newly created directories. To require certain permissions be set, see the <CODE CLASS="literal">
+force create mask</code> and <CODE CLASS="literal">
+force directory mask</code> options.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>directory mode = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0755</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+directory mask</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] dns proxy = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, and if <CODE CLASS="literal">
+wins server = YES</code>, look up hostnames in DNS if they are not found using WINS.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] domain logons = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allow Windows 95/98 or NT clients to log on to an NT-like domain.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] domain master = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Become a domain master browser list collector if possible for the entire workgroup/domain. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>dont descend = comma-list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: comma-separated list of paths</p>
+
+<P CLASS="para">
+Does not allow a change directory or search in the directories specified. This is a browsing convenience option; it doesn't provide any extra security.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>dos filetimes = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allow non-owners to change file times if they can write to the file. See also <CODE CLASS="literal">
+dos filetime resolution</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>dos filetime resolution = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Set file times on Unix to match DOS standards (round to next even second). Recommended if using Visual C++ or a PC <EM CLASS="emphasis">
+make</em> program to avoid remaking the programs unnecesarily. Use with the <CODE CLASS="literal">
+dos filetimes</code> option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] encrypt passwords = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Uses Windows NT-style password encryption. Requires an <I CLASS="filename">
+smbpasswd</i> on the Samba server.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>exec = command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: shell command</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+preexec</code>, a command to run as the user just before connecting to the share.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>fake directory create times = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Bug fix for users of Microsoft <EM CLASS="emphasis">
+nmake</em>. If set, Samba will set directory create times such that <EM CLASS="emphasis">
+nmake</em> won't remake all files every time.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>fake oplocks = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Return YES whenever a client asks if it can lock a file and cache it locally, but does not enforce lock on the server. Use only for read-only disks, as Samba now supports real <CODE CLASS="literal">
+oplocks</code> and has per-file overrides. See also <CODE CLASS="literal">
+oplocks</code> and <CODE CLASS="literal">
+veto oplock files</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>follow symlinks = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, Samba will follow symlinks in a file share or shares. See the <CODE CLASS="literal">
+wide links</code> option if you want to restrict symlinks to just the current share.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force create mask = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Provides bits that will be <CODE CLASS="literal">
+OR</code>ed into the permissions of newly created files. Used with the <CODE CLASS="literal">
+create mode</code> configuration option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force create mode = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+force create mask</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force directory mask = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Provides bits that will be <CODE CLASS="literal">
+OR</code>ed into the permissions of newly created directories, forcing those bits to be set. Used with <CODE CLASS="literal">
+directory mode</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force directory mode = octal permission bits</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: octal value from 0 to 0777</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+mask</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force group = unix group</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: group</p>
+
+<P CLASS="para">
+Sets the effective group name assigned to all users accessing a share. Used to override user's normal groups.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>force user = name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: username</p>
+
+<P CLASS="para">
+Sets the effective username assigned to all users accessing a share. Discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>fstype = string</i></b>
+<P CLASS="refpurpose">Default: NTFS</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NTFS, FAT, Samba</p>
+
+<P CLASS="para">
+Sets the filesystem type reported to the client. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] getwd cache = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Cache current directory for performance. Recommended with the <CODE CLASS="literal">
+wide links</code> option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>group = group</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: unix group</p>
+
+<P CLASS="para">
+An obsolete form of <CODE CLASS="literal">
+force group</code>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>guest account = user</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: username</p>
+
+<P CLASS="para">
+Sets the name of the unprivileged Unix account to use for tasks like printing and for accessing shares marked with <CODE CLASS="literal">
+guest ok</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>guest ok = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, passwords are not needed for this share. Synonym of <CODE CLASS="literal">
+public</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>guest only = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Forces user of a share to do so as the guest account. Requires <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> or <CODE CLASS="literal">
+public</code> to be <CODE CLASS="literal">
+yes</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>hide dot files = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Treats files beginning with a dot in a share as if they had the DOS/Windows hidden attribute set.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>hide files = slash-separated list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of patterns, separated by <CODE CLASS="literal">
+/</code> characters</p>
+
+<P CLASS="para">
+List of file or directory names to set the DOS hidden attribute on. Names may contain <CODE CLASS="literal">
+?</code> or <CODE CLASS="literal">
+*</code> pattern-characters and <CODE CLASS="literal">
+%</code>-variables. See also <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+dot</code> <CODE CLASS="literal">
+files</code> and <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+files</code>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] homedir map = NIS map name</i></b>
+<P CLASS="refpurpose">Default: auto.home</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NIS map name</p>
+
+<P CLASS="para">
+Used with <CODE CLASS="literal">
+nis homedir</code> to locate user's Unix home directory from Sun NIS (not NIS+).</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>hosts allow = host list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of hostnames</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+allow hosts</code>, a list of machines that can access a share or shares. If NULL (the default) any machine can access the share unless there is a <CODE CLASS="literal">
+hosts deny</code> option. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>hosts deny = host list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of hostnames</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+deny hosts</code>, a list of machines that cannot connect to a share or shares. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] hosts equiv = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Path to a file of trusted machines from which password-less logins are allowed. Strongly discouraged, because Windows/NT users can always override the user name, the only security in this scheme.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>include = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Include the named file in <I CLASS="filename">
+smb.conf</i> at the line where it appears. This option does not understand the variables <CODE CLASS="literal">
+%u</code> (user), <CODE CLASS="literal">
+%P</code> (current share's root directory), or <CODE CLASS="literal">
+%S</code> (current share name), because they are not set at the time the file is read.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- added for 2.0.7,. davecb -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>inherit permissions = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set, subdirectories will be created with the same permissions
+as the directory they are in. This overrides
+<CODE CLASS="literal">create mask, directory mask, force create mode
+</CODE> and <CODE CLASS="literal"> force directory mode</CODE>, but
+not <CODE CLASS="literal">map archive, map hidden </CODE> and <CODE CLASS="literal">
+map system</CODE>. Will never set the <CODE CLASS="literal">setuid
+</CODE> bit. New in 2.0.7, this is a means of ensuring Unix permissions
+can be propagated to subdirectories, especially in [homes].<p>
+
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- end of 2.0.7 -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] interfaces = interface list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: IP addresses separated by spaces</p>
+
+<P CLASS="para">
+Sets the interfaces to which Samba will respond. The default is the machine's primary interface only. Recommended on multihomed machines or to override erroneous addresses and netmasks.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>invalid users = user list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of users</p>
+
+<P CLASS="para">
+List of users that will not be permitted access to a share or shares. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] keepalive = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number of seconds</p>
+
+<P CLASS="para">
+Number of seconds between checks for a crashed client. The default of 0 causes no checks to be performed. Recommended if you want checks more often than every four hours. 3600 (10 minutes) is reasonable. See also <CODE CLASS="literal">
+socket options</code> for another approach.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] kernel oplocks = boolean</i></b>
+<P CLASS="refpurpose">Default: automatic</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Break oplock when a Unix process accesses an <EM CLASS="emphasis">
+oplocked</em> file, preventing corruption. Set to YES on operating systems supporting this, otherwise set to NO. New in Samba 2.0; supported on SGI, and hopefully soon on Linux and BSD. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] ldap filter = various</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: various</p>
+
+<P CLASS="para">
+Options beginning with <CODE CLASS="literal">
+ldap</code> are part of an experimental (circa Samba 2.0) use of the Lightweight Directory Access Protocol (LDAP) general directory/distributed database for user, name, and host information. This option is reserved for future use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] ldap port = various</i></b>
+<P CLASS="refpurpose">Default: various</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: various</p>
+
+<P CLASS="para">
+Options beginning with <CODE CLASS="literal">
+ldap</code> are part of an experimental (circa Samba 2.0) use of the Lightweight Directory Access Protocol (LDAP) general directory/distributed database for user, name, and host information. This option is reserved for future use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] ldap root = various</i></b>
+<P CLASS="refpurpose">Default: various</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: various</p>
+
+<P CLASS="para">
+Options beginning with <CODE CLASS="literal">
+ldap</code> are part of an experimental (circa Samba 2.0) use of the Lightweight Directory Access Protocol (LDAP) general directory/distributed database for user, name, and host information. This option is reserved for future use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] ldap server = various</i></b>
+<P CLASS="refpurpose">Default: various</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: various</p>
+
+<P CLASS="para">
+Options beginning with <CODE CLASS="literal">
+ldap</code> are part of an experimental (circa Samba 2.0) use of the Lightweight Directory Access Protocol (LDAP) general directory/distributed database for user, name, and host information. This option is reserved for future use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] ldap suffix = various</i></b>
+<P CLASS="refpurpose">Default: various</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: various</p>
+
+<P CLASS="para">
+Options beginning with <CODE CLASS="literal">
+ldap</code> are part of an experimental (circa Samba 2.0) use of the Lightweight Directory Access Protocol (LDAP) general directory/distributed database for user, name, and host information. This option is reserved for future use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] load printers = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Load all printer names from the system printer capabilities into browse list. Uses configuration options from the <CODE CLASS="literal">
+[printers]</code> section.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] local master = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Stands for election as the local master browser. See also <CODE CLASS="literal">
+domain master</code> and <CODE CLASS="literal">
+os level</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] lm announce = value</i></b>
+<P CLASS="refpurpose">Default: AUTO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: AUTO, YES, NO</p>
+
+<P CLASS="para">
+Produce OS/2 SMB broadcasts at an interval specified by the <CODE CLASS="literal">
+lm interval</code> option. YES/NO turns them on/off unconditionally. AUTO causes the Samba server to wait for a LAN Manager announcement from another client before sending one out. Required for OS/2 client browsing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] lm interval = seconds</i></b>
+<P CLASS="refpurpose">Default: 60</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets the time period, in seconds, between OS/2 SMB broadcast announcements.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] lock directory = pathname</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+/usr/local/samba/var/locks</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Set a directory to keep lock files in. The directory must be writable by Samba, readable by everyone.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>locking = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Perform file locking. If set to NO, Samba will accept lock requests but will not actually lock resources. Recommended only for read-only file systems.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] log file = pathname</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Set name and location of the log file. Allows all %-variables.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] log level = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+A synonym of <CODE CLASS="literal">
+debug level</code>. Sets the logging level used. Values of 3 or more slow the system noticeably.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] logon drive = drive</i></b>
+<P CLASS="refpurpose">Default: None</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: DOS drive name</p>
+
+<P CLASS="para">
+Sets the drive on Windows NT (only) of the <CODE CLASS="literal">
+logon path</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] logon home = path</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+\\</em><CODE CLASS="replaceable"><I>%</i></code></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Sets the home directory of a Windows 95/98 or NT Workstation user. Allows <CODE CLASS="literal">
+NET</code> <CODE CLASS="literal">
+USE</code> <CODE CLASS="literal">
+H:/HOME</code> from the command prompt.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] logon path = pathname</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+\\</em><CODE CLASS="replaceable"><I>N</i></code><EM CLASS="emphasis">\</em><CODE CLASS="replaceable"><I>%U</i></code><EM CLASS="emphasis">\profile</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Windows pathname</p>
+
+<P CLASS="para">
+Sets path to Windows profile directory. This contains <EM CLASS="emphasis">
+USER.MAN</em> and/or <EM CLASS="emphasis">
+USER.DAT</em> profile files and the Windows 95 Desktop, Start Menu, Network Neighborhood, and programs folders. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] logon script = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Sets pathname relative to <CODE CLASS="literal">
+[netlogin]</code> share of a DOS/NT script to run on the client at login time. Allows all %-variables.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>lppause command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualfied Unix shell command</p>
+
+<P CLASS="para">
+Sets the command to pause a print job. Honors the <CODE CLASS="literal">
+%p</code> (printer name) and <CODE CLASS="literal">
+%j</code> (job number) variables. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>lpresume command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets the command to resume a paused print job. Honors the <CODE CLASS="literal">
+%p</code> (printer name) and <CODE CLASS="literal">
+%j</code> (job number) variables. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] lpq cache time = seconds</i></b>
+<P CLASS="refpurpose">Default: 10</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number of seconds</p>
+
+<P CLASS="para">
+Sets how long to keep print queue (<CODE CLASS="literal">lpq</code>) status is cached, in seconds.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>lpq command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualfied Unix shell command</p>
+
+<P CLASS="para">
+Sets the command used to get printer status. Usually initialized to a default value by the <CODE CLASS="literal">
+printing</code> option. Honors the <CODE CLASS="literal">
+%p</code> (printer name) variable.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>lprm command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets the command to delete a print job. Usually initialized to a default value by the <CODE CLASS="literal">
+printing</code> option. Honors the <CODE CLASS="literal">
+%p</code> (printer name) and <CODE CLASS="literal">
+%j</code> (job number) variables.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>machine password timeout = seconds</i></b>
+<P CLASS="refpurpose">Default: 604,800</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number of seconds</p>
+
+<P CLASS="para">
+Sets the period between (NT domain) machine password changes. Default is 1 week, or 604,800 seconds.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>magic output = pathname</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+script.out</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Sets the output file for the discouraged <CODE CLASS="literal">
+magic scripts</code> option. Default is the script name, followed by the extension <EM CLASS="emphasis">
+.out</em>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>magic script = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Sets a filename for execution via a shell whenever the file is closed from the client, to allow clients to run commands on the server. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>mangle case = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: allowable values: YES, NO</p>
+
+<P CLASS="para">
+Mangle a name if it is in mixed case.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>mangled map = map list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of to-from pairs</p>
+
+<P CLASS="para">
+Set up a table of names to remap (e.g., <EM CLASS="emphasis">
+.html</em> to <EM CLASS="emphasis">
+.htm</em>). </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>mangled names = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Sets Samba to abbreviate names that are too long or have unsupported characters to the DOS 8.3 style. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>mangling char = character</i></b>
+<P CLASS="refpurpose">Default: ~</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: character</p>
+
+<P CLASS="para">
+Sets the unique mangling character used in all mangled names.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] mangled stack = number</i></b>
+<P CLASS="refpurpose">Default: 50</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets the size of a cache of recently-mangled filenames.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>map aliasname = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Points to a file of Unix group/NT group pairs, one per line. This is used to map NT aliases to Unix group names. See also the configuration options <CODE CLASS="literal">
+username</code> <CODE CLASS="literal">
+map</code> and <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+groupname</code>. Introduced in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>map archive = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, Samba sets the executable-by-user (0100) bit on Unix files if the DOS archive attribute is set. Recommended: if used, the <CODE CLASS="literal">
+create mask</code> must contain the 0100 bit.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>map hidden = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, sets executable-by-other (0001) bit on Unix files if the DOS hidden attribute is set. If used, the <CODE CLASS="literal">
+create mask</code> option must contain the 0001 bit.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>map groupname = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Points to a file of Unix group/NT group, one per line. This is used to map NT group names to Unix group names. See also the configuration options <CODE CLASS="literal">
+username</code> <CODE CLASS="literal">
+map</code> and <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+aliasname</code>. Introduced in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>map system = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, Samba sets the executable-by-group (0010) bit on Unix files if the DOS system attribute is set. If used, the <CODE CLASS="literal">
+create mask</code> must contain the 0010 bit.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>max connections = number</i></b>
+<P CLASS="refpurpose">Default: 0 (infinity)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Set maximum number of connections allowed to a share from each individual client machine.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max disk size = number</i></b>
+<P CLASS="refpurpose">Default: 0 (unchanged)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: size in MB</p>
+
+<P CLASS="para">
+Sets maximum disk size/free-space size (in megabytes) to return to client. Some clients or applications can't understand large maximum disk sizes.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max log size = number</i></b>
+<P CLASS="refpurpose">Default: 5000</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: size in KB</p>
+
+<P CLASS="para">
+Sets the size (in kilobytes) at which Samba will start a new log file. The current log file will be renamed with an <EM CLASS="emphasis">
+.old</em> extension, replacing any previous file with that name. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max mux = number</i></b>
+<P CLASS="refpurpose">Default: 50</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets the number of simultaneous operations that Samba clients may make. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max packet = number</i></b>
+<P CLASS="refpurpose">Default: N/A</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+packet size</code>. Obsolete as of Samba 1.7. Use <CODE CLASS="literal">
+max xmit</code> instead.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max open files = number</i></b>
+<P CLASS="refpurpose">Default: 10,000</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Limits the number of files a Samba process will try to keep open at one time. Samba allows you to set this to less than the Unix maximum. This option is a workaround for a separate problem. Avoid changing. This option was introduced in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max ttl = seconds</i></b>
+<P CLASS="refpurpose">Default: 14400 (4 hrs)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: time in seconds</p>
+
+<P CLASS="para">
+Sets the time to keep NetBIOS names in <EM CLASS="emphasis">
+nmbd</em> cache while trying to perform a lookup on it. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max wins ttl = seconds</i></b>
+<P CLASS="refpurpose">Default: 259200 (3 days)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: time in seconds</p>
+
+<P CLASS="para">
+Limits time-to-live of a NetBIOS name in <EM CLASS="emphasis">
+nmbd</em> WINS cache, in seconds. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] max xmit = bytes</i></b>
+<P CLASS="refpurpose">Default: 65535</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: size in bytes</p>
+
+<P CLASS="para">
+Sets maximum packet size that will be negotiated by Samba. Tuning parameter for slow links and older client bugs. Values less than 2048 are discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] message command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: shell command</p>
+
+<P CLASS="para">
+Sets the command on the server to run when a WinPopup message arrives from a client. The command must end in "<CODE CLASS="literal">&amp;</code>" to allow immediate return. Honors all %-variables except <CODE CLASS="literal">
+%u</code> (user), and supports the extra variables <CODE CLASS="literal">
+%s</code> (filename the message is in), <CODE CLASS="literal">
+%t</code> (destination machine), and <CODE CLASS="literal">
+%f</code> (from).</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>min print space = kilobytes</i></b>
+<P CLASS="refpurpose">Default: 0 (unlimited)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: space in KB</p>
+
+<P CLASS="para">
+Sets minimum spool space required before accepting a print request.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- 2.0.7, davecb -->
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>min password length = characters</i></b>
+<P CLASS="refpurpose">Default: 5</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: decimal number of characters</p>
+
+<P CLASS="para">
+Sets the shortest password Samba will pass to the Unix passwd command.
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- sne 2.0.7 -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] min wins ttl = seconds</i></b>
+<P CLASS="refpurpose">Default: 21600 (6 hrs)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: time in seconds</p>
+
+<P CLASS="para">
+Sets minimum time-to-live of a NetBIOS name in <EM CLASS="emphasis">
+nmbd</em> WINS cache, in seconds. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>name resolve order = list</i></b>
+<P CLASS="refpurpose">Default: lmhosts wins hosts bcast</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of lmhosts, wins, hosts and bcast</p>
+
+<P CLASS="para">
+Sets order of lookup when trying to get IP address from names. The <CODE CLASS="literal">
+hosts</code> parameter carrries out a regular name look up using the server's normal sources: <EM CLASS="emphasis">
+/etc/hosts</em>, DNS, NIS, or a combination of them. Introduced in Samba 1.9.18p4.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] netbios aliases = list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of netbios names</p>
+
+<P CLASS="para">
+Adds additional NetBIOS names by which a Samba server will advertise itself.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>netbios name = hostname</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: host name</p>
+
+<P CLASS="para">
+Sets the NetBIOS name by which a Samba server is known, or primary name if NetBIOS aliases exist. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- 2.0.7, davecb -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>netbios scope = string</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: string</p>
+
+<P CLASS="para">
+Sets the NetBIOS scope string. Samba will not communicate with a machine
+with a different scope. This was an early predecessor of workgroups: avoid
+setting it. Added in 2.0.7. <!-- why was it added, anyway? -->
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- end 2.0.7 -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] networkstation user login = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to NO, clients will not do a full login when <CODE CLASS="literal">
+security = server</code>. Avoid changing. Turning it off is a temporary workaround (introduced in Samba 1.9.18p3) for NT trusted domains bug. Automatic correction was introduced in Samba 1.9.18p10; the parameter may eventually be removed.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] nis homedir = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, the <CODE CLASS="literal">
+homedir map</code> will be used to look up the user's home-directory server name and return it to the client. The client will contact that machine to connect to the share. This avoids mounting from a machine that doesn't actually have the disk. The machine with the home directories must be an SMB server.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] nt pipe support = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allows turning off NT-specific pipe calls. This is a developer/benchmarking option and may be removed in the future. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] nt smb support = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, allow NT-specific SMBs to be used. This is a developer/benchmarking option and may be removed in the future. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] null passwords = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, allows access to accounts that have null passwords. Strongly discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>ole locking compatibility = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, locking ranges will be mapped to avoid Unix locks crashing when Windows uses locks above 32KB. You should avoid changing this option. Introduced in Samba 1.9.18p10. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>only guest = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+A synonym for <CODE CLASS="literal">
+guest only</code>. Forces user of a share to login as the guest account. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>only user = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Requires that users of the share be on a <CODE CLASS="literal">
+username =</code> list. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>oplocks = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, support local caching of <EM CLASS="emphasis">
+opportunistic</em> locked files on client. This option is recommended because it improves performance by about 30%. See also <CODE CLASS="literal">
+fake</code> <CODE CLASS="literal">
+oplocks</code> and <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+oplock</code> <CODE CLASS="literal">
+files</code>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] os level = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets the candidacy of the server when electing a browse master. Used with the <CODE CLASS="literal">
+domain</code> <CODE CLASS="literal">
+master</code> or <CODE CLASS="literal">
+local</code> <CODE CLASS="literal">
+master</code> options. You can set a higher value than a competing operating system if you want Samba to win. Windows for Workgroups and Windows 95 use 1, Windows NT client uses 17, and Windows NT Server uses 33.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] packet size = bytes</i></b>
+<P CLASS="refpurpose">Default: 65535</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number in bytes</p>
+
+<P CLASS="para">
+Obsolete. Discouraged synonym of <CODE CLASS="literal">
+max packet</code>. See <CODE CLASS="literal">
+max xmit</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] passwd chat debug = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Logs an entire password chat, including passwords passed, with a log level of 100. For debugging only. Introduced in Samba 1.9.18p5.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] passwd chat = command sequence</i></b>
+<P CLASS="refpurpose">Default: compiled-in value</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix server commands</p>
+
+<P CLASS="para">
+Sets the command used to change passwords on the server. Supports the variables <CODE CLASS="literal">
+%o</code> (old password) and <CODE CLASS="literal">
+%n</code> (new password) and allows <CODE CLASS="literal">
+\r</code> <CODE CLASS="literal">
+\n</code> <CODE CLASS="literal">
+\t</code> and <CODE CLASS="literal">
+\s</code> (space) escapes in the sequence.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] passwd program = program</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix server program</p>
+
+<P CLASS="para">
+Sets the command used to change user's password. Will be run as <CODE CLASS="literal">
+root</code>. Supports <CODE CLASS="literal">
+%u</code> (user).</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] password level = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Specifies the number of uppercase letter permutations used to match passwords. Workaround for clients that change passwords to a single case before sending them to the Samba server. Causes repeated login attempts with passwords in different cases, which can trigger account lockouts. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] password server = netbios names</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of NetBIOS names</p>
+
+<P CLASS="para">
+A list of SMB servers that will validate passwords for you. Used with an NT password server (PDC or BDC) and the <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+server</code> or <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+domain</code> configuration options. Caution: an NT password server must allow logins from the Samba server.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>panic action = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualfied Unix shell command</p>
+
+<P CLASS="para">
+Sets the command to run when Samba panics. For Samba developers and testers, <CODE CLASS="literal">
+/usr/bin/X11/xterm -display :0 -e gdb /samba/bin/smbd %d</code> is a possible value.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>path = pathname</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Sets the path to the directory provided by a file share or used by a printer share. Set automatically in <CODE CLASS="literal">
+[homes]</code> share to user's home directory, otherwise defaults to<I CLASS="filename">
+ /tmp</i>. Honors the <CODE CLASS="literal">
+%u</code> (user) and <CODE CLASS="literal">
+%m</code> (machine) variables.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>postexec = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets a command to run as the user after disconnecting from the share. See also the options <CODE CLASS="literal">
+preexec</code>, <CODE CLASS="literal">
+root preexec</code>, and <CODE CLASS="literal">
+root postexec</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>postscript = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Flags a printer as PostScript to avoid a Windows bug by inserting <CODE CLASS="literal">
+%!</code> as the first line. Works only if printer actually is PostScript compatible.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>preexec = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets a command to run as the user before connecting to the share. See also the options <CODE CLASS="literal">
+postexec</code>, <CODE CLASS="literal">
+root preexec</code>, and <CODE CLASS="literal">
+root postexec</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] preferred master = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, Samba is preferred to become the master browser. Causes Samba to call a browsing election when it comes online.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>preload = share list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of services</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+auto</code> <CODE CLASS="literal">
+services</code>. Specifies a list of shares that will always appear in browse lists.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>preserve case = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, this option leaves filenames in the case sent by client. If no, it forces filenames to the case specified by the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option. See also <CODE CLASS="literal">
+short preserve case</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>print command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets the command used to send a spooled file to the printer. Usually initialized to a default value by the <CODE CLASS="literal">
+printing</code> option. This option honors the <CODE CLASS="literal">
+%p</code> (printer name), <CODE CLASS="literal">
+%s</code> (spool file) and <CODE CLASS="literal">
+%f</code> (spool file as a relative path) variables. Note that the command in the value of the option must include file deletion of the spool file.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>print ok = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+printable</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printable = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Sets a share to be a print share. Required for all printers.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] printcap name = pathname</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+/etc/printcap</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Sets the path to the printer capabilities file used by the <CODE CLASS="literal">
+[printers]</code> share. The default value changes to <I CLASS="filename">
+/etc/qconfig</i> under AIX and <I CLASS="filename">
+lpstat</i> on System V.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printer = name</i></b>
+<P CLASS="refpurpose">Default: <CODE CLASS="literal">
+lp</code></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: printer name</p>
+
+<P CLASS="para">
+Sets the name of the Unix printer.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printer driver = printer driver name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: exact printer driver string used by Windows</p>
+
+<P CLASS="para">
+Sets the string to pass to Windows when asked what driver to use to prepare files for a printer share. Note that the value is case sensitive.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] printer driver file = path</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+samba-lib/printers.def</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Sets the location of a<EM CLASS="emphasis">
+ msprint.def</em> file, usable by Windows 95/98.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printer driver location = path</i></b>
+<P CLASS="refpurpose">Default: <EM CLASS="emphasis">
+\\</em><CODE CLASS="replaceable"><I>server</i></code><EM CLASS="emphasis">\PRINTER$</em></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Windows network path</p>
+
+<P CLASS="para">
+Sets the location of the driver for a particular printer. The value is a pathname for a share that stores the printer driver files.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printer name = name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: name</p>
+
+<P CLASS="para">
+Synonym of <CODE CLASS="literal">
+printer</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>printing = style</i></b>
+<P CLASS="refpurpose">Default: bsd</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: bsd, sysv, hpux, aix, qnx, plp, lprng</p>
+
+<P CLASS="para">
+Sets printing style to one of the above, instead of the compiled-in value. This sets initial values of at least the <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code>, <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code>, <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+command</code>, and <CODE CLASS="literal">
+lprm</code> <CODE CLASS="literal">
+command</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] protocol = protocol</i></b>
+<P CLASS="refpurpose">Default: NT1</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: NT1, LANMAN2, LANMAN1, COREPLUS, CORE</p>
+
+<P CLASS="para">
+Sets SMB protocol version to one of the allowable values. Resetting is highly discouraged. Only for backwards compatibility with older-client bugs.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>public = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, passwords are not needed for this share. A synonym is <CODE CLASS="literal">
+guest ok</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>queuepause command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: valid Unix command</p>
+
+<P CLASS="para">
+Sets the command used to pause a print queue. Usually initialized to a default value by the <CODE CLASS="literal">
+printing</code> option. Introduced in Samba 1.9.18p10.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>queueresume command = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: varies</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: valid Unix command</p>
+
+<P CLASS="para">
+Sets the command used to resume a print queue. Usually initialized to a default value by the <CODE CLASS="literal">
+printing</code> option. Introduced in Samba 1.9.18p10.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>read bmpx = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Obsolete. Do not change.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>read list = comma-separated list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: comma-separated list of users</p>
+
+<P CLASS="para">
+Specifies a list of users given read-only access to a writeable share. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>read only = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Sets a share to read-only. Antonym of <CODE CLASS="literal">
+writable</code> and <CODE CLASS="literal">
+write ok</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] read prediction = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Reads ahead data for read-only files. Obsolete; removed in Samba 2.0.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] read raw = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allows fast streaming reads over TCP using 64K buffers. Recommended.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] read size = bytes</i></b>
+<P CLASS="refpurpose">Default: 2048</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: size in bytes</p>
+
+<P CLASS="para">
+Sets a buffering option for servers with mismatched disk and network speeds. Requires experimentation. Avoid changing. Should not exceed 65536.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] remote announce = remote list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of remote addresses</p>
+
+<P CLASS="para">
+Adds workgroups to the list on which the Samba server will announce itself. Specified as IP address/workgroup (for instance, 192.168.220.215/SIMPLE) with multiple groups separated by spaces. Allows directed broadcasts. The server will appear on those workgroup's browse lists. Does not require WINS.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] remote browse sync = address list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: IP-address list</p>
+
+<P CLASS="para">
+Enables Samba-only browse list synchronization with other Samba local master browsers. Addresses can be specific addresses or directed broadcasts (i.e., ###.###.###.255). The latter will cause Samba to hunt down the local master.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>revalidate = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, requires users to re-enter passwords even after a successful initial logon to a share with a password.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] root = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+root directory</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] root dir = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+root directory</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] root directory = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Specifies a directory to <CODE CLASS="literal">
+chroot()</code> to before starting daemons. Prevents any access below that directory tree. See also the <CODE CLASS="literal">
+wide links</code> configuration option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>root postexec = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets a command to run as root after disconnecting from the share. See also <CODE CLASS="literal">
+preexec</code>, <CODE CLASS="literal">
+postexec</code>, and <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+preexec</code> configuration options. Runs after the user's <CODE CLASS="literal">
+postexec</code> command. Use with caution.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>root preexec = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: fully-qualified Unix shell command</p>
+
+<P CLASS="para">
+Sets a command to run as root before connecting to the share. See also <CODE CLASS="literal">
+preexec</code>, <CODE CLASS="literal">
+postexec</code>, and <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+postexec</code> configuration options. Runs before the user's <CODE CLASS="literal">
+preexec</code> command. Use with caution.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] security = value</i></b>
+<P CLASS="refpurpose">Default: share in Samba 1.0, user in 2.0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: share, user, server, domain</p>
+
+<P CLASS="para">
+Sets password-security policy. If <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+share</code>, services have a shared password, available to everyone. If <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+user</code>, users have (Unix) accounts and passwords. If <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+server</code>, users have accounts and passwords and a separate machine authenticates them for Samba. If <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+domain</code>, full NT-domain authentication is done. See also the <CODE CLASS="literal">
+password server</code> and <CODE CLASS="literal">
+encrypted passwords</code> configuration options. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] server string = text</i></b>
+<P CLASS="refpurpose">Default: Samba <CODE CLASS="literal">
+%v</code> in 2.0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: string</p>
+
+<P CLASS="para">
+Sets the name that appears beside a server in browse lists. Honors the <CODE CLASS="literal">
+%v</code> (Samba version number) and <CODE CLASS="literal">
+%h</code> (hostname) variables.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>set directory = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allows DEC Pathworks client to use the <EM CLASS="emphasis">
+set dir</em> command.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] shared file entries = number</i></b>
+<P CLASS="refpurpose">Default: 113</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Obsolete; do not use.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>shared mem size = bytes</i></b>
+<P CLASS="refpurpose">Default: 102400</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: size in bytes</p>
+
+<P CLASS="para">
+If compiled with FAST_SHARE_MODES (mmap), sets the shared memory size in bytes. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] smb passwd file = path</i></b>
+<P CLASS="refpurpose">Default: <I CLASS="filename">
+/usr/local/samba/private/smbpasswd</i></p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: Unix pathname</p>
+
+<P CLASS="para">
+Overrides compiled-in path to password file if <CODE CLASS="literal">
+encrypted passwords</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] smbrun = /absolute_ path/command</i></b>
+<P CLASS="refpurpose">Default: compiled-in value</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: smbrun command</p>
+
+<P CLASS="para">
+Overrides compiled-in path to <I CLASS="filename">
+smbrun</i> binary. Avoid changing.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>share modes = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, this option supports Windows-style whole-file (deny mode) locks.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>short preserve case = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, leaves mangled 8.3-style filenames in the case sent by client. If no, it forces the case to that specified by the <CODE CLASS="literal">
+default case</code> option. See also <CODE CLASS="literal">
+preserve case</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] socket address = IP address</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: IP address</p>
+
+<P CLASS="para">
+Sets address on which to listen for connections. Default is to listen to all addresses. Used to support multiple virtual interfaces on one server. Highly discouraged. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] socket options = socket option list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list</p>
+
+<P CLASS="para">
+Sets OS-specific socket options. <CODE CLASS="literal">
+SO_KEEPALIVE</code> has TCP check clients every 4 hours to see if they are still accessible. <CODE CLASS="literal">
+TCP_NODELAY</code> sends even tiny packets to keep delay low. Recommended wherever the operating system supports them. See <a href="appb_01.html"><b>Appendix B, <CITE CLASS="appendix">Samba Performance Tuning</cite></b></a>, for more information.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- 2.0.7, davecb -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] source environment = string</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+This pathname parameter causes Samba to read a list of environment
+variables from a named file on startup. This can be useful in setting
+up Samba in a clustered environment. This is new in 2.0.7.</p>
+
+<p> The file must be owned by root and not be world writable,
+and if the filename begins with a "|" (pipe) character, it must point to
+a command which is neither world writable nor resides
+in a world writable directory.</p>
+
+<p> The data should be in the form of lines such as
+<CODE CLASS="literal">SAMBA_NETBIOS_NAME=myhostname</CODE>.
+This variable will then be available in the smb.conf files as $%SAMBA_NETBIOS_NAME.</p>
+
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- end of 2.0.7 -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] status = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, logs connections to a file (or shared memory) accessible to <I CLASS="filename">
+smbstatus</i>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>strict sync = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, Samba will synchronize to disk whenever the client sets the sync bit in a packet. If set to NO, Samba flushes data to disk whenever buffers fill. Defaults to NO because Windows 98 Explorer sets the bit (incorrectly) in all packets. Introduced in Samba 1.9.18p10.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>strict locking = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, Samba checks locks on every access, not just on demand and at open time. Not recommended.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] strip dot = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Removes trailing dots from filenames. Use <CODE CLASS="literal">
+mangled map</code> instead.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] syslog = number</i></b>
+<P CLASS="refpurpose">Default: 1</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Sets number of Samba log messages to send to <I CLASS="filename">
+syslog</i>. Higher is more verbose. The <I CLASS="filename">
+syslog.conf</i> file must have suitable logging enabled.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] syslog only = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, log only to <EM CLASS="emphasis">
+syslog, </em>not standard Samba log files.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>sync always = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, Samba calls<EM CLASS="emphasis">
+ fsync</em>(3) after every write. Avoid except for debugging crashing servers.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] time offset = minutes</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: minutes</p>
+
+<P CLASS="para">
+Sets number of minutes to add to system time zone calculation. Provided to fix a client daylight-savings bug; not recommended.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] time server = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If YES, <EM CLASS="emphasis">
+nmbd</em> will provide time service to its clients.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>unix password sync = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set, will attempt to change the user's Unix password whenever the user changes his or her SMB password. Used to ease synchronization of Unix and Microsoft password databases. Added in Samba 1.9.18p4. See also <CODE CLASS="literal">
+passwd chat</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>unix realname = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set, will provide the GCOS field of <I CLASS="filename">
+/etc/passwd</i> to the client as the user's full name.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>update encrypted = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Updates the Microsoft-format password file when a user logs in with unencrypted passwords. Provided to ease conversion to encryped passwords for Windows 95/98 and NT. Added in Samba 1.9.18p5.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>user = comma-separated list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: comma-separated list of user names</p>
+
+<P CLASS="para">
+Synonym for <CODE CLASS="literal">
+username</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>username = comma-separated list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: comma-separated list of user names</p>
+
+<P CLASS="para">
+Sets a list of users to try to log in as for a share or shares with share-level security. Synonyms are <CODE CLASS="literal">
+user</code> and <CODE CLASS="literal">
+users</code>. Discouraged. Use <CODE CLASS="literal">
+NET USE \\</code><CODE CLASS="replaceable"><I>server</i></code><CODE CLASS="literal">\</code><CODE CLASS="replaceable"><I>share </i></code><CODE CLASS="literal">%</code><CODE CLASS="replaceable"><I>user</i></code> from the client instead.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>username level = number</i></b>
+<P CLASS="refpurpose">Default: 0</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: number</p>
+
+<P CLASS="para">
+Number of uppercase letter permutations allowed to match Unix usernames. Workaround for Windows feature (single-case usernames). Use is discouraged.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] username map = pathname</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+Names a file of Unix-to-Windows name pairs; used to map different spellings of account names and those Windows usernames longer than eight characters.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- 2.0.7 -->
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] utmp = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+This is available if Samba has been configured with the option
+<CODE CLASS="literal"> --with-utmp</CODE>.
+If set, Samba will add utmp/utmpx records whenever a
+connection is made to a Samba server. New in 2.0.7, sites may use this
+to record the user connecting to a Samba share.
+</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] utmp directory = string</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: pathname</p>
+
+<P CLASS="para">
+This is available if Samba has been configured with the option
+<CODE CLASS="literal">--with-utmp</CODE>. If it and <CODE CLASS="literal">
+utmp </CODE> are set, Samba will look in the specified directory
+insteqad of the default system directory for utmp/utmpx files.
+New in 2.0.7, also called <CODE CLASS="literal"> utmp dir</CODE>.
+</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- end of 2.0.7 ->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>valid chars = list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of numeric values</p>
+
+<P CLASS="para">
+Semi-obsolete. Adds national characters to a character set map. Overridden by <CODE CLASS="literal">
+client code page</code>. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>valid users = user list</i></b>
+<P CLASS="refpurpose">Default: NULL (everyone)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: list of users</p>
+
+<P CLASS="para">
+List of users that can log in to a share. </p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>veto files = slash-list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: slash-separated list of filenames</p>
+
+<P CLASS="para">
+List of files not to allow the client to see when listing a directory's contents. See also <CODE CLASS="literal">
+delete veto files</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>veto oplock files = slash-list</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: slash-separated list of filenames</p>
+
+<P CLASS="para">
+List of files not to oplock (and cache on clients). See also <CODE CLASS="literal">
+oplocks</code> and <CODE CLASS="literal">
+fake oplocks</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>volume = share name</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: string</p>
+
+<P CLASS="para">
+Sets the volume label of a disk share, notably a CD-ROM.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>wide links = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, Samba will follow symlinks out of the current disk share(s). See also the <CODE CLASS="literal">
+root dir</code> and <CODE CLASS="literal">
+follow symlinks</code> options.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] wins proxy = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, <EM CLASS="emphasis">
+nmbd</em> will proxy resolution requests to WINS servers on behalf of old clients, which use broadcasts. WINS server is typically on another subnet.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] wins server = host</i></b>
+<P CLASS="refpurpose">Default: NULL</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: hostname</p>
+
+<P CLASS="para">
+Sets the DNS name or IP address of the WINS server.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] wins support = boolean</i></b>
+<P CLASS="refpurpose">Default: NO</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+If set to YES, Samba activates WINS service. The <CODE CLASS="literal">
+wins server</code> option must not be set if <CODE CLASS="literal">
+wins support = yes</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] workgroup = name</i></b>
+<P CLASS="refpurpose">Default: compiled-in</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: workgroup name</p>
+
+<P CLASS="para">
+Sets the workgroup to which things will be served. Overrides compiled-in value. Choosing a name other than <CODE CLASS="literal">
+WORKGROUP</code> is strongly recommended.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>writable = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Antonym for <CODE CLASS="literal">
+read only</code>; synonym of <CODE CLASS="literal">
+write ok</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>write list = comma-separated list</i></b>
+<P CLASS="refpurpose">Default: NULL (everyone)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: comma-separated list of users</p>
+
+<P CLASS="para">
+List of users that are given read-write access to a read-only share. See also <CODE CLASS="literal">
+read list</code>.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<!-- 2.0.7 addendum, davecb -->
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>write cache size = decimal number</i></b>
+<P CLASS="refpurpose">Default: 0 (Disabled)</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: decimal number of bytes</p>
+
+<P CLASS="para">
+Sets the size of a write buffer that Samba uses to pre-accumulate
+write into, so as to write with a particular size that's optimal for
+a given filesystem. Typically this is used with RAID drives, which
+have a preferred write size, systems with large memory and slow disks, etc.</p>
+
+<p> As of Samba 2.0.7, this applies to the first 10 oplocked files,
+which are also found in shares where this option is set.
+</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+<!-- end of 2.0.7 addendum -->
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>write ok = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Synonym of the <CODE CLASS="literal">
+writable</code> configuration option.</p>
+</div>
+</blockquote>
+</div>
+<p>&nbsp;</p>
+
+<DIV CLASS="refentry">
+<DIV CLASS="refnamediv"><b><i>[global] write raw = boolean</i></b>
+<P CLASS="refpurpose">Default: YES</p></div><BLOCKQUOTE>
+<DIV CLASS="refsynopsisdiv">
+<P CLASS="para">Allowable values: YES, NO</p>
+
+<P CLASS="para">
+Allows fast streaming writes over TCP, using 64KB buffers. Recommended.</p>
+</div>
+</blockquote>
+
+<DIV CLASS="refsect1"><h2>Glossary of Configuration Values</h2>
+<DL CLASS="variablelist">
+<DT CLASS="term">Address list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of IP addresses in ###.###.###.### format.</p></dd><DT CLASS="term">
+Comma-separated list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A list of items separated by commas.</p></dd><DT CLASS="term">
+Command</dt><DD CLASS="listitem">
+<P CLASS="para">
+A Unix command, with full path and parameters.</p></dd><DT CLASS="term">
+Host list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of hosts. Allows IP addresses, address masks, domain names, ALL, and EXCEPT</p></dd><DT CLASS="term">
+Interface list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of interfaces, in either address/netmask or address/n-bits format. For example, 192.168.2.10/24 or 192.168.2.10/255.255.255.0</p></dd><DT CLASS="term">
+Map list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of file-remapping strings such as <CODE CLASS="literal">
+(*.html</code> <CODE CLASS="literal">
+*.htm)</code>.</p></dd><DT CLASS="term">
+Remote list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of subnet-broadcast-address/workgroup pairs. For example, 192.168.2.255/SERVERS 192.168.4.255/STAFF.</p></dd><DT CLASS="term">
+Service (share) list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of share names, without the enclosing square brackets.</p></dd><DT CLASS="term">
+Slash-list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A list of filenames, separated by "/" characters to allow embedded spaces. For example, <CODE CLASS="literal">
+/.*/fred</code> <CODE CLASS="literal">
+flintstone/*.frk/</code>.</p></dd><DT CLASS="term">
+Text</dt><DD CLASS="listitem">
+<P CLASS="para">
+One line of text. </p></dd><DT CLASS="term">
+User list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A space-separated list of usernames. In Samba 1.9, <CODE CLASS="literal">
+@group-name</code> will include everyone in Unix group <CODE CLASS="literal">
+group-name</code>. In Samba 2.0, <CODE CLASS="literal">
+@group-name</code> includes whomever is in the NIS netgroup <CODE CLASS="literal">
+group_name</code> if one exists, otherwise whomever is in the Unix group <CODE CLASS="literal">
+group_name</code>. In addition, +<CODE CLASS="literal">
+group_name</code> is a Unix group, &amp;<CODE CLASS="literal">
+group_name</code> is an NIS netgroup, and &amp;+ and +&amp; cause an ordered search of both Unix and NIS groups.</p></dd></dl></div>
+<DIV CLASS="refsect1">
+<h2>Configuration File Variables</h2>
+<P CLASS="para">
+<A CLASS="xref" HREF="appc_01.html#appc-88529">
+Table C.1</a> lists of Samba configuration file variables. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="appc-88529">
+Table C.1: Variables in Alphabetic Order </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Meaning</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%a</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's architecture (one of Samba, WfWg, WinNT, Win95, or UNKNOWN)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%d</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current server process's processID </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%f</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Print-spool file as a relative path (printing only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%f</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+User from which a message was sent (messages only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%G</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary group name of <CODE CLASS="literal">
+%U</code> (requested username) </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%g</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary group name of <CODE CLASS="literal">
+%u</code> (actual username)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%H</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Home directory of <CODE CLASS="literal">
+%u</code> (actual username)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%h</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba server's (Internet) hostname</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%I</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's IP address </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%j</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Print job number (printing only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%L</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba server's NetBIOS name (virtual servers have multiple names)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%M</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's (Internet) hostname </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%m</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's NetBIOS name </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%n</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+New password (password change only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%N</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name of the NIS home directory server (without NIS, same as <CODE CLASS="literal">
+%L</code>)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%o</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Old password (password change only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%P</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's root directory (actual)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%p</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's root directory (in an NIS homedir map)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%p</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Print filename (printing only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%R</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Protocol level in use (one of CORE, COREPLUS, LANMAN1, LANMAN2, or NT1)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%S</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's name </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%s</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Filename the message is in (messages only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%s</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Print-spool file name (printing only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%T</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current date and time </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%t</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Destination machine (messages only)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%u</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's username </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%U</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Requested username for current share </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%v</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba version</p></td></tr></tbody></table></div></blockquote></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appb_03.html" TITLE="B.3 Sizing Samba Servers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: B.3 Sizing Samba Servers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="D. Summary of Samba Daemons and Commands">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: D. Summary of Samba Daemons and Commands" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+B.3 Sizing Samba Servers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+D. Summary of Samba Daemons and Commands</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appd_01.html b/docs/htmldocs/using_samba/appd_01.html
new file mode 100755
index 00000000000..5e3bd16aa46
--- /dev/null
+++ b/docs/htmldocs/using_samba/appd_01.html
@@ -0,0 +1,1907 @@
+<HTML>
+<HEAD>
+<TITLE>Appendix D</title>
+</head>
+
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="appc_01.html" TITLE="C. Samba Configuration Option Quick Reference">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: C. Samba Configuration Option Quick Reference" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix D</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appe_01.html" TITLE="E. Downloading Samba with CVS">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: E. Downloading Samba with CVS" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+
+<blockquote>
+<div class="samplechapter">
+<h1>Appendix D<br>
+Summary of Samba Daemons and Commands</h1>
+
+<p>
+This appendix is a reference listing of command-line options and other information to help you use the executables that come with Samba distribution.
+
+<DIV>
+<H2 CLASS="FM-HeadA">Samba Distribution Programs</h2>
+<P CLASS="Body">The following sections provide information about the command-line parameters for Samba programs.</p>
+<DIV>
+<H3 CLASS="HeadB">smbd</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbd</em>
+ program provides Samba's file and printer services, using one TCP/IP stream and one daemon per client. It is controlled from the default configuration file, <EM CLASS="Replaceable">samba_dir</em><EM CLASS="Emphasis">/lib/smb.conf</em>, and can be overridden by command-line options.</p>
+<P CLASS="Body">The configuration file is automatically re-evaluated every minute. If it has changed, most new options are immediately effective. You can force Samba to immediately reload the configuration file if you send a SIGHUP to <EM CLASS="Emphasis">smbd</em>
+. Reloading the configuration file, however, will not affect any clients that are already connected. To escape this &quot;grandfather&quot; configuration, a client would need to disconnect and reconnect, or the server itself would have to be restarted, forcing all clients to reconnect.</p>
+<DIV>
+<H4 CLASS="HeadC">Other signals</h4>
+<P CLASS="Body">To shut down a <EM CLASS="Emphasis">smbd</em>
+ process, send it the termination signal SIGTERM (-15) which allows it to die gracefully instead of a SIGKILL (-9). To increment the debug logging level of <EM CLASS="Emphasis">smbd</em>
+ at runtime, send the program a SIGUSR1 signal. To decrement it at runtime, send the program a SIGUSR2 signal. </p>
+</div>
+<DIV>
+<H4 CLASS="HeadC">Command-line options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-D</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">The <EM CLASS="Emphasis">smbd</em>
+ program is run as a daemon. This is the recommended way to use <EM CLASS="Emphasis">smbd</em> (it is also the default action). In addition, <EM CLASS="Emphasis">smbd</em> can also be run from <EM CLASS="Emphasis">inetd</em>.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">debuglevel</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (sometimes called logging) level. The level can range from 0 all the way to 10. Specifying the value on the command line overrides the value specified in the <EM CLASS="Filename">smb.conf</em>
+ file. Debug level 0 logs only the most important messages; level 1 is normal; levels 3 and above are primarily for debugging and slow <EM CLASS="Emphasis">smbd</em>
+ considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+ </h4>
+<UL>
+<LI CLASS="ListVariable">Prints command-line usage information for the <EM CLASS="Filename">smbd</em>
+ program.</li>
+</ul>
+<DIV>
+<H4 CLASS="HeadC">Testing/debugging options</h4>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-a</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">If this is specified, each new connection to the Samba server will append all logging messages to the log file. This option is the opposite of <EM CLASS="Literal">-o</em>, and is the default.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-i</em>
+ <EM CLASS="Replaceable">scope</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">&nbsp;</li>
+<LI CLASS="ListVariable">This sets a NetBIOS scope identifier. Only machines with the same identifier will communicate with the server. The scope identifier was a predecessor to workgroups, and this option is included only for backwards compatibility.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-l</em>
+ <EM CLASS="Replaceable">log_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Send the log messages to somewhere other than the location compiled in or specified in the <EM CLASS="Filename">smb.conf</em> file. The default is often <EM CLASS="Filename">/usr/local/samba/var/log.smb</em>, <EM CLASS="Filename">/usr/samba/var/log.smb,</em> or <EM CLASS="Filename">/var/log/log.smb</em>. The first two are strongly discouraged on Linux, where <EM CLASS="Filename">/usr</em>
+ may be a read-only filesystem. </li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-O</em>
+ <EM CLASS="Replaceable">socket_options</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets the TCP/IP socket options, using the same parameters as the <EM CLASS="Literal">socket</em>
+ <EM CLASS="Literal">options</em>
+ configuration option. It is often used for performance tuning and testing.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-o</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option is the opposite of <EM CLASS="Literal">-a</em>. It causes log files to be overwritten when opened. Using this option saves hunting for the right log entries if you are performing a series of tests and inspecting the log file each time.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-P</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option forces <EM CLASS="Filename">smbd</em>
+ not to send any network data out. This option is typically used only by Samba developers.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-P</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option forces <EM CLASS="Filename">smbd</em>
+ not to send any network data out. This option is typically used only by Samba developers. </li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-p</em>
+ <EM CLASS="Replaceable">port_number</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets the TCP/IP port number that the server will accept requests from. Currently, all Microsoft clients send only to the default port: 139.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">configuration_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the location of the Samba configuration file. Although the file defaults to <EM CLASS="Filename">/usr/local/samba/lib/smb.conf</em>, you can override it here on the command line, typically for debugging.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">nmbd</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">nmbd</em>
+ program is Samba's NetBIOS name and browsing daemon. It replies to broadcast NetBIOS over TCP/IP (NBT) name-service requests from SMB clients and optionally to Microsoft's Windows Internet Name Service (WINS) requests. Both of these are versions of the name-to-address lookup required by SMB clients. The broadcast version uses UDP/IP broadcast on the local subnet only, while WINS uses TCP/IP, which may be routed. If running as a WINS server, <EM CLASS="Emphasis">nmbd</em>
+ keeps a current name and address database in the file <EM CLASS="Filename">wins.dat</em> in the <EM CLASS="Literal">samba_dir</em><EM CLASS="Filename">/var/locks</em> directory.</p>
+<P CLASS="Body">An active <EM CLASS="Emphasis">nmbd</em>
+ program can also respond to browsing protocol requests used by the Windows Network Neighborhood. Browsing is a combined advertising, service announcement, and active directory protocol. This protocol provides a dynamic directory of servers and the disks and printers that the servers are providing. As with WINS, this was initially done by making UDP/IP broadcasts on the local subnet. Now, with the concept of a local master browser, it is done by making TCP/IP connections to a server. If <EM CLASS="Emphasis">nmbd</em>
+ is acting as a local master browser, it stores the browsing database in the file <EM CLASS="Filename">browse.dat</em> in the <EM CLASS="Literal">samba_dir</em><EM CLASS="Filename">/var/locks</em> directory.</p>
+<DIV>
+<H4 CLASS="HeadC">Signals</h4>
+<P CLASS="Body">Like <EM CLASS="Emphasis">smbd</em>, the <EM CLASS="Emphasis">nmbd</em> program responds to several Unix signals. Sending <EM CLASS="Emphasis">nmbd</em>
+ a SIGHUP signal will cause it to dump the names it knows about to the file <EM CLASS="Filename">namelist.debug</em>
+ in the <EM CLASS="Literal">samba_dir</em>
+/<EM CLASS="Emphasis">locks</em>
+ directory and its browsing database to the <EM CLASS="Filename">browse.dat </em>
+file in the same directory. To shut down a <EM CLASS="Emphasis">nmbd</em>
+ process send it a SIGTERM (-15) signal instead of a SIGKILL (-9) to allow it to die gracefully. You can increment the debug logging level of <EM CLASS="Emphasis">nmbd</em>
+ by sending it a SIGUSR1 signal; you can decrement it by sending a SIGUSR2 signal.</p>
+</div>
+<DIV>
+<H4 CLASS="HeadC">Command-line options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-D</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Instructs the <EM CLASS="Filename">nmbd</em>
+ program to run as a daemon. This is the recommended way to use <EM CLASS="Filename">nmbd</em>. In addition, <EM CLASS="Filename">nmbd</em> can also be run from <EM CLASS="FirstTerm">inetd</em>.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">debuglevel</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (sometimes called logging) level. The level can range from 0, all the way to 10. Specifying the value on the command line overrides the value specified in the <EM CLASS="Filename">smb.conf</em>
+ file. Debug level 0 logs only the most important messages; level 1 is normal; level 3 and above are primarily for debugging, and slow <EM CLASS="Emphasis">nmbd</em>
+ considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+ </h4>
+<UL>
+<LI CLASS="ListVariable">Prints command-line usage information for the <EM CLASS="Filename">nmbd</em> program (also <EM CLASS="Literal">-?</em>).</li>
+</ul>
+<DIV>
+<H4 CLASS="HeadC">Testing/debugging options</h4>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-a</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">If this is specified, each new connection to the Samba server will append all logging messages to the log file. This option is the opposite of <EM CLASS="Literal">-o</em>, and is the default.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-H</em>
+ <EM CLASS="Replaceable">hosts_ file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option loads a standard <EM CLASS="Emphasis">hosts</em>
+ file for name resolution. </li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-i</em>
+ <EM CLASS="Replaceable">scope</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets a NetBIOS scope identifier. Only machines with the same identifier will communicate with the server. The scope identifier was a predecessor to workgroups, and this option is included only for backward compatibility.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-l</em>
+ <EM CLASS="Replaceable">log_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sends the log messages to somewhere other than the location compiled-in or specified in the <EM CLASS="Filename">smb.conf</em> file. The default is often <EM CLASS="Filename">/usr/local/samba/var/log.nmb</em>, <EM CLASS="Filename">/usr/samba/var/log.nmb,</em> or <EM CLASS="Filename">/var/log/log.nmb</em>. The first two are strongly discouraged on Linux, where <EM CLASS="Filename">/usr</em>
+ may be a read-only filesystem. </li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-n</em>
+ <EM CLASS="Replaceable">NetBIOS_name</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option allows you to override the NetBIOS name by which the daemon will advertise itself. Specifying the option on the command line overrides the <EM CLASS="Literal">netbios</em>
+ <EM CLASS="Literal">name</em>
+ option in the Samba configuration file.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-O</em>
+ <EM CLASS="Replaceable">socket_options</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets the TCP/IP socket options, using the same parameters as the <EM CLASS="Literal">socket</em>
+ <EM CLASS="Literal">options</em>
+ configuration option. It is often used for performance tuning and testing.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-o</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option is the opposite of <EM CLASS="Literal">-a</em>
+. It causes log files to be overwritten when opened. Using this option saves hunting for the right log entries if you are performing a series of tests and inspecting the log file each time.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-p</em>
+ <EM CLASS="Replaceable">port_number</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets the UDP/IP port number from which the server will accept requests. Currently, all Microsoft clients send only to the default port: 137.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">configuration_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the location of the Samba configuration file. Although the file defaults to <EM CLASS="Filename">/usr/local/samba/lib/smb.conf</em>, you can override it here on the command line, typically for debugging.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-v</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option prints the current version of Samba.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">Samba Startup File </h3>
+<P CLASS="Body">Samba is normally started by running it from your Unix system's <EM CLASS="Filename">rc</em>
+ files at boot time. For systems with a System V-like set of <EM CLASS="Filename">/etc/rcN.d</em>
+ directories, this can be done by placing a suitably named script in the <EM CLASS="Filename">/rc</em>
+ directory. Usually, the script starting Samba is called <EM CLASS="Emphasis">S91samba</em>
+, while the script stopping or &quot;killing&quot; Samba is called <EM CLASS="Emphasis">K91samba. </em>
+On Linux, the usual subdirectory for the scripts is <EM CLASS="Filename">/etc/rc2.d.</em>
+ On Solaris, the directory is <EM CLASS="Filename">/etc/rc3.d</em>
+. For machines with <EM CLASS="Filename">/etc/rc.local</em>
+ files, you would normally add the following lines to that file:</p>
+<P CLASS="Code">/usr/local/samba/bin/smbd -D</p>
+<P CLASS="Code">/usr/local/samba/bin/nmbd -D </p>
+<P CLASS="Body">The following example script supports two extra commands, <EM CLASS="Literal">status</em>
+ and <EM CLASS="Literal">restart</em>, in addition to the normal <EM CLASS="Literal">start</em>
+ and <EM CLASS="Literal">stop</em>
+ for System V machines:</p>
+
+<pre>
+#!/bin/sh
+#
+# /etc/rc2.d./S91Samba --manage the SMB server in a System V manner
+#
+OPTS=&quot;-D&quot;
+#DEBUG=-d3
+PS=&quot;ps ax&quot;
+SAMBA_DIR=/usr/local/samba
+case &quot;$1&quot; in
+'start')
+ echo &quot;samba &quot;
+ $SAMBA_DIR/bin/smbd $OPTS $DEBUG
+ $SAMBA_DIR/bin/nmbd $OPTS $DEBUG
+ ;;
+'stop')
+ echo &quot;Stopping samba&quot;
+ $PS | awk '/usr.local.samba.bin/ { print $1}' |&#92;
+ xargs kill
+ ;;
+'status')
+ x=`$PS | grep -v grep | grep '$SAMBA_DIR/bin'`
+ if [ ! &quot;$x&quot; ]; then
+ echo &quot;No samba processes running&quot;
+ else
+ echo &quot; PID TT STAT TIME COMMAND&quot;
+ echo &quot;$x&quot;
+ fi
+ ;;
+'restart')
+ /etc/rc2.d/S91samba stop
+ /etc/rc2.d/S91samba start
+ /etc/rc2.d/S91samba status
+ ;;
+*)
+ echo &quot;$0: Usage error -- you must say $0 start, stop, status or restart.&quot;
+ ;;
+esac
+exit
+</pre>
+<P CLASS="Body">You'll need to set the actual paths and <EM CLASS="Literal">ps</em>
+ options to suit the machine you're using. In addition, you might want to add additional commands to tell Samba to reload its <EM CLASS="Filename">smb.conf</em>
+ file or dump its <EM CLASS="Emphasis">nmbd</em>
+ tables, depending on your actual needs. </p>
+</div>
+<DIV>
+<H3 CLASS="HeadB">smbsh</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbsh</em>
+ program lets you use a remote Windows share on your Samba server as if the share was a regular Unix directory. When it's run, it provides an extra directory tree under <EM CLASS="Filename">/smb</em>. Subdirectories of <EM CLASS="Filename">/smb</em>
+ are servers, and subdirectories of the servers are their individual disk and printer shares. Commands run by <EM CLASS="Emphasis">smbsh</em>
+ treat the <EM CLASS="Filename">/smb</em>
+ filesystem as if it were local to Unix. This means that you don't need <EM CLASS="Emphasis">smbmount</em>
+ in your kernel to mount Windows filesystems the way you mount with NFS filesystems. However, you do need to configure Samba with the <EM CLASS="Literal">--with-smbwrappers</em>
+ option to enable <EM CLASS="Filename">smbsh</em>.</p>
+<DIV>
+<H4 CLASS="HeadC">Options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ debuglevel</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (sometimes called logging) level. The level can range from 0, the default, all the way to 10. Debug level 0 logs only the most important messages; level 1 is normal; level 3 and above are primarily for debugging, and slow <EM CLASS="Emphasis">smbsh</em>
+ considerably.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-l</em>
+ <EM CLASS="Replaceable">logfile</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the name of the logfile to use.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-P</em>
+ <EM CLASS="Replaceable">prefix</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the root directory to mount the SMB filesystem. The default is <EM CLASS="Filename">/smb</em>.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-R</em>
+ <EM CLASS="Replaceable">resolve order</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the resolve order of the name servers. This option is similar to the <EM CLASS="Literal">resolve order</em>
+ configuration option, and can take any of the four parameters, <EM CLASS="Literal">lmhosts</em>, <EM CLASS="Literal">host</em>, <EM CLASS="Literal">wins</em>, and <EM CLASS="Literal">bcast</em>, in any order.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-U</em>
+ <EM CLASS="Replaceable">user</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Supports <EM CLASS="Replaceable">user%password.</em>
+</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-W</em>
+ <EM CLASS="Replaceable">workgroup</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the NetBIOS workgroup to which the client will connect.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">smbclient</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbclient</em>
+ program is the maid-of-all-work of the Samba suite. Initially intended as a testing tool, it has become a full command-line Unix client, with an FTP-like interactive client. Some of its options are still used for testing and tuning, and it makes a simple tool for ensuring that Samba is running on a server.</p>
+<P CLASS="Body">It's convenient to look at <EM CLASS="Emphasis">smbclient</em>
+ as a suite of programs:</p>
+<UL>
+<LI CLASS="ListBullet">FTP-like interactive file transfer program</li>
+<LI CLASS="ListBullet">Interactive printing program</li>
+<LI CLASS="ListBullet">Interactive tar program </li>
+<LI CLASS="ListBullet">Command-line message program</li>
+<LI CLASS="ListBullet">Command-line <EM CLASS="Emphasis">tar</em>
+ program (but see <EM CLASS="Emphasis">smbtar</em>
+ later)</li>
+<LI CLASS="ListBullet">&quot;What services do you have&quot; query program</li>
+<LI CLASS="ListBullet">Command-line debugging program</li>
+</ul>
+<DIV>
+<H4 CLASS="HeadC">General command-line options</h4>
+<P CLASS="Body">The program has the usual set of <EM CLASS="Emphasis">smbd</em>
+-like options, which apply to all the interactive and command-line use. The syntax is:</p>
+<P CLASS="Code">smbclient //<EM CLASS="Replaceable">server_name</em>
+/<EM CLASS="Replaceable">share_name</em>
+ [<EM CLASS="Replaceable">password</em>
+] [-<EM CLASS="Replaceable">options</em>
+]</p>
+<P CLASS="Body">Here is an explanation of each of the command-line options:</p>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">debug_level</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (logging) level, from 0 to 10, with <EM CLASS="Literal">A</em>
+ for all. Overrides the value in <EM CLASS="Filename">smb.conf</em>. Debug level 0 logs only the most important messages; level 1 is normal; debug level 3 and above are for debugging, and slow <EM CLASS="Emphasis">smbclient</em>
+ considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints the command-line help information (usage) for smbclient.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-n</em>
+ <EM CLASS="Replaceable">NetBIOS_name</em>
+</h4>
+<P CLASS="ListSimple">Allows you to override the NetBIOS name by which the program will advertise itself. </p>
+<DIV>
+<H4 CLASS="HeadC">Smbclient operations</h4>
+<P CLASS="Body">Running <EM CLASS="Literal">smbclient</em><EM CLASS="Literal">//</em><EM CLASS="Replaceable">server_name</em><EM CLASS="Literal">/</em><EM CLASS="Replaceable">share</em>
+ will cause it to prompt you for a username and password. If the login is successful, it will connect to the share and give you a prompt much like an FTP prompt (the backslash in the prompt will be replaced by the current directory within the share as you move around the filesystem):</p>
+<P CLASS="Code">smb:&#92;&gt;</p>
+<P CLASS="Body">From this command line, you can use several FTP-like commands, as listed below. Arguments in square brackets are optional. </p>
+<TABLE>
+<CAPTION>
+<H4 CLASS="TableLabel"><A NAME="89417"></a>&nbsp;</h4>
+<H4 CLASS="TableTitle">smbclient Commands </h4>
+</caption>
+<TR>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Command</p>
+</th>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Description</p>
+</th>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">?</em>
+ <EM CLASS="Replaceable">command</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Provides list of commands or help on specified command.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">help</em>
+ [<EM CLASS="Replaceable">command</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Provides list of commands or help on specified command.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">!</em>
+ [<EM CLASS="Replaceable">command</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">If a command is specified, it will be run in a local shell. If not, you will be placed into a local shell on the client.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">dir</em>
+ [<EM CLASS="Replaceable">filename</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Displays any files matching <EM CLASS="Replaceable">filename</em>
+ in the current directory on the server, or all files if <EM CLASS="Replaceable">filename</em>
+ is omitted.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">ls</em>
+ [<EM CLASS="Replaceable">filename</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Displays any files matching <EM CLASS="Replaceable">filename</em>
+ in the current directory on the server, or all files if <EM CLASS="Replaceable">filename</em>
+ is omitted.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">cd</em>
+ [<EM CLASS="Replaceable">directory</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">If <EM CLASS="Replaceable">directory</em>
+ is specified, changes to the specified directory on the remote server. If not, reports the current directory on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">lcd</em>
+ [<EM CLASS="Replaceable">directory</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">If <EM CLASS="Replaceable">directory</em>
+ is specified, the current directory on the local machine will be changed. If not, the name of the current directory on the local machine will be reported.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">get</em>
+ <EM CLASS="Emphasis">remotefile </em>
+[<EM CLASS="Replaceable">localfile</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Copies the file <EM CLASS="Replaceable">remotefile</em> to the local machine. If a <EM CLASS="Replaceable">localfile</em>
+ is specified, uses that name to copy the file to. Treats the file as binary; does <EM CLASS="Emphasis">not</em>
+ do LF to CR/LF conversions.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">put</em>
+ <EM CLASS="Emphasis">localfile </em>
+[<EM CLASS="Replaceable">remotefile</em>]</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Copies <EM CLASS="Replaceable">localfile</em>
+ to the remote machine. If a <EM CLASS="Replaceable">remotefile</em>
+ is specified, uses that as the name to copy to on the remote server. Treats the file as binary; does <EM CLASS="Emphasis">not</em>
+ do LF to CR/LF conversions.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">mget</em>
+ <EM CLASS="Replaceable">pattern</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Gets all files matching <EM CLASS="Replaceable">pattern</em>
+ from the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">mput</em>
+<EM CLASS="Replaceable"> pattern</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Places all local files matching <EM CLASS="Replaceable">pattern</em>
+ on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">prompt</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Toggles interactive prompting on and off for <EM CLASS="Literal">mget</em> and <EM CLASS="Literal">mput</em>.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">lowercase ON </em>
+ <br>
+
+(or<EM CLASS="Literal"> OFF</em>)</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">If lowercase is on, <EM CLASS="Emphasis">smbclient</em>
+ will convert filenames to lowercase during an <EM CLASS="Literal">mget</em>
+ or <EM CLASS="Literal">get</em>
+ (but not a <EM CLASS="Literal">mput</em> or <EM CLASS="Literal">put</em>).</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">del</em>
+ <EM CLASS="Replaceable">filename</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Delete a file on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">md</em>
+ <EM CLASS="Replaceable">directory</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Create a directory on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">mkdir</em>
+ <EM CLASS="Replaceable">directory</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Create a directory on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">rd</em>
+ <EM CLASS="Replaceable">directory</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Remove the specified directory on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">rmdir</em>
+ <EM CLASS="Replaceable">directory</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Remove the specified directory on the remote machine.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">setmode</em>
+ <EM CLASS="Replaceable">filename</em>
+ <EM CLASS="Literal">[+|-]rsha</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Set DOS filesystem attribute bits, using Unix-like modes. <EM CLASS="Literal">r</em>
+ is read-only, <EM CLASS="Literal">s</em>
+ is system, <EM CLASS="Literal">h</em>
+ is hidden, and <EM CLASS="Literal">a</em>
+ is archive.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">exit</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Exits <EM CLASS="Emphasis">smbclient</em>.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">quit</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Exits <EM CLASS="Emphasis">smbclient</em>.</p>
+</td>
+</tr>
+</table>
+<P CLASS="Body">There are also mask and recursive commands for large copies; see the <EM CLASS="Filename">smbclient</em>
+ manual page for details on how to use these. With the exception of mask, recursive, and the lack of an ASCII transfer mode, <EM CLASS="Emphasis">smbclient</em>
+ works exactly the same as FTP. Note that because it does binary transfers, Windows files copied to Unix will have lines ending in carriage-return and linefeed (<EM CLASS="Literal">&#92;r&#92;n</em>), not Unix's linefeed (<EM CLASS="Literal">&#92;n</em>).</p>
+</div>
+<DIV>
+<H4 CLASS="HeadC">Printing commands</h4>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbclient</em>
+ program can also be used for access to a printer by connecting to a print share. Once connected, the commands shown below can be used to print. </p>
+<TABLE>
+<CAPTION>
+<H4 CLASS="TableLabel"><A NAME="39300"></a>&nbsp;</h4>
+<H4 CLASS="TableTitle">smbclient Printing Commands </h4>
+</caption>
+<TR>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Command</p>
+</th>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Description</p>
+</th>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">print</em>
+<EM CLASS="Replaceable"> filename</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Prints the file by copying it from the local machine to the remote one and then submitting it as a print job there.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">printmode</em>
+ <EM CLASS="Replaceable">text </em>
+|<EM CLASS="Replaceable"> graphics</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Instructs the server that the following files will be plain text (ASCII) or the binary graphics format that the printer requires. It's up to the user to ensure that the file is indeed the right kind.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">queue</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Displays the queue for the print share you're connected to, showing job ID, name, size, and status.</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+<DIV>
+<H4 CLASS="SidebarBody">Finally, to print from the <EM CLASS="Emphasis">smbclient</em>, use the <EM CLASS="Literal">-c</em>
+ option:</h4>
+<P CLASS="Code">cat <EM CLASS="Replaceable">printfile</em>
+ | smbclient //<EM CLASS="Replaceable">server</em>
+/<EM CLASS="Replaceable">printer_name</em>
+ -c &quot;print -&quot;</p>
+<DIV>
+<H4 CLASS="HeadC">Tar commands</h4>
+<P CLASS="Body"><EM CLASS="Emphasis">smbclient</em>
+ can tar up files from a file share. This is normally done from the command line using the <EM CLASS="Emphasis">smbtar</em>
+ command, but the commands shown below are also available interactively. </p>
+<TABLE>
+<CAPTION>
+<H4 CLASS="TableLabel"><A NAME="54517"></a>&nbsp;</h4>
+<H4 CLASS="TableTitle">smbclient Tar Commands </h4>
+</caption>
+<TR>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Command</p>
+</th>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Description</p>
+</th>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">tar c|x[IXbgNa]</em>
+ <EM CLASS="Replaceable">operands</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Performs a creation or extraction <EM CLASS="Emphasis">tar</em> similar to the command-line program. </p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">blocksize</em>
+ <EM CLASS="Replaceable">size</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Sets the block size to be used by <EM CLASS="Emphasis">tar</em>, in 512-byte blocks.</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">tarmode full|inc|reset|<br>
+
+noreset</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Makes <EM CLASS="Emphasis">tar</em>
+ pay attention to DOS archive bit for all following commands. In <EM CLASS="Literal">full</em>
+ mode (the default), <EM CLASS="Emphasis">tar</em>
+ will back up everything. In <EM CLASS="Literal">inc</em>
+ (incremental) mode, <EM CLASS="Emphasis">tar</em>
+ will back up only those files with the archive bit set. In <EM CLASS="Literal">reset</em>
+ mode, <EM CLASS="Emphasis">tar</em>
+ will reset the archive bit on all files it backs up (this requires the share to be writable), and in <EM CLASS="Literal">noreset</em>
+ mode the archive bit will not be reset even after the file has been backed up.</p>
+</td>
+</tr>
+</table>
+</div>
+<DIV>
+<H4 CLASS="HeadC">Command-line message program options</h4>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-M</em>
+ <EM CLASS="Replaceable">NetBIOS_machine_name</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option allows you to send immediate messages using the WinPopup protocol to another computer. Once a connection is established, you can type your message, pressing control-D to end. If WinPopup is not running on the receiving machine, the program returns an error.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-U</em>
+ <EM CLASS="Replaceable">user</em>
+ </h4>
+<UL>
+<LI CLASS="ListVariable">This<EM CLASS="Replaceable"> </em>
+option allows you to indirectly control the FROM part of the message. </li>
+</ul>
+<DIV>
+<H4 CLASS="HeadC">Command-line tar program options</h4>
+<P CLASS="Body">The <EM CLASS="Literal">-T</em>
+ (tar), <EM CLASS="Literal">-D</em>
+ (starting directory), and <EM CLASS="Literal">-c</em>
+ (command) options are used together to tar up files interactively. This is better done with <EM CLASS="Filename">smbtar</em>, which will be discussed shortly. We don't recommend using <EM CLASS="Emphasis">smbclient</em>
+ directly as a <EM CLASS="Emphasis">tar</em>
+ program. </p>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-D</em>
+ <EM CLASS="Replaceable">initial_directory</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Changes to initial directory before starting.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-c</em>
+ <EM CLASS="Replaceable">command_string</em>
+ </h4>
+<UL>
+<LI CLASS="ListVariable">Passes a command string to the <EM CLASS="Emphasis">smbclient</em>
+ command interpreter, which treats it as a semicolon-separated list of commands to be executed. This is handy to say things such as <EM CLASS="Literal">tarmode</em> <EM CLASS="Literal">inc</em>, for example, which forces <EM CLASS="Literal">smbclient</em>
+ <EM CLASS="Literal">-T</em>
+ to back up only files with the archive bit set.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-T</em>
+ <EM CLASS="Replaceable">command filename</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Runs the <EM CLASS="Emphasis">tar</em>
+ driver, which is <EM CLASS="Emphasis">gtar</em>
+ compatible. The two main commands are: <EM CLASS="Literal">c</em>
+ (create) and <EM CLASS="Literal">x</em>
+ (extract), which may be followed by any of:</li>
+</ul>
+<DIV>
+<H4 CLASS="FM-ListVariableTermRunin"><EM CLASS="Literal">a</em>
+</h4>
+<P CLASS="FM-ListVariable">Resets archive bits once files are saved.</p>
+</div>
+<DIV>
+<H5 CLASS="FM-ListVariableTerm"><EM CLASS="Literal">b</em>
+ <EM CLASS="Replaceable">size</em>
+</h5>
+<P CLASS="FM-ListVariable">Sets blocksize in 512-byte units.</p>
+<DIV>
+<H4 CLASS="FM-ListVariableTermRunin"><EM CLASS="Literal">g</em>
+</h4>
+<P CLASS="FM-ListVariable">Backs up only files with the archive bit set.</p>
+</div>
+</div>
+<DIV>
+<H5 CLASS="FM-ListVariableTerm"><EM CLASS="Literal">I</em>
+ <EM CLASS="Replaceable">file</em>
+</h5>
+<P CLASS="FM-ListVariable">Includes files and directories (this is the default). Does not do pattern-matching.</p>
+</div>
+<DIV>
+<H5 CLASS="FM-ListVariableTerm"><EM CLASS="Literal">N</em>
+ <EM CLASS="Replaceable">filename</em>
+</h5>
+<P CLASS="FM-ListVariable">Backs up only those files newer than <EM CLASS="Replaceable">filename.</em>
+</p>
+<DIV>
+<H4 CLASS="FM-ListVariableTermRunin"><EM CLASS="Literal">q</em>
+</h4>
+<P CLASS="FM-ListVariable">Does not produce diagnostics.</p>
+</div>
+</div>
+<DIV>
+<H5 CLASS="FM-ListVariableTerm"><EM CLASS="Literal">X</em>
+ <EM CLASS="Replaceable">file</em>
+</h5>
+<P CLASS="FM-ListVariable">Excludes files.</p>
+<DIV>
+<H4 CLASS="HeadC">Command-line query program</h4>
+<P CLASS="Body">If <EM CLASS="Filename">smbclient</em>
+ is run as:</p>
+<P CLASS="Code">smbclient -L <EM CLASS="Replaceable">server_name</em>
+</p>
+<P CLASS="Body">it will list the shares and other services that machine provides. This is handy if you don't have <EM CLASS="Filename">smbwrappers</em>. It can also be helpful as a testing program in its own right.</p>
+</div>
+<DIV>
+<H4 CLASS="HeadC">Command-line debugging /diagnostic program options</h4>
+<P CLASS="Body">Any of the various modes of operation of <EM CLASS="Emphasis">smbclient</em>
+ can be used with the debugging and testing command-line options:</p>
+</div>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-B</em>
+ <EM CLASS="Replaceable">IP_addr</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the broadcast address.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">debug_level</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (sometimes called logging) level. The level can range from 0 all the way to 10. In addition, you can specify <EM CLASS="Literal">A</em>
+ for all debugging options. Debug level 0 logs only the most important messages; level 1 is normal; level 3 and above are primarily for debugging and slow operations considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-E</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sends all messages to stderr instead of stdout.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-I</em>
+ <EM CLASS="Replaceable">IP_address</em>
+ </h4>
+<UL>
+<LI CLASS="ListVariable">Sets the IP address of the server to which it connects.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-i</em>
+ <EM CLASS="Replaceable">scope</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This sets a NetBIOS scope identifier. Only machines with the same identifier will communicate with the server. The scope identifier was a predecessor to workgroups, and this option is included only for backward compatibility.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-l</em>
+ <EM CLASS="Replaceable">log_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sends the log messages to the specified file. </li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-N</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Suppresses the password prompt. Unless a password is specified on the command line or this parameter is specified, the client will prompt for a password.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-n</em>
+ <EM CLASS="Replaceable">NetBIOS_name</em>
+</h4>
+<P CLASS="ListSimple">This option allows you to override the NetBIOS name by which the daemon will advertise itself. </p>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-O</em>
+ <EM CLASS="Replaceable">socket_options</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the TCP/IP socket options using the same parameters as the <EM CLASS="Literal">socket</em>
+ <EM CLASS="Literal">options</em>
+ configuration option. It is often used for performance tuning and testing.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-p</em>
+ <EM CLASS="Replaceable">port_number</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the port number from which the client will accept requests. </li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-R</em>
+ <EM CLASS="Replaceable">resolve_order</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the resolve order of the name servers. This option is similar to the <EM CLASS="Literal">resolve</em>
+ <EM CLASS="Literal">order</em>
+ configuration option, and can take any of the four parameters, <EM CLASS="Literal">lmhosts</em>, <EM CLASS="Literal">host</em>, <EM CLASS="Literal">wins</em>, and <EM CLASS="Literal">bcast</em>, in any order.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">configuration_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the location of the Samba configuration file. Used for debugging.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-t</em>
+ <EM CLASS="Replaceable">terminal_code</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the terminal code for Asian languages.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-U</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the username and optionally password (e.g., <EM CLASS="Literal">-U</em>
+ <EM CLASS="Literal">fred%secret</em>).</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-W</em>
+ <EM CLASS="Replaceable">workgroup</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the workgroup that you want the client to connect as.</li>
+</ul>
+<P CLASS="Body">If you want to test a particular name service, run <EM CLASS="Emphasis">smbclient</em>
+ with <EM CLASS="Literal">-R</em>
+ and just the name of the service. This will force <EM CLASS="Emphasis">smbclient</em>
+ to use only the service you gave.<EM CLASS="Emphasis"></em>
+</p>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">smbstatus</h3>
+<P CLASS="Body">The <EM CLASS="Filename">smbstatus</em>
+ program lists the current connections on a Samba server. There are three separate sections. The first section lists various shares that are in use by specific users. The second section lists the locked files that Samba currently has on all of its shares. Finally, the third section lists the amount of memory usage for each of the shares. For example:</p>
+<pre>
+# <EM CLASS="LineEmphasis">smbstatus</em>
+
+Samba version 2.0.3
+Service uid gid pid machine
+----------------------------------------------
+network davecb davecb 7470 phoenix (192.168.220.101) Sun May 16
+network davecb davecb 7589 chimaera (192.168.220.102) Sun May 16
+&nbsp;
+Locked files:
+Pid DenyMode R/W Oplock Name
+--------------------------------------------------
+7589 DENY_NONE RDONLY EXCLUSIVE+BATCH /home/samba/quicken/inet/common/system/help.bmp Sun May 16 21:23:40 1999
+7470 DENY_WRITE RDONLY NONE /home/samba/word/office/findfast.exe Sun May 16 20:51:08 1999
+7589 DENY_WRITE RDONLY EXCLUSIVE+BATCH /home/samba/quicken/lfbmp70n.dll Sun May 16 21:23:39 1999
+7589 DENY_WRITE RDWR EXCLUSIVE+BATCH /home/samba/quicken/inet/qdata/runtime.dat Sun May 16 21:23:41 1999
+7470 DENY_WRITE RDONLY EXCLUSIVE+BATCH /home/samba/word/office/osa.exe Sun May 16 20:51:09 1999
+7589 DENY_WRITE RDONLY NONE /home/samba/quicken/qversion.dll Sun May 16 21:20:33 1999
+7470 DENY_WRITE RDONLY NONE /home/samba/quicken/qversion.dll Sun May 16 20:51:11 1999
+&nbsp;
+Share mode memory usage (bytes):
+ 1043432(99%) free + 4312(0%) used + 832(0%) overhead = 1048576(100%) total
+</pre>
+<DIV>
+<H4 CLASS="HeadC">Options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-b</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Forces <EM CLASS="Filename">smbstatus</em>
+ to produce brief output. This includes the version of Samba and auditing information about the users that have logged into the server.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-d</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Gives verbose output, including each of the three reporting sections listed in the previous example. This is the default.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-L</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Forces <EM CLASS="Filename">smbstatus</em>
+ to print only the current file locks it has. This corresponds to the second section in a verbose output. </li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-p</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints a list of <EM CLASS="Filename">smbd</em>
+ process IDs only. This is often used for scripts.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-S</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints only a list of shares and their connections. This corresponds to the first section in a verbose output.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">configuration_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the Samba configuration file to use when processing this command.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-u</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Limits the <EM CLASS="Filename">smbstatus</em>
+ report to the activity of a single user.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">smbtar</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbtar</em>
+ program is a shell script on top of <EM CLASS="Emphasis">smbclient</em>
+ that gives the program more intelligible options when doing tar operations. Functionally, it is equivalent to the Unix <EM CLASS="Emphasis">tar</em>
+ program.</p>
+<DIV>
+<H4 CLASS="HeadC">Options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-a</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Resets the archive bit mode</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-b</em>
+ <EM CLASS="Replaceable">blocksize</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Blocking size. Defaults to 20.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">directory</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Changes to initial directory before restoring or backing up files.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-i</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Incremental mode; tar files are backed up only if they have the DOS archive bit set. The archive bit is reset after each file is read.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-l</em>
+ <EM CLASS="Replaceable">log_level</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable"> Sets the logging level.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-N</em>
+ <EM CLASS="Replaceable">filename</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Backs up only the files newer than the last modification date of <EM CLASS="Replaceable">filename</em>. For incremental backups.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-p</em>
+ <EM CLASS="Replaceable">password</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the password to use to access a share.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-r</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Restores files to the share from the tar file.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">server</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the SMB/CIFS server in which the share resides.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-t</em>
+ <EM CLASS="Replaceable">tape</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Tape device or file. Default is the value of the environment variable <EM CLASS="Literal">$TAPE</em>, or <EM CLASS="Emphasis">tar.out</em>
+ if <EM CLASS="Literal">$TAPE</em>
+ isn't set.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-u</em>
+ <EM CLASS="Replaceable">user</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the user to connect to the share as. You can specify the password as well, in the format <EM CLASS="Replaceable">username</em><EM CLASS="Literal">%</em><EM CLASS="Replaceable">password</em>.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-v</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the use of verbose mode.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-X</em>
+ <EM CLASS="Replaceable">file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Tells <EM CLASS="FirstTerm">smbtar</em>
+ to exclude the specified file from the <EM CLASS="Emphasis">tar</em>
+ create or restore.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-x</em>
+ <EM CLASS="Replaceable">share</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">States the share name on the server to connect to. The default is <EM CLASS="Literal">backup</em>, which is a common share name to perform backups with.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="SidebarBody">For example, a trivial backup command to archive the data for user <EM CLASS="Literal">sue</em>
+ is:</h4>
+<P CLASS="Code"># <EM CLASS="LineEmphasis">smbtar -s pc_name -x sue -u sue -p secret -t sue.tar </em>
+</p>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">nmblookup</h3>
+<P CLASS="Body">The <EM CLASS="Filename">nmblookup</em>
+ program is a client program that exercises the NetBIOS-over-UDP/IP name service for resolving NBT machine names into IP addresses. The command works by broadcasting its queries on the local subnet until a machine with that name responds. You can think of it as a Windows <EM CLASS="Emphasis">nslookup(1) </em>
+or <EM CLASS="EmailSite">dig(1). </em>
+This is useful for looking up both normal NetBIOS names, and the odd ones like <EM CLASS="Literal">__MSBROWSE__</em>
+ that the Windows name services use to provide directory-like services. If you wish to query for a particular type of NetBIOS name, add the NetBIOS <EM CLASS="Literal">&lt;type&gt;</em>
+ to the end of the name.</p>
+<P CLASS="Body">The command line is:</p>
+<P CLASS="Code">nmblookup [-options] <EM CLASS="Replaceable">name</em>
+</p>
+<P CLASS="Body">The options supported are:</p>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-A</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Interprets <EM CLASS="Replaceable">name</em>
+ as an IP address and do a node-status query on this address.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-B</em>
+ <EM CLASS="Replaceable">broadcast _address</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sends the query to the given broadcast address. The default is to send the query to the broadcast address of the primary network interface.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">debuglevel</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (sometimes called logging) level. The level can range from 0 all the way to 10. Debug level 0 logs only the most important messages; level 1 is normal; level 3 and above are primarily for debugging and slow the program considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints command-line usage information for the program.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-i</em>
+ <EM CLASS="Replaceable">scope</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets a NetBIOS scope identifier. Only machines with the same identifier will communicate with the server. The scope identifier was a predecessor to workgroups, and this option is included only for backward compatibility.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-M</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Searches for a local master browser. This is done with a broadcast searching for a machine that will respond to the special name <EM CLASS="Literal">__MSBROWSE__</em>, and then asking that machine for information, instead of broadcasting the query itself.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-R</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the recursion desired bit in the packet. This will cause the machine that responds to try to do a WINS lookup and return the address and any other information the WINS server has saved.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-r</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Use the root port of 137 for Windows 95 machines.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-S</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Once the name query has returned an IP address, does a node status query as well. This returns all the resource types that the machine knows about, with their numeric attributes. For example:</li>
+</ul>
+<pre>
+% <EM CLASS="LineEmphasis">nmblookup -d 4 -S elsbeth</em>
+received 6 names
+ ELSBETH &lt;00&gt; - &lt;GROUP&gt; B &lt;ACTIVE&gt;
+ ELSBETH &lt;03&gt; - B &lt;ACTIVE&gt;
+ ELSBETH &lt;1d&gt; - B &lt;ACTIVE&gt;
+ ELSBETH &lt;1e&gt; - &lt;GROUP&gt; B &lt;ACTIVE&gt;
+ ELSBETH &lt;20&gt; - B &lt;ACTIVE&gt;
+ ..__MSBROWSE__.. &lt;01&gt; - &lt;GROUP&gt; B &lt;ACTIVE&gt;
+</pre>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">configuration_file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies the location of the Samba configuration file. Although the file defaults to <EM CLASS="Filename">/usr/local/samba/lib/smb.conf</em>, you can override it here on the command-line, normally for debugging.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-T</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option can be used to translate IP addresses into resolved names. </li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-U</em>
+ <EM CLASS="Replaceable">unicast_address</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Performs a unicast query to the specified address. Used with <EM CLASS="Literal">-R</em>
+ to query WINS servers.</li>
+</ul>
+<P CLASS="Body">Note that there is no workgroup option for <EM CLASS="Emphasis">nmblookup</em>; you can get around this by putting <EM CLASS="Literal">workgroup</em>
+ <EM CLASS="Literal">=</em>
+ <EM CLASS="Replaceable">workgroup_name </em>
+in a file and passing it to <EM CLASS="Emphasis">nmblookup</em>
+ with the <EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">smb.conf_file</em>
+ option. </p>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">smbpasswd</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">smbpasswd</em>
+ password has two distinct sets of functions. When run by users, it changes their encrypted passwords. When run by <EM CLASS="Literal">root</em>, it updates the encrypted password file. When run by an ordinary user with no options, it connects to the primary domain controller and changes his or her Windows password.</p>
+<P CLASS="Body">The program will fail if <EM CLASS="Emphasis">smbd</em>
+ is not operating, if the <EM CLASS="Literal">hosts</em>
+ <EM CLASS="Literal">allow</em>
+ or <EM CLASS="Literal">hosts</em>
+ <EM CLASS="Literal">deny</em>
+ configuration options will not permit connections from localhost (IP address 127.0.0.1), or the <EM CLASS="Literal">encrypted</em>
+ <EM CLASS="Literal">passwords</em>
+ <EM CLASS="Literal">=</em>
+ <EM CLASS="Literal">no</em>
+ option is set.</p>
+<DIV>
+<H4 CLASS="HeadC">Regular user options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-D</em>
+ <EM CLASS="Replaceable">debug_level</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the debug (also called logging) level. The level can range from 0 to 10. Debug level 0 logs only the most important messages; level 1 is normal; level 3 and above are primarily for debugging and slow the program considerably.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints command-line usage information for the program.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-r</em>
+ <EM CLASS="Replaceable">remote_machine_name</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Specifies on which machine the password should change. The remote machine must be a primary domain controller (PDC).</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-R</em>
+ <EM CLASS="Replaceable">resolve_order</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets the resolve order of the name servers. This option is similar to the <EM CLASS="Literal">resolve</em>
+ <EM CLASS="Literal">order</em>
+ configuration option, and can take any of the four parameters, <EM CLASS="Literal">lmhosts</em>, <EM CLASS="Literal">host</em>, <EM CLASS="Literal">wins</em>, and <EM CLASS="Literal">bcast</em>,<EM CLASS="Literal"> </em> in any order.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-U</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Used only with <EM CLASS="Literal">-r</em>, to modify a username that is spelled differently on the remote machine.</li>
+</ul>
+<DIV>
+<H4 CLASS="HeadC">Root-only options</h4>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-a</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Adds a user to the encrypted password file.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-d</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Disables a user in the encrypted password file.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-e</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Enables a disabled user in the encrypted password file.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-m</em>
+ <EM CLASS="Replaceable">machine_name</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Changes a machine account's password. The machine accounts are used to authenticate machines when they connect to a primary or backup domain controller.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-j</em>
+ <EM CLASS="Replaceable">domain_name</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Adds a Samba server to a Windows NT Domain.</li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-n</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Sets no password for the user.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">username</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Causes <EM CLASS="Emphasis">smbpasswd</em>
+ to be silent and to read its old and new passwords from standard input, rather than from <EM CLASS="Filename">/dev/tty</em>. This is useful for writing scripts.</li>
+</ul>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">testparm</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">testparm</em>
+ program checks an <EM CLASS="Filename">smb.conf</em>
+ file for obvious errors and self-consistency. Its command line is:</p>
+<P CLASS="Code">testparm [options] <EM CLASS="Replaceable">configfile_name [hostname IP_addr]</em>
+</p>
+<P CLASS="Body">If the configuration file is not specified, the file at <EM CLASS="Replaceable">samba_dir</em>
+<EM CLASS="Filename">/lib/smb.conf</em>
+ is checked by default. If you specify a hostname and an IP address, an extra check will be made to ensure that the specified machine would be allowed to connect to Samba. If a hostname is specified, an IP address should be present as well.</p>
+<DIV>
+<H4 CLASS="HeadC">Options</h4>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-h</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Prints command-line information for the program.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-L</em>
+ server_name</h4>
+<UL>
+<LI CLASS="ListVariable">Resets the <EM CLASS="Literal">%L</em>
+ configuration variable to the specified server name. </li>
+</ul>
+<DIV>
+<H4 CLASS="ListVariableTermRunin"><EM CLASS="Literal">-s</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">This option prevents the <EM CLASS="Emphasis">testparm</em>
+ program from prompting the user to press the Enter key before printing a list of the configuration options for the server.</li>
+</ul>
+</div>
+</div>
+</div>
+<DIV>
+<H3 CLASS="HeadB">testprns</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">testprns</em>
+ program checks a specified printer name against the system printer capabilities (<EM CLASS="Filename">printcap</em>) file. Its command line is:</p>
+<P CLASS="Code">testprns <EM CLASS="Replaceable">printername</em>
+ [<EM CLASS="Replaceable">printcapname</em>]</p>
+<P CLASS="Body">If the <EM CLASS="Literal">printcapname</em>
+ isn't specified, Samba attempts to use one located in the <EM CLASS="Filename">smb.conf</em>
+ file. If one isn't specified there, Samba will try <EM CLASS="Filename">/etc/printcap</em>. If that fails, the program will generate an error.</p>
+</div>
+<DIV>
+<H3 CLASS="HeadB">rpcclient</h3>
+<P CLASS="Body">This is a new client that exercises the RPC (remote procedure call) interfaces of an SMB server. Like <EM CLASS="Emphasis">smbclient</em>, <EM CLASS="Emphasis">rpcclient</em>
+ started its life as a test program for the Samba developers and will likely stay that way for a while. Its command line is:</p>
+<P CLASS="Code">rpcclient //<EM CLASS="Replaceable">server</em>/<EM CLASS="Replaceable">share</em>
+</p>
+<P CLASS="Body">The command-line options are the same as the Samba 2.0 <EM CLASS="Emphasis">smbclient</em>, and the operations you can try are listed below. </p>
+<TABLE>
+<CAPTION>
+<H4 CLASS="TableLabel"><A NAME="65243"></a>&nbsp;</h4>
+<H4 CLASS="TableTitle">rpcclient commands </h4>
+</caption>
+<TR>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Command</p>
+</th>
+<TH ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellHeading">Description</p>
+</th>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regenum keyname</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Enumeration (keys, values)</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regdeletekey keyname </em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Key Delete</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regcreatekey keyname [keyvalue]</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Key Create</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regquerykey keyname</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Key Query</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regdeleteval valname</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Value Delete</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regcreateval valname valtype value</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Key Create</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">reggetsec keyname</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Registry Key Security</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">regtestsec keyname</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Test Registry Key Security</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">ntlogin [username] [password]</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">NT Domain Login Test</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">wksinfo</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Workstation Query Info</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">srvinfo</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Server Query Info</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">srvsessions</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">List Sessions on a Server</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">srvshares</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">List shares on a server</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">srvconnections</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">List connections on a server </p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">srvfiles</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">List files on a server</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">lsaquery</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Query Info Policy (domain member or server)</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">lookupsids</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">Resolve names from SIDs</p>
+</td>
+</tr>
+<TR>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody"><EM CLASS="Literal">ntpass</em>
+</p>
+</td>
+<TD ROWSPAN="1" COLSPAN="1">
+<P CLASS="CellBody">NT SAM Password Change</p>
+</td>
+</tr>
+</table>
+</div>
+<DIV>
+<H3 CLASS="HeadB">tcpdump</h3>
+<P CLASS="Body">The <EM CLASS="Emphasis">tcpdump</em>
+ utility, a classic system administration tool, dumps all the packet headers it sees on an interface that match an expression. The version included in the Samba distribution is enhanced to understand the SMB protocol. The <EM CLASS="Emphasis">expression</em>
+ is a logical expression with &quot;and,&quot; &quot;or,&quot; and &quot;not,&quot; although sometimes it's very simple. For example, <EM CLASS="Literal">host</em>
+ <EM CLASS="Literal">escrime</em>
+ would select every packet going to or from <EM CLASS="Literal">escrime</em>. The expression is normally one or more of:</p>
+<UL>
+<LI CLASS="ListBullet"><EM CLASS="Literal">host</em>
+ <EM CLASS="Replaceable">name</em>
+</li>
+<LI CLASS="ListBullet"><EM CLASS="Literal">net network_number</em>
+</li>
+<LI CLASS="ListBullet"><EM CLASS="Literal">port</em>
+ <EM CLASS="Replaceable">number</em>
+</li>
+<LI CLASS="ListBullet"><EM CLASS="Literal">src</em>
+ <EM CLASS="Replaceable">name </em>
+</li>
+<LI CLASS="ListBullet"><EM CLASS="Literal">dst</em>
+ <EM CLASS="Replaceable">name</em>
+ </li>
+</ul>
+<P CLASS="Body">The most common options are <EM CLASS="Literal">src</em>
+ (source), <EM CLASS="Literal">dst</em>
+ (destination), and <EM CLASS="Literal">port</em>. For example, in the book we used the command: </p>
+<P CLASS="Code">tcpdump port not telnet</p>
+<P CLASS="Body">This dumps all the packets except telnet; we were logged-in via telnet and wanted to see only the SMB packets. </p>
+<P CLASS="Body">Another <EM CLASS="Emphasis">tcpdump</em>
+ example is selecting traffic between server and either <EM CLASS="Literal">sue</em>
+ or <EM CLASS="Literal">joe</em>:</p>
+<P CLASS="Code">tcpdump host server and &#92;(sue or joe &#92;)</p>
+<P CLASS="Body">We recommend using the <EM CLASS="Literal">-s</em>
+ <EM CLASS="Literal">1500</em>
+ option so that you capture all of the SMB messages sent, instead of just the header information. </p>
+<DIV>
+<H4 CLASS="HeadC">Options</h4>
+<P CLASS="Body">There are many options, and many other kinds of expressions that can be used with <EM CLASS="Emphasis">tcpdump</em>. See the manual page for details on the advanced options. The most common options are as follows: </p>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-c</em>
+ <EM CLASS="Replaceable">count</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Forces the program to exit after receiving the specified number of packets.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-F</em>
+ <EM CLASS="Replaceable">file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Reads the expression from the specified file and ignores expressions on the command line.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-i</em>
+ <EM CLASS="Replaceable">interface</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Forces the program to listen on the specified interface.</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-r</em>
+ <EM CLASS="Replaceable">file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Reads packets from the specified file (captured with <EM CLASS="Literal">-w</em>).</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-s</em>
+ <EM CLASS="Replaceable">length</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Saves the specified number of bytes of data from each packet (rather than 68 bytes).</li>
+</ul>
+</div>
+<DIV>
+<H4 CLASS="ListVariableTerm"><EM CLASS="Literal">-w</em>
+ <EM CLASS="Replaceable">file</em>
+</h4>
+<UL>
+<LI CLASS="ListVariable">Writes the packets to the specified file.</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+</blockquote>
+
+
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appc_01.html" TITLE="">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: Appendix C." BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appe_01.html" TITLE="">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: Appendix E." BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+C. Samba Configuration Option Quick Reference</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+E. Downloading Samba with CVS</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+
+</html>
diff --git a/docs/htmldocs/using_samba/appe_01.html b/docs/htmldocs/using_samba/appe_01.html
new file mode 100755
index 00000000000..199fade6967
--- /dev/null
+++ b/docs/htmldocs/using_samba/appe_01.html
@@ -0,0 +1,96 @@
+<HTML>
+<HEAD>
+<TITLE>[Appendix E] Downloading Samba with CVS</title>
+</head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: Appendix D." BORDER="0"></a></td>
+<TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix E</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appf_01.html" TITLE="">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: Appendix F." BORDER="0"></a></td></tr>
+</table>
+&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="appendix"><A CLASS="title" NAME="appe-58937">Appendix E. Downloading Samba with CVS</a></h1>
+<P CLASS="para">This appendix contains information on how to download the latest source version of Samba using the Concurrent Versions System (CVS). CVS is a freely available configuration management tool available from Cyclic Software and is distributed under the GNU General Public License. You can download the latest copy from <A CLASS="systemitem.url" HREF="http://www.cyclic.com/">
+http://www.cyclic.com/</a>.</p><P CLASS="para">CVS works on top of the GNU Revision Control System (RCS). Many Unix systems come preinstalled with RCS. However, if you want to download the latest version of RCS, you can find it at <A CLASS="systemitem.url" HREF="http://ftp.gnu.org/gnu/rcs/">http://ftp.gnu.org/gnu/rcs/</a>.</p><P CLASS="para">
+One of the nicest things about CVS is its ability to handle remote logins. This means that people across the globe on the Internet can download and update various source files for any project that uses a CVS repository. Such is the case with Samba. Once you have RCS and CVS installed on your system, you must first log in to the Samba source server with the following command:</p><PRE CLASS="programlisting">
+cvs -d :pserver:cvs@cvs.samba.org:/cvsroot login</pre><P CLASS="para">
+This tells CVS to connect to the CVS server at <I CLASS="filename">
+cvs.samba.org</i>. Once you are connected, you can download the latest source tree with the following command:</p><PRE CLASS="programlisting">
+cvs -d :pserver:cvs@cvs.samba.org:/cvsroot co samba</pre><P CLASS="para">
+This will download the entire Samba distribution (file by file) into a directory entitled <I CLASS="filename">
+/samba</i>, which it will create on your hard drive. This directory will have the same structure as the Samba source distribution described in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>. It includes source and header files, documentation, and sample configuration files to help get you started. After that is completed, you can follow the instructions in <a href="ch02_01.html"><b>Chapter 2</b></a> to configure and compile Samba on your server.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: Appendix D." BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appf_01.html" TITLE="">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: Appendix F." BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+Appendix D: Summary of Samba Daemons and Commands</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+F. Sample Configuration File</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/appf_01.html b/docs/htmldocs/using_samba/appf_01.html
new file mode 100755
index 00000000000..9b709472256
--- /dev/null
+++ b/docs/htmldocs/using_samba/appf_01.html
@@ -0,0 +1,315 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Appendix F] Sample Configuration File
+</title>
+<META NAME="DC.title" CONTENT="">
+<META NAME="DC.creator" CONTENT="">
+<META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc.">
+<META NAME="DC.date" CONTENT="1999-11-08T16:28:53Z">
+<META NAME="DC.type" CONTENT="Text.Monograph">
+<META NAME="DC.format" CONTENT="text/html" SCHEME="MIME">
+<META NAME="DC.source" CONTENT="" SCHEME="ISBN">
+<META NAME="DC.language" CONTENT="en-US">
+<META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0">
+</head>
+
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<A HREF="index.html">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</a>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="D. Downloading Samba with CVS">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: D. Downloading Samba with CVS" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Appendix F</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+&nbsp;</td></tr></table>&nbsp;
+
+<hr noshade size=1></center>
+
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="appendix">
+<A CLASS="title" NAME="appf-10509">
+F. Sample Configuration File</a></h1><P CLASS="para">This appendix gives an example of a production <I CLASS="filename">
+smb.conf</i> file and looks at how many of the options are used in practice. The following is a slightly disguised version of one we used at a corporation with five Linux servers, five Windows for Workgroups clients and three NT Workstation clients:</p><PRE CLASS="programlisting">
+# smb.conf -- File Server System for: 1 Example.COM BSC &amp; Management Office
+[globals]
+ workgroup = 1EG_BSC
+ interfaces = 10.10.1.14/24 </pre><P CLASS="para">
+We provide this service on only one of the machine's interfaces. The <CODE CLASS="literal">
+interfaces</code> option sets its address and netmask, where <CODE CLASS="literal">
+/24</code> is the same as using the netmask 255.255.255.0:</p><PRE CLASS="programlisting">
+ comment = Samba ver. %v
+ preexec = csh -c `echo /usr/samba/bin/smbclient \
+ -M %m -I %I` &amp;</pre><P CLASS="para">
+We use the <KBD CLASS="command">
+preexec</kbd> command to log information about all connections by machine name (<CODE CLASS="literal">%m</code>) and IP address (<CODE CLASS="literal">%I)</code>:</p><PRE CLASS="programlisting">
+ # smbstatus will output various info on current status
+ status = yes
+ browseable = yes
+ printing = bsd
+
+ # the username that will be used for access to services
+ # specified with 'guest = ok'
+ guest account = samba </pre><P CLASS="para">
+The default guest account was <CODE CLASS="literal">
+nobody</code>, uid -1, which produced log messages on one of our machines saying "your server is being unfriendly," so we created a specific Samba guest account for browsing and printing:</p><PRE CLASS="programlisting">
+ # superuser account - admin privilages to shares, with no
+ # restrictions
+ # WARNING - use this with care: files can be modified,
+ # regardless of file permissions
+ admin users = root
+
+ # who is NOT allowed to connect to ANY service
+ invalid users = @wheel, mail, deamon, adt</pre><P CLASS="para">
+Daemons can't use Samba, only people. The <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> option closes a security hole; it prevents intruders from breaking in by pretending to be a daemon process.</p><PRE CLASS="programlisting">
+ # hosts that are ALLOWED or DENIED from connecting to ANY service
+ hosts allow = 10.10.1.
+ hosts deny = 10.10.1.6
+
+ # where the lock files will be located
+ lock directory = /var/lock/samba/locks
+
+ # debug log files
+ # %m = separate log for each NetBIOS name (each machine)
+ log file = /var/log/samba/log.%m
+
+ # We send priority 0, 1 and 2 messages to the system logs
+ syslog = 2
+
+ # If a WinPopup message is sent to the server,
+ # redirect it to a user via e-mail
+
+ message command = /bin/mail -s 'message from #% on %m' \
+ pkelly &lt; %s; rm %s
+
+# ---------------------------------------------------
+# [globals] Performance Tuning
+# ---------------------------------------------------
+
+ # caching algorithm to reduce time doing getwd() calls.
+ getwd cache = yes
+
+ socket options = TCP_NODELAY
+
+ # tell the server whether the client is present and
+ # responding in seconds
+ keep alive = 60
+
+ # num minutes of inactivity before a connection is
+ # considered dead
+ dead time = 30
+
+ read prediction = yes
+ share modes = yes
+ max xmit = 17384
+ read size = 512</pre><P CLASS="para">
+The <CODE CLASS="literal">
+share</code> <CODE CLASS="literal">
+modes</code>, <CODE CLASS="literal">
+max</code>, <CODE CLASS="literal">
+xinit</code>, and <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+size</code> options are machine-specific (see <a href="appb_01.html"><b>Appendix B, <CITE CLASS="appendix">Samba Performance Tuning</cite></b></a>): </p><PRE CLASS="programlisting">
+ # locking is done by the server
+ locking = yes
+
+ # control whether dos style attributes should be mapped
+ # to unix execute bits
+ map hidden = yes
+ map archive = yes
+ map system = yes</pre><P CLASS="para">
+The three <CODE CLASS="literal">
+map</code> options will work only on shares with a create mode that includes the execute bits (0111). Our <CODE CLASS="literal">
+homes</code> and <CODE CLASS="literal">
+printers</code> shares won't honor them, but the [<CODE CLASS="literal">www]</code> share will:</p><PRE CLASS="programlisting">
+# ---------------------------------------------------------
+# [globals] Security and Domain Logon Services
+# ---------------------------------------------------------
+# connections are made with UID and GID, not as shares
+ security = user
+
+# boolean variable that controls whether passwords
+# will be encrypted
+ encrypt passwords = yes
+ passwd chat = &quot;*New password:*&quot; %n\r &quot;*New password (again):*&quot; %n\r \ &quot;*Password changed*&quot;
+ passwd program = /usr/bin/passwd %u
+
+# Always become the local master browser
+ domain master = yes
+ preferred master = yes
+ os level = 34
+
+# For domain logons to work correctly. Samba acts as a
+# primary domain controller.
+ domain logons = yes
+
+# Logon script to run for user off the server each time
+# username (%U) logs in. Set the time, connect to shares,
+# virus checks, etc.
+ logon script = scripts\%U.bat
+
+[netlogon]
+ comment = &quot;Domain Logon Services&quot;
+ path = /u/netlogon
+ writable = yes
+ create mode = 444
+ guest ok = no
+ volume = &quot;Network&quot;</pre><P CLASS="para">
+This share, discussed in <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a>, is required for Samba to work smoothly in a Windows NT domain:</p><PRE CLASS="programlisting">
+# -----------------------------------------------------------
+# [homes] User Home Directories
+# -----------------------------------------------------------
+[homes]
+ comment = &quot;Home Directory for : %u &quot;
+ path = /u/users/%u</pre><P CLASS="para">
+The password file of the Samba server specifies each person's home directory as <EM CLASS="emphasis">
+/home/</em><CODE CLASS="replaceable"><I>machine_name</i></code><EM CLASS="emphasis">/</em><CODE CLASS="replaceable"><I>person</i></code>, which NFS converts to point to the actual physicl location under <EM CLASS="emphasis">
+/u/users</em>. The <CODE CLASS="literal">
+path</code> option in the <CODE CLASS="literal">
+[homes]</code> share tells Samba the actual (non-NFS) location:</p><PRE CLASS="programlisting">
+ guest ok = no
+ read only = no
+ create mode = 644
+ writable = yes
+ browseable = no
+
+# -----------------------------------------------------------
+# [printers] System Printers
+# -----------------------------------------------------------
+[printers]
+ comment = &quot;Printers&quot;
+ path = /var/spool/lpd/samba
+ printcap name = /etc/printcap
+ printable = yes
+ public = no
+ writable = no
+
+ lpq command = /usr/bin/lpq -P%p
+ lprm command = /usr/bin/lprm -P%p %j
+ lppause command = /usr/sbin/lpc stop %p
+ lpresume command = /usr/sbin/lpc start %p
+
+ create mode = 0700
+
+ browseable = no
+ load printers = yes
+
+# -----------------------------------------------------------
+# Specific Descriptions: [programs] [data] [retail]
+# -----------------------------------------------------------
+[programs]
+ comment = &quot;Shared Programs %T&quot;
+ volume = &quot;programs&quot;</pre><P CLASS="para">
+Shared Programs shows up in the Network Neighborhood, and <CODE CLASS="literal">
+programs</code> is the volume name you specify when an installation program wants to know the label of the CD-ROM from which it thinks it's loading:</p><PRE CLASS="programlisting">
+ path = /u/programs
+ public = yes
+ writeable = yes
+ printable = no
+ create mode = 664
+[cdrom]
+ comment = &quot;Unix CDROM&quot;
+ path = /u/cdrom
+ public = no
+ writeable = no
+ printable = no
+ volume = &quot;cdrom&quot;
+
+[data]
+ comment = &quot;Data Directories %T&quot;
+ path = /u/data
+ public = no
+ create mode = 770
+ writeable = yes
+ volume = &quot;data&quot;
+
+[nt4]
+ comment = &quot;NT4 Server&quot;
+ path = /u/systems/nt4
+ public = yes
+ create mode = 770
+ writeable = yes
+ volume = &quot;nt4_server&quot;
+
+[www]
+ comment = &quot;WWW System&quot;
+ path = /usr/www/http
+ public = yes
+ create mode = 775
+ writeable = yes
+ volume = &quot;www_system&quot;</pre><P CLASS="para">
+The <CODE CLASS="literal">
+[www]</code> share is the directory used on the Unix server to serve web pages. Samba makes the directory available to local PC users so the art department can update web pages.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appd_01.html" TITLE="D. Downloading Samba with CVS">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: D. Downloading Samba with CVS" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">&nbsp;</td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+D. Downloading Samba with CVS</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+&nbsp;</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_01.html b/docs/htmldocs/using_samba/ch01_01.html
new file mode 100755
index 00000000000..0651fa823c3
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_01.html
@@ -0,0 +1,167 @@
+<HTML>
+<HEAD>
+<TITLE>[Chapter 1] 1.1 Learning Samba</title>
+</head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+</td>
+<TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+</td>
+<TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_02.html" TITLE="1.2 What Can Samba Do For Me?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.2 What Can Samba Do For Me?" BORDER="0"></a>
+</td>
+</tr>
+</table>&nbsp;
+<hr noshade size=1>
+</center>
+</div>
+<blockquote>
+<div>
+<H1 CLASS="sect1">1. Learning the Samba</h1>
+<p>If you are a typical system administrator, then you know what it means to be <i>swamped</i> with work. Your daily routine is filled with endless hardware incompatibility issues, system outages, data backup problems, and a steady stream of angry users. So adding another program to the mix of tools that you have to maintain may sound a bit perplexing. However, if you're determined to reduce the complexity of your work environment, as well as the workload of keeping it running smoothly, Samba may be the tool you've been waiting for.</p>
+
+<p>A case in point: one of the authors of this book used to look after 70 Unix developers sharing 5 Unix servers. His neighbor administered 20 Windows 3.1 users and 5 OS/2 and Windows NT servers. To put it mildly, the Windows 3.1 administrator was swamped. When he finally left - and the domain controller melted - Samba was brought to the rescue. Our author quickly replaced the Windows NT and OS/2 servers with Samba running on a Unix server, and eventually bought PCs for most of the company developers. However, he did the latter without hiring a new PC administrator; the administrator now manages one centralized Unix application instead of fifty distributed PCs. </p>
+
+<p>If you know you're facing a problem with your network and you're sure there is a better way, we encourage you to start reading this book. Or, if you've heard about Samba and you want to see what it can do for you, this is also the place to start. We'll get you started on the path to understanding Samba and its potential. Before long, you can provide Unix services to all your Windows machines - all without spending tons of extra time or money. Sound enticing? Great, then let's get started.</p>
+
+<a name="s1"></a>
+<h2 id="ch01-28119">1.1 What is Samba?</h2>
+
+<p>Samba is a suite of Unix applications that speak the SMB (Server Message Block) protocol. Many operating systems, including Windows and OS/2, use SMB to perform client-server networking. By supporting this protocol, Samba allows Unix servers to get in on the action, communicating with the same networking protocol as Microsoft Windows products. Thus, a Samba-enabled Unix machine can masquerade as a server on your Microsoft network and offer the following services:</p>
+
+<ul>
+<li id="ch01-pgfId-940463">
+
+<p>Share one or more filesystems</p>
+
+</li>
+<li id="ch01-pgfId-940464">
+
+<p>Share printers installed on both the server and its clients</p>
+
+</li>
+<li id="ch01-pgfId-940465">
+
+<p>Assist clients with Network Neighborhood browsing</p>
+
+</li>
+<li id="ch01-pgfId-940489">
+
+<p>Authenticate clients logging onto a Windows domain</p>
+
+</li>
+<li id="ch01-pgfId-940472">
+
+<p>Provide or assist with WINS name server resolution</p>
+
+</li>
+</ul>
+
+<p>Samba is the brainchild of Andrew Tridgell, who currently heads the Samba development team from his home of Canberra, Australia. The project was born in 1991 when Andrew created a fileserver program for his local network that supported an odd DEC protocol from Digital Pathworks. Although he didn't know it at the time, that protocol later turned out to be SMB. A few years later, he expanded upon his custom-made SMB server and began distributing it as a product on the Internet under the name SMB Server. However, Andrew couldn't keep that name - it already belonged to another company's product - so he tried the following Unix renaming approach:</p>
+
+<pre>
+grep -i 's.*m.*b' /usr/dict/words </pre>
+
+<p>And the response was:</p>
+
+<Pre>
+salmonberry samba sawtimber scramble</pre>
+
+<p>Thus, the name "Samba" was born.<footnote id="ch01-pgfId-946532">
+
+<p>Which is a good thing, because our marketing people highly doubt you would have picked up a book called "Using Salmonberry"!</p>
+
+</footnote></p>
+
+<p>Today, the Samba suite revolves around a pair of Unix daemons that provide shared resources - or <i>shares</i> - to SMB clients on the network. (Shares are sometimes called s<i>ervices</i> as well.) These daemons are:</p>
+
+<dl>
+<dt>smbd</dt>
+<dd>
+
+<p id="ch01-pgfId-949804">A daemon that allows file and printer sharing on an SMB network and provides authentication and authorization for SMB clients.</p>
+
+</dd>
+
+<dt>nmbd</dt>
+<dd>
+
+<p id="ch01-pgfId-949805">A daemon that looks after the Windows Internet Name Service (WINS), and assists with browsing.</p>
+
+</dd>
+</dl>
+
+<p>Samba is currently maintained and extended by a group of volunteers under the active supervision of Andrew Tridgell. Like the Linux operating system, Samba is considered <i>Open Source software </i>(OSS) by its authors, and is distributed under the GNU General Public License (GPL). Since its inception, development of Samba has been sponsored in part by the Australian National University, where Andrew Tridgell earned his Ph.D.<a href = "#footnote"> [1]</a>
+ In addition, some development has been sponsored by independent vendors such as Whistle and SGI. It is a true testament to Samba that both commercial and non-commercial entities are prepared to spend money to support an Open Source effort.</p>
+<blockquote><a name="footnote">
+<p>[1] At the time of this printing, Andrew had completed his Ph.D. work and had joined San Francisco-based LinuxCare.</p>
+</blockquote>
+<p>Microsoft has also contributed materially by putting forward its definition of SMB and the Internet-savvy Common Internet File System (CIFS), as a public Request for Comments (RFC), a standards document. The CIFS protocol is Microsoft's renaming of future versions of the SMB protocol that will be used in Windows products - the two terms can be used interchangeably in this book. Hence, you will often see the protocol written as "SMB/CIFS."</p> </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+
+</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_02.html" TITLE="1.2 What Can Samba Do For Me?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.2 What Can Samba Do For Me?" BORDER="0"></a></td></tr><TR>
+
+<TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.1 Learning Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_02.html b/docs/htmldocs/using_samba/ch01_02.html
new file mode 100755
index 00000000000..9ccb2dfeee2
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_02.html
@@ -0,0 +1,212 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.2 What Can Samba Do For Me?</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:50Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_01.html" TITLE="1.1 What is Samba?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.1 What is Samba?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_03.html" TITLE="1.3 Getting Familiar with a SMB/CIFS Network">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.3 Getting Familiar with a SMB/CIFS Network" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-pgfId-937232">
+1.2 What Can Samba Do For Me?</a></h2><P CLASS="para">
+As explained earlier, Samba can help Windows and Unix machines coexist in the same network. However, there are some specific reasons why you might want to set up a Samba server on your network:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-941390">
+</a>You don't want to pay for&nbsp;- or can't afford&nbsp;- a full-fledged Windows NT server, yet you still need the functionality that one provides.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-941391">
+</a>You want to provide a common area for data or user directories in order to transition from a Windows server to a Unix one, or vice versa.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-941394">
+</a>You want to be able to share printers across both Windows and Unix workstations.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-941973">
+</a>You want to be able to access NT files from a Unix server.</p></li></ul><P CLASS="para">
+Let's take a quick tour of Samba in action. Assume that we have the following basic network configuration: a Samba-enabled Unix machine, to which we will assign the name <CODE CLASS="literal">
+hydra</code>, and a pair of Windows clients, to which we will assign the names <CODE CLASS="literal">
+phoenix</code> and <CODE CLASS="literal">
+chimaera</code>, all connected via a local area network (LAN). Let's also assume that <CODE CLASS="literal">
+hydra</code> also has a local inkjet printer connected to it, <CODE CLASS="literal">
+lp</code>, and a disk share named <CODE CLASS="literal">
+network</code>&nbsp;- both of which it can offer to the other two machines. A graphic of this network is shown in <A CLASS="xref" HREF="ch01_02.html#ch01-45964">
+Figure 1.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-45964">
+Figure 1.1: A simple network setup with a Samba server</a></h4><IMG CLASS="graphic" SRC="figs/sam.0101.gif" ALT="Figure 1.1"><P CLASS="para">
+In this network, each of the computers listed share the same <I CLASS="firstterm">
+workgroup</i>. A workgroup is simply a group nametag that identifies an arbitrary collection of computers and their resources on an SMB network. There can be several workgroups on the network at any time, but for our basic network example, we'll have only one: the SIMPLE workgroup.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937316">
+1.2.1 Sharing a Disk Service</a></h3><P CLASS="para">If everything is properly configured, we should be able to see the Samba server, <CODE CLASS="literal">
+hydra</code>, through the Network Neighborhood of the <CODE CLASS="literal">
+phoenix</code> Windows desktop. In fact, <A CLASS="xref" HREF="ch01_02.html#ch01-60493">
+Figure 1.2</a> shows the Network Neighborhood of the <CODE CLASS="literal">
+phoenix</code> computer, including <CODE CLASS="literal">
+hydra</code> and each of the computers that reside in the SIMPLE workgroup. Note the Entire Network icon at the top of the list. As we just mentioned, there can be more than one workgroup on an SMB network at any given time. If a user clicks on the Entire Network icon, he or she will see a list of all the workgroups that currently exist on the network. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-60493">
+Figure 1.2: The Network Neighborhood directory</a></h4><IMG CLASS="graphic" SRC="figs/sam.0102.gif" ALT="Figure 1.2"><P CLASS="para">
+We can take a closer look at the <CODE CLASS="literal">
+hydra</code> server by double-clicking on its icon. This contacts <CODE CLASS="literal">
+hydra</code> itself and requests a list of its <I CLASS="firstterm">
+shares</i>&nbsp;- the file and printer resources&nbsp;- that the machine provides. In this case, there is a printer entitled <CODE CLASS="literal">
+lp</code> and a disk share entitled <CODE CLASS="literal">
+network</code> on the server, as shown in <A CLASS="xref" HREF="ch01_02.html#ch01-76011">
+Figure 1.3</a>. Note that the Windows display shows hostnames in mixed case (Hydra). Case is irrelevant in hostnames, so you may see hydra, Hydra, and HYDRA in various displays or command output, but they all refer to a single system. Thanks to Samba, Windows 98 sees the Unix server as a valid SMB server, and can access the <CODE CLASS="literal">
+network</code> folder as if it were just another system folder. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-76011">
+Figure 1.3: Shares available on the hydra sever as viewed from phoenix</a></h4><IMG CLASS="graphic" SRC="figs/sam.0103.gif" ALT="Figure 1.3"><P CLASS="para">
+One popular feature of Windows 95/98/NT is that you can map a letter-drive to a known network directory using the Map Network Drive option in the Windows Explorer.[<A CLASS="footnote" HREF="#ch01-pgfId-941061">3</a>] Once you do so, your applications can access the folder across the network with a standard drive letter. Hence, you can store data on it, install and run programs from it, and even password-protect it against unwanted visitors. See <A CLASS="xref" HREF="ch01_02.html#ch01-55465">
+Figure 1.4</a> for an example of mapping a letter-drive to a network directory. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch01-pgfId-941061">[3]</a> You can also right-click on the shared resource in the Network Neighborhood, and then select the Map Network Drive menu item.</p></div></blockquote><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-55465">
+Figure 1.4: Mapping a network drive to a Windows letter-drive</a></h4><IMG CLASS="graphic" SRC="figs/sam.0104.gif" ALT="Figure 1.4"><P CLASS="para">
+Take a look at the Path: entry in the dialog box of <A CLASS="xref" HREF="ch01_02.html#ch01-55465">
+Figure 1.4</a>. An equivalent way to represent a directory on a network machine is by using two backslashes, followed by the name of the networked machine, another backslash, and the networked directory of the machine, as shown below:</p>
+
+<PRE><I>\\network-machine\directory</i></pre>
+
+<P CLASS="para">
+This is known as the <I CLASS="firstterm">
+UNC</i> (Universal Naming Convention) in the Windows world. For example, the dialog box in <A CLASS="xref" HREF="ch01_02.html#ch01-55465">
+Figure 1.4</a> represents the network directory on the <CODE CLASS="literal">
+hydra</code> server as:</p>
+
+<PRE CLASS="programlisting">\\HYDRA\<CODE CLASS="replaceable"><I>network</i></code></pre><P CLASS="para">
+
+If this looks somewhat familiar to you, you're probably thinking of <I CLASS="firstterm">
+uniform resource locators</i> (URLs), which are addresses that web browsers such as Netscape Navigator and Internet Explorer use to resolve machines across the Internet. Be sure not to confuse the two: web browsers typically use forward slashes instead of back slashes, and they precede the initial slashes with the data transfer protocol (i.e., ftp, http) and a colon (:). In reality, URLs and UNCs are two completely separate things.</p><P CLASS="para">
+Once the network drive is set up, Windows and its programs will behave as if the networked directory was a fixed disk. If you have any applications that support multiuser functionality on a network, you can install those programs on the network drive.[<A CLASS="footnote" HREF="#ch01-pgfId-952017">4</a>] <A CLASS="xref" HREF="ch01_02.html#ch01-32686">
+Figure 1.5</a> shows the resulting network drive as it would appear with other storage devices in the Windows 98 client. Note the pipeline attachment in the icon for the G: drive; this indicates that it is a network drive instead of a fixed drive. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch01-pgfId-952017">[4]</a> Be warned that many end-user license agreements forbid installing a program on a network such that multiple clients can access it. Check the legal agreements that accompany the product to be absolutely sure.</p></div></blockquote><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-32686">
+Figure 1.5: The Network directory mapped to the client letter-drive G</a></h4><IMG CLASS="graphic" SRC="figs/sam.0105.gif" ALT="Figure 1.5"><P CLASS="para">
+From our Windows NT Workstation machine, <CODE CLASS="literal">
+chimaera</code>, Samba looks almost identical to Windows 98. <A CLASS="xref" HREF="ch01_02.html#ch01-29255">
+Figure 1.6</a> shows the same view of the <CODE CLASS="literal">
+hydra</code> server from the Windows NT 4.0 Network Neighborhood. Setting up the network drive using the Map Network Drive option in Windows NT Workstation 4.0 would have identical results as well. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-29255">
+Figure 1.6: Shares available on hydra (viewed from chimaera) </a></h4><IMG CLASS="graphic" SRC="figs/sam.0106.gif" ALT="Figure 1.6"></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-942088">
+1.2.2 Sharing a Printer</a></h3><P CLASS="para">You probably noticed that the printer <CODE CLASS="literal">
+lp</code> appeared under the available shares for <CODE CLASS="literal">
+hydra</code> in <A CLASS="xref" HREF="ch01_02.html#ch01-76011">
+Figure 1.3</a>. This indicates that the Unix server has a printer that can be shared by the various SMB clients in the workgroup. Data sent to the printer from any of the clients will be spooled on the Unix server and printed in the order it is received.</p><P CLASS="para">Setting up a Samba-enabled printer on the Windows side is even easier than setting up a disk share. By double-clicking on the printer and identifying the manufacturer and model, you can install a driver for this printer on the Windows client. Windows can then properly format any information sent to the network printer and access it as if it were a local printer (we show you how to do this later in the chapter). <A CLASS="xref" HREF="ch01_02.html#ch01-46265">
+Figure 1.7</a> shows the resulting network printer in the Printers window of Windows 98. Again, note the pipeline attachment below the printer, which identifies it as being on a network. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-46265">
+Figure 1.7: A network printer available on hydra (viewed from chimaera)</a></h4><IMG CLASS="graphic" SRC="figs/sam.0107.gif" ALT="Figure 1.7"><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-937586">
+1.2.2.1 Seeing things from the Unix side</a></h4><P CLASS="para">
+As mentioned earlier, Samba appears in Unix as a set of daemon programs. You can view them with the Unix <CODE CLASS="literal">
+ps</code> and <CODE CLASS="literal">
+netstat</code> commands, you can read any messages they generate through custom debug files or the Unix <CODE CLASS="literal">
+syslog</code> (depending on how Samba is set up), and you can configure it from a single Samba properties file: <i>smb.conf</i>. In addition, if you want to get an idea of what each of the daemons are doing, Samba has a program called
+<i>smbstatus</i> that will lay it all on the line. Here is how it works:</p>
+
+<PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">#</code> smbstatus</b>
+</pre><PRE CLASS="programlisting">
+Samba version 2.0.4
+Service uid gid pid machine
+----------------------------------------------
+network davecb davecb 7470 phoenix (192.168.220.101) Sun May 16
+network davecb davecb 7589 chimaera (192.168.220.102) Sun May 16
+
+Locked files:
+Pid DenyMode R/W Oplock Name
+--------------------------------------------------
+7589 DENY_NONE RDONLY EXCLUSIVE+BATCH /home/samba/quicken/inet/common/system/help.bmp Sun May 16 21:23:40 1999
+7470 DENY_WRITE RDONLY NONE /home/samba/word/office/findfast.exe Sun May 16 20:51:08 1999
+7589 DENY_WRITE RDONLY EXCLUSIVE+BATCH /home/samba/quicken/lfbmp70n.dll Sun May 16 21:23:39 1999
+7589 DENY_WRITE RDWR EXCLUSIVE+BATCH /home/samba/quicken/inet/qdata/runtime.dat Sun May 16 21:23:41 1999
+7470 DENY_WRITE RDONLY EXCLUSIVE+BATCH /home/samba/word/office/osa.exe Sun May 16 20:51:09 1999
+7589 DENY_WRITE RDONLY NONE /home/samba/quicken/qversion.dll Sun May 16 21:20:33 1999
+7470 DENY_WRITE RDONLY NONE /home/samba/quicken/qversion.dll Sun May 16 20:51:11 1999
+
+Share mode memory usage (bytes):
+ 1043432(99%) free + 4312(0%) used + 832(0%) overhead = 1048576(100%) total</pre><P CLASS="para">
+The Samba status from this output provides three sets of data, each divided into separate sections. The first section tells which systems have connected to the Samba server, identifying each client by its machine name (<CODE CLASS="literal">phoenix</code> and <CODE CLASS="literal">chimaera</code>) and IP address. The second section reports the name and status of the files that are currently in use on a share on the server, including the read/write status and any locks on the files. Finally, Samba reports the amount of memory it has currently allocated to the shares that it administers, including the amount actively used by the shares plus additional overhead. (Note that this is not the same as the total amount of memory that the <EM CLASS="emphasis">
+smbd</em> or <EM CLASS="emphasis">
+nmbd</em> processes are using.)</p><P CLASS="para">
+Don't worry if you don't understand these statistics; they will become easier to understand as you move through the book. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_01.html" TITLE="1.1 What is Samba?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.1 What is Samba?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_03.html" TITLE="1.3 Getting Familiar with a SMB/CIFS Network">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.3 Getting Familiar with a SMB/CIFS Network" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.1 What is Samba?</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.3 Getting Familiar with a SMB/CIFS Network</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_03.html b/docs/htmldocs/using_samba/ch01_03.html
new file mode 100755
index 00000000000..67a86775301
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_03.html
@@ -0,0 +1,444 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.3 Getting Familiar with a SMB/CIFS Network</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:52Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_02.html" TITLE="1.2 What Can Samba Do For Me?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.2 What Can Samba Do For Me?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_04.html" TITLE="1.4 Microsoft Implementations">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.4 Microsoft Implementations" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-88536">
+1.3 Getting Familiar with a SMB/CIFS Network</a></h2><P CLASS="para">Now that you have had a brief tour of Samba, let's take some time to get familiar with Samba's adopted environment: an SMB/CIFS network. Networking with SMB is significantly different from working with a Unix TCP/IP network, because there are several new concepts to learn and a lot of information to cover. First, we will discuss the basic concepts behind an SMB network, followed by some Microsoft implementations of it, and finally we will show you where a Samba server can and cannot fit into the picture.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-941409">
+1.3.1 Understanding NetBIOS</a></h3><P CLASS="para">
+To begin, let's step back in time. In 1984, IBM authored a simple application programming interface (API) for networking its computers called the <I CLASS="firstterm">
+Network Basic Input/Output System </i>(NetBIOS). The NetBIOS API provided a rudimentary design for an application to connect and share data with other computers.</p><P CLASS="para">
+It's helpful to think of the NetBIOS API as networking extensions to the standard BIOS API calls. With BIOS, each low-level call is confined to the hardware of the local machine and doesn't need any help traveling to its destination. NetBIOS, however, originally had to exchange instructions with computers across IBM PC or Token Ring networks. It therefore required a low-level transport protocol to carry its requests from one computer to the next.</p><P CLASS="para">
+In late 1985, IBM released one such protocol, which it merged with the NetBIOS API to become the <I CLASS="firstterm">
+NetBIOS Extended User Interface</i> (<EM CLASS="emphasis">NetBEUI</em>). NetBEUI was designed for small local area networks (LANs), and it let each machine claim a name (up to 15 characters) that wasn't already in use on the network. By a "small LAN," we mean fewer than 255 nodes on the network&nbsp;- which was considered a practical restriction in 1985!</p><P CLASS="para">
+The NetBEUI protocol was very popular with networking applications, including those running under Windows for Workgroups. Later, implementations of NetBIOS over Novell's IPX networking protocols also emerged, which competed with NetBEUI. However, the networking protocols of choice for the burgeoning Internet community were TCP/IP and UDP/IP, and implementing the NetBIOS APIs over those protocols soon became a necessity.</p><P CLASS="para">
+Recall that TCP/IP uses numbers to represent computer addresses, such as 192.168.220.100, while NetBIOS uses only names. This was a major issue when trying to mesh the two protocols together. In 1987, the Internet Engineering Task Force (IETF) published a series of standardization documents, titled RFC 1001 and 1002, that outlined how NetBIOS would work over a TCP/UDP network. This set of documents still governs each of the implementations that exist today, including those provided by Microsoft with their Windows operating systems as well as the Samba suite.</p><P CLASS="para">
+Since then, the standard this document governs has become known as <I CLASS="firstterm">
+NetBIOS over TCP/IP</i>, or NBT for short. The NBT standard (RFC 1001/1002) currently outlines a trio of services on a network:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-946789">
+</a>A name service</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-946790">
+</a>Two communication services: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-952037">
+</a>Datagrams </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-952038">
+</a>Sessions</p></li></ul></li></ul><P CLASS="para">
+The name service solves the name-to-address problem mentioned earlier; it allows each computer to declare a specific name on the network that can be translated to a machine-readable IP address, much like today's DNS on the Internet. The datagram and session services are both secondary communication protocols used to transmit data back and forth from NetBIOS machines across the network.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-945521">
+1.3.2 Getting a Name</a></h3><P CLASS="para">For a human being, getting a name is easy. However, for a machine on a NetBIOS network, it can be a little more complicated. Let's look at a few of the issues.</p><P CLASS="para">
+In the NetBIOS world, when each machine comes online, it wants to claim a name for itself; this is called <I CLASS="firstterm">
+name registration</i>. However, no two machines in the same workgroup should be able to claim the same name; this would cause endless confusion for any machine that wanted to communicate with either machine. There are two different approaches to ensuring that this doesn't happen:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-945120">
+</a>Use a <I CLASS="firstterm">
+NetBIOS Name Server</i> (NBNS) to keep track of which hosts have registered a NetBIOS name. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-945121">
+</a>Allow each machine on the network to defend its name in the event that another machine attempts to use it.</p></li></ul><P CLASS="para">
+<A CLASS="xref" HREF="ch01_03.html#ch01-86658">
+Figure 1.8</a> illustrates a (failed) name registration, with and without a NetBIOS Name Server. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-86658">
+Figure 1.8: NBNS versus non-NBNS name registration</a></h4><IMG CLASS="graphic" SRC="figs/sam.0108.gif" ALT="Figure 1.8"><P CLASS="para">
+In addition, there must be a way to resolve a NetBIOS name to a specific IP address as mentioned earlier; this is known as <I CLASS="firstterm">
+name resolution</i>. There are two different approaches with NBT here as well:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-945526">
+</a>Have each machine report back its IP address when it "hears" a broadcast request for its NetBIOS name.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-945527">
+</a>Use the NBNS to help resolve NetBIOS names to IP addresses. </p></li></ul><P CLASS="para">
+<A CLASS="xref" HREF="ch01_03.html#ch01-72484">
+Figure 1.9</a> illustrates the two types of name resolution. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-72484">
+Figure 1.9: NBNS versus non-NBNS name resolution</a></h4><IMG CLASS="graphic" SRC="figs/sam.0109.gif" ALT="Figure 1.9"><P CLASS="para">
+As you might expect, having an NBNS on your network can help out tremendously. To see exactly why, let's look at the non-NBNS method.</p><P CLASS="para">
+Here, when a client machine boots, it will broadcast a message declaring that it wishes to register a specified NetBIOS name as its own. If nobody objects to the use of the name after multiple registration attempts, it keeps the name. On the other hand, if another machine on the local subnet is currently using the requested name, it will send a message back to the requesting client that the name is already taken. This is known as <I CLASS="firstterm">
+defending</i> the hostname. This type of system comes in handy when one client has unexpectedly dropped off the network&nbsp;- another can take its name unchallenged&nbsp;- but it does incur an inordinate amount of traffic on the network for something as simple as name registration.</p><P CLASS="para">
+With an NBNS, the same thing occurs, except that the communication is confined to the requesting machine and the NBNS server. No broadcasting occurs when the machine wishes to register the name; the registration message is simply sent directly from the client to NBNS server and the NBNS server replies whether or not the name is already taken. This is known as <I CLASS="firstterm">
+point-to-point communication</i>, and is often beneficial on networks with more than one subnet. This is because routers are often preconfigured to block incoming packets that are broadcast to all machines in the subnet.</p><P CLASS="para">
+The same principles apply to name resolution. Without an NBNS, NetBIOS name resolution would also be done with a broadcast mechanism. All request packets would be sent to each computer in the network, with the hope that one machine that might be affected will respond directly back to the machine that asked. At this point, it's clear that using an NBNS server and point-to-point communication for this purpose is far less taxing on the network than flooding the network with broadcasts for every name resolution request. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-945664">
+1.3.3 Node Types</a></h3><P CLASS="para">How can you tell what strategy each client on your network will use when performing name registration and resolution? Each machine on an NBT network earns one of the following designations, depending on how it handles name registration and resolution: b-node, p-node, m-node, and h-node. The behaviors of each type of node are summarized in <A CLASS="xref" HREF="ch01_03.html#ch01-91681">
+Table 1.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-91681">
+Table 1.1: NetBIOS Node Types </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Role</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Value</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+b-node</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Uses broadcast registration and resolution only.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+p-node</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Uses point-to-point registration and resolution only.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+m-node</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Uses broadcast for registration. If successful, it notifies the NBNS server of the result. Uses broadcast for resolution; uses NBNS server if broadcast is unsuccessful.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+h-node (hybrid)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Uses NBNS server for registration and resolution; uses broadcast if the NBNS server is unresponsive or inoperative.</p></td></tr></tbody></table><P CLASS="para">
+In the case of Windows clients, you will usually find them listed as <I CLASS="firstterm">
+h-nodes</i> or <I CLASS="firstterm">
+hybrid nodes</i>. Incidentally, h-nodes were invented later by Microsoft, as a more fault-tolerant route, and do not appear in RFC 1001/1002.</p><P CLASS="para">
+You can find out the node type of any Windows machine by typing the command <CODE CLASS="literal">
+ipconfig</code> <CODE CLASS="literal">
+/all</code> and searching for the line that says <CODE CLASS="literal">
+Node Type</code>.</p>
+
+<PRE CLASS="programlisting"><B CLASS="emphasis.bold">C:\&gt; ipconfig /all</b>
+</pre><PRE CLASS="programlisting">
+Windows 98 IP Configuration
+...
+ Node Type . . . . . . . . . . : Hybrid
+...</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-945128">
+1.3.4 What's in a Name?</a></h3><P CLASS="para">
+The names NetBIOS uses are quite different from the DNS hostnames you might be familiar with. First, NetBIOS names exist in a flat namespace. In other words, there are no qualifiers such as <i>ora.com</i> or <i>samba.org</i> to section off hostnames; there is only a single unique name to represent each computer. Second, NetBIOS names are allowed to be only 15 characters, may not begin with an asterisk (*), and can consist only of standard alphanumeric characters (a-z, A-Z, 0-9) and the following:</p><PRE CLASS="programlisting">
+! @ # $ % ^ &amp; ( ) - ' { } . ~ </pre><P CLASS="para">
+Although you are allowed to use a period (.) in a NetBIOS name, we recommend against it because those names are not guaranteed to work in future versions of NetBIOS over TCP/IP.</p><P CLASS="para">
+It's not a coincidence that all valid DNS names are also valid NetBIOS names. In fact, the DNS name for a Samba server is often reused as its NetBIOS name. For example, if you had a machine <CODE CLASS="literal">
+phoenix.ora.com</code>, its NetBIOS name would likely be PHOENIX (followed by 8 blanks).</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-946016">
+1.3.4.1 Resource names and types</a></h4><P CLASS="para">
+With NetBIOS, a machine not only advertises its presence, but also tells others what types of services it offers. For example, <CODE CLASS="literal">
+phoenix</code> can indicate that it's not just a workstation, but is also a file server and can receive WinPopup messages. This is done by adding a 16th byte to the end of the machine (resource) name, called the <I CLASS="firstterm">resource type</i>, and registering the name more than once. See <A CLASS="xref" HREF="ch01_03.html#ch01-74707">
+Figure 1.10</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-74707">
+Figure 1.10: The structure of NetBIOS names</a></h4><IMG CLASS="graphic" SRC="figs/sam.0110.gif" ALT="Figure 1.10"><P CLASS="para">
+The one-byte resource type indicates a unique service the named machine provides. In this book, you will often see the resource type shown in angled brackets (&lt;&gt;) after the NetBIOS name, such as:</p><PRE CLASS="programlisting">PHOENIX&lt;00&gt;</pre><P CLASS="para">
+You can see which names are registered for a particular NBT machine using the Windows command-line NBTSTAT utility. Because these services are unique (i.e., there cannot be more than one registered), you will see them listed as type UNIQUE in the output. For example, the following partial output describes the <CODE CLASS="literal">
+hydra</code> server:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold">D:\&gt; NBTSTAT -a hydra</b><B CLASS="emphasis.bold"></b></pre><PRE CLASS="programlisting">
+ NetBIOS Remote Machine Name Table
+ Name Type Status
+---------------------------------------------
+HYDRA &lt;00&gt; UNIQUE Registered
+HYDRA &lt;03&gt; UNIQUE Registered
+HYDRA &lt;20&gt; UNIQUE Registered
+...</pre><P CLASS="para">
+This says the server has registered the NetBIOS name <CODE CLASS="literal">
+hydra</code> as a machine (workstation) name, a recipient of WinPopup messages, and a file server. Some possible attributes a name can have are listed in <A CLASS="xref" HREF="ch01_03.html#ch01-11471">
+Table 1.2</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-11471">
+Table 1.2: NetBIOS Unique Resource Types </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Named Resource</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Hexidecimal Byte Value</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Standard Workstation Service</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+00</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Messenger Service (WinPopup)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+03</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+RAS Server Service</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+06</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Domain Master Browser Service (associated with primary domain controller)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1B</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Master Browser name</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1D</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+NetDDE Service</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1F</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Fileserver (including printer server)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+20</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+RAS Client Service</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+21</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Monitor Agent</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+BE</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Monitor Utility</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+BF</p></td></tr></tbody></table><P CLASS="para">
+Note that because DNS names don't have resource types, the designers intentionally made hexidecimal value 20 (an ASCII space) default to the type for a file server.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-946074">
+1.3.4.2 Group names and types</a></h4><P CLASS="para">SMB also uses the concept of groups, with which machines can register themselves. Earlier, we mentioned that the machines in our example belonged to a <I CLASS="firstterm">
+workgroup</i>, which is a partition of machines on the same network. For example, a business might very easily have an ACCOUNTING and a SALES workgroup, each with different servers and printers. In the Windows world, a workgroup and an SMB group are the same thing.</p><P CLASS="para">
+Continuing our NBTSTAT example, the <CODE CLASS="literal">
+hydra</code> Samba server is also a member of the SIMPLE workgroup (the GROUP attribute hex 00), and will stand for election as a browse master (GROUP attribute 1E). Here is the remainder of the NBTSTAT utility output:</p><PRE CLASS="programlisting">
+ NetBIOS Remote Machine Name Table, continued
+ Name Type Status
+---------------------------------------------
+SIMPLE &lt;00&gt; GROUP Registered
+SIMPLE &lt;1E&gt; GROUP Registered
+..__MSBROWSE__. &lt;01&gt; GROUP Registered</pre><P CLASS="para">
+The possible group attributes a machine can have are illustrated in <A CLASS="xref" HREF="ch01_03.html#ch01-52395">
+Table 1.3</a>. More information is available in <i>Windows NT in a Nutshell</i> by Eric Pearce, also published by O'Reilly. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-52395">
+Table 1.3: NetBIOS Group Resource Types </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Named Resource </p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Hexidecimal Byte Value</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Standard Workstation group</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+00</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Logon Server </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1C</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Master Browser name </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1D</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Normal Group name (used in browser elections)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1E</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Internet Group name (administrative)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+20</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+&lt;01&gt;&lt;02&gt;__MSBROWSE__&lt;02&gt;</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+01</p></td></tr></tbody></table><P CLASS="para">
+The final entry, <CODE CLASS="literal">
+__MSBROWSE__</code>, is used to announce a group to other master browsers. The nonprinting characters in the name show up as dots in a NBTSTAT printout. Don't worry if you don't understand all of the resource or group types. Some of them you will not need with Samba, and others you will pick up as you move through the rest of the chapter. The important thing to remember here is the logistics of the naming mechanism. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-946130">
+1.3.5 Datagrams and Sessions</a></h3><P CLASS="para">
+<I CLASS="firstterm">
+</i>At this point, let's digress to introduce another responsibility of NBT: to provide connection services between two NetBIOS machines. There are actually two services offered by NetBIOS over TCP/IP: the <I CLASS="firstterm">
+session service</i> and the <I CLASS="firstterm">
+datagram service</i>. Understanding how these two services work is not essential to using Samba, but it does give you an idea of how NBT works and how to troubleshoot Samba when it doesn't work.</p><P CLASS="para">
+The datagram service has no stable connection between one machine and another. Packets of data are simply sent or broadcast from one machine to another, without regard for the order that they arrive at the destination, or even if they arrive at all. The use of datagrams is not as network intensive as sessions, although they can bog down a network if used unwisely (remember broadcast name resolution earlier?) Datagrams, therefore, are used for quickly sending simple blocks of data to one or more machines. The datagram service communicates using the simple primitives shown in <A CLASS="xref" HREF="ch01_03.html#ch01-pgfId-946185">
+Table 1.4</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-pgfId-946185">
+Table 1.4: Datagram Primitives </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primitive</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Send Datagram</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Send datagram packet to machine or groups of machines.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Send Broadcast Datagram</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Broadcast datagram to any machine waiting with a Receive Broadcast Datagram.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Receive Datagram</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Receive a datagram from a machine.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Receive Broadcast Datagram</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Wait for a broadcast datagram.</p></td></tr></tbody></table><P CLASS="para">
+The session service is more complex. Sessions are a communication method that, in theory, offers the ability to detect problematic or inoperable connections between two NetBIOS applications. It helps to think of an NBT session in terms of a telephone call.[<A CLASS="footnote" HREF="#ch01-pgfId-946249">5</a>] A full-duplex connection is opened between a caller machine and a called machine, and it must remain open throughout the duration of their conversation. Each side knows who the caller and the called machine is, and can communicate with the simple primitives shown in <A CLASS="xref" HREF="ch01_03.html#ch01-pgfId-946256">
+Table 1.5</a>. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch01-pgfId-946249">[5]</a> As you can see in RFC 1001, the telephone analogy was strongly evident in the creation of the NBT service.</p></div></blockquote><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-pgfId-946256">
+Table 1.5: Session Primitives </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primitive</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Call</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Initiate a session with a machine listening under a specified name.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Listen</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Wait for a call from a known caller or any caller.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Hang-up</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Exit a call.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Send</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Send data to the other machine.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Receive</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Receive data from the other machine.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Session Status</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Get information on requested sessions.</p></td></tr></tbody></table><P CLASS="para">
+Sessions are the backbone of resource sharing on an NBT network. They are typically used for establishing stable connections from client machines to disk or printer shares on a server. The client "calls" the server and starts trading information such as which files it wishes to open, which data it wishes to exchange, etc. These calls can last a long time&nbsp;- hours, even days&nbsp;- and all of this occurs within the context of a single connection. If there is an error, the session software (TCP) will retransmit until the data is received properly, unlike the "punt-and-pray" approach of the datagram service (UDP).</p><P CLASS="para">
+In truth, while sessions are supposed to be able to handle problematic communications, they often don't. As you've probably already discovered when using Windows networks, this is a serious detriment to using NBT sessions. If the connection is interrupted for some reason, session information that is open between the two computers can easily become invalidated. If that happens, the only way to regain the session information is for the same two computers to call each other again and start over.</p><P CLASS="para">
+If you want more information on each of these services, we recommend you look at RFC 1001. However, there are two important things to remember here:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-946210">
+</a>Sessions always occur between <EM CLASS="emphasis">
+two</em> NetBIOS machines&nbsp;- no more and no less. If a session service is interrupted, the client is supposed to store sufficient state information for it to re-establish the connection. However, in practice, this is rarely the case.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-946211">
+</a>Datagrams can be broadcast to multiple machines, but they are unreliable. In other words, there is no way for the source to know that the datagrams it sent have indeed arrived at their<I CLASS="firstterm">
+</i> destinations. </p></li></ul></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_02.html" TITLE="1.2 What Can Samba Do For Me?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.2 What Can Samba Do For Me?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_04.html" TITLE="1.4 Microsoft Implementations">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.4 Microsoft Implementations" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.2 What Can Samba Do For Me?</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.4 Microsoft Implementations</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_04.html b/docs/htmldocs/using_samba/ch01_04.html
new file mode 100755
index 00000000000..15a1943e6eb
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_04.html
@@ -0,0 +1,277 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.4 Microsoft Implementations</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:54Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_03.html" TITLE="1.3 Getting Familiar with a SMB/CIFS Network">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.3 Getting Familiar with a SMB/CIFS Network" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_05.html" TITLE="1.5 An Overview of the Samba Distribution">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.5 An Overview of the Samba Distribution" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-43359">
+1.4 Microsoft Implementations</a></h2><P CLASS="para">With that amount of background, we can now talk about some of Microsoft's implementations of the preceding concepts in the CIFS/SMB networking world. And, as you might expect, there are some complex extensions to introduce as well.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-946918">
+1.4.1 Windows Domains</a></h3><P CLASS="para">Recall that a workgroup is a collection of SMB computers that all reside on a subnet and subscribe to the same SMB group. A <I CLASS="firstterm">
+Windows domain</i> goes a step further. It is a workgroup of SMB machines that has one addition: a server acting as a <I CLASS="firstterm">
+domain controller</i>. You must have a domain controller in order to have a Windows domain.[<A CLASS="footnote" HREF="#ch01-pgfId-947021">6</a>] Otherwise, it is only a workgroup. See <A CLASS="xref" HREF="ch01_04.html#ch01-96972">
+Figure 1.11</a>. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch01-pgfId-947021">[6]</a> Windows domains are called "Windows NT domains" by Microsoft because they assume that Windows NT machines will take the role of the domain controller. However, because Samba can perform this function as well, we'll simply call them "Windows domains" to avoid confusion.</p></div></blockquote><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-96972">
+Figure 1.11: A simple Windows domain</a></h4><IMG CLASS="graphic" SRC="figs/sam.0111.gif" ALT="Figure 1.11"><P CLASS="para">There are currently two separate protocols used by a domain controller (logon server): one for communicating with Windows 95/98 machines and one for communicating with Windows NT machines. While Samba currently implements the domain controller protocol for Windows 95/98 (which allows it to act as a domain controller for Windows 9<EM CLASS="emphasis">
+x</em> machines), it still does not fully support the protocol for Windows NT computers. However, the Samba team promises that support for the Windows NT domain controller protocol is forthcoming in Samba 2.1.</p><P CLASS="para">
+Why all the difficulty? The protocol that Windows domain controllers use to communicate with their clients and other domain controllers is proprietary and has not been released by Microsoft. This has forced the Samba development team to reverse-engineer the domain controller protocol to see which codes perform specific tasks.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-946969">
+1.4.1.1 Domain controllers</a></h4><P CLASS="para">
+The domain controller is the nerve center of a Windows domain, much like an NIS server is the nerve center of the Unix network information service. Domain controllers have a variety of responsibilities. One responsibility that you need to be concerned with is <I CLASS="firstterm">
+authentication</i>. Authentication is the process of granting or denying a user access to a shared resource on another network machine, typically through the use of a password.</p><P CLASS="para">
+Each domain controller uses a <I CLASS="firstterm">
+security account manager</i> (SAM) to maintain a list of username-password combinations. The domain controller then forms a central repository of passwords that are tied to usernames (one password per user), which is more efficient than each client machine maintaining hundreds of passwords for every network resource available.</p><P CLASS="para">
+On a Windows domain, when a non-authenticated client requests access to a server's shares, the server will turn around and ask the domain controller whether that user is authenticated. If it is, the server will establish a session connection with the access rights it has for that service and user. If not, the connection is denied. Once a user is authenticated by the domain controller, a special authenticated token will be returned to the client so that the user will not need to relogin to other resources on that domain. At this point, the user is considered "logged in" to the domain itself. See <A CLASS="xref" HREF="ch01_04.html#ch01-49344">
+Figure 1.12</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-49344">
+Figure 1.12: Using a domain controller for authentication</a></h4><IMG CLASS="graphic" SRC="figs/sam.0112.gif" ALT="Figure 1.12"></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-939079">
+1.4.1.2 Primary and backup domain controllers</a></h4><P CLASS="para">Redundancy is a key idea behind a Windows domain. The domain controller that is currently active on a domain is called the <I CLASS="firstterm">
+primary domain controller</i> (PDC). There can be one or more <I CLASS="firstterm">
+backup domain controllers</i> (BDCs) in the domain as well, which will take over in the event that the primary domain controller fails or becomes inaccessible. BDCs frequently synchronize their SAM data with the primary domain controller so that, if the need arises, any one of them can perform DC services transparently without impacting its clients. Note that BDCs, however, have only read-only copies of the SAM; they can update their data only by synchronizing with a PDC. A server in a Windows domain can use the SAM of any primary or backup domain controller to authenticate a user who attempts to access its resources and logon to the domain.</p><P CLASS="para">
+Note that in many aspects, the behaviors of a Windows workgroup and a Windows domain overlap. This is not accidental since the concept of Windows domains did not evolve until Windows NT 3.5 was introduced, and Windows domains were forced to remain backwards compatible with the workgroups present in Windows for Workgroups 3.1. The key thing to remember here is that a Windows domain is simply a Windows workgroup with one or more domain controllers added.</p><P CLASS="para">
+Samba can function as a primary domain controller for Windows 95/98 machines without any problems. However, Samba 2.0 can act as a primary domain controller only for authentication purposes; it currently cannot assume any other PDC responsibilities. (By the time you read this, Samba 2.1 may be available so you can use Samba as a PDC for NT clients.) Also, because of the closed protocol used by Microsoft to synchronize SAM data, Samba currently cannot serve as a backup domain controller. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-951817">
+1.4.2 Browsing</a></h3><P CLASS="para">Browsing is a high-level answer to the user question: "What machines are out there on the Windows network?" Note that there is no connection with a World Wide Web browser, apart from the general idea of "discovering what's there." And, like the Web, what's out there can change without warning.</p><P CLASS="para">
+Before browsing, users had to know the name of the specific computer they wanted to connect to on the network, and then manually enter a UNC such as the following into an application or file manager to access resources:</p><PRE CLASS="programlisting">
+\\HYDRA\network\</pre><P CLASS="para">
+With browsing, however, you can examine the contents of a machine using a standard point-and-click GUI&nbsp;- in this case, the Network Neighborhood window in a Windows client.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-950089">
+1.4.2.1 Levels of browsing</a></h4><P CLASS="para">
+As we hinted at the beginning of the chapter, there are actually two types of browsing that you will encounter in an SMB/CIFS network:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-944661">
+</a>Browsing a list of machines (with shared resources)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-944662">
+</a>Browsing the shared resources of a specific machine</p></li></ul><P CLASS="para">Let's look at the first one. On each Windows workgroup (or domain) subnet, one computer has the responsibility of maintaining a list of the machines that are currently accessible through the network. This computer is called the <I CLASS="firstterm">
+local master browser</i>, and the list that it maintains is called the <I CLASS="firstterm">
+browse list</i>. Machines on a subnet use the browse list in order to cut down on the amount of network traffic generated while browsing. Instead of each computer dynamically polling to determine a list of the currently available machines, the computer can simply query the local master browser to obtain a complete, up-to-date list.</p><P CLASS="para">To browse the actual resources on a machine, a user must connect to the specific machine; this information cannot be obtained from the browse list. Browsing the list of resources on a machine can be done by clicking on the machine's icon when it is presented in the Network Neighborhood in Windows 95/98 or NT. As you saw at the opening of the chapter, the machine will respond with a list of shared resources that can be accessed if that user is successfully authenticated.</p><P CLASS="para">
+Each of the servers on a Windows workgroup is required to announce its presence to the local master browser after it has registered a NetBIOS name, and (theoretically) announce that it is leaving the workgroup when it is shut down. It is the local master browser's responsibility to record what the servers have announced. Note that the local master browser is not necessarily the same machine as a NetBIOS name server (NBNS), which we discussed earlier. </p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> The Windows Network Neighborhood can behave oddly: until you select a particular machine to browse, the Network Neighborhood window may contain data that is not up-to-date. That means that the Network Neighborhood window can be showing machines that have crashed, or can be missing machines that haven't been noticed yet. Put succinctly, once you've selected a server and connected to it, you can be a lot more confident that the shares and printers really exist on the network.</p></blockquote><P CLASS="para">
+Unlike the roles you've seen earlier, almost any Windows machine (NT Server, NT Workstation, 98, 95, or Windows 3.1 for Workgroups) can act as a local master browser. As with the domain controller, the local master browser can have one or more <I CLASS="firstterm">
+backup browsers</i> on the local subnet that will take over in the event that the local master browser fails or becomes inaccessible. To ensure fluid operation, the local backup browsers will frequently synchronize their browse list with the local master browser. Let's update our Windows domain diagram to include both a local master and local backup browser. The result is shown in <A CLASS="xref" HREF="ch01_04.html#ch01-77521">
+Figure 1.13</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-77521">
+Figure 1.13: A Windows domain with a local master and local backup browser</a></h4><IMG CLASS="graphic" SRC="figs/sam.0113.gif" ALT="Figure 1.13"><P CLASS="para">
+Here is how to calculate the minimum number of backup browsers that will be allocated on a workgroup:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-944330">
+</a>If there are between 1 and 32 Windows NT workstations on the network, or between 1 and 16 Windows 95/98 machines on the network, the local master browser allocates one backup browser in addition to the local master browser.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-950113">
+</a>If the number of Windows NT workstations falls between 33 and 64, or the number of Windows 95/98 workstations falls between 17 and 32, the local master browser allocates two backup browsers.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-944332">
+</a>For each group of 32 NT workstations or 16 Windows 95/98 machines beyond this, the local master browser allocates another backup browser.</p></li></ul><P CLASS="para">
+There is currently no upper limit on the number of backup browsers that can be allocated by the local master browser. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch01-pgfId-946408">
+1.4.2.2 Browsing elections</a></h4><P CLASS="para">
+Browsing is a critical aspect of any Windows workgroup. However, not everything runs perfectly on any network. For example, let's say that the Windows NT Server on the desk of a small company's CEO is the local master browser&nbsp;- that is, until he switches it off while plugging in his massage chair. At this point the Windows NT Workstation in the spare parts department might agree to take over the job. However, that computer is currently running a large, poorly written program that has brought its processor to its knees. The moral: browsing has to be very tolerant of servers coming and going. Because nearly every Windows machine can serve as a browser, there has to be a way of deciding at any time who will take on the job. This decision-making process is called an <I CLASS="firstterm">
+election</i>.</p><P CLASS="para">
+An election algorithm is built into nearly all Windows operating systems such that they can each agree who is going to be a local master browser and who will be local backup browsers. An election can be forced at any time. For example, let's assume that the CEO has finished his massage and reboots his server. As the server comes online, it will announce its presence and an election will take place to see if the PC in the spare parts department should still be the master browser. </p><P CLASS="para">
+When an election is performed, each machine broadcasts via datagrams information about itself. This information includes the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-939575">
+</a>The version of the election protocol used</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-939577">
+</a>The operating system on the machine</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-939576">
+</a>The amount of time the client has been on the network</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-939578">
+</a>The hostname of the client</p></li></ul><P CLASS="para">
+These values determine which operating system has seniority and will fulfill the role of the local master browser. (<a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a>, describes the election process in more detail.) The architecture developed to achieve this is not elegant and has built-in security problems. While a browsing domain can be integrated with domain security, the election algorithm does not take into consideration which computers become browsers. Thus it is possible for any machine running a browser service to register itself as participating in the browsing election, and (after winning) being able to change the browse list. Nevertheless, browsing is a key feature of Windows networking and backwards compatibility requirements will ensure that it is in use for years to come. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-939834">
+1.4.3 Can a Windows Workgroup Span Multiple Subnets?</a></h3><P CLASS="para">Yes, but most people who have done it have had their share of headaches. Spanning multiple subnets was not part of the initial design of Windows NT 3.5 or Windows for Workgroups. As a result, a Windows domain that spans two or more subnets is, in reality, the "gluing" together of two or more workgroups that share an identical name. The good news is that you can still use a primary domain controller to control authentication across each of the subnets. The bad news is that things are not as simple with browsing.</p><P CLASS="para">
+As mentioned previously, each subnet must have its own local master browser. When a Windows domain spans multiple subnets, a system administrator will have to assign one of the machines as the <I CLASS="firstterm">
+domain master browser</i>. The domain master browser will keep a browse list for the entire Windows domain. This browse list is created by periodically synchronizing the browse lists of each of the local master browsers with the browse list of the domain master browser. After the synchronization, the local master browser and the domain master browser should contain identical entries. See <A CLASS="xref" HREF="ch01_04.html#ch01-52572">
+Figure 1.14</a> for an illustration. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch01-52572">
+Figure 1.14: A workgroup that spans more than one subnet</a></h4><IMG CLASS="graphic" SRC="figs/sam.0114.gif" ALT="Figure 1.14"><P CLASS="para">
+Sound good? Well, it's not quite nirvana for the following reasons:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-947419">
+</a>If it exists, a primary domain controller always plays the role of the domain master browser. By Microsoft design, the two always share the NetBIOS resource type &lt;1B&gt;, and (unfortunately) cannot be separated.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-947420">
+</a>Windows 95/98 machines cannot become <EM CLASS="emphasis">
+or</em> <EM CLASS="emphasis">
+even contact</em> a domain master browser. The Samba group feels that this is a marketing decision from Microsoft that forces customers to have at least one Windows NT workstation (or Samba server) on each subnet of a multi-subnet workgroup.</p></li></ul><P CLASS="para">
+Each subnet's local master browser continues to maintain the browse list for its subnet, for which it becomes authoritative. So if a computer wants to see a list of servers within its own subnet, the local master browser of that subnet will be queried. If a computer wants to see a list of servers outside the subnet, it can still go only as far as the local master browser. This works because, at appointed intervals, the authoritative browse list of a subnet's local master browser is synchronized with the domain master browser, which is synchronized with the local master browser of the other subnets in the domain. This is called <I CLASS="firstterm">
+browse list propagation</i>.</p><P CLASS="para">
+Samba can act as a domain master browser on a Windows domain if required. In addition, it can also act as a local master browser for a Windows subnet, synchronizing its browse list with the domain master browser.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-938926">
+1.4.4 The Windows Internet Name Service (WINS)</a></h3><P CLASS="para">
+The Windows Internet Name Service (WINS) is Microsoft's implementation of a NetBIOS name server (NBNS). As such, WINS inherits much of NetBIOS's characteristics. First, WINS is flat; you can only have machines named <CODE CLASS="literal">
+fred</code> or workgroups like CANADA or USA. In addition, WINS is dynamic: when a client first comes online, it is required to report its hostname, its address, and its workgroup to the local WINS server. This WINS server will retain the information so long as the client periodically refreshes its WINS registration, which indicates that it's still connected to the network. Note that WINS servers are not domain or workgroup specific; they can appear anywhere and serve anyone.</p><P CLASS="para">
+Multiple WINS servers can be set to synchronize with each other after a specified amount of time. This allows entries for machines that come online and offline on the network to propagate from one WINS server to another. While in theory this seems efficient, it can quickly become cumbersome if there are several WINS servers covering a network. Because WINS services can cross multiple subnets (you'll either hardcode the address of a WINS server in each of your clients or obtain it via DHCP), it is often more efficient to have each Windows client, no matter how many Windows domains there are, point themselves to the same WINS server. That way, there will only be one authoritative WINS server with the correct information, instead of several WINS servers continually struggling to synchronize themselves with the most recent changes.</p><P CLASS="para">
+The currently active WINS server is known as the <I CLASS="firstterm">
+primary WINS server</i>. You can also install a secondary WINS server, which will take over in the event that the primary WINS server fails or becomes inaccessible. Note that there is no election to determine which machine becomes a primary or backup WINS server&nbsp;- the choice of WINS servers is static and must be predetermined by the system administrator. Both the primary and any backup WINS servers will synchronize their address databases on a periodic basis.</p><P CLASS="para">
+In the Windows family of operating systems, only an NT Workstation or an NT server can serve as a <I CLASS="firstterm">
+</i>WINS server. Samba can also function as a primary WINS server, but not a secondary WINS server.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-12452">
+1.4.5 What Can Samba Do?</a></h3><P CLASS="para">Whew! Bet you never thought Microsoft networks would be that complex, did you? Now, let's wrap up by showing where Samba can help out. <A CLASS="xref" HREF="ch01_04.html#ch01-pgfId-939957">
+Table 1.6</a> summarizes which roles Samba can and cannot play in a Windows NT Domain or Windows workgroup. As you can see, because many of the NT domain protocols are proprietary and have not been documented by Microsoft, Samba cannot properly synchronize its data with a Microsoft server and cannot act as a backup in most roles. However, with version 2.0.<EM CLASS="emphasis">
+x</em>, Samba does have limited support for the primary domain controller's authentication protocols and is gaining more functionality every day. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch01-pgfId-939957">
+Table 1.6: Samba Roles (as of 2.0.4b) </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Role</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Can Perform?</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+File Server</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Printer Server</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary Domain Controller</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes (Samba 2.1 or higher recommended)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Backup Domain Controller</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+No</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 95/98 Authentication</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Local Master Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Local Backup Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+No</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Domain Master Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary WINS Server</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Yes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Secondary WINS Server</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+No </p></td></tr></tbody></table></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_03.html" TITLE="1.3 Getting Familiar with a SMB/CIFS Network">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.3 Getting Familiar with a SMB/CIFS Network" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_05.html" TITLE="1.5 An Overview of the Samba Distribution">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.5 An Overview of the Samba Distribution" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.3 Getting Familiar with a SMB/CIFS Network</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.5 An Overview of the Samba Distribution</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_05.html b/docs/htmldocs/using_samba/ch01_05.html
new file mode 100755
index 00000000000..0989ddfb91b
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_05.html
@@ -0,0 +1,130 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.5 An Overview of the Samba Distribution</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:30:00Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_04.html" TITLE="1.4 Microsoft Implementations">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.4 Microsoft Implementations" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_06.html" TITLE="1.6 How Can I Get Samba?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.6 How Can I Get Samba?" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-32691">
+1.5 An Overview of the Samba Distribution</a></h2><P CLASS="para">
+As mentioned earlier, Samba actually contains several programs that serve different but related purposes. Let's introduce each of them briefly, and show how they work together. The majority of the programs that come with the Samba distribution center on its two daemons. Let's take a refined look at the responsibilities of each daemon:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<EM CLASS="emphasis">
+smbd</em></dt><DD CLASS="listitem">
+<P CLASS="para">
+The <EM CLASS="emphasis">
+smbd</em> daemon is responsible for managing the shared resources between the Samba server machine and its clients. It provides file, print, and browser services to <SPAN CLASS="acronym">
+SMB</span> clients across one or more networks. <EM CLASS="emphasis">
+smdb</em> handles all notifications between the Samba server and the network clients. In addition, it is responsible for user authentication, resource locking, and data sharing through the <SPAN CLASS="acronym">
+SMB</span> protocol.</p></dd><DT CLASS="term">
+<EM CLASS="emphasis">
+nmbd</em></dt><DD CLASS="listitem">
+<P CLASS="para">
+The <EM CLASS="emphasis">
+nmbd</em> daemon is a simple nameserver that mimics the WINS and NetBIOS name server functionality, as you might expect to encounter with the LAN Manager package. This daemon listens for nameserver requests and provides the appropriate information when called upon. It also provides browse lists for the Network Neighborhood and participates in browsing elections.</p></dd></dl><P CLASS="para">
+The Samba distribution also comes with a small set of Unix command-line tools:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<i>smbclient</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+An FTP-like Unix client that can be used to connect to Samba shares</p></dd><DT CLASS="term">
+<i>smbtar</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A program for backing up data in shares, similar to the Unix <I CLASS="filename">
+tar</i> command</p></dd><DT CLASS="term">
+<i>nmblookup</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A program that provides NetBIOS over TCP/IP name lookups</p></dd><DT CLASS="term">
+<i>smbpasswd</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A program that allows an administrator to change the encrypted passwords used by Samba</p></dd><DT CLASS="term">
+<i>smbstatus</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A program for reporting the current network connections to the shares on a Samba server</p></dd><DT CLASS="term">
+<i>testparm</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A simple program to validate the Samba configuration file</p></dd><DT CLASS="term">
+<i>testprns</i></dt><DD CLASS="listitem">
+<P CLASS="para">
+A program that tests whether various printers are recognized by the <I CLASS="filename">
+smbd</i> daemon</p></dd></dl><P CLASS="para">
+Each significant release of Samba goes through a significant exposure test before it's announced. In addition, it is quickly updated afterward if problems or unwanted side-effects are found. The latest stable distribution as of this writing is Samba 2.0.5, the long-awaited production version of Samba 2.0. This book focuses on the functionality supported in Samba 2.0, as opposed to the older 1.9.<EM CLASS="emphasis">
+x</em> versions of Samba, which are now obsolete.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_04.html" TITLE="1.4 Microsoft Implementations">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.4 Microsoft Implementations" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_06.html" TITLE="1.6 How Can I Get Samba?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.6 How Can I Get Samba?" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.4 Microsoft Implementations</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.6 How Can I Get Samba?</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_06.html b/docs/htmldocs/using_samba/ch01_06.html
new file mode 100755
index 00000000000..f3b46b2313b
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_06.html
@@ -0,0 +1,90 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.6 How Can I Get Samba?</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:30:01Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_05.html" TITLE="1.5 An Overview of the Samba Distribution">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.5 An Overview of the Samba Distribution" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_07.html" TITLE="1.7 What's New in Samba 2.0?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.7 What's New in Samba 2.0?" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-pgfId-946850">
+1.6 How Can I Get Samba?</a></h2><P CLASS="para">Samba is available in both binary and source format from a set of mirror sites across the Internet. The primary home site for Samba is located at <A CLASS="systemitem.url" HREF="http://www.samba.org/">http://www.samba.org/</a>.</p><P CLASS="para">
+However, if you don't want to wait for packets to arrive all the way from Australia, mirror sites for Samba can be found at any of several locations on the Internet. A list of mirrors is given at the primary Samba home page.</p><P CLASS="para">
+In addition, a CD-ROM distribution is available in the back of this book. We strongly encourage you to start with the CD-ROM if this is your first time using Samba. We've included source and binaries up to Samba 2.0.5 with this book. In addition, several of the testing tools that we refer to through the book are conveniently packaged on the CD-ROM.</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_05.html" TITLE="1.5 An Overview of the Samba Distribution">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.5 An Overview of the Samba Distribution" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_07.html" TITLE="1.7 What's New in Samba 2.0?">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.7 What's New in Samba 2.0?" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.5 An Overview of the Samba Distribution</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.7 What's New in Samba 2.0?</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_07.html b/docs/htmldocs/using_samba/ch01_07.html
new file mode 100755
index 00000000000..a5fd482b03b
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_07.html
@@ -0,0 +1,138 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.7 What's New in Samba 2.0?</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:30:01Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_06.html" TITLE="1.6 How Can I Get Samba?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.6 How Can I Get Samba?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_08.html" TITLE="1.8 And That's Not All...">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.8 And That's Not All..." BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-40528">
+1.7 What's New in Samba 2.0?</a></h2><P CLASS="para">Samba 2.0 was an eagerly-awaited package. The big additions to Samba 2.0 are more concrete support for NT Domains and the new Samba Web Administration Tool (SWAT), a browser-based utility for configuring Samba. However, there are dozens of other improvements that were introduced in the summer and fall of 1998. </p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937019">
+1.7.1 NT Domains</a></h3><P CLASS="para">
+Samba's support for NT Domains (starting with version 2.0.<EM CLASS="emphasis">
+x</em>) produced a big improvement: it allows SMB servers to use its authentication mechanisms, which is essential for future NT compatibility, and to support <I CLASS="firstterm">
+NT domain logons</i>. Domain logons allow a user to log in to a Windows NT domain and use all the computers in the domain without logging into them individually. Previous to version 2.0.0, Samba supported Windows 95/98 logon services, but not NT domain logons. Although domain logons support is not complete is Samba 2.0, it is partially implemented.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937021">
+1.7.2 Ease of Administration</a></h3><P CLASS="para">SWAT, the Samba Web Administration Tool, makes it easy to set up a server and change its configuration, without giving up the simple text-based configuration file. SWAT provides a graphical interface to the resources that Samba shares with its clients. In addition, SWAT saves considerable experimentation and memory work in setting up or changing configurations across the network. You can even create an initial setup with SWAT and then modify the file later by hand, or vice versa. Samba will not complain.</p><P CLASS="para">
+On the compilation side, GNU <I CLASS="filename">
+autoconf</i> is now used to make the task of initial compilation and setup easier so you can get to SWAT quicker.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937024">
+1.7.3 Performance</a></h3><P CLASS="para">
+There are major performance and scalability increases in Samba: the code has been reorganized and <EM CLASS="emphasis">
+nmbd</em> (the Samba name service daemon) heavily rewritten:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-937026">
+</a>Name/browsing service now supports approximately 35,000 simultaneous clients.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-937027">
+</a>File and print services support 500 concurrent users from a single medium-sized server without noticeable performance degradation.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-937028">
+</a>Linux/Samba on identical hardware now consistently performs better than NT Server. And best of all, Samba is improving.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch01-pgfId-937029">
+</a>Improved "opportunistic" locking allows client machines to cache entire files locally, greatly improving speed without running the risk of accidentally overwriting the cached files.</p></li></ul></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937030">
+1.7.4 More Features</a></h3><P CLASS="para">
+There are several additional features in Samba 2.0. You can now have multiple Samba aliases on the same machine, each pretending to be a different server, a feature similar to virtual hosts in modern web servers. This allows a host to serve multiple departments and groups, or provide disk shares with normal username/password security while also providing printers to everyone without any security. Printing has been changed to make it easier for Unix System V owners: Samba can now find the available printers automatically, just as it does with Berkeley-style printing. In addition, Samba now has the capability to use multiple code pages, so it can be used with non-European languages, and to use the Secure Sockets Layer protocol (SSL) to encrypt all the data it sends across the Internet, instead of just passwords.[<A CLASS="footnote" HREF="#ch01-pgfId-938280">7</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch01-pgfId-938280">[7]</a> If you reside in the United States, there are some federal rules and regulations dealing with strong cryptography. We'll talk about his later when we set up Samba and SSL in <a href="appa_01.html"><b>Appendix A, <CITE CLASS="appendix">
+Configuring Samba with SSL</cite></b></a>.</p></div></blockquote></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937035">
+1.7.5 Compatibility Improvements</a></h3><P CLASS="para">
+At the same time as it's becoming more capable, Samba is also becoming more compatible with Windows NT. Samba has always supported Microsoft-style password encryption. It now provides tools and options for changing over to Microsoft encryption, and for keeping the Unix and Microsoft password files synchronized while doing so. Finally, a Samba master browser can be instructed to hunt down and synchronize itself with other SMB servers on different LANs, allowing SMB to work seamlessly across multiple networks. Samba uses a different method of accomplishing this from the Microsoft method, which is undocumented.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch01-pgfId-937039">
+1.7.6 Smbwrapper</a></h3><P CLASS="para">
+Finally, there is an entirely new version of the Unix client called <I CLASS="firstterm">
+smbwrapper</i>. Instead of a kernel module that allows Linux to act as a Samba client, there is now a command-line entry to load the library that provides a complete SMB filesystem on some brands of Unix. Once loaded, the command <CODE CLASS="literal">
+ls</code> <CODE CLASS="literal">
+/smb</code> will list all the machines in your workgroup, and <CODE CLASS="literal">
+cd</code> <CODE CLASS="literal">/smb/</code><CODE CLASS="replaceable"><I>server_name</i></code><CODE CLASS="literal">/</code><CODE CLASS="replaceable"><I>share_name</i></code> will take you to a particular share (shared directory), similar to the Network File System (NFS). As of this writing, <EM CLASS="emphasis">
+smbwrapper</em> currently runs on Linux, Solaris, SunOS 4, IRIX, and OSF/1, and is expected to run on several more operating systems in the near future.</p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_06.html" TITLE="1.6 How Can I Get Samba?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.6 How Can I Get Samba?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_08.html" TITLE="1.8 And That's Not All...">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 1.8 And That's Not All..." BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.6 How Can I Get Samba?</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+1.8 And That's Not All...</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch01_08.html b/docs/htmldocs/using_samba/ch01_08.html
new file mode 100755
index 00000000000..0ea2d0331ce
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch01_08.html
@@ -0,0 +1,89 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 1] 1.8 And That's Not All...</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:30:04Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_07.html" TITLE="1.7 What's New in Samba 2.0?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.7 What's New in Samba 2.0?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch01_01.html" TITLE="1. Learning the Samba">
+Chapter 1<br>
+Learning the Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2. Installing Samba on a Unix System" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch01-99818">
+1.8 And That's Not All...</a></h2><P CLASS="para">
+Samba is a wonderful tool with potential for even the smallest SMB/CIFS network. This chapter presented you with a thorough introduction to what Samba is, and more importantly, how it fits into a Windows network. The next series of chapters will help you set up Samba on both the Unix server side, where its two daemons reside, as well as configure the Windows 95, 98, and NT clients to work with Samba. Before long, the aches and pains of your heterogeneous network may seem like a thing of the past. Welcome to the wonderful world of Samba!</p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_07.html" TITLE="1.7 What's New in Samba 2.0?">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.7 What's New in Samba 2.0?" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2. Installing Samba on a Unix System" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.7 What's New in Samba 2.0?</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2. Installing Samba on a Unix System</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_01.html b/docs/htmldocs/using_samba/ch02_01.html
new file mode 100755
index 00000000000..a90a52d8abe
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_01.html
@@ -0,0 +1,197 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] Installing Samba on a Unix System</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:03Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_08.html" TITLE="1.8 And That's Not All...">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.8 And That's Not All..." BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 2</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_02.html" TITLE="2.2 Configuring Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.2 Configuring Samba" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch02-46174">
+2. Installing Samba on a Unix System</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch02-85028" TITLE="2.1 Downloading the Samba Distribution">
+Downloading the Samba Distribution</a><br>
+<A CLASS="sect1" HREF="ch02_02.html" TITLE="2.2 Configuring Samba">
+Configuring Samba</a><br>
+<A CLASS="sect1" HREF="ch02_03.html" TITLE="2.3 Compiling and Installing Samba">
+Compiling and Installing Samba</a><br>
+<A CLASS="sect1" HREF="ch02_04.html" TITLE="2.4 A Basic Samba Configuration File">
+A Basic Samba Configuration File</a><br>
+<A CLASS="sect1" HREF="ch02_05.html" TITLE="2.5 Starting the Samba Daemons">
+Starting the Samba Daemons</a><br>
+<A CLASS="sect1" HREF="ch02_06.html" TITLE="2.6 Testing the Samba Daemons">
+Testing the Samba Daemons</a></p><P>
+</p></div><P CLASS="para">Now that you know what Samba can do for you and your users, it's time to get your own network set up. Let's start with the installation of Samba itself on a Unix system. When dancing the samba, one learns by taking small steps. It's just the same when installing Samba; we need to teach it step by step. This chapter will help you to start off on the right foot. </p><P CLASS="para">
+For illustrative purposes, we will be installing the 2.0.4 version of the Samba server on a Linux[<A CLASS="footnote" HREF="#ch02-pgfId-939741">1</a>] system running version 2.0.31 of the kernel. However, the installation steps are the same for all of the platforms that Samba supports. A typical installation will take about an hour to complete, including downloading the source files and compiling them, setting up the configuration files, and testing the server. </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch02-pgfId-939741">[1]</a> If you haven't heard of Linux yet, then you're in for a treat. Linux is a freely distributed Unix-like operating system that runs on the Intel x86, Motorola PowerPC, and Sun Sparc platforms. The operating system is relatively easy to configure, extremely robust, and is gaining in popularity. You can get more information on the Linux operating system at <a href="http://www.linux.org/"><EM CLASS="emphasis">http://www.linux.org/</a></em>.</p></div></blockquote><P CLASS="para">Here is an overview of the steps:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938543">
+</a>Download the source or binary files.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938544">
+</a>Read the installation documentation.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938545">
+</a>Configure a makefile.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938546">
+</a>Compile the server code.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938547">
+</a>Install the server files.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938548">
+</a>Create a Samba configuration file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938549">
+</a>Test the configuration file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938550">
+</a>Start the Samba daemons.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938551">
+</a>Test the Samba daemons.</p></li></ol><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch02-85028">
+2.1 Downloading the Samba Distribution</a></h2><P CLASS="para">If you want to get started quickly, the CD-ROM packaged with this book contains both the sources and binaries of Samba that were available as this book went to print. The CD is a mirror image of the files and directories on the Samba download server: <EM CLASS="emphasis">
+ftp.samba.org</em>.</p><P CLASS="para">
+On the other hand, if you want to download the latest version, the primary web site for the Samba software is <A CLASS="systemitem.url" HREF="http://www.samba.org">http://www.samba.org</a>. Once connected to this page, you'll see links to several Samba mirror sites across the world, both for the standard Samba web pages and sites devoted exclusively to downloading Samba. For the best performance, choose a site that is closest to your own geographic location.</p><P CLASS="para">
+The standard Samba web sites have Samba documentation and tutorials, mailing list archives, and the latest Samba news, as well as source and binary distributions of Samba. The download sites (sometimes called <EM CLASS="emphasis">
+FTP sites</em>) have only the source and binary distributions. Unless you specifically want an older version of the Samba server or are going to install a binary distribution, download the latest source distribution from the closest mirror site. This distribution is always named:</p><PRE CLASS="programlisting">samba-latest.tar.gz</pre><P CLASS="para">
+If you choose to use the version of Samba that is located on the CD-ROM packaged with this book, you should find the latest Samba distribution in the base directory.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-938556">
+2.1.1 Binary or Source?</a></h3><P CLASS="para">Precompiled packages are also available for a large number of Unix platforms. These packages contain binaries for each of the Samba executables as well as the standard Samba documentation. Note that while installing a binary distribution can save you a fair amount of trouble and time, there are a couple of issues that you should keep in mind when deciding whether to use the binary or compile the source yourself:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938558">
+</a>The binary packages can lag behind the latest version of the software by one or two (maybe more) minor releases, especially after a series of small changes and for less popular platforms. Compare the release notes for the source and binary packages to make sure that there aren't any new features that you need on your platform. This is especially true of the sources and binaries on the CD-ROM: at the time this book went to print, they were from the latest production release of Samba. However, development is ongoing, so the beta-test versions on the Internet will be newer.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938560">
+</a>If you use a precompiled binary, you will need to ensure that you have the correct libraries required by the executables. On some platforms the executables are statically linked so this isn't an issue, but on modern Unix operating systems (e.g., Linux, SGI Irix, Solaris, HP-UX, etc.), libraries are often dynamically linked. This means that the binary looks for the right version of each library on your system, so you may have to install a new version of a library. The <I CLASS="filename">
+README</i> file or <I CLASS="filename">
+makefile</i> that accompanies the binary distribution should list any special requirements.[<A CLASS="footnote" HREF="#ch02-pgfId-943622">2</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch02-pgfId-943622">[2]</a> This is especially true with programs that use <EM CLASS="emphasis">
+glibc-2.1</em> (which comes standard with Red Hat Linux 6). This library caused quite a consternation in the development community when it was released because it was incompatable with previous versions of <EM CLASS="emphasis">g</em><I CLASS="filename">libc</i>.</p></div></blockquote><P CLASS="para">Many machines with shared libraries come with a nifty tool called <EM CLASS="emphasis">ldd</em>. This tool will tell you which libraries a specific binary requires and which libraries on the system satisfy that requirement. For example, checking the <EM CLASS="emphasis">
+smbd</em> program on our test machine gave us:</p></li></ul><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">$</code> ldd smbd</b>
+</pre><PRE CLASS="programlisting">
+libreadline.so.3 =&gt; /usr/lib/libreadline.so.3
+libdl.so.2 =&gt; /lib/libdl.so.2
+libcrypt.so.1 =&gt; /lib/libcrypt.so.1
+libc.so.6 =&gt; /lib/libc.so.6
+libtermcap.so.2 =&gt; /lib/libtermcap.so.2
+/lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2</pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+If there are any incompatibilities between Samba and specific libraries on your machine, the distribution-specific documentation should highlight those.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938567">
+</a>Keep in mind that each binary distribution carries preset values about the target platform, such as default directories and configuration option values. Again, check the documentation and the makefile included in the source directory to see which directives and variables were used when the binary was compiled. In some cases, these will not be appropriate for your situation. </p><P CLASS="para">
+A few configuration items can be reset with command-line options at runtime instead of at compile time. For example, if your binary tries to place any log, lock, or status files in the "wrong" place (for example, in <I CLASS="filename">
+/usr/local</i>), you can override this without recompiling. </p></li></ul><P CLASS="para">
+One point worth mentioning is that the Samba source requires an ANSI C compiler. If you are on a platform with a non-ANSI compiler, such as the <EM CLASS="emphasis">
+cc</em> compiler on SunOS version 4, you'll have to install an ANSI-compliant compiler such as <EM CLASS="emphasis">
+gcc </em>before you do anything else.[<A CLASS="footnote" HREF="#ch02-pgfId-939049">3</a>] If installing a compiler isn't something you want to wrestle with, you can start off with a binary package. However, for the most flexibility and compatibility on your system, we always recommend compiling from the latest source.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch02-pgfId-939049">[3]</a> <EM CLASS="emphasis">
+gcc</em> binaries are available for almost every modern machine. See <A CLASS="systemitem.url" HREF="http://www.gnu.org/">
+http://www.gnu.org/</a> for a list of sites with <EM CLASS="emphasis">
+gcc</em> and other GNU software.</p></div></blockquote></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-938574">
+2.1.2 Read the Documentation</a></h3><P CLASS="para">This sounds like an obvious thing to say, but there have probably been times where you have uncompressed a package, blindly typed <CODE CLASS="literal">
+configure</code>, <CODE CLASS="literal">
+make</code>, and <CODE CLASS="literal">
+make</code> <CODE CLASS="literal">
+install</code>, and walked away to get another cup of coffee. We'll be the first to admit that we do that, many more times than we should. It's a bad idea&nbsp;- especially when planning a network with Samba.</p><P CLASS="para">
+Samba 2.0 automatically configures itself prior to compilation. This reduces the likelihood of a machine-specific problem, but there may be an option mentioned in the <I CLASS="filename">
+README</i> file that you end up wishing for after Samba's been installed. With both source and binary packages you'll find a large number of documents in the <I CLASS="filename">
+docs</i> directory, in a variety of formats. The most important files to look at in the distribution are:</p><PRE CLASS="programlisting">
+WHATSNEW.txt
+docs/textdocs/UNIX_INSTALL.txt</pre><P CLASS="para">
+These files tell you what features you can expect in your Samba distribution, and will highlight common installation problems that you're likely to face. Be sure to look over both of them before you start the compilation process. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch01_08.html" TITLE="1.8 And That's Not All...">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 1.8 And That's Not All..." BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_02.html" TITLE="2.2 Configuring Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.2 Configuring Samba" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+1.8 And That's Not All...</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2.2 Configuring Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_02.html b/docs/htmldocs/using_samba/ch02_02.html
new file mode 100755
index 00000000000..3556314b438
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_02.html
@@ -0,0 +1,338 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] 2.2 Configuring Samba</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:05Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_01.html" TITLE="2.1 Downloading the Samba Distribution">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.1 Downloading the Samba Distribution" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+Chapter 2<br>
+Installing Samba on a Unix System</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_03.html" TITLE="2.3 Compiling and Installing Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.3 Compiling and Installing Samba" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch02-28558">
+2.2 Configuring Samba</a></h2><P CLASS="para">The source distribution of Samba 2.0 and above doesn't initially have a makefile. Instead, one is generated through a GNU <I CLASS="filename">
+configure</i> script, which is located in the <I CLASS="filename">
+samba-2.0.x /source/</i> directory. The <I CLASS="firstterm">
+configure</i> script, which must be run as root, takes care of the machine-specific issues of building Samba. However, you still may want to decide on some global options. Global options can be set by passing options on the command-line:</p><PRE CLASS="programlisting">
+# ./configure --with-ssl</pre><P CLASS="para">
+For example, this will configure the Samba makefile with support for the Secure Sockets Layer (SSL) encryption protocol. If you would like a complete list of options, type the following:</p><PRE CLASS="programlisting">
+# ./configure --help</pre><P CLASS="para">Each of these options enable or disable various features. You typically enable a feature by specifying the <CODE CLASS="literal">
+--with-</code><CODE CLASS="replaceable">
+<I>
+feature</i></code> option, which will cause the feature to be compiled and installed. Likewise, if you specify a <CODE CLASS="literal">
+--without-</code><CODE CLASS="replaceable">
+<I>
+feature</i></code> option, the feature will be disabled. As of Samba 2.0.5, each of the following features is disabled by default:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<CODE CLASS="literal">
+--with-smbwrapper</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include SMB wrapper support, which allows executables on the Unix side to access SMB/CIFS filesystems as if they were regular Unix filesystems. We recommend using this option. However, at this time this book went to press, there were several incompatibilities between the <I CLASS="filename">
+smbwrapper</i> package and the GNU <I CLASS="filename">
+libc</i> version 2.1, and it would not compile on Red Hat 6.0. Look for more information on these incompatibilities on the Samba home page.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-afs</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support of the Andrew Filesystem from Carnegie Mellon University. If you're going to serve AFS files via Samba, we recommend compiling Samba once first without enabling this feature to ensure that everything runs smoothly. Once that version is working smoothly, recompile Samba with this feature enabled and compare any errors you might receive against the previous setup.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-dfs</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for DFS, a later version of AFS, used by OSF/1 (Digital Unix). Note that this is <EM CLASS="emphasis">
+not</em> the same as Microsoft DFS, which is an entirely different filesystem. Again, we recommend compiling Samba once first without this feature to ensure that everything runs smoothly, then recompile with this feature to compare any errors against the previous setup.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-krb4</code>=<CODE CLASS="replaceable"><I>base-directory</i></code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for Kerberos version 4.0, explicitly specifying the base directory of the distribution. Kerberos is a network security protocol from MIT that uses private key cryptography to provide strong security between nodes. Incidentally, Microsoft has announced that Kerberos 5.0 will be the standard authentication mechanism for Microsoft Windows 2000 (NT 5.0). However, the Kerberos 5.0 authentication mechanisms are quite different from the Kerberos 4.0 security mechanisms. If you have Kerberos version 4 on your system, the Samba team recommends that you upgrade and use the <CODE CLASS="literal">
+--with-krb5</code> option (see the next item). You can find more information on Kerberos at <a href="http://web.mit.edu/kerberos/www"><EM CLASS="emphasis">http://web.mit.edu/kerberos/www</a></em>.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-krb5</code>=<CODE CLASS="replaceable"><I>base-directory</i></code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for Kerberos version 5.0, explicitly specifying the base directory of the distribution. Microsoft has announced that Kerberos 5.0 will be the standard authentication mechanism for Microsoft Windows 2000 (NT 5.0). However, there is no guarantee that Microsoft will not extend Kerberos for their own needs in the future. Currently, Samba's Kerberos support only uses a plaintext password interface and not an encrypted one. You can find more information on Kerberos at its home page: <a href="http://web.mit.edu/kerberos/www"><EM CLASS="emphasis">http://web.mit.edu/kerberos/www</a></em>.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-automount</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for automounter, a feature often used on sites that offer NFS. </p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-smbmount</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include <EM CLASS="emphasis">
+smbmount</em> support, which is for Linux only. This feature wasn't being maintained at the time the book was written, so the Samba team made it an optional feature and provided <EM CLASS="emphasis">
+smbwrapper</em> instead. The <EM CLASS="emphasis">
+smbwrapper</em> feature works on more Unix platforms than <EM CLASS="emphasis">
+smbmount</em>, so you'll usually want to use <CODE CLASS="literal">
+--with-smbwrapper</code> instead of this option.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-pam</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for pluggable authentication modules (PAM), an authentication feature common in the Linux operating system.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-ldap</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for the Lightweight Directory Access Protocol (LDAP). A future version of LDAP will be used in the Windows 2000 (NT 5.0) operating system; this Samba support is experimental. LDAP is a flexible client-server directory protocol that can carry information such as certificates and group memberships.[<A CLASS="footnote" HREF="#ch02-pgfId-943655">4</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch02-pgfId-943655">[4]</a> By <EM CLASS="emphasis">
+directory</em>, we don't mean a directory in a file system, but instead an indexed directory (such as a phone directory). Information is stored and can be easily retrieved in a public LDAP system.</p></div></blockquote></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-nis</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for getting password-file information from NIS (network yellow pages).</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-nisplus</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for obtaining password-file information from NIS+, the successor to NIS.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-ssl</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include experimental support for the Secure Sockets Layer (SSL), which is used to provide encrypted connections from client to server. <a href="appa_01.html"><b>Appendix A, <CITE CLASS="appendix">Configuring Samba with SSL</cite></b></a>, describes setting up Samba with SSL support.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-nisplus-home</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for locating which server contains a particular user's home directory and telling the client to connect to it. Requires <CODE CLASS="literal">
+--with-nis</code> and, usually, <CODE CLASS="literal">
+--with-automounter</code>. </p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-mmap</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include experimental memory mapping code. This is not required for fast locking, which already uses mmap or System V shared memory.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-syslog</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include support for using the SYSLOG utility for logging information generated from the Samba server. There are a couple of Samba configuration options that you can use to enable SYSLOG support; <a href="ch04_01.html"><b>Chapter 4, <CITE CLASS="chapter">Disk Shares </cite></b></a>, discusses these options.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-netatalk</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include experimental support for interoperating with the (Macintosh) Netatalk file server.</p></dd><DT CLASS="term">
+<CODE CLASS="literal">
+--with-quotas</code></dt><DD CLASS="listitem">
+<P CLASS="para">
+Include disk-quota support.</p></dd></dl><P CLASS="para">
+Because each of these options is disabled by default, none of these features are essential to Samba. However, you may want to come back and build a modified version of Samba if you discover that you need one at a later time.</p><P CLASS="para">
+In addition, <A CLASS="xref" HREF="ch02_02.html#ch02-85125">
+Table 2.1</a> shows some other parameters that you can give the <I CLASS="filename">
+configure</i> script if you wish to store parts of the Samba distribution in different places, perhaps to make use of multiple disks or partitions. Note that the defaults sometimes refer to a prefix specified earlier in the table. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch02-85125">
+Table 2.1: Additional Configure Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Meaning</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--prefix</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install architecture-independent files at the base directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<I CLASS="filename">
+/usr/local/samba</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--eprefix</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install architecture-dependent files at the base directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<I CLASS="filename">
+/usr/local/samba</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--bindir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install user executables in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+eprefix</i></code><I CLASS="filename">/bin</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--sbindir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install administrator executables in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+eprefix</i></code><I CLASS="filename">/bin</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--libexecdir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install program executables in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+eprefix</i></code><I CLASS="filename">/libexec</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--datadir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install read-only architecture independent data in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+prefix</i></code><I CLASS="filename">/share</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--libdir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install program libraries in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+eprefix</i></code><I CLASS="filename">/lib</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--includedir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install package include files in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+prefix</i></code><I CLASS="filename">/include</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--infodir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install additional information files in the directory specified.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+prefix</i></code><I CLASS="filename">/info</i></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+--mandir</code>=<CODE CLASS="replaceable"><I>directory</i></code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Install manual pages in the directory specified. </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="replaceable">
+<I>
+prefix</i></code><I CLASS="filename">/man</i></p></td></tr></tbody></table><P CLASS="para">
+Again, before running the <I CLASS="filename">
+configure</i> script, it is important that you are the root user on the system. Otherwise, you may get a warning such as:</p><PRE CLASS="programlisting">
+configure: warning: running as non-root will disable some tests</pre><P CLASS="para">
+You don't want any test to be disabled when the Samba makefile is being created; this leaves the potential for errors down the road when compiling or running Samba on your system.</p><P CLASS="para">
+Here is a sample execution of the <I CLASS="filename">
+configure</i> script, which creates a Samba 2.0.4 makefile for the Linux platform. Note that you must run the configure script in the <EM CLASS="emphasis">
+source</em> directory, and that several lines from the middle of the excerpt have been omitted:</p><PRE CLASS="programlisting">
+# cd samba-2.0.4b/source/
+# ./configure | tee mylog
+
+loading cache ./config.cache
+checking for gcc... (cached) gcc
+checking whether the C compiler (gcc -O) works... yes
+checking whether the C compiler (gcc -O) is a cross-compiler... no
+checking whether we are using GNU C... (cached) yes
+checking whether gcc accepts -g... (cached) yes
+checking for a BSD compatible install... (cached) /usr/bin/install -c
+
+<EM CLASS="emphasis">...(content omitted)...</em>
+
+checking configure summary
+configure OK
+creating ./config.status
+creating include/stamp-h
+creating Makefile
+creating include/config.h</pre><P CLASS="para">
+In general, any message from <I CLASS="filename">
+configure</i> that doesn't begin with the words <CODE CLASS="literal">
+checking</code> or <CODE CLASS="literal">
+creating</code> is an error; it often helps to redirect the output of the configure script to a file so you can quickly search for errors, as we did with the <CODE CLASS="literal">
+tee</code> command above. If there was an error during configuration, more detailed information about it can be found in the <I CLASS="filename">
+config.log</i> file, which is written to the local directory by the <I CLASS="filename">
+configure</i> script.</p><P CLASS="para">
+If the configuration works, you'll see a <CODE CLASS="literal">
+checking</code> <CODE CLASS="literal">
+configure</code> <CODE CLASS="literal">
+summary</code> message followed by a <CODE CLASS="literal">
+configure</code> <CODE CLASS="literal">
+OK</code> message and four or five file creation messages. So far, so good.... Next step: compiling. </p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_01.html" TITLE="2.1 Downloading the Samba Distribution">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.1 Downloading the Samba Distribution" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_03.html" TITLE="2.3 Compiling and Installing Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.3 Compiling and Installing Samba" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.1 Downloading the Samba Distribution</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2.3 Compiling and Installing Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_03.html b/docs/htmldocs/using_samba/ch02_03.html
new file mode 100755
index 00000000000..c4313736d8b
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_03.html
@@ -0,0 +1,235 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] 2.3 Compiling and Installing Samba</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:09Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_02.html" TITLE="2.2 Configuring Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.2 Configuring Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+Chapter 2<br>
+Installing Samba on a Unix System</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_04.html" TITLE="2.4 A Basic Samba Configuration File">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.4 A Basic Samba Configuration File" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch02-13217">
+2.3 Compiling and Installing Samba</a></h2><P CLASS="para">At this point you should be ready to build the Samba executables. Compiling is also easy: in the <I CLASS="filename">
+source</i> directory, type <CODE CLASS="literal">
+make</code> on the command line. The <I CLASS="filename">
+make</i> utility will produce a stream of explanatory and success messages, beginning with:</p><PRE CLASS="programlisting">
+Using FLAGS = -O -Iinclude ...</pre><P CLASS="para">
+This build includes compiles for both <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em>, and ends in a linking command for <I CLASS="filename">
+bin/make_ printerdef</i>. For example, here is a sample make of Samba version 2.0.4 on a Linux server:</p><PRE CLASS="programlisting"><CODE CLASS="literal"># </code>make
+Using FLAGS = -O -Iinclude -I./include -I./ubiqx -I./smbwrapper -DSMBLOGFILE=&quot;/usr/local/samba/var/log.smb&quot; -DNMBLOGFILE=&quot;/usr/local/samba/var/log.nmb&quot; -DCONFIGFILE=&quot;/usr/local/samba/lib/smb.conf&quot; -DLMHOSTSFILE=&quot;/usr/local/samba/lib/lmhosts&quot; -DSWATDIR=&quot;/usr/local/samba/swat&quot; -DSBINDIR=&quot;/usr/local/samba/bin&quot; -DLOCKDIR=&quot;/usr/local/samba/var/locks&quot; -DSMBRUN=&quot;/usr/local/samba/bin/smbrun&quot; -DCODEPAGEDIR=&quot;/usr/local/samba/lib/codepages&quot; -DDRIVERFILE=&quot;/usr/local/samba/lib/printers.def&quot; -DBINDIR=&quot;/usr/local/samba/bin&quot; -DHAVE_INCLUDES_H -DPASSWD_PROGRAM=&quot;/bin/passwd&quot; -DSMB_PASSWD_FILE=&quot;/usr/local/samba/private/smbpasswd&quot;
+Using FLAGS32 = -O -Iinclude -I./include -I./ubiqx -I./smbwrapper -DSMBLOGFILE=&quot;/usr/local/samba/var/log.smb&quot; -DNMBLOGFILE=&quot;/usr/local/samba/var/log.nmb&quot; -DCONFIGFILE=&quot;/usr/local/samba/lib/smb.conf&quot; -DLMHOSTSFILE=&quot;/usr/local/samba/lib/lmhosts&quot; -DSWATDIR=&quot;/usr/local/samba/swat&quot; -DSBINDIR=&quot;/usr/local/samba/bin&quot; -DLOCKDIR=&quot;/usr/local/samba/var/locks&quot; -DSMBRUN=&quot;/usr/local/samba/bin/smbrun&quot; -DCODEPAGEDIR=&quot;/usr/local/samba/lib/codepages&quot; -DDRIVERFILE=&quot;/usr/local/samba/lib/printers.def&quot; -DBINDIR=&quot;/usr/local/samba/bin&quot; -DHAVE_INCLUDES_H -DPASSWD_PROGRAM=&quot;/bin/passwd&quot; -DSMB_PASSWD_FILE=&quot;/usr/local/samba/private/smbpasswd&quot;
+Using LIBS = -lreadline -ldl -lcrypt -lpam
+Compiling smbd/server.c
+Compiling smbd/files.c
+Compiling smbd/chgpasswd.c
+
+<EM CLASS="emphasis">...(content omitted)...</em>
+
+Compiling rpcclient/cmd_samr.c
+Compiling rpcclient/cmd_reg.c
+Compiling rpcclient/cmd_srvsvc.c
+Compiling rpcclient/cmd_netlogon.c
+Linking bin/rpcclient
+Compiling utils/smbpasswd.c
+Linking bin/smbpasswd
+Compiling utils/make_smbcodepage.c
+Linking bin/make_smbcodepage
+Compiling utils/nmblookup.c
+Linking bin/nmblookup
+Compiling utils/make_printerdef.c
+Linking bin/make_printerdef</pre><P CLASS="para">
+If you encounter problems when compiling, check the Samba documentation to see if it is easily fixable. Another possibility is to search or post to the Samba mailing lists, which are given at the end of <a href="ch09_03.html">Chapter 9</a>, and on the Samba home page. Most compilation issues are system specific and almost always easy to overcome.</p><P CLASS="para">
+Now that the files have been compiled, you can install them into the directories you identified with the command:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>make install</b></code></pre><P CLASS="para">
+If you happen to be upgrading, your old Samba files will be saved with the extension <EM CLASS="emphasis">
+ .old</em>, and you can go back to that previous version with the command <CODE CLASS="literal">
+make</code> <CODE CLASS="literal">
+revert</code>. After doing a <CODE CLASS="literal">
+make</code> <CODE CLASS="literal">
+install</code>, you should copy the <EM CLASS="emphasis">
+.old </em>files (if they exist) to a new location or name. Otherwise, the next time you install Samba, the original <EM CLASS="emphasis">
+.old</em> will be overwritten without warning and you could lose your earlier version. If you configured Samba to use the default locations for files, the new files will be installed in the directories listed in <A CLASS="xref" HREF="ch02_03.html#ch02-pgfId-939627">
+Table 2.2</a>. Remember that you need to perform the installation from an account that has write privileges on these target directories; this is typically the root account. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch02-pgfId-939627">
+Table 2.2: Samba Installation Directories </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Directory</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Main tree</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/bin</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Binaries</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/lib</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+smb.conf</em>, <EM CLASS="emphasis">
+lmhosts</em>, configuration files, etc.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/man</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba documentation</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/private</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba encrypted password file</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/swat</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SWAT files</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+/usr/local/samba/var</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba log files, lock files, browse list info, shared memory files, process ID files</p></td></tr></tbody></table><P CLASS="para">
+Throughout the remainder of the book, we occasionally refer to the location of the main tree as <CODE CLASS="replaceable">
+<I>
+samba_dir</i></code>. In most configurations, this is the base directory of the installed Samba package: <I CLASS="filename">
+/usr/local/samba</i>.</p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Watch out if you've made <I CLASS="filename">
+/usr</i> a read-only partition. You will want to put the logs, locks, and password files somewhere else.</p></blockquote><P CLASS="para">
+Here is the installation that we performed on our machine. You can see that we used <I CLASS="filename">
+/usr/local/samba</i> as the base directory for the distribution (e.g., <CODE CLASS="replaceable">
+<I>
+samba_dir</i></code>):</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>make install</b></code>
+Using FLAGS = -O -Iinclude -I./include -I./ubiqx -I./smbwrapper -DSMBLOGFILE=&quot;/usr/local/samba/var/log.smb&quot; -DNMBLOGFILE=&quot;/usr/local/samba/var/log.nmb&quot; -DCONFIGFILE=&quot;/usr/local/samba/lib/smb.conf&quot; -
+
+<I CLASS="lineannotation">...(content omitted)...</i>
+
+The binaries are installed. You may restore the old binaries
+(if there were any) using the command &quot;make revert&quot;. You may
+uninstall the binaries using the command &quot;make uninstallbin&quot;
+or &quot;make uninstall&quot; to uninstall binaries, man pages and shell
+scripts.
+
+<I CLASS="lineannotation">...(content omitted)...</i>
+
+============================================================
+The SWAT files have been installed. Remember to read the
+README for information on enabling and using SWAT.
+============================================================</pre><P CLASS="para">
+If the last message is about SWAT, you've successfully installed all the files. Congratulations! You now have Samba on your system!</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-943188">
+2.3.1 Final Installation Steps</a></h3><P CLASS="para">There are a couple of final steps to perform. Specifically, add the Samba Web Administration Tool (SWAT) to the <I CLASS="filename">
+/etc/services</i> and <I CLASS="filename">
+/etc/inetd.conf</i> configuration files. SWAT runs as a daemon under <EM CLASS="emphasis">
+inetd</em> and provides a forms-based editor in your web browser for creating and modifying SMB configuration files.</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-943198">
+</a>To add SWAT, add the following line to the end of the <I CLASS="filename">
+/etc/services</i> file:</p></li></ol><PRE CLASS="programlisting">
+swat 901/tcp</pre><OL CLASS="orderedlist" START="2">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-938792">
+</a>Add these lines to <I CLASS="filename">
+/etc/inetd.conf.</i> (Check your <I CLASS="filename">
+inetd.conf</i> manual page to see the exact format of the<I CLASS="filename">
+ inetd.conf</i> file if it differs from the following example.) Don't forget to change the path to the SWAT binary if you installed it in a different location from the default <I CLASS="filename">
+/usr/local/samba</i>.</p></li></ol><PRE CLASS="programlisting">
+swat stream tcp nowait.400 root /usr/local/samba/bin/swat swat</pre><P CLASS="para">
+And that's pretty much it for the installation. Before you can start up Samba, however, you need to create a configuration file for it. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_02.html" TITLE="2.2 Configuring Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.2 Configuring Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_04.html" TITLE="2.4 A Basic Samba Configuration File">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.4 A Basic Samba Configuration File" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.2 Configuring Samba</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2.4 A Basic Samba Configuration File</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_04.html b/docs/htmldocs/using_samba/ch02_04.html
new file mode 100755
index 00000000000..608a1e2c40b
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_04.html
@@ -0,0 +1,186 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] 2.4 A Basic Samba Configuration File</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:10Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_03.html" TITLE="2.3 Compiling and Installing Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.3 Compiling and Installing Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+Chapter 2<br>
+Installing Samba on a Unix System</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_05.html" TITLE="2.5 Starting the Samba Daemons">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.5 Starting the Samba Daemons" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch02-13464">
+2.4 A Basic Samba Configuration File</a></h2><P CLASS="para">
+The key to configuring Samba is its lone configuration file: <I CLASS="filename">
+smb.conf</i>. This configuration file can be very simple or extremely complex, and the rest of this book is devoted to helping you get deeply personal with this file. For now, however, we'll show you how to set up a single file service, which will allow you to fire up the Samba daemons and see that everything is running as it should be. In later chapters, you will see how to configure Samba for more complicated and interesting tasks. </p><P CLASS="para">
+The installation process does not automatically create an <I CLASS="filename">
+smb.conf</i> configuration file, although several example files are included in the Samba distribution. To test the server software, though, we'll use the following file. It should be named <I CLASS="filename">
+smb.conf</i> and placed in the <EM CLASS="emphasis">
+/usr/local/samba/lib</em> directory.[<A CLASS="footnote" HREF="#ch02-pgfId-943223">5</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch02-pgfId-943223">[5]</a> If you did not compile Samba, but instead downloaded a binary, check with the documentation for the package to find out where it expects the <I CLASS="filename">
+smb.conf</i> file. If Samba came preinstalled with your Unix system, there is probably already an <I CLASS="filename">
+smb.conf</i> file somewhere on your system.</p></div></blockquote><PRE CLASS="programlisting">
+[global]
+ workgroup = SIMPLE
+[test]
+ comment = For testing only, please
+ path = /export/samba/test
+ read only = no
+ guest ok = yes</pre><P CLASS="para">
+This brief configuration file tells the Samba server to offer the directory <I CLASS="filename">
+/export/samba/test</i> on the server as an SMB/CIFS share called <CODE CLASS="literal">test</code>. The server also becomes part of the named workgroup SIMPLE, which each of the clients must also be a part of. (Use your own workgroup here if you already know what it is.) We'll use the <CODE CLASS="literal">
+[test]</code> share in the next chapter to set up the Windows clients. For now, you can complete the setup by performing the following commands as root on your Unix server:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>mkdir /export/samba/test</b></code>
+# <CODE CLASS="userinput"><B>chmod 777 /export/samba/test</b></code></pre><P CLASS="para">
+We should point out that in terms of system security, this is the worst setup possible. For the moment, however, we only wish to test Samba, so we'll leave security out of the picture. In addition, there are some encrypted password issues that we will encounter with Windows clients later on, so this setup will afford us the least amount of headaches.</p><P CLASS="para">
+If you are using Windows 98 or Windows NT Service Pack 3 or above, you must add the following entry to the <CODE CLASS="literal">
+[global]</code> section of the Samba configuration file: <CODE CLASS="literal">
+encrypt passwords = yes</code>. In addition, you must use the <I CLASS="filename">
+smbpassword</i> program (typically located in <I CLASS="filename">
+/usr/local/samba/bin/</i>) to reenter the username/password combinations of those users on the Unix server who should be able to access shares into Samba's encrypted client database. For example, if you wanted to allow Unix user <CODE CLASS="literal">
+steve</code> to access shares from an SMB client, you could type: <CODE CLASS="literal">
+smbpassword -a steve</code>. The first time a user is added, the program will output an error saying that the encrypted password database does not exist. Don't worry, it will then create the database for you. Make sure that the username/password combinations that you add to the encrypted database match the usernames and passwords that you intend to use on the Windows client side.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-942383">
+2.4.1 Using SWAT</a></h3><P CLASS="para">With Samba 2.0, creating a configuration file is even easier than writing a configuration file by hand. You can use your browser to connect to <a href="http://localhost:901"><EM CLASS="emphasis">http://localhost:901</em></a>, and log on as the root account, as shown in <A CLASS="xref" HREF="ch02_04.html#ch02-60915">
+Figure 2.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch02-60915">
+Figure 2.1: SWAT login</a></h4><IMG CLASS="graphic" SRC="figs/sam.0201.gif" ALT="Figure 2.1"><P CLASS="para">
+After logging in, press the GLOBALS button at the top of the screen. You should see the Global Variables page shown in <A CLASS="xref" HREF="ch02_04.html#ch02-49138">
+Figure 2.2</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch02-49138">
+Figure 2.2: SWAT Global Variables page</a></h4><IMG CLASS="graphic" SRC="figs/sam.0202.gif" ALT="Figure 2.2"><P CLASS="para">
+In this example, set the workgroup field to SIMPLE and the security field to USER. The only other option you need to change from the menu is one determining which system on the LAN resolves NetBIOS addresses; this system is called the <EM CLASS="emphasis">
+WINS server</em>. At the very bottom of the page, set the wins support field to Yes, unless you already have a WINS server on your network. If you do, put the WINS server's IP address in the wins server field instead. Then return to the top and press the Commit Changes button to write the changes out to the <EM CLASS="emphasis">
+smb.conf</em> file. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch02-29175">
+Figure 2.3: SWAT Share Creation screen</a></h4><IMG CLASS="graphic" SRC="figs/sam.0203.gif" ALT="Figure 2.3"><P CLASS="para">
+Next, press the Shares icon. You should see a page similar to <A CLASS="xref" HREF="ch02_04.html#ch02-29175">
+Figure 2.3</a>. Choose Test in the field beside the Choose Share button. You will see the Share Parameters screen, as shown in <A CLASS="xref" HREF="ch02_04.html#ch02-37186">
+Figure 2.4</a>. We added a comment to remind us that this is a test share in the <I CLASS="filename">
+smb.conf</i> file. SWAT has copies of all that information here.</p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch02-37186">
+Figure 2.4: SWAT Share Parameters screen</a></h4><IMG CLASS="graphic" SRC="figs/sam.0204.gif" ALT="Figure 2.4"><P CLASS="para">
+If you press the View button, SWAT shows you the following <I CLASS="filename">
+smb.conf</i> file:</p><PRE CLASS="programlisting">
+# Samba config file created using SWAT
+# from localhost (127.0.0.1)
+# Date: 1998/11/27 15:42:40
+
+# Global parameters
+ workgroup = SIMPLE
+[test]
+ comment = For testing only, please
+ path = /export/samba/test
+ read only = no
+ guest ok = yes</pre><P CLASS="para">
+Once this configuration file is completed, you can skip the next step because the output of SWAT is guaranteed to be syntactically correct. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-938862">
+2.4.2 Testing the Configuration File</a></h3><P CLASS="para">If you didn't use SWAT to create your configuration file, you should probably test it to ensure that it is syntactically correct. It may seem silly to run a test program against an eight-line configuration file, but it's good practice for the real ones that we'll be writing later on.</p><P CLASS="para">
+The test parser, <I CLASS="filename">
+testparm</i>, examines an <I CLASS="filename">
+smb.conf</i> file for syntax errors and reports any it finds along with a list of the services enabled on your machine. An example follows; you'll notice that in our haste to get the server running we mistyped <CODE CLASS="literal">
+workgroup</code> as <CODE CLASS="literal">
+workgrp</code> (the output is often lengthy, so we recommend capturing the last parts with the <CODE CLASS="literal">
+tee</code> command):</p><PRE CLASS="programlisting">
+Load smb config files from smb.conf
+Unknown parameter encountered: &quot;workgrp&quot;
+Ignoring unknown parameter &quot;workgrp&quot;
+Processing section &quot;[test]&quot;
+Loaded services file OK.
+Press enter to see a dump of your service definitions
+# Global parameters
+[global]
+ workgroup = WORKGROUP
+ netbios name =
+ netbios aliases =
+ server string = Samba 2.0.5a
+ interfaces =
+ bind interfaces only = No
+
+<I CLASS="lineannotation">...(content omitted)...</i>
+
+[test]
+ comment = For testing only, please
+ path = /export/samba/test
+ read only = No
+ guest ok = Yes</pre><P CLASS="para">
+The interesting parts are at the top and bottom. The top of the output will flag any syntax errors that you may have made, and the bottom lists the services that the server thinks it should offer. A word of advice: make sure that you and the server have the same expectations. </p><P CLASS="para">
+If everything looks good, then you are ready to fire up the server daemons! </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_03.html" TITLE="2.3 Compiling and Installing Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.3 Compiling and Installing Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_05.html" TITLE="2.5 Starting the Samba Daemons">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.5 Starting the Samba Daemons" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.3 Compiling and Installing Samba</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2.5 Starting the Samba Daemons</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_05.html b/docs/htmldocs/using_samba/ch02_05.html
new file mode 100755
index 00000000000..95d506e5e96
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_05.html
@@ -0,0 +1,195 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] 2.5 Starting the Samba Daemons</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:11Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_04.html" TITLE="2.4 A Basic Samba Configuration File">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.4 A Basic Samba Configuration File" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+Chapter 2<br>
+Installing Samba on a Unix System</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_06.html" TITLE="2.6 Testing the Samba Daemons">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.6 Testing the Samba Daemons" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch02-29069">
+2.5 Starting the Samba Daemons</a></h2><P CLASS="para">
+There are two Samba processes, <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em>, that need to be running for Samba to work correctly. There are three ways to start:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-943268">
+</a>By hand</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-943266">
+</a>As stand-alone daemons</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch02-pgfId-947794">
+</a>From <EM CLASS="emphasis">
+inetd</em></p></li></ul><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-938883">
+2.5.1 Starting the Daemons by Hand</a></h3><P CLASS="para">
+If you're in a hurry, you can start the Samba daemons by hand. As root, simply enter the following commands:</p><PRE CLASS="programlisting">
+#<CODE CLASS="userinput"> <B>/usr/local/samba/bin/smbd -D</b></code>
+#<CODE CLASS="userinput"> <B>/usr/local/samba/bin/nmbd -D</b></code></pre><P CLASS="para">
+At this point, Samba will be running on your system and will be ready to accept connections.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-943275">
+2.5.2 Stand-alone Daemons</a></h3><P CLASS="para">
+To run the Samba processes as stand-alone daemons, you need to add the commands listed in the previous section to your standard Unix startup scripts. This varies depending on whether you have a BSD-style Unix system or a System V Unix.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch02-pgfId-947593">
+2.5.2.1 BSD Unix</a></h4><P CLASS="para">
+WIth a BSD-style Unix, you need to append the following code to the <I CLASS="filename">
+rc.local </i>file, which is typically found in the <I CLASS="filename">
+/etc</i> or <I CLASS="filename">
+/etc/rc.d</i> directories:</p><PRE CLASS="programlisting">
+if [ -x /usr/local/samba/bin/smbd]; then
+ echo &quot;Starting smbd...&quot;
+ /usr/local/samba/bin/smbd -D
+ echo &quot;Starting nmbd...&quot;
+ /usr/local/samba/bin/nmbd -D
+fi</pre><P CLASS="para">
+This code is very simple; it checks to see if the <I CLASS="filename">
+smbd</i> file has execute permissions on it, and if it does, it starts up each of the Samba daemons on system boot.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch02-pgfId-943333">
+2.5.2.2 System V Unix</a></h4><P CLASS="para">
+With System V, things can get a little more complex. System V typically uses scripts to start and stop daemons on the system. Hence, you need to instruct Samba how to operate when it starts and when it stops. You can modify the contents of the <I CLASS="filename">
+/etc/rc.local</i> directory and add something similar to the following program entitled <I CLASS="filename">
+smb</i>:</p><PRE CLASS="programlisting">
+#!/bin/sh
+
+# Contains the &quot;killproc&quot; function on Red Hat Linux
+./etc/rc.d/init.d/functions
+
+PATH=&quot;/usr/local/samba/bin:$PATH&quot;
+
+case $1 in
+ 'start')
+ echo &quot;Starting smbd...&quot;
+ smbd -D
+ echo &quot;Starting nmbd...&quot;
+ nmbd -D
+ ;;
+ 'stop')
+ echo &quot;Stopping smbd and nmbd...&quot;
+ killproc smbd
+ killproc nmbd
+ rm -f /usr/local/samba/var/locks/smbd.pid
+ rm -f /usr/local/samba/var/locks/nmbd.pid
+ ;;
+ *)
+ echo &quot;usage: smb {start|stop}&quot;
+ ;;
+esac</pre><P CLASS="para">
+With this script, you can start and stop the SMB service with the following commands:</p><PRE CLASS="programlisting">
+# /etc/rc.local/smb start
+Starting smbd...
+Starting nmbd...
+# /etc/rc.local/smb stop
+Stopping smbd and nmbd...</pre></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch02-pgfId-943302">
+2.5.3 Starting From Inetd</a></h3><P CLASS="para">
+The <EM CLASS="emphasis">
+inetd</em> daemon is a Unix system's Internet "super daemon." It listens on TCP ports defined in <I CLASS="filename">
+/etc/services</i> and executes the appropriate program for each port, which is defined in <I CLASS="filename">
+/etc/inetd.conf</i>. The advantage of this scheme is that you can have a large number of daemons ready to answer queries, but they don't all have to be running. Instead, the <EM CLASS="emphasis">
+inetd</em> daemon listens in places of all the others. The penalty is a small overhead cost of creating a new daemon process, and the fact that you need to edit two files rather than one to set things up. This is handy if you have only one or two users or your machine has too many daemons already. It's also easier to perform an upgrade without disturbing an existing connection.</p><P CLASS="para">
+If you wish to start from <I CLASS="filename">
+inetd</i>, first open <I CLASS="filename">
+/etc/services</i> in your text editor. If you don't already have them defined, add the following two lines:</p><PRE CLASS="programlisting">
+netbios-ssn 139/tcp
+netbios-ns 137/udp</pre><P CLASS="para">
+Next, edit <I CLASS="filename">
+/etc/inetd.conf</i>. Look for the following two lines and add them if they don't exist. If you already have <CODE CLASS="literal">
+smbd</code> and <CODE CLASS="literal">
+nmbd</code> lines in the file, edit them to point at the new <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em> you've installed. Your brand of Unix may use a slightly different syntax in this file; use the existing entries and the <I CLASS="filename">
+inetd.conf </i><KBD CLASS="command"></kbd>manual page <KBD CLASS="command"></kbd>as a guide:</p><PRE CLASS="programlisting">
+netbios-ssn stream tcp nowait root /usr/local/samba/bin/smbd smbd
+netbios-ns dgram udp wait root /usr/local/samba/bin/nmbd nmbd</pre><P CLASS="para">
+Finally, kill any <EM CLASS="emphasis">
+smbd</em> or <EM CLASS="emphasis">
+nmbd</em> processes and send the <EM CLASS="emphasis">
+inetd</em> process a hangup (HUP) signal. (The <EM CLASS="emphasis">
+inetd</em> daemon rereads its configuration file on a HUP signal.) To do this, use the <CODE CLASS="literal">
+ps</code> command to find its process ID, then signal it with the following command:</p><PRE CLASS="programlisting">
+# <CODE CLASS="userinput"><B>kill -HUP process_id</b></code></pre><P CLASS="para">
+After that, Samba should be up and running. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_04.html" TITLE="2.4 A Basic Samba Configuration File">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.4 A Basic Samba Configuration File" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_06.html" TITLE="2.6 Testing the Samba Daemons">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 2.6 Testing the Samba Daemons" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.4 A Basic Samba Configuration File</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+2.6 Testing the Samba Daemons</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch02_06.html b/docs/htmldocs/using_samba/ch02_06.html
new file mode 100755
index 00000000000..46adba5d3b6
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch02_06.html
@@ -0,0 +1,108 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 2] 2.6 Testing the Samba Daemons</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:29:12Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_05.html" TITLE="2.5 Starting the Samba Daemons">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.5 Starting the Samba Daemons" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch02_01.html" TITLE="2. Installing Samba on a Unix System">
+Chapter 2<br>
+Installing Samba on a Unix System</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch03_01.html" TITLE="3. Configuring Windows Clients">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3. Configuring Windows Clients" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch02-67898">
+2.6 Testing the Samba Daemons</a></h2><P CLASS="para">It's hard to believe, but we're nearly done with the Samba server setup. All that's left to do is to make sure that everything is working as we think it should. A convenient way to do this is to use the <I CLASS="filename"> smbclient</i> program to examine what the server is offering to the network. If everything is set up properly, you should be able to do the following:</p><PRE CLASS="programlisting">
+<CODE CLASS="userinput"><B># smbclient -U% -L localhost</b></code>
+
+Added interface ip=192.168.220.100 bcast=192.168.220.255 nmask=255.255.255.0
+Domain=[SIMPLE] OS=[Unix] Server=[Samba 2.0.5a]
+
+ Sharename Type Comment
+ --------- ---- -------
+ test Disk For testing only, please
+ IPC$ IPC IPC Service (Samba 2.0.5a)
+
+ Server Comment
+ --------- -------
+ HYDRA Samba 2.0.5a
+
+ Workgroup Master
+ --------- -------
+ SIMPLE HYDRA</pre><P CLASS="para">
+If there is a problem, don't panic! Try to start the daemons manually, and check the system output or the debug files at <I CLASS="filename">
+/usr/local/samba/var/log.smb</i> to see if you can determine what happened. If you think it may be a more serious problem, skip to <a href="ch07_01.html"><b>Chapter 7, <CITE CLASS="chapter"> Printing and Name Resolution</cite></b></a>, for help on troubleshooting the Samba daemons. </p><P CLASS="para">
+If it worked, congratulations! You now have successfully set up the Samba server with a disk share. It's a simple one, but we can use it to set up and test the Windows 95 and NT clients in the next chapter. Then we will start making it more interesting by adding services such as home directories, printers, and security, and seeing how to integrate the server into a larger Windows domain. </p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_05.html" TITLE="2.5 Starting the Samba Daemons">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.5 Starting the Samba Daemons" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch03_01.html" TITLE="3. Configuring Windows Clients">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3. Configuring Windows Clients" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.5 Starting the Samba Daemons</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+3. Configuring Windows Clients</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch03_01.html b/docs/htmldocs/using_samba/ch03_01.html
new file mode 100755
index 00000000000..915befad0f4
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch03_01.html
@@ -0,0 +1,277 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 3] Configuring Windows Clients</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:31:14Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_06.html" TITLE="2.6 Testing the Samba Daemons">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.6 Testing the Samba Daemons" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 3</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_02.html" TITLE="3.2 Setting Up Windows NT 4.0 Computers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3.2 Setting Up Windows NT 4.0 Computers" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch03-91548">
+3. Configuring Windows Clients</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch03-55770" TITLE="3.1 Setting Up Windows 95/98 Computers">
+Setting Up Windows 95/98 Computers</a><br>
+<A CLASS="sect1" HREF="ch03_02.html" TITLE="3.2 Setting Up Windows NT 4.0 Computers">
+Setting Up Windows NT 4.0 Computers</a><br>
+<A CLASS="sect1" HREF="ch03_03.html" TITLE="3.3 An Introduction to SMB/CIFS">
+An Introduction to SMB/CIFS</a></p><P>
+</p></div><P CLASS="para">You'll be glad to know that configuring Windows to use your new Samba server is quite simple. SMB is Microsoft's native language for resource sharing on a local area network, so much of the installation and setup on the Windows client side has been taken care of already. The primary issues that we will cover in this chapter involve communication and coordination between Windows and Unix, two completely different operating systems.</p><P CLASS="para">
+Samba uses TCP/IP to talk to its clients on the network. If you aren't already using TCP/IP on your Windows computers, this chapter will show you how to install it. Then you'll need to configure your Windows machines to operate on a TCP/IP network. Once these two requirements have been taken care of, we can show how to access a shared disk on the Samba server.</p><P CLASS="para">
+This chapter is divided into three sections. The first section covers setting up Windows 95/98 computers while the second covers Windows NT 4.0 machines. The final section provides some prerequisite information on how SMB connections are made from Windows clients and servers, which is useful as we move into the later chapters of the book.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch03-55770">
+3.1 Setting Up Windows 95/98 Computers</a></h2><P CLASS="para">Unfortunately, Windows 95/98 wasn't designed for a PC to have more than one user; that concept is more inherent to a Unix operating system or Windows NT. However, Windows 95/98 does have <EM CLASS="emphasis">
+limited</em> support for multiple users: if you tell it, the operating system will keep a separate profile (desktop layout) and password file for each user. This is a far cry from true multiuser security. In other words, Windows 95/98 won't try to keep one user from destroying the work of another on the local hard drive like Unix, but profiles are a place to start.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-941931">
+3.1.1 Accounts and Passwords</a></h3><P CLASS="para">The first thing we need to do is to tell Windows to keep user profiles separate, and to collect usernames and passwords to authenticate anyone trying to access a Samba share. We do so via the Password settings in the Control Panel. If you are not familiar with the Windows Control Panel, you can access it by choosing the Settings menu item from the pop-up menu of the Start button in the lower-left corner of the screen. Alternatively, you'll find it as a folder under the icon in the upper-left corner that represents your computer and is typically labeled My Computer.</p><P CLASS="para">
+After selecting the Passwords icon in the Control Panel, click on the User Profiles tab on the far right. You should see the dialog box shown in <A CLASS="xref" HREF="ch03_01.html#ch03-84319">
+Figure 3.1</a>. Then click the lower of the two radio buttons that starts "Users can customize their preferences...." This causes Windows to store a separate profile for each user, and saves the username and password you provide, which it will use later when it connects to an SMB/CIFS server. Finally, check <EM CLASS="emphasis">
+both</em> the options under the User Profile Settings border, as shown in the figure. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-84319">
+Figure 3.1: The Passwords Properties panel</a></h4><IMG CLASS="graphic" SRC="figs/sam.0301.gif" ALT="Figure 3.1"><P CLASS="para">
+The next step is to select the Change Passwords tab on the left side of the dialog box. In order for Samba to allow you access to its shares, the username and password you give to Windows must match the account and password on the Samba server. If you don't have this tab in your dialog box, don't worry; it's probably because you haven't given yourself a Windows username and password yet. Simply click the OK button at the bottom and respond Yes when Windows asks to reboot. Then, skip down to the section entitled <A CLASS="xref" HREF="ch03_01.html#ch03-57581">
+Section 3.1.1.2, Logging in for the first time</a>.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-941948">
+3.1.1.1 Changing the Windows password</a></h4><P CLASS="para">After selecting the Change Passwords tab, the dialog box in <A CLASS="xref" HREF="ch03_01.html#ch03-26778">
+Figure 3.2</a> will appear.</p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-26778">
+Figure 3.2: The Change Passwords tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0302.gif" ALT="Figure 3.2"><P CLASS="para">
+Select the Change Windows Password button. The Change Windows Password dialog box should appear, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-97002">
+Figure 3.3</a>. From here, you can change your password to match the password of the account on the Samba server through which you intend to log in. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-97002">
+Figure 3.3: The Change Windows Password dialog box</a></h4><IMG CLASS="graphic" SRC="figs/sam.0303.gif" ALT="Figure 3.3"></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-57581">
+3.1.1.2 Logging in for the first time</a></h4><P CLASS="para">If you didn't have a Change Passwords tab in the Passwords Properties window, then after Windows has finished rebooting, it will ask you to log in with a username and a password. Give yourself the same username and password that you have on the Samba server. After confirming your new username and password, or if you already have one, Windows should ask you if you want to have a profile, using the dialog shown in <A CLASS="xref" HREF="ch03_01.html#ch03-48947">
+Figure 3.4</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-48947">
+Figure 3.4: Windows Networking profiles</a></h4><IMG CLASS="graphic" SRC="figs/sam.0304.gif" ALT="Figure 3.4"><P CLASS="para">
+Answer Yes, upon which Windows will create a separate profile and password file for you and save a copy of your password in the file. Now when you connect to Samba, Windows will send its password, which will be used to authenticate you for each share. We won't worry about profiles for the moment; we'll cover them in <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a>. We should point out, however, that there is a small security risk: someone can steal the password file and decrypt the passwords because it's weakly encrypted. Unfortunately, there isn't a solution to this with Windows 95/98. In Windows 2000 (NT 5.0), the password encryption should be replaced with a much better algorithm.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-36280">
+3.1.2 Setting Up the Network</a></h3><P CLASS="para">The next thing we need to do is make sure we have the TCP/IP networking protocol set up correctly. To do this, double-click on the Network icon in the Control Panel. You should see the network configuration dialog box, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-15320">
+Figure 3.5</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-15320">
+Figure 3.5: The Windows 95/98 Network panel</a></h4><IMG CLASS="graphic" SRC="figs/sam.0305.gif" ALT="Figure 3.5"><P CLASS="para">
+Microsoft networking works by binding specific protocols, such as IPX or TCP/IP, to a specific hardware device, such as an Ethernet card or a dialup connection. By routing a protocol through a hardware device, the machine can act as a client or server for a particular type of network. For Samba, we are interested in binding the TCP/IP protocol through a networking device, making the machine a client for Microsoft networks. Thus, when the dialog box appears, you should see at least the Client for Microsoft Networks component installed on the machine, and hopefully a networking device (preferably an Ethernet card) bound to the TCP/IP protocol. If there is only one networking hardware device, you'll see the TCP/IP protocol listed below that device. If it appears similar to <A CLASS="xref" HREF="ch03_01.html#ch03-15320">
+Figure 3.5</a>, the protocol is bound to the device.</p><P CLASS="para">
+You may also see "File and printer sharing for Microsoft Networks," which is useful. In addition, you might see NetBEUI or Novell Networking, which are standard with Windows installations but undesirable when TCP/IP is running. Remove NetBEUI if you possibly can&nbsp;- it's unnecessary and makes debugging Windows browsing difficult. If you don't have any Novell servers on your network, you can remove Novell (IPX/SPX) as well.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942014">
+3.1.2.1 Adding TCP/IP</a></h4><P CLASS="para">If you don't see TCP/IP listed at all, you'll need to install the protocol. If you already have TCP/IP, skip this section, and continue with the section <A CLASS="xref" HREF="ch03_01.html#ch03-48802">
+Section 3.1.3, Setting Your Name and Workgroup</a>, later in this chapter.</p><P CLASS="para">
+Installing TCP/IP isn't difficult since Microsoft distributes its own version of TCP/IP for free on their installation CD-ROM. You can add the protocol by clicking on the Add button below the component window. Indicate that you wish to add a specific protocol by selecting Protocol and clicking Add... on the following dialog box, which should look similar to <A CLASS="xref" HREF="ch03_01.html#ch03-24245">
+Figure 3.6</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-24245">
+Figure 3.6: Selecting a protocol to install</a></h4><IMG CLASS="graphic" SRC="figs/sam.0306.gif" ALT="Figure 3.6"><P CLASS="para">
+After that, select the protocol TCP/IP from manufacturer Microsoft, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-50801">
+Figure 3.7</a>, then click OK. After doing so, you will be returned to the network dialog. Click OK there to close the dialog box, upon which Windows will install the necessary components from disk and reboot the machine. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-50801">
+Figure 3.7: Selecting a protocol to install</a></h4><IMG CLASS="graphic" SRC="figs/sam.0307.gif" ALT="Figure 3.7"></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942047">
+3.1.2.2 Configuring TCP/IP</a></h4><P CLASS="para">If you have more than one networking device (for example, both an Ethernet card and a dialup networking modem), each appropriate hardware device should be "linked" to the TCP/IP protocol with an arrow, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-61576">
+Figure 3.8</a>. Select the TCP/IP protocol linked to the networking device that will be accessing the Samba network. When it is highlighted, click the Properties button. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-61576">
+Figure 3.8: Selecting the correct TCP/IP protocol</a></h4><IMG CLASS="graphic" SRC="figs/sam.0308.gif" ALT="Figure 3.8"><P CLASS="para">
+After doing so, the TCP/IP Properties panel for that device is displayed, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-73526">
+Figure 3.9</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-73526">
+Figure 3.9: STCP/IP Properties panel</a></h4><IMG CLASS="graphic" SRC="figs/sam.0309.gif" ALT="Figure 3.9"><P CLASS="para">
+There are seven tabs near the top of this panel, and you will need to configure four of them: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942078">
+</a>IP address</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942079">
+</a>DNS configuration</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942080">
+</a>WINS configuration</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942081">
+</a>Bindings</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-948031">
+3.1.2.3 IP Address tab </a></h4><P CLASS="para">
+The IP Address tab is shown in <A CLASS="xref" HREF="ch03_01.html#ch03-73526">
+Figure 3.9</a>. Press the "Specify an IP address" radio button and enter the client's address and subnet mask in the space provided. You or your network manager should have selected an address for the machine. The values should place the computer on the same subnet as the Samba server. For example, if the server's address is 192.168.236.86, and its network mask 255.255.255.0, you might use address 192.168.236.10 (if it is available) for the Windows 98 computer, along with the same netmask as the server. If you already use DHCP on your network to provide IP addresses to Windows machines, select the "Obtain an IP address automatically" button.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942087">
+3.1.2.4 DNS Configuration tab</a></h4><P CLASS="para">Domain Name Service (DNS) is responsible for translating Internet computer names such as <EM CLASS="emphasis">
+hobbes.example.com</em> into machine-readable IP addresses such as 192.168.236.10. There are two ways to accomplish this on a Windows 98 machine: you can specify a server to do the translation for you or you can keep a local list of name/address pairs to refer to. </p><P CLASS="para">
+Networks that are connected to the Internet typically use a server, since the hosts files required would otherwise be huge. For an unconnected LAN, the list of possible hosts is small and well-known and might be kept on a Unix machine in the <EM CLASS="emphasis">
+/etc/hosts</em> file. If you are in doubt as to whether a DNS server is being used, or what its address might be, look at the file <EM CLASS="emphasis">
+/etc/resolv.conf</em> on your Unix servers. Any machine using DNS will have this file, which looks like:</p><PRE CLASS="programlisting">
+#resolv.conf
+domain example.com
+nameserver 127.0.0.1
+nameserver 192.168.236.20</pre><P CLASS="para">
+In the example shown, the second <CODE CLASS="literal">
+nameserver</code> line in the list contains the IP address of another machine on the local network: 192.168.236.20. It's a good candidate for a DNS server.[<A CLASS="footnote" HREF="#ch03-pgfId-942097">1</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch03-pgfId-942097">[1]</a> We can disqualify the other address because every Unix machine has a localhost address of 127.0.0.1 whether it is connected to a network or not. This address is required for some system tools to operate correctly.</p></div></blockquote><P CLASS="para">
+You must type the correct IP address of one or more DNS servers (note that you <EM CLASS="emphasis">
+cannot</em> use its Internet name, such as <EM CLASS="emphasis">
+dns.oreilly.com</em>) into the appropriate field in <A CLASS="xref" HREF="ch03_01.html#ch03-86883">
+Figure 3.10</a>. Be sure not to use 127.0.0.1&nbsp;- that will never be the correct DNS server address!</p><P CLASS="para">
+Try to select addresses on your own network. Any name servers listed in <EM CLASS="emphasis">
+/etc/resolv.conf</em> should work, but you'll get better performance by using a server nearby. (If you don't find <EM CLASS="emphasis">
+/etc/resolv.conf</em> files on your Unix machines, just disable DNS until you can find the address of at least one DNS server.) Let's assume you only have one DNS server, and its address is 192.168.236.20. Click the Enable DNS radio button, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-86883">
+Figure 3.10</a>, and add the server's address to the top DNS Server Search Order field. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-86883">
+Figure 3.10: The DNS Configuration tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0310.gif" ALT="Figure 3.10"><P CLASS="para">
+Also, provide the name of the Windows 95/98 machine and the Internet domain you're in. You can safely ignore the Domain Suffix Search Order field for anything related to Samba.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942117">
+3.1.2.5 WINS Configuration tab</a></h4><P CLASS="para">WINS is the Windows Internet Name Service, its version of a NetBIOS name server. If you've enabled WINS on Samba, you must tell Windows the Samba server's address. If you are using WINS servers that are entirely Windows NT, enter each of them here as well. The dialog box shown after selecting the WINS Configuration tab is shown in <A CLASS="xref" HREF="ch03_01.html#ch03-95608">
+Figure 3.11</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-95608">
+Figure 3.11: The WINS Configuration tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0311.gif" ALT="Figure 3.11"><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Do <EM CLASS="emphasis">
+not</em> mix a Samba WINS server and a Windows NT server as a primary/backup combination in the WINS dialog. Because the two cannot replicate their databases, this will cause name resolution to perform incorrectly.</p></blockquote><P CLASS="para">
+From here, select Enable WINS Resolution and enter the WINS server's address in the space provided, then press Add. Do not enter anything in the Scope ID field.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942134">
+3.1.2.6 Hosts files</a></h4><P CLASS="para">If you do not have either DNS or WINS, and you don't wish to use broadcast resolution, you'll need to provide a table of IP addresses and hostnames, in the standard Unix <I CLASS="filename">
+/etc/hosts</i> format. On a Windows machine, this goes in \WINDOWS\HOSTS under whichever drive you installed Windows on (typically C:\). A sample host file follows:</p><PRE CLASS="programlisting">
+# 127.0.0.1 localhost
+192.168.236.1 escrime.example.com escrime
+192.168.236.2 riposte.example.com riposte
+192.168.236.3 wizzin.example.com wizzin
+192.168.236.4 touche.example.com touche
+192.168.236.10 hobbes.example.com hobbes</pre><P CLASS="para">
+You can copy this file directly from any of your Unix machines' <EM CLASS="emphasis">
+/etc/hosts</em>; the format is identical. However, <EM CLASS="emphasis">
+you should only use hosts files in Windows as a last resort for name resolution</em>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942143">
+3.1.2.7 Check the bindings</a></h4><P CLASS="para">
+The final tab to look at is Bindings, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-42906">
+Figure 3.12</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-42906">
+Figure 3.12: The Bindings tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0312.gif" ALT="Figure 3.12"><P CLASS="para">
+You should have a check beside Client for Microsoft Networks, indicating that it's using TCP/IP. If you have "File and printer sharing for Microsoft Networks" in the dialog, it should also be checked, as shown in the figure. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-48802">
+3.1.3 Setting Your Name and Workgroup </a></h3><P CLASS="para">Finally, press the OK button in the TCP/IP configuration panel, and you'll be taken back to the Network Configuration screen. Then select the Identification tab, which will take you to the dialog box shown in <A CLASS="xref" HREF="ch03_01.html#ch03-42408">
+Figure 3.13</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-42408">
+Figure 3.13: The Identification tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0313.gif" ALT="Figure 3.13"><P CLASS="para">
+Here, for the second time, set your machine's name. This time, instead of your DNS hostname and domain, you're setting your NetBIOS name. However, it is best to make this the <EM CLASS="emphasis">
+same</em> as your hostname. Try not to make a spelling mistake: it can be very confusing to configure a machine if TCP thinks it's <CODE CLASS="literal">
+fred</code> and SMB thinks its <CODE CLASS="literal">
+ferd</code> !</p><P CLASS="para">
+You also set your workgroup name here. In our case, it's SIMPLE, but if you used a different one in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>, when creating the Samba configuration file, use that here as well. Try to avoid calling it WORKGROUP or you'll be in the same workgroup as every unconfigured (or ill-configured) machine in the world. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-13238">
+3.1.4 Accessing the Samba Server</a></h3><P CLASS="para">Click on the OK button to complete the configuration; you will need to reboot in order for your changes to take effect. </p><P CLASS="para">
+Now for the big moment. Your Samba server is running, and you have set up your Windows 95/98 client to communicate with it. After rebooting, log in and double-click the Network Neighborhood icon on the desktop. You should see your Samba server listed as a member of the workgroup, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-88553">
+Figure 3.14</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-88553">
+Figure 3.14: Windows Network Neighborhood</a></h4><IMG CLASS="graphic" SRC="figs/sam.0314.gif" ALT="Figure 3.14"><P CLASS="para">
+Double-clicking the server name will show the resources that the server is offering to the network, as shown in <A CLASS="xref" HREF="ch03_01.html#ch03-17463">
+Figure 3.15</a> (in this case a printer and the <EM CLASS="emphasis">
+test </em>directory). </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-17463">
+Figure 3.15: Shares on Server</a></h4><IMG CLASS="graphic" SRC="figs/sam.0315.gif" ALT="Figure 3.15"><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> If you are presented with a dialog requesting the password for a user <CODE CLASS="literal">
+IPC$</code>, then Samba did not accept the password that was sent from the client. In this case, the username and the password that were created on the client side <EM CLASS="emphasis">
+must</em> match the username/password combination on the Samba server. If you are using Windows 98 or Windows NT Service Pack 3 or above, this is probably because the client is sending encrypted passwords instead of plaintext passwords. You can remedy this situation by performing two steps on the Samba server. First, add the following entry to the <CODE CLASS="literal">
+[global]</code> section of your Samba configuration file: <CODE CLASS="literal">
+encrypt password=yes</code>. Second, find the <I CLASS="filename">
+smbpasswd</i> program on the samba server (it is located in <I CLASS="filename">
+/usr/local/samba/bin</i> by default) and use it to add an entry to Samba's encrypted password database. For example, to add user <CODE CLASS="literal">
+steve</code> to Samba's encrypted password database, type <CODE CLASS="replaceable">
+<I>
+smbpasswd -a steve</i></code>. The first time you enter this password, the program will output an error message indicating that the password database does not exist; it will then create the database, which is typically stored in <I CLASS="filename">
+/usr/local/samba/private/smbpasswd</i>.</p></blockquote><P CLASS="para">
+If you don't see the server listed, start Windows Explorer (not Internet Explorer!) and select Map Network Drive from the Tools menu. This will give you a dialog box into which you can type the name of your server and the share <CODE CLASS="literal">
+test </code>in the Windows UNC format: <I CLASS="filename">\\</i><CODE CLASS="replaceable"><I>server</i></code><I CLASS="filename">\test</i>, like we did in the first chapter. This should attempt to contact the Samba server and its temporary share. If things still aren't right, go to <a href="ch09_01.html"><b>Chapter 9, <CITE CLASS="chapter">Troubleshooting Samba</cite></b></a>, for troubleshooting assistance. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch02_06.html" TITLE="2.6 Testing the Samba Daemons">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 2.6 Testing the Samba Daemons" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_02.html" TITLE="3.2 Setting Up Windows NT 4.0 Computers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3.2 Setting Up Windows NT 4.0 Computers" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+2.6 Testing the Samba Daemons</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+3.2 Setting Up Windows NT 4.0 Computers</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch03_02.html b/docs/htmldocs/using_samba/ch03_02.html
new file mode 100755
index 00000000000..fd87daac726
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch03_02.html
@@ -0,0 +1,260 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 3] 3.2 Setting Up Windows NT 4.0 Computers</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:31:26Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_01.html" TITLE="3.1 Setting Up Windows 95/98 Computers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.1 Setting Up Windows 95/98 Computers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch03_01.html" TITLE="3. Configuring Windows Clients">
+Chapter 3<br>
+Configuring Windows Clients</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_03.html" TITLE="3.3 An Introduction to SMB/CIFS">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3.3 An Introduction to SMB/CIFS" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch03-23093">
+3.2 Setting Up Windows NT 4.0 Computers</a></h2><P CLASS="para">Configuring Windows NT is a little different than configuring Windows 95/98. In order to use Samba with Windows NT, you will need both the Workstation service and the TCP/IP protocol. Both come standard with NT, but we'll work through installing and configuring them because they may not be configured correctly.</p><P CLASS="para">
+There are six basic steps:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942212">
+</a>Assign the machine a name.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942213">
+</a>Install the Workstation service.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942214">
+</a>Install the TCP/IP protocol.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942215">
+</a>Set the machine's name and IP address.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-948102">
+</a>Configure the DNS and WINS name services.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-948103">
+</a>Bind the protocol and service together.</p></li></ol><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-948104">
+3.2.1 Basic Configuration</a></h3><P CLASS="para">This section presents an outline of the steps to follow for getting Windows NT to cooperate with Samba. If you need more details on Windows NT network administration, refer to Craig Hunt and Robert Bruce Thompsom's <CITE CLASS="citetitle">
+Windows NT TCP/IP Network Administration </cite>(O'Reilly), an excellent guide. You should perform these steps as the "Administrator" user.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942220">
+3.2.1.1 Name the machine</a></h4><P CLASS="para">The first thing you need to do is to give the machine a NetBIOS name. From the Control Panel, double click on the Network icon. This will take you to the Network dialog box for the machine. The first tab in this dialog box should be the Identification tab, as illustrated in <A CLASS="xref" HREF="ch03_02.html#ch03-82592">
+Figure 3.16</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-82592">
+Figure 3.16: Network panel Identification tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0316.gif" ALT="Figure 3.16"><P CLASS="para">
+Here, you need to identify your machine with a name (we use the name Artish here) and change the default workgroup to the one you specified in the <EM CLASS="emphasis">
+smb.conf</em> file of your Samba server. In this case, the workgroup name is SIMPLE. However, you cannot edit either name here (as you could in Windows 95/98), but instead must use the Change button below the two text fields. Pressing this button raises an Identification Changes dialog box, where you can reset the workgroup and the machine name, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-67735">
+Figure 3.17</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-67735">
+Figure 3.17: Changing the identification</a></h4><IMG CLASS="graphic" SRC="figs/sam.0317.gif" ALT="Figure 3.17"><P CLASS="para">A word of warning: you will have to set the machine name again later while configuring TCP/IP, so be sure that the two names match. The name you set here is the NetBIOS name. You're allowed to make it different from the TCP/IP hostname, but doing so is usually not a good thing. Don't worry that Windows NT forces the computer name and the workgroup to be all capital letters; it's smart enough to figure out what you mean when it connects to the network.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942248">
+3.2.1.2 Installing the TCP/IP protocol</a></h4><P CLASS="para">Next, select the Protocols tab in the Network dialog box, and look to see if you have the TCP/IP protocol installed, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-66055">
+Figure 3.18</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-66055">
+Figure 3.18: The Protocols tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0318.gif" ALT="Figure 3.18"><P CLASS="para">
+If the protocol is not installed, you need to add it. Press the Add button, which will display the Select Network Protocol dialog box shown in <A CLASS="xref" HREF="ch03_02.html#ch03-22321">
+Figure 3.19</a>. Unlike Windows 95/98, you should immediately see the TCP/IP protocol as one of the last protocols listed. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-22321">
+Figure 3.19: Select Network Protocol dialog box</a></h4><IMG CLASS="graphic" SRC="figs/sam.0319.gif" ALT="Figure 3.19"><P CLASS="para">
+Select TCP/IP<EM CLASS="emphasis">
+ </em>as the protocol and confirm it. If possible, install only the TCP/IP protocol. You usually do not want NetBEUI installed because this causes the machine to look for services under two different protocols, only one of which is likely in use.[<A CLASS="footnote" HREF="#ch03-pgfId-943371">2</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch03-pgfId-943371">[2]</a> A common occurrence: after looking at the unused protocol for a while, the machine will time out and try the good one. This fruitless searching gives you terrible performance and mysterious delays.</p></div></blockquote></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942278">
+3.2.1.3 Installing the Workstation service</a></h4><P CLASS="para">After installing TCP/IP, press the Services tab in the Network panel and check that you have a Workstation service, as shown at the end of the list in <A CLASS="xref" HREF="ch03_02.html#ch03-97222">
+Figure 3.20</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-97222">
+Figure 3.20: Network Services panel dialog box</a></h4><IMG CLASS="graphic" SRC="figs/sam.0320.gif" ALT="Figure 3.20"><P CLASS="para">
+This service is actually the Microsoft Networking Client, which allows the machine to access SMB services. The Workstation service is mandatory. The service is installed by default on both Windows NT Workstation 4.0 and Server 4.0. If it's not there, you can install it much like TCP/IP. In this case you need to press the Add button and then select Workstation Service, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-40000">
+Figure 3.21</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-40000">
+Figure 3.21: Select Network Service dialog box </a></h4><IMG CLASS="graphic" SRC="figs/sam.0321.gif" ALT="Figure 3.21"></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-85837">
+3.2.2 Configuring TCP/IP</a></h3><P CLASS="para">After you've installed the Workstation service, return to the Protocols tab and select the TCP/IP Protocol entry in the window. Then click the Properties button below the window. The Microsoft TCP/IP Protocol panel will be displayed. There are five tabs on the Windows NT panel, and (like Windows 95/98) you will need to work on three of them: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942313">
+</a>IP address</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942314">
+</a>DNS</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942315">
+</a>WINS address</p></li></ul><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942317">
+3.2.2.1 IP Address tab</a></h4><P CLASS="para">The IP Address tab is shown in <A CLASS="xref" HREF="ch03_02.html#ch03-97098">
+Figure 3.22</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-97098">
+Figure 3.22: Microsoft TCP/IP Properties for Windows NT</a></h4><IMG CLASS="graphic" SRC="figs/sam.0322.gif" ALT="Figure 3.22"><P CLASS="para">Select the "Specify an IP address" radio button and enter the computer's address and subnet mask in the space provided for the proper adapter (Ethernet card). You or your network manager should have selected an address for the client on the same subnet (LAN) as the Samba server. For example, if the server's address is 192.168.236.86 and its network mask 255.255.255.0, you might use the address 192.168.236.10, if it is available, for the NT workstation, along with the same netmask. If you use DHCP on your network, select the "Obtain an IP Address from a DHCP server" button.</p><P CLASS="para">
+If you don't have an IP address to use, and you are on a network by yourself, steal ours, as the 192.168.<EM CLASS="emphasis">
+x.x</em> subnet is specifically reserved by the Internic for LANs. If you're not by yourself, see your system administrator for some available addresses on your network.</p><P CLASS="para">
+The gateway field refers to a machine typically known as a <EM CLASS="emphasis">
+router</em>. If you have routers connecting multiple networks, you should put in the IP address of the one on your subnet.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942339">
+3.2.2.2 DNS tab</a></h4><P CLASS="para">Next we go to the tab for DNS, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-61878">
+Figure 3.23</a>. This brings up the DNS panel. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-61878">
+Figure 3.23: The DNS panel</a></h4><IMG CLASS="graphic" SRC="figs/sam.0323.gif" ALT="Figure 3.23"><P CLASS="para">
+The Domain Name System (DNS) is responsible for translating human-readable computer names such as <EM CLASS="emphasis">
+atrish.example.com</em> into IP addresses such as 192.168.236.10. There are two ways to accomplish this on a NT machine. First, you can specify a DNS server to do the translation for you, or you can keep a local list of name/address pairs for your workstation to refer to.</p><P CLASS="para">
+For a LAN that's not on the Internet, the list of possible hosts is typically small and well known, and may be kept in a file locally. Networks that are connected to the Internet typically use DNS service since it isn't possible to guess ahead of time what addresses you might be accessing out on the net. If you are in doubt as to whether a DNS server is being used, or what its address might be, look at the file <EM CLASS="emphasis">
+/etc/resolv.conf</em> on your Samba server: any machine using DNS will have this file. It looks like the following:</p><PRE CLASS="programlisting">
+#resolv.conf
+domain example.com
+nameserver 127.0.0.1
+nameserver 192.168.236.20</pre><P CLASS="para">
+In this example, the first nameserver in the list is 127.0.0.1, which indicates that the Samba server is also a DNS server for this LAN.[<A CLASS="footnote" HREF="#ch03-pgfId-946587">3</a>] In that case, you would use its network IP address (not 127.0.0.1, its localhost address) when filling in the DNS Configuration dialog box. Otherwise, use the other addresses you find in the lines beginning with <CODE CLASS="literal">
+nameserver</code>. Try to select ones on your own network. Any name servers listed in <EM CLASS="emphasis">
+/etc/resolv.conf</em> should work, but you'll get better performance by using a server nearby.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch03-pgfId-946587">[3]</a> The address 127.0.0.1 is known as the <EM CLASS="emphasis">
+localhost</em> address, and always refers to itself. For example, if you type <CODE CLASS="literal">
+ping 127.0.0.1</code> on a Unix server, you should always get a response, as you're pinging the host itself.</p></div></blockquote><P CLASS="para">
+Finally, enter the machine name once more, making sure that it's the same one listed in the Identification tab of the Network dialog box (before the NetBIOS name). Also, enter the DNS domain on which this machine resides. For example, if your workstation has a domain name such as <EM CLASS="emphasis">
+example.com</em>, enter it here. You can safely ignore the other options.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942365">
+3.2.2.3 WINS Address tab</a></h4><P CLASS="para">If you are not using a DNS server, you still need a way of translating NetBIOS names to addresses and back again. We recommend that you configure both DNS and WINS; NT has a preference for WINS and WINS can use DNS as a fallback if it cannot resolve any machine address. The WINS Address tab is shown in <A CLASS="xref" HREF="ch03_02.html#ch03-20855">
+Figure 3.24</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-20855">
+Figure 3.24: The WINS Address tab</a></h4><IMG CLASS="graphic" SRC="figs/sam.0324.gif" ALT="Figure 3.24"><P CLASS="para">
+If you have a WINS server, enter its address in the space marked Primary WINS Server. If your Samba server is providing WINS service (in other words, you have the line <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+service</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in the <EM CLASS="emphasis">
+smb.conf</em> file of your Samba server), provide the Samba server's IP address here. Otherwise, provide the address of another WINS server on your network.</p><P CLASS="para">
+You probably noticed that there is a field here for the adaptor; this field must specify the Ethernet adaptor that you're running TCP/IP on so that WINS will provide name service on the correct network. If you have both a LAN and a dialup adaptor, make sure you have the LAN's adaptor here.</p><P CLASS="para">
+Finally, select the "Enable DNS for Windows Resolution" checkbox, so WINS will try DNS as a fallback if it can't find a name. You can safely ignore the other options.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942383">
+3.2.2.4 Hosts files</a></h4><P CLASS="para">If you don't have either DNS or WINS, and you don't wish to use broadcast name resolution, you'll need to provide a table of IP addresses and hosts names, in standard Unix <I CLASS="filename">
+/etc/hosts</i> format. We recommend against this because maintenance of this file on any dynamic network is troublesome, but we will explain it just the same. The Windows host file should appear in the <EM CLASS="emphasis">
+\WINDOWS\HOSTS</em> directory of whatever local drive Windows is installed on. A sample follows:</p><PRE CLASS="programlisting">
+127.0.0.1 localhost
+192.168.236.1 escrime escrime.example.com
+192.168.236.2 riposte riposte.example.com
+192.168.236.3 wizzin wizzin.example.com
+192.168.236.4 touche touche.example.com
+192.168.236.5 gurgi gurgi.example.com
+192.168.236.6 jessiac jessiac.example.com
+192.168.236.7 skyline skyline.example.com </pre><P CLASS="para">
+If you wish, you can copy the contents directly from the Samba server's<I CLASS="filename">
+ /etc/hosts</i>. The format is identical. This file will then serve the same purpose as the hosts file on the Unix server. Again, <EM CLASS="emphasis">
+hosts</em> files on Windows should only be used as a last resort.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942394">
+3.2.2.5 Bindings</a></h4><P CLASS="para">
+The term <I CLASS="firstterm">
+bindings</i> is a way of saying "connected together at configuration time." It means that the TCP/IP protocol will channel through the Ethernet card (instead of, say, a dialup connection), and is actually connected properly. If you return to the Network dialog box and set the Show field to "all services" and click on all the + buttons in the tree, you should see a display similar to <A CLASS="xref" HREF="ch03_02.html#ch03-83060">
+Figure 3.25</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-83060">
+Figure 3.25: Service bindings</a></h4><IMG CLASS="graphic" SRC="figs/sam.0325.gif" ALT="Figure 3.25"><P CLASS="para">
+This means that the Workstation, Server, and NetBIOS interface services are connected to the WINS client. This is the correct binding for Microsoft TCP/IP. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942410">
+3.2.3 Connecting to the Samba Server</a></h3><P CLASS="para">You can safely leave the default values for the remainder of the tabs in the Network dialog box. Click on the OK button to complete the configuration. Once the proper files are loaded (if any), you will need to reboot in order for your changes to take effect.</p><P CLASS="para">
+Now for the big moment. Your Samba server is running and you have set up your NT client to communicate with it. After the machine reboots, login and double-click the Network Neighborhood icon on the desktop, and you should see your Samba server listed as a member of the workgroup, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-50785">
+Figure 3.26</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-50785">
+Figure 3.26: Windows NT Network Neighborhood</a></h4><IMG CLASS="graphic" SRC="figs/sam.0326.gif" ALT="Figure 3.26"><P CLASS="para">Double-clicking the server name will show the resources that the server is offering to the network, as shown in <A CLASS="xref" HREF="ch03_02.html#ch03-89532">
+Figure 3.27</a>. In this case, the test and the default printer are offered to the Window NT workstation. For more information, see the warning under the "Accessing the Samba Server" section, earlier in this chapter. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-89532">
+Figure 3.27: Server's shares</a></h4><IMG CLASS="graphic" SRC="figs/sam.0327.gif" ALT="Figure 3.27"><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> If you are presented with a dialog requesting the password for a user <CODE CLASS="literal">
+IPC$</code>, then Samba did not accept the password that was sent from the client. In this case, the username and the password that were created on the client side <EM CLASS="emphasis">
+must</em> match the username/password combination on the Samba server. If you are using Windows 98 or Windows NT Service Pack 3 or above, this is probably because the client is sending encrypted passwords instead of plaintext passwords. You can remedy this situation by performing two steps on the Samba server. First, add the following entry to the <CODE CLASS="literal">
+[global]</code> section of your Samba configuration file: <CODE CLASS="literal">
+encrypt password=yes</code>. Second, find the <I CLASS="filename">
+smbpasswd</i> program on the samba server (it is located in <I CLASS="filename">
+/usr/local/samba/bin</i> by default) and use it to add an entry to Samba's encrypted password database. For example, to add user <CODE CLASS="literal">
+steve</code> to Samba's encrypted password database, type <CODE CLASS="replaceable">
+<I>
+smbpasswd -a steve</i></code>. The first time you enter this password, the program will output an error message indicating that the password database does not exist; it will then create the database, which is typically stored in <I CLASS="filename">
+/usr/local/samba/private/smbpasswd</i>.</p></blockquote><P CLASS="para">
+If you don't see the server listed, don't panic. Start the Windows NT Explorer (not Internet Explorer!) and select Map Network Drive from the Tools menu. A dialog box appears that allows you to type the name of your server and its share directory in Windows format. For example, you would enter <I CLASS="filename">
+\\</i><CODE CLASS="replaceable"><I>server</i></code><I CLASS="filename">\temp</i> if your server happened to be named "server." If things still aren't right, go directly to the section "The Fault Tree" in <a href="ch09_01.html"><b>Chapter 9</b></a>, to see if you can troubleshoot what is wrong with the network.</p><P CLASS="para">
+If it works, congratulations! Try writing to the server and sending data to the network printer. You will be pleasantly surprised how seamlessly everything works! Now that you've finished setting up the Samba server and its clients, we can starting talking about how Samba works and how to configure it to your liking. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_01.html" TITLE="3.1 Setting Up Windows 95/98 Computers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.1 Setting Up Windows 95/98 Computers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_03.html" TITLE="3.3 An Introduction to SMB/CIFS">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 3.3 An Introduction to SMB/CIFS" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+3.1 Setting Up Windows 95/98 Computers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+3.3 An Introduction to SMB/CIFS</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch03_03.html b/docs/htmldocs/using_samba/ch03_03.html
new file mode 100755
index 00000000000..d3efd007aa6
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch03_03.html
@@ -0,0 +1,579 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 3] 3.3 An Introduction to SMB/CIFS</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:31:30Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_02.html" TITLE="3.2 Setting Up Windows NT 4.0 Computers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.2 Setting Up Windows NT 4.0 Computers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch03_01.html" TITLE="3. Configuring Windows Clients">
+Chapter 3<br>
+Configuring Windows Clients</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4. Disk Shares " BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch03-64069">
+3.3 An Introduction to SMB/CIFS</a></h2><P CLASS="para">We'll wrap up this chapter with a short tutorial on SMB/CIFS. SMB/CIFS is the protocol that Windows 95/98 and NT machines use to communicate with the Samba server and each other. At a high level, the SMB protocol suite is relatively simple. It includes commands for all of the file and print operations that you might do on a local disk or printer, such as:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942445">
+</a> Opening and closing a file</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942446">
+</a> Creating and deleting files and directories</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942447">
+</a> Reading and writing a file</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942853">
+</a> Searching for files</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942448">
+</a> Queueing and dequeueing files to a print spool</p></li></ul><P CLASS="para">
+Each of these operations can be encoded into an SMB message and transmitted to and from a server. The original name SMB comes from their data format: these are versions of the standard DOS system-call data structures, or <I CLASS="firstterm">
+Server Message Blocks</i>, redesigned for transmitting to another machine across a network.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942451">
+3.3.1 SMB Format</a></h3><P CLASS="para">Richard Sharpe of the Samba team defines SMB as a "request-response" protocol.[<A CLASS="footnote" HREF="#ch03-pgfId-942928">4</a>] In effect, this means that a client sends an SMB request to a server, and the server sends an SMB response back to the client. Rarely does a server send a message that is not in response to a client.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch03-pgfId-942928">[4]</a> See <I CLASS="filename">
+<a href="http://anu.samba.org/cifs/docs/what-is-smb.html">http://anu.samba.org/cifs/docs/what-is-smb.html</i></a> for Richard's excellent summary of SMB.</p></div></blockquote><P CLASS="para">
+An SMB message is not as complex as you might think. Let's take a closer look at the internal structure of such a message. It can be broken down into two parts: the <I CLASS="firstterm">
+header</i>, which is a fixed size, and the <I CLASS="firstterm">
+command string</i>, whose size can vary dramatically based on the contents of the message.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942453">
+3.3.1.1 SMB header format</a></h4><P CLASS="para">
+<A CLASS="xref" HREF="ch03_03.html#ch03-31015">
+Table 3.1</a> shows the format of an SMB header. SMB commands are not required to use all the fields in the SMB header. For example, when a client first attempts to connect to a server, it does not yet have a tree identifier (TID) value&nbsp;- one is assigned after it successfully connects&nbsp;- so a null TID (0xFFFF) is placed in its header field. Other fields may be padded with zeros when not used. </p><P CLASS="para">
+The fields of the SMB header are listed in <A CLASS="xref" HREF="ch03_03.html#ch03-31015">
+Table 3.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch03-31015">
+Table 3.1: SMB Header Fields </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Field</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Size (bytes)</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0xFF 'SMB'</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Protocol identifier</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+COM</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Command code, from 0x00 to 0xFF</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+RCLS</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Error class</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+REH</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Reserved</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ERR</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Error code</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+REB</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Reserved</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+RES</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+14</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Reserved</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+TID</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Tree identifier; a unique ID for a resource in use by client</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+PID</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Caller process ID</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+UID</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+User identifier</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+MID</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Multiplex identifier; used to route requests inside a process</p></td></tr></tbody></table></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942527">
+3.3.1.2 SMB command format</a></h4><P CLASS="para">
+<I CLASS="firstterm">
+</i>Immediately after the header is a variable number of bytes that constitute an SMB command or reply. Each command, such as Open File (COM field identifier: <CODE CLASS="literal">SMBopen</code>) or Get Print Queue (<CODE CLASS="literal">SMBsplretq</code>), has its own set of parameters and data. Like the SMB header fields, not all of the command fields need to be filled, depending on the specific command. For example, the Get Server Attributes (<CODE CLASS="literal">SMBdskattr</code>) command sets the WCT and BCC fields to zero. The fields of the command segment are shown in <A CLASS="xref" HREF="ch03_03.html#ch03-38178">
+Table 3.2</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch03-38178">
+Table 3.2: SMB Command Contents </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Field</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Size in Bytes</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+WCT</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<I CLASS="firstterm">
+</i>Word count</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+VWV</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameter words (size given by WCT)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+BCC</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameter byte count</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DATA</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Data (size given by BCC)</p></td></tr></tbody></table><P CLASS="para">
+Don't worry if you don't understand each of these fields; they are not necessary for using Samba at an administrator level. However, they do come in handy when debugging system messages. We will show you some of the more common SMB messages that clients and servers send using a modified version of <I CLASS="filename">
+tcpdump</i> later in this section. (If you would like an SMB sniffer with a graphical interface, try "ethereal," which uses the GTK libraries; see the Samba homepage for more information on this tool.)</p><P CLASS="para">
+If you would like more information on each of the commands for the SMB protocol, see the SMB/CIFS documentation at <a href="ftp://ftp.microsoft.com/developr/drg/CIFS/"><I CLASS="filename">ftp://ftp.microsoft.com/developr/drg/CIFS/</i></a>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942573">
+3.3.1.3 SMB variations</a></h4><P CLASS="para">
+The SMB protocol has been extended with new commands several times since its inception. Each new version is backwards compatible with the previous versions. This makes it quite possible for a LAN to have various clients and servers running different versions of the SMB protocol at once.</p><P CLASS="para">
+<A CLASS="xref" HREF="ch03_03.html#ch03-67366">
+Table 3.3</a> outlines the major versions of the SMB protocol. Within each "dialect" of SMB are many sub-versions that include commands supporting particular releases of major operating systems. The ID string is used by clients and servers to determine what level of the protocol they will speak to each other. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch03-67366">
+Table 3.3: SMB Protocol Dialects </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Protocol Name</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+ID String</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Used By</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Core</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+PC NETWORK PROGRAM 1.0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Core Plus </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+MICROSOFT NETWORKS 1.03 </code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+LAN Manager 1.0 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LANMAN1.0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+LAN Manager 2.0 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LM1.2X002</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+LAN Manager 2.1 </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LANMAN2.1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+NT LAN Manager 1.0</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+NT LM 0.12</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT 4.0</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba's NT LM 0.12</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+Samba</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Common Internet File System</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+CIFS 1.0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 2000</p></td></tr></tbody></table><P CLASS="para">
+Samba implements the <CODE CLASS="literal">
+NT</code> <CODE CLASS="literal">
+LM</code> <CODE CLASS="literal">
+0.12</code> specification for NT LAN Manager 1.0. It is backwards compatible with all of the other SMB variants. The CIFS specification is, in reality, LAN Manager 0.12 with a few specific additions.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942627">
+3.3.2 SMB Clients and Servers</a></h3><P CLASS="para">
+As mentioned earlier, SMB is a client/server protocol. In the purest sense, this means that a client sends a request to a server, which acts on the request and returns a reply. However, the client/server roles can often be reversed, sometimes within the context of a single SMB session. For example, consider the two Windows 95/98 computers in <A CLASS="xref" HREF="ch03_03.html#ch03-69480">
+Figure 3.28</a>. The computer named WIZZIN shares a printer to the network, and the computer named ESCRIME shares a disk directory. WIZZIN is in the client role when accessing ESCRIME's network drive, and in the server role when printing a job for ESCRIME. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch03-69480">
+Figure 3.28: Two computers that both have resources to share</a></h4><IMG CLASS="graphic" SRC="figs/sam.0328.gif" ALT="Figure 3.28"><P CLASS="para">
+This brings out an important point in Samba terminology:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-server-defined-in-Samba-terminology">
+</a>A <I CLASS="firstterm">
+server</i> is a machine with a resource to share.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-client-defined-in-Samba-terminology">
+</a>A <I CLASS="firstterm">
+client</i> is a machine that wishes to use that resource.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-943256">
+</a>A server can be a client (of another computer's resource) at any given time.</p></li></ul><P CLASS="para">
+Note that there are no implications as to the amount of resources that make up a server, or whether it has a large disk space or fast processor. A server could be an old 486 with a printer attached to it, or it could be an UltraSparc station with a 10 gigabyte disk service.</p><P CLASS="para">
+Microsoft Windows products have both the SMB client and server built in to the operating system. Wndows NT 4.0 uses a newer SMB protocol than Windows for Workgroups, and it offers an enhanced form of network security which will be discussed in <a href="ch06_01.html"><b>Chapter 6</b></a>. In addition, there are a large number of commercial SMB server products available from companies such as Sun, Compaq, SCO, Hewlett-Packard, Syntax, and IBM. Unfortunately, on the client side there are far fewer offerings, limited mainly to Digital Equipment's Pathworks product, and of course, Samba.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942638">
+3.3.3 A Simple SMB Connection</a></h3><P CLASS="para">Before we close this chapter, let's take a look at a simple SMB connection. This is some pretty technical data&nbsp;- which isn't really necessary to administer Samba&nbsp;- so you can skip over it if you like. We present this information largely as a way to help you get familiar with how the SMB protocol negotiates connections with other computers on the network. </p><P CLASS="para">
+There are four steps that the client and server must complete in order to establish a connection to a resource:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942687">
+</a> Establish a virtual connection.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942688">
+</a> Negotiate the protocol variant to speak.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942689">
+</a> Set session parameters.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942690">
+</a> Make a tree connection to a resource.</p></li></ol><P CLASS="para">
+We will examine each of these steps through the eyes of a useful tool that we mentioned earlier: the modified <I CLASS="filename">
+tcpdump</i> that is available from the Samba web site.</p><P CLASS="para">
+You can download this program at <I CLASS="filename">
+samba.org</i> in the <I CLASS="filename">
+samba/ftp/tcpdump-smb</i> directory; the latest version as of this writing is 3.4-5. Use this program as you would use the standard <I CLASS="filename">
+tcpdump</i> application, but add the <CODE CLASS="literal">
+-s 1500</code> switch to ensure that you get the whole packet and not just the first few bytes.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch03-pgfId-942691">
+3.3.3.1 Establishing a virtual connection</a></h4><P CLASS="para">When a user first makes a request to access a network disk or send a print job to a remote printer, NetBIOS takes care of making a connection at the session layer. The result is a bidirectional virtual channel between the client and server. In reality, there are only two messages that the client and server need to establish this connection. This is shown in the following example session request and response, as captured by <I CLASS="filename">
+tcpdump</i> :</p><PRE CLASS="programlisting">
+&gt;&gt;&gt; NBT Packet
+NBT Session Request
+Flags=0x81000044
+Destination=ESCRIME NameType=0x20 (Server)
+Source=WIZZIN NameType=0x00 (Workstation)
+
+&gt;&gt;&gt; NBT Packet
+NBT Session Granted
+Flags=0x82000000</pre></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942713">
+3.3.4 Negotiating the Protocol Variant</a></h3><P CLASS="para">At this point, there is an open channel between the client and server. Next, the client sends a message to the server to negotiate an SMB protocol. As mentioned earlier, the client sets its tree identifier (TID) field to zero, since it does not yet know what TID to use. A <EM CLASS="emphasis">
+tree identifier</em> is a number that represents a connection to a share on a server.</p><P CLASS="para">
+The command in the message is <CODE CLASS="literal">
+SMBnegprot</code>, a request to negotiate a protocol variant that will be used for the entire session. Note that the client sends to the server a list of all of the variants that it can speak, not vice versa.</p><P CLASS="para">
+The server responds to the <CODE CLASS="literal">
+SMBnegprot</code> request with an index into the list of variants that the client offered, starting with index 0, or with the value 0xFF if none of the protocol variants are acceptable. Continuing this example, the server responds with the value 5, which indicates that the <CODE CLASS="literal">
+NT</code> <CODE CLASS="literal">
+LM</code> <CODE CLASS="literal">
+0.12</code> dialect will be used for the remainder of the session:</p><PRE CLASS="programlisting">
+&gt;&gt;&gt; NBT Packet
+NBT Session Packet
+Flags=0x0
+Length=154
+
+SMB PACKET: SMBnegprot (REQUEST)
+SMB Command = 0x72
+Error class = 0x0
+Error code = 0
+Flags1 = 0x0
+Flags2 = 0x0
+Tree ID = 0
+Proc ID = 5371
+UID = 0
+MID = 385
+Word Count = 0
+Dialect=PC NETWORK PROGRAM 1.0
+Dialect=MICROSOFT NETWORKS 3.0
+Dialect=DOS LM1.2X002
+Dialect=DOS LANMAN2.1
+Dialect=Windows for Workgroups 3.1a
+Dialect=NT LM 0.12
+
+&gt;&gt;&gt; NBT Packet
+NBT Session Packet
+Flags=0x0
+Length=69
+
+SMB PACKET: SMBnegprot (REPLY)
+SMB Command = 0x72
+Error class = 0x0
+Error code = 0
+Flags1 = 0x0
+Flags2 = 0x1
+Tree ID = 0
+Proc ID = 5371
+UID = 0
+MID = 385
+Word Count = 02
+[000] 05 00</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942762">
+3.3.5 Set Session and Login Parameters</a></h3><P CLASS="para">The next step is to transmit session and login parameters for the session. This includes the account name and password (if there is one), the workgroup name, the maximum size of data that can be transferred, and the number of pending requests that may be in the queue at any one time.</p><P CLASS="para">
+In the following example, the Session Setup command presented allows for an additional SMB command to be piggybacked onto it. The letter X at the end of the command name indicates this, and the hexadecimal code of the second command is given in the <CODE CLASS="literal">
+Com2</code> field. In this case the command is <CODE CLASS="literal">
+0x75</code>, which is the Tree Connect and X command. The <CODE CLASS="literal">
+SMBtconX</code> message looks for the name of the resource in the <KBD CLASS="command">
+smb_buf</kbd> buffer. (This is the last field listed in the following request.) In this example, <KBD CLASS="command">
+smb_buf</kbd> contains the string <CODE CLASS="literal">
+\\ESCRIME\PUBLIC</code>, which is the full pathname to a shared directory on node ESCRIME. Using the "and X" commands like this speeds up each transaction, since the server doesn't have to wait on the client to make a second request.</p><P CLASS="para">
+Note that the TID is still zero. The server will provide a TID to the client once the session has been established and a connection has been made to the requested resource. In addition, note that the password is sent in the open. We can change this later using encrypted passwords:</p><PRE CLASS="programlisting">
+&gt;&gt;&gt; NBT Packet
+NBT Session Packet
+Flags=0x0
+Length=139
+
+SMB PACKET: SMBsesssetupX (REQUEST)
+SMB Command = 0x73
+Error class = 0x0
+Error code = 0
+Flags1 = 0x10
+Flags2 = 0x0
+Tree ID = 0
+Proc ID = 5371
+UID = 1
+MID = 385
+Word Count = 13
+Com2=0x75
+Res1=0x0
+Off2=106
+MaxBuffer=2920
+MaxMpx=2
+VcNumber=0
+SessionKey=0x1FF2
+CaseInsensitivePasswordLength=1
+CaseSensitivePasswordLength=1
+Res=0x0
+Capabilities=0x1
+Pass1&amp;Pass2&amp;Account&amp;Domain&amp;OS&amp;LanMan=
+ KRISTIN PARKSTR Windows 4.0 Windows 4.0
+PassLen=2
+Passwd&amp;Path&amp;Device=
+smb_bcc=22
+smb_buf[]=\\ESCRIME\PUBLIC</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch03-pgfId-942801">
+3.3.6 Making Connection to a Resource</a></h3><P CLASS="para">For the final step, the server returns a TID to the client, indicating that the user has been authorized access and that the resource is ready to be used. It also sets the <KBD CLASS="command">
+ServiceType</kbd> field to "A" to indicate that this is a file service. Available service types are:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942803">
+</a> "A" for a disk or file</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942804">
+</a> "LPT1" for a spooled output</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942805">
+</a> "COMM" for a direct-connect printer or modem</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch03-pgfId-942806">
+</a> "IPC" for a named pipe</p></li></ul><P CLASS="para">
+The output is:</p><PRE CLASS="programlisting">
+&gt;&gt;&gt; NBT Packet
+NBT Session Packet
+Flags=0x0
+Length=78
+
+SMB PACKET: SMBsesssetupX (REPLY)
+SMB Command = 0x73
+Error class = 0x0
+Error code = 0
+Flags1 = 0x80
+Flags2 = 0x1
+Tree ID = 121
+Proc ID = 5371
+UID = 1
+MID = 385
+Word Count = 3
+Com2=0x75
+Off2=68
+Action=0x1
+[000] Unix Samba 1.9.1
+[010] PARKSTR
+
+SMB PACKET: SMBtconX (REPLY) (CHAINED)
+smbvwv[]=
+Com2=0xFF
+Off2=78
+smbbuf[]=
+ServiceType=A:</pre><P CLASS="para">
+Now that a TID has been assigned, the client may issue any sort of command that it would use on a local disk drive. It can open files, read and write to them, delete them, create new files, search for filenames, and so on. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_02.html" TITLE="3.2 Setting Up Windows NT 4.0 Computers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.2 Setting Up Windows NT 4.0 Computers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4. Disk Shares " BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+3.2 Setting Up Windows NT 4.0 Computers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4. Disk Shares </td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_01.html b/docs/htmldocs/using_samba/ch04_01.html
new file mode 100755
index 00000000000..1cc3494d290
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_01.html
@@ -0,0 +1,415 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] Disk Shares </title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:31:52Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_03.html" TITLE="3.3 An Introduction to SMB/CIFS">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.3 An Introduction to SMB/CIFS" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 4</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_02.html" TITLE="4.2 Special Sections">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.2 Special Sections" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch04-21486">
+4. Disk Shares </a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch04-76968" TITLE="4.1 Learning the Samba Configuration File">
+Learning the Samba Configuration File</a><br>
+<A CLASS="sect1" HREF="ch04_02.html" TITLE="4.2 Special Sections">
+Special Sections</a><br>
+<A CLASS="sect1" HREF="ch04_03.html" TITLE="4.3 Configuration File Options">
+Configuration File Options</a><br>
+<A CLASS="sect1" HREF="ch04_04.html" TITLE="4.4 Server Configuration">
+Server Configuration</a><br>
+<A CLASS="sect1" HREF="ch04_05.html" TITLE="4.5 Disk Share Configuration">
+Disk Share Configuration</a><br>
+<A CLASS="sect1" HREF="ch04_06.html" TITLE="4.6 Networking Options with Samba">
+Networking Options with Samba</a><br>
+<A CLASS="sect1" HREF="ch04_07.html" TITLE="4.7 Virtual Servers">
+Virtual Servers</a><br>
+<A CLASS="sect1" HREF="ch04_08.html" TITLE="4.8 Logging Configuration Options">
+Logging Configuration Options</a></p><P>
+</p></div><P CLASS="para">In the previous three chapters, we showed you how to install Samba on a Unix server and set up Windows clients to use a simple disk share. This chapter will show you how Samba can assume more productive roles on your network.</p><P CLASS="para">
+Samba's daemons, <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em>, are controlled through a single ASCII file, <I CLASS="filename">
+smb.conf</i>, that can contain over 200 unique options. These options define how Samba reacts to the network around it, including everything from simple permissions to encrypted connections and NT domains. The next five chapters are designed to help you get familiar with this file and its options. Some of these options you will use and change frequently; others you may never use&nbsp;- it all depends on how much functionality you want Samba to offer its clients.</p><P CLASS="para">
+This chapter introduces the structure of the Samba configuration file and shows you how to use these options to create and modify disk shares. Subsequent chapters will discuss browsing, how to configure users, security, domains, and printers, and a host of other myriad topics that you can implement with Samba on your network.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch04-76968">
+4.1 Learning the Samba Configuration File</a></h2><P CLASS="para">
+<I CLASS="filename">
+</i>Here is an <I CLASS="filename">
+</i>example of a Samba configuration file. If you have worked with a Windows .INI file, the structure of the <I CLASS="filename">
+smb.conf </i> file should look very familiar: </p><PRE CLASS="programlisting">
+[global]
+ log level = 1
+ max log size = 1000
+ socket options = TCP_NODELAY IPTOS_LOWDELAY
+ guest ok = no
+[homes]
+ browseable = no
+ map archive = yes
+[printers]
+ path = /usr/tmp
+ guest ok = yes
+ printable = yes
+ min print space = 2000
+[test]
+ browseable = yes
+ read only = yes
+ guest ok = yes
+ path = /export/samba/test</pre><P CLASS="para">
+Although you may not understand the contents yet, this is a good configuration file to grab if you're in a hurry. (If you're not, we'll create a new one from scratch shortly.) In a nutshell, this configuration file sets up basic debug logging in a default log file not to exceed 1MB, optimizes TCP/IP socket connections between the Samba server and any SMB clients, and allows Samba to create a disk share for each user that has a standard Unix account on the server. In addition, each of the printers registered on the server will be publicly available, as will a single read-only share that maps to the <I CLASS="filename">
+/export/samba/test</i> directory. The last part of this file is similar to the disk share you used to test Samba in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-52415">
+4.1.1 Configuration File Structure</a></h3><P CLASS="para">
+<I CLASS="filename">
+</i>Let's take another look at this configuration file, this time from a higher level:</p><PRE CLASS="programlisting">
+[global]
+ ...
+[homes]
+ ...
+[printers]
+ ...
+[test]
+ ...</pre><P CLASS="para">
+The names inside the square brackets delineate unique sections of the <I CLASS="filename">
+smb.conf</i> file; each section names the <I CLASS="firstterm">
+share</i> (or service) that the section refers to. For example, the <CODE CLASS="literal">
+[test]</code> and <CODE CLASS="literal">
+[homes]</code> sections are each unique disk shares; they contain options that map to specific directories on the Samba server. The <CODE CLASS="literal">
+[printers]</code> share contains options that map to various printers on the server. All the sections defined in the <I CLASS="filename">
+smb.conf</i> file, with the exception of the <CODE CLASS="literal">
+[global]</code> section, will be available as a disk or printer share to clients connecting to the Samba server.</p><P CLASS="para">
+The remaining lines are individual configuration options unique to that share. These options will continue until a new bracketed section is encountered, or until the end of the file is reached. Each configuration option follows a simple format:</p><PRE CLASS="programlisting"><CODE CLASS="replaceable"><I>option</i></code> = <CODE CLASS="replaceable"><I>value</i></code></pre><P CLASS="para">
+Options in the <I CLASS="filename">
+smb.conf</i> file are set by assigning a value to them. We should warn you up front that some of the option names in Samba are poorly chosen. For example, <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+only</code> is self-explanatory, and is typical of many recent Samba options. <CODE CLASS="literal">
+public</code> is an older option, and is vague; it now has a less-confusing synonym <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> (may be accessed by guests). We describe some of the more common historical names in this chapter in sections that highlight each major task. In addition, <a href="appc_01.html"><b>Appendix C, <CITE CLASS="appendix">Samba Configuration Option Quick Reference</cite></b></a>, contains an alphabetical index of all the configuration options and their meanings.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955562">
+4.1.1.1 Whitespaces, quotes, and commas</a></h4><P CLASS="para">
+An important item to remember about configuration options is that all whitespaces in the <CODE CLASS="replaceable">
+<I>
+value</i></code> are significant. For example, consider the following option:</p><PRE CLASS="programlisting">
+volume = The Big Bad Hard Drive Number 3543</pre><P CLASS="para">
+Samba strips away the spaces between the final <CODE CLASS="literal">
+e</code> in <CODE CLASS="literal">
+volume</code> and the first <CODE CLASS="literal">
+T</code> in <CODE CLASS="literal">
+The</code>. These whitespaces are insignificant. The rest of the whitespaces are significant and will be recognized and preserved by Samba when reading in the file. Space is not significant in option names (such as <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code>), but we recommend you follow convention and keep spaces between the words of options.</p><P CLASS="para">
+If you feel safer including quotation marks at the beginning and ending of a configuration option's value, you may do so. Samba will ignore these quotation marks when it encounters them. Never use quotation marks around an option itself; Samba will treat this as an error.</p><P CLASS="para">
+Finally, you can use whitespaces to separate a series of values in a list, or you can use commas. These two options are equivalent:</p><PRE CLASS="programlisting">
+netbios aliases = sales, accounting, payroll
+netbios aliases = sales accounting payroll</pre><P CLASS="para">
+In some values, however, you must use one form of separation&nbsp;- spaces in some cases, commas in others.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-960466">
+4.1.1.2 Capitalization</a></h4><P CLASS="para">Capitalization is not important in the Samba configuration file except in locations where it would confuse the underlying operating system. For example, let's assume that you included the following option in a share that pointed to <I CLASS="filename">
+/export/samba/simple </i>:</p><PRE CLASS="programlisting">
+PATH = /EXPORT/SAMBA/SIMPLE</pre><P CLASS="para">
+Samba would have no problem with the <CODE CLASS="literal">
+path</code> configuration option appearing entirely in capital letters. However, when it tries to connect to the given directory, it would be unsuccessful because the Unix filesystem in the underlying operating system <EM CLASS="emphasis">
+is</em> case sensitive. Consequently, the path listed would not be found and clients would be unable to connect to the share.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-960474">
+4.1.1.3 Line continuation</a></h4><P CLASS="para">
+You can continue a line in the Samba configuration file using the backslash, as follows:</p><PRE CLASS="programlisting">
+comment = The first share that has the primary copies \
+ of the new Teamworks software product.</pre><P CLASS="para">
+Because of the backslash, these two lines will be treated as one line by Samba. The second line begins at the first non-whitespace character that Samba encounters; in this case, the <CODE CLASS="literal">
+o</code> in <CODE CLASS="literal">
+of</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955588">
+4.1.1.4 Comments</a></h4><P CLASS="para">
+You can insert comments in the <I CLASS="filename">
+smb.conf</i> configuration file by preceding a line with either a hash mark (#) or a semicolon (;). Both characters are equivalent. For example, the first three lines in the following example would be considered comments:</p><PRE CLASS="programlisting">
+# This is the printers section. We have given a minimum print
+; space of 2000 to prevent some errors that we've seen when
+; the spooler runs out of space.
+
+[printers]
+ public = yes
+ min print space = 2000</pre><P CLASS="para">
+Samba will ignore all comment lines in its configuration file; there are no limitations to what can be placed on a comment line after the initial hash mark or semicolon. Note that the line continuation character (<CODE CLASS="literal">\</code>) will <EM CLASS="emphasis">
+not</em> be honored on a commented line. Like the rest of the line, it is ignored.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955563">
+4.1.1.5 Changes at runtime</a></h4><P CLASS="para">You can modify the <I CLASS="filename">
+smb.conf</i> configuration file and any of its options at any time while the Samba daemons are running. By default, Samba checks the configuration file every 60 seconds for changes. If it finds any, the changes are immediately put into effect. If you don't wish to wait that long, you can force a reload by either sending a SIGHUP signal to the <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em> processes, or simply restarting the daemons.</p><P CLASS="para">
+For example, if the <EM CLASS="emphasis">
+smbd</em> process was 893, you could force it to reread the configuration file with the following command:</p><PRE CLASS="programlisting">
+<B CLASS="emphasis.bold"><CODE CLASS="literal">#</code> kill -SIGHUP 893</b></pre><P CLASS="para">
+Not all changes will be immediately recognized by clients. For example, changes to a share that is currently in use will not be registered until the client disconnects and reconnects to that share. In addition, server-specific parameters such as the workgroup or NetBIOS name of the server will not register immediately either. This keeps active clients from being suddenly disconnected or encountering unexpected access problems while a session is open.<I CLASS="filename">
+</i> </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-87365">
+4.1.2 Variables</a></h3><P CLASS="para">
+<I CLASS="filename">
+</i>Samba includes a complete set of variables for determining characteristics of the Samba server and the clients to which it connects. Each of these variables begins with a percent sign, followed by a single uppercase or lowercase letter, and can be used only on the right side of a configuration option (e.g., after the equal sign):</p><PRE CLASS="programlisting">
+[pub]
+ path = /home/ftp/pub/%a </pre><P CLASS="para">
+The <CODE CLASS="literal">
+%a</code> stands for the client machine's architecture (e.g., <CODE CLASS="literal">
+WinNT</code> for Windows NT, <CODE CLASS="literal">
+Win95</code> for Windows 95 or 98, or <CODE CLASS="literal">
+WfWg</code> for Windows for Workgroups). Because of this, Samba will assign a unique path for the <CODE CLASS="literal">
+[pub]</code> share to client machines running Windows NT, a different path for client machines running Windows 95, and another path for Windows for Workgroups. In other words, the paths that each client would see as its share differ according to the client's architecture, as follows:</p><PRE CLASS="programlisting">
+/home/ftp/pub/WinNT
+/home/ftp/pub/Win95
+/home/ftp/pub/WfWg</pre><P CLASS="para">
+Using variables in this manner comes in handy if you wish to have different users run custom configurations based on their own unique characteristics or conditions. Samba has 19 variables, as shown in <A CLASS="xref" HREF="ch04_01.html#ch04-10883">
+Table 4.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-10883">
+Table 4.1: Samba Variables </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">Client variables</b></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%a</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<I CLASS="filename">
+</i>Client's architecture (e.g., Samba, WfWg, WinNT, Win95, or UNKNOWN)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%I</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's IP address (e.g., 192.168.220.100)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">%m</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's NetBIOS name</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%M</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Client's DNS name</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">User variables</b></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%g</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary group of <CODE CLASS="literal">
+%u</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%G</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Primary group of <CODE CLASS="literal">
+%U</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%H</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Home directory of <CODE CLASS="literal">
+%u</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%u</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current Unix username</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%U</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Requested client username (not always used by Samba)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+Share variables</b></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%p</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Automounter's path to the share's root directory, if different from <CODE CLASS="literal">
+%P</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%P</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's root directory</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%S</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current share's name</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+Server variables</b></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%d</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Current server process ID</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%h</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba server's DNS hostname</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%L</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba server's NetBIOS name</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%N</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Home directory server, from the automount map</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%v</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba version</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+Miscellaneous variables</b></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%R</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The SMB protocol level that was negotiated</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%T</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The current date and time</p></td></tr></tbody></table><P CLASS="para">Here's another example of using variables: let's say that there are five clients on your network, but one client, <CODE CLASS="literal">
+fred</code>, requires a slightly different <CODE CLASS="literal">
+[homes]</code> configuration loaded when it connects to the Samba server. With Samba, it's simple to attack such a problem: </p><PRE CLASS="programlisting">
+[homes]
+ ...
+ include = /usr/local/samba/lib/smb.conf.%m
+ ...</pre><P CLASS="para">
+The <CODE CLASS="literal">
+include</code> option here causes a separate configuration file for each particular NetBIOS machine (<CODE CLASS="literal">%m</code>) to be read in addition to the current file. If the hostname of the client machine is <CODE CLASS="literal">
+fred</code>, and if a <I CLASS="filename">
+smb.conf.fred</i> file exists in the <CODE CLASS="replaceable">
+<I>
+samba_dir</i></code><I CLASS="filename">
+/lib/</i> directory (or whatever directory you've specified for your configuration files), Samba will insert that configuration file into the default one. If any configuration options are restated in <I CLASS="filename">
+smb.conf.fred</i>, those values will override any options previously encountered in that share. Note that we say "previously." If any options are restated in the main configuration file after the <CODE CLASS="literal">
+include</code> option, Samba will honor those restated values for the share in which they are defined.</p><P CLASS="para">
+Here's the important part: if there is no such file, Samba will not generate an error. In fact, it won't do anything at all. This allows you to create only one extra configuration file for <CODE CLASS="literal">
+fred</code> when using this strategy, instead of one for each NetBIOS machine that is on the network.</p><P CLASS="para">
+Machine-specific configuration files can be used both to customize particular clients and to make debugging Samba easier. Consider the latter; if we have one client with a problem, we can use this approach to give it a private log file with a more verbose logging level. This allows us to see what Samba is doing without slowing down all the other clients or overflowing the disk with useless logs. Remember, with large networks you may not always have the option to restart the Samba server to perform debugging!</p><P CLASS="para">
+You can use each of the variables in <A CLASS="xref" HREF="ch04_01.html#ch04-10883">
+Table 4.1</a> to give custom values to a variety of Samba options. We will highlight several of these options as we move through the next few chapters.<I CLASS="filename">
+</i> </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch03_03.html" TITLE="3.3 An Introduction to SMB/CIFS">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 3.3 An Introduction to SMB/CIFS" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_02.html" TITLE="4.2 Special Sections">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.2 Special Sections" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+3.3 An Introduction to SMB/CIFS</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.2 Special Sections</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_02.html b/docs/htmldocs/using_samba/ch04_02.html
new file mode 100755
index 00000000000..d0b554e941a
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_02.html
@@ -0,0 +1,211 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.2 Special Sections</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:00Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_01.html" TITLE="4.1 Learning the Samba Configuration File">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.1 Learning the Samba Configuration File" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_03.html" TITLE="4.3 Configuration File Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.3 Configuration File Options" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-81402">
+4.2 Special Sections</a></h2><P CLASS="para">
+<I CLASS="filename">
+</i>Now that we've gotten our feet wet with variables, there are a few special sections of the Samba configuration file that we should talk about. Again, don't worry if you do not understand each and every configuration options listed below; we'll go over each of them over the course of the upcoming chapters.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-943263">
+4.2.1 The [ globals] Section</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+[globals]</code> section appears in virtually every Samba configuration file, even though it is not mandatory to define one. Any option set in this section of the file will apply to all the other shares, as if the contents of the section were copied into the share itself. There is one catch: other sections can list the same option in their section with a new value; this has the effect of overriding the value specified in the <CODE CLASS="literal">
+[globals]</code> section. </p><P CLASS="para">
+To illustrate this, let's again look at the opening example of the chapter:</p><PRE CLASS="programlisting">
+[global]
+ log level = 1
+ max log size = 1000
+ socket options = TCP_NODELAY IPTOS_LOWDELAY
+ guest ok = no
+[homes]
+ browseable = no
+ map archive = yes
+[printers]
+ path = /usr/tmp
+ guest ok = yes
+ printable = yes
+ min print space = 2000
+[test]
+ browseable = yes
+ read only = yes
+ guest ok = yes
+ path = /export/samba/test</pre><P CLASS="para">
+In the previous example, if we were going to connect a client to the <CODE CLASS="literal">
+[test]</code> share, Samba would first read in the <CODE CLASS="literal">
+[globals]</code> section. At that point, it would set the option <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+no</code> as the global default for each share it encounters throughout the configuration file. This includes the <CODE CLASS="literal">
+[homes]</code> and <CODE CLASS="literal">
+[printers]</code> shares. When it reads in the <CODE CLASS="literal">
+[test]</code> share, however, it would then find the configuration option <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code>, and override the default from the <CODE CLASS="literal">
+[globals]</code> section with the value <CODE CLASS="literal">
+yes</code> in the context of the <CODE CLASS="literal">
+[pub]</code> share.</p><P CLASS="para">
+Any option that appears outside of a section (before the first marked section) is also assumed to be a global option.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-942795">
+4.2.2 The [homes] Section</a></h3><P CLASS="para">
+If a client attempts to connect to a share that doesn't appear in the <I CLASS="filename">
+smb.conf</i> file, Samba will search for a <CODE CLASS="literal">
+[homes]</code> share in the configuration file. If one exists, the unidentified share name is assumed to be a Unix username, which is queried in the password database of the Samba server. If that username appears, Samba assumes the client is a Unix user trying to connect to his or her home directory on the server.</p><P CLASS="para">
+For example, assume a client machine is connecting to the Samba server <CODE CLASS="literal">
+hydra</code> for the first time, and tries to connect to a share named [<CODE CLASS="literal">alice]</code>. There is no <CODE CLASS="literal">
+[alice]</code> share defined in the <I CLASS="filename">
+smb.conf</i> file, but there is a <CODE CLASS="literal">
+[homes]</code>, so Samba searches the password database file and finds an <CODE CLASS="literal">alice</code> user account is present on the system. Samba then checks the password provided by the client against user <CODE CLASS="literal">alice</code>'s Unix password&nbsp;- either with the password database file if it's using non-encrypted passwords, or Samba's <I CLASS="filename">
+smbpasswd</i> file if encrypted passwords are in use. If the passwords match, then Samba knows it has guessed right: the user <CODE CLASS="literal">alice</code> is trying to connect to her home directory. Samba will then create a share called <CODE CLASS="literal">[alice]</code> for her.</p><P CLASS="para">
+The process of using the <CODE CLASS="literal">
+[homes]</code> section to create users (and dealing with their passwords) is discussed in more detail in the <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a>.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-942816">
+4.2.3 The [printers] Section</a></h3><P CLASS="para">
+The third special section is called <CODE CLASS="literal">
+[printers]</code> and is similar to <CODE CLASS="literal">
+[homes]</code>. If a client attempts to connect to a share that isn't in the <I CLASS="filename">
+smb.conf</i> file, and its name can't be found in the password file, Samba will check to see if it is a printer share. Samba does this by reading the printer capabilities file (usually <I CLASS="filename">
+/etc/printcap</i>) to see if the share name appears there.[<A CLASS="footnote" HREF="#ch04-pgfId-960558">1</a>] If it does, Samba creates a share named after the printer.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch04-pgfId-960558">[1]</a> Depending on your system, this file may not be <EM CLASS="emphasis">
+/etc/printcap</em>. You can use the <EM CLASS="emphasis">
+testparm</em> command that comes with Samba to determine the value of the <CODE CLASS="literal">
+printcap</code> <CODE CLASS="literal">
+name</code> configuration option; this was the default value chosen when Samba was compiled.</p></div></blockquote><P CLASS="para">
+Like <CODE CLASS="literal">
+[homes]</code>, this means you don't have to maintain a share for each of your system printers in the <I CLASS="filename">
+smb.conf</i> file. Instead, Samba honors the Unix printer registry if you request it to, and provides the registered printers to the client machines. There is, however, an obvious limitation: if you have an account named <CODE CLASS="literal">
+fred</code> and a printer named <CODE CLASS="literal">
+fred</code>, Samba will always find the user account first, even if the client really needed to connect to the printer.</p><P CLASS="para">
+The process of setting up the <CODE CLASS="literal">
+[printers]</code> share is discussed in more detail in <a href="ch07_01.html"><b>Chapter 7, <CITE CLASS="chapter">Printing and Name Resolution</cite></b></a>.<I CLASS="filename">
+</i> </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-968226">
+4.2.4 Configuration Options</a></h3><P CLASS="para">
+<I CLASS="filename">
+</i>Options in the Samba configuration files fall into one of two categories: <I CLASS="firstterm">
+global</i> or <I CLASS="firstterm">
+share</i>. Each category dictates where an option can appear in the configuration file.</p><DL CLASS="variablelist">
+<DT CLASS="term">
+Global</dt><DD CLASS="listitem">
+<P CLASS="para">Global options <EM CLASS="emphasis">
+must</em> appear in the <CODE CLASS="literal">
+[global]</code> section and nowhere else. These are options that typically apply to the behavior of the Samba server itself, and not to any of its shares.</p></dd><DT CLASS="term">
+Share</dt><DD CLASS="listitem">
+<P CLASS="para">Share options can appear in specific shares, or they can appear in the <CODE CLASS="literal">
+[global]</code> section. If they appear in the <CODE CLASS="literal">
+[global]</code> section, they will define a default behavior for all shares, unless a share overrides the option with a value of its own.</p></dd></dl><P CLASS="para">
+In addition, the values that a configuration option can take can be divided into four categories. They are as follows:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+Boolean</dt><DD CLASS="listitem">
+<P CLASS="para">These are simply yes or no values, but can be represented by any of the following: <CODE CLASS="literal">
+yes</code>, <CODE CLASS="literal">
+no</code>, <CODE CLASS="literal">
+true</code>, <CODE CLASS="literal">
+false</code>, <CODE CLASS="literal">
+0</code>, <CODE CLASS="literal">
+1</code>. The values are case insensitive: <CODE CLASS="literal">
+YES</code> is the same as <CODE CLASS="literal">
+yes</code>.</p></dd><DT CLASS="term">
+Numerical</dt><DD CLASS="listitem">
+<P CLASS="para">An integer, hexidecimal, or octal number. The standard <CODE CLASS="literal">
+0x</code><EM CLASS="emphasis">
+nn</em> syntax is used for hexadecimal and <CODE CLASS="literal">
+0</code><EM CLASS="emphasis">
+nnn</em> for octal.</p></dd><DT CLASS="term">
+String</dt><DD CLASS="listitem">
+<P CLASS="para">
+A string of case-sensitive characters, such as a filename or a username.</p></dd><DT CLASS="term">
+Enumerated list</dt><DD CLASS="listitem">
+<P CLASS="para">
+A finite list of known values. In effect, a boolean is an enumerated list with only two values.<I CLASS="filename">
+</i> </p></dd></dl></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_01.html" TITLE="4.1 Learning the Samba Configuration File">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.1 Learning the Samba Configuration File" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_03.html" TITLE="4.3 Configuration File Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.3 Configuration File Options" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.1 Learning the Samba Configuration File</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.3 Configuration File Options</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_03.html b/docs/htmldocs/using_samba/ch04_03.html
new file mode 100755
index 00000000000..3e5ae738659
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_03.html
@@ -0,0 +1,190 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.3 Configuration File Options</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:06Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_02.html" TITLE="4.2 Special Sections">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.2 Special Sections" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_04.html" TITLE="4.4 Server Configuration">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.4 Server Configuration" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-46076">
+4.3 Configuration File Options</a></h2><P CLASS="para">
+Samba has well over 200 configuration options at its disposal. So let's start off easy by introducing some of the options you can use to modify the configuration file itself. </p><P CLASS="para">
+As we hinted earlier in the chapter, configuration files are by no means static. You can instruct Samba to include or even replace configuration options as it is processing them. The options to do this are summarized in <A CLASS="xref" HREF="ch04_03.html#ch04-94939">
+Table 4.2</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-94939">
+Table 4.2: Configuration File Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+config file</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the location of a configuration file to use instead of the current one.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+include</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies an additional segment of configuration options to be included at this point in the configuration file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+copy</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (name of share)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows you to clone the configuration options of another share in the current share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-960146">
+4.3.1 config file</a></h3><P CLASS="para">
+The global <CODE CLASS="literal">
+config</code> <CODE CLASS="literal">
+file</code> option specifies a replacement configuration file that will be loaded when the option is encountered. If the target file exists, the remainder of the current configuration file, as well as the options encounter so far, will be discarded; Samba will configure itself entirely with the options in the new file. The <CODE CLASS="literal">
+config</code> <CODE CLASS="literal">
+file</code> option takes advantage of the variables above, which is useful in the event that you want load a special configuration file based on the machine name or user of the client that it connecting. </p><P CLASS="para">
+For example, the following line instructs Samba to use a configuration file specified by the NetBIOS name of the client connecting, if such a file exists. If it does, options specified in the original configuration file are ignored. The following example attempts to lead a new configuration file based on the client's NetBIOS name: </p><PRE CLASS="programlisting">
+[global]
+ config file = /usr/local/samba/lib/smb.conf.%m</pre><P CLASS="para">
+If the configuration file specified does not exist, the option is ignored and Samba will continue to configure itself based on the current file.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-960151">
+4.3.2 include</a></h3><P CLASS="para">
+This option, discussed in greater detail earlier, copies the target file into the current configuration file at the point specified, as shown in <A CLASS="xref" HREF="ch04_03.html#ch04-97340">
+Figure 4.1</a>. This option also takes advantage of the variables specified earlier in the chapter, which is useful in the event that you want load configuration options based on the machine name or user of the client that it connecting. You can use this option as follows:</p><PRE CLASS="programlisting">
+[global]
+ include = /usr/local/samba/lib/smb.conf.%m</pre><P CLASS="para">
+If the configuration file specified does not exist, the option is ignored. Remember that any option specified previously is overridden. In <A CLASS="xref" HREF="ch04_03.html#ch04-97340">
+Figure 4.1</a>, all three options will override their previous values. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-97340">
+Figure 4.1: The include option in a Samba configuration file</a></h4><IMG CLASS="graphic" SRC="figs/sam.0401.gif" ALT="Figure 4.1"><P CLASS="para">
+The <CODE CLASS="literal">
+include</code> option cannot understand the variables <CODE CLASS="literal">
+%u</code> (user), <CODE CLASS="literal">
+%p</code> (current share's rout directory), or <CODE CLASS="literal">
+%s</code> (current share) because they are not set at the time the file is read.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-960290">
+4.3.3 copy</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+copy</code> configuration option allows you to clone the configuration options of the share name that you specify in the current share. The target share must appear earlier in the configuration file than the share that is performing the copy. For example:</p><PRE CLASS="programlisting">
+[template]
+ writable = yes
+ browsable = yes
+ valid users = andy, dave, peter
+
+[data]
+ path = /usr/local/samba
+ copy = template</pre><P CLASS="para">
+Note that any options in the share that invoked the <CODE CLASS="literal">
+copy</code> directive will override those in the cloned share; it does not matter whether they appear before or after the <CODE CLASS="literal">
+copy</code><I CLASS="filename">
+</i> directive.<I CLASS="filename">
+</i> </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_02.html" TITLE="4.2 Special Sections">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.2 Special Sections" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_04.html" TITLE="4.4 Server Configuration">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.4 Server Configuration" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.2 Special Sections</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.4 Server Configuration</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_04.html b/docs/htmldocs/using_samba/ch04_04.html
new file mode 100755
index 00000000000..5eac6db9e5d
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_04.html
@@ -0,0 +1,214 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.4 Server Configuration</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:07Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_03.html" TITLE="4.3 Configuration File Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.3 Configuration File Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_05.html" TITLE="4.5 Disk Share Configuration">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.5 Disk Share Configuration" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-71382">
+4.4 Server Configuration</a></h2><P CLASS="para">Now it's time to begin configuring your Samba server. Let's introduce three basic configuration options that can appear in the <CODE CLASS="literal">
+[global]</code> section of your <I CLASS="filename">
+smb.conf</i> file:</p><PRE CLASS="programlisting">
+[global]
+ # Server configuration parameters
+ netbios name = HYDRA
+ server string = Samba %v on (%L)
+ workgroup = SIMPLE</pre><P CLASS="para">
+This configuration file is pretty simple; it advertises the Samba server on a NBT network under the NetBIOS name <CODE CLASS="literal">
+hydra</code>. In addition, the machine belongs to the workgroup SIMPLE and displays a description to clients that includes the Samba version number as well as the NetBIOS name of the Samba server.</p><P CLASS="para">
+If you had to enter <CODE CLASS="literal">
+encrypt passwords=yes </code>in your earlier configuration file, you should do so here as well.</p><P CLASS="para">
+Go ahead and try this configuration file. Create a file named <I CLASS="filename">
+smb.conf</i> under the <I CLASS="filename">
+/usr/local/samba/lib</i> directory with the text listed above. Then reset the Samba server and use a Windows client to verify the results. Be sure that your Windows clients are in the SIMPLE workgroup as well. After clicking on the Network Neighborhood on a Windows client, you should see a window similar to <A CLASS="xref" HREF="ch04_04.html#ch04-38915">
+Figure 4.2</a>. (In this figure, <CODE CLASS="literal">
+phoenix</code> and <CODE CLASS="literal">
+chimaera</code> are our Windows clients.) </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-38915">
+Figure 4.2: Network Neighborhood showing the Samba server</a></h4><IMG CLASS="graphic" SRC="figs/sam.0402.gif" ALT="Figure 4.2"><P CLASS="para">
+You can verify the <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+string</code> by listing the details of the Network Neighborhood window (select the Details menu item under the View menu), at which point you should see a window similar to <A CLASS="xref" HREF="ch04_04.html#ch04-50900">
+Figure 4.3</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-50900">
+Figure 4.3: Network Neighborhood details listing</a></h4><IMG CLASS="graphic" SRC="figs/sam.0403.gif" ALT="Figure 4.3"><P CLASS="para">
+If you were to click on the Hydra icon, a window should appear that shows the services that it provides. In this case, the window would be completely empty because there are no shares on the server yet.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-961293">
+4.4.1 Server Configuration Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch04_04.html#ch04-61150">Table 4.3</a> summarizes the server configuration options introduced previously. Note that all three of these options are global in scope; in other words, they must appear in the <CODE CLASS="literal">
+[global]</code> section of the configuration file. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-61150">
+Table 4.3: Server Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+netbios name</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the primary NetBIOS name of the Samba server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Server DNS hostname</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+server string</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a descriptive string for the Samba server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+Samba %v</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+workgroup</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the NetBIOS group of machines that the server belongs to.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Defined at compile time</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955762">
+4.4.1.1 netbios name</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+netbios</code> <CODE CLASS="literal">
+name</code> option allows you to set the NetBIOS name of the server. For example:</p><PRE CLASS="programlisting">
+netbios name = YORKVM1</pre><P CLASS="para">
+The default value for this configuration option is the server's hostname; that is, the first part of its complete DNS machine name. For example, a machine with the DNS name <CODE CLASS="literal">
+ruby.ora.com</code> would be given the NetBIOS name <CODE CLASS="literal">
+RUBY</code> by default. While you can use this option to restate the machine's NetBIOS name in the configuration file (as we did previously), it is more commonly used to assign the Samba server a NetBIOS name other than its current DNS name. Remember that the name given must follow the rules for valid NetBIOS machine names as outlines in <a href="ch01_01.html"><b>Chapter 1, <CITE CLASS="chapter">Learning the Samba</cite></b></a>.</p><P CLASS="para">
+Changing the NetBIOS name of the server is not recommended unless you have a good reason. One such reason might be if the hostname of the machine is not unique because the LAN is divided over two or more DNS domains. For example, YORKVM1 is a good NetBIOS candidate for <i>vm1.york.example.com</i> to differentiate it from <EM CLASS="emphasis">
+vm1.falkirk.example.com</em>, which has the same hostname but resides in a different DNS domain.</p><P CLASS="para">
+Another use of this option is for relocating SMB services from a dead or retired machine. For example, if <CODE CLASS="literal">
+SALES</code> is the SMB server for the department, and it suddenly dies, you could immediately reset <CODE CLASS="literal">
+netbios</code> <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+SALES</code> on a backup Samba machine that's taking over for it. Users won't have to change their drive mappings to a different machine; new connections to <CODE CLASS="literal">
+SALES</code> will simply go to the new machine.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955977">
+4.4.1.2 server string</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+string</code> parameter defines a comment string that will appear next to the server name in both the Network Neighborhood (when shown with the Details menu) and the comment entry of the Microsoft Windows print manager. You can use the standard variables to provide information in the description. For example, our entry earlier was:</p><PRE CLASS="programlisting">
+[global]
+ server string = Samba %v on (%h)</pre><P CLASS="para">
+The default for this option simply presents the current version of Samba and is equivalent to:</p><PRE CLASS="programlisting">
+server string = Samba %v</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-955973">
+4.4.1.3 workgroup</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+workgroup</code> parameter sets the current workgroup where the Samba server will advertise itself. Clients that wish to access shares on the Samba server should be on the same NetBIOS workgroup. Remember that workgroups are really just NetBIOS group names, and must follow the standard NetBIOS naming conventions outlined in <a href="ch01_01.html"><b>Chapter 1</b></a>. For example:</p><PRE CLASS="programlisting">
+[global]
+ workgroup = SIMPLE</pre><P CLASS="para">
+The default option for this parameter is set at compile time. If the entry is not changed in the makefile, it will be <CODE CLASS="literal">
+WORKGROUP</code>. Because this tends to be the workgroup name of every unconfigured NetBIOS network, we recommend that you always set your workgroup name in the Samba configuration file.[<A CLASS="footnote" HREF="#ch04-pgfId-962322">2</a>] </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch04-pgfId-962322">[2]</a> We should also mention that it is an inherently bad idea to have a workgroup that shares the same name as a server.</p></div></blockquote></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_03.html" TITLE="4.3 Configuration File Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.3 Configuration File Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_05.html" TITLE="4.5 Disk Share Configuration">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.5 Disk Share Configuration" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.3 Configuration File Options</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.5 Disk Share Configuration</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_05.html b/docs/htmldocs/using_samba/ch04_05.html
new file mode 100755
index 00000000000..ecb8acfebf4
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_05.html
@@ -0,0 +1,309 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.5 Disk Share Configuration</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:13Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_04.html" TITLE="4.4 Server Configuration">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.4 Server Configuration" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_06.html" TITLE="4.6 Networking Options with Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.6 Networking Options with Samba" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-14274">
+4.5 Disk Share Configuration</a></h2><P CLASS="para">We mentioned in the previous section that there were no disk shares on the <CODE CLASS="literal">
+hydra</code> server. Let's continue with the configuration file and create an empty disk share called [<CODE CLASS="literal">data</code>]. Here are the additions that will do it:</p><PRE CLASS="programlisting">
+[global]
+ netbios name = HYDRA
+ server string = Samba %v on (%L)
+ workgroup = SIMPLE
+
+[data]
+ path = /export/samba/data
+ comment = Data Drive
+ volume = Sample-Data-Drive
+ writeable = yes
+ guest ok = yes</pre><P CLASS="para">
+The <CODE CLASS="literal">
+[data]</code> share is typical for a Samba disk share. The share maps to a directory on the Samba server: <I CLASS="filename">
+/export/samba/data</i>. We've also provided a comment that describes the share as a <CODE CLASS="literal">
+Data</code> <CODE CLASS="literal">
+Drive</code>, as well as a volume name for the share itself.</p><P CLASS="para">
+The share is set to writeable so that users can write data to it; the default with Samba is to create a read-only share. As a result, this option needs to be explicitly set for each disk share you wish to make writeable.</p><P CLASS="para">
+You may have noticed that we set the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> parameter to <CODE CLASS="literal">
+yes</code>. While this isn't very security-conscious, there are some password issues that we need to understand before setting up individual users and authentication. For the moment, this will sidestep those issues and let anyone connect to the share.</p><P CLASS="para">
+Go ahead and make these additions to your configuration file. In addition, create the <I CLASS="filename">
+/export/samba/data</i> directory as root on your Samba machine with the following commands:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">#</code> mkdir /export/samba/data</b><B CLASS="emphasis.bold">
+<CODE CLASS="literal"># </code>chmod 777 /export/samba/data</b></pre><P CLASS="para">
+Now, if you connect to the <CODE CLASS="literal">
+hydra</code> server again (you can do this by clicking on its icon in the Windows Network Neighborhood), you should see a single share listed entitled <CODE CLASS="literal">
+data</code>, as shown in <A CLASS="xref" HREF="ch04_05.html#ch04-13866">
+Figure 4.4</a>. This share should also have read/write access to it. Try creating or copying a file into the share. Or, if you're really feeling adventurous, you can even try mapping a network drive to it! </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-13866">
+Figure 4.4: The initial data share on the Samba server</a></h4><IMG CLASS="graphic" SRC="figs/sam.0404.gif" ALT="Figure 4.4"><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-961433">
+4.5.1 Disk Share Configuration Options</a></h3><P CLASS="para">The basic Samba configuration options for disk shares previously introduced are listed in <A CLASS="xref" HREF="ch04_05.html#ch04-82964">
+Table 4.4</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-82964">
+Table 4.4: Basic Share Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+path (directory)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix directory that will be provided for a disk share or used for spooling by a printer share</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+/tmp</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+guest ok (public)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, authentication is not needed to access this share</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+comment</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the comment that appears with the share</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+volume</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the volume name: the DOS name of the physical drive</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share name</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+read only</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, allows read only access to a share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+writeable (write ok)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+no</code>, allows read only access to a share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-959473">
+4.5.1.1 path</a></h4><P CLASS="para">This option, which has the synonym <CODE CLASS="literal">
+directory</code>, indicates the pathname at the root of the file or printing share. You can choose any path on the Samba server, so long as the owner of the Samba process that is connecting has read and write access to that directory. If the path is for a printing share, it should point to a temporary directory where files can be written on the server before being spooled to the target printer (<I CLASS="filename">/tmp</i> and <I CLASS="filename">
+/var/spool</i> are popular choices). If this path is for a disk share, the contents of the folder representing the share name on the client will match the content of the directory on the Samba server. For example, if we have the following disk share listed in our configuration file:</p><PRE CLASS="programlisting">
+[network]
+ path = /export/samba/network
+ writable = yes
+<CODE CLASS="literal">
+ guest ok = yes</code></pre><P CLASS="para">
+And the contents of the directory <I CLASS="filename">
+/usr/local/network</i> on the Unix side are:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">$</code> ls -al /export/samba/network</b>
+</pre><PRE CLASS="programlisting">
+drwxrwxrwx 9 root nobody 1024 Feb 16 17:17 .
+drwxr-xr-x 9 nobody nobody 1024 Feb 16 17:17 ..
+drwxr-xr-x 9 nobody nobody 1024 Feb 16 17:17 quicken
+drwxr-xr-x 9 nobody nobody 1024 Feb 16 17:17 tax98
+drwxr-xr-x 9 nobody nobody 1024 Feb 16 17:17 taxdocuments</pre><P CLASS="para">
+Then we should see the equivalent of <A CLASS="xref" HREF="ch04_05.html#ch04-88746">
+Figure 4.5</a> on the client side. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-88746">
+Figure 4.5: Windows client view of a network filesystem specified by path</a></h4><IMG CLASS="graphic" SRC="figs/sam.0405.gif" ALT="Figure 4.5"></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-943587">
+4.5.1.2 guest ok</a></h4><P CLASS="para">
+This option (which has an older synonym <CODE CLASS="literal">
+public</code>) allows or prohibits guest access to a share. The default value is <CODE CLASS="literal">
+no</code>. If set to <CODE CLASS="literal">
+yes</code>, it means that no username or password will be needed to connect to the share. When a user connects, the access rights will be equivalent to the designated guest user. The default account to which Samba offers the share is <CODE CLASS="literal">
+nobody</code>. However, this can be reset with the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> configuration option. For example, the following lines allow guest user access to the <CODE CLASS="literal">
+[accounting]</code> share with the permissions of the <EM CLASS="emphasis">
+ftp</em> account:</p><PRE CLASS="programlisting">
+[global]
+ guest account = ftp
+[accounting]
+ path = /usr/local/account
+ guest ok = yes</pre><P CLASS="para">
+Note that users can still connect to the share using a valid username/password combination. If successful, they will hold the access rights granted by their own account and not the guest account. If a user attempts to log in and fails, however, he or she will default to the access rights of the guest account. You can mandate that every user who attaches to the share will be using the guest account (and will have the permissions of the guest) by setting the option <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+only</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-943593">
+4.5.1.3 comment</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+comment</code> option allows you to enter a comment that will be sent to the client when it attempts to browse the share. The user can see the comment by listing Details on the share folder under the appropriate computer in the Windows Network Neighborhood, or type the command <CODE CLASS="literal">
+NET</code> <CODE CLASS="literal">
+VIEW</code> at an MS-DOS prompt. For example, here is how you might insert a comment for a <CODE CLASS="literal">
+[network]</code> share:</p><PRE CLASS="programlisting">
+[network]
+ comment = Network Drive
+ path = /export/samba/network</pre><P CLASS="para">
+This yields a folder similar to <A CLASS="xref" HREF="ch04_05.html#ch04-34850">
+Figure 4.6</a> on the client side. Note that with the current configuration of Windows, this comment will not be shown once a share is mapped to a Windows network drive. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-34850">
+Figure 4.6: Windows client view of a share comment</a></h4><IMG CLASS="graphic" SRC="figs/sam.0406.gif" ALT="Figure 4.6"><P CLASS="para">
+Be sure not to confuse the <CODE CLASS="literal">
+comment</code> option, which documents a Samba server's shares, with the <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+string</code> option, which documents the server itself.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-967445">
+4.5.1.4 volume</a></h4><P CLASS="para">
+This option allows you to specify the volume name of the share as reported by SMB. This normally resolves to the name of the share given in the <I CLASS="filename">
+smb.conf</i> file. However, if you wish to name it something else (for whatever reason) you can do so with this option.</p><P CLASS="para">
+For example, an installer program may check the volume name of a CD-ROM to make sure the right CD-ROM is in the drive before attempting to install it. If you copy the contents of the CD-ROM into a network share, and wish to install from there, you can use this option to get around the issue:</p><PRE CLASS="programlisting">
+[network]
+ comment = Network Drive
+ volume = ASVP-102-RTYUIKA
+ path = /home/samba/network</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-952861">
+4.5.1.5 read only and writeable</a></h4><P CLASS="para">
+The options <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+only</code> and <CODE CLASS="literal">
+writeable</code> (or <CODE CLASS="literal">
+write</code> <CODE CLASS="literal">
+ok</code>) are really two ways of saying the same thing, but approached from opposite ends. For example, you can set either of the following options in the <CODE CLASS="literal">
+[global]</code> section or in an individual share:</p><PRE CLASS="programlisting">
+read only = yes
+writeable = no</pre><P CLASS="para">
+If either option is set as shown, data can be read from a share, but cannot be written to it. You might think you would need this option only if you were creating a read-only share. However, note that this read-only behavior is the <EM CLASS="emphasis">
+default</em> action for shares; if you want to be able to write data to a share, you must explicitly specify one of the following options in the configuration file for each share:</p><PRE CLASS="programlisting">
+read only = no
+writeable = yes</pre><P CLASS="para">
+Note that if you specify more than one occurrence of either option, Samba will adhere to the last value it encounters for the share. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_04.html" TITLE="4.4 Server Configuration">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.4 Server Configuration" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_06.html" TITLE="4.6 Networking Options with Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.6 Networking Options with Samba" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.4 Server Configuration</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.6 Networking Options with Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_06.html b/docs/htmldocs/using_samba/ch04_06.html
new file mode 100755
index 00000000000..897523cc55c
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_06.html
@@ -0,0 +1,414 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.6 Networking Options with Samba</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:15Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_05.html" TITLE="4.5 Disk Share Configuration">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.5 Disk Share Configuration" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_07.html" TITLE="4.7 Virtual Servers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.7 Virtual Servers" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-86705">
+4.6 Networking Options with Samba</a></h2><P CLASS="para">If you're running Samba on a multi-homed machine (that is, one on multiple subnets), or even if you want to implement a security policy on your own subnet, you should take a close look at the networking configuration options: </p><P CLASS="para">
+For the purposes of this exercise, let's assume that our Samba server is connected to a network with more than one subnet. Specifically, the machine can access both the 192.168.220.* and 134.213.233.* subnets. Here are our additions to the ongoing configuration file for the networking configuration options:</p><PRE CLASS="programlisting">
+[global]
+ netbios name = HYDRA
+ server string = Samba %v on (%L)
+ workgroup = SIMPLE
+
+ # Networking configuration options
+ hosts allow = 192.168.220. 134.213.233. localhost
+ hosts deny = 192.168.220.102
+ interfaces = 192.168.220.100/255.255.255.0 \
+ 134.213.233.110/255.255.255.0
+ bind interfaces only = yes
+
+[data]
+ path = /home/samba/data
+ guest ok = yes
+ comment = Data Drive
+ volume = Sample-Data-Drive
+ writeable = yes
+ </pre><P CLASS="para">Let's first talk about the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> options. If these options sound familiar, you're probably thinking of the <I CLASS="filename">
+hosts.allow</i> and <I CLASS="filename">
+hosts.deny</i> files that are found in the <I CLASS="filename">
+/etc</i> directories of many Unix systems. The purpose of these options is identical to those files; they provide a means of security by allowing or denying the connections of other hosts based on their IP addresses. Why not just use the <I CLASS="filename">
+hosts.allow</i> and <I CLASS="filename">
+hosts.deny</i> files themselves? Because there may be services on the server that you want others to access without giving them access Samba's disk or printer shares</p><P CLASS="para">
+With the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option above, we've specified a cropped IP address: 192.168.220. (Note that there is still a third period; it's just missing the fourth number.) This is equivalent to saying: "All hosts on the 192.168.220 subnet." However, we've explicitly specified in a hosts deny line that 192.168.220.102 is not to be allowed access.</p><P CLASS="para">
+You might be wondering: why will 192.168.220.102 be denied even though it is still in the subnet matched by the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option? Here is how Samba sorts out the rules specified by <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code>:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-961914">
+</a>If there are no <CODE CLASS="literal">
+allow</code> or <CODE CLASS="literal">
+deny</code> options defined anywhere in <I CLASS="filename">
+smb.conf</i>, Samba will allow connections from any machine allowed by the system itself.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-961915">
+</a>If there are <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> or <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> options defined in the <CODE CLASS="literal">
+[global]</code> section of <I CLASS="filename">
+smb.conf</i>, they will apply to all shares, even if the shares have an overriding option defined.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-961916">
+</a>If there is only a <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option defined for a share, only the hosts listed will be allowed to use the share. All others will be denied.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-961917">
+</a>If there is only a <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> option defined for a share, any machine which is not on the list will be able to use the share.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-961918">
+</a>If both a <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> option are defined, a host must appear in the allow list and not appear in the deny list (in any form) in order to access the share. Otherwise, the host will not be allowed.</p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Take care that you don't explicitly allow a host to access a share, but then deny access to the entire subnet of which the host is part.</p></blockquote></li></ol><P CLASS="para">
+Let's look at another example of that final item. Consider the following options:</p><PRE CLASS="programlisting">
+hosts allow = 111.222.
+hosts deny = 111.222.333.</pre><P CLASS="para">
+In this case, only the hosts that belong to the subnet 111.222.*.* will be allowed access to the Samba shares. However, if a client belongs to the 111.222.333.* subnet, it will be denied access, even though it still matches the qualifications outlined by <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code>. The client must appear on the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> list and <EM CLASS="emphasis">
+must not</em> appear on the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> list in order to gain access to a Samba share. If a computer attempts to access a share to which it is not allowed access, it will receive an error message.</p><P CLASS="para">
+The other two options that we've specified are the <CODE CLASS="literal">
+interfaces</code> and the <CODE CLASS="literal">
+bind</code> <CODE CLASS="literal">
+interface</code> <CODE CLASS="literal">
+only</code> address. Let's look at the <CODE CLASS="literal">
+interfaces</code> option first. Samba, by default, sends data only from the primary network interface, which in our example is the 192.168.220.100 subnet. If we would like it to send data to more than that one interface, we need to specify the complete list with the <CODE CLASS="literal">
+interfaces</code> option. In the previous example, we've bound Samba to interface with both subnets (192.168.220 and 134.213.233) on which the machine is operating by specifying the other network interface address: 134.213.233.100. If you have more than one interface on your computer, you should always set this option as there is no guarantee that the primary interface that Samba chooses will be the right one.</p><P CLASS="para">
+Finally, the <CODE CLASS="literal">
+bind</code> <CODE CLASS="literal">
+interfaces</code> <CODE CLASS="literal">
+only</code> option instructs the <I CLASS="filename">
+nmbd</i> process not to accept any broadcast messages other than those subnets specified with the <CODE CLASS="literal">
+interfaces</code> option. Note that this is different from the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> options, which prevent machines from making connections to services, but not from receiving broadcast messages. Using the <CODE CLASS="literal">
+bind</code> <CODE CLASS="literal">
+interfaces</code> <CODE CLASS="literal">
+only</code> option is a way to shut out even datagrams from foreign subnets from being received by the Samba server. In addition, it instructs the <EM CLASS="emphasis">
+smbd </em>process to bind to only the interface list given by the <EM CLASS="emphasis">
+interfaces</em> option. This restricts the networks that Samba will serve.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-961674">
+4.6.1 Networking Options</a></h3><P CLASS="para">The networking options we introduced above are summarized in <A CLASS="xref" HREF="ch04_06.html#ch04-32963">
+Table 4.5</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-32963">
+Table 4.5: Networking Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+hosts allow (allow hosts)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of hostnames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the machines that can connect to Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+none</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+hosts deny (deny hosts)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of hostnames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the machines that cannot connect to Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+none</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+interfaces</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of IP/netmask combinations)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the network interfaces Samba will respond to. Allows correcting defaults.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+system-dependent</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+bind</code></p><P CLASS="para">
+<CODE CLASS="literal">
+interfaces only</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, Samba will bind only to those interfaces specified by the <CODE CLASS="literal">
+interfaces</code> option.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+socket</code></p><P CLASS="para">
+<CODE CLASS="literal">
+address</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (IP address)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets IP address to listen on, for use with multiple virtual interfaces on a server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+none</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-961754">
+4.6.1.1 hosts allow</a></h4><P CLASS="para">The <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option (sometimes written as <CODE CLASS="literal">
+allow</code> <CODE CLASS="literal">
+hosts</code>) specifies the machines that have permission to access shares on the Samba server, written as a comma- or space-separated list of names of machines or their IP addresses. You can gain quite a bit of security by simply placing your LAN's subnet address in this option. For example, we specified the following in our example:</p><PRE CLASS="programlisting">
+hosts allow = 192.168.220. localhost</pre><P CLASS="para">
+Note that we placed <CODE CLASS="literal">
+localhost</code> after the subnet address. One of the most common mistakes when attempting to use the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option is to accidentally disallow the Samba server from communicating with itself. The <I CLASS="filename">
+smbpasswd</i> program will occasionally need to connect to the Samba server as a client in order to change a user's encrypted password. In addition, local browsing propagation requires local host access. If this option is enabled and the localhost address is not specified, the locally-generated packets requesting the change of the encrypted password will be discarded by Samba, and browsing propagation will not work properly. To avoid this, explicitly allow the loopback address (either <CODE CLASS="literal">
+localhost</code> or <CODE CLASS="literal">
+127.0.0.1</code>) to be used.[<A CLASS="footnote" HREF="#ch04-pgfId-965714">3</a>] </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch04-pgfId-965714">[3]</a> Starting with Samba 2.0.5, <CODE CLASS="literal">
+localhost</code> will automatically be allowed unless it is explicitly denied.</p></div></blockquote><P CLASS="para">
+You can specify any of the following formats for this option: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959824">
+</a>Hostnames, such as <CODE CLASS="literal">
+ftp.example.com</code>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959825">
+</a>IP addresses, like <CODE CLASS="literal">
+130.63.9.252</code>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959826">
+</a>Domain names, which can be differentiated from individual hostnames because they start with a dot. For example, <CODE CLASS="literal">.ora.com</code> represents all machines within the <EM CLASS="emphasis">
+ora.com</em> domain.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959827">
+</a>Netgroups, which start with an at-sign, such as <CODE CLASS="literal">
+@printerhosts</code>. Netgroups are available on systems running yellow pages/NIS or NIS+, but rarely otherwise. If netgroups are supported on your system, there should be a <CODE CLASS="literal">
+netgroups</code> manual page that describes them in more detail.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959828">
+</a>Subnets, which end with a dot. For example, <CODE CLASS="literal">
+130.63.9.</code> means all the machines whose IP addresses begin with 130.63.9.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959830">
+</a>The keyword <CODE CLASS="literal">
+ALL</code>, which allows any client access.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch04-pgfId-959831">
+</a>The keyword <CODE CLASS="literal">
+EXCEPT</code> followed by more one or more names, IP addresses, domain names, netgroups, or subnets. For example, you could specify that Samba allow all hosts except those on the 192.168.110 subnet with <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+ALL</code> <CODE CLASS="literal">
+EXCEPT</code> <CODE CLASS="literal">
+192.168.110.</code> (remember the trailing dot).</p></li></ul><P CLASS="para">
+Using the <CODE CLASS="literal">
+ALL</code> keyword is almost always a bad idea, since it means that anyone on any network can browse your files if they guess the name of your server. </p><P CLASS="para">
+Note that there is no default value for the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> configuration option, although the default course of action in the event that neither option is specified is to allow access from all sources. In addition, if you specify this option in the <CODE CLASS="literal">
+[global]</code> section of the configuration file, it will override any <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> options defined shares.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-959836">
+4.6.1.2 hosts deny</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> option (also <CODE CLASS="literal">
+deny</code> <CODE CLASS="literal">
+hosts</code>) specifies machines that do not have permission to access a share, written as a comma- or space-separated list of machine names or their IP addresses. Use the same format as specifying clients as the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> option above. For example, to restrict access to the server from everywhere but <I CLASS="filename">
+example.com</i>, you could write:</p><PRE CLASS="programlisting">
+hosts deny = ALL EXCEPT .example.com</pre><P CLASS="para">
+Like <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code>, there is no default value for the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> configuration option, although the default course of action in the event that neither option is specified is to allow access from all sources. Also, if you specify this option in the <CODE CLASS="literal">
+[global]</code> section of the configuration file, it will override any <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> options defined in shares. If you wish to deny <EM CLASS="emphasis">
+hosts</em> access to specific shares, omit both the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> options in the <CODE CLASS="literal">
+[global]</code> section of the configuration file.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-958192">
+4.6.1.3 interfaces</a></h4><P CLASS="para">The <CODE CLASS="literal">
+interfaces</code> option outlines the network addresses to which you want the Samba server to recognize and respond. This option is handy if you have a computer that resides on more than one network subnet. If this option is not set, Samba searches for the primary network interface of the server (typically the first Ethernet card) upon startup and configures itself to operate on only that subnet. If the server is configured for more than one subnet and you do not specify this option, Samba will only work on the first subnet it encounters. You must use this option to force Samba to serve the other subnets on your network.</p><P CLASS="para">
+The value of this option is one or more sets of IP address/netmask pairs, such as the following:</p><PRE CLASS="programlisting">
+interfaces = 192.168.220.100/255.255.255.0 192.168.210.30/255.255.255.0</pre><P CLASS="para">
+You can optionally specify a CIDR format bitmask, as follows:</p><PRE CLASS="programlisting">
+interfaces = 192.168.220.100/24 192.168.210.30/24</pre><P CLASS="para">
+The bitmask number specifies the first number of bits that will be turned on in the netmask. For example, the number 24 means that the first 24 (of 32) bits will be activated in the bit mask, which is the same as saying 255.255.255.0. Likewise, 16 would be equal to 255.255.0.0, and 8 would be equal to 255.0.0.0.</p><P CLASS="para">
+This option may not work correctly if you are using DHCP.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-968052">
+4.6.1.4 bind interfaces only</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+bind</code> <CODE CLASS="literal">
+interfaces</code> <CODE CLASS="literal">
+only</code> option can be used to force the <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em> processes to serve SMB requests to only those addresses specified by the <CODE CLASS="literal">
+interfaces</code> option. The <EM CLASS="emphasis">
+nmbd</em> process normally binds to the all addresses interface (0.0.0.0.) on ports 137 and 138, allowing it to receive broadcasts from anywhere. However, you can override this behavior with the following:</p><PRE CLASS="programlisting">
+bind interfaces only = yes</pre><P CLASS="para">
+This will cause both Samba processes to ignore any packets whose origination address does not match the broadcast address(es) specified by the <CODE CLASS="literal">
+interfaces</code> option, including broadcast packets. With <EM CLASS="emphasis">
+smbd</em>, this option will cause Samba to not serve file requests to subnets other than those listed in the <CODE CLASS="literal">
+interfaces</code> option. You should avoid using this option if you want to allow temporary network connections, such as those created through SLIP or PPP. It's very rare that this option is needed, and it should only be used by experts.</p><P CLASS="para">
+If you set <CODE CLASS="literal">
+bind interfaces only</code> to <CODE CLASS="literal">
+yes</code>, you should add the localhost address (127.0.01) to the "interfaces" list. Otherwise, <EM CLASS="emphasis">
+smbpasswd</em> will be unable to connect to the server using its default mode in order to change a password. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-958204">
+4.6.1.5 socket address</a></h4><P CLASS="para">The <CODE CLASS="literal">
+socket</code> <CODE CLASS="literal">
+address</code> option dictates which of the addresses specified with the <CODE CLASS="literal">
+interfaces</code> parameter Samba should listen on for connections. Samba accepts connections on all addresses specified by default. When used in an <I CLASS="filename">
+smb.conf</i> file, this option will force Samba to listen on only one IP address. For example:</p><PRE CLASS="programlisting">
+interfaces = 192.168.220.100/24 192.168.210.30/24
+socket address = 192.168.210.30</pre><P CLASS="para">
+This option is a programmer's tool and we recommend that you do not use it. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_05.html" TITLE="4.5 Disk Share Configuration">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.5 Disk Share Configuration" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_07.html" TITLE="4.7 Virtual Servers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.7 Virtual Servers" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.5 Disk Share Configuration</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.7 Virtual Servers</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_07.html b/docs/htmldocs/using_samba/ch04_07.html
new file mode 100755
index 00000000000..6f5d495a0b1
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_07.html
@@ -0,0 +1,151 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.7 Virtual Servers</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:17Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_06.html" TITLE="4.6 Networking Options with Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.6 Networking Options with Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_08.html" TITLE="4.8 Logging Configuration Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.8 Logging Configuration Options" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-16899">
+4.7 Virtual Servers</a></h2><P CLASS="para">Virtual servers are a technique for creating the illusion of multiple NetBIOS servers on the network, when in reality there is only one. The technique is simple to implement: a machine simply registers more than one NetBIOS name in association with its IP address. There are tangible benefits to doing this.</p><P CLASS="para">
+The accounting department, for example, might have an <CODE CLASS="literal">
+accounting</code> server, and clients of it would see just the accounting disks and printers. The marketing department could have their own server, <CODE CLASS="literal">
+marketing</code>, with their own reports, and so on. However, all the services would be provided by one medium-sized Unix workstation (and one relaxed administrator), instead of having one small server and one administrator per department.</p><P CLASS="para">
+Samba will allow a Unix server to use more than one NetBIOS name with the <CODE CLASS="literal">
+netbios</code> <CODE CLASS="literal">
+aliases</code> option. See <A CLASS="xref" HREF="ch04_07.html#ch04-92259">
+Table 4.6</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-92259">
+Table 4.6: Virtual Server Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+netbios aliases</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">List of NetBIOS names</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Additional NetBIOS names to respond to, for use with multiple "virtual" Samba servers.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-962377">
+4.7.1 netbios aliases</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+netbios</code> <CODE CLASS="literal">
+aliases</code> option can be used to give the Samba server more than one NetBIOS name. Each NetBIOS name listed as a value will be displayed in the Network Neighborhood of a browsing machine. When a connection is requested to any machine, however, it will connect to the same Samba server.</p><P CLASS="para">
+This might come in handy, for example, if you're transferring three departments' data to a single Unix server with modern large disks, and are retiring or reallocating the old NT servers. If the three servers are called <CODE CLASS="literal">
+sales</code>, <CODE CLASS="literal">
+accounting</code>, and <CODE CLASS="literal">
+admin</code>, you can have Samba represent all three servers with the following options:</p><PRE CLASS="programlisting">
+[global]
+ netbios aliases = sales accounting admin
+ include = /usr/local/samba/lib/smb.conf.%L</pre><P CLASS="para">
+See <A CLASS="xref" HREF="ch04_07.html#ch04-28393">
+Figure 4.7</a> for what the Network Neighborhood would display from a client.When a client attempts to connect to Samba, it will specify the name of the server that it's trying to connect to, which you can access through the <CODE CLASS="literal">
+%L</code> variable. If the requested server is <CODE CLASS="literal">
+sales</code>, Samba will include the <I CLASS="filename">
+/usr/local/samba/lib/smb.conf.sales</i> file. This file might contain global and share declarations exclusively for the sales team, such as the following:</p><PRE CLASS="programlisting">
+[global]
+ workgroup = SALES
+ hosts allow = 192.168.10.255
+
+[sales1998]
+ path = /usr/local/samba/sales/sales1998/
+...</pre><P CLASS="para">
+This particular example would set the workgroup to SALES as well, and set the IP address to allow connections only from the SALES subnet (192.168.10). In addition, it would offer shares specific to the sales department. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch04-28393">
+Figure 4.7: Using NetBIOS aliases for a Samba server </a></h4><IMG CLASS="graphic" SRC="figs/sam.0407.gif" ALT="Figure 4.7"></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_06.html" TITLE="4.6 Networking Options with Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.6 Networking Options with Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_08.html" TITLE="4.8 Logging Configuration Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 4.8 Logging Configuration Options" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.6 Networking Options with Samba</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+4.8 Logging Configuration Options</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch04_08.html b/docs/htmldocs/using_samba/ch04_08.html
new file mode 100755
index 00000000000..7336022e151
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch04_08.html
@@ -0,0 +1,423 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 4] 4.8 Logging Configuration Options</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:18Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_07.html" TITLE="4.7 Virtual Servers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.7 Virtual Servers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch04_01.html" TITLE="4. Disk Shares ">
+Chapter 4<br>
+Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5. Browsing and Advanced Disk Shares " BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch04-29331">
+4.8 Logging Configuration Options</a></h2><P CLASS="para">Occasionally, we need to find out what Samba is up to. This is especially true when Samba is performing an unexpected action or is not performing at all. To find out this information, we need to check Samba's log files to see exactly why it did what it did.</p><P CLASS="para">
+Samba log files can be as brief or verbose as you like. Here is an example of what a Samba log file looks like:</p><PRE CLASS="programlisting">
+[1999/07/21 13:23:25, 3] smbd/service.c:close_cnum(514)
+ phoenix (192.168.220.101) closed connection to service IPC$
+[1999/07/21 13:23:25, 3] smbd/connection.c:yield_connection(40)
+ Yielding connection to IPC$
+[1999/07/21 13:23:25, 3] smbd/process.c:process_smb(615)
+ Transaction 923 of length 49
+[1999/07/21 13:23:25, 3] smbd/process.c:switch_message(448)
+ switch message SMBread (pid 467)
+[1999/07/21 13:23:25, 3] lib/doscalls.c:dos_ChDir(336)
+ dos_ChDir to /home/samba
+[1999/07/21 13:23:25, 3] smbd/reply.c:reply_read(2199)
+ read fnum=4207 num=2820 nread=2820
+[1999/07/21 13:23:25, 3] smbd/process.c:process_smb(615)
+ Transaction 924 of length 55
+[1999/07/21 13:23:25, 3] smbd/process.c:switch_message(448)
+ switch message SMBreadbraw (pid 467)
+[1999/07/21 13:23:25, 3] smbd/reply.c:reply_readbraw(2053)
+ readbraw fnum=4207 start=130820 max=1276 min=0 nread=1276
+[1999/07/21 13:23:25, 3] smbd/process.c:process_smb(615)
+ Transaction 925 of length 55
+[1999/07/21 13:23:25, 3] smbd/process.c:switch_message(448)
+ switch message SMBreadbraw (pid 467) </pre><P CLASS="para">
+Many of these options are of use only to Samba programmers. However, we will go over the meaning of some of these entries in more detail in <a href="ch09_01.html"><b>Chapter 9, <CITE CLASS="chapter">Troubleshooting Samba</cite></b></a>.</p><P CLASS="para">
+Samba contains six options that allow users to describe how and where logging information should be written. Each of these options are global options and cannot appear inside a share definition. Here is an up-to-date configuration file that covers each of the share and logging options that we've seen so far:</p><PRE CLASS="programlisting">
+[global]
+ netbios name = HYDRA
+ server string = Samba %v on (%I)
+ workgroup = SIMPLE
+
+ # Networking configuration options
+ hosts allow = 192.168.220. 134.213.233. localhost
+ hosts deny = 192.168.220.102
+ interfaces = 192.168.220.100/255.255.255.0 \
+ 134.213.233.110/255.255.255.0
+ bind interfaces only = yes
+
+ # Debug logging information
+ log level = 2
+ log file = /var/log/samba.log.%m
+ max log size = 50
+ debug timestamp = yes
+
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ comment = Data Drive
+ volume = Sample-Data-Drive
+ writeable = yes
+ </pre><P CLASS="para">
+ Here, we've added a custom log file that reports information up to debug level 2. This is a relatively light debugging level. The logging level ranges from 1 to 10, where level 1 provides only a small amount of information and level 10 provides a plethora of low-level information. Level 2 will provide us with useful debugging information without wasting disk space on our server. In practice, you should avoid using log levels greater than 3 unless you are programming Samba.</p><P CLASS="para">
+This file is located in the <I CLASS="filename">
+/var/log</i> directory thanks to the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+file</code> configuration option. However, we can use variable substitution to create log files specifically for individual users or clients, such as with the <CODE CLASS="literal">
+%m</code> variable in the following line:</p><PRE CLASS="programlisting">
+log file = /usr/local/logs/samba.log.%m</pre><P CLASS="para">
+Isolating the log messages can be invaluable in tracking down a network error if you know the problem is coming from a specific machine or user.</p><P CLASS="para">
+We've added another precaution to the log files: no one log file can exceed 50 kilobytes in size, as specified by the <CODE CLASS="literal">
+max</code> <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+size</code> option. If a log file exceeds this size, the contents are moved to a file with the same name but with the suffix <EM CLASS="emphasis">
+.old</em> appended. If the <EM CLASS="emphasis">
+.old</em> file already exists, it is overwritten and its contents are lost. The original file is cleared, waiting to receive new logging information. This prevents the hard drive from being overwhelmed with Samba log files during the life of our daemons.</p><P CLASS="para">
+For convenience, we have decided to leave the debug timestamp in the logs with the <CODE CLASS="literal">
+debug</code> <CODE CLASS="literal">
+timestamp</code> option, which is the default behavior. This will place a timestamp next to each message in the logging file. If we were not interested in this information, we could specify <CODE CLASS="literal">
+no</code> for this option instead.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-97929">
+4.8.1 Using syslog</a></h3><P CLASS="para">
+If you wish to use the system logger (<I CLASS="filename">syslog</i>) in addition to or in place of the standard Samba logging file, Samba provides options for this as well. However, to use <I CLASS="filename">
+syslog</i>, the first thing you will have to do is make sure that Samba was built with the <CODE CLASS="literal">
+configure</code> <CODE CLASS="literal">
+--with-syslog</code> option. See <a href="ch02_01.html"><b>Chapter 2</b></a> for more information on configuring and compiling Samba.</p><P CLASS="para">
+Once that is done, you will need to configure your <I CLASS="filename">
+/etc/syslog.conf</i> to accept logging information from Samba. If there is not already a <CODE CLASS="literal">
+daemon.*</code> entry in the <CODE CLASS="replaceable">
+<I>
+/etc/syslog.conf</i></code> file, add the following:</p><PRE CLASS="programlisting">
+daemon.* /var/log/daemon.log</pre><P CLASS="para">
+This specifies that any logging information from system daemons will be stored in the <I CLASS="filename">
+/var/log/daemon.log</i> file. This is where the Samba information will be stored as well. From there, you can specify the following global option in your configuration file:</p><PRE CLASS="programlisting">
+syslog = 2</pre><P CLASS="para">
+This specifies that any logging messages with a level of 1 will be sent to both the <I CLASS="filename">
+syslog</i> and the Samba logging files. (The mappings to <I CLASS="filename">
+syslog</i> priorities are described in the upcoming section "syslog.") Let's assume that we set the regular <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> option above to 4. Any logging messages with a level of 2, 3, or 4 will be sent to the Samba logging files, but not to the <I CLASS="filename">
+syslog</i>. Only level 1 logging messages will be sent to both. If the <CODE CLASS="literal">
+syslog</code> value exceeds the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> value, nothing will be written to the <I CLASS="filename">
+syslog</i>.</p><P CLASS="para">
+If you want to specify that messages be sent only to <I CLASS="filename">
+syslog</i>&nbsp;- and not to the standard Samba logging files&nbsp;- you can place this option in the configuration file:</p><PRE CLASS="programlisting">
+syslog only = yes</pre><P CLASS="para">
+If this is the case, any logging information above the number specified in the <CODE CLASS="literal">
+syslog</code> option will be discarded, just like the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> option.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch04-pgfId-961771">
+4.8.2 Logging Configuration Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch04_08.html#ch04-92838">
+Table 4.7</a> lists each of the logging configuration options that Samba can use. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-92838">
+Table 4.7: Global Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+log file</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified filename)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the name and location of the log file that Samba is to use. Uses standard variables.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specified in Samba makefile</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+log level</code></p><P CLASS="para">
+<CODE CLASS="literal">
+(debug level)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (0-10)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the amount of log/debug messages that are sent to the log file. 0 is none, 3 is considerable.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max log size</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (size in KB)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the maximum size of log file. After the log exceeds this size, the file will be renamed to <EM CLASS="emphasis">
+.bak </em>and a new log file started.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+5000</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+debug</code></p><P CLASS="para">
+<CODE CLASS="literal">
+timestamp (timestamp logs)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If no, doesn't timestamp logs, making them easier to read during heavy debugging.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+syslog</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (0-10)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets level of messages sent to <EM CLASS="emphasis">
+syslog</em>. Those levels below <CODE CLASS="literal">
+syslog level</code> will be sent to the system logger.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+syslog only</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If yes, uses <EM CLASS="emphasis">
+syslog</em> entirely and sends no output to the standard Samba log files.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-log-file-option">
+4.8.2.1 log file</a></h4><P CLASS="para">
+On our server, Samba outputs log information to text files in the <I CLASS="filename">
+var</i> subdirectory of the Samba home directory, as set by the makefile during the build. The <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+file</code> option can be used to reset the name of the log file to another location. For example, to reset the name and location of the Samba log file to <I CLASS="filename">
+/usr/local/logs/samba.log</i>, you could use the following:</p><PRE CLASS="programlisting">
+[global]
+ log file = /usr/local/logs/samba.log</pre><P CLASS="para">
+You may use variable substitution to create log files specifically for individual users or clients.</p><P CLASS="para">
+You can override the default log file location using the <CODE CLASS="literal">
+-l</code> command-line switch when either daemon is started. However, this does not override the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+file</code> option. If you do specify this parameter, initial logging information will be sent to the file specified after <CODE CLASS="literal">
+-l</code> (or the default specified in the Samba makefile) until the daemons have processed the <I CLASS="filename">
+smb.conf</i> file and know to redirect it to a new log file.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-953284">
+4.8.2.2 log level</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> option sets the amount of data to be logged. Normally this is left at 0 or 1. However, if you have a specific problem you may want to set it at 3, which provides the most useful debugging information you would need to track down a problem. Levels above 3 provide information that's primarily for the developers to use for chasing internal bugs, and slows down the server considerably. Therefore, we recommend that you avoid setting this option to anything above 3. </p><PRE CLASS="programlisting">
+[global]
+log file = /usr/local/logs/samba.log.%m
+log level = 3</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-960212">
+4.8.2.3 max log size</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+max</code> <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+size</code> option sets the maximum size, in kilobytes, of the debugging log file that Samba keeps. When the log file exceeds this size, the current log file is renamed to add an <EM CLASS="emphasis">
+.old</em> extension (erasing any previous file with that name) and a new debugging log file is started with the original name. For example:</p><PRE CLASS="programlisting">
+[global]
+log file = /usr/local/logs/samba.log.%m
+max log size = 1000</pre><P CLASS="para">
+Here, if the size of any log file exceeds one megabyte in size, Samba renames the log file <EM CLASS="emphasis">
+samba.log. </em><CODE CLASS="replaceable">
+<I>
+machine-name</i></code><EM CLASS="emphasis">
+.old</em> and a new log file is generated. If there was a file there previously with the <EM CLASS="emphasis">
+.old</em> extension, Samba deletes it. We highly recommend setting this option in your configuration files because debug logging (even at lower levels) can covertly eat away at your available disk space. Using this option protects unwary administrators from suddenly discovering that most of their disk space has been swallowed up by a single Samba log file.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-953294">
+4.8.2.4 debug timestamp or timestamp logs</a></h4><P CLASS="para">
+If you happen to be debugging a network problem and you find that the date-stamp and timestamp information within the Samba log lines gets in the way, you can turn it off by giving either the <CODE CLASS="literal">
+timestamp</code> <CODE CLASS="literal">
+logs</code> or the <CODE CLASS="literal">
+debug</code> <CODE CLASS="literal">
+timestamp</code> option (they're synonymous) a value of <CODE CLASS="literal">
+no</code>. For example, a regular Samba log file presents its output in the following form:</p><PRE CLASS="programlisting">
+12/31/98 12:03:34 hydra (192.168.220.101) connect to server network as user davecb</pre><P CLASS="para">
+With a <CODE CLASS="literal">
+no</code> value for this option, the output would appear without the datestamp or the timestamp:</p><PRE CLASS="programlisting">
+hydra (192.168.220.101) connect to server network as user davecb</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-78696">
+4.8.2.5 syslog</a></h4><P CLASS="para">The <CODE CLASS="literal">
+syslog</code> option causes Samba log messages to be sent to the Unix system logger. The type of log information to be sent is specified as the parameter for this argument. Like the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> option, it can be a number from 0 to 10. Logging information with a level less than the number specified will be sent to the system logger. However, debug logs equal to or above the <CODE CLASS="literal">
+syslog</code> level, but less than log level, will still be sent to the standard Samba log files. To get around this, use the <CODE CLASS="literal">
+syslog</code> <CODE CLASS="literal">
+only</code> option. For example:</p><PRE CLASS="programlisting">
+[global]
+ log level = 3
+ syslog = 1</pre><P CLASS="para">
+With this, all logging information with a level of 0 would be sent to the standard Samba logs and the system logger, while information with levels 1, 2, and 3 would be sent only to the standard Samba logs. Levels above 3 are not logged at all. Note that all messages sent to the system logger are mapped to a priority level that the <EM CLASS="emphasis">
+syslog</em> process understands, as shown in <A CLASS="xref" HREF="ch04_08.html#ch04-80576">
+Table 4.8</a>. The default level is 1. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch04-80576">
+Table 4.8: Syslog Priority Conversion </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Log Level</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Syslog Priority</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+0</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LOG_ERR</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LOG_WARNING</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LOG_NOTICE</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LOG_INFO</code></p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4 and above</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+LOG_DEBUG</code></p></td></tr></tbody></table><P CLASS="para">
+If you wish to use <EM CLASS="emphasis">
+syslog</em>, you will have to run <CODE CLASS="literal">
+configure</code> <CODE CLASS="literal">
+--with-syslog</code> when compiling Samba, and you will need to configure your <I CLASS="filename">
+/etc/syslog.conf</i> to suit. (See the section <A CLASS="xref" HREF="ch04_08.html#ch04-97929">
+Section 4.8.1, Using syslog</a>, earlier in this chapter.)</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch04-pgfId-953338">
+4.8.2.6 syslog only</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+syslog</code> <CODE CLASS="literal">
+only</code> option tells Samba not to use the regular logging files&nbsp;- the system logger only. To enable this, specify the following option in the global ection of the Samba configuration file:</p><PRE CLASS="programlisting">
+[global]
+ syslog only = yes </pre></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_07.html" TITLE="4.7 Virtual Servers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.7 Virtual Servers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5. Browsing and Advanced Disk Shares " BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.7 Virtual Servers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+5. Browsing and Advanced Disk Shares </td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch05_01.html b/docs/htmldocs/using_samba/ch05_01.html
new file mode 100755
index 00000000000..d45bd13f32d
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch05_01.html
@@ -0,0 +1,786 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 5] Browsing and Advanced Disk Shares </title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:41Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_08.html" TITLE="4.8 Logging Configuration Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.8 Logging Configuration Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 5</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_02.html" TITLE="5.2 Filesystem Differences">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.2 Filesystem Differences" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch05-51347">
+5. Browsing and Advanced Disk Shares </a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch05-23763" TITLE="5.1 Browsing">
+Browsing</a><br>
+<A CLASS="sect1" HREF="ch05_02.html" TITLE="5.2 Filesystem Differences">
+Filesystem Differences</a><br>
+<A CLASS="sect1" HREF="ch05_03.html" TITLE="5.3 File Permissions and Attributes on MS-DOS and Unix">
+File Permissions and Attributes on MS-DOS and Unix</a><br>
+<A CLASS="sect1" HREF="ch05_04.html" TITLE="5.4 Name Mangling and Case">
+Name Mangling and Case</a><br>
+<A CLASS="sect1" HREF="ch05_05.html" TITLE="5.5 Locks and Oplocks">
+Locks and Oplocks</a></p><P>
+</p></div><P CLASS="para">This chapter continues our discussion of disk shares from the previous chapter. Here, we will discuss various differences between the Windows and Unix filesystems&nbsp;- and how Samba works to bridge the gap. There are a surprising number of inconsistencies between a DOS filesystem and a Unix filesystem. In addition, we will talk briefly about name mangling, file locking, and a relatively new feature for Samba: opportunistic locking, or oplocks. However, before we move into that territory, we should first discuss the somewhat arcane topic of browsing with Samba.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch05-23763">
+5.1 Browsing</a></h2><P CLASS="para">
+Browsing is the ability to examine the servers and shares that are currently available on your network. On a Windows NT 4.0 or 95/98 client, a user can browse network servers through the Network Neighborhood folder. By double-clicking the icon representing the server, the user should be able to see the printer and disk share resources available on that machine as well. (If you have Windows NT 3.<EM CLASS="emphasis">
+x</em>, you can use the Disk-Connect Network Drive menu in the File Manager to display the available shares on a server.) </p><P CLASS="para">
+From the Windows command line, you can also use the <CODE CLASS="literal">
+net</code> <CODE CLASS="literal">
+view</code> option to see which servers are currently on the network. Here is an example of the <CODE CLASS="literal">
+net</code> <CODE CLASS="literal">
+view</code> command in action:</p><PRE CLASS="programlisting">C:\&gt;<CODE CLASS="userinput"><B> net view</b></code>
+Servers available in workgroup SIMPLE
+Server name Remark
+----------------------------------------------------------
+\\CHIMAERA Windows NT 4.0
+\\HYDRA Samba 2.0.4 on (hydra)
+\\PHOENIX Windows 98</pre><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-962596">
+5.1.1 Preventing Browsing</a></h3><P CLASS="para">You can restrict a share from being in a browse list by using the <CODE CLASS="literal">
+browseable</code> option. This boolean option prevents a share from being seen in the Network Neighborhood at all. For example, to prevent the <CODE CLASS="literal">
+[data]</code> share from the previous chapter from being visible, we could write:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = no
+ guest ok = yes
+ comment = Data Drive
+ volume = Sample-Data-Drive
+ writeable = yes</pre><P CLASS="para">
+Although you typically don't want to do this to an ordinary disk share, the browseable option is useful in the event that you need to create a share with contents that you do not want others to see, such as a <CODE CLASS="literal">
+[netlogin]</code> share for storing logon scripts for Windows domain control (see <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a> for more information on logon scripts).</p><P CLASS="para">
+Another example is the <CODE CLASS="literal">
+[homes]</code> share. This share is often marked non-browsable so that a share named <CODE CLASS="literal">
+[homes]</code> won't appear when its machine's resources are browsed. However, if a user <CODE CLASS="literal">
+alice</code> logs on and looks at the machine's shares, an <CODE CLASS="literal">
+[alice]</code> share will appear under the machine. What if we wanted to make sure <CODE CLASS="literal">
+alice</code>'s share appeared to everyone before she logs in? This could be done with the global <CODE CLASS="literal">
+auto</code> <CODE CLASS="literal">
+services</code> option. This option preloads shares into the browse list to ensure that they are always visible: </p><PRE CLASS="programlisting">
+[global]
+ ...
+ auto services = alice
+ ...</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-962409">
+5.1.2 Default Services</a></h3><P CLASS="para">
+In the event that a user cannot successfully connect to a share, you can specify a default share to which they can connect. Since you do not know who will default to this share at any time, you will probably want to set the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> option to <CODE CLASS="literal">
+yes</code> for this share. Specifying a <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+service</code> can be useful when sending the utterly befuddled to a directory of help files. For example:</p><PRE CLASS="programlisting">
+[global]
+ ...
+ default service = helpshare
+ ...
+
+[helpshare]
+ path = /home/samba/helpshare/%S
+ browseable = yes
+ guest ok = yes
+ comment = Default Share for Unsuccessful Connections
+ volume = Sample-Data-Drive
+ writeable = no</pre><P CLASS="para">
+Note that we used the <CODE CLASS="literal">
+%S</code> variable in the <CODE CLASS="literal">
+path</code> option. If you use the <CODE CLASS="literal">
+%S</code> variable, it will refer to the requested nonexistent share (the original share requested by the user), not the name of the resulting default share. This allows us to create different paths with the names of each server, which can provide more customized help files for users. In addition, any underscores (_) specified in the requested share will be converted to slashes (/) when the <CODE CLASS="literal">
+%S</code> variable is used.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-969505">
+5.1.3 Browsing Elections</a></h3><P CLASS="para">As mentioned in <a href="ch01_01.html"><b>Chapter 1, <CITE CLASS="chapter">Learning the Samba</cite></b></a>, one machine in each subnet always keeps a list of the currently active machines. This list is called the <I CLASS="firstterm">
+browse list</i> and the server that maintains it is called the <I CLASS="firstterm">local master browser</i>. As machines come on and off the network, the local master browser continually updates the information in the browse list and provides it to any machine that requests it.</p><P CLASS="para">
+A computer becomes a local master browser by holding a browsing election on the local subnet. Browsing elections can be called at any time. Samba can rig a browsing election for a variety of outcomes, including always becoming the local master browser of the subnet or never becoming it. For example, the following options, which we've added to the configuration file from <a href="ch04_01.html"><b>Chapter 4, <CITE CLASS="chapter">Disk Shares</cite></b></a>, will ensure that Samba always wins the election for local master browser no matter which machines are also present:</p><PRE CLASS="programlisting">
+[global]
+ netbios name = HYDRA
+ server string = Samba %v on (%L)
+ workgroup = SIMPLE
+
+ # Browsing election options
+ os level = 34
+ local master = yes
+
+ # Networking configuration options
+ hosts allow = 192.168.220. 134.213.233. localhost
+ hosts deny = 192.168.220.102
+ interfaces = 192.168.220.100/255.255.255.0 \
+ 134.213.233.110/255.255.255.0
+
+ # Debug logging information
+ log level = 2
+ log file = /var/log/samba.log.%m
+ max log size = 50
+ debug timestamp = yes
+
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ comment = Data Drive
+ volume = Sample-Data-Drive
+ writable = yes</pre><P CLASS="para">
+However, what if we didn't always want to win the election? What if we wanted to yield browsing to a Windows NT Server if present? In order to do that, we need to learn how browsing elections work. As you already know, each machine that takes place in the election must broadcast information about itself. This information includes the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962259">
+</a>The version of the election protocol used</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962260">
+</a>The operating system on the machine</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962261">
+</a>The amount of time the client has been on the network</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962267">
+</a>The hostname of the client</p></li></ul><P CLASS="para">
+Here is how the election is decided. Operating systems are assigned a binary value according to their version, as shown in <A CLASS="xref" HREF="ch05_01.html#ch05-51423">
+Table 5.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-51423">
+Table 5.1: Operating System Values in an Election </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Operating System</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Value</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Windows NT Server 4.0</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+33</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT Server 3.51</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+32</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT Workstation 4.0</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+17</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT Workstation 3.51</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+16</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 98</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 95</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 3.1 for Workgroups</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td></tr></tbody></table><P CLASS="para">
+Following that, each computer on the network is assigned a separate value according to its role, as shown in <A CLASS="xref" HREF="ch05_01.html#ch05-pgfId-962213">
+Table 5.2</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-pgfId-962213">
+Table 5.2: Computer Role Settings in an Election </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Role</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Value</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Primary Domain Controller</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+128</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+WINS Client</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+32</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Preferred Master Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+8</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Active Master Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+4</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Standby Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+2</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Active Backup Browser</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+1</p></td></tr></tbody></table><P CLASS="para">Elections are decided in the following order:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962245">
+</a>The machine with the highest version of the election protocol will win. (So far, this is meaningless, as all Windows clients have version 1 of the election protocol.)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962246">
+</a>The machine with the highest operating system value wins the election.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962247">
+</a>If there is a tie, the machine with the setting of Preferred Master Browser (role 8) wins the election.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962248">
+</a>If there is still a tie, the client who has been online the longest wins the election.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962282">
+</a>And finally, if there is still a tie, the client name that comes first alphabetically wins.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-969905">
+</a>The machine that is the "runner-up" can become a backup browser.</p></li></ol><P CLASS="para">
+As a result, if you want Samba to take the role of a local master browser, but only if there isn't a Windows NT Server (4.0 or 3.51) on the network, you could change the <CODE CLASS="literal">
+os</code> <CODE CLASS="literal">
+level</code> parameter in the previous example to:</p><PRE CLASS="programlisting">
+os level = 31</pre><P CLASS="para">
+This will cause Samba to immediately lose the election to a Windows NT 4.0 or Windows NT 3.5 Server, both of which have a higher operating systems level. On the other hand, if you wanted to decide the local master browser on the basis of the network role, such as which machine is the primary domain controller, you could set the <CODE CLASS="literal">
+os</code> <CODE CLASS="literal">
+level</code> to match the highest type of operating system on the network and let the election protocol fall down to the next level.</p><P CLASS="para">How can you can tell if a machine is a local master browser? By using the <CODE CLASS="literal">
+nbtstat</code> command. Place the NetBIOS name of the machine you wish to check after the <CODE CLASS="literal">
+-a</code> option:</p><PRE CLASS="programlisting">C:\&gt;<CODE CLASS="userinput"><B> nbtstat -a hydra</b></code>
+
+ NetBIOS Remote Machine Name Table
+
+ Name Type Status
+----------------------------------------------------------
+ HYDRA &lt;00&gt; UNIQUE Registered
+ HYDRA &lt;03&gt; UNIQUE Registered
+ HYDRA &lt;20&gt; UNIQUE Registered
+ ..__MSBROWSE__. &lt;01&gt; GROUP Registered
+ SIMPLE &lt;00&gt; GROUP Registered
+ SIMPLE &lt;1D&gt; UNIQUE Registered
+ SIMPLE &lt;1E&gt; GROUP Registered
+
+ MAC Address = 00-00-00-00-00-00</pre><P CLASS="para">
+The resource entry that you're looking for is the <CODE CLASS="literal">
+..__MSBROWSE__.&lt;01&gt;</code>. This indicates that the server is currently acting as the local master browser for the current subnet. In addition, if the machine is a Samba server, you can check the Samba <I CLASS="filename">
+nmbd</i> log file for an entry such as:</p><PRE CLASS="programlisting">
+nmbd/nmbd_become_lmb.c:become_local_master_stage2(406)
+*****
+Samba name server HYDRA is now a local master browser for
+workgroup SIMPLE on subnet 192.168.220.100
+****</pre><P CLASS="para">
+Finally, Windows NT servers serving as primary domain controllers contain a sneak that allows them to assume the role of the local master browser in certain conditions; this is called the <EM CLASS="emphasis">
+preferred</em> <EM CLASS="emphasis">
+master browser</em> bit. Earlier, we mentioned that Samba could set this bit on itself as well. You can enable it with the <CODE CLASS="literal">
+preferred</code> <CODE CLASS="literal">
+master</code> option:</p><PRE CLASS="programlisting">
+# Browsing election options
+os level = 33
+local master = yes
+preferred master = yes</pre><P CLASS="para">
+If the preferred master bit is set, the machine will force a browsing election at startup. Of course, this is needed only if you set the <CODE CLASS="literal">
+os</code> <CODE CLASS="literal">
+level</code> option to match the Windows NT machine. We recommend that you don't use this option if another machine also has the role of preferred master, such as an NT server. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-962289">
+5.1.4 Domain Master Browser</a></h3><P CLASS="para">In the opening chapter, we mentioned that in order for a Windows workgroup or domain to extend into multiple subnets, one machine would have to take the role of the <I CLASS="firstterm">
+domain master browser</i>. The domain master browser propagates browse lists across each of the subnets in the workgroup. This works because each local master browser periodically synchronizes its browse list with the domain master browser. During this synchronization, the local master browser passes on any server that the domain master browser does not have in its browse list, and vice versa. In a perfect world, each local master browser would eventually have the browse list for the entire domain.</p><P CLASS="para">
+Unlike the local master browser, there is no election to determine which machine assumes the role of the domain master browser. Instead, the administrator has to set it manually. By Microsoft design, however, the domain master browser and the primary domain controller (PDC) both register a resource type of &lt;1B&gt;, so the roles&nbsp;- and the machines&nbsp;- are inseparable. </p><P CLASS="para">
+If you have a Windows NT server on the network acting as a PDC, we recommend that you do not use Samba to become the domain master browser. The reverse is true as well: if Samba is taking on the responsibilities of a PDC, we recommend making it the domain master browser as well. Although it is possible to split the roles with Samba, this is not a good idea. Using two different machines to serve as the PDC and the domain master browser can cause random errors to occur on a Windows workgroup.</p><P CLASS="para">
+Samba can assume the role of a domain master browser for all subnets in the workgroup with the following option:</p><PRE CLASS="programlisting">
+domain master = yes</pre><P CLASS="para">
+You can verify that a Samba machine is in fact the domain master browser by checking the <EM CLASS="emphasis">
+nmbd</em> log file:</p><PRE CLASS="programlisting">
+nmbd/nmbd_become_dmb.c:become_domain_master_stage2(118)
+*****
+Samba name server HYDRA is now a domain master browser for
+workgroup SIMPLE on subnet 192.168.220.100
+*****</pre><P CLASS="para">
+Or you can use the <CODE CLASS="literal">nmblookup</code> command that comes with the Samba distribution to query for a unique &lt;1B&gt; resource type in the workgroup:</p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>nmblookup SIMPLE#1B</b></code>
+Sending queries to 192.168.220.255
+192.168.220.100 SIMPLE&lt;1b&gt;</pre><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-963109">
+5.1.4.1 Multiple subnets</a></h4><P CLASS="para">There are three rules that you must remember when creating a workgroup/domain that spans more than one subnet:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962339">
+</a>You must have either a Windows NT or Samba machine acting as a local master browser on each subnet in the workgroup/domain. (If you have a domain master browser in a subnet, a local master browser is not needed.)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962340">
+</a>You must have a Windows NT Server or a Samba machine acting as a domain master browser somewhere in the workgroup.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-962343">
+</a>Each local master browser must be instructed to synchronize with the domain master browser.</p></li></ul><P CLASS="para">
+Samba has a few other features in this arena in the event that you don't have or want a domain master browser on your network. Consider the subnets shown in <A CLASS="xref" HREF="ch05_01.html#ch05-15706">
+Figure 5.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-15706">
+Figure 5.1: Multiple subnets with Samba servers</a></h4><IMG CLASS="graphic" SRC="figs/sam.0501.gif" ALT="Figure 5.1"><P CLASS="para">
+First, a Samba server that is a local master browser can use the <CODE CLASS="literal">
+remote</code> <CODE CLASS="literal">
+announce</code> configuration option to make sure that computers in different subnets are sent broadcast announcements about the server. This has the effect of ensuring that the Samba server appears in the browse lists of foreign subnets. To achieve this, however, the directed broadcasts must reach the local master browser on the other subnet. Be aware that many routers do not allow directed broadcasts by default; you may have to change this setting on the router for the directed broadcasts to get through to its subnet.</p><P CLASS="para">
+With the <CODE CLASS="literal">
+remote</code> <CODE CLASS="literal">
+announce</code> option, list the subnets and the workgroup that should receive the broadcast. For example, to ensure that machines in the 192.168.221 and 192.168.222 subnets and SIMPLE workgroup are sent broadcast information from our Samba server, we could specify the following:</p><PRE CLASS="programlisting">
+# Browsing election options
+os level = 34
+local master = yes
+remote announce = 192.168.221.255/SIMPLE \
+ 192.168.222.255/SIMPLE</pre><P CLASS="para">
+In addition, you are allowed to specify the exact address to send broadcasts to if the local master browser on the foreign subnet is guaranteed to always have a fixed IP address.</p><P CLASS="para">
+A Samba local master browser can synchronize its browse list directly with another Samba server acting as a local master browser on a different subnet. For example, let's assume that Samba is configured as a local master browser, and Samba local master browsers exist at 192.168.221.130 and 192.168.222.120. We can use the <CODE CLASS="literal">
+remote</code> <CODE CLASS="literal">
+browse</code> <CODE CLASS="literal">
+sync</code> option to sync directly with the Samba servers, as follows:</p><PRE CLASS="programlisting">
+# Browsing election options
+os level = 34
+local master = yes
+remote browse sync = 192.168.221.130 192.168.222.120</pre><P CLASS="para">
+In order for this to work, the other Samba machines must also be local master browsers. You can also use directed broadcasts with this option if you do not know specific IP addresses of local master browsers. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-969941">
+5.1.5 Browsing Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch05_01.html#ch05-81028">Table 5.3</a> shows 14 options that define how Samba handles browsing tasks. We recommend the defaults for a site that prefers to be easy on its users with respect to locating shares and printers. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-81028">
+Table 5.3: Browsing Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+announce as</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+NT</code> or <CODE CLASS="literal">
+Win95</code> or <CODE CLASS="literal">
+WfW</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the operating system that Samba will announce itself as.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+NT</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+announce version</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the version of the operating system that Samba will announce itself as.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+4.2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+browseable (browsable)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows share to be displayed in list of machine resources.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+browse list</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will provide a browse list on this server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+auto services (preload)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (share list)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a list of shares that will always appear in the browse list.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+default service (default)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (share name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Names a share (service) that will be provided if the client requests a share not listed in <EM CLASS="emphasis">
+smb.conf.</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+local master</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will try to become a master browser on the local subnet.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lm announce</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code> or <CODE CLASS="literal">
+no</code> or <CODE CLASS="literal">
+auto</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Enables or disables LAN Manager style host announcements.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+auto</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lm interval</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the frequency in seconds that LAN Manager announcements will be made if activated.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+60</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+preferred master (prefered master)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will use the preferred master browser bit to attempt to become the local master browser.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+domain master</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will try to become the main browser master for the workgroup.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+os level</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the operating system level of Samba in an election for local master browser.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+remote browse sync</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of IP addresses)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Lists Samba servers to synchronize browse lists with.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+remote announce</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (IP address/ workgroup pairs)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Lists subnets and workgroups to send directed broadcast packets to, allowing Samba to appear to browse lists.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959886">
+5.1.5.1 announce as</a></h4><P CLASS="para">
+This global configuration option specifies the type of operating system that Samba will announce to other machines on the network. The default value for this option is <CODE CLASS="literal">
+NT</code>, which represents a Windows NT operating system. Other possible values are <CODE CLASS="literal">
+Win95</code>, which represents a Windows 95 operating system, and <CODE CLASS="literal">
+WfW</code> for a Windows for Workgroup operating system. You can override the default value with the following:</p><PRE CLASS="programlisting">
+[global]
+ announce as = Win95</pre><P CLASS="para">
+We recommend against changing the default value of this configuration option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959896">
+5.1.5.2 announce version</a></h4><P CLASS="para">
+This global option is frequently used with the <CODE CLASS="literal">
+announce</code> <CODE CLASS="literal">
+as</code> configuration option; it specifies the version of the operating system that Samba will announce to other machines on the network. The default value of this options is 4.2, which places itself above the current Windows NT version of 4.0. You can specify a new value with a global entry such as the following:</p><PRE CLASS="programlisting">
+[global]
+ announce version = 4.3</pre><P CLASS="para">
+We recommend against changing the default value of this configuration option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-38345">
+5.1.5.3 browseable</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+browseable</code> option (also spelled <CODE CLASS="literal">
+browsable</code>) indicates whether the share referenced should appear in the list of available resources of the machine on which it resides. This option is always set to <CODE CLASS="literal">
+yes</code> by default. If you wish to prevent the share from being seen in a client's browser, you can reset this option to <CODE CLASS="literal">
+no</code>.</p><P CLASS="para">
+Note that this does not prevent someone from accessing the share using other means, such as specifying a UNC location (<CODE CLASS="literal">//server/accounting)</code> in Windows Explorer. It only prevents the share from being listed under the machine's resources when being browsed.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959474">
+5.1.5.4 browse list</a></h4><P CLASS="para">You should never need to change this parameter from its default value of <CODE CLASS="literal">
+yes</code>. If your Samba server is acting as a local master browser (i.e., it has won the browsing election), you can use the global <CODE CLASS="literal">
+browse</code> <CODE CLASS="literal">
+list</code> option to instruct Samba to provide or withhold its browse list to all clients. By default, Samba always provides a browse list. You can withhold this information by specifying the following:</p><PRE CLASS="programlisting">
+[global]
+ browse list = no</pre><P CLASS="para">
+If you disable the browse list, clients cannot browse the names of other machines, their services, and other domains currently available on the network. Note that this won't make any particular machine inaccessible; if someone knows a valid machine name/address and a share on that machine, they can still connect to it explicitly using NET USE or by mapping a drive letter to it using Windows Explorer. It simply prevents information in the browse list from being retrieved by any client that requests it.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957885">
+5.1.5.5 auto services</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+auto</code> <CODE CLASS="literal">
+services</code> option, which is also called <CODE CLASS="literal">
+preload</code>, ensures that the specified shares are always visible in the browse list. One common use for this option is to advertise specific user or printer shares that are created by the <CODE CLASS="literal">
+[homes]</code> or <CODE CLASS="literal">
+[printers]</code> shares, but are not otherwise browsable.</p><P CLASS="para">
+This option works best with disk shares. If you wish to force each of your system printers (i.e., those listed in the printer capabilities file) into the browse list using this option, we recommend using the <CODE CLASS="literal">
+load</code> <CODE CLASS="literal">
+printers</code> option instead. Any shares listed with the <CODE CLASS="literal">
+auto</code> <CODE CLASS="literal">
+services</code> option will not be displayed if the <CODE CLASS="literal">
+browse</code> <CODE CLASS="literal">
+list</code> option is set to <CODE CLASS="literal">
+no</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-962615">
+5.1.5.6 default service</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+service</code> option (sometimes called <CODE CLASS="literal">
+default</code>) names a "last-ditch" share. If set to an existing share name, and a client requests a nonexistent disk or printer share, Samba will attempt to connect the user to the share specified by this option instead. The option is specified as follows:</p><PRE CLASS="programlisting">
+default service = helpshare</pre><P CLASS="para">
+Note that there are no braces surrounding the share name <CODE CLASS="literal">
+helpshare</code>, even though the definition of the share later in the Samba configuration file will have braces. Also, if you use the <CODE CLASS="literal">
+%S</code> variable in the share specified by this option, it will represent the requested, nonexistent share, not the default service. Any underscores (<CODE CLASS="literal">_</code>) specified in the request share will be converted to slashes (<CODE CLASS="literal">/</code>) when the variable is used.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957903">
+5.1.5.7 local master</a></h4><P CLASS="para">This global option specifies whether Samba will attempt to become the local master browser for the subnet when it starts up. If this option is set to <CODE CLASS="literal">
+yes</code>, Samba will take place in elections. However, setting this option by itself does not guarantee victory. (Other parameters, such as <CODE CLASS="literal">
+preferred</code> <CODE CLASS="literal">
+master</code> and <CODE CLASS="literal">
+os</code> <CODE CLASS="literal">
+level</code> help Samba win browsing elections.) If this option is set to <CODE CLASS="literal">
+no</code>, Samba will lose all browsing elections, no matter which values are specified by the other configuration options. The default value is <CODE CLASS="literal">
+yes</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957907">
+5.1.5.8 lm announce</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+lm</code> <CODE CLASS="literal">
+announce</code> option tells Samba's <EM CLASS="emphasis">
+nmbd</em> whether or not to send LAN Manager host announcements on behalf of the server. These host announcements may be required by older clients, such as IBM's OS/2 operating system. This announcement allows the server to be added to the browse lists of the client. If activated, Samba will announce itself repetitively at the number of seconds specified by the <CODE CLASS="literal">
+lm</code> <CODE CLASS="literal">
+interval</code> option.</p><P CLASS="para">
+This configuration option takes the standard boolean values, <CODE CLASS="literal">
+yes</code> and <CODE CLASS="literal">
+no</code>, which engage or disengage LAN Manager announcements, respectively. In addition, there is a third option, <CODE CLASS="literal">
+auto</code>, which causes <EM CLASS="emphasis">
+nmbd</em> to passively listen for LAN Manager announcements, but not send any of its own initially. If LAN Manager announcements are detected for another machine on the network, <EM CLASS="emphasis">
+nmbd</em> will start sending its own LAN Manager announcements to ensure that it is visible. You can specify the option as follows:</p><PRE CLASS="programlisting">
+[global]
+ lm announce = yes</pre><P CLASS="para">
+The default value is <CODE CLASS="literal">
+auto</code>. You probably won't need to change this value from its default.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959967">
+5.1.5.9 lm interval</a></h4><P CLASS="para">
+This option, which is used in conjunction with <CODE CLASS="literal">
+lm</code> <CODE CLASS="literal">
+announce</code>, indicates the number of seconds <EM CLASS="emphasis">
+nmbd</em> will wait before repeatedly broadcasting LAN Manager-style announcements. Remember that LAN Manager announcements must be activated in order for this option to be used. The default value is 60 seconds. If you set this value to 0, Samba will not send any LAN Manager host announcements, no matter what the value of the <CODE CLASS="literal">
+lm</code> <CODE CLASS="literal">
+announce</code> option. You can reset the value of this option as follows:</p><PRE CLASS="programlisting">
+[global]
+ lm interval = 90</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959947">
+5.1.5.10 preferred master</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+preferred</code> <CODE CLASS="literal">
+master</code> option requests that Samba set the preferred master bit when participating in an election. This gives the server a higher preferred status in the workgroup than other machines at the same operating system level. If you are configuring your Samba machine to become the local master browser, it is wise to set the following value:</p><PRE CLASS="programlisting">
+[global]
+ preferred master = yes</pre><P CLASS="para">
+Otherwise, you should leave it set to its default, <CODE CLASS="literal">
+no</code>. If Samba is configured as a preferred master browser, it will force an election when it first comes online.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957912">
+5.1.5.11 os level</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+os</code> <CODE CLASS="literal">
+level</code> option dictates the operating system level at which Samba will masquerade during a browser election. If you wish to have Samba win an election and become the master browser, you can set the level above that of the operating system on your network with the highest current value. The values are shown in Table 5-1. The default level is 0, which means that Samba will lose all elections. If you wish Samba to win all elections, you can reset its value as follows:</p><PRE CLASS="programlisting">
+os level = 34</pre><P CLASS="para">
+This means that the server will vote for itself 34 times each time an election is called, which ensures a victory.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957960">
+5.1.5.12 domain master</a></h4><P CLASS="para">
+If Samba is the primary domain controller for your workgroup or NT domain, it should also be the domain master browser. The domain master browser is a special machine that has the NetBIOS resource type &lt;1B&gt; and is used to propagate browse lists to and from each of the local master browsers in individual subnets across the domain. To force Samba to become the domain master browser, set the following in the <CODE CLASS="literal">
+[global]</code> section of the <I CLASS="filename">
+smb.conf</i>:</p><PRE CLASS="programlisting">
+[global]
+ domain master = yes</pre><P CLASS="para">
+If you have a Windows NT server on the network acting as a primary domain controller (PDC), we recommend that you do not use Samba to become the domain master browser. The reverse is true as well: if Samba is taking on the responsibilities of a PDC, we recommend making it the domain master browser. Splitting the PDC and the domain master browser will cause unpredictable errors to occur on the network.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957965">
+5.1.5.13 remote browse sync</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+remote</code> <CODE CLASS="literal">
+browse</code> <CODE CLASS="literal">
+sync</code> option specifies that Samba should synchronize its browse lists with local master browsers in other subnets. However, the synchronization can occur only with other Samba servers, and not with Windows computers. For example, if your Samba server was a master browser on the subnet 192.168.235, and Samba local master browsers existed on other subnets at 192.168.234.92 and 192.168.236.2, you could specify the following:</p><PRE CLASS="programlisting">
+remote browse sync = 192.168.234.92 192.168.236.2 </pre><P CLASS="para">
+The Samba server would then directly contact the other machines on the address list and synchronize browse lists. You can also say:</p><PRE CLASS="programlisting">
+remote browse sync = 192.168.234.255 192.168.236.255</pre><P CLASS="para">
+This forces Samba to broadcast queries to determine the IP addresses of the local master browser on each subnet, with which it will then synchronize browse lists. This only works, however, if your router doesn't block directed broadcast requests ending in 255.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-957971">
+5.1.5.14 remote announce</a></h4><P CLASS="para">
+Samba servers are capable of providing browse lists to foreign subnets with the <CODE CLASS="literal">
+remote</code> <CODE CLASS="literal">
+announce</code> option. This is typically sent to the local master browser of the foreign subnet in question. However, if you do not know the address of the local master browser, you can do the following:</p><PRE CLASS="programlisting">
+[global]
+ remote announce = 192.168.234.255/ACCOUNTING \
+ 192.168.236.255/ACCOUNTING</pre><P CLASS="para">
+With this, Samba will broadcast host announcements to all machines on subnets 192.168.234 and 192.168.236, which will hopefully reach the local master browser of the subnet. You can also specify exact IP addresses, if they are known.</p></div></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch04_08.html" TITLE="4.8 Logging Configuration Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 4.8 Logging Configuration Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_02.html" TITLE="5.2 Filesystem Differences">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.2 Filesystem Differences" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+4.8 Logging Configuration Options</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+5.2 Filesystem Differences</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch05_02.html b/docs/htmldocs/using_samba/ch05_02.html
new file mode 100755
index 00000000000..462e23f3c09
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch05_02.html
@@ -0,0 +1,429 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 5] 5.2 Filesystem Differences</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:56Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_01.html" TITLE="5.1 Browsing">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.1 Browsing" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+Chapter 5<br>
+Browsing and Advanced Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_03.html" TITLE="5.3 File Permissions and Attributes on MS-DOS and Unix">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.3 File Permissions and Attributes on MS-DOS and Unix" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch05-34221">
+5.2 Filesystem Differences</a></h2><P CLASS="para">One of the biggest issues for which Samba has to correct is the difference between Unix and non-Unix filesystems. This includes items such as handling symbolic links, hidden files, and dot files. In addition, file permissions can also be a headache if not accounted for properly. This section describes how to use Samba to make up for some of those annoying differences, and even how to add some new functionality of its own.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-963262">
+5.2.1 Hiding and Vetoing Files</a></h3><P CLASS="para">There are some cases when we need to ensure that a user cannot see or access a file at all. Other times, we don't want to keep a user from accessing a file&nbsp;- we just want to hide it when they view the contents of the directory. On Windows systems, an attribute of files allows them to be hidden from a folder listing. With Unix, the traditional way of hiding files in a directory is to precede them with a dot (.). This prevents items such as configuration files or defaults from being seen when performing an ordinary <CODE CLASS="literal">
+ls</code> command. Keeping a user from accessing a file at all, however, involves working with permissions on files and or directories.</p><P CLASS="para">
+The first option we should discuss is the boolean <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+dot</code> <CODE CLASS="literal">
+files</code>. This option does exactly what it says. When set to <CODE CLASS="literal">
+yes</code>, the option treats files beginning with a period (.) as hidden. If set to <CODE CLASS="literal">
+no</code>, those files are always shown. The important thing to remember is that the files are only hidden. If the user has chosen to show all hidden files while browsing (e.g., using the Folder Options menu item under the View menu in Windows 98), they will still be able to see the files, as shown in <A CLASS="xref" HREF="ch05_02.html#ch05-77260">
+Figure 5.2</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-77260">
+Figure 5.2: Hidden files in the [data] share</a></h4><IMG CLASS="graphic" SRC="figs/sam.0502.gif" ALT="Figure 5.2"><P CLASS="para">
+Instead of simply hiding files beginning with a dot, you can also specify a string pattern to Samba for files to hide, using the <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> option. For example, let's assume that we specified the following in our example <CODE CLASS="literal">
+[data]</code> share:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ case sensitive = no
+ hide files = /*.java/*README*/</pre><P CLASS="para">
+Each entry for this option must begin, end, or be separated from another with a slash (/) character, even if there is only one pattern listed. This convention allows spaces to appear in filenames. In this example, the share directory would appear as shown in <A CLASS="xref" HREF="ch05_02.html#ch05-19743">
+Figure 5.3</a>. Again, note that we have set the Windows 98 option to view hidden files for the window. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-19743">
+Figure 5.3: Hiding files based on filename patterns</a></h4><IMG CLASS="graphic" SRC="figs/sam.0503.gif" ALT="Figure 5.3"><P CLASS="para">If we want to prevent users from seeing files at all, we can instead use the <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+files</code> option. This option, which takes the same syntax as the <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> option, specifies a list of files that should never be seen by the user. For example, let's change the <CODE CLASS="literal">
+[data]</code> share to the following:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ case sensitive = no
+ veto files = /*.java/*README*/</pre><P CLASS="para">
+The syntax of this option is identical to the <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> configuration option: each entry must begin, end, or be separated from another with a slash (<CODE CLASS="literal">/</code>) character, even if there is only one pattern listed. By doing so, the files <CODE CLASS="literal">
+hello.java</code> and <CODE CLASS="literal">
+README</code> will simply disappear from the directory, and the user will not be able to access them through SMB. </p><P CLASS="para">
+There is one other question that we need to address. What happens if the user tries to delete a directory that contains vetoed files? This is where the <CODE CLASS="literal">
+delete</code> <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+files</code> option comes in. If this boolean option is set to <CODE CLASS="literal">
+yes</code>, the user is allowed to delete both the regular files and the vetoed files in the directory, and the directory itself will be removed. If the option is set to <CODE CLASS="literal">
+no</code>, the user will not be able to delete the vetoed files, and consequently the directory will not be deleted either. From the user's perspective, the directory will appear to be empty, but cannot be removed.</p><P CLASS="para">
+The <CODE CLASS="literal">
+dont</code> <CODE CLASS="literal">
+descend</code> directive specifies a list of directories whose contents Samba should not allow to be visible. Note that we say <EM CLASS="emphasis">
+contents</em>, not the directory itself. Users will be able to enter a directory marked as such, but they are prohibited from descending the directory tree any farther&nbsp;- they will always see an empty folder. For example, let's use this option with a more basic form of the share that we defined earlier in the chapter:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ case sensitive = no
+ dont descend = config defaults</pre><P CLASS="para">
+In addition, let's assume that the <I CLASS="filename">
+/home/samba/data</i> directory has the following contents:</p><PRE CLASS="programlisting">
+drwxr-xr-x 6 tom users 1024 Jun 13 09:24 .
+drwxr-xr-x 8 root root 1024 Jun 10 17:53 ..
+-rw-r--r-- 2 tom users 1024 Jun 9 11:43 README
+drwxr-xr-x 3 tom users 1024 Jun 13 09:28 config
+drwxr-xr-x 3 tom users 1024 Jun 13 09:28 defaults
+drwxr-xr-x 3 tom users 1024 Jun 13 09:28 market</pre><P CLASS="para">
+If the user then connects to the share, he or she would see the directories shown in <A CLASS="xref" HREF="ch05_02.html#ch05-62659">
+Figure 5.4</a>. However, the contents of the <I CLASS="filename">
+/config</i> and <I CLASS="filename">
+/defaults</i> directories would appear empty to the user, even if other folders or files existed in them. In addition, users cannot write any data to the folder (which prevents them from creating a file or folder with the same name as one that is already there but invisible). If a user attempts to do so, he or she will receive an "Access Denied" message. <CODE CLASS="literal">
+dont</code> <CODE CLASS="literal">
+descend</code> is an administrative option, not a security option, and is not a substitute for good file permissions. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-62659">
+Figure 5.4: Contents of the [data] share with dont descend </a></h4><IMG CLASS="graphic" SRC="figs/sam.0504.gif" ALT="Figure 5.4"></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-963441">
+5.2.2 Links</a></h3><P CLASS="para">DOS and NT filesystems don't have symbolic links; Windows 95/98/NT systems approximate this with "shortcuts" instead. Therefore, when a client tries to open a symbolic link on a Samba server share, Samba attempts to follow the link to find the real file and let the client open it, as if he or she were on a Unix machine. If you don't want to allow this, set the <CODE CLASS="literal">
+follow</code> <CODE CLASS="literal">
+symlinks</code> option:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ case sensitive = no
+ follow symlinks = no</pre><P CLASS="para">
+You can test this by creating a directory on the Unix server inside the share as the user that you are logging in with. Enter the following commands:</p><PRE CLASS="programlisting">
+% <CODE CLASS="userinput"><B>mkdir hello; cd hello</b></code>
+% <CODE CLASS="userinput"><B>cat &quot;This is a test&quot; &gt;hello.txt</b></code>
+% <CODE CLASS="userinput"><B>ln -s hello.txt &quot;Link to hello&quot;</b></code></pre><P CLASS="para">
+This results in the two files shown in the window in <A CLASS="xref" HREF="ch05_02.html#ch05-36377">
+Figure 5.5</a>. Normally, if you click on either one, you will receive a file which has the text "This is a test" inside of it. However, with the <CODE CLASS="literal">
+follow</code> <CODE CLASS="literal">
+symlinks</code> option set to <CODE CLASS="literal">
+no</code>, you should receive an error similar to the dialog in <A CLASS="xref" HREF="ch05_02.html#ch05-36377">
+Figure 5.5</a> if you click on "Link to hello." </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-36377">
+Figure 5.5: An error dialog trying to follow symbolic links when forbidden by Samba</a></h4><IMG CLASS="graphic" SRC="figs/sam.0505.gif" ALT="Figure 5.5"><P CLASS="para">
+Finally, let's discuss the <CODE CLASS="literal">
+wide</code> <CODE CLASS="literal">
+links</code> option. This option, if set to <CODE CLASS="literal">
+yes</code>, allows the client user to follow symbolic links that point outside the shared directory tree, including files or directories at the other end of the link. For example, let's assume that we modified the <CODE CLASS="literal">
+[data]</code> share as follows:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ case sensitive = no
+ follow symlinks = yes
+ wide links = yes</pre><P CLASS="para">
+As long as the <CODE CLASS="literal">
+follow</code> <CODE CLASS="literal">
+symlinks</code> option is enabled, this will cause Samba to follow all symbolic links outside the current share tree. If we create a file outside the share (for example, in someone's home directory) and then create a link to it in the share as follows:</p><PRE CLASS="programlisting">
+ln -s ~tom/datafile ./datafile</pre><P CLASS="para">
+then you will be able to open the file in Tom's directory as per the target file's permissions.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-963127">
+5.2.3 Filesystem Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch05_02.html#ch05-48353">Table 5.4</a> shows a breakdown of the options we discussed earlier. We recommend the defaults for most, except those listed in the following descriptions. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-48353">
+Table 5.4: Filesystem Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+unix realname</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Provides Unix user's full name to client.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+dont descend</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of directories)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates a list of directories whose contents Samba should make invisible to clients.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+follow symlinks</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+no</code>, Samba will not honor symbolic links.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+getwd cache</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, Samba will use a cache for <CODE CLASS="literal">
+getwd()</code> calls.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+wide links</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, Samba will follow symbolic links outside the share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+hide dot files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, treats Unix hidden files as hidden files in Windows.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+hide files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of files)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+List of file patterns to treat as hidden.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+veto files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of files)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+List of file patterns to never show.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+delete veto files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, will delete files matched by <CODE CLASS="literal">
+veto files</code> when the directory they reside in is deleted.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958657">
+5.2.3.1 unix realname</a></h4><P CLASS="para">
+Some programs require a full username in order to operate. For example, a Windows email program often needs to associate a username with a given real name. If your system password file contains the real names of users in the GCOS field, the <CODE CLASS="literal">
+unix</code> <CODE CLASS="literal">
+realname</code> option instructs Samba to provide this information to clients. Without it, the name of the user will simply be his or her login ID. For example, if your Unix password file contains the following line:</p><PRE CLASS="programlisting">
+rcollins:/KaBfco47Rer5:500:500:Robert Collins:
+/home/rcollins:/bin/ksh</pre><P CLASS="para">
+And the option in the configuration file is:</p><PRE CLASS="programlisting">
+[global]
+ unix realname = yes</pre><P CLASS="para">
+then the name Robert Collins will be provided to any client that requests the real name of user <CODE CLASS="literal">
+rcollins</code>. You typically don't need to bother with this option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958929">
+5.2.3.2 dont descend</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+dont</code> <CODE CLASS="literal">
+descend</code> option can be used to specify various directories that should appear empty to the client. Note that the directory itself will still appear. However, Samba will not show any of the contents of the directory to the client user. This is not a good option to use as a security feature (a user could probably find a way around it); it really is meant only as a convenience to keep client users from browsing into directories that might have sensitive files. See our example earlier in this section.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958663">
+5.2.3.3 follow symlinks</a></h4><P CLASS="para">This option, which is discussed in greater detail earlier, controls whether Samba will follow a symbolic link in the Unix operating system to the target, or if it should return an error to the client user. If the option is set to <CODE CLASS="literal">
+yes</code>, the target of the link will be interpreted as the file.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-963512">
+5.2.3.4 getwd cache</a></h4><P CLASS="para">
+This global option specifies whether Samba should use a local cache for the Unix <CODE CLASS="literal">
+getwd()</code> (get current working directory) system call. You can override the default value of <CODE CLASS="literal">
+yes</code> as follows:</p><PRE CLASS="programlisting">
+[global]
+ getwd cache = no</pre><P CLASS="para">
+Setting this option to <CODE CLASS="literal">
+yes</code> can significantly increase the time it takes to resolve the working directory, especially if the <CODE CLASS="literal">
+wide</code> <CODE CLASS="literal">
+links</code> option is set to <CODE CLASS="literal">
+no</code>. You should normally not need to alter this option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-960186">
+5.2.3.5 wide links</a></h4><P CLASS="para">
+This option specifies whether the client user can follow symbolic links that point outside the shared directory tree. This includes any files or directories at the other end of the link, as long as the permissions are correct for the user. The default value for this option is <CODE CLASS="literal">
+yes</code>. Note that this option will not be honored if the <CODE CLASS="literal">
+follow</code> <CODE CLASS="literal">
+symlinks</code> options is set to <CODE CLASS="literal">
+no</code>. Setting this option to <CODE CLASS="literal">
+no</code> slows <EM CLASS="emphasis">
+smbd</em> considerably.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958655">
+5.2.3.6 hide files</a></h4><P CLASS="para">The <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> option provides one or more directory or filename patterns to Samba. Any file matching this pattern will be treated as a hidden file from the perspective of the client. Note that this simply means that the DOS hidden attribute is set, which may or may not mean that the user can actually see it while browsing.</p><P CLASS="para">
+Each entry in the list must begin, end, or be separated from another entry with a slash (<CODE CLASS="literal">/</code>) character, even if there is only one pattern listed. This allows spaces to appear in the list. Asterisks can be used as a wildcard to represent zero or more characters. Questions marks can be used to represent exactly one character. For example:</p><PRE CLASS="programlisting">
+hide files = /.jav*/README.???/</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-963549">
+5.2.3.7 hide dot files</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+dot</code> <CODE CLASS="literal">
+files</code> option hides any files on the server that begin with a dot (.) character, in order to mimic the functionality behind several shell commands that are present on Unix systems. Like <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code>, those files that begin with a dot have the DOS hidden attribute set, which doesn't necessarily guarantee that a client cannot view them. The default value for this option is <CODE CLASS="literal">
+yes</code>. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-963556">
+5.2.3.8 veto files</a></h4><P CLASS="para">
+More stringent than the hidden files state is the state provided by the <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+files</code> configuration option. Samba won't even admit these files exist. You cannot list or open them from the client. In reality, this isn't a trustworthy security option. It is actually a mechanism to keep PC programs from deleting special files, such as ones used to store the resource fork of a Macintosh file on a Unix filesystem. If both Windows and Macs are sharing the same files, this can prevent ill-advised power users from removing files the Mac users need.</p><P CLASS="para">
+The syntax of this option is identical to that of the <CODE CLASS="literal">
+hide</code> <CODE CLASS="literal">
+files</code> configuration option: each entry must begin, end, or be separated from another with a slash (/) character, even if only one pattern is listed. Asterisks can be used as a wildcard to represent zero or more characters. Questions marks can be used to represent exactly one character. For example:</p><PRE CLASS="programlisting">
+veto files = /*config/*default?/</pre><P CLASS="para">
+This option is primarily administrative&nbsp;- not a substitute for good file permissions.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958851">
+5.2.3.9 delete veto files</a></h4><P CLASS="para">This option tells Samba to delete vetoed files when a user attempts to delete the directory in which they reside. The default value is <CODE CLASS="literal">
+no</code>. This means if a user tries to delete a directory that contains a vetoed file, the file (and the directory) will not be deleted. Instead, the directory will remain and appear to be empty from the perspective of the user. If set to <CODE CLASS="literal">
+yes</code>, the directory and the vetoed files will be deleted.</p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_01.html" TITLE="5.1 Browsing">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.1 Browsing" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_03.html" TITLE="5.3 File Permissions and Attributes on MS-DOS and Unix">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.3 File Permissions and Attributes on MS-DOS and Unix" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+5.1 Browsing</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+5.3 File Permissions and Attributes on MS-DOS and Unix</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch05_03.html b/docs/htmldocs/using_samba/ch05_03.html
new file mode 100755
index 00000000000..aaa5648c6cb
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch05_03.html
@@ -0,0 +1,426 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 5] 5.3 File Permissions and Attributes on MS-DOS and Unix</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:32:58Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_02.html" TITLE="5.2 Filesystem Differences">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.2 Filesystem Differences" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+Chapter 5<br>
+Browsing and Advanced Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_04.html" TITLE="5.4 Name Mangling and Case">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.4 Name Mangling and Case" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch05-34062">
+5.3 File Permissions and Attributes on MS-DOS and Unix</a></h2><P CLASS="para">DOS was never intended to be a multiuser, networked operating system. Unix, on the other hand, was designed that way from the start. Consequently, there are inconsistencies and gaps in coverage between the two filesystems that Samba must not only be aware of, but also provide solutions for. One of the biggest gaps is how Unix and DOS handle permissions with files.</p><P CLASS="para">
+Let's take a look at how Unix assigns permissions. All Unix files have read, write, and execute bits for three classifications of users: owner, group, and world. These permissions can be seen at the extreme left-hand side when a <CODE CLASS="literal">
+ls</code> <CODE CLASS="literal">
+-al</code> command is issued in a Unix directory. For example:</p><PRE CLASS="programlisting">
+-rwxr--r-- 1 tom users 2014 Apr 13 14:11 access.conf </pre><P CLASS="para">
+Windows, on the other hand, has four principal bits that it uses with any file: read-only, system, hidden, and archive. You can view these bits by right-clicking on the file and choosing the Properties menu item. You should see a dialog similar to <A CLASS="xref" HREF="ch05_03.html#ch05-76568">
+Figure 5.6</a>.[<A CLASS="footnote" HREF="#ch05-pgfId-964268">1</a>] </p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch05-pgfId-964268">[1]</a> The system checkbox will probably be greyed for your file. Don't worry about that&nbsp;- you should still be able to see when the box is checked and when it isn't.</p></div></blockquote><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-76568">
+Figure 5.6: DOS and Windows file properties</a></h4><IMG CLASS="graphic" SRC="figs/sam.0506.gif" ALT="Figure 5.6"><P CLASS="para">
+The definition of each of those bits follows:</p><DL CLASS="variablelist">
+<DT CLASS="term">Read-only</dt><DD CLASS="listitem">
+<P CLASS="para">
+The file's contents can be read by a user but cannot be written to. </p></dd><DT CLASS="term">System</dt><DD CLASS="listitem">
+<P CLASS="para">
+This file has a specific purpose required by the operating system.</p></dd><DT CLASS="term">Hidden</dt><DD CLASS="listitem">
+<P CLASS="para">
+This file has been marked to be invisible to the user, unless the operating systems is explicitly set to show it.</p></dd><DT CLASS="term">Archive</dt><DD CLASS="listitem">
+<P CLASS="para">
+This file has been touched since the last DOS backup was performed on it.</p></dd></dl><P CLASS="para">
+Note that there is no bit to specify that a file is executable. DOS and Windows NT filesystems identify executable files by giving them the extensions .EXE, .COM, .CMD, or .BAT.</p><P CLASS="para">
+Consequently, there is no use for any of the three Unix executable bits that are present on a file in a Samba disk share. DOS files, however, have their own attributes that need to be preserved when they are stored in a Unix environment: the archive, system, and hidden bits. Samba can preserve these bits by reusing the executable permission bits of the file on the Unix side&nbsp;- if it is instructed to do so. Mapping these bits, however, has an unfortunate side-effect: if a Windows user stores a file in a Samba share, and you view it on Unix with the <CODE CLASS="literal">
+ls</code> <CODE CLASS="literal">
+-al</code> command, some of the executable bits won't mean what you'd expect them to.</p><P CLASS="para">
+Three Samba options decide whether the bits are mapped: <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+archive</code>, <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+system</code>, and <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+hidden</code>. These options map the archive, system, and hidden attributes to the owner, group, and world execute bits of the file, respectively. You can add these options to the <CODE CLASS="literal">
+[data]</code> share, setting each of their values as follows:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ map archive = yes
+ map system = yes
+ map hidden = yes</pre><P CLASS="para">
+After that, try creating a file in the share under Unix&nbsp;- such as <CODE CLASS="literal">
+hello.java</code>&nbsp;- and change the permissions of the file to 755. With these Samba options set, you should be able to check the permissions on the Windows side and see that each of the three values has been checked in the Properties dialog box. What about the read-only attribute? By default, Samba 2.0 sets this whenever a file does not have the Unix owner write permission bit set. In other words, you can set this bit by changing the permissions of the file to 555.</p><P CLASS="para">
+We should warn you that the default value of the <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+archive</code> option is <CODE CLASS="literal">
+yes</code>, while the other two options have a default value of <CODE CLASS="literal">
+no</code>. This is because many programs do not work properly if the archive bit is not stored correctly for DOS and Windows files. The system and hidden attributes, however, are not critical for a program's operation and are left to the discretion of the administrator.</p><P CLASS="para">
+<A CLASS="xref" HREF="ch05_03.html#ch05-56404">
+Figure 5.7</a> summarizes the Unix permission bits and illustrates how Samba maps those bits to DOS attributes. Note that the group read/write and world read/write bits do not directly translate to a DOS attribute, but they still retain their original Unix definitions on the Samba server. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-56404">
+Figure 5.7: How Samba and Unix view the permissions of a file</a></h4><IMG CLASS="graphic" SRC="figs/sam.0507.gif" ALT="Figure 5.7"><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-964095">
+5.3.1 Creation masks</a></h3><P CLASS="para">
+Samba has several options to help with file creation masks. File creation masks (or <I CLASS="firstterm">
+umasks</i>) help to define the permissions a file or directory will receive at the time it is created. In Unix, this means that you can control what permissions a file or directory does not have when it is created. For files accessed from Windows, this means you can disable the read-only, archive, system, and hidden attributes of a file as well.</p><P CLASS="para">
+For example, the <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+mask</code> option will force the permissions of a file created by a Windows client to be at most 744:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ create mask = 744</pre><P CLASS="para">
+while the <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+mask</code> option shown here will force the permissions of a newly created directory to be at most 755:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+ directory mask = 755</pre><P CLASS="para">
+Alternatively, you can also force various bits with the <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+mode</code> and <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+mode</code> options. These options will perform a logical OR against the file and directory creation masks, ensuring that those bits that are specified will always be set. You would typically set these options globally in order to ensure that group and world read/write permissions have been set appropriately for new files or directories in each share.</p><P CLASS="para">
+In the same spirit, if you wish to explicitly set the Unix user and group attributes of a file that is created on the Windows side, you can use the <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+user</code> and <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+group</code> options. For example:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+
+ create mask = 744
+ directory mask = 755
+ force user = joe
+ force group = accounting</pre><P CLASS="para">
+These options actually assign a static Unix user and group to each connection that is made to a share. However, this occurs <EM CLASS="emphasis">
+after</em> the client authenticates; it does not allow free access to a share. These options are frequently used for their side effects of assigning a specific user and group to each new file or directory that is created in a share. Use these options with discretion.</p><P CLASS="para">
+Finally, one of the capabilities of Unix that DOS lacks is the ability to delete a read-only file from a writable directory. In Unix, if a directory is writable, a read-only file in that directory can still be removed. This could permit you to delete files in any of your directories, even if the file was left by someone else.</p><P CLASS="para">
+DOS filesystems are not designed for multiple users, and so its designers decided that read-only means "protected against accidental change, including deletion," rather than "protected against some other user on a single-user machine." So the designers of DOS prohibited removal of a read-only file. Even today, Windows file systems exhibit the same behavior.</p><P CLASS="para">
+Normally, this is harmless. Windows programs don't try to remove read-only files because they know it's a bad idea. However, a number of source-code control programs&nbsp;- which were first written for Unix&nbsp;- run on Windows and require the ability to delete read-only files. Samba permits this behavior with the <CODE CLASS="literal">
+delete</code> <CODE CLASS="literal">
+readonly</code> option. In order to enable this functionality, set the option to <CODE CLASS="literal">
+yes</code>:</p><PRE CLASS="programlisting">
+[data]
+ path = /home/samba/data
+ browseable = yes
+ guest ok = yes
+ writeable = yes
+
+ create mask = 744
+ directory mask = 755
+ force user = joe
+ force group = accounting
+ delete readonly = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-964323">
+5.3.2 File and Directory Permission Options</a></h3><P CLASS="para">The options for file and directory permissions are summarized in <A CLASS="xref" HREF="ch05_03.html#ch05-96508">
+Table 5.5</a>; each option is then described in detail. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-96508">
+Table 5.5: File and Directory Permission Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+map archive</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Preserve DOS archive attribute in user execute bit (0100).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+map system</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Preserve DOS system attribute in group execute bit (0010).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+map hidden</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Preserve DOS hidden attribute in world execute bit (0001).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+create mask (create mode)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the maximum permissions for files created by Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0744</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+directory mask (directory mode)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the maximum permissions for directories created by Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0755</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+force create mode</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Forces the specified permissions (bitwise or) for directories created by Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0000</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+force directory mode</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Forces the specified permissions (bitwise or) for directories created by Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0000</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+force group (group)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (group name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the effective group for a user accessing this share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+force user</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (username)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the effective username for a user accessing this share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+delete readonly</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows a user to delete a read-only file from a writable directory.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961746">
+5.3.2.1 create mask</a></h4><P CLASS="para">
+The argument for this option is an octal number indicating which permission flags may be set at file creation by a client in a share. The default is 0755, which means the Unix owner can at most read, write, and optionally execute his or her own files, while members of the user's group and others can only read or execute them. If you need to change it for non-executable files, we recommend 0644, or <CODE CLASS="literal">
+rw-r--r--</code>. Keep in mind that the execute bits may be used by the server to map certain DOS file attributes, as described earlier. If you're altering the create mask, those bits have to be part of the create mask as well.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961749">
+5.3.2.2 directory mask</a></h4><P CLASS="para">
+The argument for this option is an octal number indicating which permission flags may be set at directory creation by a client in a share. The default is 0755, which allows everyone on the Unix side to at most read and traverse the directories, but allows only you to modify them. We recommend the mask 0750, removing access by world users.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961751">
+5.3.2.3 force create mode</a></h4><P CLASS="para">
+This option sets the permission bits that Samba will force to be set when a file permission change is made. It's often used to force group permissions, mentioned previously. It can also be used to preset any of the DOS attributes we mentioned: archive (0100), system (0010), or hidden (0001). This option always takes effect after the <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+archive</code>, <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+system </code>, <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+hidden</code>, and <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+mask</code> options.</p><P CLASS="para">
+Many Windows applications rename their data files to <EM CLASS="emphasis">
+datafile.bak</em> and create new ones, thus changing their ownership and permissions so that members of the same Unix group can't edit them. Setting <CODE CLASS="literal">
+force create mask = 0660</code> will keep the new file editable by members of the group.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961753">
+5.3.2.4 force directory mode</a></h4><P CLASS="para">
+This option sets the permission bits which Samba will force when a directory permission change is made or a directory is created. It's often used to force group permissions, as mentioned previously. This option defaults to 0000, and can be used just like the <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+mode</code> to add group or other permissions if needed. This option always takes effect after the <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+archive</code>, <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+system</code>, <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+hidden</code>, and <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+mask</code> options.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961755">
+5.3.2.5 force group</a></h4><P CLASS="para">
+This option, sometimes called <CODE CLASS="literal">
+group</code>, assigns a static group ID that will be used on all connections to a service after the client has successfully authenticated. This assigns a specific group to each new file or directory created from an SMB client.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961757">
+5.3.2.6 force user</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+force</code> <CODE CLASS="literal">
+user</code> option assigns a static user ID that will be used on all connections to a service after the client has successfully authenticated. This assigns a specific user to each new file or directory created from an SMB client.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961759">
+5.3.2.7 delete readonly</a></h4><P CLASS="para">This option allows a user to delete a directory containing a read-only file. By default, DOS and Windows will not allow such an operation. You probably will want to leave this option turned off unless a program needs this capability; many Windows users would be appalled to find that they'd accidentally deleted a file which they had set read-only. In fact, even the Unix <CODE CLASS="literal">
+rm</code> command will ask users if they really want to override the protection and delete read-only files. It's a good idea to have Samba be at least as cautious. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961826">
+5.3.2.8 map archive</a></h4><P CLASS="para">
+The DOS archive bit is used to flag a file that has been changed since it was last archived (e.g., backed up with the DOS archive program.) Setting the Samba option <CODE CLASS="literal">
+map</code> <CODE CLASS="literal">
+archive</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> causes the DOS archive flag to be mapped to the Unix execute-by-owner (0100) bit. It's best to leave this option on if your Windows users are doing their own backups, or are using programs that require the archive bit. Unix lacks the notion of an archive bit entirely. Backup programs typically keep a file that lists what files were backed up on what date, so comparing file modification dates serves the same purpose.</p><P CLASS="para">
+Setting this option to <CODE CLASS="literal">
+yes</code> causes an occasional surprise on Unix when a user notices that a data file is marked as executable, but rarely causes harm. If a user tries to run it, he or she will normally get a string of error messages as the shell tries to execute the first few lines as commands. The reverse is also possible; an executable Unix program looks like it hasn't been backed up recently on Windows. But again, this is rare, and is usually harmless. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961836">
+5.3.2.9 map system</a></h4><P CLASS="para">
+The DOS system attribute is used to indicate files that are required by the operating system, and should not be deleted, renamed, or moved without special effort. Set this option only if you need to store Windows system files on the Unix file server. Executable Unix programs will appear to be non-removable special Windows files when viewed from Windows clients. This may prove mildly inconvenient if you want to move or remove one. For most sites, however, this is fairly harmless.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-961845">
+5.3.2.10 map hidden</a></h4><P CLASS="para">DOS uses the hidden attribute to indicate that a file should not ordinarily be visible in directory listings. Unix doesn't have such a facility; it's up to individual programs (notably the shell) to decide what to display and what not to display. Normally, you won't have any DOS files that need to be hidden, so the best thing to do is to leave this option turned off.</p><P CLASS="para">
+Setting this option to <CODE CLASS="literal">
+yes</code> causes the server to map the hidden flag onto the executable-by-others bit (0001). This feature can produce a rather startling effect. Any Unix program that is executable by world seems to vanish when you look for it from a Windows client. If this option is not set, however, and a Windows user attempts to mark a file hidden on a Samba share, it will not work&nbsp;- Samba has no place to store the hidden attribute! </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_02.html" TITLE="5.2 Filesystem Differences">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.2 Filesystem Differences" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_04.html" TITLE="5.4 Name Mangling and Case">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.4 Name Mangling and Case" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+5.2 Filesystem Differences</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+5.4 Name Mangling and Case</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch05_04.html b/docs/htmldocs/using_samba/ch05_04.html
new file mode 100755
index 00000000000..e506445c103
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch05_04.html
@@ -0,0 +1,433 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 5] 5.4 Name Mangling and Case</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:01Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_03.html" TITLE="5.3 File Permissions and Attributes on MS-DOS and Unix">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.3 File Permissions and Attributes on MS-DOS and Unix" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+Chapter 5<br>
+Browsing and Advanced Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_05.html" TITLE="5.5 Locks and Oplocks">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.5 Locks and Oplocks" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch05-30534">
+5.4 Name Mangling and Case</a></h2><P CLASS="para">Back in the days of DOS and Windows 3.1, every filename was limited to eight upper-case characters, followed by a dot, and three more uppercase characters. This was known as the <I CLASS="firstterm">
+8.3 format</i>, and was a huge nuisance. Windows 95/98, Windows NT, and Unix have since relaxed this problem by allowing many more case-sensitive characters to make up a filename. <A CLASS="xref" HREF="ch05_04.html#ch05-24354">
+Table 5.6</a> shows the current naming state of several popular operating systems. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-24354">
+Table 5.6: Operating System Filename Limitations </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Operating System</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+File Naming Rules</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+DOS 6.22 or below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Eight characters followed by a dot followed by a three-letter extension (8.3 format); case insensitive</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 3.1 for Workgroups</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight characters followed by a dot followed by a three-letter extension (8.3 format); case insensitive</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 95/98</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+127 characters; case sensitive</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+127 characters; case sensitive</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Unix</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+255 characters; case sensitive</p></td></tr></tbody></table><P CLASS="para">Samba still has to remain backwards compatible with network clients who store files only in the 8.3 format, such as Windows for Workgroups. If a user creates a file on a share called <EM CLASS="emphasis">
+antidisestablishmentarianism.txt</em>, a Windows for Workgroups client couldn't tell it apart from another file in the same directory called <EM CLASS="emphasis">
+antidisease.txt</em>. Like Windows 95/98 and Windows NT, Samba has to employ a special methodology of translating a long filename to an 8.3 filename in such a way that similar filenames will not cause collisions. This is called <I CLASS="firstterm">
+name mangling</i>, and Samba deals with this in a manner that is similar, but not identical to, Windows 95 and its successors.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-959448">
+5.4.1 The Samba Mangling Operation</a></h3><P CLASS="para">Here is how Samba mangles a long filename into an 8.3 filename:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-959148">
+</a>If the original filename does not begin with a dot, up to the first five alphanumeric characters that occur before the last dot (if there is one) are converted to uppercase. These characters are used as the first five characters of the 8.3 mangled filename.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-959229">
+</a>If the original filename begins with a dot, the dot is removed and up to the first five alphanumeric characters that occur before the last dot (if there is one) are converted to uppercase. These characters are used as the first five characters of the 8.3 mangled filename.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-959228">
+</a>These characters are immediately followed a special mangling character: by default, a tilde (~), although Samba allows you to change this character.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-959149">
+</a>The base of the long filename before the last period is hashed into a two-character code; parts of the name after the last dot may be used if necessary. This two character code is appended to the 8.3 filename after the mangling character.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch05-pgfId-967828">
+</a>The first three characters after the last dot (if there is one) of the original filename are converted to uppercase and appended onto the mangled name as the extension. If the original filename began with a dot, three underscores (<CODE CLASS="literal">___</code>) are used as the extension instead.</p></li></ul><P CLASS="para">
+Here are some examples:</p><PRE CLASS="programlisting">
+virtuosity.dat VIRTU~F1.DAT
+.htaccess HTACC~U0.___
+hello.java HELLO~1F.JAV
+team.config.txt TEAMC~04.TXT
+antidisestablishmentarianism.txt ANTID~E3.TXT
+antidiseast.txt ANTID~9K.TXT</pre><P CLASS="para">
+Using these rules will allow Windows for Workgroups to differentiate the two files on behalf of the poor individual who is forced to see the network through the eyes of that operating system. Note that the same long filename should always hash to the same mangled name with Samba; this doesn't always happen with Windows. The downside of this approach is that there can still be collisions; however, the chances are greatly reduced.</p><P CLASS="para">
+You generally want to use the mangling configuration options with only the oldest clients. We recommend doing this without disrupting other clients by adding an <CODE CLASS="literal">
+include</code> directive to the <I CLASS="filename">
+smb.conf</i> file:</p><PRE CLASS="programlisting">
+[global]
+ include = /ucsr/local/samba/lib/smb.conf.%m</pre><P CLASS="para">
+This resolves to <I CLASS="filename">
+smb.conf.WfWg</i> when a Window for Workgroups client attaches. Now you can create a file <I CLASS="filename">
+/usr/local/samba/lib/smb.conf.WfWg</i> which might contain these options:</p><PRE CLASS="programlisting">
+[global]
+ case sensitive = no
+ default case = upper
+ preserve case = no
+ short preserve case = no
+ mangle case = yes
+ mangled names= yes</pre><P CLASS="para">
+If you are not using Windows for Workgroups 3.1, then you probably do not need to change any of these options from their defaults.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959447">
+5.4.1.1 Representing and resolving filenames with Samba</a></h4><P CLASS="para">Another item that we should point out is that there is a difference between how an operating system <EM CLASS="emphasis">
+represents</em> a file and how it <EM CLASS="emphasis">
+resolves</em> it. For example, if you've used Windows 95/98/NT, you have likely run across a file called <I CLASS="filename">
+README.TXT</i>. The file can be represented by the operating system entirely in uppercase letters. However, if you open an MS-DOS prompt and enter the command <CODE CLASS="literal">
+edit</code> <CODE CLASS="literal">
+readme.txt</code>, the all-caps file is loaded into the editing program, even though you typed the name in lowercase letters!</p><P CLASS="para">
+This is because the Windows 95/98/NT family of operating systems resolves files in a case-insensitive manner, even though the files are represented it in a case-sensitive manner. Unix-based operating systems, on the other hand, always resolve files in a case-sensitive manner; if you try to edit <I CLASS="filename">
+README.TXT</i> with the command <CODE CLASS="literal">
+vi</code> <CODE CLASS="literal">
+readme.txt</code>, you will likely be editing the empty buffer of a new file.</p><P CLASS="para">
+Here is how Samba handles case: if the <CODE CLASS="literal">
+preserve</code> <CODE CLASS="literal">
+case</code> is set to <CODE CLASS="literal">
+yes</code>, Samba will always use the case provided by the operating system for representing (not resolving) filenames. If it is set to <CODE CLASS="literal">
+no</code>, it will use the case specified by the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option. The same is true for <CODE CLASS="literal">
+short</code> <CODE CLASS="literal">
+preserve</code> <CODE CLASS="literal">
+case</code>. If this option is set to <CODE CLASS="literal">
+yes</code>, Samba will use the default case of the operating system for representing 8.3 filenames; otherwise it will use the case specified by the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option. Finally, Samba will always resolve filenames in its shares based on the value of the <CODE CLASS="literal">
+case</code> <CODE CLASS="literal">
+sensitive</code> option.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-970053">
+5.4.2 Mangling Options</a></h3><P CLASS="para">Samba allows you to give it more refined instructions on how it should perform name mangling, including those controlling the case sensitivity, the character inserted to form a mangled name, and the ability to manually map filenames from one format to another. These options are shown in <A CLASS="xref" HREF="ch05_04.html#ch05-47431">
+Table 5.7</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-47431">
+Table 5.7: Name Mangling Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+case sensitive</code></p><P CLASS="para">
+<CODE CLASS="literal">
+(casesignames)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will treat filenames as case-sensitive (Windows doesn't).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+default case</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+(<CODE CLASS="literal">upper</code> or <CODE CLASS="literal">
+lower</code>)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Case to assume as default (only used when preserve case is <CODE CLASS="literal">
+no</code>).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Lower</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+preserve case</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, keep the case the client supplied (i.e., do not convert to <CODE CLASS="literal">
+default case</code>).</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+short preserve case</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, preserve case of 8.3-format names that the client provides.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+mangle case</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Mangle a name if it is mixed case.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+mangled names</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Mangles long names into 8.3 DOS format.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+mangling char</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (single character)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Gives mangling character.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+~</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+mangled stack</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Number of mangled names to keep on the local mangling stack.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+50</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+mangled map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of patterns)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows mapping of filenames from one format into another.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-960977">
+5.4.2.1 case sensitive</a></h4><P CLASS="para">This share-level option, which has the obtuse synonym <CODE CLASS="literal">
+casesignames</code>, specifies whether Samba should preserve case when resolving filenames in a specific share. The default value for this option is <CODE CLASS="literal">
+no</code>, which is how Windows handles file resolution. If clients are using an operating system that takes advantage of case-sensitive filenames, you can set this configuration option to <CODE CLASS="literal">
+yes</code> as shown here:</p><PRE CLASS="programlisting">
+[accounting]
+ case sensitive = yes</pre><P CLASS="para">
+Otherwise, we recommend that you leave this option set to its default.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958897">
+5.4.2.2 default case</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option is used with <CODE CLASS="literal">
+preserve</code> <CODE CLASS="literal">
+case</code>. This specifies the default case (upper or lower) that Samba will use when it creates a file on one of its shares on behalf of a client. The default case is <CODE CLASS="literal">
+lower</code>, which means that newly created files will use the mixed-case names given to them by the client. If you need to, you can override this global option by specifying the following:</p><PRE CLASS="programlisting">
+[global]
+ default case = upper</pre><P CLASS="para">
+If you specify this value, the names of newly created files will be translated into uppercase, and cannot be overridden in a program. We recommend that you use the default value unless you are dealing with a Windows for Workgroups or other 8.3 client, in which case it should be <CODE CLASS="literal">
+upper</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958899">
+5.4.2.3 preserve case</a></h4><P CLASS="para">
+This option specifies whether a file created by Samba on behalf of the client is created with the case provided by the client operating system, or the case specified by the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> configuration option above. The default value is <CODE CLASS="literal">
+yes</code>, which uses the case provided by the client operating system. If it is set to <CODE CLASS="literal">
+no</code>, the value of the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option is used.</p><P CLASS="para">
+Note that this option does not handle 8.3 file requests sent from the client&nbsp;- see the <CODE CLASS="literal">
+short</code> <CODE CLASS="literal">
+preserve</code> <CODE CLASS="literal">
+case</code> option below. You may want to set this option to <CODE CLASS="literal">
+yes</code> if applications that create files on the Samba server are sensitive to the case used when creating the file. If you want to force Samba, for example, to mimic the behavior of a Windows NT filesystem, you can leave this option to its default, <CODE CLASS="literal">
+yes</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958901">
+5.4.2.4 short preserve case</a></h4><P CLASS="para">
+This option specifies whether an 8.3 filename created by Samba on behalf of the client is created with the default case of the client operating system, or the case specified by the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> configuration option. The default value is <CODE CLASS="literal">
+yes</code>, which uses the case provided by the client operating system. You can let Samba choose the case through the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> option by setting it as follows:</p><PRE CLASS="programlisting">
+[global]
+ short preserve case = no</pre><P CLASS="para">
+If you want to force Samba to mimic the behavior of a Windows NT filesystem, you can leave this option set to its default, <CODE CLASS="literal">
+yes</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958984">
+5.4.2.5 mangled names</a></h4><P CLASS="para">
+This share-level option specifies whether Samba will mangle filenames for 8.3 clients in that share. If the option is set to <CODE CLASS="literal">
+no</code>, Samba will not mangle the names and (depending on the client), they will either be invisible or appear truncated to those using 8.3 operating systems. The default value is <CODE CLASS="literal">
+yes</code>. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[data]
+ mangled names = no</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958903">
+5.4.2.6 mangle case</a></h4><P CLASS="para">
+This option tells Samba whether it should mangle filenames that are not composed entirely of the case specified using the <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+case</code> configuration option. The default for this option is <CODE CLASS="literal">
+no</code>. If you set it to <CODE CLASS="literal">
+yes</code>, you should be sure that all clients will be able to handle the mangled filenames that result. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[data]
+ mangle case = yes</pre><P CLASS="para">
+We recommend that you leave this option alone unless you have a well-justified need to change it.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958976">
+5.4.2.7 mangling char</a></h4><P CLASS="para">
+This share-level option specifies the mangling character used when Samba mangles filenames into the 8.3 format. The default character used is a tilde (~). You can reset it to whatever character you wish, for instance:</p><PRE CLASS="programlisting">
+[data]
+ mangling char = #</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959322">
+5.4.2.8 mangled stack</a></h4><P CLASS="para">
+Samba maintains a local stack of recently mangled 8.3 filenames; this stack can be used to reverse map mangled filenames back to their original state. This is often needed by applications that create and save a file, close it, and need to modify it later. The default number of long filename/mangled filename pairs stored on this stack is 50. However, if you want to cut down on the amount of processor time used to mangle filenames, you can increase the size of the stack to whatever you wish, at the expense of memory and slightly slower file access.</p><PRE CLASS="programlisting">
+[global]
+ mangled stack = 100</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959327">
+5.4.2.9 mangled map</a></h4><P CLASS="para">
+If the default behavior of name mangling is not sufficient, you can give Samba further instructions on how to behave using the <CODE CLASS="literal">
+mangled</code> <CODE CLASS="literal">
+map</code> option. This option allows you to specify mapping patterns that can be used before or even in place of name mangling performed by Samba. For example:</p><PRE CLASS="programlisting">
+[data]
+ mangled map =(*.database *.db) (*.class *.cls)</pre><P CLASS="para">
+Here, Samba is instructed to search each file it encounters for characters that match the first pattern specified in the parenthesis and convert them to the modified second pattern in the parenthesis for display on an 8.3 client. This is useful in the event that name mangling converts the filename incorrectly or to a format that the client cannot understand readily. Patterns are separated by whitespaces. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_03.html" TITLE="5.3 File Permissions and Attributes on MS-DOS and Unix">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.3 File Permissions and Attributes on MS-DOS and Unix" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_05.html" TITLE="5.5 Locks and Oplocks">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 5.5 Locks and Oplocks" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+5.3 File Permissions and Attributes on MS-DOS and Unix</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+5.5 Locks and Oplocks</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch05_05.html b/docs/htmldocs/using_samba/ch05_05.html
new file mode 100755
index 00000000000..b0298624f87
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch05_05.html
@@ -0,0 +1,399 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 5] 5.5 Locks and Oplocks</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:03Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_04.html" TITLE="5.4 Name Mangling and Case">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.4 Name Mangling and Case" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch05_01.html" TITLE="5. Browsing and Advanced Disk Shares ">
+Chapter 5<br>
+Browsing and Advanced Disk Shares </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6. Users, Security, and Domains " BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch05-75933">
+5.5 Locks and Oplocks</a></h2><P CLASS="para">Concurrent writes to a single file are not desirable in any operating system. To prevent this, most operating systems use <I CLASS="firstterm">
+locks</i> to guarantee that only one process can write to a file at a time. Operating systems traditionally lock entire files, although newer ones allow a range of bytes within a file to be locked. If another process attempts to write to a file (or section of one) that is already locked, it will receive an error from the operating system and will wait until the lock is released.</p><P CLASS="para">
+Samba supports the standard DOS and NT filesystem (deny-mode) locking requests, which allow only one process to write to an entire file on a server at a give time, as well as byte-range locking. In addition, Samba supports a new locking mechanism known in the Windows NT world as <I CLASS="firstterm">
+opportunistic locking&nbsp;- </i><EM CLASS="emphasis">
+oplock</em> for short.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-964663">
+5.5.1 Opportunistic Locking</a></h3><P CLASS="para">
+Opportunistic locking allows a client to notify the Samba server that it will not only be the exclusive writer of a file, but will also cache its changes to that file on its own machine (and not on the Samba server) in order to speed up file access for that client. When Samba knows that a file has been opportunistically locked by a client, it marks its version as having an opportunistic lock and waits for the client to complete work on the file, at which point it expects the client to send the final changes back to the Samba server for synchronization.</p><P CLASS="para">
+If a second client requests access to that file before the first client has finished working on it, Samba can send an <I CLASS="firstterm">
+oplock break</i> request to the first client. This tells the client to stop caching its changes and return the current state of the file to the server so that the interrupting client can use it as it sees fit. An opportunistic lock, however, is not a replacement for a standard deny-mode lock. It is not unheard of for the interrupting process to be granted an oplock break only to discover that the original process also has a deny-mode lock on a file as well. <A CLASS="xref" HREF="ch05_05.html#ch05-74304">
+Figure 5.8</a> illustrates this opportunistic locking process. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch05-74304">
+Figure 5.8: Opportunistic locking</a></h4><IMG CLASS="graphic" SRC="figs/sam.0508.gif" ALT="Figure 5.8"><P CLASS="para">
+In terms of locks, we highly recommend using the defaults provided by Samba: standard DOS/Windows deny-mode locks for compatibility and oplocks for the extra performance that local caching allows. If your operating system can take advantage of oplocks, it should provide significant performance improvements. Unless you have a specific reason for changing any of these options, it's best to leave them as they are.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch05-pgfId-969392">
+5.5.2 Unix and Locking</a></h3><P CLASS="para">Windows systems cooperate well to avoid overwriting each other's changes. But if a file stored on a Samba system is accessed by a Unix process, this process won't know a thing about Windows oplocks and could easily ride roughshod over a lock. Some Unix systems have been enhanced to understand the Windows oplocks maintained by Samba. Currently the support exists only in SGI Irix 6.5.2f and later; Linux and FreeBSD should soon follow.</p><P CLASS="para">
+If you have a system that understands oplocks, set <CODE CLASS="literal">
+kernel</code> <CODE CLASS="literal">
+oplocks</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in the Samba configuration file. That should eliminate conflicts between Unix processes and Windows users. </p><P CLASS="para">
+If your system does not support kernel oplocks, you could end up with corrupted data when somebody runs a Unix process that reads or writes a file that Windows users also access. However, Samba provides a rough protection mechanism in the absence of kernel oplocks: the <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+oplock</code> <CODE CLASS="literal">
+files</code> option. If you can anticipate which Samba files are used by both Windows users and Unix users, set their names in a <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+oplock</code> <CODE CLASS="literal">
+files</code> option. This will suppress the use of oplocks on matching filenames, which will supress client caching, and let the Windows and Unix programs use system locking or update times to detect competition for the same file. A sample option is: </p><PRE CLASS="programlisting">
+veto oplock files = /*.dbm/</pre><P CLASS="para">
+This option allows both Unix processes and Windows users to edit files ending in the suffix <EM CLASS="emphasis">
+.dbm</em>. Note that the syntax of this option is similar to <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+files</code>.</p><P CLASS="para">
+Samba's options for locks and oplocks are given in <A CLASS="xref" HREF="ch05_05.html#ch05-53407">
+Table 5.8</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-53407">
+Table 5.8: Locks and Oplocks Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+share modes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, turns on support for DOS-style whole-file locks.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+locking</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, turns on byte-range locks.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+strict locking</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, denies access to an entire file if a byte-range lock exists in it.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+oplocks</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, turn on local caching of files on the client for this share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+kernel oplocks</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, indicates that the kernel supports oplocks.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+fake oplocks</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, tells client the lock was obtained, but doesn't actually lock it.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+blocking locks </code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows lock requestor to wait for the lock to be granted.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+veto oplock files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of filenames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Does not oplock specified files.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lock directory</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the location where various Samba files, including locks, are stored.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+As specified in Samba makefile</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958552">
+5.5.2.1 share modes</a></h4><P CLASS="para">
+The most primitive locks available to Samba are deny-mode locks, known as <I CLASS="firstterm">
+share modes</i>, which are employed by programs such as text editors to avoid accidental overwriting of files. For reference, the deny-mode locks are listed in <A CLASS="xref" HREF="ch05_05.html#ch05-55885">
+Table 5.9</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch05-55885">
+Table 5.9: SMB Deny-Mode Locks </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Lock</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Description</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_NONE</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Do not deny any other file requests.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_ALL</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deny all open requests on the current file.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_READ</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deny any read-only open requests on the current file.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_WRITE</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Deny any write-only open requests on the current file.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_DOS</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If opened for reading, others can read but cannot write to the file. If opened for writing, others cannot open the file at all.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+DENY_FCB</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Obsolete.</p></td></tr></tbody></table><P CLASS="para">
+The <CODE CLASS="literal">
+share</code> <CODE CLASS="literal">
+modes</code> parameter, which enforces the use of these locks, is enabled by default. To disable it, use the following command:</p><PRE CLASS="programlisting">
+[accounting]
+ share modes = no</pre><P CLASS="para">
+We highly recommend against disabling the default locking mechanism unless you have a justifiable reason for doing so. Most Windows and DOS applications rely on these locking mechanisms in order to work correctly, and will complain bitterly if this functionality is taken away.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958557">
+5.5.2.2 locking</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+locking</code> option can be used to tell Samba to engage or disengage server-side byte-range locks on behalf of the client. Samba implements byte-range locks on the server side with normal Unix advisory locks and will consequently prevent other properly-behaved Unix processes from overwriting a locked byte range.</p><P CLASS="para">
+This option can be specified per share as follows:</p><PRE CLASS="programlisting">
+[accounting]
+ locking = yes</pre><P CLASS="para">
+If the <CODE CLASS="literal">
+locking</code> option is set to <CODE CLASS="literal">
+yes</code>, the requestor will be delayed until the holder of either type of lock releases it (or crashes). If, however, the option is set to <CODE CLASS="literal">
+no</code>, no byte-range locks will be kept for the files, although requests to lock and unlock files will appear to succeed. The option is set to <CODE CLASS="literal">
+yes</code> by default; however, you can turn this option off if you have read-only media.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-959694">
+5.5.2.3 strict locking</a></h4><P CLASS="para">
+This option checks every file access for a byte-range lock on the range of bytes being accessed. This is typically not needed if a client adheres to all the locking mechanisms in place. This option is set to <CODE CLASS="literal">
+no</code> by default; however, you can reset it per share as follows:</p><PRE CLASS="programlisting">
+[accounting]
+ strict locking = yes</pre><P CLASS="para">
+If this option is set to <CODE CLASS="literal">
+yes</code>, mandatory locks are enforced on any file with byte-range locks.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958563">
+5.5.2.4 blocking locks</a></h4><P CLASS="para">
+Samba also supports <I CLASS="firstterm">
+blocking locks</i>, a minor variant of range locks. Here, if the range of bytes is not available, the client specifies an amount of time that it's willing to wait. The server then caches the lock request, periodically checking to see if the file is available. If it is, it notifies the client; however, if time expires, Samba will tell the client that the request has failed. This strategy prevents the client from continually polling to see if the lock is available.</p><P CLASS="para">
+You can disable this option per share as follows:</p><PRE CLASS="programlisting">
+[accounting]
+ blocking locks = no</pre><P CLASS="para">
+When set to <CODE CLASS="literal">
+yes</code>, blocking locks will be enforced on the file. If this option is set to <CODE CLASS="literal">
+no</code>, Samba behaves as if normal locking mechanisms are in place on the file. The default is <CODE CLASS="literal">
+yes</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958571">
+5.5.2.5 oplocks</a></h4><P CLASS="para">
+This option enables or disables support for oplocks on the client. The option is enabled by default. However, you can disable it with the following command:</p><PRE CLASS="programlisting">
+[data]
+ oplocks = no</pre><P CLASS="para">
+If you are in an extremely unstable network environment or have many clients that cannot take advantage of opportunistic locking, it may be better to shut this Samba feature off. Oplocks should be disabled if you are accessing the same files from both Unix applications (such as <EM CLASS="emphasis">
+vi</em>) and SMB clients (unless you are lucky enough to have an operating system that supports kernel oplocks as discussed earlier).</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958575">
+5.5.2.6 fake oplocks</a></h4><P CLASS="para">
+Before opportunistic locking was available on Samba, the Samba daemons pretended to allow oplocks via the <CODE CLASS="literal">
+fake</code> <CODE CLASS="literal">
+oplocks</code> option. If this option was enabled, all clients were told that the file is available for opportunistic locking, and never warned of simultaneous access. This option is deprecated now that real oplocks are available on Samba.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958577">
+5.5.2.7 kernel oplocks</a></h4><P CLASS="para">
+If a Unix application separate from Samba tries to update a file that Samba has oplocked to a Windows client, it will likely succeed (depending on the operating system) and both Samba and the client will never be aware of it. However, if the local Unix operating system supports it, Samba can warn it of oplocked files, which can suspend the Unix process, notify the client via Samba to write its copy back, and only then allow the open to complete. Essentially, this means that the operating system kernel on the Samba system has the ability to handle oplocks as well as Samba.</p><P CLASS="para">
+You can enable this behavior with the <CODE CLASS="literal">
+kernel</code> <CODE CLASS="literal">
+oplocks</code> option, as follows:</p><PRE CLASS="programlisting">
+[global]
+ kernel oplocks = yes</pre><P CLASS="para">
+Samba can automatically detect kernel oplocks and use them if present. At the time of this writing, this feature is supported only by SGI Irix 6.5.2f and later. However, Linux and FreeBSD support are expected in the near future. A system without kernel oplocks will allow the Unix process to update the file, but the client programs will notice the change only at a later time, if at all. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-958581">
+5.5.2.8 veto oplock files</a></h4><P CLASS="para">
+You can provide a list of filenames that are never granted opportunistic locks with the <CODE CLASS="literal">
+veto</code> <CODE CLASS="literal">
+oplock</code> <CODE CLASS="literal">
+files</code> option. This option can be set either globally or on a per-share basis. For example:</p><PRE CLASS="programlisting">
+veto oplock files = /*.bat/*.htm/</pre><P CLASS="para">
+The value of this option is a series of patterns. Each pattern entry must begin, end, or be separated from another with a slash (/) character, even if there is only one pattern listed. Asterisks can be used as a wildcard to represent zero or more characters. Questions marks can be used to represent exactly one character.</p><P CLASS="para">
+We recommend that you disable oplocks on any files that are meant to be updated by Unix or are intended to be shared by several processes simultaneously.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch05-pgfId-960237">
+5.5.2.9 lock directory</a></h4><P CLASS="para">
+This option (sometimes called <CODE CLASS="literal">
+lock</code> <CODE CLASS="literal">
+dir</code>) specifies the location of a directory where Samba will store SMB deny-mode lock files. Samba stores other files in this directory as well, such as browse lists and its shared memory file. If WINS is enabled, the WINS database is written to this directory as well. The default for this option is specified in the Samba makefile; it is typically <I CLASS="filename">
+/usr/local/samba/var/locks</i>. You can override this location as follows:</p><PRE CLASS="programlisting">
+[global]
+ lock directory = /usr/local/samba/locks</pre><P CLASS="para">
+You typically would not need to override this option, unless you want to move the lock files to a more standardized location, such as <I CLASS="filename">
+/var/spool/locks</i>. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_04.html" TITLE="5.4 Name Mangling and Case">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.4 Name Mangling and Case" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6. Users, Security, and Domains " BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+5.4 Name Mangling and Case</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6. Users, Security, and Domains </td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_01.html b/docs/htmldocs/using_samba/ch06_01.html
new file mode 100755
index 00000000000..439e66f3944
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_01.html
@@ -0,0 +1,221 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] Users, Security, and Domains </title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:28Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_05.html" TITLE="5.5 Locks and Oplocks">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.5 Locks and Oplocks" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 6</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_02.html" TITLE="6.2 Controlling Access to Shares">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.2 Controlling Access to Shares" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch06-88749">
+6. Users, Security, and Domains </a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch06-92902" TITLE="6.1 Users and Groups">
+Users and Groups</a><br>
+<A CLASS="sect1" HREF="ch06_02.html" TITLE="6.2 Controlling Access to Shares">
+Controlling Access to Shares</a><br>
+<A CLASS="sect1" HREF="ch06_03.html" TITLE="6.3 Authentication Security">
+Authentication Security</a><br>
+<A CLASS="sect1" HREF="ch06_04.html" TITLE="6.4 Passwords">
+Passwords</a><br>
+<A CLASS="sect1" HREF="ch06_05.html" TITLE="6.5 Windows Domains">
+Windows Domains</a><br>
+<A CLASS="sect1" HREF="ch06_06.html" TITLE="6.6 Logon Scripts">
+Logon Scripts</a></p><P>
+</p></div><P CLASS="para">
+This chapter discusses how to configure users with the Samba server. This topic may seem straightforward at first, but you'll soon discover that there are several ancillary problems that can crop up. One issue that Samba administrators have difficulty with is user authentication&nbsp;- password and security problems are by far the most common support questions on the Samba mailing lists. Learning why various authentication mechanisms work on certain architectures (and don't on others) can save you a tremendous amount of time testing and debugging Samba users in the future.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch06-92902">
+6.1 Users and Groups</a></h2><P CLASS="para">Before we start, we need to warn you up front that if you are connecting to Samba with a Windows 98 or NT 4.0 Workstation SP3, you need to configure your server for encrypted passwords before you can make a connection; otherwise, the clients will refuse to connect to the Samba server. This is because each of those Windows clients sends encrypted passwords, and Samba needs to be configured to expect and decrypt them. We'll show you how to set up Samba for this task later in the chapter, assuming you haven't already tackled this problem in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>.</p><P CLASS="para">Let's start with a single user. The easiest way to set up a client user is to create a Unix account (and home directory) for that individual on the server, and notify Samba of the user's existence. You can do the latter by creating a disk share that maps to the user's home directory in the Samba configuration file, and restricting access to that user with the <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> option. For example:</p><PRE CLASS="programlisting">
+[dave]
+ path = /home/dave
+ comment = Dave's home directory
+ writeable = yes<B CLASS="emphasis.bold">
+ valid users = dave</b></pre><P CLASS="para">
+The <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> option lists the users that will be allowed to access the share. In this case, only the user <CODE CLASS="literal">
+dave</code> is allowed to access the share. In the previous chapters, we specified that any user could access a disk share using the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> parameter. Because we don't wish to allow guest access, that option is absent here. We could grant both authenticated users and guest users access to a specific share if we wanted to. The difference between the two typically involves access rights for each of the files. </p><P CLASS="para">
+Remember that you can abbreviate the user's home directory by using the <CODE CLASS="literal">
+%H</code> variable. In addition, you can use the Unix username variable <CODE CLASS="literal">
+%u</code> and/or the client username variable <CODE CLASS="literal">
+%U</code> in your options as well. For example<EM CLASS="emphasis"></em>:</p><PRE CLASS="programlisting">
+[dave]
+ comment = %U home directory
+ writeable = yes
+ valid users = dave
+ path = %H</pre><P CLASS="para">
+Both of these examples work as long as the Unix user that Samba uses to represent the client has read/write access to the directory referenced by the <CODE CLASS="literal">
+path</code> option. In other words, a client must first pass Samba's security mechanisms (e.g., encrypted passwords, the <CODE CLASS="literal">
+valid users</code> option, etc.) as well as the normal Unix file and directory permissions of its Unix-side user <EM CLASS="emphasis">
+before</em> it can gain read/write access to a share.</p><P CLASS="para">
+With a single user accessing a home directory, access permissions are taken care of when the operating system creates the user account. However, if you're creating a shared directory for group access, there are a few more steps you need to perform. Let's take a stab at a group share for the accounting department in the <EM CLASS="emphasis">
+smb.conf</em> file:</p><PRE CLASS="programlisting">
+[accounting]
+ comment = Accounting Department Directory
+ writeable = yes
+ valid users = @account
+ path = /home/samba/accounting
+ create mode = 0660
+ directory mode = 0770</pre><P CLASS="para">
+The first thing that you might notice we did differently is to specify <CODE CLASS="literal">
+@account</code> as the valid user instead of one or more individual usernames. This is shorthand for saying that the valid users are represented by the Unix group <CODE CLASS="literal">
+account</code>. These users will need to be added to the group entry <CODE CLASS="literal">
+account</code> in the system group file (<I CLASS="filename">/etc/group</i> or equivalent) to be recognized as part of the group. Once they are, Samba will recognize those users as valid users for the share.</p><P CLASS="para">
+In addition, you will need to create a shared directory that the members of the group can access, which is pointed to by the <CODE CLASS="literal">
+path</code> configuration option. Here are the Unix commands that create the shared directory for the accounting department (assuming <EM CLASS="emphasis">
+/home/samba</em> already exists):</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">#</code> mkdir /home/samba/accounting</b><B CLASS="emphasis.bold">
+<CODE CLASS="literal">#</code> chgrp account /home/samba/accounting</b><B CLASS="emphasis.bold">
+<CODE CLASS="literal">#</code> chmod 770 /home/samba/accounting</b></pre><P CLASS="para">
+There are two other options in this <I CLASS="filename">
+smb.conf</i> example, both of which we saw in the previous chapter. These options are <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+mode</code> and <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+mode</code>. These options set the maximum file and directory permissions that a new file or directory can have. In this case, we have denied all world access to the contents of this share. (This is reinforced by the <EM CLASS="emphasis">
+chmod</em> command, shown earlier.).</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-968835">
+6.1.1 The [homes] Share</a></h3><P CLASS="para">
+Let's return to user shares for a moment. If we have several users to set up home directory shares for, we probably want to use the special <CODE CLASS="literal">
+[homes]</code> share that we introduced in <a href="ch05_01.html"><b>Chapter 5, <CITE CLASS="chapter">Browsing and Advanced Disk Shares</cite></b></a>. With the <CODE CLASS="literal">
+[homes]</code> share, all we need to say is: </p><PRE CLASS="programlisting">
+[homes]
+<CODE CLASS="literal">
+ </code>browsable = no
+ writable = yes</pre><P CLASS="para">
+The <CODE CLASS="literal">
+[homes]</code> share is a special section of the Samba configuration file. If a user attempts to connect to an ordinary share that doesn't appear in the <I CLASS="filename">
+smb.conf</i> file (such as specifying it with a UNC in Windows Explorer), Samba will search for a <CODE CLASS="literal">
+[homes]</code> share. If one exists, the incoming share name is assumed to be a username and is queried as such in the password database (<I CLASS="filename">/etc/passwd</i> or equivalent) file of the Samba server. If it appears, Samba assumes the client is a Unix user trying to connect to his or her home directory.</p><P CLASS="para">
+As an illustration, let's assume that <CODE CLASS="literal">
+sofia</code> is attempting to connect to a share called [<CODE CLASS="literal">sofia]</code> on the Samba server. There is no share by that name in the configuration file, but a <CODE CLASS="literal">
+[homes]</code> share exists and user <CODE CLASS="literal">
+sofia</code> is present in the password database, so Samba takes the following steps:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957527">
+</a>Samba creates a new disk share called <CODE CLASS="literal">
+[sofia]</code> with the <CODE CLASS="literal">
+path</code> specified in the <CODE CLASS="literal">
+[homes]</code> section. If there is no <CODE CLASS="literal">
+path</code> option specified in <CODE CLASS="literal">
+[homes]</code>, Samba initializes it to her home directory.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957528">
+</a>Samba initializes the new share's options from the defaults in <CODE CLASS="literal">
+[globals]</code>, and any overriding options in <CODE CLASS="literal">
+[homes]</code> with the exception of <CODE CLASS="literal">
+browseable</code>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957529">
+</a>Samba connects <CODE CLASS="literal">
+sofia</code>'s client to that share.</p></li></ol><P CLASS="para">
+The <CODE CLASS="literal">
+[homes]</code> share is a fast, painless way to create shares for your user community without having to duplicate the information from the password database file in the <I CLASS="filename">
+smb.conf</i> file. It does have some peculiarities, however, that we need to point out:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957531">
+</a>The <CODE CLASS="literal">
+[homes]</code> section can represent any account on the machine, which isn't always desirable. For example, it can potentially create a share for <EM CLASS="emphasis">
+root</em>, <EM CLASS="emphasis">
+bin</em>, <EM CLASS="emphasis">
+sys</em>, <EM CLASS="emphasis">
+uucp</em>, and the like. (You can set a global <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> option to protect against this.)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957533">
+</a>The meaning of the <CODE CLASS="literal">
+browseable</code> configuration option is different from other shares; it indicates only that a <CODE CLASS="literal">
+[homes]</code> section won't show up in the local browse list, not that the <CODE CLASS="literal">
+[alice]</code> share won't. When the <CODE CLASS="literal">
+[alice]</code> section is created (after the initial connection), it will use the browsable value from the <CODE CLASS="literal">
+[globals]</code> section for that share, not the value from <CODE CLASS="literal">
+[homes]</code>.</p></li></ul><P CLASS="para">
+As we mentioned, there is no need for a path statement in <CODE CLASS="literal">
+[homes]</code> if the users have Unix home directories in the server's <I CLASS="filename">
+/etc/passwd</i> file. You should ensure that a valid home directory does exist, however, as Samba will not automatically create a home directory for a user, and will refuse a tree connect if the user's directory does not exist or is not accessible. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch05_05.html" TITLE="5.5 Locks and Oplocks">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 5.5 Locks and Oplocks" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_02.html" TITLE="6.2 Controlling Access to Shares">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.2 Controlling Access to Shares" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+5.5 Locks and Oplocks</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6.2 Controlling Access to Shares</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_02.html b/docs/htmldocs/using_samba/ch06_02.html
new file mode 100755
index 00000000000..a5b7bf4d520
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_02.html
@@ -0,0 +1,423 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] 6.2 Controlling Access to Shares</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:37Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_01.html" TITLE="6.1 Users and Groups">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.1 Users and Groups" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+Chapter 6<br>
+Users, Security, and Domains </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_03.html" TITLE="6.3 Authentication Security">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.3 Authentication Security" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch06-27678">
+6.2 Controlling Access to Shares</a></h2><P CLASS="para">Often you will need to restrict the users who can access a specific share for security reasons. This is very easy to do with Samba since it contains a wealth of options for creating practically any security configuration. Let's introduce a few configurations that you might want to use in your own Samba setup.</p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Again, if you are connecting with Windows 98 or NT 4.0 with Service Pack 3 (or above), those clients will send encrypted passwords to the Samba server. If Samba is not configured for this, it will continually refuse the connection. This chapter describes how to set up Samba for encrypted passwords. See the <A CLASS="xref" HREF="ch06_04.html">
+Section 6.4, Passwords</a> section.</p></blockquote><P CLASS="para">
+We've seen what happens when you specify valid users. However, you are also allowed to specify a list of invalid users&nbsp;- users who should never be allowed access to Samba or its shares. This is done with the <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> option. We hinted at one frequent use of this option earlier: a global default with the <CODE CLASS="literal">
+[homes]</code> section to ensure that various system users and superusers cannot be forged for access. For example:</p><PRE CLASS="programlisting">
+[global]
+ invalid users = root bin daemon adm sync shutdown \
+ halt mail news uucp operator gopher
+ auto services = dave peter bob
+
+[homes]
+ browsable = no
+ writeable = yes</pre><P CLASS="para">
+The <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> option, like <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code>, can take group names as well as usernames. In the event that a user or group appears in both lists, the <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> option takes precedence and the user or group will be denied access to the share.</p><P CLASS="para">
+At the other end of the spectrum, you can explicitly specify users who will be allowed superuser (root) access to a share with the <CODE CLASS="literal">
+admin</code> <CODE CLASS="literal">
+users</code> option. An example follows:</p><PRE CLASS="programlisting">
+[sales]
+ path = /home/sales
+ comment = Fiction Corp Sales Data
+ writeable = yes
+ valid users = tom dick harry
+ admin users = mike</pre><P CLASS="para">
+This option takes both group names and usernames. In addition, you can specify NIS netgroups by preceding them with an <CODE CLASS="literal">
+@</code> as well; if the netgroup is not found, Samba will assume that you are referring to a standard Unix group. </p><P CLASS="para">
+Be careful if you assign an entire group administrative privileges to a share. The Samba team highly recommends you avoid using this option, as it essentially gives root access to the specified users or groups for that share.</p><P CLASS="para">
+If you wish to force read-only or read-write access to users who access a share, you can do so with the <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+list</code> and <CODE CLASS="literal">
+write</code> <CODE CLASS="literal">
+list</code> options, respectively. These options can be used on a per-share basis to restrict a writable share or grant write access to specific users in a read-only share, respectively. For example:</p><PRE CLASS="programlisting">
+[sales]
+ path = /home/sales
+ comment = Fiction Corp Sales Data
+ read only = yes
+ write list = tom dick</pre><P CLASS="para">
+The <CODE CLASS="literal">
+write</code> <CODE CLASS="literal">
+list</code> option cannot override Unix permissions. If you've created the share without giving the write-list user write permission on the Unix system, he or she will be denied write access regardless of the setting of <CODE CLASS="literal">
+write</code> <CODE CLASS="literal">
+list</code>.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-968870">
+6.2.1 Guest Access</a></h3><P CLASS="para">As mentioned earlier, you can specify users who have guest access to a share. The options that control guest access are easy to work with. The first option, <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code>, specifies the Unix account that guest users should be assigned when connecting to the Samba server. The default value for this is set during compilation, and is typically <CODE CLASS="literal">
+nobody</code>. However, you may want to reset the guest user to <CODE CLASS="literal">
+ftp</code> if you have trouble accessing various system services. </p><P CLASS="para">
+If you wish to restrict access in a share only to guests&nbsp;- in other words, all clients connect as the guest account when accessing the share&nbsp;- you can use the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+only</code> option in conjunction with the <CODE CLASS="literal">
+guest ok</code> option, as shown in the following example:</p><PRE CLASS="programlisting">
+[sales]
+ path = /home/sales
+ comment = Fiction Corp Sales Data
+ writeable = yes
+ guest ok = yes
+ guest account = ftp
+ guest only = yes</pre><P CLASS="para">
+Make sure you specify <CODE CLASS="literal">
+yes</code> for both <CODE CLASS="literal">
+guest only</code> and <CODE CLASS="literal">
+guest ok</code> in this scenario; otherwise, Samba will not use the guest acount that you specify.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-960007">
+6.2.2 Access Control Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch06_02.html#ch06-28077">Table 6.1</a> summarizes the options that you can use to control access to shares. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-28077">
+Table 6.1: Share-level Access Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+admin users</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users who can perform operations as root.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+valid users</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users that can connect to a share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+invalid users</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users that will be denied access to a share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+read list</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users that have read-only access to a writable share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+write list</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users that have read-write access to a read-only share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max connections</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates the maximum number of connections for a share at a given time.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+guest only (only guest)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies that this share allows only guest access.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+guest account</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (name of account)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Names the Unix account that will be used for guest access.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+nobody</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959222">
+6.2.2.1 admin users</a></h4><P CLASS="para">
+This option specifies a list of users that perform file operations as if they were <CODE CLASS="literal">
+root</code>. This means that they can modify or destroy any other user's work, no matter what the permissions. Any files that they create will have root ownership and will use the default group of the admin user. The <CODE CLASS="literal">
+admin</code> <CODE CLASS="literal">
+users</code> option is used to allow PC users to act as administrators for particular shares. We urge you to avoid this option. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960368">
+6.2.2.2 valid users and invalid users</a></h4><P CLASS="para">
+These two options let you enumerate the users and groups who are granted or denied access to a particular share. You can enter a list of comma-delimited users, or indicate an NIS or Unix group name by prefixing the name with an at-sign (<CODE CLASS="literal">@</code>). </p><P CLASS="para">
+The important rule to remember with these options is that any name or group in the <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> list will <EM CLASS="emphasis">
+always</em> be denied access, even if it is included (in any form) in the <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> list. By default, neither option has a value associated with it. If both options have no value, any user is allowed to access the share.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959243">
+6.2.2.3 read list and write list</a></h4><P CLASS="para">
+Like the <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> <CODE CLASS="literal">
+and</code> <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> options, this pair of options specifies which users have read-only access to a writeable share and read-write access to a read-only share, respectively. The value of either options is a list of users. <CODE CLASS="literal">
+read</code> <CODE CLASS="literal">
+list</code> overrides any other Samba permissions granted&nbsp;- as well as Unix file permissions on the server system&nbsp;- to deny users write access. <CODE CLASS="literal">
+write</code> <CODE CLASS="literal">
+list</code> overrides other Samba permissions to grant write access, but cannot grant write access if the user lacks write permissions for the file on the Unix system. You can specify NIS or Unix group names by prefixing the name with an at sign (such as <CODE CLASS="literal">
+@users</code>). Neither configuration option has a default value associated with it.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959253">
+6.2.2.4 max connections</a></h4><P CLASS="para">
+This option specifies the maximum number of client connections that a share can have at any given time. Any connections that are attempted after the maximum is reached will be rejected. The default value is <CODE CLASS="literal">
+0</code>, which means that an unlimited number of connections are allowed. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[accounting]
+ max connections = 30</pre><P CLASS="para">
+This option is useful in the event that you need to limit the number of users who are accessing a licensed program or piece of data concurrently.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-958842">
+6.2.2.5 guest only</a></h4><P CLASS="para">
+This share-level option (sometimes called <CODE CLASS="literal">
+only</code> <CODE CLASS="literal">
+guest</code>) forces a connection to a share to be performed with the user specified by the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> option. The share to which this is applied must explicitly specify <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in order for this option to be recognized by Samba. The default value for this option is <CODE CLASS="literal">
+no</code>. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960637">
+6.2.2.6 guest account</a></h4><P CLASS="para">
+This option specifies the name of account to be used for guest access to shares in Samba. The default for this option varies from system to system, but it is often set to <CODE CLASS="literal">
+nobody</code>. Some default user accounts have trouble connecting as guest users. If that occurs on your system, the Samba team recommends using the ftp account as the guest user. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-959934">
+6.2.3 Username Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch06_02.html#ch06-82964">Table 6.2</a> shows two additional options that Samba can use to correct for incompatibilities in usernames between Windows and Unix. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-82964">
+Table 6.2: Username Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+username map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the name of the username mapping file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+username level</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates the number of capital letters to use when trying to match a username.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959982">
+6.2.3.1 username map</a></h4><P CLASS="para">Client usernames on an SMB network can be relatively large (up to 255 characters), while usernames on a Unix network often cannot be larger than eight characters. This means that an individual user may have one username on a client and another (shorter) one on the Samba server. You can get past this issue by<I CLASS="firstterm">
+ mapping</i> a free-form client username to a Unix username of eight or fewer characters. It is placed in a standard text file, using a format that we'll describe shortly. You can then specify the pathname to Samba with the global <CODE CLASS="literal">
+username</code> <CODE CLASS="literal">
+map</code> option. Be sure to restrict access to this file; make the root user the file's owner and deny write access to others. Otherwise, an untrusted user who can access the file can easily map their client username to the root user of the Samba server.</p><P CLASS="para">
+You can specify this option as follows:</p><PRE CLASS="programlisting">
+[global]
+ username map = /etc/samba/usermap.txt</pre><P CLASS="para">
+Each of the entries in the username map file should be listed as follows: the Unix username, followed by an equal sign (<CODE CLASS="literal">=</code>), followed by one or more whitespace-separated SMB client usernames. Note that unless instructed otherwise, (i.e., a guest connection), Samba will expect both the client and the server user to have the same password. You can also map NT groups to one or more specific Unix groups using the <CODE CLASS="literal">
+@</code> sign. Here are some examples:</p><PRE CLASS="programlisting">
+jarwin = JosephArwin
+manderso = MarkAnderson
+users = @account</pre><P CLASS="para">
+Also, you can use the asterisk to specify a wildcard that matches any free-form client username as an entry in the username map file:</p><PRE CLASS="programlisting">
+nobody = *</pre><P CLASS="para">
+Comments in the file can be specified as lines beginning with (<CODE CLASS="literal">#</code>) and (<CODE CLASS="literal">;</code>).</p><P CLASS="para">
+Note that you can also use this file to redirect one Unix user to another user. Be careful if you do so because Samba and your client may not notify the user that the mapping has been made and Samba may be expecting a different password. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959994">
+6.2.3.2 username level</a></h4><P CLASS="para">SMB clients (such as Windows) will often send usernames in SMB connection requests entirely in capital letters; in other words, client usernames are not necessarily case sensitive. On a Unix server, however, usernames <EM CLASS="emphasis">
+are</em> case sensitive: the user <CODE CLASS="literal">
+ANDY</code> is different from the user <CODE CLASS="literal">
+andy</code>. By default, Samba attacks this problem by doing the following:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-959996">
+</a>Checking for a user account with the exact name sent by the client</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-969146">
+</a>Testing the username in all lowercase letters</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-969147">
+</a>Testing the username in lowercase letters with only the first letter capitalized</p></li></ol><P CLASS="para">
+If you wish to have Samba attempt more combinations of uppercase and lowercase letters, you can use the <CODE CLASS="literal">
+username</code> <CODE CLASS="literal">
+level</code> global configuration option. This option takes an integer value that specifies how many letters in the username should be capitalized when attempting to connect to a share. You can specify this options as follows:</p><PRE CLASS="programlisting">
+[global]
+ username level = 3</pre><P CLASS="para">
+In this case, Samba will then attempt all permutations of usernames it can compute having three capital letters. The larger the number, the more computations Samba will have to perform to match the username and the longer the authentication will take. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_01.html" TITLE="6.1 Users and Groups">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.1 Users and Groups" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_03.html" TITLE="6.3 Authentication Security">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.3 Authentication Security" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.1 Users and Groups</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6.3 Authentication Security</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_03.html b/docs/htmldocs/using_samba/ch06_03.html
new file mode 100755
index 00000000000..a9e1b7ace71
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_03.html
@@ -0,0 +1,384 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] 6.3 Authentication Security</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:44Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_02.html" TITLE="6.2 Controlling Access to Shares">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.2 Controlling Access to Shares" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+Chapter 6<br>
+Users, Security, and Domains </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_04.html" TITLE="6.4 Passwords">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.4 Passwords" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch06-88596">
+6.3 Authentication Security</a></h2><P CLASS="para">At this point, we should discuss how Samba authenticates users. Each user who attempts to connect to a share that does not allow guest access must provide a password to make a successful connection. What Samba does with that password&nbsp;- and consequently the strategy Samba will use to handle user authentication&nbsp;- is the arena of the <CODE CLASS="literal">
+security</code> configuration option. There are currently four security levels that Samba supports on its network: <I CLASS="firstterm">
+share</i>, <I CLASS="firstterm">
+user</i>, <I CLASS="firstterm">
+server</i>, and <I CLASS="firstterm">
+domain</i>.</p><DL CLASS="variablelist">
+<DT CLASS="term">Share-level security</dt><DD CLASS="listitem">
+<P CLASS="para">
+Each share in the workgroup has one or more passwords associated with it. Anyone who knows a valid password for the share can access it.</p></dd><DT CLASS="term">User-level security</dt><DD CLASS="listitem">
+<P CLASS="para">
+Each share in the workgroup is configured to allow access from certain users. With each initial tree connection, the Samba server verifies users and their passwords to allow them access to the share.</p></dd><DT CLASS="term">
+Server-level security</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is the same as user-level security, except that the Samba server uses a separate SMB server to validate users and their passwords before granting access to the share.</p></dd><DT CLASS="term">Domain-level security</dt><DD CLASS="listitem">
+<P CLASS="para">
+Samba becomes a member of a Windows domain and uses the domain's primary domain controller (PDC) to perform authentication. Once authenticated, the user is given a special token that allows him or her access to any share with appropriate access rights. With this token, the PDC will not have to revalidate the user's password each time he or she attempts to access another share within the domain.</p></dd></dl><P CLASS="para">
+Each of these security policies can be implemented with the global <CODE CLASS="literal">
+security</code> option, as shown in <A CLASS="xref" HREF="ch06_03.html#ch06-73905">
+Table 6.3</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-73905">
+Table 6.3: Security Option </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+security</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">domain</code>, <CODE CLASS="literal">
+server</code>, <CODE CLASS="literal">
+share</code>, or <CODE CLASS="literal">
+user</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates the type of security that the Samba server will use.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+user</code> (Samba 2.0) or <CODE CLASS="literal">
+share</code> (Samba 1.9)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-957225">
+6.3.1 Share-level Security</a></h3><P CLASS="para">With share-level security, each share has one or more passwords associated with it. This differs from the other modes of security in that there are no restrictions as to whom can access a share, as long as that individual knows the correct password. Shares often have multiple passwords. For example, one password may grant read-only access, while another may grant read-write access, and so on. Security is maintained as long as unauthorized users do not discover the password for a share to which they shouldn't have access.</p><P CLASS="para">OS/2 and Window 95/98 both support share-level security on their resources. You can set up share-level security with Windows 95/98 by first enabling share-level security using the Access Control tab of the Network Control Panel dialog. Then select the Share-level Access Control radio button (which deselects the user-level access control radio button), as shown in <A CLASS="xref" HREF="ch06_03.html#ch06-33100">
+Figure 6.1</a>, and press the OK button. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-33100">
+Figure 6.1: Selecting share-level security on a Windows machine</a></h4><IMG CLASS="graphic" SRC="figs/sam.0601.gif" ALT="Figure 6.1"><P CLASS="para">
+Next, right click on a resource&nbsp;- such as a hard drive or a CD-ROM&nbsp;- and select the Properties menu item. This will bring up the Resource Properties dialog box. Select the Sharing tab at the top of the dialog box and enable the resource as Shared As. From here, you can configure how the shared resource will appear to individual users, as well as assigning whether the resource will appear as read-only, read-write, or a mix, depending on the password that is supplied.</p><P CLASS="para">
+You might be thinking that this security model is not a good fit for Samba&nbsp;- and you would be right. In fact, if you set the <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+share</code> option in the Samba configuration file, Samba will still reuse the username/passwords combinations in the system password files to authenticate access. More precisely, Samba will take the following steps when a client requests a connection using share-level security:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957239">
+</a>When a connection is requested, Samba will accept the password and (if sent) the username of the client.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-958140">
+</a>If the share is <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+only</code>, the user is immediately granted access to the share with the rights of the user specified by the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> parameter; no password checking is performed.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957243">
+</a>For other shares, Samba appends the username to a list of users who are allowed access to the share. It then attempts to validate the password given in association with that username. If successful, Samba grants the user access to the share with the rights assigned to that user. The user will not need to authenticate again unless a <CODE CLASS="literal">
+revalidate</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option has been set inside the share.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957257">
+</a>If the authentication is unsuccessful, Samba will attempt to validate the password against the list of users it has previously compiled throughout the attempted connections, as well as any specified under the share in the configuration file. If the password does not match any usernames (as specified in the system password file, typically <I CLASS="filename">
+/etc/passwd</i>), the user is not granted access to the share under that username.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-958141">
+</a>However, if the share has a <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> or <CODE CLASS="literal">
+public</code> option set, the user will default to access with the rights of the user specified by the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> option.</p></li></ol><P CLASS="para">
+You can indicate in the configuration file which users should be initially placed on the share-level security user list by using the <CODE CLASS="literal">
+username</code> configuration option, as shown below:</p><PRE CLASS="programlisting">
+[global]
+ security = share
+[accounting1]
+ path = /home/samba/accounting1
+ guest ok = no
+ writable = yes
+ username = davecb, pkelly, andyo</pre><P CLASS="para">
+Here, when a user attempts to connect to a share, Samba will verify the password that was sent against each of the users in its own list, in addition to the passwords of users <CODE CLASS="literal">
+davecb</code>, <CODE CLASS="literal">
+pkelly</code>, and <CODE CLASS="literal">
+andyo</code>. If any of the passwords match, the connection will be verified and the user will be allowed. Otherwise, connection to the specific share will fail.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960345">
+6.3.1.1 Share Level Security Options</a></h4><P CLASS="para">
+<A CLASS="xref" HREF="ch06_03.html#ch06-80998">
+Table 6.4</a> shows the options typically associated with share-level security. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-80998">
+Table 6.4: Share-Level Access Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+only user</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether usernames specified by <CODE CLASS="literal">
+username</code> will be the only ones allowed.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+username </code>(user or users)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (list of usernames)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a list of users against which a client's password will be tested. </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960350">
+6.3.1.2 only user</a></h4><P CLASS="para">
+This boolean option indicates whether Samba will allow connections to a share using share-level security based solely on the individuals specified in the <CODE CLASS="literal">
+username</code> option, instead of those users compiled on Samba's internal list. The default value for this option is <CODE CLASS="literal">
+no</code>. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[global]
+ security = share
+[data]
+ username = andy, peter, valerie
+ only user = yes</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960355">
+6.3.1.3 username</a></h4><P CLASS="para">
+This option presents a list of users against which Samba will test a connection password to allow access. It is typically used with clients that have share-level security to allow connections to a particular service based solely on a qualifying password&nbsp;- in this case, one that matches a password set up for a specific user:</p><PRE CLASS="programlisting">
+[global]
+ security = share
+[data]
+ username = andy, peter, terry</pre><P CLASS="para">
+We recommend against using this option unless you are implementing a Samba server with share-level security. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-957260">
+6.3.2 User-level Security</a></h3><P CLASS="para">The preferred mode of security with Samba is <I CLASS="firstterm">
+user-level security</i>. With this method, each share is assigned specific users that can access it. When a user requests a connection to a share, Samba authenticates by validating the given username and password with the authorized users in the configuration file and the passwords in the password database of the Samba server. As mentioned earlier in the chapter, one way to isolate which users are allowed access to a specific share is by using the <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> option for each share:</p><PRE CLASS="programlisting">
+[global]
+ security = user
+[accounting1]
+ writable = yes
+ valid users = bob, joe, sandy</pre><P CLASS="para">
+Each of the users listed will be allowed to connect to the share if the password provided matches the password stored in the system password database on the server. Once the initial authentication succeeds, the user will not need to re-enter a password again to access that share unless the <CODE CLASS="literal">
+revalidate</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option has been set.</p><P CLASS="para">Passwords can be sent to the Samba server in either an encrypted or a non-encrypted format. If you have both types of systems on your network, you should ensure that the passwords represented by each user are stored both in a traditional account database and Samba's encrypted password database. This way, authorized users can gain access to their shares from any type of client.[<A CLASS="footnote" HREF="#ch06-pgfId-968956">1</a>] However, we recommend that you move your system to encrypted passwords and abandon non-encrypted passwords if security is an issue. The <A CLASS="xref" HREF="ch06_04.html">
+Section 6.4</a> section of this chapter explains how to use encrypted as well as non-encrypted passwords.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch06-pgfId-968956">[1]</a> Having both encrypted and non-encrypted password clients on your network is another reason why Samba allows you to include (or not include) various options in the Samba configuration file based on the client operating system or machine name variables. </p></div></blockquote></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-957282">
+6.3.3 Server-level Security</a></h3><P CLASS="para">Server-level security is similar to user-level security. However, with server-level security, Samba delegates password authentication to another SMB password server, typically another Samba server or a Windows NT Server acting as a PDC on the network. Note that Samba still maintains its list of shares and their configuration in its <I CLASS="filename">
+smb.conf</i> file. When a client attempts to make a connection to a particular share, Samba validates that the user is indeed authorized to connect to the share. Samba will then attempt to validate the password by contacting the SMB password server through a known protocol and presenting the username and password to the SMB password server. If the password is accepted, a session will be established with the client. See <A CLASS="xref" HREF="ch06_03.html#ch06-89929">
+Figure 6.2</a> for an illustration of this setup. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-89929">
+Figure 6.2: A typical system setup using server level security</a></h4><IMG CLASS="graphic" SRC="figs/sam.0602.gif" ALT="Figure 6.2"><P CLASS="para">
+You can configure Samba to use a separate password server under server-level security with the use of the <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+server</code> global configuration option, as follows:</p><PRE CLASS="programlisting">
+[global]
+ security = server
+ password server = PHOENIX120 HYDRA134</pre><P CLASS="para">
+Note that you can specify more than one machine as the target of the <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+server</code>; Samba will move down the list of servers in the event that its first choice is unreachable. The servers identified by the <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+server</code> option are given as NetBIOS names, not their DNS names or equivalent IP addresses. Also, if any of the servers reject the given password, the connection will automatically fail&nbsp;- Samba will not attempt another server.</p><P CLASS="para">
+One caveat: when using this option, you will still need an account representing that user on the regular Samba server. This is because the Unix operating system needs a username to perform various I/O operations. The preferable method of handling this is to give the user an account on the Samba server but disable the account's password by replacing it in the system password file (e.g., <I CLASS="filename">
+/etc/passwd </i>) with an asterisk (*).</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-957298">
+6.3.4 Domain-level Security</a></h3><P CLASS="para">Domain-level security is similar to server-level security. However, with domainlevel security, the Samba server is acting as a member of a Windows domain. Recall from Chapter 1 that each domain has a <I CLASS="firstterm">
+domain controller</i>, which is usually a Windows NT server offering password authentication. Including these controllers provides the workgroup with a definitive password server. The domain controllers keep track of users and passwords in their own security authentication module (SAM), and authenticates each user when he or she first logs on and wishes to access another machine's shares.</p><P CLASS="para">
+As mentioned earlier in this chapter, Samba has a similar ability to offer user-level security, but this option is Unix-centric and assumes that the authentication occurs via Unix password files. If the Unix machine is part of a NIS or NIS+ domain, Samba will authenticate the users transparently against a shared password file, in typical Unix fashion. Samba then provides access to the NIS or NIS+ domain from Windows. There is, of course, no relationship between the NIS concept of a domain and the Windows concept of a domain.</p><P CLASS="para">With domain-level security, we now have the option of using the native NT mechanism. This has a number of advantages:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963199">
+</a>It provides far better integration with NT: there are fewer "kludges" in the <I CLASS="filename">
+smb.conf</i> options dealing with domains than with most Windows features. This allows more extensive use of NT management tools, such as the User Manager for Domains tool allowing PC support individuals to treat Samba servers as if they were large NT machines.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963200">
+</a>With the better integration comes protocol and code cleanups, allowing the Samba team to track the evolving NT implementation. NT Service Pack 4 corrects several problems in the protocol, and Samba's better integration makes it easier to track and adapt to these changes.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963202">
+</a>There is less overhead on the PDC because there is one less permanent network connection between it and the Samba server. Unlike the protocol used by the <CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+server</code> option, the Samba server can make a Remote Procedure Call (RPC) call only when it needs authentication information. It can not keep a connection permanently up just for that.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963203">
+</a>Finally, the NT domain authentication scheme returns the full set of user attributes, not just success or failure. The attributes include a longer, more network-oriented version of the Unix uid, NT groups, and other information. This includes:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963204">
+</a>Username</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963205">
+</a>Full name</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963206">
+</a>Description</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963207">
+</a>Security identifier (a domain-wide extension of the Unix uid)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963208">
+</a>NT group memberships</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963209">
+</a>Logon hours, and whether to force the user to log out immediately</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963210">
+</a>Workstations the user is allowed to use</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963211">
+</a>Account expiration date</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963212">
+</a>Home directory</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963213">
+</a>Login script</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963214">
+</a>Profile</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963215">
+</a>Account type</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963216">
+</a>The Samba developers used domain-level security in Samba version 2.0.4 to add and delete domain users on Samba servers semi-automatically. In addition, it adds room for other NT-like additions, such as supporting access control lists and changing permissions of files from the client.</p></li></ul><P CLASS="para">
+The advantage to this approach is less administration; there is only one authentication database to keep synchronized. The only local administration required on the Samba server will be creating directories for users to work in and <I CLASS="filename">
+/etc/passwd</i> entries to keep their UIDs and groups in. </p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-963191">
+6.3.4.1 Adding a Samba server to a Windows NT Domain</a></h4><P CLASS="para">
+If you already have an NT domain, you can easily add a Samba server to it. First, you will need to stop the Samba daemons. Then, add the Samba server to the NT domain on the PDC using the "Windows NT Server Manager for Domains" tool. When it asks for the computer type, choose "Windows NT Workstation or Server," and give it the NetBIOS name of the Samba server. This creates the machine account on the NT server.</p><P CLASS="para">
+Next, generate a Microsoft-format machine password using the <I CLASS="filename">
+smbpasswd</i> tool, which is explained in further detail in the next section. For example, if our domain is SIMPLE and the Windows NT PDC is <CODE CLASS="literal">
+beowulf</code>, we could use the following command on the Samba server to accomplish this:</p><PRE CLASS="programlisting">
+<CODE CLASS="literal">
+smbpasswd -j SIMPLE -r beowulf</code></pre><P CLASS="para">
+Finally, add the following options to the <CODE CLASS="literal">
+[global]</code> section of your <I CLASS="filename">
+smb.conf</i> and restart the Samba daemons.</p><PRE CLASS="programlisting">
+[global]
+ security = domain
+ domain logins = yes
+ workgroup = SIMPLE
+ password server = beowulf</pre><P CLASS="para">
+Samba should now be configured for domain-level security. The <CODE CLASS="literal">
+domain</code> <CODE CLASS="literal">
+logins</code> option is explained in more detail later in this chapter. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_02.html" TITLE="6.2 Controlling Access to Shares">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.2 Controlling Access to Shares" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_04.html" TITLE="6.4 Passwords">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.4 Passwords" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.2 Controlling Access to Shares</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6.4 Passwords</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_04.html b/docs/htmldocs/using_samba/ch06_04.html
new file mode 100755
index 00000000000..646c6128f40
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_04.html
@@ -0,0 +1,738 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] 6.4 Passwords</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:33:50Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_03.html" TITLE="6.3 Authentication Security">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.3 Authentication Security" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+Chapter 6<br>
+Users, Security, and Domains </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_05.html" TITLE="6.5 Windows Domains">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.5 Windows Domains" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch06-61393">
+6.4 Passwords</a></h2><P CLASS="para">Passwords are a thorny issue with Samba. So much so, in fact, that they are almost always the first major problem that users encounter when they install Samba, and generate by far the most questions sent to Samba support groups. In previous chapters, we've gotten around the need for passwords by placing the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> option in each of our configuration files, which allows connections without authenticating passwords. However, at this point, we need to delve deeper into Samba to discover what is happening on the network.</p><P CLASS="para">Passwords sent from individual clients can be either encrypted or non-encrypted. Encrypted passwords are, of course, more secure. A non-encrypted password can be easily read with a packet sniffing program, such as the modified <EM CLASS="emphasis">
+tcpdump</em> program for Samba that we used in <a href="ch03_01.html"><b>Chapter 3, <CITE CLASS="chapter">Configuring Windows Clients</cite></b></a>. Whether passwords are encrypted depends on the operating system that the client is using to connect to the Samba server. <A CLASS="xref" HREF="ch06_04.html#ch06-75183">
+Table 6.5</a> lists which Windows operating systems encrypt their passwords before sending them to the primary domain controller for authentication. If your client is not Windows, check the system documentation to see if SMB passwords are encrypted. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-75183">
+Table 6.5: Windows Operating Systems with Encrypted Passwords </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Operating System</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Encrypted or Non-encrypted</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+</code>Windows 95</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Non-encrypted</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 95 with SMB Update</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Encrypted</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 98</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Encrypted</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT 3.<EM CLASS="emphasis">
+x</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Non-encrypted</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT 4.0 before SP<CODE CLASS="literal">
+ 3</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Non-encrypted</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows NT 4.0 after SP 3</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Encrypted</p></td></tr></tbody></table><P CLASS="para">
+There are actually two different encryption methods used: one for Windows 95 and 98 clients that reuses Microsoft's LAN Manager encryption style, and a separate one for Windows NT clients and servers. Windows 95 and 98 use an older encryption system inherited from the LAN Manager network software, while Windows NT clients and servers use a newer encryption system.</p><P CLASS="para">
+If encrypted passwords are supported, Samba stores the encrypted passwords in a file called <I CLASS="filename">
+smbpasswd</i>. By default, this file is located in the <I CLASS="filename">
+private</i> directory of the Samba distribution (<I CLASS="filename">/usr/local/samba/private</i>). At the same time, the client stores an encrypted version of a user's password on its own system. The plaintext password is never stored on either system. Each system encrypts the password automatically using a known algorithm when the password is set or changed.</p><P CLASS="para">
+When a client requests a connection to an SMB server that supports encrypted passwords (such as Samba or Windows NT), the two computers undergo the following negotiations:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957427">
+</a>The client attempts to negotiate a protocol with the server.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957428">
+</a>The server responds with a protocol and indicates that it supports encrypted passwords. At this time, it sends back a randomly-generated 8-byte challenge string.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957433">
+</a>The client uses the challenge string as a key to encrypt its already encrypted password using an algorithm predefined by the negotiated protocol. It then sends the result to the server.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957436">
+</a>The server does the same thing with the encrypted password stored in its database. If the results match, the passwords are equivalent and the user is authenticated.</p></li></ol><P CLASS="para">
+Note that even though the original passwords are not involved in the authentication process, you need to be very careful that the encrypted passwords located inside of the <I CLASS="filename">
+smbpasswd</i> file are guarded from unauthorized users. If they are compromised, an unauthorized user can break into the system by replaying the steps of the previous algorithm. The encrypted passwords are just as sensitive as the plaintext passwords&nbsp;- this is known as <I CLASS="firstterm">
+plaintext-equivalent</i> data in the cryptography world. Of course, you should also ensure that the clients safeguard their plaintext-equivalent passwords as well.</p><P CLASS="para">
+You can configure Samba to accept encrypted passwords with the following global additions to <I CLASS="filename">
+smb.conf</i>. Note that we explicitly name the location of the Samba password file:</p><PRE CLASS="programlisting">
+[global]
+ security = user
+ encrypt passwords = yes
+ smb passwd file = /usr/local/samba/private/smbpasswd</pre><P CLASS="para">
+Samba, however, will not accept any users until the <I CLASS="filename">
+smbpasswd</i> file has been initialized.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-959309">
+6.4.1 Disabling encrypted passwords on the client</a></h3><P CLASS="para">While Unix authentication has been in use for decades, including the use of <EM CLASS="emphasis">
+telnet</em> and <EM CLASS="emphasis">
+rlogin</em> access across the Internet, it embodies well-known security risks. Plaintext passwords are sent over the Internet and can be retrieved from TCP packets by malicious snoopers. However, if you feel that your network is secure and you wish to use standard Unix <I CLASS="filename">
+/etc/passwd</i> authentication for all clients, you can do so, but you must disable encrypted passwords on those Windows clients that default to using them. </p><P CLASS="para">
+In order to do this, you must modify the Windows registry by installing two files on each system. Depending on the platform involved, the files are either <I CLASS="filename">
+NT4_PlainPassword.reg</i> or <I CLASS="filename">
+Win95_PlainPassword.reg</i>. You can perform this installation by copying the appropriate <I CLASS="filename">
+.reg</i> files from the Samba distribution's <I CLASS="filename">
+/docs</i> directory to a DOS floppy, and running it from the Run menu item on the client's Start Menu button. Incidentally, the Windows 95 <I CLASS="filename">
+.reg</i> file works fine on Windows 98 as well.</p><P CLASS="para">
+After you reboot the machine, the client will not encrypt its hashed passwords before sending them to the server. This means that the plaintext-equivalent passwords can been seen in the TCP packets that are broadcast across the network. Again, we encourage you not to do this unless you are absolutely sure that your network is secure.</p><P CLASS="para">
+If passwords are not encrypted, you can indicate as much in your Samba configuration file:</p><PRE CLASS="programlisting">
+[global]
+ security = user
+ encrypt passwords = no</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-17782">
+6.4.2 The smbpasswd File</a></h3><P CLASS="para">
+<I CLASS="filename">
+</i>Samba stores its encrypted passwords in a file called <I CLASS="filename">
+smbpasswd</i>, which by default resides in the <I CLASS="filename">
+/usr/local/samba/private</i> directory. The <I CLASS="filename">
+smbpasswd</i> file should be guarded as closely as the <I CLASS="filename">
+passwd</i> file; it should be placed in a directory to which only the root user has read/write access. All other users should not be able to read from the directory at all. In addition, the file should have all access closed off to all users except for root.</p><P CLASS="para">
+Before you can use encrypted passwords, you will need to create an entry for each Unix user in the <I CLASS="filename">
+smbpasswd</i> file. The structure of the file is somewhat similar to a Unix <I CLASS="filename">
+passwd</i> file, but has different fields. <A CLASS="xref" HREF="ch06_04.html#ch06-54128">
+Figure 6.3</a> illustrates the layout of the <I CLASS="filename">
+smbpasswd</i> file; the entry shown is actually one line in the file. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-54128">
+Figure 6.3: Structure of the smbpasswd file entry (actually one line)</a></h4><IMG CLASS="graphic" SRC="figs/sam.0603.gif" ALT="Figure 6.3"><P CLASS="para">
+Here is a breakdown of the individual fields:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+Username</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is the username of the account. It is taken directly from the system password file.</p></dd><DT CLASS="term">
+UID</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is the user ID of the account. Like the username, it is taken directly from the system password file and must match the user it represents there.</p></dd><DT CLASS="term">
+LAN Manager Password Hash</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is a 32-bit hexadecimal sequence that represents the password Windows 95 and 98 clients will use. It is derived by encrypting the string <CODE CLASS="literal">
+KGS!@#$%</code> with a 56-bit DES algorithm using the user's password (forced to 14 bytes and converted to capital letters) twice repeated as the key. If there is currently no password for this user, the first 11 characters of the hash will consist of the sequence <CODE CLASS="literal">
+NO</code> <CODE CLASS="literal">
+PASSWORD</code> followed by <CODE CLASS="literal">
+X</code> characters for the remainder. Anyone can access the share with no password. On the other hand, if the password has been disabled, it will consist of 32 <CODE CLASS="literal">
+X</code> characters. Samba will not grant access to a user without a password unless the <CODE CLASS="literal">
+null</code> <CODE CLASS="literal">
+passwords</code> option has been set.</p></dd><DT CLASS="term">
+NT Password Hash</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is a 32-bit hexadecimal sequence that represents the password Windows NT clients will use. It is derived by hashing the user's password (represented as a 16-bit little-endian Unicode sequence) with an MD4 hash. The password is not converted to uppercase letters first.</p></dd><DT CLASS="term">
+Account Flags</dt><DD CLASS="listitem">
+<P CLASS="para">
+This field consists of 11 characters between two braces ([]). Any of the following characters can appear in any order; the remaining characters should be spaces:</p><P CLASS="para">
+U</p><P CLASS="para">
+This account is a standard user account.</p><P CLASS="para">
+D</p><P CLASS="para">
+This account is currently disabled and Samba should not allow any logins.</p><P CLASS="para">
+N</p><P CLASS="para">
+This account has no password associated with it.</p><P CLASS="para">
+W</p><P CLASS="para">
+This is a workstation trust account that can be used to configure Samba as a primary domain controller (PDC) when allowing Windows NT machines to join its domain.</p></dd></dl><DL CLASS="variablelist">
+<DT CLASS="term">
+Last Change Time</dt><DD CLASS="listitem">
+<P CLASS="para">
+This code consists of the characters <CODE CLASS="literal">
+LCT-</code> followed by a hexidecimal representation of the amount of seconds since the epoch (midnight on January 1, 1970) that the entry was last changed.</p></dd></dl><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-957988">
+6.4.2.1 Adding entries to smbpasswd</a></h4><P CLASS="para">
+<I CLASS="filename">
+</i>There are a few ways you can add a new entry to the <I CLASS="filename">
+smbpasswd</i> file:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-961684">
+</a>You can use the <I CLASS="firstterm">
+smbpasswd</i> program with the <CODE CLASS="literal">
+-a</code> option to automatically add any user that currently has a standard Unix system account on the server. This program resides in the <I CLASS="filename">
+/usr/local/samba/bin</i> directory.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957867">
+</a>You can use the <I CLASS="firstterm">
+addtosmbpass</i> executable inside the <I CLASS="firstterm">
+/usr/local/samba/bin</i> directory. This is actually a simple <EM CLASS="emphasis">
+awk</em> script that parses a system password file and extracts the username and UID of each entry you wish to add to the SMB password file. It then adds default fields for the remainder of the user's entry, which can be updated using the <I CLASS="filename">
+smbpasswd</i> program later. In order to use this program, you will probably need to edit the first line of the file to correctly point to <EM CLASS="emphasis">
+awk</em> on your system.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957870">
+</a>In the event that the neither of those options work for you, you can create a default entry by hand in the <I CLASS="filename">
+smbpasswd</i> file. The entry should be entirely on one line. Each field should be colon-separated and should look similar to the following:</p></li></ul><PRE CLASS="programlisting">
+dave:500:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:</pre><P CLASS="para">
+This consists of the username and the UID as specified in the system password file, followed by two sets of exactly 32 <CODE CLASS="literal">
+X</code> characters, followed by the account flags and last change time as it appears above. After you've added this entry, you must use the <I CLASS="firstterm">
+smbpasswd</i> program to change the password for the user.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-958012">
+6.4.2.2 Changing the encrypted password</a></h4><P CLASS="para">If you need to change the encrypted password in the <I CLASS="filename">
+smbpasswd</i> file, you can also use the <I CLASS="filename">
+smbpasswd</i> program. Note that this program shares the same name as the encrypted password file itself, so be sure not to accidentally confuse the password file with the password-changing program.</p><P CLASS="para">
+The <I CLASS="filename">
+smbpasswd</i> program is almost identical to the <I CLASS="filename">
+passwd</i> program that is used to change Unix account passwords. The program simply asks you to enter your old password (unless you're the root user), and duplicate entries of your new password. No password characters are shown on the screen. </p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">#</code> smbpasswd dave</b>
+</pre><PRE CLASS="programlisting">
+Old SMB password:
+New SMB password:
+Retype new SMB password:
+Password changed for user dave</pre><P CLASS="para">
+You can look at the <I CLASS="filename">
+smbpasswd</i> file after this command completes to verify that both the LAN Manager and the NT hashes of the passwords have been stored in their respective positions. Once users have encrypted password entries in the database, they should be able to connect to shares using encrypted passwords!<I CLASS="filename">
+</i> </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-97004">
+6.4.3 Password Synchronization</a></h3><P CLASS="para">Having a regular password and an encrypted version of the same password can be troublesome when you need to change both of them. Luckily, Samba affords you a limited ability to keep your passwords synchronized. Samba has a pair of configuration options that can be used to automatically update a user's regular Unix password when the encrypted password is changed on the system. The feature can be activated by specifying the <CODE CLASS="literal">
+unix</code> <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+sync</code> global configuration option:</p><PRE CLASS="programlisting">
+[global]
+ encrypt passwords = yes
+ smb passwd file = /usr/local/samba/private/smbpasswd
+
+ unix password sync = yes</pre><P CLASS="para">
+With this option enabled, Samba will attempt to change the user's regular password (as <CODE CLASS="literal">
+root</code>) when the encrypted version is changed with <I CLASS="filename">
+smbpasswd</i>. However, there are two other options that have to be set correctly in order for this to work.</p><P CLASS="para">
+The easier of the two is <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+program</code>. This option simply specifies the Unix command used to change a user's standard system password. It is set to <CODE CLASS="literal">
+/bin/passw</code>d <CODE CLASS="literal">
+%u</code> by default. With some Unix systems, this is sufficient and you do not need to change anything. Others, such as Red Hat Linux, use <I CLASS="filename">
+/usr/bin/passwd</i> instead. In addition, you may want to change this to another program or script at some point in the future. For example, let's assume that you want to use a script called <CODE CLASS="literal">
+changepass</code> to change a user's password. Recall that you can use the variable <CODE CLASS="literal">
+%u</code> to represent the current Unix username. So the example becomes:</p><PRE CLASS="programlisting">
+[global]
+ encrypt passwords = yes
+ smb passwd file = /usr/local/samba/private/smbpasswd
+
+ unix password sync = yes
+ passwd program = changepass %u</pre><P CLASS="para">
+Note that this program will be called as the <CODE CLASS="literal">
+root</code> user when the <CODE CLASS="literal">
+unix</code> <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+sync</code> option is set to <CODE CLASS="literal">
+yes</code>. This is because Samba does not necessarily have the plaintext old password of the user. </p><P CLASS="para">
+The harder option to configure is <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code>. The <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> option works like a Unix chat script. It specifies a series of strings to send as well as responses to expect from the program specified by the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+program</code> option. For example, this is what the default <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> looks like. The delimiters are the spaces between each groupings of characters:</p><PRE CLASS="programlisting">
+passwd chat = *old*password* %o\n *new*password* %n\n *new*password* %n\n *changed*</pre><P CLASS="para">
+The first grouping represents a response expected from the password-changing program. Note that it can contain wildcards (*), which help to generalize the chat programs to be able to handle a variety of similar outputs. Here, <CODE CLASS="literal">
+*old*password*</code> indicates that Samba is expecting any line from the password program containing the letters <CODE CLASS="literal">
+old</code> followed by the letters <CODE CLASS="literal">
+password</code>, without regard for what comes on either side or between them. Once instructed to, Samba will wait indefinitely for such a match. Is Samba does not receive the expected response, the password will fail.</p><P CLASS="para">
+The second grouping indicates what Samba should send back once the data in the first grouping has been matched. In this case, you see <CODE CLASS="literal">
+%o\n</code>. This response is actually two items: the variable <CODE CLASS="literal">
+%o</code> represents the old password, while the <CODE CLASS="literal">
+\n</code> is a newline character. So, in effect, this will "type" the old password into the standard input of the password changing program, and then "press" Enter.</p><P CLASS="para">
+Following that is another response grouping, followed by data that will be sent back to the password changing program. (In fact, this response/send pattern continues indefinitely in any standard Unix <EM CLASS="emphasis">
+chat</em> script.) The script continues until the final pattern is matched.[<A CLASS="footnote" HREF="#ch06-pgfId-969009">2</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch06-pgfId-969009">[2]</a> This may not work under Red Hat Linux, as the password program typically responds "All authentication tokens updated successfully," instead of "Password changed." We provide a fix for this later in this section.</p></div></blockquote><P CLASS="para">
+You can help match the response strings sent from the password program with the characters listed in <A CLASS="xref" HREF="ch06_04.html#ch06-77246">
+Table 6.6</a>. In addition, you can use the characters listed in <A CLASS="xref" HREF="ch06_04.html#ch06-38512">
+Table 6.7</a> to help formulate your response. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-77246">
+Table 6.6: Password Chat Response Characters </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Character</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+*</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Zero or more occurrences of any character.</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+&quot; &quot;</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows you to include matching strings that contain spaces. Asterisks are still considered wildcards even inside of quotes, and you can represent a null response with empty quotes.</p></td></tr></tbody></table><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-38512">
+Table 6.7: Password Chat Send Characters </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Character</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%o</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The user's old password</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%n</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The user's new password</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\n</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The linefeed character</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\r</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The carriage-return character</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\t</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The tab character</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\s</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+A space</p></td></tr></tbody></table><P CLASS="para">
+For example, you may want to change your password chat to the following entry. This will handle scenarios in which you do not have to enter the old password. In addition, this will also handle the new <CODE CLASS="literal">
+all</code> <CODE CLASS="literal">
+tokens</code> <CODE CLASS="literal">
+updated</code> <CODE CLASS="literal">
+successfully</code> string that Red Hat Linux sends:</p><PRE CLASS="programlisting">
+passwd chat = *new password* %n\n *new password* %n\n *success*</pre><P CLASS="para">
+Again, the default chat should be sufficient for many Unix systems. If it isn't, you can use the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> <CODE CLASS="literal">
+debug</code> global option to set up a new chat script for the password change program. The <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> <CODE CLASS="literal">
+debug</code> option logs everything during a password chat. This option is a simple boolean, as shown below:</p><PRE CLASS="programlisting">
+[global]
+ encrypted passwords = yes
+ smb passwd file = /usr/local/samba/private/smbpasswd
+
+ unix password sync = yes
+ passwd chat debug = yes
+ log level = 100</pre><P CLASS="para">
+After you activate the password chat debug feature, all I/O received by Samba through the password chat will be sent to the Samba logs with a debug level of 100, which is why we entered a new log level option as well. As this can often generate multitudes of error logs, it may be more efficient to use your own script, by setting the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+program</code> option, in place of <I CLASS="filename">
+/bin/passwd</i> to record what happens during the exchange. Also, make sure to protect your log files with strict file permissions and to delete them as soon as you've grabbed the information you need, because they contain the passwords in plaintext.</p><P CLASS="para">
+The operating system on which Samba is running may have strict requirements for valid passwords in order to make them more impervious to dictionary attacks and the like. Users should be made aware of these restrictions when changing their passwords.</p><P CLASS="para">
+Earlier we said that password synchronization is limited. This is because there is no reverse synchronization of the encrypted <I CLASS="filename">
+smbpasswd</i> file when a standard Unix password is updated by a user. There are various strategies to get around this, including NIS and freely available implementations of the pluggable authentication modules (PAM) standard, but none of them really solve all the problems yet. In the future, when Windows 2000 emerges, we will see more compliance with the Lightweight Directory Access Protocol (LDAP), which promises to make password synchronization a thing of the past. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-958652">
+6.4.4 Password Configuration Options</a></h3><P CLASS="para">
+The options in <A CLASS="xref" HREF="ch06_04.html#ch06-68460">
+Table 6.8</a> will help you work with passwords in Samba. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-68460">
+Table 6.8: Password Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+encrypt passwords</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Turns on encrypted passwords.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+unix password sync </code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba updates the standard Unix password database when a user changes his or her encrypted password.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+passwd chat</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (chat commands)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a sequence of commands that will be sent to the password program.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See earlier section on this option</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+passwd chat debug</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sends debug logs of the password-change process to the log files with a level of 100.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+passwd program</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the program to be used to change passwords.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+/bin/passwd %u</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+password level</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the number of capital letter permutations to attempt when matching a client's password.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+update encrypted</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba updates the encrypted password file when a client connects to a share with a plaintext password.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+null passwords</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba allows access for users with null passwords.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+smb passwd file</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the name of the encrypted password file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+/usr/local/samba/private/smbpasswd</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+hosts equiv</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the name of a file that contains hosts and users that can connect without using a password.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+use rhosts</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the name of an .<EM CLASS="emphasis">
+rhosts</em> file that allows users to connect without using a password.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-968072">
+6.4.4.1 unix password sync</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+unix</code> <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+sync</code> global option allows Samba to update the standard Unix password file when a user changes his or her encrypted password. The encrypted password is stored on a Samba server in the <I CLASS="filename">
+smbpasswd</i> file, which is located in <I CLASS="filename">
+/usr/local/samba/private</i> by default. You can activate this feature as follows:</p><PRE CLASS="programlisting">
+[global]
+ unix password sync = yes</pre><P CLASS="para">
+If this option is enabled, Samba changes the encrypted password and, in addition, attempts to change the standard Unix password by passing the username and new password to the program specified by the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+program</code> option (described earlier). Note that Samba does not necessarily have access to the plaintext password for this user, so the password changing program must be invoked as <CODE CLASS="literal">
+root</code>.[<A CLASS="footnote" HREF="#ch06-pgfId-959675">3</a>] If the Unix password change does not succeed, for whatever reason, the SMB password will not be changed either.</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch06-pgfId-959675">[3]</a> This is because the Unix <EM CLASS="emphasis">
+passwd</em> program, which is the usual target for this operation, allows <CODE CLASS="literal">
+root</code> to change a user's password without the security restriction that requests the old password of that user.</p></div></blockquote></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-958684">
+6.4.4.2 encrypt passwords</a></h4><P CLASS="para">The <CODE CLASS="literal">
+encrypt</code> <CODE CLASS="literal">
+passwords</code> global option switches Samba from using plaintext passwords to encrypted passwords for authentication. Encrypted passwords will be expected from clients if the option is set to <CODE CLASS="literal">
+yes</code>:</p><PRE CLASS="programlisting">
+encrypt passwords = yes</pre><P CLASS="para">
+By default, Windows NT 4.0 with Service Pack 3 or above and Windows 98 transmit encrypted passwords over the network. If you are enabling encrypted passwords, you must have a valid <I CLASS="filename">
+smbpasswd</i> file in place and populated with usernames that will authenticate with encrypted passwords. (See the section <A CLASS="xref" HREF="ch06_04.html#ch06-17782">
+Section 6.4.2, The smbpasswd File</a>, earlier in this chapter.) In addition, Samba must know the location of the <I CLASS="filename">
+smbpasswd</i> file; if it is not in the default location (typically <I CLASS="filename">
+/usr/local/samba/private/smbpasswd</i>), you can explicitly name it using the <CODE CLASS="literal">
+smb</code> <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+file</code> option.</p><P CLASS="para">
+If you wish, you can use the <CODE CLASS="literal">
+update</code> <CODE CLASS="literal">
+encrypted</code> to force Samba to update the <I CLASS="filename">
+smbpasswd</i> file with encrypted passwords each time a client connects to a non-encrypted password.</p><P CLASS="para">
+A common strategy to ensure that hosts who need encrypted password authentication indeed receive it is with the <CODE CLASS="literal">
+include</code> option. With this, you can create individual configuration files that will be read in based on OS-type (<CODE CLASS="literal">%a</code>) or client name (<CODE CLASS="literal">%m</code>). These host-specific or OS-specific configuration files can contain an <CODE CLASS="literal">
+encrypted</code> <CODE CLASS="literal">
+passwords</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option that will activate only when those clients are connecting to the server.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-954367">
+6.4.4.3 passwd program</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+program</code> is used to specify a program on the Unix Samba server that Samba can use to update the standard system password file when the encrypted password file is updated. This option defaults to the standard<EM CLASS="emphasis">
+ passwd</em> program, usually located in the <I CLASS="filename">
+/bin</i> directory. The <CODE CLASS="literal">
+%u</code> variable is typically used here as the requesting user when the command is executed. The actual handling of input and output to this program during execution is handled through the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> option. The "Password Synchronization" section, earlier in this chapter, covers this option in detail.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-954372">
+6.4.4.4 passwd chat</a></h4><P CLASS="para">
+This option specifies a series of send/response strings similar to a Unix chat script, which are used to interface with the password-changing program on the Samba server. The "Password Synchronization" section, earlier in this chapter, covers this option in detail.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-954442">
+6.4.4.5 passwd chat debug</a></h4><P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, the <CODE CLASS="literal">
+passwd</code> <CODE CLASS="literal">
+chat</code> <CODE CLASS="literal">
+debug</code> global option logs everything sent or received by Samba during a password chat. All the I/O received by Samba through the password chat is sent to the Samba logs with a debug level of 100; you will need to specify <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+100</code> in order for the information to be recorded. The "Password Synchronization" section<EM CLASS="emphasis">
+,</em> earlier in this chapter, describes this option in more detail. Be aware that if you do set this option, the plaintext passwords will be visible in the debugging logs, which could be a security hazard if they are not properly secured.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-958069">
+6.4.4.6 password level</a></h4><P CLASS="para">
+With SMB, non-encrypted (or plaintext) passwords are sent with capital letters, just like the usernames mentioned previously. Many Unix users, however, choose passwords with both uppercase and lowercase letters. Samba, by default, only attempts to match the password entirely in lowercase letters, and not capitalizing the first letter.</p><P CLASS="para">
+Like <CODE CLASS="literal">
+username</code> <CODE CLASS="literal">
+level</code>, there is a <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+level</code> option that can be used to attempt various permutations of the password with capital letters. This option takes an integer value that specifies how many letters in the password should be capitalized when attempting to connect to a share. You can specify this options as follows:</p><PRE CLASS="programlisting">
+[global]
+ password level = 3</pre><P CLASS="para">
+In this case, Samba will then attempt all permutations of the password it can compute having three capital letters. The larger the number, the more computations Samba will have to perform to match the password, and the longer a connection to a specific share may take. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-954452">
+6.4.4.7 update encrypted</a></h4><P CLASS="para">
+For sites switching over to the encrypted password format, Samba provides an option that should help with the transition. The <CODE CLASS="literal">
+update</code> <CODE CLASS="literal">
+encrypted</code> option allows a site to ease into using encrypted passwords from plaintext passwords. You can activate this option as follows:</p><PRE CLASS="programlisting">
+[global]
+ update encrypted = yes</pre><P CLASS="para">
+This instructs Samba to create an encrypted version of each user's Unix password in the <I CLASS="filename">
+smbpasswd</i> file each time he or she connects to a share. When this option is enabled, you must have the <CODE CLASS="literal">
+encrypt</code> <CODE CLASS="literal">
+passwords</code> option set to <CODE CLASS="literal">
+no</code> so that the client will pass plaintext passwords to Samba to use to update the files. Once each user has connected at least once, you can set <CODE CLASS="literal">
+encrypted</code> <CODE CLASS="literal">
+passwords</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code>, allowing you to use only the encrypted passwords. The user must already have a valid entry in the <I CLASS="filename">
+smbpasswd</i> file for this option to work.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-958716">
+6.4.4.8 null passwords</a></h4><P CLASS="para">
+This global option tells Samba whether or not to allow access from users that have null passwords (encrypted or non-encrypted) set in their accounts. The default value is <CODE CLASS="literal">
+no</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+null passwords = yes</pre><P CLASS="para">
+We highly recommend against doing so unless you are familiar with the security risks this option can present to your system, including inadvertent access to system users (such as <I CLASS="filename">
+bin</i>) in the system password file who have null passwords set.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959357">
+6.4.4.9 smb passwd file</a></h4><P CLASS="para">This global option identifies the location of the encrypted password database. By default, it is set to <I CLASS="filename">
+/usr/local/samba/private/smbpasswd</i>. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ smb passwd file = /etc/smbpasswd</pre><P CLASS="para">
+This location, for example, is common on many Red Hat distributions.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-969088">
+6.4.4.10 hosts equiv</a></h4><P CLASS="para">
+This global option specifies the name of a standard Unix <I CLASS="filename">
+hosts.equiv</i> file that will allow hosts or users to access shares without specifying a password. You can specify the location of such a file as follows:</p><PRE CLASS="programlisting">
+[global]
+ hosts equiv = /etc/hosts.equiv</pre><P CLASS="para">
+The default value for this option does not specify any <I CLASS="filename">
+hosts.equiv</i> file. Because using such a file is essentially a huge security risk, we highly recommend that you do not use this option unless you are confident in the security of your network.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-959358">
+6.4.4.11 use rhosts</a></h4><P CLASS="para">
+This global option specifies the name of a standard Unix user's <I CLASS="filename">
+.rhosts</i> file that will allow foreign hosts to access shares without specifying a password. You can specify the location of such a file as follows:</p><PRE CLASS="programlisting">
+[global]
+ use rhosts = /home/dave/.rhosts</pre><P CLASS="para">
+The default value for this option does not specify any <I CLASS="filename">
+.rhosts</i> file. Like the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+equiv</code> option above, using such a file is a security risk. We highly recommend that you do use this option unless you are confident in the security of your network. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_03.html" TITLE="6.3 Authentication Security">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.3 Authentication Security" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_05.html" TITLE="6.5 Windows Domains">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.5 Windows Domains" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.3 Authentication Security</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6.5 Windows Domains</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_05.html b/docs/htmldocs/using_samba/ch06_05.html
new file mode 100755
index 00000000000..fbf6d245a16
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_05.html
@@ -0,0 +1,333 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] 6.5 Windows Domains</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:34:04Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_04.html" TITLE="6.4 Passwords">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.4 Passwords" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+Chapter 6<br>
+Users, Security, and Domains </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_06.html" TITLE="6.6 Logon Scripts">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.6 Logon Scripts" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch06-23084">
+6.5 Windows Domains</a></h2><P CLASS="para">Now that you are comfortable with users and passwords on a Samba server, we can show you how to set up Samba to become a primary domain controller for Windows 95/98 and NT machines. Why use domains? The answer probably isn't obvious until you look behind the scenes, especially with Windows 95/98.</p><P CLASS="para">
+Recall that with traditional workgroups, Windows 95/98 simply accepts each username and password that you enter when logging on to the system. There are no unauthorized users with Windows 95/98; if a new user logs on, the operating system simply asks for a new password and authenticates the user against that password from then on. The only time that Windows 95/98 attempts to use the password you entered is when connecting to another share.</p><P CLASS="para">Domain logons, on the other hand, are similar to Unix systems. In order to log on to the domain, a valid username and password must be presented at startup, which is then authenticated against the primary domain controller's password database. If the password is invalid, the user is immediately notified and they cannot log on to the domain.</p><P CLASS="para">
+There's more good news: once you have successfully logged on to the domain, you can access any of the shares in the domain to which you have rights without having to reauthenticate yourself. More precisely, the primary domain controller returns a token to the client machine that allows it to access any share without consulting the PDC again. Although you probably won't notice the shift, this can be beneficial in cutting down network traffic. (You can disable this behavior if you wish by using the <CODE CLASS="literal">
+revalidate</code> option.)</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-36822">
+6.5.1 Configuring Samba for Windows Domain Logons</a></h3><P CLASS="para">
+If you wish to allow Samba to act as a domain controller, use the following sections to configure Samba and your clients to allow domain access. </p><P CLASS="para">
+If you would like more information on how to set up domains, see the <I CLASS="filename">
+DOMAINS.TXT</i> file that comes with the Samba distribution.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962093">
+6.5.1.1 Windows 95/98 clients</a></h4><P CLASS="para">Setting up Samba as a PDC for Windows 95/98 clients is somewhat anticlimactic. All you really need to do on the server side is ensure that:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-962098">
+</a>Samba is the only primary domain controller for the current workgroup.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-963241">
+</a>There is a WINS server available on the network, either a Samba machine or a Windows NT server. (See <a href="ch07_01.html"><b>Chapter 7, <CITE CLASS="chapter">Printing and Name Resolution</cite></b></a>, for more information on WINS.)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-962099">
+</a>Samba is using user-level security (i.e., it doesn't hand off password authentication to anyone else). You do not want to use domain-level security if Samba itself is acting as the PDC.</p></li></ul><P CLASS="para">
+At that point, you can insert the following options into your Samba configuration file:</p><PRE CLASS="programlisting">
+[global]
+ workgroup = SIMPLE
+ domain logons = yes
+
+# Be sure to set user-level security!
+
+ security = user
+
+# Be sure to become the primary domain controller!
+
+ os level = 34
+ local master = yes
+ preferred master = yes
+ domain master = yes</pre><P CLASS="para">
+The <CODE CLASS="literal">
+domain</code> <CODE CLASS="literal">
+logons</code> option enables Samba to perform domain authentication on behalf of other clients that request it. The name of the domain will be the same as the workgroup listed in the Samba configuration file, in this case: SIMPLE.</p><P CLASS="para">
+After that, you need to create a non-writable, non-public, non-browesable disk share called <CODE CLASS="literal">
+[netlogon]</code> (it does not matter where this share points to as long as each Windows client can connect to it): </p><PRE CLASS="programlisting">
+[netlogon]
+ comment = The domain logon service
+ path = /export/samba/logon
+ public = no
+ writeable = no
+ browsable = no</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-961711">
+6.5.1.2 Windows NT clients</a></h4><P CLASS="para">If you have Window NT clients on your system, there are a few more steps that need to be taken in order for Samba to act as their primary domain controller.</p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> You will need to use at least Samba 2.1 to ensure that PDC functionality for Windows NT clients is present. Prior to Samba 2.1, only limited user authentication for NT clients was present. At the time this book went to press, Samba 2.0.5 was the latest version, but Samba 2.1 was available through CVS download. Instructions on downloading alpha versions of Samba are given in <a href="appe_01.html"><b>Appendix E, <CITE CLASS="appendix">Downloading Samba with CVS</cite></b></a>.</p></blockquote><P CLASS="para">
+As before, you need to ensure that Samba is a primary domain controller for the current workgroup and is using user-level security. However, you must also ensure that Samba is using encrypted passwords. In other words, alter the <CODE CLASS="literal">
+[global]</code> options the previous example to include the <CODE CLASS="literal">
+encrypted</code> <CODE CLASS="literal">
+passwords</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option, as shown here: </p><PRE CLASS="programlisting">
+[global]
+ workgroup = SIMPLE
+ encrypted passwords = yes
+ domain logons = yes
+
+ security = user </pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-961829">
+6.5.1.3 Creating trust accounts for NT clients</a></h4><P CLASS="para">
+This step is exclusively for Windows NT clients. All NT clients that connect to a primary domain controller make use of <I CLASS="firstterm">
+trust accounts</i>. These accounts allow a machine to log in to the PDC itself (not one of its shares), which means that the PDC can trust any further connections from users on that client. For all intents and purposes, a trust account is identical to a user account. In fact, we will be using standard Unix user accounts to emulate trust accounts for the Samba server.</p><P CLASS="para">
+The login name of a machine's trust account is the name of the machine with a dollar sign appended to it. For example, if our Windows NT machine is named <CODE CLASS="literal">
+chimaera</code>, the login account would be <CODE CLASS="literal">
+chimaera$</code>. The initial password of the account is simply the name of the machine in lowercase letters. In order to forge the trust account on the Samba server, you need to create a Unix account with the appropriate machine name, as well as an encrypted password entry in the <I CLASS="filename">
+smbpasswd</i> database.</p><P CLASS="para">
+Let's tackle the first part. Here, we only need to modify the <I CLASS="filename">
+/etc/passwd</i> file to support the trust account; there is no need to create a home directory or assign a shell to the "user" because the only part we are interested in is whether a login is permitted. Therefore, we can create a "dummy" account with the following entry:</p><PRE CLASS="programlisting">
+chimaera$:*:1000:900:Trust Account:/dev/null:/dev/null</pre><P CLASS="para">
+Note that we have also disabled the password field by placing a <CODE CLASS="literal">
+*</code> in it. This is because Samba will use the <I CLASS="filename">
+smbpasswd</i> file to contain the password instead, and we don't want anyone to telnet into the machine using that account. In fact, the only value other than the account name that is used here is the UID of the account for the encrypted password database (1000). This number must map to a unique resource ID on the NT server and cannot conflict with any other resource IDs. Hence, no NT user or group should map to this number or a networking error will occur.</p><P CLASS="para">
+Next, add the encrypted password using the <I CLASS="filename">
+smbpasswd</i> command, as follows: </p><PRE CLASS="programlisting"># <CODE CLASS="userinput"><B>smbpasswd -a -m chimaera</b></code>
+Added user chimaera$
+Password changed for user chimaera$</pre><P CLASS="para">
+The <CODE CLASS="literal">
+-m</code> option specifies that a machine trust account is being generated. The <I CLASS="filename">
+smbpasswd</i> program will automatically set the initial encrypted password as the NetBIOS name of the machine in lowercase letters; you don't need to enter it. When specifying this option on the command line, do not put a dollar sign after the machine name&nbsp;- it will be appended automatically. Once the encrypted password has been added, Samba is ready to handle domain logins from a NT client.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-961709">
+6.5.2 Configuring Windows Clients for Domain Logons</a></h3><P CLASS="para">
+Once you have Samba configured for domain logons, you need to set up your Windows clients to log on to the domain at startup.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962166">
+6.5.2.1 Windows 95/98</a></h4><P CLASS="para">With Windows 95/98, this can be done by raising the Network configuration dialog in the Windows Control Panel and selecting the Properties for "Client for Microsoft Networks." At this point, you should see a dialog box similar to <A CLASS="xref" HREF="ch06_05.html#ch06-48609">
+Figure 6.4</a>. Select the "Logon to Windows Domain" checkbox at the top of the dialog box, and enter the workgroup that is listed in the Samba configuration file as the Windows NT domain. Then click on OK and reboot the machine when asked. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-48609">
+Figure 6.4: Configuring a Windows 95/98 client for domain logons</a></h4><IMG CLASS="graphic" SRC="figs/sam.0604.gif" ALT="Figure 6.4"><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> If Windows complains that you are already logged into the domain, you probably have an active connection to a share in the workgroup (such as a mapped network drive). Simply disconnect the resource temporarily by right-clicking on its icon and choosing the Disconnect pop-up menu item.</p></blockquote><P CLASS="para">
+When Windows reboots, you should see the standard login dialog with an addition: a field for a domain. The domain name should already be filled in, so simply enter your password and click on the OK button. At this point, Windows should consult the primary domain controller (Samba) to see if the password is correct. (You can check the log files if you want to see this in action.) If it worked, congratulations! You have properly configured Samba to act as a domain controller for Windows 95/98 machines and your client is successfully connected.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-961780">
+6.5.2.2 Windows NT 4.0</a></h4><P CLASS="para">To configure Windows NT for domain logons, open the Network configuration dialog in the Windows NT Control Panel. The first tab that you see should list the identification of the machine.</p><P CLASS="para">
+Press the Change button and you should see the dialog box shown in <A CLASS="xref" HREF="ch06_05.html#ch06-89804">
+Figure 6.5</a>. In this dialog box, you can choose to have the Windows NT client become a member of the domain by selecting the radio button marked Domain in the "Member of" box. Then, type in the domain that you wish the client to login to; it should be the same as the workgroup that you specified in the Samba configuration file. Do not check the box marked "Create a Computer Account in the Domain"&nbsp;- Samba does not currently support this functionality. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-89804">
+Figure 6.5: Configuring a Windows NT client for domain logons</a></h4><IMG CLASS="graphic" SRC="figs/sam.0605.gif" ALT="Figure 6.5"><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Like Windows 95/98, if NT complains that you are already logged in, you probably have an active connection to a share in the workgroup (such as a mapped network drive). Disconnect the resource temporarily by right-clicking on its icon and choosing the Disconnect pop-up menu item.</p></blockquote><P CLASS="para">
+After you press the OK button, Windows should present you with a small dialog box welcoming you to the domain. At this point, you will need to reset the Windows NT machine. Once it comes up again, the machine will automatically present you with a log on screen similar to the one for Windows 95/98 clients. You can now log in using any account that you have already on the Samba server that is configured to accept logins.</p><BLOCKQUOTE CLASS="warning">
+<P CLASS="para">
+<STRONG>
+WARNING:</strong> Be sure to select the correct domain in the Windows NT logon dialog box. Once selected, it may take a moment for Windows NT to build the list of available domains.</p></blockquote><P CLASS="para">
+After you enter the password, Windows NT should consult the primary domain controller (Samba) to see if the password is correct. Again, you can check the log files if you want to see this in action. If it worked, you have successfully configured Samba to act as a domain controller for Windows NT machines.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-961353">
+6.5.3 Domain Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch06_05.html#ch06-53106">
+Table 6.9</a> shows the options that are commonly used in association with domain logons. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-53106">
+Table 6.9: Windows 95/98 Domain Logon Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+domain logons</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Indicates whether Windows domain logons are to be used.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+domain group map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name of the file used to map Unix to Windows NT domain groups.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+domain user map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name of the file used to map Unix to Windows NT domain users.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+local group map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name of the file used to map Unix to Windows NT local groups.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+revalidate</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba forces users to authenticate themselves with each connection to a share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960379">
+6.5.3.1 domain logons</a></h4><P CLASS="para">
+This option configures Samba to accept domain logons as a primary domain controller. When a client successfully logs on to the domain, Samba will return a special token to the client that allows the client to access domain shares without consulting the PDC again for authentication. Note that the Samba machine must be in user-level security (<CODE CLASS="literal">security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+user</code>) and must be the PDC in order for this option to function. In addition, Windows machines will expect a <CODE CLASS="literal">
+[netlogon]</code> share to exist on the Samba server (see the section <A CLASS="xref" HREF="ch06_05.html#ch06-36822">
+Section 6.5.1, Configuring Samba for Windows Domain Logons</a>, earlier in this chapter).</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-966160">
+6.5.3.2 domain group map</a></h4><P CLASS="para">
+This option specifies the location of a mapping file designed to translate Windows NT domain group names to Unix group names. The file should reside on the Samba server. For example:</p><PRE CLASS="programlisting">
+/usr/local/samba/private/groups.mapping</pre><P CLASS="para">
+The file has a simple format:</p><PRE CLASS="programlisting"><CODE CLASS="replaceable"><I>UnixGroup = NTGroup</i></code></pre><P CLASS="para">
+An example is:</p><PRE CLASS="programlisting">
+admin = Administrative</pre><P CLASS="para">
+The specified Unix group should be a valid group in the <I CLASS="filename">
+/etc/group</i> file. The NT group should be the name to which you want the Unix group to map on an NT client. This option will work only with Windows NT clients.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-961959">
+6.5.3.3 domain user map</a></h4><P CLASS="para">
+This option specifies the location of a mapping file designed to translate Unix usernames to Windows NT domain usernames. The file should reside on the Samba server. For example:</p><PRE CLASS="programlisting">/usr/local/samba/private/domainuser.mapping</pre><P CLASS="para">The file has a simple format:</p><PRE CLASS="programlisting"><CODE CLASS="replaceable"><I>UnixUsername</i></code> = [\\<CODE CLASS="replaceable"><I>Domain</i></code>\\]<CODE CLASS="replaceable"><I>NTUserName</i></code></pre><P CLASS="para">
+An example entry is:</p><PRE CLASS="programlisting">
+joe = Joseph Miller</pre><P CLASS="para">
+The Unix name specified should be a valid username in the <I CLASS="filename">
+/etc/passwd</i> file. The NT name should be the username to which you want to Unix username to map on an NT client. This option will work with Windows NT clients only.</p><P CLASS="para">
+If you would like more information on how Windows NT uses domain usernames and local groups, we recommend Eric Pearce's <CITE CLASS="citetitle">
+Windows NT in a Nutshell</cite>, published by O'Reilly.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-961962">
+6.5.3.4 local group map</a></h4><P CLASS="para">
+This option specifies the location of a mapping file designed to translate Windows NT local group names to Unix group names. Local group names include those such as Administrator and Users. The file should reside on the Samba server. For example:</p><PRE CLASS="programlisting">/usr/local/samba/private/localgroup.mapping</pre><P CLASS="para">The file has a simple format:</p><PRE CLASS="programlisting"><CODE CLASS="replaceable"><I>UnixGroup</i></code> = [BUILTIN\]<CODE CLASS="replaceable"><I>NTGroup</i></code></pre><P CLASS="para">
+An example entry is:</p><PRE CLASS="programlisting">
+root = BUILTIN\Administrators</pre><P CLASS="para">
+This option will work with Windows NT clients only. For more information, see Eric Pearce's <CITE CLASS="citetitle">
+Windows NT in a Nutshell</cite> (O'Reilly).</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962075">
+6.5.3.5 revalidate</a></h4><P CLASS="para">
+This share-level option tells Samba to force users to authenticate with passwords each time they connect to a different share on a machine, no matter what level of security is in place on the Samba server. The default value is <CODE CLASS="literal">
+no</code>, which allows users to be trusted once they successfully authenticate themselves. You can override it as:</p><PRE CLASS="programlisting">
+revalidate = yes</pre><P CLASS="para">
+You can use this option to increase security on your system. However, you should weigh it against the inconvenience of having users revalidate themselves to every share. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_04.html" TITLE="6.4 Passwords">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.4 Passwords" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_06.html" TITLE="6.6 Logon Scripts">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 6.6 Logon Scripts" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.4 Passwords</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+6.6 Logon Scripts</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch06_06.html b/docs/htmldocs/using_samba/ch06_06.html
new file mode 100755
index 00000000000..f80e4d37464
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch06_06.html
@@ -0,0 +1,537 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 6] 6.6 Logon Scripts</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:34:19Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_05.html" TITLE="6.5 Windows Domains">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.5 Windows Domains" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch06_01.html" TITLE="6. Users, Security, and Domains ">
+Chapter 6<br>
+Users, Security, and Domains </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch07_01.html" TITLE="7. Printing and Name Resolution">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7. Printing and Name Resolution" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch06-38153">
+6.6 Logon Scripts</a></h2><P CLASS="para">Samba supports the execution of Windows logon scripts, which are scripts (.BAT or .CMD) that are executed on the client when a user logs on to a Windows domain. Note that these scripts are stored on the Unix side, but are transported across the network to the client side and executed once a user logs on. These scripts are invaluable for dynamically setting up network configurations for users when they log on. The downside is that because they run on Windows, they must use the Windows network configuration commands.</p><P CLASS="para">
+If you would like more information on NET commands, we recommend the following O'Reilly handbooks: <EM CLASS="emphasis">
+Windows NT in a Nutshell</em>, <EM CLASS="emphasis">
+Windows 95 in a Nutshell</em>, and <EM CLASS="emphasis">
+Windows 98 in a Nutshell.</em></p><P CLASS="para">
+You can instruct Samba to use a logon script with the <CODE CLASS="literal">
+logon</code> <CODE CLASS="literal">
+script</code> option, as follows:</p><PRE CLASS="programlisting">
+[global]
+ domain logons = yes
+ security = user
+ workgroup = SIMPLE
+
+ os level = 34
+ local master = yes
+ preferred master = yes
+ domain master = yes
+ logon script = %U.bat
+
+[netlogon]
+ comment = The domain logon service
+ path = /export/samba/logon
+ public = no
+ writeable = no
+ browsable = no</pre><P CLASS="para">
+Note that this example uses the <CODE CLASS="literal">
+%U</code> variable, which will individualize the script based on the user that is logging in. It is common to customize logon scripts based on the user or machine name that is logging onto the domain. These scripts can then be used to configure individual settings for users or clients.</p><P CLASS="para">
+Each logon script should be stored at the base of the <CODE CLASS="literal">
+[netlogon]</code> share. For example, if the base of the <CODE CLASS="literal">
+[netlogon]</code> share is <I CLASS="filename">
+/export/samba/logon</i> and the logon script is <I CLASS="filename">
+jeff.bat</i>, the file should be located at <I CLASS="filename">
+/export/samba/logon/jeff.bat</i>. When a user logs on to a domain that contains a startup script, he or she will see a small dialog that informs them that the script is executing, as well as any output the script generates in an MS-DOS-like box.</p><P CLASS="para">
+One warning: because these scripts are loaded by Windows and executed on the Windows side, they must consist of DOS formatted carriage-return/linefeed characters instead of Unix carriage returns. It's best to use a DOS- or Windows-based editor to create them.</p><P CLASS="para">
+Here is an example of a logon script that sets the current time to match that of the Samba server and maps two network drives, <CODE CLASS="literal">
+h</code> and <CODE CLASS="literal">
+i</code>, to individual shares on the server:</p><PRE CLASS="programlisting">
+# Reset the current time to that shown by the server.
+# We must have the &quot;time server = yes&quot; option in the
+# smb.conf for this to work.
+
+echo Setting Current Time...
+net time \\hydra /set /yes
+
+# Here we map network drives to shares on the Samba
+# server
+echo Mapping Network Drives to Samba Server Hydra...
+net use h: \\hydra\data
+net use i: \\hydra\network</pre><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-960385">
+6.6.1 Roaming profiles</a></h3><P CLASS="para">
+<I CLASS="firstterm">
+</i>In Windows 95 and NT, each user can have his or her own <I CLASS="firstterm">
+profile</i>. A profile bundles information such as: the appearance of a user's desktop, the applications that appear on the start menus, the background, and other miscellaneous items. If the profile is stored on a local disk, it's called a <I CLASS="firstterm">
+local profile</i>, since it describes what a user's environment is like on one machine. If the profile is stored on a server, on the other hand, the user can download the same profile to any client machine that is connected to the server. The latter is called a <I CLASS="firstterm">
+roaming profile</i> because the user can roam around from machine to machine and still use the same profile. This makes it particularly convenient when someone might be logging in from his or her desk one day and from a portable in the field the next. <A CLASS="xref" HREF="ch06_06.html#ch06-71393">
+Figure 6.6</a> illustrates local and roaming profiles. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch06-71393">
+Figure 6.6: Local profiles versus roaming profiles</a></h4><IMG CLASS="graphic" SRC="figs/sam.0606.gif" ALT="Figure 6.6"><P CLASS="para">
+
+
+<!-- 2.0.7 amendment begins, davecb -->
+<P>Samba will provide roaming profiles if it is configured for domain logons
+and you set <CODE CLASS="literal">logon path</CODE> to the user's home
+directory and <CODE CLASS="literal">logon home </CODE> to a
+subdirectory of the user's home directory used to store profiles. These
+options are typically used with one of the user variables, as shown in this
+example:
+<PRE CLASS="programlisting">
+[global]
+ domain logons = yes
+ security = user
+ workgroup = SIMPLE
+ os level = 34
+ local master = yes
+ preferred master = yes
+ domain master = yes
+
+ logon home = \\%N\%U
+ logon path = \\%N\%U\profile <!-- from the man page -->
+</PRE>
+<P> Samba versions previous to 2.0.6 allowed Win9X machines to store
+profiles in separate shares, but that prevented the clients from setting
+their <CODE CLASS="literal">logon path</CODE> so they could get their home
+directory mounted by saying "net use /home". This was corrected in
+2.0.6.</P>
+
+<!-- end of profiles modification -->
+<!-- WARNING: we never warn anywhere that "Windows clients can sometimes
+maintain a connection to the [homes] share, even though there is
+no user logged in. Therefore, it is vital that the logon path does not
+include a reference to the homes share." I read the above as being
+equivalen to the homes share, just not leiterally [homes]. I expect
+the bug will persist. davecb-->
+
+
+Once a user initially logs on, the Windows client will create a <I CLASS="filename">
+user.dat</i> or <I CLASS="filename">
+ntuser.dat</i> file&nbsp;- depending on which operating system the client is running. The client then uploads the contents of the desktop, the Start Menu, the Network Neighborhood, and the programs folders in individual folders in the directory. When the user subsequently logs on, those contents will be downloaded from the server and activated for the client machine with which the user is logging on. When he or she logs off, those contents will be uploaded back on the server until the next time the user connects. If you look at the directory listing of a profile folder, you'll see the following:</p><PRE CLASS="programlisting">
+# ls -al
+
+total 321
+drwxrwxr-x 9 root simple Jul 21 20:44 .
+drwxrwxr-x 4 root simple Jul 22 14:32 ..
+drwxrwx--- 3 fred develope Jul 12 07:15 Application Data
+drwxrwx--- 3 fred develope Jul 12 07:15 Start Menu
+drwxrwx--- 2 fred develope Jul 12 07:15 cookies
+drwxrwx--- 2 fred develope Jul 12 07:15 desktop
+drwxrwx--- 7 fred develope Jul 12 07:15 history
+drwxrwx--- 2 fred develope Jul 12 07:15 nethood
+drwxrwx--- 2 fred develope Jul 19 21:05 recent
+-rw------- 1 fred develope Jul 21 21:59 user.dat</pre><P CLASS="para">
+The <I CLASS="filename">
+user.dat</i> files are binary configuration files, created automatically by Windows. They can be edited with the Profile Editor on a Windows client, but they can be somewhat tricky to get correct. Samba supports them correctly for all clients up to NT 5.0 beta, but they're still relatively new<I CLASS="firstterm"></i>.</p><P CLASS="para">
+Hints and HOWTOs for handling logon scripts are available in the Samba documentation tree, in both <I CLASS="filename">
+docs/textdocs/DOMAIN.txt</i> and <I CLASS="filename">
+docs/textdocs/PROFILES.txt</i>.<I CLASS="firstterm">
+</i> </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-961462">
+6.6.2 Mandatory profiles</a></h3><P CLASS="para">Users can also have <I CLASS="firstterm">
+mandatory profiles</i>, which are roaming profiles that they cannot change. For example, with a mandatory profile, if a user adds a command to the Start Menu on Tuesday, it will be gone when he or she logs in again on Wednesday. The mandatory profile is simply a <I CLASS="filename">
+user.dat</i> file that has been renamed to <I CLASS="filename">
+user.man</i> and made read-only on the Unix server. It normally contains settings that the administrator wishes to ensure the user always executes. For example, if an administrator wants to create a fixed user configuration, he or she can do the following:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957763">
+</a>Create the read-write directory on the Samba server. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957764">
+</a>Set the <CODE CLASS="literal">
+logon</code> <CODE CLASS="literal">
+path</code> option in the <EM CLASS="emphasis">
+smb.conf</em> file to point to this directory.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957765">
+</a>Logon as the user from Windows 95/98 to have the client populate the directory. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957766">
+</a>Rename the resulting <I CLASS="filename">
+user.dat</i> to <I CLASS="filename">
+user.man</i>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch06-pgfId-957767">
+</a>Make the directory and its contents read only.</p></li></ol><P CLASS="para">
+Mandatory profiles are fairly unusual. Roaming profiles, on the other hand, are one of the more desirable features of Windows that Samba can support.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-962637">
+6.6.3 Logon Script Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch06_06.html#ch06-46661">Table 6.10</a> summarizes the options commonly used in association with Windows domain logon scripts. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-46661">
+Table 6.10: Logon Script Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+logon script</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (DOS path)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Name of DOS/NT batch file</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+logon path</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (UNC server and share name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Location of roaming profile for user</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\\%N\%U\profile</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+logon drive</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (drive letter)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the logon drive for a home directory (NT only)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+Z</code>:</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+logon home</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (UNC server and share name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies a location for home directories for clients logging on to the domain</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+\\%N\%U</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962334">
+6.6.3.1 logon script</a></h4><P CLASS="para">
+This option specifies a Windows .BAT or .CMD file with lines ending in carriage-return/line feed that will be executed on the client after a user has logged on to the domain. Each logon script should be stored at the base of a share entitled <CODE CLASS="literal">
+[netlogin]</code> (see the section <A CLASS="xref" HREF="ch06_05.html#ch06-36822">
+Section 6.5.1</a> for details.) This option frequently uses the <CODE CLASS="literal">
+%U</code> or <CODE CLASS="literal">
+%m</code> variables (user or NetBIOS name) to point to an individual script. For example:</p><PRE CLASS="programlisting">
+logon script = %U.bat</pre><P CLASS="para">
+will execute a script based on the username located at the base of the <CODE CLASS="literal">
+[netlogin]</code> share. If the user who is connecting is <CODE CLASS="literal">
+fred</code> and the path of the <CODE CLASS="literal">
+[netlogin]</code> share maps to the directory <I CLASS="filename">
+/export/samba/netlogin</i>, the script should be <I CLASS="filename">
+/export/samba/netlogin/fred.bat</i>. Because these scripts are downloaded to the client and executed on the Windows side, they must consist of DOS formatted carriage-return/linefeed characters instead of Unix carriage returns.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962671">
+6.6.3.2 logon path</a></h4><P CLASS="para">
+This option provides a location for roaming profiles. When the user logs on, a roaming profile will be downloaded from the server to the client and activated for the user who is logging on. When the user logs off, those contents will be uploaded back on the server until the next time the user connects. </p><P CLASS="para">
+It is often more secure to create a separate share exclusively for storing user profiles:</p><PRE CLASS="programlisting">
+logon path = \\hydra\profile\%U</pre><P CLASS="para">
+For more informaiton on this option, see the section <A CLASS="xref" HREF="ch06_06.html">
+Section 6.6, Logon Scripts</a>, earlier in this chapter.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962332">
+6.6.3.3 logon drive</a></h4><P CLASS="para">
+This option specifies the drive letter on an NT client to which the home directory specified with the <CODE CLASS="literal">
+logon</code> <CODE CLASS="literal">
+home</code> option will be mapped. Note that this option will work with Windows NT clients only. For example:</p><PRE CLASS="programlisting">
+logon home = I:</pre><P CLASS="para">
+You should always use drive letters that will not conflict with fixed drives on the client machine. The default is Z:, which is a good choice because it is as far away from A:, C:, and D: as possible.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-962319">
+6.6.3.4 logon home </a></h4><P CLASS="para">
+This option specifies the location of a user's home directory for use by the DOS NET commands. For example, to specify a home directory as a share on a Samba server, use the following:</p><PRE CLASS="programlisting">
+logon home = \\hydra\%U</pre><P CLASS="para">
+Note that this works nicely with the <CODE CLASS="literal">
+[homes]</code> service, although you can specify any directory you wish. Home directories can be mapped with a logon script using the following command:</p><PRE CLASS="programlisting">
+NET USE I: /HOME</pre><P CLASS="para">
+In addition, you can use the User Environment Profile under User Properties in the Windows NT User Manager to verify that the home directory has automatically been set. </p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-960476">
+6.6.4 Other Connection Scripts</a></h3><P CLASS="para">After a user successfully makes a connection to any Samba share, you may want the Samba server to execute a program on its side to prepare the share for use. Samba allows scripts to be executed before and after someone connects to a share. You do not need to be using Windows domains to take advantage of the options. <A CLASS="xref" HREF="ch06_06.html#ch06-67528">
+Table 6.11</a> introduces some of the configuration options provided for setting up users. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-67528">
+Table 6.11: Connection Script Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+root preexec</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a command to run as <CODE CLASS="literal">
+root</code>, before connecting to the share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+preexec (exec)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a Unix command to run as the user before connecting to the share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+postexec</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a Unix command to run as the user after disconnecting from the share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+root postexec</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a Unix command to run as <CODE CLASS="literal">
+root</code> after disconnecting from the share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960575">
+6.6.4.1 root preexec</a></h4><P CLASS="para">
+The first form of the logon command is called <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+preexec</code>. This option specifies a Unix command as its value that will be run <EM CLASS="emphasis">
+as the root user</em> before any connection to a share is completed. You should use this option specifically for performing actions that require root privilege. For example, <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+preexec</code> can be used to mount CD-ROMs for a share that makes them available to the clients, or to create necessary directories. If no <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+preexec</code> option is specified, there is no default action. Here is an example of how you can use the command to mount a CD-ROM:</p><PRE CLASS="programlisting">
+[homes]
+ browseable = no
+ writeable = yes
+ root preexec = /etc/mount /dev/cdrom2</pre><P CLASS="para">
+Remember that these commands will be run as the root user. Therefore, in order to ensure security, users should never be able to modify the target of the <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+preexec</code> command.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960582">
+6.6.4.2 preexec</a></h4><P CLASS="para">
+The next option run before logon is the <CODE CLASS="literal">
+preexec</code> option, sometimes just called <CODE CLASS="literal">
+exec</code>. This is an ordinary unprivileged command run by Samba as the user specified by the variable <CODE CLASS="literal">
+%u</code>. For example, a common use of this option is to perform logging, such as the following:</p><PRE CLASS="programlisting">
+[homes]
+<CODE CLASS="userinput"><B>preexec = echo &quot;%u connected to %S from %m (%I)\&quot; &gt;&gt;/tmp/.log</b></code> </pre><P CLASS="para">
+Be warned that any information the command sends to standard output will not be seen by the user, but is instead thrown away. If you intend to use a <CODE CLASS="literal">
+preexec</code> script, you should ensure that it will run correctly before having Samba invoke it.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960594">
+6.6.4.3 postexec</a></h4><P CLASS="para">
+Once the user disconnects from the share, the command specified with <CODE CLASS="literal">
+postexec</code> is run as the user on the Samba server to do any necessary cleanup. This option is essentially the same as the <CODE CLASS="literal">
+preexec</code> option. Again, remember that the command is run as the user represented by <CODE CLASS="literal">
+%u</code> and any information sent to standard output will be ignored.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960596">
+6.6.4.4 root postexec</a></h4><P CLASS="para">
+Following the <CODE CLASS="literal">
+postexec</code> option, the <CODE CLASS="literal">
+root</code> <CODE CLASS="literal">
+postexec</code> command is run, if one has been specified. Again, this option specifies a Unix command as its value that will be run <EM CLASS="emphasis">
+as the </em><EM CLASS="emphasis">root user</em> before disconnecting from a share. You should use this option specifically for performing actions that require root privilege.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch06-pgfId-960610">
+6.6.5 Working with NIS and NFS</a></h3><P CLASS="para">
+Finally, Samba has the ability to work with NIS and NIS+. If there is more than one file server, and each runs Samba, it may be desirable to have the SMB client connect to the server whose disks actually house the user's home directory. It isn't normally a good idea to ship files across the network once via NFS to a Samba server, only to be sent across the network once again to the client via SMB. (For one thing, it's slow&nbsp;- about 30 percent of normal Samba speed). Therefore, there are a pair of options to tell Samba that NIS knows the name of the right server and indicate in which NIS map the information lives.</p><P CLASS="para">
+<A CLASS="xref" HREF="ch06_06.html#ch06-27466">
+Table 6.12</a> introduces some of the other configuration options specifically for setting up users. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch06-27466">
+Table 6.12: NIS Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+nis homedir</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, use NIS instead of <I CLASS="filename">
+/etc/passwd</i> to look up the path of a user's home directory</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+homedir map</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (NIS map name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the NIS map to use to look up a user's home directory</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch06-pgfId-960612">
+6.6.5.1 nis homedir and homedir map</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+nis</code> <CODE CLASS="literal">
+homedir</code> and <CODE CLASS="literal">
+homedir</code> <CODE CLASS="literal">
+map</code> options are for Samba servers on network sites where Unix home directories are provided using NFS, the automounter, and NIS (Yellow Pages).</p><P CLASS="para">
+The <CODE CLASS="literal">
+nis</code> <CODE CLASS="literal">
+homedir</code> option indicates that the home directory server for the user needs to be looked up in NIS. The <CODE CLASS="literal">
+homedir</code> <CODE CLASS="literal">
+map</code> option tells Samba what NIS map to look in for the server that has the user's home directory. The server needs to be a Samba server, so the client can do an SMB connect to it, and the other Samba servers need to have NIS installed so they can do the lookup.</p><P CLASS="para">
+For example, if user <CODE CLASS="literal">
+joe</code> asks for a share called <CODE CLASS="literal">
+[joe]</code>, and the <CODE CLASS="literal">
+nis</code> <CODE CLASS="literal">
+homedir</code> option is set to <CODE CLASS="literal">
+yes</code>, Samba will look in the file specified by <CODE CLASS="literal">
+homedir</code> <CODE CLASS="literal">
+map</code> for a home directory for <CODE CLASS="literal">
+joe</code>. If it finds one, Samba will return the associated machine name to the client. The client will then try to connect to <EM CLASS="emphasis">
+that</em> machine and get the share from there. Enabling NIS lookups looks like the following:</p><PRE CLASS="programlisting">
+[globals]
+ nis homedir = yes
+ homedir map = amd.map</pre></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_05.html" TITLE="6.5 Windows Domains">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.5 Windows Domains" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch07_01.html" TITLE="7. Printing and Name Resolution">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7. Printing and Name Resolution" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.5 Windows Domains</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+7. Printing and Name Resolution</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch07_01.html b/docs/htmldocs/using_samba/ch07_01.html
new file mode 100755
index 00000000000..a061c6a94ee
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch07_01.html
@@ -0,0 +1,565 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 7] Printing and Name Resolution</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:34:47Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_06.html" TITLE="6.6 Logon Scripts">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.6 Logon Scripts" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 7</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_02.html" TITLE="7.2 Printing to Windows Client Printers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7.2 Printing to Windows Client Printers" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch07-98459">
+7. Printing and Name Resolution</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch07-61388" TITLE="7.1 Sending Print Jobs to Samba">
+Sending Print Jobs to Samba</a><br>
+<A CLASS="sect1" HREF="ch07_02.html" TITLE="7.2 Printing to Windows Client Printers">
+Printing to Windows Client Printers</a><br>
+<A CLASS="sect1" HREF="ch07_03.html" TITLE="7.3 Name Resolution with Samba">
+Name Resolution with Samba</a></p><P>
+</p></div><P CLASS="para">This chapter tackles two Samba topics: setting up printers for use with a Samba server and configuring Samba to use or become a Windows Internet Name Service (WINS) server. Samba allows client machines to send documents to printers connected to the Samba server. In addition, Samba can also assist you with printing Unix documents to a printer on a Windows machine. In the first part of this chapter, we will discuss how to get printers configured to work on either side.</p><P CLASS="para">
+In the second half of the chapter, we will introduce the Windows Internet Name Service, Microsoft's implementation of a NetBIOS Name Server (NBNS). As mentioned in <a href="ch01_01.html"><b>Chapter 1, <CITE CLASS="chapter">Learning the Samba</cite></b></a>, an NBNS allows machines to perform name resolution on a NetBIOS network without having to rely on broadcasts. Instead, each machine knows exactly where the WINS server is and can query it for the IP addresses of other machines on the network.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch07-61388">
+7.1 Sending Print Jobs to Samba</a></h2><P CLASS="para">A printer attached to the Samba server shows up in the list of shares offered in the Network Neighborhood. If the printer is registered on the client machine and the client has the correct printer driver installed, the client can effortlessly send print jobs to a printer attached to a Samba server. <A CLASS="xref" HREF="ch07_01.html#ch07-35075">
+Figure 7.1</a> shows a Samba printer as it appears in the Network Neighborhood of a Windows client. </p><P CLASS="para">To administer printers with Samba, you should understand the basic process by which printing takes place on a network. Sending a print job to a printer on a Samba server involves four steps:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-948964">
+</a>Opening and authenticating a connection to the printer share</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-948965">
+</a>Copying the file over the network</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-948966">
+</a>Closing the connection</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-948967">
+</a>Printing and deleting the copy of the file </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-35075">
+Figure 7.1: A Samba printer in the Network Neighborhood</a></h4><IMG CLASS="graphic" SRC="figs/sam.0701.gif" ALT="Figure 7.1"></li></ol><P CLASS="para">
+When a print job arrives at a Samba server, the print data is temporarily written to disk in the directory specified by the <CODE CLASS="literal">
+path</code> option of the printer share. Samba then executes a Unix print command to send that data file to the printer. The job is printed as the authenticated user of the share. Note that this may be the guest user, depending on how the share is configured.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-951370">
+7.1.1 Print Commands</a></h3><P CLASS="para">In order to print the document, you'll need to tell Samba what the command is to print and delete a file. On Linux, such a command is:</p><PRE CLASS="programlisting">
+lpr -r -P<CODE CLASS="replaceable"><I>printer</i></code> <CODE CLASS="replaceable"><I>file</i></code></pre><P CLASS="para">
+This tells <CODE CLASS="literal">
+lpr</code> to copy the document to a spool area, usually <I CLASS="filename">
+/var/spool</i>, retrieve the name of the printer in the system configuration file (<I CLASS="filename">/etc/printcap</i>), and interpret the rules it finds there to decide how to process the data and which physical device to send it to. Note that because the <CODE CLASS="literal">
+-r</code> option has been listed, the file specified on the command line will be deleted after it has been printed. Of course, the file removed is just a copy stored on the Samba server; the original file on the client is unaffected.</p><P CLASS="para">
+Linux uses a Berkeley (BSD) style of printing. However, the process is similar on System V Unix. Here, printing and deleting becomes a compound command:</p><PRE CLASS="programlisting">lp -d<CODE CLASS="replaceable"><I>printer</i></code> -s <CODE CLASS="replaceable"><I>file</i></code>; rm <CODE CLASS="replaceable"> <I>file</i></code></pre><P CLASS="para">
+With System V, the <I CLASS="filename">
+/etc/printcap</i> file is replaced with different set of configuration files hiding in <I CLASS="filename">
+/usr/spool/lp</i>, and there is no option to delete the file. You have to do it yourself, which is why we have added the <CODE CLASS="literal">
+rm</code> command afterward.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-951469">
+7.1.2 Printing Variables</a></h3><P CLASS="para">Samba provides four variables specifically for use with printing configuration options. They are shown in <A CLASS="xref" HREF="ch07_01.html#ch07-29758">
+Table 7.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch07-29758">
+Table 7.1: Printing Variables </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%s</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The full pathname of the file on the Samba server to be printed</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%f</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The name of the file itself (without the preceding path) on the Samba server to be printed</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%p</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The name of the Unix printer to use</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%j</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The number of the print job (for use with <CODE CLASS="literal">
+lprm</code>, <CODE CLASS="literal">
+lppause</code>, and <CODE CLASS="literal">
+lpresume</code>)</p></td></tr></tbody></table></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-943749">
+7.1.3 A Minimal Printing Setup</a></h3><P CLASS="para">Let's start with a simple but illustrative printing share. Assuming that you're on a Linux system and you have a printer called <CODE CLASS="literal">
+lp</code> listed in the printer capabilities file, the following addition to your <I CLASS="filename">
+smb.conf</i> file will make the printer accessible through the network:</p><PRE CLASS="programlisting">
+[printer1]
+ printable = yes
+ print command = /usr/bin/lpr -r %s
+ printer = lp
+ printing = BSD
+ read only = yes
+ guest ok = yes</pre><P CLASS="para">
+This configuration allows anyone to send data to the printer, something we may want to change later. For the moment, what's important to understand is that the variable <CODE CLASS="literal">
+%s</code> in the <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code> option will be replaced with the name of the file to be printed when Samba executes the command. Changing the <CODE CLASS="literal">
+print command</code> to reflect a different style of Unix machine typically involves only replacing the right side of the <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code> option with whatever command you need for your system and changing the target of the <CODE CLASS="literal">
+printing</code> option.</p><P CLASS="para">
+Let's look at the commands for a System V Unix. With variable substitution, the System V Unix command becomes:</p><PRE CLASS="programlisting">
+print command = lp -d%p -s %s; rm %s</pre><P CLASS="para">
+As mentioned earlier, the <CODE CLASS="literal">
+%p</code> variable resolves to the name of the printer, while the <CODE CLASS="literal">
+%s</code> variable resolves to the name of the file. After that, you can change the <CODE CLASS="literal">
+printing</code> option to reflect that you're using a System V architecture:</p><PRE CLASS="programlisting">
+printing = SYSV</pre><P CLASS="para">
+If you are using share-level security, pay special attention to the guest account used by Samba. The typical setting, <CODE CLASS="literal">
+nobody</code>, may not be allowed to print by the operating system. If that's true for your operating system, you should place a <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> option under the printing share (or even perhaps the global share) specifying an account that can. A popular candidate with the Samba authors is the <CODE CLASS="literal">
+ftp</code> account, which is often preconfigured to be safe for untrusted guest users. You can set it with the following command:</p><PRE CLASS="programlisting">
+guest account = ftp</pre><P CLASS="para">
+Another common printing issue is that clients may need to request the status of a print job sent to the Samba server. Samba will not reject a document from being sent to an already busy printer share. Consequently, Samba needs the ability to communicate not only the status of the current printing job to the client, but also which documents are currently waiting to be printed on that printer. Samba also has to provide the client the ability to pause print jobs, resume print jobs, and remove print jobs from the printing queue. Samba provides options for each of these tasks. As you might expect, they borrow functionality from existing Unix commands. The options are: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956989">
+</a><CODE CLASS="literal">
+lpq command</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956990">
+</a><CODE CLASS="literal">
+lprm command</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956991">
+</a><CODE CLASS="literal">
+lppause command</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956992">
+</a><CODE CLASS="literal">
+lpresume command</code></p></li></ul><P CLASS="para">
+We will cover these options in more detail below. For the most part, however, the value of the <CODE CLASS="literal">
+printing</code> configuration option will determine their values, and you should not need to alter the default values of these options.</p><P CLASS="para">
+Here are a few important items to remember about printing shares:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-951650">
+</a>You must put <CODE CLASS="literal">
+printable</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in all printer shares (even <CODE CLASS="literal">
+[printers]</code>), so that Samba will know that they are printer shares. If you forget, the shares will not be usable for printing and will instead be treated as disk shares.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-951651">
+</a>If you set the <CODE CLASS="literal">
+path</code> configuration option in the printer section, any files sent to the printer(s) will be copied to the directory you specify instead of to the default location of <I CLASS="filename">
+/tmp</i>. As the amount of disk space allocated to <I CLASS="filename">
+/tmp</i> can be relatively small in some Unix operating systems, many administrators opt to use <I CLASS="filename">
+/var/spool</i> or some other directory instead.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-951652">
+</a>The <CODE CLASS="literal">
+read only</code> option is ignored for printer shares.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-951648">
+</a>If you set <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in a printer share and Samba is configured for share-level security, it will allow anyone to send data to the printer as the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> user. </p></li></ul><P CLASS="para">
+Using one or more Samba machines as a print server gives you a great deal of flexibility on your LAN. You can easily partition your available printers, restricting some to members of one department, or you can maintain a bank of printers available to all. In addition, you can restrict a printer to a selected few by adding the trusty <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> option to its share definition:</p><PRE CLASS="programlisting">
+[deskjet]
+ printable = yes
+ path = /var/spool/samba/print
+ valid users = gail sam</pre><P CLASS="para">
+All of the other share accessibility options defined in the previous chapter should work for printing shares as well. Since the printers themselves are accessed through Samba by name, it's also simple to delegate print services among several servers using familiar Unix commands for tasks such as load balancing or maintenance. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-951458">
+7.1.4 The [printers] Share</a></h3><P CLASS="para">
+<a href="ch04_01.html"><b>Chapter 4, <CITE CLASS="chapter">Disk Shares </cite></b></a>, briefly introduced <CODE CLASS="literal">
+[printers]</code>, a special share for automatically creating printing services. Let's review how it works: if you create a share named <CODE CLASS="literal">
+[printers]</code> in the configuration file, Samba will automatically read in your printer capabilities file and create a printing share for each printer that appears in the file. For example, if the Samba server had <CODE CLASS="literal">
+lp</code>, <CODE CLASS="literal">
+pcl</code> and <CODE CLASS="literal">
+ps</code> printers in its printer capabilities file, Samba would provide three printer shares with those names, each configured with the options in the <CODE CLASS="literal">
+[printers]</code> share.</p><P CLASS="para">Recall that Samba obeys following rules when a client requests a share that has not been created through the <I CLASS="filename">
+smb.conf</i> file:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949501">
+</a>If the share name matches a username in the system password file and a <CODE CLASS="literal">
+[homes]</code> share exists, a new share is created with the name of the user and is initialized using the values given in the <CODE CLASS="literal">
+[homes]</code> and <CODE CLASS="literal">
+[global]</code> sections.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949506">
+</a>Otherwise, if the name matches a printer in the system printer capabilities file, and a <CODE CLASS="literal">
+[printers]</code> share exists, a new share is created with the name of the printer and initialized using the values given in the <CODE CLASS="literal">
+[printers]</code> section. (Variables in the <CODE CLASS="literal">
+[global]</code> section do not apply here.) </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949507">
+</a>If neither of those succeed, Samba looks for a <CODE CLASS="literal">
+default</code> <CODE CLASS="literal">
+service</code> share. If none is found, it returns an error.</p></li></ul><P CLASS="para">
+This brings to light an important point: be careful that you do not give a printer the same name as a user. Otherwise, you will end up connecting to a disk share when you may have wanted a printer share instead.</p><P CLASS="para">
+Here is an example <CODE CLASS="literal">
+[printers]</code> share for a Linux (BSD) system. Some of these options are already defaults; however, we have listed them anyway for illustrative purposes:</p><PRE CLASS="programlisting">
+[global]
+ printing = BSD
+ print command = /usr/bin/lpr -P%p -r %s
+ printcap file = /etc/printcap
+ min print space = 2000
+
+[printers]
+ path = /usr/spool/public
+ printable = true
+ guest ok = true
+ guest account = pcguest </pre><P CLASS="para">
+Here, we've given Samba global options that specify the printing type (BSD), a print command to send data to the printer and remove a temporary file, our default printer capabilities file, and a minimum printing space of 2 megabytes.</p><P CLASS="para">
+In addition, we've created a <CODE CLASS="literal">
+[printers]</code> share for each of the system printers. Our temporary spooling directory is specified by the <CODE CLASS="literal">
+path</code> option: <I CLASS="filename">
+/usr/spool/public</i>. Each of the shares is marked as printable&nbsp;- this is necessary, even in the <CODE CLASS="literal">
+[printers]</code> section. The two <CODE CLASS="literal">
+guest</code> options are useful in the event that Samba is using share-level security: we allow guest access to the printer and we specify the guest user that Samba should use to execute print commands. </p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-943839">
+7.1.5 Test Printing</a></h3><P CLASS="para">Here is how you can test printing from the Samba server. Let's assume the most complex case and use a guest account. First, run the Samba <EM CLASS="emphasis">
+testparm</em> command on your configuration file that contains the print shares, as we did in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>. This will tell you if there are any syntactical problems with the configuration file. For example, here is what you would see if you left out the <CODE CLASS="literal">
+path</code> configuration option in the previous example:</p><PRE CLASS="programlisting">
+# testparm
+Load smb config files from /usr/local/samba/lib/smb.conf
+Processing configuration file &quot;/usr/local/samba/lib/smb.conf&quot;
+Processing section &quot;[global]&quot;
+Processing section &quot;[homes]&quot;
+Processing section &quot;[data]&quot;
+Processing section &quot;[printers]&quot;
+No path in service printers - using /tmp
+Loaded services file OK.
+Press enter to see a dump of your service definitions
+Global parameters:
+ load printers: Yes
+ printcap name: /etc/printcap
+Default service parameters:
+ guest account: ftp
+ min print space: 0
+ print command: lpr -r -P%p %s
+ lpq command: lpq -P%p
+ lprm command: lprm -P%p %j
+lppause command:
+ lpresume command:
+ Service parameters [printers]:
+ path: /tmp
+ print ok: Yes
+ read only: true
+ public: true </pre><P CLASS="para">
+Second, try the command <CODE CLASS="literal">
+testprns</code> <CODE CLASS="replaceable">
+<I>
+printername</i></code>. This is a simple program that verifies that the specified printer is available in your <EM CLASS="emphasis">
+printcap</em> file. If your <EM CLASS="emphasis">
+printcap</em> file is not in the usual place, you can specify its full pathname as the second argument to the <EM CLASS="emphasis">
+testprns</em> command:</p><PRE CLASS="programlisting">
+# testprns lp /etc/printcap
+Looking for printer lp in printcap file /etc/printcap
+Printer name lp is valid.</pre><P CLASS="para">
+Next, log on as the guest user, go to the spooling directory, and ensure that you can print using the same command that <EM CLASS="emphasis">
+testparm</em> says Samba will use. As mentioned before, this will tell you if you need to change the guest account, as the default account may not be allowed to print.</p><P CLASS="para">
+Finally, print something to the Samba server via <CODE CLASS="literal">
+smbclient</code>, and see if the following actions occur:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-943874">
+</a>The job appears (briefly) in the Samba spool directory specified by the path.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-943875">
+</a>The job shows up in your print systems spool directory.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-943876">
+</a>The job disappears from the spool directory that Samba used.</p></li></ul><P CLASS="para">
+If <EM CLASS="emphasis">
+smbclient</em> cannot print, you can reset the <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code> option to collect debugging information:</p><PRE CLASS="programlisting">
+print command = /bin/cat %s &gt;&gt;/tmp/printlog; rm %s</pre><P CLASS="para">
+or:</p><PRE CLASS="programlisting">
+print command = echo &quot;printed %s on %p&quot; &gt;&gt;/tmp/printlog</pre><P CLASS="para">
+A common problem with Samba printer configuration is forgetting to use the full pathnames for commands; simple commands often don't work because the guest account's PATH doesn't include them. Another frequent problem is not having the correct permissions on the spooling directory. </p><P CLASS="para">There is more information on debugging printers in the Samba documentation (<I CLASS="filename">Printing.txt</i>). In addition, the Unix print systems are covered in detail in AEleen Frisch's <EM CLASS="emphasis">
+Essential Systems Administration</em> (published by O'Reilly).</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-943883">
+7.1.6 Setting Up and Testing a Windows Client</a></h3><P CLASS="para">Now that Samba is offering a workable printer, you need to set it up on a Windows client. Look at the Samba server in the Network Neighborhood. It should now show each of the printers that are available. For example, in <A CLASS="xref" HREF="ch07_01.html#ch07-35075">
+Figure 7.1</a>, we saw a printer called <CODE CLASS="literal">
+lp</code>.</p><P CLASS="para">
+Next, you need to have the Windows client recognize the printer. Double-click on the printer icon to get started. If you try to select an uninstalled printer (as you just did), Windows will ask you if it should help configure it for the Windows system. Respond "Yes," which will open the Printer Wizard. </p><P CLASS="para">
+The first thing the wizard will ask is whether you need to print from DOS. Let's assume you don't, so choose No and press the Next button to get to the manufacturer/model window as shown in <A CLASS="xref" HREF="ch07_01.html#ch07-60084">
+Figure 7.2</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-60084">
+Figure 7.2: A printer in the Network Neighborhood</a></h4><IMG CLASS="graphic" SRC="figs/sam.0702.gif" ALT="Figure 7.2"><P CLASS="para">
+In this dialog box, you should see a large list of manufacturers and models for almost every printer imaginable. If you don't see your printer on the list, but you know it's a PostScript printer, select Apple as the manufacturer and Apple LaserWriter as the model. This will give you the most basic Postscript printer setup, and arguably one of the most reliable. If you already have any Postscript printers attached, you will be asked about replacing or reusing the existing driver. Be aware that if you replace it with a new one, you may make your other printers fail. Therefore, we recommend you keep using your existing printer drivers as long as they're working properly.</p><P CLASS="para">
+Following that, the Printer Wizard will ask you to name the printer. <A CLASS="xref" HREF="ch07_01.html#ch07-69466">
+Figure 7.3</a> shows this example, where the name has defaulted to our second laserwriter. Here, you rename it from Apple Laserwriter (Copy 2) to "ps on Samba server," so you know where to look for the printouts. In reality, you can name the printer anything you want. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-69466">
+Figure 7.3: Printer manufacturers and models</a></h4><IMG CLASS="graphic" SRC="figs/sam.0703.gif" ALT="Figure 7.3"><P CLASS="para">
+Finally, the Printing Wizard asks if it should print a test page. Click on Yes, and you should be presented with the dialog in <A CLASS="xref" HREF="ch07_01.html#ch07-43374">
+Figure 7.4</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-43374">
+Figure 7.4: Printing successfully completed</a></h4><IMG CLASS="graphic" SRC="figs/sam.0704.gif" ALT="Figure 7.4"><P CLASS="para">
+If the test printing was unsuccessful, press the No button in <A CLASS="xref" HREF="ch07_01.html#ch07-43374">
+Figure 7.4</a> and the Printing Wizard will walk you through some debugging steps for the client side of the process. If the test printing does work, congratulations! The remote printer will now be available to all your PC applications through the File and Print menu items.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-30008">
+7.1.7 Automatically Setting Up Printer Drivers</a></h3><P CLASS="para">The previous section described how to manually configure a printer driver for your Windows system. As a system administrator, however, you can't always guarantee that users can perform such a process without making mistakes. Luckily, however, you can ask Samba to automatically set up the printer drivers for a specific printer.</p><P CLASS="para">
+Samba has three options that can be used to automatically set up printer drivers for clients who are connecting for the first time. These options are <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code>, <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+file</code>, and <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+location</code>. This section explains how to use these options to allow users to skip over the Manufacturer dialog in the Add Printer Wizard above.</p><P CLASS="para">
+For more information on how to do this, see the <I CLASS="filename">
+PRINTER_DRIVER.TXT</i> file in the Samba distribution documentation.</p><P CLASS="para">
+There are four major steps:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949602">
+</a>Install the drivers for the printer on a Windows client (the printer need not be attached).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949746">
+</a>Create a printer definition file from the information on a Windows machine.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949600">
+</a>Create a <CODE CLASS="literal">
+PRINTER$</code> share where the resulting driver files can be placed.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949601">
+</a>Modify the Samba configuration file accordingly.</p></li></ol><P CLASS="para">
+Let's go over each of the four steps in greater detail.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949749">
+7.1.7.1 Install the drivers on a windows client</a></h4><P CLASS="para">
+Use Windows 95/98 for this step. It doesn't matter which client you choose, as long as it has the ability to load the appropriate drivers for the printer. In fact, you don't even need to have the printer attached to the machine. All you're interested in here is getting the appropriate driver files into the Windows directory. First, go to the Printers window of My Computer and double-click on the Add Printer icon, as shown in <A CLASS="xref" HREF="ch07_01.html#ch07-52397">
+Figure 7.5</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-52397">
+Figure 7.5: The Printers window</a></h4><IMG CLASS="graphic" SRC="figs/sam.0705.gif" ALT="Figure 7.5"><P CLASS="para">
+At this point, you can follow the Add Printer Wizard dialogs through to select the manufacturer and model of the printer in question. If it asks you if you want to print from MS-DOS, answer No. Windows should load the appropriate driver resources from its CD-ROM and ask you if you want to print a test page. Again, respond No and close the Add Printer Wizard dialog.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949606">
+7.1.7.2 Create a printer definition file</a></h4><P CLASS="para">
+You can create a printer definition file by using the <I CLASS="filename">
+make_ printerdef</i> script in the <I CLASS="filename">
+/usr/local/samba/bin</i> directory. In order to use this script, you need to copy over the following four files from a Windows client:[<A CLASS="footnote" HREF="#ch07-pgfId-951615">1</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch07-pgfId-951615">[1]</a> Older Windows 95 clients may have only the first two files.</p></div></blockquote><TABLE CLASS="simplelist" BORDER="0">
+<TR>
+<TD CLASS="member">
+<EM CLASS="emphasis">
+C:\WINDOWS\INF\MSPRINT.INF</em></td></tr><TR>
+<TD CLASS="member">
+<EM CLASS="emphasis">
+C:\WINDOWS\INF\MSPRINT2.INF</em></td></tr><TR>
+<TD CLASS="member">
+<EM CLASS="emphasis">
+C:\WINDOWS\INF\MSPRINT3.INF</em></td></tr><TR>
+<TD CLASS="member">
+<EM CLASS="emphasis">
+C:\WINDOWS\INF\MSPRINT4.INF</em></td></tr></table><P CLASS="para">
+Once you have the four files, you can create a printer definition file using the appropriate printer driver and its .INF file. If the printer driver starts with the letters A-K, use either the <EM CLASS="emphasis">
+MSPRINT.INF</em> file or the <EM CLASS="emphasis">
+MSPRINT3.INF</em> file. If it begins with the letters L-Z, use the <EM CLASS="emphasis">
+MSPRINT2.INF</em> file or the <EM CLASS="emphasis">
+MSPRINT4.INF</em> file. You may need to <EM CLASS="emphasis">
+grep</em> through each of the files to see where your specific driver is. For the following example, we have located our driver in <EM CLASS="emphasis">
+MSPRINT3.INF</em> and created a printer definition file for a HP DeskJet 560C printer:</p><PRE CLASS="programlisting">
+$grep &quot;HP DeskJet 560C Printer&quot; MSPRINT.INF MSPRINT3.INF
+MSPRINT3.INF: &quot;HP DeskJet 560C Printer&quot;=DESKJETC.DRV,HP_DeskJet_ ...
+
+$make_printerdef MSPRINT3.INF &quot;HP DeskJet 560C Printer&quot; &gt;printers.def
+FOUND:DESKJETC.DRV
+End of section found
+CopyFiles: DESKJETC,COLOR_DESKJETC
+Datasection: (null)
+Datafile: DESKJETC.DRV
+Driverfile: DESKJETC.DRV
+Helpfile: HPVDJC.HLP
+LanguageMonitor: (null)
+
+Copy the following files to your printer$ share location:
+DESKJETC.DRV
+HPVCM.HPM
+HPVIOL.DLL
+HPVMON.DLL
+HPVRES.DLL
+HPCOLOR.DLL
+HPVUI.DLL
+HPVDJCC.HLP
+color\HPDESK.ICM</pre><P CLASS="para">
+Note the files that the script asks you to copy. You'll need those for the next step.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949683">
+7.1.7.3 Create a PRINTER$ share</a></h4><P CLASS="para">This part is relatively easy. Create a share called <CODE CLASS="literal">
+[PRINTER$]</code> in your <I CLASS="filename">
+smb.conf</i> that points to an empty directory on the Samba server. Once that is done, copy over the files that the <I CLASS="filename">
+make_ printerdef</i> script requested of you into the location of the <CODE CLASS="literal">
+path</code> configuration option for the <CODE CLASS="literal">
+[PRINTER$]</code> share. For example, you can put the following in your configuration file:</p><PRE CLASS="programlisting">
+[PRINTER$]
+ path = /usr/local/samba/print
+ read only = yes
+ browsable = no
+ guest ok = yes</pre><P CLASS="para">
+The files requested by the <I CLASS="filename">
+make_ printerdef</i> script are typically located in the <EM CLASS="emphasis">
+C:\WINDOWS\SYSTEM</em> directory, although you can use the following commands to find out exactly where they are:</p><PRE CLASS="programlisting">
+cd C:\WINDOWS
+dir <CODE CLASS="replaceable">
+<I>
+filename</i></code> /s</pre><P CLASS="para">
+In this case, each of the files needs to be copied to the <I CLASS="filename">
+/usr/local/samba/print</i> directory on the Samba server. In addition, copy the <I CLASS="filename">
+printers.def</i> file that you created over to that share as well. Once you've done that, you're almost ready to go. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949694">
+7.1.7.4 Modify the Samba configuration file</a></h4><P CLASS="para">
+<I CLASS="filename">
+</i>The last step is to modify the Samba configuration file by adding the following three options: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956995">
+</a><CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956996">
+</a><CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+file</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-956997">
+</a><CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+location</code></p></li></ul><P CLASS="para">
+The <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+file</code> is a global option that points to the <I CLASS="filename">
+printers.def</i> file; place that option in your <CODE CLASS="literal">
+[global]</code> section. The other options should be set in the printer share for which you wish to automatically configure the drivers. The value for <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> should match the string that shows up in the Printer Wizard on the Windows system. The value of the <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> <CODE CLASS="literal">
+location</code> is the pathname of the PRINTER$ share you set up, not the Unix pathname on the server. Thus, you could use the following:</p><PRE CLASS="programlisting">
+[global]
+ printer driver file = /usr/local/samba/print/printers.def
+[hpdeskjet]
+ path = /var/spool/samba/printers
+ printable = yes
+
+ printer driver = HP DeskJet 560C Printer
+ printer driver location = \\%L\PRINTER$</pre><P CLASS="para">
+Now you're ready to test it out. At this point, remove the Windows printer that you "set up" in the first step from the list of printers in the Printers window of My Computer. If Samba asks you to delete unneeded files, do so. These files will be replaced shortly on the client, as they now exist on the Samba server.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949710">
+7.1.7.5 Testing the configuration</a></h4><P CLASS="para">
+Restart the Samba daemons and look for the <CODE CLASS="literal">
+[hpdeskjet]</code> share under the machine name in the Network Neighborhood. At this point, if you click on the printer icon, you should begin the printer setup process and come to the dialog shown in <A CLASS="xref" HREF="ch07_01.html#ch07-60108">
+Figure 7.6</a>.</p><P CLASS="para">
+This is different from the dialog you saw earlier when setting up a printer. Essentially, the dialog is asking if you wish to accept the driver that is "already installed"&nbsp;- in other words, offered by Samba. Go ahead and keep the existing driver, and press the Next button. At this point, you can give the printer a name and print out a test page. If it works, the setup should be complete. You should be able to repeat the process now from any Windows client. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-60108">
+Figure 7.6: Automatically configuring the printer driver</a></h4><IMG CLASS="graphic" SRC="figs/sam.0706.gif" ALT="Figure 7.6"></div></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch06_06.html" TITLE="6.6 Logon Scripts">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 6.6 Logon Scripts" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_02.html" TITLE="7.2 Printing to Windows Client Printers">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7.2 Printing to Windows Client Printers" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+6.6 Logon Scripts</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+7.2 Printing to Windows Client Printers</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch07_02.html b/docs/htmldocs/using_samba/ch07_02.html
new file mode 100755
index 00000000000..c9a9010e976
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch07_02.html
@@ -0,0 +1,757 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 7] 7.2 Printing to Windows Client Printers</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:34:58Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_01.html" TITLE="7.1 Sending Print Jobs to Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.1 Sending Print Jobs to Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch07_01.html" TITLE="7. Printing and Name Resolution">
+Chapter 7<br>
+Printing and Name Resolution</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_03.html" TITLE="7.3 Name Resolution with Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7.3 Name Resolution with Samba" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch07-31526">
+7.2 Printing to Windows Client Printers</a></h2><P CLASS="para">If you have printers connected to clients running Windows 95/98 or NT 4.0, those printers can also be accessed from Samba. Samba comes equipped with a tool called <EM CLASS="emphasis">
+smbprint</em> that can be used to spool print jobs to Windows-based printers. In order to use this, however, you need to set up the printer as a shared resource on the client machine. If you haven't already done this, you can reset this from the Printers window, reached from the Start button, as shown in <A CLASS="xref" HREF="ch07_02.html#ch07-32814">
+Figure 7.7</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-32814">
+Figure 7.7: The Printers window</a></h4><IMG CLASS="graphic" SRC="figs/sam.0707.gif" ALT="Figure 7.7"><P CLASS="para">
+Select a printer that's locally connected (for example, ours is the Canon printer), press the right mouse button to bring up a menu, and select Sharing. This will give you the Sharing tab of the Printer Properties frame, as shown in <A CLASS="xref" HREF="ch07_02.html#ch07-92021">
+Figure 7.8</a>. If you want it available to everybody on your LAN as the Windows guest user, enter a blank password. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-92021">
+Figure 7.8: The Sharing tab of the printer</a></h4><IMG CLASS="graphic" SRC="figs/sam.0708.gif" ALT="Figure 7.8"><P CLASS="para">
+Once you've got this working, you can add your printer to the list of standard printers and Samba can make it available to all the other PCs in the workgroup. To make installation on Unix easier, the Samba distribution provides two sample scripts: <I CLASS="filename">
+smbprint</i> and <I CLASS="filename">
+smbprint.sysv</i>. The first works with BSD-style printers; the second is designed for System V printers.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-949813">
+7.2.1 BSD printers</a></h3><P CLASS="para">There are two steps you need to have a BSD Unix recognize a remote printer:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949817">
+</a>Place an entry for the printer in the <I CLASS="filename">
+/etc/printcap</i> file (or equivalent).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949818">
+</a>Place a configuration file in the <I CLASS="filename">
+/var/spool</i> directory for the printer.</p></li></ol><P CLASS="para">
+First, edit your <I CLASS="filename">
+/etc/printcap</i> file and add an entry for the remote printer. Note that the input filter (<CODE CLASS="literal">if</code>) entry needs to point to the <EM CLASS="emphasis">
+smbprint</em> program if the machine is on Windows 95/98. The following set of lines will accomplish on a Linux machine, for example:</p><PRE CLASS="programlisting">
+laserjet:\
+ :sd=/var/spool/lpd/laser:\ <CODE CLASS="replaceable">
+<I>
+# spool directory</i></code>
+ :mx#0:\ <CODE CLASS="replaceable">
+<I>
+# maximum file size (none)</i></code>
+ :sh:\ <CODE CLASS="replaceable">
+<I>
+# surpress burst header (no)</i></code>
+ :if=/usr/local/samba/bin/smbprint: <CODE CLASS="replaceable">
+<I>
+# text filter</i></code></pre><P CLASS="para">
+After that, you need to create a configuration file in the spool directory that you specified with the <CODE CLASS="literal">
+sd</code> parameter above. (You may need to create that directory.) The file must have the name <EM CLASS="emphasis">
+.config</em> and should contain the following information: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-954773">
+</a>The NetBIOS name of the Windows machine with the printer</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-954774">
+</a>The service name that represents the printer</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-954775">
+</a>The password used to access that service</p></li></ul><P CLASS="para">
+The last two parameters were set up in the Sharing dialog for the requested resource on the Windows machine. In this case, the <EM CLASS="emphasis">
+.config</em> file would have three lines:</p><PRE CLASS="programlisting">
+server = phoenix
+service = CANON
+password = &quot;&quot;</pre><P CLASS="para">
+After you've done that, reset the Samba server machine and try printing to it using any standard Unix program.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-949855">
+7.2.2 System V printers</a></h3><P CLASS="para">Sending print jobs from a System V Unix system is a little easier. Here, you need to get obtain the <I CLASS="filename">
+smbprint.sysv</i> script in the <I CLASS="filename">
+/usr/local/samba/examples/printing</i> directory and do the following:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949865">
+</a>Change the <CODE CLASS="literal">
+server</code>, <CODE CLASS="literal">
+service</code>, and <CODE CLASS="literal">
+password</code> parameters in the script to match the NetBIOS machine, its shared printer service, and its password, respectively. For example, the following entries would be correct for the service in the previous example:</p></li></ol><PRE CLASS="programlisting">
+server = phoenix
+service = CANON
+password = &quot;&quot;</pre><OL CLASS="orderedlist" START="2">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-949876">
+</a>Run the following commands, which create a reference for the printer in the printer capabilities file. Note that the new Unix printer entry <CODE CLASS="literal">canon_printer</code> is named:</p></li></ol><PRE CLASS="programlisting">
+# lpadmin -p canon_printer -v /dev/null -i ./smbprint.sysv
+# enable canon_printer
+# accept canon_printer</pre><P CLASS="para">
+After you've done that, restart the Samba daemons and try printing to it using any standard Unix program. You should now be able to send data to a printer on a Windows client across the network.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-950287">
+7.2.3 Samba Printing Options</a></h3><P CLASS="para">
+<A CLASS="xref" HREF="ch07_02.html#ch07-19361">Table 7.2</a> summarizes the Samba printing options. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch07-19361">
+Table 7.2: Printing Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printing</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+bsd</code>, <CODE CLASS="literal">
+sysv</code>, <CODE CLASS="literal">
+hpux</code>, <CODE CLASS="literal">
+aix</code>, <CODE CLASS="literal">
+qnx</code>, <CODE CLASS="literal">
+plp</code>, <CODE CLASS="literal">
+softq</code>, or <CODE CLASS="literal">
+lprng</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the print system type for your Unix system.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+System dependent</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printable (print ok)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Marks a share as a printing share.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printer (printer name)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (Unix printer name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the name of the printer to be shown to clients.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+System dependent</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printer driver</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (printer driver name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the driver name that should be used by the client to send data to the printer.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printer driver file</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the name of the printer driver file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printer driver location</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (network pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the pathname of the share for the printer driver file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lpq cache time</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric (time in seconds)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the amount of time in seconds that Samba will cache the lpq status.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+10</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+postscript</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Treats all print jobs sent as postscript by prepending <CODE CLASS="literal">
+%!</code> at the beginning of each file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+load printers</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Automatically loads each of the printers in the <EM CLASS="emphasis">
+printcap</em> file as printing shares.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+print command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to perform printing.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lpq command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to return the status of the printing queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lprm command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to remove a job from the printing queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lppause command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to pause a job on the printing queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lpresume command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to resume a paused job on the printing queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+printcap name</code></p><P CLASS="para">
+<CODE CLASS="literal">
+(printcap)</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the location of the printer capabilities file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+System dependent</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+min print space</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numeric (size in kilobytes)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the minimum amount of disk free space that must be present to print.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+queuepause command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to pause a queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+queueresume command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (shell command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the Unix command to resume a queue.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+See below</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950502">
+7.2.3.1 printing</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+printing</code> configuration option tells Samba a little about your Unix printing system, in this case which printing parser to use. With Unix, there are several different families of commands to control printing and print statusing. Samba supports seven different types, as shown in <A CLASS="xref" HREF="ch07_02.html#ch07-28758">
+Table 7.3</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch07-28758">
+Table 7.3: Printing Types </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+BSD</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Berkeley Unix system</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SYSV</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+System V</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+AIX</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+AIX Operating System (IBM)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+HPUX</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Hewlett-Packard Unix </p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+QNX</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+QNX Realtime Operating System (QNX)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+LPRNG</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+LPR Next Generation (Powell)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SOFTQ</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SOFTQ system</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+PLP</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Portable Line Printer (Powell)</p></td></tr></tbody></table><P CLASS="para">
+The value for this optio.n will be one of these seven options. For example:</p><PRE CLASS="programlisting">
+printing = SYSV</pre><P CLASS="para">
+The default value of this option is system dependent and is configured when Samba is first compiled. For most systems, the <I CLASS="filename">
+configure</i> script will automatically detect the printing system to be used and configure it properly in the Samba makefile. However, if your system is a PLP, LPRNG, or QNX printing system, you will need to explicitly specify this in the makefile or the printing share.</p><P CLASS="para">
+The most common system types are BSD and SYSV. Each of the printers on a BSD Unix server are described in the printer capabilities file&nbsp;- normally <I CLASS="filename">
+/etc/printcap</i>.</p><P CLASS="para">
+Setting the <CODE CLASS="literal">
+printing</code> configuration option automatically sets at least three other printing options for the service in question: <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code>, <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+command</code>, and <CODE CLASS="literal">
+lprm</code> <CODE CLASS="literal">
+command</code>. If you are running Samba on a system that doesn't support any of these printing styles, simply set the commands for each of these manually.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950507">
+7.2.3.2 printable</a></h4><P CLASS="para">
+The printable option must be set to <CODE CLASS="literal">
+yes</code> in order to flag a share as a printing service. If this option is not set, the share will be treated as a disk share instead. You can set the option as follows:</p><PRE CLASS="programlisting">
+[printer1]
+ printable = yes</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950511">
+7.2.3.3 printer</a></h4><P CLASS="para">The option, sometimes called <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+name</code>, specifies the name of the printer on the server to which the share points. This option has no default and should be set explicitly in the configuration file, even though Unix systems themselves often recognize a default name such as <CODE CLASS="literal">
+lp</code> for a printer. For example:</p><PRE CLASS="programlisting">
+[deskjet]
+ printer = hpdkjet1</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950515">
+7.2.3.4 printer driver</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+printer</code> <CODE CLASS="literal">
+driver</code> option sets the string that Samba uses to tell Windows what the printer is. If this option is set correctly, the Windows Printer Wizard will already know what the printer is, making installation easier for end users by giving them one less dialog to worry about. The string given should match the string that shows up in the Printer Wizard, as shown in <A CLASS="xref" HREF="ch07_02.html#ch07-46183">
+Figure 7.9</a>. For example, an Apple LaserWriter typically uses <CODE CLASS="literal">
+Apple</code> <CODE CLASS="literal">LaserWriter</code>; a Hewlett Packard Deskjet 560C uses <CODE CLASS="literal">
+HP</code> <CODE CLASS="literal">
+DeskJet</code> <CODE CLASS="literal">
+560C</code> <CODE CLASS="literal">
+Printer</code>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch07-46183">
+Figure 7.9: The Add Printer Wizard dialog box in Windows 98</a></h4><IMG CLASS="graphic" SRC="figs/sam.0709.gif" ALT="Figure 7.9"><P CLASS="para">
+Automatically configuring printer drivers with Samba is explained in greater detail in the section <A CLASS="xref" HREF="ch07_01.html#ch07-30008">
+Section 7.1.7, Automatically Setting Up Printer Drivers</a>, earlier in this chapter.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-954814">
+7.2.3.5 printer driver file</a></h4><P CLASS="para">
+This global option gives the location of the Windows 95/98 printer driver definition file, which is needed to give printer drivers to clients using a Samba printer. The default value of this option is <I CLASS="filename">
+/usr/local/samba/lib/printers.def</i>. You can override this default as shown below:</p><PRE CLASS="programlisting">
+[deskjet]
+ printer driver file = /var/printers/printers.def</pre><P CLASS="para">
+This option is explained in greater detail in the section <A CLASS="xref" HREF="ch07_01.html#ch07-30008">
+Section 7.1.7</a>, earlier in this chapter.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950552">
+7.2.3.6 printer driver location</a></h4><P CLASS="para">
+This option specifies a specific share that contains Windows 95 and 98 printer driver and definition files. There is no default parameter for this value. You can specify the location as a network pathname. A frequent approach is to use a share on your own machine, as shown here:</p><PRE CLASS="programlisting">
+[deskjet]
+ printer driver location = \\%L\PRINTER$</pre><P CLASS="para">
+This option is also explained in greater detail in the section <A CLASS="xref" HREF="ch07_01.html#ch07-30008">
+Section 7.1.7</a>, earlier in this chapter. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950560">
+7.2.3.7 lpq cache time</a></h4><P CLASS="para">The global <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+cache</code> <CODE CLASS="literal">
+time</code> option allows you to set the number of seconds that Samba will remember the current printer status. After this time elapses, Samba will issue an <EM CLASS="emphasis">
+lpq</em> command (or whatever command you specify with the <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+command</code> option) to get a more up-to-date status. This defaults to 10 seconds, but can be increased if your <CODE CLASS="literal">
+lpq</code> <CODE CLASS="literal">
+command</code> takes an unusually long time to run or you have lots of clients. The following example resets the time to 30 seconds:</p><PRE CLASS="programlisting">
+[deskjet]
+ lpq cache time = 30</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950564">
+7.2.3.8 postscript</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+postscript</code> option forces the printer to treat all data sent to it as Postscript. It does this by prepending the characters <CODE CLASS="literal">
+%!</code> at the beginning of the first line of each job. It is normally used with PCs that insert a <CODE CLASS="literal">
+^D</code> (control-D or end-of-file mark) in front of the first line of a PostScript file. It will not, obviously, turn a non-PostScript printer into a PostScript one. The default value of this options is <CODE CLASS="literal">
+no</code>. You can override it as follows:</p><PRE CLASS="programlisting">[deskjet]
+ postscript = yes</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950568">
+7.2.3.9 print command, lpq command, lprm command, lppause command, lpresume command</a></h4><P CLASS="para">These options tell Samba which Unix commands used to control and send data to the printer. The Unix commands involved are: <EM CLASS="emphasis">
+lpr</em> (send to Line PRinter), <EM CLASS="emphasis">
+lpq</em> (List Printer Queue), <EM CLASS="emphasis">
+lprm</em> (Line printer ReMove), and optionally <EM CLASS="emphasis">
+lppause</em> and <EM CLASS="emphasis">
+lpresume</em>. Samba provides an option named after each of these commands, in case you need to override any of the system defaults. For example, consider:</p><PRE CLASS="programlisting">
+lpq command = /usr/ucb/lpq %p</pre><P CLASS="para">
+This would set the <CODE CLASS="literal">
+lpq command</code> to use <I CLASS="filename">
+/usr/ucb/lpq</i>. Similarly:</p><PRE CLASS="programlisting">
+lprm command = /usr/local/lprm -P%p %j</pre><P CLASS="para">
+would set the Samba printer remove command to <I CLASS="filename">
+/usr/local/lprm</i>, and provide it the print job number using the <CODE CLASS="literal">
+%j</code> variable.</p><P CLASS="para">
+The default values for each of these options are dependent on the value of the <CODE CLASS="literal">
+printing</code> option. <A CLASS="xref" HREF="ch07_02.html#ch07-82964">
+Table 7.4</a> shows the default commands for each of the printing options. The most popular printing system is BSD. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch07-82964">
+Table 7.4: Default Commands for Various Printing Commands </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+BSD, AIX, PLP, LPRNG</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SYSV, HPUX</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+QNX</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+SOFTQ</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+print command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpr -r -P%p %s</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">lp -c -d%p %s; rm %s</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lp -r -P%p %s</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lp -d%p -s %s; rm %s</code></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lpq command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpq -P%p</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpstat -o%p</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpq -P%p</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpstat -o%p</code></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lprm command</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lprm -P%p %j</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+cancel %p-%j</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+cancel %p-%j</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+cancel %p-%j</code></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lppause command</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lp -i %p-%j -H hold </code>(SYSV only)</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+None</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+None</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+None</td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lpresume command</code></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+lp -i %p-%j -H resume</code>(SYSV only)</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+None</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+None</td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<CODE CLASS="literal">
+qstat -s -j%j -r</code>
+</td></tr></tbody></table><P CLASS="para">
+It is typically not necessary to reset these options in Samba, with the possible exception of <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+command</code>. This option may need to be explicitly set if your printing system doesn't have a <CODE CLASS="literal">
+-r</code> (remove after printing) option on the printing command. For example: </p><PRE CLASS="programlisting">
+/usr/local/lpr -P%p %s; /bin/rm %s</pre><P CLASS="para">
+With a bit of judicious programming, these <I CLASS="filename">
+smb.conf</i> options can also used for debugging:</p><PRE CLASS="programlisting">
+print command = cat %s &gt;&gt;/tmp/printlog; lpr -r -P%p %s</pre><P CLASS="para">
+For example, this configuration can verify that files are actually being delivered to the Samba server. If they are, their contents will show up in the <I CLASS="filename">
+/tmp/printlog</i> file.</p><P CLASS="para">
+After BSD, the next most popular kind of printing system is SYSV (or System V) printing, plus some SYSV variants for IBM's AIX and Hewlett-Packard's HP-UX. These system do not have an <I CLASS="filename">
+/etc/printcap</i> file. Instead, the <CODE CLASS="literal">
+printcap</code> <CODE CLASS="literal">
+file</code> option can be set to an appropriate <EM CLASS="emphasis">
+lpstat</em> command for the system. This tells Samba to get a list of printers from the <EM CLASS="emphasis">
+lpstat</em> command. Alternatively, you can set the global configuration option <CODE CLASS="literal">
+printcap</code> <CODE CLASS="literal">
+name</code> to the name of a dummy <I CLASS="filename">
+printcap</i> file you provide. In the latter case, the file must contain a series of lines such as:</p><PRE CLASS="programlisting">
+lp|print1|My Printer 1
+print2|My Printer 2
+print3|My Printer 3</pre><P CLASS="para">
+Each line names a printer, and provides aliases for it. In this example, the first printer is called <CODE CLASS="literal">
+lp</code>, <CODE CLASS="literal">
+print1</code>, or <CODE CLASS="literal">
+My</code> <CODE CLASS="literal">
+Printer</code> <CODE CLASS="literal">
+1</code>, whichever the user prefers to use. The first name will be used in place of <CODE CLASS="literal">
+%p</code> in any command Samba executes for that printer.</p><P CLASS="para">
+Two additional printer types are also supported by Samba: LPRNG (LPR New Generation) and PLP (Public Line Printer). These are public domain and Open Source printing systems, and are used by many sites to overcome problems with vendor-supplied software. In addition, the SOFTQ and QNX realtime operating systems are supported by Samba.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950650">
+7.2.3.10 load printers</a></h4><P CLASS="para">The <CODE CLASS="literal">
+load</code> <CODE CLASS="literal">
+printers</code> option tells Samba to create shares for all known printer names and load those shares into the browse list. Samba will create and list a printer share for each printer name in <I CLASS="filename">
+/etc/printcap</i> (or system equivalent). For example, if your <I CLASS="filename">
+printcap</i> file looks like this:[<A CLASS="footnote" HREF="#ch07-pgfId-950654">2</a>]</p><BLOCKQUOTE CLASS="footnote">
+<DIV CLASS="footnote">
+<P CLASS="para">
+<A CLASS="footnote" NAME="ch07-pgfId-950654">[2]</a> We have placed annotated comments off to the side in case you've never dealt with this file before.</p></div></blockquote><PRE CLASS="programlisting">
+lp:\
+ :sd=/var/spool/lpd/lp:\ <CODE CLASS="replaceable">
+<I>
+# spool directory</i></code>
+ :mx#0:\ <CODE CLASS="replaceable">
+<I>
+# maximum file size (none)</i></code>
+ :sh:\ <CODE CLASS="replaceable">
+<I>
+# surpress burst header (no)</i></code>
+ :lp=/dev/lp1:\ <CODE CLASS="replaceable">
+<I>
+# device name for output</i></code>
+ :if=/var/spool/lpd/lp/filter: <CODE CLASS="replaceable">
+<I>
+# text filter</i></code>
+
+laser:\
+ :sd=/var/spool/lpd/laser:\ <CODE CLASS="replaceable">
+<I>
+# spool directory</i></code>
+ :mx#0:\ <CODE CLASS="replaceable">
+<I>
+# maximum file size (none)</i></code>
+ :sh:\ <CODE CLASS="replaceable">
+<I>
+# surpress burst header (no)</i></code>
+ :lp=/dev/laser:\ <CODE CLASS="replaceable">
+<I>
+# device name for output</i></code>
+ :if=/var/spool/lpd/lp/filter: <CODE CLASS="replaceable">
+<I>
+# text filter</i></code></pre><P CLASS="para">
+and you specify:</p><PRE CLASS="programlisting">
+load printers = yes</pre><P CLASS="para">
+the shares <CODE CLASS="literal">
+[lp]</code> and <CODE CLASS="literal">
+[laser]</code> will automatically be created as valid print shares when Samba is started. Both shares will borrow the configuration options specified in the <CODE CLASS="literal">
+[printers]</code> section to configure themselves, and will be available in the browse list for the Samba server.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950671">
+7.2.3.11 printcap name</a></h4><P CLASS="para">
+If the <CODE CLASS="literal">
+printcap</code> <CODE CLASS="literal">
+name</code> option (also called <CODE CLASS="literal">
+printcap</code>) appears in a printing share, Samba will use the file specified as the system printer capabilities file. This is normally <I CLASS="filename">
+/etc/printcap</i>. However, you can reset it to a file consisting of only the printers you want to share over the network. The value must be a fully-qualified filename of a printer capabilities file on the server:</p><PRE CLASS="programlisting">
+[deskjet]
+ printcap name = /usr/local/printcap</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950678">
+7.2.3.12 min print space</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+min</code> <CODE CLASS="literal">
+print</code> <CODE CLASS="literal">
+space</code> option sets the amount of spool space that must be available on the disk before printing is allowed. Setting it to zero (the default) turns the check off; setting it to any other number sets the amount of free space in kilobytes required. This option helps avoid having print jobs fill up the remaining disk space on the server, which may cause other processes to fail:</p><PRE CLASS="programlisting">
+[deskjet]
+ min print space = 4000</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950682">
+7.2.3.13 queuepause command</a></h4><P CLASS="para">
+This configuration option specifies a command that tells Samba how to pause a print queue entirely, as opposed to a single job on the queue. The default value depends on the printing type chosen. You should not need to alter this option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-950684">
+7.2.3.14 queueresume command</a></h4><P CLASS="para">
+This configuration option specifies a command that tells Samba how to resume a paused print queue, as opposed to resuming a single job on the print queue. The default value depends on the printing type chosen. You should not need to alter this option. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_01.html" TITLE="7.1 Sending Print Jobs to Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.1 Sending Print Jobs to Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_03.html" TITLE="7.3 Name Resolution with Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 7.3 Name Resolution with Samba" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+7.1 Sending Print Jobs to Samba</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+7.3 Name Resolution with Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch07_03.html b/docs/htmldocs/using_samba/ch07_03.html
new file mode 100755
index 00000000000..56a531681ca
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch07_03.html
@@ -0,0 +1,404 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 7] 7.3 Name Resolution with Samba</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:08Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_02.html" TITLE="7.2 Printing to Windows Client Printers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.2 Printing to Windows Client Printers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch07_01.html" TITLE="7. Printing and Name Resolution">
+Chapter 7<br>
+Printing and Name Resolution</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8. Additional Samba Information " BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch07-12219">
+7.3 Name Resolution with Samba</a></h2><P CLASS="para">Before NetBIOS Name Servers (NBNS) came about, name resolution worked entirely by broadcast. If you needed a machine's address, you simply broadcast its name across the network and, in theory, the machine itself would reply. This approach is still possible: anyone looking for a machine named <CODE CLASS="literal">
+fred</code> can still broadcast a query and find out if it exists and what its IP address is. (We use this capability to troubleshoot Samba name services with the <CODE CLASS="literal">
+nmblookup</code> command in <a href="ch09_01.html"><b>Chapter 9, <CITE CLASS="chapter">Troubleshooting Samba</cite></b></a>.)</p><P CLASS="para">
+As you saw in the first chapter, however, broadcasting&nbsp;- whether it be browsing or name registration and resolution&nbsp;- does not pass easily across multiple subnets. In addition, many broadcasts tend to bog down networks. To solve this problem, Microsoft now provides the Windows Internet Naming Service (WINS), a cross-subnet NBNS, which Samba supports. With it, an administrator can designate a single machine to act as a WINS server, and can then provide each client that requires name resolution the address of the WINS server. Consequently, name registration and resolution requests can be directed to a single machine from any point on the network, instead of broadcast.</p><P CLASS="para">
+WINS and broadcasting are not the only means of name resolution, however. There are actually four mechanisms that can be used with Samba:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-950848">
+</a>WINS</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-950856">
+</a>Broadcasting</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-950851">
+</a>Unix <I CLASS="filename">
+/etc/hosts</i> or NIS/NIS+ matches</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch07-pgfId-951953">
+</a><EM CLASS="emphasis">
+LMHOSTS</em> file</p></li></ul><P CLASS="para">
+Samba can use any or all of these name resolution methods in the order that you specify in the Samba configuration file using the <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+resolve</code> <CODE CLASS="literal">
+order</code> parameter. However, before delving into configuration options, let's discuss the one that you've probably not encountered before: the <I CLASS="filename">
+LMHOSTS</i> file.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-949950">
+7.3.1 The LMHOSTS File</a></h3><P CLASS="para">
+<I CLASS="filename">
+LMHOSTS</i> is the standard LAN Manager <EM CLASS="emphasis">
+hosts</em> file used to resolve names into IP addresses on the system. It is the NBT equivalent of the <I CLASS="filename">
+/etc/hosts</i> file that is standard on all Unix systems. By default, the file is usually stored as <I CLASS="filename">
+/usr/local/samba/lib/LMHOSTS</i> and shares a format similar to <I CLASS="filename">
+/etc/hosts</i>. For example:</p><PRE CLASS="programlisting">
+192.168.220.100 hydra
+192.168.220.101 phoenix</pre><P CLASS="para">
+The only difference is that the names on the right side of the entries are NetBIOS names instead of DNS names. Because they are NetBIOS names, you can assign resource types to them as well:</p><PRE CLASS="programlisting">
+192.168.220.100 hydra#20
+192.168.220.100 simple#1b
+192.168.220.101 phoenix#20</pre><P CLASS="para">
+Here, we've assigned the <CODE CLASS="literal">
+hydra</code> machine to be the primary domain controller of the <CODE CLASS="literal">
+SIMPLE</code> domain, as indicated by the resource type &lt;1B&gt; assigned to the name after <CODE CLASS="literal">
+hydra</code>'s IP address in the second line. The other two are standard workstations.</p><P CLASS="para">
+If you wish to place an <EM CLASS="emphasis">
+LMHOSTS</em> file somewhere other than the default location, you will need to notify the <EM CLASS="emphasis">
+nmbd</em> process upon start up, as follows:</p><PRE CLASS="programlisting">
+nmbd -H /etc/samba/lmhosts -D</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-951120">
+7.3.2 Setting Up Samba to Use Another WINS Server</a></h3><P CLASS="para">You can set up Samba to use a WINS server somewhere else on the network by simply pointing it to the IP address of the WINS server. This is done with the global <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+server</code> configuration option, as shown here:</p><PRE CLASS="programlisting">
+[global]
+ wins server = 192.168.200.122</pre><P CLASS="para">
+With this option enabled, Samba will direct all WINS requests to the server at 192.168.200.122. Note that because the request is directed at a single machine, we don't have to worry about any of the problems inherent to broadcasting. However, though you have specified an IP address for a WINS server in the configuration file, Samba will not necessarily use the WINS server before other forms of name resolution. The order in which Samba attempts various name-resolution techniques is given with the <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+resolve</code> <CODE CLASS="literal">
+order</code> configuration option, which we will discuss shortly.</p><P CLASS="para">
+If you have a Samba server on a subnet that still uses broadcasting and the Samba server knows the correct location of a WINS server on another subnet, you can configure the Samba server to forward any name resolution requests with the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+proxy</code> option:</p><PRE CLASS="programlisting">
+[global]
+ wins server = 192.168.200.12
+ wins proxy = yes</pre><P CLASS="para">
+Use this only in situations where the WINS server resides on another subnet. Otherwise, the broadcast will reach the WINS server regardless of any proxying.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-83429">
+7.3.3 Setting Up Samba as a WINS Server</a></h3><P CLASS="para">You can set up Samba as a WINS server by setting two global options in the configuration file, as shown below:</p><PRE CLASS="programlisting">
+[global]
+ wins support = yes
+ name resolve order = wins lmhosts hosts bcast</pre><P CLASS="para">
+The <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+support</code> option turns Samba into a WINS server. Believe it or not, that's all you need to do! Samba handles the rest of the details behind the scenes, leaving you a relaxed administrator. The <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+support=yes</code> and the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+server</code> option are mutually exclusive; you cannot simultaneously offer Samba as the WINS server and point to another system as the server.</p><P CLASS="para">
+If Samba is acting as a WINS server, you should probably get familiar with the <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+resolve</code> <CODE CLASS="literal">
+order</code> option mentioned earlier. This option tells Samba the order of methods in which it tries to resolve a NetBIOS name. It can take up to four values:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+lmhosts</dt><DD CLASS="listitem">
+<P CLASS="para">
+Uses a LAN Manager <EM CLASS="emphasis">
+LMHOSTS</em> file</p></dd><DT CLASS="term">
+hosts</dt><DD CLASS="listitem">
+<P CLASS="para">
+Uses the standard name resolution methods of the Unix system, <EM CLASS="emphasis">
+/etc/hosts</em>, DNS, NIS, or a combination (as configured for the system)</p></dd><DT CLASS="term">
+wins</dt><DD CLASS="listitem">
+<P CLASS="para">
+Uses the WINS server</p></dd><DT CLASS="term">
+bcast</dt><DD CLASS="listitem">
+<P CLASS="para">
+Uses a broadcast method</p></dd></dl><P CLASS="para">
+The order in which you specify them in the value is the order in which Samba will attempt name resolution when acting as a WINS server. For example, let's look at the value specified previously:</p><PRE CLASS="programlisting">
+name resolve order = wins lmhosts hosts bcast</pre><P CLASS="para">
+This means that Samba will attempt to use its WINS entries first for name resolution, followed by the LAN Manager <EM CLASS="emphasis">
+LMHOSTS</em> file on its system. Next, the hosts value causes it to use Unix name resolution methods. The word <CODE CLASS="literal">
+hosts</code> may be misleading; it covers not only the <I CLASS="filename">
+/etc/hosts</i> file, but also the use of DNS or NIS (as configured on the Unix host). Finally, if those three do not work, it will use a broadcast to try to locate the correct machine.</p><P CLASS="para">
+Finally, you can instruct a Samba server that is acting as a WINS server to check with the system's DNS server if a requested host cannot be found in its WINS database. With a typical Linux system, for example, you can find the IP address of the DNS server by searching the <I CLASS="filename">
+/etc/resolv.conf</i> file. In it, you might see an entry such as the following:</p><PRE CLASS="programlisting">
+nameserver 127.0.0.1
+nameserver 192.168.200.192</pre><P CLASS="para">
+This tells us that a DNS server is located at 192.168.220.192. (The 127.0.0.1 is the localhost address and is never a valid DNS server address.) </p><P CLASS="para">
+Use the global <CODE CLASS="literal">
+dns</code> <CODE CLASS="literal">
+proxy</code> option to alert Samba to use the configured DNS server:</p><PRE CLASS="programlisting">
+[global]
+ wins support = yes
+ name resolve order = wins lmhosts hosts bcast
+ dns proxy = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch07-pgfId-949952">
+7.3.4 Name Resolution Configuration Options</a></h3><P CLASS="para">Samba's WINS options are shown in <A CLASS="xref" HREF="ch07_03.html#ch07-82331">
+Table 7.5</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch07-82331">
+Table 7.5: WINS Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+wins support</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, Samba will act as a WINS server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+wins server</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (IP address or DNS name)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Identifies a WINS server for Samba to use for name registration and resolution.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+wins proxy</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows Samba to act as a proxy to a WINS server on another subnet.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+dns proxy</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If set to <CODE CLASS="literal">
+yes</code>, a Samba WINS server will search DNS if it cannot find a name in WINS.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+name resolve order</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lmhosts</code>, <CODE CLASS="literal">
+hosts</code>, <CODE CLASS="literal">
+wins</code>, or <CODE CLASS="literal">
+bcast</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies an order of the methods used to resolve NetBIOS names.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+lmhosts hosts wins bcast</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max ttl</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the maximum time-to-live in seconds for a requested NetBIOS names.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+259200</code> (3 days)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max wins ttl</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the maximum time-to-live in seconds for NetBIOS names given out by Samba as a WINS server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+518400</code> (6 days)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+min wins ttl</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the minimum time-to-live in seconds for NetBIOS names given out by Samba as a WINS server.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+21600</code> (6 hours)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-946762">
+7.3.4.1 wins support</a></h4><P CLASS="para">
+Samba will provide WINS name service to all machines in the network if you set the following in the <CODE CLASS="literal">
+[global]</code> section of the <I CLASS="filename">
+smb.conf</i> file:</p><PRE CLASS="programlisting">
+[global]
+ wins support = yes</pre><P CLASS="para">
+The default value is <CODE CLASS="literal">
+no</code>, which is typically used to allow another Windows NT server to become a WINS server. If you do enable this option, remember that a Samba WINS server currently cannot exchange data with any backup WINS servers. If activated, this option is mutually exclusive with the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+server</code> parameter; you cannot set both to <CODE CLASS="literal">
+yes</code> at the same time or Samba will flag an error.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-946766">
+7.3.4.2 wins server</a></h4><P CLASS="para">
+Samba will use an existing WINS server on the network if you specify the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+server</code> global option in your configuration file. The value of this option is either the IP address or DNS name (not NetBIOS name) of the WINS server. For example:</p><PRE CLASS="programlisting">
+[global]
+ wins server = 192.168.220.110</pre><P CLASS="para">
+or:</p><PRE CLASS="programlisting">
+[global]
+ wins server = wins.example.com</pre><P CLASS="para">
+In order for this option to work, the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+support</code> option must be set to <CODE CLASS="literal">
+no</code> (the default). Otherwise, Samba will report an error. You can specify only one WINS server using this option.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-947973">
+7.3.4.3 wins proxy</a></h4><P CLASS="para">
+This option allows Samba to act as a proxy to another WINS server, and thus relay name registration and resolution requests from itself to the real WINS server, often outside the current subnet. The WINS server can be indicated through the <CODE CLASS="literal">
+wins</code> <CODE CLASS="literal">
+server</code> option. The proxy will then return the WINS response back to the client. You can enable this option by specifying the following in the <CODE CLASS="literal">
+[global]</code> section:</p><PRE CLASS="programlisting">
+[global]
+ wins proxy = yes</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-946778">
+7.3.4.4 dns proxy</a></h4><P CLASS="para">
+If you want the domain name service (DNS) to be used if a name isn't found in WINS, you can set the following option:</p><PRE CLASS="programlisting">
+[global]
+ dns proxy = yes</pre><P CLASS="para">
+This will cause <I CLASS="filename">
+nmbd</i> to query for machine names using the server's standard domain name service. You may wish to deactivate this option if you do not have a permanent connection to your DNS server. Despite this option, we recommend using a WINS server. If you don't already have any WINS servers on your network, make one Samba machine a WINS server. Do not, however, make two Samba machines WINS servers (one primary and one backup) as they currently cannot exchange WINS databases.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949945">
+7.3.4.5 name resolve order</a></h4><P CLASS="para">
+The global <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+resolve</code> <CODE CLASS="literal">
+order</code> option specifies the order of services that Samba will use in attempting name resolution. The default order is to use the <EM CLASS="emphasis">
+LMHOSTS</em> file, followed by standard Unix name resolution methods (some combination of <I CLASS="filename">
+/etc/hosts</i>, DNS, and NIS), then query a WINS server, and finally use broadcasting to determine the address of a NetBIOS name. You can override this option by specifying something like the following:</p><PRE CLASS="programlisting">
+[global]
+ name resolve order = lmhosts wins hosts bcast</pre><P CLASS="para">
+This causes resolution to use the <EM CLASS="emphasis">
+LMHOSTS</em> file first, followed by a query to a WINS server, the system password file, and finally broadcasting. You need not use all four options if you don't want to. This option is covered in more detail in the section <A CLASS="xref" HREF="ch07_03.html#ch07-83429">
+Section 7.3.3, Setting Up Samba as a WINS Server</a>, earlier in this chapter.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949986">
+7.3.4.6 max ttl</a></h4><P CLASS="para">
+This option gives the maximum time to live (TTL) during which a NetBIOS name registered with the Samba server will remain active. You should never need to alter this value.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949988">
+7.3.4.7 max wins ttl</a></h4><P CLASS="para">
+This option give the maximum time to live (TTL) during which a NetBIOS name resolved from a WINS server will remain active. You should never need to change this value from its default.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch07-pgfId-949990">
+7.3.4.8 min wins ttl</a></h4><P CLASS="para">
+This option give the minimum time to live (TTL) during which a NetBIOS name resolved from a WINS server will remain active. You should never need to alter this value from its default. </p></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_02.html" TITLE="7.2 Printing to Windows Client Printers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.2 Printing to Windows Client Printers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8. Additional Samba Information " BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+7.2 Printing to Windows Client Printers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8. Additional Samba Information </td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_01.html b/docs/htmldocs/using_samba/ch08_01.html
new file mode 100755
index 00000000000..a6767271b62
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_01.html
@@ -0,0 +1,267 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] Additional Samba Information </title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:49Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_03.html" TITLE="7.3 Name Resolution with Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.3 Name Resolution with Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 8</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_02.html" TITLE="8.2 Magic Scripts">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.2 Magic Scripts" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch08-74589">
+8. Additional Samba Information </a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch08-56646" TITLE="8.1 Supporting Programmers">
+Supporting Programmers</a><br>
+<A CLASS="sect1" HREF="ch08_02.html" TITLE="8.2 Magic Scripts">
+Magic Scripts</a><br>
+<A CLASS="sect1" HREF="ch08_03.html" TITLE="8.3 Internationalization">
+Internationalization</a><br>
+<A CLASS="sect1" HREF="ch08_04.html" TITLE="8.4 WinPopup Messages">
+WinPopup Messages</a><br>
+<A CLASS="sect1" HREF="ch08_05.html" TITLE="8.5 Recently Added Options">
+Recently Added Options</a><br>
+<A CLASS="sect1" HREF="ch08_06.html" TITLE="8.6 Miscellaneous Options">
+Miscellaneous Options</a><br>
+<A CLASS="sect1" HREF="ch08_07.html" TITLE="8.7 Backups with smbtar">
+Backups with smbtar</a></p><P>
+</p></div><P CLASS="para">
+This chapter wraps up our coverage of the <I CLASS="filename">
+smb.conf</i> configuration file with some miscellaneous options that can perform a variety of tasks. We will talk briefly about options for supporting programmers, internationalization, messages, and common Windows bugs. For the most part, you will use these options only in isolated circumstances. We also cover performing automated backups with the <I CLASS="filename">
+smbtar</i> command at the end of this chapter. So without further ado, let's jump into our first subject: options to help programmers.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch08-56646">
+8.1 Supporting Programmers</a></h2><P CLASS="para">If you have programmers accessing your Samba server, you'll want to be aware of the special options listed in <A CLASS="xref" HREF="ch08_01.html#ch08-73167">
+Table 8.1</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-73167">
+Table 8.1: Programming Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+time server</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, <EM CLASS="emphasis">
+nmbd</em> announces itself as a SMB time service to Windows clients.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+time offset</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (number of minutes)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Adds a specified number of minutes to the reported time.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+dos filetimes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Allows non-owners of a file to change its time if they can write to it.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+dos filetime</code></p><P CLASS="para">
+<CODE CLASS="literal">
+resolution</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Causes file times to be rounded to the next even second.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+fake directory create times</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets directory times to avoid a MS <EM CLASS="emphasis">
+nmake</em> bug.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958487">
+8.1.1 Time Synchronization</a></h3><P CLASS="para">Time synchronization can be very important to programmers. Consider the following options:</p><PRE CLASS="programlisting">
+time service = yes
+dos filetimes = yes
+fake directory create times = yes
+dos filetime resolution = yes
+delete readonly = yes</pre><P CLASS="para">
+If you set these options, Samba shares will provide the kind of compatible file times that Visual C++, <EM CLASS="emphasis">
+nmake</em>, and other Microsoft programming tools require. Otherwise, PC <EM CLASS="emphasis">
+make</em> programs will tend to think that all the files in a directory need to be recompiled every time. Obviously, this is not the behavior you want.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch08-pgfId-958495">
+8.1.1.1 time server</a></h4><P CLASS="para">
+If your Samba server has an accurate clock, or if it's a client of one of the Unix network time servers, you can instruct it to advertise itself as an SMB time server by setting the <CODE CLASS="literal">
+time</code> <CODE CLASS="literal">
+server</code> option as follows:</p><PRE CLASS="programlisting">
+[global]
+ time service = yes</pre><P CLASS="para">
+The client will still have to request the correct time with the following DOS command, substituting the Samba server name in at the appropriate point:</p><PRE CLASS="programlisting">
+C:\NET TIME \\<CODE CLASS="replaceable"><I>server</i></code> /YES /SET</pre><P CLASS="para">
+This command can be placed in a Windows logon script (see <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains </cite></b></a>).</p><P CLASS="para">
+By default, the <CODE CLASS="literal">
+time</code> <CODE CLASS="literal">
+server</code> option is normally set to <CODE CLASS="literal">
+no</code>. If you turn this service on, you can use the command above to keep the client clocks from drifting. Time synchronization is important to clients using programs such as <EM CLASS="emphasis">
+make</em>, which compile based on the last time the file was changed. Incorrectly synchronized times can cause such programs to either remake all files in a directory, which wastes time, or not recompile a source file that was just modified because of a slight clock drift.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch08-pgfId-958501">
+8.1.1.2 time offset</a></h4><P CLASS="para">
+To deal with clients that don't process daylight savings time properly, Samba provides the <CODE CLASS="literal">
+time</code> <CODE CLASS="literal">
+offset</code> option. If set, it adds the specified number of minutes to the current time. This is handy if you're in Newfoundland and Windows doesn't know about the 30-minute time difference there:</p><PRE CLASS="programlisting">
+[global]
+ time offset = 30</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch08-pgfId-958505">
+8.1.1.3 dos filetimes</a></h4><P CLASS="para">
+Traditionally, only the root user and the owner of a file can change its last-modified date on a Unix system. The share-level <CODE CLASS="literal">
+dos</code> <CODE CLASS="literal">
+filetimes</code> option allows the Samba server to mimic the characteristics of a DOS/Windows machine: any user can change the last modified date on a file in that share if he or she has write permission to it. In order to do this, Samba uses its root privileges to modify the timestamp on the file. </p><P CLASS="para">
+By default, this option is disabled. Setting this option to <CODE CLASS="literal">
+yes</code> is often necessary to allow PC <EM CLASS="emphasis">
+make</em> programs to work properly. Without it, they cannot change the last-modified date themselves. This often results in the program thinking <EM CLASS="emphasis">
+all</em> files need recompiling when they really don't. </p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch08-pgfId-958509">
+8.1.1.4 dos filetime resolution</a></h4><P CLASS="para">
+<CODE CLASS="literal">
+dos</code> <CODE CLASS="literal">
+filetime</code> <CODE CLASS="literal">
+resolution</code> is share-level option. If set to <CODE CLASS="literal">
+yes</code>, Samba will arrange to have the file times rounded to the closest two-second boundary. This option exists primarily to satisfy a quirk in Windows that prevents Visual C++ from correctly recognizing that a file has not changed. You can enable it as follows:</p><PRE CLASS="programlisting">
+[data]
+ dos filetime resolution = yes</pre><P CLASS="para">
+We recommend using this option only if you are using Microsoft Visual C++ on a Samba share that supports opportunistic locking.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch08-pgfId-958515">
+8.1.1.5 fake directory create times</a></h4><P CLASS="para">
+The <CODE CLASS="literal">
+fake</code> <CODE CLASS="literal">
+directory</code> <CODE CLASS="literal">
+create</code> <CODE CLASS="literal">
+times</code> option exists to keep PC <EM CLASS="emphasis">
+make</em> programs sane. VFAT and NTFS filesystems record the creation date of a specific directory while Unix does not. Without this option, Samba takes the earliest recorded date it has for the directory (often the last-modified date of a file) and returns it to the client. If this is not sufficient, set the following option under a share definition:</p><PRE CLASS="programlisting">
+[data]
+ fake directory create times = yes</pre><P CLASS="para">
+If set, Samba will adjust the directory create time it reports to the hardcoded value January 1st, 1980. This is primarily used to convince the Visual C++ <EM CLASS="emphasis">
+nmake</em> program that any object files in its build directories are indeed younger than the creation date of the directory itself and need to be recompiled.</p></div></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch07_03.html" TITLE="7.3 Name Resolution with Samba">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 7.3 Name Resolution with Samba" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_02.html" TITLE="8.2 Magic Scripts">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.2 Magic Scripts" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">7.3 Name Resolution with Samba</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.2 Magic Scripts</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_02.html b/docs/htmldocs/using_samba/ch08_02.html
new file mode 100755
index 00000000000..54b24800711
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_02.html
@@ -0,0 +1,156 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.2 Magic Scripts</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:51Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_01.html" TITLE="8.1 Supporting Programmers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.1 Supporting Programmers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_03.html" TITLE="8.3 Internationalization">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.3 Internationalization" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-79987">
+8.2 Magic Scripts</a></h2><P CLASS="para">The following options deal with <I CLASS="firstterm">
+magic scripts</i> on the Samba server. Magic scripts are a method of running programs on Unix and redirecting the output back to the SMB client. These are essentially an experimental hack. However, some users and their programs still rely on these two options for their programs to function correctly. Magic scripts are not widely trusted and their use is highly discouraged by the Samba team. See <A CLASS="xref" HREF="ch08_02.html#ch08-33693">
+Table 8.2</a> for more information. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-33693">
+Table 8.2: Networking Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+magic script</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">string (fully-qualified filename)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the name of a file to be executed by Samba, as the logged-on user, when closed.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+magic output</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified filename)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a file to log output from the magic file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<EM CLASS="emphasis">
+scriptname.out</em></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958578">
+8.2.1 magic script</a></h3><P CLASS="para">
+If the <CODE CLASS="literal">
+magic</code> <CODE CLASS="literal">
+script</code> option is set to a filename and the client creates a file by that name in that share, Samba will run the file as soon as the user has opened and closed it. For example, let's assume that the following option was created in the share <CODE CLASS="literal">
+[accounting]</code>:</p><PRE CLASS="programlisting">
+[accounting]
+ magic script = tally.sh</pre><P CLASS="para">
+Samba continually monitors the files in that share. If one by the name of <EM CLASS="emphasis">
+tally.sh</em> is closed (after being opened) by a user, Samba will execute the contents of that file locally. The file will be passed to the shell to execute; it must therefore be a legal Unix shell script. This means that it must have newline characters as line endings instead of Windows CR/LFs. In addition, it helps if you use the <CODE CLASS="literal">
+#!</code> directive at the beginning of the file to indicate under which shell the script should run.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958584">
+8.2.2 magic output</a></h3><P CLASS="para">
+This option specifies an output file that the script specified by the <CODE CLASS="literal">
+magic</code> <CODE CLASS="literal">
+script</code> option will send output to. You must specify a filename in a writable directory:</p><PRE CLASS="programlisting">
+[accounting]
+ magic script = tally.sh
+ magic output = /var/log/magicoutput</pre><P CLASS="para">
+If this option is omitted, the default output file is the name of the script (as stated in the <CODE CLASS="literal">
+magic</code> <CODE CLASS="literal">
+script</code> option) with the extension <EM CLASS="emphasis">
+.out</em> appended onto it. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_01.html" TITLE="8.1 Supporting Programmers">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.1 Supporting Programmers" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_03.html" TITLE="8.3 Internationalization">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.3 Internationalization" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+8.1 Supporting Programmers</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.3 Internationalization</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_03.html b/docs/htmldocs/using_samba/ch08_03.html
new file mode 100755
index 00000000000..9e2f60c4328
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_03.html
@@ -0,0 +1,472 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.3 Internationalization</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:51Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_02.html" TITLE="8.2 Magic Scripts">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.2 Magic Scripts" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_04.html" TITLE="8.4 WinPopup Messages">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.4 WinPopup Messages" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-91233">
+8.3 Internationalization</a></h2><P CLASS="para">Samba has a limited ability to speak foreign tongues: if you need to deal with characters that aren't in standard ASCII, some options that can help you are shown in <A CLASS="xref" HREF="ch08_03.html#ch08-40870">
+Table 8.3</a>. Otherwise, you can skip over this section. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-40870">
+Table 8.3: Networking Configuration Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+client code page</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Described in this section</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a code page to expect from clients</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+850</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+character set</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Described in this section</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Translates code pages into alternate UNIX character sets</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+coding system</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Described in this section</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Translates code page 932 into an Asian character set</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+valid chars</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (set of characters)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Obsolete: formerly added individual characters to a code page, and had to be used after setting client code page</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-17721">
+8.3.1 client code page</a></h3><P CLASS="para">
+The character sets on Windows platforms hark back to the original concept of a <EM CLASS="emphasis">
+code page</em>. These code pages are used by DOS and Windows clients to determine rules for mapping lowercase letters to uppercase letters. Samba can be instructed to use a variety of code pages through the use of the global <CODE CLASS="literal">
+client</code> <CODE CLASS="literal">
+code</code> <CODE CLASS="literal">
+page</code> option in order to match the corresponding code page in use on the client. This option loads a code-page definition file, and can take the values specified in <A CLASS="xref" HREF="ch08_03.html#ch08-20815">
+Table 8.4</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-20815">
+Table 8.4: Valid Code Pages with Samba 2.0 </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Code Page</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+437</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">MS-DOS Latin (United States)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+737</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Windows 95 Greek</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+850</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Latin 1 (Western European)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+852</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Latin 2 (Eastern European)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+861</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Icelandic</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+866</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Cyrillic (Russian)</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+932</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Japanese Shift-JIS</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+936</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Simplified Chinese</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+949</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Korean Hangul</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+950</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+MS-DOS Traditional Chinese</p></td></tr></tbody></table><P CLASS="para">
+You can set the client code page as follows:</p><PRE CLASS="programlisting">
+[global]
+ client code page = 852</pre><P CLASS="para">
+The default value of this option is 850. You can use the <EM CLASS="emphasis">
+make_smbcodepage</em> tool that comes with Samba (by default in <I CLASS="filename">
+/usr/local/samba/bin</i>) to create your own SMB code pages, in the event that those listed earlier are not sufficient.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-965812">
+8.3.2 character set</a></h3><P CLASS="para">
+The global <CODE CLASS="literal">
+character</code> <CODE CLASS="literal">
+set</code> option can be used to convert filenames offered through a DOS code page (see the previous section, <A CLASS="xref" HREF="ch08_03.html#ch08-17721">
+Section 8.3.1, client code page</a>) to equivalents that can be represented by Unix character sets other than those in the United States. For example, if you want to convert the Western European MS-DOS character set on the client to a Western European Unix character set on the server, you can use the following in your configuration file:</p><PRE CLASS="programlisting">
+[global]
+ client code page = 850
+ character set = ISO8859-1</pre><P CLASS="para">
+Note that you must include a <CODE CLASS="literal">
+client</code> <CODE CLASS="literal">
+code</code> <CODE CLASS="literal">
+page</code> option to specify the character set from which you are converting. The valid character sets (and their matching code pages) that Samba 2.0 accepts are listed in <A CLASS="xref" HREF="ch08_03.html#ch08-14126">
+Table 8.5</a>: </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-14126">
+Table 8.5: Valid Character Sets with Samba 2.0 </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Character Set</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Matching Code Page</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ISO8859-1</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+850</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Western European Unix</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ISO8859-2</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+852</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eastern European Unix</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ISO8859-5</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+866</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Russian Cyrillic Unix</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+KOI8-R</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+866</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Alternate Russian Cyrillic Unix</p></td></tr></tbody></table><P CLASS="para">
+Normally, the <CODE CLASS="literal">
+character</code> <CODE CLASS="literal">
+set</code> option is disabled completely.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958761">
+8.3.3 coding system</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+coding</code> <CODE CLASS="literal">
+system</code> option is similar to the <CODE CLASS="literal">
+character</code> <CODE CLASS="literal">
+set</code> option. However, its purpose is to determine how to convert a Japanese Shift JIS code page into an appropriate Unix character set. In order to use this option, the <CODE CLASS="literal">
+client</code> <CODE CLASS="literal">
+code</code> <CODE CLASS="literal">
+page</code> option described previously must be set to page 932. The valid coding systems that Samba 2.0 accepts are listed in <A CLASS="xref" HREF="ch08_03.html#ch08-57476">
+Table 8.6</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-57476">
+Table 8.6: Valid Coding System Parameters with Samba 2.0 </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Character Set</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+SJIS</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Standard Shift JIS</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JIS8</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J8BB</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J8BH</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J8@B</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J8@J</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J8@H</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Eight-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JIS7</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J7BB</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J7BH</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J7@B</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J7@J</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+J7@H</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Seven-bit JIS codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JUNET</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JUBB</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JUBH</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JU@B</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JU@J</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+JU@H</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+JUNET codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+EUC</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+EUC codes</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+HEX</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Three-byte hexidecimal code</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+CAP</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Three-byte hexidecimal code (Columbia Appletalk Program)</p></td></tr></tbody></table></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958865">
+8.3.4 valid chars</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+chars</code> option is an older Samba feature that will add individual characters to a code page. However, this option is being phased out in favor of more modern coding systems. You can use this option as follows:</p><PRE CLASS="programlisting">
+valid chars = Î
+valid chars = 0450:0420 0x0A20:0x0A00
+valid chars = A:a</pre><P CLASS="para">
+Each of the characters in the list specified should be separated by spaces. If there is a colon between two characters or their numerical equivalents, the data to the left of the colon is considered an uppercase character, while the data to the right is considered the lowercase character. You can represent characters both by literals (if you can type them) and by octal, hexidecimal, or decimal Unicode equivalents.</p><P CLASS="para">
+We recommend against using this option. Instead, go with one of the standard code pages listed earlier in this section. If you do use this option, however, it must be listed after the <CODE CLASS="literal">
+client</code> <CODE CLASS="literal">
+code</code> <CODE CLASS="literal">
+page</code> to which you wish to add the character. Otherwise, the characters will not be added.</p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_02.html" TITLE="8.2 Magic Scripts">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.2 Magic Scripts" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_04.html" TITLE="8.4 WinPopup Messages">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.4 WinPopup Messages" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">8.2 Magic Scripts</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.4 WinPopup Messages</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_04.html b/docs/htmldocs/using_samba/ch08_04.html
new file mode 100755
index 00000000000..d45ce31474a
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_04.html
@@ -0,0 +1,168 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.4 WinPopup Messages</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:55Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_03.html" TITLE="8.3 Internationalization">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.3 Internationalization" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_05.html" TITLE="8.5 Recently Added Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.5 Recently Added Options" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-82569">
+8.4 WinPopup Messages</a></h2><P CLASS="para">You can use the WinPopup tool (<I CLASS="filename">WINPOPUP.EXE</i>) in Windows to send messages to users, machines, or entire workgroups on the network. This tool is provided with Windows 95 OSR2 and comes standard with Windows 98. With either Windows 95 or 98, however, you need to be running WinPopup to receive and send WinPopup messages. With Windows NT, you can still receive messages without starting such a tool; they will automatically appear in a small dialog box on the screen when received. The WinPopup application is shown in <A CLASS="xref" HREF="ch08_04.html#ch08-66444">
+Figure 8.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch08-66444">
+Figure 8.1: The WinPopup application</a></h4><IMG CLASS="graphic" SRC="figs/sam.0801.gif" ALT="Figure 8.1"><P CLASS="para">
+Samba has a single WinPopup messaging option, <CODE CLASS="literal">
+message</code> <CODE CLASS="literal">
+command</code>, as shown in <A CLASS="xref" HREF="ch08_04.html#ch08-18671">
+Table 8.7</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-18671">
+Table 8.7: WinPopup Configuration Option </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameter</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+message command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">string (fully-qualified pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a command to run on Unix when a WinPopup message is received.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-958949">
+8.4.1 message command</a></h3><P CLASS="para">
+Samba's <CODE CLASS="literal">
+message</code> <CODE CLASS="literal">
+command</code> option sets the path to a program that will run on the server when a Windows popup message arrives at the server. The command will be executed using the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+account</code> user. What to do with one of these is questionable since it's probably for the Samba administrator, and Samba doesn't know his or her name. If you know there's a human using the console, the Samba team once suggested the following:</p><PRE CLASS="programlisting">
+[global]
+ message command = /bin/csh -c 'xedit %s; rm %s' &amp;</pre><P CLASS="para">
+Note the use of variables here. The <CODE CLASS="literal">
+%s</code> variable will become the file that the message is in. This file should be deleted when the command is finished with it; otherwise, there will be a buildup of pop-up files collecting on the Samba server. In addition, the command must fork its own process (note the &amp; after the command); otherwise the client may suspend and wait for notification that the command was sent successfully before continuing.</p><P CLASS="para">
+In addition to the standard variables, <A CLASS="xref" HREF="ch08_04.html#ch08-29758">
+Table 8.8</a> shows the three unique variables that you can use in a <CODE CLASS="literal">
+message</code> <CODE CLASS="literal">
+command</code>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-29758">
+Table 8.8: Message Command Variables </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%s</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The name of the file in which the message resides</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%</code>f</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The name of the client that sent the message</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+%t</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+The name of the machine that is the destination of the message </p></td></tr></tbody></table></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_03.html" TITLE="8.3 Internationalization">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.3 Internationalization" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_05.html" TITLE="8.5 Recently Added Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.5 Recently Added Options" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+8.3 Internationalization</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.5 Recently Added Options</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_05.html b/docs/htmldocs/using_samba/ch08_05.html
new file mode 100755
index 00000000000..90fa20a8cda
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_05.html
@@ -0,0 +1,396 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.5 Recently Added Options</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:55Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_04.html" TITLE="8.4 WinPopup Messages">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.4 WinPopup Messages" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_06.html" TITLE="8.6 Miscellaneous Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.6 Miscellaneous Options" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-pgfId-958954">
+
+<!-- 2.0.7 amendments begin, davecb --> 8.5 Recently Added
+Options</a></h2><P CLASS="para">Samba has several options that appeared
+around the time of Samba 2.0, but either were not entirely supported or were
+in the process of being developed. With Samba 2.0.7, several more were
+introduced. We will give you a brief overview of their workings in this
+section. These options are shown in <A CLASS="xref"
+HREF="ch08_05.html#ch08-72538">
+<!-- end of first addition -->
+
+Table 8.9</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-72538">
+Table 8.9: Recently Added Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+change notify timeout</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (number of seconds)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the interval between checks when a client asks to wait for a change in a specified directory.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+60</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+machine password timeout</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (number of seconds)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the renewal interval for NT domain machine passwords.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+604,800</code> (1 week)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+stat cache</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, Samba will cache recent name mappings.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+stat cache size</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the size of the stat cache.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+50</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr>
+
+<!-- 2.0.7 table insertions begin -->
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+utmp</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Turns on logging of Samba users in the utmp file. Requires --with-utmp. </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+utmp dir</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the directory where Samba expects to find the utmp/utmpx file.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+None</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+inherit permissions</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the permissions of newly created directories to the same as their parent.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+write cache size</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (bytes)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the size of a write cache (buffer) used for oplocked files.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Share</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+source environment</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (pathname)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets a file to read environment variable from.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+None</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr>
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+min password length</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (number of characters)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the minimum length of a new password which Samba will try to update the password file with .</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+5</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr>
+
+
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+netbios scope</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the NetBIOS scope.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+None</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr>
+<!-- end of 2.0.7 insertions-->
+</tbody></table>
+
+<DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-959050">
+8.5.1 change notify timeout</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+change</code> <CODE CLASS="literal">
+notify</code> <CODE CLASS="literal">
+timeout</code> global option emulates a Windows NT SMB feature called <I CLASS="firstterm">
+change notification</i>. This allows a client to request that a Windows NT server periodically monitor a specific directory on a share for any changes. If any changes occur, the server will notify the client.</p><P CLASS="para">
+As of version 2.0, Samba will perform this function for its clients. However, performing these checks too often can slow the server down considerably. This option sets the time period that Samba should wait between such checks. The default is one minute (60 seconds); however, you can use this option to specify an alternate time that Samba should wait between performing checks:</p><PRE CLASS="programlisting">
+[global]
+ change notify timeout = 30</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-959054">
+8.5.2 machine password timeout</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+machine</code> <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+timeout</code> global option sets a retention period for NT domain machine passwords. The default is currently set to the same time period that Windows NT 4.0 uses: 604,800 seconds (one week). Samba will periodically attempt to change the <I CLASS="firstterm">
+machine account password</i>, which is a password used specifically by another server to report changes to it. This option specifies the number of seconds that Samba should wait before attempting to change that password. The following example changes it to a single day, by specifying the following:</p><PRE CLASS="programlisting">
+[global]
+ machine password timeout = 86400</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-959058">
+8.5.3 stat cache</a></h3><P CLASS="para">
+The <CODE CLASS="literal">
+stat</code> <CODE CLASS="literal">
+cache</code> global option turns on caching of recent case-insensitive name mappings. The default is <CODE CLASS="literal">
+yes</code>. The Samba team recommends that you never change this parameter.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-959060">
+8.5.4 stat cache size</a></h3><P CLASS="para">The <CODE CLASS="literal">
+stat</code> <CODE CLASS="literal">
+cache</code> <CODE CLASS="literal">
+size</code> global option sets the size of the cache entries to be used for the <CODE CLASS="literal">
+stat</code> <CODE CLASS="literal">
+cache</code> option. The default here is 50. Again, the Samba team recommends that you never change this parameter.</p>
+
+===
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add1">
+8.5.5 utmp</a></h3>
+<P CLASS="para">If you specified <CODE CLASS="literal">
+--with-utmp </CODE> when configuring, this option will turn on utmp logging
+of users: they will appear in the utmp file and you will be able to see if
+they are on with <I>last(1)</I>. It defaults to <CODE
+CLASS="literal">no</code>.</p>
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add2">
+8.5.6 utmp dir</a></h3>
+<P CLASS="para">
+If <CODE CLASS="literal">utmp</CODE> is set, the utmp dir option will change the directory Samba
+looks in for the utmp files. If it is not set, the default system
+location will be used.</p>
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add3">
+8.5.7 inherit permissions</a></h3>
+<P CLASS="para">
+This option causes new files and directories to be created with
+the same permissions as the directory they're in. For example,
+subdirectories will inherit setgid bits from their parents.
+This option will override the <CODE CLASS="literal">create
+mask, directory mask, force create mode</CODE> and <CODE CLASS="literal">
+force directory mode</CODE> options, but not the <CODE CLASS="literal">
+map archive, map hidden</CODE> and <CODE CLASS="literal">map system</CODE>
+options. It will never set the <CODE CLASS="literal">setuid</CODE> bit.
+This option defaults to off.</p>
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add4">
+8.5.8 write cache size</a></h3>
+<P CLASS="para">The <CODE CLASS="literal">write cache size</code>
+share option sets the size of a cache used by Samba while
+writing oplocked files. The files will be written in <I>cachesize</I>
+blocks, so you can tune Samba's write size to the optimum size for
+your filesystem or RAID disk array.</p>
+
+<p>The caching applies to the first 10 files opened with oplocks if set,
+and defaults to zero (off) initially.</p>
+
+<p>As with all caching schemes, data that hasn't been written
+will be lost if the system crashes.</p>
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add5">
+8.5.9 source environment</a></h3>
+<P CLASS="para">
+This options specifies a file of environment variables that Samba
+will read on startup. <!-- and when else? When an smb.conf is read?
+when a child server process is started? --> The variables set in this
+files can then be used in smb.conf files as $%<I>name</I>. For example,
+HOME=/home/sofia in the environment file could be used in a smb.conf
+file as "path = "$HOME"</p>
+
+<p>If the pathname begins with a "|" (pipe) symbol, Samba will attempt
+to run it and read its standard output.</p>
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add6">
+8.5.10 min password length</a></h3>
+<P CLASS="para">This option sets the minimum length, in characters,
+of a plain text password that Samba will accept when performing UNIX
+password changing. This is used to tell Samba about system-defined
+minimums, so it can return an appropriate error to the client.</p>
+
+
+<H3 CLASS="sect2"> <A CLASS="title" NAME="ch08-pgfId-959060-add1">
+8.5.11 netbios scope</a></h3>
+<P CLASS="para">
+This sets the NetBIOS scope that Samba will operate under: Samba
+will not communicate with any machine with a different scope.
+This should not be set unless every machine on your LAN also sets
+this value. It was a predecessor to workgroups, and the Samba
+team recommends against using it.</p>
+
+<!-- end of 2.0.7 additions. -->
+
+<div></div></div></blockquote>
+
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_04.html" TITLE="8.4 WinPopup Messages">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.4 WinPopup Messages" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_06.html" TITLE="8.6 Miscellaneous Options">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.6 Miscellaneous Options" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+8.4 WinPopup Messages</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.6 Miscellaneous Options</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_06.html b/docs/htmldocs/using_samba/ch08_06.html
new file mode 100755
index 00000000000..97e4e3c9767
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_06.html
@@ -0,0 +1,509 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.6 Miscellaneous Options</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:35:56Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_05.html" TITLE="8.5 Recently Added Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.5 Recently Added Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_07.html" TITLE="8.7 Backups with smbtar">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.7 Backups with smbtar" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-70923">
+8.6 Miscellaneous Options</a></h2><P CLASS="para">Many Samba options are present to deal with operating system issues on either Unix or Windows. The options shown in <A CLASS="xref" HREF="ch08_06.html#ch08-83566">
+Table 8.10</a> deal specifically with some of these known problems. We usually don't change these and we recommend the same to you. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-83566">
+Table 8.10: Miscellaneous Options </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Option</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Parameters</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Function</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Default</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Scope</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+deadtime</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">numerical (number of minutes)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the number of minutes of inactivity before a connection should be terminated.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+0</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+dfree command</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Used to provide a command that returns disk free space in a format recognized by Samba.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+fstype</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+NTFS</code>, <CODE CLASS="literal">
+FAT</code>, or <CODE CLASS="literal">
+Samba</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the filesystem type reported by the server to the client.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+NTFS</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+keep alive</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+seconds</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the number of seconds between checks for an inoperative client.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+0 (none)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max disk size</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical (size in MB)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the largest disk size to return to a client, some of which have limits. Does not affect actual operations on the disk.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+0 (infinity)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max mux</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the maximum number of simultaneous SMB operations that clients may make.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+50</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max open files</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Limits number of open files to be below Unix limits.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+10,000</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+max xmit</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+numerical</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Specifies the maximum packet size that Samba will send.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+65,535</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+nt pipe support</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Turns off an experimental NT feature, for benchmarking or in case of an error.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+nt smb support</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Turns off an experimental NT feature, for benchmarking or in case of an error.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+ole locking compatib-ility</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Remaps out-of-range lock requests used on Windows to fit in allowable range on Unix. Turning it off causes Unix lock errors.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+panic action</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+command</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Program to run if Samba server fails; for debugging.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+set directory</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, allows VMS clients to issue <CODE CLASS="literal">
+set</code> <CODE CLASS="literal">
+dir</code> commands.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+smbrun</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+string (fully-qualified command)</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Sets the command Samba uses as a wrapper for shell commands.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+None</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+status</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, allows Samba to monitor status for <CODE CLASS="literal">
+smbstatus</code> command.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+yes</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+strict sync</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+no</code>, ignores Windows applications requests to perform a sync-to-disk.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+sync always</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, forces all client writes to be committed to disk before returning from the call.</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+strip dot</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+boolean</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+If <CODE CLASS="literal">
+yes</code>, strips trailing dots from Unix filenames. </p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<CODE CLASS="literal">
+no</code></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Global</p></td></tr></tbody></table><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960795">
+8.6.1 deadtime</a></h3><P CLASS="para">
+This global option sets the number of minutes that Samba will wait for an inactive client before closing its session with the Samba server. A client is considered inactive when it has no open files and there is no data being sent from it. The default value for this option is 0, which means that Samba never closes any connections no matter how long they have been inactive. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ deadtime = 10</pre><P CLASS="para">
+This tells Samba to terminate any inactive client sessions after 10 minutes. For most networks, setting this option as such will work because reconnections from the client are generally performed transparently to the user.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960118">
+8.6.2 dfree command</a></h3><P CLASS="para">This global option is used on systems that incorrectly determine the free space left on the disk. So far, the only confirmed system that needs this option set is Ultrix. There is no default value for this option, which means that Samba already knows how to compute the free disk space on its own and the results are considered reliable. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ dfree command = /usr/local/bin/dfree</pre><P CLASS="para">
+This option should point to a script that should return the total disk space in a block, and the number of available blocks. The Samba documentation recommends the following as a usable script:</p><PRE CLASS="programlisting">
+#!/bin/sh
+df $1 | tail -1 | awk '{print $2&quot; &quot;$4}'</pre><P CLASS="para">
+On System V machines, the following will work:</p><PRE CLASS="programlisting">
+#!/bin/sh
+/usr/bin/df $1 | tail -1 | awk '{print $3&quot; &quot;$5}'</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960122">
+8.6.3 fstype</a></h3><P CLASS="para">
+This share-level option sets the type of filesystem that Samba reports when queried by the client. There are three strings that can be used as a value to this configuration option, as listed in <A CLASS="xref" HREF="ch08_06.html#ch08-80519">
+Table 8.11</a>. </p><br>
+<TABLE CLASS="table" BORDER="1" CELLPADDING="3">
+<CAPTION CLASS="table">
+<A CLASS="title" NAME="ch08-80519">
+Table 8.11: Filesystem Types </a></caption><THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Variable</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Definition</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+NTFS</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">Microsoft Windows NT filesystem</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+FAT</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+DOS FAT filesystem</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Samba filesystem</p></td></tr></tbody></table><P CLASS="para">
+The default value for this option is <CODE CLASS="literal">
+NTFS</code>, which represents a Windows NT filesystem. There probably isn't a need to specify any other type of filesystem. However, if you need to, you can override it per share as follows:</p><PRE CLASS="programlisting">
+[data]
+ fstype = FAT</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960124">
+8.6.4 keep alive</a></h3><P CLASS="para">This global option specifies the number of seconds that Samba waits between sending NetBIOS <EM CLASS="emphasis">
+keep-alive packets</em>. These packets are used to ping a client to detect whether it is still alive and on the network. The default value for this option is <CODE CLASS="literal">
+0</code>, which means that Samba will not send any such packets at all. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ keep alive = 10</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960128">
+8.6.5 max disk size</a></h3><P CLASS="para">This global option specifies an illusory limit, in megabytes, for each of the shares that Samba is using. You would typically set this option to prevent clients with older operating systems from incorrectly processing large disk spaces, such as those over one gigabyte.</p><P CLASS="para">
+The default value for this option is <CODE CLASS="literal">
+0</code>, which means there is no upper limit at all. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ max disk size = 1000</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960130">
+8.6.6 max mux</a></h3><P CLASS="para">This global option specifies the maximum number of concurrent SMB operations that Samba allows. The default value for this option is <CODE CLASS="literal">
+50</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ max mux = 100</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960132">
+8.6.7 max open files</a></h3><P CLASS="para">This global option specifies the maximum number of open files that Samba should allow at any given time for all processes. This value must be equal to or less than the amount allowed by the operating system, which varies from system to system. The default value for this option is <CODE CLASS="literal">
+10,000</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ max open files = 8000</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960136">
+8.6.8 max xmit</a></h3><P CLASS="para">This global option sets the maximum size of packets that Samba exchanges with a client. In some cases, setting a smaller maximum packet size can increase performance, especially with Windows for Workgroups. The default value for this option is <CODE CLASS="literal">
+65535</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ max xmit = 4096</pre><P CLASS="para">
+
+The section <a href="appb_02.html#b226"><b>Section B.2.2.6, The TCP receive window</b></a> in <a href="appb_01.html"><b>Appendix B,<CITE CLASS="appendix">
+Samba Performance Tuning</cite></b></a>,
+
+shows some uses for this option.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960138">
+8.6.9 nt pipe support</a></h3><P CLASS="para">This global option is used by developers to allow or disallow Windows NT clients the ability to make connections to the NT SMB-specific IPC$ pipes. As a user, you should never need to override the default:</p><PRE CLASS="programlisting">
+[global]
+ nt pipe support = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960140">
+8.6.10 nt smb support</a></h3><P CLASS="para">This global option is used by developers to negotiate NT-specific SMB options with Windows NT clients. The Samba team has discovered that slightly better performance comes from setting this value to <CODE CLASS="literal">
+no</code>. However, as a user, you should probably not override the default:</p><PRE CLASS="programlisting">
+[global]
+ nt smb support = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960178">
+8.6.11 ole locking compatibility</a></h3><P CLASS="para">
+This global option turns off Samba's internal byte-range locking manipulation in files, which gives compatibility with Object Linking and Embedding (OLE) applications that use high byte-range locks as a method of interprocess communication. The default value for this option is <CODE CLASS="literal">
+yes</code>. If you trust your Unix locking mechanisms, you can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ ole locking compatibility = no</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960182">
+8.6.12 panic action</a></h3><P CLASS="para">This global option specifies a command to execute in the event that Samba itself encounters a fatal error when loading or running. There is no default value for this option. You can specify an action as follows:</p><PRE CLASS="programlisting">
+[global]
+ panic action = /bin/csh -c
+ 'xedit &lt; &quot;Samba has shutdown unexpectedly!'</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960190">
+8.6.13 set directory</a></h3><P CLASS="para">
+This boolean share-level option allows Digital Pathworks clients to use the <CODE CLASS="literal">
+setdir</code> command to change directories on the server. If you are not using the Digital Pathworks client, you should not need to alter this option. The default value for this option is <CODE CLASS="literal">
+no</code>. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[data]
+ set directory = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960192">
+8.6.14 smbrun</a></h3><P CLASS="para">
+This option sets the location of the <EM CLASS="emphasis">
+smbrun</em> executable, which Samba uses as a wrapper to run shell commands. The default value for this option is automatically configured by Samba when it is compiled. If you did not install Samba to the standard directory, you can specify where the binary is as follows:</p><PRE CLASS="programlisting">
+[global]
+ smbrun = /usr/local/bin/smbrun</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960194">
+8.6.15 status</a></h3><P CLASS="para">
+This global option indicates whether Samba should log all active connections to a status file. This file is used only by the <EM CLASS="emphasis">
+smbstatus</em> command. If you have no intentions of using this command, you can set this option to <CODE CLASS="literal">
+no</code>, which can result in a small increase of speed on the server. The default value for this option is <CODE CLASS="literal">
+yes</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+[global]
+ status = no</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960196">
+8.6.16 strict sync</a></h3><P CLASS="para">
+This share-level option determines whether Samba honors all requests to perform a disk sync when requested to do so by a client. Many clients request a disk sync when they are really just trying to flush data to their own open files. As a result, this can substantially slow a Samba server down. The default value for this option is <CODE CLASS="literal">
+no</code>. You can override it as follows:</p><PRE CLASS="programlisting">
+[data]
+ strict sync = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960202">
+8.6.17 sync always</a></h3><P CLASS="para">
+This share-level option decides whether every write to disk should be followed by a disk synchronization before the write call returns control to the client. Even if the value of this option is <CODE CLASS="literal">
+no</code>, clients can request a disk synchronization; see the <CODE CLASS="literal">
+strict</code> <CODE CLASS="literal">
+sync</code> option above. The default value for this option is <CODE CLASS="literal">
+no</code>. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[data]
+ sync always = yes</pre></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch08-pgfId-960204">
+8.6.18 strip dot</a></h3><P CLASS="para">
+This global option determines whether to remove the trailing dot from Unix filenames that are formatted with a dot at the end. The default value for this option is <CODE CLASS="literal">
+no</code>. You can override it per share as follows:</p><PRE CLASS="programlisting">
+[global]
+ strip dot = yes</pre><P CLASS="para">
+This option is now considered obsolete; the user should use the <CODE CLASS="literal">
+mangled</code> <CODE CLASS="literal">
+map</code> option insead. </p></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_05.html" TITLE="8.5 Recently Added Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.5 Recently Added Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_07.html" TITLE="8.7 Backups with smbtar">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 8.7 Backups with smbtar" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+8.5 Recently Added Options</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+8.7 Backups with smbtar</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch08_07.html b/docs/htmldocs/using_samba/ch08_07.html
new file mode 100755
index 00000000000..c0aa0837020
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch08_07.html
@@ -0,0 +1,143 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 8] 8.7 Backups with smbtar</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:36:02Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_06.html" TITLE="8.6 Miscellaneous Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.6 Miscellaneous Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch08_01.html" TITLE="8. Additional Samba Information ">
+Chapter 8<br>
+Additional Samba Information </a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch09_01.html" TITLE="9. Troubleshooting Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9. Troubleshooting Samba" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch08-74829">
+8.7 Backups with smbtar</a></h2><P CLASS="para">Our final topic in this chapter is the <I CLASS="filename">
+smbtar</i> tool. One common problem with modem PCs is that floppies and even CD-ROMs are often too small to use for backups. However, buying one tape drive per machine would also be silly. Consequently, many sites don't back up their PCs at all. Instead, they reinstall them using floppy disks and CD-ROMs when they fail.</p><P CLASS="para">
+Thankfully, Samba provides us with another option: you can back up PCs' data using the <I CLASS="filename">
+smbtar</i> tool. This can be done on a regular basis if you keep user data on your Samba system, or only occasionally, to save the local applications and configuration files and thus make repairs and reinstallations quicker.</p><P CLASS="para">
+To back up PCs from a Unix server, you need to do three things:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961555">
+</a>Ensure that File and Printer Sharing is installed on the PC and is bound to the TCP/IP protocol.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961564">
+</a>Explicitly share a disk on the PC so it can be read from the server.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961567">
+</a>Set up the backup scripts on the server.</p></li></ol><P CLASS="para">
+We'll use Windows 95/98 to illustrate the first two steps. Go to the Networking icon in the Control Panel window, and check that File and Printer Sharing for Microsoft Networks is currently listed in the top window, as shown in <A CLASS="xref" HREF="ch08_07.html#ch08-18303">
+Figure 8.2</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch08-18303">
+Figure 8.2: The Networking window</a></h4><IMG CLASS="graphic" SRC="figs/sam.0802.gif" ALT="Figure 8.2"><P CLASS="para">
+If "File and printer sharing for Microsoft Networks" isn't installed, you can install it by clicking on the Add button on the Network panel. After pressing it, you will be asked what service to add. Select Service and move forward, and you will be asked for a vendor and a service to install. Finally, select "File and printer sharing for Microsoft Networks," and click on Done to install the service.</p><P CLASS="para">
+Once you've installed "File and printer sharing for Microsoft Networks," return to the Network panel and select the TCP/IP protocol that is tied to your Samba network adapter. Then, click on the Properties button and choose the Bindings tab at the top. You should see a dialog box similar to <A CLASS="xref" HREF="ch08_07.html#ch08-41042">
+Figure 8.3</a>. Here, you'll need to verify that the "File and Printer Sharing" checkbox is checked, giving it access to TCP/IP. At this point you can share disks with other machines on the net. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch08-41042">
+Figure 8.3: TCP/IP Bindings</a></h4><IMG CLASS="graphic" SRC="figs/sam.0803.gif" ALT="Figure 8.3"><P CLASS="para">
+The next step is to share the disk you want to back up with the tape server. Go to My Computer and select, for example, the My Documents directory. Then right-click on the icon and select its Properties. This should yield the dialog box in <A CLASS="xref" HREF="ch08_07.html#ch08-64918">
+Figure 8.4</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch08-64918">
+Figure 8.4: My Documents Properties</a></h4><IMG CLASS="graphic" SRC="figs/sam.0804.gif" ALT="Figure 8.4"><P CLASS="para">
+Select the Sharing tab and turn file sharing on. You now have the choice to share the disk as read-only, read-write (Full), or either, each with separate password. This is the Windows 95/98 version, so it provides only share-level security. In this example, we made it read/write and set a password, as shown in <A CLASS="xref" HREF="ch08_07.html#ch08-29192">
+Figure 8.5</a>. When you enter the password and click on OK, you'll be prompted to re-enter it. After that, you have finished the second step. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch08-29192">
+Figure 8.5: MyFiles Properties as shared</a></h4><IMG CLASS="graphic" SRC="figs/sam.0805.gif" ALT="Figure 8.5"><P CLASS="para">
+Finally, the last step is to set up a backup script on the tape server, using the <I CLASS="filename">
+smbtar</i> program. The simplest script might contain only a single line and would be something like the following:</p><PRE CLASS="programlisting">
+smbtar -s client -t /dev/rst0 -x &quot;My Documents&quot; -p <CODE CLASS="replaceable"><I>password</i></code></pre><P CLASS="para">
+This unconditionally backs up the <EM CLASS="emphasis">
+//client/My Documents</em> share to the device <I CLASS="filename">
+/dev/rst0</i>. Of course, this is excessively simple and quite insecure. What you will want to do will depend on your existing backup scheme. </p><P CLASS="para">
+However, to whet your appetite, here are some possibilities of what <I CLASS="filename">
+smbtar</i> can do:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961280">
+</a>Back up files incrementally using the DOS archive bit (the <CODE CLASS="literal">
+-i</code> option). This requires the client share to be accessed read-write so the bit can be cleared by <I CLASS="filename">
+smbtar</i></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961281">
+</a>Back up only files that have changed since a specified date (using the <CODE CLASS="literal">
+-N</code> <CODE CLASS="replaceable">
+<I>
+filename </i></code>option)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch08-pgfId-961282">
+</a>Back up entire PC drives, by sharing all of C: or D:, for example, and backing that up</p></li></ul><P CLASS="para">
+Except for the first example, each of these can be done with the PC sharing set to read-only, reducing the security risk of having passwords in scripts and passing them on the command line. </p></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_06.html" TITLE="8.6 Miscellaneous Options">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.6 Miscellaneous Options" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="chapter" HREF="ch09_01.html" TITLE="9. Troubleshooting Samba">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9. Troubleshooting Samba" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+8.6 Miscellaneous Options</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+9. Troubleshooting Samba</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch09_01.html b/docs/htmldocs/using_samba/ch09_01.html
new file mode 100755
index 00000000000..8dc0e80bc56
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch09_01.html
@@ -0,0 +1,397 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 9] Troubleshooting Samba</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:36:14Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_07.html" TITLE="8.7 Backups with smbtar">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.7 Backups with smbtar" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+Chapter 9</font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_02.html" TITLE="9.2 The Fault Tree">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9.2 The Fault Tree" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div class="samplechapter">
+<H1 CLASS="chapter">
+<A CLASS="title" NAME="ch09-80975">
+9. Troubleshooting Samba</a></h1><DIV CLASS="htmltoc">
+<P>
+<B>
+Contents:</b><br>
+<A CLASS="sect1" HREF="#ch09-36385" TITLE="9.1 The Tool Bag">
+The Tool Bag</a><br>
+<A CLASS="sect1" HREF="ch09_02.html" TITLE="9.2 The Fault Tree">
+The Fault Tree</a><br>
+<A CLASS="sect1" HREF="ch09_03.html" TITLE="9.3 Extra Resources">
+Extra Resources</a></p><P>
+</p></div><P CLASS="para">Samba is extremely robust. Once you've got everything set up the way you want, you'll probably forget that it is running. When trouble occurs, it's typically during installation or when you're trying to add something new to the server. Fortunately, there are a wide variety of resources that you can use to diagnose these troubles. While we can't describe in detail the solution to every problem that you might encounter, you should be able to get a good start at a resolution by following the advice given in this chapter.</p><P CLASS="para">
+The first section of the chapter lists the tool bag, a collection of tools available for troubleshooting Samba; the second section is a detailed how-to, and the last section lists extra resources you may need to track down particularly stubborn problems.</p><DIV CLASS="sect1">
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="s1"></a>
+<A CLASS="title" NAME="ch09-36385">
+9.1 The Tool Bag</a></h2><P CLASS="para">Sometimes Unix seems to be made up of a handful of applications and tools. There are tools to troubleshoot tools. And of course, there are several ways to accomplish the same task. When you are trying to solve a problem related to Samba, a good plan of attack is to check the following:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944982">
+</a>Samba logs </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944983">
+</a>Fault tree </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944984">
+</a>Unix utilities </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944985">
+</a>Samba test utilities </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944986">
+</a>Documentation and FAQs </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944987">
+</a>Searchable archives </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-944988">
+</a>Samba newsgroups</p></li></ol><P CLASS="para">
+Let's go over each of these one by one in the following sections.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-950956">
+9.1.1 Samba Logs</a></h3><P CLASS="para">Your first line of attack should always be to check the log files. The Samba log files can help diagnose the vast majority of the problems that beginning to intermediate Samba administrators are likely to face. Samba is quite flexible when it comes to logging. You can set up the server to log as little or as much as you want. Substitution variables that allow you to isolate individual logs for each machine, share, or combination thereof.</p><P CLASS="para">
+By default, logs are placed in <CODE CLASS="replaceable">
+<I>
+samba_directory</i></code><EM CLASS="emphasis">
+/var/smbd.log</em> and <CODE CLASS="replaceable">
+<I>
+samba_directory</i></code><EM CLASS="emphasis">
+/var/nmbd.log</em>, where <CODE CLASS="literal">
+samba_directory</code> is the location where Samba was installed (typically, <I CLASS="filename">
+/usr/local/samba</i>). As we mentioned in <a href=ch04_01.html><b>Chapter 4, <CITE CLASS="chapter">Disk Shares</cite></b></a>, you can override the location and name using the <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+file</code> configuration option in <I CLASS="filename">
+smb.conf</i>. This option accepts all of the substitution variables mentioned in <a href="ch02_01.html"><b>Chapter 2, <CITE CLASS="chapter">Installing Samba on a Unix System</cite></b></a>, so you could easily have the server keep a separate log for each connecting client by specifying the following in the <CODE CLASS="literal">
+[global]</code> section of <I CLASS="filename">
+smb.conf</i>:</p><PRE CLASS="programlisting">
+log file = %m.log</pre><P CLASS="para">
+Alternatively, you can specify a log directory to use with the <CODE CLASS="literal">
+-l</code> flag on the command line. For example:</p><PRE CLASS="programlisting">
+smbd -l /usr/local/var/samba</pre><P CLASS="para">
+Another useful trick is to have the server keep a log for each service (share) that is offered, especially if you suspect a particular share is causing trouble. Use the <CODE CLASS="literal">
+%S</code> variable to set this up in the <CODE CLASS="literal">
+[global]</code> section of the configuration file:</p><PRE CLASS="programlisting">
+log file = %S.log</pre><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-28969">
+9.1.1.1 Log levels</a></h4><P CLASS="para">The level of logging that Samba uses can be set in the <I CLASS="filename">
+smb.conf</i> file using the global <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> or <CODE CLASS="literal">
+debug</code> <CODE CLASS="literal">
+level</code> option; they are equivalent. The logging level is an integer which ranges from 0 (no logging), and increases the logging to voluminous by <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+3</code>. For example, let's assume that we are going to use a Windows client to browse a directory on a Samba server. For a small amount of log information, you can use <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+1</code>, which instructs Samba to show only cursory information, in this case only the connection itself: </p><PRE CLASS="programlisting">
+105/25/98 22:02:11 server (192.168.236.86) connect to service public as user pcguest (uid=503,gid=100) (pid 3377) </pre><P CLASS="para">
+Higher debug levels produce more detailed information. Usually you won't need any more than level 3; this is more than adequate for most Samba administrators. Levels above 3 are for use by the developers and dump enormous amounts of cryptic information.</p><P CLASS="para">
+Here is example output at levels 2 and 3 for the same operation. Don't worry if you don't understand the intricacies of an SMB connection; the point is simply to show you what types of information are shown at the different logging levels: </p><PRE CLASS="programlisting">
+ /* Level 2 */
+Got SIGHUP
+Processing section &quot;[homes]&quot;
+Processing section &quot;[public]&quot;
+Processing section &quot;[temp]&quot;
+Allowed connection from 192.168.236.86 (192.168.236.86) to IPC$
+Allowed connection from 192.168.236.86 (192.168.236.86) to IPC/
+
+
+/* Level 3 */
+05/25/98 22:15:09 Transaction 63 of length 67
+switch message SMBtconX (pid 3377)
+Allowed connection from 192.168.236.86 (192.168.236.86) to IPC$
+ACCEPTED: guest account and guest ok
+found free connection number 105
+Connect path is /tmp
+chdir to /tmp
+chdir to /
+05/25/98 22:15:09 server (192.168.236.86) connect to service IPC$ as user pcguest (uid=503,gid=100) (pid 3377)
+05/25/98 22:15:09 tconX service=ipc$ user=pcguest cnum=105
+05/25/98 22:15:09 Transaction 64 of length 99
+switch message SMBtrans (pid 3377)
+chdir to /tmp
+trans &lt;\PIPE\LANMAN&gt; data=0 params=19 setup=0
+Got API command 0 of form &lt;WrLeh&gt; &lt;B13BWz&gt; (tdscnt=0,tpscnt=19,mdrcnt=4096,mprcnt=8)
+Doing RNetShareEnum
+RNetShareEnum gave 4 entries of 4 (1 4096 126 4096)
+05/25/98 22:15:11 Transaction 65 of length 99
+switch message SMBtrans (pid 3377)
+chdir to /
+chdir to /tmp
+trans &lt;\PIPE\LANMAN&gt; data=0 params=19 setup=0
+Got API command 0 of form &lt;WrLeh&gt; &lt;B13BWz&gt; (tdscnt=0,tpscnt=19,mdrcnt=4096,mprcnt=8)
+Doing RNetShareEnum
+RNetShareEnum gave 4 entries of 4 (1 4096 126 4096)
+05/25/98 22:15:11 Transaction 66 of length 95
+switch message SMBtrans2 (pid 3377)
+chdir to /
+chdir to /pcdisk/public
+call_trans2findfirst: dirtype = 0, maxentries = 6, close_after_first=0, close_if_end = 0 requires_resume_key = 0 level = 260, max_data_bytes = 2432
+unix_clean_name [./DESKTOP.INI]
+unix_clean_name [desktop.ini]
+unix_clean_name [./]
+creating new dirptr 1 for path ./, expect_close = 1
+05/25/98 22:15:11 Transaction 67 of length 53
+switch message SMBgetatr (pid 3377)
+chdir to /
+
+[...]</pre><P CLASS="para">
+We cut off this listing after the first packet because it runs on for many pages. However, you should be aware that log levels above 3 will quickly fill your disk with megabytes of excruciating detail concerning Samba internal operations. Log level 3 is extremely useful for following exactly what the server is doing, and most of the time it will be obvious where an error is occurring by glancing through the log file.</p><P CLASS="para">
+A word of warning: using a high log level (3 or above) will <EM CLASS="emphasis">
+seriously</em> slow down the Samba server. Remember that every log message generated causes a write to disk (an inherently slow operation) and log levels greater than 2 produce massive amounts of data. Essentially, you should turn on logging level 3 only when you're actively tracking a problem in the Samba server.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946537">9.1.1.2 Activating and deactivating logging</a></h4><P CLASS="para">To turn logging on and off, set the appropriate level in the <CODE CLASS="literal">
+[global]</code> section of <I CLASS="filename">
+smb.conf</i>. Then, you can either restart Samba, or force the current daemon to reprocess the configuration file. You also can send the <EM CLASS="emphasis">
+smbd</em> process a SIGUSR1 signal to increase its log level by one while it's running, and a SIGUSR2 signal to decrease it by one:</p><PRE CLASS="programlisting">
+# Increase the logging level by 1
+kill -SIGUSR1 1234
+
+# Decrease the logging level by 1
+kill -SIGUSR2 1234</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-34448">
+9.1.1.3 Logging by individual client machines or users</a></h4><P CLASS="para">An effective way to diagnose problems without hampering other users is to assign different log levels for different machines in <CODE CLASS="literal">
+[global]</code> section of the <I CLASS="filename">
+smb.conf</i> file. We can do this by building on the strategy we presented earlier:</p><PRE CLASS="programlisting">
+[global]
+ log level = 0
+ log file = /usr/local/samba/lib/log.%m
+ include = /usr/local/samba/lib/smb.conf.%m</pre><P CLASS="para">
+These options instruct Samba to use unique configuration and log files for each client that connects. Now all you have to do is create an <I CLASS="filename">
+smb.conf</i> file for a specific client machine with a <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+3</code> entry in it (the others will pick up the default log level of 0) and use that log file to track down the problem.</p><P CLASS="para">
+Similarly, if only particular users are experiencing a problem, and it travels from machine to machine with them, you can isolate logging to a specific user by adding the following to the <I CLASS="filename">
+smb.conf</i> file:</p><PRE CLASS="programlisting">
+[global]
+ log level = 0
+ log file = /usr/local/samba/lib/log.%u
+ include = /usr/local/samba/lib/smb.conf.%u</pre><P CLASS="para">
+Then you can create a unique <I CLASS="filename">
+smb.conf</i> file for each user (e.g., <I CLASS="filename">
+/usr/local/samba/lib/smb.conf.tim</i>) files containing the configuration option <CODE CLASS="literal">
+log</code> <CODE CLASS="literal">
+level</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+3</code> and only those users will get more detailed logging.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-945079">9.1.2 Samba Test Utilities</a></h3><P CLASS="para">A rigorous set of tests that exercise the major parts of Samba are described in various files in the <EM CLASS="emphasis">
+/docs/textdocs</em> directory of the Samba distribution kit, starting with <EM CLASS="emphasis">
+DIAGNOSIS.TXT.</em> The fault tree in this chapter is a more detailed version of the basic tests suggested by the Samba team, but covers only installation and reconfiguration diagnosis, like <EM CLASS="emphasis">
+DIAGNOSIS.TXT.</em> The other files in the <EM CLASS="emphasis">
+/docs</em> subdirectoryies address specific problems (such as Windows NT clients) and instruct you how to troubleshoot items not included in this book. If the fault tree doesn't suffice, be sure to look at <EM CLASS="emphasis">
+DIAGNOSIS.TXT</em> and its friends.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-945083">
+9.1.3 Unix Utilities</a></h3><P CLASS="para">Sometimes it's useful to use a tool outside of the Samba suite to examine what's happening inside the server. Unix has always been a "kitchen-sink" operating system. Two diagnostic tools can be of particular help in debugging Samba troubles: <EM CLASS="emphasis">
+trace</em> and <EM CLASS="emphasis">
+tcpdump</em>.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945085">
+9.1.3.1 Using trace</a></h4><P CLASS="para">
+The <EM CLASS="emphasis">
+trace</em> command masquerades under several different names, depending on the operating system that you are using. On Linux it will be <EM CLASS="emphasis">
+strace</em>, on Solaris you'll use <EM CLASS="emphasis">
+truss</em>, and SGI will have <EM CLASS="emphasis">
+padc</em> and <EM CLASS="emphasis">
+par</em>. All have essentially the same function, which is to display each operating system function call as it is executed. This allows you to follow the execution of a program, such as the Samba server, and will often pinpoint the exact call that is causing the difficulty.</p><P CLASS="para">
+One problem that <EM CLASS="emphasis">
+trace</em> can highlight is the location of an incorrect version of a dynamically linked library. This can happen if you've downloaded prebuilt binaries of Samba. You'll typically see the offending call at the end of the <EM CLASS="emphasis">
+trace</em>, just before the program terminates.</p><P CLASS="para">
+A sample <CODE CLASS="literal">
+strace</code> output for the Linux operating system follows. This is a small section of a larger file created during the opening of a directory on the Samba server. Each line is a system-call name, and includes its parameters and the return value. If there was an error, the error value (e.g., <CODE CLASS="literal">
+ENOENT</code>) and its explanation are also shown. You can look up the parameter types and the errors that can occur in the appropriate <CODE CLASS="literal">
+trace</code> manual page for the operating system that you are using.</p><PRE CLASS="programlisting">
+chdir(&quot;/pcdisk/public&quot;) = 0
+stat(&quot;mini/desktop.ini&quot;, 0xbffff7ec) = -1 ENOENT (No such file or directory)
+stat(&quot;mini&quot;, {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
+stat(&quot;mini/desktop.ini&quot;, 0xbffff7ec) = -1 ENOENT (No such file or directory)
+open(&quot;mini&quot;, O_RDONLY) = 5
+fcntl(5, F_SETFD, FD_CLOEXEC) = 0
+fstat(5, {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
+lseek(5, 0, SEEK_CUR) = 0
+SYS_141(0x5, 0xbfffdbbc, 0xedc, 0xbfffdbbc, 0x80ba708) = 196
+lseek(5, 0, SEEK_CUR) = 1024
+SYS_141(0x5, 0xbfffdbbc, 0xedc, 0xbfffdbbc, 0x80ba708) = 0
+close(5) = 0
+stat(&quot;mini/desktop.ini&quot;, 0xbffff86c) = -1 ENOENT (No such file or directory)
+write(3, &quot;\0\0\0#\377SMB\10\1\0\2\0\200\1\0&quot;..., 39) = 39
+SYS_142(0xff, 0xbffffc3c, 0, 0, 0xbffffc08) = 1
+read(3, &quot;\0\0\0?&quot;, 4) = 4
+read(3, &quot;\377SMBu\0\0\0\0\0\0\0\0\0\0\0\0&quot;..., 63) = 63
+time(NULL) = 896143871</pre><P CLASS="para">
+This example shows several <CODE CLASS="literal">
+stat</code> calls failing to find the files they were expecting. You don't have to be a expert to see that the file <EM CLASS="emphasis">
+desktop.ini</em> is missing from that directory. In fact, many difficult problems can be identified by looking for obvious, repeatable errors with <EM CLASS="emphasis">
+trace</em>. Often, you need not look farther than the last message before a crash.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945114">
+9.1.3.2 Using tcpdump</a></h4><P CLASS="para">
+The <EM CLASS="emphasis">
+tcpdump</em> program, written by Van Jacobson, Craig Leres, and Steven McCanne, and extended by Andrew Tridgell, allows you to monitor network traffic in real time. A variety of output formats are available and you can filter the output to look at only a particular type of traffic. The <EM CLASS="emphasis">
+tcpdump</em> program lets you examine all conversations between client and server, including SMB and NMB broadcast messages. While its troubleshooting capabilities lie mainly at the OSI network layer, you can still use its output to get a general idea of what the server and client are attempting to accomplish.</p><P CLASS="para">
+A sample <EM CLASS="emphasis">
+tcpdump</em> log follows. In this instance, the client has requested a directory listing and the server has responded appropriately, giving the directory names <CODE CLASS="literal">
+homes</code>, <CODE CLASS="literal">
+public</code>, <CODE CLASS="literal">
+IPC$</code>, and <CODE CLASS="literal">
+temp</code> (we've added a few explanations on the right):</p><PRE CLASS="programlisting">$<CODE CLASS="userinput"><B> tcpdump -v -s 255 -i eth0 port not telnet</b></code>
+SMB PACKET: SMBtrans (REQUEST) <CODE CLASS="replaceable">
+<I>
+Request packet</i></code>
+SMB Command = 0x25 <CODE CLASS="replaceable">
+<I>
+Request was ls or dir</i></code>.
+
+[000] 01 00 00 10 ....
+
+
+&gt;&gt;&gt; NBT Packet <CODE CLASS="replaceable">
+<I>
+Outer frame of SMB packe</i></code>t
+NBT Session Packet
+Flags=0x0
+Length=226
+[lines skipped]
+
+SMB PACKET: SMBtrans (REPLY) <CODE CLASS="replaceable">
+<I>
+Beginning of a reply to request </i></code>
+SMB Command = 0x25 <CODE CLASS="replaceable">
+<I>
+Command was an ls or dir</i></code>
+Error class = 0x0
+Error code = 0 <CODE CLASS="replaceable">
+<I>
+No errors</i></code>
+Flags1 = 0x80
+Flags2 = 0x1
+Tree ID = 105
+Proc ID = 6075
+UID = 100
+MID = 30337
+Word Count = 10
+TotParamCnt=8
+TotDataCnt=163
+Res1=0
+ParamCnt=8
+ParamOff=55
+Res2=0
+DataCnt=163
+DataOff=63
+Res3=0
+Lsetup=0
+Param Data: (8 bytes)
+[000] 00 00 00 00 05 00 05 00 ........
+
+Data Data: (135 bytes) <CODE CLASS="replaceable">
+<I>
+ Actual directory contents:</i></code>
+[000] 68 6F 6D 65 73 00 00 00 00 00 00 00 00 00 00 00 homes... ........
+[010] 64 00 00 00 70 75 62 6C 69 63 00 00 00 00 00 00 d...publ ic......
+[020] 00 00 00 00 75 00 00 00 74 65 6D 70 00 00 00 00 ....u... temp....
+[030] 00 00 00 00 00 00 00 00 76 00 00 00 49 50 43 24 ........ v...IPC$
+[040] 00 00 00 00 00 00 00 00 00 00 03 00 77 00 00 00 ........ ....w...
+[050] 64 6F 6E 68 61 6D 00 00 00 00 00 00 00 00 00 00 donham.. ........
+[060] 92 00 00 00 48 6F 6D 65 20 44 69 72 65 63 74 6F ....Home Directo
+[070] 72 69 65 73 00 00 00 49 50 43 20 53 65 72 76 69 ries...I PC Servi
+[080] 63 65 20 28 53 61 6D ce (Sam</pre><P CLASS="para">
+This is more of the same debugging session as with the
+<i>trace</i> command; the listing of a directory. The options we used were <CODE CLASS="literal">
+-v</code> (verbose), <CODE CLASS="literal">
+-i</code> <CODE CLASS="literal">
+eth0</code> to tell <EM CLASS="emphasis">
+tcpdump</em> the interface to listen on (an Ethernet port), and <CODE CLASS="literal">
+-s</code> <CODE CLASS="literal">
+255</code> to tell it to save the first 255 bytes of each packet instead of the default: the first 68. The option <CODE CLASS="literal">
+port</code> <CODE CLASS="literal">
+not</code> <CODE CLASS="literal">
+telnet</code> is used to avoid screens of telnet traffic, since we were logged in to the server remotely. The <EM CLASS="emphasis">
+tcpdump</em> program actually has quite a number of options to filter just the traffic you want to look at. If you've used <EM CLASS="emphasis">
+snoop</em> or <EM CLASS="emphasis">
+etherdump</em>, they'll look vaguely familiar.</p><P CLASS="para">
+You can download the modified <EM CLASS="emphasis">
+tcpdump</em> from the Samba FTP server at <I CLASS="filename">
+<a href="ftp://samba.anu.edu.au/pub/samba/tcpdump-smb">ftp://samba.anu.edu.au/pub/samba/tcpdump-smb</i></a>. Other versions don't include support for the SMB protocol; if you don't see output such as that shown in the example, you'll need to<EM CLASS="emphasis">
+</em> use the SMB-enabled version.</p></div></div></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch08_07.html" TITLE="8.7 Backups with smbtar">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 8.7 Backups with smbtar" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_02.html" TITLE="9.2 The Fault Tree">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9.2 The Fault Tree" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">8.7 Backups with smbtar</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+9.2 The Fault Tree</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch09_02.html b/docs/htmldocs/using_samba/ch09_02.html
new file mode 100755
index 00000000000..e4c740fe278
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch09_02.html
@@ -0,0 +1,1772 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 9] 9.2 The Fault Tree</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:36:27Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_01.html" TITLE="9.1 The Tool Bag">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.1 The Tool Bag" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch09_01.html" TITLE="9. Troubleshooting Samba">
+Chapter 9<br>
+Troubleshooting Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_03.html" TITLE="9.3 Extra Resources">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9.3 Extra Resources" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch09-29538">
+9.2 The Fault Tree</a></h2><P CLASS="para">The fault tree is for diagnosing and fixing problems that occur when you're installing and reconfiguring Samba. It's an expanded form of a trouble and diagnostic document that is part of the Samba distribution.</p><P CLASS="para">Before you set out to troubleshoot any part of the Samba suite, you should know the following information:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945178">
+</a> Your client IP address (we use 192.168.236.10) </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945179">
+</a> Your server IP address (we use 192.168.236.86) </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945180">
+</a> The netmask for your network (typically 255.255.255.0)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945181">
+</a> Whether the machines are all on the same subnet (ours are)</p></li></ul><P CLASS="para">
+For clarity, we've renamed the server in the following examples to <EM CLASS="emphasis">
+server.example.com</em>, and the client machine to <EM CLASS="emphasis">
+client.example.com</em>.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-945183">
+9.2.1 How to use the fault tree</a></h3><P CLASS="para">Start the tests here, without skipping forward; it won't take long (about five minutes) and may actually save you time backtracking. Whenever a test succeeds, you will be given a section name and page number to which you can safely skip.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-953555">
+9.2.2 Troubleshooting Low-level IP </a></h3><P CLASS="para">The first series of tests is that of the low-level services that Samba needs in order to run. The tests in this section will verify that:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945191">
+</a> The IP software works</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945192">
+</a> The Ethernet hardware works</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945193">
+</a> Basic name service is in place</p></li></ul><P CLASS="para">
+Subsequent sections will add TCP software, the Samba daemons <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em>, host-based access control, authentication and per-user access control, file services, and browsing. The tests are described in considerable detail in order to make them understandable by both technically oriented end users and experienced systems and network administrators.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945197">
+9.2.2.1 Testing the networking software with ping </a></h4><P CLASS="para">
+The first command to enter on both the server and the client is <CODE CLASS="literal">
+ping 127.0.0.1</code>. This is the <I CLASS="firstterm">
+loopback</i> <EM CLASS="emphasis">
+address</em> and testing it will indicate whether any networking support is functioning at all. On Unix, you can use <CODE CLASS="literal">
+ping</code> <CODE CLASS="literal">
+127.0.0.1</code> with the statistics option and interrupt it after a few lines. On Sun workstations, the command is typically <CODE CLASS="literal">
+/usr/etc/ping</code> <CODE CLASS="literal">
+-s</code> <CODE CLASS="literal">
+127.0.0.1</code>; on Linux, just <CODE CLASS="literal">
+ping</code> <CODE CLASS="literal">
+127.0.0.1</code>. On Windows clients, run <CODE CLASS="literal">
+ping</code> <CODE CLASS="literal">
+127.0.0.1</code> in an MS-DOS window and it will stop by itself after four lines.</p><P CLASS="para">
+Here is an example on a Linux server:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> ping 127.0.0.1 </b>
+</pre><PRE CLASS="programlisting">
+PING localhost: 56 data bytes 64 bytes from localhost (127.0.0.1):
+icmp-seq=0. time=1. ms 64 bytes from localhost (127.0.0.1):
+icmp-seq=1. time=0. ms 64 bytes from localhost (127.0.0.1):
+icmp-seq=2. time=1. ms ^C
+----127.0.0.1 PING Statistics----
+3 packets transmitted, 3 packets received, 0% packet loss round-trip (ms)
+min/avg/max = 0/0/1 </pre><P CLASS="para">
+If you get "ping: no answer from..." or "100% packet loss," you have no IP networking at all installed on the machine. The address <CODE CLASS="literal">
+127.0.0.1</code> is the internal loopback address and doesn't depend on the computer being physically connected to a network. If this test fails, you have a serious local problem. TCP/IP either isn't installed or is seriously misconfigured. See your operating system documentation if it is a Unix server. If it is a Windows client, follow the instructions in <a href="ch03_01.html"><b>Chapter 3, <CITE CLASS="chapter">Configuring Windows Clients</cite></b></a>, to install networking support.</p><P CLASS="para">
+If <EM CLASS="emphasis">
+you're</em> the network manager, some good references are Craig Hunt's <EM CLASS="emphasis">
+TCP/IP Network Administration</em>, Chapter 11, and Craig Hunt &amp; Robert Bruce Thompson's new book, <EM CLASS="emphasis">
+Windows NT TCP/IP Network Administration, </em>both published by O'Reilly.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-20350">
+9.2.2.2 Testing local name services with ping </a></h4><P CLASS="para">Next, try to ping <CODE CLASS="literal">
+localhost</code> on the Samba server. <CODE CLASS="literal">
+localhost</code> is the conventional hostname for the 127.0.0.1 loopback, and it should resolve to that address. After typing <CODE CLASS="literal">
+ping</code> <CODE CLASS="literal">
+localhost</code>, you should see output similar to the following:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> ping localhost </b>
+</pre><PRE CLASS="programlisting">
+PING localhost: 56 data bytes 64 bytes from localhost (127.0.0.1):
+icmp-seq=0. time=0. ms 64 bytes from localhost (127.0.0.1):
+icmp-seq=1. time=0. ms 64 bytes from localhost (127.0.0.1):
+icmp-seq=2. time=0. ms ^C</pre><P CLASS="para">
+If this succeeds, try the same test on the client. Otherwise:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-951025">
+</a>If you get "unknown host: localhost," there is a problem resolving the host name localhost into a valid IP address. (This may be as simple as a missing entry in a local <EM CLASS="emphasis">
+hosts</em> file.) From here, skip down to the section <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8, Troubleshooting Name Services</a>. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946775">
+</a>If you get "ping: no answer," or "100% packet loss," but pinging 127.0.0.1 worked, then name services is resolving to an address, but it isn't the correct one. Check the file or database (typically <I CLASS="filename">
+/etc/hosts</i> on a Unix system) that the name service is using to resolve addresses to ensure that the entry is corrected.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946776">
+9.2.2.3 Testing the networking hardware with ping </a></h4><P CLASS="para">Next, ping the server's network IP address from itself. This should get you exactly the same results as pinging 127.0.0.1:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> ping 192.168.236.86 </b>
+</pre><PRE CLASS="programlisting">
+PING 192.168.236.86: 56 data bytes 64 bytes from 192.168.236.86 (192.168.236.86):
+icmp-seq=0. time=1. ms 64 bytes from 192.168.236.86 (192.168.236.86):
+icmp-seq=1. time=0. ms 64 bytes from 192.168.236.86 (192.168.236.86):
+icmp-seq=2. time=1. ms ^C
+----192.168.236.86 PING Statistics----
+3 packets transmitted, 3 packets received, 0% packet loss round-trip (ms)
+min/avg/max = 0/0/1</pre><P CLASS="para">
+If this works on the server, repeat it for the client. Otherwise:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945243">
+</a>If <CODE CLASS="literal">
+ping</code> <CODE CLASS="replaceable">
+<I>
+network_ip</i></code> fails on either the server or client, but ping 127.0.0.1 works on that machine, you have a TCP/IP problem that is specific to the Ethernet network interface card on the computer. Check with the documentation for the network card or the host operating system to determine how to correctly configure it. However, be aware that on some operating systems, the <EM CLASS="emphasis">
+ping</em> command appears to work even if the network is disconnected, so this test doesn't always diagnose all hardware problems. </p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-84079">
+9.2.2.4 Testing connections with ping</a></h4><P CLASS="para">Now, ping the server by name (instead of its IP address), once from the server and once from the client. This is the general test for working network hardware:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> ping server </b>
+</pre><PRE CLASS="programlisting">
+PING server.example.com: 56 data bytes 64 bytes from server.example.com (192.168.236.86):
+icmp-seq=0. time=1. ms 64 bytes from server.example.com (192.168.236.86):
+icmp-seq=1. time=0. ms 64 bytes from server.example.com (192.168.236.86):
+icmp-seq=2. time=1. ms ^C
+----server.example.com PING Statistics----
+3 packets transmitted, 3 packets received, 0% packet loss round-trip (ms)
+min/avg/max = 0/0/1</pre><P CLASS="para">
+On Microsoft Windows, a ping of the server would look like <A CLASS="xref" HREF="ch09_02.html#ch09-91668">
+Figure 9.1</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch09-91668">
+Figure 9.1: Pinging the Samba server from a Windows client</a></h4><IMG CLASS="graphic" SRC="figs/sam.0901.gif" ALT="Figure 9.1"><P CLASS="para">
+If successful, this test tells us five things:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946836">
+</a>The hostname (e.g., "server") is being found by your local nameserver.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946837">
+</a>The hostname has been expanded to the full name (e.g., <A CLASS="email" HREF="mailto:server.example.com" TITLE="server.example.com">
+server.example.com</a>).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945264">
+</a>Its address is being returned (192.168.236.86).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945265">
+</a>The client has sent the Samba server four 56-byte UDP/IP packets.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945266">
+</a>The Samba server has replied to all four packets.</p></li></ol><P CLASS="para">
+If this test isn't successful, there can be one of several things wrong with the network:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945267">
+</a>First, if you get "ping: no answer," or "100% packet loss," you're not connecting to the network, the other machine isn't connecting, or one of the addresses is incorrect. Check the addresses that the <CODE CLASS="literal">
+ping</code> command reports on each machine, and ensure that they match the ones you set up initially.</p><P CLASS="para">
+If not, there is at least one mismatched address between the two machines. Try entering the command <CODE CLASS="literal">
+arp</code> <CODE CLASS="literal">
+-a</code>, and see if there is an entry for the other machine. The <CODE CLASS="literal">
+arp</code> command stands for the Address Resolution Protocol. The <CODE CLASS="literal">
+arp</code> <CODE CLASS="literal">
+-a</code> command lists all the addresses known on the local machine. Here are some things to try:</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946854">
+</a>If you receive a message like "192.168.236.86 at (incomplete)," the Ethernet address of 192.168.236.86 is unknown. This indicates a complete lack of connectivity, and you're likely having a problem at the very bottom of the TCP/IP Network Administration protocol stack, at the Ethernet-interface layer. This is discussed in Chapters 5 and 6 of <CITE CLASS="citetitle">
+TCP/IP Network Administration </cite>(O'Reilly).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945274">
+</a>If you receive a response similar to "server (192.168.236.86) at 8:0:20:12:7c:94," then the server has been reached at some time, or another machine is answering on its behalf. However, this means that <EM CLASS="emphasis">
+ping</em> should have worked: you may have an intermittent networking or ARP problem.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945275">
+</a>If the IP address from ARP doesn't match the addresses you expected, investigate and correct the addresses manually.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945284">
+</a>If each machine can ping itself but not another, something is wrong on the network between them.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945287">
+</a>If you get "ping: network unreachable" or "ICMP Host Unreachable," then you're not receiving an answer and there is likely more than one network involved.</p><P CLASS="para">
+In principle, you shouldn't try to troubleshoot SMB clients and servers on different networks. Try to test a server and client on the same network. The three tests that follow assume you might be testing between two networks:</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-951057">
+</a>First, perform the tests for no answer described earlier in this section. If this doesn't identify the problem, the remaining possibilities are the following: an address is wrong, your netmask is wrong, a network is down, or just possibly you've been stopped by a firewall.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-951077">
+</a>Check both the address and the netmasks on source and destination machines to see if something is obviously wrong. Assuming both machines really are on the same network, they both should have the same netmasks and <EM CLASS="emphasis">
+ping</em> should report the correct addresses. If the addresses are wrong, you'll need to correct them. If they're right, the programs may be confused by an incorrect netmask. See <A CLASS="xref" HREF="ch09_02.html#ch09-21203">
+Section 9.2.9.1, Netmasks</a>, later in this chapter.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945300">
+</a>If the commands are still reporting that the network is unreachable and neither of the previous two conditions is in error, one network really may be unreachable from the other. This, too, is a network manager issue.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946936">
+</a>If you get "ICMP Administratively Prohibited," you've struck a firewall of some sort or a misconfigured router. You will need to speak to your network security officer.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946938">
+</a>If you get "ICMP Host redirect," and <EM CLASS="emphasis">
+ping</em> reports packets getting through, this is generally harmless: you're simply being rerouted over the network.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945305">
+</a>If you get a host redirect and no <EM CLASS="emphasis">
+ping</em> responses, you are being redirected, but no one is responding. Treat this just like the "Network unreachable" response and check your addresses and netmasks.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945308">
+</a>If you get "ICMP Host Unreachable from gateway <EM CLASS="emphasis">
+gateway_name</em>," ping packets are being routed to another network, but the other machine isn't responding and the router is reporting the problem on its behalf. Again, treat this like a "Network unreachable" response and start checking addresses and netmasks.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946955">
+</a>If you get "ping: unknown host <EM CLASS="emphasis">
+hostname</em>," your machine's name is not known. This tends to indicate a name-service problem, which didn't affect <CODE CLASS="literal">
+localhost</code>. Have a look at <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8</a>, later in this chapter.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946959">
+</a>If you get a partial success, with some pings failing but others succeeding, you either have an intermittent problem between the machines or an overloaded network. Ping for longer, and see if more than about 3 percent of the packets fail. If so, check it with your network manager: a problem may just be starting. However, if only a few fail, or if you happen to know some massive network program is running, don't worry unduly. Ping's ICMP (and UDP) are designed to drop occasional packets.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945319">
+</a>If you get a response like "smtsvr.antares.net is alive" when you actually pinged <EM CLASS="emphasis">
+client.example.com</em>, you're either using someone else's address or the machine has multiple names and addresses. If the address is wrong, name service is clearly the culprit; you'll need to change the address in the name service database to refer to the right machine. This is discussed in <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8</a>, later in this chapter.</p><P CLASS="para">
+Server machines are often <EM CLASS="emphasis">
+multihomed</em> : connected to more than one network, with different names on each net. If you are getting a response from an unexpected name on a multihomed server, look at the address and see if it's on your network (see the section <A CLASS="xref" HREF="ch09_02.html#ch09-21203">
+Section 9.2.9.1</a>, later in this chapter). If so, you should use that address, rather than one on a different network, for both performance and reliability reasons.</p><P CLASS="para">
+Servers may also have multiple names for a single Ethernet address, especially if they are web servers. This is harmless, if otherwise startling. You probably will want to use the official (and permanent) name, rather than an alias which may change.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945333">
+</a>If everything works, but the IP address reported is 127.0.0.1, you have a name service error. This typically occurs when a operating system installation program generates an <I CLASS="filename">
+/etc/hosts</i> line similar to <CODE CLASS="literal">
+127.0.0.1</code> <CODE CLASS="literal">
+localhost</code> <EM CLASS="emphasis">
+hostnamedomainname</em>. The localhost line should say <CODE CLASS="literal">
+127.0.0.1</code> <CODE CLASS="literal">
+localhost</code> or <CODE CLASS="literal">
+127.0.0.1</code> <CODE CLASS="literal">
+localhost</code> <CODE CLASS="literal">
+loghost</code>. Correct it, lest it cause failures to negotiate who is the master browse list holder and who is the master browser. It can, also cause (ambiguous) errors in later tests.</p></li></ul><P CLASS="para">
+If this worked from the server, repeat it from the client.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-945336">9.2.3 Troubleshooting TCP</a></h3><P CLASS="para">Now that you've tested IP, UDP, and a name service with <EM CLASS="emphasis">
+ping</em>, it's time to test TCP. <EM CLASS="emphasis">
+ping</em> and browsing use ICMP and UDP; file and print services (shares) use TCP. Both depend on IP as a lower layer and all four depend on name services. Testing TCP is most conveniently done using the FTP (file transfer protocol) program.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-78512">
+9.2.3.1 Testing TCP with FTP </a></h4><P CLASS="para">
+Try connecting via FTP, once from the server to itself, and once from the client to the server: </p><PRE CLASS="programlisting">
+server% <CODE CLASS="userinput"><B>ftp server</b></code>
+Connected to server.example.com.
+220 server.example.com FTP server (Version 6.2/OpenBSD/Linux-0.10) ready.
+ Name (server:davecb):
+331 Password required for davecb.
+Password:
+230 User davecb logged in.
+ ftp&gt;<CODE CLASS="userinput"><B> quit </b></code>
+221 Goodbye. </pre><P CLASS="para">
+If this worked, skip to the section <A CLASS="xref" HREF="ch09_02.html#ch09-88968">
+Section 9.2.4, Troubleshooting Server Daemons</a>. Otherwise:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945357">
+</a>If you received the message "server: unknown host," then nameservice has failed. Go back to the corresponding <EM CLASS="emphasis">
+ping</em> step, <A CLASS="xref" HREF="ch09_02.html#ch09-20350">
+Section 9.2.2.2, Testing local name services with ping </a>, and rerun those tests to see why name lookup failed.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945362">
+</a>If you received "ftp: connect: Connection refused," the machine isn't running an FTP daemon. This is mildly unusual on Unix servers. Optionally, you might try this test by connecting to the machine using telnet instead of FTP; the messages are very similar and telnet uses TCP as well.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945364">
+</a>If there was a long pause, then "ftp: connect: Connection timed out," the machine isn't reachable. Return to the section <A CLASS="xref" HREF="ch09_02.html#ch09-84079">
+Section 9.2.2.4, Testing connections with ping</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945369">
+</a>If you received "530 Logon Incorrect," you connected successfully, but you've just found a different problem. You likely provided an incorrect username or password. Try again, making sure you use your username from the Unix server and type your password correctly.</p></li></ul></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-88968">
+9.2.4 Troubleshooting Server Daemons</a></h3><P CLASS="para">Once you've confirmed that TCP networking is working properly, the next step is to make sure the daemons are running on the server. This takes three separate tests because no single one of the following will decisively prove that they're working correctly.</p><P CLASS="para">
+To be sure they're running, you need to find out if:</p><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945374">
+</a>The daemon has started</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945375">
+</a>The daemons are registered or bound to a TCP/IP port by the operating system</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945376">
+</a>They're actually paying attention</p></li></ol><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-947020">
+9.2.4.1 Before you start</a></h4><P CLASS="para">
+First, check the logs. If you've started the daemons, the message "smbd version <EM CLASS="emphasis">
+some_number</em> started" should appear. If it doesn't, you will need to restart the Samba daemons.</p><P CLASS="para">
+If the daemon reports that it has indeed started, look out for "bind failed on port 139 socket_addr=0 (Address already in use)". This means another daemon has been started on port 139 (<EM CLASS="emphasis">smbd</em>). Also, <EM CLASS="emphasis">
+nmbd</em> will report a similar failure if it cannot bind to port 137. Either you've started them twice, or the <EM CLASS="emphasis">
+inetd</em> server has tried to provide a daemon for you. If it's the latter, we'll diagnose that in a moment.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-49239">
+9.2.4.2 Looking for daemon processes with ps</a></h4><P CLASS="para">
+Next, you need to see if the daemons have been started. Use the <CODE CLASS="literal">
+ps</code> command on the server with the <CODE CLASS="literal">
+long</code> option for your machine type (commonly <CODE CLASS="literal">
+ps</code> <CODE CLASS="literal">
+ax</code> or <CODE CLASS="literal">
+ps</code> <CODE CLASS="literal">
+-ef</code>), and see if you have either <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em> already running. This often looks like the following:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> ps ax</b>
+</pre><PRE CLASS="programlisting">
+ PID TTY STAT TIME COMMAND
+ 1 ? S 0:03 init [2]
+ 2 ? SW 0:00 (kflushd)
+<EM CLASS="emphasis">
+(...many lines of processes...)</em>
+ 234 ? S 0:14 nmbd -D3
+ 237 ? S 0:11 smbd -D3
+<EM CLASS="emphasis">
+(...more lines, possibly including more smbd lines...) </em></pre><P CLASS="para">
+This example illustrates that <EM CLASS="emphasis">
+smbd</em> and <EM CLASS="emphasis">
+nmbd</em> have already started as stand-alone daemons (the <CODE CLASS="literal">
+-D</code> option) at log level 3.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945392">
+9.2.4.3 Looking for daemons bound to ports</a></h4><P CLASS="para">
+Next, the daemons have to be registered with the operating system so they can get access to TCP/IP ports. The <CODE CLASS="literal">
+netstat</code> command will tell you if this has been done. Run the command <CODE CLASS="literal">
+netstat</code> <CODE CLASS="literal">
+-a</code> on the server, and look for lines mentioning <CODE CLASS="literal">
+netbios</code>, <CODE CLASS="literal">
+137</code> or <CODE CLASS="literal">
+139</code>:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> netstat -a </b>
+</pre><PRE CLASS="programlisting">
+Active Internet connections (including servers)
+Proto Recv-Q Send-Q Local Address Foreign Address (state)
+udp 0 0 *.netbios- *.*
+tcp 0 0 *.netbios- *.* LISTEN
+tcp 8370 8760 server.netbios- client.1439
+ESTABLISHED </pre><P CLASS="para">
+or:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> netstat -a </b>
+</pre><PRE CLASS="programlisting">
+Active Internet connections (including servers)
+Proto Recv-Q Send-Q Local Address Foreign Address (state)
+udp 0 0 *.137 *.*
+tcp 0 0 *.139 *.* LISTEN
+tcp 8370 8760 server.139 client.1439 ESTABLISHED </pre><P CLASS="para">
+Among many similar lines, there should be at least one UDP line for <CODE CLASS="literal">
+*.netbios-</code> or <CODE CLASS="literal">
+*.137</code>. This indicates that the <EM CLASS="emphasis">
+nmbd</em> server is registered and (we hope) is waiting to answer requests. There should also be at least one TCP line mentioning <CODE CLASS="literal">
+*.netbios-</code> or <CODE CLASS="literal">
+*.139</code>, and it will probably be in the LISTENING state. This means that <EM CLASS="emphasis">
+smbd</em> is up and listening for connections.</p><P CLASS="para">
+There may be other TCP lines indicating connections from <EM CLASS="emphasis">
+smbd</em> to clients, one for each client. These are usually in the ESTABLISHED state. If there are <EM CLASS="emphasis">
+smbd</em> lines in the ESTABLISHED state, <EM CLASS="emphasis">
+smbd</em> is definitely running. If there is only one line in the LISTENING state, we're not sure yet. If both of the lines is missing, a daemon has not succeeded in starting, so it's time to check the logs and then go back to <a href="ch02_01.html"><b>Chapter 2</b></a>.</p><P CLASS="para">
+If there is a line for each client, it may be coming either from a Samba daemon or from the master IP daemon, <EM CLASS="emphasis">
+inetd</em>. It's quite possible that your <EM CLASS="emphasis">
+inetd</em> startup file contains lines that start Samba daemons without your realizing it; for instance, the lines may have been placed there if you installed Samba as part of a Linux distribution. The daemons started by <EM CLASS="emphasis">
+inetd</em> prevent ours from running. This problem typically produces log messages such as "bind failed on port 139 socket_addr=0 (Address already in use)."</p><P CLASS="para">
+Check your <I CLASS="filename">
+/etc/inetd.conf</i> ; unless you're intentionally starting the daemons from there, there <EM CLASS="emphasis">
+must not</em> be any <CODE CLASS="literal">
+netbios-ns</code> (udp port 137) or <CODE CLASS="literal">
+netbios-ssn</code> (tcp port 139) servers mentioned there. <EM CLASS="emphasis">
+inetd</em> is a daemon that provides numerous services, controlled by entries in <EM CLASS="emphasis">
+/etc/inetd.conf</em>. If your system is providing an SMB daemon via <EM CLASS="emphasis">
+inetd</em>, there will be lines like the following in the file:</p><PRE CLASS="programlisting">
+netbios-ssn stream tcp nowait root /usr/local/samba/bin/smbd smbd
+netbios-ns dgram udp wait root /usr/local/samba/bin/nmbd nmbd</pre></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945425">
+9.2.4.4 Checking smbd with telnet</a></h4><P CLASS="para">
+Ironically, the easiest way to test that the <EM CLASS="emphasis">
+smbd</em> server is actually working is to send it a meaningless message and see if it rejects it. Try something like the following:</p><PRE CLASS="programlisting"><CODE CLASS="userinput"><B>echo hello | telnet localhost 139</b></code></pre><P CLASS="para">
+This sends an erroneous but harmless message to <EM CLASS="emphasis">
+smbd</em>. The <CODE CLASS="literal">
+hello</code> message is important. Don't try telneting to the port and typing just anything; you'll probably just hang your process. <CODE CLASS="literal">
+hello</code>, however, is generally a harmless message.</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> echo &quot;hello&quot; | telnet localhost 139 </b>
+</pre><PRE CLASS="programlisting">
+Trying
+Trying 192.168.236.86 ...
+Connected to localhost. Escape character is '^]'.
+Connection closed by foreign host. </pre><P CLASS="para">
+If you get a "Connected" message followed by a "Connection closed" message, the test was a success. You have an <EM CLASS="emphasis">
+smbd</em> daemon listening on the port and rejecting improper connection messages. On the other hand, if you get "telnet: connect: Connection refused," there is probably no daemon present. Check the logs and go back to <a href="ch01_01.html"><b>Chapter 2</b></a>.</p><P CLASS="para">
+Regrettably, there isn't an easy test for <EM CLASS="emphasis">
+nmbd</em>. If the <CODE CLASS="literal">
+telnet</code> test and the <CODE CLASS="literal">
+netstat</code> test both say that there is an <EM CLASS="emphasis">
+smbd</em> running, there is a good chance that <CODE CLASS="literal">
+netstat</code> will also be correct about <EM CLASS="emphasis">
+nmbd</em> running.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-67494">
+9.2.4.5 Testing daemons with testparm</a></h4><P CLASS="para">Once you know there's a daemon, you should always run <CODE CLASS="literal">
+testparm</code>, in hopes of getting:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server%</code> testparm </b>
+</pre><PRE CLASS="programlisting">
+Load smb config files from /opt/samba/lib/smb.conf
+Processing section &quot;[homes]&quot;
+Processing section &quot;[printers]&quot; ...
+Processing section &quot;[tmp]&quot;
+Loaded services file OK. ... </pre><P CLASS="para">
+The <CODE CLASS="literal">
+testparm</code> program normally reports processing a series of sections, and responds with "Loaded services file OK" if it succeeds. If not, it will report one or more of the following messages, which will also appear in the logs as noted:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+<EM CLASS="emphasis">
+"Allow/Deny connection from account (n) to service"</em></dt><DD CLASS="listitem">
+<P CLASS="para">
+A <EM CLASS="emphasis">
+testparm</em>-only message produced if you have valid/invalid user options set in your <EM CLASS="emphasis">
+smb.conf</em>. You will want to make sure that you are on the valid user list, and that root, bin, etc., are on the invalid user list. If you don't, you will not be able to connect, or folks who shouldn't <EM CLASS="emphasis">
+will</em> be able to.</p></dd><DT CLASS="term">
+<EM CLASS="emphasis">
+"Warning: You have some share names that are longer than eight chars"</em></dt><DD CLASS="listitem">
+<P CLASS="para">
+For anyone using Windows for Workgroups and older clients. They will fail to connect to shares with long names, producing an overflow message that sounds confusingly like a memory overflow.</p></dd><DT CLASS="term">
+"Warning: [name] service MUST be printable!"</dt><DD CLASS="listitem">
+<P CLASS="para">
+A printer share lacks a <CODE CLASS="literal">
+printable</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option.</p></dd><DT CLASS="term">
+"No path in service name using [name]"</dt><DD CLASS="listitem">
+<P CLASS="para">
+A file share doesn't know which directory to provide to the user, or a print share doesn't know which directory to use for spooling. If no path is specified, the service will try to run with a path of <EM CLASS="emphasis">
+/tmp</em>, which may not be what you want.</p></dd><DT CLASS="term">
+"Note: Servicename is flagged unavailable"</dt><DD CLASS="listitem">
+<P CLASS="para">
+Just a reminder that you have used the <CODE CLASS="literal">
+available</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+no</code> option in a share.</p></dd><DT CLASS="term">
+"Can't find include file [name]" </dt><DD CLASS="listitem">
+<P CLASS="para">
+A configuration file referred to by an <CODE CLASS="literal">
+include</code> option did not exist. If you were including the file unconditionally, this is an error and probably a serious one: the share will not have the configuration you intended. If you were including it based one of the <CODE CLASS="literal">
+%</code> variables, such as <CODE CLASS="literal">
+%a</code> (architecture), you will need to decide if, for example, a missing Windows for Workgroups configuration file is a problem. It often isn't.</p></dd><DT CLASS="term">
+"Can't copy service name, unable to copy to itself"</dt><DD CLASS="listitem">
+<P CLASS="para">
+You tried to copy a <I CLASS="filename">
+smb.conf</i> section into itself.</p></dd><DT CLASS="term">
+"Unable to copy service&nbsp;- source not found: [name]"</dt><DD CLASS="listitem">
+<P CLASS="para">
+Indicates a missing or misspelled section in a <CODE CLASS="literal">
+copy</code> <CODE CLASS="literal">
+=</code> option.</p></dd><DT CLASS="term">
+"Ignoring unknown parameter name" </dt><DD CLASS="listitem">
+<P CLASS="para">
+Typically indicates an obsolete, misspelled or unsupported option.</p></dd><DT CLASS="term">
+"Global parameter name found in service section" </dt><DD CLASS="listitem">
+<P CLASS="para">
+Indicates a global-only parameter has been used in an individual share. Samba will ignore the parameter.</p></dd></dl><P CLASS="para">
+After the <CODE CLASS="literal">
+testparm</code> test, repeat it with (exactly) three parameters: the name of your <I CLASS="filename">
+smb.conf</i> file, the name of your client, and its IP address:</p><PRE CLASS="programlisting">testparm <CODE CLASS="replaceable"><I>samba_directory</i></code>/lib/smb.conf client 192.168.236.10</pre><P CLASS="para">
+This will run one more test that checks the host name and address against <CODE CLASS="literal">
+host</code> <CODE CLASS="literal">
+allow</code> and <CODE CLASS="literal">
+host</code> <CODE CLASS="literal">
+deny</code> options and may produce the "Allow/Deny connection from account account_name" to service message for the client machine. This message indicates you have valid/invalid host options in your <I CLASS="filename">
+smb.conf</i>, and they prohibit access from the client machine. Entering <CODE CLASS="literal">
+testparm</code> <CODE CLASS="literal">
+/usr/local/lib/experimental.conf</code> is also an effective way to test an experimental <I CLASS="filename">
+smb.conf</i> file before putting it into production.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-945478">9.2.5 Troubleshooting SMB Connections</a></h3><P CLASS="para">Now that you know the servers are up, you need to make sure that they're running properly. We start with the <I CLASS="filename">
+smb.conf</i> file in the <CODE CLASS="replaceable">
+<I>
+samba_directory</i></code><I CLASS="filename">
+/lib</i> directory.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-67928">
+9.2.5.1 A minimal smb.conf file</a></h4><P CLASS="para">
+In the following tests, we assume you have a <CODE CLASS="literal">
+[temp]</code> share suitable for testing, plus at least one account. An <I CLASS="filename">
+smb.conf</i> file that includes just these is:</p><PRE CLASS="programlisting">
+[global]
+ workgroup = <CODE CLASS="replaceable">
+<I>
+EXAMPLE</i></code>
+ security = user
+ browsable = yes
+ local master = yes
+[homes]
+ guest ok = no
+ browseble = no
+[temp]
+ path = /tmp
+ public = yes </pre><P CLASS="para">
+A word of warning: the <CODE CLASS="literal">
+public</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option in the <CODE CLASS="literal">
+[temp]</code> share is just for testing. You probably don't want people without accounts to be able to store things on your Samba server, so you should comment it out when you're done.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-40595">
+9.2.5.2 Testing locally with smbclient</a></h4><P CLASS="para">The first test is to ensure the server can list its own services (shares). Run the command <CODE CLASS="literal">
+smbclient</code> with a <CODE CLASS="literal">
+-L</code> option of <CODE CLASS="literal">
+localhost</code> to connect to itself, and a <CODE CLASS="literal">
+-U</code> option of just <CODE CLASS="literal">
+%</code> to specify the guest user. You should see the following: </p><PRE CLASS="programlisting">server% <CODE CLASS="userinput"><B>smbclient -L localhost -U% </b></code>
+Server time is Wed May 27 17:57:40 1998 Timezone is UTC-4.0
+Server=[localhost]
+User=[davecb]
+Workgroup=[EXAMPLE]
+Domain=[EXAMPLE]
+ Sharename Type Comment
+ --------- ----- ----------
+ temp Disk
+ IPC$ IPC IPC Service (Samba 1.9.18)
+ homes Disk Home directories
+This machine does not have a browse list </pre><P CLASS="para">
+If you received this output, move on to the next test, <A CLASS="xref" HREF="ch09_02.html#ch09-77154">
+Section 9.2.5.3, Testing connections with smbclient</a>. On the other hand, if you receive an error, check the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-950443">
+</a>If you get "Get_hostbyname: unknown host localhost," either you've spelled its name wrong or there actually is a problem (which should have been seen back in <A CLASS="xref" HREF="ch09_02.html#ch09-20350">
+Section 9.2.2.2</a>) In the latter case, move on to "Troubleshooting Name Services."</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945526">
+</a>If you get "Connect error: Connection refused," the server machine was found, but it wasn't running an <EM CLASS="emphasis">
+nmbd</em> daemon. Skip back to <A CLASS="xref" HREF="ch09_02.html#ch09-88968">
+Section 9.2.4</a>, and retest the daemons.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945531">
+</a>If you get the message "Your server software is being unfriendly," the initial session request packet got a garbage response from the server. The server may have crashed or started improperly. The common causes of this can be discovered by scanning the logs for:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945533">
+</a>Invalid command-line parameters to <EM CLASS="emphasis">
+smbd</em>; see the <EM CLASS="emphasis">
+smbd</em> manual page.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945534">
+</a>A fatal problem with the <I CLASS="filename">
+smb.conf</i> file that prevents the startup of <EM CLASS="emphasis">
+smbd</em>. Always check your changes, as was done in the section <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5, Testing daemons with testparm</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947160">
+</a>The directories where Samba keeps its log and lock files are missing.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947165">
+</a>There is already a server on the port (139 for <EM CLASS="emphasis">
+smbd</em>, 137 for <EM CLASS="emphasis">
+nmbd </em>), preventing it from starting.</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945543">
+</a>If you're using <EM CLASS="emphasis">
+inetd</em> instead of stand-alone daemons, check your <I CLASS="filename">
+/etc/inetd.conf</i> and <I CLASS="filename">
+/etc/services</i> entries against their manual pages for errors as well.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945544">
+</a>If you get a <CODE CLASS="literal">
+Password:</code> prompt, your guest account is not set up properly. The <CODE CLASS="literal">
+%U</code> option tells <EM CLASS="emphasis">
+smbclient</em> to do a "null login," which requires that the guest account be present but does not require it to have any privileges.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947172">
+</a>If you get the message "SMBtconX failed. ERRSRV&nbsp;- ERRaccess," you aren't permitted access to the server. This normally means you have a <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+hosts</code> option that doesn't include the server, or an <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+hosts</code> option that does. Recheck with the command <CODE CLASS="literal">
+testparm</code> <CODE CLASS="literal">
+smb.conf</code> <CODE CLASS="replaceable">
+<I>
+your_hostname</i></code> <CODE CLASS="replaceable">
+<I>
+your_ip_address</i></code> (see the section <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>) and correct any unintended prohibitions. </p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-77154">
+9.2.5.3 Testing connections with smbclient</a></h4><P CLASS="para">Run the command <CODE CLASS="literal"> smbclient</code><CODE CLASS="literal">\\</code><CODE CLASS="replaceable"><I>server</i></code><CODE CLASS="literal">\temp</code>, which connects to your server's <I CLASS="filename">
+/tmp</i> share, to see if you can connect to a file service. You should get the following response:</p><PRE CLASS="programlisting"><B CLASS="emphasis.bold"><CODE CLASS="literal">server% </code>smbclient '\\server\temp' </b>
+</pre><PRE CLASS="programlisting">
+Server time is Tue May 5 09:49:32 1998 Timezone is UTC-4.0 Password:
+<B CLASS="emphasis.bold"><CODE CLASS="literal">
+smb:\&gt;</code> quit</b></pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947183">
+</a>If you get "Get_Hostbyname: Unknown host name," "Connect error: Connection refused," or "Your server software is being unfriendly," see the section <A CLASS="xref" HREF="ch09_02.html#ch09-40595">
+Section 9.2.5.2, Testing locally with smbclient</a> for the diagnoses.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947188">
+</a>If you get the message "servertemp: Not enough `\' characters in service," you likely didn't quote the address, so Unix stripped off backslashes. You can also write the command:</p></li></ul><PRE CLASS="programlisting"><CODE CLASS="literal">smbclient</code> <CODE CLASS="literal">\\\\</code><CODE CLASS="replaceable"><I>server</i></code><CODE CLASS="literal">\\temp</code> </pre><P CLASS="para">
+or: </p><PRE CLASS="programlisting">smbclient //<CODE CLASS="replaceable"><I>server</i></code>/temp </pre><P CLASS="para">
+Now, provide your Unix account password to the <CODE CLASS="literal">
+Password</code> prompt. If you then get an <CODE CLASS="literal">
+smb\&gt;</code> prompt, it worked. Enter <CODE CLASS="literal">
+quit</code>, and continue on to <A CLASS="xref" HREF="ch09_02.html#ch09-97081">
+Section 9.2.5.4, Testing connections with NET USE</a>. If you then get "SMBtconX failed. ERRSRV&nbsp;- ERRinvnetname," the problem can be any of the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947201">
+</a>A wrong share name: you may have spelled it wrong, it may be too long, it may be in mixed case, or it may not be available. Check that it's what you expect with testparm (see the section <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>.)</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947205">
+</a><CODE CLASS="literal">
+security</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+share</code>, in which you may have to add <CODE CLASS="replaceable">
+<I>
+-U your_account</i></code> to the <EM CLASS="emphasis">
+smbclient</em> command, or know the password of a Unix account named temp. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945578">
+</a>An erroneous username.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945579">
+</a>An erroneous password.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945580">
+</a>An <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> or <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> option in your <EM CLASS="emphasis">
+smb.conf</em> file that doesn't allow your account to connect. Recheck with <CODE CLASS="literal">
+testparm</code> <CODE CLASS="literal">
+smb.conf</code> <CODE CLASS="replaceable">
+<I>
+your_hostname your_ip_address</i></code> (see <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945584">
+</a>A <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+hosts</code> option that doesn't include the server, or an <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+hosts</code> option that does. Also test this with <EM CLASS="emphasis">
+testparm</em>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945585">
+</a>A problem in authentication, such as if shadow passwords or the PAM (Password Authentication Module) is used on the server, but Samba is not compiled to use it. This is rare, but occasionally happens when a SunOS 4 Samba binary (no shadow passwords) is run without recompilation on a Solaris system (with shadow passwords).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945586">
+</a>The <CODE CLASS="literal">
+encrypted</code> <CODE CLASS="literal">
+passwords</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option in the configuration file, but no password for your account in the <EM CLASS="emphasis">
+smbpasswd</em> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945587">
+</a>You have a null password entry, either in Unix <I CLASS="filename">
+/etc/passwd</i> or in the <EM CLASS="emphasis">
+smbpasswd</em> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945588">
+</a>You are connecting to <CODE CLASS="literal">
+[temp]</code>, and you do not have the <CODE CLASS="literal">
+guest</code> <CODE CLASS="literal">
+ok</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> option in the <CODE CLASS="literal">
+[temp]</code> section of the <EM CLASS="emphasis">
+smb.conf</em> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947992">
+</a>You are connecting to <CODE CLASS="literal">
+[temp]</code> before connecting to your home directory, and your guest account isn't set up correctly. If you can connect to your home directory and then connect to <CODE CLASS="literal">
+[temp]</code>, that's the problem. See <a href="ch02_01.html"><b>Chapter 2</b></a> for more information on creating a basic Samba configuration file.</p><P CLASS="para">
+A bad guest account will also prevent you from printing or browsing until after you've logged in to your home directory. </p></li></ul><P CLASS="para">
+There is one more reason for this failure that has nothing at all to do with passwords: the <CODE CLASS="literal">
+path</code> <CODE CLASS="literal">
+=</code> line in your <I CLASS="filename">
+smb.conf</i> file may point somewhere that doesn't exist. This will not be diagnosed by <EM CLASS="emphasis">
+testparm</em>, and most SMB clients can't tell it from other types of bad user accounts. You will have to check it manually.</p><P CLASS="para">
+Once you have connected to <CODE CLASS="literal">
+[temp]</code> successfully, repeat the test, this time logging in to your home directory (e.g., map network drive <CODE CLASS="replaceable">
+<I>
+server</i></code><CODE CLASS="literal">
+\davecb</code>) looking for failures in doing that. If you have to change anything to get that to work, re-test <CODE CLASS="literal">
+[temp]</code> again afterwards.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-97081">
+9.2.5.4 Testing connections with NET USE</a></h4><P CLASS="para">Run the command <CODE CLASS="literal">
+net</code> <CODE CLASS="literal">use</code> <CODE CLASS="literal">* </code><CODE CLASS="literal">\</code><CODE CLASS="replaceable"><I>server</i></code><CODE CLASS="literal">\temp</code> on the DOS or Windows client to see if it can connect to the server. You should be prompted for a password, then receive the response "The command was completed successfully," as shown in <A CLASS="xref" HREF="ch09_02.html#ch09-99328">
+Figure 9.2</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch09-99328">
+Figure 9.2: Results of the NET USE command</a></h4><IMG CLASS="graphic" SRC="figs/sam.0902.gif" ALT="Figure 9.2"><P CLASS="para">
+If that succeeded, continue with the steps in the section <A CLASS="xref" HREF="ch09_02.html#ch09-57065">
+Section 9.2.5.5, Testing connections with Windows Explorer</a>. Otherwise:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945608">
+</a>If you get "The specified shared directory cannot be found," or "Cannot locate specified share name," the directory name is either misspelled or not in the <EM CLASS="emphasis">
+smb.conf</em> file. This message can also warn of a name in mixed case, including spaces, or is longer than eight characters.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945610">
+</a>If you get "The computer name specified in the network path cannot be located," or "Cannot locate specified computer," the directory name has been misspelled, the name service has failed, there is a networking problem, or the <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> <CODE CLASS="literal">
+=</code> option includes your host.</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945612">
+</a>If it is not a spelling mistake, you need to double back to at least the section <A CLASS="xref" HREF="ch09_02.html#ch09-77154">
+Section 9.2.5.3</a>, to investigate why it doesn't connect.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945617">
+</a>If <EM CLASS="emphasis">
+smbclient</em> does work, it's a name service problem with the client name service, and you need to go forward to the section <A CLASS="xref" HREF="ch09_02.html#ch09-12446">
+Section 9.2.6.2, Testing the server with nmblookup</a>, and see if you can look up both client and server with <EM CLASS="emphasis">
+nmblookup</em>.</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945622">
+</a>If you get "The password is invalid for <CODE CLASS="literal">\</code><CODE CLASS="replaceable"><I>server</i></code><CODE CLASS="literal">\</code><CODE CLASS="replaceable"><I>username</i></code>," your locally cached copy on the client doesn't match the one on the server. You will be prompted for a replacement.</p></li></ul><P CLASS="para">
+Windows 95 and 98 clients keep a local <EM CLASS="emphasis">
+password</em> file, but it's really just a cached copy of the password it sends to Samba and NT servers to authenticate you. That's what is being prompted for here. You can still log on to a Windows machine without a password (but not to NT).</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+If you provide your password, and it still fails, your password is not being matched on the server, you have a <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> or <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> list denying you permission, NetBEUI is interfering, or the encrypted password problem described in the next paragraph exists.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945627">
+</a>If your client is NT 4.0, NT 3.5 with Patch 3, Windows 95 with Patch 3, Windows 98 or any of these with Internet Explorer 4.0, these default to using Microsoft encryption for passwords (discussed in <a href="ch06_01.html"><b>Chapter 6, <CITE CLASS="chapter">Users, Security, and Domains</cite></b></a>'s <a href="ch06_04.html"><b>Section 6.4, Passwords</b> in <b>Chapter 6</b></a> section, along with the alternatives). In general, if you have installed a major Microsoft product recently, you may have applied an update and turned on encrypted passwords.</p></li></ul><P CLASS="para">
+Because of Internet Explorer's willingness to honor URLs such as <I CLASS="filename">
+file://somehost/somefile</i> by making SMB connections, clients up to and including Windows 95 Patch Level 2 would happily send your password, in plaintext, to SMB servers anywhere on the Internet. This was considered a bad idea, and Microsoft quite promptly switched to using only encrypted passwords in the SMB protocol. All subsequent releases of their products have included this correction. Encrypted passwords aren't actually needed unless you're using Internet Explorer 4.0 without a firewall, so it's reasonable to keep using unencrypted passwords on your own networks.</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-953889">
+</a>If you have a mixed-case password on Unix, the client is probably sending it in all one case. If changing your password to all one case works, this was the problem. Regrettably, all but the oldest clients support uppercase passwords, so Samba will try once with it in uppercase and once in lower case. If you wish to use mixed-case passwords, see the <CODE CLASS="literal">
+password</code> <CODE CLASS="literal">
+level</code> option in <a href="ch06_01.html"><b>Chapter 6</b></a> for a workaround.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-953895">
+</a>You may have a <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> problem, as tested with <EM CLASS="emphasis">
+smbclient</em> (see <A CLASS="xref" HREF="ch09_02.html#ch09-77154">
+Section 9.2.5.3</a>).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945642">
+</a>You may have the NetBEUI protocol bound to the Microsoft client. This often produces long timeouts and erratic failures, and is known to have caused failures to accept passwords in the past.</p></li></ul><P CLASS="para">
+The term "bind" is used to mean connecting a piece of software to another in this case. The Microsoft SMB client is "bound to" TCP/IP in the bindings section of the TCP/IP properties panel under the Windows 95/98 Network icon in the Control Panel. TCP/IP in turn is bound to an Ethernet card. This is not the same sense of the word as binding an SMB daemon to a TCP/IP port.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-57065">9.2.5.5 Testing connections with Windows Explorer</a></h4><P CLASS="para">Start Windows Explorer or NT Explorer (not Internet Explorer), select Tools&#8594;Map Network Drive and specify \\<CODE CLASS="replaceable">
+<I>
+server</i></code>\<CODE CLASS="literal">
+temp</code> to see if you can make Explorer connect to the <I CLASS="filename">
+/tmp</i> directory. You should see a screen similar to the one in <A CLASS="xref" HREF="ch09_02.html#ch09-74414">
+Figure 9.3</a>. If so, you've succeeded and can skip to <A CLASS="xref" HREF="ch09_02.html#ch09-23573">
+Section 9.2.6, Troubleshooting Browsing </a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch09-74414">
+Figure 9.3: Accessing the /tmp directory with Windows Explorer</a></h4><IMG CLASS="graphic" SRC="figs/sam.0903.gif" ALT="Figure 9.3"><P CLASS="para">
+A word of caution: Windows Explorer and NT Explorer are rather poor as diagnostic tools: they do tell you that something's wrong, but rarely what it is. If you get a failure, you'll need to track it down with the NET USE command, which has far superior error reporting:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945661">
+</a>If you get "The password for this connection that is in your password file is no longer correct," you may have any of the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945662">
+</a>Your locally cached copy on the client doesn't match the one on the server.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945663">
+</a>You didn't provide a username and password when logging on to the client. Most Explorers will continue to send a username and password of null, even if you provide a password.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945664">
+</a>You have misspelled the password.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945665">
+</a>You have an <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> or <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> list denying permission.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945666">
+</a>Your client is NT 4.0, NT 3.5 with Patch 3, Windows 95 with Patch 3, Windows 98, or any of these with Internet Explorer 4. They will all want encrypted passwords.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945667">
+</a>You have a mixed-case password, which the client is supplying in all one case.</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945669">
+</a>If you get "The network name is either incorrect, or a network to which you do not have full access," or "Cannot locate specified computer," you may have any of the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945671">
+</a> Misspelled name</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945672">
+</a> Malfunctioning service </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945673">
+</a> Failed share</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945674">
+</a> Networking problem</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945675">
+</a> Bad <CODE CLASS="literal">
+path</code> line</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945676">
+</a> <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> line that excludes you</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945677">
+</a>If you get "You must supply a password to make this connection," the password on the client is out of synchronization with the server, or this is the first time you've tried from this client machine and the client hasn't cached it locally yet.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945681">
+</a>If you get "Cannot locate specified share name," you have a wrong share name or a syntax error in specifying it, a share name longer than eight characters, or one containing spaces or in mixed case.</p></li></ul><P CLASS="para">
+Once you can reliably connect to the <CODE CLASS="literal">
+[temp]</code> directory, try once again, this time using your home directory. If you have to change something to get home directories working, then retest with <CODE CLASS="literal">
+[temp]</code>, and vice versa, as we showed in the section <A CLASS="xref" HREF="ch09_02.html#ch09-97081">
+Section 9.2.5.4</a>. As always, if Explorer fails, drop back to that section and debug it there.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-23573">9.2.6 Troubleshooting Browsing </a></h3><P CLASS="para">Finally, we come to browsing. This was left to last, not because it is hardest, but because it's both optional and partially dependent on a protocol that doesn't guarantee delivery of a packet. Browsing is hard to diagnose if you don't already know all the other services are running. </p><P CLASS="para">
+Browsing is purely optional: it's just a way to find the servers on your net and the shares that they provide. Unix has nothing of the sort and happily does without. Browsing also assumes all your machines are on a local area network (LAN) where broadcasts are allowable.</p><P CLASS="para">
+First, the browsing mechanism identifies a machine using the unreliable UDP protocol; then it makes a normal (reliable) TCP/IP connection to list the shares the machine provides.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-96207">
+9.2.6.1 Testing browsing with smbclient </a></h4><P CLASS="para">We'll start with testing the reliable connection first. From the server, try listing its own shares via <EM CLASS="emphasis">
+smbclient</em> with a <CODE CLASS="literal">
+-L</code> option of your server's name. You should get: </p><PRE CLASS="programlisting">server% <CODE CLASS="userinput"><B>smbclient -L server</b></code>
+Added interface ip=192.168.236.86 bcast=192.168.236.255 nmask=255.255.255.0 Server time is Tue Apr 28 09:57:28 1998 Timezone is UTC-4.0
+Password:
+Domain=[EXAMPLE]
+OS=[Unix]
+Server=[Samba 1.9.18]
+Server=[server]
+User=[davecb]
+Workgroup=[EXAMPLE]
+Domain=[EXAMPLE]
+ Sharename Type Comment
+ --------- ---- -------
+ cdrom Disk CD-ROM
+ cl Printer Color Printer 1
+ davecb Disk Home Directories
+
+ This machine has a browse list:
+ Server Comment
+ --------- -------
+ SERVER Samba 1.9.18
+
+ This machine has a workgroup list:
+ Workgroup Master
+ --------- -------
+ EXAMPLE SERVER</pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-950922">
+</a>If you didn't get a Sharename list, the server is not allowing you to browse any shares. This should not be the case if you've tested any of the shares with Windows Explorer or the NET USE command. If you haven't done the <CODE CLASS="literal">
+smbclient</code> <CODE CLASS="literal">
+-L</code> <CODE CLASS="literal">
+localhost</code> <CODE CLASS="literal">
+-U%</code> test yet (see <A CLASS="xref" HREF="ch09_02.html#ch09-40595">
+Section 9.2.5.2</a>), do it now. An erroneous guest account can prevent the shares from being seen. Also, check the <I CLASS="filename">
+smb.conf</i> file to make sure you do not have the option <CODE CLASS="literal">
+browsable</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+no</code> anywhere in it: we suggest a minimal <I CLASS="filename">
+smb.conf</i> file (see <A CLASS="xref" HREF="ch09_02.html#ch09-67928">
+Section 9.2.5.1, A minimal smb.conf file</a>) for you to steal from. You need to have <CODE CLASS="literal">
+browseable</code> enabled in order to be able to see at least the <CODE CLASS="literal">
+[temp]</code> share.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945728">
+</a>If you didn't get a browse list, the server is not providing information about the machines on the network. At least one machine on the net must support browse lists. Make sure you have <CODE CLASS="literal">
+local</code> <CODE CLASS="literal">
+master</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> in the <I CLASS="filename">
+smb.conf</i> file if you want Samba be the local master browser.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945730">
+</a>If you got a browse list but didn't get <EM CLASS="emphasis">
+/tmp</em>, you probably have a <I CLASS="filename">
+smb.conf</i> problem. Go back to <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945734">
+</a>If you didn't get a workgroup list with your workgroup name in it, it is possible that your workgroup is set incorrectly in the <I CLASS="filename">
+smb.conf</i> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945735">
+</a>If you didn't get a workgroup list at all, ensure that <CODE CLASS="literal">
+workgroup</code> <CODE CLASS="literal">
+=EXAMPLE</code> is present in the <I CLASS="filename">
+smb.conf</i> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945736">
+</a>If you get nothing, try once more with the options <CODE CLASS="literal">
+-I</code> <CODE CLASS="replaceable">
+<I>
+ip_address</i></code> <CODE CLASS="literal">
+-n</code> <CODE CLASS="replaceable">
+<I>
+netbios_name</i></code> <CODE CLASS="literal">
+-W</code> <CODE CLASS="replaceable">
+<I>
+workgroup</i></code> <CODE CLASS="literal">
+-d3</code> with the NetBIOS and workgroup name in uppercase. (The <CODE CLASS="literal">
+-d</code> <CODE CLASS="literal">
+3</code> option sets the log /debugging level to 3.)</p></li></ul><P CLASS="para">
+If you're still getting nothing, you shouldn't have gotten this far. Double back to at least <A CLASS="xref" HREF="ch09_02.html#ch09-78512">
+Section 9.2.3.1, Testing TCP with FTP </a>, or perhaps <A CLASS="xref" HREF="ch09_02.html#ch09-84079">
+Section 9.2.2.4</a>. On the other hand:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945746">
+</a>If you get "SMBtconX failed. ERRSRV&nbsp;- ERRaccess," you aren't permitted access to the server. This normally means you have a <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+hosts</code> option that doesn't include the server, or an invalid hosts option that does.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945748">
+</a> If you get "Bad password," then you presumably have one of the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945749">
+</a> An incorrect <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> or <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> line</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945750">
+</a> An incorrect <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> or <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> line</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945751">
+</a> A lowercase password and OS/2 or Windows for Workgroups clients</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945752">
+</a> A missing or invalid guest account</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+Check what your guest account is (see <A CLASS="xref" HREF="ch09_02.html#ch09-40595">
+Section 9.2.5.2</a>) and verify your <I CLASS="filename">
+smb.conf</i> file with <CODE CLASS="literal">
+testparm</code> <CODE CLASS="literal">
+smb.conf</code> <CODE CLASS="replaceable">
+<I>
+your_hostname your_ip_address</i></code> (see <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>) and change or comment out any <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code>, <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code>, <CODE CLASS="literal">
+valid</code> <CODE CLASS="literal">
+users</code> or <CODE CLASS="literal">
+invalid</code> <CODE CLASS="literal">
+users</code> lines.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945761">
+</a>If you get "Connection refused," the <EM CLASS="emphasis">
+smbd</em> server is not running or has crashed. Check that it's up, running, and listening to the network with <EM CLASS="emphasis">
+netstat</em>, see step <A CLASS="xref" HREF="ch09_02.html#ch09-67494">
+Section 9.2.4.5</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-952948">
+</a>If you get "Get_Hostbyname: Unknown host name," you've made a spelling error, there is a mismatch between Unix and NetBIOS hostname, or there is a name service problem. Start nameservice debugging with <A CLASS="xref" HREF="ch09_02.html#ch09-97081">
+Section 9.2.5.4</a>. If this works, suspect a name mismatch and go to step <A CLASS="xref" HREF="ch09_02.html#ch09-35552">
+Section 9.2.10, Troubleshooting NetBIOS Names</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945777">
+</a>If you get "Session request failed," the server refused the connection. This usually indicates an internal error, such as insufficient memory to fork a process.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945778">
+</a>If you get "Your server software is being unfriendly," the initial session request packet received a garbage response from the server. The server may have crashed or started improperly. Go back to <A CLASS="xref" HREF="ch09_02.html#ch09-40595">
+Section 9.2.5.2</a>, where the problem is first analyzed.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945785">
+</a>If you suspect the server is not running, go back to <A CLASS="xref" HREF="ch09_02.html#ch09-49239">
+Section 9.2.4.2, Looking for daemon processes with ps</a> to see why the server daemon isn't responding.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-12446">9.2.6.2 Testing the server with nmblookup</a></h4><P CLASS="para">
+This will test the "advertising" system used for Windows name services and browsing. Advertising works by broadcasting one's presence or willingness to provide services. It is the part of browsing that uses an unreliable protocol (UDP), and works only on broadcast networks like Ethernets. The <EM CLASS="emphasis">
+nmblookup</em> program broadcasts name queries for the hostname you provide, and returns its IP address and the name of the machine, much like <EM CLASS="emphasis">
+nslookup</em> does with DNS. Here, the <CODE CLASS="literal">
+-d</code> (debug- or log-level) option, and the <CODE CLASS="literal">
+-B</code> (broadcast address) options direct queries to specific machines.</p><P CLASS="para">
+First, we check the server from itself. Run <EM CLASS="emphasis">
+nmblookup</em> with a <CODE CLASS="literal">
+-B</code> option of your server's name to tell it to send the query to the Samba server, and a parameter of <CODE CLASS="literal">
+__SAMBA__</code> as the symbolic name to look up. You should get: </p><PRE CLASS="programlisting">server% <B CLASS="emphasis.bold">nmblookup -B </b><CODE CLASS="replaceable"><I>server</i></code> <B CLASS="emphasis.bold">__SAMBA__ </b>
+Added interface ip=192.168.236.86 bcast=192.168.236.255 nmask=255.255.255.0
+Sending queries to 192.168.236.86 192.168.236.86 __SAMBA__ </pre><P CLASS="para">
+You should get the IP address of the server, followed by the name <CODE CLASS="literal">
+__SAMBA__ </code>, which means that the server has successfully advertised that it has a service called <CODE CLASS="literal">
+__SAMBA__ </code>, and therefore at least part of NetBIOS nameservice works.</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945802">
+</a>If you get "Name_query failed to find name __SAMBA__" you may have specified the wrong address to the <CODE CLASS="literal">
+-B</code> option, or <EM CLASS="emphasis">
+nmbd</em> is not running. The <CODE CLASS="literal">
+-B</code> option actually takes a broadcast address: we're using a machine-name to get a unicast address, and to ask server if it has claimed <CODE CLASS="literal">
+__SAMBA__</code>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947471">
+</a>Try again with <CODE CLASS="literal">
+-B</code><CODE CLASS="replaceable">
+<I>
+ ip_address</i></code>, and if that fails too, <EM CLASS="emphasis">
+nmbd</em> isn't claiming the name. Go back briefly to "Testing daemons with testparm" to see if <EM CLASS="emphasis">
+nmbd</em> is running. If so, it may not claiming names; this means that Samba is not providing the browsing service&nbsp;- a configuratiuon problem. If that is the case, make sure that <I CLASS="filename">
+smb.conf</i> doesn't contain the option <CODE CLASS="literal">
+browsing</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+no</code>.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-32122">
+9.2.6.3 Testing the client with nmblookup</a></h4><P CLASS="para">
+Next, check the IP address of the client from the server with <EM CLASS="emphasis">
+nmblookup</em> using <CODE CLASS="literal">
+-B</code> option for the client's name and a parameter of <CODE CLASS="literal">
+'*'</code> meaning "anything," as shown here: </p><PRE CLASS="programlisting">server% <B CLASS="emphasis.bold">nmblookup -B client '*'</b>
+Sending queries to 192.168.236.10 192.168.236.10 *
+Got a positive name query response from 192.168.236.10 (192.168.236.10)</pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945817">
+</a>If you receive "Name-query failed to find name *," you have made a spelling mistake, or the client software on the PC isn't installed, started, or bound to TCP/IP. Double back to <a href="ch02_01.html"><b>Chapter 2</b></a> or <a href="ch03_01.html"><b>Chapter 3</b></a> and ensure you have a client installed and listening to the network. </p></li></ul><P CLASS="para">
+Repeat the command with the following options if you had any failures:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945824">
+</a>If <CODE CLASS="literal">
+nmblookup</code> <CODE CLASS="literal">
+-B</code> <CODE CLASS="replaceable">
+<I>
+client_IP_address</i></code> succeeds but <CODE CLASS="literal">
+-B</code> <CODE CLASS="replaceable">
+<I>
+client_name</i></code> fails, there is a name service problem with the client's name; go to <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945825">
+</a>If <CODE CLASS="literal">
+nmblookup</code> <CODE CLASS="literal">
+-B</code> <CODE CLASS="literal">
+127.0.0.1'*'</code> succeeds, but <CODE CLASS="literal">
+-B</code> <CODE CLASS="replaceable">
+<I>
+client_IP_address</i></code> fails, there is a hardware problem and ping should have failed. See your network manager. </p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-98123">
+9.2.6.4 Testing the network with nmblookup</a></h4><P CLASS="para">
+Run the command <EM CLASS="emphasis">
+nmblookup</em> again with a <CODE CLASS="literal">
+-d</code> option (debug level) of 2 and a parameter of <CODE CLASS="literal">
+'*'</code> again. This time we are testing the ability of programs (such as <EM CLASS="emphasis">
+nmbd </em>) to use broadcast. It's essentially a connectivity test, done via a broadcast to the default broadcast address. </p><P CLASS="para">
+A number of NetBIOS/TCP-IP hosts on the network should respond with "got a positive name query response" messages. Samba may not catch all of the responses in the short time it listens, so you won't always see all the SMB clients on the network. However, you should see most of them:</p><PRE CLASS="programlisting">server% <B CLASS="emphasis.bold">nmblookup -d 2 '*' </b>
+Added interface ip=192.168.236.86 bcast=192.168.236.255 nmask=255.255.255.0 Sending queries to 192.168.236.255
+Got a positive name query response from 192.168.236.191 (192.168.236.191)
+Got a positive name query response from 192.168.236.228 (192.168.236.228)
+Got a positive name query response from 192.168.236.75 (192.168.236.75)
+Got a positive name query response from 192.168.236.79 (192.168.236.79)
+Got a positive name query response from 192.168.236.206 (192.168.236.206)
+Got a positive name query response from 192.168.236.207 (192.168.236.207)
+Got a positive name query response from 192.168.236.217 (192.168.236.217)
+Got a positive name query response from 192.168.236.72 (192.168.236.72) 192.168.236.86 * </pre><P CLASS="para">
+However:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945841">
+</a>If this doesn't give at least the client address you previously tested, the default broadcast address is wrong. Try <CODE CLASS="literal">
+nmblookup</code> <CODE CLASS="literal">
+-B</code> <CODE CLASS="literal">
+255.255.255.255</code> <CODE CLASS="literal">
+-d</code> <CODE CLASS="literal">
+2</code> <CODE CLASS="literal">
+'*'</code>, which is a last-ditch variant (a broadcast address of all ones). If this draws responses, the broadcast address you've been using before is wrong. Troubleshooting these is discussed in the <A CLASS="xref" HREF="ch09_02.html#ch09-45060">
+Section 9.2.9.2, Broadcast addresses</a> section, later in this chapter.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-951306">
+</a>If the address 255.255.255.255 fails too, check your notes to see if your PC and server are on different subnets, as discovered in <A CLASS="xref" HREF="ch09_02.html#ch09-84079">
+Section 9.2.2.4</a>. You should try to diagnose this with a server and client on the same subnet, but if you can't, you can try specifying the remote subnet's broadcast address with <CODE CLASS="literal">
+-B</code>. Finding that address is discussed in the same place as troubleshooting broadcast addresses, in the section <A CLASS="xref" HREF="ch09_02.html#ch09-45060">
+Section 9.2.9.2</a>, later in this chapter. The <CODE CLASS="literal">
+-B</code> option will work if your router supports directed broadcasts; if it doesn't, you may be forced to test with a client on the same network.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-947520">
+9.2.6.5 Testing client browsing with net view</a></h4><P CLASS="para">On the client, run the command <CODE CLASS="replaceable"><I>net view \\server</i></code> in a DOS window to see if you can connect to the client and ask what shares it provides. You should get back a list of available shares on the server, as shown in <A CLASS="xref" HREF="ch09_02.html#ch09-83710">
+Figure 9.4</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch09-83710">
+Figure 9.4: Using the net view command</a></h4><IMG CLASS="graphic" SRC="figs/sam.0904.gif" ALT="Figure 9.4"><P CLASS="para">
+If you received this, continue with the section <A CLASS="xref" HREF="ch09_02.html#ch09-21713">
+Section 9.2.7, Other Things that Fail</a>.</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-953009">
+</a>If you get "Network name not found" for the name you just tested in the section <A CLASS="xref" HREF="ch09_02.html#ch09-32122">
+Section 9.2.6.3, Testing the client with nmblookup</a>, there is a problem with the client software itself. Double-check this by running <EM CLASS="emphasis">
+nmblookup</em> on the client; if it works and NET VIEW doesn't, the client is at fault.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945868">
+</a>Of course, if <EM CLASS="emphasis">
+nmblookup</em> fails, there is a NetBIOS nameservice problem, as discussed in the section <A CLASS="xref" HREF="ch09_02.html#ch09-35552">
+Section 9.2.10</a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945874">
+</a>If you get "You do not have the necessary access rights," or "This server is not configured to list shared resources," either your guest account is misconfigured (see <A CLASS="xref" HREF="ch09_02.html#ch09-40595">
+Section 9.2.5.2</a>), or you have a <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+allow</code> or <CODE CLASS="literal">
+hosts</code> <CODE CLASS="literal">
+deny</code> line that prohibits connections from your machine. These problems should have been detected by the <EM CLASS="emphasis">
+smbclient</em> tests starting in the section <A CLASS="xref" HREF="ch09_02.html#ch09-96207">
+Section 9.2.6.1, Testing browsing with smbclient </a>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945882">
+</a>If you get "The specified computer is not receiving requests," you have misspelled the name, the machine is unreachable by broadcast (tested in "Testing the network with nmblookup"), or it's not running <EM CLASS="emphasis">
+nmbd</em>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-954090">
+</a>If you get "Bad password error," you're probably encountering the Microsoft-encrypted password problem, as discussed in <a href="ch06_01.html"><b>Chapter 6</b></a>, with its corrections.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-954094">
+9.2.6.6 Browsing the server from the client</a></h4><P CLASS="para">From the Network Neighborhood (File Manager in older releases), try to browse the server. Your Samba server should appear in the browse list of your local workgroup. You should be able to double click on the name of the server and get a list of shares, as illustrated in <A CLASS="xref" HREF="ch09_02.html#ch09-60004">
+Figure 9.5</a>. </p><H4 CLASS="figure">
+<A CLASS="title" NAME="ch09-60004">
+Figure 9.5: List of shares on a server</a></h4><IMG CLASS="graphic" SRC="figs/sam.0905.gif" ALT="Figure 9.5"><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945897">
+</a>If you get an "Invalid password" error with NT 4.0, NT 3.5 with Patch 3, Windows 95 with Patch 3, Windows 98 or any of these with Internet Explorer 4.0, it's most likely the encryption problem again. All of these clients default to using Microsoft encryption for passwords (see <a href="ch06_01.html"><b>Chapter 6</b></a>).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945903">
+</a>If you receive an "Unable to browse the network" error, one of the following has ocurred:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945904">
+</a>You have looked too soon, before the broadcasts and updates have completed; try waiting 30 seconds before re-attempting.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945905">
+</a>There is a network problem you've not yet diagnosed.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945906">
+</a>There is no browse master. Add the configuration option <CODE CLASS="literal">
+local</code> <CODE CLASS="literal">
+master</code> <CODE CLASS="literal">
+=</code> <CODE CLASS="literal">
+yes</code> to your <EM CLASS="emphasis">
+smb.conf</em> file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945907">
+</a>No shares are marked <CODE CLASS="literal">
+browsable</code> in the <EM CLASS="emphasis">
+smb.conf</em> file.</p></li></ul></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945909">
+</a>If you receive the message "\\server is not accessible," then:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945910">
+</a> You have the encrypted password problem</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945911">
+</a> The machine really isn't accessible </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945912">
+</a> The machine doesn't support browsing</p></li></ul></li></ul></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-21713">9.2.7 Other Things that Fail </a></h3><P CLASS="para">
+If you've made it here, either the problem is solved or it's not one we've seen. The next sections cover troubleshooting tasks that are required to have the infrastructure to run Samba, not Samba itself.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945916">
+9.2.7.1 Not logging on</a></h4><P CLASS="para">An occasional problem is forgetting to log in to the client or logging in as a wrong (account-less) person. The former is not diagnosed at all: Windows tries to be friendly and lets you on. Locally! The only warning of the latter is that Windows welcomes you and asks about your new account. Either of these leads to repeated refusals to connect and endless requests for passwords. If nothing else seems to work, try logging out or shutting down and logging in again.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-23768">
+9.2.8 Troubleshooting Name Services</a></h3><P CLASS="para">This section looks at simple troubleshooting of all the name services that you will encounter, but only for the common problems that affect Samba.</p><P CLASS="para">
+There are several good references for troubleshooting particular name services: Paul Albitz and Cricket Liu's <EM CLASS="emphasis">
+DNS and Bind</em> covers the Domain Name Service (DNS), Hal Stern's <EM CLASS="emphasis">
+NFS and NIS</em> (both from O'Reilly) covers NIS ("Yellow pages") while WINS (Windows Internet Name Service), <I CLASS="filename">
+hosts/LMHOSTS</i> files and NIS+ are best covered by their respective vendor's manuals.</p><P CLASS="para">
+The problems addressed in this section are:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945926">
+</a>Identifying name services</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945927">
+</a>A hostname can't be looked up</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945928">
+</a>The long (FQDN) form of a hostname works but the short form doesn't </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945929">
+</a>The short form of the name works, but the long form doesn't</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945930">
+</a>A long delay ocurrs before the expected result </p></li></ul><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-945931">
+9.2.8.1 Identifying what's in use</a></h4><P CLASS="para">First, see if both the server and the client are using DNS, WINS, NIS, or <I CLASS="filename">
+hosts</i> files to look up IP addresses when you give them a name. Each kind of machine will have a different preference: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945934">
+</a>Windows 95 and 98 machines will look in WINS and <I CLASS="filename">
+LMHOSTS</i> files first, then broadcast, and finally try DNS and <I CLASS="filename">
+hosts</i> files.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945935">
+</a>NT will look in WINS, then broadcast, LMHOSTS files, and finally <I CLASS="filename">
+hosts</i> and DNS.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945936">
+</a>Windows programs using the WINSOCK standard (like PC-NFSs) will use hosts files, DNS, WINS, and then broadcast. Don't assume that if a different program's name service works, the SMB client program's name service will!</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945937">
+</a>Samba daemons will use <I CLASS="filename">
+LMHOSTS</i>, WINS, the Unix host's preference, and then broadcast.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945938">
+</a>Unix hosts can be configured to use any combination of DNS, <I CLASS="filename">
+hosts</i> files, and NIS and NIS+, generally in any order.</p></li></ul><P CLASS="para">
+We recommend that the client machines be configured to use WINS and DNS, the Samba daemons to use WINS and DNS, and the Unix server to use DNS. You'll have to look at your notes and the actual machines to see which is in use.</p><P CLASS="para">
+On the clients, the name services are all set in the TCP/IP Properties panel of the Networking Control Panel, as discussed in <a href="ch03_01.html"><b>Chapter 3</b></a>. You may need to check there to see what you've actually turned on. On the server, see if an <I CLASS="filename">
+/etc/resolv.conf</i> file exists. If it does, you're using DNS. You may be using the others as well, though. You'll need to check for NIS and combinations of services.</p><P CLASS="para">
+Check for an <I CLASS="filename">
+/etc/nsswitch.conf</i> file on Solaris and other System V Unix operating systems. If you have one, look for a line that begins <CODE CLASS="literal">
+host</code>:, followed by one or more of <CODE CLASS="literal">
+files</code>, <CODE CLASS="literal">
+bind</code>, <CODE CLASS="literal">
+nis</code> or <CODE CLASS="literal">
+nis+</code>. These are the name services to use, in order, with optional extra material in square brackets. <EM CLASS="emphasis">
+files</em> stands for using<EM CLASS="emphasis">
+ hosts</em> files, while <EM CLASS="emphasis">
+bind</em> (the Berkeley Internet Name Daemon) stands for using DNS.</p><P CLASS="para">
+If the client and server differ, the first thing to do is to get them in sync. Clients can only use only DNS, WINS, <EM CLASS="emphasis">
+hosts </em>files and <EM CLASS="emphasis">
+lmhosts</em> files, not NIS or NIS+. Servers can use <EM CLASS="emphasis">
+hosts</em> files, DNS, and NIS or NIS+, but not WINS&nbsp;- even if your Samba server provides WINS services. If you can't get all the systems to use the same services, you'll have to carefully check the server and the client for the same data.</p><P CLASS="para">
+Samba 2.0 (and late 1.9 versions) added a <CODE CLASS="literal">
+-R</code><I CLASS="option">
+ </i>(resolve order) option to <EM CLASS="emphasis">
+smbclient</em>. If you want to troubleshoot WINS, for example, you'd say:</p><PRE CLASS="programlisting"> smbclient -L <CODE CLASS="replaceable"><I>server</i></code> -R wins</pre><P CLASS="para">
+The possible settings are <CODE CLASS="literal">
+hosts</code> (which means whatever the Unix machine is using, not just<I CLASS="filename">
+ /etc/hosts</i> files), <CODE CLASS="literal">
+lmhosts</code>, <CODE CLASS="literal">
+wins</code> and <CODE CLASS="literal">
+bcast</code> (broadcast).</p><P CLASS="para">
+In the following sections, we use the term <EM CLASS="emphasis">
+long name</em> for a fully-qualified domain name (FQDN), like <CODE CLASS="literal">
+server.example.com</code>, and the term <EM CLASS="emphasis">
+short name</em> for the host part of a FQDN, like <CODE CLASS="literal">
+server</code>.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-947590">
+9.2.8.2 Cannot look up hostnames</a></h4><P CLASS="para">
+ Try the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945950">
+</a>In DNS:</p><P CLASS="para">
+Run <CODE CLASS="literal">
+nslookup</code> <CODE CLASS="replaceable">
+<I>
+name</i></code>. If this fails, look for a <I CLASS="filename">
+resolv.conf</i> error, a downed DNS server, or a short/long name problem (see the next section). Try the following:</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945952">
+</a>Your <I CLASS="filename">
+/etc/resolv.conf</i> should contain one or more name-server lines, each with an IP address. These are the addresses of your DNS servers.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947597">
+</a>ping each of the server addresses you find. If this fails for one, suspect the machine. If it fails for each, suspect your network.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947600">
+</a>Retry the lookup using the full domain name (e.g., <EM CLASS="emphasis">
+server.example.com</em>) if you tried the short name first, or the short name if you tried the long name first. If results differ, skip to the next section. </p></li></ul><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945958">
+</a>In Broadcast/ WINS:</p><P CLASS="para">
+Broadcast/ WINS does only short names such as <CODE CLASS="literal">
+server</code>, (not long ones, such as <CODE CLASS="literal">
+server.example.com)</code>. Run <CODE CLASS="literal">
+nmblookup</code> <CODE CLASS="literal">
+-S</code> <CODE CLASS="replaceable">
+<I>
+server</i></code>.<CODE CLASS="replaceable">
+<I>
+ </i></code>This reports everything broadcast has registered for the name. In our example, it looks like this:</p></li></ul><PRE CLASS="programlisting">
+Looking up status of 192.168.236.86
+received 10 names
+ SERVER &lt;00&gt; - M &lt;ACTIVE&gt;
+ SERVER &lt;03&gt; - M &lt;ACTIVE&gt;
+ SERVER &lt;1f&gt; - M &lt;ACTIVE&gt;
+ SERVER &lt;20&gt; - M &lt;ACTIVE&gt;
+ ..__MSBROWSE__. &lt;01&gt; - &lt;GROUP&gt; M &lt;ACTIVE&gt;
+ MYGROUP &lt;00&gt; - &lt;GROUP&gt; M &lt;ACTIVE&gt;
+ MYGROUP &lt;1b&gt; - M &lt;ACTIVE&gt;
+ MYGROUP &lt;1c&gt; - &lt;GROUP&gt; M &lt;ACTIVE&gt;
+ MYGROUP &lt;1d&gt; - M &lt;ACTIVE&gt;
+ MYGROUP &lt;1e&gt; - &lt;GROUP&gt; M &lt;ACTIVE&gt;</pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+The required entry is <CODE CLASS="literal">
+SERVER</code> <CODE CLASS="literal">
+&lt;00&gt;</code>, which identifies <CODE CLASS="replaceable">
+<I>
+server</i></code> as being this machine's NetBIOS name. You should also see your workgroup mentioned one or more times. If these lines are missing, Broadcast/WINS cannot look up names and will need attention.</p></li></ul><P CLASS="para">
+The numbers in angle brackets in the previous output identify NetBIOS names as being workgroups, workstations, and file users of the messenger service, master browsers, domain master browsers, domain controllers and a plethora of others. We primarily use <CODE CLASS="literal">
+&lt;00&gt;</code> to identify machine and workgroup names and <CODE CLASS="literal">
+&lt;20&gt;</code> to identify machines as servers. The complete list is available at <A CLASS="systemitem.url" HREF="http://support.microsoft.com/support/kb/articles/q163/4/09.asp">
+http://support.microsoft.com/support/kb/articles/q163/4/09.asp</a>.</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945982">
+</a>In NIS:</p><P CLASS="para">
+Try <CODE CLASS="literal">
+ypmatch</code> <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+hosts</code>. If this fails, NIS is down. Find out the NIS server's name by running<EM CLASS="emphasis">
+ ypwhich</em>, and ping the machine it to see if it's accessible.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945985">
+</a>In NIS+:</p><P CLASS="para">
+If you're running NIS+, try <CODE CLASS="literal">
+nismatch</code> <CODE CLASS="literal">
+name</code> <CODE CLASS="literal">
+hosts</code>. If this fails, NIS is down. Find out the NIS server's name by running <EM CLASS="emphasis">
+niswhich</em>, and ping that machine to see if it's accessible.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-945988">
+</a>In <I CLASS="filename">
+hosts</i> files:</p><P CLASS="para">
+Inspect <I CLASS="filename">
+/etc/hosts</i> on the client (<CODE CLASS="literal">C:\WINDOWS\HOSTS</code>). Each line should have an IP number and one or more names, the primary name first, then any optional aliases. An example follows:</p></li></ul><PRE CLASS="programlisting">
+ 127.0.0.1 localhost
+ 192.168.236.1 dns.svc.example.com
+ 192.168.236.10 client.example.com client
+ 192.168.236.11 backup.example.com loghost
+ 192.168.236.86 server.example.com server
+ 192.168.236.254 router.svc.example.com </pre><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+On Unix, <CODE CLASS="literal">
+localhost</code> should always be 127.0.0.1, although it may be just an alias for a hostname on the PC. On the client, check that there are no <CODE CLASS="literal">
+#XXX</code> directives at the ends of the lines; these are LAN Manager/NetBIOS directives, and should appear only in <EM CLASS="emphasis">
+LMHOSTS</em> files (<CODE CLASS="literal">C:\WINDOWS\LMHOSTS</code>). </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946000">
+</a>In <EM CLASS="emphasis">
+LMHOSTS</em> files:</p><P CLASS="para">
+This file is a local source for LAN Manager (NetBIOS) names. It has a format very similar to <I CLASS="filename">
+/etc/hosts</i> files, but does not support long-form domain names (e.g., <CODE CLASS="literal">
+server.example.com</code>), and may have a number of optional <CODE CLASS="literal">
+#XXX</code> directives following the names. Note there usually is a <EM CLASS="emphasis">
+lmhosts.sam</em> (for sample) file in <CODE CLASS="literal">
+C:\WINDOWS</code>, but it's not used unless renamed to <CODE CLASS="literal">
+C:\WINDOWS\LMHOSTS</code>.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946005">
+9.2.8.3 Long and short hostnames</a></h4><P CLASS="para">Where the long (FQDN) form of a hostname works but the short name doesn't (for example, <CODE CLASS="literal">
+client.example.com</code> works but <CODE CLASS="literal">
+client</code> doesn't), consider the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946007">
+</a>DNS: </p><P CLASS="para">
+This usually indicates there is no default domain in which to look up the short names. Look for a <CODE CLASS="literal">
+default</code> line in <I CLASS="filename">
+/etc/resolv.conf</i> on the Samba server with your domain in it, or a <CODE CLASS="literal">
+search</code> line with one or more domains in it. One or the other may need to be present to make short names usable; which one depends on vendor and version of the DNS resolver. Try adding <CODE CLASS="literal">
+domain</code> <CODE CLASS="replaceable">
+<I>
+your domain</i></code> to <I CLASS="filename">
+resolv.conf</i> and ask your network or DNS administrator what should have been in the file.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946010">
+</a>Broadcast/WINS: </p><P CLASS="para">
+Broadcast/WINS doesn't support long names; it won't suffer from this problem. </p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946012">
+</a>NIS: </p><P CLASS="para">
+Try the command <CODE CLASS="literal">
+ypmatch</code> <CODE CLASS="literal">
+hostname</code> <CODE CLASS="literal">
+hosts</code>. If you don't get a match, your tables don't include short names. Speak to your network manager; short names may be missing by accident, or may be unsupported as a matter of policy. Some sites don't ever use (ambiguous) short names.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946014">
+</a>NIS+ :</p><P CLASS="para">
+Try <CODE CLASS="literal">
+nismatch</code> <CODE CLASS="replaceable">
+<I>
+hostname</i></code> <CODE CLASS="literal">
+hosts</code>, and treat failure exactly as with NIS above.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946016">
+</a><EM CLASS="emphasis">
+hosts:</em> </p><P CLASS="para">
+If the short name is not in <I CLASS="filename">
+/etc/hosts</i>, consider adding it as an alias. Avoid, if you can, short names as primary names (the first one on a line). Have them as aliases if your system permits.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946018">
+</a><I CLASS="filename">
+LMHOSTS</i>: </p><P CLASS="para">
+LAN Manager doesn't support long names, so it won't suffer from this problem. </p></li></ul><P CLASS="para">
+On the other hand, if the short form of the name works and the long doesn't, consider the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946022">
+</a>DNS: </p><P CLASS="para">
+This is bizarre; see your network or DNS administrator, as this is probably a DNS setup bug.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947697">
+</a>Broadcast/WINS: </p><P CLASS="para">
+This is a normal bug; Broadcast/WINS can't use the long form. Optionally, consider DNS. Microsoft has stated that they will switch to DNS, though it's not providing name types like &lt;00&gt;.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947709">
+</a>NIS:</p><P CLASS="para">
+If you can use <CODE CLASS="literal">
+ypmatch</code> to look up the short form but not the long, consider adding the long form to the table as at least an alias.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947718">
+</a>NIS+: </p><P CLASS="para">
+Same as NIS, except you use <CODE CLASS="literal">
+nismatch</code> instead of <CODE CLASS="literal">
+ypmatch</code> to look up names.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947720">
+</a><I CLASS="filename">
+hosts:</i></p><P CLASS="para">
+Add the long name as at least an alias, and preferably as the primary form. Also consider using DNS if it's practical.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947727">
+</a><I CLASS="filename">
+LMHOSTS</i>: </p><P CLASS="para">
+This is a normal bug. LAN Manager can't use the long form; consider switching to DNS or <I CLASS="filename">
+hosts</i>.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946040">
+9.2.8.4 Unusual delays</a></h4><P CLASS="para">When there is a long delay before the expected result: </p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-947733">
+</a>DNS: </p><P CLASS="para">
+Test the same name with the <KBD CLASS="command">
+nslookup</kbd> command on the machine (client or server) that is slow. If <KBD CLASS="command">
+nslookup</kbd> is also slow, you have a DNS problem. If it's slower on a client, you have too many protocols bound to the Ethernet card. Eliminate NetBEUI, which is infamously slow, and optionally, Novel, assuming you don't need them. This is especially important on Windows 95, which is particularly sensitive to excess protocols.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946044">
+</a>Broadcast/ WINS:</p><P CLASS="para">
+Test the client using <CODE CLASS="literal">
+nmblookup</code>, and if it's faster, you probably have the protocols problem as mentioned in the previous item.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946047">
+</a>NIS:</p><P CLASS="para">
+Try <CODE CLASS="literal">
+ypmatch</code>, and if it's slow, report the problem to your network manager.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946049">
+</a>NIS+: </p><P CLASS="para">
+Try <CODE CLASS="literal">
+nismatch</code>, similarly.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946051">
+</a><EM CLASS="emphasis">
+hosts</em>:</p><P CLASS="para">
+<EM CLASS="emphasis">
+hosts</em> files, if of reasonable size, are always fast. You probably have the protocols problem mentioned under DNS, above.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946053">
+</a><EM CLASS="emphasis">
+LMHOSTS</em>:</p><P CLASS="para">
+This is not a name lookup problem; <EM CLASS="emphasis">
+LMHOSTS</em> files are as fast as <EM CLASS="emphasis">
+hosts</em> files.</p></li></ul></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946055">
+9.2.8.5 Localhost issues</a></h4><P CLASS="para">When a localhost isn't 127.0.0.1, try the following:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946056">
+</a>DNS:</p><P CLASS="para">
+There is probably no record for <CODE CLASS="literal">
+localhost.</code> <CODE CLASS="literal">
+A</code> <CODE CLASS="literal">
+127.0.0.1</code>. Arrange to add one, and a reverse entry, <CODE CLASS="literal">
+1.0.0.127.IN-ADDR.ARPA</code> <CODE CLASS="literal">
+PTR</code> <CODE CLASS="literal">
+127.0.0.1</code>.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946058">
+</a>Broadcast/WINS:</p><P CLASS="para">
+Not applicable.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946060">
+</a>NIS:</p><P CLASS="para">
+If <CODE CLASS="literal">
+localhost</code> isn't in the table, add it.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946062">
+</a>NIS+: </p><P CLASS="para">
+If <CODE CLASS="literal">
+localhost</code> isn't in the table, add it.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946064">
+</a><I CLASS="filename">
+hosts:</i></p><P CLASS="para">
+Add a line is the <EM CLASS="emphasis">
+hosts</em> file that says <CODE CLASS="literal">
+127.0.0.1</code> <CODE CLASS="literal">
+localhost</code></p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946066">
+</a><I CLASS="filename">
+LMHOSTS</i>:</p><P CLASS="para">
+Not applicable.</p></li></ul></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-953970">9.2.9 Troubleshooting Network Addresses</a></h3><P CLASS="para">
+A number of common problems are caused by incorrect Internet address routing or the incorrect assignment of addresses. This section helps you determine what your addresses are.</p><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-21203">
+9.2.9.1 Netmasks</a></h4><P CLASS="para">The netmasks tell each machine which addresses can be reached directly (are on your local network) and which addresses require forwarding packets through a router. If the netmask is wrong, the machines will make one of two mistakes. One is to try to route local packets via a router, which is an expensive way to waste time&nbsp;- it may work reasonably fast, it may run slowly, or it may fail utterly. The second mistake is to fail to send packets for a remote machine to the router, which will prevent them from being forwarded to the remote machine.</p><P CLASS="para">
+The netmask is a number like an IP address, with one-bits for the network part of an address and zero-bits for the host portion. The netmask is literally used to mask off parts of the address inside the TCP/IP code. If the mask is 255.255.0.0, the first 2 bytes are the network part and the last 2 are the host part. More common is 255.255.255.0, in which the first 3 bytes are the network part and the last one is the host part.</p><P CLASS="para">
+For example, let's say your IP address is 192.168.0.10 and the Samba server is 192.168.236.86. If your netmask happens to be 255.255.255.0, the network part of the addresses is the first 3 bytes and the host part is the last byte. In this case, the network parts are different, and the machines are on different networks: </p><TABLE CLASS="informaltable" BORDER="1" CELLPADDING="3">
+<THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Part</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Host Part</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168 000</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+10</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168 235</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+86</p></td></tr></tbody></table><P CLASS="para">
+If your netmask happens to be 255.255.0.0, the network part is just the first two bytes. In this case, the network parts match and so the two machines are on the same network: </p><TABLE CLASS="informaltable" BORDER="1" CELLPADDING="3">
+<THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Part</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Host Part</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+000 10</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+236 86</p></td></tr></tbody></table><P CLASS="para">
+Of course, if your netmask says one thing and your network manager says another, the netmask is wrong.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-45060">
+9.2.9.2 Broadcast addresses</a></h4><P CLASS="para">
+The broadcast address is a normal address, with the hosts part all one-bits. It means "all hosts on your network." You can compute it easily from your netmask and address: take the address and put one-bits in it for all the bits that are zero at the end of the netmask (the host part). The following table illustrates this: </p><TABLE CLASS="informaltable" BORDER="1" CELLPADDING="3">
+<THEAD CLASS="thead">
+<TR CLASS="row" VALIGN="TOP">
+<TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Network Part</p></th><TH CLASS="entry" ALIGN="LEFT" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+Host Part</p></th></tr></thead><TBODY CLASS="tbody">
+<TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+IP address</b></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168 236</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+86</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+Netmask</b></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+255 255 255</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+000</p></td></tr><TR CLASS="row" VALIGN="TOP">
+<TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+<B CLASS="emphasis.bold">
+Broadcast</b></p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+192 168 236</p></td><TD CLASS="entry" ROWSPAN="1" COLSPAN="1">
+<P CLASS="para">
+255</p></td></tr></tbody></table><P CLASS="para">
+In this example, the broadcast address on the 192.168.236 network is 192.168.236.255. There is also an old "universal" broadcast address, 255.255.255.255. Routers are prohibited from forwarding these, but most machines on your local network will respond to broadcasts to this address.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-946136">
+9.2.9.3 Network address ranges</a></h4><P CLASS="para">A number of address ranges have been reserved for testing and for non-connected networks; we use one of these for the book. If you don't have an address yet, feel free to use one of these to start with. They include one class A (large) network, 10.*.*.*, and 254 class C (smaller) networks, 192.168.1.* through to 192.168.254.*. In this book we use one of the latter, 192.168.236.*. The domain <I CLASS="filename">
+example.com</i> is also reserved for unconnected networks, explanatory examples, and books.</p><P CLASS="para">
+If you're actually connecting to the Internet, you'll need to get a real network and a domain name, probably through the same company that provides your connection.</p></div><DIV CLASS="sect3">
+<H4 CLASS="sect3">
+<A CLASS="title" NAME="ch09-pgfId-947786">
+9.2.9.4 Finding your network address</a></h4><P CLASS="para">If you haven't recorded your IP address, it will be displayed by the <KBD CLASS="command">
+ifconfig</kbd> command on Unix or by the IPCONFIG command on Windows 95 and NT. (Check your manual pages for any options required by your brand of Unix: Sun wants <CODE CLASS="literal">
+ifconfig</code> <CODE CLASS="literal">
+-a</code>). You should see output similar to the following:</p><PRE CLASS="programlisting">
+server% ifconfig -a
+le0: flags=63&lt;UP,BROADCAST,NOTRAILERS,RUNNING &gt;
+ inet 192.168.236.11 netmask ffffff00 broadcast 192.168.236.255
+lo0: flags=49&lt;&amp;lt&gt;UP,LOOPBACK,RUNNING&lt;&amp;gt&gt;
+ inet 127.0.0.1 netmask ff000000</pre><P CLASS="para">
+One of the interfaces will be loopback (in our examples <CODE CLASS="literal">
+lo0</code>), and the other will be the regular IP interface. The flags should show that the interface is running, and Ethernet interfaces will also say they support broadcasts (PPP interfaces don't). The other places to look for IP addresses are <I CLASS="filename">
+/etc/hosts</i> files, Windows <EM CLASS="emphasis">
+HOSTS</em> files, Windows <EM CLASS="emphasis">
+LMHOSTS</em> files, NIS, NIS+ and DNS.</p></div></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-35552">9.2.10 Troubleshooting NetBIOS Names</a></h3><P CLASS="para">Historically, SMB protocols have depended on the NetBIOS name system, also called the LAN Manager name system. This was a simple scheme where each machine had a unique 20-character name and broadcast it on the LAN for everyone to know. With TCP/IP, we tend to use names like <EM CLASS="emphasis">
+client.example.com</em> stored in <I CLASS="filename">
+/etc/hosts</i> files, through DNS or WINS.</p><P CLASS="para">
+The usual mapping to domain names such as <EM CLASS="emphasis">
+server.example.com</em> simply uses the <EM CLASS="emphasis">
+server</em> part as the NetBIOS name and converts it to uppercase. Alas, this doesn't always work, especially if you have a machine with a 21-character name; not everyone uses the same NetBIOS and DNS names. For example, <EM CLASS="emphasis">
+corpvm1</em> along with <EM CLASS="emphasis">
+vm1.corp.com</em> is not unusual.</p><P CLASS="para">
+A machine with a different NetBIOS name and domain name is confusing when you're troubleshooting; we recommend that you try to avoid this wherever possible. NetBIOS names are discoverable with <EM CLASS="emphasis">
+smbclient </em>:</p><UL CLASS="itemizedlist">
+<LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946160">
+</a>If you can list shares on your Samba server with <EM CLASS="emphasis">
+smbclient</em> and a <CODE CLASS="literal">
+-L</code> option (list shares) of <CODE CLASS="replaceable">
+<I>
+short_name_of_server</i></code>, the short name is the NetBIOS name.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946161">
+</a>If you get "Get_Hostbyname: Unknown host name," there is probably a mismatch. Check in the <I CLASS="filename">
+smb.conf</i> file to see if the NetBIOS name is explicitly set.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946162">
+</a>Try again, specifying <CODE CLASS="literal">
+-I</code> and the IP address of the Samba server (e.g., <CODE CLASS="literal">
+smbclient</code> <CODE CLASS="literal">
+-L</code> <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+-I</code> <CODE CLASS="literal">
+192.168.236.86</code>). This overrides the name lookup and forces the packets to go to the IP address. If this works, there was a mismatch.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946163">
+</a>Try with <CODE CLASS="literal">
+-I</code> and the full domain name of the server (e.g., <CODE CLASS="literal">
+smbclient</code> <CODE CLASS="literal">
+-L</code> <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+-I</code> <CODE CLASS="literal">
+server.example.com</code>). This tests the lookup of the domain name, using whatever scheme the Samba server uses (e.g., DNS). If it fails, you have a name service problem. You should reread the section <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8</a> after you finish troubleshooting the NetBIOS names.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946168">
+</a>Try with <CODE CLASS="literal">
+-n</code> (NetBIOS name) and the name you expect to work (e.g., <CODE CLASS="literal">
+smbclient</code> <CODE CLASS="literal">
+-n</code> <CODE CLASS="literal">
+server</code> <CODE CLASS="literal">
+-L</code> <CODE CLASS="literal">
+server-12</code>) but without overriding the IP address through <CODE CLASS="literal">
+-I</code>. If this works, the name you specified with <CODE CLASS="literal">
+-n</code> is the actual NetBIOS name of the server. If you receive "Get-Hostbyname: Unknown host MARY," it's not the right server yet.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-946169">
+</a>If nothing is working so far, repeat the tests specifying <CODE CLASS="literal">
+-U</code> <CODE CLASS="replaceable">
+<I>
+username</i></code> and <CODE CLASS="literal">
+-W</code> <CODE CLASS="replaceable">
+<I>
+workgroup</i></code>, with the username and workgroup in uppercase, to make sure you're not being derailed by a user or workgroup mismatch.</p></li><LI CLASS="listitem">
+<P CLASS="para">
+<A CLASS="listitem" NAME="ch09-pgfId-953522">
+</a>If nothing works still and you had evidence of a name service problem, troubleshoot name service in the section <A CLASS="xref" HREF="ch09_02.html#ch09-23768">
+Section 9.2.8</a>, and then return to NetBIOS name service.</p></li></ul></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_01.html" TITLE="9.1 The Tool Bag">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.1 The Tool Bag" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_03.html" TITLE="9.3 Extra Resources">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: 9.3 Extra Resources" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">9.1 The Tool Bag</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+9.3 Extra Resources</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/ch09_03.html b/docs/htmldocs/using_samba/ch09_03.html
new file mode 100755
index 00000000000..ecaa53ed364
--- /dev/null
+++ b/docs/htmldocs/using_samba/ch09_03.html
@@ -0,0 +1,136 @@
+<HTML>
+<HEAD>
+<TITLE>
+[Chapter 9] 9.3 Extra Resources</title><META NAME="DC.title" CONTENT=""><META NAME="DC.creator" CONTENT=""><META NAME="DC.publisher" CONTENT="O'Reilly &amp; Associates, Inc."><META NAME="DC.date" CONTENT="1999-11-05T21:41:27Z"><META NAME="DC.type" CONTENT="Text.Monograph"><META NAME="DC.format" CONTENT="text/html" SCHEME="MIME"><META NAME="DC.source" CONTENT="" SCHEME="ISBN"><META NAME="DC.language" CONTENT="en-US"><META NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"></head>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly
+<br>1st Edition November 1999
+<br>1-56592-449-5, Order Number: 4495
+<br>416 pages, $34.95
+</font>
+<p> <a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy</a>
+<p><a href="index.html">Table of Contents</a>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<center>
+<DIV CLASS="htmlnav">
+<TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_02.html" TITLE="9.2 The Fault Tree">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.2 The Fault Tree" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<B>
+<FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">
+<A CLASS="chapter" REL="up" HREF="ch09_01.html" TITLE="9. Troubleshooting Samba">
+Chapter 9<br>
+Troubleshooting Samba</a></font></b></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A. Configuring Samba with SSL" BORDER="0"></a></td></tr></table>&nbsp;<hr noshade size=1></center>
+</div>
+<blockquote>
+<div>
+<H2 CLASS="sect1">
+<A CLASS="title" NAME="ch09-49719">
+9.3 Extra Resources</a></h2><P CLASS="para">At some point during your Samba career, you will want to turn to online or printed resources for news, updates, and aid.</p><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-953071">
+9.3.1 Documentation and FAQs</a></h3><P CLASS="para">It's okay to read the documentation. Really. Nobody can see you, and we won't tell. In fact, Samba ships with a large set of documentation files, and it is well worth the effort to at least browse through them, either in the distribution directory on your computer under <I CLASS="filename">
+/docs</i>, or online at the Samba web site: <a href="http://samba.anu.edu.au/samba/"><I CLASS="filename">http://samba.anu.edu.au/samba/</i></a>. The most current FAQ list, bug information, and distribution locations are located at the web site, with links to all of the Samba manual pages and HOW-TOs.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-946178">
+9.3.2 Samba Newsgroups</a></h3><P CLASS="para">Usenet newsgroups have always been a great place to get advice on just about any topic. In the past few years, though, this vast pool of knowledge has developed something that has made it into an invaluable resource: a memory. Archival and search sites such as DejaNews (<I CLASS="filename"><a href="http://www.dejanews.com">http://www.dejanews.com</i></a>) have made sifting through years of valuable solutions on a topic as simple as a few mouse clicks. </p><P CLASS="para">
+The primary newsgroup for Samba is <EM CLASS="emphasis">
+comp.protocols.smb</em>. This should always be your first stop when there's a problem. More often than not, spending five minutes researching an error here will save hours of frustration while trying to debug something yourself.</p><P CLASS="para">
+When searching a newsgroup, try to be as specific as possible, but not too wordy. Searching on actual error messages is best. If you don't find an answer immediately in the newsgroup, resist the temptation to post a request for help until you've done a bit more work on the problem. You may find that the answer is in a FAQ or one of the many documentation files that ships with Samba, or a solution might become evident when you run one of Samba's diagnostic tools. If nothing works, post a request in <EM CLASS="emphasis">
+comp.protocols.smb</em>, and be as specific as possible about what you have tried and what you are seeing. Include any error messages that appear. It may be several days before you receive help, so be patient and keep trying things while you wait.</p><P CLASS="para">
+Once you post a request for help, keep poking at the problem yourself. Most of us have had the experience of posting a Usenet article containing hundreds of lines of intricate detail, only to solve the problem an hour later after the article has blazed its way across several continents. The rule of thumb goes something like this: the more folks who have read your request, the simpler the solution. Usually this means that once everyone in the Unix community has seen your article, the solution will be something simple like, "Plug the computer into the wall socket."</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-951527">
+9.3.3 Samba Mailing Lists</a></h3><P CLASS="para">The following are mailing lists for support with Samba. See the Samba homepage, <a href="http://www.samba.org/"><I CLASS="filename">http://www.samba.org/</i></a> for information on subscribing and unsubscribing to these mailing lists:</p><DL CLASS="variablelist">
+<DT CLASS="term">
+samba-binaries@samba.org</dt><DD CLASS="listitem">
+<P CLASS="para">
+This mailing list has information on precompiled binaries for the Samba platform.</p></dd><DT CLASS="term">
+samba@samba.org</dt><DD CLASS="listitem">
+<P CLASS="para">
+This mailing list is the place to report suspected bugs in Samba.</p></dd><DT CLASS="term">
+samba-ntdom@samba.org</dt><DD CLASS="listitem">
+<P CLASS="para">
+This mailing list has information on support for domains (particularly Windows NT) with the Samba product.</p></dd><DT CLASS="term">
+samba-technical@samba.org</dt><DD CLASS="listitem">
+<P CLASS="para">
+This mailing list maintains debate about where the future of Samba is headed.</p></dd><DT CLASS="term">
+samba@samba.org</dt><DD CLASS="listitem">
+<P CLASS="para">
+This is the primary Samba mailing list that contains general questions and HOW-TO information on Samba.</p></dd></dl></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-946184">
+9.3.4 Samba Discussion Archives</a></h3><P CLASS="para">There is a search service for the primary Samba mailing list. At the time this book was written, it was listed under "searchable" in the Sources paragraph on the first page of the Samba site and its mirrors, <a href="http://samba.anu.edu.au/listproc/ghindex.html"><I CLASS="filename">http://samba.anu.edu.au/listproc/ghindex.html</i></a>.</p></div><DIV CLASS="sect2">
+<H3 CLASS="sect2">
+<A CLASS="title" NAME="ch09-pgfId-946188">
+9.3.5 Further Reading</a></h3><OL CLASS="orderedlist">
+<LI CLASS="listitem">
+<P CLASS="para">Craig Hunt; <EM CLASS="emphasis">
+TCP/IP Network Administration, 2nd Edition</em>. Sebastopol, CA: O'Reilly and Associates, 1997 (ISBN 1-56592-322-7).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+Hunt, Craig, and Robert Bruce Thompson; <EM CLASS="emphasis">
+Windows NT TCP/IP Network Administration. </em>Sebastopol, CA: O'Reilly and Associates, 1998 (<EM CLASS="emphasis">
+ISBN </em>1-56592-377-4).</p></li><LI CLASS="listitem">
+<P CLASS="para">Albitz, Paul, and Cricket Liu; <EM CLASS="emphasis">
+DNS and Bind, 3rd Edition</em>. Sebastopol, CA: O'Reilly &amp; Associates, 1998 (ISBN 1-56592-512-2).</p></li><LI CLASS="listitem">
+<P CLASS="para">
+Stern, Hal; <EM CLASS="emphasis">
+Managing </em><EM CLASS="emphasis">NFS and NIS</em>. Sebastopol, CA: O'Reilly &amp; Associates, 1991 (ISBN 0-937175-75-7).</p></li></ol></div></div></blockquote>
+<div>
+<center>
+<hr noshade size=1><TABLE WIDTH="515" BORDER="0" CELLSPACING="0" CELLPADDING="0">
+<TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">
+<A CLASS="sect1" HREF="ch09_02.html" TITLE="9.2 The Fault Tree">
+<IMG SRC="gifs/txtpreva.gif" ALT="Previous: 9.2 The Fault Tree" BORDER="0"></a></td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="book" HREF="index.html" TITLE="">
+<IMG SRC="gifs/txthome.gif" ALT="" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+<A CLASS="appendix" HREF="appa_01.html" TITLE="A. Configuring Samba with SSL">
+<IMG SRC="gifs/txtnexta.gif" ALT="Next: A. Configuring Samba with SSL" BORDER="0"></a></td></tr><TR>
+<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="172">9.2 The Fault Tree</td><TD ALIGN="CENTER" VALIGN="TOP" WIDTH="171">
+<A CLASS="index" HREF="inx.html" TITLE="Book Index">
+<IMG SRC="gifs/index.gif" ALT="Book Index" BORDER="0"></a></td><TD ALIGN="RIGHT" VALIGN="TOP" WIDTH="172">
+A. Configuring Samba with SSL</td></tr></table><hr noshade size=1></center>
+</div>
+
+<!-- End of sample chapter -->
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/figs/sam.0101.gif b/docs/htmldocs/using_samba/figs/sam.0101.gif
new file mode 100755
index 00000000000..ce022dd3220
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0101.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0102.gif b/docs/htmldocs/using_samba/figs/sam.0102.gif
new file mode 100755
index 00000000000..2c26743160e
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0102.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0103.gif b/docs/htmldocs/using_samba/figs/sam.0103.gif
new file mode 100755
index 00000000000..480b51bdb24
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0103.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0104.gif b/docs/htmldocs/using_samba/figs/sam.0104.gif
new file mode 100755
index 00000000000..a580bfd9da5
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0104.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0105.gif b/docs/htmldocs/using_samba/figs/sam.0105.gif
new file mode 100755
index 00000000000..45782f6a54d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0105.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0106.gif b/docs/htmldocs/using_samba/figs/sam.0106.gif
new file mode 100755
index 00000000000..7e43f6a8295
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0106.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0107.gif b/docs/htmldocs/using_samba/figs/sam.0107.gif
new file mode 100755
index 00000000000..60f24ce060d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0107.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0108.gif b/docs/htmldocs/using_samba/figs/sam.0108.gif
new file mode 100755
index 00000000000..93b036c7366
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0108.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0109.gif b/docs/htmldocs/using_samba/figs/sam.0109.gif
new file mode 100755
index 00000000000..ec01228ef7c
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0109.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0110.gif b/docs/htmldocs/using_samba/figs/sam.0110.gif
new file mode 100755
index 00000000000..9695cf7c61b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0110.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0111.gif b/docs/htmldocs/using_samba/figs/sam.0111.gif
new file mode 100755
index 00000000000..4dbc2dba41b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0111.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0112.gif b/docs/htmldocs/using_samba/figs/sam.0112.gif
new file mode 100755
index 00000000000..4f559e0d0f0
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0112.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0113.gif b/docs/htmldocs/using_samba/figs/sam.0113.gif
new file mode 100755
index 00000000000..5d8cdaef6b5
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0113.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0114.gif b/docs/htmldocs/using_samba/figs/sam.0114.gif
new file mode 100755
index 00000000000..291e6f0c824
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0114.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0201.gif b/docs/htmldocs/using_samba/figs/sam.0201.gif
new file mode 100755
index 00000000000..e6f97f63015
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0201.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0202.gif b/docs/htmldocs/using_samba/figs/sam.0202.gif
new file mode 100755
index 00000000000..0490c085717
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0202.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0203.gif b/docs/htmldocs/using_samba/figs/sam.0203.gif
new file mode 100755
index 00000000000..a24c4818600
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0203.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0204.gif b/docs/htmldocs/using_samba/figs/sam.0204.gif
new file mode 100755
index 00000000000..e446b1d4f11
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0204.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0301.gif b/docs/htmldocs/using_samba/figs/sam.0301.gif
new file mode 100755
index 00000000000..82306d6cc9b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0301.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0302.gif b/docs/htmldocs/using_samba/figs/sam.0302.gif
new file mode 100755
index 00000000000..0916db72aea
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0302.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0303.gif b/docs/htmldocs/using_samba/figs/sam.0303.gif
new file mode 100755
index 00000000000..18d63dbbb73
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0303.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0304.gif b/docs/htmldocs/using_samba/figs/sam.0304.gif
new file mode 100755
index 00000000000..a0c5eee0992
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0304.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0305.gif b/docs/htmldocs/using_samba/figs/sam.0305.gif
new file mode 100755
index 00000000000..43be04655ab
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0305.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0306.gif b/docs/htmldocs/using_samba/figs/sam.0306.gif
new file mode 100755
index 00000000000..be7609d9439
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0306.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0307.gif b/docs/htmldocs/using_samba/figs/sam.0307.gif
new file mode 100755
index 00000000000..258d3390bc1
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0307.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0308.gif b/docs/htmldocs/using_samba/figs/sam.0308.gif
new file mode 100755
index 00000000000..316643ccfbe
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0308.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0309.gif b/docs/htmldocs/using_samba/figs/sam.0309.gif
new file mode 100755
index 00000000000..4a9d5d762b2
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0309.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0310.gif b/docs/htmldocs/using_samba/figs/sam.0310.gif
new file mode 100755
index 00000000000..37262b91be0
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0310.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0311.gif b/docs/htmldocs/using_samba/figs/sam.0311.gif
new file mode 100755
index 00000000000..c25e96f936f
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0311.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0312.gif b/docs/htmldocs/using_samba/figs/sam.0312.gif
new file mode 100755
index 00000000000..8823f38eb1a
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0312.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0313.gif b/docs/htmldocs/using_samba/figs/sam.0313.gif
new file mode 100755
index 00000000000..981a6849887
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0313.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0314.gif b/docs/htmldocs/using_samba/figs/sam.0314.gif
new file mode 100755
index 00000000000..9a7ed5858e2
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0314.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0315.gif b/docs/htmldocs/using_samba/figs/sam.0315.gif
new file mode 100755
index 00000000000..ed4bcc42209
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0315.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0316.gif b/docs/htmldocs/using_samba/figs/sam.0316.gif
new file mode 100755
index 00000000000..99908ac7d3b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0316.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0317.gif b/docs/htmldocs/using_samba/figs/sam.0317.gif
new file mode 100755
index 00000000000..14899010064
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0317.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0318.gif b/docs/htmldocs/using_samba/figs/sam.0318.gif
new file mode 100755
index 00000000000..263650a2749
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0318.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0319.gif b/docs/htmldocs/using_samba/figs/sam.0319.gif
new file mode 100755
index 00000000000..0d1c934a564
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0319.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0320.gif b/docs/htmldocs/using_samba/figs/sam.0320.gif
new file mode 100755
index 00000000000..061ce27cb10
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0320.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0321.gif b/docs/htmldocs/using_samba/figs/sam.0321.gif
new file mode 100755
index 00000000000..f40fbbedcad
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0321.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0322.gif b/docs/htmldocs/using_samba/figs/sam.0322.gif
new file mode 100755
index 00000000000..f421311dfc2
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0322.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0323.gif b/docs/htmldocs/using_samba/figs/sam.0323.gif
new file mode 100755
index 00000000000..578ffda5524
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0323.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0324.gif b/docs/htmldocs/using_samba/figs/sam.0324.gif
new file mode 100755
index 00000000000..4ab9ceb598f
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0324.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0325.gif b/docs/htmldocs/using_samba/figs/sam.0325.gif
new file mode 100755
index 00000000000..f6da1e74347
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0325.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0326.gif b/docs/htmldocs/using_samba/figs/sam.0326.gif
new file mode 100755
index 00000000000..df6313794d0
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0326.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0327.gif b/docs/htmldocs/using_samba/figs/sam.0327.gif
new file mode 100755
index 00000000000..1e774392154
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0327.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0328.gif b/docs/htmldocs/using_samba/figs/sam.0328.gif
new file mode 100755
index 00000000000..7baa0ef4e6d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0328.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0401.gif b/docs/htmldocs/using_samba/figs/sam.0401.gif
new file mode 100755
index 00000000000..a62d0d5675d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0401.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0402.gif b/docs/htmldocs/using_samba/figs/sam.0402.gif
new file mode 100755
index 00000000000..ecf03ca8c8a
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0402.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0403.gif b/docs/htmldocs/using_samba/figs/sam.0403.gif
new file mode 100755
index 00000000000..755522854a4
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0403.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0404.gif b/docs/htmldocs/using_samba/figs/sam.0404.gif
new file mode 100755
index 00000000000..0d28182e521
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0404.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0405.gif b/docs/htmldocs/using_samba/figs/sam.0405.gif
new file mode 100755
index 00000000000..c7cc9d681b1
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0405.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0406.gif b/docs/htmldocs/using_samba/figs/sam.0406.gif
new file mode 100755
index 00000000000..a4f82804aa0
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0406.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0407.gif b/docs/htmldocs/using_samba/figs/sam.0407.gif
new file mode 100755
index 00000000000..84ca4e87c75
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0407.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0501.gif b/docs/htmldocs/using_samba/figs/sam.0501.gif
new file mode 100755
index 00000000000..dac53c673a1
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0501.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0502.gif b/docs/htmldocs/using_samba/figs/sam.0502.gif
new file mode 100755
index 00000000000..46e282ce31b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0502.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0503.gif b/docs/htmldocs/using_samba/figs/sam.0503.gif
new file mode 100755
index 00000000000..786de36e69f
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0503.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0504.gif b/docs/htmldocs/using_samba/figs/sam.0504.gif
new file mode 100755
index 00000000000..bece7b9e0a5
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0504.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0505.gif b/docs/htmldocs/using_samba/figs/sam.0505.gif
new file mode 100755
index 00000000000..6460e0436d5
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0505.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0506.gif b/docs/htmldocs/using_samba/figs/sam.0506.gif
new file mode 100755
index 00000000000..e7282b02867
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0506.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0507.gif b/docs/htmldocs/using_samba/figs/sam.0507.gif
new file mode 100755
index 00000000000..bc7f2fda9af
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0507.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0508.gif b/docs/htmldocs/using_samba/figs/sam.0508.gif
new file mode 100755
index 00000000000..95b7ad98c4d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0508.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0601.gif b/docs/htmldocs/using_samba/figs/sam.0601.gif
new file mode 100755
index 00000000000..e826dd51415
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0601.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0602.gif b/docs/htmldocs/using_samba/figs/sam.0602.gif
new file mode 100755
index 00000000000..dce39b1c404
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0602.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0603.gif b/docs/htmldocs/using_samba/figs/sam.0603.gif
new file mode 100755
index 00000000000..15ad6f05d7b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0603.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0604.gif b/docs/htmldocs/using_samba/figs/sam.0604.gif
new file mode 100755
index 00000000000..cd9820d00e7
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0604.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0605.gif b/docs/htmldocs/using_samba/figs/sam.0605.gif
new file mode 100755
index 00000000000..db8e9c5e9f6
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0605.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0606.gif b/docs/htmldocs/using_samba/figs/sam.0606.gif
new file mode 100755
index 00000000000..a4c5e577e5a
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0606.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0701.gif b/docs/htmldocs/using_samba/figs/sam.0701.gif
new file mode 100755
index 00000000000..5933bdabbd0
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0701.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0702.gif b/docs/htmldocs/using_samba/figs/sam.0702.gif
new file mode 100755
index 00000000000..c1160e28383
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0702.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0703.gif b/docs/htmldocs/using_samba/figs/sam.0703.gif
new file mode 100755
index 00000000000..653e9b97617
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0703.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0704.gif b/docs/htmldocs/using_samba/figs/sam.0704.gif
new file mode 100755
index 00000000000..78d5a439eae
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0704.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0705.gif b/docs/htmldocs/using_samba/figs/sam.0705.gif
new file mode 100755
index 00000000000..39cee4c8569
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0705.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0706.gif b/docs/htmldocs/using_samba/figs/sam.0706.gif
new file mode 100755
index 00000000000..8725542429c
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0706.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0707.gif b/docs/htmldocs/using_samba/figs/sam.0707.gif
new file mode 100755
index 00000000000..09abcd5e78f
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0707.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0708.gif b/docs/htmldocs/using_samba/figs/sam.0708.gif
new file mode 100755
index 00000000000..bd5466b319b
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0708.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0709.gif b/docs/htmldocs/using_samba/figs/sam.0709.gif
new file mode 100755
index 00000000000..28452fd2322
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0709.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0801.gif b/docs/htmldocs/using_samba/figs/sam.0801.gif
new file mode 100755
index 00000000000..04e9210e54d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0801.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0802.gif b/docs/htmldocs/using_samba/figs/sam.0802.gif
new file mode 100755
index 00000000000..bf1718c93bf
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0802.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0803.gif b/docs/htmldocs/using_samba/figs/sam.0803.gif
new file mode 100755
index 00000000000..bb5739154a5
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0803.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0804.gif b/docs/htmldocs/using_samba/figs/sam.0804.gif
new file mode 100755
index 00000000000..eceb287e629
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0804.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0805.gif b/docs/htmldocs/using_samba/figs/sam.0805.gif
new file mode 100755
index 00000000000..5a599e13453
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0805.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0901.gif b/docs/htmldocs/using_samba/figs/sam.0901.gif
new file mode 100755
index 00000000000..1965600ab92
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0901.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0902.gif b/docs/htmldocs/using_samba/figs/sam.0902.gif
new file mode 100755
index 00000000000..f604d0ed09d
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0902.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0903.gif b/docs/htmldocs/using_samba/figs/sam.0903.gif
new file mode 100755
index 00000000000..1013d453427
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0903.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0904.gif b/docs/htmldocs/using_samba/figs/sam.0904.gif
new file mode 100755
index 00000000000..db13646f3dc
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0904.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.0905.gif b/docs/htmldocs/using_samba/figs/sam.0905.gif
new file mode 100755
index 00000000000..ef8c89bebbb
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.0905.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.aa01.gif b/docs/htmldocs/using_samba/figs/sam.aa01.gif
new file mode 100755
index 00000000000..495b649cd02
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.aa01.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.ab01.gif b/docs/htmldocs/using_samba/figs/sam.ab01.gif
new file mode 100755
index 00000000000..f7379675056
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.ab01.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/figs/sam.ab02.gif b/docs/htmldocs/using_samba/figs/sam.ab02.gif
new file mode 100755
index 00000000000..6090cfd51d2
--- /dev/null
+++ b/docs/htmldocs/using_samba/figs/sam.ab02.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/gifs/index.gif b/docs/htmldocs/using_samba/gifs/index.gif
new file mode 100755
index 00000000000..b45dcd58518
--- /dev/null
+++ b/docs/htmldocs/using_samba/gifs/index.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/gifs/samba.s.gif b/docs/htmldocs/using_samba/gifs/samba.s.gif
new file mode 100755
index 00000000000..4984d0f8f32
--- /dev/null
+++ b/docs/htmldocs/using_samba/gifs/samba.s.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/gifs/txthome.gif b/docs/htmldocs/using_samba/gifs/txthome.gif
new file mode 100755
index 00000000000..5598a0ff938
--- /dev/null
+++ b/docs/htmldocs/using_samba/gifs/txthome.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/gifs/txtnexta.gif b/docs/htmldocs/using_samba/gifs/txtnexta.gif
new file mode 100755
index 00000000000..b6d67311adc
--- /dev/null
+++ b/docs/htmldocs/using_samba/gifs/txtnexta.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/gifs/txtpreva.gif b/docs/htmldocs/using_samba/gifs/txtpreva.gif
new file mode 100755
index 00000000000..2b040b9b518
--- /dev/null
+++ b/docs/htmldocs/using_samba/gifs/txtpreva.gif
Binary files differ
diff --git a/docs/htmldocs/using_samba/index.html b/docs/htmldocs/using_samba/index.html
new file mode 100755
index 00000000000..f1b4ccec6ec
--- /dev/null
+++ b/docs/htmldocs/using_samba/index.html
@@ -0,0 +1,168 @@
+<HTML>
+<HEAD>
+<TITLE></title>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+
+<center>
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0">
+<tr>
+<td valign="TOP">
+<a href="http://www.oreilly.com/catalog/samba/">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</a>
+</td>
+<td valign="center">
+<H2>Using Samba</H2>
+<font size="-1">
+Robert Eckstein, David Collier-Brown, Peter Kelly<br>
+1st Edition November 1999<br>
+1-56592-449-5, Order Number: 4495<br>
+416 pages, $34.95
+</font>
+<p>
+<a href="http://www.oreilly.com/catalog/samba/">Buy the hardcopy version</a>
+
+</td>
+</tr>
+</table>
+</center>
+
+<hr size=1 noshade>
+<!--sample chapter begins -->
+
+<blockquote>
+<DIV CLASS="toc">
+<H2>
+Table of Contents</h2><P CLASS="toc">
+<a CLASS="chapter" HREF="licenseinfo.html" TITLE="">License Information</a><p>
+<a CLASS="chapter" HREF="this_edition.html" TITLE="">This Edition</a><p>
+<a CLASS="chapter" HREF="ch01_01.html" TITLE="">Chapter 1: <CITE CLASS="chapter">Learning the Samba</cite></a><br>
+ <blockquote>
+ <a CLASS="chapter" HREF="ch01_01.html#s1" TITLE="">Chapter 1.1: <CITE CLASS="chapter">What is Samba?</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_02.html" TITLE="">Chapter 1.2: <CITE CLASS="chapter">What Can Samba Do For Me?</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_03.html" TITLE="">Chapter 1.3: <CITE CLASS="chapter">Getting Familiar with a SMB/CIFS Network</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_04.html" TITLE="">Chapter 1.4: <CITE CLASS="chapter">Microsoft Implementations</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_05.html" TITLE="">Chapter 1.5: <CITE CLASS="chapter">An Overview of the Samba Distribution</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_06.html" TITLE="">Chapter 1.6: <CITE CLASS="chapter">How Can I Get Samba?</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_07.html" TITLE="">Chapter 1.7: <CITE CLASS="chapter">What's New in Samba 2.0?</cite></a><br>
+ <a CLASS="chapter" HREF="ch01_08.html" TITLE="">Chapter 1.8: <CITE CLASS="chapter">And That's Not All...</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch02_01.html" title="">Chapter 2: <CITE CLASS="chapter">Installing Samba on a Unix System</cite></a><br>
+ <blockquote>
+ <a CLASS="chapter" HREF="ch02_01.html#s1" TITLE="">Chapter 2.1: <CITE CLASS="chapter">Downloading the Samba Distribution</cite></a><br>
+ <a CLASS="chapter" HREF="ch02_02.html" TITLE="">Chapter 2.2: <CITE CLASS="chapter">Configuring Samba</cite></a><br>
+ <a CLASS="chapter" HREF="ch02_03.html" TITLE="">Chapter 2.3: <CITE CLASS="chapter">Compiling and Installing Samba</cite></a><br>
+ <a CLASS="chapter" HREF="ch02_04.html" TITLE="">Chapter 2.4: <CITE CLASS="chapter">A Basic Samba Configuration File</cite></a><br>
+ <a CLASS="chapter" HREF="ch02_05.html" TITLE="">Chapter 2.5: <CITE CLASS="chapter">Starting the Samba Daemons</cite></a><br>
+ <a CLASS="chapter" HREF="ch02_06.html" TITLE="">Chapter 2.6: <CITE CLASS="chapter">Testing the Samba Daemons</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch03_01.html" title="">Chapter 3: <CITE CLASS="chapter">Configuring Windows Clients</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch03_01.html#s1" title="">Chapter 3.1: <CITE CLASS="chapter">Setting Up Windows 95/98 Computers</cite></a><br>
+<a CLASS="chapter" HREF="ch03_02.html" title="">Chapter 3.2: <CITE CLASS="chapter">Setting Up Windows NT 4.0 Computers</cite></a><br>
+<a CLASS="chapter" HREF="ch03_03.html" title="">Chapter 3.3: <CITE CLASS="chapter">An Introduction to SMB/CIFS</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch04_01.html" Title="">Chapter 4: <CITE CLASS="chapter">Disk Shares</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch04_01.html#s1" Title="">Chapter 4.1: <CITE CLASS="chapter">Learning the Samba Configuration File</cite></a><br>
+<a CLASS="chapter" HREF="ch04_02.html" Title="">Chapter 4.2: <CITE CLASS="chapter">Special Sections</cite></a><br>
+<a CLASS="chapter" HREF="ch04_03.html" Title="">Chapter 4.3: <CITE CLASS="chapter">Configuration File Options</cite></a><br>
+<a CLASS="chapter" HREF="ch04_04.html" Title="">Chapter 4.4: <CITE CLASS="chapter">Server Configuration</cite></a><br>
+<a CLASS="chapter" HREF="ch04_05.html" Title="">Chapter 4.5: <CITE CLASS="chapter">Disk Share Configuration</cite></a><br>
+<a CLASS="chapter" HREF="ch04_06.html" Title="">Chapter 4.6: <CITE CLASS="chapter">Networking Options with Samba</cite></a><br>
+<a CLASS="chapter" HREF="ch04_07.html" Title="">Chapter 4.7: <CITE CLASS="chapter">Virtual Servers</cite></a><br>
+<a CLASS="chapter" HREF="ch04_08.html" Title="">Chapter 4.8: <CITE CLASS="chapter">Logging Configuration Options</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch05_01.html" title="">Chapter 5: <CITE CLASS="chapter">Browsing and Advanced Disk Shares</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch05_01.html#s1" Title="">Chapter 5.1: <CITE CLASS="chapter">Browsing</cite></a><br>
+<a CLASS="chapter" HREF="ch05_02.html" Title="">Chapter 5.2: <CITE CLASS="chapter">Filesystem Differences</cite></a><br>
+<a CLASS="chapter" HREF="ch05_03.html" Title="">Chapter 5.3: <CITE CLASS="chapter">File Permissions and Attributes on MS-DOS and Unix</cite></a><br>
+<a CLASS="chapter" HREF="ch05_04.html" Title="">Chapter 5.4: <CITE CLASS="chapter">Name Mangling and Case</cite></a><br>
+<a CLASS="chapter" HREF="ch05_05.html" Title="">Chapter 5.5: <CITE CLASS="chapter">Locks and Oplocks</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch06_01.html" title="">Chapter 6: <CITE CLASS="chapter">Users, Security, and Domains</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch06_01.html#s1" Title="">Chapter 6.1: <CITE CLASS="chapter">Users and Groups</cite></a><br>
+<a CLASS="chapter" HREF="ch06_02.html" Title="">Chapter 6.2: <CITE CLASS="chapter">Controlling Access to Shares</cite></a><br>
+<a CLASS="chapter" HREF="ch06_03.html" Title="">Chapter 6.3: <CITE CLASS="chapter">Authentication Security</cite></a><br>
+<a CLASS="chapter" HREF="ch06_04.html" Title="">Chapter 6.4: <CITE CLASS="chapter">Passwords</cite></a><br>
+<a CLASS="chapter" HREF="ch06_05.html" Title="">Chapter 6.5: <CITE CLASS="chapter">Windows Domains</cite></a><br>
+<a CLASS="chapter" HREF="ch06_06.html" Title="">Chapter 6.6: <CITE CLASS="chapter">Logon Scripts</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch07_01.html" Title="">Chapter 7: <CITE CLASS="chapter">Printing and Name Resolution</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch07_01.html#s1" Title="">Chapter 7.1: <CITE CLASS="chapter">Sending Print Jobs to Samba</cite></a><br>
+<a CLASS="chapter" HREF="ch07_02.html" Title="">Chapter 7.2: <CITE CLASS="chapter">Printing to Windows Client Printers</cite></a><br>
+<a CLASS="chapter" HREF="ch07_03.html" Title="">Chapter 7.3: <CITE CLASS="chapter">Name Resolution with Samba</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch08_01.html" title="">Chapter 8: <CITE CLASS="chapter">Additional Samba Information</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch08_01.html#s1" Title="">Chapter 8.1: <CITE CLASS="chapter">Supporting Programmers</cite></a><br>
+<a CLASS="chapter" HREF="ch08_02.html" Title="">Chapter 8.2: <CITE CLASS="chapter">Magic Scripts</cite></a><br>
+<a CLASS="chapter" HREF="ch08_03.html" Title="">Chapter 8.3: <CITE CLASS="chapter">Internationalization</cite></a><br>
+<a CLASS="chapter" HREF="ch08_04.html" Title="">Chapter 8.4: <CITE CLASS="chapter">WinPopup Messages</cite></a><br>
+<a CLASS="chapter" HREF="ch08_05.html" Title="">Chapter 8.5: <CITE CLASS="chapter">Recently Added Options</cite></a><br>
+<a CLASS="chapter" HREF="ch08_06.html" Title="">Chapter 8.6: <CITE CLASS="chapter">Miscellaneous Options</cite></a><br>
+<a CLASS="chapter" HREF="ch08_07.html" Title="">Chapter 8.7: <CITE CLASS="chapter">Backups with smbtar</cite></a><br>
+ </blockquote>
+<a CLASS="chapter" HREF="ch09_01.html" title="">Chapter 9: <CITE CLASS="chapter">Troubleshooting Samba</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="ch09_01.html#s1" Title="">Chapter 9.1: <CITE CLASS="chapter">The Tool Bag</cite></a><br>
+<a CLASS="chapter" HREF="ch09_02.html" Title="">Chapter 9.2: <CITE CLASS="chapter">The Fault Tree</cite></a><br>
+<a CLASS="chapter" HREF="ch09_03.html" Title="">Chapter 9.3: <CITE CLASS="chapter">Extra Resources</cite></a><br>
+ </blockquote>
+
+<a CLASS="appendix" HREF="appa_01.html" title="">Appendix A: <CITE CLASS="appendix">Configuring Samba with SSL</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="appa_01.html#appa-pgfId-986440" Title="">Appendix A.1: <CITE CLASS="chapter">About Certificates</cite></a><br>
+<a CLASS="chapter" HREF="appa_02.html" Title="">Appendix A.2: <CITE CLASS="chapter">Requirements</cite></a><br>
+<a CLASS="chapter" HREF="appa_03.html" Title="">Appendix A.3: <CITE CLASS="chapter">Installing SSLeay</cite></a><br>
+<a CLASS="chapter" HREF="appa_04.html" Title="">Appendix A.4: <CITE CLASS="chapter">Setting Up SSL Proxy</cite></a><br>
+<a CLASS="chapter" HREF="appa_05.html" Title="">Appendix A.5: <CITE CLASS="chapter">SSL Configuration Options</cite></a><br>
+ </blockquote>
+<a CLASS="appendix" HREF="appb_01.html" title="">Appendix B: <CITE CLASS="appendix">Samba Performance Tuning</cite></a><br>
+ <blockquote>
+<a CLASS="chapter" HREF="appb_01.html#appb-47134" Title="">Appendix B.1: <CITE CLASS="chapter">A Simple Benchmark</cite></a><br>
+<a CLASS="chapter" HREF="appb_02.html" Title="">Appendix B.2: <CITE CLASS="chapter">Samba Tuning</cite></a><br>
+<a CLASS="chapter" HREF="appb_03.html" Title="">Appendix B.3: <CITE CLASS="chapter">Sizing Samba Servers</cite></a><br>
+ </blockquote>
+<a CLASS="appendix" HREF="appc_01.html" Title="">Appendix C: <CITE CLASS="appendix">Samba Configuration Option Quick Reference</cite></a><br>
+<p>
+<a CLASS="appendix" HREF="appd_01.html" Title="">Appendix D: <CITE CLASS="appendix">Summary of Samba Daemons and Commands</cite></a><br>
+<p>
+<a CLASS="appendix" HREF="appe_01.html" Title="">Appendix E: <CITE CLASS="appendix">Downloading Samba with CVS</cite></a><br>
+<p>
+<a CLASS="appendix" HREF="appf_01.html" Title="">Appendix F: <CITE CLASS="appendix">Sample Configuration File</cite></a><br>
+<p>
+
+<a HREF="inx.html" Title="">Index</a><br>
+
+</p></div>
+</blockquote>
+
+<!-- End of sample chapter -->
+
+<hr noshade size=1></center>
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+</html>
diff --git a/docs/htmldocs/using_samba/inx.html b/docs/htmldocs/using_samba/inx.html
new file mode 100755
index 00000000000..34207d7a747
--- /dev/null
+++ b/docs/htmldocs/using_samba/inx.html
@@ -0,0 +1,1344 @@
+<html>
+<head>
+<title>Using Samba</title>
+<META NAME="metadata" CONTENT="dublincore.0.1">
+<META NAME="subject" CONTENT="Using Samba">
+<META NAME="title" CONTENT="O'Reilly Catalog Index: Using Samba">
+<META NAME="otheragent" CONTENT="cron job">
+<META NAME="source" CONTENT="internal database">
+<META NAME="publisher" CONTENT="O'Reilly &amp; Associates, Inc.">
+<META NAME="objecttype" CONTENT="catalog index">
+<META NAME="form" CONTENT="html">
+</head>
+<BODY BGCOLOR="#FFFFFF" >
+<table border=0 cellspacing=0 cellpadding=0 width=90%>
+<tr>
+<td>
+<h2>Using Samba</h2>
+<h3>Index</h3>
+
+<PRE>
+</pre>
+<A HREF="#A">[&nbsp;A&nbsp;]</A>,
+<A HREF="#B">[&nbsp;B&nbsp;]</A>,
+<A HREF="#C">[&nbsp;C&nbsp;]</A>,
+<A HREF="#D">[&nbsp;D&nbsp;]</A>,
+<A HREF="#E">[&nbsp;E&nbsp;]</A>,
+<A HREF="#F">[&nbsp;F&nbsp;]</A>,
+<A HREF="#G">[&nbsp;G&nbsp;]</A>,
+<A HREF="#H">[&nbsp;H&nbsp;]</A>,
+<A HREF="#I">[&nbsp;I&nbsp;]</A>,
+<A HREF="#J">[&nbsp;J&nbsp;]</A>,
+<A HREF="#K">[&nbsp;K&nbsp;]</A>,
+<A HREF="#L">[&nbsp;L&nbsp;]</A>,
+<A HREF="#M">[&nbsp;M&nbsp;]</A>,
+<A HREF="#N">[&nbsp;N&nbsp;]</A>,
+<A HREF="#O">[&nbsp;O&nbsp;]</A>,
+<A HREF="#P">[&nbsp;P&nbsp;]</A>,
+<A HREF="#Q">[&nbsp;Q&nbsp;]</A>,
+<A HREF="#R">[&nbsp;R&nbsp;]</A>,
+<A HREF="#S">[&nbsp;S&nbsp;]</A>,
+<A HREF="#T">[&nbsp;T&nbsp;]</A>,
+<A HREF="#U">[&nbsp;U&nbsp;]</A>,
+<A HREF="#V">[&nbsp;V&nbsp;]</A>,
+<A HREF="#W">[&nbsp;W&nbsp;]</A>,
+<A HREF="#Y">[&nbsp;Y&nbsp;]</A>,
+
+
+<BR>&lt;&gt; (angled brackets), 14
+<BR>* (asterisk), 169
+<BR>\ (backslash) in smb.conf file, 85
+<BR>\\ (backslashes, two) in directories, 5
+<BR>: (colon), 6
+<BR>\ (continuation character), 85
+<BR>. (dot), 128, 134
+<BR># (hash mark), 85
+<BR>% (percent sign), 86
+<BR>. (period), 128
+<BR>? (question mark), 135
+<BR>; (semicolon), 85
+<BR>/ (slash character), 129, 134-135
+<BR>/ (slash) in shares, 116
+<BR>_ (underscore) 116
+<BR>* wildcard, 177
+
+<P><A NAME="A"><B>A</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>access-control options (shares), 160-162
+<BR>accessing Samba server, 61
+<BR>accounts, 51-53
+<BR>active connections, option for, 244
+<BR>addresses, networking option for, 106
+<BR>addtosmbpass executable, 176
+<BR>admin users option, 161
+<BR>AFS files, support for, 35
+<BR>aliases
+<BR> &nbsp; &nbsp; &nbsp; multiple, 29
+<BR> &nbsp; &nbsp; &nbsp; for NetBIOS names, 107
+<BR>alid users option, 161
+<BR>announce as option, 123
+<BR>announce version option, 123
+<BR>API (application programming interface), 9
+<BR>archive files, 137
+<BR>authentication, 19, 164-171
+<BR> &nbsp; &nbsp; &nbsp; mechanisms for, 35
+<BR> &nbsp; &nbsp; &nbsp; NT domain, 170
+<BR> &nbsp; &nbsp; &nbsp; share-level option for, 192
+<BR>auto services option, 124
+<BR>automounter, support for, 35
+<BR>awk script, 176
+<P><A NAME="B"><B>B</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>backup browsers
+<BR> &nbsp; &nbsp; &nbsp; local master browser, 22
+<BR> &nbsp; &nbsp; &nbsp; per local master browser, 23
+<BR> &nbsp; &nbsp; &nbsp; maximum number per workgroup, 22
+<BR>backup domain controllers (BDCs), 20
+<BR>backups, with smbtar program, 245-248
+<BR>backwards compatibility
+<BR> &nbsp; &nbsp; &nbsp; elections and, 23
+<BR> &nbsp; &nbsp; &nbsp; for filenames, 143
+<BR> &nbsp; &nbsp; &nbsp; Windows domains and, 20
+<BR>base directory, 40
+<BR>.BAT scripts, 192
+<BR>BDCs (backup domain controllers), 20
+<BR>binary vs. source files, 32
+<BR>bind interfaces only option, 106
+<BR>bindings, 71
+<BR>Bindings tab, 60
+<BR>blocking locks option, 152
+<BR>b-node, 13
+<BR>boolean type, 90
+<BR>bottlenecks, 320-328
+<BR> &nbsp; &nbsp; &nbsp; reducing, 321-326
+<BR> &nbsp; &nbsp; &nbsp; types of, 320
+<BR>broadcast addresses, troubleshooting, 289
+<BR>broadcast registration, 13
+<BR>broadcast resolution, 13, 59
+<BR>broadcasting
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting with tcpdump utility, 255
+<BR> &nbsp; &nbsp; &nbsp; (see also browsing; name resolution)
+<BR>browse lists, 21, 116
+<BR> &nbsp; &nbsp; &nbsp; options for, 124, 127
+<BR> &nbsp; &nbsp; &nbsp; propagation, 24
+<BR> &nbsp; &nbsp; &nbsp; restricting shares from, 115
+<BR>browsing, 21-23, 114-127
+<BR> &nbsp; &nbsp; &nbsp; client-side, testing with net view, 280
+<BR> &nbsp; &nbsp; &nbsp; configuration options for, 122-127
+<BR> &nbsp; &nbsp; &nbsp; elections, 23, 116-119
+<BR> &nbsp; &nbsp; &nbsp; machines, list of, 21
+<BR> &nbsp; &nbsp; &nbsp; options for, list of, 122
+<BR> &nbsp; &nbsp; &nbsp; preventing, 115
+<BR> &nbsp; &nbsp; &nbsp; resources of a specific machine, 21-23
+<BR> &nbsp; &nbsp; &nbsp; server from client, 281
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 275-282
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with smbclient, 276-278
+<BR>bug avoidance options, 240-245
+<BR> &nbsp; &nbsp; &nbsp; list of, 240-241
+<P><A NAME="C"><B>C</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>cache size, new option for (Samba version 2.0), 239
+<BR>cache time (printers), option for, 220
+<BR>capitalization, 84
+<BR>Carnegie Mellon University, 35
+<BR>carriage-returns for scripts, 193
+<BR>case sensitivity
+<BR> &nbsp; &nbsp; &nbsp; hostnames and, 5
+<BR> &nbsp; &nbsp; &nbsp; options for, 146
+<BR> &nbsp; &nbsp; &nbsp; usernames and, 163
+<BR>CD-ROM with this book
+<BR> &nbsp; &nbsp; &nbsp; Samba distribution, 28, 32
+<BR> &nbsp; &nbsp; &nbsp; testing tools, 28
+<BR>certificate authority, 300-303
+<BR>change notification, new option for (Samba version 2.0), 239
+<BR>change notify timeout option, 239
+<BR>Change Windows Password dialog box, 52
+<BR>changes at runtime, 85
+<BR>chat characters for passwords, 178
+<BR>CIFS (Common Internet File System), 3
+<BR> &nbsp; &nbsp; &nbsp; (see also SMB/CIFS protocol)
+<BR>client code page option, 234
+<BR>client users (see users)
+<BR>client variables, 86
+<BR>clients, testing with nmblookup program, 279
+<BR>.CMD scripts, 192
+<BR>code pages, 234
+<BR> &nbsp; &nbsp; &nbsp; multiple, 30
+<BR>coding system option, 235
+<BR>command string, SMB, 75
+<BR>commands for Samba, 366-377
+<BR>commas in values, 84
+<BR>comment option, 99
+<BR>comments in smb.conf (Samba configuration) file, 85
+<BR>compatibility, Samba with Windows NT, 30
+<BR>compilers, 33
+<BR>compiling Samba, 38-41
+<BR> &nbsp; &nbsp; &nbsp; in version 2.0, 29
+<BR>config file option, 91
+<BR>configuration files
+<BR> &nbsp; &nbsp; &nbsp; for individual clients, 253
+<BR> &nbsp; &nbsp; &nbsp; machine-specific, 87
+<BR> &nbsp; &nbsp; &nbsp; sample of, 379-383
+<BR> &nbsp; &nbsp; &nbsp; smb.conf (Samba configuration) file (see smb.conf file)
+<BR>configuration options
+<BR> &nbsp; &nbsp; &nbsp; browsing, 122-127
+<BR> &nbsp; &nbsp; &nbsp; disk share, 97-100
+<BR> &nbsp; &nbsp; &nbsp; format of, 83
+<BR> &nbsp; &nbsp; &nbsp; list of, 329-356
+<BR> &nbsp; &nbsp; &nbsp; server, 94-96
+<BR>configuring disk shares, 96-100
+<BR>configuring DNS (Windows NT), 68
+<BR>configuring Samba, 34-38
+<BR> &nbsp; &nbsp; &nbsp; configuration file
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; creating, 41-45
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; testing, 45
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (see also smb.conf (Samba configuration) file)
+<BR> &nbsp; &nbsp; &nbsp; configure script
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GNU, 34
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample execution, 38
+<BR> &nbsp; &nbsp; &nbsp; options, 34-37
+<BR> &nbsp; &nbsp; &nbsp; performance tuning, 312-328
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; benchmark for, 312, 314
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; other options for, 319-328
+<BR> &nbsp; &nbsp; &nbsp; server, 93-96
+<BR> &nbsp; &nbsp; &nbsp; with SSL, 295-311
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; requirements for, 296
+<BR>configuring TCP/IP networking protocol, 55, 66-71
+<BR>configuring Windows clients, 50-81
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98 computers, 50-63
+<BR> &nbsp; &nbsp; &nbsp; Windows NT 4.0 computers, 63-73
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; basic configuration, 63-67
+<BR>configuring WINS address, 70
+<BR>connected systems, status of, 9
+<BR>connections
+<BR> &nbsp; &nbsp; &nbsp; active, option for, 244
+<BR> &nbsp; &nbsp; &nbsp; current, list of, 370
+<BR> &nbsp; &nbsp; &nbsp; resources, connecting to, 81
+<BR> &nbsp; &nbsp; &nbsp; scripts for, 198
+<BR> &nbsp; &nbsp; &nbsp; SMB, 77
+<BR> &nbsp; &nbsp; &nbsp; testing, 259-263
+<BR> &nbsp; &nbsp; &nbsp; virtual, 78
+<BR>copy option, 92
+<BR>creation masks, 138
+<BR> &nbsp; &nbsp; &nbsp; option for, 140
+<BR>cryptography, private key, 35
+<BR>CVS (Concurrent Versions Systems), 378
+<BR>Cyclic Software, 378
+<P><A NAME="D"><B>D</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>daemons, 82, 359-362
+<BR> &nbsp; &nbsp; &nbsp; killing, 48
+<BR> &nbsp; &nbsp; &nbsp; messages generated by, reading, 8
+<BR> &nbsp; &nbsp; &nbsp; stand-alone, 47
+<BR> &nbsp; &nbsp; &nbsp; starting, 46-48
+<BR> &nbsp; &nbsp; &nbsp; status report, 8
+<BR> &nbsp; &nbsp; &nbsp; testing, 49
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with testparm, 266
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 264-268
+<BR> &nbsp; &nbsp; &nbsp; Unix, 2
+<BR> &nbsp; &nbsp; &nbsp; viewing, 8
+<BR> &nbsp; &nbsp; &nbsp; (see also smbd daemon; nmbd daemon)
+<BR>data transfer protocol, 6
+<BR>datagram service, 10, 16-18
+<BR>deadtime option, 241
+<BR>debug files, 49
+<BR>debug level option, 251, 314
+<BR>debug timestamp option, 112
+<BR>default case option, 146
+<BR>default services, 115
+<BR> &nbsp; &nbsp; &nbsp; option for, 124
+<BR>defending hostnames, 12
+<BR>delays, troubleshooting, 287
+<BR>delete, 142
+<BR>delete readonly option, 139, 142
+<BR>delete veto files option, 135
+<BR>dfree command option, 241
+<BR>DFS, support for, 35
+<BR>DHCP (Dynamic Host Configuration Protocol), 57, 67
+<BR>dialup connection, 53
+<BR>Digital Pathworks clients, option for, 244
+<BR>directories
+<BR> &nbsp; &nbsp; &nbsp; barring users from viewing contents, 130, 133
+<BR> &nbsp; &nbsp; &nbsp; installation, 40
+<BR> &nbsp; &nbsp; &nbsp; permissions, options for, 140
+<BR> &nbsp; &nbsp; &nbsp; for Samba startup file, 363
+<BR> &nbsp; &nbsp; &nbsp; target, 40
+<BR> &nbsp; &nbsp; &nbsp; working, option for, 134
+<BR>directory mask option, 138, 141
+<BR>disabling/enabling features, 34
+<BR>discussion archives for Samba, 293
+<BR>disk quotas, support for, 37
+<BR>disk shares, 4-7, 49, 82-113
+<BR> &nbsp; &nbsp; &nbsp; advanced, 114-154
+<BR> &nbsp; &nbsp; &nbsp; configuring, 96-100
+<BR> &nbsp; &nbsp; &nbsp; creating, 96
+<BR> &nbsp; &nbsp; &nbsp; maximum size of, option for, 242
+<BR> &nbsp; &nbsp; &nbsp; path option, 98
+<BR>disk sync, options for, 245
+<BR>DMB (domain master browser), 119-122
+<BR> &nbsp; &nbsp; &nbsp; option for, 126
+<BR> &nbsp; &nbsp; &nbsp; resource type, 24
+<BR>DNS Configuration tab, 57
+<BR>DNS (Domain Name System), 57
+<BR> &nbsp; &nbsp; &nbsp; configuring, 68
+<BR> &nbsp; &nbsp; &nbsp; as fallback for WINS address, 71
+<BR> &nbsp; &nbsp; &nbsp; names
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NetBIOS names and, 14
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resource types and, 15
+<BR> &nbsp; &nbsp; &nbsp; option for, 228
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 293
+<BR> &nbsp; &nbsp; &nbsp; tab, 68
+<BR>dns proxy option, 228
+<BR>docs directory, 34
+<BR> &nbsp; &nbsp; &nbsp; test utilities, 254
+<BR>documentation for Samba, 291
+<BR> &nbsp; &nbsp; &nbsp; importance of reading, 34
+<BR>domain controllers, 20, 169
+<BR> &nbsp; &nbsp; &nbsp; for Windows 95/98, 18-20
+<BR>domain group map option, 191
+<BR>domain logons, 28, 184
+<BR> &nbsp; &nbsp; &nbsp; configuring Windows 95/98 for, 188
+<BR> &nbsp; &nbsp; &nbsp; configuring Windows NT 4.0 for, 189
+<BR> &nbsp; &nbsp; &nbsp; scripts for, 192-200
+<BR>domain logons option, 190
+<BR>domain master browser (see DMB)
+<BR>domain master option, 126
+<BR>Domain Name System (see DNS)
+<BR>domain user map option, 191
+<BR>domain-level security, 164, 169-171
+<BR>domains, 18-20
+<BR> &nbsp; &nbsp; &nbsp; adding Samba server to Windows NT domain, 171
+<BR> &nbsp; &nbsp; &nbsp; behavior vs. Windows workgroups, 20
+<BR> &nbsp; &nbsp; &nbsp; controllers (see domain controllers)
+<BR> &nbsp; &nbsp; &nbsp; logons (see domain logons)
+<BR> &nbsp; &nbsp; &nbsp; new option for password timeout (Samba version 2.0), 239
+<BR> &nbsp; &nbsp; &nbsp; roles in assumed by Samba, 26
+<BR> &nbsp; &nbsp; &nbsp; Windows, 18, 28, 184-192
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; authentication, 170
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caution when selecting, 190
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; support for, 28
+<BR>dont descend option, 133
+<BR>DOS file permissions and attributes, 135-143
+<BR>DOS-formatted carriage returns, 193
+<BR>downloads
+<BR> &nbsp; &nbsp; &nbsp; Samba, 32
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obtained using CVS, 378
+<BR> &nbsp; &nbsp; &nbsp; tcpdump utility, 78, 257
+<BR>drive letters, mapping, 5
+<BR>dynamically linked libraries, 33
+<P><A NAME="E"><B>E</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>elections, 23
+<BR> &nbsp; &nbsp; &nbsp; operating system values in, 117
+<BR> &nbsp; &nbsp; &nbsp; order of decisions in, 118
+<BR> &nbsp; &nbsp; &nbsp; role settings in, 117
+<BR> &nbsp; &nbsp; &nbsp; WINS servers and, 26
+<BR>enabling/disabling features, 34
+<BR>encrypt passwords option, 181
+<BR>encrypted passwords, 172
+<BR> &nbsp; &nbsp; &nbsp; Microsoft format, 183
+<BR> &nbsp; &nbsp; &nbsp; option for, 181
+<BR> &nbsp; &nbsp; &nbsp; vs. plaintext passwords, 173
+<BR>Entire Network icon, 4
+<BR>enumerated lists, 91
+<BR>errors
+<BR> &nbsp; &nbsp; &nbsp; searching for, 38
+<BR> &nbsp; &nbsp; &nbsp; syntax, 45
+<BR>/etc/hosts file, 57, 60
+<BR>/etc/inetd.conf configuration files, 48
+<BR> &nbsp; &nbsp; &nbsp; adding SWAT tool to, 41
+<BR>/etc/resolv.conf file, 57
+<BR>/etc/services configuration file, adding SWAT tool to, 41, 48
+<BR>Ethernet adaptor cards, 53, 70
+<BR> &nbsp; &nbsp; &nbsp; linking to TCP/IP networking protocol, 55
+<BR>execute permissions, 47
+<BR>/export/samba/test directory, 42
+<P><A NAME="F"><B>F</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>fake directory create times option, 232
+<BR>fake oplocks option, 153
+<BR>FAQ, Samba, 291
+<BR>fast locking, 36
+<BR>fatal error, option for, 244
+<BR>fault tree, 257-291
+<BR> &nbsp; &nbsp; &nbsp; how to use, 257
+<BR>"File and Printer Sharing for Microsoft Networks", 53, 60, 246
+<BR>file creation masks, 138
+<BR>filenames
+<BR> &nbsp; &nbsp; &nbsp; 8.3 format, 143
+<BR> &nbsp; &nbsp; &nbsp; limitations on, 143
+<BR> &nbsp; &nbsp; &nbsp; representing/resolving, 145
+<BR> &nbsp; &nbsp; &nbsp; Unix, option for, 245
+<BR>files
+<BR> &nbsp; &nbsp; &nbsp; archive, 137
+<BR> &nbsp; &nbsp; &nbsp; attributes, 135-143
+<BR> &nbsp; &nbsp; &nbsp; deleting, option for, 129
+<BR> &nbsp; &nbsp; &nbsp; hidden, 128, 136
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options for, 134
+<BR> &nbsp; &nbsp; &nbsp; open, option for maximum number of, 243
+<BR> &nbsp; &nbsp; &nbsp; permissions, 135-143
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options for, 140
+<BR> &nbsp; &nbsp; &nbsp; read-only, 136
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deleting, 139, 142
+<BR> &nbsp; &nbsp; &nbsp; system, 136
+<BR> &nbsp; &nbsp; &nbsp; in use, status of, 9
+<BR> &nbsp; &nbsp; &nbsp; veto, 129-131
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; option for deleting, 135
+<BR>filesystems
+<BR> &nbsp; &nbsp; &nbsp; differences between, 127-131
+<BR> &nbsp; &nbsp; &nbsp; links and, 130
+<BR> &nbsp; &nbsp; &nbsp; options for, 132-135
+<BR> &nbsp; &nbsp; &nbsp; reporting on by Samba, option for, 242
+<BR> &nbsp; &nbsp; &nbsp; (see also files)
+<BR>fixed user configuration, 196
+<BR>flat namespaces, 14, 25
+<BR>follow symlinks option, 133
+<BR>force create mode option, 141
+<BR>force directory mode option, 141
+<BR>force group option, 139, 141
+<BR>force user option, 139, 141
+<BR>foreign-language characters, 234-236
+<BR>free space on disk, option for, 241
+<BR>fstype option, 242
+<BR>FTP (File Transfer Protocol), 6
+<BR> &nbsp; &nbsp; &nbsp; sites for Samba downloads, 32
+<P><A NAME="G"><B>G</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>gateway field, 68
+<BR>getwd cache option, 134, 320
+<BR>global options, 90
+<BR>[globals] section, 88
+<BR>GNU autoconf, 29
+<BR>GNU configure script, 34
+<BR>GNU General Public License (GPL), 3, 378
+<BR>groups, 155-158
+<BR> &nbsp; &nbsp; &nbsp; administrative privileges for, 159
+<BR> &nbsp; &nbsp; &nbsp; names and types of, 15
+<BR>guest, 162
+<BR>guest access, 159-162
+<BR>guest account option, 162
+<BR>guest ok option, 98
+<BR>guest only option, 162
+<P><A NAME="H"><B>H</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>hangup (HUP) signal, 48
+<BR>header, SMB, 74
+<BR>Hexidecimal byte value
+<BR> &nbsp; &nbsp; &nbsp; for NetBIOS group resource types, 16
+<BR> &nbsp; &nbsp; &nbsp; for NetBIOS unique resource types, 15
+<BR>hidden files, 128, 136
+<BR> &nbsp; &nbsp; &nbsp; options for, 134, 142, 319
+<BR>h-node, 13
+<BR>home directory, user's, 36, 155
+<BR> &nbsp; &nbsp; &nbsp; logon script option for location of, 198
+<BR>homedir map option, 200
+<BR>[homes] share, 89, 157
+<BR>hort preserve case option, 147
+<BR>hostnames
+<BR> &nbsp; &nbsp; &nbsp; case sensitivity and, 5
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long/short, 286
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lookup, 284
+<BR>hosts
+<BR> &nbsp; &nbsp; &nbsp; files (Windows 95/98), 59
+<BR> &nbsp; &nbsp; &nbsp; files (Windows NT computers), 71
+<BR> &nbsp; &nbsp; &nbsp; networking option for connections, 101, 103, 105
+<BR> &nbsp; &nbsp; &nbsp; subnets and, caution with, 102
+<BR>hosts allow option, 103
+<BR>hosts deny option, 105
+<BR>hosts equiv option, 184
+<BR>how-tos, fault tree, 257-291
+<BR>http, 6
+<BR>HUP (hangup) signal, 48
+<P><A NAME="I"><B>I</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>Identification Changes dialog box (Windows NT), 63
+<BR>Identification tab, 60
+<BR>implementations, Microsoft, 18-27
+<BR>include option, 92
+<BR>inetd daemon, starting other daemons from, 48
+<BR>installing Samba, 31-49
+<BR> &nbsp; &nbsp; &nbsp; common problems, 34
+<BR> &nbsp; &nbsp; &nbsp; installation directories, 40
+<BR> &nbsp; &nbsp; &nbsp; steps in, 31
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final, 41
+<BR> &nbsp; &nbsp; &nbsp; time required, 31
+<BR>installing TCP/IP protocol, 65
+<BR>installing Workstation service, 65
+<BR>interfaces, networking options for, 102
+<BR>interfaces option, 105
+<BR>internationalization, 234-236
+<BR>invalid users option, 161
+<BR>IP address, 288-290
+<BR> &nbsp; &nbsp; &nbsp; setting for Windows NT computers, 67
+<BR>IP Address tab
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98, 57
+<BR> &nbsp; &nbsp; &nbsp; Windows NT, 67
+<BR>IP packet size, tuning, 316
+<P><A NAME="J"><B>J</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>Jacobson, Van, 255
+<P><A NAME="K"><B>K</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>keep-alive packets, option for, 242
+<BR>Kerberos, support for, 35
+<BR>kernel oplocks option, 153
+<P><A NAME="L"><B>L</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>languages, non-European, 30
+<BR>LDAP (Lightweight Directory Access Protocol)
+<BR> &nbsp; &nbsp; &nbsp; replacement for password synchronization, 179
+<BR> &nbsp; &nbsp; &nbsp; support for, 36
+<BR>ldd tool, 33
+<BR>legal agreements covering multi-user functionality, 6
+<BR>Leres, Craig, 255
+<BR>Lightweight Directory Access Protocol (see LDAP)
+<BR>line continuation, 85
+<BR>links, 130
+<BR> &nbsp; &nbsp; &nbsp; option for, 133
+<BR>Linux
+<BR> &nbsp; &nbsp; &nbsp; installing Samba on Linux system, 31
+<BR> &nbsp; &nbsp; &nbsp; submount and, 36
+<BR>lm announce option, 125
+<BR>lm interval option, 125
+<BR>LMHOSTS file, 224
+<BR>load printers option, 222
+<BR>local group map option, 192
+<BR>local master browser, 21, 116-122
+<BR> &nbsp; &nbsp; &nbsp; checking machines for, 118
+<BR> &nbsp; &nbsp; &nbsp; option for, 125
+<BR>local master option, 125
+<BR>local profiles, 194
+<BR>localhost
+<BR> &nbsp; &nbsp; &nbsp; address, 69
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 288
+<BR>localization, 234-236
+<BR>lock directory option, 154
+<BR>locking option, 152
+<BR>locks/locking files, 9, 149-154
+<BR> &nbsp; &nbsp; &nbsp; messaging option for, 237
+<BR> &nbsp; &nbsp; &nbsp; opportunistic locking, 29
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tuning of, 316
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (see also oplocks)
+<BR> &nbsp; &nbsp; &nbsp; options for, 151-154
+<BR> &nbsp; &nbsp; &nbsp; Unix and, 150
+<BR>log files/logging
+<BR> &nbsp; &nbsp; &nbsp; activating/deactivating, 253
+<BR> &nbsp; &nbsp; &nbsp; checking, 108-113
+<BR> &nbsp; &nbsp; &nbsp; configuration options, 108-113
+<BR> &nbsp; &nbsp; &nbsp; in for the first time (Samba), 52
+<BR> &nbsp; &nbsp; &nbsp; levels of
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setting, 251-253
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tuning, 314
+<BR> &nbsp; &nbsp; &nbsp; options for, 199
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 282
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting from, 251-254
+<BR>log level option, 112, 251, 314
+<BR>login dialog box, domain logons
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98, 188
+<BR> &nbsp; &nbsp; &nbsp; Windows NT, 190
+<BR>login parameters, setting, 79
+<BR>logon drive option, 197
+<BR>logon home option, 198
+<BR>logon path option, 197
+<BR>logon script option, 197
+<BR>logon scripts, 192-200
+<BR> &nbsp; &nbsp; &nbsp; options for, 196-198
+<BR>logons (see domain logons)
+<BR>lppause command option, 221
+<BR>lpq cache time option, 220, 319
+<BR>lpq command option, 221
+<BR>lpresume command option, 221
+<BR>lprm command option, 221
+<P><A NAME="M"><B>M</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>machine name, types, 15
+<BR>machine password timeout option, 239
+<BR>magic output option, 233
+<BR>magic script option, 233
+<BR>magic scripts, 233
+<BR>mailing lists
+<BR> &nbsp; &nbsp; &nbsp; posting to, 39
+<BR> &nbsp; &nbsp; &nbsp; for Samba, 292
+<BR>main tree, 40
+<BR>makefiles, 33-34
+<BR>mandatory profiles, 196
+<BR>mangle case option, 148
+<BR>mangled map option, 148
+<BR>mangled names option, 147
+<BR>mangled stack option, 148
+<BR>mangling char option, 148
+<BR>map archive option, 142
+<BR>map hidden option, 142
+<BR>Map Network Drive option, 5, 62
+<BR>map system option, 142
+<BR>mapping
+<BR> &nbsp; &nbsp; &nbsp; files, options for location of, 191
+<BR> &nbsp; &nbsp; &nbsp; network drives, 5
+<BR>masks
+<BR> &nbsp; &nbsp; &nbsp; creation, 138
+<BR> &nbsp; &nbsp; &nbsp; netmasks, 57
+<BR> &nbsp; &nbsp; &nbsp; subnet, 57, 67
+<BR> &nbsp; &nbsp; &nbsp; umasks, 138
+<BR>master browsers (see local master browser; DMB; preferred master browser)
+<BR>max connections option, 161
+<BR>max disk size option, 242
+<BR>max log size option, 112
+<BR>max mux option, 243
+<BR>max open files option, 243
+<BR>max ttl option, 229
+<BR>max wins ttl option, 229
+<BR>max xmit option, 243, 317
+<BR>Maximum Transport Unit (MTU), 316
+<BR>McCanne, Steven, 255
+<BR>measurement forms, 326
+<BR>memory, status of, 9
+<BR>message command option, 238
+<BR>messages
+<BR> &nbsp; &nbsp; &nbsp; from daemons, reading, 8
+<BR> &nbsp; &nbsp; &nbsp; WinPopup, 237
+<BR>Microsoft, 3
+<BR> &nbsp; &nbsp; &nbsp; encryption, 30
+<BR> &nbsp; &nbsp; &nbsp; implementations, 18-27
+<BR>Microsoft Networking Client, 65
+<BR>min print space option, 223
+<BR>min wins ttl option, 229
+<BR>mirror sites for Samba distribution, 28
+<BR>MIT, 35
+<BR>mmap code, 36
+<BR>m-node, 13
+<BR>modem, linking to TCP/IP networking protocol, 55
+<BR>MTU (Maximum Transport Unit), 316
+<BR>multiple code pages, 30
+<BR>multiple subnets, 120
+<BR>multi-user functionality, legal agreements and, 6
+<BR>My Computer (Windows 95/98), 51
+<P><A NAME="N"><B>N</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>name mangling, 143-149
+<BR> &nbsp; &nbsp; &nbsp; options for, 145-149
+<BR> &nbsp; &nbsp; &nbsp; steps in, 143
+<BR>name registration, 10
+<BR>name resolution, 11, 60, 224-229
+<BR> &nbsp; &nbsp; &nbsp; options for, 227-229
+<BR>name resolve order option, 229
+<BR>name services, 10
+<BR> &nbsp; &nbsp; &nbsp; identifying what is in use, 283
+<BR> &nbsp; &nbsp; &nbsp; nmblookup program, 372
+<BR> &nbsp; &nbsp; &nbsp; testing, 258
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 282-288
+<BR>naming
+<BR> &nbsp; &nbsp; &nbsp; machine name, types, 15
+<BR> &nbsp; &nbsp; &nbsp; machines on NetBIOS network, 10-13
+<BR> &nbsp; &nbsp; &nbsp; NT computers, 63
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caution with, 64
+<BR> &nbsp; &nbsp; &nbsp; TCP/IP networking protocol, setting machine name for, 60
+<BR>NBNS (see NetBIOS, name server)
+<BR>NBT standard, 10
+<BR>NBTSTAT utility, 15
+<BR>Netatalk (Macintosh), support for interoperating with, 37
+<BR>NetBEUI (NetBIOS Extended User Interface), 10, 53
+<BR> &nbsp; &nbsp; &nbsp; Windows NT computers and, 65
+<BR>netbios aliases option, 107
+<BR>NetBIOS name, 14-16
+<BR> &nbsp; &nbsp; &nbsp; option for aliases, 107
+<BR> &nbsp; &nbsp; &nbsp; setting
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Windows 95/98, 61
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Windows NT, 63
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 290
+<BR>netbios name option, 95
+<BR>NetBIOS (Network Basic Input/Output System), 9
+<BR> &nbsp; &nbsp; &nbsp; compared with TCP/IP, 10
+<BR> &nbsp; &nbsp; &nbsp; Extended User Interface (see NetBEUI)
+<BR> &nbsp; &nbsp; &nbsp; multiple servers (see virtual servers)
+<BR> &nbsp; &nbsp; &nbsp; name (see NetBIOS name)
+<BR> &nbsp; &nbsp; &nbsp; name server (NBNS), 11, 25, 58
+<BR> &nbsp; &nbsp; &nbsp; network, naming machines on, 10-13
+<BR> &nbsp; &nbsp; &nbsp; over TCP/IP, 10
+<BR> &nbsp; &nbsp; &nbsp; Unique Resource Types, 15
+<BR>netmasks, 57, 67
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 288
+<BR>network addresses
+<BR> &nbsp; &nbsp; &nbsp; finding, 290
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting, 288-290
+<BR>Network Basic Input/Output System (see NetBIOS)
+<BR>network configuration commands, 192
+<BR>Network dialog box (Windows NT), 63
+<BR>network drives, mapping, 5
+<BR>Network File System
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 293
+<BR>Network File System (NFS), 30
+<BR>Network icon
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98, 53
+<BR> &nbsp; &nbsp; &nbsp; Windows NT, 63
+<BR>network masks (see netmasks)
+<BR>Network Neighborhood icon, 61, 93
+<BR> &nbsp; &nbsp; &nbsp; viewing Samba server, 72
+<BR>Network Neighborhood window, 21-22
+<BR> &nbsp; &nbsp; &nbsp; mapping network drives via, 5
+<BR>networking
+<BR> &nbsp; &nbsp; &nbsp; hardware for, testing, 259
+<BR> &nbsp; &nbsp; &nbsp; network address ranges, 289
+<BR> &nbsp; &nbsp; &nbsp; nmblookup program, testing with, 279
+<BR> &nbsp; &nbsp; &nbsp; options, 101-106
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list of, 103
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; magic script, 233
+<BR> &nbsp; &nbsp; &nbsp; printing on a network, steps in, 201
+<BR> &nbsp; &nbsp; &nbsp; setting up, 53-60
+<BR>newsgroups for Samba, 291
+<BR>NFS (Network File System), 30
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 293
+<BR>nis homedir option, 200
+<BR>NIS/NIS+ protocol, 36, 169
+<BR> &nbsp; &nbsp; &nbsp; how Samba works with, 199
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 293
+<BR>nmbd daemon, 2, 29, 82, 85, 361-362
+<BR> &nbsp; &nbsp; &nbsp; browsing options for, 125
+<BR> &nbsp; &nbsp; &nbsp; killing, 48
+<BR> &nbsp; &nbsp; &nbsp; starting, 46
+<BR>nmblookup program, 372
+<BR> &nbsp; &nbsp; &nbsp; networks, testing with, 279
+<BR>node types, 13
+<BR>non-encrypted passwords, 172
+<BR>non-European languages, 30
+<BR>Novell Networking, 53
+<BR>nt pipe support option, 243
+<BR>nt smb support option, 243
+<BR>null passwords, 183
+<BR>null TID, 74
+<BR>numerical type, 90
+<P><A NAME="O"><B>O</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>.old files, 39
+<BR>ole locking compatibility option, 244
+<BR>Open Source Software (OSS), 3
+<BR>operating systems
+<BR> &nbsp; &nbsp; &nbsp; encrypted/non-encrypted passwords, 172
+<BR> &nbsp; &nbsp; &nbsp; miscellaneous options for, 240
+<BR> &nbsp; &nbsp; &nbsp; values in elections, 117
+<BR>oplock files option, 316
+<BR>oplocks, 149-154
+<BR> &nbsp; &nbsp; &nbsp; break requests, 149
+<BR> &nbsp; &nbsp; &nbsp; messaging option for, 237
+<BR> &nbsp; &nbsp; &nbsp; options for, 151-154
+<BR>oplocks option, 153
+<BR>opportunistic locking, 29
+<BR> &nbsp; &nbsp; &nbsp; tuning, 316
+<BR> &nbsp; &nbsp; &nbsp; (see also oplocks)
+<BR>option names, 84
+<BR>os filetime resolution option, 232
+<BR>os level option, 126
+<BR>OS/2, support for share-level security, 165
+<BR>OSF/1 (Digital Unix), 35
+<P><A NAME="P"><B>P</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>packets
+<BR> &nbsp; &nbsp; &nbsp; headers for, tcpdump utility and, 376
+<BR> &nbsp; &nbsp; &nbsp; maximum size of, option for, 243
+<BR>PAM (pluggable authentication modules), 179
+<BR> &nbsp; &nbsp; &nbsp; support for, 36
+<BR>panic action option, 244
+<BR>passwd chat debug option, 182
+<BR>passwd chat option, 182
+<BR>passwd program option, 182
+<BR>password file, security and, 53
+<BR>password level option, 182
+<BR>Password settings (Windows 95/98), 51
+<BR>passwords, 171-184
+<BR> &nbsp; &nbsp; &nbsp; chat characters for, 178
+<BR> &nbsp; &nbsp; &nbsp; encrypted
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; changing, 176
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; disabling on Windows computers, 173
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vs. non-encrypted, 172, 173
+<BR> &nbsp; &nbsp; &nbsp; null, 183
+<BR> &nbsp; &nbsp; &nbsp; options for, 180-184
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; share-level, 192
+<BR> &nbsp; &nbsp; &nbsp; passwd program, 182
+<BR> &nbsp; &nbsp; &nbsp; smbpasswd program, 374
+<BR> &nbsp; &nbsp; &nbsp; stored by Samba, 172
+<BR> &nbsp; &nbsp; &nbsp; synchronizing, 176-179
+<BR> &nbsp; &nbsp; &nbsp; user-level security and, 168
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98, 51-53
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; changing, 52
+<BR>pathnames
+<BR> &nbsp; &nbsp; &nbsp; option for, 98
+<BR> &nbsp; &nbsp; &nbsp; printer configuration and, 207
+<BR>paths, architecture-specific, 86
+<BR>pdate encrypted option, 183
+<BR>PDC (primary domain controller), 20
+<BR> &nbsp; &nbsp; &nbsp; domain master browser and, 119
+<BR> &nbsp; &nbsp; &nbsp; domain option for, 190
+<BR> &nbsp; &nbsp; &nbsp; domain-level security and, 164
+<BR>PDC (continued)
+<BR> &nbsp; &nbsp; &nbsp; Samba 2.1 and, 186
+<BR> &nbsp; &nbsp; &nbsp; Samba, setting up as, 184
+<BR> &nbsp; &nbsp; &nbsp; sever-level security and, 168
+<BR> &nbsp; &nbsp; &nbsp; trust accounts and, 186
+<BR>performance, 29
+<BR>performance tuning, 312-328
+<BR> &nbsp; &nbsp; &nbsp; benchmark for, 312, 314
+<BR> &nbsp; &nbsp; &nbsp; other options for, 319-328
+<BR> &nbsp; &nbsp; &nbsp; recommended enhancements, 320
+<BR>permissions, 207
+<BR> &nbsp; &nbsp; &nbsp; options for, 140-143
+<BR> &nbsp; &nbsp; &nbsp; for printing, 207
+<BR>plaintext passwords, 173
+<BR>pluggable authentication modules (PAM), 36, 179
+<BR>p-node, 13
+<BR>point-to-point communication, 13
+<BR>point-to-point registration/resolution, 13
+<BR>port not telnet option, 257
+<BR>postexec option, 199
+<BR>postscript option, 221
+<BR>preexec option, 199
+<BR>preferred master browser, 119
+<BR>preferred master option, 126
+<BR>preserve case option, 147
+<BR>preventing browsing, 115
+<BR>primary domain controller (see PDC)
+<BR>primary WINS server, 26
+<BR>print command option, 221
+<BR>print queue, options for, 223
+<BR>print shares, 7-9, 89-90, 204-205
+<BR> &nbsp; &nbsp; &nbsp; created by Samba, 205
+<BR> &nbsp; &nbsp; &nbsp; options for, 222
+<BR> &nbsp; &nbsp; &nbsp; path option, 98
+<BR> &nbsp; &nbsp; &nbsp; setting up on Windows client, 7
+<BR>printable option, 219
+<BR>printcap name option, 223
+<BR>printer capabilities file, 89
+<BR>printer driver file option, 219
+<BR>printer driver location option, 220
+<BR>printer driver option, 219
+<BR>printer option, 219
+<BR>PRINTER$ share, creating, 212
+<BR>printers
+<BR> &nbsp; &nbsp; &nbsp; BSD, 215
+<BR> &nbsp; &nbsp; &nbsp; names
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caution with, 205
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checking, 375
+<BR> &nbsp; &nbsp; &nbsp; option for, 219-221
+<BR> &nbsp; &nbsp; &nbsp; sharing (see print shares)
+<BR> &nbsp; &nbsp; &nbsp; System V, 216
+<BR>printing, 201-224
+<BR> &nbsp; &nbsp; &nbsp; commands, 202
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default commands for, 221
+<BR> &nbsp; &nbsp; &nbsp; configuration, minimal, 203-205
+<BR> &nbsp; &nbsp; &nbsp; configuration options, 203-207
+<BR> &nbsp; &nbsp; &nbsp; drivers for, setting up, 210-213
+<BR> &nbsp; &nbsp; &nbsp; on a network, steps in, 201
+<BR> &nbsp; &nbsp; &nbsp; options for, 217-224
+<BR> &nbsp; &nbsp; &nbsp; pathnames used in commands for, 207
+<BR> &nbsp; &nbsp; &nbsp; permissions for, 207
+<BR> &nbsp; &nbsp; &nbsp; print jobs, 204
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spooling with smbprint tool, 213
+<BR> &nbsp; &nbsp; &nbsp; printer definition file, 211
+<BR> &nbsp; &nbsp; &nbsp; resources for information on debugging, 208
+<BR> &nbsp; &nbsp; &nbsp; through Samba, 201-213
+<BR> &nbsp; &nbsp; &nbsp; test for, 206
+<BR> &nbsp; &nbsp; &nbsp; types, 218
+<BR> &nbsp; &nbsp; &nbsp; variables for, 203
+<BR> &nbsp; &nbsp; &nbsp; Windows client printers
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printing to, 213-224
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setting up and testing, 208
+<BR>printing configuration option, 218
+<BR>private directory (Samba distribution), 172
+<BR>private key cryptography, 35
+<BR>privileges, option for, 199
+<BR>processes (see daemons)
+<BR>profiles, 194
+<BR> &nbsp; &nbsp; &nbsp; creating, 53
+<BR> &nbsp; &nbsp; &nbsp; local, 194
+<BR> &nbsp; &nbsp; &nbsp; mandatory, 196
+<BR> &nbsp; &nbsp; &nbsp; roaming, 194-196
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; option for location of, 197
+<BR>programmers, support for, 230-233
+<BR>propagation, browse list, 24
+<BR>Properties button (Windows 95/98), 55
+<BR>protocols
+<BR> &nbsp; &nbsp; &nbsp; routed through a hardware device, 53
+<BR> &nbsp; &nbsp; &nbsp; variant, negotiating, 78
+<BR>Protocols tab, 65-66
+<P><A NAME="Q"><B>Q</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>queuepause command option, 223
+<BR>queueresume command option, 223
+<BR>quotation marks in values, 84
+<P><A NAME="R"><B>R</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>rc.local file, 47
+<BR>read list option, 161
+<BR>read only option, 100
+<BR>read prediction, testing, 318
+<BR>read raw, tuning, 315
+<BR>read size, tuning, 318
+<BR>reading documentation, importance of, 34
+<BR>read-only files, 136
+<BR> &nbsp; &nbsp; &nbsp; deleting, 139, 142
+<BR>read-only partitions, 40
+<BR>read-only/read-write access, 159
+<BR>remote announce option, 127
+<BR>remote browse sync option, 127
+<BR>remote procedure call (RPC), 376
+<BR>representing/resolving filenames, 145
+<BR>resource names, 14
+<BR>resource types, 14
+<BR> &nbsp; &nbsp; &nbsp; for primary domain controller vs. domain master browser, 24
+<BR>resources, connecting to, 81
+<BR>resources for further information, 291-293
+<BR> &nbsp; &nbsp; &nbsp; group attributes, 16
+<BR> &nbsp; &nbsp; &nbsp; NFS (Network File System), 293
+<BR> &nbsp; &nbsp; &nbsp; printers, debugging, 208
+<BR> &nbsp; &nbsp; &nbsp; Samba, 32
+<BR> &nbsp; &nbsp; &nbsp; Solaris servers, 321
+<BR> &nbsp; &nbsp; &nbsp; Windows network configuration commands, 192
+<BR>revalidation of users, 192
+<BR>roaming profiles, 194-196
+<BR> &nbsp; &nbsp; &nbsp; option for location of, 197
+<BR>role settings in elections, 117
+<BR>root postexec option, 199
+<BR>root preexec option, 198
+<BR>root user, 37, 199
+<BR> &nbsp; &nbsp; &nbsp; access, 159
+<BR>routers, TCP/IP configuring and, 68
+<BR>RPC (remote procedure call), 376
+<BR>rpcclient program, 376
+<P><A NAME="S"><B>S</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>SAM (security account manager), 19, 169
+<BR>Samba, 1-9
+<BR> &nbsp; &nbsp; &nbsp; compatibility with Windows NT, 30
+<BR> &nbsp; &nbsp; &nbsp; compiling (see compiling Samba)
+<BR> &nbsp; &nbsp; &nbsp; configuring (see configuring Samba)
+<BR> &nbsp; &nbsp; &nbsp; daemons (see daemons)
+<BR> &nbsp; &nbsp; &nbsp; distribution, xi, 28, 32
+<BR> &nbsp; &nbsp; &nbsp; documentation, importance of reading, 34
+<BR> &nbsp; &nbsp; &nbsp; downloading, 32-34
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with CVS, 378
+<BR> &nbsp; &nbsp; &nbsp; features/uses, x
+<BR> &nbsp; &nbsp; &nbsp; installing (see installing Samba)
+<BR> &nbsp; &nbsp; &nbsp; logging in for the first time, 52
+<BR> &nbsp; &nbsp; &nbsp; Microsoft encryption and, 30
+<BR> &nbsp; &nbsp; &nbsp; new features file, 34
+<BR> &nbsp; &nbsp; &nbsp; origin of name, 2
+<BR> &nbsp; &nbsp; &nbsp; performance tuning, 312-328
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; benchmark for, 312, 314
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; other options for, 319-328
+<BR> &nbsp; &nbsp; &nbsp; reasons for using, 3
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 291-293
+<BR> &nbsp; &nbsp; &nbsp; roles in Windows domains/workgroups, 26
+<BR> &nbsp; &nbsp; &nbsp; startup file, 363
+<BR> &nbsp; &nbsp; &nbsp; test utilities, 254-257
+<BR> &nbsp; &nbsp; &nbsp; version 2.0, 20, 28
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character sets, 235
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; code pages for, 234
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; coding system parameters, 235
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new options, 238
+<BR> &nbsp; &nbsp; &nbsp; version 2.0.5, xi, 28
+<BR> &nbsp; &nbsp; &nbsp; version 2.1, 20
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDC functionality and, 186
+<BR> &nbsp; &nbsp; &nbsp; web site, 32, 291
+<BR> &nbsp; &nbsp; &nbsp; WINS server and, 225
+<BR>Samba server
+<BR> &nbsp; &nbsp; &nbsp; accessing, 61
+<BR> &nbsp; &nbsp; &nbsp; connecting to, 71
+<BR> &nbsp; &nbsp; &nbsp; resources offered, 72
+<BR> &nbsp; &nbsp; &nbsp; sizing, 320-328
+<BR> &nbsp; &nbsp; &nbsp; viewing via Network Neighborhood icon, 72
+<BR>Samba Web Administration Tool (see SWAT tool)
+<BR>scripts
+<BR> &nbsp; &nbsp; &nbsp; connection, 198
+<BR> &nbsp; &nbsp; &nbsp; logon, 192-200
+<BR> &nbsp; &nbsp; &nbsp; magic, 233
+<BR> &nbsp; &nbsp; &nbsp; for Samba startup file, 363
+<BR>secondary WINS server, 26
+<BR>sections of smb.conf (Samba configuration) file, 83
+<BR>Secure Sockets Layer protocol (see SSL)
+<BR>security, 35, 164-171
+<BR> &nbsp; &nbsp; &nbsp; domain-level, 169-171
+<BR> &nbsp; &nbsp; &nbsp; levels of, 164
+<BR>security (continued)
+<BR> &nbsp; &nbsp; &nbsp; options for, 164
+<BR> &nbsp; &nbsp; &nbsp; restricting access to shares, 158-163
+<BR> &nbsp; &nbsp; &nbsp; server-level, 168
+<BR> &nbsp; &nbsp; &nbsp; share-level, 164-167
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options for, 167
+<BR> &nbsp; &nbsp; &nbsp; user-level, 167
+<BR>security account manager (SAM), 19, 169
+<BR>Select Network Protocol dialog box, 65
+<BR>server configuration options, 94-96
+<BR>Server Message Block (see SMB)
+<BR>server string parameter, 95
+<BR>server-level security, 168
+<BR>servers
+<BR> &nbsp; &nbsp; &nbsp; active, list of, 116
+<BR> &nbsp; &nbsp; &nbsp; testing with nmblookup program, 278
+<BR> &nbsp; &nbsp; &nbsp; virtual, 106-108
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options for, 107
+<BR>service bindings, 71
+<BR>services, 83
+<BR> &nbsp; &nbsp; &nbsp; list of enabled on machine, 45
+<BR> &nbsp; &nbsp; &nbsp; performed by Samba, 2
+<BR> &nbsp; &nbsp; &nbsp; testing low-level, 257-263
+<BR> &nbsp; &nbsp; &nbsp; Workstation, 65
+<BR> &nbsp; &nbsp; &nbsp; (see also shares)
+<BR>Services tab, 65
+<BR>session layer, connection at, 78
+<BR>session parameters, setting, 79
+<BR>session service, 10, 16-18
+<BR>set directory option, 244
+<BR>share modes, 151
+<BR>share options, 90
+<BR>shared directory/resources (see shares)
+<BR>shared resources (see shares)
+<BR>share-level security, 164-167
+<BR> &nbsp; &nbsp; &nbsp; options for, 167
+<BR> &nbsp; &nbsp; &nbsp; printing and guest accounts, 204
+<BR> &nbsp; &nbsp; &nbsp; steps in taken by Samba, 165
+<BR>shares, 30, 83
+<BR> &nbsp; &nbsp; &nbsp; access to
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; controlling, 158-163
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; creating for groups, 157
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; by foreign hosts, option for, 184
+<BR> &nbsp; &nbsp; &nbsp; contents, restricting view of, 115
+<BR> &nbsp; &nbsp; &nbsp; default, 115
+<BR> &nbsp; &nbsp; &nbsp; file, path option for, 98
+<BR> &nbsp; &nbsp; &nbsp; [globals] section, 88
+<BR> &nbsp; &nbsp; &nbsp; option for identifying users allowed access to, 168
+<BR> &nbsp; &nbsp; &nbsp; viewing (see browsing)
+<BR>sharing
+<BR> &nbsp; &nbsp; &nbsp; disks (see disk shares)
+<BR> &nbsp; &nbsp; &nbsp; printers (see print shares)
+<BR>Sharpe, Richard, 74
+<BR>SIGHUP signal, 85
+<BR>sizing Samba servers, 320-328
+<BR>smb passwd file option, 183
+<BR>SMB (Server Message Block), 2, 74-81
+<BR> &nbsp; &nbsp; &nbsp; command string, 75
+<BR> &nbsp; &nbsp; &nbsp; commercial products for, 77
+<BR> &nbsp; &nbsp; &nbsp; deny-mode locks, 151
+<BR> &nbsp; &nbsp; &nbsp; format of, 74
+<BR> &nbsp; &nbsp; &nbsp; header, 75
+<BR> &nbsp; &nbsp; &nbsp; magic scripts, 233
+<BR> &nbsp; &nbsp; &nbsp; making a simple connection, 77
+<BR> &nbsp; &nbsp; &nbsp; maximum number of operations, option for, 243
+<BR> &nbsp; &nbsp; &nbsp; networks, 4
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; usernames and, 162
+<BR> &nbsp; &nbsp; &nbsp; option for NT-specific options, 243
+<BR> &nbsp; &nbsp; &nbsp; password server, 168
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 74
+<BR> &nbsp; &nbsp; &nbsp; seamless operation across networks, 30
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting connections, 268-275
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; testing locally, 268
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; testing with NET USE, 271-274
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; testing with smbclient, 270
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; testing with Windows Explorer, 274-275
+<BR> &nbsp; &nbsp; &nbsp; wrapper support, 34
+<BR>SMB/CIFS protocol, 3
+<BR> &nbsp; &nbsp; &nbsp; filesystems, 34
+<BR> &nbsp; &nbsp; &nbsp; network and, 9-18
+<BR>smbclient program, 49, 364-370
+<BR>smb.conf (Samba configuration) file, 8, 41, 63, 82-93
+<BR> &nbsp; &nbsp; &nbsp; configuring printers, 203
+<BR> &nbsp; &nbsp; &nbsp; creating, 93
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for each client, 253
+<BR> &nbsp; &nbsp; &nbsp; example of, 82
+<BR> &nbsp; &nbsp; &nbsp; modifying for printer drivers, 212
+<BR> &nbsp; &nbsp; &nbsp; options for, 90-93
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; format of, 83
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; supporting programmers, 230-232
+<BR> &nbsp; &nbsp; &nbsp; special sections of, 88-91
+<BR> &nbsp; &nbsp; &nbsp; structure of, 83-86
+<BR> &nbsp; &nbsp; &nbsp; testparm program for, 375
+<BR> &nbsp; &nbsp; &nbsp; variables for, 86-88
+<BR>smbd daemon, 2, 82, 359-360
+<BR> &nbsp; &nbsp; &nbsp; file, 47
+<BR> &nbsp; &nbsp; &nbsp; killing, 48
+<BR> &nbsp; &nbsp; &nbsp; starting, 46
+<BR>smbd server, checking with telnet, 266
+<BR>smbmount, support for, 36
+<BR>smbpasswd file, 172, 174-176
+<BR> &nbsp; &nbsp; &nbsp; adding entries to, 175
+<BR> &nbsp; &nbsp; &nbsp; caution with, 173-174
+<BR> &nbsp; &nbsp; &nbsp; option for location of, 183
+<BR>smbpasswd program, 171, 374
+<BR> &nbsp; &nbsp; &nbsp; changing passwords with, 176
+<BR>smbprint tool, spooling print jobs, 213
+<BR>smbrun option, 244
+<BR>smbsh program, 364
+<BR>smbstatus program, 8, 370
+<BR>smbtar program, 245-248
+<BR> &nbsp; &nbsp; &nbsp; tar operations and, 371
+<BR>smbwrapper client, 30
+<BR>smbwrapper package, 35
+<BR>socket address option, 106
+<BR>socket options configuration options, 314
+<BR>software distribution (see Samba, distribution)
+<BR>source vs. binary files, 32
+<BR>spaces in values, 84
+<BR>special sections, smb.conf (Samba configuration) file, 88-91
+<BR>spelling, caution with, 61
+<BR>spool space, options for, 223
+<BR>square brackets, 83
+<BR>ssl CA certDir option, 308
+<BR>ssl CA certFile option, 308
+<BR>ssl ciphers option, 310
+<BR>ssl client cert option, 309
+<BR>ssl client key option, 309
+<BR>ssl compatibility option, 311
+<BR>ssl hosts option, 307
+<BR>ssl hosts resign option, 307
+<BR>ssl option, 307
+<BR>ssl require clientcert option, 309
+<BR>ssl require servercert option, 310
+<BR>SSL (Secure Sockets Layer) protocol, 30
+<BR> &nbsp; &nbsp; &nbsp; configuration options for, 306-311
+<BR> &nbsp; &nbsp; &nbsp; configuring Samba to use, 300
+<BR> &nbsp; &nbsp; &nbsp; configuring Samba with, 295-311
+<BR> &nbsp; &nbsp; &nbsp; SS Proxy, 296
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setting up, 304
+<BR> &nbsp; &nbsp; &nbsp; SSLeay, 296-304
+<BR> &nbsp; &nbsp; &nbsp; support for, 34, 36
+<BR>ssl server cert option, 308
+<BR>ssl server key option, 308
+<BR>ssl version option, 310
+<BR>stand-alone daemons, 47
+<BR>stat cache option, 239
+<BR>stat cache size option, 239
+<BR>status option, 244
+<BR>status report on Samba, 8
+<BR>strict locking option, 152, 319
+<BR>strict sync option, 245, 319
+<BR>string types, 90
+<BR>strip dot option, 245
+<BR>subnets, 12
+<BR> &nbsp; &nbsp; &nbsp; hosts and, caution with, 102
+<BR> &nbsp; &nbsp; &nbsp; mask, 57, 67
+<BR> &nbsp; &nbsp; &nbsp; multiple spanned by Windows workgroups, 24
+<BR> &nbsp; &nbsp; &nbsp; Windows NT workstations and, 24
+<BR>superuser (see root user)
+<BR>SWAT tool, 29
+<BR> &nbsp; &nbsp; &nbsp; adding to configuration files, 41
+<BR> &nbsp; &nbsp; &nbsp; creating configuration file with, 42
+<BR>sync always option, 245, 319
+<BR>synchronizing
+<BR> &nbsp; &nbsp; &nbsp; passwords, 176-179
+<BR> &nbsp; &nbsp; &nbsp; time, options for, 231
+<BR>syntax errors, 45
+<BR>syslog only option, 113
+<BR>syslog option, 113
+<BR>SYSLOG utility, 110
+<BR> &nbsp; &nbsp; &nbsp; support for, 36
+<BR>system administrator, WINS server and, 26
+<BR>system files, 136
+<BR>System V Unix, 47
+<BR> &nbsp; &nbsp; &nbsp; printer configuration for, 203
+<P><A NAME="T"><B>T</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>tar operations, 371
+<BR>tcpdump utility, 78, 255-257, 376
+<BR> &nbsp; &nbsp; &nbsp; passwords, reading, 172
+<BR>TCP/IP networking protocol, 9
+<BR> &nbsp; &nbsp; &nbsp; adding/configuring, 54
+<BR> &nbsp; &nbsp; &nbsp; checking setup, 53
+<BR> &nbsp; &nbsp; &nbsp; compared with NetBIOS, 10
+<BR> &nbsp; &nbsp; &nbsp; configuring, 66-71
+<BR> &nbsp; &nbsp; &nbsp; installing, 65
+<BR> &nbsp; &nbsp; &nbsp; NetBIOS over, 10
+<BR> &nbsp; &nbsp; &nbsp; receive window, tuning, 317
+<BR> &nbsp; &nbsp; &nbsp; resources for further information, 293
+<BR> &nbsp; &nbsp; &nbsp; TCP, troubleshooting, 263
+<BR>TCP/IP Properties panel (Windows 95/98), 55
+<BR>test parser, 45
+<BR>test share, 42
+<BR>testing
+<BR> &nbsp; &nbsp; &nbsp; configuration file, 45
+<BR> &nbsp; &nbsp; &nbsp; daemons, 49
+<BR> &nbsp; &nbsp; &nbsp; Samba, 41-46
+<BR> &nbsp; &nbsp; &nbsp; smbclient program, 364-370
+<BR> &nbsp; &nbsp; &nbsp; test utilities for Samba, 254-257
+<BR> &nbsp; &nbsp; &nbsp; tools for (CD-ROM with this book), 28
+<BR>testparm program, 375
+<BR>testparm test parser, 45
+<BR>testprns program, 375
+<BR>TID (tree identifier), 74, 78, 80
+<BR>time server option, 231
+<BR>time synchronization, options for, 231
+<BR>time to live (TTL), options for, 229
+<BR>timestamp logs option, 112
+<BR>trace utility, 254
+<BR>trailing dot, option for, 245
+<BR>tree identifier (TID), 74, 78, 80
+<BR>Tridgell, Andrew, 2, 255
+<BR>troubleshooting, 250-291
+<BR> &nbsp; &nbsp; &nbsp; information to have on hand, 257
+<BR> &nbsp; &nbsp; &nbsp; network addresses, 288-290
+<BR> &nbsp; &nbsp; &nbsp; where to start, 250
+<BR>trust accounts, creating, 186
+<BR>TTL (time to live), options for, 229
+<BR>tuning (see performance tuning)
+<P><A NAME="U"><B>U</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>umasks, 138
+<BR>uniform resource locators (URLs), 6
+<BR>Universal Naming Convention (UNC), 5
+<BR>Unix
+<BR> &nbsp; &nbsp; &nbsp; carriage returns, 193
+<BR> &nbsp; &nbsp; &nbsp; daemons, 2
+<BR> &nbsp; &nbsp; &nbsp; file permissions and attributes, 135-143
+<BR> &nbsp; &nbsp; &nbsp; filenames, option for, 245
+<BR> &nbsp; &nbsp; &nbsp; locks and, 150
+<BR> &nbsp; &nbsp; &nbsp; networks, usernames and, 162
+<BR> &nbsp; &nbsp; &nbsp; options
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for messaging, 237
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; miscellaneous, 240
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for print commands, 221
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for system logger, 113
+<BR> &nbsp; &nbsp; &nbsp; password files, 169
+<BR> &nbsp; &nbsp; &nbsp; permissions, share write access and, 159
+<BR> &nbsp; &nbsp; &nbsp; servers, backing up computers from, 246
+<BR> &nbsp; &nbsp; &nbsp; System V, 47
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printer configuration for, 203
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printing and, 29
+<BR> &nbsp; &nbsp; &nbsp; troubleshooting utilities, 254
+<BR> &nbsp; &nbsp; &nbsp; user classifications, 135
+<BR>unix password sync option, 180
+<BR>unix realname option, 133
+<BR>URLs (uniform resource locators), 6
+<BR> &nbsp; &nbsp; &nbsp; distribution, 28
+<BR> &nbsp; &nbsp; &nbsp; Kerberos, 35
+<BR> &nbsp; &nbsp; &nbsp; Samba, 28, 32
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distribution, xi
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; web site, 291
+<BR> &nbsp; &nbsp; &nbsp; SMB (Server Message Block), 74
+<BR>use rhosts option, 184
+<BR>user profiles (Windows 95/98), 50
+<BR>user variables, 86
+<BR>user-level security, 164, 167
+<BR>username level option, 163
+<BR>username map option, 162
+<BR>username option, 167
+<BR>usernames
+<BR> &nbsp; &nbsp; &nbsp; case sensitivity and, 163
+<BR> &nbsp; &nbsp; &nbsp; options for, 162-163
+<BR> &nbsp; &nbsp; &nbsp; SMB vs. Unix networks, 162
+<BR> &nbsp; &nbsp; &nbsp; Windows 95/98, 51-53
+<BR>users, 155-158
+<BR> &nbsp; &nbsp; &nbsp; allowing superuser (root) access to, 159
+<BR> &nbsp; &nbsp; &nbsp; creating, 89
+<BR> &nbsp; &nbsp; &nbsp; domain, semi-automatic deletion, 171
+<BR> &nbsp; &nbsp; &nbsp; home directory, 36
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logon script option for location of, 198
+<BR> &nbsp; &nbsp; &nbsp; invalid, specifying, 158
+<BR> &nbsp; &nbsp; &nbsp; read-only/read-write access, 159
+<BR> &nbsp; &nbsp; &nbsp; setting up, 155
+<BR> &nbsp; &nbsp; &nbsp; share-level option for authentication of, 192
+<BR> &nbsp; &nbsp; &nbsp; shares for, setting up, 157
+<BR>/usr/local/samba file, 40
+<BR>/usr/local/samba/var/log.smb file, 49
+<P><A NAME="V"><B>V</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>valid chars option, 236
+<BR>variables, 86-88
+<BR>veto files, 129-131
+<BR> &nbsp; &nbsp; &nbsp; option for deleting, 135
+<BR>veto files option, 134
+<BR>veto oplock files option, 154
+<BR>viewing daemons, 8
+<BR>virtual connection, 78
+<BR>virtual hosts, 29
+<BR>virtual servers, 106-108
+<BR> &nbsp; &nbsp; &nbsp; options for, 107
+<BR>volume option, 100
+<P><A NAME="W"><B>W</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+<BR>Whistle, 3
+<BR>whitespaces in values, 84
+<BR>wide links option, 134, 319
+<BR>Windows 95/98
+<BR> &nbsp; &nbsp; &nbsp; domain controllers for, 18-20
+<BR> &nbsp; &nbsp; &nbsp; domain logons, configuring, 185
+<BR> &nbsp; &nbsp; &nbsp; domains, 184-192
+<BR> &nbsp; &nbsp; &nbsp; miscellaneous options for, 240
+<BR> &nbsp; &nbsp; &nbsp; multiple users, support for, 50
+<BR> &nbsp; &nbsp; &nbsp; passwords, encrypted, 172
+<BR> &nbsp; &nbsp; &nbsp; printer drivers, installing, 210
+<BR> &nbsp; &nbsp; &nbsp; share-level security, support for, 165
+<BR> &nbsp; &nbsp; &nbsp; WinPopup tool, 237
+<BR>Windows clients
+<BR> &nbsp; &nbsp; &nbsp; configuring, 50-81
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Windows NT 4.0 computers, 63-73
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Windows95/98 computers, 50-63
+<BR> &nbsp; &nbsp; &nbsp; individual configuration files for, 253
+<BR> &nbsp; &nbsp; &nbsp; printers for, setting up and testing, 208
+<BR> &nbsp; &nbsp; &nbsp; role settings in elections, 117
+<BR>Windows Explorer, Map Network Drive option, 5
+<BR>Windows Internet Name Service (see WINS)
+<BR>Windows NT
+<BR> &nbsp; &nbsp; &nbsp; client/server and, 77
+<BR> &nbsp; &nbsp; &nbsp; configuring domain logons, 186
+<BR> &nbsp; &nbsp; &nbsp; domains, 18, 28, 184-192
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caution when selecting, 190
+<BR> &nbsp; &nbsp; &nbsp; IP address, setting, 67
+<BR> &nbsp; &nbsp; &nbsp; naming, caution with, 63
+<BR> &nbsp; &nbsp; &nbsp; passwords
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encrypted, 172
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new option for timeout (Samba version 2.0), 239
+<BR> &nbsp; &nbsp; &nbsp; pipes, option for, 243
+<BR> &nbsp; &nbsp; &nbsp; server, domain master browser and, 119
+<BR> &nbsp; &nbsp; &nbsp; SMB, option for, 243
+<BR> &nbsp; &nbsp; &nbsp; user authentication and, 186
+<BR> &nbsp; &nbsp; &nbsp; WINS address and, 70
+<BR>Windows NT Server 4.0, 65
+<BR>Windows NT Server Manager for Domains tool, 171
+<BR>Windows NT Workstation 4.0, 65
+<BR>Windows UNC format, 62
+<BR>Windows workgroups (see workgroups, Windows)
+<BR>WINDOWSHOSTS directory, 71
+<BR>WinPopup tool, 237
+<BR>WINS Address tab (Windows NT panel), 70
+<BR>WINS Configuration tab, 58
+<BR>wins proxy option, 228
+<BR>wins server option, 228
+<BR>wins support option, 228
+<BR>WINS (Windows Internet Name Service), 2, 25, 58
+<BR> &nbsp; &nbsp; &nbsp; address, configuring, 70
+<BR> &nbsp; &nbsp; &nbsp; name resolution and, 224
+<BR> &nbsp; &nbsp; &nbsp; options for, 228
+<BR> &nbsp; &nbsp; &nbsp; server, 44
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; configuring Windows domain logons and, 185
+<BR> &nbsp; &nbsp; &nbsp; servers, 25, 59
+<BR> &nbsp; &nbsp; &nbsp; Windows operating systems and, 26
+<BR> &nbsp; &nbsp; &nbsp; WINS server
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; primary/secondary, 26
+<BR>WINS (Windows Internet Name Service) server
+<BR> &nbsp; &nbsp; &nbsp; setting up Samba as, 226
+<BR> &nbsp; &nbsp; &nbsp; setting up Sambato use, 225
+<BR>Wong, Brian, 321
+<BR>workgroup parameter, 96
+<BR>workgroups, 4
+<BR> &nbsp; &nbsp; &nbsp; roles in assumed by Samba, 26
+<BR> &nbsp; &nbsp; &nbsp; setting, 60
+<BR> &nbsp; &nbsp; &nbsp; Windows
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; behaviors vs. Windows domain, 20
+<BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spanning multiple subnets, 24
+<BR>working directory, option for, 134
+<BR>Workstation service, installing, 65
+<BR>wrapper support for SMB (Server Message Block), 34
+<BR>write ahead, tuning, 318
+<BR>write list option, 161
+<BR>write privileges, 40
+<BR>write raw, tuning, 315
+<BR>write size, tuning, 317
+<BR>writeable/write ok option, 100
+<P><A NAME="Y"><B>Y</B><A HREF="inx.html">[&nbsp;Top&nbsp;]</A>
+
+<pre>
+</PRE>
+
+<P>
+<HR NOSHADE SIZE="-1">
+<P>
+Using Samba <a href="index.html">Table of Contents</a>
+<P>
+<CENTER>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/docs/htmldocs/using_samba/licenseinfo.html b/docs/htmldocs/using_samba/licenseinfo.html
new file mode 100755
index 00000000000..7e8962a8325
--- /dev/null
+++ b/docs/htmldocs/using_samba/licenseinfo.html
@@ -0,0 +1,181 @@
+<HTML>
+<HEAD>
+<TITLE>License Info</title>
+</head>
+
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font>
+By Robert Eckstein, David Collier-Brown & Peter Kelly
+<br>1st Edition October 1999 (est.)
+<br>1-56592-449-5, Order Number: 4495
+<br>424 pages (est.), $34.95 (est.)
+</font>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+<!--sample chapter begins -->
+<h2>License Info</h2>
+<p>"Using Samba" may be freely reproduced and distributed in any
+form, in any medium physical or electronic, in whole or in
+part, provided that the terms of this license are adhered to
+and that the reproduction includes this license or a reference
+to it. For a complete reproduction of the book, the reference
+should read:
+<blockquote>
+ Copyright (c) 1999 by O'Reilly & Associates. This book,
+ Using Samba, first edition, was written by Robert Eckstein,
+ David Collier-Brown, and Peter Kelly, and published by
+ O'Reilly & Associates. This material may be distributed only
+ subject to the terms and conditions set forth in the
+ license, which is presently available at
+ <a href="http://www.oreilly.com/catalog/samba/licenseinfo.html">
+ http://www.oreilly.com/catalog/samba/licenseinfo.html</a>.
+</blockquote>
+<p>
+For an excerpt, the reference should read:
+<blockquote>
+ Copyright (c) 1999 by O'Reilly & Associates. This material
+ was taken from the book Using Samba, first edition, written
+ by Robert Eckstein, David Collier-Brown, and Peter Kelly,
+ and published by O'Reilly & Associates. This material may be
+ distributed only subject to the terms and conditions set
+ forth in the license, which is presently available at
+ <a href="http://www.oreilly.com/catalog/samba/licenseinfo.html">
+ http://www.oreilly.com/catalog/samba/licenseinfo.html</a>.
+</blockquote>
+<p>
+Translations must contain similar references in the target
+language. A sample model for a reference in a translation is
+the following:
+<blockquote>
+ Copyright (c) 1999 by [whoever owns the translation]. This
+ is a translation of Using Samba, first edition, written by
+ Robert Eckstein, David Collier-Brown, and Peter Kelly, and
+ published by O'Reilly & Associates. This material may be
+ distributed only subject to the terms and conditions set
+ forth in the license, which is presently available at
+ <a href="http://www.oreilly.com/catalog/samba/licenseinfo.html">
+ http://www.oreilly.com/catalog/samba/licenseinfo.html</a>.
+</blockquote>
+<p>
+Both commercial and noncommercial redistribution of material
+from this book is permitted, but the following restrictions
+apply.
+<ol>
+<li> All copies of any version, including derivative works, must
+ display a prominent notice indicating the original authors
+ of the book and that it was originally developed by
+ O'Reilly & Associates. Any publication as a physical
+ (paper) book shall show the names of the authors and
+ O'Reilly & Associates on the outer surface.
+
+<li> Any changes made must be shared as described below.
+
+<li> No translation can be distributed publicly in print form
+ without approval from O'Reilly & Associates. Any
+ translation, by O'Reilly & Associates or another party,
+ falls under the same conditions as the original version.
+</ol>
+<p>
+MODIFIED VERSIONS. Distribution of any modified version must
+include a prominent notice describing the modifications that
+have been made, and must provide a URL or other sufficient
+information concerning how to obtain the original work.
+O'Reilly & Associates and the Samba Team are not responsible
+for the accuracy of any modifications not incorporated into
+their originally distributed version. The names of the
+original authors, O'Reilly & Associates, or the Samba team may
+not be used to assert or imply endorsement of the resulting
+document unless permission is obtained in advance. Anyone who
+distributes a version of the book with changes to text,
+figures, or any other element must provide the changed version
+in a standard source format to both O'Reilly and the Samba
+team, and must provide them under the same terms as the
+original book.
+<p>
+Mere aggregation of this work, or a portion of the work, with
+other works or programs on the same media shall not cause this
+license to apply to those other works. The aggregate work
+shall contain this license and a notice specifying the
+inclusion of this material.
+<p>
+The copyright will stay in O'Reilly's hands, unless O'Reilly stops
+printing the book. However, the book will be maintained by
+the Samba team. Any changes made by O'Reilly will be given to
+the team, and vice versa.
+<p>
+TRANSLATIONS. In the case of translations, O'Reilly will
+choose when to update and reprint printed versions. If
+O'Reilly lets the translation go out of print for more than 6
+months, the copyright and all other rights go to the Samba
+team.
+<p>
+SEVERABILITY. If any part of this license is found to be
+unenforceable in any jurisdiction, the remaining portions of
+the license remain in force.
+<p>
+NO WARRANTY. This work is licensed and provided "as is"
+without warranty of any kind, express or implied, including,
+but not limited to, the implied warranties of merchantability
+and fitness for a particular purpose or a warranty of
+non-infringement.
+<p>
+GOOD-PRACTICE RECOMMENDATIONS. In addition to the requirements
+of this license, it is requested from and strongly recommended
+of redistributors that:
+<ol>
+ <li> If you are distributing the work on hardcopy or CD-ROM,
+ you provide email notification to the authors of your
+ intent to redistribute at least thirty days before your
+ manuscript or media freeze, to give the authors time to
+ provide updated documents. This notification should
+ describe modifications, if any, made to the document.
+
+ <li> All substantive modifications (including deletions) should
+ be either clearly marked in the document or else described
+ in an attachment to the document.
+
+ <li> While it is not mandatory under this license, it is
+ considered good form to offer a free copy of any hardcopy
+ and CD-ROM expression of this work to its authors and the
+ original software developers.
+
+ <li> Translations should contain this license in the target
+ language.
+</ol>
+
+
+<!-- End of sample chapter -->
+<CENTER>
+<HR SIZE="1" NOSHADE>
+<FONT SIZE="1" FACE="Verdana, Arial, Helvetica">
+<A HREF="http://www.oreilly.com/">
+<B>O'Reilly Home</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/sales/bookstores">
+<B>O'Reilly Bookstores</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/order_new/">
+<B>How to Order</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/contact.html">
+<B>O'Reilly Contacts<BR></B></A>
+<A HREF="http://www.oreilly.com/international/">
+<B>International</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/oreilly/about.html">
+<B>About O'Reilly</B></A> <B> | </B>
+<A HREF="http://www.oreilly.com/affiliates.html">
+<B>Affiliated Companies</B></A><p>
+<EM>&copy; 1999, O'Reilly &amp; Associates, Inc.</EM>
+</FONT>
+</CENTER>
+</BODY>
+
+</html>
diff --git a/docs/htmldocs/using_samba/this_edition.html b/docs/htmldocs/using_samba/this_edition.html
new file mode 100755
index 00000000000..71522ac31e1
--- /dev/null
+++ b/docs/htmldocs/using_samba/this_edition.html
@@ -0,0 +1,48 @@
+<HTML>
+<HEAD>
+<TITLE>This Edition</title>
+</head>
+
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" link="#990000" vlink="#0000CC">
+<table BORDER="0" CELLPADDING="0" CELLSPACING="0" width="90%">
+<tr>
+<td width="25%" valign="TOP">
+<img hspace=10 vspace=10 src="gifs/samba.s.gif"
+alt="Using Samba" align=left valign=top border=0>
+</td>
+<td height="105" valign="TOP">
+<br>
+<H2>Using Samba</H2>
+<font>
+By Robert Eckstein, David Collier-Brown & Peter Kelly
+<br>1st Edition October 1999 (est.)
+<br>1-56592-449-5, Order Number: 4495
+<br>424 pages (est.), $34.95 (est.)
+</font>
+</td>
+</tr>
+</table>
+<hr size=1 noshade>
+
+<blockquote>
+ Copyright (c) 1999 by O'Reilly & Associates. This book,
+ Using Samba, first edition, was written by Robert Eckstein,
+ David Collier-Brown, and Peter Kelly, and published by
+ O'Reilly & Associates. This material may be distributed only
+ subject to the terms and conditions set forth in the
+ license, which is presently available at
+ <a href="http://www.oreilly.com/catalog/samba/licenseinfo.html">
+ http://www.oreilly.com/catalog/samba/licenseinfo.html</a>.
+</blockquote>
+
+<hr size=1 noshade>
+
+<pre>
+This is a modified version of the O'Reilly first edition of
+<i>Using Samba</i>. Some of the modifications were made by <a
+href="mailto:jayts@bigfoot.com">Jay Ts</a> - thanks Jay!
+
+</pre>
+
+</BODY>
+</html>
diff --git a/docs/htmldocs/wbinfo.1.html b/docs/htmldocs/wbinfo.1.html
new file mode 100755
index 00000000000..fe218a8f676
--- /dev/null
+++ b/docs/htmldocs/wbinfo.1.html
@@ -0,0 +1,382 @@
+<HTML
+><HEAD
+><TITLE
+>wbinfo</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="WBINFO"
+>wbinfo</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>wbinfo&nbsp;--&nbsp;Query information from winbind daemon</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>wbinfo</B
+> [-u] [-g] [-h name] [-i ip] [-n name] [-s sid] [-U uid] [-G gid] [-S sid] [-Y sid] [-t] [-m] [-r user] [-a user%password] [-A user%password]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN26"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This tool is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+>The <B
+CLASS="COMMAND"
+>wbinfo</B
+> program queries and returns information
+ created and used by the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+> winbindd(8)</B
+></A
+> daemon. </P
+><P
+>The <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> daemon must be configured
+ and running for the <B
+CLASS="COMMAND"
+>wbinfo</B
+> program to be able
+ to return information.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN37"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-u</DT
+><DD
+><P
+>This option will list all users available
+ in the Windows NT domain for which the <B
+CLASS="COMMAND"
+>winbindd(8)
+ </B
+> daemon is operating in. Users in all trusted domains
+ will also be listed. Note that this operation does not assign
+ user ids to any users that have not already been seen by
+ <B
+CLASS="COMMAND"
+>winbindd(8)</B
+>.</P
+></DD
+><DT
+>-g</DT
+><DD
+><P
+>This option will list all groups available
+ in the Windows NT domain for which the <B
+CLASS="COMMAND"
+>winbindd(8)
+ </B
+> daemon is operating in. Groups in all trusted domains
+ will also be listed. Note that this operation does not assign
+ group ids to any groups that have not already been seen by
+ <B
+CLASS="COMMAND"
+>winbindd(8)</B
+>. </P
+></DD
+><DT
+>-h name</DT
+><DD
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>-h</I
+></TT
+> option
+ queries <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> to query the WINS
+ server for the IP address associated with the NetBIOS name
+ specified by the <TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+> parameter.
+ </P
+></DD
+><DT
+>-i ip</DT
+><DD
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>-i</I
+></TT
+> option
+ queries <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> to send a node status
+ request to get the NetBIOS name associated with the IP address
+ specified by the <TT
+CLASS="PARAMETER"
+><I
+>ip</I
+></TT
+> parameter.
+ </P
+></DD
+><DT
+>-n name</DT
+><DD
+><P
+>The <TT
+CLASS="PARAMETER"
+><I
+>-n</I
+></TT
+> option
+ queries <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> for the SID
+ associated with the name specified. Domain names can be specified
+ before the user name by using the winbind separator character.
+ For example CWDOM1/Administrator refers to the Administrator
+ user in the domain CWDOM1. If no domain is specified then the
+ domain used is the one specified in the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+>
+ <TT
+CLASS="PARAMETER"
+><I
+>workgroup</I
+></TT
+> parameter. </P
+></DD
+><DT
+>-s sid</DT
+><DD
+><P
+>Use <TT
+CLASS="PARAMETER"
+><I
+>-s</I
+></TT
+> to resolve
+ a SID to a name. This is the inverse of the <TT
+CLASS="PARAMETER"
+><I
+>-n
+ </I
+></TT
+> option above. SIDs must be specified as ASCII strings
+ in the traditional Microsoft format. For example,
+ S-1-5-21-1455342024-3071081365-2475485837-500. </P
+></DD
+><DT
+>-U uid</DT
+><DD
+><P
+>Try to convert a UNIX user id to a Windows NT
+ SID. If the uid specified does not refer to one within
+ the winbind uid range then the operation will fail. </P
+></DD
+><DT
+>-G gid</DT
+><DD
+><P
+>Try to convert a UNIX group id to a Windows
+ NT SID. If the gid specified does not refer to one within
+ the winbind gid range then the operation will fail. </P
+></DD
+><DT
+>-S sid</DT
+><DD
+><P
+>Convert a SID to a UNIX user id. If the SID
+ does not correspond to a UNIX user mapped by <B
+CLASS="COMMAND"
+> winbindd(8)</B
+> then the operation will fail. </P
+></DD
+><DT
+>-Y sid</DT
+><DD
+><P
+>Convert a SID to a UNIX group id. If the SID
+ does not correspond to a UNIX group mapped by <B
+CLASS="COMMAND"
+> winbindd(8)</B
+> then the operation will fail. </P
+></DD
+><DT
+>-t</DT
+><DD
+><P
+>Verify that the workstation trust account
+ created when the Samba server is added to the Windows NT
+ domain is working. </P
+></DD
+><DT
+>-m</DT
+><DD
+><P
+>Produce a list of domains trusted by the
+ Windows NT server <B
+CLASS="COMMAND"
+>winbindd(8)</B
+> contacts
+ when resolving names. This list does not include the Windows
+ NT domain the server is a Primary Domain Controller for.
+ </P
+></DD
+><DT
+>-r username</DT
+><DD
+><P
+>Try to obtain the list of UNIX group ids
+ to which the user belongs. This only works for users
+ defined on a Domain Controller.
+ </P
+></DD
+><DT
+>-a username%password</DT
+><DD
+><P
+>Attempt to authenticate a user via winbindd.
+ This checks both authenticaion methods and reports its results.
+ </P
+></DD
+><DT
+>-A username%password</DT
+><DD
+><P
+>Store username and password used by winbindd
+ during session setup to a domain controller. This enables
+ winbindd to operate in a Windows 2000 domain with Restrict
+ Anonymous turned on (a.k.a. Permissions compatiable with
+ Windows 2000 servers only).
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN119"
+></A
+><H2
+>EXIT STATUS</H2
+><P
+>The wbinfo program returns 0 if the operation
+ succeeded, or 1 if the operation failed. If the <B
+CLASS="COMMAND"
+>winbindd(8)
+ </B
+> daemon is not working <B
+CLASS="COMMAND"
+>wbinfo</B
+> will always return
+ failure. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN124"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN127"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><A
+HREF="winbindd.8.html"
+TARGET="_top"
+><B
+CLASS="COMMAND"
+>winbindd(8)</B
+>
+ </A
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN132"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+><B
+CLASS="COMMAND"
+>wbinfo</B
+> and <B
+CLASS="COMMAND"
+>winbindd</B
+>
+ were written by Tim Potter.</P
+><P
+>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/wfw_slip.htm b/docs/htmldocs/wfw_slip.htm
new file mode 100755
index 00000000000..5b4a0a5e539
--- /dev/null
+++ b/docs/htmldocs/wfw_slip.htm
@@ -0,0 +1,175 @@
+<HTML>
+<HEAD>
+<TITLE>Peter Karrer Announces SLIP for WFW</TITLE>
+</HEAD>
+<BODY>
+<H1><I>Winserve</I></H1>
+<HR>
+<H2><I>Peter Karrer Announces SLIP for WFW</I></H2>
+[NEW 03-22-95)
+<HR>
+<B>Hello,</B>
+<P>
+I've discovered a way to run WfW's TCP/IP-32 over a SLIP packet driver. This
+allows WfW users to do Windows networking over dialup lines just like it is
+possible with NT and the Windows 95 beta!
+<P>
+For instance, you can mount Microsoft's FTP server as a network drive in File
+Manager or connect to an MS Mail post office over the Internet. Of course,
+the usual Internet stuff works as well. Another interesting site is
+WINSERVE.001; check out www.winserve.com.
+<HR>
+This method should work with any class 1 (Ethernet II) packet driver. However,
+I'm not in a position to try anything else than SLIPPER/CSLIPPER.
+<HR>
+<H3>Files you need:</H3>
+<B>WFWT32.EXE:</B> ftp://ftp.microsoft.com/bussys/msclient/wfw/wfwt32.exe
+<P>
+ Microsoft's free TCP/IP for WfW. It's a self-extracting archive which
+ should be executed in an empty directory.
+<P>
+<B>SLIPPER.EXE:</B> ftp://biocserver.bioc.cwru.edu/pub/dos/slipper/slippr15.zip
+<P>
+ Peter Tattam's SLIP packet driver. CSLIPPER.EXE is a variant which supports
+ VJ header compression.
+<P>
+<B>PDETHER.EXE:</B> ftp://sjf-lwp.idz.sjf.novell.com/odi/pdether/pde105.zip
+<P>
+ Don Provan's ODI-over-Packet Driver shim. This *must* be version 1.05 (or
+ above).
+<P>
+<B>LSL.COM:</B>
+<P>
+ Novell's LAN Support Layer. If you're an owner of Windows 3.10, you'll
+ have it on one of your install disks. Use "expand a:lsl.co_ lsl.com" to
+ expand it. Microsoft has stopped bundling LSL.COM with WfW 3.11, though.
+ The newest version of LSL.COM can be downloaded as part of
+ ftp://ftp.novell.com/pub/netware/nwos/dosclnt12/vlms/vlmup2.exe.
+ However, it's not clear if this one may be legally used outside Netware
+ environments.
+<P>
+<B>NET.CFG:</B>
+<P>
+ A configuration file for LSL and PDETHER. It should contain the following
+ text:
+<P>
+<PRE>
+Link Support
+ Buffers 8 1600
+Link Driver PDETHER
+ Int 60
+ Frame Ethernet_II
+ Protocol IP 800 Ethernet_II
+ Protocol ARP 806 Ethernet_II
+ Protocol RARP 8035 Ethernet_II
+</PRE>
+<P>
+<B>DISCOMX.COM:</B>
+<P>
+ A little hack of mine to disable the COM port used by the SLIP packet driver.
+ Usage is e.g. "discomx 2" to disable COM2. This should be run before
+ starting WfW, otherwise you'll get "device conflict" messages. Here it is:
+<P><PRE>
+begin 644 discomx.com
+F,=N)V8H.@`"P(+^!`/.N3XH="=MT!DN`XP/1XS')!R:)CP`$S2``
+`
+end
+ </PRE>
+ (Save this text to disk as <I>filename</I>, then run "uudecode <I>filename</I>".
+ uudecode can be found, for instance, at
+ ftp://ftp.switch.ch/mirror/simtel/msdos/starter/uudecode.com )
+<P>
+<B>LMHOSTS:</B>
+ <P>
+ An optional file which should be stored in your Windows subdirectory. It is
+ used to map NetBIOS computer names to IP addresses. Example:
+<P>
+<PRE>
+198.105.232.1 ftp #PRE # ftp.microsoft.com
+204.118.34.11 winserve.001 #PRE # Winserve
+</PRE>
+<HR>
+<H3>How to install it:</H3>
+<P>
+<UL>
+<LI>Put the files mentioned above into a directory, e.g. C:\SLIP.
+<P>
+<LI>Put the following lines into AUTOEXEC.BAT:
+<P><PRE>
+ cd \slip
+ slipper com1 vec=60 baud=57600 ether (may vary with your modem setup)
+ lsl
+ pdether
+ discomx 1 (must correspond to SLIPPER's COM port)
+</PRE>
+ (If you use another vec= setting, you must update that in NET.CFG as well.)
+ Use CSLIPPER instead of SLIPPER if your SLIP provider supports VJC.
+<P>
+<LI>Start WfW.
+<UL>
+<LI>Under Windows Setup, choose "Change Network Settings".
+<LI>Select "Install Microsoft Windows Network".
+<LI>In "Drivers...", choose "Add Adapter"
+ and install the "IPXODI Support driver (Ethernet) [ODI/NDIS3]".
+<LI>In "Add Protocols...", select "Unlisted or Updated Protocol". When asked for a
+ driver disk, enter the directory where you expanded WFWT32.EXE.
+<LI>Configure TCP/IP (IP address, enable LMHOSTS lookup, try 204.118.34.11 as primary
+ WINS server). Remove all other protocols (NetBEUI, IPX/SPX).
+</UL>
+<P>
+<LI>Windows will probably update the first lines of AUTOEXEC.BAT with
+<P>
+<PRE>
+ c:\windows\net start
+ c:\windows\odihlp.exe.
+</PRE>
+ The "odihlp" line must be moved behind the "pdether" line.
+<P>
+<LI>Windows will also update NET.CFG with some "Frame" lines. These must
+ be removed (except "Frame Ethernet_II").
+<P>
+<LI>Somehow, you will have to dial in to your SLIP provider. I do it manually
+ before slipper (or cslipper) gets loaded, using a DOS-based terminal program.
+ But there are some automatic dialers around. I've seen recommendations for
+ ftp://mvmpc9.ciw.uni-karlsruhe.de/x-slip/slip_it.exe.
+<P>
+<LI>To connect to Microsoft's FTP server (or Winserve) go into File Manager,
+ choose "Connect Network drive" and enter "\\ftp" or "\\winserve.001" into
+ the "Path:" field.
+</UL>
+<HR>
+<H3>How it works:</H3>
+<P>
+Microsoft's TCP/IP-32 requires an NDIS3 interface. NDIS is Microsoft's way
+to interface with a network.
+<P>
+WfW also contains an NDIS3-over-ODI "shim", whose real mode component is
+ODIHLP.EXE. ODI is Novell's way to interface with a network.
+<P>
+SLIPPER is a Packet Driver (PD) for use over serial lines. PDs are everybody
+else's way to interface with a network. SLIPPER's "ether" option makes it
+look like an Ethernet PD to applications using it.
+<P>
+A "shim" is a program which simulates a network application programming
+interface on top of another.
+<P>
+There is no NDIS SLIP driver which would work with WfW.
+<P>
+There is no NDIS-over-PD shim.
+<P>
+However, there's an ODI-over-PD shim (PDETHER) and an NDIS-over-ODI shim
+(ODIHLP etc.)
+<P>
+OK, so let's do NDIS-over-ODI-over-PD!
+ <P>
+This should have worked all the time; however, a non-feature in PDETHER
+versions < 1.05 has prevented the method from functioning until now.
+<HR>
+<B>Questions, suggestions etc. please to
+<P>
+<PRE>
+Peter Karrer pkarrer@ife.ee.ethz.ch
+</PRE>
+</B>
+</BODY>
+</HTML>
diff --git a/docs/htmldocs/winbind.html b/docs/htmldocs/winbind.html
new file mode 100755
index 00000000000..bb18545c5b8
--- /dev/null
+++ b/docs/htmldocs/winbind.html
@@ -0,0 +1,1211 @@
+<HTML
+><HEAD
+><TITLE
+>Unified Logons between Windows NT and UNIX using Winbind</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="WINBIND"
+>Unified Logons between Windows NT and UNIX using Winbind</A
+></H1
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN3"
+>Abstract</A
+></H1
+><P
+>Integration of UNIX and Microsoft Windows NT through
+ a unified logon has been considered a "holy grail" in heterogeneous
+ computing environments for a long time. We present
+ <I
+CLASS="EMPHASIS"
+>winbind</I
+>, a component of the Samba suite
+ of programs as a solution to the unified logon problem. Winbind
+ uses a UNIX implementation
+ of Microsoft RPC calls, Pluggable Authentication Modules, and the Name
+ Service Switch to allow Windows NT domain users to appear and operate
+ as UNIX users on a UNIX machine. This paper describes the winbind
+ system, explaining the functionality it provides, how it is configured,
+ and how it works internally.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN7"
+>Introduction</A
+></H1
+><P
+>It is well known that UNIX and Microsoft Windows NT have
+ different models for representing user and group information and
+ use different technologies for implementing them. This fact has
+ made it difficult to integrate the two systems in a satisfactory
+ manner.</P
+><P
+>One common solution in use today has been to create
+ identically named user accounts on both the UNIX and Windows systems
+ and use the Samba suite of programs to provide file and print services
+ between the two. This solution is far from perfect however, as
+ adding and deleting users on both sets of machines becomes a chore
+ and two sets of passwords are required both of which
+ can lead to synchronization problems between the UNIX and Windows
+ systems and confusion for users.</P
+><P
+>We divide the unified logon problem for UNIX machines into
+ three smaller problems:</P
+><P
+></P
+><UL
+><LI
+><P
+>Obtaining Windows NT user and group information
+ </P
+></LI
+><LI
+><P
+>Authenticating Windows NT users
+ </P
+></LI
+><LI
+><P
+>Password changing for Windows NT users
+ </P
+></LI
+></UL
+><P
+>Ideally, a prospective solution to the unified logon problem
+ would satisfy all the above components without duplication of
+ information on the UNIX machines and without creating additional
+ tasks for the system administrator when maintaining users and
+ groups on either system. The winbind system provides a simple
+ and elegant solution to all three components of the unified logon
+ problem.</P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN20"
+>What Winbind Provides</A
+></H1
+><P
+>Winbind unifies UNIX and Windows NT account management by
+ allowing a UNIX box to become a full member of a NT domain. Once
+ this is done the UNIX box will see NT users and groups as if
+ they were native UNIX users and groups, allowing the NT domain
+ to be used in much the same manner that NIS+ is used within
+ UNIX-only environments.</P
+><P
+>The end result is that whenever any
+ program on the UNIX machine asks the operating system to lookup
+ a user or group name, the query will be resolved by asking the
+ NT domain controller for the specified domain to do the lookup.
+ Because Winbind hooks into the operating system at a low level
+ (via the NSS name resolution modules in the C library) this
+ redirection to the NT domain controller is completely
+ transparent.</P
+><P
+>Users on the UNIX machine can then use NT user and group
+ names as they would use "native" UNIX names. They can chown files
+ so that they are owned by NT domain users or even login to the
+ UNIX machine and run a UNIX X-Window session as a domain user.</P
+><P
+>The only obvious indication that Winbind is being used is
+ that user and group names take the form DOMAIN\user and
+ DOMAIN\group. This is necessary as it allows Winbind to determine
+ that redirection to a domain controller is wanted for a particular
+ lookup and which trusted domain is being referenced.</P
+><P
+>Additionally, Winbind provides an authentication service
+ that hooks into the Pluggable Authentication Modules (PAM) system
+ to provide authentication via a NT domain to any PAM enabled
+ applications. This capability solves the problem of synchronizing
+ passwords between systems since all passwords are stored in a single
+ location (on the domain controller).</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN27"
+>Target Uses</A
+></H2
+><P
+>Winbind is targeted at organizations that have an
+ existing NT based domain infrastructure into which they wish
+ to put UNIX workstations or servers. Winbind will allow these
+ organizations to deploy UNIX workstations without having to
+ maintain a separate account infrastructure. This greatly
+ simplifies the administrative overhead of deploying UNIX
+ workstations into a NT based organization.</P
+><P
+>Another interesting way in which we expect Winbind to
+ be used is as a central part of UNIX based appliances. Appliances
+ that provide file and print services to Microsoft based networks
+ will be able to use Winbind to provide seamless integration of
+ the appliance into the domain.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN31"
+>How Winbind Works</A
+></H1
+><P
+>The winbind system is designed around a client/server
+ architecture. A long running <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+ listens on a UNIX domain socket waiting for requests
+ to arrive. These requests are generated by the NSS and PAM
+ clients and processed sequentially.</P
+><P
+>The technologies used to implement winbind are described
+ in detail below.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN36"
+>Microsoft Remote Procedure Calls</A
+></H2
+><P
+>Over the last two years, efforts have been underway
+ by various Samba Team members to decode various aspects of
+ the Microsoft Remote Procedure Call (MSRPC) system. This
+ system is used for most network related operations between
+ Windows NT machines including remote management, user authentication
+ and print spooling. Although initially this work was done
+ to aid the implementation of Primary Domain Controller (PDC)
+ functionality in Samba, it has also yielded a body of code which
+ can be used for other purposes.</P
+><P
+>Winbind uses various MSRPC calls to enumerate domain users
+ and groups and to obtain detailed information about individual
+ users or groups. Other MSRPC calls can be used to authenticate
+ NT domain users and to change user passwords. By directly querying
+ a Windows PDC for user and group information, winbind maps the
+ NT account information onto UNIX user and group names.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN40"
+>Name Service Switch</A
+></H2
+><P
+>The Name Service Switch, or NSS, is a feature that is
+ present in many UNIX operating systems. It allows system
+ information such as hostnames, mail aliases and user information
+ to be resolved from different sources. For example, a standalone
+ UNIX workstation may resolve system information from a series of
+ flat files stored on the local filesystem. A networked workstation
+ may first attempt to resolve system information from local files,
+ and then consult a NIS database for user information or a DNS server
+ for hostname information.</P
+><P
+>The NSS application programming interface allows winbind
+ to present itself as a source of system information when
+ resolving UNIX usernames and groups. Winbind uses this interface,
+ and information obtained from a Windows NT server using MSRPC
+ calls to provide a new source of account enumeration. Using standard
+ UNIX library calls, one can enumerate the users and groups on
+ a UNIX machine running winbind and see all users and groups in
+ a NT domain plus any trusted domain as though they were local
+ users and groups.</P
+><P
+>The primary control file for NSS is
+ <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>.
+ When a UNIX application makes a request to do a lookup
+ the C library looks in <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+>
+ for a line which matches the service type being requested, for
+ example the "passwd" service type is used when user or group names
+ are looked up. This config line species which implementations
+ of that service should be tried and in what order. If the passwd
+ config line is:</P
+><P
+><B
+CLASS="COMMAND"
+>passwd: files example</B
+></P
+><P
+>then the C library will first load a module called
+ <TT
+CLASS="FILENAME"
+>/lib/libnss_files.so</TT
+> followed by
+ the module <TT
+CLASS="FILENAME"
+>/lib/libnss_example.so</TT
+>. The
+ C library will dynamically load each of these modules in turn
+ and call resolver functions within the modules to try to resolve
+ the request. Once the request is resolved the C library returns the
+ result to the application.</P
+><P
+>This NSS interface provides a very easy way for Winbind
+ to hook into the operating system. All that needs to be done
+ is to put <TT
+CLASS="FILENAME"
+>libnss_winbind.so</TT
+> in <TT
+CLASS="FILENAME"
+>/lib/</TT
+>
+ then add "winbind" into <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> at
+ the appropriate place. The C library will then call Winbind to
+ resolve user and group names.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN56"
+>Pluggable Authentication Modules</A
+></H2
+><P
+>Pluggable Authentication Modules, also known as PAM,
+ is a system for abstracting authentication and authorization
+ technologies. With a PAM module it is possible to specify different
+ authentication methods for different system applications without
+ having to recompile these applications. PAM is also useful
+ for implementing a particular policy for authorization. For example,
+ a system administrator may only allow console logins from users
+ stored in the local password file but only allow users resolved from
+ a NIS database to log in over the network.</P
+><P
+>Winbind uses the authentication management and password
+ management PAM interface to integrate Windows NT users into a
+ UNIX system. This allows Windows NT users to log in to a UNIX
+ machine and be authenticated against a suitable Primary Domain
+ Controller. These users can also change their passwords and have
+ this change take effect directly on the Primary Domain Controller.
+ </P
+><P
+>PAM is configured by providing control files in the directory
+ <TT
+CLASS="FILENAME"
+>/etc/pam.d/</TT
+> for each of the services that
+ require authentication. When an authentication request is made
+ by an application the PAM code in the C library looks up this
+ control file to determine what modules to load to do the
+ authentication check and in what order. This interface makes adding
+ a new authentication service for Winbind very easy, all that needs
+ to be done is that the <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> module
+ is copied to <TT
+CLASS="FILENAME"
+>/lib/security/</TT
+> and the PAM
+ control files for relevant services are updated to allow
+ authentication via winbind. See the PAM documentation
+ for more details.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN64"
+>User and Group ID Allocation</A
+></H2
+><P
+>When a user or group is created under Windows NT
+ is it allocated a numerical relative identifier (RID). This is
+ slightly different to UNIX which has a range of numbers that are
+ used to identify users, and the same range in which to identify
+ groups. It is winbind's job to convert RIDs to UNIX id numbers and
+ vice versa. When winbind is configured it is given part of the UNIX
+ user id space and a part of the UNIX group id space in which to
+ store Windows NT users and groups. If a Windows NT user is
+ resolved for the first time, it is allocated the next UNIX id from
+ the range. The same process applies for Windows NT groups. Over
+ time, winbind will have mapped all Windows NT users and groups
+ to UNIX user ids and group ids.</P
+><P
+>The results of this mapping are stored persistently in
+ an ID mapping database held in a tdb database). This ensures that
+ RIDs are mapped to UNIX IDs in a consistent way.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN68"
+>Result Caching</A
+></H2
+><P
+>An active system can generate a lot of user and group
+ name lookups. To reduce the network cost of these lookups winbind
+ uses a caching scheme based on the SAM sequence number supplied
+ by NT domain controllers. User or group information returned
+ by a PDC is cached by winbind along with a sequence number also
+ returned by the PDC. This sequence number is incremented by
+ Windows NT whenever any user or group information is modified. If
+ a cached entry has expired, the sequence number is requested from
+ the PDC and compared against the sequence number of the cached entry.
+ If the sequence numbers do not match, then the cached information
+ is discarded and up to date information is requested directly
+ from the PDC.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN71"
+>Installation and Configuration</A
+></H1
+><P
+>Many thanks to John Trostel <A
+HREF="mailto:jtrostel@snapserver.com"
+TARGET="_top"
+>jtrostel@snapserver.com</A
+>
+for providing the original Linux version of this HOWTO which
+describes how to get winbind services up and running
+to control access and authenticate users on your Linux box using
+the winbind services which are included with the SAMBA 2.2.2 and later
+releases.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN75"
+>Introduction</A
+></H2
+><P
+>This HOWTO describes the procedures used to get winbind up and
+running on a RedHat 7.1 system. Winbind is capable of providing access
+and authentication control for Windows Domain users through an NT
+or Win2K PDC for 'regular' services, such as telnet and ftp, as
+well providing dynamic uid/gid allocation for Samba.</P
+><P
+>This HOWTO has been written from a 'RedHat-centric' perspective, so if
+you are using another distribution (or operating system), you may have
+to modify the instructions somewhat to fit the way your distribution works.</P
+><P
+></P
+><UL
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>Why should I to this?</I
+>
+ </P
+><P
+>This allows the SAMBA administrator to rely on the
+ authentication mechanisms on the NT/Win2K PDC for the authentication
+ of domain members. NT/Win2K users no longer need to have separate
+ accounts on the SAMBA server.
+ </P
+></LI
+><LI
+><P
+> <I
+CLASS="EMPHASIS"
+>Who should be reading this document?</I
+>
+ </P
+><P
+> This HOWTO is designed for system administrators. If you are
+ implementing SAMBA on a file server and wish to (fairly easily)
+ integrate existing NT/Win2K users from your PDC onto the
+ SAMBA server, this HOWTO is for you.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN88"
+>Requirements</A
+></H2
+><P
+>If you have a samba configuration file that you are currently
+using... <I
+CLASS="EMPHASIS"
+>BACK IT UP!</I
+> If your system already uses PAM,
+<I
+CLASS="EMPHASIS"
+>back up the <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+>)
+directory contents!</I
+> If you haven't already made a boot disk,
+<I
+CLASS="EMPHASIS"
+>MAKE ONE NOW!</I
+></P
+><P
+>Messing with the pam configuration files can make it nearly impossible
+to log in to your machine. That's why you want to be able to boot back
+into your machine in single user mode and restore your
+<TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>pam.conmf</TT
+>) back to
+the original state they were in if
+you get frustrated with the way things are going.</P
+><P
+>The first SAMBA release to inclue a stable winbindd daemon was 2.2.2. Please refer to the
+<A
+HREF="http://samba.org/"
+TARGET="_top"
+>main SAMBA web page</A
+> or,
+better yet, your closest SAMBA mirror site for instructions on
+downloading the source code. it is generally advised to obtain the lates
+Samba release as bugs are constantly being fixed.</P
+><P
+>To allow Domain users the ability to access SAMBA shares and
+files, as well as potentially other services provided by your
+SAMBA machine, PAM (pluggable authentication modules) must
+be setup properly on your machine. In order to compile the
+winbind modules, you must have at the PAM libraries and header files resident
+on your system. For recent RedHat systems (7.x, for instance), that
+means installing both <TT
+CLASS="FILENAME"
+>pam</TT
+> and <TT
+CLASS="FILENAME"
+>pam-devel</TT
+> RPM.
+The former is installed by default on all Linux systems of which the author is aware.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN104"
+>Testing Things Out</A
+></H2
+><P
+>Before starting, kill off all the SAMBA related daemons running on your server. Kill off
+all <B
+CLASS="COMMAND"
+>smbd</B
+>, <B
+CLASS="COMMAND"
+>nmbd</B
+>, and <B
+CLASS="COMMAND"
+>winbindd</B
+> processes that may
+be running (<B
+CLASS="COMMAND"
+>winbindd</B
+> will only be running if you have ao previous Winbind
+installation...but why would you be reading tis if that were the case?). To use PAM, you will
+want to make sure that you have the standard PAM package (for RedHat) which supplies the <TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+>
+directory structure, including the pam modules are used by pam-aware
+services, several pam libraries, and the <TT
+CLASS="FILENAME"
+>/usr/doc</TT
+>
+and <TT
+CLASS="FILENAME"
+>/usr/man</TT
+> entries for pam. Samba will require
+the pam-devel package if you plan to build the <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> library or
+include the <B
+CLASS="COMMAND"
+>--with-pam</B
+> option to the configure script.
+This package includes the header files needed to compile pam-aware applications.</P
+><P
+>[I have no idea which Solaris packages are quired for PAM libraries and
+development files. If you know, please mail me the information and I will include
+it in the next revision of this HOWTO. --jerry@samba.org]</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN117"
+>Configure and Compile SAMBA</A
+></H3
+><P
+>The configuration and compilation of SAMBA is straightforward.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>./configure --with-winbind</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make install</B
+></PRE
+></P
+><P
+>This will, by default, install SAMBA in <TT
+CLASS="FILENAME"
+>/usr/local/samba</TT
+>.
+See the main SAMBA documentation if you want to install SAMBA somewhere else.
+It will also build the winbindd executable and NSS library.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN130"
+>Configure <TT
+CLASS="FILENAME"
+>nsswitch.conf</TT
+> and the
+winbind libraries</A
+></H3
+><P
+>The libraries needed to run the <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+through nsswitch need to be copied to their proper locations.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>cp nsswitch/libnss_winbind.so /lib</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>chmod 755 /lib/libnss_winbind.so</B
+></P
+><P
+>It necessary to make the following symbolic link:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>ln -s /lib/libnss_winbind.so /lib/libnss_winbind.so.2</B
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>.2</TT
+> extension is due to the version of glibc used on your Linux host.
+for most modern systems, the file extension is correct. However, some other operating systems,
+Solaris 7/8 being the most common, the destination filename should be replaced with
+<TT
+CLASS="FILENAME"
+>/lib/nss_winbind.so.1</TT
+></P
+><P
+>Now, as root edit <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> to
+allow user and group entries to be visible from the <B
+CLASS="COMMAND"
+>winbindd</B
+>
+daemon. After editing, the file look appear:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+> passwd: files winbind
+ shadow: files
+ group: files winbind</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN152"
+>Configure <TT
+CLASS="FILENAME"
+>smb.conf</TT
+></A
+></H3
+><P
+>Several parameters are needed in the smb.conf file to control
+the behavior of <B
+CLASS="COMMAND"
+>winbindd</B
+>. Configure
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> These are described in more detail in
+the <A
+HREF="winbindd.8.html"
+TARGET="_top"
+>winbindd(8)</A
+> man page. My
+<TT
+CLASS="FILENAME"
+>smb.conf</TT
+> file was modified to
+include the following entries in the [global] section:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ &#60;...&#62;
+ # separate domain and username with '+', like DOMAIN+username
+ <A
+HREF="winbindd.8.html#WINBINDSEPARATOR"
+TARGET="_top"
+>winbind separator</A
+> = +
+ # use uids from 10000 to 20000 for domain users
+ <A
+HREF="winbindd.8.html#WINBINDUID"
+TARGET="_top"
+>winbind uid</A
+> = 10000-20000
+ # use gids from 10000 to 20000 for domain groups
+ <A
+HREF="winbindd.8.html#WINBINDGID"
+TARGET="_top"
+>winbind gid</A
+> = 10000-20000
+ # allow enumeration of winbind users and groups
+ # might need to disable these next two for performance
+ # reasons on the winbindd host
+ <A
+HREF="winbindd.8.html#WINBINDENUMUSERS"
+TARGET="_top"
+>winbind enum users</A
+> = yes
+ <A
+HREF="winbindd.8.html#WINBINDENUMGROUP"
+TARGET="_top"
+>winbind enum groups</A
+> = yes
+ # give winbind users a real shell (only needed if they have telnet/sshd/etc... access)
+ <A
+HREF="winbindd.8.html#TEMPLATEHOMEDIR"
+TARGET="_top"
+>template homedir</A
+> = /home/winnt/%D/%U
+ <A
+HREF="winbindd.8.html#TEMPLATESHELL"
+TARGET="_top"
+>template shell</A
+> = /bin/bash</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN169"
+>Join the SAMBA server to the PDC domain</A
+></H3
+><P
+>Enter the following command to make the SAMBA server join the
+PDC domain, where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+> is the name of
+your Windows domain and <TT
+CLASS="REPLACEABLE"
+><I
+>Administrator</I
+></TT
+> is
+a domain user who has administrative privileges in the domain.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/usr/local/samba/bin/smbpasswd -j DOMAIN -r PDC -U Administrator</B
+></P
+><P
+>The proper response to the command should be: "Joined the domain
+<TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+>" where <TT
+CLASS="REPLACEABLE"
+><I
+>DOMAIN</I
+></TT
+>
+is your DOMAIN name.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN180"
+>Start up the winbindd daemon and test it!</A
+></H3
+><P
+>Eventually, you will want to modify your smb startup script to
+automatically invoke the winbindd daemon when the other parts of
+SAMBA start, but it is possible to test out just the winbind
+portion first. To start up winbind services, enter the following
+command as root:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>export PATH=$PATH:/usr/local/samba/bin</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>winbindd</B
+></P
+><P
+>I'm always paranoid and like to make sure the daemon
+is really running...</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>ps -ae | grep winbindd</B
+></P
+><P
+>This command should produce output like this, if the daemon is running</P
+><P
+>3025 ? 00:00:00 winbindd</P
+><P
+>Note that a sample RedHat init script for starting winbindd is included in
+the SAMBA sourse distribution as <TT
+CLASS="FILENAME"
+>packaging/RedHat/winbind.init</TT
+>.</P
+><P
+>Now... for the real test, try to get some information about the
+users on your PDC</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>wbinfo -u</B
+></P
+><P
+>This should echo back a list of users on your Windows users on
+your PDC. For example, I get the following response:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>CEO+Administrator
+CEO+burdell
+CEO+Guest
+CEO+jt-ad
+CEO+krbtgt
+CEO+TsInternetUser</PRE
+></P
+><P
+>Obviously, I have named my domain 'CEO' and my <TT
+CLASS="PARAMETER"
+><I
+>winbind
+separator</I
+></TT
+> is '+'.</P
+><P
+>You can do the same sort of thing to get group information from
+the PDC:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/usr/local/samba/bin/wbinfo -g</B
+>
+CEO+Domain Admins
+CEO+Domain Users
+CEO+Domain Guests
+CEO+Domain Computers
+CEO+Domain Controllers
+CEO+Cert Publishers
+CEO+Schema Admins
+CEO+Enterprise Admins
+CEO+Group Policy Creator Owners</PRE
+></P
+><P
+>The function 'getent' can now be used to get unified
+lists of both local and PDC users and groups.
+Try the following command:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>getent passwd</B
+></P
+><P
+>You should get a list that looks like your <TT
+CLASS="FILENAME"
+>/etc/passwd</TT
+>
+list followed by the domain users with their new uids, gids, home
+directories and default shells. If you do not, verify that the permissions on the
+libnss_winbind.so library are <TT
+CLASS="FILENAME"
+>rwxr-xr-x</TT
+>.</P
+><P
+>The same thing can be done for groups with the command</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>getent group</B
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN221"
+>Configure Winbind and PAM</A
+></H3
+><P
+>At this point we are assured that <B
+CLASS="COMMAND"
+>winbindd</B
+> and <B
+CLASS="COMMAND"
+>smbd</B
+>
+are working together. If you want to use winbind to provide authentication for other
+services, keep reading. The pam configuration files need to be altered in
+this step. (Did you remember to make backups of your original
+<TT
+CLASS="FILENAME"
+>/etc/pam.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+>) file[s]? If not, do it now.)</P
+><P
+>You will need a PAM module to use <B
+CLASS="COMMAND"
+>winbindd</B
+> with these other services. This
+module will be compiled in the <TT
+CLASS="FILENAME"
+>../source/nsswitch</TT
+> directory
+by invoking the command</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make nsswitch/pam_winbind.so</B
+></P
+><P
+>from the <TT
+CLASS="FILENAME"
+>../source</TT
+> directory. The
+<TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+> file should be copied to the location of
+your other pam security modules. On Linux and Solaris systems, this is the
+<TT
+CLASS="FILENAME"
+>/lib/security</TT
+> directory.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>cp nsswitch/pam_winbind.so /lib/security</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>chmod 755 /lib/security/pam_winbind.so</B
+></P
+><P
+>Other services, such as the normal login on the console (or a terminal
+session), telnet logins, and ftp service, can be modified to allow the use of winbind
+as an authentication service. In order to enable these
+services, you may first need to change the entries in
+<TT
+CLASS="FILENAME"
+>/etc/xinetd.d</TT
+> (or <TT
+CLASS="FILENAME"
+>/etc/inetd.conf</TT
+>).
+RedHat 7.1 uses the new xinetd.d structure, in this case you need
+to change the lines in <TT
+CLASS="FILENAME"
+>/etc/xinetd.d/telnet</TT
+>
+and <TT
+CLASS="FILENAME"
+>/etc/xinetd.d/wu-ftp</TT
+> from</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>enable = no</PRE
+></P
+><P
+>to</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>enable = yes</PRE
+></P
+><P
+>For ftp services to work properly, you will also need to either
+have individual directories for the domain users already present on
+the server, or change the home directory template to a general
+directory for all domain users. These can be easily set using
+the <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> global entry
+<B
+CLASS="COMMAND"
+>template homedir</B
+>.</P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/pam.d/ftp</TT
+> file can be changed
+to allow winbind ftp access in a manner similar to the
+samba file. My <TT
+CLASS="FILENAME"
+>/etc/pam.d/ftp</TT
+> file was
+changed to look like this:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>auth required /lib/security/pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_shells.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth</PRE
+></P
+><P
+>The <TT
+CLASS="FILENAME"
+>/etc/pam.d/login</TT
+> file can be changed nearly the
+same way. It now looks like this:</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>auth required /lib/security/pam_securetty.so
+auth sufficient /lib/security/pam_winbind.so
+auth sufficient /lib/security/pam_unix.so use_first_pass
+auth required /lib/security/pam_stack.so service=system-auth
+auth required /lib/security/pam_nologin.so
+account sufficient /lib/security/pam_winbind.so
+account required /lib/security/pam_stack.so service=system-auth
+password required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth
+session optional /lib/security/pam_console.so</PRE
+></P
+><P
+>In this case, I added the <B
+CLASS="COMMAND"
+>auth sufficient /lib/security/pam_winbind.so</B
+>
+lines as before, but also added the <B
+CLASS="COMMAND"
+>required pam_securetty.so</B
+>
+above it, to disallow root logins over the network. I also added a
+<B
+CLASS="COMMAND"
+>sufficient /lib/security/pam_unix.so use_first_pass</B
+>
+line after the <B
+CLASS="COMMAND"
+>winbind.so</B
+> line to get rid of annoying
+double prompts for passwords.</P
+><P
+>Note that a Solaris <TT
+CLASS="FILENAME"
+>/etc/pam.conf</TT
+> confiruation file looks
+very similar to this except thaty the service name is included as the first entry
+per line. An example for the login service is given here.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>## excerpt from /etc/pam.conf on a Solaris 8 system
+login auth required /lib/security/pam_winbind.so
+login auth required /lib/security/$ISA/pam_unix.so.1 try_first_pass
+login auth required /lib/security/$ISA/pam_dial_auth.so.1 try_first_pass</PRE
+></P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN274"
+>Limitations</A
+></H1
+><P
+>Winbind has a number of limitations in its current
+ released version that we hope to overcome in future
+ releases:</P
+><P
+></P
+><UL
+><LI
+><P
+>The mappings of Windows NT RIDs to UNIX ids
+ is not made algorithmically and depends on the order in which
+ unmapped users or groups are seen by winbind. It may be difficult
+ to recover the mappings of rid to UNIX id mapping if the file
+ containing this information is corrupted or destroyed.</P
+></LI
+><LI
+><P
+>Currently the winbind PAM module does not take
+ into account possible workstation and logon time restrictions
+ that may be been set for Windows NT users.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN282"
+>Conclusion</A
+></H1
+><P
+>The winbind system, through the use of the Name Service
+ Switch, Pluggable Authentication Modules, and appropriate
+ Microsoft RPC calls have allowed us to provide seamless
+ integration of Microsoft Windows NT domain users on a
+ UNIX system. The result is a great reduction in the administrative
+ cost of running a mixed UNIX and NT network.</P
+></DIV
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/htmldocs/winbindd.8.html b/docs/htmldocs/winbindd.8.html
new file mode 100755
index 00000000000..5d76dae2fdc
--- /dev/null
+++ b/docs/htmldocs/winbindd.8.html
@@ -0,0 +1,964 @@
+<HTML
+><HEAD
+><TITLE
+>winbindd</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.57"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="WINBINDD"
+>winbindd</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN5"
+></A
+><H2
+>Name</H2
+>winbindd&nbsp;--&nbsp;Name Service Switch daemon for resolving names
+ from NT servers</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Synopsis</H2
+><P
+><B
+CLASS="COMMAND"
+>winbindd</B
+> [-i] [-d &#60;debug level&#62;] [-s &#60;smb config file&#62;]</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN14"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>This program is part of the <A
+HREF="samba.7.html"
+TARGET="_top"
+> Samba</A
+> suite.</P
+><P
+><B
+CLASS="COMMAND"
+>winbindd</B
+> is a daemon that provides
+ a service for the Name Service Switch capability that is present
+ in most modern C libraries. The Name Service Switch allows user
+ and system information to be obtained from different databases
+ services such as NIS or DNS. The exact behaviour can be configured
+ throught the <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file.
+ Users and groups are allocated as they are resolved to a range
+ of user and group ids specified by the administrator of the
+ Samba system.</P
+><P
+>The service provided by <B
+CLASS="COMMAND"
+>winbindd</B
+> is called `winbind' and
+ can be used to resolve user and group information from a
+ Windows NT server. The service can also provide authentication
+ services via an associated PAM module. </P
+><P
+> The <TT
+CLASS="FILENAME"
+>pam_winbind</TT
+> module in the 2.2.2 release only
+ supports the <TT
+CLASS="PARAMETER"
+><I
+>auth</I
+></TT
+> and <TT
+CLASS="PARAMETER"
+><I
+>account</I
+></TT
+>
+ module-types. The latter is simply
+ performs a getpwnam() to verify that the system can obtain a uid for the
+ user. If the <TT
+CLASS="FILENAME"
+>libnss_winbind</TT
+> library has been correctly
+ installed, this should always suceed.
+ </P
+><P
+>The following nsswitch databases are implemented by
+ the winbindd service: </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>hosts</DT
+><DD
+><P
+>User information traditionally stored in
+ the <TT
+CLASS="FILENAME"
+>hosts(5)</TT
+> file and used by
+ <B
+CLASS="COMMAND"
+>gethostbyname(3)</B
+> functions. Names are
+ resolved through the WINS server or by broadcast.
+ </P
+></DD
+><DT
+>passwd</DT
+><DD
+><P
+>User information traditionally stored in
+ the <TT
+CLASS="FILENAME"
+>passwd(5)</TT
+> file and used by
+ <B
+CLASS="COMMAND"
+>getpwent(3)</B
+> functions. </P
+></DD
+><DT
+>group</DT
+><DD
+><P
+>Group information traditionally stored in
+ the <TT
+CLASS="FILENAME"
+>group(5)</TT
+> file and used by
+ <B
+CLASS="COMMAND"
+>getgrent(3)</B
+> functions. </P
+></DD
+></DL
+></DIV
+><P
+>For example, the following simple configuration in the
+ <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file can be used to initially
+ resolve user and group information from <TT
+CLASS="FILENAME"
+>/etc/passwd
+ </TT
+> and <TT
+CLASS="FILENAME"
+>/etc/group</TT
+> and then from the
+ Windows NT server. </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>passwd: files winbind
+group: files winbind
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>The following simple configuration in the
+ <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file can be used to initially
+ resolve hostnames from <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+> and then from the
+ WINS server.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>OPTIONS</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>-d debuglevel</DT
+><DD
+><P
+>Sets the debuglevel to an integer between
+ 0 and 100. 0 is for no debugging and 100 is for reams and
+ reams. To submit a bug report to the Samba Team, use debug
+ level 100 (see BUGS.txt). </P
+></DD
+><DT
+>-i</DT
+><DD
+><P
+>Tells <B
+CLASS="COMMAND"
+>winbindd</B
+> to not
+ become a daemon and detach from the current terminal. This
+ option is used by developers when interactive debugging
+ of <B
+CLASS="COMMAND"
+>winbindd</B
+> is required. </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN70"
+></A
+><H2
+>NAME AND ID RESOLUTION</H2
+><P
+>Users and groups on a Windows NT server are assigned
+ a relative id (rid) which is unique for the domain when the
+ user or group is created. To convert the Windows NT user or group
+ into a unix user or group, a mapping between rids and unix user
+ and group ids is required. This is one of the jobs that <B
+CLASS="COMMAND"
+> winbindd</B
+> performs. </P
+><P
+>As winbindd users and groups are resolved from a server, user
+ and group ids are allocated from a specified range. This
+ is done on a first come, first served basis, although all existing
+ users and groups will be mapped as soon as a client performs a user
+ or group enumeration command. The allocated unix ids are stored
+ in a database file under the Samba lock directory and will be
+ remembered. </P
+><P
+>WARNING: The rid to unix id database is the only location
+ where the user and group mappings are stored by winbindd. If this
+ file is deleted or corrupted, there is no way for winbindd to
+ determine which user and group ids correspond to Windows NT user
+ and group rids. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN76"
+></A
+><H2
+>CONFIGURATION</H2
+><P
+>Configuration of the <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+ is done through configuration parameters in the <TT
+CLASS="FILENAME"
+>smb.conf(5)
+ </TT
+> file. All parameters should be specified in the
+ [global] section of smb.conf. </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>winbind separator</DT
+><DD
+><P
+>The winbind separator option allows you
+ to specify how NT domain names and user names are combined
+ into unix user names when presented to users. By default,
+ <B
+CLASS="COMMAND"
+>winbindd</B
+> will use the traditional '\'
+ separator so that the unix user names look like
+ DOMAIN\username. In some cases this separator character may
+ cause problems as the '\' character has special meaning in
+ unix shells. In that case you can use the winbind separator
+ option to specify an alternative separator character. Good
+ alternatives may be '/' (although that conflicts
+ with the unix directory separator) or a '+ 'character.
+ The '+' character appears to be the best choice for 100%
+ compatibility with existing unix utilities, but may be an
+ aesthetically bad choice depending on your taste. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind separator = \ </B
+>
+ </P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind separator = + </B
+></P
+></DD
+><DT
+>winbind uid</DT
+><DD
+><P
+>The winbind uid parameter specifies the
+ range of user ids that are allocated by the winbindd daemon.
+ This range of ids should have no existing local or NIS users
+ within it as strange conflicts can occur otherwise. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind uid = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind uid = 10000-20000</B
+></P
+></DD
+><DT
+>winbind gid</DT
+><DD
+><P
+>The winbind gid parameter specifies the
+ range of group ids that are allocated by the winbindd daemon.
+ This range of group ids should have no existing local or NIS
+ groups within it as strange conflicts can occur otherwise.</P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind gid = &#60;empty string&#62;
+ </B
+></P
+><P
+>Example: <B
+CLASS="COMMAND"
+>winbind gid = 10000-20000
+ </B
+> </P
+></DD
+><DT
+>winbind cache time</DT
+><DD
+><P
+>This parameter specifies the number of
+ seconds the winbindd daemon will cache user and group information
+ before querying a Windows NT server again. When a item in the
+ cache is older than this time winbindd will ask the domain
+ controller for the sequence number of the server's account database.
+ If the sequence number has not changed then the cached item is
+ marked as valid for a further <TT
+CLASS="PARAMETER"
+><I
+>winbind cache time
+ </I
+></TT
+> seconds. Otherwise the item is fetched from the
+ server. This means that as long as the account database is not
+ actively changing winbindd will only have to send one sequence
+ number query packet every <TT
+CLASS="PARAMETER"
+><I
+>winbind cache time
+ </I
+></TT
+> seconds. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind cache time = 15</B
+>
+ </P
+></DD
+><DT
+>winbind enum users</DT
+><DD
+><P
+>On large installations it may be necessary
+ to suppress the enumeration of users through the <B
+CLASS="COMMAND"
+> setpwent()</B
+>, <B
+CLASS="COMMAND"
+>getpwent()</B
+> and
+ <B
+CLASS="COMMAND"
+>endpwent()</B
+> group of system calls. If
+ the <TT
+CLASS="PARAMETER"
+><I
+>winbind enum users</I
+></TT
+> parameter is false,
+ calls to the <B
+CLASS="COMMAND"
+>getpwent</B
+> system call will not
+ return any data. </P
+><P
+><EM
+>Warning:</EM
+> Turning off user enumeration
+ may cause some programs to behave oddly. For example, the <B
+CLASS="COMMAND"
+>finger</B
+>
+ program relies on having access to the full user list when
+ searching for matching usernames. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind enum users = yes </B
+></P
+></DD
+><DT
+>winbind enum groups</DT
+><DD
+><P
+>On large installations it may be necessary
+ to suppress the enumeration of groups through the <B
+CLASS="COMMAND"
+> setgrent()</B
+>, <B
+CLASS="COMMAND"
+>getgrent()</B
+> and
+ <B
+CLASS="COMMAND"
+>endgrent()</B
+> group of system calls. If
+ the <TT
+CLASS="PARAMETER"
+><I
+>winbind enum groups</I
+></TT
+> parameter is
+ false, calls to the <B
+CLASS="COMMAND"
+>getgrent()</B
+> system
+ call will not return any data. </P
+><P
+><EM
+>Warning:</EM
+> Turning off group
+ enumeration may cause some programs to behave oddly.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>winbind enum groups = no </B
+>
+ </P
+></DD
+><DT
+>template homedir</DT
+><DD
+><P
+>When filling out the user information
+ for a Windows NT user, the <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+ uses this parameter to fill in the home directory for that user.
+ If the string <TT
+CLASS="PARAMETER"
+><I
+>%D</I
+></TT
+> is present it is
+ substituted with the user's Windows NT domain name. If the
+ string <TT
+CLASS="PARAMETER"
+><I
+>%U</I
+></TT
+> is present it is substituted
+ with the user's Windows NT user name. </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>template homedir = /home/%D/%U </B
+>
+ </P
+></DD
+><DT
+>template shell</DT
+><DD
+><P
+>When filling out the user information for
+ a Windows NT user, the <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon
+ uses this parameter to fill in the shell for that user.
+ </P
+><P
+>Default: <B
+CLASS="COMMAND"
+>template shell = /bin/false </B
+>
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN158"
+></A
+><H2
+>EXAMPLE SETUP</H2
+><P
+>To setup winbindd for user and group lookups plus
+ authentication from a domain controller use something like the
+ following setup. This was tested on a RedHat 6.2 Linux box. </P
+><P
+>In <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> put the
+ following:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>passwd: files winbind
+group: files winbind
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>In <TT
+CLASS="FILENAME"
+>/etc/pam.d/*</TT
+> replace the
+ <TT
+CLASS="PARAMETER"
+><I
+>auth</I
+></TT
+> lines with something like this: </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>auth required /lib/security/pam_securetty.so
+auth required /lib/security/pam_nologin.so
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_pwdb.so use_first_pass shadow nullok
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Note in particular the use of the <TT
+CLASS="PARAMETER"
+><I
+>sufficient</I
+></TT
+>
+ keyword and the <TT
+CLASS="PARAMETER"
+><I
+>use_first_pass</I
+></TT
+> keyword. </P
+><P
+>Now replace the account lines with this: </P
+><P
+><B
+CLASS="COMMAND"
+>account required /lib/security/pam_winbind.so
+ </B
+></P
+><P
+>The next step is to join the domain. To do that use the
+ <B
+CLASS="COMMAND"
+>smbpasswd</B
+> program like this: </P
+><P
+><B
+CLASS="COMMAND"
+>smbpasswd -j DOMAIN -r PDC -U
+ Administrator</B
+></P
+><P
+>The username after the <TT
+CLASS="PARAMETER"
+><I
+>-U</I
+></TT
+> can be any
+ Domain user that has administrator privileges on the machine.
+ Substitute your domain name for "DOMAIN" and the name of your PDC
+ for "PDC".</P
+><P
+>Next copy <TT
+CLASS="FILENAME"
+>libnss_winbind.so</TT
+> to
+ <TT
+CLASS="FILENAME"
+>/lib</TT
+> and <TT
+CLASS="FILENAME"
+>pam_winbind.so</TT
+>
+ to <TT
+CLASS="FILENAME"
+>/lib/security</TT
+>. A symbolic link needs to be
+ made from <TT
+CLASS="FILENAME"
+>/lib/libnss_winbind.so</TT
+> to
+ <TT
+CLASS="FILENAME"
+>/lib/libnss_winbind.so.2</TT
+>. If you are using an
+ older version of glibc then the target of the link should be
+ <TT
+CLASS="FILENAME"
+>/lib/libnss_winbind.so.1</TT
+>.</P
+><P
+>Finally, setup a <TT
+CLASS="FILENAME"
+>smb.conf</TT
+> containing directives like the
+ following: </P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>[global]
+ winbind separator = +
+ winbind cache time = 10
+ template shell = /bin/bash
+ template homedir = /home/%D/%U
+ winbind uid = 10000-20000
+ winbind gid = 10000-20000
+ workgroup = DOMAIN
+ security = domain
+ password server = *
+ </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Now start winbindd and you should find that your user and
+ group database is expanded to include your NT users and groups,
+ and that you can login to your unix box as a domain user, using
+ the DOMAIN+user syntax for the username. You may wish to use the
+ commands <B
+CLASS="COMMAND"
+>getent passwd</B
+> and <B
+CLASS="COMMAND"
+>getent group
+ </B
+> to confirm the correct operation of winbindd.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN197"
+></A
+><H2
+>NOTES</H2
+><P
+>The following notes are useful when configuring and
+ running <B
+CLASS="COMMAND"
+>winbindd</B
+>: </P
+><P
+><B
+CLASS="COMMAND"
+>nmbd</B
+> must be running on the local machine
+ for <B
+CLASS="COMMAND"
+>winbindd</B
+> to work. <B
+CLASS="COMMAND"
+>winbindd</B
+>
+ queries the list of trusted domains for the Windows NT server
+ on startup and when a SIGHUP is received. Thus, for a running <B
+CLASS="COMMAND"
+> winbindd</B
+> to become aware of new trust relationships between
+ servers, it must be sent a SIGHUP signal. </P
+><P
+>Client processes resolving names through the <B
+CLASS="COMMAND"
+>winbindd</B
+>
+ nsswitch module read an environment variable named <TT
+CLASS="ENVAR"
+> $WINBINDD_DOMAIN</TT
+>. If this variable contains a comma separated
+ list of Windows NT domain names, then winbindd will only resolve users
+ and groups within those Windows NT domains. </P
+><P
+>PAM is really easy to misconfigure. Make sure you know what
+ you are doing when modifying PAM configuration files. It is possible
+ to set up PAM such that you can no longer log into your system. </P
+><P
+>If more than one UNIX machine is running <B
+CLASS="COMMAND"
+>winbindd</B
+>,
+ then in general the user and groups ids allocated by winbindd will not
+ be the same. The user and group ids will only be valid for the local
+ machine.</P
+><P
+>If the the Windows NT RID to UNIX user and group id mapping
+ file is damaged or destroyed then the mappings will be lost. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN213"
+></A
+><H2
+>SIGNALS</H2
+><P
+>The following signals can be used to manipulate the
+ <B
+CLASS="COMMAND"
+>winbindd</B
+> daemon. </P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>SIGHUP</DT
+><DD
+><P
+>Reload the <TT
+CLASS="FILENAME"
+>smb.conf(5)</TT
+>
+ file and apply any parameter changes to the running
+ version of winbindd. This signal also clears any cached
+ user and group information. The list of other domains trusted
+ by winbindd is also reloaded. </P
+></DD
+><DT
+>SIGUSR1</DT
+><DD
+><P
+>The SIGUSR1 signal will cause <B
+CLASS="COMMAND"
+> winbindd</B
+> to write status information to the winbind
+ log file including information about the number of user and
+ group ids allocated by <B
+CLASS="COMMAND"
+>winbindd</B
+>.</P
+><P
+>Log files are stored in the filename specified by the
+ log file parameter.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN230"
+></A
+><H2
+>FILES</H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf(5)</TT
+></DT
+><DD
+><P
+>Name service switch configuration file.</P
+></DD
+><DT
+>/tmp/.winbindd/pipe</DT
+><DD
+><P
+>The UNIX pipe over which clients communicate with
+ the <B
+CLASS="COMMAND"
+>winbindd</B
+> program. For security reasons, the
+ winbind client will only attempt to connect to the winbindd daemon
+ if both the <TT
+CLASS="FILENAME"
+>/tmp/.winbindd</TT
+> directory
+ and <TT
+CLASS="FILENAME"
+>/tmp/.winbindd/pipe</TT
+> file are owned by
+ root. </P
+></DD
+><DT
+>/lib/libnss_winbind.so.X</DT
+><DD
+><P
+>Implementation of name service switch library.
+ </P
+></DD
+><DT
+>$LOCKDIR/winbindd_idmap.tdb</DT
+><DD
+><P
+>Storage for the Windows NT rid to UNIX user/group
+ id mapping. The lock directory is specified when Samba is initially
+ compiled using the <TT
+CLASS="PARAMETER"
+><I
+>--with-lockdir</I
+></TT
+> option.
+ This directory is by default <TT
+CLASS="FILENAME"
+>/usr/local/samba/var/locks
+ </TT
+>. </P
+></DD
+><DT
+>$LOCKDIR/winbindd_cache.tdb</DT
+><DD
+><P
+>Storage for cached user and group information.
+ </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN259"
+></A
+><H2
+>VERSION</H2
+><P
+>This man page is correct for version 2.2 of
+ the Samba suite.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN262"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><TT
+CLASS="FILENAME"
+>nsswitch.conf(5)</TT
+>,
+ <A
+HREF="samba.7.html"
+TARGET="_top"
+>samba(7)</A
+>,
+ <A
+HREF="wbinfo.1.html"
+TARGET="_top"
+>wbinfo(1)</A
+>,
+ <A
+HREF="smb.conf.5.html"
+TARGET="_top"
+>smb.conf(5)</A
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN269"
+></A
+><H2
+>AUTHOR</H2
+><P
+>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</P
+><P
+><B
+CLASS="COMMAND"
+>wbinfo</B
+> and <B
+CLASS="COMMAND"
+>winbindd</B
+>
+ were written by Tim Potter.</P
+><P
+>The conversion to DocBook for Samba 2.2 was done
+ by Gerald Carter</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/docs/manpages/findsmb.1 b/docs/manpages/findsmb.1
new file mode 100755
index 00000000000..c498abede02
--- /dev/null
+++ b/docs/manpages/findsmb.1
@@ -0,0 +1,90 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "FINDSMB" "1" "19 November 2002" "" ""
+.SH NAME
+findsmb \- list info about machines that respond to SMB name queries on a subnet
+.SH SYNOPSIS
+.sp
+\fBfindsmb\fR [ \fBsubnet broadcast address\fR ]
+.SH "DESCRIPTION"
+.PP
+This perl script is part of the Samba suite.
+.PP
+\fBfindsmb\fR is a perl script that
+prints out several pieces of information about machines
+on a subnet that respond to SMB name query requests.
+It uses \fB nmblookup(1)\fR to obtain this information.
+.SH "OPTIONS"
+.TP
+\fBsubnet broadcast address\fR
+Without this option, \fBfindsmb
+\fRwill probe the subnet of the machine where
+\fBfindsmb\fR is run. This value is passed
+to \fBnmblookup\fR as part of the
+-B option
+.SH "EXAMPLES"
+.PP
+The output of \fBfindsmb\fR lists the following
+information for all machines that respond to the initial
+\fBnmblookup\fR for any name: IP address, NetBIOS name,
+Workgroup name, operating system, and SMB server version.
+.PP
+There will be a '+' in front of the workgroup name for
+machines that are local master browsers for that workgroup. There
+will be an '*' in front of the workgroup name for
+machines that are the domain master browser for that workgroup.
+Machines that are running Windows, Windows 95 or Windows 98 will
+not show any information about the operating system or server
+version.
+.PP
+The command must be run on a system without \fBnmbd\fR running.
+If \fBnmbd\fR is running on the system, you will
+only get the IP address and the DNS name of the machine. To
+get proper responses from Windows 95 and Windows 98 machines,
+the command must be run as root.
+.PP
+For example running \fBfindsmb\fR on a machine
+without \fBnmbd\fR running would yield output similar
+to the following
+.sp
+.nf
+IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION
+---------------------------------------------------------------------
+192.168.35.10 MINESET-TEST1 [DMVENGR]
+192.168.35.55 LINUXBOX *[MYGROUP] [Unix] [Samba 2.0.6]
+192.168.35.56 HERBNT2 [HERB-NT]
+192.168.35.63 GANDALF [MVENGR] [Unix] [Samba 2.0.5a for IRIX]
+192.168.35.65 SAUNA [WORKGROUP] [Unix] [Samba 1.9.18p10]
+192.168.35.71 FROGSTAR [ENGR] [Unix] [Samba 2.0.0 for IRIX]
+192.168.35.78 HERBDHCP1 +[HERB]
+192.168.35.88 SCNT2 +[MVENGR] [Windows NT 4.0] [NT LAN Manager 4.0]
+192.168.35.93 FROGSTAR-PC [MVENGR] [Windows 5.0] [Windows 2000 LAN Manager]
+192.168.35.97 HERBNT1 *[HERB-NT] [Windows NT 4.0] [NT LAN Manager 4.0]
+
+.sp
+.fi
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBnmbd(8)\fR
+\fBsmbclient(1)
+\fR and \fBnmblookup(1)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/lmhosts.5 b/docs/manpages/lmhosts.5
new file mode 100755
index 00000000000..ad4a131aef9
--- /dev/null
+++ b/docs/manpages/lmhosts.5
@@ -0,0 +1,92 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "LMHOSTS" "5" "19 November 2002" "" ""
+.SH NAME
+lmhosts \- The Samba NetBIOS hosts file
+.SH SYNOPSIS
+.PP
+\fIlmhosts\fR is the Samba NetBIOS name to IP address mapping file.
+.SH "DESCRIPTION"
+.PP
+This file is part of the Samba suite.
+.PP
+\fIlmhosts\fR is the \fBSamba
+\fRNetBIOS name to IP address mapping file. It
+is very similar to the \fI/etc/hosts\fR file
+format, except that the hostname component must correspond
+to the NetBIOS naming format.
+.SH "FILE FORMAT"
+.PP
+It is an ASCII file containing one line for NetBIOS name.
+The two fields on each line are separated from each other by
+white space. Any entry beginning with '#' is ignored. Each line
+in the lmhosts file contains the following information :
+.TP 0.2i
+\(bu
+IP Address - in dotted decimal format.
+.TP 0.2i
+\(bu
+NetBIOS Name - This name format is a
+maximum fifteen character host name, with an optional
+trailing '#' character followed by the NetBIOS name type
+as two hexadecimal digits.
+
+If the trailing '#' is omitted then the given IP
+address will be returned for all names that match the given
+name, whatever the NetBIOS name type in the lookup.
+.PP
+An example follows :
+.PP
+.PP
+.sp
+.nf
+#
+# Sample Samba lmhosts file.
+#
+192.9.200.1 TESTPC
+192.9.200.20 NTSERVER#20
+192.9.200.21 SAMBASERVER
+
+.sp
+.fi
+.PP
+.PP
+Contains three IP to NetBIOS name mappings. The first
+and third will be returned for any queries for the names "TESTPC"
+and "SAMBASERVER" respectively, whatever the type component of
+the NetBIOS name requested.
+.PP
+.PP
+The second mapping will be returned only when the "0x20" name
+type for a name "NTSERVER" is queried. Any other name type will not
+be resolved.
+.PP
+.PP
+The default location of the \fIlmhosts\fR file
+is in the same directory as the
+smb.conf(5)> file.
+.PP
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbclient(1)
+\fR and \fB smbpasswd(8)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/make_smbcodepage.1 b/docs/manpages/make_smbcodepage.1
new file mode 100755
index 00000000000..3a8d318089e
--- /dev/null
+++ b/docs/manpages/make_smbcodepage.1
@@ -0,0 +1,140 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "MAKE_SMBCODEPAGE" "1" "19 November 2002" "" ""
+.SH NAME
+make_smbcodepage \- construct a codepage file for Samba
+.SH SYNOPSIS
+.sp
+\fBmake_smbcodepage\fR \fBc|d\fR \fBcodepage\fR \fBinputfile\fR \fBoutputfile\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBmake_smbcodepage\fR compiles or de-compiles
+codepage files for use with the internationalization features
+of Samba 2.2
+.SH "OPTIONS"
+.TP
+\fBc|d\fR
+This tells \fBmake_smbcodepage\fR
+if it is compiling (\fIc\fR) a text format code
+page file to binary, or (\fId\fR) de-compiling
+a binary codepage file to text.
+.TP
+\fBcodepage\fR
+This is the codepage we are processing (a
+number, e.g. 850).
+.TP
+\fBinputfile\fR
+This is the input file to process. In
+the \fIc\fR case this will be a text
+codepage definition file such as the ones found in the Samba
+\fIsource/codepages\fR directory. In
+the \fId\fR case this will be the
+binary format codepage definition file normally found in
+the \fIlib/codepages\fR directory in the
+Samba install directory path.
+.TP
+\fBoutputfile\fR
+This is the output file to produce.
+.SH "SAMBA CODEPAGE FILES"
+.PP
+A text Samba codepage definition file is a description
+that tells Samba how to map from upper to lower case for
+characters greater than ascii 127 in the specified DOS code page.
+Note that for certain DOS codepages (437 for example) mapping
+from lower to upper case may be non-symmetrical. For example, in
+code page 437 lower case a acute maps to a plain upper case A
+when going from lower to upper case, but plain upper case A maps
+to plain lower case a when lower casing a character.
+.PP
+A binary Samba codepage definition file is a binary
+representation of the same information, including a value that
+specifies what codepage this file is describing.
+.PP
+As Samba does not yet use UNICODE (current for Samba version 2.2)
+you must specify the client code page that your DOS and Windows
+clients are using if you wish to have case insensitivity done
+correctly for your particular language. The default codepage Samba
+uses is 850 (Western European). Text codepage definition sample files
+are provided in the Samba distribution for codepages 437 (USA), 737 (Greek),
+850 (Western European) 852 (MS-DOS Latin 2), 861 (Icelandic), 866 (Cyrillic),
+932 (Kanji SJIS), 936 (Simplified Chinese), 949 (Hangul) and 950 (Traditional
+Chinese). Users are encouraged to write text codepage definition files for
+their own code pages and donate them to samba@samba.org. All codepage files
+in the Samba \fIsource/codepages\fR directory are
+compiled and installed when a \fB'make install'\fR
+command is issued there.
+.PP
+The client codepage used by the \fBsmbd\fR server
+is configured using the \fBclient code page\fR parameter
+in the \fBsmb.conf\fR file.
+.SH "FILES"
+.PP
+\fBcodepage_def.<codepage>\fR
+.PP
+These are the input (text) codepage files provided in the
+Samba \fIsource/codepages\fR directory.
+.PP
+A text codepage definition file consists of multiple lines
+containing four fields. These fields are:
+.TP 0.2i
+\(bu
+\fBlower\fR: which is the
+(hex) lower case character mapped on this line.
+.TP 0.2i
+\(bu
+\fBupper\fR: which is the (hex)
+upper case character that the lower case character will map to.
+.TP 0.2i
+\(bu
+\fBmap upper to lower\fR which
+is a boolean value (put either True or False here) which tells
+Samba if it is to map the given upper case character to the
+given lower case character when lower casing a filename.
+.TP 0.2i
+\(bu
+\fBmap lower to upper\fR which
+is a boolean value (put either True or False here) which tells
+Samba if it is to map the given lower case character to the
+given upper case character when upper casing a filename.
+.PP
+\fBcodepage.<codepage>\fR - These are the
+output (binary) codepage files produced and placed in the Samba
+destination \fIlib/codepage\fR directory.
+.PP
+.SH "INSTALLATION"
+.PP
+The location of the server and its support files is a
+matter for individual system administrators. The following are
+thus suggestions only.
+.PP
+It is recommended that the \fBmake_smbcodepage
+\fRprogram be installed under the \fI/usr/local/samba
+\fRhierarchy, in a directory readable by all, writeable
+only by root. The program itself should be executable by all. The
+program should NOT be setuid or setgid!
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/make_unicodemap.1 b/docs/manpages/make_unicodemap.1
new file mode 100755
index 00000000000..94eeea097da
--- /dev/null
+++ b/docs/manpages/make_unicodemap.1
@@ -0,0 +1,99 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "MAKE_UNICODEMAP" "1" "19 November 2002" "" ""
+.SH NAME
+make_unicodemap \- construct a unicode map file for Samba
+.SH SYNOPSIS
+.sp
+\fBmake_unicodemap\fR \fBcodepage\fR \fBinputfile\fR \fBoutputfile\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba
+suite.
+.PP
+\fBmake_unicodemap\fR compiles text unicode map
+files into binary unicode map files for use with the
+internationalization features of Samba 2.2.
+.SH "OPTIONS"
+.TP
+\fBcodepage\fR
+This is the codepage or UNIX character
+set we are processing (a number, e.g. 850).
+.TP
+\fBinputfile\fR
+This is the input file to process. This is a
+text unicode map file such as the ones found in the Samba
+\fIsource/codepages\fR directory.
+.TP
+\fBoutputfile\fR
+This is the binary output file to produce.
+.SH "SAMBA UNICODE MAP FILES"
+.PP
+A text Samba unicode map file is a description that tells Samba
+how to map characters from a specified DOS code page or UNIX character
+set to 16 bit unicode.
+.PP
+A binary Samba unicode map file is a binary representation
+of the same information, including a value that specifies what
+codepage or UNIX character set this file is describing.
+.SH "FILES"
+.PP
+\fICP<codepage>.TXT\fR
+.PP
+These are the input (text) unicode map files provided
+in the Samba \fIsource/codepages\fR
+directory.
+.PP
+A text unicode map file consists of multiple lines
+containing two fields. These fields are :
+.TP 0.2i
+\(bu
+\fIcharacter\fR - which is
+the (hex) character mapped on this line.
+.TP 0.2i
+\(bu
+\fIunicode\fR - which
+is the (hex) 16 bit unicode character that the character
+will map to.
+.PP
+\fIunicode_map.<codepage>\fR - These are
+the output (binary) unicode map files produced and placed in
+the Samba destination \fIlib/codepage\fR
+directory.
+.PP
+.SH "INSTALLATION"
+.PP
+The location of the server and its support files is a matter
+for individual system administrators. The following are thus
+suggestions only.
+.PP
+It is recommended that the \fBmake_unicodemap\fR
+program be installed under the
+\fI$prefix/samba\fR hierarchy,
+in a directory readable by all, writeable only by root. The
+program itself should be executable by all. The program
+should NOT be setuid or setgid!
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/nmbd.8 b/docs/manpages/nmbd.8
new file mode 100755
index 00000000000..338ae3a95ed
--- /dev/null
+++ b/docs/manpages/nmbd.8
@@ -0,0 +1,260 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "NMBD" "8" "19 November 2002" "" ""
+.SH NAME
+nmbd \- NetBIOS name server to provide NetBIOS over IP naming services to clients
+.SH SYNOPSIS
+.sp
+\fBnmbd\fR [ \fB-D\fR ] [ \fB-a\fR ] [ \fB-i\fR ] [ \fB-o\fR ] [ \fB-P\fR ] [ \fB-h\fR ] [ \fB-V\fR ] [ \fB-d <debug level>\fR ] [ \fB-H <lmhosts file>\fR ] [ \fB-l <log directory>\fR ] [ \fB-n <primary netbios name>\fR ] [ \fB-p <port number>\fR ] [ \fB-s <configuration file>\fR ]
+.SH "DESCRIPTION"
+.PP
+This program is part of the Samba suite.
+.PP
+\fBnmbd\fR is a server that understands
+and can reply to NetBIOS over IP name service requests, like
+those produced by SMB/CIFS clients such as Windows 95/98/ME,
+Windows NT, Windows 2000, and LanManager clients. It also
+participates in the browsing protocols which make up the
+Windows "Network Neighborhood" view.
+.PP
+SMB/CIFS clients, when they start up, may wish to
+locate an SMB/CIFS server. That is, they wish to know what
+IP number a specified host is using.
+.PP
+Amongst other services, \fBnmbd\fR will
+listen for such requests, and if its own NetBIOS name is
+specified it will respond with the IP number of the host it
+is running on. Its "own NetBIOS name" is by
+default the primary DNS name of the host it is running on,
+but this can be overridden with the \fB-n\fR
+option (see OPTIONS below). Thus \fBnmbd\fR will
+reply to broadcast queries for its own name(s). Additional
+names for \fBnmbd\fR to respond on can be set
+via parameters in the \fI smb.conf(5)\fR configuration file.
+.PP
+\fBnmbd\fR can also be used as a WINS
+(Windows Internet Name Server) server. What this basically means
+is that it will act as a WINS database server, creating a
+database from name registration requests that it receives and
+replying to queries from clients for these names.
+.PP
+In addition, \fBnmbd\fR can act as a WINS
+proxy, relaying broadcast queries from clients that do
+not understand how to talk the WINS protocol to a WIN
+server.
+.SH "OPTIONS"
+.TP
+\fB-D\fR
+If specified, this parameter causes
+\fBnmbd\fR to operate as a daemon. That is,
+it detaches itself and runs in the background, fielding
+requests on the appropriate port. By default, \fBnmbd\fR
+will operate as a daemon if launched from a command shell.
+nmbd can also be operated from the \fBinetd\fR
+meta-daemon, although this is not recommended.
+.TP
+\fB-a\fR
+If this parameter is specified, each new
+connection will append log messages to the log file.
+This is the default.
+.TP
+\fB-i\fR
+If this parameter is specified it causes the
+server to run "interactively", not as a daemon, even if the
+server is executed on the command line of a shell. Setting this
+parameter negates the implicit deamon mode when run from the
+command line.
+.TP
+\fB-o\fR
+If this parameter is specified, the
+log files will be overwritten when opened. By default,
+\fBsmbd\fR will append entries to the log
+files.
+.TP
+\fB-h\fR
+Prints the help information (usage)
+for \fBnmbd\fR.
+.TP
+\fB-H <filename>\fR
+NetBIOS lmhosts file. The lmhosts
+file is a list of NetBIOS names to IP addresses that
+is loaded by the nmbd server and used via the name
+resolution mechanism name resolve order described in \fIsmb.conf(5)\fR
+to resolve any NetBIOS name queries needed by the server. Note
+that the contents of this file are \fBNOT\fR
+used by \fBnmbd\fR to answer any name queries.
+Adding a line to this file affects name NetBIOS resolution
+from this host \fBONLY\fR.
+
+The default path to this file is compiled into
+Samba as part of the build process. Common defaults
+are \fI/usr/local/samba/lib/lmhosts\fR,
+\fI/usr/samba/lib/lmhosts\fR or
+\fI/etc/lmhosts\fR. See the \fIlmhosts(5)\fR man page for details on the
+contents of this file.
+.TP
+\fB-V\fR
+Prints the version number for
+\fBnmbd\fR.
+.TP
+\fB-d <debug level>\fR
+debuglevel is an integer
+from 0 to 10. The default value if this parameter is
+not specified is zero.
+
+The higher this value, the more detail will
+be logged to the log files about the activities of the
+server. At level 0, only critical errors and serious
+warnings will be logged. Level 1 is a reasonable level for
+day to day running - it generates a small amount of
+information about operations carried out.
+
+Levels above 1 will generate considerable amounts
+of log data, and should only be used when investigating
+a problem. Levels above 3 are designed for use only by developers
+and generate HUGE amounts of log data, most of which is extremely
+cryptic.
+
+Note that specifying this parameter here will override
+the log level
+parameter in the \fI smb.conf\fR file.
+.TP
+\fB-l <log directory>\fR
+The -l parameter specifies a directory
+into which the "log.nmbd" log file will be created
+for operational data from the running
+\fBnmbd\fR server. The default log directory is compiled into Samba
+as part of the build process. Common defaults are \fI /usr/local/samba/var/log.nmb\fR, \fI /usr/samba/var/log.nmb\fR or
+\fI/var/log/log.nmb\fR. \fBBeware:\fR
+If the directory specified does not exist, \fBnmbd\fR
+will log to the default debug log location defined at compile time.
+.TP
+\fB-n <primary NetBIOS name>\fR
+This option allows you to override
+the NetBIOS name that Samba uses for itself. This is identical
+to setting the NetBIOS name parameter in the
+\fIsmb.conf\fR file. However, a command
+line setting will take precedence over settings in
+\fIsmb.conf\fR.
+.TP
+\fB-p <UDP port number>\fR
+UDP port number is a positive integer value.
+This option changes the default UDP port number (normally 137)
+that \fBnmbd\fR responds to name queries on. Don't
+use this option unless you are an expert, in which case you
+won't need help!
+.TP
+\fB-s <configuration file>\fR
+The default configuration file name
+is set at build time, typically as \fI /usr/local/samba/lib/smb.conf\fR, but
+this may be changed when Samba is autoconfigured.
+
+The file specified contains the configuration details
+required by the server. See \fIsmb.conf(5)\fR for more information.
+.SH "FILES"
+.TP
+\fB\fI/etc/inetd.conf\fB\fR
+If the server is to be run by the
+\fBinetd\fR meta-daemon, this file
+must contain suitable startup information for the
+meta-daemon. See the UNIX_INSTALL.html document
+for details.
+.TP
+\fB\fI/etc/rc\fB\fR
+or whatever initialization script your
+system uses).
+
+If running the server as a daemon at startup,
+this file will need to contain an appropriate startup
+sequence for the server. See the UNIX_INSTALL.html document
+for details.
+.TP
+\fB\fI/etc/services\fB\fR
+If running the server via the
+meta-daemon \fBinetd\fR, this file
+must contain a mapping of service name (e.g., netbios-ssn)
+to service port (e.g., 139) and protocol type (e.g., tcp).
+See the UNIX_INSTALL.html
+document for details.
+.TP
+\fB\fI/usr/local/samba/lib/smb.conf\fB\fR
+This is the default location of the
+\fIsmb.conf\fR
+server configuration file. Other common places that systems
+install this file are \fI/usr/samba/lib/smb.conf\fR
+and \fI/etc/smb.conf\fR.
+
+When run as a WINS server (see the
+wins support
+parameter in the \fIsmb.conf(5)\fR man page),
+\fBnmbd\fR
+will store the WINS database in the file \fIwins.dat\fR
+in the \fIvar/locks\fR directory configured under
+wherever Samba was configured to install itself.
+
+If \fBnmbd\fR is acting as a \fB browse master\fR (see the local master
+parameter in the \fIsmb.conf(5)\fR man page,
+\fBnmbd\fR
+will store the browsing database in the file \fIbrowse.dat
+\fRin the \fIvar/locks\fR directory
+configured under wherever Samba was configured to install itself.
+.SH "SIGNALS"
+.PP
+To shut down an \fBnmbd\fR process it is recommended
+that SIGKILL (-9) \fBNOT\fR be used, except as a last
+resort, as this may leave the name database in an inconsistent state.
+The correct way to terminate \fBnmbd\fR is to send it
+a SIGTERM (-15) signal and wait for it to die on its own.
+.PP
+\fBnmbd\fR will accept SIGHUP, which will cause
+it to dump out its namelists into the file \fInamelist.debug
+\fRin the \fI/usr/local/samba/var/locks\fR
+directory (or the \fIvar/locks\fR directory configured
+under wherever Samba was configured to install itself). This will also
+cause \fBnmbd\fR to dump out its server database in
+the \fIlog.nmb\fR file.
+.PP
+The debug log level of nmbd may be raised or lowered using
+\fBsmbcontrol(1)\fR
+ (SIGUSR[1|2] signals are no longer used in Samba 2.2). This is
+to allow transient problems to be diagnosed, whilst still running
+at a normally low log level.
+.SH "TROUBLESHOOTING"
+.PP
+One of the common causes of difficulty when installing Samba and SWAT
+is the existsnece of some type of firewall or port filtering software
+on the Samba server. Make sure that the appropriate ports
+outlined in this man page are available on the server and are not currently
+being blocked by some type of security software such as iptables or
+"port sentry". For more troubleshooting information, refer to the additional
+documentation included in the Samba distribution.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBinetd(8)\fR, \fBsmbd(8)\fR
+\fIsmb.conf(5)\fR
+ \fBsmbclient(1)
+\fR and the Internet RFC's
+\fIrfc1001.txt\fR, \fIrfc1002.txt\fR.
+In addition the CIFS (formerly SMB) specification is available
+as a link from the Web page
+http://samba.org/cifs/ <URL:http://samba.org/cifs/>.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/nmblookup.1 b/docs/manpages/nmblookup.1
new file mode 100755
index 00000000000..51f6aa1caef
--- /dev/null
+++ b/docs/manpages/nmblookup.1
@@ -0,0 +1,159 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "NMBLOOKUP" "1" "19 November 2002" "" ""
+.SH NAME
+nmblookup \- NetBIOS over TCP/IP client used to lookup NetBIOS names
+.SH SYNOPSIS
+.sp
+\fBnmblookup\fR [ \fB-f\fR ] [ \fB-M\fR ] [ \fB-R\fR ] [ \fB-S\fR ] [ \fB-r\fR ] [ \fB-A\fR ] [ \fB-h\fR ] [ \fB-B <broadcast address>\fR ] [ \fB-U <unicast address>\fR ] [ \fB-d <debug level>\fR ] [ \fB-s <smb config file>\fR ] [ \fB-i <NetBIOS scope>\fR ] [ \fB-T\fR ] \fBname\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBnmblookup\fR is used to query NetBIOS names
+and map them to IP addresses in a network using NetBIOS over TCP/IP
+queries. The options allow the name queries to be directed at a
+particular IP broadcast area or to a particular machine. All queries
+are done over UDP.
+.SH "OPTIONS"
+.TP
+\fB-f\fR
+Causes nmblookup to print out the flags
+in the NMB packet headers. These flags will print out as
+strings like Authoritative, Recursion_Desired, Recursion_available, etc.
+.TP
+\fB-M\fR
+Searches for a master browser by looking
+up the NetBIOS name \fIname\fR with a
+type of 0x1d. If \fI name\fR is "-" then it does a lookup on the special name
+__MSBROWSE__.
+.TP
+\fB-R\fR
+Set the recursion desired bit in the packet
+to do a recursive lookup. This is used when sending a name
+query to a machine running a WINS server and the user wishes
+to query the names in the WINS server. If this bit is unset
+the normal (broadcast responding) NetBIOS processing code
+on a machine is used instead. See rfc1001, rfc1002 for details.
+.TP
+\fB-S\fR
+Once the name query has returned an IP
+address then do a node status query as well. A node status
+query returns the NetBIOS names registered by a host.
+.TP
+\fB-r\fR
+Try and bind to UDP port 137 to send and receive UDP
+datagrams. The reason for this option is a bug in Windows 95
+where it ignores the source port of the requesting packet
+and only replies to UDP port 137. Unfortunately, on most UNIX
+systems root privilege is needed to bind to this port, and
+in addition, if the nmbd(8)
+daemon is running on this machine it also binds to this port.
+.TP
+\fB-A\fR
+Interpret \fIname\fR as
+an IP Address and do a node status query on this address.
+.TP
+\fB-h\fR
+Print a help (usage) message.
+.TP
+\fB-B <broadcast address>\fR
+Send the query to the given broadcast address. Without
+this option the default behavior of nmblookup is to send the
+query to the broadcast address of the network interfaces as
+either auto-detected or defined in the \fIinterfaces\fR
+ parameter of the \fIsmb.conf (5)\fR file.
+.TP
+\fB-U <unicast address>\fR
+Do a unicast query to the specified address or
+host \fIunicast address\fR. This option
+(along with the \fI-R\fR option) is needed to
+query a WINS server.
+.TP
+\fB-d <debuglevel>\fR
+debuglevel is an integer from 0 to 10.
+
+The default value if this parameter is not specified
+is zero.
+
+The higher this value, the more detail will be logged
+about the activities of \fBnmblookup\fR. At level
+0, only critical errors and serious warnings will be logged.
+
+Levels above 1 will generate considerable amounts of
+log data, and should only be used when investigating a problem.
+Levels above 3 are designed for use only by developers and
+generate HUGE amounts of data, most of which is extremely cryptic.
+
+Note that specifying this parameter here will override
+the \fI log level\fR parameter in the \fI smb.conf(5)\fR file.
+.TP
+\fB-s <smb.conf>\fR
+This parameter specifies the pathname to
+the Samba configuration file, smb.conf(5) This file controls all aspects of
+the Samba setup on the machine.
+.TP
+\fB-i <scope>\fR
+This specifies a NetBIOS scope that
+\fBnmblookup\fR will use to communicate with when
+generating NetBIOS names. For details on the use of NetBIOS
+scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes are
+\fBvery\fR rarely used, only set this parameter
+if you are the system administrator in charge of all the
+NetBIOS systems you communicate with.
+.TP
+\fB-T\fR
+This causes any IP addresses found in the
+lookup to be looked up via a reverse DNS lookup into a
+DNS name, and printed out before each
+
+\fBIP address .... NetBIOS name\fR
+
+pair that is the normal output.
+.TP
+\fBname\fR
+This is the NetBIOS name being queried. Depending
+upon the previous options this may be a NetBIOS name or IP address.
+If a NetBIOS name then the different name types may be specified
+by appending '#<type>' to the name. This name may also be
+\&'*', which will return all registered names within a broadcast
+area.
+.SH "EXAMPLES"
+.PP
+\fBnmblookup\fR can be used to query
+a WINS server (in the same way \fBnslookup\fR is
+used to query DNS servers). To query a WINS server,
+\fBnmblookup\fR must be called like this:
+.PP
+\fBnmblookup -U server -R 'name'\fR
+.PP
+For example, running :
+.PP
+\fBnmblookup -U samba.org -R 'IRIX#1B'\fR
+.PP
+would query the WINS server samba.org for the domain
+master browser (1B name type) for the IRIX workgroup.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBnmbd(8)\fR
+samba(7) and smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/pdbedit.8 b/docs/manpages/pdbedit.8
new file mode 100755
index 00000000000..30fe63e4da5
--- /dev/null
+++ b/docs/manpages/pdbedit.8
@@ -0,0 +1,202 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "PDBEDIT" "8" "19 November 2002" "" ""
+.SH NAME
+pdbedit \- manage the SAM database
+.SH SYNOPSIS
+.sp
+\fBpdbedit\fR [ \fB-l\fR ] [ \fB-v\fR ] [ \fB-w\fR ] [ \fB-u username\fR ] [ \fB-f fullname\fR ] [ \fB-h homedir\fR ] [ \fB-d drive\fR ] [ \fB-s script\fR ] [ \fB-p profile\fR ] [ \fB-a\fR ] [ \fB-b\fR ] [ \fB-m\fR ] [ \fB-x\fR ] [ \fB-i file\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+The pdbedit program is used to manage the users accounts
+stored in the sam database and can be run only by root.
+.PP
+The pdbedit tool use the passdb modular interface and is
+independent from the kind of users database used (currently there
+are smbpasswd, ldap, nis+ and tdb based and more can be addedd
+without changing the tool).
+.PP
+There are five main ways to use pdbedit: adding a user account,
+removing a user account, modifing a user account, listing user
+accounts, importing users accounts.
+.SH "OPTIONS"
+.TP
+\fB-l\fR
+This option list all the user accounts
+present in the users database.
+This option prints a list of user/uid pairs separated by
+the ':' character.
+
+Example: \fBpdbedit -l\fR
+
+.sp
+.nf
+ sorce:500:Simo Sorce
+ samba:45:Test User
+
+.sp
+.fi
+.TP
+\fB-v\fR
+This option sets the verbose listing format.
+It will make pdbedit list the users in the database printing
+out the account fields in a descriptive format.
+
+Example: \fBpdbedit -l -v\fR
+
+.sp
+.nf
+ ---------------
+ username: sorce
+ user ID/Group: 500/500
+ user RID/GRID: 2000/2001
+ Full Name: Simo Sorce
+ Home Directory: \\\\BERSERKER\\sorce
+ HomeDir Drive: H:
+ Logon Script: \\\\BERSERKER\\netlogon\\sorce.bat
+ Profile Path: \\\\BERSERKER\\profile
+ ---------------
+ username: samba
+ user ID/Group: 45/45
+ user RID/GRID: 1090/1091
+ Full Name: Test User
+ Home Directory: \\\\BERSERKER\\samba
+ HomeDir Drive:
+ Logon Script:
+ Profile Path: \\\\BERSERKER\\profile
+
+.sp
+.fi
+.TP
+\fB-w\fR
+This option sets the "smbpasswd" listing format.
+It will make pdbedit list the users in the database printing
+out the account fields in a format compatible with the
+\fIsmbpasswd\fR file format. (see the \fIsmbpasswd(5)\fR for details)
+
+Example: \fBpdbedit -l -w\fR
+
+.sp
+.nf
+ sorce:500:508818B733CE64BEAAD3B435B51404EE:D2A2418EFC466A8A0F6B1DBB5C3DB80C:[UX ]:LCT-00000000:
+ samba:45:0F2B255F7B67A7A9AAD3B435B51404EE:BC281CE3F53B6A5146629CD4751D3490:[UX ]:LCT-3BFA1E8D:
+
+.sp
+.fi
+.TP
+\fB-u username\fR
+This option specifies that the username to be
+used for the operation requested (listing, adding, removing)
+It is \fBrequired\fR in add, remove and modify
+operations and \fBoptional\fR in list
+operations.
+.TP
+\fB-f fullname\fR
+This option can be used while adding or
+modifing a user account. It will specify the user's full
+name.
+
+Example: \fB-f "Simo Sorce"\fR
+.TP
+\fB-h homedir\fR
+This option can be used while adding or
+modifing a user account. It will specify the user's home
+directory network path.
+
+Example: \fB-h "\\\\\\\\BERSERKER\\\\sorce"\fR
+.TP
+\fB-d drive\fR
+This option can be used while adding or
+modifing a user account. It will specify the windows drive
+letter to be used to map the home directory.
+
+Example: \fB-d "H:"\fR
+.TP
+\fB-s script\fR
+This option can be used while adding or
+modifing a user account. It will specify the user's logon
+script path.
+
+Example: \fB-s "\\\\\\\\BERSERKER\\\\netlogon\\\\sorce.bat"\fR
+.TP
+\fB-p profile\fR
+This option can be used while adding or
+modifing a user account. It will specify the user's profile
+directory.
+
+Example: \fB-p "\\\\\\\\BERSERKER\\\\netlogon"\fR
+.TP
+\fB-a\fR
+This option is used to add a user into the
+database. This command need the user name be specified with
+the -u switch. When adding a new user pdbedit will also
+ask for the password to be used
+
+Example: \fBpdbedit -a -u sorce\fR
+.sp
+.nf
+new password:
+ retype new password
+.sp
+.fi
+.TP
+\fB-b\fR
+This option causes pdbedit to read the password from standard
+input, rather than from \fI/dev/tty\fR.
+
+Example: \fBecho -e "secret\\nsecret\\n" | pdbedit -a -b -u sorce\fR
+.fi
+.TP
+\fB-m\fR
+This option may only be used in conjunction
+with the \fI-a\fR option. It will make
+pdbedit to add a machine trust account instead of a user
+account (-u username will provide the machine name).
+
+Example: \fBpdbedit -a -m -u w2k-wks\fR
+.TP
+\fB-x\fR
+This option causes pdbedit to delete an account
+from the database. It need the username be specified with the
+-u switch.
+
+Example: \fBpdbedit -x -u bob\fR
+.TP
+\fB-i file\fR
+This command is used to import a smbpasswd
+file into the database.
+
+This option will ease migration from the plain smbpasswd
+file database to more powerful backend databases like tdb and
+ldap.
+
+Example: \fBpdbedit -i /etc/smbpasswd.old\fR
+.SH "NOTES"
+.PP
+This command may be used only by root.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+smbpasswd(8)
+samba(7)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/rpcclient.1 b/docs/manpages/rpcclient.1
new file mode 100755
index 00000000000..0957b1b60cf
--- /dev/null
+++ b/docs/manpages/rpcclient.1
@@ -0,0 +1,329 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "RPCCLIENT" "1" "19 November 2002" "" ""
+.SH NAME
+rpcclient \- tool for executing client side MS-RPC functions
+.SH SYNOPSIS
+.sp
+\fBrpcclient\fR [ \fB-A authfile\fR ] [ \fB-c <command string>\fR ] [ \fB-d debuglevel\fR ] [ \fB-h\fR ] [ \fB-l logfile\fR ] [ \fB-N\fR ] [ \fB-s <smb config file>\fR ] [ \fB-U username[%password]\fR ] [ \fB-W workgroup\fR ] [ \fB-N\fR ] \fBserver\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBrpcclient\fR is a utility initially developed
+to test MS-RPC functionality in Samba itself. It has undergone
+several stages of development and stability. Many system administrators
+have now written scripts around it to manage Windows NT clients from
+their UNIX workstation.
+.SH "OPTIONS"
+.TP
+\fBserver\fR
+NetBIOS name of Server to which to connect.
+The server can be any SMB/CIFS server. The name is
+resolved using the \fIname resolve order\fR line from
+\fIsmb.conf(5)\fR.
+.TP
+\fB-A filename\fR
+This option allows
+you to specify a file from which to read the username and
+password used in the connection. The format of the file is
+
+.sp
+.nf
+ username = <value>
+ password = <value>
+ domain = <value>
+
+.sp
+.fi
+
+Make certain that the permissions on the file restrict
+access from unwanted users.
+.TP
+\fB-c 'command string'\fR
+execute semicolon separated commands (listed
+below))
+.TP
+\fB-d debuglevel\fR
+set the debuglevel. Debug level 0 is the lowest
+and 100 being the highest. This should be set to 100 if you are
+planning on submitting a bug report to the Samba team (see \fIBUGS.txt\fR).
+.TP
+\fB-h\fR
+Print a summary of command line options.
+.TP
+\fB-l logbasename\fR
+File name for log/debug files. The extension
+\&'.client' will be appended. The log file is never removed
+by the client.
+.TP
+\fB-N\fR
+instruct \fBrpcclient\fR not to ask
+for a password. By default, \fBrpcclient\fR will prompt
+for a password. See also the \fI-U\fR option.
+.TP
+\fB-s smb.conf\fR
+Specifies the location of the all important
+\fIsmb.conf\fR file.
+.TP
+\fB-U username[%password]\fR
+Sets the SMB username or username and password.
+
+If %password is not specified, the user will be prompted. The
+client will first check the \fBUSER\fR environment variable, then the
+\fBLOGNAME\fR variable and if either exists, the
+string is uppercased. If these environmental variables are not
+found, the username GUEST is used.
+
+A third option is to use a credentials file which
+contains the plaintext of the username and password. This
+option is mainly provided for scripts where the admin doesn't
+desire to pass the credentials on the command line or via environment
+variables. If this method is used, make certain that the permissions
+on the file restrict access from unwanted users. See the
+\fI-A\fR for more details.
+
+Be cautious about including passwords in scripts. Also, on
+many systems the command line of a running process may be seen
+via the \fBps\fR command. To be safe always allow
+\fBrpcclient\fR to prompt for a password and type
+it in directly.
+.TP
+\fB-W domain\fR
+Set the SMB domain of the username. This
+overrides the default domain which is the domain defined in
+smb.conf. If the domain specified is the same as the server's NetBIOS name,
+it causes the client to log on using the server's local SAM (as
+opposed to the Domain SAM).
+.SH "COMMANDS"
+.PP
+\fBLSARPC\fR
+.TP 0.2i
+\(bu
+\fBlsaquery\fR
+.TP 0.2i
+\(bu
+\fBlookupsids\fR - Resolve a list
+of SIDs to usernames.
+.TP 0.2i
+\(bu
+\fBlookupnames\fR - Resolve s list
+of usernames to SIDs.
+.TP 0.2i
+\(bu
+\fBenumtrusts\fR
+.PP
+.PP
+.PP
+\fBSAMR\fR
+.PP
+.TP 0.2i
+\(bu
+\fBqueryuser\fR
+.TP 0.2i
+\(bu
+\fBquerygroup\fR
+.TP 0.2i
+\(bu
+\fBqueryusergroups\fR
+.TP 0.2i
+\(bu
+\fBquerygroupmem\fR
+.TP 0.2i
+\(bu
+\fBqueryaliasmem\fR
+.TP 0.2i
+\(bu
+\fBquerydispinfo\fR
+.TP 0.2i
+\(bu
+\fBquerydominfo\fR
+.TP 0.2i
+\(bu
+\fBenumdomgroups\fR
+.PP
+.PP
+.PP
+\fBSPOOLSS\fR
+.PP
+.TP 0.2i
+\(bu
+\fBadddriver <arch> <config>\fR
+- Execute an AddPrinterDriver() RPC to install the printer driver
+information on the server. Note that the driver files should
+already exist in the directory returned by
+\fBgetdriverdir\fR. Possible values for
+\fIarch\fR are the same as those for
+the \fBgetdriverdir\fR command.
+The \fIconfig\fR parameter is defined as
+follows:
+
+.sp
+.nf
+ Long Printer Name:\\
+ Driver File Name:\\
+ Data File Name:\\
+ Config File Name:\\
+ Help File Name:\\
+ Language Monitor Name:\\
+ Default Data Type:\\
+ Comma Separated list of Files
+
+.sp
+.fi
+
+Any empty fields should be enter as the string "NULL".
+
+Samba does not need to support the concept of Print Monitors
+since these only apply to local printers whose driver can make
+use of a bi-directional link for communication. This field should
+be "NULL". On a remote NT print server, the Print Monitor for a
+driver must already be installed prior to adding the driver or
+else the RPC will fail.
+.TP 0.2i
+\(bu
+\fBaddprinter <printername>
+<sharename> <drivername> <port>\fR
+- Add a printer on the remote server. This printer
+will be automatically shared. Be aware that the printer driver
+must already be installed on the server (see \fBadddriver\fR)
+and the \fIport\fRmust be a valid port name (see
+\fBenumports\fR.
+.TP 0.2i
+\(bu
+\fBdeldriver\fR - Delete the
+specified printer driver for all architectures. This
+does not delete the actual driver files from the server,
+only the entry from the server's list of drivers.
+.TP 0.2i
+\(bu
+\fBenumdata\fR - Enumerate all
+printer setting data stored on the server. On Windows NT clients,
+these values are stored in the registry, while Samba servers
+store them in the printers TDB. This command corresponds
+to the MS Platform SDK GetPrinterData() function (* This
+command is currently unimplemented).
+.TP 0.2i
+\(bu
+\fBenumjobs <printer>\fR
+- List the jobs and status of a given printer.
+This command corresponds to the MS Platform SDK EnumJobs()
+function (* This command is currently unimplemented).
+.TP 0.2i
+\(bu
+\fBenumports [level]\fR
+- Executes an EnumPorts() call using the specified
+info level. Currently only info levels 1 and 2 are supported.
+.TP 0.2i
+\(bu
+\fBenumdrivers [level]\fR
+- Execute an EnumPrinterDrivers() call. This lists the various installed
+printer drivers for all architectures. Refer to the MS Platform SDK
+documentation for more details of the various flags and calling
+options. Currently supported info levels are 1, 2, and 3.
+.TP 0.2i
+\(bu
+\fBenumprinters [level]\fR
+- Execute an EnumPrinters() call. This lists the various installed
+and share printers. Refer to the MS Platform SDK documentation for
+more details of the various flags and calling options. Currently
+supported info levels are 0, 1, and 2.
+.TP 0.2i
+\(bu
+\fBgetdata <printername>\fR
+- Retrieve the data for a given printer setting. See
+the \fBenumdata\fR command for more information.
+This command corresponds to the GetPrinterData() MS Platform
+SDK function (* This command is currently unimplemented).
+.TP 0.2i
+\(bu
+\fBgetdriver <printername>\fR
+- Retrieve the printer driver information (such as driver file,
+config file, dependent files, etc...) for
+the given printer. This command corresponds to the GetPrinterDriver()
+MS Platform SDK function. Currently info level 1, 2, and 3 are supported.
+.TP 0.2i
+\(bu
+\fBgetdriverdir <arch>\fR
+- Execute a GetPrinterDriverDirectory()
+RPC to retreive the SMB share name and subdirectory for
+storing printer driver files for a given architecture. Possible
+values for \fIarch\fR are "Windows 4.0"
+(for Windows 95/98), "Windows NT x86", "Windows NT PowerPC", "Windows
+Alpha_AXP", and "Windows NT R4000".
+.TP 0.2i
+\(bu
+\fBgetprinter <printername>\fR
+- Retrieve the current printer information. This command
+corresponds to the GetPrinter() MS Platform SDK function.
+.TP 0.2i
+\(bu
+\fBopenprinter <printername>\fR
+- Execute an OpenPrinterEx() and ClosePrinter() RPC
+against a given printer.
+.TP 0.2i
+\(bu
+\fBsetdriver <printername> <drivername>\fR
+- Execute a SetPrinter() command to update the printer driver associated
+with an installed printer. The printer driver must already be correctly
+installed on the print server.
+
+See also the \fBenumprinters\fR and
+\fBenumdrivers\fR commands for obtaining a list of
+of installed printers and drivers.
+.PP
+\fBGENERAL OPTIONS\fR
+.PP
+.TP 0.2i
+\(bu
+\fBdebuglevel\fR - Set the current debug level
+used to log information.
+.TP 0.2i
+\(bu
+\fBhelp (?)\fR - Print a listing of all
+known commands or extended help on a particular command.
+.TP 0.2i
+\(bu
+\fBquit (exit)\fR - Exit \fBrpcclient
+\fR\&.
+.SH "BUGS"
+.PP
+\fBrpcclient\fR is designed as a developer testing tool
+and may not be robust in certain areas (such as command line parsing).
+It has been known to generate a core dump upon failures when invalid
+parameters where passed to the interpreter.
+.PP
+From Luke Leighton's original rpcclient man page:
+.PP
+\fB"WARNING!\fR The MSRPC over SMB code has
+been developed from examining Network traces. No documentation is
+available from the original creators (Microsoft) on how MSRPC over
+SMB works, or how the individual MSRPC services work. Microsoft's
+implementation of these services has been demonstrated (and reported)
+to be... a bit flaky in places.
+.PP
+The development of Samba's implementation is also a bit rough,
+and as more of the services are understood, it can even result in
+versions of \fBsmbd(8)\fR and \fBrpcclient(1)\fR
+that are incompatible for some commands or services. Additionally,
+the developers are sending reports to Microsoft, and problems found
+or reported to Microsoft are fixed in Service Packs, which may
+result in incompatibilities."
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of the Samba
+suite.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original rpcclient man page was written by Matthew
+Geddes, Luke Kenneth Casson Leighton, and rewritten by Gerald Carter.
+The conversion to DocBook for Samba 2.2 was done by Gerald
+Carter.
diff --git a/docs/manpages/samba.7 b/docs/manpages/samba.7
new file mode 100755
index 00000000000..383b40fa033
--- /dev/null
+++ b/docs/manpages/samba.7
@@ -0,0 +1,141 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SAMBA" "7" "19 November 2002" "" ""
+.SH NAME
+SAMBA \- A Windows SMB/CIFS fileserver for UNIX
+.SH SYNOPSIS
+.sp
+\fBSamba\fR
+.SH "DESCRIPTION"
+.PP
+The Samba software suite is a collection of programs
+that implements the Server Message Block (commonly abbreviated
+as SMB) protocol for UNIX systems. This protocol is sometimes
+also referred to as the Common Internet File System (CIFS),
+LanManager or NetBIOS protocol.
+.TP
+\fBsmbd\fR
+The \fBsmbd \fR
+daemon provides the file and print services to
+SMB clients, such as Windows 95/98, Windows NT, Windows
+for Workgroups or LanManager. The configuration file
+for this daemon is described in \fIsmb.conf\fR
+.TP
+\fBnmbd\fR
+The \fBnmbd\fR
+daemon provides NetBIOS nameserving and browsing
+support. The configuration file for this daemon
+is described in \fIsmb.conf\fR
+.TP
+\fBsmbclient\fR
+The \fBsmbclient\fR
+program implements a simple ftp-like client. This
+is useful for accessing SMB shares on other compatible
+servers (such as Windows NT), and can also be used
+to allow a UNIX box to print to a printer attached to
+any SMB server (such as a PC running Windows NT).
+.TP
+\fBtestparm\fR
+The \fBtestparm\fR
+utility is a simple syntax checker for Samba's
+\fIsmb.conf\fRconfiguration file.
+.TP
+\fBtestprns\fR
+The \fBtestprns\fR
+utility supports testing printer names defined
+in your \fIprintcap>\fR file used
+by Samba.
+.TP
+\fBsmbstatus\fR
+The \fBsmbstatus\fR
+tool provides access to information about the
+current connections to \fBsmbd\fR.
+.TP
+\fBnmblookup\fR
+The \fBnmblookup\fR
+tools allows NetBIOS name queries to be made
+from a UNIX host.
+.TP
+\fBmake_smbcodepage\fR
+The \fBmake_smbcodepage\fR
+utility provides a means of creating SMB code page
+definition files for your \fBsmbd\fR server.
+.TP
+\fBsmbpasswd\fR
+The \fBsmbpasswd\fR
+command is a tool for changing LanMan and Windows NT
+password hashes on Samba and Windows NT servers.
+.SH "COMPONENTS"
+.PP
+The Samba suite is made up of several components. Each
+component is described in a separate manual page. It is strongly
+recommended that you read the documentation that comes with Samba
+and the manual pages of those components that you use. If the
+manual pages aren't clear enough then please send a patch or
+bug report to samba@samba.org <URL:mailto:samba@samba.org>
+.SH "AVAILABILITY"
+.PP
+The Samba software suite is licensed under the
+GNU Public License(GPL). A copy of that license should
+have come with the package in the file COPYING. You are
+encouraged to distribute copies of the Samba suite, but
+please obey the terms of this license.
+.PP
+The latest version of the Samba suite can be
+obtained via anonymous ftp from samba.org in the
+directory pub/samba/. It is also available on several
+mirror sites worldwide.
+.PP
+You may also find useful information about Samba
+on the newsgroup comp.protocol.smb <URL:news:comp.protocols.smb> and the Samba mailing
+list. Details on how to join the mailing list are given in
+the README file that comes with Samba.
+.PP
+If you have access to a WWW viewer (such as Netscape
+or Mosaic) then you will also find lots of useful information,
+including back issues of the Samba mailing list, at
+http://lists.samba.org <URL:http://lists.samba.org/>.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of the
+Samba suite.
+.SH "CONTRIBUTIONS"
+.PP
+If you wish to contribute to the Samba project,
+then I suggest you join the Samba mailing list at
+http://lists.samba.org <URL:http://lists.samba.org/>.
+.PP
+If you have patches to submit or bugs to report
+then you may mail them directly to samba-patches@samba.org.
+Note, however, that due to the enormous popularity of this
+package the Samba Team may take some time to respond to mail. We
+prefer patches in \fBdiff -u\fR format.
+.SH "CONTRIBUTORS"
+.PP
+Contributors to the project are now too numerous
+to mention here but all deserve the thanks of all Samba
+users. To see a full list, look at ftp://samba.org/pub/samba/alpha/change-log <URL:ftp://samba.org/pub/samba/alpha/change-log>
+for the pre-CVS changes and at ftp://samba.org/pub/samba/alpha/cvs.log <URL:ftp://samba.org/pub/samba/alpha/cvs.log>
+for the contributors to Samba post-CVS. CVS is the Open Source
+source code control system used by the Samba Team to develop
+Samba. The project would have been unmanageable without it.
+.PP
+In addition, several commercial organizations now help
+fund the Samba Team with money and equipment. For details see
+the Samba Web pages at http://samba.org/samba/samba-thanks.html
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5
new file mode 100755
index 00000000000..d272e43f247
--- /dev/null
+++ b/docs/manpages/smb.conf.5
@@ -0,0 +1,7679 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMB.CONF" "5" "30 March 2003" "" ""
+.SH NAME
+smb.conf \- The configuration file for the Samba suite
+.SH "SYNOPSIS"
+.PP
+The \fIsmb.conf\fR file is a configuration
+file for the Samba suite. \fIsmb.conf\fR contains
+runtime configuration information for the Samba programs. The
+\fIsmb.conf\fR file is designed to be configured and
+administered by the \fBswat(8)\fR
+ program. The complete description of the file format and
+possible parameters held within are here for reference purposes.
+.SH "FILE FORMAT"
+.PP
+The file consists of sections and parameters. A section
+begins with the name of the section in square brackets and continues
+until the next section begins. Sections contain parameters of the
+form
+.PP
+\fIname\fR = \fIvalue
+\fR.PP
+The file is line-based - that is, each newline-terminated
+line represents either a comment, a section name or a parameter.
+.PP
+Section and parameter names are not case sensitive.
+.PP
+Only the first equals sign in a parameter is significant.
+Whitespace before or after the first equals sign is discarded.
+Leading, trailing and internal whitespace in section and parameter
+names is irrelevant. Leading and trailing whitespace in a parameter
+value is discarded. Internal whitespace within a parameter value
+is retained verbatim.
+.PP
+Any line beginning with a semicolon (';') or a hash ('#')
+character is ignored, as are lines containing only whitespace.
+.PP
+Any line ending in a '\\' is continued
+on the next line in the customary UNIX fashion.
+.PP
+The values following the equals sign in parameters are all
+either a string (no quotes needed) or a boolean, which may be given
+as yes/no, 0/1 or true/false. Case is not significant in boolean
+values, but is preserved in string values. Some items such as
+create modes are numeric.
+.SH "SECTION DESCRIPTIONS"
+.PP
+Each section in the configuration file (except for the
+[global] section) describes a shared resource (known
+as a "share"). The section name is the name of the
+shared resource and the parameters within the section define
+the shares attributes.
+.PP
+There are three special sections, [global],
+[homes] and [printers], which are
+described under \fBspecial sections\fR. The
+following notes apply to ordinary section descriptions.
+.PP
+A share consists of a directory to which access is being
+given plus a description of the access rights which are granted
+to the user of the service. Some housekeeping options are
+also specifiable.
+.PP
+Sections are either file share services (used by the
+client as an extension of their native file systems) or
+printable services (used by the client to access print services
+on the host running the server).
+.PP
+Sections may be designated \fBguest\fR services,
+in which case no password is required to access them. A specified
+UNIX \fBguest account\fR is used to define access
+privileges in this case.
+.PP
+Sections other than guest services will require a password
+to access them. The client provides the username. As older clients
+only provide passwords and not usernames, you may specify a list
+of usernames to check against the password using the "user ="
+option in the share definition. For modern clients such as
+Windows 95/98/ME/NT/2000, this should not be necessary.
+.PP
+Note that the access rights granted by the server are
+masked by the access rights granted to the specified or guest
+UNIX user by the host system. The server does not grant more
+access than the host system grants.
+.PP
+The following sample section defines a file space share.
+The user has write access to the path \fI/home/bar\fR.
+The share is accessed via the share name "foo":
+.sp
+.nf
+ [foo]
+ path = /home/bar
+ read only = no
+
+
+.sp
+.fi
+.PP
+The following sample section defines a printable share.
+The share is readonly, but printable. That is, the only write
+access permitted is via calls to open, write to and close a
+spool file. The \fBguest ok\fR parameter means
+access will be permitted as the default guest user (specified
+elsewhere):
+.sp
+.nf
+ [aprinter]
+ path = /usr/spool/public
+ read only = yes
+ printable = yes
+ guest ok = yes
+
+
+.sp
+.fi
+.SH "SPECIAL SECTIONS"
+.SS "THE GLOBAL SECTION"
+.PP
+parameters in this section apply to the server
+as a whole, or are defaults for sections which do not
+specifically define certain items. See the notes
+under PARAMETERS for more information.
+.SS "THE HOMES SECTION"
+.PP
+If a section called homes is included in the
+configuration file, services connecting clients to their
+home directories can be created on the fly by the server.
+.PP
+When the connection request is made, the existing
+sections are scanned. If a match is found, it is used. If no
+match is found, the requested section name is treated as a
+user name and looked up in the local password file. If the
+name exists and the correct password has been given, a share is
+created by cloning the [homes] section.
+.PP
+Some modifications are then made to the newly
+created share:
+.TP 0.2i
+\(bu
+The share name is changed from homes to
+the located username.
+.TP 0.2i
+\(bu
+If no path was given, the path is set to
+the user's home directory.
+.PP
+If you decide to use a \fBpath =\fR line
+in your [homes] section then you may find it useful
+to use the %S macro. For example :
+.PP
+.PP
+\fBpath = /data/pchome/%S\fR
+.PP
+.PP
+would be useful if you have different home directories
+for your PCs than for UNIX access.
+.PP
+.PP
+This is a fast and simple way to give a large number
+of clients access to their home directories with a minimum
+of fuss.
+.PP
+.PP
+A similar process occurs if the requested section
+name is "homes", except that the share name is not
+changed to that of the requesting user. This method of using
+the [homes] section works well if different users share
+a client PC.
+.PP
+.PP
+The [homes] section can specify all the parameters
+a normal service section can specify, though some make more sense
+than others. The following is a typical and suitable [homes]
+section:
+.PP
+.sp
+.nf
+ [homes]
+ read only = no
+
+
+.sp
+.fi
+.PP
+An important point is that if guest access is specified
+in the [homes] section, all home directories will be
+visible to all clients \fBwithout a password\fR.
+In the very unlikely event that this is actually desirable, it
+would be wise to also specify \fBread only
+access\fR.
+.PP
+.PP
+Note that the \fBbrowseable\fR flag for
+auto home directories will be inherited from the global browseable
+flag, not the [homes] browseable flag. This is useful as
+it means setting \fBbrowseable = no\fR in
+the [homes] section will hide the [homes] share but make
+any auto home directories visible.
+.PP
+.SS "THE PRINTERS SECTION"
+.PP
+This section works like [homes],
+but for printers.
+.PP
+If a [printers] section occurs in the
+configuration file, users are able to connect to any printer
+specified in the local host's printcap file.
+.PP
+When a connection request is made, the existing sections
+are scanned. If a match is found, it is used. If no match is found,
+but a [homes] section exists, it is used as described
+above. Otherwise, the requested section name is treated as a
+printer name and the appropriate printcap file is scanned to see
+if the requested section name is a valid printer share name. If
+a match is found, a new printer share is created by cloning
+the [printers] section.
+.PP
+A few modifications are then made to the newly created
+share:
+.TP 0.2i
+\(bu
+The share name is set to the located printer
+name
+.TP 0.2i
+\(bu
+If no printer name was given, the printer name
+is set to the located printer name
+.TP 0.2i
+\(bu
+If the share does not permit guest access and
+no username was given, the username is set to the located
+printer name.
+.PP
+Note that the [printers] service MUST be
+printable - if you specify otherwise, the server will refuse
+to load the configuration file.
+.PP
+.PP
+Typically the path specified would be that of a
+world-writeable spool directory with the sticky bit set on
+it. A typical [printers] entry would look like
+this:
+.PP
+.sp
+.nf
+ [printers]
+ path = /usr/spool/public
+ guest ok = yes
+ printable = yes
+
+.sp
+.fi
+.PP
+All aliases given for a printer in the printcap file
+are legitimate printer names as far as the server is concerned.
+If your printing subsystem doesn't work like that, you will have
+to set up a pseudo-printcap. This is a file consisting of one or
+more lines like this:
+.PP
+.sp
+.nf
+ alias|alias|alias|alias...
+
+
+.sp
+.fi
+.PP
+Each alias should be an acceptable printer name for
+your printing subsystem. In the [global] section, specify
+the new file as your printcap. The server will then only recognize
+names found in your pseudo-printcap, which of course can contain
+whatever aliases you like. The same technique could be used
+simply to limit access to a subset of your local printers.
+.PP
+.PP
+An alias, by the way, is defined as any component of the
+first entry of a printcap record. Records are separated by newlines,
+components (if there are more than one) are separated by vertical
+bar symbols ('|').
+.PP
+.PP
+NOTE: On SYSV systems which use lpstat to determine what
+printers are defined on the system you may be able to use
+"printcap name = lpstat" to automatically obtain a list
+of printers. See the "printcap name" option
+for more details.
+.PP
+.SH "PARAMETERS"
+.PP
+parameters define the specific attributes of sections.
+.PP
+Some parameters are specific to the [global] section
+(e.g., \fBsecurity\fR). Some parameters are usable
+in all sections (e.g., \fBcreate mode\fR). All others
+are permissible only in normal sections. For the purposes of the
+following descriptions the [homes] and [printers]
+sections will be considered normal. The letter \fBG\fR
+in parentheses indicates that a parameter is specific to the
+[global] section. The letter \fBS\fR
+indicates that a parameter can be specified in a service specific
+section. Note that all \fBS\fR parameters can also be specified in
+the [global] section - in which case they will define
+the default behavior for all services.
+.PP
+parameters are arranged here in alphabetical order - this may
+not create best bedfellows, but at least you can find them! Where
+there are synonyms, the preferred synonym is described, others refer
+to the preferred synonym.
+.SH "VARIABLE SUBSTITUTIONS"
+.PP
+Many of the strings that are settable in the config file
+can take substitutions. For example the option "path =
+/tmp/%u" would be interpreted as "path =
+/tmp/john" if the user connected with the username john.
+.PP
+These substitutions are mostly noted in the descriptions below,
+but there are some general substitutions which apply whenever they
+might be relevant. These are:
+.TP
+\fB%S\fR
+the name of the current service, if any.
+.TP
+\fB%P\fR
+the root directory of the current service,
+if any.
+.TP
+\fB%u\fR
+user name of the current service, if any.
+.TP
+\fB%g\fR
+primary group name of %u.
+.TP
+\fB%U\fR
+session user name (the user name that the client
+wanted, not necessarily the same as the one they got).
+.TP
+\fB%G\fR
+primary group name of %U.
+.TP
+\fB%H\fR
+the home directory of the user given
+by %u.
+.TP
+\fB%v\fR
+the Samba version.
+.TP
+\fB%h\fR
+the Internet hostname that Samba is running
+on.
+.TP
+\fB%m\fR
+the NetBIOS name of the client machine
+(very useful).
+.TP
+\fB%L\fR
+the NetBIOS name of the server. This allows you
+to change your config based on what the client calls you. Your
+server can have a "dual personality".
+
+Note that this paramater is not available when Samba listens
+on port 445, as clients no longer send this information
+.TP
+\fB%M\fR
+the Internet name of the client machine.
+.TP
+\fB%N\fR
+the name of your NIS home directory server.
+This is obtained from your NIS auto.map entry. If you have
+not compiled Samba with the \fB--with-automount\fR
+option then this value will be the same as %L.
+.TP
+\fB%p\fR
+the path of the service's home directory,
+obtained from your NIS auto.map entry. The NIS auto.map entry
+is split up as "%N:%p".
+.TP
+\fB%R\fR
+the selected protocol level after
+protocol negotiation. It can be one of CORE, COREPLUS,
+LANMAN1, LANMAN2 or NT1.
+.TP
+\fB%d\fR
+The process id of the current server
+process.
+.TP
+\fB%a\fR
+the architecture of the remote
+machine. Only some are recognized, and those may not be
+100% reliable. It currently recognizes Samba, "WfWg", "Win95",
+"WinNT", "Win2K", WinXP, and "Win2K3". Anything else will be known as
+"UNKNOWN". If it gets it wrong then sending a level
+3 log to samba@samba.org
+ <URL:mailto:samba@samba.org> should allow it to be fixed.
+.TP
+\fB%I\fR
+The IP address of the client machine.
+.TP
+\fB%T\fR
+the current date and time.
+.TP
+\fB%$(\fIenvvar\fB)\fR
+The value of the environment variable
+\fIenvar\fR.
+.PP
+There are some quite creative things that can be done
+with these substitutions and other smb.conf options.
+.PP
+.SH "NAME MANGLING"
+.PP
+Samba supports "name mangling" so that DOS and
+Windows clients can use files that don't conform to the 8.3 format.
+It can also be set to adjust the case of 8.3 format filenames.
+.PP
+There are several options that control the way mangling is
+performed, and they are grouped here rather than listed separately.
+For the defaults look at the output of the testparm program.
+.PP
+All of these options can be set separately for each service
+(or globally, of course).
+.PP
+The options are:
+.TP
+\fBmangling method\fR
+controls the algorithm used for the generating
+the mangled names. Can take two different values, "hash" and
+"hash2". "hash" is the default and is the algorithm that has been
+used in Samba for many years. "hash2" is a newer and considered
+a better algorithm (generates less collisions) in the names.
+However, many Win32 applications store the
+mangled names and so changing to the new algorithm must not be done
+lightly as these applications may break unless reinstalled.
+New installations of Samba may set the default to hash2.
+Default \fBhash\fR.
+.TP
+\fBmangle case = yes/no\fR
+controls if names that have characters that
+aren't of the "default" case are mangled. For example,
+if this is yes then a name like "Mail" would be mangled.
+Default \fBno\fR.
+.TP
+\fBcase sensitive = yes/no\fR
+controls whether filenames are case sensitive. If
+they aren't then Samba must do a filename search and match on passed
+names. Default \fBno\fR.
+.TP
+\fBdefault case = upper/lower\fR
+controls what the default case is for new
+filenames. Default \fBlower\fR.
+.TP
+\fBpreserve case = yes/no\fR
+controls if new files are created with the
+case that the client passes, or if they are forced to be the
+"default" case. Default \fByes\fR.
+.TP
+\fBshort preserve case = yes/no\fR
+controls if new files which conform to 8.3 syntax,
+that is all in upper case and of suitable length, are created
+upper case, or if they are forced to be the "default"
+case. This option can be use with "preserve case = yes"
+to permit long filenames to retain their case, while short names
+are lowercased. Default \fByes\fR.
+.PP
+By default, Samba 2.2 has the same semantics as a Windows
+NT server, in that it is case insensitive but case preserving.
+.PP
+.SH "NOTE ABOUT USERNAME/PASSWORD VALIDATION"
+.PP
+There are a number of ways in which a user can connect
+to a service. The server uses the following steps in determining
+if it will allow a connection to a specified service. If all the
+steps fail, then the connection request is rejected. However, if one of the
+steps succeeds, then the following steps are not checked.
+.PP
+If the service is marked "guest only = yes" and the
+server is running with share-level security ("security = share")
+then steps 1 to 5 are skipped.
+.IP 1.
+If the client has passed a username/password
+pair and that username/password pair is validated by the UNIX
+system's password programs then the connection is made as that
+username. Note that this includes the
+\\\\server\\service%\fIusername\fR method of passing
+a username.
+.IP 2.
+If the client has previously registered a username
+with the system and now supplies a correct password for that
+username then the connection is allowed.
+.IP 3.
+The client's NetBIOS name and any previously
+used user names are checked against the supplied password, if
+they match then the connection is allowed as the corresponding
+user.
+.IP 4.
+If the client has previously validated a
+username/password pair with the server and the client has passed
+the validation token then that username is used.
+.IP 5.
+If a "user = " field is given in the
+\fIsmb.conf\fR file for the service and the client
+has supplied a password, and that password matches (according to
+the UNIX system's password checking) with one of the usernames
+from the "user =" field then the connection is made as
+the username in the "user =" line. If one
+of the username in the "user =" list begins with a
+\&'@' then that name expands to a list of names in
+the group of the same name.
+.IP 6.
+If the service is a guest service then a
+connection is made as the username given in the "guest
+account =" for the service, irrespective of the
+supplied password.
+.SH "COMPLETE LIST OF GLOBAL PARAMETERS"
+.PP
+Here is a list of all global parameters. See the section of
+each parameter for details. Note that some are synonyms.
+.TP 0.2i
+\(bu
+\fIacl compatibility\fR
+.TP 0.2i
+\(bu
+\fIadd printer command\fR
+.TP 0.2i
+\(bu
+\fIadd share command\fR
+.TP 0.2i
+\(bu
+\fIadd user script\fR
+.TP 0.2i
+\(bu
+\fIallow trusted domains\fR
+.TP 0.2i
+\(bu
+\fIannounce as\fR
+.TP 0.2i
+\(bu
+\fIannounce version\fR
+.TP 0.2i
+\(bu
+\fIauto services\fR
+.TP 0.2i
+\(bu
+\fIbind interfaces only\fR
+.TP 0.2i
+\(bu
+\fIbrowse list\fR
+.TP 0.2i
+\(bu
+\fIchange notify timeout\fR
+.TP 0.2i
+\(bu
+\fIchange share command\fR
+.TP 0.2i
+\(bu
+\fIcharacter set\fR
+.TP 0.2i
+\(bu
+\fIclient code page\fR
+.TP 0.2i
+\(bu
+\fIcode page directory\fR
+.TP 0.2i
+\(bu
+\fIcoding system\fR
+.TP 0.2i
+\(bu
+\fIconfig file\fR
+.TP 0.2i
+\(bu
+\fIdeadtime\fR
+.TP 0.2i
+\(bu
+\fIdebug hires timestamp\fR
+.TP 0.2i
+\(bu
+\fIdebug pid\fR
+.TP 0.2i
+\(bu
+\fIdebug timestamp\fR
+.TP 0.2i
+\(bu
+\fIdebug uid\fR
+.TP 0.2i
+\(bu
+\fIdebuglevel\fR
+.TP 0.2i
+\(bu
+\fIdefault\fR
+.TP 0.2i
+\(bu
+\fIdefault service\fR
+.TP 0.2i
+\(bu
+\fIdelete printer command\fR
+.TP 0.2i
+\(bu
+\fIdelete share command\fR
+.TP 0.2i
+\(bu
+\fIdelete user script\fR
+.TP 0.2i
+\(bu
+\fIdfree command\fR
+.TP 0.2i
+\(bu
+\fIdisable spoolss\fR
+.TP 0.2i
+\(bu
+\fIdns proxy\fR
+.TP 0.2i
+\(bu
+\fIdomain admin group\fR
+.TP 0.2i
+\(bu
+\fIdomain guest group\fR
+.TP 0.2i
+\(bu
+\fIdomain logons\fR
+.TP 0.2i
+\(bu
+\fIdomain master\fR
+.TP 0.2i
+\(bu
+\fIencrypt passwords\fR
+.TP 0.2i
+\(bu
+\fIenhanced browsing\fR
+.TP 0.2i
+\(bu
+\fIenumports command\fR
+.TP 0.2i
+\(bu
+\fIgetwd cache\fR
+.TP 0.2i
+\(bu
+\fIhide local users\fR
+.TP 0.2i
+\(bu
+\fIhide unreadable\fR
+.TP 0.2i
+\(bu
+\fIhomedir map\fR
+.TP 0.2i
+\(bu
+\fIhost msdfs\fR
+.TP 0.2i
+\(bu
+\fIhosts equiv\fR
+.TP 0.2i
+\(bu
+\fIinterfaces\fR
+.TP 0.2i
+\(bu
+\fIkeepalive\fR
+.TP 0.2i
+\(bu
+\fIkernel oplocks\fR
+.TP 0.2i
+\(bu
+\fIlanman auth\fR
+.TP 0.2i
+\(bu
+\fIlarge readwrite\fR
+.TP 0.2i
+\(bu
+\fIldap admin dn\fR
+.TP 0.2i
+\(bu
+\fIldap filter\fR
+.TP 0.2i
+\(bu
+\fIldap port\fR
+.TP 0.2i
+\(bu
+\fIldap server\fR
+.TP 0.2i
+\(bu
+\fIldap ssl\fR
+.TP 0.2i
+\(bu
+\fIldap suffix\fR
+.TP 0.2i
+\(bu
+\fIlm announce\fR
+.TP 0.2i
+\(bu
+\fIlm interval\fR
+.TP 0.2i
+\(bu
+\fIload printers\fR
+.TP 0.2i
+\(bu
+\fIlocal master\fR
+.TP 0.2i
+\(bu
+\fIlock dir\fR
+.TP 0.2i
+\(bu
+\fIlock directory\fR
+.TP 0.2i
+\(bu
+\fIlock spin count\fR
+.TP 0.2i
+\(bu
+\fIlock spin time\fR
+.TP 0.2i
+\(bu
+\fIpid directory\fR
+.TP 0.2i
+\(bu
+\fIlog file\fR
+.TP 0.2i
+\(bu
+\fIlog level\fR
+.TP 0.2i
+\(bu
+\fIlogon drive\fR
+.TP 0.2i
+\(bu
+\fIlogon home\fR
+.TP 0.2i
+\(bu
+\fIlogon path\fR
+.TP 0.2i
+\(bu
+\fIlogon script\fR
+.TP 0.2i
+\(bu
+\fIlpq cache time\fR
+.TP 0.2i
+\(bu
+\fImachine password timeout\fR
+.TP 0.2i
+\(bu
+\fImangled stack\fR
+.TP 0.2i
+\(bu
+\fImangling method\fR
+.TP 0.2i
+\(bu
+\fImap to guest\fR
+.TP 0.2i
+\(bu
+\fImax disk size\fR
+.TP 0.2i
+\(bu
+\fImax log size\fR
+.TP 0.2i
+\(bu
+\fImax mux\fR
+.TP 0.2i
+\(bu
+\fImax open files\fR
+.TP 0.2i
+\(bu
+\fImax protocol\fR
+.TP 0.2i
+\(bu
+\fImax smbd processes\fR
+.TP 0.2i
+\(bu
+\fImax ttl\fR
+.TP 0.2i
+\(bu
+\fImax wins ttl\fR
+.TP 0.2i
+\(bu
+\fImax xmit\fR
+.TP 0.2i
+\(bu
+\fImessage command\fR
+.TP 0.2i
+\(bu
+\fImin passwd length\fR
+.TP 0.2i
+\(bu
+\fImin password length\fR
+.TP 0.2i
+\(bu
+\fImin protocol\fR
+.TP 0.2i
+\(bu
+\fImin wins ttl\fR
+.TP 0.2i
+\(bu
+\fIname resolve order\fR
+.TP 0.2i
+\(bu
+\fInetbios aliases\fR
+.TP 0.2i
+\(bu
+\fInetbios name\fR
+.TP 0.2i
+\(bu
+\fInetbios scope\fR
+.TP 0.2i
+\(bu
+\fInis homedir\fR
+.TP 0.2i
+\(bu
+\fInt pipe support\fR
+.TP 0.2i
+\(bu
+\fInt smb support\fR
+.TP 0.2i
+\(bu
+\fInt status support\fR
+.TP 0.2i
+\(bu
+\fInull passwords\fR
+.TP 0.2i
+\(bu
+\fIobey pam restrictions\fR
+.TP 0.2i
+\(bu
+\fIoplock break wait time\fR
+.TP 0.2i
+\(bu
+\fIos level\fR
+.TP 0.2i
+\(bu
+\fIos2 driver map\fR
+.TP 0.2i
+\(bu
+\fIpam password change\fR
+.TP 0.2i
+\(bu
+\fIpanic action\fR
+.TP 0.2i
+\(bu
+\fIpasswd chat\fR
+.TP 0.2i
+\(bu
+\fIpasswd chat debug\fR
+.TP 0.2i
+\(bu
+\fIpasswd program\fR
+.TP 0.2i
+\(bu
+\fIpassword level\fR
+.TP 0.2i
+\(bu
+\fIpassword server\fR
+.TP 0.2i
+\(bu
+\fIprefered master\fR
+.TP 0.2i
+\(bu
+\fIpreferred master\fR
+.TP 0.2i
+\(bu
+\fIpreload\fR
+.TP 0.2i
+\(bu
+\fIprintcap\fR
+.TP 0.2i
+\(bu
+\fIprintcap name\fR
+.TP 0.2i
+\(bu
+\fIprinter driver file\fR
+.TP 0.2i
+\(bu
+\fIprotocol\fR
+.TP 0.2i
+\(bu
+\fIread bmpx\fR
+.TP 0.2i
+\(bu
+\fIread raw\fR
+.TP 0.2i
+\(bu
+\fIread size\fR
+.TP 0.2i
+\(bu
+\fIremote announce\fR
+.TP 0.2i
+\(bu
+\fIremote browse sync\fR
+.TP 0.2i
+\(bu
+\fIrestrict anonymous\fR
+.TP 0.2i
+\(bu
+\fIroot\fR
+.TP 0.2i
+\(bu
+\fIroot dir\fR
+.TP 0.2i
+\(bu
+\fIroot directory\fR
+.TP 0.2i
+\(bu
+\fIsecurity\fR
+.TP 0.2i
+\(bu
+\fIserver string\fR
+.TP 0.2i
+\(bu
+\fIshow add printer wizard\fR
+.TP 0.2i
+\(bu
+\fIsmb passwd file\fR
+.TP 0.2i
+\(bu
+\fIsocket address\fR
+.TP 0.2i
+\(bu
+\fIsocket options\fR
+.TP 0.2i
+\(bu
+\fIsource environment\fR
+.TP 0.2i
+\(bu
+\fIssl\fR
+.TP 0.2i
+\(bu
+\fIssl CA certDir\fR
+.TP 0.2i
+\(bu
+\fIssl CA certFile\fR
+.TP 0.2i
+\(bu
+\fIssl ciphers\fR
+.TP 0.2i
+\(bu
+\fIssl client cert\fR
+.TP 0.2i
+\(bu
+\fIssl client key\fR
+.TP 0.2i
+\(bu
+\fIssl compatibility\fR
+.TP 0.2i
+\(bu
+\fIssl egd socket\fR
+.TP 0.2i
+\(bu
+\fIssl entropy bytes\fR
+.TP 0.2i
+\(bu
+\fIssl entropy file\fR
+.TP 0.2i
+\(bu
+\fIssl hosts\fR
+.TP 0.2i
+\(bu
+\fIssl hosts resign\fR
+.TP 0.2i
+\(bu
+\fIssl require clientcert\fR
+.TP 0.2i
+\(bu
+\fIssl require servercert\fR
+.TP 0.2i
+\(bu
+\fIssl server cert\fR
+.TP 0.2i
+\(bu
+\fIssl server key\fR
+.TP 0.2i
+\(bu
+\fIssl version\fR
+.TP 0.2i
+\(bu
+\fIstat cache\fR
+.TP 0.2i
+\(bu
+\fIstat cache size\fR
+.TP 0.2i
+\(bu
+\fIstrip dot\fR
+.TP 0.2i
+\(bu
+\fIsyslog\fR
+.TP 0.2i
+\(bu
+\fIsyslog only\fR
+.TP 0.2i
+\(bu
+\fItemplate homedir\fR
+.TP 0.2i
+\(bu
+\fItemplate shell\fR
+.TP 0.2i
+\(bu
+\fItime offset\fR
+.TP 0.2i
+\(bu
+\fItime server\fR
+.TP 0.2i
+\(bu
+\fItimestamp logs\fR
+.TP 0.2i
+\(bu
+\fItotal print jobs\fR
+.TP 0.2i
+\(bu
+\fIunix extensions\fR
+.TP 0.2i
+\(bu
+\fIunix password sync\fR
+.TP 0.2i
+\(bu
+\fIupdate encrypted\fR
+.TP 0.2i
+\(bu
+\fIuse mmap\fR
+.TP 0.2i
+\(bu
+\fIuse rhosts\fR
+.TP 0.2i
+\(bu
+\fIusername level\fR
+.TP 0.2i
+\(bu
+\fIusername map\fR
+.TP 0.2i
+\(bu
+\fIutmp\fR
+.TP 0.2i
+\(bu
+\fIutmp directory\fR
+.TP 0.2i
+\(bu
+\fIvalid chars\fR
+.TP 0.2i
+\(bu
+\fIwinbind cache time\fR
+.TP 0.2i
+\(bu
+\fIwinbind enum users\fR
+.TP 0.2i
+\(bu
+\fIwinbind enum groups\fR
+.TP 0.2i
+\(bu
+\fIwinbind gid\fR
+.TP 0.2i
+\(bu
+\fIwinbind separator\fR
+.TP 0.2i
+\(bu
+\fIwinbind uid\fR
+.TP 0.2i
+\(bu
+\fIwinbind use default domain\fR
+.TP 0.2i
+\(bu
+\fIwins hook\fR
+.TP 0.2i
+\(bu
+\fIwins proxy\fR
+.TP 0.2i
+\(bu
+\fIwins server\fR
+.TP 0.2i
+\(bu
+\fIwins support\fR
+.TP 0.2i
+\(bu
+\fIworkgroup\fR
+.TP 0.2i
+\(bu
+\fIwrite raw\fR
+.SH "COMPLETE LIST OF SERVICE PARAMETERS"
+.PP
+Here is a list of all service parameters. See the section on
+each parameter for details. Note that some are synonyms.
+.TP 0.2i
+\(bu
+\fIadmin users\fR
+.TP 0.2i
+\(bu
+\fIallow hosts\fR
+.TP 0.2i
+\(bu
+\fIavailable\fR
+.TP 0.2i
+\(bu
+\fIblocking locks\fR
+.TP 0.2i
+\(bu
+\fIblock size\fR
+.TP 0.2i
+\(bu
+\fIbrowsable\fR
+.TP 0.2i
+\(bu
+\fIbrowseable\fR
+.TP 0.2i
+\(bu
+\fIcase sensitive\fR
+.TP 0.2i
+\(bu
+\fIcasesignames\fR
+.TP 0.2i
+\(bu
+\fIcomment\fR
+.TP 0.2i
+\(bu
+\fIcopy\fR
+.TP 0.2i
+\(bu
+\fIcreate mask\fR
+.TP 0.2i
+\(bu
+\fIcreate mode\fR
+.TP 0.2i
+\(bu
+\fIcsc policy\fR
+.TP 0.2i
+\(bu
+\fIdefault case\fR
+.TP 0.2i
+\(bu
+\fIdefault devmode\fR
+.TP 0.2i
+\(bu
+\fIdelete readonly\fR
+.TP 0.2i
+\(bu
+\fIdelete veto files\fR
+.TP 0.2i
+\(bu
+\fIdeny hosts\fR
+.TP 0.2i
+\(bu
+\fIdirectory\fR
+.TP 0.2i
+\(bu
+\fIdirectory mask\fR
+.TP 0.2i
+\(bu
+\fIdirectory mode\fR
+.TP 0.2i
+\(bu
+\fIdirectory security mask\fR
+.TP 0.2i
+\(bu
+\fIdont descend\fR
+.TP 0.2i
+\(bu
+\fIdos filemode\fR
+.TP 0.2i
+\(bu
+\fIdos filetime resolution\fR
+.TP 0.2i
+\(bu
+\fIdos filetimes\fR
+.TP 0.2i
+\(bu
+\fIexec\fR
+.TP 0.2i
+\(bu
+\fIfake directory create times\fR
+.TP 0.2i
+\(bu
+\fIfake oplocks\fR
+.TP 0.2i
+\(bu
+\fIfollow symlinks\fR
+.TP 0.2i
+\(bu
+\fIforce create mode\fR
+.TP 0.2i
+\(bu
+\fIforce directory mode\fR
+.TP 0.2i
+\(bu
+\fIforce directory security mode\fR
+.TP 0.2i
+\(bu
+\fIforce group\fR
+.TP 0.2i
+\(bu
+\fIforce security mode\fR
+.TP 0.2i
+\(bu
+\fIforce unknown acl user\fR
+.TP 0.2i
+\(bu
+\fIforce user\fR
+.TP 0.2i
+\(bu
+\fIfstype\fR
+.TP 0.2i
+\(bu
+\fIgroup\fR
+.TP 0.2i
+\(bu
+\fIguest account\fR
+.TP 0.2i
+\(bu
+\fIguest ok\fR
+.TP 0.2i
+\(bu
+\fIguest only\fR
+.TP 0.2i
+\(bu
+\fIhide dot files\fR
+.TP 0.2i
+\(bu
+\fIhide files\fR
+.TP 0.2i
+\(bu
+\fIhosts allow\fR
+.TP 0.2i
+\(bu
+\fIhosts deny\fR
+.TP 0.2i
+\(bu
+\fIinclude\fR
+.TP 0.2i
+\(bu
+\fIinherit acls\fR
+.TP 0.2i
+\(bu
+\fIinherit permissions\fR
+.TP 0.2i
+\(bu
+\fIinvalid users\fR
+.TP 0.2i
+\(bu
+\fIlevel2 oplocks\fR
+.TP 0.2i
+\(bu
+\fIlocking\fR
+.TP 0.2i
+\(bu
+\fIlppause command\fR
+.TP 0.2i
+\(bu
+\fIlpq command\fR
+.TP 0.2i
+\(bu
+\fIlpresume command\fR
+.TP 0.2i
+\(bu
+\fIlprm command\fR
+.TP 0.2i
+\(bu
+\fImagic output\fR
+.TP 0.2i
+\(bu
+\fImagic script\fR
+.TP 0.2i
+\(bu
+\fImangle case\fR
+.TP 0.2i
+\(bu
+\fImangled map\fR
+.TP 0.2i
+\(bu
+\fImangled names\fR
+.TP 0.2i
+\(bu
+\fImangling char\fR
+.TP 0.2i
+\(bu
+\fImap archive\fR
+.TP 0.2i
+\(bu
+\fImap hidden\fR
+.TP 0.2i
+\(bu
+\fImap system\fR
+.TP 0.2i
+\(bu
+\fImax connections\fR
+.TP 0.2i
+\(bu
+\fImax print jobs\fR
+.TP 0.2i
+\(bu
+\fImin print space\fR
+.TP 0.2i
+\(bu
+\fImsdfs root\fR
+.TP 0.2i
+\(bu
+\fInt acl support\fR
+.TP 0.2i
+\(bu
+\fIonly guest\fR
+.TP 0.2i
+\(bu
+\fIonly user\fR
+.TP 0.2i
+\(bu
+\fIoplock contention limit\fR
+.TP 0.2i
+\(bu
+\fIoplocks\fR
+.TP 0.2i
+\(bu
+\fIpath\fR
+.TP 0.2i
+\(bu
+\fIposix locking\fR
+.TP 0.2i
+\(bu
+\fIpostexec\fR
+.TP 0.2i
+\(bu
+\fIpostscript\fR
+.TP 0.2i
+\(bu
+\fIpreexec\fR
+.TP 0.2i
+\(bu
+\fIpreexec close\fR
+.TP 0.2i
+\(bu
+\fIpreserve case\fR
+.TP 0.2i
+\(bu
+\fIprint command\fR
+.TP 0.2i
+\(bu
+\fIprint ok\fR
+.TP 0.2i
+\(bu
+\fIprintable\fR
+.TP 0.2i
+\(bu
+\fIprinter\fR
+.TP 0.2i
+\(bu
+\fIprinter admin\fR
+.TP 0.2i
+\(bu
+\fIprinter driver\fR
+.TP 0.2i
+\(bu
+\fIprinter driver location\fR
+.TP 0.2i
+\(bu
+\fIprinter name\fR
+.TP 0.2i
+\(bu
+\fIprinting\fR
+.TP 0.2i
+\(bu
+\fIprofile acls\fR
+.TP 0.2i
+\(bu
+\fIpublic\fR
+.TP 0.2i
+\(bu
+\fIqueuepause command\fR
+.TP 0.2i
+\(bu
+\fIqueueresume command\fR
+.TP 0.2i
+\(bu
+\fIread list\fR
+.TP 0.2i
+\(bu
+\fIread only\fR
+.TP 0.2i
+\(bu
+\fIroot postexec\fR
+.TP 0.2i
+\(bu
+\fIroot preexec\fR
+.TP 0.2i
+\(bu
+\fIroot preexec close\fR
+.TP 0.2i
+\(bu
+\fIsecurity mask\fR
+.TP 0.2i
+\(bu
+\fIset directory\fR
+.TP 0.2i
+\(bu
+\fIshare modes\fR
+.TP 0.2i
+\(bu
+\fIshort preserve case\fR
+.TP 0.2i
+\(bu
+\fIstatus\fR
+.TP 0.2i
+\(bu
+\fIstrict allocate\fR
+.TP 0.2i
+\(bu
+\fIstrict locking\fR
+.TP 0.2i
+\(bu
+\fIstrict sync\fR
+.TP 0.2i
+\(bu
+\fIsync always\fR
+.TP 0.2i
+\(bu
+\fIuse client driver\fR
+.TP 0.2i
+\(bu
+\fIuse sendfile\fR
+.TP 0.2i
+\(bu
+\fIuser\fR
+.TP 0.2i
+\(bu
+\fIusername\fR
+.TP 0.2i
+\(bu
+\fIusers\fR
+.TP 0.2i
+\(bu
+\fIvalid users\fR
+.TP 0.2i
+\(bu
+\fIveto files\fR
+.TP 0.2i
+\(bu
+\fIveto oplock files\fR
+.TP 0.2i
+\(bu
+\fIvfs object\fR
+.TP 0.2i
+\(bu
+\fIvfs options\fR
+.TP 0.2i
+\(bu
+\fIvolume\fR
+.TP 0.2i
+\(bu
+\fIwide links\fR
+.TP 0.2i
+\(bu
+\fIwritable\fR
+.TP 0.2i
+\(bu
+\fIwrite cache size\fR
+.TP 0.2i
+\(bu
+\fIwrite list\fR
+.TP 0.2i
+\(bu
+\fIwrite ok\fR
+.TP 0.2i
+\(bu
+\fIwriteable\fR
+.SH "EXPLANATION OF EACH PARAMETER"
+.TP
+\fBacl compatibility (G)\fR
+New in Samba 2.2.8 and above, this string parameter tells
+smbd if it should modify any Windows access control lists created
+from POSIX access control lists to remove features which are not
+supported by Windows 2000 but not supported by the Windows NT ACL edit.
+control.
+
+By default this parameter is set automatically by detecting the
+client type and is set to "true" if the client is Windows NT.
+
+Default: \fBclient detected\fR
+
+Example: \fBacl compatibility = Win2k\fR
+
+Example: \fBacl compatibility = winnt\fR
+.TP
+\fBadd printer command (G)\fR
+With the introduction of MS-RPC based printing
+support for Windows NT/2000 clients in Samba 2.2, The MS Add
+Printer Wizard (APW) icon is now also available in the
+"Printers..." folder displayed a share listing. The APW
+allows for printers to be add remotely to a Samba or Windows
+NT/2000 print server.
+
+For a Samba host this means that the printer must be
+physically added to the underlying printing system. The \fIadd
+printer command\fR defines a script to be run which
+will perform the necessary operations for adding the printer
+to the print system and to add the appropriate service definition
+to the \fIsmb.conf\fR file in order that it can be
+shared by \fBsmbd(8)\fR
+
+
+The \fIadd printer command\fR is
+automatically invoked with the following parameter (in
+order:
+.RS
+.TP 0.2i
+\(bu
+\fIprinter name\fR
+.TP 0.2i
+\(bu
+\fIshare name\fR
+.TP 0.2i
+\(bu
+\fIport name\fR
+.TP 0.2i
+\(bu
+\fIdriver name\fR
+.TP 0.2i
+\(bu
+\fIlocation\fR
+.TP 0.2i
+\(bu
+\fIWindows 9x driver location\fR
+.RE
+.PP
+All parameters are filled in from the PRINTER_INFO_2 structure sent
+by the Windows NT/2000 client with one exception. The "Windows 9x
+driver location" parameter is included for backwards compatibility
+only. The remaining fields in the structure are generated from answers
+to the APW questions.
+.PP
+.PP
+Once the \fIadd printer command\fR has
+been executed, \fBsmbd\fR will reparse the \fI smb.conf\fR to determine if the share defined by the APW
+exists. If the sharename is still invalid, then \fBsmbd
+\fRwill return an ACCESS_DENIED error to the client.
+.PP
+.PP
+See also \fI delete printer command\fR, \fIprinting\fR,
+\fIshow add
+printer wizard\fR
+.PP
+.PP
+Default: \fBnone\fR
+.PP
+.PP
+Example: \fBaddprinter command = /usr/bin/addprinter
+\fR.PP
+.TP
+\fBadd share command (G)\fR
+Samba 2.2.0 introduced the ability to dynamically
+add and delete shares via the Windows NT 4.0 Server Manager. The
+\fIadd share command\fR is used to define an
+external program or script which will add a new service definition
+to \fIsmb.conf\fR. In order to successfully
+execute the \fIadd share command\fR, \fBsmbd\fR
+requires that the administrator be connected using a root account (i.e.
+uid == 0).
+
+When executed, \fBsmbd\fR will automatically invoke the
+\fIadd share command\fR with four parameters.
+.RS
+.TP 0.2i
+\(bu
+\fIconfigFile\fR - the location
+of the global \fIsmb.conf\fR file.
+.TP 0.2i
+\(bu
+\fIshareName\fR - the name of the new
+share.
+.TP 0.2i
+\(bu
+\fIpathName\fR - path to an **existing**
+directory on disk.
+.TP 0.2i
+\(bu
+\fIcomment\fR - comment string to associate
+with the new share.
+.RE
+.PP
+This parameter is only used for add file shares. To add printer shares,
+see the \fIadd printer
+command\fR.
+.PP
+.PP
+See also \fIchange share
+command\fR, \fIdelete share
+command\fR.
+.PP
+.PP
+Default: \fBnone\fR
+.PP
+.PP
+Example: \fBadd share command = /usr/local/bin/addshare\fR
+.PP
+.TP
+\fBadd user script (G)\fR
+This is the full pathname to a script that will
+be run \fBAS ROOT\fR by smbd(8)
+ under special circumstances described below.
+
+Normally, a Samba server requires that UNIX users are
+created for all users accessing files on this server. For sites
+that use Windows NT account databases as their primary user database
+creating these users and keeping the user list in sync with the
+Windows NT PDC is an onerous task. This option allows smbd to create the required UNIX users
+\fBON DEMAND\fR when a user accesses the Samba server.
+
+In order to use this option, smbd
+must \fBNOT\fR be set to \fIsecurity = share\fR
+and \fIadd user script\fR
+must be set to a full pathname for a script that will create a UNIX
+user given one argument of \fI%u\fR, which expands into
+the UNIX user name to create.
+
+When the Windows user attempts to access the Samba server,
+at login (session setup in the SMB protocol) time, smbd contacts the \fIpassword server\fR and
+attempts to authenticate the given user with the given password. If the
+authentication succeeds then \fBsmbd\fR
+attempts to find a UNIX user in the UNIX password database to map the
+Windows user into. If this lookup fails, and \fIadd user script
+\fRis set then \fBsmbd\fR will
+call the specified script \fBAS ROOT\fR, expanding
+any \fI%u\fR argument to be the user name to create.
+
+If this script successfully creates the user then \fBsmbd
+\fRwill continue on as though the UNIX user
+already existed. In this way, UNIX users are dynamically created to
+match existing Windows NT accounts.
+
+See also \fI security\fR, \fIpassword server\fR,
+\fIdelete user
+script\fR.
+
+Default: \fBadd user script = <empty string>
+\fR
+Example: \fBadd user script = /usr/local/samba/bin/add_user
+%u\fR
+.TP
+\fBadmin users (S)\fR
+This is a list of users who will be granted
+administrative privileges on the share. This means that they
+will do all file operations as the super-user (root).
+
+You should use this option very carefully, as any user in
+this list will be able to do anything they like on the share,
+irrespective of file permissions.
+
+Default: \fBno admin users\fR
+
+Example: \fBadmin users = jason\fR
+.TP
+\fBallow hosts (S)\fR
+Synonym for \fIhosts allow\fR.
+.TP
+\fBallow trusted domains (G)\fR
+This option only takes effect when the \fIsecurity\fR option is set to
+server or domain.
+If it is set to no, then attempts to connect to a resource from
+a domain or workgroup other than the one which smbd is running
+in will fail, even if that domain is trusted by the remote server
+doing the authentication.
+
+This is useful if you only want your Samba server to
+serve resources to users in the domain it is a member of. As
+an example, suppose that there are two domains DOMA and DOMB. DOMB
+is trusted by DOMA, which contains the Samba server. Under normal
+circumstances, a user with an account in DOMB can then access the
+resources of a UNIX account with the same account name on the
+Samba server even if they do not have an account in DOMA. This
+can make implementing a security boundary difficult.
+
+Default: \fBallow trusted domains = yes\fR
+.TP
+\fBannounce as (G)\fR
+This specifies what type of server
+\fBnmbd\fR
+will announce itself as, to a network neighborhood browse
+list. By default this is set to Windows NT. The valid options
+are : "NT Server" (which can also be written as "NT"),
+"NT Workstation", "Win95" or "WfW" meaning Windows NT Server,
+Windows NT Workstation, Windows 95 and Windows for Workgroups
+respectively. Do not change this parameter unless you have a
+specific need to stop Samba appearing as an NT server as this
+may prevent Samba servers from participating as browser servers
+correctly.
+
+Default: \fBannounce as = NT Server\fR
+
+Example: \fBannounce as = Win95\fR
+.TP
+\fBannounce version (G)\fR
+This specifies the major and minor version numbers
+that nmbd will use when announcing itself as a server. The default
+is 4.9. Do not change this parameter unless you have a specific
+need to set a Samba server to be a downlevel server.
+
+Default: \fBannounce version = 4.9\fR
+
+Example: \fBannounce version = 2.0\fR
+.TP
+\fBauto services (G)\fR
+This is a synonym for the \fIpreload\fR.
+.TP
+\fBavailable (S)\fR
+This parameter lets you "turn off" a service. If
+\fIavailable = no\fR, then \fBALL\fR
+attempts to connect to the service will fail. Such failures are
+logged.
+
+Default: \fBavailable = yes\fR
+.TP
+\fBbind interfaces only (G)\fR
+This global parameter allows the Samba admin
+to limit what interfaces on a machine will serve SMB requests. If
+affects file service smbd(8) and
+name service nmbd(8) in slightly
+different ways.
+
+For name service it causes \fBnmbd\fR to bind
+to ports 137 and 138 on the interfaces listed in the interfaces parameter. \fBnmbd
+\fRalso binds to the "all addresses" interface (0.0.0.0)
+on ports 137 and 138 for the purposes of reading broadcast messages.
+If this option is not set then \fBnmbd\fR will service
+name requests on all of these sockets. If \fIbind interfaces
+only\fR is set then \fBnmbd\fR will check the
+source address of any packets coming in on the broadcast sockets
+and discard any that don't match the broadcast addresses of the
+interfaces in the \fIinterfaces\fR parameter list.
+As unicast packets are received on the other sockets it allows
+\fBnmbd\fR to refuse to serve names to machines that
+send packets that arrive through any interfaces not listed in the
+\fIinterfaces\fR list. IP Source address spoofing
+does defeat this simple check, however so it must not be used
+seriously as a security feature for \fBnmbd\fR.
+
+For file service it causes smbd(8)
+to bind only to the interface list given in the interfaces parameter. This restricts the networks that
+\fBsmbd\fR will serve to packets coming in those
+interfaces. Note that you should not use this parameter for machines
+that are serving PPP or other intermittent or non-broadcast network
+interfaces as it will not cope with non-permanent interfaces.
+
+If \fIbind interfaces only\fR is set then
+unless the network address \fB127.0.0.1\fR is added
+to the \fIinterfaces\fR parameter list \fBsmbpasswd(8)\fR
+and \fBswat(8)\fR may
+not work as expected due to the reasons covered below.
+
+To change a users SMB password, the \fBsmbpasswd\fR
+by default connects to the \fBlocalhost - 127.0.0.1\fR
+address as an SMB client to issue the password change request. If
+\fIbind interfaces only\fR is set then unless the
+network address \fB127.0.0.1\fR is added to the
+\fIinterfaces\fR parameter list then \fB smbpasswd\fR will fail to connect in it's default mode.
+\fBsmbpasswd\fR can be forced to use the primary IP interface
+of the local host by using its \fI-r remote machine\fR
+ parameter, with \fIremote machine\fR set
+to the IP name of the primary interface of the local host.
+
+The \fBswat\fR status page tries to connect with
+\fBsmbd\fR and \fBnmbd\fR at the address
+\fB127.0.0.1\fR to determine if they are running.
+Not adding \fB127.0.0.1\fR will cause \fB smbd\fR and \fBnmbd\fR to always show
+"not running" even if they really are. This can prevent \fB swat\fR from starting/stopping/restarting \fBsmbd\fR
+and \fBnmbd\fR.
+
+Default: \fBbind interfaces only = no\fR
+.TP
+\fBblock size (S)\fR
+This parameter controls the behavior of smbd(8) when reporting disk free sizes.
+By default, this reports a disk block size of 1024 bytes.
+
+Changing this parameter may have some effect on the
+efficiency of client writes, this is not yet confirmed. This
+parameter was added to allow advanced administrators to change
+it (usually to a higher value) and test the effect it has on
+client write performance without re-compiling the code. As this
+is an experimental option it may be removed in a future release.
+
+Changing this option does not change the disk free reporting
+size, just the block size unit reported to the client.
+
+Default: \fBblock size = 1024\fR
+
+Example: \fBblock size = 65536\fR
+.TP
+\fBblocking locks (S)\fR
+This parameter controls the behavior of smbd(8) when given a request by a client
+to obtain a byte range lock on a region of an open file, and the
+request has a time limit associated with it.
+
+If this parameter is set and the lock range requested
+cannot be immediately satisfied, Samba 2.2 will internally
+queue the lock request, and periodically attempt to obtain
+the lock until the timeout period expires.
+
+If this parameter is set to no, then
+Samba 2.2 will behave as previous versions of Samba would and
+will fail the lock request immediately if the lock range
+cannot be obtained.
+
+Default: \fBblocking locks = yes\fR
+.TP
+\fBbrowsable (S)\fR
+See the \fI browseable\fR.
+.TP
+\fBbrowse list (G)\fR
+This controls whether \fBsmbd(8)\fR will serve a browse list to
+a client doing a \fBNetServerEnum\fR call. Normally
+set to yes. You should never need to change
+this.
+
+Default: \fBbrowse list = yes\fR
+.TP
+\fBbrowseable (S)\fR
+This controls whether this share is seen in
+the list of available shares in a net view and in the browse list.
+
+Default: \fBbrowseable = yes\fR
+.TP
+\fBcase sensitive (S)\fR
+See the discussion in the section NAME MANGLING.
+
+Default: \fBcase sensitive = no\fR
+.TP
+\fBcasesignames (S)\fR
+Synonym for case
+sensitive.
+.TP
+\fBchange notify timeout (G)\fR
+This SMB allows a client to tell a server to
+"watch" a particular directory for any changes and only reply to
+the SMB request when a change has occurred. Such constant scanning of
+a directory is expensive under UNIX, hence an \fBsmbd(8)\fR daemon only performs such a scan
+on each requested directory once every \fIchange notify
+timeout\fR seconds.
+
+Default: \fBchange notify timeout = 60\fR
+
+Example: \fBchange notify timeout = 300\fR
+
+Would change the scan time to every 5 minutes.
+.TP
+\fBchange share command (G)\fR
+Samba 2.2.0 introduced the ability to dynamically
+add and delete shares via the Windows NT 4.0 Server Manager. The
+\fIchange share command\fR is used to define an
+external program or script which will modify an existing service definition
+in \fIsmb.conf\fR. In order to successfully
+execute the \fIchange share command\fR, \fBsmbd\fR
+requires that the administrator be connected using a root account (i.e.
+uid == 0).
+
+When executed, \fBsmbd\fR will automatically invoke the
+\fIchange share command\fR with four parameters.
+.RS
+.TP 0.2i
+\(bu
+\fIconfigFile\fR - the location
+of the global \fIsmb.conf\fR file.
+.TP 0.2i
+\(bu
+\fIshareName\fR - the name of the new
+share.
+.TP 0.2i
+\(bu
+\fIpathName\fR - path to an **existing**
+directory on disk.
+.TP 0.2i
+\(bu
+\fIcomment\fR - comment string to associate
+with the new share.
+.RE
+.PP
+This parameter is only used modify existing file shares definitions. To modify
+printer shares, use the "Printers..." folder as seen when browsing the Samba host.
+.PP
+.PP
+See also \fIadd share
+command\fR, \fIdelete
+share command\fR.
+.PP
+.PP
+Default: \fBnone\fR
+.PP
+.PP
+Example: \fBchange share command = /usr/local/bin/addshare\fR
+.PP
+.TP
+\fBcharacter set (G)\fR
+This allows smbd to map incoming filenames
+from a DOS Code page (see the client
+code page parameter) to several built in UNIX character sets.
+The built in code page translations are:
+.RS
+.TP 0.2i
+\(bu
+ISO8859-1 : Western European
+UNIX character set. The parameter \fIclient code page\fR
+\fBMUST\fR be set to code page 850 if the
+\fIcharacter set\fR parameter is set to
+ISO8859-1 in order for the conversion to the
+UNIX character set to be done correctly.
+.TP 0.2i
+\(bu
+ISO8859-2 : Eastern European
+UNIX character set. The parameter \fIclient code page
+\fR\fBMUST\fR be set to code page 852 if
+the \fI character set\fR parameter is set
+to ISO8859-2 in order for the conversion
+to the UNIX character set to be done correctly.
+.TP 0.2i
+\(bu
+ISO8859-5 : Russian Cyrillic
+UNIX character set. The parameter \fIclient code page
+\fR\fBMUST\fR be set to code page
+866 if the \fIcharacter set \fR parameter is
+set to ISO8859-5 in order for the conversion
+to the UNIX character set to be done correctly.
+.TP 0.2i
+\(bu
+ISO8859-7 : Greek UNIX
+character set. The parameter \fIclient code page
+\fR\fBMUST\fR be set to code page
+737 if the \fIcharacter set\fR parameter is
+set to ISO8859-7 in order for the conversion
+to the UNIX character set to be done correctly.
+.TP 0.2i
+\(bu
+KOI8-R : Alternate mapping
+for Russian Cyrillic UNIX character set. The parameter
+\fIclient code page\fR \fBMUST\fR
+be set to code page 866 if the \fIcharacter set\fR
+parameter is set to KOI8-R in order for the
+conversion to the UNIX character set to be done correctly.
+.RE
+.PP
+\fBBUG\fR. These MSDOS code page to UNIX character
+set mappings should be dynamic, like the loading of MS DOS code pages,
+not static.
+.PP
+.PP
+Normally this parameter is not set, meaning no filename
+translation is done.
+.PP
+.PP
+Default: \fBcharacter set = <empty string>\fR
+.PP
+.PP
+Example: \fBcharacter set = ISO8859-1\fR
+.PP
+.TP
+\fBclient code page (G)\fR
+This parameter specifies the DOS code page
+that the clients accessing Samba are using. To determine what code
+page a Windows or DOS client is using, open a DOS command prompt
+and type the command \fBchcp\fR. This will output
+the code page. The default for USA MS-DOS, Windows 95, and
+Windows NT releases is code page 437. The default for western
+European releases of the above operating systems is code page 850.
+
+This parameter tells smbd(8)
+which of the \fIcodepage.XXX
+\fRfiles to dynamically load on startup. These files,
+described more fully in the manual page \fBmake_smbcodepage(1)\fR tell \fB smbd\fR how to map lower to upper case characters to provide
+the case insensitivity of filenames that Windows clients expect.
+
+Samba currently ships with the following code page files :
+.RS
+.TP 0.2i
+\(bu
+Code Page 437 - MS-DOS Latin US
+.TP 0.2i
+\(bu
+Code Page 737 - Windows '95 Greek
+.TP 0.2i
+\(bu
+Code Page 850 - MS-DOS Latin 1
+.TP 0.2i
+\(bu
+Code Page 852 - MS-DOS Latin 2
+.TP 0.2i
+\(bu
+Code Page 861 - MS-DOS Icelandic
+.TP 0.2i
+\(bu
+Code Page 866 - MS-DOS Cyrillic
+.TP 0.2i
+\(bu
+Code Page 932 - MS-DOS Japanese SJIS
+.TP 0.2i
+\(bu
+Code Page 936 - MS-DOS Simplified Chinese
+.TP 0.2i
+\(bu
+Code Page 949 - MS-DOS Korean Hangul
+.TP 0.2i
+\(bu
+Code Page 950 - MS-DOS Traditional Chinese
+.RE
+.PP
+Thus this parameter may have any of the values 437, 737, 850, 852,
+861, 932, 936, 949, or 950. If you don't find the codepage you need,
+read the comments in one of the other codepage files and the
+\fBmake_smbcodepage(1)\fR man page and write one. Please
+remember to donate it back to the Samba user community.
+.PP
+.PP
+This parameter co-operates with the \fIvalid
+chars\fR parameter in determining what characters are
+valid in filenames and how capitalization is done. If you set both
+this parameter and the \fIvalid chars\fR parameter
+the \fIclient code page\fR parameter
+\fBMUST\fR be set before the \fIvalid
+chars\fR parameter in the \fIsmb.conf\fR
+file. The \fIvalid chars\fR string will then
+augment the character settings in the \fIclient code page\fR
+parameter.
+.PP
+.PP
+If not set, \fIclient code page\fR defaults
+to 850.
+.PP
+.PP
+See also : \fIvalid
+chars\fR, \fIcode page directory\fR
+.PP
+.PP
+Default: \fBclient code page = 850\fR
+.PP
+.PP
+Example: \fBclient code page = 936\fR
+.PP
+.TP
+\fBcode page directory (G)\fR
+Define the location of the various client code page
+files.
+
+See also \fIclient
+code page\fR
+
+Default: \fBcode page directory = ${prefix}/lib/codepages
+\fR
+Example: \fBcode page directory = /usr/share/samba/codepages
+\fR.TP
+\fBcoding system (G)\fR
+This parameter is used to determine how incoming
+Shift-JIS Japanese characters are mapped from the incoming \fIclient code page\fR
+used by the client, into file names in the UNIX filesystem.
+Only useful if \fIclient code page\fR is set to
+932 (Japanese Shift-JIS). The options are :
+.RS
+.TP 0.2i
+\(bu
+SJIS - Shift-JIS. Does no
+conversion of the incoming filename.
+.TP 0.2i
+\(bu
+JIS8, J8BB, J8BH, J8@B,
+J8@J, J8@H - Convert from incoming Shift-JIS to eight
+bit JIS code with different shift-in, shift out codes.
+.TP 0.2i
+\(bu
+JIS7, J7BB, J7BH, J7@B, J7@J,
+J7@H - Convert from incoming Shift-JIS to seven bit
+JIS code with different shift-in, shift out codes.
+.TP 0.2i
+\(bu
+JUNET, JUBB, JUBH, JU@B, JU@J, JU@H
+- Convert from incoming Shift-JIS to JUNET code with different shift-in,
+shift out codes.
+.TP 0.2i
+\(bu
+EUC - Convert an incoming
+Shift-JIS character to EUC code.
+.TP 0.2i
+\(bu
+HEX - Convert an incoming
+Shift-JIS character to a 3 byte hex representation, i.e.
+:AB.
+.TP 0.2i
+\(bu
+CAP - Convert an incoming
+Shift-JIS character to the 3 byte hex representation used by
+the Columbia AppleTalk Program (CAP), i.e. :AB.
+This is used for compatibility between Samba and CAP.
+.RE
+.PP
+Default: \fBcoding system = <empty value>\fR
+.PP
+.TP
+\fBcomment (S)\fR
+This is a text field that is seen next to a share
+when a client does a queries the server, either via the network
+neighborhood or via \fBnet view\fR to list what shares
+are available.
+
+If you want to set the string that is displayed next to the
+machine name then see the \fI server string\fR parameter.
+
+Default: \fBNo comment string\fR
+
+Example: \fBcomment = Fred's Files\fR
+.TP
+\fBconfig file (G)\fR
+This allows you to override the config file
+to use, instead of the default (usually \fIsmb.conf\fR).
+There is a chicken and egg problem here as this option is set
+in the config file!
+
+For this reason, if the name of the config file has changed
+when the parameters are loaded then it will reload them from
+the new config file.
+
+This option takes the usual substitutions, which can
+be very useful.
+
+If the config file doesn't exist then it won't be loaded
+(allowing you to special case the config files of just a few
+clients).
+
+Example: \fBconfig file = /usr/local/samba/lib/smb.conf.%m
+\fR.TP
+\fBcopy (S)\fR
+This parameter allows you to "clone" service
+entries. The specified service is simply duplicated under the
+current service's name. Any parameters specified in the current
+section will override those in the section being copied.
+
+This feature lets you set up a 'template' service and
+create similar services easily. Note that the service being
+copied must occur earlier in the configuration file than the
+service doing the copying.
+
+Default: \fBno value\fR
+
+Example: \fBcopy = otherservice\fR
+.TP
+\fBcreate mask (S)\fR
+A synonym for this parameter is
+\fIcreate mode\fR
+\&.
+
+When a file is created, the necessary permissions are
+calculated according to the mapping from DOS modes to UNIX
+permissions, and the resulting UNIX mode is then bit-wise 'AND'ed
+with this parameter. This parameter may be thought of as a bit-wise
+MASK for the UNIX modes of a file. Any bit \fBnot\fR
+set here will be removed from the modes set on a file when it is
+created.
+
+The default value of this parameter removes the
+\&'group' and 'other' write and execute bits from the UNIX modes.
+
+Following this Samba will bit-wise 'OR' the UNIX mode created
+from this parameter with the value of the \fIforce create mode\fR
+parameter which is set to 000 by default.
+
+This parameter does not affect directory modes. See the
+parameter \fIdirectory mode
+\fRfor details.
+
+See also the \fIforce
+create mode\fR parameter for forcing particular mode
+bits to be set on created files. See also the \fIdirectory mode\fR parameter for masking
+mode bits on created directories. See also the \fIinherit permissions\fR parameter.
+
+Note that this parameter does not apply to permissions
+set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+a mask on access control lists also, they need to set the \fIsecurity mask\fR.
+
+Default: \fBcreate mask = 0744\fR
+
+Example: \fBcreate mask = 0775\fR
+.TP
+\fBcreate mode (S)\fR
+This is a synonym for \fI create mask\fR.
+.TP
+\fBcsc policy (S)\fR
+This stands for \fBclient-side caching
+policy\fR, and specifies how clients capable of offline
+caching will cache the files in the share. The valid values
+are: manual, documents, programs, disable.
+
+These values correspond to those used on Windows
+servers.
+
+For example, shares containing roaming profiles can have
+offline caching disabled using \fBcsc policy = disable
+\fR\&.
+
+Default: \fBcsc policy = manual\fR
+
+Example: \fBcsc policy = programs\fR
+.TP
+\fBdeadtime (G)\fR
+The value of the parameter (a decimal integer)
+represents the number of minutes of inactivity before a connection
+is considered dead, and it is disconnected. The deadtime only takes
+effect if the number of open files is zero.
+
+This is useful to stop a server's resources being
+exhausted by a large number of inactive connections.
+
+Most clients have an auto-reconnect feature when a
+connection is broken so in most cases this parameter should be
+transparent to users.
+
+Using this parameter with a timeout of a few minutes
+is recommended for most systems.
+
+A deadtime of zero indicates that no auto-disconnection
+should be performed.
+
+Default: \fBdeadtime = 0\fR
+
+Example: \fBdeadtime = 15\fR
+.TP
+\fBdebug hires timestamp (G)\fR
+Sometimes the timestamps in the log messages
+are needed with a resolution of higher that seconds, this
+boolean parameter adds microsecond resolution to the timestamp
+message header when turned on.
+
+Note that the parameter \fI debug timestamp\fR must be on for this to have an
+effect.
+
+Default: \fBdebug hires timestamp = no\fR
+.TP
+\fBdebug pid (G)\fR
+When using only one log file for more then one
+forked smbdprocess there may be hard to follow which process
+outputs which message. This boolean parameter is adds the process-id
+to the timestamp message headers in the logfile when turned on.
+
+Note that the parameter \fI debug timestamp\fR must be on for this to have an
+effect.
+
+Default: \fBdebug pid = no\fR
+.TP
+\fBdebug timestamp (G)\fR
+Samba 2.2 debug log messages are timestamped
+by default. If you are running at a high \fIdebug level\fR these timestamps
+can be distracting. This boolean parameter allows timestamping
+to be turned off.
+
+Default: \fBdebug timestamp = yes\fR
+.TP
+\fBdebug uid (G)\fR
+Samba is sometimes run as root and sometime
+run as the connected user, this boolean parameter inserts the
+current euid, egid, uid and gid to the timestamp message headers
+in the log file if turned on.
+
+Note that the parameter \fI debug timestamp\fR must be on for this to have an
+effect.
+
+Default: \fBdebug uid = no\fR
+.TP
+\fBdebuglevel (G)\fR
+Synonym for \fI log level\fR.
+.TP
+\fBdefault (G)\fR
+A synonym for \fI default service\fR.
+.TP
+\fBdefault case (S)\fR
+See the section on NAME MANGLING. Also note the \fIshort preserve case\fR parameter.
+
+Default: \fBdefault case = lower\fR
+.TP
+\fBdefault devmode (S)\fR
+This parameter is only applicable to printable services. When smbd is serving
+Printer Drivers to Windows NT/2k/XP clients, each printer on the Samba
+server has a Device Mode which defines things such as paper size and
+orientation and duplex settings. The device mode can only correctly be
+generated by the printer driver itself (which can only be executed on a
+Win32 platform). Because smbd is unable to execute the driver code
+to generate the device mode, the default behavior is to set this field
+to NULL.
+
+Most problems with serving printer drivers to Windows NT/2k/XP clients
+can be traced to a problem with the generated device mode. Certain drivers
+will do things such as crashing the client's Explorer.exe with a NULL devmode.
+However, other printer drivers can cause the client's spooler service
+(spoolsv.exe) to die if the devmode was not created by the driver itself
+(i.e. smbd generates a default devmode).
+
+This parameter should be used with care and tested with the printer
+driver in question. It is better to leave the device mode to NULL
+and let the Windows client set the correct values. Because drivers do not
+do this all the time, setting \fBdefault devmode = yes\fR
+will instruct smbd to generate a default one.
+
+For more information on Windows NT/2k printing and Device Modes,
+see the MSDN documentation <URL:http://msdn.microsoft.com/>.
+
+Default: \fBdefault devmode = no\fR
+.TP
+\fBdefault service (G)\fR
+This parameter specifies the name of a service
+which will be connected to if the service actually requested cannot
+be found. Note that the square brackets are \fBNOT\fR
+given in the parameter value (see example below).
+
+There is no default value for this parameter. If this
+parameter is not given, attempting to connect to a nonexistent
+service results in an error.
+
+Typically the default service would be a \fIguest ok\fR, \fIread-only\fR service.
+
+Also note that the apparent service name will be changed
+to equal that of the requested service, this is very useful as it
+allows you to use macros like \fI%S\fR to make
+a wildcard service.
+
+Note also that any "_" characters in the name of the service
+used in the default service will get mapped to a "/". This allows for
+interesting things.
+
+Example:
+
+.sp
+.nf
+[global]
+ default service = pub
+
+[pub]
+ path = /%S
+
+.sp
+.fi
+.TP
+\fBdelete printer command (G)\fR
+With the introduction of MS-RPC based printer
+support for Windows NT/2000 clients in Samba 2.2, it is now
+possible to delete printer at run time by issuing the
+DeletePrinter() RPC call.
+
+For a Samba host this means that the printer must be
+physically deleted from underlying printing system. The \fI deleteprinter command\fR defines a script to be run which
+will perform the necessary operations for removing the printer
+from the print system and from \fIsmb.conf\fR.
+
+The \fIdelete printer command\fR is
+automatically called with only one parameter: \fI "printer name"\fR.
+
+Once the \fIdelete printer command\fR has
+been executed, \fBsmbd\fR will reparse the \fI smb.conf\fR to associated printer no longer exists.
+If the sharename is still valid, then \fBsmbd
+\fRwill return an ACCESS_DENIED error to the client.
+
+See also \fI add printer command\fR, \fIprinting\fR,
+\fIshow add
+printer wizard\fR
+
+Default: \fBnone\fR
+
+Example: \fBdeleteprinter command = /usr/bin/removeprinter
+\fR.TP
+\fBdelete readonly (S)\fR
+This parameter allows readonly files to be deleted.
+This is not normal DOS semantics, but is allowed by UNIX.
+
+This option may be useful for running applications such
+as rcs, where UNIX file ownership prevents changing file
+permissions, and DOS semantics prevent deletion of a read only file.
+
+Default: \fBdelete readonly = no\fR
+.TP
+\fBdelete share command (G)\fR
+Samba 2.2.0 introduced the ability to dynamically
+add and delete shares via the Windows NT 4.0 Server Manager. The
+\fIdelete share command\fR is used to define an
+external program or script which will remove an existing service
+definition from \fIsmb.conf\fR. In order to successfully
+execute the \fIdelete share command\fR, \fBsmbd\fR
+requires that the administrator be connected using a root account (i.e.
+uid == 0).
+
+When executed, \fBsmbd\fR will automatically invoke the
+\fIdelete share command\fR with two parameters.
+.RS
+.TP 0.2i
+\(bu
+\fIconfigFile\fR - the location
+of the global \fIsmb.conf\fR file.
+.TP 0.2i
+\(bu
+\fIshareName\fR - the name of
+the existing service.
+.RE
+.PP
+This parameter is only used to remove file shares. To delete printer shares,
+see the \fIdelete printer
+command\fR.
+.PP
+.PP
+See also \fIadd share
+command\fR, \fIchange
+share command\fR.
+.PP
+.PP
+Default: \fBnone\fR
+.PP
+.PP
+Example: \fBdelete share command = /usr/local/bin/delshare\fR
+.PP
+.TP
+\fBdelete user script (G)\fR
+This is the full pathname to a script that will
+be run \fBAS ROOT\fR by \fBsmbd(8)\fR under special circumstances
+described below.
+
+Normally, a Samba server requires that UNIX users are
+created for all users accessing files on this server. For sites
+that use Windows NT account databases as their primary user database
+creating these users and keeping the user list in sync with the
+Windows NT PDC is an onerous task. This option allows \fB smbd\fR to delete the required UNIX users \fBON
+DEMAND\fR when a user accesses the Samba server and the
+Windows NT user no longer exists.
+
+In order to use this option, \fBsmbd\fR must be
+set to \fIsecurity = domain\fR or \fIsecurity =
+user\fR and \fIdelete user script\fR
+must be set to a full pathname for a script
+that will delete a UNIX user given one argument of \fI%u\fR,
+which expands into the UNIX user name to delete.
+
+When the Windows user attempts to access the Samba server,
+at \fBlogin\fR (session setup in the SMB protocol)
+time, \fBsmbd\fR contacts the \fIpassword server\fR and attempts to authenticate
+the given user with the given password. If the authentication fails
+with the specific Domain error code meaning that the user no longer
+exists then \fBsmbd\fR attempts to find a UNIX user in
+the UNIX password database that matches the Windows user account. If
+this lookup succeeds, and \fIdelete user script\fR is
+set then \fBsmbd\fR will all the specified script
+\fBAS ROOT\fR, expanding any \fI%u\fR
+argument to be the user name to delete.
+
+This script should delete the given UNIX username. In this way,
+UNIX users are dynamically deleted to match existing Windows NT
+accounts.
+
+See also security = domain,
+\fIpassword server\fR
+, \fIadd user script\fR
+\&.
+
+Default: \fBdelete user script = <empty string>
+\fR
+Example: \fBdelete user script = /usr/local/samba/bin/del_user
+%u\fR
+.TP
+\fBdelete veto files (S)\fR
+This option is used when Samba is attempting to
+delete a directory that contains one or more vetoed directories
+(see the \fIveto files\fR
+option). If this option is set to no (the default) then if a vetoed
+directory contains any non-vetoed files or directories then the
+directory delete will fail. This is usually what you want.
+
+If this option is set to yes, then Samba
+will attempt to recursively delete any files and directories within
+the vetoed directory. This can be useful for integration with file
+serving systems such as NetAtalk which create meta-files within
+directories you might normally veto DOS/Windows users from seeing
+(e.g. \fI.AppleDouble\fR)
+
+Setting \fBdelete veto files = yes\fR allows these
+directories to be transparently deleted when the parent directory
+is deleted (so long as the user has permissions to do so).
+
+See also the \fIveto
+files\fR parameter.
+
+Default: \fBdelete veto files = no\fR
+.TP
+\fBdeny hosts (S)\fR
+Synonym for \fIhosts
+deny\fR.
+.TP
+\fBdfree command (G)\fR
+The \fIdfree command\fR setting should
+only be used on systems where a problem occurs with the internal
+disk space calculations. This has been known to happen with Ultrix,
+but may occur with other operating systems. The symptom that was
+seen was an error of "Abort Retry Ignore" at the end of each
+directory listing.
+
+This setting allows the replacement of the internal routines to
+calculate the total disk space and amount available with an external
+routine. The example below gives a possible script that might fulfill
+this function.
+
+The external program will be passed a single parameter indicating
+a directory in the filesystem being queried. This will typically consist
+of the string \fI./\fR. The script should return two
+integers in ASCII. The first should be the total disk space in blocks,
+and the second should be the number of available blocks. An optional
+third return value can give the block size in bytes. The default
+blocksize is 1024 bytes.
+
+Note: Your script should \fBNOT\fR be setuid or
+setgid and should be owned by (and writeable only by) root!
+
+Default: \fBBy default internal routines for
+determining the disk capacity and remaining space will be used.
+\fR
+Example: \fBdfree command = /usr/local/samba/bin/dfree
+\fR
+Where the script dfree (which must be made executable) could be:
+
+.sp
+.nf
+
+ #!/bin/sh
+ df $1 | tail -1 | awk '{print $2" "$4}'
+
+.sp
+.fi
+
+or perhaps (on Sys V based systems):
+
+.sp
+.nf
+
+ #!/bin/sh
+ /usr/bin/df -k $1 | tail -1 | awk '{print $3" "$5}'
+
+.sp
+.fi
+
+Note that you may have to replace the command names
+with full path names on some systems.
+.TP
+\fBdirectory (S)\fR
+Synonym for \fIpath
+\fR\&.
+.TP
+\fBdirectory mask (S)\fR
+This parameter is the octal modes which are
+used when converting DOS modes to UNIX modes when creating UNIX
+directories.
+
+When a directory is created, the necessary permissions are
+calculated according to the mapping from DOS modes to UNIX permissions,
+and the resulting UNIX mode is then bit-wise 'AND'ed with this
+parameter. This parameter may be thought of as a bit-wise MASK for
+the UNIX modes of a directory. Any bit \fBnot\fR set
+here will be removed from the modes set on a directory when it is
+created.
+
+The default value of this parameter removes the 'group'
+and 'other' write bits from the UNIX mode, allowing only the
+user who owns the directory to modify it.
+
+Following this Samba will bit-wise 'OR' the UNIX mode
+created from this parameter with the value of the \fIforce directory mode
+\fRparameter. This parameter is set to 000 by
+default (i.e. no extra mode bits are added).
+
+Note that this parameter does not apply to permissions
+set by Windows NT/2000 ACL editors. If the administrator wishes to enforce
+a mask on access control lists also, they need to set the \fIdirectory security mask\fR.
+
+See the \fIforce
+directory mode\fR parameter to cause particular mode
+bits to always be set on created directories.
+
+See also the \fIcreate mode
+\fRparameter for masking mode bits on created files,
+and the \fIdirectory
+security mask\fR parameter.
+
+Also refer to the \fI inherit permissions\fR parameter.
+
+Default: \fBdirectory mask = 0755\fR
+
+Example: \fBdirectory mask = 0775\fR
+.TP
+\fBdirectory mode (S)\fR
+Synonym for \fI directory mask\fR
+.TP
+\fBdirectory security mask (S)\fR
+This parameter controls what UNIX permission bits
+can be modified when a Windows NT client is manipulating the UNIX
+permission on a directory using the native NT security dialog
+box.
+
+This parameter is applied as a mask (AND'ed with) to
+the changed permission bits, thus preventing any bits not in
+this mask from being modified. Essentially, zero bits in this
+mask may be treated as a set of bits the user is not allowed
+to change.
+
+If not set explicitly this parameter is set to 0777
+meaning a user is allowed to modify all the user/group/world
+permissions on a directory.
+
+\fBNote\fR that users who can access the
+Samba server through other means can easily bypass this restriction,
+so it is primarily useful for standalone "appliance" systems.
+Administrators of most normal systems will probably want to leave
+it as the default of 0777.
+
+See also the \fI force directory security mode\fR, \fIsecurity mask\fR,
+\fIforce security mode
+\fRparameters.
+
+Default: \fBdirectory security mask = 0777\fR
+
+Example: \fBdirectory security mask = 0700\fR
+.TP
+\fBdisable spoolss (G)\fR
+Enabling this parameter will disables Samba's support
+for the SPOOLSS set of MS-RPC's and will yield identical behavior
+as Samba 2.0.x. Windows NT/2000 clients will downgrade to using
+Lanman style printing commands. Windows 9x/ME will be uneffected by
+the parameter. However, this will also disable the ability to upload
+printer drivers to a Samba server via the Windows NT Add Printer
+Wizard or by using the NT printer properties dialog window. It will
+also disable the capability of Windows NT/2000 clients to download
+print drivers from the Samba host upon demand.
+\fBBe very careful about enabling this parameter.\fR
+
+See also use client driver
+
+Default : \fBdisable spoolss = no\fR
+.TP
+\fBdns proxy (G)\fR
+Specifies that nmbd(8)
+when acting as a WINS server and finding that a NetBIOS name has not
+been registered, should treat the NetBIOS name word-for-word as a DNS
+name and do a lookup with the DNS server for that name on behalf of
+the name-querying client.
+
+Note that the maximum length for a NetBIOS name is 15
+characters, so the DNS name (or DNS alias) can likewise only be
+15 characters, maximum.
+
+\fBnmbd\fR spawns a second copy of itself to do the
+DNS name lookup requests, as doing a name lookup is a blocking
+action.
+
+See also the parameter \fI wins support\fR.
+
+Default: \fBdns proxy = yes\fR
+.TP
+\fBdomain admin group (G)\fR
+This parameter is intended as a temporary solution
+to enable users to be a member of the "Domain Admins" group when
+a Samba host is acting as a PDC. A complete solution will be provided
+by a system for mapping Windows NT/2000 groups onto UNIX groups.
+Please note that this parameter has a somewhat confusing name. It
+accepts a list of usernames and of group names in standard
+\fIsmb.conf\fR notation.
+
+See also \fIdomain
+guest group\fR, \fIdomain
+logons\fR
+
+Default: \fBno domain administrators\fR
+
+Example: \fBdomain admin group = root @wheel\fR
+.TP
+\fBdomain guest group (G)\fR
+This parameter is intended as a temporary solution
+to enable users to be a member of the "Domain Guests" group when
+a Samba host is acting as a PDC. A complete solution will be provided
+by a system for mapping Windows NT/2000 groups onto UNIX groups.
+Please note that this parameter has a somewhat confusing name. It
+accepts a list of usernames and of group names in standard
+\fIsmb.conf\fR notation.
+
+See also \fIdomain
+admin group\fR, \fIdomain
+logons\fR
+
+Default: \fBno domain guests\fR
+
+Example: \fBdomain guest group = nobody @guest\fR
+.TP
+\fBdomain logons (G)\fR
+If set to yes, the Samba server will serve
+Windows 95/98 Domain logons for the \fIworkgroup\fR it is in. Samba 2.2 also
+has limited capability to act as a domain controller for Windows
+NT 4 Domains. For more details on setting up this feature see
+the Samba-PDC-HOWTO included in the \fIhtmldocs/\fR
+directory shipped with the source code.
+
+Default: \fBdomain logons = no\fR
+.TP
+\fBdomain master (G)\fR
+Tell \fB nmbd(8)\fR to enable WAN-wide browse list
+collation. Setting this option causes \fBnmbd\fR to
+claim a special domain specific NetBIOS name that identifies
+it as a domain master browser for its given \fIworkgroup\fR. Local master browsers
+in the same \fIworkgroup\fR on broadcast-isolated
+subnets will give this \fBnmbd\fR their local browse lists,
+and then ask \fBsmbd(8)\fR
+for a complete copy of the browse list for the whole wide area
+network. Browser clients will then contact their local master browser,
+and will receive the domain-wide browse list, instead of just the list
+for their broadcast-isolated subnet.
+
+Note that Windows NT Primary Domain Controllers expect to be
+able to claim this \fIworkgroup\fR specific special
+NetBIOS name that identifies them as domain master browsers for
+that \fIworkgroup\fR by default (i.e. there is no
+way to prevent a Windows NT PDC from attempting to do this). This
+means that if this parameter is set and \fBnmbd\fR claims
+the special name for a \fIworkgroup\fR before a Windows
+NT PDC is able to do so then cross subnet browsing will behave
+strangely and may fail.
+
+If \fBdomain logons = yes\fR
+, then the default behavior is to enable the \fIdomain
+master\fR parameter. If \fIdomain logons\fR is
+not enabled (the default setting), then neither will \fIdomain
+master\fR be enabled by default.
+
+Default: \fBdomain master = auto\fR
+.TP
+\fBdont descend (S)\fR
+There are certain directories on some systems
+(e.g., the \fI/proc\fR tree under Linux) that are either not
+of interest to clients or are infinitely deep (recursive). This
+parameter allows you to specify a comma-delimited list of directories
+that the server should always show as empty.
+
+Note that Samba can be very fussy about the exact format
+of the "dont descend" entries. For example you may need \fI ./proc\fR instead of just \fI/proc\fR.
+Experimentation is the best policy :-)
+
+Default: \fBnone (i.e., all directories are OK
+to descend)\fR
+
+Example: \fBdont descend = /proc,/dev\fR
+.TP
+\fBdos filemode (S)\fR
+The default behavior in Samba is to provide
+UNIX-like behavior where only the owner of a file/directory is
+able to change the permissions on it. However, this behavior
+is often confusing to DOS/Windows users. Enabling this parameter
+allows a user who has write access to the file (by whatever
+means) to modify the permissions on it. Note that a user
+belonging to the group owning the file will not be allowed to
+change permissions if the group is only granted read access.
+Ownership of the file/directory is not changed, only the permissions
+are modified.
+
+Default: \fBdos filemode = no\fR
+.TP
+\fBdos filetime resolution (S)\fR
+Under the DOS and Windows FAT filesystem, the finest
+granularity on time resolution is two seconds. Setting this parameter
+for a share causes Samba to round the reported time down to the
+nearest two second boundary when a query call that requires one second
+resolution is made to \fBsmbd(8)\fR
+
+
+This option is mainly used as a compatibility option for Visual
+C++ when used against Samba shares. If oplocks are enabled on a
+share, Visual C++ uses two different time reading calls to check if a
+file has changed since it was last read. One of these calls uses a
+one-second granularity, the other uses a two second granularity. As
+the two second call rounds any odd second down, then if the file has a
+timestamp of an odd number of seconds then the two timestamps will not
+match and Visual C++ will keep reporting the file has changed. Setting
+this option causes the two timestamps to match, and Visual C++ is
+happy.
+
+Default: \fBdos filetime resolution = no\fR
+.TP
+\fBdos filetimes (S)\fR
+Under DOS and Windows, if a user can write to a
+file they can change the timestamp on it. Under POSIX semantics,
+only the owner of the file or root may change the timestamp. By
+default, Samba runs with POSIX semantics and refuses to change the
+timestamp on a file if the user \fBsmbd\fR is acting
+on behalf of is not the file owner. Setting this option to yes allows DOS semantics and smbd will change the file
+timestamp as DOS requires.
+
+Default: \fBdos filetimes = no\fR
+.TP
+\fBencrypt passwords (G)\fR
+This boolean controls whether encrypted passwords
+will be negotiated with the client. Note that Windows NT 4.0 SP3 and
+above and also Windows 98 will by default expect encrypted passwords
+unless a registry entry is changed. To use encrypted passwords in
+Samba see the file ENCRYPTION.txt in the Samba documentation
+directory \fIdocs/\fR shipped with the source code.
+
+In order for encrypted passwords to work correctly
+\fBsmbd(8)\fR must either
+have access to a local \fIsmbpasswd(5)
+\fR program for information on how to set up
+and maintain this file), or set the security = [server|domain] parameter which
+causes \fBsmbd\fR to authenticate against another
+server.
+
+Default: \fBencrypt passwords = no\fR
+.TP
+\fBenhanced browsing (G)\fR
+This option enables a couple of enhancements to
+cross-subnet browse propagation that have been added in Samba
+but which are not standard in Microsoft implementations.
+
+The first enhancement to browse propagation consists of a regular
+wildcard query to a Samba WINS server for all Domain Master Browsers,
+followed by a browse synchronization with each of the returned
+DMBs. The second enhancement consists of a regular randomised browse
+synchronization with all currently known DMBs.
+
+You may wish to disable this option if you have a problem with empty
+workgroups not disappearing from browse lists. Due to the restrictions
+of the browse protocols these enhancements can cause a empty workgroup
+to stay around forever which can be annoying.
+
+In general you should leave this option enabled as it makes
+cross-subnet browse propagation much more reliable.
+
+Default: \fBenhanced browsing = yes\fR
+.TP
+\fBenumports command (G)\fR
+The concept of a "port" is fairly foreign
+to UNIX hosts. Under Windows NT/2000 print servers, a port
+is associated with a port monitor and generally takes the form of
+a local port (i.e. LPT1:, COM1:, FILE:) or a remote port
+(i.e. LPD Port Monitor, etc...). By default, Samba has only one
+port defined--"Samba Printer Port". Under
+Windows NT/2000, all printers must have a valid port name.
+If you wish to have a list of ports displayed (\fBsmbd
+\fRdoes not use a port name for anything) other than
+the default "Samba Printer Port", you
+can define \fIenumports command\fR to point to
+a program which should generate a list of ports, one per line,
+to standard output. This listing will then be used in response
+to the level 1 and 2 EnumPorts() RPC.
+
+Default: \fBno enumports command\fR
+
+Example: \fBenumports command = /usr/bin/listports
+\fR.TP
+\fBexec (S)\fR
+This is a synonym for \fIpreexec\fR.
+.TP
+\fBfake directory create times (S)\fR
+NTFS and Windows VFAT file systems keep a create
+time for all files and directories. This is not the same as the
+ctime - status change time - that Unix keeps, so Samba by default
+reports the earliest of the various times Unix does keep. Setting
+this parameter for a share causes Samba to always report midnight
+1-1-1980 as the create time for directories.
+
+This option is mainly used as a compatibility option for
+Visual C++ when used against Samba shares. Visual C++ generated
+makefiles have the object directory as a dependency for each object
+file, and a make rule to create the directory. Also, when NMAKE
+compares timestamps it uses the creation time when examining a
+directory. Thus the object directory will be created if it does not
+exist, but once it does exist it will always have an earlier
+timestamp than the object files it contains.
+
+However, Unix time semantics mean that the create time
+reported by Samba will be updated whenever a file is created or
+or deleted in the directory. NMAKE finds all object files in
+the object directory. The timestamp of the last one built is then
+compared to the timestamp of the object directory. If the
+directory's timestamp if newer, then all object files
+will be rebuilt. Enabling this option
+ensures directories always predate their contents and an NMAKE build
+will proceed as expected.
+
+Default: \fBfake directory create times = no\fR
+.TP
+\fBfake oplocks (S)\fR
+Oplocks are the way that SMB clients get permission
+from a server to locally cache file operations. If a server grants
+an oplock (opportunistic lock) then the client is free to assume
+that it is the only one accessing the file and it will aggressively
+cache file data. With some oplock types the client may even cache
+file open/close operations. This can give enormous performance benefits.
+
+When you set \fBfake oplocks = yes\fR, \fBsmbd(8)\fR will
+always grant oplock requests no matter how many clients are using
+the file.
+
+It is generally much better to use the real \fIoplocks\fR support rather
+than this parameter.
+
+If you enable this option on all read-only shares or
+shares that you know will only be accessed from one client at a
+time such as physically read-only media like CDROMs, you will see
+a big performance improvement on many operations. If you enable
+this option on shares where multiple clients may be accessing the
+files read-write at the same time you can get data corruption. Use
+this option carefully!
+
+Default: \fBfake oplocks = no\fR
+.TP
+\fBfollow symlinks (S)\fR
+This parameter allows the Samba administrator
+to stop \fBsmbd(8)\fR
+from following symbolic links in a particular share. Setting this
+parameter to no prevents any file or directory
+that is a symbolic link from being followed (the user will get an
+error). This option is very useful to stop users from adding a
+symbolic link to \fI/etc/passwd\fR in their home
+directory for instance. However it will slow filename lookups
+down slightly.
+
+This option is enabled (i.e. \fBsmbd\fR will
+follow symbolic links) by default.
+
+Default: \fBfollow symlinks = yes\fR
+.TP
+\fBforce create mode (S)\fR
+This parameter specifies a set of UNIX mode bit
+permissions that will \fBalways\fR be set on a
+file created by Samba. This is done by bitwise 'OR'ing these bits onto
+the mode bits of a file that is being created or having its
+permissions changed. The default for this parameter is (in octal)
+000. The modes in this parameter are bitwise 'OR'ed onto the file
+mode after the mask set in the \fIcreate mask\fR
+parameter is applied.
+
+See also the parameter \fIcreate
+mask\fR for details on masking mode bits on files.
+
+See also the \fIinherit
+permissions\fR parameter.
+
+Default: \fBforce create mode = 000\fR
+
+Example: \fBforce create mode = 0755\fR
+
+would force all created files to have read and execute
+permissions set for 'group' and 'other' as well as the
+read/write/execute bits set for the 'user'.
+.TP
+\fBforce directory mode (S)\fR
+This parameter specifies a set of UNIX mode bit
+permissions that will \fBalways\fR be set on a directory
+created by Samba. This is done by bitwise 'OR'ing these bits onto the
+mode bits of a directory that is being created. The default for this
+parameter is (in octal) 0000 which will not add any extra permission
+bits to a created directory. This operation is done after the mode
+mask in the parameter \fIdirectory mask\fR is
+applied.
+
+See also the parameter \fI directory mask\fR for details on masking mode bits
+on created directories.
+
+See also the \fI inherit permissions\fR parameter.
+
+Default: \fBforce directory mode = 000\fR
+
+Example: \fBforce directory mode = 0755\fR
+
+would force all created directories to have read and execute
+permissions set for 'group' and 'other' as well as the
+read/write/execute bits set for the 'user'.
+.TP
+\fBforce directory\fR
+This parameter controls what UNIX permission bits
+can be modified when a Windows NT client is manipulating the UNIX
+permission on a directory using the native NT security dialog box.
+
+This parameter is applied as a mask (OR'ed with) to the
+changed permission bits, thus forcing any bits in this mask that
+the user may have modified to be on. Essentially, one bits in this
+mask may be treated as a set of bits that, when modifying security
+on a directory, the user has always set to be 'on'.
+
+If not set explicitly this parameter is 000, which
+allows a user to modify all the user/group/world permissions on a
+directory without restrictions.
+
+\fBNote\fR that users who can access the
+Samba server through other means can easily bypass this restriction,
+so it is primarily useful for standalone "appliance" systems.
+Administrators of most normal systems will probably want to leave
+it set as 0000.
+
+See also the \fI directory security mask\fR, \fIsecurity mask\fR,
+\fIforce security mode
+\fRparameters.
+
+Default: \fBforce directory security mode = 0\fR
+
+Example: \fBforce directory security mode = 700\fR
+.TP
+\fBforce group (S)\fR
+This specifies a UNIX group name that will be
+assigned as the default primary group for all users connecting
+to this service. This is useful for sharing files by ensuring
+that all access to files on service will use the named group for
+their permissions checking. Thus, by assigning permissions for this
+group to the files and directories within this service the Samba
+administrator can restrict or allow sharing of these files.
+
+In Samba 2.0.5 and above this parameter has extended
+functionality in the following way. If the group name listed here
+has a '+' character prepended to it then the current user accessing
+the share only has the primary group default assigned to this group
+if they are already assigned as a member of that group. This allows
+an administrator to decide that only users who are already in a
+particular group will create files with group ownership set to that
+group. This gives a finer granularity of ownership assignment. For
+example, the setting \fIforce group = +sys\fR means
+that only users who are already in group sys will have their default
+primary group assigned to sys when accessing this Samba share. All
+other users will retain their ordinary primary group.
+
+If the \fIforce user
+\fRparameter is also set the group specified in
+\fIforce group\fR will override the primary group
+set in \fIforce user\fR.
+
+See also \fIforce
+user\fR.
+
+Default: \fBno forced group\fR
+
+Example: \fBforce group = agroup\fR
+.TP
+\fBforce security mode (S)\fR
+This parameter controls what UNIX permission
+bits can be modified when a Windows NT client is manipulating
+the UNIX permission on a file using the native NT security dialog
+box.
+
+This parameter is applied as a mask (OR'ed with) to the
+changed permission bits, thus forcing any bits in this mask that
+the user may have modified to be on. Essentially, one bits in this
+mask may be treated as a set of bits that, when modifying security
+on a file, the user has always set to be 'on'.
+
+If not set explicitly this parameter is set to 0,
+and allows a user to modify all the user/group/world permissions on a file,
+with no restrictions.
+
+\fBNote\fR that users who can access
+the Samba server through other means can easily bypass this restriction,
+so it is primarily useful for standalone "appliance" systems.
+Administrators of most normal systems will probably want to leave
+this set to 0000.
+
+See also the \fI force directory security mode\fR,
+\fIdirectory security
+mask\fR, \fI security mask\fR parameters.
+
+Default: \fBforce security mode = 0\fR
+
+Example: \fBforce security mode = 700\fR
+.TP
+\fBforce unknown acl user (S)\fR
+If this parameter is set, a Windows NT ACL that contains
+an unknown SID (security descriptor, or representation of a user or group id)
+as the owner or group owner of the file will be silently mapped into the
+current UNIX uid or gid of the currently connected user.
+
+This is designed to allow Windows NT clients to copy files and
+folders containing ACLs that were created locally on the client machine
+and contain users local to that machine only (no domain users) to be
+copied to a Samba server (usually with XCOPY /O) and have the unknown
+userid and groupid of the file owner map to the current connected user.
+This can only be fixed correctly when winbindd allows arbitrary mapping
+from any Windows NT SID to a UNIX uid or gid.
+
+Try using this parameter when XCOPY /O gives an ACCESS_DENIED error.
+
+See also \fIforce group
+\fR
+Default: \fBFalse\fR
+
+Example: \fBforce unknown acl user = yes\fR
+.TP
+\fBforce user (S)\fR
+This specifies a UNIX user name that will be
+assigned as the default user for all users connecting to this service.
+This is useful for sharing files. You should also use it carefully
+as using it incorrectly can cause security problems.
+
+This user name only gets used once a connection is established.
+Thus clients still need to connect as a valid user and supply a
+valid password. Once connected, all file operations will be performed
+as the "forced user", no matter what username the client connected
+as. This can be very useful.
+
+In Samba 2.0.5 and above this parameter also causes the
+primary group of the forced user to be used as the primary group
+for all file activity. Prior to 2.0.5 the primary group was left
+as the primary group of the connecting user (this was a bug).
+
+See also \fIforce group
+\fR
+Default: \fBno forced user\fR
+
+Example: \fBforce user = auser\fR
+.TP
+\fBfstype (S)\fR
+This parameter allows the administrator to
+configure the string that specifies the type of filesystem a share
+is using that is reported by \fBsmbd(8)
+\fR when a client queries the filesystem type
+for a share. The default type is NTFS for
+compatibility with Windows NT but this can be changed to other
+strings such as Samba or FAT
+if required.
+
+Default: \fBfstype = NTFS\fR
+
+Example: \fBfstype = Samba\fR
+.TP
+\fBgetwd cache (G)\fR
+This is a tuning option. When this is enabled a
+caching algorithm will be used to reduce the time taken for getwd()
+calls. This can have a significant impact on performance, especially
+when the \fIwide links\fR
+parameter is set to no.
+
+Default: \fBgetwd cache = yes\fR
+.TP
+\fBgroup (S)\fR
+Synonym for \fIforce
+group\fR.
+.TP
+\fBguest account (S)\fR
+This is a username which will be used for access
+to services which are specified as \fI guest ok\fR (see below). Whatever privileges this
+user has will be available to any client connecting to the guest service.
+Typically this user will exist in the password file, but will not
+have a valid login. The user account "ftp" is often a good choice
+for this parameter. If a username is specified in a given service,
+the specified username overrides this one.
+
+One some systems the default guest account "nobody" may not
+be able to print. Use another account in this case. You should test
+this by trying to log in as your guest user (perhaps by using the
+\fBsu -\fR command) and trying to print using the
+system print command such as \fBlpr(1)\fR or \fB lp(1)\fR.
+
+Default: \fBspecified at compile time, usually
+"nobody"\fR
+
+Example: \fBguest account = ftp\fR
+.TP
+\fBguest ok (S)\fR
+If this parameter is yes for
+a service, then no password is required to connect to the service.
+Privileges will be those of the \fI guest account\fR.
+
+See the section below on \fI security\fR for more information about this option.
+
+Default: \fBguest ok = no\fR
+.TP
+\fBguest only (S)\fR
+If this parameter is yes for
+a service, then only guest connections to the service are permitted.
+This parameter will have no effect if \fIguest ok\fR is not set for the service.
+
+See the section below on \fI security\fR for more information about this option.
+
+Default: \fBguest only = no\fR
+.TP
+\fBhide dot files (S)\fR
+This is a boolean parameter that controls whether
+files starting with a dot appear as hidden files.
+
+Default: \fBhide dot files = yes\fR
+.TP
+\fBhide files(S)\fR
+This is a list of files or directories that are not
+visible but are accessible. The DOS 'hidden' attribute is applied
+to any files or directories that match.
+
+Each entry in the list must be separated by a '/',
+which allows spaces to be included in the entry. '*'
+and '?' can be used to specify multiple files or directories
+as in DOS wildcards.
+
+Each entry must be a Unix path, not a DOS path and must
+not include the Unix directory separator '/'.
+
+Note that the case sensitivity option is applicable
+in hiding files.
+
+Setting this parameter will affect the performance of Samba,
+as it will be forced to check all files and directories for a match
+as they are scanned.
+
+See also \fIhide
+dot files\fR, \fI veto files\fR and \fIcase sensitive\fR.
+
+Default: \fBno file are hidden\fR
+
+Example: \fBhide files =
+/.*/DesktopFolderDB/TrashFor%m/resource.frk/\fR
+
+The above example is based on files that the Macintosh
+SMB client (DAVE) available from
+Thursby <URL:http://www.thursby.com> creates for internal use, and also still hides
+all files beginning with a dot.
+.TP
+\fBhide local users(G)\fR
+This parameter toggles the hiding of local UNIX
+users (root, wheel, floppy, etc) from remote clients.
+
+Default: \fBhide local users = no\fR
+.TP
+\fBhide unreadable (S)\fR
+This parameter prevents clients from seeing the
+existance of files that cannot be read. Defaults to off.
+
+Default: \fBhide unreadable = no\fR
+.TP
+\fBhomedir map (G)\fR
+If\fInis homedir
+\fRis yes, and \fBsmbd(8)\fR is also acting
+as a Win95/98 \fIlogon server\fR then this parameter
+specifies the NIS (or YP) map from which the server for the user's
+home directory should be extracted. At present, only the Sun
+auto.home map format is understood. The form of the map is:
+
+\fBusername server:/some/file/system\fR
+
+and the program will extract the servername from before
+the first ':'. There should probably be a better parsing system
+that copes with different map formats and also Amd (another
+automounter) maps.
+
+\fBNOTE :\fRA working NIS client is required on
+the system for this option to work.
+
+See also \fInis homedir\fR
+, \fIdomain logons\fR
+\&.
+
+Default: \fBhomedir map = <empty string>\fR
+
+Example: \fBhomedir map = amd.homedir\fR
+.TP
+\fBhost msdfs (G)\fR
+This boolean parameter is only available
+if Samba has been configured and compiled with the \fB --with-msdfs\fR option. If set to yes,
+Samba will act as a Dfs server, and allow Dfs-aware clients
+to browse Dfs trees hosted on the server.
+
+See also the \fI msdfs root\fR share level parameter. For
+more information on setting up a Dfs tree on Samba,
+refer to msdfs_setup.html
+
+Default: \fBhost msdfs = no\fR
+.TP
+\fBhosts allow (S)\fR
+A synonym for this parameter is \fIallow
+hosts\fR.
+
+This parameter is a comma, space, or tab delimited
+set of hosts which are permitted to access a service.
+
+If specified in the [global] section then it will
+apply to all services, regardless of whether the individual
+service has a different setting.
+
+You can specify the hosts by name or IP number. For
+example, you could restrict access to only the hosts on a
+Class C subnet with something like \fBallow hosts = 150.203.5.
+\fR\&. The full syntax of the list is described in the man
+page \fIhosts_access(5)\fR. Note that this man
+page may not be present on your system, so a brief description will
+be given here also.
+
+Note that the localhost address 127.0.0.1 will always
+be allowed access unless specifically denied by a \fIhosts deny\fR option.
+
+You can also specify hosts by network/netmask pairs and
+by netgroup names if your system supports netgroups. The
+\fBEXCEPT\fR keyword can also be used to limit a
+wildcard list. The following examples may provide some help:
+
+Example 1: allow all IPs in 150.203.*.*; except one
+
+\fBhosts allow = 150.203. EXCEPT 150.203.6.66\fR
+
+Example 2: allow hosts that match the given network/netmask
+
+\fBhosts allow = 150.203.15.0/255.255.255.0\fR
+
+Example 3: allow a couple of hosts
+
+\fBhosts allow = lapland, arvidsjaur\fR
+
+Example 4: allow only hosts in NIS netgroup "foonet", but
+deny access from one particular host
+
+\fBhosts allow = @foonet\fR
+
+\fBhosts deny = pirate\fR
+
+Note that access still requires suitable user-level passwords.
+
+See \fBtestparm(1)\fR
+ for a way of testing your host access to see if it does
+what you expect.
+
+Default: \fBnone (i.e., all hosts permitted access)
+\fR
+Example: \fBallow hosts = 150.203.5. myhost.mynet.edu.au
+\fR.TP
+\fBhosts deny (S)\fR
+The opposite of \fIhosts allow\fR
+- hosts listed here are \fBNOT\fR permitted access to
+services unless the specific services have their own lists to override
+this one. Where the lists conflict, the \fIallow\fR
+list takes precedence.
+
+Default: \fBnone (i.e., no hosts specifically excluded)
+\fR
+Example: \fBhosts deny = 150.203.4. badhost.mynet.edu.au
+\fR.TP
+\fBhosts equiv (G)\fR
+If this global parameter is a non-null string,
+it specifies the name of a file to read for the names of hosts
+and users who will be allowed access without specifying a password.
+
+This is not be confused with \fIhosts allow\fR which is about hosts
+access to services and is more useful for guest services. \fI hosts equiv\fR may be useful for NT clients which will
+not supply passwords to Samba.
+
+\fBNOTE :\fR The use of \fIhosts equiv
+\fRcan be a major security hole. This is because you are
+trusting the PC to supply the correct username. It is very easy to
+get a PC to supply a false username. I recommend that the
+\fIhosts equiv\fR option be only used if you really
+know what you are doing, or perhaps on a home network where you trust
+your spouse and kids. And only if you \fBreally\fR trust
+them :-).
+
+Default: \fBno host equivalences\fR
+
+Example: \fBhosts equiv = /etc/hosts.equiv\fR
+.TP
+\fBinclude (G)\fR
+This allows you to include one config file
+inside another. The file is included literally, as though typed
+in place.
+
+It takes the standard substitutions, except \fI%u
+\fR, \fI%P\fR and \fI%S\fR.
+
+Default: \fBno file included\fR
+
+Example: \fBinclude = /usr/local/samba/lib/admin_smb.conf
+\fR.TP
+\fBinherit acls (S)\fR
+This parameter can be used to ensure
+that if default acls exist on parent directories,
+they are always honored when creating a subdirectory.
+The default behavior is to use the mode specified
+when creating the directory. Enabling this option
+sets the mode to 0777, thus guaranteeing that
+default directory acls are propagated.
+
+Default: \fBinherit acls = no\fR
+.TP
+\fBinherit permissions (S)\fR
+The permissions on new files and directories
+are normally governed by \fI create mask\fR, \fIdirectory mask\fR, \fIforce create mode\fR
+and \fIforce
+directory mode\fR but the boolean inherit
+permissions parameter overrides this.
+
+New directories inherit the mode of the parent directory,
+including bits such as setgid.
+
+New files inherit their read/write bits from the parent
+directory. Their execute bits continue to be determined by
+\fImap archive\fR
+, \fImap hidden\fR
+and \fImap system\fR
+as usual.
+
+Note that the setuid bit is \fBnever\fR set via
+inheritance (the code explicitly prohibits this).
+
+This can be particularly useful on large systems with
+many users, perhaps several thousand, to allow a single [homes]
+share to be used flexibly by each user.
+
+See also \fIcreate mask
+\fR, \fI directory mask\fR, \fIforce create mode\fR and \fIforce directory mode\fR
+\&.
+
+Default: \fBinherit permissions = no\fR
+.TP
+\fBinterfaces (G)\fR
+This option allows you to override the default
+network interfaces list that Samba will use for browsing, name
+registration and other NBT traffic. By default Samba will query
+the kernel for the list of all active interfaces and use any
+interfaces except 127.0.0.1 that are broadcast capable.
+
+The option takes a list of interface strings. Each string
+can be in any of the following forms:
+.RS
+.TP 0.2i
+\(bu
+a network interface name (such as eth0).
+This may include shell-like wildcards so eth* will match
+any interface starting with the substring "eth"
+.TP 0.2i
+\(bu
+an IP address. In this case the netmask is
+determined from the list of interfaces obtained from the
+kernel
+.TP 0.2i
+\(bu
+an IP/mask pair.
+.TP 0.2i
+\(bu
+a broadcast/mask pair.
+.RE
+.PP
+The "mask" parameters can either be a bit length (such
+as 24 for a C class network) or a full netmask in dotted
+decimal form.
+.PP
+.PP
+The "IP" parameters above can either be a full dotted
+decimal IP address or a hostname which will be looked up via
+the OS's normal hostname resolution mechanisms.
+.PP
+.PP
+For example, the following line:
+.PP
+.PP
+\fBinterfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0
+\fR.PP
+.PP
+would configure three network interfaces corresponding
+to the eth0 device and IP addresses 192.168.2.10 and 192.168.3.10.
+The netmasks of the latter two interfaces would be set to 255.255.255.0.
+.PP
+.PP
+See also \fIbind
+interfaces only\fR.
+.PP
+.PP
+Default: \fBall active interfaces except 127.0.0.1
+that are broadcast capable\fR
+.PP
+.TP
+\fBinvalid users (S)\fR
+This is a list of users that should not be allowed
+to login to this service. This is really a \fBparanoid\fR
+check to absolutely ensure an improper setting does not breach
+your security.
+
+A name starting with a '@' is interpreted as an NIS
+netgroup first (if your system supports NIS), and then as a UNIX
+group if the name was not found in the NIS netgroup database.
+
+A name starting with '+' is interpreted only
+by looking in the UNIX group database. A name starting with
+\&'&' is interpreted only by looking in the NIS netgroup database
+(this requires NIS to be working on your system). The characters
+\&'+' and '&' may be used at the start of the name in either order
+so the value \fI+&group\fR means check the
+UNIX group database, followed by the NIS netgroup database, and
+the value \fI&+group\fR means check the NIS
+netgroup database, followed by the UNIX group database (the
+same as the '@' prefix).
+
+The current servicename is substituted for \fI%S\fR.
+This is useful in the [homes] section.
+
+See also \fIvalid users
+\fR\&.
+
+Default: \fBno invalid users\fR
+
+Example: \fBinvalid users = root fred admin @wheel
+\fR.TP
+\fBkeepalive (G)\fR
+The value of the parameter (an integer) represents
+the number of seconds between \fIkeepalive\fR
+packets. If this parameter is zero, no keepalive packets will be
+sent. Keepalive packets, if sent, allow the server to tell whether
+a client is still present and responding.
+
+Keepalives should, in general, not be needed if the socket
+being used has the SO_KEEPALIVE attribute set on it (see \fIsocket options\fR).
+Basically you should only use this option if you strike difficulties.
+
+Default: \fBkeepalive = 300\fR
+
+Example: \fBkeepalive = 600\fR
+.TP
+\fBkernel oplocks (G)\fR
+For UNIXes that support kernel based \fIoplocks\fR
+(currently only IRIX and the Linux 2.4 kernel), this parameter
+allows the use of them to be turned on or off.
+
+Kernel oplocks support allows Samba \fIoplocks
+\fRto be broken whenever a local UNIX process or NFS operation
+accesses a file that \fBsmbd(8)\fR
+ has oplocked. This allows complete data consistency between
+SMB/CIFS, NFS and local file access (and is a \fBvery\fR
+cool feature :-).
+
+This parameter defaults to on, but is translated
+to a no-op on systems that no not have the necessary kernel support.
+You should never need to touch this parameter.
+
+See also the \fIoplocks\fR
+and \fIlevel2 oplocks
+\fRparameters.
+
+Default: \fBkernel oplocks = yes\fR
+.TP
+\fBlanman auth (G)\fR
+This parameter determines whether or not smbd will
+attempt to authenticate users using the LANMAN password hash.
+If disabled, only clients which support NT password hashes (e.g. Windows
+NT/2000 clients, smbclient, etc... but not Windows 95/98 or the MS DOS
+network client) will be able to connect to the Samba host.
+
+Default : \fBlanman auth = yes\fR
+.TP
+\fBlarge readwrite (G)\fR
+This parameter determines whether or not smbd
+supports the new 64k streaming read and write varient SMB requests introduced
+with Windows 2000. Note that due to Windows 2000 client redirector bugs
+this requires Samba to be running on a 64-bit capable operating system such
+as IRIX, Solaris or a Linux 2.4 kernel. Can improve performance by 10% with
+Windows 2000 clients. Defaults to on. Windows NT 4.0 only supports
+read version of this call, and ignores the write version.
+
+Default : \fBlarge readwrite = yes\fR
+.TP
+\fBldap admin dn (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+The \fIldap admin dn\fR defines the Distinguished
+Name (DN) name used by Samba to contact the ldap
+server when retreiving user account information. The \fIldap
+admin dn\fR is used in conjunction with the admin dn password
+stored in the \fIprivate/secrets.tdb\fR file. See the
+\fBsmbpasswd(8)\fR man
+page for more information on how to accmplish this.
+
+Default : \fBnone\fR
+.TP
+\fBldap filter (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+This parameter specifies the RFC 2254 compliant LDAP search filter.
+The default is to match the login name with the uid
+attribute for all entries matching the sambaAccount
+objectclass. Note that this filter should only return one entry.
+
+Default : \fBldap filter = (&(uid=%u)(objectclass=sambaAccount))\fR
+.TP
+\fBldap port (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+This option is used to control the tcp port number used to contact
+the \fIldap server\fR.
+The default is to use the stand LDAPS port 636.
+
+See Also: ldap ssl
+
+Default : \fBldap port = 636 ; if ldap ssl = on\fR
+
+Default : \fBldap port = 389 ; if ldap ssl = off\fR
+.TP
+\fBldap server (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+This parameter should contains the FQDN of the ldap directory
+server which should be queried to locate user account information.
+
+Default : \fBldap server = localhost\fR
+.TP
+\fBldap ssl (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+This option is used to define whether or not Samba should
+use SSL when connecting to the \fIldap
+server\fR. This is \fBNOT\fR related to
+Samba SSL support which is enabled by specifying the
+\fB--with-ssl\fR option to the \fIconfigure\fR
+script (see \fIssl\fR).
+
+The \fIldap ssl\fR can be set to one of three values:
+(a) on - Always use SSL when contacting the
+\fIldap server\fR, (b) off -
+Never use SSL when querying the directory, or (c) start_tls
+- Use the LDAPv3 StartTLS extended operation
+(RFC2830) for communicating with the directory server.
+
+Default : \fBldap ssl = on\fR
+.TP
+\fBldap suffix (G)\fR
+This parameter is only available if Samba has been
+configure to include the \fB--with-ldapsam\fR option
+at compile time. This option should be considered experimental and
+under active development.
+
+Default : \fBnone\fR
+.TP
+\fBlevel2 oplocks (S)\fR
+This parameter controls whether Samba supports
+level2 (read-only) oplocks on a share.
+
+Level2, or read-only oplocks allow Windows NT clients
+that have an oplock on a file to downgrade from a read-write oplock
+to a read-only oplock once a second client opens the file (instead
+of releasing all oplocks on a second open, as in traditional,
+exclusive oplocks). This allows all openers of the file that
+support level2 oplocks to cache the file for read-ahead only (ie.
+they may not cache writes or lock requests) and increases performance
+for many accesses of files that are not commonly written (such as
+application .EXE files).
+
+Once one of the clients which have a read-only oplock
+writes to the file all clients are notified (no reply is needed
+or waited for) and told to break their oplocks to "none" and
+delete any read-ahead caches.
+
+It is recommended that this parameter be turned on
+to speed access to shared executables.
+
+For more discussions on level2 oplocks see the CIFS spec.
+
+Currently, if \fIkernel
+oplocks\fR are supported then level2 oplocks are
+not granted (even if this parameter is set to yes).
+Note also, the \fIoplocks\fR
+parameter must be set to yes on this share in order for
+this parameter to have any effect.
+
+See also the \fIoplocks\fR
+and \fIkernel oplocks\fR
+parameters.
+
+Default: \fBlevel2 oplocks = yes\fR
+.TP
+\fBlm announce (G)\fR
+This parameter determines if \fBnmbd(8)\fR will produce Lanman announce
+broadcasts that are needed by OS/2 clients in order for them to see
+the Samba server in their browse list. This parameter can have three
+values, yes, no, or
+auto. The default is auto.
+If set to no Samba will never produce these
+broadcasts. If set to yes Samba will produce
+Lanman announce broadcasts at a frequency set by the parameter
+\fIlm interval\fR. If set to auto
+Samba will not send Lanman announce broadcasts by default but will
+listen for them. If it hears such a broadcast on the wire it will
+then start sending them at a frequency set by the parameter
+\fIlm interval\fR.
+
+See also \fIlm interval
+\fR\&.
+
+Default: \fBlm announce = auto\fR
+
+Example: \fBlm announce = yes\fR
+.TP
+\fBlm interval (G)\fR
+If Samba is set to produce Lanman announce
+broadcasts needed by OS/2 clients (see the \fIlm announce\fR parameter) then this
+parameter defines the frequency in seconds with which they will be
+made. If this is set to zero then no Lanman announcements will be
+made despite the setting of the \fIlm announce\fR
+parameter.
+
+See also \fIlm
+announce\fR.
+
+Default: \fBlm interval = 60\fR
+
+Example: \fBlm interval = 120\fR
+.TP
+\fBload printers (G)\fR
+A boolean variable that controls whether all
+printers in the printcap will be loaded for browsing by default.
+See the printers section for
+more details.
+
+Default: \fBload printers = yes\fR
+.TP
+\fBlocal master (G)\fR
+This option allows \fB nmbd(8)\fR to try and become a local master browser
+on a subnet. If set to no then \fB nmbd\fR will not attempt to become a local master browser
+on a subnet and will also lose in all browsing elections. By
+default this value is set to yes. Setting this value to yes doesn't
+mean that Samba will \fBbecome\fR the local master
+browser on a subnet, just that \fBnmbd\fR will \fB participate\fR in elections for local master browser.
+
+Setting this value to no will cause \fBnmbd\fR
+\fBnever\fR to become a local master browser.
+
+Default: \fBlocal master = yes\fR
+.TP
+\fBlock dir (G)\fR
+Synonym for \fI lock directory\fR.
+.TP
+\fBlock directory (G)\fR
+This option specifies the directory where lock
+files will be placed. The lock files are used to implement the
+\fImax connections\fR
+option.
+
+Default: \fBlock directory = ${prefix}/var/locks\fR
+
+Example: \fBlock directory = /var/run/samba/locks\fR
+.TP
+\fBlock spin count (G)\fR
+This parameter controls the number of times
+that smbd should attempt to gain a byte range lock on the
+behalf of a client request. Experiments have shown that
+Windows 2k servers do not reply with a failure if the lock
+could not be immediately granted, but try a few more times
+in case the lock could later be aquired. This behavior
+is used to support PC database formats such as MS Access
+and FoxPro.
+
+Default: \fBlock spin count = 2\fR
+.TP
+\fBlock spin time (G)\fR
+The time in microseconds that smbd should
+pause before attempting to gain a failed lock. See
+\fIlock spin
+count\fR for more details.
+
+Default: \fBlock spin time = 10\fR
+.TP
+\fBlocking (S)\fR
+This controls whether or not locking will be
+performed by the server in response to lock requests from the
+client.
+
+If \fBlocking = no\fR, all lock and unlock
+requests will appear to succeed and all lock queries will report
+that the file in question is available for locking.
+
+If \fBlocking = yes\fR, real locking will be performed
+by the server.
+
+This option \fBmay\fR be useful for read-only
+filesystems which \fBmay\fR not need locking (such as
+CDROM drives), although setting this parameter of no
+is not really recommended even in this case.
+
+Be careful about disabling locking either globally or in a
+specific service, as lack of locking may result in data corruption.
+You should never need to set this parameter.
+
+Default: \fBlocking = yes\fR
+.TP
+\fBlog file (G)\fR
+This option allows you to override the name
+of the Samba log file (also known as the debug file).
+
+This option takes the standard substitutions, allowing
+you to have separate log files for each user or machine.
+
+Example: \fBlog file = /usr/local/samba/var/log.%m
+\fR.TP
+\fBlog level (G)\fR
+The value of the parameter (an integer) allows
+the debug level (logging level) to be specified in the
+\fIsmb.conf\fR file. This is to give greater
+flexibility in the configuration of the system.
+
+The default will be the log level specified on
+the command line or level zero if none was specified.
+
+Example: \fBlog level = 3\fR
+.TP
+\fBlogon drive (G)\fR
+This parameter specifies the local path to
+which the home directory will be connected (see \fIlogon home\fR)
+and is only used by NT Workstations.
+
+Note that this option is only useful if Samba is set up as a
+logon server.
+
+Default: \fBlogon drive = z:\fR
+
+Example: \fBlogon drive = h:\fR
+.TP
+\fBlogon home (G)\fR
+This parameter specifies the home directory
+location when a Win95/98 or NT Workstation logs into a Samba PDC.
+It allows you to do
+
+C:\\> \fBNET USE H: /HOME\fR
+
+from a command prompt, for example.
+
+This option takes the standard substitutions, allowing
+you to have separate logon scripts for each user or machine.
+
+This parameter can be used with Win9X workstations to ensure
+that roaming profiles are stored in a subdirectory of the user's
+home directory. This is done in the following way:
+
+\fBlogon home = \\\\%N\\%U\\profile\fR
+
+This tells Samba to return the above string, with
+substitutions made when a client requests the info, generally
+in a NetUserGetInfo request. Win9X clients truncate the info to
+\\\\server\\share when a user does \fBnet use /home\fR
+but use the whole string when dealing with profiles.
+
+Note that in prior versions of Samba, the \fIlogon path\fR was returned rather than
+\fIlogon home\fR. This broke \fBnet use
+/home\fR but allowed profiles outside the home directory.
+The current implementation is correct, and can be used for
+profiles if you use the above trick.
+
+This option is only useful if Samba is set up as a logon
+server.
+
+Default: \fBlogon home = "\\\\%N\\%U"\fR
+
+Example: \fBlogon home = "\\\\remote_smb_server\\%U"\fR
+.TP
+\fBlogon path (G)\fR
+This parameter specifies the home directory
+where roaming profiles (NTuser.dat etc files for Windows NT) are
+stored. Contrary to previous versions of these manual pages, it has
+nothing to do with Win 9X roaming profiles. To find out how to
+handle roaming profiles for Win 9X system, see the \fIlogon home\fR parameter.
+
+This option takes the standard substitutions, allowing you
+to have separate logon scripts for each user or machine. It also
+specifies the directory from which the "Application Data",
+(\fIdesktop\fR, \fIstart menu\fR,
+\fInetwork neighborhood\fR, \fIprograms\fR
+and other folders, and their contents, are loaded and displayed on
+your Windows NT client.
+
+The share and the path must be readable by the user for
+the preferences and directories to be loaded onto the Windows NT
+client. The share must be writeable when the user logs in for the first
+time, in order that the Windows NT client can create the NTuser.dat
+and other directories.
+
+Thereafter, the directories and any of the contents can,
+if required, be made read-only. It is not advisable that the
+NTuser.dat file be made read-only - rename it to NTuser.man to
+achieve the desired effect (a \fBMAN\fRdatory
+profile).
+
+Windows clients can sometimes maintain a connection to
+the [homes] share, even though there is no user logged in.
+Therefore, it is vital that the logon path does not include a
+reference to the homes share (i.e. setting this parameter to
+\\%N\\%U\\profile_path will cause problems).
+
+This option takes the standard substitutions, allowing
+you to have separate logon scripts for each user or machine.
+
+Note that this option is only useful if Samba is set up
+as a logon server.
+
+Default: \fBlogon path = \\\\%N\\%U\\profile\fR
+
+Example: \fBlogon path = \\\\PROFILESERVER\\PROFILE\\%U\fR
+.TP
+\fBlogon script (G)\fR
+This parameter specifies the batch file (.bat) or
+NT command file (.cmd) to be downloaded and run on a machine when
+a user successfully logs in. The file must contain the DOS
+style CR/LF line endings. Using a DOS-style editor to create the
+file is recommended.
+
+The script must be a relative path to the [netlogon]
+service. If the [netlogon] service specifies a \fIpath\fR of \fI/usr/local/samba/netlogon
+\fR, and \fBlogon script = STARTUP.BAT\fR, then
+the file that will be downloaded is:
+
+\fI/usr/local/samba/netlogon/STARTUP.BAT\fR
+
+The contents of the batch file are entirely your choice. A
+suggested command would be to add \fBNET TIME \\\\SERVER /SET
+/YES\fR, to force every machine to synchronize clocks with
+the same time server. Another use would be to add \fBNET USE
+U: \\\\SERVER\\UTILS\fR for commonly used utilities, or \fB NET USE Q: \\\\SERVER\\ISO9001_QA\fR for example.
+
+Note that it is particularly important not to allow write
+access to the [netlogon] share, or to grant users write permission
+on the batch files in a secure environment, as this would allow
+the batch files to be arbitrarily modified and security to be
+breached.
+
+This option takes the standard substitutions, allowing you
+to have separate logon scripts for each user or machine.
+
+This option is only useful if Samba is set up as a logon
+server.
+
+Default: \fBno logon script defined\fR
+
+Example: \fBlogon script = scripts\\%U.bat\fR
+.TP
+\fBlppause command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to stop printing or spooling
+a specific print job.
+
+This command should be a program or script which takes
+a printer name and job number to pause the print job. One way
+of implementing this is by using job priorities, where jobs
+having a too low priority won't be sent to the printer.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. A \fI%j\fR is replaced with
+the job number (an integer). On HPUX (see \fIprinting=hpux
+\fR), if the \fI-p%p\fR option is added
+to the lpq command, the job will show up with the correct status, i.e.
+if the job priority is lower than the set fence priority it will
+have the PAUSED status, whereas if the priority is equal or higher it
+will have the SPOOLED or PRINTING status.
+
+Note that it is good practice to include the absolute path
+in the lppause command as the PATH may not be available to the server.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: Currently no default value is given to
+this string, unless the value of the \fIprinting\fR
+parameter is SYSV, in which case the default is :
+
+\fBlp -i %p-%j -H hold\fR
+
+or if the value of the \fIprinting\fR parameter
+is SOFTQ, then the default is:
+
+\fBqstat -s -j%j -h\fR
+
+Example for HPUX: \fBlppause command = /usr/bin/lpalt
+%p-%j -p0\fR
+.TP
+\fBlpq cache time (G)\fR
+This controls how long lpq info will be cached
+for to prevent the \fBlpq\fR command being called too
+often. A separate cache is kept for each variation of the \fB lpq\fR command used by the system, so if you use different
+\fBlpq\fR commands for different users then they won't
+share cache information.
+
+The cache files are stored in \fI/tmp/lpq.xxxx\fR
+where xxxx is a hash of the \fBlpq\fR command in use.
+
+The default is 10 seconds, meaning that the cached results
+of a previous identical \fBlpq\fR command will be used
+if the cached data is less than 10 seconds old. A large value may
+be advisable if your \fBlpq\fR command is very slow.
+
+A value of 0 will disable caching completely.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: \fBlpq cache time = 10\fR
+
+Example: \fBlpq cache time = 30\fR
+.TP
+\fBlpq command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to obtain \fBlpq
+\fR-style printer status information.
+
+This command should be a program or script which
+takes a printer name as its only parameter and outputs printer
+status information.
+
+Currently nine styles of printer status information
+are supported; BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, CUPS, and SOFTQ.
+This covers most UNIX systems. You control which type is expected
+using the \fIprinting =\fR option.
+
+Some clients (notably Windows for Workgroups) may not
+correctly send the connection number for the printer they are
+requesting status information about. To get around this, the
+server reports on the first printer service connected to by the
+client. This only happens if the connection number sent is invalid.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. Otherwise it is placed at the end of the
+command.
+
+Note that it is good practice to include the absolute path
+in the \fIlpq command\fR as the \fB$PATH
+\fRmay not be available to the server. When compiled with
+the CUPS libraries, no \fIlpq command\fR is
+needed because smbd will make a library call to obtain the
+print queue listing.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: \fBdepends on the setting of \fI printing\fB\fR
+
+Example: \fBlpq command = /usr/bin/lpq -P%p\fR
+.TP
+\fBlpresume command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to restart or continue
+printing or spooling a specific print job.
+
+This command should be a program or script which takes
+a printer name and job number to resume the print job. See
+also the \fIlppause command
+\fRparameter.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. A \fI%j\fR is replaced with
+the job number (an integer).
+
+Note that it is good practice to include the absolute path
+in the \fIlpresume command\fR as the PATH may not
+be available to the server.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: Currently no default value is given
+to this string, unless the value of the \fIprinting\fR
+parameter is SYSV, in which case the default is :
+
+\fBlp -i %p-%j -H resume\fR
+
+or if the value of the \fIprinting\fR parameter
+is SOFTQ, then the default is:
+
+\fBqstat -s -j%j -r\fR
+
+Example for HPUX: \fBlpresume command = /usr/bin/lpalt
+%p-%j -p2\fR
+.TP
+\fBlprm command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to delete a print job.
+
+This command should be a program or script which takes
+a printer name and job number, and deletes the print job.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. A \fI%j\fR is replaced with
+the job number (an integer).
+
+Note that it is good practice to include the absolute
+path in the \fIlprm command\fR as the PATH may not be
+available to the server.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: \fBdepends on the setting of \fIprinting
+\fB\fR
+Example 1: \fBlprm command = /usr/bin/lprm -P%p %j
+\fR
+Example 2: \fBlprm command = /usr/bin/cancel %p-%j
+\fR.TP
+\fBmachine password timeout (G)\fR
+If a Samba server is a member of a Windows
+NT Domain (see the security = domain)
+parameter) then periodically a running smbd(8) process will try and change the MACHINE ACCOUNT
+PASSWORD stored in the TDB called \fIprivate/secrets.tdb
+\fR\&. This parameter specifies how often this password
+will be changed, in seconds. The default is one week (expressed in
+seconds), the same as a Windows NT Domain member server.
+
+See also \fBsmbpasswd(8)
+\fR and the security = domain) parameter.
+
+Default: \fBmachine password timeout = 604800\fR
+.TP
+\fBmagic output (S)\fR
+This parameter specifies the name of a file
+which will contain output created by a magic script (see the
+\fImagic script\fR
+parameter below).
+
+Warning: If two clients use the same \fImagic script
+\fRin the same directory the output file content
+is undefined.
+
+Default: \fBmagic output = <magic script name>.out
+\fR
+Example: \fBmagic output = myfile.txt\fR
+.TP
+\fBmagic script (S)\fR
+This parameter specifies the name of a file which,
+if opened, will be executed by the server when the file is closed.
+This allows a UNIX script to be sent to the Samba host and
+executed on behalf of the connected user.
+
+Scripts executed in this way will be deleted upon
+completion assuming that the user has the appropriate level
+of privilege and the file permissions allow the deletion.
+
+If the script generates output, output will be sent to
+the file specified by the \fI magic output\fR parameter (see above).
+
+Note that some shells are unable to interpret scripts
+containing CR/LF instead of CR as
+the end-of-line marker. Magic scripts must be executable
+\fBas is\fR on the host, which for some hosts and
+some shells will require filtering at the DOS end.
+
+Magic scripts are \fBEXPERIMENTAL\fR and
+should \fBNOT\fR be relied upon.
+
+Default: \fBNone. Magic scripts disabled.\fR
+
+Example: \fBmagic script = user.csh\fR
+.TP
+\fBmangle case (S)\fR
+See the section on NAME MANGLING
+
+Default: \fBmangle case = no\fR
+.TP
+\fBmangled map (S)\fR
+This is for those who want to directly map UNIX
+file names which cannot be represented on Windows/DOS. The mangling
+of names is not always what is needed. In particular you may have
+documents with file extensions that differ between DOS and UNIX.
+For example, under UNIX it is common to use \fI.html\fR
+for HTML files, whereas under Windows/DOS \fI.htm\fR
+is more commonly used.
+
+So to map \fIhtml\fR to \fIhtm\fR
+you would use:
+
+\fBmangled map = (*.html *.htm)\fR
+
+One very useful case is to remove the annoying \fI;1
+\fRoff the ends of filenames on some CDROMs (only visible
+under some UNIXes). To do this use a map of (*;1 *;).
+
+Default: \fBno mangled map\fR
+
+Example: \fBmangled map = (*;1 *;)\fR
+.TP
+\fBmangled names (S)\fR
+This controls whether non-DOS names under UNIX
+should be mapped to DOS-compatible names ("mangled") and made visible,
+or whether non-DOS names should simply be ignored.
+
+See the section on NAME MANGLING for details on how to control the mangling process.
+
+If mangling algorithm "hash" is used then the mangling algorithm is as follows:
+.RS
+.TP 0.2i
+\(bu
+The first (up to) five alphanumeric characters
+before the rightmost dot of the filename are preserved, forced
+to upper case, and appear as the first (up to) five characters
+of the mangled name.
+.TP 0.2i
+\(bu
+A tilde "~" is appended to the first part of the mangled
+name, followed by a two-character unique sequence, based on the
+original root name (i.e., the original filename minus its final
+extension). The final extension is included in the hash calculation
+only if it contains any upper case characters or is longer than three
+characters.
+
+Note that the character to use may be specified using
+the \fImangling char\fR
+option, if you don't like '~'.
+.TP 0.2i
+\(bu
+The first three alphanumeric characters of the final
+extension are preserved, forced to upper case and appear as the
+extension of the mangled name. The final extension is defined as that
+part of the original filename after the rightmost dot. If there are no
+dots in the filename, the mangled name will have no extension (except
+in the case of "hidden files" - see below).
+.TP 0.2i
+\(bu
+Files whose UNIX name begins with a dot will be
+presented as DOS hidden files. The mangled name will be created as
+for other filenames, but with the leading dot removed and "___" as
+its extension regardless of actual original extension (that's three
+underscores).
+.RE
+.PP
+The two-digit hash value consists of upper case
+alphanumeric characters.
+.PP
+.PP
+This algorithm can cause name collisions only if files
+in a directory share the same first five alphanumeric characters.
+The probability of such a clash is 1/1300.
+.PP
+.PP
+If mangling algorithm "hash2" is used then the mangling algorithm is as follows:
+.PP
+.RS
+.TP 0.2i
+\(bu
+The first alphanumeric character
+before the rightmost dot of the filename is preserved, forced
+to upper case, and appears as the first character of the mangled name.
+.TP 0.2i
+\(bu
+A base63 hash of 5 characters is generated and the
+first 4 characters of that hash are appended to the first character.
+.TP 0.2i
+\(bu
+A tilde "~" is appended to the first part of the mangled
+name, followed by the final character of the base36 hash of the name.
+
+Note that the character to use may be specified using
+the \fImangling char\fR
+option, if you don't like '~'.
+.TP 0.2i
+\(bu
+The first three alphanumeric characters of the final
+extension are preserved, forced to upper case and appear as the
+extension of the mangled name. The final extension is defined as that
+part of the original filename after the rightmost dot. If there are no
+dots in the filename, the mangled name will have no extension (except
+in the case of "hidden files" - see below).
+.TP 0.2i
+\(bu
+Files whose UNIX name begins with a dot will be
+presented as DOS hidden files. The mangled name will be created as
+for other filenames, but with the leading dot removed and "___" as
+its extension regardless of actual original extension (that's three
+underscores).
+.RE
+.PP
+The name mangling (if enabled) allows a file to be
+copied between UNIX directories from Windows/DOS while retaining
+the long UNIX filename. UNIX files can be renamed to a new extension
+from Windows/DOS and will retain the same basename. Mangled names
+do not change between sessions.
+.PP
+.PP
+Default: \fBmangled names = yes\fR
+.PP
+.TP
+\fBmangled stack (G)\fR
+This parameter controls the number of mangled names
+that should be cached in the Samba server smbd(8)
+
+This stack is a list of recently mangled base names
+(extensions are only maintained if they are longer than 3 characters
+or contains upper case characters).
+
+The larger this value, the more likely it is that mangled
+names can be successfully converted to correct long UNIX names.
+However, large stack sizes will slow most directory accesses. Smaller
+stacks save memory in the server (each stack element costs 256 bytes).
+
+It is not possible to absolutely guarantee correct long
+filenames, so be prepared for some surprises!
+
+Default: \fBmangled stack = 50\fR
+
+Example: \fBmangled stack = 100\fR
+.TP
+\fBmangling char (S)\fR
+This controls what character is used as
+the \fBmagic\fR character in name mangling. The default is a '~'
+but this may interfere with some software. Use this option to set
+it to whatever you prefer.
+
+Default: \fBmangling char = ~\fR
+
+Example: \fBmangling char = ^\fR
+.TP
+\fBmangling mathod(G)\fR
+controls the algorithm used for the generating
+the mangled names. Can take two different values, "hash" and
+"hash2". "hash" is the default and is the algorithm that has been
+used in Samba for many years. "hash2" is a newer and considered
+a better algorithm (generates less collisions) in the names.
+However, many Win32 applications store the mangled names and so
+changing to the new algorithm must not be done
+lightly as these applications may break unless reinstalled.
+New installations of Samba may set the default to hash2.
+
+Default: \fBmangling method = hash\fR
+
+Example: \fBmangling method = hash2\fR
+.TP
+\fBmap archive (S)\fR
+This controls whether the DOS archive attribute
+should be mapped to the UNIX owner execute bit. The DOS archive bit
+is set when a file has been modified since its last backup. One
+motivation for this option it to keep Samba/your PC from making
+any file it touches from becoming executable under UNIX. This can
+be quite annoying for shared source code, documents, etc...
+
+Note that this requires the \fIcreate mask\fR
+parameter to be set such that owner execute bit is not masked out
+(i.e. it must include 100). See the parameter \fIcreate mask\fR for details.
+
+Default: \fBmap archive = yes\fR
+.TP
+\fBmap hidden (S)\fR
+This controls whether DOS style hidden files
+should be mapped to the UNIX world execute bit.
+
+Note that this requires the \fIcreate mask\fR
+to be set such that the world execute bit is not masked out (i.e.
+it must include 001). See the parameter \fIcreate mask\fR for details.
+
+Default: \fBmap hidden = no\fR
+.TP
+\fBmap system (S)\fR
+This controls whether DOS style system files
+should be mapped to the UNIX group execute bit.
+
+Note that this requires the \fIcreate mask\fR
+to be set such that the group execute bit is not masked out (i.e.
+it must include 010). See the parameter \fIcreate mask\fR for details.
+
+Default: \fBmap system = no\fR
+.TP
+\fBmap to guest (G)\fR
+This parameter is only useful in security modes other than \fIsecurity = share\fR
+- i.e. user, server,
+and domain.
+
+This parameter can take three different values, which tell
+smbd(8) what to do with user
+login requests that don't match a valid UNIX user in some way.
+
+The three settings are :
+.RS
+.TP 0.2i
+\(bu
+Never - Means user login
+requests with an invalid password are rejected. This is the
+default.
+.TP 0.2i
+\(bu
+Bad User - Means user
+logins with an invalid password are rejected, unless the username
+does not exist, in which case it is treated as a guest login and
+mapped into the \fI guest account\fR.
+.TP 0.2i
+\(bu
+Bad Password - Means user logins
+with an invalid password are treated as a guest login and mapped
+into the guest account. Note that
+this can cause problems as it means that any user incorrectly typing
+their password will be silently logged on as "guest" - and
+will not know the reason they cannot access files they think
+they should - there will have been no message given to them
+that they got their password wrong. Helpdesk services will
+\fBhate\fR you if you set the \fImap to
+guest\fR parameter this way :-).
+.RE
+.PP
+Note that this parameter is needed to set up "Guest"
+share services when using \fIsecurity\fR modes other than
+share. This is because in these modes the name of the resource being
+requested is \fBnot\fR sent to the server until after
+the server has successfully authenticated the client so the server
+cannot make authentication decisions at the correct time (connection
+to the share) for "Guest" shares.
+.PP
+.PP
+For people familiar with the older Samba releases, this
+parameter maps to the old compile-time setting of the GUEST_SESSSETUP value in local.h.
+.PP
+.PP
+Default: \fBmap to guest = Never\fR
+.PP
+.PP
+Example: \fBmap to guest = Bad User\fR
+.PP
+.TP
+\fBmax connections (S)\fR
+This option allows the number of simultaneous
+connections to a service to be limited. If \fImax connections
+\fRis greater than 0 then connections will be refused if
+this number of connections to the service are already open. A value
+of zero mean an unlimited number of connections may be made.
+
+Record lock files are used to implement this feature. The
+lock files will be stored in the directory specified by the \fIlock directory\fR
+option.
+
+Default: \fBmax connections = 0\fR
+
+Example: \fBmax connections = 10\fR
+.TP
+\fBmax disk size (G)\fR
+This option allows you to put an upper limit
+on the apparent size of disks. If you set this option to 100
+then all shares will appear to be not larger than 100 MB in
+size.
+
+Note that this option does not limit the amount of
+data you can put on the disk. In the above case you could still
+store much more than 100 MB on the disk, but if a client ever asks
+for the amount of free disk space or the total disk size then the
+result will be bounded by the amount specified in \fImax
+disk size\fR.
+
+This option is primarily useful to work around bugs
+in some pieces of software that can't handle very large disks,
+particularly disks over 1GB in size.
+
+A \fImax disk size\fR of 0 means no limit.
+
+Default: \fBmax disk size = 0\fR
+
+Example: \fBmax disk size = 1000\fR
+.TP
+\fBmax log size (G)\fR
+This option (an integer in kilobytes) specifies
+the max size the log file should grow to. Samba periodically checks
+the size and if it is exceeded it will rename the file, adding
+a \fI.old\fR extension.
+
+A size of 0 means no limit.
+
+Default: \fBmax log size = 5000\fR
+
+Example: \fBmax log size = 1000\fR
+.TP
+\fBmax mux (G)\fR
+This option controls the maximum number of
+outstanding simultaneous SMB operations that Samba tells the client
+it will allow. You should never need to set this parameter.
+
+Default: \fBmax mux = 50\fR
+.TP
+\fBmax open files (G)\fR
+This parameter limits the maximum number of
+open files that one smbd(8) file
+serving process may have open for a client at any one time. The
+default for this parameter is set very high (10,000) as Samba uses
+only one bit per unopened file.
+
+The limit of the number of open files is usually set
+by the UNIX per-process file descriptor limit rather than
+this parameter so you should never need to touch this parameter.
+
+Default: \fBmax open files = 10000\fR
+.TP
+\fBmax print jobs (S)\fR
+This parameter limits the maximum number of
+jobs allowable in a Samba printer queue at any given moment.
+If this number is exceeded, \fB smbd(8)\fR will remote "Out of Space" to the client.
+See all \fItotal
+print jobs\fR.
+
+Default: \fBmax print jobs = 1000\fR
+
+Example: \fBmax print jobs = 5000\fR
+.TP
+\fBmax protocol (G)\fR
+The value of the parameter (a string) is the highest
+protocol level that will be supported by the server.
+
+Possible values are :
+.RS
+.TP 0.2i
+\(bu
+CORE: Earliest version. No
+concept of user names.
+.TP 0.2i
+\(bu
+COREPLUS: Slight improvements on
+CORE for efficiency.
+.TP 0.2i
+\(bu
+LANMAN1: First \fB modern\fR version of the protocol. Long filename
+support.
+.TP 0.2i
+\(bu
+LANMAN2: Updates to Lanman1 protocol.
+.TP 0.2i
+\(bu
+NT1: Current up to date version of
+the protocol. Used by Windows NT. Known as CIFS.
+.RE
+.PP
+Normally this option should not be set as the automatic
+negotiation phase in the SMB protocol takes care of choosing
+the appropriate protocol.
+.PP
+.PP
+See also \fImin
+protocol\fR
+.PP
+.PP
+Default: \fBmax protocol = NT1\fR
+.PP
+.PP
+Example: \fBmax protocol = LANMAN1\fR
+.PP
+.TP
+\fBmax smbd processes (G)\fR
+This parameter limits the maximum number of
+\fBsmbd(8)\fR
+processes concurrently running on a system and is intended
+as a stopgap to prevent degrading service to clients in the event
+that the server has insufficient resources to handle more than this
+number of connections. Remember that under normal operating
+conditions, each user will have an smbd associated with him or her
+to handle connections to all shares from a given host.
+
+Default: \fBmax smbd processes = 0\fR ## no limit
+
+Example: \fBmax smbd processes = 1000\fR
+.TP
+\fBmax ttl (G)\fR
+This option tells nmbd(8)
+what the default 'time to live' of NetBIOS names should be (in seconds)
+when \fBnmbd\fR is requesting a name using either a
+broadcast packet or from a WINS server. You should never need to
+change this parameter. The default is 3 days.
+
+Default: \fBmax ttl = 259200\fR
+.TP
+\fBmax wins ttl (G)\fR
+This option tells nmbd(8)
+ when acting as a WINS server ( \fIwins support = yes\fR) what the maximum
+\&'time to live' of NetBIOS names that \fBnmbd\fR
+will grant will be (in seconds). You should never need to change this
+parameter. The default is 6 days (518400 seconds).
+
+See also the \fImin
+wins ttl\fR parameter.
+
+Default: \fBmax wins ttl = 518400\fR
+.TP
+\fBmax xmit (G)\fR
+This option controls the maximum packet size
+that will be negotiated by Samba. The default in Samba 2.2.6 is
+now 16644 (changed from 65535 in earlier releases) which matches
+Windows 2000. This allows better performance with Windows NT clients.
+The maximum is 65535. In some cases you may find you get better performance
+with a smaller value. A value below 2048 is likely to cause problems.
+
+Default: \fBmax xmit = 16644\fR
+
+Example: \fBmax xmit = 8192\fR
+.TP
+\fBmessage command (G)\fR
+This specifies what command to run when the
+server receives a WinPopup style message.
+
+This would normally be a command that would
+deliver the message somehow. How this is to be done is
+up to your imagination.
+
+An example is:
+
+\fBmessage command = csh -c 'xedit %s;rm %s' &\fR
+
+This delivers the message using \fBxedit\fR, then
+removes it afterwards. \fBNOTE THAT IT IS VERY IMPORTANT
+THAT THIS COMMAND RETURN IMMEDIATELY\fR. That's why I
+have the '&' on the end. If it doesn't return immediately then
+your PCs may freeze when sending messages (they should recover
+after 30 seconds, hopefully).
+
+All messages are delivered as the global guest user.
+The command takes the standard substitutions, although \fI %u\fR won't work (\fI%U\fR may be better
+in this case).
+
+Apart from the standard substitutions, some additional
+ones apply. In particular:
+.RS
+.TP 0.2i
+\(bu
+\fI%s\fR = the filename containing
+the message.
+.TP 0.2i
+\(bu
+\fI%t\fR = the destination that
+the message was sent to (probably the server name).
+.TP 0.2i
+\(bu
+\fI%f\fR = who the message
+is from.
+.RE
+.PP
+You could make this command send mail, or whatever else
+takes your fancy. Please let us know of any really interesting
+ideas you have.
+.PP
+.PP
+Here's a way of sending the messages as mail to root:
+.PP
+.PP
+\fBmessage command = /bin/mail -s 'message from %f on
+%m' root < %s; rm %s\fR
+.PP
+.PP
+If you don't have a message command then the message
+won't be delivered and Samba will tell the sender there was
+an error. Unfortunately WfWg totally ignores the error code
+and carries on regardless, saying that the message was delivered.
+.PP
+.PP
+If you want to silently delete it then try:
+.PP
+.PP
+\fBmessage command = rm %s\fR
+.PP
+.PP
+Default: \fBno message command\fR
+.PP
+.PP
+Example: \fBmessage command = csh -c 'xedit %s;
+rm %s' &\fR
+.PP
+.TP
+\fBmin passwd length (G)\fR
+Synonym for \fImin password length\fR.
+.TP
+\fBmin password length (G)\fR
+This option sets the minimum length in characters
+of a plaintext password that \fBsmbd\fR will accept when performing
+UNIX password changing.
+
+See also \fIunix
+password sync\fR, \fIpasswd program\fR and \fIpasswd chat debug\fR
+\&.
+
+Default: \fBmin password length = 5\fR
+.TP
+\fBmin print space (S)\fR
+This sets the minimum amount of free disk
+space that must be available before a user will be able to spool
+a print job. It is specified in kilobytes. The default is 0, which
+means a user can always spool a print job.
+
+See also the \fIprinting
+\fRparameter.
+
+Default: \fBmin print space = 0\fR
+
+Example: \fBmin print space = 2000\fR
+.TP
+\fBmin protocol (G)\fR
+The value of the parameter (a string) is the
+lowest SMB protocol dialect than Samba will support. Please refer
+to the \fImax protocol\fR
+parameter for a list of valid protocol names and a brief description
+of each. You may also wish to refer to the C source code in
+\fIsource/smbd/negprot.c\fR for a listing of known protocol
+dialects supported by clients.
+
+If you are viewing this parameter as a security measure, you should
+also refer to the \fIlanman
+auth\fR parameter. Otherwise, you should never need
+to change this parameter.
+
+Default : \fBmin protocol = CORE\fR
+
+Example : \fBmin protocol = NT1\fR # disable DOS
+clients
+.TP
+\fBmin wins ttl (G)\fR
+This option tells nmbd(8)
+when acting as a WINS server (\fI wins support = yes\fR) what the minimum 'time to live'
+of NetBIOS names that \fBnmbd\fR will grant will be (in
+seconds). You should never need to change this parameter. The default
+is 6 hours (21600 seconds).
+
+Default: \fBmin wins ttl = 21600\fR
+.TP
+\fBmsdfs root (S)\fR
+This boolean parameter is only available if
+Samba is configured and compiled with the \fB --with-msdfs\fR option. If set to yes,
+Samba treats the share as a Dfs root and allows clients to browse
+the distributed file system tree rooted at the share directory.
+Dfs links are specified in the share directory by symbolic
+links of the form \fImsdfs:serverA\\shareA,serverB\\shareB
+\fRand so on. For more information on setting up a Dfs tree
+on Samba, refer to msdfs_setup.html
+
+
+See also \fIhost msdfs
+\fR
+Default: \fBmsdfs root = no\fR
+.TP
+\fBname resolve order (G)\fR
+This option is used by the programs in the Samba
+suite to determine what naming services to use and in what order
+to resolve host names to IP addresses. The option takes a space
+separated string of name resolution options.
+
+The options are :"lmhosts", "host", "wins" and "bcast". They
+cause names to be resolved as follows :
+.RS
+.TP 0.2i
+\(bu
+lmhosts : Lookup an IP
+address in the Samba lmhosts file. If the line in lmhosts has
+no name type attached to the NetBIOS name (see the lmhosts(5) for details) then
+any name type matches for lookup.
+.TP 0.2i
+\(bu
+host : Do a standard host
+name to IP address resolution, using the system \fI/etc/hosts
+\fR, NIS, or DNS lookups. This method of name resolution
+is operating system depended for instance on IRIX or Solaris this
+may be controlled by the \fI/etc/nsswitch.conf\fR
+file. Note that this method is only used if the NetBIOS name
+type being queried is the 0x20 (server) name type, otherwise
+it is ignored.
+.TP 0.2i
+\(bu
+wins : Query a name with
+the IP address listed in the \fI wins server\fR parameter. If no WINS server has
+been specified this method will be ignored.
+.TP 0.2i
+\(bu
+bcast : Do a broadcast on
+each of the known local interfaces listed in the \fIinterfaces\fR
+parameter. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally
+connected subnet.
+.RE
+.PP
+Default: \fBname resolve order = lmhosts host wins bcast
+\fR.PP
+.PP
+Example: \fBname resolve order = lmhosts bcast host
+\fR.PP
+.PP
+This will cause the local lmhosts file to be examined
+first, followed by a broadcast attempt, followed by a normal
+system hostname lookup.
+.PP
+.TP
+\fBnetbios aliases (G)\fR
+This is a list of NetBIOS names that nmbd(8) will advertise as additional
+names by which the Samba server is known. This allows one machine
+to appear in browse lists under multiple names. If a machine is
+acting as a browse server or logon server none
+of these names will be advertised as either browse server or logon
+servers, only the primary name of the machine will be advertised
+with these capabilities.
+
+See also \fInetbios
+name\fR.
+
+Default: \fBempty string (no additional names)\fR
+
+Example: \fBnetbios aliases = TEST TEST1 TEST2\fR
+.TP
+\fBnetbios name (G)\fR
+This sets the NetBIOS name by which a Samba
+server is known. By default it is the same as the first component
+of the host's DNS name. If a machine is a browse server or
+logon server this name (or the first component
+of the hosts DNS name) will be the name that these services are
+advertised under.
+
+See also \fInetbios
+aliases\fR.
+
+Default: \fBmachine DNS name\fR
+
+Example: \fBnetbios name = MYNAME\fR
+.TP
+\fBnetbios scope (G)\fR
+This sets the NetBIOS scope that Samba will
+operate under. This should not be set unless every machine
+on your LAN also sets this value.
+.TP
+\fBnis homedir (G)\fR
+Get the home share server from a NIS map. For
+UNIX systems that use an automounter, the user's home directory
+will often be mounted on a workstation on demand from a remote
+server.
+
+When the Samba logon server is not the actual home directory
+server, but is mounting the home directories via NFS then two
+network hops would be required to access the users home directory
+if the logon server told the client to use itself as the SMB server
+for home directories (one over SMB and one over NFS). This can
+be very slow.
+
+This option allows Samba to return the home share as
+being on a different server to the logon server and as
+long as a Samba daemon is running on the home directory server,
+it will be mounted on the Samba client directly from the directory
+server. When Samba is returning the home share to the client, it
+will consult the NIS map specified in \fIhomedir map\fR and return the server
+listed there.
+
+Note that for this option to work there must be a working
+NIS system and the Samba server with this option must also
+be a logon server.
+
+Default: \fBnis homedir = no\fR
+.TP
+\fBnt acl support (S)\fR
+This boolean parameter controls whether
+smbd(8) will attempt to map
+UNIX permissions into Windows NT access control lists.
+This parameter was formally a global parameter in releases
+prior to 2.2.2.
+
+Default: \fBnt acl support = yes\fR
+.TP
+\fBnt pipe support (G)\fR
+This boolean parameter controls whether
+smbd(8) will allow Windows NT
+clients to connect to the NT SMB specific IPC$
+pipes. This is a developer debugging option and can be left
+alone.
+
+Default: \fBnt pipe support = yes\fR
+.TP
+\fBnt smb support (G)\fR
+This boolean parameter controls whether smbd(8) will negotiate NT specific SMB
+support with Windows NT/2k/XP clients. Although this is a developer
+debugging option and should be left alone, benchmarking has discovered
+that Windows NT clients give faster performance with this option
+set to no. This is still being investigated.
+If this option is set to no then Samba offers
+exactly the same SMB calls that versions prior to Samba 2.0 offered.
+This information may be of use if any users are having problems
+with NT SMB support.
+
+You should not need to ever disable this parameter.
+
+Default: \fBnt smb support = yes\fR
+.TP
+\fBnt status support (G)\fR
+This boolean parameter controls whether smbd(8) will negotiate NT specific status
+support with Windows NT/2k/XP clients. This is a developer
+debugging option and should be left alone.
+If this option is set to no then Samba offers
+exactly the same DOS error codes that versions prior to Samba 2.2.3
+reported.
+
+You should not need to ever disable this parameter.
+
+Default: \fBnt status support = yes\fR
+.TP
+\fBnull passwords (G)\fR
+Allow or disallow client access to accounts
+that have null passwords.
+
+See also smbpasswd (5)
+
+Default: \fBnull passwords = no\fR
+.TP
+\fBobey pam restrictions (G)\fR
+When Samba 2.2 is configured to enable PAM support
+(i.e. --with-pam), this parameter will control whether or not Samba
+should obey PAM's account and session management directives. The
+default behavior is to use PAM for clear text authentication only
+and to ignore any account or session management. Note that Samba
+always ignores PAM for authentication in the case of \fIencrypt passwords = yes\fR
+\&. The reason is that PAM modules cannot support the challenge/response
+authentication mechanism needed in the presence of SMB password encryption.
+
+Default: \fBobey pam restrictions = no\fR
+.TP
+\fBonly user (S)\fR
+This is a boolean option that controls whether
+connections with usernames not in the \fIuser\fR
+list will be allowed. By default this option is disabled so that a
+client can supply a username to be used by the server. Enabling
+this parameter will force the server to only use the login
+names from the \fIuser\fR list and is only really
+useful in share level
+security.
+
+Note that this also means Samba won't try to deduce
+usernames from the service name. This can be annoying for
+the [homes] section. To get around this you could use \fBuser =
+%S\fR which means your \fIuser\fR list
+will be just the service name, which for home directories is the
+name of the user.
+
+See also the \fIuser\fR
+parameter.
+
+Default: \fBonly user = no\fR
+.TP
+\fBonly guest (S)\fR
+A synonym for \fI guest only\fR.
+.TP
+\fBoplock break wait time (G)\fR
+This is a tuning parameter added due to bugs in
+both Windows 9x and WinNT. If Samba responds to a client too
+quickly when that client issues an SMB that can cause an oplock
+break request, then the network client can fail and not respond
+to the break request. This tuning parameter (which is set in milliseconds)
+is the amount of time Samba will wait before sending an oplock break
+request to such (broken) clients.
+
+\fBDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+AND UNDERSTOOD THE SAMBA OPLOCK CODE\fR.
+
+Default: \fBoplock break wait time = 0\fR
+.TP
+\fBoplock contention limit (S)\fR
+This is a \fBvery\fR advanced
+smbd(8) tuning option to
+improve the efficiency of the granting of oplocks under multiple
+client contention for the same file.
+
+In brief it specifies a number, which causes smbd not to
+grant an oplock even when requested if the approximate number of
+clients contending for an oplock on the same file goes over this
+limit. This causes \fBsmbd\fR to behave in a similar
+way to Windows NT.
+
+\fBDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ
+AND UNDERSTOOD THE SAMBA OPLOCK CODE\fR.
+
+Default: \fBoplock contention limit = 2\fR
+.TP
+\fBoplocks (S)\fR
+This boolean option tells \fBsmbd\fR whether to
+issue oplocks (opportunistic locks) to file open requests on this
+share. The oplock code can dramatically (approx. 30% or more) improve
+the speed of access to files on Samba servers. It allows the clients
+to aggressively cache files locally and you may want to disable this
+option for unreliable network environments (it is turned on by
+default in Windows NT Servers). For more information see the file
+\fISpeed.txt\fR in the Samba \fIdocs/\fR
+directory.
+
+Oplocks may be selectively turned off on certain files with a
+share. See the \fI veto oplock files\fR parameter. On some systems
+oplocks are recognized by the underlying operating system. This
+allows data synchronization between all access to oplocked files,
+whether it be via Samba or NFS or a local UNIX process. See the
+\fIkernel oplocks\fR parameter for details.
+
+See also the \fIkernel
+oplocks\fR and \fI level2 oplocks\fR parameters.
+
+Default: \fBoplocks = yes\fR
+.TP
+\fBos level (G)\fR
+This integer value controls what level Samba
+advertises itself as for browse elections. The value of this
+parameter determines whether nmbd(8)
+has a chance of becoming a local master browser for the \fI WORKGROUP\fR in the local broadcast area.
+
+\fBNote :\fRBy default, Samba will win
+a local master browsing election over all Microsoft operating
+systems except a Windows NT 4.0/2000 Domain Controller. This
+means that a misconfigured Samba host can effectively isolate
+a subnet for browsing purposes. See \fIBROWSING.txt
+\fRin the Samba \fIdocs/\fR directory
+for details.
+
+Default: \fBos level = 20\fR
+
+Example: \fBos level = 65 \fR
+.TP
+\fBos2 driver map (G)\fR
+The parameter is used to define the absolute
+path to a file containing a mapping of Windows NT printer driver
+names to OS/2 printer driver names. The format is:
+
+<nt driver name> = <os2 driver
+name>.<device name>
+
+For example, a valid entry using the HP LaserJet 5
+printer driver would appear as \fBHP LaserJet 5L = LASERJET.HP
+LaserJet 5L\fR.
+
+The need for the file is due to the printer driver namespace
+problem described in the Samba
+Printing HOWTO For more details on OS/2 clients, please
+refer to the OS2-Client-HOWTO
+ containing in the Samba documentation.
+
+Default: \fBos2 driver map = <empty string>
+\fR.TP
+\fBpam password change (G)\fR
+With the addition of better PAM support in Samba 2.2,
+this parameter, it is possible to use PAM's password change control
+flag for Samba. If enabled, then PAM will be used for password
+changes when requested by an SMB client instead of the program listed in
+\fIpasswd program\fR.
+It should be possible to enable this without changing your
+\fIpasswd chat\fR
+parameter for most setups.
+
+Default: \fBpam password change = no\fR
+.TP
+\fBpanic action (G)\fR
+This is a Samba developer option that allows a
+system command to be called when either smbd(8)
+crashes. This is usually used to draw attention to the fact that
+a problem occurred.
+
+Default: \fBpanic action = <empty string>\fR
+
+Example: \fBpanic action = "/bin/sleep 90000"\fR
+.TP
+\fBpasswd chat (G)\fR
+This string controls the \fB"chat"\fR
+conversation that takes places between smbd and the local password changing
+program to change the user's password. The string describes a
+sequence of response-receive pairs that smbd(8) uses to determine what to send to the
+\fIpasswd program\fR
+and what to expect back. If the expected output is not
+received then the password is not changed.
+
+This chat sequence is often quite site specific, depending
+on what local methods are used for password control (such as NIS
+etc).
+
+Note that this parameter only is only used if the \fIunix
+password sync\fR parameter is set to yes. This
+sequence is then called \fBAS ROOT\fR when the SMB password
+in the smbpasswd file is being changed, without access to the old
+password cleartext. This means that root must be able to reset the user's password
+without knowing the text of the previous password. In the presence of NIS/YP,
+this means that the passwd program must be
+executed on the NIS master.
+
+The string can contain the macro \fI%n\fR which is substituted
+for the new password. The chat sequence can also contain the standard
+macros \\n, \\r, \\t and \\s to give line-feed,
+carriage-return, tab and space. The chat sequence string can also contain
+a '*' which matches any sequence of characters.
+Double quotes can be used to collect strings with spaces
+in them into a single string.
+
+If the send string in any part of the chat sequence
+is a full stop ".", then no string is sent. Similarly,
+if the expect string is a full stop then no string is expected.
+
+If the \fIpam
+password change\fR parameter is set to yes, the chat pairs
+may be matched in any order, and success is determined by the PAM result,
+not any particular output. The \\n macro is ignored for PAM conversions.
+
+See also \fIunix password
+sync\fR, \fI passwd program\fR , \fIpasswd chat debug\fR and \fIpam password change\fR.
+
+Default: \fBpasswd chat = *new*password* %n\\n
+*new*password* %n\\n *changed*\fR
+
+Example: \fBpasswd chat = "*Enter OLD password*" %o\\n
+"*Enter NEW password*" %n\\n "*Reenter NEW password*" %n\\n "*Password
+changed*"\fR
+.TP
+\fBpasswd chat debug (G)\fR
+This boolean specifies if the passwd chat script
+parameter is run in \fBdebug\fR mode. In this mode the
+strings passed to and received from the passwd chat are printed
+in the smbd(8) log with a
+\fIdebug level\fR
+of 100. This is a dangerous option as it will allow plaintext passwords
+to be seen in the \fBsmbd\fR log. It is available to help
+Samba admins debug their \fIpasswd chat\fR scripts
+when calling the \fIpasswd program\fR and should
+be turned off after this has been done. This option has no effect if the
+\fIpam password change\fR
+paramter is set. This parameter is off by default.
+
+See also \fIpasswd chat\fR
+, \fIpam password change\fR
+, \fIpasswd program\fR
+\&.
+
+Default: \fBpasswd chat debug = no\fR
+.TP
+\fBpasswd program (G)\fR
+The name of a program that can be used to set
+UNIX user passwords. Any occurrences of \fI%u\fR
+will be replaced with the user name. The user name is checked for
+existence before calling the password changing program.
+
+Also note that many passwd programs insist in \fBreasonable
+\fRpasswords, such as a minimum length, or the inclusion
+of mixed case chars and digits. This can pose a problem as some clients
+(such as Windows for Workgroups) uppercase the password before sending
+it.
+
+\fBNote\fR that if the \fIunix
+password sync\fR parameter is set to yes
+then this program is called \fBAS ROOT\fR
+before the SMB password in the smbpasswd(5)
+ file is changed. If this UNIX password change fails, then
+\fBsmbd\fR will fail to change the SMB password also
+(this is by design).
+
+If the \fIunix password sync\fR parameter
+is set this parameter \fBMUST USE ABSOLUTE PATHS\fR
+for \fBALL\fR programs called, and must be examined
+for security implications. Note that by default \fIunix
+password sync\fR is set to no.
+
+See also \fIunix
+password sync\fR.
+
+Default: \fBpasswd program = /bin/passwd\fR
+
+Example: \fBpasswd program = /sbin/npasswd %u\fR
+.TP
+\fBpassword level (G)\fR
+Some client/server combinations have difficulty
+with mixed-case passwords. One offending client is Windows for
+Workgroups, which for some reason forces passwords to upper
+case when using the LANMAN1 protocol, but leaves them alone when
+using COREPLUS! Another problem child is the Windows 95/98
+family of operating systems. These clients upper case clear
+text passwords even when NT LM 0.12 selected by the protocol
+negotiation request/response.
+
+This parameter defines the maximum number of characters
+that may be upper case in passwords.
+
+For example, say the password given was "FRED". If \fI password level\fR is set to 1, the following combinations
+would be tried if "FRED" failed:
+
+"Fred", "fred", "fRed", "frEd","freD"
+
+If \fIpassword level\fR was set to 2,
+the following combinations would also be tried:
+
+"FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ..
+
+And so on.
+
+The higher value this parameter is set to the more likely
+it is that a mixed case password will be matched against a single
+case password. However, you should be aware that use of this
+parameter reduces security and increases the time taken to
+process a new connection.
+
+A value of zero will cause only two attempts to be
+made - the password as is and the password in all-lower case.
+
+Default: \fBpassword level = 0\fR
+
+Example: \fBpassword level = 4\fR
+.TP
+\fBpassword server (G)\fR
+By specifying the name of another SMB server (such
+as a WinNT box) with this option, and using \fBsecurity = domain
+\fRor \fBsecurity = server\fR you can get Samba
+to do all its username/password validation via a remote server.
+
+This option sets the name of the password server to use.
+It must be a NetBIOS name, so if the machine's NetBIOS name is
+different from its Internet name then you may have to add its NetBIOS
+name to the lmhosts file which is stored in the same directory
+as the \fIsmb.conf\fR file.
+
+The name of the password server is looked up using the
+parameter \fIname
+resolve order\fR and so may resolved
+by any method and order described in that parameter.
+
+The password server much be a machine capable of using
+the "LM1.2X002" or the "NT LM 0.12" protocol, and it must be in
+user level security mode.
+
+\fBNOTE:\fR Using a password server
+means your UNIX box (running Samba) is only as secure as your
+password server. \fBDO NOT CHOOSE A PASSWORD SERVER THAT
+YOU DON'T COMPLETELY TRUST\fR.
+
+Never point a Samba server at itself for password
+serving. This will cause a loop and could lock up your Samba
+server!
+
+The name of the password server takes the standard
+substitutions, but probably the only useful one is \fI%m
+\fR, which means the Samba server will use the incoming
+client as the password server. If you use this then you better
+trust your clients, and you had better restrict them with hosts allow!
+
+If the \fIsecurity\fR parameter is set to
+domain, then the list of machines in this
+option must be a list of Primary or Backup Domain controllers for the
+Domain or the character '*', as the Samba server is effectively
+in that domain, and will use cryptographically authenticated RPC calls
+to authenticate the user logging on. The advantage of using \fB security = domain\fR is that if you list several hosts in the
+\fIpassword server\fR option then \fBsmbd
+\fRwill try each in turn till it finds one that responds. This
+is useful in case your primary server goes down.
+
+If the \fIpassword server\fR option is set
+to the character '*', then Samba will attempt to auto-locate the
+Primary or Backup Domain controllers to authenticate against by
+doing a query for the name WORKGROUP<1C>
+and then contacting each server returned in the list of IP
+addresses from the name resolution source.
+
+If the \fIsecurity\fR parameter is
+set to server, then there are different
+restrictions that \fBsecurity = domain\fR doesn't
+suffer from:
+.RS
+.TP 0.2i
+\(bu
+You may list several password servers in
+the \fIpassword server\fR parameter, however if an
+\fBsmbd\fR makes a connection to a password server,
+and then the password server fails, no more users will be able
+to be authenticated from this \fBsmbd\fR. This is a
+restriction of the SMB/CIFS protocol when in \fBsecurity = server
+\fRmode and cannot be fixed in Samba.
+.TP 0.2i
+\(bu
+If you are using a Windows NT server as your
+password server then you will have to ensure that your users
+are able to login from the Samba server, as when in \fB security = server\fR mode the network logon will appear to
+come from there rather than from the users workstation.
+.RE
+.PP
+See also the \fIsecurity
+\fRparameter.
+.PP
+.PP
+Default: \fBpassword server = <empty string>\fR
+.PP
+.PP
+Example: \fBpassword server = NT-PDC, NT-BDC1, NT-BDC2
+\fR.PP
+.PP
+Example: \fBpassword server = *\fR
+.PP
+.TP
+\fBpath (S)\fR
+This parameter specifies a directory to which
+the user of the service is to be given access. In the case of
+printable services, this is where print data will spool prior to
+being submitted to the host for printing.
+
+For a printable service offering guest access, the service
+should be readonly and the path should be world-writeable and
+have the sticky bit set. This is not mandatory of course, but
+you probably won't get the results you expect if you do
+otherwise.
+
+Any occurrences of \fI%u\fR in the path
+will be replaced with the UNIX username that the client is using
+on this connection. Any occurrences of \fI%m\fR
+will be replaced by the NetBIOS name of the machine they are
+connecting from. These replacements are very useful for setting
+up pseudo home directories for users.
+
+Note that this path will be based on \fIroot dir\fR if one was specified.
+
+Default: \fBnone\fR
+
+Example: \fBpath = /home/fred\fR
+.TP
+\fBpid directory (G)\fR
+This option specifies the directory where pid
+files will be placed.
+
+Default: \fBpid directory = ${prefix}/var/locks\fR
+
+Example: \fBpid directory = /var/run/\fR
+.TP
+\fBposix locking (S)\fR
+The \fBsmbd(8)\fR
+daemon maintains an database of file locks obtained by SMB clients.
+The default behavior is to map this internal database to POSIX
+locks. This means that file locks obtained by SMB clients are
+consistent with those seen by POSIX compliant applications accessing
+the files via a non-SMB method (e.g. NFS or local file access).
+You should never need to disable this parameter.
+
+Default: \fBposix locking = yes\fR
+.TP
+\fBpostexec (S)\fR
+This option specifies a command to be run
+whenever the service is disconnected. It takes the usual
+substitutions. The command may be run as the root on some
+systems.
+
+An interesting example may be to unmount server
+resources:
+
+\fBpostexec = /etc/umount /cdrom\fR
+
+See also \fIpreexec\fR
+\&.
+
+Default: \fBnone (no command executed)\fR
+
+Example: \fBpostexec = echo \\"%u disconnected from %S
+from %m (%I)\\" >> /tmp/log\fR
+.TP
+\fBpostscript (S)\fR
+This parameter forces a printer to interpret
+the print files as PostScript. This is done by adding a %!
+to the start of print output.
+
+This is most useful when you have lots of PCs that persist
+in putting a control-D at the start of print jobs, which then
+confuses your printer.
+
+Default: \fBpostscript = no\fR
+.TP
+\fBpreexec (S)\fR
+This option specifies a command to be run whenever
+the service is connected to. It takes the usual substitutions.
+
+An interesting example is to send the users a welcome
+message every time they log in. Maybe a message of the day? Here
+is an example:
+
+\fBpreexec = csh -c 'echo \\"Welcome to %S!\\" |
+/usr/local/samba/bin/smbclient -M %m -I %I' & \fR
+
+Of course, this could get annoying after a while :-)
+
+See also \fIpreexec close
+\fRand \fIpostexec
+\fR\&.
+
+Default: \fBnone (no command executed)\fR
+
+Example: \fBpreexec = echo \\"%u connected to %S from %m
+(%I)\\" >> /tmp/log\fR
+.TP
+\fBpreexec close (S)\fR
+This boolean option controls whether a non-zero
+return code from \fIpreexec
+\fRshould close the service being connected to.
+
+Default: \fBpreexec close = no\fR
+.TP
+\fBpreferred master (G)\fR
+This boolean parameter controls if nmbd(8) is a preferred master browser
+for its workgroup.
+
+If this is set to yes, on startup, \fBnmbd\fR
+will force an election, and it will have a slight advantage in
+winning the election. It is recommended that this parameter is
+used in conjunction with \fB\fI domain master\fB = yes\fR, so that \fB nmbd\fR can guarantee becoming a domain master.
+
+Use this option with caution, because if there are several
+hosts (whether Samba servers, Windows 95 or NT) that are preferred
+master browsers on the same subnet, they will each periodically
+and continuously attempt to become the local master browser.
+This will result in unnecessary broadcast traffic and reduced browsing
+capabilities.
+
+See also \fIos level\fR
+\&.
+
+Default: \fBpreferred master = auto\fR
+.TP
+\fBprefered master (G)\fR
+Synonym for \fI preferred master\fR for people who cannot spell :-).
+.TP
+\fBpreload\fR
+This is a list of services that you want to be
+automatically added to the browse lists. This is most useful
+for homes and printers services that would otherwise not be
+visible.
+
+Note that if you just want all printers in your
+printcap file loaded then the \fIload printers\fR option is easier.
+
+Default: \fBno preloaded services\fR
+
+Example: \fBpreload = fred lp colorlp\fR
+.TP
+\fBpreserve case (S)\fR
+This controls if new filenames are created
+with the case that the client passes, or if they are forced to
+be the \fIdefault case
+\fR\&.
+
+Default: \fBpreserve case = yes\fR
+
+See the section on NAME
+MANGLING for a fuller discussion.
+.TP
+\fBprint command (S)\fR
+After a print job has finished spooling to
+a service, this command will be used via a \fBsystem()\fR
+call to process the spool file. Typically the command specified will
+submit the spool file to the host's printing subsystem, but there
+is no requirement that this be the case. The server will not remove
+the spool file, so whatever command you specify should remove the
+spool file when it has been processed, otherwise you will need to
+manually remove old spool files.
+
+The print command is simply a text string. It will be used
+verbatim after macro substitutions have been made:
+
+s, %p - the path to the spool
+file name
+
+%p - the appropriate printer
+name
+
+%J - the job
+name as transmitted by the client.
+
+%c - The number of printed pages
+of the spooled job (if known).
+
+%z - the size of the spooled
+print job (in bytes)
+
+The print command \fBMUST\fR contain at least
+one occurrence of \fI%s\fR or \fI%f
+\fR- the \fI%p\fR is optional. At the time
+a job is submitted, if no printer name is supplied the \fI%p
+\fRwill be silently removed from the printer command.
+
+If specified in the [global] section, the print command given
+will be used for any printable service that does not have its own
+print command specified.
+
+If there is neither a specified print command for a
+printable service nor a global print command, spool files will
+be created but not processed and (most importantly) not removed.
+
+Note that printing may fail on some UNIXes from the
+nobody account. If this happens then create
+an alternative guest account that can print and set the \fIguest account\fR
+in the [global] section.
+
+You can form quite complex print commands by realizing
+that they are just passed to a shell. For example the following
+will log a print job, print the file, then remove it. Note that
+\&';' is the usual separator for command in shell scripts.
+
+\fBprint command = echo Printing %s >>
+/tmp/print.log; lpr -P %p %s; rm %s\fR
+
+You may have to vary this command considerably depending
+on how you normally print files on your system. The default for
+the parameter varies depending on the setting of the \fIprinting\fR parameter.
+
+Default: For \fBprinting = BSD, AIX, QNX, LPRNG
+or PLP :\fR
+
+\fBprint command = lpr -r -P%p %s\fR
+
+For \fBprinting = SYSV or HPUX :\fR
+
+\fBprint command = lp -c -d%p %s; rm %s\fR
+
+For \fBprinting = SOFTQ :\fR
+
+\fBprint command = lp -d%p -s %s; rm %s\fR
+
+For printing = CUPS : If SAMBA is compiled against
+libcups, then printcap = cups
+uses the CUPS API to
+submit jobs, etc. Otherwise it maps to the System V
+commands with the -oraw option for printing, i.e. it
+uses \fBlp -c -d%p -oraw; rm %s\fR.
+With \fBprinting = cups\fR,
+and if SAMBA is compiled against libcups, any manually
+set print command will be ignored.
+
+Example: \fBprint command = /usr/local/samba/bin/myprintscript
+%p %s\fR
+.TP
+\fBprint ok (S)\fR
+Synonym for \fIprintable\fR.
+.TP
+\fBprintable (S)\fR
+If this parameter is yes, then
+clients may open, write to and submit spool files on the directory
+specified for the service.
+
+Note that a printable service will ALWAYS allow writing
+to the service path (user privileges permitting) via the spooling
+of print data. The \fIread only
+\fRparameter controls only non-printing access to
+the resource.
+
+Default: \fBprintable = no\fR
+.TP
+\fBprintcap (G)\fR
+Synonym for \fI printcap name\fR.
+.TP
+\fBprintcap name (G)\fR
+This parameter may be used to override the
+compiled-in default printcap name used by the server (usually \fI /etc/printcap\fR). See the discussion of the [printers] section above for reasons
+why you might want to do this.
+
+To use the CUPS printing interface set \fBprintcap name = cups
+\fR\&. This should be supplemented by an addtional setting
+printing = cups in the [global]
+section. \fBprintcap name = cups\fR will use the
+"dummy" printcap created by CUPS, as specified in your CUPS
+configuration file.
+
+On System V systems that use \fBlpstat\fR to
+list available printers you can use \fBprintcap name = lpstat
+\fRto automatically obtain lists of available printers. This
+is the default for systems that define SYSV at configure time in
+Samba (this includes most System V based systems). If \fI printcap name\fR is set to \fBlpstat\fR on
+these systems then Samba will launch \fBlpstat -v\fR and
+attempt to parse the output to obtain a printer list.
+
+A minimal printcap file would look something like this:
+
+.sp
+.nf
+ print1|My Printer 1
+ print2|My Printer 2
+ print3|My Printer 3
+ print4|My Printer 4
+ print5|My Printer 5
+
+.sp
+.fi
+
+where the '|' separates aliases of a printer. The fact
+that the second alias has a space in it gives a hint to Samba
+that it's a comment.
+
+\fBNOTE\fR: Under AIX the default printcap
+name is \fI/etc/qconfig\fR. Samba will assume the
+file is in AIX \fIqconfig\fR format if the string
+\fIqconfig\fR appears in the printcap filename.
+
+Default: \fBprintcap name = /etc/printcap\fR
+
+Example: \fBprintcap name = /etc/myprintcap\fR
+.TP
+\fBprinter admin (S)\fR
+This is a list of users that can do anything to
+printers via the remote administration interfaces offered by MS-RPC
+(usually using a NT workstation). Note that the root user always
+has admin rights.
+
+Default: \fBprinter admin = <empty string>\fR
+
+Example: \fBprinter admin = admin, @staff\fR
+.TP
+\fBprinter driver (S)\fR
+\fBNote :\fRThis is a deprecated
+parameter and will be removed in the next major release
+following version 2.2. Please see the instructions in
+the Samba 2.2. Printing
+HOWTO for more information
+on the new method of loading printer drivers onto a Samba server.
+
+This option allows you to control the string
+that clients receive when they ask the server for the printer driver
+associated with a printer. If you are using Windows95 or Windows NT
+then you can use this to automate the setup of printers on your
+system.
+
+You need to set this parameter to the exact string (case
+sensitive) that describes the appropriate printer driver for your
+system. If you don't know the exact string to use then you should
+first try with no \fI printer driver\fR option set and the client will
+give you a list of printer drivers. The appropriate strings are
+shown in a scroll box after you have chosen the printer manufacturer.
+
+See also \fIprinter
+driver file\fR.
+
+Example: \fBprinter driver = HP LaserJet 4L\fR
+.TP
+\fBprinter driver file (G)\fR
+\fBNote :\fRThis is a deprecated
+parameter and will be removed in the next major release
+following version 2.2. Please see the instructions in
+the Samba 2.2. Printing
+HOWTO for more information
+on the new method of loading printer drivers onto a Samba server.
+
+This parameter tells Samba where the printer driver
+definition file, used when serving drivers to Windows 95 clients, is
+to be found. If this is not set, the default is :
+
+\fISAMBA_INSTALL_DIRECTORY
+/lib/printers.def\fR
+
+This file is created from Windows 95 \fImsprint.inf
+\fRfiles found on the Windows 95 client system. For more
+details on setting up serving of printer drivers to Windows 95
+clients, see the outdated documentation file in the \fIdocs/\fR
+directory, \fIPRINTER_DRIVER.txt\fR.
+
+See also \fI printer driver location\fR.
+
+Default: \fBNone (set in compile).\fR
+
+Example: \fBprinter driver file =
+/usr/local/samba/printers/drivers.def\fR
+.TP
+\fBprinter driver location (S)\fR
+\fBNote :\fRThis is a deprecated
+parameter and will be removed in the next major release
+following version 2.2. Please see the instructions in
+the Samba 2.2. Printing
+HOWTO for more information
+on the new method of loading printer drivers onto a Samba server.
+
+This parameter tells clients of a particular printer
+share where to find the printer driver files for the automatic
+installation of drivers for Windows 95 machines. If Samba is set up
+to serve printer drivers to Windows 95 machines, this should be set to
+
+\fB\\\\MACHINE\\PRINTER$\fR
+
+Where MACHINE is the NetBIOS name of your Samba server,
+and PRINTER$ is a share you set up for serving printer driver
+files. For more details on setting this up see the outdated documentation
+file in the \fIdocs/\fR directory, \fI PRINTER_DRIVER.txt\fR.
+
+See also \fI printer driver file\fR.
+
+Default: \fBnone\fR
+
+Example: \fBprinter driver location = \\\\MACHINE\\PRINTER$
+\fR.TP
+\fBprinter name (S)\fR
+This parameter specifies the name of the printer
+to which print jobs spooled through a printable service will be sent.
+
+If specified in the [global] section, the printer
+name given will be used for any printable service that does
+not have its own printer name specified.
+
+Default: \fBnone (but may be lp
+on many systems)\fR
+
+Example: \fBprinter name = laserwriter\fR
+.TP
+\fBprinter (S)\fR
+Synonym for \fI printer name\fR.
+.TP
+\fBprinting (S)\fR
+This parameters controls how printer status
+information is interpreted on your system. It also affects the
+default values for the \fIprint command\fR,
+\fIlpq command\fR, \fIlppause command
+\fR, \fIlpresume command\fR, and
+\fIlprm command\fR if specified in the
+[global] section.
+
+Currently nine printing styles are supported. They are
+BSD, AIX,
+LPRNG, PLP,
+SYSV, HPUX,
+QNX, SOFTQ,
+and CUPS.
+
+To see what the defaults are for the other print
+commands when using the various options use the testparm(1) program.
+
+This option can be set on a per printer basis
+
+See also the discussion in the [printers] section.
+.TP
+\fBprofile acls (S)\fR
+This boolean parameter was added to fix the problems that people have been
+having with storing user profiles on Samba shares from Windows 2000 or
+Windows XP clients. New versions of Windows 2000 or Windows XP service
+packs do security ACL checking on the owner and ability to write of the
+profile directory stored on a local workstation when copied from a Samba
+share. When not in domain mode with winbindd then the security info copied
+onto the local workstation has no meaning to the logged in user (SID) on
+that workstation so the profile storing fails. Adding this parameter
+onto a share used for profile storage changes two things about the
+returned Windows ACL. Firstly it changes the owner and group owner
+of all reported files and directories to be BUILTIN\\Administrators,
+BUILTIN\\Users respectively (SIDs S-1-5-32-544, S-1-5-32-545). Secondly
+it adds an ACE entry of "Full Control" to the SID BUILTIN\\Users to
+every returned ACL. This will allow any Windows 2000 or XP workstation
+user to access the profile. Note that if you have multiple users logging
+on to a workstation then in order to prevent them from being able to access
+each others profiles you must remove the "Bypass traverse checking" advanced
+user right. This will prevent access to other users profile directories as
+the top level profile directory (named after the user) is created by the
+workstation profile code and has an ACL restricting entry to the directory
+tree to the owning user.
+
+If you didn't understand the above text, you probably should not set
+this parameter :-).
+
+Default \fBprofile acls = no\fR
+.TP
+\fBprotocol (G)\fR
+Synonym for \fImax protocol\fR.
+.TP
+\fBpublic (S)\fR
+Synonym for \fIguest
+ok\fR.
+.TP
+\fBqueuepause command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to pause the printer queue.
+
+This command should be a program or script which takes
+a printer name as its only parameter and stops the printer queue,
+such that no longer jobs are submitted to the printer.
+
+This command is not supported by Windows for Workgroups,
+but can be issued from the Printers window under Windows 95
+and NT.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. Otherwise it is placed at the end of the command.
+
+Note that it is good practice to include the absolute
+path in the command as the PATH may not be available to the
+server.
+
+Default: \fBdepends on the setting of \fIprinting
+\fB\fR
+Example: \fBqueuepause command = disable %p\fR
+.TP
+\fBqueueresume command (S)\fR
+This parameter specifies the command to be
+executed on the server host in order to resume the printer queue. It
+is the command to undo the behavior that is caused by the
+previous parameter (\fI queuepause command\fR).
+
+This command should be a program or script which takes
+a printer name as its only parameter and resumes the printer queue,
+such that queued jobs are resubmitted to the printer.
+
+This command is not supported by Windows for Workgroups,
+but can be issued from the Printers window under Windows 95
+and NT.
+
+If a \fI%p\fR is given then the printer name
+is put in its place. Otherwise it is placed at the end of the
+command.
+
+Note that it is good practice to include the absolute
+path in the command as the PATH may not be available to the
+server.
+
+Default: \fBdepends on the setting of \fIprinting\fB\fR
+
+Example: \fBqueuepause command = enable %p
+\fR.TP
+\fBread bmpx (G)\fR
+This boolean parameter controls whether smbd(8) will support the "Read
+Block Multiplex" SMB. This is now rarely used and defaults to
+no. You should never need to set this
+parameter.
+
+Default: \fBread bmpx = no\fR
+.TP
+\fBread list (S)\fR
+This is a list of users that are given read-only
+access to a service. If the connecting user is in this list then
+they will not be given write access, no matter what the \fIread only\fR
+option is set to. The list can include group names using the
+syntax described in the \fI invalid users\fR parameter.
+
+See also the \fI write list\fR parameter and the \fIinvalid users\fR
+parameter.
+
+Default: \fBread list = <empty string>\fR
+
+Example: \fBread list = mary, @students\fR
+.TP
+\fBread only (S)\fR
+An inverted synonym is \fIwriteable\fR.
+
+If this parameter is yes, then users
+of a service may not create or modify files in the service's
+directory.
+
+Note that a printable service (\fBprintable = yes\fR)
+will \fBALWAYS\fR allow writing to the directory
+(user privileges permitting), but only via spooling operations.
+
+Default: \fBread only = yes\fR
+.TP
+\fBread raw (G)\fR
+This parameter controls whether or not the server
+will support the raw read SMB requests when transferring data
+to clients.
+
+If enabled, raw reads allow reads of 65535 bytes in
+one packet. This typically provides a major performance benefit.
+
+However, some clients either negotiate the allowable
+block size incorrectly or are incapable of supporting larger block
+sizes, and for these clients you may need to disable raw reads.
+
+In general this parameter should be viewed as a system tuning
+tool and left severely alone. See also \fIwrite raw\fR.
+
+Default: \fBread raw = yes\fR
+.TP
+\fBread size (G)\fR
+The option \fIread size\fR
+affects the overlap of disk reads/writes with network reads/writes.
+If the amount of data being transferred in several of the SMB
+commands (currently SMBwrite, SMBwriteX and SMBreadbraw) is larger
+than this value then the server begins writing the data before it
+has received the whole packet from the network, or in the case of
+SMBreadbraw, it begins writing to the network before all the data
+has been read from disk.
+
+This overlapping works best when the speeds of disk and
+network access are similar, having very little effect when the
+speed of one is much greater than the other.
+
+The default value is 16384, but very little experimentation
+has been done yet to determine the optimal value, and it is likely
+that the best value will vary greatly between systems anyway.
+A value over 65536 is pointless and will cause you to allocate
+memory unnecessarily.
+
+Default: \fBread size = 16384\fR
+
+Example: \fBread size = 8192\fR
+.TP
+\fBremote announce (G)\fR
+This option allows you to setup nmbd(8) to periodically announce itself
+to arbitrary IP addresses with an arbitrary workgroup name.
+
+This is useful if you want your Samba server to appear
+in a remote workgroup for which the normal browse propagation
+rules don't work. The remote workgroup can be anywhere that you
+can send IP packets to.
+
+For example:
+
+\fBremote announce = 192.168.2.255/SERVERS
+192.168.4.255/STAFF\fR
+
+the above line would cause \fBnmbd\fR to announce itself
+to the two given IP addresses using the given workgroup names.
+If you leave out the workgroup name then the one given in
+the \fIworkgroup\fR
+parameter is used instead.
+
+The IP addresses you choose would normally be the broadcast
+addresses of the remote networks, but can also be the IP addresses
+of known browse masters if your network config is that stable.
+
+See the documentation file \fIBROWSING.txt\fR
+in the \fIdocs/\fR directory.
+
+Default: \fBremote announce = <empty string>
+\fR.TP
+\fBremote browse sync (G)\fR
+This option allows you to setup nmbd(8) to periodically request
+synchronization of browse lists with the master browser of a Samba
+server that is on a remote segment. This option will allow you to
+gain browse lists for multiple workgroups across routed networks. This
+is done in a manner that does not work with any non-Samba servers.
+
+This is useful if you want your Samba server and all local
+clients to appear in a remote workgroup for which the normal browse
+propagation rules don't work. The remote workgroup can be anywhere
+that you can send IP packets to.
+
+For example:
+
+\fBremote browse sync = 192.168.2.255 192.168.4.255
+\fR
+the above line would cause \fBnmbd\fR to request
+the master browser on the specified subnets or addresses to
+synchronize their browse lists with the local server.
+
+The IP addresses you choose would normally be the broadcast
+addresses of the remote networks, but can also be the IP addresses
+of known browse masters if your network config is that stable. If
+a machine IP address is given Samba makes NO attempt to validate
+that the remote machine is available, is listening, nor that it
+is in fact the browse master on its segment.
+
+Default: \fBremote browse sync = <empty string>
+\fR.TP
+\fBrestrict anonymous (G)\fR
+This is a boolean parameter. If it is yes, then
+anonymous access to the server will be restricted, namely in the
+case where the server is expecting the client to send a username,
+but it doesn't. Setting it to yes will force these anonymous
+connections to be denied, and the client will be required to always
+supply a username and password when connecting. Use of this parameter
+is only recommended for homogeneous NT client environments.
+
+This parameter makes the use of macro expansions that rely
+on the username (%U, %G, etc) consistent. NT 4.0
+likes to use anonymous connections when refreshing the share list,
+and this is a way to work around that.
+
+When restrict anonymous is yes, all anonymous connections
+are denied no matter what they are for. This can effect the ability
+of a machine to access the Samba Primary Domain Controller to revalidate
+its machine account after someone else has logged on the client
+interactively. The NT client will display a message saying that
+the machine's account in the domain doesn't exist or the password is
+bad. The best way to deal with this is to reboot NT client machines
+between interactive logons, using "Shutdown and Restart", rather
+than "Close all programs and logon as a different user".
+
+Default: \fBrestrict anonymous = no\fR
+.TP
+\fBroot (G)\fR
+Synonym for \fIroot directory"\fR.
+.TP
+\fBroot dir (G)\fR
+Synonym for \fIroot directory"\fR.
+.TP
+\fBroot directory (G)\fR
+The server will \fBchroot()\fR (i.e.
+Change its root directory) to this directory on startup. This is
+not strictly necessary for secure operation. Even without it the
+server will deny access to files not in one of the service entries.
+It may also check for, and deny access to, soft links to other
+parts of the filesystem, or attempts to use ".." in file names
+to access other directories (depending on the setting of the \fIwide links\fR
+parameter).
+
+Adding a \fIroot directory\fR entry other
+than "/" adds an extra level of security, but at a price. It
+absolutely ensures that no access is given to files not in the
+sub-tree specified in the \fIroot directory\fR
+option, \fBincluding\fR some files needed for
+complete operation of the server. To maintain full operability
+of the server you will need to mirror some system files
+into the \fIroot directory\fR tree. In particular
+you will need to mirror \fI/etc/passwd\fR (or a
+subset of it), and any binaries or configuration files needed for
+printing (if required). The set of files that must be mirrored is
+operating system dependent.
+
+Default: \fBroot directory = /\fR
+
+Example: \fBroot directory = /homes/smb\fR
+.TP
+\fBroot postexec (S)\fR
+This is the same as the \fIpostexec\fR
+parameter except that the command is run as root. This
+is useful for unmounting filesystems
+(such as CDROMs) after a connection is closed.
+
+See also \fI postexec\fR.
+
+Default: \fBroot postexec = <empty string>
+\fR.TP
+\fBroot preexec (S)\fR
+This is the same as the \fIpreexec\fR
+parameter except that the command is run as root. This
+is useful for mounting filesystems (such as CDROMs) when a
+connection is opened.
+
+See also \fI preexec\fR and \fIpreexec close\fR.
+
+Default: \fBroot preexec = <empty string>
+\fR.TP
+\fBroot preexec close (S)\fR
+This is the same as the \fIpreexec close
+\fRparameter except that the command is run as root.
+
+See also \fI preexec\fR and \fIpreexec close\fR.
+
+Default: \fBroot preexec close = no\fR
+.TP
+\fBsecurity (G)\fR
+This option affects how clients respond to
+Samba and is one of the most important settings in the \fI smb.conf\fR file.
+
+The option sets the "security mode bit" in replies to
+protocol negotiations with smbd(8)
+ to turn share level security on or off. Clients decide
+based on this bit whether (and how) to transfer user and password
+information to the server.
+
+The default is \fBsecurity = user\fR, as this is
+the most common setting needed when talking to Windows 98 and
+Windows NT.
+
+The alternatives are \fBsecurity = share\fR,
+\fBsecurity = server\fR or \fBsecurity = domain
+\fR\&.
+
+In versions of Samba prior to 2.0.0, the default was
+\fBsecurity = share\fR mainly because that was
+the only option at one stage.
+
+There is a bug in WfWg that has relevance to this
+setting. When in user or server level security a WfWg client
+will totally ignore the password you type in the "connect
+drive" dialog box. This makes it very difficult (if not impossible)
+to connect to a Samba service as anyone except the user that
+you are logged into WfWg as.
+
+If your PCs use usernames that are the same as their
+usernames on the UNIX machine then you will want to use
+\fBsecurity = user\fR. If you mostly use usernames
+that don't exist on the UNIX box then use \fBsecurity =
+share\fR.
+
+You should also use \fBsecurity = share\fR if you
+want to mainly setup shares without a password (guest shares). This
+is commonly used for a shared printer server. It is more difficult
+to setup guest shares with \fBsecurity = user\fR, see
+the \fImap to guest\fR
+parameter for details.
+
+It is possible to use \fBsmbd\fR in a \fB hybrid mode\fR where it is offers both user and share
+level security under different \fINetBIOS aliases\fR.
+
+The different settings will now be explained.
+
+\fBSECURITY = SHARE
+\fR
+When clients connect to a share level security server they
+need not log onto the server with a valid username and password before
+attempting to connect to a shared resource (although modern clients
+such as Windows 95/98 and Windows NT will send a logon request with
+a username but no password when talking to a \fBsecurity = share
+\fRserver). Instead, the clients send authentication information
+(passwords) on a per-share basis, at the time they attempt to connect
+to that share.
+
+Note that \fBsmbd\fR \fBALWAYS\fR
+uses a valid UNIX user to act on behalf of the client, even in
+\fBsecurity = share\fR level security.
+
+As clients are not required to send a username to the server
+in share level security, \fBsmbd\fR uses several
+techniques to determine the correct UNIX user to use on behalf
+of the client.
+
+A list of possible UNIX usernames to match with the given
+client password is constructed using the following methods :
+.RS
+.TP 0.2i
+\(bu
+If the \fIguest
+only\fR parameter is set, then all the other
+stages are missed and only the \fIguest account\fR username is checked.
+.TP 0.2i
+\(bu
+Is a username is sent with the share connection
+request, then this username (after mapping - see \fIusername map\fR),
+is added as a potential username.
+.TP 0.2i
+\(bu
+If the client did a previous \fBlogon
+\fRrequest (the SessionSetup SMB call) then the
+username sent in this SMB will be added as a potential username.
+.TP 0.2i
+\(bu
+The name of the service the client requested is
+added as a potential username.
+.TP 0.2i
+\(bu
+The NetBIOS name of the client is added to
+the list as a potential username.
+.TP 0.2i
+\(bu
+Any users on the \fI user\fR list are added as potential usernames.
+.RE
+.PP
+If the \fIguest only\fR parameter is
+not set, then this list is then tried with the supplied password.
+The first user for whom the password matches will be used as the
+UNIX user.
+.PP
+.PP
+If the \fIguest only\fR parameter is
+set, or no username can be determined then if the share is marked
+as available to the \fIguest account\fR, then this
+guest user will be used, otherwise access is denied.
+.PP
+.PP
+Note that it can be \fBvery\fR confusing
+in share-level security as to which UNIX username will eventually
+be used in granting access.
+.PP
+.PP
+See also the section NOTE ABOUT USERNAME/PASSWORD VALIDATION.
+.PP
+.PP
+\fBSECURITY = USER
+\fR.PP
+.PP
+This is the default security setting in Samba 2.2.
+With user-level security a client must first "log-on" with a
+valid username and password (which can be mapped using the \fIusername map\fR
+parameter). Encrypted passwords (see the \fIencrypted passwords\fR parameter) can also
+be used in this security mode. Parameters such as \fIuser\fR and \fIguest only\fR if set are then applied and
+may change the UNIX user to use on this connection, but only after
+the user has been successfully authenticated.
+.PP
+.PP
+\fBNote\fR that the name of the resource being
+requested is \fBnot\fR sent to the server until after
+the server has successfully authenticated the client. This is why
+guest shares don't work in user level security without allowing
+the server to automatically map unknown users into the \fIguest account\fR.
+See the \fImap to guest\fR
+parameter for details on doing this.
+.PP
+.PP
+See also the section NOTE ABOUT USERNAME/PASSWORD VALIDATION.
+.PP
+.PP
+\fBSECURITY = SERVER
+\fR.PP
+.PP
+In this mode Samba will try to validate the username/password
+by passing it to another SMB server, such as an NT box. If this
+fails it will revert to \fBsecurity = user\fR, but note
+that if encrypted passwords have been negotiated then Samba cannot
+revert back to checking the UNIX password file, it must have a valid
+\fIsmbpasswd\fR file to check users against. See the
+documentation file in the \fIdocs/\fR directory
+\fIENCRYPTION.txt\fR for details on how to set this
+up.
+.PP
+.PP
+\fBNote\fR that from the client's point of
+view \fBsecurity = server\fR is the same as \fB security = user\fR. It only affects how the server deals
+with the authentication, it does not in any way affect what the
+client sees.
+.PP
+.PP
+\fBNote\fR that the name of the resource being
+requested is \fBnot\fR sent to the server until after
+the server has successfully authenticated the client. This is why
+guest shares don't work in user level security without allowing
+the server to automatically map unknown users into the \fIguest account\fR.
+See the \fImap to guest\fR
+parameter for details on doing this.
+.PP
+.PP
+See also the section NOTE ABOUT USERNAME/PASSWORD VALIDATION.
+.PP
+.PP
+See also the \fIpassword
+server\fR parameter and the \fIencrypted passwords\fR
+parameter.
+.PP
+.PP
+\fBSECURITY = DOMAIN
+\fR.PP
+.PP
+This mode will only work correctly if smbpasswd(8) has been used to add this
+machine into a Windows NT Domain. It expects the \fIencrypted passwords\fR
+parameter to be set to yes. In this
+mode Samba will try to validate the username/password by passing
+it to a Windows NT Primary or Backup Domain Controller, in exactly
+the same way that a Windows NT Server would do.
+.PP
+.PP
+\fBNote\fR that a valid UNIX user must still
+exist as well as the account on the Domain Controller to allow
+Samba to have a valid UNIX account to map file access to.
+.PP
+.PP
+\fBNote\fR that from the client's point
+of view \fBsecurity = domain\fR is the same as \fBsecurity = user
+\fR\&. It only affects how the server deals with the authentication,
+it does not in any way affect what the client sees.
+.PP
+.PP
+\fBNote\fR that the name of the resource being
+requested is \fBnot\fR sent to the server until after
+the server has successfully authenticated the client. This is why
+guest shares don't work in user level security without allowing
+the server to automatically map unknown users into the \fIguest account\fR.
+See the \fImap to guest\fR
+parameter for details on doing this.
+.PP
+.PP
+\fBBUG:\fR There is currently a bug in the
+implementation of \fBsecurity = domain\fR with respect
+to multi-byte character set usernames. The communication with a
+Domain Controller must be done in UNICODE and Samba currently
+does not widen multi-byte user names to UNICODE correctly, thus
+a multi-byte username will not be recognized correctly at the
+Domain Controller. This issue will be addressed in a future release.
+.PP
+.PP
+See also the section NOTE ABOUT USERNAME/PASSWORD VALIDATION.
+.PP
+.PP
+See also the \fIpassword
+server\fR parameter and the \fIencrypted passwords\fR
+parameter.
+.PP
+.PP
+Default: \fBsecurity = USER\fR
+.PP
+.PP
+Example: \fBsecurity = DOMAIN\fR
+.PP
+.TP
+\fBsecurity mask (S)\fR
+This parameter controls what UNIX permission
+bits can be modified when a Windows NT client is manipulating
+the UNIX permission on a file using the native NT security
+dialog box.
+
+This parameter is applied as a mask (AND'ed with) to
+the changed permission bits, thus preventing any bits not in
+this mask from being modified. Essentially, zero bits in this
+mask may be treated as a set of bits the user is not allowed
+to change.
+
+If not set explicitly this parameter is 0777, allowing
+a user to modify all the user/group/world permissions on a file.
+
+\fBNote\fR that users who can access the
+Samba server through other means can easily bypass this
+restriction, so it is primarily useful for standalone
+"appliance" systems. Administrators of most normal systems will
+probably want to leave it set to 0777.
+
+See also the \fIforce directory security mode\fR,
+\fIdirectory
+security mask\fR, \fIforce security mode\fR parameters.
+
+Default: \fBsecurity mask = 0777\fR
+
+Example: \fBsecurity mask = 0770\fR
+.TP
+\fBserver string (G)\fR
+This controls what string will show up in the
+printer comment box in print manager and next to the IPC connection
+in \fBnet view\fR. It can be any string that you wish
+to show to your users.
+
+It also sets what will appear in browse lists next
+to the machine name.
+
+A \fI%v\fR will be replaced with the Samba
+version number.
+
+A \fI%h\fR will be replaced with the
+hostname.
+
+Default: \fBserver string = Samba %v\fR
+
+Example: \fBserver string = University of GNUs Samba
+Server\fR
+.TP
+\fBset directory (S)\fR
+If \fBset directory = no\fR, then
+users of the service may not use the setdir command to change
+directory.
+
+The \fBsetdir\fR command is only implemented
+in the Digital Pathworks client. See the Pathworks documentation
+for details.
+
+Default: \fBset directory = no\fR
+.TP
+\fBshare modes (S)\fR
+This enables or disables the honoring of
+the \fIshare modes\fR during a file open. These
+modes are used by clients to gain exclusive read or write access
+to a file.
+
+These open modes are not directly supported by UNIX, so
+they are simulated using shared memory, or lock files if your
+UNIX doesn't support shared memory (almost all do).
+
+The share modes that are enabled by this option are
+DENY_DOS, DENY_ALL,
+DENY_READ, DENY_WRITE,
+DENY_NONE and DENY_FCB.
+
+This option gives full share compatibility and enabled
+by default.
+
+You should \fBNEVER\fR turn this parameter
+off as many Windows applications will break if you do so.
+
+Default: \fBshare modes = yes\fR
+.TP
+\fBshort preserve case (S)\fR
+This boolean parameter controls if new files
+which conform to 8.3 syntax, that is all in upper case and of
+suitable length, are created upper case, or if they are forced
+to be the \fIdefault case
+\fR\&. This option can be use with \fBpreserve case = yes\fR
+to permit long filenames to retain their case, while short
+names are lowered.
+
+See the section on NAME MANGLING.
+
+Default: \fBshort preserve case = yes\fR
+.TP
+\fBshow add printer wizard (G)\fR
+With the introduction of MS-RPC based printing support
+for Windows NT/2000 client in Samba 2.2, a "Printers..." folder will
+appear on Samba hosts in the share listing. Normally this folder will
+contain an icon for the MS Add Printer Wizard (APW). However, it is
+possible to disable this feature regardless of the level of privilege
+of the connected user.
+
+Under normal circumstances, the Windows NT/2000 client will
+open a handle on the printer server with OpenPrinterEx() asking for
+Administrator privileges. If the user does not have administrative
+access on the print server (i.e is not root or a member of the
+\fIprinter admin\fR group), the OpenPrinterEx()
+call fails and the client makes another open call with a request for
+a lower privilege level. This should succeed, however the APW
+icon will not be displayed.
+
+Disabling the \fIshow add printer wizard\fR
+parameter will always cause the OpenPrinterEx() on the server
+to fail. Thus the APW icon will never be displayed. \fB Note :\fRThis does not prevent the same user from having
+administrative privilege on an individual printer.
+
+See also \fIaddprinter
+command\fR, \fIdeleteprinter command\fR, \fIprinter admin\fR
+
+Default :\fBshow add printer wizard = yes\fR
+.TP
+\fBsmb passwd file (G)\fR
+This option sets the path to the encrypted
+smbpasswd file. By default the path to the smbpasswd file
+is compiled into Samba.
+
+Default: \fBsmb passwd file = ${prefix}/private/smbpasswd
+\fR
+Example: \fBsmb passwd file = /etc/samba/smbpasswd
+\fR.TP
+\fBsocket address (G)\fR
+This option allows you to control what
+address Samba will listen for connections on. This is used to
+support multiple virtual interfaces on the one server, each
+with a different configuration.
+
+By default Samba will accept connections on any
+address.
+
+Example: \fBsocket address = 192.168.2.20\fR
+.TP
+\fBsocket options (G)\fR
+This option allows you to set socket options
+to be used when talking with the client.
+
+Socket options are controls on the networking layer
+of the operating systems which allow the connection to be
+tuned.
+
+This option will typically be used to tune your Samba
+server for optimal performance for your local network. There is
+no way that Samba can know what the optimal parameters are for
+your net, so you must experiment and choose them yourself. We
+strongly suggest you read the appropriate documentation for your
+operating system first (perhaps \fBman setsockopt\fR
+will help).
+
+You may find that on some systems Samba will say
+"Unknown socket option" when you supply an option. This means you
+either incorrectly typed it or you need to add an include file
+to includes.h for your OS. If the latter is the case please
+send the patch to samba@samba.org <URL:mailto:samba@samba.org>.
+
+Any of the supported socket options may be combined
+in any way you like, as long as your OS allows it.
+
+This is the list of socket options currently settable
+using this option:
+.RS
+.TP 0.2i
+\(bu
+SO_KEEPALIVE
+.TP 0.2i
+\(bu
+SO_REUSEADDR
+.TP 0.2i
+\(bu
+SO_BROADCAST
+.TP 0.2i
+\(bu
+TCP_NODELAY
+.TP 0.2i
+\(bu
+IPTOS_LOWDELAY
+.TP 0.2i
+\(bu
+IPTOS_THROUGHPUT
+.TP 0.2i
+\(bu
+SO_SNDBUF *
+.TP 0.2i
+\(bu
+SO_RCVBUF *
+.TP 0.2i
+\(bu
+SO_SNDLOWAT *
+.TP 0.2i
+\(bu
+SO_RCVLOWAT *
+.RE
+.PP
+Those marked with a \fB'*'\fR take an integer
+argument. The others can optionally take a 1 or 0 argument to enable
+or disable the option, by default they will be enabled if you
+don't specify 1 or 0.
+.PP
+.PP
+To specify an argument use the syntax SOME_OPTION = VALUE
+for example \fBSO_SNDBUF = 8192\fR. Note that you must
+not have any spaces before or after the = sign.
+.PP
+.PP
+If you are on a local network then a sensible option
+might be
+.PP
+.PP
+\fBsocket options = IPTOS_LOWDELAY\fR
+.PP
+.PP
+If you have a local network then you could try:
+.PP
+.PP
+\fBsocket options = IPTOS_LOWDELAY TCP_NODELAY\fR
+.PP
+.PP
+If you are on a wide area network then perhaps try
+setting IPTOS_THROUGHPUT.
+.PP
+.PP
+Note that several of the options may cause your Samba
+server to fail completely. Use these options with caution!
+.PP
+.PP
+Default: \fBsocket options = TCP_NODELAY\fR
+.PP
+.PP
+Example: \fBsocket options = IPTOS_LOWDELAY\fR
+.PP
+.TP
+\fBsource environment (G)\fR
+This parameter causes Samba to set environment
+variables as per the content of the file named.
+
+If the value of this parameter starts with a "|" character
+then Samba will treat that value as a pipe command to open and
+will set the environment variables from the output of the pipe.
+
+The contents of the file or the output of the pipe should
+be formatted as the output of the standard Unix \fBenv(1)
+\fRcommand. This is of the form :
+
+Example environment entry:
+
+\fBSAMBA_NETBIOS_NAME = myhostname\fR
+
+Default: \fBNo default value\fR
+
+Examples: \fBsource environment = |/etc/smb.conf.sh
+\fR
+Example: \fBsource environment =
+/usr/local/smb_env_vars\fR
+.TP
+\fBssl (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This variable enables or disables the entire SSL mode. If
+it is set to no, the SSL-enabled Samba behaves
+exactly like the non-SSL Samba. If set to yes,
+it depends on the variables \fI ssl hosts\fR and \fIssl hosts resign\fR whether an SSL
+connection will be required.
+
+Default: \fBssl = no\fR
+.TP
+\fBssl CA certDir (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This variable defines where to look up the Certification
+Authorities. The given directory should contain one file for
+each CA that Samba will trust. The file name must be the hash
+value over the "Distinguished Name" of the CA. How this directory
+is set up is explained later in this document. All files within the
+directory that don't fit into this naming scheme are ignored. You
+don't need this variable if you don't verify client certificates.
+
+Default: \fBssl CA certDir = /usr/local/ssl/certs
+\fR.TP
+\fBssl CA certFile (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This variable is a second way to define the trusted CAs.
+The certificates of the trusted CAs are collected in one big
+file and this variable points to the file. You will probably
+only use one of the two ways to define your CAs. The first choice is
+preferable if you have many CAs or want to be flexible, the second
+is preferable if you only have one CA and want to keep things
+simple (you won't need to create the hashed file names). You
+don't need this variable if you don't verify client certificates.
+
+Default: \fBssl CA certFile = /usr/local/ssl/certs/trustedCAs.pem
+\fR.TP
+\fBssl ciphers (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This variable defines the ciphers that should be offered
+during SSL negotiation. You should not set this variable unless
+you know what you are doing.
+.TP
+\fBssl client cert (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+The certificate in this file is used by \fBsmbclient(1)\fR if it exists. It's needed
+if the server requires a client certificate.
+
+Default: \fBssl client cert = /usr/local/ssl/certs/smbclient.pem
+\fR.TP
+\fBssl client key (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This is the private key for \fBsmbclient(1)\fR It's only needed if the
+client should have a certificate.
+
+Default: \fBssl client key = /usr/local/ssl/private/smbclient.pem
+\fR.TP
+\fBssl compatibility (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This variable defines whether OpenSSL should be configured
+for bug compatibility with other SSL implementations. This is
+probably not desirable because currently no clients with SSL
+implementations other than OpenSSL exist.
+
+Default: \fBssl compatibility = no\fR
+.TP
+\fBssl egd socket (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This option is used to define the location of the communiation socket of
+an EGD or PRNGD daemon, from which entropy can be retrieved. This option
+can be used instead of or together with the \fIssl entropy file\fR
+directive. 255 bytes of entropy will be retrieved from the daemon.
+
+Default: \fBnone\fR
+.TP
+\fBssl entropy bytes (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This parameter is used to define the number of bytes which should
+be read from the \fIssl entropy
+file\fR If a -1 is specified, the entire file will
+be read.
+
+Default: \fBssl entropy bytes = 255\fR
+.TP
+\fBssl entropy file (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This parameter is used to specify a file from which processes will
+read "random bytes" on startup. In order to seed the internal pseudo
+random number generator, entropy must be provided. On system with a
+\fI/dev/urandom\fR device file, the processes
+will retrieve its entropy from the kernel. On systems without kernel
+entropy support, a file can be supplied that will be read on startup
+and that will be used to seed the PRNG.
+
+Default: \fBnone\fR
+.TP
+\fBssl hosts (G)\fR
+See \fI ssl hosts resign\fR.
+.TP
+\fBssl hosts resign (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+These two variables define whether Samba will go
+into SSL mode or not. If none of them is defined, Samba will
+allow only SSL connections. If the \fIssl hosts\fR variable lists
+hosts (by IP-address, IP-address range, net group or name),
+only these hosts will be forced into SSL mode. If the \fI ssl hosts resign\fR variable lists hosts, only these
+hosts will \fBNOT\fR be forced into SSL mode. The syntax for these two
+variables is the same as for the \fI hosts allow\fR and \fIhosts deny\fR pair of variables, only
+that the subject of the decision is different: It's not the access
+right but whether SSL is used or not.
+
+The example below requires SSL connections from all hosts
+outside the local net (which is 192.168.*.*).
+
+Default: \fBssl hosts = <empty string>\fR
+
+\fBssl hosts resign = <empty string>\fR
+
+Example: \fBssl hosts resign = 192.168.\fR
+.TP
+\fBssl require clientcert (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+If this variable is set to yes, the
+server will not tolerate connections from clients that don't
+have a valid certificate. The directory/file given in \fIssl CA certDir\fR
+and \fIssl CA certFile
+\fRwill be used to look up the CAs that issued
+the client's certificate. If the certificate can't be verified
+positively, the connection will be terminated. If this variable
+is set to no, clients don't need certificates.
+Contrary to web applications you really \fBshould\fR
+require client certificates. In the web environment the client's
+data is sensitive (credit card numbers) and the server must prove
+to be trustworthy. In a file server environment the server's data
+will be sensitive and the clients must prove to be trustworthy.
+
+Default: \fBssl require clientcert = no\fR
+.TP
+\fBssl require servercert (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+If this variable is set to yes, the
+\fBsmbclient(1)\fR
+ will request a certificate from the server. Same as
+\fIssl require
+clientcert\fR for the server.
+
+Default: \fBssl require servercert = no\fR
+.TP
+\fBssl server cert (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This is the file containing the server's certificate.
+The server \fBmust\fR have a certificate. The
+file may also contain the server's private key. See later for
+how certificates and private keys are created.
+
+Default: \fBssl server cert = <empty string>
+\fR.TP
+\fBssl server key (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This file contains the private key of the server. If
+this variable is not defined, the key is looked up in the
+certificate file (it may be appended to the certificate).
+The server \fBmust\fR have a private key
+and the certificate \fBmust\fR
+match this private key.
+
+Default: \fBssl server key = <empty string>
+\fR.TP
+\fBssl version (G)\fR
+This variable is part of SSL-enabled Samba. This
+is only available if the SSL libraries have been compiled on your
+system and the configure option \fB--with-ssl\fR was
+given at configure time.
+
+This enumeration variable defines the versions of the
+SSL protocol that will be used. ssl2or3 allows
+dynamic negotiation of SSL v2 or v3, ssl2 results
+in SSL v2, ssl3 results in SSL v3 and
+tls1 results in TLS v1. TLS (Transport Layer
+Security) is the new standard for SSL.
+
+Default: \fBssl version = "ssl2or3"\fR
+.TP
+\fBstat cache (G)\fR
+This parameter determines if smbd(8) will use a cache in order to
+speed up case insensitive name mappings. You should never need
+to change this parameter.
+
+Default: \fBstat cache = yes\fR
+.TP
+\fBstat cache size (G)\fR
+This parameter determines the number of
+entries in the \fIstat cache\fR. You should
+never need to change this parameter.
+
+Default: \fBstat cache size = 50\fR
+.TP
+\fBstatus (G)\fR
+This enables or disables logging of connections
+to a status file that smbstatus(1)
+can read.
+
+With this disabled \fBsmbstatus\fR won't be able
+to tell you what connections are active. You should never need to
+change this parameter.
+
+Default: \fBstatus = yes\fR
+.TP
+\fBstrict allocate (S)\fR
+This is a boolean that controls the handling of
+disk space allocation in the server. When this is set to yes
+the server will change from UNIX behaviour of not committing real
+disk storage blocks when a file is extended to the Windows behaviour
+of actually forcing the disk system to allocate real storage blocks
+when a file is created or extended to be a given size. In UNIX
+terminology this means that Samba will stop creating sparse files.
+This can be slow on some systems.
+
+When strict allocate is no the server does sparse
+disk block allocation when a file is extended.
+
+Setting this to yes can help Samba return
+out of quota messages on systems that are restricting the disk quota
+of users.
+
+Default: \fBstrict allocate = no\fR
+.TP
+\fBstrict locking (S)\fR
+This is a boolean that controls the handling of
+file locking in the server. When this is set to yes
+the server will check every read and write access for file locks, and
+deny access if locks exist. This can be slow on some systems.
+
+When strict locking is no the server does file
+lock checks only when the client explicitly asks for them.
+
+Well-behaved clients always ask for lock checks when it
+is important, so in the vast majority of cases \fBstrict
+locking = no\fR is preferable.
+
+Default: \fBstrict locking = no\fR
+.TP
+\fBstrict sync (S)\fR
+Many Windows applications (including the Windows
+98 explorer shell) seem to confuse flushing buffer contents to
+disk with doing a sync to disk. Under UNIX, a sync call forces
+the process to be suspended until the kernel has ensured that
+all outstanding data in kernel disk buffers has been safely stored
+onto stable storage. This is very slow and should only be done
+rarely. Setting this parameter to no (the
+default) means that smbd ignores the Windows applications requests for
+a sync call. There is only a possibility of losing data if the
+operating system itself that Samba is running on crashes, so there is
+little danger in this default setting. In addition, this fixes many
+performance problems that people have reported with the new Windows98
+explorer shell file copies.
+
+See also the \fIsync
+always>\fR parameter.
+
+Default: \fBstrict sync = no\fR
+.TP
+\fBstrip dot (G)\fR
+This parameter is now unused in Samba (2.2.5 and above).
+It used strip trailing dots off UNIX filenames but was not correctly implmented.
+In Samba 2.2.5 and above UNIX filenames ending in a dot are invalid Windows long
+filenames (as they are in Windows NT and above) and are mangled to 8.3 before
+being returned to a client.
+
+Default: \fBstrip dot = no\fR
+.TP
+\fBsync always (S)\fR
+This is a boolean parameter that controls
+whether writes will always be written to stable storage before
+the write call returns. If this is no then the server will be
+guided by the client's request in each write call (clients can
+set a bit indicating that a particular write should be synchronous).
+If this is yes then every write will be followed by a \fBfsync()
+\fRcall to ensure the data is written to disk. Note that
+the \fIstrict sync\fR parameter must be set to
+yes in order for this parameter to have
+any affect.
+
+See also the \fIstrict
+sync\fR parameter.
+
+Default: \fBsync always = no\fR
+.TP
+\fBsyslog (G)\fR
+This parameter maps how Samba debug messages
+are logged onto the system syslog logging levels. Samba debug
+level zero maps onto syslog LOG_ERR, debug
+level one maps onto LOG_WARNING, debug level
+two maps onto LOG_NOTICE, debug level three
+maps onto LOG_INFO. All higher levels are mapped to LOG_DEBUG.
+
+This parameter sets the threshold for sending messages
+to syslog. Only messages with debug level less than this value
+will be sent to syslog.
+
+Default: \fBsyslog = 1\fR
+.TP
+\fBsyslog only (G)\fR
+If this parameter is set then Samba debug
+messages are logged into the system syslog only, and not to
+the debug log files.
+
+Default: \fBsyslog only = no\fR
+.TP
+\fBtemplate homedir (G)\fR
+When filling out the user information for a Windows NT
+user, the winbindd(8) daemon
+uses this parameter to fill in the home directory for that user.
+If the string \fI%D\fR is present it is substituted
+with the user's Windows NT domain name. If the string \fI%U
+\fRis present it is substituted with the user's Windows
+NT user name.
+
+Default: \fBtemplate homedir = /home/%D/%U\fR
+.TP
+\fBtemplate shell (G)\fR
+When filling out the user information for a Windows NT
+user, the winbindd(8) daemon
+uses this parameter to fill in the login shell for that user.
+
+Default: \fBtemplate shell = /bin/false\fR
+.TP
+\fBtime offset (G)\fR
+This parameter is a setting in minutes to add
+to the normal GMT to local time conversion. This is useful if
+you are serving a lot of PCs that have incorrect daylight
+saving time handling.
+
+Default: \fBtime offset = 0\fR
+
+Example: \fBtime offset = 60\fR
+.TP
+\fBtime server (G)\fR
+This parameter determines if
+nmbd(8) advertises itself as a time server to Windows
+clients.
+
+Default: \fBtime server = no\fR
+.TP
+\fBtimestamp logs (G)\fR
+Synonym for \fI debug timestamp\fR.
+.TP
+\fBtotal print jobs (G)\fR
+This parameter accepts an integer value which defines
+a limit on the maximum number of print jobs that will be accepted
+system wide at any given time. If a print job is submitted
+by a client which will exceed this number, then smbd will return an
+error indicating that no space is available on the server. The
+default value of 0 means that no such limit exists. This parameter
+can be used to prevent a server from exceeding its capacity and is
+designed as a printing throttle. See also
+\fImax print jobs\fR.
+
+Default: \fBtotal print jobs = 0\fR
+
+Example: \fBtotal print jobs = 5000\fR
+.TP
+\fBunix extensions(G)\fR
+This boolean parameter controls whether Samba
+implments the CIFS UNIX extensions, as defined by HP.
+These extensions enable Samba to better serve UNIX CIFS clients
+by supporting features such as symbolic links, hard links, etc...
+These extensions require a similarly enabled client, and are of
+no current use to Windows clients.
+
+Default: \fBunix extensions = no\fR
+.TP
+\fBunix password sync (G)\fR
+This boolean parameter controls whether Samba
+attempts to synchronize the UNIX password with the SMB password
+when the encrypted SMB password in the smbpasswd file is changed.
+If this is set to yes the program specified in the \fIpasswd
+program\fRparameter is called \fBAS ROOT\fR -
+to allow the new UNIX password to be set without access to the
+old UNIX password (as the SMB password change code has no
+access to the old password cleartext, only the new).
+
+See also \fIpasswd
+program\fR, \fI passwd chat\fR.
+
+Default: \fBunix password sync = no\fR
+.TP
+\fBupdate encrypted (G)\fR
+This boolean parameter allows a user logging
+on with a plaintext password to have their encrypted (hashed)
+password in the smbpasswd file to be updated automatically as
+they log on. This option allows a site to migrate from plaintext
+password authentication (users authenticate with plaintext
+password over the wire, and are checked against a UNIX account
+database) to encrypted password authentication (the SMB
+challenge/response authentication mechanism) without forcing
+all users to re-enter their passwords via smbpasswd at the time the
+change is made. This is a convenience option to allow the change over
+to encrypted passwords to be made over a longer period. Once all users
+have encrypted representations of their passwords in the smbpasswd
+file this parameter should be set to no.
+
+In order for this parameter to work correctly the \fIencrypt passwords\fR
+parameter must be set to no when
+this parameter is set to yes.
+
+Note that even when this parameter is set a user
+authenticating to \fBsmbd\fR must still enter a valid
+password in order to connect correctly, and to update their hashed
+(smbpasswd) passwords.
+
+Default: \fBupdate encrypted = no\fR
+.TP
+\fBuse client driver (S)\fR
+This parameter applies only to Windows NT/2000
+clients. It has no affect on Windows 95/98/ME clients. When
+serving a printer to Windows NT/2000 clients without first installing
+a valid printer driver on the Samba host, the client will be required
+to install a local printer driver. From this point on, the client
+will treat the print as a local printer and not a network printer
+connection. This is much the same behavior that will occur
+when \fBdisable spoolss = yes\fR.
+
+The differentiating
+factor is that under normal circumstances, the NT/2000 client will
+attempt to open the network printer using MS-RPC. The problem is that
+because the client considers the printer to be local, it will attempt
+to issue the OpenPrinterEx() call requesting access rights associated
+with the logged on user. If the user possesses local administator rights
+but not root privilegde on the Samba host (often the case), the OpenPrinterEx()
+call will fail. The result is that the client will now display an "Access
+Denied; Unable to connect" message in the printer queue window (even though
+jobs may successfully be printed).
+
+If this parameter is enabled for a printer, then any attempt
+to open the printer with the PRINTER_ACCESS_ADMINISTER right is mapped
+to PRINTER_ACCESS_USE instead. Thus allowing the OpenPrinterEx()
+call to succeed. \fBThis parameter MUST not be able enabled
+on a print share which has valid print driver installed on the Samba
+server.\fR
+
+See also disable spoolss
+
+Default: \fBuse client driver = no\fR
+.TP
+\fBuse mmap (G)\fR
+This global parameter determines if the tdb internals of Samba can
+depend on mmap working correctly on the running system. Samba requires a coherent
+mmap/read-write system memory cache. Currently only HPUX does not have such a
+coherent cache, and so this parameter is set to no by
+default on HPUX. On all other systems this parameter should be left alone. This
+parameter is provided to help the Samba developers track down problems with
+the tdb internal code.
+
+Default: \fBuse mmap = yes\fR
+.TP
+\fBuse rhosts (G)\fR
+If this global parameter is yes, it specifies
+that the UNIX user's \fI.rhosts\fR file in their home directory
+will be read to find the names of hosts and users who will be allowed
+access without specifying a password.
+
+\fBNOTE:\fR The use of \fIuse rhosts
+\fRcan be a major security hole. This is because you are
+trusting the PC to supply the correct username. It is very easy to
+get a PC to supply a false username. I recommend that the \fI use rhosts\fR option be only used if you really know what
+you are doing.
+
+Default: \fBuse rhosts = no\fR
+.TP
+\fBuser (S)\fR
+Synonym for \fI username\fR.
+.TP
+\fBusers (S)\fR
+Synonym for \fI username\fR.
+.TP
+\fBusername (S)\fR
+Multiple users may be specified in a comma-delimited
+list, in which case the supplied password will be tested against
+each username in turn (left to right).
+
+The \fIusername\fR line is needed only when
+the PC is unable to supply its own username. This is the case
+for the COREPLUS protocol or where your users have different WfWg
+usernames to UNIX usernames. In both these cases you may also be
+better using the \\\\server\\share%user syntax instead.
+
+The \fIusername\fR line is not a great
+solution in many cases as it means Samba will try to validate
+the supplied password against each of the usernames in the
+\fIusername\fR line in turn. This is slow and
+a bad idea for lots of users in case of duplicate passwords.
+You may get timeouts or security breaches using this parameter
+unwisely.
+
+Samba relies on the underlying UNIX security. This
+parameter does not restrict who can login, it just offers hints
+to the Samba server as to what usernames might correspond to the
+supplied password. Users can login as whoever they please and
+they will be able to do no more damage than if they started a
+telnet session. The daemon runs as the user that they log in as,
+so they cannot do anything that user cannot do.
+
+To restrict a service to a particular set of users you
+can use the \fIvalid users
+\fRparameter.
+
+If any of the usernames begin with a '@' then the name
+will be looked up first in the NIS netgroups list (if Samba
+is compiled with netgroup support), followed by a lookup in
+the UNIX groups database and will expand to a list of all users
+in the group of that name.
+
+If any of the usernames begin with a '+' then the name
+will be looked up only in the UNIX groups database and will
+expand to a list of all users in the group of that name.
+
+If any of the usernames begin with a '&'then the name
+will be looked up only in the NIS netgroups database (if Samba
+is compiled with netgroup support) and will expand to a list
+of all users in the netgroup group of that name.
+
+Note that searching though a groups database can take
+quite some time, and some clients may time out during the
+search.
+
+See the section NOTE ABOUT
+USERNAME/PASSWORD VALIDATION for more information on how
+this parameter determines access to the services.
+
+Default: \fBThe guest account if a guest service,
+else <empty string>.\fR
+
+Examples:\fBusername = fred, mary, jack, jane,
+@users, @pcgroup\fR
+.TP
+\fBusername level (G)\fR
+This option helps Samba to try and 'guess' at
+the real UNIX username, as many DOS clients send an all-uppercase
+username. By default Samba tries all lowercase, followed by the
+username with the first letter capitalized, and fails if the
+username is not found on the UNIX machine.
+
+If this parameter is set to non-zero the behavior changes.
+This parameter is a number that specifies the number of uppercase
+combinations to try while trying to determine the UNIX user name. The
+higher the number the more combinations will be tried, but the slower
+the discovery of usernames will be. Use this parameter when you have
+strange usernames on your UNIX machine, such as AstrangeUser
+\&.
+
+Default: \fBusername level = 0\fR
+
+Example: \fBusername level = 5\fR
+.TP
+\fBusername map (G)\fR
+This option allows you to specify a file containing
+a mapping of usernames from the clients to the server. This can be
+used for several purposes. The most common is to map usernames
+that users use on DOS or Windows machines to those that the UNIX
+box uses. The other is to map multiple users to a single username
+so that they can more easily share files.
+
+The map file is parsed line by line. Each line should
+contain a single UNIX username on the left then a '=' followed
+by a list of usernames on the right. The list of usernames on the
+right may contain names of the form @group in which case they
+will match any UNIX username in that group. The special client
+name '*' is a wildcard and matches any name. Each line of the
+map file may be up to 1023 characters long.
+
+The file is processed on each line by taking the
+supplied username and comparing it with each username on the right
+hand side of the '=' signs. If the supplied name matches any of
+the names on the right hand side then it is replaced with the name
+on the left. Processing then continues with the next line.
+
+If any line begins with a '#' or a ';' then it is
+ignored
+
+If any line begins with an '!' then the processing
+will stop after that line if a mapping was done by the line.
+Otherwise mapping continues with every line being processed.
+Using '!' is most useful when you have a wildcard mapping line
+later in the file.
+
+For example to map from the name admin
+or administrator to the UNIX name root you would use:
+
+\fBroot = admin administrator\fR
+
+Or to map anyone in the UNIX group system
+to the UNIX name sys you would use:
+
+\fBsys = @system\fR
+
+You can have as many mappings as you like in a username
+map file.
+
+If your system supports the NIS NETGROUP option then
+the netgroup database is checked before the \fI/etc/group
+\fRdatabase for matching groups.
+
+You can map Windows usernames that have spaces in them
+by using double quotes around the name. For example:
+
+\fBtridge = "Andrew Tridgell"\fR
+
+would map the windows username "Andrew Tridgell" to the
+unix username "tridge".
+
+The following example would map mary and fred to the
+unix user sys, and map the rest to guest. Note the use of the
+\&'!' to tell Samba to stop processing if it gets a match on
+that line.
+
+.sp
+.nf
+ !sys = mary fred
+ guest = *
+
+.sp
+.fi
+
+Note that the remapping is applied to all occurrences
+of usernames. Thus if you connect to \\\\server\\fred and fred is remapped to mary then you
+will actually be connecting to \\\\server\\mary and will need to
+supply a password suitable for mary not
+fred. The only exception to this is the
+username passed to the \fI password server\fR (if you have one). The password
+server will receive whatever username the client supplies without
+modification.
+
+Also note that no reverse mapping is done. The main effect
+this has is with printing. Users who have been mapped may have
+trouble deleting print jobs as PrintManager under WfWg will think
+they don't own the print job.
+
+Default: \fBno username map\fR
+
+Example: \fBusername map = /usr/local/samba/lib/users.map
+\fR.TP
+\fBuse sendfile (S)\fR
+If this parameter is yes, and Samba
+was built with the --with-sendfile-support option, and the underlying operating
+system supports sendfile system call, then some SMB read calls (mainly ReadAndX
+and ReadRaw) will use the more efficient sendfile system call for files that
+are exclusively oplocked. This may make more efficient use of the system CPU's
+and cause Samba to be faster. This is off by default as it's effects are unknown
+as yet.
+
+Default: \fBuse sendfile = no\fR
+.TP
+\fButmp (G)\fR
+This boolean parameter is only available if
+Samba has been configured and compiled with the option \fB --with-utmp\fR. If set to yes then Samba will attempt
+to add utmp or utmpx records (depending on the UNIX system) whenever a
+connection is made to a Samba server. Sites may use this to record the
+user connecting to a Samba share.
+
+See also the \fI utmp directory\fR parameter.
+
+Default: \fButmp = no\fR
+.TP
+\fButmp directory(G)\fR
+This parameter is only available if Samba has
+been configured and compiled with the option \fB --with-utmp\fR. It specifies a directory pathname that is
+used to store the utmp or utmpx files (depending on the UNIX system) that
+record user connections to a Samba server. See also the \fIutmp\fR parameter. By default this is
+not set, meaning the system will use whatever utmp file the
+native system is set to use (usually
+\fI/var/run/utmp\fR on Linux).
+
+Default: \fBno utmp directory\fR
+.TP
+\fBvalid chars (G)\fR
+The option allows you to specify additional
+characters that should be considered valid by the server in
+filenames. This is particularly useful for national character
+sets, such as adding u-umlaut or a-ring.
+
+The option takes a list of characters in either integer
+or character form with spaces between them. If you give two
+characters with a colon between them then it will be taken as
+an lowercase:uppercase pair.
+
+If you have an editor capable of entering the characters
+into the config file then it is probably easiest to use this
+method. Otherwise you can specify the characters in octal,
+decimal or hexadecimal form using the usual C notation.
+
+For example to add the single character 'Z' to the charset
+(which is a pointless thing to do as it's already there) you could
+do one of the following
+
+.sp
+.nf
+ valid chars = Z
+ valid chars = z:Z
+ valid chars = 0132:0172
+
+.sp
+.fi
+
+The last two examples above actually add two characters,
+and alter the uppercase and lowercase mappings appropriately.
+
+Note that you \fBMUST\fR specify this parameter
+after the \fIclient code page\fR parameter if you
+have both set. If \fIclient code page\fR is set after
+the \fIvalid chars\fR parameter the \fIvalid
+chars\fR settings will be overwritten.
+
+See also the \fIclient
+code page\fR parameter.
+
+Default: \fBSamba defaults to using a reasonable set
+of valid characters for English systems\fR
+
+Example: \fBvalid chars = 0345:0305 0366:0326 0344:0304
+\fR
+The above example allows filenames to have the Swedish
+characters in them.
+
+\fBNOTE:\fR It is actually quite difficult to
+correctly produce a \fIvalid chars\fR line for
+a particular system. To automate the process tino@augsburg.net <URL:mailto:tino@augsburg.net> has written
+a package called \fBvalidchars\fR which will automatically
+produce a complete \fIvalid chars\fR line for
+a given client system. Look in the \fIexamples/validchars/
+\fRsubdirectory of your Samba source code distribution
+for this package.
+.TP
+\fBvalid users (S)\fR
+This is a list of users that should be allowed
+to login to this service. Names starting with '@', '+' and '&'
+are interpreted using the same rules as described in the
+\fIinvalid users\fR parameter.
+
+If this is empty (the default) then any user can login.
+If a username is in both this list and the \fIinvalid
+users\fR list then access is denied for that user.
+
+The current servicename is substituted for \fI%S
+\fR\&. This is useful in the [homes] section.
+
+See also \fIinvalid users
+\fR
+Default: \fBNo valid users list (anyone can login)
+\fR
+Example: \fBvalid users = greg, @pcusers\fR
+.TP
+\fBveto files(S)\fR
+This is a list of files and directories that
+are neither visible nor accessible. Each entry in the list must
+be separated by a '/', which allows spaces to be included
+in the entry. '*' and '?' can be used to specify multiple files
+or directories as in DOS wildcards.
+
+Each entry must be a unix path, not a DOS path and
+must \fBnot\fR include the unix directory
+separator '/'.
+
+Note that the \fIcase sensitive\fR option
+is applicable in vetoing files.
+
+One feature of the veto files parameter that it
+is important to be aware of is Samba's behaviour when
+trying to delete a directory. If a directory that is
+to be deleted contains nothing but veto files this
+deletion will \fBfail\fR unless you also set
+the \fIdelete veto files\fR parameter to
+\fIyes\fR.
+
+Setting this parameter will affect the performance
+of Samba, as it will be forced to check all files and directories
+for a match as they are scanned.
+
+See also \fIhide files
+\fRand \fI case sensitive\fR.
+
+Default: \fBNo files or directories are vetoed.
+\fR
+Examples:
+.sp
+.nf
+; Veto any files containing the word Security,
+; any ending in .tmp, and any directory containing the
+; word root.
+veto files = /*Security*/*.tmp/*root*/
+
+; Veto the Apple specific files that a NetAtalk server
+; creates.
+veto files = /.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/
+.sp
+.fi
+.TP
+\fBveto oplock files (S)\fR
+This parameter is only valid when the \fIoplocks\fR
+parameter is turned on for a share. It allows the Samba administrator
+to selectively turn off the granting of oplocks on selected files that
+match a wildcarded list, similar to the wildcarded list used in the
+\fIveto files\fR
+parameter.
+
+Default: \fBNo files are vetoed for oplock
+grants\fR
+
+You might want to do this on files that you know will
+be heavily contended for by clients. A good example of this
+is in the NetBench SMB benchmark program, which causes heavy
+client contention for files ending in \fI.SEM\fR.
+To cause Samba not to grant oplocks on these files you would use
+the line (either in the [global] section or in the section for
+the particular NetBench share :
+
+Example: \fBveto oplock files = /*.SEM/
+\fR.TP
+\fBvfs object (S)\fR
+This parameter specifies a shared object file that
+is used for Samba VFS I/O operations. By default, normal
+disk I/O operations are used but these can be overloaded
+with a VFS object. The Samba VFS layer is new to Samba 2.2 and
+must be enabled at compile time with --with-vfs.
+
+Default : \fBno value\fR
+.TP
+\fBvfs options (S)\fR
+This parameter allows parameters to be passed
+to the vfs layer at initialization time. The Samba VFS layer
+is new to Samba 2.2 and must be enabled at compile time
+with --with-vfs. See also \fI vfs object\fR.
+
+Default : \fBno value\fR
+.TP
+\fBvolume (S)\fR
+This allows you to override the volume label
+returned for a share. Useful for CDROMs with installation programs
+that insist on a particular volume label.
+
+Default: \fBthe name of the share\fR
+.TP
+\fBwide links (S)\fR
+This parameter controls whether or not links
+in the UNIX file system may be followed by the server. Links
+that point to areas within the directory tree exported by the
+server are always allowed; this parameter controls access only
+to areas that are outside the directory tree being exported.
+
+Note that setting this parameter can have a negative
+effect on your server performance due to the extra system calls
+that Samba has to do in order to perform the link checks.
+
+Default: \fBwide links = yes\fR
+.TP
+\fBwinbind cache time (G)\fR
+This parameter specifies the number of seconds the
+winbindd(8) daemon will cache
+user and group information before querying a Windows NT server
+again.
+
+Default: \fBwinbind cache type = 15\fR
+.TP
+\fBwinbind enum users (G)\fR
+On large installations using
+winbindd(8) it may be
+necessary to suppress the enumeration of users through the
+\fBsetpwent()\fR,
+\fBgetpwent()\fR and
+\fBendpwent()\fR group of system calls. If
+the \fIwinbind enum users\fR parameter is
+no, calls to the \fBgetpwent\fR system call
+will not return any data.
+
+\fBWarning:\fR Turning off user
+enumeration may cause some programs to behave oddly. For
+example, the finger program relies on having access to the
+full user list when searching for matching
+usernames.
+
+Default: \fBwinbind enum users = yes \fR
+.TP
+\fBwinbind enum groups (G)\fR
+On large installations using
+winbindd(8) it may be
+necessary to suppress the enumeration of groups through the
+\fBsetgrent()\fR,
+\fBgetgrent()\fR and
+\fBendgrent()\fR group of system calls. If
+the \fIwinbind enum groups\fR parameter is
+no, calls to the \fBgetgrent()\fR system
+call will not return any data.
+
+\fBWarning:\fR Turning off group
+enumeration may cause some programs to behave oddly.
+
+Default: \fBwinbind enum groups = yes \fR
+.TP
+\fBwinbind gid (G)\fR
+The winbind gid parameter specifies the range of group
+ids that are allocated by the winbindd(8) daemon. This range of group ids should have no
+existing local or NIS groups within it as strange conflicts can
+occur otherwise.
+
+Default: \fBwinbind gid = <empty string>
+\fR
+Example: \fBwinbind gid = 10000-20000\fR
+.TP
+\fBwinbind separator (G)\fR
+This parameter allows an admin to define the character
+used when listing a username of the form of \fIDOMAIN
+\fR\\\fIuser\fR. This parameter
+is only applicable when using the \fIpam_winbind.so\fR
+and \fInss_winbind.so\fR modules for UNIX services.
+
+Please note that setting this parameter to + causes problems
+with group membership at least on glibc systems, as the character +
+is used as a special character for NIS in /etc/group.
+
+Default: \fBwinbind separator = '\\'\fR
+
+Example: \fBwinbind separator = +\fR
+.TP
+\fBwinbind uid (G)\fR
+The winbind gid parameter specifies the range of group
+ids that are allocated by the winbindd(8) daemon. This range of ids should have no
+existing local or NIS users within it as strange conflicts can
+occur otherwise.
+
+Default: \fBwinbind uid = <empty string>
+\fR
+Example: \fBwinbind uid = 10000-20000\fR
+.TP
+\fBwinbind use default domain\fR
+.TP
+\fBwinbind use default domain\fR
+This parameter specifies whether the winbindd(8)
+daemon should operate on users without domain component in their username.
+Users without a domain component are treated as is part of the winbindd server's
+own domain. While this does not benifit Windows users, it makes SSH, FTP and e-mail
+function in a way much closer to the way they would in a native unix system.
+
+Default: \fBwinbind use default domain = <no>
+\fR
+Example: \fBwinbind use default domain = yes\fR
+.TP
+\fBwins hook (G)\fR
+When Samba is running as a WINS server this
+allows you to call an external program for all changes to the
+WINS database. The primary use for this option is to allow the
+dynamic update of external name resolution databases such as
+dynamic DNS.
+
+The wins hook parameter specifies the name of a script
+or executable that will be called as follows:
+
+\fBwins_hook operation name nametype ttl IP_list
+\fR.RS
+.TP 0.2i
+\(bu
+The first argument is the operation and is one
+of "add", "delete", or "refresh". In most cases the operation can
+be ignored as the rest of the parameters provide sufficient
+information. Note that "refresh" may sometimes be called when the
+name has not previously been added, in that case it should be treated
+as an add.
+.TP 0.2i
+\(bu
+The second argument is the NetBIOS name. If the
+name is not a legal name then the wins hook is not called.
+Legal names contain only letters, digits, hyphens, underscores
+and periods.
+.TP 0.2i
+\(bu
+The third argument is the NetBIOS name
+type as a 2 digit hexadecimal number.
+.TP 0.2i
+\(bu
+The fourth argument is the TTL (time to live)
+for the name in seconds.
+.TP 0.2i
+\(bu
+The fifth and subsequent arguments are the IP
+addresses currently registered for that name. If this list is
+empty then the name should be deleted.
+.RE
+.PP
+An example script that calls the BIND dynamic DNS update
+program \fBnsupdate\fR is provided in the examples
+directory of the Samba source code.
+.PP
+.TP
+\fBwins proxy (G)\fR
+This is a boolean that controls if nmbd(8) will respond to broadcast name
+queries on behalf of other hosts. You may need to set this
+to yes for some older clients.
+
+Default: \fBwins proxy = no\fR
+.TP
+\fBwins server (G)\fR
+This specifies the IP address (or DNS name: IP
+address for preference) of the WINS server that nmbd(8) should register with. If you have a WINS server on
+your network then you should set this to the WINS server's IP.
+
+You should point this at your WINS server if you have a
+multi-subnetted network.
+
+\fBNOTE\fR. You need to set up Samba to point
+to a WINS server if you have multiple subnets and wish cross-subnet
+browsing to work correctly.
+
+See the documentation file \fIBROWSING.txt\fR
+in the docs/ directory of your Samba source distribution.
+
+Default: \fBnot enabled\fR
+
+Example: \fBwins server = 192.9.200.1\fR
+.TP
+\fBwins support (G)\fR
+This boolean controls if the
+nmbd(8) process in Samba will act as a WINS server. You should
+not set this to yes unless you have a multi-subnetted network and
+you wish a particular \fBnmbd\fR to be your WINS server.
+Note that you should \fBNEVER\fR set this to yes
+on more than one machine in your network.
+
+Default: \fBwins support = no\fR
+.TP
+\fBworkgroup (G)\fR
+This controls what workgroup your server will
+appear to be in when queried by clients. Note that this parameter
+also controls the Domain name used with the \fBsecurity = domain\fR
+setting.
+
+Default: \fBset at compile time to WORKGROUP\fR
+
+Example: \fBworkgroup = MYGROUP\fR
+.TP
+\fBwritable (S)\fR
+Synonym for \fI writeable\fR for people who can't spell :-).
+.TP
+\fBwrite cache size (S)\fR
+If this integer parameter is set to non-zero value,
+Samba will create an in-memory cache for each oplocked file
+(it does \fBnot\fR do this for
+non-oplocked files). All writes that the client does not request
+to be flushed directly to disk will be stored in this cache if possible.
+The cache is flushed onto disk when a write comes in whose offset
+would not fit into the cache or when the file is closed by the client.
+Reads for the file are also served from this cache if the data is stored
+within it.
+
+This cache allows Samba to batch client writes into a more
+efficient write size for RAID disks (i.e. writes may be tuned to
+be the RAID stripe size) and can improve performance on systems
+where the disk subsystem is a bottleneck but there is free
+memory for userspace programs.
+
+The integer parameter specifies the size of this cache
+(per oplocked file) in bytes.
+
+Default: \fBwrite cache size = 0\fR
+
+Example: \fBwrite cache size = 262144\fR
+
+for a 256k cache size per file.
+.TP
+\fBwrite list (S)\fR
+This is a list of users that are given read-write
+access to a service. If the connecting user is in this list then
+they will be given write access, no matter what the \fIread only\fR
+option is set to. The list can include group names using the
+@group syntax.
+
+Note that if a user is in both the read list and the
+write list then they will be given write access.
+
+See also the \fIread list
+\fRoption.
+
+Default: \fBwrite list = <empty string>
+\fR
+Example: \fBwrite list = admin, root, @staff
+\fR.TP
+\fBwrite ok (S)\fR
+Inverted synonym for \fI read only\fR.
+.TP
+\fBwrite raw (G)\fR
+This parameter controls whether or not the server
+will support raw write SMB's when transferring data from clients.
+You should never need to change this parameter.
+
+Default: \fBwrite raw = yes\fR
+.TP
+\fBwriteable (S)\fR
+Inverted synonym for \fI read only\fR.
+.SH "WARNINGS"
+.PP
+Although the configuration file permits service names
+to contain spaces, your client software may not. Spaces will
+be ignored in comparisons anyway, so it shouldn't be a
+problem - but be aware of the possibility.
+.PP
+On a similar note, many clients - especially DOS clients -
+limit service names to eight characters. smbd(8)
+ has no such limitation, but attempts to connect from such
+clients will fail if they truncate the service names. For this reason
+you should probably keep your service names down to eight characters
+in length.
+.PP
+Use of the [homes] and [printers] special sections make life
+for an administrator easy, but the various combinations of default
+attributes can be tricky. Take extreme care when designing these
+sections. In particular, ensure that the permissions on spool
+directories are correct.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+samba(7)
+\fBsmbpasswd(8)\fR
+\fBswat(8)\fR
+\fBsmbd(8)\fR
+\fBnmbd(8)\fR
+\fBsmbclient(1)\fR
+\fBnmblookup(1)\fR
+\fBtestparm(1)\fR
+\fBtestprns(1)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbcacls.1 b/docs/manpages/smbcacls.1
new file mode 100755
index 00000000000..f62c34265d8
--- /dev/null
+++ b/docs/manpages/smbcacls.1
@@ -0,0 +1,191 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBCACLS" "1" "19 November 2002" "" ""
+.SH NAME
+smbcacls \- Set or get ACLs on an NT file or directory names
+.SH SYNOPSIS
+.sp
+\fBsmbcacls\fR \fB//server/share\fR \fBfilename\fR [ \fB-U username\fR ] [ \fB-A acls\fR ] [ \fB-M acls\fR ] [ \fB-D acls\fR ] [ \fB-S acls\fR ] [ \fB-C name\fR ] [ \fB-G name\fR ] [ \fB-n\fR ] [ \fB-h\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+The \fBsmbcacls\fR program manipulates NT Access Control Lists
+(ACLs) on SMB file shares.
+.SH "OPTIONS"
+.PP
+The following options are available to the \fBsmbcacls\fR program.
+The format of ACLs is described in the section ACL FORMAT
+.TP
+\fB-A acls\fR
+Add the ACLs specified to the ACL list. Existing
+access control entries are unchanged.
+.TP
+\fB-M acls\fR
+Modify the mask value (permissions) for the ACLs
+specified on the command line. An error will be printed for each
+ACL specified that was not already present in the ACL list
+.TP
+\fB-D acls\fR
+Delete any ACLs specified on the command line.
+An error will be printed for each ACL specified that was not
+already present in the ACL list.
+.TP
+\fB-S acls\fR
+This command sets the ACLs on the file with
+only the ones specified on the command line. All other ACLs are
+erased. Note that the ACL specified must contain at least a revision,
+type, owner and group for the call to succeed.
+.TP
+\fB-U username\fR
+Specifies a username used to connect to the
+specified service. The username may be of the form "username" in
+which case the user is prompted to enter in a password and the
+workgroup specified in the \fIsmb.conf\fR file is
+used, or "username%password" or "DOMAIN\\username%password" and the
+password and workgroup names are used as provided.
+.TP
+\fB-C name\fR
+The owner of a file or directory can be changed
+to the name given using the \fI-C\fR option.
+The name can be a sid in the form S-1-x-y-z or a name resolved
+against the server specified in the first argument.
+
+This command is a shortcut for -M OWNER:name.
+.TP
+\fB-G name\fR
+The group owner of a file or directory can
+be changed to the name given using the \fI-G\fR
+option. The name can be a sid in the form S-1-x-y-z or a name
+resolved against the server specified n the first argument.
+
+This command is a shortcut for -M GROUP:name.
+.TP
+\fB-n\fR
+This option displays all ACL information in numeric
+format. The default is to convert SIDs to names and ACE types
+and masks to a readable string format.
+.TP
+\fB-h\fR
+Print usage information on the \fBsmbcacls
+\fRprogram.
+.SH "ACL FORMAT"
+.PP
+The format of an ACL is one or more ACL entries separated by
+either commas or newlines. An ACL entry is one of the following:
+.PP
+.sp
+.nf
+
+REVISION:<revision number>
+OWNER:<sid or name>
+GROUP:<sid or name>
+ACL:<sid or name>:<type>/<flags>/<mask>
+
+.sp
+.fi
+.PP
+The revision of the ACL specifies the internal Windows
+NT ACL revision for the security descriptor.
+If not specified it defaults to 1. Using values other than 1 may
+cause strange behaviour.
+.PP
+The owner and group specify the owner and group sids for the
+object. If a SID in the format CWS-1-x-y-z is specified this is used,
+otherwise the name specified is resolved using the server on which
+the file or directory resides.
+.PP
+ACLs specify permissions granted to the SID. This SID again
+can be specified in CWS-1-x-y-z format or as a name in which case
+it is resolved against the server on which the file or directory
+resides. The type, flags and mask values determine the type of
+access granted to the SID.
+.PP
+The type can be either 0 or 1 corresponding to ALLOWED or
+DENIED access to the SID. The flags values are generally
+zero for file ACLs and either 9 or 2 for directory ACLs. Some
+common flags are:
+.TP 0.2i
+\(bu
+#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1
+.TP 0.2i
+\(bu
+#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2
+.TP 0.2i
+\(bu
+#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4
+.TP 0.2i
+\(bu
+#define SEC_ACE_FLAG_INHERIT_ONLY 0x8
+.PP
+At present flags can only be specified as decimal or
+hexadecimal values.
+.PP
+.PP
+The mask is a value which expresses the access right
+granted to the SID. It can be given as a decimal or hexadecimal value,
+or by using one of the following text strings which map to the NT
+file permissions of the same name.
+.PP
+.TP 0.2i
+\(bu
+\fBR\fR - Allow read access
+.TP 0.2i
+\(bu
+\fBW\fR - Allow write access
+.TP 0.2i
+\(bu
+\fBX\fR - Execute permission on the object
+.TP 0.2i
+\(bu
+\fBD\fR - Delete the object
+.TP 0.2i
+\(bu
+\fBP\fR - Change permissions
+.TP 0.2i
+\(bu
+\fBO\fR - Take ownership
+.PP
+The following combined permissions can be specified:
+.PP
+.TP 0.2i
+\(bu
+\fBREAD\fR - Equivalent to 'RX'
+permissions
+.TP 0.2i
+\(bu
+\fBCHANGE\fR - Equivalent to 'RXWD' permissions
+.TP 0.2i
+\(bu
+\fBFULL\fR - Equivalent to 'RWXDPO'
+permissions
+.SH "EXIT STATUS"
+.PP
+The \fBsmbcacls\fR program sets the exit status
+depending on the success or otherwise of the operations performed.
+The exit status may be one of the following values.
+.PP
+If the operation succeeded, smbcacls returns and exit
+status of 0. If \fBsmbcacls\fR couldn't connect to the specified server,
+or there was an error getting or setting the ACLs, an exit status
+of 1 is returned. If there was an error parsing any command line
+arguments, an exit status of 2 is returned.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+\fBsmbcacls\fR was written by Andrew Tridgell
+and Tim Potter.
+.PP
+The conversion to DocBook for Samba 2.2 was done
+by Gerald Carter
diff --git a/docs/manpages/smbclient.1 b/docs/manpages/smbclient.1
new file mode 100755
index 00000000000..298cfd223a6
--- /dev/null
+++ b/docs/manpages/smbclient.1
@@ -0,0 +1,812 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBCLIENT" "1" "19 November 2002" "" ""
+.SH NAME
+smbclient \- ftp-like client to access SMB/CIFS resources on servers
+.SH SYNOPSIS
+.sp
+\fBsmbclient\fR \fBservicename\fR [ \fBpassword\fR ] [ \fB-b <buffer size>\fR ] [ \fB-d debuglevel\fR ] [ \fB-D Directory\fR ] [ \fB-U username\fR ] [ \fB-W workgroup\fR ] [ \fB-M <netbios name>\fR ] [ \fB-m maxprotocol\fR ] [ \fB-A authfile\fR ] [ \fB-N\fR ] [ \fB-l logfile\fR ] [ \fB-L <netbios name>\fR ] [ \fB-I destinationIP\fR ] [ \fB-E <terminal code>\fR ] [ \fB-c <command string>\fR ] [ \fB-i scope\fR ] [ \fB-O <socket options>\fR ] [ \fB-p port\fR ] [ \fB-R <name resolve order>\fR ] [ \fB-s <smb config file>\fR ] [ \fB-T<c|x>IXFqgbNan\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBsmbclient\fR is a client that can
+\&'talk' to an SMB/CIFS server. It offers an interface
+similar to that of the ftp program (see \fBftp(1)\fR).
+Operations include things like getting files from the server
+to the local machine, putting files from the local machine to
+the server, retrieving directory information from the server
+and so on.
+.SH "OPTIONS"
+.TP
+\fBservicename\fR
+servicename is the name of the service
+you want to use on the server. A service name takes the form
+\fI//server/service\fR where \fIserver
+\fRis the NetBIOS name of the SMB/CIFS server
+offering the desired service and \fIservice\fR
+is the name of the service offered. Thus to connect to
+the service "printer" on the SMB/CIFS server "smbserver",
+you would use the servicename \fI//smbserver/printer
+\fR
+Note that the server name required is NOT necessarily
+the IP (DNS) host name of the server ! The name required is
+a NetBIOS server name, which may or may not be the
+same as the IP hostname of the machine running the server.
+
+The server name is looked up according to either
+the \fI-R\fR parameter to \fBsmbclient\fR or
+using the name resolve order parameter in the \fIsmb.conf\fR file,
+allowing an administrator to change the order and methods
+by which server names are looked up.
+.TP
+\fBpassword\fR
+The password required to access the specified
+service on the specified server. If this parameter is
+supplied, the \fI-N\fR option (suppress
+password prompt) is assumed.
+
+There is no default password. If no password is supplied
+on the command line (either by using this parameter or adding
+a password to the \fI-U\fR option (see
+below)) and the \fI-N\fR option is not
+specified, the client will prompt for a password, even if
+the desired service does not require one. (If no password is
+required, simply press ENTER to provide a null password.)
+
+Note: Some servers (including OS/2 and Windows for
+Workgroups) insist on an uppercase password. Lowercase
+or mixed case passwords may be rejected by these servers.
+
+Be cautious about including passwords in scripts.
+.TP
+\fB-s smb.conf\fR
+Specifies the location of the all important
+\fIsmb.conf\fR file.
+.TP
+\fB-O socket options\fR
+TCP socket options to set on the client
+socket. See the socket options parameter in the \fI smb.conf (5)\fR manpage for the list of valid
+options.
+.TP
+\fB-R <name resolve order>\fR
+This option is used by the programs in the Samba
+suite to determine what naming services and in what order to resolve
+host names to IP addresses. The option takes a space-separated
+string of different name resolution options.
+
+The options are :"lmhosts", "host", "wins" and "bcast". They
+cause names to be resolved as follows :
+.RS
+.TP 0.2i
+\(bu
+lmhosts : Lookup an IP
+address in the Samba lmhosts file. If the line in lmhosts has
+no name type attached to the NetBIOS name (see the lmhosts(5) for details) then
+any name type matches for lookup.
+.TP 0.2i
+\(bu
+host : Do a standard host
+name to IP address resolution, using the system \fI/etc/hosts
+\fR, NIS, or DNS lookups. This method of name resolution
+is operating system dependent, for instance on IRIX or Solaris this
+may be controlled by the \fI/etc/nsswitch.conf\fR
+file). Note that this method is only used if the NetBIOS name
+type being queried is the 0x20 (server) name type, otherwise
+it is ignored.
+.TP 0.2i
+\(bu
+wins : Query a name with
+the IP address listed in the \fIwins server\fR
+parameter. If no WINS server has
+been specified this method will be ignored.
+.TP 0.2i
+\(bu
+bcast : Do a broadcast on
+each of the known local interfaces listed in the
+\fIinterfaces\fR
+parameter. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally
+connected subnet.
+.RE
+.PP
+If this parameter is not set then the name resolve order
+defined in the \fIsmb.conf\fR file parameter
+(name resolve order) will be used.
+.PP
+.PP
+The default order is lmhosts, host, wins, bcast and without
+this parameter or any entry in the \fIname resolve order
+\fRparameter of the \fIsmb.conf\fR file the name resolution
+methods will be attempted in this order.
+.PP
+.TP
+\fB-M NetBIOS name\fR
+This options allows you to send messages, using
+the "WinPopup" protocol, to another computer. Once a connection is
+established you then type your message, pressing ^D (control-D) to
+end.
+
+If the receiving computer is running WinPopup the user will
+receive the message and probably a beep. If they are not running
+WinPopup the message will be lost, and no error message will
+occur.
+
+The message is also automatically truncated if the message
+is over 1600 bytes, as this is the limit of the protocol.
+
+One useful trick is to cat the message through
+\fBsmbclient\fR. For example: \fB cat mymessage.txt | smbclient -M FRED \fR will
+send the message in the file \fImymessage.txt\fR
+to the machine FRED.
+
+You may also find the \fI-U\fR and
+\fI-I\fR options useful, as they allow you to
+control the FROM and TO parts of the message.
+
+See the message command parameter in the \fI smb.conf(5)\fR for a description of how to handle incoming
+WinPopup messages in Samba.
+
+\fBNote\fR: Copy WinPopup into the startup group
+on your WfWg PCs if you want them to always be able to receive
+messages.
+.TP
+\fB-i scope\fR
+This specifies a NetBIOS scope that smbclient will
+use to communicate with when generating NetBIOS names. For details
+on the use of NetBIOS scopes, see \fIrfc1001.txt\fR
+and \fIrfc1002.txt\fR.
+NetBIOS scopes are \fBvery\fR rarely used, only set
+this parameter if you are the system administrator in charge of all
+the NetBIOS systems you communicate with.
+.TP
+\fB-N\fR
+If specified, this parameter suppresses the normal
+password prompt from the client to the user. This is useful when
+accessing a service that does not require a password.
+
+Unless a password is specified on the command line or
+this parameter is specified, the client will request a
+password.
+.TP
+\fB-n NetBIOS name\fR
+By default, the client will use the local
+machine's hostname (in uppercase) as its NetBIOS name. This parameter
+allows you to override the host name and use whatever NetBIOS
+name you wish.
+.TP
+\fB-d debuglevel\fR
+\fIdebuglevel\fR is an integer from 0 to 10, or
+the letter 'A'.
+
+The default value if this parameter is not specified
+is zero.
+
+The higher this value, the more detail will be logged to
+the log files about the activities of the
+client. At level 0, only critical errors and serious warnings will
+be logged. Level 1 is a reasonable level for day to day running -
+it generates a small amount of information about operations
+carried out.
+
+Levels above 1 will generate considerable amounts of log
+data, and should only be used when investigating a problem.
+Levels above 3 are designed for use only by developers and
+generate HUGE amounts of log data, most of which is extremely
+cryptic. If \fIdebuglevel\fR is set to the letter 'A', then \fBall
+\fRdebug messages will be printed. This setting
+is for developers only (and people who \fBreally\fR want
+to know how the code works internally).
+
+Note that specifying this parameter here will override
+the log level parameter in the \fIsmb.conf (5)\fR
+file.
+.TP
+\fB-p port\fR
+This number is the TCP port number that will be used
+when making connections to the server. The standard (well-known)
+TCP port number for an SMB/CIFS server is 139, which is the
+default.
+.TP
+\fB-l logfilename\fR
+If specified, \fIlogfilename\fR specifies a base filename
+into which operational data from the running client will be
+logged.
+
+The default base name is specified at compile time.
+
+The base name is used to generate actual log file names.
+For example, if the name specified was "log", the debug file
+would be \fIlog.client\fR.
+
+The log file generated is never removed by the client.
+.TP
+\fB-h\fR
+Print the usage message for the client.
+.TP
+\fB-I IP-address\fR
+\fIIP address\fR is the address of the server to connect to.
+It should be specified in standard "a.b.c.d" notation.
+
+Normally the client would attempt to locate a named
+SMB/CIFS server by looking it up via the NetBIOS name resolution
+mechanism described above in the \fIname resolve order\fR
+parameter above. Using this parameter will force the client
+to assume that the server is on the machine with the specified IP
+address and the NetBIOS name component of the resource being
+connected to will be ignored.
+
+There is no default for this parameter. If not supplied,
+it will be determined automatically by the client as described
+above.
+.TP
+\fB-E\fR
+This parameter causes the client to write messages
+to the standard error stream (stderr) rather than to the standard
+output stream.
+
+By default, the client writes messages to standard output
+- typically the user's tty.
+.TP
+\fB-U username[%pass]\fR
+Sets the SMB username or username and password.
+If %pass is not specified, The user will be prompted. The client
+will first check the \fBUSER\fR environment variable, then the
+\fBLOGNAME\fR variable and if either exists, the
+string is uppercased. Anything in these variables following a '%'
+sign will be treated as the password. If these environment
+variables are not found, the username GUEST
+is used.
+
+If the password is not included in these environment
+variables (using the %pass syntax), \fBsmbclient\fR will look for
+a \fBPASSWD\fR environment variable from which
+to read the password.
+
+A third option is to use a credentials file which
+contains the plaintext of the domain name, username and password. This
+option is mainly provided for scripts where the admin doesn't
+wish to pass the credentials on the command line or via environment
+variables. If this method is used, make certain that the permissions
+on the file restrict access from unwanted users. See the
+\fI-A\fR for more details.
+
+Be cautious about including passwords in scripts or in
+the \fBPASSWD\fR environment variable. Also, on
+many systems the command line of a running process may be seen
+via the \fBps\fR command to be safe always allow
+\fBsmbclient\fR to prompt for a password and type
+it in directly.
+.TP
+\fB-A filename\fR
+This option allows
+you to specify a file from which to read the username, domain name, and
+password used in the connection. The format of the file is
+
+.sp
+.nf
+username = <value>
+password = <value>
+domain = <value>
+
+.sp
+.fi
+
+If the domain parameter is missing the current workgroup name
+is used instead. Make certain that the permissions on the file restrict
+access from unwanted users.
+.TP
+\fB-L\fR
+This option allows you to look at what services
+are available on a server. You use it as \fBsmbclient -L
+host\fR and a list should appear. The \fI-I
+\fRoption may be useful if your NetBIOS names don't
+match your TCP/IP DNS host names or if you are trying to reach a
+host on another network.
+.TP
+\fB-t terminal code\fR
+This option tells \fBsmbclient\fR how to interpret
+filenames coming from the remote server. Usually Asian language
+multibyte UNIX implementations use different character sets than
+SMB/CIFS servers (\fBEUC\fR instead of \fB SJIS\fR for example). Setting this parameter will let
+\fBsmbclient\fR convert between the UNIX filenames and
+the SMB filenames correctly. This option has not been seriously tested
+and may have some problems.
+
+The terminal codes include CWsjis, CWeuc, CWjis7, CWjis8,
+CWjunet, CWhex, CWcap. This is not a complete list, check the Samba
+source code for the complete list.
+.TP
+\fB-b buffersize\fR
+This option changes the transmit/send buffer
+size when getting or putting a file from/to the server. The default
+is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
+observed to speed up file transfers to and from a Win9x server.
+.TP
+\fB-W WORKGROUP\fR
+Override the default workgroup (domain) specified
+in the workgroup parameter of the \fIsmb.conf\fR
+file for this connection. This may be needed to connect to some
+servers.
+.TP
+\fB-T tar options\fR
+smbclient may be used to create \fBtar(1)
+\fRcompatible backups of all the files on an SMB/CIFS
+share. The secondary tar flags that can be given to this option
+are :
+.RS
+.TP 0.2i
+\(bu
+\fIc\fR - Create a tar file on UNIX.
+Must be followed by the name of a tar file, tape device
+or "-" for standard output. If using standard output you must
+turn the log level to its lowest value -d0 to avoid corrupting
+your tar file. This flag is mutually exclusive with the
+\fIx\fR flag.
+.TP 0.2i
+\(bu
+\fIx\fR - Extract (restore) a local
+tar file back to a share. Unless the -D option is given, the tar
+files will be restored from the top level of the share. Must be
+followed by the name of the tar file, device or "-" for standard
+input. Mutually exclusive with the \fIc\fR flag.
+Restored files have their creation times (mtime) set to the
+date saved in the tar file. Directories currently do not get
+their creation dates restored properly.
+.TP 0.2i
+\(bu
+\fII\fR - Include files and directories.
+Is the default behavior when filenames are specified above. Causes
+tar files to be included in an extract or create (and therefore
+everything else to be excluded). See example below. Filename globbing
+works in one of two ways. See r below.
+.TP 0.2i
+\(bu
+\fIX\fR - Exclude files and directories.
+Causes tar files to be excluded from an extract or create. See
+example below. Filename globbing works in one of two ways now.
+See \fIr\fR below.
+.TP 0.2i
+\(bu
+\fIb\fR - Blocksize. Must be followed
+by a valid (greater than zero) blocksize. Causes tar file to be
+written out in blocksize*TBLOCK (usually 512 byte) blocks.
+.TP 0.2i
+\(bu
+\fIg\fR - Incremental. Only back up
+files that have the archive bit set. Useful only with the
+\fIc\fR flag.
+.TP 0.2i
+\(bu
+\fIq\fR - Quiet. Keeps tar from printing
+diagnostics as it works. This is the same as tarmode quiet.
+.TP 0.2i
+\(bu
+\fIr\fR - Regular expression include
+or exclude. Uses regular expression matching for
+excluding or excluding files if compiled with HAVE_REGEX_H.
+However this mode can be very slow. If not compiled with
+HAVE_REGEX_H, does a limited wildcard match on '*' and '?'.
+.TP 0.2i
+\(bu
+\fIN\fR - Newer than. Must be followed
+by the name of a file whose date is compared against files found
+on the share during a create. Only files newer than the file
+specified are backed up to the tar file. Useful only with the
+\fIc\fR flag.
+.TP 0.2i
+\(bu
+\fIa\fR - Set archive bit. Causes the
+archive bit to be reset when a file is backed up. Useful with the
+\fIg\fR and \fIc\fR flags.
+.RE
+.PP
+\fBTar Long File Names\fR
+.PP
+.PP
+\fBsmbclient\fR's tar option now supports long
+file names both on backup and restore. However, the full path
+name of the file must be less than 1024 bytes. Also, when
+a tar archive is created, \fBsmbclient\fR's tar option places all
+files in the archive with relative names, not absolute names.
+.PP
+.PP
+\fBTar Filenames\fR
+.PP
+.PP
+All file names can be given as DOS path names (with '\\'
+as the component separator) or as UNIX path names (with '/' as
+the component separator).
+.PP
+.PP
+\fBExamples\fR
+.PP
+.PP
+Restore from tar file \fIbackup.tar\fR into myshare on mypc
+(no password on share).
+.PP
+.PP
+\fBsmbclient //mypc/yshare "" -N -Tx backup.tar
+\fR.PP
+.PP
+Restore everything except \fIusers/docs\fR
+.PP
+.PP
+\fBsmbclient //mypc/myshare "" -N -TXx backup.tar
+users/docs\fR
+.PP
+.PP
+Create a tar file of the files beneath \fI users/docs\fR.
+.PP
+.PP
+\fBsmbclient //mypc/myshare "" -N -Tc
+backup.tar users/docs \fR
+.PP
+.PP
+Create the same tar file as above, but now use
+a DOS path name.
+.PP
+.PP
+\fBsmbclient //mypc/myshare "" -N -tc backup.tar
+users\\edocs \fR
+.PP
+.PP
+Create a tar file of all the files and directories in
+the share.
+.PP
+.PP
+\fBsmbclient //mypc/myshare "" -N -Tc backup.tar *
+\fR.PP
+.TP
+\fB-D initial directory\fR
+Change to initial directory before starting. Probably
+only of any use with the tar -T option.
+.TP
+\fB-c command string\fR
+command string is a semicolon-separated list of
+commands to be executed instead of prompting from stdin. \fI -N\fR is implied by \fI-c\fR.
+
+This is particularly useful in scripts and for printing stdin
+to the server, e.g. \fB-c 'print -'\fR.
+.SH "OPERATIONS"
+.PP
+Once the client is running, the user is presented with
+a prompt :
+.PP
+smb:\\>
+.PP
+The backslash ("\\") indicates the current working directory
+on the server, and will change if the current working directory
+is changed.
+.PP
+The prompt indicates that the client is ready and waiting to
+carry out a user command. Each command is a single word, optionally
+followed by parameters specific to that command. Command and parameters
+are space-delimited unless these notes specifically
+state otherwise. All commands are case-insensitive. Parameters to
+commands may or may not be case sensitive, depending on the command.
+.PP
+You can specify file names which have spaces in them by quoting
+the name with double quotes, for example "a long file name".
+.PP
+Parameters shown in square brackets (e.g., "[parameter]") are
+optional. If not given, the command will use suitable defaults. Parameters
+shown in angle brackets (e.g., "<parameter>") are required.
+.PP
+Note that all commands operating on the server are actually
+performed by issuing a request to the server. Thus the behavior may
+vary from server to server, depending on how the server was implemented.
+.PP
+The commands available are given here in alphabetical order.
+.TP
+\fB? [command]\fR
+If \fIcommand\fR is specified, the ? command will display
+a brief informative message about the specified command. If no
+command is specified, a list of available commands will
+be displayed.
+.TP
+\fB! [shell command]\fR
+If \fIshell command\fR is specified, the !
+command will execute a shell locally and run the specified shell
+command. If no command is specified, a local shell will be run.
+.TP
+\fBaltname file\fR
+The client will request that the server return
+the "alternate" name (the 8.3 name) for a file or directory.
+.TP
+\fBcancel jobid0 [jobid1] ... [jobidN]\fR
+The client will request that the server cancel
+the printjobs identified by the given numeric print job ids.
+.TP
+\fBchmod file mode in octal\fR
+This command depends on the server supporting the CIFS
+UNIX extensions and will fail if the server does not. The client requests that the server
+change the UNIX permissions to the given octal mode, in standard UNIX format.
+.TP
+\fBchown file uid gid\fR
+This command depends on the server supporting the CIFS
+UNIX extensions and will fail if the server does not. The client requests that the server
+change the UNIX user and group ownership to the given decimal values. Note there is
+currently no way to remotely look up the UNIX uid and gid values for a given name.
+This may be addressed in future versions of the CIFS UNIX extensions.
+.TP
+\fBcd [directory name]\fR
+If "directory name" is specified, the current
+working directory on the server will be changed to the directory
+specified. This operation will fail if for any reason the specified
+directory is inaccessible.
+
+If no directory name is specified, the current working
+directory on the server will be reported.
+.TP
+\fBdel <mask>\fR
+The client will request that the server attempt
+to delete all files matching \fImask\fR from the current working
+directory on the server.
+.TP
+\fBdir <mask>\fR
+A list of the files matching \fImask\fR in the current
+working directory on the server will be retrieved from the server
+and displayed.
+.TP
+\fBexit\fR
+Terminate the connection with the server and exit
+from the program.
+.TP
+\fBget <remote file name> [local file name]\fR
+Copy the file called \fIremote file name\fR from
+the server to the machine running the client. If specified, name
+the local copy \fIlocal file name\fR. Note that all transfers in
+\fBsmbclient\fR are binary. See also the
+lowercase command.
+.TP
+\fBhelp [command]\fR
+See the ? command above.
+.TP
+\fBlcd [directory name]\fR
+If \fIdirectory name\fR is specified, the current
+working directory on the local machine will be changed to
+the directory specified. This operation will fail if for any
+reason the specified directory is inaccessible.
+
+If no directory name is specified, the name of the
+current working directory on the local machine will be reported.
+.TP
+\fBlink source destination\fR
+This command depends on the server supporting the CIFS
+UNIX extensions and will fail if the server does not. The client requests that the server
+create a hard link between the source and destination files. The source file
+must not exist.
+.TP
+\fBlowercase\fR
+Toggle lowercasing of filenames for the get and
+mget commands.
+
+When lowercasing is toggled ON, local filenames are converted
+to lowercase when using the get and mget commands. This is
+often useful when copying (say) MSDOS files from a server, because
+lowercase filenames are the norm on UNIX systems.
+.TP
+\fBls <mask>\fR
+See the dir command above.
+.TP
+\fBmask <mask>\fR
+This command allows the user to set up a mask
+which will be used during recursive operation of the mget and
+mput commands.
+
+The masks specified to the mget and mput commands act as
+filters for directories rather than files when recursion is
+toggled ON.
+
+The mask specified with the mask command is necessary
+to filter files within those directories. For example, if the
+mask specified in an mget command is "source*" and the mask
+specified with the mask command is "*.c" and recursion is
+toggled ON, the mget command will retrieve all files matching
+"*.c" in all directories below and including all directories
+matching "source*" in the current working directory.
+
+Note that the value for mask defaults to blank (equivalent
+to "*") and remains so until the mask command is used to change it.
+It retains the most recently specified value indefinitely. To
+avoid unexpected results it would be wise to change the value of
+mask back to "*" after using the mget or mput commands.
+.TP
+\fBmd <directory name>\fR
+See the mkdir command.
+.TP
+\fBmget <mask>\fR
+Copy all files matching \fImask\fR from the server to
+the machine running the client.
+
+Note that \fImask\fR is interpreted differently during recursive
+operation and non-recursive operation - refer to the recurse and
+mask commands for more information. Note that all transfers in
+\fBsmbclient\fR are binary. See also the lowercase command.
+.TP
+\fBmkdir <directory name>\fR
+Create a new directory on the server (user access
+privileges permitting) with the specified name.
+.TP
+\fBmput <mask>\fR
+Copy all files matching \fImask\fR in the current working
+directory on the local machine to the current working directory on
+the server.
+
+Note that \fImask\fR is interpreted differently during recursive
+operation and non-recursive operation - refer to the recurse and mask
+commands for more information. Note that all transfers in \fBsmbclient\fR
+are binary.
+.TP
+\fBprint <file name>\fR
+Print the specified file from the local machine
+through a printable service on the server.
+
+See also the printmode command.
+.TP
+\fBprintmode <graphics or text>\fR
+Set the print mode to suit either binary data
+(such as graphical information) or text. Subsequent print
+commands will use the currently set print mode.
+.TP
+\fBprompt\fR
+Toggle prompting for filenames during operation
+of the mget and mput commands.
+
+When toggled ON, the user will be prompted to confirm
+the transfer of each file during these commands. When toggled
+OFF, all specified files will be transferred without prompting.
+.TP
+\fBput <local file name> [remote file name]\fR
+Copy the file called \fIlocal file name\fR from the
+machine running the client to the server. If specified,
+name the remote copy \fIremote file name\fR. Note that all transfers
+in \fBsmbclient\fR are binary. See also the lowercase command.
+.TP
+\fBqueue\fR
+Displays the print queue, showing the job id,
+name, size and current status.
+.TP
+\fBquit\fR
+See the exit command.
+.TP
+\fBrd <directory name>\fR
+See the rmdir command.
+.TP
+\fBrecurse\fR
+Toggle directory recursion for the commands mget
+and mput.
+
+When toggled ON, these commands will process all directories
+in the source directory (i.e., the directory they are copying
+from ) and will recurse into any that match the mask specified
+to the command. Only files that match the mask specified using
+the mask command will be retrieved. See also the mask command.
+
+When recursion is toggled OFF, only files from the current
+working directory on the source machine that match the mask specified
+to the mget or mput commands will be copied, and any mask specified
+using the mask command will be ignored.
+.TP
+\fBrm <mask>\fR
+Remove all files matching \fImask\fR from the current
+working directory on the server.
+.TP
+\fBrmdir <directory name>\fR
+Remove the specified directory (user access
+privileges permitting) from the server.
+.TP
+\fBsetmode <filename> <perm=[+|\\-]rsha>\fR
+A version of the DOS attrib command to set
+file permissions. For example:
+
+\fBsetmode myfile +r \fR
+
+would make myfile read only.
+.TP
+\fBsymlink source destination\fR
+This command depends on the server supporting the CIFS
+UNIX extensions and will fail if the server does not. The client requests that the server
+create a symbolic hard link between the source and destination files. The source file
+must not exist. Note that the server will not create a link to any path that lies
+outside the currently connected share. This is enforced by the Samba server.
+.TP
+\fBtar <c|x>[IXbgNa]\fR
+Performs a tar operation - see the \fI-T
+\fRcommand line option above. Behavior may be affected
+by the tarmode command (see below). Using g (incremental) and N
+(newer) will affect tarmode settings. Note that using the "-" option
+with tar x may not work - use the command line option instead.
+.TP
+\fBblocksize <blocksize>\fR
+Blocksize. Must be followed by a valid (greater
+than zero) blocksize. Causes tar file to be written out in
+\fIblocksize\fR*TBLOCK (usually 512 byte) blocks.
+.TP
+\fBtarmode <full|inc|reset|noreset>\fR
+Changes tar's behavior with regard to archive
+bits. In full mode, tar will back up everything regardless of the
+archive bit setting (this is the default mode). In incremental mode,
+tar will only back up files with the archive bit set. In reset mode,
+tar will reset the archive bit on all files it backs up (implies
+read/write share).
+.SH "NOTES"
+.PP
+Some servers are fussy about the case of supplied usernames,
+passwords, share names (AKA service names) and machine names.
+If you fail to connect try giving all parameters in uppercase.
+.PP
+It is often necessary to use the -n option when connecting
+to some types of servers. For example OS/2 LanManager insists
+on a valid NetBIOS name being used, so you need to supply a valid
+name that would be known to the server.
+.PP
+smbclient supports long file names where the server
+supports the LANMAN2 protocol or above.
+.SH "ENVIRONMENT VARIABLES"
+.PP
+The variable \fBUSER\fR may contain the
+username of the person using the client. This information is
+used only if the protocol level is high enough to support
+session-level passwords.
+.PP
+The variable \fBPASSWD\fR may contain
+the password of the person using the client. This information is
+used only if the protocol level is high enough to support
+session-level passwords.
+.PP
+The variable \fBLIBSMB_PROG\fR may contain
+the path, executed with system(), which the client should connect
+to instead of connecting to a server. This functionality is primarily
+intended as a development aid, and works best when using a LMHOSTS
+file
+.SH "INSTALLATION"
+.PP
+The location of the client program is a matter for
+individual system administrators. The following are thus
+suggestions only.
+.PP
+It is recommended that the smbclient software be installed
+in the \fI/usr/local/samba/bin/\fR or \fI /usr/samba/bin/\fR directory, this directory readable
+by all, writeable only by root. The client program itself should
+be executable by all. The client should \fBNOT\fR be
+setuid or setgid!
+.PP
+The client log files should be put in a directory readable
+and writeable only by the user.
+.PP
+To test the client, you will need to know the name of a
+running SMB/CIFS server. It is possible to run \fBsmbd(8)
+\fRas an ordinary user - running that server as a daemon
+on a user-accessible port (typically any port number over 1024)
+would provide a suitable test server.
+.SH "DIAGNOSTICS"
+.PP
+Most diagnostics issued by the client are logged in a
+specified log file. The log file name is specified at compile time,
+but may be overridden on the command line.
+.PP
+The number and nature of diagnostics available depends
+on the debug level used by the client. If you have problems,
+set the debug level to 3 and peruse the log files.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbcontrol.1 b/docs/manpages/smbcontrol.1
new file mode 100755
index 00000000000..06bf845b1fb
--- /dev/null
+++ b/docs/manpages/smbcontrol.1
@@ -0,0 +1,129 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBCONTROL" "1" "19 November 2002" "" ""
+.SH NAME
+smbcontrol \- send messages to smbd, nmbd or winbindd processes
+.SH SYNOPSIS
+.sp
+\fBsmbcontrol\fR [ \fB-d <debug level>\fR ] [ \fB-s <smb config file>\fR ] \fB-i\fR
+.sp
+\fBsmbcontrol\fR [ \fB-d <debug level>\fR ] [ \fB-s <smb config file>\fR ] \fBdestination\fR \fBmessage-type\fR [ \fBparameter\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBsmbcontrol\fR is a very small program, which
+sends messages to an smbd(8)
+an nmbd(8)
+or a winbindd(8)
+daemon running on the system.
+.SH "OPTIONS"
+.TP
+\fB-d <debuglevel>\fR
+debuglevel is an integer from 0 to 10.
+.TP
+\fB-s <smb.conf>\fR
+This parameter specifies the pathname to
+the Samba configuration file, smb.conf(5) This file controls all aspects of
+the Samba setup on the machine.
+.TP
+\fB-i\fR
+Run interactively. Individual commands
+of the form destination message-type parameters can be entered
+on STDIN. An empty command line or a "q" will quit the
+program.
+.TP
+\fBdestination\fR
+One of \fInmbd\fR
+\fIsmbd\fR or a process ID.
+
+The \fIsmbd\fR destination causes the
+message to "broadcast" to all smbd daemons.
+
+The \fInmbd\fR destination causes the
+message to be sent to the nmbd daemon specified in the
+\fInmbd.pid\fR file.
+
+If a single process ID is given, the message is sent
+to only that process.
+.TP
+\fBmessage-type\fR
+One of: close-share,
+debug,
+force-election, ping
+, profile, debuglevel, profilelevel,
+or printer-notify.
+
+The close-share message-type sends a
+message to smbd which will then close the client connections to
+the named share. Note that this doesn't affect client connections
+to any other shares. This message-type takes an argument of the
+share name for which client connections will be closed, or the
+"*" character which will close all currently open shares.
+This may be useful if you made changes to the access controls on the share.
+This message can only be sent to smbd.
+
+The debug message-type allows
+the debug level to be set to the value specified by the
+parameter. This can be sent to any of the destinations.
+
+The force-election message-type can only be
+sent to the nmbd destination. This message
+causes the \fBnmbd\fR daemon to force a new browse
+master election.
+
+The ping message-type sends the
+number of "ping" messages specified by the parameter and waits
+for the same number of reply "pong" messages. This can be sent to
+any of the destinations.
+
+The profile message-type sends a
+message to an smbd to change the profile settings based on the
+parameter. The parameter can be "on" to turn on profile stats
+collection, "off" to turn off profile stats collection, "count"
+to enable only collection of count stats (time stats are
+disabled), and "flush" to zero the current profile stats. This can
+be sent to any smbd or nmbd destinations.
+
+The debuglevel message-type sends
+a "request debug level" message. The current debug level setting
+is returned by a "debuglevel" message. This can be
+sent to any of the destinations.
+
+The profilelevel message-type sends
+a "request profile level" message. The current profile level
+setting is returned by a "profilelevel" message. This can be sent
+to any smbd or nmbd destinations.
+
+The printer-notify message-type sends a
+message to smbd which in turn sends a printer notify message to
+any Windows NT clients connected to a printer. This message-type
+takes an argument of the printer name to send notify messages to.
+This message can only be sent to smbd.
+.TP
+\fBparameters\fR
+any parameters required for the message-type
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBnmbd(8)\fR
+and \fBsmbd(8)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbd.8 b/docs/manpages/smbd.8
new file mode 100755
index 00000000000..6114b5b7cc7
--- /dev/null
+++ b/docs/manpages/smbd.8
@@ -0,0 +1,316 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBD" "8" "19 November 2002" "" ""
+.SH NAME
+smbd \- server to provide SMB/CIFS services to clients
+.SH SYNOPSIS
+.sp
+\fBsmbd\fR [ \fB-D\fR ] [ \fB-a\fR ] [ \fB-i\fR ] [ \fB-o\fR ] [ \fB-P\fR ] [ \fB-h\fR ] [ \fB-V\fR ] [ \fB-d <debug level>\fR ] [ \fB-l <log directory>\fR ] [ \fB-p <port number>\fR ] [ \fB-O <socket option>\fR ] [ \fB-s <configuration file>\fR ]
+.SH "DESCRIPTION"
+.PP
+This program is part of the Samba suite.
+.PP
+\fBsmbd\fR is the server daemon that
+provides filesharing and printing services to Windows clients.
+The server provides filespace and printer services to
+clients using the SMB (or CIFS) protocol. This is compatible
+with the LanManager protocol, and can service LanManager
+clients. These include MSCLIENT 3.0 for DOS, Windows for
+Workgroups, Windows 95/98/ME, Windows NT, Windows 2000,
+OS/2, DAVE for Macintosh, and smbfs for Linux.
+.PP
+An extensive description of the services that the
+server can provide is given in the man page for the
+configuration file controlling the attributes of those
+services (see \fIsmb.conf(5)
+\fR This man page will not describe the
+services, but will concentrate on the administrative aspects
+of running the server.
+.PP
+Please note that there are significant security
+implications to running this server, and the \fIsmb.conf(5)\fR
+manpage should be regarded as mandatory reading before
+proceeding with installation.
+.PP
+A session is created whenever a client requests one.
+Each client gets a copy of the server for each session. This
+copy then services all connections made by the client during
+that session. When all connections from its client are closed,
+the copy of the server for that client terminates.
+.PP
+The configuration file, and any files that it includes,
+are automatically reloaded every minute, if they change. You
+can force a reload by sending a SIGHUP to the server. Reloading
+the configuration file will not affect connections to any service
+that is already established. Either the user will have to
+disconnect from the service, or \fBsmbd\fR killed and restarted.
+.SH "OPTIONS"
+.TP
+\fB-D\fR
+If specified, this parameter causes
+the server to operate as a daemon. That is, it detaches
+itself and runs in the background, fielding requests
+on the appropriate port. Operating the server as a
+daemon is the recommended way of running \fBsmbd\fR for
+servers that provide more than casual use file and
+print services. This switch is assumed if \fBsmbd
+\fRis executed on the command line of a shell.
+.TP
+\fB-a\fR
+If this parameter is specified, each new
+connection will append log messages to the log file.
+This is the default.
+.TP
+\fB-i\fR
+If this parameter is specified it causes the
+server to run "interactively", not as a daemon, even if the
+server is executed on the command line of a shell. Setting this
+parameter negates the implicit deamon mode when run from the
+command line.
+.TP
+\fB-o\fR
+If this parameter is specified, the
+log files will be overwritten when opened. By default,
+\fBsmbd\fR will append entries to the log
+files.
+.TP
+\fB-P\fR
+Passive option. Causes \fBsmbd\fR not to
+send any network traffic out. Used for debugging by
+the developers only.
+.TP
+\fB-h\fR
+Prints the help information (usage)
+for \fBsmbd\fR.
+.TP
+\fB-v\fR
+Prints the version number for
+\fBsmbd\fR.
+.TP
+\fB-d <debug level>\fR
+\fIdebuglevel\fR is an integer
+from 0 to 10. The default value if this parameter is
+not specified is zero.
+
+The higher this value, the more detail will be
+logged to the log files about the activities of the
+server. At level 0, only critical errors and serious
+warnings will be logged. Level 1 is a reasonable level for
+day to day running - it generates a small amount of
+information about operations carried out.
+
+Levels above 1 will generate considerable
+amounts of log data, and should only be used when
+investigating a problem. Levels above 3 are designed for
+use only by developers and generate HUGE amounts of log
+data, most of which is extremely cryptic.
+
+Note that specifying this parameter here will
+override the log
+level file.
+.TP
+\fB-l <log directory>\fR
+If specified,
+\fIlog directory\fR
+specifies a log directory into which the "log.smbd" log
+file will be created for informational and debug
+messages from the running server. The log
+file generated is never removed by the server although
+its size may be controlled by the max log size
+option in the \fI smb.conf(5)\fR file. \fBBeware:\fR
+If the directory specified does not exist, \fBsmbd\fR
+will log to the default debug log location defined at compile time.
+
+The default log directory is specified at
+compile time.
+.TP
+\fB-O <socket options>\fR
+See the socket options
+parameter in the \fIsmb.conf(5)
+\fR file for details.
+.TP
+\fB-p <port number>\fR
+\fIport number\fR is a positive integer
+value. The default value if this parameter is not
+specified is 139.
+
+This number is the port number that will be
+used when making connections to the server from client
+software. The standard (well-known) port number for the
+SMB over TCP is 139, hence the default. If you wish to
+run the server as an ordinary user rather than
+as root, most systems will require you to use a port
+number greater than 1024 - ask your system administrator
+for help if you are in this situation.
+
+In order for the server to be useful by most
+clients, should you configure it on a port other
+than 139, you will require port redirection services
+on port 139, details of which are outlined in rfc1002.txt
+section 4.3.5.
+
+This parameter is not normally specified except
+in the above situation.
+.TP
+\fB-s <configuration file>\fR
+The file specified contains the
+configuration details required by the server. The
+information in this file includes server-specific
+information such as what printcap file to use, as well
+as descriptions of all the services that the server is
+to provide. See \fI smb.conf(5)\fR for more information.
+The default configuration file name is determined at
+compile time.
+.SH "FILES"
+.TP
+\fB\fI/etc/inetd.conf\fB\fR
+If the server is to be run by the
+\fBinetd\fR meta-daemon, this file
+must contain suitable startup information for the
+meta-daemon. See the UNIX_INSTALL.html
+document for details.
+.TP
+\fB\fI/etc/rc\fB\fR
+or whatever initialization script your
+system uses).
+
+If running the server as a daemon at startup,
+this file will need to contain an appropriate startup
+sequence for the server. See the UNIX_INSTALL.html
+document for details.
+.TP
+\fB\fI/etc/services\fB\fR
+If running the server via the
+meta-daemon \fBinetd\fR, this file
+must contain a mapping of service name (e.g., netbios-ssn)
+to service port (e.g., 139) and protocol type (e.g., tcp).
+See the UNIX_INSTALL.html
+document for details.
+.TP
+\fB\fI/usr/local/samba/lib/smb.conf\fB\fR
+This is the default location of the
+\fIsmb.conf\fR
+server configuration file. Other common places that systems
+install this file are \fI/usr/samba/lib/smb.conf\fR
+and \fI/etc/smb.conf\fR.
+
+This file describes all the services the server
+is to make available to clients. See \fIsmb.conf(5)\fR for more information.
+.SH "LIMITATIONS"
+.PP
+On some systems \fBsmbd\fR cannot change uid back
+to root after a setuid() call. Such systems are called
+trapdoor uid systems. If you have such a system,
+you will be unable to connect from a client (such as a PC) as
+two different users at once. Attempts to connect the
+second user will result in access denied or
+similar.
+.SH "ENVIRONMENT VARIABLES"
+.TP
+\fBPRINTER\fR
+If no printer name is specified to
+printable services, most systems will use the value of
+this variable (or lp if this variable is
+not defined) as the name of the printer to use. This
+is not specific to the server, however.
+.SH "PAM INTERACTION"
+.PP
+Samba uses PAM for authentication (when presented with a plaintext
+password), for account checking (is this account disabled?) and for
+session management. The degree too which samba supports PAM is restricted
+by the limitations of the SMB protocol and the
+obey pam restricions
+smb.conf paramater. When this is set, the following restrictions apply:
+.TP 0.2i
+\(bu
+\fBAccount Validation\fR: All acccesses to a
+samba server are checked
+against PAM to see if the account is vaild, not disabled and is permitted to
+login at this time. This also applies to encrypted logins.
+.TP 0.2i
+\(bu
+\fBSession Management\fR: When not using share
+level secuirty, users must pass PAM's session checks before access
+is granted. Note however, that this is bypassed in share level secuirty.
+Note also that some older pam configuration files may need a line
+added for session support.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "TROUBLESHOOTING"
+.PP
+One of the common causes of difficulty when installing Samba and SWAT
+is the existsnece of some type of firewall or port filtering software
+on the Samba server. Make sure that the appropriate ports
+outlined in this man page are available on the server and are not currently
+being blocked by some type of security software such as iptables or
+"port sentry". For more troubleshooting information, refer to the additional
+documentation included in the Samba distribution.
+.PP
+Most diagnostics issued by the server are logged
+in a specified log file. The log file name is specified
+at compile time, but may be overridden on the command line.
+.PP
+The number and nature of diagnostics available depends
+on the debug level used by the server. If you have problems, set
+the debug level to 3 and peruse the log files.
+.PP
+Most messages are reasonably self-explanatory. Unfortunately,
+at the time this man page was created, there are too many diagnostics
+available in the source code to warrant describing each and every
+diagnostic. At this stage your best bet is still to grep the
+source code and inspect the conditions that gave rise to the
+diagnostics you are seeing.
+.SH "SIGNALS"
+.PP
+Sending the \fBsmbd\fR a SIGHUP will cause it to
+reload its \fIsmb.conf\fR configuration
+file within a short period of time.
+.PP
+To shut down a user's \fBsmbd\fR process it is recommended
+that \fBSIGKILL (-9)\fR \fBNOT\fR
+be used, except as a last resort, as this may leave the shared
+memory area in an inconsistent state. The safe way to terminate
+an \fBsmbd\fR is to send it a SIGTERM (-15) signal and wait for
+it to die on its own.
+.PP
+The debug log level of \fBsmbd\fR may be raised
+or lowered using \fBsmbcontrol(1)
+\fR program (SIGUSR[1|2] signals are no longer used in
+Samba 2.2). This is to allow transient problems to be diagnosed,
+whilst still running at a normally low log level.
+.PP
+Note that as the signal handlers send a debug write,
+they are not re-entrant in \fBsmbd\fR. This you should wait until
+\fBsmbd\fR is in a state of waiting for an incoming SMB before
+issuing them. It is possible to make the signal handlers safe
+by un-blocking the signals before the select call and re-blocking
+them after, however this would affect performance.
+.SH "SEE ALSO"
+.PP
+hosts_access(5), \fBinetd(8)\fR,
+\fBnmbd(8)\fR
+\fIsmb.conf(5)\fR
+ \fBsmbclient(1)
+\fR and the Internet RFC's
+\fIrfc1001.txt\fR, \fIrfc1002.txt\fR.
+In addition the CIFS (formerly SMB) specification is available
+as a link from the Web page
+http://samba.org/cifs/ <URL:http://samba.org/cifs/>.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbmnt.8 b/docs/manpages/smbmnt.8
new file mode 100755
index 00000000000..4da76c737d6
--- /dev/null
+++ b/docs/manpages/smbmnt.8
@@ -0,0 +1,63 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBMNT" "8" "19 November 2002" "" ""
+.SH NAME
+smbmnt \- helper utility for mounting SMB filesystems
+.SH SYNOPSIS
+.sp
+\fBsmbmnt\fR \fBmount-point\fR [ \fB-s <share>\fR ] [ \fB-r\fR ] [ \fB-u <uid>\fR ] [ \fB-g <gid>\fR ] [ \fB-f <mask>\fR ] [ \fB-d <mask>\fR ] [ \fB-o <options>\fR ]
+.SH "DESCRIPTION"
+.PP
+\fBsmbmnt\fR is a helper application used
+by the smbmount program to do the actual mounting of SMB shares.
+\fBsmbmnt\fR can be installed setuid root if you want
+normal users to be able to mount their SMB shares.
+.PP
+A setuid smbmnt will only allow mounts on directories owned
+by the user, and that the user has write permission on.
+.PP
+The \fBsmbmnt\fR program is normally invoked
+by \fBsmbmount(8)\fR
+ It should not be invoked directly by users.
+.PP
+smbmount searches the normal PATH for smbmnt. You must ensure
+that the smbmnt version in your path matches the smbmount used.
+.SH "OPTIONS"
+.TP
+\fB-r\fR
+mount the filesystem read-only
+.TP
+\fB-u uid\fR
+specify the uid that the files will
+be owned by
+.TP
+\fB-g gid\fR
+specify the gid that the files will be
+owned by
+.TP
+\fB-f mask\fR
+specify the octal file mask applied
+.TP
+\fB-d mask\fR
+specify the octal directory mask
+applied
+.TP
+\fB-o options\fR
+list of options that are passed as-is to smbfs, if this
+command is run on a 2.4 or higher Linux kernel.
+.SH "AUTHOR"
+.PP
+Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+and others.
+.PP
+The current maintainer of smbfs and the userspace
+tools \fBsmbmount\fR, \fBsmbumount\fR,
+and \fBsmbmnt\fR is Urban Widmark <URL:mailto:urban@teststation.com>.
+The SAMBA Mailing list <URL:mailto:samba@samba.org>
+is the preferred place to ask questions regarding these programs.
+.PP
+The conversion of this manpage for Samba 2.2 was performed
+by Gerald Carter
diff --git a/packaging/Mandrake/mount.cifs.8 b/docs/manpages/smbmount.8
index 7ab1be305c2..b195b80c733 100644..100755
--- a/packaging/Mandrake/mount.cifs.8
+++ b/docs/manpages/smbmount.8
@@ -1,57 +1,58 @@
-.\" This manpage has been automatically generated by docbook2man
-.\" from a DocBook document. This tool can be found at:
-.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "MOUNT.CIFS" "8" "03 August 2002" "" ""
+.TH "SMBMOUNT" "8" "19 November 2002" "" ""
.SH NAME
-mount.cifs \- mount using the Common Internet File System (CIFS)
+smbmount \- mount an smbfs filesystem
.SH SYNOPSIS
-
-\fBmount.cifs\fR \fBservice\fR \fBmount-point\fR [ \fB-o options\fR]
-
+.sp
+\fBsmbmount\fR \fBservice\fR \fBmount-point\fR [ \fB-o options\fR ]
.SH "DESCRIPTION"
.PP
-\fBmount.cifs\fR mounts a Linux CIFS filesystem. It
-is usually invoked as \fBmount.cifs\fR by
+\fBsmbmount\fR mounts a Linux SMB filesystem. It
+is usually invoked as \fBmount.smbfs\fR by
the \fBmount(8)\fR command when using the
-"-t cifs" option. This command only works in Linux, and the kernel must
-support the cifs filesystem. The CIFS protocol is the successor to the
-SMB protocol and is supported by most Windows servers and many other
-commercial servers and Network Attached Storage appliances as well as
-by the popular Open Source server Samba.
+"-t smbfs" option. This command only works in Linux, and the kernel must
+support the smbfs filesystem.
.PP
-Options to \fBmount.cifs\fR are specified as a comma-separated
+Options to \fBsmbmount\fR are specified as a comma-separated
list of key=value pairs. It is possible to send options other
-than those listed here, assuming that cifs supports them. If
+than those listed here, assuming that smbfs supports them. If
you get mount failures, check your kernel log for errors on
unknown options.
.PP
-\fBmount.cifs\fR is a daemon. After mounting it keeps running until
-the mounted cifs is umounted. It will log things that happen
-when in daemon mode using the "machine name" mount.cifs, so
-typically this output will end up in
-\fIlog.mount.cifs\fR.
+\fBsmbmount\fR is a daemon. After mounting it keeps running until
+the mounted smbfs is umounted. It will log things that happen
+when in daemon mode using the "machine name" smbmount, so
+typically this output will end up in \fIlog.smbmount\fR. The
+\fBsmbmount\fR process may also be called mount.smbfs.
+.PP
+\fBNOTE:\fR \fBsmbmount\fR
+calls \fBsmbmnt(8)\fR to do the actual mount. You
+must make sure that \fBsmbmnt\fR is in the path so
+that it can be found.
.SH "OPTIONS"
.TP
\fBusername=<arg>\fR
specifies the username to connect as. If
-this is not given, then the environment variable \fB USER\fR is used. This option can also take the
+this is not given, then the environment variable \fB USER\fR is used. This option can also take the
form "user%password" or "user/workgroup" or
"user/workgroup%password" to allow the password and workgroup
to be specified as part of the username.
.TP
\fBpassword=<arg>\fR
-specifies the CIFS password. If this
+specifies the SMB password. If this
option is not given then the environment variable
\fBPASSWD\fR is used. If it can find
-no password \fBmount.cifs\fR will prompt
+no password \fBsmbmount\fR will prompt
for a passeword, unless the guest option is
given.
Note that password which contain the arguement delimiter
character (i.e. a comma ',') will failed to be parsed correctly
-on the command line. However, the same password defined
+on the command line. However, the same password defined
in the PASSWD environment variable or a credentials file (see
below) will be read correctly.
.TP
@@ -59,17 +60,22 @@ below) will be read correctly.
specifies a file that contains a username
and/or password. The format of the file is:
-
+.sp
.nf
username = <value>
password = <value>
+.sp
.fi
This is preferred over having passwords in plaintext in a
shared file, such as \fI/etc/fstab\fR. Be sure to protect any
credentials file properly.
.TP
+\fBnetbiosname=<arg>\fR
+sets the source NetBIOS name. It defaults
+to the local hostname.
+.TP
\fBuid=<arg>\fR
sets the uid that will own all files on
the mounted filesystem.
@@ -82,8 +88,8 @@ It may be specified as either a groupname or a numeric
gid.
.TP
\fBport=<arg>\fR
-sets the remote cifs port number. By default
-port 445 is tried then if no response port 139 is tried.
+sets the remote SMB port number. The default
+is 139.
.TP
\fBfmask=<arg>\fR
sets the file mask. This determines the
@@ -97,15 +103,22 @@ The default is based on the current umask.
.TP
\fBdebug=<arg>\fR
sets the debug level. This is useful for
-tracking down cifs connection problems. A suggested value to
+tracking down SMB connection problems. A suggested value to
start with is 4. If set too high there will be a lot of
output, possibly hiding the useful output.
.TP
\fBip=<arg>\fR
sets the destination host or IP address.
.TP
-\fBdomain=<arg>\fR
-sets the domain (workgroup) of the user
+\fBworkgroup=<arg>\fR
+sets the workgroup on the destination
+.TP
+\fBsockopt=<arg>\fR
+sets the TCP socket options. See the \fIsmb.conf
+\fR \fIsocket options\fR option.
+.TP
+\fBscope=<arg>\fR
+sets the NetBIOS scope
.TP
\fBguest\fR
don't prompt for a password
@@ -140,13 +153,13 @@ in many cases.
.SH "ENVIRONMENT VARIABLES"
.PP
The variable \fBUSER\fR may contain the username of the
-person using the client. This information is used only if the
+person using the client. This information is used only if the
protocol level is high enough to support session-level
passwords. The variable can be used to set both username and
password by using the format username%password.
.PP
The variable \fBPASSWD\fR may contain the password of the
-person using the client. This information is used only if the
+person using the client. This information is used only if the
protocol level is high enough to support session-level
passwords.
.PP
@@ -162,20 +175,42 @@ file or in the PASSWD environment.
The credentials file does not handle usernames or passwords with
leading space.
.PP
+One smbfs bug is important enough to mention here, even if it
+is a bit misplaced:
+.TP 0.2i
+\(bu
+Mounts sometimes stop working. This is usually
+caused by smbmount terminating. Since smbfs needs smbmount to
+reconnect when the server disconnects, the mount will eventually go
+dead. An umount/mount normally fixes this. At least 2 ways to
+trigger this bug are known.
+.PP
Note that the typical response to a bug report is suggestion
to try the latest version first. So please try doing that first,
and always include which versions you use of relevant software
when reporting bugs (minimum: samba, kernel, distribution)
+.PP
.SH "SEE ALSO"
.PP
-Documentation/filesystems/cifs.txt in the linux kernel
+Documentation/filesystems/smbfs.txt in the linux kernel
source tree may contain additional options and information.
+.PP
+FreeBSD also has a smbfs, but it is not related to smbmount
+.PP
+For Solaris, HP-UX and others you may want to look at
+\fBsmbsh(1)\fR or at other
+solutions, such as sharity or perhaps replacing the SMB server with
+a NFS server.
.SH "AUTHOR"
.PP
-Steve French
-The syntax and manpage were loosely based on that of smbmount.
+Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+and others.
.PP
-The current maintainer of the Linux cifs vfs and the userspace
-tool \fBmount.cifs\fR is Steve French <URL:mailto:sfrench@samba.org>.
+The current maintainer of smbfs and the userspace
+tools \fBsmbmount\fR, \fBsmbumount\fR,
+and \fBsmbmnt\fR is Urban Widmark <URL:mailto:urban@teststation.com>.
The SAMBA Mailing list <URL:mailto:samba@samba.org>
is the preferred place to ask questions regarding these programs.
+.PP
+The conversion of this manpage for Samba 2.2 was performed
+by Gerald Carter
diff --git a/docs/manpages/smbpasswd.5 b/docs/manpages/smbpasswd.5
new file mode 100755
index 00000000000..474429c9a51
--- /dev/null
+++ b/docs/manpages/smbpasswd.5
@@ -0,0 +1,159 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBPASSWD" "5" "19 November 2002" "" ""
+.SH NAME
+smbpasswd \- The Samba encrypted password file
+.SH SYNOPSIS
+.PP
+\fIsmbpasswd\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+smbpasswd is the Samba encrypted password file. It contains
+the username, Unix user id and the SMB hashed passwords of the
+user, as well as account flag information and the time the
+password was last changed. This file format has been evolving with
+Samba and has had several different formats in the past.
+.SH "FILE FORMAT"
+.PP
+The format of the smbpasswd file used by Samba 2.2
+is very similar to the familiar Unix \fIpasswd(5)\fR
+file. It is an ASCII file containing one line for each user. Each field
+within each line is separated from the next by a colon. Any entry
+beginning with '#' is ignored. The smbpasswd file contains the
+following information for each user:
+.TP
+\fBname\fR
+This is the user name. It must be a name that
+already exists in the standard UNIX passwd file.
+.TP
+\fBuid\fR
+This is the UNIX uid. It must match the uid
+field for the same user entry in the standard UNIX passwd file.
+If this does not match then Samba will refuse to recognize
+this smbpasswd file entry as being valid for a user.
+.TP
+\fBLanman Password Hash\fR
+This is the LANMAN hash of the user's password,
+encoded as 32 hex digits. The LANMAN hash is created by DES
+encrypting a well known string with the user's password as the
+DES key. This is the same password used by Windows 95/98 machines.
+Note that this password hash is regarded as weak as it is
+vulnerable to dictionary attacks and if two users choose the
+same password this entry will be identical (i.e. the password
+is not "salted" as the UNIX password is). If the user has a
+null password this field will contain the characters "NO PASSWORD"
+as the start of the hex string. If the hex string is equal to
+32 'X' characters then the user's account is marked as
+disabled and the user will not be able to
+log onto the Samba server.
+
+\fBWARNING !!\fR Note that, due to
+the challenge-response nature of the SMB/CIFS authentication
+protocol, anyone with a knowledge of this password hash will
+be able to impersonate the user on the network. For this
+reason these hashes are known as \fBplain text
+equivalents\fR and must \fBNOT\fR be made
+available to anyone but the root user. To protect these passwords
+the smbpasswd file is placed in a directory with read and
+traverse access only to the root user and the smbpasswd file
+itself must be set to be read/write only by root, with no
+other access.
+.TP
+\fBNT Password Hash\fR
+This is the Windows NT hash of the user's
+password, encoded as 32 hex digits. The Windows NT hash is
+created by taking the user's password as represented in
+16-bit, little-endian UNICODE and then applying the MD4
+(internet rfc1321) hashing algorithm to it.
+
+This password hash is considered more secure than
+the LANMAN Password Hash as it preserves the case of the
+password and uses a much higher quality hashing algorithm.
+However, it is still the case that if two users choose the same
+password this entry will be identical (i.e. the password is
+not "salted" as the UNIX password is).
+
+\fBWARNING !!\fR. Note that, due to
+the challenge-response nature of the SMB/CIFS authentication
+protocol, anyone with a knowledge of this password hash will
+be able to impersonate the user on the network. For this
+reason these hashes are known as \fBplain text
+equivalents\fR and must \fBNOT\fR be made
+available to anyone but the root user. To protect these passwords
+the smbpasswd file is placed in a directory with read and
+traverse access only to the root user and the smbpasswd file
+itself must be set to be read/write only by root, with no
+other access.
+.TP
+\fBAccount Flags\fR
+This section contains flags that describe
+the attributes of the users account. In the Samba 2.2 release
+this field is bracketed by '[' and ']' characters and is always
+13 characters in length (including the '[' and ']' characters).
+The contents of this field may be any of the characters.
+.RS
+.TP 0.2i
+\(bu
+\fBU\fR - This means
+this is a "User" account, i.e. an ordinary user. Only User
+and Workstation Trust accounts are currently supported
+in the smbpasswd file.
+.TP 0.2i
+\(bu
+\fBN\fR - This means the
+account has no password (the passwords in the fields LANMAN
+Password Hash and NT Password Hash are ignored). Note that this
+will only allow users to log on with no password if the \fI null passwords\fR parameter is set in the \fIsmb.conf(5)
+\fR config file.
+.TP 0.2i
+\(bu
+\fBD\fR - This means the account
+is disabled and no SMB/CIFS logins will be allowed for
+this user.
+.TP 0.2i
+\(bu
+\fBW\fR - This means this account
+is a "Workstation Trust" account. This kind of account is used
+in the Samba PDC code stream to allow Windows NT Workstations
+and Servers to join a Domain hosted by a Samba PDC.
+.RE
+.PP
+Other flags may be added as the code is extended in future.
+The rest of this field space is filled in with spaces.
+.PP
+.TP
+\fBLast Change Time\fR
+This field consists of the time the account was
+last modified. It consists of the characters 'LCT-' (standing for
+"Last Change Time") followed by a numeric encoding of the UNIX time
+in seconds since the epoch (1970) that the last change was made.
+.PP
+All other colon separated fields are ignored at this time.
+.PP
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbpasswd(8)\fR
+samba(7) and
+the Internet RFC1321 for details on the MD4 algorithm.
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbpasswd.8 b/docs/manpages/smbpasswd.8
new file mode 100755
index 00000000000..064788cef5b
--- /dev/null
+++ b/docs/manpages/smbpasswd.8
@@ -0,0 +1,387 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBPASSWD" "8" "30 March 2003" "" ""
+.SH NAME
+smbpasswd \- change a user's SMB password
+.SH SYNOPSIS
+.PP
+When run by root:
+.sp
+\fBsmbpasswd\fR [ \fBoptions\fR ] [ \fBusername\fR ] [ \fBpassword\fR ]
+.PP
+otherwise:
+.sp
+\fBsmbpasswd\fR [ \fBoptions\fR ] [ \fBpassword\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+The smbpasswd program has several different
+functions, depending on whether it is run by the \fBroot\fR
+user or not. When run as a normal user it allows the user to change
+the password used for their SMB sessions on any machines that store
+SMB passwords.
+.PP
+By default (when run with no arguments) it will attempt to
+change the current user's SMB password on the local machine. This is
+similar to the way the \fBpasswd(1)\fR program works.
+\fBsmbpasswd\fR differs from how the passwd program works
+however in that it is not \fBsetuid root\fR but works in
+a client-server mode and communicates with a locally running
+\fBsmbd(8)\fR. As a consequence in order for this to
+succeed the smbd daemon must be running on the local machine. On a
+UNIX machine the encrypted SMB passwords are usually stored in
+the \fIsmbpasswd(5)\fR file.
+.PP
+When run by an ordinary user with no options. smbpasswd
+will prompt them for their old SMB password and then ask them
+for their new password twice, to ensure that the new password
+was typed correctly. No passwords will be echoed on the screen
+whilst being typed. If you have a blank SMB password (specified by
+the string "NO PASSWORD" in the smbpasswd file) then just press
+the <Enter> key when asked for your old password.
+.PP
+smbpasswd can also be used by a normal user to change their
+SMB password on remote machines, such as Windows NT Primary Domain
+Controllers. See the (-r) and -U options below.
+.PP
+When run by root, smbpasswd allows new users to be added
+and deleted in the smbpasswd file, as well as allows changes to
+the attributes of the user in this file to be made. When run by root,
+\fBsmbpasswd\fR accesses the local smbpasswd file
+directly, thus enabling changes to be made even if smbd is not
+running.
+.PP
+\fBsmbpasswd\fR can also be used to retrieve
+the SIDs related to previous incarnations of this server on the
+same machine, as well as set the SID of this domain. This is needed
+in those cases when the admin changes the NetBIOS or DNS name of
+the server without realizing that doing so will change the SID of
+the server as well. See the -W and -X options below.
+.SH "OPTIONS"
+.TP
+\fB-L\fR
+Run the smbpasswd command in local mode. This
+allows a non-root user to specify the root-only options. This
+is used mostly in test environments where a non-root user needs
+to make changes to the local \fIsmbpasswd\fR file.
+The \fIsmbpasswd\fR file must have read/write
+permissions for the user running the command.
+.TP
+\fB-h\fR
+This option prints the help string for
+\fBsmbpasswd\fR.
+.TP
+\fB-c smb.conf file\fR
+This option specifies that the configuration
+file specified should be used instead of the default value
+specified at compile time.
+.TP
+\fB-D debuglevel\fR
+\fIdebuglevel\fR is an integer
+from 0 to 10. The default value if this parameter is not specified
+is zero.
+
+The higher this value, the more detail will be logged to the
+log files about the activities of smbpasswd. At level 0, only
+critical errors and serious warnings will be logged.
+
+Levels above 1 will generate considerable amounts of log
+data, and should only be used when investigating a problem. Levels
+above 3 are designed for use only by developers and generate
+HUGE amounts of log data, most of which is extremely cryptic.
+.TP
+\fB-r remote machine name\fR
+This option allows a user to specify what machine
+they wish to change their password on. Without this parameter
+smbpasswd defaults to the local host. The \fIremote
+machine name\fR is the NetBIOS name of the SMB/CIFS
+server to contact to attempt the password change. This name is
+resolved into an IP address using the standard name resolution
+mechanism in all programs of the Samba suite. See the \fI-R
+name resolve order\fR parameter for details on changing
+this resolving mechanism.
+
+The username whose password is changed is that of the
+current UNIX logged on user. See the \fI-U username\fR
+parameter for details on changing the password for a different
+username.
+
+Note that if changing a Windows NT Domain password the
+remote machine specified must be the Primary Domain Controller for
+the domain (Backup Domain Controllers only have a read-only
+copy of the user account database and will not allow the password
+change).
+
+\fBNote\fR that Windows 95/98 do not have
+a real password database so it is not possible to change passwords
+specifying a Win95/98 machine as remote machine target.
+.TP
+\fB-s\fR
+This option causes smbpasswd to be silent (i.e.
+not issue prompts) and to read its old and new passwords from
+standard input, rather than from \fI/dev/tty\fR
+(like the \fBpasswd(1)\fR program does). This option
+is to aid people writing scripts to drive smbpasswd
+.TP
+\fB-S\fR
+This option causes \fBsmbpasswd\fR
+to query a domain controller of the domain specified
+by the workgroup
+parameter in \fIsmb.conf\fR and store the
+domain SID in the \fIsecrets.tdb\fR file
+as its own machine SID. This is only useful when configuring
+a Samba PDC and Samba BDC, or when migrating from a Windows PDC
+to a Samba PDC.
+
+The \fI-r\fR options can be used
+as well to indicate a specific domain controller which should
+be contacted. In this case, the domain SID obtained is the
+one for the domain to which the remote machine belongs.
+.TP
+\fB-t\fR
+This option is used to force smbpasswd to
+change the current password assigned to the machine trust account
+when operating in domain security mode. This is really meant to
+be used on systems that only run \fBwinbindd\fR
+Under server installations, \fBsmbd\fR
+handle the password updates automatically.
+.TP
+\fB-T\fR
+The \fI-T\fR option may be used to
+force samba to use a previously created trust account by allowing
+the trust account hash to be set in the secrets database only.
+This way, an application can change the trust account password
+and call "smbpasswd -T" so that Samba can continue to work.
+.TP
+\fB-U username[%pass]\fR
+This option may only be used in conjunction
+with the \fI-r\fR option. When changing
+a password on a remote machine it allows the user to specify
+the user name on that machine whose password will be changed. It
+is present to allow users who have different user names on
+different systems to change these passwords. The optional
+%pass may be used to specify to old password.
+
+In particular, this parameter specifies the username
+used to create the machine account when invoked with -j
+.TP
+\fB-W S-1-5-21-x-y-z\fR
+This option forces the SID S-1-5-21-x-y-z to
+be the server and domain SID for the current Samba server. It
+does this by updating the appropriate keys in the secrets
+file.
+.TP
+\fB-X server|domain\fR
+This option allows the admin to retrieve the
+SID associated with a former servername or domain name that
+this Samba server might have used. It does this by retrieving
+the appropriate entry from the secrets file.
+.TP
+\fBNOTE:\fR
+\fBThe following options are available only when the smbpasswd command is
+run as root or in local mode.\fR
+.TP
+\fB-a\fR
+This option specifies that the username
+following should be added to the local smbpasswd file, with the
+new password typed. This
+option is ignored if the username specified already exists in
+the smbpasswd file and it is treated like a regular change
+password command. Note that the user to be added must already exist
+in the system password file (usually \fI/etc/passwd\fR)
+else the request to add the user will fail.
+.TP
+\fB-d\fR
+This option specifies that the username following
+should be disabled in the local smbpasswd
+file. This is done by writing a 'D' flag
+into the account control space in the smbpasswd file. Once this
+is done all attempts to authenticate via SMB using this username
+will fail.
+
+If the smbpasswd file is in the 'old' format (pre-Samba 2.0
+format) there is no space in the user's password entry to write
+this information and so the user is disabled by writing 'X' characters
+into the password space in the smbpasswd file. See \fBsmbpasswd(5)
+\fRfor details on the 'old' and new password file formats.
+.TP
+\fB-e\fR
+This option specifies that the username following
+should be enabled in the local smbpasswd file,
+if the account was previously disabled. If the account was not
+disabled this option has no effect. Once the account is enabled then
+the user will be able to authenticate via SMB once again.
+
+If the smbpasswd file is in the 'old' format, then \fB smbpasswd\fR will prompt for a new password for this user,
+otherwise the account will be enabled by removing the 'D'
+flag from account control space in the \fI smbpasswd\fR file. See \fBsmbpasswd (5)\fR for
+details on the 'old' and new password file formats.
+.TP
+\fB-m\fR
+This option tells smbpasswd that the account
+being changed is a MACHINE account. Currently this is used
+when Samba is being used as an NT Primary Domain Controller.
+.TP
+\fB-n\fR
+This option specifies that the username following
+should have their password set to null (i.e. a blank password) in
+the local smbpasswd file. This is done by writing the string "NO
+PASSWORD" as the first part of the first password stored in the
+smbpasswd file.
+
+Note that to allow users to logon to a Samba server once
+the password has been set to "NO PASSWORD" in the smbpasswd
+file the administrator must set the following parameter in the [global]
+section of the \fIsmb.conf\fR file :
+
+\fBnull passwords = yes\fR
+.TP
+\fB-w password\fR
+This parameter is only available is Samba
+has been configured to use the experimental
+\fB--with-ldapsam\fR option. The \fI-w\fR
+switch is used to specify the password to be used with the
+\fIldap admin
+dn\fR Note that the password is stored in
+the \fIprivate/secrets.tdb\fR and is keyed off
+of the admin's DN. This means that if the value of \fIldap
+admin dn\fR ever changes, the password will need to be
+manually updated as well.
+.TP
+\fB-x\fR
+This option specifies that the username
+following should be deleted from the local smbpasswd file.
+.TP
+\fB-j DOMAIN\fR
+This option is used to add a Samba server
+into a Windows NT Domain, as a Domain member capable of authenticating
+user accounts to any Domain Controller in the same way as a Windows
+NT Server. See the \fBsecurity = domain\fR option in
+the \fIsmb.conf(5)\fR man page.
+
+This command can work both with and without the -U parameter.
+
+When invoked with -U, that username (and optional password) are
+used to contact the PDC (which must be specified with -r) to both
+create a machine account, and to set a password on it.
+
+Alternately, if -U is omitted, Samba will contact its PDC
+and attempt to change the password on a pre-existing account.
+
+In order to be used in this way, the Administrator for
+the Windows NT Domain must have used the program "Server Manager
+for Domains" to add the primary NetBIOS name of the Samba server
+as a member of the Domain.
+
+After this has been done, to join the Domain invoke \fB smbpasswd\fR with this parameter. smbpasswd will then
+look up the Primary Domain Controller for the Domain (found in
+the \fIsmb.conf\fR file in the parameter
+\fIpassword server\fR and change the machine account
+password used to create the secure Domain communication.
+
+Either way, this password is then stored by smbpasswd in a TDB,
+writeable only by root, called \fIsecrets.tdb\fR
+
+Once this operation has been performed the \fI smb.conf\fR file may be updated to set the \fB security = domain\fR option and all future logins
+to the Samba server will be authenticated to the Windows NT
+PDC.
+
+Note that even though the authentication is being
+done to the PDC all users accessing the Samba server must still
+have a valid UNIX account on that machine.
+The \fBwinbindd(8)\fR daemon can be used
+to create UNIX accounts for NT users.
+.TP
+\fB-R name resolve order\fR
+This option allows the user of smbpasswd to determine
+what name resolution services to use when looking up the NetBIOS
+name of the host being connected to.
+
+The options are :"lmhosts", "host", "wins" and "bcast". They cause
+names to be resolved as follows :
+.RS
+.TP 0.2i
+\(bu
+lmhosts : Lookup an IP
+address in the Samba lmhosts file. If the line in lmhosts has
+no name type attached to the NetBIOS name (see the lmhosts(5) for details) then
+any name type matches for lookup.
+.TP 0.2i
+\(bu
+host : Do a standard host
+name to IP address resolution, using the system \fI/etc/hosts
+\fR, NIS, or DNS lookups. This method of name resolution
+is operating system dependent. For instance, on IRIX or Solaris this
+may be controlled by the \fI/etc/nsswitch.conf\fR
+file). Note that this method is only used if the NetBIOS name
+type being queried is the 0x20 (server) name type, otherwise
+it is ignored.
+.TP 0.2i
+\(bu
+wins : Query a name with
+the IP address listed in the \fIwins server\fR
+parameter. If no WINS server has been specified this method
+will be ignored.
+.TP 0.2i
+\(bu
+bcast : Do a broadcast on
+each of the known local interfaces listed in the
+\fIinterfaces\fR parameter. This is the least
+reliable of the name resolution methods as it depends on the
+target host being on a locally connected subnet.
+.RE
+.PP
+The default order is \fBlmhosts, host, wins, bcast\fR
+and without this parameter or any entry in the
+\fIsmb.conf\fR file the name resolution methods will
+be attempted in this order.
+.PP
+.TP
+\fBusername\fR
+This specifies the username for all of the
+\fBroot only\fR options to operate on. Only root
+can specify this parameter as only root has the permission needed
+to modify attributes directly in the local smbpasswd file.
+.TP
+\fBpassword\fR
+This specifies the new password. If this parameter
+is specified you will not be prompted for the new password.
+.SH "NOTES"
+.PP
+Since \fBsmbpasswd\fR works in client-server
+mode communicating with a local smbd for a non-root user then
+the smbd daemon must be running for this to work. A common problem
+is to add a restriction to the hosts that may access the \fB smbd\fR running on the local machine by specifying a
+\fIallow hosts\fR or \fIdeny hosts\fR
+entry in the \fIsmb.conf\fR file and neglecting to
+allow "localhost" access to the smbd.
+.PP
+In addition, the smbpasswd command is only useful if Samba
+has been set up to use encrypted passwords. See the file
+\fIENCRYPTION.txt\fR in the docs directory for details
+on how to do this.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fIsmbpasswd(5)\fR
+samba(7)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbsh.1 b/docs/manpages/smbsh.1
new file mode 100755
index 00000000000..bb3b30433f0
--- /dev/null
+++ b/docs/manpages/smbsh.1
@@ -0,0 +1,172 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBSH" "1" "19 November 2002" "" ""
+.SH NAME
+smbsh \- Allows access to Windows NT filesystem using UNIX commands
+.SH SYNOPSIS
+.sp
+\fBsmbsh\fR [ \fB-W workgroup\fR ] [ \fB-U username\fR ] [ \fB-P prefix\fR ] [ \fB-R <name resolve order>\fR ] [ \fB-d <debug level>\fR ] [ \fB-l logfile\fR ] [ \fB-L libdir\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBsmbsh\fR allows you to access an NT filesystem
+using UNIX commands such as \fBls\fR, \fB egrep\fR, and \fBrcp\fR. You must use a
+shell that is dynamically linked in order for \fBsmbsh\fR
+to work correctly.
+.SH "OPTIONS"
+.TP
+\fB-W WORKGROUP\fR
+Override the default workgroup specified in the
+workgroup parameter of the \fIsmb.conf\fR file
+for this session. This may be needed to connect to some
+servers.
+.TP
+\fB-U username[%pass]\fR
+Sets the SMB username or username and password.
+If this option is not specified, the user will be prompted for
+both the username and the password. If %pass is not specified,
+the user will be prompted for the password.
+.TP
+\fB-P prefix\fR
+This option allows
+the user to set the directory prefix for SMB access. The
+default value if this option is not specified is
+\fBsmb\fR.
+.TP
+\fB-R <name resolve order>\fR
+This option is used to determine what naming
+services and in what order to resolve
+host names to IP addresses. The option takes a space-separated
+string of different name resolution options.
+
+The options are :"lmhosts", "host", "wins" and "bcast".
+They cause names to be resolved as follows :
+.RS
+.TP 0.2i
+\(bu
+lmhosts :
+Lookup an IP address in the Samba lmhosts file. If the
+line in lmhosts has no name type attached to the
+NetBIOS name
+(see the lmhosts(5)
+for details) then any name type matches for lookup.
+.TP 0.2i
+\(bu
+host :
+Do a standard host name to IP address resolution, using
+the system \fI/etc/hosts\fR, NIS, or DNS
+lookups. This method of name resolution is operating
+system dependent, for instance on IRIX or Solaris this
+may be controlled by the \fI/etc/nsswitch.conf
+\fRfile). Note that this method is only used
+if the NetBIOS name type being queried is the 0x20
+(server) name type, otherwise it is ignored.
+.TP 0.2i
+\(bu
+wins :
+Query a name with the IP address listed in the
+\fIwins server\fR parameter. If no
+WINS server has been specified this method will be
+ignored.
+.TP 0.2i
+\(bu
+bcast :
+Do a broadcast on each of the known local interfaces
+listed in the \fIinterfaces\fR
+parameter. This is the least reliable of the name
+resolution methods as it depends on the target host
+being on a locally connected subnet.
+.RE
+.PP
+If this parameter is not set then the name resolve order
+defined in the \fIsmb.conf\fR file parameter
+(name resolve order) will be used.
+.PP
+.PP
+The default order is lmhosts, host, wins, bcast. Without
+this parameter or any entry in the \fIname resolve order
+\fRparameter of the \fIsmb.conf\fR
+file, the name resolution methods will be attempted in this
+order.
+.PP
+.TP
+\fB-d <debug level>\fR
+debug level is an integer from 0 to 10.
+
+The default value if this parameter is not specified
+is zero.
+
+The higher this value, the more detail will be logged
+about the activities of \fBnmblookup\fR. At level
+0, only critical errors and serious warnings will be logged.
+.TP
+\fB-l logfilename\fR
+If specified causes all debug messages to be
+written to the file specified by \fIlogfilename
+\fR\&. If not specified then all messages will be
+written to\fIstderr\fR.
+.TP
+\fB-L libdir\fR
+This parameter specifies the location of the
+shared libraries used by \fBsmbsh\fR. The default
+value is specified at compile time.
+.SH "EXAMPLES"
+.PP
+To use the \fBsmbsh\fR command, execute \fB smbsh\fR from the prompt and enter the username and password
+that authenticates you to the machine running the Windows NT
+operating system.
+.PP
+.sp
+.nf
+ system% \fBsmbsh\fR
+ Username: \fBuser\fR
+ Password: \fBXXXXXXX\fR
+
+.sp
+.fi
+.PP
+Any dynamically linked command you execute from
+this shell will access the \fI/smb\fR directory
+using the smb protocol. For example, the command \fBls /smb
+\fRwill show a list of workgroups. The command
+\fBls /smb/MYGROUP \fR will show all the machines in
+the workgroup MYGROUP. The command
+\fBls /smb/MYGROUP/<machine-name>\fR will show the share
+names for that machine. You could then, for example, use the \fB cd\fR command to change directories, \fBvi\fR to
+edit files, and \fBrcp\fR to copy files.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "BUGS"
+.PP
+\fBsmbsh\fR works by intercepting the standard
+libc calls with the dynamically loaded versions in \fI smbwrapper.o\fR. Not all calls have been "wrapped", so
+some programs may not function correctly under \fBsmbsh
+\fR\&.
+.PP
+Programs which are not dynamically linked cannot make
+use of \fBsmbsh\fR's functionality. Most versions
+of UNIX have a \fBfile\fR command that will
+describe how a program was linked.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbspool.8 b/docs/manpages/smbspool.8
new file mode 100755
index 00000000000..f780874b309
--- /dev/null
+++ b/docs/manpages/smbspool.8
@@ -0,0 +1,102 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBSPOOL" "8" "19 November 2002" "" ""
+.SH NAME
+smbspool \- send print file to an SMB printer
+.SH SYNOPSIS
+.sp
+\fBsmbspool\fR [ \fBjob\fR ] [ \fBuser\fR ] [ \fBtitle\fR ] [ \fBcopies\fR ] [ \fBoptions\fR ] [ \fBfilename\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+smbspool is a very small print spooling program that
+sends a print file to an SMB printer. The command-line arguments
+are position-dependent for compatibility with the Common UNIX
+Printing System, but you can use smbspool with any printing system
+or from a program or script.
+.PP
+\fBDEVICE URI\fR
+.PP
+smbspool specifies the destination using a Uniform Resource
+Identifier ("URI") with a method of "smb". This string can take
+a number of forms:
+.TP 0.2i
+\(bu
+smb://server/printer
+.TP 0.2i
+\(bu
+smb://workgroup/server/printer
+.TP 0.2i
+\(bu
+smb://username:password@server/printer
+.TP 0.2i
+\(bu
+smb://username:password@workgroup/server/printer
+.PP
+smbspool tries to get the URI from argv[0]. If argv[0]
+contains the name of the program then it looks in the \fB DEVICE_URI\fR environment variable.
+.PP
+.PP
+Programs using the \fBexec(2)\fR functions can
+pass the URI in argv[0], while shell scripts must set the
+\fBDEVICE_URI\fR environment variable prior to
+running smbspool.
+.PP
+.SH "OPTIONS"
+.TP 0.2i
+\(bu
+The job argument (argv[1]) contains the
+job ID number and is presently not used by smbspool.
+.TP 0.2i
+\(bu
+The user argument (argv[2]) contains the
+print user's name and is presently not used by smbspool.
+.TP 0.2i
+\(bu
+The title argument (argv[3]) contains the
+job title string and is passed as the remote file name
+when sending the print job.
+.TP 0.2i
+\(bu
+The copies argument (argv[4]) contains
+the number of copies to be printed of the named file. If
+no filename is provided than this argument is not used by
+smbspool.
+.TP 0.2i
+\(bu
+The options argument (argv[5]) contains
+the print options in a single string and is presently
+not used by smbspool.
+.TP 0.2i
+\(bu
+The filename argument (argv[6]) contains the
+name of the file to print. If this argument is not specified
+then the print file is read from the standard input.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR
+and samba(7)
+.SH "AUTHOR"
+.PP
+\fBsmbspool\fR was written by Michael Sweet
+at Easy Software Products.
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbstatus.1 b/docs/manpages/smbstatus.1
new file mode 100755
index 00000000000..95356684915
--- /dev/null
+++ b/docs/manpages/smbstatus.1
@@ -0,0 +1,70 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBSTATUS" "1" "19 November 2002" "" ""
+.SH NAME
+smbstatus \- report on current Samba connections
+.SH SYNOPSIS
+.sp
+\fBsmbstatus\fR [ \fB-P\fR ] [ \fB-b\fR ] [ \fB-d\fR ] [ \fB-L\fR ] [ \fB-p\fR ] [ \fB-S\fR ] [ \fB-s <configuration file>\fR ] [ \fB-u <username>\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBsmbstatus\fR is a very simple program to
+list the current Samba connections.
+.SH "OPTIONS"
+.TP
+\fB-P\fR
+If samba has been compiled with the
+profiling option, print only the contents of the profiling
+shared memory area.
+.TP
+\fB-b\fR
+gives brief output.
+.TP
+\fB-d\fR
+gives verbose output.
+.TP
+\fB-L\fR
+causes smbstatus to only list locks.
+.TP
+\fB-p\fR
+print a list of \fBsmbd(8)\fR processes and exit.
+Useful for scripting.
+.TP
+\fB-S\fR
+causes smbstatus to only list shares.
+.TP
+\fB-s <configuration file>\fR
+The default configuration file name is
+determined at compile time. The file specified contains the
+configuration details required by the server. See \fIsmb.conf(5)\fR
+ for more information.
+.TP
+\fB-u <username>\fR
+selects information relevant to
+\fIusername\fR only.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR and
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/smbtar.1 b/docs/manpages/smbtar.1
new file mode 100755
index 00000000000..dd555895b84
--- /dev/null
+++ b/docs/manpages/smbtar.1
@@ -0,0 +1,120 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBTAR" "1" "19 November 2002" "" ""
+.SH NAME
+smbtar \- shell script for backing up SMB/CIFS shares directly to UNIX tape drives
+.SH SYNOPSIS
+.sp
+\fBsmbtar\fR \fB-s server\fR [ \fB-p password\fR ] [ \fB-x services\fR ] [ \fB-X\fR ] [ \fB-d directory\fR ] [ \fB-u user\fR ] [ \fB-t tape\fR ] [ \fB-t tape\fR ] [ \fB-b blocksize\fR ] [ \fB-N filename\fR ] [ \fB-i\fR ] [ \fB-r\fR ] [ \fB-l loglevel\fR ] [ \fB-v\fR ] \fBfilenames\fR
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBsmbtar\fR is a very small shell script on top
+of \fBsmbclient(1)\fR
+which dumps SMB shares directly to tape.
+.SH "OPTIONS"
+.TP
+\fB-s server\fR
+The SMB/CIFS server that the share resides
+upon.
+.TP
+\fB-x service\fR
+The share name on the server to connect to.
+The default is "backup".
+.TP
+\fB-X\fR
+Exclude mode. Exclude filenames... from tar
+create or restore.
+.TP
+\fB-d directory\fR
+Change to initial \fIdirectory
+\fRbefore restoring / backing up files.
+.TP
+\fB-v\fR
+Verbose mode.
+.TP
+\fB-p password\fR
+The password to use to access a share.
+Default: none
+.TP
+\fB-u user\fR
+The user id to connect as. Default:
+UNIX login name.
+.TP
+\fB-t tape\fR
+Tape device. May be regular file or tape
+device. Default: \fI$TAPE\fR environmental
+variable; if not set, a file called \fItar.out
+\fR\&.
+.TP
+\fB-b blocksize\fR
+Blocking factor. Defaults to 20. See
+\fBtar(1)\fR for a fuller explanation.
+.TP
+\fB-N filename\fR
+Backup only files newer than filename. Could
+be used (for example) on a log file to implement incremental
+backups.
+.TP
+\fB-i\fR
+Incremental mode; tar files are only backed
+up if they have the archive bit set. The archive bit is reset
+after each file is read.
+.TP
+\fB-r\fR
+Restore. Files are restored to the share
+from the tar file.
+.TP
+\fB-l log level\fR
+Log (debug) level. Corresponds to the
+\fI-d\fR flag of \fBsmbclient(1)
+\fR\&.
+.SH "ENVIRONMENT VARIABLES"
+.PP
+The \fI$TAPE\fR variable specifies the
+default tape device to write to. May be overridden
+with the -t option.
+.SH "BUGS"
+.PP
+The \fBsmbtar\fR script has different
+options from ordinary tar and tar called from smbclient.
+.SH "CAVEATS"
+.PP
+Sites that are more careful about security may not like
+the way the script handles PC passwords. Backup and restore work
+on entire shares, should work on file lists. smbtar works best
+with GNU tar and may not work well with other versions.
+.SH "DIAGNOSTICS"
+.PP
+See the \fBDIAGNOSTICS\fR section for the
+\fBsmbclient(1)\fR
+ command.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBsmbd(8)\fR
+\fBsmbclient(1)\fR
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+Ricky Poulten <URL:mailto:poultenr@logica.co.uk>
+wrote the tar extension and this man page. The \fBsmbtar\fR
+script was heavily rewritten and improved by Martin Kraemer <URL:mailto:Martin.Kraemer@mch.sni.de>. Many
+thanks to everyone who suggested extensions, improvements, bug
+fixes, etc. The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter.
diff --git a/docs/manpages/smbumount.8 b/docs/manpages/smbumount.8
new file mode 100755
index 00000000000..23e70e88259
--- /dev/null
+++ b/docs/manpages/smbumount.8
@@ -0,0 +1,42 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SMBUMOUNT" "8" "19 November 2002" "" ""
+.SH NAME
+smbumount \- smbfs umount for normal users
+.SH SYNOPSIS
+.sp
+\fBsmbumount\fR \fBmount-point\fR
+.SH "DESCRIPTION"
+.PP
+With this program, normal users can unmount smb-filesystems,
+provided that it is suid root. \fBsmbumount\fR has
+been written to give normal Linux users more control over their
+resources. It is safe to install this program suid root, because only
+the user who has mounted a filesystem is allowed to unmount it again.
+For root it is not necessary to use smbumount. The normal umount
+program works perfectly well, but it would certainly be problematic
+to make umount setuid root.
+.SH "OPTIONS"
+.TP
+\fBmount-point\fR
+The directory to unmount.
+.SH "SEE ALSO"
+.PP
+\fBsmbmount(8)\fR
+
+.SH "AUTHOR"
+.PP
+Volker Lendecke, Andrew Tridgell, Michael H. Warfield
+and others.
+.PP
+The current maintainer of smbfs and the userspace
+tools \fBsmbmount\fR, \fBsmbumount\fR,
+and \fBsmbmnt\fR is Urban Widmark <URL:mailto:urban@teststation.com>.
+The SAMBA Mailing list <URL:mailto:samba@samba.org>
+is the preferred place to ask questions regarding these programs.
+.PP
+The conversion of this manpage for Samba 2.2 was performed
+by Gerald Carter
diff --git a/docs/manpages/swat.8 b/docs/manpages/swat.8
new file mode 100755
index 00000000000..964ca3882b2
--- /dev/null
+++ b/docs/manpages/swat.8
@@ -0,0 +1,182 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "SWAT" "8" "19 November 2002" "" ""
+.SH NAME
+swat \- Samba Web Administration Tool
+.SH SYNOPSIS
+.sp
+\fBswat\fR [ \fB-s <smb config file>\fR ] [ \fB-a\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBswat\fR allows a Samba administrator to
+configure the complex \fI smb.conf(5)\fR file via a Web browser. In addition,
+a \fBswat\fR configuration page has help links
+to all the configurable options in the \fIsmb.conf\fR file allowing an
+administrator to easily look up the effects of any change.
+.PP
+\fBswat\fR is run from \fBinetd\fR
+.SH "OPTIONS"
+.TP
+\fB-s smb configuration file\fR
+The default configuration file path is
+determined at compile time. The file specified contains
+the configuration details required by the \fBsmbd
+\fRserver. This is the file that \fBswat\fR will modify.
+The information in this file includes server-specific
+information such as what printcap file to use, as well as
+descriptions of all the services that the server is to provide.
+See \fIsmb.conf\fR for more information.
+.TP
+\fB-a\fR
+This option disables authentication and puts
+\fBswat\fR in demo mode. In that mode anyone will be able to modify
+the \fIsmb.conf\fR file.
+
+\fBDo NOT enable this option on a production
+server. \fR
+.SH "INSTALLATION"
+.PP
+After you compile SWAT you need to run \fBmake install
+\fRto install the \fBswat\fR binary
+and the various help files and images. A default install would put
+these in:
+.TP 0.2i
+\(bu
+/usr/local/samba/bin/swat
+.TP 0.2i
+\(bu
+/usr/local/samba/swat/images/*
+.TP 0.2i
+\(bu
+/usr/local/samba/swat/help/*
+.SS "INETD INSTALLATION"
+.PP
+You need to edit your \fI/etc/inetd.conf
+\fRand \fI/etc/services\fR
+to enable SWAT to be launched via \fBinetd\fR.
+.PP
+In \fI/etc/services\fR you need to
+add a line like this:
+.PP
+\fBswat 901/tcp\fR
+.PP
+Note for NIS/YP users - you may need to rebuild the
+NIS service maps rather than alter your local \fI /etc/services\fR file.
+.PP
+the choice of port number isn't really important
+except that it should be less than 1024 and not currently
+used (using a number above 1024 presents an obscure security
+hole depending on the implementation details of your
+\fBinetd\fR daemon).
+.PP
+In \fI/etc/inetd.conf\fR you should
+add a line like this:
+.PP
+\fBswat stream tcp nowait.400 root
+/usr/local/samba/bin/swat swat\fR
+.PP
+One you have edited \fI/etc/services\fR
+and \fI/etc/inetd.conf\fR you need to send a
+HUP signal to inetd. To do this use \fBkill -1 PID
+\fRwhere PID is the process ID of the inetd daemon.
+.SS "XINETD INSTALLATION"
+.PP
+Newer Linux systems ship with a more secure implementation
+of the inetd meta-daemon. The \fBxinetd\fR daemon
+can read configuration inf9ormation from a single file (i.e.
+\fI/etc/xinetd.conf\fR) or from a collection
+of service control files in the \fIxinetd.d/\fR directory.
+These directions assume the latter configuration.
+.PP
+The following file should be created as \fI/etc/xientd.d/swat\fR.
+It is then be neccessary cause the meta-daemon to reload its configuration files.
+Refer to the xinetd man page for details on how to accomplish this.
+.PP
+.sp
+.nf
+## /etc/xinetd.d/swat
+service swat
+{
+ port = 901
+ socket_type = stream
+ wait = no
+ only_from = localhost
+ user = root
+ server = /usr/local/samba/bin/swat
+ log_on_failure += USERID
+ disable = No
+}
+.sp
+.fi
+.SS "LAUNCHING"
+.PP
+To launch SWAT just run your favorite web browser and
+point it at "http://localhost:901/".
+.PP
+Note that you can attach to SWAT from any IP connected
+machine but connecting from a remote machine leaves your
+connection open to password sniffing as passwords will be sent
+in the clear over the wire.
+.SH "TROUBLESHOOTING"
+.PP
+One of the common causes of difficulty when installing Samba and SWAT
+is the existsnece of some type of firewall or port filtering software
+on the Samba server. Make sure that the appropriate ports
+outlined in this man page are available on the server and are not currently
+being blocked by some type of security software such as iptables or
+"port sentry". For more troubleshooting information, refer to the additional
+documentation included in the Samba distribution.
+.SH "FILES"
+.TP
+\fB\fI/etc/inetd.conf\fB\fR
+This file must contain suitable startup
+information for the meta-daemon.
+.TP
+\fB\fI/etc/xinetd.d/swat\fB\fR
+This file must contain suitable startup
+information for the \fBxinetd\fR meta-daemon.
+.TP
+\fB\fI/etc/services\fB\fR
+This file must contain a mapping of service name
+(e.g., swat) to service port (e.g., 901) and protocol type
+(e.g., tcp).
+.TP
+\fB\fI/usr/local/samba/lib/smb.conf\fB\fR
+This is the default location of the \fIsmb.conf(5)
+\fRserver configuration file that swat edits. Other
+common places that systems install this file are \fI /usr/samba/lib/smb.conf\fR and \fI/etc/smb.conf
+\fR\&. This file describes all the services the server
+is to make available to clients.
+.SH "WARNINGS"
+.PP
+\fBswat\fR will rewrite your \fIsmb.conf
+\fRfile. It will rearrange the entries and delete all
+comments, \fIinclude=\fR and \fIcopy="
+\fRoptions. If you have a carefully crafted \fI smb.conf\fR then back it up or don't use swat!
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBinetd(5)\fR,
+\fBsmbd(8)\fR
+smb.conf(5) \fBxinetd(8)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/testparm.1 b/docs/manpages/testparm.1
new file mode 100755
index 00000000000..d53a6451d7b
--- /dev/null
+++ b/docs/manpages/testparm.1
@@ -0,0 +1,103 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "TESTPARM" "1" "19 November 2002" "" ""
+.SH NAME
+testparm \- check an smb.conf configuration file for internal correctness
+.SH SYNOPSIS
+.sp
+\fBtestparm\fR [ \fB-s\fR ] [ \fB-h\fR ] [ \fB-x\fR ] [ \fB-L <servername>\fR ] \fBconfig filename\fR [ \fBhostname hostIP\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBtestparm\fR is a very simple test program
+to check an \fBsmbd\fR configuration file for
+internal correctness. If this program reports no problems, you
+can use the configuration file with confidence that \fBsmbd
+\fRwill successfully load the configuration file.
+.PP
+Note that this is \fBNOT\fR a guarantee that
+the services specified in the configuration file will be
+available or will operate as expected.
+.PP
+If the optional host name and host IP address are
+specified on the command line, this test program will run through
+the service entries reporting whether the specified host
+has access to each service.
+.PP
+If \fBtestparm\fR finds an error in the \fI smb.conf\fR file it returns an exit code of 1 to the calling
+program, else it returns an exit code of 0. This allows shell scripts
+to test the output from \fBtestparm\fR.
+.SH "OPTIONS"
+.TP
+\fB-s\fR
+Without this option, \fBtestparm\fR
+will prompt for a carriage return after printing the service
+names and before dumping the service definitions.
+.TP
+\fB-h\fR
+Print usage message
+.TP
+\fB-x\fR
+Print only parameters that have non-default values
+.TP
+\fB-L servername\fR
+Sets the value of the %L macro to \fIservername\fR.
+This is useful for testing include files specified with the
+%L macro.
+.TP
+\fBconfigfilename\fR
+This is the name of the configuration file
+to check. If this parameter is not present then the
+default \fIsmb.conf\fR file will be checked.
+.TP
+\fBhostname\fR
+If this parameter and the following are
+specified, then \fBtestparm\fR will examine the \fIhosts
+allow\fR and \fIhosts deny\fR
+parameters in the \fIsmb.conf\fR file to
+determine if the hostname with this IP address would be
+allowed access to the \fBsmbd\fR server. If
+this parameter is supplied, the hostIP parameter must also
+be supplied.
+.TP
+\fBhostIP\fR
+This is the IP address of the host specified
+in the previous parameter. This address must be supplied
+if the hostname parameter is supplied.
+.SH "FILES"
+.TP
+\fB\fIsmb.conf\fB\fR
+This is usually the name of the configuration
+file used by \fBsmbd\fR.
+.SH "DIAGNOSTICS"
+.PP
+The program will issue a message saying whether the
+configuration file loaded OK or not. This message may be preceded by
+errors and warnings if the file did not load. If the file was
+loaded OK, the program then dumps all known service details
+to stdout.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fIsmb.conf(5)\fR
+\fBsmbd(8)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/testprns.1 b/docs/manpages/testprns.1
new file mode 100755
index 00000000000..6e2fb3390d9
--- /dev/null
+++ b/docs/manpages/testprns.1
@@ -0,0 +1,90 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "TESTPRNS" "1" "19 November 2002" "" ""
+.SH NAME
+testprns \- check printer name for validity with smbd
+.SH SYNOPSIS
+.sp
+\fBtestprns\fR \fBprintername\fR [ \fBprintcapname\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+\fBtestprns\fR is a very simple test program
+to determine whether a given printer name is valid for use in
+a service to be provided by \fB smbd(8)\fR
+.PP
+"Valid" in this context means "can be found in the
+printcap specified". This program is very stupid - so stupid in
+fact that it would be wisest to always specify the printcap file
+to use.
+.SH "OPTIONS"
+.TP
+\fBprintername\fR
+The printer name to validate.
+
+Printer names are taken from the first field in each
+record in the printcap file, single printer names and sets
+of aliases separated by vertical bars ("|") are recognized.
+Note that no validation or checking of the printcap syntax is
+done beyond that required to extract the printer name. It may
+be that the print spooling system is more forgiving or less
+forgiving than \fBtestprns\fR. However, if
+\fBtestprns\fR finds the printer then
+\fBsmbd\fR should do so as well.
+.TP
+\fBprintcapname\fR
+This is the name of the printcap file within
+which to search for the given printer name.
+
+If no printcap name is specified \fBtestprns
+\fRwill attempt to scan the printcap file name
+specified at compile time.
+.SH "FILES"
+.TP
+\fB\fI/etc/printcap\fB\fR
+This is usually the default printcap
+file to scan. See \fIprintcap (5)\fR.
+.SH "DIAGNOSTICS"
+.PP
+If a printer is found to be valid, the message
+"Printer name <printername> is valid" will be
+displayed.
+.PP
+If a printer is found to be invalid, the message
+"Printer name <printername> is not valid" will be
+displayed.
+.PP
+All messages that would normally be logged during
+operation of the Samba daemons are logged by this program to the
+file \fItest.log\fR in the current directory. The
+program runs at debuglevel 3, so quite extensive logging
+information is written. The log should be checked carefully
+for errors and warnings.
+.PP
+Other messages are self-explanatory.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fIprintcap(5)\fR,
+\fBsmbd(8)\fR
+\fBsmbclient(1)\fR
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+The original Samba man pages were written by Karl Auer.
+The man page sources were converted to YODL format (another
+excellent piece of Open Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the Samba 2.0
+release by Jeremy Allison. The conversion to DocBook for
+Samba 2.2 was done by Gerald Carter
diff --git a/docs/manpages/wbinfo.1 b/docs/manpages/wbinfo.1
new file mode 100755
index 00000000000..b4c6ed9be4d
--- /dev/null
+++ b/docs/manpages/wbinfo.1
@@ -0,0 +1,138 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "WBINFO" "1" "19 November 2002" "" ""
+.SH NAME
+wbinfo \- Query information from winbind daemon
+.SH SYNOPSIS
+.sp
+\fBwbinfo\fR [ \fB-u\fR ] [ \fB-g\fR ] [ \fB-h name\fR ] [ \fB-i ip\fR ] [ \fB-n name\fR ] [ \fB-s sid\fR ] [ \fB-U uid\fR ] [ \fB-G gid\fR ] [ \fB-S sid\fR ] [ \fB-Y sid\fR ] [ \fB-t\fR ] [ \fB-m\fR ] [ \fB-r user\fR ] [ \fB-a user%password\fR ] [ \fB-A user%password\fR ]
+.SH "DESCRIPTION"
+.PP
+This tool is part of the Samba suite.
+.PP
+The \fBwbinfo\fR program queries and returns information
+created and used by the \fB winbindd(8)\fR daemon.
+.PP
+The \fBwinbindd(8)\fR daemon must be configured
+and running for the \fBwbinfo\fR program to be able
+to return information.
+.SH "OPTIONS"
+.TP
+\fB-u\fR
+This option will list all users available
+in the Windows NT domain for which the \fBwinbindd(8)
+\fRdaemon is operating in. Users in all trusted domains
+will also be listed. Note that this operation does not assign
+user ids to any users that have not already been seen by
+\fBwinbindd(8)\fR.
+.TP
+\fB-g\fR
+This option will list all groups available
+in the Windows NT domain for which the \fBwinbindd(8)
+\fRdaemon is operating in. Groups in all trusted domains
+will also be listed. Note that this operation does not assign
+group ids to any groups that have not already been seen by
+\fBwinbindd(8)\fR.
+.TP
+\fB-h name\fR
+The \fI-h\fR option
+queries \fBwinbindd(8)\fR to query the WINS
+server for the IP address associated with the NetBIOS name
+specified by the \fIname\fR parameter.
+.TP
+\fB-i ip\fR
+The \fI-i\fR option
+queries \fBwinbindd(8)\fR to send a node status
+request to get the NetBIOS name associated with the IP address
+specified by the \fIip\fR parameter.
+.TP
+\fB-n name\fR
+The \fI-n\fR option
+queries \fBwinbindd(8)\fR for the SID
+associated with the name specified. Domain names can be specified
+before the user name by using the winbind separator character.
+For example CWDOM1/Administrator refers to the Administrator
+user in the domain CWDOM1. If no domain is specified then the
+domain used is the one specified in the \fIsmb.conf\fR
+\fIworkgroup\fR parameter.
+.TP
+\fB-s sid\fR
+Use \fI-s\fR to resolve
+a SID to a name. This is the inverse of the \fI-n
+\fRoption above. SIDs must be specified as ASCII strings
+in the traditional Microsoft format. For example,
+S-1-5-21-1455342024-3071081365-2475485837-500.
+.TP
+\fB-U uid\fR
+Try to convert a UNIX user id to a Windows NT
+SID. If the uid specified does not refer to one within
+the winbind uid range then the operation will fail.
+.TP
+\fB-G gid\fR
+Try to convert a UNIX group id to a Windows
+NT SID. If the gid specified does not refer to one within
+the winbind gid range then the operation will fail.
+.TP
+\fB-S sid\fR
+Convert a SID to a UNIX user id. If the SID
+does not correspond to a UNIX user mapped by \fB winbindd(8)\fR then the operation will fail.
+.TP
+\fB-Y sid\fR
+Convert a SID to a UNIX group id. If the SID
+does not correspond to a UNIX group mapped by \fB winbindd(8)\fR then the operation will fail.
+.TP
+\fB-t\fR
+Verify that the workstation trust account
+created when the Samba server is added to the Windows NT
+domain is working.
+.TP
+\fB-m\fR
+Produce a list of domains trusted by the
+Windows NT server \fBwinbindd(8)\fR contacts
+when resolving names. This list does not include the Windows
+NT domain the server is a Primary Domain Controller for.
+.TP
+\fB-r username\fR
+Try to obtain the list of UNIX group ids
+to which the user belongs. This only works for users
+defined on a Domain Controller.
+.TP
+\fB-a username%password\fR
+Attempt to authenticate a user via winbindd.
+This checks both authenticaion methods and reports its results.
+.TP
+\fB-A username%password\fR
+Store username and password used by winbindd
+during session setup to a domain controller. This enables
+winbindd to operate in a Windows 2000 domain with Restrict
+Anonymous turned on (a.k.a. Permissions compatiable with
+Windows 2000 servers only).
+.SH "EXIT STATUS"
+.PP
+The wbinfo program returns 0 if the operation
+succeeded, or 1 if the operation failed. If the \fBwinbindd(8)
+\fRdaemon is not working \fBwbinfo\fR will always return
+failure.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fBwinbindd(8)\fR
+
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+\fBwbinfo\fR and \fBwinbindd\fR
+were written by Tim Potter.
+.PP
+The conversion to DocBook for Samba 2.2 was done
+by Gerald Carter
diff --git a/docs/manpages/winbindd.8 b/docs/manpages/winbindd.8
new file mode 100755
index 00000000000..e1ce2baebb5
--- /dev/null
+++ b/docs/manpages/winbindd.8
@@ -0,0 +1,393 @@
+.\" This manpage has been automatically generated by docbook2man-spec
+.\" from a DocBook document. docbook2man-spec can be found at:
+.\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "WINBINDD" "8" "19 November 2002" "" ""
+.SH NAME
+winbindd \- Name Service Switch daemon for resolving names from NT servers
+.SH SYNOPSIS
+.sp
+\fBwinbindd\fR [ \fB-i\fR ] [ \fB-d <debug level>\fR ] [ \fB-s <smb config file>\fR ]
+.SH "DESCRIPTION"
+.PP
+This program is part of the Samba suite.
+.PP
+\fBwinbindd\fR is a daemon that provides
+a service for the Name Service Switch capability that is present
+in most modern C libraries. The Name Service Switch allows user
+and system information to be obtained from different databases
+services such as NIS or DNS. The exact behaviour can be configured
+throught the \fI/etc/nsswitch.conf\fR file.
+Users and groups are allocated as they are resolved to a range
+of user and group ids specified by the administrator of the
+Samba system.
+.PP
+The service provided by \fBwinbindd\fR is called `winbind' and
+can be used to resolve user and group information from a
+Windows NT server. The service can also provide authentication
+services via an associated PAM module.
+.PP
+The \fIpam_winbind\fR module in the 2.2.2 release only
+supports the \fIauth\fR and \fIaccount\fR
+module-types. The latter is simply
+performs a getpwnam() to verify that the system can obtain a uid for the
+user. If the \fIlibnss_winbind\fR library has been correctly
+installed, this should always suceed.
+.PP
+The following nsswitch databases are implemented by
+the winbindd service:
+.TP
+\fBhosts\fR
+User information traditionally stored in
+the \fIhosts(5)\fR file and used by
+\fBgethostbyname(3)\fR functions. Names are
+resolved through the WINS server or by broadcast.
+.TP
+\fBpasswd\fR
+User information traditionally stored in
+the \fIpasswd(5)\fR file and used by
+\fBgetpwent(3)\fR functions.
+.TP
+\fBgroup\fR
+Group information traditionally stored in
+the \fIgroup(5)\fR file and used by
+\fBgetgrent(3)\fR functions.
+.PP
+For example, the following simple configuration in the
+\fI/etc/nsswitch.conf\fR file can be used to initially
+resolve user and group information from \fI/etc/passwd
+\fRand \fI/etc/group\fR and then from the
+Windows NT server.
+.PP
+.PP
+.sp
+.nf
+passwd: files winbind
+group: files winbind
+
+.sp
+.fi
+.PP
+.PP
+The following simple configuration in the
+\fI/etc/nsswitch.conf\fR file can be used to initially
+resolve hostnames from \fI/etc/hosts\fR and then from the
+WINS server.
+.PP
+.SH "OPTIONS"
+.TP
+\fB-d debuglevel\fR
+Sets the debuglevel to an integer between
+0 and 100. 0 is for no debugging and 100 is for reams and
+reams. To submit a bug report to the Samba Team, use debug
+level 100 (see BUGS.txt).
+.TP
+\fB-i\fR
+Tells \fBwinbindd\fR to not
+become a daemon and detach from the current terminal. This
+option is used by developers when interactive debugging
+of \fBwinbindd\fR is required.
+.SH "NAME AND ID RESOLUTION"
+.PP
+Users and groups on a Windows NT server are assigned
+a relative id (rid) which is unique for the domain when the
+user or group is created. To convert the Windows NT user or group
+into a unix user or group, a mapping between rids and unix user
+and group ids is required. This is one of the jobs that \fB winbindd\fR performs.
+.PP
+As winbindd users and groups are resolved from a server, user
+and group ids are allocated from a specified range. This
+is done on a first come, first served basis, although all existing
+users and groups will be mapped as soon as a client performs a user
+or group enumeration command. The allocated unix ids are stored
+in a database file under the Samba lock directory and will be
+remembered.
+.PP
+WARNING: The rid to unix id database is the only location
+where the user and group mappings are stored by winbindd. If this
+file is deleted or corrupted, there is no way for winbindd to
+determine which user and group ids correspond to Windows NT user
+and group rids.
+.SH "CONFIGURATION"
+.PP
+Configuration of the \fBwinbindd\fR daemon
+is done through configuration parameters in the \fIsmb.conf(5)
+\fRfile. All parameters should be specified in the
+[global] section of smb.conf.
+.TP
+\fBwinbind separator\fR
+The winbind separator option allows you
+to specify how NT domain names and user names are combined
+into unix user names when presented to users. By default,
+\fBwinbindd\fR will use the traditional '\\'
+separator so that the unix user names look like
+DOMAIN\\username. In some cases this separator character may
+cause problems as the '\\' character has special meaning in
+unix shells. In that case you can use the winbind separator
+option to specify an alternative separator character. Good
+alternatives may be '/' (although that conflicts
+with the unix directory separator) or a '+ 'character.
+The '+' character appears to be the best choice for 100%
+compatibility with existing unix utilities, but may be an
+aesthetically bad choice depending on your taste.
+
+Default: \fBwinbind separator = \\ \fR
+
+Example: \fBwinbind separator = + \fR
+.TP
+\fBwinbind uid\fR
+The winbind uid parameter specifies the
+range of user ids that are allocated by the winbindd daemon.
+This range of ids should have no existing local or NIS users
+within it as strange conflicts can occur otherwise.
+
+Default: \fBwinbind uid = <empty string>
+\fR
+Example: \fBwinbind uid = 10000-20000\fR
+.TP
+\fBwinbind gid\fR
+The winbind gid parameter specifies the
+range of group ids that are allocated by the winbindd daemon.
+This range of group ids should have no existing local or NIS
+groups within it as strange conflicts can occur otherwise.
+
+Default: \fBwinbind gid = <empty string>
+\fR
+Example: \fBwinbind gid = 10000-20000
+\fR.TP
+\fBwinbind cache time\fR
+This parameter specifies the number of
+seconds the winbindd daemon will cache user and group information
+before querying a Windows NT server again. When a item in the
+cache is older than this time winbindd will ask the domain
+controller for the sequence number of the server's account database.
+If the sequence number has not changed then the cached item is
+marked as valid for a further \fIwinbind cache time
+\fRseconds. Otherwise the item is fetched from the
+server. This means that as long as the account database is not
+actively changing winbindd will only have to send one sequence
+number query packet every \fIwinbind cache time
+\fRseconds.
+
+Default: \fBwinbind cache time = 15\fR
+.TP
+\fBwinbind enum users\fR
+On large installations it may be necessary
+to suppress the enumeration of users through the \fB setpwent()\fR, \fBgetpwent()\fR and
+\fBendpwent()\fR group of system calls. If
+the \fIwinbind enum users\fR parameter is false,
+calls to the \fBgetpwent\fR system call will not
+return any data.
+
+\fBWarning:\fR Turning off user enumeration
+may cause some programs to behave oddly. For example, the \fBfinger\fR
+program relies on having access to the full user list when
+searching for matching usernames.
+
+Default: \fBwinbind enum users = yes \fR
+.TP
+\fBwinbind enum groups\fR
+On large installations it may be necessary
+to suppress the enumeration of groups through the \fB setgrent()\fR, \fBgetgrent()\fR and
+\fBendgrent()\fR group of system calls. If
+the \fIwinbind enum groups\fR parameter is
+false, calls to the \fBgetgrent()\fR system
+call will not return any data.
+
+\fBWarning:\fR Turning off group
+enumeration may cause some programs to behave oddly.
+
+Default: \fBwinbind enum groups = no \fR
+.TP
+\fBtemplate homedir\fR
+When filling out the user information
+for a Windows NT user, the \fBwinbindd\fR daemon
+uses this parameter to fill in the home directory for that user.
+If the string \fI%D\fR is present it is
+substituted with the user's Windows NT domain name. If the
+string \fI%U\fR is present it is substituted
+with the user's Windows NT user name.
+
+Default: \fBtemplate homedir = /home/%D/%U \fR
+.TP
+\fBtemplate shell\fR
+When filling out the user information for
+a Windows NT user, the \fBwinbindd\fR daemon
+uses this parameter to fill in the shell for that user.
+
+Default: \fBtemplate shell = /bin/false \fR
+.SH "EXAMPLE SETUP"
+.PP
+To setup winbindd for user and group lookups plus
+authentication from a domain controller use something like the
+following setup. This was tested on a RedHat 6.2 Linux box.
+.PP
+In \fI/etc/nsswitch.conf\fR put the
+following:
+.PP
+.sp
+.nf
+passwd: files winbind
+group: files winbind
+
+.sp
+.fi
+.PP
+In \fI/etc/pam.d/*\fR replace the
+\fIauth\fR lines with something like this:
+.PP
+.sp
+.nf
+auth required /lib/security/pam_securetty.so
+auth required /lib/security/pam_nologin.so
+auth sufficient /lib/security/pam_winbind.so
+auth required /lib/security/pam_pwdb.so use_first_pass shadow nullok
+
+.sp
+.fi
+.PP
+Note in particular the use of the \fIsufficient\fR
+keyword and the \fIuse_first_pass\fR keyword.
+.PP
+Now replace the account lines with this:
+.PP
+\fBaccount required /lib/security/pam_winbind.so
+\fR.PP
+The next step is to join the domain. To do that use the
+\fBsmbpasswd\fR program like this:
+.PP
+\fBsmbpasswd -j DOMAIN -r PDC -U
+Administrator\fR
+.PP
+The username after the \fI-U\fR can be any
+Domain user that has administrator privileges on the machine.
+Substitute your domain name for "DOMAIN" and the name of your PDC
+for "PDC".
+.PP
+Next copy \fIlibnss_winbind.so\fR to
+\fI/lib\fR and \fIpam_winbind.so\fR
+to \fI/lib/security\fR. A symbolic link needs to be
+made from \fI/lib/libnss_winbind.so\fR to
+\fI/lib/libnss_winbind.so.2\fR. If you are using an
+older version of glibc then the target of the link should be
+\fI/lib/libnss_winbind.so.1\fR.
+.PP
+Finally, setup a \fIsmb.conf\fR containing directives like the
+following:
+.PP
+.sp
+.nf
+[global]
+ winbind separator = +
+ winbind cache time = 10
+ template shell = /bin/bash
+ template homedir = /home/%D/%U
+ winbind uid = 10000-20000
+ winbind gid = 10000-20000
+ workgroup = DOMAIN
+ security = domain
+ password server = *
+
+.sp
+.fi
+.PP
+Now start winbindd and you should find that your user and
+group database is expanded to include your NT users and groups,
+and that you can login to your unix box as a domain user, using
+the DOMAIN+user syntax for the username. You may wish to use the
+commands \fBgetent passwd\fR and \fBgetent group
+\fRto confirm the correct operation of winbindd.
+.SH "NOTES"
+.PP
+The following notes are useful when configuring and
+running \fBwinbindd\fR:
+.PP
+\fBnmbd\fR must be running on the local machine
+for \fBwinbindd\fR to work. \fBwinbindd\fR
+queries the list of trusted domains for the Windows NT server
+on startup and when a SIGHUP is received. Thus, for a running \fB winbindd\fR to become aware of new trust relationships between
+servers, it must be sent a SIGHUP signal.
+.PP
+Client processes resolving names through the \fBwinbindd\fR
+nsswitch module read an environment variable named \fB $WINBINDD_DOMAIN\fR. If this variable contains a comma separated
+list of Windows NT domain names, then winbindd will only resolve users
+and groups within those Windows NT domains.
+.PP
+PAM is really easy to misconfigure. Make sure you know what
+you are doing when modifying PAM configuration files. It is possible
+to set up PAM such that you can no longer log into your system.
+.PP
+If more than one UNIX machine is running \fBwinbindd\fR,
+then in general the user and groups ids allocated by winbindd will not
+be the same. The user and group ids will only be valid for the local
+machine.
+.PP
+If the the Windows NT RID to UNIX user and group id mapping
+file is damaged or destroyed then the mappings will be lost.
+.SH "SIGNALS"
+.PP
+The following signals can be used to manipulate the
+\fBwinbindd\fR daemon.
+.TP
+\fBSIGHUP\fR
+Reload the \fIsmb.conf(5)\fR
+file and apply any parameter changes to the running
+version of winbindd. This signal also clears any cached
+user and group information. The list of other domains trusted
+by winbindd is also reloaded.
+.TP
+\fBSIGUSR1\fR
+The SIGUSR1 signal will cause \fB winbindd\fR to write status information to the winbind
+log file including information about the number of user and
+group ids allocated by \fBwinbindd\fR.
+
+Log files are stored in the filename specified by the
+log file parameter.
+.SH "FILES"
+.TP
+\fB\fI/etc/nsswitch.conf(5)\fB\fR
+Name service switch configuration file.
+.TP
+\fB/tmp/.winbindd/pipe\fR
+The UNIX pipe over which clients communicate with
+the \fBwinbindd\fR program. For security reasons, the
+winbind client will only attempt to connect to the winbindd daemon
+if both the \fI/tmp/.winbindd\fR directory
+and \fI/tmp/.winbindd/pipe\fR file are owned by
+root.
+.TP
+\fB/lib/libnss_winbind.so.X\fR
+Implementation of name service switch library.
+.TP
+\fB$LOCKDIR/winbindd_idmap.tdb\fR
+Storage for the Windows NT rid to UNIX user/group
+id mapping. The lock directory is specified when Samba is initially
+compiled using the \fI--with-lockdir\fR option.
+This directory is by default \fI/usr/local/samba/var/locks
+\fR\&.
+.TP
+\fB$LOCKDIR/winbindd_cache.tdb\fR
+Storage for cached user and group information.
+.SH "VERSION"
+.PP
+This man page is correct for version 2.2 of
+the Samba suite.
+.SH "SEE ALSO"
+.PP
+\fInsswitch.conf(5)\fR,
+samba(7)
+wbinfo(1)
+smb.conf(5)
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities
+were created by Andrew Tridgell. Samba is now developed
+by the Samba Team as an Open Source project similar
+to the way the Linux kernel is developed.
+.PP
+\fBwbinfo\fR and \fBwinbindd\fR
+were written by Tim Potter.
+.PP
+The conversion to DocBook for Samba 2.2 was done
+by Gerald Carter
diff --git a/docs/textdocs/Application_Serving.txt b/docs/textdocs/Application_Serving.txt
new file mode 100755
index 00000000000..55125b7bad5
--- /dev/null
+++ b/docs/textdocs/Application_Serving.txt
@@ -0,0 +1,59 @@
+!==
+!== Application_Serving.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributed: January 7, 1997
+Updated: March 24, 1998
+Contributor: John H Terpstra <samba@samba.org>
+ Copyright (C) 1997 - John H Terpstra
+Status: Current
+
+Subject: Using a Samba share as an administrative share for MS Office, etc.
+==============================================================================
+
+Problem:
+========
+Microsoft Office products can be installed as an administrative installation
+from which the application can either be run off the administratively installed
+product that resides on a shared resource, or from which that product can be
+installed onto workstation clients.
+
+The general mechanism for implementing an adminstrative installation involves
+running:
+ X:\setup /A, where X is the drive letter of either CDROM or floppy
+
+This installation process will NOT install the product for use per se, but
+rather results in unpacking of the compressed distribution files into a target
+shared folder. For this process you need write privilidge to the share and it
+is desirable to enable file locking and share mode operation during this
+process.
+
+Subsequent installation of MS Office from this share will FAIL unless certain
+precautions are taken. This failure will be caused by share mode operation
+which will prevent the MS Office installation process from re-opening various
+dynamic link library files and will cause sporadic file not found problems.
+
+Solution:
+=========
+1. As soon as the administrative installation (unpacking) has completed
+ set the following parameters on the share containing it:
+ [MSOP95]
+ path = /where_you_put_it
+ comment = Your comment
+ volume = "The_CD_ROM_Label"
+ read only = yes
+ available = yes
+ share modes = no
+ locking = no
+ browseable = yes
+ public = yes
+
+2. Now you are ready to run the setup program from the Microsoft Windows
+workstation as follows:-
+ \\"Server_Name"\MSOP95\msoffice\setup
+
+MS Office Sharing - Please note:
+================================
+
+Workgroup Templates should be stored on an ordinary writable or read-only share
+but USER templates MUST be stored on a writable share _OR_ on the users' local
+machine.
diff --git a/docs/textdocs/BROWSING-Config.txt b/docs/textdocs/BROWSING-Config.txt
new file mode 100755
index 00000000000..26f55dc4c38
--- /dev/null
+++ b/docs/textdocs/BROWSING-Config.txt
@@ -0,0 +1,218 @@
+!==
+!== BROWSING-Config.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Date: July 5, 1998
+Contributor: John H Terpstra <jht@samba.org>
+
+Subject: Cross Subnet Browsing / Cross Workgroup Browsing
+===============================================================================
+
+OVERVIEW:
+=========
+
+This document should be read in conjunction with BROWSING.txt and may
+be taken as the fast track guide to implementing browsing across subnets
+and / or across workgroups (or domains). WINS is the best tool for resolution
+of NetBIOS names to IP addesses. WINS is NOT involved in browse list handling
+except by way of name to address mapping.
+
+
+DISCUSSION:
+===========
+
+Firstly, all MS Windows networking is based on SMB (Server Message
+Block) based messaging. SMB messaging is implemented using NetBIOS. Samba
+implements NetBIOS by encapsulating it over TCP/IP. MS Windows products can
+do likewise. NetBIOS based networking uses broadcast messaging to affect
+browse list management. When running NetBIOS over TCP/IP this uses UDP
+based messaging. UDP messages can be broadcast or unicast.
+
+Normally, only unicast UDP messaging can be forwarded by routers. The
+"remote announce" parameter to smb.conf helps to project browse announcements
+to remote network segments via unicast UDP. Similarly, the "remote browse sync"
+parameter of smb.conf implements browse list collation using unicast UDP.
+
+Secondly, in those networks where Samba is the only SMB server technology
+wherever possible nmbd should be configured on one (1) machine as the WINS
+server. This makes it easy to manage the browsing environment. If each network
+segment is configured with it's own Samba WINS server, then the only way to
+get cross segment browsing to work is by using the "remote announce" and
+the "remote browse sync" parameters to your smb.conf file.
+
+If only one WINS server is used then the use of the "remote announce" and the
+"remote browse sync" parameters should NOT be necessary.
+
+Samba WINS does not support MS-WINS replication. This means that when setting up
+Samba as a WINS server there must only be one nmbd configured as a WINS server
+on the network. Some sites have used multiple Samba WINS servers for redundancy
+(one server per subnet) and then used "remote browse sync" and "remote announce"
+to affect browse list collation across all segments. Note that this means
+clients will only resolve local names, and must be configured to use DNS to
+resolve names on other subnets in order to resolve the IP addresses of the
+servers they can see on other subnets. This setup is not recommended, but is
+mentioned as a practical consideration (ie: an 'if all else fails' scenario).
+
+Lastly, take note that browse lists are a collection of unreliable broadcast
+messages that are repeated at intervals of not more than 15 minutes. This means
+that it will take time to establish a browse list and it can take up to 45
+minutes to stabilise, particularly across network segments.
+
+
+A) Use of the "Remote Announce" parameter
+------------------------------------------
+The "remote announce" parameter of smb.conf can be used to forcibly ensure
+that all the NetBIOS names on a network get announced to a remote network.
+The syntax of the "remote announce" parameter is:
+
+ remote announce = a.b.c.d [e.f.g.h] ...
+_or_
+ remote announce = a.b.c.d/WORKGROUP [e.f.g.h/WORKGROUP] ...
+
+where:
+ a.b.c.d: is either the LMB (Local Master Browser) IP address
+ e.f.g.h: or the broadcst address of the remote network.
+ ie: the LMB is at 192.168.1.10, or the address
+ could be given as 192.168.1.255 where the netmask
+ is assumed to be 24 bits (255.255.255.0).
+ When the remote announcement is made to the broadcast
+ address of the remote network every host will receive
+ our announcements. This is noisy and therefore
+ undesirable but may be necessary if we do NOT know
+ the IP address of the remote LMB.
+
+ WORKGROUP: is optional and can be either our own workgroup
+ or that of the remote network. If you use the
+ workgroup name of the remote network then our
+ NetBIOS machine names will end up looking like
+ they belong to that workgroup, this may cause
+ name resolution problems and should be avoided.
+
+
+B) Use of the "Remote Browse Sync" parameter
+--------------------------------------------
+
+The "remote browse sync" parameter of smb.conf is used to announce to
+another LMB that it must synchronise it's NetBIOS name list with our
+Samba LMB. It works ONLY if the Samba server that has this option is
+simultaneously the LMB on it's network segment.
+
+The syntax of the "remote browse sync" parameter is:
+
+ remote browse sync = a.b.c.d
+
+where:
+ a.b.c.d: is either the IP address of the remote LMB or else
+ is the network broadcast address of the remote segment.
+
+
+C) Use of WINS
+--------------
+
+Use of WINS (either Samba WINS _or_ MS Windows NT Server WINS) is highly
+recommended. Every NetBIOS machine registers it's name together with a
+name_type value for each of of several types of service it has available.
+eg: It registers it's name directly as a unique (the type 0x03) name.
+It also registers it's name if it is running the lanmanager compatible
+server service (used to make shares and printers available to other users)
+by registering the server (the type 0x20) name.
+
+All NetBIOS names are up to 15 characters in length. The name_type variable
+is added to the end of the name - thus creating a 16 character name. Any
+name that is shorter than 15 characters is padded with spaces to the 15th
+character. ie: All NetBIOS names are 16 characters long (including the
+name_type information).
+
+WINS can store these 16 character names as they get registered. A client
+that wants to log onto the network can ask the WINS server for a list
+of all names that have registered the NetLogon service name_type. This saves
+broadcast traffic and greatly expedites logon processing. Since broadcast
+name resolution can not be used across network segments this type of
+information can only be provided via WINS _or_ via statically configured
+"lmhosts" files that must reside on all clients in the absence of WINS.
+
+WINS also serves the purpose of forcing browse list synchronisation by all
+LMB's. LMB's must synchronise their browse list with the DMB (domain master
+browser) and WINS helps the LMB to identify it's DMB. By definition this
+will work only within a single workgroup. Note that the domain master browser
+has NOTHING to do with what is referred to as an MS Windows NT Domain. The
+later is a reference to a security environment while the DMB refers to the
+master controller for browse list information only.
+
+Use of WINS will work correctly only if EVERY client TCP/IP protocol stack
+has been configured to use the WINS server/s. Any client that has not been
+configured to use the WINS server will continue to use only broadcast based
+name registration so that WINS may NEVER get to know about it. In any case,
+machines that have not registered with a WINS server will fail name to address
+lookup attempts by other clients and will therefore cause workstation access
+errors.
+
+To configure Samba as a WINS server just add "wins support = yes" to the
+smb.conf file [globals] section.
+
+To configure Samba to register with a WINS server just add
+"wins server = a.b.c.d" to your smb.conf file [globals] section.
+
+DO NOT EVER use both "wins support = yes" together with "wins server = a.b.c.d"
+particularly not using it's own IP address.
+
+
+D) Do NOT use more than one (1) protocol on MS Windows machines
+---------------------------------------------------------------
+
+A very common cause of browsing problems results from installing more than
+one protocol on an MS Windows machine.
+
+Every NetBIOS machine take part in a process of electing the LMB (and DMB)
+every 15 minutes. A set of election criteria is used to determine the order
+of precidence for winning this election process. A machine running Samba or
+Windows NT will be biased so that the most suitable machine will predictably
+win and thus retain it's role.
+
+The election process is "fought out" so to speak over every NetBIOS network
+interface. In the case of a Windows 9x machine that has both TCP/IP and IPX
+installed and has NetBIOS enabled over both protocols the election will be
+decided over both protocols. As often happens, if the Windows 9x machine is
+the only one with both protocols then the LMB may be won on the NetBIOS
+interface over the IPX protocol. Samba will then lose the LMB role as Windows
+9x will insist it knows who the LMB is. Samba will then cease to function
+as an LMB and thus browse list operation on all TCP/IP only machines will
+fail.
+
+The safest rule of all to follow it this - USE ONLY ONE PROTOCOL!
+
+
+E) Name Resolution Order
+========================
+
+Resolution of NetBIOS names to IP addresses can take place using a number
+of methods. The only ones that can provide NetBIOS name_type information
+are:
+ WINS: the best tool!
+ LMHOSTS: is static and hard to maintain.
+ Broadcast: uses UDP and can not resolve names across
+ remote segments.
+
+Alternative means of name resolution includes:
+ /etc/hosts: is static, hard to maintain, and lacks name_type info.
+ DNS: is a good choice but lacks essential name_type info.
+
+Many sites want to restrict DNS lookups and want to avoid broadcast name
+resolution traffic. The "name resolve order" parameter is of great help here.
+The syntax of the "name resolve order" parameter is:
+
+ name resolve order = wins lmhosts bcast host
+_or_
+ name resolve order = wins lmhosts (eliminates bcast and host)
+
+the default is:
+ name resolve order = host lmhost wins bcast
+
+where:
+ "host" refers the the native methods used by the Unix system
+ to implement the gethostbyname() function call. This is normally
+ controlled by:
+ /etc/host.conf
+ /etc/nsswitch.conf
+ /etc/resolv.conf
+
+===============================================================================
diff --git a/docs/textdocs/BROWSING.txt b/docs/textdocs/BROWSING.txt
new file mode 100755
index 00000000000..af57e4d5c39
--- /dev/null
+++ b/docs/textdocs/BROWSING.txt
@@ -0,0 +1,562 @@
+!==
+!== BROWSING.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Author/s: Many (Thanks to Luke, Jeremy, Andrew, etc.)
+Updated: July 5, 1998
+Status: Current - For VERY Advanced Users ONLY
+
+Summary: This describes how to configure Samba for improved browsing.
+=====================================================================
+
+OVERVIEW:
+=========
+
+SMB networking provides a mechanism by which clients can access a list
+of machines in a network, a so-called "browse list". This list
+contains machines that are ready to offer file and/or print services
+to other machines within the network. Thus it does not include
+machines which aren't currently able to do server tasks. The browse
+list is heavily used by all SMB clients. Configuration of SMB
+browsing has been problematic for some Samba users, hence this
+document.
+
+Browsing will NOT work if name resolution from NetBIOS names to IP
+addresses does not function correctly. Use of a WINS server is highly
+recommended to aid the resolution of NetBIOS (SMB) names to IP addresses.
+WINS allows remote segment clients to obtain NetBIOS name_type information
+that can NOT be provided by any other means of name resolution.
+
+=====================================================================
+
+BROWSING
+========
+Samba now fully supports browsing. The browsing is supported by nmbd
+and is also controlled by options in the smb.conf file (see smb.conf(5)).
+
+Samba can act as a local browse master for a workgroup and the ability
+for samba to support domain logons and scripts is now available. See
+DOMAIN.txt for more information on domain logons.
+
+Samba can also act as a domain master browser for a workgroup. This
+means that it will collate lists from local browse masters into a
+wide area network server list. In order for browse clients to
+resolve the names they may find in this list, it is recommended that
+both samba and your clients use a WINS server.
+
+Note that you should NOT set Samba to be the domain master for a
+workgroup that has the same name as an NT Domain: on each wide area
+network, you must only ever have one domain master browser per workgroup,
+regardless of whether it is NT, Samba or any other type of domain master
+that is providing this service.
+
+[Note that nmbd can be configured as a WINS server, but it is not
+necessary to specifically use samba as your WINS server. NTAS can
+be configured as your WINS server. In a mixed NT server and
+samba environment on a Wide Area Network, it is recommended that
+you use the NT server's WINS server capabilities. In a samba-only
+environment, it is recommended that you use one and only one nmbd
+as your WINS server].
+
+To get browsing to work you need to run nmbd as usual, but will need
+to use the "workgroup" option in smb.conf to control what workgroup
+Samba becomes a part of.
+
+Samba also has a useful option for a Samba server to offer itself for
+browsing on another subnet. It is recommended that this option is only
+used for 'unusual' purposes: announcements over the internet, for
+example. See "remote announce" in the smb.conf man page.
+
+If something doesn't work then hopefully the log.nmb file will help
+you track down the problem. Try a debug level of 2 or 3 for finding
+problems. Also note that the current browse list usually gets stored
+in text form in a file called browse.dat.
+
+Note that if it doesn't work for you, then you should still be able to
+type the server name as \\SERVER in filemanager then hit enter and
+filemanager should display the list of available shares.
+
+Some people find browsing fails because they don't have the global
+"guest account" set to a valid account. Remember that the IPC$
+connection that lists the shares is done as guest, and thus you must
+have a valid guest account.
+
+Also, a lot of people are getting bitten by the problem of too many
+parameters on the command line of nmbd in inetd.conf. This trick is to
+not use spaces between the option and the parameter (eg: -d2 instead
+of -d 2), and to not use the -B and -N options. New versions of nmbd
+are now far more likely to correctly find your broadcast and network
+address, so in most cases these aren't needed.
+
+The other big problem people have is that their broadcast address,
+netmask or IP address is wrong (specified with the "interfaces" option
+in smb.conf)
+
+
+BROWSING ACROSS SUBNETS
+=======================
+
+With the release of Samba 1.9.17(alpha1 and above) Samba has been
+updated to enable it to support the replication of browse lists
+across subnet boundaries. New code and options have been added to
+achieve this. This section describes how to set this feature up
+in different settings.
+
+To see browse lists that span TCP/IP subnets (ie. networks separated
+by routers that don't pass broadcast traffic) you must set up at least
+one WINS server. The WINS server acts as a DNS for NetBIOS names, allowing
+NetBIOS name to IP address translation to be done by doing a direct
+query of the WINS server. This is done via a directed UDP packet on
+port 137 to the WINS server machine. The reason for a WINS server is
+that by default, all NetBIOS name to IP address translation is done
+by broadcasts from the querying machine. This means that machines
+on one subnet will not be able to resolve the names of machines on
+another subnet without using a WINS server.
+
+Remember, for browsing across subnets to work correctly, all machines,
+be they Windows 95, Windows NT, or Samba servers must have the IP address
+of a WINS server given to them by a DHCP server, or by manual configuration
+(for Win95 and WinNT, this is in the TCP/IP Properties, under Network
+settings) for Samba this is in the smb.conf file.
+
+How does cross subnet browsing work ?
+=====================================
+
+Cross subnet browsing is a complicated dance, containing multiple
+moving parts. It has taken Microsoft several years to get the code
+that achieves this correct, and Samba lags behind in some areas.
+However, with the 1.9.17 release, Samba is capable of cross subnet
+browsing when configured correctly.
+
+Consider a network set up as follows :
+
+ (DMB)
+ N1_A N1_B N1_C N1_D N1_E
+ | | | | |
+ -------------------------------------------------------
+ | subnet 1 |
+ +---+ +---+
+ |R1 | Router 1 Router 2 |R2 |
+ +---+ +---+
+ | |
+ | subnet 2 subnet 3 |
+ -------------------------- ------------------------------------
+ | | | | | | | |
+ N2_A N2_B N2_C N2_D N3_A N3_B N3_C N3_D
+ (WINS)
+
+Consisting of 3 subnets (1, 2, 3) conneted by two routers
+(R1, R2) - these do not pass broadcasts. Subnet 1 has 5 machines
+on it, subnet 2 has 4 machines, subnet 3 has 4 machines. Assume
+for the moment that all these machines are configured to be in the
+same workgroup (for simplicities sake). Machine N1_C on subnet 1
+is configured as Domain Master Browser (ie. it will collate the
+browse lists for the workgroup). Machine N2_D is configured as
+WINS server and all the other machines are configured to register
+their NetBIOS names with it.
+
+As all these machines are booted up, elections for master browsers
+will take place on each of the three subnets. Assume that machine
+N1_C wins on subnet 1, N2_B wins on subnet 2, and N3_D wins on
+subnet 3 - these machines are known as local master browsers for
+their particular subnet. N1_C has an advantage in winning as the
+local master browser on subnet 1 as it is set up as Domain Master
+Browser.
+
+On each of the three networks, machines that are configured to
+offer sharing services will broadcast that they are offering
+these services. The local master browser on each subnet will
+receive these broadcasts and keep a record of the fact that
+the machine is offering a service. This list of records is
+the basis of the browse list. For this case, assume that
+all the machines are configured to offer services so all machines
+will be on the browse list.
+
+For each network, the local master browser on that network is
+considered 'authoritative' for all the names it receives via
+local broadcast. This is because a machine seen by the local
+master browser via a local broadcast must be on the same
+network as the local master browser and thus is a 'trusted'
+and 'verifiable' resource. Machines on other networks that
+the local master browsers learn about when collating their
+browse lists have not been directly seen - these records are
+called 'non-authoritative'.
+
+At this point the browse lists look as follows (these are
+the machines you would see in your network neighborhood if
+you looked in it on a particular network right now).
+
+Subnet Browse Master List
+------ ------------- ----
+Subnet1 N1_C N1_A, N1_B, N1_C, N1_D, N1_E
+
+Subnet2 N2_B N2_A, N2_B, N2_C, N2_D
+
+Subnet3 N3_D N3_A, N3_B, N3_C, N3_D
+
+Note that at this point all the subnets are separate, no
+machine is seen across any of the subnets.
+
+Now examine subnet 2. As soon as N2_B has become the local
+master browser it looks for a Domain master browser to synchronize
+its browse list with. It does this by querying the WINS server
+(N2_D) for the IP address associated with the NetBIOS name
+WORKGROUP<1B>. This name was registerd by the Domain master
+browser (N1_C) with the WINS server as soon as it was booted.
+
+Once N2_B knows the address of the Domain master browser it
+tells it that is the local master browser for subnet 2 by
+sending a MasterAnnouncement packet as a UDP port 138 packet.
+It then synchronizes with it by doing a NetServerEnum2 call. This
+tells the Domain Master Browser to send it all the server
+names it knows about. Once the domain master browser receives
+the MasterAnnouncement packet it schedules a synchronization
+request to the sender of that packet. After both synchronizations
+are done the browse lists look like :
+
+Subnet Browse Master List
+------ ------------- ----
+Subnet1 N1_C N1_A, N1_B, N1_C, N1_D, N1_E,
+ N2_A(*), N2_B(*), N2_C(*), N2_D(*)
+
+Subnet2 N2_B N2_A, N2_B, N2_C, N2_D
+ N1_A(*), N1_B(*), N1_C(*), N1_D(*), N1_E(*)
+
+Subnet3 N3_D N3_A, N3_B, N3_C, N3_D
+
+Servers with a (*) after them are non-authoritative names.
+
+At this point users looking in their network neighborhood on
+subnets 1 or 2 will see all the servers on both, users on
+subnet 3 will still only see the servers on their own subnet.
+
+The same sequence of events that occured for N2_B now occurs
+for the local master browser on subnet 3 (N3_D). When it
+synchronizes browse lists with the domain master browser (N1_A)
+it gets both the server entries on subnet 1, and those on
+subnet 2. After N3_D has synchronized with N1_C and vica-versa
+the browse lists look like.
+
+Subnet Browse Master List
+------ ------------- ----
+Subnet1 N1_C N1_A, N1_B, N1_C, N1_D, N1_E,
+ N2_A(*), N2_B(*), N2_C(*), N2_D(*),
+ N3_A(*), N3_B(*), N3_C(*), N3_D(*)
+
+Subnet2 N2_B N2_A, N2_B, N2_C, N2_D
+ N1_A(*), N1_B(*), N1_C(*), N1_D(*), N1_E(*)
+
+Subnet3 N3_D N3_A, N3_B, N3_C, N3_D
+ N1_A(*), N1_B(*), N1_C(*), N1_D(*), N1_E(*),
+ N2_A(*), N2_B(*), N2_C(*), N2_D(*)
+
+Servers with a (*) after them are non-authoritative names.
+
+At this point users looking in their network neighborhood on
+subnets 1 or 3 will see all the servers on all sunbets, users on
+subnet 2 will still only see the servers on subnets 1 and 2, but not 3.
+
+Finally, the local master browser for subnet 2 (N2_B) will sync again
+with the domain master browser (N1_C) and will recieve the missing
+server entries. Finally - and as a steady state (if no machines
+are removed or shut off) the browse lists will look like :
+
+Subnet Browse Master List
+------ ------------- ----
+Subnet1 N1_C N1_A, N1_B, N1_C, N1_D, N1_E,
+ N2_A(*), N2_B(*), N2_C(*), N2_D(*),
+ N3_A(*), N3_B(*), N3_C(*), N3_D(*)
+
+Subnet2 N2_B N2_A, N2_B, N2_C, N2_D
+ N1_A(*), N1_B(*), N1_C(*), N1_D(*), N1_E(*)
+ N3_A(*), N3_B(*), N3_C(*), N3_D(*)
+
+Subnet3 N3_D N3_A, N3_B, N3_C, N3_D
+ N1_A(*), N1_B(*), N1_C(*), N1_D(*), N1_E(*),
+ N2_A(*), N2_B(*), N2_C(*), N2_D(*)
+
+Servers with a (*) after them are non-authoritative names.
+
+Synchronizations between the domain master browser and local
+master browsers will continue to occur, but this should be a
+steady state situation.
+
+If either router R1 or R2 fails the following will occur:
+
+1) Names of computers on each side of the inaccessible network fragments
+will be maintained for as long as 36 minutes, in the network neighbourhood
+lists.
+
+2) Attempts to connect to these inaccessible computers will fail, but the
+names will not be removed from the network neighbourhood lists.
+
+3) If one of the fragments is cut off from the WINS server, it will only
+be able to access servers on its local subnet, by using subnet-isolated
+broadcast NetBIOS name resolution. The effects are similar to that of
+losing access to a DNS server.
+
+Setting up a WINS server
+========================
+
+Either a Samba machine or a Windows NT Server machine may be set up
+as a WINS server. To set a Samba machine to be a WINS server you must
+add the following option to the smb.conf file on the selected machine :
+in the [globals] section add the line
+
+ wins support = yes
+
+Versions of Samba previous to 1.9.17 had this parameter default to
+yes. If you have any older versions of Samba on your network it is
+strongly suggested you upgrade to 1.9.17 or above, or at the very
+least set the parameter to 'no' on all these machines.
+
+Machines with "wins support = yes" will keep a list of all NetBIOS
+names registered with them, acting as a DNS for NetBIOS names.
+
+You should set up only ONE wins server. Do NOT set the
+"wins support = yes" option on more than one Samba server.
+
+To set up a Windows NT Server as a WINS server you need to set up
+the WINS service - see your NT documentation for details. Note that
+Windows NT WINS Servers can replicate to each other, allowing more
+than one to be set up in a complex subnet environment. As Microsoft
+refuse to document these replication protocols Samba cannot currently
+participate in these replications. It is possible in the future that
+a Samba->Samba WINS replication protocol may be defined, in which
+case more than one Samba machine could be set up as a WINS server
+but currently only one Samba server should have the "wins support = yes"
+parameter set.
+
+After the WINS server has been configured you must ensure that all
+machines participating on the network are configured with the address
+of this WINS server. If your WINS server is a Samba machine, fill in
+the Samba machine IP address in the "Primary WINS Server" field of
+the "Control Panel->Network->Protocols->TCP->WINS Server" dialogs
+in Windows 95 or Windows NT. To tell a Samba server the IP address
+of the WINS server add the following line to the [global] section of
+all smb.conf files :
+
+ wins server = <name or IP address>
+
+where <name or IP address> is either the DNS name of the WINS server
+machine or its IP address.
+
+Note that this line MUST NOT BE SET in the smb.conf file of the Samba
+server acting as the WINS server itself. If you set both the
+"wins support = yes" option and the "wins server = <name>" option then
+nmbd will fail to start.
+
+There are two possible scenarios for setting up cross subnet browsing.
+The first details setting up cross subnet browsing on a network containing
+Windows 95, Samba and Windows NT machines that are not configured as
+part of a Windows NT Domain. The second details setting up cross subnet
+browsing on networks that contain NT Domains.
+
+Setting up Browsing in a WORKGROUP
+==================================
+
+To set up cross subnet browsing on a network containing machines
+in up to be in a WORKGROUP, not an NT Domain you need to set up one
+Samba server to be the Domain Master Browser (note that this is *NOT*
+the same as a Primary Domain Controller, although in an NT Domain the
+same machine plays both roles). The role of a Domain master browser is
+to collate the browse lists from local master browsers on all the
+subnets that have a machine participating in the workgroup. Without
+one machine configured as a domain master browser each subnet would
+be an isolated workgroup, unable to see any machines on any other
+subnet. It is the presense of a domain master browser that makes
+cross subnet browsing possible for a workgroup.
+
+In an WORKGROUP environment the domain master browser must be a
+Samba server, and there must only be one domain master browser per
+workgroup name. To set up a Samba server as a domain master browser,
+set the following option in the [global] section of the smb.conf file :
+
+ domain master = yes
+
+The domain master browser should also preferrably be the local master
+browser for its own subnet. In order to achieve this set the following
+options in the [global] section of the smb.conf file :
+
+ domain master = yes
+ local master = yes
+ preferred master = yes
+ os level = 65
+
+The domain master browser may be the same machine as the WINS
+server, if you require.
+
+Next, you should ensure that each of the subnets contains a
+machine that can act as a local master browser for the
+workgroup. Any NT machine should be able to do this, as will
+Windows 95 machines (although these tend to get rebooted more
+often, so it's not such a good idea to use these). To make a
+Samba server a local master browser set the following
+options in the [global] section of the smb.conf file :
+
+ domain master = no
+ local master = yes
+ preferred master = yes
+ os level = 65
+
+Do not do this for more than one Samba server on each subnet,
+or they will war with each other over which is to be the local
+master browser.
+
+The "local master" parameter allows Samba to act as a local master
+browser. The "preferred master" causes nmbd to force a browser
+election on startup and the "os level" parameter sets Samba high
+enough so that it should win any browser elections.
+
+If you have an NT machine on the subnet that you wish to
+be the local master browser then you can disable Samba from
+becoming a local master browser by setting the following
+options in the [global] section of the smb.conf file :
+
+ domain master = no
+ local master = no
+ preferred master = no
+ os level = 0
+
+Setting up Browsing in a DOMAIN
+===============================
+
+If you are adding Samba servers to a Windows NT Domain then
+you must not set up a Samba server as a domain master browser.
+By default, a Windows NT Primary Domain Controller for a Domain
+name is also the Domain master browser for that name, and many
+things will break if a Samba server registers the Domain master
+browser NetBIOS name (DOMAIN<1B>) with WINS instead of the PDC.
+
+For subnets other than the one containing the Windows NT PDC
+you may set up Samba servers as local master browsers as
+described. To make a Samba server a local master browser set
+the following options in the [global] section of the smb.conf
+file :
+
+ domain master = no
+ local master = yes
+ preferred master = yes
+ os level = 65
+
+If you wish to have a Samba server fight the election with machines
+on the same subnet you may set the "os level" parameter to lower
+levels. By doing this you can tune the order of machines that
+will become local master browsers if they are running. For
+more details on this see the section "FORCING SAMBA TO BE THE MASTER"
+below.
+
+If you have Windows NT machines that are members of the domain
+on all subnets, and you are sure they will always be running then
+you can disable Samba from taking part in browser elections and
+ever becoming a local master browser by setting following options
+in the [global] section of the smb.conf file :
+
+ domain master = no
+ local master = no
+ preferred master = no
+ os level = 0
+
+FORCING SAMBA TO BE THE MASTER
+==============================
+
+Who becomes the "master browser" is determined by an election process
+using broadcasts. Each election packet contains a number of parameters
+which determine what precedence (bias) a host should have in the
+election. By default Samba uses a very low precedence and thus loses
+elections to just about anyone else.
+
+If you want Samba to win elections then just set the "os level" global
+option in smb.conf to a higher number. It defaults to 0. Using 34
+would make it win all elections over every other system (except other
+samba systems!)
+
+A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A
+NTAS domain controller uses level 32.
+
+The maximum os level is 255
+
+If you want samba to force an election on startup, then set the
+"preferred master" global option in smb.conf to "yes". Samba will
+then have a slight advantage over other potential master browsers
+that are not preferred master browsers. Use this parameter with
+care, as if you have two hosts (whether they are windows 95 or NT or
+samba) on the same local subnet both set with "preferred master" to
+"yes", then periodically and continually they will force an election
+in order to become the local master browser.
+
+If you want samba to be a "domain master browser", then it is
+recommended that you also set "preferred master" to "yes", because
+samba will not become a domain master browser for the whole of your
+LAN or WAN if it is not also a local master browser on its own
+broadcast isolated subnet.
+
+It is possible to configure two samba servers to attempt to become
+the domain master browser for a domain. The first server that comes
+up will be the domain master browser. All other samba servers will
+attempt to become the domain master browser every 5 minutes. They
+will find that another samba server is already the domain master
+browser and will fail. This provides automatic redundancy, should
+the current domain master browser fail.
+
+
+MAKING SAMBA THE DOMAIN MASTER
+==============================
+
+The domain master is responsible for collating the browse lists of
+multiple subnets so that browsing can occur between subnets. You can
+make samba act as the domain master by setting "domain master = yes"
+in smb.conf. By default it will not be a domain master.
+
+Note that you should NOT set Samba to be the domain master for a
+workgroup that has the same name as an NT Domain.
+
+When samba is the domain master and the master browser it will listen
+for master announcements (made roughly every twelve minutes) from local
+master browsers on other subnets and then contact them to synchronise
+browse lists.
+
+If you want samba to be the domain master then I suggest you also set
+the "os level" high enough to make sure it wins elections, and set
+"preferred master" to "yes", to get samba to force an election on
+startup.
+
+Note that all your servers (including samba) and clients should be
+using a WINS server to resolve NetBIOS names. If your clients are only
+using broadcasting to resolve NetBIOS names, then two things will occur:
+
+a) your local master browsers will be unable to find a domain master
+ browser, as it will only be looking on the local subnet.
+
+b) if a client happens to get hold of a domain-wide browse list, and
+ a user attempts to access a host in that list, it will be unable to
+ resolve the NetBIOS name of that host.
+
+If, however, both samba and your clients are using a WINS server, then:
+
+a) your local master browsers will contact the WINS server and, as long as
+ samba has registered that it is a domain master browser with the WINS
+ server, your local master browser will receive samba's ip address
+ as its domain master browser.
+
+b) when a client receives a domain-wide browse list, and a user attempts
+ to access a host in that list, it will contact the WINS server to
+ resolve the NetBIOS name of that host. as long as that host has
+ registered its NetBIOS name with the same WINS server, the user will
+ be able to see that host.
+
+NOTE ABOUT BROADCAST ADDRESSES
+==============================
+
+If your network uses a "0" based broadcast address (for example if it
+ends in a 0) then you will strike problems. Windows for Workgroups
+does not seem to support a 0's broadcast and you will probably find
+that browsing and name lookups won't work.
+
+
+MULTIPLE INTERFACES
+===================
+
+Samba now supports machines with multiple network interfaces. If you
+have multiple interfaces then you will need to use the "interfaces"
+option in smb.conf to configure them. See smb.conf(5) for details.
+
diff --git a/docs/textdocs/BUGS.txt b/docs/textdocs/BUGS.txt
new file mode 100755
index 00000000000..8dd6b0200f4
--- /dev/null
+++ b/docs/textdocs/BUGS.txt
@@ -0,0 +1,138 @@
+!==
+!== BUGS.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Samba Team
+Updated: June 27, 1997
+
+Subject: This file describes how to report Samba bugs.
+============================================================================
+
+>> The email address for bug reports is samba@samba.org <<
+
+Please take the time to read this file before you submit a bug
+report. Also, please see if it has changed between releases, as we
+may be changing the bug reporting mechanism at some time.
+
+Please also do as much as you can yourself to help track down the
+bug. Samba is maintained by a dedicated group of people who volunteer
+their time, skills and efforts. We receive far more mail about it than
+we can possibly answer, so you have a much higher chance of an answer
+and a fix if you send us a "developer friendly" bug report that lets
+us fix it fast.
+
+Do not assume that if you post the bug to the comp.protocols.smb
+newsgroup or the mailing list that we will read it. If you suspect that your
+problem is not a bug but a configuration problem then it is better to send
+it to the Samba mailing list, as there are (at last count) 5000 other users on
+that list that may be able to help you.
+
+You may also like to look though the recent mailing list archives,
+which are conveniently accessible on the Samba web pages
+at http://samba.org/samba/
+
+
+GENERAL INFO
+------------
+
+Before submitting a bug report check your config for silly
+errors. Look in your log files for obvious messages that tell you that
+you've misconfigured something and run testparm to test your config
+file for correct syntax.
+
+Have you run through DIAGNOSIS.txt? This is very important.
+
+If you include part of a log file with your bug report then be sure to
+annotate it with exactly what you were doing on the client at the
+time, and exactly what the results were.
+
+
+DEBUG LEVELS
+------------
+
+If the bug has anything to do with Samba behaving incorrectly as a
+server (like refusing to open a file) then the log files will probably
+be very useful. Depending on the problem a log level of between 3 and
+10 showing the problem may be appropriate. A higher level givesmore
+detail, but may use too much disk space.
+
+To set the debug level use "log level =" in your smb.conf. You may
+also find it useful to set the log level higher for just one machine
+and keep separate logs for each machine. To do this use:
+
+log level = 10
+log file = /usr/local/samba/lib/log.%m
+include = /usr/local/samba/lib/smb.conf.%m
+
+then create a file "/usr/local/samba/lib/smb.conf.machine" where
+"machine" is the name of the client you wish to debug. In that file
+put any smb.conf commands you want, for example "log level=" may be
+useful. This also allows you to experiment with different security
+systems, protocol levels etc on just one machine.
+
+The smb.conf entry "log level =" is synonymous with the entry
+"debuglevel =" that has been used in older versions of Samba and
+is being retained for backwards compatibility of smb.conf files.
+
+As the "log level =" value is increased you will record a significantly
+increasing level of debugging information. For most debugging operations
+you may not need a setting higher than 3. Nearly all bugs can be tracked
+at a setting of 10, but be prepared for a VERY large volume of log data.
+
+
+INTERNAL ERRORs
+---------------
+
+If you get a "INTERNAL ERROR" message in your log files it means that
+Samba got an unexpected signal while running. It is probably a
+segmentation fault and almost certainly means a bug in Samba (unless
+you have faulty hardware or system software)
+
+If the message came from smbd then it will probably be accompanied by
+a message which details the last SMB message received by smbd. This
+info is often very useful in tracking down the problem so please
+include it in your bug report.
+
+You should also detail how to reproduce the problem, if
+possible. Please make this reasonably detailed.
+
+You may also find that a core file appeared in a "corefiles"
+subdirectory of the directory where you keep your samba log
+files. This file is the most useful tool for tracking down the bug. To
+use it you do this:
+
+gdb smbd core
+
+adding appropriate paths to smbd and core so gdb can find them. If you
+don't have gdb then try "dbx". Then within the debugger use the
+command "where" to give a stack trace of where the problem
+occurred. Include this in your mail.
+
+If you known any assembly language then do a "disass" of the routine
+where the problem occurred (if its in a library routine then
+disassemble the routine that called it) and try to work out exactly
+where the problem is by looking at the surrounding code. Even if you
+don't know assembly then incuding this info in the bug report can be
+useful.
+
+
+ATTACHING TO A RUNNING PROCESS
+------------------------------
+
+Unfortunately some unixes (in particular some recent linux kernels)
+refuse to dump a core file if the task has changed uid (which smbd
+does often). To debug with this sort of system you could try to attach
+to the running process using "gdb smbd PID" where you get PID from
+smbstatus. Then use "c" to continue and try to cause the core dump
+using the client. The debugger should catch the fault and tell you
+where it occurred.
+
+
+PATCHES
+-------
+
+The best sort of bug report is one that includes a fix! If you send us
+patches please use "diff -u" format if your version of diff supports
+it, otherwise use "diff -c4". Make sure your do the diff against a
+clean version of the source and let me know exactly what version you
+used.
+
diff --git a/docs/textdocs/CUPS-PrintingInfo.txt b/docs/textdocs/CUPS-PrintingInfo.txt
new file mode 100755
index 00000000000..bbe14f33e8f
--- /dev/null
+++ b/docs/textdocs/CUPS-PrintingInfo.txt
@@ -0,0 +1,589 @@
+Date: Sun, 22 Sep 2002 15:38:02 +0200
+From: "Kurt Pfeifle" <kpfeifle@danka.de>
+Reply-To: kpfeifle@danka.de
+Organization: Danka Deutschland GmbH
+To: samba@lists.samba.org
+Subject: CUPS filtering mechanism explained, was: [cups raw mode, was Re: [Samba] unlink data file in cups_job_submit]
+
+Paul Janzen wrote on Samba digest:
+
+ > Message: 7
+ > To: Gerald Carter <jerry@samba.org>
+ > Cc: samba@lists.samba.org
+ > From: Paul Janzen <pcj@samba.sez.to>
+ > Subject: cups raw mode, was Re: [Samba] unlink data file in cups_job_submit
+ > Date: 21 Sep 2002 12:09:23 -0700
+ >
+ >
+ > Gerald Carter <jerry@samba.org> writes:
+ >
+ > > Looks right to me [:-)] Applying it now. Thanks. I've been meaning to
+ > > track this one down.
+ >
+ >
+ > Thanks!
+ >
+ > While we are on the subject... [:-)]
+ >
+ > If I am using native printer drivers on Windows clients, I would like
+ > the "raw" option to get propagated to CUPS. Otherwise cups does not
+ > pass the data on to the printer.
+
+Paul,
+
+I see you know about what you call the "raw data passthrough feature".
+I guess you mean the lines in "/etc/cups/mime.types" and
+"/etc/cups/mime.convs" which need to be uncommented to allow "raw"
+printing ?
+
+Here is some clarification (likely not very useful for you, but
+possibly for some other readers of the Samba list):
+
+### If you have "printing = cups" and "printcap = cups" enabled,
+--- everything is handled by Samba accessing the CUPS API. (And any
+ "print command" directive in Samba will be ignored.) If the CUPS
+ API is not available (because Samba might not be compiled against
+libcups), it automatically maps to the "System V" command set, with
+"-oraw" enabled automatically.
+
+ > (If I enable cups's application/
+ > octet-stream raw-data passthrough feature, both cupsomatic and the
+ > Windows driver add PJL headers and footers, which is not what I want
+ > either.)
+
+### According to my experience, cupsomatic on the Samba/CUPS server
+--- does *not* add any features if a file is really printed "raw".
+ However, if you have loaded the driver for the Windows client
+from the CUPS server, using the "cupsaddsmb" utility, and if this
+driver is one using a "Foomatic" PPD, the PJL header in question is
+already added on the Windows client, at the time when the driver
+initially generated the PostScript data -- and CUPS in true "-oraw"
+manner doesn't remove this PJL header and passes the file "as is"
+to its printer communication backend.
+
+NOTE, please, that the editing in the "mime.convs" and the
+----- "mime.types" file does not *enforce* "raw" printing, it
+ only *allows* it. Any file arriving from Windows is
+"auto-typed" by CUPS, which might consecutively lead to its
+treatment by various filters automatically (depending on the
+actual outcome of the auto-typing and the configuration of the
+printqueue in question):
+
+ --> Files generated by PCL drivers and destined to PCL
+ printers get auto-typed "application/octet-stream"
+ and are indeed printed "raw". Also, unknown file
+ types are getting tagged as "application/octet-stream".
+
+ --> Files generated by a PostScript driver (and destined
+ for any target printer type) are auto-typed. Depending
+ on the driver, the discovered MIME type may be
+
+ * application/postscript or
+ * application/vnd.cups-postscript
+
+"application/postscript" goes first thru the "pstops" filter
+ (where also the page counting and accounting takes place
+ currently), and the outcome will be of MIME type
+ "application/vnd.cups-postscript". The pstopsfilter reads and
+ uses information from the PPD and inserts user-provided options
+ into the PostScript file. As a consequence, the filtered file
+ will possibly have the PJL header you don't want.
+
+"application/postscript" will be all files with a ".ps", ".ai",
+ ".eps" suffix or which have as their first character string one
+ of "%!" or "<04>%".
+
+"application/vnd.cups-postscript" will be those files which do both,
+ first...
+ ...carry a string "LANGUAGE=POSTSCRIPT" (or similar variations
+ with different capitalization) amongst the first 512 bytes,
+ *plus*...
+ ...contain the "PJL super escape code" amongst the first 128
+ bytes ("<1B>%-12345X"). Very likely, most PostScript files
+ generated on Windows using a CUPS- or other PPD, will have
+ to be auto-typed as "vnd.cups-postscript".
+ Probably a file produced with a "Generic PostScript driver"
+ will be just "application/postscript" (have not checked).
+
+Once the file is in "application/vnd.cups-postscript" format,
+either "pstoraster" or "cupsomatic" will take over (depending
+on the printer configuration, as determined by the PPD in use).
+
+NOTE: a printer queue with *no* PPD associated to it is a "raw"
+----- printer and all files will go directly there as received
+ by the spooler; the exeption are file types
+"application/octet-stream" which need the mentioned "passthrough
+feature" enabled. "Raw" queues don't do any filtering at all, they
+hand the file directly to the CUPS backend. This backend is
+responsible for the sending of the data to the device (as visible
+in the "device URI" notation as lpd://, socket://, smb://, ipp://,
+http://, parallel:/, serial:/, usb:/ etc.)
+
+NOTE, please, also the following fact: "cupsomatic"/Foomatic are
+----- *not* native CUPS drivers and they don't ship with CUPS.
+ They are a Third Party add-on, developed at Linuxprinting.org.
+As such, they are a brilliant hack to make all models (driven by
+Ghostscript drivers/filters in traditional spoolers) also work via
+CUPS, with the same (good or bad!) quality as in these other
+spoolers. "cupsomatic" is only a vehicle to execute a ghostscript
+commandline at that stage in the CUPS filtering chain, where
+"normally" the native CUPS "pstoraster" filter would kick in.
+cupsomatic by-passes pstoraster, "kidnaps" the printfile from CUPS
+away and re-directs it to go through Ghostscipt. CUPS accepts this,
+because the associated CUPS-O-Matic-/Foomatic-PPD carries a line
+reading
+
+ *cupsFilter: "application/vnd.cups-postscript 0 cupsomatic"
+
+This line persuades CUPS to hand the file to cupsomatic, once it
+has successfully converted it to the MIME type
+"application/vnd.cups-postscript". This conversion will not
+happen for Jobs arriving from Windows which are autotyped
+"application/octet-stream", with the according changes in
+"/etc/cups/mime.types" in place.
+
+See small drawings at the end...
+
+I am not a programmer, so please correct me if I am wrong.
+
+ > With traditional lpr, you can just add "-oraw" to the "print command"
+ > line in smb.conf. With cups, you don't have that alternative.
+
+You *do* have it, I think.
+
+But you need to disable the settings "printing = cups" and "printcap =
+= cups" and use "printing = bsd" and "printcap = /etc/printcap"
+instead. [Additionally, you will probably have to enable and configure
+the CUPS mini-LPD daemon ("cups-lpd") run from inetd... but I have not
+checked, so take this item with a grain of salt and a proper dose of
+caution, please.]
+
+ > The result is that to support both unix printing and native-driver
+ > Windows printing from CUPS, you have to have two logical printers per
+ > physical printer: one ("cooked") for Unix clients and one ("raw") for
+ > Samba to use.
+
+Yes, that is one current workaround, if you don't want the auto-typing
+of CUPS influencing Samba/Windows client PostScript jobs.
+
+CUPS is widely configurable and flexible, even regarding its filtering
+mechanism. Another workaround in some situations would be to have
+lines in "/etc/cups/mime.types" saying
+
+ application/postscript application/vnd.cups-raw 0 -
+ application/vnd.cups-postscript application/vnd.cups-raw 0 -
+
+This would prevent all Postscript files to be filtered (or rather, they
+will go thru the virtual "nullfilter" denoted with "-". (This could only
+be useful for PS printers, or if you want to print PS code on non-PS
+printers ;-)
+
+A single line of
+
+ */* application/vnd.cups-raw 0 -
+
+would effectively send *all* files towards the backend immediately
+(good luck!)
+
+Last, you could have the following (without the need for a Samba
+patch):
+
+ application/vnd.cups-postscript application/vnd.cups-raw 0 my_PJL_stripping_filter
+
+You'd need to write a "my_PJL_stripping_filter" (could be a shellscript)
+which parses the PostScript and removes the undesired PJL. This would
+need to conform to CUPS filter design (mainly, receive and pass the
+parameters printername, job-id, username, jobtitle, copies, printoptions
+and possibly the filename). It would just go as world executably into
+"/usr/lib/cups/filters/" and work from there, called by cups if it
+encounters a MIME type "application/vnd.cups-postscript"
+
+ > The attached patch allows you to specify an option string for cups
+ > printers in smb.conf.
+
+I think your patch is in any case very useful (if it works as
+advertised ;-). It is the most generic, simple and flexible
+approach to complement CUPS.
+
+ > So, if you want to use native Windows drivers,
+ > all you need is
+ >
+ > cups printer options = raw
+ >
+ > in smb.conf. You can add any other options that cups and the printer
+ > understand.
+
+Now this last sentence makes me very curious. Do you mean you can add
+*multiple* options to this directive? Which syntax would be required
+for this ? (Some CUPS options are specified by an "-o option=value"
+pair on the commandline, some are single values, like the "-o raw"
+one...)
+
+I am thinking on one specific usage now:
+
+-----------------------------------------------------------------------
+-> passing any available IPP job attribute to the printer / the spooler
+-----------------------------------------------------------------------
+
+For example, CUPS can handle "-o job-hold-until=indefinite". This
+keeps the job in the queue "on hold". It will only be printed upon
+manual release by the printer operator. This is a requirement in
+many "central reproduction departments", where a few operators
+manage the jobs of hundreds of users on some big machine, where no
+user is allowed to have direct access. (The operators often need to
+load the proper paper type before running the 10.000 page job
+requested by marketing for the mailing, etc.).
+
+A lot more useful applications come to mind, if I could pass
+"any other options that cups and the printer understand" via
+the smb.conf directive!!
+
+Thanks a lot!
+
+Cheers,
+Kurt
+
+P.S.: List, please give me some feedback, if you think this type of
+ explanation could be useful in the Samba HOWTO Collection. In
+ that case, I'll try to write it up in a nicer form.
+
+
+#########################################################################
+#
+# CUPS in and of itself has this (general) filter chain (CAPITAL
+# letters are FILE-FORMATS or MIME types, other are filters (this is
+# true for pre-1.1.15 of pre-4.3 versions of CUPS and ESP PrintPro):
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT
+# |
+# |
+# V
+# pstoraster # as shipped with CUPS, independent from any Ghostscipt
+# | # installation on the system
+# | (= "postscipt interpreter")
+# |
+# V
+# APPLICATION/VND.CUPS-RASTER
+# |
+# |
+# V
+# rasterto<something> (f.e. Gimp-Print filters may be plugged in here)
+# | (= "raster driver")
+# |
+# V
+# SOMETHING-DEVICE-SPECIFIC
+# |
+# |
+# V
+# backend
+#
+#
+# ESP PrintPro has some enhanced "rasterto<something>" filters as compared to
+# CUPS, and also a somewhat improved "pstoraster" filter.
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+#
+#########################################################################
+#
+# This is how "cupsomatic" comes into play:
+# =========================================
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT ----------------+
+# | |
+# | V
+# V cupsomatic
+# pstoraster (constructs complicated
+# | (= "postscipt interpreter") Ghostscript commandline
+# | to let the file be
+# V processed by a
+# APPLICATION/VND.CUPS-RASTER "-sDEVICE=<s.th.>"
+# | call...)
+# | |
+# V |
+# rasterto<something> V
+# | (= "raster driver") +-------------------------+
+# | | Ghostscript at work.... |
+# V | |
+# SOMETHING-DEVICE-SPECIFIC *-------------------------+
+# | |
+# | |
+# V |
+# backend <------------------------------------+
+# |
+# |
+# V
+# THE PRINTER
+#
+#
+#
+# Note, that cupsomatic "kidnaps" the printfile after the
+# "APPLICATION/VND.CUPS-POSTSCRPT" stage and deviates it through
+# the CUPS-external, systemwide Ghostscript installation, bypassing the
+# "pstoraster" filter (therefor also bypassing the CUPS-raster-drivers
+# "rasterto<something>", and hands the rasterized file directly to the CUPS
+# backend...
+#
+# cupsomatic is not made by the CUPS developers. It is an independent
+# contribution to printing development, made by people from
+# Linuxprinting.org. (see also http://www.cups.org/cups-help.html)
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+#
+#########################################################################
+#
+# And this is how it works for ESP PrintPro from 4.3:
+# ===================================================
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT
+# |
+# |
+# V
+# gsrip
+# | (= "postscipt interpreter")
+# |
+# V
+# APPLICATION/VND.CUPS-RASTER
+# |
+# |
+# V
+# rasterto<something> (f.e. Gimp-Print filters may be plugged in here)
+# | (= "raster driver")
+# |
+# V
+# SOMETHING-DEVICE-SPECIFIC
+# |
+# |
+# V
+# backend
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+#
+#########################################################################
+#
+# This is how "cupsomatic" would come into play with ESP PrintPro:
+# ================================================================
+#
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT ----------------+
+# | |
+# | V
+# V cupsomatic
+# gsrip (constructs complicated
+# | (= "postscipt interpreter") Ghostscript commandline
+# | to let the file be
+# V processed by a
+# APPLICATION/VND.CUPS-RASTER "-sDEVICE=<s.th.>"
+# | call...)
+# | |
+# V |
+# rasterto<something> V
+# | (= "raster driver") +-------------------------+
+# | | Ghostscript at work.... |
+# V | |
+# SOMETHING-DEVICE-SPECIFIC *-------------------------+
+# | |
+# | |
+# V |
+# backend <------------------------------------+
+# |
+# |
+# V
+# THE PRINTER
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+#########################################################################
+#
+# And this is how it works for CUPS from 1.1.15:
+# ==============================================
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT-----+
+# |
+# +------------------v------------------------------+
+# | Ghostscript |
+# | at work... |
+# | (with |
+# | "-sDEVICE=cups") |
+# | |
+# | (= "postscipt interpreter") |
+# | |
+# +------------------v------------------------------+
+# |
+# |
+# APPLICATION/VND.CUPS-RASTER <-------+
+# |
+# |
+# V
+# rasterto<something>
+# | (= "raster driver")
+# |
+# V
+# SOMETHING-DEVICE-SPECIFIC
+# |
+# |
+# V
+# backend
+#
+#
+# NOTE: since version 1.1.15 CUPS "outsourced" the pstoraster process to
+# Ghostscript. GNU Ghostscript needs to be patched to handle the
+# CUPS requirement; ESP Ghostscript has this builtin. In any case,
+# "gs -h" needs to show up a "cups" device. pstoraster is now a
+# calling an appropriate "gs -sDEVICE=cups..." commandline to do
+# the job. It will output "application/vnd.cup-raster", which will
+# be finally processed by a CUPS raster driver "rasterto<something>"
+# Note the difference to "cupsomatic", which will *not* output
+# CUPS-raster, but a final version of the printfile, ready to be
+# sent to the printer. cupsomatic also doesn't use the "cups"
+# devicemode in Ghostscript, but one of the classical devicemodes....
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+#########################################################################
+#
+# And this is how it works for CUPS from 1.1.15, with cupsomatic included:
+# ========================================================================
+#
+# <SOMETHNG>-FILEFORMAT
+# |
+# |
+# V
+# <something>tops
+# |
+# |
+# V
+# APPLICATION/POSTSCRIPT
+# |
+# |
+# V
+# pstops
+# |
+# |
+# V
+# APPLICATION/VND.CUPS-POSTSCRIPT-----+
+# |
+# +------------------v------------------------------+
+# | Ghostscript . Ghostscript at work.... |
+# | at work... . (with "-sDEVICE= |
+# | (with . <s.th.>" |
+# | "-sDEVICE=cups") . |
+# | . |
+# | (CUPS standard) . (cupsomatic) |
+# | . |
+# | (= "postscript interpreter") |
+# | . |
+# +------------------v--------------v---------------+
+# | |
+# | |
+# APPLICATION/VND.CUPS-RASTER <-------+ |
+# | |
+# | |
+# V |
+# rasterto<something> |
+# | (= "raster driver") |
+# | |
+# V |
+# SOMETHING-DEVICE-SPECIFIC <------------------------+
+# |
+# |
+# V
+# backend
+#
+#
+# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
+# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
+#
+##########################################################################
+
+I hope this helps more people understand how CUPS works and how they
+can possibly tweak it to their needs.
+
+
diff --git a/docs/textdocs/DHCP-Server-Configuration.txt b/docs/textdocs/DHCP-Server-Configuration.txt
new file mode 100755
index 00000000000..82b54c2f5df
--- /dev/null
+++ b/docs/textdocs/DHCP-Server-Configuration.txt
@@ -0,0 +1,243 @@
+!==
+!== DHCP-Server-Configuration.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Subject: DHCP Server Configuration for SMB Clients
+Date: March 1, 1998
+Updated: May 15, 2001
+Contributor: John H Terpstra <jht@samba.org>
+Support: This is an unsupported document. Refer to documentation that is
+ supplied with the ISC DHCP Server. Do NOT email the contributor
+ for ANY assistance.
+===============================================================================
+
+Background:
+===========
+
+We wish to help those folks who wish to use the ISC DHCP Server and provide
+sample configuration settings. Most operating systems today come ship with
+the ISC DHCP Server. ISC DHCP is available from:
+ ftp://ftp.isc.org/isc/dhcp
+
+Incorrect configuration of MS Windows clients (Windows9X, Windows ME, Windows
+NT/2000) will lead to problems with browsing and with general network
+operation. Windows 9X/ME users often report problems where the TCP/IP and related
+network settings will inadvertantly become reset at machine start-up resulting
+in loss of configuration settings. This results in increased maintenance
+overheads as well as serious user frustration.
+
+In recent times users on one mailing list incorrectly attributed the cause of
+network operating problems to incorrect configuration of Samba.
+
+One user insisted that the only way to provent Windows95 from periodically
+performing a full system reset and hardware detection process on start-up was
+to install the NetBEUI protocol in addition to TCP/IP. This assertion is not
+correct.
+
+In the first place, there is NO need for NetBEUI. All Microsoft Windows clients
+natively run NetBIOS over TCP/IP, and that is the only protocol that is
+recognised by Samba. Installation of NetBEUI and/or NetBIOS over IPX will
+cause problems with browse list operation on most networks. Even Windows NT
+networks experience these problems when incorrectly configured Windows95
+systems share the same name space. It is important that only those protocols
+that are strictly needed for site specific reasons should EVER be installed.
+
+Secondly, and totally against common opinion, DHCP is NOT an evil design but is
+an extension of the BOOTP protocol that has been in use in Unix environments
+for many years without any of the melt-down problems that some sensationalists
+would have us believe can be experienced with DHCP. In fact, DHCP in covered by
+rfc1541 and is a very safe method of keeping an MS Windows desktop environment
+under control and for ensuring stable network operation.
+
+Please note that MS Windows systems as of MS Windows NT 3.1 and MS Windows 95
+store all network configuration settings a registry. There are a few reports
+from MS Windows network administrators that warrant mention here. It would appear
+that when one sets certain MS TCP/IP protocol settings (either directly or via
+DHCP) that these do get written to the registry. Even though a subsequent
+change of setting may occur the old value may persist in the registry. This
+has been known to create serious networking problems.
+
+An example of this occurs when a manual TCP/IP environment is configured to
+include a NetBIOS Scope. In this event, when the administrator then changes the
+configuration of the MS TCP/IP protocol stack, without first deleting the
+current settings, by simply checking the box to configure the MS TCP/IP stack
+via DHCP then the NetBIOS Scope that is still persistent in the registry WILL be
+applied to the resulting DHCP offered settings UNLESS the DHCP server also sets
+a NetBIOS Scope. It may therefore be prudent to forcibly apply a NULL NetBIOS
+Scope from your DHCP server. The can be done in the dhcpd.conf file with the
+parameter:
+ option netbios-scope "";
+
+While it is true that the Microsoft DHCP server that comes with Windows NT
+Server provides only a sub-set of rfc1533 functionality this is hardly an issue
+in those sites that already have a large investment and commitment to Unix
+systems and technologies. The current state of the art of the DHCP Server
+specification in covered in rfc2132.
+
+This document aims to provide enough background information so that the
+majority of site can without too much hardship get the Internet Software
+Consortium's (ISC) DHCP Server into operation. The key benefits of using DHCP
+includes:
+
+1) Automated IP Address space management and maximised re-use of available IP
+Addresses,
+
+2) Automated control of MS Windows client TCP/IP network configuration,
+
+3) Automatic recovery from start-up and run-time problems with Windows95.
+
+
+
+Client Configuration for SMB Networking:
+========================================
+SMB network clients need to be configured so that all standard TCP/IP name to
+address resolution works correctly. Once this has been achieved the SMB
+environment provides additional tools and services that act as helper agents in
+the translation of SMB (NetBIOS) names to their appropriate IP Addresses. One
+such helper agent is the NetBIOS Name Server (NBNS) or as Microsoft called it
+in their Windows NT Server implementation WINS (Windows Internet Name Server).
+
+A client needs to be configured so that it has a unique Machine (Computer)
+Name.
+
+This can be done, but needs a few NT registry hacks and you need to be able to
+speak UNICODE, which is of course no problem for a True Wizzard(tm) :)
+Instructions on how to do this (including a small util for less capable
+Wizzards) can be found at
+
+ http://www.unixtools.org/~nneul/sw/nt/dhcp-netbios-hostname.html
+
+
+All remaining TCP/IP networking parameters can be assigned via DHCP. These include:
+
+a) IP Address,
+b) Netmask,
+c) Gateway (Router) Address,
+d) DNS Domain Name,
+e) DNS Server addresses,
+f) WINS (NBNS) Server addresses,
+g) IP Forwarding,
+h) Timezone offset,
+i) Node Type,
+j) NetBIOS Scope
+
+Other assignments can be made from a DHCP server too, but the above cover the
+major needs.
+
+Note: IF ever an entry has has been made to the NetBIOS Scope field of the
+TCP/IP configuration panel on an MS Windows machine, and it has then been
+committed, then that setting may become persistent. In such a c ase it is better
+to configure the DHCP server with a NetBIOS Scope consisting of an empty string
+(ie: A NULL scope).
+
+
+DHCP Server Installation:
+=========================
+It is assumed that you will have obtained a copy of the GPL'd ISC DHCP server
+source files from ftp://ftp.isc.org/isc/dhcp, it is also assumed that you have
+compiled the sources and have installed the binary files.
+
+The following simply serves to provide sample configuration files to enable
+dhcpd to operate. The sample files assume that your site is configured to use
+private IP network address space using the Class B range of 172.16.1.0 -
+172.16.1.255 and is using a netmask of 255.255.255.0 (ie:24 bits). It is
+assumed that your router to the outside world is at 172.16.1.254 and that your
+Internet Domain Name is bestnet.com.au. The IP Address range 172.16.1.100 to
+172.16.1.240 has been set aside as your dynamically allocated range. In
+addition, bestnet.com.au have two print servers that need to obtain settings
+via BOOTP. The machine linux.bestnet.com.au has IP address 172.16.1.1 and is
+you primary Samba server with WINS support enabled by adding the parameter to
+the /etc/smb.conf file: [globals] wins support = yes. The dhcp lease time will
+be set to 20 hours.
+
+Configuration Files:
+====================
+Before dhcpd will run you need to install a file that speifies the
+configuration settings, and another that holds the database of issued IP
+addresses. On many systems these are stored in the /etc directory on the Unix
+system.
+
+Example /etc/dhcpd.conf:
+========================
+server-identifier linux.bestnet.com.au;
+
+subnet 172.16.1.0 netmask 255.255.255.0 {
+ range 172.16.1.100 172.16.1.240;
+ default-lease-time 72000;
+ max-lease-time 144000;
+ option subnet-mask 255.255.255.0;
+ option broadcast-address 172.16.1.255;
+ option routers 172.16.1.254;
+ option domain-name-servers 172.16.1.1, 172.16.1.2;
+ option domain-name "bestnet.com.au";
+ option time-offset 39600;
+ option ip-forwarding off;
+ option netbios-name-servers 172.16.0.1, 172.16.0.1;
+ option netbios-dd-server 172.16.0.1;
+ option netbios-node-type 8;
+ option netbios-scope "";
+}
+
+; Note: The above netbios-scope is purposely an empty (NULL) string.
+
+group {
+ next-server 172.16.1.10;
+ option subnet-mask 255.255.255.0;
+ option domain-name "bestnet.com.au";
+ option domain-name-servers 172.16.1.1, 172.16.0.2;
+ option netbios-name-servers 172.16.0.1, 172.16.0.1;
+ option netbios-dd-server 172.16.0.1;
+ option netbios-node-type 8;
+ option netbios-scope "SomeCrazyScope";
+ option routers 172.16.1.240;
+ option time-offset 39600;
+ host lexmark1 {
+ hardware ethernet 06:07:08:09:0a:0b;
+ fixed-address 172.16.1.245;
+ }
+ host epson4 {
+ hardware ethernet 01:02:03:04:05:06;
+ fixed-address 172.16.1.242;
+ }
+}
+
+
+Creating the /etc/dhcpd.leases file:
+====================================
+At a Unix shell create an empty dhcpd.leases file in the /etc directory.
+You can do this by typing: cp /dev/null /etc/dhcpd.leases
+
+
+Setting up a route table for all-ones addresses:
+================================================
+Quoting from the README file that comes with the ISC DHCPD Server:
+
+ BROADCAST
+
+In order for dhcpd to work correctly with picky DHCP clients (e.g.,
+Windows 95), it must be able to send packets with an IP destination
+address of 255.255.255.255. Unfortunately, Linux insists on changing
+255.255.255.255 into the local subnet broadcast address (here, that's
+192.5.5.223). This results in a DHCP protocol violation, and while
+many DHCP clients don't notice the problem, some (e.g., all Microsoft
+DHCP clients) do. Clients that have this problem will appear not to
+see DHCPOFFER messages from the server.
+
+It is possible to work around this problem on some versions of Linux
+by creating a host route from your network interface address to
+255.255.255.255. The command you need to use to do this on Linux
+varies from version to version. The easiest version is:
+
+ route add -host 255.255.255.255 dev eth0
+
+On some older Linux systems, you will get an error if you try to do
+this. On those systems, try adding the following entry to your
+/etc/hosts file:
+
+255.255.255.255 all-ones
+
+Then, try:
+
+ route add -host all-ones dev eth0
+
+
+For more information please refer to the ISC DHCPD Server documentation.
diff --git a/docs/textdocs/DIAGNOSIS.txt b/docs/textdocs/DIAGNOSIS.txt
new file mode 100755
index 00000000000..5ca1743a23a
--- /dev/null
+++ b/docs/textdocs/DIAGNOSIS.txt
@@ -0,0 +1,324 @@
+!==
+!== DIAGNOSIS.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Andrew Tridgell
+Updated: November 1, 1999
+
+Subject: DIAGNOSING YOUR SAMBA SERVER
+===========================================================================
+
+This file contains a list of tests you can perform to validate your
+Samba server. It also tells you what the likely cause of the problem
+is if it fails any one of these steps. If it passes all these tests
+then it is probably working fine.
+
+You should do ALL the tests, in the order shown. I have tried to
+carefully choose them so later tests only use capabilities verified in
+the earlier tests.
+
+If you send me an email saying "it doesn't work" and you have not
+followed this test procedure then you should not be surprised if I
+ignore your email.
+
+
+ASSUMPTIONS
+-----------
+
+In all of the tests I assume you have a Samba server called BIGSERVER
+and a PC called ACLIENT both in workgroup TESTGROUP. I also assume the
+PC is running windows for workgroups with a recent copy of the
+microsoft tcp/ip stack. Alternatively, your PC may be running Windows
+95 or Windows NT (Workstation or Server).
+
+The procedure is similar for other types of clients.
+
+I also assume you know the name of an available share in your
+smb.conf. I will assume this share is called "tmp". You can add a
+"tmp" share like by adding the following to smb.conf:
+
+[tmp]
+ comment = temporary files
+ path = /tmp
+ read only = yes
+
+
+THESE TESTS ASSUME VERSION 2.0.6 OR LATER OF THE SAMBA SUITE. SOME
+COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS
+
+Please pay attention to the error messages you receive. If any error message
+reports that your server is being unfriendly you should first check that you
+IP name resolution is correctly set up. eg: Make sure your /etc/resolv.conf
+file points to name servers that really do exist.
+
+Also, if you do not have DNS server access for name resolution please check
+that the settings for your smb.conf file results in "dns proxy = no". The
+best way to check this is with "testparm smb.conf"
+
+
+TEST 1:
+-------
+
+In the directory in which you store your smb.conf file, run the command
+"testparm smb.conf". If it reports any errors then your smb.conf
+configuration file is faulty.
+
+Note: Your smb.conf file may be located in: /etc
+ Or in: /usr/local/samba/lib
+
+
+TEST 2:
+-------
+
+run the command "ping BIGSERVER" from the PC and "ping ACLIENT" from
+the unix box. If you don't get a valid response then your TCP/IP
+software is not correctly installed.
+
+Note that you will need to start a "dos prompt" window on the PC to
+run ping.
+
+If you get a message saying "host not found" or similar then your DNS
+software or /etc/hosts file is not correctly setup. It is possible to
+run samba without DNS entries for the server and client, but I assume
+you do have correct entries for the remainder of these tests.
+
+Another reason why ping might fail is if your host is running firewall
+software. You will need to relax the rules to let in the workstation
+in question, perhaps by allowing access from another subnet (on Linux
+this is done via the ipfwadm program.)
+
+
+TEST 3:
+-------
+
+Run the command "smbclient -L BIGSERVER" on the unix box. You
+should get a list of available shares back.
+
+If you get a error message containing the string "Bad password" then
+you probably have either an incorrect "hosts allow", "hosts deny" or
+"valid users" line in your smb.conf, or your guest account is not
+valid. Check what your guest account is using "testparm" and
+temporarily remove any "hosts allow", "hosts deny", "valid users" or
+"invalid users" lines.
+
+If you get a "connection refused" response then the smbd server may
+not be running. If you installed it in inetd.conf then you probably edited
+that file incorrectly. If you installed it as a daemon then check that
+it is running, and check that the netbios-ssn port is in a LISTEN
+state using "netstat -a".
+
+If you get a "session request failed" then the server refused the
+connection. If it says "Your server software is being unfriendly" then
+its probably because you have invalid command line parameters to smbd,
+or a similar fatal problem with the initial startup of smbd. Also
+check your config file (smb.conf) for syntax errors with "testparm"
+and that the various directories where samba keeps its log and lock
+files exist.
+
+There are a number of reasons for which smbd may refuse or decline
+a session request. The most common of these involve one or more of
+the following smb.conf file entries:
+ hosts deny = ALL
+ hosts allow = xxx.xxx.xxx.xxx/yy
+ bind interfaces only = Yes
+
+In the above, no allowance has been made for any session requests that
+will automatically translate to the loopback adaptor address 127.0.0.1.
+To solve this problem change these lines to:
+ hosts deny = ALL
+ hosts allow = xxx.xxx.xxx.xxx/yy 127.
+Do NOT use the "bind interfaces only" parameter where you may wish to
+use the samba password change facility, or where smbclient may need to
+access local service for name resolution or for local resource
+connections. (Note: the "bind interfaces only" parameter deficiency
+where it will not allow connections to the loopback address will be
+fixed soon).
+
+Another common cause of these two errors is having something already running
+on port 139, such as Samba (ie: smbd is running from inetd already) or
+something like Digital's Pathworks. Check your inetd.conf file before trying
+to start smbd as a daemon, it can avoid a lot of frustration!
+
+And yet another possible cause for failure of TEST 3 is when the subnet mask
+and / or broadcast address settings are incorrect. Please check that the
+network interface IP Address / Broadcast Address / Subnet Mask settings are
+correct and that Samba has correctly noted these in the log.nmb file.
+
+TEST 4:
+-------
+
+Run the command "nmblookup -B BIGSERVER __SAMBA__". You should get the
+IP address of your Samba server back.
+
+If you don't then nmbd is incorrectly installed. Check your inetd.conf
+if you run it from there, or that the daemon is running and listening
+to udp port 137.
+
+One common problem is that many inetd implementations can't take many
+parameters on the command line. If this is the case then create a
+one-line script that contains the right parameters and run that from
+inetd.
+
+
+TEST 5:
+-------
+
+run the command "nmblookup -B ACLIENT '*'"
+
+You should get the PCs IP address back. If you don't then the client
+software on the PC isn't installed correctly, or isn't started, or you
+got the name of the PC wrong.
+
+If ACLIENT doesn't resolve via DNS then use the IP address of the
+client in the above test.
+
+
+TEST 6:
+-------
+
+Run the command "nmblookup -d 2 '*'"
+
+This time we are trying the same as the previous test but are trying
+it via a broadcast to the default broadcast address. A number of
+Netbios/TCPIP hosts on the network should respond, although Samba may
+not catch all of the responses in the short time it listens. You
+should see "got a positive name query response" messages from several
+hosts.
+
+If this doesn't give a similar result to the previous test then
+nmblookup isn't correctly getting your broadcast address through its
+automatic mechanism. In this case you should experiment use the
+"interfaces" option in smb.conf to manually configure your IP
+address, broadcast and netmask.
+
+If your PC and server aren't on the same subnet then you will need to
+use the -B option to set the broadcast address to the that of the PCs
+subnet.
+
+This test will probably fail if your subnet mask and broadcast address are
+not correct. (Refer to TEST 3 notes above).
+
+TEST 7:
+-------
+
+Run the command "smbclient //BIGSERVER/TMP". You should then be
+prompted for a password. You should use the password of the account
+you are logged into the unix box with. If you want to test with
+another account then add the -U <accountname> option to the end of
+the command line. eg: smbclient //bigserver/tmp -Ujohndoe
+
+Note: It is possible to specify the password along with the username
+as follows:
+ smbclient //bigserver/tmp -Ujohndoe%secret
+
+Once you enter the password you should get the "smb>" prompt. If you
+don't then look at the error message. If it says "invalid network
+name" then the service "tmp" is not correctly setup in your smb.conf.
+
+If it says "bad password" then the likely causes are:
+
+- you have shadow passords (or some other password system) but didn't
+compile in support for them in smbd
+- your "valid users" configuration is incorrect
+- you have a mixed case password and you haven't enabled the "password
+level" option at a high enough level
+- the "path =" line in smb.conf is incorrect. Check it with testparm
+- you enabled password encryption but didn't create the SMB encrypted
+password file
+
+Once connected you should be able to use the commands "dir" "get"
+"put" etc. Type "help <command>" for instructions. You should
+especially check that the amount of free disk space shown is correct
+when you type "dir".
+
+
+TEST 8:
+-------
+
+On the PC type the command "net view \\BIGSERVER". You will need to do
+this from within a "dos prompt" window. You should get back a list of
+available shares on the server.
+
+If you get a "network name not found" or similar error then netbios
+name resolution is not working. This is usually caused by a problem in
+nmbd. To overcome it you could do one of the following (you only need
+to choose one of them):
+
+- fixup the nmbd installation
+- add the IP address of BIGSERVER to the "wins server" box in the
+advanced tcp/ip setup on the PC.
+- enable windows name resolution via DNS in the advanced section of
+the tcp/ip setup
+- add BIGSERVER to your lmhosts file on the PC.
+
+If you get a "invalid network name" or "bad password error" then the
+same fixes apply as they did for the "smbclient -L" test above. In
+particular, make sure your "hosts allow" line is correct (see the man
+pages)
+
+Also, do not overlook that fact that when the workstation requests the
+connection to the samba server it will attempt to connect using the
+name with which you logged onto your Windows machine. You need to make
+sure that an account exists on your Samba server with that exact same
+name and password.
+
+If you get "specified computer is not receiving requests" or similar
+it probably means that the host is not contactable via tcp services.
+Check to see if the host is running tcp wrappers, and if so add an entry in
+the hosts.allow file for your client (or subnet, etc.)
+
+
+TEST 9:
+--------
+
+Run the command "net use x: \\BIGSERVER\TMP". You should be prompted
+for a password then you should get a "command completed successfully"
+message. If not then your PC software is incorrectly installed or your
+smb.conf is incorrect. make sure your "hosts allow" and other config
+lines in smb.conf are correct.
+
+It's also possible that the server can't work out what user name to
+connect you as. To see if this is the problem add the line "user =
+USERNAME" to the [tmp] section of smb.conf where "USERNAME" is the
+username corresponding to the password you typed. If you find this
+fixes things you may need the username mapping option.
+
+TEST 10:
+--------
+
+Run the command "nmblookup -M TESTGROUP" where TESTGROUP is the name
+of the workgroup that your Samba server and Windows PCs belong to. You
+should get back the IP address of the master browser for that
+workgroup.
+
+If you don't then the election process has failed. Wait a minute to
+see if it is just being slow then try again. If it still fails after
+that then look at the browsing options you have set in smb.conf. Make
+sure you have "preferred master = yes" to ensure that an election is
+held at startup.
+
+TEST 11:
+--------
+
+From file manager try to browse the server. Your samba server should
+appear in the browse list of your local workgroup (or the one you
+specified in smb.conf). You should be able to double click on the name
+of the server and get a list of shares. If you get a "invalid
+password" error when you do then you are probably running WinNT and it
+is refusing to browse a server that has no encrypted password
+capability and is in user level security mode. In this case either set
+"security = server" AND "password server = Windows_NT_Machine" in your
+smb.conf file, or enable encrypted passwords AFTER compiling in support
+for encrypted passwords (refer to the Makefile).
+
+
+Still having troubles?
+----------------------
+
+Try the mailing list or newsgroup, or use the tcpdump-smb utility to
+sniff the problem. The official samba mailing list can be reached at
+samba@samba.org. To find out more about samba and how to
+subscribe to the mailing list check out the samba web page at
+ http://samba.org/samba
+
+Also look at the other docs in the Samba package!
+
diff --git a/docs/textdocs/DNIX.txt b/docs/textdocs/DNIX.txt
new file mode 100755
index 00000000000..fed77b939b4
--- /dev/null
+++ b/docs/textdocs/DNIX.txt
@@ -0,0 +1,72 @@
+!==
+!== DNIX.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+DNIX has a problem with seteuid() and setegid(). These routines are
+needed for Samba to work correctly, but they were left out of the DNIX
+C library for some reason.
+
+For this reason Samba by default defines the macro NO_EID in the DNIX
+section of includes.h. This works around the problem in a limited way,
+but it is far from ideal, some things still won't work right.
+
+To fix the problem properly you need to assemble the following two
+functions and then either add them to your C library or link them into
+Samba.
+
+put this in the file setegid.s:
+
+ .globl _setegid
+_setegid:
+ moveq #47,d0
+ movl #100,a0
+ moveq #1,d1
+ movl 4(sp),a1
+ trap #9
+ bccs 1$
+ jmp cerror
+1$:
+ clrl d0
+ rts
+
+
+put this in the file seteuid.s:
+
+ .globl _seteuid
+_seteuid:
+ moveq #47,d0
+ movl #100,a0
+ moveq #0,d1
+ movl 4(sp),a1
+ trap #9
+ bccs 1$
+ jmp cerror
+1$:
+ clrl d0
+ rts
+
+after creating the above files you then assemble them using
+
+as seteuid.s
+as setegid.s
+
+that should produce the files seteuid.o and setegid.o
+
+then you need to add these to the LIBSM line in the DNIX section of
+the Samba Makefile. Your LIBSM line will then look something like this:
+
+LIBSM = setegid.o seteuid.o -ln
+
+You should then remove the line:
+
+#define NO_EID
+
+from the DNIX section of includes.h
+
+Then recompile and try it out!
+
+Note that this file was derived from an email from Peter Olsson
+<pol@leissner.se>. I don't have DNIX myself, so you're probably better
+off contacting Peter if you have problems.
+
+Andrew
+
diff --git a/docs/textdocs/Faxing.txt b/docs/textdocs/Faxing.txt
new file mode 100755
index 00000000000..eb4e5f58a1a
--- /dev/null
+++ b/docs/textdocs/Faxing.txt
@@ -0,0 +1,223 @@
+!==
+!== Faxing.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Gerhard Zuber <zuber@berlin.snafu.de>
+Date: August 5th 1997.
+Status: Current
+
+Subject: F A X I N G with S A M B A
+==========================================================================
+
+This text describes how to turn your SAMBA-server into a fax-server
+for any environment, especially for Windows.
+ Author: Gerhard Zuber <zuber@berlin.snafu.de>
+ Version: 1.4
+ Date: 04. Aug. 1997
+
+Requirements:
+ UNIX box (Linux preferred) with SAMBA and a faxmodem
+ ghostscript package
+ mgetty+sendfax package
+ pbm package (portable bitmap tools)
+
+FTP sites:
+ sunsite.unc.edu:/pub/Linux/system/Serial/mgetty+sendfax*
+ tsx-11.mit.edu:/pub/linux/sources/sbin/mgetty+sendfax
+ ftp.leo.org:/pub/comp/networking/communication/modem/mgetty/mgetty1.1.6-May05.tar.gz
+
+ pbm10dec91.tgz
+ ftp.leo.org:/pub/comp/networking/communication/modem/mgetty/pbm10dec91.tgz
+ sunsite.unc.edu: ..../apps/graphics/convert/pbmplus-10dec91-bin.tar.gz
+ ftp.gwdg.de/pub/linux/grafik/pbmplus.src.tar.Z (this is 10dec91 source)
+ or ??? pbm10dec91.tgz pbmplus10dec91.tgz
+
+
+making mgetty+sendfax running:
+==============================
+
+ go to source tree: /usr/src/mgetty+sendfax
+ cp policy.h-dist policy.h
+
+ change your settings: valid tty ports, modem initstring, Station-Id
+
+#define MODEM_INIT_STRING "AT &F S0=0 &D3 &K3 &C1\\\\N2"
+
+#define FAX_STATION_ID "49 30 12345678"
+
+#define FAX_MODEM_TTYS "ttyS1:ttyS2:ttyS3"
+
+ Modem initstring is for rockwell based modems
+ if you want to use mgetty+sendfax as PPP-dialin-server,
+ define AUTO_PPP in Makefile:
+
+CFLAGS=-O2 -Wall -pipe -DAUTO_PPP
+
+ compile it and install the package.
+ edit your /etc/inittab and let mgetty running on your preferred
+ ports:
+
+s3:45:respawn:/usr/local/sbin/mgetty ttyS2 vt100
+
+ now issue a
+ kill -HUP 1
+ and enjoy with the lightning LEDs on your modem
+ your now are ready to receive faxes !
+
+
+ if you want a PPP dialin-server, edit
+ /usr/local/etc/mgetty+sendfax/login.config
+
+/AutoPPP/ - ppp /usr/sbin/pppd auth debug passive modem
+
+
+ Note: this package automatically decides between a fax call and
+ a modem call. In case of modem call you get a login prompt !
+
+Tools for printing faxes:
+=========================
+
+ your incomed faxes are in:
+ /var/spool/fax/incoming
+
+ print it with:
+
+ for i in *
+ do
+ g3cat $i | g3tolj | lpr -P hp
+ done
+
+ in case of low resolution use instead:
+
+ g3cat $i | g3tolj -aspect 2 | lpr -P hp
+
+
+ g3cat is in the tools-section, g3tolj is in the contrib-section
+ for printing to HP lasers.
+
+ If you want to produce files for displaying and printing with Windows, use
+ some tools from the pbm-package like follow
+
+ g3cat $i | g3topbm - | ppmtopcx - >$i.pcx
+
+ and view it with your favourite Windows tool (maybe paintbrush)
+
+
+Now making the fax-server:
+===========================
+
+ fetch the file
+ mgetty+sendfax/frontends/winword/faxfilter
+
+ and place it in
+
+ /usr/local/etc/mgetty+sendfax/
+
+ prepare your faxspool file as mentioned in this file
+ edit fax/faxspool.in and reinstall or change the final
+ /usr/local/bin/faxspool too.
+
+ if [ "$user" = "root" -o "$user" = "fax" -o \
+ "$user" = "lp" -o "$user" = "daemon" -o "$user" = "bin" ]
+
+ find the first line and change the second.
+
+ make sure you have pbmtext (from the pbm-package). This is
+ needed for creating the small header line on each page.
+ Notes on pbmplus:
+ Some peoples had problems with precompiled binaries (especially
+ at linux) with a shared lib libgr.so.x.x. The better way is
+ to fetch the source and compile it. One needs only pbmtext for
+ generating the small line on top of each page /faxheader). Install
+ only the individual programs you need. If you install the full
+ package then install pbmplus first and then mgetty+sendfax, because
+ this package has some changed programs by itself (but not pbmtext).
+
+ make sure your ghostscript is functional. You need fonts !
+ I prefer these from the OS/2 disks
+
+ prepare your faxheader
+ /usr/local/etc/mgetty+sendfax/faxheader
+
+ edit your /etc/printcap file:
+
+# FAX
+lp3|fax:\
+ :lp=/dev/null:\
+ :sd=/usr/spool/lp3:\
+ :if=/usr/local/etc/mgetty+sendfax/faxfilter:sh:sf:mx#0:\
+ :lf=/usr/spool/lp3/fax-log:
+
+
+
+
+ edit your /usr/local/samba/lib/smb.conf
+
+ so you have a smb based printer named "fax"
+
+
+The final step:
+===============
+
+ Now you have a printer called "fax" which can be used via
+ TCP/IP-printing (lpd-system) or via SAMBA (windows printing).
+
+ On every system you are able to produce postscript-files you
+ are ready to fax.
+
+ On Windows 3.1 95 and NT:
+
+ Install a printer wich produces postscript output,
+ e.g. apple laserwriter
+
+ connect the "fax" to your printer
+
+
+ Now write your first fax. Use your favourite wordprocessor,
+ write, winword, notepad or whatever you want, and start
+ with the headerpage.
+
+ Usually each fax has a header page. It carries your name,
+ your address, your phone/fax-number.
+
+ It carries also the recipient, his address and his *** fax
+ number ***. Now here is the trick:
+
+ Use the text:
+ Fax-Nr: 123456789
+ as the recipients fax-number. Make sure this text does not
+ occur in regular text ! Make sure this text is not broken
+ by formatting information, e.g. format it as a single entity.
+ (Windows Write and Win95 Wordpad are functional, maybe newer
+ versions of Winword are breaking formatting information).
+
+ The trick is that postscript output is human readable and
+ the faxfilter program scans the text for this pattern and
+ uses the found number as the fax-destination-number.
+
+ Now print your fax through the fax-printer and it will be
+ queued for later transmission. Use faxrunq for sending the
+ queue out.
+
+ Notes of SAMBA smb.conf:
+ Simply use fall through from the samba printer to the unix
+ printer. Sample:
+
+
+ printcap name = /etc/printcap
+ print command = /usr/bin/lpr -r -P %p %s
+ lpq command = /usr/bin/lpq -P %p
+ lprm command = /usr/bin/lprm -P %p %j
+
+
+[fax]
+ comment = FAX (mgetty+sendfax)
+ path = /tmp
+ printable = yes
+ public = yes
+ writable = no
+ create mode = 0700
+ browseable = yes
+ guest ok = no
+
+
+
diff --git a/docs/textdocs/GOTCHAS.txt b/docs/textdocs/GOTCHAS.txt
new file mode 100755
index 00000000000..afa5f8f4542
--- /dev/null
+++ b/docs/textdocs/GOTCHAS.txt
@@ -0,0 +1,71 @@
+!==
+!== GOTCHAS.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+This file lists Gotchas to watch out for:
+=========================================================================
+Item Number: 1.0
+Description: Problem Detecting Interfaces
+Symptom: Workstations do NOT see Samba server in Browse List
+OS: RedHat - Rembrandt Beta 2
+Platform: Intel
+Date: August 16, 1996
+Submitted By: John H Terpstra
+Details:
+ By default RedHat Rembrandt-II during installation adds an
+ entry to /etc/hosts as follows:-
+ 127.0.0.1 loopback "hostname"."domainname"
+
+ This causes Samba to loop back onto the loopback interface.
+ The result is that Samba fails to communicate correctly with
+ the world and therefor may fail to correctly negotiate who
+ is the master browse list holder and who is the master browser.
+
+Corrective Action: Delete the entry after the word loopback
+ in the line starting 127.0.0.1
+=========================================================================
+Item Number: 2.0
+Description: Problems with MS Windows NT Server network logon service
+Symptom: Loss of Domain Logon Services and failed Windows NT / 95
+ logon attempts.
+OS: All Unix systems with Windows NT Domain Control environments.
+Platform: All
+Date: February 1, 1997
+Submitted By: John H Terpstra
+Details:
+ Samba is configured for Domain logon control in a network
+ where a Windows NT Domain Primary Controller is running.
+
+ Case 1:
+ The Windows NT Server is shut down, then restarted. Then
+ the Samba server is reconfigured so that it NO LONGER offers
+ Domain logon services. Windows NT and 95 workstations can no
+ longer log onto the domain. Ouch!!!
+
+ Case 2:
+ The Windows NT Server which is running the Network logon
+ Service is shut down and restarted while Samba is a domain
+ controller offering the Domain LogOn service. Windows NT
+ Workstation and Server can no longer log onto the network.
+
+ Cause:
+ Windows NT checks at start up to see if any domain logon
+ controllers are already running within the domain. It finds
+ Samba claiming to offer the service and therefore does NOT
+ start its Network Logon Service.
+
+ Windows NT needs the Windows NT network logon service to gain
+ from its Domain controller's SAM database the security
+ identifier for the user loging on.
+
+Work-around: Stop the Samba nmbd and smbd processes, then on the Windows
+ NT Primary Domain Controller start the Network Logon Service.
+ Now restart the Samba nmbd and smbd services.
+
+ Better still: DO NOT CONFIGURE SAMBA AS THE NETWORK LOGON
+ SERVER, DO NOT SET SAMBA TO BE THE DOMAIN MASTER, DO NOT
+ SET SAMBA TO OS LEVEL GREATER THAN 0.
+
+ ie: Let Windows NT Server be the Domain Logon server, the
+ domain master browser and do NOT interfere with any aspect
+ of Microsoft Windows NT Domain Control.
+=========================================================================
diff --git a/docs/textdocs/HINTS.txt b/docs/textdocs/HINTS.txt
new file mode 100755
index 00000000000..5b0854b36e5
--- /dev/null
+++ b/docs/textdocs/HINTS.txt
@@ -0,0 +1,212 @@
+!==
+!== HINTS.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Many
+Updated: Not for a long time!
+
+Subject: A collection of hints
+Status: May be useful information but NOT current
+===============================================================================
+
+Here are some random hints that you may find useful. These really
+should be incorporated in the main docs someday.
+
+
+----------------------
+HINT: Always test your smb.conf with testparm before using it
+
+If your smb.conf file is invalid then samba will fail to load. Run
+testparm over it before you install it just to make sure there aren't
+any basic syntax or logical errors.
+
+
+----------------------
+HINT: Try printing with smbclient first
+
+If you have problems printing, test with smbclient first. Just connect using
+"smbclient '\\server\printer' -P" and use the "print" command.
+
+Once this works, you know that Samba is setup correctly for printing,
+and you should be able to get it to work from your PCs.
+
+This particularly helps in getting the "print command" right.
+
+
+----------------------
+HINT: Mount cdroms with conv=binary
+
+Some OSes (notably Linux) default to auto detection of file type on
+cdroms and do cr/lf translation. This is a very bad idea when use with
+Samba. It causes all sorts of stuff ups.
+
+To overcome this problem use conv=binary when mounting the cdrom
+before exporting it with Samba.
+
+
+----------------------
+HINT: Convert between unix and dos text formats
+
+Jim barry has written an excellent drag-and-drop cr/lf converter for
+windows. Just drag your file onto the icon and it converts the file.
+
+Get it from
+ftp://samba.org/pub/samba/contributed/fixcrlf.zip
+
+----------------------
+HINT: Use the "username map" option
+
+If the usernames used on your PCs don't match those used on the unix
+server then you will find the "username map" option useful.
+
+-----------------------
+HINT: Use "security = user" in [global]
+
+If you have the same usernames on the unix box and the PCs or have
+mapped them with the "username map" option then choose "security =
+user" in the [global] section of smb.conf.
+
+This will mean your password is checked only when you first connect,
+and subsequent connections to printers, disks etc will go more
+smoothly and much faster.
+
+The main problem with "security = user" if you use WfWg is that you
+will ONLY be able to connect as the username that you log into WfWg
+with. This is because WfWg silently ignores the password field in the
+connect drive dialog box if the server is in user security mode.
+
+------------------------
+HINT: Make your printers not "guest ok"
+
+If your printers are not "guest ok" and you are using "security =
+user" and have matching unix and PC usernames then you will attach to
+the printer without trouble as your own username. This will mean you
+will be able to delete print jobs (in 1.8.06 and above) and printer
+accounting will be possible.
+
+
+-----------------------
+HINT: Use a sensible "guest" account
+
+Even if all your services are not available to "guest" you will need a
+guest account. This is because the browsing is done as guest. In many
+cases setting "guest account = ftp" will do the trick. Using the
+default guest account or "guest account = nobody" will give problems on
+many unixes. If in doubt create another account with minimal
+privilages and use it instead. Your users don't need to know the
+password of the guest account.
+
+
+-----------------------
+HINT: Use the latest TCP/IP stack from microsoft if you use Windows
+for workgroups.
+
+The early TCP/IP stacks had lots of bugs.
+
+Microsoft has released an incremental upgrade to their TCP/IP 32-Bit
+VxD drivers. The latest release can be found on their ftp site at
+ftp.microsoft.com, located in /peropsys/windows/public/tcpip/wfwt32.exe.
+There is an update.txt file there that describes the problems that were
+fixed. New files include WINSOCK.DLL, TELNET.EXE, WSOCK.386, VNBT.386,
+WSTCP.386, TRACERT.EXE, NETSTAT.EXE, and NBTSTAT.EXE.
+
+
+-----------------------
+HINT: nmbd can act as a "WINS" server
+
+By default SMB clients use broadcasts to find shares. Recent clients
+(such as WfWg) can use a "wins" server instead, whcih reduces your
+broadcast traffic and allows you to find names across routers.
+
+Just point your WfWg, Win95 and NT clients at the Samba box in the WINS option.
+
+Note: nmbd does not support all WINS operations. Anyone out there have
+a spec they could send me?
+
+-----------------------
+HINT: you may need to delete your .pwl files when you change password.
+
+WfWg does a lousy job with passwords. I find that if I change my
+password on either the unix box or the PC the safest thing to do is to
+delete the .pwl files in the windows directory. The PC will complain about not finding the files, but will soon get over it, allowing you to enter the new password.
+
+If you don't do this you may find that WfWg remembers and uses the old
+password, even if you told it a new one.
+
+Often WfWg will totally ignore a password you give it in a dialog box.
+
+----------------------
+HINT: Using MS Access
+
+Here are some notes on running MS-Access on a Samba drive from Stefan
+Kjellberg <stefank@esi.com.au>
+
+1. Opening a database in 'exclusive' mode does NOT work. Samba ignores
+ r/w/share modes on file open.
+
+2. Make sure that you open the database as 'shared' and to 'lock modified
+ records'
+
+3. Of course locking must be enabled for the particular share (smb.conf)
+
+
+---------------------
+HINT: password cacheing in WfWg
+
+Here is a hint from michael@ecel.uwa.edu.au (Michael Simmons):
+
+In case people where not aware. There is a program call admincfg.exe
+on the last disk (disk 8) of the WFW 3.11 disk set. To install it
+type EXPAND A:\ADMINCFG.EX_ C:\WINDOWS\ADMINCFG.EXE Then add an icon
+for it via the "Progam Manager" "New" Menu. This program allows you
+to control how WFW handles passwords. ie disable Password Caching etc
+for use with "security = user"
+
+
+--------------------
+HINT: file descriptor limits
+
+If you have problems with the limits on the number of open files you
+can edit local.h to fix it.
+
+--------------------
+HINT: HPUX initgroups() problem
+
+here is a hint from Frank Wales [frank@arcglade.demon.co.uk]:
+
+HP's implementation of supplementary groups is, er, non-standard (for
+hysterical reasons). There are two group files, /etc/group and
+/etc/logingroup; the system maps UIDs to numbers using the former, but
+initgroups() reads the latter. Most system admins who know the ropes
+symlink /etc/group to /etc/logingroup (hard link doesn't work for reasons
+too stupid to go into here). initgroups() will complain if one of the
+groups you're in in /etc/logingroup has what it considers to be an invalid
+ID, which means outside the range [0..UID_MAX], where UID_MAX is (I think)
+60000 currently on HP-UX. This precludes -2 and 65534, the usual 'nobody'
+GIDs.
+
+Perhaps you could suggest to users that, if they encounter this problem,
+they make sure that the programs that are failing to initgroups() be
+run as users not in any groups with GIDs outside the allowed range.
+
+This is documented in the HP manual pages under setgroups(2) and passwd(4).
+
+
+---------------------
+HINT: Patch your SCO system
+
+If you run SCO Unix then you may need to get important TCP/IP patches
+for Samba to work correctly. Try
+
+Paul_Davis@mindlink.bc.ca writes:
+
+ I was having problems with Accpac using 1.9.02 on SCO Unix. One
+ posting function reported corrupted data. After installing uod385a,
+ the problem went away (a restore from backup and then another
+ run-thru).
+
+ It appears that the uod385a update for SCO may be fairly important for
+ a lot of different DOS and Windows software under Samba.
+
+ uod385a can be found at ftp.sco.com /SLS/uod385a.Z and uod385a.ltr.Z.
+
+
diff --git a/docs/textdocs/INSTALL.sambatar b/docs/textdocs/INSTALL.sambatar
new file mode 100755
index 00000000000..413f54d3c65
--- /dev/null
+++ b/docs/textdocs/INSTALL.sambatar
@@ -0,0 +1,33 @@
+Contributor: Ricky Poulten <poultenr@logica.co.uk>
+Date: Unknown
+Status: Current
+
+Subject: Using smbtar
+=============================================================================
+
+Please see the readme and the man page for general info.
+
+1) Follow the samba installation instructions.
+
+2) If all goes well, test it out by creating a share on your PC (called
+backup for example) then doing something like,
+
+ ./smbtar -s mypc -t /dev/rmt/0ubn -x backup
+
+substituting whatever your tape drive is for the -t option, or set your
+tape environmental variable.
+
+If all does not go well, feel free to mail the author (poultenr@logica.co.uk)
+about bug reports / help / money / pizza / etc.
+
+3) Read the man page and the NOTES file for more information
+
+4) Work smbtar into your usual nightly backup scheme (presuming you
+have one :-}).
+
+
+NOTE:
+
+If you have problems with smbtar then it's probably best to contact the
+author Ricky Poulten (poultenr@logica.co.uk).
+
diff --git a/docs/textdocs/Imprints.txt b/docs/textdocs/Imprints.txt
new file mode 100755
index 00000000000..025381166b1
--- /dev/null
+++ b/docs/textdocs/Imprints.txt
@@ -0,0 +1,50 @@
+!==
+!== Imprints.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+==================================================================
+
+
+Imprints (Installation Manager of Printer driver
+Retreival and Installation for Samba) is a project to
+implement a UNIX equivalent of the Windows NT APW.
+It has been taken on in part by the Samba Team, VA Linux
+Systems and Hewlett-Packard. The Imprints toolset seeks
+to provide central repository for users and administrators
+to locate, download, and install all variations Window
+95/98/NT printer drivers on Samba print servers.
+
+The server portion of Imprints is composed of a database
+server which contains information and locations of various
+printer driver packages. This server can be queried over
+standard HTTP get requests and should therefore be available
+to most administrators behind firewalls. The server's
+database consists of records containing data about each
+known printer driver package. For example, each driver
+record contains a URL from which the Imprints installation
+client can download the package as well as a public key which
+can be used to verify the package's integrity.
+
+Once downloaded, the installation client will attempt to
+install the printer driver on the defined remote server
+using the username and password provided by the administrator.
+If the username/password pair can be authenticated by the
+remote server (and has the appropriate authorization), then
+the printer driver(s) is (are) installed and the new Printer
+is created.
+
+From Samba's point of view, the process of creating a new
+printer via the Imprints installation client is identical to
+that of using the Windows NT APW. In fact, Imprints utilizes
+Samba's rpcclient and smbclient tools to issue the same MS-RPC
+and file copy operations as an NT client. This means that
+Imprints can also be used to install printers on remote Windows
+NT print servers.
+
+For more information on Imprints, visit the project homepage
+at
+
+ http://imprints.sourceforge.net/.
+
+
+
+
diff --git a/docs/textdocs/Macintosh_Clients.txt b/docs/textdocs/Macintosh_Clients.txt
new file mode 100755
index 00000000000..c6b35811643
--- /dev/null
+++ b/docs/textdocs/Macintosh_Clients.txt
@@ -0,0 +1,26 @@
+!==
+!== Macintosh_Clients.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+> Are there any Macintosh clients for Samba?
+
+Yes. Thursby now have a CIFS Client / Server called DAVE - see
+http://www.thursby.com/
+
+They test it against Windows 95, Windows NT and samba for
+compatibility issues. At the time of writing, DAVE was at version
+1.0.1. The 1.0.0 to 1.0.1 update is available as a free download from
+the Thursby web site (the speed of finder copies has been greatly
+enhanced, and there are bug-fixes included).
+
+Alternatives - There are two free implementations of AppleTalk for
+several kinds of UNIX machnes, and several more commercial ones.
+These products allow you to run file services and print services
+natively to Macintosh users, with no additional support required on
+the Macintosh. The two free omplementations are Netatalk,
+http://www.umich.edu/~rsug/netatalk/, and CAP,
+http://www.cs.mu.oz.au/appletalk/atalk.html. What Samba offers MS
+Windows users, these packages offer to Macs. For more info on these
+packages, Samba, and Linux (and other UNIX-based systems) see
+http://www.eats.com/linux_mac_win.html
+
+
diff --git a/docs/textdocs/NetBIOS.txt b/docs/textdocs/NetBIOS.txt
new file mode 100755
index 00000000000..866ec82a727
--- /dev/null
+++ b/docs/textdocs/NetBIOS.txt
@@ -0,0 +1,155 @@
+!==
+!== NetBIOS.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: lkcl - samba@samba.org
+ Copyright 1997 Luke Kenneth Casson Leighton
+Date: March 1997
+Status: Current
+Updated: 12jun97
+
+Subject: Definition of NetBIOS Protocol and Name Resolution Modes
+=============================================================================
+
+=======
+NETBIOS
+=======
+
+NetBIOS runs over the following tranports: TCP/IP; NetBEUI and IPX/SPX.
+Samba only uses NetBIOS over TCP/IP. For details on the TCP/IP NetBIOS
+Session Service NetBIOS Datagram Service, and NetBIOS Names, see
+rfc1001.txt and rfc1002.txt.
+
+NetBEUI is a raw NetBIOS frame protocol implementation that allows NetBIOS
+datagrams to be sent out over the 'wire' embedded within LLC frames.
+NetBEUI is not required when using NetBIOS over TCP/IP protocols and it
+is preferable NOT to install NetBEUI if it can be avoided.
+
+IPX/SPX is also not required when using NetBIOS over TCP/IP, and it is
+preferable NOT to install the IPX/SPX transport unless you are using Novell
+servers. At the very least, it is recommended that you do not install
+'NetBIOS over IPX/SPX'.
+
+[When installing Windows 95, you will find that NetBEUI and IPX/SPX are
+installed as the default protocols. This is because they are the simplest
+to manage: no Windows 95 user-configuration is required].
+
+
+NetBIOS applications (such as samba) offer their services (for example,
+SMB file and print sharing) on a NetBIOS name. They must claim this name
+on the network before doing so. The NetBIOS session service will then
+accept connections on the application's behalf (on the NetBIOS name
+claimed by the application). A NetBIOS session between the application
+and the client can then commence.
+
+NetBIOS names consist of 15 characters plus a 'type' character. This is
+similar, in concept, to an IP address and a TCP port number, respectively.
+A NetBIOS-aware application on a host will offer different services under
+different NetBIOS name types, just as a host will offer different TCP/IP
+services on different port numbers.
+
+NetBIOS names must be claimed on a network, and must be defended. The use
+of NetBIOS names is most suitable on a single subnet; a Local Area Network
+or a Wide Area Network.
+
+NetBIOS names are either UNIQUE or GROUP. Only one application can claim a
+UNIQUE NetBIOS name on a network.
+
+There are two kinds of NetBIOS Name resolution: Broadcast and Point-to-Point.
+
+
+=================
+BROADCAST NetBIOS
+=================
+
+Clients can claim names, and therefore offer services on successfully claimed
+names, on their broadcast-isolated subnet. One way to get NetBIOS services
+(such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
+SMB file/print sharing: see cifs4.txt) working on a LAN or WAN is to make
+your routers forward all broadcast packets from TCP/IP ports 137, 138 and 139.
+
+This, however, is not recommended. If you have a large LAN or WAN, you will
+find that some of your hosts spend 95 percent of their time dealing with
+broadcast traffic. [If you have IPX/SPX on your LAN or WAN, you will find
+that this is already happening: a packet analyzer will show, roughly
+every twelve minutes, great swathes of broadcast traffic!].
+
+
+============
+NBNS NetBIOS
+============
+
+rfc1001.txt describes, amongst other things, the implementation and use
+of, a 'NetBIOS Name Service'. NT/AS offers 'Windows Internet Name Service'
+which is fully rfc1001/2 compliant, but has had to take specific action
+with certain NetBIOS names in order to make it useful. (for example, it
+deals with the registration of <1c> <1d> <1e> names all in different ways.
+I recommend the reading of the Microsoft WINS Server Help files for full
+details).
+
+Samba also offers WINS server capabilities. Samba does not interact
+with NT/AS (WINS replication), so if you have a mixed NT server and
+Samba server environment, it is recommended that you use the NT server's
+WINS capabilities, instead of samba's WINS server capabilities.
+
+The use of a WINS server cuts down on broadcast network traffic for
+NetBIOS name resolution. It has the effect of pulling all the broadcast
+isolated subnets together into a single NetBIOS scope, across your LAN
+or WAN, while avoiding the use of TCP/IP broadcast packets.
+
+When you have a WINS server on your LAN, WINS clients will be able to
+contact the WINS server to resolve NetBIOS names. Note that only those
+WINS clients that have registered with the same WINS server will be
+visible. The WINS server _can_ have static NetBIOS entries added to its
+database (usually for security reasons you might want to consider putting
+your domain controllers or other important servers as static entries,
+but you should not rely on this as your sole means of security), but for
+the most part, NetBIOS names are registered dynamically.
+
+[It is important to mention that samba's browsing capabilities (as a WINS
+client) must have access to a WINS server. if you are using samba also
+as a WINS server, then it will have a direct short-cut into the WINS
+database.
+
+This provides some confusion for lots of people, and is worth mentioning
+here: a Browse Server is NOT a WINS Server, even if these services are
+implemented in the same application. A Browse Server _needs_ a WINS server
+because a Browse Server is a WINS client, which is _not_ the same thing].
+
+Clients can claim names, and therefore offer services on successfully claimed
+names, on their broadcast-isolated subnet. One way to get NetBIOS services
+(such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
+SMB file/print sharing: see cifs6.txt) working on a LAN or WAN is to make
+your routers forward all broadcast packets from TCP/IP ports 137, 138 and 139.
+You will find, however, if you do this on a large LAN or a WAN, that your
+network is completely swamped by NetBIOS and browsing packets, which is why
+WINS was developed to minimise the necessity of broadcast traffic.
+
+WINS Clients therefore claim names from the WINS server. If the WINS
+server allows them to register a name, the client's NetBIOS session service
+can then offer services on this name. Other WINS clients will then
+contact the WINS server to resolve a NetBIOS name.
+
+
+=======================
+Samba WINS Capabilities
+=======================
+
+To configure samba as a WINS server, you must add "wins support = yes" to
+the [global] section of your smb.conf file. This will enable WINS server
+capabilities in nmbd.
+
+To configure samba as a WINS client, you must add "wins server = x.x.x.x"
+to the [global] section of your smb.conf file, where x.x.x.x is the TCP/IP
+address of your WINS server. The browsing capabilities in nmbd will then
+register (and resolve) WAN-wide NetBIOS names with this WINS server.
+
+Note that if samba has "wins support = yes", then the browsing capabilities
+will _not_ use the "wins server" option to resolve NetBIOS names: it will
+go directly to the internal WINS database for NetBIOS name resolution. It
+is therefore invalid to have both "wins support = yes" and
+"wins server = x.x.x.x". Note, in particular, that if you configure the
+"wins server" parameter to be the ip address of your samba server itself
+(as might one intuitively think), that you will run into difficulties.
+Do not use both parameters!
+
+
diff --git a/docs/textdocs/PROFILES.txt b/docs/textdocs/PROFILES.txt
new file mode 100755
index 00000000000..69fec36f08b
--- /dev/null
+++ b/docs/textdocs/PROFILES.txt
@@ -0,0 +1,388 @@
+!==
+!== PROFILES.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributors: Bruce Cook <BC3-AU@bigfoot.com>
+ Copyright (C) 1998 Bruce Cook
+
+ John Terpstra <samba@samba.org>
+ Copyright (C) 1998 John H. Terpstra
+
+ Wolfgang Ratzka <ratzka@hrz.uni-marburg.de>
+ Copyright (C) 1998 Wolfgang Ratzka
+
+Created: April 11, 1998
+Updated: April 11, 1998
+
+Subject: User Profiles
+===========================================================================
+
+From BC3-AU@bigfoot.com Sat Apr 11 13:36:05 1998
+Date: Sat, 11 Apr 1998 17:13:49 +1000
+From: Bruce Cook <BC3-AU@bigfoot.com>
+To: Multiple recipients of list <samba-ntdom@samba.org>
+Subject: RE: A question about NT Domains
+
+Luke Kenneth Casson Leighton writes:
+ > On Fri, 10 Apr 1998, Jean-Francois Micouleau wrote:
+ >
+ > > On Fri, 10 Apr 1998, Luke Kenneth Casson Leighton wrote:
+ > >
+ > > > ah, then i need to explain better. two or more users have identical
+ > > > profiles. say only one user installs a program which adds additional keys
+ > > > into the registry. those keys, as i understand it, will *not* be removed
+ > > > from HKEY_LOCAL_USER when subsequent users log in.
+ > >
+ > > under W95 or NT ?
+ >
+ > my experience is with Win95, but i expect the same for NT, and have been
+ > told that it is so by someone who runs NT admin training courses.
+ >
+ > > and why do you want to have one profile shared between multiples users ?
+ >
+ > you don't. how did you get that impression? i said multiple users with
+ > identical profiles, not multiple users sharing one profile.
+
+In my experience with both Win95 and NT, is that the HKEY_LOCAL_USER information
+is stored in USER.dat or NTuser.DAT for NT. ALL of this branch is in this file
+and there is no overlap between any two users (Unless you have '95 set up
+to use a single common profile).
+
+[** lkcl: see jht's message for conditions under which an overlap can occur **]
+
+The HKEY_LOCAL_MACHINE branch is machine based, and shared by all users of that
+machine.
+
+
+[And now for a whole stack of caveats]
+
+1. User start menu paths are not stored in the registry (obviously) they're
+ a directory structure that located by settings in HKEY_LOCAL_USER.
+
+ If you want start menues / desktop / favorites to be individual to a user
+ you must set up your user registry so these can be located individually.
+ The easiest tool to manage this is the policy editor.
+
+2. When you log onto 'Doze 95, it has to find the user registry.
+
+
+ If you have specified a common profile, a "default user" USER.DAT is used.
+
+ If you have specified individualised profiles, then USER.DAT will be found
+ by the following formula:
+
+ 1. if NET USE x: /HOME was used at startup, try for x:\USER.DAT (where
+ x: is any drive letter from A to Z.
+ if no USER.DAT is found go to step 3
+
+ 2. if no home is specified in a mapping,
+ ...\windows\profiles\username\USER.DAT is used. If no USER.DAT exists
+ go to step 3.
+
+ 3. If neither of the previous two found a USER.DAT, then it will use
+ a prototype USER.DAT which it will later save to the above specified
+ path when the user logs out.
+
+ The interesting thing here is that the prototype USER.DAT used here
+ is actually a copy of the last USER.DAT used on this machine. (This
+ may be the effect that the original poster is seeing)
+
+ 4. As discussed above the start menu and desktop are specified in the
+ registry contained within USER.DAT. When a new USER.DAT is created
+ from a prototype, new directories are created for the start menu and
+ desktop ACCORDING TO HOW THE COPIED PROTOTYPE DEFINES THEM.
+
+ So if the prototype USER.DAT says that start menu is in H:\Start Menu
+ but programs folder is C:\windows\start menu\programs, then the
+ H:\start menu will be created, and the existing machine programs
+ folder used.
+
+ This means that is is important when creating roving profiles to get
+ your prototype USER.DAT and general user directory structure set up
+ exactly as you want it, and then make a copy of it that you know will
+ be safe from modification. When creating a new user you then copy
+ this prototype into the new user area, so that the new user doesn't
+ just inherit what the previous user had.
+
+
+3. When you log onto 'Doze NT, it has to find the user registry.
+
+
+ NT is easier to see what's going on, but follows much the same rules as
+ '95. The big difference being that 'NT gets its profile location from
+ the login server when it's logged in. (On an NT system have a look at user
+ manager/user/profile - you will see that you can specify the user profile
+ path) Under NT3.51 this profile path was a path to NTuser.DAT, on 4.0 this
+ seems to be a path to a directory structure (haven't played with many NT4
+ servers)
+
+ I'm not sure how this works in samba, as I haven't yet tried the NT_DOM stuff
+ yet (Luke: I assume you have a keyword for this?)
+
+[lkcl: nt workstations should look in exactly the same places for things on
+ samba or other SMB servers as they do on an NT server, as long as that
+ SMB server looks like NT. if anyone finds that something fails, alert
+ us on samba@samba.org and we'll look into it].
+
+ When an NT system find a user without a NTuser.DAT, it copies from a
+ prototype that it stores especially for this purpose, so while unlike '95
+ the user doesn't get whatever happened last on the machine, the user will
+ get a fairly minimalist configuration.
+
+[[jht:
+When a Win95 machine logs onto a Windows NT Domain the Win95 machine looks
+for the presence of a file called Config.Pol in the following location:
+ \\"Authenticating Server"\NETLOGON
+It reads this file and uses it to ammend both the desktop environment as well
+as the file %WinDir%\Profiles\%USERNAME%\User.DAT. As with Windows NT, on log
+out this file gets written back to the profile server into the %USERNAME%
+directory in the profile share.
+
+It is thus possible to share a common desktop profile between Windows NT and
+Windows 9x.
+:jht]]
+
+
+4. There are a *LOT* of reasons that the 'doze machine might not find USER.DAT
+ and therefore default to a prototype.
+
+ 1. Can't execute logon script & therefore no /HOME mapping (Most common)
+ .Make sure the script exists
+ .that you have your logon script set right
+ .Netlogon share must exist
+ .Protection/ownership of the script and share
+
+ 2. no /HOME mapping in the logon script
+
+ 3. no home path specified in /etc/smb.conf (Or no home mapping set
+ up for that user in NT's user manager)
+
+ 4. Protection/ownership of the user directory
+
+ 5. protection/ownership of USER.DAT
+
+ 6. basic networking problems
+ .Is the networking available (Test it by manually mapping
+ to both the user share and netlogon share)
+ .Was the networking working during logon ?
+
+ 7. Has it defaulted to a prototype, and then had you map the home
+ directory afterwards ? - This will result in the bad prototype
+ being written into the users home, and them being stuck with it,
+ (Just replace USER.DAT again)
+
+
+5. Interesting NOTE
+
+ When '95 is performing the logon script, the HKEY_LOCAL_USERS has
+ NOT been mapped from the USER.DAT. What has been mapped at this stage
+ is the prototype registry (last one used).
+
+ I assume the reason for this is that '95 is waiting for the logon
+ script to complete so that it can identify where the user's home
+ directory is.
+
+ If at this point you attempt to do anything that uses the USER registry,
+ (installing something for example or reading something from the user
+ registry) you will actually be operating on the machine stored prototype
+ profile not the user profile. This means that nothing will realy
+ happen to the user setup (No menu items, no settings etc).
+
+ To get around this you can name a process in the "run once" entries in
+ the HKEY_LOCAL_MACHINE branch, and these "run once" processes will be
+ executed once the USER.DAT is loaded, and all the user directories are
+ accessible.
+
+
+To sum up:
+
+ NET USE H: /HOME
+ is the key to getting your user profiles loaded from a server.
+ NET USE H: \\server\homes
+ Won't get it right without a lot of stuffing about.
+
+ Windoze '95 goes through a lot to bring you your user profile and
+ if anything goes wrong during this process, it will drop back to
+ using whatever profile was last used on the machine.
+
+
+From samba@aquasoft.com.au Sat Apr 11 13:48:54 1998
+Date: Sat, 11 Apr 1998 09:34:08 +1000
+From: Samba Bugs <samba@aquasoft.com.au>
+To: Multiple recipients of list <samba-ntdom@samba.org>
+Subject: Re: A question about NT Domains
+
+Just for the sake of completeness I thought I'd add a bit to this.
+Let's be clear about which files affect registry changes (or contents).
+
+Under NT, open a command prompt interface:
+cd %SystemRoot%\System32\config
+dir
+
+The standard registry files are:
+ Default - all component default settings
+ System - all HKLM\System entries
+ Software - all HKLM\Software entries
+ Security - Domain/Machine releated User Rights & Privs.
+ SAM - the Security Access Manager database (ie:Passwords etc.)
+
+[[jht:
+The SAM and Security files are the only files that get synchronised between
+Windows NT Domain Controllers.
+:jht]]
+
+These are used by EVERYTHING!!
+
+When a user logs in the following files get checked:
+ 1) \\"Authenticating Server"\NETLOGON\NTConfig.Pol
+ 2) %SystemRoot%\Profiles\Policies\NTConfig.Pol
+ this one is a copy of the last NTConfig.Pol downloaded
+ from (1) above - if available.
+ 3) %SystemRoot%\Policies\%UserName%\NTUser.DAT
+
+[[jht:
+The System Policy Editor on Windows NT can be used to create both the
+Windows 95 "Config.Pol" file, as well as the Windows NT "NTConfig.Pol"
+file. To create the Windows 95 policy file you MUST load the Windows 95
+policy template BEFORE creating the Config.Pol file.
+:jht]]
+
+The later, is first obtained from a profile server if the User_Init_Info
+passed from the Domain Logon Server specifies use of a roaming profile.
+If item (3) does NOT exist and/or NO default profile is available one gets
+created from the system default settings PLUS the last loaded file at item
+(2) above.
+
+The HKCU is always unique to the currently logged in user, BUT if the
+currently logged in user is using a shared profile that has NOT been made
+exclusive then on logout the HKCU will be written over the top of the
+source files. That is why Mandatory profiles are essential when sharing a
+roaming profile.
+
+On Sat, 11 Apr 1998, Wolfgang Ratzka wrote:
+
+> Luke Kenneth Casson Leighton wrote:
+>
+> > my experience is with Win95, but i expect the same for NT, and have been
+> > told that it is so by someone who runs NT admin training courses.
+>
+> On NT it is quite definitely not so. HKCU will always be loaded completely from
+> the user's NTuser.dat file and unloaded again after logout.
+> In fact HKCU is not a proper registry hive but a symbolic reference to the subkey of
+> HKEY_USERS that corresponds to the current user. If more than one user
+> is active on an NT machine (on plain vanilla NT this *is* possible if you have
+> services running as a non-system user; on WinFrame or Hydra multiple users
+> can be logged in) you will see several subkeys of HKU that correspond to
+> the active users and don't interfere with each other.
+>
+> Of course some settings that a user can change do not go into the HKCU hive
+> but into HKLM, most notably the screen resolution and the number of colours
+> (you can use policies to prevent user's from changing these).
+> Some applications put information that should go into HKCU into HKLM instead.
+> (Hall of Shame: Netscape Communicator, Microsoft Office 97 [User dictionaries!]...).
+> Others just use plain good old INI files in their program directory or even
+> in \WINNT\SYSTEM32. Those changes will not be user specific but machine
+> specific and those programs will cause trouble, when one tries to run them
+> on WinFrame or Hydra... :-).
+>
+> Summarizing:
+>
+> Q: Will the next user inherit a previous user's additions
+> to the HKCU registry hive?
+> A: Quite definitely not.
+
+Correct.
+
+>
+> Q: Can a user foul up the configuration for the next user?
+> A: Quite definitely yes!
+
+See above. Yes, but not if correctly configured.
+
+>
+> Q: Is this discussion out of place on the samba-ntdom list?
+> A: Errr....
+
+Errr... Really? I think it is. Do we, or do we not, want to help people to
+gain stable and dependable use of samba?
+
+> --
+> Wolfgang Ratzka (dialing in from home)
+
+Cheers,
+John H Terpstra (Also from home!!!!)
+
+=============================================================================
+Further notes by Bruce Cook
+
+Date: Sun, 12 Apr 1998 14:12:22 +1000
+From: Bruce Cook <BC3-AU@bigfoot.com>
+Subject: Re: Win95 / NT Profiles (was: RE: A question about NT Domains)
+
+Ah yes I knew there was something I forgot.
+here it is for completeness.
+
+=============================================================================
+
+When a user logs into a specific machine for the first time, they will be
+told that they've never logged into the machine, and would they like to
+store the user setting for future use.
+
+If the user answers NO, they will be nagged about this every time they
+log into the machine until they say YES. (How about it MS, could we
+possible do something about this feature?)
+
+When the user answers YES, thereafter upon logging out of the machine,
+a copy of the user's profile is also written onto the machines local disk
+for later use.
+
+When a user logs into a machine where his/her profile has previously been
+saved, a comparison is made between the date of the profile copy kept on
+the machine, and the date of the profile stored on the server. In theory
+the server date should be later or the same.
+
+If the local machine date is later than the server date, the client
+machine will tell you the the settings on the local machine are more
+recent than those of the server, and would you like to user them instead.
+
+This occurs for a couple of reasons:
+ 1. Server not available when the user logs out
+ 2. Date mismatch between the server and the client
+ (I always use NET TIME \\server /SET /YES in my logon scripts)
+
+
+Logging in with NO server available.
+
+In some cases a client will want to log into a network with no server
+available. (Portables away from the office, or a dead server)
+
+This can only happen if the administrator has NOT set the machine to
+give access only upon password verification from the server.
+(If the admin has done this, it can be circumvented by restarting
+ the machine in safe mode, and running poledit, or regedit and
+ disabling that feature)
+
+If you are able to log in while the server is unavailable, you have
+two choices
+ 1. Log in as a user that previously stored a profile
+ (The password won't have to match unless the machine
+ is set up to store passwords)
+
+ 2. log in as the default user (bit the cancel button or escape key)
+
+If you choose to use your profile stored on the local machine, there are
+several things you should be wary of:
+ 1. the profile stored on the machine will be a copy of the last
+ profile used when you logged into THAT machine. You may get
+ quite an old profile.
+ 2. When you log out, that local profile is garunteed to be later
+ than the one on the server, and if the server is available, or
+ you later log into that machine when the server is available
+ you could overwrite the good server profile with a bogus profile.
+
+
+Technique note:
+ I set portable computers up so that they don't use roaming profiles,
+ rather they have a single profile kept on the machine. This means
+ that a user has the same desktop look an feel regardless of where
+ they are. This follows the philosophy that laptops tend to be used
+ by only one person.
diff --git a/docs/textdocs/Passwords.txt b/docs/textdocs/Passwords.txt
new file mode 100755
index 00000000000..1f5407eec81
--- /dev/null
+++ b/docs/textdocs/Passwords.txt
@@ -0,0 +1,49 @@
+!==
+!== Passwords.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Unknown
+Date: Updated April 19th 1999.
+Status: Current
+
+Subject: NOTE ABOUT PASSWORDS
+=============================================================================
+
+Unix systems use a wide variety of methods for checking the validity
+of a password. This is primarily controlled with the Makefile defines
+mentioned in the Makefile.
+
+Also note that some clients (notably WfWg) uppercase the password
+before sending it. The server tries the password as it receives it and
+also after lowercasing it.
+
+The Samba server can also be configured to try different
+upper/lowercase combinations. This is controlled by the [global]
+parameter "password level". A level of N means to try all combinations
+up to N uppercase characters in the password. A high value can chew a
+fair bit of CPU time and can lower the security of your system. Do not
+use this options unless you really need it - the time taken for
+password checking can become so high that clients time out.
+
+If you do use the "password level" option then you might like to use
+-DUFC_CRYPT in your Makefile. On some machine this makes password
+checking _much_ faster. This is also useful if you use the @group
+syntax in the user= option.
+
+If your site uses AFS (the Andrew File System), you can use the AFS section
+in the Makefile. This will first attempt to authenticate a username and
+password to AFS. If that succeeds, then the associated AFS rights will be
+granted. Otherwise, the password checking routine falls back to whatever
+Unix password checking method you are using. Note that the AFS code is
+only written and tested for AFS 3.3 and later.
+
+
+SECURITY = SERVER or DOMAIN
+===========================
+
+Samba can use a remote server to do its username/password
+validation. This allows you to have one central machine (for example a
+NT box) control the passwords for the Unix box.
+
+See the section on "security =" in smb.conf(5) for details.
+
+
diff --git a/docs/textdocs/Printing.txt b/docs/textdocs/Printing.txt
new file mode 100755
index 00000000000..bdd4cbd59c2
--- /dev/null
+++ b/docs/textdocs/Printing.txt
@@ -0,0 +1,258 @@
+!==
+!== Printing.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Unknown <samba@samba.org>
+Revised by: Patrick Powell <papowell@lprng.org>
+Date: August 11, 2000
+Status: Current
+
+Subject: Dubugging Printing Problems
+=============================================================================
+
+This is a short description of how to debug printing problems with
+Samba. This describes how to debug problems with printing from a SMB
+client to a Samba server, not the other way around. For the reverse
+see the examples/printing directory.
+
+Please send enhancements to this file to samba@samba.org
+
+Ok, so you want to print to a Samba server from your PC. The first
+thing you need to understand is that Samba does not actually do any
+printing itself, it just acts as a middleman between your PC client
+and your Unix printing subsystem. Samba receives the file from the PC
+then passes the file to a external "print command". What print command
+you use is up to you.
+
+The whole things is controlled using options in smb.conf. The most
+relevant options (which you should look up in the smb.conf man page)
+are:
+ [global]
+ print command - send a file to a spooler
+ lpq command - get spool queue status
+ lprm command - remove a job
+ [printers]
+ path = /var/spool/lpd/samba
+
+The following are nice to know about:
+
+ queuepause command - stop a printer or print queue
+ queueresume command - start a printer or print queue
+
+Example:
+ print command = /usr/bin/lpr -r -P%p %s
+ lpq command = /usr/bin/lpq -P%p %s
+ lprm command = /usr/bin/lprm -P%p %j
+ queuepause command = /usr/sbin/lpc -P%p stop
+ queueresume command = /usr/sbin/lpc -P%p start
+
+Samba should set reasonable defaults for these depending on your
+system type, but it isn't clairvoyant. It is not uncommon that you
+have to tweak these for local conditions. The commands should
+always have fully specified pathnames, as the smdb may not have
+the correct PATH values.
+
+When you send a job to Samba to be printed, it will make a temporary
+copy of it in the directory specified in the [printers] section.
+and it should be periodically cleaned out. The lpr -r option
+requests that the temporary copy be removed after printing; If
+printing fails then you might find leftover files in this directory,
+and it should be periodically cleaned out. Samba used the lpq
+command to determine the "job number" assigned to your print job
+by the spooler.
+
+The %<letter> are "macros" that get dynamically replaced with appropriate
+values when they are used. The %s gets replaced with the name of the spool
+file that Samba creates and the %p gets replaced with the name of the
+printer. The %j gets replaced with the "job number" which comes from
+the lpq output.
+
+DEBUGGING PRINTER PROBLEMS
+
+One way to debug printing problems is to start by replacing these
+command with shell scripts that record the arguments and the contents
+of the print file. A simple example of this kind of things might
+be:
+
+ print command = /tmp/saveprint %p %s
+
+ #!/bin/saveprint
+ # we make sure that we are the right user
+ /usr/bin/id -p >/tmp/tmp.print
+ # we run the command and save the error messages
+ # replace the command with the one appropriate for your system
+ /usr/bin/lpr -r -P$1 $2 2>>&/tmp/tmp.print
+
+Then you print a file and try removing it. You may find that the
+print queue needs to be stopped in order to see the queue status
+and remove the job:
+
+h4: {42} % echo hi >/tmp/hi
+h4: {43} % smbclient //localhost/lw4
+added interface ip=10.0.0.4 bcast=10.0.0.255 nmask=255.255.255.0
+Password:
+Domain=[ASTART] OS=[Unix] Server=[Samba 2.0.7]
+smb: \> print /tmp/hi
+putting file /tmp/hi as hi-17534 (0.0 kb/s) (average 0.0 kb/s)
+smb: \> queue
+1049 3 hi-17534
+smb: \> cancel 1049
+Error cancelling job 1049 : code 0
+smb: \> cancel 1049
+Job 1049 cancelled
+smb: \> queue
+smb: \> exit
+
+The 'code 0' indicates that the job was removed. The comment
+by the smbclient is a bit misleading on this.
+You can observe the command output and then and look at the
+/tmp/tmp.print file to see what the results are. You can quickly
+find out if the problem is with your printing system. Often people
+have problems with their /etc/printcap file or permissions on
+various print queues.
+
+WHAT PRINTERS DO I HAVE
+
+You can use the 'testprns' program to check to see if the printer
+name you are using is recognized by Samba. For example, you can
+use:
+
+ testprns printer /etc/printcap
+
+Samba can get its printcap information from a file or from a program.
+You can try the following to see the format of the extracted
+information:
+
+ testprns -a printer /etc/printcap
+
+ testprns -a printer '|/bin/cat printcap'
+
+SETTING UP PRINTCAP AND PRINT SERVERS
+
+You may need to set up some printcaps for your Samba system to use.
+It is strongly recommended that you use the facilities provided by
+the print spooler to set up queues and printcap information.
+
+Samba requires either a printcap or program to deliver printcap
+information. This printcap information has the format:
+
+ name|alias1|alias2...:option=value:...
+
+For almost all printing systems, the printer 'name' must be composed
+only of alphanumeric or underscore '_' characters. Some systems also
+allow hyphens ('-') as well. An alias is an alternative name for the
+printer, and an alias with a space in it is used as a 'comment'
+about the printer. The printcap format optionally uses a \ at the end of lines
+to extend the printcap to multiple lines.
+
+
+Here are some examples of printcap files:
+
+pr just printer name
+pr|alias printer name and alias
+pr|My Printer printer name, alias used as comment
+pr:sh:\ Same as pr:sh:cm= testing
+ :cm= \
+ testing
+pr:sh Same as pr:sh:cm= testing
+ :cm= testing
+
+Samba reads the printcap information when first started. If you make
+changes in the printcap information, then you must do the following:
+
+a) make sure that the print spooler is aware of these changes.
+ The LPRng system uses the 'lpc reread' command to do this.
+
+b) make sure that the spool queues, etc., exist and have the
+ correct permissions. The LPRng system uses the 'checkpc -f'
+ command to do this.
+
+c) You now should send a SIGHUP signal to the smbd server to have
+ it reread the printcap information.
+
+JOB SENT, NO OUTPUT
+
+This is the most frustrating part of printing. You may have sent the
+job, verified that the job was forwarded, set up a wrapper around
+the command to send the file, but there was no output from the printer.
+
+First, check to make sure that the job REALLY is getting to the
+right print queue. If you are using a BSD or LPRng print spooler,
+you can temporarily stop the printing of jobs. Jobs can still be
+submitted, but they will not be printed. Use:
+
+ lpc -Pprinter stop
+
+Now submit a print job and then use 'lpq -Pprinter' to see if the
+job is in the print queue. If it is not in the print queue then
+you will have to find out why it is not being accepted for printing.
+
+Next, you may want to check to see what the format of the job really
+was. With the assistance of the system administrator you can view
+the submitted jobs files. You may be surprised to find that these
+are not in what you would expect to call a printable format.
+You can use the UNIX 'file' utitily to determine what the job
+format actually is:
+
+ cd /var/spool/lpd/printer # spool directory of print jobs
+ ls # find job files
+ file dfA001myhost
+
+You should make sure that your printer supports this format OR that
+your system administrator has installed a 'print filter' that will
+convert the file to a format appropriate for your printer.
+
+JOB SENT, STRANGE OUTPUT
+
+Once you have the job printing, you can then start worrying about
+making it print nicely.
+
+The most common problem is extra pages of output: banner pages
+OR blank pages at the end.
+
+If you are getting banner pages, check and make sure that the
+printcap option or printer option is configured for no banners.
+If you have a printcap, this is the :sh (suppress header or banner
+page) option. You should have the following in your printer.
+
+ printer: ... :sh
+
+If you have this option and are still getting banner pages, there
+is a strong chance that your printer is generating them for you
+automatically. You should make sure that banner printing is disabled
+for the printer. This usually requires using the printer setup software
+or procedures supplied by the printer manufacturer.
+
+If you get an extra page of output, this could be due to problems
+with your job format, or if you are generating PostScript jobs,
+incorrect setting on your printer driver on the MicroSoft client.
+For example, under Win95 there is a option:
+
+ Printers|Printer Name|(Right Click)Properties|Postscript|Advanced|
+
+that allows you to choose if a Ctrl-D is appended to all jobs.
+This is a very bad thing to do, as most spooling systems will
+automatically add a ^D to the end of the job if it is detected as
+PostScript. The multiple ^D may cause an additional page of output.
+
+RAW POSTSCRIPT PRINTED
+
+This is a problem that is usually caused by either the print spooling
+system putting information at the start of the print job that makes
+the printer think the job is a text file, or your printer simply
+does not support PostScript. You may need to enable 'Automatic
+Format Detection' on your printer.
+
+ADVANCED PRINTING
+
+Note that you can do some pretty magic things by using your
+imagination with the "print command" option and some shell scripts.
+Doing print accounting is easy by passing the %U option to a print
+command shell script. You could even make the print command detect
+the type of output and its size and send it to an appropriate
+printer.
+
+DEBUGGING
+
+If the above debug tips don't help, then maybe you need to bring in
+the bug guns, system tracing. See Tracing.txt in this directory.
+-----------------------------------------------------------------------------
diff --git a/docs/textdocs/README.DCEDFS b/docs/textdocs/README.DCEDFS
new file mode 100755
index 00000000000..da9bb2197da
--- /dev/null
+++ b/docs/textdocs/README.DCEDFS
@@ -0,0 +1,78 @@
+Contributor: Jim Doyle <doyle@oec.com>
+Date: 06-02-95
+Status: Current but needs updating
+
+Subject: Basic DCE/DFS Support for SAMBA 1.9.13
+=============================================================================
+
+Functionality:
+--------------
+
+ Per-instance authentication for DCE/DFS.
+
+Missing Functionality in this Implementation:
+---------------------------------------------
+
+ * No automatic refresh of credentials
+
+ To do so would not be that hard.. One could simply
+ stash the clear-text key in memory, spawn a key management
+ thread to wake up right before credentials expire and
+ refresh the login context.
+
+ * No UNIX Signals support (SIGCLD, SIGPIPE, SIGHUP, SIGBUS, SIGSEGV)
+
+
+ There is no support for signal processing in Samba daemons
+ that need to authenticate with DCE. The explanation for this
+ is that the smbd is linked against thread-safe libraries in
+ order to be able to use DCE authentication mechanisms.
+ Because smbd uses signal() and fork(), it represents the
+ worst case scenario for DCE portability. In order
+ to properly support signals in a forked server environment,
+ some rework of smbd is needed in order to properly
+ construct, shutdown and reconstruct asynchronous signal
+ handling threads and synchronous signal traps across the
+ parent and child. I have not had contiguous time to work
+ on it, I expect it to be a weeks worth of work to cleanly
+ integrate thread-safe signal handing into the code and
+ test it. Until I can get to this task, I will leave it up
+ to someone adventurous enough to engineer it and negotiate
+ with Andrew to integrate the changes into the mainline branch.
+
+ The lack of full signal support means that you cannot
+ rely upon SIGHUP-ing the parent daemon to refresh
+ the configuration data. Likewise, you cannot take advantage
+ of the builtin SIGBUS/SIGSEGV traps to diagnose failures.
+ You will have to halt Samba in order to make changes
+ and then have them take effect.
+
+ The SMBD server as it stands is suitable to use if you
+ already have experience with configuring and running
+ SAMBA.
+
+Tested Platforms:
+-----------------
+
+ HP-UX 9.05 / HP-UX DCE 1.2.1
+ AIX 3.2.5 / AIX DCE/6000 1.3
+ DEC OSF-1 3.0 / DEC DCE 1.3
+
+Building:
+---------
+
+ - Uncomment the the appropriate block in the Makefile
+ for the platform you wish to build on.
+
+ - Samples of Samba server configuration files for our
+ DFS environment are included in samples.dcedfs/
+
+
+
+Bugs, Suggestions, etc..
+--------------------------
+
+ Please post them to the mailing list.
+ That way I will see them and they will become part of
+ the archives so others can share the knowledge.
+
diff --git a/docs/textdocs/README.NOW b/docs/textdocs/README.NOW
new file mode 100755
index 00000000000..1184a9d057f
--- /dev/null
+++ b/docs/textdocs/README.NOW
@@ -0,0 +1,8 @@
+The files in the directory have either yet to
+converted into SGML/DocBook format or are outdated.
+To create ASCII versions of the documentation
+in the ../htmldocs/ directory, run
+
+ $ lynx -dump file.html > file.txt
+
+
diff --git a/docs/textdocs/README.jis b/docs/textdocs/README.jis
new file mode 100755
index 00000000000..50ff0cced74
--- /dev/null
+++ b/docs/textdocs/README.jis
@@ -0,0 +1,149 @@
+$B!|(B samba $BF|K\8lBP1~$K$D$$$F(B
+
+1. $BL\E*(B
+
+ $BF|K\8lBP1~$O!"(B
+
+ (1) MS-Windows $B>e$G!"4A;z%U%!%$%kL>$r$I$&$7$F$b07$&I,MW$N$"$k%"%W%j%1!<%7%g%s$,$A$c(B
+ $B$s$HF0:n$9$k!#Nc$($P!"(BMS-WORD 5 $B$J$I$O!"%$%s%9%H!<%k;~$K4A;z$N%U%!%$%kL>$r>!<j(B
+ $B$K$D$1$F$7$^$$$^$9!#$3$&$$$C$?>l9g$K$A$c$s$HBP1~$G$-$k$h$&$K$9$k!#(B
+
+ (2) UNIX $B$O!":G6a$G$O$[$H$s$I$N$b$N$,(B 8 bits $B$N%U%!%$%kL>$r%5%]!<%H$7$F$$$^$9$,!"(B
+ $BCf$K$O!"$3$l$r%5%]!<%H$7$F$$$J$$$b$N$b$"$j$^$9!#$3$N$h$&$J>l9g$G$b!"(B(1)$B$NL\E*(B
+ $B$,K~B-$G$-$k$h$&$K$9$k!#(B
+
+ $B$rL\E*$H$7$F$$$^$9!#$=$N$?$a!"F|K\8lBP1~$O!"I,MW:G>.8B$7$+9T$J$C$F$*$j$^$;$s!#(B
+
+ $BF|K\8lBP1~$7$?(B samba $B$rMxMQ$9$k$?$a$K$O!"%3%s%Q%$%k$9$k;~$K!"I,$:!"(BKANJI $B$NDj5A$rDI(B
+ $B2C$7$F$/$@$5$$!#$3$N%*%W%7%g%s$r;XDj$7$F$$$J$$>l9g$O!"F|K\8l$N%U%!%$%kL>$r@5$7$/07(B
+ $B$&$3$H$O$G$-$^$;$s!#!J%3%s%Q%$%k$K$D$$$F$O!"2<5-(B 3. $B$r;2>H$7$F2<$5$$!K(B
+
+2. $BMxMQJ}K!(B
+
+(1) $BDI2C$7$?%Q%i%a!<%?(B
+
+ smb.conf $B%U%!%$%k$N(B global $B%;%/%7%g%s$K0J2<$N%Q%i%a!<%?$r@_Dj$G$-$k$h$&$K$7$^$7$?!#(B
+
+ [global]
+ ....
+ coding system = <$B%3!<%I7O(B>
+
+ $B$3$3$G;XDj$5$l$?%3!<%I7O$,(B UNIX $B>e$N%U%!%$%k%7%9%F%`$N%U%!%$%kL>$N%3!<%I$K$J$j$^$9!#(B
+ $B@_Dj$G$-$k$b$N$O!"<!$N$h$&$K$J$C$F$$$^$9!#(B
+
+ sjis: SHIFT JIS (MS $B4A;z%3!<%I(B)
+ euc: EUC $B%3!<%I(B
+ hex: 7 bits $B$N(B ASCII $B%3!<%I0J30$N%3!<%I$r0J2<$N7A<0$GI=$9J}<0$G$9!#Nc$($P!"(B
+ '$B%*%U%#%9(B' $B$H$$$&L>A0$O!"(B':83:49:83:74:83:42:83:58' $B$N$h$&$K!"(B':' $B$N8e$K#27e(B
+ $B$N(B16$B?J?t$rB3$1$k7A<0$K$J$j$^$9!#(B
+ $B$3$3$G!"(B':' $B$rB>$NJ8;z$KJQ99$7$?$$>l9g$O!"(Bhex $B$N8e$m$K$=$NJ8;z$r;XDj$7$^$9!#(B
+ $BNc$($P!"(B@$B$rJQ$o$j$K;H$$$?$$>l9g$O!"(B'hex@'$B$N$h$&$K;XDj$7$^$9!#(B
+ cap: 7 bits $B$N(B ASCII $B%3!<%I0J30$N%3!<%I$r0J2<$N7A<0$GI=$9J}<0$H$$$&E@$G$O(B
+ hex$B$HF1MM$G$9$,!"(BCAP (The Columbia AppleTalk Package)$B$H8_49@-$r;}$DJQ49(B
+ $BJ}<0$H$J$C$F$$$^$9!#(Bhex$B$H$N0c$$$O(B0x80$B0J>e$N%3!<%I$N$_(B':80'$B$N$h$&$KJQ49(B
+ $B$5$l!"$=$NB>$O(BASCII$B%3!<%I$G8=$5$l$^$9!#(B
+ $BNc$($P!"(B'$B%*%U%#%9(B'$B$H$$$&L>A0$O!"(B':83I:83t:83B:83X'$B$H$J$j$^$9!#(B
+
+ JIS $B%3!<%I$K$D$$$F$O!"0J2<$NI=$r;2>H$7$F2<$5$$!#(B
+ $B(#(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(!(!(!(!(!($(B
+ $B(";XDj(B $B("4A;z3+;O("4A;z=*N;("%+%J3+;O("%+%J=*N;("1Q?t3+;O("Hw9M(B $B("(B
+ $B('(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(!(!(!(!(!()(B
+ $B("(Bjis7 $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis 7$BC10LId9f(B $B("(B
+ $B("(Bjunet $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B7bits $B%3!<%I(B $B("(B
+ $B("(Bjis8 $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis 8$BC10LId9f(B $B("(B
+ $B("(Bj7bb $B("(B\E$B $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
+ $B("(Bj7bj $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis7$B$HF1$8(B $B("(B
+ $B("(Bj7bh $B("(B\E$B $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
+ $B("(Bj7@b $B("(B\E$@ $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
+ $B("(Bj7@j $B("(B\E$@ $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(B $B("(B
+ $B("(Bj7@h $B("(B\E$@ $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
+ $B("(Bj8bb $B("(B\E$B $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
+ $B("(Bj8bj $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis8$B$HF1$8(B $B("(B
+ $B("(Bj8bh $B("(B\E$B $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
+ $B("(Bj8@b $B("(B\E@@ $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
+ $B("(Bj8@j $B("(B\E$@ $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(B $B("(B
+ $B("(Bj8@h $B("(B\E$@ $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
+ $B("(Bjubb $B("(B\E$B $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
+ $B("(Bjubj $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(Bjunet$B$HF1$8(B $B("(B
+ $B("(Bjubh $B("(B\E$B $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
+ $B("(Bju@b $B("(B\E$@ $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
+ $B("(Bju@j $B("(B\E$@ $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B $B("(B
+ $B("(Bju@h $B("(B\E$@ $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
+ $B(&(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(!(!(!(!(!(%(B
+
+ $B$$$:$l$N>l9g$b!"$9$G$KB8:_$7$F$$$kL>A0$KBP$7$F$O!"4A;z$N3+;O=*N;%7!<%1%s%9$O!"0J2<(B
+ $B$N$b$N$rG'<1$7$^$9!#(B
+ $B4A;z$N;O$^$j(B: \E$B $B$+(B \E$@
+ $B4A;z$N=*$j(B: \E(J $B$+(B \E(B $B$+(B \E(H
+
+(2) smbclient $B$N%*%W%7%g%s(B
+
+ $B%/%i%$%"%s%H%W%m%0%i%`$G$b!"4A;z$d2>L>$r4^$s$@%U%!%$%k$r07$($k$h$&$K!"<!$N%*%W%7%g%s(B
+ $B$rDI2C$7$^$7$?!#(B
+
+ -t <$B%?!<%_%J%k%3!<%I7O(B>
+
+ $B$3$3$G!"(B<$B%?!<%_%J%k%3!<%I7O(B>$B$K;XDj$G$-$k$b$N$O!">e$N(B<$B%3!<%I7O(B>$B$HF1$8$b$N$G$9!#(B
+
+(3) $B%G%U%)%k%H(B
+
+ $B%G%U%)%k%H$N%3!<%I7O$O!"%3%s%Q%$%k;~$K7h$^$j$^$9!#(B
+
+3. $B%3%s%Q%$%k;~$N@_Dj(B
+
+ Makefile $B$K@_Dj$9$k9`L\$r0J2<$K<($7$^$9!#(B
+
+(1) KANJI $B%U%i%0(B
+
+ $B%3%s%Q%$%k%*%W%7%g%s$K(B -DKANJI=\"$B%3!<%I7O(B\" $B$r;XDj$7$^$9!#$3$N%3!<%I7O$O(B 2. $B$G;X(B
+ $BDj$9$k$b$N$HF1$8$G$9!#Nc$($P!"(B-DKANJI=\"euc\" $B$r(BFLAGSM $B$K@_Dj$9$k$H(B UNIX $B>e$N%U%!(B
+ $B%$%kL>$O!"(BEUC $B%3!<%I$K$J$j$^$9!#$3$3$G;XDj$7$?%3!<%I7O$O!"%5!<%P5Z$S%/%i%$%"%s%H(B
+ $B%W%m%0%i%`$N%G%U%)%k%H$KCM$J$j$^$9!#(B
+
+ $B>0!"%*%W%7%g%sCf$N(B \ $B$d(B " $B$bK:$l$:$K;XDj$7$F2<$5$$!#(B
+
+3. $B@)8B;v9`(B
+
+(1) $B4A;z%3!<%I(B
+ smbd $B$rF0:n$5$;$k%[%9%H$N(B UNIX $B$,%5%]!<%H$7$F$$$J$$4A;z%3!<%I$O!"MxMQ$G$-$J$$$3$H$,(B
+ $B$"$j$^$9!#JQ$JF0:n$r$9$k$h$&$J$i(B hex $B$N;XDj$r$9$k$N$,NI$$$G$7$g$&!#(B
+
+(2) smbclient $B%3%^%s%I(B
+ $B%7%U%H%3!<%I$J$I$N4X78$G!"4A;z$d2>L>$r4^$s$@%U%!%$%kL>$N(B ls $B$NI=<($,Mp$l$k$3$H$,$"$j(B
+ $B$^$9!#(B
+
+(3) $B%o%$%k%I%+!<%I$K$D$$$F(B
+ $B$A$c$s$H$7$?%9%Z%C%/$,$h$/$o$+$i$J$+$C$?$N$G$9$,!"0l1~!"(BDOS/V $B$NF0:n$HF1$8F0:n$r9T$J(B
+ $B$&$h$&$K$J$C$F$$$^$9!#(B
+
+(4) $B%m%s%0%U%!%$%kL>$K$D$$$F(B
+ Windows NT/95 $B$G$O!"%m%s%0%U%!%$%kL>$,07$($^$9!#%m%s%0%U%!%$%kL>$r(B 8.3 $B%U%)!<%^%C%H(B
+ $B$G07$&$?$a$K!"(Bmangling $B$7$F$$$^$9$,!"$3$NJ}K!$O!"(BNT $B$d(B 95 $B$,9T$J$C$F$$$k(B mangling $B$H(B
+ $B$O0[$J$j$^$9$N$GCm0U$7$F2<$5$$!#(B
+
+4. $B>c32Ey$N%l%]!<%H$K$D$$$F(B
+
+ $BF|K\8l$N%U%!%$%kL>$K4X$7$F!"J8;z2=$1Ey$N>c32$,$"$l$P!";d$K%l%]!<%H$7$FD:$1$l$P9,$$$G(B
+$B$9!#$?$@$7!"%*%j%8%J%k$+$i$NLdBjE@$d<ALd$K$D$$$F$O!"%*%j%8%J%k$N:n<T$XD>@\Ld$$9g$o$;$k(B
+$B$+!"$b$7$/$O%a!<%j%s%0%j%9%H$J$I$X%l%]!<%H$9$k$h$&$K$7$F2<$5$$!#(B
+
+$B%l%]!<%H$5$l$k>l9g!"MxMQ$5$l$F$$$k4D6-(B(UNIX $B5Z$S(B PC $BB&$N(BOS$B$J$I(B)$B$H$G$-$^$7$?$i@_Dj%U%!(B
+$B%$%k$d%m%0$J$I$rE:IU$7$FD:$1$k$H9,$$$G$9!#(B
+
+5. $B$=$NB>(B
+
+ $B%3!<%IJQ49$O0J2<$NJ}!9$,:n$i$l$?%W%m%0%i%`$rMxMQ$7$F$$$^$9!#(B
+
+ hex $B7A<0(B $BBgLZ!wBgDM!&C^GH(B <ohki@gssm.otsuka.tsukuba.ac.jp>$B;a(B
+ cap $B7A<0(B $BI%ED(B $BF;O:(B (michiro@po.iijnet.or.jp)(michiro@dms.toppan.co.jp)$B;a(B
+
+ $B$=$NB>!"$?$/$5$s$NJ}!9$+$i$$$m$$$m$H8f65<($$$?$@$-$"$j$,$H$&$4$6$$$^$7$?!#:#8e$H$b$h(B
+$B$m$7$/$*4j$$CW$7$^$9!#(B
+
+1994$BG/(B10$B7n(B28$BF|(B $BBh#1HG(B
+1995$BG/(B 8$B7n(B16$BF|(B $BBh#2HG(B
+1995$BG/(B11$B7n(B24$BF|(B $BBh#3HG(B
+1996$BG/(B 5$B7n(B13$BF|(B $BBh#4HG(B
+
+$BF#ED(B $B?r(B fujita@ainix.isac.co.jp
+
diff --git a/docs/textdocs/README.sambatar b/docs/textdocs/README.sambatar
new file mode 100755
index 00000000000..af7250c2a49
--- /dev/null
+++ b/docs/textdocs/README.sambatar
@@ -0,0 +1,23 @@
+Contributor/s: Martin.Kraemer <Martin.Kraemer@mch.sni.de>
+ and Ricky Poulten (ricky@logcam.co.uk)
+Date: Unknown - circa 1994
+Status: Obsoleted - smbtar has been a stable part of Samba
+ since samba-1.9.13
+
+Subject: Sambatar (now smbtar)
+=============================================================================
+
+This is version 1.4 of my small extension to samba that allows PC shares
+to be backed up directly to a UNIX tape. It only has been tested under
+Solaris 2.3, Linux 1.1.59 and DG/UX 5.4r3.10 with version 1.9.13 of samba.
+
+See the file INSTALL for installation instructions, and
+the man page and NOTES file for some basic usage. Please let me know if you
+have any problems getting it to work under your flavour of Unix.
+
+This is only (yet another) intermediate version of sambatar.
+This version also comes with an extra gift, zen.bas, written in
+microsoft qbasic by a colleague. It is (apparently) based on a 70s
+British sci-fi series known as Blake's 7. If you have any questions
+about this program, or any suggestions (e.g. what about servillan.bas
+?), feel free to mail the author (of zen.bas) greenm@lilhd.logica.com.
diff --git a/docs/textdocs/Recent-FAQs.txt b/docs/textdocs/Recent-FAQs.txt
new file mode 100755
index 00000000000..6e614abed1a
--- /dev/null
+++ b/docs/textdocs/Recent-FAQs.txt
@@ -0,0 +1,289 @@
+!==
+!== Recent-FAQs.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Samba-bugs@samba.org
+Date: July 5, 1998
+Status: Current
+
+=============================================================================
+Subject: Recent FAQ answers to common questions / problems
+=============================================================================
+Contents: NetWkstaUserLogon
+ Not listening for calling name
+ System Error 1240
+ Trapdoor UID
+ User Access Control
+ Using NT to Browse Samba Shares
+ setup.exe and 16 bit programs
+ smbclient -N
+
+NetWkstaUserLogon
+=================
+FAQ answer about the new password server code:
+
+In 1.9.18 you can disable the NetWkstaUserLogon call at compile time
+in local.h and from 1.9.18p3 you can now disable it from an option in
+your smb.conf.
+
+The password server behaviour changed because we discovered that bugs
+in some NT servers allowed anyone to login with no password if they
+chose an account name that did not exist on the password server. The
+NT password server was saying "yes, it's OK to login" even when the
+account didn't exist at all! Adding the NetWkstaUserLogon call fixed
+the problem, and follows the "recommended" method that MS have
+recently documented for pass through authentication.
+
+The problem now is that some NT servers (in particular NT
+workstation?) don't support the NetWkstaUserLogon call. The call also
+doesn't work for accounts in trust relationships.
+
+The eventual solution for this will be to replace the password server
+code in Samba with NT domain code as that is developed. For now you
+have the choice of compiling Samba either with or without the
+NetWkstaUserLogon call in the password server code.
+
+In 1.9.18p3 the following was added (copied from the 1.9.18p3 release
+notes):
+
+In the [global] section of smb.conf :
+
+networkstation user login
+
+This code (submitted by Rob Nielsen) allows the code many people
+were having problems with that queries an NT password server to
+be turned off at runtime rather than compile time. Please see the
+documentation in the smb.conf manual page for details. This is a
+security option - it must only be turned off after checks have been
+made to ensure that your NT password server does not suffer from the
+bug this code was meant to protect against !
+
+In 1.9.18 you can enable/disable this call in local.h. In 1.9.17p5
+you could apply the following patch. Applying this patch will make
+the password server code behave like the code in earlier versions
+of Samba. If you do this then please ensure that you test to see
+that users are prevented from logging in if they give a bogus
+username/password. You may have a NT server that is affected by the
+bug that this code is designed to avoid.
+
+
+--- password.c 1997/10/21 10:09:28 1.25.2.4
++++ password.c 1997/12/31 06:43:06
+@@ -1619,6 +1619,7 @@
+ }
+
+
++#if 0
+ if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) {
+ DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost));
+ cli_tdis(&cli);
+@@ -1638,6 +1639,7 @@
+ cli_tdis(&cli);
+ return False;
+ }
++#endif
+
+ DEBUG(3,("password server %s accepted the password\n", cli.desthost));
+===============================================================================
+
+Not listening for calling name
+==============================
+
+> Session request failed (131,129) with myname=HOBBES destname=CALVIN
+> Not listening for calling name
+
+If you get this when talking to a Samba box then it means that your
+global "hosts allow" or "hosts deny" settings are causing the Samba
+server to refuse the connection.
+
+Look carefully at your "hosts allow" and "hosts deny" lines in the
+global section of smb.conf.
+
+It can also be a problem with reverse DNS lookups not functioning
+correctly, leading to the remote host identity not being able to
+be confirmed, but that is less likely.
+===============================================================================
+
+System Error 1240
+=================
+System error 1240 means that the client is refusing to talk
+to a non-encrypting server. Microsoft changed WinNT in service
+pack 3 to refuse to connect to servers that do not support
+SMB password encryption.
+
+There are two main solutions:
+
+1) enable SMB password encryption in Samba. See ENCRYPTION.txt in the
+Samba docs
+
+2) disable this new behaviour in NT. See WinNT.txt in the
+Samba docs
+===============================================================================
+
+Trapdoor UID
+============
+> Log message "you appear to have a trapdoor uid system"
+
+This can have several causes. It might be because you are using a uid
+or gid of 65535 or -1. This is a VERY bad idea, and is a big security
+hole. Check carefully in your /etc/passwd file and make sure that no
+user has uid 65535 or -1. Especially check the "nobody" user, as many
+broken systems are shipped with nobody setup with a uid of 65535.
+
+It might also mean that your OS has a trapdoor uid/gid system :-)
+
+This means that once a process changes effective uid from root to
+another user it can't go back to root. Unfortunately Samba relies on
+being able to change effective uid from root to non-root and back
+again to implement its security policy. If your OS has a trapdoor uid
+system this won't work, and several things in Samba may break. Less
+things will break if you use user or server level security instead of
+the default share level security, but you may still strike
+problems.
+
+The problems don't give rise to any security holes, so don't panic,
+but it does mean some of Samba's capabilities will be unavailable.
+In particular you will not be able to connect to the Samba server as
+two different uids at once. This may happen if you try to print as a
+"guest" while accessing a share as a normal user. It may also affect
+your ability to list the available shares as this is normally done as
+the guest user.
+
+Complain to your OS vendor and ask them to fix their system.
+
+Note: the reason why 65535 is a VERY bad choice of uid and gid is that
+it casts to -1 as a uid, and the setreuid() system call ignores (with
+no error) uid changes to -1. This means any daemon attempting to run
+as uid 65535 will actually run as root. This is not good!
+===============================================================================
+
+User Access Control
+===================
+> In windows when i set up a share in "user mode" i get the message:
+> "You cannot view the list of users at this time. Please try again later."
+>
+> I know you have lists of users for access and aliasing purposes, but i
+> have read nothing to support the idea that these lists control the Domain
+> Users List...
+
+Samba does NOT at this time support user mode access control for Window 9x
+of for NT. This is a priority item and requires full implementation of the NT SMB
+protocol calls. Samba-1.9.19 will go into alpha in about 2 months time and will
+have a more full implementation of the NT SMB protocols to support Domain Client
+interoperability. When we can see that this has been succesful we wil then implement
+the NT SMB Server components. This will probably be released as Samba-2.0
+
+Samba-1.9.18p5 is scheduled to go out within 14 days. This will close off the 1.9.18
+branch and then opens the way to progress 1.9.19.
+
+I hope this answers your concerns adequately.
+===============================================================================
+
+Using NT to Browse Samba Shares
+===============================
+> WIN-NT workstations (nt4.0, service pack 3)
+> samba with
+> security = user
+> encrypt passwords = yes
+> guest account = guest
+>
+> start the explorer on a win-nt workstation and select network. I find
+> my unix server running samba, but I can not see the list of shares
+> unless I am a user, who is known in the smbpasswd of the unix machine.
+> The guest account "guest" exists on my unix machine. For testing I even
+> made him a regular user with a password.
+>
+> With my network monitor I can see, that the win-nt workstation uses the
+> current login, to connect to IPC$ on the samba server
+> (for example "administrator"), not the guest account.
+
+This is exactly how Windows NT works. You MUST have a valid account on the Windows
+NT box you are trying to see the resource list on. If your currently logged in
+account details do NOT match an account on the NT machine you are trying to access
+then you will be presented with a logon box for that machine. When you enter the
+name of an account on that machine / domain, together with a valid password then
+the resource list is made available. If the account details are not correct then
+no resource list is shown.
+
+Samba follows the behaviour of Windows NT exactly.
+
+Warning:Warning:Warning:
+========================
+Samba can be compiled with the GUEST_SESSION_SETUP option at 0,1 or 2.
+The default is 0. If this is set to 1 or 2 then Windows NT machines that DO NOT
+have an account on the Samba server will see the resource list. The down side of this
+is that legitimate users may then be refused access to their legitimate resources.
+Setting this option creates serious security holes. DO NOT DO IT. Samba has the
+value of this option set at 0 - NOT WITHOUT REASON!!!!
+
+******> Warning:Warning:Warning: ****> Do not tamper with this setting!!!
+===============================================================================
+
+setup.exe and 16 bit programs
+=============================
+Running 16 bit programs from Windows NT on a Samba mapped drive
+---------------------------------------------------------------
+
+The Windows NT redirector has a bug when running against a
+Samba or Windows 95 mapped drive and attempting to run a
+16 bit executable.
+
+The problem occurs when the pathname to a 16 bit executable
+contains a non 8.3 filename complient directory component,
+Windows NT will fail to load the program and complain it
+cannot find the path to the program.
+
+It can be verified that this is a bug in Windows NT and
+not Samba as the same problem can be reproduced exactly
+when attempting to run the same program with the same
+pathname from a Windows 95 server (ie. the problem still
+exists even with no Samba server involved).
+
+Microsoft have been made aware of this problem, it is
+unknown if they regard it as serious enough to provide
+a fix for this.
+
+One of the reasons this problem is reported frequently
+is that InstallShield setup.exe executables are frequently
+written as 16 bit programs, and so hit this problem.
+
+As a workaround, you may create (on a Samba server at
+least) a symbolic link with an 8.3 complient name to
+the non 8.3 complient directory name, and then the 16
+bit program will run. Alternatively, use the 8.3
+complient mangled name to specify the path to run
+the binary.
+
+This will be fixed when Samba adds the NT-specific
+SMB calls (currently targeted for the next major
+Samba release), as once the NT SMB calls are used
+this problem no longer occurs (which is why the
+problem doesn't occur when running against a drive
+mapped to a Windows NT server).
+
+Regards,
+
+ Jeremy Allison.
+ Samba Team.
+===============================================================================
+
+smbclient -N
+============
+> When getting the list of shares available on a host using the command
+> smbclient -N -L <server>
+> the program always prompts for the password if the server is a Samba server.
+> It also ignores the "-N" argument when querying some (but not all) of our
+> NT servers.
+
+No, it does not ignore -N, it is just that your server rejected the
+null password in the connection, so smbclient prompts for a password
+to try again.
+
+To get the behaviour that you probably want use
+ smbclient -L host -U%
+
+this will set both the username and password to null, which is
+an anonymous login for SMB. Using -N would only set the password
+to null, and this is not accepted as an anonymous login for most
+SMB servers.
+===============================================================================
+
diff --git a/docs/textdocs/RoutedNetworks.txt b/docs/textdocs/RoutedNetworks.txt
new file mode 100755
index 00000000000..aea9fd77db7
--- /dev/null
+++ b/docs/textdocs/RoutedNetworks.txt
@@ -0,0 +1,66 @@
+!==
+!== RoutedNetworks.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+#NOFNR Flag in LMHosts to Communicate Across Routers
+
+ Last reviewed: May 5, 1997
+ Article ID: Q103765
+ The information in this article applies to:
+
+ Microsoft Windows NT operating system version 3.1
+ Microsoft Windows NT Advanced Server version 3.1
+
+ SUMMARY
+
+ Some of the LAN Manager for UNIX and Pathworks servers may have
+problems in communicating across routers with
+ Windows NT workstations. The use of #NOFNR flag in the LMHosts
+file solves the problem.
+
+ MORE INFORMATION
+
+ When you are communicating with a server across a router in a IP
+routed environment, the LMHosts file is used to
+ resolve Workstation name-to-IP address mapping. The LMHosts
+entry for a remote machine name provides the IP
+ address for the remote machine. In Lan Manager 2.x, providing
+the LMHosts entry eliminates the need to do a Name
+ Query broadcast to the local domain and instead a TCP session is
+established with the remote machine. Windows NT
+ performs the same function in a different way.
+
+ When an LMHosts entry exists for a remote server, Windows NT
+will not send a Name Query broadcast to the local
+ subnet and instead send a directed Name Query to the remote
+server. If the remote server does not respond to the Name
+ Query, further communications (TCP SYN, and so on) will not take
+place. This was done to eliminate the performance
+ issues when trying to connect to a remote machine when it was
+not available (down).
+
+ Some of the older LAN Manager for UNIX and DEC Pathworks servers
+do not respond to directed Name Queries sent
+ by Windows NT. In that case, the users will see an error 53
+(Path not found), even though they have specified the
+ LMHosts entries correctly. A new LMHosts flag #NOFNR was added
+to solve this problem. By specifying the
+ #NOFNR flag on the same line where the name resolution
+information for the server is provided, the directed Name
+ Query can be avoided. For example:
+
+ 130.20.1.1 mylmxserver #PRE #NOFNR
+
+
+ Note that this will only apply to mylmxserver and not to any
+other entries in the LMHosts file. To set
+ a global flag, an entry could be added in the registry. To
+completely remove any directed Name
+ Queries sent from a Windows NT machine, create the following
+value in
+
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Nbt\Parameters:
+
+ NoDirectedFNR REG_DWORD 1
+
+
+ This will cause the directed Name Queries to not go out for any
diff --git a/docs/textdocs/SCO.txt b/docs/textdocs/SCO.txt
new file mode 100755
index 00000000000..9d10d6b233e
--- /dev/null
+++ b/docs/textdocs/SCO.txt
@@ -0,0 +1,22 @@
+!==
+!== SCO.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Geza Makay <makayg@math.u-szeged.hu>
+Date: Unknown
+Status: Obsolete - Dates to SCO Unix v3.2.4 approx.
+
+Subject: TCP/IP Bug in SCO Unix
+============================================================================
+
+There is an annoying TCPIP bug in SCO Unix. This causes corruption when
+transferring files with Samba.
+
+Geza Makay (makayg@math.u-szeged.hu) sends this information:
+
+The patch you need is UOD385 Connection Drivers SLS. It is available from
+SCO (ftp.sco.com, directory SLS, files uod385a.Z and uod385a.ltr.Z).
+
+You do not need anything else but the above patch. It installs in seconds,
+and corrected the Excel problem. We also had some other minor problems (not
+only with Samba) that disappeared by installing this patch.
+
diff --git a/docs/textdocs/SMBTAR.notes b/docs/textdocs/SMBTAR.notes
new file mode 100755
index 00000000000..679d776f56c
--- /dev/null
+++ b/docs/textdocs/SMBTAR.notes
@@ -0,0 +1,46 @@
+Contributor: Unknown
+Date: 1994
+Status: Mostly Current - refer man page
+
+Subject: Smbtar
+============================================================================
+
+Intro
+-----
+
+sambatar is just a small extension to the smbclient program distributed with
+samba. A basic front end shell script, smbtar, is provided as an interface
+to the smbclient extensions.
+
+Extensions
+----------
+
+This release adds the following extensions to smbclient,
+
+tar [c|x] filename
+ creates or restores from a tar file. The tar file may be a tape
+or a unix tar file. tar's behaviour is modified with the newer and tarmode
+commands.
+
+tarmode [full|inc|reset|noreset]
+ With no arguments, tarmode prints the current tar mode (by default full,
+noreset). In full mode, every file is backed up during a tar command.
+In incremental, only files with the dos archive bit set are backed up.
+The archive bit is reset if in reset mode, or left untouched if in noreset.
+In reset mode, the share has to be writable, which makes sambatar even
+less secure. An alternative might be to use tarmode inc noreset which
+would implement an "expanding incremental" backup (which some may prefer
+anyway).
+
+setmode <setmode string> filename
+ This is a "freebie" - nothing really to do with sambatar. This
+is a crude attrib like command (only the other way around). Setmode string
+is a combination of +-rhsa. So for example -rh would reset the read only
+bit on filename.
+
+newer filename
+ This is in fact part of the 1.9.13 samba distribution, but comes
+into its own with sambatar. This causes tar (or get, mget, etc) to
+only copy files newer than the specified file name. Could be used
+against the previous nights (or whatever) log file to implement incremental
+backups.
diff --git a/docs/textdocs/Samba-OpenSSL.txt b/docs/textdocs/Samba-OpenSSL.txt
new file mode 100755
index 00000000000..44a5fee96e2
--- /dev/null
+++ b/docs/textdocs/Samba-OpenSSL.txt
@@ -0,0 +1,408 @@
+!==
+!== SSLeay.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Christian Starkjohann <cs@obdev.at>
+Date: May 29, 1998
+Status:
+
+Comment: Updated by Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>
+Date: July 16, 2001
+
+Subject: Compiling and using samba with SSL support
+============================================================================
+
+What is SSL and SSLeay/OpenSSL?
+===============================
+SSL (Secure Socket Layer) is a protocol for encrypted and authenticated data
+transport. It is used by secure web servers for shopping malls, telebanking
+and things like that.
+
+SSLeay is a free implementation of the SSL protocol. The successor of it is
+OpenSSL, available from
+
+ http://www.openssl.org/
+
+The current version while these lines are written is 0.9.6b. In some countries
+encryption is plagued by legal problems, even though things have relaxed a
+lot in the last years.
+
+To compile samba with SSL support, you must first compile and install OpenSSL.
+At least version 0.9.5 of OpenSSL is required. Version 0.9.6b is the latest
+version and is strongly recommended.
+OpenSSL consists of a library (which can be linked to other applications like
+samba) and several utility programs needed for key generation, certification
+etc. OpenSSL installs to /usr/local/ssl/ by default.
+
+
+Compiling samba with OpenSSL
+============================
+1. Get and install OpenSSL. The rest of this documentation assumes that you
+ have installed it at the default location, which is /usr/local/ssl/.
+2. Call "configure" with the "--with-ssl" flag. If OpenSSL is not installed in
+ the default directory, you can use the "--with-sslinc" and "--with-ssllib"
+ flags to specify the location.
+3. Compile and install as usual.
+
+
+Configuring SSL in samba
+========================
+Before you configure SSL, you should know the basics of cryptography and how
+SSL relates to all of this. A basic introduction can be found further down in
+this document. The following variables in the "[global]" section of the
+configuration file are used to configure SSL:
+
+ssl = yes
+ This variable enables or disables the entire SSL mode. If it is set to
+ "no", the SSL enabled samba behaves exactly like the non-SSL samba. If set
+ to "yes", it depends on the variables "ssl hosts" and "ssl hosts resign"
+ whether an SSL connection will be required.
+ssl hosts =
+ssl hosts resign = 192.168.
+ These two variables define whether samba will go into SSL mode or not. If
+ none of them is defined, samba will allow only SSL connections. If the
+ "ssl hosts" variable lists hosts (by IP-address, IP-address range, net
+ group or name), only these hosts will be forced into SSL mode. If the
+ "ssl hosts resign" variable lists hosts, only these hosts will NOT be
+ forced into SSL mode. The syntax for these two variables is the same as
+ for the "hosts allow" and "hosts deny" pair of variables, only that the
+ subject of the decision is different: It's not the access right but
+ whether SSL is used or not. See the man page of smb.conf (section about
+ "allow hosts") for details. The above example requires SSL connections
+ from all hosts outside the local net (which is 192.168.*.*).
+ssl CA certDir = /usr/local/ssl/certs
+ This variable defines where to look up the Certification Autorities. The
+ given directory should contain one file for each CA that samba will trust.
+ The file name must be the hash value over the "Distinguished Name" of the
+ CA. How this directory is set up is explained later in this document. All
+ files within the directory that don't fit into this naming scheme are
+ ignored. You don't need this variable if you don't verify client
+ certificates.
+ssl CA certFile = /usr/local/ssl/certs/trustedCAs.pem
+ This variable is a second way to define the trusted CAs. The certificates
+ of the trusted CAs are collected in one big file and this variable points
+ to the file. You will probably only use one of the two ways to define your
+ CAs. The first choice is preferable if you have many CAs or want to be
+ flexible, the second is perferable if you only have one CA and want to
+ keep things simple (you won't need to create the hashed file names). You
+ don't need this variable if you don't verify client certificates.
+ssl server cert = /usr/local/ssl/certs/samba.pem
+ This is the file containing the server's certificate. The server _must_
+ have a certificate. The file may also contain the server's private key.
+ See later for how certificates and private keys are created.
+ssl server key = /usr/local/ssl/private/samba.pem
+ This file contains the private key of the server. If this variable is not
+ defined, the key is looked up in the certificate file (it may be appended
+ to the certificate). The server _must_ have a private key and the
+ certificate _must_ match this private key.
+ssl client cert = /usr/local/ssl/certs/smbclient.pem
+ The certificate in this file is used by smbclient if it exists. It's needed
+ if the server requires a client certificate.
+ssl client key = /usr/local/ssl/private/smbclient.pem
+ This is the private key for smbclient. It's only needed if the client
+ should have a certificate.
+ssl require clientcert = yes
+ If this variable is set to "yes", the server will not tolerate connections
+ from clients that don't have a valid certificate. The directory/file
+ given in "ssl CA certDir" and "ssl CA certFile" will be used to look up
+ the CAs that issued the client's certificate. If the certificate can't be
+ verified positively, the connection will be terminated.
+ If this variable is set to "no", clients don't need certificates. Contrary
+ to web applications you really _should_ require client certificates. In
+ the web environment the client's data is sensitive (credit card numbers)
+ and the server must prove to be trustworthy. In a file server environment
+ the server's data will be sensitive and the clients must prove to be
+ trustworthy.
+ssl require servercert = yes
+ If this variable is set to "yes", the smbclient will request a certificate
+ from the server. Same as "ssl require clientcert" for the server.
+ssl ciphers = ???
+ This variable defines the ciphers that should be offered during SSL
+ negotiation. You should not set this variable unless you know what you do.
+ssl version = ssl2or3
+ This enumeration variable defines the versions of the SSL protocol that
+ will be used. "ssl2or3" allows dynamic negotiation of SSL v2 or v3, "ssl2"
+ results SSL v2, "ssl3" results in SSL v3 and "tls1" results in TLS v1. TLS
+ (Transport Layer Security) is the (proposed?) new standard for SSL. The
+ default value is "ssl2or3".
+ssl compatibility = no
+ This variable defines whether SSLeay should be configured for bug
+ compatibility with other SSL implementations. This is probably not
+ desirable because currently no clients with SSL implementations other than
+ SSLeay exist.
+ssl entropy file =
+ Specifies a file from which processes will read "random bytes" on startup.
+ In order to seed the internal pseudo random number generator, entropy
+ must be provided. On system with a /dev/urandom device file, the processes
+ will retrieve its entropy from the kernel. On systems without kernel
+ entropy support, a file can be supplied that will be read on startup
+ and that will be used to seed the PRNG.
+ssl entropy bytes = 256
+ Number of bytes that will be read from entropy file. If -1 is given, the
+ complete file will be read.
+ssl egd socket =
+ Location of the communiation socket of an EGD or PRNGD daemon, from which
+ entropy can be retrieved. This option can be used instead of or together
+ with the "ssl entropy file" directive. 255bytes of entropy will be
+ retrieved from the daemon.
+
+
+Running samba with OpenSSL
+==========================
+Samba is started as usual. The daemon will ask for the private key's pass
+phrase before it goes to background if the private key has been encrypted.
+If you start smbd from inetd, this won't work. Therefore you must not encrypt
+your private key if you run smbd from inetd.
+
+Windows clients will try to connect to the SSL enabled samba daemon and they
+will fail. This can fill your log with failed SSL negotiation messages. To
+avoid this, you can either not run nmbd (if all clients use DNS to look up
+the server), which will leave the Windows machine unaware of the server, or
+list all (local) Windows machines in the "ssl hosts resign" variable.
+
+
+About certificates
+==================
+Secure samba servers will not be set up for public use as it is the case with
+secure web servers. Most installations will probably use it for distributed
+offices that use parts of the internet for their intranet, for access to a
+web server that's physically hosted by the provider or simply for teleworking.
+All these applications work with a known group of users that can easily agree
+on a certification authority. The CA can be operated by the company and the
+policy for issuing certificates can be determined by the company. If samba is
+configured to verify client certificates, it (currently) only verifies
+whether a valid certificate exists. It does not verify any of the data within
+the certificate (although it prints some of the data to the log file).
+
+
+Which clients are available that support SSL?
+=============================================
+Currently there are only smbclient which is part of the samba package and
+Sharity. Shariy versions newer than 0.14 in the beta branch and 1.01 in the
+main branch can be compiled with SSLeay. Sharity is a CIFS/SMB client
+implementation for Unix. It is a commercial product, but it is available in
+source code and the demo-mode allows access to the first three layers of the
+mounted directory hierarchy. Licenses for universities and students are free.
+Sharity is available at
+
+ http://www.obdev.at/Products/Sharity.html
+
+
+
+###########################################################################
+Basics about Cryptography and SSL(eay)
+###########################################################################
+
+There are many good introductions to cryptography. I assume that the reader
+is familiar with the words "encryption", "digital signature" and RSA. If you
+don't know these terms, please read the cryptography FAQ part 6 and 7, which
+is posted to the usenet newsgroup sci.crypt. It is also available from
+
+ ftp://rtfm.mit.edu/pub/usenet/news.answers/cryptography-faq
+and
+ http://www.cis.ohio-state.edu/hypertext/faq/usenet/cryptography-faq
+
+I'll concentrate on the questions specific to SSL and samba here.
+
+
+What is a certificate?
+======================
+A certificate is issued by an issuer, usually a "Certification Authority"
+(CA), who confirms something by issuing the certificate. The subject of this
+confirmation depends on the CA's policy. CAs for secure web servers (used for
+shopping malls etc.) usually only attest that the given public key belongs the
+the given domain name. Company-wide CAs might attest that you are an employee
+of the company, that you have permissions to use a server or whatever.
+
+
+What is an X.509 certificate technically?
+=========================================
+Technically, the certificate is a block of data signed by the certificate
+issuer (the CA). The relevant fields are:
+ - unique identifier (name) of the certificate issuer
+ - time range during that the certificate is valid
+ - unique identifier (name) of the certified subject
+ - public key of the certified subject
+ - the issuer's signature over all of the above
+If this certificate should be verified, the verifier must have a table of the
+names and public keys of trusted CAs. For simplicity, these tables are lists
+of certificates issued by the respective CAs for themselves (self-signed
+certificates).
+
+
+What are the implications of this certificate structure?
+========================================================
+ - Because the certificate contains the subject's public key, the
+ certificate and the private key together are all that's needed to encrypt
+ and decrypt.
+ - To verify certificates, you need the certificates of all CAs you trust.
+ - The simplest form of a dummy-certificate is one that's signed by the
+ subject itself.
+ - A CA is needed. The client can't simply issue local certificates for
+ servers it trusts because the server determines which certificate it
+ presents.
+
+
+
+###########################################################################
+Setting up files and directories for OpenSSL
+###########################################################################
+
+The first thing you should do is to change your PATH environment variable to
+include the bin directory of OpenSSL. E.g.:
+
+ PATH=$PATH:/usr/local/ssl/bin
+
+If your system's kernel supports a /dev/urandom device, all OpenSSL operations
+will automatically retrieve its entropy from it. If your system does not
+support /dev/urandom, you may install an EGD/PRNGD daemon for entropy
+supply or can generate seed from reading files (that should contain information
+unpredictable/unknown to attackers). Use the "-rand" option to the openssl
+commands to specify the entropy source (if /dev/urandom is not available).
+
+OpenSSL additionally keeps random seed in the $HOME/.rnd file. You can
+initialize this file using:
+
+ openssl rand -rand /tmp/rfile.txt > $HOME/.rnd
+ rm -f /tmp/rfile.txt # nobody must know!!
+
+or
+
+ openssl rand -rand /path/to/egd-socket > $HOME/.rnd
+
+How to create a keypair
+=======================
+This is done with 'genrsa' for RSA keys and 'gendsa' for DSA keys. For an RSA
+key with 1024 bits which is written to the file "key.pem" type:
+
+ openssl genrsa -des3 -rand /path/to/source 1024 > key.pem
+
+You will be asked for a pass phrase to protect this key. If you don't want to
+protect your private key with a pass phrase, just omit the parameter "-des3".
+If you want a different key size, replace the parameter "1024". You really
+should use a pass phrase.
+
+If you want to remove the pass phrase from a key use:
+
+ openssl rsa -in key.pem -out newkey.pem
+
+And to add or change a pass phrase:
+
+ openssl rsa -des3 -in key.pem -out newkey.pem
+
+
+How to create a dummy certificate
+=================================
+If you still have your keypair in the file "key.pem", the command
+
+ openssl req -new -x509 -key key.pem -out cert.pem
+
+will write a self-signed dummy certificate to the file "cert.pem". This can
+be used for testing or if only encryption and no certification is needed.
+Please bear in mind that encryption without authentication (certification)
+can never be secure. It's open to (at least) "man-in-the-middle" attacks.
+
+
+How to create a certificate signing request
+===========================================
+You must not simply send your keypair to the CA for signing because it
+contains the private key which _must_ be kept secret. A signing request
+consists of your public key and some additional information you want to have
+bound to that key by the certificate. If you operate a secure web server,
+this additional information will (among other things) contain the URL of
+your server in the field "Common Name". The certificate signing request is
+created from the keypair with the following command (assuming that the key
+pair is still in "key.pem"):
+
+ openssl req -new -key key.pem -out csr.pem
+
+This command will ask you for the information which must be included in the
+certificate and will write the signing request to the file "csr.pem". This
+signing request is all the CA needs for signing, at least technically. Most
+CAs will demand bureaucratic material and money, too.
+
+
+How to set up a Certification Authority (CA)
+============================================
+Being a certification authority requires a database that holds the CA's
+keypair, the CA's certificate, a list of all signed certificates and other
+information. This database is kept in a directory hierarchy below a
+configurable starting point. The starting point must be configured in the
+ssleay.conf file. This file is at /usr/local/ssl/lib/ssleay.conf if you have
+not changed the default installation path.
+
+The first thing you should do is to edit this file according to your needs.
+Let's assume that you want to hold the CA's database at the directory
+"/usr/local/ssl/CA". Change the variable "dir" in section "CA_default" to
+this path. You may also want to edit the default settings for some variables,
+but the values given should be OK. This path is also contained in the shell
+script CA.sh, which should be at "/usr/local/ssl/bin/CA.sh". Change the path
+in the shell script:
+
+ CATOP=/usr/local/ssl/CA
+ CAKEY=./cakey.pem # relative to $CATOP/
+ CACERT=./cacert.pem # relative to $CATOP/private/
+
+Then create the directory "/usr/local/ssl/CA" and make it writable for the
+user that operates the CA. You should also initialize SSLeay as CA user (set
+up the random number generator). Now you should call the shell script CA.sh
+to set up the initial database:
+
+ CA.sh -newca
+
+This command will ask you whether you want to use an existing certificate or
+create one. Just press enter to create a new key pair and certificate. You
+will be asked the usual questions for certificates: the country, state, city,
+"Common Name", etc. Enter the appropriate values for the CA. When CA.sh
+finishes, it has set up a bunch of directories and files. A CA must publish
+it's certificate, which is in the file "/usr/local/ssl/CA/cacert.pem".
+
+
+How to sign a certificate request
+=================================
+After setting up the CA stuff, you can start signing certificate requests.
+Make sure that the SSLeay utilities know where the configuration file is.
+The default is compiled in, if you don't use the default location, add the
+parameter "-config <cfg-file>". Make also sure that the configuration file
+contains the correct path to the CA database. If all this is set up properly,
+you can sign the request in the file "csr.pem" with the command:
+
+ openssl ca -policy policy_anything -days 365 -infiles csr.pem >cert.pem
+
+The resulting certificate (and additional information) will be in "cert.pem".
+If you want the certificate to be valid for a period different from 365 days,
+simply change the "-days" parameter.
+
+
+How to install a new CA certificate
+===================================
+Whereever a certificate must be checked, the CA's certificate must be
+available. Let's take the common case where the client verifies the server's
+certificate. The case where the server verfies the client's certificate works
+the same way. The client receives the server's certificate, which contains
+the "Distinguished Name" of the CA. To verify whether the signature in this
+certificate is OK, it must look up the public key of that CA. Therefore each
+client must hold a database of CAs, indexed by CA name. This database is best
+kept in a directory where each file contains the certificate of one CA and is
+named after the hashvalue (checksum) of the CA's name. This section describes
+how such a database is managed technically. Whether or not to install (and
+thereby trust) a CA is a totally different matter.
+
+The client must know the directory of the CA database. This can be configured.
+There may also be a configuration option to set up a CA database file which
+contains all CA certs in one file. Let's assume that the CA database is kept
+in the directory "/usr/local/ssl/certs". The following example assumes that
+the CA's certificate is in the file "cacert.pem" and the CA is known as
+"myCA". To install the certificate, do the following:
+
+ cp cacert.pem /usr/local/ssl/cers/myCA.pem
+ cd /usr/local/ssl/certs
+ ln -s myCA.pem `openssl x509 -noout -hash < myCA.pem`.0
+
+The last command creates a link from the hashed name to the real file.
+
+From now on all certificates signed by the myCA authority will be accepted by
+clients that use the directory "/usr/local/ssl/certs/" as their CA certificate
+database.
+
+
+
diff --git a/docs/textdocs/Speed.txt b/docs/textdocs/Speed.txt
new file mode 100755
index 00000000000..325376ac250
--- /dev/null
+++ b/docs/textdocs/Speed.txt
@@ -0,0 +1,341 @@
+!==
+!== Speed.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+
+Subject: Samba performance issues
+============================================================================
+
+This file tries to outline the ways to improve the speed of a Samba server.
+
+COMPARISONS
+-----------
+
+The Samba server uses TCP to talk to the client. Thus if you are
+trying to see if it performs well you should really compare it to
+programs that use the same protocol. The most readily available
+programs for file transfer that use TCP are ftp or another TCP based
+SMB server.
+
+If you want to test against something like a NT or WfWg server then
+you will have to disable all but TCP on either the client or
+server. Otherwise you may well be using a totally different protocol
+(such as Netbeui) and comparisons may not be valid.
+
+Generally you should find that Samba performs similarly to ftp at raw
+transfer speed. It should perform quite a bit faster than NFS,
+although this very much depends on your system.
+
+Several people have done comparisons between Samba and Novell, NFS or
+WinNT. In some cases Samba performed the best, in others the worst. I
+suspect the biggest factor is not Samba vs some other system but the
+hardware and drivers used on the various systems. Given similar
+hardware Samba should certainly be competitive in speed with other
+systems.
+
+
+OPLOCKS
+-------
+
+Oplocks are the way that SMB clients get permission from a server to
+locally cache file operations. If a server grants an oplock
+(opportunistic lock) then the client is free to assume that it is the
+only one accessing the file and it will agressively cache file
+data. With some oplock types the client may even cache file open/close
+operations. This can give enormous performance benefits.
+
+With the release of Samba 1.9.18 we now correctly support opportunistic
+locks. This is turned on by default, and can be turned off on a share-
+by-share basis by setting the parameter :
+
+oplocks = False
+
+We recommend that you leave oplocks on however, as current benchmark
+tests with NetBench seem to give approximately a 30% improvement in
+speed with them on. This is on average however, and the actual
+improvement seen can be orders of magnitude greater, depending on
+what the client redirector is doing.
+
+Previous to Samba 1.9.18 there was a 'fake oplocks' option. This
+option has been left in the code for backwards compatibility reasons
+but it's use is now deprecated. A short summary of what the old
+code did follows.
+
+LEVEL2 OPLOCKS
+--------------
+
+With Samba 2.0.5 a new capability - level2 (read only) oplocks is
+supported (although the option is off by default - see the smb.conf
+man page for details). Turning on level2 oplocks (on a share-by-share basis)
+by setting the parameter :
+
+level2 oplocks = true
+
+should speed concurrent access to files that are not commonly written
+to, such as application serving shares (ie. shares that contain common
+.EXE files - such as a Microsoft Office share) as it allows clients to
+read-ahread cache copies of these files.
+
+Old 'fake oplocks' option - deprecated.
+---------------------------------------
+
+Samba can also fake oplocks, by granting a oplock whenever a client
+asks for one. This is controlled using the smb.conf option "fake
+oplocks". If you set "fake oplocks = yes" then you are telling the
+client that it may agressively cache the file data for all opens.
+
+Enabling 'fake oplocks' on all read-only shares or shares that you know
+will only be accessed from one client at a time you will see a big
+performance improvement on many operations. If you enable this option
+on shares where multiple clients may be accessing the files read-write
+at the same time you can get data corruption.
+
+SOCKET OPTIONS
+--------------
+
+There are a number of socket options that can greatly affect the
+performance of a TCP based server like Samba.
+
+The socket options that Samba uses are settable both on the command
+line with the -O option, or in the smb.conf file.
+
+The "socket options" section of the smb.conf manual page describes how
+to set these and gives recommendations.
+
+Getting the socket options right can make a big difference to your
+performance, but getting them wrong can degrade it by just as
+much. The correct settings are very dependent on your local network.
+
+The socket option TCP_NODELAY is the one that seems to make the
+biggest single difference for most networks. Many people report that
+adding "socket options = TCP_NODELAY" doubles the read performance of
+a Samba drive. The best explanation I have seen for this is that the
+Microsoft TCP/IP stack is slow in sending tcp ACKs.
+
+
+READ SIZE
+---------
+
+The option "read size" affects the overlap of disk reads/writes with
+network reads/writes. If the amount of data being transferred in
+several of the SMB commands (currently SMBwrite, SMBwriteX and
+SMBreadbraw) is larger than this value then the server begins writing
+the data before it has received the whole packet from the network, or
+in the case of SMBreadbraw, it begins writing to the network before
+all the data has been read from disk.
+
+This overlapping works best when the speeds of disk and network access
+are similar, having very little effect when the speed of one is much
+greater than the other.
+
+The default value is 16384, but very little experimentation has been
+done yet to determine the optimal value, and it is likely that the best
+value will vary greatly between systems anyway. A value over 65536 is
+pointless and will cause you to allocate memory unnecessarily.
+
+
+MAX XMIT
+--------
+
+At startup the client and server negotiate a "maximum transmit" size,
+which limits the size of nearly all SMB commands. You can set the
+maximum size that Samba will negotiate using the "max xmit = " option
+in smb.conf. Note that this is the maximum size of SMB request that
+Samba will accept, but not the maximum size that the *client* will accept.
+The client maximum receive size is sent to Samba by the client and Samba
+honours this limit.
+
+It defaults to 65536 bytes (the maximum), but it is possible that some
+clients may perform better with a smaller transmit unit. Trying values
+of less than 2048 is likely to cause severe problems.
+
+In most cases the default is the best option.
+
+
+LOCKING
+-------
+
+By default Samba does not implement strict locking on each read/write
+call (although it did in previous versions). If you enable strict
+locking (using "strict locking = yes") then you may find that you
+suffer a severe performance hit on some systems.
+
+The performance hit will probably be greater on NFS mounted
+filesystems, but could be quite high even on local disks.
+
+
+SHARE MODES
+-----------
+
+Some people find that opening files is very slow. This is often
+because of the "share modes" code needed to fully implement the dos
+share modes stuff. You can disable this code using "share modes =
+no". This will gain you a lot in opening and closing files but will
+mean that (in some cases) the system won't force a second user of a
+file to open the file read-only if the first has it open
+read-write. For many applications that do their own locking this
+doesn't matter, but for some it may. Most Windows applications
+depend heavily on "share modes" working correctly and it is
+recommended that the Samba share mode support be left at the
+default of "on".
+
+The share mode code in Samba has been re-written in the 1.9.17
+release following tests with the Ziff-Davis NetBench PC Benchmarking
+tool. It is now believed that Samba 1.9.17 implements share modes
+similarly to Windows NT.
+
+NOTE: In the most recent versions of Samba there is an option to use
+shared memory via mmap() to implement the share modes. This makes
+things much faster. See the Makefile for how to enable this.
+
+
+LOG LEVEL
+---------
+
+If you set the log level (also known as "debug level") higher than 2
+then you may suffer a large drop in performance. This is because the
+server flushes the log file after each operation, which can be very
+expensive.
+
+
+WIDE LINKS
+----------
+
+The "wide links" option is now enabled by default, but if you disable
+it (for better security) then you may suffer a performance hit in
+resolving filenames. The performance loss is lessened if you have
+"getwd cache = yes", which is now the default.
+
+
+READ RAW
+--------
+
+The "read raw" operation is designed to be an optimised, low-latency
+file read operation. A server may choose to not support it,
+however. and Samba makes support for "read raw" optional, with it
+being enabled by default.
+
+In some cases clients don't handle "read raw" very well and actually
+get lower performance using it than they get using the conventional
+read operations.
+
+So you might like to try "read raw = no" and see what happens on your
+network. It might lower, raise or not affect your performance. Only
+testing can really tell.
+
+
+WRITE RAW
+---------
+
+The "write raw" operation is designed to be an optimised, low-latency
+file write operation. A server may choose to not support it,
+however. and Samba makes support for "write raw" optional, with it
+being enabled by default.
+
+Some machines may find "write raw" slower than normal write, in which
+case you may wish to change this option.
+
+READ PREDICTION
+---------------
+
+Samba can do read prediction on some of the SMB commands. Read
+prediction means that Samba reads some extra data on the last file it
+read while waiting for the next SMB command to arrive. It can then
+respond more quickly when the next read request arrives.
+
+This is disabled by default. You can enable it by using "read
+prediction = yes".
+
+Note that read prediction is only used on files that were opened read
+only.
+
+Read prediction should particularly help for those silly clients (such
+as "Write" under NT) which do lots of very small reads on a file.
+
+Samba will not read ahead more data than the amount specified in the
+"read size" option. It always reads ahead on 1k block boundaries.
+
+
+MEMORY MAPPING
+--------------
+
+Samba supports reading files via memory mapping them. One some
+machines this can give a large boost to performance, on others it
+makes not difference at all, and on some it may reduce performance.
+
+To enable you you have to recompile Samba with the -DUSE_MMAP option
+on the FLAGS line of the Makefile.
+
+Note that memory mapping is only used on files opened read only, and
+is not used by the "read raw" operation. Thus you may find memory
+mapping is more effective if you disable "read raw" using "read raw =
+no".
+
+
+SLOW CLIENTS
+------------
+
+One person has reported that setting the protocol to COREPLUS rather
+than LANMAN2 gave a dramatic speed improvement (from 10k/s to 150k/s).
+
+I suspect that his PC's (386sx16 based) were asking for more data than
+they could chew. I suspect a similar speed could be had by setting
+"read raw = no" and "max xmit = 2048", instead of changing the
+protocol. Lowering the "read size" might also help.
+
+
+SLOW LOGINS
+-----------
+
+Slow logins are almost always due to the password checking time. Using
+the lowest practical "password level" will improve things a lot. You
+could also enable the "UFC crypt" option in the Makefile.
+
+CLIENT TUNING
+-------------
+
+Often a speed problem can be traced to the client. The client (for
+example Windows for Workgroups) can often be tuned for better TCP
+performance.
+
+See your client docs for details. In particular, I have heard rumours
+that the WfWg options TCPWINDOWSIZE and TCPSEGMENTSIZE can have a
+large impact on performance.
+
+Also note that some people have found that setting DefaultRcvWindow in
+the [MSTCP] section of the SYSTEM.INI file under WfWg to 3072 gives a
+big improvement. I don't know why.
+
+My own experience wth DefaultRcvWindow is that I get much better
+performance with a large value (16384 or larger). Other people have
+reported that anything over 3072 slows things down enourmously. One
+person even reported a speed drop of a factor of 30 when he went from
+3072 to 8192. I don't know why.
+
+It probably depends a lot on your hardware, and the type of unix box
+you have at the other end of the link.
+
+
+MY RESULTS
+----------
+
+Some people want to see real numbers in a document like this, so here
+they are. I have a 486sx33 client running WfWg 3.11 with the 3.11b
+tcp/ip stack. It has a slow IDE drive and 20Mb of ram. It has a SMC
+Elite-16 ISA bus ethernet card. The only WfWg tuning I've done is to
+set DefaultRcvWindow in the [MSTCP] section of system.ini to 16384. My
+server is a 486dx3-66 running Linux. It also has 20Mb of ram and a SMC
+Elite-16 card. You can see my server config in the examples/tridge/
+subdirectory of the distribution.
+
+I get 490k/s on reading a 8Mb file with copy.
+I get 441k/s writing the same file to the samba server.
+
+Of course, there's a lot more to benchmarks than 2 raw throughput
+figures, but it gives you a ballpark figure.
+
+I've also tested Win95 and WinNT, and found WinNT gave me the best
+speed as a samba client. The fastest client of all (for me) is
+smbclient running on another linux box. Maybe I'll add those results
+here someday ...
+
+
diff --git a/docs/textdocs/Speed2.txt b/docs/textdocs/Speed2.txt
new file mode 100755
index 00000000000..cbdce761de5
--- /dev/null
+++ b/docs/textdocs/Speed2.txt
@@ -0,0 +1,60 @@
+!==
+!== Speed2.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Paul Cochrane <paulc@dth.scot.nhs.uk>
+Organization: Dundee Limb Fitting Centre
+Date: Fri, 10 Apr 1998
+Subject: Samba SPEED.TXT comment
+=============================================================================
+
+This might be relevant to Client Tuning. I have been trying various methods
+of getting win95 to talk to Samba quicker. The results I have come up with
+are:
+
+1. Install the W2setup.exe file from www.microsoft.com. This is an
+update for the winsock stack and utilities which improve performance.
+
+2. Configure the win95 TCPIP registry settings to give better
+perfomance. I use a program called MTUSPEED.exe which I got off the
+net. There are various other utilities of this type freely available.
+The setting which give the best performance for me are:
+
+(a) MaxMTU Remove
+(b) RWIN Remove
+(c) MTUAutoDiscover Disable
+(d) MTUBlackHoleDetect Disable
+(e) Time To Live Enabled
+(f) Time To Live - HOPS 32
+(g) NDI Cache Size 0
+
+3. I tried virtually all of the items mentioned in the document and
+the only one which made a difference to me was the socket options. It
+turned out I was better off without any!!!!!
+
+In terms of overall speed of transfer, between various win95 clients
+and a DX2-66 20MB server with a crappy NE2000 compatible and old IDE
+drive (Kernel 2.0.30). The transfer rate was reasonable for 10 baseT.
+
+The figures are: Put Get
+P166 client 3Com card: 420-440kB/s 500-520kB/s
+P100 client 3Com card: 390-410kB/s 490-510kB/s
+DX4-75 client NE2000: 370-380kB/s 330-350kB/s
+
+I based these test on transfer two files a 4.5MB text file and a 15MB
+textfile. The results arn't bad considering the hardware Samba is
+running on. It's a crap machine!!!!
+
+The updates mentioned in 1 and 2 brought up the transfer rates from
+just over 100kB/s in some clients.
+
+A new client is a P333 connected via a 100MB/s card and hub. The
+transfer rates from this were good: 450-500kB/s on put and 600+kB/s
+on get.
+
+Looking at standard FTP throughput, Samba is a bit slower (100kB/s
+upwards). I suppose there is more going on in the samba protocol, but
+if it could get up to the rate of FTP the perfomance would be quite
+staggering.
+
+Paul Cochrane
+
diff --git a/docs/textdocs/Tracing.txt b/docs/textdocs/Tracing.txt
new file mode 100755
index 00000000000..96d863d0742
--- /dev/null
+++ b/docs/textdocs/Tracing.txt
@@ -0,0 +1,96 @@
+!==
+!== Tracing.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Andrew Tridgell <samba@samba.org>
+Date: Old
+Status: Questionable
+
+Subject: How to trace samba system calls for debugging purposes
+=============================================================================
+
+This file describes how to do a system call trace on Samba to work out
+what its doing wrong. This is not for the faint of heart, but if you
+are reading this then you are probably desperate.
+
+Actually its not as bad as the the above makes it sound, just don't
+expect the output to be very pretty :-)
+
+Ok, down to business. One of the big advantages of unix systems is
+that they nearly all come with a system trace utility that allows you
+to monitor all system calls that a program is making. This is
+extremely using for debugging and also helps when trying to work out
+why something is slower than you expect. You can use system tracing
+without any special compilation options.
+
+The system trace utility is called different things on different
+systems. On Linux systems its called strace. Under SunOS 4 its called
+trace. Under SVR4 style systems (including solaris) its called
+truss. Under many BSD systems its called ktrace.
+
+The first thing you should do is read the man page for your native
+system call tracer. In the discussion below I'll assume its called
+strace as strace is the only portable system tracer (its available for
+free for many unix types) and its also got some of the nicest
+features.
+
+Next, try using strace on some simple commands. For example, "strace
+ls" or "strace echo hello".
+
+You'll notice that it produces a LOT of output. It is showing you the
+arguments to every system call that the program makes and the
+result. Very little happens in a program without a system call so you
+get lots of output. You'll also find that it produces a lot of
+"preamble" stuff showing the loading of shared libraries etc. Ignore
+this (unless its going wrong!)
+
+For example, the only line that really matters in the "strace echo
+hello" output is:
+
+write(1, "hello\n", 6) = 6
+
+all the rest is just setting up to run the program.
+
+Ok, now you're famialiar with strace. To use it on Samba you need to
+strace the running smbd daemon. The way I tend ot use it is to first
+login from my Windows PC to the Samba server, then use smbstatus to
+find which process ID that client is attached to, then as root I do
+"strace -p PID" to attach to that process. I normally redirect the
+stderr output from this command to a file for later perusal. For
+example, if I'm using a csh style shell:
+
+ strace -f -p 3872 >& strace.out
+
+or with a sh style shell:
+
+ strace -f -p 3872 > strace.out 2>&1
+
+Note the "-f" option. This is only available on some systems, and
+allows you to trace not just the current process, but any children it
+forks. This is great for finding printing problems caused by the
+"print command" being wrong.
+
+Once you are attached you then can do whatever it is on the client
+that is causing problems and you will capture all the system calls
+that smbd makes.
+
+So how do you interpret the results? Generally I search thorugh the
+output for strings that I know will appear when the problem
+happens. For example, if I am having touble with permissions on a file
+I would search for that files name in the strace output and look at
+the surrounding lines. Another trick is to match up file descriptor
+numbers and "follow" what happens to an open file until it is closed.
+
+Beyond this you will have to use your initiative. To give you an idea
+of wehat you are looking for here is a piece of strace output that
+shows that /dev/null is not world writeable, which causes printing to
+fail with Samba:
+
+[pid 28268] open("/dev/null", O_RDWR) = -1 EACCES (Permission denied)
+[pid 28268] open("/dev/null", O_WRONLY) = -1 EACCES (Permission denied)
+
+the process is trying to first open /dev/null read-write then
+read-only. Both fail. This means /dev/null has incorrect permissions.
+
+Have fun!
+
+(please send updates/fixes to this file to samba@samba.org)
diff --git a/docs/textdocs/UNIX-SMB.txt b/docs/textdocs/UNIX-SMB.txt
new file mode 100755
index 00000000000..5c6d5b8c813
--- /dev/null
+++ b/docs/textdocs/UNIX-SMB.txt
@@ -0,0 +1,234 @@
+!==
+!== UNIX-SMB.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Andrew Tridgell <samba@samba.org>
+Date: April 1995
+
+Subject: Discussion of NetBIOS in a Unix World
+============================================================================
+
+This is a short document that describes some of the issues that
+confront a SMB implementation on unix, and how Samba copes with
+them. They may help people who are looking at unix<->PC
+interoperability.
+
+It was written to help out a person who was writing a paper on unix to
+PC connectivity.
+
+
+Usernames
+=========
+
+The SMB protocol has only a loose username concept. Early SMB
+protocols (such as CORE and COREPLUS) have no username concept at
+all. Even in later protocols clients often attempt operations
+(particularly printer operations) without first validating a username
+on the server.
+
+Unix security is based around username/password pairs. A unix box
+should not allow clients to do any substantive operation without some
+sort of validation.
+
+The problem mostly manifests itself when the unix server is in "share
+level" security mode. This is the default mode as the alternative
+"user level" security mode usually forces a client to connect to the
+server as the same user for each connected share, which is
+inconvenient in many sites.
+
+In "share level" security the client normally gives a username in the
+"session setup" protocol, but does not supply an accompanying
+password. The client then connects to resources using the "tree
+connect" protocol, and supplies a password. The problem is that the
+user on the PC types the username and the password in different
+contexts, unaware that they need to go together to give access to the
+server. The username is normally the one the user typed in when they
+"logged onto" the PC (this assumes Windows for Workgroups). The
+password is the one they chose when connecting to the disk or printer.
+
+The user often chooses a totally different username for their login as
+for the drive connection. Often they also want to access different
+drives as different usernames. The unix server needs some way of
+divining the correct username to combine with each password.
+
+Samba tries to avoid this problem using several methods. These succeed
+in the vast majority of cases. The methods include username maps, the
+service%user syntax, the saving of session setup usernames for later
+validation and the derivation of the username from the service name
+(either directly or via the user= option).
+
+File Ownership
+==============
+
+The commonly used SMB protocols have no way of saying "you can't do
+that because you don't own the file". They have, in fact, no concept
+of file ownership at all.
+
+This brings up all sorts of interesting problems. For example, when
+you copy a file to a unix drive, and the file is world writeable but
+owned by another user the file will transfer correctly but will
+receive the wrong date. This is because the utime() call under unix
+only succeeds for the owner of the file, or root, even if the file is
+world writeable. For security reasons Samba does all file operations
+as the validated user, not root, so the utime() fails. This can stuff
+up shared development diectories as programs like "make" will not get
+file time comparisons right.
+
+There are several possible solutions to this problem, including
+username mapping, and forcing a specific username for particular
+shares.
+
+Passwords
+=========
+
+Many SMB clients uppercase passwords before sending them. I have no
+idea why they do this. Interestingly WfWg uppercases the password only
+if the server is running a protocol greater than COREPLUS, so
+obviously it isn't just the data entry routines that are to blame.
+
+Unix passwords are case sensitive. So if users use mixed case
+passwords they are in trouble.
+
+Samba can try to cope with this by either using the "password level"
+option which causes Samba to try the offered password with up to the
+specified number of case changes, or by using the "password server"
+option which allows Samba to do its validation via another machine
+(typically a WinNT server).
+
+Samba supports the password encryption method used by SMB
+clients. Note that the use of password encryption in Microsoft
+networking leads to password hashes that are "plain text equivalent".
+This means that it is *VERY* important to ensure that the Samba
+smbpasswd file containing these password hashes is only readable
+by the root user. See the documentation ENCRYPTION.txt for more
+details.
+
+
+Locking
+=======
+
+The locking calls available under a DOS/Windows environment are much
+richer than those available in unix. This means a unix server (like
+Samba) choosing to use the standard fcntl() based unix locking calls
+to implement SMB locking has to improvise a bit.
+
+One major problem is that dos locks can be in a 32 bit (unsigned)
+range. Unix locking calls are 32 bits, but are signed, giving only a 31
+bit range. Unfortunately OLE2 clients use the top bit to select a
+locking range used for OLE semaphores.
+
+To work around this problem Samba compresses the 32 bit range into 31
+bits by appropriate bit shifting. This seems to work but is not
+ideal. In a future version a separate SMB lockd may be added to cope
+with the problem.
+
+It also doesn't help that many unix lockd daemons are very buggy and
+crash at the slightest provocation. They normally go mostly unused in
+a unix environment because few unix programs use byte range
+locking. The stress of huge numbers of lock requests from dos/windows
+clients can kill the daemon on some systems.
+
+The second major problem is the "opportunistic locking" requested by
+some clients. If a client requests opportunistic locking then it is
+asking the server to notify it if anyone else tries to do something on
+the same file, at which time the client will say if it is willing to
+give up its lock. Unix has no simple way of implementing
+opportunistic locking, and currently Samba has no support for it.
+
+Deny Modes
+==========
+
+When a SMB client opens a file it asks for a particular "deny mode" to
+be placed on the file. These modes (DENY_NONE, DENY_READ, DENY_WRITE,
+DENY_ALL, DENY_FCB and DENY_DOS) specify what actions should be
+allowed by anyone else who tries to use the file at the same time. If
+DENY_READ is placed on the file, for example, then any attempt to open
+the file for reading should fail.
+
+Unix has no equivalent notion. To implement this Samba uses either lock
+files based on the files inode and placed in a separate lock
+directory or a shared memory implementation. The lock file method
+is clumsy and consumes processing and file resources,
+the shared memory implementation is vastly prefered and is turned on
+by default for those systems that support it.
+
+Trapdoor UIDs
+=============
+
+A SMB session can run with several uids on the one socket. This
+happens when a user connects to two shares with different
+usernames. To cope with this the unix server needs to switch uids
+within the one process. On some unixes (such as SCO) this is not
+possible. This means that on those unixes the client is restricted to
+a single uid.
+
+Note that you can also get the "trapdoor uid" message for other
+reasons. Please see the FAQ for details.
+
+Port numbers
+============
+
+There is a convention that clients on sockets use high "unprivilaged"
+port numbers (>1000) and connect to servers on low "privilaged" port
+numbers. This is enforced in Unix as non-root users can't open a
+socket for listening on port numbers less than 1000.
+
+Most PC based SMB clients (such as WfWg and WinNT) don't follow this
+convention completely. The main culprit is the netbios nameserving on
+udp port 137. Name query requests come from a source port of 137. This
+is a problem when you combine it with the common firewalling technique
+of not allowing incoming packets on low port numbers. This means that
+these clients can't query a netbios nameserver on the other side of a
+low port based firewall.
+
+The problem is more severe with netbios node status queries. I've
+found that WfWg, Win95 and WinNT3.5 all respond to netbios node status
+queries on port 137 no matter what the source port was in the
+request. This works between machines that are both using port 137, but
+it means it's not possible for a unix user to do a node status request
+to any of these OSes unless they are running as root. The answer comes
+back, but it goes to port 137 which the unix user can't listen
+on. Interestingly WinNT3.1 got this right - it sends node status
+responses back to the source port in the request.
+
+
+Protocol Complexity
+===================
+
+There are many "protocol levels" in the SMB protocol. It seems that
+each time new functionality was added to a Microsoft operating system,
+they added the equivalent functions in a new protocol level of the SMB
+protocol to "externalise" the new capabilities.
+
+This means the protocol is very "rich", offering many ways of doing
+each file operation. This means SMB servers need to be complex and
+large. It also means it is very difficult to make them bug free. It is
+not just Samba that suffers from this problem, other servers such as
+WinNT don't support every variation of every call and it has almost
+certainly been a headache for MS developers to support the myriad of
+SMB calls that are available.
+
+There are about 65 "top level" operations in the SMB protocol (things
+like SMBread and SMBwrite). Some of these include hundreds of
+sub-functions (SMBtrans has at least 120 sub-functions, like
+DosPrintQAdd and NetSessionEnum). All of them take several options
+that can change the way they work. Many take dozens of possible
+"information levels" that change the structures that need to be
+returned. Samba supports all but 2 of the "top level" functions. It
+supports only 8 (so far) of the SMBtrans sub-functions. Even NT
+doesn't support them all.
+
+Samba currently supports up to the "NT LM 0.12" protocol, which is the
+one preferred by Win95 and WinNT3.5. Luckily this protocol level has a
+"capabilities" field which specifies which super-duper new-fangled
+options the server suports. This helps to make the implementation of
+this protocol level much easier.
+
+There is also a problem with the SMB specications. SMB is a X/Open
+spec, but the X/Open book is far from ideal, and fails to cover many
+important issues, leaving much to the imagination. Microsoft recently
+renamed the SMB protocol CIFS (Common Internet File System) and have
+published new specifications. These are far superior to the old
+X/Open documents but there are still undocumented calls and features.
+This specification is actively being worked on by a CIFS developers
+mailing list hosted by Microsft.
+
diff --git a/docs/textdocs/UNIX_SECURITY.txt b/docs/textdocs/UNIX_SECURITY.txt
new file mode 100755
index 00000000000..a979dc5a497
--- /dev/null
+++ b/docs/textdocs/UNIX_SECURITY.txt
@@ -0,0 +1,57 @@
+!==
+!== UNIX_SECURITY.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: John H Terpstra <jht@samba.org>
+Date: July 5, 1998
+Status: Current
+
+Subject: SETTING UNIX FILE SYSTEM SECURITY
+===============================================================================
+The following excerpt from a bug report demonstrates the need to
+understand Unix file system security and to manage it correctly.
+
+Quote:
+======
+> We are unable to keep individual users from mapping to any other user's
+> home directory once they have supplied a valid password! They only need
+> to enter their own password. I have not found *any* method that I can
+> use to configure samba to enforce that only a user may map their own
+> home directory.
+>
+> User xyzzy can map his home directory. Once mapped user xyzzy can also map
+> *anyone* elses home directory!
+
+ANSWER:
+=======
+This is not a security flaw, it is by design. Samba allows
+users to have *exactly* the same access to the UNIX filesystem
+as they would if they were logged onto the UNIX box, except
+that it only allows such views onto the file system as are
+allowed by the defined shares.
+
+This means that if your UNIX home directories are set up
+such that one user can happily cd into another users
+directory and do an ls, the UNIX security solution is to
+change the UNIX file permissions on the users home directories
+such that the cd and ls would be denied.
+
+Samba tries very hard not to second guess the UNIX administrators
+security policies, and trusts the UNIX admin to set
+the policies and permissions he or she desires.
+
+Samba does allow the setup you require when you have set the
+"only user = yes" option on the share, is that you have not set the
+valid users list for the share.
+
+Note that only user works in conjunction with the users= list,
+so to get the behavior you require, add the line :
+
+users = %S
+
+this is equivalent to:
+
+valid users = %S
+
+to the definition of the [homes] share, as recommended in
+the smb.conf man page.
+
diff --git a/docs/textdocs/Win95.txt b/docs/textdocs/Win95.txt
new file mode 100755
index 00000000000..911fddf427a
--- /dev/null
+++ b/docs/textdocs/Win95.txt
@@ -0,0 +1,77 @@
+!==
+!== Win95.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Copyright (C) 1997 - Samba-Team
+Contributed Date: August 20, 1997
+Last Update: August 20, 1997
+
+Subject: Windows 95 and Samba Interoperability
+===============================================================================
+
+Password Handling:
+------------------
+Microsoft periodically release updates to all their operating systems. Some of
+these are welcomed while others cause us to change the way we do things. Few
+people like change, particularly if the change is unexpected. The best advice
+always is to read the documentation provided BEFORE applying an update.
+
+One of the recent Win95 updates (VRDRUPD.EXE) disables plain text (also called
+clear text) password authentication. The effects of this updates are desirable
+where MS Windows NT is providing the password authentication service. This
+update is most undesirable where Samba must provide the authentication service
+unless Samba has been specifically configured to use encrypted passwords _AND_
+has been linked with the libdes library.
+
+If the above conditions have not been complied with, and you are using Samba,
+then Windows 95 clients will NOT be able to authenticate to a Samba server.
+
+To re-enable plain text password capabilities AFTER applying this update
+you must create a new value in the Windows 95 registry.
+
+Either foillow the following procedure or just double click on the
+file Win95_PlainPassword.reg for an easier way to do this.
+
+Procedure:
+1) Launch the Registry Editor as follows:
+ Click on: /Start/Run
+ Type "regedit" and press enter.
+
+2) Double click on: HKEY_LOCAL_MACHINE
+
+3) Locate the following Key:
+ /HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/VxD/VNETSUP
+
+4) From the menu bar select Edit/New/DWORD Value
+
+5) Rename the entry from "New Value #1" to:
+ EnablePlainTextPassword
+
+6) Press Enter, then double click on the new entry.
+ A dialog box will pop up and enable you to set a value.
+ You must set this value to 1.
+
+-------------------------------------------------------------------------------
+
+Windows 95 Updates:
+-------------------
+When using Windows 95 OEM SR2 the following updates are recommended where Samba
+is being used. Please NOTE that the above change will affect you once these
+updates have been installed.
+
+There are more updates than the ones mentioned here. You are referred to the
+Microsoft Web site for all currently available updates to your specific version
+of Windows 95.
+
+Kernel Update: KRNLUPD.EXE
+Ping Fix: PINGUPD.EXE
+RPC Update: RPCRTUPD.EXE
+TCP/IP Update: VIPUPD.EXE
+Redirector Update: VRDRUPD.EXE
+
+Also, if using MS OutLook it is desirable to install the OLEUPD.EXE fix. This
+fix may stop your machine from hanging for an extended period when exiting
+OutLook and you may also notice a significant speedup when accessing network
+neighborhood services.
+
+-------------------------------------------------------------------------------
+The above password information was provided by: Jochen Huppertz <jhu@nrh.de>
diff --git a/docs/textdocs/WinNT.txt b/docs/textdocs/WinNT.txt
new file mode 100755
index 00000000000..c7d41a4114a
--- /dev/null
+++ b/docs/textdocs/WinNT.txt
@@ -0,0 +1,107 @@
+!==
+!== WinNT.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributors: Various
+ Password Section - Copyright (C) 1997 - John H Terpstra
+ Printing Section - Copyright (C) 1997 - Matthew Harrell
+ Priting Info - Copyright (C) 1997 - Frank Varnavas
+Updated: October 16, 1997
+Status: Current
+
+Subject: Samba and Windows NT Password Handling
+=============================================================================
+
+There are some particular issues with Samba and Windows NT.
+
+Passwords:
+==========
+One of the most annoying problems with WinNT is that NT refuses to
+connect to a server that is in user level security mode and that
+doesn't support password encryption unless it first prompts the user
+for a password.
+
+This means even if you have the same password on the NT box and the
+Samba server you will get prompted for a password. Entering the
+correct password will get you connected only if Windows NT can
+communicate with Samba using a compatible mode of password security.
+
+All versions of Windows NT prior to 4.0 Service Pack 3 could negotiate
+plain text (clear text) passwords. Windows NT 4.0 Service Pack 3 changed
+this default behaviour so it now will only handle encrypted passwords.
+The following registry entry change will re-enable clear text password
+handling:
+
+Run regedt32.exe and locate the hive key entry:
+HKEY_LOCAL_MACHINE\system\CurrentControlSet\Services\Rdr\Parameters\
+
+Add the following value:
+ EnablePlainTextPassword:REG_DWORD=1
+
+Alternatively, use the NT4_PlainPassword.reg file in this directory (either
+by double clicking on it, or running regedt32.exe and selecting "Import
+Registry File" from the "Registry" Menu).
+
+The other major ramification of this feature of NT is that it can't
+browse a user level non-encrypted server unless it already has a
+connection open. This is because there is no spot for a password
+prompt in the browser window. It works fine if you already have a
+drive mounted (for example, one auto mounted on startup).
+=====================================================================
+
+Printing:
+=========
+When you mount a printer using the print manager in NT you may find
+the following info from Matthew Harrell <harrell@leech.nrl.navy.mil>
+useful:
+
+------------
+ I noticed in your change-log you noted that some people were
+still unable to use print manager under NT. If this is the same problem
+that I encountered, it's caused by the length of time it takes NT to
+determine if the printer is ready.
+
+The problem occurs when you double-click on a printer to connect it to
+the NT machine. Because it's unable to determine if the printer is ready
+in the short span of time it has, it assumes it isn't and gives some
+strange error about not having enough resources (I forget what the error
+is). A solution to this that seems to work fine for us is to click
+once on the printer, look at the bottom of the window and wait until
+it says it's ready, then click on "OK".
+
+By the way, this problem probably occurs in our group because the
+Samba server doesn't actually have the printers - it queues them to
+remote printers either on other machines or using their own network
+cards. Because of this "middle layer", it takes an extra amount of
+time for the NT machine to get verification that the printer queue
+actually exists.
+
+I hope this helped in some way...
+
+=====================================================================
+Printing Info:
+--------------
+
+From: Frank Varnavas <varnavas@ny.ubs.com>
+Subject: RE: Samba as a print server
+
+When an NT client attempts to connect to a printer on a non-NT print
+server the attempt is failed with an error, something like:
+
+ "You have insufficient access to your computer to perform the
+ operation because a driver needs to be installed"
+
+This is because domain users must have 'Power User' status on the
+desktop to connect to printers on a non-NT print server.
+
+This error occurs regardless of whether the driver in question is
+already installed or not. What it really means is that the server is
+a non-NT server and the client does not have permission to create
+printers locally. Apparently when a connection to a non-NT print
+server is made the printer is defined locally. Such an action can be
+performed by either a local administrator or a Power User.
+Unfortunately there is no way to limit the powers of a Power User, nor
+is there any way to grant the Printer Creation right to another group.
+
+This permission policy is documented in PSS database WINNT, ID Q101874
+
+Frank Varnavas (varnavas@ny.ubs.com)
diff --git a/docs/textdocs/cifsntdomain.txt b/docs/textdocs/cifsntdomain.txt
new file mode 100755
index 00000000000..91d032b1695
--- /dev/null
+++ b/docs/textdocs/cifsntdomain.txt
@@ -0,0 +1,1501 @@
+!==
+!== cifsntdomain.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+NT Domain Authentication
+------------------------
+
+Authors: - Luke Kenneth Casson Leighton (lkcl@switchboard.net)
+-------- - Paul Ashton (paul@argo.demon.co.uk)
+ - Duncan Stansfield (duncans@sco.com)
+
+ Copyright (C) 1997 Luke Kenneth Casson Leighton
+ Copyright (C) 1997 Paul Ashton
+ Copyright (C) 1997 Duncan Stansfield
+
+Version: 0.024 (01Nov97)
+--------
+
+Distribution: Unlimited and encouraged, for the purposes of implementation
+------------- and comments. Feedback welcomed by the authors.
+
+Liability: Absolutely none accepted implicitly or explicitly, direct
+---------- or consequentially, for use, abuse, misuse, lack of use,
+ misunderstandings, mistakes, omissions, mis-information for
+ anything in or not in, related to or not related to, or
+ pertaining to this document, or anything else that a lawyer
+ can think of or not think of.
+
+Warning: Please bear in mind that an incorrect implementation of this
+-------- protocol can cause NT workstation to fail irrevocably, for
+ which the authors accept no liability (see above). Please
+ contact your vendor if you have any problems.
+
+Sources: - Packet Traces from Netmonitor (Service Pack 1 and above)
+-------- - Paul Ashton and Luke Leighton's other "NT Domain" doc.
+ - CIFS documentation - cifs6.txt
+ - CIFS documentation - cifsrap2.txt
+
+Original: http://mailhost.cb1.com/~lkcl/cifsntdomain.txt.
+--------- (Controlled copy maintained by lkcl@switchboard.net)
+
+Credits: - Paul Ashton: loads of work with Net Monitor;
+-------- understanding the NT authentication system;
+ reference implementation of the NT domain support on which
+ this document is originally based.
+ - Duncan Stansfield: low-level analysis of MSRPC Pipes.
+ - Linus Nordberg: producing c-code from Paul's crypto spec.
+ - Windows Sourcer development team
+
+
+Contents:
+---------
+
+ 1) Introduction
+
+ 2) Structures and notes
+
+ 2.1) Notes
+ 2.3) Enumerations
+ 2.3) Structures
+
+ 3) Transact Named Pipe Header/Tail
+
+ 3.1) MSRPC Pipes
+ 3.2) Header
+ 3.3) Tail
+
+ 4) NTLSA Transact Named Pipe
+
+ 4.1) LSA Open Policy
+ 4.2) LSA Query Info Policy
+ 4.3) LSA Enumerate Trusted Domains
+ 4.4) LSA Open Secret
+ 4.5) LSA Close
+ 4.6) LSA Lookup SIDS
+ 4.7) LSA Lookup Names
+
+ 5) NETLOGON rpc Transact Named Pipe
+
+ 5.1) LSA Request Challenge
+ 5.2) LSA Authenticate 2
+ 5.3) LSA Server Password Set
+ 5.4) LSA SAM Logon
+ 5.5) LSA SAM Logoff
+
+ 6) \\MAILSLOT\NET\NTLOGON
+
+ 6.1) Query for PDC
+ 6.2) SAM Logon
+
+ 7) SRVSVC Transact Named Pipe
+
+ 7.1) Net Share Enum
+ 7.2) Net Server Get Info
+
+
+Appendix:
+---------
+
+ A1) Cryptographic side of NT Domain Authentication
+
+ A1.1) Definitions
+ A1.2) Protocol
+ A1.3) Comments
+
+ A2) SIDs and RIDs
+
+ A2.1) Well-known SIDs
+
+ A2.1.1) Universal well-known SIDs
+ A2.1.2) NT well-known SIDs
+
+ A2.2) Well-known RIDS
+
+ A2.2.1) Well-known RID users
+ A2.2.2) Well-known RID groups
+ A2.2.3) Well-known RID aliases
+
+
+
+1) Introduction
+---------------
+
+
+This document contains information to provide an NT workstation with login
+services, without the need for an NT server.
+
+It should be possible to select a domain instead of a workgroup (in the NT
+workstation's TCP/IP settings) and after the obligatory reboot, type in a
+username, password, select a domain and successfully log in. I would
+appreciate any feedback on your experiences with this process, and any
+comments, corrections and additions to this document.
+
+
+The packets described here can be easily derived from (and are probably
+better understood using) Netmon.exe. You will need to use the version
+of Netmon that matches your system, in order to correctly decode the
+NETLOGON, lsarpc and srvsvc Transact pipes. This document is derived from
+NT Service Pack 1 and its corresponding version of Netmon. It is intended
+that an annotated packet trace be produced, which will likely be more
+instructive than this document.
+
+Also needed, to fully implement NT Domain Login Services, is the
+document describing the cryptographic part of the NT authentication.
+This document is available from comp.protocols.smb; from the ntsecurity.net
+digest and from the samba digest, amongst other sources.
+
+A copy is available from:
+
+http://ntbugtraq.rc.on.ca/SCRIPTS/WA.EXE?A2=ind9708&L=ntbugtraq&O=A&P=2935
+http://mailhost.cb1.com/~lkcl/crypt.html
+
+
+A c-code implementation, provided by Linus Nordberg <linus@incolumitas.se>
+of this protocol is available from:
+
+http://samba.org/cgi-bin/mfs/01/digest/1997/97aug/0391.html
+http://mailhost.cb1.com/~lkcl/crypt.txt
+
+
+Also used to provide debugging information is the Check Build version of
+NT workstation, and enabling full debugging in NETLOGON. This is
+achieved by setting the following REG_SZ registry key to 0x1ffffff:
+
+HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters
+
+- Incorrect direct editing of the registry can cause your machine to fail.
+ Then again, so can incorrect implementation of this protocol.
+ See "Liability:" above.
+
+
+Bear in mind that each packet over-the-wire will have its origin in an
+API call. Therefore, there are likely to be structures, enumerations
+and defines that are usefully documented elsewhere.
+
+
+This document is by no means complete or authoritative. Missing sections
+include, but are not limited to:
+
+- the meaning (and use by NT) of SIDs and RIDs.
+
+- mappings of RIDs to usernames (and vice-versa).
+
+- what a User ID is and what a Group ID is.
+
+- the exact meaning/definition of various magic constants or enumerations.
+
+- the reply error code and use of that error code when a workstation
+ becomes a member of a domain (to be described later). Failure to
+ return this error code will make the workstation report that it is
+ already a member of the domain.
+
+- the cryptographic side of the NetrServerPasswordSet command, which would
+ allow the workstation to change its password. This password is used to
+ generate the long-term session key. [It is possible to reject this
+ command, and keep the default workstation password].
+
+
+2) Notes and Structures
+-----------------------
+
+
+2.1) Notes
+----------
+
+- In the SMB Transact pipes, some "Structures", described here, appear to be
+ 4-byte aligned with the SMB header, at their start. Exactly which
+ "Structures" need aligning is not precisely known or documented.
+
+- In the UDP NTLOGON Mailslots, some "Structures", described here, appear to be
+ 2-byte aligned with the start of the mailslot, at their start.
+
+- Domain SID is of the format S-revision-version-auth1-auth2...authN.
+ e.g S-1-5-123-456-789-123-456. the 5 could be a sub-revision.
+
+- any undocumented buffer pointers must be non-zero if the string buffer it
+ refers to contains characters. exactly what value they should be is unknown.
+ 0x0000 0002 seems to do the trick to indicate that the buffer exists. a
+ NULL buffer pointer indicates that the string buffer is of zero length.
+ If the buffer pointer is NULL, then it is suspected that the structure it
+ refers to is NOT put into (or taken out of) the SMB data stream. This is
+ empirically derived from, for example, the LSA SAM Logon response packet,
+ where if the buffer pointer is NULL, the user information is not inserted
+ into the data stream. Exactly what happens with an array of buffer pointers
+ is not known, although an educated guess can be made.
+
+- an array of structures (a container) appears to have a count and a pointer.
+ if the count is zero, the pointer is also zero. no further data is put
+ into or taken out of the SMB data stream. if the count is non-zero, then
+ the pointer is also non-zero. immediately following the pointer is the
+ count again, followed by an array of container sub-structures. the count
+ appears a third time after the last sub-structure.
+
+
+2.2) Enumerations
+-----------------
+
+- MSRPC Header type. command number in the msrpc packet header
+
+ MSRPC_Request: 0x00
+ MSRPC_Response: 0x02
+ MSRPC_Bind: 0x0B
+ MSRPC_BindAck: 0x0C
+
+- MSRPC Packet info. the meaning of these flags is undocumented
+
+ FirstFrag: 0x01
+ LastFrag: 0x02
+ NotaFrag: 0x04
+ RecRespond: 0x08
+ NoMultiplex: 0x10
+ NotForIdemp: 0x20
+ NotforBcast: 0x40
+ NoUuid: 0x80
+
+
+2.3) Structures
+---------------
+
+- sizeof VOID* is 32 bits.
+
+- sizeof char is 8 bits.
+
+- UTIME is 32 bits, indicating time in seconds since 01jan1970. documented
+ in cifs6.txt (section 3.5 page, page 30).
+
+- NTTIME is 64 bits. documented in cifs6.txt (section 3.5 page, page 30).
+
+- DOM_SID (domain SID structure) :
+
+ UINT32 num of sub-authorities in domain SID
+ UINT8 SID revision number
+ UINT8 num of sub-authorities in domain SID
+ UINT8[6] 6 bytes for domain SID - Identifier Authority.
+ UINT16[n_subauths] domain SID sub-authorities
+
+ Note: the domain SID is documented elsewhere.
+
+- STR (string) :
+
+ char[] null-terminated string of ascii characters.
+
+- UNIHDR (unicode string header) :
+
+ UINT16 length of unicode string
+ UINT16 max length of unicode string
+ UINT32 4 - undocumented.
+
+- UNIHDR2 (unicode string header plus buffer pointer) :
+
+ UNIHDR unicode string header
+ VOID* undocumented buffer pointer
+
+- UNISTR (unicode string) :
+
+ UINT16[] null-terminated string of unicode characters.
+
+- NAME (length-indicated unicode string) :
+
+ UINT32 length of unicode string
+ UINT16[] null-terminated string of unicode characters.
+
+- UNISTR2 (aligned unicode string) :
+
+ UINT8[] padding to get unicode string 4-byte aligned
+ with the start of the SMB header.
+ UINT32 max length of unicode string
+ UINT32 0 - undocumented
+ UINT32 length of unicode string
+ UINT16[] string of uncode characters.
+
+- OBJ_ATTR (object attributes) :
+
+ UINT32 0x18 - length (in bytes) including the length field.
+ VOID* 0 - root directory (pointer)
+ VOID* 0 - object name (pointer)
+ UINT32 0 - attributes (undocumented)
+ VOID* 0 - security descriptior (pointer)
+ UINT32 0 - security quality of service
+
+- POL_HND (LSA policy handle) :
+
+ char[20] policy handle
+
+- DOM_SID2 (domain SID structure, SIDS stored in unicode) :
+
+ UINT32 5 - SID type
+ UINT32 0 - undocumented
+ UNIHDR2 domain SID unicode string header
+ UNISTR domain SID unicode string
+
+ Note: there is a conflict between the unicode string header and the
+ unicode string itself as to which to use to indicate string
+ length. this will need to be resolved.
+
+ Note: the SID type indicates, for example, an alias; a well-known group etc.
+ this is documented somewhere.
+
+- DOM_RID (domain RID structure) :
+
+ UINT32 5 - well-known SID. 1 - user SID (see ShowACLs)
+ UINT32 5 - undocumented
+ UINT32 domain RID
+ UINT32 0 - domain index out of above reference domains
+
+
+- LOG_INFO (server, account, client structure) :
+
+ Note: logon server name starts with two '\' characters and is upper case.
+
+ Note: account name is the logon client name from the LSA Request Challenge,
+ with a $ on the end of it, in upper case.
+
+ VOID* undocumented buffer pointer
+ UNISTR2 logon server unicode string
+ UNISTR2 account name unicode string
+ UINT16 sec_chan - security channel type
+ UNISTR2 logon client machine unicode string
+
+- CLNT_SRV (server, client names structure) :
+
+ Note: logon server name starts with two '\' characters and is upper case.
+
+ VOID* undocumented buffer pointer
+ UNISTR2 logon server unicode string
+ VOID* undocumented buffer pointer
+ UNISTR2 logon client machine unicode string
+
+- CREDS (credentials + time stamp)
+
+ char[8] credentials
+ UTIME time stamp
+
+- CLNT_INFO2 (server, client structure, client credentials) :
+
+ Note: whenever this structure appears in a request, you must take a copy
+ of the client-calculated credentials received, because they will be
+ used in subsequent credential checks. the presumed intention is to
+ maintain an authenticated request/response trail.
+
+ CLNT_SRV client and server names
+ UINT8[] ???? padding, for 4-byte alignment with SMB header.
+ VOID* pointer to client credentials.
+ CREDS client-calculated credentials + client time
+
+- CLNT_INFO (server, account, client structure, client credentials) :
+
+ Note: whenever this structure appears in a request, you must take a copy
+ of the client-calculated credentials received, because they will be
+ used in subsequent credential checks. the presumed intention is to
+ maintain an authenticated request/response trail.
+
+ LOG_INFO logon account info
+ CREDS client-calculated credentials + client time
+
+- ID_INFO_1 (id info structure, auth level 1) :
+
+ VOID* ptr_id_info_1
+ UNIHDR domain name unicode header
+ UINT32 param control
+ UINT64 logon ID
+ UNIHDR user name unicode header
+ UNIHDR workgroup name unicode header
+ char[16] arc4 LM OWF Password
+ char[16] arc4 NT OWF Password
+ UNISTR2 domain name unicode string
+ UNISTR2 user name unicode string
+ UNISTR2 workstation name unicode string
+
+- SAM_INFO (sam logon/logoff id info structure) :
+
+ Note: presumably, the return credentials is supposedly for the server to
+ verify that the credential chain hasn't been compromised.
+
+ CLNT_INFO2 client identification/authentication info
+ VOID* pointer to return credentials.
+ CRED return credentials - ignored.
+ UINT16 logon level
+ UINT16 switch value
+
+ switch (switch_value)
+ case 1:
+ {
+ ID_INFO_1 id_info_1;
+ }
+
+- GID (group id info) :
+
+ UINT32 group id
+ UINT32 user attributes (only used by NT 3.1 and 3.51)
+
+- DOM_REF (domain reference info) :
+
+ VOID* undocumented buffer pointer.
+ UINT32 num referenced domains?
+ VOID* undocumented domain name buffer pointer.
+ UINT32 32 - max number of entries
+ UINT32 4 - num referenced domains?
+
+ UNIHDR2 domain name unicode string header
+ UNIHDR2[num_ref_doms-1] referenced domain unicode string headers
+
+ UNISTR domain name unicode string
+ DOM_SID[num_ref_doms] referenced domain SIDs
+
+- DOM_INFO (domain info, levels 3 and 5 are the same)) :
+
+ UINT8[] ??? padding to get 4-byte alignment with start of SMB header
+ UINT16 domain name string length * 2
+ UINT16 domain name string length * 2
+ VOID* undocumented domain name string buffer pointer
+ VOID* undocumented domain SID string buffer pointer
+ UNISTR2 domain name (unicode string)
+ DOM_SID domain SID
+
+- USER_INFO (user logon info) :
+
+ Note: it would be nice to know what the 16 byte user session key is for.
+
+ NTTIME logon time
+ NTTIME logoff time
+ NTTIME kickoff time
+ NTTIME password last set time
+ NTTIME password can change time
+ NTTIME password must change time
+
+ UNIHDR username unicode string header
+ UNIHDR user's full name unicode string header
+ UNIHDR logon script unicode string header
+ UNIHDR profile path unicode string header
+ UNIHDR home directory unicode string header
+ UNIHDR home directory drive unicode string header
+
+ UINT16 logon count
+ UINT16 bad password count
+
+ UINT32 User ID
+ UINT32 Group ID
+ UINT32 num groups
+ VOID* undocumented buffer pointer to groups.
+
+ UINT32 user flags
+ char[16] user session key
+
+ UNIHDR logon server unicode string header
+ UNIHDR logon domain unicode string header
+ VOID* undocumented logon domain id pointer
+ char[40] 40 undocumented padding bytes. future expansion?
+
+ UINT32 0 - num_other_sids?
+ VOID* NULL - undocumented pointer to other domain SIDs.
+
+ UNISTR2 username unicode string
+ UNISTR2 user's full name unicode string
+ UNISTR2 logon script unicode string
+ UNISTR2 profile path unicode string
+ UNISTR2 home directory unicode string
+ UNISTR2 home directory drive unicode string
+
+ UINT32 num groups
+ GID[num_groups] group info
+
+ UNISTR2 logon server unicode string
+ UNISTR2 logon domain unicode string
+
+ DOM_SID domain SID
+ DOM_SID[num_sids] other domain SIDs?
+
+- SH_INFO_1_PTR (pointers to level 1 share info strings):
+
+Note: see cifsrap2.txt section5, page 10.
+
+ 0 for shi1_type indicates a Disk.
+ 1 for shi1_type indicates a Print Queue.
+ 2 for shi1_type indicates a Device.
+ 3 for shi1_type indicates an IPC pipe.
+ 0x8000 0000 (top bit set in shi1_type) indicates a hidden share.
+
+ VOID* shi1_netname - pointer to net name
+ UINT32 shi1_type - type of share. 0 - undocumented.
+ VOID* shi1_remark - pointer to comment.
+
+- SH_INFO_1_STR (level 1 share info strings) :
+
+ UNISTR2 shi1_netname - unicode string of net name
+ UNISTR2 shi1_remark - unicode string of comment.
+
+- SHARE_INFO_1_CTR :
+
+ share container with 0 entries:
+
+ UINT32 0 - EntriesRead
+ UINT32 0 - Buffer
+
+ share container with > 0 entries:
+
+ UINT32 EntriesRead
+ UINT32 non-zero - Buffer
+ UINT32 EntriesRead
+
+ SH_INFO_1_PTR[EntriesRead] share entry pointers
+ SH_INFO_1_STR[EntriesRead] share entry strings
+
+ UINT8[] padding to get unicode string 4-byte
+ aligned with start of the SMB header.
+ UINT32 EntriesRead
+ UINT32 0 - padding
+
+- SERVER_INFO_101 :
+
+Note: see cifs6.txt section 6.4 - the fields described therein will be
+ of assistance here. for example, the type listed below is the
+ same as fServerType, which is described in 6.4.1.
+
+ SV_TYPE_WORKSTATION 0x00000001 All workstations
+ SV_TYPE_SERVER 0x00000002 All servers
+ SV_TYPE_SQLSERVER 0x00000004 Any server running with SQL
+ server
+ SV_TYPE_DOMAIN_CTRL 0x00000008 Primary domain controller
+ SV_TYPE_DOMAIN_BAKCTRL 0x00000010 Backup domain controller
+ SV_TYPE_TIME_SOURCE 0x00000020 Server running the timesource
+ service
+ SV_TYPE_AFP 0x00000040 Apple File Protocol servers
+ SV_TYPE_NOVELL 0x00000080 Novell servers
+ SV_TYPE_DOMAIN_MEMBER 0x00000100 Domain Member
+ SV_TYPE_PRINTQ_SERVER 0x00000200 Server sharing print queue
+ SV_TYPE_DIALIN_SERVER 0x00000400 Server running dialin service.
+ SV_TYPE_XENIX_SERVER 0x00000800 Xenix server
+ SV_TYPE_NT 0x00001000 NT server
+ SV_TYPE_WFW 0x00002000 Server running Windows for
+
+ SV_TYPE_SERVER_NT 0x00008000 Windows NT non DC server
+ SV_TYPE_POTENTIAL_BROWSER 0x00010000 Server that can run the browser
+ service
+ SV_TYPE_BACKUP_BROWSER 0x00020000 Backup browser server
+ SV_TYPE_MASTER_BROWSER 0x00040000 Master browser server
+ SV_TYPE_DOMAIN_MASTER 0x00080000 Domain Master Browser server
+ SV_TYPE_LOCAL_LIST_ONLY 0x40000000 Enumerate only entries marked
+ "local"
+ SV_TYPE_DOMAIN_ENUM 0x80000000 Enumerate Domains. The pszServer
+ and pszDomain parameters must be
+ NULL.
+
+ UINT32 500 - platform_id
+ VOID* pointer to name
+ UINT32 5 - major version
+ UINT32 4 - minor version
+ UINT32 type (SV_TYPE_... bit field)
+ VOID* pointer to comment
+
+ UNISTR2 sv101_name - unicode string of server name
+ UNISTR2 sv_101_comment - unicode string of server comment.
+
+ UINT8[] padding to get unicode string 4-byte
+ aligned with start of the SMB header.
+
+
+
+3) MSRPC over Transact Named Pipe
+---------------------------------
+
+For details on the SMB Transact Named Pipe, see cifs6.txt
+
+
+3.1) MSRPC Pipes
+----------------
+
+The MSRPC is conducted over an SMB Transact Pipe with a name of "\PIPE\".
+You must first obtain a 16 bit file handle, by sending a SMBopenX with the
+pipe name "\PIPE\srvsvc" for example. You can then perform an SMB Trans,
+and must carry out an SMBclose on the file handle once you are finished.
+
+Trans Requests must be sent with two setup UINT16s, no UINT16 params (none
+known about), and UINT8 data parameters sufficient to contain the MSRPC
+header, and MSRPC data. The first UINT16 setup parameter must be either
+0x0026 to indicate an RPC, or 0x0001 to indicate Set Named Pipe Handle
+state. The second UINT16 parameter must be the file handle for the pipe,
+obtained above.
+
+The Data section for an API Command of 0x0026 (RPC pipe) in the Trans
+Request is the RPC Header, followed by the RPC Data. The Data section for
+an API Command of 0x0001 (Set Named Pipe Handle state) is two bytes. The
+only value seen for these two bytes is 0x00 0x43.
+
+
+MSRPC Responses are sent as response data inside standard SMB Trans
+responses, with the MSRPC Header, MSRPC Data and MSRPC tail.
+
+
+It is suspected that the Trans Requests will need to be at least 2-byte
+aligned (probably 4-byte). This is standard practice for SMBs. It is also
+independent of the observed 4-byte alignments with the start of the MSRPC
+header, including the 4-byte alignment between the MSRPC header and the
+MSRPC data.
+
+
+First, an SMBtconX connection is made to the IPC$ share. The connection
+must be made using encrypted passwords, not clear-text. Then, an SMBopenX
+is made on the pipe. Then, a Set Named Pipe Handle State must be sent,
+after which the pipe is ready to accept API commands. Lastly, and SMBclose
+is sent.
+
+
+To be resolved:
+
+ lkcl/01nov97 there appear to be two additional bytes after the null-
+ terminated \PIPE\ name for the RPC pipe. Values seen so far are
+ listed below:
+
+ initial SMBopenX request: RPC API command 0x26 params:
+
+ "\\PIPE\\lsarpc" 0x65 0x63; 0x72 0x70; 0x44 0x65;
+ "\\PIPE\\srvsvc" 0x73 0x76; 0x4E 0x00; 0x5C 0x43;
+
+
+3.2) Header
+-----------
+
+[section to be rewritten, following receipt of work by Duncan Stansfield]
+
+
+Interesting note: if you set packed data representation to 0x0100 0000
+then all 4-byte and 2-byte word ordering is turned around!
+
+The start of each of the NTLSA and NETLOGON named pipes begins with:
+
+00 UINT8 5 - RPC major version
+01 UINT8 0 - RPC minor version
+02 UINT8 2 - RPC response packet
+03 UINT8 3 - (FirstFrag bit-wise or with LastFrag)
+04 UINT32 0x1000 0000 - packed data representation
+08 UINT16 fragment length - data size (bytes) inc header and tail.
+0A UINT16 0 - authentication length
+0C UINT32 call identifier. matches 12th UINT32 of incoming RPC data.
+10 UINT32 allocation hint - data size (bytes) minus header and tail.
+14 UINT16 0 - presentation context identifier
+16 UINT8 0 - cancel count
+17 UINT8 in replies: 0 - reserved; in requests: opnum - see #defines.
+18 ...... start of data (goes on for allocation_hint bytes)
+
+
+RPC_Packet for request, response, bind and bind acknowledgement.
+{
+
+ UINT8 versionmaj # reply same as request (0x05)
+ UINT8 versionmin # reply same as request (0x00)
+ UINT8 type # one of the MSRPC_Type enums
+ UINT8 flags # reply same as request (0x00 for Bind, 0x03 for Request)
+ UINT32 representation # reply same as request (0x00000010)
+ UINT16 fraglength # the length of the data section of the SMB trans packet
+ UINT16 authlength
+ UINT32 callid # call identifier. (e.g. 0x00149594)
+
+ * stub USE TvPacket # the remainder of the packet depending on the "type"
+}
+
+
+# the interfaces are numbered. as yet I haven't seen more than one interface
+# used on the same pipe name
+# srvsvc
+# abstract (0x4B324FC8, 0x01D31670, 0x475A7812, 0x88E16EBF, 0x00000003)
+# transfer (0x8A885D04, 0x11C91CEB, 0x0008E89F, 0x6048102B, 0x00000002)
+RPC_Iface RW
+{
+ UINT8 byte[16] # 16 bytes of number
+ UINT32 version # the interface number
+}
+
+
+# the remainder of the packet after the header if "type" was Bind
+# in the response header, "type" should be BindAck
+RPC_ReqBind RW
+{
+ UINT16 maxtsize # maximum transmission fragment size (0x1630)
+ UINT16 maxrsize # max receive fragment size (0x1630)
+ UINT32 assocgid # associated group id (0x0)
+ UINT32 numelements # the number of elements (0x1)
+ UINT16 contextid # presentation context identifier (0x0)
+ UINT8 numsyntaxes # the number of syntaxes (has always been 1?)(0x1)
+ UINT8[] # 4-byte alignment padding, against SMB header
+
+ * abstractint USE RPC_Iface # num and vers. of interface client is using
+ * transferint USE RPC_Iface # num and vers. of interface to use for replies
+}
+
+
+RPC_Address RW
+{
+ UINT16 length # length of the string including null terminator
+ * port USE string # the string above in single byte, null terminated form
+}
+
+
+# the response to place after the header in the reply packet
+RPC_ResBind RW
+{
+ UINT16 maxtsize # same as request
+ UINT16 maxrsize # same as request
+ UINT32 assocgid # zero
+
+ * secondaddr USE RPC_Address # the address string, as described earlier
+
+ UINT8[] # 4-byte alignment padding, against SMB header
+
+ UINT8 numresults # the number of results (0x01)
+
+ UINT8[] # 4-byte alignment padding, against SMB header
+ UINT16 result # result (0x00 = accept)
+ UINT16 reason # reason (0x00 = no reason specified)
+
+ * transfersyntax USE RPC_Iface # the transfer syntax from the request
+}
+
+
+# the remainder of the packet after the header for every other other
+# request
+RPC_ReqNorm RW
+{
+ UINT32 allochint # the size of the stub data in bytes
+ UINT16 prescontext # presentation context identifier (0x0)
+ UINT16 opnum # operation number (0x15)
+
+ * stub USE TvPacket # a packet dependent on the pipe name
+ # (probably the interface) and the op number)
+}
+
+
+# response to a request
+RPC_ResNorm RW
+{
+ UINT32 allochint # size of the stub data in bytes
+ UINT16 prescontext # presentation context identifier (same as request)
+ UINT8 cancelcount # cancel count? (0x0)
+ UINT8 reserved # 0 - one byte padding
+
+ * stub USE TvPacket # the remainder of the reply
+}
+
+
+3.3) Tail
+---------
+
+The end of each of the NTLSA and NETLOGON named pipes ends with:
+
+ ...... end of data
+ UINT32 return code
+
+
+
+3.4 RPC Bind / Bind Ack
+-----------------------
+
+RPC Binds are the process of associating an RPC pipe (e.g \PIPE\lsarpc)
+with a "transfer syntax" (see RPC_Iface structure). The purpose for doing
+this is unknown.
+
+Note: The RPC_ResBind SMB Transact request is sent with two uint16 setup
+ parameters. The first is 0x0026; the second is the file handle
+ returned by the SMBopenX Transact response.
+
+Note: The RPC_ResBind members maxtsize, maxrsize and assocgid are the
+ same in the response as the same members in the RPC_ReqBind. The
+ RPC_ResBind member transfersyntax is the same in the response as
+ the
+
+Note: The RPC_ResBind response member secondaddr contains the name
+ of what is presumed to be the service behind the RPC pipe. The
+ mapping identified so far is:
+
+ initial SMBopenX request: RPC_ResBind response:
+
+ "\\PIPE\\srvsvc" "\\PIPE\\ntsvcs"
+ "\\PIPE\\samr" "\\PIPE\\lsass"
+ "\\PIPE\\lsarpc" "\\PIPE\\lsass"
+ "\\PIPE\\wkssvc" "\\PIPE\\wksvcs"
+ "\\PIPE\\NETLOGON" "\\PIPE\\NETLOGON"
+
+Note: The RPC_Packet fraglength member in both the Bind Request and Bind
+ Acknowledgment must contain the length of the entire RPC data,
+ including the RPC_Packet header.
+
+Request:
+
+ RPC_Packet
+ RPC_ReqBind
+
+Response:
+
+ RPC_Packet
+ RPC_ResBind
+
+
+
+4) NTLSA Transact Named Pipe
+----------------------------
+
+The sequence of actions taken on this pipe are:
+
+- Establish a connection to the IPC$ share (SMBtconX). use encrypted passwords.
+- Open an RPC Pipe with the name "\\PIPE\\lsarpc". Store the file handle.
+- Using the file handle, send a Set Named Pipe Handle state to 0x4300.
+- Send an LSA Open Policy request. Store the Policy Handle.
+- Using the Policy Handle, send LSA Query Info Policy requests, etc.
+- Using the Policy Handle, send an LSA Close.
+- Close the IPC$ share.
+
+
+Defines for this pipe, identifying the query are:
+
+- LSA Open Policy: 0x2c
+- LSA Query Info Policy: 0x07
+- LSA Enumerate Trusted Domains: 0x0d
+- LSA Open Secret: 0xff
+- LSA Lookup SIDs: 0xfe
+- LSA Lookup Names: 0xfd
+- LSA Close: 0x00
+
+
+4.1) LSA Open Policy
+--------------------
+
+Note: The policy handle can be anything you like.
+
+Request:
+
+ VOID* buffer pointer
+ UNISTR2 server name - unicode string starting with two '\'s
+ OBJ_ATTR object attributes
+ UINT32 1 - desired access
+
+Response:
+
+ POL_HND LSA policy handle
+
+ return 0 - indicates success
+
+
+4.2) LSA Query Info Policy
+--------------------------
+
+Note: The info class in response must be the same as that in the request.
+
+Request:
+
+ POL_HND LSA policy handle
+ UINT16 info class (also a policy handle?)
+
+Response:
+
+ VOID* undocumented buffer pointer
+ UINT16 info class (same as info class in request).
+
+ switch (info class)
+ case 3:
+ case 5:
+ {
+ DOM_INFO domain info, levels 3 and 5 (are the same).
+ }
+
+ return 0 - indicates success
+
+
+4.3) LSA Enumerate Trusted Domains
+----------------------------------
+
+Request:
+
+ no extra data
+
+Response:
+
+ UINT32 0 - enumeration context
+ UINT32 0 - entries read
+ UINT32 0 - trust information
+
+ return 0x8000 001a - "no trusted domains" success code
+
+
+4.4) LSA Open Secret
+--------------------
+
+Request:
+
+ no extra data
+
+Response:
+
+ UINT32 0 - undocumented
+ UINT32 0 - undocumented
+ UINT32 0 - undocumented
+ UINT32 0 - undocumented
+ UINT32 0 - undocumented
+
+ return 0x0C00 0034 - "no such secret" success code
+
+
+4.5) LSA Close
+--------------
+
+Request:
+
+ POL_HND policy handle to be closed
+
+Response:
+
+ POL_HND 0s - closed policy handle (all zeros)
+
+ return 0 - indicates success
+
+
+4.6) LSA Lookup SIDS
+--------------------
+
+Note: num_entries in response must be same as num_entries in request.
+
+Request:
+
+ POL_HND LSA policy handle
+ UINT32 num_entries
+ VOID* undocumented domain SID buffer pointer
+ VOID* undocumented domain name buffer pointer
+ VOID*[num_entries] undocumented domain SID pointers to be looked up.
+ DOM_SID[num_entries] domain SIDs to be looked up.
+ char[16] completely undocumented 16 bytes.
+
+Response:
+
+ DOM_REF domain reference response
+
+ UINT32 num_entries (listed above)
+ VOID* undocumented buffer pointer
+
+ UINT32 num_entries (listed above)
+ DOM_SID2[num_entries] domain SIDs (from Request, listed above).
+
+ UINT32 num_entries (listed above)
+
+ return 0 - indicates success
+
+
+4.7) LSA Lookup Names
+---------------------
+
+Note: num_entries in response must be same as num_entries in request.
+
+Request:
+
+ POL_HND LSA policy handle
+ UINT32 num_entries
+ UINT32 num_entries
+ VOID* undocumented domain SID buffer pointer
+ VOID* undocumented domain name buffer pointer
+ NAME[num_entries] names to be looked up.
+ char[] undocumented bytes - falsely translated SID structure?
+
+Response:
+
+ DOM_REF domain reference response
+
+ UINT32 num_entries (listed above)
+ VOID* undocumented buffer pointer
+
+ UINT32 num_entries (listed above)
+ DOM_RID[num_entries] domain SIDs (from Request, listed above).
+
+ UINT32 num_entries (listed above)
+
+ return 0 - indicates success
+
+
+
+5) NETLOGON rpc Transact Named Pipe
+-----------------------------------
+
+The sequence of actions taken on this pipe are:
+
+- Establish a connection to the IPC$ share (SMBtconX). use encrypted passwords.
+- Open an RPC Pipe with the name "\\PIPE\\NETLOGON". Store the file handle.
+- Using the file handle, send a Set Named Pipe Handle state to 0x4300.
+- Create Client Challenge. Send LSA Request Challenge. Store Server Challenge.
+- Calculate Session Key. Send an LSA Auth 2 Challenge. Store Auth2 Challenge.
+- Calc/Verify Client Creds. Send LSA Srv PW Set. Calc/Verify Server Creds.
+- Calc/Verify Client Creds. Send LSA SAM Logon . Calc/Verify Server Creds.
+- Calc/Verify Client Creds. Send LSA SAM Logoff. Calc/Verify Server Creds.
+- Close the IPC$ share.
+
+
+Defines for this pipe, identifying the query are:
+
+- LSA Request Challenge: 0x04
+- LSA Server Password Set: 0x06
+- LSA SAM Logon: 0x02
+- LSA SAM Logoff: 0x03
+- LSA Auth 2: 0x0f
+- LSA Logon Control: 0x0e
+
+
+5.1) LSA Request Challenge
+--------------------------
+
+Note: logon server name starts with two '\' characters and is upper case.
+
+Note: logon client is the machine, not the user.
+
+Note: the initial LanManager password hash, against which the challenge
+ is issued, is the machine name itself (lower case). there will be
+ calls issued (LSA Server Password Set) which will change this, later.
+ refusing these calls allows you to always deal with the same password
+ (i.e the LM# of the machine name in lower case).
+
+Request:
+
+ VOID* undocumented buffer pointer
+ UNISTR2 logon server unicode string
+ UNISTR2 logon client unicode string
+ char[8] client challenge
+
+Response:
+
+ char[8] server challenge
+
+ return 0 - indicates success
+
+
+
+5.2) LSA Authenticate 2
+-----------------------
+
+Note: in between request and response, calculate the client credentials,
+ and check them against the client-calculated credentials (this
+ process uses the previously received client credentials).
+
+Note: neg_flags in the response is the same as that in the request.
+
+Note: you must take a copy of the client-calculated credentials received
+ here, because they will be used in subsequent authentication packets.
+
+Request:
+
+ LOG_INFO client identification info
+
+ char[8] client-calculated credentials
+ UINT8[] padding to 4-byte align with start of SMB header.
+ UINT32 neg_flags - negotiated flags (usual value is 0x0000 01ff)
+
+Response:
+
+ char[8] server credentials.
+ UINT32 neg_flags - same as neg_flags in request.
+
+ return 0 - indicates success. failure value unknown.
+
+
+5.3) LSA Server Password Set
+----------------------------
+
+Note: the new password is suspected to be a DES encryption using the old
+ password to generate the key.
+
+Note: in between request and response, calculate the client credentials,
+ and check them against the client-calculated credentials (this
+ process uses the previously received client credentials).
+
+Note: the server credentials are constructed from the client-calculated
+ credentials and the client time + 1 second.
+
+Note: you must take a copy of the client-calculated credentials received
+ here, because they will be used in subsequent authentication packets.
+
+Request:
+
+ CLNT_INFO client identification/authentication info
+ char[] new password - undocumented.
+
+Response:
+
+ CREDS server credentials. server time stamp appears to be ignored.
+
+ return 0 - indicates success; 0xC000 006a indicates failure
+
+
+5.4) LSA SAM Logon
+------------------
+
+Note: valid_user is True iff the username and password hash are valid for
+ the requested domain.
+
+Request:
+
+ SAM_INFO sam_id structure
+
+Response:
+
+ VOID* undocumented buffer pointer
+ CREDS server credentials. server time stamp appears to be ignored.
+
+ if (valid_user)
+ {
+ UINT16 3 - switch value indicating USER_INFO structure.
+ VOID* non-zero - pointer to USER_INFO structure
+ USER_INFO user logon information
+
+ UINT32 1 - Authoritative response; 0 - Non-Auth?
+
+ return 0 - indicates success
+ }
+ else
+ {
+ UINT16 0 - switch value. value to indicate no user presumed.
+ VOID* 0x0000 0000 - indicates no USER_INFO structure.
+
+ UINT32 1 - Authoritative response; 0 - Non-Auth?
+
+ return 0xC000 0064 - NT_STATUS_NO_SUCH_USER.
+ }
+
+
+5.5) LSA SAM Logoff
+--------------------
+
+Note: presumably, the SAM_INFO structure is validated, and a (currently
+ undocumented) error code returned if the Logoff is invalid.
+
+Request:
+
+ SAM_INFO sam_id structure
+
+Response:
+
+ VOID* undocumented buffer pointer
+ CREDS server credentials. server time stamp appears to be ignored.
+
+ return 0 - indicates success. undocumented failure indication.
+
+
+6) \\MAILSLOT\NET\NTLOGON
+-------------------------
+
+Note: mailslots will contain a response mailslot, to which the response
+ should be sent. the target NetBIOS name is REQUEST_NAME<20>, where
+ REQUEST_NAME is the name of the machine that sent the request.
+
+
+6.1) Query for PDC
+------------------
+
+Note: NTversion, LMNTtoken, LM20token in response are the same as those
+ given in the request.
+
+Request:
+
+ UINT16 0x0007 - Query for PDC
+ STR machine name
+ STR response mailslot
+ UINT8[] padding to 2-byte align with start of mailslot.
+ UNISTR machine name
+ UINT32 NTversion
+ UINT16 LMNTtoken
+ UINT16 LM20token
+
+Response:
+
+ UINT16 0x000A - Respose to Query for PDC
+ STR machine name (in uppercase)
+ UINT8[] padding to 2-byte align with start of mailslot.
+ UNISTR machine name
+ UNISTR domain name
+ UINT32 NTversion (same as received in request)
+ UINT16 LMNTtoken (same as received in request)
+ UINT16 LM20token (same as received in request)
+
+
+6.2) SAM Logon
+--------------
+
+Note: machine name in response is preceded by two '\' characters.
+
+Note: NTversion, LMNTtoken, LM20token in response are the same as those
+ given in the request.
+
+Note: user name in the response is presumably the same as that in the request.
+
+Request:
+
+ UINT16 0x0012 - SAM Logon
+ UINT16 request count
+ UNISTR machine name
+ UNISTR user name
+ STR response mailslot
+ UINT32 alloweable account
+ UINT32 domain SID size
+ char[sid_size] domain SID, of sid_size bytes.
+ UINT8[] ???? padding to 4? 2? -byte align with start of mailslot.
+ UINT32 NTversion
+ UINT16 LMNTtoken
+ UINT16 LM20token
+
+Response:
+
+ UINT16 0x0013 - Response to SAM Logon
+ UNISTR machine name
+ UNISTR user name - workstation trust account
+ UNISTR domain name
+ UINT32 NTversion
+ UINT16 LMNTtoken
+ UINT16 LM20token
+
+
+
+7) SRVSVC Transact Named Pipe
+-----------------------------
+
+
+Defines for this pipe, identifying the query are:
+
+- Net Share Enum : 0x0f
+- Net Server Get Info : 0x15
+
+
+7.1) Net Share Enum
+------------------
+
+Note: share level and switch value in the response are presumably the
+ same as those in the request.
+
+Note: cifsrap2.txt (section 5) may be of limited assistance here.
+
+Request:
+
+ VOID* pointer (to server name?)
+ UNISTR2 server name
+
+ UINT8[] padding to get unicode string 4-byte aligned
+ with the start of the SMB header.
+
+ UINT32 share level
+ UINT32 switch value
+
+ VOID* pointer to SHARE_INFO_1_CTR
+ SHARE_INFO_1_CTR share info with 0 entries
+
+ UINT32 preferred maximum length (0xffff ffff)
+
+Response:
+
+ UINT32 share level
+ UINT32 switch value
+
+ VOID* pointer to SHARE_INFO_1_CTR
+ SHARE_INFO_1_CTR share info (only added if share info ptr is non-zero)
+
+ return 0 - indicates success
+
+
+7.2) Net Server Get Info
+------------------
+
+Note: level is the same value as in the request.
+
+Request:
+
+ UNISTR2 server name
+ UINT32 switch level
+
+Response:
+
+ UINT32 switch level
+ VOID* pointer to SERVER_INFO_101
+
+ SERVER_INFO_101 server info (only added if server info ptr is non-zero)
+
+ return 0 - indicates success
+
+
+
+Appendix
+--------
+
+A1) Cryptographic side of NT Domain Authentication
+--------------------------------------------------
+
+
+A1.1) Definitions
+-----------------
+
+Add(A1,A2): Intel byte ordered addition of corresponding 4 byte words
+in arrays A1 and A2
+
+E(K,D): DES ECB encryption of 8 byte data D using 7 byte key K
+
+lmowf(): Lan man hash
+
+ntowf(): NT hash
+
+PW: md4(machine_password) == md4(lsadump $machine.acc) ==
+pwdump(machine$) (initially) == md4(lmowf(unicode(machine)))
+
+ARC4(K,Lk,D,Ld): ARC4 encryption of data D of length Ld with key K of
+length Lk
+
+v[m..n(,l)]: subset of v from bytes m to n, optionally padded with
+zeroes to length l
+
+Cred(K,D): E(K[7..7,7],E(K[0..6],D)) computes a credential
+
+Time(): 4 byte current time
+
+Cc,Cs: 8 byte client and server challenges Rc,Rs: 8 byte client and
+server credentials
+
+
+A1.2) Protocol
+--------------
+
+C->S ReqChal,Cc S->C Cs
+
+C & S compute session key Ks = E(PW[9..15],E(PW[0..6],Add(Cc,Cs)))
+
+C: Rc = Cred(Ks,Cc) C->S Authenticate,Rc S: Rs = Cred(Ks,Cs),
+assert(Rc == Cred(Ks,Cc)) S->C Rs C: assert(Rs == Cred(Ks,Cs))
+
+On joining the domain the client will optionally attempt to change its
+password and the domain controller may refuse to update it depending
+on registry settings. This will also occur weekly afterwards.
+
+C: Tc = Time(), Rc' = Cred(Ks,Rc+Tc) C->S ServerPasswordSet,Rc',Tc,
+arc4(Ks[0..7,16],lmowf(randompassword()) C: Rc = Cred(Ks,Rc+Tc+1) S:
+assert(Rc' == Cred(Ks,Rc+Tc)), Ts = Time() S: Rs' = Cred(Ks,Rs+Tc+1)
+S->C Rs',Ts C: assert(Rs' == Cred(Ks,Rs+Tc+1)) S: Rs = Rs'
+
+User: U with password P wishes to login to the domain (incidental data
+such as workstation and domain omitted)
+
+C: Tc = Time(), Rc' = Cred(Ks,Rc+Tc) C->S NetLogonSamLogon,Rc',Tc,U,
+arc4(Ks[0..7,16],16,ntowf(P),16), arc4(Ks[0..7,16],16,lmowf(P),16) S:
+assert(Rc' == Cred(Ks,Rc+Tc)) assert(passwords match those in SAM) S:
+Ts = Time()
+
+S->C Cred(Ks,Cred(Ks,Rc+Tc+1)),userinfo(logon script,UID,SIDs,etc) C:
+assert(Rs == Cred(Ks,Cred(Rc+Tc+1)) C: Rc = Cred(Ks,Rc+Tc+1)
+
+
+A1.3) Comments
+--------------
+
+On first joining the domain the session key could be computed by
+anyone listening in on the network as the machine password has a well
+known value. Until the machine is rebooted it will use this session
+key to encrypt NT and LM one way functions of passwords which are
+password equivalents. Any user who logs in before the machine has been
+rebooted a second time will have their password equivalent exposed. Of
+course the new machine password is exposed at this time anyway.
+
+None of the returned user info such as logon script, profile path and
+SIDs *appear* to be protected by anything other than the TCP checksum.
+
+The server time stamps appear to be ignored.
+
+The client sends a ReturnAuthenticator in the SamLogon request which I
+can't find a use for. However its time is used as the timestamp
+returned by the server.
+
+The password OWFs should NOT be sent over the network reversibly
+encrypted. They should be sent using ARC4(Ks,md4(owf)) with the server
+computing the same function using the owf values in the SAM.
+
+
+A2) SIDs and RIDs
+-----------------
+
+SIDs and RIDs are well documented elsewhere.
+
+A SID is an NT Security ID (see DOM_SID structure). They are of the form:
+
+ S-revision-NN-SubAuth1-SubAuth2-SubAuth3...
+ S-revision-0xNNNNNNNNNNNN-SubAuth1-SubAuth2-SubAuth3...
+
+currently, the SID revision is 1.
+The Sub-Authorities are known as Relative IDs (RIDs).
+
+
+A2.1) Well-known SIDs
+---------------------
+
+
+A2.1.1) Universal well-known SIDs
+---------------------------------
+
+ Null SID S-1-0-0
+ World S-1-1-0
+ Local S-1-2-0
+ Creator Owner ID S-1-3-0
+ Creator Group ID S-1-3-1
+ Creator Owner Server ID S-1-3-2
+ Creator Group Server ID S-1-3-3
+
+ (Non-unique IDs) S-1-4
+
+
+A2.1.2) NT well-known SIDs
+--------------------------
+
+ NT Authority S-1-5
+ Dialup S-1-5-1
+
+ Network S-1-5-2
+ Batch S-1-5-3
+ Interactive S-1-5-4
+ Service S-1-5-6
+ AnonymousLogon S-1-5-7 (aka null logon session)
+ Proxy S-1-5-8
+ ServerLogon S-1-5-8 (aka domain controller account)
+
+ (Logon IDs) S-1-5-5-X-Y
+
+ (NT non-unique IDs) S-1-5-0x15-...
+
+ (Built-in domain) s-1-5-0x20
+
+
+
+A2.2) Well-known RIDS
+---------------------
+
+A RID is a sub-authority value, as part of either a SID, or in the case
+of Group RIDs, part of the DOM_GID structure, in the USER_INFO_1
+structure, in the LSA SAM Logon response.
+
+
+A2.2.1) Well-known RID users
+----------------------------
+
+ DOMAIN_USER_RID_ADMIN 0x0000 01F4
+ DOMAIN_USER_RID_GUEST 0x0000 01F5
+
+
+
+A2.2.2) Well-known RID groups
+----------------------------
+
+ DOMAIN_GROUP_RID_ADMINS 0x0000 0200
+ DOMAIN_GROUP_RID_USERS 0x0000 0201
+ DOMAIN_GROUP_RID_GUESTS 0x0000 0202
+
+
+
+A2.2.3) Well-known RID aliases
+------------------------------
+
+ DOMAIN_ALIAS_RID_ADMINS 0x0000 0220
+ DOMAIN_ALIAS_RID_USERS 0x0000 0221
+ DOMAIN_ALIAS_RID_GUESTS 0x0000 0222
+ DOMAIN_ALIAS_RID_POWER_USERS 0x0000 0223
+
+ DOMAIN_ALIAS_RID_ACCOUNT_OPS 0x0000 0224
+ DOMAIN_ALIAS_RID_SYSTEM_OPS 0x0000 0225
+ DOMAIN_ALIAS_RID_PRINT_OPS 0x0000 0226
+ DOMAIN_ALIAS_RID_BACKUP_OPS 0x0000 0227
+
+ DOMAIN_ALIAS_RID_REPLICATOR 0x0000 0228
+
+
diff --git a/docs/textdocs/outdated/NTDOMAIN.txt b/docs/textdocs/outdated/NTDOMAIN.txt
new file mode 100755
index 00000000000..20510519462
--- /dev/null
+++ b/docs/textdocs/outdated/NTDOMAIN.txt
@@ -0,0 +1,51 @@
+!==
+!== NTDOMAIN.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Luke Kenneth Casson Leighton (samba@samba.org)
+ Copyright (C) 1997 Luke Kenneth Casson Leighton
+Created: October 20, 1997
+Updated: February 25, 1999 (Jerry Carter)
+
+Subject: NT Domain Logons
+===========================================================================
+
+As of 1.9.18alpha1, Samba supports logins for NT 3.51 and 4.0 Workstations,
+without the need, use or intervention of NT Server. This document describes
+how to set this up. Over the continued development of the 1.9.18alpha
+series, this process (and therefore this document) should become simpler.
+
+One useful thing to do is to get this version of Samba up and running
+with Win95 profiles, as you would for the current stable version of
+Samba (currently at 1.9.17p4), and is fully documented. You will need
+to set up encrypted passwords. Even if you don't have any Win95 machines,
+using your Samba Server to store the profile for one of your NT Workstation
+users is a good test that you have 1.9.18alpha1 correctly configured *prior*
+to attempting NT Domain Logons.
+
+The support is still experimental, so should be used at your own risk.
+
+NT is not as robust as you might have been led to believe: during the
+development of the Domain Logon Support, one person reported having to
+reinstall NT from scratch: their workstation had become totally unuseable.
+
+[further reports on ntsec@iss.net by independent administrators showing
+ similar symptoms lead us to believe that the SAM database file may be
+ corruptible. this _is_ recoverable (or, at least the machine is accessible),
+ by deleting the SAM file, under which circumstances all user account details
+ are lost, but at least the Administrator can log in with a blank password.
+ this is *not* possible except if the NT system is installed in a FAT
+ partition.]
+
+This *has* been reported to the NTBUGTRAQ@LISTSERV.NTBUGTRAQ.COM digest.
+
+==========================================================================
+Please note that Samba 2.0 does not **officially** support domain logons
+for Windows NT clients. Of course, domain logon support for Windows 9x
+clients is complete and official. These are two different issues.
+
+Samba's capability to act as a Primary Domain Controller for Windows NT
+domains is not advertised as it is not completed yet. For more information
+regarding how to obtain the latest development (HEAD branch) source code
+and what features are available, please refer to the NT Domain FAQ on-line
+at the Samba web site under the documentation page.
+
diff --git a/docs/textdocs/outdated/PRINTER_DRIVER.txt b/docs/textdocs/outdated/PRINTER_DRIVER.txt
new file mode 100755
index 00000000000..c8bfd7c7a4d
--- /dev/null
+++ b/docs/textdocs/outdated/PRINTER_DRIVER.txt
@@ -0,0 +1,240 @@
+!==
+!== PRINTER_DRIVER.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+==========================================================================
+ Supporting the famous PRINTER$ share
+
+ Jean-Francois.Micouleau@utc.fr, 10/26/97
+ modified by herb@sgi.com 1/2/98
+
+===========================================================================
+
+Disclaimer:
+
+ This ONLY works with Windows 95
+ It does NOT work with Windows NT 4
+
+
+Goal:
+
+ When you click on a samba shared printer, you can now install the driver
+ automatically onto the Windows 95 machine, as you would from an NT server.
+
+How To:
+
+ It's a three step config.
+
+ First, create a new directory, where you will put the driver files, and
+ make a share in smb.conf pointing to it.
+
+ Example:
+
+ [printer$]
+ path=/usr/local/samba/printer
+ public=yes
+ writable=no
+ browseable=yes
+
+ Second, you have to build the list of drivers required for a specific
+ printer. This is the most complicated thing to do. Get the files
+ 'msprint.inf' and 'msprint2.inf' from Windows 95, the easiest way is to
+ grab them from a working Windows 95 computer. They are usually located
+ in 'c:\windows\inf'. Look in them for the printer you have. Run the new
+ program 'make_printerdef' with the file name and the printer name as
+ parameters. If you have drivers for an unsupported or updated printer,
+ first install these drivers on an Windows 95 system. There will be a
+ file created in your inf directory named 'oem?.inf' (where the ? is some
+ number). Use this file instead of msprint.inf.
+
+ Example: (from the /usr/local/samba/lib directory)
+
+ make_printerdef msprint.inf "Apple LaserWriter" >> printers.def
+
+ The program will print out a list of required files to stderr.
+ Copy all the files listed into the directory you created in step 1.
+ If you have "preserve case = yes" make sure your files names match
+ EXACTLY the names listed.
+
+ Third, you need to add 2 new parameters in smb.conf. One is in the
+ [global] section, called 'printer driver file' pointing to the printer
+ description file you just created, and the other in each printer share,
+ called 'printer driver location' pointing to where the client will get
+ the drivers. Don't forget to set correctly the printer driver parameter
+ to the Windows printer name.
+
+ Example:
+
+ [global]
+ printer driver file=/usr/local/samba/lib/printers.def
+
+ [lp]
+ comment = My old printer laser
+ browseable = yes
+ printable = yes
+ public = yes
+ writable = no
+ create mode = 0700
+ printer driver=Apple LaserWriter
+ printer driver location=\\%h\PRINTER$
+
+ %h will expand to the computer name, and PRINTER$ is the name of the
+ share created in step one.
+
+
+If it doesn't work for you, don't send flame ! It worked for me. In case of
+trouble don't hesitate to send me a mail with your smb.conf file and
+printers.def
+
+
+******* added by herb@sgi.com
+
+For those of you who like to know the details, and in case I have guessed
+wrong on some of the fields - The following is the format of the entries
+in the printers.def file: (entries are 1 single line - they are split here
+for readability)
+
+<Long Printer Name>:<Driver File Name>:<Data File Name>:<Help File Name>:
+<Language Monitor Name>:<Default Data Type>:<Comma Separated list of Files>
+
+The <Help File Name> and the <Language Monitor Name> can be empty.
+If no <Driver File Name> or <Data File Name> are specified in the inf file,
+these will default to the section name for the printer.
+
+The following is an excerpt from the MSPRINT2.INF file on a WIN95 machine.
+I have deleted all but the entries relating to installing a driver for the
+"QMS ColorScript 100 Model 30" printer. Using this "file" I'll try to
+explain how the printers.def file is created.
+
+make_printerdef is run with the first argument being the name of this
+file (MSPRINT2.INF in this case) and the second argument being the
+name of the printer ("QMS ColorScript 100 Model 30" in this case).
+
+The printer name is first found in the "Model section" to obtain the
+name of the "Installer Section" (this is the name after the equal sign).
+We ignore the alternate name.
+
+The "Installer Section" contains entries for "CopyFiles" and "DataSection".
+The "CopyFiles" line gives a list of all the required files for this
+printer. If the name begins with an @ it is the name of a file (after
+you strip off the @), otherwise it is the name of a "Copy Section" which
+in turn is a list of files required. This printer has one file listed
+"QCS30503.SPD" and two sections "COLOR_QMS_100_30" and "PSCRIPT". The
+"COLOR_QMS_100_30" section is listed in the "[DestinationDirs]" as
+having a value of 23. This means that all files listed in this section
+should go into the "color" subdirectory. The list of files to copy for
+this printer is thus:
+
+QCS30503.SPD,color\QMS10030.ICM,PSCRIPT.DRV,PSCRIPT.HLP,PSCRIPT.INI,
+TESTPS.TXT,APPLE380.SPD,FONTS.MFM,ICONLIB.DLL,PSMON.DLL
+
+From the "Data Section" we obtain values for "DriverFile", "HelpFile",
+and "LanguageMonitor". The % around the value for "LanguageMonitor"
+indicates that it is a string that can be localized so its actual value
+is obtained from the "[Strings]" section. The "Data Section" could also
+have contained an entry for "DefaultDataType".
+
+Using the information we have obtained we can now construct the entry
+for the printers.def file.
+
+<Long Printer Name> -> QMS ColorScript 100 Model 30 (name given
+ on the command line)
+<Driver File Name> -> PSCRIPT.DRV (given in Data Section)
+<Data File Name> -> QCS30503.SPD (defaults to Install Section name)
+<Help File Name> -> PSCRIPT.HLP (given in Data Section)
+<Language Monitor Name> -> PostScript Language Monitor (given in Data Section)
+<Default Data Type> -> RAW (default if not specified)
+
+
+So.... the enty (actually one line but split here for readability) would
+be:
+
+QMS ColorScript 100 Model 30:PSCRIPT.DRV:QCS30503.SPD:
+PSCRIPT.HLP:PostScript Language Monitor:RAW:
+QCS30503.SPD,color\QMS10030.ICM,PSCRIPT.DRV,PSCRIPT.HLP,PSCRIPT.INI,
+TESTPS.TXT,APPLE380.SPD,FONTS.MFM,ICONLIB.DLL,PSMON.DLL
+
+---------------------- Info from MSPRINT2.INF ------------------------
+;
+; The Manufacturer section lists all of the manufacturers that we will
+; display in the Dialog box
+
+[Manufacturer]
+"QMS"
+
+
+;
+; Model sections. Each section here corresponds with an entry listed in the
+; [Manufacturer] section, above. The models will be displayed in the order
+; that they appear in the INF file.
+;
+; Each model lists a variation of its own name as a compatible ID. This
+; is done primarily as an optimization during upgrade.
+;
+[QMS]
+"QMS ColorScript 100 Model 30" = QCS30503.SPD,QMS_ColorScript_100_Model_30
+
+
+;
+; Installer Sections
+;
+; These sections control file installation, and reference all files that
+; need to be copied. The section name will be assumed to be the driver
+; file, unless there is an explicit DriverFile section listed.
+;
+[QCS30503.SPD]
+CopyFiles=@QCS30503.SPD,COLOR_QMS_100_30,PSCRIPT
+DataSection=PSCRIPT_DATA
+
+; Copy Sections
+;
+; Lists of files that are actually copied. These sections are referenced
+; from the installer sections, above. Only create a section if it contains
+; two or more files (if we only copy a single file, identify it in the
+; installer section, using the @filename notation) or if it's a color
+; profile (since the DestinationDirs can only handle sections, and not
+; individual files).
+;
+[COLOR_QMS_100_30]
+QMS10030.ICM
+
+[PSCRIPT]
+PSCRIPT.DRV
+PSCRIPT.HLP
+PSCRIPT.INI
+TESTPS.TXT
+APPLE380.SPD
+FONTS.MFM
+ICONLIB.DLL
+PSMON.DLL
+
+
+;
+; Data Sections
+;
+; These sections contain data that is shared between devices.
+;
+[PSCRIPT_DATA]
+DriverFile=PSCRIPT.DRV
+HelpFile=PSCRIPT.HLP
+LanguageMonitor=%PS_MONITOR%
+
+
+;
+; Color profiles go to the colors directory. All other files go to the
+; system directory
+;
+
+[DestinationDirs]
+DefaultDestDir=11
+COLOR_QMS_100_30=23
+COLOR_TEKTRONIX_200I=23
+COLOR_TEKTRONIX_III_PXI=23
+
+
+;
+; Localizable Strings
+;
+[Strings]
+MS="Microsoft"
+PS_MONITOR="PostScript Language Monitor,PSMON.DLL"
+
diff --git a/docs/textdocs/outdated/PROJECTS b/docs/textdocs/outdated/PROJECTS
new file mode 100755
index 00000000000..b962b503f2e
--- /dev/null
+++ b/docs/textdocs/outdated/PROJECTS
@@ -0,0 +1,88 @@
+ Samba Projects Directory
+ ========================
+
+
+>>>>> NOTE: THIS FILE IS NOW VERY OUT OF DATE <<<<<
+
+
+This is a list of who's working on what in Samba. It's not guaranteed
+to be uptodate or accurate but I hope it will help us getting
+coordinated.
+
+If you are working on something to do with Samba and you aren't here
+then please let me know! Also, if you are listed below and you have
+any corrections or updates then please let me know.
+
+Email contact:
+samba@samba.org
+
+========================================================================
+Documentation and FAQ
+
+Docs and FAQ files for the Samba suite of software.
+
+Contact samba@samba.org with the diffs. These are urgently
+required.
+
+The FAQ is being added to on an ad hoc basis, see the web pages for info.
+
+Mark Preston was working on a set of formatted docs for Samba. Is this
+still happening? Contact mpreston@sghms.ac.uk
+
+Status last updated 2nd October 1996
+========================================================================
+
+========================================================================
+Netbeui support
+
+This aimed to produce patches so that Samba can be used with clients
+that do not have TCP/IP. It will try to remain as portable as possible.
+Contact Brian.Onn@Canada.Sun.COM (Brian Onn) Unfortunately it died, and
+although a lot of people have expressed interest nobody has come forward
+to do it. The Novell port (see Samba web pages) includes NetBEUI
+functionality in a proprietrary library which should still be helpful as
+we have the interfaces. Alan Cox (a.cox@li.org) has the information
+required to write the state machine if someone is going to do the work.
+
+Status last updated 2nd October 1996
+========================================================================
+
+========================================================================
+Smbfs
+
+A mountable smb filesystem for Linux using the userfs userspace filesystem
+
+Contact lendecke@namu01.gwdg.de (Volker Lendecke)
+
+This works really well, and is measurably more efficient than commercial
+client software. It is now part of the Linux kernel. Long filename support
+is in use.
+
+Status last updated June 1997
+========================================================================
+
+========================================================================
+Admin Tool
+
+Aims to produce a nice smb.conf editor and other useful tools for
+administering a Samba system.
+
+Contact: Steve Brown (steve@unicorn.dungeon.com)
+
+In the design phase.
+
+Status last updated 4th September 1994
+========================================================================
+
+
+========================================================================
+Lanman Client.
+
+Contact: john@amanda.xs4all.nl (John Stewart)
+
+Aims to produce a reliable LANMAN Client implementation for LINUX,
+and possibly other variations of UNIX. Project ably started by
+Tor Lillqvist; tml@hemuli.tte.vtt.fi
+
+Status last updated 17th January 1995
+========================================================================
diff --git a/docs/textdocs/security_level.txt b/docs/textdocs/security_level.txt
new file mode 100755
index 00000000000..dad4bd78314
--- /dev/null
+++ b/docs/textdocs/security_level.txt
@@ -0,0 +1,103 @@
+!==
+!== security_level.txt for Samba release 2.2.0-alpha3 24 Mar 2001
+!==
+Contributor: Andrew Tridgell
+Updated: June 27, 1997
+Status: Current
+
+Subject: Description of SMB security levels.
+===========================================================================
+
+Samba supports the following options to the global smb.conf parameter
+"security =":
+ share, user, server
+
+Note: Samba-2.0.0 now adds the "domain" security mode. Please refer to
+the smb.conf man page for usage information and to the document
+docs/textdocs/DOMAIN_MEMBER.txt for further background details.
+
+Of the above, "security = server" means that Samba reports to clients that
+it is running in "user mode" but actually passes off all authentication
+requests to another "user mode" server. This requires an additional
+parameter "password server =" that points to the real authentication server.
+That real authentication server can be another Samba server or can be a
+Windows NT server, the later natively capable of encrypted password support.
+
+Below is a more complete description of security levels.
+===========================================================================
+
+A SMB server tells the client at startup what "security level" it is
+running. There are two options "share level" and "user level". Which
+of these two the client receives affects the way the client then tries
+to authenticate itself. It does not directly affect (to any great
+extent) the way the Samba server does security. I know this is
+strange, but it fits in with the client/server approach of SMB. In SMB
+everything is initiated and controlled by the client, and the server
+can only tell the client what is available and whether an action is
+allowed.
+
+I'll describe user level security first, as its simpler. In user level
+security the client will send a "session setup" command directly after
+the protocol negotiation. This contains a username and password. The
+server can either accept or reject that username/password
+combination. Note that at this stage the server has no idea what
+share the client will eventually try to connect to, so it can't base
+the "accept/reject" on anything other than:
+
+- the username/password
+- the machine that the client is coming from
+
+If the server accepts the username/password then the client expects to
+be able to mount any share (using a "tree connection") without
+specifying a password. It expects that all access rights will be as
+the username/password specified in the "session setup".
+
+It is also possible for a client to send multiple "session setup"
+requests. When the server responds it gives the client a "uid" to use
+as an authentication tag for that username/password. The client can
+maintain multiple authentication contexts in this way (WinDD is an
+example of an application that does this)
+
+
+Ok, now for share level security. In share level security the client
+authenticates itself separately for each share. It will send a
+password along with each "tree connection" (share mount). It does not
+explicitly send a username with this operation. The client is
+expecting a password to be associated with each share, independent of
+the user. This means that samba has to work out what username the
+client probably wants to use. It is never explicitly sent the
+username. Some commercial SMB servers such as NT actually associate
+passwords directly with shares in share level security, but samba
+always uses the unix authentication scheme where it is a
+username/password that is authenticated, not a "share/password".
+
+Many clients send a "session setup" even if the server is in share
+level security. They normally send a valid username but no
+password. Samba records this username in a list of "possible
+usernames". When the client then does a "tree connection" it also adds
+to this list the name of the share they try to connect to (useful for
+home directories) and any users listed in the "user =" smb.conf
+line. The password is then checked in turn against these "possible
+usernames". If a match is found then the client is authenticated as
+that user.
+
+Finally "server level" security. In server level security the samba
+server reports to the client that it is in user level security. The
+client then does a "session setup" as described earlier. The samba
+server takes the username/password that the client sends and attempts
+to login to the "password server" by sending exactly the same
+username/password that it got from the client. If that server is in
+user level security and accepts the password then samba accepts the
+clients connection. This allows the samba server to use another SMB
+server as the "password server".
+
+You should also note that at the very start of all this, where the
+server tells the client what security level it is in, it also tells
+the client if it supports encryption. If it does then it supplies the
+client with a random "cryptkey". The client will then send all
+passwords in encrypted form. You have to compile samba with encryption
+enabled to support this feature, and you have to maintain a separate
+smbpasswd file with SMB style encrypted passwords. It is
+cryptographically impossible to translate from unix style encryption
+to SMB style encryption, although there are some fairly simple management
+schemes by which the two could be kept in sync.
diff --git a/docs/yodldocs/README-NOW b/docs/yodldocs/README-NOW
new file mode 100755
index 00000000000..592d38c1351
--- /dev/null
+++ b/docs/yodldocs/README-NOW
@@ -0,0 +1,14 @@
+!==
+!== Notice of change of documentation format
+!==
+
+Samba is no longer using yodl as the source markup
+language for our documentation. As of release 2.2.0,
+we are using DocBook V4.1 exclusively (assuming you are not
+counting the ASCII files yet to be converted).
+
+Please see ../docbook/docbook.txt for more information
+on this.
+
+jerry carter
+SAMBA Team
diff --git a/examples/LDAP/README b/examples/LDAP/README
index 2f4b4f2a056..c7ff16ad083 100644
--- a/examples/LDAP/README
+++ b/examples/LDAP/README
@@ -1,11 +1,26 @@
!==
-!== README File for various LDAP examples
+!== README File for storing smbpasswd in LDAP
!==
!== written by Gerald Carter <jerry@samba.org>
!==
-OpenLDAP 2.x
-------------
+This is a quick and dirty means of converting smbpasswd entries
+to sambaAccount entriues in an LDAP directory.
+
+
+Pre-requisites for import_smbpasswd.pl & export_smbpasswd.pl
+--------------------------------------------------------------
+These two scripts are modified versions of
+[import|export]_smbpasswd.pl rewritten to use the Net::LDAP
+perl module available from
+
+ http://perl-ldap.sourceforge.net
+
+
+
+
+OpenLDAP 2.0.x
+--------------
A sample schema file (samba.schema) has been included for use
with OpenLDAP 2.0.x. The OIDs used in this file are owned by
@@ -35,31 +50,39 @@ nis.schema and cosine.schema in your slapd.conf file.
You must restart the LDAP server for these new included schema files
to become active.
-SunOne/Netscape DS
-------------------
-The schema file has not been updated for the sambaSamAccount
-objectclass.
+import_smbpasswd.pl
+----------------------
+Make sure you customize the local site variable in the perl script
+(i.e. ldapserver, rootdn, rootpw, etc...). The script reads from
+standard input and requires that user entries already exist
+in your directories containing the 'objectclass: posixAccount'
+value pair. For more information on this object and related schema,
+refer to RFC2307 and http://www.padl.com/software.html).
-Novell eDirectory
------------------
+The following will import an smbpasswd file into an LDAP directory
-The schema file has not been updated for the sambaSamAccount
-objectclass.
+ $ cat smbpasswd | import_smbpasswd.pl
-smbldap-tools/
---------------
+export_smbpasswd.pl
+----------------------
+
+Make sure you customize the local site variable in the perl script
+(i.e. ldapserver, rootdn, rootpw, etc...). You can then generate
+an smbpasswd file by executing
+
+ $ export_smbpasswd.pl > smbpasswd
+
+NOTE: Server side (or client side) search limites may prevent
+all users from being listed. Check you directory server documentation
+for details.
-This is a collection of perl scripts (wrapped around the standard
-OpenLDAP command line tools) for managing Samba and posix accounts
-in an LDAP directory. See the README file included with the scripts
-for more details.
-ldapsync.pl
------------
+ldapsync.pl & ldapchgpasswd.pl
+------------------------------
For more information on these scripts, see
http://www.mami.net/univr/tng-ldap/howto/
diff --git a/examples/LDAP/convertSambaAccount b/examples/LDAP/convertSambaAccount
deleted file mode 100755
index 4357dbc8f8d..00000000000
--- a/examples/LDAP/convertSambaAccount
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/usr/bin/perl -w
-##
-## Convert an LDIF file containing sambaAccount entries
-## to the new sambaSamAccount objectclass
-##
-## Copyright Gerald (Jerry) Carter 2003
-##
-## Usage: convertSambaAccount --sid=<Domain SID> \
-## --input=<input ldif> --output=<output ldif> \
-## --changetype=[modify|add]
-##
-## You can generate an input ldif file using:
-## $ ldapsearch -LL -x -h ldapsrv -D cn=root,dc=company,dc=com \
-## -b dc=copmany,dc=com > /tmp/samba3.alpha23.ldif
-##
-## Note the "-LL" so no additional comments are generated
-##
-
-
-use strict;
-use Net::LDAP::LDIF;
-use Getopt::Long;
-
-
-##############################################################################
-## local variables
-
-my ( $domain, $domsid, $changetype );
-my ( $ldif, $ldif2 );
-my ( $entry, @objclasses, $obj );
-my ( $is_samba_account, $is_samba_group );
-my ( %attr_map, %group_attr_map, $key );
-my ( @dels, $deletion, @adds, $addition );
-my ( $result, %options );
-
-
-##############################################################################
-## Print the option usage
-
-sub usage {
-
- print "convertSambaAccount <options>\n";
- print "Options:\n";
- print " --help print this help message\n";
- print " --input input LDIF filename\n";
- print " --output output LDIF filename\n";
- print " --sid domain SID\n";
- print " --changetype [modify|add] (default is 'add')\n";
-}
-
-
-##############################################################################
-## MAIN DRIVER ##
-##############################################################################
-
-##
-## hashes to map old attribute names to new ones
-##
-
-%attr_map = (
- lmPassword => 'sambaLMPassword',
- ntPassword => 'sambaNTPassword',
- pwdLastSet => 'sambaPwdLastSet',
- pwdMustChange => 'sambaPwdMustChange',
- pwdCanChange => 'sambaPwdCanChange',
- homeDrive => 'sambaHomeDrive',
- smbHome => 'sambaHomePath',
- scriptPath => 'sambaLogonScript',
- profilePath => 'sambaProfilePath',
- kickoffTime => 'sambaKickoffTime',
- logonTime => 'sambaLogonTime',
- logoffTime => 'sambaLogoffTime',
- userWorkstations => 'sambaUserWorkstations',
- domain => 'sambaDomainName',
- acctFlags => 'sambaAcctFlags',
-);
-
-%group_attr_map = (
- ntSid => 'sambaSID',
- ntGroupType => 'sambaGroupType',
-);
-
-##
-## process command line args
-##
-
-$result = GetOptions(\%options,
- "help",
- "input=s",
- "output=s",
- "sid=s",
- "changetype=s");
-
-if (!$result && ($#ARGV != -1)) {
- usage();
- exit 1;
-}
-
-if ( defined($options{'help'}) ) {
- usage();
- exit 0;
-}
-
-
-if ( !defined( $options{'sid'} ) ) {
- print "You must provide a domain sid\n";
- exit 1;
-}
-
-$domsid = $options{'sid'};
-
-$changetype = 'add';
-if ( defined( $options{'changetype'} ) ) {
- $changetype = $options{'changetype'};
-}
-
-##
-## open files
-##
-
-$ldif = Net::LDAP::LDIF->new ($options{'input'}, "r") or die $!;
-
-if ( "$changetype" eq "add" ) {
- $ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!;
-}
-elsif ( "$changetype" eq "modify" ) {
- open( OUTPUT, ">$options{'output'}" ) or die $!;
-}
-else {
- print "Bad changetype!\n";
- exit 1;
-}
-
-##
-## process LDIF
-##
-
-while ( !$ldif->eof ) {
- undef ( $entry );
- $entry = $ldif->read_entry();
-
- ## skip entry if we find an error
- if ( $ldif->error() ) {
- print "Error msg: ",$ldif->error(),"\n";
- print "Error lines:\n",$ldif->error_lines(),"\n";
- next;
- }
-
- ##
- ## check to see if we have anything to do on this
- ## entry. If not just write it out
- ##
- @objclasses = $entry->get_value( "objectClass" );
- undef ( $is_samba_account );
- undef ( $is_samba_group );
- @adds = ();
- @dels = ();
- foreach $obj ( @objclasses ) {
- if ( "$obj" eq "sambaAccount" ) {
- $is_samba_account = 1;
- } elsif ( "$obj" eq "sambaGroupMapping" ) {
- $is_samba_group = 1;
- }
- }
-
- if ( defined ( $is_samba_account ) ) {
- ##
- ## start editing the sambaAccount
- ##
-
- @dels = ( 'objectclass: sambaAccount', 'rid' );
- @adds = ('objectclass: sambaSamAccount', "sambaSID: " . ${domsid} . "-" . ${entry}->get_value( 'rid' ) );
- $entry->delete( 'objectclass' => [ 'sambaAccount' ] );
- $entry->add( 'objectclass' => 'sambaSamAccount' );
-
- $entry->add( 'sambaSID' => $domsid."-".$entry->get_value( "rid" ) );
- $entry->delete( 'rid' );
-
- if ( defined($entry->get_value( "primaryGroupID" )) ) {
- push @adds, "sambaPrimaryGroupSID: " . $domsid."-".$entry->get_value( "primaryGroupID" );
- push @dels, "primaryGroupID";
- $entry->add( 'sambaPrimaryGroupSID' => $domsid."-".$entry->get_value( "primaryGroupID" ) );
- $entry->delete( 'primaryGroupID' );
- }
-
-
- foreach $key ( keys %attr_map ) {
- if ( defined($entry->get_value($key)) ) {
- push @adds, "$attr_map{$key}: " . $entry->get_value($key);
- push @dels, "$key";
- $entry->add( $attr_map{$key} => $entry->get_value($key) );
- $entry->delete( $key );
- }
- }
- } elsif ( defined ( $is_samba_group ) ) {
- foreach $key ( keys %group_attr_map ) {
- if ( defined($entry->get_value($key)) ) {
- push @adds, "$group_attr_map{$key}: " . $entry->get_value($key);
- push @dels, "$key";
- $entry->add( $group_attr_map{$key} => $entry->get_value($key) );
- $entry->delete( $key );
- }
- }
- }
-
- ## see if we should write full entries or only the changes
-
- if ( "$changetype" eq "add" ) {
- $ldif2->write_entry( $entry );
- }
- else {
- if ( defined ( $is_samba_account ) || defined ( $is_samba_group ) ){
- if ( @adds + @dels > 0 ) {
- print OUTPUT "dn: " . $entry->dn . "\n";
- foreach $addition (@adds) {
- $addition =~ /(^\w+):/;
- print OUTPUT "add: " . $1 . "\n";
- print OUTPUT "$addition\n-\n";
- }
- foreach $deletion (@dels) {
- if ( $deletion =~ /^(\w+):\s(.*)/ ) {
- print OUTPUT "delete: $1\n$1: $2\n-\n";
- } else {
- print OUTPUT "delete: $deletion\n-\n"
- }
- }
- print OUTPUT "\n"
- }
- }
- }
-}
-
-
diff --git a/examples/LDAP/export_smbpasswd.pl b/examples/LDAP/export_smbpasswd.pl
new file mode 100755
index 00000000000..90f5805e55f
--- /dev/null
+++ b/examples/LDAP/export_smbpasswd.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+##
+## Example script to export ldap entries into an smbpasswd file format
+## using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+## ported to Net::LDAP by dkrovich@slackworks.com
+
+use Net::LDAP;
+
+######################################################
+## Set these values to whatever you need for your site
+##
+
+$DN="dc=samba,dc=my-domain,dc=com";
+$ROOTDN="cn=Manager,dc=my-domain,dc=com";
+$rootpw = "secret";
+$LDAPSERVER="localhost";
+
+##
+## end local site variables
+######################################################
+
+$ldap = Net::LDAP->new($LDAPSERVER) or die "Unable to connect to LDAP server $LDAPSERVER";
+
+print "##\n";
+print "## Autogenerated smbpasswd file via ldapsearch\n";
+print "## from $LDAPSERVER ($DN)\n";
+print "##\n";
+
+## scheck for the existence of the posixAccount first
+$result = $ldap->search ( base => "$DN",
+ scope => "sub",
+ filter => "(objectclass=smbpasswordentry)"
+ );
+
+
+
+## loop over the entries we found
+while ( $entry = $result->shift_entry() ) {
+
+ @uid = $entry->get_value("uid");
+ @uidNumber = $entry->get_value("uidNumber");
+ @lm_pw = $entry->get_value("lmpassword");
+ @nt_pw = $entry->get_value("ntpassword");
+ @acct = $entry->get_value("acctFlags");
+ @pwdLastSet = $entry->get_value("pwdLastSet");
+
+ if (($#uid+1) && ($#uidNumber+1)) {
+
+ $lm_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#lm_pw+1));
+ $nt_pw[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" if (! ($#nt_pw+1));
+ $acct[0] = "[DU ]" if (! ($#acct+1));
+ $pwdLastSet[0] = "FFFFFFFF" if (! ($#pwdLastSet+1));
+
+ print "$uid[0]:$uidNumber[0]:$lm_pw[0]:$nt_pw[0]:$acct[0]:LCT-$pwdLastSet[0]\n";
+ }
+
+}
+
+$ldap->unbind();
+exit 0;
+
diff --git a/examples/LDAP/import_smbpasswd.pl b/examples/LDAP/import_smbpasswd.pl
new file mode 100755
index 00000000000..61ad33c8099
--- /dev/null
+++ b/examples/LDAP/import_smbpasswd.pl
@@ -0,0 +1,119 @@
+#!/usr/bin/perl
+##
+## Example script of how you could import a smbpasswd file into an LDAP
+## directory using the Mozilla PerLDAP module.
+##
+## writen by jerry@samba.org
+##
+## ported to Net::LDAP by dkrovich@slackworks.com
+
+use Net::LDAP;
+
+#################################################
+## set these to a value appropriate for your site
+##
+
+$DN="ou=people,dc=plainjoe,dc=org";
+$ROOTDN="cn=Manager,dc=plainjoe,dc=org";
+# If you use perl special character in your
+# rootpw, escape them:
+# $rootpw = "secr\@t" instead of $rootpw = "secr@t"
+$rootpw = "n0pass";
+$LDAPSERVER="scooby";
+
+##
+## end local site variables
+#################################################
+
+$ldap = Net::LDAP->new($LDAPSERVER) or die "Unable to connect to LDAP server $LDAPSERVER";
+
+## Bind as $ROOTDN so you can do updates
+$mesg = $ldap->bind($ROOTDN, password => $rootpw);
+$mesg->error() if $mesg->code();
+
+while ( $string = <STDIN> ) {
+ chomp ($string);
+
+ ## Get the account info from the smbpasswd file
+ @smbentry = split (/:/, $string);
+
+ ## Check for the existence of a system account
+ @getpwinfo = getpwnam($smbentry[0]);
+ if (! @getpwinfo ) {
+ print STDERR "**$smbentry[0] does not have a system account... \n";
+ next;
+ }
+ ## Calculate RID = uid*2 +1000
+ $rid=@getpwinfo[2]*2+1000;
+
+ ## check and see if account info already exists in LDAP.
+ $result = $ldap->search ( base => "$DN",
+ scope => "sub",
+ filter => "(uid=$smbentry[0])"
+ );
+
+ ## If no LDAP entry exists, create one.
+ if ( $result->count == 0 ) {
+ $new_entry = Net::LDAP::Entry->new();
+ $new_entry->add( dn => "uid=$smbentry[0],$DN",
+ uid => $smbentry[0],
+ rid => $rid,
+ lmPassword => $smbentry[2],
+ ntPassword => $smbentry[3],
+ acctFlags => $smbentry[4],
+ cn => $smbentry[0],
+ pwdLastSet => hex(substr($smbentry[5],4)),
+ objectclass => 'sambaAccount' );
+
+ $result = $ldap->add( $new_entry );
+ $result->error() if $result->code();
+ print "Adding [uid=" . $smbentry[0] . "," . $DN . "]\n";
+
+ ## Otherwise, supplement/update the existing entry.
+ }
+ elsif ($result->count == 1)
+ {
+ # Put the search results into an entry object
+ $entry = $result->entry(0);
+
+ print "Updating [" . $entry->dn . "]\n";
+
+ ## Add the objectclass: sambaAccount attribute if it's not there
+ @values = $entry->get_value( "objectclass" );
+ $flag = 1;
+ foreach $item (@values) {
+ print "$item\n";
+ if ( "$item" eq "sambaAccount" ) {
+ $flag = 0;
+ }
+ }
+ if ( $flag ) {
+ ## Adding sambaAccount objectclass requires adding at least rid:
+ ## uid attribute already exists we know since we searched on it
+ $entry->add(objectclass => "sambaAccount",
+ rid => $rid );
+ }
+
+ ## Set the other attribute values
+ $entry->replace(rid => $rid,
+ lmPassword => $smbentry[2],
+ ntPassword => $smbentry[3],
+ acctFlags => $smbentry[4],
+ pwdLastSet => hex(substr($smbentry[5],4)));
+
+ ## Apply changes to the LDAP server
+ $updatemesg = $entry->update($ldap);
+ $updatemesg->error() if $updatemesg->code();
+
+ ## If we get here, the LDAP search returned more than one value
+ ## which shouldn't happen under normal circumstances.
+ } else {
+ print STDERR "LDAP search returned more than one entry for $smbentry[0]... skipping!\n";
+ next;
+ }
+}
+
+$ldap->unbind();
+exit 0;
+
+
diff --git a/examples/LDAP/ldapchpasswd b/examples/LDAP/ldapchpasswd
new file mode 100755
index 00000000000..0776d9bed1a
--- /dev/null
+++ b/examples/LDAP/ldapchpasswd
@@ -0,0 +1,152 @@
+#!/usr/bin/perl -w
+
+# LDAP to unix password sync script for samba-tng
+# originally by Jody Haynes <Jody.Haynes@isunnetworks.com>
+# 2000/12/12 milos@interactivesi.com
+# modified for use with MD5 passwords
+# 2000/12/16 mami@arena.sci.univr.it
+# modified to change lmpassword and ntpassword for samba
+# 2001/01/05 mami@arena.sci.univr.it
+# modified for being also a /bin/passwd replacement
+# 2001/01/29 mami@arena.sci.univr.it
+# now there are two small programs: ldapchpasswd to
+# change password from unix and ldapsync.pl to sync
+# from NT/2000. ldapchpasswd do not need clear password.
+# 2001/01/31 mami@arena.sci.univr.it
+# add server parameter to ldap commands
+# 2001/06/20 mami@arena.sci.univr.it
+# add pwdlastset and shadowlastchange update
+
+$basedn = "ou=Students,dc=univr, dc=it";
+$binddn = "uid=root,dc=univr,dc=it";
+$scope = "sub";
+$server = "my_server";
+
+foreach $arg (@ARGV) {
+ if ($< != 0) {
+ die "Only root can specify parameters\n";
+ } else {
+ if ( ($arg eq '-?') || ($arg eq '--help') ) {
+ print "Usage: $0 [-o] [username]\n";
+ print " -o, --without-old-password do not ask for old password (root only)\n";
+ print " -?, --help show this help message\n";
+ exit (-1);
+ } elsif ( ($arg eq '-o') || ($arg eq '--without-old-password') ) {
+ $oldpass = 1;
+ } elsif (substr($arg,0) ne '-') {
+ $user = $arg;
+ if (!defined(getpwnam($user))) {
+ die "$0: Unknown user name '$user'\n"; ;
+ }
+ }
+ }
+}
+
+if (!defined($user)) {
+ $user=$ENV{"USER"};
+}
+
+# current user's dn
+my $dn = '';
+
+if ($< == 0) {
+ system "stty -echo";
+ print "LDAP password for root DN: ";
+ chomp($passwd=<STDIN>);
+ print "\n";
+ system "stty echo";
+ # Find dn for user $user binding as root's dn
+ chomp($dn=`ldapsearch -h '$server' -b '$basedn' -s '$scope' -D '$binddn' -w '$passwd' '(uid=$user)'|head -1`);
+ if ( ($dn eq '') || ($passwd eq '') ) {
+ print "Wrong LDAP password for root DN!\n";
+ exit (-1);
+ }
+} else {
+ if (!defined($oldpass)) {
+ system "stty -echo";
+ print "Old password for user $user: ";
+ chomp($oldpass=<STDIN>);
+ print "\n";
+ system "stty echo";
+
+ # Find path to uid
+ chomp($path_to_uid=`ldapsearch -h '$server' -b '$basedn' -s '$scope' '(uid=$user)'|head -1`);
+ # Find old password for user $user binding as self
+ chomp($dn=`ldapsearch -h '$server' -b '$basedn' -s '$scope' -D '$path_to_uid' -w '$oldpass' '(uid=$user)'|head -1`);
+
+ if ( ($dn eq '') || ($oldpass eq '') ) {
+ print "Wrong password for user $user!\n";
+ exit (-1);
+ }
+ }
+}
+
+system "stty -echo";
+print "New password for user $user: ";
+chomp($pass=<STDIN>);
+print "\n";
+system "stty echo";
+
+system "stty -echo";
+print "Retype new password for user $user: ";
+chomp($pass2=<STDIN>);
+print "\n";
+system "stty echo";
+
+if ( ($pass ne $pass2) || (length($pass)<1) ) {
+ die "Wrong password!\n";
+} else {
+# MD5 password
+$random = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
+$bsalt = "\$1\$"; $esalt = "\$";
+$modsalt = $bsalt.$random.$esalt;
+$password = crypt($pass, $modsalt);
+
+# LanManager and NT clear text passwords
+$ntpwd = `/usr/local/sbin/mkntpwd '$pass'`;
+chomp($lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+chomp($ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+#$FILE="|/usr/bin/ldapmodify -h '$server' -D '$binddn' -w $passwd";
+if ($< != 0) {
+ $FILE="|/usr/bin/ldapmodify -h '$server' -D '$dn' -w '$oldpass'";
+} else {
+ $FILE="|/usr/bin/ldapmodify -h '$server' -D '$binddn' -w '$passwd'";
+}
+
+# Chenge time
+$shadowlastchange=int(time/24/3600);
+$pwdlastset=sprintf('%x',time);
+
+open FILE or die;
+
+print FILE <<EOF;
+dn: $dn
+changetype: modify
+replace: userPassword
+userPassword: {crypt}$password
+-
+changetype: modify
+replace: lmpassword
+lmpassword: $lmpassword
+-
+changetype: modify
+replace: ntpassword
+ntpassword: $ntpassword
+-
+changetype: modify
+replace: shadowlastchange
+shadowlastchange: $shadowlastchange
+-
+changetype: modify
+replace: pwdlastset
+pwdlastset: $pwdlastset
+-
+
+EOF
+close FILE;
+
+}
+
+exit 0;
+
diff --git a/examples/LDAP/ldapsync.pl b/examples/LDAP/ldapsync.pl
index c112bcc34cb..fecc594c2d2 100644
--- a/examples/LDAP/ldapsync.pl
+++ b/examples/LDAP/ldapsync.pl
@@ -8,11 +8,6 @@
# modified to change lmpassword and ntpassword for samba
# 05/01/2001 mami@arena.sci.univr.it
# modified for being also a /bin/passwd replacement
-#
-# ACHTUNG!! For servers that support the LDAP Modify password
-# extended op (e.g. OpenLDAP), see the "ldap password
-# sync" option in smb.conf(5).
-#
$basedn = "ou=Students,dc=univr, dc=it";
$binddn = "uid=root,dc=univr,dc=it";
diff --git a/examples/LDAP/samba-nds.schema b/examples/LDAP/samba-nds.schema
index 8369c8404ec..99e56d75dc9 100644
--- a/examples/LDAP/samba-nds.schema
+++ b/examples/LDAP/samba-nds.schema
@@ -1,151 +1,201 @@
-##
-## Schema file for Novell eDirectory 8.7.x by Uli Iske
-## Schema for storing Samba's smbpasswd file in LDAP
-## OIDs are owned by the Samba Team
-##
-#######################################################################
-## Attributes used by Samba 3.0 schema ##
-#######################################################################
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-dn: cn=schema
-changetype: modify
-add: attributetypes
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#######################################################################
-## objectClasses used by Samba 3.0 schema ##
-#######################################################################
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' DESC 'Samba 3.0 Auxilary SAM Account' SUP top AUXILIARY MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $sambaLogonTime $ sambaLogoffTime $sambaKickoffTime $sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $sambaProfilePath $ description $ sambaUserWorkstations $sambaPrimaryGroupSID $ sambaDomainName ))
-
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' DESC 'Samba Group Mapping' SUP top AUXILIARY MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description ))
-
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' DESC 'Samba Domain Information' SUP top STRUCTURAL MUST ( sambaDomainName $sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $sambaAlgorithmicRidBase ) )
-
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' DESC 'Pool for allocating UNIX uids/gids' SUP top AUXILIARY MUST ( uidNumber $ gidNumber ) )
-
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' DESC 'Mapping from a SID to an ID' SUP top AUXILIARY MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) )
-
-dn: cn=schema
-changetype: modify
-add: objectClasses
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' DESC 'Structural Class for a SID' SUP top STRUCTURAL MUST ( sambaSID ) )
+--
+-- Submitted by Bruno Gimenes Pereti <pereti@ut mp dot edu dot br>
+--
+-- schema file for Novell's eDirectory 8.6
+--
+
+SambaAccountSchemaExtensions DEFINITIONS ::=
+BEGIN
+
+-- Password hashes
+"lmPassword" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 1 }
+}
+
+"ntPassword" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 2 }
+}
+
+-- Account flags in string format ([UWDX ])
+"acctFlags" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 4 }
+}
+
+-- Password timestamps & policies
+"pwdLastSet" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 3 }
+}
+
+"logonTime" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 5 }
+}
+
+"logoffTime" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 6 }
+}
+
+"kickoffTime" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 7 }
+}
+
+"pwdCanChange" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 8 }
+}
+
+"pwdMustChange" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 9 }
+}
+
+-- string settings
+"homeDrive" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 10 }
+}
+
+"scriptPath" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 5 1 4 1 7165 2 1 11 }
+}
+
+"profilePath" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 12 }
+}
+
+"userWorkstations" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 13 }
+}
+
+"smbHome" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 17 }
+}
+
+"domain" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_CI_STRING,
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 18 }
+}
+
+-- user and group RID
+"rid" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 14 }
+}
+
+"primaryGroupID" ATTRIBUTE ::=
+{
+ Operation ADD,
+ SyntaxID SYN_INTEGER,
+ Flags { DS_SINGLE_VALUED_ATTR },
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 1 15 }
+}
+
+"sambaAccount" OBJECT-CLASS ::=
+{
+ Operation ADD,
+ Flags {DS_AUXILIARY_CLASS},
+ SubClassOf {"TOP"},
+ MustContain { "uid"},
+ MustContain { "rid"},
+ MayContain { "CN"},
+ MayContain { "lmPassword"},
+ MayContain { "ntPassword"},
+ MayContain { "pwdLastSet"},
+ MayContain { "logonTime"},
+ MayContain { "logoffTime"},
+ MayContain { "kickoffTime"},
+ MayContain { "pwdCanChange"},
+ MayContain { "pwdMustChange"},
+ MayContain { "acctFlags"},
+ MayContain { "displayName"},
+ MayContain { "smbHome"},
+ MayContain { "homeDrive"},
+ MayContain { "scriptPath"},
+ MayContain { "profilePath"},
+ MayContain { "description"},
+ MayContain { "userWorkstations"},
+ MayContain { "primaryGroupID"},
+ MayContain { "domain"},
+ ASN1ObjID { 1 3 6 1 4 1 7165 2 2 3 }
+}
+
+-- Used for Winbind experimentation
+"uidPool" OBJECT-CLASS ::=
+{
+ Operation ADD,
+ Flags {DS_AUXILIARY_CLASS},
+ SubClassOf {"TOP"},
+ MustContain { "uidNumber"},
+ MustContain { "CN"},
+ ASN1ObjID { 1 3 6 1 4 1 7165 1 2 2 3 }
+}
+
+"gidPool" OBJECT-CLASS ::=
+{
+ Operation ADD,
+ Flags {DS_AUXILIARY_CLASS},
+ SubClassOf {"TOP"},
+ MustContain { "gidNumber"},
+ MustContain { "CN"},
+ ASN1ObjID { 1 3 6 1 4 1 7165 1 2 2 4 }
+}
+
+END
+
+
diff --git a/examples/LDAP/samba-schema-netscapeds4.x b/examples/LDAP/samba-schema-netscapeds4.x
index 9f409664187..074b78c52cc 100644
--- a/examples/LDAP/samba-schema-netscapeds4.x
+++ b/examples/LDAP/samba-schema-netscapeds4.x
@@ -1,112 +1,54 @@
#
-# LDAP Schema file for SAMBA 3.0 attribute storage
-# For Netscape Directory Server 4.1x
-# Prepared by Osman Demirhan
-
-attribute sambaLMPassword 1.3.6.1.4.1.7165.2.1.24 cis single
-attribute sambaNTPassword 1.3.6.1.4.1.7165.2.1.25 cis single
-attribute sambaAcctFlags 1.3.6.1.4.1.7165.2.1.26 cis single
-attribute sambaPwdLastSet 1.3.6.1.4.1.7165.2.1.27 int single
-attribute sambaPwdCanChange 1.3.6.1.4.1.7165.2.1.28 int single
-attribute sambaPwdMustChange 1.3.6.1.4.1.7165.2.1.29 int single
-attribute sambaLogonTime 1.3.6.1.4.1.7165.2.1.30 int single
-attribute sambaLogoffTime 1.3.6.1.4.1.7165.2.1.31 int single
-attribute sambaKickoffTime 1.3.6.1.4.1.7165.2.1.32 int single
-attribute sambaHomeDrive 1.3.6.1.4.1.7165.2.1.33 cis single
-attribute sambaLogonScript 1.3.6.1.4.1.7165.2.1.34 cis single
-attribute sambaProfilePath 1.3.6.1.4.1.7165.2.1.35 cis single
-attribute sambaUserWorkstations 1.3.6.1.4.1.7165.2.1.36 cis single
-attribute sambaHomePath 1.3.6.1.4.1.7165.2.1.37 cis single
-attribute sambaDomainName 1.3.6.1.4.1.7165.2.1.38 cis single
-attribute sambaSID 1.3.6.1.4.1.7165.2.1.20 cis single
-attribute sambaPrimaryGroupSID 1.3.6.1.4.1.7165.2.1.23 cis single
-attribute sambaGroupType 1.3.6.1.4.1.7165.2.1.19 int single
-attribute sambaNextUserRid 1.3.6.1.4.1.7165.2.1.21 int single
-attribute sambaNextGroupRid 1.3.6.1.4.1.7165.2.1.22 int single
-attribute sambaNextRid 1.3.6.1.4.1.7165.2.1.39 int single
-attribute sambaAlgorithmicRidBase 1.3.6.1.4.1.7165.2.1.40 int single
-
-objectclass sambaSamAccount
- oid
- 1.3.6.1.4.1.7165.2.2.6
- superior
- top
- requires
- objectClass,
- uid,
- sambaSID
- allows
- cn,
- sambaLMPassword,
- sambaNTPassword,
- sambaPwdLastSet,
- sambaLogonTime,
- sambaLogoffTime,
- sambaKickoffTime,
- sambaPwdCanChange,
- sambaPwdMustChange,
- sambaAcctFlags,
- displayName,
- sambaHomePath,
- sambaHomeDrive,
- sambaLogonScript,
- sambaProfilePath,
- description,
- sambaUserWorkstations,
- sambaPrimaryGroupSID,
- sambaDomainName
-
-objectclass sambaGroupMapping
- oid
- 1.3.6.1.4.1.7165.2.2.4
- superior
- top
- requires
- gidNumber,
- sambaSID,
- sambaGroupType
- allows
- displayName,
- description
-
-objectclass sambaDomain
- oid
- 1.3.6.1.4.1.7165.2.2.5
- superior
- top
- requires
- sambaDomainName,
- sambaSID
- allows
- sambaNextRid,
- sambaNextGroupRid,
- sambaNextUserRid,
- sambaAlgorithmicRidBase
+# LDAP Schema file for SAMBA attribute storage
+# This file is suitable for usage with Netscape Directory Server 4.1x
+# Adapted by Scott Lawson with help from Ron Creamer
+#
-objectclass sambaUnixIdPool
- oid
- 1.3.6.1.4.1.7165.1.2.2.7
- superior
- top
- requires
- uidNumber,
- gidNumber
+attribute lmPassword 1.3.6.1.4.1.7165.2.1.1 cis single
+attribute ntPassword 1.3.6.1.4.1.7165.2.1.2 cis single
+attribute acctFlags 1.3.6.1.4.1.7165.2.1.4 cis single
+attribute pwdLastSet 1.3.6.1.4.1.7165.2.1.3 int single
+attribute logonTime 1.3.6.1.4.1.7165.2.1.5 int single
+attribute logoffTime 1.3.6.1.4.1.7165.2.1.6 int single
+attribute kickoffTime 1.3.6.1.4.1.7165.2.1.7 int single
+attribute pwdCanChange 1.3.6.1.4.1.7165.2.1.8 int single
+attribute pwdMustChange 1.3.6.1.4.1.7165.2.1.9 int single
+attribute homedrive 1.3.6.1.4.1.7165.2.1.10 cis single
+attribute scriptPath 1.3.6.1.4.1.7165.2.1.11 cis single
+attribute profilePath 1.3.6.1.4.1.7165.2.1.12 cis single
+attribute userWorkstations 1.3.6.1.4.1.7165.2.1.13 cis single
+attribute rid 1.3.6.1.4.1.7165.2.1.14 int single
+attribute primaryGroupID 1.3.6.1.4.1.7165.2.1.15 int single
+attribute smbHome 1.3.6.1.4.1.7165.2.1.17 cis single
+attribute domain 1.3.6.1.4.1.7165.2.1.18 cis single
-objectclass sambaIdmapEntry
- oid
- 1.3.6.1.4.1.7165.1.2.2.8
- superior
- top
- requires
- sambaSID
- allows
- uidNumber,
- gidNumber
+objectclass sambaAccount
+ oid
+ 1.3.1.5.1.4.1.7165.2.2.3
+ superior
+ top
+ requires
+ objectClass,
+ uid,
+ rid
+ allows
+ cn,
+ lmPassword,
+ ntPassword,
+ pwdLastSet,
+ logonTime,
+ logoffTime,
+ KickoffTime,
+ pwdCanChange,
+ pwdMustChange,
+ acctFlags,
+ displayName,
+ smbHome,
+ homeDrive,
+ scriptPath,
+ profilePath,
+ description,
+ userWorkstations,
+ primaryGroupID,
+ domain
-objectclass sambaSidEntry
- oid
- 1.3.6.1.4.1.7165.1.2.2.9
- superior
- top
- requires
- sambaSID
diff --git a/examples/LDAP/samba-schema-netscapeds5.x b/examples/LDAP/samba-schema-netscapeds5.x
index 56f66a54a5b..888758f67f3 100644
--- a/examples/LDAP/samba-schema-netscapeds5.x
+++ b/examples/LDAP/samba-schema-netscapeds5.x
@@ -1,14 +1,10 @@
-##
-## Darren Chew <darren.chew at vicscouts dot asn dot au>
-## Andre Fiebach <andre dot fiebach at stud dot uni-rostock dot de>
-## Thomas Mueller 12.04.2003, thomas.mueller@christ-wasser.de
-##
-## Samba 3.0 schema file for Netscape DS 5.x
-##
-## INSTALL-DIRECTORY/slapd-your_name/config/schema/samba-schema-netscapeds5.ldif
-####################################################################
-# Sun One DS do not load the schema without this lines
-# André Fiebach <af123@uni-rostock.de>
+##
+## submitted by Martin.Dehn@comparex.de
+##
+## Experiement sambaAccount schema file Netscape DS 5.0
+##
+## INSTALL-DIRECTORY/slapd-your_name/config/schema/samba-schema-netscapeds5.ldif
+##
dn: cn=schema
objectClass: top
objectClass: ldapSubentry
@@ -23,32 +19,56 @@ aci: (targetattr = "*")(version 3.0; acl "Local Directory Administrators Group
"; allow (all) groupdn = "ldap:///cn=Directory Administrators, dc=samba,dc=org";)
aci: (targetattr = "*")(version 3.0; acl "SIE Group"; allow (all)groupdn = "ld
ap:///cn=slapd-sambaldap, cn=iPlanet Directory Server, cn=Server Group, cn=iPlanetDirectory.samba.org, ou=samba.org, o=NetscapeRoot";)
-####################################################################
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName ) X-ORIGIN 'user defined' )
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description ) X-ORIGIN 'user defined' )
-objectClasses: ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase ) X-ORIGIN 'user defined' )
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY DESC 'Pool for allocating UNIX uids/gids' MUST ( uidNumber $ gidNumber ) X-ORIGIN 'user defined' )
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY DESC 'Mapping from a SID to an ID' MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) X-ORIGIN 'user defined' )
-objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes: ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+modifiersName: cn=directory manager
+modifyTimestamp: 20020322124844Z
+objectClasses: ( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+ MAY ( acctFlags $ domain $ homeDrive $ kickoffTime $ lmPassword $ logofft
+ ime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $
+ pwdLastSet $ pwdMustChange $ rid $ scriptPath $ smbHome $ userWorkstations
+ ) X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath' DESC 'NT script pa
+ th' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined
+ ' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime' DESC 'NT logon time'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath' DESC 'NT profile
+ path' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defin
+ ed' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange' DESC 'NT passwd c
+ an change' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user
+ defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome' DESC 'smbHome' SYNTAX
+ 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet' SYNTAX 1.3.6.1.4.1
+ .1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain' DESC 'Windows NT domai
+ n Samba' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user de
+ fined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive' DESC 'NT home drive
+ ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined'
+ )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logofftime' DESC 'logoff Time'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID' DESC 'NT Group
+ RID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defin
+ ed' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword' DESC 'LanManager Pa
+ sswd' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defin
+ ed' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange' DESC 'NT pwdmust
+ chnage' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user def
+ ined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags' DESC 'Account Flags'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations' DESC 'userWo
+ rkstations' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user
+ defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime' DESC 'NT kickoff T
+ ime' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user define
+ d' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid' DESC 'rid' SYNTAX 1.3.6.1
+ .4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword' DESC 'NT Passwd' SY
+ NTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+nsSchemaCSN: 3c9b282c000000000000
+
diff --git a/examples/LDAP/samba-schema.IBMSecureWay b/examples/LDAP/samba-schema.IBMSecureWay
index 1fca4a749a6..73d767b03c8 100644
--- a/examples/LDAP/samba-schema.IBMSecureWay
+++ b/examples/LDAP/samba-schema.IBMSecureWay
@@ -10,7 +10,7 @@
## ibm-slapdIncludeSchema: /etc/lapschema/samba.schema
##
objectClasses {
-( 1.3.1.5.1.4.1.7165.2.2.2 NAME 'sambaAccount' DESC 'Samba Account' SUP top MUST uid $ rid MAY ( acctFlags $ cn $ description $ displayName $ homeDrive $ kickoffTime $ lmPassword $ logoffTime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ scriptPath $ smbHome $ userWorkstations ) )
+( 1.3.1.5.1.4.1.7165.2.2.3 NAME 'sambaAccount' DESC 'Samba Account' SUP top MUST uid $ rid MAY ( acctFlags $ cn $ description $ displayName $ homeDrive $ kickoffTime $ lmPassword $ logoffTime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ scriptPath $ smbHome $ userWorkstations ) )
}
attributeTypes {
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
index 19f318b5fac..f71c344e067 100644
--- a/examples/LDAP/samba.schema
+++ b/examples/LDAP/samba.schema
@@ -1,442 +1,152 @@
##
-## schema file for OpenLDAP 2.x
-## Schema for storing Samba user accounts and group maps in LDAP
+## schema file for OpenLDAP 2.0.x
+## Schema for storing Samba's smbpasswd file in LDAP
## OIDs are owned by the Samba Team
##
-## Prerequisite schemas - uid (cosine.schema)
+## Prerequisite schemas - uid (cosine.schema)
## - displayName (inetorgperson.schema)
-## - gidNumber (nis.schema)
##
## 1.3.6.1.4.1.7165.2.1.x - attributetypes
## 1.3.6.1.4.1.7165.2.2.x - objectclasses
##
-########################################################################
-## HISTORICAL ##
-########################################################################
-
##
## Password hashes
##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
-# DESC 'LanManager Passwd'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
-# DESC 'NT Passwd'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-##
-## Account flags in string format ([UWDX ])
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
-# DESC 'Account Flags'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-
-##
-## Password timestamps & policies
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
-# DESC 'NT pwdLastSet'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
-# DESC 'NT logonTime'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
-# DESC 'NT logoffTime'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
-# DESC 'NT kickoffTime'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
-# DESC 'NT pwdCanChange'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
-# DESC 'NT pwdMustChange'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## string settings
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
-# DESC 'NT homeDrive'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
-# DESC 'NT scriptPath'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
-# DESC 'NT profilePath'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
-# DESC 'userWorkstations'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
-# DESC 'smbHome'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
-# DESC 'Windows NT domain to which the user belongs'
-# EQUALITY caseIgnoreIA5Match
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-##
-## user and group RID
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
-# DESC 'NT rid'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
-# DESC 'NT Group RID'
-# EQUALITY integerMatch
-# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## The smbPasswordEntry objectclass has been depreciated in favor of the
-## sambaAccount objectclass
-##
-#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
-# DESC 'Samba smbpasswd entry'
-# MUST ( uid $ uidNumber )
-# MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
-
-#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
-# DESC 'Samba Account'
-# MUST ( uid $ rid )
-# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
-# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-# description $ userWorkstations $ primaryGroupID $ domain ))
-
-#objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
-# DESC 'Samba Auxiliary Account'
-# MUST ( uid $ rid )
-# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
-# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-# description $ userWorkstations $ primaryGroupID $ domain ))
-
-########################################################################
-## END OF HISTORICAL ##
-########################################################################
-
-#######################################################################
-## Attributes used by Samba 3.0 schema ##
-#######################################################################
-
-##
-## Password hashes
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword'
- DESC 'LanManager Password'
+attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
+ DESC 'LanManager Passwd'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword'
- DESC 'MD4 hash of the unicode password'
+attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
+ DESC 'NT Passwd'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
##
## Account flags in string format ([UWDX ])
##
-attributetype ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags'
+attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
DESC 'Account Flags'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-##
+##
## Password timestamps & policies
##
-attributetype ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet'
- DESC 'Timestamp of the last password update'
+attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
+ DESC 'NT pwdLastSet'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange'
- DESC 'Timestamp of when the user is allowed to update the password'
+attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
+ DESC 'NT logonTime'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange'
- DESC 'Timestamp of when the password will expire'
+attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
+ DESC 'NT logoffTime'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime'
- DESC 'Timestamp of last logon'
+attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
+ DESC 'NT kickoffTime'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime'
- DESC 'Timestamp of last logoff'
+attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
+ DESC 'NT pwdCanChange'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime'
- DESC 'Timestamp of when the user will be logged off automatically'
+attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
+ DESC 'NT pwdMustChange'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount'
- DESC 'Bad password attempt count'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime'
- DESC 'Time of the last bad password attempt'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-
##
## string settings
##
-attributetype ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive'
- DESC 'Driver letter of home directory mapping'
+attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
+ DESC 'NT homeDrive'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript'
- DESC 'Logon script path'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath'
- DESC 'Roaming profile path'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations'
- DESC 'List of user workstations the user is allowed to logon to'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath'
- DESC 'Home directory UNC path'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName'
- DESC 'Windows NT domain to which the user belongs'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial'
- DESC ''
- EQUALITY caseExactMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
-
-##
-## SID, of any type
-##
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID'
- DESC 'Security ID'
+attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
+ DESC 'NT scriptPath'
EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
+ DESC 'NT profilePath'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-##
-## Primary group SID, compatible with ntSid
-##
+attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
+ DESC 'userWorkstations'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID'
- DESC 'Primary Group Security ID'
+attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
+ DESC 'smbHome'
EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-##
-## group mapping attributes
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType'
- DESC 'NT Group Type'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
+ DESC 'Windows NT domain to which the user belongs'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
##
-## Store info on the domain
+## user and group RID
##
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid'
- DESC 'Next NT rid to give our for users'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid'
- DESC 'Next NT rid to give out for groups'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid'
- DESC 'Next NT rid to give out for anything'
+attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
+ DESC 'NT rid'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase'
- DESC 'Base at which the samba RID generation algorithm should operate'
+attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
+ DESC 'NT Group RID'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName'
- DESC 'Share Name'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName'
- DESC 'Option Name'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption'
- DESC 'A boolean option'
- EQUALITY booleanMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption'
- DESC 'An integer option'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption'
- DESC 'A string option'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption'
- DESC 'A string list option'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME ( 'sambaPrivName' ) SUP name )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList'
- DESC 'Security ID List'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
- DESC 'Privileges List'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
- DESC 'Trust Password Flags'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-#######################################################################
-## objectClasses used by Samba 3.0 schema ##
-#######################################################################
-
-## The X.500 data model (and therefore LDAPv3) says that each entry can
-## only have one structural objectclass. OpenLDAP 2.0 does not enforce
-## this currently but will in v2.1
-
##
-## added new objectclass (and OID) for 3.0 to help us deal with backwards
-## compatibility with 2.2 installations (e.g. ldapsam_compat) --jerry
+## The smbPasswordEntry objectclass has been depreciated in favor of the
+## sambaAccount objectclass
##
-objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY
- DESC 'Samba 3.0 Auxilary SAM Account'
- MUST ( uid $ sambaSID )
- MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $
- sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $
- sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
- displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
- sambaProfilePath $ description $ sambaUserWorkstations $
- sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $
- sambaBadPasswordCount $ sambaBadPasswordTime))
+#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
+# DESC 'Samba smbpasswd entry'
+# MUST ( uid $ uidNumber )
+# MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
-##
-## Group mapping info
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY
- DESC 'Samba Group Mapping'
- MUST ( gidNumber $ sambaSID $ sambaGroupType )
- MAY ( displayName $ description $ sambaSIDList))
+#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
+# DESC 'Samba Account'
+# MUST ( uid $ rid )
+# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+# description $ userWorkstations $ primaryGroupID $ domain ))
-##
-## Trust password for trust relationships (any kind)
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL
- DESC 'Samba Trust Password'
- MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags )
- MAY ( sambaSID $ sambaPwdLastSet ))
+## The X.500 data model (and therefore LDAPv3) says that each entry can
+## only have one structural objectclass. OpenLDAP 2.0 does not enforce
+## this currently but will in v2.1
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+ DESC 'Samba Auxilary Account'
+ MUST ( uid $ rid )
+ MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ description $ userWorkstations $ primaryGroupID $ domain ))
##
-## Whole-of-domain info
+## Used for Winbind experimentation
##
-objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
- DESC 'Samba Domain Information'
- MUST ( sambaDomainName $
- sambaSID )
- MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
- sambaAlgorithmicRidBase ) )
-
-## used for idmap_ldap module
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY
- DESC 'Pool for allocating UNIX uids/gids'
- MUST ( uidNumber $ gidNumber ) )
-
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY
- DESC 'Mapping from a SID to an ID'
- MUST ( sambaSID )
- MAY ( uidNumber $ gidNumber ) )
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL
- DESC 'Structural Class for a SID'
- MUST ( sambaSID ) )
-
-
-
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY
- DESC 'Samba Configuration Section'
- MAY ( description ) )
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL
- DESC 'Samba Share Section'
- MUST ( sambaShareName )
- MAY ( description ) )
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL
- DESC 'Samba Configuration Option'
- MUST ( sambaOptionName )
- MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) )
-
+#objectclass ( 1.3.6.1.4.1.7165.1.2.2.3 NAME 'uidPool' SUP top AUXILIARY
+# DESC 'Pool for allocating UNIX uids'
+# MUST ( uidNumber $ cn ) )
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
- DESC 'Samba Privilege'
- MUST ( sambaSID )
- MAY ( sambaPrivilegeList ) )
+#objectclass ( 1.3.6.1.4.1.7165.1.2.2.4 NAME 'gidPool' SUP top AUXILIARY
+# DESC 'Pool for allocating UNIX gids'
+# MUST ( gidNumber $ cn ) )
diff --git a/examples/LDAP/samba.schema.at.IBM-DS b/examples/LDAP/samba.schema.at.IBM-DS
deleted file mode 100644
index bc39d520fb6..00000000000
--- a/examples/LDAP/samba.schema.at.IBM-DS
+++ /dev/null
@@ -1,59 +0,0 @@
-## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password'EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetypes=( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC '' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
diff --git a/examples/LDAP/samba.schema.oc.IBM-DS b/examples/LDAP/samba.schema.oc.IBM-DS
deleted file mode 100644
index 8f556520de9..00000000000
--- a/examples/LDAP/samba.schema.oc.IBM-DS
+++ /dev/null
@@ -1,19 +0,0 @@
-## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only
-
-objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial ))
-
-objectclasses=( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description ))
-
-objectclasses=( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY DESC 'Pool for allocating UNIX uids/gids' MUST ( uidNumber $ gidNumber ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY DESC 'Mapping from a SID to an ID' MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY DESC 'Samba Configuration Section' MAY ( description ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL DESC 'Samba Share Section' MUST ( sambaShareName ) MAY ( description ) )
-
-objectclasses=( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL DESC 'Samba Configuration Option' MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) )
diff --git a/examples/LDAP/smbldap-tools/AUTHORS b/examples/LDAP/smbldap-tools/AUTHORS
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/examples/LDAP/smbldap-tools/AUTHORS
diff --git a/examples/LDAP/smbldap-tools/CONTRIBUTORS b/examples/LDAP/smbldap-tools/CONTRIBUTORS
index 697f93b7f49..7cda936c1e0 100644
--- a/examples/LDAP/smbldap-tools/CONTRIBUTORS
+++ b/examples/LDAP/smbldap-tools/CONTRIBUTORS
@@ -3,17 +3,13 @@
## Authors and actives contributors to SMBLDAP-TOOLS
Have contributed directly to this tools, or are always in charge of
-some aspects of it developments:
- . Jérôme Tournier <jerome.tournier@IDEALX.com>
- . Terry Davis <terry@terryd.net>
+some aspects of it developments (alphabetical order):
+ . Terry Davis <tdavis@approbation.org>
. David Le Corfec <dlc@freesurf.fr>
. Olivier Lemaire <olivier.lemaire@IDEALX.com>
+ . Jérôme Tournier <jerome.tournier@IDEALX.com>
Many thanks to contributors for bug report and patches:
- . Marc Schoechlin <ms@LF.net>
- load the perl-modules without setting environment-variables or making symlinks
- . Alexander Bergolth <leo@strike.wu-wien.ac.at>
- more Net::LDAP support
. Gert-Jan Braas <braas@wyldebeast-wunderliebe.com>
bug report for 2.2.3 samba.schema
. Jody Haynes <Jody.Haynes@isunnetworks.com>
@@ -28,6 +24,6 @@ Many thanks to contributors for bug report and patches:
bug report for smbldap-passwd
. Xavier Boschian <Xavier.Boschian@rtlgroup.net>
bug report for smbldap-populate
- . Christophe DUBREUIL <christophe.dubreuil@laposte.net>
- Net::LDAP support in smbldap_tools.pm
+
+
# - The End
diff --git a/examples/LDAP/smbldap-tools/ChangeLog b/examples/LDAP/smbldap-tools/ChangeLog
index 54ba1aed66f..798f0036d2f 100644
--- a/examples/LDAP/smbldap-tools/ChangeLog
+++ b/examples/LDAP/smbldap-tools/ChangeLog
@@ -1,89 +1,29 @@
# $Source: /home/cvs/samba/examples/LDAP/smbldap-tools/ChangeLog,v $
-# $id: $
#
## ChangeLog for SMBLDAP-TOOLS
-2003-11-18:
- . new option '-a' to smbldap-usermod.pl that allow adding the sambaSamAccount
- objectclass to an existing posixAccount
-2003-11-07:
- . patch that allow adding user to a group when the group is in a higher level depth
- then ou=Groups (for example, ou=grp1,ou=Groups,...)
- . check the unicity of a group when adding/removing a user to this group
-2003-10-28:
- . new option '-p' in smbldap-groupadd.pl to 'print' the gidNumber
- of the group to STDOUT. This is needed by samba (see the man page)
-2003-10-19:
- . new function does_sid_exist that check if samaSID sttribute is already
- defined for another use or another group
-2003-10-13:
- . smbldap-populate.pl now also add the group mapping
-2003-10-01:
- . one can now comment the two directives '$_userSmbHome' and '$_userProfile'
- if you want to use the smb.conf directives instead ('logon home' and
- 'logon path' respectively), or if you want to desable roaming profiles
- . Patch from Alexander Bergolth <leo@strike.wu-wien.ac.at>: the sambaPrimaryGroupSID
- of a user is now set to the sambaSID of his primary group
-2003-09-29:
- . added new option '$_defaultMaxPasswordAge' in smbldap_conf.pm to specifie
- how long a password is valid
- . The '-B' option was not always valid: to force a user to change his password:
- . the attribut sambaPwdLastSet must be != 0
- . the attribut sambaAcctFlags must not match the 'X' flag
- . logon script is set (for every one) to the default '_userScript' value if it is defined
- . Patch from Alexander Bergolth <leo@strike.wu-wien.ac.at>:
- gid-sid group mapping to smbldap-groupadd.pl and smbldap-groupmod.pl
-2003-09-19: Patch from Marc Schoechlin <ms@LF.net>
- . load the perl-modules without setting environment-variables or making symlinks
-2003-09-18: Patch from Alexander Bergolth <leo@strike.wu-wien.ac.at>
- . options "-u", "-g", "-s" and "-c" are now functionnal
- . the existence of samba account was made on sambaAccount and
- not sambaSamAccount as it should be for samba3
- . new function read_user_entry to smbldap_tools.pm that returns
- a Net::LDAP:Entry object of the user
- . Use this object to get the dn and user attributes instead of
- producing an ldif and searching for attributes within that ldif
-2003-09-15:
- . change machine account creation to not add the sambaSamAccount objectclass.
- It is now added directly by samba when joigning the domain
- . new option in smbldap-usermod.pl: '-e' to set an expire date
- . Start_tls support activated when ldapSSL is set to 1
- . Net::LDAP support more scripts
- . bugs correction
-2003-09-02:
- . sambaPwdLastSet is updated when smbldap-passwd.pl is used
- . add a function is_group_member to test the existence of a
- user in a particular group
- . add a function is_unix_user to test if a particular user exist
- . Net::LDAP support more scripts
-2003-08-15:
- . Samba3.0 support
-2003-08-01:
- . Final version for samba 2.2.8a (cvs tag SAMBA-2-2-8a-FINAL)
- . OpenLDAP 2.1 support (only one structural objectclass allowed)
-2002-07-24: top and account objectclasses replaced with inetorgperson
-2002-06-03: notes to webmin.idealx.org (idxldapaccounts)
-2002-06-01: release 0.7. tested with 2.2.4
-2002-05-31: fixed smbldap-populate compliance to smbldap_conf
- cleaned up smbldap_conf to be more readable
- some more documentation
- bugfixes on smbldap-passwd and smbldap-populate
-2002-05-16: modified default mode on homes: now 700
-2002-05-13: fixed spec (relocation and reqs)
-2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl
+* 2002-06-03: notes to webmin.idealx.org (idxldapaccounts)
+* 2002-06-01: release 0.7. tested with 2.2.4
+* 2002-05-31: fixed smbldap-populate compliance to smbldap_conf
+ cleaned up smbldap_conf to be more readable
+ some more documentation
+ bugfixes on smbldap-passwd and smbldap-populate
+* 2002-05-16: modified default mode on homes: now 700
+* 2002-05-13: fixed spec (relocation and reqs)
+* 2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl
(rid is now mandatory in the sambaAccount objectClass)
-2002-02-14: just modified default populate for Administrator
-2002-02-05: release 0.6. enable/disable user in usermod
-2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups
- from a net group dump. added samba parameters to smbldap-useradd
- and smbldap-usermod.
-2002-01-12: added smbldap-migrate-accounts to migrate users/machines
- accounts from a PWDUMP dump
-2001-12-13: added smbldap-populate to create the initial base
-2001-12-13: initial release 0.1
-2001-12-12: fixed the SPEC file for RedHat
-2001-12-03: cleaned the code and use strict;
-2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG)
+* 2002-02-14: just modified default populate for Administrator
+* 2002-02-05: release 0.6. enable/disable user in usermod
+* 2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups
+ from a net group dump. added samba parameters to smbldap-useradd
+ and smbldap-usermod.
+* 2002-01-12: added smbldap-migrate-accounts to migrate users/machines
+ accounts from a PWDUMP dump
+* 2001-12-13: added smbldap-populate to create the initial base
+* 2001-12-13: initial release 0.1
+* 2001-12-12: fixed the SPEC file for RedHat
+* 2001-12-03: cleaned the code and use strict;
+* 2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG)
# - The End
diff --git a/examples/LDAP/smbldap-tools/INFRASTRUCTURE b/examples/LDAP/smbldap-tools/INFRASTRUCTURE
index 8ea07ead44b..2955f87b9cb 100644
--- a/examples/LDAP/smbldap-tools/INFRASTRUCTURE
+++ b/examples/LDAP/smbldap-tools/INFRASTRUCTURE
@@ -43,15 +43,6 @@ man smb.conf for more):
domain admin group = " @"Domain Admins" "
-However, to make pdb_ldap accept bind without being uid=0, a quick and
-dirty patch must be applied to 2.2.4 (see samba-2.2.4-ldapbindnotuid0.patch).
-This patch is Q&D because the check is there because Samba store admin
-credentials to establish the LDAP connection. The uid == 0 check was to
-ensure that a normal user could not get write access to the LDAP backend.
-A more logical situation should be done for 2.2.5 by checking if the user
-is a member of the domain admin group (reported to Jerremy and Gerald
-2002-05-28).
-
Other built in groups are really cosmetic ones with Samba 2.2.x. We did not
removed them because one of these days, we whish to use Samba 3.0 where
Windows Group Support should be operational.
diff --git a/examples/LDAP/smbldap-tools/Makefile b/examples/LDAP/smbldap-tools/Makefile
index 783a3571a99..3e5eac427d7 100644
--- a/examples/LDAP/smbldap-tools/Makefile
+++ b/examples/LDAP/smbldap-tools/Makefile
@@ -1,5 +1,5 @@
PACKAGE=smbldap-tools
-RELEASE=0.8.2-1
+RELEASE=0.7
DESTDIR = $(PACKAGE)-$(RELEASE)
dist: distclean $(DESTDIR).tgz
diff --git a/examples/LDAP/smbldap-tools/NEWS b/examples/LDAP/smbldap-tools/NEWS
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/examples/LDAP/smbldap-tools/NEWS
diff --git a/examples/LDAP/smbldap-tools/TODO b/examples/LDAP/smbldap-tools/TODO
index 8fdc2a55994..ffbd4a97e39 100644
--- a/examples/LDAP/smbldap-tools/TODO
+++ b/examples/LDAP/smbldap-tools/TODO
@@ -4,7 +4,6 @@
## (BF: Bug Report / FR: Feature Request)
-FR * add 'LDAP port' for both slave and master LDAP server in smbldap_conf.pm
FR * use RFC2307 best practices (Luke, next time you visit Paris, have a
beer at IDEALX'cantina ;-)
FR * add mail (sendmail/postfix/qmail/courier) support
diff --git a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl
index e242d6e223f..ee804b34d3b 100755
--- a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,108 +23,34 @@
# Purpose of smbldap-groupadd : group (posix) add
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
-use smbldap_conf;
+
use Getopt::Std;
my %Options;
-my $ok = getopts('ag:or:s:t:p?', \%Options);
+my $ok = getopts('og:?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-agorst?] groupname\n";
- print " -a add automatic group mapping entry\n";
- print " -g gid\n";
- print " -o gid is not unique\n";
- print " -r group-rid\n";
- print " -s group-sid\n";
- print " -t group-type\n";
- print " -p print the gidNumber to stdout\n";
- print " -? show this help message\n";
- exit (1);
+ print "Usage: $0 [-go?] groupname\n";
+ print " -g gid\n";
+ print " -o gid is not unique\n";
+ print " -? show this help message\n";
+ exit (1);
}
my $_groupName = $ARGV[0];
if (defined(get_group_dn($_groupName))) {
- warn "$0: group $_groupName exists\n";
- exit (6);
+ print "$0: group $_groupName exists\n";
+ exit (6);
}
my $_groupGidNumber = $Options{'g'};
-if (! defined ($_groupGidNumber = group_add($_groupName, $_groupGidNumber, $Options{'o'}))) {
- warn "$0: error adding group $_groupName\n";
- exit (6);
-}
-
-my $group_sid;
-my $tmp;
-if ($tmp= $Options{'s'}) {
- if ($tmp =~ /^S-(?:\d+-)+\d+$/) {
- $group_sid = $tmp;
- } else {
- warn "$0: illegal group-rid $tmp\n";
- exit(7);
- }
-} elsif ($Options{'r'} || $Options{'a'}) {
- my $group_rid;
- if ($tmp= $Options{'r'}) {
- if ($tmp =~ /^\d+$/) {
- $group_rid = $tmp;
- } else {
- warn "$0: illegal group-rid $tmp\n";
- exit(7);
- }
- } else {
- # algorithmic mapping
- $group_rid = 2*$_groupGidNumber+1001;
- }
- $group_sid = $SID.'-'.$group_rid;
-}
-if ($Options{'r'} || $Options{'a'} || $Options{'s'}) {
- # let's test if this SID already exist
- my $test_exist_sid=does_sid_exist($group_sid,$groupsdn);
- if ($test_exist_sid->count == 1) {
- warn "Group SID already owned by\n";
- # there should not exist more than one entry, but ...
- foreach my $entry ($test_exist_sid->all_entries) {
- my $dn= $entry->dn;
- chomp($dn);
- warn "$dn\n";
- }
- exit(7);
- }
+if (!group_add($_groupName, $_groupGidNumber, $Options{'o'})) {
+ print "$0: error adding group $_groupName\n";
+ exit (6);
}
-if ($group_sid) {
- my $group_type;
- my $tmp;
- if ($tmp= $Options{'t'}) {
- unless (defined($group_type = &group_type_by_name($tmp))) {
- warn "$0: unknown group type $tmp\n";
- exit(8);
- }
- } else {
- $group_type = group_type_by_name('domain');
- }
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ( "cn=$_groupName,$groupsdn",
- add => {
- 'objectClass' => 'sambaGroupMapping',
- 'sambaSID' => $group_sid,
- 'sambaGroupType' => $group_type
- }
- );
- $modify->code && warn "failed to delete entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
-}
-
-if ($Options{'p'}) {
- print STDOUT "$_groupGidNumber";
-}
exit(0);
########################################
diff --git a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl
index 4f6839ebe59..3d072585b21 100755
--- a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,39 +23,39 @@
# Purpose of smbldap-groupdel : group (posix) deletion
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
#####################
+
use Getopt::Std;
my %Options;
my $ok = getopts('?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 groupname\n";
- print " -? show this help message\n";
- exit (1);
+ print "Usage: $0 groupname\n";
+ print " -? show this help message\n";
+ exit (1);
}
my $_groupName = $ARGV[0];
my $dn_line;
if (!defined($dn_line = get_group_dn($_groupName))) {
- print "$0: group $_groupName doesn't exist\n";
- exit (6);
+ print "$0: group $_groupName doesn't exist\n";
+ exit (6);
}
my $dn = get_dn_from_line($dn_line);
-group_del($dn);
+my $rc = system "$ldapdelete $dn >/dev/null";
+die "$0: error while deleting group $_groupName\n"
+ unless ($rc == 0);
my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd restart > /dev/null 2>&1";
+ system "/etc/init.d/nscd restart > /dev/null 2>&1";
}
#if (defined($dn_line = get_group_dn($_groupName))) {
diff --git a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl
index 3f9741e0152..f9b42f95b4c 100755
--- a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -24,39 +24,32 @@
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
+
#####################
use Getopt::Std;
my %Options;
-my $ok = getopts('ag:n:m:or:s:t:x:?', \%Options);
+my $ok = getopts('og:n:m:x:?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-a] [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] [-r rid] [-s sid] [-t type] groupname\n";
- print " -a add automatic group mapping entry\n";
- print " -g new gid\n";
- print " -o gid is not unique\n";
- print " -n new group name\n";
- print " -m add members (comma delimited)\n";
- print " -r group-rid\n";
- print " -s group-sid\n";
- print " -t group-type\n";
- print " -x delete members (comma delimted)\n";
- print " -? show this help message\n";
- exit (1);
+ print "Usage: $0 [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] groupname\n";
+ print " -g new gid\n";
+ print " -o gid is not unique\n";
+ print " -n new group name\n";
+ print " -m add members (comma delimited)\n";
+ print " -x delete members (comma delimted)\n";
+ print " -? show this help message\n";
+ exit (1);
}
my $groupName = $ARGV[0];
-my $group_entry;
-if (! ($group_entry = read_group_entry($groupName))) {
- print "$0: group $groupName doesn't exist\n";
- exit (6);
+if (!defined(get_group_dn($groupName))) {
+ print "$0: group $groupName doesn't exist\n";
+ exit (6);
}
my $newname = $Options{'n'};
@@ -64,168 +57,103 @@ my $newname = $Options{'n'};
my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd restart > /dev/null 2>&1";
+ system "/etc/init.d/nscd restart > /dev/null 2>&1";
}
my $gid = getgrnam($groupName);
-unless (defined ($gid)) {
- print "$0: group $groupName not found!\n";
- exit(6);
-}
my $tmp;
if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) {
- if (!defined($Options{'o'})) {
+ if (!defined($Options{'o'})) {
if (defined(getgrgid($tmp))) {
- print "$0: gid $tmp exists\n";
- exit (6);
+ print "$0: gid $tmp exists\n";
+ exit (6);
}
- }
- if (!($gid == $tmp)) {
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
- changes => [
- replace => [gidNumber => $tmp]
- ]
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
- }
-}
+ }
+ if (!($gid == $tmp)) {
+ my $tmpldif =
+"dn: cn=$groupName,$groupsdn
+changetype: modify
+replace: gidNumber
+gidNumber: $tmp
+
+";
+ die "$0: error while modifying group $groupName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+ }
+}
if (defined($newname)) {
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->moddn (
- "cn=$groupName,$groupsdn",
- newrdn => "cn=$newname",
- deleteoldrdn => "1",
- newsuperior => "$groupsdn"
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
+ my $FILE="|$ldapmodrdn >/dev/null";
+ open (FILE, $FILE) || die "$!\n";
+ print FILE <<EOF;
+cn=$groupName,$groupsdn
+cn=$newname
+
+EOF
+ ;
+ close FILE;
+ die "$0: error while modifying group $groupName\n" if ($?);
+
+ my $tmpldif =
+"dn: cn=$newname,$groupsdn
+changetype: modify
+delete: cn
+-
+add: cn
+cn: $newname
+
+";
+ die "$0: error while modifying group $groupName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+
}
# Add members
if (defined($Options{'m'})) {
- my $members = $Options{'m'};
- my @members = split( /,/, $members );
- my $member;
- foreach $member ( @members ) {
- my $group_entry=read_group_entry($groupName);
- $groupsdn=$group_entry->dn;
- if (is_unix_user($member)) {
- if (is_group_member($groupsdn,$member)) {
- print "User $member already in the group\n";
- } else {
- print "adding user $member to group $groupName\n";
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ($groupsdn,
- changes => [
- add => [memberUid => $member]
- ]
- );
- $modify->code && warn "failed to add entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
- }
- } else {
- print "User $member does not exist: create it first !\n";
+ my $members = $Options{'m'};
+ my @members = split( /,/, $members );
+ my $member;
+ foreach $member ( @members ) {
+ my $tmpldif =
+"dn: cn=$groupName,$groupsdn
+changetype: modify
+add: memberUid
+memberUid: $member
+
+";
+ die "$0: error while modifying group $groupName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
}
- }
}
# Delete members
if (defined($Options{'x'})) {
- my $members = $Options{'x'};
- my @members = split( /,/, $members );
- my $member;
- foreach $member ( @members ) {
- my $group_entry=read_group_entry($groupName);
- $groupsdn=$group_entry->dn;
- if (is_group_member("$groupsdn",$member)) {
- print "deleting user $member from group $groupName\n";
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ($groupsdn,
- changes => [
- delete => [memberUid => $member]
- ]
- );
- $modify->code && warn "failed to delete entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
- } else {
- print "User $member is not in the group $groupName!\n";
- }
- }
-}
-
-my $group_sid;
-if ($tmp= $Options{'s'}) {
- if ($tmp =~ /^S-(?:\d+-)+\d+$/) {
- $group_sid = $tmp;
- } else {
- print "$0: illegal group-rid $tmp\n";
- exit(7);
- }
-} elsif ($Options{'r'} || $Options{'a'}) {
- my $group_rid;
- if ($tmp= $Options{'r'}) {
- if ($tmp =~ /^\d+$/) {
- $group_rid = $tmp;
- } else {
- print "$0: illegal group-rid $tmp\n";
- exit(7);
- }
- } else {
- # algorithmic mapping
- $group_rid = 2*$gid+1001;
- }
- $group_sid = $SID.'-'.$group_rid;
-}
-
-if ($group_sid) {
- my @adds;
- my @mods;
- push(@mods, 'sambaSID' => $group_sid);
-
- if ($tmp= $Options{'t'}) {
- my $group_type;
- if (defined($group_type = &group_type_by_name($tmp))) {
- push(@mods, 'sambaGroupType' => $group_type);
- } else {
- print "$0: unknown group type $tmp\n";
- exit(8);
- }
- } else {
- if (! defined($group_entry->get_value('sambaGroupType'))) {
- push(@mods, 'sambaGroupType' => group_type_by_name('domain'));
- }
- }
-
- my @oc = $group_entry->get_value('objectClass');
- unless (grep($_ =~ /^sambaGroupMapping$/i, @oc)) {
- push (@adds, 'objectClass' => 'sambaGroupMapping');
- }
-
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn",
- changes => [
- 'add' => [ @adds ],
- 'replace' => [ @mods ]
- ]
- );
- $modify->code && warn "failed to delete entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind
+ my $members = $Options{'x'};
+ my @members = split( /,/, $members );
+ my $member;
+ foreach $member ( @members ) {
+ my $tmpldif =
+"dn: cn=$groupName,$groupsdn
+changetype: modify
+delete: memberUid
+memberUid: $member
+
+";
+ die "$0: error while modifying group $groupName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+ }
}
$nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd restart > /dev/null 2>&1";
+ system "/etc/init.d/nscd restart > /dev/null 2>&1";
}
exit (0);
@@ -234,19 +162,19 @@ exit (0);
=head1 NAME
-smbldap-groupmod.pl - Modify a group
+ smbldap-groupmod.pl - Modify a group
=head1 SYNOPSIS
-smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group
+ smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group
=head1 DESCRIPTION
-The smbldap-groupmod.pl command modifies the system account files to
- reflect the changes that are specified on the command line.
- The options which apply to the smbldap-groupmod command are
+ The smbldap-groupmod.pl command modifies the system account files to
+ reflect the changes that are specified on the command line.
+ The options which apply to the smbldap-groupmod command are
- -g gid The numerical value of the group's ID. This value must be
+ -g gid The numerical value of the group's ID. This value must be
unique, unless the -o option is used. The value must be non-
negative. Any files which the old group ID is the file
group ID must have the file group ID changed manually.
diff --git a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl
index a9d368763ee..bc5b4d98fbd 100755
--- a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -26,18 +26,16 @@
# . originally by David Le Corfec <david.le-corfec@IDEALX.com>
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
+
use Getopt::Std;
my %Options;
my $ok = getopts('?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-?] group\n";
- print " -? show this help message\n";
+ print "Usage: $0 [-?] group\n";
+ print " -? show this help message\n";
exit (1);
}
diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl
index 54e4d7f7e3f..b1780dec619 100755
--- a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -25,13 +25,10 @@
use strict;
use Getopt::Std;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
-# smbldap-migrate.pl (-? or -h for help)
+# smbldap-migrate.pl (-? for help)
#
# Read pwdump entries on stdin, and add them to the ldap server.
# Output uncreated/unmodified entries (see parameters -C -U)
@@ -39,40 +36,41 @@ use smbldap_conf;
# Errors, debug and stats are output to stderr.
sub modify_account
- {
- my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_;
- # bind to a directory with dn and password
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ("uid=$login,$basedn",
- changes => [
- replace => [sambaLMPassword => "$lmpwd"],
- replace => [sambaNTpassword => "$ntpwd"],
- replace => [gecos => "$gecos"],
- replace => [sambaHomePath => "$homedir"]
- ]
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
- # take down the session
- $ldap_master->unbind;
- }
+{
+ my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_;
+
+ my $tmpldif =
+"dn: uid=$login,$basedn
+changetype: modify
+lmpassword: $lmpwd
+ntpassword: $ntpwd
+gecos: $gecos
+smbHome: $homedir
+
+";
+
+ die "$0: error while modifying user $login\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+}
#####################
my %Options;
-my $ok = getopts('awA:CUW:?h', \%Options);
-
-if ( (!$ok) || ($Options{'?'}) || ($Options{'h'}) ) {
- print "Usage: $0 [-awAWCU?]\n";
- print " -a process only people, ignore computers\n";
- print " -w process only computers, ignore persons\n";
- print " -A <opts> option string passed verbatim to smbldap-useradd for persons\n";
- print " -W <opts> option string passed verbatim to smbldap-useradd for computers\n";
- print " -C if entry not found, don't create it and log it to stdout (default: create it)\n";
- print " -U if entry found, don't update it and log it to stdout (default: update it)\n";
- print " -?|-h show this help message\n";
- exit (1);
+my $ok = getopts('awA:CUW:?', \%Options);
+
+if ( (!$ok) || ($Options{'?'}) ) {
+ print "Usage: $0 [-awAWCU?]\n";
+ print " -a process only people, ignore computers\n";
+ print " -w process only computers, ignore persons\n";
+ print " -A <opts> option string passed verbatim to smbldap-useradd for persons\n";
+ print " -W <opts> option string passed verbatim to smbldap-useradd for computers\n";
+ print " -C if entry not found, don't create it and log it to stdout (default: create it)\n";
+ print " -U if entry found, don't update it and log it to stdout (default: update it)\n";
+ print " -? show this help message\n";
+ exit (1);
}
my %processed = ( 'user' => 0, 'machine' => 0);
@@ -83,14 +81,15 @@ my %errors = ( 'user' => 0, 'machine' => 0);
my %existing = ( 'user' => 0, 'machine' => 0);
my $specialskipped = 0;
-while (<>) {
+while (<>)
+{
my ($login, $rid, $lmpwd, $ntpwd, $gecos, $homedir, $b) = split(/:/, $_);
my $usertype;
my $userbasedn;
my $entry_type = 'user';
- if ($login =~ m/.*\$$/ ) { # computer
+ if ($login =~ m/.*\$$/ ) { # computer
$processed{'machine'}++;
$entry_type = 'machine';
if (defined($Options{'a'})) {
@@ -100,7 +99,8 @@ while (<>) {
$usertype = "-w $Options{'W'}";
$userbasedn = $computersdn;
- } else { # people
+ }
+ else { # people
$processed{'user'}++;
if (defined($Options{'w'})) {
print STDERR "ignoring $login\n";
@@ -117,10 +117,10 @@ while (<>) {
}
# normalize homedir
- # uncomment to replace configured share with share from pwdump
- # if ($homedir eq "") {
- $homedir = $_userSmbHome;
- # }
+# uncomment to replace configured share with share from pwdump
+# if ($homedir eq "") {
+ $homedir = $_userSmbHome;
+# }
# normalize gecos
if (!($gecos eq "")) {
@@ -141,22 +141,26 @@ while (<>) {
print STDERR "error adding $login, skipping\n";
next;
}
- # lem modif... a retirer si pb
- if ($entry_type eq "user") {
+ # lem modif... a retirer si pb
+ if ($entry_type eq "user")
+ {
modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir);
- }
+ }
- $created{$entry_type}++;
- } else { # uid doesn't exist and no create => log
+ $created{$entry_type}++;
+ }
+ else { # uid doesn't exist and no create => log
print "$_";
$logged{$entry_type}++;
}
- } else { # account exists
+ }
+ else { # account exists
$existing{$entry_type}++;
if (!defined($Options{'U'})) { # exists and modify
modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir);
$updated{$entry_type}++;
- } else { # exists and log
+ }
+ else { # exists and log
print "$_";
$logged{$entry_type}++;
}
@@ -187,7 +191,7 @@ print STDERR "special users skipped: $specialskipped\n";
=head1 NAME
-smbldap-migrate.pl - Migrate NT accounts to LDAP
+ smbldap-migrate.pl - Migrate NT accounts to LDAP
=head1 SYNOPSIS
diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl
index a2b07bf817c..0d3dd07d505 100644
--- a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl
@@ -26,57 +26,56 @@
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
use Getopt::Std;
+
+
sub process_rec_group
- {
+{
my ($group, $mb) = @_;
my @members;
if (!(@members = group_get_members($group))) {
- return 0;
+ return 0;
}
foreach my $m (@members) {
- if ( !($m =~ m/^\*/) ) {
+ if ( !($m =~ m/^\*/) ) {
push @{$mb}, $m;
- } else {
+ } else {
my $gname = $m;
$gname =~ s/^.//;
if (!process_rec_group($gname, $mb)) {
- print "recursive group not added : $gname\n";
+ print "recursive group not added : $gname\n";
}
- }
+ }
}
- }
+}
# given a group dn and a list of members, update the group
sub modify_group
- {
+{
my ($group, $dn_line, @members, $recgroup) = @_;
my $m;
my @new_mb;
foreach $m (@members) {
- if ( ($m =~ m/^\*/) ) {
+ if ( ($m =~ m/^\*/) ) {
my $gname = $m;
$gname =~ s/^.//;
if (!$recgroup) {
- print "recursive group not added : $gname\n";
+ print "recursive group not added : $gname\n";
} else {
- if (!process_rec_group($gname, \@new_mb)) {
+ if (!process_rec_group($gname, \@new_mb)) {
print "recursive group not added : $gname\n";
- }
+ }
}
- } else {
+ } else {
push @new_mb, $m;
- }
+ }
}
# new_mb contains flat members from group dump
@@ -92,7 +91,7 @@ sub modify_group
my $mbs;
foreach $m (@new_mb) {
- $mbs .= "memberUid: $m\n";
+ $mbs .= "memberUid: $m\n";
}
my $mods="$dn_line
@@ -103,16 +102,16 @@ $mbs
#print "$mods\n";
my $tmpldif =
- "$mods
+"$mods
";
die "$0: error while modifying group $group\n"
- unless (do_ldapmodify($tmpldif) == 0);
+ unless (do_ldapmodify($tmpldif) == 0);
undef $tmpldif;
- }
+}
sub display_group
- {
+{
my ($group, @members) = @_;
print "Group name $group\n";
@@ -120,43 +119,43 @@ sub display_group
my $m;
my $i = 0;
foreach $m (@members) {
- print "$m ";
- if ($i % 5 == 0) {
+ print "$m ";
+ if ($i % 5 == 0) {
print "\n";
- }
- $i++;
+ }
+ $i++;
}
- }
+}
sub process_group
- {
+{
my ($group, @members, $nocreate, $noupdate, $recgroup) = @_;
my $dn_line;
if (!defined($dn_line = get_group_dn($group))) {
- # group not found, create it ?
- if (!$nocreate) {
+ # group not found, create it ?
+ if (!$nocreate) {
system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5";
if (!defined($dn_line = get_group_dn($group))) {
- return 1;
+ return 1;
}
modify_group($group, $dn_line, @members, $recgroup);
- } else {
+ } else {
# don't create
print "not created:\n";
display_group($group, @members);
- }
+ }
} else {
- # group found, update it ?
- if (!$noupdate) {
+ # group found, update it ?
+ if (!$noupdate) {
modify_group($group, $dn_line, @members, $recgroup);
- } else {
+ } else {
# don't update
print "not updated:\n";
display_group($group, @members);
- }
+ }
}
- }
+}
###################################################
@@ -164,11 +163,11 @@ my %Options;
my $ok = getopts('CUr?', \%Options);
if ( (!$ok) || ($Options{'?'}) ) {
- print "Usage: $0 [-CUr?] < group_dump\n";
- print " -C don't create group if it doesn't exist\n";
- print " -U don't update group if it exists\n";
- print " -r recursively process groups\n";
- exit(1);
+ print "Usage: $0 [-CUr?] < group_dump\n";
+ print " -C don't create group if it doesn't exist\n";
+ print " -U don't update group if it exists\n";
+ print " -r recursively process groups\n";
+ exit(1);
}
my $group_name;
@@ -176,19 +175,20 @@ my $group_desc;
my $has_members = 0;
my @members = ();
-while (<>) {
+while (<>)
+{
my $line = $_;
chomp($line);
next if ( $line =~ m/^\s*$/ );
if ($group_name eq "") {
- if ( $line =~ m/^Group name\s+(.+).$/ ) {
+ if ( $line =~ m/^Group name\s+(.+).$/ ) {
$group_name = $1;
next;
- }
+ }
}
if ($group_desc eq "") {
- if ( $line =~ m/^Comment\s+(.*)$/ ) {
+ if ( $line =~ m/^Comment\s+(.*)$/ ) {
$group_desc = $1;
next;
}
diff --git a/examples/LDAP/smbldap-tools/smbldap-passwd.pl b/examples/LDAP/smbldap-tools/smbldap-passwd.pl
index afbc87a058d..ef7687a49e1 100755
--- a/examples/LDAP/smbldap-tools/smbldap-passwd.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl
@@ -1,7 +1,6 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# LDAP to unix password sync script for samba
-
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
#
@@ -23,13 +22,10 @@
# USA.
# Purpose :
-# . ldap-unix passwd sync for SAMBA>2.2.2 + LDAP
+# . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP
# . may also replace /bin/passwd
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
@@ -40,29 +36,29 @@ my $ret;
my $arg;
foreach $arg (@ARGV) {
- if ($< != 0) {
- die "Only root can specify parameters\n";
- } else {
- if ( ($arg eq '-?') || ($arg eq '--help') ) {
- print "Usage: $0 [username]\n";
- print " -?, --help show this help message\n";
- exit (6);
- } elsif (substr($arg,0) ne '-') {
- $user = $arg;
+ if ($< != 0) {
+ die "Only root can specify parameters\n";
+ } else {
+ if ( ($arg eq '-?') || ($arg eq '--help') ) {
+ print "Usage: $0 [username]\n";
+ print " -?, --help show this help message\n";
+ exit (6);
+ } elsif (substr($arg,0) ne '-') {
+ $user = $arg;
+ }
+ $oldpass = 1;
}
- $oldpass = 1;
- }
}
if (!defined($user)) {
- $user=$ENV{"USER"};
+ $user=$ENV{"USER"};
}
# test existence of user in LDAP
my $dn_line;
if (!defined($dn_line = get_user_dn($user))) {
- print "$0: user $user doesn't exist\n";
- exit (10);
+ print "$0: user $user doesn't exist\n";
+ exit (10);
}
my $dn = get_dn_from_line($dn_line);
@@ -73,17 +69,17 @@ print "Changing password for $user\n";
# non-root user
if (!defined($oldpass)) {
- # prompt for current password
- system "stty -echo";
- print "(current) UNIX password: ";
- chomp($oldpass=<STDIN>);
- print "\n";
- system "stty echo";
-
- if (!is_user_valid($user, $dn, $oldpass)) {
- print "Authentication failure\n";
- exit (10);
- }
+ # prompt for current password
+ system "stty -echo";
+ print "(current) UNIX password: ";
+ chomp($oldpass=<STDIN>);
+ print "\n";
+ system "stty echo";
+
+ if (!is_user_valid($user, $dn, $oldpass)) {
+ print "Authentication failure\n";
+ exit (10);
+ }
}
# prompt for new password
@@ -104,77 +100,69 @@ print "\n";
system "stty echo";
if ($pass ne $pass2) {
- print "New passwords don't match!\n";
- exit (10);
+ print "New passwords don't match!\n";
+ exit (10);
}
-# First, connecting to the directory
-my $ldap_master=connect_ldap_master();
-
# only modify smb passwords if smb user
if ($samba == 1) {
- if (!$with_smbpasswd) {
- # generate LanManager and NT clear text passwords
+ if (!$with_smbpasswd) {
+# generate LanManager and NT clear text passwords
if ($mk_ntpasswd eq '') {
- print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
- exit(1);
+ print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
+ exit(1);
}
my $ntpwd = `$mk_ntpasswd '$pass'`;
- chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':')));
- chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1));
- # the sambaPwdLastSet must be updating
- my $date=time;
- my @mods;
- push(@mods, 'sambaLMPassword' => $sambaLMPassword);
- push(@mods, 'sambaNTPassword' => $sambaNTPassword);
- push(@mods, 'sambaPwdLastSet' => $date);
- if (defined $_defaultMaxPasswordAge) {
- my $new_sambaPwdMustChange=$date+$_defaultMaxPasswordAge*24*60*60;
- push(@mods, 'sambaPwdMustChange' => $new_sambaPwdMustChange);
- push(@mods, 'sambaAcctFlags' => '[U]');
- }
- # Let's change nt/lm passwords
- my $modify = $ldap_master->modify ( "$dn",
- 'replace' => { @mods }
- );
- $modify->code && warn "failed to modify entry: ", $modify->error ;
-
- } else {
+ chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+ chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+# change nt/lm passwords
+ my $tmpldif =
+"$dn_line
+changetype: modify
+replace: lmpassword
+lmpassword: $lmpassword
+-
+changetype: modify
+replace: ntpassword
+ntpassword: $ntpassword
+-
+
+";
+ die "$0: error while modifying password for $user\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+ }
+ else {
if ($< != 0) {
- my $FILE="|$smbpasswd -s >/dev/null";
- open (FILE, $FILE) || die "$!\n";
- print FILE <<EOF;
+ my $FILE="|$smbpasswd -s >/dev/null";
+ open (FILE, $FILE) || die "$!\n";
+ print FILE <<EOF;
'$oldpass'
'$pass'
'$pass'
EOF
- ;
- close FILE;
+ ;
+ close FILE;
} else {
- my $FILE="|$smbpasswd $user -s >/dev/null";
- open (FILE, $FILE) || die "$!\n";
- print FILE <<EOF;
+ my $FILE="|$smbpasswd $user -s >/dev/null";
+ open (FILE, $FILE) || die "$!\n";
+ print FILE <<EOF;
'$pass'
'$pass'
EOF
- ;
- close FILE;
+ ;
+ close FILE;
}
- }
+ }
}
-
# change unix password
-my $hash_password = `slappasswd -h {$hash_encrypt} -s '$pass'`;
-chomp($hash_password);
-my $modify = $ldap_master->modify ( "$dn",
- changes => [
- replace => [userPassword => "$hash_password"]
- ]
- );
-$modify->code && warn "Unable to change password : ", $modify->error ;
-
-# take down session
-$ldap_master->unbind;
+$ret = system "$ldappasswd $dn -s '$pass' > /dev/null";
+if ($ret == 0) {
+ print "all authentication tokens updated successfully\n";
+} else {
+ return $ret;
+}
exit 0;
@@ -191,7 +179,7 @@ smbldap-passwd.pl - change user password
=head1 DESCRIPTION
-smbldap-passwd.pl changes passwords for user accounts. A normal user
+ smbldap-passwd.pl changes passwords for user accounts. A normal user
may only change the password for their own account, the super user may
change the password for any account.
diff --git a/examples/LDAP/smbldap-tools/smbldap-populate.pl b/examples/LDAP/smbldap-tools/smbldap-populate.pl
index b691a848500..5be9ca4262a 100755
--- a/examples/LDAP/smbldap-tools/smbldap-populate.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl
@@ -1,8 +1,7 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# Populate a LDAP base for Samba-LDAP usage
#
-
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
#
@@ -28,83 +27,75 @@
# . For lazy people, replace ldapadd (with only an ldif parameter)
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
+
use Getopt::Std;
-use Net::LDAP::LDIF;
use vars qw(%oc);
# objectclass of the suffix
%oc = (
- "ou" => "organizationalUnit",
- "o" => "organization",
- "dc" => "dcObject",
- );
+ "ou" => "organizationalUnit",
+ "o" => "organization",
+ "dc" => "dcObject",
+);
my %Options;
my $ok = getopts('a:b:?', \%Options);
if ( (!$ok) || ($Options{'?'}) ) {
- print "Usage: $0 [-ab?] [ldif]\n";
- print " -a administrator login name (default: Administrator)\n";
- print " -b guest login name (default: nobody)\n";
- print " -? show this help message\n";
- print " ldif file to add to ldap (default: suffix, Groups,";
- print " Users, Computers and builtin users )\n";
- exit (1);
+ print "Usage: $0 [-ab?] [ldif]\n";
+ print " -a administrator login name (default: Administrator)\n";
+ print " -b guest login name (default: nobody)\n";
+ print " -? show this help message\n";
+ print " ldif file to add to ldap (default: suffix, Groups,";
+ print " Users, Computers and builtin users )\n";
+ exit (1);
}
my $_ldifName;
-my $tmp_ldif_file="/tmp/$$.ldif";
if (@ARGV >= 1) {
- $_ldifName = $ARGV[0];
+ $_ldifName = $ARGV[0];
}
my $adminName = $Options{'a'};
if (!defined($adminName)) {
- $adminName = "Administrator";
+ $adminName = "Administrator";
}
my $guestName = $Options{'b'};
if (!defined($guestName)) {
- $guestName = "nobody";
+ $guestName = "nobody";
}
if (!defined($_ldifName)) {
- my $attr;
- my $val;
- my $objcl;
+ my $attr;
+ my $val;
+ my $objcl;
- print "Using builtin directory structure\n";
- if ($suffix =~ m/([^=]+)=([^,]+)/) {
+ if ($suffix =~ m/([^=]+)=([^,]+)/) {
$attr = $1;
$val = $2;
$objcl = $oc{$attr} if (exists $oc{$attr});
if (!defined($objcl)) {
- $objcl = "myhardcodedobjectclass";
+ $objcl = "myhardcodedobjectclass";
}
- } else {
+ } else {
die "can't extract first attr and value from suffix $suffix";
- }
- #print "$attr=$val\n";
- my ($organisation,$ext) = ($suffix =~ m/dc=(.*),dc=(.*)$/);
+ }
+ #print "$attr=$val\n";
- #my $FILE="|cat";
- my $FILE=$tmp_ldif_file;
- open (FILE, ">$FILE") || die "Can't open file $FILE: $!\n";
+ #my $FILE="|cat";
+ my $FILE="|$ldapadd -c";
+ open (FILE, $FILE) || die "$!\n";
- print FILE <<EOF;
+ print FILE <<EOF;
dn: $suffix
objectClass: $objcl
-objectclass: organization
$attr: $val
-o: $organisation
dn: $usersdn
objectClass: organizationalUnit
@@ -120,211 +111,142 @@ ou: $computersou
dn: uid=$adminName,$usersdn
cn: $adminName
-sn: $adminName
-objectClass: inetOrgPerson
-objectClass: sambaSamAccount
+objectClass: sambaAccount
objectClass: posixAccount
gidNumber: 512
uid: $adminName
uidNumber: 998
homeDirectory: $_userHomePrefix
-sambaPwdLastSet: 0
-sambaLogonTime: 0
-sambaLogoffTime: 2147483647
-sambaKickoffTime: 2147483647
-sambaPwdCanChange: 0
-sambaPwdMustChange: 2147483647
-sambaHomePath: $_userSmbHome
-sambaHomeDrive: $_userHomeDrive
-sambaProfilePath: $_userProfile
-sambaPrimaryGroupSID: $SID-512
-sambaLMPassword: XXX
-sambaNTPassword: XXX
-sambaAcctFlags: [U ]
-sambaSID: $SID-2996
+pwdLastSet: 0
+logonTime: 0
+logoffTime: 2147483647
+kickoffTime: 2147483647
+pwdCanChange: 0
+pwdMustChange: 2147483647
+smbHome: $_userSmbHome
+homeDrive: $_userHomeDrive
+profilePath: $_userProfile
+rid: 500
+primaryGroupID: 512
+lmPassword: XXX
+ntPassword: XXX
+acctFlags: [U ]
loginShell: /bin/false
gecos: Netbios Domain Administrator
dn: uid=$guestName,$usersdn
cn: $guestName
-sn: $guestName
-objectClass: inetOrgPerson
-objectClass: sambaSamAccount
+objectClass: sambaAccount
objectClass: posixAccount
gidNumber: 514
uid: $guestName
uidNumber: 999
homeDirectory: /dev/null
-sambaPwdLastSet: 0
-sambaLogonTime: 0
-sambaLogoffTime: 2147483647
-sambaKickoffTime: 2147483647
-sambaPwdCanChange: 0
-sambaPwdMustChange: 2147483647
-sambaHomePath: $_userSmbHome
-sambaHomeDrive: $_userHomeDrive
-sambaProfilePath: $_userProfile
-sambaPrimaryGroupSID: $SID-514
-sambaLMPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
-sambaNTPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
-sambaAcctFlags: [NU ]
-sambaSID: $SID-2998
+pwdLastSet: 0
+logonTime: 0
+logoffTime: 2147483647
+kickoffTime: 2147483647
+pwdCanChange: 0
+pwdMustChange: 2147483647
+smbHome: $_userSmbHome
+homeDrive: $_userHomeDrive
+profilePath: $_userProfile
+rid: 501
+primaryGroupID: 514
+lmPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
+ntPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
+acctFlags: [NU ]
loginShell: /bin/false
dn: cn=Domain Admins,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 512
cn: Domain Admins
memberUid: $adminName
-description: Netbios Domain Administrators
-sambaSID: $SID-512
-sambaGroupType: 2
-displayName: Domain Admins
+description: Netbios Domain Administrators (need smb.conf configuration)
dn: cn=Domain Users,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 513
cn: Domain Users
-description: Netbios Domain Users
-sambaSID: $SID-513
-sambaGroupType: 2
-displayName: Domain Users
+description: Netbios Domain Users (not implemented yet)
dn: cn=Domain Guests,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 514
cn: Domain Guests
-description: Netbios Domain Guests Users
-sambaSID: $SID-514
-sambaGroupType: 2
-displayName: Domain Guests
+description: Netbios Domain Guests Users (not implemented yet)
dn: cn=Administrators,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 544
cn: Administrators
-description: Netbios Domain Members can fully administer the computer/sambaDomainName
-sambaSID: $SID-544
-sambaGroupType: 2
-displayName: Administrators
+description: Netbios Domain Members can fully administer the computer/domain (not implemented yet)
dn: cn=Users,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 545
cn: Users
-description: Netbios Domain Ordinary users
-sambaSID: $SID-545
-sambaGroupType: 2
-displayName: users
+description: Netbios Domain Ordinary users (not implemented yet)
dn: cn=Guests,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 546
cn: Guests
memberUid: $guestName
-description: Netbios Domain Users granted guest access to the computer/sambaDomainName
-sambaSID: $SID-546
-sambaGroupType: 2
-displayName: Guests
+description: Netbios Domain Users granted guest access to the computer/domain (not implemented yet)
+
dn: cn=Power Users,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 547
cn: Power Users
-description: Netbios Domain Members can share directories and printers
-sambaSID: $SID-547
-sambaGroupType: 2
-displayName: Power Users
+description: Netbios Domain Members can share directories and printers (not implemented yet)
dn: cn=Account Operators,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 548
cn: Account Operators
-description: Netbios Domain Users to manipulate users accounts
-sambaSID: $SID-548
-sambaGroupType: 2
-displayName: Account Operators
+description: Netbios Domain Users to manipulate users accounts (not implemented yet)
dn: cn=Server Operators,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 549
cn: Server Operators
-description: Netbios Domain Server Operators
-sambaSID: $SID-549
-sambaGroupType: 2
-displayName: Server Operators
+description: Netbios Domain Server Operators (need smb.conf configuration)
dn: cn=Print Operators,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 550
cn: Print Operators
-description: Netbios Domain Print Operators
-sambaSID: $SID-550
-sambaGroupType: 2
-displayName: Print Operators
+description: Netbios Domain Print Operators (need smb.conf configuration)
dn: cn=Backup Operators,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 551
cn: Backup Operators
-description: Netbios Domain Members can bypass file security to back up files
-sambaSID: $SID-551
-sambaGroupType: 2
-displayName: Backup Operators
+description: Netbios Domain Members can bypass file security to back up files (not implemented yet)
dn: cn=Replicator,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 552
cn: Replicator
-description: Netbios Domain Supports file replication in a sambaDomainName
-sambaSID: $SID-552
-sambaGroupType: 2
-displayName: Replicator
+description: Netbios Domain Supports file replication in a domain (not implemented yet)
dn: cn=Domain Computers,$groupsdn
objectClass: posixGroup
-objectClass: sambaGroupMapping
gidNumber: 553
cn: Domain Computers
description: Netbios Domain Computers accounts
-sambaSID: $SID-553
-sambaGroupType: 2
-displayName: Domain Computers
EOF
- close FILE;
+ close FILE;
+ exit($?)
+
} else {
- $tmp_ldif_file=$_ldifName;
+ exec "$ldapadd < $_ldifName";
}
-my $ldap_master=connect_ldap_master();
-my $ldif = Net::LDAP::LDIF->new($tmp_ldif_file, "r", onerror => 'undef' );
-while( not $ldif->eof() ) {
- my $entry = $ldif->read_entry();
- if ( $ldif->error() ) {
- print "Error msg: ",$ldif->error(),"\n";
- print "Error lines:\n",$ldif->error_lines(),"\n";
- } else {
- my $dn = $entry->dn;
- print "adding new entry: $dn\n";
- my $result=$ldap_master->add($entry);
- $result->code && warn "failed to add entry: ", $result->error ;
- }
-}
-$ldap_master->unbind;
-system "rm -f $tmp_ldif_file";
exit(0);
@@ -332,11 +254,11 @@ exit(0);
=head1 NAME
-smbldap-populate.pl - Populate your LDAP database
+ smbldap-populate.pl - Populate your LDAP database
=head1 SYNOPSIS
- smbldap-populate.pl [ldif-file]
+ smbldap-populate.pl [ldif-file]
=head1 DESCRIPTION
@@ -351,7 +273,9 @@ smbldap-populate.pl - Populate your LDAP database
If you give an extra parameter, it is assumed to be the ldif
file to use instead of the builtin one. Options -a and -b
- will be ignored.
+ will be ignored. This usage mode makes the command behave
+ like ldapadd(1) with extra parameters taken from the smbldap-tools
+ config (smbldap_conf.pm).
=head1 FILES
diff --git a/examples/LDAP/smbldap-tools/smbldap-tools.spec b/examples/LDAP/smbldap-tools/smbldap-tools.spec
index 4bd2968defe..b0c07ba02a0 100755
--- a/examples/LDAP/smbldap-tools/smbldap-tools.spec
+++ b/examples/LDAP/smbldap-tools/smbldap-tools.spec
@@ -1,6 +1,6 @@
# $Source: /home/cvs/samba/examples/LDAP/smbldap-tools/smbldap-tools.spec,v $
-%define version 0.8.2
-%define release 1
+%define version 0.7
+%define release 1
%define name smbldap-tools
%define realname smbldap-tools
@@ -13,7 +13,7 @@ License: GPL
Vendor: IDEALX S.A.S.
URL: http://samba.IDEALX.org/
-Packager: Jerome Tournier <jerome.tournier@IDEALX.com>
+Packager: Olivier Lemaire <olivier.lemaire@IDEALX.com>
Source0: smbldap-groupadd.pl
Source1: smbldap-groupdel.pl
Source2: smbldap-groupmod.pl
@@ -36,7 +36,6 @@ Source18: smbldap-populate.pl
Source19: smbldap-migrate-accounts.pl
Source20: smbldap-migrate-groups.pl
Source21: INFRA
-Source22: smb.conf
BuildRoot: /%{_tmppath}/%{name}
Prefix: /usr/local
BuildRequires: perl >= 5.6
@@ -61,8 +60,8 @@ make
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{prefix}/sbin
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share
-mkdir -p $RPM_BUILD_ROOT/usr/share/doc
-mkdir -p $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools
+mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc
+mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools
cd mkntpwd ; make PREFIX=$RPM_BUILD_ROOT/%{prefix} install
@@ -81,28 +80,20 @@ install -m 555 %{SOURCE10} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap_tools.pm
install -m 550 %{SOURCE19} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-migrate-accounts.pl
install -m 550 %{SOURCE20} $RPM_BUILD_ROOT/%{prefix}/sbin/smbldap-migrate-groups.pl
-install -m 644 %{SOURCE11} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/CONTRIBUTORS
-install -m 644 %{SOURCE12} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/COPYING
-install -m 644 %{SOURCE13} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/ChangeLog
-install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/FILES
-install -m 644 %{SOURCE15} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/README
-install -m 644 %{SOURCE16} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/TODO
-install -m 644 %{SOURCE21} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/INFRA
-install -m 644 %{SOURCE22} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/smb.conf
+install -m 644 %{SOURCE11} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/CONTRIBUTORS
+install -m 644 %{SOURCE12} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/COPYING
+install -m 644 %{SOURCE13} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/ChangeLog
+install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/FILES
+install -m 644 %{SOURCE15} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/README
+install -m 644 %{SOURCE16} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/TODO
+install -m 644 %{SOURCE21} $RPM_BUILD_ROOT/%{prefix}/share/doc/smbldap-tools/INFRA
%clean
rm -rf $RPM_BUILD_ROOT
%post
-# from smbldap-tools-0.8-2, librairies are loaded with the FindBin perl package
-if [ -f /usr/lib/perl5/site_perl/smbldap_tools.pm ];
-then
- rm -f /usr/lib/perl5/site_perl/smbldap_tools.pm
-fi
-if [ -f /usr/lib/perl5/site_perl/smbldap_conf.pm ];
-then
- rm -f /usr/lib/perl5/site_perl/smbldap_conf.pm
-fi
+ln -sf %{prefix}/sbin/smbldap_tools.pm /usr/lib/perl5/site_perl/smbldap_tools.pm
+ln -sf %{prefix}/sbin/smbldap_conf.pm /usr/lib/perl5/site_perl/smbldap_conf.pm
chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /usr/local/sbin. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC."
perl -i -pe 's/_SLAVELDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_MASTERLDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm
@@ -111,11 +102,11 @@ perl -i -pe 's/_USERS_/Users/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_COMPUTERS_/Computers/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_GROUPS_/Groups/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_LOGINSHELL_/\/bin\/bash/' %{prefix}/sbin/smbldap_conf.pm
-perl -i -pe 's/_HOMEPREFIX_/\/home/' %{prefix}/sbin/smbldap_conf.pm
+perl -i -pe 's/_USERHOMEPREFIX_/\/home\//' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_BINDDN_/cn=Manager,\$suffix/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_BINDPW_/secret/' %{prefix}/sbin/smbldap_conf.pm
perl -i -pe 's/_PDCNAME_/PDC-SRV/' %{prefix}/sbin/smbldap_conf.pm
-perl -i -pe 's/_HOMEDRIVE_/H:/' %{prefix}/sbin/smbldap_conf.pm
+perl -i -pe 's/_HOMEDRIVE_/D/' %{prefix}/sbin/smbldap_conf.pm
# FIXME: links should not be removed on upgrade
#%postun
@@ -128,13 +119,51 @@ perl -i -pe 's/_HOMEDRIVE_/H:/' %{prefix}/sbin/smbldap_conf.pm
%defattr(-,root,root)
%{prefix}/sbin/*.pl
%{prefix}/sbin/smbldap_tools.pm
-%config(noreplace) %{prefix}/sbin/smbldap_conf.pm
+%config %{prefix}/sbin/smbldap_conf.pm
%{prefix}/sbin/mkntpwd
-%doc /usr/share/doc/%{name}/
+%doc %{prefix}/share/doc/%{name}/TODO
+%doc %{prefix}/share/doc/%{name}/README
+%doc %{prefix}/share/doc/%{name}/CONTRIBUTORS
+%doc %{prefix}/share/doc/%{name}/FILES
+%doc %{prefix}/share/doc/%{name}/COPYING
%changelog
-* Fri Nov 28 2003 Jerome Tournier <jerome.tournier@idealx.com> 0.8.2-1
-- new smb.conf file as example configuration file
-- see Changelog file for updates in scripts
+* Sat Jun 1 2002 Olivier Lemaire <olem@IDEALX.com> 0.7-1
+- some bugfixes about smbldap-populate
+- bugfixed the smbpasswd call in smbldap-useradd
+- cleaned up the smbldap_conf
+- more documentation
+* Tue Apr 30 2002 Brad Langhorst <brad@langhorst.com> 0.6-2
+- changed requires samba-common to samba
+- replaced /usr/local with %{prefix} to allow relocation
+
+* Tue Feb 5 2002 David Le Corfec <dlc@IDEALX.com> 0.6-1
+- v0.6
+
+* Mon Feb 4 2002 David Le Corfec <dlc@IDEALX.com> 0.5-1
+- v0.5
+
+* Mon Jan 14 2002 David Le Corfec <dlc@IDEALX.com> 0.3-4
+- internal changes
+- should upgrade smoothly from now on
+
+* Mon Jan 14 2002 David Le Corfec <dlc@IDEALX.com> 0.2-1
+- added migration scripts
+
+* Fri Dec 28 2001 David Le Corfec <dlc@IDEALX.com> 0.1-5
+- numeric group for chmod
+
+* Thu Dec 27 2001 David Le Corfec <dlc@IDEALX.com> 0.1-4
+- misc bugfixes
+
+* Mon Dec 18 2001 David Le Corfec <dlc@IDEALX.com> 0.1-3
+- changed files attrs for domain admins to add users
+- added smbldap-populate.pl
+
+* Fri Dec 14 2001 David Le Corfec <dlc@IDEALX.com>
+- added mkntpwd
+
+* Wed Dec 12 2001 Olivier Lemaire <olivier.lemaire@IDEALX.com>
+- Spec file was generated, and tested atomically.
diff --git a/examples/LDAP/smbldap-tools/smbldap-useradd.pl b/examples/LDAP/smbldap-tools/smbldap-useradd.pl
index 918bd4a4f66..508487af937 100755
--- a/examples/LDAP/smbldap-tools/smbldap-useradd.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,231 +23,196 @@
# Purpose of smbldap-useradd : user (posix,shadow,samba) add
use strict;
-
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
+
#####################
use Getopt::Std;
my %Options;
-my $ok = getopts('anmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options);
+my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n";
- print " -a is a Windows User (otherwise, Posix stuff only)\n";
- print " -w is a Windows Workstation (otherwise, Posix stuff only)\n";
- print " -u uid\n";
- print " -g gid\n";
- print " -G supplementary comma-separated groups\n";
- print " -n do not create a group\n";
- print " -d home\n";
- print " -s shell\n";
- print " -c gecos\n";
- print " -m creates home directory and copies /etc/skel\n";
- print " -k skeleton dir (with -m)\n";
- print " -P ends by invoking smbldap-passwd.pl\n";
- print " -A can change password ? 0 if no, 1 if yes\n";
- print " -B must change password ? 0 if no, 1 if yes\n";
- print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
- print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n";
- print " -E sambaLogonScript (DOS script to execute on login)\n";
- print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
- print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
- print " -N canonical name\n";
- print " -S surname\n";
- print " -? show this help message\n";
- exit (1);
+ print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n";
+ print " -a is a Windows User (otherwise, Posix stuff only)\n";
+ print " -w is a Windows Workstation (otherwise, Posix stuff only)\n";
+ print " -x creates rid and primaryGroupID in hex instead of decimal\n";
+ print " -u uid\n";
+ print " -g gid\n";
+ print " -G supplementary comma-separated groups\n";
+ print " -n do not create a group\n";
+ print " -d home\n";
+ print " -s shell\n";
+ print " -c gecos\n";
+ print " -m creates home directory and copies /etc/skel\n";
+ print " -k skeleton dir (with -m)\n";
+ print " -P ends by invoking smbldap-passwd.pl\n";
+ print " -A can change password ? 0 if no, 1 if yes\n";
+ print " -B must change password ? 0 if no, 1 if yes\n";
+ print " -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')\n";
+ print " -D homeDrive (letter associated with home share, like 'H:')\n";
+ print " -E scriptPath (DOS script to execute on login)\n";
+ print " -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
+ print " -H acctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
+ print " -? show this help message\n";
+ exit (1);
}
-
# cause problems when dealing with getpwuid because of the
# negative ttl and ldap modification
my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd stop > /dev/null 2>&1";
+ system "/etc/init.d/nscd stop > /dev/null 2>&1";
}
-
# Read options
my $userUidNumber = $Options{'u'};
if (!defined($userUidNumber)) {
- # find first unused uid starting from $UID_START
- while (defined(getpwuid($UID_START))) {
- $UID_START++;
- }
- $userUidNumber = $UID_START;
-} elsif (getpwuid($userUidNumber)) {
- die "Uid already exists.\n";
-}
+ # find first unused uid starting from $UID_START
+ while (defined(getpwuid($UID_START))) {
+ $UID_START++;
+ }
+ $userUidNumber = $UID_START;
+} elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; }
if ($nscd_status == 0) {
- system "/etc/init.d/nscd start > /dev/null 2>&1";
+ system "/etc/init.d/nscd start > /dev/null 2>&1";
}
+# as rid we use 2 * uid + 1000
+my $userRid = 2 * $userUidNumber + 1000;
+if (defined($Options{'x'})) {
+ $userRid= sprint("%x", $userRid);
+}
+
my $createGroup = 0;
my $userGidNumber = $Options{'g'};
# gid not specified ?
if (!defined($userGidNumber)) {
- # windows machine => $_defaultComputerGid
- if (defined($Options{'w'})) {
+ # windows machine => $_defaultComputerGid
+ if (defined($Options{'w'})) {
$userGidNumber = $_defaultComputerGid;
- # } elsif (!defined($Options{'n'})) {
+# } elsif (!defined($Options{'n'})) {
# create new group (redhat style)
# find first unused gid starting from $GID_START
- # while (defined(getgrgid($GID_START))) {
- # $GID_START++;
- # }
- # $userGidNumber = $GID_START;
+# while (defined(getgrgid($GID_START))) {
+# $GID_START++;
+# }
+# $userGidNumber = $GID_START;
- # $createGroup = 1;
+# $createGroup = 1;
- } else {
+ } else {
# user will have gid = $_defaultUserGid
$userGidNumber = $_defaultUserGid;
- }
+ }
} else {
- my $gid;
- if (($gid = parse_group($userGidNumber)) < 0) {
+ my $gid;
+ if (($gid = parse_group($userGidNumber)) < 0) {
print "$0: unknown group $userGidNumber\n";
exit (6);
- }
- $userGidNumber = $gid;
+ }
+ $userGidNumber = $gid;
}
+# as grouprid we use 2 * gid + 1001
+my $userGroupRid = 2 * $userGidNumber + 1001;
+if (defined($Options{'x'})) {
+ $userGroupRid = sprint("%x", $userGroupRid);
+}
# Read only first @ARGV
my $userName = $ARGV[0];
-# untaint $userName (can finish with one or two $)
-if ($userName =~ /^([\w -]+\$?)$/) {
- $userName = $1;
-} else {
- print "$0: illegal username\n";
- exit (1);
-}
-
# user must not exist in LDAP (should it be nss-wide ?)
my ($rc, $dn) = get_user_dn2($userName);
if ($rc and defined($dn)) {
- print "$0: user $userName exists\n";
- exit (9);
+ print "$0: user $userName exists\n";
+ exit (9);
} elsif (!$rc) {
- print "$0: error in get_user_dn2\n";
- exit(10);
-}
-
-my $group_entry;
-my $userGroupSID;
-my $userRid;
-if ($Options{'a'}) {
- # as grouprid we use the value of the sambaSID attribute for
- # group of gidNumber=$userGidNumber
- $group_entry = read_group_entry_gid($userGidNumber);
- $userGroupSID = $group_entry->get_value('sambaSID');
- unless ($userGroupSID) {
- print "$0: unknown group SID not set for unix group $userGidNumber\n";
- print "check if your unix group is mapped to an NT group\n";
- exit (7);
- }
-
- # as rid we use 2 * uid + 1000
- $userRid = 2 * $userUidNumber + 1000;
- # let's test if this SID already exist
- my $user_sid="$SID-$userRid";
- my $test_exist_sid=does_sid_exist($user_sid,$usersdn);
- if ($test_exist_sid->count == 1) {
- print "User SID already owned by\n";
- # there should not exist more than one entry, but ...
- foreach my $entry ($test_exist_sid->all_entries) {
- my $dn= $entry->dn;
- chomp($dn);
- print "$dn\n";
- }
- exit(7);
- }
+ print "$0: error in get_user_dn2\n";
+ exit(10);
}
my $userHomeDirectory;
-my ($userCN, $userSN);
my $tmp;
-if (!defined($userHomeDirectory = $Options{'d'})) {
- $userHomeDirectory = $_userHomePrefix."/".$userName;
+if (!defined($userHomeDirectory = $Options{'d'}))
+{
+ $userHomeDirectory = $_userHomePrefix.$userName;
}
$_userLoginShell = $tmp if (defined($tmp = $Options{'s'}));
$_userGecos = $tmp if (defined($tmp = $Options{'c'}));
$_skeletonDir = $tmp if (defined($tmp = $Options{'k'}));
-$userCN = ($Options{'c'} || $userName);
-$userCN = $tmp if (defined($tmp = $Options{'N'}));
-$userSN = $userName;
-$userSN = $tmp if (defined($tmp = $Options{'S'}));
-
########################
-my $ldap_master=connect_ldap_master();
-
# MACHINE ACCOUNT
if (defined($tmp = $Options{'w'})) {
- # add a trailing dollar if missing
- if ($userName =~ /[^\$]$/s) {
+ # add a trailing dollar if missing
+ if ($userName =~ /[^\$]$/s) {
$userName .= "\$";
- }
+ }
- #print "About to create machine $userName:\n";
+ #print "About to create machine $userName:\n";
- if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) {
+ if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) {
die "$0: error while adding posix account\n";
- }
-
- if (!$with_smbpasswd) {
- # (jtournier)
- # Objectclass sambaSamAccount is now added directly by samba when joigning the domain (for samba3)
- #if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) {
- # die "$0: error while adding samba account\n";
- #}
- } else {
+ }
+
+ if (!$with_smbpasswd) {
+ if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) {
+ die "$0: error while adding samba account\n";
+ }
+ } else {
if (!add_samba_machine($userName)) {
- die "$0: error while adding samba account\n";
+ die "$0: error while adding samba account\n";
}
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- replace => [sambaAcctFlags => '[W ]']
- ]
- );
- $modify->code && warn "failed to modify entry: ", $modify->error ;
- }
-
- exit 0;
+
+ my $tmpldif =
+"dn: uid=$userName,$computersdn
+changetype: modify
+acctFlags: [W ]
+
+";
+ die "$0: error while modifying accountflags of $userName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+ }
+
+ exit 0;
}
+#######################
+
# USER ACCOUNT
+
# add posix account first
-my $add = $ldap_master->add ("uid=$userName,$usersdn",
- attr => [
- 'objectclass' => ['top','inetOrgPerson', 'posixAccount'],
- 'cn' => "$userCN",
- 'sn' => "$userSN",
- 'uid' => "$userName",
- 'uidNumber' => "$userUidNumber",
- 'gidNumber' => "$userGidNumber",
- 'homeDirectory' => "$userHomeDirectory",
- 'loginShell' => "$_userLoginShell",
- 'gecos' => "$_userGecos",
- 'description' => "$_userGecos",
- 'userPassword' => "{crypt}x"
- ]
- );
-
-$add->code && warn "failed to add entry: ", $add->error ;
+my $tmpldif =
+"dn: uid=$userName,$usersdn
+objectclass: top
+objectclass: account
+objectclass: posixAccount
+cn: $userName
+uid: $userName
+uidNumber: $userUidNumber
+gidNumber: $userGidNumber
+homeDirectory: $userHomeDirectory
+loginShell: $_userLoginShell
+gecos: $_userGecos
+description: $_userGecos
+userPassword: {crypt}x
+
+";
+die "$0: error while adding posix user $userName\n"
+ unless (do_ldapadd($tmpldif) == 0);
+
+undef $tmpldif;
#if ($createGroup) {
# group_add($userName, $userGidNumber);
@@ -258,76 +223,73 @@ group_add_user($userGidNumber, $userName);
my $grouplist;
# adds to supplementary groups
if (defined($grouplist = $Options{'G'})) {
- add_grouplist_user($grouplist, $userName);
+ add_grouplist_user($grouplist, $userName);
}
# If user was created successfully then we should create his/her home dir
if (defined($tmp = $Options{'m'})) {
- unless ( $userName =~ /\$$/ ) {
if ( !(-e $userHomeDirectory) ) {
- system "mkdir $userHomeDirectory 2>/dev/null";
- system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null";
- system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null";
- system "chmod 700 $userHomeDirectory 2>/dev/null";
+ system "mkdir $userHomeDirectory 2>/dev/null";
+ system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null";
+ system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null";
+ system "chmod 700 $userHomeDirectory 2>/dev/null";
}
- }
}
# Add Samba user infos
if (defined($Options{'a'})) {
- if (!$with_smbpasswd) {
+ if (!$with_smbpasswd) {
my $winmagic = 2147483647;
my $valpwdcanchange = 0;
my $valpwdmustchange = $winmagic;
- my $valpwdlastset = 0;
my $valacctflags = "[UX]";
if (defined($tmp = $Options{'A'})) {
- if ($tmp != 0) {
+ if ($tmp != 0) {
$valpwdcanchange = "0";
- } else {
+ } else {
$valpwdcanchange = "$winmagic";
- }
+ }
}
if (defined($tmp = $Options{'B'})) {
- if ($tmp != 0) {
+ if ($tmp != 0) {
$valpwdmustchange = "0";
- # To force a user to change his password:
- # . the attribut sambaPwdLastSet must be != 0
- # . the attribut sambaAcctFlags must not match the 'X' flag
- $valpwdlastset=$winmagic;
- $valacctflags = "[U]";
- } else {
+ } else {
$valpwdmustchange = "$winmagic";
- }
+ }
}
if (defined($tmp = $Options{'H'})) {
- $valacctflags = "$tmp";
+ $valacctflags = "$tmp";
}
-
- my $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
- changes => [
- add => [objectClass => 'sambaSamAccount'],
- add => [sambaPwdLastSet => "$valpwdlastset"],
- add => [sambaLogonTime => '0'],
- add => [sambaLogoffTime => '2147483647'],
- add => [sambaKickoffTime => '2147483647'],
- add => [sambaPwdCanChange => "$valpwdcanchange"],
- add => [sambaPwdMustChange => "$valpwdmustchange"],
- add => [displayName => "$_userGecos"],
- add => [sambaAcctFlags => "$valacctflags"],
- add => [sambaSID => "$SID-$userRid"]
- ]
- );
+ my $tmpldif =
+"dn: uid=$userName,$usersdn
+changetype: modify
+objectclass: top
+objectclass: account
+objectclass: posixAccount
+objectClass: sambaAccount
+pwdLastSet: 0
+logonTime: 0
+logoffTime: 2147483647
+kickoffTime: 2147483647
+pwdCanChange: $valpwdcanchange
+pwdMustChange: $valpwdmustchange
+displayName: $_userGecos
+acctFlags: $valacctflags
+rid: $userRid
+
+";
- $modify->code && die "failed to add entry: ", $modify->error ;
+ die "$0: error while adding samba account to posix user $userName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
- } else {
+ undef $tmpldif;
+ } else {
my $FILE="|smbpasswd -s -a $userName >/dev/null" ;
open (FILE, $FILE) || die "$!\n";
print FILE <<EOF;
@@ -337,73 +299,54 @@ EOF
;
close FILE;
if ($?) {
- print "$0: error adding samba account\n";
- exit (10);
+ print "$0: error adding samba account\n";
+ exit (10);
}
- } # with_smbpasswd
-
- my @mods;
- my $valscriptpath;
- if (defined $_userScript) {
- $valscriptpath="$_userScript";
- } else {
- $valscriptpath = "$userName.cmd";
- }
- if (defined($tmp = $Options{'E'})) {
- $valscriptpath = "$tmp";
- }
+ } # with_smbpasswd
+
+ my $valscriptpath = "$userName.cmd";
+ my $valprofilepath = "$_userProfile$userName";
+ my $valsmbhome = "$_userSmbHome";
+ my $valhomedrive = "$_userHomeDrive";
- my $valsmbhome;
- if (defined $_userSmbHome) {
- $valsmbhome = "$_userSmbHome";
- }
- if (defined($tmp = $Options{'C'})) {
+if (defined($tmp = $Options{'C'})) {
$valsmbhome = "$tmp";
- }
- if (defined $valsmbhome) {
- push(@mods, 'sambaHomePath', $valsmbhome);
- }
+}
- my $valhomedrive = "$_userHomeDrive";
- if (defined($tmp = $Options{'D'})) {
+if (defined($tmp = $Options{'D'})) {
$tmp = $tmp.":" unless ($tmp =~ /:/);
$valhomedrive = "$tmp";
- }
+}
- my $valprofilepath;
- if (defined $_userProfile) {
- $valprofilepath = "$_userProfile$userName";
- }
+if (defined($tmp = $Options{'E'})) {
+ $valscriptpath = "$tmp";
+}
- if (defined($tmp = $Options{'F'})) {
+if (defined($tmp = $Options{'F'})) {
$valprofilepath = "$tmp";
- }
- if (defined $valprofilepath) {
- push(@mods, 'sambaProfilePath', $valprofilepath);
- }
-
- my $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
- changes => [
- add => [sambaPrimaryGroupSID => "$userGroupSID"],
- add => [sambaHomeDrive => "$valhomedrive"],
- add => [sambaLogonScript => "$valscriptpath"],
- add => [sambaLMPassword => 'XXX'],
- add => [sambaNTPassword => 'XXX']
- ]
- );
- $modify = $ldap_master->modify ( "uid=$userName,$usersdn",
- 'replace' => { @mods }
- );
-
-
- $modify->code && die "failed to add entry: ", $modify->error ;
-
}
-$ldap_master->unbind; # take down session
+ my $tmpldif =
+"dn: uid=$userName,$usersdn
+changetype: modify
+rid: $userRid
+primaryGroupID: $userGroupRid
+homeDrive: $valhomedrive
+smbHome: $valsmbhome
+profilePath: $valprofilepath
+scriptPath: $valscriptpath
+lmPassword: XXX
+ntPassword: XXX
+
+";
+
+ die "$0: error while modifying samba account of user $userName\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+}
if (defined($Options{'P'})) {
- exec "/usr/local/sbin/smbldap-passwd.pl $userName"
+ exec "/usr/local/sbin/smbldap-passwd.pl $userName"
}
exit 0;
@@ -412,57 +355,57 @@ exit 0;
=head1 NAME
-smbldap-useradd.pl - Create a new user or update default new
- user information
+ smbldap-useradd.pl - Create a new user or update default new
+ user information
=head1 SYNOPSIS
-smbldap-useradd.pl [-c comment] [-d home_dir]
- [-g initial_group] [-G group[,...]]
- [-m [-k skeleton_dir]]
- [-s shell] [-u uid [ -o]] [-P]
- [-A canchange] [-B mustchange] [-C smbhome]
- [-D homedrive] [-E scriptpath] [-F profilepath]
- [-H acctflags] login
+ smbldap-useradd.pl [-c comment] [-d home_dir]
+ [-g initial_group] [-G group[,...]]
+ [-m [-k skeleton_dir]]
+ [-s shell] [-u uid [ -o]] [-P]
+ [-A canchange] [-B mustchange] [-C smbhome]
+ [-D homedrive] [-E scriptpath] [-F profilepath]
+ [-H acctflags] login
=head1 DESCRIPTION
-Creating New Users
- The smbldap-useradd.pl command creates a new user account using
- the values specified on the command line and the default
- values from the system.
- The new user account will be entered into the system
- files as needed, the home directory will be created, and
- initial files copied, depending on the command line options.
+ Creating New Users
+ The smbldap-useradd.pl command creates a new user account using
+ the values specified on the command line and the default
+ values from the system.
+ The new user account will be entered into the system
+ files as needed, the home directory will be created, and
+ initial files copied, depending on the command line options.
- You have to use smbldap-passwd to set the user password.
- For Samba users, rid is 2*uidNumber+1000, and primaryGroupID
- is 2*gidNumber+1001. Thus you may want to use
- smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator
- to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and
- grouprid is 0x200 = 512)
+ You have to use smbldap-passwd to set the user password.
+ For Samba users, rid is 2*uidNumber+1000, and primaryGroupID
+ is 2*gidNumber+1001. Thus you may want to use
+ smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator
+ to create a domain administrator (admin rid is 0x1F4 = 500 and
+ grouprid is 0x200 = 512)
- Without any option, the account created will be an Unix (Posix)
- account. The following options may be used to add information:
+ Without any option, the account created will be an Unix (Posix)
+ account. The following options may be used to add information:
--a The user will have a Samba account (and Unix).
+ -a The user will have a Samba account (and Unix).
- -w Creates an account for a Samba machine (Workstation), so that
- it can join a sambaDomainName.
+ -w Creates an account for a Samba machine (Workstation), so that
+ it can join a domain.
- -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else
- decimal (2.2.2 patched from cvs or 2.2.x, x > 2)
+ -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else
+ decimal (2.2.2 patched from cvs or 2.2.x, x > 2)
- -c comment
- The new user's comment field (gecos).
+ -c comment
+ The new user's comment field (gecos).
-d home_dir
The new user will be created using home_dir as the value for the
user's login directory. The default is to append the login name
- to default_home and use that as the login directory name.
+ to default_home and use that as the login directory name.
- -g initial_group
- The group name or number of the user's initial login group. The
+ -g initial_group
+ The group name or number of the user's initial login group. The
group name must exist. A group number must refer to an already
existing group. The default group number is 1.
@@ -474,20 +417,20 @@ Creating New Users
is for the user to belong only to the initial group.
-m The user's home directory will be created if it does not exist.
- The files contained in skeleton_dir will be copied to the home
- directory if the -k option is used, otherwise the files con­
- tained in /etc/skel will be used instead. Any directories con­
- tained in skeleton_dir or /etc/skel will be created in the
- user's home directory as well. The -k option is only valid in
+ The files contained in skeleton_dir will be copied to the home
+ directory if the -k option is used, otherwise the files con­
+ tained in /etc/skel will be used instead. Any directories con­
+ tained in skeleton_dir or /etc/skel will be created in the
+ user's home directory as well. The -k option is only valid in
conjunction with the -m option. The default is to not create
the directory and to not copy any files.
-s shell
The name of the user's login shell. The default is to leave
- this field blank, which causes the system to select the default
- login shell.
+ this field blank, which causes the system to select the default
+ login shell.
- -u uid The numerical value of the user's ID. This value must be
+ -u uid The numerical value of the user's ID. This value must be
unique, unless the -o option is used. The value must be non-
negative. The default is to use the smallest ID value greater
than 1000 and greater than every other user.
@@ -498,20 +441,15 @@ Creating New Users
-B must change password ? 0 if no, 1 if yes
- -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')
-
- -D sambaHomeDrive (letter associated with home share, like 'H:')
-
- -E sambaLogonScript, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat')
-
- -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')
+ -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')
- -H sambaAcctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]')
+ -D homeDrive (letter associated with home share, like 'H:')
- -N canonical name (defaults to gecos or username, if gecos not set)
+ -E scriptPath, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat')
- -S surname (defaults to username)
+ -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')
+ -H acctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]')
=head1 SEE ALSO
diff --git a/examples/LDAP/smbldap-tools/smbldap-userdel.pl b/examples/LDAP/smbldap-tools/smbldap-userdel.pl
index f1e69e209c5..54309fa5dbf 100755
--- a/examples/LDAP/smbldap-tools/smbldap-userdel.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,9 +23,6 @@
# Purpose of smbldap-userdel : user (posix,shadow,samba) deletion
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
@@ -37,9 +34,9 @@ my %Options;
my $ok = getopts('r?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-r?] username\n";
- print " -r remove home directory\n";
- exit (1);
+ print "Usage: $0 [-r?] username\n";
+ print " -r remove home directory\n";
+ exit (1);
}
# Read only first @ARGV
@@ -48,34 +45,34 @@ my $user = $ARGV[0];
my $dn;
# user must not exist in LDAP
if (!defined($dn=get_user_dn($user))) {
- print "$0: user $user does not exist\n";
- exit (6);
+ print "$0: user $user does not exist\n";
+ exit (6);
}
if ($< != 0) {
- print "You must be root to delete an user\n";
- exit (1);
+ print "You must be root to delete an user\n";
+ exit (1);
}
my $homedir;
if (defined($Options{'r'})) {
- $homedir=get_homedir($user);
+ $homedir=get_homedir($user);
}
# remove user from groups
my $groups = find_groups_of $user;
-my @grplines = split(/\n/,$groups);
+my @grplines = split(/\n/, $groups);
my $grp;
foreach $grp (@grplines) {
- my $gname = "";
- if ( $grp =~ /dn: cn=([^,]+),/) {
+ my $gname = "";
+ if ( $grp =~ /dn: cn=([^,]+),/) {
$gname = $1;
#print "xx $gname\n";
- }
- if ($gname ne "") {
+ }
+ if ($gname ne "") {
group_remove_member($gname, $user);
- }
+ }
}
# XXX
@@ -83,9 +80,9 @@ delete_user($user);
# delete dir -- be sure that homeDir is not a strange value
if (defined($Options{'r'})) {
- if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) {
+ if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) {
system "rm -rf $homedir";
- }
+ }
}
my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
diff --git a/examples/LDAP/smbldap-tools/smbldap-usermod.pl b/examples/LDAP/smbldap-tools/smbldap-usermod.pl
index 70151b74122..016d7b54228 100755
--- a/examples/LDAP/smbldap-tools/smbldap-usermod.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,380 +23,295 @@
# Purpose of smbldap-usermod : user (posix,shadow,samba) modification
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use smbldap_conf;
+
#####################
use Getopt::Std;
my %Options;
my $nscd_status;
-my $ok = getopts('A:B:C:D:E:F:H:IJN:S:Pame:f:u:g:G:d:l:s:c:ok:?h', \%Options);
-if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) {
- print "Usage: $0 [-awmugdsckxABCDEFGHI?h] username\n";
- print "Available options are:\n";
- print " -c gecos\n";
- print " -d home directory\n";
- #print " -m move home directory\n";
- #print " -f inactive days\n";
- print " -u uid\n";
- print " -o uid can be non unique\n";
- print " -g gid\n";
- print " -G supplementary groups (comma separated)\n";
- print " -l login name\n";
- print " -s shell\n";
- print " -N canonical name\n";
- print " -S surname\n";
- print " -P ends by invoking smbldap-passwd.pl\n";
- print " For samba users:\n";
- print " -a add sambaSamAccount objectclass\n";
- print " -e expire date (\"YYYY-MM-DD HH:MM:SS\")\n";
- print " -A can change password ? 0 if no, 1 if yes\n";
- print " -B must change password ? 0 if no, 1 if yes\n";
- print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
- print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n";
- print " -E sambaLogonScript (DOS script to execute on login)\n";
- print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
- print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
- print " -I disable an user. Can't be used with -H or -J\n";
- print " -J enable an user. Can't be used with -H or -I\n";
- print " -?|-h show this help message\n";
- exit (1);
+my $ok = getopts('A:B:C:D:E:F:H:IJxme:f:u:g:G:d:l:s:c:ok:?', \%Options);
+if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
+ print "Usage: $0 [-awmugdsckxABCDEFGHI?] username\n";
+ print " -c gecos\n";
+ print " -d home directory\n";
+ #print " -m move home directory\n";
+ #print " -e expire date (YYYY-MM-DD)\n";
+ #print " -f inactive days\n";
+ print " -u uid\n";
+ print " -o uid can be non unique\n";
+ print " -g gid\n";
+ print " -G supplementary groups (comma separated)\n";
+ print " -l login name\n";
+ print " -s shell\n";
+ print " -x creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only)\n";
+ print " -A can change password ? 0 if no, 1 if yes\n";
+ print " -B must change password ? 0 if no, 1 if yes\n";
+ print " -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')\n";
+ print " -D homeDrive (letter associated with home share, like 'H:')\n";
+ print " -E scriptPath (DOS script to execute on login)\n";
+ print " -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
+ print " -H acctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
+ print " -I disable an user. Can't be used with -H or -J\n";
+ print " -J enable an user. Can't be used with -H or -I\n";
+ print " -? show this help message\n";
+ exit (1);
}
if ($< != 0) {
- print "You must be root to modify an user\n";
- exit (1);
+ print "You must be root to modify an user\n";
+ exit (1);
}
# Read only first @ARGV
my $user = $ARGV[0];
-# Read user data
-my $user_entry = read_user_entry($user);
-if (!defined($user_entry)) {
- print "$0: user $user doesn't exist\n";
- exit (1);
+# Read user datas
+my $lines = read_user($user);
+if (!defined($lines)) {
+ print "$0: user $user doesn't exist\n";
+ exit (1);
+}
+
+#print "$lines\n";
+my $dn_line;
+if ( $lines =~ /(^dn: .*)/ ) {
+ $dn_line = $1;
}
+chomp($dn_line);
+
my $samba = 0;
-if (grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) {
- $samba = 1;
+if ($lines =~ m/objectClass: sambaAccount/) {
+ $samba = 1;
}
-# get the dn of the user
-my $dn= $user_entry->dn();
+############
my $tmp;
-my @mods;
-if (defined($tmp = $Options{'a'})) {
- # Let's connect to the directory first
- my $ldap_master=connect_ldap_master();
- my $winmagic = 2147483647;
- my $valpwdcanchange = 0;
- my $valpwdmustchange = $winmagic;
- my $valpwdlastset = 0;
- my $valacctflags = "[UX]";
- my $user_entry=read_user_entry($user);
- my $uidNumber = $user_entry->get_value('uidNumber');
- my $userRid = 2 * $uidNumber + 1000;
- # apply changes
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- add => [objectClass => 'sambaSamAccount'],
- add => [sambaPwdLastSet => "$valpwdlastset"],
- add => [sambaLogonTime => '0'],
- add => [sambaLogoffTime => '2147483647'],
- add => [sambaKickoffTime => '2147483647'],
- add => [sambaPwdCanChange => "$valpwdcanchange"],
- add => [sambaPwdMustChange => "$valpwdmustchange"],
- add => [displayName => "$_userGecos"],
- add => [sambaSID=> "$SID-$userRid"],
- add => [sambaAcctFlags => "$valacctflags"],
- ]
- );
- $modify->code && warn "failed to modify entry: ", $modify->error ;
-}
+my $mods;
# Process options
my $changed_uid;
my $_userUidNumber;
my $_userRid;
if (defined($tmp = $Options{'u'})) {
- if (defined($Options{'o'})) {
+ if (defined($Options{'o'})) {
$nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd stop > /dev/null 2>&1";
+ system "/etc/init.d/nscd stop > /dev/null 2>&1";
}
if (getpwuid($tmp)) {
- if ($nscd_status == 0) {
+ if ($nscd_status == 0) {
system "/etc/init.d/nscd start > /dev/null 2>&1";
- }
+ }
- print "$0: uid number $tmp exists\n";
- exit (6);
+ print "$0: uid number $tmp exists\n";
+ exit (6);
}
if ($nscd_status == 0) {
- system "/etc/init.d/nscd start > /dev/null 2>&1";
+ system "/etc/init.d/nscd start > /dev/null 2>&1";
}
- }
- push(@mods, 'uidNumber', $tmp);
- $_userUidNumber = $tmp;
- if ($samba) {
+ }
+ $_userUidNumber = $tmp;
# as rid we use 2 * uid + 1000
my $_userRid = 2 * $_userUidNumber + 1000;
if (defined($Options{'x'})) {
- $_userRid= sprint("%x", $_userRid);
+ $_userRid= sprint("%x", $_userRid);
}
- push(@mods, 'sambaSID', $SID.'-'.$_userRid);
- }
- $changed_uid = 1;
+ $mods .= "uidNumber: $_userUidNumber\n";
+ if ($samba) {
+ $mods .= "rid: $_userRid\n";
+ }
+ $changed_uid = 1;
}
my $changed_gid;
my $_userGidNumber;
-my $_userGroupSID;
+my $_userGroupRid;
if (defined($tmp = $Options{'g'})) {
- $_userGidNumber = parse_group($tmp);
- if ($_userGidNumber < 0) {
+ $_userGidNumber = parse_group($tmp);
+ if ($_userGidNumber < 0) {
print "$0: group $tmp doesn't exist\n";
exit (6);
- }
- push(@mods, 'gidNumber', $_userGidNumber);
- if ($samba) {
- # as grouprid we use the sambaSID attribute's value of the group
- my $group_entry = read_group_entry_gid($_userGidNumber);
- my $_userGroupSID = $group_entry->get_value('sambaSID');
- unless ($_userGroupSID) {
- print "$0: unknown group SID not set for unix group $_userGidNumber\n";
- exit (7);
}
- push(@mods, 'sambaPrimaryGroupSid', $_userGroupSID);
- }
- $changed_gid = 1;
+# as grouprid we use 2 * gid + 1001
+ my $_userGroupRid = 2 * $_userGidNumber + 1001;
+ if (defined($Options{'x'})) {
+ $_userGroupRid = sprint("%x", $_userGroupRid);
+ }
+ $mods .= "gidNumber: $_userGidNumber\n";
+ if ($samba) {
+ $mods .= "primaryGroupID: $_userGroupRid\n";
+ }
+ $changed_gid = 1;
}
+my $changed_shell;
+my $_userLoginShell;
if (defined($tmp = $Options{'s'})) {
- push(@mods, 'loginShell' => $tmp);
+ $_userLoginShell = $tmp;
+ $mods .= "loginShell: $_userLoginShell\n";
+ $changed_shell = 1;
}
-
-if (defined($tmp = $Options{'c'})) {
- push(@mods, 'gecos' => $tmp,
- 'description' => $tmp);
- if ($samba == 1) {
- push(@mods, 'displayName' => $tmp);
- }
+my $changed_gecos;
+my $_userGecos;
+if (defined($tmp = $Options{'c'})) {
+ $_userGecos = $tmp;
+ $mods .= "gecos: $_userGecos\n";
+ $changed_gecos = 1;
}
+my $changed_homedir;
+my $newhomedir;
if (defined($tmp = $Options{'d'})) {
- push(@mods, 'homeDirectory' => $tmp);
-}
-
-if (defined($tmp = $Options{'N'})) {
- push(@mods, 'cn' => $tmp);
+ $newhomedir = $tmp;
+ $mods .= "homeDirectory: $newhomedir\n";
+ $changed_homedir = 1;
}
-if (defined($tmp = $Options{'S'})) {
- push(@mods, 'sn' => $tmp);
-}
if (defined($tmp = $Options{'G'})) {
- # remove user from old groups
- my $groups = find_groups_of $user;
- my @grplines = split(/\n/,$groups);
+ # remove user from old groups
+ my $groups = find_groups_of $user;
+ my @grplines = split(/\n/, $groups);
- my $grp;
- foreach $grp (@grplines) {
+ my $grp;
+ foreach $grp (@grplines) {
my $gname = "";
if ( $grp =~ /dn: cn=([^,]+),/) {
- $gname = $1;
- #print "xx $gname\n";
+ $gname = $1;
+ #print "xx $gname\n";
}
if ($gname ne "") {
- group_remove_member($gname, $user);
+ group_remove_member($gname, $user);
}
- }
+ }
- # add user to new groups
- add_grouplist_user($tmp, $user);
+ # add user to new groups
+ add_grouplist_user($tmp, $user);
}
#
-# A : sambaPwdCanChange
-# B : sambaPwdMustChange
-# C : sambaHomePath
-# D : sambaHomeDrive
-# E : sambaLogonScript
-# F : sambaProfilePath
-# H : sambaAcctFlags
+# A : pwdCanChange
+# B : pwdMustChange
+# C : smbHome
+# D : homeDrive
+# E : scriptPath
+# F : profilePath
+# H : acctFlags
my $attr;
my $winmagic = 2147483647;
-$samba = is_samba_user($user);
-
-if (defined($tmp = $Options{'e'})) {
- if ($samba == 1) {
- my $kickoffTime=`date --date='$tmp' +%s`;
- chomp($kickoffTime);
- push(@mods, 'sambakickoffTime' => $kickoffTime);
- } else {
- print "User $user is not a samba user\n";
- }
-}
-
-my $_sambaPwdCanChange;
if (defined($tmp = $Options{'A'})) {
- if ($samba == 1) {
- $attr = "sambaPwdCanChange";
+ $attr = "pwdCanChange";
if ($tmp != 0) {
- $_sambaPwdCanChange=0;
+ $mods .= "$attr: 0\n";
} else {
- $_sambaPwdCanChange=$winmagic;
+ $mods .= "$attr: $winmagic\n";
}
- push(@mods, 'sambaPwdCanChange' => $_sambaPwdCanChange);
- } else {
- print "User $user is not a samba user\n";
- }
}
-my $_sambaPwdMustChange;
if (defined($tmp = $Options{'B'})) {
- if ($samba == 1) {
+ $attr = "pwdMustChange";
if ($tmp != 0) {
- $_sambaPwdMustChange=0;
- # To force a user to change his password:
- # . the attribut sambaPwdLastSet must be != 0
- # . the attribut sambaAcctFlags must not match the 'X' flag
- my $_sambaAcctFlags;
- my $flags = $user_entry->get_value('sambaAcctFlags');
- if ( $flags =~ /X/ ) {
- my $letters;
- if ($flags =~ /(\w+)/) {
- $letters = $1;
- }
- $letters =~ s/X//;
- $_sambaAcctFlags="\[$letters\]";
- push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags);
- }
- my $_sambaPwdLastSet = $user_entry->get_value('sambaPwdLastSet');
- if ($_sambaPwdLastSet == 0) {
- push(@mods, 'sambaPwdLastSet' => $winmagic);
- }
+ $mods .= "$attr: 0\n";
} else {
- $_sambaPwdMustChange=$winmagic;
+ $mods .= "$attr: $winmagic\n";
}
- push(@mods, 'sambaPwdMustChange' => $_sambaPwdMustChange);
- } else {
- print "User $user is not a samba user\n";
- }
}
if (defined($tmp = $Options{'C'})) {
- if ($samba == 1) {
+ $attr = "smbHome";
#$tmp =~ s/\\/\\\\/g;
- push(@mods, 'sambaHomePath' => $tmp);
- } else {
- print "User $user is not a samba user\n";
- }
+ $mods .= "$attr: $tmp\n";
}
-my $_sambaHomeDrive;
if (defined($tmp = $Options{'D'})) {
- if ($samba == 1) {
+ $attr = "homeDrive";
$tmp = $tmp.":" unless ($tmp =~ /:/);
- push(@mods, 'sambaHomeDrive' => $tmp);
- } else {
- print "User $user is not a samba user\n";
- }
+ $mods .= "$attr: $tmp\n";
}
if (defined($tmp = $Options{'E'})) {
- if ($samba == 1) {
+ $attr = "scriptPath";
#$tmp =~ s/\\/\\\\/g;
- push(@mods, 'sambaLogonScript' => $tmp);
- } else {
- print "User $user is not a samba user\n";
- }
+ $mods .= "$attr: $tmp\n";
}
if (defined($tmp = $Options{'F'})) {
- if ($samba == 1) {
+ $attr = "profilePath";
#$tmp =~ s/\\/\\\\/g;
- push(@mods, 'sambaProfilePath' => $tmp);
- } else {
- print "User $user is not a samba user\n";
- }
+ $mods .= "$attr: $tmp\n";
}
-if ($samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) {
- my $_sambaAcctFlags;
- if (defined($tmp = $Options{'H'})) {
+if (defined($tmp = $Options{'H'})) {
+ $attr = "acctFlags";
#$tmp =~ s/\\/\\\\/g;
- $_sambaAcctFlags=$tmp;
- } else {
- # I or J
+ $mods .= "$attr: $tmp\n";
+} elsif (defined($tmp = $Options{'I'})) {
my $flags;
- $flags = $user_entry->get_value('sambaAcctFlags');
-
- if (defined($tmp = $Options{'I'})) {
- if ( !($flags =~ /D/) ) {
- my $letters;
- if ($flags =~ /(\w+)/) {
- $letters = $1;
- }
- $_sambaAcctFlags="\[D$letters\]";
- }
- } elsif (defined($tmp = $Options{'J'})) {
- if ( $flags =~ /D/ ) {
- my $letters;
- if ($flags =~ /(\w+)/) {
- $letters = $1;
- }
- $letters =~ s/D//;
- $_sambaAcctFlags="\[$letters\]";
- }
+
+ if ( $lines =~ /^acctFlags: (.*)/m ) {
+ $flags = $1;
+ }
+
+ chomp($flags);
+
+ if ( !($flags =~ /D/) ) {
+ my $letters;
+ if ($flags =~ /(\w+)/) {
+ $letters = $1;
}
- }
+ $mods .= "acctFlags: \[D$letters\]\n";
+ }
+} elsif (defined($tmp = $Options{'J'})) {
+ my $flags;
+ if ( $lines =~ /^acctFlags: (.*)/m ) {
+ $flags = $1;
+ }
- if ("$_sambaAcctFlags" ne '') {
- push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags);
- }
+ chomp($flags);
-} elsif (!$samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) {
- print "User $user is not a samba user\n";
+ if ( $flags =~ /D/ ) {
+ my $letters;
+ if ($flags =~ /(\w+)/) {
+ $letters = $1;
+ }
+ $letters =~ s/D//;
+ $mods .= "acctFlags: \[$letters\]\n";
+ }
}
-# Let's connect to the directory first
-my $ldap_master=connect_ldap_master();
+if ($mods ne '') {
+ #print "----\n$dn_line\n$mods\n----\n";
-# apply changes
-my $modify = $ldap_master->modify ( "$dn",
- 'replace' => { @mods }
- );
-$modify->code && warn "failed to modify entry: ", $modify->error ;
+ my $tmpldif =
+"$dn_line
+changetype: modify
+$mods
+";
-# take down session
-$ldap_master->unbind;
+ die "$0: error while modifying user $user\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+
+ undef $tmpldif;
+}
$nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
- system "/etc/init.d/nscd restart > /dev/null 2>&1";
-}
-
-if (defined($Options{'P'})) {
- exec "/usr/local/sbin/smbldap-passwd.pl $user"
+ system "/etc/init.d/nscd restart > /dev/null 2>&1";
}
@@ -404,32 +319,32 @@ if (defined($Options{'P'})) {
=head1 NAME
-smbldap-usermod.pl - Modify a user account
+ smbldap-usermod.pl - Modify a user account
=head1 SYNOPSIS
-smbldap-usermod.pl [-c comment] [-d home_dir]
- [-g initial_group] [-G group[,...]]
- [-l login_name] [-p passwd]
- [-s shell] [-u uid [ -o]] [-x]
- [-A canchange] [-B mustchange] [-C smbhome]
- [-D homedrive] [-E scriptpath] [-F profilepath]
- [-H acctflags] login
+ smbldap-usermod.pl [-c comment] [-d home_dir]
+ [-g initial_group] [-G group[,...]]
+ [-l login_name] [-p passwd]
+ [-s shell] [-u uid [ -o]] [-x]
+ [-A canchange] [-B mustchange] [-C smbhome]
+ [-D homedrive] [-E scriptpath] [-F profilepath]
+ [-H acctflags] login
=head1 DESCRIPTION
-The smbldap-usermod.pl command modifies the system account files
- to reflect the changes that are specified on the command line.
- The options which apply to the usermod command are
+ The smbldap-usermod.pl command modifies the system account files
+ to reflect the changes that are specified on the command line.
+ The options which apply to the usermod command are
- -c comment
- The new value of the user's comment field (gecos).
+ -c comment
+ The new value of the user's comment field (gecos).
-d home_dir
The user's new login directory.
- -g initial_group
- The group name or number of the user's new initial login group.
+ -g initial_group
+ The group name or number of the user's new initial login group.
The group name must exist. A group number must refer to an
already existing group. The default group number is 1.
@@ -444,17 +359,17 @@ The smbldap-usermod.pl command modifies the system account files
-l login_name
The name of the user will be changed from login to login_name.
Nothing else is changed. In particular, the user's home direc­
- tory name should probably be changed to reflect the new login
- name.
+ tory name should probably be changed to reflect the new login
+ name.
- -s shell
- The name of the user's new login shell. Setting this field to
+ -s shell
+ The name of the user's new login shell. Setting this field to
blank causes the system to select the default login shell.
-u uid The numerical value of the user's ID. This value must be
- unique, unless the -o option is used. The value must be non-
- negative. Any files which the user owns and which are
- located in the directory tree rooted at the user's home direc­
+ unique, unless the -o option is used. The value must be non-
+ negative. Any files which the user owns and which are
+ located in the directory tree rooted at the user's home direc­
tory will have the file user ID changed automatically. Files
outside of the user's home directory must be altered manually.
@@ -465,15 +380,15 @@ The smbldap-usermod.pl command modifies the system account files
-B must change password ? 0 if no, 1 if yes
- -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')
+ -C smbHome (SMB home share, like '\\\\PDC-SRV\\homes')
- -D sambaHomeDrive (letter associated with home share, like 'H:')
+ -D homeDrive (letter associated with home share, like 'H:')
- -E sambaLogonScript, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat')
+ -E scriptPath, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat')
- -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')
+ -F profilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')
- -H sambaAcctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]')
+ -H acctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]')
-I disable user. Can't be used with -H or -J
diff --git a/examples/LDAP/smbldap-tools/smbldap-usershow.pl b/examples/LDAP/smbldap-tools/smbldap-usershow.pl
index 173480d76c2..b05f0876203 100755
--- a/examples/LDAP/smbldap-tools/smbldap-usershow.pl
+++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -23,9 +23,6 @@
# Purpose of smbldap-userdisplay : user (posix,shadow,samba) display
use strict;
-use FindBin;
-use FindBin qw($RealBin);
-use lib "$RealBin/";
use smbldap_tools;
use Getopt::Std;
@@ -34,8 +31,8 @@ my %Options;
my $ok = getopts('?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
- print "Usage: $0 [-?] username\n";
- print " -? show this help message\n";
+ print "Usage: $0 [-?] username\n";
+ print " -? show this help message\n";
exit (1);
}
diff --git a/examples/LDAP/smbldap-tools/smbldap_conf.pm b/examples/LDAP/smbldap-tools/smbldap_conf.pm
index 257c205a2cd..9a5a116b98c 100644
--- a/examples/LDAP/smbldap-tools/smbldap_conf.pm
+++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm
@@ -28,33 +28,36 @@ package smbldap_conf;
# . be the configuration file for all smbldap-tools scripts
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS
- $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
- $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
- $ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn
- $groupsdn $scope $binddn $bindpasswd
- $slaveDN $slavePw $masterDN $masterPw
- $_userLoginShell $_userHomePrefix $_userGecos
- $_defaultUserGid $_defaultComputerGid
- $_skeletonDir $_userSmbHome
- $_userProfile $_userHomeDrive
- $_userScript $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge
- );
+$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
+$with_smbpasswd $mk_ntpasswd
+$ldap_path $ldap_opts $ldapsearch $ldapsearchnobind
+$ldapmodify $ldappasswd $ldapadd $ldapdelete $ldapmodrdn
+$suffix $usersdn $computersdn
+$groupsdn $scope $binddn $bindpasswd
+$slaveDN $slavePw $masterDN $masterPw
+$_userLoginShell $_userHomePrefix $_userGecos
+$_defaultUserGid $_defaultComputerGid
+$_skeletonDir $_userSmbHome
+$_userProfile $_userHomeDrive
+$_userScript $usersou $computersou $groupsou
+);
use Exporter;
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(
- $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
- $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd
- $ldap_path $ldap_opts $ldapmodify $suffix $usersdn
- $computersdn $groupsdn $scope $binddn $bindpasswd
- $slaveDN $slavePw $masterDN $masterPw
- $_userLoginShell $_userHomePrefix $_userGecos
- $_defaultUserGid $_defaultComputerGid $_skeletonDir
- $_userSmbHome $_userProfile $_userHomeDrive $_userScript
- $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge
- );
+$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP
+$with_smbpasswd $mk_ntpasswd
+$ldap_path $ldap_opts $ldapsearch $ldapsearchnobind $ldapmodify $ldappasswd
+$ldapadd $ldapdelete $ldapmodrdn $suffix $usersdn
+$computersdn $groupsdn $scope $binddn $bindpasswd
+$slaveDN $slavePw $masterDN $masterPw
+$_userLoginShell $_userHomePrefix $_userGecos
+$_defaultUserGid $_defaultComputerGid $_skeletonDir
+$_userSmbHome $_userProfile $_userHomeDrive $_userScript
+$usersou $computersou $groupsou
+);
##############################################################################
@@ -63,14 +66,13 @@ $VERSION = 1.00;
#
##############################################################################
+#
# UID and GID starting at...
+#
+
$UID_START = 1000;
$GID_START = 1000;
-# Put your own SID
-# to obtain this number do: "net getlocalsid"
-$SID='S-1-5-21-3516781642-1962875130-3438800523';
-
##############################################################################
#
# LDAP Configuration
@@ -80,65 +82,69 @@ $SID='S-1-5-21-3516781642-1962875130-3438800523';
# Notes: to use to dual ldap servers backend for Samba, you must patch
# Samba with the dual-head patch from IDEALX. If not using this patch
# just use the same server for slaveLDAP and masterLDAP.
-# Those two servers declarations can also be used when you have
-# . one master LDAP server where all writing operations must be done
-# . one slave LDAP server where all reading operations must be done
-# (typically a replication directory)
-
+#
+# Slave LDAP : needed for read operations
+#
# Ex: $slaveLDAP = "127.0.0.1";
-$slaveLDAP = "127.0.0.1";
-$slavePort = "389";
+$slaveLDAP = "_SLAVELDAP_";
+#
# Master LDAP : needed for write operations
+#
# Ex: $masterLDAP = "127.0.0.1";
-$masterLDAP = "127.0.0.1";
-$masterPort = "389";
-
-# Use SSL for LDAP
-# If set to "1", this option will use start_tls for connection
-# (you should also used the port 389)
-$ldapSSL = "0";
+$masterLDAP = "_MASTERLDAP_";
+#
# LDAP Suffix
+#
# Ex: $suffix = "dc=IDEALX,dc=ORG";
-$suffix = "dc=IDEALX,dc=COM";
-
+$suffix = "_SUFFIX_";
+#
# Where are stored Users
+#
# Ex: $usersdn = "ou=Users,$suffix"; for ou=Users,dc=IDEALX,dc=ORG
$usersou = q(_USERS_);
+
$usersdn = "ou=$usersou,$suffix";
+#
# Where are stored Computers
+#
# Ex: $computersdn = "ou=Computers,$suffix"; for ou=Computers,dc=IDEALX,dc=ORG
$computersou = q(_COMPUTERS_);
+
$computersdn = "ou=$computersou,$suffix";
+#
# Where are stored Groups
+#
# Ex $groupsdn = "ou=Groups,$suffix"; for ou=Groups,dc=IDEALX,dc=ORG
$groupsou = q(_GROUPS_);
+
$groupsdn = "ou=$groupsou,$suffix";
+#
# Default scope Used
+#
$scope = "sub";
-# Unix password encryption (CRYPT, MD5, SMD5, SSHA, SHA)
-$hash_encrypt="SSHA";
-
-############################
-# Credential Configuration #
-############################
+#
+# Credential Configuration
+#
# Bind DN used
# Ex: $binddn = "cn=Manager,$suffix"; for cn=Manager,dc=IDEALX,dc=org
-$binddn = "cn=Manager,$suffix";
-
+$binddn = "_BINDDN_";
+#
# Bind DN passwd used
# Ex: $bindpasswd = 'secret'; for 'secret'
-$bindpasswd = "secret";
+$bindpasswd = "_BINDPW_";
+#
# Notes: if using dual ldap patch, you can specify to different configuration
# By default, we will use the same DN (so it will work for standard Samba
# release)
+#
$slaveDN = $binddn;
$slavePw = $bindpasswd;
$masterDN = $binddn;
@@ -151,59 +157,67 @@ $masterPw = $bindpasswd;
##############################################################################
# Login defs
+#
# Default Login Shell
+#
# Ex: $_userLoginShell = q(/bin/bash);
$_userLoginShell = q(_LOGINSHELL_);
+#
# Home directory prefix (without username)
-# Ex: $_userHomePrefix = q(/home/);
-$_userHomePrefix = q(_HOMEPREFIX_);
+#
+#Ex: $_userHomePrefix = q(/home/);
+$_userHomePrefix = q(_USERHOMEPREFIX_);
+#
# Gecos
+#
$_userGecos = q(System User);
+#
# Default User (POSIX and Samba) GID
-$_defaultUserGid = 513;
+#
+$_defaultUserGid = 100;
+#
# Default Computer (Samba) GID
+#
$_defaultComputerGid = 553;
+#
# Skel dir
+#
$_skeletonDir = q(/etc/skel);
-# Default password validation time (time in days) Comment the next line if
-# you don't want password to be enable for $_defaultMaxPasswordAge days (be
-# careful to the sambaPwdMustChange attribute's value)
-$_defaultMaxPasswordAge = 45;
-
##############################################################################
#
# SAMBA Configuration
#
##############################################################################
+#
# The UNC path to home drives location without the username last extension
# (will be dynamically prepended)
# Ex: q(\\\\My-PDC-netbios-name\\homes) for \\My-PDC-netbios-name\homes
-# Just comment this if you want to use the smb.conf 'logon home' directive
-# and/or desabling roaming profiles
$_userSmbHome = q(\\\\_PDCNAME_\\homes);
+#
# The UNC path to profiles locations without the username last extension
# (will be dynamically prepended)
-# Ex: q(\\\\My-PDC-netbios-name\\profiles\\) for \\My-PDC-netbios-name\profiles
-# Just comment this if you want to use the smb.conf 'logon path' directive
-# and/or desabling roaming profiles
+# Ex: q(\\\\My-PDC-netbios-name\\profiles) for \\My-PDC-netbios-name\profiles
$_userProfile = q(\\\\_PDCNAME_\\profiles\\);
+#
# The default Home Drive Letter mapping
# (will be automatically mapped at logon time if home directory exist)
# Ex: q(U:) for U:
-$_userHomeDrive = q(_HOMEDRIVE_);
+$_userHomeDrive = q(_HOMEDRIVE_:);
+#
# The default user netlogon script name
# if not used, will be automatically username.cmd
-# $_userScript = q(startup.cmd); # make sure script file is edited under dos
+#
+#$_userScript = q(startup.cmd); # make sure script file is edited under dos
##############################################################################
@@ -218,28 +232,15 @@ $with_smbpasswd = 0;
$smbpasswd = "/usr/bin/smbpasswd";
$mk_ntpasswd = "/usr/local/sbin/mkntpwd";
-# those next externals commands are kept fot the migration scripts and
-# for the populate script: this will be updated as soon as possible
-$slaveURI = "ldap://$slaveLDAP:$slavePort";
-$masterURI = "ldap://$masterLDAP:$masterPort";
-
$ldap_path = "/usr/bin";
-
-if ( $ldapSSL eq "0" ) {
- $ldap_opts = "-x";
-} elsif ( $ldapSSL eq "1" ) {
- $ldap_opts = "-x -Z";
-} else {
- die "ldapSSL option must be either 0 or 1.\n";
-}
-
-#$ldapsearch = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI -D '$slaveDN' -w '$slavePw'";
-#$ldapsearchnobind = "$ldap_path/ldapsearch $ldap_opts -H $slaveURI";
-$ldapmodify = "$ldap_path/ldapmodify $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'";
-#$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'";
-#$ldapadd = "$ldap_path/ldapadd $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'";
-#$ldapdelete = "$ldap_path/ldapdelete $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'";
-#$ldapmodrdn = "$ldap_path/ldapmodrdn $ldap_opts -H $masterURI -D '$masterDN' -w '$masterPw'";
+$ldap_opts = "-x";
+$ldapsearch = "$ldap_path/ldapsearch $ldap_opts -h $slaveLDAP -D '$slaveDN' -w '$slavePw'";
+$ldapsearchnobind = "$ldap_path/ldapsearch $ldap_opts -h $slaveLDAP";
+$ldapmodify = "$ldap_path/ldapmodify $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
+$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
+$ldapadd = "$ldap_path/ldapadd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
+$ldapdelete = "$ldap_path/ldapdelete $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
+$ldapmodrdn = "$ldap_path/ldapmodrdn $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
diff --git a/examples/LDAP/smbldap-tools/smbldap_tools.pm b/examples/LDAP/smbldap-tools/smbldap_tools.pm
index d33a65b7d17..0a451210f31 100755
--- a/examples/LDAP/smbldap-tools/smbldap_tools.pm
+++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm
@@ -1,8 +1,7 @@
-#! /usr/bin/perl -w
+#! /usr/bin/perl
use strict;
package smbldap_tools;
use smbldap_conf;
-use Net::LDAP;
# This code was developped by IDEALX (http://IDEALX.org/) and
# contributors (their names can be found in the CONTRIBUTORS file).
@@ -30,739 +29,552 @@ use Net::LDAP;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
use Exporter;
$VERSION = 1.00;
-
@ISA = qw(Exporter);
@EXPORT = qw(
- get_user_dn
- get_group_dn
- is_group_member
- is_samba_user
- is_unix_user
- is_user_valid
- does_sid_exist
- get_dn_from_line
- add_posix_machine
- add_samba_machine
- add_samba_machine_mkntpwd
- group_add_user
- add_grouplist_user
- disable_user
- delete_user
- group_add
- group_del
- get_homedir
- read_user
- read_user_entry
- read_group
- read_group_entry
- read_group_entry_gid
- find_groups_of
- parse_group
- group_remove_member
- group_get_members
- do_ldapadd
- do_ldapmodify
- get_user_dn2
- connect_ldap_master
- connect_ldap_slave
- group_type_by_name
- );
-
-sub connect_ldap_master
- {
- # bind to a directory with dn and password
- my $ldap_master = Net::LDAP->new(
- "$masterLDAP",
- port => "$masterPort",
- version => 3,
- # debug => 0xffff,
- )
- or die "erreur LDAP: Can't contact master ldap server ($@)";
- if ($ldapSSL == 1) {
- $ldap_master->start_tls(
- # verify => 'require',
- # clientcert => 'mycert.pem',
- # clientkey => 'mykey.pem',
- # decryptkey => sub { 'secret'; },
- # capath => '/usr/local/cacerts/'
- );
- }
- $ldap_master->bind ( "$binddn",
- password => "$masterPw"
- );
- return($ldap_master);
- }
-
-sub connect_ldap_slave
- {
- # bind to a directory with dn and password
- my $ldap_slave = Net::LDAP->new(
- "$slaveLDAP",
- port => "$slavePort",
- version => 3,
- # debug => 0xffff,
- )
- or die "erreur LDAP: Can't contact slave ldap server ($@)";
- if ($ldapSSL == 1) {
- $ldap_slave->start_tls(
- # verify => 'require',
- # clientcert => 'mycert.pem',
- # clientkey => 'mykey.pem',
- # decryptkey => sub { 'secret'; },
- # capath => '/usr/local/cacerts/'
- );
- }
- $ldap_slave->bind ( "$binddn",
- password => "$slavePw"
- );
- return($ldap_slave);
- }
-
+get_user_dn
+get_group_dn
+is_samba_user
+is_user_valid
+get_dn_from_line
+add_posix_machine
+add_samba_machine
+add_samba_machine_mkntpwd
+group_add_user
+add_grouplist_user
+disable_user
+delete_user
+group_add
+get_homedir
+read_user
+read_group
+find_groups_of
+parse_group
+group_remove_member
+group_get_members
+do_ldapadd
+do_ldapmodify
+get_user_dn2
+);
+
+# dn_line = get_user_dn($username)
+# where dn_line is like "dn: a=b,c=d"
sub get_user_dn
- {
+{
my $user = shift;
- my $dn='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $suffix,
- scope => $scope,
- filter => "(&(objectclass=posixAccount)(uid=$user))"
- );
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- $dn= $entry->dn;
- }
- $ldap_slave->unbind;
- chomp($dn);
+ my $dn=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^dn:"`;
+ chomp $dn;
if ($dn eq '') {
- return undef;
+ return undef;
}
- $dn="dn: ".$dn;
+
return $dn;
- }
-
+}
+# return (success, dn)
sub get_user_dn2
- {
+{
my $user = shift;
- my $dn='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $suffix,
- scope => $scope,
- filter => "(&(objectclass=posixAccount)(uid=$user))"
- );
- $mesg->code && warn "failed to perform search; ", $mesg->error;
-
- foreach my $entry ($mesg->all_entries) {
- $dn= $entry->dn;
+
+ my $sr = `$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))'`;
+ if ($sr eq "") {
+ print "get_user_dn2: error in ldapsearch :
+$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))'\n";
+ return (0, undef);
}
- $ldap_slave->unbind;
- chomp($dn);
+
+ my @lines = split(/\n/, $sr);
+
+ my @matches = grep(/^dn:/, @lines);
+
+ my $dn = $matches[0];
+ chomp $dn;
if ($dn eq '') {
- return (1,undef);
+ return (1, undef);
}
- $dn="dn: ".$dn;
- return (1,$dn);
- }
-
+
+ return (1, $dn);
+}
+# dn_line = get_group_dn($groupname)
+# where dn_line is like "dn: a=b,c=d"
sub get_group_dn
- {
- my $group = shift;
- my $dn='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))"
- );
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- $dn= $entry->dn;
- }
- $ldap_slave->unbind;
- chomp($dn);
- if ($dn eq '') {
- return undef;
- }
- $dn="dn: ".$dn;
- return $dn;
- }
+{
+ my $group = shift;
+ my $dn=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))' | grep "^dn:"`;
+ chomp $dn;
+ if ($dn eq '') {
+ return undef;
+ }
+
+ return $dn;
+}
-# return (success, dn)
# bool = is_samba_user($username)
sub is_samba_user
- {
- my $user = shift;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $suffix,
- scope => $scope,
- filter => "(&(objectClass=sambaSamAccount)(uid=$user))"
- );
- $mesg->code && die $mesg->error;
- $ldap_slave->unbind;
- return ($mesg->count ne 0);
- }
-
-sub is_unix_user
- {
- my $user = shift;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $suffix,
- scope => $scope,
- filter => "(&(objectClass=posixAccount)(uid=$user))"
- );
- $mesg->code && die $mesg->error;
- $ldap_slave->unbind;
- return ($mesg->count ne 0);
- }
-
-sub is_group_member
- {
- my $dn_group = shift;
- my $user = shift;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $dn_group,
- scope => 'base',
- filter => "(&(memberUid=$user))"
- );
- $mesg->code && die $mesg->error;
- $ldap_slave->unbind;
- return ($mesg->count ne 0);
- }
-
-# all entries = does_sid_exist($sid,$scope)
-sub does_sid_exist
- {
- my $sid = shift;
- my $dn_group=shift;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( base => $dn_group,
- scope => $scope,
- filter => "(sambaSID=$sid)"
- #filter => "(&(objectClass=sambaSamAccount|objectClass=sambaGroupMapping)(sambaSID=$sid))"
- );
- $mesg->code && die $mesg->error;
- $ldap_slave->unbind;
- return ($mesg);
- }
+{
+ my $user = shift;
+ my $cmd = "$ldapsearch -b '$suffix' -s '$scope' '(&(objectClass=sambaAccount)(uid=$user))' | grep '^dn:\'";
+ my $res=`$cmd`;
+ chomp $res;
+ if ($res ne '') {
+ return 1;
+ }
+ return 0;
+}
+# bool = is_user_valid($username)
# try to bind with user dn and password to validate current password
-sub is_user_valid
- {
- my ($user, $dn, $pass) = @_;
- my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
- my $mesg= $ldap->bind (dn => $dn, password => $pass );
- if ($mesg->code eq 0) {
- $ldap->unbind;
- return 1;
- } else {
- if ($ldap->bind()) {
- $ldap->unbind;
- return 0;
- } else {
- print ("The LDAP directory is not available.\n Check the server, cables ...");
- $ldap->unbind;
- return 0;
- }
- die "Problem : contact your administrator";
- }
- }
-
+sub is_user_valid
+{
+ my ($user, $dn, $pass) = @_;
+ my $res=`$ldapsearchnobind -b '$usersdn' -s '$scope' -D '$dn' -w '$pass' '(&(objectclass=posixAccount)(uid=$user))' 2>/dev/null | grep "^dn:"`;
+ chomp $res;
+ if ($res eq '') {
+ return 0;
+ }
+ return 1;
+}
# dn = get_dn_from_line ($dn_line)
# helper to get "a=b,c=d" from "dn: a=b,c=d"
sub get_dn_from_line
- {
- my $dn = shift;
- $dn =~ s/^dn: //;
- return $dn;
- }
-
+{
+ my $dn = shift;
+ $dn =~ s/^dn: //;
+ return $dn;
+}
# success = add_posix_machine($user, $uid, $gid)
sub add_posix_machine
- {
- my ($user, $uid, $gid) = @_;
- # bind to a directory with dn and password
- my $ldap_master=connect_ldap_master();
- my $add = $ldap_master->add ( "uid=$user,$computersdn",
- attr => [
- 'objectclass' => ['top','inetOrgPerson', 'posixAccount'],
- 'cn' => "$user",
- 'sn' => "$user",
- 'uid' => "$user",
- 'uidNumber' => "$uid",
- 'gidNumber' => "$gid",
- 'homeDirectory' => '/dev/null',
- 'loginShell' => '/bin/false',
- 'description' => 'Computer',
- ]
- );
-
- $add->code && warn "failed to add entry: ", $add->error ;
- # take down the session
- $ldap_master->unbind;
-
- }
+{
+ my ($user, $uid, $gid) = @_;
+
+my $tmpldif =
+"dn: uid=$user,$computersdn
+objectclass: top
+objectclass: posixAccount
+cn: $user
+uid: $user
+uidNumber: $uid
+gidNumber: $gid
+homeDirectory: /dev/null
+loginShell: /bin/false
+description: Computer
+
+";
+
+ die "$0: error while adding posix account to machine $user\n"
+ unless (do_ldapadd($tmpldif) == 0);
+
+ undef $tmpldif;
+ return 1;
+}
# success = add_samba_machine($computername)
sub add_samba_machine
- {
+{
my $user = shift;
system "smbpasswd -a -m $user";
+
return 1;
- }
+}
sub add_samba_machine_mkntpwd
- {
- my ($user, $uid) = @_;
- my $sambaSID = 2 * $uid + 1000;
- my $name = $user;
- $name =~ s/.$//s;
-
- if ($mk_ntpasswd eq '') {
- print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
- return 0;
- }
+{
+ my ($user, $uid) = @_;
+ my $rid = 2 * $uid + 1000; # Samba 2.2.2 stuff
- my $ntpwd = `$mk_ntpasswd '$name'`;
- chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
- chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
-
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ( "uid=$user,$computersdn",
- changes => [
- replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSamAccount']],
- add => [sambaPwdLastSet => '0'],
- add => [sambaLogonTime => '0'],
- add => [sambaLogoffTime => '2147483647'],
- add => [sambaKickoffTime => '2147483647'],
- add => [sambaPwdCanChange => '0'],
- add => [sambaPwdMustChange => '0'],
- add => [sambaAcctFlags => '[W ]'],
- add => [sambaLMPassword => "$lmpassword"],
- add => [sambaNTPassword => "$ntpassword"],
- add => [sambaSID => "$SID-$sambaSID"],
- add => [sambaPrimaryGroupSID => "$SID-0"]
- ]
- );
-
- $modify->code && die "failed to add entry: ", $modify->error ;
+ my $name = $user;
+ $name =~ s/.$//s;
- return 1;
- # take down the session
- $ldap_master->unbind;
+ if ($mk_ntpasswd eq '') {
+ print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n";
+ return 0;
+ }
+
+ my $ntpwd = `$mk_ntpasswd '$name'`;
+ chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+ chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+ my $tmpldif =
+"dn: uid=$user,$computersdn
+changetype: modify
+objectclass: top
+objectclass: posixAccount
+objectClass: sambaAccount
+pwdLastSet: 0
+logonTime: 0
+logoffTime: 2147483647
+kickoffTime: 2147483647
+pwdCanChange: 0
+pwdMustChange: 2147483647
+acctFlags: [W ]
+lmpassword: $lmpassword
+ntpassword: $ntpassword
+rid: $rid
+primaryGroupID: 0
+
+";
+
+ die "$0: error while adding samba account to $user\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+
+ return 1;
+}
- }
sub group_add_user
- {
- my ($group, $userid) = @_;
- my $members='';
- my $dn_line = get_group_dn($group);
- if (!defined(get_group_dn($group))) {
- print "$0: group \"$group\" doesn't exist\n";
- exit (6);
- }
- if (!defined($dn_line)) {
- return 1;
- }
- my $dn = get_dn_from_line("$dn_line");
- # on look if the user is already present in the group
- my $is_member=is_group_member($dn,$userid);
- if ($is_member == 1) {
- print "User \"$userid\" already member of the group \"$group\".\n";
- } else {
- # bind to a directory with dn and password
- my $ldap_master=connect_ldap_master();
- # It does not matter if the user already exist, Net::LDAP will add the user
- # if he does not exist, and ignore him if his already in the directory.
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- add => [memberUid => $userid]
- ]
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind;
- }
- }
-
-sub group_del
- {
- my $group_dn=shift;
- # bind to a directory with dn and password
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->delete ($group_dn);
- $modify->code && die "failed to delete group : ", $modify->error ;
- # take down session
- $ldap_master->unbind;
- }
-
-sub add_grouplist_user
- {
- my ($grouplist, $user) = @_;
- my @array = split(/,/, $grouplist);
- foreach my $group (@array) {
- group_add_user($group, $user);
- }
- }
+{
+ my ($group, $userid) = @_;
+ my $dn_line;
+
+ if (!defined($dn_line = get_group_dn($group))) {
+ return 1;
+ }
+ my $dn = get_dn_from_line($dn_line);
+ my $members = `$ldapsearch -b '$dn' -s base | grep -i "^memberUid:"`;
+ chomp($members);
+ # user already member ?
+ if ($members =~ m/^memberUid: $userid/) {
+ return 2;
+ }
+ my $mods = "";
+ if ($members ne '') {
+ $mods="$dn_line
+changetype: modify
+replace: memberUid
+$members
+memberUid: $userid
+";
+ } else {
+ $mods="$dn_line
+changetype: modify
+add: memberUid
+memberUid: $userid
+";
+ }
+
+ #print "$mods\n";
+
+ my $tmpldif =
+"$mods
+";
+
+ die "$0: error while modifying group $group\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+ return 0;
+}
+
+sub add_grouplist_user
+{
+ my ($grouplist, $user) = @_;
+ my @array = split(/,/, $grouplist);
+ foreach my $group (@array) {
+ group_add_user($group, $user);
+ }
+}
+# XXX FIXME : acctFlags |= D, and not acctFlags = D
sub disable_user
- {
- my $user = shift;
- my $dn_line;
- my $dn = get_dn_from_line($dn_line);
-
- if (!defined($dn_line = get_user_dn($user))) {
- print "$0: user $user doesn't exist\n";
- exit (10);
- }
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- replace => [userPassword => '{crypt}!x']
- ]
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
-
- if (is_samba_user($user)) {
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- replace => [sambaAcctFlags => '[D ]']
- ]
- );
- $modify->code && die "failed to modify entry: ", $modify->error ;
- }
- # take down session
- $ldap_master->unbind;
- }
+{
+ my $user = shift;
+ my $dn_line;
+
+ if (!defined($dn_line = get_user_dn($user))) {
+ print "$0: user $user doesn't exist\n";
+ exit (10);
+ }
+
+ my $tmpldif =
+"dn: $dn_line
+changetype: modify
+replace: userPassword
+userPassword: {crypt}!x
+
+";
+
+ die "$0: error while modifying user $user\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+
+ if (is_samba_user($user)) {
+
+ my $tmpldif =
+"dn: $dn_line
+changetype: modify
+replace: acctFlags
+acctFlags: [D ]
+
+";
+
+ die "$0: error while modifying user $user\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+
+ }
+
+}
# delete_user($user)
sub delete_user
- {
- my $user = shift;
- my $dn_line;
+{
+ my $user = shift;
+ my $dn_line;
- if (!defined($dn_line = get_user_dn($user))) {
- print "$0: user $user doesn't exist\n";
- exit (10);
- }
+ if (!defined($dn_line = get_user_dn($user))) {
+ print "$0: user $user doesn't exist\n";
+ exit (10);
+ }
- my $dn = get_dn_from_line($dn_line);
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->delete($dn);
- $ldap_master->unbind;
- }
+ my $dn = get_dn_from_line($dn_line);
+ system "$ldapdelete $dn >/dev/null";
+}
-# $gid = group_add($groupname, $group_gid, $force_using_existing_gid)
+# $success = group_add($groupname, $group_gid, $force_using_existing_gid)
sub group_add
- {
- my ($gname, $gid, $force) = @_;
- my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
- if ($nscd_status == 0) {
- system "/etc/init.d/nscd stop > /dev/null 2>&1";
- }
- if (!defined($gid)) {
- while (defined(getgrgid($GID_START))) {
- $GID_START++;
- }
- $gid = $GID_START;
- } else {
- if (!defined($force)) {
- if (defined(getgrgid($gid))) {
- return undef;
- }
- }
+{
+ my ($gname, $gid, $force) = @_;
+
+ my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
+
+ if ($nscd_status == 0) {
+ system "/etc/init.d/nscd stop > /dev/null 2>&1";
+ }
+
+ if (!defined($gid)) {
+ while (defined(getgrgid($GID_START))) {
+ $GID_START++;
}
- if ($nscd_status == 0) {
- system "/etc/init.d/nscd start > /dev/null 2>&1";
+ $gid = $GID_START;
+ } else {
+ if (!defined($force)) {
+ if (defined(getgrgid($gid))) {
+ return 0;
+ }
}
- my $ldap_master=connect_ldap_master();
- my $modify = $ldap_master->add ( "cn=$gname,$groupsdn",
- attrs => [
- objectClass => 'posixGroup',
- cn => "$gname",
- gidNumber => "$gid"
- ]
- );
-
- $modify->code && die "failed to add entry: ", $modify->error ;
- # take down session
- $ldap_master->unbind;
- return $gid;
- }
+ }
+
+ if ($nscd_status == 0) {
+ system "/etc/init.d/nscd start > /dev/null 2>&1";
+ }
+
+ my $tmpldif =
+"dn: cn=$gname,$groupsdn
+objectclass: posixGroup
+cn: $gname
+gidNumber: $gid
+
+";
+
+ die "$0: error while adding posix group $gname\n"
+ unless (do_ldapadd($tmpldif) == 0);
+
+ undef $tmpldif;
+
+ return 1;
+}
# $homedir = get_homedir ($user)
sub get_homedir
- {
- my $user = shift;
- my $homeDir='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search (
- base =>$suffix,
- scope => $scope,
- filter => "(&(objectclass=posixAccount)(uid=$user))"
- );
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- foreach my $attr ($entry->attributes) {
- if ($attr=~/\bhomeDirectory\b/) {
- foreach my $ent ($entry->get_value($attr)) {
- $homeDir.= $attr.": ".$ent."\n";
- }
- }
- }
- }
- $ldap_slave->unbind;
- chomp $homeDir;
- if ($homeDir eq '') {
- return undef;
- }
- $homeDir =~ s/^homeDirectory: //;
- return $homeDir;
- }
+{
+ my $user = shift;
+ my $homeDir=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' | grep "^homeDirectory:"`;
+ chomp $homeDir;
+ if ($homeDir eq '') {
+ return undef;
+ }
+ $homeDir =~ s/^homeDirectory: //;
+
+ return $homeDir;
+}
# search for an user
sub read_user
- {
- my $user = shift;
- my $lines ='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( # perform a search
- base => $suffix,
- scope => $scope,
- filter => "(&(objectclass=posixAccount)(uid=$user))"
- );
-
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- $lines.= "dn: " . $entry->dn."\n";
- foreach my $attr ($entry->attributes) {
- {
- $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
- }
- }
- }
- # take down session
- $ldap_slave->unbind;
- chomp $lines;
- if ($lines eq '') {
- return undef;
- }
- return $lines;
- }
-
-# search for a user
-# return the attributes in an array
-sub read_user_entry
- {
- my $user = shift;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( # perform a search
- base => $suffix,
- scope => $scope,
- filter => "(&(objectclass=posixAccount)(uid=$user))"
- );
-
- $mesg->code && die $mesg->error;
- my $entry = $mesg->entry();
- $ldap_slave->unbind;
- return $entry;
- }
+{
+ my $user = shift;
+ my $lines=`$ldapsearch -b '$suffix' -s '$scope' '(&(objectclass=posixAccount)(uid=$user))' -LLL`;
+ chomp $lines;
+ if ($lines eq '') {
+ return undef;
+ }
+
+ return $lines;
+}
# search for a group
sub read_group
- {
- my $user = shift;
- my $lines ='';
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( # perform a search
- base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixGroup)(cn=$user))"
- );
-
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- $lines.= "dn: " . $entry->dn."\n";
- foreach my $attr ($entry->attributes) {
- {
- $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n";
- }
- }
- }
- # take down session
- $ldap_slave->unbind;
- chomp $lines;
- if ($lines eq '') {
- return undef;
- }
- return $lines;
- }
+{
+ my $user = shift;
+ my $lines=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(cn=$user))' -LLL`;
+ chomp $lines;
+ if ($lines eq '') {
+ return undef;
+ }
+
+ return $lines;
+}
# find groups of a given user
-##### MODIFIE ########
sub find_groups_of
- {
- my $user = shift;
- my $lines ='';
- my $ldap_slave=connect_ldap_slave;
- my $mesg = $ldap_slave->search ( # perform a search
- base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixGroup)(memberuid=$user))"
- );
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- $lines.= "dn: ".$entry->dn."\n";
- }
- $ldap_slave->unbind;
- chomp($lines);
- if ($lines eq '') {
- return undef;
- }
- return $lines;
- }
-
-sub read_group_entry {
- my $group = shift;
- my $entry;
- my %res;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( # perform a search
- base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixGroup)(cn=$group))"
- );
-
- $mesg->code && die $mesg->error;
- my $nb=$mesg->count;
- if ($nb > 1) {
- print "Error: $nb groups exist \"cn=$group\"\n";
- foreach $entry ($mesg->all_entries) { my $dn=$entry->dn; print " $dn\n"; }
- exit 11;
- } else {
- $entry = $mesg->shift_entry();
- }
- return $entry;
-}
+{
+ my $user = shift;
+ my $lines=`$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixGroup)(memberuid=$user))' -LLL | grep "^dn: "`;
+ chomp $lines;
+ if ($lines eq '') {
+ return undef;
+ }
-sub read_group_entry_gid {
- my $group = shift;
- my %res;
- my $ldap_slave=connect_ldap_slave();
- my $mesg = $ldap_slave->search ( # perform a search
- base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixGroup)(gidNumber=$group))"
- );
-
- $mesg->code && die $mesg->error;
- my $entry = $mesg->shift_entry();
- return $entry;
+ return $lines;
}
# return the gidnumber for a group given as name or gid
# -1 : bad group name
# -2 : bad gidnumber
sub parse_group
- {
- my $userGidNumber = shift;
- if ($userGidNumber =~ /[^\d]/ ) {
- my $gname = $userGidNumber;
- my $gidnum = getgrnam($gname);
- if ($gidnum !~ /\d+/) {
- return -1;
- } else {
- $userGidNumber = $gidnum;
- }
- } elsif (!defined(getgrgid($userGidNumber))) {
- return -2;
+{
+ my $userGidNumber = shift;
+
+ if ($userGidNumber =~ /[^\d]/ ) {
+ my $gname = $userGidNumber;
+ my $gidnum = getgrnam($gname);
+ if ($gidnum !~ /\d+/) {
+ return -1;
+ } else {
+ $userGidNumber = $gidnum;
}
- return $userGidNumber;
- }
+ } elsif (!defined(getgrgid($userGidNumber))) {
+ return -2;
+ }
+ return $userGidNumber;
+}
# remove $user from $group
sub group_remove_member
- {
- my ($group, $user) = @_;
- my $members='';
- my $grp_line = get_group_dn($group);
- if (!defined($grp_line)) {
- return 0;
- }
- my $dn = get_dn_from_line($grp_line);
- # we test if the user exist in the group
- my $is_member=is_group_member($dn,$user);
- if ($is_member == 1) {
- my $ldap_master=connect_ldap_master();
- # delete only the user from the group
- my $modify = $ldap_master->modify ( "$dn",
- changes => [
- delete => [memberUid => ["$user"]]
- ]
- );
- $modify->code && die "failed to delete entry: ", $modify->error ;
- $ldap_master->unbind;
- }
- return 1;
- }
+{
+ my ($group, $user) = @_;
+
+ my $grp_line = get_group_dn($group);
+ if (!defined($grp_line)) {
+ return 0;
+ }
+ my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' | grep -i "^memberUid:"`;
+
+ #print "avant ---\n$members\n";
+ $members =~ s/memberUid: $user\n//;
+ #print "----\n$members\n---\n";
+
+ chomp($members);
+
+ my $header;
+ if ($members eq '') {
+ $header = "changetype: modify\n";
+ $header .= "delete: memberUid";
+ } else {
+ $header = "changetype: modify\n";
+ $header .= "replace: memberUid";
+ }
+
+ my $tmpldif =
+"$grp_line
+$header
+$members
+";
+ die "$0: error while modifying group $group\n"
+ unless (do_ldapmodify($tmpldif) == 0);
+ undef $tmpldif;
+
+ return 1;
+}
sub group_get_members
- {
- my ($group) = @_;
- my $members;
- my @resultat;
- my $grp_line = get_group_dn($group);
- if (!defined($grp_line)) {
- return 0;
- }
+{
+ my ($group) = @_;
+ my @members;
- my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP";
- $ldap->bind ;
- my $mesg = $ldap->search (
- base => $groupsdn,
- scope => $scope,
- filter => "(&(objectclass=posixgroup)(cn=$group))"
- );
- $mesg->code && die $mesg->error;
- foreach my $entry ($mesg->all_entries) {
- foreach my $attr ($entry->attributes) {
- if ($attr=~/\bmemberUid\b/) {
- foreach my $ent ($entry->get_value($attr)) {
- push (@resultat,$ent);
- }
- }
- }
- }
- return @resultat;
- }
+ my $grp_line = get_group_dn($group);
+ if (!defined($grp_line)) {
+ return 0;
+ }
+ my $members = `$ldapsearch -b '$groupsdn' -s '$scope' '(&(objectclass=posixgroup)(cn=$group))' memberUid | grep -i "^memberUid:"`;
+
+ my @lines = split (/\n/, $members);
+ foreach my $line (@lines) {
+ $line =~ s/^memberUid: //;
+ push(@members, $line);
+ }
+
+ return @members;
+}
+
+sub file_write {
+ my ($filename, $filecontent) = @_;
+ local *FILE;
+ open (FILE, "> $filename") ||
+ die "Cannot open «$filename» for writing: $!\n";
+ print FILE $filecontent;
+ close FILE;
+}
+
+# wrapper for ldapadd
+sub do_ldapadd2
+{
+ my $ldif = shift;
+
+ my $tempfile = "/tmp/smbldapadd.$$";
+ file_write($tempfile, $ldif);
+
+ my $rc = system "$ldapadd < $tempfile >/dev/null";
+ unlink($tempfile);
+ return $rc;
+}
+
+sub do_ldapadd
+{
+ my $ldif = shift;
+
+ my $FILE = "|$ldapadd >/dev/null";
+ open (FILE, $FILE) || die "$!\n";
+ print FILE <<EOF;
+$ldif
+EOF
+ ;
+ close FILE;
+ my $rc = $?;
+ return $rc;
+}
+
+# wrapper for ldapmodify
+sub do_ldapmodify2
+{
+ my $ldif = shift;
+
+ my $tempfile = "/tmp/smbldapmod.$$";
+ file_write($tempfile, $ldif);
+
+ my $rc = system "$ldapmodify -r < $tempfile >/dev/null";
+ unlink($tempfile);
+ return $rc;
+}
sub do_ldapmodify
- {
- my $ldif = shift;
- my $FILE = "|$ldapmodify -r >/dev/null";
- open (FILE, $FILE) || die "$!\n";
- print FILE <<EOF;
+{
+ my $ldif = shift;
+
+ my $FILE = "|$ldapmodify -r >/dev/null";
+ open (FILE, $FILE) || die "$!\n";
+ print FILE <<EOF;
$ldif
EOF
- ;
- close FILE;
- my $rc = $?;
- return $rc;
- }
-
-sub group_type_by_name {
- my $type_name = shift;
- my %groupmap = (
- 'domain' => 2,
- 'local' => 4,
- 'builtin' => 5
- );
- return $groupmap{$type_name};
+ ;
+ close FILE;
+ my $rc = $?;
+
+ return $rc;
}
diff --git a/examples/VFS/Makefile.in b/examples/VFS/Makefile.in
index c368974bd5e..a39ab511dd1 100644
--- a/examples/VFS/Makefile.in
+++ b/examples/VFS/Makefile.in
@@ -1,43 +1,31 @@
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LDSHFLAGS = @LDSHFLAGS@
-INSTALLCMD = @INSTALL@
-SAMBA_SOURCE = @SAMBA_SOURCE@
-SHLIBEXT = @SHLIBEXT@
-OBJEXT = @OBJEXT@
-FLAGS = $(CFLAGS) -Iinclude -I$(SAMBA_SOURCE)/include -I$(SAMBA_SOURCE)/ubiqx -I$(SAMBA_SOURCE)/smbwrapper -I. $(CPPFLAGS) -I$(SAMBA_SOURCE)
+##########################################################################
+# Makefile.in for Samba VFS modules
+###########################################################################
+CC=@CC@
+LIBTOOL=@LIBTOOL@
+CFLAGS=@CFLAGS@
+LDFLAGS=@LDFLAGS@
-prefix = @prefix@
-libdir = @libdir@
+VFS_OBJS=audit.so skel.so block/block.so recycle/recycle.so
-VFS_LIBDIR = $(libdir)/vfs
+SHELL=/bin/sh
-# Auto target
-default: $(patsubst %.c,%.$(SHLIBEXT),$(wildcard *.c))
+default: $(VFS_OBJS)
# Pattern rules
-%.$(SHLIBEXT): %.$(OBJEXT)
- @echo "Linking $@"
- @$(CC) $(LDSHFLAGS) $(LDFLAGS) -o $@ $<
+%.so: %.lo
+ @echo Linking $<
+ @$(LIBTOOL) --mode=link $(CC) -o $@ $< $(LDFLAGS)
-%.$(OBJEXT): %.c
- @echo "Compiling $<"
- @$(CC) $(FLAGS) -c $<
-
-
-install: default
- $(INSTALLCMD) -d $(VFS_LIBDIR)
- $(INSTALLCMD) -m 755 *.$(SHLIBEXT) $(VFS_LIBDIR)
+%.lo: %.c
+ @echo Compiling $<
+ @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
# Misc targets
-clean:
- rm -rf .libs
- rm -f core *~ *% *.bak *.o *.$(SHLIBEXT)
-distclean: clean
- rm config.* Makefile
+clean:
+ rm -rf .libs */.libs
+ rm -f core *~ *% *.bak *.o */*.o *.lo $(VFS_OBJS)
diff --git a/examples/VFS/README b/examples/VFS/README
index 2f6196d1178..475c4ec43fe 100644
--- a/examples/VFS/README
+++ b/examples/VFS/README
@@ -1,20 +1,45 @@
-README for Samba Virtual File System (VFS) Example
+README for Samba Virtual File System (VFS) Examples
===================================================
-This directory contains skeleton VFS modules. When used,
-this module simply passes all requests back to the disk functions
-(i.e it operates as a passthrough filter). It should be
-useful as a starting point for developing new VFS
-modules.
+This directory contains some sample code to demonstrate VFS
+construction. The following VFS modules are given:
-Please look at skel_opaque.c when you want your module to provide
-final functions, like a database filesystem.
+ skel
+ A skeleton VFS module. When used, this module simply
+ passes all requests back to the disk functions (i.e it
+ operates as a passthrough filter). It should be
+ useful as a starting point for developing new VFS
+ modules.
-Please look at skel_transport.c when you want your module to provide
-passthrough functions, like audit modules.
+ audit
+ A simple module to audit file access to the syslog
+ facility. The following operations are logged: share
+ connect/disconnect, directory opens/create/remove,
+ file open/close/rename/unlink/chmod.
-Please read the VFS chapter in the HOWTO collection for general help
-on the usage of VFS modules.
+ recycle/
+ Add a recycle bin facility to a samba share.
+ see recycle/README for details
+
+ block/
+
+ A directory containing a sample module by Ronald Kuetemeier
+ <ronald@kuetemeier.com> to block named symbolic link following.
+ Note: Config file is in /etc/samba/samba-block.conf
+
+The libtool program, available from your favourite GNU software
+archive, is required to compile these programs.
+
+To use the VFS modules, create a share similar to the one below. The
+important parameter is the 'vfs object' parameter which must point to
+the exact pathname of the shared library object.
+
+ [audit]
+ comment = Audited /data directory
+ path = /data
+ vfs object = /path/to/audit.so
+ writeable = yes
+ browseable = yes
Further documentation on writing VFS modules for Samba can be found in
-Samba Developers Guide.
+docs directory of the Samba source distribution.
diff --git a/examples/VFS/audit.c b/examples/VFS/audit.c
new file mode 100755
index 00000000000..b06d5af9557
--- /dev/null
+++ b/examples/VFS/audit.c
@@ -0,0 +1,333 @@
+/*
+ * Auditing VFS module for samba. Log selected file operations to syslog
+ * facility.
+ *
+ * Copyright (C) Tim Potter, 1999-2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <syslog.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <includes.h>
+#include <vfs.h>
+
+#ifndef SYSLOG_FACILITY
+#define SYSLOG_FACILITY LOG_USER
+#endif
+
+#ifndef SYSLOG_PRIORITY
+#define SYSLOG_PRIORITY LOG_NOTICE
+#endif
+
+/* Function prototypes */
+
+int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
+void audit_disconnect(struct connection_struct *conn);
+DIR *audit_opendir(struct connection_struct *conn, const char *fname);
+int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
+int audit_rmdir(struct connection_struct *conn, const char *path);
+int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
+int audit_close(struct files_struct *fsp, int fd);
+int audit_rename(struct connection_struct *conn, const char *old, const char *new);
+int audit_unlink(struct connection_struct *conn, const char *path);
+int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
+int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
+int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
+int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
+
+/* VFS operations */
+
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
+
+struct vfs_ops audit_ops = {
+
+ /* Disk operations */
+
+ audit_connect,
+ audit_disconnect,
+ NULL, /* disk free */
+
+ /* Directory operations */
+
+ audit_opendir,
+ NULL, /* readdir */
+ audit_mkdir,
+ audit_rmdir,
+ NULL, /* closedir */
+
+ /* File operations */
+
+ audit_open,
+ audit_close,
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ NULL, /* sendfile */
+ audit_rename,
+ NULL, /* fsync */
+ NULL, /* stat */
+ NULL, /* fstat */
+ NULL, /* lstat */
+ audit_unlink,
+ audit_chmod,
+ audit_fchmod,
+ NULL, /* chown */
+ NULL, /* fchown */
+ NULL, /* chdir */
+ NULL, /* getwd */
+ NULL, /* utime */
+ NULL, /* ftruncate */
+ NULL, /* lock */
+ NULL, /* symlink */
+ NULL, /* readlink */
+ NULL, /* link */
+ NULL, /* mknod */
+ NULL, /* realpath */
+ NULL, /* fget_nt_acl */
+ NULL, /* get_nt_acl */
+ NULL, /* fset_nt_acl */
+ NULL, /* set_nt_acl */
+
+ audit_chmod_acl, /* chmod_acl */
+ audit_fchmod_acl, /* fchmod_acl */
+
+ NULL, /* sys_acl_get_entry */
+ NULL, /* sys_acl_get_tag_type */
+ NULL, /* sys_acl_get_permset */
+ NULL, /*sys_acl_get_qualifier */
+ NULL, /* sys_acl_get_file */
+ NULL, /* sys_acl_get_fd */
+ NULL, /* sys_acl_clear_perms */
+ NULL, /* sys_acl_add_perm */
+ NULL, /* sys_acl_to_text */
+ NULL, /* sys_acl_init */
+ NULL, /* sys_acl_create_entry */
+ NULL, /* sys_acl_set_tag_type */
+ NULL, /* sys_acl_set_qualifier */
+ NULL, /* sys_acl_set_permset */
+ NULL, /* sys_acl_valid */
+ NULL, /* sys_acl_set_file */
+ NULL, /* sys_acl_set_fd */
+ NULL, /* sys_acl_delete_def_file */
+ NULL, /* sys_acl_get_perm */
+ NULL, /* sys_acl_free_text */
+ NULL, /* sys_acl_free_acl */
+ NULL /* sys_acl_free_qualifier */
+};
+
+/* VFS initialisation function. Return initialised vfs_ops structure
+ back to SAMBA. */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+ struct vfs_ops tmp_ops;
+
+ *vfs_version = SMB_VFS_INTERFACE_VERSION;
+ memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+ tmp_ops.connect = audit_connect;
+ tmp_ops.disconnect = audit_disconnect;
+ tmp_ops.opendir = audit_opendir;
+ tmp_ops.mkdir = audit_mkdir;
+ tmp_ops.rmdir = audit_rmdir;
+ tmp_ops.open = audit_open;
+ tmp_ops.close = audit_close;
+ tmp_ops.rename = audit_rename;
+ tmp_ops.unlink = audit_unlink;
+ tmp_ops.chmod = audit_chmod;
+ tmp_ops.chmod_acl = audit_chmod_acl;
+ tmp_ops.fchmod = audit_fchmod;
+ tmp_ops.fchmod_acl = audit_fchmod_acl;
+
+ memcpy(&audit_ops, &tmp_ops, sizeof(struct vfs_ops));
+
+ openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
+ syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
+ return &audit_ops;
+}
+
+/* Implementation of vfs_ops. Pass everything on to the default
+ operation but log event first. */
+
+int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
+{
+ syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n",
+ svc, user);
+
+ return default_vfs_ops.connect(conn, svc, user);
+}
+
+void audit_disconnect(struct connection_struct *conn)
+{
+ syslog(SYSLOG_PRIORITY, "disconnected\n");
+ default_vfs_ops.disconnect(conn);
+}
+
+DIR *audit_opendir(struct connection_struct *conn, const char *fname)
+{
+ DIR *result = default_vfs_ops.opendir(conn, fname);
+
+ syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
+ fname,
+ (result == NULL) ? "failed: " : "",
+ (result == NULL) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ int result = default_vfs_ops.mkdir(conn, path, mode);
+
+ syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n",
+ path,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_rmdir(struct connection_struct *conn, const char *path)
+{
+ int result = default_vfs_ops.rmdir(conn, path);
+
+ syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n",
+ path,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
+{
+ int result = default_vfs_ops.open(conn, fname, flags, mode);
+
+ syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n",
+ fname, result,
+ ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_close(struct files_struct *fsp, int fd)
+{
+ int result = default_vfs_ops.close(fsp, fd);
+
+ syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
+ fd,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_rename(struct connection_struct *conn, const char *old, const char *new)
+{
+ int result = default_vfs_ops.rename(conn, old, new);
+
+ syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
+ old, new,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_unlink(struct connection_struct *conn, const char *path)
+{
+ int result = default_vfs_ops.unlink(conn, path);
+
+ syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
+ path,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ int result = default_vfs_ops.chmod(conn, path, mode);
+
+ syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
+ path, mode,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ int result;
+
+ if ( !default_vfs_ops.chmod_acl )
+ return 0;
+
+ result = default_vfs_ops.chmod_acl(conn, path, mode);
+
+ syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
+ path, mode,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+{
+ int result = default_vfs_ops.fchmod(fsp, fd, mode);
+
+ syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
+ fsp->fsp_name, mode,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
+
+int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+{
+ int result;
+
+ if ( !default_vfs_ops.fchmod_acl )
+ return 0;
+
+ result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
+
+ syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
+ fsp->fsp_name, mode,
+ (result < 0) ? "failed: " : "",
+ (result < 0) ? strerror(errno) : "");
+
+ return result;
+}
diff --git a/examples/VFS/autogen.sh b/examples/VFS/autogen.sh
deleted file mode 100755
index fcae16ec5c8..00000000000
--- a/examples/VFS/autogen.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-# Run this script to build samba from CVS.
-
-## insert all possible names (only works with
-## autoconf 2.x
-#TESTAUTOHEADER="autoheader autoheader-2.53"
-TESTAUTOCONF="autoconf autoconf-2.53"
-
-#AUTOHEADERFOUND="0"
-AUTOCONFFOUND="0"
-
-
-##
-## Look for autoheader
-##
-#for i in $TESTAUTOHEADER; do
-# if which $i > /dev/null 2>&1; then
-# if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
-# AUTOHEADER=$i
-# AUTOHEADERFOUND="1"
-# break
-# fi
-# fi
-#done
-
-##
-## Look for autoconf
-##
-
-for i in $TESTAUTOCONF; do
- if which $i > /dev/null 2>&1; then
- if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
- AUTOCONF=$i
- AUTOCONFFOUND="1"
- break
- fi
- fi
-done
-
-
-##
-## do we have it?
-##
-if [ "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0" ]; then
- echo "$0: need autoconf 2.53 or later to build samba from CVS" >&2
- exit 1
-fi
-
-
-
-#echo "$0: running $AUTOHEADER"
-#$AUTOHEADER || exit 1
-
-echo "$0: running $AUTOCONF"
-$AUTOCONF || exit 1
-
-echo "Now run ./configure and then make."
-exit 0
-
diff --git a/examples/VFS/block/block.c b/examples/VFS/block/block.c
new file mode 100755
index 00000000000..bdcc0b62c71
--- /dev/null
+++ b/examples/VFS/block/block.c
@@ -0,0 +1,515 @@
+/*
+ *
+ * Block access from links to dev mount points specified in PARAMCONF file
+ *
+ * Copyright (C) Ronald Kuetemeier, 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <syslog.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+#include <includes.h>
+#include <vfs.h>
+
+
+
+
+DIR *block_opendir(struct connection_struct *conn, const char *fname);
+int block_connect(struct connection_struct *conn, const char *service, const char *user);
+void block_disconnect(struct connection_struct *conn);
+
+
+/* VFS operations */
+
+
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
+
+struct vfs_ops execute_vfs_ops = {
+
+ /* Disk operations */
+
+ block_connect,
+ block_disconnect,
+ NULL, /* disk free */
+
+ /* Directory operations */
+
+ block_opendir,
+ NULL, /* readdir */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* closedir */
+
+ /* File operations */
+
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ NULL, /* sendfile */
+ NULL, /* rename */
+ NULL, /* fsync */
+ NULL, /* stat */
+ NULL, /* fstat */
+ NULL, /* lstat */
+ NULL, /* unlink */
+ NULL, /* chmod */
+ NULL, /* fchmod */
+ NULL, /* chown */
+ NULL, /* fchown */
+ NULL, /* chdir */
+ NULL, /* getwd */
+ NULL, /* utime */
+ NULL, /* ftruncate */
+ NULL, /* lock */
+ NULL, /* symlink */
+ NULL, /* readlink */
+ NULL, /* link */
+ NULL, /* mknod */
+ NULL, /* realpath */
+
+ /* NT ACL operations */
+
+ NULL, /* fget_nt_acl */
+ NULL, /* get_nt_acl */
+ NULL, /* fset_nt_acl */
+ NULL, /* set_nt_acl */
+
+ /* POSIX ACL operations. */
+
+ NULL, /* chmod_acl */
+ NULL, /* fchmod_acl */
+ NULL, /* sys_acl_get_entry */
+ NULL, /* sys_acl_get_tag_type */
+ NULL, /* sys_acl_get_permset */
+ NULL, /* sys_acl_get_qualifier */
+ NULL, /* sys_acl_get_file */
+ NULL, /* sys_acl_get_fd */
+ NULL, /* sys_acl_clear_perms */
+ NULL, /* sys_acl_add_perm */
+ NULL, /* sys_acl_to_text */
+ NULL, /* sys_acl_init */
+ NULL, /* sys_acl_create_entry */
+ NULL, /* sys_acl_set_tag_type */
+ NULL, /* sys_acl_set_qualifier */
+ NULL, /* sys_acl_set_permset */
+ NULL, /* sys_acl_valid */
+ NULL, /* sys_acl_set_file */
+ NULL, /* sys_acl_set_fd */
+ NULL, /* sys_acl_delete_def_file */
+ NULL, /* sys_acl_get_perm */
+ NULL, /* sys_acl_free_text */
+ NULL, /* sys_acl_free_acl */
+ NULL /* sys_acl_free_qualifier */
+};
+
+
+#ifndef PARAMCONF
+#define PARAMCONF "/etc/samba/samba-block.conf"
+#endif
+
+extern BOOL pm_process(char *FileName, BOOL (*sfunc)(char *), BOOL(*pfunc)(char * , char *));
+
+/* functions */
+
+BOOL enter_pblock_mount(char *dir);
+BOOL get_section(char *sect);
+BOOL get_parameter_value(char *param, char *value);
+BOOL load_param(void);
+BOOL search(struct stat *stat_buf);
+BOOL dir_search(char *link, const char *dir);
+BOOL enter_pblock_dir(char *dir);
+
+
+
+typedef struct block_dir
+{
+ dev_t st_dev;
+ int str_len;
+ char *dir_name;
+ struct block_dir *next;
+} block_dir;
+
+
+static char *params[] = {"mount_point","dir_name"};
+enum { MOUNT_POINT , DIR_NAME };
+
+static struct block_dir *pblock_mountp = NULL;
+static struct block_dir *pblock_dir = NULL;
+
+
+
+/*
+ * Load the conf file into a table
+ */
+
+BOOL load_param(void)
+{
+
+ if ((pm_process(PARAMCONF,&get_section,&get_parameter_value)) == TRUE)
+ {
+ return TRUE;
+
+ }
+ return FALSE;
+}
+
+
+
+/*
+ * Enter the key and data into the list
+ *
+ */
+
+BOOL enter_pblock_mount(char *dir)
+{
+ struct stat stat_buf;
+ static struct block_dir *tmp_pblock;
+
+
+ if((stat(dir,&stat_buf)) != 0)
+ {
+ return FALSE;
+ }
+
+ if(pblock_mountp == NULL)
+ {
+ pblock_mountp = calloc(1, sizeof(block_dir));
+ if( pblock_mountp == NULL)
+ {
+ return FALSE;
+ }
+ tmp_pblock = pblock_mountp;
+ tmp_pblock->next = NULL;
+
+ }else
+ {
+ tmp_pblock->next = calloc(1, sizeof(block_dir));
+ if(tmp_pblock->next == NULL)
+ {
+ return FALSE;
+ }
+ tmp_pblock = tmp_pblock->next;
+ tmp_pblock->next = NULL;
+
+ }
+
+
+ tmp_pblock->st_dev = stat_buf.st_dev;
+ tmp_pblock->dir_name = strdup(dir);
+
+
+ return TRUE;
+
+}
+
+
+/*
+ * Enter the key and data into the list
+ *
+ */
+
+BOOL enter_pblock_dir(char *dir)
+{
+ static struct block_dir *tmp_pblock;
+
+
+ if(pblock_dir == NULL)
+ {
+ pblock_dir = calloc(1, sizeof(block_dir));
+ if( pblock_dir == NULL)
+ {
+ return FALSE;
+ }
+ tmp_pblock = pblock_dir;
+ tmp_pblock->next = NULL;
+
+ }else
+ {
+ tmp_pblock->next = calloc(1, sizeof(block_dir));
+ if(tmp_pblock->next == NULL)
+ {
+ return FALSE;
+ }
+ tmp_pblock = tmp_pblock->next;
+ tmp_pblock->next = NULL;
+
+ }
+
+
+ tmp_pblock->dir_name = strdup(dir);
+ tmp_pblock->str_len = strlen(dir);
+
+
+ return TRUE;
+
+}
+
+
+
+
+/*
+ * Function callback for config section names
+ */
+
+BOOL get_section(char *sect)
+{
+ return TRUE;
+}
+
+
+
+/*
+ * Function callback for config parameter value pairs
+ *
+ */
+
+BOOL get_parameter_value(char *param, char *value)
+{
+ int i = 0, maxargs = sizeof(params) / sizeof(char *);
+
+
+ for( i= 0; i < maxargs; i++)
+ {
+ if (strcmp(param,params[i]) == 0)
+ {
+ switch(i)
+ {
+ case MOUNT_POINT :
+ enter_pblock_mount(value);
+ break;
+ case DIR_NAME :
+ enter_pblock_dir(value);
+ break;
+ default :
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+
+}
+
+
+
+
+/* VFS initialisation function. Return initialised vfs_ops structure
+ back to SAMBA. */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+ struct vfs_ops tmp_ops;
+
+ *vfs_version = SMB_VFS_INTERFACE_VERSION;
+
+ memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+ /* Override the ones we want. */
+ tmp_ops.connect = block_connect;
+ tmp_ops.disconnect = block_disconnect;
+ tmp_ops.opendir = block_opendir;
+
+ memcpy(&execute_vfs_ops, &tmp_ops, sizeof(struct vfs_ops));
+ return(&execute_vfs_ops);
+}
+
+
+/*
+ * VFS connect and param file loading
+ */
+
+int block_connect(struct connection_struct *conn, const char *service, const char *user)
+{
+ if((load_param()) == FALSE)
+ {
+
+ return -1;
+
+ }
+
+ DEBUG(0,("%s connecting \n",conn->user));
+
+ return (default_vfs_ops.connect(conn, service,user));
+}
+
+/*
+ * Free allocated structures and disconnect
+ *
+ */
+
+
+void block_disconnect(struct connection_struct *conn)
+{
+
+ struct block_dir *tmp_pblock = (pblock_mountp == NULL ? pblock_dir : pblock_mountp);
+ struct block_dir *free_pblock = NULL;
+
+ while(tmp_pblock != NULL)
+ {
+ free(tmp_pblock->dir_name);
+ free_pblock = tmp_pblock;
+ tmp_pblock = tmp_pblock->next;
+ free(free_pblock);
+
+ if(tmp_pblock == NULL && pblock_dir != NULL)
+ {
+ tmp_pblock = (pblock_mountp == NULL ? pblock_dir : NULL);
+ pblock_dir = NULL;
+
+ }
+
+ }
+
+
+
+ default_vfs_ops.disconnect(conn);
+}
+
+/*
+ * VFS opendir
+ */
+
+DIR *block_opendir(struct connection_struct *conn, const char *fname)
+{
+
+ char *dir_name = NULL;
+ struct stat stat_buf;
+
+ dir_name = alloca((strlen(conn->origpath) + strlen(fname) + 2) * sizeof(char));
+
+ pstrcpy(dir_name,conn->origpath);
+ pstrcat(dir_name, "/");
+ strncat(dir_name, fname, strcspn(fname,"/"));
+
+ if((lstat(dir_name,&stat_buf)) == 0)
+ {
+ if((S_ISLNK(stat_buf.st_mode)) == 1)
+ {
+ stat(dir_name,&stat_buf);
+ if((search(&stat_buf) || dir_search(dir_name, fname) ) == TRUE)
+ {
+ DEBUG(0,("%s used link to blocked dir: %s \n", conn->user, dir_name));
+ errno = EACCES;
+ return NULL;
+ }
+ }
+ }
+
+ return (default_vfs_ops.opendir(conn, fname));
+}
+
+
+/*
+ * Find mount point to block in list
+ */
+
+BOOL search(struct stat *stat_buf)
+{
+ struct block_dir *tmp_pblock = pblock_mountp;
+
+ while(tmp_pblock != NULL)
+ {
+
+ if(tmp_pblock->st_dev == stat_buf->st_dev)
+ {
+ return TRUE;
+ }
+ tmp_pblock = tmp_pblock->next;
+ }
+
+ return FALSE;
+
+}
+
+/*
+ * Find dir in list to block id the starting point is link from a share
+ */
+
+BOOL dir_search(char *link, const char *dir)
+{
+ char *ext_path;
+
+#ifdef PATH_MAX
+ char buf[PATH_MAX +1];
+#else
+#ifdef MAXPATHLEN
+ char buf[MAXPATHLEN +1];
+#else
+ char buf[BUFSIZ];
+#endif
+#endif
+
+ int len = 0;
+ struct block_dir *tmp_pblock = pblock_dir;
+
+ if((len = readlink(link,buf,sizeof(buf))) == -1)
+ {
+ return TRUE;
+
+ }else
+ {
+ buf[len] = '\0';
+ }
+
+
+ if((ext_path = strchr(dir,'/')) != NULL)
+ {
+ pstrcat(buf,&ext_path[1]);
+ len = strlen(buf);
+ }
+
+ while(tmp_pblock != NULL)
+ {
+ if(len < tmp_pblock->str_len)
+ {
+ tmp_pblock = tmp_pblock->next;
+ continue;
+ }
+
+ if((strstr(buf,tmp_pblock->dir_name)) != NULL)
+ {
+ return TRUE;
+ }
+ tmp_pblock = tmp_pblock->next;
+ }
+
+
+ return FALSE;
+
+}
diff --git a/examples/VFS/block/samba-block.conf b/examples/VFS/block/samba-block.conf
new file mode 100755
index 00000000000..7a137980b73
--- /dev/null
+++ b/examples/VFS/block/samba-block.conf
@@ -0,0 +1,6 @@
+[ blocked ]
+mount_point = /
+mount_point = /boot
+mount_point = /proc
+dir_name = /usr/local/src/samba
+dir_name = /usr/bin
diff --git a/examples/VFS/block/smb.conf b/examples/VFS/block/smb.conf
new file mode 100755
index 00000000000..368155f1f83
--- /dev/null
+++ b/examples/VFS/block/smb.conf
@@ -0,0 +1,13 @@
+[homes]
+ comment = Home Directories
+ vfs object = /usr/local/samba/lib/block.so
+ browseable = yes
+ writable = yes
+
+
+
+
+
+
+
+
diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in
index fda4cf3a316..2afa2e1a044 100644
--- a/examples/VFS/configure.in
+++ b/examples/VFS/configure.in
@@ -1,350 +1,92 @@
-dnl -*- mode: m4-mode -*-
-dnl Process this file with autoconf to produce a configure script.
+dnl Samba VFS Modules
-dnl We must use autotools 2.53 or above
-AC_PREREQ(2.53)
-AC_INIT(Makefile.in)
+AC_INIT
-#dnl Uncomment this if you want to use your own define's too
-#AC_CONFIG_HEADER(module_config.h)
-#dnl To make sure that didn't get #define PACKAGE_* in modules_config.h
-#echo "" > confdefs.h
+uname=`uname`
-dnl Checks for programs.
+dnl Check programs needed
AC_PROG_CC
-AC_PROG_INSTALL
-#################################################
-# Directory handling stuff to support both the
-# legacy SAMBA directories and FHS compliant
-# ones...
-AC_PREFIX_DEFAULT(/usr/local/samba)
-
-AC_ARG_WITH(fhs,
-[ --with-fhs Use FHS-compliant paths (default=no)],
- libdir="\${prefix}/lib/samba",
- libdir="\${prefix}/lib")
-
-AC_SUBST(libdir)
-
-SAMBA_SOURCE="../../source"
-####################################################
-# set the location location of the samba source tree
-AC_ARG_WITH(samba-source,
-[ --with-samba-source=DIR Where is the samba source tree (../../source)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody calls it without argument
- #
- AC_MSG_WARN([--with-samba-source called without argument - will use default])
- ;;
- * )
- SAMBA_SOURCE="$withval"
- ;;
- esac])
-
-AC_SUBST(SAMBA_SOURCE)
-
-dnl Unique-to-Samba variables we'll be playing with.
-AC_SUBST(CC)
-AC_SUBST(SHELL)
-AC_SUBST(LDSHFLAGS)
-AC_SUBST(SONAMEFLAG)
-AC_SUBST(SHLD)
-AC_SUBST(HOST_OS)
-AC_SUBST(PICFLAGS)
-AC_SUBST(PICSUFFIX)
-AC_SUBST(SHLIBEXT)
-AC_SUBST(INSTALLCLIENTCMD_SH)
-AC_SUBST(INSTALLCLIENTCMD_A)
-AC_SUBST(SHLIB_PROGS)
-AC_SUBST(EXTRA_BIN_PROGS)
-AC_SUBST(EXTRA_SBIN_PROGS)
-AC_SUBST(EXTRA_ALL_TARGETS)
-
-AC_ARG_ENABLE(debug,
-[ --enable-debug Turn on compiler debugging information (default=no)],
- [if eval "test x$enable_debug = xyes"; then
- CFLAGS="${CFLAGS} -g"
- fi])
-
-AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
- [if eval "test x$enable_developer = xyes"; then
- developer=yes
- CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
- fi])
-
-# compile with optimization and without debugging by default, but
-# allow people to set their own preference.
-if test "x$CFLAGS" = x
-then
- CFLAGS="-O ${CFLAGS}"
+dnl ensure libtool is installed
+AC_PATH_PROG(LIBTOOL, libtool,,)
+if test "$LIBTOOL" = ""; then
+ echo
+ echo 'FATAL ERROR: libtool does not seem to be installed.'
+ echo $pkg_name cannot be built without a working libtool installation.
+ exit 1
fi
- #################################################
- # check for krb5-config from recent MIT and Heimdal kerberos 5
- AC_PATH_PROG(KRB5_CONFIG, krb5-config)
- AC_MSG_CHECKING(for working krb5-config)
- if test -x "$KRB5_CONFIG"; then
- CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- FOUND_KRB5=yes
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no. Fallback to previous krb5 detection strategy)
- fi
-
- if test x$FOUND_KRB5 = x"no"; then
- #################################################
- # check for location of Kerberos 5 install
- AC_MSG_CHECKING(for kerberos 5 install path)
- AC_ARG_WITH(krb5,
- [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
- [ case "$withval" in
- no)
- AC_MSG_RESULT(no)
- ;;
- *)
- AC_MSG_RESULT(yes)
- CFLAGS="$CFLAGS -I$withval/include"
- CPPFLAGS="$CPPFLAGS -I$withval/include"
- FOUND_KRB5=yes
- ;;
- esac ],
- AC_MSG_RESULT(no)
- )
- fi
+#
+# Config CFLAGS settings
+#
+CFLAGS="-Wall"
+
+case "$uname" in
+ AIX)
+ if test "${GCC}" = "yes"; then
+ CFLAGS="$CFLAGS -I/usr/include -D_LINUX_SOURCE_COMPAT"
+ else
+ CFLAGS="-D_LINUX_SOURCE_COMPAT"
+ fi
+ ;;
+ SunOS)
+ if test "${GCC}" = "yes"; then
+ CFLAGS="$CFLAGS"
+ else
+ CFLAGS=""
+ fi
+ ;;
+# Linux)
+# CFLAGS="-Wall"
+# ;;
+esac
+
+#
+# Config LDLAGS settings
+#
+LDFLAGS="-shared"
+
+case "$uname" in
+ AIX)
+ LDFLAGS="-Wl,-G,-bexpall,-bnoentry"
+ ;;
+ SunOS)
+ LDFLAGS="-G"
+ ;;
+# Linux)
+# echo "Linux found"
+# LDFLAGS="-shared"
+# ;;
+esac
-if test x$FOUND_KRB5 = x"no"; then
#################################################
-# see if this box has the SuSE location for the heimdal kerberos implementation
-AC_MSG_CHECKING(for /usr/include/heimdal)
-if test -d /usr/include/heimdal; then
- if test -f /usr/lib/heimdal/lib/libkrb5.a; then
- CFLAGS="$CFLAGS -I/usr/include/heimdal"
- CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
- AC_MSG_RESULT(yes)
- else
- CFLAGS="$CFLAGS -I/usr/include/heimdal"
- CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
- AC_MSG_RESULT(yes)
-
- fi
-else
- AC_MSG_RESULT(no)
+# Check to see if we should use the included popt
+
+AC_ARG_WITH(included-popt,
+[ --with-included-popt use bundled popt library, not from system],
+[
+ case "$withval" in
+ yes)
+ INCLUDED_POPT=yes
+ ;;
+ no)
+ INCLUDED_POPT=no
+ ;;
+ esac ],
+)
+if test x"$INCLUDED_POPT" != x"yes"; then
+ AC_CHECK_LIB(popt, poptGetContext,
+ INCLUDED_POPT=no, INCLUDED_POPT=yes)
fi
-fi
-
-if test x$FOUND_KRB5 = x"no"; then
-#################################################
-# see if this box has the RedHat location for kerberos
-AC_MSG_CHECKING(for /usr/kerberos)
-if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then
- LDFLAGS="$LDFLAGS -L/usr/kerberos/lib"
- CFLAGS="$CFLAGS -I/usr/kerberos/include"
- CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
- AC_MSG_RESULT(yes)
+AC_MSG_CHECKING(whether to use included popt)
+if test x"$INCLUDED_POPT" = x"yes"; then
+ AC_MSG_RESULT($srcdir/popt)
+ CFLAGS="$CFLAGS -I../../source/popt"
else
- AC_MSG_RESULT(no)
-fi
+ AC_MSG_RESULT(no)
fi
- # now check for krb5.h. Some systems have the libraries without the headers!
- # note that this check is done here to allow for different kerberos
- # include paths
- AC_CHECK_HEADERS(krb5.h)
-
- # now check for gssapi headers. This is also done here to allow for
- # different kerberos include paths
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h)
-
-#dnl Check if we use GNU ld
-#LD=ld
-#AC_PROG_LD_GNU
-
-#dnl look for executable suffix
-#AC_EXEEXT
-
-builddir=`pwd`
-AC_SUBST(builddir)
-
-# Assume non-shared by default and override below
-BLDSHARED="false"
-
-# these are the defaults, good for lots of systems
-HOST_OS="$host_os"
-LDSHFLAGS="-shared"
-SONAMEFLAG="#"
-SHLD="\${CC}"
-PICFLAGS=""
-PICSUFFIX="po"
-SHLIBEXT="so"
-
-if test "$enable_shared" = "yes"; then
- # this bit needs to be modified for each OS that is suported by
- # smbwrapper. You need to specify how to created a shared library and
- # how to compile C code to produce PIC object files
-
- AC_MSG_CHECKING([ability to build shared libraries])
-
- # and these are for particular systems
- case "$host_os" in
- *linux*)
- BLDSHARED="true"
- LDSHFLAGS="-shared"
- DYNEXP="-Wl,--export-dynamic"
- PICFLAGS="-fPIC"
- SONAMEFLAG="-Wl,-soname="
- ;;
- *solaris*)
- BLDSHARED="true"
- LDSHFLAGS="-G"
- SONAMEFLAG="-h "
- if test "${GCC}" = "yes"; then
- PICFLAGS="-fPIC"
- if test "${ac_cv_prog_gnu_ld}" = "yes"; then
- DYNEXP="-Wl,-E"
- fi
- else
- PICFLAGS="-KPIC"
- ## ${CFLAGS} added for building 64-bit shared
- ## libs using Sun's Compiler
- LDSHFLAGS="-G \${CFLAGS}"
- PICSUFFIX="po.o"
- fi
- ;;
- *sunos*)
- BLDSHARED="true"
- LDSHFLAGS="-G"
- SONAMEFLAG="-Wl,-h,"
- PICFLAGS="-KPIC" # Is this correct for SunOS
- ;;
- *netbsd* | *freebsd*) BLDSHARED="true"
- LDSHFLAGS="-shared"
- DYNEXP="-Wl,--export-dynamic"
- SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC -DPIC"
- ;;
- *openbsd*) BLDSHARED="true"
- LDSHFLAGS="-shared"
- DYNEXP="-Wl,-Bdynamic"
- SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC"
- ;;
- *irix*)
- case "$host_os" in
- *irix6*)
- ;;
- esac
- ATTEMPT_WRAP32_BUILD=yes
- BLDSHARED="true"
- LDSHFLAGS="-set_version sgi1.0 -shared"
- SONAMEFLAG="-soname "
- SHLD="\${LD}"
- if test "${GCC}" = "yes"; then
- PICFLAGS="-fPIC"
- else
- PICFLAGS="-KPIC"
- fi
- ;;
- *aix*)
- BLDSHARED="true"
- LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok"
- DYNEXP="-Wl,-brtl,-bexpall"
- PICFLAGS="-O2"
- if test "${GCC}" != "yes"; then
- ## for funky AIX compiler using strncpy()
- CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000"
- fi
- ;;
- *hpux*)
- SHLIBEXT="sl"
- # Use special PIC flags for the native HP-UX compiler.
- if test $ac_cv_prog_cc_Ae = yes; then
- BLDSHARED="true"
- SHLD="/usr/bin/ld"
- LDSHFLAGS="-B symbolic -b -z"
- SONAMEFLAG="+h "
- PICFLAGS="+z"
- fi
- DYNEXP="-Wl,-E"
- ;;
- *qnx*)
- ;;
- *osf*)
- BLDSHARED="true"
- LDSHFLAGS="-shared"
- SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC"
- ;;
- *sco*)
- ;;
- *unixware*)
- BLDSHARED="true"
- LDSHFLAGS="-shared"
- SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-KPIC"
- ;;
- *next2*)
- ;;
- *dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man])
- ;;
- *sysv4*)
- case "$host" in
- *-univel-*)
- LDSHFLAGS="-G"
- DYNEXP="-Bexport"
- ;;
- *mips-sni-sysv4*)
- ;;
- esac
- ;;
-
- *sysv5*)
- LDSHFLAGS="-G"
- ;;
- *vos*)
- BLDSHARED="false"
- LDSHFLAGS=""
- ;;
- *)
- ;;
- esac
- AC_SUBST(DYNEXP)
- AC_MSG_RESULT($BLDSHARED)
- AC_MSG_CHECKING([linker flags for shared libraries])
- AC_MSG_RESULT([$LDSHFLAGS])
- AC_MSG_CHECKING([compiler flags for position-independent code])
- AC_MSG_RESULT([$PICFLAGS])
-fi
-
-#######################################################
-# test whether building a shared library actually works
-if test $BLDSHARED = true; then
-AC_CACHE_CHECK([whether building shared libraries actually works],
- [ac_cv_shlib_works],[
- ac_cv_shlib_works=no
- # try building a trivial shared library
- if test "$PICSUFFIX" = "po"; then
- $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.po ${srcdir-.}/tests/shlib.c &&
- $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po &&
- ac_cv_shlib_works=yes
- else
- $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c &&
- mv shlib.$PICSUFFIX shlib.po &&
- $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po &&
- ac_cv_shlib_works=yes
- fi
- rm -f "shlib.$SHLIBEXT" shlib.po
-])
-if test $ac_cv_shlib_works = no; then
- BLDSHARED=false
-fi
-fi
-
-
-
+CFLAGS="$CFLAGS -I../../source -I../../source/include -I../../source/ubiqx -I../../source/smbwrapper"
-AC_OUTPUT(Makefile)
+AC_OUTPUT([Makefile])
diff --git a/examples/VFS/install-sh b/examples/VFS/install-sh
deleted file mode 100644
index 58719246f04..00000000000
--- a/examples/VFS/install-sh
+++ /dev/null
@@ -1,238 +0,0 @@
-#! /bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/examples/VFS/recycle/README b/examples/VFS/recycle/README
new file mode 100755
index 00000000000..2b85a65925e
--- /dev/null
+++ b/examples/VFS/recycle/README
@@ -0,0 +1,83 @@
+The recycle VFS module implements a recycle bin for Samba.
+Deleted files will be moved to a special directory and
+not be deleted unless specified in the configuration file.
+It is up to the administrator/user to clean up the files
+in the recycle bin.
+
+Installation:
+
+1. Build VFS module using the GNU autoconf script and Makefile
+ in the parent directory (cd .. && ./configure && make)
+2. Install module by copying to /usr/lib/samba/vfs (or any other place you like)
+3. Install/modify recycle.conf. See below for the description
+4. Modify smb.conf to use the recycle module
+ Add the lines "vfs object = /usr/lib/samba/recycle.so"
+ and "vfs options = /etc/samba/recycle.conf".
+5. Start Samba
+
+
+Options for recycle.conf:
+name
+ name of the recycle bin at root level of the share
+ allows smb.conf substutitions like %U.
+ Example:
+ name = .recycle/%U
+
+mode
+ KEEP_DIRECTORIES : retain directory hierarchy of deleted file,
+ VERSIONS : create several versions of a file in recycle bin if
+ the file already exists in the recycle bin
+ e.g. mytext.doc
+ Copy #1 of mytext.doc
+ Copy #2 of mytext.doc
+
+ TOUCH : touch access date when moving files to the recycle bin.
+ This is useful for automatic cleanup scripts.
+ Attn: This doesn't work if you have no write permissions
+ to the file being deleted. Deletion works if you
+ have write permissions to the parent directory.
+ Example:
+ mode = KEEP_DIRECTORIES|VERSIONS|TOUCH
+
+maxsize
+ maximum size of files to be moved to recycle bin. Setting this zo
+ zero (default) moves files of any size to the recycle bin.
+ Example:
+ maxsize = 0
+
+exclude
+ exclude files from moving to recycle bin. Delete them immediately
+ Useful for temporary files. You can use the wildcards * and ?
+ Example:
+ exclude = *.tmp|*.temp|*.obj|~$*|*.$$$
+
+excludedir
+ exclude directories from the recycle bin, useful for temporary
+ directories.
+ Example
+ excludedir = /tmp|/temp|/trash
+
+noversions
+ don't create versions of files in the recycle bin. Only usefull if
+ mode = VERSIONS is set.
+ Examples:
+ noversions = *.doc|*.xls|*.ppt
+
+Example smb.conf:
+
+[homes]
+ comment = Home-directory
+ path = /home/%u
+ read only = No
+ create mask = 0750
+ vfs object = /usr/lib/samba/recycle.so
+ vfs options = /etc/samba/recycle.conf
+
+Example recycle.conf:
+
+name = .recycle/%U
+mode = KEEP_DIRECTORIES|NOVERSIONS|TOUCH
+maxsize = 0
+exclude = *.tmp|*.temp|*.o|*.obj|~$*
+excludedir = /tmp|/temp|/cache
+noversions = *.doc|*.xls|*.ppt
diff --git a/examples/VFS/recycle/cleanup_recycle.pl b/examples/VFS/recycle/cleanup_recycle.pl
new file mode 100755
index 00000000000..f614cf78708
--- /dev/null
+++ b/examples/VFS/recycle/cleanup_recycle.pl
@@ -0,0 +1,25 @@
+# !/usr/bin/perl -w
+#
+# this script looks for all files with an access date older than
+# $maxage days and deletes them.
+# Empty directories will be deleted afterwards
+#
+
+$dirpath = "/data/.recycle";
+$maxage = 2;
+
+# delete all old files
+@a=`find $dirpath -atime +$maxage`;
+foreach (@a)
+ {
+ print "deleting file: $_";
+ $r = `rm -f $_ 2> /dev/zero`;
+ }
+
+# delete all empty directories
+@a=`find $dirpath -type d | sort -r`;
+foreach (@a)
+ {
+ print "deleting directory: $_";
+ $r = `rmdir $_ 2> /dev/zero`;
+ }
diff --git a/examples/VFS/recycle/recycle.c b/examples/VFS/recycle/recycle.c
new file mode 100755
index 00000000000..25cae65822e
--- /dev/null
+++ b/examples/VFS/recycle/recycle.c
@@ -0,0 +1,557 @@
+/*
+ * Recycle bin VFS module for Samba.
+ *
+ * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>.
+ * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module.
+ * Copyright (C) 2002, Juergen Hasch - added some options.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <includes.h>
+#include <vfs.h>
+
+const char delimiter = '|'; /* delimiter for options */
+
+/* One per connection */
+
+typedef struct recycle_bin_struct
+{
+ TALLOC_CTX *ctx;
+ char *recycle_bin; /* name of the recycle bin directory */
+ BOOL keep_directories; /* keep directory structure of deleted file in recycle bin */
+ BOOL versions; /* create versions of deleted files with identical name */
+ BOOL touch; /* touch access date of deleted file */
+ char *exclude; /* which files to exclude */
+ char *exclude_dir; /* which directories to exclude */
+ char *noversions; /* which files to exclude from versioning */
+ SMB_OFF_T max_size; /* maximum file size to be saved */
+} recycle_bin_struct;
+
+/* Global Variables */
+static recycle_bin_struct *current;
+
+/* VFS operations */
+
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
+
+static int recycle_unlink(connection_struct *, const char *);
+static int recycle_connect(struct connection_struct *conn, const char *service, const char *user);
+static void recycle_disconnect(struct connection_struct *conn);
+
+BOOL checkparam(char *haystack,char *needle);
+
+struct vfs_ops recycle_ops = {
+
+ /* Disk operations */
+
+ recycle_connect, /* connect */
+ recycle_disconnect, /* disconnect */
+ NULL, /* disk free */
+
+ /* Directory operations */
+
+ NULL, /* opendir */
+ NULL, /* readdir */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* closedir */
+
+ /* File operations */
+
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ NULL, /* sendfile */
+ NULL, /* rename */
+ NULL, /* fsync */
+ NULL, /* stat */
+ NULL, /* fstat */
+ NULL, /* lstat */
+ recycle_unlink,
+ NULL, /* chmod */
+ NULL, /* fchmod */
+ NULL, /* chown */
+ NULL, /* fchown */
+ NULL, /* chdir */
+ NULL, /* getwd */
+ NULL, /* utime */
+ NULL, /* ftruncate */
+ NULL, /* lock */
+ NULL, /* symlink */
+ NULL, /* readlink */
+ NULL, /* link */
+ NULL, /* mknod */
+ NULL, /* realpath */
+ NULL, /* fget_nt_acl */
+ NULL, /* get_nt_acl */
+ NULL, /* fset_nt_acl */
+ NULL, /* set_nt_acl */
+
+ NULL, /* chmod_acl */
+ NULL, /* fchmod_acl */
+
+ NULL, /* sys_acl_get_entry */
+ NULL, /* sys_acl_get_tag_type */
+ NULL, /* sys_acl_get_permset */
+ NULL, /* sys_acl_get_qualifier */
+ NULL, /* sys_acl_get_file */
+ NULL, /* sys_acl_get_fd */
+ NULL, /* sys_acl_clear_perms */
+ NULL, /* sys_acl_add_perm */
+ NULL, /* sys_acl_to_text */
+ NULL, /* sys_acl_init */
+ NULL, /* sys_acl_create_entry */
+ NULL, /* sys_acl_set_tag_type */
+ NULL, /* sys_acl_set_qualifier */
+ NULL, /* sys_acl_set_permset */
+ NULL, /* sys_acl_valid */
+ NULL, /* sys_acl_set_file */
+ NULL, /* sys_acl_set_fd */
+ NULL, /* sys_acl_delete_def_file */
+ NULL, /* sys_acl_get_perm */
+ NULL, /* sys_acl_free_text */
+ NULL, /* sys_acl_free_acl */
+ NULL /* sys_acl_free_qualifier */
+};
+
+/**
+ * Parse recycle bin configuration parameters
+ *
+ * @retval False if out of memory
+ **/
+static BOOL do_parameter(char *pszParmName, char *pszParmValue)
+{
+ if (StrCaseCmp("name",pszParmName)==0) {
+ current->recycle_bin = (char *)talloc(current->ctx,sizeof(pstring));
+ if (current->recycle_bin == NULL)
+ return False;
+ current->recycle_bin = safe_strcpy(current->recycle_bin,pszParmValue,sizeof(pstring));
+ DEBUG(10, ("name=%s\n", current->recycle_bin));
+ } else if (StrCaseCmp("mode",pszParmName)==0) {
+ if (checkparam(pszParmValue,"KEEP_DIRECTORIES") == True)
+ current->keep_directories = True;
+ if (checkparam(pszParmValue,"VERSIONS") == True)
+ current->versions = True;
+ if (checkparam(pszParmValue,"TOUCH") == True)
+ current->touch = True;
+ DEBUG(10, ("mode=%s\n", pszParmValue));
+ } else if (StrCaseCmp("maxsize",pszParmName)==0) {
+ current->max_size = strtoul(pszParmValue,NULL,10);
+ DEBUG(10, ("max_size=%ld\n", (long int)current->max_size));
+ } else if (StrCaseCmp("exclude",pszParmName)==0) {
+ current->exclude = talloc_strdup(current->ctx, pszParmValue);
+ if (current->exclude == NULL)
+ return False;
+ DEBUG(10, ("exclude=%s\n", current->exclude));
+ } else if (StrCaseCmp("excludedir",pszParmName)==0) {
+ current->exclude_dir = talloc_strdup(current->ctx, pszParmValue);
+ if (current->exclude_dir == NULL)
+ return False;
+ DEBUG(10, ("exclude_dir=%s\n", current->exclude_dir));
+ } else if (StrCaseCmp("noversions",pszParmName)==0) {
+ current->noversions = talloc_strdup(current->ctx, pszParmValue);
+ if (current->noversions == NULL)
+ return False;
+ DEBUG(10, ("noversions=%s\n", current->noversions));
+ }
+ return True;
+}
+
+/**
+ * We don't care for sections in configuration file
+ *
+ **/
+static BOOL do_section(char *pszSectionName)
+{
+ return True;
+}
+
+/**
+ * VFS initialisation function.
+ *
+ * @retval initialised vfs_ops structure
+ **/
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+ struct vfs_ops tmp_ops;
+ DEBUG(3, ("Initializing VFS module recycle\n"));
+
+ *vfs_version = SMB_VFS_INTERFACE_VERSION;
+ memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+ tmp_ops.unlink = recycle_unlink;
+ tmp_ops.connect = recycle_connect;
+ tmp_ops.disconnect = recycle_disconnect;
+ memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops));
+ return &recycle_ops;
+}
+
+static int recycle_connect(struct connection_struct *conn, const char *service, const char *user)
+{
+ const char *p;
+ pstring conf_file;
+ int rc;
+ TALLOC_CTX *ctx=NULL;
+
+ DEBUG(3,("Called for service %s (%d) as user %s\n", service, SNUM(conn), user));
+
+ if (!(ctx = talloc_init_named("recycle bin"))) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ return 0;
+ }
+
+ /* read configuration file */
+ *conf_file='\0';
+ p = (const char *)lp_vfs_options(SNUM(conn));
+ if (p != NULL && strlen(p) > 0) {
+ pstrcpy(conf_file,p);
+ DEBUG(10,("Using configuration file %s\n",conf_file));
+ }
+
+ current = talloc(ctx,sizeof(recycle_bin_struct));
+ if ( current == NULL) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ return -1;
+ }
+ current->ctx = ctx;
+ /* Set defaults */
+ current->recycle_bin = talloc_strdup(ctx,".recycle");
+ current->keep_directories = False;
+ current->versions = False;
+ current->touch = False;
+ current->exclude = "";
+ current->exclude_dir = "";
+ current->noversions = "";
+ current->max_size = 0;
+ if (strlen(conf_file) > 0) {
+ rc=pm_process( conf_file, do_section, do_parameter);
+ DEBUG(10, ("pm_process returned %d\n", rc));
+ }
+ standard_sub_conn( conn , current->recycle_bin,sizeof(pstring));
+ trim_string(current->recycle_bin,"/","/");
+ conn->vfs_private= (void *)current;
+ return 0;
+}
+
+static void recycle_disconnect(struct connection_struct *conn)
+{
+ DEBUG(3, ("Disconnecting VFS module recycle_bin\n"));
+ talloc_destroy(((recycle_bin_struct*)conn->vfs_private)->ctx);
+ default_vfs_ops.disconnect(conn);
+}
+
+static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir)
+{
+ SMB_STRUCT_STAT st;
+
+ if (default_vfs_ops.stat(conn,dname,&st) != 0)
+ return(False);
+
+ if (isdir)
+ return S_ISDIR(st.st_mode) ? True : False;
+ else
+ return S_ISREG(st.st_mode) ? True : False;
+}
+
+static BOOL recycle_directory_exist(connection_struct *conn, const char *dname)
+{
+ return recycle_XXX_exist(conn, dname, True);
+}
+
+static BOOL recycle_file_exist(connection_struct *conn, const char *fname)
+{
+ return recycle_XXX_exist(conn, fname, False);
+}
+
+/**
+ * Return file size
+ * @param conn connection
+ * @param fname file name
+ * @return size in bytes
+ **/
+static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname)
+{
+ SMB_STRUCT_STAT st;
+ if (default_vfs_ops.stat(conn,fname,&st) != 0) {
+ DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno)));
+ return (SMB_OFF_T)0;
+ }
+ return(st.st_size);
+}
+
+/**
+ * Create directory tree
+ * @param conn connection
+ * @param dname Directory tree to be created
+ * @return Returns True for success
+ **/
+static BOOL recycle_create_dir(connection_struct *conn, const char *dname)
+{
+ char *c,*y;
+ int i;
+
+ mode_t mode;
+ pstring tempstr;
+ pstring newdir;
+
+ *newdir='\0';
+ mode=S_IREAD|S_IWRITE|S_IEXEC;
+ pstrcpy(tempstr,dname);
+ y=tempstr;
+ /* Create directory tree if neccessary */
+ for(c = strtok(y,"/"); c; c= strtok(NULL,"/")) {
+ pstrcat(newdir,c);
+ if (recycle_directory_exist(conn,newdir))
+ DEBUG(3, ("dir %s already exists\n",newdir));
+ else {
+ DEBUG(3, ("creating new dir %s\n",newdir));
+ i=default_vfs_ops.mkdir(conn,newdir,mode);
+ if (i) {
+ DEBUG(3,("mkdir failed for %s with error %s\n",newdir,strerror(errno)));
+ return False;
+ }
+ }
+ pstrcat(newdir,"/");
+ }
+ return True;
+}
+
+/**
+ * Check if needle is contained exactly in haystack
+ * @param haystack list of parameters separated by delimimiter character
+ * @param needle string to be matched exactly to haystack
+ * @return True if found
+ **/
+BOOL checkparam(char *haystack,char *needle)
+{
+ char *p,*c;
+ pstring str;
+ int i,len;
+
+ if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0)
+ return False;
+
+ pstrcpy(str,haystack);
+ len=strlen(str)+1;
+ p=c=str;
+
+ for (i=0; i < len; i++, p++) {
+ if (*p == delimiter || *p == '\0') {
+ *p='\0';
+ if(strncmp(c,needle,c-p) == 0)
+ return True;
+ c=p+1;
+ }
+ }
+ return False;
+}
+
+/**
+ * Check if needle is contained in haystack, * and ? patterns are resolved
+ * @param haystack list of parameters separated by delimimiter character
+ * @param needle string to be matched exectly to haystack including pattern matching
+ * @return True if found
+ **/
+BOOL matchparam(char *haystack,char *needle)
+{
+ char *p,*c;
+ pstring str;
+ int i,len;
+
+ if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0)
+ return False;
+
+ pstrcpy(str,haystack);
+ len=strlen(str)+1;
+ p=c=str;
+
+ for (i=0; i < len; i++, p++) {
+ if (*p == delimiter || *p == '\0') {
+ *p='\0';
+ if (!unix_wild_match(c,needle))
+ return True;
+ c=p+1;
+ }
+ }
+ return False;
+}
+
+/**
+ * Touch access date
+ **/
+void recycle_touch(connection_struct *conn, const char *fname)
+{
+ SMB_STRUCT_STAT st;
+ struct utimbuf tb;
+ time_t current;
+
+ if (default_vfs_ops.stat(conn,fname,&st) != 0) {
+ DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno)));
+ return;
+ }
+ current = time(&current);
+ tb.actime = current;
+ tb.modtime = st.st_mtime;
+
+ if (default_vfs_ops.utime(conn, fname, &tb) == -1 )
+ DEBUG(0, ("Touching %s failed, reason = %s\n",fname,strerror(errno)));
+ }
+
+/**
+ * Check if file should be recycled
+ **/
+static int recycle_unlink(connection_struct *conn, const char *inname)
+{
+ pstring fname,fpath, bin;
+ char *base, *ext;
+ int i=1, len, addlen;
+ SMB_BIG_UINT dfree,dsize,bsize,space_avail;
+ SMB_OFF_T fsize;
+ BOOL exist;
+ int rc;
+
+ pstrcpy(fname,inname);
+ if (conn->vfs_private)
+ current = (recycle_bin_struct *)conn->vfs_private;
+ else {
+ DEBUG(0,("Recycle bin not initialized!\n"));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ if(!current->recycle_bin || !*(current->recycle_bin)) {
+ DEBUG(3, ("Recycle path not set, purging %s...\n", fname));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ /* we don't recycle the recycle bin... */
+ if (strstr(fname,current->recycle_bin)==fname) {
+ DEBUG(3, ("File is within recycling bin\n"));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ fsize = recycle_get_file_size(conn,fname);
+ if(fsize == 0) {
+ DEBUG(3, ("File %s is empty, purging...\n", fname));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ if(current->max_size > 0 && fsize > current->max_size) {
+ DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", fname));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ space_avail = default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize)*1024L;
+ DEBUG(10,("space_avail = %Lu, fsize = %Lu\n",space_avail,fsize));
+ if(space_avail < (SMB_BIG_UINT)fsize) {
+ DEBUG(3, ("Not enough diskspace, purging file %s\n",fname));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ /* extract filename and path */
+ pstrcpy(fpath,"/");
+ pstrcat(fpath, fname);
+ base = strrchr(fpath, '/');
+ if (base == NULL) {
+ ext = strrchr(fname, '.');
+ base = (char *)fname;
+ pstrcpy(fpath,"/");
+ }
+ else {
+ ext = strrchr(base, '.');
+ *(base++) = '\0';
+ }
+
+ DEBUG(10, ("fname:%s\n", fname)); /* original filename with path */
+ DEBUG(10, ("fpath:%s\n", fpath)); /* original path */
+ DEBUG(10, ("base:%s\n", base)); /* filename without path */
+ DEBUG(10, ("ext:%s\n", ext)); /* filename extension */
+
+ if (matchparam(current->exclude,base)) {
+ DEBUG(3, ("file %s is excluded \n",base));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ if (checkparam(current->exclude_dir,fpath)) {
+ DEBUG(3, ("directory %s is excluded \n",fpath));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ pstrcpy(bin, current->recycle_bin);
+
+ /* see if we need to recreate the original directory structure in the recycle bin */
+ if (current->keep_directories == True)
+ pstrcat(bin, fpath);
+
+ exist=recycle_directory_exist(conn,bin);
+ if (exist)
+ DEBUG(10, ("Directory already exists\n"));
+ else {
+ DEBUG(10, ("Creating directory %s\n",bin));
+ rc=recycle_create_dir(conn,bin);
+ if (rc == False)
+ {
+ DEBUG(3, ("Could not create directory, purging %s...\n", fname));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+ }
+
+ pstrcat(bin, "/");
+ pstrcat(bin,base);
+ DEBUG(10, ("bin:%s\n", bin)); /* new filename with path */
+
+ /* check if we should delete file from recycle bin */
+ if (recycle_file_exist(conn,bin)) {
+ if (current->versions == False || matchparam(current->noversions,base) == True) {
+ DEBUG(3, ("Removing old file %s from recycle bin\n",bin));
+ default_vfs_ops.unlink(conn,bin);
+ }
+ }
+
+ /* rename file we move to recycle bin */
+ len = strlen(bin);
+ addlen = sizeof(pstring)-len-1;
+ while(recycle_file_exist(conn,bin)) {
+ slprintf(bin+len, addlen, " (Copy #%d)", i++);
+ pstrcat(bin, ext);
+ }
+
+ DEBUG(10, ("Moving source=%s to dest=%s\n", fname, bin));
+ rc = default_vfs_ops.rename(conn, fname, bin);
+ if (rc == -1) {
+ DEBUG(3, ("Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno),fname,bin));
+ return default_vfs_ops.unlink(conn,fname);
+ }
+
+ /* touch access date of moved file */
+ if (current->touch == True )
+ recycle_touch(conn,bin);
+ return rc;
+}
diff --git a/examples/VFS/recycle/recycle.conf b/examples/VFS/recycle/recycle.conf
new file mode 100755
index 00000000000..00cc7982124
--- /dev/null
+++ b/examples/VFS/recycle/recycle.conf
@@ -0,0 +1,17 @@
+# name of the recycle bin at root level of share
+name = .recycle
+# mode :
+# KEEP_DIRECTORIES = retain directory hierarchy of deleted file,
+# i.e. recreate all directories in recycle bin
+# VERSIONS = create copies in case of identical file names in recycle bin
+# TOUCH = touch access date of files moved into the recycle bin
+mode = KEEP_DIRECTORIES|VERSIONS|TOUCH
+# maximum file size to be moved to the recycle bin (0 means any size)
+maxsize = 0
+# exclude file names with the following extensions:
+exclude = *.tmp|*.temp|*.o|*.obj|~$*
+# exclude directories:
+excludedir = /tmp|/temp|/cache
+# Add file extensions of files where no versioning is wanted (i.e. copy # 1...)
+# only valid when mode=VERSIONS is set
+noversions = *.doc|*.xls|*.ppt
diff --git a/examples/VFS/shadow_copy_test.c b/examples/VFS/shadow_copy_test.c
deleted file mode 100644
index d2b7206cd35..00000000000
--- a/examples/VFS/shadow_copy_test.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * TEST implementation of an Shadow Copy module
- *
- * Copyright (C) Stefan Metzmacher 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-/* USE THIS MODULE ONLY FOR TESTING!!!! */
-
-/*
- For this share
- Z:\
-
- the ShadowCopies are in this directories
-
- Z:\@GMT-2003.08.05-12.00.00\
- Z:\@GMT-2003.08.05-12.01.00\
- Z:\@GMT-2003.08.05-12.02.00\
-
- e.g.
-
- Z:\testfile.txt
- Z:\@GMT-2003.08.05-12.02.00\testfile.txt
-
- or:
-
- Z:\testdir\testfile.txt
- Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt
-
-
- Note: Files must differ to be displayed via Windows Explorer!
- Directories are always displayed...
-*/
-
-static int test_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- uint32 num = 3;
- uint32 i;
-
- shadow_copy_data->num_volumes = num;
-
- if (labels) {
- shadow_copy_data->labels = (SHADOW_COPY_LABEL *)talloc_zero(shadow_copy_data->mem_ctx,(num)*sizeof(SHADOW_COPY_LABEL));
- for (i=0;i<num;i++) {
- snprintf(shadow_copy_data->labels[i], sizeof(SHADOW_COPY_LABEL), "@GMT-2003.08.05-12.%02u.00",i);
- }
- } else {
- shadow_copy_data->labels = NULL;
- }
-
- return 0;
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple shadow_copy_test_ops[] = {
- {SMB_VFS_OP(test_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS init_module(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy_test", shadow_copy_test_ops);
-}
diff --git a/examples/VFS/skel.c b/examples/VFS/skel.c
new file mode 100755
index 00000000000..e784ce8f125
--- /dev/null
+++ b/examples/VFS/skel.c
@@ -0,0 +1,528 @@
+/*
+ * Skeleton VFS module. Implements passthrough operation of all VFS
+ * calls to disk functions.
+ *
+ * Copyright (C) Tim Potter, 1999-2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <string.h>
+
+#include <includes.h>
+#include <vfs.h>
+
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
+extern struct vfs_ops skel_ops;
+
+static int skel_connect(struct connection_struct *conn, const char *service, const char *user)
+{
+ return default_vfs_ops.connect(conn, service, user);
+}
+
+static void skel_disconnect(struct connection_struct *conn)
+{
+ default_vfs_ops.disconnect(conn);
+}
+
+static SMB_BIG_UINT skel_disk_free(struct connection_struct *conn, const char *path,
+ BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+{
+ return default_vfs_ops.disk_free(conn, path, small_query, bsize,
+ dfree, dsize);
+}
+
+static DIR *skel_opendir(struct connection_struct *conn, const char *fname)
+{
+ return default_vfs_ops.opendir(conn, fname);
+}
+
+static struct dirent *skel_readdir(struct connection_struct *conn, DIR *dirp)
+{
+ return default_vfs_ops.readdir(conn, dirp);
+}
+
+static int skel_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ return default_vfs_ops.mkdir(conn, path, mode);
+}
+
+static int skel_rmdir(struct connection_struct *conn, const char *path)
+{
+ return default_vfs_ops.rmdir(conn, path);
+}
+
+static int skel_closedir(struct connection_struct *conn, DIR *dir)
+{
+ return default_vfs_ops.closedir(conn, dir);
+}
+
+static int skel_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
+{
+ return default_vfs_ops.open(conn, fname, flags, mode);
+}
+
+static int skel_close(struct files_struct *fsp, int fd)
+{
+ return default_vfs_ops.close(fsp, fd);
+}
+
+static ssize_t skel_read(struct files_struct *fsp, int fd, void *data, size_t n)
+{
+ return default_vfs_ops.read(fsp, fd, data, n);
+}
+
+static ssize_t skel_write(struct files_struct *fsp, int fd, const void *data, size_t n)
+{
+ return default_vfs_ops.write(fsp, fd, data, n);
+}
+
+static ssize_t skel_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
+ SMB_OFF_T offset, size_t n)
+{
+ return default_vfs_ops.sendfile(tofd, fsp, fromfd, hdr, offset, n);
+}
+
+static SMB_OFF_T skel_lseek(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
+{
+ return default_vfs_ops.lseek(fsp, filedes, offset, whence);
+}
+
+static int skel_rename(struct connection_struct *conn, const char *old, const char *new)
+{
+ return default_vfs_ops.rename(conn, old, new);
+}
+
+static int skel_fsync(struct files_struct *fsp, int fd)
+{
+ return default_vfs_ops.fsync(fsp, fd);
+}
+
+static int skel_stat(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ return default_vfs_ops.stat(conn, fname, sbuf);
+}
+
+static int skel_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+{
+ return default_vfs_ops.fstat(fsp, fd, sbuf);
+}
+
+static int skel_lstat(struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
+{
+ return default_vfs_ops.lstat(conn, path, sbuf);
+}
+
+static int skel_unlink(struct connection_struct *conn, const char *path)
+{
+ return default_vfs_ops.unlink(conn, path);
+}
+
+static int skel_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+{
+ return default_vfs_ops.chmod(conn, path, mode);
+}
+
+static int skel_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+{
+ return default_vfs_ops.fchmod(fsp, fd, mode);
+}
+
+static int skel_chown(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+{
+ return default_vfs_ops.chown(conn, path, uid, gid);
+}
+
+static int skel_fchown(struct files_struct *fsp, int fd, uid_t uid, gid_t gid)
+{
+ return default_vfs_ops.fchown(fsp, fd, uid, gid);
+}
+
+static int skel_chdir(struct connection_struct *conn, const char *path)
+{
+ return default_vfs_ops.chdir(conn, path);
+}
+
+static char *skel_getwd(struct connection_struct *conn, char *buf)
+{
+ return default_vfs_ops.getwd(conn, buf);
+}
+
+static int skel_utime(struct connection_struct *conn, const char *path, struct utimbuf *times)
+{
+ return default_vfs_ops.utime(conn, path, times);
+}
+
+static int skel_ftruncate(struct files_struct *fsp, int fd, SMB_OFF_T offset)
+{
+ return default_vfs_ops.ftruncate(fsp, fd, offset);
+}
+
+static BOOL skel_lock(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+{
+ return default_vfs_ops.lock(fsp, fd, op, offset, count, type);
+}
+
+static BOOL skel_symlink(struct connection_struct *conn, const char *oldpath, const char *newpath)
+{
+ return default_vfs_ops.symlink(conn, oldpath, newpath);
+}
+
+static BOOL skel_readlink(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz)
+{
+ return default_vfs_ops.readlink(conn, path, buf, bufsiz);
+}
+
+static int skel_link(struct connection_struct *conn, const char *oldpath, const char *newpath)
+{
+ return default_vfs_ops.link(conn, oldpath, newpath);
+}
+
+static int skel_mknod(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
+{
+ return default_vfs_ops.mknod(conn, path, mode, dev);
+}
+
+static char *skel_realpath(struct connection_struct *conn, const char *path, char *resolved_path)
+{
+ return default_vfs_ops.realpath(conn, path, resolved_path);
+}
+
+static size_t skel_fget_nt_acl(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc)
+{
+ return default_vfs_ops.fget_nt_acl(fsp, fd, ppdesc);
+}
+
+static size_t skel_get_nt_acl(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc)
+{
+ return default_vfs_ops.get_nt_acl(fsp, name, ppdesc);
+}
+
+static BOOL skel_fset_nt_acl(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
+{
+ return default_vfs_ops.fset_nt_acl(fsp, fd, security_info_sent, psd);
+}
+
+static BOOL skel_set_nt_acl(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
+{
+ return default_vfs_ops.set_nt_acl(fsp, name, security_info_sent, psd);
+}
+
+static BOOL skel_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode)
+{
+ return default_vfs_ops.chmod_acl(conn, name, mode);
+}
+
+static BOOL skel_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+{
+ return default_vfs_ops.fchmod_acl(fsp, fd, mode);
+}
+
+static int skel_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+ return default_vfs_ops.sys_acl_get_entry(conn, theacl, entry_id, entry_p);
+}
+
+static int skel_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+{
+ return default_vfs_ops.sys_acl_get_tag_type(conn, entry_d, tag_type_p);
+}
+
+static int skel_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+ return default_vfs_ops.sys_acl_get_permset(conn, entry_d, permset_p);
+}
+
+static void *skel_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
+{
+ return default_vfs_ops.sys_acl_get_qualifier(conn, entry_d);
+}
+
+static SMB_ACL_T skel_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
+{
+ return default_vfs_ops.sys_acl_get_file(conn, path_p, type);
+}
+
+static SMB_ACL_T skel_sys_acl_get_fd(struct files_struct *fsp, int fd)
+{
+ return default_vfs_ops.sys_acl_get_fd(fsp, fd);
+}
+
+static int skel_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset)
+{
+ return default_vfs_ops.sys_acl_clear_perms(conn, permset);
+}
+
+static int skel_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return default_vfs_ops.sys_acl_add_perm(conn, permset, perm);
+}
+
+static char *skel_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
+{
+ return default_vfs_ops.sys_acl_to_text(conn, theacl, plen);
+}
+
+static SMB_ACL_T skel_sys_acl_init(struct connection_struct *conn, int count)
+{
+ return default_vfs_ops.sys_acl_init(conn, count);
+}
+
+static int skel_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+{
+ return default_vfs_ops.sys_acl_create_entry(conn, pacl, pentry);
+}
+
+static int skel_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+{
+ return default_vfs_ops.sys_acl_set_tag_type(conn, entry, tagtype);
+}
+
+static int skel_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
+{
+ return default_vfs_ops.sys_acl_set_qualifier(conn, entry, qual);
+}
+
+static int skel_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+{
+ return default_vfs_ops.sys_acl_set_permset(conn, entry, permset);
+}
+
+static int skel_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl )
+{
+ return default_vfs_ops.sys_acl_valid(conn, theacl );
+}
+
+static int skel_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+{
+ return default_vfs_ops.sys_acl_set_file(conn, name, acltype, theacl);
+}
+
+static int skel_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
+{
+ return default_vfs_ops.sys_acl_set_fd(fsp, fd, theacl);
+}
+
+static int skel_sys_acl_delete_def_file(struct connection_struct *conn, const char *path)
+{
+ return default_vfs_ops.sys_acl_delete_def_file(conn, path);
+}
+
+static int skel_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return default_vfs_ops.sys_acl_get_perm(conn, permset, perm);
+}
+
+static int skel_sys_acl_free_text(struct connection_struct *conn, char *text)
+{
+ return default_vfs_ops.sys_acl_free_text(conn, text);
+}
+
+static int skel_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl)
+{
+ return default_vfs_ops.sys_acl_free_acl(conn, posix_acl);
+}
+
+static int skel_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
+{
+ return default_vfs_ops.sys_acl_free_qualifier(conn, qualifier, tagtype);
+}
+
+/* VFS initialisation - return vfs_ops function pointer structure */
+
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
+{
+ struct vfs_ops tmp_ops;
+
+ DEBUG(3, ("Initialising default vfs hooks\n"));
+
+ *vfs_version = SMB_VFS_INTERFACE_VERSION;
+ memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops));
+
+ tmp_ops.connect = skel_connect;
+ tmp_ops.disconnect = skel_disconnect;
+ tmp_ops.disk_free = skel_disk_free;
+
+ /* Directory operations */
+
+ tmp_ops.opendir = skel_opendir;
+ tmp_ops.readdir = skel_readdir;
+ tmp_ops.mkdir = skel_mkdir;
+ tmp_ops.rmdir = skel_rmdir;
+ tmp_ops.closedir = skel_closedir;
+
+ /* File operations */
+
+ tmp_ops.open = skel_open;
+ tmp_ops.close = skel_close;
+ tmp_ops.read = skel_read;
+ tmp_ops.write = skel_write;
+ tmp_ops.lseek = skel_lseek;
+ tmp_ops.sendfile = skel_sendfile;
+ tmp_ops.rename = skel_rename;
+ tmp_ops.fsync = skel_fsync;
+ tmp_ops.stat = skel_stat;
+ tmp_ops.fstat = skel_fstat;
+ tmp_ops.lstat = skel_lstat;
+ tmp_ops.unlink = skel_unlink;
+ tmp_ops.chmod = skel_chmod;
+ tmp_ops.fchmod = skel_fchmod;
+ tmp_ops.chown = skel_chown;
+ tmp_ops.fchown = skel_fchown;
+ tmp_ops.chdir = skel_chdir;
+ tmp_ops.getwd = skel_getwd;
+ tmp_ops.utime = skel_utime;
+ tmp_ops.ftruncate = skel_ftruncate;
+ tmp_ops.lock = skel_lock;
+ tmp_ops.symlink = skel_symlink;
+ tmp_ops.readlink = skel_readlink;
+ tmp_ops.link = skel_link;
+ tmp_ops.mknod = skel_mknod;
+ tmp_ops.realpath = skel_realpath;
+
+ tmp_ops.fget_nt_acl = skel_fget_nt_acl;
+ tmp_ops.get_nt_acl = skel_get_nt_acl;
+ tmp_ops.fset_nt_acl = skel_fset_nt_acl;
+ tmp_ops.set_nt_acl = skel_set_nt_acl;
+
+ /* POSIX ACL operations. */
+
+ tmp_ops.chmod_acl = skel_chmod_acl;
+ tmp_ops.fchmod_acl = skel_fchmod_acl;
+ tmp_ops.sys_acl_get_entry = skel_sys_acl_get_entry;
+ tmp_ops.sys_acl_get_tag_type = skel_sys_acl_get_tag_type;
+ tmp_ops.sys_acl_get_permset = skel_sys_acl_get_permset;
+ tmp_ops.sys_acl_get_qualifier = skel_sys_acl_get_qualifier;
+ tmp_ops.sys_acl_get_file = skel_sys_acl_get_file;
+ tmp_ops.sys_acl_get_fd = skel_sys_acl_get_fd;
+ tmp_ops.sys_acl_clear_perms = skel_sys_acl_clear_perms;
+ tmp_ops.sys_acl_add_perm = skel_sys_acl_add_perm;
+ tmp_ops.sys_acl_to_text = skel_sys_acl_to_text;
+ tmp_ops.sys_acl_init = skel_sys_acl_init;
+ tmp_ops.sys_acl_create_entry = skel_sys_acl_create_entry;
+ tmp_ops.sys_acl_set_tag_type = skel_sys_acl_set_tag_type;
+ tmp_ops.sys_acl_set_qualifier = skel_sys_acl_set_qualifier;
+ tmp_ops.sys_acl_set_permset = skel_sys_acl_set_permset;
+ tmp_ops.sys_acl_valid = skel_sys_acl_valid;
+ tmp_ops.sys_acl_set_file = skel_sys_acl_set_file;
+ tmp_ops.sys_acl_set_fd = skel_sys_acl_set_fd;
+ tmp_ops.sys_acl_delete_def_file = skel_sys_acl_delete_def_file;
+ tmp_ops.sys_acl_get_perm = skel_sys_acl_get_perm;
+ tmp_ops.sys_acl_free_text = skel_sys_acl_free_text;
+ tmp_ops.sys_acl_free_acl = skel_sys_acl_free_acl;
+ tmp_ops.sys_acl_free_qualifier = skel_sys_acl_free_qualifier;
+
+ memcpy(&skel_ops, &tmp_ops, sizeof(struct vfs_ops));
+
+ return &skel_ops;
+}
+
+/* VFS operations structure */
+
+struct vfs_ops skel_ops = {
+
+ /* Disk operations */
+
+ skel_connect,
+ skel_disconnect,
+ skel_disk_free,
+
+ /* Directory operations */
+
+ skel_opendir,
+ skel_readdir,
+ skel_mkdir,
+ skel_rmdir,
+ skel_closedir,
+
+ /* File operations */
+
+ skel_open,
+ skel_close,
+ skel_read,
+ skel_write,
+ skel_lseek,
+ skel_sendfile,
+ skel_rename,
+ skel_fsync,
+ skel_stat,
+ skel_fstat,
+ skel_lstat,
+ skel_unlink,
+ skel_chmod,
+ skel_fchmod,
+ skel_chown,
+ skel_fchown,
+ skel_chdir,
+ skel_getwd,
+ skel_utime,
+ skel_ftruncate,
+ skel_lock,
+ skel_symlink,
+ skel_readlink,
+ skel_link,
+ skel_mknod,
+ skel_realpath,
+
+ /* NT File ACL operations */
+
+ skel_fget_nt_acl,
+ skel_get_nt_acl,
+ skel_fset_nt_acl,
+ skel_set_nt_acl,
+
+ /* POSIX ACL operations */
+
+ skel_chmod_acl,
+ skel_fchmod_acl,
+
+ skel_sys_acl_get_entry,
+ skel_sys_acl_get_tag_type,
+ skel_sys_acl_get_permset,
+ skel_sys_acl_get_qualifier,
+ skel_sys_acl_get_file,
+ skel_sys_acl_get_fd,
+ skel_sys_acl_clear_perms,
+ skel_sys_acl_add_perm,
+ skel_sys_acl_to_text,
+ skel_sys_acl_init,
+ skel_sys_acl_create_entry,
+ skel_sys_acl_set_tag_type,
+ skel_sys_acl_set_qualifier,
+ skel_sys_acl_set_permset,
+ skel_sys_acl_valid,
+ skel_sys_acl_set_file,
+ skel_sys_acl_set_fd,
+ skel_sys_acl_delete_def_file,
+ skel_sys_acl_get_perm,
+ skel_sys_acl_free_text,
+ skel_sys_acl_free_acl,
+ skel_sys_acl_free_qualifier
+};
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
deleted file mode 100644
index 310d305cee3..00000000000
--- a/examples/VFS/skel_opaque.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Skeleton VFS module. Implements passthrough operation of all VFS
- * calls to disk functions.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) Stefan (metze) Metzmacher, 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-/* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE
- SAMBA DEVELOPERS GUIDE!!!!!!
- */
-
-/* If you take this file as template for your module
- * please make sure that you remove all vfswrap_* functions and
- * implement your own function!!
- *
- * for functions you didn't want to provide implement dummy functions
- * witch return ERROR and errno = ENOSYS; !
- *
- * --metze
- */
-
-static int skel_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
-{
- return 0;
-}
-
-static void skel_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
- return;
-}
-
-static SMB_BIG_UINT skel_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path,
- BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-{
- return vfswrap_disk_free(NULL, conn, path, small_query, bsize,
- dfree, dsize);
-}
-
-static int skel_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- return vfswrap_get_quota(NULL, conn, qtype, id, dq);
-}
-
-static int skel_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- return vfswrap_set_quota(NULL, conn, qtype, id, dq);
-}
-
-static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- return vfswrap_get_shadow_copy_data(NULL, fsp, shadow_copy_data, labels);
-}
-
-static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- return vfswrap_opendir(NULL, conn, fname);
-}
-
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
-{
- return vfswrap_readdir(NULL, conn, dirp);
-}
-
-static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- return vfswrap_mkdir(NULL, conn, path, mode);
-}
-
-static int skel_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return vfswrap_rmdir(NULL, conn, path);
-}
-
-static int skel_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dir)
-{
- return vfswrap_closedir(NULL, conn, dir);
-}
-
-static int skel_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- return vfswrap_open(NULL, conn, fname, flags, mode);
-}
-
-static int skel_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return vfswrap_close(NULL, fsp, fd);
-}
-
-static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
-{
- return vfswrap_read(NULL, fsp, fd, data, n);
-}
-
-static ssize_t skel_pread(vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset)
-{
- return vfswrap_pread(NULL, fsp, fd, data, n, offset);
-}
-
-static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
-{
- return vfswrap_write(NULL, fsp, fd, data, n);
-}
-
-ssize_t skel_pwrite(vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset)
-{
- return vfswrap_pwrite(NULL, fsp, fd, data, n, offset);
-}
-
-static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
-{
- return vfswrap_lseek(NULL, fsp, filedes, offset, whence);
-}
-
-static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
-{
- return vfswrap_rename(NULL, conn, old, new);
-}
-
-static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return vfswrap_fsync(NULL, fsp, fd);
-}
-
-static int skel_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- return vfswrap_stat(NULL, conn, fname, sbuf);
-}
-
-static int skel_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
-{
- return vfswrap_fstat(NULL, fsp, fd, sbuf);
-}
-
-static int skel_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-{
- return vfswrap_lstat(NULL, conn, path, sbuf);
-}
-
-static int skel_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return vfswrap_unlink(NULL, conn, path);
-}
-
-static int skel_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- return vfswrap_chmod(NULL, conn, path, mode);
-}
-
-static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- return vfswrap_fchmod(NULL, fsp, fd, mode);
-}
-
-static int skel_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-{
- return vfswrap_chown(NULL, conn, path, uid, gid);
-}
-
-static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
-{
- return vfswrap_fchown(NULL, fsp, fd, uid, gid);
-}
-
-static int skel_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return vfswrap_chdir(NULL, conn, path);
-}
-
-static char *skel_getwd(vfs_handle_struct *handle, connection_struct *conn, char *buf)
-{
- return vfswrap_getwd(NULL, conn, buf);
-}
-
-static int skel_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
-{
- return vfswrap_utime(NULL, conn, path, times);
-}
-
-static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T offset)
-{
- return vfswrap_ftruncate(NULL, fsp, fd, offset);
-}
-
-static BOOL skel_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
-{
- return vfswrap_lock(NULL, fsp, fd, op, offset, count, type);
-}
-
-static BOOL skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- return vfswrap_symlink(NULL, conn, oldpath, newpath);
-}
-
-static BOOL skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
-{
- return vfswrap_readlink(NULL, conn, path, buf, bufsiz);
-}
-
-static int skel_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- return vfswrap_link(NULL, conn, oldpath, newpath);
-}
-
-static int skel_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
-{
- return vfswrap_mknod(NULL, conn, path, mode, dev);
-}
-
-static char *skel_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
-{
- return vfswrap_realpath(NULL, conn, path, resolved_path);
-}
-
-static size_t skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, struct security_descriptor_info **ppdesc)
-{
- errno = ENOSYS;
- return 0;
-}
-
-static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor_info **ppdesc)
-{
- errno = ENOSYS;
- return 0;
-}
-
-static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- errno = ENOSYS;
- return False;
-}
-
-static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- errno = ENOSYS;
- return False;
-}
-
-static int skel_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static void *skel_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
-{
- errno = ENOSYS;
- return NULL;
-}
-
-static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- errno = ENOSYS;
- return NULL;
-}
-
-static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- errno = ENOSYS;
- return NULL;
-}
-
-static int skel_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static char *skel_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
-{
- errno = ENOSYS;
- return NULL;
-}
-
-static SMB_ACL_T skel_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
-{
- errno = ENOSYS;
- return NULL;
-}
-
-static int skel_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t
-size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_listxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_llistxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static ssize_t skel_flistxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- errno = ENOSYS;
- return -1;
-}
-
-static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-{
- errno = ENOSYS;
- return -1;
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple skel_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(skel_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
-
- /* Directory operations */
-
- {SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_OPAQUE},
-
- /* File operations */
-
- {SMB_VFS_OP(skel_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_read), SMB_VFS_OP_READ, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_pread), SMB_VFS_OP_PREAD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_write), SMB_VFS_OP_WRITE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_pwrite), SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lseek), SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fsync), SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_utime), SMB_VFS_OP_UTIME, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lock), SMB_VFS_OP_LOCK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_OPAQUE},
-
- /* NT File ACL operations */
-
- {SMB_VFS_OP(skel_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_OPAQUE},
-
- /* POSIX ACL operations */
-
- {SMB_VFS_OP(skel_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_OPAQUE},
-
- {SMB_VFS_OP(skel_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_OPAQUE},
-
- /* EA operations. */
- {SMB_VFS_OP(skel_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_flistxattr), SMB_VFS_OP_FLISTXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_OPAQUE},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS init_module(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "skel_opaque", skel_op_tuples);
-}
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
deleted file mode 100644
index 448390e72f4..00000000000
--- a/examples/VFS/skel_transparent.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Skeleton VFS module. Implements passthrough operation of all VFS
- * calls to disk functions.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) Stefan (metze) Metzmacher, 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-/* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE
- SAMBA DEVELOPERS GUIDE!!!!!!
- */
-
-/* If you take this file as template for your module
- * please make sure that you remove all functions you didn't
- * want to implement!!
- *
- * This passthrough operations are useless in reall vfs modules!
- *
- * --metze
- */
-
-static int skel_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
-{
- return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
-}
-
-static void skel_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
-}
-
-static SMB_BIG_UINT skel_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path,
- BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-{
- return SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize,
- dfree, dsize);
-}
-
-static int skel_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- return SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, dq);
-}
-
-static int skel_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- return SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, dq);
-}
-
-static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- return SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data, labels);
-}
-
-static DIR *skel_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- return SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
-}
-
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
-{
- return SMB_VFS_NEXT_READDIR(handle, conn, dirp);
-}
-
-static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- return SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
-}
-
-static int skel_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return SMB_VFS_NEXT_RMDIR(handle, conn, path);
-}
-
-static int skel_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dir)
-{
- return SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir);
-}
-
-static int skel_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- return SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
-}
-
-static int skel_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
-}
-
-static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
-{
- return SMB_VFS_NEXT_READ(handle, fsp, fd, data, n);
-}
-
-static ssize_t skel_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset)
-{
- return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, offset);
-}
-
-static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
-{
- return SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n);
-}
-
-static ssize_t skel_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset)
-{
- return SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, offset);
-}
-
-static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
-{
- return SMB_VFS_NEXT_LSEEK(handle, fsp, filedes, offset, whence);
-}
-
-static int skel_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
-{
- return SMB_VFS_NEXT_RENAME(handle, conn, old, new);
-}
-
-static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return SMB_VFS_NEXT_FSYNC(handle, fsp, fd);
-}
-
-static int skel_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- return SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
-}
-
-static int skel_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
-{
- return SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf);
-}
-
-static int skel_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-{
- return SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf);
-}
-
-static int skel_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return SMB_VFS_NEXT_UNLINK(handle, conn, path);
-}
-
-static int skel_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- return SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
-}
-
-static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- return SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
-}
-
-static int skel_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-{
- return SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid);
-}
-
-static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
-{
- return SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid);
-}
-
-static int skel_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return SMB_VFS_NEXT_CHDIR(handle, conn, path);
-}
-
-static char *skel_getwd(vfs_handle_struct *handle, connection_struct *conn, char *buf)
-{
- return SMB_VFS_NEXT_GETWD(handle, conn, buf);
-}
-
-static int skel_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
-{
- return SMB_VFS_NEXT_UTIME(handle, conn, path, times);
-}
-
-static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T offset)
-{
- return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset);
-}
-
-static BOOL skel_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
-{
- return SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type);
-}
-
-static BOOL skel_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
-}
-
-static BOOL skel_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
-{
- return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
-}
-
-static int skel_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
-}
-
-static int skel_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
-{
- return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev);
-}
-
-static char *skel_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
-{
- return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
-}
-
-static size_t skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, struct security_descriptor_info **ppdesc)
-{
- return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, fd, security_info, ppdesc);
-}
-
-static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor_info **ppdesc)
-{
- return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc);
-}
-
-static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent, psd);
-}
-
-static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd);
-}
-
-static int skel_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
-{
- /* If the underlying VFS doesn't have ACL support... */
- if (!handle->vfs_next.ops.chmod_acl) {
- errno = ENOSYS;
- return -1;
- }
- return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode);
-}
-
-static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- /* If the underlying VFS doesn't have ACL support... */
- if (!handle->vfs_next.ops.fchmod_acl) {
- errno = ENOSYS;
- return -1;
- }
- return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
-}
-
-static int skel_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id, entry_p);
-}
-
-static int skel_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d, tag_type_p);
-}
-
-static int skel_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d, permset_p);
-}
-
-static void *skel_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d);
-}
-
-static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type);
-}
-
-static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, fd);
-}
-
-static int skel_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
-{
- return SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset);
-}
-
-static int skel_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm);
-}
-
-static char *skel_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
-{
- return SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen);
-}
-
-static SMB_ACL_T skel_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
-{
- return SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count);
-}
-
-static int skel_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
-{
- return SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry);
-}
-
-static int skel_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
-{
- return SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry, tagtype);
-}
-
-static int skel_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
-{
- return SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual);
-}
-
-static int skel_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
-{
- return SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset);
-}
-
-static int skel_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
-{
- return SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl);
-}
-
-static int skel_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, theacl);
-}
-
-static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
-{
- return SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, fd, theacl);
-}
-
-static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path);
-}
-
-static int skel_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm);
-}
-
-static int skel_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
-{
- return SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text);
-}
-
-static int skel_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
-{
- return SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl);
-}
-
-static int skel_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
-{
- return SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier, tagtype);
-}
-
-static ssize_t skel_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- return SMB_VFS_NEXT_GETXATTR(handle, conn, path, name, value, size);
-}
-
-static ssize_t skel_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t
-size)
-{
- return SMB_VFS_NEXT_LGETXATTR(handle, conn, path, name, value, size);
-}
-
-static ssize_t skel_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-{
- return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, name, value, size);
-}
-
-static ssize_t skel_listxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return SMB_VFS_NEXT_LISTXATTR(handle, conn, path, list, size);
-}
-
-static ssize_t skel_llistxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return SMB_VFS_NEXT_LLISTXATTR(handle, conn, path, list, size);
-}
-
-static ssize_t skel_flistxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
-{
- return SMB_VFS_NEXT_FLISTXATTR(handle, fsp, fd, list, size);
-}
-
-static int skel_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return SMB_VFS_NEXT_REMOVEXATTR(handle, conn, path, name);
-}
-
-static int skel_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, path, name);
-}
-
-static int skel_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-{
- return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, fd, name);
-}
-
-static int skel_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return SMB_VFS_NEXT_SETXATTR(handle, conn, path, name, value, size, flags);
-}
-
-static int skel_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return SMB_VFS_NEXT_LSETXATTR(handle, conn, path, name, value, size, flags);
-}
-
-static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-{
- return SMB_VFS_NEXT_FSETXATTR(handle, fsp, fd, name, value, size, flags);
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple skel_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(skel_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_TRANSPARENT},
-
- /* Directory operations */
-
- {SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {SMB_VFS_OP(skel_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_read), SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_write), SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lseek), SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fsync), SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_utime), SMB_VFS_OP_UTIME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lock), SMB_VFS_OP_LOCK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-
- /* NT File ACL operations */
-
- {SMB_VFS_OP(skel_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
-
- {SMB_VFS_OP(skel_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(skel_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
-
- /* EA operations. */
- {SMB_VFS_OP(skel_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_flistxattr), SMB_VFS_OP_FLISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS init_module(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "skel_transparent", skel_op_tuples);
-}
diff --git a/examples/auth/Makefile b/examples/auth/Makefile
deleted file mode 100644
index dac28fdd40a..00000000000
--- a/examples/auth/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-# Makefile for samba-pdb examples
-# Variables
-
-CC = gcc
-LIBTOOL = libtool
-
-SAMBA_SRC = ../../source
-SAMBA_INCL = ../../source/include
-UBIQX_SRC = ../../source/ubiqx
-SMBWR_SRC = ../../source/smbwrapper
-CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
-AUTH_OBJS = auth_skel.so
-
-# Default target
-
-default: $(AUTH_OBJS)
-
-# Pattern rules
-
-%.so: %.lo
- $(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS)
-
-%.lo: %.c
- $(LIBTOOL) $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
-
-# Misc targets
-
-clean:
- rm -rf .libs
- rm -f core *~ *% *.bak \
- $(AUTH_OBJS) $(AUTH_OBJS:.so=.o) $(AUTH_OBJS:.so=.lo)
diff --git a/examples/auth/auth_skel.c b/examples/auth/auth_skel.c
deleted file mode 100644
index bcc3bdd96a3..00000000000
--- a/examples/auth/auth_skel.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jelmer Vernooij 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-static NTSTATUS check_skel_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- if (!user_info || !auth_context) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
- /* Insert your authentication checking code here,
- * and return NT_STATUS_OK if authentication succeeds */
-
- /* For now, just refuse all connections */
- return NT_STATUS_LOGON_FAILURE;
-}
-
-/* module initialisation */
-NTSTATUS auth_init_skel(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_skel_security;
- (*auth_method)->name = "skel";
- return NT_STATUS_OK;
-}
-
-NTSTATUS init_module(void)
-{
- return smb_register_auth(AUTH_INTERFACE_VERSION, "skel", auth_init_skel);
-}
diff --git a/examples/genlogon/genlogon.pl b/examples/genlogon/genlogon.pl
deleted file mode 100644
index 8ebf3921411..00000000000
--- a/examples/genlogon/genlogon.pl
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/perl
-#
-# genlogon.pl
-#
-# Perl script to generate user logon scripts on the fly, when users
-# connect from a Windows client. This script should be called from smb.conf
-# with the %U, %G and %L parameters. I.e:
-#
-# root preexec = genlogon.pl %U %G %L
-#
-# The script generated will perform
-# the following:
-#
-# 1. Log the user connection to /var/log/samba/netlogon.log
-# 2. Set the PC's time to the Linux server time (which is maintained
-# daily to the National Institute of Standard's Atomic clock on the
-# internet.
-# 3. Connect the user's home drive to H: (H for Home).
-# 4. Connect common drives that everyone uses.
-# 5. Connect group-specific drives for certain user groups.
-# 6. Connect user-specific drives for certain users.
-# 7. Connect network printers.
-
-# Log client connection
-#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
-($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
-open LOG, ">>/var/log/samba/netlogon.log";
-print LOG "$mon/$mday/$year $hour:$min:$sec - User $ARGV[0] logged into $ARGV[1]\n";
-close LOG;
-
-# Start generating logon script
-open LOGON, ">/shared/netlogon/$ARGV[0].bat";
-print LOGON "\@ECHO OFF\r\n";
-
-# Connect shares just use by Software Development group
-if ($ARGV[1] eq "SOFTDEV" || $ARGV[0] eq "softdev")
-{
- print LOGON "NET USE M: \\\\$ARGV[2]\\SOURCE\r\n";
-}
-
-# Connect shares just use by Technical Support staff
-if ($ARGV[1] eq "SUPPORT" || $ARGV[0] eq "support")
-{
- print LOGON "NET USE S: \\\\$ARGV[2]\\SUPPORT\r\n";
-}
-
-# Connect shares just used by Administration staff
-If ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin")
-{
- print LOGON "NET USE L: \\\\$ARGV[2]\\ADMIN\r\n";
- print LOGON "NET USE K: \\\\$ARGV[2]\\MKTING\r\n";
-}
-
-# Now connect Printers. We handle just two or three users a little
-# differently, because they are the exceptions that have desktop
-# printers on LPT1: - all other user's go to the LaserJet on the
-# server.
-if ($ARGV[0] eq 'jim'
- || $ARGV[0] eq 'yvonne')
-{
- print LOGON "NET UsE LPT2: \\\\$ARGV[2]\\LJET3\r\n";
- print LOGON "NET USE LPT3: \\\\$ARGV[2]\\FAXQ\r\n";
-}
-else
-{
- print LOGON "NET USE LPT1: \\\\$ARGV[2]\\LJET3\r\n";
- print LOGON "NET USE LPT3: \\\\$ARGV[2]\\FAXQ\r\n";
-}
-
-# All done! Close the output file.
-close LOGON;
diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile
index fcd5ef29003..8c1def8a162 100644
--- a/examples/libsmbclient/Makefile
+++ b/examples/libsmbclient/Makefile
@@ -2,19 +2,16 @@
CC = gcc
SAMBA_INCL = ../../source/include
-EXTLIB_INCL = -I/usr/include/gtk-1.2 \
- -I/usr/include/glib-1.2 \
- -I/usr/lib/glib/include
-CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL)
+CFLAGS = -I$(SAMBA_INCL)
LDFLAGS = -L/usr/lib
-all: testsmbc tree testacl testbrowse
+all: testsmbc tree
testsmbc: testsmbc.o
@echo Linking testsmbc
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient -L/usr/local/lib
+ @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient
testsmbc-static: testsmbc.o
@echo Linking testsmbc
@@ -24,13 +21,5 @@ tree: tree.o
@echo Linking tree
@$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ `gtk-config --libs` -lsmbclient $<
-testacl: testacl.o
- @echo Linking testacl
- @$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ `gtk-config --libs` -lsmbclient -lpopt $<
-
-testbrowse: testbrowse.o
- @echo Linking testbrowse
- @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -lsmbclient -lpopt $<
-
clean:
@rm -f *.o *~
diff --git a/examples/libsmbclient/testacl.c b/examples/libsmbclient/testacl.c
deleted file mode 100644
index 47668f7c9c4..00000000000
--- a/examples/libsmbclient/testacl.c
+++ /dev/null
@@ -1,280 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <popt.h>
-#include "libsmbclient.h"
-
-enum acl_mode
-{
- SMB_ACL_GET,
- SMB_ACL_SET,
- SMB_ACL_DELETE,
- SMB_ACL_MODIFY,
- SMB_ACL_ADD,
- SMB_ACL_CHOWN,
- SMB_ACL_CHGRP
-};
-
-static void
-get_auth_data_fn(const char * pServer,
- const char * pShare,
- char * pWorkgroup,
- int maxLenWorkgroup,
- char * pUsername,
- int maxLenUsername,
- char * pPassword,
- int maxLenPassword)
-
-{
- char temp[128];
-
- fprintf(stdout, "Workgroup: [%s] ", pWorkgroup);
- fgets(temp, sizeof(temp), stdin);
-
- if (temp[strlen(temp) - 1] == '\n') /* A new line? */
- {
- temp[strlen(temp) - 1] = '\0';
- }
-
- if (temp[0] != '\0')
- {
- strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
- }
-
- fprintf(stdout, "Username: [%s] ", pUsername);
- fgets(temp, sizeof(temp), stdin);
-
- if (temp[strlen(temp) - 1] == '\n') /* A new line? */
- {
- temp[strlen(temp) - 1] = '\0';
- }
-
- if (temp[0] != '\0')
- {
- strncpy(pUsername, temp, maxLenUsername - 1);
- }
-
- fprintf(stdout, "Password: ");
- fgets(temp, sizeof(temp), stdin);
-
- if (temp[strlen(temp) - 1] == '\n') /* A new line? */
- {
- temp[strlen(temp) - 1] = '\0';
- }
-
- if (temp[0] != '\0')
- {
- strncpy(pPassword, temp, maxLenPassword - 1);
- }
-}
-
-
-int main(int argc, const char *argv[])
-{
- int opt;
- int flags;
- int debug = 0;
- int numeric = 0;
- enum acl_mode mode = SMB_ACL_GET;
- static char *the_acl = NULL;
- int ret;
- char *p;
- char *debugstr;
- char path[1024];
- char value[1024];
- poptContext pc;
- struct poptOption long_options[] =
- {
- POPT_AUTOHELP
- {
- "numeric", 'n', POPT_ARG_NONE, &numeric,
- 1, "Don't resolve sids or masks to names"
- },
- {
- "debug", 'd', POPT_ARG_INT, &debug,
- 0, "Set debug level (0-100)"
- },
- {
- "delete", 'D', POPT_ARG_STRING, NULL,
- 'D', "Delete an acl", "ACL"
- },
- {
- "modify", 'M', POPT_ARG_STRING, NULL,
- 'M', "Modify an acl", "ACL"
- },
- {
- "add", 'a', POPT_ARG_STRING, NULL,
- 'a', "Add an acl", "ACL"
- },
- {
- "set", 'S', POPT_ARG_STRING, NULL,
- 'S', "Set acls", "ACLS"
- },
- {
- "chown", 'C', POPT_ARG_STRING, NULL,
- 'C', "Change ownership of a file", "USERNAME"
- },
- {
- "chgrp", 'G', POPT_ARG_STRING, NULL,
- 'G', "Change group ownership of a file", "GROUPNAME"
- },
- {
- "get", 'g', POPT_ARG_STRING, NULL,
- 'g', "Get a specific acl attribute", "ACL"
- },
- {
- NULL
- }
- };
-
- setbuf(stdout, NULL);
-
- pc = poptGetContext("smbcacls", argc, argv, long_options, 0);
-
- poptSetOtherOptionHelp(pc, "smb://server1/share1/filename");
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'S':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_SET;
- break;
-
- case 'D':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_DELETE;
- break;
-
- case 'M':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_MODIFY;
- break;
-
- case 'a':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_ADD;
- break;
-
- case 'g':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_GET;
- break;
-
- case 'C':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_CHOWN;
- break;
-
- case 'G':
- the_acl = strdup(poptGetOptArg(pc));
- mode = SMB_ACL_CHGRP;
- break;
- }
- }
-
- /* Make connection to server */
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- return 1;
- }
-
- strcpy(path, poptGetArg(pc));
-
- if (smbc_init(get_auth_data_fn, debug) != 0)
- {
- printf("Could not initialize smbc_ library\n");
- return 1;
- }
-
- /* Perform requested action */
-
- switch(mode)
- {
- case SMB_ACL_GET:
- if (the_acl == NULL)
- {
- if (numeric)
- {
- the_acl = "system.nt_sec_desc.*";
- }
- else
- {
- the_acl = "system.nt_sec_desc.*+";
- }
- }
- ret = smbc_getxattr(path, the_acl, value, sizeof(value));
- if (ret < 0)
- {
- printf("Could not get attributes for [%s] %d: %s\n",
- path, errno, strerror(errno));
- return 1;
- }
-
- printf("Attributes for [%s] are:\n%s\n", path, value);
- break;
-
- case SMB_ACL_ADD:
- flags = SMBC_XATTR_FLAG_CREATE;
- debugstr = "add attributes";
- goto do_set;
-
- case SMB_ACL_MODIFY:
- flags = SMBC_XATTR_FLAG_REPLACE;
- debugstr = "modify attributes";
- goto do_set;
-
- case SMB_ACL_CHOWN:
- snprintf(value, sizeof(value),
- "system.nt_sec_desc.owner%s:%s",
- numeric ? "" : "+", the_acl);
- the_acl = value;
- debugstr = "chown owner";
- goto do_set;
-
- case SMB_ACL_CHGRP:
- snprintf(value, sizeof(value),
- "system.nt_sec_desc.group%s:%s",
- numeric ? "" : "+", the_acl);
- the_acl = value;
- debugstr = "change group";
- goto do_set;
-
- case SMB_ACL_SET:
- flags = 0;
- debugstr = "set attributes";
-
- do_set:
- if ((p = strchr(the_acl, ':')) == NULL)
- {
- printf("Missing value. ACL must be name:value pair\n");
- return 1;
- }
-
- *p++ = '\0';
-
- ret = smbc_setxattr(path, the_acl, p, strlen(p), flags);
- if (ret < 0)
- {
- printf("Could not %s for [%s] %d: %s\n",
- debugstr, path, errno, strerror(errno));
- return 1;
- }
- break;
-
- case SMB_ACL_DELETE:
- ret = smbc_removexattr(path, the_acl);
- if (ret < 0)
- {
- printf("Could not remove attribute %s for [%s] %d:%s\n",
- the_acl, path, errno, strerror(errno));
- return 1;
- }
- break;
-
- default:
- printf("operation not yet implemented\n");
- break;
- }
-
- return 0;
-}
diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c
deleted file mode 100644
index d2472230a20..00000000000
--- a/examples/libsmbclient/testbrowse.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB client library test program for browsing with different master browsers
- Copyright (C) Derrell Lipman 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <libsmbclient.h>
-
-static void
-auth_fn(const char * pServer,
- const char * pShare,
- char * pWorkgroup,
- int workgroup_len,
- char * pUsername,
- int username_len,
- char * pPassword,
- int password_len)
-
-{
- strncpy(pUsername, "anonymous", username_len); /* doesn't matter what */
- strncpy(pPassword, "password", password_len); /* ditto */
-}
-
-
-int
-main(int argc, char * argv[])
-{
- int debug = 4;
- int opt;
- char * p;
- char buf[1024];
- int dir;
- struct smbc_dirent * dirent;
- char ** ppUrl;
- char * urlList[] =
- {
- "smb://",
- "smb://?mb=.any",
- "smb://?mb=.all",
- "smb://?mb=xx", /* this one is suupposed to fail */
- NULL
- };
-
- if (smbc_init(auth_fn, debug) != 0)
- {
- printf("Could not initialize smbc_ library\n");
- return 1;
- }
-
- for (ppUrl = urlList; *ppUrl != NULL; ppUrl++)
- {
- printf("Opening (%s)...\n", *ppUrl);
-
- if ((dir = smbc_opendir(*ppUrl)) < 0)
- {
- printf("Could not open [%s] (%d:%s)\n",
- *ppUrl, errno, strerror(errno));
- continue;
- }
-
- while ((dirent = smbc_readdir(dir)) != NULL)
- {
- printf("%s\n", dirent->name);
- }
-
- smbc_closedir(dir);
- }
-
- exit(0);
-}
-
diff --git a/examples/libsmbclient/testsmbc.c b/examples/libsmbclient/testsmbc.c
index 888a9c0d4f9..7aae9d85616 100644
--- a/examples/libsmbclient/testsmbc.c
+++ b/examples/libsmbclient/testsmbc.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB client library test program
Copyright (C) Andrew Tridgell 1998
Copyright (C) Richard Sharpe 2000
@@ -94,10 +95,74 @@ int main(int argc, char *argv[])
if (argc > 1) {
- if ((dh1 = smbc_opendir(argv[1]))<1) {
+ /* Try to list the print jobs ... */
- fprintf(stderr, "Could not open directory: %s: %s\n",
- argv[1], strerror(errno));
+ if (smbc_list_print_jobs("smb://samba/pclp", print_list_fn) < 0) {
+
+ fprintf(stderr, "Could not list print jobs: %s, %d\n", strerror(errno), errno);
+ exit(1);
+
+ }
+
+ /* Try to delete the last job listed */
+
+ if (global_id > 0) {
+
+ fprintf(stdout, "Trying to delete print job %u\n", global_id);
+
+ if (smbc_unlink_print_job("smb://samba/pclp", global_id) < 0) {
+
+ fprintf(stderr, "Failed to unlink job id %u, %s, %u\n", global_id,
+ strerror(errno), errno);
+
+ exit(1);
+
+ }
+
+ }
+
+ /* Try to print a file ... */
+
+ if (smbc_print_file("smb://samba/public/testfile2.txt", "smb://samba/pclp") < 0) {
+
+ fprintf(stderr, "Failed to print job: %s %u\n", strerror(errno), errno);
+ exit(1);
+
+ }
+
+ /* Try to delete argv[1] as a file ... */
+
+ if (smbc_unlink(argv[1]) < 0) {
+
+ fprintf(stderr, "Could not unlink: %s, %s, %d\n",
+ argv[1], strerror(errno), errno);
+
+ exit(0);
+
+ }
+
+ if ((dh1 = smbc_opendir("smb://"))<1) {
+
+ fprintf(stderr, "Could not open directory: smb://: %s\n",
+ strerror(errno));
+
+ exit(1);
+
+ }
+
+ if ((dh2 = smbc_opendir("smb://sambanet")) < 0) {
+
+ fprintf(stderr, "Could not open directory: smb://sambanet: %s\n",
+ strerror(errno));
+
+ exit(1);
+
+ }
+
+ if ((dh3 = smbc_opendir("smb://samba")) < 0) {
+
+ fprintf(stderr, "Could not open directory: smb://samba: %s\n",
+ strerror(errno));
exit(1);
@@ -138,6 +203,62 @@ int main(int argc, char *argv[])
dirp = (char *)dirbuf;
+ if ((dirc = smbc_getdents(dh2, (struct smbc_dirent *)dirp,
+ sizeof(dirbuf))) < 0) {
+
+ fprintf(stderr, "Problems getting directory entries: %s\n",
+ strerror(errno));
+
+ exit(1);
+
+ }
+
+ /* Now, process the list of names ... */
+
+ fprintf(stdout, "\nDirectory listing, size = %u\n", dirc);
+
+ while (dirc > 0) {
+
+ dsize = ((struct smbc_dirent *)dirp)->dirlen;
+ fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n",
+ ((struct smbc_dirent *)dirp)->smbc_type,
+ ((struct smbc_dirent *)dirp)->name,
+ ((struct smbc_dirent *)dirp)->comment);
+
+ dirp += dsize;
+ (char *)dirc -= dsize;
+
+ }
+
+ dirp = (char *)dirbuf;
+
+ if ((dirc = smbc_getdents(dh3, (struct smbc_dirent *)dirp,
+ sizeof(dirbuf))) < 0) {
+
+ fprintf(stderr, "Problems getting directory entries: %s\n",
+ strerror(errno));
+
+ exit(1);
+
+ }
+
+ /* Now, process the list of names ... */
+
+ fprintf(stdout, "Directory listing, size = %u\n", dirc);
+
+ while (dirc > 0) {
+
+ dsize = ((struct smbc_dirent *)dirp)->dirlen;
+ fprintf(stdout, "\nDir Ent, Type: %u, Name: %s, Comment: %s\n",
+ ((struct smbc_dirent *)dirp)->smbc_type,
+ ((struct smbc_dirent *)dirp)->name,
+ ((struct smbc_dirent *)dirp)->comment);
+
+ (char *)dirp += dsize;
+ (char *)dirc -= dsize;
+
+ }
+
exit(1);
}
diff --git a/examples/libsmbclient/tree.c b/examples/libsmbclient/tree.c
index f50b3670cff..da60236e601 100644
--- a/examples/libsmbclient/tree.c
+++ b/examples/libsmbclient/tree.c
@@ -51,8 +51,7 @@ void error_message(gchar *message) {
/* Ensure that the dialog box is destroyed when the user clicks ok. */
gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy),
- GTK_OBJECT(dialog));
+ GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
okay_button);
@@ -706,9 +705,9 @@ int main( int argc,
/* Now, build the top level display ... */
- if ((dh = smbc_opendir("smb://")) < 0) {
+ if ((dh = smbc_opendir("smb:///")) < 0) {
- fprintf(stderr, "Could not list workgroups: smb://: %s\n",
+ fprintf(stderr, "Could not list default workgroup: smb:///: %s\n",
strerror(errno));
exit(1);
@@ -745,6 +744,8 @@ int main( int argc,
/* Now, get the items in smb:/// and add them to the tree */
+ dirp = (struct smbc_dirent *)dirbuf;
+
while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
sizeof(dirbuf))) != 0) {
@@ -757,8 +758,6 @@ int main( int argc,
}
- dirp = (struct smbc_dirent *)dirbuf;
-
fprintf(stdout, "Dir len: %u\n", err);
while (err > 0) { /* Extract each entry and make a sub-tree */
diff --git a/examples/misc/modify_samba_config.pl b/examples/misc/modify_samba_config.pl
index ad958625d66..eb997f9b0c8 100755
--- a/examples/misc/modify_samba_config.pl
+++ b/examples/misc/modify_samba_config.pl
@@ -66,7 +66,7 @@ while (<CONFIGFILE>) {
## check for a param = value
if ($_ =~ /=/) {
- ($param, $value) = split (/=/, $_,2);
+ ($param, $value) = split (/=/, $_);
$param =~ s/./\l$&/g;
$param =~ s/\s+//g;
$value =~ s/^\s+//;
diff --git a/examples/misc/swat.pl b/examples/misc/swat.pl
index f6414b63497..a6f7d7cde80 100644
--- a/examples/misc/swat.pl
+++ b/examples/misc/swat.pl
@@ -37,7 +37,7 @@ $lastone = "nothing";
if (@ARGV[0]) {
$filename = @ARGV[0];
} else {
- $filename = "/usr3/samba20/samba/source/param/loadparm.c";
+ $filename = "source/param/loadparm.c";
}
open (INFILE,$filename) || die "unable to open $filename\n";
diff --git a/examples/nss/nss_winbind.c b/examples/nss/nss_winbind.c
deleted file mode 100644
index 968cc7adddc..00000000000
--- a/examples/nss/nss_winbind.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- nss sample code for extended winbindd functionality
-
- Copyright (C) Andrew Tridgell (tridge@samba.org)
-
- you are free to use this code in any way you see fit, including
- without restriction, using this code in your own products. You do
- not need to give any attribution.
-*/
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <nss.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "nss_winbind.h"
-
-/*
- find a function in the nss library
-*/
-static void *find_fn(struct nss_state *nss, const char *name)
-{
- void *res;
- char *s = NULL;
-
- asprintf(&s, "_nss_%s_%s", nss->nss_name, name);
- if (!s) {
- errno = ENOMEM;
- return NULL;
- }
- res = dlsym(nss->dl_handle, s);
- free(s);
- if (!res) {
- errno = ENOENT;
- return NULL;
- }
- return res;
-}
-
-/*
- establish a link to the nss library
- Return 0 on success and -1 on error
-*/
-int nss_open(struct nss_state *nss, const char *nss_path)
-{
- char *p;
- p = strrchr(nss_path, '_');
- if (!p) {
- errno = EINVAL;
- return -1;
- }
-
- nss->nss_name = strdup(p+1);
- p = strchr(nss->nss_name, '.');
- if (p) *p = 0;
-
- nss->dl_handle = dlopen(nss_path, RTLD_LAZY);
- if (!nss->dl_handle) {
- free(nss->nss_name);
- return -1;
- }
-
- return 0;
-}
-
-/*
- close and cleanup a nss state
-*/
-void nss_close(struct nss_state *nss)
-{
- free(nss->nss_name);
- dlclose(nss->dl_handle);
-}
-
-/*
- make a getpwnam call.
- Return 0 on success and -1 on error
-*/
-int nss_getpwent(struct nss_state *nss, struct passwd *pwd)
-{
- enum nss_status (*_nss_getpwent_r)(struct passwd *, char *,
- size_t , int *);
- enum nss_status status;
- int nss_errno = 0;
-
- _nss_getpwent_r = find_fn(nss, "getpwent_r");
-
- if (!_nss_getpwent_r) {
- return -1;
- }
-
- status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf),
- &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- return 0;
-}
-
-/*
- make a setpwent call.
- Return 0 on success and -1 on error
-*/
-int nss_setpwent(struct nss_state *nss)
-{
- enum nss_status (*_nss_setpwent)(void) = find_fn(nss, "setpwent");
- enum nss_status status;
- if (!_nss_setpwent) {
- return -1;
- }
- status = _nss_setpwent();
- if (status != NSS_STATUS_SUCCESS) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-/*
- make a endpwent call.
- Return 0 on success and -1 on error
-*/
-int nss_endpwent(struct nss_state *nss)
-{
- enum nss_status (*_nss_endpwent)(void) = find_fn(nss, "endpwent");
- enum nss_status status;
- if (!_nss_endpwent) {
- return -1;
- }
- status = _nss_endpwent();
- if (status != NSS_STATUS_SUCCESS) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-
-/*
- convert a name to a SID
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_nametosid(struct nss_state *nss, const char *name, char **sid)
-{
- enum nss_status (*_nss_nametosid)(const char *, char **, char *,
- size_t, int *);
- enum nss_status status;
- int nss_errno = 0;
- char buf[200];
-
- _nss_nametosid = find_fn(nss, "nametosid");
-
- if (!_nss_nametosid) {
- return -1;
- }
-
- status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- *sid = strdup(*sid);
-
- return 0;
-}
-
-/*
- convert a SID to a name
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_sidtoname(struct nss_state *nss, const char *sid, char **name)
-{
- enum nss_status (*_nss_sidtoname)(const char *, char **, char *,
- size_t, int *);
- enum nss_status status;
- int nss_errno = 0;
- char buf[200];
-
- _nss_sidtoname = find_fn(nss, "sidtoname");
-
- if (!_nss_sidtoname) {
- return -1;
- }
-
- status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- *name = strdup(*name);
-
- return 0;
-}
-
-/*
- return a list of group SIDs for a user SID
- the returned list is NULL terminated
- Return 0 on success and -1 on error
-*/
-int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids)
-{
- enum nss_status (*_nss_getusersids)(const char *, char **, int *,
- char *, size_t, int *);
- enum nss_status status;
- int nss_errno = 0;
- char *s;
- int i, num_groups = 0;
- unsigned bufsize = 10;
- char *buf;
-
- _nss_getusersids = find_fn(nss, "getusersids");
-
- if (!_nss_getusersids) {
- return -1;
- }
-
-again:
- buf = malloc(bufsize);
- if (!buf) {
- errno = ENOMEM;
- return -1;
- }
-
- status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize,
- &nss_errno);
-
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- free(buf);
- return -1;
- }
-
- if (status == NSS_STATUS_TRYAGAIN) {
- bufsize *= 2;
- free(buf);
- goto again;
- }
-
- if (status != NSS_STATUS_SUCCESS) {
- free(buf);
- errno = nss_errno;
- return -1;
- }
-
- if (num_groups == 0) {
- free(buf);
- return 0;
- }
-
- *sids = (char **)malloc(sizeof(char *) * (num_groups+1));
- if (! *sids) {
- errno = ENOMEM;
- free(buf);
- return -1;
- }
-
- for (i=0;i<num_groups;i++) {
- (*sids)[i] = strdup(s);
- s += strlen(s) + 1;
- }
- (*sids)[i] = NULL;
-
- free(buf);
-
- return 0;
-}
-
-/*
- convert a sid to a uid
- Return 0 on success and -1 on error
-*/
-int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid)
-{
- enum nss_status (*_nss_sidtouid)(const char*, uid_t *, int*);
-
- enum nss_status status;
- int nss_errno = 0;
-
- _nss_sidtouid = find_fn(nss, "sidtouid");
-
- if (!_nss_sidtouid) {
- return -1;
- }
-
- status = _nss_sidtouid(sid, uid, &nss_errno);
-
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
-
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- return 0;
-}
-
-/*
- convert a sid to a gid
- Return 0 on success and -1 on error
-*/
-int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid)
-{
- enum nss_status (*_nss_sidtogid)(const char*, gid_t *, int*);
-
- enum nss_status status;
- int nss_errno = 0;
-
- _nss_sidtogid = find_fn(nss, "sidtogid");
-
- if (!_nss_sidtogid) {
- return -1;
- }
-
- status = _nss_sidtogid(sid, gid, &nss_errno);
-
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
-
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- return 0;
-}
-
-/*
- convert a uid to a sid
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid)
-{
- enum nss_status (*_nss_uidtosid)(uid_t, char **, char *,
- size_t, int *);
- enum nss_status status;
- int nss_errno = 0;
- char buf[200];
-
- _nss_uidtosid = find_fn(nss, "uidtosid");
-
- if (!_nss_uidtosid) {
- return -1;
- }
-
- status = _nss_uidtosid(uid, sid, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- *sid = strdup(*sid);
-
- return 0;
-}
-
-/*
- convert a gid to a sid
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid)
-{
- enum nss_status (*_nss_gidtosid)(gid_t, char **, char *,
- size_t, int *);
- enum nss_status status;
- int nss_errno = 0;
- char buf[200];
-
- _nss_gidtosid = find_fn(nss, "gidtosid");
-
- if (!_nss_gidtosid) {
- return -1;
- }
-
- status = _nss_gidtosid(gid, sid, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- errno = ENOENT;
- return -1;
- }
- if (status != NSS_STATUS_SUCCESS) {
- errno = nss_errno;
- return -1;
- }
-
- *sid = strdup(*sid);
-
- return 0;
-}
-
diff --git a/examples/nss/nss_winbind.h b/examples/nss/nss_winbind.h
deleted file mode 100644
index 5a124a5a8ec..00000000000
--- a/examples/nss/nss_winbind.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- nss sample code for extended winbindd functionality
-
- Copyright (C) Andrew Tridgell (tridge@samba.org)
- Copyright (C) Volker Lendecke (vl@samba.org)
-
- you are free to use this code in any way you see fit, including
- without restriction, using this code in your own products. You do
- not need to give any attribution.
-*/
-
-#define _GNU_SOURCE
-
-#include <pwd.h>
-#include <grp.h>
-
-struct nss_state {
- void *dl_handle;
- char *nss_name;
- char pwnam_buf[512];
-};
-
-/*
- establish a link to the nss library
- Return 0 on success and -1 on error
-*/
-int nss_open(struct nss_state *nss, const char *nss_path);
-
-/*
- close and cleanup a nss state
-*/
-void nss_close(struct nss_state *nss);
-
-/*
- make a getpwnam call.
- Return 0 on success and -1 on error
-*/
-int nss_getpwent(struct nss_state *nss, struct passwd *pwd);
-
-/*
- make a setpwent call.
- Return 0 on success and -1 on error
-*/
-int nss_setpwent(struct nss_state *nss);
-
-/*
- make a endpwent call.
- Return 0 on success and -1 on error
-*/
-int nss_endpwent(struct nss_state *nss);
-
-/*
- convert a name to a SID
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_nametosid(struct nss_state *nss, const char *name, char **sid);
-
-/*
- convert a SID to a name
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_sidtoname(struct nss_state *nss, const char *sid, char **name);
-
-/*
- return a list of group SIDs for a user SID
- the returned list is NULL terminated
- Return 0 on success and -1 on error
-*/
-int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids);
-
-/*
- convert a sid to a uid
- Return 0 on success and -1 on error
-*/
-int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid);
-
-/*
- convert a sid to a gid
- Return 0 on success and -1 on error
-*/
-int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid);
-
-/*
- convert a uid to a sid
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid);
-
-/*
- convert a gid to a sid
- caller frees
- Return 0 on success and -1 on error
-*/
-int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid);
diff --git a/examples/nss/wbtest.c b/examples/nss/wbtest.c
deleted file mode 100644
index 14265bd54c1..00000000000
--- a/examples/nss/wbtest.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- nss sample code for extended winbindd functionality
-
- Copyright (C) Andrew Tridgell (tridge@samba.org)
-
- you are free to use this code in any way you see fit, including
- without restriction, using this code in your own products. You do
- not need to give any attribution.
-*/
-
-/*
- compile like this:
-
- cc -o wbtest wbtest.c nss_winbind.c -ldl
-
- and run like this:
-
- ./wbtest /lib/libnss_winbind.so
-*/
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <nss.h>
-#include <dlfcn.h>
-#include <pwd.h>
-#include <grp.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "nss_winbind.h"
-
-static int nss_test_users(struct nss_state *nss)
-{
- struct passwd pwd;
-
- if (nss_setpwent(nss) != 0) {
- perror("setpwent");
- return -1;
- }
-
- /* loop over all users */
- while ((nss_getpwent(nss, &pwd) == 0)) {
- char *sid, **group_sids, *name2;
- int i;
-
- printf("User %s\n", pwd.pw_name);
- if (nss_nametosid(nss, pwd.pw_name, &sid) != 0) {
- perror("nametosid");
- return -1;
- }
- printf("\tSID %s\n", sid);
-
- if (nss_sidtoname(nss, sid, &name2) != 0) {
- perror("sidtoname");
- return -1;
- }
- printf("\tSID->name %s\n", name2);
-
- if (nss_getusersids(nss, sid, &group_sids) != 0) {
- perror("getusersids");
- return -1;
- }
-
- printf("\tGroups:\n");
- for (i=0; group_sids[i]; i++) {
- printf("\t\t%s\n", group_sids[i]);
- free(group_sids[i]);
- }
-
- free(sid);
- free(name2);
- free(group_sids);
- }
-
-
- if (nss_endpwent(nss) != 0) {
- perror("endpwent");
- return -1;
- }
-
- return 0;
-}
-
-
-/*
- main program. It lists all users, listing user SIDs for each user
- */
-int main(int argc, char *argv[])
-{
- struct nss_state nss;
- const char *so_path = "/lib/libnss_winbind.so";
- int ret;
-
- if (argc > 1) {
- so_path = argv[1];
- }
-
- if (nss_open(&nss, so_path) != 0) {
- perror("nss_open");
- exit(1);
- }
-
- ret = nss_test_users(&nss);
-
- nss_close(&nss);
-
- return ret;
-}
diff --git a/examples/ntlogon/README b/examples/ntlogon/README
deleted file mode 100644
index e33c565d717..00000000000
--- a/examples/ntlogon/README
+++ /dev/null
@@ -1,160 +0,0 @@
-ntlogon.py v0.8b Copyright 2002 by Timothy (rhacer) Grant
-This programme is released under the terms of the GNU Public License
-This programme has NO WARRANTY of any kind, use at your own risk.
-
-===================
-CHANGES SINCE v0.7b
-===================
-included patch that made machine name %m a macro substitution value.
-Thanks to: Nick Lopez <kimo_sabe@atdot.org>
-
-==================
-CHANGES SINCE v0.6
-==================
-PLEASE NOT THAT I AM CONSIDERING THIS A BETA UNTIL I GET SOME FEEDBACK
-FROM USERS ON WHETHER THE MACRO FEATURE WORKS FOR THEM.
-
-added the ability to define substitution macros: see the useage section
-
-removed the large docstring from the file and moved the information to
-the USEAGE section of this file
-
-cleaned up the code and made more flexible
-
-improved the code comments
-
-==================
-CHANGES SINCE v0.5
-==================
-added a -v --version switch
-
-added a --pause switch which will put a pause statement between each
-non-blank line of the script.
-
-===============
-A PERSONAL NOTE
-===============
-When I originally posted v0.5 on Freshmeat, I really expected *some*
-feedback. To date this little script has been downloaded over 700 times, but
-absolutely nobody has sent me an e-mail to tell me if it is useful, or if
-it is absolutely the stupidest waste of bandwidth they have ever seen.
-I'd really love to know if even one person other than me and the other techs
-here at Avalon have found it useful.
-
-Thanks.
- rhacer (rhacer@craigelachie.org)
-
-September 27, 2000
-Thanks to those that did respond to my plea! I'd still love to hear from
-any other users!
-
-============
-INTRODUCTION
-============
-As my experience with Linux and Samba increased, I had no trouble whipping up
-a custom Perl, Python or Bash script to create Samba Logon Scripts, but I
-noticed that I changed things from place to place, and that my users had *no*
-chance of ever figuring out how to modify those scripts themselves.
-
-In an attempt to create a company wide standard that both my co-workers and my
-customers could *easily* modify I hit upon the scheme I used here.
-
-I settled on an INI file feel, because most who have experience with Win boxes
-have some concept of INI files.
-
-============
-INSTALLATION
-============
-The distribution archive contains three files:
-
-README This file
-ntlogon.py The actual Python script (place in /usr/local/samba/bin)
-ntlogon.conf A sample configuration file (place in /etc)
-
-This script was created using Python v1.5.2, and I believe it uses only
-standard libraries.
-
-Your smb.conf file needs to contain a netlogon section similar to the
-following (These settings *are not* normal on a RH box. These settings
-are all based on the excellent book that I learned Samba from: Samba
-Integrating Unix and Windows by John D. Blair. It is somewhat out of
-date now, but that's the history of the strange file locations):
-
-[netlogon]
- path = /usr/local/samba/netlogon
- writeable = no
- guest ok = no
- root preexec = /usr/local/samba/bin/ntlogon --user=%U --os=%m
- root postexec = rm /usr/local/samba/netlogon/%U.bat
-
-======
-USEAGE
-======
-PLEASE SEE NTLOGON.CONF FOR A DETAILED CONFIGURATION EXAMPLE
-
-This programme will build a Windows NT logon script for users connecting
-to a Samba server. Samba macros that are curently understood:
-
- %U user name
- %G group name
- %a machine architecture
- %m machine netbios name
-
-This programme reads a configuration that looks strikingly similar to both
-the Samba configuration file, and a DOS "boot menu" AUTOEXEC.BAT file.
-
-The default file name is /etc/ntlogon.conf (though I really think it ought
-to be called ntlogon.batch!) You may change the filename by using the -f
-or --templatefile startup option.
-
-The default netlogon directory is /usr/local/samba/netlogon though this
-can be changed with the -d or --dir startup option.
-
-The default batch file name generated is username.bat if no username is
-specified the default value is logon.bat (e.g., if --user=fred is specified
-on the command line then the logon script generated will be stored in
-fred.bat)
-
-Use the --debug option to print the logon script to screen instead of the
-output file
-
-Use the --pause option to place a pause statement between each line of the
-script to assist in debugging a logon script.
-
-The file is divided into sections that have headers in square brackets
-
-[Global]
-[User-username]
-[Group-groupname]
-[OS-osname]
-
-The file may also contain user defined substitution macros. They are
-defined by placing the macro name on the left side of an equal sign,
-and the substitution text on the right side of the equal sign. They
-are also case sensitive:
-
-MAINDRIVE = G:
-USERDRIVE = U:
-SERVERNAME = myservername
-
-They are referenced by prepending a "%" sign to the variable name:
-
-NET USE %MAINDRIVE \\\\servername\\mainshare /YES
-NET USE %USERDRIVE \\\\%SERVERNAME\\usershare /YES
-
-==============
-SPECIAL THANKS
-==============
-Nick Lopez <kimo_sabe@atdot.org> for the net bios name patch.
-
-===================
-CONTACT INFORMATION
-===================
-Author : Timothy (rhacer) Grant
-
-I can be reached at tjg@craigelachie.org
-ntlogon website www.craigelachie.org/rhacer/ntlogon
-
-Please feel free to contact me with any suggestions, improvements, bugs you
-might find.
-
diff --git a/examples/ntlogon/ntlogon.conf b/examples/ntlogon/ntlogon.conf
deleted file mode 100644
index e1573a6118f..00000000000
--- a/examples/ntlogon/ntlogon.conf
+++ /dev/null
@@ -1,44 +0,0 @@
-# Everything in the Global section applies to all users logging on to the
-# network
-[Global]
-
-#Some substitution macro definitions
-MAINDRIVE = G:
-USERDRIVE = U:
-SERVERNAME = myservername
-
-@ECHO "Welcome to our network!!!"
-NET TIME \\servername /SET /YES
-NET USE %MAINDRIVE \\%SERVERNAME\globalshare /YES
-
-# Map the private user area in the global section so we don't have to
-# create individual user entries for each user!
-NET USE %USERDRIVE \\servername\%U /YES
-
-# Group entries, User entries and OS entries each start with the
-# keyword followed by a dash followed by--appropriately enough the Group
-# name, the User name, or the OS name.
-[Group-admin]
-@ECHO "Welcome administrators!"
-NET USE G: \\servername\adminshare1 /YES
-NET USE I: \\servername\adminshare2 /YES
-
-[Group-peons]
-@ECHO "Be grateful we let you use computers!"
-NET USE G: \\servername\peonshare1 /YES
-
-[Group-hackers]
-@ECHO "What can I do for you today great one?"
-NET USE G: \\servername\hackershare1 /YES
-NET USE I: \\servername\adminshare2 /YES
-
-[User-fred]
-@ECHO "Hello there Fred!"
-NET USE F: \\servername\fredsspecialshare /YES
-
-[OS-WfWg]
-@ECHO "Time to upgrade isn't it?"
-
-# End configuration file
-
-X = Will this break?
diff --git a/examples/ntlogon/ntlogon.py b/examples/ntlogon/ntlogon.py
deleted file mode 100755
index ba46ba8ffcf..00000000000
--- a/examples/ntlogon/ntlogon.py
+++ /dev/null
@@ -1,376 +0,0 @@
-#!/usr/bin/env python
-"""
-ntlogon.py written by Timothy (rhacer) Grant
-
-Copyright 1999 - 2002 by Timothy Grant
-
-is distributed under the terms of the GNU Public License.
-
-The format for the configuration file is as follows:
-
-While there is some room for confusion, we attempt to process things in
-order of specificity: Global first, Group second, User third, OS Type
-forth. This order can be debated forever, but it seems to make the most
-sense.
-
-# Everything in the Global section applies to all users logging on to the
-# network
-[Global]
-@ECHO "Welcome to our network!!!"
-NET TIME \\\\servername /SET /YES
-NET USE F: \\\\servername\\globalshare /YES
-
-# Map the private user area in the global section so we don't have to
-# create individual user entries for each user!
-NET USE U: \\\\servername\\%U /YES
-
-# Group entries, User entries and OS entries each start with the
-# keyword followed by a dash followed by--appropriately enough the Group
-# name, the User name, or the OS name.
-[Group-admin]
-@ECHO "Welcome administrators!"
-NET USE G: \\\\servername\\adminshare1 /YES
-NET USE I: \\\\servername\\adminshare2 /YES
-
-[Group-peons]
-@ECHO "Be grateful we let you use computers!"
-NET USE G: \\\\servername\\peonshare1 /YES
-
-[Group-hackers]
-@ECHO "What can I do for you today great one?"
-NET USE G: \\\\servername\\hackershare1 /YES
-NET USE I: \\\\servername\\adminshare2 /YES
-
-[User-fred]
-@ECHO "Hello there Fred!"
-NET USE F: \\\\servername\\fredsspecialshare /YES
-
-[OS-WfWg]
-@ECHO "Time to upgrade it?"
-
-# End configuration file
-
-usage: ntlogon [-g | --group=groupname]
- [-u | --user=username]
- [-o | --os=osname]
- [-m | --machine=netbiosname]
- [-f | --templatefile=filename]
- [-d | --dir=netlogon directory]
- [-v | --version]
- [-h | --help]
- [--pause]
- [--debug]
-"""
-#
-#" This quote mark is an artifact of the inability of my editor to
-# correctly colour code anything after the triple-quoted docstring.
-# if your editor does not have this flaw, feel free to remove it.
-
-
-import sys
-import getopt
-import re
-import string
-import os
-
-version = "ntlogon.py v0.8"
-
-def buildScript(buf, sections, group, user, ostype, machine, debug, pause):
- """
- buildScript() Takes the contents of the template file and builds
- a DOS batch file to be executed as an NT logon script. It does this
- by determining which sections of the configuration file should be included
- and creating a list object that contains each line contained in each
- included section. The list object is then returned to the calling
- routine.
-
- All comments (#) are removed. A REM is inserted to show
- which section of the configuration file each line comes from.
- We leave blanklines as they are sometimes useful for debugging
-
- We also replace all of the Samba macros (e.g., %U, %G, %a, %m) with their
- expanded versions which have been passed to us by smbd
- """
- hdrstring = ''
- script = []
-
- #
- # These are the Samba macros that we currently know about.
- # any user defined macros will also be added to this dictionary.
- # We do not store the % sign as part of the macro name.
- # The replace routine will prepend the % sign to all possible
- # replacements.
- #
- macros = {
- 'U': user,
- 'G': group,
- 'a': ostype,
- 'm': machine
- }
-
- #
- # Process each section defined in the list sections
- #
- for s in sections:
- # print 'searching for: ' + s
-
- idx = 0
-
- while idx < len(buf):
- ln = buf[idx]
-
- #
- # We need to set up a regex for each possible section we
- # know about. This is slightly complicated due to the fact
- # that section headers contain user defined text.
- #
- if s == 'Global':
- hdrstring = '\[ *' + s + ' *\]'
- elif s == 'Group':
- hdrstring = '\[ *' + s + ' *- *' + group + ' *\]'
- elif s == 'User':
- hdrstring = '\[ *' + s + ' *- *' + user + ' *\]'
- elif s == 'OS':
- hdrstring = '\[ *' + s + ' *- *' + ostype + ' *\]'
- elif s == 'Machine':
- hdrstring = '\[ *' + s + ' *- *' + machine + ' *\]'
-
- #
- # See if we have found a section header
- #
- if re.search(r'(?i)' + hdrstring, ln):
- idx = idx + 1 # increment the counter to move to the next
- # line.
-
- x = re.match(r'([^#\r\n]*)', ln) # Determine the section
- # name and strip out CR/LF
- # and comment information
-
- if debug:
- print 'rem ' + x.group(1) + ' commands'
- else:
- # create the rem at the beginning of each section of the
- # logon script.
- script.append('rem ' + x.group(1) + ' commands')
-
- #
- # process each line until we have found another section
- # header
- #
- while not re.search(r'.*\[.*\].*', buf[idx]):
-
- #
- # strip comments and line endings
- #
- x = re.match(r'([^#\r\n]*)', buf[idx])
-
- if string.strip(x.group(1)) != '' :
- # if there is still content after stripping comments and
- # line endings then this is a line to process
-
- line = x.group(1)
-
- #
- # Check to see if this is a macro definition line
- #
- vardef = re.match(r'(.*)=(.*)', line)
-
- if vardef:
- varname = string.strip(vardef.group(1)) # Strip leading and
- varsub = string.strip(vardef.group(2)) # and trailing spaces
-
- if varname == '':
- print "Error: No substition name specified line: %d" % idx
- sys.exit(1)
-
- if varsub == '':
- print "Error: No substitution text provided line: %d" % idx
- sys.exit(1)
-
- if macros.has_key(varname):
- print "Warning: macro %s redefined line: %d" % (varname, idx)
-
- macros[varname] = varsub
- idx = idx + 1
- continue
-
- #
- # Replace all the macros that we currently
- # know about.
- #
- # Iterate over the dictionary that contains all known
- # macro substitutions.
- #
- # We test for a macro name by prepending % to each dictionary
- # key.
- #
- for varname in macros.keys():
- line = re.sub(r'%' + varname + r'(\W)',
- macros[varname] + r'\1', line)
-
- if debug:
- print line
- if pause:
- print 'pause'
- else:
- script.append(line)
-
- idx = idx + 1
-
- if idx == len(buf):
- break # if we have reached the end of the file
- # stop processing.
-
- idx = idx + 1 # increment the line counter
-
- if debug:
- print ''
- else:
- script.append('')
-
- return script
-
-# End buildScript()
-
-def run():
- """
- run() everything starts here. The main routine reads the command line
- arguments, opens and reads the configuration file.
- """
- configfile = '/etc/ntlogon.conf' # Default configuration file
- group = '' # Default group
- user = '' # Default user
- ostype = '' # Default os
- machine = '' # Default machine type
- outfile = 'logon.bat' # Default batch file name
- # this file name WILL take on the form
- # username.bat if a username is specified
- debug = 0 # Default debugging mode
- pause = 0 # Default pause mode
- outdir = '/usr/local/samba/netlogon/' # Default netlogon directory
-
- sections = ['Global', 'Machine', 'OS', 'Group', 'User'] # Currently supported
- # configuration file
- # sections
-
- options, args = getopt.getopt(sys.argv[1:], 'd:f:g:ho:u:m:v',
- ['templatefile=',
- 'group=',
- 'help',
- 'os=',
- 'user=',
- 'machine=',
- 'dir=',
- 'version',
- 'pause',
- 'debug'])
-
- #
- # Process the command line arguments
- #
- for i in options:
- # template file to process
- if (i[0] == '-f') or (i[0] == '--templatefile'):
- configfile = i[1]
- # print 'configfile = ' + configfile
-
- # define the group to be used
- elif (i[0] == '-g') or (i[0] == '--group'):
- group = i[1]
- # print 'group = ' + group
-
- # define the os type
- elif (i[0] == '-o') or (i[0] == '--os'):
- ostype = i[1]
- # print 'os = ' + os
-
- # define the user
- elif (i[0] == '-u') or (i[0] == '--user'):
- user = i[1]
- outfile = user + '.bat' # Setup the output file name
- # print 'user = ' + user
-
- # define the machine
- elif (i[0] == '-m') or (i[0] == '--machine'):
- machine = i[1]
-
- # define the netlogon directory
- elif (i[0] == '-d') or (i[0] == '--dir'):
- outdir = i[1]
- # print 'outdir = ' + outdir
-
- # if we are asked to turn on debug info, do so.
- elif (i[0] == '--debug'):
- debug = 1
- # print 'debug = ' + debug
-
- # if we are asked to turn on the automatic pause functionality, do so
- elif (i[0] == '--pause'):
- pause = 1
- # print 'pause = ' + pause
-
- # if we are asked for the version number, print it.
- elif (i[0] == '-v') or (i[0] == '--version'):
- print version
- sys.exit(0)
-
- # if we are asked for help print the docstring.
- elif (i[0] == '-h') or (i[0] == '--help'):
- print __doc__
- sys.exit(0)
-
- #
- # open the configuration file
- #
- try:
- iFile = open(configfile, 'r')
- except IOError:
- print 'Unable to open configuration file: ' + configfile
- sys.exit(1)
-
-
- #
- # open the output file
- #
- if not debug:
- try:
- oFile = open(outdir + outfile, 'w')
- except IOError:
- print 'Unable to open logon script file: ' + outdir + outfile
- sys.exit(1)
-
- buf = iFile.readlines() # read in the entire configuration file
-
- #
- # call the script building routine
- #
- script = buildScript(buf, sections, group, user, ostype, machine, debug, pause)
-
- #
- # write out the script file
- #
- if not debug:
- for ln in script:
- oFile.write(ln + '\r\n')
- if pause:
- if string.strip(ln) != '': # Because whitespace
- oFile.write('pause' + '\r\n') # is a useful tool, we
- # don't put pauses after
- # an empty line.
-
-
-# End run()
-
-#
-# immediate-mode commands, for drag-and-drop or execfile() execution
-#
-if __name__ == '__main__':
- run()
-else:
- print "Module ntlogon.py imported."
- print "To run, type: ntlogon.run()"
- print "To reload after changes to the source, type: reload(ntlogon)"
-
-#
-# End NTLogon.py
-#
diff --git a/examples/pdb/Makefile b/examples/pdb/Makefile
deleted file mode 100644
index a53cd5d5e2d..00000000000
--- a/examples/pdb/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-# Makefile for samba-pdb examples
-# Variables
-
-CC = gcc
-LIBTOOL = libtool
-
-SAMBA_SRC = ../../source
-SAMBA_INCL = ../../source/include
-UBIQX_SRC = ../../source/ubiqx
-SMBWR_SRC = ../../source/smbwrapper
-CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -I/usr/include/heimdal -fPIC
-PDB_OBJS = pdb_test.so
-
-# Default target
-
-default: $(PDB_OBJS)
-
-# Pattern rules
-
-%.so: %.lo
- $(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS)
-
-%.lo: %.c
- $(LIBTOOL) $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
-
-# Misc targets
-
-clean:
- rm -rf .libs
- rm -f core *~ *% *.bak \
- $(PDB_OBJS) $(PDB_OBJS:.so=.o) $(PDB_OBJS:.so=.lo)
diff --git a/examples/pdb/README b/examples/pdb/README
deleted file mode 100644
index ab1baed2366..00000000000
--- a/examples/pdb/README
+++ /dev/null
@@ -1,16 +0,0 @@
-README for Samba Password Database (PDB) examples
-====================================================
-Jelmer Vernooij <jelmer@nl.linux.org>
-Stefan (metze) Metzmacher <metze@samba.org>
-
-The pdb_test.c file in this directory contains a very basic example of
-a pdb plugin. It just prints the name of the function that is executed using
-DEBUG. Maybe it's nice to include some of the arguments to the function in the
-future too..
-
-To debug passdb backends, try to run gdb on the 'pdbedit' executable. That's
-really much easier than restarting smbd constantly and attaching with your
-debugger.
-
-New passdb plugins should go into the samba lib directory, (/usr/lib/samba/pdb/
-for most distributions). An example would be: /usr/lib/samba/pdb/test.so
diff --git a/examples/pdb/mysql/mysql.dump b/examples/pdb/mysql/mysql.dump
deleted file mode 100644
index 5da75f5745c..00000000000
--- a/examples/pdb/mysql/mysql.dump
+++ /dev/null
@@ -1,37 +0,0 @@
-# Put this in your MySQL database by running
-# mysql -u<user> -p<password> -h<host> <database> < mysql.dump
-
-CREATE TABLE user (
- logon_time int(9),
- logoff_time int(9),
- kickoff_time int(9),
- pass_last_set_time int(9),
- pass_can_change_time int(9),
- pass_must_change_time int(9),
- username varchar(255),
- domain varchar(255),
- nt_username varchar(255),
- nt_fullname varchar(255),
- home_dir varchar(255),
- dir_drive varchar(4),
- logon_script varchar(255),
- profile_path varchar(255),
- acct_desc varchar(255),
- workstations varchar(255),
- unknown_str varchar(255),
- munged_dial varchar(255),
- uid int(9) NOT NULL DEFAULT "0" PRIMARY KEY auto_increment,
- gid int(9),
- user_sid varchar(255),
- group_sid varchar(255),
- lm_pw varchar(255),
- nt_pw varchar(255),
- acct_ctrl int(9),
- unknown_3 int(9),
- logon_divs int(9),
- hours_len int(9),
- unknown_5 int(9),
- unknown_6 int(9),
- bad_password_count int(9),
- logon_count(9)
-);
diff --git a/examples/pdb/mysql/smb.conf b/examples/pdb/mysql/smb.conf
deleted file mode 100644
index 61a3f198168..00000000000
--- a/examples/pdb/mysql/smb.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-[global]
-netbios name = FOOBAR
-workgroup = TESTGROUP
-security = domain
-domain logons = yes
-domain master = yes
-passdb backend = plugin:/usr/local/samba/lib/pdb_mysql.so:mysql
-mysql:mysql host = rhonwyn
-mysql:mysql user = samba
-mysql:mysql password = ambas
-mysql:mysql database = samba
diff --git a/examples/pdb/pdb_test.c b/examples/pdb/pdb_test.c
deleted file mode 100644
index e46c621d48e..00000000000
--- a/examples/pdb/pdb_test.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Test password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-static int testsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS testsam_debug_level
-
-/***************************************************************
- Start enumeration of the passwd list.
-****************************************************************/
-
-static NTSTATUS testsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- DEBUG(10, ("testsam_setsampwent called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
-****************************************************************/
-
-static void testsam_endsampwent(struct pdb_methods *methods)
-{
- DEBUG(10, ("testsam_endsampwent called\n"));
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
-*****************************************************************/
-
-static NTSTATUS testsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
-{
- DEBUG(10, ("testsam_getsampwent called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
-******************************************************************/
-
-static NTSTATUS testsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
-{
- DEBUG(10, ("testsam_getsampwnam called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS testsam_getsampwsid (struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid)
-{
- DEBUG(10, ("testsam_getsampwsid called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
-****************************************************************************/
-
-static NTSTATUS testsam_delete_sam_account(struct pdb_methods *methods, SAM_ACCOUNT *sam_pass)
-{
- DEBUG(10, ("testsam_delete_sam_account called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/***************************************************************************
- Modifies an existing SAM_ACCOUNT
-****************************************************************************/
-
-static NTSTATUS testsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
- DEBUG(10, ("testsam_update_sam_account called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/***************************************************************************
- Adds an existing SAM_ACCOUNT
-****************************************************************************/
-
-static NTSTATUS testsam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
- DEBUG(10, ("testsam_add_sam_account called\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS testsam_init(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "testsam";
-
- /* Functions your pdb module doesn't provide should be set
- * to NULL */
-
- (*pdb_method)->setsampwent = testsam_setsampwent;
- (*pdb_method)->endsampwent = testsam_endsampwent;
- (*pdb_method)->getsampwent = testsam_getsampwent;
- (*pdb_method)->getsampwnam = testsam_getsampwnam;
- (*pdb_method)->getsampwsid = testsam_getsampwsid;
- (*pdb_method)->add_sam_account = testsam_add_sam_account;
- (*pdb_method)->update_sam_account = testsam_update_sam_account;
- (*pdb_method)->delete_sam_account = testsam_delete_sam_account;
-
- testsam_debug_level = debug_add_class("testsam");
- if (testsam_debug_level == -1) {
- testsam_debug_level = DBGC_ALL;
- DEBUG(0, ("testsam: Couldn't register custom debugging class!\n"));
- } else DEBUG(0, ("testsam: Debug class number of 'testsam': %d\n", testsam_debug_level));
-
- DEBUG(0, ("Initializing testsam\n"));
- if (location)
- DEBUG(10, ("Location: %s\n", location));
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS init_module(void) {
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "testsam",
- testsam_init);
-}
diff --git a/examples/pdb/sambapdb.dtd b/examples/pdb/sambapdb.dtd
deleted file mode 100644
index 1f4054ddec4..00000000000
--- a/examples/pdb/sambapdb.dtd
+++ /dev/null
@@ -1,46 +0,0 @@
-<!ELEMENT samba:crypt (#PCDATA)* >
-<!ATTLIST samba:crypt type CDATA #REQUIRED >
-
-<!ELEMENT samba:password (samba:crypt*) >
-<!ATTLIST samba:password last_set CDATA #IMPLIED
- must_change CDATA #IMPLIED
- can_change CDATA #IMPLIED>
-
-<!ELEMENT samba:group (#PCDATA)* >
-<!ATTLIST samba:group sid CDATA #REQUIRED
- gid CDATA #IMPLIED >
-
-<!ELEMENT samba:domain (#PCDATA)* >
-<!ELEMENT samba:fullname (#PCDATA)* >
-<!ELEMENT samba:nt_username (#PCDATA)* >
-<!ELEMENT samba:logon_script (#PCDATA)* >
-<!ELEMENT samba:profile_path (#PCDATA)* >
-<!ELEMENT samba:logon_time (#PCDATA)* >
-<!ELEMENT samba:logoff_time (#PCDATA)* >
-<!ELEMENT samba:kickoff_time (#PCDATA)* >
-<!ELEMENT samba:logon_divs (#PCDATA)* >
-<!ELEMENT samba:hours_len (#PCDATA)* >
-<!ELEMENT samba:unknown_3 (#PCDATA)* >
-<!ELEMENT samba:unknown_5 (#PCDATA)* >
-<!ELEMENT samba:unknown_6 (#PCDATA)* >
-<!ELEMENT samba:homedir (#PCDATA)* >
-<!ELEMENT samba:unknown_str (#PCDATA)* >
-<!ELEMENT samba:dir_drive (#PCDATA)* >
-<!ELEMENT samba:munged_dial (#PCDATA)* >
-<!ELEMENT samba:acct_desc (#PCDATA)* >
-<!ELEMENT samba:acct_ctrl (#PCDATA)* >
-<!ELEMENT samba:workstations (#PCDATA)* >
-
-<!ELEMENT samba:user ( samba:group?, samba:domain?, samba:nt_username?, samba:fullname?, samba:homedir?, samba:dir_drive?, samba:logon_script?, samba:profile_path?, samba:password?, samba:acct_ctrl?,samba:unknown_3?, samba:logon_divs?, samba:hours_len?, samba:logon_time?, samba:logoff_time?, samba:kickoff_time?, samba:unknown_5?, samba:unknown_6?, samba:unknown_str?, samba:munged_dial?, samba:acct_desc?, samba:workstations? ) >
-
-<!ATTLIST samba:user sid CDATA #REQUIRED
- uid CDATA #IMPLIED
- name CDATA #REQUIRED>
-
-<!ELEMENT samba:users (samba:user*) >
-
-<!ELEMENT samba (samba:users?) >
-
-<!ATTLIST samba
- xmlns CDATA #FIXED 'http://samba.org/~jelmer/sambapdb.dtd'>
-
diff --git a/examples/printing/prtpub.c b/examples/printing/prtpub.c
deleted file mode 100644
index ea71e03d073..00000000000
--- a/examples/printing/prtpub.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Set printer capabilities in DsDriver Keys on remote printer
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* This needs to be defined for certain compilers */
-#define WINVER 0x0500
-
-#include <tchar.h>
-#include <windows.h>
-#include <stdio.h>
-
-#define SAMBA_PORT _T("Samba")
-
-TCHAR *PrintLastError(void)
-{
- static TCHAR msgtxt[1024*sizeof(TCHAR)];
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(),
- 0, msgtxt, 0, NULL);
-
- return msgtxt;
-}
-
-void map_orientation(HANDLE ph, TCHAR *printer, TCHAR *port)
-{
- DWORD rot;
- TCHAR portrait_only[] = _T("PORTRAIT\0");
- TCHAR both[] = _T("LANDSCAPE\0PORTRAIT\0");
-
- /* orentation of 90 or 270 indicates landscape supported, 0 means it isn't */
- rot = DeviceCapabilities(printer, port, DC_BINNAMES, NULL, NULL);
-
- printf("printOrientationsSupported:\n");
-
- if (rot) {
- printf("\tPORTRAIT\n\tLANDSCAPE\n");
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printOrientationsSupported"), REG_MULTI_SZ,
- both, sizeof(both));
- } else {
- printf("\tPORTRAIT\n");
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printOrientationsSupported"), REG_MULTI_SZ,
- portrait_only, sizeof(portrait_only));
- }
-}
-
-void map_resolution(HANDLE ph, TCHAR *printer, TCHAR *port)
-{
- DWORD num, *res, maxres = 0, i;
-
- num = DeviceCapabilities(printer, port, DC_ENUMRESOLUTIONS, NULL, NULL);
- if ((DWORD) -1 == num)
- return;
- res = malloc(num*2*sizeof(DWORD));
- num = DeviceCapabilities(printer, port, DC_ENUMRESOLUTIONS, (BYTE *) res, NULL);
- for (i=0; i < num*2; i++) {
- maxres = (res[i] > maxres) ? res[i] : maxres;
- }
- printf("printMaxResolutionSupported: %d\n", maxres);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxResolutionSupported"), REG_DWORD,
- (BYTE *) &maxres, sizeof(maxres));
-}
-
-void map_extents(HANDLE ph, TCHAR *printer, TCHAR *port)
-{
- DWORD extentval, xval, yval;
-
- extentval = DeviceCapabilities(printer, port, DC_MINEXTENT, NULL, NULL);
- xval = (DWORD) (LOWORD(extentval));
- yval = (DWORD) (HIWORD(extentval));
- printf("printMinXExtent: %d\n", xval);
- printf("printMinYExtent: %d\n", yval);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMinXExtent"), REG_DWORD, (BYTE *) &xval, sizeof(xval));
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMinYExtent"), REG_DWORD, (BYTE *) &yval, sizeof(yval));
- extentval = DeviceCapabilities(printer, port, DC_MAXEXTENT, NULL, NULL);
- xval = (DWORD) (LOWORD(extentval));
- yval = (DWORD) (HIWORD(extentval));
- printf("printMaxXExtent: %d\n", xval);
- printf("printMaxYExtent: %d\n", yval);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxXExtent"), REG_DWORD, (BYTE *) &xval, sizeof(xval));
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxYExtent"), REG_DWORD, (BYTE *) &yval, sizeof(yval));
-}
-
-void map_printrateunit(HANDLE ph, TCHAR *printer, TCHAR *port)
-{
- DWORD unit;
- TCHAR ppm[] = _T("PagesPerMinute");
- TCHAR ipm[] = _T("InchesPerMinute");
- TCHAR lpm[] = _T("LinesPerMinute");
- TCHAR cps[] = _T("CharactersPerSecond");
-
- unit = DeviceCapabilities(printer, port, DC_PRINTRATEUNIT, NULL, NULL);
- switch(unit) {
- case PRINTRATEUNIT_PPM:
- printf("printRateUnit: %s\n", ppm);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, ppm, sizeof(ppm));
- break;
- case PRINTRATEUNIT_IPM:
- printf("printRateUnit: %s\n", ipm);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, ipm, sizeof(ipm));
- break;
- case PRINTRATEUNIT_LPM:
- printf("printRateUnit: %s\n", lpm);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, lpm, sizeof(lpm));
- break;
- case PRINTRATEUNIT_CPS:
- printf("printRateUnit: %s\n", cps);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, cps, sizeof(cps));
- break;
- default:
- printf("printRateUnit: unknown value %d\n", unit);
- }
-}
-
-void map_generic_boolean(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key)
-{
- BYTE boolval;
- /* DeviceCapabilities doesn't always return 1 for true...just nonzero */
- boolval = (BYTE) (DeviceCapabilities(printer, port, cap, NULL, NULL) ? 1 : 0);
- printf("%s: %s\n", key, boolval ? "TRUE" : "FALSE");
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_BINARY, &boolval, sizeof(boolval));
-}
-
-void map_generic_dword(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key)
-{
- DWORD dword;
-
- dword = DeviceCapabilities(printer, port, cap, NULL, NULL);
- if ((DWORD) -1 == dword)
- return;
-
- printf("%s: %d\n", key, dword);
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_DWORD, (BYTE *) &dword, sizeof(dword));
-}
-
-void map_generic_multi_sz(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key, int size)
-{
- TCHAR *strings_in;
- TCHAR *strings_out, *strings_cur;
- DWORD num_items, i;
-
- num_items = DeviceCapabilities(printer, port, cap, NULL, NULL);
- if ((DWORD) -1 == num_items)
- return;
- strings_in = malloc(num_items * size);
- strings_out = calloc(num_items, size);
- num_items = DeviceCapabilities(printer, port, cap, strings_in, NULL);
- printf("%s:\n", key);
- for (i=0, strings_cur = strings_out; i < num_items; i++) {
- _tcsncpy(strings_cur, &strings_in[i*size], size);
- printf("\t%s\n", strings_cur);
- strings_cur += _tcslen(strings_cur) + 1;
- }
-
- SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_MULTI_SZ, strings_out,
- (strings_cur - strings_out + 1) * sizeof(TCHAR));
-
- free(strings_in);
- free(strings_out);
-}
-
-int main(int argc, char *argv[])
-{
- HANDLE ph;
- BYTE *driver_info;
- DWORD needed;
- TCHAR *printer;
- TCHAR *port = SAMBA_PORT;
- PRINTER_DEFAULTS admin_access = {NULL, NULL, PRINTER_ACCESS_ADMINISTER};
- PRINTER_INFO_7 publish = {NULL, DSPRINT_PUBLISH};
-
- if (argc < 2) {
- printf("Usage: %s <printername>\n", argv[0]);
- return -1;
- }
-
- printer = argv[1];
-
- if (!(OpenPrinter(printer, &ph, &admin_access))) {
- printf("OpenPrinter failed, error = %s\n", PrintLastError());
- return -1;
- }
-
- GetPrinterDriver(ph, NULL, 1, NULL, 0, &needed);
- if (!needed) {
- printf("GetPrinterDriver failed, error = %s\n", PrintLastError());
- ClosePrinter(ph);
- return -1;
- }
- driver_info = malloc(needed);
- if (!(GetPrinterDriver(ph, NULL, 1, driver_info, needed, &needed))) {
- printf("GetPrinterDriver failed, error = %s\n", PrintLastError());
- ClosePrinter(ph);
- return -1;
- }
-
- map_generic_multi_sz(ph, printer, port, DC_BINNAMES, _T("printBinNames"), 24);
- map_generic_boolean(ph, printer, port, DC_COLLATE, _T("printCollate"));
- map_generic_dword(ph, printer, port, DC_COPIES, _T("printMaxCopies"));
- map_generic_dword(ph, printer, port, DC_DRIVER, _T("driverVersion"));
- map_generic_boolean(ph, printer, port, DC_DUPLEX, _T("printDuplexSupported"));
- map_extents(ph, printer, port);
- map_resolution(ph, printer, port);
- map_orientation(ph, printer, port);
- map_generic_multi_sz(ph, printer, port, DC_PAPERNAMES, _T("printMediaSupported"), 64);
-#if (WINVER >= 0x0500)
- map_generic_boolean(ph, printer, port, DC_COLORDEVICE, _T("printColor"));
- map_generic_multi_sz(ph, printer, port, DC_PERSONALITY, _T("printLanguage"), 64);
- map_generic_multi_sz(ph, printer, port, DC_MEDIAREADY, _T("printMediaReady"),64);
- map_generic_dword(ph, printer, port, DC_PRINTERMEM, _T("printMemory"));
- map_generic_dword(ph, printer, port, DC_PRINTRATE, _T("printRate"));
- map_printrateunit(ph, printer, port);
-#ifdef DC_STAPLE
- map_generic_boolean(ph, printer, port, DC_STAPLE, _T("printStaplingSupported"));
-#endif
-#ifdef DC_PRINTRATEPPM
- map_generic_dword(ph, printer, port, DC_PRINTRATEPPM, _T("printPagesPerMinute"));
-#endif
-#endif
- SetPrinter(ph, 7, (BYTE *) &publish, 0);
- ClosePrinter(ph);
- return 0;
-}
diff --git a/examples/printing/readme.prtpub b/examples/printing/readme.prtpub
deleted file mode 100644
index 319ce605c3b..00000000000
--- a/examples/printing/readme.prtpub
+++ /dev/null
@@ -1,12 +0,0 @@
-prtpub.c contains a program which, when compiled with Visual C, can
-download a driver for a printer, query the capabilities of the driver,
-then write back the DsDriver keys necessary to publish all the fields
-of a printer in the directory. After writing back the fields, it issues
-a SetPrinter with info level 7, telling the server to publish the
-printer.
-
-It also writes the fields to stdout.
-
-In order to be distributed, it should be compiled using DLLs for C runtime.
-
-The program takes the UNC name of a printer as the only argument.
diff --git a/examples/printing/smbprint b/examples/printing/smbprint
index 61ee41f4440..68bd66a13fe 100755
--- a/examples/printing/smbprint
+++ b/examples/printing/smbprint
@@ -140,5 +140,6 @@ $smbclient \
$IP \
$debugargs \
-U $username \
+ -P \
-c "$command"
#
diff --git a/examples/printing/smbprint.newer b/examples/printing/smbprint.newer
new file mode 100755
index 00000000000..a741fd7078d
--- /dev/null
+++ b/examples/printing/smbprint.newer
@@ -0,0 +1,95 @@
+#!/bin/sh
+
+# This script is an input filter for printcap printing on a unix machine. It
+# uses the smbclient program to print the file to the specified smb-based
+# server and service.
+# For example you could have a printcap entry like this
+#
+# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
+#
+# which would create a unix printer called "smb" that will print via this
+# script. You will need to create the spool directory /usr/spool/smb with
+# appropriate permissions and ownerships for your system.
+
+# Set these to the server and service you wish to print to
+# In this example I have a WfWg PC called "lapland" that has a printer
+# exported called "printer" with no password.
+
+#
+# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
+# so that the server, service, and password can be read from
+# a /usr/var/spool/lpd/PRINTNAME/.config file.
+#
+# Script further modified by Richard Sharpe to fix some things.
+# Get rid of the -x on the first line, and add parameters
+#
+# -t now causes translate to be used when sending files
+#
+# In order for this to work the /etc/printcap entry must include an
+# accounting file (af=...):
+#
+# cdcolour:\
+# :cm=CD IBM Colorjet on 6th:\
+# :sd=/var/spool/lpd/cdcolour:\
+# :af=/var/spool/lpd/cdcolour/acct:\
+# :if=/usr/local/etc/smbprint:\
+# :mx=0:\
+# :lp=/dev/null:
+#
+# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
+# server=PC_SERVER
+# service=PR_SHARENAME
+# password="password"
+#
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
+# password=""
+
+#
+# Debugging log file, change to /dev/null if you like.
+#
+logfile=/tmp/smb-print.log
+# logfile=/dev/null
+
+
+#
+# The last parameter to the filter is the accounting file name.
+# Extract the directory name from the file name.
+# Concat this with /.config to get the config file.
+#
+TRANS=0
+eval acct_file=\${$#}
+spool_dir=`dirname $acct_file`
+config_file=$spool_dir/.config
+
+# Should read the following variables set in the config file:
+# server
+# service
+# password
+eval `cat $config_file`
+
+while getopts t c; do
+ case $c in
+ t)
+ TRANS=1
+ ;;
+
+ '?') # Bad parameters, ignore it ...
+ ;;
+ esac
+done
+#
+# Some debugging help, change the >> to > if you want to same space.
+#
+echo "server $server, service $service" >> $logfile
+
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+ if [ $TRANS -eq 1 ]; then
+ echo translate
+ fi
+ echo "print -"
+ cat
+) | /usr/local/samba/bin/smbclient "//$server/$service" $password -U $server -N -P >> $logfile
diff --git a/examples/printing/smbprint-new.sh b/examples/printing/smbprint.safer
index 61ee41f4440..79a879badc5 100644..100755
--- a/examples/printing/smbprint-new.sh
+++ b/examples/printing/smbprint.safer
@@ -77,8 +77,11 @@ config_file=$spool_dir/.config
# debugfile (optional)
. $config_file
+password_flag=""
if [ "x$password" = "x" ] ; then
- password="-N"
+ password_flag="-N"
+else
+ export PASSWD=$password
fi
if [ "x$username" == "x" ] ; then
@@ -132,13 +135,13 @@ if [ "x$debugargs" != "x" ]; then
debugargs="-l $debugargs"
fi
-
+export USER=$username
$smbclient \
"\\\\$server\\$service" \
- $password \
+ $password_flag \
$smbconf \
$IP \
$debugargs \
- -U $username \
+ -P \
-c "$command"
#
diff --git a/examples/printing/smbprint.sysv b/examples/printing/smbprint.sysv
index 11fea21441b..3e1cec47f50 100644
--- a/examples/printing/smbprint.sysv
+++ b/examples/printing/smbprint.sysv
@@ -47,6 +47,6 @@ password=""
echo translate
echo "print -"
cat $*
-) | /opt/samba/smbclient "\\\\$server\\$service" $password -N > /dev/null
+) | /opt/samba/smbclient "\\\\$server\\$service" $password -N -P > /dev/null
exit $?
diff --git a/examples/smb.conf.default b/examples/smb.conf.default
index 839fede1233..cb9f632b18c 100644
--- a/examples/smb.conf.default
+++ b/examples/smb.conf.default
@@ -3,175 +3,247 @@
# here. Samba has a huge number of configurable options (perhaps too
# many!) most of which are not shown in this example
#
-# For a step to step guide on installing, configuring and using samba,
-# read the Samba HOWTO Collection.
-#
-# Any line which starts with a ; (semi-colon) or a # (hash)
+# Any line which starts with a ; (semi-colon) or a # (hash)
# is a comment and is ignored. In this example we will use a #
# for commentry and a ; for parts of the config file that you
# may wish to enable
#
# NOTE: Whenever you modify this file you should run the command "testparm"
-# to check that you have not made any basic syntactic errors.
+# to check that you have not many any basic syntactic errors.
#
#======================= Global Settings =====================================
[global]
-# workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4
- workgroup = MYGROUP
-
-# server string is the equivalent of the NT Description field
- server string = Samba Server
-
-# Security mode. Defines in which mode Samba will operate. Possible
-# values are share, user, server, domain and ads. Most people will want
-# user level security. See the HOWTO Collection for details.
- security = user
-
-# This option is important for security. It allows you to restrict
-# connections to machines which are on your local network. The
-# following example restricts access to two C class networks and
-# the "loopback" interface. For more examples of the syntax see
-# the smb.conf man page
-; hosts allow = 192.168.1. 192.168.2. 127.
-
-# If you want to automatically load your printer list rather
-# than setting them up individually then you'll need this
- load printers = yes
-
-# you may wish to override the location of the printcap file
-; printcap name = /etc/printcap
-
-# on SystemV system setting printcap name to lpstat should allow
-# you to automatically obtain a printer list from the SystemV spool
-# system
-; printcap name = lpstat
-
-# It should not be necessary to specify the print system type unless
-# it is non-standard. Currently supported print systems include:
-# bsd, cups, sysv, plp, lprng, aix, hpux, qnx
-; printing = cups
-
-# Uncomment this if you want a guest account, you must add this to /etc/passwd
-# otherwise the user "nobody" is used
-; guest account = pcguest
-
-# this tells Samba to use a separate log file for each machine
-# that connects
- log file = /usr/local/samba/var/log.%m
-
-# Put a capping on the size of the log files (in Kb).
- max log size = 50
-
-# Use password server option only with security = server
-# The argument list may include:
-# password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name]
-# or to auto-locate the domain controller/s
-# password server = *
-; password server = <NT-Server-Name>
-
-# Use the realm option only with security = ads
-# Specifies the Active Directory realm the host is part of
-; realm = MY_REALM
-
-# Backend to store user information in. New installations should
-# use either tdbsam or ldapsam. smbpasswd is available for backwards
-# compatibility. tdbsam requires no further configuration.
-; passdb backend = tdbsam
-
-# Using the following line enables you to customise your configuration
-# on a per machine basis. The %m gets replaced with the netbios name
-# of the machine that is connecting.
-# Note: Consider carefully the location in the configuration file of
-# this line. The included file is read at that point.
-; include = /usr/local/samba/lib/smb.conf.%m
-
-# Most people will find that this option gives better performance.
-# See the chapter 'Samba performance issues' in the Samba HOWTO Collection
-# and the manual pages for details.
-# You may want to add the following on a Linux system:
-# SO_RCVBUF=8192 SO_SNDBUF=8192
- socket options = TCP_NODELAY
-
-# Configure Samba to use multiple interfaces
-# If you have multiple network interfaces then you must list them
-# here. See the man page for details.
-; interfaces = 192.168.12.2/24 192.168.13.2/24
-
-# Browser Control Options:
-# set local master to no if you don't want Samba to become a master
-# browser on your network. Otherwise the normal election rules apply
-; local master = no
-
-# OS Level determines the precedence of this server in master browser
-# elections. The default value should be reasonable
-; os level = 33
-
-# Domain Master specifies Samba to be the Domain Master Browser. This
-# allows Samba to collate browse lists between subnets. Don't use this
-# if you already have a Windows NT domain controller doing this job
-; domain master = yes
-
-# Preferred Master causes Samba to force a local browser election on startup
-# and gives it a slightly higher chance of winning the election
-; preferred master = yes
-
-# Enable this if you want Samba to be a domain logon server for
-# Windows95 workstations.
-; domain logons = yes
-
-# if you enable domain logons then you may want a per-machine or
-# per user logon script
-# run a specific logon batch file per workstation (machine)
-; logon script = %m.bat
-# run a specific logon batch file per username
-; logon script = %U.bat
-
-# Where to store roving profiles (only for Win95 and WinNT)
-# %L substitutes for this servers netbios name, %U is username
-# You must uncomment the [Profiles] share below
-; logon path = \\%L\Profiles\%U
-
-# Windows Internet Name Serving Support Section:
-# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
-; wins support = yes
-
-# WINS Server - Tells the NMBD components of Samba to be a WINS Client
-# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
-; wins server = w.x.y.z
-
-# WINS Proxy - Tells Samba to answer name resolution queries on
-# behalf of a non WINS capable client, for this to work there must be
-# at least one WINS Server on the network. The default is NO.
-; wins proxy = yes
-
-# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
-# via DNS nslookups. The default is NO.
- dns proxy = no
-
-# These scripts are used on a domain controller or stand-alone
-# machine to add or delete corresponding unix accounts
-; add user script = /usr/sbin/useradd %u
-; add group script = /usr/sbin/groupadd %g
-; add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u
-; delete user script = /usr/sbin/userdel %u
-; delete user from group script = /usr/sbin/deluser %u %g
-; delete group script = /usr/sbin/groupdel %g
+##
+## Basic Server Settings
+##
+
+ # workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4
+ workgroup = MYGROUP
+
+ # server string is the equivalent of the NT Description field
+ server string = Samba Server
+
+ # This option is important for security. It allows you to restrict
+ # connections to machines which are on your local network. The
+ # following example restricts access to two C class networks and
+ # the "loopback" interface. For more examples of the syntax see
+ # the smb.conf man page
+ ; hosts allow = 192.168.1. 192.168.2.0./24 192.168.3.0/255.255.255.0 127.0.0.1
+
+ # Uncomment this if you want a guest account, you must add this to /etc/passwd
+ # otherwise the user "nobody" is used
+ ; guest account = pcguest
+
+ # this tells Samba to use a separate log file for each machine
+ # that connects
+ log file = /usr/local/samba/var/log.%m
+
+ # How much information do you want to see in the logs?
+ # default is only to log critical messages
+ ; log level = 1
+
+ # Put a capping on the size of the log files (in Kb).
+ max log size = 50
+
+ # Security mode. Most people will want user level security. See
+ # security_level.txt for details.
+ security = user
+
+ # Using the following line enables you to customise your configuration
+ # on a per machine basis. The %m gets replaced with the netbios name
+ # of the machine that is connecting.
+ # Note: Consider carefully the location in the configuration file of
+ # this line. The included file is read at that point.
+ ; include = /usr/local/samba/lib/smb.conf.%m
+
+ # Most people will find that this option gives better performance.
+ # See speed.txt and the manual pages for details
+ # You may want to add the following on a Linux system:
+ # SO_RCVBUF=8192 SO_SNDBUF=8192
+ ; socket options = TCP_NODELAY
+
+ # Configure Samba to use multiple interfaces
+ # If you have multiple network interfaces and want to limit smbd will
+ # use, list the ones desired here. Otherwise smbd & nmbd will bind to all
+ # active interfaces on the system. See the man page for details.
+ ; interfaces = 192.168.12.2/24 192.168.13.2/24
+
+ # Should smbd report that it has MS-DFS Capabilities? Only available
+ # if --with-msdfs was passed to ./configure
+ ; host msdfs = yes
+
+##
+## Network Browsing
+##
+ # set local master to no if you don't want Samba to become a master
+ # browser on your network. Otherwise the normal election rules apply
+ ; local master = no
+
+ # OS Level determines the precedence of this server in master browser
+ # elections. The default value (20) should be reasonable
+ ; os level = 20
+
+ # Domain Master specifies Samba to be the Domain Master Browser. This
+ # allows Samba to collate browse lists between subnets. Don't use this
+ # if you already have a Windows NT domain controller doing this job
+ ; domain master = yes
+
+ # Preferred Master causes Samba to force a local browser election on startup
+ # and gives it a slightly higher chance of winning the election
+ ; preferred master = yes
+
+
+##
+## WINS & Name Resolution
+##
+ # Windows Internet Name Serving Support Section:
+ # WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+ ; wins support = yes
+
+ # WINS Server - Tells the NMBD components of Samba to be a WINS Client
+ # Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+ ; wins server = w.x.y.z
+
+ # WINS Proxy - Tells Samba to answer name resolution queries on
+ # behalf of a non WINS capable client, for this to work there must be
+ # at least one WINS Server on the network. The default is NO.
+ ; wins proxy = yes
+
+ # DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+ # via DNS nslookups.
+ dns proxy = no
+
+
+##
+## Passwords & Authentication
+##
+ # Use password server option only with security = server
+ # The argument list may include:
+ # password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name]
+ # or to auto-locate the domain controller/s
+ ; password server = *
+ ; password server = <NT-Server-Name>
+
+ # You may wish to use password encryption. Please read
+ # ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+ # Do not enable this option unless you have read those documents
+ ; encrypt passwords = yes
+
+ # Should smbd obey the session and account lines in /etc/pam.d/samba ?
+ # only available if --with-pam was used at compile time
+ ; obey pam restrictions = yes
+
+ # When using encrypted passwords, Samba can synchronize the local
+ # UNIX password as well. You will also need the "passwd chat" parameters
+ ; unix password sync = yes
+
+ # how should smbd talk to the local system when changing a UNIX
+ # password? See smb.conf(5) for details
+ ; passwd chat = <custom chat string>
+
+ # This is only available if you compiled Samba to include --with-pam
+ # Use PAM for changing the password
+ ; pam password change = yes
+
+##
+## Domain Control
+##
+ # Enable this if you want Samba act as a domain controller.
+ # make sure you have read the Samba-PDC-HOWTO included in the documentation
+ # before enabling this parameter
+ ; domain logons = yes
+
+ # if you enable domain logons then you may want a per-machine or
+ # per user logon script
+ # run a specific logon batch file per workstation (machine)
+ ; logon script = %m.bat
+ # run a specific logon batch file per username
+ ; logon script = %U.bat
+
+ # Where to store roving profiles (only for Win95 and WinNT)
+ # %L substitutes for this servers netbios name, %U is username
+ # You must uncomment the [Profiles] share below
+ ; logon path = \\%L\Profiles\%U
+
+ # UNC path specifying the network location of the user's home directory
+ # only used when acting as a DC for WinNT/2k/XP. Ignored by Win9x clients
+ ; logon home = \\%L\%U
+
+ # What drive should the "logon home" be mounted at upon login ?
+ # only used when acting as a DC for WinNT/2k/XP. Ignored by Win9x clients
+ ; logon drive = H:
+
+##
+## Printing
+##
+
+ # If you want to automatically load your printer list rather
+ # than setting them up individually then you'll need this
+ load printers = yes
+
+ # you may wish to override the location of the printcap file
+ ; printcap name = /etc/printcap
+
+ # on SystemV system setting printcap name to lpstat should allow
+ # you to automatically obtain a printer list from the SystemV spool
+ # system
+ ; printcap name = lpstat
+
+ # It should not be necessary to specify the print system type unless
+ # it is non-standard. Currently supported print systems include:
+ # bsd, sysv, plp, lprng, aix, hpux, qnx
+ ; printing = bsd
+
+ # Enable this to make Samba 2.2 behavior just like Samba 2.0
+ # not recommended nuless you are sure of what you are doing
+ ; disable spoolss = yes
+
+ # list of users and groups which should be able to remotely manage
+ # printer drivers installed on the server
+ ; printer admin = root, +ntadmin
+
+
+##
+## Winbind
+##
+
+ # specify the uid range which can be used by winbindd
+ # to allocate uids for Windows users as necessary
+ ; winbind uid = 10000-65000
+
+ # specify the uid range which can be used by winbindd
+ # to allocate uids for Windows users as necessary
+ ; winbind gid = 10000-65000
+
+ # Define a home directory to be given to passwd(5) style entries
+ # generated by libnss_winbind.so. You can use variables here
+ ; winbind template homedir = /home/%D/%U
+
+ # Specify a shell for all winbind user entries return by the
+ # libnss_winbind.so library.
+ ; winbind template shell = /bin/sh
+
+ # What character should be used to separate the DOMAIN and Username
+ # for a Windows user. The default is DOMAIN\user, but many people
+ # prefer DOMAIN+user
+ ; winbind separator = +
#============================ Share Definitions ==============================
[homes]
- comment = Home Directories
- browseable = no
- writable = yes
+ comment = Home Directories
+ browseable = no
+ writable = yes
+ valid users = %S
# Un-comment the following and create the netlogon directory for Domain Logons
; [netlogon]
-; comment = Network Logon Service
-; path = /usr/local/samba/lib/netlogon
-; guest ok = yes
-; writable = no
-; share modes = no
+; comment = Network Logon Service
+; path = /usr/local/samba/lib/netlogon
+; guest ok = yes
+; writable = no
+; share modes = no
# Un-comment the following to provide a specific roving profile share
@@ -182,23 +254,30 @@
; guest ok = yes
-# NOTE: If you have a BSD-style print system there is no need to
+# NOTE: If you have a BSD-style print system there is no need to
# specifically define each individual printer
[printers]
comment = All Printers
path = /usr/spool/samba
browseable = no
-# Set public = yes to allow user 'guest account' to print
+ # Set public = yes to allow user 'guest account' to print
guest ok = no
writable = no
printable = yes
# This one is useful for people to share files
-;[tmp]
-; comment = Temporary file space
-; path = /tmp
-; read only = no
-; public = yes
+#[tmp]
+# comment = Temporary file space
+# path = /tmp
+# read only = no
+# public = yes
+
+
+# MS-DFS support is only available if Samba was compiled to
+# include --with-msdfs
+;[dfsroot]
+; dfs root = yes
+
# A publicly accessible directory, but read only, except for people in
# the "staff" group
@@ -210,64 +289,67 @@
; printable = no
; write list = @staff
-# Other examples.
-#
+
+##
+## Other examples.
+##
+
# A private printer, usable only by fred. Spool data will be placed in fred's
# home directory. Note that fred must have write access to the spool directory,
# wherever it is.
-;[fredsprn]
-; comment = Fred's Printer
-; valid users = fred
-; path = /homes/fred
-; printer = freds_printer
-; public = no
-; writable = no
-; printable = yes
+#[fredsprn]
+# comment = Fred's Printer
+# valid users = fred
+# path = /homes/fred
+# printer = freds_printer
+# public = no
+# writable = no
+# printable = yes
# A private directory, usable only by fred. Note that fred requires write
# access to the directory.
-;[fredsdir]
-; comment = Fred's Service
-; path = /usr/somewhere/private
-; valid users = fred
-; public = no
-; writable = yes
-; printable = no
+#[fredsdir]
+# comment = Fred's Service
+# path = /usr/somewhere/private
+# valid users = fred
+# public = no
+# writable = yes
+# printable = no
# a service which has a different directory for each machine that connects
# this allows you to tailor configurations to incoming machines. You could
# also use the %U option to tailor it by user name.
# The %m gets replaced with the machine name that is connecting.
-;[pchome]
-; comment = PC Directories
-; path = /usr/pc/%m
-; public = no
-; writable = yes
+#[pchome]
+# comment = PC Directories
+# path = /usr/pc/%m
+# public = no
+# writable = yes
# A publicly accessible directory, read/write to all users. Note that all files
# created in the directory by users will be owned by the default user, so
# any user with access can delete any other user's files. Obviously this
# directory must be writable by the default user. Another user could of course
# be specified, in which case all files would be owned by that user instead.
-;[public]
-; path = /usr/somewhere/else/public
-; public = yes
-; only guest = yes
-; writable = yes
-; printable = no
+#[public]
+# path = /usr/somewhere/else/public
+# public = yes
+# only guest = yes
+# writable = yes
+# printable = no
# The following two entries demonstrate how to share a directory so that two
# users can place files there that will be owned by the specific users. In this
# setup, the directory should be writable by both users and should have the
# sticky bit set on it to prevent abuse. Obviously this could be extended to
# as many users as required.
-;[myshare]
-; comment = Mary's and Fred's stuff
-; path = /usr/somewhere/shared
-; valid users = mary fred
-; public = no
-; writable = yes
-; printable = no
-; create mask = 0765
+#[myshare]
+# comment = Mary's and Fred's stuff
+# path = /usr/somewhere/shared
+# valid users = mary fred
+# public = no
+# writable = yes
+# printable = no
+# create mask = 0765
diff --git a/examples/wins_hook/README b/examples/wins_hook/README
deleted file mode 100644
index 1147f57e22f..00000000000
--- a/examples/wins_hook/README
+++ /dev/null
@@ -1,8 +0,0 @@
-This is an example script for doing dynamic DNS updates from the WINS
-database. You use this by putting the full path to the script in the
-"wins hook" option in smb.conf. Remember to mark the script executable
-and to set the right domain at the top of the script.
-
-See the BIND documentation for how to enable dynamic DNS
-updates. Remember to restrict the updates as far as you can to reduce
-the security risks inherent in dynamic DNS.
diff --git a/examples/wins_hook/dns_update b/examples/wins_hook/dns_update
deleted file mode 100644
index a4c1a79ab9c..00000000000
--- a/examples/wins_hook/dns_update
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-#
-# Example script for "wins hook". This attempts to update the DNS with
-# new A records for the NETBIOS name that Samba passes us. We do this
-# the simple way, by deleting all DNS records for the name and then
-# readding all the expected 'A' records.
-#
-# Written by Stephen Rothwell <sfr@linuxcare.com>
-#
-
-#
-# Configurable things
-#
-# The domain in which to create names
-# YOU MUST CHANGE THIS
-# N.B. include the trailing dot
-#
-# It is a good idea to use a subdomain of your primary domain to ensure
-# that rogue machines can't take over (or delete) important names on
-# your network.
-DOMAIN=wins.example.com.
-
-#
-# The DNS TTL to give the records (in seconds)
-#
-TTL=3600
-#
-# NETBIOS name types that we want to create DNS records for:
-# 20 is server
-# 00 is workstation
-# 03 is user
-#
-USEFUL_TYPES="20 00 03"
-#
-# The name of a cache file to use to avoid continual updates
-# of the same name and IP addresses. If you comment this out
-# then the cache is not kept at all.
-#
-#CACHE_FILE=/usr/local/samba/var/wins_update.cache
-
-if [ $# -lt 4 ]; then
- echo "Usage: $0 op name type ttl [ip_addr ...]" 1>&2
- echo " op is one of add, refresh, delete" 1>&2
- echo " name is the NETBIOS name" 1>&2
- echo " type is the NETBIOS name type" 1>&2
- echo " ttl is the NETBIOS time to live" 1>&2
- echo " ip_addr's are the remaining IP addresses for this name" 1>&2
- exit 1
-fi
-
-NSUPDATE=`which nsupdate`
-[ -x "$NSUPDATE" ] || NSUPDATE=/usr/bin/nsupdate
-[ -x "$NSUPDATE" ] || NSUPDATE=/sbin/nsupdate
-[ -x "$NSUPDATE" ] || NSUPDATE=/usr/sbin/nsupdate
-[ -x "$NSUPDATE" ] || {
- echo "Cannot find nsupdate." 1>&2
- exit 1
-}
-
-OP=$1
-NAME=$2
-TYPE=$3
-WINS_TTL=$4
-shift 4
-IP_ADDRS="$@"
-
-do_update=0
-for i in $USEFUL_TYPES
-do
- [ "$TYPE" = "$i" ] && do_update=1
-done
-[ $do_update = 1 ] || exit 0
-
-if [ -n "$CACHE_FILE" ]; then
- if [ -r "$CACHE_FILE" ]; then
- fgrep -q -x -i "$NAME $IP_ADDRS" "$CACHE_FILE" &&
- exit 0
- grep -v -i "^$NAME " "$CACHE_FILE" >"$CACHE_FILE".$$
- fi
- echo "$NAME $IP_ADDRS" >>"$CACHE_FILE".$$
- mv "$CACHE_FILE" "$CACHE_FILE".old 2>/dev/null
- mv "$CACHE_FILE".$$ "$CACHE_FILE"
-fi
-
-{
- echo update delete $NAME.$DOMAIN
- for i in $IP_ADDRS
- do
- echo update add $NAME.$DOMAIN $TTL A $i
- done
- echo
-} 2>/dev/null | $NSUPDATE >/dev/null 2>&1 &
-
-exit 0
diff --git a/make-tarball.sh b/make-tarball.sh
deleted file mode 100644
index 1eb05db70dc..00000000000
--- a/make-tarball.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-## A simple script to build a tarball of the current CVS tree.
-## You either need to include the using_samba cvs module in the
-## parent directory or tell the script where to find it
-##
-## Usgae: ./make-tarball.sh
-
-USING_SAMBA=../using_samba/
-SRCDIR=`pwd`
-
-if [ ! -d $USING_SAMBA ]; then
-
- echo Cannot find "Using Samba" directory \(assuming $USING_SAMBA\).
- echo Please set the USING_SAMBA variable in this script to the correct
- echo location. The html files are available in the using_samba CVS
- echo module on cvs.samba.org. See http://cvs/samba.org/ for details
- echo about anonymous CVS access. Exiting now....
-
- exit 1
-
-fi
-
-VERSION=`grep SAMBA_VERSION_OFFICIAL_STRING source/include/version.h | cut -d\" -f2 | sed 's/ /_/g'`
-TARBALLDIR=/tmp/samba-$VERSION
-
-echo Creating the tarball source directory in $TARBALLDIR
-
-/bin/rm -rf $TARBALLDIR
-/bin/rm -f samba-$VERSION.tar
-
-mkdir $TARBALLDIR
-rsync -aC ./ $TARBALLDIR
-rsync -aC $USING_SAMBA $TARBALLDIR/docs/htmldocs/
-
-echo Creating packaging scripts...
-( cd $TARBALLDIR/packaging; sh bin/update-pkginfo $VERSION 1 )
-
-echo Creating source/configure...
-( cd $TARBALLDIR/source; ./autogen.sh )
-
-echo Making tarball samba-$VERSION.tar in current directory...
-( cd `dirname $TARBALLDIR`; tar cf $SRCDIR/samba-$VERSION.tar samba-$VERSION )
diff --git a/packaging/Caldera/OpenLinux/README.Public b/packaging/Caldera/OpenLinux/README.Public
new file mode 100755
index 00000000000..00f41f37382
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/README.Public
@@ -0,0 +1,9 @@
+This directory is exported to any windows computer, if the daemon
+"SMB server processes (samba)" is started and the distributed
+configuration is used. So be careful about any data you put into
+this directory.
+
+The default configuration restricts the access rights to read only
+access.
+
+2000-03-13, Klaus Singvogel, Caldera (Deutschland) GmbH.
diff --git a/packaging/Caldera/OpenLinux/README.home b/packaging/Caldera/OpenLinux/README.home
new file mode 100755
index 00000000000..5a893eb0e12
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/README.home
@@ -0,0 +1,15 @@
+This directory $HOME/Samba is exported to any windows computer, if
+the daemon "SMB server processes (samba)" is started and the distributed
+configuration is used. So be careful about the data you put into this
+directory.
+
+Note: Only the user of this account can connect to this share. The
+shares name is equal to the users Linux account, e.g.
+\\your_linuxmachine\\your_linuxaccount
+
+If you want to have the files public accessible use the public browseable
+share instead. It's currently /srv/samba/Public, but have a look at file
+/etc/samba.d/smb.conf to get the latest name.
+
+
+2000-03-13, Klaus Singvogel, Caldera (Deutschland) GmbH.
diff --git a/packaging/Caldera/OpenLinux/README.profiles b/packaging/Caldera/OpenLinux/README.profiles
new file mode 100755
index 00000000000..b629e10966b
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/README.profiles
@@ -0,0 +1,10 @@
+This directory is used to store the roaming Profiles of your Windows
+users. For more information install the package samba-doc and read the
+file /usr/share/doc/packages/samba-2.0.7/docs/textdocs/DOMAIN.txt
+
+The default configuration sets the access rights to read/write for
+anyone. If you see a problem in this, disable the Profiles support in
+your samba configuration: either edit file /etc/samba.d/smb.conf or
+use swat (http://localhost:901/).
+
+2000-03-13, Klaus Singvogel, Caldera (Deutschland) GmbH.
diff --git a/packaging/SGI/findsmb b/packaging/Caldera/OpenLinux/findsmb
index 336ff07c16f..04bc6080508 100755
--- a/packaging/SGI/findsmb
+++ b/packaging/Caldera/OpenLinux/findsmb
@@ -1,4 +1,4 @@
-#!/bin/perl
+#!/usr/bin/perl
#
# Prints info on all smb responding machines on a subnet.
# This script needs to be run on a machine without nmbd running and be
@@ -15,7 +15,7 @@
# that workgroup.
#
-$SAMBABIN = "/usr/samba/bin";
+$SAMBABIN = "/usr/bin";
for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
$_ = shift;
@@ -63,7 +63,7 @@ foreach $ip (@ipaddrs) # loop through each IP address found
# get the first <00> name
- @name = grep(/<00> - /,@nmblookup);
+ @name = grep(/<00>/,@nmblookup);
$_ = @name[0];
if ($_) { # we have a netbios name
if (/GROUP/) { # is it a group name
@@ -73,6 +73,9 @@ foreach $ip (@ipaddrs) # loop through each IP address found
$name = "unknown nis name";
}
} else {
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cure inside name space but not
+# names starting or ending with spaces
/(.{1,15})\s+<00>\s+/;
$name = $1;
}
@@ -95,7 +98,7 @@ foreach $ip (@ipaddrs) # loop through each IP address found
@info = grep(/OS=/,@smb);
$_ = @info[0];
if ($_) { # we found response
- s/.*Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
} else { # no OS= string in response (WIN95 client)
@@ -103,6 +106,7 @@ foreach $ip (@ipaddrs) # loop through each IP address found
@name = grep(/<00> - <GROUP>/,@nmblookup);
$_ = @name[0];
if ($_) {
+# Same as before for space and characters
/(.{1,15})\s+<00>\s+/;
$_ = "[$1]";
} else {
diff --git a/packaging/Caldera/OpenLinux/kanji-makefile.patch b/packaging/Caldera/OpenLinux/kanji-makefile.patch
new file mode 100755
index 00000000000..b0b39777c92
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/kanji-makefile.patch
@@ -0,0 +1,11 @@
+--- source/Makefile.orig Tue Jan 15 23:14:29 2002
++++ source/Makefile Tue Jan 15 23:12:13 2002
+@@ -12,7 +12,7 @@
+ LIBS=-lcups -ldl -lnsl -lpam
+ CC=gcc
+ SHLD=${CC}
+-CFLAGS=-O -O2 -m486 -fno-strength-reduce
++CFLAGS=-O -O2 -m486 -fno-strength-reduce -DKANJI=\"sjis\"
+ CPPFLAGS=-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ LDFLAGS=-s
+ AWK=mawk
diff --git a/packaging/Caldera/OpenLinux/makerpms.sh.tmpl b/packaging/Caldera/OpenLinux/makerpms.sh.tmpl
new file mode 100755
index 00000000000..5f6e76c75a0
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/makerpms.sh.tmpl
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Copyright (C) 1998 John H Terpstra, 2000 Klaus Singvogel
+#
+SPECDIR=${SPECDIR:-/usr/src/OpenLinux/SPECS}
+SRCDIR=${SRCDIR:-/usr/src/OpenLinux/SOURCES}
+USERID=`id -u`
+GRPID=`id -g`
+devel=0;
+old=0;
+
+# Do some argument parsing...
+if [ z$1 = z"devel" ]; then
+ devel=1;
+ shift
+fi
+if [ z$1 = z"old" ]; then
+ old=1;
+ shift
+fi
+if [ z$1 = z"team" ]; then
+ team=1;
+ shift
+fi
+
+# Start preparing the packages...
+if [ $devel -ne 0 ]; then
+ ( cd ../../../.. ; chown -R ${USERID}.${GRPID} samba; mv samba samba-PVERSION )
+ ( cd ../../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION; mv samba-PVERSION samba )
+else
+ ( cd ../../../.. ; chown -R ${USERID}.${GRPID} samba-PVERSION )
+ ( cd ../../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION )
+fi
+
+cp -af *.spec *.spec-lsb $SPECDIR
+if [ $team -ne 0 ]; then
+ cp *.spec-team $SPECDIR
+fi
+for i in `ls *.patch`
+do
+ cp $i $SRCDIR/
+done
+# Start building the package
+cd $SPECDIR
+if [ $old -eq 0 ]; then
+mv -f samba2.spec samba2.spec-nonlsb
+ln -f samba2.spec-lsb samba2.spec
+fi
+if [ $team -ne 0 ]; then
+ mv -f samba2.spec samba2.spec-lsb
+ ln -f samba2.spec-team samba2.spec
+ rpm -ba -v samba2.spec
+else
+ rpm -ba -v --rmsource --clean samba2.spec
+fi
diff --git a/packaging/Caldera/OpenLinux/samba-2.2.2-libsmbclient.patch b/packaging/Caldera/OpenLinux/samba-2.2.2-libsmbclient.patch
new file mode 100755
index 00000000000..d232871316e
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba-2.2.2-libsmbclient.patch
@@ -0,0 +1,12 @@
+--- samba-2.2.2/source/Makefile.in.orig Wed Oct 10 08:13:13 2001
++++ samba-2.2.2/source/Makefile.in Wed Oct 10 08:16:46 2001
+@@ -608,7 +608,8 @@
+
+ libsmbclient: $(LIBSMBCLIENT_PICOBJS)
+ @echo Linking libsmbclient shared library bin/$@.@SHLIBEXT@
+- @$(SHLD) @LDSHFLAGS@ -o bin/$@.@SHLIBEXT@ \
++ @$(SHLD) @LDSHFLAGS@ -o bin/$@.@SHLIBEXT@ \
++ -Wl,-soname,libsmbclient.so.$(LIBSMBCLIENT_MAJOR) \
+ $(LIBSMBCLIENT_PICOBJS) $(LIBS)
+ @echo Linking libsmbclient non-shared library bin/$@.a
+ @-$(AR) -rc bin/$@.a $(LIBSMBCLIENT_PICOBJS)
diff --git a/packaging/Caldera/OpenLinux/samba.daemon b/packaging/Caldera/OpenLinux/samba.daemon
new file mode 100755
index 00000000000..78c357005e9
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba.daemon
@@ -0,0 +1,7 @@
+IDENT=samba
+DESCRIPTIVE="SMB server processes (samba)"
+CONFIGURED="no"
+ONBOOT="no"
+OPTIONS_SMB="-D"
+OPTIONS_NMB="-D"
+OPTIONS_WINBD=""
diff --git a/packaging/Caldera/OpenLinux/samba.init b/packaging/Caldera/OpenLinux/samba.init
new file mode 100755
index 00000000000..37955e15558
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba.init
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# description: Starts and stops the Samba smbd and nmbd daemons
+# used to provide SMB network services.
+
+NAME_S=smbd
+DAEMON_S=/usr/sbin/$NAME_S
+NAME_N=nmbd
+DAEMON_N=/usr/sbin/$NAME_N
+NAME_W=winbindd
+DAEMON_W=/usr/sbin/winbindd
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# See how we were called.
+case "$1" in
+ start)
+ [ -e $SVIlock ] && exit 1
+ [ ${NETWORKING} = "no" ] && exit 2
+ [ -x $DAEMON_S -a -x $DAEMON_N ] || exit 2
+
+ #[ "$CONFIGURED" != "no" -a "$CONFIGURED" != "false" ] || {
+ SVIemptyConfig /etc/samba.d/smb.conf && {
+ echo "$DESCRIPTIVE: not configured! Skipped..."
+ exit 2
+ }
+
+ echo -n "Starting $IDENT: "
+ ssd -S -n $NAME_S -x $DAEMON_S -- $OPTIONS_SMB
+ ssd -S -n $NAME_N -x $DAEMON_N -- $OPTIONS_NMB
+ ssd -S -n $NAME_W -x $DAEMON_W -- $OPTIONS_WINBD
+
+ echo "."
+ touch $SVIlock
+ ;;
+
+ stop)
+ [ -e $SVIlock ] || exit 0
+
+ echo -n "Stopping $IDENT: "
+ ssd -K -p /var/lock/samba.d/$NAME_W.pid -n $NAME_W #-x $DAEMON_W
+ ssd -K -p /var/lock/samba.d/$NAME_N.pid -n $NAME_N #-x $DAEMON_N
+ ssd -K -p /var/lock/samba.d/$NAME_S.pid -n $NAME_S #-x $DAEMON_S
+
+ echo "."
+ rm -f $SVIlock
+ ;;
+
+ restart)
+ echo -n "Restarting $IDENT: "
+ $0 stop
+ $0 start
+ exit $?
+ ;;
+
+ *)
+ echo "Usage: $SVIscript {start|restart|stop}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/packaging/Caldera/OpenLinux/samba.init-lsb b/packaging/Caldera/OpenLinux/samba.init-lsb
new file mode 100755
index 00000000000..80913c3340e
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba.init-lsb
@@ -0,0 +1,144 @@
+#!/bin/bash
+#
+#
+### BEGIN INIT INFO
+# Provides: $samba
+# Required-Start: $network
+# Required-Stop: $network
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Description: samba
+# Starts and stops the Samba smbd and nmbd daemons
+# used to provide SMB network services.
+### END INIT INFO
+#
+# Written by Miquel van Smoorenburg <miquels@drinkel.ow.org>.
+# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Modified for OpenLinux by Raymund Will <ray@caldera.de>
+# Adapted for samba by Klaus Singvogel <klaus@caldera.de>
+
+NAME_S=smbd
+DAEMON_S=/usr/sbin/$NAME_S
+NAME_N=nmbd
+DAEMON_N=/usr/sbin/$NAME_N
+NAME_W=winbindd
+DAEMON_W=/usr/sbin/$NAME_W
+
+config_file=/etc/samba.d/smb.conf
+
+# Source function library (and set vital variables).
+. @SVIdir@/functions
+
+status() {
+ [ -e $1 ] || return 3; # lock / pid file doesn't exist, seems to be stopped
+
+ i=`cat "$1"`
+ state=`egrep '^State' /proc/$i/status 2>/dev/null| sed 's#.* \(.\).*#\1#'`
+ if [ x$state = x -o x$state = xZ ]; then
+ return 2 # no such process (or zombie) --> dead
+ fi
+ return 0 # seems to be up and running
+}
+
+WinbdConfig() {
+ # returns 0 if winbindd is not configured,
+ # and 1 if winbindd is configured.
+
+ local config_file=$1; shift # file to check
+
+ # check if "winbind uid" is set in samba config file
+ egrep -q '[^#]*winbind uid' $config_file || return 0
+
+ found=0;
+ # We also need to check if least one PAM module control file does
+ # NOT have pam_winbind.so commented out
+ for i in /etc/pam.d/*; do
+ if [ ! -f $i ]; then next; fi
+ egrep -q '[^#]*pam_winbind.so' $i && found=1 && break;
+ done
+
+ if [ $found != 0 ]; then
+ # if so, ensure that in /etc/nsswitch.conf we have for
+ # "passwd", "shadow", "group" an entry for "winbind"
+ egrep -q '^passwd:.*winbind' /etc/nsswitch.conf && return 1
+ egrep -q '^shadow:.*winbind' /etc/nsswitch.conf && return 1
+ egrep -q '^group:.*winbind' /etc/nsswitch.conf && return 1
+ fi
+
+ return 0
+}
+
+case "$1" in
+ start)
+ [ ! -e $SVIlock ] || exit 0
+ [ -x $DAEMON_S -a -x $DAEMON_N ] || exit 5
+ SVIemptyConfig $config_file && exit 6
+
+ echo -n "Starting $SVIsubsys services: "
+ ssd -S -n $NAME_S -x $DAEMON_S -- $OPTIONS_SMB
+ WinbdConfig $config_file || SVIstatus winbindd || ssd -S -n $NAME_W -x $DAEMON_W -- $OPTIONS_WINBD
+ ssd -S -n $NAME_N -x $DAEMON_N -- $OPTIONS_NMB
+ ret=$?
+
+ echo "."
+ touch $SVIlock
+ ;;
+
+ stop)
+ [ -e $SVIlock ] || exit 0
+
+ echo -n "Stopping $SVIsubsys services: "
+ ssd -K -p /var/lock/samba.d/$NAME_S.pid -n $NAME_S #-x $DAEMON_S
+ ssd -K -p /var/lock/samba.d/$NAME_W.pid -n $NAME_W #-x $DAEMON_W
+ ssd -K -p /var/lock/samba.d/$NAME_N.pid -n $NAME_N #-x $DAEMON_N
+
+ ret=$?
+
+ echo "."
+ rm -f $SVIlock
+ ;;
+
+ force-reload)
+ [ -e $SVIlock ] || exit 0
+ $0 restart
+ ret=$?
+ ;;
+
+ reload)
+ echo -n "Reloading $SVIsubsys service configuration: "
+ # nmbd has no config file to reload
+ ssd -K --signal 1 -p /var/lock/samba.d/$NAME_N.pid -n $NAME_N #-x $DAEMON_N
+ ssd -K --signal 1 -p /var/lock/samba.d/$NAME_W.pid -n $NAME_W #-x $DAEMON_W
+ ssd -K --signal 1 -p /var/lock/samba.d/$NAME_S.pid -n $NAME_S #-x $DAEMON_S
+ ret=$?
+ echo "."
+ ;;
+
+ restart)
+ $0 stop
+ $0 start
+ ret=$?
+ ;;
+
+ status)
+ echo -n "Checking status of $SVIsubsys service: "
+ status /var/lock/samba.d/$NAME_N.pid
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo -n "$NAME_N "
+ status /var/lock/samba.d/$NAME_S.pid
+ ret=$?
+ [ $ret -eq 0 ] && echo -n "$NAME_S"
+ fi
+ echo "."
+ ;;
+
+ *)
+ echo "Usage: $SVIscript {start|stop|restart|force-reload|reload|status}"
+ ret=2
+ ;;
+
+esac
+
+exit $ret
+
diff --git a/packaging/Caldera/OpenLinux/samba.logrotate b/packaging/Caldera/OpenLinux/samba.logrotate
new file mode 100755
index 00000000000..46611f83d8f
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba.logrotate
@@ -0,0 +1,12 @@
+/var/log/samba.d/nmbd {
+ postrotate
+ /usr/bin/killall -HUP nmbd
+ endscript
+}
+
+/var/log/samba.d/smbd {
+ postrotate
+ /usr/bin/killall -HUP smbd
+ endscript
+}
+
diff --git a/packaging/Caldera/OpenLinux/samba.pam b/packaging/Caldera/OpenLinux/samba.pam
new file mode 100755
index 00000000000..821c9046a6f
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba.pam
@@ -0,0 +1,49 @@
+#%PAM-1.0
+#[For version 1.0 syntax, the above header is optional]
+#
+# The PAM configuration file for the `samba' service
+#
+# Note: Only one section should be active at a time.
+# Uncomment only those features needed. The default is a minimal implementation.
+#
+# --------------------------------------------------------------------------------
+# This example uses the standard System Files (/etc/passwd,/etc/shadow,/etc/group)
+# and uses a very vanila PAM configuration
+#
+# auth requisite pam_securetty.so
+# auth requisite pam_nologin.so
+# auth optional pam_env.so
+auth required pam_pwdb.so nullok nodelay # audit
+account required pam_pwdb.so nodelay # audit
+# session required pam_mkhomedir.so
+session required pam_pwdb.so nodelay
+password required pam_pwdb.so nodelay # shadow md5 audit
+#
+# --------------------------------------------------------------------------------
+# This example uses PAM smbpass
+#
+# auth requisite pam_securetty.so
+# auth requisite pam_nologin.so
+# auth optional pam_env.so
+# auth required pam_smbpass.so nodelay
+# account required pam_pwdb.so nodelay # audit
+# account sufficient pam_winbind.so
+# session required pam_mkhomedir.so
+# session required pam_pwdb.so nodelay
+# password required pam_pwdb.so shadow md5
+# password required pam_smbpass.so nodelay smbconf=/etc/samba.d/smb.conf
+#
+# --------------------------------------------------------------------------------
+# This example uses PAM WinBind
+#
+# auth requisite pam_securetty.so
+# auth requisite pam_nologin.so
+# auth optional pam_env.so
+# auth sufficient pam_winbind.so
+# auth sufficient pam_pwdb.so shadow nullok use_first_pass
+# account required pam_pwdb.so nodelay # audit
+# account sufficient pam_winbind.so
+# session required pam_mkhomedir.so
+# session required pam_pwdb.so nodelay
+# password required pam_pwdb.so shadow md5
+#
diff --git a/packaging/Caldera/OpenLinux/samba2.spec-lsb.tmpl b/packaging/Caldera/OpenLinux/samba2.spec-lsb.tmpl
new file mode 100755
index 00000000000..2b8bba8fb29
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba2.spec-lsb.tmpl
@@ -0,0 +1,555 @@
+%define Version PVERSION
+%define date PRELEASE
+%define Vendor Caldera
+%define Dist OpenLinux
+%define EtcSamba /etc/samba.d
+%define LSBservedir /srv/samba
+
+Name : samba
+Version : %{Version}
+Release : %{date}
+Group : Server/Network
+
+Summary : Samba SMB client and server.
+Summary(de) : Samba SMB Client und Server.
+Summary(es) : Cliente y servidor SMB Samba.
+Summary(fr) : Client et serveur SMB Samba.
+Summary(it) : Client e server SMB.
+Summary(pt) : Cliente e servidor SMB Samba.
+
+Copyright : Andrew Tridgell, John H Terpstra; GPL
+Packager : Klaus Singvogel <klaus@caldera.de>
+#Icon : Caldera-daemon.gif
+URL : http://samba.org/samba
+
+Requires : libpam >= 0.66, SysVinit-scripts >= 1.04-6
+
+
+BuildRoot : /tmp/%{Name}-%{Version}
+
+Source: ftp://ftp.samba.org/pub/samba/%{Name}-%{Version}.tar.gz
+
+%Package doc
+Group : Server/Network
+
+Summary : Documentation on SAMBA.
+Summary(de) : Die Dokumentation für Samba.
+Summary(es) : Documentation de SAMBA.
+Summary(fr) : Documentation pour Samba.
+Summary(it) : Documentazione su SAMBA.
+Summary(pt) : Documentação sobre o SAMBA.
+
+%Package -n smbfs
+Group : System/Network
+
+Summary : Mount and unmount commands for SMB filesystems (smbfs).
+Summary(de) : Mount und unmount für SMB-Dateisysteme (smbfs).
+Summary(es) : Comandos de montaje y desmontaje de sistemas de ficheros SMB (smbfs).
+Summary(fr) : Commandes pour le montage et le démontage des systèmes de fichiers SMB (smbfs).
+Summary(it) : Comandi per montare e smontare i file system SMB (smbfs).
+Summary(pt) : Comandos mount e unmount para o sistema de ficheiros SMB (smbfs).
+
+%Package -n swat
+Group : Administration/Network
+Requires : setup >= 2.0-2, tcp_wrappers, netkit-base >= 0.17-5
+
+Summary : Samba Web Administration Tool.
+Summary(de) : Das Samba Web Administrationstool.
+Summary(es) : Utilidad de administración Samba.
+Summary(fr) : Outil d'administration Internet pour Samba.
+Summary(it) : Strumento per l'amministrazione di Samba via Web.
+Summary(pt) : Ferramenta Web de administração de Samba (Samba Web Administration Tool).
+
+%Package -n libsmbclient
+Group : System/Network
+
+Summary : Samba Client Library.
+
+
+%Description
+Samba provides an SMB server which can be used to provide network
+services to SMB (sometimes called "Lan Manager") clients, including
+various versions of MS Windows, OS/2, and other Linux machines.
+
+%Description -l de
+Samba stellt einen SMB Server zur Verfügung, mit dem Netzwerkdienste für SMB
+(auch "Lan Manager" genannt) Clients bereitgestellt werden können. Dies
+schließt verschiedene Versionen von MS Windows, OS/2 und andere Linux
+Maschinen ein.
+
+%Description -l es
+Samba dispone de un servidor SMB que puede utilizarse para proporcionar
+servicios de red a clientes SMB (a veces conocido como "Lan Manager"),
+incluyendo varias versiones de MS Windows, OS/2 y otras máquinas Linux.
+
+%Description -l fr
+Samba fournit un serveur SMB qui peut être utilisé pour fournir des services
+de réseau aux clients SMB (parfois appelés "Lan Manager"), comportant
+diverses versions de MS Windows, OS/2 et d'autres machines Linux.
+
+%Description -l it
+Samba fornisce un server SMB che può essere usato per fornire servizi
+di rete a client SMB (talvolta chiamato "Lan Manager"), comprese varie
+versioni di MS Windows, OS/2 e altre macchine Linux.
+
+%Description -l pt
+O Samba fornece um servidor de SMB que pode ser usado para fornecer serviços de
+rede aos clientes de SMB (denominado por vezes como "Lan Manager"), incluindo
+várias versões do Windows, OS/2 e outras máquinas Linux.
+
+%Description doc
+This package contains extensive SAMBA documentation, including a FAQ,
+comprehensive usage documentation, and a number of examples.
+
+%Description -l de doc
+Dieses Paket enthält eine ausführliche SAMBA Dokumentation, inklusive
+einer FAQ, umfassender Gebrauchsdokumentation und einer Reihe von
+Beispielen.
+
+%Description -l es doc
+Este paquete contiene una extensa documentación sobre SAMBA, incluyendo
+FAQ (Preguntas de Uso Frecuente), documentación sobre el uso y algunos
+ejemplos.
+
+%Description -l fr doc
+Ce paquetage contient une documentation complète sur Samba, y compris
+une FAQ détaillée de son utilisation et un certain nombre d'exemples.
+
+%Description -l it doc
+Questo pacchetto contiene la documentazione su SAMBA tra cui una FAQ
+una esaustiva documentazione d'uso e un certo numero di esempi.
+
+%Description -l pt doc
+Este pacote contém alguma documentação extensa sobre o SAMBA, incluindo a FAQ,
+alguma documentação compreensiva sobre a utilização e alguns exemplos.
+
+%Description -n smbfs
+This package includes the tools necessary to mount filesystems from
+SMB servers.
+
+%Description -l de -n smbfs
+Dieses Paket enthält die nötigen Tools, um Dateisysteme von SMB-Servern
+zu mounten.
+
+%Description -l es -n smbfs
+este paqeute incluye las herramientas necesarias para montar sistemas de
+ficheros de servidores SMB.
+
+%Description -l fr -n smbfs
+Ce paquetage contient les outils nécessaires pour monter des systèmes
+de fichiers sur des serveurs SMB.
+
+%Description -l it -n smbfs
+Questo pacchetto contiene gli strumenti necessari per montare filesystem
+da server SMB.
+
+%Description -l pt -n smbfs
+Este pacote contém as ferramentas necessárias para montar sistema de
+ficheiros de servidores SMB.
+
+%Description -n swat
+SWAT allows a Samba administrator to configure the complex smb.conf
+file via a Web browser. It also provides links to all the configurable
+options in the smb.conf file allowing an administrator to easily look
+up the effects of any change.
+
+%Description -l de -n swat
+Mit SWAT kann ein Samba-Administrator die komplexe smb.conf
+Datei mit Hilfe eines Web-Browsers konfigurieren. Es stellt auch Links zu
+allen konfigurierbaren Optionen in der smb.conf Datei bereit, wodurch ein
+Administrator die Auswirkungen einer Änderung leicht nachvollziehen kann.
+
+%Description -l es -n swat
+SWAT permite a un administrador de Samba configurar el complejo fichero
+smb.conf mediante una navegador web. También proporciona enlaces a todas las
+opciones configurables en el fichero smb.conf, permitiendo al administrador
+comprobar fácilmente los efectos de cualquier cambio.
+
+%Description -l fr -n swat
+SWAT permet à un administrateur Samba de configurer le fichier smb.conf
+complexe via un navigateur Web. Il fournit également des liens d'aide pour
+toutes les options configurables dans le fichier smb.conf permettant à un
+administrateur de consulter aisément les effets d'une modification.
+
+%Description -l it -n swat
+SWAT permette ad un amministratore Samba di configurare il complesso file
+smb.conf attraverso un browser Web. SWAT ha anche dei link di aiuto per
+tutte le opzioni di configurazione del file smb.conf.
+
+%Description -l pt -n swat
+O SWAT permite a um administrador de Samba configurar o complexo ficheiro
+smb.conf através de uma interface Web. Fornece também referências para
+todas as opções configuraveis no smb.conf, permitindo a um admnistrador
+verificar rapidamente o efeite de qualquer alteração.
+
+%Description -n libsmbclient
+SMB Client Library allows for POSIX like SMB client calls providing developers
+a clean and stable API for SMB client application development.
+
+%Prep
+%setup
+
+# instead of patch (to help configuration) ... ;^)
+%{fixUP} -vbT source/Makefile.in -e '
+ s:we don.t use sbindir because we want:if you want : +
+ s:(the previous releases of Samba):$1, please use: +
+ s:(SBINDIR\s*=\s*\@)b:# ./configure --sbindir=\\\$(BINDIR)\n${1}sb: +
+ s:/log\.(\S+):/log/samba.d/${1}d: +
+ s:(PASSWD_PROGRAM\s*=\s*)(/bin):$1/usr$2:
+'
+# s:^(LIBS\s*=):AUTH_$1: +
+# s:((CLIENT|CUPS|NMBD|SMBD|SWAT|RPCCLIENT|SMBPASSWD|STATUS|TESTPRNS|TESTPARM)_OBJ\) )(\$\(LDF):$1\$(AUTH_LIBS) $3:
+
+for i in {cvs.,change-}log; do [ ! -f ../$i ] || mv ../$i source; done
+
+mv swat/help/welcome.html docs
+%{fixUP} -vT docs -e '
+ s:/usr/local/samba/bin/(smb(client|run)):/usr/bin/$1:g +
+ s:/usr/local/samba/bin/((s|n)mbd|swat|smbstatus):/usr/sbin/$1:g +
+ s:/usr/local/samba/var/locks:/var/lock/samba.d: +
+ s:/usr/local/samba/(var|lib)/log:/var/log/samba.d/smb: +
+ s:/usr/local/samba/swat:/usr/share/samba/swat:g +
+ s:/usr/local/samba/lib:%{EtcSamba}:g +
+ s:/usr/local/samba/printers:/var/spool/samba:g +
+ s:/usr/local/samba/private/smbpasswd:/usr/bin/smbpasswd:g +
+ s:/usr/local/samba/netlogon:%{LSBservedir}/netlogon:g;
+'
+mv docs/welcome.html swat/help
+for i in docs/*/smb.conf.5*; do
+ %{fixUP} -vT $i -e '
+ s:users\.map:smbusers:g +
+ s:SAMBA_INSTALL_DIRECTORY/lib:%{EtcSamba}: +
+ s:None \(set in compile\)\.:(see above).: +
+ s:/usr/local/:/usr/:g;
+ '
+done
+%{fixUP} -vT docs/textdocs/Faxing.txt -e '
+ s:/usr/local/etc/:/etc/: +
+ s:/usr/local/:/usr/:;
+'
+# ENCRYPTION.txt is gone.
+%{fixUP} -vT docs/docbook/projdoc/ENCRYPTION.sgml -e '
+ s:/usr/local/samba/private:%{EtcSamba}:g +
+ s:mksmbpasswd.sh:mksmbpasswd:g +
+ s:the Samba source directory:/usr/bin:;
+'
+
+%{fixUP} -vT docs/htmldocs/make_smbcodepage.1.html -e '
+ s:/usr/local/samba:/usr/bin/:g;
+'
+for i in htmldocs/DOMAIN_MEMBER.html htmldocs/Samba-HOWTO-Collection.html \
+ htmldocs/smbclient.1.html htmldocs/smbd.8.html \
+ docbook/projdoc/DOMAIN_MEMBER.sgml docbook/projdoc/DOMAIN_MEMBER.sgml \
+ docbook/manpages/smbclient.1.sgml docbook/manpages/smbd.8.sgml \
+ docbook/projdoc/ENCRYPTION.sgml manpages/smbclient.1 manpages/smbd.8 ; do
+%{fixUP} -vT docs/$i -e '
+ s:/usr/local/samba/private/FOREST.SLEEPY.SID:/var/lock/samba.d/FOREST.SLEEPY.SID: +
+ s:/usr/local/samba/private:/usr/bin:g +
+ s:/usr/local/samba/bin:/usr/bin:g +
+ s:/usr/local/sbin:/usr/sbin:g +
+ s:/usr/local/src/samba:/usr/src/samba:g ;'
+done
+%{fixUP} -vT docs/docbook/manpages/make_smbcodepage.1.sgml -e '
+ s:/usr/local/samba:/usr/bin:g ;
+'
+# End of DirtyHack(TM)
+
+
+%Build
+cd source
+#autoreconf
+
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}' \
+ --with-privatedir='$(LIBDIR)' \
+ --with-lockdir='$(DESTDIR)/var/lock/samba.d' \
+ --with-piddir='$(DESTDIR)/var/run/samba' \
+ --with-swatdir='$(DESTDIR)/usr/share/swat' \
+ --with-sambabook='$(DESTDIR)/usr/share/swat/using_samba' \
+ --with-configdir='$(DESTDIR)'%{EtcSamba} \
+ --with-codepagedir='$(DESTDIR)'/usr/share/samba/codepages \
+ --without-smbwrapper \
+ --with-libsmbclient \
+ --with-smbmount \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-quotas \
+ --with-utmp \
+ --with-winbind \
+ --with-syslog
+# The following will go back later - JHT
+# --with-tdbsam
+
+make LOGFILEBASE=/var/log/samba.d all nsswitch/libnss_wins.so debug2html bin/smbspool
+
+# Now build the VFS modules
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}'
+cd block
+mv block.c block.c.old
+sed 's/etc\/samba/etc\/samba\.d\/vfs/g' < block.c.old > block.c
+cd ..
+make
+
+
+%Install
+%{mkDESTDIR}
+VVS=packaging/%{Vendor}/%{Dist}
+
+mkdir -p $DESTDIR/etc/{{logrotate,pam}.d,sysconfig/daemons}
+mkdir -p $DESTDIR/var/{lo{ck,g}/samba.d,spool/samba,run/samba}
+mkdir -p $DESTDIR/usr/share/swat/using_samba/{gifs,figs}
+mkdir -p $DESTDIR/lib/security
+mkdir -p $DESTDIR/%{LSBservedir}/{netlogon,profiles,Public}
+mkdir -p $DESTDIR/etc/skel/Samba
+mkdir -p $DESTDIR/usr/share/samba/codepages/src $DESTDIR/sbin
+mkdir -p $DESTDIR/%{SVIdir}
+mkdir -p $DESTDIR/usr/{include,lib/samba/vfs}
+
+make LOGFILEBASE=/var/log/samba.d -C source install
+
+strip $DESTDIR/usr/bin/smb{mnt,umount}
+#mv $DESTDIR/usr/bin/{make,add,conv}* $DESTDIR/usr/bin
+
+cp -p source/codepages/codepage_def.??? $DESTDIR/usr/share/samba/codepages/src
+
+# Install the nsswitch library extension file
+install -m 755 source/nsswitch/libnss_wins.so $DESTDIR/lib/libnss_wins.so.2.0
+# Make link for wins resolver
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so.2
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so
+
+# Add PAM smbpass and winbind facilities
+install -m 755 source/bin/pam_smbpass.so $DESTDIR/lib/security
+install -m 755 source/nsswitch/libnss_winbind.so $DESTDIR/lib/libnss_winbind.so.2.0
+
+# Make link for winbind resolver
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so.2
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so
+
+# Adding VFS modules
+install -m 755 examples/VFS/audit.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.conf $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/skel.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/block/block.so $DESTDIR/usr/lib/samba/vfs
+install -m 644 examples/VFS/block/samba-block.conf $DESTDIR/etc/samba.d/samba-block.conf.example
+install -m 644 examples/VFS/block/smb.conf $DESTDIR/etc/samba.d/smb.conf.example-with-block-use
+
+install -m 755 source/nsswitch/pam_winbind.so $DESTDIR/lib/security
+install -m 755 source/bin/wbinfo $DESTDIR/usr/bin
+install -m 755 source/bin/debug2html $DESTDIR/usr/sbin/debug2html
+
+install -m 755 source/bin/libsmbclient.so $DESTDIR/usr/lib
+install -m 755 source/bin/libsmbclient.a $DESTDIR/usr/lib
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0.1
+install -m 644 source/include/libsmbclient.h $DESTDIR/usr/include
+
+cp -p $VVS/smb.conf.sample $DESTDIR%{EtcSamba}/smb.conf.sample
+cp -p $VVS/smb.conf $DESTDIR%{EtcSamba}/smb.conf
+cp -p $VVS/smbusers $DESTDIR%{EtcSamba}
+cp -p $VVS/smbprint $DESTDIR/usr/bin
+
+cp -p $VVS/smbadduser $DESTDIR/usr/bin/smbadduser
+#cp -p $VVS/make_smbpasswd.perl $DESTDIR/usr/bin/make_smbpasswd
+#cp -p $VVS/convertsmbpasswd.perl $DESTDIR/usr/bin/convertsmbpasswd
+#cp -p $VVS/updatesmbpasswd.perl $DESTDIR/usr/bin/updatesmbpasswd
+
+cp -p $VVS/samba.daemon $DESTDIR/etc/sysconfig/daemons/samba
+cp -p $VVS/winbind.daemon $DESTDIR/etc/sysconfig/daemons/winbind
+cp -p $VVS/samba.pam $DESTDIR/etc/pam.d/samba
+cp -p $VVS/samba.logrotate $DESTDIR/etc/logrotate.d/samba
+cp -p $VVS/README.home $DESTDIR/etc/skel/Samba/README.txt
+cp -p $VVS/README.Public $DESTDIR/%{LSBservedir}/Public/README.txt
+cp -p $VVS/README.profiles $DESTDIR/%{LSBservedir}/profiles/README.txt
+
+
+#lsb: cp -p $VVS/samba.init $DESTDIR/etc/rc.d/init.d/samba
+install -m 755 $VVS/samba.init-lsb $DESTDIR/%{SVIdir}/samba
+install -m 755 $VVS/winbind.init $DESTDIR/%{SVIdir}/winbind
+ln -s /etc/rc.d/init.d/samba $DESTDIR/usr/sbin
+
+for f in testparm testprns; do
+ ln -s $f $DESTDIR/usr/bin/smb$f
+ ln -s $f.1 $DESTDIR/usr/man/man1/smb$f.1
+done
+
+#ln -s make_smbcodepage $DESTDIR/usr/bin/mksmbcodepage
+#ln -s make_smbpasswd $DESTDIR/usr/bin/mksmbpasswd
+#ln -sf convert_smbpasswd $DESTDIR/usr/bin/convertsmbpasswd
+
+ln -s ../usr/bin/smbmount $DESTDIR/sbin/mount.smbfs
+
+
+cat <<-'EoH' > $DESTDIR%{EtcSamba}/lmhosts
+ 127.0.0.1 localhost
+EoH
+
+# lsb has new way of inetd configuration
+mkdir -p $DESTDIR%{NKinetdir}
+cat <<EoI >$DESTDIR%{NKinetdir}/swat
+swat stream tcp nowait.400 root /usr/sbin/tcpd swat
+EoI
+
+pushd $DESTDIR/usr/sbin
+rm -f *.so
+popd
+
+# -------------------- Documentation -------------------------------
+DOCD="$DESTDIR/%{_defaultdocdir}/samba-%{Version}"; mkdir -p $DOCD
+ln -sf ../Copyrights/GPL-2.0 $DOCD/COPYING
+
+#cp -p README README-smbmount Manifest Read-Manifest-Now $DOCD
+
+cp -p README Manifest Read-Manifest-Now $DOCD
+cp -p WHATSNEW.txt Roadmap $DOCD
+cp -a docs examples $DOCD
+
+mv $DOCD/docs/htmldocs/wfw_slip.htm $DOCD/docs/wfw_slip.html
+
+rm -rf $DOCD/docs/{htmldocs,manpages,yodldocs}
+rm -rf $DOCD/examples/{svr4-startup,printing}
+rm -rf $DOCD/CVS $DOCD/*/CVS $DOCD/*/*/CVS $DOCD/*/*/*/CVS
+
+cp -p swat/README $DOCD/README.swat
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/gifs
+done
+
+# -------------------- Fixing final pathes -------------------------------
+
+%{fixUP} -T $DESTDIR/%{SVIdir} -e 's:\@SVIdir\@:%{SVIdir}:'
+%{fixUP} -vT $DOCD/examples -e 's:/usr/local/bin/:/usr/bin/:g;'
+%{fixUP} -vT $DESTDIR/%{EtcSamba} -e 's:\@samba_home\@:%{LSBservedir}:'
+
+%{fixManPages}
+
+%{mkLists} -c samba
+cat << 'EOF' | %{mkLists} -d samba
+Samba base
+/lib/$ base
+/usr/lib/samba/$ base
+%{LSBservedir} config-IGNORED
+^/(etc|var|home|tmp) config-IGNORED
+swat swat
+%{_defaultdocdir}/samba-[^/]+/$ base
+%{_defaultdocdir}/samba- doc
+tmp IGNORED
+man IGNORED
+/src/$ IGNORED
+/usr/private/$ IGNORED
+@default@
+EOF
+cat << 'EOF' | %{mkLists} -f -a samba
+\.old$ IGNORED
+Samba/README.txt base
+^/etc config-IGNORED
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+libnss_* base
+pam_* base
+winbind* base
+/usr/lib/samba/* base
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+%{_defaultdocdir}/samba- doc
+smb(mount|mnt|umount) smbfs
+mount.smbfs smbfs
+swat swat
+libsmbclient libsmbclient
+@default@
+EOF
+
+
+%Clean
+%{rmDESTDIR}
+
+
+%Post
+/usr/lib/LSB/init-install %{Name}
+
+
+%Post -n swat
+%{NKinetdReload}
+perl -pi -e '$s=1 if /^swat/;
+ print "swat:ALL EXCEPT 127.0.0.1\n" if eof && ! $s' /etc/hosts.deny
+
+
+%PostUn
+test "$1" = "0" || exit 0
+/usr/lib/LSB/init-remove %{Name}
+# We want to remove the browse.dat and wins.dat files so they can not
+# interfer with a new version of samba!
+rm -f /var/lock/samba/browse.dat
+rm -f /var/lock/samba/{brlock,connections,locking,messages}.tdb
+if [ -e /var/lock/samba.d/namelist.debug ]; then
+ rm -f /var/lock/samba.d/namelist.debug
+fi
+rm -f /var/lock/samba/unexpected.tdb
+rm -f /var/lock/samba/{smbd,nmbd}.pid
+
+# Note: We MUST keep:
+# winbindd_*, sshare_info*, printing*, ntdrivers*
+
+
+%PostUn -n swat
+#$no lsb: lisa --inetd disable swat $1
+test "$1" = "0" || exit 0
+%{SVIdir}/inet reload
+[ -x /usr/sbin/swat ]||perl -ni -e '/^swat\s*\:/||print' /etc/hosts.deny
+
+
+%Files -f files-samba-base
+%defattr(-,root,root)
+%config %attr(0755,root,root) %{SVIdir}/samba
+%config %attr(0755,root,root) %{SVIdir}/winbind
+%config %attr(644,root,root) /etc/sysconfig/daemons/samba
+%config %attr(644,root,root) /etc/sysconfig/daemons/winbind
+%config %attr(644,root,root) /etc/pam.d/samba
+%config %attr(644,root,root) /etc/logrotate.d/samba
+%config %attr(-,root,root) %{EtcSamba}
+%dir %attr(755,root,root) /var/lock/samba.d
+%dir %attr(755,root,root) /var/log/samba.d
+%dir %attr(1777,root,root) /var/spool/samba
+%dir %attr(755,root,root) /var/run/samba
+%dir %attr(755,root,root) %{LSBservedir}
+%dir %attr(755,root,root) %{LSBservedir}/netlogon
+%dir %attr(755,root,root) %{LSBservedir}/profiles
+%dir %attr(755,root,root) %{LSBservedir}/Public
+
+
+%Files doc -f files-samba-doc
+%defattr(-,root,root)
+
+
+%Files -n smbfs -f files-samba-smbfs
+%defattr(-,root,root)
+
+
+%Files -n swat -f files-samba-swat
+%defattr(-,root,root)
+%config %attr(644,root,root) %{NKinetdir}/swat
+
+%Files -n libsmbclient -f files-samba-libsmbclient
+%defattr(-,root,root)
+
+%ChangeLog
+* Mon Jan 01 1997 ...
+ - nothing here for now
diff --git a/packaging/Caldera/OpenLinux/samba2.spec-sam.tmpl b/packaging/Caldera/OpenLinux/samba2.spec-sam.tmpl
new file mode 100755
index 00000000000..86ed85a3513
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba2.spec-sam.tmpl
@@ -0,0 +1,546 @@
+%define Version PVERSIONsam
+%define date PRELEASE
+%define Vendor Caldera
+%define Dist OpenLinux
+%define EtcSamba /etc/samba.d
+%define LSBservedir /srv/samba
+
+Name : samba
+Version : %{Version}
+Release : %{date}
+Group : Server/Network
+
+Summary : Samba SMB client and server.
+Summary(de) : Samba SMB Client und Server.
+Summary(es) : Cliente y servidor SMB Samba.
+Summary(fr) : Client et serveur SMB Samba.
+Summary(it) : Client e server SMB.
+Summary(pt) : Cliente e servidor SMB Samba.
+
+Copyright : Andrew Tridgell, John H Terpstra; GPL Version 2
+Packager : Klaus Singvogel <klaus@caldera.de>
+#Icon : Caldera-daemon.gif
+URL : http://samba.org/samba
+
+Requires : libpam >= 0.66, SysVinit-scripts >= 1.04-6
+
+
+BuildRoot : /tmp/%{Name}-%{Version}
+
+Source: ftp://ftp.samba.org/pub/samba/%{Name}-%{Version}.tar.gz
+
+%Package doc
+Group : Server/Network
+
+Summary : Documentation on SAMBA.
+Summary(de) : Die Dokumentation für Samba.
+Summary(es) : Documentation de SAMBA.
+Summary(fr) : Documentation pour Samba.
+Summary(it) : Documentazione su SAMBA.
+Summary(pt) : Documentação sobre o SAMBA.
+
+%Package -n smbfs
+Group : System/Network
+
+Summary : Mount and unmount commands for SMB filesystems (smbfs).
+Summary(de) : Mount und unmount für SMB-Dateisysteme (smbfs).
+Summary(es) : Comandos de montaje y desmontaje de sistemas de ficheros SMB (smbfs).
+Summary(fr) : Commandes pour le montage et le démontage des systèmes de fichiers SMB (smbfs).
+Summary(it) : Comandi per montare e smontare i file system SMB (smbfs).
+Summary(pt) : Comandos mount e unmount para o sistema de ficheiros SMB (smbfs).
+
+%Package -n swat
+Group : Administration/Network
+Requires : setup >= 2.0-2, tcp_wrappers, netkit-base >= 0.17-5
+
+Summary : Samba Web Administration Tool.
+Summary(de) : Das Samba Web Administrationstool.
+Summary(es) : Utilidad de administración Samba.
+Summary(fr) : Outil d'administration Internet pour Samba.
+Summary(it) : Strumento per l'amministrazione di Samba via Web.
+Summary(pt) : Ferramenta Web de administração de Samba (Samba Web Administration Tool).
+
+%Package -n libsmbclient
+Group : System/Network
+
+Summary : SMB Client Library
+
+%Description
+Samba provides an SMB server which can be used to provide network
+services to SMB (sometimes called "Lan Manager") clients, including
+various versions of MS Windows, OS/2, and other Linux machines.
+
+%Description -l de
+Samba stellt einen SMB Server zur Verfügung, mit dem Netzwerkdienste für SMB
+(auch "Lan Manager" genannt) Clients bereitgestellt werden können. Dies
+schließt verschiedene Versionen von MS Windows, OS/2 und andere Linux
+Maschinen ein.
+
+%Description -l es
+Samba dispone de un servidor SMB que puede utilizarse para proporcionar
+servicios de red a clientes SMB (a veces conocido como "Lan Manager"),
+incluyendo varias versiones de MS Windows, OS/2 y otras máquinas Linux.
+
+%Description -l fr
+Samba fournit un serveur SMB qui peut être utilisé pour fournir des services
+de réseau aux clients SMB (parfois appelés "Lan Manager"), comportant
+diverses versions de MS Windows, OS/2 et d'autres machines Linux.
+
+%Description -l it
+Samba fornisce un server SMB che può essere usato per fornire servizi
+di rete a client SMB (talvolta chiamato "Lan Manager"), comprese varie
+versioni di MS Windows, OS/2 e altre macchine Linux.
+
+%Description -l pt
+O Samba fornece um servidor de SMB que pode ser usado para fornecer serviços de
+rede aos clientes de SMB (denominado por vezes como "Lan Manager"), incluindo
+várias versões do Windows, OS/2 e outras máquinas Linux.
+
+%Description doc
+This package contains extensive SAMBA documentation, including a FAQ,
+comprehensive usage documentation, and a number of examples.
+
+%Description -l de doc
+Dieses Paket enthält eine ausführliche SAMBA Dokumentation, inklusive
+einer FAQ, umfassender Gebrauchsdokumentation und einer Reihe von
+Beispielen.
+
+%Description -l es doc
+Este paquete contiene una extensa documentación sobre SAMBA, incluyendo
+FAQ (Preguntas de Uso Frecuente), documentación sobre el uso y algunos
+ejemplos.
+
+%Description -l fr doc
+Ce paquetage contient une documentation complète sur Samba, y compris
+une FAQ détaillée de son utilisation et un certain nombre d'exemples.
+
+%Description -l it doc
+Questo pacchetto contiene la documentazione su SAMBA tra cui una FAQ
+una esaustiva documentazione d'uso e un certo numero di esempi.
+
+%Description -l pt doc
+Este pacote contém alguma documentação extensa sobre o SAMBA, incluindo a FAQ,
+alguma documentação compreensiva sobre a utilização e alguns exemplos.
+
+%Description -n smbfs
+This package includes the tools necessary to mount filesystems from
+SMB servers.
+
+%Description -l de -n smbfs
+Dieses Paket enthält die nötigen Tools, um Dateisysteme von SMB-Servern
+zu mounten.
+
+%Description -l es -n smbfs
+este paqeute incluye las herramientas necesarias para montar sistemas de
+ficheros de servidores SMB.
+
+%Description -l fr -n smbfs
+Ce paquetage contient les outils nécessaires pour monter des systèmes
+de fichiers sur des serveurs SMB.
+
+%Description -l it -n smbfs
+Questo pacchetto contiene gli strumenti necessari per montare filesystem
+da server SMB.
+
+%Description -l pt -n smbfs
+Este pacote contém as ferramentas necessárias para montar sistema de
+ficheiros de servidores SMB.
+
+%Description -n swat
+SWAT allows a Samba administrator to configure the complex smb.conf
+file via a Web browser. It also provides links to all the configurable
+options in the smb.conf file allowing an administrator to easily look
+up the effects of any change.
+
+%Description -l de -n swat
+Mit SWAT kann ein Samba-Administrator die komplexe smb.conf
+Datei mit Hilfe eines Web-Browsers konfigurieren. Es stellt auch Links zu
+allen konfigurierbaren Optionen in der smb.conf Datei bereit, wodurch ein
+Administrator die Auswirkungen einer Änderung leicht nachvollziehen kann.
+
+%Description -l es -n swat
+SWAT permite a un administrador de Samba configurar el complejo fichero
+smb.conf mediante una navegador web. También proporciona enlaces a todas las
+opciones configurables en el fichero smb.conf, permitiendo al administrador
+comprobar fácilmente los efectos de cualquier cambio.
+
+%Description -l fr -n swat
+SWAT permet à un administrateur Samba de configurer le fichier smb.conf
+complexe via un navigateur Web. Il fournit également des liens d'aide pour
+toutes les options configurables dans le fichier smb.conf permettant à un
+administrateur de consulter aisément les effets d'une modification.
+
+%Description -l it -n swat
+SWAT permette ad un amministratore Samba di configurare il complesso file
+smb.conf attraverso un browser Web. SWAT ha anche dei link di aiuto per
+tutte le opzioni di configurazione del file smb.conf.
+
+%Description -l pt -n swat
+O SWAT permite a um administrador de Samba configurar o complexo ficheiro
+smb.conf através de uma interface Web. Fornece também referências para
+todas as opções configuraveis no smb.conf, permitindo a um admnistrador
+verificar rapidamente o efeite de qualquer alteração.
+
+%Description -n libsmbclient
+SMB Client Library allows for POSIX like SMB client calls providing developers
+a clean and stable API for SMB client application development.
+
+%Prep
+%setup
+
+# instead of patch (to help configuration) ... ;^)
+%{fixUP} -vbT source/Makefile.in -e '
+ s:we don.t use sbindir because we want:if you want : +
+ s:(the previous releases of Samba):$1, please use: +
+ s:(SBINDIR\s*=\s*\@)b:# ./configure --sbindir=\\\$(BINDIR)\n${1}sb: +
+ s:/log\.(\S+):/log/samba.d/${1}d: +
+ s:(PASSWD_PROGRAM\s*=\s*)(/bin):$1/usr$2:
+'
+for i in {cvs.,change-}log; do [ ! -f ../$i ] || mv ../$i source; done
+
+mv swat/help/welcome.html docs
+%{fixUP} -vT docs -e '
+ s:/usr/local/samba/bin/(smb(client|run)):/usr/bin/$1:g +
+ s:/usr/local/samba/bin/((s|n)mbd|swat|smbstatus):/usr/sbin/$1:g +
+ s:/usr/local/samba/var/locks:/var/lock/samba.d: +
+ s:/usr/local/samba/(var|lib)/log:/var/log/samba.d/smb: +
+ s:/usr/local/samba/swat:/usr/share/samba/swat:g +
+ s:/usr/local/samba/lib:%{EtcSamba}:g +
+ s:/usr/local/samba/printers:/var/spool/samba:g +
+ s:/usr/local/samba/private/smbpasswd:/usr/bin/smbpasswd:g +
+ s:/usr/local/samba/netlogon:%{LSBservedir}/netlogon:g;
+'
+mv docs/welcome.html swat/help
+for i in docs/*/smb.conf.5*; do
+ %{fixUP} -vT $i -e '
+ s:users\.map:smbusers:g +
+ s:SAMBA_INSTALL_DIRECTORY/lib:%{EtcSamba}: +
+ s:None \(set in compile\)\.:(see above).: +
+ s:/usr/local/:/usr/:g;
+ '
+done
+%{fixUP} -vT docs/textdocs/Faxing.txt -e '
+ s:/usr/local/etc/:/etc/: +
+ s:/usr/local/:/usr/:;
+'
+# ENCRYPTION.txt is gone.
+%{fixUP} -vT docs/docbook/projdoc/ENCRYPTION.sgml -e '
+ s:/usr/local/samba/private:%{EtcSamba}:g +
+ s:mksmbpasswd.sh:mksmbpasswd:g +
+ s:the Samba source directory:/usr/bin:;
+'
+
+%{fixUP} -vT docs/htmldocs/make_smbcodepage.1.html -e '
+ s:/usr/local/samba:/usr/bin/:g;
+'
+for i in htmldocs/DOMAIN_MEMBER.html htmldocs/Samba-HOWTO-Collection.html \
+ htmldocs/smbclient.1.html htmldocs/smbd.8.html \
+ docbook/projdoc/DOMAIN_MEMBER.sgml docbook/projdoc/DOMAIN_MEMBER.sgml \
+ docbook/manpages/smbclient.1.sgml docbook/manpages/smbd.8.sgml \
+ docbook/projdoc/ENCRYPTION.sgml manpages/smbclient.1 manpages/smbd.8 ; do
+%{fixUP} -vT docs/$i -e '
+ s:/usr/local/samba/private/FOREST.SLEEPY.SID:/var/lock/samba.d/FOREST.SLEEPY.SID: +
+ s:/usr/local/samba/private:/usr/bin:g +
+ s:/usr/local/samba/bin:/usr/bin:g +
+ s:/usr/local/sbin:/usr/sbin:g +
+ s:/usr/local/src/samba:/usr/src/samba:g ;'
+done
+%{fixUP} -vT docs/docbook/manpages/make_smbcodepage.1.sgml -e '
+ s:/usr/local/samba:/usr/bin:g ;
+'
+# End of DirtyHack(TM)
+
+
+%Build
+cd source
+rm -f configure
+autoconf
+
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}' \
+ --with-privatedir='$(LIBDIR)' \
+ --with-lockdir='$(DESTDIR)/var/lock/samba.d' \
+ --with-piddir='$(DESTDIR)/var/run/samba' \
+ --with-swatdir='$(DESTDIR)/usr/share/swat' \
+ --with-sambabook='$(DESTDIR)/usr/share/swat/using_samba' \
+ --with-configdir='$(DESTDIR)'%{EtcSamba} \
+ --with-codepagedir='$(DESTDIR)'/usr/share/samba/codepages \
+ --with-smbwrapper \
+ --with-libsmbclient \
+ --with-smbmount \
+ --with-automount \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-quotas \
+ --with-utmp \
+ --with-winbind \
+ --with-syslog \
+ --with-vfs \
+ --with-msdfs \
+ --with-tdbsam \
+ --with-ldapsam \
+ --with-nisplussam \
+ --with-nisplushome \
+ --with-krb5=/usr/athena
+
+make LOGFILEBASE=/var/log/samba.d everything nsswitch/libnss_wins.so
+
+# Now build the VFS modules
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}'
+cd block
+mv block.c block.c.old
+sed 's/etc\/samba/etc\/samba\.d\/vfs/g' < block.c.old > block.c
+cd ..
+make
+
+
+
+%Install
+%{mkDESTDIR}
+VVS=packaging/%{Vendor}/%{Dist}
+
+mkdir -p $DESTDIR/etc/{{logrotate,pam}.d,sysconfig/daemons}
+mkdir -p $DESTDIR/var/{lo{ck,g}/samba.d,spool/samba,run/samba}
+mkdir -p $DESTDIR/usr/share/swat/using_samba/{gifs,figs}
+mkdir -p $DESTDIR/lib/security
+mkdir -p $DESTDIR/%{LSBservedir}/{netlogon,profiles,Public}
+mkdir -p $DESTDIR/etc/skel/Samba
+mkdir -p $DESTDIR/usr/share/samba/codepages/src $DESTDIR/sbin
+mkdir -p $DESTDIR/%{SVIdir}
+mkdir -p $DESTDIR/usr/{include,lib/samba/vfs}
+
+make LOGFILEBASE=/var/log/samba.d -C source install
+
+strip $DESTDIR/usr/bin/smb{mnt,umount}
+#mv $DESTDIR/usr/bin/{make,add,conv}* $DESTDIR/usr/bin
+
+cp -p source/codepages/codepage_def.??? $DESTDIR/usr/share/samba/codepages/src
+
+# Install the nsswitch library extension file
+install -m 755 source/nsswitch/libnss_wins.so $DESTDIR/lib/libnss_wins.so.2.0
+# Make link for wins resolver
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so.2
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so
+
+# Add PAM smbpass and winbind facilities
+install -m 755 source/bin/pam_smbpass.so $DESTDIR/lib/security
+install -m 755 source/nsswitch/libnss_winbind.so $DESTDIR/lib/libnss_winbind.so.2.0
+
+# Make link for winbind resolver
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so.2
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so
+
+install -m 755 source/nsswitch/pam_winbind.so $DESTDIR/lib/security
+install -m 755 source/bin/wbinfo $DESTDIR/usr/bin
+install -m 755 source/bin/debug2html $DESTDIR/usr/sbin/debug2html
+
+install -m 755 source/bin/libsmbclient.so $DESTDIR/usr/lib
+install -m 755 source/bin/libsmbclient.a $DESTDIR/usr/lib
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0.1
+install -m 644 source/include/libsmbclient.h $DESTDIR/usr/include
+
+# Adding extra stuff
+install -m 755 source/bin/smbfilter $DESTDIR/usr/bin
+install -m 755 source/bin/smbsh $DESTDIR/usr/bin
+install -m 755 source/bin/smbwrapper.so $DESTDIR/usr/bin
+install -m 755 source/bin/smbtorture $DESTDIR/usr/sbin
+
+# Adding VFS modules
+install -m 755 examples/VFS/audit.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.conf $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/skel.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/block/block.so $DESTDIR/usr/lib/samba/vfs
+install -m 644 examples/VFS/block/samba-block.conf $DESTDIR/etc/samba.d/samba-block.conf.example
+install -m 644 examples/VFS/block/smb.conf $DESTDIR/etc/samba.d/smb.conf.example-with-block-use
+
+cp -p $VVS/smb.conf.sample $DESTDIR%{EtcSamba}/smb.conf.sample
+cp -p $VVS/smb.conf $DESTDIR%{EtcSamba}/smb.conf
+cp -p $VVS/smbusers $DESTDIR%{EtcSamba}
+cp -p $VVS/smbprint $DESTDIR/usr/bin
+cp -p $VVS/samba.daemon $DESTDIR/etc/sysconfig/daemons/samba
+cp -p $VVS/winbind.daemon $DESTDIR/etc/sysconfig/daemons/winbind
+cp -p $VVS/samba.pam $DESTDIR/etc/pam.d/samba
+cp -p $VVS/samba.logrotate $DESTDIR/etc/logrotate.d/samba
+cp -p $VVS/README.home $DESTDIR/etc/skel/Samba/README.txt
+cp -p $VVS/README.Public $DESTDIR/%{LSBservedir}/Public/README.txt
+cp -p $VVS/README.profiles $DESTDIR/%{LSBservedir}/profiles/README.txt
+
+
+install -m 755 $VVS/samba.init-lsb $DESTDIR/%{SVIdir}/%{Name}
+#lsb: cp -p $VVS/samba.init $DESTDIR/etc/rc.d/init.d/samba
+#lsb: cp -p $VVS/winbind.init $DESTDIR/etc/rc.d/init.d/winbind
+ln -s /etc/rc.d/init.d/samba $DESTDIR/usr/sbin
+
+
+for f in testparm testprns; do
+ ln -s $f $DESTDIR/usr/bin/smb$f
+ ln -s $f.1 $DESTDIR/usr/man/man1/smb$f.1
+done
+
+ln -s ../usr/bin/smbmount $DESTDIR/sbin/mount.smbfs
+
+cat <<-'EoH' > $DESTDIR%{EtcSamba}/lmhosts
+ 127.0.0.1 localhost
+EoH
+
+# lsb has new way of inetd configuration
+mkdir -p $DESTDIR%{NKinetdir}
+cat <<EoI >$DESTDIR%{NKinetdir}/swat
+swat stream tcp nowait.400 root /usr/sbin/tcpd swat
+EoI
+
+pushd $DESTDIR/usr/sbin
+rm -f *.so
+popd
+
+# -------------------- Documentation -------------------------------
+DOCD="$DESTDIR/%{_defaultdocdir}/samba-%{Version}"; mkdir -p $DOCD
+ln -sf ../Copyrights/GPL-2.0 $DOCD/COPYING
+
+cp -p README Manifest Read-Manifest-Now $DOCD
+cp -p WHATSNEW.txt Roadmap $DOCD
+cp -a docs examples $DOCD
+
+mv $DOCD/docs/htmldocs/wfw_slip.htm $DOCD/docs/wfw_slip.html
+
+rm -rf $DOCD/docs/{htmldocs,manpages,yodldocs}
+rm -rf $DOCD/examples/{svr4-startup,printing}
+rm -rf $DOCD/CVS $DOCD/*/CVS $DOCD/*/*/CVS $DOCD/*/*/*/CVS
+
+cp -p swat/README $DOCD/README.swat
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/gifs
+done
+
+# -------------------- Fixing final pathes -------------------------------
+
+%{fixUP} -T $DESTDIR/%{SVIdir} -e 's:\@SVIdir\@:%{SVIdir}:'
+%{fixUP} -vT $DOCD/examples -e 's:/usr/local/bin/:/usr/bin/:g;'
+%{fixUP} -vT $DESTDIR/%{EtcSamba} -e 's:\@samba_home\@:%{LSBservedir}:'
+
+%{fixManPages}
+
+%{mkLists} -c samba
+cat << 'EOF' | %{mkLists} -d samba
+Samba base
+/lib/$ base
+/usr/lib/samba/$ base
+%{LSBservedir} config-IGNORED
+^/(etc|var|home|tmp) config-IGNORED
+swat swat
+%{_defaultdocdir}/samba-[^/]+/$ base
+%{_defaultdocdir}/samba- doc
+tmp IGNORED
+man IGNORED
+/src/$ IGNORED
+/usr/private/$ IGNORED
+@default@
+EOF
+cat << 'EOF' | %{mkLists} -f -a samba
+\.old$ IGNORED
+Samba/README.txt base
+^/etc config-IGNORED
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+libnss_* base
+pam_* base
+winbind* base
+/usr/lib/samba/$ base
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+%{_defaultdocdir}/samba- doc
+smb(mount|mnt|umount) smbfs
+mount.smbfs smbfs
+swat swat
+libsmbclient libsmbclient
+@default@
+EOF
+
+%Clean
+
+%Post
+/usr/lib/LSB/init-install %{Name}
+
+%Post -n swat
+%{NKinetdReload}
+perl -pi -e '$s=1 if /^swat/;
+ print "swat:ALL EXCEPT 127.0.0.1\n" if eof && ! $s' /etc/hosts.deny
+
+%PostUn
+test "$1" = "0" || exit 0
+/usr/lib/LSB/init-remove %{Name}
+# We want to remove the browse.dat and wins.dat files so they can not
+# interfer with a new version of samba!
+rm -f /var/lock/samba/browse.dat
+rm -f /var/lock/samba/{brlock,connections,locking,messages}.tdb
+if [ -e /var/lock/samba.d/namelist.debug ]; then
+ rm -f /var/lock/samba.d/namelist.debug
+fi
+rm -f /var/lock/samba/unexpected.tdb
+rm -f /var/lock/samba/{smbd,nmbd}.pid
+
+# Note: We MUST keep:
+# winbindd_*, sshare_info*, printing*, ntdrivers*
+
+%PostUn -n swat
+#$no lsb: lisa --inetd disable swat $1
+test "$1" = "0" || exit 0
+%{SVIdir}/inet reload
+[ -x /usr/sbin/swat ]||perl -ni -e '/^swat\s*\:/||print' /etc/hosts.deny
+
+
+%Files -f files-samba-base
+%defattr(-,root,root)
+%config %attr(0755,root,root) %{SVIdir}/samba
+%config %attr(0755,root,root) %{SVIdir}/winbind
+%config %attr(644,root,root) /etc/sysconfig/daemons/samba
+%config %attr(644,root,root) /etc/sysconfig/daemons/winbind
+%config %attr(644,root,root) /etc/pam.d/samba
+%config %attr(644,root,root) /etc/logrotate.d/samba
+%config %attr(-,root,root) %{EtcSamba}
+%dir %attr(755,root,root) /var/lock/samba.d
+%dir %attr(755,root,root) /var/log/samba.d
+%dir %attr(1777,root,root) /var/spool/samba
+%dir %attr(755,root,root) %{LSBservedir}
+%dir %attr(755,root,root) %{LSBservedir}/netlogon
+%dir %attr(755,root,root) %{LSBservedir}/profiles
+%dir %attr(755,root,root) %{LSBservedir}/Public
+
+
+%Files doc -f files-samba-doc
+%defattr(-,root,root)
+
+
+%Files -n smbfs -f files-samba-smbfs
+%defattr(-,root,root)
+
+
+%Files -n swat -f files-samba-swat
+%defattr(-,root,root)
+%config %attr(644,root,root) %{NKinetdir}/swat
+
+%Files -n libsmbclient -f files-samba-libsmbclient
+%defattr(-,root,root)
+
+%ChangeLog
+* Mon Jan 01 1997 ...
+ - nothing here for now
diff --git a/packaging/Caldera/OpenLinux/samba2.spec-team.tmpl b/packaging/Caldera/OpenLinux/samba2.spec-team.tmpl
new file mode 100755
index 00000000000..3d90ecc7fe9
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba2.spec-team.tmpl
@@ -0,0 +1,539 @@
+%define Version PVERSION
+%define date PRELEASE
+%define Vendor Caldera
+%define Dist OpenLinux
+%define EtcSamba /etc/samba.d
+%define LSBservedir /srv/samba
+
+Name : samba
+Version : %{Version}
+Release : %{date}
+Group : Server/Network
+
+Summary : Samba SMB client and server.
+Summary(de) : Samba SMB Client und Server.
+Summary(es) : Cliente y servidor SMB Samba.
+Summary(fr) : Client et serveur SMB Samba.
+Summary(it) : Client e server SMB.
+Summary(pt) : Cliente e servidor SMB Samba.
+
+Copyright : Andrew Tridgell, John H Terpstra; GPL Version 2
+Packager : Klaus Singvogel <klaus@caldera.de>
+#Icon : Caldera-daemon.gif
+URL : http://samba.org/samba
+
+Requires : libpam >= 0.66, SysVinit-scripts >= 1.04-6
+
+
+BuildRoot : /tmp/%{Name}-%{Version}
+
+Source: ftp://ftp.samba.org/pub/samba/%{Name}-%{Version}.tar.gz
+
+%Package doc
+Group : Server/Network
+
+Summary : Documentation on SAMBA.
+Summary(de) : Die Dokumentation für Samba.
+Summary(es) : Documentation de SAMBA.
+Summary(fr) : Documentation pour Samba.
+Summary(it) : Documentazione su SAMBA.
+Summary(pt) : Documentação sobre o SAMBA.
+
+%Package -n smbfs
+Group : System/Network
+
+Summary : Mount and unmount commands for SMB filesystems (smbfs).
+Summary(de) : Mount und unmount für SMB-Dateisysteme (smbfs).
+Summary(es) : Comandos de montaje y desmontaje de sistemas de ficheros SMB (smbfs).
+Summary(fr) : Commandes pour le montage et le démontage des systèmes de fichiers SMB (smbfs).
+Summary(it) : Comandi per montare e smontare i file system SMB (smbfs).
+Summary(pt) : Comandos mount e unmount para o sistema de ficheiros SMB (smbfs).
+
+%Package -n swat
+Group : Administration/Network
+Requires : setup >= 2.0-2, tcp_wrappers, netkit-base >= 0.17-5
+
+Summary : Samba Web Administration Tool.
+Summary(de) : Das Samba Web Administrationstool.
+Summary(es) : Utilidad de administración Samba.
+Summary(fr) : Outil d'administration Internet pour Samba.
+Summary(it) : Strumento per l'amministrazione di Samba via Web.
+Summary(pt) : Ferramenta Web de administração de Samba (Samba Web Administration Tool).
+
+%Package -n libsmbclient
+Group : System/Network
+
+Summary : SMB Client Library
+
+%Description
+Samba provides an SMB server which can be used to provide network
+services to SMB (sometimes called "Lan Manager") clients, including
+various versions of MS Windows, OS/2, and other Linux machines.
+
+%Description -l de
+Samba stellt einen SMB Server zur Verfügung, mit dem Netzwerkdienste für SMB
+(auch "Lan Manager" genannt) Clients bereitgestellt werden können. Dies
+schließt verschiedene Versionen von MS Windows, OS/2 und andere Linux
+Maschinen ein.
+
+%Description -l es
+Samba dispone de un servidor SMB que puede utilizarse para proporcionar
+servicios de red a clientes SMB (a veces conocido como "Lan Manager"),
+incluyendo varias versiones de MS Windows, OS/2 y otras máquinas Linux.
+
+%Description -l fr
+Samba fournit un serveur SMB qui peut être utilisé pour fournir des services
+de réseau aux clients SMB (parfois appelés "Lan Manager"), comportant
+diverses versions de MS Windows, OS/2 et d'autres machines Linux.
+
+%Description -l it
+Samba fornisce un server SMB che può essere usato per fornire servizi
+di rete a client SMB (talvolta chiamato "Lan Manager"), comprese varie
+versioni di MS Windows, OS/2 e altre macchine Linux.
+
+%Description -l pt
+O Samba fornece um servidor de SMB que pode ser usado para fornecer serviços de
+rede aos clientes de SMB (denominado por vezes como "Lan Manager"), incluindo
+várias versões do Windows, OS/2 e outras máquinas Linux.
+
+%Description doc
+This package contains extensive SAMBA documentation, including a FAQ,
+comprehensive usage documentation, and a number of examples.
+
+%Description -l de doc
+Dieses Paket enthält eine ausführliche SAMBA Dokumentation, inklusive
+einer FAQ, umfassender Gebrauchsdokumentation und einer Reihe von
+Beispielen.
+
+%Description -l es doc
+Este paquete contiene una extensa documentación sobre SAMBA, incluyendo
+FAQ (Preguntas de Uso Frecuente), documentación sobre el uso y algunos
+ejemplos.
+
+%Description -l fr doc
+Ce paquetage contient une documentation complète sur Samba, y compris
+une FAQ détaillée de son utilisation et un certain nombre d'exemples.
+
+%Description -l it doc
+Questo pacchetto contiene la documentazione su SAMBA tra cui una FAQ
+una esaustiva documentazione d'uso e un certo numero di esempi.
+
+%Description -l pt doc
+Este pacote contém alguma documentação extensa sobre o SAMBA, incluindo a FAQ,
+alguma documentação compreensiva sobre a utilização e alguns exemplos.
+
+%Description -n smbfs
+This package includes the tools necessary to mount filesystems from
+SMB servers.
+
+%Description -l de -n smbfs
+Dieses Paket enthält die nötigen Tools, um Dateisysteme von SMB-Servern
+zu mounten.
+
+%Description -l es -n smbfs
+este paqeute incluye las herramientas necesarias para montar sistemas de
+ficheros de servidores SMB.
+
+%Description -l fr -n smbfs
+Ce paquetage contient les outils nécessaires pour monter des systèmes
+de fichiers sur des serveurs SMB.
+
+%Description -l it -n smbfs
+Questo pacchetto contiene gli strumenti necessari per montare filesystem
+da server SMB.
+
+%Description -l pt -n smbfs
+Este pacote contém as ferramentas necessárias para montar sistema de
+ficheiros de servidores SMB.
+
+%Description -n swat
+SWAT allows a Samba administrator to configure the complex smb.conf
+file via a Web browser. It also provides links to all the configurable
+options in the smb.conf file allowing an administrator to easily look
+up the effects of any change.
+
+%Description -l de -n swat
+Mit SWAT kann ein Samba-Administrator die komplexe smb.conf
+Datei mit Hilfe eines Web-Browsers konfigurieren. Es stellt auch Links zu
+allen konfigurierbaren Optionen in der smb.conf Datei bereit, wodurch ein
+Administrator die Auswirkungen einer Änderung leicht nachvollziehen kann.
+
+%Description -l es -n swat
+SWAT permite a un administrador de Samba configurar el complejo fichero
+smb.conf mediante una navegador web. También proporciona enlaces a todas las
+opciones configurables en el fichero smb.conf, permitiendo al administrador
+comprobar fácilmente los efectos de cualquier cambio.
+
+%Description -l fr -n swat
+SWAT permet à un administrateur Samba de configurer le fichier smb.conf
+complexe via un navigateur Web. Il fournit également des liens d'aide pour
+toutes les options configurables dans le fichier smb.conf permettant à un
+administrateur de consulter aisément les effets d'une modification.
+
+%Description -l it -n swat
+SWAT permette ad un amministratore Samba di configurare il complesso file
+smb.conf attraverso un browser Web. SWAT ha anche dei link di aiuto per
+tutte le opzioni di configurazione del file smb.conf.
+
+%Description -l pt -n swat
+O SWAT permite a um administrador de Samba configurar o complexo ficheiro
+smb.conf através de uma interface Web. Fornece também referências para
+todas as opções configuraveis no smb.conf, permitindo a um admnistrador
+verificar rapidamente o efeite de qualquer alteração.
+
+%Description -n libsmbclient
+SMB Client Library allows for POSIX like SMB client calls providing developers
+a clean and stable API for SMB client application development.
+
+%Prep
+%setup
+
+# instead of patch (to help configuration) ... ;^)
+%{fixUP} -vbT source/Makefile.in -e '
+ s:we don.t use sbindir because we want:if you want : +
+ s:(the previous releases of Samba):$1, please use: +
+ s:(SBINDIR\s*=\s*\@)b:# ./configure --sbindir=\\\$(BINDIR)\n${1}sb: +
+ s:/log\.(\S+):/log/samba.d/${1}d: +
+ s:(PASSWD_PROGRAM\s*=\s*)(/bin):$1/usr$2:
+'
+for i in {cvs.,change-}log; do [ ! -f ../$i ] || mv ../$i source; done
+
+mv swat/help/welcome.html docs
+%{fixUP} -vT docs -e '
+ s:/usr/local/samba/bin/(smb(client|run)):/usr/bin/$1:g +
+ s:/usr/local/samba/bin/((s|n)mbd|swat|smbstatus):/usr/sbin/$1:g +
+ s:/usr/local/samba/var/locks:/var/lock/samba.d: +
+ s:/usr/local/samba/(var|lib)/log:/var/log/samba.d/smb: +
+ s:/usr/local/samba/swat:/usr/share/samba/swat:g +
+ s:/usr/local/samba/lib:%{EtcSamba}:g +
+ s:/usr/local/samba/printers:/var/spool/samba:g +
+ s:/usr/local/samba/private/smbpasswd:/usr/bin/smbpasswd:g +
+ s:/usr/local/samba/netlogon:%{LSBservedir}/netlogon:g;
+'
+mv docs/welcome.html swat/help
+for i in docs/*/smb.conf.5*; do
+ %{fixUP} -vT $i -e '
+ s:users\.map:smbusers:g +
+ s:SAMBA_INSTALL_DIRECTORY/lib:%{EtcSamba}: +
+ s:None \(set in compile\)\.:(see above).: +
+ s:/usr/local/:/usr/:g;
+ '
+done
+%{fixUP} -vT docs/textdocs/Faxing.txt -e '
+ s:/usr/local/etc/:/etc/: +
+ s:/usr/local/:/usr/:;
+'
+# ENCRYPTION.txt is gone.
+%{fixUP} -vT docs/docbook/projdoc/ENCRYPTION.sgml -e '
+ s:/usr/local/samba/private:%{EtcSamba}:g +
+ s:mksmbpasswd.sh:mksmbpasswd:g +
+ s:the Samba source directory:/usr/bin:;
+'
+
+%{fixUP} -vT docs/htmldocs/make_smbcodepage.1.html -e '
+ s:/usr/local/samba:/usr/bin/:g;
+'
+for i in htmldocs/DOMAIN_MEMBER.html htmldocs/Samba-HOWTO-Collection.html \
+ htmldocs/smbclient.1.html htmldocs/smbd.8.html \
+ docbook/projdoc/DOMAIN_MEMBER.sgml docbook/projdoc/DOMAIN_MEMBER.sgml \
+ docbook/manpages/smbclient.1.sgml docbook/manpages/smbd.8.sgml \
+ docbook/projdoc/ENCRYPTION.sgml manpages/smbclient.1 manpages/smbd.8 ; do
+%{fixUP} -vT docs/$i -e '
+ s:/usr/local/samba/private/FOREST.SLEEPY.SID:/var/lock/samba.d/FOREST.SLEEPY.SID: +
+ s:/usr/local/samba/private:/usr/bin:g +
+ s:/usr/local/samba/bin:/usr/bin:g +
+ s:/usr/local/sbin:/usr/sbin:g +
+ s:/usr/local/src/samba:/usr/src/samba:g ;'
+done
+%{fixUP} -vT docs/docbook/manpages/make_smbcodepage.1.sgml -e '
+ s:/usr/local/samba:/usr/bin:g ;
+'
+# End of DirtyHack(TM)
+
+
+%Build
+cd source
+rm -f configure
+autoconf
+
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}' \
+ --with-privatedir='$(LIBDIR)' \
+ --with-lockdir='$(DESTDIR)/var/lock/samba.d' \
+ --with-piddir='$(DESTDIR)/var/run/samba' \
+ --with-swatdir='$(DESTDIR)/usr/share/swat' \
+ --with-sambabook='$(DESTDIR)/usr/share/swat/using_samba' \
+ --with-configdir='$(DESTDIR)'%{EtcSamba} \
+ --with-codepagedir='$(DESTDIR)'/usr/share/samba/codepages \
+ --with-smbwrapper \
+ --with-libsmbclient \
+ --with-smbmount \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-quotas \
+ --with-utmp \
+ --with-winbind \
+ --with-syslog
+
+make LOGFILEBASE=/var/log/samba.d everything nsswitch/libnss_wins.so
+
+# Now build the VFS modules
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --with-fhs \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}'
+cd block
+mv block.c block.c.old
+sed 's/etc\/samba/etc\/samba\.d\/vfs/g' < block.c.old > block.c
+cd ..
+make
+
+
+%Install
+%{mkDESTDIR}
+VVS=packaging/%{Vendor}/%{Dist}
+
+mkdir -p $DESTDIR/etc/{{logrotate,pam}.d,sysconfig/daemons}
+mkdir -p $DESTDIR/var/{lo{ck,g}/samba.d,spool/samba,run/samba}
+mkdir -p $DESTDIR/usr/share/swat/using_samba/{gifs,figs}
+mkdir -p $DESTDIR/lib/security
+mkdir -p $DESTDIR/%{LSBservedir}/{netlogon,profiles,Public}
+mkdir -p $DESTDIR/etc/skel/Samba
+mkdir -p $DESTDIR/usr/share/samba/codepages/src $DESTDIR/sbin
+mkdir -p $DESTDIR/%{SVIdir}
+mkdir -p $DESTDIR/usr/{include,lib/samba/vfs}
+
+make LOGFILEBASE=/var/log/samba.d -C source install
+
+strip $DESTDIR/usr/bin/smb{mnt,umount}
+#mv $DESTDIR/usr/bin/{make,add,conv}* $DESTDIR/usr/bin
+
+cp -p source/codepages/codepage_def.??? $DESTDIR/usr/share/samba/codepages/src
+
+# Install the nsswitch library extension file
+install -m 755 source/nsswitch/libnss_wins.so $DESTDIR/lib/libnss_wins.so.2.0
+# Make link for wins resolver
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so.2
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so
+
+# Add PAM smbpass and winbind facilities
+install -m 755 source/bin/pam_smbpass.so $DESTDIR/lib/security
+install -m 755 source/nsswitch/libnss_winbind.so $DESTDIR/lib/libnss_winbind.so.2.0
+
+# Make link for winbind resolver
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so.2
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so
+
+install -m 755 source/nsswitch/pam_winbind.so $DESTDIR/lib/security
+install -m 755 source/bin/wbinfo $DESTDIR/usr/bin
+install -m 755 source/bin/debug2html $DESTDIR/usr/sbin/debug2html
+
+install -m 755 source/bin/libsmbclient.so $DESTDIR/usr/lib
+install -m 755 source/bin/libsmbclient.a $DESTDIR/usr/lib
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0
+ln -s libsmbclient.so $DESTDIR/usr/lib/libsmbclient.so.0.1
+install -m 644 source/include/libsmbclient.h $DESTDIR/usr/include
+
+# Adding extra stuff
+install -m 755 source/bin/smbfilter $DESTDIR/usr/bin
+install -m 755 source/bin/smbsh $DESTDIR/usr/bin
+install -m 755 source/bin/smbwrapper.so $DESTDIR/usr/bin
+install -m 755 source/bin/smbtorture $DESTDIR/usr/sbin
+install -m 755 $VVS/smbadduser $DESTDIR/usr/bin
+
+# Adding VFS modules
+install -m 755 examples/VFS/audit.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/recycle/recycle.conf $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/skel.so $DESTDIR/usr/lib/samba/vfs
+install -m 755 examples/VFS/block/block.so $DESTDIR/usr/lib/samba/vfs
+install -m 644 examples/VFS/block/samba-block.conf $DESTDIR/etc/samba.d/samba-block.conf.example
+install -m 644 examples/VFS/block/smb.conf $DESTDIR/etc/samba.d/smb.conf.example-with-block-use
+
+cp -p $VVS/smb.conf.sample $DESTDIR%{EtcSamba}/smb.conf.sample
+cp -p $VVS/smb.conf $DESTDIR%{EtcSamba}/smb.conf
+cp -p $VVS/smbusers $DESTDIR%{EtcSamba}
+cp -p $VVS/smbprint $DESTDIR/usr/bin
+cp -p $VVS/samba.daemon $DESTDIR/etc/sysconfig/daemons/samba
+cp -p $VVS/winbind.daemon $DESTDIR/etc/sysconfig/daemons/winbind
+cp -p $VVS/samba.pam $DESTDIR/etc/pam.d/samba
+cp -p $VVS/samba.logrotate $DESTDIR/etc/logrotate.d/samba
+cp -p $VVS/README.home $DESTDIR/etc/skel/Samba/README.txt
+cp -p $VVS/README.Public $DESTDIR/%{LSBservedir}/Public/README.txt
+cp -p $VVS/README.profiles $DESTDIR/%{LSBservedir}/profiles/README.txt
+
+
+install -m 755 $VVS/samba.init-lsb $DESTDIR/%{SVIdir}/%{Name}
+install -m 755 $VVS/winbind.init $DESTDIR/%{SVIdir}/winbind
+#lsb: cp -p $VVS/samba.init $DESTDIR/etc/rc.d/init.d/samba
+ln -s /etc/rc.d/init.d/samba $DESTDIR/usr/sbin
+
+
+for f in testparm testprns; do
+ ln -s $f $DESTDIR/usr/bin/smb$f
+ ln -s $f.1 $DESTDIR/usr/man/man1/smb$f.1
+done
+
+ln -s ../usr/bin/smbmount $DESTDIR/sbin/mount.smbfs
+
+cat <<-'EoH' > $DESTDIR%{EtcSamba}/lmhosts
+ 127.0.0.1 localhost
+EoH
+
+# lsb has new way of inetd configuration
+mkdir -p $DESTDIR%{NKinetdir}
+cat <<EoI >$DESTDIR%{NKinetdir}/swat
+swat stream tcp nowait.400 root /usr/sbin/tcpd swat
+EoI
+
+pushd $DESTDIR/usr/sbin
+rm -f *.so
+popd
+
+# -------------------- Documentation -------------------------------
+DOCD="$DESTDIR/%{_defaultdocdir}/samba-%{Version}"; mkdir -p $DOCD
+ln -sf ../Copyrights/GPL-2.0 $DOCD/COPYING
+
+cp -p README Manifest Read-Manifest-Now $DOCD
+cp -p WHATSNEW.txt Roadmap $DOCD
+cp -a docs examples $DOCD
+
+mv $DOCD/docs/htmldocs/wfw_slip.htm $DOCD/docs/wfw_slip.html
+
+rm -rf $DOCD/docs/{htmldocs,manpages,yodldocs}
+rm -rf $DOCD/examples/{svr4-startup,printing}
+rm -rf $DOCD/CVS $DOCD/*/CVS $DOCD/*/*/CVS $DOCD/*/*/*/CVS
+
+cp -p swat/README $DOCD/README.swat
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/gifs
+done
+
+# -------------------- Fixing final pathes -------------------------------
+
+%{fixUP} -T $DESTDIR/%{SVIdir} -e 's:\@SVIdir\@:%{SVIdir}:'
+%{fixUP} -vT $DOCD/examples -e 's:/usr/local/bin/:/usr/bin/:g;'
+%{fixUP} -vT $DESTDIR/%{EtcSamba} -e 's:\@samba_home\@:%{LSBservedir}:'
+
+%{fixManPages}
+
+%{mkLists} -c samba
+cat << 'EOF' | %{mkLists} -d samba
+Samba base
+/lib/$ base
+/usr/lib/samba/$ base
+%{LSBservedir} config-IGNORED
+^/(etc|var|home|tmp) config-IGNORED
+swat swat
+%{_defaultdocdir}/samba-[^/]+/$ base
+%{_defaultdocdir}/samba- doc
+tmp IGNORED
+man IGNORED
+/src/$ IGNORED
+/usr/private/$ IGNORED
+@default@
+EOF
+cat << 'EOF' | %{mkLists} -f -a samba
+\.old$ IGNORED
+Samba/README.txt base
+^/etc config-IGNORED
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+libnss_* base
+pam_* base
+winbind* base
+/usr/lib/samba/* base
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+%{_defaultdocdir}/samba- doc
+smb(mount|mnt|umount) smbfs
+mount.smbfs smbfs
+swat swat
+libsmbclient libsmbclient
+@default@
+EOF
+
+%Clean
+
+%Post
+/usr/lib/LSB/init-install %{Name}
+
+%Post -n swat
+%{NKinetdReload}
+perl -pi -e '$s=1 if /^swat/;
+ print "swat:ALL EXCEPT 127.0.0.1\n" if eof && ! $s' /etc/hosts.deny
+
+%PostUn
+test "$1" = "0" || exit 0
+/usr/lib/LSB/init-remove %{Name}
+# We want to remove the browse.dat and wins.dat files so they can not
+# interfer with a new version of samba!
+rm -f /var/lock/samba/browse.dat
+rm -f /var/lock/samba/{brlock,connections,locking,messages}.tdb
+if [ -e /var/lock/samba.d/namelist.debug ]; then
+ rm -f /var/lock/samba.d/namelist.debug
+fi
+rm -f /var/lock/samba/unexpected.tdb
+rm -f /var/lock/samba/{smbd,nmbd}.pid
+
+# Note: We MUST keep:
+# winbindd_*, sshare_info*, printing*, ntdrivers*
+
+%PostUn -n swat
+#$no lsb: lisa --inetd disable swat $1
+test "$1" = "0" || exit 0
+%{SVIdir}/inet reload
+[ -x /usr/sbin/swat ]||perl -ni -e '/^swat\s*\:/||print' /etc/hosts.deny
+
+
+%Files -f files-samba-base
+%defattr(-,root,root)
+%config %attr(0755,root,root) %{SVIdir}/samba
+%config %attr(0755,root,root) %{SVIdir}/winbind
+%config %attr(644,root,root) /etc/sysconfig/daemons/samba
+%config %attr(644,root,root) /etc/sysconfig/daemons/winbind
+%config %attr(644,root,root) /etc/pam.d/samba
+%config %attr(644,root,root) /etc/logrotate.d/samba
+%config %attr(-,root,root) %{EtcSamba}
+%dir %attr(755,root,root) /var/lock/samba.d
+%dir %attr(755,root,root) /var/log/samba.d
+%dir %attr(1777,root,root) /var/spool/samba
+%dir %attr(755,root,root) /var/run/samba
+%dir %attr(755,root,root) %{LSBservedir}
+%dir %attr(755,root,root) %{LSBservedir}/netlogon
+%dir %attr(755,root,root) %{LSBservedir}/profiles
+%dir %attr(755,root,root) %{LSBservedir}/Public
+
+
+%Files doc -f files-samba-doc
+%defattr(-,root,root)
+
+
+%Files -n smbfs -f files-samba-smbfs
+%defattr(-,root,root)
+
+
+%Files -n swat -f files-samba-swat
+%defattr(-,root,root)
+%config %attr(644,root,root) %{NKinetdir}/swat
+
+%Files -n libsmbclient -f files-samba-libsmbclient
+%defattr(-,root,root)
+
+%ChangeLog
+* Mon Jan 01 1997 ...
+ - nothing here for now
diff --git a/packaging/Caldera/OpenLinux/samba2.spec.tmpl b/packaging/Caldera/OpenLinux/samba2.spec.tmpl
new file mode 100755
index 00000000000..8036a112f27
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/samba2.spec.tmpl
@@ -0,0 +1,493 @@
+%define Version PVERSION
+%define date PRELEASE
+%define Vendor Caldera
+%define Dist OpenLinux
+%define EtcSamba /etc/samba.d
+%define _defaultdocdir /usr/doc
+%define LSBservedir /srv/samba
+
+Name : samba
+Version : %{Version}
+Release : %{date}
+Group : Server/Network
+
+Summary : Samba SMB client and server.
+Summary(de) : Samba SMB Client und Server.
+Summary(es) : Cliente y servidor SMB Samba.
+Summary(fr) : Client et serveur SMB Samba.
+Summary(it) : Client e server SMB.
+Summary(pt) : Cliente e servidor SMB Samba.
+
+Copyright : Andrew Tridgell, John H Terpstra; GPL Version 2
+Packager : Klaus Singvogel <klaus@caldera.de>
+#Icon : Caldera-daemon.gif
+URL : http://samba.org/samba
+
+Requires : libpam >= 0.66, SysVinit-scripts >= 1.04-6
+
+
+BuildRoot : /tmp/%{Name}-%{Version}
+
+Source: ftp://ftp.samba.org/pub/samba/%{Name}-%{Version}.tar.gz
+
+
+%Package doc
+Group : Server/Network
+
+Summary : Documentation on SAMBA.
+Summary(de) : Die Dokumentation für Samba.
+Summary(es) : Documentation de SAMBA.
+Summary(fr) : Documentation pour Samba.
+Summary(it) : Documentazione su SAMBA.
+Summary(pt) : Documentação sobre o SAMBA.
+
+
+%Package -n smbfs
+Group : System/Network
+
+Summary : Mount and unmount commands for SMB filesystems (smbfs).
+Summary(de) : Mount und unmount für SMB-Dateisysteme (smbfs).
+Summary(es) : Comandos de montaje y desmontaje de sistemas de ficheros SMB (smbfs).
+Summary(fr) : Commandes pour le montage et le démontage des systèmes de fichiers SMB (smbfs).
+Summary(it) : Comandi per montare e smontare i file system SMB (smbfs).
+Summary(pt) : Comandos mount e unmount para o sistema de ficheiros SMB (smbfs).
+
+
+
+%Package -n swat
+Group : Administration/Network
+Requires : setup >= 2.0-2, tcp_wrappers
+
+Summary : Samba Web Administration Tool.
+Summary(de) : Das Samba Web Administrationstool.
+Summary(es) : Utilidad de administración Samba.
+Summary(fr) : Outil d'administration Internet pour Samba.
+Summary(it) : Strumento per l'amministrazione di Samba via Web.
+Summary(pt) : Ferramenta Web de administração de Samba (Samba Web Administration Tool).
+
+
+%Description
+Samba provides an SMB server which can be used to provide network
+services to SMB (sometimes called "Lan Manager") clients, including
+various versions of MS Windows, OS/2, and other Linux machines.
+
+%Description -l de
+Samba stellt einen SMB Server zur Verfügung, mit dem Netzwerkdienste für SMB
+(auch "Lan Manager" genannt) Clients bereitgestellt werden können. Dies
+schließt verschiedene Versionen von MS Windows, OS/2 und andere Linux
+Maschinen ein.
+
+%Description -l es
+Samba dispone de un servidor SMB que puede utilizarse para proporcionar
+servicios de red a clientes SMB (a veces conocido como "Lan Manager"),
+incluyendo varias versiones de MS Windows, OS/2 y otras máquinas Linux.
+
+%Description -l fr
+Samba fournit un serveur SMB qui peut être utilisé pour fournir des services
+de réseau aux clients SMB (parfois appelés "Lan Manager"), comportant
+diverses versions de MS Windows, OS/2 et d'autres machines Linux.
+
+%Description -l it
+Samba fornisce un server SMB che può essere usato per fornire servizi
+di rete a client SMB (talvolta chiamato "Lan Manager"), comprese varie
+versioni di MS Windows, OS/2 e altre macchine Linux.
+
+%Description -l pt
+O Samba fornece um servidor de SMB que pode ser usado para fornecer serviços de
+rede aos clientes de SMB (denominado por vezes como "Lan Manager"), incluindo
+várias versões do Windows, OS/2 e outras máquinas Linux.
+
+%Description doc
+This package contains extensive SAMBA documentation, including a FAQ,
+comprehensive usage documentation, and a number of examples.
+
+%Description -l de doc
+Dieses Paket enthält eine ausführliche SAMBA Dokumentation, inklusive
+einer FAQ, umfassender Gebrauchsdokumentation und einer Reihe von
+Beispielen.
+
+%Description -l es doc
+Este paquete contiene una extensa documentación sobre SAMBA, incluyendo
+FAQ (Preguntas de Uso Frecuente), documentación sobre el uso y algunos
+ejemplos.
+
+%Description -l fr doc
+Ce paquetage contient une documentation complète sur Samba, y compris
+une FAQ détaillée de son utilisation et un certain nombre d'exemples.
+
+%Description -l it doc
+Questo pacchetto contiene la documentazione su SAMBA tra cui una FAQ
+una esaustiva documentazione d'uso e un certo numero di esempi.
+
+%Description -l pt doc
+Este pacote contém alguma documentação extensa sobre o SAMBA, incluindo a FAQ,
+alguma documentação compreensiva sobre a utilização e alguns exemplos.
+
+%Description -n smbfs
+This package includes the tools necessary to mount filesystems from
+SMB servers.
+
+%Description -l de -n smbfs
+Dieses Paket enthält die nötigen Tools, um Dateisysteme von SMB-Servern
+zu mounten.
+
+%Description -l es -n smbfs
+este paqeute incluye las herramientas necesarias para montar sistemas de
+ficheros de servidores SMB.
+
+%Description -l fr -n smbfs
+Ce paquetage contient les outils nécessaires pour monter des systèmes
+de fichiers sur des serveurs SMB.
+
+%Description -l it -n smbfs
+Questo pacchetto contiene gli strumenti necessari per montare filesystem
+da server SMB.
+
+%Description -l pt -n smbfs
+Este pacote contém as ferramentas necessárias para montar sistema de
+ficheiros de servidores SMB.
+
+%Description -n swat
+SWAT allows a Samba administrator to configure the complex smb.conf
+file via a Web browser. It also provides links to all the configurable
+options in the smb.conf file allowing an administrator to easily look
+up the effects of any change.
+
+%Description -l de -n swat
+Mit SWAT kann ein Samba-Administrator die komplexe smb.conf
+Datei mit Hilfe eines Web-Browsers konfigurieren. Es stellt auch Links zu
+allen konfigurierbaren Optionen in der smb.conf Datei bereit, wodurch ein
+Administrator die Auswirkungen einer Änderung leicht nachvollziehen kann.
+
+%Description -l es -n swat
+SWAT permite a un administrador de Samba configurar el complejo fichero
+smb.conf mediante una navegador web. También proporciona enlaces a todas las
+opciones configurables en el fichero smb.conf, permitiendo al administrador
+comprobar fácilmente los efectos de cualquier cambio.
+
+%Description -l fr -n swat
+SWAT permet à un administrateur Samba de configurer le fichier smb.conf
+complexe via un navigateur Web. Il fournit également des liens d'aide pour
+toutes les options configurables dans le fichier smb.conf permettant à un
+administrateur de consulter aisément les effets d'une modification.
+
+%Description -l it -n swat
+SWAT permette ad un amministratore Samba di configurare il complesso file
+smb.conf attraverso un browser Web. SWAT ha anche dei link di aiuto per
+tutte le opzioni di configurazione del file smb.conf.
+
+%Description -l pt -n swat
+O SWAT permite a um administrador de Samba configurar o complexo ficheiro
+smb.conf através de uma interface Web. Fornece também referências para
+todas as opções configuraveis no smb.conf, permitindo a um admnistrador
+verificar rapidamente o efeite de qualquer alteração.
+
+
+%Prep
+%setup
+
+# instead of patch (to help configuration) ... ;^)
+%{fixUP} -vbT source/Makefile.in -e '
+ s:we don.t use sbindir because we want:if you want : +
+ s:(the previous releases of Samba):$1, please use: +
+ s:(SBINDIR\s*=\s*\@)b:# ./configure --sbindir=\\\$(BINDIR)\n${1}sb: +
+ s:/log\.(\S+):/log/samba.d/${1}d: +
+ s:(PASSWD_PROGRAM\s*=\s*)(/bin):$1/usr$2:
+'
+# s:^(LIBS\s*=):AUTH_$1: +
+# s:((CLIENT|CUPS|NMBD|SMBD|SWAT|RPCCLIENT|SMBPASSWD|STATUS|TESTPRNS|TESTPARM)_OBJ\) )(\$\(LDF):$1\$(AUTH_LIBS) $3:
+
+for i in {cvs.,change-}log; do [ ! -f ../$i ] || mv ../$i source; done
+
+mv swat/help/welcome.html docs
+%{fixUP} -vT docs -e '
+ s:/usr/local/samba/bin/(smb(client|run)):/usr/bin/$1:g +
+ s:/usr/local/samba/bin/((s|n)mbd|swat|smbstatus):/usr/sbin/$1:g +
+ s:/usr/local/samba/var/locks:/var/lock/samba.d: +
+ s:/usr/local/samba/(var|lib)/log:/var/log/samba.d/smb: +
+ s:/usr/local/samba/swat:/usr/share/samba/swat:g +
+ s:/usr/local/samba/lib:%{EtcSamba}:g +
+ s:/usr/local/samba/printers:/var/spool/samba:g +
+ s:/usr/local/samba/private/smbpasswd:/usr/bin/smbpasswd:g +
+ s:/usr/local/samba/netlogon:%{LSBservedir}/netlogon:g;
+'
+mv docs/welcome.html swat/help
+for i in docs/*/smb.conf.5*; do
+ %{fixUP} -vT $i -e '
+ s:users\.map:smbusers:g +
+ s:SAMBA_INSTALL_DIRECTORY/lib:%{EtcSamba}: +
+ s:None \(set in compile\)\.:(see above).: +
+ s:/usr/local/:/usr/:g;
+ '
+done
+%{fixUP} -vT docs/textdocs/Faxing.txt -e '
+ s:/usr/local/etc/:/etc/: +
+ s:/usr/local/:/usr/:;
+'
+%{fixUP} -vT docs/docbook/projdoc/ENCRYPTION.sgml -e '
+ s:/usr/local/samba/private:%{EtcSamba}:g +
+ s:mksmbpasswd.sh:mksmbpasswd:g +
+ s:the Samba source directory:/usr/bin:;
+'
+%{fixUP} -vT docs/htmldocs/make_smbcodepage.1.html -e '
+ s:/usr/local/samba:/usr/bin/:g;
+'
+for i in htmldocs/DOMAIN_MEMBER.html htmldocs/Samba-HOWTO-Collection.html \
+ htmldocs/smbclient.1.html htmldocs/smbd.8.html \
+ docbook/projdoc/DOMAIN_MEMBER.sgml htmldocs/DOMAIN_MEMBER.html \
+ docbook/manpages/smbclient.1.sgml docbook/manpages/smbd.8.sgml \
+ docbook/projdoc/ENCRYPTION.sgml manpages/smbclient.1 manpages/smbd.8 ; do
+%{fixUP} -vT docs/$i -e '
+ s:/usr/local/samba/private/FOREST.SLEEPY.SID:/var/lock/samba.d/FOREST.SLEEPY.SID: +
+ s:/usr/local/samba/private:/usr/bin:g +
+ s:/usr/local/samba/bin:/usr/bin:g +
+ s:/usr/local/sbin:/usr/sbin:g +
+ s:/usr/local/src/samba:/usr/src/samba:g ;'
+done
+%{fixUP} -vT docs/docbook/manpages/make_smbcodepage.1.sgml -e '
+ s:/usr/local/samba:/usr/bin:g ;
+'
+# End of DirtyHack(TM)
+
+
+%Build
+cd source
+autoreconf
+
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}' \
+ --with-privatedir='$(LIBDIR)' \
+ --with-lockdir='$(DESTDIR)/var/lock/samba.d' \
+ --with-swatdir='$(DESTDIR)/usr/share/swat' \
+ --with-swatdir='$(DESTDIR)/usr/share/swat' \
+ --with-sambabook='$(DESTDIR)/usr/share/swat/using_samba' \
+ --with-configdir='$(DESTDIR)'%{EtcSamba} \
+ --with-codepagedir='$(DESTDIR)'/usr/share/samba/codepages \
+ --without-smbwrapper \
+ --with-smbmount \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-quotas \
+ --with-syslog \
+ --win_winbind \
+ --with-utmp
+
+make LOGFILEBASE=/var/log/samba.d all
+make LOGFILEBASE=/var/log/samba.d nsswitch/libnss_wins.so
+make LOGFILEBASE=/var/log/samba.d smbfilter debug2html
+make LOGFILEBASE=/var/log/samba.d bin/smbspool
+
+
+%Install
+%{mkDESTDIR}
+VVS=packaging/%{Vendor}/%{Dist}
+
+mkdir -p $DESTDIR/etc/{{rc.d/init,logrotate,pam}.d,sysconfig/daemons,skel/Samba}
+mkdir -p $DESTDIR/var/{lo{ck,g}/samba.d,spool/samba}
+mkdir -p $DESTDIR/usr/share/swat/using_samba/{gifs,figs}
+mkdir -p $DESTDIR/lib/security
+mkdir -p $DESTDIR/%{LSBservedir}/{netlogon,profiles,Public}
+mkdir -p $DESTDIR/usr/share/samba/codepages/src $DESTDIR/sbin
+
+make -C source install
+make LOGFILEBASE=/var/log/samba.d -C source install
+
+strip $DESTDIR/usr/bin/smb{mnt,umount}
+#mv $DESTDIR/usr/bin/{make,add,conv}* $DESTDIR/usr/sbin
+
+cp -p source/codepages/codepage_def.??? $DESTDIR/usr/share/samba/codepages/src
+
+# Install the nsswitch library extension file
+install -m 755 source/nsswitch/libnss_wins.so $DESTDIR/lib/libnss_wins.so.2.0
+# Make link for wins resolver
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so.2
+ln -s libnss_wins.so.2.0 $DESTDIR/lib/libnss_wins.so
+
+# Add PAM smbpass and winbind facilities
+install -m 755 source/bin/pam_smbpass.so $DESTDIR/lib/security
+install -m 755 source/nsswitch/libnss_winbind.so $DESTDIR/lib/libnss_winbind.so.2.0
+
+# Make link for winbind resolver
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so.2
+ln -s libnss_winbind.so.2.0 $DESTDIR/lib/libnss_winbind.so
+
+install -m 755 source/nsswitch/pam_winbind.so $DESTDIR/lib/security
+install -m 755 source/bin/wbinfo $DESTDIR/usr/bin
+install -m 755 source/bin/debug2html $DESTDIR/usr/sbin/debug2html
+
+cp -p $VVS/smb.conf.sample $DESTDIR%{EtcSamba}/smb.conf.sample
+cp -p $VVS/smb.conf $DESTDIR%{EtcSamba}/smb.conf
+cp -p $VVS/smbusers $DESTDIR%{EtcSamba}
+cp -p $VVS/smbprint $DESTDIR/usr/bin
+
+cp -p $VVS/smbadduser $DESTDIR/usr/bin/smbadduser
+#cp -p $VVS/make_smbpasswd.perl $DESTDIR/usr/bin/make_smbpasswd
+#cp -p $VVS/convertsmbpasswd.perl $DESTDIR/usr/bin/convertsmbpasswd
+#cp -p $VVS/updatesmbpasswd.perl $DESTDIR/usr/bin/updatesmbpasswd
+
+cp -p $VVS/samba.daemon $DESTDIR/etc/sysconfig/daemons/samba
+cp -p $VVS/samba.pam $DESTDIR/etc/pam.d/samba
+cp -p $VVS/samba.logrotate $DESTDIR/etc/logrotate.d/samba
+cp -p $VVS/README.home $DESTDIR/etc/skel/Samba/README.txt
+cp -p $VVS/README.Public $DESTDIR/%{LSBservedir}/Public/README.txt
+cp -p $VVS/README.profiles $DESTDIR/%{LSBservedir}/profiles/README.txt
+
+install -m 755 $VVS/samba.init-lsb $DESTDIR/etc/rc.d/init.d/samba
+ln -s /etc/rc.d/init.d/samba $DESTDIR/usr/sbin
+
+for f in testparm testprns; do
+ ln -s $f $DESTDIR/usr/bin/smb$f
+ ln -s $f.1 $DESTDIR/usr/man/man1/smb$f.1
+done
+
+#ln -s make_smbcodepage $DESTDIR/usr/bin/mksmbcodepage
+#ln -s make_smbpasswd $DESTDIR/usr/bin/mksmbpasswd
+#ln -sf convert_smbpasswd $DESTDIR/usr/bin/convertsmbpasswd
+
+ln -s ../usr/bin/smbmount $DESTDIR/sbin/mount.smbfs
+
+cat <<-'EoH' > $DESTDIR%{EtcSamba}/lmhosts
+ 127.0.0.1 localhost
+EoH
+
+
+# -------------------- Documentation -------------------------------
+DOCD="$DESTDIR/%{_defaultdocdir}/samba-%{Version}"; mkdir -p $DOCD
+ln -sf ../Copyrights/GPL-2.0 $DOCD/COPYING
+
+#cp -p README README-smbmount Manifest Read-Manifest-Now $DOCD
+
+cp -p README Manifest Read-Manifest-Now $DOCD
+cp -p WHATSNEW.txt Roadmap $DOCD
+cp -a docs examples $DOCD
+
+mv $DOCD/docs/htmldocs/wfw_slip.htm $DOCD/docs/wfw_slip.html
+
+rm -rf $DOCD/docs/{htmldocs,manpages,yodldocs}
+rm -rf $DOCD/examples/{svr4-startup,printing}
+rm -rf $DOCD/CVS $DOCD/*/CVS $DOCD/*/*/CVS $DOCD/*/*/*/CVS
+
+cp -p swat/README $DOCD/README.swat
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+install -m644 $i $DESTDIR/usr/share/swat/using_samba/gifs
+done
+
+%{fixUP} -vT $DOCD/examples -e 's:/usr/local/bin/:/usr/bin/:g;'
+%{fixUP} -vT $DESTDIR/etc/samba.d -e 's:\@samba_home\@:%{LSBservedir}:'
+
+%{fixManPages}
+
+%{mkLists} -c samba
+cat << 'EOF' | %{mkLists} -d samba
+Samba base
+%{LSBservedir} config-IGNORED
+^/(etc|var|home|tmp) config-IGNORED
+swat swat
+%{_defaultdocdir}/samba-[^/]+/$ base
+%{_defaultdocdir}/samba- doc
+/lib/$ IGNORED
+/srv/$ IGNORED
+tmp IGNORED
+man IGNORED
+/src/$ IGNORED
+/usr/private/$ IGNORED
+@default@
+EOF
+cat << 'EOF' | %{mkLists} -f -a samba
+\.old$ IGNORED
+Samba/README.txt base
+^/etc config-IGNORED
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+libnss_wins.so base
+pam_* base
+%{_defaultdocdir}/samba-[^/]+/(COPYING|README$) base
+%{_defaultdocdir}/samba- doc
+smb(mount|mnt|umount) smbfs
+mount.smbfs smbfs
+swat swat
+libsmbclient libsmbclient
+@default@
+EOF
+
+
+%Clean
+%{rmDESTDIR}
+
+
+%Post
+lisa --SysV-init install samba S91 3:4:5 K09 0:1:2:6
+/sbin/ldconfig
+
+
+%Post -n swat
+lisa --inetd install swat stream tcp nowait.400 root /usr/sbin/tcpd swat
+perl -pi -e '$s=1 if /^swat/;
+ print "swat:ALL EXCEPT 127.0.0.1\n" if eof && ! $s' /etc/hosts.deny
+
+
+%PostUn
+lisa --SysV-init remove samba $1
+/sbin/ldconfig
+# We want to remove the browse.dat and wins.dat files so they can not
+# interfer with a new version of samba!
+rm -f /var/lock/samba/browse.dat
+rm -f /var/lock/samba/{brlock,connections,locking,messages}.tdb
+if [ -e /var/lock/samba.d/namelist.debug ]; then
+ rm -f /var/lock/samba.d/namelist.debug
+fi
+rm -f /var/lock/samba/unexpected.tdb
+rm -f /var/lock/samba/{smbd,nmbd}.pid
+
+# Note: We MUST keep:
+# winbindd_*, sshare_info*, printing*, ntdrivers*
+
+
+%PostUn -n swat
+lisa --inetd disable swat $1
+[ -x /usr/sbin/swat ]||perl -ni -e '/^swat\s*\:/||print' /etc/hosts.deny
+
+
+%Files -f files-samba-base
+%defattr(-,root,root)
+%config %attr(755,root,root) /etc/rc.d/init.d/samba
+%config %attr(644,root,root) /etc/sysconfig/daemons/samba
+%config %attr(644,root,root) /etc/pam.d/samba
+%config %attr(644,root,root) /etc/logrotate.d/samba
+%config %attr(-,root,root) %{EtcSamba}
+%dir %attr(755,root,root) /var/lock/samba.d
+%dir %attr(755,root,root) /var/log/samba.d
+%dir %attr(1777,root,root) /var/spool/samba
+%dir %attr(755,root,root) %{LSBservedir}
+%dir %attr(755,root,root) %{LSBservedir}/netlogon
+%dir %attr(755,root,root) %{LSBservedir}/profiles
+%dir %attr(755,root,root) %{LSBservedir}/Public
+
+
+%Files doc -f files-samba-doc
+%defattr(-,root,root)
+
+
+%Files -n smbfs -f files-samba-smbfs
+%defattr(-,root,root)
+
+
+%Files -n swat -f files-samba-swat
+%defattr(-,root,root)
+
+
+%ChangeLog
+* Mon Jan 01 1997 ...
+ - nothing here for now
diff --git a/packaging/Caldera/OpenLinux/smb.conf b/packaging/Caldera/OpenLinux/smb.conf
new file mode 100755
index 00000000000..b16d8a250c2
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/smb.conf
@@ -0,0 +1,52 @@
+# Samba config file created using SWAT
+# from localhost (127.0.0.1)
+
+# Global parameters
+[global]
+ workgroup = MYGROUP
+ server string = Samba Server on Caldera OpenLinux
+ encrypt passwords = Yes
+ username map = /etc/samba.d/smbusers
+ password level = 8
+ username level = 8
+ log file = /var/log/samba.d/smb.%m
+ max log size = 200
+ socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+ logon path = \\%L\Profiles\%U
+ logon home = \\%L\Profiles\%U
+ dns proxy = No
+ printing = cups
+
+[homes]
+ comment = Home Directories
+ path = %H/Samba
+ username = %S
+ valid users = %S
+ writeable = Yes
+ create mask = 0750
+ only user = Yes
+ browseable = No
+
+[netlogon]
+ comment = Samba Network Logon Service
+ path = @samba_home@/netlogon
+ guest ok = Yes
+
+[profiles]
+ path = @samba_home@/profiles
+ writeable = Yes
+ guest ok = Yes
+ browseable = No
+ admin users = root
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ create mask = 0700
+ printable = Yes
+ browseable = No
+
+[public]
+ comment = Public Stuff
+ path = @samba_home@/Public
+ write list = @users
diff --git a/packaging/Caldera/OpenLinux/smb.conf.sample b/packaging/Caldera/OpenLinux/smb.conf.sample
new file mode 100755
index 00000000000..f0a59d6193b
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/smb.conf.sample
@@ -0,0 +1,318 @@
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not many any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+# workgroup = NT-Domain-Name or Workgroup-Name
+ workgroup = MYGROUP
+
+# server string is the equivalent of the NT Description field
+ server string = Samba Server on Caldera OpenLinux
+
+# This option is important for security. It allows you to restrict
+# connections to machines which are on your local network. The
+# following example restricts access to two C class networks and
+# the "loopback" interface. For more examples of the syntax see
+# the smb.conf man page
+; hosts allow = 192.168.1. 192.168.2. 127.
+
+# If you want to automatically load your printer list rather
+# than setting them up individually then you'll need this
+ load printers = yes
+
+# you may wish to override the location of the printcap file
+; printcap name = /etc/printcap
+
+# It should not be necessary to specify the print system type unless
+# it is non-standard. Currently supported print systems include:
+# bsd, sysv, plp, lprng, aix, hpux, qnx
+ printing = cups
+
+# Uncomment this if you want a guest account, you must add this to /etc/passwd
+# otherwise the user "nobody" is used
+; guest account = pcguest
+
+# this tells Samba to use a separate log file for each machine
+# that connects
+ log file = /var/log/samba.d/smb.%m
+
+# Put a capping on the size of the log files (in Kb).
+ max log size = 200
+
+# Security mode. Most people will want user level security. See
+# security_level.txt for details.
+ security = user
+# Use password server option only with security = server
+; password server = <NT-Server-Name>
+
+# Password Level allows matching of _n_ characters of the password for
+# all combinations of upper and lower case.
+ password level = 8
+ username level = 8
+
+# You may wish to use password encryption. Please read
+# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+# Do not enable this option unless you have read those documents
+ encrypt passwords = yes
+ smb passwd file = /etc/samba.d/smbpasswd
+
+# The following are needed to allow password changing from Windows to
+# update the Linux sytsem password also.
+# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
+# NOTE2: You do NOT need these to allow workstations to change only
+# the encrypted SMB passwords. They allow the Unix password
+# to be kept in sync with the SMB password.
+; unix password sync = Yes
+; passwd program = /usr/bin/passwd %u
+; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
+
+# Unix users can map to different SMB User names
+ username map = /etc/samba.d/smbusers
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+; include = /etc/samba.d/smb.conf.%m
+
+# Most people will find that this option gives better performance.
+# See speed.txt and the manual pages for details
+ socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+
+# Configure Samba to use multiple interfaces
+# If you have multiple network interfaces then you must list them
+# here. See the man page for details.
+; interfaces = 192.168.12.2/24 192.168.13.2/24
+
+# Configure remote browse list synchronisation here
+# request announcement to, or browse list sync from:
+# a specific host or from / to a whole subnet (see below)
+; remote browse sync = 192.168.3.25 192.168.5.255
+# Cause this host to announce itself to local subnets here
+; remote announce = 192.168.1.255 192.168.2.44
+
+# Browser Control Options:
+# set local master to no if you don't want Samba to become a master
+# browser on your network. Otherwise the normal election rules apply
+; local master = no
+
+# OS Level determines the precedence of this server in master browser
+# elections. The default value should be reasonable
+ os level = 20
+
+# Domain Master specifies Samba to be the Domain Master Browser. This
+# allows Samba to collate browse lists between subnets. Don't use this
+# if you already have a Windows NT domain controller doing this job
+; domain master = yes
+
+# Preferred Master causes Samba to force a local browser election on startup
+# and gives it a slightly higher chance of winning the election
+; preferred master = yes
+
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = <NT-Domain-Controller-SMBName>
+
+# Enable this if you want Samba to be a domain logon server for
+# Windows95 workstations.
+; domain logons = yes
+
+# if you enable domain logons then you may want a per-machine or
+# per user logon script
+# run a specific logon batch file per workstation (machine)
+; logon script = %m.bat
+# run a specific logon batch file per username
+; logon script = %U.bat
+
+# Where to store roving profiles (only for Win95 and WinNT)
+# %L substitutes for this servers netbios name, %U is username
+# You must uncomment the [Profiles] share below
+# Note: "logon home" is for Win9X/ME clients
+# "logon path" is for WinNT/2K/XP clients
+ logon home = \\%L\Profiles\%U
+ logon path = \\%L\Profiles\%U
+
+# All NetBIOS names must be resolved to IP Addresses
+# 'Name Resolve Order' allows the named resolution mechanism to be specified
+# the default order is "host lmhosts wins bcast". "host" means use the unix
+# system gethostbyname() function call that will use either /etc/hosts OR
+# DNS or NIS depending on the settings of /etc/host.config, /etc/nsswitch.conf
+# and the /etc/resolv.conf file. "host" therefore is system configuration
+# dependant. This parameter is most often of use to prevent DNS lookups
+# in order to resolve NetBIOS names to IP Addresses. Use with care!
+# The example below excludes use of name resolution for machines that are NOT
+# on the local network segment
+# - OR - are not deliberately to be known via lmhosts or via WINS.
+; name resolve order = wins lmhosts bcast
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = yes
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = w.x.y.z
+
+# WINS Proxy - Tells Samba to answer name resolution queries on
+# behalf of a non WINS capable client, for this to work there must be
+# at least one WINS Server on the network. The default is NO.
+; wins proxy = yes
+
+# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+# via DNS nslookups. The built-in default for versions 1.9.17 is yes,
+# this has been changed in version 1.9.18 to no.
+ dns proxy = no
+
+# Case Preservation can be handy - system default is _no_
+# NOTE: These can be set on a per share basis
+; preserve case = no
+; short preserve case = no
+# Default case is normally upper case for all DOS files
+; default case = lower
+# Be very careful with case sensitivity - it can break things!
+; case sensitive = no
+
+#============================ Share Definitions ==============================
+[homes]
+ comment = Home Directories
+; this gives access to a 'Public' sub-directory in each user's home...
+; (it is named 'public' as it is intended to be used by other sharing
+; technologies (like NetWare, appletalk) too and may get disclosed due
+; to weak protocols! -- hmm, are there less secure protocols than NFS? :)
+ path = %H/Samba
+ valid users = %S
+ users = %S
+ only user = yes
+ browseable = no
+ writable = yes
+ create mask = 0750
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+[netlogon]
+ comment = Samba Network Logon Service
+ path = @samba_home@/netlogon
+ guest ok = yes
+ writable = no
+ admin users = root
+
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+[profiles]
+ path = @samba_home@/profiles
+ writeable = yes
+ browseable = no
+ guest ok = yes
+
+
+# NOTE: If you have a BSD-style print system there is no need to
+# specifically define each individual printer
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+# Set public = yes to allow user 'guest account' to print
+ guest ok = no
+ writable = no
+ printable = yes
+ create mask = 0700
+
+# A publicly accessible directory, but read only, except for people in
+# the "users" group
+[public]
+ comment = Public Stuff
+ path = @samba_home@/public
+ browseable = yes
+ read only = yes
+ public = no
+ printable = no
+; writable = yes
+# access may be controlled by these options
+; read list = user1, user2, @group
+; valid users = user1, user3
+; write list = @users
+
+# Other examples.
+#
+# This one is useful for people to share files, BUT
+# access to '/tmp' or '/var/tmp' should *not* be given lightly,
+# as this can (still) pose a security threat!
+# Better use a dedicate sub-directory to /(var/)tmp or something
+# like a [public] share!
+[tmp]
+ comment = Temporary file space
+ path = /tmp
+ browseable = yes
+ read only = yes
+ public = no
+ printable = no
+
+# A private printer, usable only by fred. Spool data will be placed in fred's
+# home directory. Note that fred must have write access to the spool directory,
+# wherever it is.
+;[fredsprn]
+; comment = Fred's Printer
+; valid users = fred
+; path = /homes/fred
+; printer = freds_printer
+; public = no
+; writable = no
+; printable = yes
+
+# A private directory, usable only by fred. Note that fred requires write
+# access to the directory.
+;[fredsdir]
+; comment = Fred's Service
+; path = /usr/somewhere/private
+; valid users = fred
+; public = no
+; writable = yes
+; printable = no
+
+# a service which has a different directory for each machine that connects
+# this allows you to tailor configurations to incoming machines. You could
+# also use the %u option to tailor it by user name.
+# The %m gets replaced with the machine name that is connecting.
+;[pchome]
+; comment = PC Directories
+; path = /usr/pc/%m
+; public = no
+; writable = yes
+
+# A publicly accessible directory, read/write to all users. Note that all files
+# created in the directory by users will be owned by the default user, so
+# any user with access can delete any other user's files. Obviously this
+# directory must be writable by the default user. Another user could of course
+# be specified, in which case all files would be owned by that user instead.
+;[public]
+; path = /usr/somewhere/else/public
+; public = yes
+; only guest = yes
+; writable = yes
+; printable = no
+
+# The following two entries demonstrate how to share a directory so that two
+# users can place files there that will be owned by the specific users. In this
+# setup, the directory should be writable by both users and should have the
+# sticky bit set on it to prevent abuse. Obviously this could be extended to
+# as many users as required.
+;[myshare]
+; comment = Mary's and Fred's stuff
+; path = /usr/somewhere/shared
+; valid users = mary fred
+; public = no
+; writable = yes
+; printable = no
+; create mask = 0765
+
+
diff --git a/packaging/Caldera/OpenLinux/smbadduser b/packaging/Caldera/OpenLinux/smbadduser
new file mode 100755
index 00000000000..9eb23bf8dbd
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/smbadduser
@@ -0,0 +1,76 @@
+#!/bin/csh
+#
+# smbadduser - Written by Mike Zakharoff
+#
+unalias *
+set path = ($path /usr/local/samba/bin)
+
+#set smbpasswd = /usr/local/samba/private/smbpasswd
+set smbpasswd = /etc/samba.d/smbpasswd
+#set user_map = /usr/local/samba/lib/users.map
+set user_map = /etc/samba.d/smbusers
+#
+# Set to site specific passwd command
+#
+set passwd = "cat /etc/passwd"
+#set passwd = "niscat passwd.org_dir"
+#set passwd = "ypcat passwd"
+
+set line = "----------------------------------------------------------"
+if ($#argv == 0) then
+ echo $line
+ echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
+ echo ""
+ echo " 1) Updates $smbpasswd"
+ echo " 2) Updates $user_map"
+ echo " 3) Executes smbpasswd for each new user"
+ echo ""
+ echo "smbadduser unixid:ntid unixid:ntid ..."
+ echo ""
+ echo "Example: smbadduser zak:zakharoffm johns:smithj"
+ echo $line
+ exit 1
+endif
+
+touch $smbpasswd $user_map
+set new = ()
+foreach one ($argv)
+ echo $one | grep ':' >& /dev/null
+ if ($status != 0) then
+ echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
+ continue
+ endif
+ set unix = `echo $one | awk -F: '{print $1}'`
+ set ntid = `echo $one | awk -F: '{print $2}'`
+
+ set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#usr != 1) then
+ echo "ERROR: $unix Not in passwd database SKIPPING..."
+ continue
+ endif
+ set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#tmp != 0) then
+ echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
+ continue
+ endif
+
+ echo "Adding: $unix to $smbpasswd"
+# eval $passwd | \
+# awk -F: '$1==USR { \
+# printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
+ /usr/bin/smbpasswd -a -n $unix
+ if ($unix != $ntid) then
+ echo "Adding: {$unix = $ntid} to $user_map"
+ echo "$unix = $ntid" >> $user_map
+ endif
+ set new = ($new $unix)
+end
+
+#
+# Enter password for new users
+#
+foreach one ($new)
+ echo $line
+ echo "ENTER password for $one"
+ smbpasswd $one
+end
diff --git a/packaging/Fedora/smbprint b/packaging/Caldera/OpenLinux/smbprint
index 1c3959d49b5..5d66aa13774 100644..100755
--- a/packaging/Fedora/smbprint
+++ b/packaging/Caldera/OpenLinux/smbprint
@@ -1,4 +1,5 @@
#!/bin/sh
+
# This script is an input filter for printcap printing on a unix machine. It
# uses the smbclient program to print the file to the specified smb-based
# server and service.
@@ -17,7 +18,7 @@
#
# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
# so that the server, service, and password can be read from
-# a /usr/var/spool/lpd/PRINTNAME/.config file.
+# a /var/spool/lpd/PRINTNAME/.config file.
#
# In order for this to work the /etc/printcap entry must include an
# accounting file (af=...):
@@ -31,17 +32,23 @@
# :lp=/dev/null:
#
# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
-# share=PC_SERVER
-# user="user"
+# server=PC_SERVER
+# service=PR_SHARENAME
# password="password"
#
-# Please, do not modify the order in the file.
-# Example:
-# share=\\server\deskjet
-# user="fred"
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
# password=""
#
+# Debugging log file, change to /dev/null if you like.
+#
+# logfile=/tmp/smb-print.log
+logfile=/dev/null
+
+
+#
# The last parameter to the filter is the accounting file name.
# Extract the directory name from the file name.
# Concat this with /.config to get the config file.
@@ -51,34 +58,20 @@ spool_dir=`dirname $acct_file`
config_file=$spool_dir/.config
# Should read the following variables set in the config file:
-# share
-# hostip
-# user
+# server
+# service
# password
-
eval `cat $config_file`
-share=`echo $share | sed "s/[\]/\//g"`
-
-if [ "$user" != "" ]; then
- usercmd="-U"
-else
- usercmd=""
-fi
-
-if [ "$workgroup" != "" ]; then
- workgroupcmd="-W"
-else
- workgroupcmd=""
-fi
-
-if [ "$translate" = "yes" ]; then
- command="translate ; print -"
-else
- command="print -"
-fi
-#echo $share $password $translate $x_command > /tmp/smbprint.log
+#
+# Some debugging help, change the >> to > if you want to save space.
+#
+echo "server $server, service $service" >> $logfile
-cat | /usr/bin/smbclient "$share" "$password" -E ${hostip:+-I} \
- $hostip -N -P $usercmd "$user" $workgroupcmd "$workgroup" \
- -c "$command" 2>/dev/null
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+# echo translate
+ echo "print -"
+ cat
+) | /usr/bin/smbclient "//$server/$service" $password -U $server -N -P >> $logfile 2>&1
diff --git a/packaging/Fedora/smbusers b/packaging/Caldera/OpenLinux/smbusers
index ae3389f53f8..ae3389f53f8 100644..100755
--- a/packaging/Fedora/smbusers
+++ b/packaging/Caldera/OpenLinux/smbusers
diff --git a/packaging/Caldera/OpenLinux/winbind.daemon b/packaging/Caldera/OpenLinux/winbind.daemon
new file mode 100755
index 00000000000..a09914e6051
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/winbind.daemon
@@ -0,0 +1,5 @@
+IDENT=winbind
+DESCRIPTIVE="Winbind server processes (samba)"
+CONFIGURED="no"
+ONBOOT="no"
+OPTIONS_WINBD=""
diff --git a/packaging/Caldera/OpenLinux/winbind.init b/packaging/Caldera/OpenLinux/winbind.init
new file mode 100755
index 00000000000..96a3026d836
--- /dev/null
+++ b/packaging/Caldera/OpenLinux/winbind.init
@@ -0,0 +1,132 @@
+#!/bin/bash
+#
+#
+### BEGIN INIT INFO
+# Provides: $winbind
+# Required-Start: $network $samba
+# Required-Stop: $network
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Description: samba
+# Starts and stops the Samba smbd and nmbd daemons
+# used to provide SMB network services.
+### END INIT INFO
+#
+# Written by Miquel van Smoorenburg <miquels@drinkel.ow.org>.
+# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Modified for OpenLinux by Raymund Will <ray@caldera.de>
+# Adapted for samba by Klaus Singvogel <klaus@caldera.de>
+
+NAME_W=winbindd
+DAEMON_W=/usr/sbin/$NAME_W
+
+config_file=/etc/samba.d/smb.conf
+
+# Source function library (and set vital variables).
+. @SVIdir@/functions
+
+status() {
+ [ -e $1 ] || return 3; # lock / pid file doesn't exist, seems to be stopped
+
+ i=`cat "$1"`
+ state=`egrep '^State' /proc/$i/status 2>/dev/null| sed 's#.* \(.\).*#\1#'`
+ if [ x$state = x -o x$state = xZ ]; then
+ return 2 # no such process (or zombie) --> dead
+ fi
+ return 0 # seems to be up and running
+}
+
+# this function is dedicated to Jan Terpstra. -- Klaus Singvogel, Sep. 2001.
+WinbdConfig() {
+ # returns 0 if winbindd is not configured,
+ # and 1 if winbindd is configured.
+
+ local config_file=$1; shift # file to check
+
+ # check if "winbind uid" is set in samba config file
+ egrep -q '[^#]*winbind uid' $config_file || return 0
+
+ found=0;
+ # We also need to check if least one PAM module control file does
+ # NOT have pam_winbind.so commented out
+ for i in /etc/pam.d/*; do
+ if [ ! -f $i ]; then next; fi
+ egrep -q '[^#]*pam_winbind.so' $i && found=1 && break;
+ done
+
+ if [ $found != 0 ]; then
+ # if so, ensure that in /etc/nsswitch.conf we have for
+ # "passwd", "shadow", "group" an entry for "winbind"
+ egrep -q '^passwd:.*winbind' /etc/nsswitch.conf && return 1
+ egrep -q '^shadow:.*winbind' /etc/nsswitch.conf && return 1
+ egrep -q '^group:.*winbind' /etc/nsswitch.conf && return 1
+ fi
+
+ return 0
+}
+
+case "$1" in
+ start)
+ [ ! -e $SVIlock ] || exit 0
+ [ -x $DAEMON_W ] || exit 5
+ SVIemptyConfig $config_file && exit 6
+
+ echo -n "Starting $SVIsubsys services: "
+ WinbdConfig $config_file || ssd -S -n $NAME_W -x $DAEMON_W -- $OPTIONS_WINBD
+ ret=$?
+
+ echo "."
+ touch $SVIlock
+ ;;
+
+ stop)
+ [ -e $SVIlock ] || exit 0
+
+ echo -n "Stopping $SVIsubsys services: "
+ ssd -K -p /var/lock/samba.d/$NAME_W.pid -n $NAME_W #-x $DAEMON_W
+
+ ret=$?
+
+ echo "."
+ rm -f $SVIlock
+ ;;
+
+ force-reload)
+ [ -e $SVIlock ] || exit 0
+ $0 restart
+ ret=$?
+ ;;
+
+ reload)
+ echo -n "Reloading $SVIsubsys service configuration: "
+ # nmbd has no config file to reload
+ ssd -K --signal 1 -p /var/lock/samba.d/$NAME_W.pid -n $NAME_W #-x $DAEMON_W
+ ret=$?
+ echo "."
+ ;;
+
+ restart)
+ $0 stop
+ $0 start
+ ret=$?
+ ;;
+
+ status)
+ echo -n "Checking status of $SVIsubsys service: "
+ status /var/lock/samba.d/$NAME_W.pid
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo -n "$NAME_W "
+ fi
+ echo "."
+ ;;
+
+ *)
+ echo "Usage: $SVIscript {start|stop|restart|force-reload|reload|status}"
+ ret=2
+ ;;
+
+esac
+
+exit $ret
+
diff --git a/packaging/Caldera/OpenServer/Clean b/packaging/Caldera/OpenServer/Clean
new file mode 100755
index 00000000000..fe4eed25270
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Clean
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Cleanup after having configured, compiled, installed and packaged.
+# Careful - running this script attempts to restore this hierarchy to
+# freshly unpacked source
+#
+# Invoke as "./Clean -n" to get this script to tell you what it would do
+# without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+[ -d dist ] && $V rm -rf dist
+[ -f ../../../source/Makefile ] && {
+ $V cd ../../../source
+ $V rm -f bin/locktest bin/masktest bin/smbsh bin/debug2html \
+ bin/locktest2 bin/smbfilter bin/smbtorture
+ $V make clean
+ $V make distclean
+ $V rm -f mout*
+}
diff --git a/packaging/Caldera/OpenServer/Compile b/packaging/Caldera/OpenServer/Compile
new file mode 100755
index 00000000000..d3f5ed957df
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Compile
@@ -0,0 +1,57 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+CC="gcc"
+CFLAGS="-O3"
+CXX="g++"
+CXXFLAGS="-O3"
+RANLIB=true
+MAKE=/usr/gnu/bin/make
+if [ "$V" = "echo" ]
+then
+ echo "exporting the following shell variables:"
+ echo "CC=$CC"
+ echo "CXX=$CXX"
+ echo "RANLIB=$RANLIB"
+ echo "MAKE=$MAKE"
+ echo "CFLAGS=$CFLAGS"
+ echo "CXXFLAGS=$CXXFLAGS"
+else
+ export CC CXX RANLIB MAKE CFLAGS CXXFLAGS
+fi
+
+if [ "$V" = "echo" ]
+then
+ echo "cd ../../../source"
+ echo "rm -f mout-1 mout-2 mout-3 mout-4"
+ echo "make all 2>&1 | tee mout-1"
+ echo "make smbfilter debug2html 2>&1 | tee mout-2"
+ echo "make bin/smbspool bin/wbinfo 2>&1 | tee mout-3"
+ echo "cd ../examples/VFS"
+ echo "rm -f mout-1"
+ echo "gmake 2>&1 | tee mout-1"
+ echo "cd block"
+ echo "rm -f mout-1"
+ echo "gmake 2>&1 | tee mout-1"
+else
+ cd ../../../source
+ rm -f mout-1 mout-2 mout-3 mout-4
+ make all 2>&1 | tee mout-1
+ make smbfilter debug2html 2>&1 | tee mout-2
+ make bin/smbspool bin/wbinfo 2>&1 | tee mout-3
+ cd ../examples/VFS
+ rm -f mout-1
+ gmake 2>&1 | tee mout-1
+fi
+#
+# Not building :
+# nsswitch - no <nss.h>
+# rpctorture - improper use of client_info struct, dunno
+# smbtorture, locktest, locktest2, masktest - used for dev. only
+# smbwrapper, smbsh - untested and unlikely to work on osr5
diff --git a/packaging/Caldera/OpenServer/Configure b/packaging/Caldera/OpenServer/Configure
new file mode 100755
index 00000000000..0c63f7ff5b4
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Configure
@@ -0,0 +1,102 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+CC="gcc"
+CFLAGS="-O3"
+CXX="g++"
+#CXXFLAGS="-O3 -I/usr/local/include/stl -I/usr/local/include -L/usr/local/lib"
+CXXFLAGS="-O3"
+RANLIB=true
+MAKE=/usr/gnu/bin/make
+PREFIX=/usr/lib/samba
+LIBDIR=/etc/samba.d
+PRIVATEDIR=/etc/samba.d
+LOCKDIR=/var/locks/samba.d
+LOGDIR=/var/log/samba.d
+if [ "$V" = "echo" ]
+then
+ echo "exporting the following shell variables:"
+ echo "CC=$CC"
+ echo "CXX=$CXX"
+ echo "RANLIB=$RANLIB"
+ echo "MAKE=$MAKE"
+ echo "CFLAGS=$CFLAGS"
+ echo "CXXFLAGS=$CXXFLAGS"
+ echo "PREFIX=$PREFIX"
+else
+ export CC CXX RANLIB MAKE CFLAGS CXXFLAGS PREFIX
+fi
+
+cd ../../../source
+[ -f mout-config ] && {
+ if [ "$V" = "echo" ]
+ then
+ echo "mv mout-config mout-config$$"
+ else
+ mv mout-config mout-config$$
+ fi
+}
+if [ "$V" = "echo" ]
+then
+ echo "./configure \
+ --prefix=${PREFIX} \
+ --libdir=${LIBDIR} \
+ --with-privatedir=${PRIVATEDIR} \
+ --with-lockdir=${LOCKDIR} \
+ --with-logfilebase=${LOGDIR} \
+ --with-profile \
+ --with-syslog \
+ --with-utmp \
+ --with-vfs \
+ --with-msdfs \
+ --with-readline=/usr \
+ --with-sambabook=${PREFIX}/swat/using_samba \
+ 2>&1 | tee mout-config"
+else
+ ./configure \
+ --prefix=${PREFIX} \
+ --libdir=${LIBDIR} \
+ --with-privatedir=${PRIVATEDIR} \
+ --with-lockdir=${LOCKDIR} \
+ --with-logfilebase=${LOGDIR} \
+ --with-profile \
+ --with-syslog \
+ --with-utmp \
+ --with-vfs \
+ --with-msdfs \
+ --with-readline=/usr \
+ --with-sambabook=${PREFIX}/swat/using_samba \
+ 2>&1 | tee mout-config
+fi
+
+cat >> include/config.h <<EOF
+#ifdef HAVE_LONGLONG
+#undef HAVE_LONGLONG
+#endif
+EOF
+
+sed -e "s/nobody/nouser/" include/local.h > /tmp/nouser$$
+cp /tmp/nouser$$ include/local.h
+rm -f /tmp/nouser$$
+
+cd ../examples/VFS
+[ -f mout-config ] && {
+ if [ "$V" = "echo" ]
+ then
+ echo "mv mout-config mout-config$$"
+ else
+ mv mout-config mout-config$$
+ fi
+}
+if [ "$V" = "echo" ]
+then
+ echo "./configure 2>&1 | tee mout-config"
+else
+ ./configure 2>&1 | tee mout-config
+fi
diff --git a/packaging/Caldera/OpenServer/Install b/packaging/Caldera/OpenServer/Install
new file mode 100755
index 00000000000..7a38533b1c1
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Install
@@ -0,0 +1,195 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+# Make sure we pick up the install binary from /usr/local/bin
+# rather than /etc/install
+#PATH=/usr/local/bin:$PATH
+#export PATH
+
+PREFIX=/usr/lib/samba
+HERE=`pwd`
+PKGDIR=packaging/Caldera/OpenServer
+
+BUILD_ROOT=${HERE}/dist
+BLDFIX=${BUILD_ROOT}/${PREFIX}
+$V rm -rf $BUILD_ROOT
+$V mkdir -p $BUILD_ROOT/etc/copyrights
+$V mkdir -p $BUILD_ROOT/etc/init.d
+$V mkdir -p $BUILD_ROOT/etc/samba.d
+$V mkdir -p $BUILD_ROOT/usr/lib/mkdev
+$V mkdir -p $BUILD_ROOT/doc
+$V mkdir -p ${BLDFIX}/bin
+$V mkdir -p ${BLDFIX}/sbin
+$V mkdir -p ${BLDFIX}/swat/using_samba/gifs
+$V mkdir -p ${BLDFIX}/swat/using_samba/figs
+$V mkdir -p ${BLDFIX}/swat/images
+$V mkdir -p ${BLDFIX}/swat/help
+$V mkdir -p ${BLDFIX}/swat/include
+$V mkdir -p ${BLDFIX}/man/man.1
+$V mkdir -p ${BLDFIX}/man/man.5
+$V mkdir -p ${BLDFIX}/man/man.7
+$V mkdir -p ${BLDFIX}/man/man.8
+$V mkdir -p ${BLDFIX}/man/cat.1
+$V mkdir -p ${BLDFIX}/man/cat.5
+$V mkdir -p ${BLDFIX}/man/cat.7
+$V mkdir -p ${BLDFIX}/man/cat.8
+$V mkdir -p ${BLDFIX}/var/locks
+$V mkdir -p ${BLDFIX}/lib/codepages/src
+
+# Copy into the dist tree the custom data files
+for i in Clean Install MakeSSO Packem Remove cdmt.config
+do
+ $V cp pkg/$i ${BUILD_ROOT}
+done
+for i in cntl input
+do
+ $V rm -rf ${BUILD_ROOT}/$i
+ $V cp -r pkg/$i ${BUILD_ROOT}/$i
+done
+
+cd ../../..
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool
+do
+$V install -m755 -s source/bin/$i ${BLDFIX}/bin
+done
+for i in mksmbpasswd.sh smbtar
+do
+$V install -m755 source/script/$i ${BLDFIX}/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat debug2html smbfilter
+do
+$V install -m755 -s source/bin/$i ${BLDFIX}/sbin
+done
+
+# Install VFS libraries
+$V install -m644 -s examples/VFS/block/block.so ${BLDFIX}/lib
+$V install -m644 -s examples/VFS/audit.so ${BLDFIX}/lib
+$V install -m644 -s examples/VFS/recycle/recycle.so ${BLDFIX}/lib
+$V install -m644 -s examples/VFS/skel.so ${BLDFIX}/lib
+
+# Install level 1 man pages
+for i in *.1
+do
+$V install -m644 docs/manpages/$i ${BLDFIX}/man/man.1
+done
+
+# Install codepage source files
+for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+do
+$V install -m644 source/codepages/codepage_def.$i ${BLDFIX}/lib/codepages/src
+done
+for i in 437 737 850 852 861 866 932 936 949 950 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+do
+$V install -m644 source/codepages/CP$i.TXT ${BLDFIX}/lib/codepages/src
+done
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/help
+done
+for i in swat/images/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/images
+done
+for i in swat/include/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/include
+done
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba/gifs
+done
+
+# Install the miscellany
+$V install -m644 docs/manpages/smb.conf.5 ${BLDFIX}/man/man.5
+$V install -m644 docs/manpages/lmhosts.5 ${BLDFIX}/man/man.5
+$V install -m644 docs/manpages/smbpasswd.5 ${BLDFIX}/man/man.5
+$V install -m644 docs/manpages/samba.7 ${BLDFIX}/man/man.7
+$V install -m644 docs/manpages/smbd.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/nmbd.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/smbpasswd.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/swat.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/smbmount.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/smbmnt.8 ${BLDFIX}/man/man.8
+$V install -m644 docs/manpages/smbumount.8 ${BLDFIX}/man/man.8
+$V install -m644 examples/VFS/recycle/recycle.conf ${BLDFIX}/lib
+$V install -m644 examples/VFS/block/samba-block.conf ${BUILD_ROOT}/etc/samba.d
+$V install -m644 ${PKGDIR}/example.block.smb.conf ${BUILD_ROOT}/etc/samba.d
+$V install -m644 ${PKGDIR}/smb.conf $BUILD_ROOT/etc/samba.d/smb.conf.default
+$V install -m644 ${PKGDIR}/smbusers $BUILD_ROOT/etc/samba.d/smbusers
+$V install -m644 ${PKGDIR}/lmhosts $BUILD_ROOT/etc/samba.d/lmhosts
+$V install -m755 ${PKGDIR}/smbprint ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/findsmb ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/smbadduser ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/initconfig ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/smb.init $BUILD_ROOT/etc/init.d/samba
+$V install -m755 ${PKGDIR}/smb.mkdev $BUILD_ROOT/usr/lib/mkdev/samba
+$V install -m644 ${PKGDIR}/docview.html $BUILD_ROOT/doc/index.html
+$V install -m644 ${PKGDIR}/osr5config.html $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/sco_logo_med.gif $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/samba_help.desktop $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/samba_using.desktop $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/samba_configure.desktop $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/samba.directory $BUILD_ROOT/doc
+$V install -m644 ${PKGDIR}/swat.readme ${BLDFIX}/swat/README
+$V install -m644 ${PKGDIR}/copyrights $BUILD_ROOT/etc/copyrights/samba
+
+for i in ${PKGDIR}/man/cat.1/*; do
+$V install -m644 $i ${BLDFIX}/man/cat.1
+done
+for i in ${PKGDIR}/man/cat.5/*; do
+$V install -m644 $i ${BLDFIX}/man/cat.5
+done
+for i in ${PKGDIR}/man/cat.7/*; do
+$V install -m644 $i ${BLDFIX}/man/cat.7
+done
+for i in ${PKGDIR}/man/cat.8/*; do
+$V install -m644 $i ${BLDFIX}/man/cat.8
+done
+
+# The following is now done in the postinstall script
+#
+# if [ "$V" = "echo" ]
+# then
+# echo "echo 127.0.0.1 localhost > $BUILD_ROOT/etc/lmhosts"
+# else
+# echo 127.0.0.1 localhost > $BUILD_ROOT/etc/lmhosts
+# fi
+#
+# Build codepage load files
+# $V cd ${BLDFIX}/lib/codepages
+# for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+# do
+# $V ${PREFIX}/bin/make_smbcodepage c $i \
+# ${BLDFIX}/lib/codepages/src/codepage_def.$i \
+# ${BLDFIX}/lib/codepages/codepage.$i
+# done
+# for i in 437 737 850 852 861 866 932 936 949 950 \
+# ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+# do
+# $V ${PREFIX}/bin/make_unicodemap $i \
+# ${BLDFIX}/lib/codepages/src/CP$i.TXT \
+# ${BLDFIX}/lib/codepages/unicode_map.$i
+# done
diff --git a/packaging/Caldera/OpenServer/Makevol b/packaging/Caldera/OpenServer/Makevol
new file mode 100755
index 00000000000..dc57b246ef5
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Makevol
@@ -0,0 +1,10 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+./Configure $*
+./Compile $*
+./Install $*
+./Package $*
diff --git a/packaging/Caldera/OpenServer/Package b/packaging/Caldera/OpenServer/Package
new file mode 100755
index 00000000000..c954e55e1e8
--- /dev/null
+++ b/packaging/Caldera/OpenServer/Package
@@ -0,0 +1,13 @@
+#!/bin/ksh
+#
+# Now create the actual custom installable media images
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+$V cd dist
+$V ./MakeSSO
diff --git a/packaging/Caldera/OpenServer/README b/packaging/Caldera/OpenServer/README
new file mode 100755
index 00000000000..678e45a90cf
--- /dev/null
+++ b/packaging/Caldera/OpenServer/README
@@ -0,0 +1,29 @@
+Preparation Date: January 24, 2002
+Preparer: Evan Hunt <evanh@caldera.com>
+
+Instructions: Preparing Samba Packages for SCO OpenServer
+===============================================================
+
+We provide support only for current versions of SCO OpenServer
+
+To produce the custom installable media images simply type (in this directory):
+ # ./Makevol
+
+The resultant samba media images should reside in the ./dist subdirectory.
+To install from the media images, issue the command (as root):
+
+ # cd dist
+ # ./Install
+
+Alternately, each of the steps in building the media images may be performed
+individually by invoking each of the following:
+
+ # ./Configure
+ # ./Compile
+ # ./Install
+ # ./Package
+
+If files are added or deleted from the SCO OpenServer Samba distribution then
+the prototype file in the pkg directory should be appropriately modified.
+The files in the pkg subdirectory were initially created using the mkpkg
+package from SCO Skunkware (see http://www.sco.com/skunkware).
diff --git a/packaging/Caldera/OpenServer/callogo.gif b/packaging/Caldera/OpenServer/callogo.gif
new file mode 100755
index 00000000000..0f7a266b775
--- /dev/null
+++ b/packaging/Caldera/OpenServer/callogo.gif
Binary files differ
diff --git a/packaging/Caldera/OpenServer/copyrights b/packaging/Caldera/OpenServer/copyrights
new file mode 100755
index 00000000000..e7abb9b6c75
--- /dev/null
+++ b/packaging/Caldera/OpenServer/copyrights
@@ -0,0 +1,50 @@
+Copyright (C) 1990-1998 Karl Auer
+Copyright (C) 1991-1998 Free Software Foundation, Inc
+Copyright (C) 1991-1998, 2000 Christopher R. Hertel
+Copyright (C) 1991-1999 Unicode, Inc
+Copyright (C) 1992-2001 Jeremy R. Allison
+Copyright (C) 1992-2002 Andrew Tridgell
+Copyright (C) 1992-2002 The Samba Team
+Copyright (C) 1994-2001 Luke Kenneth Casson Leighton
+Copyright (C) 1995 Patrick Powell
+Copyright (C) 1995-1998 Paal-Kr. Engstad
+Copyright (C) 1995-1998 Ricky Poulten
+Copyright (C) 1995-1998 Volker Lendecke
+Copyright (C) 1996 Alex O. Yuriev
+Copyright (C) 1996 Cristian Gafton
+Copyright (C) 1996 Elliot Lee, Red Hat Software
+Copyright (C) 1996-1998 Andrew G. Morgan
+Copyright (C) 1997-1998 Norm Jacobs
+Copyright (C) 1997-1998 Sun Microsystems, Inc
+Copyright (C) 1997-1998 University of Minnesota
+Copyright (C) 1997-2000 Paul Ashton
+Copyright (C) 1998 Benny Holmgren
+Copyright (C) 1998 Christian Starkjohann
+Copyright (C) 1998 Francesco Ferrara
+Copyright (C) 1998 John D. Blair
+Copyright (C) 1998 Red Hat Software
+Copyright (C) 1998-2001 Jean Francois Micouleau
+Copyright (C) 1998-2001 John H Terpsta
+Copyright (C) 1998-2001 Richard Sharpe
+Copyright (C) 1998-2002 Tim Potter
+Copyright (C) 1999 Easy Software Products
+Copyright (C) 1999 Hewlett-Packard Company
+Copyright (C) 1999 Jan Rkorajski
+Copyright (C) 1999-2000 Marc Jacobsen
+Copyright (C) 1999-2001 Michael R Sweet
+Copyright (C) 2000 Elrond
+Copyright (C) 2000 Paul `Rusty' Russell
+Copyright (C) 2000 Shirish Kalele
+Copyright (C) 2000 Silicon Graphics, Inc
+Copyright (C) 2000 Ying Chen
+Copyright (C) 2000-2002 Gerald Carter
+Copyright (C) 2000-2002 Simo Sorce
+Copyright (C) 2001 Andrew Esh
+Copyright (C) 2001 Anton Blanchard
+Copyright (C) 2001 Jim McDonough
+Copyright (C) 2001 Shahms King
+Copyright (C) 2001 Steve French
+Copyright (C) 2001 Toomas Soome
+Copyright (C) 2001-2002 Andrew Bartlett
+Copyright (C) 2001-2002 Martin Pool
+Copyright (C) 2002 Herb Lewis
diff --git a/packaging/Caldera/OpenServer/docview.html b/packaging/Caldera/OpenServer/docview.html
new file mode 100755
index 00000000000..9907f171378
--- /dev/null
+++ b/packaging/Caldera/OpenServer/docview.html
@@ -0,0 +1,103 @@
+<HTML>
+<HEAD>
+ <TITLE>Samba for SCO OpenServer</TITLE>
+</HEAD> <BODY TEXT="#000066" BGCOLOR="#FFFFFF" LINK="#0066CC" VLINK="#660033" ALINK="#FFCC00">
+
+<CENTER>
+<IMG SRC="./sco_logo_med.gif" HEIGHT="90" ALT="" </IMG>
+<H1>Samba File and Print Server for SCO OpenServer</H1>
+</CENTER>
+
+Samba is a suite of networking products that implement the
+Windows SMB and CIFS protocols on UNIX and Linux operating
+systems. Samba enables your SCO OpenServer system
+as a file and print server for Windows and OS/2 clients.
+
+<p>
+To order to activate Samba software, you must first configure it
+according to the instructions in
+<a href="./osr5config.html">"Configuring Samba on SCO OpenServer
+systems"</a>.
+We recommend that you consult the O'Reilly & Associates publication
+<a href="../using_samba/index.html">"Using Samba"</a>
+for further information on configuring and administering your Samba
+server. Links to Samba HOWTO documents and manual pages are also
+provided below.
+
+<p>
+For the latest information concerning Samba releases on
+SCO OpenServer systems, including unsupported functionality,
+see the <i>Late News</i> document. It is available on the
+SCO web site and is free to all customers:
+<br>
+<br>
+<a HREF="http://www.sco.com/support/docs/openserver"><i>www.sco.com/support/docs/openserver</i></a>
+
+
+<h3><a href="./samba.7.html">Samba</a> Documentation</h3>
+
+<ul>
+ <li><b>Initial Configuration Instructions</b>
+ <ul>
+ <li><a href="./osr5config.html">Configuring
+ Samba on SCO OpenServer systems</a>
+ </ul>
+ <li><b>Books</b>
+ <ul>
+ <li><a href="../using_samba/index.html">Using Samba</a> - by Robert Eckstein, David Collier-Brown and Peter Kelly.
+ </ul>
+ <li><b>Samba HOWTO Collection</b></li>
+ <ul>
+ <li><a href="./DOMAIN_MEMBER.html">security = domain in Samba 2.x</a>
+ <li><a href="./winbind.html">Unified Logons between Windows NT and UNIX Using Winbind</a>
+ <li><a href="./msdfs_setup.html">Setting Samba as an MS-DFS server</a>
+ <li><a href="./NT_Security.html">UNIX Permission Bits and Samba 2.x</a>
+ <li><a href="./OS2-Client-HOWTO.html">OS/2 Clients and Samba</a>
+ <li><a href="./printer_driver2.html">Printing under Samba 2.2.x</a>
+ <li><a href="./Integrating-with-Windows.html">Integrating
+MS Windows networks with Samba</a>
+ <li><a href="./Samba-HOWTO-Collection.html">Entire Collection (one file; includes developer information)</a>
+ </ul>
+ <li><b>Daemons</b>
+ <ul>
+ <li><a href="./smbd.8.html">smbd</a> - the SMB daemon
+ <li><a href="./nmbd.8.html">nmbd</a> - the NetBIOS nameserver
+ <li><a href="./winbindd.8.html">winbindd</a> - the winbind daemon
+ </ul>
+ <li><b>Configuration Files</b>
+ <ul>
+ <li><a href="./smb.conf.5.html">smb.conf</a> - the main Samba configuration file
+ <li><a href="./lmhosts.5.html">lmhosts</a> - NetBIOS hosts file
+ <li><a href="./smbpasswd.5.html">smbpasswd</a> - SMB password file
+ </ul>
+ <li><b>Administrative Utilities</b>
+ <ul>
+ <li><a href="./smbcontrol.1.html">smbcontrol</a> - send control messages to Samba daemons
+ <li><a href="./smbpasswd.8.html">smbpasswd</a> - managing SMB passwords
+ <li><a href="./swat.8.html">SWAT</a> - web configuration tool
+ <li><a href="./make_smbcodepage.1.html">make_smbcodepage</a> - codepage creation
+ <li><a href="./make_unicodemap.1.html">make_unicodemap</a> - unicode map file creation
+ </ul>
+ <li><b>Client Tools</b>
+ <ul>
+ <li><a href="./rpcclient.1.html">rpcclient</a> - command line MS-RPC client
+ <li><a href="./smbtar.1.html">smbtar</a> - SMB backup tool
+ <li><a href="./smbclient.1.html">smbclient</a> - command line SMB client
+ <li><a href="./smbmnt.8.html" >smbmnt</a> - helper utility for mounting SMB filesystems on Linux hosts
+ <li><a href="./smbmount.8.html" >smbmount</a> - user space tool for mounting SMB filesystems under Linux
+ <li><a href="./smbspool.8.html" >smbspool</a> - command line SMB print client
+ <li><a href="./smbumount.8.html" >smbumount</a> - user space tool for umounting SMB filesystems under Linux
+ </ul>
+ <li><b>Diagnostic Utilities</b>
+ <ul>
+ <li><a href="./smbstatus.1.html">smbstatus</a> - monitoring Samba
+ <li><a href="./testparm.1.html">testparm</a> - validating your config file
+ <li><a href="./testprns.1.html">testprns</a> - testing printer configuration
+ <li><a href="./nmblookup.1.html">nmblookup</a> - NetBIOS name query tool
+ </ul>
+</ul>
+
+<HR>
+<A HREF="http://www.sco.com/company/legal/">Copyright</A>
+&#169; 2002 Caldera International, Inc. All Rights Reserved.
+</HTML>
diff --git a/packaging/Caldera/OpenServer/example.block.smb.conf b/packaging/Caldera/OpenServer/example.block.smb.conf
new file mode 100755
index 00000000000..793fbeb52b1
--- /dev/null
+++ b/packaging/Caldera/OpenServer/example.block.smb.conf
@@ -0,0 +1,5 @@
+[homes]
+ comment = Home Directories
+ vfs object = /usr/lib/samba/lib/block.so
+ browseable = yes
+ writable = yes
diff --git a/packaging/Caldera/OpenServer/findsmb b/packaging/Caldera/OpenServer/findsmb
new file mode 100755
index 00000000000..08c5df11250
--- /dev/null
+++ b/packaging/Caldera/OpenServer/findsmb
@@ -0,0 +1,145 @@
+#!/usr/bin/perl
+#
+# Prints info on all smb responding machines on a subnet.
+# This script needs to be run on a machine without nmbd running and be
+# run as root to get correct info from WIN95 clients.
+#
+# syntax:
+# findsmb [subnet broadcast address]
+#
+# with no agrument it will list machines on the current subnet
+#
+# There will be a "+" in front of the workgroup name for machines that are
+# local master browsers for that workgroup. There will be an "*" in front
+# of the workgroup name for machines that are the domain master browser for
+# that workgroup.
+#
+
+$SAMBABIN = "/usr/lib/samba/bin";
+
+for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } else {
+ if ($_) {
+ $BCAST = "-B $_";
+ }
+ }
+}
+
+sub ipsort # do numeric sort on last field of IP address
+{
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
+}
+
+# look for all machines that respond to a name lookup
+
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*'|") ||
+ die("Can't run nmblookup '*'.\n");
+
+# get rid of all lines that are not a response IP address,
+# strip everything but IP address and sort by last field in address
+
+@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
+
+# print header info
+
+print "\nIP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
+print "---------------------------------------------------------------------\n";
+
+foreach $ip (@ipaddrs) # loop through each IP address found
+{
+ $ip =~ s/\n//; # strip newline from IP address
+
+# find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -r -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+# get the first <00> name
+
+ @name = grep(/<00>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) { # we have a netbios name
+ if (/GROUP/) { # is it a group name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ } else {
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cure inside name space but not
+# names starting or ending with spaces
+ /(.{1,15})\s+<00>\s+/;
+ $name = $1;
+ }
+
+# do an smbclient command on the netbios name.
+
+ open(SMB,"$SAMBABIN/smbclient -N -L $name -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+# look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+# for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+# Same as before for space and characters
+ /(.{1,15})\s+<00>\s+/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+
+# see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+# line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
+
+ } else { # no netbios name found
+# try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup
+ print "===============================================================\n";
+ print @nmblookup;
+ }
+ print "$ip".' 'x(16-length($ip))."$name\n";
+ }
+}
+
diff --git a/packaging/Caldera/OpenServer/initconfig b/packaging/Caldera/OpenServer/initconfig
new file mode 100755
index 00000000000..518d5962c43
--- /dev/null
+++ b/packaging/Caldera/OpenServer/initconfig
@@ -0,0 +1,254 @@
+#!/bin/sh
+# Initial configuration script for Samba.
+# This script should be run once, immediately after Samba is installed,
+# to get a basic smb.conf script into place. Subsequent modification
+# of this initial configuration should be done by swat.
+#
+# It is expected that in future versions of Samba, swat will be able to
+# do the initial configuration as well, and this script will become
+# unnecessary.
+
+CONF_SRC=/etc/samba.d/smb.conf.default
+CONF=/etc/samba.d/smb.conf
+
+# getyn: ask a question, return value indicates response
+
+getyn () {
+ while true; do
+ echo "$1 [$2] \c"
+ read answer
+ [ -z "$answer" ] && answer=$2
+
+ case $answer in
+ [Yy]*) echo; return 0;
+ ;;
+ [Nn]*) echo; return 1;
+ ;;
+ *) echo "Please answer yes or no."
+ continue
+ ;;
+ esac
+ done
+}
+
+# conf_replace: call sed to replace strings in smb.conf file with new
+# values, and if necessary uncomment the lines in which those strings
+# appear. For this to work, the source file needs to contain unique
+# placeholder strings to be replaced, e.g., %%WORKGROUP%%
+
+conf_replace () {
+ sed -e 's/^;*\(.*\)'$1'\(.*\)$/\1'$2'\2/' < $CONF > /tmp/smb.conf.$$
+ cp -f /tmp/smb.conf.$$ $CONF
+ rm -f /tmp/smb.conf.$$
+}
+
+# Begin main
+
+# Check whether conf file has already been edited
+if [ -f $CONF ]; then
+ cmp -s $CONF_SRC $CONF || {
+ echo "The file $CONF appears to have been previously edited.
+If you continue, this file will be restored to its original
+state and any changes you have made may be lost.\n"
+ if getyn "Continue?" No; then
+ echo "Backing up $CONF to ${CONF}-\n"
+ cp -f $CONF ${CONF}-
+ cp -f $CONF_SRC $CONF
+ else
+ exit 0
+ fi
+ }
+else
+ cp -f $CONF_SRC $CONF
+fi
+
+# Question 1: Workgroup/Domain Name
+# Default is MYGROUP. Responses must begin with an alphabetical
+# character and contain no punctuation.
+while true; do
+ default=MYGROUP
+ echo "Enter Workgroup/NT-Domain name: [$default] \c"
+ read workgroup
+
+ if [ -z "$workgroup" ]; then
+ workgroup=$default
+ fi
+
+ set -- $workgroup
+ if [ $# -gt 1 ]; then
+ echo "ERROR: Workgroup names cannot contain spaces or punctuation.\n"
+ continue
+ fi
+
+ workgroup=`echo $workgroup | tr a-z A-Z | tr -d [:punct:]`
+ if expr "$workgroup" : '[^A-Z]' >&-; then
+ echo "ERROR: Workgroup name must begin with an alphabetic character.\n"
+ continue
+ fi
+
+ echo "Workgroup name set to \"$workgroup\".\n"
+
+ break
+done
+
+
+# Question 2: Machine Name
+# Default is the uname, forced to capital letters and with punctuation
+# excised. Responses must begin with an alphabetical
+# character and contain no punctuation.
+while true; do
+ default=`uname -n | tr a-z A-Z | tr -d [:punct:]`
+ echo "Enter Machine name: [$default] \c"
+ read name
+
+ if [ -z "$name" ]; then
+ name=$default
+ fi
+
+ set -- $name
+ if [ $# -gt 1 ]; then
+ echo "ERROR: Machine names cannot contain spaces or punctuation.\n"
+ continue
+ fi
+
+ name=`echo $name | tr a-z A-Z | tr -d [:punct:]`
+ if expr "$name" : '[^A-Z]' >&-; then
+ echo "ERROR: Machine name must begin with an alphabetic character.\n"
+ continue
+ fi
+
+ echo "Machine name set to \"$name\".\n"
+
+ break
+done
+
+# Question 3: use WINS?
+wins=false
+if getyn "Will this system use WINS (recommended)?" Yes; then
+ wins=true
+fi
+
+# Optional questions, asked only if WINS will be used
+if [ "$wins" = "true" ]; then
+ # Question 3.1: Are we the WINS server?
+ echo "NOTE: A workgroup can have only one WINS server."
+ wins_svr=false
+ if getyn "Will this system be the WINS server for your workgroup?" No; then
+ wins_svr=true
+ fi
+
+ # Question 3.2: Who is the WINS server?
+ if [ "$wins_svr" = "false" ]; then
+ while true; do
+ echo "Enter the address of the primary WINS server for your workgroup: \c"
+ read wins_addr
+
+ if expr "$wins_addr" : '[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*$' >&- ; then
+ echo
+ break
+ fi
+
+ echo "ERROR: Invalid IP address format.\n"
+ done
+ fi
+fi
+
+# Question 4: Which interfaces will be active?
+iflist=`ifconfig -a | grep -v LOOPBACK | grep '^[^ ]*:' | cut -f1 -d:`
+
+set -- $iflist
+if [ "$#" -eq 0 ]; then
+ echo "FATAL ERROR: No network interfaces"
+ exit 1
+elif [ "$#" -eq 1 ]; then
+ interfaces=$1
+else
+ while true; do
+ interfaces=""
+ echo "Which of the following interfaces should Samba run on?\n"
+ for i in $iflist; do
+ addr=`ifconfig $i | grep "inet " | sed 's/inet \([^ ]*\) .*$/\1/'`
+ echo "\t$i:\t$addr"
+ done
+ echo "\nList all interfaces to activate (e.g., net0, net1, etc): \c"
+ read response
+ for i in $response; do
+ found=false
+ for j in $iflist; do
+ if [ "$i" = "$j" ]; then
+ found=true
+ break
+ fi
+ done
+ if [ "$found" = "true" ]; then
+ interfaces="$interfaces $j"
+ else
+ echo "ERROR: Invalid interface name $i\n"
+ continue 2
+ fi
+ done
+
+ interfaces="$interfaces lo0 atl0"
+ break
+ done
+fi
+
+# Question 5: Are we part of an existing security domain or active # directory?
+domain_exists=false
+if getyn "Will this system be part of a currently existing Microsoft Security\n\
+Domain or Active Directory?" No; then
+ domain_exists=true
+fi
+
+# Optional questions, depending on response to question 5
+if [ "$domain_exists" = "true" ]; then
+ # Question 5.1: (if yes to 5) Who's the PDC?
+ default='*'
+ echo "Enter the name of the Primary Domain Controller: [*] \c"
+ read pdc
+ if [ -z "$pdc" ]; then
+ pdc=$default
+ else
+ pdc=`echo $pdc | tr a-z A-Z | tr -d [:punct:]`
+ fi
+ echo "Primary Domain Controller set to \"$pdc\".\n"
+else
+ # Question 5.2: (if no to 5) Are we going to be the PDC?
+ domain_master=false
+ if getyn "Will this system be the domain controller for a new Microsoft\n\
+Security Domain?" No; then
+ domain_master=true
+ fi
+fi
+
+# Done asking questions.
+# Edit conf file with new values
+conf_replace %%WORKGROUP%% "$workgroup"
+conf_replace %%NBNAME%% "$name"
+
+if [ "$wins" = true ]; then
+ if [ "$wins_svr" = true ]; then
+ conf_replace %%WINSSUPPORT%% yes
+ else
+ conf_replace %%WINSSERVER%% $wins_addr
+ fi
+fi
+
+conf_replace %%INTERFACES%% "$interfaces"
+conf_replace %%BINDONLY%% yes
+
+if [ "$domain_exists" = true ]; then
+ conf_replace %%SECURITY%% domain
+ conf_replace %%PWSERVER%% "$pdc"
+else
+ conf_replace %%SECURITY%% user
+fi
+
+if [ "$domain_master" = true ]; then
+ conf_replace %%DOMAINMASTER%% yes
+ conf_replace %%DOMAINLOGONS%% yes
+ conf_replace %%OSLEVEL%% 33
+else
+ conf_replace %%OSLEVEL%% 20
+fi
+
diff --git a/packaging/Caldera/OpenServer/lmhosts b/packaging/Caldera/OpenServer/lmhosts
new file mode 100755
index 00000000000..75721cd5afd
--- /dev/null
+++ b/packaging/Caldera/OpenServer/lmhosts
@@ -0,0 +1 @@
+127.0.0.1 localhost
diff --git a/packaging/Caldera/OpenServer/man/cat.1/findsmb.1 b/packaging/Caldera/OpenServer/man/cat.1/findsmb.1
new file mode 100755
index 00000000000..d6b6f753921
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/findsmb.1
@@ -0,0 +1,132 @@
+
+
+
+ FFFFIIIINNNNDDDDSSSSMMMMBBBB((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) FFFFIIIINNNNDDDDSSSSMMMMBBBB((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ findsmb - list info about machines that respond to SMB name
+ queries on a subnet
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ffffiiiinnnnddddssssmmmmbbbb [ ssssuuuubbbbnnnneeeetttt bbbbrrrrooooaaaaddddccccaaaasssstttt aaaaddddddddrrrreeeessssssss ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This perl script is part of the Samba suite.
+
+ ffffiiiinnnnddddssssmmmmbbbb is a perl script that prints out several pieces of
+ information about machines on a subnet that respond to SMB
+ name query requests. It uses nnnnmmmmbbbbllllooooooookkkkuuuupppp((((1111)))) to obtain this
+ information.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ssssuuuubbbbnnnneeeetttt bbbbrrrrooooaaaaddddccccaaaasssstttt aaaaddddddddrrrreeeessssssss
+ Without this option, ffffiiiinnnnddddssssmmmmbbbb will probe the subnet of
+ the machine where ffffiiiinnnnddddssssmmmmbbbb is run. This value is passed
+ to nnnnmmmmbbbbllllooooooookkkkuuuupppp as part of the -B option
+
+ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
+ The output of ffffiiiinnnnddddssssmmmmbbbb lists the following information for
+ all machines that respond to the initial nnnnmmmmbbbbllllooooooookkkkuuuupppp for any
+ name: IP address, NetBIOS name, Workgroup name, operating
+ system, and SMB server version.
+
+ There will be a '+' in front of the workgroup name for
+ machines that are local master browsers for that workgroup.
+ There will be an '*' in front of the workgroup name for
+ machines that are the domain master browser for that
+ workgroup. Machines that are running Windows, Windows 95 or
+ Windows 98 will not show any information about the operating
+ system or server version.
+
+ The command must be run on a system without nnnnmmmmbbbbdddd running. If
+ nnnnmmmmbbbbdddd is running on the system, you will only get the IP
+ address and the DNS name of the machine. To get proper
+ responses from Windows 95 and Windows 98 machines, the
+ command must be run as root.
+
+ For example running ffffiiiinnnnddddssssmmmmbbbb on a machine without nnnnmmmmbbbbdddd
+ running would yield output similar to the following
+
+ IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION
+ ---------------------------------------------------------------------
+ 192.168.35.10 MINESET-TEST1 [DMVENGR]
+ 192.168.35.55 LINUXBOX *[MYGROUP] [Unix] [Samba 2.0.6]
+ 192.168.35.56 HERBNT2 [HERB-NT]
+ 192.168.35.63 GANDALF [MVENGR] [Unix] [Samba 2.0.5a for IRIX]
+ 192.168.35.65 SAUNA [WORKGROUP] [Unix] [Samba 1.9.18p10]
+ 192.168.35.71 FROGSTAR [ENGR] [Unix] [Samba 2.0.0 for IRIX]
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ FFFFIIIINNNNDDDDSSSSMMMMBBBB((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) FFFFIIIINNNNDDDDSSSSMMMMBBBB((((1111))))
+
+
+
+ 192.168.35.78 HERBDHCP1 +[HERB]
+ 192.168.35.88 SCNT2 +[MVENGR] [Windows NT 4.0] [NT LAN Manager 4.0]
+ 192.168.35.93 FROGSTAR-PC [MVENGR] [Windows 5.0] [Windows 2000 LAN Manager]
+ 192.168.35.97 HERBNT1 *[HERB-NT] [Windows NT 4.0] [NT LAN Manager 4.0]
+
+
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ nnnnmmmmbbbbdddd((((8888)))) ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ and nnnnmmmmbbbbllllooooooookkkkuuuupppp((((1111))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/make_smbcodepage.1 b/packaging/Caldera/OpenServer/man/cat.1/make_smbcodepage.1
new file mode 100755
index 00000000000..b76a57e4ad6
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/make_smbcodepage.1
@@ -0,0 +1,198 @@
+
+
+
+ MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222))))MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ make_smbcodepage - construct a codepage file for Samba
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee cccc||||dddd ccccooooddddeeeeppppaaaaggggeeee iiiinnnnppppuuuuttttffffiiiilllleeee oooouuuuttttppppuuuuttttffffiiiilllleeee
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee compiles or de-compiles codepage files for
+ use with the internationalization features of Samba 2.2
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ cccc||||dddd This tells mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee if it is compiling (_c) a
+ text format code page file to binary, or (_d) de-
+ compiling a binary codepage file to text.
+
+ ccccooooddddeeeeppppaaaaggggeeee
+ This is the codepage we are processing (a number, e.g.
+ 850).
+
+ iiiinnnnppppuuuuttttffffiiiilllleeee
+ This is the input file to process. In the _c case this
+ will be a text codepage definition file such as the
+ ones found in the Samba _s_o_u_r_c_e/_c_o_d_e_p_a_g_e_s directory. In
+ the _d case this will be the binary format codepage
+ definition file normally found in the _l_i_b/_c_o_d_e_p_a_g_e_s
+ directory in the Samba install directory path.
+
+ oooouuuuttttppppuuuuttttffffiiiilllleeee
+ This is the output file to produce.
+
+ SSSSAAAAMMMMBBBBAAAA CCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE FFFFIIIILLLLEEEESSSS
+ A text Samba codepage definition file is a description that
+ tells Samba how to map from upper to lower case for
+ characters greater than ascii 127 in the specified DOS code
+ page. Note that for certain DOS codepages (437 for example)
+ mapping from lower to upper case may be non-symmetrical. For
+ example, in code page 437 lower case a acute maps to a plain
+ upper case A when going from lower to upper case, but plain
+ upper case A maps to plain lower case a when lower casing a
+ character.
+
+ A binary Samba codepage definition file is a binary
+ representation of the same information, including a value
+ that specifies what codepage this file is describing.
+
+ As Samba does not yet use UNICODE (current for Samba version
+ 2.2) you must specify the client code page that your DOS and
+ Windows clients are using if you wish to have case
+ insensitivity done correctly for your particular language.
+ The default codepage Samba uses is 850 (Western European).
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222))))MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))
+
+
+
+ Text codepage definition sample files are provided in the
+ Samba distribution for codepages 437 (USA), 737 (Greek), 850
+ (Western European) 852 (MS-DOS Latin 2), 861 (Icelandic),
+ 866 (Cyrillic), 932 (Kanji SJIS), 936 (Simplified Chinese),
+ 949 (Hangul) and 950 (Traditional Chinese). Users are
+ encouraged to write text codepage definition files for their
+ own code pages and donate them to samba@samba.org. All
+ codepage files in the Samba _s_o_u_r_c_e/_c_o_d_e_p_a_g_e_s directory are
+ compiled and installed when a ''''mmmmaaaakkkkeeee iiiinnnnssssttttaaaallllllll'''' command is
+ issued there.
+
+ The client codepage used by the ssssmmmmbbbbdddd server is configured
+ using the cccclllliiiieeeennnntttt ccccooooddddeeee ppppaaaaggggeeee parameter in the ssssmmmmbbbb....ccccoooonnnnffff file.
+
+ FFFFIIIILLLLEEEESSSS
+ ccccooooddddeeeeppppaaaaggggeeee____ddddeeeeffff....<<<<ccccooooddddeeeeppppaaaaggggeeee>>>>
+
+ These are the input (text) codepage files provided in the
+ Samba _s_o_u_r_c_e/_c_o_d_e_p_a_g_e_s directory.
+
+ A text codepage definition file consists of multiple lines
+ containing four fields. These fields are:
+
+ o+ lllloooowwwweeeerrrr: which is the (hex) lower case character mapped on
+ this line.
+
+ o+ uuuuppppppppeeeerrrr: which is the (hex) upper case character that the
+ lower case character will map to.
+
+ o+ mmmmaaaapppp uuuuppppppppeeeerrrr ttttoooo lllloooowwwweeeerrrr which is a boolean value (put either
+ True or False here) which tells Samba if it is to map the
+ given upper case character to the given lower case
+ character when lower casing a filename.
+
+ o+ mmmmaaaapppp lllloooowwwweeeerrrr ttttoooo uuuuppppppppeeeerrrr which is a boolean value (put either
+ True or False here) which tells Samba if it is to map the
+ given lower case character to the given upper case
+ character when upper casing a filename.
+
+ ccccooooddddeeeeppppaaaaggggeeee....<<<<ccccooooddddeeeeppppaaaaggggeeee>>>> - These are the output (binary) codepage
+ files produced and placed in the Samba destination
+ _l_i_b/_c_o_d_e_p_a_g_e directory.
+
+ IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ The location of the server and its support files is a matter
+ for individual system administrators. The following are thus
+ suggestions only.
+
+ It is recommended that the mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee program be
+ installed under the /_u_s_r/_l_o_c_a_l/_s_a_m_b_a hierarchy, in a
+ directory readable by all, writeable only by root. The
+ program itself should be executable by all. The program
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222))))MMMMAAAAKKKKEEEE____SSSSMMMMBBBBCCCCOOOODDDDEEEEPPPPAAAAGGGGEEEE((((1111))))
+
+
+
+ should NOT be setuid or setgid!
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbdddd((((8888)))) smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/make_unicodemap.1 b/packaging/Caldera/OpenServer/man/cat.1/make_unicodemap.1
new file mode 100755
index 00000000000..368914f87c7
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/make_unicodemap.1
@@ -0,0 +1,132 @@
+
+
+
+ MMMMAAAAKKKKEEEE____UUUUNNNNIIIICCCCOOOODDDDEEEEMMMMAAAAPPPP((((1111))))UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222))))MMMMAAAAKKKKEEEE____UUUUNNNNIIIICCCCOOOODDDDEEEEMMMMAAAAPPPP((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ make_unicodemap - construct a unicode map file for Samba
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ mmmmaaaakkkkeeee____uuuunnnniiiiccccooooddddeeeemmmmaaaapppp ccccooooddddeeeeppppaaaaggggeeee iiiinnnnppppuuuuttttffffiiiilllleeee oooouuuuttttppppuuuuttttffffiiiilllleeee
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ mmmmaaaakkkkeeee____uuuunnnniiiiccccooooddddeeeemmmmaaaapppp compiles text unicode map files into binary
+ unicode map files for use with the internationalization
+ features of Samba 2.2.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ccccooooddddeeeeppppaaaaggggeeee
+ This is the codepage or UNIX character set we are
+ processing (a number, e.g. 850).
+
+ iiiinnnnppppuuuuttttffffiiiilllleeee
+ This is the input file to process. This is a text
+ unicode map file such as the ones found in the Samba
+ _s_o_u_r_c_e/_c_o_d_e_p_a_g_e_s directory.
+
+ oooouuuuttttppppuuuuttttffffiiiilllleeee
+ This is the binary output file to produce.
+
+ SSSSAAAAMMMMBBBBAAAA UUUUNNNNIIIICCCCOOOODDDDEEEE MMMMAAAAPPPP FFFFIIIILLLLEEEESSSS
+ A text Samba unicode map file is a description that tells
+ Samba how to map characters from a specified DOS code page
+ or UNIX character set to 16 bit unicode.
+
+ A binary Samba unicode map file is a binary representation
+ of the same information, including a value that specifies
+ what codepage or UNIX character set this file is describing.
+
+ FFFFIIIILLLLEEEESSSS
+ _C_P<_c_o_d_e_p_a_g_e>._T_X_T
+
+ These are the input (text) unicode map files provided in the
+ Samba _s_o_u_r_c_e/_c_o_d_e_p_a_g_e_s directory.
+
+ A text unicode map file consists of multiple lines
+ containing two fields. These fields are :
+
+ o+ _c_h_a_r_a_c_t_e_r - which is the (hex) character mapped on this
+ line.
+
+ o+ _u_n_i_c_o_d_e - which is the (hex) 16 bit unicode character that
+ the character will map to.
+
+ _u_n_i_c_o_d_e__m_a_p.<_c_o_d_e_p_a_g_e> - These are the output (binary)
+ unicode map files produced and placed in the Samba
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ MMMMAAAAKKKKEEEE____UUUUNNNNIIIICCCCOOOODDDDEEEEMMMMAAAAPPPP((((1111))))UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222))))MMMMAAAAKKKKEEEE____UUUUNNNNIIIICCCCOOOODDDDEEEEMMMMAAAAPPPP((((1111))))
+
+
+
+ destination _l_i_b/_c_o_d_e_p_a_g_e directory.
+
+ IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ The location of the server and its support files is a matter
+ for individual system administrators. The following are thus
+ suggestions only.
+
+ It is recommended that the mmmmaaaakkkkeeee____uuuunnnniiiiccccooooddddeeeemmmmaaaapppp program be
+ installed under the $_p_r_e_f_i_x/_s_a_m_b_a hierarchy, in a directory
+ readable by all, writeable only by root. The program itself
+ should be executable by all. The program should NOT be
+ setuid or setgid!
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbdddd((((8888)))) smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/nmblookup.1 b/packaging/Caldera/OpenServer/man/cat.1/nmblookup.1
new file mode 100755
index 00000000000..3ac640c61b6
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/nmblookup.1
@@ -0,0 +1,198 @@
+
+
+
+ NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ nmblookup - NetBIOS over TCP/IP client used to lookup
+ NetBIOS names
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp [ ----ffff ] [ ----MMMM ] [ ----RRRR ] [ ----SSSS ] [ ----rrrr ] [ ----AAAA ] [
+ ----hhhh ] [ ----BBBB <<<<bbbbrrrrooooaaaaddddccccaaaasssstttt aaaaddddddddrrrreeeessssssss>>>> ] [ ----UUUU <<<<uuuunnnniiiiccccaaaasssstttt aaaaddddddddrrrreeeessssssss>>>> ]
+ [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----ssss <<<<ssssmmmmbbbb ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ] [ ----iiii
+ <<<<NNNNeeeettttBBBBIIIIOOOOSSSS ssssccccooooppppeeee>>>> ] [ ----TTTT ] nnnnaaaammmmeeee
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp is used to query NetBIOS names and map them to IP
+ addresses in a network using NetBIOS over TCP/IP queries.
+ The options allow the name queries to be directed at a
+ particular IP broadcast area or to a particular machine. All
+ queries are done over UDP.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----ffff Causes nmblookup to print out the flags in the NMB
+ packet headers. These flags will print out as strings
+ like Authoritative, Recursion_Desired,
+ Recursion_available, etc.
+
+ ----MMMM Searches for a master browser by looking up the NetBIOS
+ name _n_a_m_e with a type of 0x1d. If _n_a_m_e is "-" then it
+ does a lookup on the special name __MSBROWSE__.
+
+ ----RRRR Set the recursion desired bit in the packet to do a
+ recursive lookup. This is used when sending a name
+ query to a machine running a WINS server and the user
+ wishes to query the names in the WINS server. If this
+ bit is unset the normal (broadcast responding) NetBIOS
+ processing code on a machine is used instead. See
+ rfc1001, rfc1002 for details.
+
+ ----SSSS Once the name query has returned an IP address then do
+ a node status query as well. A node status query
+ returns the NetBIOS names registered by a host.
+
+ ----rrrr Try and bind to UDP port 137 to send and receive UDP
+ datagrams. The reason for this option is a bug in
+ Windows 95 where it ignores the source port of the
+ requesting packet and only replies to UDP port 137.
+ Unfortunately, on most UNIX systems root privilege is
+ needed to bind to this port, and in addition, if the
+ nmbd(8) daemon is running on this machine it also binds
+ to this port.
+
+ ----AAAA Interpret _n_a_m_e as an IP Address and do a node status
+ query on this address.
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111))))
+
+
+
+ ----hhhh Print a help (usage) message.
+
+ ----BBBB <<<<bbbbrrrrooooaaaaddddccccaaaasssstttt aaaaddddddddrrrreeeessssssss>>>>
+ Send the query to the given broadcast address. Without
+ this option the default behavior of nmblookup is to
+ send the query to the broadcast address of the network
+ interfaces as either auto-detected or defined in the
+ _i_n_t_e_r_f_a_c_e_s
+ parameter of the _s_m_b._c_o_n_f (_5) file.
+
+ ----UUUU <<<<uuuunnnniiiiccccaaaasssstttt aaaaddddddddrrrreeeessssssss>>>>
+ Do a unicast query to the specified address or host
+ _u_n_i_c_a_s_t _a_d_d_r_e_s_s. This option (along with the -_R option)
+ is needed to query a WINS server.
+
+ ----dddd <<<<ddddeeeebbbbuuuugggglllleeeevvvveeeellll>>>>
+ debuglevel is an integer from 0 to 10.
+
+ The default value if this parameter is not specified is
+ zero.
+
+ The higher this value, the more detail will be logged
+ about the activities of nnnnmmmmbbbbllllooooooookkkkuuuupppp. At level 0, only
+ critical errors and serious warnings will be logged.
+
+ Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a
+ problem. Levels above 3 are designed for use only by
+ developers and generate HUGE amounts of data, most of
+ which is extremely cryptic.
+
+ Note that specifying this parameter here will override
+ the _l_o_g _l_e_v_e_l parameter in the _s_m_b._c_o_n_f(_5) file.
+
+ ----ssss <<<<ssssmmmmbbbb....ccccoooonnnnffff>>>>
+ This parameter specifies the pathname to the Samba
+ configuration file, smb.conf(5) This file controls all
+ aspects of the Samba setup on the machine.
+
+ ----iiii <<<<ssssccccooooppppeeee>>>>
+ This specifies a NetBIOS scope that nnnnmmmmbbbbllllooooooookkkkuuuupppp will use
+ to communicate with when generating NetBIOS names. For
+ details on the use of NetBIOS scopes, see rfc1001.txt
+ and rfc1002.txt. NetBIOS scopes are vvvveeeerrrryyyy rarely used,
+ only set this parameter if you are the system
+ administrator in charge of all the NetBIOS systems you
+ communicate with.
+
+ ----TTTT This causes any IP addresses found in the lookup to be
+ looked up via a reverse DNS lookup into a DNS name, and
+ printed out before each
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBLLLLOOOOOOOOKKKKUUUUPPPP((((1111))))
+
+
+
+ IIIIPPPP aaaaddddddddrrrreeeessssssss ................ NNNNeeeettttBBBBIIIIOOOOSSSS nnnnaaaammmmeeee
+
+ pair that is the normal output.
+
+ nnnnaaaammmmeeee This is the NetBIOS name being queried. Depending upon
+ the previous options this may be a NetBIOS name or IP
+ address. If a NetBIOS name then the different name
+ types may be specified by appending '#<type>' to the
+ name. This name may also be '*', which will return all
+ registered names within a broadcast area.
+
+ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp can be used to query a WINS server (in the same
+ way nnnnssssllllooooooookkkkuuuupppp is used to query DNS servers). To query a WINS
+ server, nnnnmmmmbbbbllllooooooookkkkuuuupppp must be called like this:
+
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp ----UUUU sssseeeerrrrvvvveeeerrrr ----RRRR ''''nnnnaaaammmmeeee''''
+
+ For example, running :
+
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp ----UUUU ssssaaaammmmbbbbaaaa....oooorrrrgggg ----RRRR ''''IIIIRRRRIIIIXXXX####1111BBBB''''
+
+ would query the WINS server samba.org for the domain master
+ browser (1B name type) for the IRIX workgroup.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ nnnnmmmmbbbbdddd((((8888)))) samba(7) and smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/rpcclient.1 b/packaging/Caldera/OpenServer/man/cat.1/rpcclient.1
new file mode 100755
index 00000000000..679a303739d
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/rpcclient.1
@@ -0,0 +1,396 @@
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ rpcclient - tool for executing client side MS-RPC functions
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ rrrrppppcccccccclllliiiieeeennnntttt [ ----AAAA aaaauuuutttthhhhffffiiiilllleeee ] [ ----cccc <<<<ccccoooommmmmmmmaaaannnndddd ssssttttrrrriiiinnnngggg>>>> ] [ ----dddd
+ ddddeeeebbbbuuuugggglllleeeevvvveeeellll ] [ ----hhhh ] [ ----llll llllooooggggffffiiiilllleeee ] [ ----NNNN ] [ ----ssss <<<<ssssmmmmbbbb
+ ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ] [ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee[[[[%%%%ppppaaaasssssssswwwwoooorrrrdddd]]]] ] [ ----WWWW wwwwoooorrrrkkkkggggrrrroooouuuupppp ]
+ [ ----NNNN ] sssseeeerrrrvvvveeeerrrr
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ rrrrppppcccccccclllliiiieeeennnntttt is a utility initially developed to test MS-RPC
+ functionality in Samba itself. It has undergone several
+ stages of development and stability. Many system
+ administrators have now written scripts around it to manage
+ Windows NT clients from their UNIX workstation.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ sssseeeerrrrvvvveeeerrrr
+ NetBIOS name of Server to which to connect. The server
+ can be any SMB/CIFS server. The name is resolved using
+ the _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r line from _s_m_b._c_o_n_f(_5).
+
+ ----AAAA ffffiiiilllleeeennnnaaaammmmeeee
+ This option allows you to specify a file from which to
+ read the username and password used in the connection.
+ The format of the file is
+
+
+ username = <value>
+ password = <value>
+ domain = <value>
+
+
+
+ Make certain that the permissions on the file restrict
+ access from unwanted users.
+
+ ----cccc ''''ccccoooommmmmmmmaaaannnndddd ssssttttrrrriiiinnnngggg''''
+ execute semicolon separated commands (listed below))
+
+ ----dddd ddddeeeebbbbuuuugggglllleeeevvvveeeellll
+ set the debuglevel. Debug level 0 is the lowest and 100
+ being the highest. This should be set to 100 if you are
+ planning on submitting a bug report to the Samba team
+ (see _B_U_G_S._t_x_t).
+
+ ----hhhh Print a summary of command line options.
+
+ ----llll llllooooggggbbbbaaaasssseeeennnnaaaammmmeeee
+ File name for log/debug files. The extension '.client'
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ will be appended. The log file is never removed by the
+ client.
+
+ ----NNNN instruct rrrrppppcccccccclllliiiieeeennnntttt not to ask for a password. By
+ default, rrrrppppcccccccclllliiiieeeennnntttt will prompt for a password. See also
+ the -_U option.
+
+ ----ssss ssssmmmmbbbb....ccccoooonnnnffff
+ Specifies the location of the all important _s_m_b._c_o_n_f
+ file.
+
+ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee[[[[%%%%ppppaaaasssssssswwwwoooorrrrdddd]]]]
+ Sets the SMB username or username and password.
+
+ If %password is not specified, the user will be
+ prompted. The client will first check the UUUUSSSSEEEERRRR
+ environment variable, then the LLLLOOOOGGGGNNNNAAAAMMMMEEEE variable and if
+ either exists, the string is uppercased. If these
+ environmental variables are not found, the username
+ GUEST is used.
+
+ A third option is to use a credentials file which
+ contains the plaintext of the username and password.
+ This option is mainly provided for scripts where the
+ admin doesn't desire to pass the credentials on the
+ command line or via environment variables. If this
+ method is used, make certain that the permissions on
+ the file restrict access from unwanted users. See the
+ -_A for more details.
+
+ Be cautious about including passwords in scripts. Also,
+ on many systems the command line of a running process
+ may be seen via the ppppssss command. To be safe always allow
+ rrrrppppcccccccclllliiiieeeennnntttt to prompt for a password and type it in
+ directly.
+
+ ----WWWW ddddoooommmmaaaaiiiinnnn
+ Set the SMB domain of the username. This overrides the
+ default domain which is the domain defined in smb.conf.
+ If the domain specified is the same as the server's
+ NetBIOS name, it causes the client to log on using the
+ server's local SAM (as opposed to the Domain SAM).
+
+ CCCCOOOOMMMMMMMMAAAANNNNDDDDSSSS
+ LLLLSSSSAAAARRRRPPPPCCCC
+
+ o+ llllssssaaaaqqqquuuueeeerrrryyyy
+
+ o+ llllooooooookkkkuuuuppppssssiiiiddddssss - Resolve a list of SIDs to usernames.
+
+ o+ llllooooooookkkkuuuuppppnnnnaaaammmmeeeessss - Resolve s list of usernames to SIDs.
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ o+ eeeennnnuuuummmmttttrrrruuuussssttttssss
+
+ SSSSAAAAMMMMRRRR
+
+ o+ qqqquuuueeeerrrryyyyuuuusssseeeerrrr
+
+ o+ qqqquuuueeeerrrryyyyggggrrrroooouuuupppp
+
+ o+ qqqquuuueeeerrrryyyyuuuusssseeeerrrrggggrrrroooouuuuppppssss
+
+ o+ qqqquuuueeeerrrryyyyggggrrrroooouuuuppppmmmmeeeemmmm
+
+ o+ qqqquuuueeeerrrryyyyaaaalllliiiiaaaassssmmmmeeeemmmm
+
+ o+ qqqquuuueeeerrrryyyyddddiiiissssppppiiiinnnnffffoooo
+
+ o+ qqqquuuueeeerrrryyyyddddoooommmmiiiinnnnffffoooo
+
+ o+ eeeennnnuuuummmmddddoooommmmggggrrrroooouuuuppppssss
+
+ SSSSPPPPOOOOOOOOLLLLSSSSSSSS
+
+ o+ aaaaddddddddddddrrrriiiivvvveeeerrrr <<<<aaaarrrrcccchhhh>>>> <<<<ccccoooonnnnffffiiiigggg>>>> - Execute an AddPrinterDriver()
+ RPC to install the printer driver information on the
+ server. Note that the driver files should already exist in
+ the directory returned by ggggeeeettttddddrrrriiiivvvveeeerrrrddddiiiirrrr. Possible values
+ for _a_r_c_h are the same as those for the ggggeeeettttddddrrrriiiivvvveeeerrrrddddiiiirrrr
+ command. The _c_o_n_f_i_g parameter is defined as follows:
+
+
+ Long Printer Name:\
+ Driver File Name:\
+ Data File Name:\
+ Config File Name:\
+ Help File Name:\
+ Language Monitor Name:\
+ Default Data Type:\
+ Comma Separated list of Files
+
+
+
+ Any empty fields should be enter as the string "NULL".
+
+ Samba does not need to support the concept of Print
+ Monitors since these only apply to local printers whose
+ driver can make use of a bi-directional link for
+ communication. This field should be "NULL". On a remote NT
+ print server, the Print Monitor for a driver must already
+ be installed prior to adding the driver or else the RPC
+ will fail.
+
+ o+ aaaaddddddddpppprrrriiiinnnntttteeeerrrr <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> <<<<sssshhhhaaaarrrreeeennnnaaaammmmeeee>>>> <<<<ddddrrrriiiivvvveeeerrrrnnnnaaaammmmeeee>>>> <<<<ppppoooorrrrtttt>>>> -
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ Add a printer on the remote server. This printer will be
+ automatically shared. Be aware that the printer driver
+ must already be installed on the server (see aaaaddddddddddddrrrriiiivvvveeeerrrr)
+ and the _p_o_r_tmust be a valid port name (see eeeennnnuuuummmmppppoooorrrrttttssss.
+
+ o+ ddddeeeellllddddrrrriiiivvvveeeerrrr - Delete the specified printer driver for all
+ architectures. This does not delete the actual driver
+ files from the server, only the entry from the server's
+ list of drivers.
+
+ o+ eeeennnnuuuummmmddddaaaattttaaaa - Enumerate all printer setting data stored on
+ the server. On Windows NT clients, these values are stored
+ in the registry, while Samba servers store them in the
+ printers TDB. This command corresponds to the MS Platform
+ SDK GetPrinterData() function (* This command is currently
+ unimplemented).
+
+ o+ eeeennnnuuuummmmjjjjoooobbbbssss <<<<pppprrrriiiinnnntttteeeerrrr>>>> - List the jobs and status of a given
+ printer. This command corresponds to the MS Platform SDK
+ EnumJobs() function (* This command is currently
+ unimplemented).
+
+ o+ eeeennnnuuuummmmppppoooorrrrttttssss [[[[lllleeeevvvveeeellll]]]] - Executes an EnumPorts() call using the
+ specified info level. Currently only info levels 1 and 2
+ are supported.
+
+ o+ eeeennnnuuuummmmddddrrrriiiivvvveeeerrrrssss [[[[lllleeeevvvveeeellll]]]] - Execute an EnumPrinterDrivers()
+ call. This lists the various installed printer drivers for
+ all architectures. Refer to the MS Platform SDK
+ documentation for more details of the various flags and
+ calling options. Currently supported info levels are 1, 2,
+ and 3.
+
+ o+ eeeennnnuuuummmmpppprrrriiiinnnntttteeeerrrrssss [[[[lllleeeevvvveeeellll]]]] - Execute an EnumPrinters() call.
+ This lists the various installed and share printers. Refer
+ to the MS Platform SDK documentation for more details of
+ the various flags and calling options. Currently supported
+ info levels are 0, 1, and 2.
+
+ o+ ggggeeeettttddddaaaattttaaaa <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> - Retrieve the data for a given
+ printer setting. See the eeeennnnuuuummmmddddaaaattttaaaa command for more
+ information. This command corresponds to the
+ GetPrinterData() MS Platform SDK function (* This command
+ is currently unimplemented).
+
+ o+ ggggeeeettttddddrrrriiiivvvveeeerrrr <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> - Retrieve the printer driver
+ information (such as driver file, config file, dependent
+ files, etc...) for the given printer. This command
+ corresponds to the GetPrinterDriver() MS Platform SDK
+ function. Currently info level 1, 2, and 3 are supported.
+
+ o+ ggggeeeettttddddrrrriiiivvvveeeerrrrddddiiiirrrr <<<<aaaarrrrcccchhhh>>>> - Execute a
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ GetPrinterDriverDirectory() RPC to retreive the SMB share
+ name and subdirectory for storing printer driver files for
+ a given architecture. Possible values for _a_r_c_h are
+ "Windows 4.0" (for Windows 95/98), "Windows NT x86",
+ "Windows NT PowerPC", "Windows Alpha_AXP", and "Windows NT
+ R4000".
+
+ o+ ggggeeeettttpppprrrriiiinnnntttteeeerrrr <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> - Retrieve the current printer
+ information. This command corresponds to the GetPrinter()
+ MS Platform SDK function.
+
+ o+ ooooppppeeeennnnpppprrrriiiinnnntttteeeerrrr <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> - Execute an OpenPrinterEx() and
+ ClosePrinter() RPC against a given printer.
+
+ o+ sssseeeettttddddrrrriiiivvvveeeerrrr <<<<pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee>>>> <<<<ddddrrrriiiivvvveeeerrrrnnnnaaaammmmeeee>>>> - Execute a
+ SetPrinter() command to update the printer driver
+ associated with an installed printer. The printer driver
+ must already be correctly installed on the print server.
+
+ See also the eeeennnnuuuummmmpppprrrriiiinnnntttteeeerrrrssss and eeeennnnuuuummmmddddrrrriiiivvvveeeerrrrssss commands for
+ obtaining a list of of installed printers and drivers.
+
+ GGGGEEEENNNNEEEERRRRAAAALLLL OOOOPPPPTTTTIIIIOOOONNNNSSSS
+
+ o+ ddddeeeebbbbuuuugggglllleeeevvvveeeellll - Set the current debug level used to log
+ information.
+
+ o+ hhhheeeellllpppp ((((????)))) - Print a listing of all known commands or
+ extended help on a particular command.
+
+ o+ qqqquuuuiiiitttt ((((eeeexxxxiiiitttt)))) - Exit rrrrppppcccccccclllliiiieeeennnntttt .
+
+ BBBBUUUUGGGGSSSS
+ rrrrppppcccccccclllliiiieeeennnntttt is designed as a developer testing tool and may
+ not be robust in certain areas (such as command line
+ parsing). It has been known to generate a core dump upon
+ failures when invalid parameters where passed to the
+ interpreter.
+
+ From Luke Leighton's original rpcclient man page:
+
+ """"WWWWAAAARRRRNNNNIIIINNNNGGGG!!!! The MSRPC over SMB code has been developed from
+ examining Network traces. No documentation is available from
+ the original creators (Microsoft) on how MSRPC over SMB
+ works, or how the individual MSRPC services work.
+ Microsoft's implementation of these services has been
+ demonstrated (and reported) to be... a bit flaky in places.
+
+ The development of Samba's implementation is also a bit
+ rough, and as more of the services are understood, it can
+ even result in versions of ssssmmmmbbbbdddd((((8888)))) and rrrrppppcccccccclllliiiieeeennnntttt((((1111)))) that are
+ incompatible for some commands or services. Additionally,
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
+
+
+
+ RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) RRRRPPPPCCCCCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ the developers are sending reports to Microsoft, and
+ problems found or reported to Microsoft are fixed in Service
+ Packs, which may result in incompatibilities."
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original rpcclient man page was written by Matthew
+ Geddes, Luke Kenneth Casson Leighton, and rewritten by
+ Gerald Carter. The conversion to DocBook for Samba 2.2 was
+ done by Gerald Carter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 6 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbcacls.1 b/packaging/Caldera/OpenServer/man/cat.1/smbcacls.1
new file mode 100755
index 00000000000..f2233184b1e
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbcacls.1
@@ -0,0 +1,264 @@
+
+
+
+ SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbcacls - Set or get ACLs on an NT file or directory names
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbccccaaaaccccllllssss ////////sssseeeerrrrvvvveeeerrrr////sssshhhhaaaarrrreeee ffffiiiilllleeeennnnaaaammmmeeee [ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee ] [ ----AAAA aaaaccccllllssss
+ ] [ ----MMMM aaaaccccllllssss ] [ ----DDDD aaaaccccllllssss ] [ ----SSSS aaaaccccllllssss ] [ ----CCCC nnnnaaaammmmeeee ] [ ----GGGG
+ nnnnaaaammmmeeee ] [ ----nnnn ] [ ----hhhh ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ The ssssmmmmbbbbccccaaaaccccllllssss program manipulates NT Access Control Lists
+ (ACLs) on SMB file shares.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ The following options are available to the ssssmmmmbbbbccccaaaaccccllllssss program.
+ The format of ACLs is described in the section ACL FORMAT
+
+ ----AAAA aaaaccccllllssss
+ Add the ACLs specified to the ACL list. Existing access
+ control entries are unchanged.
+
+ ----MMMM aaaaccccllllssss
+ Modify the mask value (permissions) for the ACLs
+ specified on the command line. An error will be printed
+ for each ACL specified that was not already present in
+ the ACL list
+
+ ----DDDD aaaaccccllllssss
+ Delete any ACLs specified on the command line. An error
+ will be printed for each ACL specified that was not
+ already present in the ACL list.
+
+ ----SSSS aaaaccccllllssss
+ This command sets the ACLs on the file with only the
+ ones specified on the command line. All other ACLs are
+ erased. Note that the ACL specified must contain at
+ least a revision, type, owner and group for the call to
+ succeed.
+
+ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee
+ Specifies a username used to connect to the specified
+ service. The username may be of the form "username" in
+ which case the user is prompted to enter in a password
+ and the workgroup specified in the _s_m_b._c_o_n_f file is
+ used, or "username%password" or
+ "DOMAIN\username%password" and the password and
+ workgroup names are used as provided.
+
+ ----CCCC nnnnaaaammmmeeee
+ The owner of a file or directory can be changed to the
+ name given using the -_C option. The name can be a sid
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111))))
+
+
+
+ in the form S-1-x-y-z or a name resolved against the
+ server specified in the first argument.
+
+ This command is a shortcut for -M OWNER:name.
+
+ ----GGGG nnnnaaaammmmeeee
+ The group owner of a file or directory can be changed
+ to the name given using the -_G option. The name can be
+ a sid in the form S-1-x-y-z or a name resolved against
+ the server specified n the first argument.
+
+ This command is a shortcut for -M GROUP:name.
+
+ ----nnnn This option displays all ACL information in numeric
+ format. The default is to convert SIDs to names and ACE
+ types and masks to a readable string format.
+
+ ----hhhh Print usage information on the ssssmmmmbbbbccccaaaaccccllllssss program.
+
+ AAAACCCCLLLL FFFFOOOORRRRMMMMAAAATTTT
+ The format of an ACL is one or more ACL entries separated by
+ either commas or newlines. An ACL entry is one of the
+ following:
+
+
+ REVISION:<revision number>
+ OWNER:<sid or name>
+ GROUP:<sid or name>
+ ACL:<sid or name>:<type>/<flags>/<mask>
+
+
+
+ The revision of the ACL specifies the internal Windows NT
+ ACL revision for the security descriptor. If not specified
+ it defaults to 1. Using values other than 1 may cause
+ strange behaviour.
+
+ The owner and group specify the owner and group sids for the
+ object. If a SID in the format CWS-1-x-y-z is specified this
+ is used, otherwise the name specified is resolved using the
+ server on which the file or directory resides.
+
+ ACLs specify permissions granted to the SID. This SID again
+ can be specified in CWS-1-x-y-z format or as a name in which
+ case it is resolved against the server on which the file or
+ directory resides. The type, flags and mask values determine
+ the type of access granted to the SID.
+
+ The type can be either 0 or 1 corresponding to ALLOWED or
+ DENIED access to the SID. The flags values are generally
+ zero for file ACLs and either 9 or 2 for directory ACLs.
+ Some common flags are:
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111))))
+
+
+
+ o+ #define SEC_ACE_FLAG_OBJECT_INHERIT 0x1
+
+ o+ #define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2
+
+ o+ #define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4
+
+ o+ #define SEC_ACE_FLAG_INHERIT_ONLY 0x8
+
+ At present flags can only be specified as decimal or
+ hexadecimal values.
+
+ The mask is a value which expresses the access right granted
+ to the SID. It can be given as a decimal or hexadecimal
+ value, or by using one of the following text strings which
+ map to the NT file permissions of the same name.
+
+ o+ RRRR - Allow read access
+
+ o+ WWWW - Allow write access
+
+ o+ XXXX - Execute permission on the object
+
+ o+ DDDD - Delete the object
+
+ o+ PPPP - Change permissions
+
+ o+ OOOO - Take ownership
+
+ The following combined permissions can be specified:
+
+ o+ RRRREEEEAAAADDDD - Equivalent to 'RX' permissions
+
+ o+ CCCCHHHHAAAANNNNGGGGEEEE - Equivalent to 'RXWD' permissions
+
+ o+ FFFFUUUULLLLLLLL - Equivalent to 'RWXDPO' permissions
+
+ EEEEXXXXIIIITTTT SSSSTTTTAAAATTTTUUUUSSSS
+ The ssssmmmmbbbbccccaaaaccccllllssss program sets the exit status depending on the
+ success or otherwise of the operations performed. The exit
+ status may be one of the following values.
+
+ If the operation succeeded, smbcacls returns and exit status
+ of 0. If ssssmmmmbbbbccccaaaaccccllllssss couldn't connect to the specified server,
+ or there was an error getting or setting the ACLs, an exit
+ status of 1 is returned. If there was an error parsing any
+ command line arguments, an exit status of 2 is returned.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCAAAACCCCLLLLSSSS((((1111))))
+
+
+
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ ssssmmmmbbbbccccaaaaccccllllssss was written by Andrew Tridgell and Tim Potter.
+
+ The conversion to DocBook for Samba 2.2 was done by Gerald
+ Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbclient.1 b/packaging/Caldera/OpenServer/man/cat.1/smbclient.1
new file mode 100755
index 00000000000..b985a9f19f4
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbclient.1
@@ -0,0 +1,1056 @@
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbclient - ftp-like client to access SMB/CIFS resources on
+ servers
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbcccclllliiiieeeennnntttt sssseeeerrrrvvvviiiicccceeeennnnaaaammmmeeee [ ppppaaaasssssssswwwwoooorrrrdddd ] [ ----bbbb <<<<bbbbuuuuffffffffeeeerrrr ssssiiiizzzzeeee>>>> ] [
+ ----dddd ddddeeeebbbbuuuugggglllleeeevvvveeeellll ] [ ----DDDD DDDDiiiirrrreeeeccccttttoooorrrryyyy ] [ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee ] [ ----WWWW
+ wwwwoooorrrrkkkkggggrrrroooouuuupppp ] [ ----MMMM <<<<nnnneeeettttbbbbiiiioooossss nnnnaaaammmmeeee>>>> ] [ ----mmmm mmmmaaaaxxxxpppprrrroooottttooooccccoooollll ] [ ----AAAA
+ aaaauuuutttthhhhffffiiiilllleeee ] [ ----NNNN ] [ ----llll llllooooggggffffiiiilllleeee ] [ ----LLLL <<<<nnnneeeettttbbbbiiiioooossss nnnnaaaammmmeeee>>>> ] [
+ ----IIII ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnnIIIIPPPP ] [ ----EEEE <<<<tttteeeerrrrmmmmiiiinnnnaaaallll ccccooooddddeeee>>>> ] [ ----cccc <<<<ccccoooommmmmmmmaaaannnndddd
+ ssssttttrrrriiiinnnngggg>>>> ] [ ----iiii ssssccccooooppppeeee ] [ ----OOOO <<<<ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss>>>> ] [ ----pppp ppppoooorrrrtttt
+ ] [ ----RRRR <<<<nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr>>>> ] [ ----ssss <<<<ssssmmmmbbbb ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ] [
+ ----TTTT<<<<cccc||||xxxx>>>>IIIIXXXXFFFFqqqqggggbbbbNNNNaaaannnn ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt is a client that can 'talk' to an SMB/CIFS server.
+ It offers an interface similar to that of the ftp program
+ (see ffffttttpppp((((1111))))). Operations include things like getting files
+ from the server to the local machine, putting files from the
+ local machine to the server, retrieving directory
+ information from the server and so on.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ sssseeeerrrrvvvviiiicccceeeennnnaaaammmmeeee
+ servicename is the name of the service you want to use
+ on the server. A service name takes the form
+ //_s_e_r_v_e_r/_s_e_r_v_i_c_e where _s_e_r_v_e_r is the NetBIOS name of
+ the SMB/CIFS server offering the desired service and
+ _s_e_r_v_i_c_e is the name of the service offered. Thus to
+ connect to the service "printer" on the SMB/CIFS server
+ "smbserver", you would use the servicename
+ //_s_m_b_s_e_r_v_e_r/_p_r_i_n_t_e_r
+
+ Note that the server name required is NOT necessarily
+ the IP (DNS) host name of the server ! The name
+ required is a NetBIOS server name, which may or may not
+ be the same as the IP hostname of the machine running
+ the server.
+
+ The server name is looked up according to either the -_R
+ parameter to ssssmmmmbbbbcccclllliiiieeeennnntttt or using the name resolve order
+ parameter in the _s_m_b._c_o_n_f file, allowing an
+ administrator to change the order and methods by which
+ server names are looked up.
+
+ ppppaaaasssssssswwwwoooorrrrdddd
+ The password required to access the specified service
+ on the specified server. If this parameter is supplied,
+ the -_N option (suppress password prompt) is assumed.
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ There is no default password. If no password is
+ supplied on the command line (either by using this
+ parameter or adding a password to the -_U option (see
+ below)) and the -_N option is not specified, the client
+ will prompt for a password, even if the desired service
+ does not require one. (If no password is required,
+ simply press ENTER to provide a null password.)
+
+ Note: Some servers (including OS/2 and Windows for
+ Workgroups) insist on an uppercase password. Lowercase
+ or mixed case passwords may be rejected by these
+ servers.
+
+ Be cautious about including passwords in scripts.
+
+ ----ssss ssssmmmmbbbb....ccccoooonnnnffff
+ Specifies the location of the all important _s_m_b._c_o_n_f
+ file.
+
+ ----OOOO ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss
+ TCP socket options to set on the client socket. See the
+ socket options parameter in the _s_m_b._c_o_n_f (_5) manpage
+ for the list of valid options.
+
+ ----RRRR <<<<nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr>>>>
+ This option is used by the programs in the Samba suite
+ to determine what naming services and in what order to
+ resolve host names to IP addresses. The option takes a
+ space-separated string of different name resolution
+ options.
+
+ The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :
+
+ o+ lmhosts : Lookup an IP address in the Samba lmhosts
+ file. If the line in lmhosts has no name type
+ attached to the NetBIOS name (see the lmhosts(5) for
+ details) then any name type matches for lookup.
+
+ o+ host : Do a standard host name to IP address
+ resolution, using the system /_e_t_c/_h_o_s_t_s , NIS, or DNS
+ lookups. This method of name resolution is operating
+ system dependent, for instance on IRIX or Solaris
+ this may be controlled by the /_e_t_c/_n_s_s_w_i_t_c_h._c_o_n_f
+ file). Note that this method is only used if the
+ NetBIOS name type being queried is the 0x20 (server)
+ name type, otherwise it is ignored.
+
+ o+ wins : Query a name with the IP address listed in the
+ _w_i_n_s _s_e_r_v_e_r parameter. If no WINS server has been
+ specified this method will be ignored.
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ o+ bcast : Do a broadcast on each of the known local
+ interfaces listed in the _i_n_t_e_r_f_a_c_e_s parameter. This
+ is the least reliable of the name resolution methods
+ as it depends on the target host being on a locally
+ connected subnet.
+
+ If this parameter is not set then the name resolve order
+ defined in the _s_m_b._c_o_n_f file parameter (name resolve order)
+ will be used.
+
+ The default order is lmhosts, host, wins, bcast and without
+ this parameter or any entry in the _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r
+ parameter of the _s_m_b._c_o_n_f file the name resolution methods
+ will be attempted in this order.
+
+ ----MMMM NNNNeeeettttBBBBIIIIOOOOSSSS nnnnaaaammmmeeee
+ This options allows you to send messages, using the
+ "WinPopup" protocol, to another computer. Once a
+ connection is established you then type your message,
+ pressing ^D (control-D) to end.
+
+ If the receiving computer is running WinPopup the user
+ will receive the message and probably a beep. If they
+ are not running WinPopup the message will be lost, and
+ no error message will occur.
+
+ The message is also automatically truncated if the
+ message is over 1600 bytes, as this is the limit of the
+ protocol.
+
+ One useful trick is to cat the message through
+ ssssmmmmbbbbcccclllliiiieeeennnntttt. For example: ccccaaaatttt mmmmyyyymmmmeeeessssssssaaaaggggeeee....ttttxxxxtttt |||| ssssmmmmbbbbcccclllliiiieeeennnntttt
+ ----MMMM FFFFRRRREEEEDDDD will send the message in the file
+ _m_y_m_e_s_s_a_g_e._t_x_t to the machine FRED.
+
+ You may also find the -_U and -_I options useful, as they
+ allow you to control the FROM and TO parts of the
+ message.
+
+ See the message command parameter in the _s_m_b._c_o_n_f(_5)
+ for a description of how to handle incoming WinPopup
+ messages in Samba.
+
+ NNNNooootttteeee: Copy WinPopup into the startup group on your WfWg
+ PCs if you want them to always be able to receive
+ messages.
+
+ ----iiii ssssccccooooppppeeee
+ This specifies a NetBIOS scope that smbclient will use
+ to communicate with when generating NetBIOS names. For
+ details on the use of NetBIOS scopes, see _r_f_c_1_0_0_1._t_x_t
+ and _r_f_c_1_0_0_2._t_x_t. NetBIOS scopes are vvvveeeerrrryyyy rarely used,
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ only set this parameter if you are the system
+ administrator in charge of all the NetBIOS systems you
+ communicate with.
+
+ ----NNNN If specified, this parameter suppresses the normal
+ password prompt from the client to the user. This is
+ useful when accessing a service that does not require a
+ password.
+
+ Unless a password is specified on the command line or
+ this parameter is specified, the client will request a
+ password.
+
+ ----nnnn NNNNeeeettttBBBBIIIIOOOOSSSS nnnnaaaammmmeeee
+ By default, the client will use the local machine's
+ hostname (in uppercase) as its NetBIOS name. This
+ parameter allows you to override the host name and use
+ whatever NetBIOS name you wish.
+
+ ----dddd ddddeeeebbbbuuuugggglllleeeevvvveeeellll
+ _d_e_b_u_g_l_e_v_e_l is an integer from 0 to 10, or the letter
+ 'A'.
+
+ The default value if this parameter is not specified is
+ zero.
+
+ The higher this value, the more detail will be logged
+ to the log files about the activities of the client. At
+ level 0, only critical errors and serious warnings will
+ be logged. Level 1 is a reasonable level for day to day
+ running - it generates a small amount of information
+ about operations carried out.
+
+ Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a
+ problem. Levels above 3 are designed for use only by
+ developers and generate HUGE amounts of log data, most
+ of which is extremely cryptic. If _d_e_b_u_g_l_e_v_e_l is set to
+ the letter 'A', then aaaallllllll debug messages will be
+ printed. This setting is for developers only (and
+ people who rrrreeeeaaaallllllllyyyy want to know how the code works
+ internally).
+
+ Note that specifying this parameter here will override
+ the log level parameter in the _s_m_b._c_o_n_f (_5) file.
+
+ ----pppp ppppoooorrrrtttt
+ This number is the TCP port number that will be used
+ when making connections to the server. The standard
+ (well-known) TCP port number for an SMB/CIFS server is
+ 139, which is the default.
+
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ ----llll llllooooggggffffiiiilllleeeennnnaaaammmmeeee
+ If specified, _l_o_g_f_i_l_e_n_a_m_e specifies a base filename
+ into which operational data from the running client
+ will be logged.
+
+ The default base name is specified at compile time.
+
+ The base name is used to generate actual log file
+ names. For example, if the name specified was "log",
+ the debug file would be _l_o_g._c_l_i_e_n_t.
+
+ The log file generated is never removed by the client.
+
+ ----hhhh Print the usage message for the client.
+
+ ----IIII IIIIPPPP----aaaaddddddddrrrreeeessssssss
+ _I_P _a_d_d_r_e_s_s is the address of the server to connect to.
+ It should be specified in standard "a.b.c.d" notation.
+
+ Normally the client would attempt to locate a named
+ SMB/CIFS server by looking it up via the NetBIOS name
+ resolution mechanism described above in the _n_a_m_e
+ _r_e_s_o_l_v_e _o_r_d_e_r parameter above. Using this parameter
+ will force the client to assume that the server is on
+ the machine with the specified IP address and the
+ NetBIOS name component of the resource being connected
+ to will be ignored.
+
+ There is no default for this parameter. If not
+ supplied, it will be determined automatically by the
+ client as described above.
+
+ ----EEEE This parameter causes the client to write messages to
+ the standard error stream (stderr) rather than to the
+ standard output stream.
+
+ By default, the client writes messages to standard
+ output - typically the user's tty.
+
+ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee[[[[%%%%ppppaaaassssssss]]]]
+ Sets the SMB username or username and password. If
+ %pass is not specified, The user will be prompted. The
+ client will first check the UUUUSSSSEEEERRRR environment variable,
+ then the LLLLOOOOGGGGNNNNAAAAMMMMEEEE variable and if either exists, the
+ string is uppercased. Anything in these variables
+ following a '%' sign will be treated as the password.
+ If these environment variables are not found, the
+ username GUEST is used.
+
+ If the password is not included in these environment
+ variables (using the %pass syntax), ssssmmmmbbbbcccclllliiiieeeennnntttt will look
+ for a PPPPAAAASSSSSSSSWWWWDDDD environment variable from which to read
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ the password.
+
+ A third option is to use a credentials file which
+ contains the plaintext of the domain name, username and
+ password. This option is mainly provided for scripts
+ where the admin doesn't wish to pass the credentials on
+ the command line or via environment variables. If this
+ method is used, make certain that the permissions on
+ the file restrict access from unwanted users. See the
+ -_A for more details.
+
+ Be cautious about including passwords in scripts or in
+ the PPPPAAAASSSSSSSSWWWWDDDD environment variable. Also, on many systems
+ the command line of a running process may be seen via
+ the ppppssss command to be safe always allow ssssmmmmbbbbcccclllliiiieeeennnntttt to
+ prompt for a password and type it in directly.
+
+ ----AAAA ffffiiiilllleeeennnnaaaammmmeeee
+ This option allows you to specify a file from which to
+ read the username, domain name, and password used in
+ the connection. The format of the file is
+
+
+ username = <value>
+ password = <value>
+ domain = <value>
+
+
+
+ If the domain parameter is missing the current
+ workgroup name is used instead. Make certain that the
+ permissions on the file restrict access from unwanted
+ users.
+
+ ----LLLL This option allows you to look at what services are
+ available on a server. You use it as ssssmmmmbbbbcccclllliiiieeeennnntttt ----LLLL hhhhoooosssstttt
+ and a list should appear. The -_I option may be useful
+ if your NetBIOS names don't match your TCP/IP DNS host
+ names or if you are trying to reach a host on another
+ network.
+
+ ----tttt tttteeeerrrrmmmmiiiinnnnaaaallll ccccooooddddeeee
+ This option tells ssssmmmmbbbbcccclllliiiieeeennnntttt how to interpret filenames
+ coming from the remote server. Usually Asian language
+ multibyte UNIX implementations use different character
+ sets than SMB/CIFS servers (EEEEUUUUCCCC instead of SSSSJJJJIIIISSSS for
+ example). Setting this parameter will let ssssmmmmbbbbcccclllliiiieeeennnntttt
+ convert between the UNIX filenames and the SMB
+ filenames correctly. This option has not been seriously
+ tested and may have some problems.
+
+ The terminal codes include CWsjis, CWeuc, CWjis7,
+
+
+
+ Page 6 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ CWjis8, CWjunet, CWhex, CWcap. This is not a complete
+ list, check the Samba source code for the complete
+ list.
+
+ ----bbbb bbbbuuuuffffffffeeeerrrrssssiiiizzzzeeee
+ This option changes the transmit/send buffer size when
+ getting or putting a file from/to the server. The
+ default is 65520 bytes. Setting this value smaller (to
+ 1200 bytes) has been observed to speed up file
+ transfers to and from a Win9x server.
+
+ ----WWWW WWWWOOOORRRRKKKKGGGGRRRROOOOUUUUPPPP
+ Override the default workgroup (domain) specified in
+ the workgroup parameter of the _s_m_b._c_o_n_f file for this
+ connection. This may be needed to connect to some
+ servers.
+
+ ----TTTT ttttaaaarrrr ooooppppttttiiiioooonnnnssss
+ smbclient may be used to create ttttaaaarrrr((((1111)))) compatible
+ backups of all the files on an SMB/CIFS share. The
+ secondary tar flags that can be given to this option
+ are :
+
+ o+ _c - Create a tar file on UNIX. Must be followed by
+ the name of a tar file, tape device or "-" for
+ standard output. If using standard output you must
+ turn the log level to its lowest value -d0 to avoid
+ corrupting your tar file. This flag is mutually
+ exclusive with the _x flag.
+
+ o+ _x - Extract (restore) a local tar file back to a
+ share. Unless the -D option is given, the tar files
+ will be restored from the top level of the share.
+ Must be followed by the name of the tar file, device
+ or "-" for standard input. Mutually exclusive with
+ the _c flag. Restored files have their creation times
+ (mtime) set to the date saved in the tar file.
+ Directories currently do not get their creation dates
+ restored properly.
+
+ o+ _I - Include files and directories. Is the default
+ behavior when filenames are specified above. Causes
+ tar files to be included in an extract or create (and
+ therefore everything else to be excluded). See
+ example below. Filename globbing works in one of two
+ ways. See r below.
+
+ o+ _X - Exclude files and directories. Causes tar files
+ to be excluded from an extract or create. See example
+ below. Filename globbing works in one of two ways
+ now. See _r below.
+
+
+
+
+ Page 7 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ o+ _b - Blocksize. Must be followed by a valid (greater
+ than zero) blocksize. Causes tar file to be written
+ out in blocksize*TBLOCK (usually 512 byte) blocks.
+
+ o+ _g - Incremental. Only back up files that have the
+ archive bit set. Useful only with the _c flag.
+
+ o+ _q - Quiet. Keeps tar from printing diagnostics as it
+ works. This is the same as tarmode quiet.
+
+ o+ _r - Regular expression include or exclude. Uses
+ regular expression matching for excluding or
+ excluding files if compiled with HAVE_REGEX_H.
+ However this mode can be very slow. If not compiled
+ with HAVE_REGEX_H, does a limited wildcard match on
+ '*' and '?'.
+
+ o+ _N - Newer than. Must be followed by the name of a
+ file whose date is compared against files found on
+ the share during a create. Only files newer than the
+ file specified are backed up to the tar file. Useful
+ only with the _c flag.
+
+ o+ _a - Set archive bit. Causes the archive bit to be
+ reset when a file is backed up. Useful with the _g and
+ _c flags.
+
+ TTTTaaaarrrr LLLLoooonnnngggg FFFFiiiilllleeee NNNNaaaammmmeeeessss
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt's tar option now supports long file names both on
+ backup and restore. However, the full path name of the file
+ must be less than 1024 bytes. Also, when a tar archive is
+ created, ssssmmmmbbbbcccclllliiiieeeennnntttt's tar option places all files in the
+ archive with relative names, not absolute names.
+
+ TTTTaaaarrrr FFFFiiiilllleeeennnnaaaammmmeeeessss
+
+ All file names can be given as DOS path names (with '\' as
+ the component separator) or as UNIX path names (with '/' as
+ the component separator).
+
+ EEEExxxxaaaammmmpppplllleeeessss
+
+ Restore from tar file _b_a_c_k_u_p._t_a_r into myshare on mypc (no
+ password on share).
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt ////////mmmmyyyyppppcccc////yyyysssshhhhaaaarrrreeee """""""" ----NNNN ----TTTTxxxx bbbbaaaacccckkkkuuuupppp....ttttaaaarrrr
+
+ Restore everything except _u_s_e_r_s/_d_o_c_s
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt ////////mmmmyyyyppppcccc////mmmmyyyysssshhhhaaaarrrreeee """""""" ----NNNN ----TTTTXXXXxxxx bbbbaaaacccckkkkuuuupppp....ttttaaaarrrr uuuusssseeeerrrrssss////ddddooooccccssss
+
+
+
+
+ Page 8 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ Create a tar file of the files beneath _u_s_e_r_s/_d_o_c_s.
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt ////////mmmmyyyyppppcccc////mmmmyyyysssshhhhaaaarrrreeee """""""" ----NNNN ----TTTTcccc bbbbaaaacccckkkkuuuupppp....ttttaaaarrrr uuuusssseeeerrrrssss////ddddooooccccssss
+
+ Create the same tar file as above, but now use a DOS path
+ name.
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt ////////mmmmyyyyppppcccc////mmmmyyyysssshhhhaaaarrrreeee """""""" ----NNNN ----ttttcccc bbbbaaaacccckkkkuuuupppp....ttttaaaarrrr uuuusssseeeerrrrssss\\\\eeeeddddooooccccssss
+
+ Create a tar file of all the files and directories in the
+ share.
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt ////////mmmmyyyyppppcccc////mmmmyyyysssshhhhaaaarrrreeee """""""" ----NNNN ----TTTTcccc bbbbaaaacccckkkkuuuupppp....ttttaaaarrrr ****
+
+ ----DDDD iiiinnnniiiittttiiiiaaaallll ddddiiiirrrreeeeccccttttoooorrrryyyy
+ Change to initial directory before starting. Probably
+ only of any use with the tar -T option.
+
+ ----cccc ccccoooommmmmmmmaaaannnndddd ssssttttrrrriiiinnnngggg
+ command string is a semicolon-separated list of
+ commands to be executed instead of prompting from
+ stdin. -_N is implied by -_c.
+
+ This is particularly useful in scripts and for printing
+ stdin to the server, e.g. ----cccc ''''pppprrrriiiinnnntttt ----''''.
+
+ OOOOPPPPEEEERRRRAAAATTTTIIIIOOOONNNNSSSS
+ Once the client is running, the user is presented with a
+ prompt :
+
+ smb:\>
+
+ The backslash ("\") indicates the current working directory
+ on the server, and will change if the current working
+ directory is changed.
+
+ The prompt indicates that the client is ready and waiting to
+ carry out a user command. Each command is a single word,
+ optionally followed by parameters specific to that command.
+ Command and parameters are space-delimited unless these
+ notes specifically state otherwise. All commands are case-
+ insensitive. Parameters to commands may or may not be case
+ sensitive, depending on the command.
+
+ You can specify file names which have spaces in them by
+ quoting the name with double quotes, for example "a long
+ file name".
+
+ Parameters shown in square brackets (e.g., "[parameter]")
+ are optional. If not given, the command will use suitable
+ defaults. Parameters shown in angle brackets (e.g.,
+ "<parameter>") are required.
+
+
+
+ Page 9 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ Note that all commands operating on the server are actually
+ performed by issuing a request to the server. Thus the
+ behavior may vary from server to server, depending on how
+ the server was implemented.
+
+ The commands available are given here in alphabetical order.
+
+ ???? [[[[ccccoooommmmmmmmaaaannnndddd]]]]
+ If _c_o_m_m_a_n_d is specified, the ? command will display a
+ brief informative message about the specified command.
+ If no command is specified, a list of available
+ commands will be displayed.
+
+ !!!! [[[[sssshhhheeeellllllll ccccoooommmmmmmmaaaannnndddd]]]]
+ If _s_h_e_l_l _c_o_m_m_a_n_d is specified, the ! command will
+ execute a shell locally and run the specified shell
+ command. If no command is specified, a local shell will
+ be run.
+
+ aaaallllttttnnnnaaaammmmeeee ffffiiiilllleeee
+ The client will request that the server return the
+ "alternate" name (the 8.3 name) for a file or
+ directory.
+
+ ccccaaaannnncccceeeellll jjjjoooobbbbiiiidddd0000 [[[[jjjjoooobbbbiiiidddd1111]]]] ............ [[[[jjjjoooobbbbiiiiddddNNNN]]]]
+ The client will request that the server cancel the
+ printjobs identified by the given numeric print job
+ ids.
+
+ cccchhhhmmmmoooodddd ffffiiiilllleeee mmmmooooddddeeee iiiinnnn ooooccccttttaaaallll
+ This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not.
+ The client requests that the server change the UNIX
+ permissions to the given octal mode, in standard UNIX
+ format.
+
+ cccchhhhoooowwwwnnnn ffffiiiilllleeee uuuuiiiidddd ggggiiiidddd
+ This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not.
+ The client requests that the server change the UNIX
+ user and group ownership to the given decimal values.
+ Note there is currently no way to remotely look up the
+ UNIX uid and gid values for a given name. This may be
+ addressed in future versions of the CIFS UNIX
+ extensions.
+
+ ccccdddd [[[[ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee]]]]
+ If "directory name" is specified, the current working
+ directory on the server will be changed to the
+ directory specified. This operation will fail if for
+ any reason the specified directory is inaccessible.
+
+
+
+
+ Page 10 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ If no directory name is specified, the current working
+ directory on the server will be reported.
+
+ ddddeeeellll <<<<mmmmaaaasssskkkk>>>>
+ The client will request that the server attempt to
+ delete all files matching _m_a_s_k from the current working
+ directory on the server.
+
+ ddddiiiirrrr <<<<mmmmaaaasssskkkk>>>>
+ A list of the files matching _m_a_s_k in the current
+ working directory on the server will be retrieved from
+ the server and displayed.
+
+ eeeexxxxiiiitttt Terminate the connection with the server and exit from
+ the program.
+
+ ggggeeeetttt <<<<rrrreeeemmmmooootttteeee ffffiiiilllleeee nnnnaaaammmmeeee>>>> [[[[llllooooccccaaaallll ffffiiiilllleeee nnnnaaaammmmeeee]]]]
+ Copy the file called _r_e_m_o_t_e _f_i_l_e _n_a_m_e from the server
+ to the machine running the client. If specified, name
+ the local copy _l_o_c_a_l _f_i_l_e _n_a_m_e. Note that all transfers
+ in ssssmmmmbbbbcccclllliiiieeeennnntttt are binary. See also the lowercase
+ command.
+
+ hhhheeeellllpppp [[[[ccccoooommmmmmmmaaaannnndddd]]]]
+ See the ? command above.
+
+ llllccccdddd [[[[ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee]]]]
+ If _d_i_r_e_c_t_o_r_y _n_a_m_e is specified, the current working
+ directory on the local machine will be changed to the
+ directory specified. This operation will fail if for
+ any reason the specified directory is inaccessible.
+
+ If no directory name is specified, the name of the
+ current working directory on the local machine will be
+ reported.
+
+ lllliiiinnnnkkkk ssssoooouuuurrrrcccceeee ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn
+ This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not.
+ The client requests that the server create a hard link
+ between the source and destination files. The source
+ file must not exist.
+
+ lllloooowwwweeeerrrrccccaaaasssseeee
+ Toggle lowercasing of filenames for the get and mget
+ commands.
+
+ When lowercasing is toggled ON, local filenames are
+ converted to lowercase when using the get and mget
+ commands. This is often useful when copying (say) MSDOS
+ files from a server, because lowercase filenames are
+ the norm on UNIX systems.
+
+
+
+ Page 11 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ llllssss <<<<mmmmaaaasssskkkk>>>>
+ See the dir command above.
+
+ mmmmaaaasssskkkk <<<<mmmmaaaasssskkkk>>>>
+ This command allows the user to set up a mask which
+ will be used during recursive operation of the mget and
+ mput commands.
+
+ The masks specified to the mget and mput commands act
+ as filters for directories rather than files when
+ recursion is toggled ON.
+
+ The mask specified with the mask command is necessary
+ to filter files within those directories. For example,
+ if the mask specified in an mget command is "source*"
+ and the mask specified with the mask command is "*.c"
+ and recursion is toggled ON, the mget command will
+ retrieve all files matching "*.c" in all directories
+ below and including all directories matching "source*"
+ in the current working directory.
+
+ Note that the value for mask defaults to blank
+ (equivalent to "*") and remains so until the mask
+ command is used to change it. It retains the most
+ recently specified value indefinitely. To avoid
+ unexpected results it would be wise to change the value
+ of mask back to "*" after using the mget or mput
+ commands.
+
+ mmmmdddd <<<<ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee>>>>
+ See the mkdir command.
+
+ mmmmggggeeeetttt <<<<mmmmaaaasssskkkk>>>>
+ Copy all files matching _m_a_s_k from the server to the
+ machine running the client.
+
+ Note that _m_a_s_k is interpreted differently during
+ recursive operation and non-recursive operation - refer
+ to the recurse and mask commands for more information.
+ Note that all transfers in ssssmmmmbbbbcccclllliiiieeeennnntttt are binary. See
+ also the lowercase command.
+
+ mmmmkkkkddddiiiirrrr <<<<ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee>>>>
+ Create a new directory on the server (user access
+ privileges permitting) with the specified name.
+
+ mmmmppppuuuutttt <<<<mmmmaaaasssskkkk>>>>
+ Copy all files matching _m_a_s_k in the current working
+ directory on the local machine to the current working
+ directory on the server.
+
+ Note that _m_a_s_k is interpreted differently during
+
+
+
+ Page 12 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ recursive operation and non-recursive operation - refer
+ to the recurse and mask commands for more information.
+ Note that all transfers in ssssmmmmbbbbcccclllliiiieeeennnntttt are binary.
+
+ pppprrrriiiinnnntttt <<<<ffffiiiilllleeee nnnnaaaammmmeeee>>>>
+ Print the specified file from the local machine through
+ a printable service on the server.
+
+ See also the printmode command.
+
+ pppprrrriiiinnnnttttmmmmooooddddeeee <<<<ggggrrrraaaapppphhhhiiiiccccssss oooorrrr tttteeeexxxxtttt>>>>
+ Set the print mode to suit either binary data (such as
+ graphical information) or text. Subsequent print
+ commands will use the currently set print mode.
+
+ pppprrrroooommmmpppptttt
+ Toggle prompting for filenames during operation of the
+ mget and mput commands.
+
+ When toggled ON, the user will be prompted to confirm
+ the transfer of each file during these commands. When
+ toggled OFF, all specified files will be transferred
+ without prompting.
+
+ ppppuuuutttt <<<<llllooooccccaaaallll ffffiiiilllleeee nnnnaaaammmmeeee>>>> [[[[rrrreeeemmmmooootttteeee ffffiiiilllleeee nnnnaaaammmmeeee]]]]
+ Copy the file called _l_o_c_a_l _f_i_l_e _n_a_m_e from the machine
+ running the client to the server. If specified, name
+ the remote copy _r_e_m_o_t_e _f_i_l_e _n_a_m_e. Note that all
+ transfers in ssssmmmmbbbbcccclllliiiieeeennnntttt are binary. See also the
+ lowercase command.
+
+ qqqquuuueeeeuuuueeee
+ Displays the print queue, showing the job id, name,
+ size and current status.
+
+ qqqquuuuiiiitttt See the exit command.
+
+ rrrrdddd <<<<ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee>>>>
+ See the rmdir command.
+
+ rrrreeeeccccuuuurrrrsssseeee
+ Toggle directory recursion for the commands mget and
+ mput.
+
+ When toggled ON, these commands will process all
+ directories in the source directory (i.e., the
+ directory they are copying from ) and will recurse into
+ any that match the mask specified to the command. Only
+ files that match the mask specified using the mask
+ command will be retrieved. See also the mask command.
+
+ When recursion is toggled OFF, only files from the
+
+
+
+ Page 13 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ current working directory on the source machine that
+ match the mask specified to the mget or mput commands
+ will be copied, and any mask specified using the mask
+ command will be ignored.
+
+ rrrrmmmm <<<<mmmmaaaasssskkkk>>>>
+ Remove all files matching _m_a_s_k from the current working
+ directory on the server.
+
+ rrrrmmmmddddiiiirrrr <<<<ddddiiiirrrreeeeccccttttoooorrrryyyy nnnnaaaammmmeeee>>>>
+ Remove the specified directory (user access privileges
+ permitting) from the server.
+
+ sssseeeettttmmmmooooddddeeee <<<<ffffiiiilllleeeennnnaaaammmmeeee>>>> <<<<ppppeeeerrrrmmmm====[[[[++++||||----]]]]rrrrsssshhhhaaaa>>>>
+ A version of the DOS attrib command to set file
+ permissions. For example:
+
+ sssseeeettttmmmmooooddddeeee mmmmyyyyffffiiiilllleeee ++++rrrr
+
+ would make myfile read only.
+
+ ssssyyyymmmmlllliiiinnnnkkkk ssssoooouuuurrrrcccceeee ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn
+ This command depends on the server supporting the CIFS
+ UNIX extensions and will fail if the server does not.
+ The client requests that the server create a symbolic
+ hard link between the source and destination files. The
+ source file must not exist. Note that the server will
+ not create a link to any path that lies outside the
+ currently connected share. This is enforced by the
+ Samba server.
+
+ ttttaaaarrrr <<<<cccc||||xxxx>>>>[[[[IIIIXXXXbbbbggggNNNNaaaa]]]]
+ Performs a tar operation - see the -_T command line
+ option above. Behavior may be affected by the tarmode
+ command (see below). Using g (incremental) and N
+ (newer) will affect tarmode settings. Note that using
+ the "-" option with tar x may not work - use the
+ command line option instead.
+
+ bbbblllloooocccckkkkssssiiiizzzzeeee <<<<bbbblllloooocccckkkkssssiiiizzzzeeee>>>>
+ Blocksize. Must be followed by a valid (greater than
+ zero) blocksize. Causes tar file to be written out in
+ _b_l_o_c_k_s_i_z_e*TBLOCK (usually 512 byte) blocks.
+
+ ttttaaaarrrrmmmmooooddddeeee <<<<ffffuuuullllllll||||iiiinnnncccc||||rrrreeeesssseeeetttt||||nnnnoooorrrreeeesssseeeetttt>>>>
+ Changes tar's behavior with regard to archive bits. In
+ full mode, tar will back up everything regardless of
+ the archive bit setting (this is the default mode). In
+ incremental mode, tar will only back up files with the
+ archive bit set. In reset mode, tar will reset the
+ archive bit on all files it backs up (implies
+ read/write share).
+
+
+
+ Page 14 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ NNNNOOOOTTTTEEEESSSS
+ Some servers are fussy about the case of supplied usernames,
+ passwords, share names (AKA service names) and machine
+ names. If you fail to connect try giving all parameters in
+ uppercase.
+
+ It is often necessary to use the -n option when connecting
+ to some types of servers. For example OS/2 LanManager
+ insists on a valid NetBIOS name being used, so you need to
+ supply a valid name that would be known to the server.
+
+ smbclient supports long file names where the server supports
+ the LANMAN2 protocol or above.
+
+ EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT VVVVAAAARRRRIIIIAAAABBBBLLLLEEEESSSS
+ The variable UUUUSSSSEEEERRRR may contain the username of the person
+ using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords.
+
+ The variable PPPPAAAASSSSSSSSWWWWDDDD may contain the password of the person
+ using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords.
+
+ The variable LLLLIIIIBBBBSSSSMMMMBBBB____PPPPRRRROOOOGGGG may contain the path, executed with
+ system(), which the client should connect to instead of
+ connecting to a server. This functionality is primarily
+ intended as a development aid, and works best when using a
+ LMHOSTS file
+
+ IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ The location of the client program is a matter for
+ individual system administrators. The following are thus
+ suggestions only.
+
+ It is recommended that the smbclient software be installed
+ in the /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_b_i_n/ or /_u_s_r/_s_a_m_b_a/_b_i_n/ directory,
+ this directory readable by all, writeable only by root. The
+ client program itself should be executable by all. The
+ client should NNNNOOOOTTTT be setuid or setgid!
+
+ The client log files should be put in a directory readable
+ and writeable only by the user.
+
+ To test the client, you will need to know the name of a
+ running SMB/CIFS server. It is possible to run ssssmmmmbbbbdddd((((8888)))) as an
+ ordinary user - running that server as a daemon on a user-
+ accessible port (typically any port number over 1024) would
+ provide a suitable test server.
+
+ DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
+
+
+
+ PPPPaaaaggggeeee 11115555 ((((pppprrrriiiinnnntttteeeedddd 1111////7777////111100003333))))
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCLLLLIIIIEEEENNNNTTTT((((1111))))
+
+
+
+ Most diagnostics issued by the client are logged in a
+ specified log file. The log file name is specified at
+ compile time, but may be overridden on the command line.
+
+ The number and nature of diagnostics available depends on
+ the debug level used by the client. If you have problems,
+ set the debug level to 3 and peruse the log files.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 16 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbcontrol.1 b/packaging/Caldera/OpenServer/man/cat.1/smbcontrol.1
new file mode 100755
index 00000000000..064dbe2a1dc
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbcontrol.1
@@ -0,0 +1,198 @@
+
+
+
+ SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbcontrol - send messages to smbd, nmbd or winbindd
+ processes
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbccccoooonnnnttttrrrroooollll [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----ssss <<<<ssssmmmmbbbb ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ]
+ ----iiii
+
+ ssssmmmmbbbbccccoooonnnnttttrrrroooollll [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----ssss <<<<ssssmmmmbbbb ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ]
+ ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn mmmmeeeessssssssaaaaggggeeee----ttttyyyyppppeeee [ ppppaaaarrrraaaammmmeeeetttteeeerrrr ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ ssssmmmmbbbbccccoooonnnnttttrrrroooollll is a very small program, which sends messages to
+ an smbd(8) an nmbd(8) or a winbindd(8) daemon running on the
+ system.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----dddd <<<<ddddeeeebbbbuuuugggglllleeeevvvveeeellll>>>>
+ debuglevel is an integer from 0 to 10.
+
+ ----ssss <<<<ssssmmmmbbbb....ccccoooonnnnffff>>>>
+ This parameter specifies the pathname to the Samba
+ configuration file, smb.conf(5) This file controls all
+ aspects of the Samba setup on the machine.
+
+ ----iiii Run interactively. Individual commands of the form
+ destination message-type parameters can be entered on
+ STDIN. An empty command line or a "q" will quit the
+ program.
+
+ ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn
+ One of _n_m_b_d _s_m_b_d or a process ID.
+
+ The _s_m_b_d destination causes the message to "broadcast"
+ to all smbd daemons.
+
+ The _n_m_b_d destination causes the message to be sent to
+ the nmbd daemon specified in the _n_m_b_d._p_i_d file.
+
+ If a single process ID is given, the message is sent to
+ only that process.
+
+ mmmmeeeessssssssaaaaggggeeee----ttttyyyyppppeeee
+ One of: close-share, debug, force-election, ping ,
+ profile, debuglevel, profilelevel, or printer-notify.
+
+ The close-share message-type sends a message to smbd
+ which will then close the client connections to the
+ named share. Note that this doesn't affect client
+ connections to any other shares. This message-type
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111))))
+
+
+
+ takes an argument of the share name for which client
+ connections will be closed, or the "*" character which
+ will close all currently open shares. This may be
+ useful if you made changes to the access controls on
+ the share. This message can only be sent to smbd.
+
+ The debug message-type allows the debug level to be set
+ to the value specified by the parameter. This can be
+ sent to any of the destinations.
+
+ The force-election message-type can only be sent to the
+ nmbd destination. This message causes the nnnnmmmmbbbbdddd daemon
+ to force a new browse master election.
+
+ The ping message-type sends the number of "ping"
+ messages specified by the parameter and waits for the
+ same number of reply "pong" messages. This can be sent
+ to any of the destinations.
+
+ The profile message-type sends a message to an smbd to
+ change the profile settings based on the parameter. The
+ parameter can be "on" to turn on profile stats
+ collection, "off" to turn off profile stats collection,
+ "count" to enable only collection of count stats (time
+ stats are disabled), and "flush" to zero the current
+ profile stats. This can be sent to any smbd or nmbd
+ destinations.
+
+ The debuglevel message-type sends a "request debug
+ level" message. The current debug level setting is
+ returned by a "debuglevel" message. This can be sent to
+ any of the destinations.
+
+ The profilelevel message-type sends a "request profile
+ level" message. The current profile level setting is
+ returned by a "profilelevel" message. This can be sent
+ to any smbd or nmbd destinations.
+
+ The printer-notify message-type sends a message to smbd
+ which in turn sends a printer notify message to any
+ Windows NT clients connected to a printer. This
+ message-type takes an argument of the printer name to
+ send notify messages to. This message can only be sent
+ to smbd.
+
+ ppppaaaarrrraaaammmmeeeetttteeeerrrrssss
+ any parameters required for the message-type
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+
+
+
+ PPPPaaaaggggeeee 2222 ((((pppprrrriiiinnnntttteeeedddd 1111////7777////111100003333))))
+
+
+
+
+
+
+ SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBCCCCOOOONNNNTTTTRRRROOOOLLLL((((1111))))
+
+
+
+ nnnnmmmmbbbbdddd((((8888)))) and ssssmmmmbbbbdddd((((8888))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbsh.1 b/packaging/Caldera/OpenServer/man/cat.1/smbsh.1
new file mode 100755
index 00000000000..532b442f92b
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbsh.1
@@ -0,0 +1,198 @@
+
+
+
+ SSSSMMMMBBBBSSSSHHHH((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBSSSSHHHH((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbsh - Allows access to Windows NT filesystem using UNIX
+ commands
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbsssshhhh [ ----WWWW wwwwoooorrrrkkkkggggrrrroooouuuupppp ] [ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee ] [ ----PPPP pppprrrreeeeffffiiiixxxx ] [ ----RRRR
+ <<<<nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr>>>> ] [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----llll llllooooggggffffiiiilllleeee ]
+ [ ----LLLL lllliiiibbbbddddiiiirrrr ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ ssssmmmmbbbbsssshhhh allows you to access an NT filesystem using UNIX
+ commands such as llllssss, eeeeggggrrrreeeepppp, and rrrrccccpppp. You must use a shell
+ that is dynamically linked in order for ssssmmmmbbbbsssshhhh to work
+ correctly.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----WWWW WWWWOOOORRRRKKKKGGGGRRRROOOOUUUUPPPP
+ Override the default workgroup specified in the
+ workgroup parameter of the _s_m_b._c_o_n_f file for this
+ session. This may be needed to connect to some servers.
+
+ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee[[[[%%%%ppppaaaassssssss]]]]
+ Sets the SMB username or username and password. If
+ this option is not specified, the user will be prompted
+ for both the username and the password. If %pass is not
+ specified, the user will be prompted for the password.
+
+ ----PPPP pppprrrreeeeffffiiiixxxx
+ This option allows the user to set the directory prefix
+ for SMB access. The default value if this option is not
+ specified is ssssmmmmbbbb.
+
+ ----RRRR <<<<nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr>>>>
+ This option is used to determine what naming services
+ and in what order to resolve host names to IP
+ addresses. The option takes a space-separated string of
+ different name resolution options.
+
+ The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :
+
+ o+ lmhosts : Lookup an IP address in the Samba lmhosts
+ file. If the line in lmhosts has no name type
+ attached to the NetBIOS name (see the lmhosts(5) for
+ details) then any name type matches for lookup.
+
+ o+ host : Do a standard host name to IP address
+ resolution, using the system /_e_t_c/_h_o_s_t_s, NIS, or DNS
+ lookups. This method of name resolution is operating
+ system dependent, for instance on IRIX or Solaris
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBSSSSHHHH((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBSSSSHHHH((((1111))))
+
+
+
+ this may be controlled by the /_e_t_c/_n_s_s_w_i_t_c_h._c_o_n_f
+ file). Note that this method is only used if the
+ NetBIOS name type being queried is the 0x20 (server)
+ name type, otherwise it is ignored.
+
+ o+ wins : Query a name with the IP address listed in the
+ _w_i_n_s _s_e_r_v_e_r parameter. If no WINS server has been
+ specified this method will be ignored.
+
+ o+ bcast : Do a broadcast on each of the known local
+ interfaces listed in the _i_n_t_e_r_f_a_c_e_s parameter. This
+ is the least reliable of the name resolution methods
+ as it depends on the target host being on a locally
+ connected subnet.
+
+ If this parameter is not set then the name resolve order
+ defined in the _s_m_b._c_o_n_f file parameter (name resolve order)
+ will be used.
+
+ The default order is lmhosts, host, wins, bcast. Without
+ this parameter or any entry in the _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r
+ parameter of the _s_m_b._c_o_n_f file, the name resolution methods
+ will be attempted in this order.
+
+ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>>
+ debug level is an integer from 0 to 10.
+
+ The default value if this parameter is not specified is
+ zero.
+
+ The higher this value, the more detail will be logged
+ about the activities of nnnnmmmmbbbbllllooooooookkkkuuuupppp. At level 0, only
+ critical errors and serious warnings will be logged.
+
+ ----llll llllooooggggffffiiiilllleeeennnnaaaammmmeeee
+ If specified causes all debug messages to be written to
+ the file specified by _l_o_g_f_i_l_e_n_a_m_e . If not specified
+ then all messages will be written to_s_t_d_e_r_r.
+
+ ----LLLL lllliiiibbbbddddiiiirrrr
+ This parameter specifies the location of the shared
+ libraries used by ssssmmmmbbbbsssshhhh. The default value is specified
+ at compile time.
+
+ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
+ To use the ssssmmmmbbbbsssshhhh command, execute ssssmmmmbbbbsssshhhh from the prompt and
+ enter the username and password that authenticates you to
+ the machine running the Windows NT operating system.
+
+ system% ssssmmmmbbbbsssshhhh
+ Username: uuuusssseeeerrrr
+ Password: XXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBSSSSHHHH((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBSSSSHHHH((((1111))))
+
+
+
+
+
+
+ Any dynamically linked command you execute from this shell
+ will access the /_s_m_b directory using the smb protocol. For
+ example, the command llllssss ////ssssmmmmbbbb will show a list of workgroups.
+ The command llllssss ////ssssmmmmbbbb////MMMMYYYYGGGGRRRROOOOUUUUPPPP will show all the machines in
+ the workgroup MYGROUP. The command llllssss
+ ////ssssmmmmbbbb////MMMMYYYYGGGGRRRROOOOUUUUPPPP////<<<<mmmmaaaacccchhhhiiiinnnneeee----nnnnaaaammmmeeee>>>> will show the share names for
+ that machine. You could then, for example, use the ccccdddd
+ command to change directories, vvvviiii to edit files, and rrrrccccpppp to
+ copy files.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ BBBBUUUUGGGGSSSS
+ ssssmmmmbbbbsssshhhh works by intercepting the standard libc calls with the
+ dynamically loaded versions in _s_m_b_w_r_a_p_p_e_r._o. Not all calls
+ have been "wrapped", so some programs may not function
+ correctly under ssssmmmmbbbbsssshhhh .
+
+ Programs which are not dynamically linked cannot make use of
+ ssssmmmmbbbbsssshhhh's functionality. Most versions of UNIX have a ffffiiiilllleeee
+ command that will describe how a program was linked.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbdddd((((8888)))) smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbstatus.1 b/packaging/Caldera/OpenServer/man/cat.1/smbstatus.1
new file mode 100755
index 00000000000..3896925a7f2
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbstatus.1
@@ -0,0 +1,132 @@
+
+
+
+ SSSSMMMMBBBBSSSSTTTTAAAATTTTUUUUSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBSSSSTTTTAAAATTTTUUUUSSSS((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbstatus - report on current Samba connections
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbssssttttaaaattttuuuussss [ ----PPPP ] [ ----bbbb ] [ ----dddd ] [ ----LLLL ] [ ----pppp ] [ ----SSSS ] [
+ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>> ] [ ----uuuu <<<<uuuusssseeeerrrrnnnnaaaammmmeeee>>>> ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ ssssmmmmbbbbssssttttaaaattttuuuussss is a very simple program to list the current Samba
+ connections.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----PPPP If samba has been compiled with the profiling option,
+ print only the contents of the profiling shared memory
+ area.
+
+ ----bbbb gives brief output.
+
+ ----dddd gives verbose output.
+
+ ----LLLL causes smbstatus to only list locks.
+
+ ----pppp print a list of ssssmmmmbbbbdddd((((8888)))) processes and exit. Useful for
+ scripting.
+
+ ----SSSS causes smbstatus to only list shares.
+
+ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>>
+ The default configuration file name is determined at
+ compile time. The file specified contains the
+ configuration details required by the server. See
+ _s_m_b._c_o_n_f(_5)
+ for more information.
+
+ ----uuuu <<<<uuuusssseeeerrrrnnnnaaaammmmeeee>>>>
+ selects information relevant to _u_s_e_r_n_a_m_e only.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbdddd((((8888)))) and smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBSSSSTTTTAAAATTTTUUUUSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBSSSSTTTTAAAATTTTUUUUSSSS((((1111))))
+
+
+
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/smbtar.1 b/packaging/Caldera/OpenServer/man/cat.1/smbtar.1
new file mode 100755
index 00000000000..fbcc24d9979
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/smbtar.1
@@ -0,0 +1,132 @@
+
+
+
+ SSSSMMMMBBBBTTTTAAAARRRR((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBTTTTAAAARRRR((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbtar - shell script for backing up SMB/CIFS shares
+ directly to UNIX tape drives
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbttttaaaarrrr ----ssss sssseeeerrrrvvvveeeerrrr [ ----pppp ppppaaaasssssssswwwwoooorrrrdddd ] [ ----xxxx sssseeeerrrrvvvviiiicccceeeessss ] [ ----XXXX ] [
+ ----dddd ddddiiiirrrreeeeccccttttoooorrrryyyy ] [ ----uuuu uuuusssseeeerrrr ] [ ----tttt ttttaaaappppeeee ] [ ----tttt ttttaaaappppeeee ] [ ----bbbb
+ bbbblllloooocccckkkkssssiiiizzzzeeee ] [ ----NNNN ffffiiiilllleeeennnnaaaammmmeeee ] [ ----iiii ] [ ----rrrr ] [ ----llll lllloooogggglllleeeevvvveeeellll
+ ] [ ----vvvv ] ffffiiiilllleeeennnnaaaammmmeeeessss
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ ssssmmmmbbbbttttaaaarrrr is a very small shell script on top of ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ which dumps SMB shares directly to tape.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----ssss sssseeeerrrrvvvveeeerrrr
+ The SMB/CIFS server that the share resides upon.
+
+ ----xxxx sssseeeerrrrvvvviiiicccceeee
+ The share name on the server to connect to. The default
+ is "backup".
+
+ ----XXXX Exclude mode. Exclude filenames... from tar create or
+ restore.
+
+ ----dddd ddddiiiirrrreeeeccccttttoooorrrryyyy
+ Change to initial _d_i_r_e_c_t_o_r_y before restoring / backing
+ up files.
+
+ ----vvvv Verbose mode.
+
+ ----pppp ppppaaaasssssssswwwwoooorrrrdddd
+ The password to use to access a share. Default: none
+
+ ----uuuu uuuusssseeeerrrr
+ The user id to connect as. Default: UNIX login name.
+
+ ----tttt ttttaaaappppeeee
+ Tape device. May be regular file or tape device.
+ Default: $_T_A_P_E environmental variable; if not set, a
+ file called _t_a_r._o_u_t .
+
+ ----bbbb bbbblllloooocccckkkkssssiiiizzzzeeee
+ Blocking factor. Defaults to 20. See ttttaaaarrrr((((1111)))) for a
+ fuller explanation.
+
+ ----NNNN ffffiiiilllleeeennnnaaaammmmeeee
+ Backup only files newer than filename. Could be used
+ (for example) on a log file to implement incremental
+ backups.
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBTTTTAAAARRRR((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBTTTTAAAARRRR((((1111))))
+
+
+
+ ----iiii Incremental mode; tar files are only backed up if they
+ have the archive bit set. The archive bit is reset
+ after each file is read.
+
+ ----rrrr Restore. Files are restored to the share from the tar
+ file.
+
+ ----llll lllloooogggg lllleeeevvvveeeellll
+ Log (debug) level. Corresponds to the -_d flag of
+ ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111)))) .
+
+ EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT VVVVAAAARRRRIIIIAAAABBBBLLLLEEEESSSS
+ The $_T_A_P_E variable specifies the default tape device to
+ write to. May be overridden with the -t option.
+
+ BBBBUUUUGGGGSSSS
+ The ssssmmmmbbbbttttaaaarrrr script has different options from ordinary tar
+ and tar called from smbclient.
+
+ CCCCAAAAVVVVEEEEAAAATTTTSSSS
+ Sites that are more careful about security may not like the
+ way the script handles PC passwords. Backup and restore work
+ on entire shares, should work on file lists. smbtar works
+ best with GNU tar and may not work well with other versions.
+
+ DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
+ See the DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS section for the ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ command.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbdddd((((8888)))) ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111)))) smb.conf(5)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ Ricky Poulten <URL:mailto:poultenr@logica.co.uk> wrote the
+ tar extension and this man page. The ssssmmmmbbbbttttaaaarrrr script was
+ heavily rewritten and improved by Martin Kraemer
+ <URL:mailto:Martin.Kraemer@mch.sni.de>. Many thanks to
+ everyone who suggested extensions, improvements, bug fixes,
+ etc. The man page sources were converted to YODL format
+ (another excellent piece of Open Source software, available
+ at ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter.
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/testparm.1 b/packaging/Caldera/OpenServer/man/cat.1/testparm.1
new file mode 100755
index 00000000000..b1dfa24bb00
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/testparm.1
@@ -0,0 +1,132 @@
+
+
+
+ TTTTEEEESSSSTTTTPPPPAAAARRRRMMMM((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) TTTTEEEESSSSTTTTPPPPAAAARRRRMMMM((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ testparm - check an smb.conf configuration file for
+ internal correctness
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ tttteeeessssttttppppaaaarrrrmmmm [ ----ssss ] [ ----hhhh ] [ ----xxxx ] [ ----LLLL <<<<sssseeeerrrrvvvveeeerrrrnnnnaaaammmmeeee>>>> ] ccccoooonnnnffffiiiigggg
+ ffffiiiilllleeeennnnaaaammmmeeee [ hhhhoooossssttttnnnnaaaammmmeeee hhhhoooossssttttIIIIPPPP ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ tttteeeessssttttppppaaaarrrrmmmm is a very simple test program to check an ssssmmmmbbbbdddd
+ configuration file for internal correctness. If this program
+ reports no problems, you can use the configuration file with
+ confidence that ssssmmmmbbbbdddd will successfully load the
+ configuration file.
+
+ Note that this is NNNNOOOOTTTT a guarantee that the services
+ specified in the configuration file will be available or
+ will operate as expected.
+
+ If the optional host name and host IP address are specified
+ on the command line, this test program will run through the
+ service entries reporting whether the specified host has
+ access to each service.
+
+ If tttteeeessssttttppppaaaarrrrmmmm finds an error in the _s_m_b._c_o_n_f file it returns
+ an exit code of 1 to the calling program, else it returns an
+ exit code of 0. This allows shell scripts to test the output
+ from tttteeeessssttttppppaaaarrrrmmmm.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----ssss Without this option, tttteeeessssttttppppaaaarrrrmmmm will prompt for a
+ carriage return after printing the service names and
+ before dumping the service definitions.
+
+ ----hhhh Print usage message
+
+ ----xxxx Print only parameters that have non-default values
+
+ ----LLLL sssseeeerrrrvvvveeeerrrrnnnnaaaammmmeeee
+ Sets the value of the %L macro to _s_e_r_v_e_r_n_a_m_e. This is
+ useful for testing include files specified with the %L
+ macro.
+
+ ccccoooonnnnffffiiiiggggffffiiiilllleeeennnnaaaammmmeeee
+ This is the name of the configuration file to check. If
+ this parameter is not present then the default _s_m_b._c_o_n_f
+ file will be checked.
+
+ hhhhoooossssttttnnnnaaaammmmeeee
+ If this parameter and the following are specified, then
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ TTTTEEEESSSSTTTTPPPPAAAARRRRMMMM((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) TTTTEEEESSSSTTTTPPPPAAAARRRRMMMM((((1111))))
+
+
+
+ tttteeeessssttttppppaaaarrrrmmmm will examine the _h_o_s_t_s _a_l_l_o_w and _h_o_s_t_s _d_e_n_y
+ parameters in the _s_m_b._c_o_n_f file to determine if the
+ hostname with this IP address would be allowed access
+ to the ssssmmmmbbbbdddd server. If this parameter is supplied, the
+ hostIP parameter must also be supplied.
+
+ hhhhoooossssttttIIIIPPPP
+ This is the IP address of the host specified in the
+ previous parameter. This address must be supplied if
+ the hostname parameter is supplied.
+
+ FFFFIIIILLLLEEEESSSS
+ _s_m_b._c_o_n_f
+ This is usually the name of the configuration file used
+ by ssssmmmmbbbbdddd.
+
+ DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
+ The program will issue a message saying whether the
+ configuration file loaded OK or not. This message may be
+ preceded by errors and warnings if the file did not load. If
+ the file was loaded OK, the program then dumps all known
+ service details to stdout.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ _s_m_b._c_o_n_f(_5) ssssmmmmbbbbdddd((((8888))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/testprns.1 b/packaging/Caldera/OpenServer/man/cat.1/testprns.1
new file mode 100755
index 00000000000..8b0eab57b6f
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/testprns.1
@@ -0,0 +1,132 @@
+
+
+
+ TTTTEEEESSSSTTTTPPPPRRRRNNNNSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) TTTTEEEESSSSTTTTPPPPRRRRNNNNSSSS((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ testprns - check printer name for validity with smbd
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ tttteeeessssttttpppprrrrnnnnssss pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee [ pppprrrriiiinnnnttttccccaaaappppnnnnaaaammmmeeee ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ tttteeeessssttttpppprrrrnnnnssss is a very simple test program to determine whether
+ a given printer name is valid for use in a service to be
+ provided by ssssmmmmbbbbdddd((((8888))))
+
+ "Valid" in this context means "can be found in the printcap
+ specified". This program is very stupid - so stupid in fact
+ that it would be wisest to always specify the printcap file
+ to use.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ pppprrrriiiinnnntttteeeerrrrnnnnaaaammmmeeee
+ The printer name to validate.
+
+ Printer names are taken from the first field in each
+ record in the printcap file, single printer names and
+ sets of aliases separated by vertical bars ("|") are
+ recognized. Note that no validation or checking of the
+ printcap syntax is done beyond that required to extract
+ the printer name. It may be that the print spooling
+ system is more forgiving or less forgiving than
+ tttteeeessssttttpppprrrrnnnnssss. However, if tttteeeessssttttpppprrrrnnnnssss finds the printer then
+ ssssmmmmbbbbdddd should do so as well.
+
+ pppprrrriiiinnnnttttccccaaaappppnnnnaaaammmmeeee
+ This is the name of the printcap file within which to
+ search for the given printer name.
+
+ If no printcap name is specified tttteeeessssttttpppprrrrnnnnssss will attempt
+ to scan the printcap file name specified at compile
+ time.
+
+ FFFFIIIILLLLEEEESSSS
+ /_e_t_c/_p_r_i_n_t_c_a_p
+ This is usually the default printcap file to scan. See
+ _p_r_i_n_t_c_a_p (_5).
+
+ DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
+ If a printer is found to be valid, the message "Printer name
+ <printername> is valid" will be displayed.
+
+ If a printer is found to be invalid, the message "Printer
+ name <printername> is not valid" will be displayed.
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ TTTTEEEESSSSTTTTPPPPRRRRNNNNSSSS((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) TTTTEEEESSSSTTTTPPPPRRRRNNNNSSSS((((1111))))
+
+
+
+ All messages that would normally be logged during operation
+ of the Samba daemons are logged by this program to the file
+ _t_e_s_t._l_o_g in the current directory. The program runs at
+ debuglevel 3, so quite extensive logging information is
+ written. The log should be checked carefully for errors and
+ warnings.
+
+ Other messages are self-explanatory.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ _p_r_i_n_t_c_a_p(_5), ssssmmmmbbbbdddd((((8888)))) ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.1/wbinfo.1 b/packaging/Caldera/OpenServer/man/cat.1/wbinfo.1
new file mode 100755
index 00000000000..22a459a61ef
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.1/wbinfo.1
@@ -0,0 +1,198 @@
+
+
+
+ WWWWBBBBIIIINNNNFFFFOOOO((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) WWWWBBBBIIIINNNNFFFFOOOO((((1111))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ wbinfo - Query information from winbind daemon
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ wwwwbbbbiiiinnnnffffoooo [ ----uuuu ] [ ----gggg ] [ ----hhhh nnnnaaaammmmeeee ] [ ----iiii iiiipppp ] [ ----nnnn nnnnaaaammmmeeee ]
+ [ ----ssss ssssiiiidddd ] [ ----UUUU uuuuiiiidddd ] [ ----GGGG ggggiiiidddd ] [ ----SSSS ssssiiiidddd ] [ ----YYYY ssssiiiidddd ]
+ [ ----tttt ] [ ----mmmm ] [ ----rrrr uuuusssseeeerrrr ] [ ----aaaa uuuusssseeeerrrr%%%%ppppaaaasssssssswwwwoooorrrrdddd ] [ ----AAAA
+ uuuusssseeeerrrr%%%%ppppaaaasssssssswwwwoooorrrrdddd ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ The wwwwbbbbiiiinnnnffffoooo program queries and returns information created
+ and used by the wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon.
+
+ The wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon must be configured and running for
+ the wwwwbbbbiiiinnnnffffoooo program to be able to return information.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----uuuu This option will list all users available in the
+ Windows NT domain for which the wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon is
+ operating in. Users in all trusted domains will also be
+ listed. Note that this operation does not assign user
+ ids to any users that have not already been seen by
+ wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))).
+
+ ----gggg This option will list all groups available in the
+ Windows NT domain for which the wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon is
+ operating in. Groups in all trusted domains will also
+ be listed. Note that this operation does not assign
+ group ids to any groups that have not already been seen
+ by wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))).
+
+ ----hhhh nnnnaaaammmmeeee
+ The -_h option queries wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) to query the WINS
+ server for the IP address associated with the NetBIOS
+ name specified by the _n_a_m_e parameter.
+
+ ----iiii iiiipppp
+ The -_i option queries wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) to send a node status
+ request to get the NetBIOS name associated with the IP
+ address specified by the _i_p parameter.
+
+ ----nnnn nnnnaaaammmmeeee
+ The -_n option queries wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) for the SID
+ associated with the name specified. Domain names can be
+ specified before the user name by using the winbind
+ separator character. For example CWDOM1/Administrator
+ refers to the Administrator user in the domain CWDOM1.
+ If no domain is specified then the domain used is the
+ one specified in the _s_m_b._c_o_n_f _w_o_r_k_g_r_o_u_p parameter.
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ WWWWBBBBIIIINNNNFFFFOOOO((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) WWWWBBBBIIIINNNNFFFFOOOO((((1111))))
+
+
+
+ ----ssss ssssiiiidddd
+ Use -_s to resolve a SID to a name. This is the inverse
+ of the -_n option above. SIDs must be specified as ASCII
+ strings in the traditional Microsoft format. For
+ example, S-1-5-21-1455342024-3071081365-2475485837-500.
+
+ ----UUUU uuuuiiiidddd
+ Try to convert a UNIX user id to a Windows NT SID. If
+ the uid specified does not refer to one within the
+ winbind uid range then the operation will fail.
+
+ ----GGGG ggggiiiidddd
+ Try to convert a UNIX group id to a Windows NT SID. If
+ the gid specified does not refer to one within the
+ winbind gid range then the operation will fail.
+
+ ----SSSS ssssiiiidddd
+ Convert a SID to a UNIX user id. If the SID does not
+ correspond to a UNIX user mapped by wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) then
+ the operation will fail.
+
+ ----YYYY ssssiiiidddd
+ Convert a SID to a UNIX group id. If the SID does not
+ correspond to a UNIX group mapped by wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) then
+ the operation will fail.
+
+ ----tttt Verify that the workstation trust account created when
+ the Samba server is added to the Windows NT domain is
+ working.
+
+ ----mmmm Produce a list of domains trusted by the Windows NT
+ server wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) contacts when resolving names. This
+ list does not include the Windows NT domain the server
+ is a Primary Domain Controller for.
+
+ ----rrrr uuuusssseeeerrrrnnnnaaaammmmeeee
+ Try to obtain the list of UNIX group ids to which the
+ user belongs. This only works for users defined on a
+ Domain Controller.
+
+ ----aaaa uuuusssseeeerrrrnnnnaaaammmmeeee%%%%ppppaaaasssssssswwwwoooorrrrdddd
+ Attempt to authenticate a user via winbindd. This
+ checks both authenticaion methods and reports its
+ results.
+
+ ----AAAA uuuusssseeeerrrrnnnnaaaammmmeeee%%%%ppppaaaasssssssswwwwoooorrrrdddd
+ Store username and password used by winbindd during
+ session setup to a domain controller. This enables
+ winbindd to operate in a Windows 2000 domain with
+ Restrict Anonymous turned on (a.k.a. Permissions
+ compatiable with Windows 2000 servers only).
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ WWWWBBBBIIIINNNNFFFFOOOO((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) WWWWBBBBIIIINNNNFFFFOOOO((((1111))))
+
+
+
+ EEEEXXXXIIIITTTT SSSSTTTTAAAATTTTUUUUSSSS
+ The wbinfo program returns 0 if the operation succeeded, or
+ 1 if the operation failed. If the wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon is not
+ working wwwwbbbbiiiinnnnffffoooo will always return failure.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888))))
+
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ wwwwbbbbiiiinnnnffffoooo and wwwwiiiinnnnbbbbiiiinnnndddddddd were written by Tim Potter.
+
+ The conversion to DocBook for Samba 2.2 was done by Gerald
+ Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.5/lmhosts.5 b/packaging/Caldera/OpenServer/man/cat.5/lmhosts.5
new file mode 100755
index 00000000000..d0c0765ac0c
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.5/lmhosts.5
@@ -0,0 +1,132 @@
+
+
+
+ LLLLMMMMHHHHOOOOSSSSTTTTSSSS((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) LLLLMMMMHHHHOOOOSSSSTTTTSSSS((((5555))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ lmhosts - The Samba NetBIOS hosts file
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ _l_m_h_o_s_t_s is the Samba NetBIOS name to IP address mapping
+ file.
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This file is part of the Samba suite.
+
+ _l_m_h_o_s_t_s is the SSSSaaaammmmbbbbaaaa NetBIOS name to IP address mapping
+ file. It is very similar to the /_e_t_c/_h_o_s_t_s file format,
+ except that the hostname component must correspond to the
+ NetBIOS naming format.
+
+ FFFFIIIILLLLEEEE FFFFOOOORRRRMMMMAAAATTTT
+ It is an ASCII file containing one line for NetBIOS name.
+ The two fields on each line are separated from each other by
+ white space. Any entry beginning with '#' is ignored. Each
+ line in the lmhosts file contains the following information
+ :
+
+ o+ IP Address - in dotted decimal format.
+
+ o+ NetBIOS Name - This name format is a maximum fifteen
+ character host name, with an optional trailing '#'
+ character followed by the NetBIOS name type as two
+ hexadecimal digits.
+
+ If the trailing '#' is omitted then the given IP address
+ will be returned for all names that match the given name,
+ whatever the NetBIOS name type in the lookup.
+
+ An example follows :
+
+ #
+ # Sample Samba lmhosts file.
+ #
+ 192.9.200.1 TESTPC
+ 192.9.200.20 NTSERVER#20
+ 192.9.200.21 SAMBASERVER
+
+
+
+ Contains three IP to NetBIOS name mappings. The first and
+ third will be returned for any queries for the names
+ "TESTPC" and "SAMBASERVER" respectively, whatever the type
+ component of the NetBIOS name requested.
+
+ The second mapping will be returned only when the "0x20"
+ name type for a name "NTSERVER" is queried. Any other name
+ type will not be resolved.
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ LLLLMMMMHHHHOOOOSSSSTTTTSSSS((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) LLLLMMMMHHHHOOOOSSSSTTTTSSSS((((5555))))
+
+
+
+ The default location of the _l_m_h_o_s_t_s file is in the same
+ directory as the smb.conf(5)> file.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ and ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.5/smb.conf.5 b/packaging/Caldera/OpenServer/man/cat.5/smb.conf.5
new file mode 100755
index 00000000000..b9dc8c1b2b7
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.5/smb.conf.5
@@ -0,0 +1,9108 @@
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smb.conf - The configuration file for the Samba suite
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ The _s_m_b._c_o_n_f file is a configuration file for the Samba
+ suite. _s_m_b._c_o_n_f contains runtime configuration information
+ for the Samba programs. The _s_m_b._c_o_n_f file is designed to be
+ configured and administered by the sssswwwwaaaatttt((((8888))))
+ program. The complete description of the file format and
+ possible parameters held within are here for reference
+ purposes.
+
+ FFFFIIIILLLLEEEE FFFFOOOORRRRMMMMAAAATTTT
+ The file consists of sections and parameters. A section
+ begins with the name of the section in square brackets and
+ continues until the next section begins. Sections contain
+ parameters of the form
+
+ _n_a_m_e = _v_a_l_u_e
+
+ The file is line-based - that is, each newline-terminated
+ line represents either a comment, a section name or a
+ parameter.
+
+ Section and parameter names are not case sensitive.
+
+ Only the first equals sign in a parameter is significant.
+ Whitespace before or after the first equals sign is
+ discarded. Leading, trailing and internal whitespace in
+ section and parameter names is irrelevant. Leading and
+ trailing whitespace in a parameter value is discarded.
+ Internal whitespace within a parameter value is retained
+ verbatim.
+
+ Any line beginning with a semicolon (';') or a hash ('#')
+ character is ignored, as are lines containing only
+ whitespace.
+
+ Any line ending in a '\' is continued on the next line in
+ the customary UNIX fashion.
+
+ The values following the equals sign in parameters are all
+ either a string (no quotes needed) or a boolean, which may
+ be given as yes/no, 0/1 or true/false. Case is not
+ significant in boolean values, but is preserved in string
+ values. Some items such as create modes are numeric.
+
+ SSSSEEEECCCCTTTTIIIIOOOONNNN DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNNSSSS
+ Each section in the configuration file (except for the
+ [global] section) describes a shared resource (known as a
+ "share"). The section name is the name of the shared
+ resource and the parameters within the section define the
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ shares attributes.
+
+ There are three special sections, [global], [homes] and
+ [printers], which are described under ssssppppeeeecccciiiiaaaallll sssseeeeccccttttiiiioooonnnnssss. The
+ following notes apply to ordinary section descriptions.
+
+ A share consists of a directory to which access is being
+ given plus a description of the access rights which are
+ granted to the user of the service. Some housekeeping
+ options are also specifiable.
+
+ Sections are either file share services (used by the client
+ as an extension of their native file systems) or printable
+ services (used by the client to access print services on the
+ host running the server).
+
+ Sections may be designated gggguuuueeeesssstttt services, in which case no
+ password is required to access them. A specified UNIX gggguuuueeeesssstttt
+ aaaaccccccccoooouuuunnnntttt is used to define access privileges in this case.
+
+ Sections other than guest services will require a password
+ to access them. The client provides the username. As older
+ clients only provide passwords and not usernames, you may
+ specify a list of usernames to check against the password
+ using the "user =" option in the share definition. For
+ modern clients such as Windows 95/98/ME/NT/2000, this should
+ not be necessary.
+
+ Note that the access rights granted by the server are masked
+ by the access rights granted to the specified or guest UNIX
+ user by the host system. The server does not grant more
+ access than the host system grants.
+
+ The following sample section defines a file space share. The
+ user has write access to the path /_h_o_m_e/_b_a_r. The share is
+ accessed via the share name "foo":
+
+ [foo]
+ path = /home/bar
+ read only = no
+
+
+
+
+ The following sample section defines a printable share. The
+ share is readonly, but printable. That is, the only write
+ access permitted is via calls to open, write to and close a
+ spool file. The gggguuuueeeesssstttt ooookkkk parameter means access will be
+ permitted as the default guest user (specified elsewhere):
+
+ [aprinter]
+ path = /usr/spool/public
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ read only = yes
+ printable = yes
+ guest ok = yes
+
+
+
+
+ SSSSPPPPEEEECCCCIIIIAAAALLLL SSSSEEEECCCCTTTTIIIIOOOONNNNSSSS
+ TTTTHHHHEEEE GGGGLLLLOOOOBBBBAAAALLLL SSSSEEEECCCCTTTTIIIIOOOONNNN
+ parameters in this section apply to the server as a whole,
+ or are defaults for sections which do not specifically
+ define certain items. See the notes under PARAMETERS for
+ more information.
+
+ TTTTHHHHEEEE HHHHOOOOMMMMEEEESSSS SSSSEEEECCCCTTTTIIIIOOOONNNN
+ If a section called homes is included in the configuration
+ file, services connecting clients to their home directories
+ can be created on the fly by the server.
+
+ When the connection request is made, the existing sections
+ are scanned. If a match is found, it is used. If no match is
+ found, the requested section name is treated as a user name
+ and looked up in the local password file. If the name exists
+ and the correct password has been given, a share is created
+ by cloning the [homes] section.
+
+ Some modifications are then made to the newly created share:
+
+ o+ The share name is changed from homes to the located
+ username.
+
+ o+ If no path was given, the path is set to the user's home
+ directory.
+
+ If you decide to use a ppppaaaatttthhhh ==== line in your [homes] section
+ then you may find it useful to use the %S macro. For example
+ :
+
+ ppppaaaatttthhhh ==== ////ddddaaaattttaaaa////ppppcccchhhhoooommmmeeee////%%%%SSSS
+
+ would be useful if you have different home directories for
+ your PCs than for UNIX access.
+
+ This is a fast and simple way to give a large number of
+ clients access to their home directories with a minimum of
+ fuss.
+
+ A similar process occurs if the requested section name is
+ "homes", except that the share name is not changed to that
+ of the requesting user. This method of using the [homes]
+ section works well if different users share a client PC.
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The [homes] section can specify all the parameters a normal
+ service section can specify, though some make more sense
+ than others. The following is a typical and suitable [homes]
+ section:
+
+ [homes]
+ read only = no
+
+
+
+
+ An important point is that if guest access is specified in
+ the [homes] section, all home directories will be visible to
+ all clients wwwwiiiitttthhhhoooouuuutttt aaaa ppppaaaasssssssswwwwoooorrrrdddd. In the very unlikely event
+ that this is actually desirable, it would be wise to also
+ specify rrrreeeeaaaadddd oooonnnnllllyyyy aaaacccccccceeeessssssss.
+
+ Note that the bbbbrrrroooowwwwsssseeeeaaaabbbblllleeee flag for auto home directories will
+ be inherited from the global browseable flag, not the
+ [homes] browseable flag. This is useful as it means setting
+ bbbbrrrroooowwwwsssseeeeaaaabbbblllleeee ==== nnnnoooo in the [homes] section will hide the [homes]
+ share but make any auto home directories visible.
+
+ TTTTHHHHEEEE PPPPRRRRIIIINNNNTTTTEEEERRRRSSSS SSSSEEEECCCCTTTTIIIIOOOONNNN
+ This section works like [homes], but for printers.
+
+ If a [printers] section occurs in the configuration file,
+ users are able to connect to any printer specified in the
+ local host's printcap file.
+
+ When a connection request is made, the existing sections are
+ scanned. If a match is found, it is used. If no match is
+ found, but a [homes] section exists, it is used as described
+ above. Otherwise, the requested section name is treated as a
+ printer name and the appropriate printcap file is scanned to
+ see if the requested section name is a valid printer share
+ name. If a match is found, a new printer share is created by
+ cloning the [printers] section.
+
+ A few modifications are then made to the newly created
+ share:
+
+ o+ The share name is set to the located printer name
+
+ o+ If no printer name was given, the printer name is set to
+ the located printer name
+
+ o+ If the share does not permit guest access and no username
+ was given, the username is set to the located printer
+ name.
+
+ Note that the [printers] service MUST be printable - if you
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ specify otherwise, the server will refuse to load the
+ configuration file.
+
+ Typically the path specified would be that of a world-
+ writeable spool directory with the sticky bit set on it. A
+ typical [printers] entry would look like this:
+
+ [printers]
+ path = /usr/spool/public
+ guest ok = yes
+ printable = yes
+
+
+
+ All aliases given for a printer in the printcap file are
+ legitimate printer names as far as the server is concerned.
+ If your printing subsystem doesn't work like that, you will
+ have to set up a pseudo-printcap. This is a file consisting
+ of one or more lines like this:
+
+ alias|alias|alias|alias...
+
+
+
+
+ Each alias should be an acceptable printer name for your
+ printing subsystem. In the [global] section, specify the new
+ file as your printcap. The server will then only recognize
+ names found in your pseudo-printcap, which of course can
+ contain whatever aliases you like. The same technique could
+ be used simply to limit access to a subset of your local
+ printers.
+
+ An alias, by the way, is defined as any component of the
+ first entry of a printcap record. Records are separated by
+ newlines, components (if there are more than one) are
+ separated by vertical bar symbols ('|').
+
+ NOTE: On SYSV systems which use lpstat to determine what
+ printers are defined on the system you may be able to use
+ "printcap name = lpstat" to automatically obtain a list of
+ printers. See the "printcap name" option for more details.
+
+ PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRRSSSS
+ parameters define the specific attributes of sections.
+
+ Some parameters are specific to the [global] section (e.g.,
+ sssseeeeccccuuuurrrriiiittttyyyy). Some parameters are usable in all sections (e.g.,
+ ccccrrrreeeeaaaatttteeee mmmmooooddddeeee). All others are permissible only in normal
+ sections. For the purposes of the following descriptions the
+ [homes] and [printers] sections will be considered normal.
+ The letter GGGG in parentheses indicates that a parameter is
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ specific to the [global] section. The letter SSSS indicates
+ that a parameter can be specified in a service specific
+ section. Note that all SSSS parameters can also be specified in
+ the [global] section - in which case they will define the
+ default behavior for all services.
+
+ parameters are arranged here in alphabetical order - this
+ may not create best bedfellows, but at least you can find
+ them! Where there are synonyms, the preferred synonym is
+ described, others refer to the preferred synonym.
+
+ VVVVAAAARRRRIIIIAAAABBBBLLLLEEEE SSSSUUUUBBBBSSSSTTTTIIIITTTTUUUUTTTTIIIIOOOONNNNSSSS
+ Many of the strings that are settable in the config file can
+ take substitutions. For example the option "path = /tmp/%u"
+ would be interpreted as "path = /tmp/john" if the user
+ connected with the username john.
+
+ These substitutions are mostly noted in the descriptions
+ below, but there are some general substitutions which apply
+ whenever they might be relevant. These are:
+
+ %%%%SSSS the name of the current service, if any.
+
+ %%%%PPPP the root directory of the current service, if any.
+
+ %%%%uuuu user name of the current service, if any.
+
+ %%%%gggg primary group name of %u.
+
+ %%%%UUUU session user name (the user name that the client
+ wanted, not necessarily the same as the one they got).
+
+ %%%%GGGG primary group name of %U.
+
+ %%%%HHHH the home directory of the user given by %u.
+
+ %%%%vvvv the Samba version.
+
+ %%%%hhhh the Internet hostname that Samba is running on.
+
+ %%%%mmmm the NetBIOS name of the client machine (very useful).
+
+ %%%%LLLL the NetBIOS name of the server. This allows you to
+ change your config based on what the client calls you.
+ Your server can have a "dual personality".
+
+ Note that this paramater is not available when Samba
+ listens on port 445, as clients no longer send this
+ information
+
+ %%%%MMMM the Internet name of the client machine.
+
+
+
+
+ Page 6 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ %%%%NNNN the name of your NIS home directory server. This is
+ obtained from your NIS auto.map entry. If you have not
+ compiled Samba with the --------wwwwiiiitttthhhh----aaaauuuuttttoooommmmoooouuuunnnntttt option then
+ this value will be the same as %L.
+
+ %%%%pppp the path of the service's home directory, obtained from
+ your NIS auto.map entry. The NIS auto.map entry is
+ split up as "%N:%p".
+
+ %%%%RRRR the selected protocol level after protocol negotiation.
+ It can be one of CORE, COREPLUS, LANMAN1, LANMAN2 or
+ NT1.
+
+ %%%%dddd The process id of the current server process.
+
+ %%%%aaaa the architecture of the remote machine. Only some are
+ recognized, and those may not be 100% reliable. It
+ currently recognizes Samba, WfWg, Win95, WinNT and
+ Win2k. Anything else will be known as "UNKNOWN". If it
+ gets it wrong then sending a level 3 log to
+ samba@samba.org
+ <URL:mailto:samba@samba.org> should allow it to be
+ fixed.
+
+ %%%%IIII The IP address of the client machine.
+
+ %%%%TTTT the current date and time.
+
+ %%%%$$$$((((_e_n_v_v_a_r))))
+ The value of the environment variable _e_n_v_a_r.
+
+ There are some quite creative things that can be done with
+ these substitutions and other smb.conf options.
+
+ NNNNAAAAMMMMEEEE MMMMAAAANNNNGGGGLLLLIIIINNNNGGGG
+ Samba supports "name mangling" so that DOS and Windows
+ clients can use files that don't conform to the 8.3 format.
+ It can also be set to adjust the case of 8.3 format
+ filenames.
+
+ There are several options that control the way mangling is
+ performed, and they are grouped here rather than listed
+ separately. For the defaults look at the output of the
+ testparm program.
+
+ All of these options can be set separately for each service
+ (or globally, of course).
+
+ The options are:
+
+ mmmmaaaannnngggglllliiiinnnngggg mmmmeeeetttthhhhoooodddd
+ controls the algorithm used for the generating the
+
+
+
+ Page 7 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ mangled names. Can take two different values, "hash"
+ and "hash2". "hash" is the default and is the algorithm
+ that has been used in Samba for many years. "hash2" is
+ a newer and considered a better algorithm (generates
+ less collisions) in the names. However, many Win32
+ applications store the mangled names and so changing to
+ the new algorithm must not be done lightly as these
+ applications may break unless reinstalled. New
+ installations of Samba may set the default to hash2.
+ Default hhhhaaaasssshhhh.
+
+ mmmmaaaannnngggglllleeee ccccaaaasssseeee ==== yyyyeeeessss////nnnnoooo
+ controls if names that have characters that aren't of
+ the "default" case are mangled. For example, if this is
+ yes then a name like "Mail" would be mangled. Default
+ nnnnoooo.
+
+ ccccaaaasssseeee sssseeeennnnssssiiiittttiiiivvvveeee ==== yyyyeeeessss////nnnnoooo
+ controls whether filenames are case sensitive. If they
+ aren't then Samba must do a filename search and match
+ on passed names. Default nnnnoooo.
+
+ ddddeeeeffffaaaauuuulllltttt ccccaaaasssseeee ==== uuuuppppppppeeeerrrr////lllloooowwwweeeerrrr
+ controls what the default case is for new filenames.
+ Default lllloooowwwweeeerrrr.
+
+ pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ==== yyyyeeeessss////nnnnoooo
+ controls if new files are created with the case that
+ the client passes, or if they are forced to be the
+ "default" case. Default yyyyeeeessss.
+
+ sssshhhhoooorrrrtttt pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ==== yyyyeeeessss////nnnnoooo
+ controls if new files which conform to 8.3 syntax, that
+ is all in upper case and of suitable length, are
+ created upper case, or if they are forced to be the
+ "default" case. This option can be use with "preserve
+ case = yes" to permit long filenames to retain their
+ case, while short names are lowercased. Default yyyyeeeessss.
+
+ By default, Samba 2.2 has the same semantics as a Windows NT
+ server, in that it is case insensitive but case preserving.
+
+ NNNNOOOOTTTTEEEE AAAABBBBOOOOUUUUTTTT UUUUSSSSEEEERRRRNNNNAAAAMMMMEEEE////PPPPAAAASSSSSSSSWWWWOOOORRRRDDDD VVVVAAAALLLLIIIIDDDDAAAATTTTIIIIOOOONNNN
+ There are a number of ways in which a user can connect to a
+ service. The server uses the following steps in determining
+ if it will allow a connection to a specified service. If all
+ the steps fail, then the connection request is rejected.
+ However, if one of the steps succeeds, then the following
+ steps are not checked.
+
+ If the service is marked "guest only = yes" and the server
+ is running with share-level security ("security = share")
+
+
+
+ Page 8 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ then steps 1 to 5 are skipped.
+
+ 1. If the client has passed a username/password pair and
+ that username/password pair is validated by the UNIX
+ system's password programs then the connection is made
+ as that username. Note that this includes the
+ \\server\service%_u_s_e_r_n_a_m_e method of passing a username.
+
+ 2. If the client has previously registered a username with
+ the system and now supplies a correct password for that
+ username then the connection is allowed.
+
+ 3. The client's NetBIOS name and any previously used user
+ names are checked against the supplied password, if
+ they match then the connection is allowed as the
+ corresponding user.
+
+ 4. If the client has previously validated a
+ username/password pair with the server and the client
+ has passed the validation token then that username is
+ used.
+
+ 5. If a "user = " field is given in the _s_m_b._c_o_n_f file for
+ the service and the client has supplied a password, and
+ that password matches (according to the UNIX system's
+ password checking) with one of the usernames from the
+ "user =" field then the connection is made as the
+ username in the "user =" line. If one of the username
+ in the "user =" list begins with a '@' then that name
+ expands to a list of names in the group of the same
+ name.
+
+ 6. If the service is a guest service then a connection is
+ made as the username given in the "guest account =" for
+ the service, irrespective of the supplied password.
+
+ CCCCOOOOMMMMPPPPLLLLEEEETTTTEEEE LLLLIIIISSSSTTTT OOOOFFFF GGGGLLLLOOOOBBBBAAAALLLL PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRRSSSS
+ Here is a list of all global parameters. See the section of
+ each parameter for details. Note that some are synonyms.
+
+ o+ _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d
+
+ o+ _a_d_d _s_h_a_r_e _c_o_m_m_a_n_d
+
+ o+ _a_d_d _u_s_e_r _s_c_r_i_p_t
+
+ o+ _a_l_l_o_w _t_r_u_s_t_e_d _d_o_m_a_i_n_s
+
+ o+ _a_n_n_o_u_n_c_e _a_s
+
+ o+ _a_n_n_o_u_n_c_e _v_e_r_s_i_o_n
+
+
+
+
+ Page 9 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _a_u_t_o _s_e_r_v_i_c_e_s
+
+ o+ _b_i_n_d _i_n_t_e_r_f_a_c_e_s _o_n_l_y
+
+ o+ _b_r_o_w_s_e _l_i_s_t
+
+ o+ _c_h_a_n_g_e _n_o_t_i_f_y _t_i_m_e_o_u_t
+
+ o+ _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d
+
+ o+ _c_h_a_r_a_c_t_e_r _s_e_t
+
+ o+ _c_l_i_e_n_t _c_o_d_e _p_a_g_e
+
+ o+ _c_o_d_e _p_a_g_e _d_i_r_e_c_t_o_r_y
+
+ o+ _c_o_d_i_n_g _s_y_s_t_e_m
+
+ o+ _c_o_n_f_i_g _f_i_l_e
+
+ o+ _d_e_a_d_t_i_m_e
+
+ o+ _d_e_b_u_g _h_i_r_e_s _t_i_m_e_s_t_a_m_p
+
+ o+ _d_e_b_u_g _p_i_d
+
+ o+ _d_e_b_u_g _t_i_m_e_s_t_a_m_p
+
+ o+ _d_e_b_u_g _u_i_d
+
+ o+ _d_e_b_u_g_l_e_v_e_l
+
+ o+ _d_e_f_a_u_l_t
+
+ o+ _d_e_f_a_u_l_t _s_e_r_v_i_c_e
+
+ o+ _d_e_l_e_t_e _p_r_i_n_t_e_r _c_o_m_m_a_n_d
+
+ o+ _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d
+
+ o+ _d_e_l_e_t_e _u_s_e_r _s_c_r_i_p_t
+
+ o+ _d_f_r_e_e _c_o_m_m_a_n_d
+
+ o+ _d_i_s_a_b_l_e _s_p_o_o_l_s_s
+
+ o+ _d_n_s _p_r_o_x_y
+
+ o+ _d_o_m_a_i_n _a_d_m_i_n _g_r_o_u_p
+
+ o+ _d_o_m_a_i_n _g_u_e_s_t _g_r_o_u_p
+
+
+
+
+ Page 10 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _d_o_m_a_i_n _l_o_g_o_n_s
+
+ o+ _d_o_m_a_i_n _m_a_s_t_e_r
+
+ o+ _e_n_c_r_y_p_t _p_a_s_s_w_o_r_d_s
+
+ o+ _e_n_h_a_n_c_e_d _b_r_o_w_s_i_n_g
+
+ o+ _e_n_u_m_p_o_r_t_s _c_o_m_m_a_n_d
+
+ o+ _g_e_t_w_d _c_a_c_h_e
+
+ o+ _h_i_d_e _l_o_c_a_l _u_s_e_r_s
+
+ o+ _h_i_d_e _u_n_r_e_a_d_a_b_l_e
+
+ o+ _h_o_m_e_d_i_r _m_a_p
+
+ o+ _h_o_s_t _m_s_d_f_s
+
+ o+ _h_o_s_t_s _e_q_u_i_v
+
+ o+ _i_n_t_e_r_f_a_c_e_s
+
+ o+ _k_e_e_p_a_l_i_v_e
+
+ o+ _k_e_r_n_e_l _o_p_l_o_c_k_s
+
+ o+ _l_a_n_m_a_n _a_u_t_h
+
+ o+ _l_a_r_g_e _r_e_a_d_w_r_i_t_e
+
+ o+ _l_d_a_p _a_d_m_i_n _d_n
+
+ o+ _l_d_a_p _f_i_l_t_e_r
+
+ o+ _l_d_a_p _p_o_r_t
+
+ o+ _l_d_a_p _s_e_r_v_e_r
+
+ o+ _l_d_a_p _s_s_l
+
+ o+ _l_d_a_p _s_u_f_f_i_x
+
+ o+ _l_m _a_n_n_o_u_n_c_e
+
+ o+ _l_m _i_n_t_e_r_v_a_l
+
+ o+ _l_o_a_d _p_r_i_n_t_e_r_s
+
+ o+ _l_o_c_a_l _m_a_s_t_e_r
+
+
+
+
+ Page 11 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _l_o_c_k _d_i_r
+
+ o+ _l_o_c_k _d_i_r_e_c_t_o_r_y
+
+ o+ _l_o_c_k _s_p_i_n _c_o_u_n_t
+
+ o+ _l_o_c_k _s_p_i_n _t_i_m_e
+
+ o+ _p_i_d _d_i_r_e_c_t_o_r_y
+
+ o+ _l_o_g _f_i_l_e
+
+ o+ _l_o_g _l_e_v_e_l
+
+ o+ _l_o_g_o_n _d_r_i_v_e
+
+ o+ _l_o_g_o_n _h_o_m_e
+
+ o+ _l_o_g_o_n _p_a_t_h
+
+ o+ _l_o_g_o_n _s_c_r_i_p_t
+
+ o+ _l_p_q _c_a_c_h_e _t_i_m_e
+
+ o+ _m_a_c_h_i_n_e _p_a_s_s_w_o_r_d _t_i_m_e_o_u_t
+
+ o+ _m_a_n_g_l_e_d _s_t_a_c_k
+
+ o+ _m_a_n_g_l_i_n_g _m_e_t_h_o_d
+
+ o+ _m_a_p _t_o _g_u_e_s_t
+
+ o+ _m_a_x _d_i_s_k _s_i_z_e
+
+ o+ _m_a_x _l_o_g _s_i_z_e
+
+ o+ _m_a_x _m_u_x
+
+ o+ _m_a_x _o_p_e_n _f_i_l_e_s
+
+ o+ _m_a_x _p_r_o_t_o_c_o_l
+
+ o+ _m_a_x _s_m_b_d _p_r_o_c_e_s_s_e_s
+
+ o+ _m_a_x _t_t_l
+
+ o+ _m_a_x _w_i_n_s _t_t_l
+
+ o+ _m_a_x _x_m_i_t
+
+ o+ _m_e_s_s_a_g_e _c_o_m_m_a_n_d
+
+
+
+
+ Page 12 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _m_i_n _p_a_s_s_w_d _l_e_n_g_t_h
+
+ o+ _m_i_n _p_a_s_s_w_o_r_d _l_e_n_g_t_h
+
+ o+ _m_i_n _p_r_o_t_o_c_o_l
+
+ o+ _m_i_n _w_i_n_s _t_t_l
+
+ o+ _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r
+
+ o+ _n_e_t_b_i_o_s _a_l_i_a_s_e_s
+
+ o+ _n_e_t_b_i_o_s _n_a_m_e
+
+ o+ _n_e_t_b_i_o_s _s_c_o_p_e
+
+ o+ _n_i_s _h_o_m_e_d_i_r
+
+ o+ _n_t _p_i_p_e _s_u_p_p_o_r_t
+
+ o+ _n_t _s_m_b _s_u_p_p_o_r_t
+
+ o+ _n_t _s_t_a_t_u_s _s_u_p_p_o_r_t
+
+ o+ _n_u_l_l _p_a_s_s_w_o_r_d_s
+
+ o+ _o_b_e_y _p_a_m _r_e_s_t_r_i_c_t_i_o_n_s
+
+ o+ _o_p_l_o_c_k _b_r_e_a_k _w_a_i_t _t_i_m_e
+
+ o+ _o_s _l_e_v_e_l
+
+ o+ _o_s_2 _d_r_i_v_e_r _m_a_p
+
+ o+ _p_a_m _p_a_s_s_w_o_r_d _c_h_a_n_g_e
+
+ o+ _p_a_n_i_c _a_c_t_i_o_n
+
+ o+ _p_a_s_s_w_d _c_h_a_t
+
+ o+ _p_a_s_s_w_d _c_h_a_t _d_e_b_u_g
+
+ o+ _p_a_s_s_w_d _p_r_o_g_r_a_m
+
+ o+ _p_a_s_s_w_o_r_d _l_e_v_e_l
+
+ o+ _p_a_s_s_w_o_r_d _s_e_r_v_e_r
+
+ o+ _p_r_e_f_e_r_e_d _m_a_s_t_e_r
+
+ o+ _p_r_e_f_e_r_r_e_d _m_a_s_t_e_r
+
+
+
+
+ Page 13 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _p_r_e_l_o_a_d
+
+ o+ _p_r_i_n_t_c_a_p
+
+ o+ _p_r_i_n_t_c_a_p _n_a_m_e
+
+ o+ _p_r_i_n_t_e_r _d_r_i_v_e_r _f_i_l_e
+
+ o+ _p_r_o_t_o_c_o_l
+
+ o+ _r_e_a_d _b_m_p_x
+
+ o+ _r_e_a_d _r_a_w
+
+ o+ _r_e_a_d _s_i_z_e
+
+ o+ _r_e_m_o_t_e _a_n_n_o_u_n_c_e
+
+ o+ _r_e_m_o_t_e _b_r_o_w_s_e _s_y_n_c
+
+ o+ _r_e_s_t_r_i_c_t _a_n_o_n_y_m_o_u_s
+
+ o+ _r_o_o_t
+
+ o+ _r_o_o_t _d_i_r
+
+ o+ _r_o_o_t _d_i_r_e_c_t_o_r_y
+
+ o+ _s_e_c_u_r_i_t_y
+
+ o+ _s_e_r_v_e_r _s_t_r_i_n_g
+
+ o+ _s_h_o_w _a_d_d _p_r_i_n_t_e_r _w_i_z_a_r_d
+
+ o+ _s_m_b _p_a_s_s_w_d _f_i_l_e
+
+ o+ _s_o_c_k_e_t _a_d_d_r_e_s_s
+
+ o+ _s_o_c_k_e_t _o_p_t_i_o_n_s
+
+ o+ _s_o_u_r_c_e _e_n_v_i_r_o_n_m_e_n_t
+
+ o+ _s_s_l
+
+ o+ _s_s_l _C_A _c_e_r_t_D_i_r
+
+ o+ _s_s_l _C_A _c_e_r_t_F_i_l_e
+
+ o+ _s_s_l _c_i_p_h_e_r_s
+
+ o+ _s_s_l _c_l_i_e_n_t _c_e_r_t
+
+
+
+
+ Page 14 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _s_s_l _c_l_i_e_n_t _k_e_y
+
+ o+ _s_s_l _c_o_m_p_a_t_i_b_i_l_i_t_y
+
+ o+ _s_s_l _e_g_d _s_o_c_k_e_t
+
+ o+ _s_s_l _e_n_t_r_o_p_y _b_y_t_e_s
+
+ o+ _s_s_l _e_n_t_r_o_p_y _f_i_l_e
+
+ o+ _s_s_l _h_o_s_t_s
+
+ o+ _s_s_l _h_o_s_t_s _r_e_s_i_g_n
+
+ o+ _s_s_l _r_e_q_u_i_r_e _c_l_i_e_n_t_c_e_r_t
+
+ o+ _s_s_l _r_e_q_u_i_r_e _s_e_r_v_e_r_c_e_r_t
+
+ o+ _s_s_l _s_e_r_v_e_r _c_e_r_t
+
+ o+ _s_s_l _s_e_r_v_e_r _k_e_y
+
+ o+ _s_s_l _v_e_r_s_i_o_n
+
+ o+ _s_t_a_t _c_a_c_h_e
+
+ o+ _s_t_a_t _c_a_c_h_e _s_i_z_e
+
+ o+ _s_t_r_i_p _d_o_t
+
+ o+ _s_y_s_l_o_g
+
+ o+ _s_y_s_l_o_g _o_n_l_y
+
+ o+ _t_e_m_p_l_a_t_e _h_o_m_e_d_i_r
+
+ o+ _t_e_m_p_l_a_t_e _s_h_e_l_l
+
+ o+ _t_i_m_e _o_f_f_s_e_t
+
+ o+ _t_i_m_e _s_e_r_v_e_r
+
+ o+ _t_i_m_e_s_t_a_m_p _l_o_g_s
+
+ o+ _t_o_t_a_l _p_r_i_n_t _j_o_b_s
+
+ o+ _u_n_i_x _e_x_t_e_n_s_i_o_n_s
+
+ o+ _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c
+
+ o+ _u_p_d_a_t_e _e_n_c_r_y_p_t_e_d
+
+
+
+
+ Page 15 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _u_s_e _m_m_a_p
+
+ o+ _u_s_e _r_h_o_s_t_s
+
+ o+ _u_s_e_r_n_a_m_e _l_e_v_e_l
+
+ o+ _u_s_e_r_n_a_m_e _m_a_p
+
+ o+ _u_t_m_p
+
+ o+ _u_t_m_p _d_i_r_e_c_t_o_r_y
+
+ o+ _v_a_l_i_d _c_h_a_r_s
+
+ o+ _w_i_n_b_i_n_d _c_a_c_h_e _t_i_m_e
+
+ o+ _w_i_n_b_i_n_d _e_n_u_m _u_s_e_r_s
+
+ o+ _w_i_n_b_i_n_d _e_n_u_m _g_r_o_u_p_s
+
+ o+ _w_i_n_b_i_n_d _g_i_d
+
+ o+ _w_i_n_b_i_n_d _s_e_p_a_r_a_t_o_r
+
+ o+ _w_i_n_b_i_n_d _u_i_d
+
+ o+ _w_i_n_b_i_n_d _u_s_e _d_e_f_a_u_l_t _d_o_m_a_i_n
+
+ o+ _w_i_n_s _h_o_o_k
+
+ o+ _w_i_n_s _p_r_o_x_y
+
+ o+ _w_i_n_s _s_e_r_v_e_r
+
+ o+ _w_i_n_s _s_u_p_p_o_r_t
+
+ o+ _w_o_r_k_g_r_o_u_p
+
+ o+ _w_r_i_t_e _r_a_w
+
+ CCCCOOOOMMMMPPPPLLLLEEEETTTTEEEE LLLLIIIISSSSTTTT OOOOFFFF SSSSEEEERRRRVVVVIIIICCCCEEEE PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRRSSSS
+ Here is a list of all service parameters. See the section on
+ each parameter for details. Note that some are synonyms.
+
+ o+ _a_d_m_i_n _u_s_e_r_s
+
+ o+ _a_l_l_o_w _h_o_s_t_s
+
+ o+ _a_v_a_i_l_a_b_l_e
+
+ o+ _b_l_o_c_k_i_n_g _l_o_c_k_s
+
+
+
+
+ Page 16 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _b_l_o_c_k _s_i_z_e
+
+ o+ _b_r_o_w_s_a_b_l_e
+
+ o+ _b_r_o_w_s_e_a_b_l_e
+
+ o+ _c_a_s_e _s_e_n_s_i_t_i_v_e
+
+ o+ _c_a_s_e_s_i_g_n_a_m_e_s
+
+ o+ _c_o_m_m_e_n_t
+
+ o+ _c_o_p_y
+
+ o+ _c_r_e_a_t_e _m_a_s_k
+
+ o+ _c_r_e_a_t_e _m_o_d_e
+
+ o+ _c_s_c _p_o_l_i_c_y
+
+ o+ _d_e_f_a_u_l_t _c_a_s_e
+
+ o+ _d_e_f_a_u_l_t _d_e_v_m_o_d_e
+
+ o+ _d_e_l_e_t_e _r_e_a_d_o_n_l_y
+
+ o+ _d_e_l_e_t_e _v_e_t_o _f_i_l_e_s
+
+ o+ _d_e_n_y _h_o_s_t_s
+
+ o+ _d_i_r_e_c_t_o_r_y
+
+ o+ _d_i_r_e_c_t_o_r_y _m_a_s_k
+
+ o+ _d_i_r_e_c_t_o_r_y _m_o_d_e
+
+ o+ _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_a_s_k
+
+ o+ _d_o_n_t _d_e_s_c_e_n_d
+
+ o+ _d_o_s _f_i_l_e_m_o_d_e
+
+ o+ _d_o_s _f_i_l_e_t_i_m_e _r_e_s_o_l_u_t_i_o_n
+
+ o+ _d_o_s _f_i_l_e_t_i_m_e_s
+
+ o+ _e_x_e_c
+
+ o+ _f_a_k_e _d_i_r_e_c_t_o_r_y _c_r_e_a_t_e _t_i_m_e_s
+
+ o+ _f_a_k_e _o_p_l_o_c_k_s
+
+
+
+
+ Page 17 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _f_o_l_l_o_w _s_y_m_l_i_n_k_s
+
+ o+ _f_o_r_c_e _c_r_e_a_t_e _m_o_d_e
+
+ o+ _f_o_r_c_e _d_i_r_e_c_t_o_r_y _m_o_d_e
+
+ o+ _f_o_r_c_e _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_o_d_e
+
+ o+ _f_o_r_c_e _g_r_o_u_p
+
+ o+ _f_o_r_c_e _s_e_c_u_r_i_t_y _m_o_d_e
+
+ o+ _f_o_r_c_e _u_n_k_n_o_w_n _a_c_l _u_s_e_r
+
+ o+ _f_o_r_c_e _u_s_e_r
+
+ o+ _f_s_t_y_p_e
+
+ o+ _g_r_o_u_p
+
+ o+ _g_u_e_s_t _a_c_c_o_u_n_t
+
+ o+ _g_u_e_s_t _o_k
+
+ o+ _g_u_e_s_t _o_n_l_y
+
+ o+ _h_i_d_e _d_o_t _f_i_l_e_s
+
+ o+ _h_i_d_e _f_i_l_e_s
+
+ o+ _h_o_s_t_s _a_l_l_o_w
+
+ o+ _h_o_s_t_s _d_e_n_y
+
+ o+ _i_n_c_l_u_d_e
+
+ o+ _i_n_h_e_r_i_t _a_c_l_s
+
+ o+ _i_n_h_e_r_i_t _p_e_r_m_i_s_s_i_o_n_s
+
+ o+ _i_n_v_a_l_i_d _u_s_e_r_s
+
+ o+ _l_e_v_e_l_2 _o_p_l_o_c_k_s
+
+ o+ _l_o_c_k_i_n_g
+
+ o+ _l_p_p_a_u_s_e _c_o_m_m_a_n_d
+
+ o+ _l_p_q _c_o_m_m_a_n_d
+
+ o+ _l_p_r_e_s_u_m_e _c_o_m_m_a_n_d
+
+
+
+
+ Page 18 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _l_p_r_m _c_o_m_m_a_n_d
+
+ o+ _m_a_g_i_c _o_u_t_p_u_t
+
+ o+ _m_a_g_i_c _s_c_r_i_p_t
+
+ o+ _m_a_n_g_l_e _c_a_s_e
+
+ o+ _m_a_n_g_l_e_d _m_a_p
+
+ o+ _m_a_n_g_l_e_d _n_a_m_e_s
+
+ o+ _m_a_n_g_l_i_n_g _c_h_a_r
+
+ o+ _m_a_p _a_r_c_h_i_v_e
+
+ o+ _m_a_p _h_i_d_d_e_n
+
+ o+ _m_a_p _s_y_s_t_e_m
+
+ o+ _m_a_x _c_o_n_n_e_c_t_i_o_n_s
+
+ o+ _m_a_x _p_r_i_n_t _j_o_b_s
+
+ o+ _m_i_n _p_r_i_n_t _s_p_a_c_e
+
+ o+ _m_s_d_f_s _r_o_o_t
+
+ o+ _n_t _a_c_l _s_u_p_p_o_r_t
+
+ o+ _o_n_l_y _g_u_e_s_t
+
+ o+ _o_n_l_y _u_s_e_r
+
+ o+ _o_p_l_o_c_k _c_o_n_t_e_n_t_i_o_n _l_i_m_i_t
+
+ o+ _o_p_l_o_c_k_s
+
+ o+ _p_a_t_h
+
+ o+ _p_o_s_i_x _l_o_c_k_i_n_g
+
+ o+ _p_o_s_t_e_x_e_c
+
+ o+ _p_o_s_t_s_c_r_i_p_t
+
+ o+ _p_r_e_e_x_e_c
+
+ o+ _p_r_e_e_x_e_c _c_l_o_s_e
+
+ o+ _p_r_e_s_e_r_v_e _c_a_s_e
+
+
+
+
+ Page 19 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _p_r_i_n_t _c_o_m_m_a_n_d
+
+ o+ _p_r_i_n_t _o_k
+
+ o+ _p_r_i_n_t_a_b_l_e
+
+ o+ _p_r_i_n_t_e_r
+
+ o+ _p_r_i_n_t_e_r _a_d_m_i_n
+
+ o+ _p_r_i_n_t_e_r _d_r_i_v_e_r
+
+ o+ _p_r_i_n_t_e_r _d_r_i_v_e_r _l_o_c_a_t_i_o_n
+
+ o+ _p_r_i_n_t_e_r _n_a_m_e
+
+ o+ _p_r_i_n_t_i_n_g
+
+ o+ _p_r_o_f_i_l_e _a_c_l_s
+
+ o+ _p_u_b_l_i_c
+
+ o+ _q_u_e_u_e_p_a_u_s_e _c_o_m_m_a_n_d
+
+ o+ _q_u_e_u_e_r_e_s_u_m_e _c_o_m_m_a_n_d
+
+ o+ _r_e_a_d _l_i_s_t
+
+ o+ _r_e_a_d _o_n_l_y
+
+ o+ _r_o_o_t _p_o_s_t_e_x_e_c
+
+ o+ _r_o_o_t _p_r_e_e_x_e_c
+
+ o+ _r_o_o_t _p_r_e_e_x_e_c _c_l_o_s_e
+
+ o+ _s_e_c_u_r_i_t_y _m_a_s_k
+
+ o+ _s_e_t _d_i_r_e_c_t_o_r_y
+
+ o+ _s_h_a_r_e _m_o_d_e_s
+
+ o+ _s_h_o_r_t _p_r_e_s_e_r_v_e _c_a_s_e
+
+ o+ _s_t_a_t_u_s
+
+ o+ _s_t_r_i_c_t _a_l_l_o_c_a_t_e
+
+ o+ _s_t_r_i_c_t _l_o_c_k_i_n_g
+
+ o+ _s_t_r_i_c_t _s_y_n_c
+
+
+
+
+ Page 20 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _s_y_n_c _a_l_w_a_y_s
+
+ o+ _u_s_e _c_l_i_e_n_t _d_r_i_v_e_r
+
+ o+ _u_s_e _s_e_n_d_f_i_l_e
+
+ o+ _u_s_e_r
+
+ o+ _u_s_e_r_n_a_m_e
+
+ o+ _u_s_e_r_s
+
+ o+ _v_a_l_i_d _u_s_e_r_s
+
+ o+ _v_e_t_o _f_i_l_e_s
+
+ o+ _v_e_t_o _o_p_l_o_c_k _f_i_l_e_s
+
+ o+ _v_f_s _o_b_j_e_c_t
+
+ o+ _v_f_s _o_p_t_i_o_n_s
+
+ o+ _v_o_l_u_m_e
+
+ o+ _w_i_d_e _l_i_n_k_s
+
+ o+ _w_r_i_t_a_b_l_e
+
+ o+ _w_r_i_t_e _c_a_c_h_e _s_i_z_e
+
+ o+ _w_r_i_t_e _l_i_s_t
+
+ o+ _w_r_i_t_e _o_k
+
+ o+ _w_r_i_t_e_a_b_l_e
+
+ EEEEXXXXPPPPLLLLAAAANNNNAAAATTTTIIIIOOOONNNN OOOOFFFF EEEEAAAACCCCHHHH PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRR
+ aaaadddddddd pppprrrriiiinnnntttteeeerrrr ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ With the introduction of MS-RPC based printing support
+ for Windows NT/2000 clients in Samba 2.2, The MS Add
+ Printer Wizard (APW) icon is now also available in the
+ "Printers..." folder displayed a share listing. The APW
+ allows for printers to be add remotely to a Samba or
+ Windows NT/2000 print server.
+
+ For a Samba host this means that the printer must be
+ physically added to the underlying printing system. The
+ _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d defines a script to be run which
+ will perform the necessary operations for adding the
+ printer to the print system and to add the appropriate
+ service definition to the _s_m_b._c_o_n_f file in order that
+ it can be shared by ssssmmmmbbbbdddd((((8888))))
+
+
+
+ Page 21 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d is automatically invoked with
+ the following parameter (in order:
+
+ o+ _p_r_i_n_t_e_r _n_a_m_e
+
+ o+ _s_h_a_r_e _n_a_m_e
+
+ o+ _p_o_r_t _n_a_m_e
+
+ o+ _d_r_i_v_e_r _n_a_m_e
+
+ o+ _l_o_c_a_t_i_o_n
+
+ o+ _W_i_n_d_o_w_s _9_x _d_r_i_v_e_r _l_o_c_a_t_i_o_n
+
+ All parameters are filled in from the PRINTER_INFO_2
+ structure sent by the Windows NT/2000 client with one
+ exception. The "Windows 9x driver location" parameter is
+ included for backwards compatibility only. The remaining
+ fields in the structure are generated from answers to the
+ APW questions.
+
+ Once the _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d has been executed, ssssmmmmbbbbdddd will
+ reparse the _s_m_b._c_o_n_f to determine if the share defined by
+ the APW exists. If the sharename is still invalid, then ssssmmmmbbbbdddd
+ will return an ACCESS_DENIED error to the client.
+
+ See also _d_e_l_e_t_e _p_r_i_n_t_e_r _c_o_m_m_a_n_d, _p_r_i_n_t_i_n_g, _s_h_o_w _a_d_d _p_r_i_n_t_e_r
+ _w_i_z_a_r_d
+
+ Default: nnnnoooonnnneeee
+
+ Example: aaaaddddddddpppprrrriiiinnnntttteeeerrrr ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////aaaaddddddddpppprrrriiiinnnntttteeeerrrr
+
+ aaaadddddddd sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ Samba 2.2.0 introduced the ability to dynamically add
+ and delete shares via the Windows NT 4.0 Server
+ Manager. The _a_d_d _s_h_a_r_e _c_o_m_m_a_n_d is used to define an
+ external program or script which will add a new service
+ definition to _s_m_b._c_o_n_f. In order to successfully
+ execute the _a_d_d _s_h_a_r_e _c_o_m_m_a_n_d, ssssmmmmbbbbdddd requires that the
+ administrator be connected using a root account (i.e.
+ uid == 0).
+
+ When executed, ssssmmmmbbbbdddd will automatically invoke the _a_d_d
+ _s_h_a_r_e _c_o_m_m_a_n_d with four parameters.
+
+ o+ _c_o_n_f_i_g_F_i_l_e - the location of the global _s_m_b._c_o_n_f
+ file.
+
+ o+ _s_h_a_r_e_N_a_m_e - the name of the new share.
+
+
+
+
+ Page 22 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ _p_a_t_h_N_a_m_e - path to an **existing** directory on disk.
+
+ o+ _c_o_m_m_e_n_t - comment string to associate with the new
+ share.
+
+ This parameter is only used for add file shares. To add
+ printer shares, see the _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d.
+
+ See also _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d, _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d.
+
+ Default: nnnnoooonnnneeee
+
+ Example: aaaadddddddd sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////llllooooccccaaaallll////bbbbiiiinnnn////aaaaddddddddsssshhhhaaaarrrreeee
+
+ aaaadddddddd uuuusssseeeerrrr ssssccccrrrriiiipppptttt ((((GGGG))))
+ This is the full pathname to a script that will be run
+ AAAASSSS RRRROOOOOOOOTTTT by smbd(8)
+ under special circumstances described below.
+
+ Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server.
+ For sites that use Windows NT account databases as
+ their primary user database creating these users and
+ keeping the user list in sync with the Windows NT PDC
+ is an onerous task. This option allows smbd to create
+ the required UNIX users OOOONNNN DDDDEEEEMMMMAAAANNNNDDDD when a user accesses
+ the Samba server.
+
+ In order to use this option, smbd must NNNNOOOOTTTT be set to
+ _s_e_c_u_r_i_t_y = _s_h_a_r_e and _a_d_d _u_s_e_r _s_c_r_i_p_t must be set to a
+ full pathname for a script that will create a UNIX user
+ given one argument of %_u, which expands into the UNIX
+ user name to create.
+
+ When the Windows user attempts to access the Samba
+ server, at login (session setup in the SMB protocol)
+ time, smbd contacts the _p_a_s_s_w_o_r_d _s_e_r_v_e_r and attempts
+ to authenticate the given user with the given password.
+ If the authentication succeeds then ssssmmmmbbbbdddd attempts to
+ find a UNIX user in the UNIX password database to map
+ the Windows user into. If this lookup fails, and _a_d_d
+ _u_s_e_r _s_c_r_i_p_t is set then ssssmmmmbbbbdddd will call the specified
+ script AAAASSSS RRRROOOOOOOOTTTT, expanding any %_u argument to be the
+ user name to create.
+
+ If this script successfully creates the user then ssssmmmmbbbbdddd
+ will continue on as though the UNIX user already
+ existed. In this way, UNIX users are dynamically
+ created to match existing Windows NT accounts.
+
+ See also _s_e_c_u_r_i_t_y, _p_a_s_s_w_o_r_d _s_e_r_v_e_r, _d_e_l_e_t_e _u_s_e_r
+ _s_c_r_i_p_t.
+
+
+
+ Page 23 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: aaaadddddddd uuuusssseeeerrrr ssssccccrrrriiiipppptttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: aaaadddddddd uuuusssseeeerrrr ssssccccrrrriiiipppptttt ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////aaaadddddddd____uuuusssseeeerrrr %%%%uuuu
+
+ aaaaddddmmmmiiiinnnn uuuusssseeeerrrrssss ((((SSSS))))
+ This is a list of users who will be granted
+ administrative privileges on the share. This means that
+ they will do all file operations as the super-user
+ (root).
+
+ You should use this option very carefully, as any user
+ in this list will be able to do anything they like on
+ the share, irrespective of file permissions.
+
+ Default: nnnnoooo aaaaddddmmmmiiiinnnn uuuusssseeeerrrrssss
+
+ Example: aaaaddddmmmmiiiinnnn uuuusssseeeerrrrssss ==== jjjjaaaassssoooonnnn
+
+ aaaalllllllloooowwww hhhhoooossssttttssss ((((SSSS))))
+ Synonym for _h_o_s_t_s _a_l_l_o_w.
+
+ aaaalllllllloooowwww ttttrrrruuuusssstttteeeedddd ddddoooommmmaaaaiiiinnnnssss ((((GGGG))))
+ This option only takes effect when the _s_e_c_u_r_i_t_y option
+ is set to server or domain. If it is set to no, then
+ attempts to connect to a resource from a domain or
+ workgroup other than the one which smbd is running in
+ will fail, even if that domain is trusted by the remote
+ server doing the authentication.
+
+ This is useful if you only want your Samba server to
+ serve resources to users in the domain it is a member
+ of. As an example, suppose that there are two domains
+ DOMA and DOMB. DOMB is trusted by DOMA, which contains
+ the Samba server. Under normal circumstances, a user
+ with an account in DOMB can then access the resources
+ of a UNIX account with the same account name on the
+ Samba server even if they do not have an account in
+ DOMA. This can make implementing a security boundary
+ difficult.
+
+ Default: aaaalllllllloooowwww ttttrrrruuuusssstttteeeedddd ddddoooommmmaaaaiiiinnnnssss ==== yyyyeeeessss
+
+ aaaannnnnnnnoooouuuunnnncccceeee aaaassss ((((GGGG))))
+ This specifies what type of server nnnnmmmmbbbbdddd will announce
+ itself as, to a network neighborhood browse list. By
+ default this is set to Windows NT. The valid options
+ are : "NT Server" (which can also be written as "NT"),
+ "NT Workstation", "Win95" or "WfW" meaning Windows NT
+ Server, Windows NT Workstation, Windows 95 and Windows
+ for Workgroups respectively. Do not change this
+ parameter unless you have a specific need to stop Samba
+
+
+
+ Page 24 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ appearing as an NT server as this may prevent Samba
+ servers from participating as browser servers
+ correctly.
+
+ Default: aaaannnnnnnnoooouuuunnnncccceeee aaaassss ==== NNNNTTTT SSSSeeeerrrrvvvveeeerrrr
+
+ Example: aaaannnnnnnnoooouuuunnnncccceeee aaaassss ==== WWWWiiiinnnn99995555
+
+ aaaannnnnnnnoooouuuunnnncccceeee vvvveeeerrrrssssiiiioooonnnn ((((GGGG))))
+ This specifies the major and minor version numbers that
+ nmbd will use when announcing itself as a server. The
+ default is 4.5. Do not change this parameter unless you
+ have a specific need to set a Samba server to be a
+ downlevel server.
+
+ Default: aaaannnnnnnnoooouuuunnnncccceeee vvvveeeerrrrssssiiiioooonnnn ==== 4444....5555
+
+ Example: aaaannnnnnnnoooouuuunnnncccceeee vvvveeeerrrrssssiiiioooonnnn ==== 2222....0000
+
+ aaaauuuuttttoooo sssseeeerrrrvvvviiiicccceeeessss ((((GGGG))))
+ This is a synonym for the _p_r_e_l_o_a_d.
+
+ aaaavvvvaaaaiiiillllaaaabbbblllleeee ((((SSSS))))
+ This parameter lets you "turn off" a service. If
+ _a_v_a_i_l_a_b_l_e = _n_o, then AAAALLLLLLLL attempts to connect to the
+ service will fail. Such failures are logged.
+
+ Default: aaaavvvvaaaaiiiillllaaaabbbblllleeee ==== yyyyeeeessss
+
+ bbbbiiiinnnndddd iiiinnnntttteeeerrrrffffaaaacccceeeessss oooonnnnllllyyyy ((((GGGG))))
+ This global parameter allows the Samba admin to limit
+ what interfaces on a machine will serve SMB requests.
+ If affects file service smbd(8) and name service
+ nmbd(8) in slightly different ways.
+
+ For name service it causes nnnnmmmmbbbbdddd to bind to ports 137
+ and 138 on the interfaces listed in the interfaces
+ parameter. nnnnmmmmbbbbdddd also binds to the "all addresses"
+ interface (0.0.0.0) on ports 137 and 138 for the
+ purposes of reading broadcast messages. If this option
+ is not set then nnnnmmmmbbbbdddd will service name requests on all
+ of these sockets. If _b_i_n_d _i_n_t_e_r_f_a_c_e_s _o_n_l_y is set then
+ nnnnmmmmbbbbdddd will check the source address of any packets
+ coming in on the broadcast sockets and discard any that
+ don't match the broadcast addresses of the interfaces
+ in the _i_n_t_e_r_f_a_c_e_s parameter list. As unicast packets
+ are received on the other sockets it allows nnnnmmmmbbbbdddd to
+ refuse to serve names to machines that send packets
+ that arrive through any interfaces not listed in the
+ _i_n_t_e_r_f_a_c_e_s list. IP Source address spoofing does defeat
+ this simple check, however so it must not be used
+ seriously as a security feature for nnnnmmmmbbbbdddd.
+
+
+
+ Page 25 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ For file service it causes smbd(8) to bind only to the
+ interface list given in the interfaces parameter. This
+ restricts the networks that ssssmmmmbbbbdddd will serve to packets
+ coming in those interfaces. Note that you should not
+ use this parameter for machines that are serving PPP or
+ other intermittent or non-broadcast network interfaces
+ as it will not cope with non-permanent interfaces.
+
+ If _b_i_n_d _i_n_t_e_r_f_a_c_e_s _o_n_l_y is set then unless the network
+ address 111122227777....0000....0000....1111 is added to the _i_n_t_e_r_f_a_c_e_s parameter
+ list ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888)))) and sssswwwwaaaatttt((((8888)))) may not work as expected
+ due to the reasons covered below.
+
+ To change a users SMB password, the ssssmmmmbbbbppppaaaasssssssswwwwdddd by
+ default connects to the llllooooccccaaaallllhhhhoooosssstttt ---- 111122227777....0000....0000....1111 address
+ as an SMB client to issue the password change request.
+ If _b_i_n_d _i_n_t_e_r_f_a_c_e_s _o_n_l_y is set then unless the network
+ address 111122227777....0000....0000....1111 is added to the _i_n_t_e_r_f_a_c_e_s parameter
+ list then ssssmmmmbbbbppppaaaasssssssswwwwdddd will fail to connect in it's
+ default mode. ssssmmmmbbbbppppaaaasssssssswwwwdddd can be forced to use the
+ primary IP interface of the local host by using its -_r
+ _r_e_m_o_t_e _m_a_c_h_i_n_e
+ parameter, with _r_e_m_o_t_e _m_a_c_h_i_n_e set to the IP name of
+ the primary interface of the local host.
+
+ The sssswwwwaaaatttt status page tries to connect with ssssmmmmbbbbdddd and
+ nnnnmmmmbbbbdddd at the address 111122227777....0000....0000....1111 to determine if they are
+ running. Not adding 111122227777....0000....0000....1111 will cause ssssmmmmbbbbdddd and nnnnmmmmbbbbdddd
+ to always show "not running" even if they really are.
+ This can prevent sssswwwwaaaatttt from
+ starting/stopping/restarting ssssmmmmbbbbdddd and nnnnmmmmbbbbdddd.
+
+ Default: bbbbiiiinnnndddd iiiinnnntttteeeerrrrffffaaaacccceeeessss oooonnnnllllyyyy ==== nnnnoooo
+
+ bbbblllloooocccckkkk ssssiiiizzzzeeee ((((SSSS))))
+ This parameter controls the behavior of smbd(8) when
+ reporting disk free sizes. By default, this reports a
+ disk block size of 1024 bytes.
+
+ Changing this parameter may have some effect on the
+ efficiency of client writes, this is not yet confirmed.
+ This parameter was added to allow advanced
+ administrators to change it (usually to a higher value)
+ and test the effect it has on client write performance
+ without re-compiling the code. As this is an
+ experimental option it may be removed in a future
+ release.
+
+ Changing this option does not change the disk free
+ reporting size, just the block size unit reported to
+ the client.
+
+
+
+
+ Page 26 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: bbbblllloooocccckkkk ssssiiiizzzzeeee ==== 1111000022224444
+
+ Example: bbbblllloooocccckkkk ssssiiiizzzzeeee ==== 66665555555533336666
+
+ bbbblllloooocccckkkkiiiinnnngggg lllloooocccckkkkssss ((((SSSS))))
+ This parameter controls the behavior of smbd(8) when
+ given a request by a client to obtain a byte range lock
+ on a region of an open file, and the request has a time
+ limit associated with it.
+
+ If this parameter is set and the lock range requested
+ cannot be immediately satisfied, Samba 2.2 will
+ internally queue the lock request, and periodically
+ attempt to obtain the lock until the timeout period
+ expires.
+
+ If this parameter is set to no, then Samba 2.2 will
+ behave as previous versions of Samba would and will
+ fail the lock request immediately if the lock range
+ cannot be obtained.
+
+ Default: bbbblllloooocccckkkkiiiinnnngggg lllloooocccckkkkssss ==== yyyyeeeessss
+
+ bbbbrrrroooowwwwssssaaaabbbblllleeee ((((SSSS))))
+ See the _b_r_o_w_s_e_a_b_l_e.
+
+ bbbbrrrroooowwwwsssseeee lllliiiisssstttt ((((GGGG))))
+ This controls whether ssssmmmmbbbbdddd((((8888)))) will serve a browse list
+ to a client doing a NNNNeeeettttSSSSeeeerrrrvvvveeeerrrrEEEEnnnnuuuummmm call. Normally set to
+ yes. You should never need to change this.
+
+ Default: bbbbrrrroooowwwwsssseeee lllliiiisssstttt ==== yyyyeeeessss
+
+ bbbbrrrroooowwwwsssseeeeaaaabbbblllleeee ((((SSSS))))
+ This controls whether this share is seen in the list of
+ available shares in a net view and in the browse list.
+
+ Default: bbbbrrrroooowwwwsssseeeeaaaabbbblllleeee ==== yyyyeeeessss
+
+ ccccaaaasssseeee sssseeeennnnssssiiiittttiiiivvvveeee ((((SSSS))))
+ See the discussion in the section NAME MANGLING.
+
+ Default: ccccaaaasssseeee sssseeeennnnssssiiiittttiiiivvvveeee ==== nnnnoooo
+
+ ccccaaaasssseeeessssiiiiggggnnnnaaaammmmeeeessss ((((SSSS))))
+ Synonym for case sensitive.
+
+ cccchhhhaaaannnnggggeeee nnnnoooottttiiiiffffyyyy ttttiiiimmmmeeeeoooouuuutttt ((((GGGG))))
+ This SMB allows a client to tell a server to "watch" a
+ particular directory for any changes and only reply to
+ the SMB request when a change has occurred. Such
+ constant scanning of a directory is expensive under
+
+
+
+ Page 27 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ UNIX, hence an ssssmmmmbbbbdddd((((8888)))) daemon only performs such a
+ scan on each requested directory once every _c_h_a_n_g_e
+ _n_o_t_i_f_y _t_i_m_e_o_u_t seconds.
+
+ Default: cccchhhhaaaannnnggggeeee nnnnoooottttiiiiffffyyyy ttttiiiimmmmeeeeoooouuuutttt ==== 66660000
+
+ Example: cccchhhhaaaannnnggggeeee nnnnoooottttiiiiffffyyyy ttttiiiimmmmeeeeoooouuuutttt ==== 333300000000
+
+ Would change the scan time to every 5 minutes.
+
+ cccchhhhaaaannnnggggeeee sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ Samba 2.2.0 introduced the ability to dynamically add
+ and delete shares via the Windows NT 4.0 Server
+ Manager. The _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d is used to define an
+ external program or script which will modify an
+ existing service definition in _s_m_b._c_o_n_f. In order to
+ successfully execute the _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d, ssssmmmmbbbbdddd
+ requires that the administrator be connected using a
+ root account (i.e. uid == 0).
+
+ When executed, ssssmmmmbbbbdddd will automatically invoke the
+ _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d with four parameters.
+
+ o+ _c_o_n_f_i_g_F_i_l_e - the location of the global _s_m_b._c_o_n_f
+ file.
+
+ o+ _s_h_a_r_e_N_a_m_e - the name of the new share.
+
+ o+ _p_a_t_h_N_a_m_e - path to an **existing** directory on disk.
+
+ o+ _c_o_m_m_e_n_t - comment string to associate with the new
+ share.
+
+ This parameter is only used modify existing file shares
+ definitions. To modify printer shares, use the "Printers..."
+ folder as seen when browsing the Samba host.
+
+ See also _a_d_d _s_h_a_r_e _c_o_m_m_a_n_d, _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d.
+
+ Default: nnnnoooonnnneeee
+
+ Example: cccchhhhaaaannnnggggeeee sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////llllooooccccaaaallll////bbbbiiiinnnn////aaaaddddddddsssshhhhaaaarrrreeee
+
+ cccchhhhaaaarrrraaaacccctttteeeerrrr sssseeeetttt ((((GGGG))))
+ This allows smbd to map incoming filenames from a DOS
+ Code page (see the client code page parameter) to
+ several built in UNIX character sets. The built in code
+ page translations are:
+
+ o+ ISO8859-1 : Western European UNIX character set. The
+ parameter _c_l_i_e_n_t _c_o_d_e _p_a_g_e MMMMUUUUSSSSTTTT be set to code page
+ 850 if the _c_h_a_r_a_c_t_e_r _s_e_t parameter is set to
+
+
+
+ Page 28 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ ISO8859-1 in order for the conversion to the UNIX
+ character set to be done correctly.
+
+ o+ ISO8859-2 : Eastern European UNIX character set. The
+ parameter _c_l_i_e_n_t _c_o_d_e _p_a_g_e MMMMUUUUSSSSTTTT be set to code page
+ 852 if the _c_h_a_r_a_c_t_e_r _s_e_t parameter is set to
+ ISO8859-2 in order for the conversion to the UNIX
+ character set to be done correctly.
+
+ o+ ISO8859-5 : Russian Cyrillic UNIX character set. The
+ parameter _c_l_i_e_n_t _c_o_d_e _p_a_g_e MMMMUUUUSSSSTTTT be set to code page
+ 866 if the _c_h_a_r_a_c_t_e_r _s_e_t parameter is set to
+ ISO8859-5 in order for the conversion to the UNIX
+ character set to be done correctly.
+
+ o+ ISO8859-7 : Greek UNIX character set. The parameter
+ _c_l_i_e_n_t _c_o_d_e _p_a_g_e MMMMUUUUSSSSTTTT be set to code page 737 if the
+ _c_h_a_r_a_c_t_e_r _s_e_t parameter is set to ISO8859-7 in order
+ for the conversion to the UNIX character set to be
+ done correctly.
+
+ o+ KOI8-R : Alternate mapping for Russian Cyrillic UNIX
+ character set. The parameter _c_l_i_e_n_t _c_o_d_e _p_a_g_e MMMMUUUUSSSSTTTT be
+ set to code page 866 if the _c_h_a_r_a_c_t_e_r _s_e_t parameter
+ is set to KOI8-R in order for the conversion to the
+ UNIX character set to be done correctly.
+
+ BBBBUUUUGGGG. These MSDOS code page to UNIX character set mappings
+ should be dynamic, like the loading of MS DOS code pages,
+ not static.
+
+ Normally this parameter is not set, meaning no filename
+ translation is done.
+
+ Default: cccchhhhaaaarrrraaaacccctttteeeerrrr sssseeeetttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: cccchhhhaaaarrrraaaacccctttteeeerrrr sssseeeetttt ==== IIIISSSSOOOO8888888855559999----1111
+
+ cccclllliiiieeeennnntttt ccccooooddddeeee ppppaaaaggggeeee ((((GGGG))))
+ This parameter specifies the DOS code page that the
+ clients accessing Samba are using. To determine what
+ code page a Windows or DOS client is using, open a DOS
+ command prompt and type the command cccchhhhccccpppp. This will
+ output the code page. The default for USA MS-DOS,
+ Windows 95, and Windows NT releases is code page 437.
+ The default for western European releases of the above
+ operating systems is code page 850.
+
+ This parameter tells smbd(8) which of the _c_o_d_e_p_a_g_e._X_X_X
+ files to dynamically load on startup. These files,
+ described more fully in the manual page
+ mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee((((1111)))) tell ssssmmmmbbbbdddd how to map lower to
+
+
+
+ Page 29 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ upper case characters to provide the case insensitivity
+ of filenames that Windows clients expect.
+
+ Samba currently ships with the following code page
+ files :
+
+ o+ Code Page 437 - MS-DOS Latin US
+
+ o+ Code Page 737 - Windows '95 Greek
+
+ o+ Code Page 850 - MS-DOS Latin 1
+
+ o+ Code Page 852 - MS-DOS Latin 2
+
+ o+ Code Page 861 - MS-DOS Icelandic
+
+ o+ Code Page 866 - MS-DOS Cyrillic
+
+ o+ Code Page 932 - MS-DOS Japanese SJIS
+
+ o+ Code Page 936 - MS-DOS Simplified Chinese
+
+ o+ Code Page 949 - MS-DOS Korean Hangul
+
+ o+ Code Page 950 - MS-DOS Traditional Chinese
+
+ Thus this parameter may have any of the values 437, 737,
+ 850, 852, 861, 932, 936, 949, or 950. If you don't find the
+ codepage you need, read the comments in one of the other
+ codepage files and the mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee((((1111)))) man page and
+ write one. Please remember to donate it back to the Samba
+ user community.
+
+ This parameter co-operates with the _v_a_l_i_d _c_h_a_r_s parameter in
+ determining what characters are valid in filenames and how
+ capitalization is done. If you set both this parameter and
+ the _v_a_l_i_d _c_h_a_r_s parameter the _c_l_i_e_n_t _c_o_d_e _p_a_g_e parameter
+ MMMMUUUUSSSSTTTT be set before the _v_a_l_i_d _c_h_a_r_s parameter in the _s_m_b._c_o_n_f
+ file. The _v_a_l_i_d _c_h_a_r_s string will then augment the character
+ settings in the _c_l_i_e_n_t _c_o_d_e _p_a_g_e parameter.
+
+ If not set, _c_l_i_e_n_t _c_o_d_e _p_a_g_e defaults to 850.
+
+ See also : _v_a_l_i_d _c_h_a_r_s, _c_o_d_e _p_a_g_e _d_i_r_e_c_t_o_r_y
+
+ Default: cccclllliiiieeeennnntttt ccccooooddddeeee ppppaaaaggggeeee ==== 888855550000
+
+ Example: cccclllliiiieeeennnntttt ccccooooddddeeee ppppaaaaggggeeee ==== 999933336666
+
+ ccccooooddddeeee ppppaaaaggggeeee ddddiiiirrrreeeeccccttttoooorrrryyyy ((((GGGG))))
+ Define the location of the various client code page
+ files.
+
+
+
+ Page 30 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ See also _c_l_i_e_n_t _c_o_d_e _p_a_g_e
+
+ Default: ccccooooddddeeee ppppaaaaggggeeee ddddiiiirrrreeeeccccttttoooorrrryyyy ==== $$$${{{{pppprrrreeeeffffiiiixxxx}}}}////lllliiiibbbb////ccccooooddddeeeeppppaaaaggggeeeessss
+
+ Example: ccccooooddddeeee ppppaaaaggggeeee ddddiiiirrrreeeeccccttttoooorrrryyyy ====
+ ////uuuussssrrrr////sssshhhhaaaarrrreeee////ssssaaaammmmbbbbaaaa////ccccooooddddeeeeppppaaaaggggeeeessss
+
+ ccccooooddddiiiinnnngggg ssssyyyysssstttteeeemmmm ((((GGGG))))
+ This parameter is used to determine how incoming
+ Shift-JIS Japanese characters are mapped from the
+ incoming _c_l_i_e_n_t _c_o_d_e _p_a_g_e used by the client, into file
+ names in the UNIX filesystem. Only useful if _c_l_i_e_n_t
+ _c_o_d_e _p_a_g_e is set to 932 (Japanese Shift-JIS). The
+ options are :
+
+ o+ SJIS - Shift-JIS. Does no conversion of the incoming
+ filename.
+
+ o+ JIS8, J8BB, J8BH, J8@B, J8@J, J8@H - Convert from
+ incoming Shift-JIS to eight bit JIS code with
+ different shift-in, shift out codes.
+
+ o+ JIS7, J7BB, J7BH, J7@B, J7@J, J7@H - Convert from
+ incoming Shift-JIS to seven bit JIS code with
+ different shift-in, shift out codes.
+
+ o+ JUNET, JUBB, JUBH, JU@B, JU@J, JU@H - Convert from
+ incoming Shift-JIS to JUNET code with different
+ shift-in, shift out codes.
+
+ o+ EUC - Convert an incoming Shift-JIS character to EUC
+ code.
+
+ o+ HEX - Convert an incoming Shift-JIS character to a 3
+ byte hex representation, i.e. :AB.
+
+ o+ CAP - Convert an incoming Shift-JIS character to the
+ 3 byte hex representation used by the Columbia
+ AppleTalk Program (CAP), i.e. :AB. This is used for
+ compatibility between Samba and CAP.
+
+ Default: ccccooooddddiiiinnnngggg ssssyyyysssstttteeeemmmm ==== <<<<eeeemmmmppppttttyyyy vvvvaaaalllluuuueeee>>>>
+
+ ccccoooommmmmmmmeeeennnntttt ((((SSSS))))
+ This is a text field that is seen next to a share when
+ a client does a queries the server, either via the
+ network neighborhood or via nnnneeeetttt vvvviiiieeeewwww to list what
+ shares are available.
+
+ If you want to set the string that is displayed next to
+ the machine name then see the _s_e_r_v_e_r _s_t_r_i_n_g parameter.
+
+
+
+
+ Page 31 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: NNNNoooo ccccoooommmmmmmmeeeennnntttt ssssttttrrrriiiinnnngggg
+
+ Example: ccccoooommmmmmmmeeeennnntttt ==== FFFFrrrreeeedddd''''ssss FFFFiiiilllleeeessss
+
+ ccccoooonnnnffffiiiigggg ffffiiiilllleeee ((((GGGG))))
+ This allows you to override the config file to use,
+ instead of the default (usually _s_m_b._c_o_n_f). There is a
+ chicken and egg problem here as this option is set in
+ the config file!
+
+ For this reason, if the name of the config file has
+ changed when the parameters are loaded then it will
+ reload them from the new config file.
+
+ This option takes the usual substitutions, which can be
+ very useful.
+
+ If the config file doesn't exist then it won't be
+ loaded (allowing you to special case the config files
+ of just a few clients).
+
+ Example: ccccoooonnnnffffiiiigggg ffffiiiilllleeee ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////lllliiiibbbb////ssssmmmmbbbb....ccccoooonnnnffff....%%%%mmmm
+
+ ccccooooppppyyyy ((((SSSS))))
+ This parameter allows you to "clone" service entries.
+ The specified service is simply duplicated under the
+ current service's name. Any parameters specified in the
+ current section will override those in the section
+ being copied.
+
+ This feature lets you set up a 'template' service and
+ create similar services easily. Note that the service
+ being copied must occur earlier in the configuration
+ file than the service doing the copying.
+
+ Default: nnnnoooo vvvvaaaalllluuuueeee
+
+ Example: ccccooooppppyyyy ==== ooootttthhhheeeerrrrsssseeeerrrrvvvviiiicccceeee
+
+ ccccrrrreeeeaaaatttteeee mmmmaaaasssskkkk ((((SSSS))))
+ A synonym for this parameter is _c_r_e_a_t_e _m_o_d_e .
+
+ When a file is created, the necessary permissions are
+ calculated according to the mapping from DOS modes to
+ UNIX permissions, and the resulting UNIX mode is then
+ bit-wise 'AND'ed with this parameter. This parameter
+ may be thought of as a bit-wise MASK for the UNIX modes
+ of a file. Any bit nnnnooootttt set here will be removed from
+ the modes set on a file when it is created.
+
+ The default value of this parameter removes the 'group'
+ and 'other' write and execute bits from the UNIX modes.
+
+
+
+ Page 32 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Following this Samba will bit-wise 'OR' the UNIX mode
+ created from this parameter with the value of the _f_o_r_c_e
+ _c_r_e_a_t_e _m_o_d_e parameter which is set to 000 by default.
+
+ This parameter does not affect directory modes. See the
+ parameter _d_i_r_e_c_t_o_r_y _m_o_d_e for details.
+
+ See also the _f_o_r_c_e _c_r_e_a_t_e _m_o_d_e parameter for forcing
+ particular mode bits to be set on created files. See
+ also the _d_i_r_e_c_t_o_r_y _m_o_d_e parameter for masking mode
+ bits on created directories. See also the _i_n_h_e_r_i_t
+ _p_e_r_m_i_s_s_i_o_n_s parameter.
+
+ Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the
+ administrator wishes to enforce a mask on access
+ control lists also, they need to set the _s_e_c_u_r_i_t_y _m_a_s_k.
+
+ Default: ccccrrrreeeeaaaatttteeee mmmmaaaasssskkkk ==== 0000777744444444
+
+ Example: ccccrrrreeeeaaaatttteeee mmmmaaaasssskkkk ==== 0000777777775555
+
+ ccccrrrreeeeaaaatttteeee mmmmooooddddeeee ((((SSSS))))
+ This is a synonym for _c_r_e_a_t_e _m_a_s_k.
+
+ ccccsssscccc ppppoooolllliiiiccccyyyy ((((SSSS))))
+ This stands for cccclllliiiieeeennnntttt----ssssiiiiddddeeee ccccaaaacccchhhhiiiinnnngggg ppppoooolllliiiiccccyyyy, and
+ specifies how clients capable of offline caching will
+ cache the files in the share. The valid values are:
+ manual, documents, programs, disable.
+
+ These values correspond to those used on Windows
+ servers.
+
+ For example, shares containing roaming profiles can
+ have offline caching disabled using ccccsssscccc ppppoooolllliiiiccccyyyy ====
+ ddddiiiissssaaaabbbblllleeee .
+
+ Default: ccccsssscccc ppppoooolllliiiiccccyyyy ==== mmmmaaaannnnuuuuaaaallll
+
+ Example: ccccsssscccc ppppoooolllliiiiccccyyyy ==== pppprrrrooooggggrrrraaaammmmssss
+
+ ddddeeeeaaaaddddttttiiiimmmmeeee ((((GGGG))))
+ The value of the parameter (a decimal integer)
+ represents the number of minutes of inactivity before a
+ connection is considered dead, and it is disconnected.
+ The deadtime only takes effect if the number of open
+ files is zero.
+
+ This is useful to stop a server's resources being
+ exhausted by a large number of inactive connections.
+
+
+
+
+ Page 33 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Most clients have an auto-reconnect feature when a
+ connection is broken so in most cases this parameter
+ should be transparent to users.
+
+ Using this parameter with a timeout of a few minutes is
+ recommended for most systems.
+
+ A deadtime of zero indicates that no auto-disconnection
+ should be performed.
+
+ Default: ddddeeeeaaaaddddttttiiiimmmmeeee ==== 0000
+
+ Example: ddddeeeeaaaaddddttttiiiimmmmeeee ==== 11115555
+
+ ddddeeeebbbbuuuugggg hhhhiiiirrrreeeessss ttttiiiimmmmeeeessssttttaaaammmmpppp ((((GGGG))))
+ Sometimes the timestamps in the log messages are needed
+ with a resolution of higher that seconds, this boolean
+ parameter adds microsecond resolution to the timestamp
+ message header when turned on.
+
+ Note that the parameter _d_e_b_u_g _t_i_m_e_s_t_a_m_p must be on for
+ this to have an effect.
+
+ Default: ddddeeeebbbbuuuugggg hhhhiiiirrrreeeessss ttttiiiimmmmeeeessssttttaaaammmmpppp ==== nnnnoooo
+
+ ddddeeeebbbbuuuugggg ppppiiiidddd ((((GGGG))))
+ When using only one log file for more then one forked
+ smbdprocess there may be hard to follow which process
+ outputs which message. This boolean parameter is adds
+ the process-id to the timestamp message headers in the
+ logfile when turned on.
+
+ Note that the parameter _d_e_b_u_g _t_i_m_e_s_t_a_m_p must be on for
+ this to have an effect.
+
+ Default: ddddeeeebbbbuuuugggg ppppiiiidddd ==== nnnnoooo
+
+ ddddeeeebbbbuuuugggg ttttiiiimmmmeeeessssttttaaaammmmpppp ((((GGGG))))
+ Samba 2.2 debug log messages are timestamped by
+ default. If you are running at a high _d_e_b_u_g _l_e_v_e_l
+ these timestamps can be distracting. This boolean
+ parameter allows timestamping to be turned off.
+
+ Default: ddddeeeebbbbuuuugggg ttttiiiimmmmeeeessssttttaaaammmmpppp ==== yyyyeeeessss
+
+ ddddeeeebbbbuuuugggg uuuuiiiidddd ((((GGGG))))
+ Samba is sometimes run as root and sometime run as the
+ connected user, this boolean parameter inserts the
+ current euid, egid, uid and gid to the timestamp
+ message headers in the log file if turned on.
+
+ Note that the parameter _d_e_b_u_g _t_i_m_e_s_t_a_m_p must be on for
+
+
+
+ Page 34 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ this to have an effect.
+
+ Default: ddddeeeebbbbuuuugggg uuuuiiiidddd ==== nnnnoooo
+
+ ddddeeeebbbbuuuugggglllleeeevvvveeeellll ((((GGGG))))
+ Synonym for _l_o_g _l_e_v_e_l.
+
+ ddddeeeeffffaaaauuuulllltttt ((((GGGG))))
+ A synonym for _d_e_f_a_u_l_t _s_e_r_v_i_c_e.
+
+ ddddeeeeffffaaaauuuulllltttt ccccaaaasssseeee ((((SSSS))))
+ See the section on NAME MANGLING. Also note the _s_h_o_r_t
+ _p_r_e_s_e_r_v_e _c_a_s_e parameter.
+
+ Default: ddddeeeeffffaaaauuuulllltttt ccccaaaasssseeee ==== lllloooowwwweeeerrrr
+
+ ddddeeeeffffaaaauuuulllltttt ddddeeeevvvvmmmmooooddddeeee ((((SSSS))))
+ This parameter is only applicable to printable
+ services. When smbd is serving Printer Drivers to
+ Windows NT/2k/XP clients, each printer on the Samba
+ server has a Device Mode which defines things such as
+ paper size and orientation and duplex settings. The
+ device mode can only correctly be generated by the
+ printer driver itself (which can only be executed on a
+ Win32 platform). Because smbd is unable to execute the
+ driver code to generate the device mode, the default
+ behavior is to set this field to NULL.
+
+ Most problems with serving printer drivers to Windows
+ NT/2k/XP clients can be traced to a problem with the
+ generated device mode. Certain drivers will do things
+ such as crashing the client's Explorer.exe with a NULL
+ devmode. However, other printer drivers can cause the
+ client's spooler service (spoolsv.exe) to die if the
+ devmode was not created by the driver itself (i.e. smbd
+ generates a default devmode).
+
+ This parameter should be used with care and tested with
+ the printer driver in question. It is better to leave
+ the device mode to NULL and let the Windows client set
+ the correct values. Because drivers do not do this all
+ the time, setting ddddeeeeffffaaaauuuulllltttt ddddeeeevvvvmmmmooooddddeeee ==== yyyyeeeessss will instruct
+ smbd to generate a default one.
+
+ For more information on Windows NT/2k printing and
+ Device Modes, see the MSDN documentation
+ <URL:http://msdn.microsoft.com/>.
+
+ Default: ddddeeeeffffaaaauuuulllltttt ddddeeeevvvvmmmmooooddddeeee ==== nnnnoooo
+
+ ddddeeeeffffaaaauuuulllltttt sssseeeerrrrvvvviiiicccceeee ((((GGGG))))
+ This parameter specifies the name of a service which
+
+
+
+ Page 35 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ will be connected to if the service actually requested
+ cannot be found. Note that the square brackets are NNNNOOOOTTTT
+ given in the parameter value (see example below).
+
+ There is no default value for this parameter. If this
+ parameter is not given, attempting to connect to a
+ nonexistent service results in an error.
+
+ Typically the default service would be a _g_u_e_s_t _o_k,
+ _r_e_a_d-_o_n_l_y service.
+
+ Also note that the apparent service name will be
+ changed to equal that of the requested service, this is
+ very useful as it allows you to use macros like %_S to
+ make a wildcard service.
+
+ Note also that any "_" characters in the name of the
+ service used in the default service will get mapped to
+ a "/". This allows for interesting things.
+
+ Example:
+
+
+ [global]
+ default service = pub
+
+ [pub]
+ path = /%S
+
+
+
+ ddddeeeelllleeeetttteeee pppprrrriiiinnnntttteeeerrrr ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ With the introduction of MS-RPC based printer support
+ for Windows NT/2000 clients in Samba 2.2, it is now
+ possible to delete printer at run time by issuing the
+ DeletePrinter() RPC call.
+
+ For a Samba host this means that the printer must be
+ physically deleted from underlying printing system. The
+ _d_e_l_e_t_e_p_r_i_n_t_e_r _c_o_m_m_a_n_d defines a script to be run which
+ will perform the necessary operations for removing the
+ printer from the print system and from _s_m_b._c_o_n_f.
+
+ The _d_e_l_e_t_e _p_r_i_n_t_e_r _c_o_m_m_a_n_d is automatically called with
+ only one parameter: "_p_r_i_n_t_e_r _n_a_m_e".
+
+ Once the _d_e_l_e_t_e _p_r_i_n_t_e_r _c_o_m_m_a_n_d has been executed, ssssmmmmbbbbdddd
+ will reparse the _s_m_b._c_o_n_f to associated printer no
+ longer exists. If the sharename is still valid, then
+ ssssmmmmbbbbdddd will return an ACCESS_DENIED error to the client.
+
+ See also _a_d_d _p_r_i_n_t_e_r _c_o_m_m_a_n_d, _p_r_i_n_t_i_n_g, _s_h_o_w _a_d_d
+
+
+
+ Page 36 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ _p_r_i_n_t_e_r _w_i_z_a_r_d
+
+ Default: nnnnoooonnnneeee
+
+ Example: ddddeeeelllleeeetttteeeepppprrrriiiinnnntttteeeerrrr ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////rrrreeeemmmmoooovvvveeeepppprrrriiiinnnntttteeeerrrr
+
+ ddddeeeelllleeeetttteeee rrrreeeeaaaaddddoooonnnnllllyyyy ((((SSSS))))
+ This parameter allows readonly files to be deleted.
+ This is not normal DOS semantics, but is allowed by
+ UNIX.
+
+ This option may be useful for running applications such
+ as rcs, where UNIX file ownership prevents changing
+ file permissions, and DOS semantics prevent deletion of
+ a read only file.
+
+ Default: ddddeeeelllleeeetttteeee rrrreeeeaaaaddddoooonnnnllllyyyy ==== nnnnoooo
+
+ ddddeeeelllleeeetttteeee sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ Samba 2.2.0 introduced the ability to dynamically add
+ and delete shares via the Windows NT 4.0 Server
+ Manager. The _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d is used to define an
+ external program or script which will remove an
+ existing service definition from _s_m_b._c_o_n_f. In order to
+ successfully execute the _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d, ssssmmmmbbbbdddd
+ requires that the administrator be connected using a
+ root account (i.e. uid == 0).
+
+ When executed, ssssmmmmbbbbdddd will automatically invoke the
+ _d_e_l_e_t_e _s_h_a_r_e _c_o_m_m_a_n_d with two parameters.
+
+ o+ _c_o_n_f_i_g_F_i_l_e - the location of the global _s_m_b._c_o_n_f
+ file.
+
+ o+ _s_h_a_r_e_N_a_m_e - the name of the existing service.
+
+ This parameter is only used to remove file shares. To delete
+ printer shares, see the _d_e_l_e_t_e _p_r_i_n_t_e_r _c_o_m_m_a_n_d.
+
+ See also _a_d_d _s_h_a_r_e _c_o_m_m_a_n_d, _c_h_a_n_g_e _s_h_a_r_e _c_o_m_m_a_n_d.
+
+ Default: nnnnoooonnnneeee
+
+ Example: ddddeeeelllleeeetttteeee sssshhhhaaaarrrreeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////llllooooccccaaaallll////bbbbiiiinnnn////ddddeeeellllsssshhhhaaaarrrreeee
+
+ ddddeeeelllleeeetttteeee uuuusssseeeerrrr ssssccccrrrriiiipppptttt ((((GGGG))))
+ This is the full pathname to a script that will be run
+ AAAASSSS RRRROOOOOOOOTTTT by ssssmmmmbbbbdddd((((8888)))) under special circumstances
+ described below.
+
+ Normally, a Samba server requires that UNIX users are
+ created for all users accessing files on this server.
+
+
+
+ Page 37 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ For sites that use Windows NT account databases as
+ their primary user database creating these users and
+ keeping the user list in sync with the Windows NT PDC
+ is an onerous task. This option allows ssssmmmmbbbbdddd to delete
+ the required UNIX users OOOONNNN DDDDEEEEMMMMAAAANNNNDDDD when a user accesses
+ the Samba server and the Windows NT user no longer
+ exists.
+
+ In order to use this option, ssssmmmmbbbbdddd must be set to
+ _s_e_c_u_r_i_t_y = _d_o_m_a_i_n or _s_e_c_u_r_i_t_y = _u_s_e_r and _d_e_l_e_t_e _u_s_e_r
+ _s_c_r_i_p_t must be set to a full pathname for a script that
+ will delete a UNIX user given one argument of %_u, which
+ expands into the UNIX user name to delete.
+
+ When the Windows user attempts to access the Samba
+ server, at llllooooggggiiiinnnn (session setup in the SMB protocol)
+ time, ssssmmmmbbbbdddd contacts the _p_a_s_s_w_o_r_d _s_e_r_v_e_r and attempts
+ to authenticate the given user with the given password.
+ If the authentication fails with the specific Domain
+ error code meaning that the user no longer exists then
+ ssssmmmmbbbbdddd attempts to find a UNIX user in the UNIX password
+ database that matches the Windows user account. If this
+ lookup succeeds, and _d_e_l_e_t_e _u_s_e_r _s_c_r_i_p_t is set then
+ ssssmmmmbbbbdddd will all the specified script AAAASSSS RRRROOOOOOOOTTTT, expanding
+ any %_u argument to be the user name to delete.
+
+ This script should delete the given UNIX username. In
+ this way, UNIX users are dynamically deleted to match
+ existing Windows NT accounts.
+
+ See also security = domain, _p_a_s_s_w_o_r_d _s_e_r_v_e_r , _a_d_d _u_s_e_r
+ _s_c_r_i_p_t .
+
+ Default: ddddeeeelllleeeetttteeee uuuusssseeeerrrr ssssccccrrrriiiipppptttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: ddddeeeelllleeeetttteeee uuuusssseeeerrrr ssssccccrrrriiiipppptttt ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////ddddeeeellll____uuuusssseeeerrrr %%%%uuuu
+
+ ddddeeeelllleeeetttteeee vvvveeeettttoooo ffffiiiilllleeeessss ((((SSSS))))
+ This option is used when Samba is attempting to delete
+ a directory that contains one or more vetoed
+ directories (see the _v_e_t_o _f_i_l_e_s option). If this option
+ is set to no (the default) then if a vetoed directory
+ contains any non-vetoed files or directories then the
+ directory delete will fail. This is usually what you
+ want.
+
+ If this option is set to yes, then Samba will attempt
+ to recursively delete any files and directories within
+ the vetoed directory. This can be useful for
+ integration with file serving systems such as NetAtalk
+ which create meta-files within directories you might
+
+
+
+ Page 38 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ normally veto DOS/Windows users from seeing (e.g.
+ ._A_p_p_l_e_D_o_u_b_l_e)
+
+ Setting ddddeeeelllleeeetttteeee vvvveeeettttoooo ffffiiiilllleeeessss ==== yyyyeeeessss allows these
+ directories to be transparently deleted when the parent
+ directory is deleted (so long as the user has
+ permissions to do so).
+
+ See also the _v_e_t_o _f_i_l_e_s parameter.
+
+ Default: ddddeeeelllleeeetttteeee vvvveeeettttoooo ffffiiiilllleeeessss ==== nnnnoooo
+
+ ddddeeeennnnyyyy hhhhoooossssttttssss ((((SSSS))))
+ Synonym for _h_o_s_t_s _d_e_n_y.
+
+ ddddffffrrrreeeeeeee ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ The _d_f_r_e_e _c_o_m_m_a_n_d setting should only be used on
+ systems where a problem occurs with the internal disk
+ space calculations. This has been known to happen with
+ Ultrix, but may occur with other operating systems. The
+ symptom that was seen was an error of "Abort Retry
+ Ignore" at the end of each directory listing.
+
+ This setting allows the replacement of the internal
+ routines to calculate the total disk space and amount
+ available with an external routine. The example below
+ gives a possible script that might fulfill this
+ function.
+
+ The external program will be passed a single parameter
+ indicating a directory in the filesystem being queried.
+ This will typically consist of the string ./. The
+ script should return two integers in ASCII. The first
+ should be the total disk space in blocks, and the
+ second should be the number of available blocks. An
+ optional third return value can give the block size in
+ bytes. The default blocksize is 1024 bytes.
+
+ Note: Your script should NNNNOOOOTTTT be setuid or setgid and
+ should be owned by (and writeable only by) root!
+
+ Default: BBBByyyy ddddeeeeffffaaaauuuulllltttt iiiinnnntttteeeerrrrnnnnaaaallll rrrroooouuuuttttiiiinnnneeeessss ffffoooorrrr ddddeeeetttteeeerrrrmmmmiiiinnnniiiinnnngggg
+ tttthhhheeee ddddiiiisssskkkk ccccaaaappppaaaacccciiiittttyyyy aaaannnndddd rrrreeeemmmmaaaaiiiinnnniiiinnnngggg ssssppppaaaacccceeee wwwwiiiillllllll bbbbeeee uuuusssseeeedddd....
+
+ Example: ddddffffrrrreeeeeeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////ddddffffrrrreeeeeeee
+
+ Where the script dfree (which must be made executable)
+ could be:
+
+
+
+ #!/bin/sh
+
+
+
+ Page 39 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ df $1 | tail -1 | awk '{print $2" "$4}'
+
+
+
+ or perhaps (on Sys V based systems):
+
+
+
+ #!/bin/sh
+ /usr/bin/df -k $1 | tail -1 | awk '{print $3" "$5}'
+
+
+
+ Note that you may have to replace the command names
+ with full path names on some systems.
+
+ ddddiiiirrrreeeeccccttttoooorrrryyyy ((((SSSS))))
+ Synonym for _p_a_t_h .
+
+ ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmaaaasssskkkk ((((SSSS))))
+ This parameter is the octal modes which are used when
+ converting DOS modes to UNIX modes when creating UNIX
+ directories.
+
+ When a directory is created, the necessary permissions
+ are calculated according to the mapping from DOS modes
+ to UNIX permissions, and the resulting UNIX mode is
+ then bit-wise 'AND'ed with this parameter. This
+ parameter may be thought of as a bit-wise MASK for the
+ UNIX modes of a directory. Any bit nnnnooootttt set here will be
+ removed from the modes set on a directory when it is
+ created.
+
+ The default value of this parameter removes the 'group'
+ and 'other' write bits from the UNIX mode, allowing
+ only the user who owns the directory to modify it.
+
+ Following this Samba will bit-wise 'OR' the UNIX mode
+ created from this parameter with the value of the _f_o_r_c_e
+ _d_i_r_e_c_t_o_r_y _m_o_d_e parameter. This parameter is set to 000
+ by default (i.e. no extra mode bits are added).
+
+ Note that this parameter does not apply to permissions
+ set by Windows NT/2000 ACL editors. If the
+ administrator wishes to enforce a mask on access
+ control lists also, they need to set the _d_i_r_e_c_t_o_r_y
+ _s_e_c_u_r_i_t_y _m_a_s_k.
+
+ See the _f_o_r_c_e _d_i_r_e_c_t_o_r_y _m_o_d_e parameter to cause
+ particular mode bits to always be set on created
+ directories.
+
+
+
+
+ Page 40 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ See also the _c_r_e_a_t_e _m_o_d_e parameter for masking mode
+ bits on created files, and the _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_a_s_k
+ parameter.
+
+ Also refer to the _i_n_h_e_r_i_t _p_e_r_m_i_s_s_i_o_n_s parameter.
+
+ Default: ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmaaaasssskkkk ==== 0000777755555555
+
+ Example: ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmaaaasssskkkk ==== 0000777777775555
+
+ ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmooooddddeeee ((((SSSS))))
+ Synonym for _d_i_r_e_c_t_o_r_y _m_a_s_k
+
+ ddddiiiirrrreeeeccccttttoooorrrryyyy sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ((((SSSS))))
+ This parameter controls what UNIX permission bits can
+ be modified when a Windows NT client is manipulating
+ the UNIX permission on a directory using the native NT
+ security dialog box.
+
+ This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits
+ not in this mask from being modified. Essentially, zero
+ bits in this mask may be treated as a set of bits the
+ user is not allowed to change.
+
+ If not set explicitly this parameter is set to 0777
+ meaning a user is allowed to modify all the
+ user/group/world permissions on a directory.
+
+ NNNNooootttteeee that users who can access the Samba server through
+ other means can easily bypass this restriction, so it
+ is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably
+ want to leave it as the default of 0777.
+
+ See also the _f_o_r_c_e _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_o_d_e, _s_e_c_u_r_i_t_y
+ _m_a_s_k, _f_o_r_c_e _s_e_c_u_r_i_t_y _m_o_d_e parameters.
+
+ Default: ddddiiiirrrreeeeccccttttoooorrrryyyy sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ==== 0000777777777777
+
+ Example: ddddiiiirrrreeeeccccttttoooorrrryyyy sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ==== 0000777700000000
+
+ ddddiiiissssaaaabbbblllleeee ssssppppoooooooollllssssssss ((((GGGG))))
+ Enabling this parameter will disables Samba's support
+ for the SPOOLSS set of MS-RPC's and will yield
+ identical behavior as Samba 2.0.x. Windows NT/2000
+ clients will downgrade to using Lanman style printing
+ commands. Windows 9x/ME will be uneffected by the
+ parameter. However, this will also disable the ability
+ to upload printer drivers to a Samba server via the
+ Windows NT Add Printer Wizard or by using the NT
+ printer properties dialog window. It will also disable
+
+
+
+ Page 41 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ the capability of Windows NT/2000 clients to download
+ print drivers from the Samba host upon demand. BBBBeeee vvvveeeerrrryyyy
+ ccccaaaarrrreeeeffffuuuullll aaaabbbboooouuuutttt eeeennnnaaaabbbblllliiiinnnngggg tttthhhhiiiissss ppppaaaarrrraaaammmmeeeetttteeeerrrr....
+
+ See also use client driver
+
+ Default : ddddiiiissssaaaabbbblllleeee ssssppppoooooooollllssssssss ==== nnnnoooo
+
+ ddddnnnnssss pppprrrrooooxxxxyyyy ((((GGGG))))
+ Specifies that nmbd(8) when acting as a WINS server and
+ finding that a NetBIOS name has not been registered,
+ should treat the NetBIOS name word-for-word as a DNS
+ name and do a lookup with the DNS server for that name
+ on behalf of the name-querying client.
+
+ Note that the maximum length for a NetBIOS name is 15
+ characters, so the DNS name (or DNS alias) can likewise
+ only be 15 characters, maximum.
+
+ nnnnmmmmbbbbdddd spawns a second copy of itself to do the DNS name
+ lookup requests, as doing a name lookup is a blocking
+ action.
+
+ See also the parameter _w_i_n_s _s_u_p_p_o_r_t.
+
+ Default: ddddnnnnssss pppprrrrooooxxxxyyyy ==== yyyyeeeessss
+
+ ddddoooommmmaaaaiiiinnnn aaaaddddmmmmiiiinnnn ggggrrrroooouuuupppp ((((GGGG))))
+ This parameter is intended as a temporary solution to
+ enable users to be a member of the "Domain Admins"
+ group when a Samba host is acting as a PDC. A complete
+ solution will be provided by a system for mapping
+ Windows NT/2000 groups onto UNIX groups. Please note
+ that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in
+ standard _s_m_b._c_o_n_f notation.
+
+ See also _d_o_m_a_i_n _g_u_e_s_t _g_r_o_u_p, _d_o_m_a_i_n _l_o_g_o_n_s
+
+ Default: nnnnoooo ddddoooommmmaaaaiiiinnnn aaaaddddmmmmiiiinnnniiiissssttttrrrraaaattttoooorrrrssss
+
+ Example: ddddoooommmmaaaaiiiinnnn aaaaddddmmmmiiiinnnn ggggrrrroooouuuupppp ==== rrrrooooooootttt @@@@wwwwhhhheeeeeeeellll
+
+ ddddoooommmmaaaaiiiinnnn gggguuuueeeesssstttt ggggrrrroooouuuupppp ((((GGGG))))
+ This parameter is intended as a temporary solution to
+ enable users to be a member of the "Domain Guests"
+ group when a Samba host is acting as a PDC. A complete
+ solution will be provided by a system for mapping
+ Windows NT/2000 groups onto UNIX groups. Please note
+ that this parameter has a somewhat confusing name. It
+ accepts a list of usernames and of group names in
+ standard _s_m_b._c_o_n_f notation.
+
+
+
+ Page 42 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ See also _d_o_m_a_i_n _a_d_m_i_n _g_r_o_u_p, _d_o_m_a_i_n _l_o_g_o_n_s
+
+ Default: nnnnoooo ddddoooommmmaaaaiiiinnnn gggguuuueeeessssttttssss
+
+ Example: ddddoooommmmaaaaiiiinnnn gggguuuueeeesssstttt ggggrrrroooouuuupppp ==== nnnnoooobbbbooooddddyyyy @@@@gggguuuueeeesssstttt
+
+ ddddoooommmmaaaaiiiinnnn llllooooggggoooonnnnssss ((((GGGG))))
+ If set to yes, the Samba server will serve Windows
+ 95/98 Domain logons for the _w_o_r_k_g_r_o_u_p it is in. Samba
+ 2.2 also has limited capability to act as a domain
+ controller for Windows NT 4 Domains. For more details
+ on setting up this feature see the Samba-PDC-HOWTO
+ included in the _h_t_m_l_d_o_c_s/ directory shipped with the
+ source code.
+
+ Default: ddddoooommmmaaaaiiiinnnn llllooooggggoooonnnnssss ==== nnnnoooo
+
+ ddddoooommmmaaaaiiiinnnn mmmmaaaasssstttteeeerrrr ((((GGGG))))
+ Tell nnnnmmmmbbbbdddd((((8888)))) to enable WAN-wide browse list collation.
+ Setting this option causes nnnnmmmmbbbbdddd to claim a special
+ domain specific NetBIOS name that identifies it as a
+ domain master browser for its given _w_o_r_k_g_r_o_u_p. Local
+ master browsers in the same _w_o_r_k_g_r_o_u_p on broadcast-
+ isolated subnets will give this nnnnmmmmbbbbdddd their local browse
+ lists, and then ask ssssmmmmbbbbdddd((((8888)))) for a complete copy of the
+ browse list for the whole wide area network. Browser
+ clients will then contact their local master browser,
+ and will receive the domain-wide browse list, instead
+ of just the list for their broadcast-isolated subnet.
+
+ Note that Windows NT Primary Domain Controllers expect
+ to be able to claim this _w_o_r_k_g_r_o_u_p specific special
+ NetBIOS name that identifies them as domain master
+ browsers for that _w_o_r_k_g_r_o_u_p by default (i.e. there is
+ no way to prevent a Windows NT PDC from attempting to
+ do this). This means that if this parameter is set and
+ nnnnmmmmbbbbdddd claims the special name for a _w_o_r_k_g_r_o_u_p before a
+ Windows NT PDC is able to do so then cross subnet
+ browsing will behave strangely and may fail.
+
+ If ddddoooommmmaaaaiiiinnnn llllooooggggoooonnnnssss ==== yyyyeeeessss , then the default behavior is
+ to enable the _d_o_m_a_i_n _m_a_s_t_e_r parameter. If _d_o_m_a_i_n _l_o_g_o_n_s
+ is not enabled (the default setting), then neither will
+ _d_o_m_a_i_n _m_a_s_t_e_r be enabled by default.
+
+ Default: ddddoooommmmaaaaiiiinnnn mmmmaaaasssstttteeeerrrr ==== aaaauuuuttttoooo
+
+ ddddoooonnnntttt ddddeeeesssscccceeeennnndddd ((((SSSS))))
+ There are certain directories on some systems (e.g.,
+ the /_p_r_o_c tree under Linux) that are either not of
+ interest to clients or are infinitely deep (recursive).
+ This parameter allows you to specify a comma-delimited
+
+
+
+ Page 43 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ list of directories that the server should always show
+ as empty.
+
+ Note that Samba can be very fussy about the exact
+ format of the "dont descend" entries. For example you
+ may need ./_p_r_o_c instead of just /_p_r_o_c. Experimentation
+ is the best policy :-)
+
+ Default: nnnnoooonnnneeee ((((iiii....eeee....,,,, aaaallllllll ddddiiiirrrreeeeccccttttoooorrrriiiieeeessss aaaarrrreeee OOOOKKKK ttttoooo ddddeeeesssscccceeeennnndddd))))
+
+ Example: ddddoooonnnntttt ddddeeeesssscccceeeennnndddd ==== ////pppprrrroooocccc,,,,////ddddeeeevvvv
+
+ ddddoooossss ffffiiiilllleeeemmmmooooddddeeee ((((SSSS))))
+ The default behavior in Samba is to provide UNIX-like
+ behavior where only the owner of a file/directory is
+ able to change the permissions on it. However, this
+ behavior is often confusing to DOS/Windows users.
+ Enabling this parameter allows a user who has write
+ access to the file (by whatever means) to modify the
+ permissions on it. Note that a user belonging to the
+ group owning the file will not be allowed to change
+ permissions if the group is only granted read access.
+ Ownership of the file/directory is not changed, only
+ the permissions are modified.
+
+ Default: ddddoooossss ffffiiiilllleeeemmmmooooddddeeee ==== nnnnoooo
+
+ ddddoooossss ffffiiiilllleeeettttiiiimmmmeeee rrrreeeessssoooolllluuuuttttiiiioooonnnn ((((SSSS))))
+ Under the DOS and Windows FAT filesystem, the finest
+ granularity on time resolution is two seconds. Setting
+ this parameter for a share causes Samba to round the
+ reported time down to the nearest two second boundary
+ when a query call that requires one second resolution
+ is made to ssssmmmmbbbbdddd((((8888))))
+
+
+ This option is mainly used as a compatibility option
+ for Visual C++ when used against Samba shares. If
+ oplocks are enabled on a share, Visual C++ uses two
+ different time reading calls to check if a file has
+ changed since it was last read. One of these calls uses
+ a one-second granularity, the other uses a two second
+ granularity. As the two second call rounds any odd
+ second down, then if the file has a timestamp of an odd
+ number of seconds then the two timestamps will not
+ match and Visual C++ will keep reporting the file has
+ changed. Setting this option causes the two timestamps
+ to match, and Visual C++ is happy.
+
+ Default: ddddoooossss ffffiiiilllleeeettttiiiimmmmeeee rrrreeeessssoooolllluuuuttttiiiioooonnnn ==== nnnnoooo
+
+ ddddoooossss ffffiiiilllleeeettttiiiimmmmeeeessss ((((SSSS))))
+
+
+
+ Page 44 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Under DOS and Windows, if a user can write to a file
+ they can change the timestamp on it. Under POSIX
+ semantics, only the owner of the file or root may
+ change the timestamp. By default, Samba runs with POSIX
+ semantics and refuses to change the timestamp on a file
+ if the user ssssmmmmbbbbdddd is acting on behalf of is not the file
+ owner. Setting this option to yes allows DOS semantics
+ and smbd will change the file timestamp as DOS
+ requires.
+
+ Default: ddddoooossss ffffiiiilllleeeettttiiiimmmmeeeessss ==== nnnnoooo
+
+ eeeennnnccccrrrryyyypppptttt ppppaaaasssssssswwwwoooorrrrddddssss ((((GGGG))))
+ This boolean controls whether encrypted passwords will
+ be negotiated with the client. Note that Windows NT 4.0
+ SP3 and above and also Windows 98 will by default
+ expect encrypted passwords unless a registry entry is
+ changed. To use encrypted passwords in Samba see the
+ file ENCRYPTION.txt in the Samba documentation
+ directory _d_o_c_s/ shipped with the source code.
+
+ In order for encrypted passwords to work correctly
+ ssssmmmmbbbbdddd((((8888)))) must either have access to a local _s_m_b_p_a_s_s_w_d(_5)
+ program for information on how to set up and maintain
+ this file), or set the security = [server|domain]
+ parameter which causes ssssmmmmbbbbdddd to authenticate against
+ another server.
+
+ Default: eeeennnnccccrrrryyyypppptttt ppppaaaasssssssswwwwoooorrrrddddssss ==== nnnnoooo
+
+ eeeennnnhhhhaaaannnncccceeeedddd bbbbrrrroooowwwwssssiiiinnnngggg ((((GGGG))))
+ This option enables a couple of enhancements to cross-
+ subnet browse propagation that have been added in Samba
+ but which are not standard in Microsoft
+ implementations.
+
+ The first enhancement to browse propagation consists of
+ a regular wildcard query to a Samba WINS server for all
+ Domain Master Browsers, followed by a browse
+ synchronization with each of the returned DMBs. The
+ second enhancement consists of a regular randomised
+ browse synchronization with all currently known DMBs.
+
+ You may wish to disable this option if you have a
+ problem with empty workgroups not disappearing from
+ browse lists. Due to the restrictions of the browse
+ protocols these enhancements can cause a empty
+ workgroup to stay around forever which can be annoying.
+
+ In general you should leave this option enabled as it
+ makes cross-subnet browse propagation much more
+ reliable.
+
+
+
+ Page 45 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: eeeennnnhhhhaaaannnncccceeeedddd bbbbrrrroooowwwwssssiiiinnnngggg ==== yyyyeeeessss
+
+ eeeennnnuuuummmmppppoooorrrrttttssss ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ The concept of a "port" is fairly foreign to UNIX
+ hosts. Under Windows NT/2000 print servers, a port is
+ associated with a port monitor and generally takes the
+ form of a local port (i.e. LPT1:, COM1:, FILE:) or a
+ remote port (i.e. LPD Port Monitor, etc...). By
+ default, Samba has only one port defined--"Samba
+ Printer Port". Under Windows NT/2000, all printers must
+ have a valid port name. If you wish to have a list of
+ ports displayed (ssssmmmmbbbbdddd does not use a port name for
+ anything) other than the default "Samba Printer Port",
+ you can define _e_n_u_m_p_o_r_t_s _c_o_m_m_a_n_d to point to a program
+ which should generate a list of ports, one per line, to
+ standard output. This listing will then be used in
+ response to the level 1 and 2 EnumPorts() RPC.
+
+ Default: nnnnoooo eeeennnnuuuummmmppppoooorrrrttttssss ccccoooommmmmmmmaaaannnndddd
+
+ Example: eeeennnnuuuummmmppppoooorrrrttttssss ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////lllliiiissssttttppppoooorrrrttttssss
+
+ eeeexxxxeeeecccc ((((SSSS))))
+ This is a synonym for _p_r_e_e_x_e_c.
+
+ ffffaaaakkkkeeee ddddiiiirrrreeeeccccttttoooorrrryyyy ccccrrrreeeeaaaatttteeee ttttiiiimmmmeeeessss ((((SSSS))))
+ NTFS and Windows VFAT file systems keep a create time
+ for all files and directories. This is not the same as
+ the ctime - status change time - that Unix keeps, so
+ Samba by default reports the earliest of the various
+ times Unix does keep. Setting this parameter for a
+ share causes Samba to always report midnight 1-1-1980
+ as the create time for directories.
+
+ This option is mainly used as a compatibility option
+ for Visual C++ when used against Samba shares. Visual
+ C++ generated makefiles have the object directory as a
+ dependency for each object file, and a make rule to
+ create the directory. Also, when NMAKE compares
+ timestamps it uses the creation time when examining a
+ directory. Thus the object directory will be created if
+ it does not exist, but once it does exist it will
+ always have an earlier timestamp than the object files
+ it contains.
+
+ However, Unix time semantics mean that the create time
+ reported by Samba will be updated whenever a file is
+ created or or deleted in the directory. NMAKE finds all
+ object files in the object directory. The timestamp of
+ the last one built is then compared to the timestamp of
+ the object directory. If the directory's timestamp if
+ newer, then all object files will be rebuilt. Enabling
+
+
+
+ Page 46 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ this option ensures directories always predate their
+ contents and an NMAKE build will proceed as expected.
+
+ Default: ffffaaaakkkkeeee ddddiiiirrrreeeeccccttttoooorrrryyyy ccccrrrreeeeaaaatttteeee ttttiiiimmmmeeeessss ==== nnnnoooo
+
+ ffffaaaakkkkeeee oooopppplllloooocccckkkkssss ((((SSSS))))
+ Oplocks are the way that SMB clients get permission
+ from a server to locally cache file operations. If a
+ server grants an oplock (opportunistic lock) then the
+ client is free to assume that it is the only one
+ accessing the file and it will aggressively cache file
+ data. With some oplock types the client may even cache
+ file open/close operations. This can give enormous
+ performance benefits.
+
+ When you set ffffaaaakkkkeeee oooopppplllloooocccckkkkssss ==== yyyyeeeessss, ssssmmmmbbbbdddd((((8888)))) will always
+ grant oplock requests no matter how many clients are
+ using the file.
+
+ It is generally much better to use the real _o_p_l_o_c_k_s
+ support rather than this parameter.
+
+ If you enable this option on all read-only shares or
+ shares that you know will only be accessed from one
+ client at a time such as physically read-only media
+ like CDROMs, you will see a big performance improvement
+ on many operations. If you enable this option on shares
+ where multiple clients may be accessing the files
+ read-write at the same time you can get data
+ corruption. Use this option carefully!
+
+ Default: ffffaaaakkkkeeee oooopppplllloooocccckkkkssss ==== nnnnoooo
+
+ ffffoooolllllllloooowwww ssssyyyymmmmlllliiiinnnnkkkkssss ((((SSSS))))
+ This parameter allows the Samba administrator to stop
+ ssssmmmmbbbbdddd((((8888)))) from following symbolic links in a particular
+ share. Setting this parameter to no prevents any file
+ or directory that is a symbolic link from being
+ followed (the user will get an error). This option is
+ very useful to stop users from adding a symbolic link
+ to /_e_t_c/_p_a_s_s_w_d in their home directory for instance.
+ However it will slow filename lookups down slightly.
+
+ This option is enabled (i.e. ssssmmmmbbbbdddd will follow symbolic
+ links) by default.
+
+ Default: ffffoooolllllllloooowwww ssssyyyymmmmlllliiiinnnnkkkkssss ==== yyyyeeeessss
+
+ ffffoooorrrrcccceeee ccccrrrreeeeaaaatttteeee mmmmooooddddeeee ((((SSSS))))
+ This parameter specifies a set of UNIX mode bit
+ permissions that will aaaallllwwwwaaaayyyyssss be set on a file created
+ by Samba. This is done by bitwise 'OR'ing these bits
+
+
+
+ Page 47 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ onto the mode bits of a file that is being created or
+ having its permissions changed. The default for this
+ parameter is (in octal) 000. The modes in this
+ parameter are bitwise 'OR'ed onto the file mode after
+ the mask set in the _c_r_e_a_t_e _m_a_s_k parameter is applied.
+
+ See also the parameter _c_r_e_a_t_e _m_a_s_k for details on
+ masking mode bits on files.
+
+ See also the _i_n_h_e_r_i_t _p_e_r_m_i_s_s_i_o_n_s parameter.
+
+ Default: ffffoooorrrrcccceeee ccccrrrreeeeaaaatttteeee mmmmooooddddeeee ==== 000000000000
+
+ Example: ffffoooorrrrcccceeee ccccrrrreeeeaaaatttteeee mmmmooooddddeeee ==== 0000777755555555
+
+ would force all created files to have read and execute
+ permissions set for 'group' and 'other' as well as the
+ read/write/execute bits set for the 'user'.
+
+ ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmooooddddeeee ((((SSSS))))
+ This parameter specifies a set of UNIX mode bit
+ permissions that will aaaallllwwwwaaaayyyyssss be set on a directory
+ created by Samba. This is done by bitwise 'OR'ing these
+ bits onto the mode bits of a directory that is being
+ created. The default for this parameter is (in octal)
+ 0000 which will not add any extra permission bits to a
+ created directory. This operation is done after the
+ mode mask in the parameter _d_i_r_e_c_t_o_r_y _m_a_s_k is applied.
+
+ See also the parameter _d_i_r_e_c_t_o_r_y _m_a_s_k for details on
+ masking mode bits on created directories.
+
+ See also the _i_n_h_e_r_i_t _p_e_r_m_i_s_s_i_o_n_s parameter.
+
+ Default: ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmooooddddeeee ==== 000000000000
+
+ Example: ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmooooddddeeee ==== 0000777755555555
+
+ would force all created directories to have read and
+ execute permissions set for 'group' and 'other' as well
+ as the read/write/execute bits set for the 'user'.
+
+ ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy
+ This parameter controls what UNIX permission bits can
+ be modified when a Windows NT client is manipulating
+ the UNIX permission on a directory using the native NT
+ security dialog box.
+
+ This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this
+ mask that the user may have modified to be on.
+ Essentially, one bits in this mask may be treated as a
+
+
+
+ Page 48 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ set of bits that, when modifying security on a
+ directory, the user has always set to be 'on'.
+
+ If not set explicitly this parameter is 000, which
+ allows a user to modify all the user/group/world
+ permissions on a directory without restrictions.
+
+ NNNNooootttteeee that users who can access the Samba server through
+ other means can easily bypass this restriction, so it
+ is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably
+ want to leave it set as 0000.
+
+ See also the _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_a_s_k, _s_e_c_u_r_i_t_y _m_a_s_k,
+ _f_o_r_c_e _s_e_c_u_r_i_t_y _m_o_d_e parameters.
+
+ Default: ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy sssseeeeccccuuuurrrriiiittttyyyy mmmmooooddddeeee ==== 0000
+
+ Example: ffffoooorrrrcccceeee ddddiiiirrrreeeeccccttttoooorrrryyyy sssseeeeccccuuuurrrriiiittttyyyy mmmmooooddddeeee ==== 777700000000
+
+ ffffoooorrrrcccceeee ggggrrrroooouuuupppp ((((SSSS))))
+ This specifies a UNIX group name that will be assigned
+ as the default primary group for all users connecting
+ to this service. This is useful for sharing files by
+ ensuring that all access to files on service will use
+ the named group for their permissions checking. Thus,
+ by assigning permissions for this group to the files
+ and directories within this service the Samba
+ administrator can restrict or allow sharing of these
+ files.
+
+ In Samba 2.0.5 and above this parameter has extended
+ functionality in the following way. If the group name
+ listed here has a '+' character prepended to it then
+ the current user accessing the share only has the
+ primary group default assigned to this group if they
+ are already assigned as a member of that group. This
+ allows an administrator to decide that only users who
+ are already in a particular group will create files
+ with group ownership set to that group. This gives a
+ finer granularity of ownership assignment. For example,
+ the setting _f_o_r_c_e _g_r_o_u_p = +_s_y_s means that only users
+ who are already in group sys will have their default
+ primary group assigned to sys when accessing this Samba
+ share. All other users will retain their ordinary
+ primary group.
+
+ If the _f_o_r_c_e _u_s_e_r parameter is also set the group
+ specified in _f_o_r_c_e _g_r_o_u_p will override the primary
+ group set in _f_o_r_c_e _u_s_e_r.
+
+ See also _f_o_r_c_e _u_s_e_r.
+
+
+
+ Page 49 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: nnnnoooo ffffoooorrrrcccceeeedddd ggggrrrroooouuuupppp
+
+ Example: ffffoooorrrrcccceeee ggggrrrroooouuuupppp ==== aaaaggggrrrroooouuuupppp
+
+ ffffoooorrrrcccceeee sssseeeeccccuuuurrrriiiittttyyyy mmmmooooddddeeee ((((SSSS))))
+ This parameter controls what UNIX permission bits can
+ be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT
+ security dialog box.
+
+ This parameter is applied as a mask (OR'ed with) to the
+ changed permission bits, thus forcing any bits in this
+ mask that the user may have modified to be on.
+ Essentially, one bits in this mask may be treated as a
+ set of bits that, when modifying security on a file,
+ the user has always set to be 'on'.
+
+ If not set explicitly this parameter is set to 0, and
+ allows a user to modify all the user/group/world
+ permissions on a file, with no restrictions.
+
+ NNNNooootttteeee that users who can access the Samba server through
+ other means can easily bypass this restriction, so it
+ is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably
+ want to leave this set to 0000.
+
+ See also the _f_o_r_c_e _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_o_d_e, _d_i_r_e_c_t_o_r_y
+ _s_e_c_u_r_i_t_y _m_a_s_k, _s_e_c_u_r_i_t_y _m_a_s_k parameters.
+
+ Default: ffffoooorrrrcccceeee sssseeeeccccuuuurrrriiiittttyyyy mmmmooooddddeeee ==== 0000
+
+ Example: ffffoooorrrrcccceeee sssseeeeccccuuuurrrriiiittttyyyy mmmmooooddddeeee ==== 777700000000
+
+ ffffoooorrrrcccceeee uuuunnnnkkkknnnnoooowwwwnnnn aaaaccccllll uuuusssseeeerrrr ((((SSSS))))
+ If this parameter is set, a Windows NT ACL that
+ contains an unknown SID (security descriptor, or
+ representation of a user or group id) as the owner or
+ group owner of the file will be silently mapped into
+ the current UNIX uid or gid of the currently connected
+ user.
+
+ This is designed to allow Windows NT clients to copy
+ files and folders containing ACLs that were created
+ locally on the client machine and contain users local
+ to that machine only (no domain users) to be copied to
+ a Samba server (usually with XCOPY /O) and have the
+ unknown userid and groupid of the file owner map to the
+ current connected user. This can only be fixed
+ correctly when winbindd allows arbitrary mapping from
+ any Windows NT SID to a UNIX uid or gid.
+
+
+
+
+ Page 50 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Try using this parameter when XCOPY /O gives an
+ ACCESS_DENIED error.
+
+ See also _f_o_r_c_e _g_r_o_u_p
+
+ Default: FFFFaaaallllsssseeee
+
+ Example: ffffoooorrrrcccceeee uuuunnnnkkkknnnnoooowwwwnnnn aaaaccccllll uuuusssseeeerrrr ==== yyyyeeeessss
+
+ ffffoooorrrrcccceeee uuuusssseeeerrrr ((((SSSS))))
+ This specifies a UNIX user name that will be assigned
+ as the default user for all users connecting to this
+ service. This is useful for sharing files. You should
+ also use it carefully as using it incorrectly can cause
+ security problems.
+
+ This user name only gets used once a connection is
+ established. Thus clients still need to connect as a
+ valid user and supply a valid password. Once connected,
+ all file operations will be performed as the "forced
+ user", no matter what username the client connected as.
+ This can be very useful.
+
+ In Samba 2.0.5 and above this parameter also causes the
+ primary group of the forced user to be used as the
+ primary group for all file activity. Prior to 2.0.5 the
+ primary group was left as the primary group of the
+ connecting user (this was a bug).
+
+ See also _f_o_r_c_e _g_r_o_u_p
+
+ Default: nnnnoooo ffffoooorrrrcccceeeedddd uuuusssseeeerrrr
+
+ Example: ffffoooorrrrcccceeee uuuusssseeeerrrr ==== aaaauuuusssseeeerrrr
+
+ ffffssssttttyyyyppppeeee ((((SSSS))))
+ This parameter allows the administrator to configure
+ the string that specifies the type of filesystem a
+ share is using that is reported by ssssmmmmbbbbdddd((((8888))))
+ when a client queries the filesystem type for a share.
+ The default type is NTFS for compatibility with Windows
+ NT but this can be changed to other strings such as
+ Samba or FAT if required.
+
+ Default: ffffssssttttyyyyppppeeee ==== NNNNTTTTFFFFSSSS
+
+ Example: ffffssssttttyyyyppppeeee ==== SSSSaaaammmmbbbbaaaa
+
+ ggggeeeettttwwwwdddd ccccaaaacccchhhheeee ((((GGGG))))
+ This is a tuning option. When this is enabled a caching
+ algorithm will be used to reduce the time taken for
+ getwd() calls. This can have a significant impact on
+
+
+
+ Page 51 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ performance, especially when the _w_i_d_e _l_i_n_k_s parameter
+ is set to no.
+
+ Default: ggggeeeettttwwwwdddd ccccaaaacccchhhheeee ==== yyyyeeeessss
+
+ ggggrrrroooouuuupppp ((((SSSS))))
+ Synonym for _f_o_r_c_e _g_r_o_u_p.
+
+ gggguuuueeeesssstttt aaaaccccccccoooouuuunnnntttt ((((SSSS))))
+ This is a username which will be used for access to
+ services which are specified as _g_u_e_s_t _o_k (see below).
+ Whatever privileges this user has will be available to
+ any client connecting to the guest service. Typically
+ this user will exist in the password file, but will not
+ have a valid login. The user account "ftp" is often a
+ good choice for this parameter. If a username is
+ specified in a given service, the specified username
+ overrides this one.
+
+ One some systems the default guest account "nobody" may
+ not be able to print. Use another account in this case.
+ You should test this by trying to log in as your guest
+ user (perhaps by using the ssssuuuu ---- command) and trying to
+ print using the system print command such as llllpppprrrr((((1111)))) or
+ llllpppp((((1111)))).
+
+ Default: ssssppppeeeecccciiiiffffiiiieeeedddd aaaatttt ccccoooommmmppppiiiilllleeee ttttiiiimmmmeeee,,,, uuuussssuuuuaaaallllllllyyyy """"nnnnoooobbbbooooddddyyyy""""
+
+ Example: gggguuuueeeesssstttt aaaaccccccccoooouuuunnnntttt ==== ffffttttpppp
+
+ gggguuuueeeesssstttt ooookkkk ((((SSSS))))
+ If this parameter is yes for a service, then no
+ password is required to connect to the service.
+ Privileges will be those of the _g_u_e_s_t _a_c_c_o_u_n_t.
+
+ See the section below on _s_e_c_u_r_i_t_y for more information
+ about this option.
+
+ Default: gggguuuueeeesssstttt ooookkkk ==== nnnnoooo
+
+ gggguuuueeeesssstttt oooonnnnllllyyyy ((((SSSS))))
+ If this parameter is yes for a service, then only guest
+ connections to the service are permitted. This
+ parameter will have no effect if _g_u_e_s_t _o_k is not set
+ for the service.
+
+ See the section below on _s_e_c_u_r_i_t_y for more information
+ about this option.
+
+ Default: gggguuuueeeesssstttt oooonnnnllllyyyy ==== nnnnoooo
+
+ hhhhiiiiddddeeee ddddooootttt ffffiiiilllleeeessss ((((SSSS))))
+
+
+
+ Page 52 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ This is a boolean parameter that controls whether files
+ starting with a dot appear as hidden files.
+
+ Default: hhhhiiiiddddeeee ddddooootttt ffffiiiilllleeeessss ==== yyyyeeeessss
+
+ hhhhiiiiddddeeee ffffiiiilllleeeessss((((SSSS))))
+ This is a list of files or directories that are not
+ visible but are accessible. The DOS 'hidden' attribute
+ is applied to any files or directories that match.
+
+ Each entry in the list must be separated by a '/',
+ which allows spaces to be included in the entry. '*'
+ and '?' can be used to specify multiple files or
+ directories as in DOS wildcards.
+
+ Each entry must be a Unix path, not a DOS path and must
+ not include the Unix directory separator '/'.
+
+ Note that the case sensitivity option is applicable in
+ hiding files.
+
+ Setting this parameter will affect the performance of
+ Samba, as it will be forced to check all files and
+ directories for a match as they are scanned.
+
+ See also _h_i_d_e _d_o_t _f_i_l_e_s, _v_e_t_o _f_i_l_e_s and _c_a_s_e
+ _s_e_n_s_i_t_i_v_e.
+
+ Default: nnnnoooo ffffiiiilllleeee aaaarrrreeee hhhhiiiiddddddddeeeennnn
+
+ Example: hhhhiiiiddddeeee ffffiiiilllleeeessss ====
+ ////....****////DDDDeeeesssskkkkttttooooppppFFFFoooollllddddeeeerrrrDDDDBBBB////TTTTrrrraaaasssshhhhFFFFoooorrrr%%%%mmmm////rrrreeeessssoooouuuurrrrcccceeee....ffffrrrrkkkk////
+
+ The above example is based on files that the Macintosh
+ SMB client (DAVE) available from Thursby
+ <URL:http://www.thursby.com> creates for internal use,
+ and also still hides all files beginning with a dot.
+
+ hhhhiiiiddddeeee llllooooccccaaaallll uuuusssseeeerrrrssss((((GGGG))))
+ This parameter toggles the hiding of local UNIX users
+ (root, wheel, floppy, etc) from remote clients.
+
+ Default: hhhhiiiiddddeeee llllooooccccaaaallll uuuusssseeeerrrrssss ==== nnnnoooo
+
+ hhhhiiiiddddeeee uuuunnnnrrrreeeeaaaaddddaaaabbbblllleeee ((((SSSS))))
+ This parameter prevents clients from seeing the
+ existance of files that cannot be read. Defaults to
+ off.
+
+ Default: hhhhiiiiddddeeee uuuunnnnrrrreeeeaaaaddddaaaabbbblllleeee ==== nnnnoooo
+
+ hhhhoooommmmeeeeddddiiiirrrr mmmmaaaapppp ((((GGGG))))
+
+
+
+ Page 53 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ If_n_i_s _h_o_m_e_d_i_r is yes, and ssssmmmmbbbbdddd((((8888)))) is also acting as a
+ Win95/98 _l_o_g_o_n _s_e_r_v_e_r then this parameter specifies the
+ NIS (or YP) map from which the server for the user's
+ home directory should be extracted. At present, only
+ the Sun auto.home map format is understood. The form of
+ the map is:
+
+ uuuusssseeeerrrrnnnnaaaammmmeeee sssseeeerrrrvvvveeeerrrr::::////ssssoooommmmeeee////ffffiiiilllleeee////ssssyyyysssstttteeeemmmm
+
+ and the program will extract the servername from before
+ the first ':'. There should probably be a better
+ parsing system that copes with different map formats
+ and also Amd (another automounter) maps.
+
+ NNNNOOOOTTTTEEEE ::::A working NIS client is required on the system
+ for this option to work.
+
+ See also _n_i_s _h_o_m_e_d_i_r , _d_o_m_a_i_n _l_o_g_o_n_s .
+
+ Default: hhhhoooommmmeeeeddddiiiirrrr mmmmaaaapppp ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: hhhhoooommmmeeeeddddiiiirrrr mmmmaaaapppp ==== aaaammmmdddd....hhhhoooommmmeeeeddddiiiirrrr
+
+ hhhhoooosssstttt mmmmssssddddffffssss ((((GGGG))))
+ This boolean parameter is only available if Samba has
+ been configured and compiled with the --------wwwwiiiitttthhhh----mmmmssssddddffffssss
+ option. If set to yes, Samba will act as a Dfs server,
+ and allow Dfs-aware clients to browse Dfs trees hosted
+ on the server.
+
+ See also the _m_s_d_f_s _r_o_o_t share level parameter. For
+ more information on setting up a Dfs tree on Samba,
+ refer to msdfs_setup.html
+
+ Default: hhhhoooosssstttt mmmmssssddddffffssss ==== nnnnoooo
+
+ hhhhoooossssttttssss aaaalllllllloooowwww ((((SSSS))))
+ A synonym for this parameter is _a_l_l_o_w _h_o_s_t_s.
+
+ This parameter is a comma, space, or tab delimited set
+ of hosts which are permitted to access a service.
+
+ If specified in the [global] section then it will apply
+ to all services, regardless of whether the individual
+ service has a different setting.
+
+ You can specify the hosts by name or IP number. For
+ example, you could restrict access to only the hosts on
+ a Class C subnet with something like aaaalllllllloooowwww hhhhoooossssttttssss ====
+ 111155550000....222200003333....5555.... . The full syntax of the list is described
+ in the man page _h_o_s_t_s__a_c_c_e_s_s(_5). Note that this man
+ page may not be present on your system, so a brief
+
+
+
+ Page 54 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ description will be given here also.
+
+ Note that the localhost address 127.0.0.1 will always
+ be allowed access unless specifically denied by a _h_o_s_t_s
+ _d_e_n_y option.
+
+ You can also specify hosts by network/netmask pairs and
+ by netgroup names if your system supports netgroups.
+ The EEEEXXXXCCCCEEEEPPPPTTTT keyword can also be used to limit a wildcard
+ list. The following examples may provide some help:
+
+ Example 1: allow all IPs in 150.203.*.*; except one
+
+ hhhhoooossssttttssss aaaalllllllloooowwww ==== 111155550000....222200003333.... EEEEXXXXCCCCEEEEPPPPTTTT 111155550000....222200003333....6666....66666666
+
+ Example 2: allow hosts that match the given
+ network/netmask
+
+ hhhhoooossssttttssss aaaalllllllloooowwww ==== 111155550000....222200003333....11115555....0000////222255555555....222255555555....222255555555....0000
+
+ Example 3: allow a couple of hosts
+
+ hhhhoooossssttttssss aaaalllllllloooowwww ==== llllaaaappppllllaaaannnndddd,,,, aaaarrrrvvvviiiiddddssssjjjjaaaauuuurrrr
+
+ Example 4: allow only hosts in NIS netgroup "foonet",
+ but deny access from one particular host
+
+ hhhhoooossssttttssss aaaalllllllloooowwww ==== @@@@ffffoooooooonnnneeeetttt
+
+ hhhhoooossssttttssss ddddeeeennnnyyyy ==== ppppiiiirrrraaaatttteeee
+
+ Note that access still requires suitable user-level
+ passwords.
+
+ See tttteeeessssttttppppaaaarrrrmmmm((((1111))))
+ for a way of testing your host access to see if it
+ does what you expect.
+
+ Default: nnnnoooonnnneeee ((((iiii....eeee....,,,, aaaallllllll hhhhoooossssttttssss ppppeeeerrrrmmmmiiiitttttttteeeedddd aaaacccccccceeeessssssss))))
+
+ Example: aaaalllllllloooowwww hhhhoooossssttttssss ==== 111155550000....222200003333....5555.... mmmmyyyyhhhhoooosssstttt....mmmmyyyynnnneeeetttt....eeeedddduuuu....aaaauuuu
+
+ hhhhoooossssttttssss ddddeeeennnnyyyy ((((SSSS))))
+ The opposite of _h_o_s_t_s _a_l_l_o_w - hosts listed here are NNNNOOOOTTTT
+ permitted access to services unless the specific
+ services have their own lists to override this one.
+ Where the lists conflict, the _a_l_l_o_w list takes
+ precedence.
+
+ Default: nnnnoooonnnneeee ((((iiii....eeee....,,,, nnnnoooo hhhhoooossssttttssss ssssppppeeeecccciiiiffffiiiiccccaaaallllllllyyyy eeeexxxxcccclllluuuuddddeeeedddd))))
+
+ Example: hhhhoooossssttttssss ddddeeeennnnyyyy ==== 111155550000....222200003333....4444.... bbbbaaaaddddhhhhoooosssstttt....mmmmyyyynnnneeeetttt....eeeedddduuuu....aaaauuuu
+
+
+
+ Page 55 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ hhhhoooossssttttssss eeeeqqqquuuuiiiivvvv ((((GGGG))))
+ If this global parameter is a non-null string, it
+ specifies the name of a file to read for the names of
+ hosts and users who will be allowed access without
+ specifying a password.
+
+ This is not be confused with _h_o_s_t_s _a_l_l_o_w which is
+ about hosts access to services and is more useful for
+ guest services. _h_o_s_t_s _e_q_u_i_v may be useful for NT
+ clients which will not supply passwords to Samba.
+
+ NNNNOOOOTTTTEEEE :::: The use of _h_o_s_t_s _e_q_u_i_v can be a major security
+ hole. This is because you are trusting the PC to supply
+ the correct username. It is very easy to get a PC to
+ supply a false username. I recommend that the _h_o_s_t_s
+ _e_q_u_i_v option be only used if you really know what you
+ are doing, or perhaps on a home network where you trust
+ your spouse and kids. And only if you rrrreeeeaaaallllllllyyyy trust them
+ :-).
+
+ Default: nnnnoooo hhhhoooosssstttt eeeeqqqquuuuiiiivvvvaaaalllleeeennnncccceeeessss
+
+ Example: hhhhoooossssttttssss eeeeqqqquuuuiiiivvvv ==== ////eeeettttcccc////hhhhoooossssttttssss....eeeeqqqquuuuiiiivvvv
+
+ iiiinnnncccclllluuuuddddeeee ((((GGGG))))
+ This allows you to include one config file inside
+ another. The file is included literally, as though
+ typed in place.
+
+ It takes the standard substitutions, except %_u , %_P and
+ %_S.
+
+ Default: nnnnoooo ffffiiiilllleeee iiiinnnncccclllluuuuddddeeeedddd
+
+ Example: iiiinnnncccclllluuuuddddeeee ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////lllliiiibbbb////aaaaddddmmmmiiiinnnn____ssssmmmmbbbb....ccccoooonnnnffff
+
+ iiiinnnnhhhheeeerrrriiiitttt aaaaccccllllssss ((((SSSS))))
+ This parameter can be used to ensure that if default
+ acls exist on parent directories, they are always
+ honored when creating a subdirectory. The default
+ behavior is to use the mode specified when creating the
+ directory. Enabling this option sets the mode to 0777,
+ thus guaranteeing that default directory acls are
+ propagated.
+
+ Default: iiiinnnnhhhheeeerrrriiiitttt aaaaccccllllssss ==== nnnnoooo
+
+ iiiinnnnhhhheeeerrrriiiitttt ppppeeeerrrrmmmmiiiissssssssiiiioooonnnnssss ((((SSSS))))
+ The permissions on new files and directories are
+ normally governed by _c_r_e_a_t_e _m_a_s_k, _d_i_r_e_c_t_o_r_y _m_a_s_k,
+ _f_o_r_c_e _c_r_e_a_t_e _m_o_d_e and _f_o_r_c_e _d_i_r_e_c_t_o_r_y _m_o_d_e but the
+ boolean inherit permissions parameter overrides this.
+
+
+
+ Page 56 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ New directories inherit the mode of the parent
+ directory, including bits such as setgid.
+
+ New files inherit their read/write bits from the parent
+ directory. Their execute bits continue to be determined
+ by _m_a_p _a_r_c_h_i_v_e , _m_a_p _h_i_d_d_e_n and _m_a_p _s_y_s_t_e_m as usual.
+
+ Note that the setuid bit is nnnneeeevvvveeeerrrr set via inheritance
+ (the code explicitly prohibits this).
+
+ This can be particularly useful on large systems with
+ many users, perhaps several thousand, to allow a single
+ [homes] share to be used flexibly by each user.
+
+ See also _c_r_e_a_t_e _m_a_s_k , _d_i_r_e_c_t_o_r_y _m_a_s_k, _f_o_r_c_e _c_r_e_a_t_e
+ _m_o_d_e and _f_o_r_c_e _d_i_r_e_c_t_o_r_y _m_o_d_e .
+
+ Default: iiiinnnnhhhheeeerrrriiiitttt ppppeeeerrrrmmmmiiiissssssssiiiioooonnnnssss ==== nnnnoooo
+
+ iiiinnnntttteeeerrrrffffaaaacccceeeessss ((((GGGG))))
+ This option allows you to override the default network
+ interfaces list that Samba will use for browsing, name
+ registration and other NBT traffic. By default Samba
+ will query the kernel for the list of all active
+ interfaces and use any interfaces except 127.0.0.1 that
+ are broadcast capable.
+
+ The option takes a list of interface strings. Each
+ string can be in any of the following forms:
+
+ o+ a network interface name (such as eth0). This may
+ include shell-like wildcards so eth* will match any
+ interface starting with the substring "eth"
+
+ o+ an IP address. In this case the netmask is determined
+ from the list of interfaces obtained from the kernel
+
+ o+ an IP/mask pair.
+
+ o+ a broadcast/mask pair.
+
+ The "mask" parameters can either be a bit length (such as 24
+ for a C class network) or a full netmask in dotted decimal
+ form.
+
+ The "IP" parameters above can either be a full dotted
+ decimal IP address or a hostname which will be looked up via
+ the OS's normal hostname resolution mechanisms.
+
+ For example, the following line:
+
+ iiiinnnntttteeeerrrrffffaaaacccceeeessss ==== eeeetttthhhh0000 111199992222....111166668888....2222....11110000////22224444 111199992222....111166668888....3333....11110000////222255555555....222255555555....222255555555....0000
+
+
+
+ Page 57 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ would configure three network interfaces corresponding to
+ the eth0 device and IP addresses 192.168.2.10 and
+ 192.168.3.10. The netmasks of the latter two interfaces
+ would be set to 255.255.255.0.
+
+ See also _b_i_n_d _i_n_t_e_r_f_a_c_e_s _o_n_l_y.
+
+ Default: aaaallllllll aaaaccccttttiiiivvvveeee iiiinnnntttteeeerrrrffffaaaacccceeeessss eeeexxxxcccceeeepppptttt 111122227777....0000....0000....1111 tttthhhhaaaatttt aaaarrrreeee
+ bbbbrrrrooooaaaaddddccccaaaasssstttt ccccaaaappppaaaabbbblllleeee
+
+ iiiinnnnvvvvaaaalllliiiidddd uuuusssseeeerrrrssss ((((SSSS))))
+ This is a list of users that should not be allowed to
+ login to this service. This is really a ppppaaaarrrraaaannnnooooiiiidddd check
+ to absolutely ensure an improper setting does not
+ breach your security.
+
+ A name starting with a '@' is interpreted as an NIS
+ netgroup first (if your system supports NIS), and then
+ as a UNIX group if the name was not found in the NIS
+ netgroup database.
+
+ A name starting with '+' is interpreted only by looking
+ in the UNIX group database. A name starting with '&' is
+ interpreted only by looking in the NIS netgroup
+ database (this requires NIS to be working on your
+ system). The characters '+' and '&' may be used at the
+ start of the name in either order so the value +&_g_r_o_u_p
+ means check the UNIX group database, followed by the
+ NIS netgroup database, and the value &+_g_r_o_u_p means
+ check the NIS netgroup database, followed by the UNIX
+ group database (the same as the '@' prefix).
+
+ The current servicename is substituted for %_S. This is
+ useful in the [homes] section.
+
+ See also _v_a_l_i_d _u_s_e_r_s .
+
+ Default: nnnnoooo iiiinnnnvvvvaaaalllliiiidddd uuuusssseeeerrrrssss
+
+ Example: iiiinnnnvvvvaaaalllliiiidddd uuuusssseeeerrrrssss ==== rrrrooooooootttt ffffrrrreeeedddd aaaaddddmmmmiiiinnnn @@@@wwwwhhhheeeeeeeellll
+
+ kkkkeeeeeeeeppppaaaalllliiiivvvveeee ((((GGGG))))
+ The value of the parameter (an integer) represents the
+ number of seconds between _k_e_e_p_a_l_i_v_e packets. If this
+ parameter is zero, no keepalive packets will be sent.
+ Keepalive packets, if sent, allow the server to tell
+ whether a client is still present and responding.
+
+ Keepalives should, in general, not be needed if the
+ socket being used has the SO_KEEPALIVE attribute set on
+ it (see _s_o_c_k_e_t _o_p_t_i_o_n_s). Basically you should only use
+ this option if you strike difficulties.
+
+
+
+ Page 58 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: kkkkeeeeeeeeppppaaaalllliiiivvvveeee ==== 333300000000
+
+ Example: kkkkeeeeeeeeppppaaaalllliiiivvvveeee ==== 666600000000
+
+ kkkkeeeerrrrnnnneeeellll oooopppplllloooocccckkkkssss ((((GGGG))))
+ For UNIXes that support kernel based _o_p_l_o_c_k_s (currently
+ only IRIX and the Linux 2.4 kernel), this parameter
+ allows the use of them to be turned on or off.
+
+ Kernel oplocks support allows Samba _o_p_l_o_c_k_s to be
+ broken whenever a local UNIX process or NFS operation
+ accesses a file that ssssmmmmbbbbdddd((((8888))))
+ has oplocked. This allows complete data consistency
+ between SMB/CIFS, NFS and local file access (and is a
+ vvvveeeerrrryyyy cool feature :-).
+
+ This parameter defaults to on, but is translated to a
+ no-op on systems that no not have the necessary kernel
+ support. You should never need to touch this
+ parameter.
+
+ See also the _o_p_l_o_c_k_s and _l_e_v_e_l_2 _o_p_l_o_c_k_s parameters.
+
+ Default: kkkkeeeerrrrnnnneeeellll oooopppplllloooocccckkkkssss ==== yyyyeeeessss
+
+ llllaaaannnnmmmmaaaannnn aaaauuuutttthhhh ((((GGGG))))
+ This parameter determines whether or not smbd will
+ attempt to authenticate users using the LANMAN password
+ hash. If disabled, only clients which support NT
+ password hashes (e.g. Windows NT/2000 clients,
+ smbclient, etc... but not Windows 95/98 or the MS DOS
+ network client) will be able to connect to the Samba
+ host.
+
+ Default : llllaaaannnnmmmmaaaannnn aaaauuuutttthhhh ==== yyyyeeeessss
+
+ llllaaaarrrrggggeeee rrrreeeeaaaaddddwwwwrrrriiiitttteeee ((((GGGG))))
+ This parameter determines whether or not smbd supports
+ the new 64k streaming read and write varient SMB
+ requests introduced with Windows 2000. Note that due to
+ Windows 2000 client redirector bugs this requires Samba
+ to be running on a 64-bit capable operating system such
+ as IRIX, Solaris or a Linux 2.4 kernel. Can improve
+ performance by 10% with Windows 2000 clients. Defaults
+ to on. Windows NT 4.0 only supports read version of
+ this call, and ignores the write version.
+
+ Default : llllaaaarrrrggggeeee rrrreeeeaaaaddddwwwwrrrriiiitttteeee ==== yyyyeeeessss
+
+ llllddddaaaapppp aaaaddddmmmmiiiinnnn ddddnnnn ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+
+
+
+ Page 59 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ compile time. This option should be considered
+ experimental and under active development.
+
+ The _l_d_a_p _a_d_m_i_n _d_n defines the Distinguished Name (DN)
+ name used by Samba to contact the ldap server when
+ retreiving user account information. The _l_d_a_p _a_d_m_i_n _d_n
+ is used in conjunction with the admin dn password
+ stored in the _p_r_i_v_a_t_e/_s_e_c_r_e_t_s._t_d_b file. See the
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888)))) man page for more information on how to
+ accmplish this.
+
+ Default : nnnnoooonnnneeee
+
+ llllddddaaaapppp ffffiiiilllltttteeeerrrr ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+ compile time. This option should be considered
+ experimental and under active development.
+
+ This parameter specifies the RFC 2254 compliant LDAP
+ search filter. The default is to match the login name
+ with the uid attribute for all entries matching the
+ sambaAccount objectclass. Note that this filter should
+ only return one entry.
+
+ Default : llllddddaaaapppp ffffiiiilllltttteeeerrrr ====
+ ((((&&&&((((uuuuiiiidddd====%%%%uuuu))))((((oooobbbbjjjjeeeeccccttttccccllllaaaassssssss====ssssaaaammmmbbbbaaaaAAAAccccccccoooouuuunnnntttt))))))))
+
+ llllddddaaaapppp ppppoooorrrrtttt ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+ compile time. This option should be considered
+ experimental and under active development.
+
+ This option is used to control the tcp port number used
+ to contact the _l_d_a_p _s_e_r_v_e_r. The default is to use the
+ stand LDAPS port 636.
+
+ See Also: ldap ssl
+
+ Default : llllddddaaaapppp ppppoooorrrrtttt ==== 666633336666 ;;;; iiiiffff llllddddaaaapppp ssssssssllll ==== oooonnnn
+
+ Default : llllddddaaaapppp ppppoooorrrrtttt ==== 333388889999 ;;;; iiiiffff llllddddaaaapppp ssssssssllll ==== ooooffffffff
+
+ llllddddaaaapppp sssseeeerrrrvvvveeeerrrr ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+ compile time. This option should be considered
+ experimental and under active development.
+
+ This parameter should contains the FQDN of the ldap
+ directory server which should be queried to locate user
+
+
+
+ Page 60 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ account information.
+
+ Default : llllddddaaaapppp sssseeeerrrrvvvveeeerrrr ==== llllooooccccaaaallllhhhhoooosssstttt
+
+ llllddddaaaapppp ssssssssllll ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+ compile time. This option should be considered
+ experimental and under active development.
+
+ This option is used to define whether or not Samba
+ should use SSL when connecting to the _l_d_a_p _s_e_r_v_e_r. This
+ is NNNNOOOOTTTT related to Samba SSL support which is enabled by
+ specifying the --------wwwwiiiitttthhhh----ssssssssllll option to the _c_o_n_f_i_g_u_r_e
+ script (see _s_s_l).
+
+ The _l_d_a_p _s_s_l can be set to one of three values: (a) on
+ - Always use SSL when contacting the _l_d_a_p _s_e_r_v_e_r, (b)
+ off - Never use SSL when querying the directory, or (c)
+ start_tls - Use the LDAPv3 StartTLS extended operation
+ (RFC2830) for communicating with the directory server.
+
+ Default : llllddddaaaapppp ssssssssllll ==== oooonnnn
+
+ llllddddaaaapppp ssssuuuuffffffffiiiixxxx ((((GGGG))))
+ This parameter is only available if Samba has been
+ configure to include the --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm option at
+ compile time. This option should be considered
+ experimental and under active development.
+
+ Default : nnnnoooonnnneeee
+
+ lllleeeevvvveeeellll2222 oooopppplllloooocccckkkkssss ((((SSSS))))
+ This parameter controls whether Samba supports level2
+ (read-only) oplocks on a share.
+
+ Level2, or read-only oplocks allow Windows NT clients
+ that have an oplock on a file to downgrade from a
+ read-write oplock to a read-only oplock once a second
+ client opens the file (instead of releasing all oplocks
+ on a second open, as in traditional, exclusive
+ oplocks). This allows all openers of the file that
+ support level2 oplocks to cache the file for read-ahead
+ only (ie. they may not cache writes or lock requests)
+ and increases performance for many accesses of files
+ that are not commonly written (such as application .EXE
+ files).
+
+ Once one of the clients which have a read-only oplock
+ writes to the file all clients are notified (no reply
+ is needed or waited for) and told to break their
+ oplocks to "none" and delete any read-ahead caches.
+
+
+
+ Page 61 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ It is recommended that this parameter be turned on to
+ speed access to shared executables.
+
+ For more discussions on level2 oplocks see the CIFS
+ spec.
+
+ Currently, if _k_e_r_n_e_l _o_p_l_o_c_k_s are supported then level2
+ oplocks are not granted (even if this parameter is set
+ to yes). Note also, the _o_p_l_o_c_k_s parameter must be set
+ to yes on this share in order for this parameter to
+ have any effect.
+
+ See also the _o_p_l_o_c_k_s and _k_e_r_n_e_l _o_p_l_o_c_k_s parameters.
+
+ Default: lllleeeevvvveeeellll2222 oooopppplllloooocccckkkkssss ==== yyyyeeeessss
+
+ llllmmmm aaaannnnnnnnoooouuuunnnncccceeee ((((GGGG))))
+ This parameter determines if nnnnmmmmbbbbdddd((((8888)))) will produce
+ Lanman announce broadcasts that are needed by OS/2
+ clients in order for them to see the Samba server in
+ their browse list. This parameter can have three
+ values, yes, no, or auto. The default is auto. If set
+ to no Samba will never produce these broadcasts. If set
+ to yes Samba will produce Lanman announce broadcasts at
+ a frequency set by the parameter _l_m _i_n_t_e_r_v_a_l. If set to
+ auto Samba will not send Lanman announce broadcasts by
+ default but will listen for them. If it hears such a
+ broadcast on the wire it will then start sending them
+ at a frequency set by the parameter _l_m _i_n_t_e_r_v_a_l.
+
+ See also _l_m _i_n_t_e_r_v_a_l .
+
+ Default: llllmmmm aaaannnnnnnnoooouuuunnnncccceeee ==== aaaauuuuttttoooo
+
+ Example: llllmmmm aaaannnnnnnnoooouuuunnnncccceeee ==== yyyyeeeessss
+
+ llllmmmm iiiinnnntttteeeerrrrvvvvaaaallll ((((GGGG))))
+ If Samba is set to produce Lanman announce broadcasts
+ needed by OS/2 clients (see the _l_m _a_n_n_o_u_n_c_e parameter)
+ then this parameter defines the frequency in seconds
+ with which they will be made. If this is set to zero
+ then no Lanman announcements will be made despite the
+ setting of the _l_m _a_n_n_o_u_n_c_e parameter.
+
+ See also _l_m _a_n_n_o_u_n_c_e.
+
+ Default: llllmmmm iiiinnnntttteeeerrrrvvvvaaaallll ==== 66660000
+
+ Example: llllmmmm iiiinnnntttteeeerrrrvvvvaaaallll ==== 111122220000
+
+ llllooooaaaadddd pppprrrriiiinnnntttteeeerrrrssss ((((GGGG))))
+ A boolean variable that controls whether all printers
+
+
+
+ Page 62 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ in the printcap will be loaded for browsing by default.
+ See the printers section for more details.
+
+ Default: llllooooaaaadddd pppprrrriiiinnnntttteeeerrrrssss ==== yyyyeeeessss
+
+ llllooooccccaaaallll mmmmaaaasssstttteeeerrrr ((((GGGG))))
+ This option allows nnnnmmmmbbbbdddd((((8888)))) to try and become a local
+ master browser on a subnet. If set to no then nnnnmmmmbbbbdddd
+ will not attempt to become a local master browser on a
+ subnet and will also lose in all browsing elections. By
+ default this value is set to yes. Setting this value to
+ yes doesn't mean that Samba will bbbbeeeeccccoooommmmeeee the local
+ master browser on a subnet, just that nnnnmmmmbbbbdddd will
+ ppppaaaarrrrttttiiiicccciiiippppaaaatttteeee in elections for local master browser.
+
+ Setting this value to no will cause nnnnmmmmbbbbdddd nnnneeeevvvveeeerrrr to
+ become a local master browser.
+
+ Default: llllooooccccaaaallll mmmmaaaasssstttteeeerrrr ==== yyyyeeeessss
+
+ lllloooocccckkkk ddddiiiirrrr ((((GGGG))))
+ Synonym for _l_o_c_k _d_i_r_e_c_t_o_r_y.
+
+ lllloooocccckkkk ddddiiiirrrreeeeccccttttoooorrrryyyy ((((GGGG))))
+ This option specifies the directory where lock files
+ will be placed. The lock files are used to implement
+ the _m_a_x _c_o_n_n_e_c_t_i_o_n_s option.
+
+ Default: lllloooocccckkkk ddddiiiirrrreeeeccccttttoooorrrryyyy ==== $$$${{{{pppprrrreeeeffffiiiixxxx}}}}////vvvvaaaarrrr////lllloooocccckkkkssss
+
+ Example: lllloooocccckkkk ddddiiiirrrreeeeccccttttoooorrrryyyy ==== ////vvvvaaaarrrr////rrrruuuunnnn////ssssaaaammmmbbbbaaaa////lllloooocccckkkkssss
+
+ lllloooocccckkkk ssssppppiiiinnnn ccccoooouuuunnnntttt ((((GGGG))))
+ This parameter controls the number of times that smbd
+ should attempt to gain a byte range lock on the behalf
+ of a client request. Experiments have shown that
+ Windows 2k servers do not reply with a failure if the
+ lock could not be immediately granted, but try a few
+ more times in case the lock could later be aquired.
+ This behavior is used to support PC database formats
+ such as MS Access and FoxPro.
+
+ Default: lllloooocccckkkk ssssppppiiiinnnn ccccoooouuuunnnntttt ==== 2222
+
+ lllloooocccckkkk ssssppppiiiinnnn ttttiiiimmmmeeee ((((GGGG))))
+ The time in microseconds that smbd should pause before
+ attempting to gain a failed lock. See _l_o_c_k _s_p_i_n _c_o_u_n_t
+ for more details.
+
+ Default: lllloooocccckkkk ssssppppiiiinnnn ttttiiiimmmmeeee ==== 11110000
+
+ lllloooocccckkkkiiiinnnngggg ((((SSSS))))
+
+
+
+ Page 63 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ This controls whether or not locking will be performed
+ by the server in response to lock requests from the
+ client.
+
+ If lllloooocccckkkkiiiinnnngggg ==== nnnnoooo, all lock and unlock requests will
+ appear to succeed and all lock queries will report that
+ the file in question is available for locking.
+
+ If lllloooocccckkkkiiiinnnngggg ==== yyyyeeeessss, real locking will be performed by the
+ server.
+
+ This option mmmmaaaayyyy be useful for read-only filesystems
+ which mmmmaaaayyyy not need locking (such as CDROM drives),
+ although setting this parameter of no is not really
+ recommended even in this case.
+
+ Be careful about disabling locking either globally or
+ in a specific service, as lack of locking may result in
+ data corruption. You should never need to set this
+ parameter.
+
+ Default: lllloooocccckkkkiiiinnnngggg ==== yyyyeeeessss
+
+ lllloooogggg ffffiiiilllleeee ((((GGGG))))
+ This option allows you to override the name of the
+ Samba log file (also known as the debug file).
+
+ This option takes the standard substitutions, allowing
+ you to have separate log files for each user or
+ machine.
+
+ Example: lllloooogggg ffffiiiilllleeee ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////vvvvaaaarrrr////lllloooogggg....%%%%mmmm
+
+ lllloooogggg lllleeeevvvveeeellll ((((GGGG))))
+ The value of the parameter (an integer) allows the
+ debug level (logging level) to be specified in the
+ _s_m_b._c_o_n_f file. This is to give greater flexibility in
+ the configuration of the system.
+
+ The default will be the log level specified on the
+ command line or level zero if none was specified.
+
+ Example: lllloooogggg lllleeeevvvveeeellll ==== 3333
+
+ llllooooggggoooonnnn ddddrrrriiiivvvveeee ((((GGGG))))
+ This parameter specifies the local path to which the
+ home directory will be connected (see _l_o_g_o_n _h_o_m_e) and
+ is only used by NT Workstations.
+
+ Note that this option is only useful if Samba is set up
+ as a logon server.
+
+
+
+
+ Page 64 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: llllooooggggoooonnnn ddddrrrriiiivvvveeee ==== zzzz::::
+
+ Example: llllooooggggoooonnnn ddddrrrriiiivvvveeee ==== hhhh::::
+
+ llllooooggggoooonnnn hhhhoooommmmeeee ((((GGGG))))
+ This parameter specifies the home directory location
+ when a Win95/98 or NT Workstation logs into a Samba
+ PDC. It allows you to do
+
+ C:\> NNNNEEEETTTT UUUUSSSSEEEE HHHH:::: ////HHHHOOOOMMMMEEEE
+
+ from a command prompt, for example.
+
+ This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or
+ machine.
+
+ This parameter can be used with Win9X workstations to
+ ensure that roaming profiles are stored in a
+ subdirectory of the user's home directory. This is done
+ in the following way:
+
+ llllooooggggoooonnnn hhhhoooommmmeeee ==== \\\\\\\\%%%%NNNN\\\\%%%%UUUU\\\\pppprrrrooooffffiiiilllleeee
+
+ This tells Samba to return the above string, with
+ substitutions made when a client requests the info,
+ generally in a NetUserGetInfo request. Win9X clients
+ truncate the info to \\server\share when a user does
+ nnnneeeetttt uuuusssseeee ////hhhhoooommmmeeee but use the whole string when dealing
+ with profiles.
+
+ Note that in prior versions of Samba, the _l_o_g_o_n _p_a_t_h
+ was returned rather than _l_o_g_o_n _h_o_m_e. This broke nnnneeeetttt uuuusssseeee
+ ////hhhhoooommmmeeee but allowed profiles outside the home directory.
+ The current implementation is correct, and can be used
+ for profiles if you use the above trick.
+
+ This option is only useful if Samba is set up as a
+ logon server.
+
+ Default: llllooooggggoooonnnn hhhhoooommmmeeee ==== """"\\\\\\\\%%%%NNNN\\\\%%%%UUUU""""
+
+ Example: llllooooggggoooonnnn hhhhoooommmmeeee ==== """"\\\\\\\\rrrreeeemmmmooootttteeee____ssssmmmmbbbb____sssseeeerrrrvvvveeeerrrr\\\\%%%%UUUU""""
+
+ llllooooggggoooonnnn ppppaaaatttthhhh ((((GGGG))))
+ This parameter specifies the home directory where
+ roaming profiles (NTuser.dat etc files for Windows NT)
+ are stored. Contrary to previous versions of these
+ manual pages, it has nothing to do with Win 9X roaming
+ profiles. To find out how to handle roaming profiles
+ for Win 9X system, see the _l_o_g_o_n _h_o_m_e parameter.
+
+
+
+
+ Page 65 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or
+ machine. It also specifies the directory from which the
+ "Application Data", (_d_e_s_k_t_o_p, _s_t_a_r_t _m_e_n_u, _n_e_t_w_o_r_k
+ _n_e_i_g_h_b_o_r_h_o_o_d, _p_r_o_g_r_a_m_s and other folders, and their
+ contents, are loaded and displayed on your Windows NT
+ client.
+
+ The share and the path must be readable by the user for
+ the preferences and directories to be loaded onto the
+ Windows NT client. The share must be writeable when the
+ user logs in for the first time, in order that the
+ Windows NT client can create the NTuser.dat and other
+ directories.
+
+ Thereafter, the directories and any of the contents
+ can, if required, be made read-only. It is not
+ advisable that the NTuser.dat file be made read-only -
+ rename it to NTuser.man to achieve the desired effect
+ (a MMMMAAAANNNNdatory profile).
+
+ Windows clients can sometimes maintain a connection to
+ the [homes] share, even though there is no user logged
+ in. Therefore, it is vital that the logon path does not
+ include a reference to the homes share (i.e. setting
+ this parameter to \%N\%U\profile_path will cause
+ problems).
+
+ This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or
+ machine.
+
+ Note that this option is only useful if Samba is set up
+ as a logon server.
+
+ Default: llllooooggggoooonnnn ppppaaaatttthhhh ==== \\\\\\\\%%%%NNNN\\\\%%%%UUUU\\\\pppprrrrooooffffiiiilllleeee
+
+ Example: llllooooggggoooonnnn ppppaaaatttthhhh ==== \\\\\\\\PPPPRRRROOOOFFFFIIIILLLLEEEESSSSEEEERRRRVVVVEEEERRRR\\\\PPPPRRRROOOOFFFFIIIILLLLEEEE\\\\%%%%UUUU
+
+ llllooooggggoooonnnn ssssccccrrrriiiipppptttt ((((GGGG))))
+ This parameter specifies the batch file (.bat) or NT
+ command file (.cmd) to be downloaded and run on a
+ machine when a user successfully logs in. The file must
+ contain the DOS style CR/LF line endings. Using a DOS-
+ style editor to create the file is recommended.
+
+ The script must be a relative path to the [netlogon]
+ service. If the [netlogon] service specifies a _p_a_t_h of
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_n_e_t_l_o_g_o_n , and llllooooggggoooonnnn ssssccccrrrriiiipppptttt ====
+ SSSSTTTTAAAARRRRTTTTUUUUPPPP....BBBBAAAATTTT, then the file that will be downloaded is:
+
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_n_e_t_l_o_g_o_n/_S_T_A_R_T_U_P._B_A_T
+
+
+
+ Page 66 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The contents of the batch file are entirely your
+ choice. A suggested command would be to add NNNNEEEETTTT TTTTIIIIMMMMEEEE
+ \\\\\\\\SSSSEEEERRRRVVVVEEEERRRR ////SSSSEEEETTTT ////YYYYEEEESSSS, to force every machine to
+ synchronize clocks with the same time server. Another
+ use would be to add NNNNEEEETTTT UUUUSSSSEEEE UUUU:::: \\\\\\\\SSSSEEEERRRRVVVVEEEERRRR\\\\UUUUTTTTIIIILLLLSSSS for
+ commonly used utilities, or NNNNEEEETTTT UUUUSSSSEEEE QQQQ::::
+ \\\\\\\\SSSSEEEERRRRVVVVEEEERRRR\\\\IIIISSSSOOOO9999000000001111____QQQQAAAA for example.
+
+ Note that it is particularly important not to allow
+ write access to the [netlogon] share, or to grant users
+ write permission on the batch files in a secure
+ environment, as this would allow the batch files to be
+ arbitrarily modified and security to be breached.
+
+ This option takes the standard substitutions, allowing
+ you to have separate logon scripts for each user or
+ machine.
+
+ This option is only useful if Samba is set up as a
+ logon server.
+
+ Default: nnnnoooo llllooooggggoooonnnn ssssccccrrrriiiipppptttt ddddeeeeffffiiiinnnneeeedddd
+
+ Example: llllooooggggoooonnnn ssssccccrrrriiiipppptttt ==== ssssccccrrrriiiippppttttssss\\\\%%%%UUUU....bbbbaaaatttt
+
+ llllppppppppaaaauuuusssseeee ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to stop printing or spooling a
+ specific print job.
+
+ This command should be a program or script which takes
+ a printer name and job number to pause the print job.
+ One way of implementing this is by using job
+ priorities, where jobs having a too low priority won't
+ be sent to the printer.
+
+ If a %_p is given then the printer name is put in its
+ place. A %_j is replaced with the job number (an
+ integer). On HPUX (see _p_r_i_n_t_i_n_g=_h_p_u_x ), if the -_p%_p
+ option is added to the lpq command, the job will show
+ up with the correct status, i.e. if the job priority is
+ lower than the set fence priority it will have the
+ PAUSED status, whereas if the priority is equal or
+ higher it will have the SPOOLED or PRINTING status.
+
+ Note that it is good practice to include the absolute
+ path in the lppause command as the PATH may not be
+ available to the server.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: Currently no default value is given to this
+
+
+
+ Page 67 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ string, unless the value of the _p_r_i_n_t_i_n_g parameter is
+ SYSV, in which case the default is :
+
+ llllpppp ----iiii %%%%pppp----%%%%jjjj ----HHHH hhhhoooolllldddd
+
+ or if the value of the _p_r_i_n_t_i_n_g parameter is SOFTQ,
+ then the default is:
+
+ qqqqssssttttaaaatttt ----ssss ----jjjj%%%%jjjj ----hhhh
+
+ Example for HPUX: llllppppppppaaaauuuusssseeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////llllppppaaaalllltttt %%%%pppp----
+ %%%%jjjj ----pppp0000
+
+ llllppppqqqq ccccaaaacccchhhheeee ttttiiiimmmmeeee ((((GGGG))))
+ This controls how long lpq info will be cached for to
+ prevent the llllppppqqqq command being called too often. A
+ separate cache is kept for each variation of the llllppppqqqq
+ command used by the system, so if you use different llllppppqqqq
+ commands for different users then they won't share
+ cache information.
+
+ The cache files are stored in /_t_m_p/_l_p_q._x_x_x_x where xxxx
+ is a hash of the llllppppqqqq command in use.
+
+ The default is 10 seconds, meaning that the cached
+ results of a previous identical llllppppqqqq command will be
+ used if the cached data is less than 10 seconds old. A
+ large value may be advisable if your llllppppqqqq command is
+ very slow.
+
+ A value of 0 will disable caching completely.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: llllppppqqqq ccccaaaacccchhhheeee ttttiiiimmmmeeee ==== 11110000
+
+ Example: llllppppqqqq ccccaaaacccchhhheeee ttttiiiimmmmeeee ==== 33330000
+
+ llllppppqqqq ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to obtain llllppppqqqq -style printer
+ status information.
+
+ This command should be a program or script which takes
+ a printer name as its only parameter and outputs
+ printer status information.
+
+ Currently nine styles of printer status information are
+ supported; BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, CUPS,
+ and SOFTQ. This covers most UNIX systems. You control
+ which type is expected using the _p_r_i_n_t_i_n_g = option.
+
+
+
+
+ Page 68 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Some clients (notably Windows for Workgroups) may not
+ correctly send the connection number for the printer
+ they are requesting status information about. To get
+ around this, the server reports on the first printer
+ service connected to by the client. This only happens
+ if the connection number sent is invalid.
+
+ If a %_p is given then the printer name is put in its
+ place. Otherwise it is placed at the end of the
+ command.
+
+ Note that it is good practice to include the absolute
+ path in the _l_p_q _c_o_m_m_a_n_d as the $$$$PPPPAAAATTTTHHHH may not be
+ available to the server. When compiled with the CUPS
+ libraries, no _l_p_q _c_o_m_m_a_n_d is needed because smbd will
+ make a library call to obtain the print queue listing.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: ddddeeeeppppeeeennnnddddssss oooonnnn tttthhhheeee sssseeeettttttttiiiinnnngggg ooooffff _p_r_i_n_t_i_n_g
+
+ Example: llllppppqqqq ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////llllppppqqqq ----PPPP%%%%pppp
+
+ llllpppprrrreeeessssuuuummmmeeee ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to restart or continue
+ printing or spooling a specific print job.
+
+ This command should be a program or script which takes
+ a printer name and job number to resume the print job.
+ See also the _l_p_p_a_u_s_e _c_o_m_m_a_n_d parameter.
+
+ If a %_p is given then the printer name is put in its
+ place. A %_j is replaced with the job number (an
+ integer).
+
+ Note that it is good practice to include the absolute
+ path in the _l_p_r_e_s_u_m_e _c_o_m_m_a_n_d as the PATH may not be
+ available to the server.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: Currently no default value is given to this
+ string, unless the value of the _p_r_i_n_t_i_n_g parameter is
+ SYSV, in which case the default is :
+
+ llllpppp ----iiii %%%%pppp----%%%%jjjj ----HHHH rrrreeeessssuuuummmmeeee
+
+ or if the value of the _p_r_i_n_t_i_n_g parameter is SOFTQ,
+ then the default is:
+
+ qqqqssssttttaaaatttt ----ssss ----jjjj%%%%jjjj ----rrrr
+
+
+
+ Page 69 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Example for HPUX: llllpppprrrreeeessssuuuummmmeeee ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////llllppppaaaalllltttt
+ %%%%pppp----%%%%jjjj ----pppp2222
+
+ llllpppprrrrmmmm ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to delete a print job.
+
+ This command should be a program or script which takes
+ a printer name and job number, and deletes the print
+ job.
+
+ If a %_p is given then the printer name is put in its
+ place. A %_j is replaced with the job number (an
+ integer).
+
+ Note that it is good practice to include the absolute
+ path in the _l_p_r_m _c_o_m_m_a_n_d as the PATH may not be
+ available to the server.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: ddddeeeeppppeeeennnnddddssss oooonnnn tttthhhheeee sssseeeettttttttiiiinnnngggg ooooffff _p_r_i_n_t_i_n_g
+
+ Example 1: llllpppprrrrmmmm ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////llllpppprrrrmmmm ----PPPP%%%%pppp %%%%jjjj
+
+ Example 2: llllpppprrrrmmmm ccccoooommmmmmmmaaaannnndddd ==== ////uuuussssrrrr////bbbbiiiinnnn////ccccaaaannnncccceeeellll %%%%pppp----%%%%jjjj
+
+ mmmmaaaacccchhhhiiiinnnneeee ppppaaaasssssssswwwwoooorrrrdddd ttttiiiimmmmeeeeoooouuuutttt ((((GGGG))))
+ If a Samba server is a member of a Windows NT Domain
+ (see the security = domain) parameter) then
+ periodically a running smbd(8) process will try and
+ change the MACHINE ACCOUNT PASSWORD stored in the TDB
+ called _p_r_i_v_a_t_e/_s_e_c_r_e_t_s._t_d_b . This parameter specifies
+ how often this password will be changed, in seconds.
+ The default is one week (expressed in seconds), the
+ same as a Windows NT Domain member server.
+
+ See also ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888))))
+ and the security = domain) parameter.
+
+ Default: mmmmaaaacccchhhhiiiinnnneeee ppppaaaasssssssswwwwoooorrrrdddd ttttiiiimmmmeeeeoooouuuutttt ==== 666600004444888800000000
+
+ mmmmaaaaggggiiiicccc oooouuuuttttppppuuuutttt ((((SSSS))))
+ This parameter specifies the name of a file which will
+ contain output created by a magic script (see the _m_a_g_i_c
+ _s_c_r_i_p_t parameter below).
+
+ Warning: If two clients use the same _m_a_g_i_c _s_c_r_i_p_t in
+ the same directory the output file content is
+ undefined.
+
+ Default: mmmmaaaaggggiiiicccc oooouuuuttttppppuuuutttt ==== <<<<mmmmaaaaggggiiiicccc ssssccccrrrriiiipppptttt nnnnaaaammmmeeee>>>>....oooouuuutttt
+
+
+
+ Page 70 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Example: mmmmaaaaggggiiiicccc oooouuuuttttppppuuuutttt ==== mmmmyyyyffffiiiilllleeee....ttttxxxxtttt
+
+ mmmmaaaaggggiiiicccc ssssccccrrrriiiipppptttt ((((SSSS))))
+ This parameter specifies the name of a file which, if
+ opened, will be executed by the server when the file is
+ closed. This allows a UNIX script to be sent to the
+ Samba host and executed on behalf of the connected
+ user.
+
+ Scripts executed in this way will be deleted upon
+ completion assuming that the user has the appropriate
+ level of privilege and the file permissions allow the
+ deletion.
+
+ If the script generates output, output will be sent to
+ the file specified by the _m_a_g_i_c _o_u_t_p_u_t parameter (see
+ above).
+
+ Note that some shells are unable to interpret scripts
+ containing CR/LF instead of CR as the end-of-line
+ marker. Magic scripts must be executable aaaassss iiiissss on the
+ host, which for some hosts and some shells will require
+ filtering at the DOS end.
+
+ Magic scripts are EEEEXXXXPPPPEEEERRRRIIIIMMMMEEEENNNNTTTTAAAALLLL and should NNNNOOOOTTTT be relied
+ upon.
+
+ Default: NNNNoooonnnneeee.... MMMMaaaaggggiiiicccc ssssccccrrrriiiippppttttssss ddddiiiissssaaaabbbblllleeeedddd....
+
+ Example: mmmmaaaaggggiiiicccc ssssccccrrrriiiipppptttt ==== uuuusssseeeerrrr....ccccsssshhhh
+
+ mmmmaaaannnngggglllleeee ccccaaaasssseeee ((((SSSS))))
+ See the section on NAME MANGLING
+
+ Default: mmmmaaaannnngggglllleeee ccccaaaasssseeee ==== nnnnoooo
+
+ mmmmaaaannnngggglllleeeedddd mmmmaaaapppp ((((SSSS))))
+ This is for those who want to directly map UNIX file
+ names which cannot be represented on Windows/DOS. The
+ mangling of names is not always what is needed. In
+ particular you may have documents with file extensions
+ that differ between DOS and UNIX. For example, under
+ UNIX it is common to use ._h_t_m_l for HTML files, whereas
+ under Windows/DOS ._h_t_m is more commonly used.
+
+ So to map _h_t_m_l to _h_t_m you would use:
+
+ mmmmaaaannnngggglllleeeedddd mmmmaaaapppp ==== ((((****....hhhhttttmmmmllll ****....hhhhttttmmmm))))
+
+ One very useful case is to remove the annoying ;_1 off
+ the ends of filenames on some CDROMs (only visible
+ under some UNIXes). To do this use a map of (*;1 *;).
+
+
+
+ Page 71 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: nnnnoooo mmmmaaaannnngggglllleeeedddd mmmmaaaapppp
+
+ Example: mmmmaaaannnngggglllleeeedddd mmmmaaaapppp ==== ((((****;;;;1111 ****;;;;))))
+
+ mmmmaaaannnngggglllleeeedddd nnnnaaaammmmeeeessss ((((SSSS))))
+ This controls whether non-DOS names under UNIX should
+ be mapped to DOS-compatible names ("mangled") and made
+ visible, or whether non-DOS names should simply be
+ ignored.
+
+ See the section on NAME MANGLING for details on how to
+ control the mangling process.
+
+ If mangling algorithm "hash" is used then the mangling
+ algorithm is as follows:
+
+ o+ The first (up to) five alphanumeric characters before
+ the rightmost dot of the filename are preserved,
+ forced to upper case, and appear as the first (up to)
+ five characters of the mangled name.
+
+ o+ A tilde "~" is appended to the first part of the
+ mangled name, followed by a two-character unique
+ sequence, based on the original root name (i.e., the
+ original filename minus its final extension). The
+ final extension is included in the hash calculation
+ only if it contains any upper case characters or is
+ longer than three characters.
+
+ Note that the character to use may be specified using
+ the _m_a_n_g_l_i_n_g _c_h_a_r option, if you don't like '~'.
+
+ o+ The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and
+ appear as the extension of the mangled name. The
+ final extension is defined as that part of the
+ original filename after the rightmost dot. If there
+ are no dots in the filename, the mangled name will
+ have no extension (except in the case of "hidden
+ files" - see below).
+
+ o+ Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will
+ be created as for other filenames, but with the
+ leading dot removed and "___" as its extension
+ regardless of actual original extension (that's three
+ underscores).
+
+ The two-digit hash value consists of upper case alphanumeric
+ characters.
+
+ This algorithm can cause name collisions only if files in a
+
+
+
+ Page 72 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ directory share the same first five alphanumeric characters.
+ The probability of such a clash is 1/1300.
+
+ If mangling algorithm "hash2" is used then the mangling
+ algorithm is as follows:
+
+ o+ The first alphanumeric character before the rightmost
+ dot of the filename is preserved, forced to upper
+ case, and appears as the first character of the
+ mangled name.
+
+ o+ A base63 hash of 5 characters is generated and the
+ first 4 characters of that hash are appended to the
+ first character.
+
+ o+ A tilde "~" is appended to the first part of the
+ mangled name, followed by the final character of the
+ base36 hash of the name.
+
+ Note that the character to use may be specified using
+ the _m_a_n_g_l_i_n_g _c_h_a_r option, if you don't like '~'.
+
+ o+ The first three alphanumeric characters of the final
+ extension are preserved, forced to upper case and
+ appear as the extension of the mangled name. The
+ final extension is defined as that part of the
+ original filename after the rightmost dot. If there
+ are no dots in the filename, the mangled name will
+ have no extension (except in the case of "hidden
+ files" - see below).
+
+ o+ Files whose UNIX name begins with a dot will be
+ presented as DOS hidden files. The mangled name will
+ be created as for other filenames, but with the
+ leading dot removed and "___" as its extension
+ regardless of actual original extension (that's three
+ underscores).
+
+ The name mangling (if enabled) allows a file to be copied
+ between UNIX directories from Windows/DOS while retaining
+ the long UNIX filename. UNIX files can be renamed to a new
+ extension from Windows/DOS and will retain the same
+ basename. Mangled names do not change between sessions.
+
+ Default: mmmmaaaannnngggglllleeeedddd nnnnaaaammmmeeeessss ==== yyyyeeeessss
+
+ mmmmaaaannnngggglllleeeedddd ssssttttaaaacccckkkk ((((GGGG))))
+ This parameter controls the number of mangled names
+ that should be cached in the Samba server smbd(8)
+
+ This stack is a list of recently mangled base names
+ (extensions are only maintained if they are longer than
+
+
+
+ Page 73 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ 3 characters or contains upper case characters).
+
+ The larger this value, the more likely it is that
+ mangled names can be successfully converted to correct
+ long UNIX names. However, large stack sizes will slow
+ most directory accesses. Smaller stacks save memory in
+ the server (each stack element costs 256 bytes).
+
+ It is not possible to absolutely guarantee correct long
+ filenames, so be prepared for some surprises!
+
+ Default: mmmmaaaannnngggglllleeeedddd ssssttttaaaacccckkkk ==== 55550000
+
+ Example: mmmmaaaannnngggglllleeeedddd ssssttttaaaacccckkkk ==== 111100000000
+
+ mmmmaaaannnngggglllliiiinnnngggg cccchhhhaaaarrrr ((((SSSS))))
+ This controls what character is used as the mmmmaaaaggggiiiicccc
+ character in name mangling. The default is a '~' but
+ this may interfere with some software. Use this option
+ to set it to whatever you prefer.
+
+ Default: mmmmaaaannnngggglllliiiinnnngggg cccchhhhaaaarrrr ==== ~~~~
+
+ Example: mmmmaaaannnngggglllliiiinnnngggg cccchhhhaaaarrrr ==== ^^^^
+
+ mmmmaaaannnngggglllliiiinnnngggg mmmmaaaatttthhhhoooodddd((((GGGG))))
+ controls the algorithm used for the generating the
+ mangled names. Can take two different values, "hash"
+ and "hash2". "hash" is the default and is the algorithm
+ that has been used in Samba for many years. "hash2" is
+ a newer and considered a better algorithm (generates
+ less collisions) in the names. However, many Win32
+ applications store the mangled names and so changing to
+ the new algorithm must not be done lightly as these
+ applications may break unless reinstalled. New
+ installations of Samba may set the default to hash2.
+
+ Default: mmmmaaaannnngggglllliiiinnnngggg mmmmeeeetttthhhhoooodddd ==== hhhhaaaasssshhhh
+
+ Example: mmmmaaaannnngggglllliiiinnnngggg mmmmeeeetttthhhhoooodddd ==== hhhhaaaasssshhhh2222
+
+ mmmmaaaapppp aaaarrrrcccchhhhiiiivvvveeee ((((SSSS))))
+ This controls whether the DOS archive attribute should
+ be mapped to the UNIX owner execute bit. The DOS
+ archive bit is set when a file has been modified since
+ its last backup. One motivation for this option it to
+ keep Samba/your PC from making any file it touches from
+ becoming executable under UNIX. This can be quite
+ annoying for shared source code, documents, etc...
+
+ Note that this requires the _c_r_e_a_t_e _m_a_s_k parameter to be
+ set such that owner execute bit is not masked out (i.e.
+
+
+
+ Page 74 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ it must include 100). See the parameter _c_r_e_a_t_e _m_a_s_k
+ for details.
+
+ Default: mmmmaaaapppp aaaarrrrcccchhhhiiiivvvveeee ==== yyyyeeeessss
+
+ mmmmaaaapppp hhhhiiiiddddddddeeeennnn ((((SSSS))))
+ This controls whether DOS style hidden files should be
+ mapped to the UNIX world execute bit.
+
+ Note that this requires the _c_r_e_a_t_e _m_a_s_k to be set such
+ that the world execute bit is not masked out (i.e. it
+ must include 001). See the parameter _c_r_e_a_t_e _m_a_s_k for
+ details.
+
+ Default: mmmmaaaapppp hhhhiiiiddddddddeeeennnn ==== nnnnoooo
+
+ mmmmaaaapppp ssssyyyysssstttteeeemmmm ((((SSSS))))
+ This controls whether DOS style system files should be
+ mapped to the UNIX group execute bit.
+
+ Note that this requires the _c_r_e_a_t_e _m_a_s_k to be set such
+ that the group execute bit is not masked out (i.e. it
+ must include 010). See the parameter _c_r_e_a_t_e _m_a_s_k for
+ details.
+
+ Default: mmmmaaaapppp ssssyyyysssstttteeeemmmm ==== nnnnoooo
+
+ mmmmaaaapppp ttttoooo gggguuuueeeesssstttt ((((GGGG))))
+ This parameter is only useful in security modes other
+ than _s_e_c_u_r_i_t_y = _s_h_a_r_e - i.e. user, server, and domain.
+
+ This parameter can take three different values, which
+ tell smbd(8) what to do with user login requests that
+ don't match a valid UNIX user in some way.
+
+ The three settings are :
+
+ o+ Never - Means user login requests with an invalid
+ password are rejected. This is the default.
+
+ o+ Bad User - Means user logins with an invalid password
+ are rejected, unless the username does not exist, in
+ which case it is treated as a guest login and mapped
+ into the _g_u_e_s_t _a_c_c_o_u_n_t.
+
+ o+ Bad Password - Means user logins with an invalid
+ password are treated as a guest login and mapped into
+ the guest account. Note that this can cause problems
+ as it means that any user incorrectly typing their
+ password will be silently logged on as "guest" - and
+ will not know the reason they cannot access files
+ they think they should - there will have been no
+
+
+
+ Page 75 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ message given to them that they got their password
+ wrong. Helpdesk services will hhhhaaaatttteeee you if you set the
+ _m_a_p _t_o _g_u_e_s_t parameter this way :-).
+
+ Note that this parameter is needed to set up "Guest" share
+ services when using _s_e_c_u_r_i_t_y modes other than share. This is
+ because in these modes the name of the resource being
+ requested is nnnnooootttt sent to the server until after the server
+ has successfully authenticated the client so the server
+ cannot make authentication decisions at the correct time
+ (connection to the share) for "Guest" shares.
+
+ For people familiar with the older Samba releases, this
+ parameter maps to the old compile-time setting of the
+ GUEST_SESSSETUP value in local.h.
+
+ Default: mmmmaaaapppp ttttoooo gggguuuueeeesssstttt ==== NNNNeeeevvvveeeerrrr
+
+ Example: mmmmaaaapppp ttttoooo gggguuuueeeesssstttt ==== BBBBaaaadddd UUUUsssseeeerrrr
+
+ mmmmaaaaxxxx ccccoooonnnnnnnneeeeccccttttiiiioooonnnnssss ((((SSSS))))
+ This option allows the number of simultaneous
+ connections to a service to be limited. If _m_a_x
+ _c_o_n_n_e_c_t_i_o_n_s is greater than 0 then connections will be
+ refused if this number of connections to the service
+ are already open. A value of zero mean an unlimited
+ number of connections may be made.
+
+ Record lock files are used to implement this feature.
+ The lock files will be stored in the directory
+ specified by the _l_o_c_k _d_i_r_e_c_t_o_r_y option.
+
+ Default: mmmmaaaaxxxx ccccoooonnnnnnnneeeeccccttttiiiioooonnnnssss ==== 0000
+
+ Example: mmmmaaaaxxxx ccccoooonnnnnnnneeeeccccttttiiiioooonnnnssss ==== 11110000
+
+ mmmmaaaaxxxx ddddiiiisssskkkk ssssiiiizzzzeeee ((((GGGG))))
+ This option allows you to put an upper limit on the
+ apparent size of disks. If you set this option to 100
+ then all shares will appear to be not larger than 100
+ MB in size.
+
+ Note that this option does not limit the amount of data
+ you can put on the disk. In the above case you could
+ still store much more than 100 MB on the disk, but if a
+ client ever asks for the amount of free disk space or
+ the total disk size then the result will be bounded by
+ the amount specified in _m_a_x _d_i_s_k _s_i_z_e.
+
+ This option is primarily useful to work around bugs in
+ some pieces of software that can't handle very large
+ disks, particularly disks over 1GB in size.
+
+
+
+ Page 76 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ A _m_a_x _d_i_s_k _s_i_z_e of 0 means no limit.
+
+ Default: mmmmaaaaxxxx ddddiiiisssskkkk ssssiiiizzzzeeee ==== 0000
+
+ Example: mmmmaaaaxxxx ddddiiiisssskkkk ssssiiiizzzzeeee ==== 1111000000000000
+
+ mmmmaaaaxxxx lllloooogggg ssssiiiizzzzeeee ((((GGGG))))
+ This option (an integer in kilobytes) specifies the max
+ size the log file should grow to. Samba periodically
+ checks the size and if it is exceeded it will rename
+ the file, adding a ._o_l_d extension.
+
+ A size of 0 means no limit.
+
+ Default: mmmmaaaaxxxx lllloooogggg ssssiiiizzzzeeee ==== 5555000000000000
+
+ Example: mmmmaaaaxxxx lllloooogggg ssssiiiizzzzeeee ==== 1111000000000000
+
+ mmmmaaaaxxxx mmmmuuuuxxxx ((((GGGG))))
+ This option controls the maximum number of outstanding
+ simultaneous SMB operations that Samba tells the client
+ it will allow. You should never need to set this
+ parameter.
+
+ Default: mmmmaaaaxxxx mmmmuuuuxxxx ==== 55550000
+
+ mmmmaaaaxxxx ooooppppeeeennnn ffffiiiilllleeeessss ((((GGGG))))
+ This parameter limits the maximum number of open files
+ that one smbd(8) file serving process may have open for
+ a client at any one time. The default for this
+ parameter is set very high (10,000) as Samba uses only
+ one bit per unopened file.
+
+ The limit of the number of open files is usually set by
+ the UNIX per-process file descriptor limit rather than
+ this parameter so you should never need to touch this
+ parameter.
+
+ Default: mmmmaaaaxxxx ooooppppeeeennnn ffffiiiilllleeeessss ==== 11110000000000000000
+
+ mmmmaaaaxxxx pppprrrriiiinnnntttt jjjjoooobbbbssss ((((SSSS))))
+ This parameter limits the maximum number of jobs
+ allowable in a Samba printer queue at any given moment.
+ If this number is exceeded, ssssmmmmbbbbdddd((((8888)))) will remote "Out
+ of Space" to the client. See all _t_o_t_a_l _p_r_i_n_t _j_o_b_s.
+
+ Default: mmmmaaaaxxxx pppprrrriiiinnnntttt jjjjoooobbbbssss ==== 1111000000000000
+
+ Example: mmmmaaaaxxxx pppprrrriiiinnnntttt jjjjoooobbbbssss ==== 5555000000000000
+
+ mmmmaaaaxxxx pppprrrroooottttooooccccoooollll ((((GGGG))))
+ The value of the parameter (a string) is the highest
+
+
+
+ Page 77 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ protocol level that will be supported by the server.
+
+ Possible values are :
+
+ o+ CORE: Earliest version. No concept of user names.
+
+ o+ COREPLUS: Slight improvements on CORE for efficiency.
+
+ o+ LANMAN1: First mmmmooooddddeeeerrrrnnnn version of the protocol. Long
+ filename support.
+
+ o+ LANMAN2: Updates to Lanman1 protocol.
+
+ o+ NT1: Current up to date version of the protocol. Used
+ by Windows NT. Known as CIFS.
+
+ Normally this option should not be set as the automatic
+ negotiation phase in the SMB protocol takes care of choosing
+ the appropriate protocol.
+
+ See also _m_i_n _p_r_o_t_o_c_o_l
+
+ Default: mmmmaaaaxxxx pppprrrroooottttooooccccoooollll ==== NNNNTTTT1111
+
+ Example: mmmmaaaaxxxx pppprrrroooottttooooccccoooollll ==== LLLLAAAANNNNMMMMAAAANNNN1111
+
+ mmmmaaaaxxxx ssssmmmmbbbbdddd pppprrrroooocccceeeesssssssseeeessss ((((GGGG))))
+ This parameter limits the maximum number of ssssmmmmbbbbdddd((((8888))))
+ processes concurrently running on a system and is
+ intended as a stopgap to prevent degrading service to
+ clients in the event that the server has insufficient
+ resources to handle more than this number of
+ connections. Remember that under normal operating
+ conditions, each user will have an smbd associated with
+ him or her to handle connections to all shares from a
+ given host.
+
+ Default: mmmmaaaaxxxx ssssmmmmbbbbdddd pppprrrroooocccceeeesssssssseeeessss ==== 0000 ## no limit
+
+ Example: mmmmaaaaxxxx ssssmmmmbbbbdddd pppprrrroooocccceeeesssssssseeeessss ==== 1111000000000000
+
+ mmmmaaaaxxxx ttttttttllll ((((GGGG))))
+ This option tells nmbd(8) what the default 'time to
+ live' of NetBIOS names should be (in seconds) when nnnnmmmmbbbbdddd
+ is requesting a name using either a broadcast packet or
+ from a WINS server. You should never need to change
+ this parameter. The default is 3 days.
+
+ Default: mmmmaaaaxxxx ttttttttllll ==== 222255559999222200000000
+
+ mmmmaaaaxxxx wwwwiiiinnnnssss ttttttttllll ((((GGGG))))
+ This option tells nmbd(8)
+
+
+
+ Page 78 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ when acting as a WINS server ( _w_i_n_s _s_u_p_p_o_r_t = _y_e_s)
+ what the maximum 'time to live' of NetBIOS names that
+ nnnnmmmmbbbbdddd will grant will be (in seconds). You should never
+ need to change this parameter. The default is 6 days
+ (518400 seconds).
+
+ See also the _m_i_n _w_i_n_s _t_t_l parameter.
+
+ Default: mmmmaaaaxxxx wwwwiiiinnnnssss ttttttttllll ==== 555511118888444400000000
+
+ mmmmaaaaxxxx xxxxmmmmiiiitttt ((((GGGG))))
+ This option controls the maximum packet size that will
+ be negotiated by Samba. The default in Samba 2.2.6 is
+ now 16644 (changed from 65535 in earlier releases)
+ which matches Windows 2000. This allows better
+ performance with Windows NT clients. The maximum is
+ 65535. In some cases you may find you get better
+ performance with a smaller value. A value below 2048 is
+ likely to cause problems.
+
+ Default: mmmmaaaaxxxx xxxxmmmmiiiitttt ==== 11116666666644444444
+
+ Example: mmmmaaaaxxxx xxxxmmmmiiiitttt ==== 8888111199992222
+
+ mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd ((((GGGG))))
+ This specifies what command to run when the server
+ receives a WinPopup style message.
+
+ This would normally be a command that would deliver the
+ message somehow. How this is to be done is up to your
+ imagination.
+
+ An example is:
+
+ mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd ==== ccccsssshhhh ----cccc ''''xxxxeeeeddddiiiitttt %%%%ssss;;;;rrrrmmmm %%%%ssss'''' &&&&
+
+ This delivers the message using xxxxeeeeddddiiiitttt, then removes it
+ afterwards. NNNNOOOOTTTTEEEE TTTTHHHHAAAATTTT IIIITTTT IIIISSSS VVVVEEEERRRRYYYY IIIIMMMMPPPPOOOORRRRTTTTAAAANNNNTTTT TTTTHHHHAAAATTTT TTTTHHHHIIIISSSS
+ CCCCOOOOMMMMMMMMAAAANNNNDDDD RRRREEEETTTTUUUURRRRNNNN IIIIMMMMMMMMEEEEDDDDIIIIAAAATTTTEEEELLLLYYYY. That's why I have the '&'
+ on the end. If it doesn't return immediately then your
+ PCs may freeze when sending messages (they should
+ recover after 30 seconds, hopefully).
+
+ All messages are delivered as the global guest user.
+ The command takes the standard substitutions, although
+ %_u won't work (%_U may be better in this case).
+
+ Apart from the standard substitutions, some additional
+ ones apply. In particular:
+
+ o+ %_s = the filename containing the message.
+
+
+
+
+ Page 79 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ %_t = the destination that the message was sent to
+ (probably the server name).
+
+ o+ %_f = who the message is from.
+
+ You could make this command send mail, or whatever else
+ takes your fancy. Please let us know of any really
+ interesting ideas you have.
+
+ Here's a way of sending the messages as mail to root:
+
+ mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd ==== ////bbbbiiiinnnn////mmmmaaaaiiiillll ----ssss ''''mmmmeeeessssssssaaaaggggeeee ffffrrrroooommmm %%%%ffff oooonnnn %%%%mmmm'''' rrrrooooooootttt
+ <<<< %%%%ssss;;;; rrrrmmmm %%%%ssss
+
+ If you don't have a message command then the message won't
+ be delivered and Samba will tell the sender there was an
+ error. Unfortunately WfWg totally ignores the error code and
+ carries on regardless, saying that the message was
+ delivered.
+
+ If you want to silently delete it then try:
+
+ mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd ==== rrrrmmmm %%%%ssss
+
+ Default: nnnnoooo mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd
+
+ Example: mmmmeeeessssssssaaaaggggeeee ccccoooommmmmmmmaaaannnndddd ==== ccccsssshhhh ----cccc ''''xxxxeeeeddddiiiitttt %%%%ssss;;;; rrrrmmmm %%%%ssss'''' &&&&
+
+ mmmmiiiinnnn ppppaaaasssssssswwwwdddd lllleeeennnnggggtttthhhh ((((GGGG))))
+ Synonym for _m_i_n _p_a_s_s_w_o_r_d _l_e_n_g_t_h.
+
+ mmmmiiiinnnn ppppaaaasssssssswwwwoooorrrrdddd lllleeeennnnggggtttthhhh ((((GGGG))))
+ This option sets the minimum length in characters of a
+ plaintext password that ssssmmmmbbbbdddd will accept when
+ performing UNIX password changing.
+
+ See also _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c, _p_a_s_s_w_d _p_r_o_g_r_a_m and _p_a_s_s_w_d
+ _c_h_a_t _d_e_b_u_g .
+
+ Default: mmmmiiiinnnn ppppaaaasssssssswwwwoooorrrrdddd lllleeeennnnggggtttthhhh ==== 5555
+
+ mmmmiiiinnnn pppprrrriiiinnnntttt ssssppppaaaacccceeee ((((SSSS))))
+ This sets the minimum amount of free disk space that
+ must be available before a user will be able to spool a
+ print job. It is specified in kilobytes. The default is
+ 0, which means a user can always spool a print job.
+
+ See also the _p_r_i_n_t_i_n_g parameter.
+
+ Default: mmmmiiiinnnn pppprrrriiiinnnntttt ssssppppaaaacccceeee ==== 0000
+
+ Example: mmmmiiiinnnn pppprrrriiiinnnntttt ssssppppaaaacccceeee ==== 2222000000000000
+
+
+
+ Page 80 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ mmmmiiiinnnn pppprrrroooottttooooccccoooollll ((((GGGG))))
+ The value of the parameter (a string) is the lowest SMB
+ protocol dialect than Samba will support. Please refer
+ to the _m_a_x _p_r_o_t_o_c_o_l parameter for a list of valid
+ protocol names and a brief description of each. You may
+ also wish to refer to the C source code in
+ _s_o_u_r_c_e/_s_m_b_d/_n_e_g_p_r_o_t._c for a listing of known protocol
+ dialects supported by clients.
+
+ If you are viewing this parameter as a security
+ measure, you should also refer to the _l_a_n_m_a_n _a_u_t_h
+ parameter. Otherwise, you should never need to change
+ this parameter.
+
+ Default : mmmmiiiinnnn pppprrrroooottttooooccccoooollll ==== CCCCOOOORRRREEEE
+
+ Example : mmmmiiiinnnn pppprrrroooottttooooccccoooollll ==== NNNNTTTT1111 # disable DOS clients
+
+ mmmmiiiinnnn wwwwiiiinnnnssss ttttttttllll ((((GGGG))))
+ This option tells nmbd(8) when acting as a WINS server
+ ( _w_i_n_s _s_u_p_p_o_r_t = _y_e_s) what the minimum 'time to live'
+ of NetBIOS names that nnnnmmmmbbbbdddd will grant will be (in
+ seconds). You should never need to change this
+ parameter. The default is 6 hours (21600 seconds).
+
+ Default: mmmmiiiinnnn wwwwiiiinnnnssss ttttttttllll ==== 22221111666600000000
+
+ mmmmssssddddffffssss rrrrooooooootttt ((((SSSS))))
+ This boolean parameter is only available if Samba is
+ configured and compiled with the --------wwwwiiiitttthhhh----mmmmssssddddffffssss option.
+ If set to yes, Samba treats the share as a Dfs root and
+ allows clients to browse the distributed file system
+ tree rooted at the share directory. Dfs links are
+ specified in the share directory by symbolic links of
+ the form _m_s_d_f_s:_s_e_r_v_e_r_A\_s_h_a_r_e_A,_s_e_r_v_e_r_B\_s_h_a_r_e_B and so on.
+ For more information on setting up a Dfs tree on Samba,
+ refer to msdfs_setup.html
+
+
+ See also _h_o_s_t _m_s_d_f_s
+
+ Default: mmmmssssddddffffssss rrrrooooooootttt ==== nnnnoooo
+
+ nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr ((((GGGG))))
+ This option is used by the programs in the Samba suite
+ to determine what naming services to use and in what
+ order to resolve host names to IP addresses. The option
+ takes a space separated string of name resolution
+ options.
+
+ The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :
+
+
+
+ Page 81 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ lmhosts : Lookup an IP address in the Samba lmhosts
+ file. If the line in lmhosts has no name type
+ attached to the NetBIOS name (see the lmhosts(5) for
+ details) then any name type matches for lookup.
+
+ o+ host : Do a standard host name to IP address
+ resolution, using the system /_e_t_c/_h_o_s_t_s , NIS, or DNS
+ lookups. This method of name resolution is operating
+ system depended for instance on IRIX or Solaris this
+ may be controlled by the /_e_t_c/_n_s_s_w_i_t_c_h._c_o_n_f file.
+ Note that this method is only used if the NetBIOS
+ name type being queried is the 0x20 (server) name
+ type, otherwise it is ignored.
+
+ o+ wins : Query a name with the IP address listed in the
+ _w_i_n_s _s_e_r_v_e_r parameter. If no WINS server has been
+ specified this method will be ignored.
+
+ o+ bcast : Do a broadcast on each of the known local
+ interfaces listed in the _i_n_t_e_r_f_a_c_e_s parameter. This
+ is the least reliable of the name resolution methods
+ as it depends on the target host being on a locally
+ connected subnet.
+
+ Default: nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr ==== llllmmmmhhhhoooossssttttssss hhhhoooosssstttt wwwwiiiinnnnssss bbbbccccaaaasssstttt
+
+ Example: nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr ==== llllmmmmhhhhoooossssttttssss bbbbccccaaaasssstttt hhhhoooosssstttt
+
+ This will cause the local lmhosts file to be examined first,
+ followed by a broadcast attempt, followed by a normal system
+ hostname lookup.
+
+ nnnneeeettttbbbbiiiioooossss aaaalllliiiiaaaasssseeeessss ((((GGGG))))
+ This is a list of NetBIOS names that nmbd(8) will
+ advertise as additional names by which the Samba server
+ is known. This allows one machine to appear in browse
+ lists under multiple names. If a machine is acting as a
+ browse server or logon server none of these names will
+ be advertised as either browse server or logon servers,
+ only the primary name of the machine will be advertised
+ with these capabilities.
+
+ See also _n_e_t_b_i_o_s _n_a_m_e.
+
+ Default: eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg ((((nnnnoooo aaaaddddddddiiiittttiiiioooonnnnaaaallll nnnnaaaammmmeeeessss))))
+
+ Example: nnnneeeettttbbbbiiiioooossss aaaalllliiiiaaaasssseeeessss ==== TTTTEEEESSSSTTTT TTTTEEEESSSSTTTT1111 TTTTEEEESSSSTTTT2222
+
+ nnnneeeettttbbbbiiiioooossss nnnnaaaammmmeeee ((((GGGG))))
+ This sets the NetBIOS name by which a Samba server is
+ known. By default it is the same as the first component
+ of the host's DNS name. If a machine is a browse server
+
+
+
+ Page 82 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ or logon server this name (or the first component of
+ the hosts DNS name) will be the name that these
+ services are advertised under.
+
+ See also _n_e_t_b_i_o_s _a_l_i_a_s_e_s.
+
+ Default: mmmmaaaacccchhhhiiiinnnneeee DDDDNNNNSSSS nnnnaaaammmmeeee
+
+ Example: nnnneeeettttbbbbiiiioooossss nnnnaaaammmmeeee ==== MMMMYYYYNNNNAAAAMMMMEEEE
+
+ nnnneeeettttbbbbiiiioooossss ssssccccooooppppeeee ((((GGGG))))
+ This sets the NetBIOS scope that Samba will operate
+ under. This should not be set unless every machine on
+ your LAN also sets this value.
+
+ nnnniiiissss hhhhoooommmmeeeeddddiiiirrrr ((((GGGG))))
+ Get the home share server from a NIS map. For UNIX
+ systems that use an automounter, the user's home
+ directory will often be mounted on a workstation on
+ demand from a remote server.
+
+ When the Samba logon server is not the actual home
+ directory server, but is mounting the home directories
+ via NFS then two network hops would be required to
+ access the users home directory if the logon server
+ told the client to use itself as the SMB server for
+ home directories (one over SMB and one over NFS). This
+ can be very slow.
+
+ This option allows Samba to return the home share as
+ being on a different server to the logon server and as
+ long as a Samba daemon is running on the home directory
+ server, it will be mounted on the Samba client directly
+ from the directory server. When Samba is returning the
+ home share to the client, it will consult the NIS map
+ specified in _h_o_m_e_d_i_r _m_a_p and return the server listed
+ there.
+
+ Note that for this option to work there must be a
+ working NIS system and the Samba server with this
+ option must also be a logon server.
+
+ Default: nnnniiiissss hhhhoooommmmeeeeddddiiiirrrr ==== nnnnoooo
+
+ nnnntttt aaaaccccllll ssssuuuuppppppppoooorrrrtttt ((((SSSS))))
+ This boolean parameter controls whether smbd(8) will
+ attempt to map UNIX permissions into Windows NT access
+ control lists. This parameter was formally a global
+ parameter in releases prior to 2.2.2.
+
+ Default: nnnntttt aaaaccccllll ssssuuuuppppppppoooorrrrtttt ==== yyyyeeeessss
+
+
+
+
+ Page 83 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ nnnntttt ppppiiiippppeeee ssssuuuuppppppppoooorrrrtttt ((((GGGG))))
+ This boolean parameter controls whether smbd(8) will
+ allow Windows NT clients to connect to the NT SMB
+ specific IPC$ pipes. This is a developer debugging
+ option and can be left alone.
+
+ Default: nnnntttt ppppiiiippppeeee ssssuuuuppppppppoooorrrrtttt ==== yyyyeeeessss
+
+ nnnntttt ssssmmmmbbbb ssssuuuuppppppppoooorrrrtttt ((((GGGG))))
+ This boolean parameter controls whether smbd(8) will
+ negotiate NT specific SMB support with Windows NT/2k/XP
+ clients. Although this is a developer debugging option
+ and should be left alone, benchmarking has discovered
+ that Windows NT clients give faster performance with
+ this option set to no. This is still being
+ investigated. If this option is set to no then Samba
+ offers exactly the same SMB calls that versions prior
+ to Samba 2.0 offered. This information may be of use
+ if any users are having problems with NT SMB support.
+
+ You should not need to ever disable this parameter.
+
+ Default: nnnntttt ssssmmmmbbbb ssssuuuuppppppppoooorrrrtttt ==== yyyyeeeessss
+
+ nnnntttt ssssttttaaaattttuuuussss ssssuuuuppppppppoooorrrrtttt ((((GGGG))))
+ This boolean parameter controls whether smbd(8) will
+ negotiate NT specific status support with Windows
+ NT/2k/XP clients. This is a developer debugging option
+ and should be left alone. If this option is set to no
+ then Samba offers exactly the same DOS error codes that
+ versions prior to Samba 2.2.3 reported.
+
+ You should not need to ever disable this parameter.
+
+ Default: nnnntttt ssssttttaaaattttuuuussss ssssuuuuppppppppoooorrrrtttt ==== yyyyeeeessss
+
+ nnnnuuuullllllll ppppaaaasssssssswwwwoooorrrrddddssss ((((GGGG))))
+ Allow or disallow client access to accounts that have
+ null passwords.
+
+ See also smbpasswd (5)
+
+ Default: nnnnuuuullllllll ppppaaaasssssssswwwwoooorrrrddddssss ==== nnnnoooo
+
+ oooobbbbeeeeyyyy ppppaaaammmm rrrreeeessssttttrrrriiiiccccttttiiiioooonnnnssss ((((GGGG))))
+ When Samba 2.2 is configured to enable PAM support
+ (i.e. --with-pam), this parameter will control whether
+ or not Samba should obey PAM's account and session
+ management directives. The default behavior is to use
+ PAM for clear text authentication only and to ignore
+ any account or session management. Note that Samba
+ always ignores PAM for authentication in the case of
+
+
+
+ Page 84 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ _e_n_c_r_y_p_t _p_a_s_s_w_o_r_d_s _= _y_e_s . The reason is that PAM
+ modules cannot support the challenge/response
+ authentication mechanism needed in the presence of SMB
+ password encryption.
+
+ Default: oooobbbbeeeeyyyy ppppaaaammmm rrrreeeessssttttrrrriiiiccccttttiiiioooonnnnssss ==== nnnnoooo
+
+ oooonnnnllllyyyy uuuusssseeeerrrr ((((SSSS))))
+ This is a boolean option that controls whether
+ connections with usernames not in the _u_s_e_r list will be
+ allowed. By default this option is disabled so that a
+ client can supply a username to be used by the server.
+ Enabling this parameter will force the server to only
+ user the login names from the _u_s_e_r list and is only
+ really useful in shave level security.
+
+ Note that this also means Samba won't try to deduce
+ usernames from the service name. This can be annoying
+ for the [homes] section. To get around this you could
+ use uuuusssseeeerrrr ==== %%%%SSSS which means your _u_s_e_r list will be just
+ the service name, which for home directories is the
+ name of the user.
+
+ See also the _u_s_e_r parameter.
+
+ Default: oooonnnnllllyyyy uuuusssseeeerrrr ==== nnnnoooo
+
+ oooonnnnllllyyyy gggguuuueeeesssstttt ((((SSSS))))
+ A synonym for _g_u_e_s_t _o_n_l_y.
+
+ oooopppplllloooocccckkkk bbbbrrrreeeeaaaakkkk wwwwaaaaiiiitttt ttttiiiimmmmeeee ((((GGGG))))
+ This is a tuning parameter added due to bugs in both
+ Windows 9x and WinNT. If Samba responds to a client too
+ quickly when that client issues an SMB that can cause
+ an oplock break request, then the network client can
+ fail and not respond to the break request. This tuning
+ parameter (which is set in milliseconds) is the amount
+ of time Samba will wait before sending an oplock break
+ request to such (broken) clients.
+
+ DDDDOOOO NNNNOOOOTTTT CCCCHHHHAAAANNNNGGGGEEEE TTTTHHHHIIIISSSS PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRR UUUUNNNNLLLLEEEESSSSSSSS YYYYOOOOUUUU HHHHAAAAVVVVEEEE RRRREEEEAAAADDDD AAAANNNNDDDD
+ UUUUNNNNDDDDEEEERRRRSSSSTTTTOOOOOOOODDDD TTTTHHHHEEEE SSSSAAAAMMMMBBBBAAAA OOOOPPPPLLLLOOOOCCCCKKKK CCCCOOOODDDDEEEE.
+
+ Default: oooopppplllloooocccckkkk bbbbrrrreeeeaaaakkkk wwwwaaaaiiiitttt ttttiiiimmmmeeee ==== 0000
+
+ oooopppplllloooocccckkkk ccccoooonnnntttteeeennnnttttiiiioooonnnn lllliiiimmmmiiiitttt ((((SSSS))))
+ This is a vvvveeeerrrryyyy advanced smbd(8) tuning option to
+ improve the efficiency of the granting of oplocks under
+ multiple client contention for the same file.
+
+ In brief it specifies a number, which causes smbd not
+ to grant an oplock even when requested if the
+
+
+
+ Page 85 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ approximate number of clients contending for an oplock
+ on the same file goes over this limit. This causes ssssmmmmbbbbdddd
+ to behave in a similar way to Windows NT.
+
+ DDDDOOOO NNNNOOOOTTTT CCCCHHHHAAAANNNNGGGGEEEE TTTTHHHHIIIISSSS PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRR UUUUNNNNLLLLEEEESSSSSSSS YYYYOOOOUUUU HHHHAAAAVVVVEEEE RRRREEEEAAAADDDD AAAANNNNDDDD
+ UUUUNNNNDDDDEEEERRRRSSSSTTTTOOOOOOOODDDD TTTTHHHHEEEE SSSSAAAAMMMMBBBBAAAA OOOOPPPPLLLLOOOOCCCCKKKK CCCCOOOODDDDEEEE.
+
+ Default: oooopppplllloooocccckkkk ccccoooonnnntttteeeennnnttttiiiioooonnnn lllliiiimmmmiiiitttt ==== 2222
+
+ oooopppplllloooocccckkkkssss ((((SSSS))))
+ This boolean option tells ssssmmmmbbbbdddd whether to issue oplocks
+ (opportunistic locks) to file open requests on this
+ share. The oplock code can dramatically (approx. 30% or
+ more) improve the speed of access to files on Samba
+ servers. It allows the clients to aggressively cache
+ files locally and you may want to disable this option
+ for unreliable network environments (it is turned on by
+ default in Windows NT Servers). For more information
+ see the file _S_p_e_e_d._t_x_t in the Samba _d_o_c_s/ directory.
+
+ Oplocks may be selectively turned off on certain files
+ with a share. See the _v_e_t_o _o_p_l_o_c_k _f_i_l_e_s parameter. On
+ some systems oplocks are recognized by the underlying
+ operating system. This allows data synchronization
+ between all access to oplocked files, whether it be via
+ Samba or NFS or a local UNIX process. See the _k_e_r_n_e_l
+ _o_p_l_o_c_k_s parameter for details.
+
+ See also the _k_e_r_n_e_l _o_p_l_o_c_k_s and _l_e_v_e_l_2 _o_p_l_o_c_k_s
+ parameters.
+
+ Default: oooopppplllloooocccckkkkssss ==== yyyyeeeessss
+
+ oooossss lllleeeevvvveeeellll ((((GGGG))))
+ This integer value controls what level Samba advertises
+ itself as for browse elections. The value of this
+ parameter determines whether nmbd(8) has a chance of
+ becoming a local master browser for the _W_O_R_K_G_R_O_U_P in
+ the local broadcast area.
+
+ NNNNooootttteeee ::::By default, Samba will win a local master
+ browsing election over all Microsoft operating systems
+ except a Windows NT 4.0/2000 Domain Controller. This
+ means that a misconfigured Samba host can effectively
+ isolate a subnet for browsing purposes. See
+ _B_R_O_W_S_I_N_G._t_x_t in the Samba _d_o_c_s/ directory for details.
+
+ Default: oooossss lllleeeevvvveeeellll ==== 22220000
+
+ Example: oooossss lllleeeevvvveeeellll ==== 66665555
+
+ oooossss2222 ddddrrrriiiivvvveeeerrrr mmmmaaaapppp ((((GGGG))))
+
+
+
+ Page 86 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The parameter is used to define the absolute path to a
+ file containing a mapping of Windows NT printer driver
+ names to OS/2 printer driver names. The format is:
+
+ <nt driver name> = <os2 driver name>.<device name>
+
+ For example, a valid entry using the HP LaserJet 5
+ printer driver would appear as HHHHPPPP LLLLaaaasssseeeerrrrJJJJeeeetttt 5555LLLL ====
+ LLLLAAAASSSSEEEERRRRJJJJEEEETTTT....HHHHPPPP LLLLaaaasssseeeerrrrJJJJeeeetttt 5555LLLL.
+
+ The need for the file is due to the printer driver
+ namespace problem described in the Samba Printing HOWTO
+ For more details on OS/2 clients, please refer to the
+ OS2-Client-HOWTO
+ containing in the Samba documentation.
+
+ Default: oooossss2222 ddddrrrriiiivvvveeeerrrr mmmmaaaapppp ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ ppppaaaammmm ppppaaaasssssssswwwwoooorrrrdddd cccchhhhaaaannnnggggeeee ((((GGGG))))
+ With the addition of better PAM support in Samba 2.2,
+ this parameter, it is possible to use PAM's password
+ change control flag for Samba. If enabled, then PAM
+ will be used for password changes when requested by an
+ SMB client instead of the program listed in _p_a_s_s_w_d
+ _p_r_o_g_r_a_m. It should be possible to enable this without
+ changing your _p_a_s_s_w_d _c_h_a_t parameter for most setups.
+
+ Default: ppppaaaammmm ppppaaaasssssssswwwwoooorrrrdddd cccchhhhaaaannnnggggeeee ==== nnnnoooo
+
+ ppppaaaannnniiiicccc aaaaccccttttiiiioooonnnn ((((GGGG))))
+ This is a Samba developer option that allows a system
+ command to be called when either smbd(8) crashes. This
+ is usually used to draw attention to the fact that a
+ problem occurred.
+
+ Default: ppppaaaannnniiiicccc aaaaccccttttiiiioooonnnn ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: ppppaaaannnniiiicccc aaaaccccttttiiiioooonnnn ==== """"////bbbbiiiinnnn////sssslllleeeeeeeepppp 99990000000000000000""""
+
+ ppppaaaasssssssswwwwdddd cccchhhhaaaatttt ((((GGGG))))
+ This string controls the """"cccchhhhaaaatttt"""" conversation that takes
+ places between smbd and the local password changing
+ program to change the user's password. The string
+ describes a sequence of response-receive pairs that
+ smbd(8) uses to determine what to send to the _p_a_s_s_w_d
+ _p_r_o_g_r_a_m and what to expect back. If the expected output
+ is not received then the password is not changed.
+
+ This chat sequence is often quite site specific,
+ depending on what local methods are used for password
+ control (such as NIS etc).
+
+
+
+
+ Page 87 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Note that this parameter only is only used if the _u_n_i_x
+ _p_a_s_s_w_o_r_d _s_y_n_c parameter is set to yes. This sequence is
+ then called AAAASSSS RRRROOOOOOOOTTTT when the SMB password in the
+ smbpasswd file is being changed, without access to the
+ old password cleartext. This means that root must be
+ able to reset the user's password without knowing the
+ text of the previous password. In the presence of
+ NIS/YP, this means that the passwd program must be
+ executed on the NIS master.
+
+ The string can contain the macro %_n which is
+ substituted for the new password. The chat sequence can
+ also contain the standard macros \n, \r, \t and \s to
+ give line-feed, carriage-return, tab and space. The
+ chat sequence string can also contain a '*' which
+ matches any sequence of characters. Double quotes can
+ be used to collect strings with spaces in them into a
+ single string.
+
+ If the send string in any part of the chat sequence is
+ a full stop ".", then no string is sent. Similarly, if
+ the expect string is a full stop then no string is
+ expected.
+
+ If the _p_a_m _p_a_s_s_w_o_r_d _c_h_a_n_g_e parameter is set to yes, the
+ chat pairs may be matched in any order, and success is
+ determined by the PAM result, not any particular
+ output. The \n macro is ignored for PAM conversions.
+
+ See also _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c, _p_a_s_s_w_d _p_r_o_g_r_a_m , _p_a_s_s_w_d
+ _c_h_a_t _d_e_b_u_g and _p_a_m _p_a_s_s_w_o_r_d _c_h_a_n_g_e.
+
+ Default: ppppaaaasssssssswwwwdddd cccchhhhaaaatttt ==== ****nnnneeeewwww****ppppaaaasssssssswwwwoooorrrrdddd**** %%%%nnnn\\\\nnnn
+ ****nnnneeeewwww****ppppaaaasssssssswwwwoooorrrrdddd**** %%%%nnnn\\\\nnnn ****cccchhhhaaaannnnggggeeeedddd****
+
+ Example: ppppaaaasssssssswwwwdddd cccchhhhaaaatttt ==== """"****EEEEnnnntttteeeerrrr OOOOLLLLDDDD ppppaaaasssssssswwwwoooorrrrdddd****"""" %%%%oooo\\\\nnnn
+ """"****EEEEnnnntttteeeerrrr NNNNEEEEWWWW ppppaaaasssssssswwwwoooorrrrdddd****"""" %%%%nnnn\\\\nnnn """"****RRRReeeeeeeennnntttteeeerrrr NNNNEEEEWWWW ppppaaaasssssssswwwwoooorrrrdddd****""""
+ %%%%nnnn\\\\nnnn """"****PPPPaaaasssssssswwwwoooorrrrdddd cccchhhhaaaannnnggggeeeedddd****""""
+
+ ppppaaaasssssssswwwwdddd cccchhhhaaaatttt ddddeeeebbbbuuuugggg ((((GGGG))))
+ This boolean specifies if the passwd chat script
+ parameter is run in ddddeeeebbbbuuuugggg mode. In this mode the
+ strings passed to and received from the passwd chat are
+ printed in the smbd(8) log with a _d_e_b_u_g _l_e_v_e_l of 100.
+ This is a dangerous option as it will allow plaintext
+ passwords to be seen in the ssssmmmmbbbbdddd log. It is available
+ to help Samba admins debug their _p_a_s_s_w_d _c_h_a_t scripts
+ when calling the _p_a_s_s_w_d _p_r_o_g_r_a_m and should be turned
+ off after this has been done. This option has no effect
+ if the _p_a_m _p_a_s_s_w_o_r_d _c_h_a_n_g_e paramter is set. This
+ parameter is off by default.
+
+
+
+
+ Page 88 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ See also _p_a_s_s_w_d _c_h_a_t , _p_a_m _p_a_s_s_w_o_r_d _c_h_a_n_g_e , _p_a_s_s_w_d
+ _p_r_o_g_r_a_m .
+
+ Default: ppppaaaasssssssswwwwdddd cccchhhhaaaatttt ddddeeeebbbbuuuugggg ==== nnnnoooo
+
+ ppppaaaasssssssswwwwdddd pppprrrrooooggggrrrraaaammmm ((((GGGG))))
+ The name of a program that can be used to set UNIX user
+ passwords. Any occurrences of %_u will be replaced with
+ the user name. The user name is checked for existence
+ before calling the password changing program.
+
+ Also note that many passwd programs insist in
+ rrrreeeeaaaassssoooonnnnaaaabbbblllleeee passwords, such as a minimum length, or the
+ inclusion of mixed case chars and digits. This can pose
+ a problem as some clients (such as Windows for
+ Workgroups) uppercase the password before sending it.
+
+ NNNNooootttteeee that if the _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c parameter is set to
+ yes then this program is called AAAASSSS RRRROOOOOOOOTTTT before the SMB
+ password in the smbpasswd(5)
+ file is changed. If this UNIX password change fails,
+ then ssssmmmmbbbbdddd will fail to change the SMB password also
+ (this is by design).
+
+ If the _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c parameter is set this
+ parameter MMMMUUUUSSSSTTTT UUUUSSSSEEEE AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE PPPPAAAATTTTHHHHSSSS for AAAALLLLLLLL programs
+ called, and must be examined for security implications.
+ Note that by default _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c is set to no.
+
+ See also _u_n_i_x _p_a_s_s_w_o_r_d _s_y_n_c.
+
+ Default: ppppaaaasssssssswwwwdddd pppprrrrooooggggrrrraaaammmm ==== ////bbbbiiiinnnn////ppppaaaasssssssswwwwdddd
+
+ Example: ppppaaaasssssssswwwwdddd pppprrrrooooggggrrrraaaammmm ==== ////ssssbbbbiiiinnnn////nnnnppppaaaasssssssswwwwdddd %%%%uuuu
+
+ ppppaaaasssssssswwwwoooorrrrdddd lllleeeevvvveeeellll ((((GGGG))))
+ Some client/server combinations have difficulty with
+ mixed-case passwords. One offending client is Windows
+ for Workgroups, which for some reason forces passwords
+ to upper case when using the LANMAN1 protocol, but
+ leaves them alone when using COREPLUS! Another problem
+ child is the Windows 95/98 family of operating systems.
+ These clients upper case clear text passwords even when
+ NT LM 0.12 selected by the protocol negotiation
+ request/response.
+
+ This parameter defines the maximum number of characters
+ that may be upper case in passwords.
+
+ For example, say the password given was "FRED". If
+ _p_a_s_s_w_o_r_d _l_e_v_e_l is set to 1, the following combinations
+ would be tried if "FRED" failed:
+
+
+
+ Page 89 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ "Fred", "fred", "fRed", "frEd","freD"
+
+ If _p_a_s_s_w_o_r_d _l_e_v_e_l was set to 2, the following
+ combinations would also be tried:
+
+ "FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ..
+
+ And so on.
+
+ The higher value this parameter is set to the more
+ likely it is that a mixed case password will be matched
+ against a single case password. However, you should be
+ aware that use of this parameter reduces security and
+ increases the time taken to process a new connection.
+
+ A value of zero will cause only two attempts to be made
+ - the password as is and the password in all-lower
+ case.
+
+ Default: ppppaaaasssssssswwwwoooorrrrdddd lllleeeevvvveeeellll ==== 0000
+
+ Example: ppppaaaasssssssswwwwoooorrrrdddd lllleeeevvvveeeellll ==== 4444
+
+ ppppaaaasssssssswwwwoooorrrrdddd sssseeeerrrrvvvveeeerrrr ((((GGGG))))
+ By specifying the name of another SMB server (such as a
+ WinNT box) with this option, and using sssseeeeccccuuuurrrriiiittttyyyy ====
+ ddddoooommmmaaaaiiiinnnn or sssseeeeccccuuuurrrriiiittttyyyy ==== sssseeeerrrrvvvveeeerrrr you can get Samba to do all
+ its username/password validation via a remote server.
+
+ This option sets the name of the password server to
+ use. It must be a NetBIOS name, so if the machine's
+ NetBIOS name is different from its Internet name then
+ you may have to add its NetBIOS name to the lmhosts
+ file which is stored in the same directory as the
+ _s_m_b._c_o_n_f file.
+
+ The name of the password server is looked up using the
+ parameter _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r and so may resolved by any
+ method and order described in that parameter.
+
+ The password server much be a machine capable of using
+ the "LM1.2X002" or the "NT LM 0.12" protocol, and it
+ must be in user level security mode.
+
+ NNNNOOOOTTTTEEEE:::: Using a password server means your UNIX box
+ (running Samba) is only as secure as your password
+ server. DDDDOOOO NNNNOOOOTTTT CCCCHHHHOOOOOOOOSSSSEEEE AAAA PPPPAAAASSSSSSSSWWWWOOOORRRRDDDD SSSSEEEERRRRVVVVEEEERRRR TTTTHHHHAAAATTTT YYYYOOOOUUUU DDDDOOOONNNN''''TTTT
+ CCCCOOOOMMMMPPPPLLLLEEEETTTTEEEELLLLYYYY TTTTRRRRUUUUSSSSTTTT.
+
+ Never point a Samba server at itself for password
+ serving. This will cause a loop and could lock up your
+ Samba server!
+
+
+
+ Page 90 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The name of the password server takes the standard
+ substitutions, but probably the only useful one is %_m ,
+ which means the Samba server will use the incoming
+ client as the password server. If you use this then you
+ better trust your clients, and you had better restrict
+ them with hosts allow!
+
+ If the _s_e_c_u_r_i_t_y parameter is set to domain, then the
+ list of machines in this option must be a list of
+ Primary or Backup Domain controllers for the Domain or
+ the character '*', as the Samba server is effectively
+ in that domain, and will use cryptographically
+ authenticated RPC calls to authenticate the user
+ logging on. The advantage of using sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn
+ is that if you list several hosts in the _p_a_s_s_w_o_r_d
+ _s_e_r_v_e_r option then ssssmmmmbbbbdddd will try each in turn till it
+ finds one that responds. This is useful in case your
+ primary server goes down.
+
+ If the _p_a_s_s_w_o_r_d _s_e_r_v_e_r option is set to the character
+ '*', then Samba will attempt to auto-locate the Primary
+ or Backup Domain controllers to authenticate against by
+ doing a query for the name WORKGROUP<1C> and then
+ contacting each server returned in the list of IP
+ addresses from the name resolution source.
+
+ If the _s_e_c_u_r_i_t_y parameter is set to server, then there
+ are different restrictions that sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn
+ doesn't suffer from:
+
+ o+ You may list several password servers in the _p_a_s_s_w_o_r_d
+ _s_e_r_v_e_r parameter, however if an ssssmmmmbbbbdddd makes a
+ connection to a password server, and then the
+ password server fails, no more users will be able to
+ be authenticated from this ssssmmmmbbbbdddd. This is a
+ restriction of the SMB/CIFS protocol when in sssseeeeccccuuuurrrriiiittttyyyy
+ ==== sssseeeerrrrvvvveeeerrrr mode and cannot be fixed in Samba.
+
+ o+ If you are using a Windows NT server as your password
+ server then you will have to ensure that your users
+ are able to login from the Samba server, as when in
+ sssseeeeccccuuuurrrriiiittttyyyy ==== sssseeeerrrrvvvveeeerrrr mode the network logon will appear
+ to come from there rather than from the users
+ workstation.
+
+ See also the _s_e_c_u_r_i_t_y parameter.
+
+ Default: ppppaaaasssssssswwwwoooorrrrdddd sssseeeerrrrvvvveeeerrrr ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: ppppaaaasssssssswwwwoooorrrrdddd sssseeeerrrrvvvveeeerrrr ==== NNNNTTTT----PPPPDDDDCCCC,,,, NNNNTTTT----BBBBDDDDCCCC1111,,,, NNNNTTTT----BBBBDDDDCCCC2222
+
+ Example: ppppaaaasssssssswwwwoooorrrrdddd sssseeeerrrrvvvveeeerrrr ==== ****
+
+
+
+ Page 91 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ ppppaaaatttthhhh ((((SSSS))))
+ This parameter specifies a directory to which the user
+ of the service is to be given access. In the case of
+ printable services, this is where print data will spool
+ prior to being submitted to the host for printing.
+
+ For a printable service offering guest access, the
+ service should be readonly and the path should be
+ world-writeable and have the sticky bit set. This is
+ not mandatory of course, but you probably won't get the
+ results you expect if you do otherwise.
+
+ Any occurrences of %_u in the path will be replaced with
+ the UNIX username that the client is using on this
+ connection. Any occurrences of %_m will be replaced by
+ the NetBIOS name of the machine they are connecting
+ from. These replacements are very useful for setting up
+ pseudo home directories for users.
+
+ Note that this path will be based on _r_o_o_t _d_i_r if one
+ was specified.
+
+ Default: nnnnoooonnnneeee
+
+ Example: ppppaaaatttthhhh ==== ////hhhhoooommmmeeee////ffffrrrreeeedddd
+
+ ppppiiiidddd ddddiiiirrrreeeeccccttttoooorrrryyyy ((((GGGG))))
+ This option specifies the directory where pid files
+ will be placed.
+
+ Default: ppppiiiidddd ddddiiiirrrreeeeccccttttoooorrrryyyy ==== $$$${{{{pppprrrreeeeffffiiiixxxx}}}}////vvvvaaaarrrr////lllloooocccckkkkssss
+
+ Example: ppppiiiidddd ddddiiiirrrreeeeccccttttoooorrrryyyy ==== ////vvvvaaaarrrr////rrrruuuunnnn////
+
+ ppppoooossssiiiixxxx lllloooocccckkkkiiiinnnngggg ((((SSSS))))
+ The ssssmmmmbbbbdddd((((8888)))) daemon maintains an database of file locks
+ obtained by SMB clients. The default behavior is to
+ map this internal database to POSIX locks. This means
+ that file locks obtained by SMB clients are consistent
+ with those seen by POSIX compliant applications
+ accessing the files via a non-SMB method (e.g. NFS or
+ local file access). You should never need to disable
+ this parameter.
+
+ Default: ppppoooossssiiiixxxx lllloooocccckkkkiiiinnnngggg ==== yyyyeeeessss
+
+ ppppoooosssstttteeeexxxxeeeecccc ((((SSSS))))
+ This option specifies a command to be run whenever the
+ service is disconnected. It takes the usual
+ substitutions. The command may be run as the root on
+ some systems.
+
+
+
+
+ Page 92 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ An interesting example may be to unmount server
+ resources:
+
+ ppppoooosssstttteeeexxxxeeeecccc ==== ////eeeettttcccc////uuuummmmoooouuuunnnntttt ////ccccddddrrrroooommmm
+
+ See also _p_r_e_e_x_e_c .
+
+ Default: nnnnoooonnnneeee ((((nnnnoooo ccccoooommmmmmmmaaaannnndddd eeeexxxxeeeeccccuuuutttteeeedddd))))
+
+ Example: ppppoooosssstttteeeexxxxeeeecccc ==== eeeecccchhhhoooo \\\\""""%%%%uuuu ddddiiiissssccccoooonnnnnnnneeeecccctttteeeedddd ffffrrrroooommmm %%%%SSSS ffffrrrroooommmm
+ %%%%mmmm ((((%%%%IIII))))\\\\"""" >>>>>>>> ////ttttmmmmpppp////lllloooogggg
+
+ ppppoooossssttttssssccccrrrriiiipppptttt ((((SSSS))))
+ This parameter forces a printer to interpret the print
+ files as PostScript. This is done by adding a %! to
+ the start of print output.
+
+ This is most useful when you have lots of PCs that
+ persist in putting a control-D at the start of print
+ jobs, which then confuses your printer.
+
+ Default: ppppoooossssttttssssccccrrrriiiipppptttt ==== nnnnoooo
+
+ pppprrrreeeeeeeexxxxeeeecccc ((((SSSS))))
+ This option specifies a command to be run whenever the
+ service is connected to. It takes the usual
+ substitutions.
+
+ An interesting example is to send the users a welcome
+ message every time they log in. Maybe a message of the
+ day? Here is an example:
+
+ pppprrrreeeeeeeexxxxeeeecccc ==== ccccsssshhhh ----cccc ''''eeeecccchhhhoooo \\\\""""WWWWeeeellllccccoooommmmeeee ttttoooo %%%%SSSS!!!!\\\\"""" ||||
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////ssssmmmmbbbbcccclllliiiieeeennnntttt ----MMMM %%%%mmmm ----IIII %%%%IIII'''' &&&&
+
+ Of course, this could get annoying after a while :-)
+
+ See also _p_r_e_e_x_e_c _c_l_o_s_e and _p_o_s_t_e_x_e_c .
+
+ Default: nnnnoooonnnneeee ((((nnnnoooo ccccoooommmmmmmmaaaannnndddd eeeexxxxeeeeccccuuuutttteeeedddd))))
+
+ Example: pppprrrreeeeeeeexxxxeeeecccc ==== eeeecccchhhhoooo \\\\""""%%%%uuuu ccccoooonnnnnnnneeeecccctttteeeedddd ttttoooo %%%%SSSS ffffrrrroooommmm %%%%mmmm
+ ((((%%%%IIII))))\\\\"""" >>>>>>>> ////ttttmmmmpppp////lllloooogggg
+
+ pppprrrreeeeeeeexxxxeeeecccc cccclllloooosssseeee ((((SSSS))))
+ This boolean option controls whether a non-zero return
+ code from _p_r_e_e_x_e_c should close the service being
+ connected to.
+
+ Default: pppprrrreeeeeeeexxxxeeeecccc cccclllloooosssseeee ==== nnnnoooo
+
+ pppprrrreeeeffffeeeerrrrrrrreeeedddd mmmmaaaasssstttteeeerrrr ((((GGGG))))
+
+
+
+ Page 93 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ This boolean parameter controls if nmbd(8) is a
+ preferred master browser for its workgroup.
+
+ If this is set to yes, on startup, nnnnmmmmbbbbdddd will force an
+ election, and it will have a slight advantage in
+ winning the election. It is recommended that this
+ parameter is used in conjunction with _d_o_m_a_i_n _m_a_s_t_e_r ====
+ yyyyeeeessss, so that nnnnmmmmbbbbdddd can guarantee becoming a domain
+ master.
+
+ Use this option with caution, because if there are
+ several hosts (whether Samba servers, Windows 95 or NT)
+ that are preferred master browsers on the same subnet,
+ they will each periodically and continuously attempt to
+ become the local master browser. This will result in
+ unnecessary broadcast traffic and reduced browsing
+ capabilities.
+
+ See also _o_s _l_e_v_e_l .
+
+ Default: pppprrrreeeeffffeeeerrrrrrrreeeedddd mmmmaaaasssstttteeeerrrr ==== aaaauuuuttttoooo
+
+ pppprrrreeeeffffeeeerrrreeeedddd mmmmaaaasssstttteeeerrrr ((((GGGG))))
+ Synonym for _p_r_e_f_e_r_r_e_d _m_a_s_t_e_r for people who cannot
+ spell :-).
+
+ pppprrrreeeellllooooaaaadddd
+ This is a list of services that you want to be
+ automatically added to the browse lists. This is most
+ useful for homes and printers services that would
+ otherwise not be visible.
+
+ Note that if you just want all printers in your
+ printcap file loaded then the _l_o_a_d _p_r_i_n_t_e_r_s option is
+ easier.
+
+ Default: nnnnoooo pppprrrreeeellllooooaaaaddddeeeedddd sssseeeerrrrvvvviiiicccceeeessss
+
+ Example: pppprrrreeeellllooooaaaadddd ==== ffffrrrreeeedddd llllpppp ccccoooolllloooorrrrllllpppp
+
+ pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ((((SSSS))))
+ This controls if new filenames are created with the
+ case that the client passes, or if they are forced to
+ be the _d_e_f_a_u_l_t _c_a_s_e .
+
+ Default: pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ==== yyyyeeeessss
+
+ See the section on NAME MANGLING for a fuller
+ discussion.
+
+ pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ After a print job has finished spooling to a service,
+
+
+
+ Page 94 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ this command will be used via a ssssyyyysssstttteeeemmmm(((()))) call to
+ process the spool file. Typically the command specified
+ will submit the spool file to the host's printing
+ subsystem, but there is no requirement that this be the
+ case. The server will not remove the spool file, so
+ whatever command you specify should remove the spool
+ file when it has been processed, otherwise you will
+ need to manually remove old spool files.
+
+ The print command is simply a text string. It will be
+ used verbatim after macro substitutions have been made:
+
+ s, %p - the path to the spool file name
+
+ %p - the appropriate printer name
+
+ %J - the job name as transmitted by the client.
+
+ %c - The number of printed pages of the spooled job (if
+ known).
+
+ %z - the size of the spooled print job (in bytes)
+
+ The print command MMMMUUUUSSSSTTTT contain at least one occurrence
+ of %_s or %_f - the %_p is optional. At the time a job is
+ submitted, if no printer name is supplied the %_p will
+ be silently removed from the printer command.
+
+ If specified in the [global] section, the print command
+ given will be used for any printable service that does
+ not have its own print command specified.
+
+ If there is neither a specified print command for a
+ printable service nor a global print command, spool
+ files will be created but not processed and (most
+ importantly) not removed.
+
+ Note that printing may fail on some UNIXes from the
+ nobody account. If this happens then create an
+ alternative guest account that can print and set the
+ _g_u_e_s_t _a_c_c_o_u_n_t in the [global] section.
+
+ You can form quite complex print commands by realizing
+ that they are just passed to a shell. For example the
+ following will log a print job, print the file, then
+ remove it. Note that ';' is the usual separator for
+ command in shell scripts.
+
+ pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ==== eeeecccchhhhoooo PPPPrrrriiiinnnnttttiiiinnnngggg %%%%ssss >>>>>>>> ////ttttmmmmpppp////pppprrrriiiinnnntttt....lllloooogggg;;;; llllpppprrrr
+ ----PPPP %%%%pppp %%%%ssss;;;; rrrrmmmm %%%%ssss
+
+ You may have to vary this command considerably
+
+
+
+ Page 95 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ depending on how you normally print files on your
+ system. The default for the parameter varies depending
+ on the setting of the _p_r_i_n_t_i_n_g parameter.
+
+ Default: For pppprrrriiiinnnnttttiiiinnnngggg ==== BBBBSSSSDDDD,,,, AAAAIIIIXXXX,,,, QQQQNNNNXXXX,,,, LLLLPPPPRRRRNNNNGGGG oooorrrr PPPPLLLLPPPP ::::
+
+ pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ==== llllpppprrrr ----rrrr ----PPPP%%%%pppp %%%%ssss
+
+ For pppprrrriiiinnnnttttiiiinnnngggg ==== SSSSYYYYSSSSVVVV oooorrrr HHHHPPPPUUUUXXXX ::::
+
+ pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ==== llllpppp ----cccc ----dddd%%%%pppp %%%%ssss;;;; rrrrmmmm %%%%ssss
+
+ For pppprrrriiiinnnnttttiiiinnnngggg ==== SSSSOOOOFFFFTTTTQQQQ ::::
+
+ pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ==== llllpppp ----dddd%%%%pppp ----ssss %%%%ssss;;;; rrrrmmmm %%%%ssss
+
+ For printing = CUPS : If SAMBA is compiled against
+ libcups, then printcap = cups uses the CUPS API to
+ submit jobs, etc. Otherwise it maps to the System V
+ commands with the -oraw option for printing, i.e. it
+ uses llllpppp ----cccc ----dddd%%%%pppp ----oooorrrraaaawwww;;;; rrrrmmmm %%%%ssss. With pppprrrriiiinnnnttttiiiinnnngggg ==== ccccuuuuppppssss, and
+ if SAMBA is compiled against libcups, any manually set
+ print command will be ignored.
+
+ Example: pppprrrriiiinnnntttt ccccoooommmmmmmmaaaannnndddd ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////mmmmyyyypppprrrriiiinnnnttttssssccccrrrriiiipppptttt %%%%pppp %%%%ssss
+
+ pppprrrriiiinnnntttt ooookkkk ((((SSSS))))
+ Synonym for _p_r_i_n_t_a_b_l_e.
+
+ pppprrrriiiinnnnttttaaaabbbblllleeee ((((SSSS))))
+ If this parameter is yes, then clients may open, write
+ to and submit spool files on the directory specified
+ for the service.
+
+ Note that a printable service will ALWAYS allow writing
+ to the service path (user privileges permitting) via
+ the spooling of print data. The _r_e_a_d _o_n_l_y parameter
+ controls only non-printing access to the resource.
+
+ Default: pppprrrriiiinnnnttttaaaabbbblllleeee ==== nnnnoooo
+
+ pppprrrriiiinnnnttttccccaaaapppp ((((GGGG))))
+ Synonym for _p_r_i_n_t_c_a_p _n_a_m_e.
+
+ pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ((((GGGG))))
+ This parameter may be used to override the compiled-in
+ default printcap name used by the server (usually
+ /_e_t_c/_p_r_i_n_t_c_a_p). See the discussion of the [printers]
+ section above for reasons why you might want to do
+ this.
+
+
+
+
+ Page 96 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ To use the CUPS printing interface set pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ====
+ ccccuuuuppppssss . This should be supplemented by an addtional
+ setting printing = cups in the [global] section.
+ pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ==== ccccuuuuppppssss will use the "dummy" printcap
+ created by CUPS, as specified in your CUPS
+ configuration file.
+
+ On System V systems that use llllppppssssttttaaaatttt to list available
+ printers you can use pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ==== llllppppssssttttaaaatttt to
+ automatically obtain lists of available printers. This
+ is the default for systems that define SYSV at
+ configure time in Samba (this includes most System V
+ based systems). If _p_r_i_n_t_c_a_p _n_a_m_e is set to llllppppssssttttaaaatttt on
+ these systems then Samba will launch llllppppssssttttaaaatttt ----vvvv and
+ attempt to parse the output to obtain a printer list.
+
+ A minimal printcap file would look something like this:
+
+
+ print1|My Printer 1
+ print2|My Printer 2
+ print3|My Printer 3
+ print4|My Printer 4
+ print5|My Printer 5
+
+
+
+ where the '|' separates aliases of a printer. The fact
+ that the second alias has a space in it gives a hint to
+ Samba that it's a comment.
+
+ NNNNOOOOTTTTEEEE: Under AIX the default printcap name is
+ /_e_t_c/_q_c_o_n_f_i_g. Samba will assume the file is in AIX
+ _q_c_o_n_f_i_g format if the string _q_c_o_n_f_i_g appears in the
+ printcap filename.
+
+ Default: pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ==== ////eeeettttcccc////pppprrrriiiinnnnttttccccaaaapppp
+
+ Example: pppprrrriiiinnnnttttccccaaaapppp nnnnaaaammmmeeee ==== ////eeeettttcccc////mmmmyyyypppprrrriiiinnnnttttccccaaaapppp
+
+ pppprrrriiiinnnntttteeeerrrr aaaaddddmmmmiiiinnnn ((((SSSS))))
+ This is a list of users that can do anything to
+ printers via the remote administration interfaces
+ offered by MS-RPC (usually using a NT workstation).
+ Note that the root user always has admin rights.
+
+ Default: pppprrrriiiinnnntttteeeerrrr aaaaddddmmmmiiiinnnn ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: pppprrrriiiinnnntttteeeerrrr aaaaddddmmmmiiiinnnn ==== aaaaddddmmmmiiiinnnn,,,, @@@@ssssttttaaaaffffffff
+
+ pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr ((((SSSS))))
+ NNNNooootttteeee ::::This is a deprecated parameter and will be
+
+
+
+ Page 97 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ removed in the next major release following version
+ 2.2. Please see the instructions in the Samba 2.2.
+ Printing HOWTO for more information on the new method
+ of loading printer drivers onto a Samba server.
+
+ This option allows you to control the string that
+ clients receive when they ask the server for the
+ printer driver associated with a printer. If you are
+ using Windows95 or Windows NT then you can use this to
+ automate the setup of printers on your system.
+
+ You need to set this parameter to the exact string
+ (case sensitive) that describes the appropriate printer
+ driver for your system. If you don't know the exact
+ string to use then you should first try with no
+ _p_r_i_n_t_e_r _d_r_i_v_e_r option set and the client will give you
+ a list of printer drivers. The appropriate strings are
+ shown in a scroll box after you have chosen the printer
+ manufacturer.
+
+ See also _p_r_i_n_t_e_r _d_r_i_v_e_r _f_i_l_e.
+
+ Example: pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr ==== HHHHPPPP LLLLaaaasssseeeerrrrJJJJeeeetttt 4444LLLL
+
+ pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr ffffiiiilllleeee ((((GGGG))))
+ NNNNooootttteeee ::::This is a deprecated parameter and will be
+ removed in the next major release following version
+ 2.2. Please see the instructions in the Samba 2.2.
+ Printing HOWTO for more information on the new method
+ of loading printer drivers onto a Samba server.
+
+ This parameter tells Samba where the printer driver
+ definition file, used when serving drivers to Windows
+ 95 clients, is to be found. If this is not set, the
+ default is :
+
+ _S_A_M_B_A__I_N_S_T_A_L_L__D_I_R_E_C_T_O_R_Y /_l_i_b/_p_r_i_n_t_e_r_s._d_e_f
+
+ This file is created from Windows 95 _m_s_p_r_i_n_t._i_n_f files
+ found on the Windows 95 client system. For more details
+ on setting up serving of printer drivers to Windows 95
+ clients, see the outdated documentation file in the
+ _d_o_c_s/ directory, _P_R_I_N_T_E_R__D_R_I_V_E_R._t_x_t.
+
+ See also _p_r_i_n_t_e_r _d_r_i_v_e_r _l_o_c_a_t_i_o_n.
+
+ Default: NNNNoooonnnneeee ((((sssseeeetttt iiiinnnn ccccoooommmmppppiiiilllleeee))))....
+
+ Example: pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr ffffiiiilllleeee ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////pppprrrriiiinnnntttteeeerrrrssss////ddddrrrriiiivvvveeeerrrrssss....ddddeeeeffff
+
+ pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr llllooooccccaaaattttiiiioooonnnn ((((SSSS))))
+
+
+
+ Page 98 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ NNNNooootttteeee ::::This is a deprecated parameter and will be
+ removed in the next major release following version
+ 2.2. Please see the instructions in the Samba 2.2.
+ Printing HOWTO for more information on the new method
+ of loading printer drivers onto a Samba server.
+
+ This parameter tells clients of a particular printer
+ share where to find the printer driver files for the
+ automatic installation of drivers for Windows 95
+ machines. If Samba is set up to serve printer drivers
+ to Windows 95 machines, this should be set to
+
+ \\\\\\\\MMMMAAAACCCCHHHHIIIINNNNEEEE\\\\PPPPRRRRIIIINNNNTTTTEEEERRRR$$$$
+
+ Where MACHINE is the NetBIOS name of your Samba server,
+ and PRINTER$ is a share you set up for serving printer
+ driver files. For more details on setting this up see
+ the outdated documentation file in the _d_o_c_s/ directory,
+ _P_R_I_N_T_E_R__D_R_I_V_E_R._t_x_t.
+
+ See also _p_r_i_n_t_e_r _d_r_i_v_e_r _f_i_l_e.
+
+ Default: nnnnoooonnnneeee
+
+ Example: pppprrrriiiinnnntttteeeerrrr ddddrrrriiiivvvveeeerrrr llllooooccccaaaattttiiiioooonnnn ==== \\\\\\\\MMMMAAAACCCCHHHHIIIINNNNEEEE\\\\PPPPRRRRIIIINNNNTTTTEEEERRRR$$$$
+
+ pppprrrriiiinnnntttteeeerrrr nnnnaaaammmmeeee ((((SSSS))))
+ This parameter specifies the name of the printer to
+ which print jobs spooled through a printable service
+ will be sent.
+
+ If specified in the [global] section, the printer name
+ given will be used for any printable service that does
+ not have its own printer name specified.
+
+ Default: nnnnoooonnnneeee ((((bbbbuuuutttt mmmmaaaayyyy bbbbeeee llllpppp oooonnnn mmmmaaaannnnyyyy ssssyyyysssstttteeeemmmmssss))))
+
+ Example: pppprrrriiiinnnntttteeeerrrr nnnnaaaammmmeeee ==== llllaaaasssseeeerrrrwwwwrrrriiiitttteeeerrrr
+
+ pppprrrriiiinnnntttteeeerrrr ((((SSSS))))
+ Synonym for _p_r_i_n_t_e_r _n_a_m_e.
+
+ pppprrrriiiinnnnttttiiiinnnngggg ((((SSSS))))
+ This parameters controls how printer status information
+ is interpreted on your system. It also affects the
+ default values for the _p_r_i_n_t _c_o_m_m_a_n_d, _l_p_q _c_o_m_m_a_n_d,
+ _l_p_p_a_u_s_e _c_o_m_m_a_n_d , _l_p_r_e_s_u_m_e _c_o_m_m_a_n_d, and _l_p_r_m _c_o_m_m_a_n_d if
+ specified in the [global] section.
+
+ Currently nine printing styles are supported. They are
+ BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, SOFTQ, and CUPS.
+
+
+
+
+ Page 99 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ To see what the defaults are for the other print
+ commands when using the various options use the
+ testparm(1) program.
+
+ This option can be set on a per printer basis
+
+ See also the discussion in the [printers] section.
+
+ pppprrrrooooffffiiiilllleeee aaaaccccllllssss ((((SSSS))))
+ This boolean parameter was added to fix the problems
+ that people have been having with storing user profiles
+ on Samba shares from Windows 2000 or Windows XP
+ clients. New versions of Windows 2000 or Windows XP
+ service packs do security ACL checking on the owner and
+ ability to write of the profile directory stored on a
+ local workstation when copied from a Samba share. When
+ not in domain mode with winbindd then the security info
+ copied onto the local workstation has no meaning to the
+ logged in user (SID) on that workstation so the profile
+ storing fails. Adding this parameter onto a share used
+ for profile storage changes two things about the
+ returned Windows ACL. Firstly it changes the owner and
+ group owner of all reported files and directories to be
+ BUILTIN\Administrators, BUILTIN\Users respectively
+ (SIDs S-1-5-32-544, S-1-5-32-545). Secondly it adds an
+ ACE entry of "Full Control" to the SID BUILTIN\Users to
+ every returned ACL. This will allow any Windows 2000 or
+ XP workstation user to access the profile. Note that if
+ you have multiple users logging on to a workstation
+ then in order to prevent them from being able to access
+ each others profiles you must remove the "Bypass
+ traverse checking" advanced user right. This will
+ prevent access to other users profile directories as
+ the top level profile directory (named after the user)
+ is created by the workstation profile code and has an
+ ACL restricting entry to the directory tree to the
+ owning user.
+
+ If you didn't understand the above text, you probably
+ should not set this parameter :-).
+
+ Default pppprrrrooooffffiiiilllleeee aaaaccccllllssss ==== nnnnoooo
+
+ pppprrrroooottttooooccccoooollll ((((GGGG))))
+ Synonym for _m_a_x _p_r_o_t_o_c_o_l.
+
+ ppppuuuubbbblllliiiicccc ((((SSSS))))
+ Synonym for _g_u_e_s_t _o_k.
+
+ qqqquuuueeeeuuuueeeeppppaaaauuuusssseeee ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to pause the printer queue.
+
+
+
+ Page 100 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ This command should be a program or script which takes
+ a printer name as its only parameter and stops the
+ printer queue, such that no longer jobs are submitted
+ to the printer.
+
+ This command is not supported by Windows for
+ Workgroups, but can be issued from the Printers window
+ under Windows 95 and NT.
+
+ If a %_p is given then the printer name is put in its
+ place. Otherwise it is placed at the end of the
+ command.
+
+ Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to
+ the server.
+
+ Default: ddddeeeeppppeeeennnnddddssss oooonnnn tttthhhheeee sssseeeettttttttiiiinnnngggg ooooffff _p_r_i_n_t_i_n_g
+
+ Example: qqqquuuueeeeuuuueeeeppppaaaauuuusssseeee ccccoooommmmmmmmaaaannnndddd ==== ddddiiiissssaaaabbbblllleeee %%%%pppp
+
+ qqqquuuueeeeuuuueeeerrrreeeessssuuuummmmeeee ccccoooommmmmmmmaaaannnndddd ((((SSSS))))
+ This parameter specifies the command to be executed on
+ the server host in order to resume the printer queue.
+ It is the command to undo the behavior that is caused
+ by the previous parameter ( _q_u_e_u_e_p_a_u_s_e _c_o_m_m_a_n_d).
+
+ This command should be a program or script which takes
+ a printer name as its only parameter and resumes the
+ printer queue, such that queued jobs are resubmitted to
+ the printer.
+
+ This command is not supported by Windows for
+ Workgroups, but can be issued from the Printers window
+ under Windows 95 and NT.
+
+ If a %_p is given then the printer name is put in its
+ place. Otherwise it is placed at the end of the
+ command.
+
+ Note that it is good practice to include the absolute
+ path in the command as the PATH may not be available to
+ the server.
+
+ Default: ddddeeeeppppeeeennnnddddssss oooonnnn tttthhhheeee sssseeeettttttttiiiinnnngggg ooooffff _p_r_i_n_t_i_n_g
+
+ Example: qqqquuuueeeeuuuueeeeppppaaaauuuusssseeee ccccoooommmmmmmmaaaannnndddd ==== eeeennnnaaaabbbblllleeee %%%%pppp
+
+ rrrreeeeaaaadddd bbbbmmmmppppxxxx ((((GGGG))))
+ This boolean parameter controls whether smbd(8) will
+ support the "Read Block Multiplex" SMB. This is now
+ rarely used and defaults to no. You should never need
+
+
+
+ Page 101 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ to set this parameter.
+
+ Default: rrrreeeeaaaadddd bbbbmmmmppppxxxx ==== nnnnoooo
+
+ rrrreeeeaaaadddd lllliiiisssstttt ((((SSSS))))
+ This is a list of users that are given read-only access
+ to a service. If the connecting user is in this list
+ then they will not be given write access, no matter
+ what the _r_e_a_d _o_n_l_y option is set to. The list can
+ include group names using the syntax described in the
+ _i_n_v_a_l_i_d _u_s_e_r_s parameter.
+
+ See also the _w_r_i_t_e _l_i_s_t parameter and the _i_n_v_a_l_i_d
+ _u_s_e_r_s parameter.
+
+ Default: rrrreeeeaaaadddd lllliiiisssstttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: rrrreeeeaaaadddd lllliiiisssstttt ==== mmmmaaaarrrryyyy,,,, @@@@ssssttttuuuuddddeeeennnnttttssss
+
+ rrrreeeeaaaadddd oooonnnnllllyyyy ((((SSSS))))
+ An inverted synonym is _w_r_i_t_e_a_b_l_e.
+
+ If this parameter is yes, then users of a service may
+ not create or modify files in the service's directory.
+
+ Note that a printable service (pppprrrriiiinnnnttttaaaabbbblllleeee ==== yyyyeeeessss) will
+ AAAALLLLWWWWAAAAYYYYSSSS allow writing to the directory (user privileges
+ permitting), but only via spooling operations.
+
+ Default: rrrreeeeaaaadddd oooonnnnllllyyyy ==== yyyyeeeessss
+
+ rrrreeeeaaaadddd rrrraaaawwww ((((GGGG))))
+ This parameter controls whether or not the server will
+ support the raw read SMB requests when transferring
+ data to clients.
+
+ If enabled, raw reads allow reads of 65535 bytes in one
+ packet. This typically provides a major performance
+ benefit.
+
+ However, some clients either negotiate the allowable
+ block size incorrectly or are incapable of supporting
+ larger block sizes, and for these clients you may need
+ to disable raw reads.
+
+ In general this parameter should be viewed as a system
+ tuning tool and left severely alone. See also _w_r_i_t_e
+ _r_a_w.
+
+ Default: rrrreeeeaaaadddd rrrraaaawwww ==== yyyyeeeessss
+
+ rrrreeeeaaaadddd ssssiiiizzzzeeee ((((GGGG))))
+
+
+
+ Page 102 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The option _r_e_a_d _s_i_z_e affects the overlap of disk
+ reads/writes with network reads/writes. If the amount
+ of data being transferred in several of the SMB
+ commands (currently SMBwrite, SMBwriteX and
+ SMBreadbraw) is larger than this value then the server
+ begins writing the data before it has received the
+ whole packet from the network, or in the case of
+ SMBreadbraw, it begins writing to the network before
+ all the data has been read from disk.
+
+ This overlapping works best when the speeds of disk and
+ network access are similar, having very little effect
+ when the speed of one is much greater than the other.
+
+ The default value is 16384, but very little
+ experimentation has been done yet to determine the
+ optimal value, and it is likely that the best value
+ will vary greatly between systems anyway. A value over
+ 65536 is pointless and will cause you to allocate
+ memory unnecessarily.
+
+ Default: rrrreeeeaaaadddd ssssiiiizzzzeeee ==== 11116666333388884444
+
+ Example: rrrreeeeaaaadddd ssssiiiizzzzeeee ==== 8888111199992222
+
+ rrrreeeemmmmooootttteeee aaaannnnnnnnoooouuuunnnncccceeee ((((GGGG))))
+ This option allows you to setup nmbd(8) to periodically
+ announce itself to arbitrary IP addresses with an
+ arbitrary workgroup name.
+
+ This is useful if you want your Samba server to appear
+ in a remote workgroup for which the normal browse
+ propagation rules don't work. The remote workgroup can
+ be anywhere that you can send IP packets to.
+
+ For example:
+
+ rrrreeeemmmmooootttteeee aaaannnnnnnnoooouuuunnnncccceeee ==== 111199992222....111166668888....2222....222255555555////SSSSEEEERRRRVVVVEEEERRRRSSSS
+ 111199992222....111166668888....4444....222255555555////SSSSTTTTAAAAFFFFFFFF
+
+ the above line would cause nnnnmmmmbbbbdddd to announce itself to
+ the two given IP addresses using the given workgroup
+ names. If you leave out the workgroup name then the one
+ given in the _w_o_r_k_g_r_o_u_p parameter is used instead.
+
+ The IP addresses you choose would normally be the
+ broadcast addresses of the remote networks, but can
+ also be the IP addresses of known browse masters if
+ your network config is that stable.
+
+ See the documentation file _B_R_O_W_S_I_N_G._t_x_t in the _d_o_c_s/
+ directory.
+
+
+
+ Page 103 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: rrrreeeemmmmooootttteeee aaaannnnnnnnoooouuuunnnncccceeee ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ rrrreeeemmmmooootttteeee bbbbrrrroooowwwwsssseeee ssssyyyynnnncccc ((((GGGG))))
+ This option allows you to setup nmbd(8) to periodically
+ request synchronization of browse lists with the master
+ browser of a Samba server that is on a remote segment.
+ This option will allow you to gain browse lists for
+ multiple workgroups across routed networks. This is
+ done in a manner that does not work with any non-Samba
+ servers.
+
+ This is useful if you want your Samba server and all
+ local clients to appear in a remote workgroup for which
+ the normal browse propagation rules don't work. The
+ remote workgroup can be anywhere that you can send IP
+ packets to.
+
+ For example:
+
+ rrrreeeemmmmooootttteeee bbbbrrrroooowwwwsssseeee ssssyyyynnnncccc ==== 111199992222....111166668888....2222....222255555555 111199992222....111166668888....4444....222255555555
+
+ the above line would cause nnnnmmmmbbbbdddd to request the master
+ browser on the specified subnets or addresses to
+ synchronize their browse lists with the local server.
+
+ The IP addresses you choose would normally be the
+ broadcast addresses of the remote networks, but can
+ also be the IP addresses of known browse masters if
+ your network config is that stable. If a machine IP
+ address is given Samba makes NO attempt to validate
+ that the remote machine is available, is listening, nor
+ that it is in fact the browse master on its segment.
+
+ Default: rrrreeeemmmmooootttteeee bbbbrrrroooowwwwsssseeee ssssyyyynnnncccc ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ rrrreeeessssttttrrrriiiicccctttt aaaannnnoooonnnnyyyymmmmoooouuuussss ((((GGGG))))
+ This is a boolean parameter. If it is yes, then
+ anonymous access to the server will be restricted,
+ namely in the case where the server is expecting the
+ client to send a username, but it doesn't. Setting it
+ to yes will force these anonymous connections to be
+ denied, and the client will be required to always
+ supply a username and password when connecting. Use of
+ this parameter is only recommended for homogeneous NT
+ client environments.
+
+ This parameter makes the use of macro expansions that
+ rely on the username (%U, %G, etc) consistent. NT 4.0
+ likes to use anonymous connections when refreshing the
+ share list, and this is a way to work around that.
+
+ When restrict anonymous is yes, all anonymous
+
+
+
+ Page 104 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ connections are denied no matter what they are for.
+ This can effect the ability of a machine to access the
+ Samba Primary Domain Controller to revalidate its
+ machine account after someone else has logged on the
+ client interactively. The NT client will display a
+ message saying that the machine's account in the domain
+ doesn't exist or the password is bad. The best way to
+ deal with this is to reboot NT client machines between
+ interactive logons, using "Shutdown and Restart",
+ rather than "Close all programs and logon as a
+ different user".
+
+ Default: rrrreeeessssttttrrrriiiicccctttt aaaannnnoooonnnnyyyymmmmoooouuuussss ==== nnnnoooo
+
+ rrrrooooooootttt ((((GGGG))))
+ Synonym for _r_o_o_t _d_i_r_e_c_t_o_r_y".
+
+ rrrrooooooootttt ddddiiiirrrr ((((GGGG))))
+ Synonym for _r_o_o_t _d_i_r_e_c_t_o_r_y".
+
+ rrrrooooooootttt ddddiiiirrrreeeeccccttttoooorrrryyyy ((((GGGG))))
+ The server will cccchhhhrrrrooooooootttt(((()))) (i.e. Change its root
+ directory) to this directory on startup. This is not
+ strictly necessary for secure operation. Even without
+ it the server will deny access to files not in one of
+ the service entries. It may also check for, and deny
+ access to, soft links to other parts of the filesystem,
+ or attempts to use ".." in file names to access other
+ directories (depending on the setting of the _w_i_d_e _l_i_n_k_s
+ parameter).
+
+ Adding a _r_o_o_t _d_i_r_e_c_t_o_r_y entry other than "/" adds an
+ extra level of security, but at a price. It absolutely
+ ensures that no access is given to files not in the
+ sub-tree specified in the _r_o_o_t _d_i_r_e_c_t_o_r_y option,
+ iiiinnnncccclllluuuuddddiiiinnnngggg some files needed for complete operation of
+ the server. To maintain full operability of the server
+ you will need to mirror some system files into the _r_o_o_t
+ _d_i_r_e_c_t_o_r_y tree. In particular you will need to mirror
+ /_e_t_c/_p_a_s_s_w_d (or a subset of it), and any binaries or
+ configuration files needed for printing (if required).
+ The set of files that must be mirrored is operating
+ system dependent.
+
+ Default: rrrrooooooootttt ddddiiiirrrreeeeccccttttoooorrrryyyy ==== ////
+
+ Example: rrrrooooooootttt ddddiiiirrrreeeeccccttttoooorrrryyyy ==== ////hhhhoooommmmeeeessss////ssssmmmmbbbb
+
+ rrrrooooooootttt ppppoooosssstttteeeexxxxeeeecccc ((((SSSS))))
+ This is the same as the _p_o_s_t_e_x_e_c parameter except that
+ the command is run as root. This is useful for
+ unmounting filesystems (such as CDROMs) after a
+
+
+
+ Page 105 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ connection is closed.
+
+ See also _p_o_s_t_e_x_e_c.
+
+ Default: rrrrooooooootttt ppppoooosssstttteeeexxxxeeeecccc ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ rrrrooooooootttt pppprrrreeeeeeeexxxxeeeecccc ((((SSSS))))
+ This is the same as the _p_r_e_e_x_e_c parameter except that
+ the command is run as root. This is useful for mounting
+ filesystems (such as CDROMs) when a connection is
+ opened.
+
+ See also _p_r_e_e_x_e_c and _p_r_e_e_x_e_c _c_l_o_s_e.
+
+ Default: rrrrooooooootttt pppprrrreeeeeeeexxxxeeeecccc ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ rrrrooooooootttt pppprrrreeeeeeeexxxxeeeecccc cccclllloooosssseeee ((((SSSS))))
+ This is the same as the _p_r_e_e_x_e_c _c_l_o_s_e parameter except
+ that the command is run as root.
+
+ See also _p_r_e_e_x_e_c and _p_r_e_e_x_e_c _c_l_o_s_e.
+
+ Default: rrrrooooooootttt pppprrrreeeeeeeexxxxeeeecccc cccclllloooosssseeee ==== nnnnoooo
+
+ sssseeeeccccuuuurrrriiiittttyyyy ((((GGGG))))
+ This option affects how clients respond to Samba and is
+ one of the most important settings in the _s_m_b._c_o_n_f
+ file.
+
+ The option sets the "security mode bit" in replies to
+ protocol negotiations with smbd(8)
+ to turn share level security on or off. Clients decide
+ based on this bit whether (and how) to transfer user
+ and password information to the server.
+
+ The default is sssseeeeccccuuuurrrriiiittttyyyy ==== uuuusssseeeerrrr, as this is the most
+ common setting needed when talking to Windows 98 and
+ Windows NT.
+
+ The alternatives are sssseeeeccccuuuurrrriiiittttyyyy ==== sssshhhhaaaarrrreeee, sssseeeeccccuuuurrrriiiittttyyyy ====
+ sssseeeerrrrvvvveeeerrrr or sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn .
+
+ In versions of Samba prior to 2.0.0, the default was
+ sssseeeeccccuuuurrrriiiittttyyyy ==== sssshhhhaaaarrrreeee mainly because that was the only
+ option at one stage.
+
+ There is a bug in WfWg that has relevance to this
+ setting. When in user or server level security a WfWg
+ client will totally ignore the password you type in the
+ "connect drive" dialog box. This makes it very
+ difficult (if not impossible) to connect to a Samba
+ service as anyone except the user that you are logged
+
+
+
+ Page 106 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ into WfWg as.
+
+ If your PCs use usernames that are the same as their
+ usernames on the UNIX machine then you will want to use
+ sssseeeeccccuuuurrrriiiittttyyyy ==== uuuusssseeeerrrr. If you mostly use usernames that don't
+ exist on the UNIX box then use sssseeeeccccuuuurrrriiiittttyyyy ==== sssshhhhaaaarrrreeee.
+
+ You should also use sssseeeeccccuuuurrrriiiittttyyyy ==== sssshhhhaaaarrrreeee if you want to
+ mainly setup shares without a password (guest shares).
+ This is commonly used for a shared printer server. It
+ is more difficult to setup guest shares with sssseeeeccccuuuurrrriiiittttyyyy ====
+ uuuusssseeeerrrr, see the _m_a_p _t_o _g_u_e_s_t parameter for details.
+
+ It is possible to use ssssmmmmbbbbdddd in a hhhhyyyybbbbrrrriiiidddd mmmmooooddddeeee where it
+ is offers both user and share level security under
+ different _N_e_t_B_I_O_S _a_l_i_a_s_e_s.
+
+ The different settings will now be explained.
+
+ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY ==== SSSSHHHHAAAARRRREEEE
+
+ When clients connect to a share level security server
+ they need not log onto the server with a valid username
+ and password before attempting to connect to a shared
+ resource (although modern clients such as Windows 95/98
+ and Windows NT will send a logon request with a
+ username but no password when talking to a sssseeeeccccuuuurrrriiiittttyyyy ====
+ sssshhhhaaaarrrreeee server). Instead, the clients send authentication
+ information (passwords) on a per-share basis, at the
+ time they attempt to connect to that share.
+
+ Note that ssssmmmmbbbbdddd AAAALLLLWWWWAAAAYYYYSSSS uses a valid UNIX user to act on
+ behalf of the client, even in sssseeeeccccuuuurrrriiiittttyyyy ==== sssshhhhaaaarrrreeee level
+ security.
+
+ As clients are not required to send a username to the
+ server in share level security, ssssmmmmbbbbdddd uses several
+ techniques to determine the correct UNIX user to use on
+ behalf of the client.
+
+ A list of possible UNIX usernames to match with the
+ given client password is constructed using the
+ following methods :
+
+ o+ If the _g_u_e_s_t _o_n_l_y parameter is set, then all the
+ other stages are missed and only the _g_u_e_s_t _a_c_c_o_u_n_t
+ username is checked.
+
+ o+ Is a username is sent with the share connection
+ request, then this username (after mapping - see
+ _u_s_e_r_n_a_m_e _m_a_p), is added as a potential username.
+
+
+
+
+ Page 107 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ If the client did a previous llllooooggggoooonnnn request (the
+ SessionSetup SMB call) then the username sent in this
+ SMB will be added as a potential username.
+
+ o+ The name of the service the client requested is added
+ as a potential username.
+
+ o+ The NetBIOS name of the client is added to the list
+ as a potential username.
+
+ o+ Any users on the _u_s_e_r list are added as potential
+ usernames.
+
+ If the _g_u_e_s_t _o_n_l_y parameter is not set, then this list is
+ then tried with the supplied password. The first user for
+ whom the password matches will be used as the UNIX user.
+
+ If the _g_u_e_s_t _o_n_l_y parameter is set, or no username can be
+ determined then if the share is marked as available to the
+ _g_u_e_s_t _a_c_c_o_u_n_t, then this guest user will be used, otherwise
+ access is denied.
+
+ Note that it can be vvvveeeerrrryyyy confusing in share-level security
+ as to which UNIX username will eventually be used in
+ granting access.
+
+ See also the section NOTE ABOUT USERNAME/PASSWORD
+ VALIDATION.
+
+ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY ==== UUUUSSSSEEEERRRR
+
+ This is the default security setting in Samba 2.2. With
+ user-level security a client must first "log-on" with a
+ valid username and password (which can be mapped using the
+ _u_s_e_r_n_a_m_e _m_a_p parameter). Encrypted passwords (see the
+ _e_n_c_r_y_p_t_e_d _p_a_s_s_w_o_r_d_s parameter) can also be used in this
+ security mode. Parameters such as _u_s_e_r and _g_u_e_s_t _o_n_l_y if
+ set are then applied and may change the UNIX user to use on
+ this connection, but only after the user has been
+ successfully authenticated.
+
+ NNNNooootttteeee that the name of the resource being requested is nnnnooootttt
+ sent to the server until after the server has successfully
+ authenticated the client. This is why guest shares don't
+ work in user level security without allowing the server to
+ automatically map unknown users into the _g_u_e_s_t _a_c_c_o_u_n_t. See
+ the _m_a_p _t_o _g_u_e_s_t parameter for details on doing this.
+
+ See also the section NOTE ABOUT USERNAME/PASSWORD
+ VALIDATION.
+
+ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY ==== SSSSEEEERRRRVVVVEEEERRRR
+
+
+
+ Page 108 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ In this mode Samba will try to validate the
+ username/password by passing it to another SMB server, such
+ as an NT box. If this fails it will revert to sssseeeeccccuuuurrrriiiittttyyyy ====
+ uuuusssseeeerrrr, but note that if encrypted passwords have been
+ negotiated then Samba cannot revert back to checking the
+ UNIX password file, it must have a valid _s_m_b_p_a_s_s_w_d file to
+ check users against. See the documentation file in the _d_o_c_s/
+ directory _E_N_C_R_Y_P_T_I_O_N._t_x_t for details on how to set this up.
+
+ NNNNooootttteeee that from the client's point of view sssseeeeccccuuuurrrriiiittttyyyy ==== sssseeeerrrrvvvveeeerrrr
+ is the same as sssseeeeccccuuuurrrriiiittttyyyy ==== uuuusssseeeerrrr. It only affects how the
+ server deals with the authentication, it does not in any way
+ affect what the client sees.
+
+ NNNNooootttteeee that the name of the resource being requested is nnnnooootttt
+ sent to the server until after the server has successfully
+ authenticated the client. This is why guest shares don't
+ work in user level security without allowing the server to
+ automatically map unknown users into the _g_u_e_s_t _a_c_c_o_u_n_t. See
+ the _m_a_p _t_o _g_u_e_s_t parameter for details on doing this.
+
+ See also the section NOTE ABOUT USERNAME/PASSWORD
+ VALIDATION.
+
+ See also the _p_a_s_s_w_o_r_d _s_e_r_v_e_r parameter and the _e_n_c_r_y_p_t_e_d
+ _p_a_s_s_w_o_r_d_s parameter.
+
+ SSSSEEEECCCCUUUURRRRIIIITTTTYYYY ==== DDDDOOOOMMMMAAAAIIIINNNN
+
+ This mode will only work correctly if smbpasswd(8) has been
+ used to add this machine into a Windows NT Domain. It
+ expects the _e_n_c_r_y_p_t_e_d _p_a_s_s_w_o_r_d_s parameter to be set to yes.
+ In this mode Samba will try to validate the
+ username/password by passing it to a Windows NT Primary or
+ Backup Domain Controller, in exactly the same way that a
+ Windows NT Server would do.
+
+ NNNNooootttteeee that a valid UNIX user must still exist as well as the
+ account on the Domain Controller to allow Samba to have a
+ valid UNIX account to map file access to.
+
+ NNNNooootttteeee that from the client's point of view sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn
+ is the same as sssseeeeccccuuuurrrriiiittttyyyy ==== uuuusssseeeerrrr . It only affects how the
+ server deals with the authentication, it does not in any way
+ affect what the client sees.
+
+ NNNNooootttteeee that the name of the resource being requested is nnnnooootttt
+ sent to the server until after the server has successfully
+ authenticated the client. This is why guest shares don't
+ work in user level security without allowing the server to
+ automatically map unknown users into the _g_u_e_s_t _a_c_c_o_u_n_t. See
+ the _m_a_p _t_o _g_u_e_s_t parameter for details on doing this.
+
+
+
+ Page 109 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ BBBBUUUUGGGG:::: There is currently a bug in the implementation of
+ sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn with respect to multi-byte character set
+ usernames. The communication with a Domain Controller must
+ be done in UNICODE and Samba currently does not widen
+ multi-byte user names to UNICODE correctly, thus a multi-
+ byte username will not be recognized correctly at the Domain
+ Controller. This issue will be addressed in a future
+ release.
+
+ See also the section NOTE ABOUT USERNAME/PASSWORD
+ VALIDATION.
+
+ See also the _p_a_s_s_w_o_r_d _s_e_r_v_e_r parameter and the _e_n_c_r_y_p_t_e_d
+ _p_a_s_s_w_o_r_d_s parameter.
+
+ Default: sssseeeeccccuuuurrrriiiittttyyyy ==== UUUUSSSSEEEERRRR
+
+ Example: sssseeeeccccuuuurrrriiiittttyyyy ==== DDDDOOOOMMMMAAAAIIIINNNN
+
+ sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ((((SSSS))))
+ This parameter controls what UNIX permission bits can
+ be modified when a Windows NT client is manipulating
+ the UNIX permission on a file using the native NT
+ security dialog box.
+
+ This parameter is applied as a mask (AND'ed with) to
+ the changed permission bits, thus preventing any bits
+ not in this mask from being modified. Essentially, zero
+ bits in this mask may be treated as a set of bits the
+ user is not allowed to change.
+
+ If not set explicitly this parameter is 0777, allowing
+ a user to modify all the user/group/world permissions
+ on a file.
+
+ NNNNooootttteeee that users who can access the Samba server through
+ other means can easily bypass this restriction, so it
+ is primarily useful for standalone "appliance" systems.
+ Administrators of most normal systems will probably
+ want to leave it set to 0777.
+
+ See also the _f_o_r_c_e _d_i_r_e_c_t_o_r_y _s_e_c_u_r_i_t_y _m_o_d_e, _d_i_r_e_c_t_o_r_y
+ _s_e_c_u_r_i_t_y _m_a_s_k, _f_o_r_c_e _s_e_c_u_r_i_t_y _m_o_d_e parameters.
+
+ Default: sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ==== 0000777777777777
+
+ Example: sssseeeeccccuuuurrrriiiittttyyyy mmmmaaaasssskkkk ==== 0000777777770000
+
+ sssseeeerrrrvvvveeeerrrr ssssttttrrrriiiinnnngggg ((((GGGG))))
+ This controls what string will show up in the printer
+ comment box in print manager and next to the IPC
+ connection in nnnneeeetttt vvvviiiieeeewwww. It can be any string that you
+
+
+
+ Page 110 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ wish to show to your users.
+
+ It also sets what will appear in browse lists next to
+ the machine name.
+
+ A %_v will be replaced with the Samba version number.
+
+ A %_h will be replaced with the hostname.
+
+ Default: sssseeeerrrrvvvveeeerrrr ssssttttrrrriiiinnnngggg ==== SSSSaaaammmmbbbbaaaa %%%%vvvv
+
+ Example: sssseeeerrrrvvvveeeerrrr ssssttttrrrriiiinnnngggg ==== UUUUnnnniiiivvvveeeerrrrssssiiiittttyyyy ooooffff GGGGNNNNUUUUssss SSSSaaaammmmbbbbaaaa
+ SSSSeeeerrrrvvvveeeerrrr
+
+ sssseeeetttt ddddiiiirrrreeeeccccttttoooorrrryyyy ((((SSSS))))
+ If sssseeeetttt ddddiiiirrrreeeeccccttttoooorrrryyyy ==== nnnnoooo, then users of the service may
+ not use the setdir command to change directory.
+
+ The sssseeeettttddddiiiirrrr command is only implemented in the Digital
+ Pathworks client. See the Pathworks documentation for
+ details.
+
+ Default: sssseeeetttt ddddiiiirrrreeeeccccttttoooorrrryyyy ==== nnnnoooo
+
+ sssshhhhaaaarrrreeee mmmmooooddddeeeessss ((((SSSS))))
+ This enables or disables the honoring of the _s_h_a_r_e
+ _m_o_d_e_s during a file open. These modes are used by
+ clients to gain exclusive read or write access to a
+ file.
+
+ These open modes are not directly supported by UNIX, so
+ they are simulated using shared memory, or lock files
+ if your UNIX doesn't support shared memory (almost all
+ do).
+
+ The share modes that are enabled by this option are
+ DENY_DOS, DENY_ALL, DENY_READ, DENY_WRITE, DENY_NONE
+ and DENY_FCB.
+
+ This option gives full share compatibility and enabled
+ by default.
+
+ You should NNNNEEEEVVVVEEEERRRR turn this parameter off as many
+ Windows applications will break if you do so.
+
+ Default: sssshhhhaaaarrrreeee mmmmooooddddeeeessss ==== yyyyeeeessss
+
+ sssshhhhoooorrrrtttt pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ((((SSSS))))
+ This boolean parameter controls if new files which
+ conform to 8.3 syntax, that is all in upper case and of
+ suitable length, are created upper case, or if they are
+ forced to be the _d_e_f_a_u_l_t _c_a_s_e . This option can be use
+
+
+
+ Page 111 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ with pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ==== yyyyeeeessss to permit long filenames to
+ retain their case, while short names are lowered.
+
+ See the section on NAME MANGLING.
+
+ Default: sssshhhhoooorrrrtttt pppprrrreeeesssseeeerrrrvvvveeee ccccaaaasssseeee ==== yyyyeeeessss
+
+ sssshhhhoooowwww aaaadddddddd pppprrrriiiinnnntttteeeerrrr wwwwiiiizzzzaaaarrrrdddd ((((GGGG))))
+ With the introduction of MS-RPC based printing support
+ for Windows NT/2000 client in Samba 2.2, a
+ "Printers..." folder will appear on Samba hosts in the
+ share listing. Normally this folder will contain an
+ icon for the MS Add Printer Wizard (APW). However, it
+ is possible to disable this feature regardless of the
+ level of privilege of the connected user.
+
+ Under normal circumstances, the Windows NT/2000 client
+ will open a handle on the printer server with
+ OpenPrinterEx() asking for Administrator privileges. If
+ the user does not have administrative access on the
+ print server (i.e is not root or a member of the
+ _p_r_i_n_t_e_r _a_d_m_i_n group), the OpenPrinterEx() call fails
+ and the client makes another open call with a request
+ for a lower privilege level. This should succeed,
+ however the APW icon will not be displayed.
+
+ Disabling the _s_h_o_w _a_d_d _p_r_i_n_t_e_r _w_i_z_a_r_d parameter will
+ always cause the OpenPrinterEx() on the server to fail.
+ Thus the APW icon will never be displayed. NNNNooootttteeee ::::This
+ does not prevent the same user from having
+ administrative privilege on an individual printer.
+
+ See also _a_d_d_p_r_i_n_t_e_r _c_o_m_m_a_n_d, _d_e_l_e_t_e_p_r_i_n_t_e_r _c_o_m_m_a_n_d,
+ _p_r_i_n_t_e_r _a_d_m_i_n
+
+ Default :sssshhhhoooowwww aaaadddddddd pppprrrriiiinnnntttteeeerrrr wwwwiiiizzzzaaaarrrrdddd ==== yyyyeeeessss
+
+ ssssmmmmbbbb ppppaaaasssssssswwwwdddd ffffiiiilllleeee ((((GGGG))))
+ This option sets the path to the encrypted smbpasswd
+ file. By default the path to the smbpasswd file is
+ compiled into Samba.
+
+ Default: ssssmmmmbbbb ppppaaaasssssssswwwwdddd ffffiiiilllleeee ==== $$$${{{{pppprrrreeeeffffiiiixxxx}}}}////pppprrrriiiivvvvaaaatttteeee////ssssmmmmbbbbppppaaaasssssssswwwwdddd
+
+ Example: ssssmmmmbbbb ppppaaaasssssssswwwwdddd ffffiiiilllleeee ==== ////eeeettttcccc////ssssaaaammmmbbbbaaaa////ssssmmmmbbbbppppaaaasssssssswwwwdddd
+
+ ssssoooocccckkkkeeeetttt aaaaddddddddrrrreeeessssssss ((((GGGG))))
+ This option allows you to control what address Samba
+ will listen for connections on. This is used to support
+ multiple virtual interfaces on the one server, each
+ with a different configuration.
+
+
+
+
+ Page 112 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ By default Samba will accept connections on any
+ address.
+
+ Example: ssssoooocccckkkkeeeetttt aaaaddddddddrrrreeeessssssss ==== 111199992222....111166668888....2222....22220000
+
+ ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss ((((GGGG))))
+ This option allows you to set socket options to be used
+ when talking with the client.
+
+ Socket options are controls on the networking layer of
+ the operating systems which allow the connection to be
+ tuned.
+
+ This option will typically be used to tune your Samba
+ server for optimal performance for your local network.
+ There is no way that Samba can know what the optimal
+ parameters are for your net, so you must experiment and
+ choose them yourself. We strongly suggest you read the
+ appropriate documentation for your operating system
+ first (perhaps mmmmaaaannnn sssseeeettttssssoooocccckkkkoooopppptttt will help).
+
+ You may find that on some systems Samba will say
+ "Unknown socket option" when you supply an option. This
+ means you either incorrectly typed it or you need to
+ add an include file to includes.h for your OS. If the
+ latter is the case please send the patch to
+ samba@samba.org <URL:mailto:samba@samba.org>.
+
+ Any of the supported socket options may be combined in
+ any way you like, as long as your OS allows it.
+
+ This is the list of socket options currently settable
+ using this option:
+
+ o+ SO_KEEPALIVE
+
+ o+ SO_REUSEADDR
+
+ o+ SO_BROADCAST
+
+ o+ TCP_NODELAY
+
+ o+ IPTOS_LOWDELAY
+
+ o+ IPTOS_THROUGHPUT
+
+ o+ SO_SNDBUF *
+
+ o+ SO_RCVBUF *
+
+ o+ SO_SNDLOWAT *
+
+
+
+
+ Page 113 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ SO_RCVLOWAT *
+
+ Those marked with a ''''****'''' take an integer argument. The others
+ can optionally take a 1 or 0 argument to enable or disable
+ the option, by default they will be enabled if you don't
+ specify 1 or 0.
+
+ To specify an argument use the syntax SOME_OPTION = VALUE
+ for example SSSSOOOO____SSSSNNNNDDDDBBBBUUUUFFFF ==== 8888111199992222. Note that you must not have
+ any spaces before or after the = sign.
+
+ If you are on a local network then a sensible option might
+ be
+
+ ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss ==== IIIIPPPPTTTTOOOOSSSS____LLLLOOOOWWWWDDDDEEEELLLLAAAAYYYY
+
+ If you have a local network then you could try:
+
+ ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss ==== IIIIPPPPTTTTOOOOSSSS____LLLLOOOOWWWWDDDDEEEELLLLAAAAYYYY TTTTCCCCPPPP____NNNNOOOODDDDEEEELLLLAAAAYYYY
+
+ If you are on a wide area network then perhaps try setting
+ IPTOS_THROUGHPUT.
+
+ Note that several of the options may cause your Samba server
+ to fail completely. Use these options with caution!
+
+ Default: ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss ==== TTTTCCCCPPPP____NNNNOOOODDDDEEEELLLLAAAAYYYY
+
+ Example: ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss ==== IIIIPPPPTTTTOOOOSSSS____LLLLOOOOWWWWDDDDEEEELLLLAAAAYYYY
+
+ ssssoooouuuurrrrcccceeee eeeennnnvvvviiiirrrroooonnnnmmmmeeeennnntttt ((((GGGG))))
+ This parameter causes Samba to set environment
+ variables as per the content of the file named.
+
+ If the value of this parameter starts with a "|"
+ character then Samba will treat that value as a pipe
+ command to open and will set the environment variables
+ from the output of the pipe.
+
+ The contents of the file or the output of the pipe
+ should be formatted as the output of the standard Unix
+ eeeennnnvvvv((((1111)))) command. This is of the form :
+
+ Example environment entry:
+
+ SSSSAAAAMMMMBBBBAAAA____NNNNEEEETTTTBBBBIIIIOOOOSSSS____NNNNAAAAMMMMEEEE ==== mmmmyyyyhhhhoooossssttttnnnnaaaammmmeeee
+
+ Default: NNNNoooo ddddeeeeffffaaaauuuulllltttt vvvvaaaalllluuuueeee
+
+ Examples: ssssoooouuuurrrrcccceeee eeeennnnvvvviiiirrrroooonnnnmmmmeeeennnntttt ==== ||||////eeeettttcccc////ssssmmmmbbbb....ccccoooonnnnffff....sssshhhh
+
+ Example: ssssoooouuuurrrrcccceeee eeeennnnvvvviiiirrrroooonnnnmmmmeeeennnntttt ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssmmmmbbbb____eeeennnnvvvv____vvvvaaaarrrrssss
+
+
+
+ Page 114 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ ssssssssllll ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This variable enables or disables the entire SSL mode.
+ If it is set to no, the SSL-enabled Samba behaves
+ exactly like the non-SSL Samba. If set to yes, it
+ depends on the variables _s_s_l _h_o_s_t_s and _s_s_l _h_o_s_t_s
+ _r_e_s_i_g_n whether an SSL connection will be required.
+
+ Default: ssssssssllll ==== nnnnoooo
+
+ ssssssssllll CCCCAAAA cccceeeerrrrttttDDDDiiiirrrr ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This variable defines where to look up the
+ Certification Authorities. The given directory should
+ contain one file for each CA that Samba will trust. The
+ file name must be the hash value over the
+ "Distinguished Name" of the CA. How this directory is
+ set up is explained later in this document. All files
+ within the directory that don't fit into this naming
+ scheme are ignored. You don't need this variable if you
+ don't verify client certificates.
+
+ Default: ssssssssllll CCCCAAAA cccceeeerrrrttttDDDDiiiirrrr ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssssssllll////cccceeeerrrrttttssss
+
+ ssssssssllll CCCCAAAA cccceeeerrrrttttFFFFiiiilllleeee ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This variable is a second way to define the trusted
+ CAs. The certificates of the trusted CAs are collected
+ in one big file and this variable points to the file.
+ You will probably only use one of the two ways to
+ define your CAs. The first choice is preferable if you
+ have many CAs or want to be flexible, the second is
+ preferable if you only have one CA and want to keep
+ things simple (you won't need to create the hashed file
+ names). You don't need this variable if you don't
+ verify client certificates.
+
+ Default: ssssssssllll CCCCAAAA cccceeeerrrrttttFFFFiiiilllleeee ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssssssllll////cccceeeerrrrttttssss////ttttrrrruuuusssstttteeeeddddCCCCAAAAssss....ppppeeeemmmm
+
+
+
+
+ Page 115 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ ssssssssllll cccciiiipppphhhheeeerrrrssss ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This variable defines the ciphers that should be
+ offered during SSL negotiation. You should not set this
+ variable unless you know what you are doing.
+
+ ssssssssllll cccclllliiiieeeennnntttt cccceeeerrrrtttt ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ The certificate in this file is used by ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ if it exists. It's needed if the server requires a
+ client certificate.
+
+ Default: ssssssssllll cccclllliiiieeeennnntttt cccceeeerrrrtttt ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssssssllll////cccceeeerrrrttttssss////ssssmmmmbbbbcccclllliiiieeeennnntttt....ppppeeeemmmm
+
+ ssssssssllll cccclllliiiieeeennnntttt kkkkeeeeyyyy ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This is the private key for ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111)))) It's only
+ needed if the client should have a certificate.
+
+ Default: ssssssssllll cccclllliiiieeeennnntttt kkkkeeeeyyyy ====
+ ////uuuussssrrrr////llllooooccccaaaallll////ssssssssllll////pppprrrriiiivvvvaaaatttteeee////ssssmmmmbbbbcccclllliiiieeeennnntttt....ppppeeeemmmm
+
+ ssssssssllll ccccoooommmmppppaaaattttiiiibbbbiiiilllliiiittttyyyy ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This variable defines whether OpenSSL should be
+ configured for bug compatibility with other SSL
+ implementations. This is probably not desirable because
+ currently no clients with SSL implementations other
+ than OpenSSL exist.
+
+ Default: ssssssssllll ccccoooommmmppppaaaattttiiiibbbbiiiilllliiiittttyyyy ==== nnnnoooo
+
+ ssssssssllll eeeeggggdddd ssssoooocccckkkkeeeetttt ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+
+
+
+ Page 116 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This option is used to define the location of the
+ communiation socket of an EGD or PRNGD daemon, from
+ which entropy can be retrieved. This option can be used
+ instead of or together with the _s_s_l _e_n_t_r_o_p_y _f_i_l_e
+ directive. 255 bytes of entropy will be retrieved from
+ the daemon.
+
+ Default: nnnnoooonnnneeee
+
+ ssssssssllll eeeennnnttttrrrrooooppppyyyy bbbbyyyytttteeeessss ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This parameter is used to define the number of bytes
+ which should be read from the _s_s_l _e_n_t_r_o_p_y _f_i_l_e If a -1
+ is specified, the entire file will be read.
+
+ Default: ssssssssllll eeeennnnttttrrrrooooppppyyyy bbbbyyyytttteeeessss ==== 222255555555
+
+ ssssssssllll eeeennnnttttrrrrooooppppyyyy ffffiiiilllleeee ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This parameter is used to specify a file from which
+ processes will read "random bytes" on startup. In order
+ to seed the internal pseudo random number generator,
+ entropy must be provided. On system with a /_d_e_v/_u_r_a_n_d_o_m
+ device file, the processes will retrieve its entropy
+ from the kernel. On systems without kernel entropy
+ support, a file can be supplied that will be read on
+ startup and that will be used to seed the PRNG.
+
+ Default: nnnnoooonnnneeee
+
+ ssssssssllll hhhhoooossssttttssss ((((GGGG))))
+ See _s_s_l _h_o_s_t_s _r_e_s_i_g_n.
+
+ ssssssssllll hhhhoooossssttttssss rrrreeeessssiiiiggggnnnn ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ These two variables define whether Samba will go into
+ SSL mode or not. If none of them is defined, Samba will
+
+
+
+ Page 117 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ allow only SSL connections. If the _s_s_l _h_o_s_t_s variable
+ lists hosts (by IP-address, IP-address range, net group
+ or name), only these hosts will be forced into SSL
+ mode. If the _s_s_l _h_o_s_t_s _r_e_s_i_g_n variable lists hosts,
+ only these hosts will NNNNOOOOTTTT be forced into SSL mode. The
+ syntax for these two variables is the same as for the
+ _h_o_s_t_s _a_l_l_o_w and _h_o_s_t_s _d_e_n_y pair of variables, only
+ that the subject of the decision is different: It's not
+ the access right but whether SSL is used or not.
+
+ The example below requires SSL connections from all
+ hosts outside the local net (which is 192.168.*.*).
+
+ Default: ssssssssllll hhhhoooossssttttssss ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ ssssssssllll hhhhoooossssttttssss rrrreeeessssiiiiggggnnnn ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: ssssssssllll hhhhoooossssttttssss rrrreeeessssiiiiggggnnnn ==== 111199992222....111166668888....
+
+ ssssssssllll rrrreeeeqqqquuuuiiiirrrreeee cccclllliiiieeeennnnttttcccceeeerrrrtttt ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ If this variable is set to yes, the server will not
+ tolerate connections from clients that don't have a
+ valid certificate. The directory/file given in _s_s_l _C_A
+ _c_e_r_t_D_i_r and _s_s_l _C_A _c_e_r_t_F_i_l_e will be used to look up the
+ CAs that issued the client's certificate. If the
+ certificate can't be verified positively, the
+ connection will be terminated. If this variable is set
+ to no, clients don't need certificates. Contrary to web
+ applications you really sssshhhhoooouuuulllldddd require client
+ certificates. In the web environment the client's data
+ is sensitive (credit card numbers) and the server must
+ prove to be trustworthy. In a file server environment
+ the server's data will be sensitive and the clients
+ must prove to be trustworthy.
+
+ Default: ssssssssllll rrrreeeeqqqquuuuiiiirrrreeee cccclllliiiieeeennnnttttcccceeeerrrrtttt ==== nnnnoooo
+
+ ssssssssllll rrrreeeeqqqquuuuiiiirrrreeee sssseeeerrrrvvvveeeerrrrcccceeeerrrrtttt ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ If this variable is set to yes, the ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ will request a certificate from the server. Same as
+ _s_s_l _r_e_q_u_i_r_e _c_l_i_e_n_t_c_e_r_t for the server.
+
+
+
+
+ Page 118 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: ssssssssllll rrrreeeeqqqquuuuiiiirrrreeee sssseeeerrrrvvvveeeerrrrcccceeeerrrrtttt ==== nnnnoooo
+
+ ssssssssllll sssseeeerrrrvvvveeeerrrr cccceeeerrrrtttt ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This is the file containing the server's certificate.
+ The server mmmmuuuusssstttt have a certificate. The file may also
+ contain the server's private key. See later for how
+ certificates and private keys are created.
+
+ Default: ssssssssllll sssseeeerrrrvvvveeeerrrr cccceeeerrrrtttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ ssssssssllll sssseeeerrrrvvvveeeerrrr kkkkeeeeyyyy ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This file contains the private key of the server. If
+ this variable is not defined, the key is looked up in
+ the certificate file (it may be appended to the
+ certificate). The server mmmmuuuusssstttt have a private key and
+ the certificate mmmmuuuusssstttt match this private key.
+
+ Default: ssssssssllll sssseeeerrrrvvvveeeerrrr kkkkeeeeyyyy ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ ssssssssllll vvvveeeerrrrssssiiiioooonnnn ((((GGGG))))
+ This variable is part of SSL-enabled Samba. This is
+ only available if the SSL libraries have been compiled
+ on your system and the configure option --------wwwwiiiitttthhhh----ssssssssllll was
+ given at configure time.
+
+ This enumeration variable defines the versions of the
+ SSL protocol that will be used. ssl2or3 allows dynamic
+ negotiation of SSL v2 or v3, ssl2 results in SSL v2,
+ ssl3 results in SSL v3 and tls1 results in TLS v1. TLS
+ (Transport Layer Security) is the new standard for SSL.
+
+ Default: ssssssssllll vvvveeeerrrrssssiiiioooonnnn ==== """"ssssssssllll2222oooorrrr3333""""
+
+ ssssttttaaaatttt ccccaaaacccchhhheeee ((((GGGG))))
+ This parameter determines if smbd(8) will use a cache
+ in order to speed up case insensitive name mappings.
+ You should never need to change this parameter.
+
+ Default: ssssttttaaaatttt ccccaaaacccchhhheeee ==== yyyyeeeessss
+
+ ssssttttaaaatttt ccccaaaacccchhhheeee ssssiiiizzzzeeee ((((GGGG))))
+ This parameter determines the number of entries in the
+
+
+
+ Page 119 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ _s_t_a_t _c_a_c_h_e. You should never need to change this
+ parameter.
+
+ Default: ssssttttaaaatttt ccccaaaacccchhhheeee ssssiiiizzzzeeee ==== 55550000
+
+ ssssttttaaaattttuuuussss ((((GGGG))))
+ This enables or disables logging of connections to a
+ status file that smbstatus(1) can read.
+
+ With this disabled ssssmmmmbbbbssssttttaaaattttuuuussss won't be able to tell you
+ what connections are active. You should never need to
+ change this parameter.
+
+ Default: ssssttttaaaattttuuuussss ==== yyyyeeeessss
+
+ ssssttttrrrriiiicccctttt aaaallllllllooooccccaaaatttteeee ((((SSSS))))
+ This is a boolean that controls the handling of disk
+ space allocation in the server. When this is set to yes
+ the server will change from UNIX behaviour of not
+ committing real disk storage blocks when a file is
+ extended to the Windows behaviour of actually forcing
+ the disk system to allocate real storage blocks when a
+ file is created or extended to be a given size. In UNIX
+ terminology this means that Samba will stop creating
+ sparse files. This can be slow on some systems.
+
+ When strict allocate is no the server does sparse disk
+ block allocation when a file is extended.
+
+ Setting this to yes can help Samba return out of quota
+ messages on systems that are restricting the disk quota
+ of users.
+
+ Default: ssssttttrrrriiiicccctttt aaaallllllllooooccccaaaatttteeee ==== nnnnoooo
+
+ ssssttttrrrriiiicccctttt lllloooocccckkkkiiiinnnngggg ((((SSSS))))
+ This is a boolean that controls the handling of file
+ locking in the server. When this is set to yes the
+ server will check every read and write access for file
+ locks, and deny access if locks exist. This can be slow
+ on some systems.
+
+ When strict locking is no the server does file lock
+ checks only when the client explicitly asks for them.
+
+ Well-behaved clients always ask for lock checks when it
+ is important, so in the vast majority of cases ssssttttrrrriiiicccctttt
+ lllloooocccckkkkiiiinnnngggg ==== nnnnoooo is preferable.
+
+ Default: ssssttttrrrriiiicccctttt lllloooocccckkkkiiiinnnngggg ==== nnnnoooo
+
+ ssssttttrrrriiiicccctttt ssssyyyynnnncccc ((((SSSS))))
+
+
+
+ Page 120 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Many Windows applications (including the Windows 98
+ explorer shell) seem to confuse flushing buffer
+ contents to disk with doing a sync to disk. Under UNIX,
+ a sync call forces the process to be suspended until
+ the kernel has ensured that all outstanding data in
+ kernel disk buffers has been safely stored onto stable
+ storage. This is very slow and should only be done
+ rarely. Setting this parameter to no (the default)
+ means that smbd ignores the Windows applications
+ requests for a sync call. There is only a possibility
+ of losing data if the operating system itself that
+ Samba is running on crashes, so there is little danger
+ in this default setting. In addition, this fixes many
+ performance problems that people have reported with the
+ new Windows98 explorer shell file copies.
+
+ See also the _s_y_n_c _a_l_w_a_y_s> parameter.
+
+ Default: ssssttttrrrriiiicccctttt ssssyyyynnnncccc ==== nnnnoooo
+
+ ssssttttrrrriiiipppp ddddooootttt ((((GGGG))))
+ This parameter is now unused in Samba (2.2.5 and
+ above). It used strip trailing dots off UNIX filenames
+ but was not correctly implmented. In Samba 2.2.5 and
+ above UNIX filenames ending in a dot are invalid
+ Windows long filenames (as they are in Windows NT and
+ above) and are mangled to 8.3 before being returned to
+ a client.
+
+ Default: ssssttttrrrriiiipppp ddddooootttt ==== nnnnoooo
+
+ ssssyyyynnnncccc aaaallllwwwwaaaayyyyssss ((((SSSS))))
+ This is a boolean parameter that controls whether
+ writes will always be written to stable storage before
+ the write call returns. If this is no then the server
+ will be guided by the client's request in each write
+ call (clients can set a bit indicating that a
+ particular write should be synchronous). If this is yes
+ then every write will be followed by a ffffssssyyyynnnncccc(((()))) call to
+ ensure the data is written to disk. Note that the
+ _s_t_r_i_c_t _s_y_n_c parameter must be set to yes in order for
+ this parameter to have any affect.
+
+ See also the _s_t_r_i_c_t _s_y_n_c parameter.
+
+ Default: ssssyyyynnnncccc aaaallllwwwwaaaayyyyssss ==== nnnnoooo
+
+ ssssyyyysssslllloooogggg ((((GGGG))))
+ This parameter maps how Samba debug messages are logged
+ onto the system syslog logging levels. Samba debug
+ level zero maps onto syslog LOG_ERR, debug level one
+ maps onto LOG_WARNING, debug level two maps onto
+
+
+
+ Page 121 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ LOG_NOTICE, debug level three maps onto LOG_INFO. All
+ higher levels are mapped to LOG_DEBUG.
+
+ This parameter sets the threshold for sending messages
+ to syslog. Only messages with debug level less than
+ this value will be sent to syslog.
+
+ Default: ssssyyyysssslllloooogggg ==== 1111
+
+ ssssyyyysssslllloooogggg oooonnnnllllyyyy ((((GGGG))))
+ If this parameter is set then Samba debug messages are
+ logged into the system syslog only, and not to the
+ debug log files.
+
+ Default: ssssyyyysssslllloooogggg oooonnnnllllyyyy ==== nnnnoooo
+
+ tttteeeemmmmppppllllaaaatttteeee hhhhoooommmmeeeeddddiiiirrrr ((((GGGG))))
+ When filling out the user information for a Windows NT
+ user, the winbindd(8) daemon uses this parameter to
+ fill in the home directory for that user. If the string
+ %_D is present it is substituted with the user's Windows
+ NT domain name. If the string %_U is present it is
+ substituted with the user's Windows NT user name.
+
+ Default: tttteeeemmmmppppllllaaaatttteeee hhhhoooommmmeeeeddddiiiirrrr ==== ////hhhhoooommmmeeee////%%%%DDDD////%%%%UUUU
+
+ tttteeeemmmmppppllllaaaatttteeee sssshhhheeeellllllll ((((GGGG))))
+ When filling out the user information for a Windows NT
+ user, the winbindd(8) daemon uses this parameter to
+ fill in the login shell for that user.
+
+ Default: tttteeeemmmmppppllllaaaatttteeee sssshhhheeeellllllll ==== ////bbbbiiiinnnn////ffffaaaallllsssseeee
+
+ ttttiiiimmmmeeee ooooffffffffsssseeeetttt ((((GGGG))))
+ This parameter is a setting in minutes to add to the
+ normal GMT to local time conversion. This is useful if
+ you are serving a lot of PCs that have incorrect
+ daylight saving time handling.
+
+ Default: ttttiiiimmmmeeee ooooffffffffsssseeeetttt ==== 0000
+
+ Example: ttttiiiimmmmeeee ooooffffffffsssseeeetttt ==== 66660000
+
+ ttttiiiimmmmeeee sssseeeerrrrvvvveeeerrrr ((((GGGG))))
+ This parameter determines if nmbd(8) advertises itself
+ as a time server to Windows clients.
+
+ Default: ttttiiiimmmmeeee sssseeeerrrrvvvveeeerrrr ==== nnnnoooo
+
+ ttttiiiimmmmeeeessssttttaaaammmmpppp llllooooggggssss ((((GGGG))))
+ Synonym for _d_e_b_u_g _t_i_m_e_s_t_a_m_p.
+
+
+
+
+ Page 122 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ ttttoooottttaaaallll pppprrrriiiinnnntttt jjjjoooobbbbssss ((((GGGG))))
+ This parameter accepts an integer value which defines a
+ limit on the maximum number of print jobs that will be
+ accepted system wide at any given time. If a print job
+ is submitted by a client which will exceed this number,
+ then smbd will return an error indicating that no space
+ is available on the server. The default value of 0
+ means that no such limit exists. This parameter can be
+ used to prevent a server from exceeding its capacity
+ and is designed as a printing throttle. See also _m_a_x
+ _p_r_i_n_t _j_o_b_s.
+
+ Default: ttttoooottttaaaallll pppprrrriiiinnnntttt jjjjoooobbbbssss ==== 0000
+
+ Example: ttttoooottttaaaallll pppprrrriiiinnnntttt jjjjoooobbbbssss ==== 5555000000000000
+
+ uuuunnnniiiixxxx eeeexxxxtttteeeennnnssssiiiioooonnnnssss((((GGGG))))
+ This boolean parameter controls whether Samba implments
+ the CIFS UNIX extensions, as defined by HP. These
+ extensions enable Samba to better serve UNIX CIFS
+ clients by supporting features such as symbolic links,
+ hard links, etc... These extensions require a
+ similarly enabled client, and are of no current use to
+ Windows clients.
+
+ Default: uuuunnnniiiixxxx eeeexxxxtttteeeennnnssssiiiioooonnnnssss ==== nnnnoooo
+
+ uuuunnnniiiixxxx ppppaaaasssssssswwwwoooorrrrdddd ssssyyyynnnncccc ((((GGGG))))
+ This boolean parameter controls whether Samba attempts
+ to synchronize the UNIX password with the SMB password
+ when the encrypted SMB password in the smbpasswd file
+ is changed. If this is set to yes the program specified
+ in the _p_a_s_s_w_d _p_r_o_g_r_a_mparameter is called AAAASSSS RRRROOOOOOOOTTTT - to
+ allow the new UNIX password to be set without access to
+ the old UNIX password (as the SMB password change code
+ has no access to the old password cleartext, only the
+ new).
+
+ See also _p_a_s_s_w_d _p_r_o_g_r_a_m, _p_a_s_s_w_d _c_h_a_t.
+
+ Default: uuuunnnniiiixxxx ppppaaaasssssssswwwwoooorrrrdddd ssssyyyynnnncccc ==== nnnnoooo
+
+ uuuuppppddddaaaatttteeee eeeennnnccccrrrryyyypppptttteeeedddd ((((GGGG))))
+ This boolean parameter allows a user logging on with a
+ plaintext password to have their encrypted (hashed)
+ password in the smbpasswd file to be updated
+ automatically as they log on. This option allows a site
+ to migrate from plaintext password authentication
+ (users authenticate with plaintext password over the
+ wire, and are checked against a UNIX account database)
+ to encrypted password authentication (the SMB
+ challenge/response authentication mechanism) without
+
+
+
+ Page 123 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ forcing all users to re-enter their passwords via
+ smbpasswd at the time the change is made. This is a
+ convenience option to allow the change over to
+ encrypted passwords to be made over a longer period.
+ Once all users have encrypted representations of their
+ passwords in the smbpasswd file this parameter should
+ be set to no.
+
+ In order for this parameter to work correctly the
+ _e_n_c_r_y_p_t _p_a_s_s_w_o_r_d_s parameter must be set to no when this
+ parameter is set to yes.
+
+ Note that even when this parameter is set a user
+ authenticating to ssssmmmmbbbbdddd must still enter a valid
+ password in order to connect correctly, and to update
+ their hashed (smbpasswd) passwords.
+
+ Default: uuuuppppddddaaaatttteeee eeeennnnccccrrrryyyypppptttteeeedddd ==== nnnnoooo
+
+ uuuusssseeee cccclllliiiieeeennnntttt ddddrrrriiiivvvveeeerrrr ((((SSSS))))
+ This parameter applies only to Windows NT/2000 clients.
+ It has no affect on Windows 95/98/ME clients. When
+ serving a printer to Windows NT/2000 clients without
+ first installing a valid printer driver on the Samba
+ host, the client will be required to install a local
+ printer driver. From this point on, the client will
+ treat the print as a local printer and not a network
+ printer connection. This is much the same behavior that
+ will occur when ddddiiiissssaaaabbbblllleeee ssssppppoooooooollllssssssss ==== yyyyeeeessss.
+
+ The differentiating factor is that under normal
+ circumstances, the NT/2000 client will attempt to open
+ the network printer using MS-RPC. The problem is that
+ because the client considers the printer to be local,
+ it will attempt to issue the OpenPrinterEx() call
+ requesting access rights associated with the logged on
+ user. If the user possesses local administator rights
+ but not root privilegde on the Samba host (often the
+ case), the OpenPrinterEx() call will fail. The result
+ is that the client will now display an "Access Denied;
+ Unable to connect" message in the printer queue window
+ (even though jobs may successfully be printed).
+
+ If this parameter is enabled for a printer, then any
+ attempt to open the printer with the
+ PRINTER_ACCESS_ADMINISTER right is mapped to
+ PRINTER_ACCESS_USE instead. Thus allowing the
+ OpenPrinterEx() call to succeed. TTTThhhhiiiissss ppppaaaarrrraaaammmmeeeetttteeeerrrr MMMMUUUUSSSSTTTT
+ nnnnooootttt bbbbeeee aaaabbbblllleeee eeeennnnaaaabbbblllleeeedddd oooonnnn aaaa pppprrrriiiinnnntttt sssshhhhaaaarrrreeee wwwwhhhhiiiicccchhhh hhhhaaaassss vvvvaaaalllliiiidddd
+ pppprrrriiiinnnntttt ddddrrrriiiivvvveeeerrrr iiiinnnnssssttttaaaalllllllleeeedddd oooonnnn tttthhhheeee SSSSaaaammmmbbbbaaaa sssseeeerrrrvvvveeeerrrr....
+
+ See also disable spoolss
+
+
+
+ Page 124 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Default: uuuusssseeee cccclllliiiieeeennnntttt ddddrrrriiiivvvveeeerrrr ==== nnnnoooo
+
+ uuuusssseeee mmmmmmmmaaaapppp ((((GGGG))))
+ This global parameter determines if the tdb internals
+ of Samba can depend on mmap working correctly on the
+ running system. Samba requires a coherent mmap/read-
+ write system memory cache. Currently only HPUX does not
+ have such a coherent cache, and so this parameter is
+ set to no by default on HPUX. On all other systems this
+ parameter should be left alone. This parameter is
+ provided to help the Samba developers track down
+ problems with the tdb internal code.
+
+ Default: uuuusssseeee mmmmmmmmaaaapppp ==== yyyyeeeessss
+
+ uuuusssseeee rrrrhhhhoooossssttttssss ((((GGGG))))
+ If this global parameter is yes, it specifies that the
+ UNIX user's ._r_h_o_s_t_s file in their home directory will
+ be read to find the names of hosts and users who will
+ be allowed access without specifying a password.
+
+ NNNNOOOOTTTTEEEE:::: The use of _u_s_e _r_h_o_s_t_s can be a major security
+ hole. This is because you are trusting the PC to supply
+ the correct username. It is very easy to get a PC to
+ supply a false username. I recommend that the _u_s_e
+ _r_h_o_s_t_s option be only used if you really know what you
+ are doing.
+
+ Default: uuuusssseeee rrrrhhhhoooossssttttssss ==== nnnnoooo
+
+ uuuusssseeeerrrr ((((SSSS))))
+ Synonym for _u_s_e_r_n_a_m_e.
+
+ uuuusssseeeerrrrssss ((((SSSS))))
+ Synonym for _u_s_e_r_n_a_m_e.
+
+ uuuusssseeeerrrrnnnnaaaammmmeeee ((((SSSS))))
+ Multiple users may be specified in a comma-delimited
+ list, in which case the supplied password will be
+ tested against each username in turn (left to right).
+
+ The _u_s_e_r_n_a_m_e line is needed only when the PC is unable
+ to supply its own username. This is the case for the
+ COREPLUS protocol or where your users have different
+ WfWg usernames to UNIX usernames. In both these cases
+ you may also be better using the \\server\share%user
+ syntax instead.
+
+ The _u_s_e_r_n_a_m_e line is not a great solution in many cases
+ as it means Samba will try to validate the supplied
+ password against each of the usernames in the _u_s_e_r_n_a_m_e
+ line in turn. This is slow and a bad idea for lots of
+
+
+
+ Page 125 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ users in case of duplicate passwords. You may get
+ timeouts or security breaches using this parameter
+ unwisely.
+
+ Samba relies on the underlying UNIX security. This
+ parameter does not restrict who can login, it just
+ offers hints to the Samba server as to what usernames
+ might correspond to the supplied password. Users can
+ login as whoever they please and they will be able to
+ do no more damage than if they started a telnet
+ session. The daemon runs as the user that they log in
+ as, so they cannot do anything that user cannot do.
+
+ To restrict a service to a particular set of users you
+ can use the _v_a_l_i_d _u_s_e_r_s parameter.
+
+ If any of the usernames begin with a '@' then the name
+ will be looked up first in the NIS netgroups list (if
+ Samba is compiled with netgroup support), followed by a
+ lookup in the UNIX groups database and will expand to a
+ list of all users in the group of that name.
+
+ If any of the usernames begin with a '+' then the name
+ will be looked up only in the UNIX groups database and
+ will expand to a list of all users in the group of that
+ name.
+
+ If any of the usernames begin with a '&'then the name
+ will be looked up only in the NIS netgroups database
+ (if Samba is compiled with netgroup support) and will
+ expand to a list of all users in the netgroup group of
+ that name.
+
+ Note that searching though a groups database can take
+ quite some time, and some clients may time out during
+ the search.
+
+ See the section NOTE ABOUT USERNAME/PASSWORD VALIDATION
+ for more information on how this parameter determines
+ access to the services.
+
+ Default: TTTThhhheeee gggguuuueeeesssstttt aaaaccccccccoooouuuunnnntttt iiiiffff aaaa gggguuuueeeesssstttt sssseeeerrrrvvvviiiicccceeee,,,, eeeellllsssseeee
+ <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>....
+
+ Examples:uuuusssseeeerrrrnnnnaaaammmmeeee ==== ffffrrrreeeedddd,,,, mmmmaaaarrrryyyy,,,, jjjjaaaacccckkkk,,,, jjjjaaaannnneeee,,,, @@@@uuuusssseeeerrrrssss,,,,
+ @@@@ppppccccggggrrrroooouuuupppp
+
+ uuuusssseeeerrrrnnnnaaaammmmeeee lllleeeevvvveeeellll ((((GGGG))))
+ This option helps Samba to try and 'guess' at the real
+ UNIX username, as many DOS clients send an all-
+ uppercase username. By default Samba tries all
+ lowercase, followed by the username with the first
+
+
+
+ Page 126 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ letter capitalized, and fails if the username is not
+ found on the UNIX machine.
+
+ If this parameter is set to non-zero the behavior
+ changes. This parameter is a number that specifies the
+ number of uppercase combinations to try while trying to
+ determine the UNIX user name. The higher the number the
+ more combinations will be tried, but the slower the
+ discovery of usernames will be. Use this parameter when
+ you have strange usernames on your UNIX machine, such
+ as AstrangeUser .
+
+ Default: uuuusssseeeerrrrnnnnaaaammmmeeee lllleeeevvvveeeellll ==== 0000
+
+ Example: uuuusssseeeerrrrnnnnaaaammmmeeee lllleeeevvvveeeellll ==== 5555
+
+ uuuusssseeeerrrrnnnnaaaammmmeeee mmmmaaaapppp ((((GGGG))))
+ This option allows you to specify a file containing a
+ mapping of usernames from the clients to the server.
+ This can be used for several purposes. The most common
+ is to map usernames that users use on DOS or Windows
+ machines to those that the UNIX box uses. The other is
+ to map multiple users to a single username so that they
+ can more easily share files.
+
+ The map file is parsed line by line. Each line should
+ contain a single UNIX username on the left then a '='
+ followed by a list of usernames on the right. The list
+ of usernames on the right may contain names of the form
+ @group in which case they will match any UNIX username
+ in that group. The special client name '*' is a
+ wildcard and matches any name. Each line of the map
+ file may be up to 1023 characters long.
+
+ The file is processed on each line by taking the
+ supplied username and comparing it with each username
+ on the right hand side of the '=' signs. If the
+ supplied name matches any of the names on the right
+ hand side then it is replaced with the name on the
+ left. Processing then continues with the next line.
+
+ If any line begins with a '#' or a ';' then it is
+ ignored
+
+ If any line begins with an '!' then the processing will
+ stop after that line if a mapping was done by the line.
+ Otherwise mapping continues with every line being
+ processed. Using '!' is most useful when you have a
+ wildcard mapping line later in the file.
+
+ For example to map from the name admin or administrator
+ to the UNIX name root you would use:
+
+
+
+ Page 127 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ rrrrooooooootttt ==== aaaaddddmmmmiiiinnnn aaaaddddmmmmiiiinnnniiiissssttttrrrraaaattttoooorrrr
+
+ Or to map anyone in the UNIX group system to the UNIX
+ name sys you would use:
+
+ ssssyyyyssss ==== @@@@ssssyyyysssstttteeeemmmm
+
+ You can have as many mappings as you like in a username
+ map file.
+
+ If your system supports the NIS NETGROUP option then
+ the netgroup database is checked before the /_e_t_c/_g_r_o_u_p
+ database for matching groups.
+
+ You can map Windows usernames that have spaces in them
+ by using double quotes around the name. For example:
+
+ ttttrrrriiiiddddggggeeee ==== """"AAAAnnnnddddrrrreeeewwww TTTTrrrriiiiddddggggeeeellllllll""""
+
+ would map the windows username "Andrew Tridgell" to the
+ unix username "tridge".
+
+ The following example would map mary and fred to the
+ unix user sys, and map the rest to guest. Note the use
+ of the '!' to tell Samba to stop processing if it gets
+ a match on that line.
+
+
+ !sys = mary fred
+ guest = *
+
+
+
+ Note that the remapping is applied to all occurrences
+ of usernames. Thus if you connect to \\server\fred and
+ fred is remapped to mary then you will actually be
+ connecting to \\server\mary and will need to supply a
+ password suitable for mary not fred. The only exception
+ to this is the username passed to the _p_a_s_s_w_o_r_d _s_e_r_v_e_r
+ (if you have one). The password server will receive
+ whatever username the client supplies without
+ modification.
+
+ Also note that no reverse mapping is done. The main
+ effect this has is with printing. Users who have been
+ mapped may have trouble deleting print jobs as
+ PrintManager under WfWg will think they don't own the
+ print job.
+
+ Default: nnnnoooo uuuusssseeeerrrrnnnnaaaammmmeeee mmmmaaaapppp
+
+ Example: uuuusssseeeerrrrnnnnaaaammmmeeee mmmmaaaapppp ==== ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////lllliiiibbbb////uuuusssseeeerrrrssss....mmmmaaaapppp
+
+
+
+ Page 128 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ uuuusssseeee sssseeeennnnddddffffiiiilllleeee ((((SSSS))))
+ If this parameter is yes, and Samba was built with the
+ --with-sendfile-support option, and the underlying
+ operating system supports sendfile system call, then
+ some SMB read calls (mainly ReadAndX and ReadRaw) will
+ use the more efficient sendfile system call for files
+ that are exclusively oplocked. This may make more
+ efficient use of the system CPU's and cause Samba to be
+ faster. This is off by default as it's effects are
+ unknown as yet.
+
+ Default: uuuusssseeee sssseeeennnnddddffffiiiilllleeee ==== nnnnoooo
+
+ uuuuttttmmmmpppp ((((GGGG))))
+ This boolean parameter is only available if Samba has
+ been configured and compiled with the option --------wwwwiiiitttthhhh----
+ uuuuttttmmmmpppp. If set to yes then Samba will attempt to add utmp
+ or utmpx records (depending on the UNIX system)
+ whenever a connection is made to a Samba server. Sites
+ may use this to record the user connecting to a Samba
+ share.
+
+ See also the _u_t_m_p _d_i_r_e_c_t_o_r_y parameter.
+
+ Default: uuuuttttmmmmpppp ==== nnnnoooo
+
+ uuuuttttmmmmpppp ddddiiiirrrreeeeccccttttoooorrrryyyy((((GGGG))))
+ This parameter is only available if Samba has been
+ configured and compiled with the option --------wwwwiiiitttthhhh----uuuuttttmmmmpppp.
+ It specifies a directory pathname that is used to store
+ the utmp or utmpx files (depending on the UNIX system)
+ that record user connections to a Samba server. See
+ also the _u_t_m_p parameter. By default this is not set,
+ meaning the system will use whatever utmp file the
+ native system is set to use (usually /_v_a_r/_r_u_n/_u_t_m_p on
+ Linux).
+
+ Default: nnnnoooo uuuuttttmmmmpppp ddddiiiirrrreeeeccccttttoooorrrryyyy
+
+ vvvvaaaalllliiiidddd cccchhhhaaaarrrrssss ((((GGGG))))
+ The option allows you to specify additional characters
+ that should be considered valid by the server in
+ filenames. This is particularly useful for national
+ character sets, such as adding u-umlaut or a-ring.
+
+ The option takes a list of characters in either integer
+ or character form with spaces between them. If you give
+ two characters with a colon between them then it will
+ be taken as an lowercase:uppercase pair.
+
+ If you have an editor capable of entering the
+ characters into the config file then it is probably
+
+
+
+ Page 129 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ easiest to use this method. Otherwise you can specify
+ the characters in octal, decimal or hexadecimal form
+ using the usual C notation.
+
+ For example to add the single character 'Z' to the
+ charset (which is a pointless thing to do as it's
+ already there) you could do one of the following
+
+
+ valid chars = Z
+ valid chars = z:Z
+ valid chars = 0132:0172
+
+
+
+ The last two examples above actually add two
+ characters, and alter the uppercase and lowercase
+ mappings appropriately.
+
+ Note that you MMMMUUUUSSSSTTTT specify this parameter after the
+ _c_l_i_e_n_t _c_o_d_e _p_a_g_e parameter if you have both set. If
+ _c_l_i_e_n_t _c_o_d_e _p_a_g_e is set after the _v_a_l_i_d _c_h_a_r_s parameter
+ the _v_a_l_i_d _c_h_a_r_s settings will be overwritten.
+
+ See also the _c_l_i_e_n_t _c_o_d_e _p_a_g_e parameter.
+
+ Default: SSSSaaaammmmbbbbaaaa ddddeeeeffffaaaauuuullllttttssss ttttoooo uuuussssiiiinnnngggg aaaa rrrreeeeaaaassssoooonnnnaaaabbbblllleeee sssseeeetttt ooooffff
+ vvvvaaaalllliiiidddd cccchhhhaaaarrrraaaacccctttteeeerrrrssss ffffoooorrrr EEEEnnnngggglllliiiisssshhhh ssssyyyysssstttteeeemmmmssss
+
+ Example: vvvvaaaalllliiiidddd cccchhhhaaaarrrrssss ==== 0000333344445555::::0000333300005555 0000333366666666::::0000333322226666 0000333344444444::::0000333300004444
+
+ The above example allows filenames to have the Swedish
+ characters in them.
+
+ NNNNOOOOTTTTEEEE:::: It is actually quite difficult to correctly
+ produce a _v_a_l_i_d _c_h_a_r_s line for a particular system. To
+ automate the process tino@augsburg.net
+ <URL:mailto:tino@augsburg.net> has written a package
+ called vvvvaaaalllliiiiddddcccchhhhaaaarrrrssss which will automatically produce a
+ complete _v_a_l_i_d _c_h_a_r_s line for a given client system.
+ Look in the _e_x_a_m_p_l_e_s/_v_a_l_i_d_c_h_a_r_s/ subdirectory of your
+ Samba source code distribution for this package.
+
+ vvvvaaaalllliiiidddd uuuusssseeeerrrrssss ((((SSSS))))
+ This is a list of users that should be allowed to login
+ to this service. Names starting with '@', '+' and '&'
+ are interpreted using the same rules as described in
+ the _i_n_v_a_l_i_d _u_s_e_r_s parameter.
+
+ If this is empty (the default) then any user can login.
+ If a username is in both this list and the _i_n_v_a_l_i_d
+ _u_s_e_r_s list then access is denied for that user.
+
+
+
+ Page 130 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ The current servicename is substituted for %_S . This is
+ useful in the [homes] section.
+
+ See also _i_n_v_a_l_i_d _u_s_e_r_s
+
+ Default: NNNNoooo vvvvaaaalllliiiidddd uuuusssseeeerrrrssss lllliiiisssstttt ((((aaaannnnyyyyoooonnnneeee ccccaaaannnn llllooooggggiiiinnnn))))
+
+ Example: vvvvaaaalllliiiidddd uuuusssseeeerrrrssss ==== ggggrrrreeeegggg,,,, @@@@ppppccccuuuusssseeeerrrrssss
+
+ vvvveeeettttoooo ffffiiiilllleeeessss((((SSSS))))
+ This is a list of files and directories that are
+ neither visible nor accessible. Each entry in the list
+ must be separated by a '/', which allows spaces to be
+ included in the entry. '*' and '?' can be used to
+ specify multiple files or directories as in DOS
+ wildcards.
+
+ Each entry must be a unix path, not a DOS path and must
+ nnnnooootttt include the unix directory separator '/'.
+
+ Note that the _c_a_s_e _s_e_n_s_i_t_i_v_e option is applicable in
+ vetoing files.
+
+ One feature of the veto files parameter that it is
+ important to be aware of is Samba's behaviour when
+ trying to delete a directory. If a directory that is to
+ be deleted contains nothing but veto files this
+ deletion will ffffaaaaiiiillll unless you also set the _d_e_l_e_t_e _v_e_t_o
+ _f_i_l_e_s parameter to _y_e_s.
+
+ Setting this parameter will affect the performance of
+ Samba, as it will be forced to check all files and
+ directories for a match as they are scanned.
+
+ See also _h_i_d_e _f_i_l_e_s and _c_a_s_e _s_e_n_s_i_t_i_v_e.
+
+ Default: NNNNoooo ffffiiiilllleeeessss oooorrrr ddddiiiirrrreeeeccccttttoooorrrriiiieeeessss aaaarrrreeee vvvveeeettttooooeeeedddd....
+
+ Examples:
+
+ ; Veto any files containing the word Security,
+ ; any ending in .tmp, and any directory containing the
+ ; word root.
+ veto files = /*Security*/*.tmp/*root*/
+
+ ; Veto the Apple specific files that a NetAtalk server
+ ; creates.
+ veto files = /.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/
+
+
+ vvvveeeettttoooo oooopppplllloooocccckkkk ffffiiiilllleeeessss ((((SSSS))))
+ This parameter is only valid when the _o_p_l_o_c_k_s parameter
+
+
+
+ Page 131 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ is turned on for a share. It allows the Samba
+ administrator to selectively turn off the granting of
+ oplocks on selected files that match a wildcarded list,
+ similar to the wildcarded list used in the _v_e_t_o _f_i_l_e_s
+ parameter.
+
+ Default: NNNNoooo ffffiiiilllleeeessss aaaarrrreeee vvvveeeettttooooeeeedddd ffffoooorrrr oooopppplllloooocccckkkk ggggrrrraaaannnnttttssss
+
+ You might want to do this on files that you know will
+ be heavily contended for by clients. A good example of
+ this is in the NetBench SMB benchmark program, which
+ causes heavy client contention for files ending in
+ ._S_E_M. To cause Samba not to grant oplocks on these
+ files you would use the line (either in the [global]
+ section or in the section for the particular NetBench
+ share :
+
+ Example: vvvveeeettttoooo oooopppplllloooocccckkkk ffffiiiilllleeeessss ==== ////****....SSSSEEEEMMMM////
+
+ vvvvffffssss oooobbbbjjjjeeeecccctttt ((((SSSS))))
+ This parameter specifies a shared object file that is
+ used for Samba VFS I/O operations. By default, normal
+ disk I/O operations are used but these can be
+ overloaded with a VFS object. The Samba VFS layer is
+ new to Samba 2.2 and must be enabled at compile time
+ with --with-vfs.
+
+ Default : nnnnoooo vvvvaaaalllluuuueeee
+
+ vvvvffffssss ooooppppttttiiiioooonnnnssss ((((SSSS))))
+ This parameter allows parameters to be passed to the
+ vfs layer at initialization time. The Samba VFS layer
+ is new to Samba 2.2 and must be enabled at compile time
+ with --with-vfs. See also _v_f_s _o_b_j_e_c_t.
+
+ Default : nnnnoooo vvvvaaaalllluuuueeee
+
+ vvvvoooolllluuuummmmeeee ((((SSSS))))
+ This allows you to override the volume label returned
+ for a share. Useful for CDROMs with installation
+ programs that insist on a particular volume label.
+
+ Default: tttthhhheeee nnnnaaaammmmeeee ooooffff tttthhhheeee sssshhhhaaaarrrreeee
+
+ wwwwiiiiddddeeee lllliiiinnnnkkkkssss ((((SSSS))))
+ This parameter controls whether or not links in the
+ UNIX file system may be followed by the server. Links
+ that point to areas within the directory tree exported
+ by the server are always allowed; this parameter
+ controls access only to areas that are outside the
+ directory tree being exported.
+
+
+
+
+ Page 132 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Note that setting this parameter can have a negative
+ effect on your server performance due to the extra
+ system calls that Samba has to do in order to perform
+ the link checks.
+
+ Default: wwwwiiiiddddeeee lllliiiinnnnkkkkssss ==== yyyyeeeessss
+
+ wwwwiiiinnnnbbbbiiiinnnndddd ccccaaaacccchhhheeee ttttiiiimmmmeeee ((((GGGG))))
+ This parameter specifies the number of seconds the
+ winbindd(8) daemon will cache user and group
+ information before querying a Windows NT server again.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd ccccaaaacccchhhheeee ttttyyyyppppeeee ==== 11115555
+
+ wwwwiiiinnnnbbbbiiiinnnndddd eeeennnnuuuummmm uuuusssseeeerrrrssss ((((GGGG))))
+ On large installations using winbindd(8) it may be
+ necessary to suppress the enumeration of users through
+ the sssseeeettttppppwwwweeeennnntttt(((()))), ggggeeeettttppppwwwweeeennnntttt(((()))) and eeeennnnddddppppwwwweeeennnntttt(((()))) group of
+ system calls. If the _w_i_n_b_i_n_d _e_n_u_m _u_s_e_r_s parameter is
+ no, calls to the ggggeeeettttppppwwwweeeennnntttt system call will not return
+ any data.
+
+ WWWWaaaarrrrnnnniiiinnnngggg:::: Turning off user enumeration may cause some
+ programs to behave oddly. For example, the finger
+ program relies on having access to the full user list
+ when searching for matching usernames.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd eeeennnnuuuummmm uuuusssseeeerrrrssss ==== yyyyeeeessss
+
+ wwwwiiiinnnnbbbbiiiinnnndddd eeeennnnuuuummmm ggggrrrroooouuuuppppssss ((((GGGG))))
+ On large installations using winbindd(8) it may be
+ necessary to suppress the enumeration of groups through
+ the sssseeeettttggggrrrreeeennnntttt(((()))), ggggeeeettttggggrrrreeeennnntttt(((()))) and eeeennnnddddggggrrrreeeennnntttt(((()))) group of
+ system calls. If the _w_i_n_b_i_n_d _e_n_u_m _g_r_o_u_p_s parameter is
+ no, calls to the ggggeeeettttggggrrrreeeennnntttt(((()))) system call will not return
+ any data.
+
+ WWWWaaaarrrrnnnniiiinnnngggg:::: Turning off group enumeration may cause some
+ programs to behave oddly.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd eeeennnnuuuummmm ggggrrrroooouuuuppppssss ==== yyyyeeeessss
+
+ wwwwiiiinnnnbbbbiiiinnnndddd ggggiiiidddd ((((GGGG))))
+ The winbind gid parameter specifies the range of group
+ ids that are allocated by the winbindd(8) daemon. This
+ range of group ids should have no existing local or NIS
+ groups within it as strange conflicts can occur
+ otherwise.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd ggggiiiidddd ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: wwwwiiiinnnnbbbbiiiinnnndddd ggggiiiidddd ==== 11110000000000000000----22220000000000000000
+
+
+
+ Page 133 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ wwwwiiiinnnnbbbbiiiinnnndddd sssseeeeppppaaaarrrraaaattttoooorrrr ((((GGGG))))
+ This parameter allows an admin to define the character
+ used when listing a username of the form of _D_O_M_A_I_N
+ \_u_s_e_r. This parameter is only applicable when using the
+ _p_a_m__w_i_n_b_i_n_d._s_o and _n_s_s__w_i_n_b_i_n_d._s_o modules for UNIX
+ services.
+
+ Please note that setting this parameter to + causes
+ problems with group membership at least on glibc
+ systems, as the character + is used as a special
+ character for NIS in /etc/group.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd sssseeeeppppaaaarrrraaaattttoooorrrr ==== ''''\\\\''''
+
+ Example: wwwwiiiinnnnbbbbiiiinnnndddd sssseeeeppppaaaarrrraaaattttoooorrrr ==== ++++
+
+ wwwwiiiinnnnbbbbiiiinnnndddd uuuuiiiidddd ((((GGGG))))
+ The winbind gid parameter specifies the range of group
+ ids that are allocated by the winbindd(8) daemon. This
+ range of ids should have no existing local or NIS users
+ within it as strange conflicts can occur otherwise.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd uuuuiiiidddd ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: wwwwiiiinnnnbbbbiiiinnnndddd uuuuiiiidddd ==== 11110000000000000000----22220000000000000000
+
+ wwwwiiiinnnnbbbbiiiinnnndddd uuuusssseeee ddddeeeeffffaaaauuuulllltttt ddddoooommmmaaaaiiiinnnn
+
+ wwwwiiiinnnnbbbbiiiinnnndddd uuuusssseeee ddddeeeeffffaaaauuuulllltttt ddddoooommmmaaaaiiiinnnn
+ This parameter specifies whether the winbindd(8)
+ daemon should operate on users without domain component
+ in their username. Users without a domain component are
+ treated as is part of the winbindd server's own domain.
+ While this does not benifit Windows users, it makes
+ SSH, FTP and e-mail function in a way much closer to
+ the way they would in a native unix system.
+
+ Default: wwwwiiiinnnnbbbbiiiinnnndddd uuuusssseeee ddddeeeeffffaaaauuuulllltttt ddddoooommmmaaaaiiiinnnn ==== <<<<nnnnoooo>>>>
+
+ Example: wwwwiiiinnnnbbbbiiiinnnndddd uuuusssseeee ddddeeeeffffaaaauuuulllltttt ddddoooommmmaaaaiiiinnnn ==== yyyyeeeessss
+
+ wwwwiiiinnnnssss hhhhooooooookkkk ((((GGGG))))
+ When Samba is running as a WINS server this allows you
+ to call an external program for all changes to the WINS
+ database. The primary use for this option is to allow
+ the dynamic update of external name resolution
+ databases such as dynamic DNS.
+
+ The wins hook parameter specifies the name of a script
+ or executable that will be called as follows:
+
+ wwwwiiiinnnnssss____hhhhooooooookkkk ooooppppeeeerrrraaaattttiiiioooonnnn nnnnaaaammmmeeee nnnnaaaammmmeeeettttyyyyppppeeee ttttttttllll IIIIPPPP____lllliiiisssstttt
+
+
+
+ Page 134 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ o+ The first argument is the operation and is one of
+ "add", "delete", or "refresh". In most cases the
+ operation can be ignored as the rest of the
+ parameters provide sufficient information. Note that
+ "refresh" may sometimes be called when the name has
+ not previously been added, in that case it should be
+ treated as an add.
+
+ o+ The second argument is the NetBIOS name. If the name
+ is not a legal name then the wins hook is not called.
+ Legal names contain only letters, digits, hyphens,
+ underscores and periods.
+
+ o+ The third argument is the NetBIOS name type as a 2
+ digit hexadecimal number.
+
+ o+ The fourth argument is the TTL (time to live) for the
+ name in seconds.
+
+ o+ The fifth and subsequent arguments are the IP
+ addresses currently registered for that name. If this
+ list is empty then the name should be deleted.
+
+ An example script that calls the BIND dynamic DNS update
+ program nnnnssssuuuuppppddddaaaatttteeee is provided in the examples directory of
+ the Samba source code.
+
+ wwwwiiiinnnnssss pppprrrrooooxxxxyyyy ((((GGGG))))
+ This is a boolean that controls if nmbd(8) will respond
+ to broadcast name queries on behalf of other hosts. You
+ may need to set this to yes for some older clients.
+
+ Default: wwwwiiiinnnnssss pppprrrrooooxxxxyyyy ==== nnnnoooo
+
+ wwwwiiiinnnnssss sssseeeerrrrvvvveeeerrrr ((((GGGG))))
+ This specifies the IP address (or DNS name: IP address
+ for preference) of the WINS server that nmbd(8) should
+ register with. If you have a WINS server on your
+ network then you should set this to the WINS server's
+ IP.
+
+ You should point this at your WINS server if you have a
+ multi-subnetted network.
+
+ NNNNOOOOTTTTEEEE. You need to set up Samba to point to a WINS
+ server if you have multiple subnets and wish cross-
+ subnet browsing to work correctly.
+
+ See the documentation file _B_R_O_W_S_I_N_G._t_x_t in the docs/
+ directory of your Samba source distribution.
+
+ Default: nnnnooootttt eeeennnnaaaabbbblllleeeedddd
+
+
+
+ Page 135 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ Example: wwwwiiiinnnnssss sssseeeerrrrvvvveeeerrrr ==== 111199992222....9999....222200000000....1111
+
+ wwwwiiiinnnnssss ssssuuuuppppppppoooorrrrtttt ((((GGGG))))
+ This boolean controls if the nmbd(8) process in Samba
+ will act as a WINS server. You should not set this to
+ yes unless you have a multi-subnetted network and you
+ wish a particular nnnnmmmmbbbbdddd to be your WINS server. Note
+ that you should NNNNEEEEVVVVEEEERRRR set this to yes on more than one
+ machine in your network.
+
+ Default: wwwwiiiinnnnssss ssssuuuuppppppppoooorrrrtttt ==== nnnnoooo
+
+ wwwwoooorrrrkkkkggggrrrroooouuuupppp ((((GGGG))))
+ This controls what workgroup your server will appear to
+ be in when queried by clients. Note that this parameter
+ also controls the Domain name used with the sssseeeeccccuuuurrrriiiittttyyyy ====
+ ddddoooommmmaaaaiiiinnnn setting.
+
+ Default: sssseeeetttt aaaatttt ccccoooommmmppppiiiilllleeee ttttiiiimmmmeeee ttttoooo WWWWOOOORRRRKKKKGGGGRRRROOOOUUUUPPPP
+
+ Example: wwwwoooorrrrkkkkggggrrrroooouuuupppp ==== MMMMYYYYGGGGRRRROOOOUUUUPPPP
+
+ wwwwrrrriiiittttaaaabbbblllleeee ((((SSSS))))
+ Synonym for _w_r_i_t_e_a_b_l_e for people who can't spell :-).
+
+ wwwwrrrriiiitttteeee ccccaaaacccchhhheeee ssssiiiizzzzeeee ((((SSSS))))
+ If this integer parameter is set to non-zero value,
+ Samba will create an in-memory cache for each oplocked
+ file (it does nnnnooootttt do this for non-oplocked files). All
+ writes that the client does not request to be flushed
+ directly to disk will be stored in this cache if
+ possible. The cache is flushed onto disk when a write
+ comes in whose offset would not fit into the cache or
+ when the file is closed by the client. Reads for the
+ file are also served from this cache if the data is
+ stored within it.
+
+ This cache allows Samba to batch client writes into a
+ more efficient write size for RAID disks (i.e. writes
+ may be tuned to be the RAID stripe size) and can
+ improve performance on systems where the disk subsystem
+ is a bottleneck but there is free memory for userspace
+ programs.
+
+ The integer parameter specifies the size of this cache
+ (per oplocked file) in bytes.
+
+ Default: wwwwrrrriiiitttteeee ccccaaaacccchhhheeee ssssiiiizzzzeeee ==== 0000
+
+ Example: wwwwrrrriiiitttteeee ccccaaaacccchhhheeee ssssiiiizzzzeeee ==== 222266662222111144444444
+
+ for a 256k cache size per file.
+
+
+
+ Page 136 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ wwwwrrrriiiitttteeee lllliiiisssstttt ((((SSSS))))
+ This is a list of users that are given read-write
+ access to a service. If the connecting user is in this
+ list then they will be given write access, no matter
+ what the _r_e_a_d _o_n_l_y option is set to. The list can
+ include group names using the @group syntax.
+
+ Note that if a user is in both the read list and the
+ write list then they will be given write access.
+
+ See also the _r_e_a_d _l_i_s_t option.
+
+ Default: wwwwrrrriiiitttteeee lllliiiisssstttt ==== <<<<eeeemmmmppppttttyyyy ssssttttrrrriiiinnnngggg>>>>
+
+ Example: wwwwrrrriiiitttteeee lllliiiisssstttt ==== aaaaddddmmmmiiiinnnn,,,, rrrrooooooootttt,,,, @@@@ssssttttaaaaffffffff
+
+ wwwwrrrriiiitttteeee ooookkkk ((((SSSS))))
+ Inverted synonym for _r_e_a_d _o_n_l_y.
+
+ wwwwrrrriiiitttteeee rrrraaaawwww ((((GGGG))))
+ This parameter controls whether or not the server will
+ support raw write SMB's when transferring data from
+ clients. You should never need to change this
+ parameter.
+
+ Default: wwwwrrrriiiitttteeee rrrraaaawwww ==== yyyyeeeessss
+
+ wwwwrrrriiiitttteeeeaaaabbbblllleeee ((((SSSS))))
+ Inverted synonym for _r_e_a_d _o_n_l_y.
+
+ WWWWAAAARRRRNNNNIIIINNNNGGGGSSSS
+ Although the configuration file permits service names to
+ contain spaces, your client software may not. Spaces will be
+ ignored in comparisons anyway, so it shouldn't be a problem
+ - but be aware of the possibility.
+
+ On a similar note, many clients - especially DOS clients -
+ limit service names to eight characters. smbd(8)
+ has no such limitation, but attempts to connect from such
+ clients will fail if they truncate the service names. For
+ this reason you should probably keep your service names down
+ to eight characters in length.
+
+ Use of the [homes] and [printers] special sections make life
+ for an administrator easy, but the various combinations of
+ default attributes can be tricky. Take extreme care when
+ designing these sections. In particular, ensure that the
+ permissions on spool directories are correct.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+
+
+
+ Page 137 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((11115555 OOOOccccttttoooobbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBB....CCCCOOOONNNNFFFF((((5555))))
+
+
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ samba(7) ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888)))) sssswwwwaaaatttt((((8888)))) ssssmmmmbbbbdddd((((8888)))) nnnnmmmmbbbbdddd((((8888)))) ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp((((1111)))) tttteeeessssttttppppaaaarrrrmmmm((((1111)))) tttteeeessssttttpppprrrrnnnnssss((((1111))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 138 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.5/smbpasswd.5 b/packaging/Caldera/OpenServer/man/cat.5/smbpasswd.5
new file mode 100755
index 00000000000..dec8d83b1ba
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.5/smbpasswd.5
@@ -0,0 +1,198 @@
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbpasswd - The Samba encrypted password file
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ _s_m_b_p_a_s_s_w_d
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ smbpasswd is the Samba encrypted password file. It contains
+ the username, Unix user id and the SMB hashed passwords of
+ the user, as well as account flag information and the time
+ the password was last changed. This file format has been
+ evolving with Samba and has had several different formats in
+ the past.
+
+ FFFFIIIILLLLEEEE FFFFOOOORRRRMMMMAAAATTTT
+ The format of the smbpasswd file used by Samba 2.2 is very
+ similar to the familiar Unix _p_a_s_s_w_d(_5) file. It is an ASCII
+ file containing one line for each user. Each field within
+ each line is separated from the next by a colon. Any entry
+ beginning with '#' is ignored. The smbpasswd file contains
+ the following information for each user:
+
+ nnnnaaaammmmeeee This is the user name. It must be a name that already
+ exists in the standard UNIX passwd file.
+
+ uuuuiiiidddd This is the UNIX uid. It must match the uid field for
+ the same user entry in the standard UNIX passwd file.
+ If this does not match then Samba will refuse to
+ recognize this smbpasswd file entry as being valid for
+ a user.
+
+ LLLLaaaannnnmmmmaaaannnn PPPPaaaasssssssswwwwoooorrrrdddd HHHHaaaasssshhhh
+ This is the LANMAN hash of the user's password, encoded
+ as 32 hex digits. The LANMAN hash is created by DES
+ encrypting a well known string with the user's password
+ as the DES key. This is the same password used by
+ Windows 95/98 machines. Note that this password hash is
+ regarded as weak as it is vulnerable to dictionary
+ attacks and if two users choose the same password this
+ entry will be identical (i.e. the password is not
+ "salted" as the UNIX password is). If the user has a
+ null password this field will contain the characters
+ "NO PASSWORD" as the start of the hex string. If the
+ hex string is equal to 32 'X' characters then the
+ user's account is marked as disabled and the user will
+ not be able to log onto the Samba server.
+
+ WWWWAAAARRRRNNNNIIIINNNNGGGG !!!!!!!! Note that, due to the challenge-response
+ nature of the SMB/CIFS authentication protocol, anyone
+ with a knowledge of this password hash will be able to
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555))))
+
+
+
+ impersonate the user on the network. For this reason
+ these hashes are known as ppppllllaaaaiiiinnnn tttteeeexxxxtttt eeeeqqqquuuuiiiivvvvaaaalllleeeennnnttttssss and
+ must NNNNOOOOTTTT be made available to anyone but the root user.
+ To protect these passwords the smbpasswd file is placed
+ in a directory with read and traverse access only to
+ the root user and the smbpasswd file itself must be set
+ to be read/write only by root, with no other access.
+
+ NNNNTTTT PPPPaaaasssssssswwwwoooorrrrdddd HHHHaaaasssshhhh
+ This is the Windows NT hash of the user's password,
+ encoded as 32 hex digits. The Windows NT hash is
+ created by taking the user's password as represented in
+ 16-bit, little-endian UNICODE and then applying the MD4
+ (internet rfc1321) hashing algorithm to it.
+
+ This password hash is considered more secure than the
+ LANMAN Password Hash as it preserves the case of the
+ password and uses a much higher quality hashing
+ algorithm. However, it is still the case that if two
+ users choose the same password this entry will be
+ identical (i.e. the password is not "salted" as the
+ UNIX password is).
+
+ WWWWAAAARRRRNNNNIIIINNNNGGGG !!!!!!!!. Note that, due to the challenge-response
+ nature of the SMB/CIFS authentication protocol, anyone
+ with a knowledge of this password hash will be able to
+ impersonate the user on the network. For this reason
+ these hashes are known as ppppllllaaaaiiiinnnn tttteeeexxxxtttt eeeeqqqquuuuiiiivvvvaaaalllleeeennnnttttssss and
+ must NNNNOOOOTTTT be made available to anyone but the root user.
+ To protect these passwords the smbpasswd file is placed
+ in a directory with read and traverse access only to
+ the root user and the smbpasswd file itself must be set
+ to be read/write only by root, with no other access.
+
+ AAAAccccccccoooouuuunnnntttt FFFFllllaaaaggggssss
+ This section contains flags that describe the
+ attributes of the users account. In the Samba 2.2
+ release this field is bracketed by '[' and ']'
+ characters and is always 13 characters in length
+ (including the '[' and ']' characters). The contents
+ of this field may be any of the characters.
+
+ o+ UUUU - This means this is a "User" account, i.e. an
+ ordinary user. Only User and Workstation Trust
+ accounts are currently supported in the smbpasswd
+ file.
+
+ o+ NNNN - This means the account has no password (the
+ passwords in the fields LANMAN Password Hash and NT
+ Password Hash are ignored). Note that this will only
+ allow users to log on with no password if the _n_u_l_l
+ _p_a_s_s_w_o_r_d_s parameter is set in the _s_m_b._c_o_n_f(_5)
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((5555))))
+
+
+
+ config file.
+
+ o+ DDDD - This means the account is disabled and no
+ SMB/CIFS logins will be allowed for this user.
+
+ o+ WWWW - This means this account is a "Workstation Trust"
+ account. This kind of account is used in the Samba
+ PDC code stream to allow Windows NT Workstations and
+ Servers to join a Domain hosted by a Samba PDC.
+
+ Other flags may be added as the code is extended in future.
+ The rest of this field space is filled in with spaces.
+
+ LLLLaaaasssstttt CCCChhhhaaaannnnggggeeee TTTTiiiimmmmeeee
+ This field consists of the time the account was last
+ modified. It consists of the characters 'LCT-'
+ (standing for "Last Change Time") followed by a numeric
+ encoding of the UNIX time in seconds since the epoch
+ (1970) that the last change was made.
+
+ All other colon separated fields are ignored at this time.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd((((8888)))) samba(7) and the Internet RFC1321 for details
+ on the MD4 algorithm.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.7/samba.7 b/packaging/Caldera/OpenServer/man/cat.7/samba.7
new file mode 100755
index 00000000000..6f1655902d5
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.7/samba.7
@@ -0,0 +1,198 @@
+
+
+
+ SSSSAAAAMMMMBBBBAAAA((((7777)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSAAAAMMMMBBBBAAAA((((7777))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ SAMBA - A Windows SMB/CIFS fileserver for UNIX
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ SSSSaaaammmmbbbbaaaa
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ The Samba software suite is a collection of programs that
+ implements the Server Message Block (commonly abbreviated as
+ SMB) protocol for UNIX systems. This protocol is sometimes
+ also referred to as the Common Internet File System (CIFS),
+ LanManager or NetBIOS protocol.
+
+ ssssmmmmbbbbdddd The ssssmmmmbbbbdddd daemon provides the file and print services to
+ SMB clients, such as Windows 95/98, Windows NT, Windows
+ for Workgroups or LanManager. The configuration file
+ for this daemon is described in _s_m_b._c_o_n_f
+
+ nnnnmmmmbbbbdddd The nnnnmmmmbbbbdddd daemon provides NetBIOS nameserving and
+ browsing support. The configuration file for this
+ daemon is described in _s_m_b._c_o_n_f
+
+ ssssmmmmbbbbcccclllliiiieeeennnntttt
+ The ssssmmmmbbbbcccclllliiiieeeennnntttt program implements a simple ftp-like
+ client. This is useful for accessing SMB shares on
+ other compatible servers (such as Windows NT), and can
+ also be used to allow a UNIX box to print to a printer
+ attached to any SMB server (such as a PC running
+ Windows NT).
+
+ tttteeeessssttttppppaaaarrrrmmmm
+ The tttteeeessssttttppppaaaarrrrmmmm utility is a simple syntax checker for
+ Samba's _s_m_b._c_o_n_fconfiguration file.
+
+ tttteeeessssttttpppprrrrnnnnssss
+ The tttteeeessssttttpppprrrrnnnnssss utility supports testing printer names
+ defined in your _p_r_i_n_t_c_a_p> file used by Samba.
+
+ ssssmmmmbbbbssssttttaaaattttuuuussss
+ The ssssmmmmbbbbssssttttaaaattttuuuussss tool provides access to information about
+ the current connections to ssssmmmmbbbbdddd.
+
+ nnnnmmmmbbbbllllooooooookkkkuuuupppp
+ The nnnnmmmmbbbbllllooooooookkkkuuuupppp tools allows NetBIOS name queries to be
+ made from a UNIX host.
+
+ mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee
+ The mmmmaaaakkkkeeee____ssssmmmmbbbbccccooooddddeeeeppppaaaaggggeeee utility provides a means of
+ creating SMB code page definition files for your ssssmmmmbbbbdddd
+ server.
+
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSAAAAMMMMBBBBAAAA((((7777)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSAAAAMMMMBBBBAAAA((((7777))))
+
+
+
+ The ssssmmmmbbbbppppaaaasssssssswwwwdddd command is a tool for changing LanMan and
+ Windows NT password hashes on Samba and Windows NT
+ servers.
+
+ CCCCOOOOMMMMPPPPOOOONNNNEEEENNNNTTTTSSSS
+ The Samba suite is made up of several components. Each
+ component is described in a separate manual page. It is
+ strongly recommended that you read the documentation that
+ comes with Samba and the manual pages of those components
+ that you use. If the manual pages aren't clear enough then
+ please send a patch or bug report to samba@samba.org
+ <URL:mailto:samba@samba.org>
+
+ AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY
+ The Samba software suite is licensed under the GNU Public
+ License(GPL). A copy of that license should have come with
+ the package in the file COPYING. You are encouraged to
+ distribute copies of the Samba suite, but please obey the
+ terms of this license.
+
+ The latest version of the Samba suite can be obtained via
+ anonymous ftp from samba.org in the directory pub/samba/. It
+ is also available on several mirror sites worldwide.
+
+ You may also find useful information about Samba on the
+ newsgroup comp.protocol.smb <URL:news:comp.protocols.smb>
+ and the Samba mailing list. Details on how to join the
+ mailing list are given in the README file that comes with
+ Samba.
+
+ If you have access to a WWW viewer (such as Netscape or
+ Mosaic) then you will also find lots of useful information,
+ including back issues of the Samba mailing list, at
+ http://lists.samba.org <URL:http://lists.samba.org/>.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ CCCCOOOONNNNTTTTRRRRIIIIBBBBUUUUTTTTIIIIOOOONNNNSSSS
+ If you wish to contribute to the Samba project, then I
+ suggest you join the Samba mailing list at
+ http://lists.samba.org <URL:http://lists.samba.org/>.
+
+ If you have patches to submit or bugs to report then you may
+ mail them directly to samba-patches@samba.org. Note,
+ however, that due to the enormous popularity of this package
+ the Samba Team may take some time to respond to mail. We
+ prefer patches in ddddiiiiffffffff ----uuuu format.
+
+ CCCCOOOONNNNTTTTRRRRIIIIBBBBUUUUTTTTOOOORRRRSSSS
+ Contributors to the project are now too numerous to mention
+ here but all deserve the thanks of all Samba users. To see a
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSAAAAMMMMBBBBAAAA((((7777)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSAAAAMMMMBBBBAAAA((((7777))))
+
+
+
+ full list, look at ftp://samba.org/pub/samba/alpha/change-
+ log <URL:ftp://samba.org/pub/samba/alpha/change-log> for the
+ pre-CVS changes and at
+ ftp://samba.org/pub/samba/alpha/cvs.log
+ <URL:ftp://samba.org/pub/samba/alpha/cvs.log> for the
+ contributors to Samba post-CVS. CVS is the Open Source
+ source code control system used by the Samba Team to develop
+ Samba. The project would have been unmanageable without it.
+
+ In addition, several commercial organizations now help fund
+ the Samba Team with money and equipment. For details see the
+ Samba Web pages at http://samba.org/samba/samba-thanks.html
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/nmbd.8 b/packaging/Caldera/OpenServer/man/cat.8/nmbd.8
new file mode 100755
index 00000000000..ef04c45df7d
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/nmbd.8
@@ -0,0 +1,330 @@
+
+
+
+ NNNNMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBDDDD((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ nmbd - NetBIOS name server to provide NetBIOS over IP
+ naming services to clients
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ nnnnmmmmbbbbdddd [ ----DDDD ] [ ----aaaa ] [ ----iiii ] [ ----oooo ] [ ----PPPP ] [ ----hhhh ] [ ----VVVV ]
+ [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----HHHH <<<<llllmmmmhhhhoooossssttttssss ffffiiiilllleeee>>>> ] [ ----llll <<<<lllloooogggg
+ ddddiiiirrrreeeeccccttttoooorrrryyyy>>>> ] [ ----nnnn <<<<pppprrrriiiimmmmaaaarrrryyyy nnnneeeettttbbbbiiiioooossss nnnnaaaammmmeeee>>>> ] [ ----pppp <<<<ppppoooorrrrtttt
+ nnnnuuuummmmbbbbeeeerrrr>>>> ] [ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>> ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This program is part of the Samba suite.
+
+ nnnnmmmmbbbbdddd is a server that understands and can reply to NetBIOS
+ over IP name service requests, like those produced by
+ SMB/CIFS clients such as Windows 95/98/ME, Windows NT,
+ Windows 2000, and LanManager clients. It also participates
+ in the browsing protocols which make up the Windows "Network
+ Neighborhood" view.
+
+ SMB/CIFS clients, when they start up, may wish to locate an
+ SMB/CIFS server. That is, they wish to know what IP number a
+ specified host is using.
+
+ Amongst other services, nnnnmmmmbbbbdddd will listen for such requests,
+ and if its own NetBIOS name is specified it will respond
+ with the IP number of the host it is running on. Its "own
+ NetBIOS name" is by default the primary DNS name of the host
+ it is running on, but this can be overridden with the ----nnnn
+ option (see OPTIONS below). Thus nnnnmmmmbbbbdddd will reply to
+ broadcast queries for its own name(s). Additional names for
+ nnnnmmmmbbbbdddd to respond on can be set via parameters in the
+ _s_m_b._c_o_n_f(_5) configuration file.
+
+ nnnnmmmmbbbbdddd can also be used as a WINS (Windows Internet Name
+ Server) server. What this basically means is that it will
+ act as a WINS database server, creating a database from name
+ registration requests that it receives and replying to
+ queries from clients for these names.
+
+ In addition, nnnnmmmmbbbbdddd can act as a WINS proxy, relaying
+ broadcast queries from clients that do not understand how to
+ talk the WINS protocol to a WIN server.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----DDDD If specified, this parameter causes nnnnmmmmbbbbdddd to operate as
+ a daemon. That is, it detaches itself and runs in the
+ background, fielding requests on the appropriate port.
+ By default, nnnnmmmmbbbbdddd will operate as a daemon if launched
+ from a command shell. nmbd can also be operated from
+ the iiiinnnneeeettttdddd meta-daemon, although this is not
+ recommended.
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBDDDD((((8888))))
+
+
+
+ ----aaaa If this parameter is specified, each new connection
+ will append log messages to the log file. This is the
+ default.
+
+ ----iiii If this parameter is specified it causes the server to
+ run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell.
+ Setting this parameter negates the implicit deamon mode
+ when run from the command line.
+
+ ----oooo If this parameter is specified, the log files will be
+ overwritten when opened. By default, ssssmmmmbbbbdddd will append
+ entries to the log files.
+
+ ----hhhh Prints the help information (usage) for nnnnmmmmbbbbdddd.
+
+ ----HHHH <<<<ffffiiiilllleeeennnnaaaammmmeeee>>>>
+ NetBIOS lmhosts file. The lmhosts file is a list of
+ NetBIOS names to IP addresses that is loaded by the
+ nmbd server and used via the name resolution mechanism
+ name resolve order described in _s_m_b._c_o_n_f(_5) to resolve
+ any NetBIOS name queries needed by the server. Note
+ that the contents of this file are NNNNOOOOTTTT used by nnnnmmmmbbbbdddd to
+ answer any name queries. Adding a line to this file
+ affects name NetBIOS resolution from this host OOOONNNNLLLLYYYY.
+
+ The default path to this file is compiled into Samba as
+ part of the build process. Common defaults are
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_l_i_b/_l_m_h_o_s_t_s, /_u_s_r/_s_a_m_b_a/_l_i_b/_l_m_h_o_s_t_s or
+ /_e_t_c/_l_m_h_o_s_t_s. See the _l_m_h_o_s_t_s(_5) man page for details
+ on the contents of this file.
+
+ ----VVVV Prints the version number for nnnnmmmmbbbbdddd.
+
+ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>>
+ debuglevel is an integer from 0 to 10. The default
+ value if this parameter is not specified is zero.
+
+ The higher this value, the more detail will be logged
+ to the log files about the activities of the server. At
+ level 0, only critical errors and serious warnings will
+ be logged. Level 1 is a reasonable level for day to day
+ running - it generates a small amount of information
+ about operations carried out.
+
+ Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a
+ problem. Levels above 3 are designed for use only by
+ developers and generate HUGE amounts of log data, most
+ of which is extremely cryptic.
+
+ Note that specifying this parameter here will override
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBDDDD((((8888))))
+
+
+
+ the log level parameter in the _s_m_b._c_o_n_f file.
+
+ ----llll <<<<lllloooogggg ddddiiiirrrreeeeccccttttoooorrrryyyy>>>>
+ The -l parameter specifies a directory into which the
+ "log.nmbd" log file will be created for operational
+ data from the running nnnnmmmmbbbbdddd server. The default log
+ directory is compiled into Samba as part of the build
+ process. Common defaults are
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_v_a_r/_l_o_g._n_m_b, /_u_s_r/_s_a_m_b_a/_v_a_r/_l_o_g._n_m_b
+ or /_v_a_r/_l_o_g/_l_o_g._n_m_b. BBBBeeeewwwwaaaarrrreeee:::: If the directory specified
+ does not exist, nnnnmmmmbbbbdddd will log to the default debug log
+ location defined at compile time.
+
+ ----nnnn <<<<pppprrrriiiimmmmaaaarrrryyyy NNNNeeeettttBBBBIIIIOOOOSSSS nnnnaaaammmmeeee>>>>
+ This option allows you to override the NetBIOS name
+ that Samba uses for itself. This is identical to
+ setting the NetBIOS name parameter in the _s_m_b._c_o_n_f
+ file. However, a command line setting will take
+ precedence over settings in _s_m_b._c_o_n_f.
+
+ ----pppp <<<<UUUUDDDDPPPP ppppoooorrrrtttt nnnnuuuummmmbbbbeeeerrrr>>>>
+ UDP port number is a positive integer value. This
+ option changes the default UDP port number (normally
+ 137) that nnnnmmmmbbbbdddd responds to name queries on. Don't use
+ this option unless you are an expert, in which case you
+ won't need help!
+
+ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>>
+ The default configuration file name is set at build
+ time, typically as /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f, but
+ this may be changed when Samba is autoconfigured.
+
+ The file specified contains the configuration details
+ required by the server. See _s_m_b._c_o_n_f(_5) for more
+ information.
+
+ FFFFIIIILLLLEEEESSSS
+ /_e_t_c/_i_n_e_t_d._c_o_n_f
+ If the server is to be run by the iiiinnnneeeettttdddd meta-daemon,
+ this file must contain suitable startup information for
+ the meta-daemon. See the UNIX_INSTALL.html document for
+ details.
+
+ /_e_t_c/_r_c
+ or whatever initialization script your system uses).
+
+ If running the server as a daemon at startup, this file
+ will need to contain an appropriate startup sequence
+ for the server. See the UNIX_INSTALL.html document for
+ details.
+
+ /_e_t_c/_s_e_r_v_i_c_e_s
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBDDDD((((8888))))
+
+
+
+ If running the server via the meta-daemon iiiinnnneeeettttdddd, this
+ file must contain a mapping of service name (e.g.,
+ netbios-ssn) to service port (e.g., 139) and protocol
+ type (e.g., tcp). See the UNIX_INSTALL.html document
+ for details.
+
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f
+ This is the default location of the _s_m_b._c_o_n_f server
+ configuration file. Other common places that systems
+ install this file are /_u_s_r/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f and
+ /_e_t_c/_s_m_b._c_o_n_f.
+
+ When run as a WINS server (see the wins support
+ parameter in the _s_m_b._c_o_n_f(_5) man page), nnnnmmmmbbbbdddd will store
+ the WINS database in the file _w_i_n_s._d_a_t in the _v_a_r/_l_o_c_k_s
+ directory configured under wherever Samba was
+ configured to install itself.
+
+ If nnnnmmmmbbbbdddd is acting as a bbbbrrrroooowwwwsssseeee mmmmaaaasssstttteeeerrrr (see the local
+ master parameter in the _s_m_b._c_o_n_f(_5) man page, nnnnmmmmbbbbdddd will
+ store the browsing database in the file _b_r_o_w_s_e._d_a_t in
+ the _v_a_r/_l_o_c_k_s directory configured under wherever Samba
+ was configured to install itself.
+
+ SSSSIIIIGGGGNNNNAAAALLLLSSSS
+ To shut down an nnnnmmmmbbbbdddd process it is recommended that SIGKILL
+ (-9) NNNNOOOOTTTT be used, except as a last resort, as this may leave
+ the name database in an inconsistent state. The correct way
+ to terminate nnnnmmmmbbbbdddd is to send it a SIGTERM (-15) signal and
+ wait for it to die on its own.
+
+ nnnnmmmmbbbbdddd will accept SIGHUP, which will cause it to dump out its
+ namelists into the file _n_a_m_e_l_i_s_t._d_e_b_u_g in the
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_v_a_r/_l_o_c_k_s directory (or the _v_a_r/_l_o_c_k_s
+ directory configured under wherever Samba was configured to
+ install itself). This will also cause nnnnmmmmbbbbdddd to dump out its
+ server database in the _l_o_g._n_m_b file.
+
+ The debug log level of nmbd may be raised or lowered using
+ ssssmmmmbbbbccccoooonnnnttttrrrroooollll((((1111))))
+ (SIGUSR[1|2] signals are no longer used in Samba 2.2). This
+ is to allow transient problems to be diagnosed, whilst still
+ running at a normally low log level.
+
+ TTTTRRRROOOOUUUUBBBBLLLLEEEESSSSHHHHOOOOOOOOTTTTIIIINNNNGGGG
+ One of the common causes of difficulty when installing Samba
+ and SWAT is the existsnece of some type of firewall or port
+ filtering software on the Samba server. Make sure that the
+ appropriate ports outlined in this man page are available on
+ the server and are not currently being blocked by some type
+ of security software such as iptables or "port sentry". For
+ more troubleshooting information, refer to the additional
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ NNNNMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) NNNNMMMMBBBBDDDD((((8888))))
+
+
+
+ documentation included in the Samba distribution.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ iiiinnnneeeettttdddd((((8888)))), ssssmmmmbbbbdddd((((8888)))) _s_m_b._c_o_n_f(_5)
+ ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ and the Internet RFC's _r_f_c_1_0_0_1._t_x_t, _r_f_c_1_0_0_2._t_x_t. In
+ addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page http://samba.org/cifs/
+ <URL:http://samba.org/cifs/>.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/smbd.8 b/packaging/Caldera/OpenServer/man/cat.8/smbd.8
new file mode 100755
index 00000000000..45f49491d5d
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/smbd.8
@@ -0,0 +1,396 @@
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbd - server to provide SMB/CIFS services to clients
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbdddd [ ----DDDD ] [ ----aaaa ] [ ----iiii ] [ ----oooo ] [ ----PPPP ] [ ----hhhh ] [ ----VVVV ]
+ [ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>> ] [ ----llll <<<<lllloooogggg ddddiiiirrrreeeeccccttttoooorrrryyyy>>>> ] [ ----pppp <<<<ppppoooorrrrtttt
+ nnnnuuuummmmbbbbeeeerrrr>>>> ] [ ----OOOO <<<<ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnn>>>> ] [ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>>
+ ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This program is part of the Samba suite.
+
+ ssssmmmmbbbbdddd is the server daemon that provides filesharing and
+ printing services to Windows clients. The server provides
+ filespace and printer services to clients using the SMB (or
+ CIFS) protocol. This is compatible with the LanManager
+ protocol, and can service LanManager clients. These include
+ MSCLIENT 3.0 for DOS, Windows for Workgroups, Windows
+ 95/98/ME, Windows NT, Windows 2000, OS/2, DAVE for
+ Macintosh, and smbfs for Linux.
+
+ An extensive description of the services that the server can
+ provide is given in the man page for the configuration file
+ controlling the attributes of those services (see
+ _s_m_b._c_o_n_f(_5)
+ This man page will not describe the services, but will
+ concentrate on the administrative aspects of running the
+ server.
+
+ Please note that there are significant security implications
+ to running this server, and the _s_m_b._c_o_n_f(_5) manpage should
+ be regarded as mandatory reading before proceeding with
+ installation.
+
+ A session is created whenever a client requests one. Each
+ client gets a copy of the server for each session. This copy
+ then services all connections made by the client during that
+ session. When all connections from its client are closed,
+ the copy of the server for that client terminates.
+
+ The configuration file, and any files that it includes, are
+ automatically reloaded every minute, if they change. You can
+ force a reload by sending a SIGHUP to the server. Reloading
+ the configuration file will not affect connections to any
+ service that is already established. Either the user will
+ have to disconnect from the service, or ssssmmmmbbbbdddd killed and
+ restarted.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----DDDD If specified, this parameter causes the server to
+ operate as a daemon. That is, it detaches itself and
+ runs in the background, fielding requests on the
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ appropriate port. Operating the server as a daemon is
+ the recommended way of running ssssmmmmbbbbdddd for servers that
+ provide more than casual use file and print services.
+ This switch is assumed if ssssmmmmbbbbdddd is executed on the
+ command line of a shell.
+
+ ----aaaa If this parameter is specified, each new connection
+ will append log messages to the log file. This is the
+ default.
+
+ ----iiii If this parameter is specified it causes the server to
+ run "interactively", not as a daemon, even if the
+ server is executed on the command line of a shell.
+ Setting this parameter negates the implicit deamon mode
+ when run from the command line.
+
+ ----oooo If this parameter is specified, the log files will be
+ overwritten when opened. By default, ssssmmmmbbbbdddd will append
+ entries to the log files.
+
+ ----PPPP Passive option. Causes ssssmmmmbbbbdddd not to send any network
+ traffic out. Used for debugging by the developers only.
+
+ ----hhhh Prints the help information (usage) for ssssmmmmbbbbdddd.
+
+ ----vvvv Prints the version number for ssssmmmmbbbbdddd.
+
+ ----dddd <<<<ddddeeeebbbbuuuugggg lllleeeevvvveeeellll>>>>
+ _d_e_b_u_g_l_e_v_e_l is an integer from 0 to 10. The default
+ value if this parameter is not specified is zero.
+
+ The higher this value, the more detail will be logged
+ to the log files about the activities of the server. At
+ level 0, only critical errors and serious warnings will
+ be logged. Level 1 is a reasonable level for day to day
+ running - it generates a small amount of information
+ about operations carried out.
+
+ Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a
+ problem. Levels above 3 are designed for use only by
+ developers and generate HUGE amounts of log data, most
+ of which is extremely cryptic.
+
+ Note that specifying this parameter here will override
+ the log level file.
+
+ ----llll <<<<lllloooogggg ddddiiiirrrreeeeccccttttoooorrrryyyy>>>>
+ If specified, _l_o_g _d_i_r_e_c_t_o_r_y specifies a log directory
+ into which the "log.smbd" log file will be created for
+ informational and debug messages from the running
+ server. The log file generated is never removed by the
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ server although its size may be controlled by the max
+ log size option in the _s_m_b._c_o_n_f(_5) file. BBBBeeeewwwwaaaarrrreeee:::: If
+ the directory specified does not exist, ssssmmmmbbbbdddd will log
+ to the default debug log location defined at compile
+ time.
+
+ The default log directory is specified at compile time.
+
+ ----OOOO <<<<ssssoooocccckkkkeeeetttt ooooppppttttiiiioooonnnnssss>>>>
+ See the socket options parameter in the _s_m_b._c_o_n_f(_5)
+ file for details.
+
+ ----pppp <<<<ppppoooorrrrtttt nnnnuuuummmmbbbbeeeerrrr>>>>
+ _p_o_r_t _n_u_m_b_e_r is a positive integer value. The default
+ value if this parameter is not specified is 139.
+
+ This number is the port number that will be used when
+ making connections to the server from client software.
+ The standard (well-known) port number for the SMB over
+ TCP is 139, hence the default. If you wish to run the
+ server as an ordinary user rather than as root, most
+ systems will require you to use a port number greater
+ than 1024 - ask your system administrator for help if
+ you are in this situation.
+
+ In order for the server to be useful by most clients,
+ should you configure it on a port other than 139, you
+ will require port redirection services on port 139,
+ details of which are outlined in rfc1002.txt section
+ 4.3.5.
+
+ This parameter is not normally specified except in the
+ above situation.
+
+ ----ssss <<<<ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee>>>>
+ The file specified contains the configuration details
+ required by the server. The information in this file
+ includes server-specific information such as what
+ printcap file to use, as well as descriptions of all
+ the services that the server is to provide. See
+ _s_m_b._c_o_n_f(_5) for more information. The default
+ configuration file name is determined at compile time.
+
+ FFFFIIIILLLLEEEESSSS
+ /_e_t_c/_i_n_e_t_d._c_o_n_f
+ If the server is to be run by the iiiinnnneeeettttdddd meta-daemon,
+ this file must contain suitable startup information for
+ the meta-daemon. See the UNIX_INSTALL.html document for
+ details.
+
+ /_e_t_c/_r_c
+ or whatever initialization script your system uses).
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ If running the server as a daemon at startup, this file
+ will need to contain an appropriate startup sequence
+ for the server. See the UNIX_INSTALL.html document for
+ details.
+
+ /_e_t_c/_s_e_r_v_i_c_e_s
+ If running the server via the meta-daemon iiiinnnneeeettttdddd, this
+ file must contain a mapping of service name (e.g.,
+ netbios-ssn) to service port (e.g., 139) and protocol
+ type (e.g., tcp). See the UNIX_INSTALL.html document
+ for details.
+
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f
+ This is the default location of the _s_m_b._c_o_n_f server
+ configuration file. Other common places that systems
+ install this file are /_u_s_r/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f and
+ /_e_t_c/_s_m_b._c_o_n_f.
+
+ This file describes all the services the server is to
+ make available to clients. See _s_m_b._c_o_n_f(_5) for more
+ information.
+
+ LLLLIIIIMMMMIIIITTTTAAAATTTTIIIIOOOONNNNSSSS
+ On some systems ssssmmmmbbbbdddd cannot change uid back to root after a
+ setuid() call. Such systems are called trapdoor uid systems.
+ If you have such a system, you will be unable to connect
+ from a client (such as a PC) as two different users at once.
+ Attempts to connect the second user will result in access
+ denied or similar.
+
+ EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT VVVVAAAARRRRIIIIAAAABBBBLLLLEEEESSSS
+ PPPPRRRRIIIINNNNTTTTEEEERRRR
+ If no printer name is specified to printable services,
+ most systems will use the value of this variable (or lp
+ if this variable is not defined) as the name of the
+ printer to use. This is not specific to the server,
+ however.
+
+ PPPPAAAAMMMM IIIINNNNTTTTEEEERRRRAAAACCCCTTTTIIIIOOOONNNN
+ Samba uses PAM for authentication (when presented with a
+ plaintext password), for account checking (is this account
+ disabled?) and for session management. The degree too which
+ samba supports PAM is restricted by the limitations of the
+ SMB protocol and the obey pam restricions smb.conf
+ paramater. When this is set, the following restrictions
+ apply:
+
+ o+ AAAAccccccccoooouuuunnnntttt VVVVaaaalllliiiiddddaaaattttiiiioooonnnn: All acccesses to a samba server are
+ checked against PAM to see if the account is vaild, not
+ disabled and is permitted to login at this time. This also
+ applies to encrypted logins.
+
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ o+ SSSSeeeessssssssiiiioooonnnn MMMMaaaannnnaaaaggggeeeemmmmeeeennnntttt: When not using share level secuirty,
+ users must pass PAM's session checks before access is
+ granted. Note however, that this is bypassed in share
+ level secuirty. Note also that some older pam
+ configuration files may need a line added for session
+ support.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ TTTTRRRROOOOUUUUBBBBLLLLEEEESSSSHHHHOOOOOOOOTTTTIIIINNNNGGGG
+ One of the common causes of difficulty when installing Samba
+ and SWAT is the existsnece of some type of firewall or port
+ filtering software on the Samba server. Make sure that the
+ appropriate ports outlined in this man page are available on
+ the server and are not currently being blocked by some type
+ of security software such as iptables or "port sentry". For
+ more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+
+ Most diagnostics issued by the server are logged in a
+ specified log file. The log file name is specified at
+ compile time, but may be overridden on the command line.
+
+ The number and nature of diagnostics available depends on
+ the debug level used by the server. If you have problems,
+ set the debug level to 3 and peruse the log files.
+
+ Most messages are reasonably self-explanatory.
+ Unfortunately, at the time this man page was created, there
+ are too many diagnostics available in the source code to
+ warrant describing each and every diagnostic. At this stage
+ your best bet is still to grep the source code and inspect
+ the conditions that gave rise to the diagnostics you are
+ seeing.
+
+ SSSSIIIIGGGGNNNNAAAALLLLSSSS
+ Sending the ssssmmmmbbbbdddd a SIGHUP will cause it to reload its
+ _s_m_b._c_o_n_f configuration file within a short period of time.
+
+ To shut down a user's ssssmmmmbbbbdddd process it is recommended that
+ SSSSIIIIGGGGKKKKIIIILLLLLLLL ((((----9999)))) NNNNOOOOTTTT be used, except as a last resort, as this
+ may leave the shared memory area in an inconsistent state.
+ The safe way to terminate an ssssmmmmbbbbdddd is to send it a SIGTERM
+ (-15) signal and wait for it to die on its own.
+
+ The debug log level of ssssmmmmbbbbdddd may be raised or lowered using
+ ssssmmmmbbbbccccoooonnnnttttrrrroooollll((((1111))))
+ program (SIGUSR[1|2] signals are no longer used in Samba
+ 2.2). This is to allow transient problems to be diagnosed,
+ whilst still running at a normally low log level.
+
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBDDDD((((8888))))
+
+
+
+ Note that as the signal handlers send a debug write, they
+ are not re-entrant in ssssmmmmbbbbdddd. This you should wait until ssssmmmmbbbbdddd
+ is in a state of waiting for an incoming SMB before issuing
+ them. It is possible to make the signal handlers safe by
+ un-blocking the signals before the select call and re-
+ blocking them after, however this would affect performance.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ hosts_access(5), iiiinnnneeeettttdddd((((8888)))), nnnnmmmmbbbbdddd((((8888)))) _s_m_b._c_o_n_f(_5)
+ ssssmmmmbbbbcccclllliiiieeeennnntttt((((1111))))
+ and the Internet RFC's _r_f_c_1_0_0_1._t_x_t, _r_f_c_1_0_0_2._t_x_t. In
+ addition the CIFS (formerly SMB) specification is available
+ as a link from the Web page http://samba.org/cifs/
+ <URL:http://samba.org/cifs/>.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 6 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/smbmnt.8 b/packaging/Caldera/OpenServer/man/cat.8/smbmnt.8
new file mode 100755
index 00000000000..e4c5d6a6cf2
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/smbmnt.8
@@ -0,0 +1,132 @@
+
+
+
+ SSSSMMMMBBBBMMMMNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMNNNNTTTT((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbmnt - helper utility for mounting SMB filesystems
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbmmmmnnnntttt mmmmoooouuuunnnntttt----ppppooooiiiinnnntttt [ ----ssss <<<<sssshhhhaaaarrrreeee>>>> ] [ ----rrrr ] [ ----uuuu <<<<uuuuiiiidddd>>>> ] [
+ ----gggg <<<<ggggiiiidddd>>>> ] [ ----ffff <<<<mmmmaaaasssskkkk>>>> ] [ ----dddd <<<<mmmmaaaasssskkkk>>>> ] [ ----oooo <<<<ooooppppttttiiiioooonnnnssss>>>> ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ ssssmmmmbbbbmmmmnnnntttt is a helper application used by the smbmount program
+ to do the actual mounting of SMB shares. ssssmmmmbbbbmmmmnnnntttt can be
+ installed setuid root if you want normal users to be able to
+ mount their SMB shares.
+
+ A setuid smbmnt will only allow mounts on directories owned
+ by the user, and that the user has write permission on.
+
+ The ssssmmmmbbbbmmmmnnnntttt program is normally invoked by ssssmmmmbbbbmmmmoooouuuunnnntttt((((8888))))
+ It should not be invoked directly by users.
+
+ smbmount searches the normal PATH for smbmnt. You must
+ ensure that the smbmnt version in your path matches the
+ smbmount used.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----rrrr mount the filesystem read-only
+
+ ----uuuu uuuuiiiidddd
+ specify the uid that the files will be owned by
+
+ ----gggg ggggiiiidddd
+ specify the gid that the files will be owned by
+
+ ----ffff mmmmaaaasssskkkk
+ specify the octal file mask applied
+
+ ----dddd mmmmaaaasssskkkk
+ specify the octal directory mask applied
+
+ ----oooo ooooppppttttiiiioooonnnnssss
+ list of options that are passed as-is to smbfs, if this
+ command is run on a 2.4 or higher Linux kernel.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ Volker Lendecke, Andrew Tridgell, Michael H. Warfield and
+ others.
+
+ The current maintainer of smbfs and the userspace tools
+ ssssmmmmbbbbmmmmoooouuuunnnntttt, ssssmmmmbbbbuuuummmmoooouuuunnnntttt, and ssssmmmmbbbbmmmmnnnntttt is Urban Widmark
+ <URL:mailto:urban@teststation.com>. The SAMBA Mailing list
+ <URL:mailto:samba@samba.org> is the preferred place to ask
+ questions regarding these programs.
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBMMMMNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMNNNNTTTT((((8888))))
+
+
+
+ The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/smbmount.8 b/packaging/Caldera/OpenServer/man/cat.8/smbmount.8
new file mode 100755
index 00000000000..22bbe913959
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/smbmount.8
@@ -0,0 +1,264 @@
+
+
+
+ SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbmount - mount an smbfs filesystem
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbmmmmoooouuuunnnntttt sssseeeerrrrvvvviiiicccceeee mmmmoooouuuunnnntttt----ppppooooiiiinnnntttt [ ----oooo ooooppppttttiiiioooonnnnssss ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ ssssmmmmbbbbmmmmoooouuuunnnntttt mounts a Linux SMB filesystem. It is usually
+ invoked as mmmmoooouuuunnnntttt....ssssmmmmbbbbffffssss by the mmmmoooouuuunnnntttt((((8888)))) command when using
+ the "-t smbfs" option. This command only works in Linux, and
+ the kernel must support the smbfs filesystem.
+
+ Options to ssssmmmmbbbbmmmmoooouuuunnnntttt are specified as a comma-separated list
+ of key=value pairs. It is possible to send options other
+ than those listed here, assuming that smbfs supports them.
+ If you get mount failures, check your kernel log for errors
+ on unknown options.
+
+ ssssmmmmbbbbmmmmoooouuuunnnntttt is a daemon. After mounting it keeps running until
+ the mounted smbfs is umounted. It will log things that
+ happen when in daemon mode using the "machine name"
+ smbmount, so typically this output will end up in
+ _l_o_g._s_m_b_m_o_u_n_t. The ssssmmmmbbbbmmmmoooouuuunnnntttt process may also be called
+ mount.smbfs.
+
+ NNNNOOOOTTTTEEEE:::: ssssmmmmbbbbmmmmoooouuuunnnntttt calls ssssmmmmbbbbmmmmnnnntttt((((8888)))) to do the actual mount. You
+ must make sure that ssssmmmmbbbbmmmmnnnntttt is in the path so that it can be
+ found.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ uuuusssseeeerrrrnnnnaaaammmmeeee====<<<<aaaarrrrgggg>>>>
+ specifies the username to connect as. If this is not
+ given, then the environment variable UUUUSSSSEEEERRRR is used.
+ This option can also take the form "user%password" or
+ "user/workgroup" or "user/workgroup%password" to allow
+ the password and workgroup to be specified as part of
+ the username.
+
+ ppppaaaasssssssswwwwoooorrrrdddd====<<<<aaaarrrrgggg>>>>
+ specifies the SMB password. If this option is not given
+ then the environment variable PPPPAAAASSSSSSSSWWWWDDDD is used. If it can
+ find no password ssssmmmmbbbbmmmmoooouuuunnnntttt will prompt for a passeword,
+ unless the guest option is given.
+
+ Note that password which contain the arguement
+ delimiter character (i.e. a comma ',') will failed to
+ be parsed correctly on the command line. However, the
+ same password defined in the PASSWD environment
+ variable or a credentials file (see below) will be read
+ correctly.
+
+ ccccrrrreeeeddddeeeennnnttttiiiiaaaallllssss====<<<<ffffiiiilllleeeennnnaaaammmmeeee>>>>
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888))))
+
+
+
+ specifies a file that contains a username and/or
+ password. The format of the file is:
+
+
+ username = <value>
+ password = <value>
+
+
+
+ This is preferred over having passwords in plaintext in
+ a shared file, such as /_e_t_c/_f_s_t_a_b. Be sure to protect
+ any credentials file properly.
+
+ nnnneeeettttbbbbiiiioooossssnnnnaaaammmmeeee====<<<<aaaarrrrgggg>>>>
+ sets the source NetBIOS name. It defaults to the local
+ hostname.
+
+ uuuuiiiidddd====<<<<aaaarrrrgggg>>>>
+ sets the uid that will own all files on the mounted
+ filesystem. It may be specified as either a username
+ or a numeric uid.
+
+ ggggiiiidddd====<<<<aaaarrrrgggg>>>>
+ sets the gid that will own all files on the mounted
+ filesystem. It may be specified as either a groupname
+ or a numeric gid.
+
+ ppppoooorrrrtttt====<<<<aaaarrrrgggg>>>>
+ sets the remote SMB port number. The default is 139.
+
+ ffffmmmmaaaasssskkkk====<<<<aaaarrrrgggg>>>>
+ sets the file mask. This determines the permissions
+ that remote files have in the local filesystem. The
+ default is based on the current umask.
+
+ ddddmmmmaaaasssskkkk====<<<<aaaarrrrgggg>>>>
+ sets the directory mask. This determines the
+ permissions that remote directories have in the local
+ filesystem. The default is based on the current umask.
+
+ ddddeeeebbbbuuuugggg====<<<<aaaarrrrgggg>>>>
+ sets the debug level. This is useful for tracking down
+ SMB connection problems. A suggested value to start
+ with is 4. If set too high there will be a lot of
+ output, possibly hiding the useful output.
+
+ iiiipppp====<<<<aaaarrrrgggg>>>>
+ sets the destination host or IP address.
+
+ wwwwoooorrrrkkkkggggrrrroooouuuupppp====<<<<aaaarrrrgggg>>>>
+ sets the workgroup on the destination
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888))))
+
+
+
+ ssssoooocccckkkkoooopppptttt====<<<<aaaarrrrgggg>>>>
+ sets the TCP socket options. See the _s_m_b._c_o_n_f
+ _s_o_c_k_e_t _o_p_t_i_o_n_s option.
+
+ ssssccccooooppppeeee====<<<<aaaarrrrgggg>>>>
+ sets the NetBIOS scope
+
+ gggguuuueeeesssstttt
+ don't prompt for a password
+
+ rrrroooo mount read-only
+
+ rrrrwwww mount read-write
+
+ iiiioooocccchhhhaaaarrrrsssseeeetttt====<<<<aaaarrrrgggg>>>>
+ sets the charset used by the Linux side for codepage to
+ charset translations (NLS). Argument should be the name
+ of a charset, like iso8859-1. (Note: only kernel 2.4.0
+ or later)
+
+ ccccooooddddeeeeppppaaaaggggeeee====<<<<aaaarrrrgggg>>>>
+ sets the codepage the server uses. See the iocharset
+ option. Example value cp850. (Note: only kernel 2.4.0
+ or later)
+
+ ttttttttllll====<<<<aaaarrrrgggg>>>>
+ how long a directory listing is cached in milliseconds
+ (also affects visibility of file size and date
+ changes). A higher value means that changes on the
+ server take longer to be noticed but it can give better
+ performance on large directories, especially over long
+ distances. Default is 1000ms but something like 10000ms
+ (10 seconds) is probably more reasonable in many cases.
+ (Note: only kernel 2.4.2 or later)
+
+ EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT VVVVAAAARRRRIIIIAAAABBBBLLLLEEEESSSS
+ The variable UUUUSSSSEEEERRRR may contain the username of the person
+ using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords. The variable can be used to set both username and
+ password by using the format username%password.
+
+ The variable PPPPAAAASSSSSSSSWWWWDDDD may contain the password of the person
+ using the client. This information is used only if the
+ protocol level is high enough to support session-level
+ passwords.
+
+ The variable PPPPAAAASSSSSSSSWWWWDDDD____FFFFIIIILLLLEEEE may contain the pathname of a file
+ to read the password from. A single line of input is read
+ and used as the password.
+
+ BBBBUUUUGGGGSSSS
+
+
+
+ PPPPaaaaggggeeee 3333 ((((pppprrrriiiinnnntttteeeedddd 1111////7777////111100003333))))
+
+
+
+
+
+
+ SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBMMMMOOOOUUUUNNNNTTTT((((8888))))
+
+
+
+ Passwords and other options containing , can not be handled.
+ For passwords an alternative way of passing them is in a
+ credentials file or in the PASSWD environment.
+
+ The credentials file does not handle usernames or passwords
+ with leading space.
+
+ One smbfs bug is important enough to mention here, even if
+ it is a bit misplaced:
+
+ o+ Mounts sometimes stop working. This is usually caused by
+ smbmount terminating. Since smbfs needs smbmount to
+ reconnect when the server disconnects, the mount will
+ eventually go dead. An umount/mount normally fixes this.
+ At least 2 ways to trigger this bug are known.
+
+ Note that the typical response to a bug report is suggestion
+ to try the latest version first. So please try doing that
+ first, and always include which versions you use of relevant
+ software when reporting bugs (minimum: samba, kernel,
+ distribution)
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ Documentation/filesystems/smbfs.txt in the linux kernel
+ source tree may contain additional options and information.
+
+ FreeBSD also has a smbfs, but it is not related to smbmount
+
+ For Solaris, HP-UX and others you may want to look at
+ ssssmmmmbbbbsssshhhh((((1111)))) or at other solutions, such as sharity or perhaps
+ replacing the SMB server with a NFS server.
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ Volker Lendecke, Andrew Tridgell, Michael H. Warfield and
+ others.
+
+ The current maintainer of smbfs and the userspace tools
+ ssssmmmmbbbbmmmmoooouuuunnnntttt, ssssmmmmbbbbuuuummmmoooouuuunnnntttt, and ssssmmmmbbbbmmmmnnnntttt is Urban Widmark
+ <URL:mailto:urban@teststation.com>. The SAMBA Mailing list
+ <URL:mailto:samba@samba.org> is the preferred place to ask
+ questions regarding these programs.
+
+ The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/smbpasswd.8 b/packaging/Caldera/OpenServer/man/cat.8/smbpasswd.8
new file mode 100755
index 00000000000..5b86144432c
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/smbpasswd.8
@@ -0,0 +1,462 @@
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbpasswd - change a user's SMB password
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ When run by root:
+
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd [ ooooppppttttiiiioooonnnnssss ] [ uuuusssseeeerrrrnnnnaaaammmmeeee ] [ ppppaaaasssssssswwwwoooorrrrdddd ]
+
+ otherwise:
+
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd [ ooooppppttttiiiioooonnnnssss ] [ ppppaaaasssssssswwwwoooorrrrdddd ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ The smbpasswd program has several different functions,
+ depending on whether it is run by the rrrrooooooootttt user or not. When
+ run as a normal user it allows the user to change the
+ password used for their SMB sessions on any machines that
+ store SMB passwords.
+
+ By default (when run with no arguments) it will attempt to
+ change the current user's SMB password on the local machine.
+ This is similar to the way the ppppaaaasssssssswwwwdddd((((1111)))) program works.
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd differs from how the passwd program works however
+ in that it is not sssseeeettttuuuuiiiidddd rrrrooooooootttt but works in a client-server
+ mode and communicates with a locally running ssssmmmmbbbbdddd((((8888)))). As a
+ consequence in order for this to succeed the smbd daemon
+ must be running on the local machine. On a UNIX machine the
+ encrypted SMB passwords are usually stored in the
+ _s_m_b_p_a_s_s_w_d(_5) file.
+
+ When run by an ordinary user with no options. smbpasswd will
+ prompt them for their old SMB password and then ask them for
+ their new password twice, to ensure that the new password
+ was typed correctly. No passwords will be echoed on the
+ screen whilst being typed. If you have a blank SMB password
+ (specified by the string "NO PASSWORD" in the smbpasswd
+ file) then just press the <Enter> key when asked for your
+ old password.
+
+ smbpasswd can also be used by a normal user to change their
+ SMB password on remote machines, such as Windows NT Primary
+ Domain Controllers. See the (-r) and -U options below.
+
+ When run by root, smbpasswd allows new users to be added and
+ deleted in the smbpasswd file, as well as allows changes to
+ the attributes of the user in this file to be made. When run
+ by root, ssssmmmmbbbbppppaaaasssssssswwwwdddd accesses the local smbpasswd file
+ directly, thus enabling changes to be made even if smbd is
+ not running.
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----LLLL Run the smbpasswd command in local mode. This allows a
+ non-root user to specify the root-only options. This is
+ used mostly in test environments where a non-root user
+ needs to make changes to the local _s_m_b_p_a_s_s_w_d file. The
+ _s_m_b_p_a_s_s_w_d file must have read/write permissions for the
+ user running the command.
+
+ ----hhhh This option prints the help string for ssssmmmmbbbbppppaaaasssssssswwwwdddd.
+
+ ----cccc ssssmmmmbbbb....ccccoooonnnnffff ffffiiiilllleeee
+ This option specifies that the configuration file
+ specified should be used instead of the default value
+ specified at compile time.
+
+ ----DDDD ddddeeeebbbbuuuugggglllleeeevvvveeeellll
+ _d_e_b_u_g_l_e_v_e_l is an integer from 0 to 10. The default
+ value if this parameter is not specified is zero.
+
+ The higher this value, the more detail will be logged
+ to the log files about the activities of smbpasswd. At
+ level 0, only critical errors and serious warnings will
+ be logged.
+
+ Levels above 1 will generate considerable amounts of
+ log data, and should only be used when investigating a
+ problem. Levels above 3 are designed for use only by
+ developers and generate HUGE amounts of log data, most
+ of which is extremely cryptic.
+
+ ----rrrr rrrreeeemmmmooootttteeee mmmmaaaacccchhhhiiiinnnneeee nnnnaaaammmmeeee
+ This option allows a user to specify what machine they
+ wish to change their password on. Without this
+ parameter smbpasswd defaults to the local host. The
+ _r_e_m_o_t_e _m_a_c_h_i_n_e _n_a_m_e is the NetBIOS name of the SMB/CIFS
+ server to contact to attempt the password change. This
+ name is resolved into an IP address using the standard
+ name resolution mechanism in all programs of the Samba
+ suite. See the -_R _n_a_m_e _r_e_s_o_l_v_e _o_r_d_e_r parameter for
+ details on changing this resolving mechanism.
+
+ The username whose password is changed is that of the
+ current UNIX logged on user. See the -_U _u_s_e_r_n_a_m_e
+ parameter for details on changing the password for a
+ different username.
+
+ Note that if changing a Windows NT Domain password the
+ remote machine specified must be the Primary Domain
+ Controller for the domain (Backup Domain Controllers
+ only have a read-only copy of the user account database
+ and will not allow the password change).
+
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ NNNNooootttteeee that Windows 95/98 do not have a real password
+ database so it is not possible to change passwords
+ specifying a Win95/98 machine as remote machine target.
+
+ ----ssss This option causes smbpasswd to be silent (i.e. not
+ issue prompts) and to read its old and new passwords
+ from standard input, rather than from /_d_e_v/_t_t_y (like
+ the ppppaaaasssssssswwwwdddd((((1111)))) program does). This option is to aid
+ people writing scripts to drive smbpasswd
+
+ ----SSSS This option causes ssssmmmmbbbbppppaaaasssssssswwwwdddd to query a domain
+ controller of the domain specified by the workgroup
+ parameter in _s_m_b._c_o_n_f and store the domain SID in the
+ _s_e_c_r_e_t_s._t_d_b file as its own machine SID. This is only
+ useful when configuring a Samba PDC and Samba BDC, or
+ when migrating from a Windows PDC to a Samba PDC.
+
+ The -_r options can be used as well to indicate a
+ specific domain controller which should be contacted.
+ In this case, the domain SID obtained is the one for
+ the domain to which the remote machine belongs.
+
+ ----tttt This option is used to force smbpasswd to change the
+ current password assigned to the machine trust account
+ when operating in domain security mode. This is really
+ meant to be used on systems that only run wwwwiiiinnnnbbbbiiiinnnndddddddd
+ Under server installations, ssssmmmmbbbbdddd handle the password
+ updates automatically.
+
+ ----UUUU uuuusssseeeerrrrnnnnaaaammmmeeee[[[[%%%%ppppaaaassssssss]]]]
+ This option may only be used in conjunction with the -_r
+ option. When changing a password on a remote machine it
+ allows the user to specify the user name on that
+ machine whose password will be changed. It is present
+ to allow users who have different user names on
+ different systems to change these passwords. The
+ optional %pass may be used to specify to old password.
+
+ In particular, this parameter specifies the username
+ used to create the machine account when invoked with -j
+
+ NNNNOOOOTTTTEEEE::::
+ TTTThhhheeee ffffoooolllllllloooowwwwiiiinnnngggg ooooppppttttiiiioooonnnnssss aaaarrrreeee aaaavvvvaaaaiiiillllaaaabbbblllleeee oooonnnnllllyyyy wwwwhhhheeeennnn tttthhhheeee
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd ccccoooommmmmmmmaaaannnndddd iiiissss rrrruuuunnnn aaaassss rrrrooooooootttt oooorrrr iiiinnnn llllooooccccaaaallll mmmmooooddddeeee....
+
+ ----aaaa This option specifies that the username following
+ should be added to the local smbpasswd file, with the
+ new password typed. This option is ignored if the
+ username specified already exists in the smbpasswd file
+ and it is treated like a regular change password
+ command. Note that the user to be added must already
+ exist in the system password file (usually /_e_t_c/_p_a_s_s_w_d)
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ else the request to add the user will fail.
+
+ ----dddd This option specifies that the username following
+ should be disabled in the local smbpasswd file. This is
+ done by writing a 'D' flag into the account control
+ space in the smbpasswd file. Once this is done all
+ attempts to authenticate via SMB using this username
+ will fail.
+
+ If the smbpasswd file is in the 'old' format (pre-Samba
+ 2.0 format) there is no space in the user's password
+ entry to write this information and so the user is
+ disabled by writing 'X' characters into the password
+ space in the smbpasswd file. See ssssmmmmbbbbppppaaaasssssssswwwwdddd((((5555)))) for
+ details on the 'old' and new password file formats.
+
+ ----eeee This option specifies that the username following
+ should be enabled in the local smbpasswd file, if the
+ account was previously disabled. If the account was not
+ disabled this option has no effect. Once the account is
+ enabled then the user will be able to authenticate via
+ SMB once again.
+
+ If the smbpasswd file is in the 'old' format, then
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd will prompt for a new password for this user,
+ otherwise the account will be enabled by removing the
+ 'D' flag from account control space in the _s_m_b_p_a_s_s_w_d
+ file. See ssssmmmmbbbbppppaaaasssssssswwwwdddd ((((5555)))) for details on the 'old' and
+ new password file formats.
+
+ ----mmmm This option tells smbpasswd that the account being
+ changed is a MACHINE account. Currently this is used
+ when Samba is being used as an NT Primary Domain
+ Controller.
+
+ ----nnnn This option specifies that the username following
+ should have their password set to null (i.e. a blank
+ password) in the local smbpasswd file. This is done by
+ writing the string "NO PASSWORD" as the first part of
+ the first password stored in the smbpasswd file.
+
+ Note that to allow users to logon to a Samba server
+ once the password has been set to "NO PASSWORD" in the
+ smbpasswd file the administrator must set the following
+ parameter in the [global] section of the _s_m_b._c_o_n_f file
+ :
+
+ nnnnuuuullllllll ppppaaaasssssssswwwwoooorrrrddddssss ==== yyyyeeeessss
+
+ ----wwww ppppaaaasssssssswwwwoooorrrrdddd
+ This parameter is only available is Samba has been
+ configured to use the experimental --------wwwwiiiitttthhhh----llllddddaaaappppssssaaaammmm
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ option. The -_w switch is used to specify the password
+ to be used with the _l_d_a_p _a_d_m_i_n _d_n Note that the
+ password is stored in the _p_r_i_v_a_t_e/_s_e_c_r_e_t_s._t_d_b and is
+ keyed off of the admin's DN. This means that if the
+ value of _l_d_a_p _a_d_m_i_n _d_n ever changes, the password will
+ need to be manually updated as well.
+
+ ----xxxx This option specifies that the username following
+ should be deleted from the local smbpasswd file.
+
+ ----jjjj DDDDOOOOMMMMAAAAIIIINNNN
+ This option is used to add a Samba server into a
+ Windows NT Domain, as a Domain member capable of
+ authenticating user accounts to any Domain Controller
+ in the same way as a Windows NT Server. See the
+ sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn option in the _s_m_b._c_o_n_f(_5) man page.
+
+ This command can work both with and without the -U
+ parameter.
+
+ When invoked with -U, that username (and optional
+ password) are used to contact the PDC (which must be
+ specified with -r) to both create a machine account,
+ and to set a password on it.
+
+ Alternately, if -U is omitted, Samba will contact its
+ PDC and attempt to change the password on a pre-
+ existing account.
+
+ In order to be used in this way, the Administrator for
+ the Windows NT Domain must have used the program
+ "Server Manager for Domains" to add the primary NetBIOS
+ name of the Samba server as a member of the Domain.
+
+ After this has been done, to join the Domain invoke
+ ssssmmmmbbbbppppaaaasssssssswwwwdddd with this parameter. smbpasswd will then look
+ up the Primary Domain Controller for the Domain (found
+ in the _s_m_b._c_o_n_f file in the parameter _p_a_s_s_w_o_r_d _s_e_r_v_e_r
+ and change the machine account password used to create
+ the secure Domain communication.
+
+ Either way, this password is then stored by smbpasswd
+ in a TDB, writeable only by root, called _s_e_c_r_e_t_s._t_d_b
+
+ Once this operation has been performed the _s_m_b._c_o_n_f
+ file may be updated to set the sssseeeeccccuuuurrrriiiittttyyyy ==== ddddoooommmmaaaaiiiinnnn
+ option and all future logins to the Samba server will
+ be authenticated to the Windows NT PDC.
+
+ Note that even though the authentication is being done
+ to the PDC all users accessing the Samba server must
+ still have a valid UNIX account on that machine. The
+
+
+
+ Page 5 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ wwwwiiiinnnnbbbbiiiinnnndddddddd((((8888)))) daemon can be used to create UNIX accounts
+ for NT users.
+
+ ----RRRR nnnnaaaammmmeeee rrrreeeessssoooollllvvvveeee oooorrrrddddeeeerrrr
+ This option allows the user of smbpasswd to determine
+ what name resolution services to use when looking up
+ the NetBIOS name of the host being connected to.
+
+ The options are :"lmhosts", "host", "wins" and "bcast".
+ They cause names to be resolved as follows :
+
+ o+ lmhosts : Lookup an IP address in the Samba lmhosts
+ file. If the line in lmhosts has no name type
+ attached to the NetBIOS name (see the lmhosts(5) for
+ details) then any name type matches for lookup.
+
+ o+ host : Do a standard host name to IP address
+ resolution, using the system /_e_t_c/_h_o_s_t_s , NIS, or DNS
+ lookups. This method of name resolution is operating
+ system dependent. For instance, on IRIX or Solaris
+ this may be controlled by the /_e_t_c/_n_s_s_w_i_t_c_h._c_o_n_f
+ file). Note that this method is only used if the
+ NetBIOS name type being queried is the 0x20 (server)
+ name type, otherwise it is ignored.
+
+ o+ wins : Query a name with the IP address listed in the
+ _w_i_n_s _s_e_r_v_e_r parameter. If no WINS server has been
+ specified this method will be ignored.
+
+ o+ bcast : Do a broadcast on each of the known local
+ interfaces listed in the _i_n_t_e_r_f_a_c_e_s parameter. This
+ is the least reliable of the name resolution methods
+ as it depends on the target host being on a locally
+ connected subnet.
+
+ The default order is llllmmmmhhhhoooossssttttssss,,,, hhhhoooosssstttt,,,, wwwwiiiinnnnssss,,,, bbbbccccaaaasssstttt and without
+ this parameter or any entry in the _s_m_b._c_o_n_f file the name
+ resolution methods will be attempted in this order.
+
+ uuuusssseeeerrrrnnnnaaaammmmeeee
+ This specifies the username for all of the rrrrooooooootttt oooonnnnllllyyyy
+ options to operate on. Only root can specify this
+ parameter as only root has the permission needed to
+ modify attributes directly in the local smbpasswd file.
+
+ ppppaaaasssssssswwwwoooorrrrdddd
+ This specifies the new password. If this parameter is
+ specified you will not be prompted for the new
+ password.
+
+ NNNNOOOOTTTTEEEESSSS
+ Since ssssmmmmbbbbppppaaaasssssssswwwwdddd works in client-server mode communicating
+
+
+
+ Page 6 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBPPPPAAAASSSSSSSSWWWWDDDD((((8888))))
+
+
+
+ with a local smbd for a non-root user then the smbd daemon
+ must be running for this to work. A common problem is to add
+ a restriction to the hosts that may access the ssssmmmmbbbbdddd running
+ on the local machine by specifying a _a_l_l_o_w _h_o_s_t_s or _d_e_n_y
+ _h_o_s_t_s entry in the _s_m_b._c_o_n_f file and neglecting to allow
+ "localhost" access to the smbd.
+
+ In addition, the smbpasswd command is only useful if Samba
+ has been set up to use encrypted passwords. See the file
+ _E_N_C_R_Y_P_T_I_O_N._t_x_t in the docs directory for details on how to
+ do this.
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ _s_m_b_p_a_s_s_w_d(_5) samba(7)
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 7 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/smbumount.8 b/packaging/Caldera/OpenServer/man/cat.8/smbumount.8
new file mode 100755
index 00000000000..dff37301ba9
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/smbumount.8
@@ -0,0 +1,66 @@
+
+
+
+ SSSSMMMMBBBBUUUUMMMMOOOOUUUUNNNNTTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSMMMMBBBBUUUUMMMMOOOOUUUUNNNNTTTT((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ smbumount - smbfs umount for normal users
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ ssssmmmmbbbbuuuummmmoooouuuunnnntttt mmmmoooouuuunnnntttt----ppppooooiiiinnnntttt
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ With this program, normal users can unmount smb-filesystems,
+ provided that it is suid root. ssssmmmmbbbbuuuummmmoooouuuunnnntttt has been written to
+ give normal Linux users more control over their resources.
+ It is safe to install this program suid root, because only
+ the user who has mounted a filesystem is allowed to unmount
+ it again. For root it is not necessary to use smbumount. The
+ normal umount program works perfectly well, but it would
+ certainly be problematic to make umount setuid root.
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ mmmmoooouuuunnnntttt----ppppooooiiiinnnntttt
+ The directory to unmount.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ ssssmmmmbbbbmmmmoooouuuunnnntttt((((8888))))
+
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ Volker Lendecke, Andrew Tridgell, Michael H. Warfield and
+ others.
+
+ The current maintainer of smbfs and the userspace tools
+ ssssmmmmbbbbmmmmoooouuuunnnntttt, ssssmmmmbbbbuuuummmmoooouuuunnnntttt, and ssssmmmmbbbbmmmmnnnntttt is Urban Widmark
+ <URL:mailto:urban@teststation.com>. The SAMBA Mailing list
+ <URL:mailto:samba@samba.org> is the preferred place to ask
+ questions regarding these programs.
+
+ The conversion of this manpage for Samba 2.2 was performed
+ by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/man/cat.8/swat.8 b/packaging/Caldera/OpenServer/man/cat.8/swat.8
new file mode 100755
index 00000000000..36ef19b1765
--- /dev/null
+++ b/packaging/Caldera/OpenServer/man/cat.8/swat.8
@@ -0,0 +1,264 @@
+
+
+
+ SSSSWWWWAAAATTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSWWWWAAAATTTT((((8888))))
+
+
+
+ NNNNAAAAMMMMEEEE
+ swat - Samba Web Administration Tool
+
+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+ sssswwwwaaaatttt [ ----ssss <<<<ssssmmmmbbbb ccccoooonnnnffffiiiigggg ffffiiiilllleeee>>>> ] [ ----aaaa ]
+
+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+ This tool is part of the Samba suite.
+
+ sssswwwwaaaatttt allows a Samba administrator to configure the complex
+ _s_m_b._c_o_n_f(_5) file via a Web browser. In addition, a sssswwwwaaaatttt
+ configuration page has help links to all the configurable
+ options in the _s_m_b._c_o_n_f file allowing an administrator to
+ easily look up the effects of any change.
+
+ sssswwwwaaaatttt is run from iiiinnnneeeettttdddd
+
+ OOOOPPPPTTTTIIIIOOOONNNNSSSS
+ ----ssss ssssmmmmbbbb ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn ffffiiiilllleeee
+ The default configuration file path is determined at
+ compile time. The file specified contains the
+ configuration details required by the ssssmmmmbbbbdddd server. This
+ is the file that sssswwwwaaaatttt will modify. The information in
+ this file includes server-specific information such as
+ what printcap file to use, as well as descriptions of
+ all the services that the server is to provide. See
+ _s_m_b._c_o_n_f for more information.
+
+ ----aaaa This option disables authentication and puts sssswwwwaaaatttt in
+ demo mode. In that mode anyone will be able to modify
+ the _s_m_b._c_o_n_f file.
+
+ DDDDoooo NNNNOOOOTTTT eeeennnnaaaabbbblllleeee tttthhhhiiiissss ooooppppttttiiiioooonnnn oooonnnn aaaa pppprrrroooodddduuuuccccttttiiiioooonnnn sssseeeerrrrvvvveeeerrrr....
+
+ IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ After you compile SWAT you need to run mmmmaaaakkkkeeee iiiinnnnssssttttaaaallllllll to
+ install the sssswwwwaaaatttt binary and the various help files and
+ images. A default install would put these in:
+
+ o+ /usr/local/samba/bin/swat
+
+ o+ /usr/local/samba/swat/images/*
+
+ o+ /usr/local/samba/swat/help/*
+
+ IIIINNNNEEEETTTTDDDD IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ You need to edit your /_e_t_c/_i_n_e_t_d._c_o_n_f and /_e_t_c/_s_e_r_v_i_c_e_s to
+ enable SWAT to be launched via iiiinnnneeeettttdddd.
+
+ In /_e_t_c/_s_e_r_v_i_c_e_s you need to add a line like this:
+
+ sssswwwwaaaatttt 999900001111////ttttccccpppp
+
+
+
+ Page 1 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSWWWWAAAATTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSWWWWAAAATTTT((((8888))))
+
+
+
+ Note for NIS/YP users - you may need to rebuild the NIS
+ service maps rather than alter your local /_e_t_c/_s_e_r_v_i_c_e_s
+ file.
+
+ the choice of port number isn't really important except that
+ it should be less than 1024 and not currently used (using a
+ number above 1024 presents an obscure security hole
+ depending on the implementation details of your iiiinnnneeeettttdddd
+ daemon).
+
+ In /_e_t_c/_i_n_e_t_d._c_o_n_f you should add a line like this:
+
+ sssswwwwaaaatttt ssssttttrrrreeeeaaaammmm ttttccccpppp nnnnoooowwwwaaaaiiiitttt....444400000000 rrrrooooooootttt ////uuuussssrrrr////llllooooccccaaaallll////ssssaaaammmmbbbbaaaa////bbbbiiiinnnn////sssswwwwaaaatttt
+ sssswwwwaaaatttt
+
+ One you have edited /_e_t_c/_s_e_r_v_i_c_e_s and /_e_t_c/_i_n_e_t_d._c_o_n_f you
+ need to send a HUP signal to inetd. To do this use kkkkiiiillllllll ----1111
+ PPPPIIIIDDDD where PID is the process ID of the inetd daemon.
+
+ XXXXIIIINNNNEEEETTTTDDDD IIIINNNNSSSSTTTTAAAALLLLLLLLAAAATTTTIIIIOOOONNNN
+ Newer Linux systems ship with a more secure implementation
+ of the inetd meta-daemon. The xxxxiiiinnnneeeettttdddd daemon can read
+ configuration inf9ormation from a single file (i.e.
+ /_e_t_c/_x_i_n_e_t_d._c_o_n_f) or from a collection of service control
+ files in the _x_i_n_e_t_d._d/ directory. These directions assume
+ the latter configuration.
+
+ The following file should be created as /_e_t_c/_x_i_e_n_t_d._d/_s_w_a_t.
+ It is then be neccessary cause the meta-daemon to reload its
+ configuration files. Refer to the xinetd man page for
+ details on how to accomplish this.
+
+ ## /etc/xinetd.d/swat
+ service swat
+ {
+ port = 901
+ socket_type = stream
+ wait = no
+ only_from = localhost
+ user = root
+ server = /usr/local/samba/bin/swat
+ log_on_failure += USERID
+ disable = No
+ }
+
+
+ LLLLAAAAUUUUNNNNCCCCHHHHIIIINNNNGGGG
+ To launch SWAT just run your favorite web browser and point
+ it at "http://localhost:901/".
+
+ Note that you can attach to SWAT from any IP connected
+ machine but connecting from a remote machine leaves your
+
+
+
+ Page 2 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSWWWWAAAATTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSWWWWAAAATTTT((((8888))))
+
+
+
+ connection open to password sniffing as passwords will be
+ sent in the clear over the wire.
+
+ TTTTRRRROOOOUUUUBBBBLLLLEEEESSSSHHHHOOOOOOOOTTTTIIIINNNNGGGG
+ One of the common causes of difficulty when installing Samba
+ and SWAT is the existsnece of some type of firewall or port
+ filtering software on the Samba server. Make sure that the
+ appropriate ports outlined in this man page are available on
+ the server and are not currently being blocked by some type
+ of security software such as iptables or "port sentry". For
+ more troubleshooting information, refer to the additional
+ documentation included in the Samba distribution.
+
+ FFFFIIIILLLLEEEESSSS
+ /_e_t_c/_i_n_e_t_d._c_o_n_f
+ This file must contain suitable startup information for
+ the meta-daemon.
+
+ /_e_t_c/_x_i_n_e_t_d._d/_s_w_a_t
+ This file must contain suitable startup information for
+ the xxxxiiiinnnneeeettttdddd meta-daemon.
+
+ /_e_t_c/_s_e_r_v_i_c_e_s
+ This file must contain a mapping of service name (e.g.,
+ swat) to service port (e.g., 901) and protocol type
+ (e.g., tcp).
+
+ /_u_s_r/_l_o_c_a_l/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f
+ This is the default location of the _s_m_b._c_o_n_f(_5) server
+ configuration file that swat edits. Other common places
+ that systems install this file are
+ /_u_s_r/_s_a_m_b_a/_l_i_b/_s_m_b._c_o_n_f and /_e_t_c/_s_m_b._c_o_n_f . This file
+ describes all the services the server is to make
+ available to clients.
+
+ WWWWAAAARRRRNNNNIIIINNNNGGGGSSSS
+ sssswwwwaaaatttt will rewrite your _s_m_b._c_o_n_f file. It will rearrange the
+ entries and delete all comments, _i_n_c_l_u_d_e= and _c_o_p_y="
+ options. If you have a carefully crafted _s_m_b._c_o_n_f then back
+ it up or don't use swat!
+
+ VVVVEEEERRRRSSSSIIIIOOOONNNN
+ This man page is correct for version 2.2 of the Samba suite.
+
+ SSSSEEEEEEEE AAAALLLLSSSSOOOO
+ iiiinnnneeeettttdddd((((5555)))), ssssmmmmbbbbdddd((((8888)))) smb.conf(5) xxxxiiiinnnneeeettttdddd((((8888))))
+
+ AAAAUUUUTTTTHHHHOOOORRRR
+ The original Samba software and related utilities were
+ created by Andrew Tridgell. Samba is now developed by the
+ Samba Team as an Open Source project similar to the way the
+ Linux kernel is developed.
+
+
+
+ Page 3 (printed 1/7/103)
+
+
+
+
+
+
+ SSSSWWWWAAAATTTT((((8888)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ((((00003333 SSSSeeeepppptttteeeemmmmbbbbeeeerrrr 2222000000002222)))) SSSSWWWWAAAATTTT((((8888))))
+
+
+
+ The original Samba man pages were written by Karl Auer. The
+ man page sources were converted to YODL format (another
+ excellent piece of Open Source software, available at
+ ftp://ftp.icce.rug.nl/pub/unix/
+ <URL:ftp://ftp.icce.rug.nl/pub/unix/>) and updated for the
+ Samba 2.0 release by Jeremy Allison. The conversion to
+ DocBook for Samba 2.2 was done by Gerald Carter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 4 (printed 1/7/103)
+
+
+
diff --git a/packaging/Caldera/OpenServer/osr5config.html b/packaging/Caldera/OpenServer/osr5config.html
new file mode 100755
index 00000000000..cfaa27155c4
--- /dev/null
+++ b/packaging/Caldera/OpenServer/osr5config.html
@@ -0,0 +1,59 @@
+<html>
+<head>
+<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
+<title>Configuring Samba on SCO OpenServer systems</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.48">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article">
+<div class="titlepage">
+<div><h2 class="title">
+<a name="id2744732"></a>Configuring Samba on SCO OpenServer systems</h2></div>
+<hr>
+</div>
+<p>After installing Samba, you must configure and activate it. To
+do so, run the command <b>mkdev samba</b>. When prompted, enter the appropriate information in these categories: </p>
+<div class="variablelist"><dl>
+<dt><span class="term"><i><tt>Workgroup Name/NT-Domain</tt></i></span></dt>
+<dd><p>Default: <tt>MYGROUP</tt>
+</p></dd>
+<dt><span class="term"><i><tt>Machine name</tt></i></span></dt>
+<dd><p>Default: your system's name as reported by the <b>uname -n</b> command,
+ capitalized. For example, <tt>MYSYSTEM</tt>.</p></dd>
+<dt><span class="term"><i><tt>Windows Internet Naming Service (WINS)</tt></i> usage</span></dt>
+<dd>
+<p>Whether your network uses the Windows Internet Naming Service (WINS). The use of WINS is recommended; failure to do so may significantly
+ increase your network traffic. However, some sites are unable to use it
+ because, for example, of security policies.</p>
+<p>If you are using WINS, you will be asked whether your machine is intended
+to be the WINS server for your network. If some other machine will be the
+WINS server, you will be asked for its IP address.</p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>
+<p>A network may
+not have more than one WINS server. If any other machine will be acting as
+the WINS server, your machine cannot do so.</p>
+</div>
+</dd>
+<dt><span class="term"><i><tt>Network interface(s)</tt></i></span></dt>
+<dd><p>The network interface(s) over which will Samba run. For example, <tt>net0</tt>.</p></dd>
+<dt><span class="term"><i><tt>Microsoft
+ Security Domain or Active Directory</tt></i> usage</span></dt>
+<dd>
+<p>Whether your system is being installed into an already-existing Microsoft
+ Security Domain or Active Directory.</p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>If <tt>Yes</tt>, you will be asked for the name of the Primary
+ Domain Controller.</p></li>
+<li><p>
+ If <tt>No</tt>, you will be asked whether <span class="emphasis"><i>your system</i></span> will be
+ the Primary Domain Controller. </p></li>
+</ul></div>
+</dd>
+</dl></div>
+<p>From the answers to these questions, an initial <a href="./smb.conf.5.html" target="_top"><tt>smb.conf</tt></a> file will be
+created that should work in most circumstances. Additional configuration
+should be completed using the <a href="./swat.8.html" target="_top"><b>swat</b></a> utility.</p>
+<p>Once this initial configuration is complete, Samba will automatically be
+launched at boot time.</p>
+</div></body>
+</html>
diff --git a/packaging/Caldera/OpenServer/pkg/Clean b/packaging/Caldera/OpenServer/pkg/Clean
new file mode 100755
index 00000000000..fa68f18118c
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/Clean
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+rm -rf archives sso usr
diff --git a/packaging/Caldera/OpenServer/pkg/Install b/packaging/Caldera/OpenServer/pkg/Install
new file mode 100755
index 00000000000..ef0f61f33e1
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/Install
@@ -0,0 +1 @@
+custom -p SKUNK2000:Samba -i -z `pwd`/archives/FLOPPY
diff --git a/packaging/Caldera/OpenServer/pkg/MakeSSO b/packaging/Caldera/OpenServer/pkg/MakeSSO
new file mode 100755
index 00000000000..538aaf58f77
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/MakeSSO
@@ -0,0 +1,25 @@
+:
+# MakeSSO
+#
+
+rm -rf archives sso
+
+ CDMT_DIR=`pwd`; export CDMT_DIR
+ Samba_DIR=`pwd`; export Samba_DIR
+ cdmtParse
+ if test $? != 0
+ then
+ exit 1
+ fi
+
+ cdmtCompress
+ if test $? != 0
+ then
+ exit 1
+ fi
+
+ cdmtArchive
+ if test $? != 0
+ then
+ exit 1
+ fi
diff --git a/packaging/Caldera/OpenServer/pkg/Packem b/packaging/Caldera/OpenServer/pkg/Packem
new file mode 100755
index 00000000000..a1b67e972d9
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/Packem
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+P=`pwd`
+PKGTAR=`basename $P`-VOLS.tar
+PKGDIST=`basename $P`-dist.tar.gz
+
+DIRS=usr
+[ -d etc ] && DIRS="etc usr"
+cd archives/FLOPPY
+tar cf ../../$PKGTAR VOL*
+cd ../..
+tar cf - $DIRS | /usr/local/bin/gzip -9 > $PKGDIST
+[ -f $PKGTAR ] && rm -rf archives
+[ -f $PKGDIST ] && rm -rf $DIRS
+rm -rf sso
diff --git a/packaging/Caldera/OpenServer/pkg/Remove b/packaging/Caldera/OpenServer/pkg/Remove
new file mode 100755
index 00000000000..ea6102ac38a
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/Remove
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Generic command-line Software Manger (custom) removal from
+# media images. Based on the installation script by Phil Hollenback
+# (philiph@sco.com) and Ron Record (rr@sco.com)
+#
+
+# Set this to be the full pathname to the directory
+# where your media images are:
+VDIR=`pwd`/archives/FLOPPY
+VOLS=$VDIR/VOL.000.000
+
+component=`grep "component" < $VOLS | head -1 | cut -d= -f2 | cut -d: -f1`
+package=`grep "component" < $VOLS | head -1 | cut -d= -f2 | cut -d: -f2`
+
+custom -p $component:$package -r
diff --git a/packaging/Caldera/OpenServer/pkg/cdmt.config b/packaging/Caldera/OpenServer/pkg/cdmt.config
new file mode 100755
index 00000000000..d0eb8cb996a
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cdmt.config
@@ -0,0 +1,36 @@
+MACROS:
+
+Samba_NAME = Samba File and Print Server
+Samba_VER = 2.2.8a
+
+DEFAULT_EXEC_MODE = 0755
+
+DEFAULT_FILE_MODE = 0644
+DEFAULT_FILE_OWNER = bin
+DEFAULT_FILE_GROUP = bin
+
+DEFAULT_DIR_MODE = 0755
+DEFAULT_DIR_OWNER = bin
+DEFAULT_DIR_GROUP = bin
+
+DEFAULT_FIFO_MODE = 0644
+DEFAULT_FIFO_OWNER = bin
+DEFAULT_FIFO_GROUP = bin
+
+DEFAULT_DISTTREEROOT_SHARED = $CDMT_DIR
+DEFAULT_DISTTREEROOT_CLIENT = $CDMT_DIR
+
+CONFIG:
+ removeFiles = FALSE
+ removalPrompt = FALSE
+ archiveMedia = FLOPPY
+ compress = TRUE
+ ssoDir = sso
+
+FLOPPY_MEDIA:
+ device = /dev/rfd0
+ volumeSize = 8000
+ distVersion = $Samba_VER
+ distCode = SCO
+ paperLabel = "Samba"
+
diff --git a/packaging/Caldera/OpenServer/pkg/cntl/ccs b/packaging/Caldera/OpenServer/pkg/cntl/ccs
new file mode 100755
index 00000000000..c5e69e1b167
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cntl/ccs
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Postinstallscript written by Ron Record (rr@sco.com)
+#
+
+scriptname="$0"
+step="$1"
+keywords="$2"
+pkglist="$3"
+
+# Source in the standard functions library, ccsSetup.sh
+. ccsSetup.sh
+
+PKG_DIR=${SSO_SHARED_ROOT}/cntl/packages
+
+# call ccs in subsidiary packages with same arguments we were called with
+pkgCodes=`getPackageCode $pkglist`
+returnCode=$OK
+for pkg in $pkgCodes; do
+ pkgscript=${PKG_DIR}/${pkg}/ccs
+ if [ -f "$pkgscript" ]; then
+ ${pkgscript} "${step}" "${keywords}" "${pkglist}"
+
+ # exit with the most severe exit code of subsidiary package scripts
+ case "$?" in
+ $FAIL) returnCode=$FAIL ;;
+ $WARN) [ "$returnCode" -eq "$OK" ] && returnCode=$WARN ;;
+ esac
+ fi
+done
+
+exit $returnCode
+
diff --git a/packaging/Caldera/OpenServer/pkg/cntl/cqs b/packaging/Caldera/OpenServer/pkg/cntl/cqs
new file mode 100755
index 00000000000..fec327a298d
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cntl/cqs
@@ -0,0 +1,111 @@
+#!/ibin/sh
+#
+# The component query script for the Samba component
+#
+# %Z% %M% %I% %E% %Q%
+#
+# input:
+# $1 - keyword list (e.g. "UPGRADE OLD_CUSTOM_UPGRADE")
+# $2 - package list (e.g. "Samba:<component>:<package> )
+#
+
+# Save input arguments
+#
+keywords=$1
+pkgList=$2
+
+# Source in the standard functions library
+#
+. ccsSetup.sh
+
+# Local Variables
+#
+installType=FRESH
+
+# set custom install mode
+customMode=LAYERED
+[ "$IQM_FILE" ] && {
+ # Invoking custom from the IQM. IQM output will be stored
+ # in $IQM_FILE.
+ customMode="IQM"
+}
+
+# Local Functions
+
+##############################################################################
+#
+# If called with an argument indicating failure, remove any possible saved
+# configuration info. Exit with arg passed to this function.
+#
+cleanup()
+{
+ trap '' 1 2 3 15
+ exit $1
+}
+
+################################################################################
+#
+# We are doing a SSO -> SSO upgrade.
+#
+Save_SSO_Upgrade_Config()
+{
+ if [ -f /etc/samba.d/smbusers ]; then
+ ex_cmd cp -f /etc/samba.d/smbusers $CCS_PERSISTENT_STORAGE/smbusers
+ fi
+ if [ -f /etc/samba.d/smbpasswd ]; then
+ ex_cmd cp -f /etc/samba.d/smbpasswd ${CCS_PERSISTENT_STORAGE}/smbpasswd
+ fi
+ if [ -f /etc/samba.d/smb.conf ]; then
+ ex_cmd cp -f /etc/samba.d/smb.conf ${CCS_PERSISTENT_STORAGE}/smb.conf
+ fi
+ if [ -f /etc/samba.d/lmhosts ]; then
+ ex_cmd cp -f /etc/samba.d/lmhosts ${CCS_PERSISTENT_STORAGE}/lmhosts
+ fi
+ if [ -f /etc/samba.d/printers.def ]; then
+ ex_cmd cp -f /etc/samba.d/printers.def \
+ ${CCS_PERSISTENT_STORAGE}/printers.def
+ fi
+
+ return 0
+}
+
+################################################################################
+# main Main MAIN
+#
+trap "cleanup $FAIL" 1 2 3 15
+
+# Parse keyword list to determine how custom was invoked, the installation type,
+# whether we running on the target CPU, and finally if we have access to
+# the target's root filesystem.
+#
+for k in $keywords
+do
+ case $k in
+ "UPGRADE")
+ # SSO -> SSO upgrade
+ #
+ installType="SSO_UPGRADE"
+ ;;
+
+ "OLD_CUSTOM_UPGRADE")
+ # OLD_CUSTOM -> SSO upgrade
+ #
+ installType="OLD_UPGRADE"
+ ;;
+ esac
+done
+
+case "$installType" in
+"FRESH")
+ # No previous version of component on the system. Perform a
+ # fresh install.
+ ;;
+
+"SSO_UPGRADE")
+ # Existing SSO component upgraded to newer SSO version.
+ #
+ Save_SSO_Upgrade_Config
+ ;;
+esac
+
+cleanup $OK
diff --git a/packaging/Caldera/OpenServer/pkg/cntl/packages/Samba/ccs b/packaging/Caldera/OpenServer/pkg/cntl/packages/Samba/ccs
new file mode 100755
index 00000000000..b1286da037c
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cntl/packages/Samba/ccs
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+scriptname="$0"
+step="$1"
+keywords="$2"
+pkglist="$3"
+
+# Source in the standard functions library, ccsSetup.sh
+. ccsSetup.sh
+
+ccs_return_value=0
+
+SPOOL=/var/spool/samba
+PREFIX=/usr/lib/samba
+
+#
+# Build the codepages
+#
+PostExport()
+{
+ # restore preserved configuration files
+ if [ "${upgrade}" ]; then
+ for file in smb.conf smbusers smbpasswd lmhosts printers.def; do
+ ex_cmd cp -f ${CCS_PERSISTENT_STORAGE}/$file /etc/samba.d/$file
+ done
+ fi
+
+ if [ ! -d /etc/samba.d/codepages ]; then
+ mkdir /etc/samba.d/codepages
+ fi
+
+ for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+ do
+ ${PREFIX}/bin/make_smbcodepage c $i \
+ ${PREFIX}/lib/codepages/src/codepage_def.$i \
+ /etc/samba.d/codepages/codepage.$i
+ done
+ for i in 437 737 850 852 861 866 932 936 949 950 \
+ ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+ do
+ ${PREFIX}/bin/make_unicodemap $i \
+ ${PREFIX}/lib/codepages/src/CP$i.TXT \
+ /etc/samba.d/codepages/unicode_map.$i
+ done
+}
+
+DisableStop()
+{
+ /etc/init.d/samba disable > /dev/null 2>&1
+ /etc/init.d/samba stop > /dev/null 2>&1
+}
+
+#
+# Remove the spool directory and codepages
+#
+PostUnexport()
+{
+ if [ -n "$SPOOL" -a -d "$SPOOL" ]; then
+ rm -rf ${SPOOL}/*
+ fi
+
+ rm -rf /etc/samba.d/codepages
+}
+
+#
+# Is this an upgrade?
+#
+upgrade=
+for word in $keywords
+do
+ case "$word" in
+ OLD_CUSTOM_UPGRADE) upgrade=nonSSOupgrade
+ ;;
+ UPGRADE) upgrade=SSOupgrade
+ ;;
+ esac
+done
+
+case "$step" in
+ POST_EXPORT) PostExport ;;
+ PRE_UNEXPORT) DisableStop ;;
+ POST_UNEXPORT) PostUnexport ;;
+esac
+
+exit $ccs_return_value
diff --git a/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaDOC/ccs b/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaDOC/ccs
new file mode 100755
index 00000000000..0dd9bde4655
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaDOC/ccs
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+scriptname="$0"
+step="$1"
+keywords="$2"
+pkglist="$3"
+
+# Source in the standard functions library, ccsSetup.sh
+. ccsSetup.sh
+
+ccs_return_value=0
+
+PostExport()
+{
+ if [ -x /usr/bin/doctool ]; then
+ /usr/bin/doctool --add NetworkDoc/WinConnect/Samba/.directory >&- 2>&-
+ /usr/bin/doctool --add \
+ NetworkDoc/WinConnect/Samba/samba_help.desktop >&- 2>&-
+ /usr/bin/doctool --add \
+ NetworkDoc/WinConnect/Samba/samba_using.desktop >&- 2>&-
+ /usr/bin/doctool --add \
+ NetworkDoc/WinConnect/Samba/samba_configure.desktop >&- 2>&-
+ fi
+}
+
+PreUnexport()
+{
+ if [ -x /usr/bin/doctool ]; then
+ /usr/bin/doctool --remove \
+ NetworkDoc/WinConnect/Samba/samba_help.desktop >&- 2>&-
+ /usr/bin/doctool --remove \
+ NetworkDoc/WinConnect/Samba/samba_using.desktop >&- 2>&-
+ /usr/bin/doctool --remove \
+ NetworkDoc/WinConnect/Samba/samba_configure.desktop >&- 2>&-
+ /usr/bin/doctool --remove \
+ NetworkDoc/WinConnect/Samba/.directory >&- 2>&-
+ fi
+}
+
+case "$step" in
+ POST_EXPORT) PostExport ;;
+ PRE_UNEXPORT) PreUnexport ;;
+esac
+
+exit $ccs_return_value
+
diff --git a/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaSWAT/ccs b/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaSWAT/ccs
new file mode 100755
index 00000000000..a7260bc80ab
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/cntl/packages/SambaSWAT/ccs
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+scriptname="$0"
+step="$1"
+keywords="$2"
+pkglist="$3"
+
+# Source in the standard functions library, ccsSetup.sh
+. ccsSetup.sh
+
+ccs_return_value=0
+
+SERVICE="swat 598/tcp Samba Web Administration Tool"
+INETD="swat stream tcp nowait root /usr/lib/samba/sbin/swat swat"
+
+PostConfigure()
+{
+ grep -q "^swat[ ]" /etc/services ||
+ echo $SERVICE >> /etc/services
+
+ grep -q "^swat[ ]" /etc/inetd.conf ||
+ echo $INETD >> /etc/inetd.conf
+
+ kill -HUP `cat /etc/inetd.pid`
+}
+
+case "$step" in
+ POST_CONFIGURE) PostConfigure ;;
+esac
+
+exit $ccs_return_value
+
diff --git a/packaging/Caldera/OpenServer/pkg/input/Samba.cmpnt b/packaging/Caldera/OpenServer/pkg/input/Samba.cmpnt
new file mode 100755
index 00000000000..f1db1fde038
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/input/Samba.cmpnt
@@ -0,0 +1,29 @@
+
+COMP:SCO:Samba:
+description = $Samba_NAME
+version = $Samba_VER
+subpackages = Samba
+subpackages = SambaSWAT
+subpackages = SambaDOC
+required = Samba
+dependencies =
+distTreeRootSHARED = $Samba_DIR
+distTreeRootCLIENT = $Samba_DIR
+pkgFiles = $Samba_DIR/input/Samba.pkg
+pkgFiles = $Samba_DIR/input/SambaSWAT.pkg
+pkgFiles = $Samba_DIR/input/SambaDOC.pkg
+
+FILE_DEFAULT:
+mode = $DEFAULT_FILE_MODE
+owner = $DEFAULT_FILE_OWNER
+group = $DEFAULT_FILE_GROUP
+
+DIR_DEFAULT:
+mode = $DEFAULT_DIR_MODE
+owner = $DEFAULT_DIR_OWNER
+group = $DEFAULT_DIR_GROUP
+
+FIFO_DEFAULT:
+mode = $DEFAULT_FIFO_MODE
+owner = $DEFAULT_FIFO_OWNER
+group = $DEFAULT_FIFO_GROUP
diff --git a/packaging/Caldera/OpenServer/pkg/input/Samba.pkg b/packaging/Caldera/OpenServer/pkg/input/Samba.pkg
new file mode 100755
index 00000000000..a7c6d2d771f
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/input/Samba.pkg
@@ -0,0 +1,502 @@
+
+PKG:Control:
+description = "Control package"
+dependencies =
+distTreeRootSHARED = $Samba_DIR
+distTreeRootCLIENT = $Samba_DIR
+
+DIR:Control:SHARED:cntl:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Control:SHARED:cntl/ccs:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Control:SHARED:cntl/cqs:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Control:SHARED:cntl/packages:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Control:SHARED:cntl/packages/Samba:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Control:SHARED:cntl/packages/Samba/ccs:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Control:SHARED:cntl/packages/SambaSWAT:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Control:SHARED:cntl/packages/SambaSWAT/ccs:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Control:SHARED:cntl/packages/SambaDOC:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Control:SHARED:cntl/packages/SambaDOC/ccs:
+mode = 0755
+owner = root
+group = sys
+
+PKG:Samba:
+description = "Samba"
+dependencies =
+distTreeRootSHARED = $Samba_DIR
+distTreeRootCLIENT = $Samba_DIR
+
+DIR:Samba:SHARED:etc:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:SHARED:etc/copyrights:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:etc/copyrights/samba:
+mode = 0644
+owner = root
+group = sys
+exportPath = /etc/copyrights/samba
+
+DIR:Samba:SHARED:etc/init.d:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:etc/init.d/samba:
+mode = 0755
+owner = root
+group = sys
+exportPath = /etc/init.d/samba
+
+DIR:Samba:SHARED:usr:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:SHARED:usr/lib:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:SHARED:usr/lib/mkdev:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:usr/lib/mkdev/samba:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/mkdev/samba
+
+DIR:Samba:SHARED:usr/lib/samba:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:SHARED:usr/lib/samba/bin:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:usr/lib/samba/bin/initconfig:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/initconfig
+
+FILE:Samba:SHARED:usr/lib/samba/bin/nmblookup:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/nmblookup
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbclient:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbclient
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbpasswd:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbpasswd
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbstatus:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbstatus
+
+FILE:Samba:SHARED:usr/lib/samba/bin/testparm:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/testparm
+
+FILE:Samba:SHARED:usr/lib/samba/bin/testprns:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/testprns
+
+FILE:Samba:SHARED:usr/lib/samba/bin/make_smbcodepage:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/make_smbcodepage
+
+FILE:Samba:SHARED:usr/lib/samba/bin/make_unicodemap:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/make_unicodemap
+
+FILE:Samba:SHARED:usr/lib/samba/bin/make_printerdef:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/make_printerdef
+
+FILE:Samba:SHARED:usr/lib/samba/bin/rpcclient:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/rpcclient
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbspool:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbspool
+
+FILE:Samba:SHARED:usr/lib/samba/bin/mksmbpasswd.sh:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/mksmbpasswd.sh
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbtar:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbtar
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbprint:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbprint
+
+FILE:Samba:SHARED:usr/lib/samba/bin/findsmb:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/findsmb
+
+FILE:Samba:SHARED:usr/lib/samba/bin/smbadduser:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/bin/smbadduser
+
+DIR:Samba:SHARED:usr/lib/samba/sbin:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:usr/lib/samba/sbin/smbd:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/sbin/smbd
+
+FILE:Samba:SHARED:usr/lib/samba/sbin/nmbd:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/sbin/nmbd
+
+FILE:Samba:SHARED:usr/lib/samba/sbin/debug2html:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/sbin/debug2html
+
+FILE:Samba:SHARED:usr/lib/samba/sbin/smbfilter:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/sbin/smbfilter
+
+FILE:Samba:SHARED:etc/samba.d/smb.conf.default:
+mode = 0644
+owner = root
+group = sys
+exportPath = /etc/samba.d/smb.conf.default
+
+FILE:Samba:SHARED:etc/samba.d/example.block.smb.conf:
+mode = 0644
+owner = root
+group = sys
+exportPath = /etc/samba.d/example.block.smb.conf
+
+DIR:Samba:SHARED:usr/lib/samba/lib:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:usr/lib/samba/lib/audit.so:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/audit.so
+
+FILE:Samba:SHARED:usr/lib/samba/lib/block.so:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/block.so
+
+FILE:Samba:SHARED:usr/lib/samba/lib/recycle.so:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/recycle.so
+
+FILE:Samba:SHARED:usr/lib/samba/lib/skel.so:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/skel.so
+
+DIR:Samba:SHARED:usr/lib/samba/lib/codepages:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:SHARED:usr/lib/samba/lib/codepages/src:
+mode = 0755
+owner = root
+group = sys
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.437:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.437
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.737:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.737
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.775:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.775
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.850:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.850
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.852:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.852
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.861:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.861
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.866:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.866
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.932:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.932
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.936:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.936
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.949:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.949
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.950:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.950
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/codepage_def.1251:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/codepage_def.1251
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP437.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP437.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP737.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP737.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP850.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP850.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP852.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP852.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP861.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP861.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP866.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP866.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP932.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP932.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP936.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP936.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP949.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP949.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CP950.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CP950.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CPISO8859-1.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CPISO8859-1.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CPISO8859-2.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CPISO8859-2.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CPISO8859-5.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CPISO8859-5.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CPISO8859-7.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CPISO8859-7.TXT
+
+FILE:Samba:SHARED:usr/lib/samba/lib/codepages/src/CPKOI8-R.TXT:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/lib/codepages/src/CPKOI8-R.TXT
+
+FILE:Samba:CLIENT:etc/samba.d/smbusers:
+mode = 0644
+owner = root
+group = sys
+exportPath = /etc/samba.d/smbusers
+
+FILE:Samba:CLIENT:etc/samba.d/lmhosts:
+mode = 0644
+owner = root
+group = sys
+exportPath = /etc/samba.d/lmhosts
+
+DIR:Samba:CLIENT:usr/lib/samba/var:
+mode = 0755
+owner = root
+group = sys
+
+DIR:Samba:CLIENT:usr/lib/samba/var/log:
+mode = 0755
+owner = root
+group = sys
+exportPath = /var/log/samba.d
+exportPath = /usr/lib/samba/var/log
+
+DIR:Samba:CLIENT:usr/lib/samba/var/locks:
+mode = 1777
+owner = root
+group = sys
+exportPath = /var/locks/samba.d
+exportPath = /usr/lib/samba/var/locks
+
+DIR:Samba:CLIENT:usr/lib/samba/var/spool:
+mode = 0755
+owner = root
+group = sys
+exportPath = /var/spool/samba
+exportPath = /usr/lib/samba/var/spool
diff --git a/packaging/Caldera/OpenServer/pkg/input/Samba.prd b/packaging/Caldera/OpenServer/pkg/input/Samba.prd
new file mode 100755
index 00000000000..296a21624bd
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/input/Samba.prd
@@ -0,0 +1,5 @@
+PROD:SCO:Samba:
+description = $Samba_NAME
+version = $Samba_VER
+packages = SCO:Samba::$Samba_VER
+cmpntFiles = Samba.cmpnt
diff --git a/packaging/Caldera/OpenServer/pkg/input/SambaDOC.pkg b/packaging/Caldera/OpenServer/pkg/input/SambaDOC.pkg
new file mode 100755
index 00000000000..2d341b02c28
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/input/SambaDOC.pkg
@@ -0,0 +1,1370 @@
+
+PKG:SambaDOC:
+description = "Samba Documentation"
+dependencies = SCO:Samba:SambaSWAT::.*
+distTreeRootSHARED = $Samba_DIR
+distTreeRootCLIENT = $Samba_DIR
+
+DIR:SambaDOC:SHARED:doc:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:doc/samba.directory:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/meta/doc/NetworkDoc/WinConnect/Samba/.directory
+
+FILE:SambaDOC:SHARED:doc/samba_using.desktop:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/meta/doc/NetworkDoc/WinConnect/Samba/samba_using.desktop
+
+FILE:SambaDOC:SHARED:doc/samba_configure.desktop:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/meta/doc/NetworkDoc/WinConnect/Samba/samba_configure.desktop
+
+FILE:SambaDOC:SHARED:doc/samba_help.desktop:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/meta/doc/NetworkDoc/WinConnect/Samba/samba_help.desktop
+
+FILE:SambaDOC:SHARED:doc/index.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/help/index.html
+
+FILE:SambaDOC:SHARED:doc/osr5config.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/help/osr5config.html
+
+FILE:SambaDOC:SHARED:doc/sco_logo_med.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/help/sco_logo_med.gif
+
+DIR:SambaDOC:SHARED:usr/lib:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaDOC:SHARED:usr/lib/samba:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/man.1:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/findsmb.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/findsmb.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/make_smbcodepage.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/make_smbcodepage.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/make_unicodemap.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/make_unicodemap.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/nmblookup.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/nmblookup.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/rpcclient.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/rpcclient.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/smbcacls.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/smbcacls.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/smbclient.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/smbclient.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/smbcontrol.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/smbcontrol.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/smbstatus.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/smbstatus.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/smbtar.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/smbtar.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/testparm.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/testparm.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/testprns.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/testprns.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.1/wbinfo.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.1/wbinfo.1
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/man.5:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.5/smb.conf.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.5/smb.conf.5
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.5/lmhosts.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.5/lmhosts.5
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.5/smbpasswd.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.5/smbpasswd.5
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/man.7:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.7/samba.7:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.7/samba.7
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/man.8:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/smbd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/smbd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/nmbd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/nmbd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/smbpasswd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/smbpasswd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/swat.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/swat.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/smbmount.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/smbmount.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/smbmnt.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/smbmnt.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/man.8/smbumount.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/man.8/smbumount.8
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/cat.1:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/findsmb.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/findsmb.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/make_smbcodepage.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/make_smbcodepage.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/make_unicodemap.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/make_unicodemap.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/nmblookup.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/nmblookup.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/rpcclient.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/rpcclient.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/smbcacls.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/smbcacls.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/smbclient.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/smbclient.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/smbcontrol.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/smbcontrol.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/smbstatus.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/smbstatus.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/smbtar.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/smbtar.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/testparm.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/testparm.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/testprns.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/testprns.1
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.1/wbinfo.1:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.1/wbinfo.1
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/cat.5:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.5/smb.conf.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.5/smb.conf.5
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.5/lmhosts.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.5/lmhosts.5
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.5/smbpasswd.5:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.5/smbpasswd.5
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/cat.7:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.7/samba.7:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.7/samba.7
+
+DIR:SambaDOC:SHARED:usr/lib/samba/man/cat.8:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/smbd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/smbd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/nmbd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/nmbd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/smbpasswd.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/smbpasswd.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/swat.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/swat.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/smbmount.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/smbmount.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/smbmnt.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/smbmnt.8
+
+FILE:SambaDOC:SHARED:usr/lib/samba/man/cat.8/smbumount.8:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/man/cat.8/smbumount.8
+
+DIR:SambaDOC:SHARED:usr/lib/samba/swat:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaDOC:SHARED:usr/lib/samba/swat/using_samba:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs/index.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/gifs/index.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs/samba.s.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/gifs/samba.s.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs/txthome.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/gifs/txthome.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs/txtnexta.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/gifs/txtnexta.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/gifs/txtpreva.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/gifs/txtpreva.gif
+
+DIR:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0101.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0101.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0102.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0102.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0103.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0103.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0104.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0104.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0105.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0105.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0106.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0106.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0107.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0107.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0108.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0108.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0109.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0109.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0110.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0110.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0111.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0111.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0112.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0112.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0113.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0113.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0114.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0114.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0201.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0201.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0202.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0202.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0203.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0203.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0204.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0204.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0301.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0301.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0302.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0302.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0303.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0303.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0304.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0304.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0305.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0305.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0306.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0306.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0307.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0307.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0308.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0308.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0309.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0309.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0310.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0310.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0311.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0311.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0312.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0312.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0313.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0313.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0314.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0314.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0315.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0315.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0316.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0316.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0317.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0317.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0318.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0318.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0319.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0319.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0320.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0320.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0321.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0321.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0322.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0322.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0323.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0323.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0324.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0324.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0325.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0325.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0326.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0326.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0327.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0327.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0328.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0328.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0401.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0401.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0402.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0402.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0403.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0403.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0404.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0404.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0405.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0405.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0406.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0406.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0407.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0407.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0501.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0501.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0502.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0502.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0503.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0503.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0504.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0504.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0505.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0505.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0506.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0506.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0507.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0507.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0508.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0508.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0601.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0601.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0602.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0602.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0603.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0603.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0604.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0604.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0605.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0605.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0606.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0606.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0701.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0701.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0702.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0702.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0703.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0703.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0704.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0704.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0705.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0705.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0706.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0706.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0707.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0707.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0708.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0708.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0709.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0709.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0801.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0801.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0802.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0802.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0803.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0803.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0804.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0804.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0805.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0805.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0901.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0901.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0902.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0902.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0903.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0903.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0904.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0904.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.0905.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.0905.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.aa01.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.aa01.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.ab01.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.ab01.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/figs/sam.ab02.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/figs/sam.ab02.gif
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appa_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appa_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appa_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appa_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appa_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appa_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appa_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appa_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appa_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appa_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appb_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appb_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appb_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appb_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appb_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appb_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appc_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appc_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appd_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appd_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appe_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appe_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/appf_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/appf_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_06.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_06.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_07.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_07.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch01_08.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch01_08.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch02_06.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch02_06.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch03_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch03_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch03_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch03_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch03_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch03_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_06.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_06.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_07.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_07.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch04_08.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch04_08.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch05_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch05_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch05_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch05_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch05_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch05_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch05_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch05_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch05_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch05_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch06_06.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch06_06.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch07_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch07_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch07_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch07_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch07_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch07_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_04.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_04.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_05.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_05.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_06.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_06.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch08_07.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch08_07.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch09_01.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch09_01.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch09_02.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch09_02.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/ch09_03.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/ch09_03.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/index.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/index.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/inx.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/inx.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/licenseinfo.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/licenseinfo.html
+
+FILE:SambaDOC:SHARED:usr/lib/samba/swat/using_samba/this_edition.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/share/doc/samba/using_samba/this_edition.html
diff --git a/packaging/Caldera/OpenServer/pkg/input/SambaSWAT.pkg b/packaging/Caldera/OpenServer/pkg/input/SambaSWAT.pkg
new file mode 100755
index 00000000000..329f81c108f
--- /dev/null
+++ b/packaging/Caldera/OpenServer/pkg/input/SambaSWAT.pkg
@@ -0,0 +1,363 @@
+
+PKG:SambaSWAT:
+description = "Samba Web Administration Tool"
+dependencies =
+distTreeRootSHARED = $Samba_DIR
+distTreeRootCLIENT = $Samba_DIR
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/sbin/swat:
+mode = 0755
+owner = root
+group = sys
+exportPath = /usr/lib/samba/sbin/swat
+
+DIR:SambaSWAT:SHARED:usr/lib/samba/swat:
+mode = 0755
+owner = root
+group = sys
+
+DIR:SambaSWAT:SHARED:usr/lib/samba/swat/images:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/globals.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/globals.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/home.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/home.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/passwd.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/passwd.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/printers.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/printers.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/samba.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/samba.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/shares.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/shares.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/status.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/status.gif
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/images/viewconfig.gif:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/images/viewconfig.gif
+
+DIR:SambaSWAT:SHARED:usr/lib/samba/swat/help:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/welcome.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/welcome.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/DOMAIN_MEMBER.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/DOMAIN_MEMBER.html
+exportPath = /usr/share/doc/samba/help/DOMAIN_MEMBER.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/Integrating-with-Windows.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/Integrating-with-Windows.html
+exportPath = /usr/share/doc/samba/help/Integrating-with-Windows.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/NT_Security.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/NT_Security.html
+exportPath = /usr/share/doc/samba/help/NT_Security.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/OS2-Client-HOWTO.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/OS2-Client-HOWTO.html
+exportPath = /usr/share/doc/samba/help/OS2-Client-HOWTO.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/Samba-HOWTO-Collection.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/Samba-HOWTO-Collection.html
+exportPath = /usr/share/doc/samba/help/Samba-HOWTO-Collection.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/Samba-LDAP-HOWTO.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/Samba-LDAP-HOWTO.html
+exportPath = /usr/share/doc/samba/help/Samba-LDAP-HOWTO.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/UNIX_INSTALL.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/UNIX_INSTALL.html
+exportPath = /usr/share/doc/samba/help/UNIX_INSTALL.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/findsmb.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/findsmb.1.html
+exportPath = /usr/share/doc/samba/help/findsmb.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/lmhosts.5.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/lmhosts.5.html
+exportPath = /usr/share/doc/samba/help/lmhosts.5.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/make_unicodemap.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/make_unicodemap.1.html
+exportPath = /usr/share/doc/samba/help/make_unicodemap.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/make_smbcodepage.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/make_smbcodepage.1.html
+exportPath = /usr/share/doc/samba/help/make_smbcodepage.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/msdfs_setup.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/msdfs_setup.html
+exportPath = /usr/share/doc/samba/help/msdfs_setup.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/nmbd.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/nmbd.8.html
+exportPath = /usr/share/doc/samba/help/nmbd.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/nmblookup.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/nmblookup.1.html
+exportPath = /usr/share/doc/samba/help/nmblookup.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/pdbedit.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/pdbedit.1.html
+exportPath = /usr/share/doc/samba/help/pdbedit.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/printer_driver2.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/printer_driver2.html
+exportPath = /usr/share/doc/samba/help/printer_driver2.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/rpcclient.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/rpcclient.1.html
+exportPath = /usr/share/doc/samba/help/rpcclient.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/samba.7.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/samba.7.html
+exportPath = /usr/share/doc/samba/help/samba.7.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smb.conf.5.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smb.conf.5.html
+exportPath = /usr/share/doc/samba/help/smb.conf.5.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbcacls.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbcacls.1.html
+exportPath = /usr/share/doc/samba/help/smbcacls.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbclient.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbclient.1.html
+exportPath = /usr/share/doc/samba/help/smbclient.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbcontrol.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbcontrol.1.html
+exportPath = /usr/share/doc/samba/help/smbcontrol.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbd.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbd.8.html
+exportPath = /usr/share/doc/samba/help/smbd.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbmnt.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbmnt.8.html
+exportPath = /usr/share/doc/samba/help/smbmnt.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbmount.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbmount.8.html
+exportPath = /usr/share/doc/samba/help/smbmount.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbpasswd.5.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbpasswd.5.html
+exportPath = /usr/share/doc/samba/help/smbpasswd.5.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbpasswd.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbpasswd.8.html
+exportPath = /usr/share/doc/samba/help/smbpasswd.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbspool.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbspool.8.html
+exportPath = /usr/share/doc/samba/help/smbspool.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbstatus.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbstatus.1.html
+exportPath = /usr/share/doc/samba/help/smbstatus.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbtar.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbtar.1.html
+exportPath = /usr/share/doc/samba/help/smbtar.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/smbumount.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/smbumount.8.html
+exportPath = /usr/share/doc/samba/help/smbumount.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/swat.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/swat.8.html
+exportPath = /usr/share/doc/samba/help/swat.8.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/testparm.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/testparm.1.html
+exportPath = /usr/share/doc/samba/help/testparm.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/testprns.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/testprns.1.html
+exportPath = /usr/share/doc/samba/help/testprns.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/wbinfo.1.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/wbinfo.1.html
+exportPath = /usr/share/doc/samba/help/wbinfo.1.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/winbind.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/winbind.html
+exportPath = /usr/share/doc/samba/help/winbind.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/help/winbindd.8.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/help/winbindd.8.html
+exportPath = /usr/share/doc/samba/help/winbindd.8.html
+
+DIR:SambaSWAT:SHARED:usr/lib/samba/swat/include:
+mode = 0755
+owner = root
+group = sys
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/include/footer.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/include/footer.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/include/header.html:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/include/header.html
+
+FILE:SambaSWAT:SHARED:usr/lib/samba/swat/README:
+mode = 0644
+owner = root
+group = sys
+exportPath = /usr/lib/samba/swat/README
diff --git a/packaging/Caldera/OpenServer/samba.desktop b/packaging/Caldera/OpenServer/samba.desktop
new file mode 100755
index 00000000000..33512125141
--- /dev/null
+++ b/packaging/Caldera/OpenServer/samba.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Name=Samba Documentation
+DocPath=/usr/share/doc/samba/help/index.html
+X-COL-Weight=1.0
diff --git a/packaging/Caldera/OpenServer/samba.directory b/packaging/Caldera/OpenServer/samba.directory
new file mode 100755
index 00000000000..bdc6fa8af41
--- /dev/null
+++ b/packaging/Caldera/OpenServer/samba.directory
@@ -0,0 +1,3 @@
+[Desktop Entry]
+Name=Samba File and Print Server
+Type=group
diff --git a/packaging/Caldera/OpenServer/samba_configure.desktop b/packaging/Caldera/OpenServer/samba_configure.desktop
new file mode 100755
index 00000000000..d2048ab3c73
--- /dev/null
+++ b/packaging/Caldera/OpenServer/samba_configure.desktop
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Configuring Samba
+DocPath=/usr/share/doc/samba/help/osr5config.html
+X-COL-Weight=2.0
+X-COL-rewrite=samba_help
diff --git a/packaging/Caldera/OpenServer/samba_help.desktop b/packaging/Caldera/OpenServer/samba_help.desktop
new file mode 100755
index 00000000000..d191c9d312e
--- /dev/null
+++ b/packaging/Caldera/OpenServer/samba_help.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Name=About Samba
+DocPath=/usr/share/doc/samba/help/index.html
+X-COL-Weight=1.0
diff --git a/packaging/Caldera/OpenServer/samba_using.desktop b/packaging/Caldera/OpenServer/samba_using.desktop
new file mode 100755
index 00000000000..9925fa0b336
--- /dev/null
+++ b/packaging/Caldera/OpenServer/samba_using.desktop
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Using Samba
+DocPath=/usr/share/doc/samba/using_samba/index.html
+X-COL-Rewrite=using_samba
+X-COL-Weight=3.0
diff --git a/packaging/Caldera/OpenServer/sco_logo_med.gif b/packaging/Caldera/OpenServer/sco_logo_med.gif
new file mode 100755
index 00000000000..ee2d33db5dd
--- /dev/null
+++ b/packaging/Caldera/OpenServer/sco_logo_med.gif
Binary files differ
diff --git a/packaging/Caldera/OpenServer/smb.conf b/packaging/Caldera/OpenServer/smb.conf
new file mode 100755
index 00000000000..494fd0f1e19
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smb.conf
@@ -0,0 +1,294 @@
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not many any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+# workgroup = NT-Domain-Name or Workgroup-Name
+ workgroup = %%WORKGROUP%%
+
+# netbios name
+ netbios name = %%NBNAME%%
+
+# server string is the equivalent of the NT Description field
+ server string = Samba Server
+
+# This option is important for security. It allows you to restrict
+# connections to machines which are on your local network. The
+# following example restricts access to two C class networks and
+# the "loopback" interface. For more examples of the syntax see
+# the smb.conf man page
+; hosts allow = 192.168.1. 192.168.2. 127.
+
+# if you want to automatically load your printer list rather
+# than setting them up individually then you'll need this
+ printcap name = lpstat
+ load printers = yes
+
+# It should not be necessary to spell out the print system type unless
+# yours is non-standard. Currently supported print systems include:
+# bsd, sysv, plp, lprng, aix, hpux, qnx
+ printing = sysv
+
+# Uncomment this if you want a guest account, you must add this to /etc/passwd
+# otherwise the user "nouser" is used
+; guest account = pcguest
+
+# this tells Samba to use a separate log file for each machine
+# that connects
+ log file = /var/log/samba.d/log.%m
+
+# Put a capping on the size of the log files (in Kb).
+ max log size = 50
+
+# Security mode. Most people will want user level security. See
+# security_level.txt for details.
+ security = %%SECURITY%%
+# Use password server option only with security = server
+; password server = %%PWSERVER%%
+
+# Password Level allows matching of _n_ characters of the password for
+# all combinations of upper and lower case.
+; password level = 8
+; username level = 8
+
+# You may wish to use password encryption. Please read
+# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+# Do not enable this option unless you have read those documents
+; encrypt passwords = yes
+; smb passwd file = /etc/smbpasswd
+
+# The following are needed to allow password changing from Windows to
+# update the Linux sytsem password also.
+# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
+# NOTE2: You do NOT need these to allow workstations to change only
+# the encrypted SMB passwords. They allow the Unix password
+# to be kept in sync with the SMB password.
+; unix password sync = Yes
+; passwd program = /usr/bin/passwd %u
+; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
+
+# Unix users can map to different SMB User names
+; username map = /etc/smbusers
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+; include = /etc/smb.conf.%m
+
+# Most people will find that this option gives better performance.
+# See speed.txt and the manual pages for details
+ socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+
+# Configure Samba to use multiple interfaces
+# If you have multiple network interfaces then you must list them
+# here. See the man page for details.
+; interfaces = %%INTERFACES%%
+
+# Configure remote browse list synchronisation here
+# request announcement to, or browse list sync from:
+# a specific host or from / to a whole subnet (see below)
+; remote browse sync = 192.168.3.25 192.168.5.255
+# Cause this host to announce itself to local subnets here
+; remote announce = 192.168.1.255 192.168.2.44
+
+# Browser Control Options:
+# set local master to no if you don't want Samba to become a master
+# browser on your network. Otherwise the normal election rules apply
+; local master = no
+
+# OS Level determines the precedence of this server in master browser
+# elections. The default value should be reasonable
+ os level = %%OSLEVEL%%
+
+# Domain Master specifies Samba to be the Domain Master Browser. This
+# allows Samba to collate browse lists between subnets. Don't use this
+# if you already have a Windows NT domain controller doing this job
+; domain master = %%DOMAINMASTER%%
+
+# Preferred Master causes Samba to force a local browser election on startup
+# and gives it a slightly higher chance of winning the election
+; preferred master = yes
+
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = %%PDC%%
+
+# Enable this if you want Samba to be a domain logon server for
+# Windows95 workstations.
+; domain logons = %%DOMAINLOGONS%%
+
+# if you enable domain logons then you may want a per-machine or
+# per user logon script
+# run a specific logon batch file per workstation (machine)
+; logon script = %m.bat
+# run a specific logon batch file per username
+; logon script = %U.bat
+
+# Where to store roving profiles (only for Win95 and WinNT)
+# %L substitutes for this servers netbios name, %U is username
+# You must uncomment the [Profiles] share below
+; logon path = \\%L\Profiles\%U
+
+# All NetBIOS names must be resolved to IP Addresses
+# 'Name Resolve Order' allows the named resolution mechanism to be specified
+# the default order is "host lmhosts wins bcast". "host" means use the unix
+# system gethostbyname() function call that will use either /etc/hosts OR
+# DNS or NIS depending on the settings of /etc/host.config, /etc/nsswitch.conf
+# and the /etc/resolv.conf file. "host" therefore is system configuration
+# dependant. This parameter is most often of use to prevent DNS lookups
+# in order to resolve NetBIOS names to IP Addresses. Use with care!
+# The example below excludes use of name resolution for machines that are NOT
+# on the local network segment
+# - OR - are not deliberately to be known via lmhosts or via WINS.
+; name resolve order = wins lmhosts bcast
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = %%WINSSUPPORT%%
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = %%WINSSERVER%%
+
+# WINS Proxy - Tells Samba to answer name resolution queries on
+# behalf of a non WINS capable client, for this to work there must be
+# at least one WINS Server on the network. The default is NO.
+; wins proxy = yes
+
+# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+# via DNS nslookups. The built-in default for versions 1.9.17 is yes,
+# this has been changed in version 1.9.18 to no.
+ dns proxy = no
+
+# Case Preservation can be handy - system default is _no_
+# NOTE: These can be set on a per share basis
+; preserve case = no
+; short preserve case = no
+# Default case is normally upper case for all DOS files
+; default case = lower
+# Be very careful with case sensitivity - it can break things!
+; case sensitive = no
+
+#============================ Share Definitions ==============================
+[homes]
+ comment = Home Directories
+ browseable = no
+ writable = yes
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+; [netlogon]
+; comment = Network Logon Service
+; path = /home/netlogon
+; guest ok = yes
+; writable = no
+; share modes = no
+
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+;[Profiles]
+; path = /home/profiles
+; browseable = no
+; guest ok = yes
+
+
+# NOTE: If you have a BSD-style print system there is no need to
+# specifically define each individual printer
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+# Set public = yes to allow user 'guest account' to print
+ guest ok = no
+ writable = no
+ printable = yes
+
+# This one is useful for people to share files
+;[tmp]
+; comment = Temporary file space
+; path = /tmp
+; read only = no
+; public = yes
+
+# A publicly accessible directory, but read only, except for people in
+# the "staff" group
+;[public]
+; comment = Public Stuff
+; path = /home/samba
+; public = yes
+; writable = yes
+; printable = no
+; write list = @staff
+
+# Other examples.
+#
+# A private printer, usable only by fred. Spool data will be placed in fred's
+# home directory. Note that fred must have write access to the spool directory,
+# wherever it is.
+;[fredsprn]
+; comment = Fred's Printer
+; valid users = fred
+; path = /homes/fred
+; printer = freds_printer
+; public = no
+; writable = no
+; printable = yes
+
+# A private directory, usable only by fred. Note that fred requires write
+# access to the directory.
+;[fredsdir]
+; comment = Fred's Service
+; path = /usr/somewhere/private
+; valid users = fred
+; public = no
+; writable = yes
+; printable = no
+
+# a service which has a different directory for each machine that connects
+# this allows you to tailor configurations to incoming machines. You could
+# also use the %u option to tailor it by user name.
+# The %m gets replaced with the machine name that is connecting.
+;[pchome]
+; comment = PC Directories
+; path = /usr/pc/%m
+; public = no
+; writable = yes
+
+# A publicly accessible directory, read/write to all users. Note that all files
+# created in the directory by users will be owned by the default user, so
+# any user with access can delete any other user's files. Obviously this
+# directory must be writable by the default user. Another user could of course
+# be specified, in which case all files would be owned by that user instead.
+;[public]
+; path = /usr/somewhere/else/public
+; public = yes
+; only guest = yes
+; writable = yes
+; printable = no
+
+# The following two entries demonstrate how to share a directory so that two
+# users can place files there that will be owned by the specific users. In this
+# setup, the directory should be writable by both users and should have the
+# sticky bit set on it to prevent abuse. Obviously this could be extended to
+# as many users as required.
+;[myshare]
+; comment = Mary's and Fred's stuff
+; path = /usr/somewhere/shared
+; valid users = mary fred
+; public = no
+; writable = yes
+; printable = no
+; create mask = 0765
+
+
diff --git a/packaging/Caldera/OpenServer/smb.init b/packaging/Caldera/OpenServer/smb.init
new file mode 100755
index 00000000000..194b8a2bb29
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smb.init
@@ -0,0 +1,71 @@
+#!/bin/sh
+#ident "@(#)samba.server 1.0 96/06/19 TK" /* SVr4.0 1.1.13.1*/
+#
+# Please send info on modifications to knuutila@cs.utu.fi
+#
+# This file should have uid root, gid sys and chmod 744
+#
+# Modified 17-Jul-99 by Ron Record (rr@sco.com) for use in SCO Skunkware
+#
+
+SAMBADIR=/usr/lib/samba
+RCSCRIPT=/etc/rc2.d/S99samba
+
+killproc() { # kill the named process(es)
+ if [ -f /var/locks/samba.d/$1.pid ]
+ then
+ kill `cat /var/locks/samba.d/$1.pid`
+ else
+ pid=`/bin/ps -e |
+ /bin/grep $1 |
+ /bin/sed -e 's/^ *//' -e 's/ .*//'`
+ [ "$pid" != "" ] && kill $pid
+ fi
+}
+
+start() {
+#
+# Edit these lines to suit your installation (paths, workgroup, host)
+#
+ $SAMBADIR/sbin/smbd -D -s /etc/samba.d/smb.conf
+ $SAMBADIR/sbin/nmbd -D -s /etc/samba.d/smb.conf
+}
+
+stop() {
+ killproc nmbd
+ killproc smbd
+}
+
+# Start/stop processes required for samba server
+
+case "$1" in
+
+'start')
+ start
+ ;;
+'stop')
+ stop
+ ;;
+'restart')
+ stop
+ start
+ ;;
+'enable')
+ if [ -h $RCSCRIPT ] ; then
+ echo "Samba is already enabled."
+ else
+ echo "Enabling Samba ... \c"
+ rm -f $RCSCRIPT
+ ln -s /etc/init.d/samba $RCSCRIPT
+ echo "Done"
+ fi
+ ;;
+'disable')
+ echo "Disabling Samba ... \c"
+ rm -f $RCSCRIPT
+ echo "Done"
+ ;;
+*)
+ echo "Usage: /etc/init.d/samba { start | stop | restart | enable | disable }"
+ ;;
+esac
diff --git a/packaging/Caldera/OpenServer/smb.mkdev b/packaging/Caldera/OpenServer/smb.mkdev
new file mode 100755
index 00000000000..df7e0adcc81
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smb.mkdev
@@ -0,0 +1,49 @@
+#!/bin/sh
+# Samba mkdev script for SCO OpenServer
+#
+# Run "initconfig" to set up initial Samba configuration;
+# move init script into place so that Samba will be started
+# at boot time.
+
+# Prompt with mesg, return non-zero on q
+prompt() {
+ FAIL=1 OK=0
+ while echo "\n${mesg}or enter q to quit: \c" >&2
+ do read cmd
+ case $cmd in
+ +x|-x) set $cmd ;;
+ Q|q) return $FAIL ;;
+ !*) eval `expr "$cmd" : "!\(.*\)"` ;;
+ "") # If there is an argument use it as the default
+ # else loop until 'cmd' is set
+ [ "$1" ] && {
+ cmd=$1
+ return $OK
+ }
+ : continue
+ ;;
+ *) return $OK ;;
+ esac
+ done
+}
+
+mesg="\tSamba Configuration\n
+\t1. Configure and activate Samba
+\t2. Deactivate Samba\n
+Select an option "
+
+while true ; do
+ prompt || exit 1
+ case $cmd in
+ 1) /usr/lib/samba/bin/initconfig
+ /etc/init.d/samba enable
+ /etc/init.d/samba start
+ exit 0
+ ;;
+ 2) /etc/init.d/samba disable
+ /etc/init.d/samba stop
+ exit 0
+ ;;
+ esac
+done
+
diff --git a/packaging/Caldera/OpenServer/smbadduser b/packaging/Caldera/OpenServer/smbadduser
new file mode 100755
index 00000000000..d7a19626369
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smbadduser
@@ -0,0 +1,73 @@
+#!/bin/csh
+#
+# smbadduser - Written by Mike Zakharoff
+#
+unalias *
+set path = ($path)
+
+set smbpasswd = /etc/samba.d/smbpasswd
+set user_map = /etc/samba.d/smbusers
+#
+# Set to site specific passwd command
+#
+set passwd = "cat /etc/passwd"
+#set passwd = "niscat passwd.org_dir"
+#set passwd = "ypcat passwd"
+
+set line = "----------------------------------------------------------"
+if ($#argv == 0) then
+ echo $line
+ echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
+ echo ""
+ echo " 1) Updates $smbpasswd"
+ echo " 2) Updates $user_map"
+ echo " 3) Executes smbpasswd for each new user"
+ echo ""
+ echo "smbadduser unixid:ntid unixid:ntid ..."
+ echo ""
+ echo "Example: smbadduser zak:zakharoffm johns:smithj"
+ echo $line
+ exit 1
+endif
+
+touch $smbpasswd $user_map
+set new = ()
+foreach one ($argv)
+ echo $one | grep ':' >& /dev/null
+ if ($status != 0) then
+ echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
+ continue
+ endif
+ set unix = `echo $one | awk -F: '{print $1}'`
+ set ntid = `echo $one | awk -F: '{print $2}'`
+
+ set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#usr != 1) then
+ echo "ERROR: $unix Not in passwd database SKIPPING..."
+ continue
+ endif
+ set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#tmp != 0) then
+ echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
+ continue
+ endif
+
+ echo "Adding: $unix to $smbpasswd"
+ eval $passwd | \
+ awk -F: '$1==USR { \
+ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
+ if ($unix != $ntid) then
+ echo "Adding: {$unix = $ntid} to $user_map"
+ echo "$unix = $ntid" >> $user_map
+ endif
+ set new = ($new $unix)
+end
+
+#
+# Enter password for new users
+#
+foreach one ($new)
+ echo $line
+ echo "ENTER password for $one"
+ smbpasswd $one
+end
diff --git a/packaging/Caldera/OpenServer/smbprint b/packaging/Caldera/OpenServer/smbprint
new file mode 100755
index 00000000000..7f50aadb46e
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smbprint
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# This script is an input filter for printcap printing on a unix machine. It
+# uses the smbclient program to print the file to the specified smb-based
+# server and service.
+# For example you could have a printcap entry like this
+#
+# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/lib/samba/smbprint
+#
+# which would create a unix printer called "smb" that will print via this
+# script. You will need to create the spool directory /usr/spool/smb with
+# appropriate permissions and ownerships for your system.
+
+# Set these to the server and service you wish to print to
+# In this example I have a WfWg PC called "lapland" that has a printer
+# exported called "printer" with no password.
+
+#
+# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
+# so that the server, service, and password can be read from
+# a /var/spool/lpd/PRINTNAME/.config file.
+#
+# In order for this to work the /etc/printcap entry must include an
+# accounting file (af=...):
+#
+# cdcolour:\
+# :cm=CD IBM Colorjet on 6th:\
+# :sd=/var/spool/lpd/cdcolour:\
+# :af=/var/spool/lpd/cdcolour/acct:\
+# :if=/usr/lib/samba/smbprint:\
+# :mx=0:\
+# :lp=/dev/null:
+#
+# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
+# server=PC_SERVER
+# service=PR_SHARENAME
+# password="password"
+#
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
+# password=""
+
+#
+# Debugging log file, change to /dev/null if you like.
+#
+# logfile=/tmp/smb-print.log
+logfile=/dev/null
+
+
+#
+# The last parameter to the filter is the accounting file name.
+# Extract the directory name from the file name.
+# Concat this with /.config to get the config file.
+#
+eval acct_file=\${$#}
+spool_dir=`dirname $acct_file`
+config_file=$spool_dir/.config
+
+# Should read the following variables set in the config file:
+# server
+# service
+# password
+eval `cat $config_file`
+
+#
+# Some debugging help, change the >> to > if you want to same space.
+#
+echo "server $server, service $service" >> $logfile
+
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+# echo translate
+ echo "print -"
+ cat
+) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/Caldera/OpenServer/smbusers b/packaging/Caldera/OpenServer/smbusers
new file mode 100755
index 00000000000..08f611826ab
--- /dev/null
+++ b/packaging/Caldera/OpenServer/smbusers
@@ -0,0 +1,3 @@
+# Unix_name = SMB_name1 SMB_name2 ...
+root = administrator admin
+nouser = guest pcguest smbguest
diff --git a/packaging/Caldera/OpenServer/swat.readme b/packaging/Caldera/OpenServer/swat.readme
new file mode 100755
index 00000000000..b7467baa1ca
--- /dev/null
+++ b/packaging/Caldera/OpenServer/swat.readme
@@ -0,0 +1,40 @@
+This is a brief description of how to use the Samba Web
+Administration Tool on your machine.
+
+Launching
+---------
+
+To launch SWAT just run your favourite web browser and point it at
+http://localhost:598/
+
+Note that you can attach to SWAT from any IP connected machine but
+connecting from a remote machine leaves your connection open to
+password sniffing as passwords will be sent in the clear over the
+wire.
+
+You should be prompted for a username/password when you connect. You
+will need to provide the username "root" and the correct root
+password.
+
+Running
+-------
+
+Just follow your nose! If you can't work out how to use it then maybe
+you should use "vi smb.conf" instead.
+
+
+WARNINGS
+--------
+
+SWAT will rewrite your smb.conf file. It will rearrange the entries
+and delete all comments, include= and copy= options. If you have a
+carefully crafted smb.conf then back it up or don't use SWAT!
+
+
+Development
+-----------
+
+Please join the samba-technical mailing list if you want to discuss
+the development of SWAT. Note that this list is for technical developer
+discussions and is not a general help list.
+
diff --git a/packaging/Caldera/UnixWare/Clean b/packaging/Caldera/UnixWare/Clean
new file mode 100755
index 00000000000..fe4eed25270
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Clean
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Cleanup after having configured, compiled, installed and packaged.
+# Careful - running this script attempts to restore this hierarchy to
+# freshly unpacked source
+#
+# Invoke as "./Clean -n" to get this script to tell you what it would do
+# without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+[ -d dist ] && $V rm -rf dist
+[ -f ../../../source/Makefile ] && {
+ $V cd ../../../source
+ $V rm -f bin/locktest bin/masktest bin/smbsh bin/debug2html \
+ bin/locktest2 bin/smbfilter bin/smbtorture
+ $V make clean
+ $V make distclean
+ $V rm -f mout*
+}
diff --git a/packaging/Caldera/UnixWare/Compile b/packaging/Caldera/UnixWare/Compile
new file mode 100755
index 00000000000..c4870163053
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Compile
@@ -0,0 +1,70 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+#CC="cc -Kthread -Kalloca -I/usr/local/include -L/usr/local/lib"
+CC="cc -Kthread -Kalloca"
+CPP="$CC -E"
+CFLAGS="-Xa -Dasm=__asm -DANSICPP -O3"
+#LDFLAGS="-L/usr/local/lib"
+LDFLAGS=
+#CXX="CC -I/usr/local/include"
+CXX="CC"
+#CXXFLAGS="-O3 -I/usr/local/include/stl -L/usr/local/lib"
+CXXFLAGS="-O3"
+RANLIB=true
+
+if [ -x /usr/gnu/bin/make ]
+then
+ MAKE=/usr/gnu/bin/make
+elif [ -x /usr/local/bin/make ]
+then
+ MAKE=/usr/local/bin/make
+elif [ -x /usr/bin/make ]
+then
+ MAKE=/usr/bin/make
+else
+ echo "Can't find make - exiting"
+ exit 1
+fi
+
+if [ "$V" = "echo" ]
+then
+ echo "exporting the following shell variables:"
+ echo "CC=$CC"
+ echo "CPP=$CPP"
+ echo "CXX=$CXX"
+ echo "RANLIB=$RANLIB"
+ echo "MAKE=$MAKE"
+ echo "CFLAGS=$CFLAGS"
+ echo "CXXFLAGS=$CXXFLAGS"
+ echo "LDFLAGS=$LDFLAGS"
+else
+ export CC CPP CXX RANLIB MAKE CFLAGS CXXFLAGS LDFLAGS
+fi
+
+if [ "$V" = "echo" ]
+then
+ echo "cd ../../../source"
+ echo "rm -f mout-1 mout-2 mout-3 mout-4"
+ echo "$MAKE all 2>&1 | tee mout-1"
+ echo "$MAKE smbfilter smbtorture debug2html 2>&1 | tee mout-2"
+ echo "$MAKE bin/smbspool smbwrapper bin/wbinfo 2>&1 | tee mout-3"
+ echo "$MAKE masktest locktest locktest2 2>&1 | tee mout-3"
+else
+ cd ../../../source
+ rm -f mout-1 mout-2 mout-3 mout-4
+ $MAKE all 2>&1 | tee mout-1
+ $MAKE smbfilter smbtorture debug2html 2>&1 | tee mout-2
+ $MAKE bin/smbspool smbwrapper bin/wbinfo 2>&1 | tee mout-3
+ $MAKE masktest locktest locktest2 2>&1 | tee mout-3
+fi
+#
+# Not building :
+# nsswitch - no <nss.h>
+# rpctorture - improper use of client_info struct, dunno
diff --git a/packaging/Caldera/UnixWare/Configure b/packaging/Caldera/UnixWare/Configure
new file mode 100755
index 00000000000..e899742ce90
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Configure
@@ -0,0 +1,83 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+#CC="cc -Kthread -Kalloca -I/usr/local/include -L/usr/local/lib"
+CC="cc -Kthread -Kalloca"
+CPP="$CC -E"
+CFLAGS="-Xa -Dasm=__asm -DANSICPP -O3"
+#LDFLAGS="-L/usr/local/lib"
+LDFLAGS=
+#CXX="CC -I/usr/local/include"
+CXX="CC"
+#CXXFLAGS="-O3 -I/usr/local/include/stl -L/usr/local/lib"
+CXXFLAGS="-O3"
+RANLIB=true
+PREFIX=/usr/lib/samba
+
+if [ -x /usr/gnu/bin/make ]
+then
+ MAKE=/usr/gnu/bin/make
+elif [ -x /usr/local/bin/make ]
+then
+ MAKE=/usr/local/bin/make
+elif [ -x /usr/bin/make ]
+then
+ MAKE=/usr/bin/make
+else
+ echo "Can't find make - exiting"
+ exit 1
+fi
+
+if [ "$V" = "echo" ]
+then
+ echo "exporting the following shell variables:"
+ echo "CC=$CC"
+ echo "CPP=$CPP"
+ echo "CXX=$CXX"
+ echo "RANLIB=$RANLIB"
+ echo "MAKE=$MAKE"
+ echo "CFLAGS=$CFLAGS"
+ echo "CXXFLAGS=$CXXFLAGS"
+ echo "LDFLAGS=$LDFLAGS"
+ echo "PREFIX=$PREFIX"
+else
+ export CC CPP CXX RANLIB MAKE CFLAGS CXXFLAGS LDFLAGS PREFIX
+fi
+
+cd ../../../source
+[ -f mout-config ] && {
+ if [ "$V" = "echo" ]
+ then
+ echo "mv mout-config mout-config$$"
+ else
+ mv mout-config mout-config$$
+ fi
+}
+if [ "$V" = "echo" ]
+then
+ echo "./configure \
+ --prefix=${PREFIX} \
+ --with-profile \
+ --with-syslog \
+ --with-utmp \
+ --with-vfs \
+ --with-msdfs \
+ --with-sambabook=${PREFIX}/swat/using_samba \
+ 2>&1 | tee mout-config"
+else
+ ./configure \
+ --prefix=${PREFIX} \
+ --with-profile \
+ --with-syslog \
+ --with-utmp \
+ --with-vfs \
+ --with-msdfs \
+ --with-sambabook=${PREFIX}/swat/using_samba \
+ 2>&1 | tee mout-config
+fi
diff --git a/packaging/Caldera/UnixWare/Install b/packaging/Caldera/UnixWare/Install
new file mode 100755
index 00000000000..a2d8da12eaa
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Install
@@ -0,0 +1,145 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+PREFIX=/usr/lib/samba
+HERE=`pwd`
+PKGDIR=packaging/Caldera/UnixWare
+
+BUILD_ROOT=${HERE}/dist
+BLDFIX=${BUILD_ROOT}/${PREFIX}
+$V rm -rf $BUILD_ROOT
+$V mkdir -p $BUILD_ROOT/etc/init.d
+$V mkdir -p ${BLDFIX}/bin
+$V mkdir -p ${BLDFIX}/sbin
+$V mkdir -p ${BLDFIX}/swat/using_samba/gifs
+$V mkdir -p ${BLDFIX}/swat/using_samba/figs
+$V mkdir -p ${BLDFIX}/swat/images
+$V mkdir -p ${BLDFIX}/swat/help
+$V mkdir -p ${BLDFIX}/swat/include
+$V mkdir -p ${BLDFIX}/man/man1
+$V mkdir -p ${BLDFIX}/man/man5
+$V mkdir -p ${BLDFIX}/man/man7
+$V mkdir -p ${BLDFIX}/man/man8
+$V mkdir -p ${BLDFIX}/var/locks
+$V mkdir -p ${BLDFIX}/lib/codepages/src
+
+# Copy into the dist tree the pkg data files
+for i in pkg/*
+do
+ [ -f $i ] && $V cp $i ${BUILD_ROOT}
+done
+
+cd ../../..
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool
+do
+$V install -m755 -s source/bin/$i ${BLDFIX}/bin
+done
+for i in mksmbpasswd.sh smbtar
+do
+$V install -m755 source/script/$i ${BLDFIX}/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat debug2html smbtorture smbfilter locktest2 masktest
+do
+$V install -m755 -s source/bin/$i ${BLDFIX}/sbin
+done
+
+
+# Install level 1 man pages
+for i in *.1
+do
+$V install -m644 docs/manpages/$i ${BLDFIX}/man/man1
+done
+
+# Install codepage source files
+for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+do
+$V install -m644 source/codepages/codepage_def.$i ${BLDFIX}/lib/codepages/src
+done
+for i in 437 737 850 852 861 866 932 936 949 950 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+do
+$V install -m644 source/codepages/CP$i.TXT ${BLDFIX}/lib/codepages/src
+done
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/help
+done
+for i in swat/images/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/images
+done
+for i in swat/include/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/include
+done
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+$V install -m644 $i ${BLDFIX}/swat/using_samba/gifs
+done
+
+# Install the miscellany
+$V install -m644 swat/README ${BLDFIX}/swat
+$V install -m644 docs/manpages/smb.conf.5 ${BLDFIX}/man/man5
+$V install -m644 docs/manpages/lmhosts.5 ${BLDFIX}/man/man5
+$V install -m644 docs/manpages/smbpasswd.5 ${BLDFIX}/man/man5
+$V install -m644 docs/manpages/samba.7 ${BLDFIX}/man/man7
+$V install -m644 docs/manpages/smbd.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/nmbd.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/smbpasswd.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/swat.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/smbmount.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/smbmnt.8 ${BLDFIX}/man/man8
+$V install -m644 docs/manpages/smbumount.8 ${BLDFIX}/man/man8
+$V install -m644 ${PKGDIR}/smb.conf ${BLDFIX}/lib/smb.conf
+$V install -m644 ${PKGDIR}/smbusers $BUILD_ROOT/etc/smbusers
+$V install -m755 ${PKGDIR}/smbprint ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/findsmb ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/smbadduser ${BLDFIX}/bin
+$V install -m755 ${PKGDIR}/smb.init $BUILD_ROOT/etc/init.d/samba
+
+# The following is now done in the postinstall script
+#
+# if [ "$V" = "echo" ]
+# then
+# echo "echo 127.0.0.1 localhost > $BUILD_ROOT/etc/lmhosts"
+# else
+# echo 127.0.0.1 localhost > $BUILD_ROOT/etc/lmhosts
+# fi
+#
+# Build codepage load files
+# $V cd ${BLDFIX}/lib/codepages
+# for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+# do
+# $V ${PREFIX}/bin/make_smbcodepage c $i \
+# ${BLDFIX}/lib/codepages/src/codepage_def.$i \
+# ${BLDFIX}/lib/codepages/codepage.$i
+# done
+# for i in 437 737 850 852 861 866 932 936 949 950 \
+# ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+# do
+# $V ${PREFIX}/bin/make_unicodemap $i \
+# ${BLDFIX}/lib/codepages/src/CP$i.TXT \
+# ${BLDFIX}/lib/codepages/unicode_map.$i
+# done
diff --git a/packaging/Caldera/UnixWare/Makepkg b/packaging/Caldera/UnixWare/Makepkg
new file mode 100755
index 00000000000..dc57b246ef5
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Makepkg
@@ -0,0 +1,10 @@
+#!/bin/ksh
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+./Configure $*
+./Compile $*
+./Install $*
+./Package $*
diff --git a/packaging/Caldera/UnixWare/Package b/packaging/Caldera/UnixWare/Package
new file mode 100755
index 00000000000..f225b8eb7ea
--- /dev/null
+++ b/packaging/Caldera/UnixWare/Package
@@ -0,0 +1,40 @@
+#!/bin/ksh
+#
+# Now create the actual pkgadd installable datastream
+#
+# invoke with -n as the first argument to get this script to tell
+# you what it would do without doing anything
+#
+
+V=
+[ "$1" = "-n" ] && V=echo
+
+$V cd dist
+PKGNAME=samba
+PKGBLD=`pwd`
+[ "$V" = "echo" ] && PKGBLD=$PKGBLD/dist
+
+PKGCOMPRESS="-c"
+#PKGBLOCKLIM=2876
+PKGBLOCKLIM=6200
+
+##############################################################################
+#
+# make filesystem-type package in directory ./$PKGNAME/
+# (source files reside in ./root)
+#
+# don't use PKGBLOCKLIM for now
+#
+$V pkgmk -o $PKGCOMPRESS -d $PKGBLD -r $PKGBLD
+#pkgmk -o $PKGCOMPRESS -l $PKGBLOCKLIM -d $PKGBLD -r $PKGBLD
+#pkgmk -o $PKGCOMPRESS -l $PKGBLOCKLIM -d $PKGBLD -r $PKGBLD/root
+
+#
+# make $PKGNAME.pkg datastream-type package
+#
+$V pkgtrans -s $PKGBLD $PKGBLD/$PKGNAME.pkg $PKGNAME
+
+#
+# remove filesystem-type package
+#
+#rm -rf $PKGBLD/$PKGNAME
diff --git a/packaging/Caldera/UnixWare/README b/packaging/Caldera/UnixWare/README
new file mode 100755
index 00000000000..74f8dc53d5d
--- /dev/null
+++ b/packaging/Caldera/UnixWare/README
@@ -0,0 +1,54 @@
+Preparation Date: December 28, 2000
+Preparer: Ronald Joe Record <rr@sco.com>
+
+Instructions: Preparing Samba Packages for UnixWare
+===============================================================
+
+We provide support only for current versions of UnixWare.
+
+The file samba-2.2-uw7.patch is a patch file suitable for use
+with the patch command as follows:
+
+ # cd ../../../source
+ # patch -p 0 -i ../packaging/Caldera/UnixWare/samba-2.2-uw7.patch
+
+The files modified by this patch are:
+ smbwrapper/smbw.c
+ tdb/tdb.c
+ utils/torture.c
+ utils/locktest.c
+ utils/locktest2.c
+ utils/masktest.c
+ utils/smbcacls.c
+ ltconfig
+ configure.in
+
+This patch should only be necessary until these changes are accepted
+back into the 2.2 source tree. Until then, this patch must be applied
+prior to building Samba 2.2 on UnixWare 7. After applying the patch it
+is then necessary to run autoconf again and regenerate the configure file:
+
+ # cd ../../../source
+ # autoconf
+
+To produce the pkgadd installable datastream simply type (in this directory):
+ # ./Makepkg
+
+The resultant samba.pkg should reside in the ./dist subdirectory.
+To install from this pkgadd datastream, issue the command (as root):
+
+ # cd dist
+ # pkgadd -d `pwd`/samba.pkg all
+
+Alternately, each of the steps in building the datastream may be performed
+individually by invoking each of the following:
+
+ # ./Configure
+ # ./Compile
+ # ./Install
+ # ./Package
+
+If files are added or deleted from the UnixWare Samba distribution then
+the prototype file in the pkg directory should be appropriately modified.
+The files in the pkg subdirectory were initially created using the mkpkg
+package from SCO Skunkware (see http://www.sco.com/skunkware).
diff --git a/packaging/Caldera/UnixWare/findsmb b/packaging/Caldera/UnixWare/findsmb
new file mode 100755
index 00000000000..04bc6080508
--- /dev/null
+++ b/packaging/Caldera/UnixWare/findsmb
@@ -0,0 +1,145 @@
+#!/usr/bin/perl
+#
+# Prints info on all smb responding machines on a subnet.
+# This script needs to be run on a machine without nmbd running and be
+# run as root to get correct info from WIN95 clients.
+#
+# syntax:
+# findsmb [subnet broadcast address]
+#
+# with no agrument it will list machines on the current subnet
+#
+# There will be a "+" in front of the workgroup name for machines that are
+# local master browsers for that workgroup. There will be an "*" in front
+# of the workgroup name for machines that are the domain master browser for
+# that workgroup.
+#
+
+$SAMBABIN = "/usr/bin";
+
+for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } else {
+ if ($_) {
+ $BCAST = "-B $_";
+ }
+ }
+}
+
+sub ipsort # do numeric sort on last field of IP address
+{
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
+}
+
+# look for all machines that respond to a name lookup
+
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*'|") ||
+ die("Can't run nmblookup '*'.\n");
+
+# get rid of all lines that are not a response IP address,
+# strip everything but IP address and sort by last field in address
+
+@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
+
+# print header info
+
+print "\nIP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
+print "---------------------------------------------------------------------\n";
+
+foreach $ip (@ipaddrs) # loop through each IP address found
+{
+ $ip =~ s/\n//; # strip newline from IP address
+
+# find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -r -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+# get the first <00> name
+
+ @name = grep(/<00>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) { # we have a netbios name
+ if (/GROUP/) { # is it a group name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ } else {
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cure inside name space but not
+# names starting or ending with spaces
+ /(.{1,15})\s+<00>\s+/;
+ $name = $1;
+ }
+
+# do an smbclient command on the netbios name.
+
+ open(SMB,"$SAMBABIN/smbclient -N -L $name -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+# look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+# for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+# Same as before for space and characters
+ /(.{1,15})\s+<00>\s+/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+
+# see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+# line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
+
+ } else { # no netbios name found
+# try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup
+ print "===============================================================\n";
+ print @nmblookup;
+ }
+ print "$ip".' 'x(16-length($ip))."$name\n";
+ }
+}
+
diff --git a/packaging/Caldera/UnixWare/pkg/admin b/packaging/Caldera/UnixWare/pkg/admin
new file mode 100755
index 00000000000..fe2438c770c
--- /dev/null
+++ b/packaging/Caldera/UnixWare/pkg/admin
@@ -0,0 +1 @@
+basedir=ask
diff --git a/packaging/Caldera/UnixWare/pkg/pkginfo b/packaging/Caldera/UnixWare/pkg/pkginfo
new file mode 100755
index 00000000000..c35373d3523
--- /dev/null
+++ b/packaging/Caldera/UnixWare/pkg/pkginfo
@@ -0,0 +1,9 @@
+PKG="samba"
+NAME="Samba - A Windows SMB/CIFS fileserver for UNIX"
+VERSION="2.2.4"
+VENDOR="Caldera"
+EMAIL="rr@caldera.com"
+CATEGORY="skunkware"
+CLASSES="samba"
+ARCH="i386"
+BASEDIR=/
diff --git a/packaging/Caldera/UnixWare/pkg/postinstall b/packaging/Caldera/UnixWare/pkg/postinstall
new file mode 100755
index 00000000000..0cbdfad238e
--- /dev/null
+++ b/packaging/Caldera/UnixWare/pkg/postinstall
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# Create /var/spool/samba, setup swat to be run out of inetd on port 901,
+# initialize the lmhosts file and create the codepage load files
+#
+# Written 10-Aug-1999 by Ronald Joe Record (rr@caldera.com)
+#
+
+SPOOL=/var/spool/samba
+SVCS=/etc/services
+INET=/etc/inetd.conf
+PREFIX=/usr/lib/samba
+LMHOST=/etc/lmhosts
+
+[ -d $SPOOL ] || {
+ mkdir -p $SPOOL
+ chmod 1777 $SPOOL
+}
+
+grep swat $SVCS > /dev/null || {
+ echo "swat 901/tcp # Samba Web Administration Tool " >> $SVCS
+}
+
+grep swat $INET > /dev/null || {
+ echo "swat stream tcp nowait root /usr/lib/samba/sbin/swat swat " >> $INET
+}
+
+if [ -f $LMHOST ]
+then
+ grep localhost $LMHOST > /dev/null || {
+ echo 127.0.0.1 localhost >> $LMHOST
+ }
+else
+ echo 127.0.0.1 localhost > $LMHOST
+fi
+
+#
+# Build codepage load files
+#
+
+cd ${PREFIX}/lib/codepages
+for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+do
+ ${PREFIX}/bin/make_smbcodepage c $i \
+ ${PREFIX}/lib/codepages/src/codepage_def.$i \
+ ${PREFIX}/lib/codepages/codepage.$i
+done
+for i in 437 737 850 852 861 866 932 936 949 950 \
+ ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+do
+ ${PREFIX}/bin/make_unicodemap $i \
+ ${PREFIX}/lib/codepages/src/CP$i.TXT \
+ ${PREFIX}/lib/codepages/unicode_map.$i
+done
+
+kill -1 `ps -e | grep inetd | awk ' { print $1 } '`
diff --git a/packaging/Caldera/UnixWare/pkg/postremove b/packaging/Caldera/UnixWare/pkg/postremove
new file mode 100755
index 00000000000..dc81d6fa85f
--- /dev/null
+++ b/packaging/Caldera/UnixWare/pkg/postremove
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Remove /var/spool/samba and delete inetd entries for swat
+#
+
+SPOOL=/var/spool/samba
+SVCS=/etc/services
+INET=/etc/inetd.conf
+
+[ -d $SPOOL ] && {
+ rm -rf $SPOOL
+}
+
+grep swat $SVCS > /dev/null && {
+ B=`basename $SVCS`
+ T=$B$$
+ grep -v swat $SVCS > /tmp/$T
+ cp /tmp/$T $SVCS
+ rm -f /tmp/$T
+}
+
+grep swat $INET > /dev/null || {
+ B=`basename $INET`
+ T=$B$$
+ grep -v swat $INET > /tmp/$T
+ cp /tmp/$T $INET
+ rm -f /tmp/$T
+}
+
+kill -1 `ps -e | grep inetd | awk ' { print $1 } '`
diff --git a/packaging/Caldera/UnixWare/pkg/prototype b/packaging/Caldera/UnixWare/pkg/prototype
new file mode 100755
index 00000000000..5424e2cfc9e
--- /dev/null
+++ b/packaging/Caldera/UnixWare/pkg/prototype
@@ -0,0 +1,303 @@
+i admin=admin
+i pkginfo=pkginfo
+i postinstall=postinstall
+i postremove=postremove
+
+d samba etc 0755 root sys
+d samba etc/init.d 0755 root sys
+f samba etc/init.d/samba 0755 root sys
+f samba etc/smbusers 0644 root sys
+d samba usr 0755 root sys
+d samba usr/lib 0755 root sys
+d samba usr/lib/samba 0755 root sys
+d samba usr/lib/samba/bin 0755 root sys
+f samba usr/lib/samba/bin/nmblookup 0755 root sys
+f samba usr/lib/samba/bin/smbclient 0755 root sys
+f samba usr/lib/samba/bin/smbpasswd 0755 root sys
+f samba usr/lib/samba/bin/smbstatus 0755 root sys
+f samba usr/lib/samba/bin/testparm 0755 root sys
+f samba usr/lib/samba/bin/testprns 0755 root sys
+f samba usr/lib/samba/bin/make_smbcodepage 0755 root sys
+f samba usr/lib/samba/bin/make_unicodemap 0755 root sys
+f samba usr/lib/samba/bin/make_printerdef 0755 root sys
+f samba usr/lib/samba/bin/rpcclient 0755 root sys
+f samba usr/lib/samba/bin/smbspool 0755 root sys
+f samba usr/lib/samba/bin/mksmbpasswd.sh 0755 root sys
+f samba usr/lib/samba/bin/smbtar 0755 root sys
+f samba usr/lib/samba/bin/smbprint 0755 root sys
+f samba usr/lib/samba/bin/findsmb 0755 root sys
+f samba usr/lib/samba/bin/smbadduser 0755 root sys
+d samba usr/lib/samba/sbin 0755 root sys
+f samba usr/lib/samba/sbin/smbd 0755 root sys
+f samba usr/lib/samba/sbin/nmbd 0755 root sys
+f samba usr/lib/samba/sbin/swat 0755 root sys
+f samba usr/lib/samba/sbin/debug2html 0755 root sys
+f samba usr/lib/samba/sbin/smbtorture 0755 root sys
+f samba usr/lib/samba/sbin/smbfilter 0755 root sys
+f samba usr/lib/samba/sbin/locktest2 0755 root sys
+f samba usr/lib/samba/sbin/masktest 0755 root sys
+d samba usr/lib/samba/swat 0755 root sys
+d samba usr/lib/samba/swat/using_samba 0755 root sys
+d samba usr/lib/samba/swat/using_samba/gifs 0755 root sys
+f samba usr/lib/samba/swat/using_samba/gifs/index.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/gifs/samba.s.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/gifs/txthome.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/gifs/txtnexta.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/gifs/txtpreva.gif 0644 root sys
+d samba usr/lib/samba/swat/using_samba/figs 0755 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0101.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0102.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0103.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0104.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0105.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0106.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0107.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0108.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0109.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0110.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0111.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0112.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0113.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0114.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0201.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0202.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0203.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0204.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0301.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0302.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0303.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0304.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0305.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0306.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0307.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0308.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0309.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0310.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0311.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0312.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0313.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0314.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0315.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0316.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0317.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0318.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0319.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0320.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0321.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0322.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0323.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0324.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0325.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0326.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0327.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0328.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0401.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0402.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0403.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0404.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0405.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0406.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0407.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0501.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0502.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0503.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0504.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0505.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0506.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0507.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0508.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0601.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0602.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0603.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0604.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0605.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0606.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0701.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0702.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0703.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0704.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0705.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0706.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0707.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0708.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0709.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0801.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0802.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0803.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0804.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0805.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0901.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0902.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0903.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0904.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.0905.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.aa01.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.ab01.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/figs/sam.ab02.gif 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appa_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appa_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appa_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appa_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appa_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appb_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appb_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appb_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appc_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appd_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appe_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/appf_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_06.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_07.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch01_08.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch02_06.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch03_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch03_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch03_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_06.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_07.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch04_08.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch05_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch05_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch05_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch05_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch05_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch06_06.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch07_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch07_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch07_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_04.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_05.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_06.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch08_07.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch09_01.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch09_02.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/ch09_03.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/index.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/inx.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/licenseinfo.html 0644 root sys
+f samba usr/lib/samba/swat/using_samba/this_edition.html 0644 root sys
+d samba usr/lib/samba/swat/images 0755 root sys
+f samba usr/lib/samba/swat/images/globals.gif 0644 root sys
+f samba usr/lib/samba/swat/images/home.gif 0644 root sys
+f samba usr/lib/samba/swat/images/passwd.gif 0644 root sys
+f samba usr/lib/samba/swat/images/printers.gif 0644 root sys
+f samba usr/lib/samba/swat/images/samba.gif 0644 root sys
+f samba usr/lib/samba/swat/images/shares.gif 0644 root sys
+f samba usr/lib/samba/swat/images/status.gif 0644 root sys
+f samba usr/lib/samba/swat/images/viewconfig.gif 0644 root sys
+d samba usr/lib/samba/swat/help 0755 root sys
+f samba usr/lib/samba/swat/help/welcome.html 0644 root sys
+f samba usr/lib/samba/swat/help/DOMAIN_MEMBER.html 0644 root sys
+f samba usr/lib/samba/swat/help/NT_Security.html 0644 root sys
+f samba usr/lib/samba/swat/help/findsmb.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/lmhosts.5.html 0644 root sys
+f samba usr/lib/samba/swat/help/make_smbcodepage.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/nmbd.8.html 0644 root sys
+f samba usr/lib/samba/swat/help/nmblookup.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/rpcclient.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/samba.7.html 0644 root sys
+f samba usr/lib/samba/swat/help/smb.conf.5.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbclient.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbcontrol.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbd.8.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbpasswd.5.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbpasswd.8.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbsh.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbspool.8.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbstatus.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/smbtar.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/swat.8.html 0644 root sys
+f samba usr/lib/samba/swat/help/testparm.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/testprns.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/wbinfo.1.html 0644 root sys
+f samba usr/lib/samba/swat/help/winbindd.8.html 0644 root sys
+d samba usr/lib/samba/swat/include 0755 root sys
+f samba usr/lib/samba/swat/include/footer.html 0644 root sys
+f samba usr/lib/samba/swat/include/header.html 0644 root sys
+f samba usr/lib/samba/swat/README 0644 root sys
+d samba usr/lib/samba/man 0755 root sys
+d samba usr/lib/samba/man/man1 0755 root sys
+f samba usr/lib/samba/man/man1/findsmb.1 0644 root sys
+f samba usr/lib/samba/man/man1/make_smbcodepage.1 0644 root sys
+f samba usr/lib/samba/man/man1/make_unicodemap.1 0644 root sys
+f samba usr/lib/samba/man/man1/nmblookup.1 0644 root sys
+f samba usr/lib/samba/man/man1/smbclient.1 0644 root sys
+f samba usr/lib/samba/man/man1/smbcontrol.1 0644 root sys
+f samba usr/lib/samba/man/man1/smbsh.1 0644 root sys
+f samba usr/lib/samba/man/man1/smbstatus.1 0644 root sys
+f samba usr/lib/samba/man/man1/smbtar.1 0644 root sys
+f samba usr/lib/samba/man/man1/testparm.1 0644 root sys
+f samba usr/lib/samba/man/man1/testprns.1 0644 root sys
+f samba usr/lib/samba/man/man1/wbinfo.1 0644 root sys
+d samba usr/lib/samba/man/man5 0755 root sys
+f samba usr/lib/samba/man/man5/smb.conf.5 0644 root sys
+f samba usr/lib/samba/man/man5/lmhosts.5 0644 root sys
+f samba usr/lib/samba/man/man5/smbpasswd.5 0644 root sys
+d samba usr/lib/samba/man/man7 0755 root sys
+f samba usr/lib/samba/man/man7/samba.7 0644 root sys
+d samba usr/lib/samba/man/man8 0755 root sys
+f samba usr/lib/samba/man/man8/smbd.8 0644 root sys
+f samba usr/lib/samba/man/man8/nmbd.8 0644 root sys
+f samba usr/lib/samba/man/man8/smbpasswd.8 0644 root sys
+f samba usr/lib/samba/man/man8/swat.8 0644 root sys
+f samba usr/lib/samba/man/man8/smbmount.8 0644 root sys
+f samba usr/lib/samba/man/man8/smbmnt.8 0644 root sys
+f samba usr/lib/samba/man/man8/smbumount.8 0644 root sys
+d samba usr/lib/samba/var 0755 root sys
+d samba usr/lib/samba/var/locks 0755 root sys
+d samba usr/lib/samba/lib 0755 root sys
+d samba usr/lib/samba/lib/codepages 0755 root sys
+d samba usr/lib/samba/lib/codepages/src 0755 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.437 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.737 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.775 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.850 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.852 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.861 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.866 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.932 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.936 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.949 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.950 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/codepage_def.1251 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP437.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP737.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP850.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP852.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP861.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP866.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP932.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP936.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP949.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CP950.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CPISO8859-1.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CPISO8859-2.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CPISO8859-5.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CPISO8859-7.TXT 0644 root sys
+f samba usr/lib/samba/lib/codepages/src/CPKOI8-R.TXT 0644 root sys
+f samba usr/lib/samba/lib/smb.conf 0644 root sys
+d samba usr/man 0755 root sys
+s samba usr/man/html.1samba=/usr/lib/samba/swat/using_samba
diff --git a/packaging/Caldera/UnixWare/samba-2.2-uw7-prototype.patch b/packaging/Caldera/UnixWare/samba-2.2-uw7-prototype.patch
new file mode 100755
index 00000000000..7678379b063
--- /dev/null
+++ b/packaging/Caldera/UnixWare/samba-2.2-uw7-prototype.patch
@@ -0,0 +1,11 @@
+--- packaging/Caldera/UnixWare/pkg/prototype.00 Tue Jan 9 05:40:47 2001
++++ packaging/Caldera/UnixWare/pkg/prototype Fri Apr 13 14:44:33 2001
+@@ -220,7 +220,7 @@
+ f samba usr/local/samba/swat/help/make_smbcodepage.1.html 0644 root sys
+ f samba usr/local/samba/swat/help/nmbd.8.html 0644 root sys
+ f samba usr/local/samba/swat/help/nmblookup.1.html 0644 root sys
+-f samba usr/local/samba/swat/help/rpcclient.8.html 0644 root sys
++f samba usr/local/samba/swat/help/rpcclient.1.html 0644 root sys
+ f samba usr/local/samba/swat/help/samba-pdc-faq.html 0644 root sys
+ f samba usr/local/samba/swat/help/samba-pdc-howto.html 0644 root sys
+ f samba usr/local/samba/swat/help/samba.7.html 0644 root sys
diff --git a/packaging/Caldera/UnixWare/samba-2.2-uw7.patch b/packaging/Caldera/UnixWare/samba-2.2-uw7.patch
new file mode 100755
index 00000000000..c4412e542ee
--- /dev/null
+++ b/packaging/Caldera/UnixWare/samba-2.2-uw7.patch
@@ -0,0 +1,200 @@
+--- smbwrapper/smbw.c.orig Mon Jan 8 12:37:48 2001
++++ smbwrapper/smbw.c Fri Apr 13 13:09:00 2001
+@@ -22,6 +22,11 @@
+ #include "includes.h"
+ #include "realcalls.h"
+
++#if defined(__USLC__) && defined(HAVE_SYS_ACL_H)
++#define GETACL ACL_GET
++#define GETACLCNT ACL_CNT
++#endif
++
+ pstring smbw_cwd;
+
+ static struct smbw_file *smbw_files;
+@@ -1462,7 +1467,11 @@
+ /*****************************************************
+ say no to acls
+ *******************************************************/
++#if defined(__USLC__)
++ int smbw_acl(const char *pathp, int cmd, int nentries, void *aclbufp)
++#else
+ int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
++#endif
+ {
+ if (cmd == GETACL || cmd == GETACLCNT) return 0;
+ errno = ENOSYS;
+@@ -1474,7 +1483,11 @@
+ /*****************************************************
+ say no to acls
+ *******************************************************/
++#if defined(__USLC__)
++ int smbw_facl(int fd, int cmd, int nentries, void *aclbufp)
++#else
+ int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
++#endif
+ {
+ if (cmd == GETACL || cmd == GETACLCNT) return 0;
+ errno = ENOSYS;
+--- tdb/tdb.c.orig Fri Apr 13 05:58:34 2001
++++ tdb/tdb.c Fri Apr 13 13:34:18 2001
+@@ -856,7 +856,11 @@
+ {
+ TDB_DATA key, dbuf;
+ struct list_struct rec;
++#if defined(__USLC__)
++ struct tdb_traverse_lock tl = { (struct tdb_traverse_lock *)0, 0, 0 };
++#else
+ struct tdb_traverse_lock tl = { NULL, 0, 0 };
++#endif
+ int ret, count = 0;
+
+ /* This was in the initializaton, above, but the IRIX compiler
+--- utils/torture.c.orig Fri Mar 30 13:53:26 2001
++++ utils/torture.c Fri Apr 13 13:09:01 2001
+@@ -2703,7 +2703,11 @@
+
+ dbf = stdout;
+
++#if defined(__USLC__)
++ setbuf(stdout, NULL);
++#else
+ setbuffer(stdout, NULL, 0);
++#endif
+
+ charset_initialise();
+
+--- utils/locktest.c.orig Fri Sep 29 13:18:14 2000
++++ utils/locktest.c Fri Apr 13 13:09:01 2001
+@@ -34,7 +34,7 @@
+
+ #define FILENAME "\\locktest.dat"
+ #define LOCKRANGE 1000
+-#define LOCKBASE 0;
++#define LOCKBASE 0
+
+ /*
+ #define LOCKBASE (0x40000000 - 50)
+@@ -59,6 +59,7 @@
+ char needed;
+ };
+
++#ifndef __USLC__
+ static struct record preset[] = {
+ #if 0
+ {36, 5, 0, 0, 0, 8, 1},
+@@ -67,6 +68,7 @@
+ {99, 11, 0, 0, 7, 1, 1},
+ #endif
+ };
++#endif /* __USLC__) */
+
+ static struct record *recorded;
+
+@@ -378,20 +380,23 @@
+ recorded = (struct record *)malloc(sizeof(*recorded) * numops);
+
+ for (n=0; n<numops; n++) {
++#ifndef __USLC__
+ if (n < sizeof(preset) / sizeof(preset[0])) {
+ recorded[n] = preset[n];
+ } else {
++#endif
+ recorded[n].conn = random() % NCONNECTIONS;
+ recorded[n].f = random() % NFILES;
+ recorded[n].start = LOCKBASE + ((unsigned)random() % (LOCKRANGE-1));
+- recorded[n].len = 1 +
+- random() % (LOCKRANGE-(recorded[n].start-LOCKBASE));
++ recorded[n].len = 1 + random() % (LOCKRANGE-(recorded[n].start-LOCKBASE));
+ recorded[n].start *= RANGE_MULTIPLE;
+ recorded[n].len *= RANGE_MULTIPLE;
+ recorded[n].r1 = random() % 100;
+ recorded[n].r2 = random() % 100;
+ recorded[n].needed = True;
++#ifndef __USLC__
+ }
++#endif
+ }
+
+ reconnect(cli, fnum, share);
+@@ -484,7 +489,11 @@
+ int seed, server;
+ static pstring servicesf = CONFIGFILE;
+
++#if defined(__USLC__)
++ setvbuf(stdout,NULL,_IOLBF,0); /* line buffered */
++#else
+ setlinebuf(stdout);
++#endif
+
+ dbf = stderr;
+
+--- utils/locktest2.c.orig Tue Jun 13 08:47:44 2000
++++ utils/locktest2.c Fri Apr 13 13:09:01 2001
+@@ -540,7 +540,11 @@
+ int seed;
+ static pstring servicesf = CONFIGFILE;
+
++#if defined(__USLC__)
++ setvbuf(stdout,NULL,_IOLBF,0); /* line buffered */
++#else
+ setlinebuf(stdout);
++#endif
+
+ dbf = stderr;
+
+--- utils/masktest.c.orig Fri May 26 17:28:02 2000
++++ utils/masktest.c Fri Apr 13 13:09:01 2001
+@@ -310,7 +310,11 @@
+ int seed;
+ static pstring servicesf = CONFIGFILE;
+
++#if defined(__USLC__)
++ setvbuf(stdout,NULL,_IOLBF,0); /* line buffered */
++#else
+ setlinebuf(stdout);
++#endif
+
+ dbf = stderr;
+
+--- utils/smbcacls.c.orig Thu Apr 12 21:09:39 2001
++++ utils/smbcacls.c Fri Apr 13 13:09:01 2001
+@@ -824,7 +824,11 @@
+
+ ctx=talloc_init();
+
++#if defined(__USLC__)
++ setvbuf(stdout,NULL,_IOLBF,0); /* line buffered */
++#else
+ setlinebuf(stdout);
++#endif
+
+ dbf = stderr;
+
+--- ltconfig.orig Mon Mar 13 15:20:00 2000
++++ ltconfig Fri Apr 13 13:09:01 2001
+@@ -1482,9 +1482,9 @@
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
++ archive_cmds='$LD -G${allow_undefined_flag} -h $rpath/$soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
++ $LD -G${allow_undefined_flag} -M $lib.exp -h $rpath/$soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+--- configure.in.orig Fri Apr 13 11:33:18 2001
++++ configure.in Fri Apr 13 13:09:01 2001
+@@ -727,6 +727,10 @@
+ *sysv5*)
+ if [ test "$GCC" != yes ]; then
+ AC_DEFINE(HAVE_MEMSET)
++ PICFLAG="-KPIC"
++ ac_cv_prog_cc_fpic=no
++ ac_cv_prog_cc_Kpic=no
++ ac_cv_prog_cc_KPIC=yes
+ fi
+ LDSHFLAGS="-G"
+ ;;
diff --git a/packaging/Caldera/UnixWare/smb.conf b/packaging/Caldera/UnixWare/smb.conf
new file mode 100755
index 00000000000..e3b3ae9e693
--- /dev/null
+++ b/packaging/Caldera/UnixWare/smb.conf
@@ -0,0 +1,291 @@
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not many any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+# workgroup = NT-Domain-Name or Workgroup-Name
+ workgroup = MYGROUP
+
+# server string is the equivalent of the NT Description field
+ server string = Samba Server
+
+# This option is important for security. It allows you to restrict
+# connections to machines which are on your local network. The
+# following example restricts access to two C class networks and
+# the "loopback" interface. For more examples of the syntax see
+# the smb.conf man page
+; hosts allow = 192.168.1. 192.168.2. 127.
+
+# if you want to automatically load your printer list rather
+# than setting them up individually then you'll need this
+ printcap name = lpstat
+ load printers = yes
+
+# It should not be necessary to spell out the print system type unless
+# yours is non-standard. Currently supported print systems include:
+# bsd, sysv, plp, lprng, aix, hpux, qnx
+ printing = sysv
+
+# Uncomment this if you want a guest account, you must add this to /etc/passwd
+# otherwise the user "nobody" is used
+; guest account = pcguest
+
+# this tells Samba to use a separate log file for each machine
+# that connects
+ log file = /usr/local/samba/var/log.%m
+
+# Put a capping on the size of the log files (in Kb).
+ max log size = 50
+
+# Security mode. Most people will want user level security. See
+# security_level.txt for details.
+ security = user
+# Use password server option only with security = server
+; password server = <NT-Server-Name>
+
+# Password Level allows matching of _n_ characters of the password for
+# all combinations of upper and lower case.
+; password level = 8
+; username level = 8
+
+# You may wish to use password encryption. Please read
+# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+# Do not enable this option unless you have read those documents
+; encrypt passwords = yes
+; smb passwd file = /etc/smbpasswd
+
+# The following are needed to allow password changing from Windows to
+# update the Linux sytsem password also.
+# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
+# NOTE2: You do NOT need these to allow workstations to change only
+# the encrypted SMB passwords. They allow the Unix password
+# to be kept in sync with the SMB password.
+; unix password sync = Yes
+; passwd program = /usr/bin/passwd %u
+; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
+
+# Unix users can map to different SMB User names
+; username map = /etc/smbusers
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+; include = /etc/smb.conf.%m
+
+# Most people will find that this option gives better performance.
+# See speed.txt and the manual pages for details
+ socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+
+# Configure Samba to use multiple interfaces
+# If you have multiple network interfaces then you must list them
+# here. See the man page for details.
+; interfaces = 192.168.12.2/24 192.168.13.2/24
+
+# Configure remote browse list synchronisation here
+# request announcement to, or browse list sync from:
+# a specific host or from / to a whole subnet (see below)
+; remote browse sync = 192.168.3.25 192.168.5.255
+# Cause this host to announce itself to local subnets here
+; remote announce = 192.168.1.255 192.168.2.44
+
+# Browser Control Options:
+# set local master to no if you don't want Samba to become a master
+# browser on your network. Otherwise the normal election rules apply
+; local master = no
+
+# OS Level determines the precedence of this server in master browser
+# elections. The default value should be reasonable
+; os level = 33
+
+# Domain Master specifies Samba to be the Domain Master Browser. This
+# allows Samba to collate browse lists between subnets. Don't use this
+# if you already have a Windows NT domain controller doing this job
+; domain master = yes
+
+# Preferred Master causes Samba to force a local browser election on startup
+# and gives it a slightly higher chance of winning the election
+; preferred master = yes
+
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = <NT-Domain-Controller-SMBName>
+
+# Enable this if you want Samba to be a domain logon server for
+# Windows95 workstations.
+; domain logons = yes
+
+# if you enable domain logons then you may want a per-machine or
+# per user logon script
+# run a specific logon batch file per workstation (machine)
+; logon script = %m.bat
+# run a specific logon batch file per username
+; logon script = %U.bat
+
+# Where to store roving profiles (only for Win95 and WinNT)
+# %L substitutes for this servers netbios name, %U is username
+# You must uncomment the [Profiles] share below
+; logon path = \\%L\Profiles\%U
+
+# All NetBIOS names must be resolved to IP Addresses
+# 'Name Resolve Order' allows the named resolution mechanism to be specified
+# the default order is "host lmhosts wins bcast". "host" means use the unix
+# system gethostbyname() function call that will use either /etc/hosts OR
+# DNS or NIS depending on the settings of /etc/host.config, /etc/nsswitch.conf
+# and the /etc/resolv.conf file. "host" therefore is system configuration
+# dependant. This parameter is most often of use to prevent DNS lookups
+# in order to resolve NetBIOS names to IP Addresses. Use with care!
+# The example below excludes use of name resolution for machines that are NOT
+# on the local network segment
+# - OR - are not deliberately to be known via lmhosts or via WINS.
+; name resolve order = wins lmhosts bcast
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = yes
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = w.x.y.z
+
+# WINS Proxy - Tells Samba to answer name resolution queries on
+# behalf of a non WINS capable client, for this to work there must be
+# at least one WINS Server on the network. The default is NO.
+; wins proxy = yes
+
+# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+# via DNS nslookups. The built-in default for versions 1.9.17 is yes,
+# this has been changed in version 1.9.18 to no.
+ dns proxy = no
+
+# Case Preservation can be handy - system default is _no_
+# NOTE: These can be set on a per share basis
+; preserve case = no
+; short preserve case = no
+# Default case is normally upper case for all DOS files
+; default case = lower
+# Be very careful with case sensitivity - it can break things!
+; case sensitive = no
+
+#============================ Share Definitions ==============================
+[homes]
+ comment = Home Directories
+ browseable = no
+ writable = yes
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+; [netlogon]
+; comment = Network Logon Service
+; path = /home/netlogon
+; guest ok = yes
+; writable = no
+; share modes = no
+
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+;[Profiles]
+; path = /home/profiles
+; browseable = no
+; guest ok = yes
+
+
+# NOTE: If you have a BSD-style print system there is no need to
+# specifically define each individual printer
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+# Set public = yes to allow user 'guest account' to print
+ guest ok = no
+ writable = no
+ printable = yes
+
+# This one is useful for people to share files
+;[tmp]
+; comment = Temporary file space
+; path = /tmp
+; read only = no
+; public = yes
+
+# A publicly accessible directory, but read only, except for people in
+# the "staff" group
+;[public]
+; comment = Public Stuff
+; path = /home/samba
+; public = yes
+; writable = yes
+; printable = no
+; write list = @staff
+
+# Other examples.
+#
+# A private printer, usable only by fred. Spool data will be placed in fred's
+# home directory. Note that fred must have write access to the spool directory,
+# wherever it is.
+;[fredsprn]
+; comment = Fred's Printer
+; valid users = fred
+; path = /homes/fred
+; printer = freds_printer
+; public = no
+; writable = no
+; printable = yes
+
+# A private directory, usable only by fred. Note that fred requires write
+# access to the directory.
+;[fredsdir]
+; comment = Fred's Service
+; path = /usr/somewhere/private
+; valid users = fred
+; public = no
+; writable = yes
+; printable = no
+
+# a service which has a different directory for each machine that connects
+# this allows you to tailor configurations to incoming machines. You could
+# also use the %u option to tailor it by user name.
+# The %m gets replaced with the machine name that is connecting.
+;[pchome]
+; comment = PC Directories
+; path = /usr/pc/%m
+; public = no
+; writable = yes
+
+# A publicly accessible directory, read/write to all users. Note that all files
+# created in the directory by users will be owned by the default user, so
+# any user with access can delete any other user's files. Obviously this
+# directory must be writable by the default user. Another user could of course
+# be specified, in which case all files would be owned by that user instead.
+;[public]
+; path = /usr/somewhere/else/public
+; public = yes
+; only guest = yes
+; writable = yes
+; printable = no
+
+# The following two entries demonstrate how to share a directory so that two
+# users can place files there that will be owned by the specific users. In this
+# setup, the directory should be writable by both users and should have the
+# sticky bit set on it to prevent abuse. Obviously this could be extended to
+# as many users as required.
+;[myshare]
+; comment = Mary's and Fred's stuff
+; path = /usr/somewhere/shared
+; valid users = mary fred
+; public = no
+; writable = yes
+; printable = no
+; create mask = 0765
+
+
diff --git a/packaging/Caldera/UnixWare/smb.init b/packaging/Caldera/UnixWare/smb.init
new file mode 100755
index 00000000000..ce6c6fa4b38
--- /dev/null
+++ b/packaging/Caldera/UnixWare/smb.init
@@ -0,0 +1,76 @@
+#!/bin/sh
+#ident "@(#)samba.server 1.0 96/06/19 TK" /* SVr4.0 1.1.13.1*/
+#
+# Please send info on modifications to knuutila@cs.utu.fi
+#
+# This file should have uid root, gid sys and chmod 744
+#
+# Modified 17-Jul-99 by Ron Record (rr@sco.com) for use in SCO Skunkware
+#
+
+SAMBADIR=/usr/local/samba
+RCSCRIPT=/etc/rc2.d/S99samba
+
+if [ ! -d /usr/bin ]
+then # /usr not mounted
+ exit
+fi
+
+killproc() { # kill the named process(es)
+ if [ -f $SAMBADIR/var/locks/$1.pid ]
+ then
+ kill `cat $SAMBADIR/var/locks/$1.pid`
+ else
+ pid=`/usr/bin/ps -e |
+ /usr/bin/grep $1 |
+ /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
+ [ "$pid" != "" ] && kill $pid
+ fi
+}
+
+start() {
+#
+# Edit these lines to suit your installation (paths, workgroup, host)
+#
+ $SAMBADIR/sbin/smbd -D -s $SAMBADIR/lib/smb.conf
+ $SAMBADIR/sbin/nmbd -D -s $SAMBADIR/lib/smb.conf
+}
+
+stop() {
+ killproc nmbd
+ killproc smbd
+}
+
+# Start/stop processes required for samba server
+
+case "$1" in
+
+'start')
+ start
+ ;;
+'stop')
+ stop
+ ;;
+'restart')
+ stop
+ start
+ ;;
+'enable')
+ if [ -h $RCSCRIPT ] ; then
+ echo "Samba is already enabled."
+ else
+ echo "Enabling Samba ... \c"
+ rm -f $RCSCRIPT
+ ln -s /etc/init.d/samba $RCSCRIPT
+ echo "Done"
+ fi
+ ;;
+'disable')
+ echo "Disabling Samba ... \c"
+ rm -f $RCSCRIPT
+ echo "Done"
+ ;;
+*)
+ echo "Usage: /etc/init.d/samba { start | stop | restart | enable | disable }"
+ ;;
+esac
diff --git a/source/smbadduser.in b/packaging/Caldera/UnixWare/smbadduser
index 05da7de08ee..2f38bf28f1a 100644..100755
--- a/source/smbadduser.in
+++ b/packaging/Caldera/UnixWare/smbadduser
@@ -2,19 +2,11 @@
#
# smbadduser - Written by Mike Zakharoff
#
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-LIBDIR=@libdir@
-PRIVATEDIR=@privatedir@
-CONFIGDIR=@configdir@
-
unalias *
-set path = ($path /usr/local/samba/bin)
-
-set smbpasswd = $PRIVATEDIR/smbpasswd
-set user_map = $CONFIGDIR/users.map
+set path = ($path)
+set smbpasswd = /etc/smbpasswd
+set user_map = /etc/smbusers
#
# Set to site specific passwd command
#
@@ -61,7 +53,9 @@ foreach one ($argv)
endif
echo "Adding: $unix to $smbpasswd"
- /usr/bin/smbpasswd -a -n $unix
+ eval $passwd | \
+ awk -F: '$1==USR { \
+ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
if ($unix != $ntid) then
echo "Adding: {$unix = $ntid} to $user_map"
echo "$unix = $ntid" >> $user_map
diff --git a/packaging/Caldera/UnixWare/smbprint b/packaging/Caldera/UnixWare/smbprint
new file mode 100755
index 00000000000..ec083eede62
--- /dev/null
+++ b/packaging/Caldera/UnixWare/smbprint
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# This script is an input filter for printcap printing on a unix machine. It
+# uses the smbclient program to print the file to the specified smb-based
+# server and service.
+# For example you could have a printcap entry like this
+#
+# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
+#
+# which would create a unix printer called "smb" that will print via this
+# script. You will need to create the spool directory /usr/spool/smb with
+# appropriate permissions and ownerships for your system.
+
+# Set these to the server and service you wish to print to
+# In this example I have a WfWg PC called "lapland" that has a printer
+# exported called "printer" with no password.
+
+#
+# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
+# so that the server, service, and password can be read from
+# a /var/spool/lpd/PRINTNAME/.config file.
+#
+# In order for this to work the /etc/printcap entry must include an
+# accounting file (af=...):
+#
+# cdcolour:\
+# :cm=CD IBM Colorjet on 6th:\
+# :sd=/var/spool/lpd/cdcolour:\
+# :af=/var/spool/lpd/cdcolour/acct:\
+# :if=/usr/local/etc/smbprint:\
+# :mx=0:\
+# :lp=/dev/null:
+#
+# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
+# server=PC_SERVER
+# service=PR_SHARENAME
+# password="password"
+#
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
+# password=""
+
+#
+# Debugging log file, change to /dev/null if you like.
+#
+# logfile=/tmp/smb-print.log
+logfile=/dev/null
+
+
+#
+# The last parameter to the filter is the accounting file name.
+# Extract the directory name from the file name.
+# Concat this with /.config to get the config file.
+#
+eval acct_file=\${$#}
+spool_dir=`dirname $acct_file`
+config_file=$spool_dir/.config
+
+# Should read the following variables set in the config file:
+# server
+# service
+# password
+eval `cat $config_file`
+
+#
+# Some debugging help, change the >> to > if you want to same space.
+#
+echo "server $server, service $service" >> $logfile
+
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+# echo translate
+ echo "print -"
+ cat
+) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/Caldera/UnixWare/smbusers b/packaging/Caldera/UnixWare/smbusers
new file mode 100755
index 00000000000..ae3389f53f8
--- /dev/null
+++ b/packaging/Caldera/UnixWare/smbusers
@@ -0,0 +1,3 @@
+# Unix_name = SMB_name1 SMB_name2 ...
+root = administrator admin
+nobody = guest pcguest smbguest
diff --git a/packaging/Debian/README b/packaging/Debian/README
index 95c75d5fc51..d6250c12095 100644
--- a/packaging/Debian/README
+++ b/packaging/Debian/README
@@ -1,22 +1,12 @@
Building Samba Packages for Debian GNU/Linux
--------------------------------------------
-Building Debian packages is not as hard as some people might think.
-The following instructions will allow you to build your own Samba
-Debian packages. These instructions and the files in packaging/Debian/
-are current as of Samba 3.0.0, and allow you to build Debian packages
-for Debian unstable (so you need some development packages available
-only in Debian unstable.) If you are using something newer than 3.0.0
-you might want to try to follow the instructions to see if patches
-apply cleanly. If some patches don't apply cleanly please e-mail
-samba@packages.debian.org since we might have fixed patches that we have
-not yet integrated into upstream Samba.
-
-We try to maintain as much compatibility with previous releases
-of Debian as possible, so it is possible that the files in
-packaging/Debian/ can also be used to build Samba Debian packages for
-other Debian releases. However, sometimes this is just not possible
-because we need to use stuff that is only available on Debian unstable.
+Building Debian packages is not as hard as some people might think. The
+following instructions will allow you to build your own Samba Debian
+packages. These instructions, and the files in packaging/Debian/, are
+current as of Samba 2.2.6, and should allow you to build Debian packages
+for Debian Potato (2.2), Debian Woody (3.0), and Debian unstable as of
+the date Samba 2.2.6 was released.
Instructions
------------
@@ -32,29 +22,19 @@ these instructions:
to the normal Debian development packages -- dpkg-dev, libc6-dev,
devscripts, etc.):
- autoconf
debhelper
libpam0g-dev
libreadline4-dev
libcupsys2-dev
- libacl1-dev, libacl1 (>= 2.2.11-1)
- libkrb5-dev
- libldap2-dev
- po-debconf
- python2.3-dev
+ autoconf
- Notes regarding the packages required to build Samba Debian packages:
+ Notes about the packages required to build Samba Debian packages:
* The libcupsys2-dev is not available in Debian Potato (Debian 2.2).
- That's fine; the configure script won't detect CUPS support and the
- resulting binaries won't support CUPS.
-
- * The list above is current as of samba-3.0.0rc2, but it can get
- out of date. The best way to check what packages are required to
- build the samba packages on Debian is to look for the Build-Depends:
- field in the file debian/control.
+ That's fine; the configure script won't detect CUPS support and the
+ resulting binaries won't support CUPS.
-1) cd samba[-<version>]. For example, "cd samba-3.0.0rc2".
+1) cd samba[-<version>]. For example, "cd samba-2.2.6".
2) cp -a packaging/Debian/debian/ debian
It's important that you copy instead of symlink because the build
tools in Potato have a problem that prevents the build to work with
@@ -63,8 +43,9 @@ devscripts, etc.):
Debian version numbers! Don't complain later if you can't upgrade
to official versions of the Samba packages for Debian.)
- Edit the changelog and make sure the version is right. For example,
- for Samba 3.0.0beta3, the version number should something like
- 3.0.0beta3-0.1.
+ for Samba 2.2.6, the version number should something like 2.2.6-0.1
+ (use a number less than 1 like 0.1, 0.2, etc. so there is no conflict
+ with future upgrades to the official Debian packages.)
4) Run 'debian/rules binary'.
- It is better that you prefix the above command with 'fakeroot'.
If you have problems you might try building as root.
diff --git a/packaging/Debian/debian/README.build-upstream b/packaging/Debian/debian/README.build-upstream
index 95c75d5fc51..d6250c12095 100644
--- a/packaging/Debian/debian/README.build-upstream
+++ b/packaging/Debian/debian/README.build-upstream
@@ -1,22 +1,12 @@
Building Samba Packages for Debian GNU/Linux
--------------------------------------------
-Building Debian packages is not as hard as some people might think.
-The following instructions will allow you to build your own Samba
-Debian packages. These instructions and the files in packaging/Debian/
-are current as of Samba 3.0.0, and allow you to build Debian packages
-for Debian unstable (so you need some development packages available
-only in Debian unstable.) If you are using something newer than 3.0.0
-you might want to try to follow the instructions to see if patches
-apply cleanly. If some patches don't apply cleanly please e-mail
-samba@packages.debian.org since we might have fixed patches that we have
-not yet integrated into upstream Samba.
-
-We try to maintain as much compatibility with previous releases
-of Debian as possible, so it is possible that the files in
-packaging/Debian/ can also be used to build Samba Debian packages for
-other Debian releases. However, sometimes this is just not possible
-because we need to use stuff that is only available on Debian unstable.
+Building Debian packages is not as hard as some people might think. The
+following instructions will allow you to build your own Samba Debian
+packages. These instructions, and the files in packaging/Debian/, are
+current as of Samba 2.2.6, and should allow you to build Debian packages
+for Debian Potato (2.2), Debian Woody (3.0), and Debian unstable as of
+the date Samba 2.2.6 was released.
Instructions
------------
@@ -32,29 +22,19 @@ these instructions:
to the normal Debian development packages -- dpkg-dev, libc6-dev,
devscripts, etc.):
- autoconf
debhelper
libpam0g-dev
libreadline4-dev
libcupsys2-dev
- libacl1-dev, libacl1 (>= 2.2.11-1)
- libkrb5-dev
- libldap2-dev
- po-debconf
- python2.3-dev
+ autoconf
- Notes regarding the packages required to build Samba Debian packages:
+ Notes about the packages required to build Samba Debian packages:
* The libcupsys2-dev is not available in Debian Potato (Debian 2.2).
- That's fine; the configure script won't detect CUPS support and the
- resulting binaries won't support CUPS.
-
- * The list above is current as of samba-3.0.0rc2, but it can get
- out of date. The best way to check what packages are required to
- build the samba packages on Debian is to look for the Build-Depends:
- field in the file debian/control.
+ That's fine; the configure script won't detect CUPS support and the
+ resulting binaries won't support CUPS.
-1) cd samba[-<version>]. For example, "cd samba-3.0.0rc2".
+1) cd samba[-<version>]. For example, "cd samba-2.2.6".
2) cp -a packaging/Debian/debian/ debian
It's important that you copy instead of symlink because the build
tools in Potato have a problem that prevents the build to work with
@@ -63,8 +43,9 @@ devscripts, etc.):
Debian version numbers! Don't complain later if you can't upgrade
to official versions of the Samba packages for Debian.)
- Edit the changelog and make sure the version is right. For example,
- for Samba 3.0.0beta3, the version number should something like
- 3.0.0beta3-0.1.
+ for Samba 2.2.6, the version number should something like 2.2.6-0.1
+ (use a number less than 1 like 0.1, 0.2, etc. so there is no conflict
+ with future upgrades to the official Debian packages.)
4) Run 'debian/rules binary'.
- It is better that you prefix the above command with 'fakeroot'.
If you have problems you might try building as root.
diff --git a/packaging/Debian/debian/README.debian b/packaging/Debian/debian/README.debian
index 3802e329e53..49c2710b26d 100644
--- a/packaging/Debian/debian/README.debian
+++ b/packaging/Debian/debian/README.debian
@@ -11,9 +11,9 @@ samba and sambades (merged together for longer than we can remember.)
Contents of this README file:
1. Notes
-2. Upgrading from Samba 2.2
-3. Packages Generated from the Samba Sources
-4. Support for NT Domains
+2. Packages Generated from the Samba Sources
+3. Support for NT Domains
+4. Samba and LDAP
5. Reporting bugs
@@ -36,45 +36,7 @@ Contents of this README file:
(/var/log/{nmb,smb} were moved to the new location.
-2. Upgrading from Samba 2.2
----------------------------
-
-Samba 3.0 provides greatly improved support for modern Windows systems,
-including support for Unicode and LDAP. In the process, Samba 3.0
-necessarily also breaks backward compatiblity with past releases. These
-issues are documented herein; if you are aware of other problems related
-to upgrading from Samba 2.2, please let us know at
-<samba@packages.debian.org>.
-
-Samba and LDAP
---------------
-Starting with Samba 2.999+3.0cvs20020723-1 we are building Samba with
-LDAP support. However, the LDAP schema for Samba 3.0 differs
-substantially from the schema used by many sites with Samba 2.2 (not
-enabled in the Debian packages). If upgrading from an LDAP-enabled 2.2,
-you will need to run the convertSambaAccount script found in
-/usr/share/doc/samba-doc/examples/LDAP. A copy of the schema itself can
-also be found at /usr/share/doc/samba-doc/examples/LDAP/samba.schema.
-
-Character Sets
---------------
-Samba 3.0 introduces support for negotiating Unicode (UCS-2LE) with
-Windows clients. Owing to the close similarity between Windows and Unix
-NLS charsets, in the past, many users were able to pass filenames
-containing non-ASCII characters between clients and servers without
-configuring Samba to know what character set was in use. Now, Samba
-must be able to convert Unix filenames to Unicode before sending to the
-client, so Samba must know what character set the filenames are being
-converted from. If you will be sharing files with non-ASCII names, and
-the filenames are not encoded with UTF-8, you will need to tell Samba
-which character set to use with the 'unix charset' option.
-
-If you had previously specified 'character set' and 'client code page'
-options under 2.2, these settings should be automatically converted for
-you.
-
-
-3. Packages Generated from the Samba Sources
+2. Packages Generated from the Samba Sources
--------------------------------------------
Currently, the Samba sources produce the following binary packages:
@@ -92,8 +54,6 @@ libsmbclient: Shared library that allows applications to talk to SMB servers.
libsmbclient-dev: libsmbclient shared libraries.
winbind: Service to resolve user and group information from a Windows NT
server.
-python2.2-samba: Python bindings that allow access to various aspects of
- Samba.
Please note that the package smbwrapper (a shared library that provides
SMB client services that existed between Samba 2.0.0-1 and Samba-2.0.5a-4
@@ -104,7 +64,7 @@ with glibc2.1 get cleared out (the problem is with glibc, not with Samba
itself).
-4. Support for NT Domains
+3. Support for NT Domains
-------------------------
Samba 2.2 includes preliminary support for NT domains. A Samba server
@@ -124,6 +84,26 @@ Please note that NT domain PDC support is far from complete and is still
experimental.
+4. Samba and LDAP
+-----------------
+
+Samba 2.2 has experimental LDAP code. However, the official Debian
+packages have not been compiled with LDAP support for a good reason: if
+LDAP support is compiled in then the other authentication methods (PAM,
+smbpasswd, etc.) cannot be used, only LDAP will work. So, while LDAP
+cannot coexist peacefully with the other methods we will not provide
+LDAP-enabled packages. The workaround is, of course, to build your own
+packages. We can help with this if you don't know how to build packages.
+
+We follow Samba development, so please do not file bug reports asking
+for LDAP, we will add support for it when it doesn't break other
+things.
+
+update (2002/10/16): the Debian Samba packages in Debian unstable have
+been compiled with --ldapsam support. If you need LDAP support you can
+use those packages, or as we said, build your own 2.2.x packages.
+
+
5. Reporting Bugs
-----------------
diff --git a/packaging/Debian/debian/TODO b/packaging/Debian/debian/TODO
index 5883f72a92b..f53691f26b1 100644
--- a/packaging/Debian/debian/TODO
+++ b/packaging/Debian/debian/TODO
@@ -1,4 +1,8 @@
-Nothing in our list right now.
+In no particular order:
+
+- Fix stuff in packaging/Debian/ (add infrastructure for stable
+ builds)
+- Compile with LDAP support.
+- Review /etc/init.d/samba (Brian White reports problems, should add
+ --oknodo to start-stop-daemon)
-Debian Samba Maintainers.-
-Sun Apr 6 01:34:21 EST 2003
diff --git a/packaging/Debian/debian/changelog b/packaging/Debian/debian/changelog
index 0561f063fa6..fed54fe2e0b 100644
--- a/packaging/Debian/debian/changelog
+++ b/packaging/Debian/debian/changelog
@@ -1,486 +1,47 @@
-samba (3.0.0-1) unstable; urgency=low
+samba (2.2.8-0.1) stable; urgency=high
- * Local build.
-
- -- Debian User <somebody@somewhere.com> Tue, 23 Sep 2003 21:50:26 -0400
-
-samba (3.0.0beta2+3.0.0rc4-1) unstable; urgency=low
-
- * New upstream version.
-
- -- Eloy A. Paris <peloy@debian.org> Sat, 13 Sep 2003 08:47:56 -0400
-
-samba (3.0.0beta2+3.0.0rc3-1) unstable; urgency=low
-
- * New upstream release. Last Release Candidate according to the
- Samba Team. Samba 3.0.0 is around the corner, in a week or so.
- - Fixes use of non-PIC code in nss shared libraries (closes: #208773)
- - 'unix password sync' option now runs the unix password program as
- root again (closes: #209739).
- * One-line patch to make packages buildable with distcc (closes: #210227)
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 9 Sep 2003 07:57:16 -0400
-
-samba (3.0.0beta2+3.0.0rc2-1) unstable; urgency=low
-
- * New upstream release.
- * Incorporate Dutch debconf translations; thanks to Bart Cornelis
- <cobaco@linux.be>. (closes: #207824)
- * Link against libgnutls7 instead of libgnutls5. (closes: #208151)
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 2 Sep 2003 21:37:13 -0400
-
-samba (3.0.0beta2+3.0.0rc1-1) unstable; urgency=low
-
- * New upstream version (skipped samba 3.0.0beta3 due to time
- constraints.) This ugly version number will go away when the final
- Samba 3.0.0 is released.
- * Drag new unpackaged tools into the packages: smbcquotas (smbclient),
- vfs modules (samba), smbtree(1) manpage (smbclient), tdbbackup(8)
- manpage (samba). (closes: #151158)
- * Switch to DH_COMPAT level 4:
- - no explicit conffile listings needed
- - the postinst for libsmbclient is now completely autogenerated
- - use the default init script handling (with support for
- invoke-rc.d) in debhelper, instead of the currently buggy upgrade
- path (closes: #185439)
- - add support for ${misc:Depends} in control for those packages with
- init scripts
- * Add versioned dependency on libpam-runtime and change
- /etc/pam.d/samba to use the new common PAM config blocks.
- * New python2.3-samba package (old python2.2-samba is no more.)
- (closes: #206171)
-
- -- Eloy A. Paris <peloy@debian.org> Mon, 25 Aug 2003 17:05:14 -0400
-
-samba (3.0.0beta2-1) unstable; urgency=low
-
- * New upstream release
- - The smb.conf(5) manpage documents config options again
- (closes: #197963).
- - Handling of winbind/idmap has been restructured; domain members
- should be able to map domain accounts to local accounts again
- (closes: #196815).
- - Use the locale charset for 'display charset' by default
- (closes: #194406).
- - Fix for segfault in smbclient when using the -b option
- (closes: #196833).
- - Handle an empty 'passdb backend' list gracefully (closes: #193946).
- * Don't set 'display charset' anymore on upgrade, since this is now
- grabbed from the locale by default -- a much better option.
- * Removed time.c.patch which is now in the upstream sources.
- * Update FHS patch for two new tdb files (netsamlogon_cache.tdb,
- privilege.tdb).
- * Remove python-linker.patch, since the Kerberos package has been
- fixed to no longer use rpath
- * Remove configure.patch: the hppa glibc bug this was added for is
- long since fixed, and upstream isn't interested in supporting this
- kludge.
- * Update references to missing documentation in sample smb.conf file
- (closes: #187632).
- * Fix handling of krb5 link line, building on a patch from Stefan
- Metzmacher <metze@metzemix.de>.
- * Add patch so smbclient's tar support works with popt
- (closes: #194921).
-
- -- Steve Langasek <vorlon@debian.org> Wed, 2 Jul 2003 20:59:09 -0500
-
-samba (3.0.0beta1-2) unstable; urgency=low
-
- * Update build-deps to libacl1-dev (>= 2.2.11-1), libacl1 (>= 2.2.11-1)
- to make sure we get the right shlib dependencies (closes: #193149).
- * Update the dhcp config hooks so they're suitable for sourcing (i.e.,
- don't call "exit") (closes: #196477).
- * Bring package into line with current policy by adding support for
- the DEB_BUILD_OPTIONS flag, and enabling debugging symbols (-gstabs)
- by default
- * Make sure libpam-smbpass is a self-contained DSO.
- * Fix a typo in samba-common.dhcp that caused us to spuriously rewrite
- the server list.
- * Fix python install script to ignore -Wl linker flags, as seen in the
- output from the latest krb5-config.
- * Add LDAP and Unicode information about upgrading from 2.2 to
- README.debian.
- * Remove dangerous and confusing browse options from the default
- smb.conf (closes: #198804).
- * Reorder smb.conf options for clearer grouping, and clarify the
- comments.
- * Add a default [print$] share to the sample smb.conf, and create the
- necessary tree under /var/lib/samba/printers. (closes: #168173)
- * s/winbind/idmap/ in smb.conf, since the option names have changed.
- * Fix the patch for postexec handling, so that we chdir("/") at the
- right time.
-
- -- Steve Langasek <vorlon@debian.org> Thu, 12 Jun 2003 15:02:00 -0500
-
-samba (3.0.0beta1-1) unstable; urgency=low
-
- * New upstream version.
- - fix for empty browselist bug (closes: #194553)
- - fix for tab completion segfault in smbclient (closes: #194776)
- - Samba now works as a domain member again without segfaulting
- (closes: #194134, #194394, #194775)
- - WinXP machines can join a Samba-controlled domain again
- (closes: #195362)
- * Build-depend on python-dev >= 2.2 instead of on just python-dev
- (without version).
- * Added Vorlon'n patch to source/lib/time.c to fix #194075.
- (closes: #194075)
-
- -- Eloy A. Paris <peloy@debian.org> Sun, 8 Jun 2003 22:26:43 -0400
-
-samba (2.999+3.0.alpha24-3) unstable; urgency=low
-
- * Make sure Samba DSOs are compiled with -fPIC. (closes: #194324)
- * Rebuild against pristine Kerberos libs, to squelch warnings about
- versioned symbols. (closes: #194431, #194396)
-
- -- Steve Langasek <vorlon@debian.org> Thu, 22 May 2003 15:32:00 -0500
-
-samba (2.999+3.0.alpha24-2) unstable; urgency=low
-
- * Fixed description of the smbfs package. (closes: #194183)
- * Negate the sense of the unixsam check when upgrading. (closes: #194234)
-
- -- Steve Langasek <vorlon@debian.org> Wed, 21 May 2003 12:21:53 -0400
-
-samba (2.999+3.0.alpha24-1) unstable; urgency=low
-
- * New upstream version. (closes: #189354)
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 20 May 2003 13:55:57 -0400
-
-samba (2.999+3.0.alpha23-5) unstable; urgency=low
-
- * Move the python package from section "net" to section "python".
- * Make sure we use PIC code for python on all platforms.
- * French translation of an additional debconf template, courtesy of
- Christian Perrier <bubulle@debian.org>. (closes: #188832)
- * Updated Brazilian Portuguese translation from André Luís Lopes
- <andrelop@ig.com.br>.
- * s/unixsam/guest/ everywhere, since the unixsam backend is now
- deprecated. (closes: #190095)
- * Create our temp config file as /etc/samba/smb.conf.dpkg-tmp; not
- only does using /tmp violate SELinux policies, it introduces the
- possibility of data loss during the final copy if /tmp is a separate
- filesystem. (closes: #189823)
- * Pull in fix for SWAT, so that logins work again
- (closes: #188255, #192077).
- * Move passdb.tdb into /var/lib/samba, since it's not user-editable.
- * Make sure with don't ship any .cvsignore files.
- * Don't ship examples for python2.2-samba and samba-doc in an
- "examples" directory inside another "examples" directory.
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 6 May 2003 12:05:46 -0400
-
-samba (2.999+3.0.alpha23-4) unstable; urgency=low
-
- * Instead of s/LPT1:/LPT:/, we need to do s/LPT:/LPT1:/ -- now all
- non-RPC printing clients are working again.
- * Change shlibs to 0 instead of 0.1. The library already in the
- archive is using this soname, and there are no packages depending
- on libsmbclient, so skip changing the package name for now.
- (closes: #188661)
-
- -- Steve Langasek <vorlon@debian.org> Fri, 11 Apr 2003 14:42:00 -0500
-
-samba (2.999+3.0.alpha23-3) unstable; urgency=low
-
- * Put the Samba Python modules in /usr/lib/python2.2/site-packages/,
- not in /usr/lib/python2.2/lib-dynload/.
-
- -- Eloy A. Paris <peloy@debian.org> Wed, 9 Apr 2003 19:49:25 -0400
-
-samba (2.999+3.0.alpha23-2) unstable; urgency=low
-
- * New package python2.2-samba that includes the Python modules
- included in the Samba sources. Feedback on these modules and the new
- package is welcome, as we (Debian Samba maintainers) don't use them.
- (closes: #170731, #173322)
- * Move libsmbclient-dev from section "devel" to "libdevel".
- * Fix panic action script to give a sensible error message instead of
- an empty backtrace when we don't have permission to attach to the
- process. (closes: #188164)
- * Fix libpam-smbpass so that it really does something. (closes: #178245)
- * Apply patch to fix printing-related segfaults. (closes: #188076)
-
- -- Eloy A. Paris <peloy@debian.org> Sun, 6 Apr 2003 21:40:33 -0400
-
-samba (2.999+3.0.alpha23-1) unstable; urgency=high
-
- * new upstream release, includes security fix for DSA-262
- * tweak the debconf templates to avoid references to specific
- front-ends (closes: #183718)
-
- -- Steve Langasek <vorlon@debian.org> Sun, 9 Mar 2003 14:58:00 -0600
-
-samba (2.999+3.0.alpha21-5) unstable; urgency=low
-
- * touch up the package descriptions a little bit (caps, punctuation)
- * remove addtosmbpass, which snuck back in when we weren't looking
- * reverse the position of the wins server tag, after looking more
- closely at the code (closes: #183061)
- * fix a glitch in the Spanish .po that rendered it invalid, plus a typo
- * updated Brazilian Portuguese templates (closes: #183295)
- * fix a typo in upstream manpage (s/shave/share/) (closes: #180546)
- * run sed before we run sed, to deal with crazybad special chars
- in the workgroup name (!) (closes: #176717)
-
- -- Steve Langasek <vorlon@debian.org> Sat, 1 Mar 2003 15:14:00 -0600
+ * Samba Team Build
+ * Security Fix for anonymous root exploit
-samba (2.999+3.0.alpha21-4) unstable; urgency=low
-
- * add scripts to samba-common to grab the netbios-name-servers options
- if we're running a DHCP client (closes: #38413)
- * major rearrangement of build scripts: install target now operates on
- debian/tmp, not debian/samba, so we can see when new files are
- added and decide where to put them; several files that should have
- been in samba-common but were in samba (for the above reason) --
- smbcacls, -- have been moved, with a replaces: added.
- * Fix rc script so that whitespace is consistent between inetd and
- daemon modes (closes: #174677).
- * smbclient -M must always connect to port 139, because port 445
- doesn't support messaging and we can't do the port 135 stuff yet
- (closes: #175292, #167859).
- * Import the diff from upstream CVS, which has fixed a few bugs
- (closes: #178219, #177583, #181467, #181487, #181603, #175864).
- Remove a few patches of ours which are now superseded.
- * Add po-debconf support to the tree, for better i18n.
- * Install the libsmbclient.so symlink in the libsmbclient-dev package,
- per policy (closes: #181466).
-
- -- Steve Langasek <vorlon@debian.org> Fri, 27 Dec 2002 00:37:00 -0600
-
-samba (2.999+3.0.alpha21-3) unstable; urgency=low
-
- * Drop --with-ldapsam from the configure options, since this no longer
- means what we thought it did. Revert patch for changing the 'passdb
- backend' defaults.
- * Add patch from CVS HEAD to fix pdbedit segfault; postinst script
- should work better now. (Closes: #173936)
-
- -- Steve Langasek <vorlon@debian.org> Sun, 22 Dec 2002 13:29:00 -0600
-
-samba (2.999+3.0.alpha21-2) unstable; urgency=low
-
- * add CONFIGDIR to the set of directories exported in the install
- target, so we don't try to write to /etc/ on the autobuilders.
- * Reset the default 'passdb backend' value to something sensible, so
- that we don't unnecessarily break upgrading systems (closes: #173731).
-
- -- Steve Langasek <vorlon@debian.org> Fri, 20 Dec 2002 09:13:00 -0600
+ -- Simo Sorce <idra@samba.org> Wed, 16 Mar 2003 02:30:00 +0100
-samba (2.999+3.0.alpha21-1) unstable; urgency=low
-
- * new upstream release, many patches now incorporated upstream
-
- -- Steve Langasek <vorlon@debian.org> Mon, 16 Dec 2002 23:39:00 -0600
-
-samba (2.999+3.0.alpha20-4) unstable; urgency=low
-
- * Remove obsolete comments about non-existant LDAP support in the
- Debian Samba packages. (Closes: #165035)
- * Apply patch for segfault in pam_smbpass when using the unixsam
- backend.
- * Drop support for nmbd in inetd, since it's not supported by
- upstream and is reported to cause problems (closes: #23243, #137726,
- 165037).
- * Clarify example printing configs in smb.conf (closes: #168174).
- * Make sure nmbd still responds to SIGTERM if it has no interfaces to
- listen on (closes: #168079).
- * Fix to get samba working again on 64-bit archs, after a
- pointer<->int size mismatch bug. Already fixed in upstream CVS.
- * Merge fix from CVS for broken libsmbclient.h references to internal
- structures (closes: #162956).
- * Add a default 'panic action' for Samba that will give us genuinely
- useful debugging information after a crash.
- * Fixed correct patch to example configurations in the libpam-smbpass
- packages (closes: #169350).
- * acl-dev is not in sid anymore; Build-Depend on libacl1-dev instead
- (closes: #169682).
- * Only ask the user for permission to edit if there's a chance of us
- damaging something.
-
- -- Steve Langasek <vorlon@debian.org> Mon, 18 Nov 2002 19:53:00 -0500
-
-samba (2.999+3.0.alpha20-3) unstable; urgency=low
-
- * Make sure smbstatus behavior is sane when Samba *has* been started,
- as well as when it has not (closes: #164179). Thank to Robbert Kouprie
- <robbert@radium.jvb.tudelft.nl> for this patch.
- * Not using 'killall' in any of the maintainer scripts (the last one
- remaining was winbind.logrotate.) We now just use 'kill' to send
- a SIGHUP to a specific PID (which is stored in a file in
- /var/run/samba.)
- * Do not depend on procps because we're not using killall anymore.
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 15 Oct 2002 22:15:57 -0400
-
-samba (2.999+3.0.alpha20-2) unstable; urgency=low
-
- * fix an off-by-one error in smbd/lanman.c, which should shut off the
- flood of log messages (closes: #157432)
- * add a --config-cache option to the configure invocation, since
- autoconf 2.5 doesn't load config.cache by default (closes: #163504)
-
- -- Steve Langasek <vorlon@debian.org> Sat, 5 Oct 2002 01:40:00 -0500
-
-samba (2.999+3.0.alpha20-1) unstable; urgency=low
-
- * new upstream release
- - non-primary groups appear to work again (closes: #161271)
- * the official beginning of the upstream 3.0 branch
- * exit without error from smbstatus when no connections have
- been seen yet (closes: #161489)
-
- -- Steve Langasek <vorlon@debian.org> Wed, 2 Oct 2002 19:02:00 -0500
-
-samba (2.999+3.0cvs20020906-1) unstable; urgency=low
-
- * CVS update
- - domain authentication works again (closes: #158698)
- * Factor out common code in samba-common.config
- * Handle character set settings in smb.conf on upgrade
- (closes: #153913, #158770)
- * Don't use killall in logrotate script; there are better ways
- (closes: #160076)
- * Ignore value of 'hostname lookups' for hosts allow/hosts deny
- (closes: #154376)
+samba (2.2.7a-0.1) unstable; urgency=low
- -- Steve Langasek <vorlon@debian.org> Sat, 7 Sep 2002 11:46:00 -0500
+ * Team Build
-samba (2.999+3.0cvs20020829-1) unstable; urgency=low
+ -- Simo Sorce <idra@samba.org> Wed, 18 Dec 2002 16:56:49 +0100
- * CVS update.
- * Move the smb.conf manpage to the samba-common package (closes: #159572)
-
- -- Steve Langasek <vorlon@debian.org> Thu, 29 Aug 2002 17:53:25 -0500
-
-samba (2.999+3.0cvs20020827-1) unstable; urgency=low
-
- * CVS update. (Closes: #158508)
- * Part 1 of 3 of the library separation patch that Vorlon wrote has
- gone upstream - removed the patch from our patches/ directory.
- * Debconf note to warn users that their smb.conf will be re-written
- and changed if they use Swat to maintain it. (Closes: #158479)
- * Fixed typo in samba.prerm.
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 27 Aug 2002 15:23:23 -0400
-
-samba (2.999+3.0cvs20020825-2) unstable; urgency=low
-
- * scale back the tdbsam migration support, because of undesirable
- side-effects; now always defaults to 'no'.
- * strip out hyperactive library dependencies that are only needed by
- smbd (closes: #155156).
- * nuke any broken registry.tdb files left by previous CVS snapshots.
- * support rolling back the smbpasswd->tdbsam conversion on downgrade,
- since many people are likely to need to downgrade for a while.
- * remove postrm handling of legacy directories, and add handling of
- current ones.
+samba (2.2.6-0.1) unstable; urgency=low
- -- Steve Langasek <vorlon@debian.org> Sun, 28 Jul 2002 09:44:24 -0500
-
-samba (2.999+3.0cvs20020825-1) unstable; urgency=low
-
- * CVS update. These packages are based on Samba 3.0alpha19 + any
- code commited after 3.0alpha19 was released.
-
- -- Eloy A. Paris <peloy@debian.org> Sun, 25 Aug 2002 14:56:46 -0400
-
-samba (2.999+3.0cvs20020723-1) unstable; urgency=medium
-
- * remove spurious line from samba.config
- * migrate from smbpasswd to tdbsam
- * re-add the pdbedit util and manpage
- * compile in ldapsam support (closes: #146935)
- * add PRIVATEDIR to the list of vars we override for the install
- target, so Samba doesn't try to create /etc/samba (closes: #153746).
- * fix makefile handling of LOGBASEDIR, so that logs always end up in
- the right place (closes: 153727).
- * Fixed bug in the FHS migration path that causes nmbd to read its
- state from one location, but write it out to another. (closes: #154210)
- * Make sure nmbd is always looking for wins.tdb in the same place.
+ * Local build.
- -- Steve Langasek <vorlon@debian.org> Fri, 19 Jul 2002 21:38:54 -0500
+ -- Debian User <user@somewhere.in.the.planet> Sun, 13 Oct 2002 02:33:32 -0400
-samba (2.99.cvs.20020713-1) unstable; urgency=low
+samba (2.2.5-1.woody) stable; urgency=low
- * first attempt for 3.0pre.
- * only post a debconf note about moving logfiles if we're upgrading
- from a version that had the logfiles in the old location
- (closes: #152924).
+ * Upload latest stable Samba release to woody.
+ - includes improved NT printing support (closes: #157406)
+ * Fix the filename-matching algorithm used for smbtar's 'exclude'
+ functionality. (closes: #131571)
+ * Remove patches/srv_spoolss_nt.patch, now included upstream.
- -- Steve Langasek <vorlon@debian.org> Sat, 13 Jul 2002 12:54:25 -0500
+ -- Steve Langasek <vorlon@debian.org> Fri, 23 Aug 2002 17:20:08 -0500
-samba (2.2.5-2) unstable; urgency=low
+samba (2.2.3a-8) stable; urgency=low
- * No longer ship make_printerdef, which is deprecated. (closes: #63059)
- * Clean up some empty directories from the samba package.
- * Add call to dh_installinit for winbind rc.x symlinks (closes: #151860).
- * Clean up per-package documentation lists, to reduce clutter
- (closes: #147638).
- * Make sure we don't ship pdbedit's man page since we are still using
- smbpasswd passwords. (closes: #152208)
- * move libnss_wins.so to libnss_wins.so.2, where glibc expects to find
- it (closes: #148586).
+ * maintainer script fixes backported from sid.
* reorder postinst, so that installing samba-common from scratch loads
the debconf answers properly (closes: #151985).
- * add lintian overrides for winbind, to eliminate some noise.
- * rename pam_smbpass changelog to comply with policy.
-
- -- Steve Langasek <vorlon@debian.org> Sun, 23 Jun 2002 22:45:04 -0500
-
-samba (2.2.5-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Eloy A. Paris <peloy@debian.org> Sun, 9 Jun 2002 15:49:21 -0400
-
-samba (2.2.4+2.2.5pre1-1) experimental; urgency=low
-
- * Getting ready for Samba 2.2.5.
- * Remove patches/parse_spoolss.patch, now included upstream.
- * Fixed thinko WRT POSIX ACL support, which we "half-enabled" in
- 2.2.4-1. We don't use POSIX ACL support ourselves, so we'd
- appreciate reports from those using this feature so we can
- be sure this works.
- * Fix the filename-matching algorithm used for smbtar's 'exclude'
- functionality. (closes: #131571)
* Look for secrets.tdb in /var/lib/samba, and handle in the postinst.
This is not really a config file, because users don't edit it.
(closes: #147429)
- * Doxygen fix for libsmbclient.h, thanks to Tommi Komulainen
- <Tommi.Komulainen@iki.fi> for the patch. (closes: #144847)
-
- -- Eloy A. Paris <peloy@debian.org> Tue, 28 May 2002 11:33:51 -0400
-
-samba (2.2.4-1) unstable; urgency=low
-
- * New upstream release (closes: #144713)
- * Building with POSIX ACL support (closes: #137819)
- * Include samples, exclude INSTALL from libpam-smbpass (closes: #145055)
- * Compile with --with-automount, for NIS homedir support (closes: #123396)
- * Add a proper 'flags' field to the mount entry we write to /etc/mtab;
- fixes a display bug with mount (closes: #140397)
- * Added logic to /etc/init.d/samba so a help message is printed out
- when Samba is running from inetd _and_ we are not booting, i.e. the
- user called the init script manually. Thanks to Francesco
- Potorti <pot@gnu.org> for the suggestion on how to implement this.
- (Closes: #139807, #140204)
* samba.postinst: added logic so we don't call /etc/init.d/samba if
we are running from inetd (this prevents the stupid help message
to be printed during package upgrades if we are running from inetd.)
- * samba.prerm: idem.
- * /etc/init.d/samba: delete stale PID files after nmbd and smbd are
- stopped. This prevents start-stop-daemon from printing an ugly
- error message when called from '/etc/init.d/samba stop'. I prefer
- this than running start-stop-daemon with --oknodo because
- start-stop-daemon might print other important error messages that with
- --oknodo it would otherwise not print. (Closes: #102187, #109301)
- * Patch from jerry@samba.org to fix parsing of spoolss structures.
+ * Fixed bug in the FHS migration path that causes nmbd to read its
+ state from one location, but write it out to another. (closes: #154210)
- -- Eloy A. Paris <peloy@debian.org> Thu, 23 May 2002 23:16:52 -0400
+ -- Steve Langasek <vorlon@debian.org> Sat, 13 Jul 2002 10:18:56 -0500
samba (2.2.3a-7) unstable; urgency=medium
@@ -501,7 +62,7 @@ samba (2.2.3a-7) unstable; urgency=medium
running before the upgrade starts.
* Tweak the wording of debconf templates.
* Incorporate debconf translations for French, Spanish and Portuguese;
- thanks to Carlos Valdivia Yagüe <valyag@hotpop.com> (es),
+ thanks to Carlos Valdivia Yagüe <valyag@hotpop.com> (es),
Andre Luis Lopes <andrelop@ig.com.br> (pt_BR), and Philippe
Batailler and Denis Barbier <barbier@debian.org> (fr).
(closes: #142657, #142659, #141551, #141699, #141682)
@@ -529,7 +90,7 @@ samba (2.2.3a-6) unstable; urgency=low
* Bring our shipped smb.conf closer in line with the upstream
defaults: don't twiddle the send/recv buffer sizes, since the Linux
kernel already provides a much better default setting
- (closes: #80966, #80934, #137415, #133477)
+ (closes: #80966, #80934, #137415, #133477)
* Added libnss_wins.so to the winbind package (closes: #137201)
* Updates to README.debian.
diff --git a/packaging/Debian/debian/config.cache b/packaging/Debian/debian/config.cache
index 8872a27b761..c0a70a5b19b 100644
--- a/packaging/Debian/debian/config.cache
+++ b/packaging/Debian/debian/config.cache
@@ -46,6 +46,12 @@ samba_cv_have_setresgid=${samba_cv_have_setresgid=yes}
samba_cv_USE_SETRESUID=${samba_cv_USE_SETRESUID=yes}
+# POSIX ACL support not present in Linux 2.2; not allowed in the
+# Debian packages, even if present on the build machine.
+
+ac_cv_header_sys_acl_h=${ac_cv_header_sys_acl_h=no}
+
+
# Various basic libc/compiler stuff that it's blindingly obvious that
# Linux supports (now watch me get bitten for saying that)
@@ -124,6 +130,8 @@ samba_cv_HAVE_FCNTL_LOCK=${samba_cv_HAVE_FCNTL_LOCK=yes}
# to support transparent userland VFS. We might as well preempt
# any checks for shadowed symbols that are only useful for smbwrapper.
+ac_cv_func___acl=${ac_cv_func___acl=no}
+ac_cv_func__acl=${ac_cv_func__acl=no}
ac_cv_func___chdir=${ac_cv_func___chdir=no}
ac_cv_func__chdir=${ac_cv_func__chdir=no}
ac_cv_func___close=${ac_cv_func___close=no}
@@ -134,6 +142,8 @@ ac_cv_func___dup=${ac_cv_func___dup=no}
ac_cv_func__dup=${ac_cv_func__dup=no}
ac_cv_func___dup2=${ac_cv_func___dup2=no}
ac_cv_func__dup2=${ac_cv_func__dup2=no}
+ac_cv_func___facl=${ac_cv_func___facl=no}
+ac_cv_func__facl=${ac_cv_func__facl=no}
ac_cv_func___fchdir=${ac_cv_func___fchdir=no}
ac_cv_func__fchdir=${ac_cv_func__fchdir=no}
ac_cv_func___fcntl=${ac_cv_func___fcntl=no}
diff --git a/packaging/Debian/debian/control b/packaging/Debian/debian/control
index 7bfb41b79d9..eb80a6f20db 100644
--- a/packaging/Debian/debian/control
+++ b/packaging/Debian/debian/control
@@ -1,17 +1,17 @@
Source: samba
Section: net
Priority: optional
-Maintainer: Eloy A. Paris <peloy@debian.org>
-Uploaders: Steve Langasek <vorlon@debian.org>
-Build-Depends: debhelper (>= 4.1.13), libpam0g-dev, libreadline4-dev, libcupsys2-dev, autoconf, libacl1-dev (>= 2.2.11-1), libacl1 (>= 2.2.11-1), libkrb5-dev, libldap2-dev, po-debconf, python2.3-dev
-Standards-Version: 3.5.10
+Maintainer: Simo Sorce <idra@samba.org>
+Uploaders: Simo Sorce <idra@samba.org>
+Build-Depends: debhelper (>=2.0.103), libpam0g-dev, libreadline4-dev, libcupsys2-dev, autoconf
+Standards-Version: 3.1.1
Package: samba
Architecture: any
-Depends: samba-common (= ${Source-Version}), netbase, logrotate, ${shlibs:Depends}, ${misc:Depends}, libpam-runtime (>= 0.76-13.1), libpam-modules
+Depends: debconf, samba-common (= ${Source-Version}), netbase, logrotate, ${shlibs:Depends}
Replaces: samba-common (<= 2.0.5a-2)
Suggests: samba-doc
-Description: a LanManager-like file and printer server for Unix
+Description: A LanManager like file and printer server for Unix.
The Samba software suite is a collection of programs that
implements the SMB protocol for unix systems, allowing you to serve
files and printers to Windows, NT, OS/2 and DOS clients. This protocol
@@ -22,17 +22,16 @@ Description: a LanManager-like file and printer server for Unix
.
Currently, the Samba Debian packages consist of the following:
.
- samba - LanManager-like file and printer server for Unix.
+ samba - A LanManager like file and printer server for Unix.
samba-common - Samba common files used by both the server and the client.
- smbclient - LanManager-like simple client for Unix.
+ smbclient - A LanManager like simple client for Unix.
swat - Samba Web Administration Tool
samba-doc - Samba documentation.
- smbfs - Mount and umount commands for the smbfs (kernels 2.2.x and above).
+ smbfs - Mount and umount commands for the smbfs (kernels 2.0.x and above).
libpam-smbpass - pluggable authentication module for SMB password database
libsmbclient - Shared library that allows applications to talk to SMB servers
libsmbclient-dev - libsmbclient shared libraries
winbind: Service to resolve user and group information from Windows NT servers
- python2.3-samba: Python bindings that allow access to various aspects of Samba
.
It is possible to install a subset of these packages depending on
your particular needs. For example, to access other SMB servers you
@@ -41,8 +40,8 @@ Description: a LanManager-like file and printer server for Unix
Package: samba-common
Architecture: any
Depends: debconf, libpam-modules, ${shlibs:Depends}
-Replaces: samba (<< 2.999+3.0.alpha21-4)
-Description: Samba common files used by both the server and the client
+Replaces: samba (<= 2.0.5a-2)
+Description: Samba common files used by both the server and the client.
The Samba software suite is a collection of programs that
implements the SMB protocol for unix systems, allowing you to serve
files and printers to Windows, NT, OS/2 and DOS clients. This protocol
@@ -55,10 +54,10 @@ Description: Samba common files used by both the server and the client
Package: smbclient
Architecture: any
Depends: samba-common (= ${Source-Version}), ${shlibs:Depends}
-Replaces: samba (<< 2.999+3.0.alpha21-4)
+Replaces: samba (<= 2.2.2-5)
Provides: samba-client
Suggests: smbfs
-Description: a LanManager-like simple client for Unix
+Description: A LanManager like simple client for Unix.
The Samba software suite is a collection of programs that
implements the SMB protocol for unix systems, allowing you to serve
files and printers to Windows, NT, OS/2 and DOS clients. This protocol
@@ -71,7 +70,7 @@ Description: a LanManager-like simple client for Unix
Package: swat
Architecture: any
-Depends: debconf, samba (= ${Source-Version}), ${shlibs:Depends}
+Depends: samba (= ${Source-Version}), ${shlibs:Depends}
Recommends: samba-doc
Description: Samba Web Administration Tool
The Samba software suite is a collection of programs that
@@ -88,7 +87,7 @@ Description: Samba Web Administration Tool
Package: samba-doc
Section: doc
Architecture: all
-Description: Samba documentation
+Description: Samba documentation.
The Samba software suite is a collection of programs that
implements the SMB protocol for unix systems, allowing you to serve
files and printers to Windows, NT, OS/2 and DOS clients. This protocol
@@ -113,7 +112,7 @@ Description: mount and umount commands for the smbfs (for kernels >= than 2.2.x)
site into a file server for DOS or Windows clients.
.
If you want to use command-line utilities like smbclient, smbtar
- and/or smbspool you just need to install the smbclient package.
+ and/or smbspool just need to install the smbclient package.
.
Starting with the Debian Samba packages version 2.2.0-1, the old smbfs
utilities for 2.0.x have been removed. There are no wrapper scripts
@@ -139,7 +138,7 @@ Section: libs
Priority: extra
Architecture: any
Depends: ${shlibs:Depends}
-Description: shared library that allows applications to talk to SMB servers
+Description: Shared library that allows applications to talk to SMB servers
libsmbclient allows to write applications that use the SMB protocol.
This gives applications the ability to talk to Microsoft Windows servers
and Unix servers running Samba.
@@ -147,7 +146,7 @@ Description: shared library that allows applications to talk to SMB servers
This package contains the libsmbclient shared library.
Package: libsmbclient-dev
-Section: libdevel
+Section: devel
Priority: extra
Architecture: any
Depends: libsmbclient (= ${Source-Version})
@@ -163,9 +162,9 @@ Package: winbind
Section: net
Priority: optional
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: ${shlibs:Depends}
Replaces: samba (<= 2.2.3-2)
-Description: service to resolve user and group information from Windows NT servers
+Description: Service to resolve user and group information from Windows NT servers
This package provides the winbindd daemon, which provides a
service for the Name Service Switch capability that is present
in most modern C libraries (like the GNU C Library - glibc.)
@@ -174,15 +173,3 @@ Description: service to resolve user and group information from Windows NT serve
can be used to resolve user and group information from a
Windows NT server. The service can also provide authentication
services via an associated PAM module.
-
-Package: python2.3-samba
-Section: python
-Priority: optional
-Architecture: any
-Depends: ${shlibs:Depends}, python2.3
-Description: Python bindings that allow access to various aspects of Samba
- The Samba Python bindings allow you to access various aspects of Samba.
- At the moment their status is "experimental" but they have been reported
- to work well.
- .
- See /usr/share/doc/python2.3-samba/examples for a couple of examples.
diff --git a/packaging/Debian/debian/gdbcommands b/packaging/Debian/debian/gdbcommands
deleted file mode 100644
index 5774b9ae311..00000000000
--- a/packaging/Debian/debian/gdbcommands
+++ /dev/null
@@ -1,2 +0,0 @@
-bt
-quit
diff --git a/packaging/Debian/debian/libsmbclient-dev.examples b/packaging/Debian/debian/libsmbclient-dev.examples
deleted file mode 100644
index 2094c40b556..00000000000
--- a/packaging/Debian/debian/libsmbclient-dev.examples
+++ /dev/null
@@ -1 +0,0 @@
-examples/libsmbclient/
diff --git a/packaging/Debian/debian/libsmbclient-dev.files b/packaging/Debian/debian/libsmbclient-dev.files
index a52c17cfc56..3ca6033fe7b 100644
--- a/packaging/Debian/debian/libsmbclient-dev.files
+++ b/packaging/Debian/debian/libsmbclient-dev.files
@@ -1,3 +1,2 @@
usr/lib/libsmbclient.a
-usr/lib/libsmbclient.so
usr/include/libsmbclient.h
diff --git a/packaging/Debian/debian/libsmbclient.postinst b/packaging/Debian/debian/libsmbclient.postinst
new file mode 100755
index 00000000000..bd85266cdf9
--- /dev/null
+++ b/packaging/Debian/debian/libsmbclient.postinst
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# postinst script for libsmbclient
+#
+#
+
+if [ "$1" = "configure" ]; then
+ ldconfig
+fi
+
+#DEBHELPER#
diff --git a/packaging/Debian/debian/libsmbclient.shlibs b/packaging/Debian/debian/libsmbclient.shlibs
index 9c6eea200a9..74329f2c08d 100644
--- a/packaging/Debian/debian/libsmbclient.shlibs
+++ b/packaging/Debian/debian/libsmbclient.shlibs
@@ -1 +1 @@
-libsmbclient 0 libsmbclient (>= 2.2.2-11)
+libsmbclient 0.1 libsmbclient (>= 2.2.2-11)
diff --git a/packaging/Debian/debian/panic-action b/packaging/Debian/debian/panic-action
deleted file mode 100644
index 13f773c1ef8..00000000000
--- a/packaging/Debian/debian/panic-action
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-
-# Redirect all output to our mail command
-(
- # We must be given a pid to look at
- if [ -z "$1" ]; then
- echo "$0 called with no arguments."
- exit 1
- fi
-
- if [ ! -d "/proc/$1" ]; then
- echo "$0: No such process: $1"
- exit 1
- fi
-
- # Find out what binary we're debugging
- BINARYNAME=`readlink "/proc/$1/exe"`
-
- # Generic header for our email
- echo "The Samba 'panic action' script, $0,"
- echo "was called for pid $1 ($BINARYNAME)."
- echo
-
- if [ -z "$BINARYNAME" ]; then
- echo "This means there was a problem with the program, such as a segfault."
- echo "However, the executable could not be found for process $1."
- echo "It may have died unexpectedly, or you may not have permission to"
- echo "debug the process."
- exit 1
- fi
-
- # No debugger
- if [ ! -x /usr/bin/gdb ]; then
- echo "This means there was a problem with the program, such as a segfault."
- echo "However, gdb was not found on your system, so the error could not be"
- echo "debugged. Please install the gdb package so that debugging information is"
- echo "available the next time such a problem occurs."
- exit 1
- fi
-
- echo "Below is a backtrace for this process generated with gdb, which shows"
- echo "the state of the program at the time the error occured. You are"
- echo "encouraged to submit this information as a bug report to Debian. For"
- echo "information about the procedure for submitting bug reports , please see"
- echo "http://www.debian.org/Bugs/Reporting or the reportbug(1) manpage."
- echo
- gdb -x /etc/samba/gdbcommands -batch "$BINARYNAME" "$1"
-) | mail -s "Segfault in Samba" root
diff --git a/packaging/Debian/debian/patches/Makefile.in.patch b/packaging/Debian/debian/patches/Makefile.in.patch
new file mode 100755
index 00000000000..1c4d67418f8
--- /dev/null
+++ b/packaging/Debian/debian/patches/Makefile.in.patch
@@ -0,0 +1,17 @@
+--- samba/source/Makefile.in.orig 2002-10-13 01:43:10.000000000 -0400
++++ samba/source/Makefile.in 2002-10-13 01:43:10.000000000 -0400
+@@ -727,10 +727,10 @@
+ @$(SHELL) $(srcdir)/script/installswat.sh $(SWATDIR) $(srcdir)
+
+ installclientlib:
+- -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@
+- -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a
+- -$(INSTALLCMD) -d ${prefix}/include
+- -$(INSTALLCMD) include/libsmbclient.h ${prefix}/include
++ -$(INSTALLCMD) bin/libsmbclient.@SHLIBEXT@ $(BASEDIR)/lib
++ -$(INSTALLCMD) bin/libsmbclient.a $(BASEDIR)/lib
++ -$(INSTALLCMD) -d $(INCLUDEDIR)
++ -$(INSTALLCMD) include/libsmbclient.h $(INCLUDEDIR)
+
+ # revert to the previously installed version
+ revert:
diff --git a/packaging/Debian/debian/patches/VERSION.patch b/packaging/Debian/debian/patches/VERSION.patch
deleted file mode 100644
index 0f5c129c564..00000000000
--- a/packaging/Debian/debian/patches/VERSION.patch
+++ /dev/null
@@ -1,8 +0,0 @@
---- samba-3.0.0rc2/source/VERSION.orig 2003-09-02 21:56:11.000000000 -0400
-+++ samba-3.0.0rc2/source/VERSION 2003-09-02 21:56:30.000000000 -0400
-@@ -120,4 +120,4 @@
- # e.g. SAMBA_VERSION_VENDOR_SUFFIX=vendor_version() #
- # -> "CVS 3.0.0rc2-VendorVersion" #
- ########################################################
--SAMBA_VERSION_VENDOR_SUFFIX=
-+SAMBA_VERSION_VENDOR_SUFFIX="Debian"
diff --git a/packaging/Debian/debian/patches/configure.patch b/packaging/Debian/debian/patches/configure.patch
new file mode 100755
index 00000000000..17b488c2923
--- /dev/null
+++ b/packaging/Debian/debian/patches/configure.patch
@@ -0,0 +1,32 @@
+diff -uNr samba-2.2.5pre1.orig/source/configure.in samba-2.2.5pre1/source/configure.in
+--- samba-2.2.5pre1.orig/source/configure.in Sat Jun 8 07:55:55 2002
++++ samba-2.2.5pre1/source/configure.in Wed Jun 12 15:27:28 2002
+@@ -384,6 +384,28 @@
+ #endif
+ }
+ ], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross])
++ if test x$LINUX_LFS_SUPPORT = xyes ; then
++ AC_TRY_RUN([
++#include <unistd.h>
++#include <sys/types.h>
++#include <fcntl.h>
++main() {
++ unsigned int *padding;
++ struct flock foo_lock = {F_WRLCK, SEEK_SET, 0, 1, 0};
++ int fd = open("/dev/null", O_RDWR);
++
++ /* Yes, we're depending on the internals of the Linux flock structure
++ here -- but this test is explicitly Linux-specific to begin with. */
++ padding = (unsigned int *)&foo_lock;
++ padding[1] = 0xffffffff;
++ foo_lock.l_start = 0;
++ if (fcntl(fd, F_SETLK, &foo_lock) < 0)
++ exit(1);
++
++ exit(0);
++}
++], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross])
++ fi
+ CPPFLAGS="$old_CPPFLAGS"
+ if test x$LINUX_LFS_SUPPORT = xyes ; then
+ CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS"
diff --git a/packaging/Debian/debian/patches/documentation.patch b/packaging/Debian/debian/patches/documentation.patch
deleted file mode 100644
index c5e66232f9c..00000000000
--- a/packaging/Debian/debian/patches/documentation.patch
+++ /dev/null
@@ -1,68 +0,0 @@
---- samba_3_0/docs/manpages/swat.8.orig 2003-06-06 16:16:24.000000000 -0400
-+++ samba_3_0/docs/manpages/swat.8 2003-06-06 16:25:13.000000000 -0400
-@@ -89,6 +89,13 @@
- .SH "INSTALLATION"
-
- .PP
-+\fBDebian-specific Note\fR: all these steps have already been done for
-+you. However, by default, swat is not enabled. This has been done for
-+security reasons. To enable swat you need to edit /etc/inetd.conf,
-+uncomment the swat entry (usually at the end of the file), and then
-+restart inetd.
-+
-+.PP
- Swat is included as binary package with most distributions\&. The package manager in this case takes care of the installation and configuration\&. This section is only for those who have compiled swat from scratch\&.
-
- .PP
-@@ -96,15 +103,15 @@
-
- .TP 3
- \(bu
--/usr/local/samba/bin/swat
-+/usr/sbin/swat
-
- .TP
- \(bu
--/usr/local/samba/swat/images/*
-+/usr/share/samba/swat/images/*
-
- .TP
- \(bu
--/usr/local/samba/swat/help/*
-+/usr/share/samba/swat/help/*
-
- .LP
-
-@@ -114,7 +121,7 @@
- You need to edit your \fI/etc/inetd\&.conf \fR and \fI/etc/services\fR to enable SWAT to be launched via \fBinetd\fR\&.
-
- .PP
--In \fI/etc/services\fR you need to add a line like this:
-+In \fI/etc/services\fR you need to add a line like this (not needed for Debian):
-
- .PP
- \fBswat 901/tcp\fR
-@@ -126,10 +133,10 @@
- the choice of port number isn't really important except that it should be less than 1024 and not currently used (using a number above 1024 presents an obscure security hole depending on the implementation details of your\fBinetd\fR daemon)\&.
-
- .PP
--In \fI/etc/inetd\&.conf\fR you should add a line like this:
-+In \fI/etc/inetd\&.conf\fR you should add a line like this (not needed for Debian since the maintainer scripts do it. You need to uncomment the line, though, because it is added commented out for security reasons):
-
- .PP
--\fBswat stream tcp nowait.400 root /usr/local/samba/bin/swat swat\fR
-+\fBswat stream tcp nowait.400 root /usr/sbin/swat swat\fR
-
- .PP
- One you have edited \fI/etc/services\fR and \fI/etc/inetd\&.conf\fR you need to send a HUP signal to inetd\&. To do this use \fBkill -1 PID \fR where PID is the process ID of the inetd daemon\&.
-@@ -155,8 +162,8 @@
-
-
- .TP
--\fI/usr/local/samba/lib/smb\&.conf\fR
--This is the default location of the \fBsmb.conf\fR(5) server configuration file that swat edits\&. Other common places that systems install this file are \fI /usr/samba/lib/smb\&.conf\fR and \fI/etc/smb\&.conf \fR\&. This file describes all the services the server is to make available to clients\&.
-+\fI/etc/samba/smb\&.conf\fR
-+This is the default location of the \fBsmb.conf\fR(5) server configuration file that swat edits\&. This file describes all the services the server is to make available to clients\&.
-
-
- .SH "WARNINGS"
diff --git a/packaging/Debian/debian/patches/fhs.patch b/packaging/Debian/debian/patches/fhs.patch
index 652641216b6..173024ef1a1 100644
--- a/packaging/Debian/debian/patches/fhs.patch
+++ b/packaging/Debian/debian/patches/fhs.patch
@@ -1,215 +1,87 @@
-diff -uNr samba-3.0.0beta2.orig/source/Makefile.in samba-3.0.0beta2/source/Makefile.in
---- samba-3.0.0beta2.orig/source/Makefile.in 2003-07-02 23:26:46.000000000 -0500
-+++ samba-3.0.0beta2/source/Makefile.in 2003-07-02 23:19:46.000000000 -0500
-@@ -67,6 +67,7 @@
- CONFIGDIR = @configdir@
- VARDIR = @localstatedir@
- MANDIR = @mandir@
-+DATADIR = @datadir@
-
- # The permissions to give the executables
- INSTALLPERMS = 0755
-@@ -90,6 +91,13 @@
- # the directory where lock files go
- LOCKDIR = @lockdir@
-
-+# FHS directories; equal to LOCKDIR if not using --with-fhs
-+CACHEDIR = @cachedir@
-+STATEDIR = @statedir@
-+
-+# Where to look for (and install) codepage databases.
-+CODEPAGEDIR = @codepagedir@
-+
- # the directory where pid files go
- PIDDIR = @piddir@
- # man pages language(s)
-@@ -114,7 +122,7 @@
- PATH_FLAGS4 = $(PATH_FLAGS3) -DSWATDIR=\"$(SWATDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DPIDDIR=\"$(PIDDIR)\"
- PATH_FLAGS5 = $(PATH_FLAGS4) -DLIBDIR=\"$(LIBDIR)\" \
- -DLOGFILEBASE=\"$(LOGFILEBASE)\" -DSHLIBEXT=\"@SHLIBEXT@\"
--PATH_FLAGS6 = $(PATH_FLAGS5) -DCONFIGDIR=\"$(CONFIGDIR)\"
-+PATH_FLAGS6 = $(PATH_FLAGS5) -DCONFIGDIR=\"$(CONFIGDIR)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" -DCACHEDIR=\"$(CACHEDIR)\" -DSTATEDIR=\"$(STATEDIR)\"
- PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS)
-
- # Note that all executable programs now provide for an optional executable suffix.
-@@ -1203,7 +1211,7 @@
- @$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS)
-
- installdat: installdirs
-- @$(SHELL) $(srcdir)/script/installdat.sh $(DESTDIR)$(LIBDIR) $(srcdir)
-+ @$(SHELL) $(srcdir)/script/installdat.sh $(DESTDIR)$(CODEPAGEDIR) $(srcdir)
-
- installswat: installdirs
- @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir)
-diff -uNr samba-3.0.0beta2.orig/source/configure.in samba-3.0.0beta2/source/configure.in
---- samba-3.0.0beta2.orig/source/configure.in 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/configure.in 2003-07-02 23:19:02.000000000 -0500
-@@ -17,18 +17,25 @@
- AC_ARG_WITH(fhs,
+diff -uNr samba-2.2.8-orig/source/Makefile.in samba-2.2.8/source/Makefile.in
+--- samba-2.2.8-orig/source/Makefile.in Fri Feb 28 16:56:06 2003
++++ samba-2.2.8/source/Makefile.in Sun Mar 16 00:53:38 2003
+@@ -86,7 +86,7 @@
+ FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DLOGFILEBASE=\"$(LOGFILEBASE)\"
+ FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
+ FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
+-FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DPIDDIR=\"$(PIDDIR)\" -DLIBDIR=\"$(LIBDIR)\"
++FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DPIDDIR=\"$(PIDDIR)\" -DLIBDIR=\"$(LIBDIR)\" -DVARDIR=\"$(VARDIR)\"
+ FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
+ FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS)
+ FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS)
+diff -uNr samba-2.2.8-orig/source/acconfig.h samba-2.2.8/source/acconfig.h
+--- samba-2.2.8-orig/source/acconfig.h Fri Feb 28 16:56:06 2003
++++ samba-2.2.8/source/acconfig.h Sun Mar 16 00:53:38 2003
+@@ -177,6 +177,7 @@
+ #undef HAVE_DEVICE_MAJOR_FN
+ #undef HAVE_DEVICE_MINOR_FN
+ #undef HAVE_MAKEDEV_FN
++#undef FHS_COMPATIBLE
+ #undef HAVE_GETGROUPS_TOO_MANY_EGIDS
+ #undef HAVE_PASSWD_PW_COMMENT
+ #undef HAVE_PASSWD_PW_AGE
+diff -uNr samba-2.2.8-orig/source/configure.in samba-2.2.8/source/configure.in
+--- samba-2.2.8-orig/source/configure.in Fri Feb 28 16:56:18 2003
++++ samba-2.2.8/source/configure.in Sun Mar 16 00:53:38 2003
+@@ -12,11 +12,12 @@
[ --with-fhs Use FHS-compliant paths (default=no)],
+ codepagedir="\$(DATADIR)/samba/codepages"
configdir="${sysconfdir}/samba"
- lockdir="\${VARDIR}/cache/samba"
+ lockdir="\${VARDIR}/run/samba"
- piddir="\${VARDIR}/run/samba"
+ piddir="\$(VARDIR)/run/samba"
logfilebase="\${VARDIR}/log/samba"
privatedir="\${CONFIGDIR}/private"
- libdir="\${prefix}/lib/samba"
- swatdir="\${DATADIR}/samba/swat",
+ swatdir="\${DATADIR}/samba/swat"
-+ codepagedir="\${DATADIR}/samba"
-+ statedir="\${VARDIR}/lib/samba"
-+ cachedir="\${VARDIR}/cache/samba"
-+ AC_DEFINE(FHS_COMPATIBLE, 1, [Whether to use fully FHS-compatible paths]),
- configdir="\${LIBDIR}"
- logfilebase="\${VARDIR}"
- lockdir="\${VARDIR}/locks"
- piddir="\${VARDIR}/locks"
- privatedir="\${prefix}/private"
-- swatdir="\${prefix}/swat")
-+ codepagedir="\${LIBDIR}"
-+ swatdir="\${prefix}/swat"
-+ statedir="\${LOCKDIR}"
-+ cachedir="\${LOCKDIR}")
-
- #################################################
- # set private directory location
-@@ -134,6 +141,9 @@
- AC_SUBST(swatdir)
- AC_SUBST(bindir)
- AC_SUBST(sbindir)
-+AC_SUBST(codepagedir)
-+AC_SUBST(statedir)
-+AC_SUBST(cachedir)
-
- dnl Unique-to-Samba variables we'll be playing with.
- AC_SUBST(SHELL)
-diff -uNr samba-3.0.0beta2.orig/source/dynconfig.c samba-3.0.0beta2/source/dynconfig.c
---- samba-3.0.0beta2.orig/source/dynconfig.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/dynconfig.c 2003-07-02 23:19:02.000000000 -0500
-@@ -53,6 +53,13 @@
- pstring dyn_LMHOSTSFILE = LMHOSTSFILE;
-
- /**
-+ * @brief Samba data directory.
-+ *
-+ * @sa data_path() to get the path to a file inside the CODEPAGEDIR.
-+ **/
-+pstring dyn_CODEPAGEDIR = CODEPAGEDIR;
++ AC_DEFINE(FHS_COMPATIBLE),
+ codepagedir="\$(LIBDIR)/codepages"
+ configdir="\$(LIBDIR)"
+ logfilebase="\$(VARDIR)"
+diff -uNr samba-2.2.8-orig/source/include/config.h.in samba-2.2.8/source/include/config.h.in
+--- samba-2.2.8-orig/source/include/config.h.in Fri Feb 28 16:56:18 2003
++++ samba-2.2.8/source/include/config.h.in Sun Mar 16 00:53:38 2003
+@@ -243,6 +243,7 @@
+ #undef HAVE_DEVICE_MAJOR_FN
+ #undef HAVE_DEVICE_MINOR_FN
+ #undef HAVE_MAKEDEV_FN
++#undef FHS_COMPATIBLE
+ #undef HAVE_GETGROUPS_TOO_MANY_EGIDS
+ #undef HAVE_PASSWD_PW_COMMENT
+ #undef HAVE_PASSWD_PW_AGE
+diff -uNr samba-2.2.8-orig/source/include/local.h samba-2.2.8/source/include/local.h
+--- samba-2.2.8-orig/source/include/local.h Fri Feb 28 16:56:18 2003
++++ samba-2.2.8/source/include/local.h Sun Mar 16 00:56:25 2003
+@@ -196,4 +196,21 @@
+
+ /* Max number of simultaneous winbindd socket connections. */
+ #define WINBINDD_MAX_SIMULTANEOUS_CLIENTS 200
+
-+/**
- * @brief Samba library directory.
- *
- * @sa lib_path() to get the path to a file inside the LIBDIR.
-@@ -70,3 +77,27 @@
-
- const pstring dyn_SMB_PASSWD_FILE = SMB_PASSWD_FILE;
- const pstring dyn_PRIVATE_DIR = PRIVATE_DIR;
-+
-+
-+/* In non-FHS mode, these should be configurable using 'lock dir =';
-+ but in FHS mode, they are their own directory. Implement as wrapper
-+ functions so that everything can still be kept in dynconfig.c.
-+ */
-+
-+char *dyn_STATEDIR(void)
-+{
++/* FHS-compatible directory defines */
+#ifdef FHS_COMPATIBLE
-+ return STATEDIR;
-+#else
-+ return lp_lockdir();
++#ifndef CACHEDIR
++#define CACHEDIR VARDIR "/cache/samba"
++#endif
++#ifndef STATEDIR
++#define STATEDIR VARDIR "/lib/samba"
+#endif
-+}
+
-+char *dyn_CACHEDIR(void)
-+{
-+#ifdef FHS_COMPATIBLE
-+ return CACHEDIR;
+#else
-+ return lp_lockdir();
++
++#define CACHEDIR lp_lockdir()
++#define STATEDIR lp_lockdir()
++
+#endif
-+}
-diff -uNr samba-3.0.0beta2.orig/source/groupdb/mapping.c samba-3.0.0beta2/source/groupdb/mapping.c
---- samba-3.0.0beta2.orig/source/groupdb/mapping.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/groupdb/mapping.c 2003-07-02 23:19:02.000000000 -0500
-@@ -134,7 +134,7 @@
-
- if (tdb && local_pid == sys_getpid())
- return True;
-- tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-+ tdb = tdb_open_log(state_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open group mapping database\n"));
- return False;
-diff -uNr samba-3.0.0beta2.orig/source/include/dynconfig.h samba-3.0.0beta2/source/include/dynconfig.h
---- samba-3.0.0beta2.orig/source/include/dynconfig.h 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/include/dynconfig.h 2003-07-02 23:19:02.000000000 -0500
-@@ -31,8 +31,12 @@
- extern pstring dyn_CONFIGFILE;
- extern pstring dyn_LOGFILEBASE, dyn_LMHOSTSFILE;
- extern pstring dyn_LIBDIR;
-+extern pstring dyn_CODEPAGEDIR;
- extern const fstring dyn_SHLIBEXT;
- extern const pstring dyn_LOCKDIR;
- extern const pstring dyn_PIDDIR;
- extern const pstring dyn_SMB_PASSWD_FILE;
- extern const pstring dyn_PRIVATE_DIR;
+
-+char *dyn_STATEDIR(void);
-+char *dyn_CACHEDIR(void);
-diff -uNr samba-3.0.0beta2.orig/source/intl/lang_tdb.c samba-3.0.0beta2/source/intl/lang_tdb.c
---- samba-3.0.0beta2.orig/source/intl/lang_tdb.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/intl/lang_tdb.c 2003-07-02 23:19:02.000000000 -0500
-@@ -123,7 +123,7 @@
- /* if no lang then we don't translate */
- if (!lang) return True;
-
-- asprintf(&msg_path, "%s.msg", lib_path((const char *)lang));
-+ asprintf(&msg_path, "%s.msg", data_path((const char *)lang));
- if (stat(msg_path, &st) != 0) {
- /* the msg file isn't available */
- free(msg_path);
-@@ -131,7 +131,7 @@
- }
-
-
-- asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang);
-+ asprintf(&path, "%s%s.tdb", state_path("lang_"), lang);
-
- tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
- if (!tdb) {
-diff -uNr samba-3.0.0beta2.orig/source/lib/account_pol.c samba-3.0.0beta2/source/lib/account_pol.c
---- samba-3.0.0beta2.orig/source/lib/account_pol.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/lib/account_pol.c 2003-07-02 23:19:02.000000000 -0500
-@@ -36,7 +36,7 @@
-
- if (tdb && local_pid == sys_getpid())
- return True;
-- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-+ tdb = tdb_open_log(state_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open account policy database\n"));
- return False;
-diff -uNr samba-3.0.0beta2.orig/source/lib/util.c samba-3.0.0beta2/source/lib/util.c
---- samba-3.0.0beta2.orig/source/lib/util.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/lib/util.c 2003-07-02 23:19:02.000000000 -0500
-@@ -2190,6 +2190,61 @@
+ #endif
+diff -uNr samba-2.2.8-orig/source/lib/util.c samba-2.2.8/source/lib/util.c
+--- samba-2.2.8-orig/source/lib/util.c Fri Mar 14 22:34:47 2003
++++ samba-2.2.8/source/lib/util.c Sun Mar 16 00:53:38 2003
+@@ -1872,6 +1872,46 @@
+ return fname;
}
- /**
-+ * @brief Returns an absolute path to a file in the Samba data directory.
-+ *
-+ * @param name File to find, relative to CODEPAGEDIR.
-+ *
-+ * @retval Pointer to a static #pstring containing the full path.
-+ **/
-+
-+char *data_path(const char *name)
-+{
-+ static pstring fname;
-+ snprintf(fname, sizeof(fname), "%s/%s", dyn_CODEPAGEDIR, name);
-+ return fname;
-+}
-+
+/*****************************************************************
+a useful function for returning a path in the Samba state directory
+ *****************************************************************/
@@ -217,7 +89,7 @@ diff -uNr samba-3.0.0beta2.orig/source/lib/util.c samba-3.0.0beta2/source/lib/ut
+{
+ static pstring fname;
+
-+ pstrcpy(fname,dyn_STATEDIR());
++ pstrcpy(fname,STATEDIR);
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
@@ -237,11 +109,11 @@ diff -uNr samba-3.0.0beta2.orig/source/lib/util.c samba-3.0.0beta2/source/lib/ut
+{
+ static pstring fname;
+
-+ pstrcpy(fname,dyn_CACHEDIR());
++ pstrcpy(fname,CACHEDIR);
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
-+ mkdir(fname,0755);
++ mkdir(fname,0755);
+ }
+
+ pstrcat(fname,"/");
@@ -250,113 +122,69 @@ diff -uNr samba-3.0.0beta2.orig/source/lib/util.c samba-3.0.0beta2/source/lib/ut
+ return fname;
+}
+
-+/**
- * @brief Returns the platform specific shared library extension.
- *
- * @retval Pointer to a static #fstring containing the extension.
-diff -uNr samba-3.0.0beta2.orig/source/lib/util_unistr.c samba-3.0.0beta2/source/lib/util_unistr.c
---- samba-3.0.0beta2.orig/source/lib/util_unistr.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/lib/util_unistr.c 2003-07-02 23:19:02.000000000 -0500
-@@ -54,8 +54,8 @@
- if (initialised) return;
- initialised = 1;
-
-- upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
-- lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
-+ upcase_table = map_file(data_path("upcase.dat"), 0x20000);
-+ lowcase_table = map_file(data_path("lowcase.dat"), 0x20000);
-
- /* we would like Samba to limp along even if these tables are
- not available */
-@@ -161,7 +161,7 @@
- return;
- }
-
-- valid_file = map_file(lib_path("valid.dat"), 0x10000);
-+ valid_file = map_file(data_path("valid.dat"), 0x10000);
- if (valid_file) {
- valid_table = valid_file;
- mapped_file = 1;
-diff -uNr samba-3.0.0beta2.orig/source/libsmb/samlogon_cache.c samba-3.0.0beta2/source/libsmb/samlogon_cache.c
---- samba-3.0.0beta2.orig/source/libsmb/samlogon_cache.c 2003-07-01 09:40:37.000000000 -0500
-+++ samba-3.0.0beta2/source/libsmb/samlogon_cache.c 2003-07-02 23:19:02.000000000 -0500
-@@ -34,7 +34,7 @@
- BOOL netsamlogon_cache_init(void)
- {
- if (!netsamlogon_tdb) {
-- netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0,
-+ netsamlogon_tdb = tdb_open_log(cache_path(NETSAMLOGON_TDB), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
- }
-
-@@ -67,7 +67,7 @@
- winbindd_cache.tdb open. Open the tdb if a NULL is passed. */
-
- if (!tdb) {
-- tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
-+ tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), 5000,
- TDB_DEFAULT, O_RDWR, 0600);
- if (!tdb) {
- DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n"));
---- samba_3_0/source/nmbd/nmbd_serverlistdb.c.orig 2003-09-08 10:53:13.000000000 -0400
-+++ samba_3_0/source/nmbd/nmbd_serverlistdb.c 2003-09-08 11:22:03.000000000 -0400
-@@ -327,7 +327,7 @@
-
- updatecount++;
+ /*******************************************************************
+ Given a filename - get its directory name
+ NB: Returned in static storage. Caveats:
+diff -uNr samba-2.2.8-orig/source/nmbd/nmbd_serverlistdb.c samba-2.2.8/source/nmbd/nmbd_serverlistdb.c
+--- samba-2.2.8-orig/source/nmbd/nmbd_serverlistdb.c Fri Feb 1 23:13:43 2002
++++ samba-2.2.8/source/nmbd/nmbd_serverlistdb.c Sun Mar 16 00:53:38 2003
+@@ -348,7 +348,7 @@
+
+ updatecount++;
-- pstrcpy(fname,lp_lockdir());
-+ pstrcpy(fname,dyn_CACHEDIR());
- trim_char(fname,'\0' ,'/');
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
---- samba-3.0.0rc2/source/nmbd/nmbd_winsserver.c.orig 2003-08-28 17:42:44.000000000 -0400
-+++ samba-3.0.0rc2/source/nmbd/nmbd_winsserver.c 2003-08-31 08:09:11.000000000 -0400
-@@ -228,7 +228,7 @@
-
- add_samba_names_to_subnet(wins_server_subnet);
-
-- if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
-+ if((fp = x_fopen(state_path(WINS_LIST),O_RDONLY,0)) == NULL) {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
- WINS_LIST, strerror(errno) ));
- return True;
-@@ -1759,7 +1759,7 @@
- }
+- pstrcpy(fname,lp_lockdir());
++ pstrcpy(fname,CACHEDIR);
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,SERVER_LIST);
+diff -uNr samba-2.2.8-orig/source/nmbd/nmbd_winsserver.c samba-2.2.8/source/nmbd/nmbd_winsserver.c
+--- samba-2.2.8-orig/source/nmbd/nmbd_winsserver.c Fri Mar 14 22:34:48 2003
++++ samba-2.2.8/source/nmbd/nmbd_winsserver.c Sun Mar 16 00:53:38 2003
+@@ -178,7 +178,7 @@
+
+ add_samba_names_to_subnet(wins_server_subnet);
+
+- if((fp = sys_fopen(lock_path(WINS_LIST),"r")) == NULL)
++ if((fp = sys_fopen(state_path(WINS_LIST),"r")) == NULL)
+ {
+ DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
+ WINS_LIST, strerror(errno) ));
+diff -uNr samba-2.2.8-orig/source/nsswitch/winbindd_cache.c samba-2.2.8/source/nsswitch/winbindd_cache.c
+--- samba-2.2.8-orig/source/nsswitch/winbindd_cache.c Tue Dec 10 15:58:15 2002
++++ samba-2.2.8/source/nsswitch/winbindd_cache.c Sun Mar 16 00:53:38 2003
+@@ -50,7 +50,7 @@
}
-
-- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
-+ slprintf(fname,sizeof(fname)-1,"%s/%s", dyn_STATEDIR(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
-diff -uNr samba-3.0.0beta2.orig/source/nsswitch/winbindd_cache.c samba-3.0.0beta2/source/nsswitch/winbindd_cache.c
---- samba-3.0.0beta2.orig/source/nsswitch/winbindd_cache.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/nsswitch/winbindd_cache.c 2003-07-02 23:19:02.000000000 -0500
-@@ -56,7 +56,7 @@
- if (opt_nocache)
- return;
+ if (opt_nocache) return;
- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
+ wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), 5000,
- TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
+ TDB_DEFAULT, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (!wcache->tdb) {
-diff -uNr samba-3.0.0beta2.orig/source/nsswitch/winbindd_util.c samba-3.0.0beta2/source/nsswitch/winbindd_util.c
---- samba-3.0.0beta2.orig/source/nsswitch/winbindd_util.c 2003-07-01 15:44:25.000000000 -0500
-+++ samba-3.0.0beta2/source/nsswitch/winbindd_util.c 2003-07-02 23:19:02.000000000 -0500
-@@ -813,7 +813,7 @@
- SMB_STRUCT_STAT stbuf;
- TDB_CONTEXT *idmap_tdb;
+diff -uNr samba-2.2.8-orig/source/nsswitch/winbindd_idmap.c samba-2.2.8/source/nsswitch/winbindd_idmap.c
+--- samba-2.2.8-orig/source/nsswitch/winbindd_idmap.c Tue Apr 30 15:27:26 2002
++++ samba-2.2.8/source/nsswitch/winbindd_idmap.c Sun Mar 16 00:53:38 2003
+@@ -427,14 +427,14 @@
+ {
+ /* Open tdb cache */
-- pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb"));
-+ pstrcpy(idmap_name, state_path("winbindd_idmap.tdb"));
+- if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
++ if (!(idmap_tdb = tdb_open_log(state_path("winbindd_idmap.tdb"), 0,
+ TDB_DEFAULT, O_RDWR | O_CREAT, 0600))) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n"));
+ return False;
+ }
- if (!file_exist(idmap_name, &stbuf)) {
- /* nothing to convert return */
-diff -uNr samba-3.0.0beta2.orig/source/param/loadparm.c samba-3.0.0beta2/source/param/loadparm.c
---- samba-3.0.0beta2.orig/source/param/loadparm.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/param/loadparm.c 2003-07-02 23:19:02.000000000 -0500
-@@ -104,6 +104,9 @@
+ /* possibly convert from an earlier version */
+- if (!idmap_convert(lock_path("winbindd_idmap.tdb"))) {
++ if (!idmap_convert(state_path("winbindd_idmap.tdb"))) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n"));
+ return False;
+ }
+diff -uNr samba-2.2.8-orig/source/param/loadparm.c samba-2.2.8/source/param/loadparm.c
+--- samba-2.2.8-orig/source/param/loadparm.c Fri Mar 14 22:34:48 2003
++++ samba-2.2.8/source/param/loadparm.c Sun Mar 16 00:53:38 2003
+@@ -107,6 +107,9 @@
char *szAddPrinterCommand;
char *szDeletePrinterCommand;
char *szOs2DriverMap;
@@ -366,67 +194,41 @@ diff -uNr samba-3.0.0beta2.orig/source/param/loadparm.c samba-3.0.0beta2/source/
char *szLockDir;
char *szPidDir;
char *szRootdir;
-@@ -1083,8 +1083,13 @@
- {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
- {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
- {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
+@@ -1046,8 +1049,13 @@
+ {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
+ {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING},
+ {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING},
+#ifdef FHS_COMPATIBLE
-+ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDirStub, NULL, NULL, 0},
-+ {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDirStub, NULL, NULL, 0},
++ {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDirStub, NULL, NULL, 0},
++ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDirStub, NULL, NULL, 0},
+#else
- {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
- {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
+ {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+#endif
- {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
+ {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, 0},
#ifdef WITH_UTMP
- {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
-diff -uNr samba-3.0.0beta2.orig/source/passdb/pdb_tdb.c samba-3.0.0beta2/source/passdb/pdb_tdb.c
---- samba-3.0.0beta2.orig/source/passdb/pdb_tdb.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/passdb/pdb_tdb.c 2003-07-02 23:19:02.000000000 -0500
-@@ -501,10 +501,7 @@
- if (location) {
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
-- pstring tdbfile;
-- get_private_directory(tdbfile);
-- pstrcat(tdbfile, "/");
-- pstrcat(tdbfile, PASSDB_FILE_NAME);
-+ char *tdbfile = state_path(PASSDB_FILE_NAME);
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile);
- }
-
-diff -uNr samba-3.0.0beta2.orig/source/passdb/privileges.c samba-3.0.0beta2/source/passdb/privileges.c
---- samba-3.0.0beta2.orig/source/passdb/privileges.c 2003-06-07 12:57:35.000000000 -0500
-+++ samba-3.0.0beta2/source/passdb/privileges.c 2003-07-02 23:19:02.000000000 -0500
-@@ -62,7 +62,7 @@
- /* initialise the privilege database */
- BOOL privilege_init(void)
- {
-- tdb = tdb_open_log(lock_path("privilege.tdb"), 0, TDB_DEFAULT,
-+ tdb = tdb_open_log(state_path("privilege.tdb"), 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open privilege database\n"));
-diff -uNr samba-3.0.0beta2.orig/source/passdb/secrets.c samba-3.0.0beta2/source/passdb/secrets.c
---- samba-3.0.0beta2.orig/source/passdb/secrets.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/passdb/secrets.c 2003-07-02 23:19:02.000000000 -0500
-@@ -37,8 +37,7 @@
+ {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
+diff -uNr samba-2.2.8-orig/source/passdb/secrets.c samba-2.2.8/source/passdb/secrets.c
+--- samba-2.2.8-orig/source/passdb/secrets.c Fri Mar 14 22:34:48 2003
++++ samba-2.2.8/source/passdb/secrets.c Sun Mar 16 00:57:57 2003
+@@ -34,9 +34,7 @@
if (tdb)
return True;
-- pstrcpy(fname, lp_private_dir());
+- get_private_directory(fname);
+-
- pstrcat(fname,"/secrets.tdb");
+ pstrcpy(fname, state_path("secrets.tdb"));
tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-diff -uNr samba-3.0.0beta2.orig/source/printing/nt_printing.c samba-3.0.0beta2/source/printing/nt_printing.c
---- samba-3.0.0beta2.orig/source/printing/nt_printing.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/printing/nt_printing.c 2003-07-02 23:19:02.000000000 -0500
-@@ -293,28 +293,28 @@
+diff -uNr samba-2.2.8-orig/source/printing/nt_printing.c samba-2.2.8/source/printing/nt_printing.c
+--- samba-2.2.8-orig/source/printing/nt_printing.c Fri Mar 14 22:34:48 2003
++++ samba-2.2.8/source/printing/nt_printing.c Sun Mar 16 00:53:38 2003
+@@ -262,24 +262,24 @@
+ if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
+ return True;
- if (tdb_drivers)
- tdb_close(tdb_drivers);
- tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_drivers) {
@@ -436,8 +238,6 @@ diff -uNr samba-3.0.0beta2.orig/source/printing/nt_printing.c samba-3.0.0beta2/s
return False;
}
- if (tdb_printers)
- tdb_close(tdb_printers);
- tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_printers) {
@@ -447,8 +247,6 @@ diff -uNr samba-3.0.0beta2.orig/source/printing/nt_printing.c samba-3.0.0beta2/s
return False;
}
- if (tdb_forms)
- tdb_close(tdb_forms);
- tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_forms) {
@@ -458,56 +256,26 @@ diff -uNr samba-3.0.0beta2.orig/source/printing/nt_printing.c samba-3.0.0beta2/s
return False;
}
-diff -uNr samba-3.0.0beta2.orig/source/printing/printing.c samba-3.0.0beta2/source/printing/printing.c
---- samba-3.0.0beta2.orig/source/printing/printing.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/printing/printing.c 2003-07-02 23:19:02.000000000 -0500
-@@ -174,8 +174,8 @@
- if (local_pid == sys_getpid())
- return True;
-
-- unlink(lock_path("printing.tdb"));
-- pstrcpy(printing_path,lock_path("printing"));
-+ unlink(cache_path("printing.tdb"));
-+ pstrcpy(printing_path,cache_path("printing"));
- mkdir(printing_path,0755);
+diff -uNr samba-2.2.8-orig/source/printing/printing.c samba-2.2.8/source/printing/printing.c
+--- samba-2.2.8-orig/source/printing/printing.c Fri Mar 14 22:34:48 2003
++++ samba-2.2.8/source/printing/printing.c Sun Mar 16 00:53:38 2003
+@@ -55,10 +55,10 @@
- local_pid = sys_getpid();
-diff -uNr samba-3.0.0beta2.orig/source/printing/printing_db.c samba-3.0.0beta2/source/printing/printing_db.c
---- samba-3.0.0beta2.orig/source/printing/printing_db.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/printing/printing_db.c 2003-07-02 23:19:02.000000000 -0500
-@@ -86,7 +86,7 @@
- DLIST_ADD(print_db_head, p);
+ if (tdb && local_pid == sys_getpid())
+ return True;
+- tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
++ tdb = tdb_open_log(cache_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb) {
+ DEBUG(0,("print_backend_init: Failed to open printing backend database %s.\n",
+- lock_path("printing.tdb") ));
++ cache_path("printing.tdb") ));
+ return False;
}
-
-- pstrcpy(printdb_path, lock_path("printing/"));
-+ pstrcpy(printdb_path, cache_path("printing/"));
- pstrcat(printdb_path, printername);
- pstrcat(printdb_path, ".tdb");
-
-diff -uNr samba-3.0.0beta2.orig/source/registry/reg_db.c samba-3.0.0beta2/source/registry/reg_db.c
---- samba-3.0.0beta2.orig/source/registry/reg_db.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/registry/reg_db.c 2003-07-02 23:19:02.000000000 -0500
-@@ -131,13 +131,13 @@
- * if we need to init the data in the registry
- */
-
-- tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
-+ tdb_reg = tdb_open_log(state_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
- if ( !tdb_reg )
- {
-- tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-+ tdb_reg = tdb_open_log(state_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if ( !tdb_reg ) {
- DEBUG(0,("init_registry: Failed to open registry %s (%s)\n",
-- lock_path("registry.tdb"), strerror(errno) ));
-+ state_path("registry.tdb"), strerror(errno) ));
- return False;
- }
-
-diff -uNr samba-3.0.0beta2.orig/source/rpc_server/srv_srvsvc_nt.c samba-3.0.0beta2/source/rpc_server/srv_srvsvc_nt.c
---- samba-3.0.0beta2.orig/source/rpc_server/srv_srvsvc_nt.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/rpc_server/srv_srvsvc_nt.c 2003-07-02 23:19:02.000000000 -0500
-@@ -133,10 +133,10 @@
+ local_pid = sys_getpid();
+diff -uNr samba-2.2.8-orig/source/rpc_server/srv_srvsvc_nt.c samba-2.2.8/source/rpc_server/srv_srvsvc_nt.c
+--- samba-2.2.8-orig/source/rpc_server/srv_srvsvc_nt.c Fri Mar 14 22:34:49 2003
++++ samba-2.2.8/source/rpc_server/srv_srvsvc_nt.c Sun Mar 16 00:53:38 2003
+@@ -127,10 +127,10 @@
if (share_tdb && local_pid == sys_getpid())
return True;
@@ -520,51 +288,18 @@ diff -uNr samba-3.0.0beta2.orig/source/rpc_server/srv_srvsvc_nt.c samba-3.0.0bet
return False;
}
-diff -uNr samba-3.0.0beta2.orig/source/sam/idmap_tdb.c samba-3.0.0beta2/source/sam/idmap_tdb.c
---- samba-3.0.0beta2.orig/source/sam/idmap_tdb.c 2003-07-01 15:44:26.000000000 -0500
-+++ samba-3.0.0beta2/source/sam/idmap_tdb.c 2003-07-02 23:19:02.000000000 -0500
-@@ -487,7 +487,7 @@
- BOOL tdb_is_new = False;
-
- /* use the old database if present */
-- tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
-+ tdbfile = strdup(state_path("winbindd_idmap.tdb"));
- if (!tdbfile) {
- DEBUG(0, ("idmap_init: out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
-diff -uNr samba-3.0.0beta2.orig/source/smbd/lanman.c samba-3.0.0beta2/source/smbd/lanman.c
---- samba-3.0.0beta2.orig/source/smbd/lanman.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/smbd/lanman.c 2003-07-02 23:19:02.000000000 -0500
-@@ -966,9 +966,9 @@
+diff -uNr samba-2.2.8-orig/source/smbd/lanman.c samba-2.2.8/source/smbd/lanman.c
+--- samba-2.2.8-orig/source/smbd/lanman.c Fri Mar 14 22:34:49 2003
++++ samba-2.2.8/source/smbd/lanman.c Sun Mar 16 00:53:38 2003
+@@ -1109,9 +1109,9 @@
BOOL local_list_only;
int i;
-- lines = file_lines_load(lock_path(SERVER_LIST), NULL);
-+ lines = file_lines_load(cache_path(SERVER_LIST), NULL);
+- lines = file_lines_load(lock_path(SERVER_LIST), NULL, False);
++ lines = file_lines_load(cache_path(SERVER_LIST), NULL, False);
if (!lines) {
- DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno)));
+ DEBUG(4,("Can't open %s - %s\n",cache_path(SERVER_LIST),strerror(errno)));
return(0);
}
-diff -uNr samba-3.0.0beta2.orig/source/wrepld/process.c samba-3.0.0beta2/source/wrepld/process.c
---- samba-3.0.0beta2.orig/source/wrepld/process.c 2003-07-02 23:26:47.000000000 -0500
-+++ samba-3.0.0beta2/source/wrepld/process.c 2003-07-02 23:19:02.000000000 -0500
-@@ -197,7 +197,7 @@
- {
- TDB_CONTEXT *tdb;
-
-- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
-+ tdb = tdb_open_log(state_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("get_our_last_id: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
-@@ -489,7 +489,7 @@
- }
-
-
-- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
-+ tdb = tdb_open_log(state_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("send_entry_request: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
diff --git a/packaging/Debian/debian/patches/installswat.sh.patch b/packaging/Debian/debian/patches/installswat.sh.patch
deleted file mode 100644
index b425e3bef76..00000000000
--- a/packaging/Debian/debian/patches/installswat.sh.patch
+++ /dev/null
@@ -1,76 +0,0 @@
---- samba_3_0/source/script/installswat.sh.orig 2003-08-28 18:03:10.000000000 -0400
-+++ samba_3_0/source/script/installswat.sh 2003-08-28 18:11:14.000000000 -0400
-@@ -9,7 +9,7 @@
- echo Installing the Samba Web Administration Tool
-
- LANGS=". `cd $SRCDIR../swat/; /bin/echo lang/??`"
--echo Installing langs are `cd $SRCDIR../swat/lang/; /bin/echo ??`
-+echo Installing the following additional langs: `cd $SRCDIR../swat/lang/; /bin/echo ??`
-
- for ln in $LANGS; do
- SWATLANGDIR=$SWATDIR/$ln
-@@ -23,21 +23,17 @@
- fi
- fi
- done
--done
--
--# Install images
--for ln in $LANGS; do
-
--for f in $SRCDIR../swat/$ln/images/*.gif; do
-+ # Install images
-+ for f in $SRCDIR../swat/$ln/images/*.gif; do
- FNAME=$SWATDIR/$ln/images/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
--done
--
--# Install html help
-+ done
-
--for f in $SRCDIR../swat/$ln/help/*.html; do
-+ # Install html help
-+ for f in $SRCDIR../swat/$ln/help/*.html; do
- FNAME=$SWATDIR/$ln/help/`basename $f`
- echo $FNAME
- if [ "x$BOOKDIR" = "x" ]; then
-@@ -49,26 +45,24 @@
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- rm -f $f
- chmod 0644 $FNAME
--done
--
--# Install html documentation
--
--for f in $SRCDIR../docs/htmldocs/*.html; do
-- FNAME=$SWATDIR/help/`basename $f`
-- echo $FNAME
-- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
-- chmod 0644 $FNAME
--done
--
--# Install "server-side" includes
-+ done
-
--for f in $SRCDIR../swat/$ln/include/*.html; do
-+ # Install "server-side" includes
-+ for f in $SRCDIR../swat/$ln/include/*.html; do
- FNAME=$SWATDIR/$ln/include/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
-+ done
-+
- done
-
-+# Install html documentation
-+for f in $SRCDIR../docs/htmldocs/*.html; do
-+ FNAME=$SWATDIR/help/`basename $f`
-+ echo $FNAME
-+ ln -s ../../../doc/samba-doc/htmldocs/`basename $f` $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
-+ chmod 0644 $FNAME
- done
-
- # Install Using Samba book (but only if it is there)
diff --git a/packaging/Debian/debian/patches/loadparm.patch b/packaging/Debian/debian/patches/loadparm.patch
new file mode 100755
index 00000000000..3741f8c1e06
--- /dev/null
+++ b/packaging/Debian/debian/patches/loadparm.patch
@@ -0,0 +1,78 @@
+--- samba-2.2.5/source/param/loadparm.c.orig Tue Jun 18 23:15:07 2002
++++ samba-2.2.5/source/param/loadparm.c Tue Jun 18 23:15:07 2002
+@@ -1146,26 +1146,26 @@
+ case PRINT_AIX:
+ case PRINT_LPRNT:
+ case PRINT_LPROS2:
+- string_set(&sDefault.szLpqcommand, "lpq -P%p");
+- string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
++ string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
++ string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
+ string_set(&sDefault.szPrintcommand,
+- "lpr -r -P%p %s");
++ "lpr -r -P'%p' %s");
+ break;
+
+ case PRINT_LPRNG:
+ case PRINT_PLP:
+- string_set(&sDefault.szLpqcommand, "lpq -P%p");
+- string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
++ string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
++ string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
+ string_set(&sDefault.szPrintcommand,
+- "lpr -r -P%p %s");
++ "lpr -r -P'%p' %s");
+ string_set(&sDefault.szQueuepausecommand,
+- "lpc stop %p");
++ "lpc stop '%p'");
+ string_set(&sDefault.szQueueresumecommand,
+- "lpc start %p");
++ "lpc start '%p'");
+ string_set(&sDefault.szLppausecommand,
+- "lpc hold %p %j");
++ "lpc hold '%p' %j");
+ string_set(&sDefault.szLpresumecommand,
+- "lpc release %p %j");
++ "lpc release '%p' %j");
+ break;
+
+ case PRINT_CUPS:
+@@ -1181,19 +1181,19 @@
+ string_set(&Globals.szPrintcapname, "cups");
+ #else
+ string_set(&sDefault.szLpqcommand,
+- "/usr/bin/lpstat -o %p");
++ "/usr/bin/lpstat -o '%p'");
+ string_set(&sDefault.szLprmcommand,
+- "/usr/bin/cancel %p-%j");
++ "/usr/bin/cancel '%p-%j'");
+ string_set(&sDefault.szPrintcommand,
+- "/usr/bin/lp -d %p %s; rm %s");
++ "/usr/bin/lp -d '%p' %s; rm %s");
+ string_set(&sDefault.szLppausecommand,
+- "lp -i %p-%j -H hold");
++ "lp -i '%p-%j' -H hold");
+ string_set(&sDefault.szLpresumecommand,
+- "lp -i %p-%j -H resume");
++ "lp -i '%p-%j' -H resume");
+ string_set(&sDefault.szQueuepausecommand,
+- "/usr/bin/disable %p");
++ "/usr/bin/disable '%p'");
+ string_set(&sDefault.szQueueresumecommand,
+- "/usr/bin/enable %p");
++ "/usr/bin/enable '%p'");
+ string_set(&Globals.szPrintcapname, "lpstat");
+ #endif /* HAVE_CUPS */
+ break;
+@@ -1513,7 +1513,10 @@
+ else
+ StrnCpy(ret, s, len);
+
+- trim_string(ret, "\"", "\"");
++ if (trim_string(ret, "\"", "\"")) {
++ if (strchr(ret,'"') != NULL)
++ StrnCpy(ret, s, len);
++ }
+
+ standard_sub_basic(ret, len + 100);
+ return (ret);
diff --git a/packaging/Debian/debian/patches/lpq_parse.c.patch b/packaging/Debian/debian/patches/lpq_parse.c.patch
new file mode 100755
index 00000000000..5e8d0cc1f0e
--- /dev/null
+++ b/packaging/Debian/debian/patches/lpq_parse.c.patch
@@ -0,0 +1,12 @@
+--- samba/source/printing/lpq_parse.c.orig 2002-07-24 09:22:49.000000000 -0400
++++ samba/source/printing/lpq_parse.c 2002-10-13 01:43:10.000000000 -0400
+@@ -265,6 +265,9 @@
+ buf->status = LPQ_PAUSED;
+ }
+
++ if(strequal(tokarr[LPRNG_RANKTOK],"done"))
++ buf->status = LPQ_PRINTED;
++
+ buf->priority = *tokarr[LPRNG_PRIOTOK] -'A';
+
+ buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
diff --git a/packaging/Debian/debian/patches/nmbd-signalling.patch b/packaging/Debian/debian/patches/nmbd-signalling.patch
deleted file mode 100644
index ca04cce3bfa..00000000000
--- a/packaging/Debian/debian/patches/nmbd-signalling.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-diff -uNr samba-2.999+3.0.alpha21.orig/source/nmbd/nmbd_subnetdb.c samba-2.999+3.0.alpha21/source/nmbd/nmbd_subnetdb.c
---- samba-2.999+3.0.alpha21.orig/source/nmbd/nmbd_subnetdb.c 2002-11-26 20:54:19.000000000 -0600
-+++ samba-2.999+3.0.alpha21/source/nmbd/nmbd_subnetdb.c 2002-12-16 23:34:13.000000000 -0600
-@@ -214,12 +214,16 @@
- extern struct in_addr loopback_ip;
-
- if(num_interfaces == 0) {
-+ void (*old_handler)(int);
-+
- DEBUG(0,("create_subnets: No local interfaces !\n"));
- DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
-+ old_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
- while (iface_count() == 0) {
- sleep(5);
- load_interfaces();
- }
-+ CatchSignal( SIGTERM, SIGNAL_CAST old_handler );
- }
-
- num_interfaces = iface_count();
diff --git a/packaging/Debian/debian/patches/samba.patch b/packaging/Debian/debian/patches/samba.patch
index 8707ec517ba..e7dd4d8813e 100644
--- a/packaging/Debian/debian/patches/samba.patch
+++ b/packaging/Debian/debian/patches/samba.patch
@@ -1,16 +1,15 @@
-diff -uNr samba-3.0.0beta1.orig/source/client/smbmount.c samba-3.0.0beta1/source/client/smbmount.c
---- samba-3.0.0beta1.orig/source/client/smbmount.c 2003-06-07 12:57:32.000000000 -0500
-+++ samba-3.0.0beta1/source/client/smbmount.c 2003-06-30 20:12:22.000000000 -0500
-@@ -765,7 +765,7 @@
+--- samba-2.2.4/source/client/smbmount.c.orig Wed May 1 23:13:57 2002
++++ samba-2.2.4/source/client/smbmount.c Thu May 2 00:20:44 2002
+@@ -716,7 +716,7 @@
*lp = 0;
pstrcpy(password,lp+1);
got_pass = True;
-- memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
-+ memset(strchr_m(opteq+1,'%')+1,'\0',strlen(password));
+- memset(strchr(opteq+1,'%')+1,'X',strlen(password));
++ memset(strchr(opteq+1,'%')+1,'\0',strlen(password));
}
- if ((lp=strchr_m(username,'/'))) {
+ if ((lp=strchr(username,'/'))) {
*lp = 0;
-@@ -775,7 +775,7 @@
+@@ -726,7 +726,7 @@
!strcmp(opts, "password")) {
pstrcpy(password,opteq+1);
got_pass = True;
@@ -19,19 +18,41 @@ diff -uNr samba-3.0.0beta1.orig/source/client/smbmount.c samba-3.0.0beta1/source
} else if(!strcmp(opts, "credentials")) {
pstrcpy(credentials,opteq+1);
} else if(!strcmp(opts, "netbiosname")) {
-@@ -889,7 +901,7 @@
+@@ -819,7 +819,7 @@
*p = 0;
pstrcpy(password,p+1);
got_pass = True;
-- memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
-+ memset(strchr_m(getenv("USER"),'%')+1,'\0',strlen(password));
+- memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
++ memset(strchr(getenv("USER"),'%')+1,'\0',strlen(password));
}
- strupper_m(username);
+ strupper(username);
}
-diff -uNr samba-3.0.0beta1.orig/source/script/installbin.sh samba-3.0.0beta1/source/script/installbin.sh
---- samba-3.0.0beta1.orig/source/script/installbin.sh 2002-04-22 13:16:20.000000000 -0500
-+++ samba-3.0.0beta1/source/script/installbin.sh 2003-06-30 20:12:22.000000000 -0500
-@@ -22,9 +22,11 @@
+--- samba-2.2.4/source/pam_smbpass/pam_smb_passwd.c.orig Wed May 1 23:14:47 2002
++++ samba-2.2.4/source/pam_smbpass/pam_smb_passwd.c Thu May 2 00:20:44 2002
+@@ -190,6 +190,11 @@
+
+ } else if (flags & PAM_UPDATE_AUTHTOK) {
+
++/*
++ The following has been commented out per Steve Langasek
++ <vorlon@debian.org> instructions. It's about Debian bug
++ #113763.
++*/
+ #if 0
+ /* We used to return when this flag was set, but that breaks
+ password synchronization when /other/ tokens are expired. For
+--- samba-2.2.2.cvs20020120.orig/source/script/installbin.sh
++++ samba-2.2.2.cvs20020120/source/script/installbin.sh
+@@ -11,7 +11,7 @@
+ shift
+ shift
+
+-for d in $BASEDIR $BINDIR $LIBDIR $VARDIR $BASEDIR/private; do
++for d in $BASEDIR $BINDIR $LIBDIR $VARDIR; do
+ if [ ! -d $d ]; then
+ mkdir $d
+ if [ ! -d $d ]; then
+@@ -33,9 +33,11 @@
chmod $INSTALLPERMS $BINDIR/$p2
# this is a special case, mount needs this in a specific location
@@ -46,44 +67,45 @@ diff -uNr samba-3.0.0beta1.orig/source/script/installbin.sh samba-3.0.0beta1/sou
done
-diff -uNr samba-3.0.0beta1.orig/source/smbd/service.c samba-3.0.0beta1/source/smbd/service.c
---- samba-3.0.0beta1.orig/source/smbd/service.c 2003-06-07 12:57:39.000000000 -0500
-+++ samba-3.0.0beta1/source/smbd/service.c 2003-06-30 20:12:57.000000000 -0500
-@@ -887,6 +887,9 @@
- file_close_conn(conn);
- dptr_closecnum(conn);
+--- samba-2.2.2.cvs20020120.orig/source/script/installswat.sh
++++ samba-2.2.2.cvs20020120/source/script/installswat.sh
+@@ -48,8 +48,8 @@
+ for f in $SRCDIR../docs/htmldocs/*.html; do
+ FNAME=$SWATDIR/help/`basename $f`
+ echo $FNAME
+- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
+- chmod 0644 $FNAME
++ ln -s ../../../doc/samba-doc/htmldocs/`basename $f` $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
++# chmod 0644 $FNAME
+ done
-+ /* make sure we leave the directory available for unmount */
-+ vfs_ChDir(conn, "/");
-+
- /* execute any "postexec = " line */
- if (*lp_postexec(SNUM(conn)) &&
- change_to_user(conn, vuid)) {
-@@ -906,8 +909,5 @@
- smbrun(cmd,NULL);
- }
+ # Install "server-side" includes
+@@ -63,7 +63,10 @@
+
+ # Install Using Samba book
+
+-if [ "x$BOOKDIR" != "x" ]; then
++# For Debian we do not install anything here, we just create a symlink
++# pointing to /usr/share/doc/samba-doc/htmldocs/using_samba/ in
++# debian/rules (peloy@debian.org)
++if /bin/false; then
-- /* make sure we leave the directory available for unmount */
-- vfs_ChDir(conn, "/");
--
- conn_free(conn);
- }
-diff -uNr samba-3.0.0beta1.orig/source/smbwrapper/smbsh.c samba-3.0.0beta1/source/smbwrapper/smbsh.c
---- samba-3.0.0beta1.orig/source/smbwrapper/smbsh.c 2003-06-07 12:57:40.000000000 -0500
-+++ samba-3.0.0beta1/source/smbwrapper/smbsh.c 2003-06-30 20:12:22.000000000 -0500
-@@ -36,7 +36,7 @@
+ # Create directories
+
+--- samba-2.2.2.cvs20020120.orig/source/smbwrapper/smbsh.c
++++ samba-2.2.2.cvs20020120/source/smbwrapper/smbsh.c
+@@ -39,7 +39,7 @@
int main(int argc, char *argv[])
{
char *p, *u;
-- const char *libd = dyn_BINDIR;
-+ const char *libd = dyn_LIBDIR;
+- char *libd = BINDIR;
++ char *libd = "/usr/share/samba";
pstring line, wd;
int opt;
extern char *optarg;
-diff -uNr samba-3.0.0beta1.orig/source/web/diagnose.c samba-3.0.0beta1/source/web/diagnose.c
---- samba-3.0.0beta1.orig/source/web/diagnose.c 2003-06-07 12:57:41.000000000 -0500
-+++ samba-3.0.0beta1/source/web/diagnose.c 2003-06-30 20:12:22.000000000 -0500
-@@ -70,6 +70,7 @@
+--- samba-2.2.2.cvs20020120.orig/source/web/diagnose.c
++++ samba-2.2.2.cvs20020120/source/web/diagnose.c
+@@ -54,6 +54,7 @@
static struct cli_state cli;
extern struct in_addr loopback_ip;
@@ -91,3 +113,40 @@ diff -uNr samba-3.0.0beta1.orig/source/web/diagnose.c samba-3.0.0beta1/source/we
if (!cli_initialise(&cli))
return False;
+--- samba-2.2.2.cvs20020120.orig/source/web/startstop.c
++++ samba-2.2.2.cvs20020120/source/web/startstop.c
+@@ -37,7 +37,7 @@
+ return;
+ }
+
+- slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", SBINDIR);
++ slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", "/usr/sbin");
+
+ become_daemon();
+
+@@ -58,7 +58,7 @@
+ return;
+ }
+
+- slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", SBINDIR);
++ slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", "/usr/sbin");
+
+ become_daemon();
+
+--- samba/source/smbd/service.c.orig 2002-10-12 11:54:24.000000000 -0400
++++ samba/source/smbd/service.c 2002-10-13 01:43:10.000000000 -0400
+@@ -698,6 +698,14 @@
+ smbrun(cmd,NULL);
+ }
+
++ /* If our root postexec command includes a call to 'unmount', we want
++ to make sure we aren't blocking the mount point. */
++ /* I think this patch should go here, but I am not sure since
++ the code looks very different than in Samba 2.2.2. Will come
++ back later; should check what change_to_root_user() does. Eloy.-
++ vfs_ChDir(conn,"/");
++ /*
++
+ change_to_root_user();
+ /* execute any "root postexec = " line */
+ if (*lp_rootpostexec(SNUM(conn))) {
diff --git a/packaging/Debian/debian/patches/smbadduser.patch b/packaging/Debian/debian/patches/smbadduser.patch
new file mode 100755
index 00000000000..9bfb4573012
--- /dev/null
+++ b/packaging/Debian/debian/patches/smbadduser.patch
@@ -0,0 +1,22 @@
+--- samba-2.2.2.cvs20020120.orig/source/script/smbadduser
++++ samba-2.2.2.cvs20020120/source/script/smbadduser
+@@ -2,13 +2,14 @@
+ #
+ # smbadduser - Written by Mike Zakharoff
+ #
++# Customized for Debian by Eloy A. Paris <peloy@debian.org>
++#
+ unalias *
+-set path = ($path /usr/local/samba/bin)
++# No need to set a path in Debian
++#set path = ($path /usr/local/samba/bin)
+
+-set smbpasswd = /usr/local/samba/private/smbpasswd
+-#set smbpasswd = /etc/samba.d/smbpasswd
+-set user_map = /usr/local/samba/lib/users.map
+-#set user_map = /etc/samba.d/smbusers
++set smbpasswd = /etc/samba/smbpasswd
++set user_map = /etc/samba/users.map
+ #
+ # Set to site specific passwd command
+ #
diff --git a/packaging/Debian/debian/patches/smbclient-pager.patch b/packaging/Debian/debian/patches/smbclient-pager.patch
index 3ee85d4118c..d600c1bd9c2 100644
--- a/packaging/Debian/debian/patches/smbclient-pager.patch
+++ b/packaging/Debian/debian/patches/smbclient-pager.patch
@@ -1,7 +1,6 @@
-diff -uNr samba-2.999+3.0cvs20020906.orig/source/include/local.h samba-2.999+3.0cvs20020906/source/include/local.h
---- samba-2.999+3.0cvs20020906.orig/source/include/local.h 2002-09-04 14:13:06.000000000 -0500
-+++ samba-2.999+3.0cvs20020906/source/include/local.h 2002-09-08 14:19:24.000000000 -0500
-@@ -109,7 +109,7 @@
+--- samba-2.2.2.cvs20020120.orig/source/include/local.h
++++ samba-2.2.2.cvs20020120/source/include/local.h
+@@ -105,7 +105,7 @@
/* the default pager to use for the client "more" command. Users can
override this with the PAGER environment variable */
#ifndef PAGER
diff --git a/packaging/Debian/debian/patches/smbclient-tar.patch.unused b/packaging/Debian/debian/patches/smbclient-tar.patch.unused
deleted file mode 100644
index e2a4c3ce2c0..00000000000
--- a/packaging/Debian/debian/patches/smbclient-tar.patch.unused
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -uNr samba-3.0.0beta2.orig/source/client/client.c samba-3.0.0beta2/source/client/client.c
---- samba-3.0.0beta2.orig/source/client/client.c 2003-07-01 22:36:24.000000000 -0500
-+++ samba-3.0.0beta2/source/client/client.c 2003-07-06 15:17:36.000000000 -0500
-@@ -2773,6 +2773,7 @@
- int opt;
- pstring query_host;
- BOOL message = False;
-+ char* tar_args = NULL;
- extern char tar_type;
- pstring term_code;
- static const char *new_name_resolve_order = NULL;
-@@ -2816,7 +2817,7 @@
- max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);
- break;
- case 'T':
-- if (!tar_parseargs(argc, argv, poptGetOptArg(pc), optind)) {
-+ if (!(tar_args = poptGetOptArg(pc))) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
-@@ -2917,6 +2917,22 @@
- pstrcpy(cmdline_auth_info.password,poptGetArg(pc));
- }
-
-+ /* The tar command may take a number of string options; pass
-+ everything we have left to tar_parseargs(). */
-+ if (tar_args) {
-+ const char **argv2 = poptGetArgs(pc);
-+ int argc2 = 0;
-+
-+ if (argv2) {
-+ while (argv2[argc2]) argc2++;
-+ }
-+
-+ if (!tar_parseargs(argc2, argv2, tar_args, 0)) {
-+ poptPrintUsage(pc, stderr, 0);
-+ exit(1);
-+ }
-+ }
-+
- init_names();
-
- if(new_name_resolve_order)
diff --git a/packaging/Debian/debian/patches/smbclient-xfer-speed.patch b/packaging/Debian/debian/patches/smbclient-xfer-speed.patch
new file mode 100755
index 00000000000..bbadda33870
--- /dev/null
+++ b/packaging/Debian/debian/patches/smbclient-xfer-speed.patch
@@ -0,0 +1,17 @@
+--- samba-2.2.2.cvs20020120/source/client/client.c.orig Wed Jan 23 23:32:44 2002
++++ samba-2.2.2.cvs20020120/source/client/client.c Wed Jan 23 23:33:50 2002
+@@ -91,10 +91,10 @@
+ extern file_info def_finfo;
+
+ /* timing globals */
+-int get_total_size = 0;
+-int get_total_time_ms = 0;
+-int put_total_size = 0;
+-int put_total_time_ms = 0;
++SMB_BIG_UINT get_total_size = 0;
++unsigned int get_total_time_ms = 0;
++SMB_BIG_UINT put_total_size = 0;
++unsigned int put_total_time_ms = 0;
+
+ /* totals globals */
+ static double dir_total;
diff --git a/packaging/Debian/debian/patches/smbmount-nomtab.patch b/packaging/Debian/debian/patches/smbmount-nomtab.patch
index 88071481705..e85ceaed32a 100644
--- a/packaging/Debian/debian/patches/smbmount-nomtab.patch
+++ b/packaging/Debian/debian/patches/smbmount-nomtab.patch
@@ -1,6 +1,5 @@
-diff -uNr samba-3.0alpha22.orig/source/client/smbmnt.c samba-3.0alpha22/source/client/smbmnt.c
---- samba-3.0alpha22.orig/source/client/smbmnt.c 2003-03-15 12:11:39.000000000 -0600
-+++ samba-3.0alpha22/source/client/smbmnt.c 2003-03-15 12:11:49.000000000 -0600
+--- samba-2.2.3a/source/client/smbmnt.c.orig Tue Apr 2 09:58:18 2002
++++ samba-2.2.3a/source/client/smbmnt.c Tue Apr 2 09:58:24 2002
@@ -28,6 +28,7 @@
static uid_t mount_uid;
static gid_t mount_gid;
@@ -102,18 +101,17 @@ diff -uNr samba-3.0alpha22.orig/source/client/smbmnt.c samba-3.0alpha22/source/c
return 0;
}
-diff -uNr samba-3.0alpha22.orig/source/client/smbmount.c samba-3.0alpha22/source/client/smbmount.c
---- samba-3.0alpha22.orig/source/client/smbmount.c 2003-03-15 12:04:29.000000000 -0600
-+++ samba-3.0alpha22/source/client/smbmount.c 2003-03-15 12:15:10.000000000 -0600
-@@ -48,6 +48,7 @@
+--- samba/source/client/smbmount.c.orig 2002-10-13 01:34:58.000000000 -0400
++++ samba/source/client/smbmount.c 2002-10-13 01:34:59.000000000 -0400
+@@ -50,6 +50,7 @@
static int mount_ro;
static unsigned mount_fmask;
static unsigned mount_dmask;
+static BOOL no_mtab = False;
- static BOOL use_kerberos;
- /* TODO: Add code to detect smbfs version in kernel */
- static BOOL status32_smbfs = False;
-@@ -273,6 +274,9 @@
+
+ static void usage(void);
+
+@@ -250,6 +251,9 @@
return;
}
@@ -121,9 +119,9 @@ diff -uNr samba-3.0alpha22.orig/source/client/smbmount.c samba-3.0alpha22/source
+ return;
+
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
- DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
+ DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", getpid()));
return;
-@@ -466,6 +470,9 @@
+@@ -444,6 +448,9 @@
args[i++] = "-s";
args[i++] = svc2;
@@ -133,7 +131,7 @@ diff -uNr samba-3.0alpha22.orig/source/client/smbmount.c samba-3.0alpha22/source
if (mount_ro) {
args[i++] = "-r";
}
-@@ -661,7 +668,7 @@
+@@ -626,7 +633,7 @@
****************************************************************************/
static void usage(void)
{
@@ -142,7 +140,7 @@ diff -uNr samba-3.0alpha22.orig/source/client/smbmount.c samba-3.0alpha22/source
printf("Version %s\n\n",VERSION);
-@@ -739,8 +746,13 @@
+@@ -691,8 +698,13 @@
argc -= 2;
argv += 2;
diff --git a/packaging/Debian/debian/patches/smbstatus-locking.patch b/packaging/Debian/debian/patches/smbstatus-locking.patch
deleted file mode 100644
index d37896a3699..00000000000
--- a/packaging/Debian/debian/patches/smbstatus-locking.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-diff -uNr samba-2.999+3.0.alpha21.orig/source/utils/status.c samba-2.999+3.0.alpha21/source/utils/status.c
---- samba-2.999+3.0.alpha21.orig/source/utils/status.c 2002-11-26 20:54:22.000000000 -0600
-+++ samba-2.999+3.0.alpha21/source/utils/status.c 2002-12-16 23:37:14.000000000 -0600
-@@ -630,6 +630,16 @@
- if (!shares_only) {
- int ret;
-
-+ tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
-+
-+ if (!tdb) {
-+ d_printf("%s not initialised\n", lock_path("locking.tdb"));
-+ d_printf("This is normal if an SMB client has never connected to your server.\n");
-+ exit(0);
-+ } else {
-+ tdb_close(tdb);
-+ }
-+
- if (!locking_init(1)) {
- d_printf("Can't initialise locking module - exiting\n");
- exit(1);
diff --git a/packaging/Debian/debian/patches/smbtar-exclude.patch b/packaging/Debian/debian/patches/smbtar-exclude.patch
new file mode 100755
index 00000000000..a5cacc82824
--- /dev/null
+++ b/packaging/Debian/debian/patches/smbtar-exclude.patch
@@ -0,0 +1,12 @@
+diff -uNr samba-2.2.4.orig/source/client/clitar.c samba-2.2.4/source/client/clitar.c
+--- samba-2.2.4.orig/source/client/clitar.c Thu May 2 20:02:58 2002
++++ samba-2.2.4/source/client/clitar.c Sat Jun 1 00:25:28 2002
+@@ -515,7 +515,7 @@
+ if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
+
+ /* check for s1 is an "initial" string of s2 */
+- if (*s2 == '/' || *s2 == '\\') return 0;
++ if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
+
+ return *s1-*s2;
+ }
diff --git a/packaging/Debian/debian/po/POTFILES.in b/packaging/Debian/debian/po/POTFILES.in
deleted file mode 100644
index 95a7ea81506..00000000000
--- a/packaging/Debian/debian/po/POTFILES.in
+++ /dev/null
@@ -1,3 +0,0 @@
-[type: gettext/rfc822deb] samba-common.templates
-[type: gettext/rfc822deb] samba.templates
-[type: gettext/rfc822deb] swat.templates
diff --git a/packaging/Debian/debian/po/es.po b/packaging/Debian/debian/po/es.po
deleted file mode 100644
index 0d1d1a770de..00000000000
--- a/packaging/Debian/debian/po/es.po
+++ /dev/null
@@ -1,298 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Samba for Debian 3.0.0beta2-1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-30 19:08-0500\n"
-"PO-Revision-Date: 2003-07-02 21:51-0500\n"
-"Last-Translator: Steve Langasek <vorlon@debian.org>\n"
-"Language-Team: Spanish <debian-l10n-spanish@lists.debian.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Description
-#: ../samba-common.templates:3
-msgid "Character Set for Unix filesystem"
-msgstr "Juego de caracteres para el sistema de ficheros Unix"
-
-#
-#. Description
-#: ../samba-common.templates:3
-msgid ""
-"You currently have a \"character set\" configured in your smb.conf. In "
-"Samba 3.0, this option is replaced by a new option, \"unix charset\". Please "
-"specify the character set you wish to use for theis new option, which "
-"controls how Samba interprets filenames on the file system."
-msgstr ""
-"Actualmente hay una opción de \"character set\" en smb.conf. En Samba 3.0 "
-"esta opción ha sido reemplazado por una opción nueva: \"unix charset\". Por "
-"favor, indique el juego de caracteres que desea usar para esta opción nueva, "
-"que controla cómo Samba interpretará los nombres en el sistema de ficheros."
-
-#. Description
-#: ../samba-common.templates:3
-msgid "If you leave this option blank, your smb.conf will not be changed."
-msgstr "Si deja en blanco este campo, no se cambiará smb.conf."
-
-#. Description
-#: ../samba-common.templates:13
-msgid "Character Set for DOS clients"
-msgstr "Juego de caracteres para los clientes DOS"
-
-#. Description
-#: ../samba-common.templates:13
-msgid ""
-"You currently have a \"client code page\" set in your smb.conf. In Samba "
-"3.0, this option is replaced by the option \"dos charset\". Please specify "
-"the character set you wish to use for this new option. In most cases, the "
-"default chosen for you will be sufficient. Note that this option is not "
-"needed to support Windows clients, it is only for DOS clients. If you leave "
-"this option blank, your smb.conf will not be changed."
-msgstr ""
-"Actualmente hay una opción de \"client code page\" en smb.conf. En Samba "
-"3.0 esta opción ha sido reemplazado por la opción \"dos charset\". Por "
-"favor, indique el juego de caracteres que desea usar para esta opción "
-"nueva. Esta opción no se necesita en absoluto para clientes Windows; es "
-"exclusivamente para los clientes DOS. Si deja en blanco este campo, no se "
-"cambiará smb.conf."
-
-#. Description
-#: ../samba-common.templates:24
-msgid "Modify smb.conf to use WINS settings from DHCP?"
-msgstr ""
-"¿Modificar smb.conf para usar la configuración WINS que proviene de DHCP?"
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"If your computer gets IP address information from a DHCP server on the "
-"network, the DHCP server may also provide information about WINS servers "
-"(\"NetBIOS name servers\") present on the network. This requires a change "
-"to your smb.conf file so that DHCP-provided WINS settings will automatically "
-"be read from /etc/samba/dhcp.conf."
-msgstr ""
-"Si su sistema recibe la dirección IP desde un servidor DHCP en la red, el "
-"servidor DHCP también puede proveerle informaciones sobre los servidores de "
-"WINS que haya en la red. Esto requiere un cambio en el fichero smb.conf "
-"para que la configuración de WINS proveniente de DHCP se lea automaticamente "
-"de /etc/samba/dhcp.conf."
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"You must have the dhcp3-client package installed to take advantage of this "
-"feature."
-msgstr ""
-"Hay que instalar el paquete dhcp3-client para aprovechar esta funcionalidad."
-
-#. Description
-#: ../samba-common.templates:37
-msgid "Configure smb.conf through debconf?"
-msgstr "¿Configurar smb.conf mediante debconf?"
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"The rest of the configuration of Samba deals with questions that affect "
-"parameters in /etc/samba/smb.conf, which is the file used to configure the "
-"Samba programs (nmbd and smbd.) Your current smb.conf contains an 'include' "
-"line or an option that spans multiple lines, which could confuse debconf and "
-"require you to edit your smb.conf by hand to get it working again."
-msgstr ""
-"El resto de la configuración de Samba trata sobre cuestiones que afectan al "
-"contenido de /etc/samba/smb.conf, que es el fichero utilizado para "
-"configurar los programas de Samba (nmbd y smbd). Su smb.conf actual contiene "
-"una línea 'include' o una opción que atraviesa más de una línea, así que "
-"debconf puede dejarlo con un smb.conf descompuesto, requiriendo que lo "
-"arregle a mano."
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"If you don't use debconf to configure smb.conf, you will have to handle any "
-"configuration changes yourself, and will not be able to take advantage of "
-"periodic configuration enhancements. Therefore, use of debconf is "
-"recommended if possible."
-msgstr ""
-"Si no usa debconf para configurar smb.conf, tendrá que cuidar a mano "
-"cualquier cambio a la configuración de Samba y no disfrutará de aumentos "
-"periódicos de configuración. Por eso se recomienda el uso de debconf cuando "
-"sea posible."
-
-#. Description
-#: ../samba-common.templates:52
-msgid "Workgroup/Domain Name?"
-msgstr "Nombre del dominio o del grupo de trabajo"
-
-#. Description
-#: ../samba-common.templates:52
-msgid ""
-"This controls what workgroup your server will appear to be in when queried "
-"by clients. Note that this parameter also controls the Domain name used with "
-"the security=domain setting."
-msgstr ""
-"Es el grupo de trabajo en el que aparecerá su servidor cuando se lo "
-"pregunten los clientes de la red. Este parámetro también controla el nombre "
-"de dominio que se usa con la configuración security=domain."
-
-#. Description
-#: ../samba-common.templates:60
-msgid "Use password encryption?"
-msgstr "¿Utilizar contraseñas cifradas?"
-
-#. Description
-#: ../samba-common.templates:60
-msgid ""
-"Recent Windows clients communicate with SMB servers using encrypted "
-"passwords. If you want to use clear text passwords you will need to change a "
-"parameter in your Windows registry. It is recommended that you use encrypted "
-"passwords. If you do, make sure you have a valid /etc/samba/smbpasswd file "
-"and that you set passwords in there for each user using the smbpasswd "
-"command."
-msgstr ""
-"Los clientes Windows más modernos se comunican con los servidores SMB "
-"utilizando contraseñas cifradas. Si quiere usar contraseñas en texto plano, "
-"tendrá que cambiar un parámetro en el registro de Windows. Es muy "
-"recomendable usar cifrado en las contraseñas. Si elige hacerlo, compruebe "
-"que tiene un fichero /etc/samba/smbpasswd válido y que ha puesto las "
-"contraseñas con el programa smbpasswd."
-
-#. Description
-#: ../samba.templates:4
-msgid "Create samba password database, /var/lib/samba/passdb.tdb?"
-msgstr "¿Crear el base de dados de contraseñas /var/lib/samba/passdb.tdb?"
-
-#. Description
-#: ../samba.templates:4
-msgid ""
-"To be compatible with the defaults in most versions of Windows, Samba must "
-"be configured to use encrypted passwords. This requires user passwords to "
-"be stored in a file separate from /etc/passwd. This file can be created "
-"automatically, but the passwords must be added manually (by you or the user) "
-"by running smbpasswd, and you must arrange to keep it up-to-date in the "
-"future. If you do not create it, you will have to reconfigure samba (and "
-"probably your client machines) to use plaintext passwords. See /usr/share/"
-"doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc package for more "
-"details."
-msgstr ""
-"Para manterner la compatibilidad con el comportamiento por defecto de la "
-"mayoria de los sistemas Windows, hay que configurar Samba para que use "
-"contraseñas cifradas, lo cual requiere la creación de un fichero, distinto "
-"del /etc/passwd, donde se guarden las contraseñas de los usuarios. El "
-"fichero se puede crear automaticamente, aunque es necesario añadir las "
-"contraseñas manualmente (por usted o por el usuario) mediante el programa "
-"'smbpasswd', y debe encargarse de mantener las contraseñas al día. Si no "
-"crea este fichero, es imprescindible configurar Samba (y posiblemente los "
-"sistemas Windows) para que use contraseñas no cifradas. Véa /usr/share/doc/"
-"samba-doc/htmldocs/ENCRYPTION.html del paquete samba-doc para más "
-"información."
-
-#. Description
-#: ../samba.templates:17
-msgid "Samba's log files have moved."
-msgstr "Se han cambiado de lugar los ficheros de registro de Samba."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"Starting with the first packages of Samba 2.2 for Debian the log files for "
-"both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The "
-"names of the files are log.nmbd and log.smbd, for nmbd and smbd respectively."
-msgstr ""
-"A partir de los primeros paquetes Debian de Samba 2.2, los ficheros de "
-"registro de los dos demonios del Samba (nmbd y smbd) se encuentran en /var/"
-"log/samba/. Los nombres de estos ficheros son log.nmbd y log.smbd, para "
-"nmbd y smbd respectivamente."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"The old log files that were in /var/log/ will be moved to the new location "
-"for you."
-msgstr ""
-"Los ficheros de registro antiguos que había en /var/log se moverán "
-"automáticamente a su nueva ubicación."
-
-#. Description
-#: ../samba.templates:28
-msgid "Running nmbd from inetd is no longer supported"
-msgstr "Ya no se puede ejecutar nmbd desde el inetd"
-
-#. Description
-#: ../samba.templates:28
-msgid ""
-"Your system was previously configured to start nmbd and smbd from inetd. As "
-"of version 2.999+3.0.alpha20-4, nmbd will no longer be started from inetd. "
-"If you have modified your /etc/init.d/samba startup script, you may need to "
-"adjust it by hand now so that nmbd will start."
-msgstr ""
-"Su sistema estaba configurado anteriormente para ejectuar nmbd y smbd desde "
-"inetd. A partir de la version 2.999+3.0.alpha20-4, nmbd ya no se ejecuta "
-"desde inetd. Si ha modificado el script de arranque /etc/init.d/samba, "
-"puede que tenga que editarlo ahora para que nmbd se ejecute."
-
-#. Choices
-#: ../samba.templates:36
-msgid "daemons, inetd"
-msgstr "demonios, inetd"
-
-#. Description
-#: ../samba.templates:38
-msgid "How do you want to run Samba?"
-msgstr "¿Cómo quiere que se ejecute Samba?"
-
-#. Description
-#: ../samba.templates:38
-msgid ""
-"The Samba daemon smbd can run as a normal daemon or from inetd. Running as a "
-"daemon is the recommended approach."
-msgstr ""
-"El servicio Samba smbd puede ejecutarse como demonio normal o desde el "
-"inetd. Se recomienda que se ejecute como demonio independiente."
-
-#. Description
-#: ../samba.templates:45
-msgid "Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?"
-msgstr ""
-"¿Convertir el fichero /etc/samba/smbpasswd en /var/lib/samba/passdb.tdb?"
-
-#. Description
-#: ../samba.templates:45
-#, fuzzy
-msgid ""
-"Samba 3.0 introduces a newer, more complete SAM database interface which "
-"supersedes the /etc/samba/smbpasswd file. Would you like your existing "
-"smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you "
-"plan to use another pdb backend (e.g., LDAP) instead, you should answer 'no' "
-"here."
-msgstr ""
-"La versión 3.0 de Samba introduce un nuevo base de dados \"SAM\" más "
-"completo que suplanta al fichero /etc/samba/smbpasswd. ¿Quiere que el "
-"fichero corriente smbpasswd sea convertido en /var/lib/samba/passdb.tdb? Si "
-"pretende usar otro "
-
-#. Description
-#: ../swat.templates:3
-msgid "Your smb.conf will be re-written!"
-msgstr "¡Se sobrescribirá su configuración smb.conf!"
-
-#. Description
-#: ../swat.templates:3
-msgid ""
-"SWAT will rewrite your smb.conf file. It will rearrange the entries and "
-"delete all comments, include= and copy= options. If you have a carefully "
-"crafted smb.conf then back it up or don't use SWAT!"
-msgstr ""
diff --git a/packaging/Debian/debian/po/fr.po b/packaging/Debian/debian/po/fr.po
deleted file mode 100644
index 6be14c19b43..00000000000
--- a/packaging/Debian/debian/po/fr.po
+++ /dev/null
@@ -1,301 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Samba for Debian 3.0.0beta2-1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-30 19:08-0500\n"
-"PO-Revision-Date: 2003-07-02 21:52-0500\n"
-"Last-Translator: Steve Langasek <vorlon@debian.org>\n"
-"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-15\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Description
-#: ../samba-common.templates:3
-msgid "Character Set for Unix filesystem"
-msgstr "Jeu de caractères pour les systèmes de fichiers Unix"
-
-#. Description
-#: ../samba-common.templates:3
-msgid ""
-"You currently have a \"character set\" configured in your smb.conf. In "
-"Samba 3.0, this option is replaced by a new option, \"unix charset\". Please "
-"specify the character set you wish to use for theis new option, which "
-"controls how Samba interprets filenames on the file system."
-msgstr ""
-"Une instruction « character set » (jeu de caractères) est utilisée dans "
-"votre fichier smb.conf. Avec Samba 3.0, cette option est remplacée par une "
-"nouvelle option, « unix charset » (jeu de caractères Unix). Veuillez "
-"indiquer le jeu de caractères que vous voulez utiliser avec cette option, "
-"qui permet d'interpréter les noms de fichiers sur le système."
-
-#. Description
-#: ../samba-common.templates:3
-msgid "If you leave this option blank, your smb.conf will not be changed."
-msgstr ""
-"Le fichier smb.conf ne sera pas modifié si vous laissez cette option sans "
-"réponse."
-
-#. Description
-#: ../samba-common.templates:13
-msgid "Character Set for DOS clients"
-msgstr "Jeu de caractères pour les clients DOS"
-
-#. Description
-#: ../samba-common.templates:13
-msgid ""
-"You currently have a \"client code page\" set in your smb.conf. In Samba "
-"3.0, this option is replaced by the option \"dos charset\". Please specify "
-"the character set you wish to use for this new option. In most cases, the "
-"default chosen for you will be sufficient. Note that this option is not "
-"needed to support Windows clients, it is only for DOS clients. If you leave "
-"this option blank, your smb.conf will not be changed."
-msgstr ""
-"Votre fichier smb.conf contient une option « client code page » (page de "
-"codes du client). Avec Samba 3.0, cette option a été remplacée par l'option "
-"« dos charset » (jeu de caractères DOS). Veuillez indiquer le jeu de "
-"caractères que vous voulez utiliser avec la nouvelle option. En général le "
-"jeu de caractères choisi par défaut est suffisant. Veuillez noter que cette "
-"option ne sert pas pour les clients Windows mais seulement pour les clients "
-"DOS. Le fichier smb.conf ne sera pas modifié si vous laissez cette option "
-"sans réponse. "
-
-#. Description
-#: ../samba-common.templates:24
-msgid "Modify smb.conf to use WINS settings from DHCP?"
-msgstr "Modifier smb.conf pour utiliser les paramètres WINS fournis par DHCP ?"
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"If your computer gets IP address information from a DHCP server on the "
-"network, the DHCP server may also provide information about WINS servers "
-"(\"NetBIOS name servers\") present on the network. This requires a change "
-"to your smb.conf file so that DHCP-provided WINS settings will automatically "
-"be read from /etc/samba/dhcp.conf."
-msgstr ""
-"Si votre ordinateur obtient ses paramètres IP à partir d'un serveur DHCP du "
-"réseau, ce serveur peut aussi fournir des informations sur les serveurs WINS "
-"(serveurs de noms NetBIOS) présents sur le réseau. Une modification du "
-"fichier smb.conf est nécessaire afin que les réglages WINS fournis par le "
-"serveur DHCP soient lus dans /etc/samba/dhcp.conf."
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"You must have the dhcp3-client package installed to take advantage of this "
-"feature."
-msgstr "Pour cela, le paquet dhcp3-client doit être installé."
-
-#. Description
-#: ../samba-common.templates:37
-msgid "Configure smb.conf through debconf?"
-msgstr "Voulez-vous configurer smb.conf avec debconf ?"
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"The rest of the configuration of Samba deals with questions that affect "
-"parameters in /etc/samba/smb.conf, which is the file used to configure the "
-"Samba programs (nmbd and smbd.) Your current smb.conf contains an 'include' "
-"line or an option that spans multiple lines, which could confuse debconf and "
-"require you to edit your smb.conf by hand to get it working again."
-msgstr ""
-"La suite de la configuration de Samba pose des questions sur des paramètres "
-"de /etc/samba/smb.conf, le fichier utilisé pour configurer les programmes de "
-"Samba (nmbd et smbd). Votre fichier actuel contient une ligne « include » ou "
-"une option qui s'étale sur plusieurs lignes : cela peut perturber debconf et "
-"il vaut mieux gérer manuellement le contenu de ce fichier."
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"If you don't use debconf to configure smb.conf, you will have to handle any "
-"configuration changes yourself, and will not be able to take advantage of "
-"periodic configuration enhancements. Therefore, use of debconf is "
-"recommended if possible."
-msgstr ""
-"Si vous n'utilisez pas debconf pour configurer smb.conf, vous devrez vous-"
-"même gérer les modifications de configuration et vous ne pourrez pas "
-"bénéficier des améliorations faites dans la configuration. Si possible, il "
-"est conseillé d'utiliser debconf."
-
-#. Description
-#: ../samba-common.templates:52
-msgid "Workgroup/Domain Name?"
-msgstr "Groupe de travail et nom de domaine ?"
-
-#. Description
-#: ../samba-common.templates:52
-msgid ""
-"This controls what workgroup your server will appear to be in when queried "
-"by clients. Note that this parameter also controls the Domain name used with "
-"the security=domain setting."
-msgstr ""
-"Ce paramètre indique le groupe de travail où les clients trouveront le "
-"serveur. Il indique aussi le nom de domaine utilisé par le paramètre "
-"« security=domain »."
-
-#. Description
-#: ../samba-common.templates:60
-msgid "Use password encryption?"
-msgstr "Voulez-vous chiffrer les mots de passe ?"
-
-#. Description
-#: ../samba-common.templates:60
-msgid ""
-"Recent Windows clients communicate with SMB servers using encrypted "
-"passwords. If you want to use clear text passwords you will need to change a "
-"parameter in your Windows registry. It is recommended that you use encrypted "
-"passwords. If you do, make sure you have a valid /etc/samba/smbpasswd file "
-"and that you set passwords in there for each user using the smbpasswd "
-"command."
-msgstr ""
-"Des clients Windows récents communiquent avec les serveurs SMB en utilisant "
-"des mots de passe chiffrés. Si vous voulez utiliser des mots de passe sans "
-"chiffrement, vous devez modifier un paramètre dans le registre de Windows. "
-"Il est recommandé d'utiliser des mots de passe chiffrés. Si vous le faites, "
-"n'oubliez pas de créer un fichier /etc/samba/smbpasswd et d'y mettre les "
-"mots de passe de tous les utilisateurs qui se servent de la commande "
-"smbpasswd."
-
-#. Description
-#: ../samba.templates:4
-msgid "Create samba password database, /var/lib/samba/passdb.tdb?"
-msgstr "Faut-il créer une base de données /var/lib/samba/passdb.tdb ?"
-
-#. Description
-#: ../samba.templates:4
-msgid ""
-"To be compatible with the defaults in most versions of Windows, Samba must "
-"be configured to use encrypted passwords. This requires user passwords to "
-"be stored in a file separate from /etc/passwd. This file can be created "
-"automatically, but the passwords must be added manually (by you or the user) "
-"by running smbpasswd, and you must arrange to keep it up-to-date in the "
-"future. If you do not create it, you will have to reconfigure samba (and "
-"probably your client machines) to use plaintext passwords. See /usr/share/"
-"doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc package for more "
-"details."
-msgstr ""
-"Pour préserver la compatibilité avec le comportement par défaut de la "
-"plupart des systèmes Windows, Samba doit utiliser les mots de passe "
-"chiffrés. Cela exige la création d'un fichier, distinct du fichier /etc/"
-"passwd, pour mettre les mots de passe des utilisateurs. Ce fichier peut être "
-"créé automatiquement, mais quelqu'un (vous ou l'utilisateur) devra ajouter "
-"les mots de passe manuellement en utilisant la commande smbpasswd ; et vous "
-"devrez maintenir à jour ce fichier. Si vous ne voulez pas créer le fichier "
-"maintenant, Samba (et peut-être les ordinateurs Windows) devra utiliser des "
-"mots de passe non chiffrés. Voyez /usr/share/doc/samba-doc/htmldocs/"
-"ENCRYPTION.html dans le paquet samba-doc pour plus de détails."
-
-#. Description
-#: ../samba.templates:17
-msgid "Samba's log files have moved."
-msgstr "Les fichiers-journaux de Samba ont changé de place."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"Starting with the first packages of Samba 2.2 for Debian the log files for "
-"both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The "
-"names of the files are log.nmbd and log.smbd, for nmbd and smbd respectively."
-msgstr ""
-"À partir des premiers paquets de Samba 2.2 pour Debian, les fichiers-"
-"journaux des démons nmbd et smbd se trouvent dans /var/log/samba/. Les noms "
-"de ces fichiers sont log.nmbd et log.smbd pour, respectivement, nmbd et smbd."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"The old log files that were in /var/log/ will be moved to the new location "
-"for you."
-msgstr ""
-"Les anciens fichiers-journaux dans /var/log/ seront mis au bon endroit."
-
-#. Description
-#: ../samba.templates:28
-msgid "Running nmbd from inetd is no longer supported"
-msgstr "L'utilisation de nmbd à partir d'inetd n'est plus supportée"
-
-#. Description
-#: ../samba.templates:28
-msgid ""
-"Your system was previously configured to start nmbd and smbd from inetd. As "
-"of version 2.999+3.0.alpha20-4, nmbd will no longer be started from inetd. "
-"If you have modified your /etc/init.d/samba startup script, you may need to "
-"adjust it by hand now so that nmbd will start."
-msgstr ""
-"Votre système lançait nmbd et smbd à partir d'inetd. Depuis la version 2.999"
-"+3.0.alpha20-4, on ne peut plus exécuter nmbd à partir d'inetd. Si vous avez "
-"modifié le script de lancement /etc/init.d/samba, vous avez peut-être besoin "
-"de le corriger manuellement pour permettre le lancement de nmbd. "
-
-#. Choices
-#: ../samba.templates:36
-msgid "daemons, inetd"
-msgstr "démons, inetd"
-
-#. Description
-#: ../samba.templates:38
-msgid "How do you want to run Samba?"
-msgstr "Comment voulez-vous lancer Samba ?"
-
-#. Description
-#: ../samba.templates:38
-msgid ""
-"The Samba daemon smbd can run as a normal daemon or from inetd. Running as a "
-"daemon is the recommended approach."
-msgstr ""
-"Le service de Samba smbd peut s'exécuter en tant que démon classique ou bien "
-"être lancé par inetd. L'approche recommandée est qu'il s'exécute en tant que "
-"démon."
-
-#. Description
-#: ../samba.templates:45
-msgid "Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?"
-msgstr "Faut-il convertir /etc/samba/smbpasswd en /var/lib/samba/passdb.tdb ?"
-
-#. Description
-#: ../samba.templates:45
-msgid ""
-"Samba 3.0 introduces a newer, more complete SAM database interface which "
-"supersedes the /etc/samba/smbpasswd file. Would you like your existing "
-"smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you "
-"plan to use another pdb backend (e.g., LDAP) instead, you should answer 'no' "
-"here."
-msgstr ""
-"Avec Samba 3.0, une nouvelle interface pour les bases de données SAM, plus "
-"complète, vient remplacer le fichier /etc/samba/smbpasswd. Voulez-vous que "
-"votre fichier existant soit remplacé par /var/lib/samba/passdb.tdb ? Si vous "
-"envisagez d'utiliser une autre interface d'authentification (p.ex. LDAP), "
-"refusez la proposition maintenant."
-
-#. Description
-#: ../swat.templates:3
-msgid "Your smb.conf will be re-written!"
-msgstr "Ré-écriture de votre fichier smb.conf !"
-
-#. Description
-#: ../swat.templates:3
-msgid ""
-"SWAT will rewrite your smb.conf file. It will rearrange the entries and "
-"delete all comments, include= and copy= options. If you have a carefully "
-"crafted smb.conf then back it up or don't use SWAT!"
-msgstr ""
-"SWAT va modifier votre fichier smb.conf. Les entrées seront réorganisées et "
-"les commentaires détruits ainsi que les entrées « include = » et « copy = ». "
-"Si votre smb.conf était soigneusement construit, sauvegardez-le ou "
-"n'utilisez pas SWAT !"
diff --git a/packaging/Debian/debian/po/nl.po b/packaging/Debian/debian/po/nl.po
deleted file mode 100644
index 61e8742dbb5..00000000000
--- a/packaging/Debian/debian/po/nl.po
+++ /dev/null
@@ -1,302 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: samba\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-30 19:08-0500\n"
-"PO-Revision-Date: 2003-08-30 02:03+0100\n"
-"Last-Translator: Bart Cornelis <cobaco@linux.be>\n"
-"Language-Team: dutch <debian-l10n-dutch@lists.debian.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Description
-#: ../samba-common.templates:3
-msgid "Character Set for Unix filesystem"
-msgstr "Karakterset voor Unix bestandsysteem"
-
-#. Description
-#: ../samba-common.templates:3
-msgid ""
-"You currently have a \"character set\" configured in your smb.conf. In "
-"Samba 3.0, this option is replaced by a new option, \"unix charset\". Please "
-"specify the character set you wish to use for theis new option, which "
-"controls how Samba interprets filenames on the file system."
-msgstr ""
-"U heeft momenteel een \"karakterset\" ingesteld in uw smb.conf. In Samba 3.0 "
-"werd deze optie vervangen door een nieuwe \"unix karakterset\" optie. "
-"Gelieve de karakterset die u voor deze nieuwe optie wil gebruiken aan te "
-"geven, deze bepaald hoe Samba de bestandsnamen in het bestandsysteem "
-"interpreteerd."
-
-#. Description
-#: ../samba-common.templates:3
-msgid "If you leave this option blank, your smb.conf will not be changed."
-msgstr ""
-"Uw smb.conf bestand wordt niet aangepast indien u deze optie leeg laat."
-
-#. Description
-#: ../samba-common.templates:13
-msgid "Character Set for DOS clients"
-msgstr "Karakterset voor DOS-clients"
-
-#. Description
-#: ../samba-common.templates:13
-msgid ""
-"You currently have a \"client code page\" set in your smb.conf. In Samba "
-"3.0, this option is replaced by the option \"dos charset\". Please specify "
-"the character set you wish to use for this new option. In most cases, the "
-"default chosen for you will be sufficient. Note that this option is not "
-"needed to support Windows clients, it is only for DOS clients. If you leave "
-"this option blank, your smb.conf will not be changed."
-msgstr ""
-"U heeft momenteel een \"client code pagina\" ingesteld in uw smb.conf. In "
-"Samba 3.0 werd deze optie vervangen door de optie \"dos karakterset\". "
-"Gelieve de karakterset die u voor deze nieuwe optie wilt gebruiken aan te "
-"geven. In de meeste gevallen zal het standaard ingevulde antwoord voldoen. "
-"Merk op dat deze optie niet nodig is voor ondersteuning van Windows-clients, "
-"enkel voor DOS-clients. Uw smb.conf wordt niet veranderd wanneer u deze "
-"optie blank laat."
-
-#. Description
-#: ../samba-common.templates:24
-msgid "Modify smb.conf to use WINS settings from DHCP?"
-msgstr "smb.conf aanpassen om de WINS instellingen van DHCP te gebruiken?"
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"If your computer gets IP address information from a DHCP server on the "
-"network, the DHCP server may also provide information about WINS servers "
-"(\"NetBIOS name servers\") present on the network. This requires a change "
-"to your smb.conf file so that DHCP-provided WINS settings will automatically "
-"be read from /etc/samba/dhcp.conf."
-msgstr ""
-"Indien uw computer zijn ip-addres informatie van een DHCP-server op het "
-"netwerk haalt, voorziet deze mogelijks ook informatie betreffende de op het "
-"netwerk aanwezige WINS-servers (\"NetBIOS naam servers\").\" Dit vereist een "
-"verandering aan uw smb.conf bestand, opdat de door DHCP doorgegeven WINS "
-"instellingen automatisch gelezen worden van /etc/samba/dhcp.conf."
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"You must have the dhcp3-client package installed to take advantage of this "
-"feature."
-msgstr ""
-"U dient het dhcp3-client-pakket geïnstalleert te hebben om van deze optie "
-"gebruik te maken."
-
-#. Description
-#: ../samba-common.templates:37
-msgid "Configure smb.conf through debconf?"
-msgstr "Configuratie in smb.conf met debconf beheren?"
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"The rest of the configuration of Samba deals with questions that affect "
-"parameters in /etc/samba/smb.conf, which is the file used to configure the "
-"Samba programs (nmbd and smbd.) Your current smb.conf contains an 'include' "
-"line or an option that spans multiple lines, which could confuse debconf and "
-"require you to edit your smb.conf by hand to get it working again."
-msgstr ""
-"De resterende Samba configuratie beslaat parameters in /etc/samba/smb.conf, "
-"het configuratiebestand dat gebruikt wordt voor de Samba programmas (nmbd en "
-"smbd). Uw huidige smb.conf bevat een 'include' regel of een optie die "
-"meerdere regels beslaat, dit kan debconf mogelijks in verwarring brenngen. "
-"Indien debconf in verwarring raakt dient u uw smb.conf handmatig aan te "
-"passen om samba terug werkend te krijgen."
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"If you don't use debconf to configure smb.conf, you will have to handle any "
-"configuration changes yourself, and will not be able to take advantage of "
-"periodic configuration enhancements. Therefore, use of debconf is "
-"recommended if possible."
-msgstr ""
-"Indien u geen gebruik maakt van debconf voor het beheer van smb.conf dient u "
-"alle configuratie instellingen zelf te doen, en zult u geen voordeel halen "
-"uit de periodieke configuratie verbeteringen. Het gebruik van debconf wordt "
-"dan ook aangeraden. "
-
-#. Description
-#: ../samba-common.templates:52
-msgid "Workgroup/Domain Name?"
-msgstr "Werkgroep/Domeinnaam?"
-
-#. Description
-#: ../samba-common.templates:52
-msgid ""
-"This controls what workgroup your server will appear to be in when queried "
-"by clients. Note that this parameter also controls the Domain name used with "
-"the security=domain setting."
-msgstr ""
-"Dit bepaald van welke werkgroep uw server deel zal lijken uit te maken bij "
-"het beantwoorden van vragen door clients. Merk op dat deze parameter ook de "
-"domeinnaam die gebruikt wordt voor de security=domein instelling bepaald."
-
-#. Description
-#: ../samba-common.templates:60
-msgid "Use password encryption?"
-msgstr "Wachtwoord versleuteling gebruiken?"
-
-#. Description
-#: ../samba-common.templates:60
-msgid ""
-"Recent Windows clients communicate with SMB servers using encrypted "
-"passwords. If you want to use clear text passwords you will need to change a "
-"parameter in your Windows registry. It is recommended that you use encrypted "
-"passwords. If you do, make sure you have a valid /etc/samba/smbpasswd file "
-"and that you set passwords in there for each user using the smbpasswd "
-"command."
-msgstr ""
-"Recente Windows clients maken gebruik van versleutelde wachtwoorden voor de "
-"communicatie met SMB-servers. Indien u onversleutelde tekst wachtwoorden "
-"wilt gebruiken dient u een parameter te veranderen in de Windows registry. "
-"Het gebruik van versleutelde wachtwoorden wordt aangeraden. Indien u dit "
-"doet zorg er dan voor dat u een geldig /etc/samba/smbpasswd bestand heeft en "
-"dat u de wachtwoorden daar voor elke gebruiker met behulp van smbpasswd "
-"insteld. "
-
-#. Description
-#: ../samba.templates:4
-msgid "Create samba password database, /var/lib/samba/passdb.tdb?"
-msgstr "Samba wachtwoord database, /var/lib/samba/passdb.tdb, aanmaken?"
-
-#. Description
-#: ../samba.templates:4
-msgid ""
-"To be compatible with the defaults in most versions of Windows, Samba must "
-"be configured to use encrypted passwords. This requires user passwords to "
-"be stored in a file separate from /etc/passwd. This file can be created "
-"automatically, but the passwords must be added manually (by you or the user) "
-"by running smbpasswd, and you must arrange to keep it up-to-date in the "
-"future. If you do not create it, you will have to reconfigure samba (and "
-"probably your client machines) to use plaintext passwords. See /usr/share/"
-"doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc package for more "
-"details."
-msgstr ""
-"Om compatibel te zijn met de standaard instellingen van de meeste "
-"Windowsversies dient Samba gebruik te maken van versleutelde wachtwoorden. "
-"Dit vereist dat de gebruikerswachtwoorden opgeslagen worden in een bestand "
-"dat verschilt van /etc/passwd. Dit bestand kan automatisch aangemaakt "
-"worden, maar de wachtwoorden dienen handmatig (door de gebuiker) toegevoegt "
-"te worden met het smbpasswd commando. U dient dit bestand in de toekomst ook "
-"aktueel te houden. Indien u dit bestand niet aanmaakt zult u samba (en naar "
-"alle waarschijnlijkheid de client machines) moeten herconfigureren zodat "
-"deze onversleutelde wachtwoorden gebruiken. Zie /usr/share/doc/samba-doc/"
-"htmldocs/ENCRYPTION.html uit het samba-doc pakket voor meer details."
-
-#. Description
-#: ../samba.templates:17
-msgid "Samba's log files have moved."
-msgstr "Samba's log bestanden zijn verhuisd."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"Starting with the first packages of Samba 2.2 for Debian the log files for "
-"both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The "
-"names of the files are log.nmbd and log.smbd, for nmbd and smbd respectively."
-msgstr ""
-"Vanaf de eerste Debian pakketten vaan Samba versie 2.2 zijn de log bestanden "
-"van beide Samba daemons (nmbd en smbd) opgeslagen in /var/log/samba/. De log "
-"bestanden voor nmbd en smbd zijn, respectievelijk, log.nmbd en log.smbd."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"The old log files that were in /var/log/ will be moved to the new location "
-"for you."
-msgstr ""
-"De oude logbestanden in /var/log worden voor u naar de nieuwe locatie "
-"verplaatst."
-
-#. Description
-#: ../samba.templates:28
-msgid "Running nmbd from inetd is no longer supported"
-msgstr "nmbd vanuit inetd draaien wordt niet langer ondersteund"
-
-#. Description
-#: ../samba.templates:28
-msgid ""
-"Your system was previously configured to start nmbd and smbd from inetd. As "
-"of version 2.999+3.0.alpha20-4, nmbd will no longer be started from inetd. "
-"If you have modified your /etc/init.d/samba startup script, you may need to "
-"adjust it by hand now so that nmbd will start."
-msgstr ""
-"Uw systeem was geconfigureerd om nmbd en smbd vanuit inetd te starten. Vanaf "
-"versie 2.999+3.0.alpha20-4 kan nmbd niet langer door inetd gestart worden. "
-"Indien u uw /etc/init.d/samba startup-script aangepast had, dient u dit "
-"mogelijks aan te passen opdat nmbd zou starten."
-
-#. Choices
-#: ../samba.templates:36
-msgid "daemons, inetd"
-msgstr "daemons, inetd"
-
-#. Description
-#: ../samba.templates:38
-msgid "How do you want to run Samba?"
-msgstr "Hoe wilt u Samba draaien?"
-
-#. Description
-#: ../samba.templates:38
-msgid ""
-"The Samba daemon smbd can run as a normal daemon or from inetd. Running as a "
-"daemon is the recommended approach."
-msgstr ""
-"De Samba daemon smbd kan als een normale daemon of via inetd draaien. Als "
-"een daemon is de aangeraden aanpak."
-
-#. Description
-#: ../samba.templates:45
-msgid "Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?"
-msgstr "/etc/samba/smbpasswd verplaatsen naar /var/lib/samba/passdb.tdb?"
-
-#. Description
-#: ../samba.templates:45
-msgid ""
-"Samba 3.0 introduces a newer, more complete SAM database interface which "
-"supersedes the /etc/samba/smbpasswd file. Would you like your existing "
-"smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you "
-"plan to use another pdb backend (e.g., LDAP) instead, you should answer 'no' "
-"here."
-msgstr ""
-"Samba 3.0 introduceert een nieuwe, meer complete SAM databaseinterface die "
-"het /etc/samba/smbpasswd bestand overstijgt. \"Wilt u dat ik uw bestaand "
-"smbpasswd bestand voor u naar /var/lib/samba/passdb.tdb migreer? Indien u "
-"van plan bent om, in plaats hiervan, een ander pdb-backend (e.g. LDAP) te "
-"gebruiken dient u hier 'nee' te antwoorden."
-
-#. Description
-#: ../swat.templates:3
-msgid "Your smb.conf will be re-written!"
-msgstr "Uw smb.conf wordt herschreven!"
-
-#. Description
-#: ../swat.templates:3
-msgid ""
-"SWAT will rewrite your smb.conf file. It will rearrange the entries and "
-"delete all comments, include= and copy= options. If you have a carefully "
-"crafted smb.conf then back it up or don't use SWAT!"
-msgstr ""
-"SWAT zal uw smb.conf bestand herschrijven. Het zal de ingangen anders "
-"schikken en alle comments, include= en copy= opties verwijderen. Als u een, "
-"met veel zorg, handmatig opgebouwd smb.conf bestand heeft, maak dan een "
-"reservekopie of zie van het gebruik van SWAT af! "
diff --git a/packaging/Debian/debian/po/pt_BR.po b/packaging/Debian/debian/po/pt_BR.po
deleted file mode 100644
index 2af42a562b9..00000000000
--- a/packaging/Debian/debian/po/pt_BR.po
+++ /dev/null
@@ -1,308 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: samba_3.0.0beta2-1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-30 19:08-0500\n"
-"PO-Revision-Date: 2003-07-02 21:56-0500\n"
-"Last-Translator: Steve Langasek <vorlon@debian.org>\n"
-"Language-Team: Debian-BR Project <debian-l10n-portuguese@lists.debian.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Description
-#: ../samba-common.templates:3
-msgid "Character Set for Unix filesystem"
-msgstr "Conjunto de caracteres para sistema de arquivos Unix"
-
-#. Description
-#: ../samba-common.templates:3
-#, fuzzy
-msgid ""
-"You currently have a \"character set\" configured in your smb.conf. In "
-"Samba 3.0, this option is replaced by a new option, \"unix charset\". Please "
-"specify the character set you wish to use for theis new option, which "
-"controls how Samba interprets filenames on the file system."
-msgstr ""
-"Atualmente existe um \"conjunto de caracteres\" (\"character set\") "
-"configurado em seu arquivo smb.conf. No Samba 3.0, esta opção foi "
-"substituída por uma nova opção, \"unix charset\". Por favor especifique o "
-"conjunto de caracteres a ser usado para essa nova opção, a qual controla "
-"como o Samba interpreta nomes de arquivos no sistema de arquivos."
-
-#. Description
-#: ../samba-common.templates:3
-msgid "If you leave this option blank, your smb.conf will not be changed."
-msgstr ""
-"Caso você deixe esta opção em branco, seu arquivo smb.conf não será "
-"modificado."
-
-#. Description
-#: ../samba-common.templates:13
-msgid "Character Set for DOS clients"
-msgstr "Conjunto de caracteres para clientes DOS"
-
-#. Description
-#: ../samba-common.templates:13
-msgid ""
-"You currently have a \"client code page\" set in your smb.conf. In Samba "
-"3.0, this option is replaced by the option \"dos charset\". Please specify "
-"the character set you wish to use for this new option. In most cases, the "
-"default chosen for you will be sufficient. Note that this option is not "
-"needed to support Windows clients, it is only for DOS clients. If you leave "
-"this option blank, your smb.conf will not be changed."
-msgstr ""
-"Atualmente existe um \"código de página do cliente\" (\"client code page\") "
-"definido em seu arquivo smb.conf. No Samba 3.0, essa opção foi substituída "
-"pela opção \"dos charset\". Por favor, especifique o conjunto de caracteres "
-"que você deseja usar para essa nova opção. Note que essa opção não é "
-"necessária para suportar clientes Windows mas sim válida somente para "
-"clientes DOS. Caso você deixe essa opção em branco, seu arquivo smb.conf não "
-"será modificado."
-
-#. Description
-#: ../samba-common.templates:24
-msgid "Modify smb.conf to use WINS settings from DHCP?"
-msgstr "Modificar smb.conf para usar configurações WINS fornecidas via DHCP ?"
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"If your computer gets IP address information from a DHCP server on the "
-"network, the DHCP server may also provide information about WINS servers "
-"(\"NetBIOS name servers\") present on the network. This requires a change "
-"to your smb.conf file so that DHCP-provided WINS settings will automatically "
-"be read from /etc/samba/dhcp.conf."
-msgstr ""
-"Caso seu computador obtenha as informações de endereçamento IP de um "
-"servidor DHCP na rede, o servidor DHCP pode também fornecer informações "
-"sobre servidor WINS (\"Servidor de Nomes NetBIOS\") presentes na rede. Para "
-"o Samba ler as configurações WINS fornecidas pelo servidor DHCP "
-"automaticamente do arquivo /etc/samba/dhcp.conf, é preciso modificar seu "
-"arquivo smb.conf."
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"You must have the dhcp3-client package installed to take advantage of this "
-"feature."
-msgstr ""
-"Você deve possuir o pacote dhcp3-client instalado para poder usar este "
-"recurso."
-
-#. Description
-#: ../samba-common.templates:37
-msgid "Configure smb.conf through debconf?"
-msgstr "Configurar smb.conf através do debconf ?"
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"The rest of the configuration of Samba deals with questions that affect "
-"parameters in /etc/samba/smb.conf, which is the file used to configure the "
-"Samba programs (nmbd and smbd.) Your current smb.conf contains an 'include' "
-"line or an option that spans multiple lines, which could confuse debconf and "
-"require you to edit your smb.conf by hand to get it working again."
-msgstr ""
-"O restante da configuração do Samba lida com questões que afetam parâmetros "
-"no arquivo /etc/samba/smb.conf, que é o arquivo usado para configurar os "
-"programas Samba (nmbd e smbd). Seu arquivo smb.conf atual contém uma linha "
-"'include' ou uma opção que ocupa diversas linhas, o que pode confundir o "
-"debconf e requerer que você edite seu arquivo smb.conf manualmente para tê-"
-"lo funcional novamente."
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"If you don't use debconf to configure smb.conf, you will have to handle any "
-"configuration changes yourself, and will not be able to take advantage of "
-"periodic configuration enhancements. Therefore, use of debconf is "
-"recommended if possible."
-msgstr ""
-"Caso você opte por não usar o debconf para configurar o smb.conf, será "
-"necessário que você lide com quaisquer mudanças de configurações manualmente "
-"e você não poderá aproveitar os melhoramentos periódicos de configuração. "
-"Por esse motivo, é recomendado usar o debconf, caso seja possível."
-
-#. Description
-#: ../samba-common.templates:52
-msgid "Workgroup/Domain Name?"
-msgstr "Nome de Domínio/Grupo de Trabalho ?"
-
-#. Description
-#: ../samba-common.templates:52
-msgid ""
-"This controls what workgroup your server will appear to be in when queried "
-"by clients. Note that this parameter also controls the Domain name used with "
-"the security=domain setting."
-msgstr ""
-"Este parâmetro controla em qual grupo de trabalho (workgroup) seu servidor "
-"parecerá estar quando o mesmo for pesquisado por clientes. Note que este "
-"parâmetro também controla o nome de Domínio usado com a configuração "
-"security=domain."
-
-#. Description
-#: ../samba-common.templates:60
-msgid "Use password encryption?"
-msgstr "Usar encriptação de senhas ?"
-
-#. Description
-#: ../samba-common.templates:60
-msgid ""
-"Recent Windows clients communicate with SMB servers using encrypted "
-"passwords. If you want to use clear text passwords you will need to change a "
-"parameter in your Windows registry. It is recommended that you use encrypted "
-"passwords. If you do, make sure you have a valid /etc/samba/smbpasswd file "
-"and that you set passwords in there for each user using the smbpasswd "
-"command."
-msgstr ""
-"Clientes Windows atuais comunicam-se com servidores SMB usando senhas "
-"encriptadas. Caso você queira usar senhas em texto puro você precisará "
-"modificar um parâmetro no registro de seu Windows. É recomendado que você "
-"use senhas encriptadas. Se for usá-las, certifique-se de possuir um arquivo /"
-"etc/samba/smbpasswd válido e que você tenha definido senhas no mesmo para "
-"cada usuário, utilizando o comando smbpasswd."
-
-#. Description
-#: ../samba.templates:4
-msgid "Create samba password database, /var/lib/samba/passdb.tdb?"
-msgstr "Gerar a base de dados para senhas /var/lib/samba/passdb.tdb ?"
-
-#. Description
-#: ../samba.templates:4
-msgid ""
-"To be compatible with the defaults in most versions of Windows, Samba must "
-"be configured to use encrypted passwords. This requires user passwords to "
-"be stored in a file separate from /etc/passwd. This file can be created "
-"automatically, but the passwords must be added manually (by you or the user) "
-"by running smbpasswd, and you must arrange to keep it up-to-date in the "
-"future. If you do not create it, you will have to reconfigure samba (and "
-"probably your client machines) to use plaintext passwords. See /usr/share/"
-"doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc package for more "
-"details."
-msgstr ""
-"Para compatibilidade com os padrões adotados em todas as versões atuais do "
-"Windows o Samba deve ser configurado para usar senhas encriptadas. Isso "
-"requer que as senhas dos usuários sejam armazenadas em um arquivo diferente "
-"do /etc/passwd. Esse arquivo pode ser criado automaticamente, mas as senhas "
-"devem ser definidas manualmente (por você ou pelo usuário) executando o "
-"utilitário smbpasswd. Você deve certificar-se de manter esse arquivo "
-"atualizado futuramente. Caso você não crie esse arquivo, você terá que "
-"reconfigurar o Samba (e provavelmente suas máquinas clientes) para "
-"utilização de senhas em texto puro. Consulte a documentação do pacote samba-"
-"doc em /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html para maiores "
-"detalhes."
-
-#. Description
-#: ../samba.templates:17
-msgid "Samba's log files have moved."
-msgstr "Arquivos de log do Samba foram movidos."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"Starting with the first packages of Samba 2.2 for Debian the log files for "
-"both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The "
-"names of the files are log.nmbd and log.smbd, for nmbd and smbd respectively."
-msgstr ""
-"Desde os primeiros pacotes Debian do Samba 2.2 os arquivos de log para ambos "
-"os daemons Samba (nmbd e smbd) são armazenados no diretório /var/log/samba/. "
-"Os nomes desses arquivos são log.nmbd e log.smbd, para o nmbd e para o smbd, "
-"respectivamente."
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"The old log files that were in /var/log/ will be moved to the new location "
-"for you."
-msgstr ""
-"Os antigos arquivos de log que estavam em /var/log/ serão movidos para a "
-"nova localização automaticamente para você."
-
-#. Description
-#: ../samba.templates:28
-msgid "Running nmbd from inetd is no longer supported"
-msgstr "A execução do nmbd a partir do inetd não é mais suportada"
-
-#. Description
-#: ../samba.templates:28
-msgid ""
-"Your system was previously configured to start nmbd and smbd from inetd. As "
-"of version 2.999+3.0.alpha20-4, nmbd will no longer be started from inetd. "
-"If you have modified your /etc/init.d/samba startup script, you may need to "
-"adjust it by hand now so that nmbd will start."
-msgstr ""
-"Seu sistema foi previamente configurado para iniciar os daemons nmbd e smbd "
-"a partir do inetd. Desde a versão 2.999+3.0.alpha20-4, o nmbd não mais será "
-"iniciado a partir do inetd. Caso você tenha modificado seu script de "
-"inicialização /etc/init.d/samba, você pode precisar ajustá-lo manualmente "
-"agora para que o nmbd seja iniciado."
-
-#. Choices
-#: ../samba.templates:36
-msgid "daemons, inetd"
-msgstr "daemons, inetd"
-
-#. Description
-#: ../samba.templates:38
-msgid "How do you want to run Samba?"
-msgstr "Como você deseja que o Samba seja executado ?"
-
-#. Description
-#: ../samba.templates:38
-msgid ""
-"The Samba daemon smbd can run as a normal daemon or from inetd. Running as a "
-"daemon is the recommended approach."
-msgstr ""
-"O serviço Samba smbd pode ser executado como daemon normal ou a partir do "
-"inetd. Executá-lo como daemon é o método recomendado."
-
-#. Description
-#: ../samba.templates:45
-msgid "Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?"
-msgstr "Mover /etc/samba/smbpasswd para /var/lib/samba/passdb.tdb ?"
-
-#. Description
-#: ../samba.templates:45
-msgid ""
-"Samba 3.0 introduces a newer, more complete SAM database interface which "
-"supersedes the /etc/samba/smbpasswd file. Would you like your existing "
-"smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you "
-"plan to use another pdb backend (e.g., LDAP) instead, you should answer 'no' "
-"here."
-msgstr ""
-"O Samba 3.0 introduz uma nova e mais complete interface de base de dados SAM "
-"que substitui o arquivo /etc/samba/smbpasswd. Você gostaria que o arquivo "
-"smbpasswd existente fosse migrado para /var/lib/samba/passdb.tdb para você ? "
-"Caso você planeje usar um outro backend (como LDAP, por exemplo) você deverá "
-"escolher 'não' aqui."
-
-#. Description
-#: ../swat.templates:3
-msgid "Your smb.conf will be re-written!"
-msgstr "Seu arquivo smb.conf será reescrito !"
-
-#. Description
-#: ../swat.templates:3
-msgid ""
-"SWAT will rewrite your smb.conf file. It will rearrange the entries and "
-"delete all comments, include= and copy= options. If you have a carefully "
-"crafted smb.conf then back it up or don't use SWAT!"
-msgstr ""
-"O SWAT irá reescrever seu arquivo smb.conf. Ele irá rearrumar as entradas e "
-"apagar todos os comentários, opções include= e copy=. Caso você possua um "
-"arquivo smb.conf cuidadosamente criado e comentado, faça uma cópia de "
-"segurança (backup) do mesmo ou não use o SWAT !"
diff --git a/packaging/Debian/debian/po/templates.pot b/packaging/Debian/debian/po/templates.pot
deleted file mode 100644
index 465f4719b0d..00000000000
--- a/packaging/Debian/debian/po/templates.pot
+++ /dev/null
@@ -1,233 +0,0 @@
-#
-# Translators, if you are not familiar with the PO format, gettext
-# documentation is worth reading, especially sections dedicated to
-# this format, e.g. by running:
-# info -n '(gettext)PO Files'
-# info -n '(gettext)Header Entry'
-#
-# Some information specific to po-debconf are available at
-# /usr/share/doc/po-debconf/README-trans
-# or http://www.debian.org/intl/l10n/po-debconf/README-trans
-#
-# Developers do not need to manually edit POT or PO files.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2003-08-30 19:08-0500\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. Description
-#: ../samba-common.templates:3
-msgid "Character Set for Unix filesystem"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:3
-msgid ""
-"You currently have a \"character set\" configured in your smb.conf. In "
-"Samba 3.0, this option is replaced by a new option, \"unix charset\". Please "
-"specify the character set you wish to use for theis new option, which "
-"controls how Samba interprets filenames on the file system."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:3
-msgid "If you leave this option blank, your smb.conf will not be changed."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:13
-msgid "Character Set for DOS clients"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:13
-msgid ""
-"You currently have a \"client code page\" set in your smb.conf. In Samba "
-"3.0, this option is replaced by the option \"dos charset\". Please specify "
-"the character set you wish to use for this new option. In most cases, the "
-"default chosen for you will be sufficient. Note that this option is not "
-"needed to support Windows clients, it is only for DOS clients. If you leave "
-"this option blank, your smb.conf will not be changed."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:24
-msgid "Modify smb.conf to use WINS settings from DHCP?"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"If your computer gets IP address information from a DHCP server on the "
-"network, the DHCP server may also provide information about WINS servers "
-"(\"NetBIOS name servers\") present on the network. This requires a change "
-"to your smb.conf file so that DHCP-provided WINS settings will automatically "
-"be read from /etc/samba/dhcp.conf."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:24
-msgid ""
-"You must have the dhcp3-client package installed to take advantage of this "
-"feature."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:37
-msgid "Configure smb.conf through debconf?"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"The rest of the configuration of Samba deals with questions that affect "
-"parameters in /etc/samba/smb.conf, which is the file used to configure the "
-"Samba programs (nmbd and smbd.) Your current smb.conf contains an 'include' "
-"line or an option that spans multiple lines, which could confuse debconf and "
-"require you to edit your smb.conf by hand to get it working again."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:37
-msgid ""
-"If you don't use debconf to configure smb.conf, you will have to handle any "
-"configuration changes yourself, and will not be able to take advantage of "
-"periodic configuration enhancements. Therefore, use of debconf is "
-"recommended if possible."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:52
-msgid "Workgroup/Domain Name?"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:52
-msgid ""
-"This controls what workgroup your server will appear to be in when queried "
-"by clients. Note that this parameter also controls the Domain name used with "
-"the security=domain setting."
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:60
-msgid "Use password encryption?"
-msgstr ""
-
-#. Description
-#: ../samba-common.templates:60
-msgid ""
-"Recent Windows clients communicate with SMB servers using encrypted "
-"passwords. If you want to use clear text passwords you will need to change a "
-"parameter in your Windows registry. It is recommended that you use encrypted "
-"passwords. If you do, make sure you have a valid /etc/samba/smbpasswd file "
-"and that you set passwords in there for each user using the smbpasswd "
-"command."
-msgstr ""
-
-#. Description
-#: ../samba.templates:4
-msgid "Create samba password database, /var/lib/samba/passdb.tdb?"
-msgstr ""
-
-#. Description
-#: ../samba.templates:4
-msgid ""
-"To be compatible with the defaults in most versions of Windows, Samba must "
-"be configured to use encrypted passwords. This requires user passwords to "
-"be stored in a file separate from /etc/passwd. This file can be created "
-"automatically, but the passwords must be added manually (by you or the user) "
-"by running smbpasswd, and you must arrange to keep it up-to-date in the "
-"future. If you do not create it, you will have to reconfigure samba (and "
-"probably your client machines) to use plaintext passwords. See /usr/share/"
-"doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc package for more "
-"details."
-msgstr ""
-
-#. Description
-#: ../samba.templates:17
-msgid "Samba's log files have moved."
-msgstr ""
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"Starting with the first packages of Samba 2.2 for Debian the log files for "
-"both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The "
-"names of the files are log.nmbd and log.smbd, for nmbd and smbd respectively."
-msgstr ""
-
-#. Description
-#: ../samba.templates:17
-msgid ""
-"The old log files that were in /var/log/ will be moved to the new location "
-"for you."
-msgstr ""
-
-#. Description
-#: ../samba.templates:28
-msgid "Running nmbd from inetd is no longer supported"
-msgstr ""
-
-#. Description
-#: ../samba.templates:28
-msgid ""
-"Your system was previously configured to start nmbd and smbd from inetd. As "
-"of version 2.999+3.0.alpha20-4, nmbd will no longer be started from inetd. "
-"If you have modified your /etc/init.d/samba startup script, you may need to "
-"adjust it by hand now so that nmbd will start."
-msgstr ""
-
-#. Choices
-#: ../samba.templates:36
-msgid "daemons, inetd"
-msgstr ""
-
-#. Description
-#: ../samba.templates:38
-msgid "How do you want to run Samba?"
-msgstr ""
-
-#. Description
-#: ../samba.templates:38
-msgid ""
-"The Samba daemon smbd can run as a normal daemon or from inetd. Running as a "
-"daemon is the recommended approach."
-msgstr ""
-
-#. Description
-#: ../samba.templates:45
-msgid "Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?"
-msgstr ""
-
-#. Description
-#: ../samba.templates:45
-msgid ""
-"Samba 3.0 introduces a newer, more complete SAM database interface which "
-"supersedes the /etc/samba/smbpasswd file. Would you like your existing "
-"smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you "
-"plan to use another pdb backend (e.g., LDAP) instead, you should answer 'no' "
-"here."
-msgstr ""
-
-#. Description
-#: ../swat.templates:3
-msgid "Your smb.conf will be re-written!"
-msgstr ""
-
-#. Description
-#: ../swat.templates:3
-msgid ""
-"SWAT will rewrite your smb.conf file. It will rearrange the entries and "
-"delete all comments, include= and copy= options. If you have a carefully "
-"crafted smb.conf then back it up or don't use SWAT!"
-msgstr ""
diff --git a/packaging/Debian/debian/python2.3-samba.files b/packaging/Debian/debian/python2.3-samba.files
deleted file mode 100644
index 82759d81b89..00000000000
--- a/packaging/Debian/debian/python2.3-samba.files
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/python2.3/site-packages/
diff --git a/packaging/Debian/debian/rules b/packaging/Debian/debian/rules
index 73e5d16bc19..c5f4a22b198 100755
--- a/packaging/Debian/debian/rules
+++ b/packaging/Debian/debian/rules
@@ -10,7 +10,7 @@
#export DH_VERBOSE=1
# This is the debhelper compatability version to use.
-export DH_COMPAT=4
+export DH_COMPAT=2
# This has to be exported to make some magic below work.
export DH_OPTIONS
@@ -23,37 +23,20 @@ DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
export DEB_HOST_GNU_TYPE
export DEB_BUILD_GNU_TYPE
-
-# Support the DEB_BUILD_OPTIONS variable
-CFLAGS = -gstabs -Wall
-INSTALL = install
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
-else
- CFLAGS += -O2
-endif
-
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
- INSTALL += -s
-endif
-
-
-DESTDIR=`pwd`/debian/tmp
+DESTDIR=`pwd`/debian/samba
SWATDIR=`pwd`/debian/swat
+SAMBABOOK=`pwd`/debian/swat
IVARS = BASEDIR=$(DESTDIR)/usr \
- prefix=$(DESTDIR)/usr \
BINDIR=$(DESTDIR)/usr/bin \
SBINDIR=$(DESTDIR)/usr/sbin \
MANDIR=$(DESTDIR)/usr/share/man \
- LIBDIR=$(DESTDIR)/usr/lib/samba \
+ LIBDIR=$(DESTDIR)/etc/samba \
VARDIR=$(DESTDIR)/var \
INCLUDEDIR=$(DESTDIR)/usr/include \
SWATDIR=$(SWATDIR)/usr/share/samba/swat \
- CODEPAGEDIR=$(DESTDIR)/usr/share/samba/ \
- PRIVATEDIR=$(DESTDIR)/etc/samba \
- CONFIGDIR=$(DESTDIR)/etc/samba
+ SAMBABOOK=$(SAMBABOOK)/usr/share/samba/swat/using_samba \
+ CODEPAGEDIR=$(DESTDIR)/usr/share/samba/codepages
patch: patch-stamp
patch-stamp:
@@ -74,33 +57,25 @@ configure-stamp:
cp -f debian/config.cache source/config.cache; \
fi
- [ -f source/Makefile ] || (cd source && CFLAGS="$(CFLAGS)" ./configure \
+ [ -f source/Makefile ] || (cd source && ./configure \
--host=$(DEB_HOST_GNU_TYPE) \
--build=$(DEB_BUILD_GNU_TYPE) \
- --cache-file=./config.cache \
--with-fhs \
- --enable-shared \
- --enable-static \
--prefix=/usr \
--sysconfdir=/etc \
- --libdir=/etc/samba \
--with-privatedir=/etc/samba \
--localstatedir=/var \
--with-netatalk \
--with-smbmount \
--with-pam \
--with-syslog \
+ --with-sambabook \
--with-utmp \
--with-readline \
--with-pam_smbpass \
--with-libsmbclient \
--with-winbind \
- --with-msdfs \
- --with-automount \
- --with-acl-support \
- --with-tdbsam \
- --with-ldap \
- --with-python=python2.3)
+ --with-msdfs)
touch configure-stamp
@@ -108,8 +83,7 @@ build: patch-stamp configure-stamp build-stamp
build-stamp:
dh_testdir
- $(MAKE) -C source headers
- $(MAKE) -C source all nsswitch/libnss_wins.so python_ext
+ $(MAKE) -C source all nsswitch/libnss_wins.so
touch build-stamp
@@ -121,11 +95,11 @@ clean: unpatch
# Clean first the Samba package
# -$(MAKE) -C source realclean
# -$(MAKE) -C source clean
- -$(MAKE) -C source python_clean distclean
+ -$(MAKE) -C source distclean
# Delete stuff left after a build that is not deleted by 'make clean'
rm -f source/bin/wbinfo source/bin/winbindd source/bin/debug2html \
- source/bin/libsmbclient.a source/include/stamp-h
+ source/include/stamp-h
dh_clean
@@ -136,12 +110,6 @@ install: build
dh_clean -k
dh_installdirs
- mkdir -p $(DESTDIR)/usr/share/man $(DESTDIR)/usr/lib \
- $(DESTDIR)/lib/security $(DESTDIR)/sbin \
- $(DESTDIR)/usr/lib/cups/backend $(DESTDIR)/usr/share/samba \
- $(DESTDIR)/etc/pam.d $(DESTDIR)/etc/dhcp3/dhclient-enter-hooks.d \
- $(DESTDIR)/usr/lib/python2.3/site-packages
-
# Add here commands to install the package into debian/tmp.
$(MAKE) -C source install $(IVARS)
@@ -149,8 +117,6 @@ install: build
# 'make install' - do it manually.
$(MAKE) -C source installclientlib $(IVARS)
mv $(DESTDIR)/usr/lib/libsmbclient.so $(DESTDIR)/usr/lib/libsmbclient.so.0.1
- ln -s libsmbclient.so.0.1 $(DESTDIR)/usr/lib/libsmbclient.so.0
- ln -s libsmbclient.so.0.1 $(DESTDIR)/usr/lib/libsmbclient.so
# Install other stuff not installed by "make install"
install -m 0755 debian/mksmbpasswd.awk $(DESTDIR)/usr/sbin/mksmbpasswd
@@ -163,13 +129,13 @@ install: build
# Install libnss_wins.so, which is not installed by 'make install' either.
install -m 0644 source/nsswitch/libnss_wins.so \
- $(DESTDIR)/lib/libnss_wins.so.2
+ $(DESTDIR)/lib/libnss_wins.so
- # pam_smbpass.so isn't being installed by 'make install'.
+ # pam_smbpass.so is installed by 'make install' in $(DESTDIR)/usr/bin/.
# We'll move it here to $(DESTDIR)/lib/security/ and then
# libpam-smbpass.files will make dh_movefiles move it to the
# right location in the libpam-smbpass package.
- install -m 0644 source/bin/pam_smbpass.so $(DESTDIR)/lib/security/
+ mv $(DESTDIR)/usr/bin/pam_smbpass.so $(DESTDIR)/lib/security/
# Create the symlink that will allow us to do "mount -t smbfs ...".
# Create also a symlink that will allow "mount -t smb ..." to
@@ -185,6 +151,14 @@ install: build
# Erich Schubert <debian@vitavonni.de> in #109509):
ln -s ../../../bin/smbspool $(DESTDIR)/usr/lib/cups/backend/smb
+ # To avoid duplication of a large number of files, the swat package
+ # does not contain the "Using Samba" book nor the HTML docs.
+ # Instead, these are provided by the samba-doc package and
+ # are accessed through symlinks provided in the swat package.
+ # Here we create the symlink for the book, and the symlinks
+ # for the HTML files are created by the script installswat.sh.
+ ln -s ../../doc/samba-doc/htmldocs/using_samba $(SAMBABOOK)/usr/share/samba/swat/using_samba
+
# Install man pages for files without man pages in the upstream sources
install -m 0644 debian/mksmbpasswd.8 $(DESTDIR)/usr/share/man/man8/mksmbpasswd.8
@@ -196,25 +170,21 @@ install: build
# We're not providing findsmb (should we?) so let's remove the man
# pages.
- find debian/ -name 'findsmb*' -exec rm -f {} \;
+ find debian/ -name 'findsmb*' -exec rm {} \;
# Install samba-common's conffiles - they'll get moved later to their
# correct place by dh_movefiles.
cp debian/smb.conf $(DESTDIR)/usr/share/samba/
- install -m755 debian/panic-action $(DESTDIR)/usr/share/samba/
- cp debian/gdbcommands $(DESTDIR)/etc/samba/
cp debian/samba.pamd $(DESTDIR)/etc/pam.d/samba
- install -m755 debian/samba-common.dhcp $(DESTDIR)/etc/dhcp3/dhclient-enter-hooks.d/samba
- # Install the Python modules
- #
- # Hmmm... need to figure this out. We have lib.linux-i686-2.2
- # and lib.linux-i686-2.3 directories. Using only the stuff from
- # the 2.3 directory for now. peloy.-
- #cp source/build/lib.*/samba/*.so $(DESTDIR)/usr/lib/python2.3/site-packages/
- cp source/build/lib.linux-*-2.3/samba/*.so $(DESTDIR)/usr/lib/python2.3/site-packages/
+ # This is to comply with policy (the symlink that ldconfig would
+ # produce must exist in the package).
+ /sbin/ldconfig -n $(DESTDIR)/usr/lib/
+
+ dh_movefiles --sourcedir=debian/samba/
- dh_movefiles
+ # Remove empty directories that will never be used.
+ rmdir $(DESTDIR)/sbin
# Build architecture-independent files here.
# Pass -i to all debhelper commands in this target to reduce clutter.
@@ -223,9 +193,9 @@ binary-indep: build install
dh_testdir
dh_testroot
dh_installdebconf
- dh_installdocs -A debian/README.build
+ dh_installdocs -A docs/textdocs/DIAGNOSIS.txt debian/README.build docs/README* docs/Samba-HOWTO-Collection.pdf
# dh_installexamples is not available in Debian Potato...
- [ -x /usr/bin/dh_installexamples ] && DH_OPTIONS= dh_installexamples -v -psamba-doc examples/*
+ [ -x /usr/bin/dh_installexamples ] && dh_installexamples
# dh_installmenu
# dh_installemacsen
# dh_installpam
@@ -234,14 +204,10 @@ binary-indep: build install
# dh_installmanpages
# dh_installinfo
# dh_undocumented
- dh_installchangelogs
+ dh_installchangelogs
dh_link
dh_compress
dh_fixperms
-
- # Get rid of those pesky .cvsignore files to make lintian happy
- find debian/ -name .cvsignore -exec rm -f {} \;
-
dh_installdeb
# dh_perl
dh_gencontrol
@@ -255,9 +221,9 @@ binary-arch: build install
dh_testdir
dh_testroot
dh_installdebconf
- dh_installdocs -A debian/README.build
+ dh_installdocs -A docs/textdocs/DIAGNOSIS.txt debian/README.build docs/README* docs/Samba-HOWTO-Collection.pdf
# dh_installexamples is not available in Debian Potato...
- [ -x /usr/bin/dh_installexamples ] && DH_OPTIONS= dh_installexamples -v -ppython2.3-samba source/python/examples/*
+ [ -x /usr/bin/dh_installexamples ] && dh_installexamples
# dh_installmenu
# dh_installlogrotate is not available in Debian Potato...
if [ -x /usr/bin/dh_installlogrotate ]; then \
@@ -270,15 +236,12 @@ binary-arch: build install
fi
# dh_installemacsen
# dh_installpam
- DH_OPTIONS= dh_installinit -psamba -- "defaults 20 19"
- DH_OPTIONS= dh_installinit -pwinbind
- dh_installcron
+ dh_installinit -n
+ dh_installcron
# dh_installmanpages
# dh_installinfo
- cp debian/winbind.lintian debian/winbind/usr/share/lintian/overrides/winbind
-# dh_undocumented
- dh_installchangelogs -Nlibpam-smbpass
- DH_OPTIONS= dh_installchangelogs -plibpam-smbpass source/pam_smbpass/CHANGELOG
+ dh_undocumented
+ dh_installchangelogs
dh_strip
dh_link
dh_compress
@@ -296,13 +259,8 @@ binary-arch: build install
chmod u+s debian/smbfs/usr/bin/smbumount
# Set some reasonable default perms for the samba logdir.
- chmod 0750 debian/samba/var/log/samba/
- chown root.adm debian/samba/var/log/samba/
-
- # Get rid of those pesky .cvsignore files to make lintian happy
- # (maybe we only need the "find ... -exec rm -f {} ;" we have
- # in the binary-indep target?) peloy.-
- find debian/ -name .cvsignore -exec rm -f {} \;
+ chmod 0750 $(DESTDIR)/var/log/samba/
+ chown root.adm $(DESTDIR)/var/log/samba/
dh_installdeb
# dh_makeshlibs
diff --git a/packaging/Debian/debian/samba-common.conffiles b/packaging/Debian/debian/samba-common.conffiles
new file mode 100755
index 00000000000..d14c1b51c1b
--- /dev/null
+++ b/packaging/Debian/debian/samba-common.conffiles
@@ -0,0 +1 @@
+/etc/pam.d/samba
diff --git a/packaging/Debian/debian/samba-common.config b/packaging/Debian/debian/samba-common.config
index ed76b95cb84..c82dd887b06 100644
--- a/packaging/Debian/debian/samba-common.config
+++ b/packaging/Debian/debian/samba-common.config
@@ -3,42 +3,12 @@
# Source debconf library.
. /usr/share/debconf/confmodule
-# Function for grabbing a parameter from an smb.conf file
-smbconf_retr() {
- if [ -z "$1" ]; then
- return
- fi
-
- if [ -n "$2" ]; then
- local FILE="$2"
- fi
-
- if [ -z "$FILE" ]; then
- return
- fi
-
- sed -n -e"
- s/^[[:space:]]*\[global\]/\[global\]/i
- /^\[global\]/,/^[[:space:]]*\[/ {
- s/^[[:space:]]*$1[[:space:]]*=[[:space:]]*//pi
- }" $FILE \
- | tail -1
-}
-
FILE=/etc/samba/smb.conf
db_title "Samba Server"
-# We ask the question IFF the config contains complex options that could
-# cause us to break the config.
-if [ -f "$FILE" ] && grep -v dhcp.conf $FILE \
- | grep -qEi '\\$|^[[:space:]]*include[[:space:]]*='
-then
- db_input high samba-common/do_debconf || true
- db_go
-else
- db_set samba-common/do_debconf true
-fi
+db_input medium samba-common/do_debconf || true
+db_go
# If user doesn't want to use debconf to configure Samba the leave...
db_get samba-common/do_debconf || true
@@ -59,12 +29,16 @@ fi
# Preload any values from the existing smb.conf file
if [ -f $FILE ]; then
- WORKGROUP=`smbconf_retr workgroup`
+ WORKGROUP=`grep -i '^[[:space:]]*workgroup[[:space:]]*=' $FILE \
+ | sed -e's/^[[:space:]]*workgroup[[:space:]]*=[[:space:]]*//i' \
+ | tail -1`
if [ "$WORKGROUP" ]; then
db_set samba-common/workgroup "$WORKGROUP"
fi
- ENCRYPT=`smbconf_retr "encrypt passwords"`
+ ENCRYPT=`grep -i '^[[:space:]]*encrypt passwords[[:space:]]*=' $FILE \
+ | sed -e's/^[[:space:]]*encrypt passwords[[:space:]]*=[[:space:]]*//i' \
+ | tail -1`
if [ "$ENCRYPT" ]; then
ENCRYPT=`echo $ENCRYPT | tr '[A-Z]' '[a-z]'`
if [ "$ENCRYPT" = "yes" ]; then
@@ -75,29 +49,6 @@ if [ -f $FILE ]; then
db_set samba-common/encrypt_passwords "$ENCRYPT"
fi
-
- CHARSET=`smbconf_retr "character set"`
- CODEPAGE=`smbconf_retr "client code page"`
- UNIXCHARSET=`smbconf_retr "unix charset"`
- DOSCHARSET=`smbconf_retr "dos charset"`
-
- # If we're upgrading from an old version and there's no
- # 'passdb backend' setting, add one.
- if [ "$1" = "configure" -a -n "$2" ] \
- && dpkg --compare-versions "$2" lt 2.99.cvs.20020713-2 \
- && ! grep -q -i '^[[:space:]]*passdb backend[[:space:]]*=' $FILE
- then
- TMPFILE=/etc/samba/smb.conf.dpkg-tmp
- sed -e'
- s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- s/^\([[:space:]]*\)encrypt passwords/\1encrypt passwords/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ {
- /^[[:space:]]*encrypt passwords[[:space:]]*=/a \
- passdb backend = smbpasswd guest
- }' < $FILE > ${TMPFILE}
- chmod a+r ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- fi
fi
# Get workgroup name
@@ -108,47 +59,3 @@ db_go
db_input medium samba-common/encrypt_passwords || true
db_go
-# Handle migrating character sets
-if [ -n "$CHARSET" -a -z "$UNIXCHARSET" ]
-then
- UNIXCHARSET=`echo $CHARSET | sed -e's/iso-/ISO/i'`
- db_set samba-common/character_set "$UNIXCHARSET"
- # FIXME: should eventually be low.
- db_input medium samba-common/character_set || true
- db_go
-fi
-
-if [ -n "$CODEPAGE" -a -z "$DOSCHARSET" ]
-then
- DOSCHARSET=CP`echo $CODEPAGE | sed -e's/[[:alpha:]]*//g'`
- db_set samba-common/codepage "$DOSCHARSET"
- # FIXME: should eventually be low.
- db_input medium samba-common/codepage || true
- db_go
-fi
-
-DHCPPRIORITY=medium
-#if [ "$DEBCONF_RECONFIGURE" = 1 ] && [ -f /sbin/dhclient3 ]
-if [ -f /sbin/dhclient3 ]
-then
- DHCPPRIORITY=high
-# TODO: see if we can detect that dhcp3-client is *going* to be installed,
-# even if it isn't yet.
-#elif dpkg-query -W --showformat='${Status}\n' dhcp3-client | grep ???
-# unknown ok not-installed ?
-# DHCPPRIORITY=high
-fi
-
-if [ ! -f $FILE ] || grep -q -i 'wins server' $FILE
-then
- # check the values before and after; unset the 'applied' flag
- # if they don't match.
- db_get samba-common/dhcp || true
- OLDDHCP="$RET"
- db_input $DHCPPRIORITY samba-common/dhcp || true
- db_go
- db_get samba-common/dhcp || true
- if [ "$OLDDHCP" != "$RET" ]; then
- db_fset samba-common/dhcp applied false
- fi
-fi
diff --git a/packaging/Debian/debian/samba-common.dhcp b/packaging/Debian/debian/samba-common.dhcp
deleted file mode 100644
index 3b2fa4ba191..00000000000
--- a/packaging/Debian/debian/samba-common.dhcp
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-netbios_setup() {
- # No need to continue if we're called with an unsupported option
-
- if [ "$reason" != BOUND ] && [ "$reason" != RENEW ] \
- && [ "$reason" != REBIND ] && [ "$reason" != REBOOT ] \
- && [ "$reason" != EXPIRE ] && [ "$reason" != FAIL ]
- then
- return
- fi
-
- umask 022
-
- if [ -z "$new_netbios_name_servers" ] || [ "$reason" = FAIL ] \
- || [ "$reason" = EXPIRE ]
- then
- # FIXME: add sed magic to only remove wins servers
- # associated with this interface
- echo -n > /etc/samba/dhcp.conf
- elif [ "$new_netbios_name_servers" != "$old_netbios_name_servers" ]
- then
- local serverlist=""
- for server in $new_netbios_name_servers
- do
- serverlist="$serverlist $interface:$server"
- done
- # FIXME: add sed magic to only update wins servers
- # associated with this interface
- echo " wins server =$serverlist" > /etc/samba/dhcp.conf
- fi
-}
-
-netbios_setup
diff --git a/packaging/Debian/debian/samba-common.dirs b/packaging/Debian/debian/samba-common.dirs
index c089ad73573..7c8094b988a 100644
--- a/packaging/Debian/debian/samba-common.dirs
+++ b/packaging/Debian/debian/samba-common.dirs
@@ -1,2 +1 @@
etc/samba
-etc/dhcp3/dhclient-enter-hooks.d
diff --git a/packaging/Debian/debian/samba-common.files b/packaging/Debian/debian/samba-common.files
index 9fb3a3a1623..0929836f6a6 100644
--- a/packaging/Debian/debian/samba-common.files
+++ b/packaging/Debian/debian/samba-common.files
@@ -1,15 +1,8 @@
-etc/samba/
-etc/dhcp3/
-etc/pam.d/
-usr/bin/net
+etc/samba
usr/bin/nmblookup
usr/bin/smbpasswd
-usr/bin/testparm
+etc/pam.d/
usr/share/man/man1/nmblookup.1
-usr/share/man/man1/testparm.1
-usr/share/man/man5/lmhosts.5
-usr/share/man/man5/smb.conf.5
-usr/share/man/man7/samba.7
-usr/share/man/man8/net.8
usr/share/man/man8/smbpasswd.8
-usr/share/samba/
+usr/share/samba/codepages/
+usr/share/samba/smb.conf
diff --git a/packaging/Debian/debian/samba-common.postinst b/packaging/Debian/debian/samba-common.postinst
index 6c6eb9bf537..8d256f4146f 100644
--- a/packaging/Debian/debian/samba-common.postinst
+++ b/packaging/Debian/debian/samba-common.postinst
@@ -13,9 +13,6 @@ if [ ! -e /etc/samba/smb.conf ]; then
cp -a /usr/share/samba/smb.conf /etc/samba/
fi
-# Static tempfile location, dpkg-style
-TMPFILE=/etc/samba/smb.conf.dpkg-tmp
-
# ------------------------- Debconf questions start ---------------------
# Is the user configuring with debconf, or he/she prefers swat/manual
@@ -26,17 +23,8 @@ if [ "${RET}" = "true" ]; then
db_get samba-common/workgroup || true
WORKGROUP="${RET}"
- # Oh my GOD, this is ugly. Why would anyone put these
- # characters in a workgroup name? Why, Lord, why???
- WORKGROUP=`echo $WORKGROUP | \
- sed -e's/\\\\/\\\\\\\\/g
- s#/#\\\\/#g
- s/&/\\\&/g
- s/\\\$/\\\\\\\$/g'`
-
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ \
- s/^\([[:space:]]*\)workgroup[[:space:]]*=.*/\1workgroup = ${WORKGROUP}/i" \
+ TMPFILE=`mktemp -q /tmp/smb.conf.XXXXXX`
+ sed -e "s/^\([[:space:]]*\)workgroup[[:space:]]*=.*/\1workgroup = ${WORKGROUP}/" \
< /etc/samba/smb.conf >${TMPFILE}
mv -f ${TMPFILE} /etc/samba/smb.conf
@@ -44,90 +32,10 @@ if [ "${RET}" = "true" ]; then
db_get samba-common/encrypt_passwords || true
ENCRYPT_PASSWORDS="${RET}"
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ \
- s/^\([[:space:]]*\)encrypt passwords[[:space:]]*=.*/\1encrypt passwords = ${ENCRYPT_PASSWORDS}/i" \
+ TMPFILE=`mktemp -q /tmp/smb.conf.XXXXXX`
+ sed -e "s/^\([[:space:]]*\)encrypt passwords[[:space:]]*=.*/\1encrypt passwords = ${ENCRYPT_PASSWORDS}/" \
< /etc/samba/smb.conf >${TMPFILE}
mv -f ${TMPFILE} /etc/samba/smb.conf
-
- # Install DHCP support
- db_get samba-common/dhcp && DHCPVAL="$RET"
- db_fget samba-common/dhcp applied || true
- if [ "$DHCPVAL" = true ] && [ "$RET" != true ] && \
- ! grep -q dhcp.conf /etc/samba/smb.conf
- then
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ {
- /wins server[[:space:]]*=/a \\
-\\
-# If we receive WINS server info from DHCP, override the options above. \\
- include = /etc/samba/dhcp.conf
-}" < /etc/samba/smb.conf > ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- elif [ "$RET" != true ] && grep -q dhcp.conf /etc/samba/smb.conf
- then
- :
- # FIXME: here we /delete/ the lines?
- fi
- # Once we get here, the config has been applied, whatever
- # it is.
- if [ "$RET" != true ]; then
- db_fset samba-common/dhcp applied true
- fi
-
- # Update charset settings?
- if ! grep -q "^[[:space:]]*unix charset[[:space:]]*=" /etc/samba/smb.conf
- then
- db_get samba-common/character_set || true
- UNIXCHARSET="${RET}"
- if [ -n "$UNIXCHARSET" ]
- then
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- s/^\([[:space:]]*\)character set/\1character set/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ {
- /^[[:space:]]*character set[[:space:]]*=/c \\
- unix charset = $UNIXCHARSET
- }" < /etc/samba/smb.conf > ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- fi
- fi
-
- if grep -qi "^[[:space:]]*passdb backend[[:space:]]*=.*unixsam" /etc/samba/smb.conf
- then
- sed -e 's/^\([[:space:]]*\)passdb backend/\1passdb backend/i
- /^[[:space:]]*passdb backend/ {
- s/unixsam/guest/i
- }' < /etc/samba/smb.conf > ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- fi
-
- if ! grep -q "^[[:space:]]*dos charset[[:space:]]*=" /etc/samba/smb.conf
- then
- db_get samba-common/codepage || true
- DOSCHARSET="${RET}"
- if [ -n "$DOSCHARSET" ]
- then
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- s/^\([[:space:]]*\)client code page/\1client code page/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ {
- /^[[:space:]]*client code page[[:space:]]*=/c \\
- dos charset = $DOSCHARSET
-}" < /etc/samba/smb.conf > ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- fi
- fi
-
- if dpkg --compare-versions "$2" lt 2.999+3.0.alpha20-4 \
- && ! grep -q "^[[:space:]]*panic action[[:space:]]*=" /etc/samba/smb.conf
- then
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- /^[[:space:]]*\[global\]/a \\
-\\
-# Do something sensible when Samba crashes: mail the admin a backtrace\\
- panic action = /usr/share/samba/panic-action %d" < /etc/samba/smb.conf > ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
- fi
-
fi
chmod a+r /etc/samba/smb.conf
diff --git a/packaging/Debian/debian/samba-common.templates b/packaging/Debian/debian/samba-common.templates
index e5f7b1ae0cc..c729b0b3243 100644
--- a/packaging/Debian/debian/samba-common.templates
+++ b/packaging/Debian/debian/samba-common.templates
@@ -1,66 +1,28 @@
-Template: samba-common/character_set
-Type: string
-_Description: Character Set for Unix filesystem
- You currently have a "character set" configured in your smb.conf. In
- Samba 3.0, this option is replaced by a new option, "unix charset".
- Please specify the character set you wish to use for theis new option,
- which controls how Samba interprets filenames on the file system.
- .
- If you leave this option blank, your smb.conf will not be changed.
-
-Template: samba-common/codepage
-Type: string
-_Description: Character Set for DOS clients
- You currently have a "client code page" set in your smb.conf. In Samba
- 3.0, this option is replaced by the option "dos charset". Please specify
- the character set you wish to use for this new option. In most cases, the
- default chosen for you will be sufficient. Note that this option is not
- needed to support Windows clients, it is only for DOS clients. If you
- leave this option blank, your smb.conf will not be changed.
-
-Template: samba-common/dhcp
-Type: boolean
-Default: false
-_Description: Modify smb.conf to use WINS settings from DHCP?
- If your computer gets IP address information from a DHCP server on the
- network, the DHCP server may also provide information about WINS servers
- ("NetBIOS name servers") present on the network. This requires a
- change to your smb.conf file so that DHCP-provided WINS settings will
- automatically be read from /etc/samba/dhcp.conf.
- .
- You must have the dhcp3-client package installed to take advantage of this
- feature.
-
Template: samba-common/do_debconf
Type: boolean
Default: true
-_Description: Configure smb.conf through debconf?
- The rest of the configuration of Samba deals with questions that affect
- parameters in /etc/samba/smb.conf, which is the file used to configure the
- Samba programs (nmbd and smbd.) Your current smb.conf contains an
- 'include' line or an option that spans multiple lines, which could confuse
- debconf and require you to edit your smb.conf by hand to get it working
- again.
- .
- If you don't use debconf to configure smb.conf, you will have to handle
- any configuration changes yourself, and will not be able to take
- advantage of periodic configuration enhancements. Therefore, use of
- debconf is recommended if possible.
+Description: Configure smb.conf through debconf?
+ The rest of the configuration of Samba deals with questions that
+ affect parameters in /etc/samba/smb.conf, which is the file used
+ to configure the Samba programs (nmbd and smbd.) If you want to be
+ asked just a few questions then select "Yes" and continue with the
+ configuration. If you want to have full control, select "No" and
+ configure your smb.conf manually or through SWAT.
Template: samba-common/workgroup
Type: string
-_Description: Workgroup/Domain Name?
- This controls what workgroup your server will appear to be in when queried
- by clients. Note that this parameter also controls the Domain name used
- with the security=domain setting.
+Description: Workgroup/Domain Name?
+ This controls what workgroup your server will appear to be in when
+ queried by clients. Note that this parameter also controls the Domain
+ name used with the security=domain setting.
Template: samba-common/encrypt_passwords
Type: boolean
Default: true
-_Description: Use password encryption?
+Description: Use password encryption?
Recent Windows clients communicate with SMB servers using encrypted
- passwords. If you want to use clear text passwords you will need to change
- a parameter in your Windows registry. It is recommended that you use
- encrypted passwords. If you do, make sure you have a valid
- /etc/samba/smbpasswd file and that you set passwords in there for each
- user using the smbpasswd command.
+ passwords. If you want to use clear text passwords you will need to
+ change a parameter in your Windows registry. It is recommended that
+ you use encrypted passwords. If you do, make sure you have a valid
+ /etc/samba/smbpasswd file and that you set passwords in there for
+ each user using the smbpasswd command.
diff --git a/packaging/Debian/debian/samba-common.templates.es b/packaging/Debian/debian/samba-common.templates.es
new file mode 100755
index 00000000000..2db32ba9ad6
--- /dev/null
+++ b/packaging/Debian/debian/samba-common.templates.es
@@ -0,0 +1,46 @@
+Template: samba-common/do_debconf
+Type: boolean
+Default: true
+Description: Configure smb.conf through debconf?
+ The rest of the configuration of Samba deals with questions that affect
+ parameters in /etc/samba/smb.conf, which is the file used to configure the
+ Samba programs (nmbd and smbd.) If you want to be asked just a few
+ questions then select "Yes" and continue with the configuration. If you
+ want to have full control, select "No" and configure your smb.conf
+ manually or through SWAT.
+Description-es: ¿Configurar smb.conf mediante debconf?
+ El resto de la configuración de Samba trata sobre cuestiones que afectan
+ al contenido de /etc/samba/smb.conf, que es el fichero utilizado para
+ configurar los programas de Samba (nmbd y smbd). Si desea responder a las
+ preguntas, elija "Sí" y continuará con la configuración. Si quiere
+ tener control total, escoja "No" y configure smb.conf manualmente o con
+ SWAT.
+
+Template: samba-common/workgroup
+Type: string
+Description: Workgroup/Domain Name?
+ This controls what workgroup your server will appear to be in when queried
+ by clients. Note that this parameter also controls the Domain name used
+ with the security=domain setting.
+Description-es: Nombre del dominio o del grupo de trabajo.
+ Es el grupo de trabajo en el que aparecerá su servidor cuando se lo
+ pregunten los clientes de la red. Este parámetro también controla el
+ nombre de dominio que se usa con la configuración security=domain.
+
+Template: samba-common/encrypt_passwords
+Type: boolean
+Default: true
+Description: Use password encryption?
+ Recent Windows clients communicate with SMB servers using encrypted
+ passwords. If you want to use clear text passwords you will need to change
+ a parameter in your Windows registry. It is recommended that you use
+ encrypted passwords. If you do, make sure you have a valid
+ /etc/samba/smbpasswd file and that you set passwords in there for each
+ user using the smbpasswd command.
+Description-es: ¿Utilizar contraseñas cifradas?
+ Los clientes Windows más modernos se comunican con los servidores SMB
+ utilizando contraseñas cifradas. Si quiere usar contraseñas en texto
+ plano, tendrá que cambiar un parámetro en el registro de Windows. Es muy
+ recomendable usar cifrado en las contraseñas. Si elige hacerlo, compruebe
+ que tiene un fichero /etc/samba/smbpasswd válido y que ha puesto las
+ contraseñas con el programa smbpasswd.
diff --git a/packaging/Debian/debian/samba-common.templates.fr b/packaging/Debian/debian/samba-common.templates.fr
new file mode 100755
index 00000000000..e26fedaf5b7
--- /dev/null
+++ b/packaging/Debian/debian/samba-common.templates.fr
@@ -0,0 +1,47 @@
+Template: samba-common/do_debconf
+Type: boolean
+Default: true
+Description: Configure smb.conf through debconf?
+ The rest of the configuration of Samba deals with questions that affect
+ parameters in /etc/samba/smb.conf, which is the file used to configure the
+ Samba programs (nmbd and smbd.) If you want to be asked just a few
+ questions then select "Yes" and continue with the configuration. If you
+ want to have full control, select "No" and configure your smb.conf
+ manually or through SWAT.
+Description-fr: Voulez-vous configurer smb.conf avec debconf ?
+ La suite de la configuration de Samba pose des questions sur des paramètres
+ de /etc/samba/smb.conf, le fichier utilisé pour configurer les programmes
+ de Samba (nmbd et smbd). Si vous voulez bien répondre à quelques questions,
+ choisissez « Yes » et poursuivez la configuration. Si vous voulez un
+ contrôle total, choisissez « No » et configurez le fichier smb.conf
+ manuellement ou avec SWAT.
+
+Template: samba-common/workgroup
+Type: string
+Description: Workgroup/Domain Name?
+ This controls what workgroup your server will appear to be in when queried
+ by clients. Note that this parameter also controls the Domain name used
+ with the security=domain setting.
+Description-fr: Groupe de travail et nom de domaine ?
+ Ce paramètre indique le groupe de travail où les clients trouveront le
+ serveur. Il indique aussi le nom de domaine utilisé par le paramètre
+ « security=domain ».
+
+Template: samba-common/encrypt_passwords
+Type: boolean
+Default: true
+Description: Use password encryption?
+ Recent Windows clients communicate with SMB servers using encrypted
+ passwords. If you want to use clear text passwords you will need to change
+ a parameter in your Windows registry. It is recommended that you use
+ encrypted passwords. If you do, make sure you have a valid
+ /etc/samba/smbpasswd file and that you set passwords in there for each
+ user using the smbpasswd command.
+Description-fr: Voulez-vous chiffrer les mots de passe ?
+ Des clients Windows récents communiquent avec les serveurs SMB en utilisant
+ des mots de passe chiffrés. Si vous voulez utiliser des mots de passe sans
+ chiffrement, vous devez modifier un paramètre dans le registre de Windows.
+ Il est recommandé d'utiliser des mots de passe chiffrés. Si vous le faites,
+ n'oubliez pas de créer un fichier /etc/samba/smbpasswd et d'y mettre les
+ mots de passe de tous les utilisateurs qui se servent de la commande
+ smbpasswd.
diff --git a/packaging/Debian/debian/samba-common.templates.pt_BR b/packaging/Debian/debian/samba-common.templates.pt_BR
new file mode 100755
index 00000000000..69d5ed8d46f
--- /dev/null
+++ b/packaging/Debian/debian/samba-common.templates.pt_BR
@@ -0,0 +1,47 @@
+Template: samba-common/do_debconf
+Type: boolean
+Default: true
+Description: Configure smb.conf through debconf?
+ The rest of the configuration of Samba deals with questions that affect
+ parameters in /etc/samba/smb.conf, which is the file used to configure the
+ Samba programs (nmbd and smbd.) If you want to be asked just a few
+ questions then select "Yes" and continue with the configuration. If you
+ want to have full control, select "No" and configure your smb.conf
+ manually or through SWAT.
+Description-pt_BR: Configurar smb.conf através do debconf ?
+ O restante da configuração do Samba lida com questões que afetam
+ parâmetros no arquivo /etc/samba/smb.conf, que é o arquivo usado para
+ configurar os programas Samba (nmbd e smbd). Caso você prefira somente
+ algumas perguntas selecione "Sim" e continue com a configuração. Se você
+ quer ter controle total, selecione "Não" e configure seu arquivo smb.conf
+ manualmente ou através da ferramenta SWAT.
+
+Template: samba-common/workgroup
+Type: string
+Description: Workgroup/Domain Name?
+ This controls what workgroup your server will appear to be in when queried
+ by clients. Note that this parameter also controls the Domain name used
+ with the security=domain setting.
+Description-pt_BR: Nome de Domínio/Grupo de Trabalho ?
+ Este parâmetro controla qual grupo de trabalho (workgroup) seu servidor
+ parecerá estar quando o mesmo for pesquisado por clientes. Note que este
+ parâmetro também controla o nome de Domínio usado com a configuração
+ security=domain.
+
+Template: samba-common/encrypt_passwords
+Type: boolean
+Default: true
+Description: Use password encryption?
+ Recent Windows clients communicate with SMB servers using encrypted
+ passwords. If you want to use clear text passwords you will need to change
+ a parameter in your Windows registry. It is recommended that you use
+ encrypted passwords. If you do, make sure you have a valid
+ /etc/samba/smbpasswd file and that you set passwords in there for each
+ user using the smbpasswd command.
+Description-pt_BR: Usar encriptação de senhas ?
+ Clientes Windows atuais comunicam-se com servidores SMB usando senhas
+ encriptadas. Caso você queira usar senhas em texto puro você precisará
+ modificar um parâmetro no registro de seu Windows. É recomendado que você
+ use senhas encriptadas. Se você usar, certifique-se de possuir um arquivo
+ /etc/samba/smbpasswd válido e que você definiu senhas no mesmo para cada
+ usuário utilizando o comando smbpasswd.
diff --git a/packaging/Debian/debian/samba-doc.docs b/packaging/Debian/debian/samba-doc.docs
index 4d2cec2ee22..68753e54f08 100644
--- a/packaging/Debian/debian/samba-doc.docs
+++ b/packaging/Debian/debian/samba-doc.docs
@@ -1,7 +1,9 @@
README
docs/Samba-HOWTO-Collection.pdf
docs/THANKS
+docs/announce
docs/history
+docs/textdocs/
docs/faq/
docs/htmldocs/
docs/Registry/
diff --git a/packaging/Debian/debian/samba-doc.examples b/packaging/Debian/debian/samba-doc.examples
index e71180364cf..e692dd810f0 100644
--- a/packaging/Debian/debian/samba-doc.examples
+++ b/packaging/Debian/debian/samba-doc.examples
@@ -1,2 +1,3 @@
+examples/
debian/wins2dns.awk
-source/smbadduser
+source/script/smbadduser
diff --git a/packaging/Debian/debian/samba.conffiles b/packaging/Debian/debian/samba.conffiles
new file mode 100755
index 00000000000..908a791a629
--- /dev/null
+++ b/packaging/Debian/debian/samba.conffiles
@@ -0,0 +1,3 @@
+/etc/cron.daily/samba
+/etc/init.d/samba
+/etc/logrotate.d/samba
diff --git a/packaging/Debian/debian/samba.config b/packaging/Debian/debian/samba.config
index 89792d436e4..d82e56ccf63 100644
--- a/packaging/Debian/debian/samba.config
+++ b/packaging/Debian/debian/samba.config
@@ -5,75 +5,27 @@
# Source debconf library.
. /usr/share/debconf/confmodule
-# Function for grabbing a parameter from an smb.conf file
-smbconf_retr() {
- if [ -z "$1" ]; then
- return
- fi
-
- if [ -n "$2" ]; then
- local FILE="$2"
- fi
-
- if [ -z "$FILE" ]; then
- return
- fi
-
- sed -n -e"
- s/^[[:space:]]*\[global\]/\[global\]/i
- /^\[global\]/,/^[[:space:]]*\[/ {
- s/^[[:space:]]*$1[[:space:]]*=[[:space:]]*//pi
- }" $FILE \
- | tail -1
-}
-
-FILE=/etc/samba/smb.conf
-
db_title "Samba Server"
# Babysit users who don't read README.Debian
-if [ -n "$2" ] && dpkg --compare-versions "$2" lt "2.2"
-then
- db_input medium samba/log_files_moved || true
- db_go
-fi
+db_input medium samba/log_files_moved || true
+db_go
db_input medium samba/run_mode || true
db_go
-
-# Offer to move the password database for existing users
-if [ "$1" = "configure" -a -n "$2" -a -e /etc/samba/smbpasswd \
- -a ! -e /var/lib/samba/passdb.tdb ] \
- && dpkg --compare-versions "$2" lt 2.99.cvs.20020713-2
-then
- FILE=/etc/samba/smb.conf
- PASSDB=""
- if [ -f "$FILE" ]; then
- PASSDB=`smbconf_retr "passdb backend"`
- fi
- TDBPRIORITY=medium
- if echo "$PASSDB" | grep -q ldapsam; then
- TDBPRIORITY=low
- fi
- db_get samba-common/do_debconf || true
- if [ "${RET}" = "false" ]; then
- TDBPRIORITY=low
- fi
-
- db_input "$TDBPRIORITY" samba/tdbsam || true
-fi
-
# We vary the priority of the next question depending on whether
-# the password database already exists...
-if [ -e /etc/samba/smbpasswd -o -e /var/lib/samba/passdb.tdb ]; then
+# /etc/samba/smbpasswd already exists...
+if [ -f /etc/samba/smbpasswd ]; then
PRIORITY="low"
else
# If 'encrypt passwords' is true in smb.conf, and smbpasswd
# does not exist, default to yes here.
FILE=/etc/samba/smb.conf
if [ -f "$FILE" ]; then
- ENCRYPT=`smbconf_retr "encrypt passwords"`
+ ENCRYPT=`grep -i '^[[:space:]]*encrypt passwords[[:space:]]*=' $FILE \
+ | sed -e's/^[[:space:]]*encrypt passwords[[:space:]]*=[[:space:]]*//i' \
+ | tail -1`
if [ "$ENCRYPT" ]; then
ENCRYPT=`echo $ENCRYPT | tr '[A-Z]' '[a-z]'`
if [ "$ENCRYPT" = "yes" ]; then
diff --git a/packaging/Debian/debian/samba.dirs b/packaging/Debian/debian/samba.dirs
index a58e4e98929..0b57a891a76 100644
--- a/packaging/Debian/debian/samba.dirs
+++ b/packaging/Debian/debian/samba.dirs
@@ -1,7 +1,12 @@
+sbin
usr/bin
usr/sbin
var/log/samba
-var/lib/samba/printers/W32X86
-var/lib/samba/printers/WIN40
+var/lib/samba
var/run/samba
var/cache/samba
+etc/pam.d
+usr/share
+usr/share/samba
+lib/security
+usr/lib/cups/backend
diff --git a/packaging/Debian/debian/samba.docs b/packaging/Debian/debian/samba.docs
index b8cc5419fb1..187fdd34058 100644
--- a/packaging/Debian/debian/samba.docs
+++ b/packaging/Debian/debian/samba.docs
@@ -1,5 +1,3 @@
README
Roadmap
WHATSNEW.txt
-docs/htmldocs/diagnosis.html
-docs/README.ldap
diff --git a/packaging/Debian/debian/samba.files b/packaging/Debian/debian/samba.files
deleted file mode 100644
index f52e6c5e4f7..00000000000
--- a/packaging/Debian/debian/samba.files
+++ /dev/null
@@ -1,19 +0,0 @@
-usr/bin/testprns
-usr/bin/smbstatus
-usr/bin/smbcontrol
-usr/bin/tdbbackup
-usr/bin/pdbedit
-usr/sbin/smbd
-usr/sbin/nmbd
-usr/sbin/mksmbpasswd
-usr/lib/samba/vfs
-usr/share/man/man1/smbcontrol.1
-usr/share/man/man1/smbstatus.1
-usr/share/man/man1/testprns.1
-usr/share/man/man5/smbpasswd.5
-usr/share/man/man8/nmbd.8
-usr/share/man/man8/pdbedit.8
-usr/share/man/man8/smbd.8
-usr/share/man/man8/mksmbpasswd.8
-usr/share/man/man8/tdbbackup.8
-
diff --git a/packaging/Debian/debian/samba.init b/packaging/Debian/debian/samba.init
index 5d0f4671a00..0ad8bc07e13 100644
--- a/packaging/Debian/debian/samba.init
+++ b/packaging/Debian/debian/samba.init
@@ -16,6 +16,19 @@ SMBDPID=/var/run/samba/smbd.pid
# clear conflicting settings from the environment
unset TMPDIR
+# If Samba is running from inetd then there is nothing to do
+if [ "$RUN_MODE" = "inetd" ]; then
+ # Commented out to close bug #26884 (startup message is rather long). I
+ # have yet to think how to let the user know that if he/she is running
+ # Samba from inetd, he can't just "/etc/init.d/samba stop" to stop
+ # the Samba daemons.
+# echo "Warning: Samba is not running as daemons. Daemons not restarted/stopped."
+# echo "Daemons will start automatically by inetd (if you wanted to start Samba)."
+# echo "If you want to stop Samba, get the PID's of all nmbd and smbd processes"
+# echo "and send them a SIGTERM signal but keep in mind that inetd could restart them."
+ exit 0
+fi
+
# See if the daemons are there
test -x /usr/sbin/nmbd -a -x /usr/sbin/smbd || exit 0
@@ -26,42 +39,21 @@ case "$1" in
echo -n " nmbd"
start-stop-daemon --start --quiet --exec /usr/sbin/nmbd -- -D
- if [ "$RUN_MODE" != "inetd" ]; then
- echo -n " smbd"
- start-stop-daemon --start --quiet --exec /usr/sbin/smbd -- -D
- fi
+ echo -n " smbd"
+ start-stop-daemon --start --quiet --exec /usr/sbin/smbd -- -D
echo "."
;;
stop)
- echo -n "Stopping Samba daemons: "
+ echo -n "Stopping Samba daemons:"
+ echo -n " nmbd"
start-stop-daemon --stop --quiet --pidfile $NMBDPID
- # Wait a little and remove stale PID file
- sleep 1
- if [ -f $NMBDPID ] && ! ps h `cat $NMBDPID` > /dev/null
- then
- # Stale PID file (nmbd was succesfully stopped),
- # remove it (should be removed by nmbd itself IMHO.)
- rm -f $NMBDPID
- fi
- echo -n "nmbd"
-
- if [ "$RUN_MODE" != "inetd" ]; then
- start-stop-daemon --stop --quiet --pidfile $SMBDPID
- # Wait a little and remove stale PID file
- sleep 1
- if [ -f $SMBDPID ] && ! ps h `cat $SMBDPID` > /dev/null
- then
- # Stale PID file (nmbd was succesfully stopped),
- # remove it (should be removed by smbd itself IMHO.)
- rm -f $SMBDPID
- fi
- echo -n " smbd"
- fi
- echo "."
+ echo -n " smbd"
+ start-stop-daemon --stop --quiet --pidfile $SMBDPID
+ echo "."
;;
reload)
echo -n "Reloading /etc/samba/smb.conf (smbd only)"
@@ -70,9 +62,19 @@ case "$1" in
echo "."
;;
restart|force-reload)
- $0 stop
- sleep 1
- $0 start
+ echo -n "Restarting Samba daemons:"
+
+ echo -n " nmbd"
+ start-stop-daemon --stop --quiet --pidfile $NMBDPID
+ sleep 2
+ start-stop-daemon --start --quiet --exec /usr/sbin/nmbd -- -D
+
+ echo -n " smbd"
+ start-stop-daemon --stop --quiet --pidfile $SMBDPID
+ sleep 2
+ start-stop-daemon --start --quiet --exec /usr/sbin/smbd -- -D
+
+ echo "."
;;
*)
echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload}"
diff --git a/packaging/Debian/debian/samba.logrotate b/packaging/Debian/debian/samba.logrotate
index f90437bf2ad..d264ce3d71b 100644
--- a/packaging/Debian/debian/samba.logrotate
+++ b/packaging/Debian/debian/samba.logrotate
@@ -3,7 +3,7 @@
missingok
rotate 7
postrotate
- invoke-rc.d --quiet samba reload > /dev/null
+ killall -q -HUP smbd || true
endscript
compress
notifempty
@@ -14,7 +14,7 @@
missingok
rotate 7
postrotate
- [ -f /var/run/samba/nmbd.pid ] && kill -HUP `cat /var/run/samba/nmbd.pid`
+ killall -q -HUP nmbd || true
endscript
compress
notifempty
diff --git a/packaging/Debian/debian/samba.pamd b/packaging/Debian/debian/samba.pamd
index e2c7a99356d..1a5a14c7089 100644
--- a/packaging/Debian/debian/samba.pamd
+++ b/packaging/Debian/debian/samba.pamd
@@ -1,3 +1,5 @@
-@include common-auth
-@include common-account
-@include common-session
+auth required pam_unix.so nullok
+account required pam_unix.so
+session required pam_unix.so
+password required pam_unix.so
+
diff --git a/packaging/Debian/debian/samba.postinst b/packaging/Debian/debian/samba.postinst
index 1a25290ed27..772513f4c78 100644
--- a/packaging/Debian/debian/samba.postinst
+++ b/packaging/Debian/debian/samba.postinst
@@ -28,7 +28,6 @@ INITCONFFILE=/etc/default/samba
# them to be readable only by root.
umask 022
-
# Generate configuration file if it does not exist, using default values.
[ -r "${INITCONFFILE}" ] || {
echo Generating ${INITCONFFILE}... >&2
@@ -42,7 +41,7 @@ umask 022
# This is a POSIX shell fragment
#
-# How should Samba (smbd) run? Possible values are "daemons"
+# How should Samba (nmbd and smbd) run? Possible values are "daemons"
# or "inetd".
RUN_MODE=""
EOFMAGICNUMBER1234
@@ -97,113 +96,65 @@ then
mv /etc/samba/secrets.tdb /var/lib/samba/
fi
-# If upgrading from a previous 2.999 snapshot, move the passdb.tdb
-# database into /var/lib.
-
-if [ -n "$2" ] && dpkg --compare-versions "$2" lt 2.999+3.0.alpha23-5 \
- && [ -e /etc/samba/passdb.tdb -a ! -e /var/lib/samba/passdb.tdb ]
-then
- mv /etc/samba/passdb.tdb /var/lib/samba/
-fi
-
# --- End of FHS migration code ---
-# If upgrading from a previous 2.999 snapshot, clear the broken
-# registry.tdb file.
-if [ -n "$2" ] && dpkg --compare-versions "$2" gt 2.99.cvs.20020713-1 \
- && dpkg --compare-versions "$2" lt 2.999+3.0cvs20020805-1
-then
- rm -f /var/lib/samba/registry.tdb
-fi
-
# ------------------------- Debconf questions start ---------------------
# Run Samba as daemons or from inetd?
db_get samba/run_mode || true
RUN_MODE="${RET}"
-TMPFILE=/etc/default/samba.dpkg-tmp
+TMPFILE=`mktemp -q /tmp/samba.config.XXXXXX`
sed -e "s/^[[:space:]]*RUN_MODE[[:space:]]*=.*/RUN_MODE=\"${RUN_MODE}\"/" \
< ${INITCONFFILE} >${TMPFILE}
-chmod a+r ${TMPFILE}
mv -f ${TMPFILE} ${INITCONFFILE}
# Generate a smbpasswd file?
db_get samba/generate_smbpasswd || true
GENERATE_SMBPASSWD="${RET}"
-db_get samba/tdbsam || true
-PDB_MIGRATE="${RET}"
-
# Done with debconf now.
db_stop
-umask 066
-
-# FIXME: disable if ldapsam support is enabled?
-# FIXME: we don't want to pass these through the smbpasswd backend,
-# some of the faking can cause us problems!
-if [ "${GENERATE_SMBPASSWD}" = "true" -a ! -e /var/lib/samba/passdb.tdb -a ! -e /etc/samba/smbpasswd ]; then
+if [ "${GENERATE_SMBPASSWD}" = "true" -a ! -e /etc/samba/smbpasswd ]; then
getent passwd | /usr/sbin/mksmbpasswd > /etc/samba/smbpasswd
- pdbedit -i smbpasswd -e tdbsam
- rm /etc/samba/smbpasswd
-fi
-
-umask 022
-
-if [ -n "$2" -a -e /etc/samba/smbpasswd \
- -a ! -e /var/lib/samba/passdb.tdb -a "$PDB_MIGRATE" = "true" ] \
- && dpkg --compare-versions "$2" lt 2.99.cvs.20020713-2
-then
- umask 066
- pdbedit -i smbpasswd -e tdbsam
- rm /etc/samba/smbpasswd
- umask 022
-
- # The database has been moved, now make sure we can still find it.
- PASSDB=`sed -n -e"s/^[[:space:]]*\[global\]/\[global\]/i
- /^\[global\]/,/^[[:space:]]*\[/ \
- s/^[[:space:]]*passdb backend[[:space:]]*=[[:space:]]*//pi" \
- < /etc/samba/smb.conf \
- | tail -1`
- if echo "$PASSDB" | egrep -q "(^|[[:space:]])smbpasswd"; then
- if ! echo "$PASSDB" | egrep -q "(^|[[:space:]])tdbsam"; then
- PASSDB=`echo $PASSDB | sed -e's/\(^\|[[:space:]]\)smbpasswd/\1tdbsam/'`
- fi
- fi
- if ! echo "$PASSDB" | egrep -q "(^|[[:space:]])tdbsam"; then
- PASSDB="tdbsam $PASSDB"
- fi
- TMPFILE=/etc/samba/smb.conf.dpkg-tmp
- sed -e "s/^\([[:space:]]*\)\[global\]/\1\[global\]/i
- /^[[:space:]]*\[global\]/,/^[[:space:]]*\[/ \
- s/^\([[:space:]]*\)passdb backend[[:space:]]*=.*/\1passdb backend = ${PASSDB}/i" \
- < /etc/samba/smb.conf >${TMPFILE}
- chmod a+r ${TMPFILE}
- mv -f ${TMPFILE} /etc/samba/smb.conf
+ chmod 600 /etc/samba/smbpasswd
fi
# ------------------------- Debconf questions end ---------------------
-# Handle removal of nmbd from inetd.conf, which is no longer a supported
-# configuration.
-if dpkg --compare-versions "$2" lt 2.999+3.0.alpha20-4; then
- update-inetd --remove netbios-ns
-fi
+# We always run /etc/init.d/samba, even if we run Samba from inetd.
+# The init.d script takes care of handling the conflict of running
+# from inetd or as daemons.
+update-rc.d samba defaults 20 19 > /dev/null
# We want to add these entries to inetd.conf commented out. Otherwise
# UDP traffic could make inetd to start nmbd or smbd right during
# the configuration stage.
-if [ -z "$2" ]; then
+if [ "$1" = "configure" -a -z "$2" ]; then
+ update-inetd --add "#<off># netbios-ns dgram udp wait root /usr/sbin/tcpd /usr/sbin/nmbd -a"
update-inetd --add "#<off># netbios-ssn stream tcp nowait root /usr/sbin/tcpd /usr/sbin/smbd"
fi
if [ "$RUN_MODE" = "daemons" ]; then
+ update-inetd --disable netbios-ns
update-inetd --disable netbios-ssn
else
+ update-inetd --enable netbios-ns
update-inetd --enable netbios-ssn
fi
+# Start Samba: we don't want to call /etc/init.d/samba if we are
+# running from inetd because a nasty help message would be printed out.
+
+# Run the init script if this is a first-time install, or if it's an
+# upgrade and Samba was running before, _and_ we're not running from inetd.
+if [ \( -z "$2" -o ! -f /tmp/samba-was-not-running \) -a \
+ "$RUN_MODE" = "daemons" ]; then
+ # Check the script is executable before running it.
+ [ -x /etc/init.d/samba ] && /etc/init.d/samba start
+fi
+
# This check is a safety net: the /etc/samba/smbpasswd file must have
# permissions 600.
if [ -f /etc/samba/smbpasswd ]; then
@@ -223,6 +174,10 @@ rm -f /etc/samba/debian_config
mv -f /var/log/nmb* /var/log/samba/ 2> /dev/null || true
mv -f /var/log/smb* /var/log/samba/ 2> /dev/null || true
+# Do this last, so we don't accidentally start the daemons if something
+# else in the script fails above.
+rm -f /tmp/samba-was-not-running
+
#DEBHELPER#
exit 0
diff --git a/packaging/Debian/debian/samba.postrm b/packaging/Debian/debian/samba.postrm
index b79fe1d0099..17503df6b7d 100644
--- a/packaging/Debian/debian/samba.postrm
+++ b/packaging/Debian/debian/samba.postrm
@@ -1,11 +1,17 @@
-#!/bin/sh -e
+#!/bin/sh
#
#
if [ "$1" = purge ]; then
- # Remove Samba's state files, both volatile and non-volatile
- rm -Rf /var/run/samba/ /var/cache/samba/ /var/lib/samba
+ # Remove WINS.DAT, BROWSE.DAT and lock information file
+ rm -Rf /var/samba/
+
+ # Remove any files in the old and obsolete /var/lock/samba directory
+ rm -Rf /var/lock/samba/
+
+ # Remove files left in /etc/samba/
+ rm -Rf /etc/samba/MACHINE.SID
# Remove log files
rm -Rf /var/log/samba/
@@ -16,11 +22,13 @@ if [ "$1" = purge ]; then
# Remove NetBIOS entries from /etc/inetd.conf
update-inetd --remove netbios-ssn
+ update-inetd --remove netbios-ns
+ update-rc.d samba remove >/dev/null
else
# Not purging, do not remove NetBIOS entries from /etc/inetd.conf
update-inetd --disable netbios-ssn
-
+ update-inetd --disable netbios-ns
fi
#DEBHELPER#
diff --git a/packaging/Debian/debian/samba.preinst b/packaging/Debian/debian/samba.preinst
new file mode 100755
index 00000000000..8f6c3e210a7
--- /dev/null
+++ b/packaging/Debian/debian/samba.preinst
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# The purpose of the preinst script for the samba package is to help
+# the migration of the conffiles smb.conf and smbpasswd from their
+# old location (/etc/) to their new location (/etc/samba/).
+#
+# Thanks to Ben Pfaff <pfaffben@pilot.msu.edu> for sharing on debian-devel
+# his ideas about how to move conffiles to new locations.
+#
+#
+
+# First see if a smb.conf file currently exists.
+test -f /etc/smb.conf || exit 0
+
+# Now see if a smb.conf file exists in the new location.
+test -e /etc/samba/smb.conf && exit 0
+
+#
+# Move smb.conf conffile from its old location (/etc/) to its new one
+# (/etc/samba).
+#
+# If conffile exists in old location AND conffile does not exist on new
+# location then...
+#
+if [ -f /etc/smb.conf -a ! -e /etc/samba/smb.conf ]; then
+ # The new location for the conffile should not exist yet, so we create the
+ # dir.
+ mkdir -p /etc/samba
+
+ # Finally, move the conffile to its new location.
+ mv /etc/smb.conf /etc/samba/smb.conf
+fi
+
+#
+# Move smbpasswd conffile from its old location (/etc/) to its new one
+# (/etc/samba).
+#
+# If conffile exists in old location AND conffile does not exist on new
+# location then...
+#
+if [ -f /etc/smbpasswd -a ! -e /etc/samba/smbpasswd ]; then
+ # The new location for the conffile should not exist yet, so we create the
+ # dir.
+ mkdir -p /etc/samba
+
+ # Finally, move the conffile to its new location.
+ mv /etc/smbpasswd /etc/samba/smbpasswd
+fi
+
+#DEBHELPER#
diff --git a/packaging/Debian/debian/samba.prerm b/packaging/Debian/debian/samba.prerm
index ab62c706d85..ec30ff6687b 100644
--- a/packaging/Debian/debian/samba.prerm
+++ b/packaging/Debian/debian/samba.prerm
@@ -1,10 +1,26 @@
#!/bin/sh -e
-if [ "$1" = upgrade -a -n "$2" ] && dpkg --compare-versions "$2" lt 2.99 \
- && [ -e /var/lib/samba/passdb.tdb -a ! -e /etc/samba/smbpasswd ]
+# Clean up any such stale file.
+rm -f /tmp/samba-was-not-running
+
+# The smbd pid file is missing, or points to a dead process
+if [ ! -f /var/run/samba/smbd.pid ] || \
+ ! ps h `cat /var/run/samba/smbd.pid` > /dev/null
then
- pdbedit -i tdbsam -e smbpasswd
- rm -f /var/lib/samba/passdb.tdb
+ # The nmbd pid file is missing, or points to a dead process
+ if [ -f /var/run/samba/nmbd.pid ] || \
+ ! ps h `cat /var/run/samba/nmbd.pid` > /dev/null
+ then
+ # let the postinst know not to start samba.
+ [ "$1" = "upgrade" ] && touch /tmp/samba-was-not-running
+ fi
fi
+# We read /etc/default/samba to know if we're running from inetd or as
+# daemons so we don't call the init script if we are running from inetd.
+[ -r /etc/default/samba ] && . /etc/default/samba
+
+# We call the init script to stop Samba only if we are running as daemons.
+[ -x /etc/init.d/samba -a "$RUN_MODE" != "inetd" ] && /etc/init.d/samba stop
+
#DEBHELPER#
diff --git a/packaging/Debian/debian/samba.templates b/packaging/Debian/debian/samba.templates
index ce503aea5c4..9deeaa42b04 100644
--- a/packaging/Debian/debian/samba.templates
+++ b/packaging/Debian/debian/samba.templates
@@ -1,50 +1,33 @@
+Template: samba/run_mode
+Type: select
+Default: daemons
+Choices: daemons, inetd
+Description: How do you want to run Samba?
+ The Samba services (nmbd and smbd) can run as normal daemons or
+ from inetd. Running as daemons is the recommended approach.
+
Template: samba/generate_smbpasswd
Type: boolean
Default: false
-_Description: Create samba password database, /var/lib/samba/passdb.tdb?
- To be compatible with the defaults in most versions of Windows, Samba must
- be configured to use encrypted passwords. This requires user passwords to
- be stored in a file separate from /etc/passwd. This file can be created
- automatically, but the passwords must be added manually (by you or the
- user) by running smbpasswd, and you must arrange to keep it up-to-date in
- the future. If you do not create it, you will have to reconfigure samba
- (and probably your client machines) to use plaintext passwords. See
- /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html from the samba-doc
- package for more details.
+Description: Create samba password file, /etc/samba/smbpasswd?
+ To be compatible with the defaults in most versions of Windows,
+ Samba must be configured to use encrypted passwords. This requires
+ user passwords to be stored in a file separate from /etc/passwd.
+ This file can be created automatically, but the passwords must
+ be added manually (by you or the user) by running smbpasswd,
+ and you must arrange to keep it up-to-date in the future. If
+ you do not create it, you will have to reconfigure samba
+ (and probably your client machines) to use plaintext passwords.
+ See /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html from the
+ samba-doc package for more details.
Template: samba/log_files_moved
Type: note
-_Description: Samba's log files have moved.
- Starting with the first packages of Samba 2.2 for Debian the log files for
- both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The
- names of the files are log.nmbd and log.smbd, for nmbd and smbd
- respectively.
+Description: Samba's log files have moved.
+ Starting with the first packages of Samba 2.2 for Debian the log
+ files for both Samba daemons (nmbd and smbd) are now stored in
+ /var/log/samba/. The names of the files are log.nmbd and log.smbd,
+ for nmbd and smbd respectively.
.
- The old log files that were in /var/log/ will be moved to the new location
- for you.
-
-Template: samba/nmbd_from_inetd
-Type: note
-_Description: Running nmbd from inetd is no longer supported
- Your system was previously configured to start nmbd and smbd from inetd.
- As of version 2.999+3.0.alpha20-4, nmbd will no longer be started from
- inetd. If you have modified your /etc/init.d/samba startup script, you
- may need to adjust it by hand now so that nmbd will start.
-
-Template: samba/run_mode
-Type: select
-_Choices: daemons, inetd
-Default: daemons
-_Description: How do you want to run Samba?
- The Samba daemon smbd can run as a normal daemon or from inetd. Running as
- a daemon is the recommended approach.
-
-Template: samba/tdbsam
-Type: boolean
-Default: false
-_Description: Move /etc/samba/smbpasswd to /var/lib/samba/passdb.tdb?
- Samba 3.0 introduces a newer, more complete SAM database interface which
- supersedes the /etc/samba/smbpasswd file. Would you like your existing
- smbpasswd file to be migrated to /var/lib/samba/passdb.tdb for you? If you
- plan to use another pdb backend (e.g., LDAP) instead, you should answer
- 'no' here.
+ The old log files that were in /var/log/ will be moved to
+ the new location for you.
diff --git a/packaging/Debian/debian/samba.templates.es b/packaging/Debian/debian/samba.templates.es
new file mode 100755
index 00000000000..a3ea2c0e8bb
--- /dev/null
+++ b/packaging/Debian/debian/samba.templates.es
@@ -0,0 +1,56 @@
+Template: samba/run_mode
+Type: select
+Default: daemons
+Choices: daemons, inetd
+Choices-es: demonios, inetd
+Description: How do you want to run Samba?
+ The Samba services (nmbd and smbd) can run as normal daemons or
+ from inetd. Running as daemons is the recommended approach.
+Description-es: ¿Cómo quiere que Samba se ejecute?
+ Los servicios Samba (nmbd y smbd) pueden ejecutarse como demonios
+ normales o desde el inetd. Se recomienda que se ejecuten como demonios
+ independientes.
+
+Template: samba/generate_smbpasswd
+Type: boolean
+Default: false
+Description: Create samba password file, /etc/samba/smbpasswd?
+ To be compatible with the defaults in most versions of Windows,
+ Samba must be configured to use encrypted passwords. This requires
+ user passwords to be stored in a file separate from /etc/passwd.
+ This file can be created automatically, but the passwords must
+ be added manually (by you or the user) by running smbpasswd,
+ and you must arrange to keep it up-to-date in the future. If
+ you do not create it, you will have to reconfigure samba
+ (and probably your client machines) to use plaintext passwords.
+ See /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html from the
+ samba-doc package for more details.
+Description-es: ¿Crear el fichero de contraseñas /etc/samba/smbpasswd?
+ Para manterner compatibilidad con el comportamiento por defecto de la
+ mayoria de los sistemas Windows, hay que configurar Samba para que use
+ contraseñas encriptadas, lo cual requiere la creación de un fichero
+ distinto del /etc/passwd donde se guarden las contraseñas de los usuarios.
+ El fichero se puede crear automaticamente, aunque es necesario añadir
+ las contraseñas manualmente (por usted o por el usuario) usando
+ el programa `smbpasswd', y usted debe hacer arreglos para mantener las
+ contraseñas al día. Si no se crea este fichero, es imprescindible
+ configurar Samba (y posiblemente los ordenadores Windows) para usar
+ contraseñas no cifradas. Véa
+ /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html del paquete samba-doc
+ para más información.
+
+Template: samba/log_files_moved
+Type: note
+Description: Samba's log files have moved.
+ Starting with the first packages of Samba 2.2 for Debian the log
+ files for both Samba daemons (nmbd and smbd) are now stored in
+ /var/log/samba/. The names of the files are log.nmbd and log.smbd,
+ for nmbd and smbd respectively.
+ .
+ The old log files that were in /var/log/ will be moved to
+ the new location for you.
+Description-es: Se han movido los ficheros de registro de Samba.
+ A partir de los primeros paquetes de Samba 2.2 para Debian,
+ los ficheros de registro para los dos demonios del Samba (nmbd y smbd)
+ se encuentran en /var/log/samba/. Los nombres de estos ficheros
+ son log.nmbd y log.smbd, para nmbd y smbd respectivamente.
diff --git a/packaging/Debian/debian/samba.templates.fr b/packaging/Debian/debian/samba.templates.fr
new file mode 100755
index 00000000000..4a207750c24
--- /dev/null
+++ b/packaging/Debian/debian/samba.templates.fr
@@ -0,0 +1,57 @@
+Template: samba/run_mode
+Type: select
+Choices: daemons, inetd
+Choices-fr: démons, inetd
+Default: daemons
+Description: How do you want to run Samba?
+ The Samba services (nmbd and smbd) can run as normal daemons or from
+ inetd. Running as daemons is the recommended approach.
+Description-fr: Comment voulez-vous lancer Samba ?
+ Les services de Samba (nmbd et smbd) peuvent s'exécuter en tant que démons
+ classiques ou bien être lancés par inetd. L'approche recommandée est qu'ils
+ s'exécutent en tant que démons.
+
+Template: samba/generate_smbpasswd
+Type: boolean
+Default: false
+Description: Create samba password file, /etc/samba/smbpasswd?
+ To be compatible with the defaults in most versions of Windows,
+ Samba must be configured to use encrypted passwords. This requires
+ user passwords to be stored in a file separate from /etc/passwd.
+ This file can be created automatically, but the passwords must
+ be added manually (by you or the user) by running smbpasswd,
+ and you must arrange to keep it up-to-date in the future. If
+ you do not create it, you will have to reconfigure samba
+ (and probably your client machines) to use plaintext passwords.
+ See /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html from the
+ samba-doc package for more details.
+Description-fr: Faut-il créer un fichier /etc/samba/smbpasswd ?
+ Pour préserver la compatibilité avec le comportement par défaut de la
+ plupart des systèmes Windows, Samba doit utiliser
+ les mots de passe chiffrés. Cela exige la création d'un fichier,
+ distinct du fichier /etc/passwd, pour mettre les mots de passe des
+ utilisateurs. Ce fichier peut être créé automatiquement, mais
+ quelqu'un (vous ou l'utilisateur) devra ajouter les mots de
+ passe manuellement en utilisant la commande smbpasswd ; et vous devrez
+ maintenir à jour ce fichier. Si vous ne voulez pas créer le fichier
+ maintenant, Samba (et peut-être les ordinateurs Windows)
+ devra utiliser des mots de passe non chiffrés.
+ Voyez /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html dans le
+ paquet samba-doc pour plus de détails.
+
+Template: samba/log_files_moved
+Type: note
+Description: Samba's log files have moved.
+ Starting with the first packages of Samba 2.2 for Debian the log files for
+ both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The
+ names of the files are log.nmbd and log.smbd, for nmbd and smbd
+ respectively.
+ .
+ The old log files that were in /var/log/ will be moved to the new location
+ for you.
+Description-fr: Les fichiers-journaux de Samba ont changé de place.
+ À partir des premiers paquets de Samba 2.2 pour Debian, les fichiers-journaux
+ des démons nmbd et smbd se trouvent dans /var/log/samba/. Les noms de ces
+ fichiers sont log.nmbd et log.smbd pour, respectivement, nmbd et smbd.
+ .
+ Les anciens fichiers-journaux dans /var/log/ seront mis au bon endroit.
diff --git a/packaging/Debian/debian/samba.templates.pt_BR b/packaging/Debian/debian/samba.templates.pt_BR
new file mode 100755
index 00000000000..597c4a55e35
--- /dev/null
+++ b/packaging/Debian/debian/samba.templates.pt_BR
@@ -0,0 +1,57 @@
+Template: samba/run_mode
+Type: select
+Choices: daemons, inetd
+Choices-pt_BR:
+Default: daemons
+Description: How do you want to run Samba?
+ The Samba services (nmbd and smbd) can run as normal daemons or from
+ inetd. Running as daemons is the recommended approach.
+Description-pt_BR: Como você deseja que o Samba seja executado ?
+ Os serviços Samba (nmbd e smbd) podem ser executados como daemons normais
+ ou a partir do inetd. Executá-los como daemons é o método recomendado.
+
+Template: samba/generate_smbpasswd
+Type: boolean
+Default: false
+Description: Create samba password file, /etc/samba/smbpasswd?
+ To be compatible with the defaults in most versions of Windows, Samba must
+ be configured to use encrypted passwords. This requires user passwords to
+ be stored in a file separate from /etc/passwd. This file can be created
+ automatically, but the passwords must be added manually (by you or the
+ user) by running smbpasswd, and you must arrange to keep it up-to-date in
+ the future. If you do not create it, you will have to reconfigure samba
+ (and probably your client machines) to use plaintext passwords. See
+ See /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html from the
+ samba-doc package for more details.
+Description-pt_BR: Gerar o arquivo de senhas /etc/samba/smbpasswd ?
+ Para compatibilidade com os padrões adotados em todas as versões
+ atuais do Windows o Samba deve ser configurado para usar senhas
+ encriptadas. Isso requer que as senhas dos usuários sejam armazenadas
+ em um arquivo diferente de /etc/passwd. Esse arquivo pode ser criado
+ automaticamente, mas as senhas devem ser definidas manualmente (por
+ você ou pelo usuário) executando-se o utilitário smbpasswd. Você deve
+ certificar-se de manter esse arquivo atualizado futuramente.
+ Caso você não crie esse arquivo, você terá que reconfigurar o
+ Samba (e provavelmente suas máquinas clientes) para utilização de senhas
+ em texto puro. Consulte a documentação em
+ /usr/share/doc/samba-doc/htmldocs/ENCRYPTION.html do pacote samba-doc
+ para maiores detalhes.
+
+Template: samba/log_files_moved
+Type: note
+Description: Samba's log files have moved.
+ Starting with the first packages of Samba 2.2 for Debian the log files for
+ both Samba daemons (nmbd and smbd) are now stored in /var/log/samba/. The
+ names of the files are log.nmbd and log.smbd, for nmbd and smbd
+ respectively.
+ .
+ The old log files that were in /var/log/ will be moved to the new location
+ for you.
+Description-pt_BR: Arquivos de log do Samba foram movidos.
+ Desde os primeiros pacotes Debian do Samba 2.2 os arquivos de log para
+ ambos os daemons Samba (nmbd e smbd) são armazenados no diretório
+ /var/log/samba/. Os nomes desses arquivos são log.nmbd e log.smbd, para
+ o nmbd e para o smbd, respectivamente.
+ .
+ Os antigos arquivos de log que estavam em /var/log/ serão movidos para
+ a nova localização automaticamente para você.
diff --git a/packaging/Debian/debian/scripts/patch-source b/packaging/Debian/debian/scripts/patch-source
index a8559b41676..f514417e5e1 100755
--- a/packaging/Debian/debian/scripts/patch-source
+++ b/packaging/Debian/debian/scripts/patch-source
@@ -3,26 +3,13 @@
#
for patch in debian/patches/*.patch; do
- echo '->'`basename $patch`:
- patch -p1 --ignore-whitespace < $patch
+ patch -p1 < $patch
done
-# This code is currently not used because it creates a long version
-# number string. For now we're sticking to <upstream version>-Debian,
-# as in 3.0.0rc2-Debian. peloy@debian.org.-
-
-# ---- Begin unused code ----
-# Get Debian version number from 1st line of the Debian changelog
-#DEBIAN_VERSION=`sed -n -e '1s/^.*(\(.*\)).*$/\1/p' debian/changelog`
-
-# Insert Debian version number in source/VERSION, which will then be
-# used to create source/include/version.h.
-#TMPFILE=source/VERSION.debian
-#sed -e "s/^\(SAMBA_VERSION_VENDOR_SUFFIX=\).*$/\1\"Debian-${DEBIAN_VERSION}\"/" source/VERSION > ${TMPFILE}
-#mv -f ${TMPFILE} source/VERSION
-# ---- End unused code ----
+cat debian/changelog | perl -pi -e '($version) = <STDIN> =~/\((.*)\)/; \
+ s/\".*\"/\"$version for Debian\"/' source/include/version.h
# Regenerate configure only if it is older than configure.in
-[ source/configure -ot source/configure.in ] && (cd source && sh ./autogen.sh)
+[ source/configure -ot source/configure.in ] && (cd source && autoconf)
exit 0
diff --git a/packaging/Debian/debian/scripts/unpatch-source b/packaging/Debian/debian/scripts/unpatch-source
index d3681cfa504..057ae43c3b4 100755
--- a/packaging/Debian/debian/scripts/unpatch-source
+++ b/packaging/Debian/debian/scripts/unpatch-source
@@ -5,16 +5,12 @@
# We want to reverse the patches in the opposite order we applied
# them, hence the 'ls|sort -r'.
for patch in `ls debian/patches/*.patch | sort -r`; do
- patch -p1 -R --ignore-whitespace < $patch
+ patch -p1 -R < $patch
done
-# Unused code. See comment in the patch-source script.
-
-#TMPFILE=source/VERSION.debian
-#sed -e "s/^\(SAMBA_VERSION_VENDOR_SUFFIX=\).*$/\1/" source/VERSION > ${TMPFILE}
-#mv -f ${TMPFILE} source/VERSION
+perl -pi -e's/-.* for Debian//' source/include/version.h
# Regenerate configure only if it is older than configure.in
-[ source/configure -ot source/configure.in ] && (cd source && autoheader && autoconf)
+[ source/configure -ot source/configure.in ] && (cd source && autoconf)
exit 0
diff --git a/packaging/Debian/debian/smb.conf b/packaging/Debian/debian/smb.conf
index 8a75979945a..e9fc0607ace 100644
--- a/packaging/Debian/debian/smb.conf
+++ b/packaging/Debian/debian/smb.conf
@@ -21,31 +21,24 @@
[global]
-## Browsing/Identification ###
-
-# Change this to the workgroup/NT-domain name your Samba server will part of
+# Change this for the workgroup/NT-domain name your Samba server will part of
workgroup = DEBIAN_FANS
# server string is the equivalent of the NT Description field
server string = %h server (Samba %v)
-# Windows Internet Name Serving Support Section:
-# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
-; wins support = no
-
-# WINS Server - Tells the NMBD components of Samba to be a WINS Client
-# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
-; wins server = w.x.y.z
-
-# This will prevent nmbd to search for NetBIOS names through DNS.
- dns proxy = no
+# If you want to automatically load your printer list rather
+# than setting them up individually then you'll need this
+; load printers = yes
-# What naming service and in what order should we use to resolve host names
-# to IP addresses
-; name resolve order = lmhosts host wins bcast
+# You may wish to override the location of the printcap file
+; printcap name = /etc/printcap
+# 'printing = cups' works nicely
+; printing = bsd
-#### Debugging/Accounting ####
+; guest account = nobody
+ invalid users = root
# This tells Samba to use a separate log file for each machine
# that connects
@@ -54,114 +47,109 @@
# Put a capping on the size of the log files (in Kb).
max log size = 1000
-# If you want Samba to only log through syslog then set the following
-# parameter to 'yes'.
+# If you want Samba to log though syslog only then set the following
+# parameter to 'yes'. Please note that logging through syslog in
+# Samba is still experimental.
; syslog only = no
# We want Samba to log a minimum amount of information to syslog. Everything
-# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
+# should go to /var/log/samba/log.{smb,nmb} instead. If you want to log
# through syslog you should set the following parameter to something higher.
syslog = 0
-# Do something sensible when Samba crashes: mail the admin a backtrace
- panic action = /usr/share/samba/panic-action %d
-
-
-####### Authentication #######
-
# "security = user" is always a good idea. This will require a Unix account
# in this server for every user accessing the server. See
-# /usr/share/doc/samba-doc/htmldocs/ServerType.html in the samba-doc
-# package for details.
+# security_level.txt for details.
; security = user
-# You may wish to use password encryption. See the section on
-# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
+# You may wish to use password encryption. Please read ENCRYPTION.txt,
+# Win95.txt and WinNT.txt in the Samba documentation. Do not enable this
+# option unless you have read those documents
encrypt passwords = no
-# If you are using encrypted passwords, Samba will need to know what
-# password database type you are using.
- passdb backend = tdbsam guest
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+; include = /home/samba/etc/smb.conf.%m
- obey pam restrictions = yes
+# Most people will find that this option gives better performance.
+# See speed.txt and the manual pages for details
+# You may want to add the following on a Linux system:
+# SO_RCVBUF=8192 SO_SNDBUF=8192
+ socket options = TCP_NODELAY
-; guest account = nobody
- invalid users = root
+# --- Browser Control Options ---
-# This boolean parameter controls whether Samba attempts to sync the Unix
-# password with the SMB password when the encrypted SMB password in the
-# passdb is changed.
-; unix password sync = no
+# Please _read_ BROWSING.txt and set the next four parameters according
+# to your network setup. The defaults are specified below (commented
+# out.) It's important that you read BROWSING.txt so you don't break
+# browsing in your network!
-# For Unix password sync to work on a Debian GNU/Linux system, the following
-# parameters must be set (thanks to Augustin Luton <aluton@hybrigenics.fr> for
-# sending the correct chat script for the passwd program in Debian Potato).
- passwd program = /usr/bin/passwd %u
- passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n .
-
-# This boolean controls whether PAM will be used for password changes
-# when requested by an SMB client instead of the program listed in
-# 'passwd program'. The default is 'no'.
-; pam password change = no
+# set local master to no if you don't want Samba to become a master
+# browser on your network. Otherwise the normal election rules apply
+; local master = yes
+# OS Level determines the precedence of this server in master browser
+# elections. The default value should be reasonable
+; os level = 20
-########## Printing ##########
+# Domain Master specifies Samba to be the Domain Master Browser. This
+# allows Samba to collate browse lists between subnets. Don't use this
+# if you already have a Windows NT domain controller doing this job
+; domain master = auto
-# If you want to automatically load your printer list rather
-# than setting them up individually then you'll need this
-; load printers = yes
+# Preferred Master causes Samba to force a local browser election on startup
+# and gives it a slightly higher chance of winning the election
+; preferred master = auto
-# lpr(ng) printing. You may wish to override the location of the
-# printcap file
-; printing = bsd
-; printcap name = /etc/printcap
+# --- End of Browser Control Options ---
-# CUPS printing. See also the cupsaddsmb(8) manpage in the
-# cupsys-client package.
-; printing = cups
-; printcap name = cups
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = no
-# When using [print$], root is implicitly a 'printer admin', but you can
-# also give this right to other users to add drivers and set printer
-# properties
-; printer admin = @ntadmin
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = w.x.y.z
+# This will prevent nmbd to search for NetBIOS names through DNS.
+ dns proxy = no
-######## File sharing ########
+# What naming service and in what order should we use to resolve host names
+# to IP addresses
+; name resolve order = lmhosts host wins bcast
# Name mangling options
; preserve case = yes
; short preserve case = yes
+# This boolean parameter controlls whether Samba attempts to sync. the Unix
+# password with the SMB password when the encrypted SMB password in the
+# /etc/samba/smbpasswd file is changed.
+; unix password sync = false
-############ Misc ############
-
-# Using the following line enables you to customise your configuration
-# on a per machine basis. The %m gets replaced with the netbios name
-# of the machine that is connecting
-; include = /home/samba/etc/smb.conf.%m
+# For Unix password sync. to work on a Debian GNU/Linux system, the following
+# parameters must be set (thanks to Augustin Luton <aluton@hybrigenics.fr> for
+# sending the correct chat script for the passwd program in Debian Potato).
+ passwd program = /usr/bin/passwd %u
+ passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n .
-# Most people will find that this option gives better performance.
-# See smb.conf(5) and /usr/share/doc/samba-doc/htmldocs/speed.html
-# for details
-# You may want to add the following on a Linux system:
-# SO_RCVBUF=8192 SO_SNDBUF=8192
- socket options = TCP_NODELAY
+# This boolean controls whether PAM will be used for password changes
+# when requested by an SMB client instead of the program listed in
+# 'passwd program'. The default is 'no'.
+; pam password change = no
# The following parameter is useful only if you have the linpopup package
# installed. The samba maintainer and the linpopup maintainer are
# working to ease installation and configuration of linpopup and samba.
; message command = /bin/sh -c '/usr/bin/linpopup "%f" "%m" %s; rm %s' &
-# Domain Master specifies Samba to be the Domain Master Browser. If this
-# machine will be configured as a BDC (a secondary logon server), you
-# must set this to 'no'; otherwise, the default behavior is recommended.
-; domain master = auto
+ obey pam restrictions = yes
# Some defaults for winbind (make sure you're not using the ranges
# for something else.)
-; idmap uid = 10000-20000
-; idmap gid = 10000-20000
+; winbind uid = 10000-20000
+; winbind gid = 10000-20000
; template shell = /bin/bash
#======================= Share Definitions =======================
@@ -200,19 +188,6 @@
writable = no
create mode = 0700
-# Windows clients look for this share name as a source of downloadable
-# printer drivers
-[print$]
- comment = Printer Drivers
- path = /var/lib/samba/printers
- browseable = yes
- read only = yes
- guest ok = no
-# Uncomment to allow remote administration of Windows print drivers.
-# Replace 'ntadmin' with the name of the group your admin users are
-# members of.
-; write list = root, @ntadmin
-
# A sample share for sharing your CD-ROM with others.
;[cdrom]
; comment = Samba server's CD-ROM
diff --git a/packaging/Debian/debian/smbclient.files b/packaging/Debian/debian/smbclient.files
index 96e8945bf3d..5a660fc8d4e 100644
--- a/packaging/Debian/debian/smbclient.files
+++ b/packaging/Debian/debian/smbclient.files
@@ -2,14 +2,8 @@ usr/bin/smbclient
usr/bin/smbtar
usr/bin/rpcclient
usr/bin/smbspool
-usr/bin/smbtree
-usr/bin/smbcacls
-usr/bin/smbcquotas
usr/share/man/man1/smbclient.1
usr/share/man/man1/smbtar.1
usr/share/man/man1/rpcclient.1
usr/share/man/man8/smbspool.8
-usr/share/man/man1/smbcacls.1
-usr/share/man/man1/smbcquotas.1
-usr/share/man/man1/smbtree.1
usr/lib/cups/backend/smb
diff --git a/packaging/Debian/debian/swat.config b/packaging/Debian/debian/swat.config
deleted file mode 100644
index e210fae55ea..00000000000
--- a/packaging/Debian/debian/swat.config
+++ /dev/null
@@ -1,11 +0,0 @@
-#/bin/sh -e
-#
-#
-
-# Source debconf library.
-. /usr/share/debconf/confmodule
-
-db_title "Samba Web Administration Tool (SWAT)"
-
-db_input medium swat/smb_conf_warn || true
-db_go
diff --git a/packaging/Debian/debian/swat.docs b/packaging/Debian/debian/swat.docs
new file mode 100755
index 00000000000..afbfcf0c612
--- /dev/null
+++ b/packaging/Debian/debian/swat.docs
@@ -0,0 +1 @@
+swat/README
diff --git a/packaging/Debian/debian/swat.templates b/packaging/Debian/debian/swat.templates
deleted file mode 100644
index 3407f7efbc1..00000000000
--- a/packaging/Debian/debian/swat.templates
+++ /dev/null
@@ -1,6 +0,0 @@
-Template: swat/smb_conf_warn
-Type: note
-_Description: Your smb.conf will be re-written!
- SWAT will rewrite your smb.conf file. It will rearrange the entries and
- delete all comments, include= and copy= options. If you have a carefully
- crafted smb.conf then back it up or don't use SWAT!
diff --git a/packaging/Debian/debian/winbind.conffiles b/packaging/Debian/debian/winbind.conffiles
new file mode 100755
index 00000000000..c9adbfff174
--- /dev/null
+++ b/packaging/Debian/debian/winbind.conffiles
@@ -0,0 +1,2 @@
+/etc/init.d/winbind
+/etc/logrotate.d/winbind
diff --git a/packaging/Debian/debian/winbind.dirs b/packaging/Debian/debian/winbind.dirs
deleted file mode 100644
index 1da8fba83ad..00000000000
--- a/packaging/Debian/debian/winbind.dirs
+++ /dev/null
@@ -1 +0,0 @@
-usr/share/lintian/overrides
diff --git a/packaging/Debian/debian/winbind.files b/packaging/Debian/debian/winbind.files
index 2834acf7caf..9730900e7e9 100644
--- a/packaging/Debian/debian/winbind.files
+++ b/packaging/Debian/debian/winbind.files
@@ -4,4 +4,4 @@ usr/share/man/man1/wbinfo.1
usr/share/man/man8/winbindd.8
lib/security/pam_winbind.so
lib/libnss_winbind.so.2
-lib/libnss_wins.so.2
+lib/libnss_wins.so
diff --git a/packaging/Debian/debian/winbind.lintian b/packaging/Debian/debian/winbind.lintian
deleted file mode 100644
index fca17d3cca1..00000000000
--- a/packaging/Debian/debian/winbind.lintian
+++ /dev/null
@@ -1,6 +0,0 @@
-winbind: ldconfig-symlink-missing-for-shlib lib/libnss_winbind.so lib/libnss_winbind.so.2 libnss_winbind.so
-winbind: ldconfig-symlink-missing-for-shlib lib/libnss_wins.so lib/libnss_wins.so.2 libnss_wins.so
-winbind: no-shlibs-control-file lib/libnss_winbind.so.2
-winbind: no-shlibs-control-file lib/libnss_wins.so.2
-winbind: postinst-must-call-ldconfig lib/libnss_wins.so.2
-winbind: postrm-should-call-ldconfig lib/libnss_wins.so.2
diff --git a/packaging/Debian/debian/winbind.logrotate b/packaging/Debian/debian/winbind.logrotate
index e36cd1281c5..7300885eb12 100644
--- a/packaging/Debian/debian/winbind.logrotate
+++ b/packaging/Debian/debian/winbind.logrotate
@@ -3,7 +3,7 @@
missingok
rotate 7
postrotate
- [ -f /var/run/samba/winbindd.pid ] && kill -HUP `cat /var/run/samba/winbindd.pid`
+ killall -q -HUP winbindd || true
endscript
compress
notifempty
diff --git a/packaging/Digital/Instructions b/packaging/Digital/Instructions
new file mode 100755
index 00000000000..f764ad350dd
--- /dev/null
+++ b/packaging/Digital/Instructions
@@ -0,0 +1,55 @@
+Copyright (C) 1997-1998 John H Terpstra
+E-mail: jht@samba.org
+
+Subject: Installation Instructions for Digital Unix v4.0
+--------------------------------------------------------
+
+1) cd /
+2) tar xvf [path-to-]/install.tar
+3) cd /usr/local/samba/lib
+4) vi smb.conf
+
+Now modify smb.conf to reflect your site needs.
+
+5) samba start
+
+To stop samba:
+
+ samba stop
+
+You could install samba to run from the system start-up scripts
+(recommended) by running ./setup.sh
+
+Start / Stop Samba as follows:-
+
+ samba [start | stop]
+
+
+Subject: Encrypted password support
+-----------------------------------
+
+Encrypted password support is quite distinct from Digital Enhanced
+Security Mode operation of the Unix system. Encrypted passwords
+applies to the SMB connections serviced by this machine, not to
+local user logons. Local user logons are services by the security
+system chosen by your system administrator.
+
+Digital Unix knows of either BASIC or ENHANCED security mode
+operation. BASIC mode uses the traditional /etc/passwd database
+containing Unix crypted passwords. ENHANCED mode uses a TCB database.
+Samba-1.9.18p10 has been modified so that if OSF1_ENH_SEC is defined
+at compile time then a password check will be made first using ENHANCED
+mode and if that fails then it will try BASIC mode. This is the case
+for this binary distribution - you need not recompile. In other
+words: this binary distribution will work with either security mode.
+
+To enable SMB encrypted password support do the following:
+
+1) Put /usr/local/samba/bin in your PATH
+2) Edit /usr/local/samba/lib/smb.conf and uncomment the
+ line "encrypt passwd = yes"
+3) Execute: smbpasswd -a "username" "password"
+
+The above will create your /usr/local/samba/private/smbpasswd file
+in which will be the NT and LanMAN hashed passwords.
+
diff --git a/packaging/Digital/PackageDate b/packaging/Digital/PackageDate
new file mode 100755
index 00000000000..360e4148aa0
--- /dev/null
+++ b/packaging/Digital/PackageDate
@@ -0,0 +1 @@
+November 14, 1998, Australia/Sydney
diff --git a/packaging/Digital/Packager b/packaging/Digital/Packager
new file mode 100755
index 00000000000..75252978dc1
--- /dev/null
+++ b/packaging/Digital/Packager
@@ -0,0 +1,2 @@
+Date: November 14, 1998
+Packager: John H Terpstra <jht@samba.org>
diff --git a/packaging/Digital/Packaging-instructions b/packaging/Digital/Packaging-instructions
new file mode 100755
index 00000000000..77eafd312f5
--- /dev/null
+++ b/packaging/Digital/Packaging-instructions
@@ -0,0 +1,14 @@
+The package building files should be located in a directory
+called: samba-2.0.0
+
+Step Directions
+==== ============================================
+1. Copy the samba distribution tarball into the packaging directory
+2. Make sure you have a installed on your system the GNU gzip/gunzip files
+3. Edit "package-prep" script as required
+4. Run "package-prep"
+
+If all goes well, you should now have a usable distribution package.
+
+Note: Update the Instructions file as required.
+
diff --git a/packaging/Digital/package-prep b/packaging/Digital/package-prep
new file mode 100755
index 00000000000..2daee8b69ef
--- /dev/null
+++ b/packaging/Digital/package-prep
@@ -0,0 +1,30 @@
+tar xvf skeleton.tar
+NOWDIR=`pwd`;
+( cd /usr/local;
+ if [ -x man ]; then mv man man.orig; fi
+ if [ -x samba ]; then mv samba samba.orig; fi
+ ln -sf $NOWDIR/usr/local/man man;
+ ln -sf $NOWDIR/usr/local/samba samba; )
+gunzip samba-2.0.0.tar.gz
+tar xvf samba-2.0.0.tar
+cd samba-2.0.0/source
+./configure
+make
+make install
+cd $NOWDIR/usr/local/samba
+cp -pr man ../
+rm -rf man
+cd $NOWDIR
+tar cvf install.tar usr var
+cd samba-2.0.0/source
+rm -f ../source/bin/*
+make clean
+cd ../..
+tar cvf samba-2.0.0.tar samba-2.0.0
+rm -rf samba-2.0.0
+rm -rf usr var
+cd ..
+find samba-2.0.0 -print | cpio -o > samba-2.0.0-OSF1-v4.0-beta5.cpio
+gzip samba-2.0.0-OSF1-v4.0-beta5.cpio
+cd samba-2.0.0
+tar xvf install.tar
diff --git a/packaging/Digital/samba.init b/packaging/Digital/samba.init
new file mode 100755
index 00000000000..6a742440890
--- /dev/null
+++ b/packaging/Digital/samba.init
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+if [ ! -d /usr/bin ]; then
+ echo "The /usr file system is not mounted."
+ exit 1
+fi
+
+killproc() {
+ pid=`/bin/ps ax | grep -w $1 | sed -e 's/^ *//' -e 's/ .*//'`
+ echo "Stopping $1 now."
+ [ "$pid" != "" ] && kill -15 $pid
+ echo $pid
+}
+
+
+# Start/stop processes required for samba server
+
+case "$1" in
+
+ 'start')
+ echo "Starting Samba"
+ /usr/local/samba/bin/smbd
+ /usr/local/samba/bin/nmbd
+ echo "Done."
+ ;;
+ 'stop')
+ killproc smbd
+ killproc nmbd
+ ;;
+ *)
+ echo "Usage: /sbin/init.d/samba.init [ start | stop ]"
+ ;;
+esac
+exit 0
diff --git a/packaging/Digital/setup.sh b/packaging/Digital/setup.sh
new file mode 100755
index 00000000000..81b04878bb1
--- /dev/null
+++ b/packaging/Digital/setup.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+echo "Setting up for SWAT - The Samba Web Administration Tool"
+
+echo 'swat 901/tcp' >> /etc/services
+uniq /etc/services /tmp/tempserv
+cp /tmp/tempserv /etc/services
+rm /tmp/tempserv
+echo 'swat stream tcp nowait.400 root /usr/local/samba/bin/swat swat' >> /etc/inetd.conf
+uniq /etc/inetd.conf /tmp/tempinetd
+cp /tmp/tempinetd /etc/inetd.conf
+rm /tmp/tempinetd
+echo "Creating Symbolic Links for Start up Scripts"
+cp -f samba.init /sbin/init.d
+chown bin.bin /sbin/init.d/samba.init
+chmod 750 /sbin/init.d/samba.init
+ln -sf /sbin/init.d/samba.init /sbin/rc0.d/K01samba
+ln -sf /sbin/init.d/samba.init /sbin/rc2.d/K91samba
+ln -sf /sbin/init.d/samba.init /sbin/rc3.d/S91samba
+echo "Done. Now settting up samba command"
+ln /sbin/init.d/samba.init /sbin/samba
+echo "Done."
+echo "To start / stop samba:"
+echo " execute: samba [start | stop]
diff --git a/packaging/Digital/skeleton.tar b/packaging/Digital/skeleton.tar
new file mode 100755
index 00000000000..92598d0c5e7
--- /dev/null
+++ b/packaging/Digital/skeleton.tar
Binary files differ
diff --git a/packaging/Example/samba.init b/packaging/Example/samba.init
index c1d605cda06..4f02cd8a1af 100755
--- a/packaging/Example/samba.init
+++ b/packaging/Example/samba.init
@@ -1,5 +1,8 @@
#!/bin/sh
#
+SMBD=/usr/local/samba/bin/smbd
+NMBD=/usr/local/samba/bin/nmbd
+
if [ ! -d /usr/bin ]; then
echo "The /usr file system is not mounted."
exit 1
@@ -19,8 +22,8 @@ case "$1" in
'start')
echo "Starting Samba"
- /usr/local/samba/sbin/smbd
- /usr/local/samba/sbin/nmbd
+ $SMBD
+ $NMBD
echo "Done."
;;
'stop')
diff --git a/packaging/Fedora/filter-requires-samba.sh b/packaging/Fedora/filter-requires-samba.sh
deleted file mode 100755
index 1ba10a0ee3d..00000000000
--- a/packaging/Fedora/filter-requires-samba.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-/usr/lib/rpm/perl.req $* | grep -v "Net::LDAP"
diff --git a/packaging/Fedora/makerpms.sh.tmpl b/packaging/Fedora/makerpms.sh.tmpl
deleted file mode 100644
index 361d8418761..00000000000
--- a/packaging/Fedora/makerpms.sh.tmpl
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-# Copyright (C) John H Terpstra 1998-2002
-# Gerald (Jerry) Carter 2003
-
-# The following allows environment variables to override the target directories
-# the alternative is to have a file in your home directory calles .rpmmacros
-# containing the following:
-# %_topdir /home/mylogin/redhat
-#
-# Note: Under this directory rpm expects to find the same directories that are under the
-# /usr/src/redhat directory
-#
-
-SPECDIR=`rpm --eval %_specdir`
-SRCDIR=`rpm --eval %_sourcedir`
-
-# At this point the SPECDIR and SRCDIR vaiables must have a value!
-
-USERID=`id -u`
-GRPID=`id -g`
-VERSION='PVERSION'
-SPECFILE="samba.spec"
-RPMVER=`rpm --version | awk '{print $3}'`
-RPM="rpmbuild"
-
-##
-## Check the RPM version (paranoid)
-##
-case $RPMVER in
- 4*)
- echo "Supported RPM version [$RPMVER]"
- ;;
- *)
- echo "Unknown RPM version: `rpm --version`"
- exit 1
- ;;
-esac
-
-( cd ../../source; if [ -f Makefile ]; then make distclean; fi )
-( cd ../../.. ; chown -R ${USERID}.${GRPID} samba-${VERSION} )
-
-( cd ../../.. ; tar --exclude=CVS -cf - samba-${VERSION}/. | bzip2 > ${SRCDIR}/samba-${VERSION}.tar.bz2 )
-
-##
-## copy additional source files
-##
-for file in samba.pamd samba.sysconfig samba.spec \
- smb.init swat.desktop filter-requires-samba.sh \
- samba.log samba.xinetd smbprint winbind.init \
- smb.conf smbusers
-do
- cp -p $file ${SRCDIR}
-
-done
-
-chmod 755 ${SRCDIR}/filter-requires-samba.sh
-
-cp -p ${SPECFILE} ${SPECDIR}
-
-##
-## Build
-##
-echo Getting Ready to build release package
-cd ${SPECDIR}
-${RPM} -ba --clean --rmsource $SPECFILE
-
-echo Done.
-
diff --git a/packaging/Fedora/samba.log b/packaging/Fedora/samba.log
deleted file mode 100644
index 04106239fb1..00000000000
--- a/packaging/Fedora/samba.log
+++ /dev/null
@@ -1,9 +0,0 @@
-/var/log/samba/*.log {
- notifempty
- missingok
- sharedscripts
- copytruncate
- postrotate
- /bin/kill -HUP `cat /var/run/smbd.pid /var/run/nmbd.pid /var/run/winbindd.pid 2> /dev/null` 2> /dev/null || true
- endscript
-}
diff --git a/packaging/Fedora/samba.pamd b/packaging/Fedora/samba.pamd
deleted file mode 100644
index f88aae628c2..00000000000
--- a/packaging/Fedora/samba.pamd
+++ /dev/null
@@ -1,4 +0,0 @@
-auth required /lib/security/pam_stack.so service=system-auth
-session required /lib/security/pam_stack.so service=system-auth
-account required /lib/security/pam_stack.so service=system-auth
-password required /lib/security/pam_stack.so service=system-auth
diff --git a/packaging/Fedora/samba.spec.tmpl b/packaging/Fedora/samba.spec.tmpl
deleted file mode 100644
index dde2fc7af3e..00000000000
--- a/packaging/Fedora/samba.spec.tmpl
+++ /dev/null
@@ -1,398 +0,0 @@
-%define initdir %{_sysconfdir}/rc.d/init.d
-%define auth %(test -f /etc/pam.d/system-auth && echo /etc/pam.d/system-auth || echo)
-
-Summary: The Samba SMB server.
-Name: samba
-Version: PVERSION
-Release: PRELEASE
-License: GNU GPL Version 2
-Group: System Environment/Daemons
-URL: http://www.samba.org/
-
-Source: ftp://www.samba.org/pub/samba/%{name}-%{version}.tar.bz2
-
-# Red Hat specific replacement-files
-Source1: samba.log
-Source2: samba.xinetd
-Source4: samba.sysconfig
-Source5: smb.init
-Source6: winbind.init
-Source7: samba.pamd
-Source8: smbprint
-Source9: smbusers
-Source10: smb.conf
-
-# Don't depend on Net::LDAP
-Source999: filter-requires-samba.sh
-
-# generic patches
-
-Requires: pam >= 0.64 %{auth} samba-common = %{version}
-Requires: logrotate >= 3.4 initscripts >= 5.54-1
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-Prereq: /sbin/chkconfig /bin/mktemp /usr/bin/killall
-Prereq: fileutils sed /etc/init.d
-BuildRequires: pam-devel, readline-devel, ncurses-devel, fileutils, libacl-devel, openldap-devel, krb5-devel
-
-
-# Working around perl dependency problem from docs
-%define __perl_requires %{SOURCE999}
-
-%description
-Samba is the protocol by which a lot of PC-related machines share
-files, printers, and other information (such as lists of available
-files and printers). The Windows NT, OS/2, and Linux operating systems
-support this natively, and add-on packages can enable the same thing
-for DOS, Windows, VMS, UNIX of all kinds, MVS, and more. This package
-provides an SMB server that can be used to provide network services to
-SMB (sometimes called "Lan Manager") clients. Samba uses NetBIOS over
-TCP/IP (NetBT) protocols and does NOT need the NetBEUI (Microsoft Raw
-NetBIOS frame) protocol.
-
-%package client
-Summary: Samba (SMB) client programs.
-Group: Applications/System
-Requires: samba-common = %{version}
-Obsoletes: smbfs
-
-%description client
-The samba-client package provides some SMB clients to compliment the
-built-in SMB filesystem in Linux. These clients allow access of SMB
-shares and printing to SMB printers.
-
-%package common
-Summary: Files used by both Samba servers and clients.
-Group: Applications/System
-
-%description common
-Samba-common provides files necessary for both the server and client
-packages of Samba.
-
-%package swat
-Summary: The Samba SMB server configuration program.
-Group: Applications/System
-Requires: samba = %{version} xinetd
-
-%description swat
-The samba-swat package includes the new SWAT (Samba Web Administration
-Tool), for remotely managing Samba's smb.conf file using your favorite
-Web browser.
-
-%prep
-%setup -q
-
-# copy Red Hat specific scripts
-cp %{SOURCE5} packaging/Fedora/
-cp %{SOURCE6} packaging/Fedora/
-cp %{SOURCE7} packaging/Fedora/
-cp %{SOURCE8} packaging/Fedora/winbind.init
-
-%build
-
-cd source
-%ifarch i386 sparc
-RPM_OPT_FLAGS="$RPM_OPT_FLAGS -D_FILE_OFFSET_BITS=64"
-%endif
-%ifarch ia64
-libtoolize --copy --force # get it to recognize IA-64
-autoheader
-autoconf
-EXTRA="-D_LARGEFILE64_SOURCE"
-%endif
-
-## run autogen if missing the configure script
-if [ ! -f "configure" ]; then
- ./autogen.sh
-fi
-
-CFLAGS="$RPM_OPT_FLAGS" ./configure \
- --prefix=%{_prefix} \
- --localstatedir=/var \
- --sysconfdir=/etc \
- --with-privatedir=%{_sysconfdir}/samba \
- --with-fhs \
- --with-quotas \
- --with-smbmount \
- --with-pam \
- --with-pam_smbpass \
- --with-syslog \
- --with-utmp \
- --with-sambabook=%{_datadir}/swat/using_samba \
- --with-swatdir=%{_datadir}/swat \
- --with-libsmbclient \
- --with-acl-support
-make showlayout
-make proto
-make %{?_smp_mflags} all nsswitch/libnss_wins.so debug2html
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-mkdir -p $RPM_BUILD_ROOT/sbin
-mkdir -p $RPM_BUILD_ROOT/usr/{sbin,bin}
-mkdir -p $RPM_BUILD_ROOT/%{initdir}
-mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/{pam.d,logrotate.d}
-mkdir -p $RPM_BUILD_ROOT/var/{log,spool,lib}/samba
-mkdir -p $RPM_BUILD_ROOT/%{_datadir}/swat/using_samba
-mkdir -p $RPM_BUILD_ROOT/%{_datadir}/samba/codepages
-
-cd source
-
-make DESTDIR=$RPM_BUILD_ROOT \
- install
-
-cd ..
-
-# Install other stuff
-install -m644 %{SOURCE10} $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf
-install -m644 %{SOURCE8} $RPM_BUILD_ROOT/etc/samba/smbusers
-install -m755 %{SOURCE8} $RPM_BUILD_ROOT%{_bindir}
-install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/pam.d/samba
-install -m644 %{SOURCE1} $RPM_BUILD_ROOT/etc/logrotate.d/samba
-install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir}
-
-install -m755 %{SOURCE5} $RPM_BUILD_ROOT%{initdir}/smb
-install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{initdir}/winbind
-ln -s ../..%{initdir}/smb $RPM_BUILD_ROOT%{_sbindir}/samba
-ln -s ../..%{initdir}/winbind $RPM_BUILD_ROOT%{_sbindir}/winbind
-
-ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
-## Samba's Makefile is breaking this currently. Remove it and set our own
-/bin/rm -f $RPM_BUILD_ROOT/sbin/mount.smbfs
-ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
-
-echo 127.0.0.1 localhost > $RPM_BUILD_ROOT%{_sysconfdir}/samba/lmhosts
-
-
-# pam_smbpass
-mkdir -p $RPM_BUILD_ROOT/%{_lib}/security
-mv source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass.so
-
-# winbind
-mkdir -p $RPM_BUILD_ROOT/%{_lib}/security
-install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so
-install -m 755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/%{_lib}/libnss_winbind.so
-install -m 755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/%{_lib}/libnss_wins.so
-( cd $RPM_BUILD_ROOT/%{_lib};
- ln -sf libnss_winbind.so libnss_winbind.so.2;
- ln -sf libnss_wins.so libnss_wins.so.2 )
-
-# libsmbclient
-
-# make install puts libsmbclient.so in the wrong place on x86_64
-rm -f $RPM_BUILD_ROOT/usr/lib || true
-mkdir -p $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT%{_includedir}
-install -m 755 source/bin/libsmbclient.so $RPM_BUILD_ROOT%{_libdir}/libsmbclient.so
-install -m 644 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{_libdir}/libsmbclient.a
-install -m 644 source/include/libsmbclient.h $RPM_BUILD_ROOT%{_includedir}
-
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d
-install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/swat
-
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig
-install -m644 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/samba
-
-##
-## Clean out man pages for tools not installed here
-##
-rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/editreg.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbget.1*
-rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8*
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%post
-/sbin/chkconfig --add smb
-
-%preun
-if [ $1 = 0 ] ; then
- /sbin/chkconfig --del smb
- rm -rf /var/log/samba/* /var/cache/samba/*
- /sbin/service smb stop >/dev/null 2>&1
-fi
-exit 0
-
-%postun
-if [ "$1" -ge "1" ]; then
- %{initdir}/smb condrestart >/dev/null 2>&1
-fi
-
-
-%post swat
-# Add swat entry to /etc/services if not already there.
-if [ ! "`grep ^\s**swat /etc/services`" ]; then
- echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
-fi
-
-%post common
-/sbin/chkconfig --add winbind
-/sbin/ldconfig
-
-%preun common
-if [ $1 = 0 ] ; then
- /sbin/chkconfig --del winbind
- /sbin/service winbind stop >/dev/null 2>&1
-fi
-exit 0
-
-%postun common -p /sbin/ldconfig
-
-%triggerpostun -- samba < 1.9.18p7
-if [ $1 != 0 ]; then
- /sbin/chkconfig --add smb
-fi
-
-%triggerpostun -- samba < 2.0.5a-3
-if [ $1 != 0 ]; then
- [ ! -d /var/lock/samba ] && mkdir -m 0755 /var/lock/samba
- [ ! -d /var/spool/samba ] && mkdir -m 1777 /var/spool/samba
- chmod 644 /etc/services
- [ -f /etc/inetd.conf ] && chmod 644 /etc/inetd.conf
-fi
-
-%files
-%defattr(-,root,root)
-%doc README COPYING Manifest
-%doc WHATSNEW.txt Roadmap
-%doc docs
-%doc examples/autofs examples/LDAP examples/libsmbclient examples/misc examples/printer-accounting
-%doc examples/printing
-
-%attr(755,root,root) /%{_lib}/security/pam_smbpass.so
-%{_sbindir}/smbd
-%{_sbindir}/nmbd
-# %{_bindir}/make_unicodemap
-%{_bindir}/mksmbpasswd.sh
-%{_bindir}/smbcontrol
-%{_bindir}/smbstatus
-# %{_bindir}/smbadduser
-%{_bindir}/tdbbackup
-%config(noreplace) %{_sysconfdir}/sysconfig/samba
-%config(noreplace) %{_sysconfdir}/samba/smbusers
-%attr(755,root,root) %config %{initdir}/smb
-%config(noreplace) %{_sysconfdir}/logrotate.d/samba
-%config(noreplace) %{_sysconfdir}/pam.d/samba
-# %{_mandir}/man1/make_unicodemap.1*
-%{_mandir}/man1/smbcontrol.1*
-%{_mandir}/man1/smbstatus.1*
-%{_mandir}/man5/smbpasswd.5*
-%{_mandir}/man7/samba.7*
-%{_mandir}/man8/nmbd.8*
-%{_mandir}/man8/pdbedit.8*
-%{_mandir}/man8/smbd.8*
-%{_mandir}/man8/tdbbackup.8*
-#%{_mandir}/ja/man1/smbstatus.1*
-#%{_mandir}/ja/man5/smbpasswd.5*
-#%{_mandir}/ja/man7/samba.7*
-#%{_mandir}/ja/man8/smbd.8*
-#%{_mandir}/ja/man8/nmbd.8*
-%{_libdir}/samba/vfs
-
-%attr(0700,root,root) %dir /var/log/samba
-%attr(1777,root,root) %dir /var/spool/samba
-
-%files swat
-%defattr(-,root,root)
-%config(noreplace) %{_sysconfdir}/xinetd.d/swat
-%{_datadir}/swat
-%{_sbindir}/swat
-%{_mandir}/man8/swat.8*
-#%{_mandir}/ja/man8/swat.8*
-%attr(755,root,root) %{_libdir}/samba/*.msg
-
-%files client
-%defattr(-,root,root)
-/sbin/mount.smb
-/sbin/mount.smbfs
-%{_libdir}/samba/lowcase.dat
-%{_libdir}/samba/upcase.dat
-%{_libdir}/samba/valid.dat
-%{_bindir}/rpcclient
-%{_bindir}/smbcacls
-%{_bindir}/smbmount
-%{_bindir}/smbmnt
-%{_bindir}/smbumount
-%{_bindir}/findsmb
-%{_bindir}/tdbdump
-%{_mandir}/man8/tdbdump.8*
-%{_mandir}/man8/smbmnt.8*
-%{_mandir}/man8/smbmount.8*
-%{_mandir}/man8/smbumount.8*
-%{_mandir}/man8/smbspool.8*
-%{_bindir}/nmblookup
-%{_bindir}/smbclient
-%{_bindir}/smbprint
-%{_bindir}/smbspool
-%{_bindir}/smbtar
-%{_bindir}/net
-%{_bindir}/smbtree
-%{_mandir}/man1/findsmb.1*
-%{_mandir}/man1/nmblookup.1*
-%{_mandir}/man1/rpcclient.1*
-%{_mandir}/man1/smbcacls.1*
-%{_mandir}/man1/smbclient.1*
-%{_mandir}/man1/smbtar.1*
-%{_mandir}/man1/smbtree.1*
-%{_mandir}/man8/net.8*
-#%{_mandir}/ja/man1/smbtar.1*
-#%{_mandir}/ja/man1/smbclient.1*
-#%{_mandir}/ja/man1/nmblookup.1*
-
-%files common
-%defattr(-,root,root)
-/%{_lib}/libnss_wins.so*
-/%{_lib}/libnss_winbind.so*
-/%{_lib}/security/pam_winbind.so
-%{_libdir}/libsmbclient.a
-%{_libdir}/libsmbclient.so
-%{_libdir}/samba/charset/CP*.so
-%{_includedir}/libsmbclient.h
-%{_bindir}/testparm
-%{_bindir}/testprns
-%{_bindir}/smbpasswd
-# %{_bindir}/make_printerdef
-%{_bindir}/wbinfo
-# %{_bindir}/editreg
-%{_bindir}/ntlm_auth
-%{_bindir}/pdbedit
-%{_bindir}/profiles
-%{_bindir}/smbcquotas
-#%{_bindir}/vfstest
-%{_sbindir}/winbindd
-%config(noreplace) %{_sysconfdir}/samba/smb.conf
-%config(noreplace) %{_sysconfdir}/samba/lmhosts
-%dir %{_datadir}/samba
-%dir %{_datadir}/samba/codepages
-%dir %{_sysconfdir}/samba
-%{initdir}/winbind
-# %{_datadir}/samba/codepages/*
-# %{_mandir}/man1/make_smbcodepage.1*
-%{_mandir}/man1/ntlm_auth.1*
-%{_mandir}/man1/profiles.1*
-%{_mandir}/man1/smbcquotas.1*
-%{_mandir}/man1/testparm.1*
-%{_mandir}/man1/testprns.1*
-%{_mandir}/man5/smb.conf.5*
-%{_mandir}/man5/lmhosts.5*
-%{_mandir}/man8/smbpasswd.8*
-%{_mandir}/man1/wbinfo.1*
-%{_mandir}/man8/winbindd.8*
-%{_mandir}/man1/vfstest.1*
-
-# #%lang(ja) %{_mandir}/ja/man1/make_smbcodepage.1*
-#%lang(ja) %{_mandir}/ja/man1/testparm.1*
-#%lang(ja) %{_mandir}/ja/man1/testprns.1*
-#%lang(ja) %{_mandir}/ja/man5/smb.conf.5*
-#%lang(ja) %{_mandir}/ja/man5/lmhosts.5*
-#%lang(ja) %{_mandir}/ja/man8/smbpasswd.8*
-
-%changelog
-* Fri Jan 16 2004 Gerald (Jerry) Carter <jerry@samba,org>
-- Removed ChangeLog entries since they are kept in CVS
-
-
-
diff --git a/packaging/Fedora/samba.sysconfig b/packaging/Fedora/samba.sysconfig
deleted file mode 100644
index 944b72fcc28..00000000000
--- a/packaging/Fedora/samba.sysconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-# Options to smbd
-SMBDOPTIONS="-D"
-# Options to nmbd
-NMBDOPTIONS="-D"
-# Options for winbindd
-WINBINDOPTIONS=""
diff --git a/packaging/Fedora/samba.xinetd b/packaging/Fedora/samba.xinetd
deleted file mode 100644
index 8b62348dde3..00000000000
--- a/packaging/Fedora/samba.xinetd
+++ /dev/null
@@ -1,15 +0,0 @@
-# default: off
-# description: SWAT is the Samba Web Admin Tool. Use swat \
-# to configure your Samba server. To use SWAT, \
-# connect to port 901 with your favorite web browser.
-service swat
-{
- port = 901
- socket_type = stream
- wait = no
- only_from = 127.0.0.1
- user = root
- server = /usr/sbin/swat
- log_on_failure += USERID
- disable = yes
-}
diff --git a/packaging/Fedora/smb.init b/packaging/Fedora/smb.init
deleted file mode 100644
index 11a011883f9..00000000000
--- a/packaging/Fedora/smb.init
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/sh
-#
-# chkconfig: - 91 35
-# description: Starts and stops the Samba smbd and nmbd daemons \
-# used to provide SMB network services.
-#
-# pidfile: /var/run/samba/smbd.pid
-# pidfile: /var/run/samba/nmbd.pid
-# config: /etc/samba/smb.conf
-
-
-# Source function library.
-if [ -f /etc/init.d/functions ] ; then
- . /etc/init.d/functions
-elif [ -f /etc/rc.d/init.d/functions ] ; then
- . /etc/rc.d/init.d/functions
-else
- exit 0
-fi
-
-# Avoid using root's TMPDIR
-unset TMPDIR
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-if [ -f /etc/sysconfig/samba ]; then
- . /etc/sysconfig/samba
-fi
-
-# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
-
-# Check that smb.conf exists.
-[ -f /etc/samba/smb.conf ] || exit 0
-
-# Check that we can write to it... so non-root users stop here
-[ -w /etc/samba/smb.conf ] || exit 0
-
-
-RETVAL=0
-
-
-start() {
- KIND="SMB"
- echo -n $"Starting $KIND services: "
- daemon smbd $SMBDOPTIONS
- RETVAL=$?
- echo
- KIND="NMB"
- echo -n $"Starting $KIND services: "
- daemon nmbd $NMBDOPTIONS
- RETVAL2=$?
- echo
- [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && touch /var/lock/subsys/smb || \
- RETVAL=1
- return $RETVAL
-}
-
-stop() {
- KIND="SMB"
- echo -n $"Shutting down $KIND services: "
- killproc smbd -TERM
- RETVAL=$?
- [ $RETVAL -eq 0 ] && rm -f /var/run/smbd.pid
- echo
- KIND="NMB"
- echo -n $"Shutting down $KIND services: "
- killproc nmbd -TERM
- RETVAL2=$?
- [ $RETVAL2 -eq 0 ] && rm -f /var/run/nmbd.pid
- [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && rm -f /var/lock/subsys/smb
- echo ""
- return $RETVAL
-}
-
-restart() {
- stop
- start
-}
-
-reload() {
- echo -n $"Reloading smb.conf file: "
- killproc smbd -HUP
- RETVAL=$?
- echo
- return $RETVAL
-}
-
-rhstatus() {
- status smbd
- status nmbd
-}
-
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload
- ;;
- status)
- rhstatus
- ;;
- condrestart)
- [ -f /var/lock/subsys/smb ] && restart || :
- ;;
- *)
- echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}"
- exit 1
-esac
-
-exit $?
diff --git a/packaging/Fedora/swat.desktop b/packaging/Fedora/swat.desktop
deleted file mode 100644
index 0d7b4b5c48c..00000000000
--- a/packaging/Fedora/swat.desktop
+++ /dev/null
@@ -1,8 +0,0 @@
-[Desktop Entry]
-Name=Samba Configuration
-Name[de]=Samba Konfiguration
-Type=Application
-Comment=Configure Samba with a web based interface
-Exec=htmlview http://127.0.0.1:901/
-Terminal=false
-Categories=X-Red-Hat-Extra;Application;System;X-Red-Hat-ServerConfig;
diff --git a/packaging/Fedora/winbind.init b/packaging/Fedora/winbind.init
deleted file mode 100644
index 05e0eb4d006..00000000000
--- a/packaging/Fedora/winbind.init
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/sh
-#
-# chkconfig: - 91 35
-# description: Starts and stops the Samba winbind daemon
-# #
-# pidfile: /var/cache/samba/winbind.pid
-# config: /etc/samba/smb.conf
-
-
-# Source function library.
-if [ -f /etc/init.d/functions ] ; then
- . /etc/init.d/functions
-elif [ -f /etc/rc.d/init.d/functions ] ; then
- . /etc/rc.d/init.d/functions
-else
- exit 0
-fi
-
-# Avoid using root's TMPDIR
-unset TMPDIR
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-if [ -f /etc/sysconfig/samba ]; then
- . /etc/sysconfig/samba
-fi
-
-# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
-
-# Check that smb.conf exists.
-[ -f /etc/samba/smb.conf ] || exit 0
-
-RETVAL=0
-
-
-start() {
- KIND="Winbind"
- echo -n $"Starting $KIND services: "
- daemon winbindd "$WINBINDOPTIONS"
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/winbindd || RETVAL=1
- return $RETVAL
-}
-
-stop() {
- echo
- KIND="Winbind"
- echo -n $"Shutting down $KIND services: "
- killproc winbindd -TERM
- RETVAL=$?
- [ $RETVAL -eq 0 ] \
- && && rm -f /var/run/nmbd.pid \
- && rm -f /var/lock/subsys/winbindd
- echo ""
- return $RETVAL
-}
-
-restart() {
- stop
- start
-}
-
-reload() {
- echo -n $"Reloading smb.conf file: "
- killproc winbindd -HUP
- RETVAL=$?
- echo
- return $RETVAL
-}
-
-rhstatus() {
- status winbindd
-}
-
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload
- ;;
- status)
- rhstatus
- ;;
- condrestart)
- [ -f /var/lock/subsys/winbindd ] && restart || :
- ;;
- *)
- echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}"
- exit 1
-esac
-
-exit $?
diff --git a/packaging/HPUX/Instructions b/packaging/HPUX/Instructions
new file mode 100755
index 00000000000..5e5bd542d3f
--- /dev/null
+++ b/packaging/HPUX/Instructions
@@ -0,0 +1,49 @@
+Installation Instructions for HP-UX Software Distributor package
+----------------------------------------------------------------
+
+1. Run swinstall
+
+ You may have copied (swcopy) the depot to the depot server. In such cases
+ select the depot on server.
+
+ In order to install from the depot file, as root enter the following
+ command:
+
+ swinstall -s `pwd`/samba.depot Samba
+
+2. Create configuration file
+
+ Create /usr/local/samba/lib/smb.conf. You can use one of the examples from
+ /usr/local/samba/newconfig/examples as template.
+
+ Make sure that "guest account = pcguest" is included in the global
+ configuration variables. The swinstall will have created the pcguest
+ user on HPUX for you. The default value of "guest account" is "nobody"
+ which causes problems for Samba on HPUX because it has a negative uid.
+
+3. Start/stop Samba
+
+ The installation provides the boot startup script at /sbin/init.d/samba.
+ Samba will automatically start at run level 3 and stop during the
+ transition to run level 2.
+
+ You can use this script to manually manipulate Samba. Enter:
+
+ # /sbin/init.d/samba start to start Samba
+ # /sbin/init.d/samba stop to stop Samba
+
+4. Customization
+
+ The autostart is controled by editing file /etc/rc.config.d/samba. This
+ file has the following variables:
+
+ SAMBA_START=[0|1] 1 start Samba at boot (default)
+ 0 do not start samba at boot
+
+ SAMBA_DEBUG=[0-9] debug level for smbd and nmbd. Default debug
+ level is 1.
+
+ The configuration file is not overwritten at next install while the boot
+ script (/sbin/init.d/samba) is.
+
+Author: Leon Mlakar <leon@hermes.si>
diff --git a/packaging/HPUX/Packaging-instructions b/packaging/HPUX/Packaging-instructions
new file mode 100755
index 00000000000..8645fba2756
--- /dev/null
+++ b/packaging/HPUX/Packaging-instructions
@@ -0,0 +1,75 @@
+Create Software Depot for Samba
+-------------------------------
+
+1. Compile the source code
+ The packaging assumes that the final product will install under /usr/local/samba and will use /usr/local/samba for var directory. In order to support these
+ assumptions, run configure as follows:
+
+ ./configure --prefix /usr/local/samba --localstatedir /usr/local/samba
+
+ NOTE: to compile samba with optional winbind capability (HP-UX 11.x only),
+ use the following configure command line instead:
+
+ ./configure --with-winbind --with-pam --prefix /usr/local/samba --localstatedir /usr/local/samba
+
+ Afterwards compile the source code in a standard way.
+
+2. In packaging/HPUX directory run the following command:
+
+ WITHOUT winbind:
+
+ $ create_package.sh
+
+ WITH winbind:
+
+ $ create_package_with_winbind.sh
+
+3. Use resulting samba.depot file as the software depot for Samba.
+
+Brief Description of Depot
+--------------------------
+
+The software depot contains product Samba, which consists of the following
+three filesets:
+
+ Samba.core Core samba server components, everything but SWAT
+ and man pages
+
+ Samba.man Man pages. Note that HP-UX uses different section
+ numbering, so the man pages are moved and modified
+ to correct the section references (i.e. nmbd(8) changed
+ to nmbd(1m)).
+
+ Samba.swat SWAT tool.
+
+The configure scripts will take care of the following:
+
+ Samba.core 1. create pcguest account should it not exist. The
+ login shell is set to /usr/bin/true
+ 2. create startup/shutdown links at:
+ /sbin/rc3.d/S911samba
+ /sbin/rc2.d/K130samba
+ 3. copy boot configuration file from newconfig to
+ /etc/rc.config.d, if one does not exist.
+
+ Samba.man 1. add /usr/local/samba/man to default man search path in
+ /etc/MANPATH
+
+ Samba.swat 1. add swat service to /etc/services if necessary.
+ Swat will run through port 901.
+ 2. add swat to /etc/inetd.conf, if necessary.
+ 3. signal (SIGHUP) inetd to reread configuration if
+ 1. or 2. were changed.
+
+The unconfigure scripts will, upon the product removal, do the following:
+
+ Samba.core 1. remove startup/shutdown links
+ 2. remove user pcguest
+
+ Samba.man N/A
+
+ Samba.swat 1. remove swat from /etc/services
+ 2. remove swat from /etc/inetd.conf
+ 3. signal inetd (SIGHUP) to reread configuration
+
+Author: Leon Mlakar <leon@hermes.si>
diff --git a/packaging/HPUX/configure.bin b/packaging/HPUX/configure.bin
new file mode 100755
index 00000000000..60363336054
--- /dev/null
+++ b/packaging/HPUX/configure.bin
@@ -0,0 +1,44 @@
+# Samba.core configure script
+
+RC=0
+
+addUser()
+{
+ if grep -q '^pcguest:' /etc/passwd
+ then
+ cat <<__EOF__
+NOTE: Username pcguest already exists in /etc/passwd file.
+__EOF__
+ return
+ fi
+
+ /usr/sbin/useradd -g users -d /home/pcguest -c "Samba Guest" \
+ -s /usr/bin/true -m pcguest
+
+
+ if [ $? -ne 0 ]
+ then
+ cat >&2 <<__EOF__
+ERROR: Failed to create username pcguest.
+__EOF__
+ RC=1
+ else
+ cat <<__EOF__
+NOTE: The configure script has added username pcguest in /etc/passwd file.
+ You must set the password for user pcguest in order to activate it.
+__EOF__
+ fi
+}
+
+
+addUser
+
+ln -s /sbin/init.d/samba /sbin/rc3.d/S911samba
+ln -s /sbin/init.d/samba /sbin/rc2.d/K130samba
+
+if [ ! -f /etc/rc.config.d/samba ]
+then
+ cp /usr/local/samba/newconfig/samba.config /etc/rc.config.d/samba
+fi
+
+exit 0
diff --git a/packaging/HPUX/configure.man b/packaging/HPUX/configure.man
new file mode 100755
index 00000000000..5aa5545fee5
--- /dev/null
+++ b/packaging/HPUX/configure.man
@@ -0,0 +1,12 @@
+# Samba.man configure script
+
+
+grep -q '/usr/local/samba/man' /etc/MANPATH
+if [ $? -eq 1 ]
+then
+ echo "`cat /etc/MANPATH`:/usr/local/samba/man" >/tmp/$$.PATH
+ cp /tmp/$$.PATH /etc/MANPATH
+ rm -f /tmp/$$.PATH
+fi
+
+exit 0
diff --git a/packaging/HPUX/configure.swat b/packaging/HPUX/configure.swat
new file mode 100755
index 00000000000..0e69fc03fe4
--- /dev/null
+++ b/packaging/HPUX/configure.swat
@@ -0,0 +1,61 @@
+# Configure script for Samba.swat
+
+UPDATE=0
+
+KillProcess()
+{
+ proc=$1
+ sig=$2
+
+ # Determine PID of process(es) to stop and kill it. This routine
+ # is designed to work with bourne shell, ksh and posix shell.
+
+ Command=`basename $proc | cut -c1-8` # Solaris ps limited to 8 chars.
+
+ pid=`ps -e | awk "\\$NF~/$Command/ {print \\$1}"`
+
+ if [ "X$pid" != "X" ]; then
+ kill -$sig $pid
+ fi
+}
+
+UpdateServices()
+{
+ if grep -q '^swat' /etc/services
+ then
+ return
+ fi
+
+ echo "swat 901/tcp" >>/etc/services
+ cat <<__EOF__
+NOTE: The following entry had been added to /etc/services:
+ swat 901/tcp
+ Should you want to move SWAT to another port, modify the entry
+ accordingly and restart inetd daemon with -HUP signal.
+__EOF__
+ UPDATE=1
+}
+
+UpdateInetd()
+{
+ if grep -q '^swat' /etc/inetd.conf
+ then
+ return
+ fi
+
+ echo "swat stream tcp nowait.400 root /usr/local/samba/bin/swat swat" >>/etc/inetd.conf
+
+
+ UPDATE=1
+}
+
+UpdateServices
+UpdateInetd
+
+if [ "$UPDATE" -eq 1 ]
+then
+ KillProcess inetd HUP
+fi
+
+exit 0
+
diff --git a/packaging/HPUX/configure.winbind b/packaging/HPUX/configure.winbind
new file mode 100755
index 00000000000..fc9b8ded684
--- /dev/null
+++ b/packaging/HPUX/configure.winbind
@@ -0,0 +1,9 @@
+# Samba.winbind configure script
+
+
+ echo "heres where wed create links to winbind libs"
+ ln -s /usr/local/samba/lib/winbind/libnss_winbind.so /usr/lib/libnss_winbind.1
+ ln -s /usr/local/samba/lib/winbind/pam_winbind.so /usr/lib/security/libpam_winbind.1
+
+
+exit 0
diff --git a/packaging/HPUX/create_package.sh b/packaging/HPUX/create_package.sh
new file mode 100755
index 00000000000..f8e321dbff7
--- /dev/null
+++ b/packaging/HPUX/create_package.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/sh
+PRODUCT=Samba
+DEPOT=samba.depot
+PSF=samba.psf
+export PRODUCT
+export DEPOT
+export PSF
+
+mkdir codepage >/dev/null 2>&1
+mkdir man >/dev/null 2>&1
+
+./gen_psf.sh $PRODUCT
+
+echo "Creating software depot ($DEPOT) for product $PRODUCT"
+
+/usr/sbin/swpackage -vv -s samba.psf -x target_type=tape -d `pwd`/$DEPOT $PRODUCT
+
+#- clean-up temporary directories
+rm -r codepage
+rm -r man
+
diff --git a/packaging/HPUX/create_package_with_winbind.sh b/packaging/HPUX/create_package_with_winbind.sh
new file mode 100755
index 00000000000..b58c38f0a91
--- /dev/null
+++ b/packaging/HPUX/create_package_with_winbind.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/sh
+PRODUCT=Samba
+DEPOT=samba.depot
+PSF=samba.psf
+export PRODUCT
+export DEPOT
+export PSF
+
+mkdir codepage >/dev/null 2>&1
+mkdir man >/dev/null 2>&1
+
+./gen_psf_with_winbind.sh $PRODUCT
+
+echo "Creating software depot ($DEPOT) for product $PRODUCT"
+
+/usr/sbin/swpackage -vv -s samba.psf -x target_type=tape -d `pwd`/$DEPOT $PRODUCT
+
+#- clean-up temporary directories
+rm -r codepage
+rm -r man
+
diff --git a/packaging/HPUX/gen_psf.sh b/packaging/HPUX/gen_psf.sh
new file mode 100755
index 00000000000..4a24bab49b4
--- /dev/null
+++ b/packaging/HPUX/gen_psf.sh
@@ -0,0 +1,357 @@
+#!/usr/bin/sh
+#- Below variables are editable.
+#- VERSION Script tries to set the version automatically if it's empty
+#- string. The version number is assumed to be in
+#- ../../source/include/version.h. Should this fail to find correct
+#- version, set it manually to override automatic search.
+#- BIN List of binaries from ../../source/bin. Note: do not include
+#- swat here for it is a part of Samba.swat fileset
+#- SCRIPT List of scripts
+#- OS_REVISION The regular expression to determine the supported OS version.
+#- The default versions are HP-UX 10.10 or later as well as 11.*.
+#- You can modify this to reflect the OS you compile on. For
+#- instance, to support any 10.? and 11.? releases, use the
+#- following string:
+#- '?.10.*|?.11.*
+ VERSION=""
+
+ BIN="smbd nmbd smbclient testparm testprns smbstatus\
+ rpcclient smbpasswd make_smbcodepage nmblookup "
+
+# SCRIPT="smbtar addtosmbpass convert_smbpasswd"
+
+ OS_RELEASE='?.10.[2-9]?|?.11.*'
+
+
+#- Below variables should be exported from create_package.sh
+
+if [ -z "$PSF" ]
+then
+ PSF=samba.psf
+fi
+
+if [ -z "$DEPOT" ]
+then
+ DEPOT=samba.depot
+fi
+
+if [ -z "$PRODUCT" ]
+then
+ PRODUCT=Samba
+fi
+
+#--------------------------------------------------------------------------
+CODEPAGES=""
+if [ -z "$VERSION" ]
+then
+ echo "Deducing Samba version from version.h ... \c"
+ VERSION=`grep VERSION ../../source/include/version.h | awk '{print $3}' |\
+ tr -d '"'`
+ if [ $? -ne 0 -o -z "$VERSION" ]
+ then
+ echo "failed."
+ echo "Cannot find Samba version. Edit gen_psf.sh and set VERSION"
+ echo "variable manually."
+ exit 1
+ else
+ echo "$VERSION"
+ fi
+fi
+
+echo "Creating list of codepage definitions ..."
+
+#- create codepages from definition and add them to PSF file
+for a in ../../source/codepages/codepage_def.[0-9][0-9][0-9]
+do
+ b=${a##../../source/codepages/codepage_def.}
+ CODEPAGES="$CODEPAGES $b"
+done
+echo "\t$CODEPAGES"
+
+echo "Running make_smbcodepage on codepage definitions ... \c"
+
+mkdir codepage >/dev/null 2>&1
+for a in $CODEPAGES
+do
+../../source/bin/make_smbcodepage c $a ../../source/codepages/codepage_def.$a\
+ codepage/codepage.$a
+done
+echo "done."
+
+#- HP-UX uses slightly different section numbers for man pages. The following
+#- compares to "normal" sections:
+#-
+#- Section HP-UX section
+#- 1 1 user commands
+#- 5 4 files
+#- 7 5 concepts
+#- 8 1m administration commands
+#- NOTE:
+#- Sed expressions used in below loops replaces original section references
+#- inside man page with HP-UX section references. Assumption is that
+#- only numbers in brackets are section references and nothing else.
+#- So far I did not see the man pages corrupted by replacing anything
+#- else but section references.
+
+mkdir man >/dev/null 2>&1
+echo "Coverting man pages to HP-UX numbering ..."
+echo "\t Sections 1 \c"
+for a in ../../docs/manpages/*.1
+do
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 1/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/`basename $a`
+done
+echo "1m \c"
+for a in ../../docs/manpages/*.8
+do
+ b=`basename $a`
+ c=${b%.8}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 1M/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.1m
+done
+echo "4 \c"
+for a in ../../docs/manpages/*.5
+do
+ b=`basename $a`
+ c=${b%.5}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 4/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.4
+done
+echo "5"
+for a in ../../docs/manpages/*.7
+do
+ b=`basename $a`
+ c=${b%.7}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 5/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.5
+done
+
+echo "Creating product specification file:"
+echo "\tVendor and product description"
+#- vendor and header of product definition
+cat <<_EOF_ >$PSF
+vendor
+ tag Samba
+ title Samba Team
+ description <vendor_description
+end
+
+product
+ tag $PRODUCT
+ title Samba Server
+ description < ../../WHATSNEW.txt
+ copyright "Copyright (c) 1998 Samba Team. See COPYING for details."
+ readme < ../../README
+ revision $VERSION
+ machine_type *
+ os_name HP-UX
+ os_release $OS_RELEASE
+ os_version *
+ directory /
+ is_locatable false
+ vendor_tag Samba
+
+_EOF_
+
+echo "\tFileset $PRODUCT.core"
+
+cat <<_EOF_ >>$PSF
+ fileset
+ tag core
+ title Samba server core components
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ configure configure.bin
+ unconfigure unconfigure.bin
+
+ file -m 0755 -o root -g sys / /usr/local/samba/
+ file -m 0755 -o root -g sys / /usr/local/samba/bin/
+ file -m 0755 -o root -g sys / /usr/local/samba/lib/
+ file -m 0755 -o root -g sys / /usr/local/samba/lib/codepages/
+ file -m 0755 -o root -g sys / /usr/local/samba/newconfig/
+ file -m 0755 -o root -g sys / /usr/local/samba/newconfig/examples/
+ file -m 0700 -o root -g sys / /usr/local/samba/private/
+ file -m 0755 -o root -g sys / /var/usr/local/samba/
+ file -m 0755 -o root -g sys / /var/usr/local/samba/locks/
+
+ file -m 0444 -o root -g sys ../../COPYING /usr/local/samba/COPYING
+ file -m 0555 -o root -g sys ./samba.boot /sbin/init.d/samba
+ file -m 0444 -o root -g sys ./samba.config /usr/local/samba/newconfig/samba.config
+
+ file -m 0444 -o root -g sys ../../examples/smb.conf.default /usr/local/samba/newconfig/examples/smb.conf.default
+ file -m 0444 -o root -g sys ../../examples/simple/smb.conf /usr/local/samba/newconfig/examples/smb.conf.simple
+ file -m 0444 -o root -g sys ../../examples/dce-dfs/smb.conf /usr/local/samba/newconfig/examples/smb.conf.dce-dfs
+
+ directory ../../source/bin=/usr/local/samba/bin
+_EOF_
+ for a in $BIN
+ do
+ echo " file -m 0555 -o root -g sys $a" >>$PSF
+ done
+
+ echo " directory ../../source/script=/usr/local/samba/bin" >>$PSF
+
+ for a in $SCRIPT
+ do
+ echo " file -m 0555 -o root -g sys $a" >>$PSF
+ done
+
+ echo " directory ./codepage=/usr/local/samba/lib/codepages" >> $PSF
+
+ for a in $CODEPAGES
+ do
+ echo " file -m 0444 -o root -g sys codepage.$a" >>$PSF
+ done
+ echo " end" >>$PSF
+#- end of fileset CORE
+
+echo "\tFileset $PRODUCT.man"
+#- Man pages
+cat <<_EOF_ >>$PSF
+ fileset
+ tag man
+ title Samba server man pages
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ configure configure.man
+
+ file -m 0755 -o root -g sys / /usr/local/samba/man/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man1/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man1m/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man4/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man5/
+
+_EOF_
+
+#- HP-UX uses slightly different section numbers for man pages. The following
+#- compares to "normal" sections:
+#-
+#- Section HP-UX section
+#- 1 1 user commands
+#- 5 4 files
+#- 7 5 concepts
+#- 8 1m administration commands
+
+ for a in man/*.1
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man1/$b" >>$PSF
+ done
+
+ for a in man/*.1m
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man1m/$b" >>$PSF
+ done
+
+ for a in man/*.4
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man4/$b" >>$PSF
+ done
+
+ for a in man/*.5
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man5/$b" >>$PSF
+ done
+
+ echo " end" >>$PSF
+
+echo "\tFileset $PRODUCT.swat"
+
+cat <<_EOF_ >>$PSF
+
+ fileset
+ tag swat
+ title Samba Web-based administration tool
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ prerequisite Samba.core
+ configure configure.swat
+ unconfigure unconfigure.swat
+
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/help/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/images/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/include/
+
+ directory ../../swat=/usr/local/samba/swat
+ file -m 0444 -o root -g sys README
+
+ directory ../../source/bin=/usr/local/samba/bin
+ file -m 0555 -o root -g sys swat
+
+ directory ../../swat/images=/usr/local/samba/swat/images
+_EOF_
+
+ for a in ../../swat/images/*.gif
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../swat/help=/usr/local/samba/swat/help" >>$PSF
+
+ for a in ../../swat/help/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../docs/htmldocs=/usr/local/samba/swat/help" >>$PSF
+
+ for a in ../../docs/htmldocs/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../swat/include=/usr/local/samba/swat/include" >>$PSF
+
+ for a in ../../swat/include/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+cat <<_EOF_ >>$PSF
+ end
+
+end
+_EOF_
+
diff --git a/packaging/HPUX/gen_psf_with_winbind.sh b/packaging/HPUX/gen_psf_with_winbind.sh
new file mode 100755
index 00000000000..ef32590ea83
--- /dev/null
+++ b/packaging/HPUX/gen_psf_with_winbind.sh
@@ -0,0 +1,380 @@
+#!/usr/bin/sh
+#- Below variables are editable.
+#- VERSION Script tries to set the version automatically if it's empty
+#- string. The version number is assumed to be in
+#- ../../source/include/version.h. Should this fail to find correct
+#- version, set it manually to override automatic search.
+#- BIN List of binaries from ../../source/bin. Note: do not include
+#- swat here for it is a part of Samba.swat fileset
+#- SCRIPT List of scripts
+#- OS_REVISION The regular expression to determine the supported OS version.
+#- The default versions are HP-UX 10.10 or later as well as 11.*.
+#- You can modify this to reflect the OS you compile on. For
+#- instance, to support any 10.? and 11.? releases, use the
+#- following string:
+#- '?.10.*|?.11.*
+ VERSION=""
+
+ BIN="smbd nmbd smbclient testparm testprns smbstatus\
+ rpcclient smbpasswd make_smbcodepage nmblookup "
+
+# SCRIPT="smbtar addtosmbpass convert_smbpasswd"
+
+ OS_RELEASE='?.10.[2-9]?|?.11.*'
+# WINBINDD_OS_RELEASE='?.11.*'
+ WINBINDD_OS_RELEASE='?.11.11'
+
+#- Below variables should be exported from create_package.sh
+
+if [ -z "$PSF" ]
+then
+ PSF=samba.psf
+fi
+
+if [ -z "$DEPOT" ]
+then
+ DEPOT=samba.depot
+fi
+
+if [ -z "$PRODUCT" ]
+then
+ PRODUCT=Samba
+fi
+
+#--------------------------------------------------------------------------
+CODEPAGES=""
+if [ -z "$VERSION" ]
+then
+ echo "Deducing Samba version from version.h ... \c"
+ VERSION=`grep VERSION ../../source/include/version.h | awk '{print $3}' |\
+ tr -d '"'`
+ if [ $? -ne 0 -o -z "$VERSION" ]
+ then
+ echo "failed."
+ echo "Cannot find Samba version. Edit gen_psf.sh and set VERSION"
+ echo "variable manually."
+ exit 1
+ else
+ echo "$VERSION"
+ fi
+fi
+
+echo "Creating list of codepage definitions ..."
+
+#- create codepages from definition and add them to PSF file
+for a in ../../source/codepages/codepage_def.[0-9][0-9][0-9]
+do
+ b=${a##../../source/codepages/codepage_def.}
+ CODEPAGES="$CODEPAGES $b"
+done
+echo "\t$CODEPAGES"
+
+echo "Running make_smbcodepage on codepage definitions ... \c"
+
+mkdir codepage >/dev/null 2>&1
+for a in $CODEPAGES
+do
+../../source/bin/make_smbcodepage c $a ../../source/codepages/codepage_def.$a\
+ codepage/codepage.$a
+done
+echo "done."
+
+#- HP-UX uses slightly different section numbers for man pages. The following
+#- compares to "normal" sections:
+#-
+#- Section HP-UX section
+#- 1 1 user commands
+#- 5 4 files
+#- 7 5 concepts
+#- 8 1m administration commands
+#- NOTE:
+#- Sed expressions used in below loops replaces original section references
+#- inside man page with HP-UX section references. Assumption is that
+#- only numbers in brackets are section references and nothing else.
+#- So far I did not see the man pages corrupted by replacing anything
+#- else but section references.
+
+mkdir man >/dev/null 2>&1
+echo "Coverting man pages to HP-UX numbering ..."
+echo "\t Sections 1 \c"
+for a in ../../docs/manpages/*.1
+do
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 1/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/`basename $a`
+done
+echo "1m \c"
+for a in ../../docs/manpages/*.8
+do
+ b=`basename $a`
+ c=${b%.8}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 1M/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.1m
+done
+echo "4 \c"
+for a in ../../docs/manpages/*.5
+do
+ b=`basename $a`
+ c=${b%.5}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 4/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.4
+done
+echo "5"
+for a in ../../docs/manpages/*.7
+do
+ b=`basename $a`
+ c=${b%.7}
+ sed -e 's/^[.]TH \([^ ][^ ]*\) .*/.TH \1 5/'\
+ -e '1a\
+.ds )H Samba Team'\
+ -e "1a\\
+.ds ]W $VERSION"\
+ -e 's/(8)/(1m)/g' \
+ -e 's/(5)/(4)/g' \
+ -e 's/(7)/(5)/g' \
+ $a >man/$c.5
+done
+
+echo "Creating product specification file:"
+echo "\tVendor and product description"
+#- vendor and header of product definition
+cat <<_EOF_ >$PSF
+vendor
+ tag Samba
+ title Samba Team
+ description <vendor_description
+end
+
+product
+ tag $PRODUCT
+ title Samba Server
+ description < ../../WHATSNEW.txt
+ copyright "Copyright (c) 1998 Samba Team. See COPYING for details."
+ readme < ../../README
+ revision $VERSION
+ machine_type *
+ os_name HP-UX
+ os_release $OS_RELEASE
+ os_version *
+ directory /
+ is_locatable false
+ vendor_tag Samba
+
+_EOF_
+
+echo "\tFileset $PRODUCT.core"
+
+cat <<_EOF_ >>$PSF
+ fileset
+ tag core
+ title Samba server core components
+ revision $VERSION
+ os_release $WINBIND_OS_RELEASE
+ is_kernel false
+ is_reboot false
+ is_secure false
+ configure configure.bin
+ unconfigure unconfigure.bin
+
+ file -m 0755 -o root -g sys / /usr/local/samba/
+ file -m 0755 -o root -g sys / /usr/local/samba/bin/
+ file -m 0755 -o root -g sys / /usr/local/samba/lib/
+ file -m 0755 -o root -g sys / /usr/local/samba/lib/codepages/
+ file -m 0755 -o root -g sys / /usr/local/samba/newconfig/
+ file -m 0755 -o root -g sys / /usr/local/samba/newconfig/examples/
+ file -m 0700 -o root -g sys / /usr/local/samba/private/
+ file -m 0755 -o root -g sys / /var/usr/local/samba/
+ file -m 0755 -o root -g sys / /var/usr/local/samba/locks/
+
+ file -m 0444 -o root -g sys ../../COPYING /usr/local/samba/COPYING
+ file -m 0555 -o root -g sys ./samba.boot /sbin/init.d/samba
+ file -m 0444 -o root -g sys ./samba.config /usr/local/samba/newconfig/samba.config
+
+ file -m 0444 -o root -g sys ../../examples/smb.conf.default /usr/local/samba/newconfig/examples/smb.conf.default
+ file -m 0444 -o root -g sys ../../examples/simple/smb.conf /usr/local/samba/newconfig/examples/smb.conf.simple
+ file -m 0444 -o root -g sys ../../examples/dce-dfs/smb.conf /usr/local/samba/newconfig/examples/smb.conf.dce-dfs
+
+ directory ../../source/bin=/usr/local/samba/bin
+_EOF_
+ for a in $BIN
+ do
+ echo " file -m 0555 -o root -g sys $a" >>$PSF
+ done
+
+ echo " directory ../../source/script=/usr/local/samba/bin" >>$PSF
+
+ for a in $SCRIPT
+ do
+ echo " file -m 0555 -o root -g sys $a" >>$PSF
+ done
+
+ echo " directory ./codepage=/usr/local/samba/lib/codepages" >> $PSF
+
+ for a in $CODEPAGES
+ do
+ echo " file -m 0444 -o root -g sys codepage.$a" >>$PSF
+ done
+ echo " end" >>$PSF
+#- end of fileset CORE
+
+echo "\tFileset $PRODUCT.man"
+#- Man pages
+cat <<_EOF_ >>$PSF
+ fileset
+ tag man
+ title Samba server man pages
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ configure configure.man
+
+ file -m 0755 -o root -g sys / /usr/local/samba/man/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man1/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man1m/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man4/
+ file -m 0755 -o root -g sys / /usr/local/samba/man/man5/
+
+_EOF_
+
+#- HP-UX uses slightly different section numbers for man pages. The following
+#- compares to "normal" sections:
+#-
+#- Section HP-UX section
+#- 1 1 user commands
+#- 5 4 files
+#- 7 5 concepts
+#- 8 1m administration commands
+
+ for a in man/*.1
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man1/$b" >>$PSF
+ done
+
+ for a in man/*.1m
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man1m/$b" >>$PSF
+ done
+
+ for a in man/*.4
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man4/$b" >>$PSF
+ done
+
+ for a in man/*.5
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $a /usr/local/samba/man/man5/$b" >>$PSF
+ done
+
+ echo " end" >>$PSF
+
+echo "\tFileset $PRODUCT.swat"
+
+cat <<_EOF_ >>$PSF
+
+ fileset
+ tag winbind
+ title Samba winbind
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ prerequisite Samba.core
+ configure configure.winbind
+ unconfigure unconfigure.winbind
+
+ directory ../../source/nsswitch=/usr/local/samba/lib/winbind
+ file -m 0755 -o root -g sys libnss_winbind.so
+ file -m 0755 -o root -g sys pam_winbind.so
+ directory ../../source/bin=/usr/local/samba/bin
+ file -m 0755 -o root -g sys winbindd
+ file -m 0755 -o root -g sys wbinfo
+
+
+cat <<_EOF_ >>$PSF
+ end
+ fileset
+ tag swat
+ title Samba Web-based administration tool
+ revision $VERSION
+ is_kernel false
+ is_reboot false
+ is_secure false
+ prerequisite Samba.core
+ configure configure.swat
+ unconfigure unconfigure.swat
+
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/help/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/images/
+ file -m 0755 -o root -g sys / /usr/local/samba/swat/include/
+
+ directory ../../swat=/usr/local/samba/swat
+ file -m 0444 -o root -g sys README
+
+ directory ../../source/bin=/usr/local/samba/bin
+ file -m 0555 -o root -g sys swat
+
+ directory ../../swat/images=/usr/local/samba/swat/images
+_EOF_
+
+ for a in ../../swat/images/*.gif
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../swat/help=/usr/local/samba/swat/help" >>$PSF
+
+ for a in ../../swat/help/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../docs/htmldocs=/usr/local/samba/swat/help" >>$PSF
+
+ for a in ../../docs/htmldocs/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+ echo " directory ../../swat/include=/usr/local/samba/swat/include" >>$PSF
+
+ for a in ../../swat/include/*.html
+ do
+ b=`basename $a`
+ echo " file -m 0444 -o root -g sys $b" >>$PSF
+ done
+
+cat <<_EOF_ >>$PSF
+ end
+
+end
+_EOF_
+
diff --git a/packaging/HPUX/samba.boot b/packaging/HPUX/samba.boot
new file mode 100755
index 00000000000..a0d55d7d766
--- /dev/null
+++ b/packaging/HPUX/samba.boot
@@ -0,0 +1,72 @@
+
+SUCCESS=0
+FAILURE=1
+exitval=$SUCCESS
+
+
+KillProcess()
+{
+ proc=$1
+ sig=$2
+
+ # Determine PID of process(es) to stop and kill it. This routine
+ # is designed to work with bourne shell, ksh and posix shell.
+
+ Command=`basename $proc | cut -c1-8` # Solaris ps limited to 8 chars.
+
+ pid=`ps -e | awk "\\$NF~/$Command/ {print \\$1}"`
+
+ if [ "X$pid" != "X" ]; then
+ kill -$sig $pid
+ fi
+}
+
+if [ ! -f /etc/rc.config.d/samba ]
+then
+ echo "ERROR: Config file /etc/rc.config.d/samba missing."
+ exit $FAILURE
+fi
+
+. /etc/rc.config.d/samba
+
+case $1 in
+ 'start_msg')
+ echo "Start Samba Services"
+ ;;
+
+ 'stop_msg')
+ echo "Stop Samba Services"
+ ;;
+
+ 'start')
+ # Starting Samba is easy ...
+ if [ "$SAMBA_START" -eq 1 ]
+ then
+ if [ -x /usr/local/samba/bin/smbd ]
+ then
+ /usr/local/samba/bin/smbd -D -d $SAMBA_DEBUG
+ fi
+
+ if [ -x /usr/local/samba/bin/nmbd ]
+ then
+ /usr/local/samba/bin/nmbd -D -d $SAMBA_DEBUG
+ fi
+ fi
+ ;;
+
+ 'stop')
+ #
+ # ... stopping it, however, is another story
+ #
+ KillProcess nmbd TERM
+ KillProcess smbd TERM
+ ;;
+
+ *)
+ echo "usage: $0 {start|stop|start_msg|stop_msg}"
+ exitval=$FAILURE
+ ;;
+esac
+
+exit $exitval
+
diff --git a/packaging/HPUX/samba.config b/packaging/HPUX/samba.config
new file mode 100755
index 00000000000..a5c6fd2cd06
--- /dev/null
+++ b/packaging/HPUX/samba.config
@@ -0,0 +1,2 @@
+SAMBA_START=1
+SAMBA_DEBUG=1
diff --git a/packaging/HPUX/unconfigure.bin b/packaging/HPUX/unconfigure.bin
new file mode 100755
index 00000000000..3d5c7d9dc04
--- /dev/null
+++ b/packaging/HPUX/unconfigure.bin
@@ -0,0 +1,8 @@
+# Samba.core unconfigure script
+
+rm -f /sbin/rc3.d/S911samba
+rm -f /sbin/rc2.d/K130samba
+
+/usr/sbin/userdel -r pcguest
+
+exit 0
diff --git a/packaging/HPUX/unconfigure.swat b/packaging/HPUX/unconfigure.swat
new file mode 100755
index 00000000000..b0dd325bc91
--- /dev/null
+++ b/packaging/HPUX/unconfigure.swat
@@ -0,0 +1,29 @@
+# Unconfigure script for Samba.swat
+
+KillProcess()
+{
+ proc=$1
+ sig=$2
+
+ # Determine PID of process(es) to stop and kill it. This routine
+ # is designed to work with bourne shell, ksh and posix shell.
+
+ Command=`basename $proc | cut -c1-8` # Solaris ps limited to 8 chars.
+
+ pid=`ps -e | awk "\\$NF~/$Command/ {print \\$1}"`
+
+ if [ "X$pid" != "X" ]; then
+ kill -$sig $pid
+ fi
+}
+
+grep -v '^swat' /etc/services >/tmp/services$$
+mv /tmp/services$$ /etc/services
+
+grep -v '^swat' /etc/inetd.conf >/tmp/inetd.conf$$
+mv /tmp/inetd.conf$$ /etc/inetd.conf
+
+KillProcess inetd HUP
+
+exit 0
+
diff --git a/packaging/HPUX/unconfigure.winbind b/packaging/HPUX/unconfigure.winbind
new file mode 100755
index 00000000000..80709eb86dd
--- /dev/null
+++ b/packaging/HPUX/unconfigure.winbind
@@ -0,0 +1,8 @@
+# Samba.winbind configure script
+
+
+ echo "heres where wed remove links to winbind libs"
+ rm /usr/lib/libnss_winbind.1
+ rm /usr/lib/security/libpam_winbind.1
+
+exit 0
diff --git a/packaging/HPUX/vendor_description b/packaging/HPUX/vendor_description
new file mode 100755
index 00000000000..2f661188048
--- /dev/null
+++ b/packaging/HPUX/vendor_description
@@ -0,0 +1,2 @@
+Read more about Samba and Samba Team at http://www.samba.org/
+
diff --git a/packaging/LSB/lsb-samba.spec b/packaging/LSB/lsb-samba.spec
index 516eaa430eb..7394213d253 100644
--- a/packaging/LSB/lsb-samba.spec
+++ b/packaging/LSB/lsb-samba.spec
@@ -1,13 +1,11 @@
#
-# "$Id: lsb-samba.spec,v 1.2 2001/07/03 01:01:12 jra Exp $"
-#
# Linux Standards Based RPM "spec" file for SAMBA.
#
Summary: SAMBA
Name: lsb-samba
-Version: 2.2.1
-Release: 0
+Version: PVERSION
+Release: PRELEASE
Copyright: GPL
Group: System Environment/Daemons
Source: ftp://ftp.samba.org/pub/samba/samba-%{version}.tar.gz
@@ -96,5 +94,4 @@ rm -rf $RPM_BUILD_ROOT
%dir /var/log/samba
#
-# End of "$Id: lsb-samba.spec,v 1.2 2001/07/03 01:01:12 jra Exp $".
#
diff --git a/packaging/LSB/samba.sh b/packaging/LSB/samba.sh
index 99fa1b0117d..a97949de14b 100755
--- a/packaging/LSB/samba.sh
+++ b/packaging/LSB/samba.sh
@@ -1,7 +1,5 @@
#!/bin/sh
#
-# "$Id: samba.sh,v 1.2 2001/07/03 01:01:12 jra Exp $"
-#
# SAMBA startup (init) script for LSB-compliant systems.
#
# Provides: smbd nmbd
@@ -76,5 +74,4 @@ esac
exit 0
#
-# End of "$Id: samba.sh,v 1.2 2001/07/03 01:01:12 jra Exp $".
#
diff --git a/packaging/Mandrake/findsmb b/packaging/Mandrake/findsmb
index f70d18dcbdc..04bc6080508 100755
--- a/packaging/Mandrake/findsmb
+++ b/packaging/Mandrake/findsmb
@@ -73,6 +73,9 @@ foreach $ip (@ipaddrs) # loop through each IP address found
$name = "unknown nis name";
}
} else {
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cure inside name space but not
+# names starting or ending with spaces
/(.{1,15})\s+<00>\s+/;
$name = $1;
}
@@ -103,6 +106,7 @@ foreach $ip (@ipaddrs) # loop through each IP address found
@name = grep(/<00> - <GROUP>/,@nmblookup);
$_ = @name[0];
if ($_) {
+# Same as before for space and characters
/(.{1,15})\s+<00>\s+/;
$_ = "[$1]";
} else {
diff --git a/packaging/Mandrake/makerpms-cvs.sh b/packaging/Mandrake/makerpms-cvs.sh
index 08c4370b314..72c75b772b5 100644
--- a/packaging/Mandrake/makerpms-cvs.sh
+++ b/packaging/Mandrake/makerpms-cvs.sh
@@ -22,16 +22,13 @@ done
#Change up three directories, rename directory to samba-$VERSION, change back
#then run makerpms.sh
-
+(
CURRENT=$(pwd)
-pushd $(dirname $(dirname $(dirname $CURRENT)))
+cd $(dirname $(dirname $(dirname $CURRENT)))
SAMBA_DIR=$(basename $(dirname $(dirname $CURRENT)))
mv $SAMBA_DIR samba-$VERSION
-pushd samba-$VERSION/source
-./autogen.sh
-popd
-pushd samba-$VERSION/packaging/Mandrake
+cd samba-$VERSION/packaging/Mandrake
sh makerpms.sh $@
-popd
+cd $(dirname $(dirname $(dirname $CURRENT)))
mv samba-$VERSION $SAMBA_DIR
-popd
+)
diff --git a/packaging/Mandrake/makerpms.sh.tmpl b/packaging/Mandrake/makerpms.sh.tmpl
index 5d06e2bbcca..ba4eff0e2b1 100644
--- a/packaging/Mandrake/makerpms.sh.tmpl
+++ b/packaging/Mandrake/makerpms.sh.tmpl
@@ -13,8 +13,8 @@
#
# rpm --eval should always give a correct answer for this
-SPECDIR=`rpm "$@" --eval "%{_specdir}"`
-SRCDIR=`rpm "$@" --eval "%{_sourcedir}"`
+SPECDIR=`rpm --eval "%{_specdir}"`
+SRCDIR=`rpm --eval "%{_sourcedir}"`
# At this point the (SPECDIR and) SRCDIR vaiables must have a value!
diff --git a/packaging/Mandrake/mount.smb b/packaging/Mandrake/mount.smb
new file mode 100755
index 00000000000..ba3cee84e0a
--- /dev/null
+++ b/packaging/Mandrake/mount.smb
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# by Bill Nottingham <notting@redhat.com>
+#
+# Adapted from mount.smb by Greg Galperin, MAR99 <grg@ai.mit.edu>
+#
+
+if [ $# != 4 -o "$3" != "-o" ]; then
+ echo "unsupported commandline $0 $*"
+ exit -1
+fi
+
+for arg in `echo $4 | tr ',' ' '`; do
+ case "$arg" in
+ user=*)
+ SMBUSER="`echo $arg | cut -d '=' -f 2-`"
+ ;;
+ passwd=*)
+ PASSWD=`echo $arg | cut -d '=' -f 2-`
+ ;;
+ domain=*)
+ DOMAIN="-W `echo $arg | cut -d '=' -f 2-`"
+ ;;
+ *)
+ ;;
+ esac
+done
+
+if [ -n "$PASSWD" ]; then
+ USER=$SMBUSER%$PASSWD exec smbmount "$1" $2 $DOMAIN
+else
+ USER=$SMBUSER exec smbmount "$1" $2 $DOMAIN -N
+fi
+exit $?
diff --git a/packaging/Mandrake/samba-2.2.0-buildroot.patch b/packaging/Mandrake/samba-2.2.0-buildroot.patch
deleted file mode 100644
index 72091a13bcb..00000000000
--- a/packaging/Mandrake/samba-2.2.0-buildroot.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- samba-2.2.0/source/script/installbin.sh Fri Jan 12 21:28:02 2001
-+++ samba-2.2.0/source/script/installbin.sh.207 Thu Apr 19 09:40:57 2001
-@@ -33,9 +33,9 @@
- chmod $INSTALLPERMS $BINDIR/$p2
-
- # this is a special case, mount needs this in a specific location
-- if [ $p2 = smbmount ]; then
-- ln -sf $BINDIR/$p2 /sbin/mount.smbfs
-- fi
-+ #if [ $p2 = smbmount ]; then
-+ # ln -sf $BINDIR/$p2 /sbin/mount.smbfs
-+ #fi
- done
-
-
diff --git a/packaging/Mandrake/samba-2.2.0-buildroot.patch.bz2 b/packaging/Mandrake/samba-2.2.0-buildroot.patch.bz2
new file mode 100755
index 00000000000..08f6401a5d0
--- /dev/null
+++ b/packaging/Mandrake/samba-2.2.0-buildroot.patch.bz2
Binary files differ
diff --git a/packaging/Mandrake/samba-2.2.0-gawk.patch.bz2 b/packaging/Mandrake/samba-2.2.0-gawk.patch.bz2
new file mode 100755
index 00000000000..c1272fbcb44
--- /dev/null
+++ b/packaging/Mandrake/samba-2.2.0-gawk.patch.bz2
Binary files differ
diff --git a/packaging/Mandrake/samba-2.2.5-gp-reloc-fix.patch b/packaging/Mandrake/samba-2.2.5-gp-reloc-fix.patch
new file mode 100755
index 00000000000..8888d6622e5
--- /dev/null
+++ b/packaging/Mandrake/samba-2.2.5-gp-reloc-fix.patch
@@ -0,0 +1,12 @@
+diff -ur samba-2.2.5.orig/examples/VFS/Makefile.in samba-2.2.5/examples/VFS/Makefile.in
+--- samba-2.2.5.orig/examples/VFS/Makefile.in 2002-06-17 20:35:09.000000000 +0200
++++ samba-2.2.5/examples/VFS/Makefile.in 2002-06-30 16:43:15.000000000 +0200
+@@ -4,7 +4,7 @@
+
+ CC=@CC@
+ LIBTOOL=@LIBTOOL@
+-CFLAGS=@CFLAGS@
++CFLAGS=@CFLAGS@ -DPIC -fPIC
+ LDFLAGS=@LDFLAGS@
+
+ VFS_OBJS=audit.so skel.so block/block.so recycle/recycle.so
diff --git a/packaging/Mandrake/samba-2.2.7a-smbldaptools-paths.patch b/packaging/Mandrake/samba-2.2.7a-smbldaptools-paths.patch
new file mode 100755
index 00000000000..971bfc27e7e
--- /dev/null
+++ b/packaging/Mandrake/samba-2.2.7a-smbldaptools-paths.patch
@@ -0,0 +1,139 @@
+diff -ur samba-2.2.7a.orig/examples/LDAP/ldapchpasswd samba-2.2.7a/examples/LDAP/ldapchpasswd
+--- samba-2.2.7a.orig/examples/LDAP/ldapchpasswd 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/ldapchpasswd 2003-02-10 15:38:24.000000000 -0500
+@@ -103,7 +103,7 @@
+ $password = crypt($pass, $modsalt);
+
+ # LanManager and NT clear text passwords
+-$ntpwd = `/usr/local/sbin/mkntpwd '$pass'`;
++$ntpwd = `/usr/sbin/mkntpwd '$pass'`;
+ chomp($lmpassword = substr($ntpwd, 0, index($ntpwd, ':')));
+ chomp($ntpassword = substr($ntpwd, index($ntpwd, ':')+1));
+
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/INSTALL samba-2.2.7a/examples/LDAP/smbldap-tools/INSTALL
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/INSTALL 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/INSTALL 2003-02-10 15:56:06.000000000 -0500
+@@ -4,12 +4,12 @@
+
+ Quick & Dirty:
+ =-=-=-=-=-=-=-
+- . Copy all those scripts in /usr/local/sbin/
++ . Copy all those scripts in /usr/share/samba/scripts
+ . Modify smbldap_conf.pm to match your configuration
+ . If not already done : "smbpasswd -w secret" to set up
+ the ldap admin password in secrets.tdb
+- . Either add /usr/local/sbin in $PERLLIB or run the scripts
+- from this directory, or make a symlink from /usr/local/sbin/*.pm
++ . Either add /usr/share/samba/scripts in $PERLLIB or run the scripts
++ from this directory, or make a symlink from /etc/samba/*.pm
+ to /usr/lib/perl5/.
+ . to allow a domain admin to add user using "add user script" in smb.conf :
+ chmod 753 smbldap_conf.pm
+@@ -21,7 +21,7 @@
+ RedHat RPM:
+ =-=-=-=-=-=
+ Install smbldap-tools-0.7-1.i386.rpm
+-Modify /usr/local/sbin/smbldap_conf.pm to match you configuration
++Modify /etc/samba/smbldap_conf.pm to match you configuration
+ If not already done : "smbpasswd -w secret" to set up
+ the ldap admin password in secrets.tdb
+
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap_conf.pm samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap_conf.pm
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap_conf.pm 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap_conf.pm 2003-02-10 15:39:42.000000000 -0500
+@@ -230,7 +230,7 @@
+ # prefer mkntpwd... most of the time, it's a wise choice :-)
+ $with_smbpasswd = 0;
+ $smbpasswd = "/usr/bin/smbpasswd";
+-$mk_ntpasswd = "/usr/local/sbin/mkntpwd";
++$mk_ntpasswd = "/usr/sbin/mkntpwd";
+
+ $ldap_path = "/usr/bin";
+ $ldap_opts = "-x";
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl 2003-02-10 15:50:15.000000000 -0500
+@@ -134,7 +134,7 @@
+ if (!$user_exists) {
+ if (!defined($Options{'C'})) {
+ # uid doesn't exist and we want to create it
+- my $addcmd = "/usr/local/sbin/smbldap-useradd.pl $usertype $login > /dev/null";
++ my $addcmd = "/usr/share/samba/scripts/smbldap-useradd.pl $usertype $login > /dev/null";
+ print STDERR "$addcmd\n";
+ my $r = system "$addcmd";
+ if ($r != 0) {
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl 2003-02-10 15:52:51.000000000 -0500
+@@ -135,7 +135,7 @@
+ if (!defined($dn_line = get_group_dn($group))) {
+ # group not found, create it ?
+ if (!$nocreate) {
+- system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5";
++ system "/usr/share/samba/scripts/smbldap-groupadd.pl \"$group\"; sleep 5";
+ if (!defined($dn_line = get_group_dn($group))) {
+ return 1;
+ }
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-tools.spec samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-tools.spec
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-tools.spec 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-tools.spec 2003-02-10 15:47:58.000000000 -0500
+@@ -1,6 +1,6 @@
+ # $Source: /home/cvs/samba/packaging/Mandrake/Attic/samba-2.2.7a-smbldaptools-paths.patch,v $
+ %define version 0.7
+-%define release 1
++%define release 2
+ %define name smbldap-tools
+ %define realname smbldap-tools
+
+@@ -37,7 +37,7 @@
+ Source20: smbldap-migrate-groups.pl
+ Source21: INFRA
+ BuildRoot: /%{_tmppath}/%{name}
+-Prefix: /usr/local
++Prefix: /usr
+ BuildRequires: perl >= 5.6
+ Requires: perl >= 5.6, openldap, openldap-clients, samba
+
+@@ -94,7 +94,7 @@
+ %post
+ ln -sf %{prefix}/sbin/smbldap_tools.pm /usr/lib/perl5/site_perl/smbldap_tools.pm
+ ln -sf %{prefix}/sbin/smbldap_conf.pm /usr/lib/perl5/site_perl/smbldap_conf.pm
+-chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /usr/local/sbin. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC."
++chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /etc/samba. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC."
+ perl -i -pe 's/_SLAVELDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm
+ perl -i -pe 's/_MASTERLDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm
+ perl -i -pe 's/_SUFFIX_/dc=IDEALX,dc=org/' %{prefix}/sbin/smbldap_conf.pm
+@@ -129,6 +129,10 @@
+
+
+ %changelog
++* Mon Feb 10 2003 Jim Collings <jcllings@tsunamicomm.net> 0.7-2
++- Changed prefix to /usr instead of
++- /usr/local for Mandrake compatibility.
++
+ * Sat Jun 1 2002 Olivier Lemaire <olem@IDEALX.com> 0.7-1
+ - some bugfixes about smbldap-populate
+ - bugfixed the smbpasswd call in smbldap-useradd
+diff -ur samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-useradd.pl samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-useradd.pl
+--- samba-2.2.7a.orig/examples/LDAP/smbldap-tools/smbldap-useradd.pl 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/LDAP/smbldap-tools/smbldap-useradd.pl 2003-02-10 15:53:50.000000000 -0500
+@@ -346,7 +346,7 @@
+ }
+
+ if (defined($Options{'P'})) {
+- exec "/usr/local/sbin/smbldap-passwd.pl $userName"
++ exec "/usr/share/samba/scripts/smbldap-passwd.pl $userName"
+ }
+
+ exit 0;
+diff -ur samba-2.2.7a.orig/examples/VFS/block/smb.conf samba-2.2.7a/examples/VFS/block/smb.conf
+--- samba-2.2.7a.orig/examples/VFS/block/smb.conf 2003-02-10 15:17:53.000000000 -0500
++++ samba-2.2.7a/examples/VFS/block/smb.conf 2003-02-11 13:53:53.000000000 -0500
+@@ -1,6 +1,6 @@
+ [homes]
+ comment = Home Directories
+- vfs object = /usr/local/samba/lib/block.so
++ vfs object = /usr/lib/samba/vfs/block.so
+ browseable = yes
+ writable = yes
+
diff --git a/packaging/Mandrake/samba-3.0-smbmount-sbin.patch b/packaging/Mandrake/samba-3.0-smbmount-sbin.patch
deleted file mode 100644
index 586fb3cff9c..00000000000
--- a/packaging/Mandrake/samba-3.0-smbmount-sbin.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- samba-3.0alpha1/source/client/smbmount.c.orig Fri Nov 30 02:29:22 2001
-+++ samba-3.0alpha1/source/client/smbmount.c Thu Dec 6 00:48:57 2001
-@@ -468,7 +468,7 @@
- if (sys_fork() == 0) {
- char *smbmnt_path;
-
-- asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
-+ asprintf(&smbmnt_path, "%s/smbmnt", dyn_SBINDIR);
-
- if (file_exist(smbmnt_path, NULL)) {
- execv(smbmnt_path, args);
diff --git a/packaging/Mandrake/samba-print-pdf.sh b/packaging/Mandrake/samba-print-pdf.sh
index 973bb4f90ee..4f500569bc5 100644
--- a/packaging/Mandrake/samba-print-pdf.sh
+++ b/packaging/Mandrake/samba-print-pdf.sh
@@ -5,20 +5,7 @@
# and turn it into a PDF, informing the user of where it is when it
# is done
#
-# (c) Buchan Milne <bgmilne@cae.co.za> 2002
-# License: GPLv2
-# Changelog
-# v0.0.6 20030428
-# - Allow options passed as env. variables from print command
-# - Inline and simplify sed (use tr) clean script
-# - Ensure file arrives in PREFIX even if TEMP is used without provided name
-# - Changes from Joshua M. Schmidlkofer <joshua@imr-net.com> 20030425
-# - Debugging, adjustments, and corrections.
-# - Stupid sed sanitizing script. [probably horribly inefficient also].
-# - Temp file usage cleanup.
-# v0.0.5 20020723
-# - Add support for preset settings
-# - Allow passing of filename provided by client as final filename
+# Buchan Milne <bgmilne@cae.co.za> 20020723
#
# Arguments:
# $1 = file (usually passed with %s from samba)
@@ -27,84 +14,53 @@
# $4 = user/computer to send a notification to (%u or %m)
# $5 = IP address of client (%I)
# $6 = Name of destination file without extension (%J)
-# $7 = PDF setting (prepress,print,screen etc)
-#
-# If you want to customise any of the following configuration defaults,
-# you can place them in the file /etc/samba/print-pdf.conf.
-# If you need to modify anything in this script, please provide me with your
-# changes, preferably in such a way that the changes are configurable.
+
PS2PDF=ps2pdf13
OPTIONS="-dAutoFilterColorImages=false -sColorImageFilter=FlateEncode"
-#Values taken from arguments:
INPUT=$1
+KEEP_PS=1
+PERMS=640
+INFILE=$(basename $INPUT)
+BASEFILE=pdf-service
PREFIX="$2"
+NAME="$6"
WINBASE=$(echo "$3"|sed -e 's,/,\\\\,g')
-#NAME=`echo "$6"|sed -e 's/[&/:{}\\\[<>$#@*^!?=|]/-/g;s/\]/-/g'`
-NAME=`echo "$6"|tr '[:punct:]' '[-*]'`
-
-# Source config file if it exists:
-CONFFILE=/etc/samba/print-pdf.conf
-[ -e $CONFFILE ] && . $CONFFILE
-
-#Values not taken as arguments, could be set via env. vars (?) or config file
-KEEP_PS=${KEEP_PS=0}
-PERMS=${PERMS=640}
-BASEFILE=${BASEFILE=pdf-service}
-TEMP="${TEMP=$2}"
-UMASK=${UMASK=006}
-
-#Make sure that destination directory exists
-mkdir -p "$PREFIX"
-
-INFILE=$(basename $INPUT)
-
-umask $UMASK
-
-[ -n "$NAME" ] && TEMP="$PREFIX"
#make a temp file to use for the output of the PDF
-OUTPUT=`mktemp -q $TEMP/$BASEFILE-XXXXXX`
+OUTPUT=`mktemp -q $2/$BASEFILE-XXXXXX`
if [ $? -ne 0 ]; then
- echo "$0: Can't create temp file $TEMP/$OUTPUT, exiting..."
+ echo "$0: Can't create temp file $2/$BASEFILE-XXXXXX, exiting..."
exit 1
fi
-if [ -n "$NAME" ]; then
+if [ "$NAME" != "" ]; then
FINALOUTPUT="$PREFIX/$NAME"
else
FINALOUTPUT="$OUTPUT"
fi
-if [ -n "$7" ]; then
- OPTIONS="$OPTIONS -dPDFSETTINGS=/${7#pdf-}"
-else
- OPTIONS="$OPTIONS -dPDFSETTINGS=/default"
-fi
-
+
WIN_OUTPUT="$WINBASE\\"`basename "$FINALOUTPUT"`
-#mv "$INPUT" "$INPUT.ps";INPUT="$INPUT.ps"
-# create the pdf
-$PS2PDF $OPTIONS "$INPUT" "$OUTPUT.pdf" >/dev/null 2>&1
-mv -f "${OUTPUT}.pdf" "${FINALOUTPUT}".pdf
+# create the PDF:
+$PS2PDF $OPTIONS $INPUT "$OUTPUT".pdf >/dev/null 2>&1
+mv -f "$OUTPUT".pdf "$FINALOUTPUT".pdf
# Generate a message to send to the user, and deal with the original file:
MESSAGE=$(echo "Your PDF file has been created as $WIN_OUTPUT.pdf\n")
-
-# Cleanup
-if [ $KEEP_PS != 0 ];then
+if [ $KEEP_PS ];then
mv -f $INPUT "${FINALOUTPUT}".ps
MESSAGE=$(echo "$MESSAGE and your postscript file as $WIN_OUTPUT.ps")
# Fix permissions on the generated files
- chmod $PERMS "${FINALOUTPUT}".ps "${FINALOUTPUT}".pdf
+ chmod $PERMS "${FINALOUTPUT}".ps
else
rm -f $INPUT
+ chmod $PERMS "${FINALOUTPUT}".ps "${FINALOUTPUT}".pdf
# Fix permissions on the generated files
- chmod $PERMS "${FINALOUTPUT}".pdf
fi
-
+
#Remove empty file from mktemp:
-rm -f $OUTPUT
+[ "x$NAME" -eq "x" ] && rm -f $OUTPUT
# Send notification to user
echo -e $MESSAGE|smbclient -M $4 -I $5 -U "PDF Generator" >/dev/null 2>&1
diff --git a/packaging/Mandrake/samba.pamd b/packaging/Mandrake/samba.pamd
index 30912de1726..27eeb99e32a 100644
--- a/packaging/Mandrake/samba.pamd
+++ b/packaging/Mandrake/samba.pamd
@@ -3,3 +3,4 @@ auth required /lib/security/pam_nologin.so
auth required /lib/security/pam_stack.so service=system-auth
account required /lib/security/pam_stack.so service=system-auth
session required /lib/security/pam_stack.so service=system-auth
+password required /lib/security/pam_stack.so service=system-auth
diff --git a/packaging/Mandrake/samba2.spec.tmpl b/packaging/Mandrake/samba2.spec.tmpl
index 127aee48d8e..7b492239b72 100644
--- a/packaging/Mandrake/samba2.spec.tmpl
+++ b/packaging/Mandrake/samba2.spec.tmpl
@@ -1,68 +1,41 @@
-# Note that this file exists in Mandrake packaging cvs (as samba3.spec)
-# and samba cvs (as packaging/Mandrake/samba2.spec.tmpl).
-# Keep in mind that any changes should take both locations into account
-# Considerable effort has gone into making this possible, so that only
-# one spec file is maintained, please don't break it.
-# It should be possible, without any changes to this file, to build
-# binary packages on most recent Mandrake releases:
-# 1)from official source releases, using 'cd packaging/Mandrake; sh makerpms.sh'
-# 2)from cvs snapshots, using 'cd packaging/Mandrake; sh makerpms-cvs.sh <ver>'
-# 3)using official source releases and updated Mandrake packaging, by
-# 'rpm -ba samba.spec'
-# As such, any sources or patches used in a build from a samba release or
-# cvs should be submitted for inclusion in samba cvs.
-
-%define pkg_name samba
-%define ver 3.0.1pre3
-%define rel 5mdk
-%define vscanver 0.3.3beta1
-%define libsmbmajor 0
-
-%{!?lib: %global lib lib}
-%{!?mklibname: %global mklibname(ds) %lib%{1}%{?2:%{2}}%{?3:_%{3}}%{-s:-static}%{-d:-devel}}
-
-%define libname %mklibname smbclient %libsmbmajor
-
-# Version and release replaced by samba-team at release from samba cvs
+%define ver 2.2.7a
+%define rel 4mdk
+%define vscanver 0.3.1
+
+# 2.2.4 and 1 replace by samba-team at release
%define pversion PVERSION
%define prelease PRELEASE
+# For testing this setup:
+#%define pversion1 2.2.5
+#%define prelease1 %(date +%Y%m%d)
#Check to see if p(version|release) has been replaced (1 if replaced)
%define have_pversion %(if [ "%pversion" = `echo "pversion" |tr '[:lower:]' '[:upper:]'` ];then echo 0; else echo 1; fi)
%define have_prelease %(if [ "%prelease" = `echo "prelease" |tr '[:lower:]' '[:upper:]'` ];then echo 0; else echo 1; fi)
-%if %have_pversion
-%define source_ver %{pversion}
-# Don't abort for stupid reasons on builds from tarballs:
-%global _unpackaged_files_terminate_build 0
-%global _missing_doc_files_terminate_build 0
-%else
-%define source_ver %{ver}
-%endif
-
-# We might have a prerelease:
-%define have_pre %(echo %source_ver|awk '{p=0} /[a-z,A-Z][a-z,A-Z]/ {p=1} {print p}')
+# We might have a alpha-/beta-/pre-/rc-release:
+%define have_pre %(echo %pversion|awk '{p=0} /[a-z,A-Z][a-z,A-Z]/ {p=1} {print p}')
%if %have_pre
-%define pre_ver %(perl -e '$name="%source_ver"; print ($name =~ /(.*?)[a-z]/);')
-%define pre_pre %(echo %source_ver|sed -e 's/%pre_ver//g')
+%define pre_ver %(perl -e '$name="%pversion"; print ($name =~ /(.*?)[a-z]/);')
+%define pre_pre %(echo %pversion|sed -e 's/%pre_ver//g')
%endif
+
# Check to see if we are running a build from a tarball release from samba.org
# (%have_pversion) If so, disable vscan, unless explicitly requested
# (--with vscan).
-%define build_vscan 1
+%define build_vscan 1
%if %have_pversion
-%define build_vscan 0
+%define build_vscan 0
%{?_with_vscan: %define build_vscan 1}
%endif
# We now do detection of the Mandrake release we are building on:
#%define build_cooker %(if [ `awk '{print $3}' /etc/mandrake-release` = "Cooker" ];then echo 1; else echo 0; fi)
#%define build_cooker %(if [[ `cat /etc/mandrake-release|grep Cooker` ]];then echo 1; else echo 0; fi)
-%define build_mdk100 %(if [ `awk '{print $4}' /etc/mandrake-release` = 10.0 ];then echo 1; else echo 0; fi)
-%define build_mdk92 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.2 ];then echo 1; else echo 0; fi)
%define build_mdk91 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.1 ];then echo 1; else echo 0; fi)
%define build_mdk90 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.0 ];then echo 1; else echo 0; fi)
+%define build_mdk83 %(if [ `awk '{print $4}' /etc/mandrake-release` = 8.3 ];then echo 1; else echo 0; fi)
%define build_mdk82 %(if [ `awk '{print $4}' /etc/mandrake-release` = 8.2 ];then echo 1; else echo 0; fi)
%define build_mdk81 %(if [ `awk '{print $4}' /etc/mandrake-release` = 8.1 ];then echo 1; else echo 0; fi)
%define build_mdk80 %(if [ `awk '{print $4}' /etc/mandrake-release` = 8.0 ];then echo 1; else echo 0; fi)
@@ -70,117 +43,94 @@
%define build_non_default 0
# Default options
-%define build_alternatives 0
-%define build_system 0
%define build_acl 1
%define build_winbind 1
%define build_wins 1
%define build_ldap 0
-%define build_ads 1
%define build_scanners 0
-# CUPS supports functionality for 'printcap name = cups' (9.0 and later):
-%define build_cupspc 0
-# %_{pre,postun}_service are provided by rpm-helper in 9.0 and later
-%define have_rpmhelper 1
# Set defaults for each version
-%if %build_mdk100
-%define build_system 1
-%define build_alternatives 1
-%define build_cupspc 1
-%endif
-
-%if %build_mdk92
-%define build_alternatives 1
-%define build_cupspc 1
-%endif
-
%if %build_mdk91
-%define build_cupspc 1
+%define build_ldap 0
%endif
%if %build_mdk90
+%define build_ldap 0
+%endif
+
+%if %build_mdk83
+%define build_ldap 0
%endif
%if %build_mdk82
-%define have_rpmhelper 0
+%define build_ldap 0
%endif
%if %build_mdk81
-%define build_winbind 0
-%define build_wins 0
-%define have_rpmhelper 0
+%define build_winbind 0
+%define build_wins 0
+%define build_ldap 0
%endif
%if %build_mdk80
-%define build_acl 0
-%define build_winbind 0
-%define build_wins 0
-%define build_ads 0
-%define have_rpmhelper 1
+%define build_acl 0
+%define build_winbind 0
+%define build_wins 0
+%define build_ldap 0
%endif
%if %build_mdk72
-%define build_acl 0
-%define build_winbind 0
-%define build_wins 0
-%define build_ads 0
-%define have_rpmhelper 1
+%define build_acl 0
+%define build_winbind 0
+%define build_wins 0
+%define build_ldap 0
%endif
-
# Allow commandline option overrides (borrowed from Vince's qmail srpm):
# To use it, do rpm [-ba|--rebuild] --with 'xxx'
# Check if the rpm was built with the defaults, otherwise we inform the user
-%define build_non_default 0
-%{?_with_system: %global build_system 1}
-%{?_without_system: %global build_system 0}
-%{?_with_acl: %global build_acl 1}
-%{?_with_acl: %global build_non_default 1}
-%{?_without_acl: %global build_acl 0}
-%{?_without_acl: %global build_non_default 1}
-%{?_with_winbind: %global build_winbind 1}
-%{?_with_winbind: %global build_non_default 1}
-%{?_without_winbind: %global build_winbind 0}
-%{?_without_winbind: %global build_non_default 1}
-%{?_with_wins: %global build_wins 1}
-%{?_with_wins: %global build_non_default 1}
-%{?_without_wins: %global build_wins 0}
-%{?_without_wins: %global build_non_default 1}
-%{?_with_ldap: %global build_ldap 1}
-%{?_with_ldap: %global build_non_default 1}
-%{?_without_ldap: %global build_ldap 0}
-%{?_without_ldap: %global build_non_default 1}
-%{?_with_ads: %global build_ads 1}
-%{?_with_ads: %global build_non_default 1}
-%{?_without_ads: %global build_ads 0}
-%{?_without_ads: %global build_non_default 1}
-%{?_with_scanners: %global build_scanners 1}
-%{?_with_scanners: %global build_non_default 1}
+%{?_with_acl: %{expand: %%define build_acl 1}}
+%{?_with_acl: %{expand: %%define build_non_default 1}}
+%{?_without_acl: %{expand: %%define build_acl 0}}
+%{?_without_acl: %{expand: %%define build_non_default 1}}
+%{?_with_winbind: %{expand: %%global build_winbind 1}}
+%{?_with_winbind: %{expand: %%define build_non_default 1}}
+%{?_without_winbind: %{expand: %%global build_winbind 0}}
+%{?_without_winbind: %{expand: %%define build_non_default 1}}
+%{?_with_wins: %{expand: %%global build_wins 1}}
+%{?_with_wins: %{expand: %%define build_non_default 1}}
+%{?_without_wins: %{expand: %%global build_wins 0}}
+%{?_without_wins: %{expand: %%define build_non_default 1}}
+%{?_with_ldap: %{expand: %%global build_ldap 1}}
+%{?_with_ldap: %{expand: %%define build_non_default 1}}
+%{?_without_ldap: %{expand: %%global build_ldap 0}}
+%{?_without_ldap: %{expand: %%define build_non_default 1}}
+%{?_with_scanners: %{expand: %%define build_scanners 1}}
+%{?_with_scanners: %{expand: %%define build_non_default 1}}
# As if that weren't enough, we're going to try building with antivirus
# support as an option also
-%define build_fprot 0
+%define build_fprot 0
%define build_kaspersky 0
-%define build_mks 0
-%define build_openav 0
-%define build_sophos 0
-%define build_symantec 0
+%define build_mks 0
+%define build_openantivirus 0
+%define build_sophos 0
+%define build_symantec 0
%define build_trend 0
%if %build_vscan && %build_scanners
#These can be enabled here by default
# (kaspersky requires their library present)
-%define build_fprot 1
-%define build_mks 1
-%define build_openav 1
-%define build_sophos 1
-%define build_trend 1
+%define build_fprot 1
+%define build_mks 1
+%define build_openantivirus 1
+%define build_sophos 1
+%define build_trend 1
%endif
%if %build_vscan
%{?_with_fprot: %{expand: %%global build_fprot 1}}
%{?_with_kaspersky: %{expand: %%global build_kaspersky 1}}
%{?_with_mks: %{expand: %%global build_mks 1}}
-%{?_with_openav: %{expand: %%global build_openav 1}}
+%{?_with_openav: %{expand: %%global build_openantivirus 1}}
%{?_with_sophos: %{expand: %%global build_sophos 1}}
#%{?_with_symantec: %{expand: %%global build_symantec 1}}
%{?_with_trend: %{expand: %%global build_trend 1}}
@@ -188,100 +138,69 @@
%endif
%global vfsdir examples.bin/VFS
-#Standard texts for descriptions:
-%define message_bugzilla() %(echo -e -n "Please file bug reports for this package at Mandrake bugzilla \\n(http://qa.mandrakesoft.com) under the product name %{1}")
-%define message_system %(echo -e -n "NOTE: These packages of samba-%{version}, are provided, parallel installable\\nwith samba-2.2.x, to allow easy migration from samba-2.2.x to samba-%{version},\\nbut are not officially supported")
-
-#check gcc version to disable some optimisations on gcc-3.3.1
-%define gcc331 %(gcc -dumpversion|awk '{if ($1>3.3) print 1; else print 0}')
-
-#Define sets of binaries that we can use in globs and loops:
-%global commonbin net,ntlm_auth,rpcclient,smbcacls,smbcquotas,smbpasswd,smbtree,testparm,testprns
-
-%global serverbin editreg,pdbedit,profiles,smbcontrol,smbstatus,tdbbackup,tdbdump
-%global serversbin nmbd,samba,smbd,mkntpwd
-
-%global clientbin findsmb,nmblookup,smbclient,smbmnt,smbmount,smbprint,smbspool,smbtar,smbumount
-%global client_bin mount.cifs
-%global client_sbin mount.smb,mount.smbfs
-
-%global testbin debug2html,smbtorture,msgtest,masktest,locktest,locktest2,nsstest,vfstest
-
-%ifarch alpha
-%define build_expsam xml
-%else
-%define build_expsam mysql,xml
-%endif
-
#Workaround missing macros in 8.x:
%{!?perl_vendorlib: %{expand: %%global perl_vendorlib %{perl_sitearch}/../}}
-# Determine whether this is the system samba or not.
-%if %build_system
-%define samba_major %{nil}
-%else
-%define samba_major 3
-%endif
-# alternatives_major is %{nil} if we aren't system and not using alternatives
-%if !%build_system || %build_alternatives
-%define alternative_major 3
-%else
-%define alternative_major %{nil}
-%endif
-
Summary: Samba SMB server.
-Name: %{pkg_name}%{samba_major}
-
-%if %have_pre
+Name: samba
+%if %have_pversion && %have_pre
Version: %{pre_ver}
-%else
-Version: %{source_ver}
+%define source_ver %{pversion}
+%endif
+%if %have_pversion && !%have_pre
+Version: %{pversion}
+%define source_ver %{pversion}
+%endif
+%if !%have_pversion
+Version: %{ver}
+%define source_ver %{ver}
%endif
-
%if %have_prelease && !%have_pre
Release: 1.%{prelease}mdk
%endif
%if %have_prelease && %have_pre
-Release: 0.%{pre_pre}.%{prelease}mdk
+Release: 1.0.%{pre_pre}.%{prelease}mdk
%endif
-%if !%have_prelease && !%have_pre
+%if !%have_prelease
Release: %{rel}
%endif
-%if !%have_prelease && %have_pre
-Release: 0.%{pre_pre}.%{rel}
-%endif
-
License: GPL
+URL: http://www.samba.org
Group: System/Servers
Source: ftp://samba.org/pub/samba/samba-%{source_ver}.tar.bz2
-URL: http://www.samba.org
Source1: samba.log
+Source2: mount.smb
Source3: samba.xinetd
-Source4: swat_48.png.bz2
-Source5: swat_32.png.bz2
-Source6: swat_16.png.bz2
+Source4: swat_48.xpm.bz2
+Source5: swat_32.xpm.bz2
+Source6: swat_16.xpm.bz2
Source7: README.%{name}-mandrake-rpm
%if %build_vscan
Source8: samba-vscan-%{vscanver}.tar.bz2
%endif
Source10: samba-print-pdf.sh.bz2
Patch1: smbw.patch.bz2
-Patch4: samba-3.0-smbmount-sbin.patch.bz2
+Patch2: samba-2.2.0-gawk.patch.bz2
+Patch3: samba-2.2.0-buildroot.patch.bz2
+Patch4: smbmount-sbin.patch.bz2
+Patch5: samba-2.2.5-gp-reloc-fix.patch.bz2
+Patch6: samba-2.2.7a-smbldaptools-paths.patch.bz2
%if !%have_pversion
# Version specific patches: current version
+Patch101: samba-2.2.7a-smbtar-large-file-fix.patch.bz2
+Patch102: samba-2.2.7a-smbclient-large-file-fix.patch.bz2
+Patch103: samba-2.2.7a-ldap-rebind.patch.bz2
+Patch104: samba-2.2.7a-mandrake-packaging.patch.bz2
+Patch105: samba-2.2.6-smbumount_lazy.patch.bz2
%else
# Version specific patches: upcoming version
%endif
-# Limbo patches (applied to prereleases, but not preleases, ie destined for
+# Limbo patches (applied to prereleases, but not preleases, ie destined for
# samba CVS)
%if %have_pversion && %have_pre
%endif
Requires: pam >= 0.64, samba-common = %{version}
-BuildRequires: pam-devel readline-devel libncurses-devel popt-devel
-BuildRequires: libxml2-devel
-%ifnarch alpha
-BuildRequires: mysql-devel
-%endif
+BuildRequires: pam-devel autoconf readline-devel libldap2-devel popt-devel
%if %build_acl
BuildRequires: libacl-devel
%endif
@@ -290,11 +209,10 @@ BuildRequires: cups-devel
%else
BuildRequires: libcups-devel
%endif
-BuildRequires: libldap-devel
-%if %build_ads
-BuildRequires: libldap-devel krb5-devel
-%endif
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
+#%if %build_ldap
+#BuildRequires: libldap-devel
+#%endif
+BuildRoot: %{_tmppath}/%{name}-root
Prefix: /usr
Prereq: /sbin/chkconfig /bin/mktemp /usr/bin/killall
Prereq: fileutils sed /bin/grep
@@ -309,167 +227,148 @@ in Linux. Samba uses NetBIOS over TCP/IP (NetBT) protocols
and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
protocol.
-Samba-3.0 features working NT Domain Control capability and
+Samba-2.2 features working NT Domain Control capability and
includes the SWAT (Samba Web Administration Tool) that
allows samba's smb.conf file to be remotely managed using your
favourite web browser. For the time being this is being
enabled on TCP port 901 via xinetd. SWAT is now included in
it's own subpackage, samba-swat.
+Users are advised to use Samba-2.2 as a Windows NT4
+Domain Controller only on networks that do NOT have a Windows
+NT Domain Controller. This release does NOT as yet have
+Backup Domain control ability.
+
Please refer to the WHATSNEW.txt document for fixup information.
This binary release includes encrypted password support.
Please read the smb.conf file and ENCRYPTION.txt in the
docs directory for implementation details.
-%if %have_pversion
-%message_bugzilla samba3
-%endif
-%if !%build_system
-%message_system
-%endif
+
%if %build_non_default
WARNING: This RPM was built with command-line options. Please
see README.%{name}-mandrake-rpm in the documentation for
more information.
%endif
+%if %build_ldap
+%package server-ldap
+Summary: Samba (SMB) server programs with LDAP (only) support
+Obsoletes: samba-server
+Provides: samba-server
+Requires: samba-common-ldap = %{version}
+%else
%package server
-URL: http://www.samba.org
Summary: Samba (SMB) server programs.
-Requires: %{name}-common = %{version}
-%if %have_rpmhelper
-PreReq: rpm-helper
+Obsoletes: samba-server-ldap
+Requires: samba-common = %{version}
%endif
Group: Networking/Other
-%if %build_system
Provides: samba
Obsoletes: samba
-Provides: samba-server-ldap
-Obsoletes: samba-server-ldap
-Provides: samba3-server
-Obsoletes: samba3-server
-%else
-#Provides: samba-server
-%endif
+%if %build_ldap
+%description server-ldap
+%else
%description server
+%endif
Samba-server provides a SMB server which can be used to provide
network services to SMB (sometimes called "Lan Manager")
clients. Samba uses NetBIOS over TCP/IP (NetBT) protocols
and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
protocol.
-Samba-3.0 features working NT Domain Control capability and
+Samba-2.2 features working NT Domain Control capability and
includes the SWAT (Samba Web Administration Tool) that
allows samba's smb.conf file to be remotely managed using your
favourite web browser. For the time being this is being
enabled on TCP port 901 via xinetd. SWAT is now included in
it's own subpackage, samba-swat.
+Users are advised to use Samba-2.2 as a Windows NT4
+Domain Controller only on networks that do NOT have a Windows
+NT Domain Controller. This release does NOT as yet have
+Backup Domain control ability.
+
Please refer to the WHATSNEW.txt document for fixup information.
This binary release includes encrypted password support.
Please read the smb.conf file and ENCRYPTION.txt in the
docs directory for implementation details.
-%if %have_pversion
-%message_bugzilla samba3-server
-%endif
-%if !%build_system
-%message_system
+
+%if %build_ldap
+This package was compiled with LDAP support, which means that
+passwords can ONLY be stored in LDAP, not in smbpasswd files.
+To migrate your passwords from smbpasswd into LDAP, try
+examples/LDAP/import_smbpasswd.pl using:
+/usr/share/samba/scripts/import_smbpasswd.pl </etc/samba/smbpasswd
+
+Scripts for managing users in LDAP have been added to
+/usr/share/samba/scripts, configuration is in /etc/samba/smbldap_conf.pm
%endif
%package client
-URL: http://www.samba.org
Summary: Samba (SMB) client programs.
Group: Networking/Other
-Requires: %{name}-common = %{version}
-%if %build_alternatives
-#Conflicts: samba-client < 2.2.8a-9mdk
-%endif
-%if %build_system
-Provides: samba3-client
-Obsoletes: samba3-client
+Requires: samba-common = %{version}
Obsoletes: smbfs
-%else
-#Provides: samba-client
-%endif
-%if !%build_system && %build_alternatives
-Provides: samba-client
-%endif
%description client
Samba-client provides some SMB clients, which complement the built-in
SMB filesystem in Linux. These allow the accessing of SMB shares, and
printing to SMB printers.
-%if %have_pversion
-%message_bugzilla samba3-client
-%endif
-%if !%build_system
-%message_system
-%endif
+%if %build_ldap
+%package common-ldap
+Summary: Files used by both Samba servers and clients with LDAP support
+Obsoletes: samba-common
+Provides: samba-common
+%else
%package common
-URL: http://www.samba.org
Summary: Files used by both Samba servers and clients.
-Group: System/Servers
-%if %build_system
-Provides: samba-common-ldap
Obsoletes: samba-common-ldap
-Provides: samba3-common
-Obsoletes: samba3-common
-%else
-#Provides: samba-common
%endif
+Group: System/Servers
+%if %build_ldap
+%description common-ldap
+%else
%description common
+%endif
Samba-common provides files necessary for both the server and client
packages of Samba.
-%if %have_pversion
-%message_bugzilla samba3-common
-%endif
-%if !%build_system
-%message_system
-%endif
%package doc
-URL: http://www.samba.org
Summary: Documentation for Samba servers and clients.
Group: System/Servers
-Requires: %{name}-common = %{version}
-%if %build_system
-Obsoletes: samba3-doc
-Provides: samba3-doc
-%else
-#Provides: samba-doc
-%endif
+Requires: samba-common = %{version}
%description doc
Samba-doc provides documentation files for both the server and client
packages of Samba.
-%if %have_pversion
-%message_bugzilla samba3-doc
-%endif
-%if !%build_system
-%message_system
-%endif
+%if %build_ldap
+%package swat-ldap
+Summary: The Samba Web Administration Tool (with LDAP support)
+Obsoletes: samba-swat
+Provides: samba-swat
+Requires: samba-server-ldap = %{version}
+%else
%package swat
-URL: http://www.samba.org
Summary: The Samba Web Administration Tool.
-Requires: %{name}-server = %{version}
-Requires: xinetd
-Group: System/Servers
-%if %build_system
-Provides: samba-swat-ldap
Obsoletes: samba-swat-ldap
-Provides: samba3-swat
-Obsoletes: samba3-swat
-%else
-#Provides: samba-swat
+Requires: samba-server = %{version}
%endif
+Requires: xinetd
+Group: System/Servers
+Provides: samba-swat swat
+%if %build_ldap
+%description swat-ldap
+%else
%description swat
-SWAT (the Samba Web Administration Tool) allows samba's smb.conf file
+%endif
+SWAT (the Samba Web Administration Tool) allows the samba smb.conf file
to be remotely managed using your favourite web browser. For the time
being this is being enabled on TCP port 901 via xinetd. Note that
SWAT does not use SSL encryption, nor does it preserve comments in
@@ -477,192 +376,53 @@ your smb.conf file. Webmin uses SSL encryption by default, and
preserves comments in configuration files, even if it does not display
them, and is therefore the preferred method for remotely managing
Samba.
-%if %have_pversion
-%message_bugzilla samba3-swat
+
+
+%if %build_winbind && %build_ldap
+%package winbind-ldap
+Requires: samba-common-ldap = %{version}
+Obsoletes: samba-winbind
+Provides: samba-winbind
%endif
-%if !%build_system
-%message_system
+%if %build_winbind && !%build_ldap
+%package winbind
+Requires: samba-common = %{version}
+Obsoletes: samba-winbind-ldap
%endif
-
%if %build_winbind
-%package winbind
-URL: http://www.samba.org
Summary: Samba-winbind daemon, utilities and documentation
Group: System/Servers
-Requires: %{name}-common = %{version}
+Provides: winbind samba-winbind
%endif
-%if %build_winbind && !%build_system
-Conflicts: samba-winbind
+%if %build_winbind && %build_ldap
+%description winbind-ldap
%endif
-%if %build_winbind
+%if %build_winbind && !%build_ldap
%description winbind
-Provides the winbind daemon and testing tools to allow authentication
-and group/user enumeration from a Windows or Samba domain controller.
%endif
-%if %have_pversion
-%message_bugzilla samba3-winbind
-%endif
-%if !%build_system
-%message_system
+%if %build_winbind
+Provides the winbind daemon and testing tools to allow authentication
+and group/user enumeration from a Windows or Samba domain controller.
%endif
%if %build_wins
-%package -n nss_wins%{samba_major}
-URL: http://www.samba.org
+%package -n nss_wins
Summary: Name Service Switch service for WINS
Group: System/Servers
-Requires: %{name}-common = %{version}
+Requires: samba-common = %{version}
PreReq: glibc
-%endif
-%if %build_wins && !%build_system
-Conflicts: nss_wins
-%endif
-%if %build_wins
-%description -n nss_wins%{samba_major}
-Provides the libnss_wins shared library which resolves NetBIOS names to
+%description -n nss_wins
+Provides the libnss_wins shared library which resolves NetBIOS names to
IP addresses.
%endif
-%if %have_pversion
-%message_bugzilla nss_wins3
-%endif
-%if !%build_system
-%message_system
-%endif
-
-%if %{?_with_test:1}%{!?_with_test:0}
-%package test
-URL: http://www.samba.org
-Summary: Debugging and benchmarking tools for samba
-Group: System/Servers
-Requires: %{name}-common = %{version}
-%endif
-%if %build_system && %{?_with_test:1}%{!?_with_test:0}
-Provides: samba3-test samba3-debug
-Obsoletes: samba3-test samba3-debug
-%endif
-%if !%build_system && %{?_with_test:1}%{!?_with_test:0}
-Provides: samba-test samba3-debug
-Obsoletes: samba3-debug
-%endif
-%if %{?_with_test:1}%{!?_with_test:0}
-
-%description test
-This package provides tools for benchmarking samba, and debugging
-the correct operation of tools against smb servers.
-%endif
-
-%if %build_system
-%package -n %{libname}
-URL: http://www.samba.org
-Summary: SMB Client Library
-Group: System/Libraries
-Provides: libsmbclient
-
-%description -n %{libname}
-This package contains the SMB client library, part of the samba
-suite of networking software, allowing other software to access
-SMB shares.
-%endif
-%if %have_pversion && %build_system
-%message_bugzilla %{libname}
-%endif
-
-%if %build_system
-%package -n %{libname}-devel
-URL: http://www.samba.org
-Summary: SMB Client Library Development files
-Group: System/Libraries
-Provides: libsmbclient-devel
-Requires: %{libname} = %{version}-%{release}
-
-%description -n %{libname}-devel
-This package contains the development files for the SMB client
-library, part of the samba suite of networking software, allowing
-the development of other software to access SMB shares.
-%endif
-%if %have_pversion && %build_system
-%message_bugzilla %{libname}-devel
-%endif
-
-%if %build_system
-%package -n %{libname}-static-devel
-URL: http://www.samba.org
-Summary: SMB Client Static Library Development files
-Group: System/Libraries
-Provides: libsmbclient-static-devel = %{version}-%{release}
-Requires: %{libname}-devel = %{version}-%{release}
-
-%description -n %{libname}-static-devel
-This package contains the static development files for the SMB
-client library, part of the samba suite of networking software,
-allowing the development of other software to access SMB shares.
-%endif
-%if %have_pversion && %build_system
-%message_bugzilla %{libname}-devel
-%endif
-
-#%package passdb-ldap
-#URL: http://www.samba.org
-#Summary: Samba password database plugin for MySQL
-#Group: System/Libraries
-#
-#%description passdb-ldap
-#The passdb-ldap package for samba provides a password database
-#backend allowing samba to store account details in an LDAP
-#database
-#_if %have_pversion
-#_message_bugzilla samba3-passdb-ldap
-#_endif
-#_if !%build_system
-#_message_system
-#_endif
-
-%ifnarch alpha
-%package passdb-mysql
-URL: http://www.samba.org
-Summary: Samba password database plugin for MySQL
-Group: System/Libraries
-Requires: %{name}-server = %{version}-%{release}
-%endif
-%ifnarch alpha && %build_system
-Obsoletes: samba3-passdb-mysql
-Provides: samba3-passdb-mysql
-%endif
-%ifnarch alpha
-
-%description passdb-mysql
-The passdb-mysql package for samba provides a password database
-backend allowing samba to store account details in a MySQL
-database
-%endif
-
-%package passdb-xml
-URL: http://www.samba.org
-Summary: Samba password database plugin for XML files
-Group: System/Libraries
-Requires: %{name}-server = %{version}-%{release}
-%if %build_system
-Obsoletes: samba3-passdb-xml
-Provides: samba3-passdb-xml
-%endif
-
-%description passdb-xml
-The passdb-xml package for samba provides a password database
-backend allowing samba to store account details in XML files.
-%if %have_pversion
-%message_bugzilla samba3-passdb-xml
-%endif
-%if !%build_system
-%message_system
-%endif
#Antivirus packages:
%if %build_fprot
%package vscan-fprot
Summary: On-access virus scanning for samba using FPROT
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-fprot
A vfs-module for samba to implement on-access scanning using the
@@ -673,8 +433,8 @@ FPROT antivirus software (which must be installed to use this).
%package vscan-kaspersky
Summary: On-access virus scanning for samba using Kaspersky
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-kaspersky
A vfs-module for samba to implement on-access scanning using the
@@ -685,22 +445,22 @@ Kaspersky antivirus software (which must be installed to use this).
%package vscan-mks
Summary: On-access virus scanning for samba using MKS
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-mks
A vfs-module for samba to implement on-access scanning using the
MKS antivirus software (which must be installed to use this).
%endif
-%if %build_openav
-%package vscan-openav
+%if %build_openantivirus
+%package vscan-openantivirus
Summary: On-access virus scanning for samba using OpenAntivirus
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
-%description vscan-openav
+%description vscan-openantivirus
A vfs-module for samba to implement on-access scanning using the
OpenAntivirus antivirus software (which must be installed to use this).
%endif
@@ -709,8 +469,8 @@ OpenAntivirus antivirus software (which must be installed to use this).
%package vscan-sophos
Summary: On-access virus scanning for samba using Sophos
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-sophos
A vfs-module for samba to implement on-access scanning using the
@@ -721,8 +481,8 @@ Sophos antivirus software (which must be installed to use this).
%package vscan-symantec
Summary: On-access virus scanning for samba using Symantec
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-symantec
A vfs-module for samba to implement on-access scanning using the
@@ -733,8 +493,8 @@ Symantec antivirus software (which must be installed to use this).
%package vscan-trend
Summary: On-access virus scanning for samba using Trend
Group: System/Servers
-Requires: %{name}-server = %{version}
-Provides: %{name}-vscan
+Requires: samba = %{version}
+Provides: samba-vscan
Autoreq: 0
%description vscan-trend
A vfs-module for samba to implement on-access scanning using the
@@ -742,59 +502,29 @@ Trend antivirus software (which must be installed to use this).
%endif
%prep
-
-# Allow users to query build options with --with options:
-#%define opt_status(%1) %(echo %{1})
-%if %{?_with_options:1}%{!?_with_options:0}
-%define opt_status(%{1}) %(if [ %{1} -eq 1 ];then echo enabled;else echo disabled;fi)
-#exit 1
-%{error: }
-%{error:Build options available are:}
-%{error:--with[out] system Build as the system samba package [or as samba3]}
-%{error:--with[out] acl Build with support for file ACLs - %opt_status %build_acl}
-%{error:--with[out] winbind Build with Winbind support - %opt_status %build_winbind}
-%{error:--with[out] wins Build with WINS name resolution support - %opt_status %build_wins}
-%{error:--with[out] ldap Build with legacy (samba2) LDAP support - %opt_status %build_ldap}
-%{error:--with[out] ads Build with Active Directory support - %opt_status %build_ads}
-%{error:--with[out] scanners Enable on-access virus scanners - %opt_status %build_scanners}
-%{error: }
+# Build a summary of how this RPM was built:
+%if %build_acl
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --with acl"
%else
-%{error: }
-%{error: This rpm has build options available, use --with options to see them}
-%{error: }
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --without acl"
%endif
-
-%if %{?_with_options:1}%{!?_with_options:0} && %build_scanners
-%{error:--with scanners enables fprot,mks,openav,sophos and trend by default}
-%{error: }
-%{error:To enable others (requires development libraries for the scanner):}
-%{error:--with kaspersky Enable on-access scanning with Kaspersky - %opt_status %build_kaspersky}
-%{error: }
+%if %build_winbind
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --with winbind"
+%else
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --without winbind"
%endif
-
-%if %{?_with_options:1}%{!?_with_options:0}
-clear
-exit 1
+%if %build_wins
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --with wins"
+%else
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --without wins"
+%endif
+%if %build_ldap
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --with ldap"
+%else
+RPM_EXTRA_OPTIONS="$RPM_EXTRA_OPTIONS --without ldap"
%endif
-
%if %build_non_default
-RPM_EXTRA_OPTIONS="\
-%{?_with_system: --with system}\
-%{?_without_system: --without system}\
-%{?_with_acl: --with acl}\
-%{?_without_acl: --without acl}\
-%{?_with_winbind: --with winbind}\
-%{?_without_winbind: --without winbind}\
-%{?_with_wins: --with wins}\
-%{?_without_wins: --without wins}\
-%{?_with_ldap: --with ldap}\
-%{?_without_ldap: --without ldap}\
-%{?_with_ads: --with ads}\
-%{?_without_ads: --without ads}\
-%{?_with_scanners: --with scanners}\
-%{?_without_scanners: --without scanners}\
-"
echo "Building a non-default rpm with the following command-line arguments:"
echo "$RPM_EXTRA_OPTIONS"
echo "This rpm was built with non-default options, thus, to build ">%{SOURCE7}
@@ -807,16 +537,30 @@ echo -e "\n%{name}-%{version}-%{release}\n">>%{SOURCE7}
%endif
%if %build_vscan
-%setup -q -a 8 -n %{pkg_name}-%{source_ver}
+%setup -q -a 8 -n %{name}-%{source_ver}
%else
-%setup -q -n %{pkg_name}-%{source_ver}
+%setup -q -n %{name}-%{source_ver}
%endif
-#%patch111 -p1
+# Current patches
+echo "Applying patches for version: %{ver}"
%patch1 -p1 -b .smbw
-%patch4 -p1 -b .sbin
+%patch2 -p1 -b .gawk
+%patch3 -p1 -b .buildroot
+%patch4 -p1
+%patch5 -p1 -b .gp-reloc-fix
+%patch6 -p1
# Version specific patches: current version
%if !%have_pversion
echo "Applying patches for current version: %{ver}"
+(cd source/client
+%patch101 -p0 -b .lfs
+)
+( cd source
+%patch102 -p0 -b .lfs
+)
+%patch103 -p1 -b .ldap
+%patch104 -p1 -b .mdk
+%patch105 -p1
%else
# Version specific patches: upcoming version
echo "Applying patches for new versions: %{pversion}"
@@ -827,117 +571,72 @@ echo "Applying patches for new versions: %{pversion}"
echo "Appling patches which should only be applied to prereleases"
%endif
-# Fix quota compilation in glibc>2.3
-%if %build_mdk91 || %build_mdk92
-#grep "<linux/quota.h>" source/smbd/quotas.c >/dev/null && \
-perl -pi -e 's@<linux/quota.h>@<sys/quota.h>@' source/smbd/quotas.c
-%endif
-
cp %{SOURCE7} .
# Make a copy of examples so that we have a clean one for doc:
cp -a examples examples.bin
%if %build_vscan
+# put antivirus files in examples.bin/VFS/
+#for av in fprot kaspersky mks openantivirus sophos trend; do
+# [ -e %{vscandir}/$av ] && cp -a %{vscandir}/$av %{vfsdir}
+#done
cp -a %{vscandir} %{vfsdir}
#fix stupid directory names:
mv %{vfsdir}/%{vscandir}/openantivirus %{vfsdir}/%{vscandir}/oav
%endif
-# Inline replacement of config dir
-for av in fprot kaspersky mks oav sophos trend; do
- [ -e %{vfsdir}/%{vscandir}/$av/vscan-$av.h ] && perl -pi -e \
- 's,^#define PARAMCONF "/etc/samba,#define PARAMCONF "/etc/%{name},' \
- %{vfsdir}/%{vscandir}/$av/vscan-$av.h
-done
-#Inline edit vscan header:
-perl -pi -e 's/^# define SAMBA_VERSION_MAJOR 2/# define SAMBA_VERSION_MAJOR 3/g' %{vfsdir}/%{vscandir}/include/vscan-global.h
-
-# Edit some files when not building system samba:
-%if !%build_system
-perl -pi -e 's/%{pkg_name}/%{name}/g' source/auth/pampass.c
-%endif
-
-#remove cvs internal files from docs:
-find docs examples -name '.cvsignore' -exec rm -f {} \;
-
-#make better doc trees:
-mkdir -p clean-docs/samba-doc
-cp -a examples docs clean-docs/samba-doc
-mv -f clean-docs/samba-doc/examples/libsmbclient clean-docs/
-rm -Rf clean-docs/samba-doc/docs/{docbook,manpages,htmldocs,using_samba}
-ln -s %{_datadir}/swat%{samba_major}/using_samba/ clean-docs/samba-doc/docs/using_samba
-ln -sf %{_datadir}/swat%{samba_major}/help/ clean-docs/samba-doc/docs/htmldocs
%build
#%serverbuild
(cd source
-CFLAGS=`echo "$RPM_OPT_FLAGS"|sed -e 's/-g//g'`
-%if %gcc331
-#CFLAGS=`echo "$CFLAGS"|sed -e 's/-O2/-Os/g'`
-%endif
-# Don't use --with-fhs now, since it overrides libdir, it sets configdir,
-# lockdir,piddir logfilebase,privatedir and swatdir
-%configure --prefix=%{_prefix} \
- --sysconfdir=%{_sysconfdir}/%{name} \
- --localstatedir=/var \
- --libdir=%{_libdir}/%{name} \
- --with-privatedir=%{_sysconfdir}/%{name} \
- --with-lockdir=/var/cache/%{name} \
- --with-piddir=/var/run/%{name} \
- --with-swatdir=%{_datadir}/swat%{samba_major} \
- --with-configdir=%{_sysconfdir}/%{name} \
- --with-logfilebase=/var/log/%{name} \
-%if !%build_ads
- --with-ads=no \
-%endif
- --with-automount \
- --with-smbmount \
- --with-pam \
- --with-pam_smbpass \
-%if %build_ldap
- --with-ldapsam \
-%endif
- --with-tdbsam \
- --with-syslog \
- --with-quotas \
- --with-utmp \
- --with-manpages-langs=en \
+autoconf
+CPPFLAGS="-I/usr/include/openssl"; export CPPFLAGS
+CFLAGS="$RPM_OPT_FLAGS"
+%configure --prefix=%{prefix} \
+ --with-fhs \
+ --libdir=/etc/samba \
+ --sysconfdir=/etc/samba \
+ --localstatedir=/var \
+ --with-configdir=/etc/samba \
+ --with-codepagedir=/var/lib/samba/codepages \
+ --with-privatedir=/etc/samba \
+ --with-swatdir=%{prefix}/share/swat \
+ --with-smbmount \
+ --with-syslog \
+ --with-automount \
+ --with-pam \
+ --with-sendfile-support \
+ --with-pam_smbpass \
+ --with-vfs \
+ --with-utmp \
+ --with-msdfs \
+ --with-smbwrapper \
+ --with-libsmbclient \
%if %build_acl
- --with-acl-support \
+ --with-acl-support \
%endif
- --disable-mysqltest \
- --with-expsam=%build_expsam \
- --program-suffix=%{samba_major}
-# --with-shared-modules=pdb_ldap,idmap_ldap \
-# --with-manpages-langs=en,ja,pl \
-#_if !%build_system
-# --with-smbwrapper \
-#_endif
-# --with-nisplussam \
-# --with-fhs \
-
-#Fix the make file so we don't create debug information on 9.2
-%if %build_mdk92
-perl -pi -e 's/-g //g' Makefile
+%if %build_ldap
+ --with-ldapsam \
+ --with-winbind-ldap-hack \
%endif
+ --with-winbind-auth-challenge \
+ --with-quotas
-perl -pi -e 's|-Wl,-rpath,%{_libdir}||g;s|-Wl,-rpath -Wl,%{_libdir}||g' Makefile
-
-make proto_exists
-%make all libsmbclient smbfilter wins modules %{?_with_test: torture debug2html bin/log2pcap} bin/editreg client/mount.cifs
-
-
+#make CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" all
+make CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" \
+ all smbfilter smbwrapper smbcacls pam_smbpass nsswitch nsswitch/libnss_wins.so debug2html
# Build VFS modules (experimental)
-#cd ../%vfsdir
-#_configure --prefix=%{prefix} \
-# --mandir=%{prefix}/share/man
-#make
-#make CFLAGS="$RPM_OPT_FLAGS -I../../source -I../../source/include -I../../source/ubiqx \
-# -I../../source/smbwrapper -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE"
+cd ../%vfsdir
+%configure --prefix=%{prefix} \
+ --mandir=%{prefix}/share/man
+make
)
# Build mkntpasswd in examples/LDAP/ for smbldaptools
-make -C examples.bin/LDAP/smbldap-tools/mkntpwd
+(
+cd examples.bin/LDAP/smbldap-tools/mkntpwd
+make
+)
# Build antivirus vfs objects:
%if %build_fprot
@@ -947,16 +646,13 @@ echo "Building fprot"
%endif
%if %build_kaspersky
echo "Building Kaspersky"
-(cd %{vfsdir}/%{vscandir}/kavp
- perl -p -i -e "s|/usr/local/|/usr/|g" Makefile.KAV4
- make -f Makefile.KAV4
-)
+(cd %{vfsdir}/%{vscandir}/kaspersky;make)
%endif
%if %build_mks
echo "Building mks"
(cd %{vfsdir}/%{vscandir}/mks;make)
%endif
-%if %build_openav
+%if %build_openantivirus
echo "Building OpenAntivirus"
(cd %{vfsdir}/%{vscandir}/oav;make)
%endif
@@ -976,266 +672,312 @@ echo "Building Trend"
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT/etc/samba
+mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d,xinetd.d}
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+mkdir -p $RPM_BUILD_ROOT/%{prefix}/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/swat/{images,help,include,using_samba}
+mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/swat/using_samba/{figs,gifs}
+mkdir -p $RPM_BUILD_ROOT/%{_mandir}/{man1,man5,man7,man8}
+mkdir -p $RPM_BUILD_ROOT/var/cache/samba
+mkdir -p $RPM_BUILD_ROOT/var/log/samba
+mkdir -p $RPM_BUILD_ROOT/var/run/samba
+mkdir -p $RPM_BUILD_ROOT/var/spool/samba
+mkdir -p $RPM_BUILD_ROOT/var/lib/samba/{netlogon,profiles,printers}
+mkdir -p $RPM_BUILD_ROOT/var/lib/samba/printers/{W32X86,WIN40,W32ALPHA,W32MIPS,W32PPC}
+mkdir -p $RPM_BUILD_ROOT/var/lib/samba/codepages/src
+mkdir -p $RPM_BUILD_ROOT/lib/security
+mkdir -p $RPM_BUILD_ROOT%prefix/lib
+mkdir -p $RPM_BUILD_ROOT%{_libdir}/samba/vfs
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/samba/scripts
+
+# Install standard binary files
+
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool \
+ smbcacls smbclient smbmount smbumount smbsh wbinfo
+do
+ install -m755 source/bin/$i $RPM_BUILD_ROOT/%{prefix}/bin
+done
-#Ensure all docs are readable
-chmod a+r docs -R
-
-# Any entries here mean samba makefile is *really* broken:
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}
-mkdir -p $RPM_BUILD_ROOT/%{_datadir}
-mkdir -p $RPM_BUILD_ROOT%{_libdir}/%{name}/vfs
-
-(cd source
-make DESTDIR=$RPM_BUILD_ROOT LIBDIR=%{_libdir}/%{name} install installclientlib installmodules)
-
-install -m755 source/bin/editreg %{buildroot}/%{_bindir}
-
-#need to stay
-mkdir -p $RPM_BUILD_ROOT/{sbin,bin}
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/{logrotate.d,pam.d,xinetd.d}
-mkdir -p $RPM_BUILD_ROOT/%{_initrddir}
-mkdir -p $RPM_BUILD_ROOT/var/cache/%{name}
-mkdir -p $RPM_BUILD_ROOT/var/log/%{name}
-mkdir -p $RPM_BUILD_ROOT/var/run/%{name}
-mkdir -p $RPM_BUILD_ROOT/var/spool/%{name}
-mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/%{name}/{netlogon,profiles,printers}
-mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/%{name}/printers/{W32X86,WIN40,W32ALPHA,W32MIPS,W32PPC}
-mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/%{name}/codepages/src
-mkdir -p $RPM_BUILD_ROOT/%{_lib}/security
-mkdir -p $RPM_BUILD_ROOT%{_libdir}
-mkdir -p $RPM_BUILD_ROOT%{_libdir}/%{name}/vfs
-mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name}/scripts
-
-#smbwrapper and pam_winbind not handled by make, pam_smbpass.so doesn't build
-#install -m 755 source/bin/smbwrapper.so $RPM_BUILD_ROOT%{_libdir}/smbwrapper%{samba_major}.so
-install -m 755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass%{samba_major}.so
-install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so
-
-install -m755 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{_libdir}/libsmbclient.a
-pushd $RPM_BUILD_ROOT/%{_libdir}
-[ -f libsmbclient.so ] && mv -f libsmbclient.so libsmbclient.so.%{libsmbmajor}
-ln -sf libsmbclient.so.%{libsmbmajor} libsmbclient.so
-popd
-
-# smbsh forgotten
-#install -m 755 source/bin/smbsh $RPM_BUILD_ROOT%{_bindir}/
+install -m755 source/bin/smbwrapper.so $RPM_BUILD_ROOT%prefix/lib/smbwrapper.so
+install -m755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/lib/security/pam_smbpass.so
+install -m755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security/pam_winbind.so
+install -m755 source/bin/libsmbclient.so $RPM_BUILD_ROOT%prefix/lib/libsmbclient.so
# Install VFS modules
-#install -m755 %vfsdir/audit.so $RPM_BUILD_ROOT/%{_libdir}/samba/vfs
-#for i in block recycle
-#do
-# install -m755 %vfsdir/$i/$i.so $RPM_BUILD_ROOT/%{_libdir}/samba/vfs
-#done
+install -m755 %vfsdir/audit.so $RPM_BUILD_ROOT/%{_libdir}/samba/vfs
+for i in block recycle
+do
+ install -m755 %vfsdir/$i/$i.so $RPM_BUILD_ROOT/%{_libdir}/samba/vfs
+done
# Antivirus support:
# mkdir -p $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan
for av in fprot kavp mks oav sophos symantec trend; do
if [ -d %{vfsdir}/%{vscandir}/$av -a -e %{vfsdir}/%{vscandir}/$av/vscan-$av*.so ];then
cp %{vfsdir}/%{vscandir}/$av/vscan-$av*.so \
- $RPM_BUILD_ROOT%{_libdir}/%{name}/vfs/
+ $RPM_BUILD_ROOT%{_libdir}/samba/vfs/
cp %{vfsdir}/%{vscandir}/$av/vscan-$av*.conf \
$RPM_BUILD_ROOT%{_sysconfdir}/%{name}
fi
done
-
-#libnss_* not handled by make:
+
+for i in mksmbpasswd.sh smbtar convert_smbpasswd
+do
+ install -m755 source/script/$i $RPM_BUILD_ROOT/%{prefix}/bin
+done
+
+# Install secure binary files
+
+for i in smbd nmbd swat smbfilter debug2html smbmnt smbcontrol winbindd
+do
+ install -m755 source/bin/$i $RPM_BUILD_ROOT/%{prefix}/sbin
+done
+
+# Install level 1,5,7,8 man pages
+
+for mpl in 1 5 7 8;do
+ mp=$(ls docs/manpages/*.$mpl)
+ for i in $mp;do
+ install -m644 $i $RPM_BUILD_ROOT/%{_mandir}/man$mpl
+ done
+done
+
+# Install codepage source files
+
+for i in 437 737 775 850 852 857 861 862 866 932 936 949 950 1125 1251
+do
+ install -m644 source/codepages/codepage_def.$i $RPM_BUILD_ROOT/var/lib/samba/codepages/src
+done
+
+for i in 437 737 775 850 852 857 861 862 866 932 936 949 950 1125 1251 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-13 ISO8859-15 KOI8-R KOI8-U
+do
+ install -m644 source/codepages/CP$i.TXT $RPM_BUILD_ROOT/var/lib/samba/codepages/src
+done
+
+# Build codepage load files
+for i in 437 737 775 850 852 857 861 862 866 932 936 949 950 1125 1251; do
+ $RPM_BUILD_ROOT/%{prefix}/bin/make_smbcodepage c $i $RPM_BUILD_ROOT/var/lib/samba/codepages/src/codepage_def.$i $RPM_BUILD_ROOT/var/lib/samba/codepages/codepage.$i
+done
+
+# Build unicode load files
+for i in 437 737 775 850 852 857 861 862 866 932 936 949 950 1125 1251 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-13 ISO8859-15 KOI8-R KOI8-U; do
+ $RPM_BUILD_ROOT/%{prefix}/bin/make_unicodemap $i $RPM_BUILD_ROOT/var/lib/samba/codepages/src/CP$i.TXT $RPM_BUILD_ROOT/var/lib/samba/codepages/unicode_map.$i
+done
+rm -rf $RPM_BUILD_ROOT/var/lib/samba/codepages/src
+
# Install the nsswitch library extension file
for i in wins winbind; do
- install -m755 source/nsswitch/libnss_${i}.so $RPM_BUILD_ROOT/%{_lib}/libnss_${i}.so
+ install -m755 source/nsswitch/libnss_$i.so $RPM_BUILD_ROOT/lib
done
# Make link for wins and winbind resolvers
-( cd $RPM_BUILD_ROOT/%{_lib}; ln -s libnss_wins.so libnss_wins.so.2; ln -s libnss_winbind.so libnss_winbind.so.2)
+( cd $RPM_BUILD_ROOT/lib; ln -s libnss_wins.so libnss_wins.so.2; ln -s libnss_winbind.so libnss_winbind.so.2)
-%if %{?_with_test:1}%{!?_with_test:0}
-for i in {%{testbin}};do
- install -m755 source/bin/${i} $RPM_BUILD_ROOT/%{_bindir}/${i}%{samba_major}
-done
-%endif
+# Install SWAT helper files
+ for i in swat/help/*.html docs/htmldocs/*.html; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/help
+ done
+
+ for i in swat/images/*.gif; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/images
+ done
+
+ for i in swat/include/*.html; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/include
+ done
+
+# Install the O'Reilly "Using Samba" book
+
+ for i in docs/htmldocs/using_samba/*.html; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/using_samba
+ done
+
+ for i in docs/htmldocs/using_samba/gifs/*.gif; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/using_samba/gifs
+ done
+
+ for i in docs/htmldocs/using_samba/figs/*.gif; do
+ install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/using_samba/figs
+ done
# Install other stuff
-# install -m644 examples/VFS/recycle/recycle.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/
- install -m644 packaging/Mandrake/smbusers $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/smbusers
- install -m755 packaging/Mandrake/smbprint $RPM_BUILD_ROOT/%{_bindir}
- #install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT/usr/bin
- install -m755 packaging/Mandrake/findsmb $RPM_BUILD_ROOT/%{_bindir}
- install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_initrddir}/smb%{samba_major}
- install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_sbindir}/%{name}
- install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_initrddir}/winbind
-# install -m755 packaging/Mandrake/wrepld.init $RPM_BUILD_ROOT/%{_initrddir}/wrepld%{samba_major}
- install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_sbindir}/winbind
- install -m644 packaging/Mandrake/samba.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/%{name}
- install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind
+ install -m644 examples/VFS/recycle/recycle.conf $RPM_BUILD_ROOT/etc/samba/
+ install -m644 packaging/Mandrake/smb.conf $RPM_BUILD_ROOT/etc/samba/smb.conf
+ install -m644 packaging/Mandrake/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers
+ install -m755 packaging/Mandrake/smbprint $RPM_BUILD_ROOT/usr/bin
+ install -m755 packaging/Mandrake/findsmb $RPM_BUILD_ROOT/usr/bin
+ install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
+ install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/usr/sbin/samba
+ install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/etc/rc.d/init.d/winbind
+ install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/usr/sbin/winbind
+ install -m644 packaging/Mandrake/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
+ install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/etc/pam.d/system-auth-winbind
#
- install -m644 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/%{name}
-# install -m644 packaging/Mandrake/samba-slapd-include.conf $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/samba-slapd.include
+ install -m644 $RPM_SOURCE_DIR/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
+ install -m644 packaging/Mandrake/samba-slapd-include.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/samba-slapd.include
# Install smbldap-tools scripts:
for i in examples/LDAP/smbldap-tools/*.pl; do
- install -m 750 $i $RPM_BUILD_ROOT/%{_datadir}/%{name}/scripts/
- ln -s %{_datadir}/%{name}/scripts/`basename $i` $RPM_BUILD_ROOT/%{_bindir}/`basename $i|sed -e 's/\.pl//g'`%{samba_major}
+ install -m 750 $i $RPM_BUILD_ROOT/%{_datadir}/samba/scripts/
+ ln -s %{_datadir}/%{name}/scripts/`basename $i` $RPM_BUILD_ROOT/%{_bindir}/`basename $i|sed -e 's/\.pl//g'`
done
-install -m 750 examples/LDAP/smbldap-tools/smbldap_tools.pm $RPM_BUILD_ROOT/%{_datadir}/%{name}/scripts/
+install -m 750 examples/LDAP/smbldap-tools/smbldap_tools.pm $RPM_BUILD_ROOT/%{_datadir}/samba/scripts/
# The conf file
install -m 640 examples/LDAP/smbldap-tools/smbldap_conf.pm $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}
-#Fix the smbldap-tools when not system samba:
-%if !%build_system
-perl -pi -e 's/^(use|package)(\s+)smbldap_(\w+);$/${1}${2}smbldap_${3}%{samba_major};/g' \
-%{buildroot}/%{_sysconfdir}/%{name}/smbldap_conf.pm \
-%{buildroot}/%{_datadir}/%{name}/scripts/smbldap*.p?
-perl -pi -e 's,/usr/local/sbin/mkntpwd,/usr/sbin/mkntpwd%{samba_major},g;s,553,421,g' %{buildroot}/%{_sysconfdir}/%{name}/smbldap_conf.pm
-perl -pi -e 's,\$smbldap_conf::SID,\$smbldap_conf3::SID,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap*.p?
-%endif
-perl -pi -e 's,/usr/local/sbin/smbldap-passwd.pl,%{_datadir}/%{name}/scripts/smbldap-passwd.pl,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap-useradd.pl
-
# Link both smbldap*.pm into vendor-perl (any better ideas?)
mkdir -p %{buildroot}/%{perl_vendorlib}
-ln -s %{_sysconfdir}/%{name}/smbldap_conf.pm $RPM_BUILD_ROOT/%{perl_vendorlib}/smbldap_conf%{samba_major}.pm
-ln -s %{_datadir}/%{name}/scripts/smbldap_tools.pm $RPM_BUILD_ROOT/%{perl_vendorlib}/smbldap_tools%{samba_major}.pm
+ln -s %{_sysconfdir}/samba/smbldap_conf.pm $RPM_BUILD_ROOT/%{perl_vendorlib}
+ln -s %{_datadir}/samba/scripts/smbldap_tools.pm $RPM_BUILD_ROOT/%{perl_vendorlib}
+
#mkntpwd
-install -m750 examples.bin/LDAP/smbldap-tools/mkntpwd/mkntpwd %{buildroot}/%{_sbindir}/mkntpwd%{samba_major}
+install -m750 examples.bin/LDAP/smbldap-tools/mkntpwd/mkntpwd %{buildroot}/%{_sbindir}
# Samba smbpasswd migration script:
-install -m755 examples/LDAP/convertSambaAccount $RPM_BUILD_ROOT/%{_datadir}/%{name}/scripts/
-
-# make a conf file for winbind from the default one:
- cat packaging/Mandrake/smb.conf|sed -e 's/^; winbind/ winbind/g;s/^; obey pam/ obey pam/g; s/^; printer admin = @"D/ printer admin = @"D/g;s/^; password server = \*/ password server = \*/g;s/^; template/ template/g; s/^ security = user/ security = domain/g' > packaging/Mandrake/smb-winbind.conf
- install -m644 packaging/Mandrake/smb-winbind.conf $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smb-winbind.conf
+install -m700 examples/LDAP/export_smbpasswd.pl $RPM_BUILD_ROOT/%{_datadir}/samba/scripts/
+install -m700 examples/LDAP/import_smbpasswd.pl $RPM_BUILD_ROOT/%{_datadir}/samba/scripts/
-# Some inline fixes for smb.conf for non-winbind use
-install -m644 packaging/Mandrake/smb.conf $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smb.conf
-cat packaging/Mandrake/smb.conf | \
-sed -e 's/^; printer admin = @adm/ printer admin = @adm/g' >$RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smb.conf
-%if %build_cupspc
-perl -pi -e 's/printcap name = lpstat/printcap name = cups/g' $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smb.conf
-perl -pi -e 's/printcap name = lpstat/printcap name = cups/g' $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smb-winbind.conf
-%endif
-#%if !%build_system
-# Fix script paths in smb.conf
-#perl -pi -e 's,%{_datadir}/samba,%{_datadir}/%{name},g' %{buildroot}/%{_sysconfdir}/%{name}/smb*.conf
-#%endif
+# make a conf file for winbind from the default one:
+ cat packaging/Mandrake/smb.conf|sed -e 's/^; winbind/ winbind/g;s/^; obey pam/ obey pam/g; s/^; printer admin = @"D/ printer admin = @"D/g;s/^; password server = \*/ password server = \*/g;s/^; template/ template/g; s/^ security = user/ security = domain/g' > packaging/Mandrake/smb-winbind.conf
+ install -m644 packaging/Mandrake/smb-winbind.conf $RPM_BUILD_ROOT/etc/samba/smb-winbind.conf
-#install mount.cifs
-install -m755 source/client/mount.cifs %{buildroot}/bin/mount.cifs%{samba_major}
+# Link smbmount to /sbin/mount.smb and /sbin/mount.smbfs
- echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/lmhosts
+ ln -s /%{prefix}/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
+ ln -s /%{prefix}/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+ echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts
# Link smbspool to CUPS (does not require installed CUPS)
- mkdir -p $RPM_BUILD_ROOT/%{_libdir}/cups/backend
- ln -s %{_bindir}/smbspool%{alternative_major} $RPM_BUILD_ROOT/%{_libdir}/cups/backend/smb%{alternative_major}
+ mkdir -p $RPM_BUILD_ROOT/usr/lib/cups/backend
+ ln -s /usr/bin/smbspool $RPM_BUILD_ROOT/usr/lib/cups/backend/smb
# xinetd support
- mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/xinetd.d
- install -m644 %{SOURCE3} $RPM_BUILD_ROOT/%{_sysconfdir}/xinetd.d/swat%{samba_major}
+ mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d
+ install -m644 %{SOURCE3} $RPM_BUILD_ROOT/etc/xinetd.d/swat
# menu support
mkdir -p $RPM_BUILD_ROOT%{_menudir}
-cat > $RPM_BUILD_ROOT%{_menudir}/%{name}-swat << EOF
-?package(%{name}-swat):\
-command="gnome-moz-remote http://localhost:901/" \
-needs="gnome" \
-icon="swat%{samba_major}.png" \
-section="Configuration/Networking" \
-title="Samba Configuration (SWAT)" \
+cat > $RPM_BUILD_ROOT%{_menudir}/%{name} << EOF
+?package(%{name}):command="gnome-moz-remote http://localhost:901/" needs="gnome" \
+icon="swat.xpm" section="Configuration/Networking" title="Samba Configuration" \
longtitle="The Swat Samba Administration Tool"
-?package(%{name}-swat):\
-command="sh -c '\$BROWSER http://localhost:901/'" \
-needs="x11" \
-icon="swat%{samba_major}.png" \
-section="Configuration/Networking" \
-title="Samba Configuration (SWAT)" \
+?package(%{name}):command="sh -c '\$BROWSER http://localhost:901/'" needs="x11" \
+icon="swat.xpm" section="Configuration/Networking" title="Samba Configuration" \
longtitle="The Swat Samba Administration Tool"
EOF
mkdir -p $RPM_BUILD_ROOT%{_liconsdir} $RPM_BUILD_ROOT%{_iconsdir} $RPM_BUILD_ROOT%{_miconsdir}
-bzcat %{SOURCE4} > $RPM_BUILD_ROOT%{_liconsdir}/swat%{samba_major}.png
-bzcat %{SOURCE5} > $RPM_BUILD_ROOT%{_iconsdir}/swat%{samba_major}.png
-bzcat %{SOURCE6} > $RPM_BUILD_ROOT%{_miconsdir}/swat%{samba_major}.png
+bzcat %{SOURCE4} > $RPM_BUILD_ROOT%{_liconsdir}/swat.xpm
+bzcat %{SOURCE5} > $RPM_BUILD_ROOT%{_iconsdir}/swat.xpm
+bzcat %{SOURCE6} > $RPM_BUILD_ROOT%{_miconsdir}/swat.xpm
-bzcat %{SOURCE10}> $RPM_BUILD_ROOT%{_datadir}/%{name}/scripts/print-pdf
+bzcat %{SOURCE10}> $RPM_BUILD_ROOT%{_datadir}/samba/scripts/print-pdf
-# Fix configs when not building system samba:
+# Delete files which will not be included, so that /usr/lib/rpm/check-files
+# doesn't error out when Checking for unpackaged file(s)
+%if ! %build_ldap
+%endif
-#Client binaries will have suffixes while we use alternatives, even
-# if we are system samba
-%if !%build_system || %build_alternatives
-for OLD in %{buildroot}/%{_bindir}/{%{clientbin}} %{buildroot}/bin/%{client_bin} %{buildroot}/%{_libdir}/cups/backend/smb
-do
- NEW=`echo ${OLD}%{alternative_major}`
- [ -e $OLD ] && mv -f $OLD $NEW
-done
-for OLD in %{buildroot}/%{_mandir}/man?/{%{clientbin}}* %{buildroot}/%{_mandir}/man?/%{client_bin}*
-do
- if [ -e $OLD ]
- then
- BASE=`perl -e '$_="'${OLD}'"; m,(%buildroot)(.*?)(\.[0-9]),;print "$1$2\n";'`
- EXT=`echo $OLD|sed -e 's,'${BASE}',,g'`
- NEW=`echo ${BASE}%{alternative_major}${EXT}`
- mv $OLD $NEW
- fi
-done
+%if ! %build_acl
%endif
-# Link smbmount to /sbin/mount.smb and /sbin/mount.smbfs
-#I don't think it's possible for make to do this ...
-(cd $RPM_BUILD_ROOT/sbin
- ln -s ..%{_bindir}/smbmount%{alternative_major} mount.smb%{alternative_major}
- ln -s ..%{_bindir}/smbmount%{alternative_major} mount.smbfs%{alternative_major}
-)
-# Server/common binaries are versioned only if not system samba:
-%if !%build_system
-for OLD in %{buildroot}/%{_bindir}/{%{commonbin}} %{buildroot}/%{_bindir}/{%{serverbin}} %{buildroot}/%{_sbindir}/{%{serversbin},swat}
-do
- NEW=`echo ${OLD}%{alternative_major}`
- mv $OLD $NEW -f ||:
-done
-# And the man pages too:
-for OLD in %{buildroot}/%{_mandir}/man?/{%{commonbin},%{serverbin},%{serversbin},swat,{%testbin},smb.conf,lmhosts}*
-do
- if [ -e $OLD ]
- then
- BASE=`perl -e '$_="'${OLD}'"; m,(%buildroot)(.*?)(\.[0-9]),;print "$1$2\n";'`
-# BASE=`perl -e '$name="'${OLD}'"; print "",($name =~ /(.*?)\.[0-9]/), "\n";'`
- EXT=`echo $OLD|sed -e 's,'${BASE}',,g'`
- NEW=`echo ${BASE}%{samba_major}${EXT}`
- mv $OLD $NEW
- fi
-done
-# Replace paths in config files and init scripts:
-for i in smb ;do
- perl -pi -e 's,/subsys/'$i',/subsys/'$i'%{samba_major},g' $RPM_BUILD_ROOT/%{_initrddir}/${i}%{samba_major}
-done
-for i in %{_sysconfdir}/%{name}/smb.conf %{_initrddir}/smb%{samba_major} %{_sbindir}/%{name} %{_initrddir}/winbind /%{_sysconfdir}/logrotate.d/%{name} /%{_sysconfdir}/xinetd.d/swat%{samba_major} %{_initrddir}/wrepld%{samba_major}; do
- perl -pi -e 's,/%{pkg_name},/%{name},g; s,smbd,%{_sbindir}/smbd%{samba_major},g; s,nmbd,%{_sbindir}/nmbd%{samba_major},g; s,/usr/sbin/swat,%{_sbindir}/swat%{samba_major},g;s,wrepld,%{_sbindir}/wrepld%{samba_major},g' $RPM_BUILD_ROOT/$i;
-done
-# Fix xinetd file for swat:
-perl -pi -e 's,/usr/sbin,%{_sbindir},g' $RPM_BUILD_ROOT/%{_sysconfdir}/xinetd.d/swat%{samba_major}
+
+%if ! %build_winbind
+rm -f $RPM_BUILD_ROOT%{_sbindir}/winbind
+rm -f $RPM_BUILD_ROOT%{_sbindir}/winbindd
+rm -f $RPM_BUILD_ROOT%{_bindir}/wbinfo
+rm -f $RPM_BUILD_ROOT/lib/security/pam_winbind*
+rm -f $RPM_BUILD_ROOT/lib/libnss_winbind*
+rm -f $RPM_BUILD_ROOT/etc/rc.d/init.d/winbind
+rm -f $RPM_BUILD_ROOT/etc/pam.d/system-auth-winbind
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/winbindd.8*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man1/wbinfo.1*
%endif
-#Clean up unpackaged files:
-for i in %{_bindir}/pam_smbpass.so %{_bindir}/smbwrapper.so;do
-rm -f %{buildroot}/$i
-done
+%if ! %build_wins
+rm -f $RPM_BUILD_ROOT/lib/libnss_wins.so*
+%endif
+
+%ifarch alpha
+rm -f $RPM_BUILD_ROOT/sbin/mount.smb
+rm -f $RPM_BUILD_ROOT/sbin/mount.smbfs
+rm -f $RPM_BUILD_ROOT%{_bindir}/smbmount
+rm -f $RPM_BUILD_ROOT%{_bindir}/smbumount
+rm -f $RPM_BUILD_ROOT%{_sbindir}/smbmnt
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/smbmnt.8*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/smbmount.8*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/smbumount.8*
+%endif
+
+#Files for antivirus support:
+%if ! %build_fprot
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-fprotd.so
+%endif
+
+%if ! %build_kaspersky
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-kavp.so
+%endif
+
+%if ! %build_mks
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-mksd.so
+%endif
+
+%if ! %build_openantivirus
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-oav.so
+%endif
+
+%if ! %build_sophos
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-sophos.so
+%endif
+
+%if ! %build_symantec
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-symantec.so
+%endif
+
+%if ! %build_trend
+rm -f $RPM_BUILD_ROOT%{_libdir}/samba/vfs/vscan-trend.so
+%endif
%clean
rm -rf $RPM_BUILD_ROOT
-%post server
-
-%_post_service smb%{samba_major}
-#%_post_service wrepld%{samba_major}
+%if %build_ldap
+%post -n samba-server-ldap
+%else
+%post -n samba-server
+%endif
+%_post_service smb
+#/sbin/chkconfig --level 35 smb on
# Add a unix group for samba machine accounts
groupadd -frg 421 machines
+%if %build_ldap
+%post -n samba-common-ldap
+%else
+%post -n samba-common
+%endif
+# Basic migration script for pre-2.2.1 users,
+# since smb config moved from /etc to /etc/samba
+
+mkdir -p /etc/samba
+for s in smb.conf smbusers smbpasswd printers.def secrets.tdb lmhosts; do
+[ -f /etc/$s ] && {
+ cp -f /etc/$s /etc/$s.OLD
+ mv -f /etc/$s /etc/samba/
+}
+done
+
# Migrate tdb's from /var/lock/samba (taken from official samba spec file):
for i in /var/lock/samba/*.tdb
do
@@ -1246,186 +988,224 @@ if [ -f $i ]; then
fi
done
-%post common
-# Basic migration script for pre-2.2.1 users,
-# since smb config moved from /etc to %{_sysconfdir}/samba
+# Remove the transient tdb files (modified from version in off. samba spec:
+for TDB in brlock unexpected locking messages; do
+ if [ -e /var/cache/samba/$TDB.tdb ]; then
+ rm -f /var/cache/samba/$TDB.tdb;
+ fi;
+done
-# Let's create a proper %{_sysconfdir}/samba/smbpasswd file
-[ -f %{_sysconfdir}/%{name}/smbpasswd ] || {
+if [ -d /var/lock/samba ]; then
+ rm -rf /var/lock/samba
+fi
+# Make a symlink on /usr/lib/smbwrapper.so in /usr/bin
+# to fix smbsh problem (another way to do that, anyone???)
+
+ln -sf /usr/lib/smbwrapper.so /usr/bin/smbwrapper.so
+
+# Let's create a proper /etc/samba/smbpasswd file
+[ -f /etc/samba/smbpasswd ] || {
echo "Creating password file for samba..."
- touch %{_sysconfdir}/%{name}/smbpasswd
+ touch /etc/samba/smbpasswd
}
# And this too, in case we don't have smbd to create it for us
-[ -f /var/cache/%{name}/unexpected.tdb ] || {
- touch /var/cache/%{name}/unexpected.tdb
+[ -f /var/cache/samba/unexpected.tdb ] || {
+ touch /var/cache/samba/unexpected.tdb
}
# Let's define the proper paths for config files
-perl -pi -e 's/(\/etc\/)(smb)/\1%{name}\/\2/' %{_sysconfdir}/%{name}/smb.conf
+perl -pi -e 's/(\/etc\/)(smb)/\1samba\/\2/' /etc/samba/smb.conf
# Fix the logrotate.d file from smb and nmb to smbd and nmbd
-if [ -f %{_sysconfdir}/logrotate.d/samba ]; then
- perl -pi -e 's/smb /smbd /' %{_sysconfdir}/logrotate.d/samba
- perl -pi -e 's/nmb /nmbd /' %{_sysconfdir}/logrotate.d/samba
+if [ -f /etc/logrotate.d/samba ]; then
+ perl -pi -e 's/smb /smbd /' /etc/logrotate.d/samba
+ perl -pi -e 's/nmb /nmbd /' /etc/logrotate.d/samba
fi
# And not loose our machine account SID
-[ -f %{_sysconfdir}/MACHINE.SID ] && mv -f %{_sysconfdir}/MACHINE.SID %{_sysconfdir}/%{name}/ ||:
+[ -f /etc/MACHINE.SID ] && mv -f /etc/MACHINE.SID /etc/samba/ ||:
+%if %build_winbind && %build_ldap
+%post -n samba-winbind-ldap
+%endif
+%if %build_winbind && !%build_ldap
+%post -n samba-winbind
+%endif
%if %build_winbind
-%post winbind
+%_post_service winbind
if [ $1 = 1 ]; then
- /sbin/chkconfig winbind on
- cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave
- cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp
+# /sbin/chkconfig winbind on
+ cp -af /etc/nsswitch.conf /etc/nsswitch.conf.rpmsave
+ cp -af /etc/nsswitch.conf /etc/nsswitch.conf.rpmtemp
for i in passwd group;do
- grep ^$i %{_sysconfdir}/nsswitch.conf |grep -v 'winbind' >/dev/null
+ grep ^$i /etc/nsswitch.conf |grep -v 'winbind' 1>/dev/null 2>/dev/null
if [ $? = 0 ];then
- echo "Adding a winbind entry to the $i section of %{_sysconfdir}/nsswitch.conf"
- awk '/^'$i'/ {print $0 " winbind"};!/^'$i'/ {print}' %{_sysconfdir}/nsswitch.conf.rpmtemp >%{_sysconfdir}/nsswitch.conf;
- cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp
+ echo "Adding a winbind entry to the $i section of /etc/nsswitch.conf"
+ awk '/^'$i'/ {print $0 " winbind"};!/^'$i'/ {print}' /etc/nsswitch.conf.rpmtemp >/etc/nsswitch.conf;
+ cp -af /etc/nsswitch.conf /etc/nsswitch.conf.rpmtemp
else
- echo "$i entry found in %{_sysconfdir}/nsswitch.conf"
+ echo "$i entry found in /etc/nsswitch.conf"
fi
done
- if [ -f %{_sysconfdir}/nsswitch.conf.rpmtemp ];then rm -f %{_sysconfdir}/nsswitch.conf.rpmtemp;fi
+ if [ -f /etc/nsswitch.conf.rpmtemp ];then
+ rm -f /etc/nsswitch.conf.rpmtemp;fi
fi
+%endif
-%preun winbind
+%if %build_winbind && %build_ldap
+%preun -n samba-winbind-ldap
+%endif
+%if %build_winbind && !%build_ldap
+%preun -n samba-winbind
+%endif
+%if %build_winbind
+%_preun_service winbind
if [ $1 = 0 ]; then
- echo "Removing winbind entries from %{_sysconfdir}/nsswitch.conf"
- perl -pi -e 's/ winbind//' %{_sysconfdir}/nsswitch.conf
+ echo "Removing winbind entries from /etc/nsswitch.conf"
+ perl -pi -e 's/ winbind//' /etc/nsswitch.conf
- /sbin/chkconfig winbind reset
+# /sbin/chkconfig winbind reset
fi
-%endif %build_winbind
+%endif
%if %build_wins
-%post -n nss_wins%{samba_major}
+%post -n nss_wins
if [ $1 = 1 ]; then
- cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave
- grep '^hosts' %{_sysconfdir}/nsswitch.conf |grep -v 'wins' >/dev/null
+ cp -af /etc/nsswitch.conf /etc/nsswitch.conf.rpmsave
+ grep '^hosts' /etc/nsswitch.conf |grep -v 'wins' >/dev/null
if [ $? = 0 ];then
- echo "Adding a wins entry to the hosts section of %{_sysconfdir}/nsswitch.conf"
- awk '/^hosts/ {print $0 " wins"};!/^hosts/ {print}' %{_sysconfdir}/nsswitch.conf.rpmsave >%{_sysconfdir}/nsswitch.conf;
+ echo "Adding a wins entry to the hosts section of /etc/nsswitch.conf"
+ awk '/^hosts/ {print $0 " wins"};!/^hosts/ {print}' /etc/nsswitch.conf.rpmsave >/etc/nsswitch.conf;
else
- echo "wins entry found in %{_sysconfdir}/nsswitch.conf"
+ echo "wins entry found in /etc/nsswitch.conf"
fi
# else
# echo "Upgrade, leaving nsswitch.conf intact"
fi
-%preun -n nss_wins%{samba_major}
+%preun -n nss_wins
if [ $1 = 0 ]; then
- echo "Removing wins entry from %{_sysconfdir}/nsswitch.conf"
- perl -pi -e 's/ wins//' %{_sysconfdir}/nsswitch.conf
+ echo "Removing wins entry from /etc/nsswitch.conf"
+ perl -pi -e 's/ wins//' /etc/nsswitch.conf
#else
-# echo "Leaving %{_sysconfdir}/nsswitch.conf intact"
+# echo "Leaving /etc/nsswitch.conf intact"
fi
%endif %build_wins
-%preun server
-
-%_preun_service smb%{samba_major}
-#%_preun_service wrepld%{samba_major}
+%if %build_ldap
+%preun -n samba-server-ldap
+%else
+%preun -n samba-server
+%endif
if [ $1 = 0 ] ; then
-# /sbin/chkconfig --level 35 smb reset
-# Let's not loose /var/cache/samba
-
- if [ -d /var/cache/%{name} ]; then
- mv -f /var/cache/%{name} /var/cache/%{name}.BAK
+%_preun_service smb
+ if [ -d /var/log/samba ]; then
+ rm -rf /var/log/samba/*
fi
+ if [ -d /var/cache/samba ]; then
+ mv -f /var/cache/samba /var/cache/samba.BAK
+ fi
+fi
+
+%if %build_ldap
+%preun -n samba-common-ldap
+%else
+%preun -n samba-common
+%endif
+
+if [ $1 = 0 ] ; then
+ for n in /etc/samba/codepages/*; do
+ if [ "$n" != "/etc/samba/codepages/src" ]; then
+ rm -rf $n
+ fi
+ done
fi
-%post swat
+
+%if %build_ldap
+%post -n samba-swat-ldap
+%else
+%post -n samba-swat
+%endif
+# Change only_from entry in /etc/xinetd.d/swat (localhost bug)
+[[ `/bin/grep "localhost" /etc/xinetd.d/swat` ]] && {
+echo "-- Setting swat xinetd only_from entry to 127.0.0.1"
+perl -pi -e 's/localhost/127.0.0.1/' /etc/xinetd.d/swat
+}
if [ -f /var/lock/subsys/xinetd ]; then
service xinetd reload >/dev/null 2>&1 || :
fi
%update_menus
-%postun swat
-
+%if %build_ldap
+%postun -n samba-swat-ldap
+%else
+%postun -n samba-swat
+%endif
# Remove swat entry from xinetd
-if [ $1 = 0 -a -f %{_sysconfdir}/xinetd.conf ] ; then
-rm -f %{_sysconfdir}/xinetd.d/swat%{samba_major}
+if [ -f /var/lock/subsys/xinetd ]; then
service xinetd reload &>/dev/null || :
fi
-
-if [ "$1" = "0" -a -x /usr/bin/update-menus ]; then /usr/bin/update-menus || true ; fi
-
%clean_menus
-%if %build_system
-%post -n %{libname} -p /sbin/ldconfig
-%postun -n %{libname} -p /sbin/ldconfig
-%endif
-
-%if %build_alternatives
-%post client
+%triggerpostun -- samba < 1.9.18p7
-update-alternatives --install %{_bindir}/smbclient smbclient \
-%{_bindir}/smbclient%{alternative_major} 10 \
-$(for i in {/bin/mount.cifs,/sbin/{%{client_sbin}},%{_bindir}/{%{clientbin}}};do
-j=`basename $i`
-[ "$j" = "smbclient" ] || \
-echo -n " --slave ${i} ${j} ${i}%{alternative_major}";done) \
---slave %{_libdir}/cups/backend/smb cups_smb %{_libdir}/cups/backend/smb%{alternative_major} || \
-update-alternatives --auto smbclient
+if [ $1 != 0 ]; then
+ /sbin/chkconfig --level 35 smb on
+fi
-%preun client
-[ $1 = 0 ] && update-alternatives --remove smbclient %{_bindir}/smbclient%{alternative_major} ||:
-%endif
+%triggerpostun -- samba < 2.0.5a-3, samba >= 2.0.0
-%if %build_alternatives
-%triggerpostun client -- samba-client, samba2-client
-[ ! -e %{_bindir}/smbclient ] && update-alternatives --auto smbclient || :
-%endif
+if [ $1 != 0 ]; then
+ [ ! -d /var/lock/samba ] && mkdir -m 0755 /var/lock/samba ||:
+ [ ! -d /var/spool/samba ] && mkdir -m 1777 /var/spool/samba ||:
+ [ -f /etc/inetd.conf ] && chmod 644 /etc/services /etc/inetd.conf ||:
+fi
+%if %build_ldap
+%files server-ldap
+%else
%files server
+%endif
%defattr(-,root,root)
-#%attr(-,root,root) /sbin/*
-%(for i in %{_sbindir}/{%{serversbin}}%{samba_major};do echo $i;done)
-#%{_sbindir}/%{name}
-#%{_sbindir}/smbd%{samba_major}
-#%{_sbindir}/nmbd%{samba_major}
-#%{_sbindir}/mkntpwd%{samba_major}
-#%{_sbindir}/wrepld%{samba_major}
-%(for i in %{_bindir}/{%{serverbin}}%{samba_major};do echo $i;done)
-#%{_bindir}/smbcontrol%{samba_major}
-#%{_bindir}/smbstatus%{samba_major}
-#%{_bindir}/pdbedit%{samba_major}
-#%{_bindir}/tdbbackup%{samba_major}
-#%{_bindir}/profiles%{samba_major}
-#%{_bindir}/editreg%{samba_major}
-%attr(755,root,root) /%{_lib}/security/pam_smbpass*
-%dir %{_libdir}/%{name}/vfs
-%{_libdir}/%{name}/vfs/*.so
-%dir %{_libdir}/%{name}/pdb
-
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/%{name}/smbusers
-%attr(-,root,root) %config(noreplace) %{_initrddir}/smb%{samba_major}
-#%attr(-,root,root) %config(noreplace) %{_initrddir}/wrepld%{samba_major}
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/pam.d/%{name}
-#%attr(-,root,root) %config(noreplace) %{_sysconfdir}/%{name}/samba-slapd.include
-%{_mandir}/man1/smbstatus*.1*
-%{_mandir}/man5/smbpasswd*.5*
-%{_mandir}/man7/samba*.7*
-%{_mandir}/man8/smbd*.8*
-%{_mandir}/man8/nmbd*.8*
-%{_mandir}/man8/pdbedit*.8*
-%{_mandir}/man1/smbcontrol*.1*
-%{_mandir}/man8/tdbbackup*.8*
-%{_mandir}/man1/profiles*.1*
-%{_mandir}/man1/editreg*.1*
-%attr(775,root,adm) %dir %{_localstatedir}/%{name}/netlogon
-%attr(755,root,root) %dir %{_localstatedir}/%{name}/profiles
-%attr(755,root,root) %dir %{_localstatedir}/%{name}/printers
-%attr(2775,root,adm) %dir %{_localstatedir}/%{name}/printers/*
-%attr(1777,root,root) %dir /var/spool/%{name}
-%dir %{_datadir}/%{name}
+#%attr(-,root,root) %{prefix}/sbin/*
+%attr(-,root,root) /sbin/*
+#%attr(-,root,root) %{prefix}/bin/*
+#%attr(755,root,root) /lib/*
+%{_sbindir}/samba
+%{_sbindir}/smbd
+%{_sbindir}/nmbd
+%{_sbindir}/smbcontrol
+%{_sbindir}/mkntpwd
+#%{prefix}/bin/addtosmbpass
+%{_bindir}/mksmbpasswd.sh
+%{_bindir}/smbstatus
+%{_bindir}/convert_smbpasswd
+%attr(755,root,root) /lib/security/pam_smbpass*
+%attr(-,root,root) %config(noreplace) /etc/samba/smbusers
+%attr(-,root,root) %config /etc/rc.d/init.d/smb
+%attr(-,root,root) %config(noreplace) /etc/logrotate.d/samba
+%attr(-,root,root) %config(noreplace) /etc/pam.d/samba
+%attr(-,root,root) %config(noreplace) /etc/samba/samba-slapd.include
+%{_mandir}/man1/smbstatus.1*
+%{_mandir}/man5/smbpasswd.5*
+%{_mandir}/man7/samba.7*
+%{_mandir}/man8/smbd.8*
+%{_mandir}/man8/nmbd.8*
+%{_mandir}/man1/smbcontrol.1*
+#%{_mandir}/man1/lmhosts.1*
+%attr(755,root,root) %dir /var/lib/samba/netlogon
+%attr(775,root,users) %dir /var/lib/samba/profiles
+%attr(775,root,adm) %dir /var/lib/samba/printers/*
+%attr(755,root,root) %dir %{_libdir}/samba/vfs
+%attr(755,root,root) %{_libdir}/samba/vfs/audit.so
+%attr(755,root,root) %{_libdir}/samba/vfs/block.so
+%attr(755,root,root) %{_libdir}/samba/vfs/recycle.so
+%attr(-,root,root) %config(noreplace) %{_sysconfdir}/samba/recycle.conf
+#%attr(775,root,root) %dir %{_libdir}/samba/vfs/vscan
+%attr(1777,root,root) %dir /var/spool/samba
%dir %{_datadir}/%{name}/scripts
%attr(0755,root,root) %{_datadir}/%{name}/scripts/print-pdf
%attr(0750,root,adm) %{_datadir}/%{name}/scripts/smbldap*.pl
@@ -1433,166 +1213,134 @@ update-alternatives --auto smbclient
%attr(0640,root,adm) %config(noreplace) %{_sysconfdir}/%{name}/smbldap_conf.pm
%attr(0644,root,root) %{_datadir}/%{name}/scripts/smbldap_tools.pm
%{perl_vendorlib}/*.pm
-#%attr(0700,root,root) %{_datadir}/%{name}/scripts/*port_smbpasswd.pl
-%attr(0755,root,root) %{_datadir}/%{name}/scripts/convertSambaAccount
+%attr(0700,root,root) %{_datadir}/%{name}/scripts/*port_smbpasswd.pl
%files doc
-%defattr(-,root,root)
+%defattr(644,root,root,755)
%doc README COPYING Manifest Read-Manifest-Now
%doc WHATSNEW.txt Roadmap
%doc README.%{name}-mandrake-rpm
-%doc clean-docs/samba-doc/docs
-%doc clean-docs/samba-doc/examples
-%attr(-,root,root) %{_datadir}/swat%{samba_major}/using_samba/
+%doc docs
+%doc examples
+%doc swat/README
+%attr(-,root,root) %{prefix}/share/swat/using_samba/*
+%if %build_ldap
+%files swat-ldap
+%else
%files swat
+%endif
%defattr(-,root,root)
-%config(noreplace) %{_sysconfdir}/xinetd.d/swat%{samba_major}
-#%attr(-,root,root) /sbin/*
-%{_sbindir}/swat%{samba_major}
-%{_menudir}/%{name}-swat
-%{_miconsdir}/*.png
-%{_liconsdir}/*.png
-%{_iconsdir}/*.png
-%attr(-,root,root) %{_datadir}/swat%{samba_major}/help/
-%attr(-,root,root) %{_datadir}/swat%{samba_major}/images/
-%attr(-,root,root) %{_datadir}/swat%{samba_major}/include/
-%lang(ja) %{_datadir}/swat%{samba_major}/lang/ja
-%lang(tr) %{_datadir}/swat%{samba_major}/lang/tr
-%{_mandir}/man8/swat*.8*
-%lang(de) %{_libdir}/%{name}/de.msg
-%lang(en) %{_libdir}/%{name}/en.msg
-%lang(fr) %{_libdir}/%{name}/fr.msg
-%lang(it) %{_libdir}/%{name}/it.msg
-%lang(ja) %{_libdir}/%{name}/ja.msg
-%lang(nl) %{_libdir}/%{name}/nl.msg
-%lang(pl) %{_libdir}/%{name}/pl.msg
-%lang(tr) %{_libdir}/%{name}/tr.msg
-#%doc swat/README
+%config(noreplace) /etc/xinetd.d/swat
+%attr(-,root,root) /sbin/*
+%{_sbindir}/swat
+%{_menudir}/%{name}
+%{_miconsdir}/*.xpm
+%{_liconsdir}/*.xpm
+%{_iconsdir}/*.xpm
+%attr(-,root,root) %{_datadir}/swat/help/*
+%attr(-,root,root) %{_datadir}/swat/images/*
+%attr(-,root,root) %{_datadir}/swat/include/*
+%{_mandir}/man8/swat.8*
%files client
%defattr(-,root,root)
-%(for i in %{_bindir}/{%{clientbin}}%{alternative_major};do echo $i;done)
-%(for i in %{_mandir}/man?/{%{clientbin}}%{alternative_major}.?.*;do echo $i|grep -v smbprint;done)
%ifnarch alpha
-%(for i in /sbin/{%{client_sbin}}%{alternative_major};do echo $i;done)
-%attr(4755,root,root) /bin/mount.cifs%{alternative_major}
-%attr(755,root,root) %{_bindir}/smbmount%{alternative_major}
-%attr(4755,root,root) %{_bindir}/smbumount%{alternative_major}
-%attr(4755,root,root) %{_bindir}/smbmnt%{alternative_major}
-%{_mandir}/man8/smbmnt*.8*
-%{_mandir}/man8/smbmount*.8*
-%{_mandir}/man8/smbumount*.8*
-%{_mandir}/man8/mount.cifs*.8*
-%else
-%exclude %{_bindir}/smb*m*nt%{samba_major}
-%exclude %{_mandir}/man8/smb*m*nt*.8*
-%endif
+/sbin/mount.smb
+/sbin/mount.smbfs
+%attr(755,root,root) %{_bindir}/smbmount
+%attr(4755,root,root) %{_bindir}/smbumount
+%attr(4755,root,root) %{_sbindir}/smbmnt
+%{_mandir}/man8/smbmnt.8*
+%{_mandir}/man8/smbmount.8*
+%{_mandir}/man8/smbumount.8*
+%endif
+%{_bindir}/nmblookup
+%{_bindir}/findsmb
+%{_bindir}/smbclient
+%{_bindir}/smbprint
+%{_bindir}/smbtar
+%{_bindir}/smbspool
# Link of smbspool to CUPS
-/%{_libdir}/cups/backend/smb%{alternative_major}
+%{_libdir}/cups/backend/smb
+%{_mandir}/man1/nmblookup.1*
+%{_mandir}/man1/findsmb.1*
+%{_mandir}/man1/smbclient.1*
+%{_mandir}/man1/smbtar.1*
+%{_mandir}/man8/smbspool.8*
+%if %build_ldap
+%files common-ldap
+%else
%files common
+%endif
%defattr(-,root,root)
-%dir /var/cache/%{name}
-%dir /var/log/%{name}
-%dir /var/run/%{name}
-%(for i in %{_bindir}/{%{commonbin}}%{samba_major};do echo $i;done)
-%(for i in %{_mandir}/man?/{%{commonbin}}%{samba_major}\.[0-9]*;do echo $i;done)
-#%{_libdir}/smbwrapper%{samba_major}.so
-%dir %{_libdir}/%{name}
-%{_libdir}/%{name}/*.dat
-%{_libdir}/%{name}/charset
-#%{_libdir}/%{name}/lowcase.dat
-#%{_libdir}/%{name}/valid.dat
-%dir %{_sysconfdir}/%{name}
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/%{name}/smb.conf
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/%{name}/smb-winbind.conf
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/%{name}/lmhosts
-%dir %{_localstatedir}/%{name}
-%attr(-,root,root) %{_localstatedir}/%{name}/codepages
-%{_mandir}/man5/smb.conf*.5*
-%{_mandir}/man5/lmhosts*.5*
-#%{_mandir}/man7/Samba*.7*
-%dir %{_datadir}/swat%{samba_major}
-
-%if %build_winbind
+%dir /var/cache/samba
+%dir /var/log/samba
+%dir /var/run/samba
+%{_bindir}/make_smbcodepage
+%{_bindir}/make_unicodemap
+%{_bindir}/testparm
+%{_bindir}/testprns
+%{_bindir}/make_printerdef
+%{_bindir}/rpcclient
+%{_bindir}/smbsh
+%{_bindir}/smbpasswd
+%{_bindir}/smbcacls
+%{_sbindir}/debug2html
+%{_sbindir}/smbfilter
+%{_libdir}/smbwrapper.so
+%{_libdir}/libsmbclient.so
+%attr(-,root,root) %config(noreplace) /etc/samba/smb.conf
+%attr(-,root,root) %config(noreplace) /etc/samba/smb-winbind.conf
+%attr(-,root,root) %config(noreplace) /etc/samba/lmhosts
+%attr(-,root,root) /var/lib/samba/codepages
+%{_mandir}/man1/make_smbcodepage.1*
+%{_mandir}/man1/make_unicodemap.1*
+%{_mandir}/man1/testparm.1*
+%{_mandir}/man1/smbsh.1*
+%{_mandir}/man1/testprns.1*
+%{_mandir}/man5/smb.conf.5*
+%{_mandir}/man5/lmhosts.5*
+%{_mandir}/man8/smbpasswd.8*
+%{_mandir}/man1/smbcacls.1*
+%{_mandir}/man1/rpcclient.1*
+%{_mandir}/man8/pdbedit.8*
+
+#%if %build_winbind
+#%if %build_ldap
+%if %build_winbind && %build_ldap
+%files winbind-ldap
+%endif
+#%else
+%if %build_winbind && !%build_ldap
%files winbind
+%endif
+%if %build_winbind
%defattr(-,root,root)
%{_sbindir}/winbindd
%{_sbindir}/winbind
%{_bindir}/wbinfo
-%attr(755,root,root) /%{_lib}/security/pam_winbind*
-%attr(755,root,root) /%{_lib}/libnss_winbind*
-%attr(-,root,root) %config(noreplace) %{_initrddir}/winbind
-%attr(-,root,root) %config(noreplace) %{_sysconfdir}/pam.d/system-auth-winbind*
-%{_mandir}/man8/winbindd*.8*
-%{_mandir}/man1/wbinfo*.1*
+%attr(755,root,root) /lib/security/pam_winbind*
+%attr(755,root,root) /lib/libnss_winbind*
+%attr(-,root,root) %config /etc/rc.d/init.d/winbind
+%attr(-,root,root) %config(noreplace) /etc/pam.d/system-auth-winbind
+%{_mandir}/man8/winbindd.8*
+%{_mandir}/man1/wbinfo.1*
%endif
%if %build_wins
-%files -n nss_wins%{samba_major}
-%defattr(-,root,root)
-%attr(755,root,root) /%{_lib}/libnss_wins.so*
-%endif
-
-%if %{?_with_test:1}%{!?_with_test:0}
-%files test
+%files -n nss_wins
%defattr(-,root,root)
-%(for i in %{_bindir}/{%{testbin}}%{samba_major};do echo $i;done)
-%{_mandir}/man1/vfstest%{samba_major}*.1*
-%exclude %{_mandir}/man1/log2pcap*.1*
-%else
-%exclude %{_mandir}/man1/vfstest%{samba_major}*.1*
-%exclude %{_mandir}/man1/log2pcap*.1*
+%attr(755,root,root) /lib/libnss_wins.so*
%endif
-%if %build_system
-%files -n %{libname}
-%defattr(-,root,root)
-%{_libdir}/libsmbclient.so.*
-%else
-%exclude %{_libdir}/libsmbclient.so.*
-%endif
-
-%if %build_system
-%files -n %{libname}-devel
-%defattr(-,root,root)
-%{_includedir}/*
-%{_libdir}/libsmbclient.so
-%doc clean-docs/libsmbclient/*
-%else
-%exclude %{_includedir}/*
-%exclude %{_libdir}/libsmbclient.so
-%endif
-
-%if %build_system
-%files -n %{libname}-static-devel
-%defattr(-,root,root)
-%{_libdir}/libsmbclient.a
-%else
-%exclude %{_libdir}/libsmbclient.a
-%endif
-
-#%files passdb-ldap
-#%defattr(-,root,root)
-#%{_libdir}/%{name}/*/*ldap.so
-
-%ifnarch alpha
-%files passdb-mysql
-%defattr(-,root,root)
-%{_libdir}/%{name}/pdb/*mysql.so
-%endif
-
-%files passdb-xml
-%defattr(-,root,root)
-%{_libdir}/%{name}/pdb/*xml.so
-
#Files for antivirus support:
%if %build_fprot
%files vscan-fprot
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-fprotd.so
+%{_libdir}/samba/vfs/vscan-fprotd.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-fprotd.conf
%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
@@ -1600,23 +1348,23 @@ update-alternatives --auto smbclient
%if %build_kaspersky
%files vscan-kaspersky
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-kavp.so
+%{_libdir}/samba/vfs/vscan-kavp.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-kavp.conf
-%doc %{vfsdir}/%{vscandir}/INSTALL
+%doc %{vfsdir}/%{vscandir}/examples.bin/VFS/kaspersky/INSTALL
%endif
%if %build_mks
%files vscan-mks
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-mksd.so
+%{_libdir}/samba/vfs/vscan-mksd.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-mks*.conf
%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
-%if %build_openav
-%files vscan-openav
+%if %build_openantivirus
+%files vscan-openantivirus
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-oav.so
+%{_libdir}/samba/vfs/vscan-oav.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-oav.conf
%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
@@ -1624,15 +1372,15 @@ update-alternatives --auto smbclient
%if %build_sophos
%files vscan-sophos
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-sophos.so
+%{_libdir}/samba/vfs/vscan-sophos.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-sophos.conf
-%doc %{vfsdir}/%{vscandir}/INSTALL
+%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
%if %build_symantec
%files vscan-symantec
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-symantec.so
+%{_libdir}/samba/vfs/vscan-symantec.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-symantec.conf
%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
@@ -1640,286 +1388,378 @@ update-alternatives --auto smbclient
%if %build_trend
%files vscan-trend
%defattr(-,root,root)
-%{_libdir}/%{name}/vfs/vscan-trend.so
+%{_libdir}/samba/vfs/vscan-trend.so
%config(noreplace) %{_sysconfdir}/%{name}/vscan-trend.conf
%doc %{vfsdir}/%{vscandir}/INSTALL
%endif
-%exclude %{_mandir}/man1/smbsh*.1*
-
%changelog
-* Fri Dec 05 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre3.5mdk
-- Allow winbind to start if old winbind ranges are used (ease upgrades)
-
-* Tue Nov 18 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre3.4mdk
-- Fix build as system on 8.2 (and probably earlier)
-
-* Sun Nov 16 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre3.3mdk
-- Ensure printer drivers keep permissions by default (setgid and inherit perms)
-
-* Fri Nov 14 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre3.2mdk
-- 3.0.1pre3
-- Add support for Mandrake 10.0 (as system samba)
-- Fix alternatives triggers
-- Fix obsoletes
-
-* Mon Nov 10 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre2.2mdk
-- 3.0.1pre2
-- misc spec files (pointed out by Luca Olivetti)
-- Fix path to smbldap-passwd.pl
-- Only allow one copy of winbind and nss_wins
-- Add trigger for alternatives
-
-* Sun Oct 12 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre1.2mdk
-- 3.0.1pre1
-- remove buildroot patch (p3), fixed upstream
-
-* Thu Sep 25 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-2mdk
-- 3.0.0 final
-
-* Sat Sep 13 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc4.2mdk
-- rc4
-- Don't update alternatives in pre/post scripts when not using alternatives
-- Fix case of --with-system without alternatives
-- Final fixes to smbldap-tools for non-system case
-- Remove duplicate docs (really - 1 character typo ...)
-- Update configs (fix winbind init script, add example scripts in smb.conf)
-
-* Tue Sep 09 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc3.2mdk
-- rc3
-- Fix mount.smb{,fs} alternatives (spotted by Laurent Culioli)
-
-* Thu Sep 04 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc2.3mdk
-- Fix alternatives
-- Fix libname (can I blame guillomovitch's evil line-wrapping spec mode?)
-- Fix smbldap-tools package/use names when not system samba
-- Don't conflict samba3-client with samba-client for now so we can install it
-
-* Fri Aug 29 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc2.2mdk
-- rc2
-- Remove patches 100-102 (upstream)
-- Fix libname
-- Alternatavise client
-- Better solution to avoid rpath
-
-* Fri Aug 22 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc1.3mdk
-- Fix build with test package (p100), but not by default (too big)
-- Fix (p101) for SID resolution when member of samba-2.2.x domain
-- Fix libsmbclient packages (thanks Gotz)
-- version mount.cifs, patch from CVS (p102), and setuid it
-- Clean up docs (guillomovitch spam ;-)
-
-* Sat Aug 16 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc1.2mdk
-- rc1
-- disable test subpackage since it's broken again
-
-* Mon Jul 28 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta3.3mdk
-- Rebuild for kerberos-1.3 on cooker
-- Put printer directories back
-- Add mount.cifs
-- Go back to standard optimisations
-
-* Thu Jul 17 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta3.2mdk
-- beta3
-- remove -g from cflags to avoid large static libraries
-- drop optimisation from O2 to O1 for gcc 3.3.1
-- own some directories for distriblint's benefit
-- use chrpath on distro's that have it to drastically reduce rpmlint score
-
-* Mon Jul 14 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta2.3mdk
-- place non-conditional excludes at the end of files list, to prevent causing
- rpm in Mandrake <=8.2 from segfaulting when processing files.
-- Update default config
-
-* Wed Jul 02 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta2.2mdk
-- 3.0.0beta2
-- manually build editreg
-- Add some new man pages
-
-* Tue Jun 10 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta1.3mdk
-- add provision for passdb-ldap subpackage (it doesn't build like that yet)
-- avoid debugging info on cooker/9.2 for the moment
-- We probably don't need to autoconf (and can thus build on 8.1)
-- We can probably build without kerberos support (and thus on 8.0)
-- Don't require mysql-devel on alpha's (maybe we want to be able to disable
- mysql support for other arches?)
-- We shouldn't need to specifically add openssl to include path, since ssl
- support is deprecated.
-- png icons, change menu title to not conflict with ksambaplugin
-- update to samba-vscan-0.3.3beta1, but it still does not build the vscan
- modules.
-- add -static-devel package
-- Add buildrequires for lib packages that are picked up if installed
- (ncurses, popt) in an attempt to get slbd to build samba3
-- Fix default config (P100)
-
-* Sun Jun 08 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.beta1.2mdk
-- Get packages into cooker (klama doesn't want to build this package ..)
-- samba-vscan-0.3.2b
-
-* Fri Jun 06 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha24.2mdk
-- Rename debug package to test and other fixes for rpm-4.2
-- prepare for beta1
-
-* Wed Apr 30 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha24.1mdk
-- Remove some files removed upstream
-- In builds from source, don't terminate on missing docs or unpackaged files
- (if only we could do it for other missing files ...)
-
-* Mon Apr 28 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha24.0mdk
-- Reenable debug package by (--without debug to not build it), fixed post-a23
-- Add bugzilla note for builds from source (also intended for packages made
- available on samba FTP site) at samba team request
-- Fix build from CVS (run autogen.sh, pass options to all rpm commands)
-- Appease distriblint, but not much to be done about /usr/share/swat3/ since
- samba-doc owns some subdirs, and samba-swat others, and they can be installed
- independantly.
-- Apply kaspersky vscan build fix from samba2
-- Final for alpha24
-
-* Wed Apr 23 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha23.3mdk
-- Small fixes in preparation for testing as system samba
-- Make debug package optional (--with debug) since it's often broken
-- Add support for 9.2 (including in-line smbd quota patch for glibc2.3)
-- Add --with options option, which will just show you the available options and exit
-
-* Sun Apr 06 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha23.2mdk
-- Alpha23
-- buildrequire autconf2.5
-- samba-vscan 0.3.2a
-- Remove patch 102 (upstreamed)
-
-* Thu Mar 06 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha22.2mdk
-- Alpha22
-- Add profiles binary to server and ntlm_auth to common
-- smbwrapper and torture target broken (only in 9.0?)
-- remove unused source 2
-
-* Tue Mar 04 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha21.4mdk
-- Don't provide samba-{server,client,common} when not system samba (bug #2617)
-- Don't build libsmbclient packages when not system samba
-- Fix conflict between samba-server and samba3-server (pam_smbpass)
-- Fix smbwrapper (from 2.2.7a-5mdk for bug #2356)
-- Fix codepage/charset example (bug #1574)
-
-* Thu Jan 23 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha21.3mdk
-- samba-vscan 0.3.1 (and make it build again), including required inline edits
-- Make all vscan packages provide samba(3)-vscan
+* Fri Feb 14 2003 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.7a-4mdk
+- Fix build openantivirus with default scanners
+- buildrequire popt-devel
+- From Jim Collings <jcllings@tsunamicomm.net>
+ - Patched smbldap-tools and created links to same in /usr/bin
+
+* Thu Jan 23 2003 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.7a-3mdk
+- Two patches to fix large file support (smbtar:p101 and smbclient:p102)
+- Patch to enable ldap referral (103)
- Build all vscan except kav (requires kaspersky lib) with --with-scanners
+- Allow adm group to install printer drivers and use smbldaptools by default
+- Remove smb.conf man page conflict
+
+* Thu Jan 02 2003 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7a-2mdk
+- Rebuilt because of new rpm macros and new glibc.
+- Happy new year 2003 to all samba developers, contributors and users!
+
+* Wed Dec 11 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7a-1mdk
+- Upgraded to 2.2.7a.
+
+* Sun Dec 08 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.7-5mdk
+- samba-vscan 0.3.1 (and make it build again)
+- Make all vscan packages provide samba-vscan
+- All scanner packages (besides kaspersky) can be built without the
+ scanner installed, but we don't quite to this yet ...
- Add vscan-(scanner).conf files
-- Explicitly add ldapsam for 2.2 compatability when building --with ldap,
- default build now uses new ldap passdb backend (ie you always get ldap)
-- Enable (experimental) tdb passdb backend
-- Fix file ownership conflicts between server and common
-- Cleanup configure, to match order of --help
-- Fix libdir location, was being overridden by --with-fhs
-- Split off a libsmbclient and -devel package
-- Add wins replication init script (patch 102)
-- Workaround passdb/pdb_xml.c not compiling
-- Workaround missing install targets for smbsh/smbwrapper.so in cvs
-- Inline patch smbd/quotas.c for Mandrake >9.0
-
-* Wed Nov 27 2002 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha21.2mdk
-- Remove patch 20,21,22,23,25,26 (upstream)
-- New destdir patch from cvs (18)
-- package installed but non-packaged files
-- new debug subpackage for vfstest and related files (it was that or nuke the
- manpage ;-))
-- use _libdir for libdir instead of _sysconfdir
-- Update samba-vscan (untested)
-
-* Mon Oct 28 2002 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha20.3mdk
-- Fix mount.smbfs3 pointing to smbmount not in package
-- Remove unnecessary lines from install (now done by make)
-- Build with ldap and ads on all releases by default
-- Put av-stuff back
-
-* Mon Oct 21 2002 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha20.2mdk
-- When not building as system samba, avoid conflicting with system samba
-- Macro-ize as much as possible for above (aka finish cleanups)
-- Fix paths in init scripts and logrotate and xinetd
-- Fix provides and obsoletes so as to provide samba, but not obsolete
- current stable until we have a stable release (when it's the system samba).
-- Add warnings to descriptions when not system samba.
-- This is now parallel installable with the normal samba release, for easy
- testing. It shouldn't touch existing installations. Of course, only
- one samba at a time on the same interface!
-
-* Sat Sep 28 2002 Buchan Milne <bgmilne@linux-mandrake.com> 3.0-0.alpha20.1mdk
-- Merge with 2.2.6pre2.2mdk
-- Detect alpha- and beta-, along with pre-releases
-
-* Tue Feb 05 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha14-0.1mdk
-- Sync with 2.2.3-2mdk (new --without options, detect when
- building for a different distribution.
-
-* Mon Feb 04 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha14-0.0mdk
-- Sync with 2.2.2-10mdk, which added build-time options --with ldap,
- winbind, acl, wins, mdk72, mdk80, mdk81, mdk82, cooker. Added
- warning in description if built with these options.
-
-* Wed Jan 23 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha13-0.2mdk
-- Added if's for build_ads, which hopefully will add Active Directory
- Support (by request).
-
-* Thu Jan 17 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha13-0.1mdk
-- More syncing with 2.2 rpm (post and postun scripts)
-- Testing without ldap
-
-* Thu Jan 17 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha13-0.0mdk
-- 3.0-alpha13
-- Fixed installman.sh patch.
-
-* Wed Jan 09 2002 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha12-0.1mdk
-- Fixed %post and %preun for nss_wins, added %post and %preun for
- samba-winbind (chkconfig and winbind entries in nsswitch.conf)
-
-* Sun Dec 23 2001 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha12-0.0mdk
-- 3.0-alpha12
+- Add winbind-auth-challenge to configure, for squid support
+- Use winbind-ldap-hack only when building with ldapsam support
+ since no-one has been able to test this thoroughly, and my only
+ tests indicated performance problems with it (and I need this RPM to
+ work for squid)
+
+* Tue Nov 26 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7-4mdk
+- Fix perms on doc.
+- Cleaned up specfile a bit.
+- Added support for upcoming Mandrake Linux 9.1 in auto build process.
+
+* Tue Nov 26 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7-3mdk
+- Put (noreplace) back in %files swat.
+- Changed only_from entry in sample swat to "127.0.0.1".
+- Change only_from entry in /etc/xinetd.d/swat to "127.0.0.1" on %post swat.
+
+* Fri Nov 22 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7-2mdk
+- Removed noreplace of /etc/xinetd.d/swat on update.
+- Updated samba-vscan (0.3.0).
+
+* Wed Nov 20 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.7-1mdk
+- Update to 2.2.7.
+- Removed patch 38.
+
+* Sat Nov 16 2002 Alexander Skwar <ASkwar@DigitalProjects.com> 2.2.6-6mdk
+- Remove installed files which will not be included due to build options,
+ so that /usr/lib/rpm/check-files doesn't error out when
+ Checking for unpackaged file(s)
+- Add debug2html, smbfilter to common package
+- Add /usr/sbin/winbind to winbind package
+- Add rpcclient manpage to common package
+- Add smbspool, pdbedit manpage to client package
+
+* Wed Nov 06 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-5mdk
+- add winbind ldap hack again, with proper build-require (libldap2-devel)
+- enable --with-sendfile-support (default in 3.0. Increases performance).
+
+* Wed Oct 30 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-4mdk
+- Patch to fix fd leak with kernel change notify. (38) (--Jeremy Allison)
+
+* Fri Oct 25 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-3mdk
+- Add URL to http://www.samba.org
+- Add --with-winbind-ldap-hack to remove the need to enable
+ pre-windows2000-compatible access for winbind.
+
+* Tue Oct 22 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-2mdk
+- Really switch back to std versioning.
+- samba-vscan v-0.2.5e
+
+* Fri Oct 18 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-1.3mdk
+- Clean-up patches.
+- Switch back to normal versioning.
+- added ISO8859-8 (Hebrew).
+
+* Fri Oct 18 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-1.2mdk
+- Birthday release ;o)
+- Added smbumount patch back (37).
+
+* Thu Oct 17 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.6-1.1mdk
+- New version: 2.2.6
+
+* Wed Oct 16 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-23mdk
+- Upgrade to 2.2.6rc4
+- 2.2.6-1.0.rc4.1mdk
+- remove patch 36.
+
+* Mon Oct 14 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-22mdk
+- Upgrade to 2.2.6rc3
+- 2.2.6-1.0.rc3.1mdk
+
+* Thu Oct 10 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-21mdk
+- Put docs back (aka rpm sucks, builds cleanly when doc fails)
+- 2.2.6-1.0.rc2.3mdk
+
+* Thu Oct 10 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-20mdk
+- Fix typo in print-pdf script
+- Make spec resistant to arbitrary pre/alpha/rc/beta/iamnotfinishedyet strings
+ in version
+- Stop filling CVS with READMEs (use README.samba-mandrake-rpm instead)
+- Make example profiles share writeable by default, and add auto-creation
+ example (smb.conf)
+- Make ps printing example remove printed files by default (smb.conf)
+- Fix ntlogon example (smb.conf)
+
+* Thu Oct 10 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-19mdk
+- almost 2.26 (rc2)!
+
+* Mon Oct 07 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-18mdk
+- add lazy umount patch for smbumount to allow smbumount to handle
+ broken connection. (36) (-- <kevin@vega.idv.tw>)
+
+* Thu Sep 05 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-17mdk
+- changed localhost entry in /etc/xinetd.d/swat to 127.0.0.1
+ for resolving issue.
+
+* Thu Aug 15 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-16mdk
+- Don't remove swat xinetd config (that's what RPM is for!)
+- Don't clean menus twice
+- This should also be 2.2.6-1.1mdk (build from official samba tarball)
+- Use samba-slapd-include.conf from packaging dir (patch it in for 2.2.5)
+
+* Wed Aug 07 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-15mdk
+- put /var/log/samba and /var/run/samba in common (for winbind - sbenedict)
+- Integrate smbldap-tools, now in /usr/share/scripts/samba, with examples
+ in smb.conf, configuration is /etc/samba/smbldap_conf.pm (please test!)
+ This links smbldap_tools.pm and smbldap_conf.pm into perl_vendorlib
+ (better ideas?)
+- Add mkntpwd (for smbldap-tools)
+- Samba smbpasswd->ldap migration script also in samba scripts dir.
+- Add recycle.conf, fix recycle example in smb.conf (pascal@vmfacility.fr)
+- spec cleanups
+- bump samba-vscan to 0.2.5c (not tested though - yet).
+
+* Wed Jul 24 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-14mdk
+- Fix ldap description (really only when built with LDAP)
+- Expand -server description
+- more winbind examples in smb.conf
+- add winbind version of default smb.conf (smb-winbind.conf)
+- Add PDF-creation script and share
+- Rebuild for new acl
+
+* Wed Jul 24 2002 Thierry Vignaud <tvignaud@mandrakesoft.com> 2.2.5-13mdk
+- rebuild for new readline
+
+* Mon Jul 22 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-12mdk
+- fixed source no. for samba-slapd.include (-- Oden Eriksson)
+- added CVS win2k copy bug patch (34) (-- Jeremy Alison)
+
+* Tue Jul 16 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-11mdk
+- Fix winbind init script (doesn't need nmbd)
+- Add ldap examples, pam password change, obey pam restrictions (winbind)
+ in smb.conf (disabled of course)
+- Add sample LDAP configuration (/etc/samba/samba-slapd.include
+- Add password section to /etc/pam.d/samba (pam password change)
+- buildrequires readline-devel
+- Ensure unexpected.tdb exists for winbind/client without smbd (post in common)
+
+* Wed Jul 10 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-10mdk
+- patch (30) to randomize the way smb re-reads config files (-- Jonathan Knight)
+
+* Thu Jul 04 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-9mdk
+- changed a few perms from 775 to 755 to make rpmlint happy.
+
+* Mon Jul 01 2002 Geoffrey Lee <snailtalk@mandrakesoft.com> 2.2.5-8mdk
+- Don't make smbmnt and smbumount group writable.
+
+* Mon Jul 01 2002 Geoffrey Lee <snailtalk@mandrakesoft.com> 2.2.5-7mdk
+- Really fix the Alpha (I suck).
+
+* Thu Jun 27 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-6mdk
+- directory listings vs NT/win2k servers helper patch (30) (--Urban Widmark)
+- build --with-libsmbclient
+
+* Thu Jun 27 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-5mdk
+- parsing fix for spoolss (29) (-- Jerry Carter)
+- Don't make the -ldap packages conflicts with the "normal" packages,
+ but make them Obsoletes (-- Alexander Skwar)
+
+* Thu Jun 27 2002 Geoffrey Lee <snailtalk@mandrakesoft.com> 2.2.5-4mdk
+- Alpha build fix.
+
+* Wed Jun 26 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-3mdk
+- ldap patch (28) (-- Jerry Carter)
+
+* Wed Jun 19 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-2mdk
+- Fix build on 8.1 (no nested conditionals)
+- Make provision for newer Mandrake releases
+
+* Wed Jun 19 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-1mdk
+- 2.2.5 is out!
+- removed patch27 (included in new release)
+
+* Mon Jun 18 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-0.pre1.5mdk
+- Modifications for samba-2.2.5 source release
+- New samba-vscan (0.2.5a)
+- Samba releases will be 1.prelease.mdk (to upgrade prereleases nicely).
+
+* Mon Jun 17 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-0.pre1.4mdk
+- docs are now 755.
+- Please TEST, REBUILD with or without LDAP etc., and report any errors... Thanks!
+
+* Mon Jun 17 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-0.pre1.3mdk
+- s/%%define/%%global for macros used for package definitions (so --with
+ ldap and --with sophos actually build appropriate packages f.e.)
+- Obsoletes: samba in samba-server
+- Prevent vscan vfs objects going into samba-server (!deps on scanner)
+- Disable automatic dependency checks for vscan subpackages
+- Build vfs objects in a copy of examples (examples.bin) so no bins in doc
+- Make vi faster ;-) (remove spurious single quote in swat description)
+- Add doc (INSTALL) for vscan packages
+- Try and sort out dependencies and conflicts
+
+* Fri Jun 14 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-0.pre1.2mdk
+- Patch27 (prevent all samba binaries linking to libldap)
+- New samba-swat-ldap and samba-winbind-ldap packages
+- move smbcacls to samba-common(-ldap), since it links to libldap
+- Only packages which don't build ldap-specific are nss_wins,doc and client
+
+* Mon Jun 10 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.5-0.pre1.1mdk
+- Introduce new samba-server-ldap and samba-common-ldap packages
+
+* Mon Jun 10 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.5-0.pre1.0mdk
+- first release with 2.2.5pre1.
+- samba-*.rpm now renamed samba-server-*.rpm
+- vfs modules are back in town
+
+* Tue Jun 04 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.4-5mdk
+- changed vfs location in sample mdk smb.conf.
+
+* Mon Jun 03 2002 Buchan Milne <bgmilne@linux-mandrake.com> 2.2.4-4mdk
+- More patch cleaning
+- Antivirus support (optional at build time). Please test if you have one of
+ fprot, kaspersky,mks,symantec or trend. Sophos has been tested and builds
+ and works.
+- Move all vfs objects to /usr/lib/samba/vfs
+
+* Mon May 27 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.4-3mdk
+- Rollup patch for most of the printing fixes in SAMBA_2_2. (-- Jerry Carter)
+- build + install VFS objects
+- patched VFS network recycle_bin (-- Kohei Yoshida)
+- added VFS examples in smb.conf
+
+* Mon May 13 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.4-2mdk
+- Cleaned a few useless patches.
+- Added a few codepages.
+- LDAP support in option.
+
+* Fri May 03 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.4-1mdk
+- Upped to 2.2.4.
+- Default build for cooker now includes LDAP support (as in 2.2.X).
+- Commented pversion/prelease defs.
+- Modif of the Cooker detection routine (use of grep).
+
+* Fri Apr 26 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3a-12mdk
+- Final changes for 2.2.4 release
+- Removed patches 4(nsl),11(smbspool-guest)
+- Made patch 7 (2.2.3a-init) release specific
+
+* Sun Apr 21 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3a-11mdk
+- Tested with CVS snapshot (upcoming relaese, sync packaging)
+- Added detection of samba-official release (so we can keep one spec
+ file in sync in both cvs trees)
+- Add Distro-detection(tm) (allows us to remove some arbitrary repitition)
+- Made patches 20,21,23 (merged upstream), and 22 (breaks pam_smbpass
+ compilation, pam_smbpass.so seems to be built correctly without it)
+ version-specific
+- Removed patches 18,19 (only applicable to 2.2.2)
+
+* Sat Mar 16 2002 Pixel <pixel@mandrakesoft.com> 2.2.3a-10mdk
+- fix Patch 7 to fix samba not starting at boot time
+
+* Tue Mar 12 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-9mdk
+- Patch 7 to fix samba not starting at boot time (-- Pixel)
+
+* Sat Mar 9 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-8mdk
+- Patch 23 from CVS to fix saving changes in printer properties (-- Gerald Carter)
+
+* Fri Mar 8 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-7mdk
+- Added a few new codepage/character sets.
+- replace deletion of /var/cache/samba by simple backup when removing samba
+ to avoid loosing winbind rid->uid map and print driver tdbs.
+- Moved /var/cache/samba migration process from %post samba to %post samba-common.
+- Moved require xinetd from samba to samba-swat.
+
+* Mon Feb 27 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-6mdk
+- Fixed pam_smbpass compiling problem. (-- Ilia Chipitsine)
+- moved /var/cache/samba from server to common as it's used by client too.
+- symlinked smbwrapper.so back to /usr/bin to fix smbsh pb. (-- Alexander Skwar)
+- added %_post/preun_service macro for smb & winbind.
+
+* Fri Feb 22 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-5mdk
+- added cli_spoolss_notify patch to prevent smbd dying when a printer
+ is opened from Win2k. (-- Gerald Carter)
+
+* Mon Feb 18 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-4mdk
+- fixed the chkconfig --reset when upgrading form previos version.
+- added correct LDAP schema in example section.
+
+* Fri Feb 08 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-3mdk
+- _Really_ suid back smbumount; OK, you can laugh now...
+
+* Fri Feb 08 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-2mdk
+- suid back smbumount.
+
+* Thu Feb 07 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.3a-1mdk
+- upped to 2.2.3a bugfix version.
+- removed suid on smb(u)mount, suid smbmnt instead.
+
+* Mon Feb 04 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3-2mdk
+- Added --without xxx support for all the --with xxx command-
+ line options. Now also detects (and warns) when built
+ for non-default distro.
+- Fix %post -n samba-winbind
+
+* Mon Feb 04 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3-1mdk
+- Samba-2.2.3. Disabled patches 6,18,19, which should have been
+ applied in samba CVS.
+
+* Sun Feb 03 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.2-10mdk
+- Reenable patches 6 and 19 (applied in CVS, but this is 2.2.2!)
+- Added option to use --with xxx when building, options so far
+ for mdk72, mdk80, mdk81, mdk82, cooker, ldap, winbind, wins, acl
+- Put warning text in %description if the RPM was built with
+ non-defaults.
+
+* Mon Jan 21 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.2-9mdk
+- Fixed %post scripts here and there.
+- samba-common %post scriptlet is now clean (-- thanks Zytho).
+
+* Mon Jan 21 2002 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.2-8mdk
+- rebuilt on cooker.
+- please test extensively this package,
+ but consider our target _is_ 2.2.3.
+
+* Thu Jan 17 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.2-7mdk
+- Make a 2.2.2 package for the changes in 2.2.3:
+- reenable XFS quota patch, turned off ldap
+
+* Thu Jan 17 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3-0.20020117mdk
+- New scripts for winbind from 3.0alpha spec file
+
+* Wed Jan 16 2002 Buchan Milne <bgmilne@cae.co.za> 2.2.3-0.20020116mdk
+- Updated CVS snapshot
+
+* Sun Dec 23 2001 Buchan Milne <bgmilne@cae.co.za> 2.2.3-0.20011222mdk
+- New CVS snapshot
- Sync up with changes made in 2.2.2 to support Mandrake 8.0, 7.2
- Added new subpackage for swat
-- More if's for ldap.
-
-* Thu Dec 20 2001 Buchan Milne <bgmilne@cae.co.za> 3.0-alpha11-0.0mdk
-- 3.0-alpha11
-
-* Wed Dec 19 2001 Buchan Milne <bgmilne@cae.co.za> 3.0alpha10-0.0mdk
-- 3.0-alpha10
-
-* Tue Dec 18 2001 Buchan Milne <bgmilne@cae.co.za> 3.0alpha9-0.0mdk
-- 3.0-alpha9
-
-* Mon Dec 17 2001 Buchan Milne <bgmilne@cae.co.za> 3.0alpha8-0.1mdk
-- Added net command to %files common, pdbedit and smbgroupedit to
- %files, s/%{prefix}\/bin/%{_bindir}/ (the big cleanup).
- Added patch to smb.init from 2.2.2 (got missed with 3.0-alpha1 patches)
-
-* Sun Dec 16 2001 Buchan Milne <bgmilne@cae.co.za> 3.0alpha8-0.0mdk
-- Patch for installman.sh to handle lang=en correctly (p24)
-- added --with-manpages-langs=en,ja,pl (translated manpages), but there
- aren't any manpages for these languages yet ... so we still
- need %dir and %doc entries for them ...
-- patch (p25) to configure.in to support more than 2 languages.
-- addtosmbpass seems to have returned for now, but make_* have disappeared!
-
-* Fri Dec 14 2001 Buchan Milne <bgmilne@cae.co.za> 3.0alpha6-0.0mdk
-- DESTDIR patch for Makefile.in (p23), remove a lot of %%install scripts
- this forces move of smbcontrol and smbmnt to %{prefix}/bin
- removed --with-pam_smbpass as it doesn't compile.
-
-* Thu Dec 06 2001 Buchan Milne <bgmilne@cae.co.za> 3.0-0.0alpha1mdk
-- Samba 3.0alpha1 released (we missed Samba 3.0alpha0!)
-- Redid smbmount-sbin patch and smb.conf patch (20), removed xfs quota patch
- (applied upstream), removed ook-patch (codepage directory totally different).
-- Added winbind.init (21) and system-auth-winbind.pamd (22). Patches 20-23
- should be applied upstream before 3.0 ships ...
+- More %if's for ldap.
+
+* Thu Dec 06 2001 Buchan Milne <bgmilne@cae.co.za> 2.2.3-0.20011205mdk
+- Build from CVS snapshot of SAMBA_2_2 to test XFS quotas
+- Removed XFS quota patch (applied upstream)
* Wed Dec 05 2001 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.2-6mdk
- fixed typo in system-auth-winbind.pamd (--Thanks J. Gluck).
- fixed %post xxx problem (smb not started in chkconfig --Thanks Viet & B. Kenworthy).
* Fri Nov 23 2001 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.2-5mdk
-- Had to remove the network recycle bin patch: it seems to mess up
+- Had to remove the network recycle bin patch: it seems to mess up
file deletion from windows (files appear to be "already in use")
* Tue Nov 13 2001 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.2-4mdk
@@ -2012,7 +1852,7 @@ update-alternatives --auto smbclient
- cleanup /var/lib/samba/codepage/src
* Tue Aug 21 2001 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.1a-7mdk
-- moved codepage generation to %%install and codepage dir to /var/lib/samba
+- moved codepage generation to %install and codepage dir to /var/lib/samba
* Tue Aug 21 2001 Sylvestre Taburet <staburet@mandrakesoft.com> 2.2.1a-6mdk
- /lib/* was in both samba and samba-common
diff --git a/packaging/Mandrake/smb.conf b/packaging/Mandrake/smb.conf
index 6c1c05fa52e..fe23ee36c3b 100644
--- a/packaging/Mandrake/smb.conf
+++ b/packaging/Mandrake/smb.conf
@@ -48,6 +48,7 @@
# server. The printer admins (or root) may install drivers onto samba.
# Note that this feature uses the print$ share, so you will need to
# enable it below.
+# This parameter works like domain admin group:
# printer admin = @<group> <user>
; printer admin = @adm
# This should work well for winbind:
@@ -112,7 +113,7 @@
# enable pam password change
; pam password change = yes
; passwd program = /usr/bin/passwd %u
-; passwd chat = *New*UNIX*password* %n\n *Re*ype*new*UNIX*password* %n\n \
+; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n
;*passwd:*all*authentication*tokens*updated*successfully*
# Unix users can map to different SMB User names
@@ -212,66 +213,28 @@
# impacts where Win2k finds it's /HOME share
; logon home = \\%L\%U\.profile
-
# The add user script is used by a domain member to add local user accounts
-# that have been authenticated by the domain controller, or when adding
-# users via the Windows NT Tools (ie User Manager for Domains).
-
-# Scripts for file (passwd, smbpasswd) backend:
-; add user script = /usr/sbin/useradd -s /bin/false '%u'
-; delete user script = /usr/sbin/userdel '%s'
-; add user to group script = /usr/bin/gpasswd -a '%u' '%g'
-; delete user from group script = /usr/bin/gpasswd -d '%u' '%g'
-; set primary group script = /usr/sbin/usermod -g '%g' '%u'
-; add group script = /usr/sbin/groupadd %g && getent group '%g'|awk -F: '{print $3}'
-; delete group script = /usr/sbin/groupdel '%g'
-
-# Scripts for LDAP backend (assumes nss_ldap is in use on the domain controller,
-# and needs configuration in smbldap_conf.pm
-; add user script = /usr/share/samba/scripts/smbldap-useradd.pl '%u'
-; delete user script = /usr/share/samba/scripts/smbldap-userdel.pl '%u'
-; add user to group script = /usr/share/samba/scripts/smbldap-groupmod.pl -m '%u' '%g'
-; delete user from group script = /usr/share/samba/scripts/smbldap-groupmod.pl -x '%u' '%g'
-; set primary group script = /usr/share/samba/scripts/smbldap-usermod.pl -g '%g' '%u'
-; add group script = /usr/share/samba/scripts/smbldap-groupadd.pl '%g' && /usr/share/samba/scripts/smbldap-groupshow.pl %g|awk '/^gidNumber:/ {print $2}'
-; delete group script = /usr/share/samba/scripts/smbldap-userdel.pl '%g'
-
-
-# The add machine script is use by a samba server configured as a domain
+# that have been authenticated by the domain controller, or by the domain
# controller to add local machine accounts when adding machines to the domain.
# The script must work from the command line when replacing the macros,
# or the operation will fail. Check that groups exist if forcing a group.
# Script for domain controller for adding machines:
-; add machine script = /usr/sbin/useradd -d /dev/null -g machines -c 'Machine Account' -s /bin/false -M %u
+; add user script = /usr/sbin/useradd -d /dev/null -g machines -c 'Machine Account' -s /bin/false -M %u
# Script for domain controller with LDAP backend for adding machines (please
# configure in /etc/samba/smbldap_conf.pm first):
-; add machine script = /usr/share/samba/scripts/smbldap-useradd.pl -w -d /dev/null -g machines -c 'Machine Account' -s /bin/false %u
+; add user script = /usr/share/samba/scripts/smbldap-useradd.pl -w -d /dev/null -g machines -c 'Machine Account' -s /bin/false %u
+# Script for domain member for adding local accounts for authenticated users:
+; add user script = /usr/sbin/useradd -s /bin/false %u
# Domain groups:
-# Domain groups are now configured by using the 'net groupmap' tool
-
-# Samba Password Database configuration:
-# Samba now has runtime-configurable password database backends. Multiple
-# passdb backends may be used, but users will only be added to the first one
-# Default:
-; passdb backend = smbpasswd guest
-# TDB backen with fallback to smbpasswd and guest
-; passdb backend = tdbsam smbpasswd guest
-# LDAP with fallback to smbpasswd guest
-# Enable SSL by using an ldaps url, or enable tls with 'ldap ssl' below.
-; passdb backend = ldapsam:ldaps://ldap.mydomain.com smbpasswd guest
-# Use the samba2 LDAP schema:
-; passdb backend = ldapsam_compat:ldaps://ldap.mydomain.com smbpasswd guest
-
-# Idmap settings:
-# Idmap backend to use:
-; idmap backend = ldap:ldap://ldap.mydomain.com
-
-# This is a range of unix user-id's that samba will map non-unix RIDs to,
-# such as when using Winbind
-; idmap uid = 10000-20000
-; idmap gid = 10000-20000
-
+# domain admin group is a list of unix users or groups who are made members
+# of the Domain Admin group
+; domain admin group = root @adm
+#
+# domain guest groups is a list of unix users or groups who are made members
+# of the Domain Guests group
+; domain guest group = nobody @guest
+
# LDAP configuration for Domain Controlling:
# The account (dn) that samba uses to access the LDAP server
# This account needs to have write access to the LDAP tree
@@ -282,18 +245,7 @@
# start_tls should run on 389, but samba defaults incorrectly to 636
; ldap port = 389
; ldap suffix = dc=mydomain,dc=com
-# Seperate suffixes are available for machines, users, groups, and idmap, if
-# ldap suffix appears first, it is appended to the specific suffix.
-# Example for a unix-ish directory layout:
-; ldap machine suffix = ou=Hosts
-; ldap user suffix = ou=People
-; ldap group suffix = ou=Group
-; ldap idmap suffix = ou=Idmap
-# Example for AD-ish layout:
-; ldap machine suffix = cn=Computers
-; ldap user suffix = cn=Users
-; ldap group suffix = cn=Groups
-; ldap idmap suffix = cn=Idmap
+; ldap server = ldap.mydomain.com
# 7. Name Resolution Options:
@@ -347,8 +299,8 @@
# UNIX: ISO8859-1 (Western European), ISO8859-2 (Eastern Eu.),
# ISO8859-5 (Russian Cyrillic), KOI8-R (Alt-Russ. Cyril.)
# This is an example for french users:
-; dos charset = 850
-; unix charset = ISO8859-1
+; client code page = 850
+; character set = ISO8859-1
#============================ Share Definitions ==============================
@@ -362,6 +314,9 @@
# all users will have write access to it. See
# examples/VFS/recycle/REAME in samba-doc for details
; vfs object = /usr/lib/samba/vfs/recycle.so
+; vfs options= /etc/samba/recycle.conf
+# You may want to prevent abuse of your server disk space, and spread of virii
+; veto files = /*.eml/*.nws/*.dll/*.mp3/*.MP3/*.mpg/*.MPG/*.vbs/*.VBS/
# Un-comment the following and create the netlogon directory for Domain Logons
; [netlogon]
@@ -373,7 +328,7 @@
#Uncomment the following 2 lines if you would like your login scripts to
#be created dynamically by ntlogon (check that you have it in the correct
#location (the default of the ntlogon rpm available in contribs)
-;root preexec = /usr/bin/ntlogon -u %U -g %G -o %a -d /var/lib/samba/netlogon
+;root preexec = /usr/bin/ntlogon -u %U -g %G -o %a -d /var/lib/samba/netlogon/
;root postexec = rm -f /var/lib/samba/netlogon/%U.bat
# Un-comment the following to provide a specific roving profile share
@@ -382,22 +337,21 @@
; path = /var/lib/samba/profiles
; browseable = no
; guest ok = yes
+; writable = yes
# This script can be enabled to create profile directories on the fly
# You may want to turn off guest acces if you enable this, as it
# hasn't been thoroughly tested.
-;root preexec = PROFILE=/var/lib/samba/profiles/%u; if [ ! -e $PROFILE ]; \
-; then mkdir -pm700 $PROFILE; chown %u.%g $PROFILE;fi
+; root preexec = PROFILE=/var/lib/samba/profiles/%u; if [ ! -e $PROFILE ]; \
+; then mkdir -pm700 $PROFILE; chown %u.%g $PROFILE;fi
+
# NOTE: If you have a CUPS print system there is no need to
# specifically define each individual printer.
# You must configure the samba printers with the appropriate Windows
-# drivers on your Windows clients or upload the printer driver to the
-# server from Windows (NT/2000/XP). On the Samba server no filtering is
+# drivers on your Windows clients. On the Samba server no filtering is
# done. If you wish that the server provides the driver and the clients
# send PostScript ("Generic PostScript Printer" under Windows), you have
-# to use 'printcap name = cups' or swap the 'print command' line below
-# with the commented one. Note that print commands only work if not using
-# 'printing=cups'
+# to swap the 'print command' line below with the commented one.
[printers]
comment = All Printers
path = /var/spool/samba
@@ -411,7 +365,11 @@
# print command: see above for details.
# =====================================
print command = lpr-cups -P %p -o raw %s -r # using client side printer drivers.
-; print command = lpr-cups -P %p %s # using cups own drivers (use generic PostScript on clients).
+; print command = lpr-cups -P %p %s -r # using cups own drivers (use generic PostScript on clients).
+# The following two commands are the samba defaults for printing=cups
+# change them only if you need different options:
+; lpq command = lpq -P %p
+; lprm command = cancel %p-%j
# This share is used for Windows NT-style point-and-print support.
# To be able to install drivers, you need to be either root, or listed
@@ -419,33 +377,22 @@
# to the directory and share definition to be able to upload the drivers.
# For more information on this, please see the Printing Support Section of
# /usr/share/doc/samba-<version>/docs/Samba-HOWTO-Collection.pdf
-#
-# A special case is using the CUPS Windows Postscript driver, which allows
-# all features available via CUPS on the client, by publishing the ppd file
-# and the cups driver by using the 'cupsaddsmb' tool. This requires the
-# installation of the CUPS driver (http://www.cups.org/windows.php)
-# on the server, but doesn't require you to use Windows at all :-).
[print$]
path = /var/lib/samba/printers
browseable = yes
+ read only = yes
write list = @adm root
- guest ok = yes
- inherit permissions = yes
- # Settings suitable for Winbind:
- ; write list = @"Domain Admins" root
- ; force group = +@"Domain Admins"
# A useful application of samba is to make a PDF-generation service
# To streamline this, install windows postscript drivers (preferably colour)
# on the samba server, so that clients can automatically install them.
-# Note that this only works if 'printing' is *not* set to 'cups'
[pdf-generator]
path = /var/tmp
guest ok = No
printable = Yes
comment = PDF Generator (only valid users)
- #print command = /usr/share/samba/scripts/print-pdf file path win_path recipient IP &
+ #print command = /usr/share/samba/scripts/print-pdf file path win_path recipient IP doc_name &
print command = /usr/share/samba/scripts/print-pdf %s ~%u //%L/%u %m %I "%J" &
# This one is useful for people to share files
diff --git a/packaging/Mandrake/smb.init b/packaging/Mandrake/smb.init
index c5d3c8dc21e..bdc15187095 100755
--- a/packaging/Mandrake/smb.init
+++ b/packaging/Mandrake/smb.init
@@ -29,7 +29,7 @@ start() {
# If CUPS is used as printing system, reload smb after a 1 minute delay
# to allow the printers to appear properly as samba shares.
if killall -0 cupsd 2>/dev/null; then
- ( sleep 60 && killproc smbd -HUP 1>/dev/null) &
+ ( sleep 60 && killproc smbd -HUP ) &
fi
export TMPDIR="/var/tmp"
echo -n "Starting SMB services: "
diff --git a/packaging/Mandrake/smbmount-sbin.patch.bz2 b/packaging/Mandrake/smbmount-sbin.patch.bz2
new file mode 100755
index 00000000000..667e2af363a
--- /dev/null
+++ b/packaging/Mandrake/smbmount-sbin.patch.bz2
Binary files differ
diff --git a/packaging/Mandrake/smbprint b/packaging/Mandrake/smbprint
index b5f689f2912..0d07c9c7833 100755
--- a/packaging/Mandrake/smbprint
+++ b/packaging/Mandrake/smbprint
@@ -74,4 +74,4 @@ echo "server $server, service $service" >> $logfile
# echo translate
echo "print -"
cat
-) | /usr/bin/smbclient "//$server/$service" $password -U $server -N >> $logfile
+) | /usr/bin/smbclient "//$server/$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/Mandrake/smbw.patch.bz2 b/packaging/Mandrake/smbw.patch.bz2
new file mode 100755
index 00000000000..5cb7361d17d
--- /dev/null
+++ b/packaging/Mandrake/smbw.patch.bz2
Binary files differ
diff --git a/packaging/Mandrake/swat_16.png.bz2 b/packaging/Mandrake/swat_16.png.bz2
deleted file mode 100644
index 25522cab06b..00000000000
--- a/packaging/Mandrake/swat_16.png.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/Mandrake/swat_16.xpm.bz2 b/packaging/Mandrake/swat_16.xpm.bz2
new file mode 100755
index 00000000000..c17430c5890
--- /dev/null
+++ b/packaging/Mandrake/swat_16.xpm.bz2
Binary files differ
diff --git a/packaging/Mandrake/swat_32.png.bz2 b/packaging/Mandrake/swat_32.png.bz2
deleted file mode 100644
index 737d16034fa..00000000000
--- a/packaging/Mandrake/swat_32.png.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/Mandrake/swat_32.xpm.bz2 b/packaging/Mandrake/swat_32.xpm.bz2
new file mode 100755
index 00000000000..c8e4df6bff7
--- /dev/null
+++ b/packaging/Mandrake/swat_32.xpm.bz2
Binary files differ
diff --git a/packaging/Mandrake/swat_48.png.bz2 b/packaging/Mandrake/swat_48.png.bz2
deleted file mode 100644
index 3e921c1feb5..00000000000
--- a/packaging/Mandrake/swat_48.png.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/Mandrake/swat_48.xpm.bz2 b/packaging/Mandrake/swat_48.xpm.bz2
new file mode 100755
index 00000000000..812b737b4f4
--- /dev/null
+++ b/packaging/Mandrake/swat_48.xpm.bz2
Binary files differ
diff --git a/packaging/Mandrake/system-auth b/packaging/Mandrake/system-auth
new file mode 100755
index 00000000000..6b415e012c4
--- /dev/null
+++ b/packaging/Mandrake/system-auth
@@ -0,0 +1,14 @@
+#%PAM-1.0
+
+auth required /lib/security/pam_env.so
+auth sufficient /lib/security/pam_unix.so likeauth nullok
+auth required /lib/security/pam_deny.so
+
+account required /lib/security/pam_unix.so
+
+password required /lib/security/pam_cracklib.so retry=3
+password sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow
+password required /lib/security/pam_deny.so
+
+session required /lib/security/pam_limits.so
+session required /lib/security/pam_unix.so
diff --git a/packaging/Mandrake/winbind.init b/packaging/Mandrake/winbind.init
index 06e5b375d0c..b7b452eb0b9 100644
--- a/packaging/Mandrake/winbind.init
+++ b/packaging/Mandrake/winbind.init
@@ -28,7 +28,7 @@ RETVAL=0
start() {
echo -n "Starting Winbind services: "
RETVAL=1
- if [ "`grep -i -E '(idmap|winbind) uid' /etc/samba/smb.conf | egrep -v [\#\;]`" -a "`grep -i -E '(idmap|winbind) gid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
+ if [ "`grep -i 'winbind uid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
daemon winbindd
RETVAL=$?
else
@@ -42,7 +42,7 @@ start() {
stop() {
echo -n "Shutting down Winbind services: "
RETVAL=1
- if [ "`grep -i 'winbind uid' /etc/samba/smb.conf | egrep -v [\#\;]`" -a "`grep -i 'idmap gid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
+ if [ "`grep -i 'winbind uid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
killproc winbindd
RETVAL=$?
fi
diff --git a/packaging/Mandrake/wrepld.init b/packaging/Mandrake/wrepld.init
deleted file mode 100644
index b8057f5f40a..00000000000
--- a/packaging/Mandrake/wrepld.init
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/sh
-#
-# chkconfig: 345 81 45
-# description: Starts and stops the Samba wrepld daemon to provide \
-# WINS replication services between WINS partner servers.
-
-# Source function library.
-if [ -f /etc/init.d/functions ] ; then
- . /etc/init.d/functions
-elif [ -f /etc/rc.d/init.d/functions ] ; then
- . /etc/rc.d/init.d/functions
-else
- exit 0
-fi
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
-
-# Check that smb.conf exists.
-[ -f /etc/samba/smb.conf ] || exit 0
-
-RETVAL=0
-
-
-start() {
- echo -n "Starting WINS Replication services: "
- RETVAL=1
- if [ "`grep -i 'wins partners' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
- daemon wrepld
- RETVAL=$?
- else
- echo "WINS replication is not configured in /etc/samba/smb.conf, not starting"
- fi
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/wrepld || \
- RETVAL=1
- return $RETVAL
-}
-stop() {
- echo -n "Shutting down WINS replication services: "
- RETVAL=1
- if [ "`grep -i 'wins partners' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
- killproc wrepld
- RETVAL=$?
- fi
- echo
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/wrepld
- return $RETVAL
-}
-restart() {
- stop
- start
-}
-reload() {
- export TMPDIR="/var/tmp"
- echo -n "Reloading WINS replication: "
- killproc wrepld -HUP
- RETVAL=$?
- echo
- return $RETVAL
-}
-mdkstatus() {
- status wrepld
-}
-
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload
- ;;
- status)
- mdkstatus
- ;;
- condrestart)
- [ -f /var/lock/subsys/wrepld ] && restart || :
- ;;
- *)
- echo "Usage: $0 {start|stop|restart|status|condrestart}"
- exit 1
-esac
-
-exit $?
diff --git a/packaging/PHT/TurboLinux/README b/packaging/PHT/TurboLinux/README
new file mode 100755
index 00000000000..867ff01811b
--- /dev/null
+++ b/packaging/PHT/TurboLinux/README
@@ -0,0 +1,11 @@
+Preparation Date: October 25, 1998
+Preparer: John H Terpstra <jht@samba.org>
+
+Instructions: Preparing Samba Packages for TurboLinux
+===============================================================
+
+We provide support only for current versions of TurboLinux.
+
+To produce the RPMS simply type:
+ sh makerpms.sh
+
diff --git a/packaging/PHT/TurboLinux/findsmb b/packaging/PHT/TurboLinux/findsmb
new file mode 100755
index 00000000000..04bc6080508
--- /dev/null
+++ b/packaging/PHT/TurboLinux/findsmb
@@ -0,0 +1,145 @@
+#!/usr/bin/perl
+#
+# Prints info on all smb responding machines on a subnet.
+# This script needs to be run on a machine without nmbd running and be
+# run as root to get correct info from WIN95 clients.
+#
+# syntax:
+# findsmb [subnet broadcast address]
+#
+# with no agrument it will list machines on the current subnet
+#
+# There will be a "+" in front of the workgroup name for machines that are
+# local master browsers for that workgroup. There will be an "*" in front
+# of the workgroup name for machines that are the domain master browser for
+# that workgroup.
+#
+
+$SAMBABIN = "/usr/bin";
+
+for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } else {
+ if ($_) {
+ $BCAST = "-B $_";
+ }
+ }
+}
+
+sub ipsort # do numeric sort on last field of IP address
+{
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
+}
+
+# look for all machines that respond to a name lookup
+
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*'|") ||
+ die("Can't run nmblookup '*'.\n");
+
+# get rid of all lines that are not a response IP address,
+# strip everything but IP address and sort by last field in address
+
+@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
+
+# print header info
+
+print "\nIP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
+print "---------------------------------------------------------------------\n";
+
+foreach $ip (@ipaddrs) # loop through each IP address found
+{
+ $ip =~ s/\n//; # strip newline from IP address
+
+# find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -r -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+# get the first <00> name
+
+ @name = grep(/<00>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) { # we have a netbios name
+ if (/GROUP/) { # is it a group name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ } else {
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cure inside name space but not
+# names starting or ending with spaces
+ /(.{1,15})\s+<00>\s+/;
+ $name = $1;
+ }
+
+# do an smbclient command on the netbios name.
+
+ open(SMB,"$SAMBABIN/smbclient -N -L $name -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+# look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+# for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+# Same as before for space and characters
+ /(.{1,15})\s+<00>\s+/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+
+# see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+# line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
+
+ } else { # no netbios name found
+# try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup
+ print "===============================================================\n";
+ print @nmblookup;
+ }
+ print "$ip".' 'x(16-length($ip))."$name\n";
+ }
+}
+
diff --git a/packaging/PHT/TurboLinux/makerpms.sh.tmpl b/packaging/PHT/TurboLinux/makerpms.sh.tmpl
new file mode 100755
index 00000000000..c389bf1a68a
--- /dev/null
+++ b/packaging/PHT/TurboLinux/makerpms.sh.tmpl
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Copyright (C) 1998 John H Terpstra, 1999 K Spoon
+#
+SPECDIR=/usr/src/turbo/SPECS
+SRCDIR=/usr/src/turbo/SOURCES
+USERID=`id -u`
+GRPID=`id -g`
+
+( cd ../../../.. ; chown -R ${USERID}.${GRPID} ${SRCDIR}/samba-PVERSION )
+( cd ../../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION )
+cp -a *.spec $SPECDIR
+cp -a *.patch smb.* samba.log $SRCDIR
+cd $SPECDIR
+rpm -ba -v samba2.spec
diff --git a/packaging/PHT/TurboLinux/samba.log b/packaging/PHT/TurboLinux/samba.log
new file mode 100755
index 00000000000..c5f2a5b45bc
--- /dev/null
+++ b/packaging/PHT/TurboLinux/samba.log
@@ -0,0 +1,11 @@
+/var/log/samba/log.nmb {
+ postrotate
+ /usr/bin/killall -HUP nmbd
+ endrotate
+}
+
+/var/log/samba/log.smb {
+ postrotate
+ /usr/bin/killall -HUP smbd
+ endrotate
+}
diff --git a/packaging/PHT/TurboLinux/samba.pamd b/packaging/PHT/TurboLinux/samba.pamd
new file mode 100755
index 00000000000..225ab724ec9
--- /dev/null
+++ b/packaging/PHT/TurboLinux/samba.pamd
@@ -0,0 +1,11 @@
+#%PAM-1.0
+#[For version 1.0 syntax, the above header is optional]
+#
+# The PAM configuration file for the `samba' service
+#
+auth required /lib/security/pam_pwdb.so nullok nodelay # shadow audit
+# auth required /lib/security/pam_smbpass.so nodelay
+account required /lib/security/pam_pwdb.so audit nodelay
+session required /lib/security/pam_pwdb.so nodelay
+password required /lib/security/pam_pwdb.so # shadow md5
+#password required /lib/security/pam_smbpass.so nodelay smbconf=/etc/samba.d/smb.conf
diff --git a/packaging/PHT/TurboLinux/samba2.spec.tmpl b/packaging/PHT/TurboLinux/samba2.spec.tmpl
new file mode 100755
index 00000000000..5f586f0bbca
--- /dev/null
+++ b/packaging/PHT/TurboLinux/samba2.spec.tmpl
@@ -0,0 +1,513 @@
+Summary: Samba SMB client and server
+Name: samba
+Version: PVERSION
+Release: PRELEASE
+Copyright: GNU GPL version 2
+Group: Networking
+Source: ftp://samba.org/pub/samba/samba-PVERSION.tar.gz
+Patch: smbw.patch
+Requires: pam >= 0.64 kernel >= 2.2.1 glibc >= 2.1.2
+Prereq: chkconfig fileutils
+BuildRoot: /var/tmp/samba
+Prefix: /usr
+
+%package -n smbfs
+Version: PVERSION
+Release: PRELEASE
+Group: Utilities/File
+Summary: Programs to mount SMB shares.
+
+%description
+Samba provides an SMB server which can be used to provide
+network services to SMB (sometimes called "Lan Manager")
+clients, including various versions of MS Windows, OS/2,
+and other Linux machines. Samba also provides some SMB
+clients, which complement the built-in SMB filesystem
+in Linux. Samba uses NetBIOS over TCP/IP (NetBT) protocols
+and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
+protocol.
+
+Samba-2.2 features working NT Domain Control capability and
+includes the SWAT (Samba Web Administration Tool) that
+allows samba's smb.conf file to be remotely managed using your
+favourite web browser. For the time being this is being
+enabled on TCP port 901 via inetd.
+
+Users are advised to use Samba-2.2 as a Windows NT4
+Domain Controller only on networks that do NOT have a Windows
+NT Domain Controller. This release does NOT as yet have
+Backup Domain control ability.
+
+Please refer to the WHATSNEW.txt document for fixup information.
+This binary release includes encrypted password support.
+
+Please read the smb.conf file and ENCRYPTION.txt in the
+docs directory for implementation details.
+
+NOTE: TurboLinux uses PAM which has integrated support
+for Shadow passwords and quotas. Do NOT recompile with the
+SHADOW_PWD option enabled.
+
+
+%description -n smbfs
+This package includes the tools necessary to mount filesystems from
+SMB servers.
+
+Smbmount and smbumount are an interface to the SMB filesystem. Smbfs is
+a filesystem which understands the SMB protocol. This is the protocol
+Windows for Workgroups, Windows NT or Lan Manager use to talk to each
+other. It was inspired by samba, the program by Andrew Tridgell that
+turns any unix site into a file server for DOS or Windows clients. See
+http://samba.org/samba for this interesting program suite and lots of
+more information on SMB and NetBIOS over TCP/IP. There you also find
+explanation for conceps like NetBIOS name or share.
+
+%changelog
+* Thu Jul 26 2001 John H Terpstra <jht@samba.org>
+- Addded WinBind stuff
+
+* Tue Mar 27 2001 John H Terpstra <jht@samba.org>
+- Fixes to make 2.2 compile
+
+* Sat Nov 04 2000 John H Terpstra <jht@samba.org>
+- Put Symlink for libnss_wins.so back into main install section
+
+* Fri Nov 3 2000 Uros Prestor <uros@turbolinux.com>
+- ported to IA-64
+
+* Mon Oct 09 2000 John H Terpstra <jht@turbolinux.com>
+- Started move to Samba-2.2.0
+- Added nsswitch wins support
+
+* Mon May 29 2000 John H Terpstra <jht@turbolinux.com>
+- moved linkage of libnss_wins.so.2 to %post
+- added removal step to %postun
+
+* Fri Apr 14 2000 John H Terpstra <jht@turbolinux.com>
+- Added unicode pages
+
+* Sat Apr 08 2000 John H Terpsta <jht@turbolinux.com>
+- Added nsswitch stuff
+- Fixed some typos
+- Changed hard link for smbmount to symlink
+
+* Sun Apr 02 2000 John H Terpstra <jht@turbolinux.com>
+- Updated for samba-2.0.7
+- Added codepages 775 1251
+- Added configure options "--with-profile --with-utmp
+ --with-netatalk --with-sambabook=/usr/share/swat/using_samba"
+- added using_samba book
+
+* Fri Oct 29 1999 Kelley Spoon <kspoon@turbolinux.com>
+- get rid of the rc?.d directories
+- -j flags for make command to (hopefully) speed up on
+ SMP systems
+- discoverd that John had already made the changes I
+ was going to do...
+- Wait! He forgot to move the man pages into /usr/share!
+ Cool... I get to do something substantial.
+
+* Sun Oct 16 1999 John H Terspstra <jht@turbolinux.com>
+- changed mount.smb to link to smbmount
+- removed smbwrappers as it is broken with glibc-2.1.x
+
+* Sun May 09 1999 John H Terpstra <jht@samba.org>
+- Added smbtorture et al.
+
+* Wed Mar 10 1999 Scott Stone <sstone@turbolinux.com>
+- This package now builds smbfs stuff
+- Added xinetd autosetup in the post install section
+- (todo: add remove of xinetd stuff in postuninstall section)
+
+* Sun Feb 28 1999 Jeremy Allison <jra@samba.org>
+ - Removed smbrun binary and tidied up some loose ends
+
+* Sun Oct 25 1998 John H Terpstra <jht@samba.org>
+ - Added modifier to /config specifier so that smb.conf,
+ lmhosts and smbusers never get lost
+
+* Sat Oct 24 1998 John H Terpstra <jht@samba.org>
+ - removed README.smbsh file from docs area
+
+* Mon Oct 05 1998 John H Terpstra <jht@samba.org>
+ - Added rpcclient to binaries list
+ - Added smbwrapper stuff
+
+* Fri Aug 21 1998 John H Terpstra <jht@samba.org>
+ - Updated for Samba version 2.0 building
+
+* Tue Jul 07 1998 Erik Troan <ewt@redhat.com>
+ - updated postun triggerscript to check $0
+ - clear /etc/codepages from %preun instead of %postun
+
+* Sat Jul 04 1998 John H Terpstra <jht@samba.org>
+ - fixed codepage preservation during update via -Uvh
+
+* Mon Jun 08 1998 Erik Troan <ewt@redhat.com>
+ - made the %postun script a tad less agressive; no reason to remove
+ the logs or lock file
+ - the %postun and %preun should only exectute if this is the final
+ removal
+ - migrated %triggerpostun from Red Hat's samba package to work around
+ packaging problems in some Red Hat samba releases
+
+* Sun Apr 26 1998 John H Terpstra <jht@samba.org>
+ - Tidy up for early alpha releases
+ - added findsmb from SGI packaging
+
+* Thu Apr 09 1998 John H Terpstra <jht@samba.org>
+ - Updated spec file
+ - Included new codepage.936
+
+* Sat Mar 20 1998 John H Terpstra <jht@samba.org>
+ - Added swat facility
+
+* Sat Jan 24 1998 John H Terpstra <jht@samba.org>
+ - Many optimisations (some suggested by Manoj Kasichainula <manojk@io.com>
+ - Use of chkconfig in place of individual symlinks to /etc/rc.d/init/smb
+ - Compounded make line
+ - Updated smb.init restart mechanism
+ - Use compound mkdir -p line instead of individual calls to mkdir
+ - Fixed smb.conf file path for log files
+ - Fixed smb.conf file path for incoming smb print spool directory
+ - Added a number of options to smb.conf file
+ - Added smbadduser command (missed from all previous RPMs) - Doooh!
+ - Added smbuser file and smb.conf file updates for username map
+
+%prep
+%setup
+%patch -p1
+
+
+%build
+cd source
+
+%ifarch ia64
+libtoolize --copy --force # get it to recognize IA-64
+%endif
+
+autoconf
+autoheader
+NUMCPU=`grep processor /proc/cpuinfo | wc -l`
+CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
+ --libdir=/etc/samba \
+ --prefix=%{prefix} \
+ --with-lockdir=/var/lock/samba \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-privatedir=/etc \
+ --with-profile \
+ --with-quotas \
+ --with-sambabook=%{prefix}/share/swat/using_samba
+ --with-smbmount \
+ --with-swatdir=%{prefix}/share/swat \
+ --with-syslog \
+ --with-utmp \
+ --with-codepagedir=/usr/share/samba/codepages \
+ --with-configdir=/etc/samba \
+ --with-fhs \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-quotas \
+ --with-smbmount \
+ --with-syslog
+ --with-utmp \
+ --without-smbwrapper \
+
+make -j${NUMCPU} all smbfilter nsswitch/libnss_wins.so
+make -j${NUMCPU} debug2html
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/samba/codepages/src
+mkdir -p $RPM_BUILD_ROOT/etc/samba
+mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d}
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+mkdir -p $RPM_BUILD_ROOT/lib
+mkdir -p $RPM_BUILD_ROOT/home/samba
+mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/{gifs,figs}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/man/{man1,man5,man7,man8}
+mkdir -p $RPM_BUILD_ROOT/var/lock/samba
+mkdir -p $RPM_BUILD_ROOT/var/log/samba
+mkdir -p $RPM_BUILD_ROOT/var/spool/samba
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool
+do
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+for i in mksmbpasswd.sh smbtar
+do
+install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat smbmount smbumount smbmnt debug2html smbfilter wbinfo winbindd
+do
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/sbin
+done
+
+
+# Install level 1 man pages
+for i in *.1
+do
+install -m644 docs/manpages/$i $RPM_BUILD_ROOT%{prefix}/share/man/man1
+done
+
+# Install codepage source files
+for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+do
+install -m644 source/codepages/codepage_def.$i $RPM_BUILD_ROOT%{prefix}/share/samba/codepages/src
+done
+for i in 437 737 850 852 861 866 932 936 949 950 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+do
+install -m644 source/codepages/CP$i.TXT $RPM_BUILD_ROOT%{prefix}/share/samba/codepages/src
+done
+
+# Install the nsswitch library extension files
+install -m755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/lib
+install -m755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/lib
+# Make link for wins resolver
+( cd $RPM_BUILD_ROOT/lib; ln -s libnss_wins.so libnss_wins.so.2; )
+( cd $RPM_BUILD_ROOT/lib; ln -s libnss_winbind.so libnss_winbind.so.2; )
+
+# Install PAM pam_smbpass.so
+install -m644 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/lib/security
+install -m644 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/help
+done
+for i in swat/images/*.gif
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/images
+done
+for i in swat/include/*.html
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/include
+done
+
+# This is the O'Reily Samba Book - on-line
+for i in docs/htmldocs/using_samba/*.html
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba
+done
+for i in docs/htmldocs/using_samba/figs/*.gif
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/figs
+done
+for i in docs/htmldocs/using_samba/gifs/*.gif
+do
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/gifs
+done
+
+# Install the miscellany
+install -m644 swat/README $RPM_BUILD_ROOT%{prefix}/share/swat
+install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT%{prefix}/share/man/man5
+install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT%{prefix}/share/man/man5
+install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT%{prefix}/share/man/man5
+install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT%{prefix}/share/man/man7
+install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/smbmount.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/smbmnt.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/smbumount.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 docs/manpages/winbindd.8 $RPM_BUILD_ROOT%{prefix}/share/man/man8
+install -m644 packaging/PHT/TurboLinux/smb.conf $RPM_BUILD_ROOT/etc/samba/smb.conf
+install -m644 packaging/PHT/TurboLinux/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers
+install -m755 packaging/PHT/TurboLinux/smbprint $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/PHT/TurboLinux/findsmb $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/PHT/TurboLinux/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
+install -m755 packaging/PHT/TurboLinux/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
+install -m644 packaging/PHT/TurboLinux/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
+install -m644 packaging/PHT/TurboLinux/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
+echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts
+
+# Link smbmount to /sbin/mount.smb and /sbin/mount.smbfs
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add smb
+/sbin/chkconfig smb off
+
+# Build codepage load files
+cd %{prefix}/share/samba
+for i in 437 737 775 850 852 861 866 932 936 949 950 1251
+do
+%{prefix}/bin/make_smbcodepage c $i %{prefix}/share/samba/codepages/src/codepage_def.$i %{prefix}/share/samba/codepages/codepage.$i
+done
+for i in 437 737 850 852 861 866 932 936 949 950 1251 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R
+do
+%{prefix}/bin/make_unicodemap $i %{prefix}/share/samba/codepages/src/CP$i.TXT %{prefix}/share/samba/codepages/unicode_map.$i
+done
+
+# Add swat entry to /etc/services if not already there
+if !( grep ^[:space:]*swat /etc/services > /dev/null ) then
+ echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
+fi
+
+# Add swat entry to /etc/inetd.conf if needed
+if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
+ echo '#swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf
+ killall -1 inetd || :
+fi
+
+# Now create the xinetd.conf file from our inetd.conf file, back up orig first.
+if [ -f /etc/xinetd.conf ]; then
+ mv /etc/xinetd.conf /etc/xinetd.conf.presamba
+ /usr/sbin/itox --daemon_dir /usr/sbin < /etc/inetd.conf > /etc/xinetd.conf
+fi
+
+
+%preun
+if [ $1 = 0 ] ; then
+ /sbin/chkconfig --del smb
+
+ for n in %{prefix}/share/samba/codepages/*; do
+ if [ $n != %{prefix}/share/samba/codepages/src ]; then
+ rm -rf $n
+ fi
+ done
+ # We want to remove the browse.dat and wins.dat files so they can not interfer with a new version of samba!
+ if [ -e /var/lock/samba/browse.dat ]; then
+ rm -f /var/lock/samba/browse.dat
+ fi
+ if [ -e /var/lock/samba/wins.dat ]; then
+ rm -f /var/lock/samba/wins.dat
+ fi
+fi
+
+%postun
+# Only delete remnants of samba if this is the final deletion.
+if [ $1 = 0 ] ; then
+ if [ -x /etc/pam.d/samba ]; then
+ rm -f /etc/pam.d/samba
+ fi
+ if [ -e /var/log/samba ]; then
+ rm -rf /var/log/samba
+ fi
+
+# Note: We MUST keep:
+# winbindd_*, sshare_info*, printing*, ntdrivers*
+
+ if [ -x /var/lock/samba ]; then
+ rm -f /var/lock/samba/browse.dat
+ rm -f /var/lock/samba/{brlock,connections,locking,messages}.tdb
+ if [ -e /var/lock/samba.d/namelist.debug ]; then
+ rm -f /var/lock/samba.d/namelist.debug
+ fi
+ rm -f /var/lock/samba/unexpected.tdb
+ rm -f /var/lock/samba/{smbd,nmbd}.pid
+ fi
+
+ # Remove swat entries from /etc/inetd.conf and /etc/services
+ cd /etc
+ tmpfile=/etc/tmp.$$
+ sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile
+ mv $tmpfile inetd.conf
+ sed -e '/#swat.*$/d' /etc/inetd.conf > $tmpfile
+ mv $tmpfile inetd.conf
+ sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile
+ mv $tmpfile services
+
+ # Recreate xinetd.conf file from /etc/inetd.conf
+ mv /etc/xinetd.conf /etc/xinetd.conf.samba
+ /usr/sbin/itox --daemon_dir /usr/sbin < /etc/inetd.conf > /etc/xinetd.conf
+fi
+
+
+%triggerpostun -- samba < samba-2.0.0
+if [ $0 != 0 ]; then
+ /sbin/chkconfig --add smb
+fi
+
+
+%files
+%doc README COPYING Manifest Read-Manifest-Now
+%doc WHATSNEW.txt Roadmap
+%doc docs
+%doc swat/README
+%doc examples
+%attr(-,root,root) %{prefix}/sbin/smbd
+%attr(-,root,root) %{prefix}/sbin/nmbd
+%attr(-,root,root) %{prefix}/sbin/swat
+%attr(-,root,root) %{prefix}/sbin/wbinfo
+%attr(-,root,root) %{prefix}/sbin/winbindd
+%attr(-,root,root) %{prefix}/sbin/debug2html
+%attr(0750,root,root) %{prefix}/sbin/samba
+%attr(-,root,root) %{prefix}/bin/smbclient
+%attr(-,root,root) %{prefix}/bin/rpcclient
+%attr(-,root,root) %{prefix}/bin/testparm
+%attr(-,root,root) %{prefix}/bin/testprns
+%attr(-,root,root) %{prefix}/bin/findsmb
+%attr(-,root,root) %{prefix}/bin/smbstatus
+%attr(-,root,root) %{prefix}/bin/nmblookup
+%attr(-,root,root) %{prefix}/bin/make_smbcodepage
+%attr(-,root,root) %{prefix}/bin/make_unicodemap
+%attr(-,root,root) %{prefix}/bin/make_printerdef
+%attr(-,root,root) %{prefix}/bin/smbpasswd
+%attr(-,root,root) %{prefix}/bin/smbtar
+%attr(-,root,root) %{prefix}/bin/smbprint
+%attr(-,root,root) %{prefix}/bin/smbspool
+%attr(755,root,root) /lib/libnss_win*
+%attr(755,root,root) /lib/security/pam_*
+%attr(-,root,root) %{prefix}/share/swat/help/*
+%attr(-,root,root) %{prefix}/share/swat/images/*
+%attr(-,root,root) %{prefix}/share/swat/include/header.html
+%attr(-,root,root) %{prefix}/share/swat/include/footer.html
+%attr(-,root,root) %{prefix}/share/swat/using_samba/*
+%attr(-,root,root) %config(noreplace) /etc/samba/lmhosts
+%attr(-,root,root) %config(noreplace) /etc/samba/smb.conf
+%attr(-,root,root) %config(noreplace) /etc/samba/smbusers
+%attr(-,root,root) /etc/rc.d/init.d/smb
+%attr(-,root,root) /etc/logrotate.d/samba
+%attr(-,root,root) /etc/pam.d/samba
+%attr(-,root,root) %{prefix}/share/samba/codepages/src/codepage_def.*
+%attr(-,root,root) %{prefix}/share/samba/codepages/src/CP*
+# %attr(-,root,root) %{prefix}/share/man/man1/smbsh.1
+%attr(-,root,root) %{prefix}/share/man/man1/make_smbcodepage.1
+%attr(-,root,root) %{prefix}/share/man/man1/make_unicodemap.1
+%attr(-,root,root) %{prefix}/share/man/man1/nmblookup.1
+%attr(-,root,root) %{prefix}/share/man/man1/smbclient.1
+%attr(-,root,root) %{prefix}/share/man/man1/smbrun.1
+%attr(-,root,root) %{prefix}/share/man/man1/smbstatus.1
+%attr(-,root,root) %{prefix}/share/man/man1/smbtar.1
+%attr(-,root,root) %{prefix}/share/man/man1/testparm.1
+%attr(-,root,root) %{prefix}/share/man/man1/testprns.1
+%attr(-,root,root) %{prefix}/share/man/man5/lmhosts.5
+%attr(-,root,root) %{prefix}/share/man/man5/smb.conf.5
+%attr(-,root,root) %{prefix}/share/man/man5/smbpasswd.5
+%attr(-,root,root) %{prefix}/share/man/man7/samba.7
+%attr(-,root,root) %{prefix}/share/man/man8/nmbd.8
+%attr(-,root,root) %{prefix}/share/man/man8/smbd.8
+%attr(-,root,root) %{prefix}/share/man/man8/smbpasswd.8
+%attr(-,root,root) %{prefix}/share/man/man8/swat.8
+%attr(-,root,nobody) %dir /home/samba
+%attr(-,root,root) %dir %{prefix}/share/samba/codepages
+%attr(-,root,root) %dir %{prefix}/share/samba/codepages/src
+%attr(-,root,root) %dir /var/lock/samba
+%attr(-,root,root) %dir /var/log/samba
+%attr(1777,root,root) %dir /var/spool/samba
+
+%files -n smbfs
+%attr(-,root,root) %{prefix}/sbin/smbmount
+%attr(-,root,root) %{prefix}/sbin/smbumount
+%attr(-,root,root) %{prefix}/sbin/smbmnt
+%attr(-,root,root) /sbin/mount.smb
+%attr(-,root,root) /sbin/mount.smbfs
+%attr(-,root,root) %{prefix}/share/man/man8/smbmnt.8
+%attr(-,root,root) %{prefix}/share/man/man8/smbmount.8
+%attr(-,root,root) %{prefix}/share/man/man8/smbumount.8
diff --git a/packaging/Fedora/smb.conf b/packaging/PHT/TurboLinux/smb.conf
index 74806da16bb..e07d15c93ef 100644..100755
--- a/packaging/Fedora/smb.conf
+++ b/packaging/PHT/TurboLinux/smb.conf
@@ -9,7 +9,7 @@
# may wish to enable
#
# NOTE: Whenever you modify this file you should run the command "testparm"
-# to check that you have not made any basic syntactic errors.
+# to check that you have not many any basic syntactic errors.
#
#======================= Global Settings =====================================
[global]
@@ -63,10 +63,10 @@
# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
# Do not enable this option unless you have read those documents
; encrypt passwords = yes
-; smb passwd file = /etc/samba/smbpasswd
+; smb passwd file = /etc/smbpasswd
# The following are needed to allow password changing from Windows to
-# update the Linux system password also.
+# update the Linux sytsem password also.
# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
# NOTE2: You do NOT need these to allow workstations to change only
# the encrypted SMB passwords. They allow the Unix password
@@ -76,12 +76,12 @@
; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
# Unix users can map to different SMB User names
-; username map = /etc/samba/smbusers
+; username map = /etc/smbusers
# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting
-; include = /etc/samba/smb.conf.%m
+; include = /etc/smb.conf.%m
# Most people will find that this option gives better performance.
# See speed.txt and the manual pages for details
@@ -117,6 +117,10 @@
# and gives it a slightly higher chance of winning the election
; preferred master = yes
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = <NT-Domain-Controller-SMBName>
+
# Enable this if you want Samba to be a domain logon server for
# Windows95 workstations.
; domain logons = yes
@@ -220,7 +224,8 @@
; comment = Public Stuff
; path = /home/samba
; public = yes
-; read only = yes
+; writable = yes
+; printable = no
; write list = @staff
# Other examples.
diff --git a/packaging/PHT/TurboLinux/smb.init b/packaging/PHT/TurboLinux/smb.init
new file mode 100755
index 00000000000..03aaceccc51
--- /dev/null
+++ b/packaging/PHT/TurboLinux/smb.init
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# chkconfig: 345 91 35
+# description: Starts and stops the Samba smbd and nmbd daemons \
+# used to provide SMB network services.
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Check that networking is up.
+[ ${NETWORKING} = "no" ] && exit 0
+
+# Check that smb.conf exists.
+[ -f /etc/samba/smb.conf ] || exit 0
+
+# See how we were called.
+case "$1" in
+ start)
+ echo -n "Starting SMB services: "
+ daemon smbd -D
+ daemon nmbd -D
+ daemon winbindd
+ echo
+ touch /var/lock/subsys/smb
+ ;;
+ stop)
+ echo -n "Shutting down SMB services: "
+ killproc winbindd
+ killproc smbd
+ killproc nmbd
+ rm -f /var/lock/subsys/smb
+ echo ""
+ ;;
+ status)
+ status winbind
+ status smbd
+ status nmbd
+ ;;
+ restart)
+ echo -n "Restarting SMB services: "
+ $0 stop
+ $0 start
+ echo "done."
+ ;;
+ *)
+ echo "Usage: smb {start|stop|restart|status}"
+ exit 1
+esac
+
diff --git a/packaging/PHT/TurboLinux/smbadduser b/packaging/PHT/TurboLinux/smbadduser
new file mode 100755
index 00000000000..2f38bf28f1a
--- /dev/null
+++ b/packaging/PHT/TurboLinux/smbadduser
@@ -0,0 +1,73 @@
+#!/bin/csh
+#
+# smbadduser - Written by Mike Zakharoff
+#
+unalias *
+set path = ($path)
+
+set smbpasswd = /etc/smbpasswd
+set user_map = /etc/smbusers
+#
+# Set to site specific passwd command
+#
+set passwd = "cat /etc/passwd"
+#set passwd = "niscat passwd.org_dir"
+#set passwd = "ypcat passwd"
+
+set line = "----------------------------------------------------------"
+if ($#argv == 0) then
+ echo $line
+ echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
+ echo ""
+ echo " 1) Updates $smbpasswd"
+ echo " 2) Updates $user_map"
+ echo " 3) Executes smbpasswd for each new user"
+ echo ""
+ echo "smbadduser unixid:ntid unixid:ntid ..."
+ echo ""
+ echo "Example: smbadduser zak:zakharoffm johns:smithj"
+ echo $line
+ exit 1
+endif
+
+touch $smbpasswd $user_map
+set new = ()
+foreach one ($argv)
+ echo $one | grep ':' >& /dev/null
+ if ($status != 0) then
+ echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
+ continue
+ endif
+ set unix = `echo $one | awk -F: '{print $1}'`
+ set ntid = `echo $one | awk -F: '{print $2}'`
+
+ set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#usr != 1) then
+ echo "ERROR: $unix Not in passwd database SKIPPING..."
+ continue
+ endif
+ set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#tmp != 0) then
+ echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
+ continue
+ endif
+
+ echo "Adding: $unix to $smbpasswd"
+ eval $passwd | \
+ awk -F: '$1==USR { \
+ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
+ if ($unix != $ntid) then
+ echo "Adding: {$unix = $ntid} to $user_map"
+ echo "$unix = $ntid" >> $user_map
+ endif
+ set new = ($new $unix)
+end
+
+#
+# Enter password for new users
+#
+foreach one ($new)
+ echo $line
+ echo "ENTER password for $one"
+ smbpasswd $one
+end
diff --git a/packaging/PHT/TurboLinux/smbprint b/packaging/PHT/TurboLinux/smbprint
new file mode 100755
index 00000000000..ec083eede62
--- /dev/null
+++ b/packaging/PHT/TurboLinux/smbprint
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# This script is an input filter for printcap printing on a unix machine. It
+# uses the smbclient program to print the file to the specified smb-based
+# server and service.
+# For example you could have a printcap entry like this
+#
+# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
+#
+# which would create a unix printer called "smb" that will print via this
+# script. You will need to create the spool directory /usr/spool/smb with
+# appropriate permissions and ownerships for your system.
+
+# Set these to the server and service you wish to print to
+# In this example I have a WfWg PC called "lapland" that has a printer
+# exported called "printer" with no password.
+
+#
+# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
+# so that the server, service, and password can be read from
+# a /var/spool/lpd/PRINTNAME/.config file.
+#
+# In order for this to work the /etc/printcap entry must include an
+# accounting file (af=...):
+#
+# cdcolour:\
+# :cm=CD IBM Colorjet on 6th:\
+# :sd=/var/spool/lpd/cdcolour:\
+# :af=/var/spool/lpd/cdcolour/acct:\
+# :if=/usr/local/etc/smbprint:\
+# :mx=0:\
+# :lp=/dev/null:
+#
+# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
+# server=PC_SERVER
+# service=PR_SHARENAME
+# password="password"
+#
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
+# password=""
+
+#
+# Debugging log file, change to /dev/null if you like.
+#
+# logfile=/tmp/smb-print.log
+logfile=/dev/null
+
+
+#
+# The last parameter to the filter is the accounting file name.
+# Extract the directory name from the file name.
+# Concat this with /.config to get the config file.
+#
+eval acct_file=\${$#}
+spool_dir=`dirname $acct_file`
+config_file=$spool_dir/.config
+
+# Should read the following variables set in the config file:
+# server
+# service
+# password
+eval `cat $config_file`
+
+#
+# Some debugging help, change the >> to > if you want to same space.
+#
+echo "server $server, service $service" >> $logfile
+
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+# echo translate
+ echo "print -"
+ cat
+) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/PHT/TurboLinux/smbusers b/packaging/PHT/TurboLinux/smbusers
new file mode 100755
index 00000000000..ae3389f53f8
--- /dev/null
+++ b/packaging/PHT/TurboLinux/smbusers
@@ -0,0 +1,3 @@
+# Unix_name = SMB_name1 SMB_name2 ...
+root = administrator admin
+nobody = guest pcguest smbguest
diff --git a/packaging/Mandrake/smbw.patch b/packaging/PHT/TurboLinux/smbw.patch
index 0abbfdf73f6..0abbfdf73f6 100644..100755
--- a/packaging/Mandrake/smbw.patch
+++ b/packaging/PHT/TurboLinux/smbw.patch
diff --git a/packaging/README b/packaging/README
index 74445508e0b..ce651377907 100644
--- a/packaging/README
+++ b/packaging/README
@@ -1,9 +1,7 @@
-Copyright (C) 1997-2003 Samba-Team
+Copyright (C) 1997-1998 Samba-Team
Date: November 16, 1998
Updates: First Release - 19970819
19981116
- 20030329
- 20030905
===============================================================================
Note:
@@ -18,10 +16,19 @@ packages for distribution via the official samba ftp sites.
The files contained here are intended for use only by those wishing to build
distribution packages and are NOT considered suitable material for anyone who
wants to just install Samba from the pristine source files contained under
-the ../source directory.
+the ~/source directory.
All contributions / modifications / additions / etc. to the packaging files
-should be logged in https://bugzilla.samba.org/.
+should be sent to samba-patches@samba.org with the subject marked:
+ PACKAGING: [add|mod|contrib] Your subject.
+
+Should you, or anyone you know of, have package build instructions and/or files
+that may be of use to the wider community of Samba users please mail the above
+account with subject: PACKAGING: [avail] OS xxxxxxxxxx
+where xxxxxxxxxx is the operating system platform that may be contributed.
+
+We will contact the person who is offering to contribute package build details
+to ensure that their contribution can be included in the official Samba sources.
In the event that anyone wishes to contribute package build information please
indicate in your response how we may access a suitable system to ensure our
@@ -29,4 +36,3 @@ ability to keep the binary distribution itself current with the released source.
The future of cooperatively developed software such as Samba depends on the
willingness of all partners to share the fruit of their labours.
-
diff --git a/packaging/README.UnixWare b/packaging/README.UnixWare
new file mode 100755
index 00000000000..a4b08954ecc
--- /dev/null
+++ b/packaging/README.UnixWare
@@ -0,0 +1,6 @@
+Date: January 9, 2001
+Maintainer: John H Terpstra
+Subject: UnixWare Packaging Files
+Modifications: Initial release 20010109
+
+Note: The packaging build files for UnixWare are located under ~samba/packaging/Caldera/UnixWare.
diff --git a/packaging/RedHat/README b/packaging/RedHat/README
index 646b10dbbbf..210248fa35a 100644
--- a/packaging/RedHat/README
+++ b/packaging/RedHat/README
@@ -1,13 +1,11 @@
-Preparer: Gerald Carter <jerry@samba.org>
+Preparation Date: Fri Aug 21, 1998
+Preparer: John H Terpstra <jht@samba.org>
-Instructions: Preparing Samba Packages for Red Hat Linux
+Instructions: Preparing Samba Packages for Red Hat Linux 5.X
===============================================================
-We provide support only for the latest stable release of major
-branches (e.g 6.2, 7.3, and 8.0). The makerpms.sh script
-supports rpm version 2.x, 3.x, and 4.x
+We provide support only for current versions of Red Hat Linux.
To produce the RPMS simply type:
-
- root# sh makerpms.sh
+ sh makerpms.sh
diff --git a/packaging/RedHat/filter-requires-samba_rh8.sh b/packaging/RedHat/filter-requires-samba_rh8.sh
deleted file mode 100755
index 8428a6ad013..00000000000
--- a/packaging/RedHat/filter-requires-samba_rh8.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-/usr/lib/rpm/find-requires $* | egrep -v '(Net::LDAP|CGI)'
diff --git a/packaging/RedHat/filter-requires-samba_rh9.sh b/packaging/RedHat/filter-requires-samba_rh9.sh
deleted file mode 100755
index 8378523bceb..00000000000
--- a/packaging/RedHat/filter-requires-samba_rh9.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-/usr/lib/rpm/perl.req $* | egrep -v '(Net::LDAP|CGI)'
diff --git a/packaging/RedHat/makerpms.sh.tmpl b/packaging/RedHat/makerpms.sh.tmpl
index a37e03a1447..9d71452db8e 100644
--- a/packaging/RedHat/makerpms.sh.tmpl
+++ b/packaging/RedHat/makerpms.sh.tmpl
@@ -12,29 +12,48 @@
# Note: Under this directory rpm expects to find the same directories that are under the
# /usr/src/redhat directory
#
+if [ -r ~/.rpmmacros ]; then
+ TOPDIR=`awk '/topdir/ {print $2}' < ~/.rpmmacros`
+ if [ z$TOPDIR != "z" ]; then
+ SPECDIR=${TOPDIR}/SPECS
+ SRCDIR=${TOPDIR}/SOURCES
+ fi
+fi
-SPECDIR=`rpm --eval %_specdir`
-SRCDIR=`rpm --eval %_sourcedir`
+SPECDIR=${SPECDIR:-/usr/src/redhat/SPECS}
+SRCDIR=${SRCDIR:-/usr/src/redhat/SOURCES}
# At this point the SPECDIR and SRCDIR vaiables must have a value!
USERID=`id -u`
GRPID=`id -g`
VERSION='PVERSION'
-SPECFILE="samba3.spec"
+
RPMVER=`rpm --version | awk '{print $3}'`
RPM="rpm"
echo The RPM Version on this machine is: $RPMVER
-##
-## fix the mandir macro
-##
case $RPMVER in
- [23]*)
- sed -e "s/MANDIR_MACRO/\%\{prefix\}\/man/g" < samba.spec > $SPECFILE
+ 2*)
+ echo Building for RPM v2.x
+ sed -e "s/MANDIR_MACRO/\%\{prefix\}\/man/g" < samba2.spec > samba.spec
+ sed -e "s/MANDIR_MACRO/\%\{prefix\}\/man/g" < samba2-devel.spec > samba-devel.spec
+ ;;
+ 3*)
+ echo Building for RPM v3.x
+ sed -e "s/MANDIR_MACRO/\%\{prefix\}\/man/g" < samba2.spec > samba.spec
+ sed -e "s/MANDIR_MACRO/\%\{prefix\}\/man/g" < samba2-devel.spec > samba-devel.spec
+ ;;
+ 4.1*)
+ echo Building for RPM v4.1
+ RPM="rpmbuild"
+ sed -e "s/MANDIR_MACRO/\%\{_mandir\}/g" < samba2.spec > samba.spec
+ sed -e "s/MANDIR_MACRO/\%\{_mandir\}/g" < samba2-devel.spec > samba-devel.spec
;;
4*)
- sed -e "s/MANDIR_MACRO/\%\{_mandir\}/g" < samba.spec > $SPECFILE
+ echo Building for RPM v4.x
+ sed -e "s/MANDIR_MACRO/\%\{_mandir\}/g" < samba2.spec > samba.spec
+ sed -e "s/MANDIR_MACRO/\%\{_mandir\}/g" < samba2-devel.spec > samba-devel.spec
;;
*)
echo "Unknown RPM version: `rpm --version`"
@@ -42,30 +61,30 @@ case $RPMVER in
;;
esac
-##
-## now catch the right command to build an RPM (defaults ro 'rpm'
-##
-case $RPMVER in
- 4.[12]*)
- RPM="rpmbuild"
- ;;
-esac
-
-echo "RPM build command is \"$RPM\""
-
( cd ../../source; if [ -f Makefile ]; then make distclean; fi )
( cd ../../.. ; chown -R ${USERID}.${GRPID} samba-${VERSION} )
+# We do this to make sure that the package always has the current version in it''s name
+if [ z$1 = z"devel" ]; then
+ (cd ../../.. ; mv samba samba-${VERSION} )
+fi
+
( cd ../../.. ; tar --exclude=CVS -cf - samba-${VERSION}/. | bzip2 > ${SRCDIR}/samba-${VERSION}.tar.bz2 )
-/bin/cp -p filter-requires-samba_rh8.sh ${SRCDIR}
-/bin/cp -p filter-requires-samba_rh9.sh ${SRCDIR}
-chmod 755 ${SRCDIR}/filter-requires-samba_rh?.sh
-/bin/cp -av $SPECFILE ${SPECDIR}
+cp -av samba.spec ${SPECDIR}
+cp -av samba-devel.spec ${SPECDIR}
-echo Getting Ready to build release package
-cd ${SPECDIR}
-${RPM} -ba --clean --rmsource $SPECFILE
+if [ z$1 = "zdevel" ]; then
+ echo Restoring source samba directory name
+ ( cd ../../.. ; mv samba-${VERSION} samba )
+ echo Getting Ready to build Developmental Build
+ cd ${SPECDIR}
+ ${RPM} -ba -v samba-devel.spec
+else
+ echo Getting Ready to build release package
+ cd ${SPECDIR}
+ ${RPM} -ba -v --clean --rmsource samba.spec
+fi
echo Done.
diff --git a/packaging/RedHat/samba.spec.tmpl b/packaging/RedHat/samba.spec.tmpl
deleted file mode 100644
index 787fe87d4ae..00000000000
--- a/packaging/RedHat/samba.spec.tmpl
+++ /dev/null
@@ -1,457 +0,0 @@
-## grab the major and minor version of rpm
-%define rpm_version `rpm --version | awk '{print $3}' | awk -F. '{print $1$2}'`
-
-Summary: Samba SMB client and server
-Vendor: Samba Team
-Name: samba
-Version: PVERSION
-Release: PRELEASE
-License: GNU GPL version 2
-Group: Networking
-Source: http://download.samba.org/samba/ftp/samba-%{version}.tar.bz2
-
-# Don't depend on Net::LDAP
-# one filter for RH 8 and one for 9
-Source998: filter-requires-samba_rh8.sh
-Source999: filter-requires-samba_rh9.sh
-
-Packager: Gerald Carter [Samba-Team] <jerry@samba.org>
-Requires: pam >= 0.72 kernel >= 2.2.1 glibc >= 2.1.2
-Prereq: chkconfig fileutils /sbin/ldconfig
-Provides: samba = %{version}
-Obsoletes: samba-common, samba-client, samba-swat
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-Prefix: /usr
-
-%description
-Samba provides an SMB/CIFS server which can be used to provide
-network file and print services to SMB/CIFS clients, including
-various versions of MS Windows, OS/2, and other Linux machines.
-Samba also provides some SMB clients, which complement the
-built-in SMB filesystem in Linux. Samba uses NetBIOS over TCP/IP
-(NetBT) protocols and does NOT need NetBEUI (Microsoft Raw NetBIOS
-frame) protocol.
-
-Samba 3.0 also introduces UNICODE support and kerberos/ldap
-integration as a member server in a Windows 2000 domain.
-
-Please refer to the WHATSNEW.txt document for fixup information.
-docs directory for implementation details.
-
-%changelog
-* Mon Nov 18 2002 Gerald Carter <jerry@samba.org>
- - removed change log entries since history
- is being maintained in CVS
-
-%prep
-%setup
-
-%build
-
-# Working around perl dependency problem from docs
-# Only > RH 8.0 seems to care here
-
-echo "rpm_version == %{rpm_version}"
-if [ "%{rpm_version}" == "42" ]; then
- %define __perl_requires %{SOURCE999}
- echo "%{__perl_requires}"
-elif [ "%{rpm_version}" == "41" ]; then
- %define __find_requires %{SOURCE998}
- echo "%{__find_requires}"
-fi
-
-## Build main Samba source
-cd source
-
-%ifarch ia64
-libtoolize --copy --force # get it to recognize IA-64
-autoheader
-autoconf
-EXTRA="-D_LARGEFILE64_SOURCE"
-%endif
-
-## Get number of cpu's, default for 1 cpu on error
-NUMCPU=`grep processor /proc/cpuinfo | wc -l`
-if [ $NUMCPU -eq 0 ]; then
- NUMCPU=1;
-fi
-
-## run autogen if missing the configure script
-if [ ! -f "configure" ]; then
- ./autogen.sh
-fi
-
-CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
- --prefix=%{prefix} \
- --localstatedir=/var \
- --with-configdir=/etc/samba \
- --with-privatedir=/etc/samba \
- --with-fhs \
- --with-quotas \
- --with-smbmount \
- --with-pam \
- --with-pam_smbpass \
- --with-syslog \
- --with-utmp \
- --with-sambabook=%{prefix}/share/swat/using_samba \
- --with-swatdir=%{prefix}/share/swat \
- --with-libsmbclient
-make -j${NUMCPU} proto
-make -j${NUMCPU} all nsswitch/libnss_wins.so
-make -j${NUMCPU} debug2html
-
-# Remove some permission bits to avoid to many dependencies
-find examples docs -type f | xargs -r chmod -x
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/sbin
-mkdir -p $RPM_BUILD_ROOT/etc/samba
-mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d,samba}
-mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
-mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include,using_samba}
-mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/{figs,gifs}
-mkdir -p $RPM_BUILD_ROOTMANDIR_MACRO
-mkdir -p $RPM_BUILD_ROOT/var/lib/samba
-mkdir -p $RPM_BUILD_ROOT/var/{log,run}/samba
-mkdir -p $RPM_BUILD_ROOT/var/spool/samba
-mkdir -p $RPM_BUILD_ROOT/lib/security
-mkdir -p $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
-mkdir -p $RPM_BUILD_ROOT%{prefix}/{lib,include}
-
-# Install standard binary files
-for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
- rpcclient smbspool smbcacls smbcontrol wbinfo smbmnt net \
- smbcacls pdbedit tdbbackup smbtree ntlm_auth smbcquotas
-do
- install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
-done
-
-for i in mksmbpasswd.sh smbtar findsmb
-do
- install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
-done
-
-# Install secure binary files
-for i in smbd nmbd swat smbmount smbumount debug2html winbindd
-do
- install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/sbin
-done
-
-# we need a symlink for mount to recognise the smb and smbfs filesystem types
-ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
-ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
-
-# This allows us to get away without duplicating code that
-# sombody else can maintain for us.
-cd source
-make DESTDIR=$RPM_BUILD_ROOT \
- BASEDIR=/usr \
- CONFIGDIR=/etc/samba \
- LIBDIR=%{prefix}/lib/samba \
- VARDIR=/var \
- SBINDIR=%{prefix}/sbin \
- BINDIR=%{prefix}/bin \
- MANDIR=MANDIR_MACRO \
- SWATDIR=%{prefix}/share/swat \
- SAMBABOOK=%{prefix}/share/swat/using_samba \
- installman installswat installdat installmodules
-cd ..
-
-# Install the nsswitch wins library
-install -m755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/lib
-( cd $RPM_BUILD_ROOT/lib; ln -sf libnss_wins.so libnss_wins.so.2 )
-
-# Install winbind shared libraries
-install -m755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/lib
-( cd $RPM_BUILD_ROOT/lib; ln -sf libnss_winbind.so libnss_winbind.so.2 )
-install -m755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security
-
-# Install pam_smbpass.so
-install -m755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/lib/security
-
-# libsmbclient
-install -m 755 source/bin/libsmbclient.so $RPM_BUILD_ROOT%{prefix}/lib/
-install -m 755 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{prefix}/lib/
-install -m 644 source/include/libsmbclient.h $RPM_BUILD_ROOT%{prefix}/include/
-
-# Install the miscellany
-install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{prefix}/bin
-install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
-install -m755 packaging/RedHat/winbind.init $RPM_BUILD_ROOT/etc/rc.d/init.d/winbind
-install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
-install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
-install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/samba/smb.conf
-install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers
-install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
-install -m644 packaging/RedHat/samba.pamd.stack $RPM_BUILD_ROOT/etc/samba/samba.stack
-install -m644 packaging/RedHat/samba.xinetd $RPM_BUILD_ROOT/etc/samba/samba.xinetd
-echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts
-
-# Remove "*.old" files
-find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \;
-
-##
-## Clean out man pages for tools not installed here
-##
-rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/editreg.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1*
-rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbget.1*
-rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8*
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%post
-##
-## only needed if this is a new install (not an upgrade)
-##
-if [ "$1" -eq "1" ]; then
- /sbin/chkconfig --add smb
- /sbin/chkconfig --add winbind
- /sbin/chkconfig smb off
- /sbin/chkconfig winbind off
-fi
-
-##
-## we only have to wory about this if we are upgrading
-##
-if [ "$1" -eq "2" ]; then
- if [ -f /etc/smb.conf -a ! -f /etc/samba/smb.conf ]; then
- echo "Moving old /etc/smb.conf to /etc/samba/smb.conf"
- mv /etc/smb.conf /etc/samba/smb.conf
- fi
-
- if [ -f /etc/smbusers -a ! -f /etc/samba/smbusers ]; then
- echo "Moving old /etc/smbusers to /etc/samba/smbusers"
- mv /etc/smbusers /etc/samba/smbusers
- fi
-
- if [ -f /etc/lmhosts -a ! -f /etc/samba/lmhosts ]; then
- echo "Moving old /etc/lmhosts to /etc/samba/lmhosts"
- mv /etc/lmhosts /etc/samba/lmhosts
- fi
-
- if [ -f /etc/MACHINE.SID -a ! -f /etc/samba/MACHINE.SID ]; then
- echo "Moving old /etc/MACHINE.SID to /etc/samba/MACHINE.SID"
- mv /etc/MACHINE.SID /etc/samba/MACHINE.SID
- fi
-
- if [ -f /etc/smbpasswd -a ! -f /etc/samba/smbpasswd ]; then
- echo "Moving old /etc/smbpasswd to /etc/samba/smbpasswd"
- mv /etc/smbpasswd /etc/samba/smbpasswd
- fi
-
- #
- # For 2.2.1 we move the tdb files from /var/lock/samba to /var/cache/samba
- # to preserve across reboots.
- #
- for i in /var/lock/samba/*.tdb; do
- if [ -f $i ]; then
- newname="/var/lib/samba/`basename $i`"
- echo "Moving $i to $newname"
- mv $i $newname
- fi
- done
-
- #
- # For 3.0.1 we move the tdb files from /var/cache/samba to /var/lib/samba
- #
- echo "Moving tdb files in /var/cache/samba/*.tdb to /var/lib/samba/*.tdb"
- for i in /var/cache/samba/*.tdb; do
- if [ -f $i ]; then
- newname="/var/lib/samba/`basename $i`"
- echo "Moving $i to $newname"
- mv $i $newname
- fi
- done
-fi
-
-##
-## New things
-##
-
-# Add swat entry to /etc/services if not already there.
-if [ ! "`grep ^\s**swat /etc/services`" ]; then
- echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
-fi
-
-# Add swat entry to /etc/inetd.conf if needed.
-if [ -f /etc/inetd.conf ]; then
- if [ ! "`grep ^\s*swat /etc/inetd.conf`" ]; then
- echo 'swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf
- killall -HUP inetd || :
- fi
-fi
-
-# Add swat entry to xinetd.d if needed.
-if [ -d /etc/xinetd.d -a ! -f /etc/xinetd.d/swat ]; then
- mv /etc/samba/samba.xinetd /etc/xinetd.d/swat
-else
- rm -f /etc/samba/samba.xinetd
-fi
-
-# Install the correct version of the samba pam file
-if [ -f /lib/security/pam_stack.so ]; then
- echo "Installing stack version of /etc/pam.d/samba..."
- mv /etc/samba/samba.stack /etc/pam.d/samba
-else
- echo "Installing non-stack version of /etc/pam.d/samba..."
- rm -f /etc/samba/samba.stack
-fi
-
-## call ldconfig to create the version symlink for libsmbclient.so
-/sbin/ldconfig
-
-%preun
-if [ "$1" -eq "0" ] ; then
- /sbin/chkconfig --del smb
- /sbin/chkconfig --del winbind
-
- # We want to remove the browse.dat and wins.dat files
- # so they can not interfer with a new version of samba!
- if [ -e /var/lib/samba/browse.dat ]; then
- rm -f /var/lib/samba/browse.dat
- fi
- if [ -e /var/lib/samba/wins.dat ]; then
- rm -f /var/lib/samba/wins.dat
- fi
-
- # Remove the transient tdb files.
- if [ -e /var/lib/samba/brlock.tdb ]; then
- rm -f /var/lib/samba/brlock.tdb
- fi
-
- if [ -e /var/lib/samba/unexpected.tdb ]; then
- rm -f /var/lib/samba/unexpected.tdb
- fi
-
- if [ -e /var/lib/samba/connections.tdb ]; then
- rm -f /var/lib/samba/connections.tdb
- fi
-
- if [ -e /var/lib/samba/locking.tdb ]; then
- rm -f /var/lib/samba/locking.tdb
- fi
-
- if [ -e /var/lib/samba/messages.tdb ]; then
- rm -f /var/lib/samba/messages.tdb
- fi
-fi
-
-%postun
-# Only delete remnants of samba if this is the final deletion.
-if [ "$1" -eq "0" ] ; then
- if [ -x /etc/pam.d/samba ]; then
- rm -f /etc/pam.d/samba
- fi
-
- if [ -e /var/log/samba ]; then
- rm -rf /var/log/samba
- fi
-
- if [ -e /var/lib/samba ]; then
- rm -rf /var/lib/samba
- fi
-
- # Remove swat entries from /etc/inetd.conf and /etc/services
- cd /etc
- tmpfile=/etc/tmp.$$
- if [ -f /etc/inetd.conf ]; then
- # preserve inetd.conf permissions.
- cp -p /etc/inetd.conf $tmpfile
- sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile
- mv $tmpfile inetd.conf
- fi
-
- # preserve services permissions.
- cp -p /etc/services $tmpfile
- sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile
- mv $tmpfile /etc/services
-
- # Remove swat entry from /etc/xinetd.d
- if [ -f /etc/xinetd.d/swat ]; then
- rm -r /etc/xinetd.d/swat
- fi
-fi
-
-/sbin/ldconfig
-
-%files
-%defattr(-,root,root)
-%doc README COPYING Manifest Read-Manifest-Now
-%doc WHATSNEW.txt Roadmap
-%doc docs
-%doc examples
-%{prefix}/sbin/smbd
-%{prefix}/sbin/nmbd
-%{prefix}/sbin/swat
-%{prefix}/bin/smbmnt
-%{prefix}/sbin/smbmount
-%{prefix}/sbin/smbumount
-%{prefix}/sbin/winbindd
-%{prefix}/sbin/samba
-%{prefix}/sbin/debug2html
-/sbin/mount.smbfs
-/sbin/mount.smb
-%{prefix}/bin/mksmbpasswd.sh
-%{prefix}/bin/smbclient
-%{prefix}/bin/smbspool
-%{prefix}/bin/rpcclient
-%{prefix}/bin/testparm
-%{prefix}/bin/testprns
-%{prefix}/bin/findsmb
-%{prefix}/bin/smbstatus
-%{prefix}/bin/nmblookup
-%{prefix}/bin/smbpasswd
-%{prefix}/bin/smbtar
-%{prefix}/bin/smbprint
-%{prefix}/bin/smbcontrol
-%{prefix}/bin/wbinfo
-%{prefix}/bin/net
-%{prefix}/bin/ntlm_auth
-%{prefix}/bin/smbcquotas
-%{prefix}/bin/smbcacls
-%{prefix}/bin/pdbedit
-%{prefix}/bin/tdbbackup
-%{prefix}/bin/smbtree
-%attr(755,root,root) /lib/libnss_wins.s*
-%attr(755,root,root) %{prefix}/lib/samba/vfs/*.so
-%attr(755,root,root) %{prefix}/lib/samba/charset/*.so
-#%attr(755,root,root) %{prefix}/lib/samba/pdb/*.so
-%attr(755,root,root) %{prefix}/lib/samba/*.dat
-%attr(755,root,root) %{prefix}/lib/samba/*.msg
-%{prefix}/include/libsmbclient.h
-%{prefix}/lib/libsmbclient.a
-%{prefix}/lib/libsmbclient.so
-%{prefix}/share/swat/help/*
-%{prefix}/share/swat/images/*
-%{prefix}/share/swat/include/*.html
-%{prefix}/share/swat/lang/*/help/*
-%{prefix}/share/swat/lang/*/images/*
-%{prefix}/share/swat/lang/*/include/*.html
-%{prefix}/share/swat/using_samba/*
-%config(noreplace) /etc/samba/lmhosts
-%config(noreplace) /etc/samba/smb.conf
-%config(noreplace) /etc/samba/smbusers
-/etc/samba/samba.stack
-/etc/samba/samba.xinetd
-/etc/rc.d/init.d/smb
-/etc/rc.d/init.d/winbind
-/etc/logrotate.d/samba
-%config(noreplace) /etc/pam.d/samba
-MANDIR_MACRO/man1/*
-MANDIR_MACRO/man5/*
-MANDIR_MACRO/man7/*
-MANDIR_MACRO/man8/*
-%attr(755,root,root) %dir /var/lib/samba
-%dir /var/log/samba
-%dir /var/run/samba
-%attr(1777,root,root) %dir /var/spool/samba
-%attr(-,root,root) /lib/libnss_winbind.so*
-%attr(-,root,root) /lib/security/pam_winbind.so
-%attr(-,root,root) /lib/security/pam_smbpass.so
diff --git a/packaging/RedHat/samba.xinetd b/packaging/RedHat/samba.xinetd
index 8c38b354218..7431aaaeae7 100644
--- a/packaging/RedHat/samba.xinetd
+++ b/packaging/RedHat/samba.xinetd
@@ -7,7 +7,7 @@ service swat
port = 901
socket_type = stream
wait = no
- only_from = localhost
+ only_from = 127.0.0.1
user = root
server = /usr/sbin/swat
log_on_failure += USERID
diff --git a/packaging/RedHat/samba2-devel.spec.tmpl b/packaging/RedHat/samba2-devel.spec.tmpl
new file mode 100755
index 00000000000..5f48051d8d7
--- /dev/null
+++ b/packaging/RedHat/samba2-devel.spec.tmpl
@@ -0,0 +1,547 @@
+Summary: Samba SMB client and server
+Name: samba
+Version: PVERSION
+Release: PRELEASE
+Copyright: GNU GPL version 2
+Group: Networking
+Source: ftp://samba.org/pub/samba/samba-%{version}.tar.gz
+Packager: John H Terpstra [Samba-Team] <jht@samba.org>
+Requires: pam >= 0.72 kernel >= 2.2.1 glibc >= 2.1.2
+Prereq: chkconfig fileutils
+Provides: samba = %{version}
+Obsoletes: samba-common, samba-client, samba-swat
+BuildRoot: /var/tmp/samba
+Prefix: /usr
+
+%description
+Samba provides an SMB server which can be used to provide
+network services to SMB (sometimes called "Lan Manager")
+clients, including various versions of MS Windows, OS/2,
+and other Linux machines. Samba also provides some SMB
+clients, which complement the built-in SMB filesystem
+in Linux. Samba uses NetBIOS over TCP/IP (NetBT) protocols
+and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
+protocol.
+
+Samba-2.2 features working NT Domain Control capability and
+includes the SWAT (Samba Web Administration Tool) that
+allows samba's smb.conf file to be remotely managed using your
+favourite web browser. For the time being this is being
+enabled on TCP port 901 via inetd.
+
+Users are advised to use Samba-2.2 as a Windows NT4
+Domain Controller only on networks that do NOT have a Windows
+NT Domain Controller. This release does NOT as yet have
+Backup Domain control ability.
+
+Please refer to the WHATSNEW.txt document for fixup information.
+This binary release includes encrypted password support.
+
+Please read the smb.conf file and ENCRYPTION.txt in the
+docs directory for implementation details.
+
+NOTE: Red Hat Linux uses PAM which has integrated support
+for Shadow passwords and quotas. Do NOT recompile with the
+SHADOW_PWD option enabled
+
+%changelog
+* Sun Jun 2 2002 Gerald Carter <jerry@samba.org>
+ - include audit and recycle VFS modules in /usr/lib/samba
+
+* Mon May 6 2002 Gerald Carter <jerry@samba.org>
+ - moved findsmb to a standard component in samba's
+ "make install". Removed from specfile.
+
+* Sun Oct 14 2001 Andrew Bartlett <abartlet@samba.org>
+ - Set SBINDIR for codepage/manpage install, cope with
+ broken Makefile
+
+* Mon Aug 1 2001 Tim Potter <tpot@samba.org>
+ - Install winbind daemon, client programs, nss and pam libraries
+
+* Sat Mar 31 2001 Andrew Bartlett <abartlet@pcug.org.au>
+ - Changed prefix/share/man for _mandir/share/man
+ - Changed this for a sed macro MANDIR_MACRO
+ - This allows us to build both RH7 (RPM4)
+ and older versions from same specfile.
+ - Made makerpms.sh use the rpm -ta command rather
+ than attempting to devine the correct location to
+ put the file. Also removes some /tmp symlink games.
+ - Allows build on RPM4
+ - Increased PAM requirements to allow us to use
+ system-auth (this pam is in 6.x errata at least)
+
+* Tue Mar 27 2001 John H Terpstra <jht@samba.org>
+ - Fixed typos introduced by Sum Wun.
+ - Build for Red Hat 7.x
+
+* Sun Nov 12 2000 John H Terpstra <jht@samba.org>
+ - Updated for Samba-2.2 releases
+ - Added libnss_wins.so stuff
+ - Added compile-time options
+
+* Sat Nov 29 1999 Matthew Vanecek <mev0003@unt.edu>
+ - Added a Prefix and changed "/usr" to "%{prefix}"
+
+* Sat Nov 11 1999 Tridge <tridge@linuxcare.com>
+ - changed from mount.smb to mount.smbfs
+
+* Sat Oct 9 1999 Tridge <tridge@linuxcare.com>
+ - removed smbwrapper
+ - added smbmnt and smbmount
+
+* Sun Apr 25 1999 John H Terpstra <jht@samba.org>
+ - added smbsh.1 man page
+
+* Fri Mar 26 1999 Andrew Tridgell <tridge@samba.org>
+ - added --with-pam as pam is no longer used by default
+
+* Sat Jan 27 1999 Jeremy Allison <jra@samba.org>
+ - Removed smbrun binary and tidied up some loose ends
+
+* Sun Oct 25 1998 John H Terpstra <jht@samba.org>
+ - Added parameters to /config to ensure smb.conf, lmhosts,
+ and smbusers never gets over-written.
+
+* Sat Oct 24 1998 John H Terpstra <jht@samba.org>
+ - removed README.smbsh file from docs area
+
+* Mon Oct 05 1998 John H Terpstra <jht@samba.org>
+ - Added rpcclient to binaries list
+ - Added smbwrapper stuff
+
+* Fri Aug 21 1998 John H Terpstra <jht@samba.org>
+ - Updated for Samba version 2.0 building
+
+* Tue Jul 07 1998 Erik Troan <ewt@redhat.com>
+ - updated postun triggerscript to check $0
+ - clear /etc/codepages from %preun instead of %postun
+
+* Sat Jul 04 1998 John H Terpstra <jht@samba.org>
+ - fixed codepage preservation during update via -Uvh
+
+* Mon Jun 08 1998 Erik Troan <ewt@redhat.com>
+ - made the %postun script a tad less agressive; no reason to remove
+ the logs or lock file
+ - the %postun and %preun should only exectute if this is the final
+ removal
+ - migrated %triggerpostun from Red Hat's samba package to work around
+ packaging problems in some Red Hat samba releases
+
+* Sun Apr 26 1998 John H Terpstra <jht@samba.org>
+ - Tidy up for early alpha releases
+ - added findsmb from SGI packaging
+
+* Thu Apr 09 1998 John H Terpstra <jht@samba.org>
+ - Updated spec file
+ - Included new codepage.936
+
+* Sat Mar 20 1998 John H Terpstra <jht@samba.org>
+ - Added swat facility
+
+* Sat Jan 24 1998 John H Terpstra <jht@samba.org>
+ - Many optimisations (some suggested by Manoj Kasichainula <manojk@io.com>
+ - Use of chkconfig in place of individual symlinks to /etc/rc.d/init/smb
+ - Compounded make line
+ - Updated smb.init restart mechanism
+ - Use compound mkdir -p line instead of individual calls to mkdir
+ - Fixed smb.conf file path for log files
+ - Fixed smb.conf file path for incoming smb print spool directory
+ - Added a number of options to smb.conf file
+ - Added smbuser file and smb.conf file updates for username map
+
+%prep
+%setup
+
+%build
+## Build main Samba source
+cd source
+
+%ifarch ia64
+libtoolize --copy --force # get it to recognize IA-64
+autoheader
+autoconf
+EXTRA="-D_LARGEFILE64_SOURCE"
+%endif
+NUMCPU=`grep processor /proc/cpuinfo | wc -l`
+CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
+ --prefix=%{prefix} \
+ --localstatedir=/var \
+ --with-configdir=/etc/samba \
+ --with-privatedir=/etc/samba \
+ --with-codepagedir=/etc/codepages \
+ --with-fhs \
+ --with-quotas \
+ --with-msdfs \
+ --with-smbmount \
+ --with-pam \
+ --with-syslog \
+ --with-utmp \
+ --with-sambabook=%{prefix}/share/swat/using_samba \
+ --with-swatdir=%{prefix}/share/swat
+make -j${NUMCPU} proto
+make -j${NUMCPU} all nsswitch/libnss_wins.so
+make -j${NUMCPU} debug2html
+make -j${NUMCPU} bin/smbspool everything
+
+## Build VFS modules
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
+ --prefix=%{prefix} \
+ --localstatedir=/var
+make
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT/etc/samba
+mkdir -p $RPM_BUILD_ROOT/etc/codepages/src
+mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d,samba}
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include,using_samba}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/{figs,gifs}
+mkdir -p $RPM_BUILD_ROOTMANDIR_MACRO
+mkdir -p $RPM_BUILD_ROOT/var/cache/samba
+mkdir -p $RPM_BUILD_ROOT/var/{log,run}/samba
+mkdir -p $RPM_BUILD_ROOT/var/spool/samba
+mkdir -p $RPM_BUILD_ROOT/lib/security
+mkdir -p $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool \
+ smbcacls smbcontrol wbinfo
+do
+install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+for i in mksmbpasswd.sh smbtar findsmb
+do
+ install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat smbmount smbumount smbmnt debug2html winbindd
+do
+ install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/sbin
+done
+
+# we need a symlink for mount to recognise the smb and smbfs filesystem types
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
+
+# This allows us to get away without duplicating code that
+# sombody else can maintain for us.
+cd source
+make BASEDIR=$RPM_BUILD_ROOT/usr \
+ LIBDIR=$RPM_BUILD_ROOT/etc/samba \
+ SBINDIR=$RPM_BUILD_ROOT%{prefix}/sbin \
+ BINDIR=$RPM_BUILD_ROOT%{prefix}/bin \
+ MANDIR=$RPM_BUILD_ROOTMANDIR_MACRO \
+ CODEPAGEDIR=$RPM_BUILD_ROOT/etc/codepages \
+ SWATDIR=$RPM_BUILD_ROOT/usr/share/swat \
+ SAMBABOOK=$RPM_BUILD_ROOT/usr/share/swat/using_samba \
+ installman installcp installswat
+cd ..
+
+# Install codepage source files
+for i in source/codepages/codepage_def.* source/codepages/*.TXT
+do
+ install -m644 $i $RPM_BUILD_ROOT/etc/codepages/src
+done
+
+# Install the nsswitch wins library
+install -m755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/lib
+
+# Make link for wins resolver
+( cd $RPM_BUILD_ROOT/lib; ln -sf libnss_wins.so libnss_wins.so.2; )
+
+# Install winbind shared libraries
+install -m755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/lib
+install -m755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security
+
+# Install the VFS modules
+install -m755 examples/VFS/recycle.so $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+install -m755 examples/VFS/audit.so $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+# clean out VFS directory since it will get installed as documentation later
+(cd examples/VFS; make clean)
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/help
+done
+for i in swat/images/*.gif
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/images
+done
+for i in swat/include/*.html
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/include
+done
+
+# Install the miscellany
+install -m644 swat/README $RPM_BUILD_ROOT%{prefix}/share/swat
+install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
+install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
+install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/samba/smb.conf
+install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers
+install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
+install -m644 packaging/RedHat/samba.pamd.stack $RPM_BUILD_ROOT/etc/samba/samba.stack
+install -m644 packaging/RedHat/samba.xinetd $RPM_BUILD_ROOT/etc/samba/samba.xinetd
+echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add smb
+/sbin/chkconfig smb off
+
+echo "Looking for old /etc/smb.conf..."
+if [ -f /etc/smb.conf -a ! -f /etc/samba/smb.conf ]; then
+ echo "Moving old /etc/smb.conf to /etc/samba/smb.conf"
+ mv /etc/smb.conf /etc/samba/smb.conf
+fi
+
+echo "Looking for old /etc/smbusers..."
+if [ -f /etc/smbusers -a ! -f /etc/samba/smbusers ]; then
+ echo "Moving old /etc/smbusers to /etc/samba/smbusers"
+ mv /etc/smbusers /etc/samba/smbusers
+fi
+
+echo "Looking for old /etc/lmhosts..."
+if [ -f /etc/lmhosts -a ! -f /etc/samba/lmhosts ]; then
+ echo "Moving old /etc/lmhosts to /etc/samba/lmhosts"
+ mv /etc/lmhosts /etc/samba/lmhosts
+fi
+
+echo "Looking for old /etc/MACHINE.SID..."
+if [ -f /etc/MACHINE.SID -a ! -f /etc/samba/MACHINE.SID ]; then
+ echo "Moving old /etc/MACHINE.SID to /etc/samba/MACHINE.SID"
+ mv /etc/MACHINE.SID /etc/samba/MACHINE.SID
+fi
+
+echo "Looking for old /etc/smbpasswd..."
+if [ -f /etc/smbpasswd -a ! -f /etc/samba/smbpasswd ]; then
+ echo "Moving old /etc/smbpasswd to /etc/samba/smbpasswd"
+ mv /etc/smbpasswd /etc/samba/smbpasswd
+fi
+
+#
+# For 2.2.1 we move the tdb files from /var/lock/samba to /var/cache/samba
+# to preserve across reboots.
+#
+echo "Moving tdb files in /var/lock/samba/*.tdb to /var/cache/samba/*.tdb"
+for i in /var/lock/samba/*.tdb
+do
+if [ -f $i ]; then
+ newname=`echo $i | sed -e's|var\/lock\/samba|var\/cache\/samba|'`
+ echo "Moving $i to $newname"
+ mv $i $newname
+fi
+done
+
+# Remove the transient tdb files.
+if [ -e /var/cache/samba/brlock.tdb ]; then
+ rm -f /var/cache/samba/brlock.tdb
+fi
+
+if [ -e /var/cache/samba/unexpected.tdb ]; then
+ rm -f /var/cache/samba/unexpected.tdb
+fi
+
+if [ -e /var/cache/samba/connections.tdb ]; then
+ rm -f /var/cache/samba/connections.tdb
+fi
+
+if [ -e /var/cache/samba/locking.tdb ]; then
+ rm -f /var/cache/samba/locking.tdb
+fi
+
+if [ -e /var/cache/samba/messages.tdb ]; then
+ rm -f /var/cache/samba/messages.tdb
+fi
+
+if [ -d /var/lock/samba ]; then
+ rm -rf /var/lock/samba
+fi
+
+# Add swat entry to /etc/services if not already there.
+if !( grep ^[:space:]*swat /etc/services > /dev/null ) then
+ echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
+fi
+
+# Add swat entry to /etc/inetd.conf if needed.
+if [ -f /etc/inetd.conf ]; then
+ if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
+ echo 'swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf
+ killall -1 inetd || :
+ fi
+fi
+
+# Add swat entry to xinetd.d if needed.
+if [ -d $RPM_BUILD_ROOT/etc/xinetd.d -a ! -f /etc/xinetd.d/swat ]; then
+ mv /etc/samba/samba.xinetd /etc/xinetd.d/swat
+else
+ rm -f /etc/samba/samba.xinetd
+fi
+
+# Install the correct version of the samba pam file, depending on pam version.
+if [ -f /lib/security/pam_stack.so ]; then
+ echo "Installing stack version of /etc/pam.d/samba..."
+ mv /etc/samba/samba.stack /etc/pam.d/samba
+else
+ echo "Installing non-stack version of /etc/pam.d/samba..."
+ rm -f /etc/samba/samba.stack
+fi
+
+# Create winbind nss client symlink
+
+if [ -e /lib/libnss_winbind.so ]; then
+ ln -sf /lib/libnss_winbind.so /lib/libnss_winbind.so.2
+fi
+
+%preun
+if [ $1 = 0 ] ; then
+ /sbin/chkconfig --del smb
+
+ # We want to remove the browse.dat and wins.dat files so they can not interfer with a new version of samba!
+ if [ -e /var/cache/samba/browse.dat ]; then
+ rm -f /var/cache/samba/browse.dat
+ fi
+ if [ -e /var/cache/samba/wins.dat ]; then
+ rm -f /var/cache/samba/wins.dat
+ fi
+
+ # Remove the transient tdb files.
+ if [ -e /var/cache/samba/brlock.tdb ]; then
+ rm -f /var/cache/samba/brlock.tdb
+ fi
+
+ if [ -e /var/cache/samba/unexpected.tdb ]; then
+ rm -f /var/cache/samba/unexpected.tdb
+ fi
+
+ if [ -e /var/cache/samba/connections.tdb ]; then
+ rm -f /var/cache/samba/connections.tdb
+ fi
+
+ if [ -e /var/cache/samba/locking.tdb ]; then
+ rm -f /var/cache/samba/locking.tdb
+ fi
+
+ if [ -e /var/cache/samba/messages.tdb ]; then
+ rm -f /var/cache/samba/messages.tdb
+ fi
+
+ # Remove winbind nss client symlink
+
+ if [ -L /lib/libnss_winbind.so.2 ]; then
+ rm -f /lib/libnss_winbind.so.2
+ fi
+fi
+
+%postun
+# Only delete remnants of samba if this is the final deletion.
+if [ $1 = 0 ] ; then
+ if [ -x /etc/pam.d/samba ]; then
+ rm -f /etc/pam.d/samba
+ fi
+ if [ -e /var/log/samba ]; then
+ rm -rf /var/log/samba
+ fi
+ if [ -e /var/cache/samba ]; then
+ rm -rf /var/cache/samba
+ fi
+
+ # Remove swat entries from /etc/inetd.conf and /etc/services
+ cd /etc
+ tmpfile=/etc/tmp.$$
+ if [ -f /etc/inetd.conf ]; then
+ # preserve inetd.conf permissions.
+ cp -p /etc/inetd.conf $tmpfile
+ sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile
+ mv $tmpfile inetd.conf
+ fi
+ # preserve services permissions.
+ cp -p /etc/services $tmpfile
+ sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile
+ mv $tmpfile /etc/services
+
+ # Remove swat entry from /etc/xinetd.d
+ if [ -f /etc/xinetd.d/swat ]; then
+ rm -r /etc/xinetd.d/swat
+ fi
+fi
+
+%triggerpostun -- samba < samba-2.0.0
+if [ $0 != 0 ]; then
+ /sbin/chkconfig --add smb
+fi
+
+%files
+%defattr(-,root,root)
+%doc README COPYING Manifest Read-Manifest-Now
+%doc WHATSNEW.txt Roadmap
+%doc docs
+%doc swat/README
+%doc examples
+%{prefix}/sbin/smbd
+%{prefix}/sbin/nmbd
+%{prefix}/sbin/swat
+%{prefix}/sbin/smbmnt
+%{prefix}/sbin/smbmount
+%{prefix}/sbin/smbumount
+%{prefix}/sbin/winbindd
+/sbin/mount.smbfs
+/sbin/mount.smb
+%{prefix}/bin/mksmbpasswd.sh
+%{prefix}/bin/smbclient
+%{prefix}/bin/smbspool
+%{prefix}/bin/rpcclient
+%{prefix}/bin/testparm
+%{prefix}/bin/testprns
+%{prefix}/bin/findsmb
+%{prefix}/bin/smbstatus
+%{prefix}/bin/nmblookup
+%{prefix}/bin/make_smbcodepage
+%{prefix}/bin/make_unicodemap
+%{prefix}/bin/make_printerdef
+%{prefix}/bin/smbpasswd
+%{prefix}/bin/smbtar
+%{prefix}/bin/smbprint
+%{prefix}/bin/smbcontrol
+%{prefix}/bin/smbcacls
+%{prefix}/bin/wbinfo
+%attr(755,root,root) /lib/libnss_wins.s*
+%attr(755,root,root) %{prefix}/lib/samba/*.so
+%{prefix}/share/swat/help/*
+%{prefix}/share/swat/images/*
+%{prefix}/share/swat/include/header.html
+%{prefix}/share/swat/include/footer.html
+%{prefix}/share/swat/using_samba/*
+%config(noreplace) /etc/samba/lmhosts
+%config(noreplace) /etc/samba/smb.conf
+%config(noreplace) /etc/samba/smbusers
+/etc/samba/samba.stack
+/etc/samba/samba.xinetd
+/etc/rc.d/init.d/smb
+/etc/logrotate.d/samba
+%config(noreplace) /etc/pam.d/samba
+MANDIR_MACRO/man1/*
+MANDIR_MACRO/man5/*
+MANDIR_MACRO/man7/*
+MANDIR_MACRO/man8/*
+%dir /etc/codepages/*
+%attr(755,root,root) %dir /var/cache/samba
+%dir /var/log/samba
+%dir /var/run/samba
+%attr(1777,root,root) %dir /var/spool/samba
+%attr(-,root,root) /lib/libnss_winbind.so
+%attr(-,root,root) /lib/security/pam_winbind.so
+%attr(755,root,root) %{prefix}/lib/samba/*.so
diff --git a/packaging/RedHat/samba2.spec.tmpl b/packaging/RedHat/samba2.spec.tmpl
new file mode 100755
index 00000000000..776f535701e
--- /dev/null
+++ b/packaging/RedHat/samba2.spec.tmpl
@@ -0,0 +1,587 @@
+Summary: Samba SMB client and server
+Name: samba
+Version: PVERSION
+Release: PRELEASE
+Copyright: GNU GPL version 2
+Group: Networking
+Source: http://download.samba.org/samba/ftp/samba-%{version}.tar.bz2
+Packager: Gerald Carter [Samba-Team] <jerry@samba.org>
+Requires: pam >= 0.72 kernel >= 2.2.1 glibc >= 2.1.2
+Prereq: chkconfig fileutils
+Provides: samba = %{version}
+BuildPreReq: libtool
+Obsoletes: samba-common, samba-client, samba-swat
+BuildRoot: /var/tmp/samba
+Prefix: /usr
+
+%description
+Samba provides an SMB server which can be used to provide
+network services to SMB (sometimes called "Lan Manager")
+clients, including various versions of MS Windows, OS/2,
+and other Linux machines. Samba also provides some SMB
+clients, which complement the built-in SMB filesystem
+in Linux. Samba uses NetBIOS over TCP/IP (NetBT) protocols
+and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
+protocol.
+
+Samba-2.2 features working NT Domain Control capability and
+includes the SWAT (Samba Web Administration Tool) that
+allows samba's smb.conf file to be remotely managed using your
+favourite web browser. For the time being this is being
+enabled on TCP port 901 via inetd.
+
+Users are advised to use Samba-2.2 as a Windows NT4
+Domain Controller only on networks that do NOT have a Windows
+NT Domain Controller. This release does NOT as yet have
+Backup Domain control ability.
+
+Please refer to the WHATSNEW.txt document for fixup information.
+This binary release includes encrypted password support.
+
+Please read the smb.conf file and ENCRYPTION.txt in the
+docs directory for implementation details.
+
+NOTE: Red Hat Linux uses PAM which has integrated support
+for Shadow passwords and quotas. Do NOT recompile with the
+SHADOW_PWD option enabled
+
+%changelog
+* Thu Jun 6 2002 Gerald Carter <jerry@samba.org>
+ - add separate winbindd init script
+ - build and install libsmbclient
+
+* Sun Jun 2 2002 Gerald Carter <jerry@samba.org>
+ - include audit and recycle VFS modules in /usr/lib/samba
+
+* Mon May 6 2002 Gerald Carter <jerry@samba.org>
+ - moved findsmb to a standard component in samba's
+ "make install". Removed from specfile.
+
+* Sun Oct 14 2001 Andrew Bartlett <abartlet@samba.org>
+ - Set SBINDIR for codepage/manpage install, cope with
+ broken Makefile
+
+* Mon Aug 1 2001 Tim Potter <tpot@samba.org>
+ - Install winbind daemon, client programs, nss and pam libraries
+
+* Sat Mar 31 2001 Andrew Bartlett <abartlet@pcug.org.au>
+ - Changed prefix/share/man for _mandir/share/man
+ - Changed this for a sed macro MANDIR_MACRO
+ - This allows us to build both RH7 (RPM4)
+ and older versions from same specfile.
+ - Made makerpms.sh use the rpm -ta command rather
+ than attempting to devine the correct location to
+ put the file. Also removes some /tmp symlink games.
+ - Allows build on RPM4
+ - Increased PAM requirements to allow us to use
+ system-auth (this pam is in 6.x errata at least)
+
+* Tue Mar 27 2001 John H Terpstra <jht@samba.org>
+ - Fixed typos introduced by Sum Wun.
+ - Build for Red Hat 7.x
+
+* Sun Nov 12 2000 John H Terpstra <jht@samba.org>
+ - Updated for Samba-2.2 releases
+ - Added libnss_wins.so stuff
+ - Added compile-time options
+
+* Sat Nov 29 1999 Matthew Vanecek <mev0003@unt.edu>
+ - Added a Prefix and changed "/usr" to "%{prefix}"
+
+* Sat Nov 11 1999 Tridge <tridge@linuxcare.com>
+ - changed from mount.smb to mount.smbfs
+
+* Sat Oct 9 1999 Tridge <tridge@linuxcare.com>
+ - removed smbwrapper
+ - added smbmnt and smbmount
+
+* Sun Apr 25 1999 John H Terpstra <jht@samba.org>
+ - added smbsh.1 man page
+
+* Fri Mar 26 1999 Andrew Tridgell <tridge@samba.org>
+ - added --with-pam as pam is no longer used by default
+
+* Sat Jan 27 1999 Jeremy Allison <jra@samba.org>
+ - Removed smbrun binary and tidied up some loose ends
+
+* Sun Oct 25 1998 John H Terpstra <jht@samba.org>
+ - Added parameters to /config to ensure smb.conf, lmhosts,
+ and smbusers never gets over-written.
+
+* Sat Oct 24 1998 John H Terpstra <jht@samba.org>
+ - removed README.smbsh file from docs area
+
+* Mon Oct 05 1998 John H Terpstra <jht@samba.org>
+ - Added rpcclient to binaries list
+ - Added smbwrapper stuff
+
+* Fri Aug 21 1998 John H Terpstra <jht@samba.org>
+ - Updated for Samba version 2.0 building
+
+* Tue Jul 07 1998 Erik Troan <ewt@redhat.com>
+ - updated postun triggerscript to check $0
+ - clear /etc/codepages from %preun instead of %postun
+
+* Sat Jul 04 1998 John H Terpstra <jht@samba.org>
+ - fixed codepage preservation during update via -Uvh
+
+* Mon Jun 08 1998 Erik Troan <ewt@redhat.com>
+ - made the %postun script a tad less agressive; no reason to remove
+ the logs or lock file
+ - the %postun and %preun should only exectute if this is the final
+ removal
+ - migrated %triggerpostun from Red Hat's samba package to work around
+ packaging problems in some Red Hat samba releases
+
+* Sun Apr 26 1998 John H Terpstra <jht@samba.org>
+ - Tidy up for early alpha releases
+ - added findsmb from SGI packaging
+
+* Thu Apr 09 1998 John H Terpstra <jht@samba.org>
+ - Updated spec file
+ - Included new codepage.936
+
+* Sat Mar 20 1998 John H Terpstra <jht@samba.org>
+ - Added swat facility
+
+* Sat Jan 24 1998 John H Terpstra <jht@samba.org>
+ - Many optimisations (some suggested by Manoj Kasichainula <manojk@io.com>
+ - Use of chkconfig in place of individual symlinks to /etc/rc.d/init/smb
+ - Compounded make line
+ - Updated smb.init restart mechanism
+ - Use compound mkdir -p line instead of individual calls to mkdir
+ - Fixed smb.conf file path for log files
+ - Fixed smb.conf file path for incoming smb print spool directory
+ - Added a number of options to smb.conf file
+ - Added smbuser file and smb.conf file updates for username map
+
+%prep
+%setup
+
+%build
+## Build main Samba source
+cd source
+
+%ifarch ia64
+libtoolize --copy --force # get it to recognize IA-64
+autoheader
+autoconf
+EXTRA="-D_LARGEFILE64_SOURCE"
+%endif
+NUMCPU=`grep processor /proc/cpuinfo | wc -l`
+CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
+ --prefix=%{prefix} \
+ --localstatedir=/var \
+ --with-configdir=/etc/samba \
+ --with-privatedir=/etc/samba \
+ --with-codepagedir=/etc/codepages \
+ --with-fhs \
+ --with-quotas \
+ --with-msdfs \
+ --with-smbmount \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-syslog \
+ --with-utmp \
+ --with-sambabook=%{prefix}/share/swat/using_samba \
+ --with-swatdir=%{prefix}/share/swat \
+ --with-libsmbclient
+make -j${NUMCPU} proto
+make -j${NUMCPU} all nsswitch/libnss_wins.so
+make -j${NUMCPU} debug2html
+make -j${NUMCPU} bin/smbspool
+
+## Build VFS modules
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \
+ --prefix=%{prefix} \
+ --localstatedir=/var
+make
+cd ../..
+
+# Remove some permission bits to avoid to many dependencies
+find examples docs -type f | xargs -r chmod -x
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT/etc/samba
+mkdir -p $RPM_BUILD_ROOT/etc/codepages/src
+mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d,samba}
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include,using_samba}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/{figs,gifs}
+mkdir -p $RPM_BUILD_ROOTMANDIR_MACRO
+mkdir -p $RPM_BUILD_ROOT/var/cache/samba
+mkdir -p $RPM_BUILD_ROOT/var/{log,run}/samba
+mkdir -p $RPM_BUILD_ROOT/var/spool/samba
+mkdir -p $RPM_BUILD_ROOT/lib/security
+mkdir -p $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+mkdir -p $RPM_BUILD_ROOT%{prefix}/{lib,include}
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbstatus testparm testprns \
+ make_smbcodepage make_unicodemap make_printerdef rpcclient smbspool \
+ smbcacls smbcontrol wbinfo smbmnt tdbbackup
+do
+ install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+for i in mksmbpasswd.sh smbtar findsmb
+do
+ install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat smbmount smbumount debug2html winbindd
+do
+ install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/sbin
+done
+
+# we need a symlink for mount to recognise the smb and smbfs filesystem types
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb
+
+# This allows us to get away without duplicating code that
+# sombody else can maintain for us.
+cd source
+make BASEDIR=$RPM_BUILD_ROOT/usr \
+ LIBDIR=$RPM_BUILD_ROOT/etc/samba \
+ VARDIR=$RPM_BUILD_ROOT/var \
+ SBINDIR=$RPM_BUILD_ROOT%{prefix}/sbin \
+ BINDIR=$RPM_BUILD_ROOT%{prefix}/bin \
+ MANDIR=$RPM_BUILD_ROOTMANDIR_MACRO \
+ CODEPAGEDIR=$RPM_BUILD_ROOT/etc/codepages \
+ SWATDIR=$RPM_BUILD_ROOT/usr/share/swat \
+ SAMBABOOK=$RPM_BUILD_ROOT/usr/share/swat/using_samba \
+ installman installcp installswat
+cd ..
+
+# Install codepage source files
+for i in source/codepages/codepage_def.* source/codepages/*.TXT
+do
+ install -m644 $i $RPM_BUILD_ROOT/etc/codepages/src
+done
+
+# Install the nsswitch wins library
+install -m755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/lib
+( cd $RPM_BUILD_ROOT/lib; ln -sf libnss_wins.so libnss_wins.so.2; )
+
+# Install winbind shared libraries
+install -m755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/lib
+( cd $RPM_BUILD_ROOT/lib; ln -sf libnss_winbind.so libnss_winbind.so.2; )
+install -m755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security
+
+# Install pam_smbpass.so
+install -m755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/lib/security
+
+# Install the VFS modules
+install -m755 examples/VFS/recycle/recycle.so $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+install -m644 examples/VFS/recycle/recycle.conf $RPM_BUILD_ROOT/etc/samba/
+install -m755 examples/VFS/block/block.so $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+install -m644 examples/VFS/block/samba-block.conf $RPM_BUILD_ROOT/etc/samba/
+install -m755 examples/VFS/audit.so $RPM_BUILD_ROOT%{prefix}/lib/samba/vfs
+
+# clean out VFS directory since it will get installed as documentation later
+(cd examples/VFS; make clean)
+
+# libsmbclient
+install -m 755 source/bin/libsmbclient.so $RPM_BUILD_ROOT%{prefix}/lib/
+install -m 755 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{prefix}/lib/
+install -m 644 source/include/libsmbclient.h $RPM_BUILD_ROOT%{prefix}/include/
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/help
+done
+for i in swat/images/*.gif
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/images
+done
+for i in swat/include/*.html
+do
+ install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/include
+done
+
+# Install the miscellany
+install -m644 swat/README $RPM_BUILD_ROOT%{prefix}/share/swat
+install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
+install -m755 packaging/RedHat/winbind.init $RPM_BUILD_ROOT/etc/rc.d/init.d/winbind
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
+install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
+install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/samba/smb.conf
+install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers
+install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
+install -m644 packaging/RedHat/samba.pamd.stack $RPM_BUILD_ROOT/etc/samba/samba.stack
+install -m644 packaging/RedHat/samba.xinetd $RPM_BUILD_ROOT/etc/samba/samba.xinetd
+echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts
+
+# Remove "*.old" files
+find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \;
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add smb
+/sbin/chkconfig --add winbind
+/sbin/chkconfig smb off
+/sbin/chkconfig winbind off
+
+echo "Looking for old /etc/smb.conf..."
+if [ -f /etc/smb.conf -a ! -f /etc/samba/smb.conf ]; then
+ echo "Moving old /etc/smb.conf to /etc/samba/smb.conf"
+ mv /etc/smb.conf /etc/samba/smb.conf
+fi
+
+echo "Looking for old /etc/smbusers..."
+if [ -f /etc/smbusers -a ! -f /etc/samba/smbusers ]; then
+ echo "Moving old /etc/smbusers to /etc/samba/smbusers"
+ mv /etc/smbusers /etc/samba/smbusers
+fi
+
+echo "Looking for old /etc/lmhosts..."
+if [ -f /etc/lmhosts -a ! -f /etc/samba/lmhosts ]; then
+ echo "Moving old /etc/lmhosts to /etc/samba/lmhosts"
+ mv /etc/lmhosts /etc/samba/lmhosts
+fi
+
+echo "Looking for old /etc/MACHINE.SID..."
+if [ -f /etc/MACHINE.SID -a ! -f /etc/samba/MACHINE.SID ]; then
+ echo "Moving old /etc/MACHINE.SID to /etc/samba/MACHINE.SID"
+ mv /etc/MACHINE.SID /etc/samba/MACHINE.SID
+fi
+
+echo "Looking for old /etc/smbpasswd..."
+if [ -f /etc/smbpasswd -a ! -f /etc/samba/smbpasswd ]; then
+ echo "Moving old /etc/smbpasswd to /etc/samba/smbpasswd"
+ mv /etc/smbpasswd /etc/samba/smbpasswd
+fi
+
+#
+# For 2.2.1 we move the tdb files from /var/lock/samba to /var/cache/samba
+# to preserve across reboots.
+#
+echo "Moving tdb files in /var/lock/samba/*.tdb to /var/cache/samba/*.tdb"
+for i in /var/lock/samba/*.tdb
+do
+if [ -f $i ]; then
+ newname=`echo $i | sed -e's|var\/lock\/samba|var\/cache\/samba|'`
+ echo "Moving $i to $newname"
+ mv $i $newname
+fi
+done
+
+# Remove the transient tdb files.
+if [ -e /var/cache/samba/brlock.tdb ]; then
+ rm -f /var/cache/samba/brlock.tdb
+fi
+
+if [ -e /var/cache/samba/unexpected.tdb ]; then
+ rm -f /var/cache/samba/unexpected.tdb
+fi
+
+if [ -e /var/cache/samba/connections.tdb ]; then
+ rm -f /var/cache/samba/connections.tdb
+fi
+
+if [ -e /var/cache/samba/locking.tdb ]; then
+ rm -f /var/cache/samba/locking.tdb
+fi
+
+if [ -e /var/cache/samba/messages.tdb ]; then
+ rm -f /var/cache/samba/messages.tdb
+fi
+
+if [ -d /var/lock/samba ]; then
+ rm -rf /var/lock/samba
+fi
+
+# Add swat entry to /etc/services if not already there.
+if !( grep ^[:space:]*swat /etc/services > /dev/null ) then
+ echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
+fi
+
+# Add swat entry to /etc/inetd.conf if needed.
+if [ -f /etc/inetd.conf ]; then
+ if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
+ echo 'swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf
+ killall -1 inetd || :
+ fi
+fi
+
+# Add swat entry to xinetd.d if needed.
+if [ -d $RPM_BUILD_ROOT/etc/xinetd.d -a ! -f /etc/xinetd.d/swat ]; then
+ mv /etc/samba/samba.xinetd /etc/xinetd.d/swat
+else
+ rm -f /etc/samba/samba.xinetd
+fi
+
+# Install the correct version of the samba pam file, depending on pam version.
+if [ -f /lib/security/pam_stack.so ]; then
+ echo "Installing stack version of /etc/pam.d/samba..."
+ mv /etc/samba/samba.stack /etc/pam.d/samba
+else
+ echo "Installing non-stack version of /etc/pam.d/samba..."
+ rm -f /etc/samba/samba.stack
+fi
+
+# Create winbind nss client symlink
+
+if [ -e /lib/libnss_winbind.so ]; then
+ ln -sf /lib/libnss_winbind.so /lib/libnss_winbind.so.2
+fi
+
+%preun
+if [ $1 = 0 ] ; then
+ /sbin/chkconfig --del smb
+
+ # We want to remove the browse.dat and wins.dat files so they can not interfer with a new version of samba!
+ if [ -e /var/cache/samba/browse.dat ]; then
+ rm -f /var/cache/samba/browse.dat
+ fi
+ if [ -e /var/cache/samba/wins.dat ]; then
+ rm -f /var/cache/samba/wins.dat
+ fi
+
+ # Remove the transient tdb files.
+ if [ -e /var/cache/samba/brlock.tdb ]; then
+ rm -f /var/cache/samba/brlock.tdb
+ fi
+
+ if [ -e /var/cache/samba/unexpected.tdb ]; then
+ rm -f /var/cache/samba/unexpected.tdb
+ fi
+
+ if [ -e /var/cache/samba/connections.tdb ]; then
+ rm -f /var/cache/samba/connections.tdb
+ fi
+
+ if [ -e /var/cache/samba/locking.tdb ]; then
+ rm -f /var/cache/samba/locking.tdb
+ fi
+
+ if [ -e /var/cache/samba/messages.tdb ]; then
+ rm -f /var/cache/samba/messages.tdb
+ fi
+
+ # Remove winbind nss client symlink
+
+ if [ -L /lib/libnss_winbind.so.2 ]; then
+ rm -f /lib/libnss_winbind.so.2
+ fi
+fi
+
+%postun
+# Only delete remnants of samba if this is the final deletion.
+if [ $1 = 0 ] ; then
+ if [ -x /etc/pam.d/samba ]; then
+ rm -f /etc/pam.d/samba
+ fi
+ if [ -e /var/log/samba ]; then
+ rm -rf /var/log/samba
+ fi
+ if [ -e /var/cache/samba ]; then
+ rm -rf /var/cache/samba
+ fi
+
+ # Remove swat entries from /etc/inetd.conf and /etc/services
+ cd /etc
+ tmpfile=/etc/tmp.$$
+ if [ -f /etc/inetd.conf ]; then
+ # preserve inetd.conf permissions.
+ cp -p /etc/inetd.conf $tmpfile
+ sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile
+ mv $tmpfile inetd.conf
+ fi
+ # preserve services permissions.
+ cp -p /etc/services $tmpfile
+ sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile
+ mv $tmpfile /etc/services
+
+ # Remove swat entry from /etc/xinetd.d
+ if [ -f /etc/xinetd.d/swat ]; then
+ rm -r /etc/xinetd.d/swat
+ fi
+fi
+
+#%triggerpostun -- samba < samba-2.0.0
+#if [ $0 != 0 ]; then
+# /sbin/chkconfig --add smb
+#fi
+
+%files
+%defattr(-,root,root)
+%doc README COPYING Manifest Read-Manifest-Now
+%doc WHATSNEW.txt Roadmap
+%doc docs
+%doc swat/README
+%doc examples
+%{prefix}/sbin/smbd
+%{prefix}/sbin/nmbd
+%{prefix}/sbin/swat
+%{prefix}/bin/smbmnt
+%{prefix}/sbin/smbmount
+%{prefix}/sbin/smbumount
+%{prefix}/sbin/winbindd
+%{prefix}/sbin/debug2html
+%{prefix}/sbin/samba
+/sbin/mount.smbfs
+/sbin/mount.smb
+%{prefix}/bin/mksmbpasswd.sh
+%{prefix}/bin/smbclient
+%{prefix}/bin/smbspool
+%{prefix}/bin/rpcclient
+%{prefix}/bin/testparm
+%{prefix}/bin/testprns
+%{prefix}/bin/findsmb
+%{prefix}/bin/smbstatus
+%{prefix}/bin/nmblookup
+%{prefix}/bin/make_smbcodepage
+%{prefix}/bin/make_unicodemap
+%{prefix}/bin/make_printerdef
+%{prefix}/bin/smbpasswd
+%{prefix}/bin/smbtar
+%{prefix}/bin/smbprint
+%{prefix}/bin/smbcontrol
+%{prefix}/bin/smbcacls
+%{prefix}/bin/wbinfo
+%{prefix}/bin/tdbbackup
+%attr(755,root,root) /lib/libnss_wins.s*
+%attr(755,root,root) %{prefix}/lib/samba/vfs/*.so
+%{prefix}/include/libsmbclient.h
+%{prefix}/lib/libsmbclient.a
+%{prefix}/lib/libsmbclient.so
+%{prefix}/share/swat/help/*
+%{prefix}/share/swat/images/*
+%{prefix}/share/swat/include/header.html
+%{prefix}/share/swat/include/footer.html
+%{prefix}/share/swat/using_samba/*
+%{prefix}/share/swat/README
+%config(noreplace) /etc/samba/lmhosts
+%config(noreplace) /etc/samba/smb.conf
+%config(noreplace) /etc/samba/recycle.conf
+%config(noreplace) /etc/samba/samba-block.conf
+%config(noreplace) /etc/samba/smbusers
+/etc/samba/samba.stack
+/etc/samba/samba.xinetd
+/etc/rc.d/init.d/smb
+/etc/rc.d/init.d/winbind
+/etc/logrotate.d/samba
+%config(noreplace) /etc/pam.d/samba
+MANDIR_MACRO/man1/*
+MANDIR_MACRO/man5/*
+MANDIR_MACRO/man7/*
+MANDIR_MACRO/man8/*
+%dir /etc/codepages/*
+%dir /etc/codepages/src/*
+%attr(755,root,root) %dir /var/cache/samba
+%dir /var/log/samba
+%dir /var/run/samba
+%attr(1777,root,root) %dir /var/spool/samba
+%attr(-,root,root) /lib/libnss_winbind.so
+%attr(-,root,root) /lib/security/pam_winbind.so
+%attr(-,root,root) /lib/security/pam_smbpass.so
diff --git a/packaging/RedHat/smb.conf b/packaging/RedHat/smb.conf
index 74806da16bb..71ff9463884 100644
--- a/packaging/RedHat/smb.conf
+++ b/packaging/RedHat/smb.conf
@@ -66,7 +66,7 @@
; smb passwd file = /etc/samba/smbpasswd
# The following are needed to allow password changing from Windows to
-# update the Linux system password also.
+# update the Linux sytsem password also.
# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
# NOTE2: You do NOT need these to allow workstations to change only
# the encrypted SMB passwords. They allow the Unix password
@@ -117,6 +117,10 @@
# and gives it a slightly higher chance of winning the election
; preferred master = yes
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = <NT-Domain-Controller-SMBName>
+
# Enable this if you want Samba to be a domain logon server for
# Windows95 workstations.
; domain logons = yes
diff --git a/packaging/RedHat/smb.init b/packaging/RedHat/smb.init
index 79f4f322d03..f50da2c6b2a 100755
--- a/packaging/RedHat/smb.init
+++ b/packaging/RedHat/smb.init
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# chkconfig: 345 81 35
+# chkconfig: 345 91 35
# description: Starts and stops the Samba smbd and nmbd daemons \
# used to provide SMB network services.
diff --git a/packaging/RedHat/smbprint b/packaging/RedHat/smbprint
index a0fd2e481b5..ec083eede62 100755
--- a/packaging/RedHat/smbprint
+++ b/packaging/RedHat/smbprint
@@ -74,4 +74,4 @@ echo "server $server, service $service" >> $logfile
# echo translate
echo "print -"
cat
-) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N >> $logfile
+) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/RedHat/winbind.init b/packaging/RedHat/winbind.init
index 1635dca93be..291c351df3a 100644
--- a/packaging/RedHat/winbind.init
+++ b/packaging/RedHat/winbind.init
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# chkconfig: 345 91 45
+# chkconfig: 345 81 45
# description: Starts and stops the Samba winbind daemon to provide \
# user and group information from a domain controller to linux.
@@ -19,16 +19,17 @@ fi
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
-CONFIG=/etc/samba/smb.conf
-
# Check that smb.conf exists.
-[ -f $CONFIG ] || exit 0
+[ -f /etc/samba/smb.conf ] || exit 0
+
+RETVAL=0
+
start() {
echo -n "Starting Winbind services: "
RETVAL=1
- if [ "`egrep -i '(idmap.*uid|winbind.*uid)' $CONFIG | egrep -v [\#\;]`" ]; then
- daemon winbindd
+ if [ "`grep -i 'winbind uid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
+ daemon winbindd
RETVAL=$?
fi
echo
@@ -39,7 +40,7 @@ start() {
stop() {
echo -n "Shutting down Winbind services: "
RETVAL=1
- if [ "`egrep -i '(idmap.*uid|winbind.*uid)' $CONFIG | egrep -v [\#\;]`" ]; then
+ if [ "`grep -i 'winbind uid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then
killproc winbindd
RETVAL=$?
fi
diff --git a/packaging/SGI/idb.pl b/packaging/SGI/idb.pl
index 529695b14b2..9e9ce0a1d8d 100755
--- a/packaging/SGI/idb.pl
+++ b/packaging/SGI/idb.pl
@@ -35,37 +35,73 @@ close IGNORES;
# get the names of all the binary files to be installed
open(MAKEFILE,"$SRCDIR/source/Makefile") || die "Unable to open Makefile\n";
-while (not eof(MAKEFILE)) {
- $_ = <MAKEFILE>;
- chomp;
- last if /^# object file lists/ ;
- if (/^EXEEXT/) {
- /^.*=(.*)/;
- $EXEEXT = $1;
- }
- if (/^srcdir/) {
- /^.*=(.*)/;
- $srcdir = $1;
- }
- if (/^builddir/) {
- /^.*=(.*)/;
- $builddir = $1;
- }
- if (/^SBIN_PROGS/) { @sbinprogs = get_line($_); }
- if (/^BIN_PROGS1/) { @binprogs1 = get_line($_); }
- if (/^BIN_PROGS2/) { @binprogs2 = get_line($_); }
- if (/^BIN_PROGS3/) { @binprogs3 = get_line($_); }
- if (/^BIN_PROGS/) { @binprogs = get_line($_); }
- if (/^SCRIPTS/) { @scripts = get_line($_); }
- if (/^TORTURE_PROGS/) { @tortureprogs = get_line($_); }
- if (/^SHLIBS/) { @shlibs = get_line($_); }
-}
+@makefile = <MAKEFILE>;
+@winbind_progs = grep(/^WINBIND_PROGS /,@makefile);
+@winbind_sprogs = grep(/^WINBIND_SPROGS /,@makefile);
+@winbind_lprogs = grep(/^WINBIND_LPROGS /,@makefile);
+@winbind_pam_progs = grep(/^WINBIND_PAM_PROGS /,@makefile);
+@sprogs = grep(/^SPROGS /,@makefile);
+@progs1 = grep(/^PROGS1 /,@makefile);
+@progs2 = grep(/^PROGS2 /,@makefile);
+@mprogs = grep(/^MPROGS /,@makefile);
+@progs = grep(/^PROGS /,@makefile);
+@scripts = grep(/^SCRIPTS /,@makefile);
+@codepagelist = grep(/^CODEPAGELIST/,@makefile);
close MAKEFILE;
-# add my local files to the list of binaries to install
-@bins = sort byfilename (@sbinprogs,@binprogs,@binprogs1,@binprogs2,@binprogs3,@scripts,("sambalp","smbprint"));
+if (@winbind_progs) {
+ @winbind_progs[0] =~ s/^.*\=//;
+ @winbind_progs = split(' ',@winbind_progs[0]);
+}
+if (@winbind_sprogs) {
+ @winbind_sprogs[0] =~ s/^.*\=//;
+ @winbind_sprogs = split(' ',@winbind_sprogs[0]);
+}
+if (@winbind_lprogs) {
+ @winbind_lprogs[0] =~ s/^.*\=//;
+ @winbind_lprogs = split(' ',@winbind_lprogs[0]);
+}
+if (@winbind_pam_progs) {
+ @winbind_pam_progs[0] =~ s/^.*\=//;
+ @winbind_pam_progs = split(' ',@winbind_pam_progs[0]);
+}
+if (@sprogs) {
+ @sprogs[0] =~ s/^.*\=//;
+ @sprogs[0] =~ s/\$\(\S+\)\s//g;
+ @sprogs = split(' ',@sprogs[0]);
+}
+if (@progs) {
+ @progs[0] =~ s/^.*\=//;
+ @progs[0] =~ s/\$\(\S+\)\s//g;
+ @progs = split(' ',@progs[0]);
+}
+if (@mprogs) {
+ @mprogs[0] =~ s/^.*\=//;
+ @mprogs = split(' ',@mprogs[0]);
+}
+if (@progs1) {
+ @progs1[0] =~ s/^.*\=//;
+ @progs1 = split(' ',@progs1[0]);
+}
+if (@progs2) {
+ @progs2[0] =~ s/^.*\=//;
+ @progs2 = split(' ',@progs2[0]);
+}
+if (@scripts) {
+ @scripts[0] =~ s/^.*\=//;
+ @scripts[0] =~ s/\$\(srcdir\)\///g;
+ @scripts = split(' ',@scripts[0]);
+}
-@nsswitch = sort byfilename (@shlibs);
+# we need to create codepages for the package
+@codepagelist[0] =~ s/^.*\=//;
+chdir "$SRCDIR/source";
+system("chmod +x ./script/installcp.sh");
+system("./script/installcp.sh . . ../packaging/SGI/codepages ./bin @codepagelist[0]");
+chdir $curdir;
+opendir(DIR,"$SRCDIR/packaging/SGI/codepages") || die "Can't open codepages directory";
+@codepage = sort readdir(DIR);
+closedir(DIR);
# install the swat files
chdir "$SRCDIR/source";
@@ -74,6 +110,11 @@ system("./script/installswat.sh ../packaging/SGI/swat ./ ../packaging/SGI/swat/
system("cp -f ../swat/README ../packaging/SGI/swat");
chdir $curdir;
+# add my local files to the list of binaries to install
+@bins = sort byfilename (@sprogs,@progs,@progs1,@progs2,@mprogs,@scripts,@winbind_progs,@winbind_sprogs,("/sambalp","/smbprint","bin/pdbedit","bin/tdbdump"));
+
+@nsswitch = sort byfilename (@winbind_lprogs,@winbind_pam_progs);
+
# get a complete list of all files in the tree
chdir "$SRCDIR/";
&dodir('.');
@@ -81,12 +122,10 @@ chdir $curdir;
# the files installed in docs include all the original files in docs plus all
# the "*.doc" files from the source tree
-@docs = sort bynextdir grep (!/CVS/ & (/^source\/.*\.doc$/ | /^docs\/\w/),@allfiles);
-@docs = grep(!/htmldocs/ & !/manpages/, @docs);
+@docs = sort byfilename grep (!/^docs\/$/ & (/^source\/.*\.doc$/ | /^docs\//),@allfiles);
+@docs = grep(!/htmldocs\/using_samba/, @docs);
@docs = grep(!/docbook/, @docs);
-@libfiles = sort byfilename (grep (/^source\/codepages\/\w/,@allfiles),("packaging/SGI/smb.conf","source/bin/libsmbclient.a","source/bin/libsmbclient.so"));
-
@swatfiles = sort grep(/^packaging\/SGI\/swat/, @allfiles);
@catman = sort grep(/^packaging\/SGI\/catman/ & !/\/$/, @allfiles);
@catman = sort bydirnum @catman;
@@ -107,6 +146,13 @@ print IDB "l 0000 root sys etc/rc2.d/S81samba $SRCPFX/packaging/SGI $PKG.sw.base
print IDB "l 0000 root sys etc/rc2.d/S82winbind $SRCPFX/packaging/SGI $PKG.sw.base symval(../init.d/winbind)\n";
if ($PKG eq "samba_irix") {
+ print IDB "d 0755 root sys usr/include/samba $SRCPFX/packaging/SGI $PKG.sw.base\n";
+ print IDB "f 0644 root sys usr/include/samba/libsmbclient.h $SRCPFX/source/include/libsmbclient.h $PKG.sw.base\n";
+
+ print IDB "d 0755 root sys usr/lib32/samba $SRCPFX/packaging/SGI $PKG.sw.base\n";
+ print IDB "f 0644 root sys usr/lib32/samba/libsmbclient.a $SRCPFX/source/bin/libsmbclient.a $PKG.sw.base\n";
+ print IDB "f 0644 root sys usr/lib32/samba/libsmbclient.so $SRCPFX/source/bin/libsmbclient.so $PKG.sw.base\n";
+
print IDB "d 0755 root sys usr/relnotes/samba_irix $SRCPFX/packaging/SGI $PKG.man.relnotes\n";
print IDB "f 0644 root sys usr/relnotes/samba_irix/TC relnotes/TC $PKG.man.relnotes\n";
print IDB "f 0644 root sys usr/relnotes/samba_irix/ch1.z relnotes/ch1.z $PKG.man.relnotes\n";
@@ -133,7 +179,7 @@ while(@bins) {
print IDB "f 0755 root sys usr/samba/bin/$filename $SRCPFX/source/$nextfile $PKG.sw.base \n";
}
elsif ($filename eq "swat") {
- print IDB "f 4755 root sys usr/samba/bin/$filename $SRCPFX/source/$nextfile $PKG.sw.base preop(\"chroot \$rbase /etc/init.d/samba stop\") exitop(\"chroot \$rbase /usr/samba/scripts/startswat.sh\") removeop(\"chroot \$rbase /sbin/cp /etc/inetd.conf /etc/inetd.conf.O ; chroot \$rbase /sbin/sed -e '/^swat/D' -e '/^#SWAT/D' /etc/inetd.conf.O >/etc/inetd.conf; /etc/killall -HUP inetd || true\")\n";
+ print IDB "f 4755 root sys usr/samba/bin/$filename $SRCPFX/source/$nextfile $PKG.sw.base preop(\"chroot \$rbase /etc/init.d/samba stop; exit 0\") exitop(\"chroot \$rbase /usr/samba/scripts/startswat.sh; exit 0\") removeop(\"chroot \$rbase /sbin/cp /etc/inetd.conf /etc/inetd.conf.O ; chroot \$rbase /sbin/sed -e '/^swat/D' -e '/^#SWAT/D' /etc/inetd.conf.O >/etc/inetd.conf; /etc/killall -HUP inetd || true; exit 0\")\n";
}
elsif ($filename eq "sambalp") {
print IDB "f 0755 root sys usr/samba/bin/$filename $SRCPFX/packaging/SGI/$filename $PKG.sw.base \n";
@@ -165,6 +211,7 @@ while(@bins) {
print IDB "d 0755 root sys usr/samba/docs $SRCPFX/docs $PKG.man.doc\n";
while (@docs) {
$nextfile = shift @docs;
+ next if ($nextfile eq "CVS");
($junk,$file) = split(/\//,$nextfile,2);
if (grep(/\/$/,$nextfile)) {
$file =~ s/\/$//;
@@ -176,19 +223,22 @@ while (@docs) {
}
}
-print IDB "d 0755 root sys usr/samba/include $SRCPFX/packaging/SGI $PKG.sw.base\n";
-print IDB "f 0644 root sys usr/samba/include/libsmbclient.h $SRCPFX/source/include/libsmbclient.h $PKG.sw.base\n";
+if ($PKG ne "samba_irix") {
+ print IDB "d 0755 root sys usr/samba/include $SRCPFX/packaging/SGI $PKG.sw.base\n";
+ print IDB "f 0644 root sys usr/samba/include/libsmbclient.h $SRCPFX/source/include/libsmbclient.h $PKG.sw.base\n";
+}
print IDB "d 0755 root sys usr/samba/lib $SRCPFX/packaging/SGI $PKG.sw.base\n";
-while (@libfiles) {
- $nextfile = shift @libfiles;
- ($file = $nextfile) =~ s/.*\///;
- if ($file eq "smb.conf") {
- print IDB "f 0644 root sys usr/samba/lib/$file $SRCPFX/$nextfile $PKG.sw.base config(suggest)\n";
- } else {
- print IDB "f 0644 root sys usr/samba/lib/$file $SRCPFX/$nextfile $PKG.sw.base nostrip \n";
- }
+print IDB "d 0755 root sys usr/samba/lib/codepages $SRCPFX/packaging/SGI $PKG.sw.base\n";
+while (@codepage) {
+ $nextpage = shift @codepage;
+ print IDB "f 0644 root sys usr/samba/lib/codepages/$nextpage $SRCPFX/packaging/SGI/codepages/$nextpage $PKG.sw.base nostrip \n";
+}
+if ($PKG ne "samba_irix") {
+ print IDB "f 0644 root sys usr/samba/lib/libsmbclient.a $SRCPFX/source/bin/libsmbclient.a $PKG.sw.base\n";
+ print IDB "f 0644 root sys usr/samba/lib/libsmbclient.so $SRCPFX/source/bin/libsmbclient.so $PKG.sw.base\n";
}
+print IDB "f 0644 root sys usr/samba/lib/smb.conf $SRCPFX/packaging/SGI/smb.conf $PKG.sw.base config(suggest)\n";
print IDB "d 0755 lp sys usr/samba/printer $SRCPFX/packaging/SGI $PKG.sw.base\n";
print IDB "d 0755 lp sys usr/samba/printer/W32ALPHA $SRCPFX/packaging/SGI $PKG.sw.base\n";
@@ -202,7 +252,7 @@ print IDB "f 0600 root sys usr/samba/private/smbpasswd $SRCPFX/packaging/SGI/smb
print IDB "d 0755 root sys usr/samba/scripts $SRCPFX/packaging/SGI $PKG.src.samba\n";
print IDB "f 0755 root sys usr/samba/scripts/inetd.sh $SRCPFX/packaging/SGI/inetd.sh $PKG.sw.base\n";
-print IDB "f 0755 root sys usr/samba/scripts/inst.msg $SRCPFX/packaging/SGI/inst.msg $PKG.sw.base exitop(\"chroot \$rbase /usr/samba/scripts/inst.msg\")\n";
+print IDB "f 0755 root sys usr/samba/scripts/inst.msg $SRCPFX/packaging/SGI/inst.msg $PKG.sw.base exitop(\"chroot \$rbase /usr/samba/scripts/inst.msg; exit 0\")\n";
print IDB "f 0755 root sys usr/samba/scripts/mkprintcap.sh $SRCPFX/packaging/SGI/mkprintcap.sh $PKG.sw.base\n";
print IDB "f 0755 root sys usr/samba/scripts/removeswat.sh $SRCPFX/packaging/SGI/removeswat.sh $PKG.sw.base\n";
print IDB "f 0755 root sys usr/samba/scripts/startswat.sh $SRCPFX/packaging/SGI/startswat.sh $PKG.sw.base\n";
@@ -271,10 +321,8 @@ if (@nsswitch) {
print IDB "d 0755 root sys var/ns/lib $SRCPFX/packaging/SGI $PKG.sw.base\n";
while(@nsswitch) {
$nextfile = shift @nsswitch;
- next if $nextfile eq 'libsmbclient';
($filename = $nextfile) =~ s/^.*\///;
- $filename =~ s/libnss/libns/;
- print IDB "f 0644 root sys var/ns/lib/$filename $SRCPFX/source/$nextfile $PKG.sw.base \n";
+ print IDB "f 0644 root sys var/ns/lib/$filename $SRCPFX/source/nsswitch/$filename $PKG.sw.base \n";
}
}
@@ -324,20 +372,12 @@ sub dodir {
}
}
-sub bynextdir {
+sub byfilename {
($f0,$f1) = split(/\//,$a,2);
($f0,$f2) = split(/\//,$b,2);
$f1 cmp $f2;
}
-sub byfilename {
- ($f0,$f1) = split(/.*\//,$a,2);
- if ($f1 eq "") { $f1 = $f0 };
- ($f0,$f2) = split(/.*\//,$b,2);
- if ($f2 eq "") { $f2 = $f0 };
- $f1 cmp $f2;
-}
-
sub bydirnum {
($f1 = $a) =~ s/^.*\///;
($f2 = $b) =~ s/^.*\///;
@@ -357,22 +397,3 @@ sub idbsort {
$f3 cmp $f4;
}
-sub get_line {
- local ($line) = @_;
-
- $line =~ s/^.*=//;
- while (($cont = index($line,"\\")) > 0) {
- $_ = <MAKEFILE>;
- chomp;
- s/^\s*/ /;
- substr($line,$cont,1) = $_;
- }
- $line =~ s/\$\(EXEEXT\)/$EXEEXT/g;
- $line =~ s/\$\(srcdir\)//g;
- $line =~ s/\$\(builddir\)//g;
- $line =~ s/\$\(\S*\)\s*//g;
- $line =~ s/\s\s*/ /g;
- @line = split(' ',$line);
- return @line;
-}
-
diff --git a/packaging/SGI/mkrelease.sh b/packaging/SGI/mkrelease.sh
index 89854300aaf..eb8a836173c 100755
--- a/packaging/SGI/mkrelease.sh
+++ b/packaging/SGI/mkrelease.sh
@@ -67,8 +67,7 @@ echo Making binaries
echo "===================== Making Profile versions ======================="
make clean
-make headers
-make -P "CFLAGS=-O -g3 -woff 1188 -D WITH_PROFILE" bin/smbd bin/nmbd
+make -P "CFLAGS=-O -g3 -woff 1188 -D WITH_PROFILE" CHECK bin/smbd bin/nmbd
errstat=$?
if [ $errstat -ne 0 ]; then
echo "Error $errstat building profile sources\n";
@@ -79,8 +78,7 @@ mv bin/nmbd bin/nmbd.profile
echo "===================== Making No Quota versions ======================="
make clean
-make headers
-make -P "CFLAGS=-O -g3 -woff 1188 -D QUOTAOBJS=smbd/noquotas.o" bin/smbd
+make -P "CFLAGS=-O -g3 -woff 1188 -D QUOTAOBJS=smbd/noquotas.o" CHECK bin/smbd
errstat=$?
if [ $errstat -ne 0 ]; then
echo "Error $errstat building noquota sources\n";
@@ -89,7 +87,7 @@ fi
mv bin/smbd bin/smbd.noquota
echo "===================== Making Regular versions ======================="
-make -P "CFLAGS=-O -g3 -woff 1188" all libsmbclient
+make -P "CFLAGS=-O -g3 -woff 1188" all libsmbclient bin/libsmbclient.so bin/pdbedit bin/tdbdump
errstat=$?
if [ $errstat -ne 0 ]; then
echo "Error $errstat building sources\n";
@@ -114,8 +112,6 @@ if [ $errstat -ne 0 ]; then
echo "Error $errstat creating samba.idb\n";
exit $errstat;
fi
-sort +4 samba.idb > xxx
-mv xxx samba.idb
if [ ! -d bins ]; then
mkdir bins
diff --git a/packaging/SGI/samba.rc b/packaging/SGI/samba.rc
index bc0f90ee77f..108220455b4 100644
--- a/packaging/SGI/samba.rc
+++ b/packaging/SGI/samba.rc
@@ -4,8 +4,25 @@
# Samba server control
#
+stop_samba()
+{
+ if [ -r /usr/samba/var/locks/smbd.pid ]; then
+ smbd_group=`cat /usr/samba/var/locks/smbd.pid`
+ ps -p $smbd_group | grep smbd > /dev/null
+ if [ $? -eq 0 ]; then
+ /usr/bin/kill -15 -$smbd_group
+ fi
+ fi
+ if [ -r /usr/samba/var/locks/nmbd.pid ]; then
+ nmbd_group=`cat /usr/samba/var/locks/nmbd.pid`
+ ps -p $nmbd_group | grep nmbd > /dev/null
+ if [ $? -eq 0 ]; then
+ /usr/bin/kill -15 $nmbd_group
+ fi
+ fi
+}
+
IS_ON=/etc/chkconfig
-KILLALL=/sbin/killall
SAMBAD=/usr/samba/bin/smbd
#SAMBA_OPTS=-d2
@@ -23,21 +40,30 @@ else # For a quiet startup and shutdown
fi
case $1 in
+'profile')
+ if $IS_ON samba && test -x $SAMBAD; then
+ stop_samba;
+ $ECHO "Samba:\c"
+ $SAMBAD.profile $SAMBA_OPTS; $ECHO " smbd.profile\c"
+ $NMBD.profile $NMBD_OPTS; $ECHO " nmbd.profile\c"
+ $ECHO "."
+ fi
+ ;;
'start')
if $IS_ON samba && test -x $SAMBAD; then
- $KILLALL -15 smbd nmbd
+ stop_samba;
$ECHO "Samba:\c"
- $SAMBAD $SAMBA_OPTS -D; $ECHO " smbd\c"
- $NMBD $NMBD_OPTS -D; $ECHO " nmbd\c"
+ $SAMBAD $SAMBA_OPTS; $ECHO " smbd\c"
+ $NMBD $NMBD_OPTS; $ECHO " nmbd\c"
$ECHO "."
fi
;;
'stop')
$ECHO "Stopping Samba Servers."
- $KILLALL -15 smbd nmbd
+ stop_samba;
exit 0
;;
*)
- echo "usage: /etc/init.d/samba {start|stop}"
+ echo "usage: /etc/init.d/samba {start|stop|profile}"
;;
esac
diff --git a/packaging/SGI/spec.pl b/packaging/SGI/spec.pl
index d581db7043f..ff5d3c097a6 100755
--- a/packaging/SGI/spec.pl
+++ b/packaging/SGI/spec.pl
@@ -4,21 +4,15 @@
# information in the version.h file in the source tree
open (VER,'../../source/include/version.h') || die "Unable to open version.h\n";
-while ( <VER> ) {
- chomp;
- if ( /SAMBA_VERSION_OFFICIAL_STRING/ ) {
- s/^.*SAMBA_VERSION_OFFICIAL_STRING "//;
- s/".*$//;
- $SambaVersion = $_;
- }
-}
+($_ = <VER>) =~ s/"//g;
close (VER);
+@foo = split(' ');
+splice(@foo,0,2);
+$_ = $foo[0];
# create the package name
-$vername = " id \"Samba Version ".$SambaVersion."\"\n";
+$vername = " id \"Samba Version ".$_."\"\n";
-$_ = $SambaVersion;
-s/^.* //;
$patch = 0;
#create the subsystem version numbers
if (/alpha/) {
@@ -57,6 +51,7 @@ print SPEC " subsys base default\n";
print SPEC " id \"Samba Execution Environment\"\n";
print SPEC " replaces fw_samba.sw.base 0 9999999999\n";
print SPEC " replaces fw_samba.sw.samba 0 9999999999\n";
+print SPEC " incompat samba_irix.sw.base 0 9999999999\n";
print SPEC " exp samba.sw.base\n";
print SPEC " endsubsys\n";
print SPEC " endimage\n";
@@ -68,16 +63,19 @@ print SPEC " subsys manpages default\n";
print SPEC " id \"Samba Man Page\"\n";
print SPEC " replaces fw_samba.man.manpages 0 9999999999\n";
print SPEC " replaces fw_samba.man.samba 0 9999999999\n";
+print SPEC " incompat samba_irix.man.manpages 0 9999999999\n";
print SPEC " exp samba.man.manpages\n";
print SPEC " endsubsys\n";
print SPEC " subsys doc default\n";
print SPEC " id \"Samba Documentation\"\n";
print SPEC " replaces fw_samba.man.doc 0 9999999999\n";
+print SPEC " incompat samba_irix.man.doc 0 9999999999\n";
print SPEC " exp samba.man.doc\n";
print SPEC " endsubsys\n";
print SPEC " subsys relnotes default\n";
print SPEC " id \"Samba Release Notes\"\n";
print SPEC " replaces fw_samba.man.relnotes 0 9999999999\n";
+print SPEC " incompat samba_irix.man.relnotes 0 9999999999\n";
print SPEC " exp samba.man.relnotes\n";
print SPEC " endsubsys\n";
print SPEC " endimage\n";
@@ -88,6 +86,7 @@ print SPEC " order 2\n";
print SPEC " subsys samba\n";
print SPEC " id \"Samba Source Code\"\n";
print SPEC " replaces fw_samba.src.samba 0 9999999999\n";
+print SPEC " incompat samba_irix.src.samba 0 9999999999\n";
print SPEC " exp samba.src.samba\n";
print SPEC " endsubsys\n";
print SPEC " endimage\n";
diff --git a/packaging/Solaris/copyright b/packaging/Solaris/copyright
index 1792668d174..de94e42367a 100644
--- a/packaging/Solaris/copyright
+++ b/packaging/Solaris/copyright
@@ -1 +1,2 @@
-Copyright (C) 2001 Samba Team
+Copyright (C) 2003 Samba Team
+Licensed under the GNU GPL version 2
diff --git a/packaging/Solaris/makepkg.sh.tmpl b/packaging/Solaris/makepkg.sh
index 2a46321f818..ac85de8c3c0 100755
--- a/packaging/Solaris/makepkg.sh.tmpl
+++ b/packaging/Solaris/makepkg.sh
@@ -11,51 +11,77 @@ INSTALL_BASE=/usr/local
add_dynamic_entries()
{
+ # First build the codepages and append codepage entries to prototype
+ echo "#\n# Codepages \n#"
+ echo d none samba/lib/codepages 0755 root other
+
+ CODEPAGELIST="437 737 850 852 861 932 866 949 950 936"
+ # Check if make_smbcodepage exists
+ if [ ! -f $DISTR_BASE/source/bin/make_smbcodepage ]; then
+ echo "Could not find $DISTR_BASE/source/bin/make_smbcodepage to generate codepages.\n\
+ Please create the binaries before packaging." >&2
+ exit 1
+ fi
+
+ for p in $CODEPAGELIST; do
+ $DISTR_BASE/source/bin/make_smbcodepage c $p $DISTR_BASE/source/codepages/codepage_def.$p $DISTR_BASE/source/codepages/codepage.$p
+ echo f none samba/lib/codepages/codepage.$p=source/codepages/codepage.$p 0644 root other
+ done
+
+ # Create unicode maps
+ if [ ! -f $DISTR_BASE/source/bin/make_unicodemap ]; then
+ echo "Missing $DISTR_BASE/source/bin/make_unicodemap. Aborting." >&2
+ exit 1
+ fi
+
+ # Pull in all the unicode map files from source/codepages/CP*.TXT
+ list=`find $DISTR_BASE/source/codepages -name "CP*.TXT" | sed 's|^.*CP\(.*\)\.TXT|\1|'`
+ for umap in $list
+ do
+ $DISTR_BASE/source/bin/make_unicodemap $umap $DISTR_BASE/source/codepages/CP$umap.TXT $DISTR_BASE/source/codepages/unicode_map.$umap
+ echo f none samba/lib/codepages/unicode_map.$umap=source/codepages/unicode_map.$umap 0644 root other
+ done
+
# Add the binaries, docs and SWAT files
+ echo "#\n# libraries\n#"
+ echo f none /usr/lib/nss_winbind.so.1=source/nsswitch/libnss_winbind.so 0755 root other
+ echo f none /usr/lib/security/pam_winbind.so=source/nsswitch/pam_winbind.so 0755 root other
+
+ echo "#\n# libsmbclient\n#"
+ echo f none /usr/local/include/libsmbclient.h=source/include/libsmbclient.h 0755 root other
+ echo f none /usr/local/lib/libsmbclient.so=source/bin/libsmbclient.so 0755 root other
+ echo f none /usr/local/lib/libsmbclient.a=source/bin/libsmbclient.a 0755 root other
+
+ chmod 644 $DISTR_BASE/source/bin/libsmbclient.*
+
echo "#\n# Binaries \n#"
cd $DISTR_BASE/source/bin
for binfile in *
do
- if [ -f $binfile ]; then
- case $file in
- CP*.so)
- echo echo f none samba/lib/charset/$binfile=source/bin/$binfile 0755 root other
- ;;
- *)
- echo f none samba/bin/$binfile=source/bin/$binfile 0755 root other
- ;;
- esac
+ if [ -f $binfile -a -x $binfile ]; then
+ echo f none samba/bin/$binfile=source/bin/$binfile 0755 root other
fi
done
+ chmod 755 $DISTR_BASE/source/bin/libsmbclient.*
+
# Add the scripts to bin/
echo "#\n# Scripts \n#"
- cd $DISTR_BASE/source/script
- for shfile in *
+ echo f none samba/bin/findsmb=source/script/findsmb 755 root other
+ echo f none samba/bin/smbtar=source/script/smbtar 755 root other
+ echo f none samba/bin/smbadduser=source/script/smbadduser 755 root other
+
+ # Add the Registry files
+ echo "#\n# Registry files \n#"
+ echo d none samba/docs/Registry 0755 root other
+ cd $DISTR_BASE
+ list=`find docs/Registry -type f -name "*.reg" | grep -v "/CVS$"`
+ for regfile in $list
do
- if [ -f $shfile ]; then
- echo f none samba/bin/$shfile=source/script/$shfile 0755 root other
- fi
+ echo f none samba/$regfile=$regfile 0644 root other
done
- # add libraries to /lib for winbind
- echo "#\n# Libraries \n#"
- if [ -f $DISTR_BASE/source/nsswitch/libnss_winbind.so ] ; then
- echo f none /usr/lib/libnss_winbind.so=source/nsswitch/libnss_winbind.so 0755 root other
- echo s none /usr/lib/libnss_winbind.so.1=/usr/lib/libnss_winbind.so 0755 root other
- echo s none /usr/lib/libnss_winbind.so.2=/usr/lib/libnss_winbind.so 0755 root other
- echo s none /usr/lib/nss_winbind.so.1=/usr/lib/libnss_winbind.so 0755 root other
- echo s none /usr/lib/nss_winbind.so.2=/usr/lib/libnss_winbind.so 0755 root other
- fi
-
- # add the .dat codepages
- echo "#\n# Codepages \n#"
- for file in $DISTR_BASE/source/codepages/*.dat ; do
- bfile=`basename $file`
- echo f none /usr/local/samba/lib/$bfile=source/codepages/$bfile
- done
-
# Add the manpages
echo "#\n# man pages \n#"
echo d none /usr ? ? ?
@@ -98,6 +124,15 @@ add_dynamic_entries()
# Create a symbolic link to the Samba book in docs/ for beginners
echo 's none samba/docs/samba_book=htmldocs/using_samba'
+ echo "#\n# Text Docs \n#"
+ echo d none samba/docs/textdocs 0755 root other
+ cd $DISTR_BASE/docs/textdocs
+ for textdoc in *
+ do
+ if [ -f $textdoc ]; then
+ echo f none samba/docs/textdocs/$textdoc=docs/textdocs/$textdoc 0644 root other
+ fi
+ done
echo "#\n# SWAT \n#"
cd $DISTR_BASE
list=`find swat -type d | grep -v "/CVS$"`
@@ -110,13 +145,6 @@ add_dynamic_entries()
do
echo "f none samba/$i=$i 0644 root other"
done
- # add the .msg files for SWAT
- echo "#\n# msg files \n#"
- for file in $DISTR_BASE/source/po/*.msg ; do
- bfile=`basename $file`
- echo f none /usr/local/samba/lib/$bfile=source/po/$bfile
- done
-
echo "#\n# HTML documentation for SWAT\n#"
cd $DISTR_BASE/docs/htmldocs
for htmldoc in *
@@ -156,7 +184,7 @@ if [ -f prototype ]; then
fi
# Setup version from version.h
-VERSION=PVERSION
+VERSION=`sed 's/#define VERSION \"\(.*\)\"$/\1/' ../../source/include/version.h`
sed -e "s|__VERSION__|$VERSION|" -e "s|__ARCH__|`uname -p`|" -e "s|__BASEDIR__|$INSTALL_BASE|g" pkginfo.master >pkginfo
sed -e "s|__BASEDIR__|$INSTALL_BASE|g" inetd.conf.master >inetd.conf
@@ -171,6 +199,6 @@ cp prototype.master prototype
pkgmk -o -d /tmp -b $DISTR_BASE -f prototype
if [ $? = 0 ]
then
- pkgtrans /tmp samba.pkg samba
+ pkgtrans /tmp samba-$VERSION.pkg samba
fi
echo The samba package is in /tmp
diff --git a/packaging/Solaris/pkg-specs/pkginfo b/packaging/Solaris/pkg-specs/pkginfo
deleted file mode 100644
index d24ecaefe81..00000000000
--- a/packaging/Solaris/pkg-specs/pkginfo
+++ /dev/null
@@ -1,12 +0,0 @@
-PKG=samba
-NAME=SMB based file/printer sharing
-ARCH=sparc
-VERSION=3.0.0beta3
-CATEGORY=system
-VENDOR=Samba Group
-DESC=File and printer sharing for NT workstations
-HOTLINE=Please contact your local UNIX support group
-EMAIL=samba@samba.org
-CLASSES=none
-BASEDIR=/usr/local
-INTONLY=1
diff --git a/packaging/Solaris/pkginfo.master b/packaging/Solaris/pkginfo.master
index 33e7cdb471d..36e93814165 100644
--- a/packaging/Solaris/pkginfo.master
+++ b/packaging/Solaris/pkginfo.master
@@ -1,5 +1,5 @@
PKG=samba
-NAME=SMB based file/printer sharing
+NAME=SMB/CIFS based file/printer sharing
ARCH=__ARCH__
VERSION=__VERSION__
CATEGORY=system
diff --git a/packaging/Solaris/prototype.master b/packaging/Solaris/prototype.master
index 6c5aa3e28ab..65af6deba37 100644
--- a/packaging/Solaris/prototype.master
+++ b/packaging/Solaris/prototype.master
@@ -16,10 +16,13 @@ i r.swat=./r.swat
# Stuff that goes into the system areas of the filesystem.
#
d none /etc ? ? ?
-d initscript /etc/init.d ? ? ?
-f initscript /etc/init.d/samba.server=packaging/Solaris/samba.server 0744 root sys
+d none /etc/init.d ? ? ?
+f none /etc/init.d/samba.server=packaging/Solaris/samba.server 0744 root sys
d initscript /etc/rc3.d ? ? ?
s initscript /etc/rc3.d/S99samba.server=../init.d/samba.server
+d none /usr/local/ ? ? ?
+d none /usr/local/lib ? ? ?
+d none /usr/local/include ? ? ?
#
# Stuff to set up SWAT
#
@@ -30,22 +33,15 @@ e swat /etc/inet/inetd.conf=packaging/Solaris/inetd.conf ? ? ?
# Create the samba subtree. (Usually /usr/local/samba )
#
d none samba 0755 root other
-d none samba/var 0755 root other
+d none samba/var 0711 root other
d none samba/bin 0755 root other
d none samba/lib 0755 root other
d none samba/docs 0755 root other
+d none samba/private 0700 root other
#
# Stuff that goes into lib
#
-d none samba/lib/charset 0755 root other
f none samba/lib/smb.conf.example=examples/smb.conf.default 0644 root other
-d none samba/lib/regeditscripts 0755 root other
-f none samba/lib/regeditscripts/NT4_PlainPassword.reg=docs/Registry/NT4_PlainPassword.reg 0444 root other
-f none samba/lib/regeditscripts/Win95_PlainPassword.reg=docs/Registry/Win95_PlainPassword.reg 0444 root other
-f none samba/lib/regeditscripts/Win98_PlainPassword.reg=docs/Registry/Win98_PlainPassword.reg 0444 root other
-f none samba/lib/regeditscripts/WinME_PlainPassword.reg=docs/Registry/WinME_PlainPassword.reg 0444 root other
-f none samba/lib/regeditscripts/Win2000_PlainPassword.reg=docs/Registry/Win2000_PlainPassword.reg 0444 root other
-f none samba/lib/regeditscripts/WinXP_PlainPassword.reg=docs/Registry/WinXP_PlainPassword.reg 0444 root other
#
# Random files
f none samba/docs/Samba-HOWTO-Collection.pdf=docs/Samba-HOWTO-Collection.pdf 0644 root other
diff --git a/packaging/Solaris/samba.server.master b/packaging/Solaris/samba.server.master
index d8bea2421c3..55109227b1e 100755
--- a/packaging/Solaris/samba.server.master
+++ b/packaging/Solaris/samba.server.master
@@ -39,7 +39,7 @@ case "$1" in
killproc smbd
BASE=__BASEDIR__/samba
$BASE/bin/smbd -D -s$BASE/lib/smb.conf
- $BASE/bin/nmbd -D -l$BASE/var/log -s$BASE/lib/smb.conf
+ $BASE/bin/nmbd -D -s$BASE/lib/smb.conf
;;
*)
diff --git a/packaging/SuSE/5.2/samba-1.9.18p5.dif b/packaging/SuSE/5.2/samba-1.9.18p5.dif
new file mode 100755
index 00000000000..39b13f010de
--- /dev/null
+++ b/packaging/SuSE/5.2/samba-1.9.18p5.dif
@@ -0,0 +1,234 @@
+--- Makefile.Linux
++++ Makefile.Linux 1998/05/06 15:58:42
+@@ -0,0 +1,35 @@
++#
++#
++# Makefile.Linux to integrate package into source tree of S.u.S.E.-Linux
++#
++# Copyright (C) 1996 S.u.S.E. GmbH Fuerth, Germany.
++#
++# Please send bug-fixes or comments to feedback@suse.de.
++#
++# Author: Florian La Roche <florian@suse.de>
++# Volker Lendecke <vl@suse.de>
++#
++#
++
++doc=/usr/doc/packages/samba
++
++compile:
++ make -C source
++
++install:
++ make install -C source
++ mkdir -p $(doc)
++ cp -a docs/* $(doc)
++ rm -rf $(doc)/*.[0-9]
++ cp -R examples $(doc)
++ chmod 644 `find $(doc) -type f`
++ chmod 755 `find $(doc) -type d`
++ install -m 644 smb.conf /etc/smb.conf
++ install rc /sbin/init.d/smb
++ install -m 755 source/mksmbpasswd.sh /usr/bin/mksmbpasswd.sh
++ ln -sf ../smb /sbin/init.d/rc2.d/S20smb
++ ln -sf ../smb /sbin/init.d/rc2.d/K20smb
++ ln -sf ../smb /sbin/init.d/rc3.d/S20smb
++ ln -sf ../smb /sbin/init.d/rc3.d/K20smb
++ mkdir -p /var/adm/fillup-templates
++ cp rc.config.samba /var/adm/fillup-templates
+--- doinst.sh
++++ doinst.sh 1998/05/06 15:54:52
+@@ -0,0 +1,15 @@
++#
++# install/doinst.sh - to be done after extraction
++#
++# Copyright (c) 1997 S.u.S.E. GmbH Fuerth, Germany.
++#
++#
++echo "Updating etc/rc.config..."
++if [ -x bin/fillup ] ; then
++ bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.samba
++else
++ echo "ERROR: fillup not found. This should not happen. Please compare"
++ echo "etc/rc.config and var/adm/fillup-templates/rc.config.samba and"
++ echo "update by hand."
++fi
++
+--- rc
++++ rc 1998/05/06 15:54:52
+@@ -0,0 +1,32 @@
++#! /bin/sh
++# Copyright (c) 1996 StarDivision GmbH. All rights reserved.
++# Copyright (c) 1996 S.u.S.E. Gmbh Fuerth, Germany. All rights reserved.
++#
++# Author: Bastian Epting, StarDivision GmbH <be@stardivision.de>
++# Florian La Roche, <florian@suse.de>
++# Volker Lendecke, <vl@suse.de>
++#
++
++. /etc/rc.config
++
++test "$START_SMB" = "yes" || exit 0
++
++case "$1" in
++ start)
++ echo -n "Starting SMB services."
++ /usr/sbin/nmbd -D
++ /usr/sbin/smbd -D
++ echo
++ ;;
++ stop)
++ echo -n "Shutting down SMB services."
++ killproc -TERM /usr/sbin/nmbd
++ killproc -TERM /usr/sbin/smbd
++ echo
++ ;;
++ *)
++ echo "Usage: $0 {start|stop}"
++ exit 1
++esac
++
++exit 0
+--- rc.config.samba
++++ rc.config.samba 1998/05/06 15:54:52
+@@ -0,0 +1,5 @@
++#
++# start samba? ("yes" or "no")
++# Windows 95 / NT - File- and Printservices
++#
++START_SMB="no"
+--- smb.conf
++++ smb.conf 1998/05/06 15:54:52
+@@ -0,0 +1,48 @@
++[global]
++ workgroup = arbeitsgruppe
++ guest account = nobody
++ keep alive = 30
++ os level = 2
++ security = user
++ printing = bsd
++ printcap name = /etc/printcap
++ load printers = yes
++
++; Please uncomment the following entry and replace the
++; ip number and netmask with the correct numbers for
++; your ethernet interface.
++; interfaces = 192.168.1.1/255.255.255.0
++
++; If you want Samba to act as a wins server, please set
++; 'wins support = yes'
++ wins support = no
++
++; If you want Samba to use an existing wins server,
++; please uncomment the following line and replace
++; the dummy with the wins server's ip number.
++; wins server = 192.168.1.1
++
++[homes]
++ comment = Heimatverzeichnis
++ browseable = no
++ read only = no
++ create mode = 0750
++
++; The following share gives all users access to the Server's CD drive,
++; assuming it is mounted under /cd. To enable this share, please remove
++; the semicolons before the lines
++;
++; [cdrom]
++; comment = Linux CD-ROM
++; path = /cd
++; read only = yes
++; locking = no
++
++[printers]
++ comment = All Printers
++ browseable = no
++ printable = yes
++ public = no
++ read only = yes
++ create mode = 0700
++ directory = /tmp
+--- source/Makefile
++++ source/Makefile 1998/05/06 15:54:52
+@@ -5,11 +5,11 @@
+ ###########################################################################
+
+ # The base directory for all samba files
+-BASEDIR = /usr/local/samba
++BASEDIR = /usr
+
+ # The base manpages directory to put the man pages in
+ # Note: $(MANDIR)/man1, $(MANDIR)/man5 and $(MANDIR)/man8 must exist.
+-MANDIR = /usr/local/man
++MANDIR = /usr/man
+
+ # The directories to put things in. If you use multiple
+ # architectures or share the samba binaries across NFS then
+@@ -18,16 +18,16 @@
+ # normally only applies to nmbd and smbd
+ # SBINDIR implies a secure binary directory
+ BINDIR = $(BASEDIR)/bin
+-SBINDIR = $(BASEDIR)/bin
+-LIBDIR = $(BASEDIR)/lib
+-VARDIR = $(BASEDIR)/var
++SBINDIR = $(BASEDIR)/sbin
++LIBDIR = $(BASEDIR)/lib/samba
++VARDIR = /var/log
+
+ # The permissions to give the executables
+ INSTALLPERMS = 0755
+
+ # Add any optimisation or debugging flags here
+ # add -DSYSLOG for syslog support
+-FLAGS1 = -O
++FLAGS1 = -O2
+ LIBS1 =
+
+ # You will need to use a ANSI C compiler. This means under SunOS 4 you can't
+@@ -47,15 +47,15 @@
+ # or in smb.conf (see smb.conf(5))
+ SMBLOGFILE = $(VARDIR)/log.smb
+ NMBLOGFILE = $(VARDIR)/log.nmb
+-CONFIGFILE = $(LIBDIR)/smb.conf
+-LMHOSTSFILE = $(LIBDIR)/lmhosts
+-DRIVERFILE = $(LIBDIR)/printers.def
++CONFIGFILE = /etc/smb.conf
++LMHOSTSFILE = /etc/lmhosts
++DRIVERFILE = /etc/printers.def
+ SMB_PASSWD = $(BINDIR)/smbpasswd
+-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+-WEB_ROOT = $(BASEDIR)
++SMB_PASSWD_FILE = /etc/smbpasswd
++WEB_ROOT = /etc
+
+ # the directory where lock files go
+-LOCKDIR = $(VARDIR)/locks
++LOCKDIR = /var/lock
+
+ # The directory where code page definition files go
+ CODEPAGEDIR = $(LIBDIR)/codepages
+@@ -206,7 +206,7 @@
+ # contributed by Andrew.Tridgell@anu.edu.au
+ # add -DLINUX_BIGCRYPT is you have shadow passwords but don't have the
+ # right libraries and includes
+-# FLAGSM = -DLINUX -DSHADOW_PWD -DFAST_SHARE_MODES
++FLAGSM = -DLINUX -DSHADOW_PWD -DFAST_SHARE_MODES
+ # LIBSM = -lshadow
+
+ # Use this for Linux without shadow passwords or for any Linux
+--- source/includes.h
++++ source/includes.h 1998/05/06 15:54:52
+@@ -244,13 +244,6 @@
+ #define USE_SETFS
+ #endif
+ #endif
+-#ifdef SHADOW_PWD
+-#if _LINUX_C_LIB_VERSION_MAJOR < 5
+-#ifndef crypt
+-#define crypt pw_encrypt
+-#endif
+-#endif
+-#endif
+ #endif
+
+ #ifdef SUNOS4
diff --git a/packaging/SuSE/5.2/samba.spec b/packaging/SuSE/5.2/samba.spec
new file mode 100755
index 00000000000..5f20875c9ea
--- /dev/null
+++ b/packaging/SuSE/5.2/samba.spec
@@ -0,0 +1,119 @@
+#
+# spec file for package samba (Version 1.9.18p1)
+#
+# Copyright (c) 1997 S.u.S.E. GmbH Fuerth, Germany.
+#
+# please send bugfixes or comments to feedback@suse.de.
+#
+
+Vendor: S.u.S.E. GmbH, Fuerth, Germany
+Distribution: S.u.S.E. Linux 5.1 (i386)
+Name: samba
+Release: 1
+Copyright: 1992-98 Andrew Tridgell, Karl Auer, Jeremy Allison
+Group:
+Provides: samba smbfs
+Requires:
+Conflicts:
+Autoreqprov: on
+Packager: feedback@suse.de
+
+Version: 1.9.18p5
+Summary: Samba is a file server for Unix, similar to LanManager.
+Source: samba-1.9.18p5.tar.gz
+Source1: smbfs-2.0.2.tar.gz
+Patch: samba-1.9.18p5.dif
+Patch1: smbfs-2.0.2.dif
+%prep
+%setup
+%patch
+%setup -T -n smbfs-2.0.2 -b1
+%patch -P 1
+%build
+cd ../samba-1.9.18p5
+make -f Makefile.Linux compile
+cd ../smbfs-2.0.2
+make -f Makefile.Linux compile
+%install
+cd ../samba-1.9.18p5
+make -f Makefile.Linux install
+cd ../smbfs-2.0.2
+make -f Makefile.Linux install
+Check
+%post
+echo "Updating etc/rc.config..."
+if [ -x bin/fillup ] ; then
+ bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.samba
+else
+ echo "ERROR: fillup not found. This should not happen. Please compare"
+ echo "etc/rc.config and var/adm/fillup-templates/rc.config.samba and"
+ echo "update by hand."
+fi
+%files
+%docdir /usr/doc/packages/samba
+/usr/doc/packages/samba
+%config /etc/smb.conf
+/usr/lib/samba/codepages
+/sbin/init.d/rc2.d/K20smb
+/sbin/init.d/rc2.d/S20smb
+/sbin/init.d/rc3.d/K20smb
+/sbin/init.d/rc3.d/S20smb
+%config /sbin/init.d/smb
+/usr/bin/addtosmbpass
+/usr/bin/mksmbpasswd.sh
+/usr/bin/make_printerdef
+/usr/bin/make_smbcodepage
+/usr/bin/nmblookup
+/usr/bin/smbclient
+/usr/bin/smbmount
+/usr/bin/smbpasswd
+/usr/bin/smbstatus
+/usr/bin/smbtar
+/usr/bin/smbumount
+/usr/bin/testparm
+/usr/bin/testprns
+%doc /usr/man/man1/smbclient.1.gz
+%doc /usr/man/man1/smbrun.1.gz
+%doc /usr/man/man1/smbstatus.1.gz
+%doc /usr/man/man1/smbtar.1.gz
+%doc /usr/man/man1/testparm.1.gz
+%doc /usr/man/man1/testprns.1.gz
+%doc /usr/man/man1/make_smbcodepage.1.gz
+%doc /usr/man/man5/smb.conf.5.gz
+%doc /usr/man/man7/samba.7.gz
+%doc /usr/man/man8/nmbd.8.gz
+%doc /usr/man/man8/smbd.8.gz
+%doc /usr/man/man8/smbmount.8.gz
+%doc /usr/man/man8/smbumount.8.gz
+%doc /usr/man/man8/smbmnt.8.gz
+%doc /usr/man/man8/smbpasswd.8.gz
+/usr/sbin/nmbd
+/usr/sbin/smbd
+/var/adm/fillup-templates/rc.config.samba
+%description
+Samba is a suite of programs which work together to allow clients to
+access Unix filespace and printers via the SMB protocol (Seerver Message
+Block).
+CAUTION: The samba daemons are started by the init script
+/sbin/init.d/samba, not by inetd. The entries for /usr/sbin/smbd
+and /usr/sbin/nmbd must be commented out in /etc/inetd.conf.
+In practice, this means that you can redirect disks and printers to
+Unix disks and printers from LAN Manager clients, Windows for
+Workgroups 3.11 clients, Windows'95 clients, Windows NT clients
+and OS/2 clients. There is
+also a Unix client program supplied as part of the suite which allows
+Unix users to use an ftp-like interface to access filespace and
+printers on any other SMB server.
+Samba includes the following programs (in summary):
+* smbd, the SMB server. This handles actual connections from clients.
+* nmbd, the Netbios name server, which helps clients locate servers.
+* smbclient, the Unix-hosted client program.
+* testprns, a program to test server access to printers.
+* testparm, a program to test the Samba configuration file for correctness.
+* smb.conf, the Samba configuration file.
+* smbprint, a sample script to allow a Unix host to use smbclient
+to print to an SMB server.
+The suite is supplied with full source and is GPLed.
+This package expects its config file under /etc/smb.conf .
+Documentation: /usr/doc/packages/samba
+
diff --git a/packaging/SuSE/7.1/samba-2.2.0-alpha0.dif b/packaging/SuSE/7.1/samba-2.2.0-alpha0.dif
new file mode 100755
index 00000000000..75bfdf18c66
--- /dev/null
+++ b/packaging/SuSE/7.1/samba-2.2.0-alpha0.dif
@@ -0,0 +1,224 @@
+--- lmhosts
++++ lmhosts 2000/08/28 07:32:33
+@@ -0,0 +1,8 @@
++# This file provides the same function that the
++# lmhosts file does for Windows.
++# It provides another way to map netbios names to ip addresses.
++# See the section on 'name resolve order' in the manual page to
++# smb.conf for more information.
++
++# Sample entry:
++# 192.168.1.1 samba
+--- mount.smbfs
++++ mount.smbfs 2000/08/28 07:32:55
+@@ -0,0 +1,14 @@
++#!/bin/sh
++#
++# Copyright (c) 1999 SuSE GmbH Nuernberg, Germany. All rights reserved.
++#
++# Author: Carsten Hoeger <choeger@suse.de>
++#
++# /sbin/mount.smbfs
++#
++# I'm called by the mount-command and smbmount want's to get
++# called by me, so lets do it.
++#
++# P.S.: This is a very very raw solution and I don't know, if this
++# is intentionally.
++smbmount "$@"
+--- rc
++++ rc 2000/08/28 07:32:33
+@@ -0,0 +1,53 @@
++#! /bin/sh
++# Copyright (c) 1996 StarDivision GmbH. All rights reserved.
++# Copyright (c) 1996 S.u.S.E. Gmbh Fuerth, Germany. All rights reserved.
++#
++# Author: Bastian Epting, StarDivision GmbH <be@stardivision.de>
++# Florian La Roche, <florian@suse.de>
++# Volker Lendecke, <vl@suse.de>
++#
++
++. /etc/rc.config
++
++# Determine the base and follow a runlevel link name.
++base=${0##*/}
++link=${base#*[SK][0-9][0-9]}
++
++# Force execution if not called by a runlevel directory.
++test $link = $base && START_SMB=yes
++test "$START_SMB" = "yes" || exit 0
++
++# The echo return value for success (defined in /etc/rc.config).
++return=$rc_done
++case "$1" in
++ start)
++ echo -n "Starting SMB services:"
++ startproc /usr/sbin/nmbd -D || return=$rc_failed
++ startproc /usr/sbin/smbd -D || return=$rc_failed
++ echo -e "$return"
++ ;;
++ stop)
++ echo -n "Shutting down SMB services:"
++ killproc -TERM /usr/sbin/nmbd || return=$rc_failed
++ killproc -TERM /usr/sbin/smbd || return=$rc_failed
++ echo -e "$return"
++ ;;
++ restart|reload)
++ echo -n "Reloading SMB services:"
++ killproc -HUP /usr/sbin/nmbd || return=$rc_failed
++ killproc -HUP /usr/sbin/smbd || return=$rc_failed
++ echo -e "$return"
++ ;;
++ status)
++ echo -n "Checking for service smb: "
++ checkproc /usr/sbin/nmbd && echo -n "OK " || echo -n "No process "
++ checkproc /usr/sbin/smbd && echo "OK " || echo "No process"
++ ;;
++ *)
++ echo "Usage: $0 {start|stop|restart|reload|status}"
++ exit 1
++esac
++
++# Inform the caller not only verbosely and set an exit status.
++test "$return" = "$rc_done" || exit 1
++exit 0
+--- rc.config.samba
++++ rc.config.samba 2000/08/28 07:32:33
+@@ -0,0 +1,5 @@
++#
++# start samba? ("yes" or "no")
++# Windows 95 / NT - File- and Printservices
++#
++START_SMB="no"
+--- smb.conf
++++ smb.conf 2000/08/28 07:32:33
+@@ -0,0 +1,80 @@
++;
++; /etc/smb.conf
++;
++; Copyright (c) 1999 SuSE GmbH Nuernberg, Germany.
++;
++[global]
++ workgroup = arbeitsgruppe
++ guest account = nobody
++ keep alive = 30
++ os level = 2
++ kernel oplocks = false
++ security = user
++
++; Uncomment the following, if you want to use an existing
++; NT-Server to authenticate users, but don't forget that
++; you also have to create them locally!!!
++; security = server
++; password server = 192.168.1.10
++; encrypt passwords = yes
++
++ printing = bsd
++ printcap name = /etc/printcap
++ load printers = yes
++
++ socket options = TCP_NODELAY
++
++ map to guest = Bad User
++
++; Uncomment this, if you want to integrate your server
++; into an existing net e.g. with NT-WS to prevent nettraffic
++; local master = no
++
++; Please uncomment the following entry and replace the
++; ip number and netmask with the correct numbers for
++; your ethernet interface.
++; interfaces = 192.168.1.1/255.255.255.0
++
++; If you want Samba to act as a wins server, please set
++; 'wins support = yes'
++ wins support = no
++
++; If you want Samba to use an existing wins server,
++; please uncomment the following line and replace
++; the dummy with the wins server's ip number.
++; wins server = 192.168.1.1
++
++; Do you wan't samba to act as a logon-server for
++; your windows 95/98 clients, so uncomment the
++; following:
++; logon script =%U.bat
++; domain logons = yes
++; domain master = yes
++; [netlogon]
++; path = /netlogon
++
++
++[homes]
++ comment = Heimatverzeichnis
++ browseable = no
++ read only = no
++ create mode = 0750
++
++; The following share gives all users access to the Server's CD drive,
++; assuming it is mounted under /cd. To enable this share, please remove
++; the semicolons before the lines
++;
++; [cdrom]
++; comment = Linux CD-ROM
++; path = /cdrom
++; read only = yes
++; locking = no
++
++[printers]
++ comment = All Printers
++ browseable = no
++ printable = yes
++ public = no
++ read only = yes
++ create mode = 0700
++ directory = /tmp
+--- smbfs
++++ smbfs 2000/08/28 07:32:33
+@@ -0,0 +1,40 @@
++#! /bin/bash
++# Copyright (c) 1996 SuSE GmbH Nuernberg, Germany. All rights reserved.
++#
++# Author: Thomas Fehr <fehr@suse.de>, 1999
++#
++# /sbin/init.d/smbfs
++#
++
++smbfs=no
++if [ `cat /proc/mounts | grep " smbfs " | wc -l` -gt 0 ]
++then
++ smbfs=yes
++fi
++
++return=$rc_done
++case "$1" in
++ start|reload)
++ ;;
++ stop)
++ if [ "$smbfs" = "yes" ]
++ then
++ echo -n "Remove SMB File System"
++ #
++ # Unmount in background because during long timeouts
++ #
++ umount -at smbfs &
++ sleep 2
++ echo -e "$return"
++ fi
++ ;;
++ restart)
++ $0 stop && $0 start || return=$rc_failed
++ ;;
++ status)
++ ;;
++ *)
++ echo "Usage: $0 {start|stop|status|reload|restart}"
++ exit 1
++esac
++exit 0
+--- smbpasswd
++++ smbpasswd 2000/08/28 07:32:33
+@@ -0,0 +1,3 @@
++# Sample smbpasswd file.
++# To use this, set 'encrypt passwords = yes' in the [global]-section
++# of /etc/smb.conf
diff --git a/packaging/SuSE/7.1/samba.pamd b/packaging/SuSE/7.1/samba.pamd
new file mode 100755
index 00000000000..d9e7088bea3
--- /dev/null
+++ b/packaging/SuSE/7.1/samba.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+auth required /lib/security/pam_unix.so
+account required /lib/security/pam_unix.so
diff --git a/packaging/SuSE/7.1/samba.spec b/packaging/SuSE/7.1/samba.spec
new file mode 100755
index 00000000000..60d8099edbf
--- /dev/null
+++ b/packaging/SuSE/7.1/samba.spec
@@ -0,0 +1,381 @@
+#
+# spec file for package samba (Version 2.0.7)
+#
+# Copyright (c) 2000 SuSE GmbH Nuernberg, Germany.
+#
+# please send bugfixes or comments to feedback@suse.de.
+#
+
+# neededforbuild automake openldap
+# usedforbuild aaa_base aaa_dir autoconf automake base bash bindutil binutils bison bzip compress cpio cracklib devs diff ext2fs file fileutil find flex gawk gcc gdbm gettext gpm gppshare groff gzip kbd less libc libtool libz lx_suse make mktemp modules ncurses net_tool netcfg nkita nkitb nssv1 openldap pam patch perl pgp ps rcs rpm sendmail sh_utils shadow shlibs strace syslogd sysvinit texinfo textutil timezone unzip util vim xdevel xf86 xshared
+
+Vendor: SuSE GmbH, Nuernberg, Germany
+Distribution: SuSE Linux 7.1a (i386)
+Name: samba
+Release: 0
+Packager: feedback@suse.de
+
+Copyright: 1992-95 Andrew Tridgell, Karl Auer, Jeremy Allison
+Group: Networking/Daemons
+Url: http://www.samba.org
+Provides: samba smbfs
+Requires: smbclnt
+Autoreqprov: on
+Version: 2.2
+Summary: An SMB file server for Unix
+Source: samba-2.2.0-alpha0.tar.gz
+Source1: samba.pamd
+Patch: samba-2.2.0-alpha0.dif
+%package -n smbclnt
+Summary: Samba client utilities
+Autoreqprov: on
+Group: Networking
+%prep
+%setup -n samba-2.2.0-alpha0
+%patch
+
+%build
+cd source
+%{?suse_update_config:%{suse_update_config -f}}
+LIBS=-lnsl \
+./configure --prefix=/usr --libdir=/etc \
+ --with-privatedir=/etc --localstatedir=/var/log \
+ --with-smbmount --with-pam \
+ --mandir=%{_mandir} \
+ --with-swatdir=/usr/lib/samba/swat \
+ --with-sambabook=/usr/lib/samba/swat/using_samba
+cd ..
+make LOCKDIR=/var/lock/samba SBINDIR=/usr/sbin \
+ CODEPAGEDIR=/usr/lib/samba/codepages -C source
+
+%install
+mkdir -p /usr/lib/samba
+make install LOCKDIR=/var/lock/samba SBINDIR=/usr/sbin \
+ CODEPAGEDIR=/usr/lib/samba/codepages -C source
+# cleanup docs
+rm -rf docs/*.[0-9]
+chmod 644 `find docs examples -type f`
+chmod 755 `find docs examples -type d`
+#utility scripts
+mkdir -p /usr/lib/samba/scripts
+cp -a source/script/* /usr/lib/samba/scripts
+# configuration files
+install -m 644 smb.conf /etc/smb.conf
+install -m 644 lmhosts /etc/lmhosts
+install -m 600 smbpasswd -o root -g root /etc/smbpasswd
+install -d 755 /etc/pam.d
+install -m 644 $RPM_SOURCE_DIR/samba.pamd /etc/pam.d/samba
+install -m 755 mount.smbfs /sbin/mount.smbfs
+# start script
+install rc /sbin/init.d/smb
+ln -sf ../smb /sbin/init.d/rc2.d/S20smb
+ln -sf ../smb /sbin/init.d/rc2.d/K20smb
+ln -sf ../smb /sbin/init.d/rc3.d/S20smb
+ln -sf ../smb /sbin/init.d/rc3.d/K20smb
+ln -sf ../../sbin/init.d/smb /usr/sbin/rcsmb
+install smbfs /sbin/init.d/smbfs
+ln -sf ../smbfs /sbin/init.d/rc2.d/S21smbfs
+ln -sf ../smbfs /sbin/init.d/rc2.d/K19smbfs
+ln -sf ../smbfs /sbin/init.d/rc3.d/S21smbfs
+ln -sf ../smbfs /sbin/init.d/rc3.d/K19smbfs
+ln -sf ../../sbin/init.d/smbfs /usr/sbin/rcsmbfs
+# rc.config fragment
+mkdir -p /var/adm/fillup-templates
+cp rc.config.samba /var/adm/fillup-templates
+%{?suse_check}
+
+%post
+echo "Updating etc/rc.config..."
+if [ -x bin/fillup ] ; then
+ bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.samba
+else
+ echo "ERROR: fillup not found. This should not happen. Please compare"
+ echo "etc/rc.config and var/adm/fillup-templates/rc.config.samba and"
+ echo "update by hand."
+fi
+if grep -q '^[#[:space:]]*swat' etc/inetd.conf ; then
+ echo /etc/inetd.conf is up to date
+else
+ echo updating inetd.conf
+ cat >> etc/inetd.conf << EOF
+# swat is the Samba Web Administration Tool
+swat stream tcp nowait.400 root /usr/sbin/swat swat
+EOF
+fi
+if grep -q '^swat' etc/services ; then
+ echo /etc/services is up to date
+else
+ echo updating services
+ cat >> etc/services << EOF
+swat 901/tcp # swat is the Samba Web Administration Tool
+EOF
+fi
+mkdir -p var/adm/notify/messages
+cat << EOF > var/adm/notify/messages/samba-notify
+Achtung!
+========
+Die Syntax des smbmount Kommandos hat sich geaendert!
+smbmount kann nicht mehr direkt aufgerufen werden. Es wird von einem
+Shellscript /sbin/mount.smbfs aufgerufen, welches wiederum von mount
+aufgerufen wird.
+Hier ein Beispielaufruf:
+mount -t smbfs -o username=uname,password=passwd //smbserv/share /destination
+*****************************************************************************
+Attention!
+==========
+The syntax of smbmount has changed!
+smbmount can not be called direct anymore. It will be called by a shell
+script /sbin/mount.smbfs, which will be called by mount.
+A sample call to smbfs:
+mount -t smbfs -o username=uname,password=passwd //smbserv/share /destination
+EOF
+
+%files
+%config(noreplace) /etc/smb.conf
+%config(noreplace) /etc/lmhosts
+%config(noreplace) /etc/smbpasswd
+%config /etc/pam.d/samba
+/usr/lib/samba
+/sbin/init.d/rc2.d/K20smb
+/sbin/init.d/rc2.d/S20smb
+/sbin/init.d/rc3.d/K20smb
+/sbin/init.d/rc3.d/S20smb
+%config /sbin/init.d/smb
+/usr/bin/addtosmbpass
+/usr/bin/convert_smbpasswd
+/usr/bin/make_printerdef
+/usr/bin/make_smbcodepage
+/usr/bin/make_unicodemap
+/usr/bin/smbpasswd
+/usr/bin/smbstatus
+/usr/bin/testparm
+/usr/bin/testprns
+%doc docs/* examples
+%doc %{_mandir}/man1/make_smbcodepage.1.gz
+%doc %{_mandir}/man1/make_unicodemap.1.gz
+%doc %{_mandir}/man1/smbrun.1.gz
+%doc %{_mandir}/man1/smbsh.1.gz
+%doc %{_mandir}/man1/smbstatus.1.gz
+%doc %{_mandir}/man1/testparm.1.gz
+%doc %{_mandir}/man1/testprns.1.gz
+%doc %{_mandir}/man5/lmhosts.5.gz
+%doc %{_mandir}/man5/smb.conf.5.gz
+%doc %{_mandir}/man5/smbpasswd.5.gz
+%doc %{_mandir}/man7/samba.7.gz
+%doc %{_mandir}/man8/nmbd.8.gz
+%doc %{_mandir}/man8/smbd.8.gz
+%doc %{_mandir}/man8/smbpasswd.8.gz
+%doc %{_mandir}/man8/swat.8.gz
+/usr/sbin/nmbd
+/usr/sbin/rcsmb
+/usr/sbin/smbd
+/usr/sbin/swat
+/var/adm/fillup-templates/rc.config.samba
+
+%files -n smbclnt
+/sbin/init.d/rc2.d/K19smbfs
+/sbin/init.d/rc2.d/S21smbfs
+/sbin/init.d/rc3.d/K19smbfs
+/sbin/init.d/rc3.d/S21smbfs
+%config /sbin/init.d/smbfs
+/usr/sbin/rcsmbfs
+/sbin/mount.smbfs
+/usr/bin/nmblookup
+/usr/bin/rpcclient
+/usr/bin/smbclient
+/usr/bin/smbmnt
+/usr/bin/smbmount
+/usr/bin/smbumount
+/usr/bin/smbspool
+/usr/bin/smbtar
+%doc %{_mandir}/man1/nmblookup.1.gz
+%doc %{_mandir}/man1/smbclient.1.gz
+%doc %{_mandir}/man1/smbtar.1.gz
+%doc %{_mandir}/man8/smbmnt.8.gz
+%doc %{_mandir}/man8/smbmount.8.gz
+%doc %{_mandir}/man8/smbspool.8.gz
+%doc %{_mandir}/man8/smbumount.8.gz
+
+%description
+Samba is a suite of programs which work together to allow clients to
+access Unix filespace and printers via the SMB protocol (Server Message
+Block).
+In practice, this means that you can redirect disks and printers to
+Unix disks and printers from LAN Manager clients, Windows for
+Workgroups 3.11 clients, Windows'95 clients, Windows NT clients
+and OS/2 clients. There is
+also a Unix client program supplied as part of the suite which allows
+Unix users to use an ftp-like interface to access filespace and
+printers on any other SMB server.
+Samba includes the following programs (in summary):
+* smbd, the SMB server. This handles actual connections from clients.
+* nmbd, the Netbios name server, which helps clients locate servers.
+* smbclient, the Unix-hosted client program.
+* smbrun, a little 'glue' program to help the server run external
+programs.
+* testprns, a program to test server access to printers.
+* testparm, a program to test the Samba configuration file for correctness.
+* smb.conf, the Samba configuration file.
+* smbprint, a sample script to allow a Unix host to use smbclient
+to print to an SMB server.
+The suite is supplied with full source and is GPLed.
+This package expects its config file under /etc/smb.conf .
+
+Authors:
+--------
+ Andrew Tridgell <Andrew.Tridgell@anu.edu.au>
+ Karl Auer <Karl.Auer@anu.edu.au>
+ Jeremy Allison <jeremy@netcom.com>
+
+SuSE series: n
+
+
+%description -n smbclnt
+This package contains all programs, that are needed to act as a samba
+client. This includes also smbmount, of course.
+
+Authors:
+--------
+ Andrew Tridgell <Andrew.Tridgell@anu.edu.au>
+ Karl Auer <Karl.Auer@anu.edu.au>
+ Jeremy Allison <jeremy@netcom.com>
+
+SuSE series: n
+
+
+%changelog -n samba
+* Mon Aug 28 2000 - choeger@suse.de
+- changed $* to "$@" in mount.smbfs to make it also
+ possible to mount shares with spaces
+* Mon Jul 31 2000 - choeger@suse.de
+- improvement for rcsmb
+- fix for spec-file to compile with NIS netgroups
+* Thu Jul 20 2000 - choeger@suse.de
+- added smbfs initscript that has been removed
+ by an error
+* Tue Jul 11 2000 - choeger@suse.de
+- split package into client and server parts
+ client package name: smbclnt
+* Wed Apr 26 2000 - choeger@suse.de
+- new version, 2.0.7
+* Thu Apr 06 2000 - ro@suse.de
+- removed pam,cracklib from neededforbuild: build handles this
+* Wed Apr 05 2000 - bk@suse.de
+- s390 team added config.{sub,guess} update macro for s390
+* Mon Mar 27 2000 - choeger@suse.de
+- fixed bug in specfile
+ the multilined configure call missed a "" :-(
+* Thu Mar 09 2000 - choeger@suse.de
+- fixed typo in specfile
+* Wed Mar 01 2000 - choeger@suse.de
+- added %{_mandir}
+* Tue Feb 08 2000 - choeger@suse.de
+- removed /sbin/init.d/smbfs because it is no longer needed
+* Mon Jan 03 2000 - choeger@suse.de
+- bugfix for ipc.c
+ to make roaming profiles work again.
+* Tue Nov 30 1999 - choeger@suse.de
+- changed kernel oplocks = off to
+ kernel oplocks = false
+* Tue Nov 16 1999 - choeger@suse.de
+- added kernel oplocks = off in smb.conf
+* Fri Nov 12 1999 - choeger@suse.de
+- new version, 2.0.6
+* Fri Nov 05 1999 - choeger@suse.de
+- Fix for the smbmount lost-connection problem
+ _seems_ to work...
+* Fri Oct 29 1999 - choeger@suse.de
+- removed comment sign in /etc/inetd.conf for swat
+* Mon Sep 13 1999 - bs@suse.de
+- ran old prepare_spec on spec file to switch to new prepare_spec.
+* Tue Aug 10 1999 - fehr@suse.de
+- set execute permissions for mksmbpasswd.sh and changesmbpasswd.sh
+* Thu Jul 29 1999 - fehr@suse.de
+- fixed typo in /sbin/init.d/smbfs
+* Thu Jul 22 1999 - fehr@suse.de
+- changed to new version 2.0.5a
+* Wed Jul 21 1999 - fehr@suse.de
+- changed to new version 2.0.5
+* Tue Jul 20 1999 - fehr@suse.de
+- install /sbin/init.d/smbfs
+- changed to new version 2.0.5pre4
+* Mon Jul 19 1999 - fehr@suse.de
+- add /sbin/init.d/smbfs
+- changed to new version 2.0.5pre3
+* Fri Jul 02 1999 - fehr@suse.de
+- removed "umount -a -t smbfs" from start sscript
+* Tue Jun 22 1999 - kukuk@suse.de
+- 2.0.4b changed default values, enable PAM again
+* Fri Jun 18 1999 - kukuk@suse.de
+- changed to new version 2.0.4b
+* Mon Jun 14 1999 - kukuk@suse.de
+- Enable PAM, add samba.pamd
+* Mon May 03 1999 - fehr@suse.de
+- add umount -a -t smbfs to shutdown sequence of samba
+* Thu Mar 11 1999 - ro@suse.de
+- smbmount: define NR_OPEN to 1024 if undefined (GLIBC-2.1)
+* Wed Mar 10 1999 - choeger@suse.de
+- some enhancements for smb.conf
+* Wed Mar 10 1999 - choeger@suse.de
+- new version 2.0.3 and smbmount now seems to work
+* Tue Mar 09 1999 - ro@suse.de
+- use samba-2.0.2 for STABLE
+- use smbfs-2.1 with kernel 2.2.2
+* Sun Feb 28 1999 - ro@suse.de
+- for glibc-2.1 strncat uses strcat for one subcase, so don't
+ redefine strcat to "ERROR" for glibc-2.1
+* Mon Feb 15 1999 - fehr@suse.de
+- fix for umount problem from Volker
+* Tue Feb 09 1999 - fehr@suse.de
+- changed to version 2.0.2 of samba
+* Fri Jan 15 1999 - bs@suse.de
+- replaced /sbin/init.d/smb with newer style version (again)
+* Fri Jan 15 1999 - fehr@suse.de
+- switched to new version 2.0.0
+* Wed Jan 13 1999 - bs@suse.de
+- fixed entry in inetd.conf
+* Wed Jan 13 1999 - bs@suse.de
+- replaced /sbin/init.d/smb with newer style version
+* Mon Jan 11 1999 - vl@suse.de
+- make 2.0.0beta5 package of samba
+* Mon Aug 24 1998 - vl@suse.de
+- changed to version 1.9.18p10
+* Mon Jun 29 1998 - vl@suse.de
+- changed to version 1.9.18p8
+* Mon Apr 20 1998 - vl@suse.de
+- changed to version 1.9.18p4
+* Thu Feb 19 1998 - vl@suse.de
+- changed to version 1.9.18p3
+* Tue Feb 03 1998 - vl@suse.de
+- changed to version 1.9.18p2
+- fixed some problems in spec-file, some files were missing :-(
+- fixed smbfs-2.0.2/Makefile.Linux
+* Tue Jan 13 1998 - vl@suse.de
+- changed to version 1.9.18p1
+* Fri Jan 09 1998 - vl@suse.de
+- changed to version 1.9.18
+* Tue Dec 02 1997 - bs@suse.de
+- disable samba by default in /etc/rc.config
+* Mon Oct 06 1997 - fehr@suse.de
+- package prepared for automatic building
+* Mon Sep 29 1997 - fehr@suse.de
+- updated to version 1.9.17p2 due to security hole.
+* Wed Jul 16 1997 - fehr@suse.de
+- add fillup-template for rc.config and install it in doinst.sh
+* Fri Jun 27 1997 - bs@suse.de
+- update to smbfs-2.0.2, due to security hole.
+* Tue Jun 17 1997 - fehr@suse.de
+- changed init-skript to recognize entry START_SMB of rc.config
+* Mon Jun 02 1997 - vl@suse.de
+- update to version 1.9.16p11
+- Starting Samba from /sbin/init.d, not from inetd.conf
+* Sun Feb 02 1997 - vl@suse.de
+- update to version 1.9.16p10
+- Adapted /etc/smb.conf.sample to 4.4.1 manual
+* Thu Jan 02 1997 - florian@suse.de
+- update to version 1.9.16p9
+- configuration file is now /etc/smb.conf
+- smbd and nmbd are now in /usr/sbin
+- added start-script /sbin/init.d/smb and entry in /etc/rc.config
+* Thu Jan 02 1997 - florian@suse.de
+- Update auf neue Version 1.9.16p6.
diff --git a/packaging/SuSE/8.0/lmhosts b/packaging/SuSE/8.0/lmhosts
new file mode 100755
index 00000000000..edf6a498f21
--- /dev/null
+++ b/packaging/SuSE/8.0/lmhosts
@@ -0,0 +1,7 @@
+# This file provides the same function that the lmhosts file does for
+# Windows. It's another way to map netbios names to ip addresses.
+#
+# Cf. section 'name resolve order' in the manual page of smb.conf for
+# more information.
+
+127.0.0.1 localhost
diff --git a/packaging/SuSE/8.0/rc.smb b/packaging/SuSE/8.0/rc.smb
new file mode 100755
index 00000000000..fa6573caa9f
--- /dev/null
+++ b/packaging/SuSE/8.0/rc.smb
@@ -0,0 +1,130 @@
+#! /bin/sh
+# Copyright (c) 2001 SuSE Gmbh Nueremberg, Germany. All rights reserved.
+#
+# <fedback@suse.de>
+#
+### BEGIN INIT INFO
+# Provides: smb
+# Required-Start: $network $remote_fs syslog
+# Required-Stop:
+# Default-Start: 3 5
+# Default-Stop:
+# Description: initscript for the SAMBA services
+### END INIT INFO
+#
+# init.d/smb
+
+. /etc/rc.config
+
+SMB_BIN=/usr/sbin/smbd
+NMB_BIN=/usr/sbin/nmbd
+SMB_CONF=/etc/samba/smb.conf
+SMB_PID=/var/run/samba/smbd.pid
+NMB_PID=/var/run/samba/nmbd.pid
+
+
+if [ ! -x $SMB_BIN ] ; then
+ echo -n "SMB demon not installed ! "
+ exit 5
+fi
+
+if [ ! -x $NMB_BIN ] ; then
+ echo -n "NMB demon not installed ! "
+ exit 5
+fi
+
+
+# The echo return value for success (defined in /etc/rc.config).
+#return=$rc_done
+
+. /etc/rc.status
+rc_reset
+
+case "$1" in
+ start)
+ if [ -f /usr/share/doc/packages/samba/WARN-cvs-version ]; then
+ echo -en "${warn}"
+ while read warn_message; do
+ echo WARNING ${warn_message}
+ done < /usr/share/doc/packages/samba/WARN-cvs-version
+ echo -en "${norm}"
+
+ read answer
+ if [ "$answer" != "yes" ]; then
+ exit 0
+ fi
+ fi
+ echo -n "Starting SAMBA nmbd"
+ checkproc $NMB_BIN
+ if [ $? -eq 0 ] ; then
+ echo -n " Warning: nmbd already running! "
+ else
+ [ -e $NMB_PID ] && echo -n " Warning: $NMB_PID exists! "
+ fi
+ startproc $NMB_BIN -D
+ rc_status -v
+ echo -n "Starting SAMBA smbd"
+ checkproc $SMB_BIN
+ if [ $? -eq 0 ] ; then
+ echo -n " Warning: smbd already running! "
+ else
+ [ -e $SMB_PID ] && echo -n " Warning: $SMB_PID exists! "
+ fi
+ startproc $SMB_BIN -D
+ rc_status -v
+ ;;
+ stop)
+ echo -n "Shutting down SAMBA nmbd"
+ checkproc $NMB_BIN || echo -n " Warning: nmbd not running! "
+ killproc -TERM $NMB_BIN
+ rc_status -v
+ rm -f $NMB_PID
+ echo -n "Shutting down SAMBA smbd"
+ checkproc $SMB_BIN || echo -n " Warning: smbd not running! "
+ killproc -TERM $SMB_BIN
+ rc_status -v
+ rm -f $SMB_PID
+ ;;
+ try-restart)
+ $0 stop && $0 start
+ rc_status
+ ;;
+ restart)
+ $0 stop
+ $0 start
+ rc_status
+ ;;
+ force-reload)
+ $0 reload
+ rc_status
+ ;;
+ reload)
+ echo -n "Reloading SAMBA nmbd"
+ checkproc $NMB_BIN || echo -n " Warning: nmbd not running! "
+ killproc -HUP $NMB_BIN
+# [ -e $NMB_PID ] && touch -c -m $NMB_PID
+ rc_status -v
+ echo -n "Reloading SAMBA smbd"
+ checkproc $SMB_BIN || echo -n " Warning: smbd not running! "
+ killproc -HUP $SMB_BIN
+# [ -e $SMB_PID ] && touch -c -m $SMB_PID
+ rc_status -v
+ ;;
+ status)
+ echo -n "Checking for SAMBA nmbd"
+ checkproc $NMB_BIN
+ rc_status -v
+ echo -n "Checking for SAMBA smbd"
+ checkproc $SMB_BIN
+ rc_status -v
+ ;;
+ probe)
+ test $SMB_CONF -nt $SMB_PID && echo reload
+ test $SMB_CONF -nt $NMB_PID && echo reload
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
+ exit 1
+ ;;
+esac
+rc_exit
diff --git a/packaging/SuSE/8.0/rc.smbfs b/packaging/SuSE/8.0/rc.smbfs
new file mode 100755
index 00000000000..6c6de927f11
--- /dev/null
+++ b/packaging/SuSE/8.0/rc.smbfs
@@ -0,0 +1,48 @@
+#! /bin/bash
+# Copyright (c) 1996 SuSE GmbH Nuernberg, Germany. All rights reserved.
+#
+# Author: Thomas Fehr <feedback@suse.de>, 1999
+#
+# /etc/init.d/smbfs
+#
+### BEGIN INIT INFO
+# Provides: smbfs
+# Required-Start: $network $remote_fs syslog smb
+# Required-Stop:
+# Default-Start: 2 3 5
+# Default-Stop:
+# Description: initscript for the smbclient
+### END INIT INFO
+
+smbfs=no
+if [ `cat /proc/mounts | grep " smbfs " | wc -l` -gt 0 ]
+then
+ smbfs=yes
+fi
+
+return=$rc_done
+case "$1" in
+ start|reload)
+ ;;
+ stop)
+ if [ "$smbfs" = "yes" ]
+ then
+ echo -n "Remove SMB File System"
+ #
+ # Unmount in background because during long timeouts
+ #
+ umount -at smbfs &
+ sleep 2
+ echo -e "$return"
+ fi
+ ;;
+ restart)
+ $0 stop && $0 start || return=$rc_failed
+ ;;
+ status)
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|reload|restart}"
+ exit 1
+esac
+exit 0
diff --git a/packaging/SuSE/8.0/samba-2.2.3-smbadduser.dif b/packaging/SuSE/8.0/samba-2.2.3-smbadduser.dif
new file mode 100755
index 00000000000..9b6564ca271
--- /dev/null
+++ b/packaging/SuSE/8.0/samba-2.2.3-smbadduser.dif
@@ -0,0 +1,20 @@
+--- source/script/smbadduser
++++ source/script/smbadduser Mon Feb 4 23:13:19 2002
+@@ -1,13 +1,13 @@
+-#!/bin/csh
++#!/bin/bash
+ #
+ # smbadduser - Written by Mike Zakharoff
+ #
+ unalias *
+-set path = ($path /usr/local/samba/bin)
++set path = ($path /usr/bin)
+
+-set smbpasswd = /usr/local/samba/private/smbpasswd
++set smbpasswd = /etc/samba/smbpasswd
+ #set smbpasswd = /etc/samba.d/smbpasswd
+-set user_map = /usr/local/samba/lib/users.map
++set user_map = /etc/samba/smbusers
+ #set user_map = /etc/samba.d/smbusers
+ #
+ # Set to site specific passwd command
diff --git a/packaging/SuSE/8.0/samba-2.2.3-smbsh.dif b/packaging/SuSE/8.0/samba-2.2.3-smbsh.dif
new file mode 100755
index 00000000000..dd647dc4977
--- /dev/null
+++ b/packaging/SuSE/8.0/samba-2.2.3-smbsh.dif
@@ -0,0 +1,11 @@
+--- source/smbwrapper/smbsh.c
++++ source/smbwrapper/smbsh.c Wed Jan 23 12:47:16 2002
+@@ -39,7 +39,7 @@
+ int main(int argc, char *argv[])
+ {
+ char *p, *u;
+- char *libd = BINDIR;
++ char *libd = LIBDIR;
+ pstring line, wd;
+ int opt;
+ extern char *optarg;
diff --git a/packaging/SuSE/8.0/samba-2.2.4-pid_path.diff b/packaging/SuSE/8.0/samba-2.2.4-pid_path.diff
new file mode 100755
index 00000000000..3c04601476a
--- /dev/null
+++ b/packaging/SuSE/8.0/samba-2.2.4-pid_path.diff
@@ -0,0 +1,121 @@
+--- source/include/proto.h
++++ source/include/proto.h Sat Apr 20 22:26:47 2002
+@@ -1889,6 +1889,7 @@
+ char *lp_deleteprinter_cmd(void);
+ char *lp_os2_driver_map(void);
+ char *lp_lockdir(void);
++char *lp_piddir(void);
+ char *lp_utmpdir(void);
+ char *lp_wtmpdir(void);
+ BOOL lp_utmp(void);
+--- source/lib/util.c
++++ source/lib/util.c Sat Apr 20 22:26:47 2002
+@@ -1836,6 +1836,26 @@
+ return fname;
+ }
+
++/*****************************************************************
++a useful function for returning a path in the Samba pid directory
++ *****************************************************************/
++char *pid_path(char *name)
++{
++ static pstring fname;
++
++ pstrcpy(fname,lp_piddir());
++ trim_string(fname,"","/");
++
++ if (!directory_exist(fname,NULL)) {
++ mkdir(fname,0755);
++ }
++
++ pstrcat(fname,"/");
++ pstrcat(fname,name);
++
++ return fname;
++}
++
+ /*******************************************************************
+ Given a filename - get its directory name
+ NB: Returned in static storage. Caveats:
+--- source/param/loadparm.c
++++ source/param/loadparm.c Sat Apr 20 22:26:47 2002
+@@ -108,6 +108,7 @@
+ char *szDeletePrinterCommand;
+ char *szOs2DriverMap;
+ char *szLockDir;
++ char *szPidDir;
+ char *szRootdir;
+ char *szDefaultService;
+ char *szDfree;
+@@ -1024,6 +1025,7 @@
+ {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING},
+ {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
++ {"pid dir", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, 0},
+ #ifdef WITH_UTMP
+ {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
+ {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0},
+@@ -1262,6 +1264,7 @@
+ string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
+ string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
+ string_set(&Globals.szLockDir, LOCKDIR);
++ string_set(&Globals.szPidDir, PIDDIR);
+ #ifdef WITH_UTMP
+ string_set(&Globals.szUtmpDir, "");
+ string_set(&Globals.szWtmpDir, "");
+@@ -1521,6 +1524,7 @@
+ FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
+ FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
+ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
++FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
+ #ifdef WITH_UTMP
+ FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
+ FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
+--- source/utils/testparm.c
++++ source/utils/testparm.c Sat Apr 20 22:26:47 2002
+@@ -72,6 +72,16 @@
+ ret = 1;
+ }
+
++ if (!directory_exist(lp_piddir(), &st)) {
++ printf("ERROR: tdb directory %s does not exist\n",
++ lp_piddir());
++ ret = 1;
++ } else if ((st.st_mode & 0777) != 0755) {
++ printf("WARNING: pid directory %s should have permissions 0755 for browsing to work\n",
++ lp_piddir());
++ ret = 1;
++ }
++
+ /*
+ * Password server sanity checks.
+ */
+--- source/lib/pidfile.c
++++ source/lib/pidfile.c Sat Apr 20 22:26:47 2002
+@@ -37,7 +37,7 @@
+ unsigned ret;
+ pstring pidFile;
+
+- slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
++ slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
+
+ fd = sys_open(pidFile, O_NONBLOCK | O_RDONLY, 0644);
+ if (fd == -1) {
+@@ -70,7 +70,7 @@
+ return 0;
+ }
+
+-/* create a pid file in the lock directory. open it and leave it locked */
++/* create a pid file in the pid directory. open it and leave it locked */
+ void pidfile_create(char *name)
+ {
+ int fd;
+@@ -78,7 +78,7 @@
+ pstring pidFile;
+ pid_t pid;
+
+- slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
++ slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
+
+ pid = pidfile_pid(name);
+ if (pid != 0) {
diff --git a/packaging/SuSE/8.0/samba-2.2.4-vfs_modules.diff b/packaging/SuSE/8.0/samba-2.2.4-vfs_modules.diff
new file mode 100755
index 00000000000..386598a70e6
--- /dev/null
+++ b/packaging/SuSE/8.0/samba-2.2.4-vfs_modules.diff
@@ -0,0 +1,95 @@
+--- examples/VFS/Makefile
++++ examples/VFS/Makefile Tue Apr 23 00:13:11 2002
+@@ -12,7 +12,7 @@
+ SAMBA_INCL = ../../source/include
+ UBIQX_SRC = ../../source/ubiqx
+ SMBWR_SRC = ../../source/smbwrapper
+-CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
++CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -O -D_LARGEFILE64_SOURCE -D_GNU_SOURCE
+ VFS_OBJS = audit.so skel.so recycle.so
+
+ # Default target
+--- examples/VFS/block/block.c
++++ examples/VFS/block/block.c Mon Apr 22 23:34:53 2002
+@@ -47,7 +47,7 @@
+
+
+
+-DIR *block_opendir(struct connection_struct *conn, char *fname);
++DIR *block_opendir(struct connection_struct *conn, const char *fname);
+ int block_connect(struct connection_struct *conn, const char *service, const char *user);
+ void block_disconnect(struct connection_struct *conn);
+
+@@ -138,7 +138,7 @@
+
+
+ #ifndef PARAMCONF
+-#define PARAMCONF "/etc/samba-block.conf"
++#define PARAMCONF "/etc/samba/samba-block.conf"
+ #endif
+
+ extern BOOL pm_process(char *FileName, BOOL (*sfunc)(char *), BOOL(*pfunc)(char * , char *));
+@@ -150,7 +150,7 @@
+ BOOL get_parameter_value(char *param, char *value);
+ BOOL load_param(void);
+ BOOL search(struct stat *stat_buf);
+-BOOL dir_search(char *link, char *dir);
++BOOL dir_search(char *link, const char *dir);
+ BOOL enter_pblock_dir(char *dir);
+
+
+@@ -352,7 +349,7 @@
+ * VFS connect and param file loading
+ */
+
+-int block_connect(struct connection_struct *conn, char *service, char *user)
++int block_connect(struct connection_struct *conn, const char *service, const char *user)
+ {
+ if((load_param()) == FALSE)
+ {
+@@ -403,7 +403,7 @@
+ * VFS opendir
+ */
+
+-DIR *block_opendir(struct connection_struct *conn, char *fname)
++DIR *block_opendir(struct connection_struct *conn, const char *fname)
+ {
+
+ char *dir_name = NULL;
+@@ -459,7 +459,7 @@
+ * Find dir in list to block id the starting point is link from a share
+ */
+
+-BOOL dir_search(char *link, char *dir)
++BOOL dir_search(char *link, const char *dir)
+ {
+ char buf[PATH_MAX +1], *ext_path;
+ int len = 0;
+--- examples/VFS/block/Makefile
++++ examples/VFS/block/Makefile Mon Apr 22 23:50:14 2002
+@@ -12,7 +12,7 @@
+ SAMBA_INCL = ${SAMBA_SRC}/include
+ UBIQX_SRC = ${SAMBA_SRC}/ubiqx
+ SMBWR_SRC = ${SAMBA_SRC}/smbwrapper
+-CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -D_LARGEFILE63_SOURCE -D_GNU_SOURCE -fno-builtin
++CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -fno-builtin
+
+
+ VFS_OBJS = block.so
+--- examples/VFS/block/samba-block.conf.orig Wed May 16 04:13:52 2001
++++ examples/VFS/block/samba-block.conf Mon Apr 22 23:51:55 2002
+@@ -1,3 +1,4 @@
++# This is /etc/samba/samba-block.conf for the block VFS module
+ [ blocked ]
+ mount_point = /
+ mount_point = /boot
+--- examples/VFS/block/smb.conf.orig Wed May 16 04:13:52 2001
++++ examples/VFS/block/smb.conf Mon Apr 22 23:55:11 2002
+@@ -1,6 +1,6 @@
+ [homes]
+ comment = Home Directories
+- vfs object = /usr/local/samba/lib/block.so
++ vfs object = /usr/lib/samba/block.so
+ browseable = yes
+ writable = yes
+
diff --git a/packaging/SuSE/8.0/samba-2.2.4.dif b/packaging/SuSE/8.0/samba-2.2.4.dif
new file mode 100755
index 00000000000..3a97fe84b75
--- /dev/null
+++ b/packaging/SuSE/8.0/samba-2.2.4.dif
@@ -0,0 +1,41 @@
+--- source/Makefile.in
++++ source/Makefile.in Sat Apr 20 22:17:25 2002
+@@ -79,8 +79,8 @@
+ PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" -DTDB_PASSWD_FILE=\"$(TDB_PASSWD_FILE)\"
+ FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DLOGFILEBASE=\"$(LOGFILEBASE)\"
+ FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
+-FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
+-FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\"
++FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" -DVARDIR=\"$(VARDIR)\" -DPIDDIR=\"$(PIDDIR)\"
++FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DLIBDIR=\"$(LIBDIR)\"
+ FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
+ FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS)
+ FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS)
+--- source/aclocal.m4
++++ source/aclocal.m4 Sat Apr 20 22:17:26 2002
+@@ -87,7 +87,7 @@
+
+ dnl Add an #include
+ dnl AC_ADD_INCLUDE(VARIABLE)
+-define(AC_ADD_INCLUDE,
++AC_DEFUN(AC_ADD_INCLUDE,
+ [cat >> confdefs.h <<\EOF
+ [#include] $1
+ EOF
+--- source/configure.in
++++ source/configure.in Sat Apr 20 22:17:26 2002
+@@ -922,9 +922,11 @@
+ AC_MSG_RESULT([$PICFLAGS])
+
+ # try to work out how to produce pic code with this compiler
+-AC_PROG_CC_FLAG(fpic)
+-if test $ac_cv_prog_cc_fpic = yes; then
+- PICFLAG="-fpic";
++if test x$PICFLAG = x; then
++ AC_PROG_CC_FLAG(fpic)
++ if test $ac_cv_prog_cc_fpic = yes; then
++ PICFLAG="-fpic";
++ fi
+ fi
+ if test x$PICFLAG = x; then
+ AC_PROG_CC_FLAG(KPIC)
diff --git a/packaging/SuSE/8.0/samba.pamd b/packaging/SuSE/8.0/samba.pamd
new file mode 100755
index 00000000000..b699a38d873
--- /dev/null
+++ b/packaging/SuSE/8.0/samba.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+auth required pam_unix.so
+account required pam_unix.so
diff --git a/packaging/SuSE/8.0/samba.spec b/packaging/SuSE/8.0/samba.spec
new file mode 100755
index 00000000000..37a3aeb9e24
--- /dev/null
+++ b/packaging/SuSE/8.0/samba.spec
@@ -0,0 +1,696 @@
+#
+# spec file for package samba (Version 2.2.3a.200204230937cvs)
+#
+# Copyright (c) 2002 SuSE Linux AG, Nuernberg, Germany.
+# This file and all modifications and additions to the pristine
+# package are under the same license as the package itself.
+#
+# please send bugfixes or comments to feedback@suse.de.
+#
+
+# neededforbuild automake cups-devel cups-libs cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi des openldap2 openldap2-client openldap2-devel openssl openssl-devel popt readline readline-devel
+# usedforbuild aaa_base aaa_dir aaa_version autoconf automake base bash bindutil binutils bison bzip compat cpio cpp cracklib cups-devel cups-libs cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi db des devs diffutils e2fsprogs file fileutils findutils flex gawk gcc gdbm gdbm-devel gettext glibc glibc-devel glibc-locale gpm grep groff gzip heimdal-lib kbd less libgcc libstdc++ libtool libxcrypt libz m4 make man mktemp modutils ncurses ncurses-devel net-tools netcfg openldap2 openldap2-client openldap2-devel openssl openssl-devel pam pam-devel pam-modules patch perl popt ps rcs readline readline-devel rpm sendmail sh-utils shadow strace syslogd sysvinit texinfo textutils timezone unzip util-linux vim
+
+Name: samba
+Version: PVERSION
+Release: PRELEASE
+License: 1992-95 Andrew Tridgell, Karl Auer, Jeremy Allison
+Group: Productivity/Networking/Samba
+Url: http://www.samba.org
+Provides: smbfs
+Autoreqprov: on
+Requires: samba-client = %{version}
+Summary: An SMB file server for Unix
+Source: ftp://ftp.samba.org/pub/samba/%{name}-%{version}.tar.bz2
+Source1: samba.pamd
+Source10: lmhosts
+Source13: rc.smb
+Source14: rc.smbfs
+Source15: smb.conf
+Source16: smbpasswd
+Source17: smbusers
+#Patch: samba-%{version}.dif
+Patch: samba-2.2.4.dif
+Patch1: samba-2.2.4-pid_path.diff
+Patch2: samba-2.2.4-vfs_modules.diff
+Patch3: samba-2.2.3-smbadduser.dif
+Patch4: samba-2.2.3-smbsh.dif
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+%define ETCSMBDIR /%{_sysconfdir}/samba
+%define LIBDIR %{_libdir}/samba
+%define DOCDIR %{_defaultdocdir}/%{name}
+%define SHAREDIR %{_datadir}/samba
+%define CODEPAGEDIR %{SHAREDIR}/codepages
+%define SWATDIR %{SHAREDIR}/swat
+%define LOCKDIR /%{_localstatedir}/lib/samba
+%define LOGDIR /%{_localstatedir}/log/samba
+%define PIDDIR /%{_localstatedir}/run/samba
+%define INITDIR %(if [ -x /sbin/insserv ]; then echo -n etc ; else echo -n sbin; fi)/init.d
+
+%description
+Samba is a suite of programs which work together to allow clients to access Unix filespace and printers via the SMB protocol (Server Message Block).
+
+In practice, this means that you can redirect disks and printers to
+Unix disks and printers from LAN Manager clients, Windows for
+Workgroups 3.11 clients, Windows'95 clients, Windows NT clients
+and OS/2 clients. There is also a Unix client program supplied as part of the suite which allows Unix users to use an ftp-like interface to access filespace and printers on any other SMB server.
+
+Samba includes the following programs (in summary):
+
+* smbd, the SMB server. This handles actual connections from clients.
+
+* nmbd, the Netbios name server, which helps clients locate servers.
+
+* smbclient, the Unix-hosted client program.
+
+* smbrun, a little 'glue' program to help the server run external programs.
+
+* testprns, a program to test server access to printers.
+
+* testparm, a program to test the Samba configuration file for correctness.
+
+* smb.conf, the Samba configuration file.
+
+* smbprint, a sample script to allow a Unix host to use smbclient
+ to print to an SMB server.
+
+The suite is supplied with full source and is GPLed.
+
+This package expects its config file under /etc/samba/smb.conf.
+
+Authors:
+--------
+ Andrew Tridgell <Andrew.Tridgell@anu.edu.au>
+ Karl Auer <Karl.Auer@anu.edu.au>
+ Jeremy Allison <jeremy@netcom.com>
+
+SuSE series: n
+
+%package client
+Summary: Samba client utilities
+Autoreqprov: on
+Group: Productivity/Networking/Samba
+Provides: smbclnt
+Obsoletes: smbclnt
+
+%description client
+This package contains all programs, that are needed to act as a samba
+client. This includes also smbmount, of course.
+
+Authors:
+--------
+ Andrew Tridgell <Andrew.Tridgell@anu.edu.au>
+ Karl Auer <Karl.Auer@anu.edu.au>
+ Jeremy Allison <jeremy@netcom.com>
+
+SuSE series: n
+
+%prep
+%setup
+%patch
+%patch1
+%patch2
+%patch3
+%patch4
+echo %{version} | grep cvs &&
+ echo "#define VERSION \"%{version}\"" > source/include/version.h
+
+%build
+cd source
+%{?suse_update_config:%{suse_update_config -f}}
+autoconf
+# -O Means: Don't do inlining(cancels O2 from OPT_FLAGS), bins are big enough
+CFLAGS="$RPM_OPT_FLAGS -Wall -O -D_GNU_SOURCE -D_LARGEFILE64_SOURCE" \
+./configure \
+ --prefix=%{_prefix} \
+ --libdir=%{LIBDIR} \
+ --localstatedir=%{LOCKDIR} \
+ --mandir=%{_mandir} \
+ --sbindir=%{_sbindir} \
+ --with-codepagedir=%{CODEPAGEDIR} \
+ --with-privatedir=%{ETCSMBDIR} \
+ --with-configdir=%{ETCSMBDIR} \
+ --with-swatdir=%{SWATDIR} \
+ --with-sambabook=%{DOCDIR}/htmldocs/using_samba \
+ --with-lockdir=%{LOCKDIR} \
+ --with-automount \
+ --with-smbmount \
+ --with-smbwrapper \
+ --with-pam \
+ --with-pam_smbpass \
+ --with-syslog \
+ --with-profiling-data \
+ --with-quotas \
+ --with-utmp \
+ --with-msdfs \
+ --with-vfs \
+ --with-libsmbclient \
+ --with-acl-support \
+ --with-winbind
+make \
+ LOGFILEBASE=%{LOGDIR} \
+ PASSWDPROG=/%{_bindir}/passwd \
+ PIDDIR=%{PIDDIR}
+make nsswitch
+make nsswitch/libnss_wins.so
+( cd ../example/VFS; ./configure --prefix=%{_prefix} --libdir=%{LIBDIR} --sbindir=%{_sbindir} )
+make -C ../examples/VFS
+make -C ../examples/VFS/block
+
+%install
+[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT
+cd source/
+mkdir -p \
+ $RPM_BUILD_ROOT/%{_bindir} \
+ $RPM_BUILD_ROOT/sbin \
+ $RPM_BUILD_ROOT/%{_sbindir} \
+ $RPM_BUILD_ROOT/%{ETCSMBDIR} \
+ $RPM_BUILD_ROOT/%{INITDIR} \
+ $RPM_BUILD_ROOT/%{LIBDIR} \
+ $RPM_BUILD_ROOT/%{_includedir} \
+ $RPM_BUILD_ROOT/%{_lib}/security \
+ $RPM_BUILD_ROOT/%{_mandir} \
+ $RPM_BUILD_ROOT/%{CODEPAGEDIR} \
+ $RPM_BUILD_ROOT/%{SHAREDIR}/script \
+ $RPM_BUILD_ROOT/%{DOCDIR} \
+ $RPM_BUILD_ROOT/%{LOCKDIR} \
+ $RPM_BUILD_ROOT/%{SWATDIR} \
+ $RPM_BUILD_ROOT/%{LOGDIR} \
+ $RPM_BUILD_ROOT/%{PIDDIR} \
+ $RPM_BUILD_ROOT/%{_localstatedir}/spool/samba
+
+make \
+ BASEDIR=$RPM_BUILD_ROOT/%{_prefix} \
+ BINDIR=$RPM_BUILD_ROOT/%{_bindir} \
+ SBINDIR=$RPM_BUILD_ROOT/%{_sbindir} \
+ LIBDIR=$RPM_BUILD_ROOT/%{LIBDIR} \
+ MANDIR=$RPM_BUILD_ROOT/%{_mandir} \
+ CODEPAGEDIR=$RPM_BUILD_ROOT/%{CODEPAGEDIR} \
+ LOCKDIR=$RPM_BUILD_ROOT/%{LOCKDIR} \
+ SWATDIR=$RPM_BUILD_ROOT/%{SWATDIR} \
+ install
+# smbadduser
+install -m 755 script/smbadduser $RPM_BUILD_ROOT/%{_bindir}/smbadduser
+# call smbmount as mount.smbfs
+ln -sf %{_bindir}/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+# smbpass pam support
+install -m 755 bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security
+# wins support for NSS
+install -m 755 nsswitch/libnss_wins.so $RPM_BUILD_ROOT/%{_lib}/libnss_wins.so.2
+# winbind and shared libraries
+install -m 755 nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/%{_lib}/libnss_winbind.so.2
+install -m 755 nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security
+# libsmbclient
+install -m 644 include/libsmbclient.h $RPM_BUILD_ROOT/%{_includedir}
+install -m 644 bin/libsmbclient.a $RPM_BUILD_ROOT/%{_libdir}
+install -m 755 bin/libsmbclient.so $RPM_BUILD_ROOT/%{_libdir}
+# smbwrapper lib
+install -m 755 bin/smbwrapper.so $RPM_BUILD_ROOT/%{_libdir}/samba
+# doc
+mv msdfs/README $RPM_BUILD_ROOT/%{DOCDIR}/README.msdfs
+mv nsswitch/README $RPM_BUILD_ROOT/%{DOCDIR}/README.nsswitch
+mv smbwrapper/README $RPM_BUILD_ROOT/%{DOCDIR}/README.smbwrapper
+mkdir $RPM_BUILD_ROOT/%{DOCDIR}/pam_smbpass
+mv pam_smbpass/README $RPM_BUILD_ROOT/%{DOCDIR}/pam_smbpass
+mv pam_smbpass/samples $RPM_BUILD_ROOT/%{DOCDIR}/pam_smbpass
+# utility scripts
+cd script
+install -m 755 convert_smbpasswd $RPM_BUILD_ROOT/%{SHAREDIR}/script
+install -m 755 mknissmbp* $RPM_BUILD_ROOT/%{SHAREDIR}/script
+install -m 755 mksmbpasswd.sh $RPM_BUILD_ROOT/%{SHAREDIR}/script
+cd ../..
+# findsmb
+install -m 755 packaging/RedHat/findsmb $RPM_BUILD_ROOT/%{_bindir}/findsmb
+# VFS libs
+for module in $( find examples/VFS/ -name *.so); do
+ install -m 755 "${module}" $RPM_BUILD_ROOT/%{LIBDIR}/
+ rm "${module}"
+done
+# Remove superfluous files
+for fn in Makefile *.c *.o .libs; do
+ find examples/VFS/ -iname $fn -print0 | xargs -0 rm -rf
+done
+# Cleanup docs
+rm -rf \
+ docs/{docbook,manpages,yodldocs} \
+ docs/faq/*{sgml,txt} \
+ docs/htmldocs/*.[0-9].html \
+ $RPM_BUILD_ROOT/%{SWATDIR}/using_samba
+find docs examples -type d -print0 | xargs -0 chmod 755
+find docs examples -type f -print0 | xargs -0 chmod 644
+# doc
+mv docs/* examples COPYING Manifest README Roadmap WHATSNEW.txt $RPM_BUILD_ROOT/%{DOCDIR}
+
+# configuration files
+install -m 644 $RPM_SOURCE_DIR/smb.conf $RPM_BUILD_ROOT/%{ETCSMBDIR}/
+install -m 644 $RPM_SOURCE_DIR/lmhosts $RPM_BUILD_ROOT/%{ETCSMBDIR}/
+install -m 600 $RPM_SOURCE_DIR/smbpasswd $RPM_BUILD_ROOT/%{ETCSMBDIR}/
+install -m 644 $RPM_SOURCE_DIR/smbusers $RPM_BUILD_ROOT/%{ETCSMBDIR}/
+install -D -m 644 $RPM_SOURCE_DIR/samba.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/samba
+# start script
+install -m 744 $RPM_SOURCE_DIR/rc.smb $RPM_BUILD_ROOT/%{INITDIR}/smb
+ln -sf ../../%{INITDIR}/smb $RPM_BUILD_ROOT/%{_sbindir}/rcsmb
+ln -sf ../../%{INITDIR}/smb $RPM_BUILD_ROOT/%{_sbindir}/rcsamba
+install -m 744 $RPM_SOURCE_DIR/rc.smbfs $RPM_BUILD_ROOT/%{INITDIR}/smbfs
+ln -sf ../../%{INITDIR}/smbfs $RPM_BUILD_ROOT/%{_sbindir}/rcsmbfs
+# create netlogon and profiles directories
+mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/lib/samba/{netlogon,profiles}
+# let ldconfig create symlinks
+ldconfig -n $RPM_BUILD_ROOT/%{_libdir}
+
+%post
+# Are we in update mode?
+if [ $1 -gt 1 ]; then
+ rm -f $( find tmp/.*.EtCmV -size 0 2> /dev/null)
+ for fn in lmhosts smb.conf smbpasswd; do
+ if [ -e etc/$fn -a ! -L etc/$fn ]; then
+ if [ ! -e tmp/.samba.EtCmV ]; then
+ echo "Copying samba config files to new location /etc/samba/:"
+ touch tmp/.samba.EtCmV
+ fi
+ echo $fn
+ if [ -f etc/samba/$fn ]; then
+ diff etc/$fn etc/samba/$fn >/dev/null ||
+ mv etc/samba/$fn etc/samba/$fn.rpmpost
+ fi
+ cp -a etc/$fn etc/samba/$fn
+ touch tmp/.$fn.EtCmV
+ fi
+ done
+ rm -f $( find tmp/.samba.EtCmV -size 0 2> /dev/null)
+ for fn in $( find etc/*.SID 2> /dev/null) secrets.tdb; do
+ fn=$( basename $fn)
+ if [ -e etc/$fn -a ! -L etc/$fn -a ! -e etc/samba/$fn ]; then
+ if [ ! -e tmp/.samba.EtCmV ]; then
+ echo "Copying samba SID and secret files to new location /etc/samba/:"
+ touch tmp/.samba.EtCmV
+ fi
+ echo $fn
+ cp -a etc/$fn etc/samba/$fn
+ fi
+ done
+ rm -f $( find tmp/.samba.EtCmV -size 0 2> /dev/null)
+fi
+mkdir -p var/adm/notify/messages
+cat << EOF > var/adm/notify/messages/samba-notify
+Hallo, (english text below)
+
+die Konfigurationsdateien, lmhosts, smb.conf und smbpasswd, liegen jetzt
+in /etc/samba. Bei einem Update wird die alte Konfiguration dorthin
+kopiert. Insoweit die Dateien angepasst wurden, finden sich in /etc
+Sicherungskopien mit der Endung .rpmsave. Die mitgelieferten neuen
+Beispieldateien werden gegebenenfalls mit der Endung .rpmpost oder
+.rpmnew gesichert.
+
+
+Hello,
+
+the configuration files, lmhosts, smb.conf und smbpasswd, are now
+located in /etc/samba. While an update the old configuration will be
+copied here. If you made changes to these files, also backups with
+endings .rpmsave are left in /etc. The new example configuration files
+are stored with the ending .rpmpost or .rpmnew if necessary.
+
+Have a lot of fun...
+ Your SuSE Team
+EOF
+# ---------------------------------------------------------------------------
+#
+# Initialize runlevel links and take care of old START_SMB
+#
+%{fillup_and_insserv smb}
+
+%postun
+%{insserv_cleanup}
+
+%post client
+# check and copy old or old.rpmsave configuration files
+function ckandcp()
+{
+ if [ ! -e tmp/.samba-client.EtCmV ]; then
+ echo "Copying samba-client config files to new location /etc/samba/:"
+ touch tmp/.samba-client.EtCmV
+ fi
+ echo "$fn"
+ if [ -f etc/samba/$fn ]; then
+ diff etc/$1 etc/samba/$fn >/dev/null ||
+ mv etc/samba/$fn etc/samba/$fn.rpmpost
+ fi
+ cp -a etc/$1 etc/samba/$fn
+}
+for fn in lmhosts smb.conf; do
+ if [ -e etc/$fn -a ! -L etc/$fn ]; then
+ ckandcp $fn
+ elif [ -e tmp/.$fn.EtCmV -a -e etc/$fn.rpmsave -a ! -L etc/$fn.rpmsave ]; then
+ ckandcp $fn.rpmsave
+ fi
+done
+rm -f $( find tmp/.*.EtCmV -size 0 2> /dev/null)
+# never had a start-variable, no fillup magic needed
+%{fillup_and_insserv -fpy smbfs}
+
+%postun client
+%{insserv_cleanup}
+
+%files
+%config /%{_sysconfdir}/pam.d/samba
+%config /%{_sysconfdir}/init.d/smb
+%config(noreplace) /%{ETCSMBDIR}/smbpasswd
+%config(noreplace) /%{ETCSMBDIR}/smbusers
+%{_bindir}/make_printerdef
+%{_bindir}/make_smbcodepage
+%{_bindir}/make_unicodemap
+# build without --ldapsam
+#%{_bindir}/pdbedit
+%{_bindir}/smbadduser
+%{_bindir}/smbstatus
+%{_bindir}/tdbbackup
+%{_bindir}/testprns
+%{_sbindir}/nmbd
+%{_sbindir}/rcsmb
+%{_sbindir}/rcsamba
+%{_sbindir}/smbd
+%{_sbindir}/swat
+/%{_lib}/security/pam_smbpass.so
+%{LIBDIR}
+%dir %{SHAREDIR}
+%{SHAREDIR}/script
+%{SWATDIR}
+%doc %{_mandir}/man1/make_smbcodepage.1.gz
+%doc %{_mandir}/man1/make_unicodemap.1.gz
+%doc %{_mandir}/man1/smbsh.1.gz
+%doc %{_mandir}/man1/smbstatus.1.gz
+%doc %{_mandir}/man1/testprns.1.gz
+%doc %{_mandir}/man5/smbpasswd.5.gz
+%doc %{_mandir}/man7/samba.7.gz
+%doc %{_mandir}/man8/nmbd.8.gz
+%doc %{_mandir}/man8/smbd.8.gz
+%doc %{_mandir}/man8/swat.8.gz
+%dir /%{_localstatedir}/lib/samba/netlogon
+%attr(770,root,users) %dir /%{_localstatedir}/lib/samba/profiles
+%attr(750,lp,lp) %dir /%{_localstatedir}/spool/samba
+%dir %{LOCKDIR}
+%attr(750,root,root) %dir %{LOGDIR}
+%dir %{PIDDIR}
+
+%files client
+%dir %{ETCSMBDIR}
+%config(noreplace) /%{ETCSMBDIR}/smb.conf
+%config(noreplace) /%{ETCSMBDIR}/lmhosts
+%config /%{_sysconfdir}/init.d/smbfs
+%{_bindir}/findsmb
+%{_bindir}/nmblookup
+%{_bindir}/rpcclient
+%{_bindir}/smbcacls
+%{_bindir}/smbclient
+%{_bindir}/smbcontrol
+%{_bindir}/smbmnt
+%{_bindir}/smbmount
+%{_bindir}/smbpasswd
+%{_bindir}/smbsh
+%{_bindir}/smbumount
+%{_bindir}/smbspool
+%{_bindir}/smbtar
+%{_bindir}/testparm
+%{_bindir}/wbinfo
+%{_sbindir}/rcsmbfs
+%{_sbindir}/winbindd
+/sbin/mount.smbfs
+%{CODEPAGEDIR}
+/%{_lib}/libnss_wins.so.2
+/%{_lib}/libnss_winbind.so.2
+/%{_lib}/security/pam_winbind.so
+%{_includedir}/libsmbclient.h
+%{_libdir}/libsmbclient.a
+%{_libdir}/libsmbclient.so
+%{_libdir}/libsmbclient.so.0
+%{_libdir}/samba/smbwrapper.so
+%doc %{_mandir}/man1/findsmb.1.gz
+%doc %{_mandir}/man1/nmblookup.1.gz
+%doc %{_mandir}/man1/rpcclient.1.gz
+%doc %{_mandir}/man1/smbcacls.1.gz
+%doc %{_mandir}/man1/smbclient.1.gz
+%doc %{_mandir}/man1/smbcontrol.1.gz
+%doc %{_mandir}/man1/testparm.1.gz
+%doc %{_mandir}/man1/wbinfo.1.gz
+%doc %{_mandir}/man1/smbtar.1.gz
+%doc %{_mandir}/man5/lmhosts.5.gz
+%doc %{_mandir}/man5/smb.conf.5.gz
+%doc %{_mandir}/man8/smbmnt.8.gz
+%doc %{_mandir}/man8/smbmount.8.gz
+%doc %{_mandir}/man8/smbpasswd.8.gz
+%doc %{_mandir}/man8/smbspool.8.gz
+%doc %{_mandir}/man8/smbumount.8.gz
+%doc %{_mandir}/man8/winbindd.8.gz
+%docdir %{DOCDIR}
+%{DOCDIR}
+
+%changelog -n samba
+* Fri Mar 08 2002 - kukuk@suse.de
+- Add libsmbclient.so.0 and /usr/share/samba to filelist
+* Thu Feb 14 2002 - adrian@suse.de
+- install needed header file for libsmbclient.so
+* Sun Feb 10 2002 - kukuk@suse.de
+- Don't test for -fpic if PICFLAG is already set
+* Thu Feb 07 2002 - lmuelle@suse.de
+- Update to 2.2.3a, minor bugfix release
+* Thu Feb 07 2002 - lmuelle@suse.de
+- Update to 2.2.3
+- Fix smbsh library search path
+- Removed 'kernel oplocks = No' from smb.conf; default is yes
+- Include pam_smbpass, syslog, utmp, and winbind support
+- Include libsmbclient
+- Include findsmb
+* Tue Jan 08 2002 - egmont@suselinux.hu
+- Cosmetical changes in init scripts
+* Thu Dec 20 2001 - ro@suse.de
+- removed START_SMB and added insserv_macros
+* Sun Sep 23 2001 - lmuelle@suse.de
+- Shorten output and tunig of old configuration files handling
+- Include SID and secrets files to old configuration files handling
+- Move netlogon and profiles directories to /var/lib/samba
+- Move smbpasswd binary and man page to samba-client package
+- Introduce additional sym link from /etc/init.d/smb to rcsamba due to
+ too many typos and cleaner systematic
+- Add character set = ISO8859-15 and client code page = 850 to smb.conf
+ in the global section to enable correct UNIX <-> DOS character
+ mapping for west European languages
+- Change create mask of home section to 0640, directory mask to 0750;
+ change create mask of printers section to 0600 in smb.conf
+- Move path of printers section to /var/tmp
+* Fri Aug 24 2001 - lmuelle@suse.de
+- Move all configuration files to /etc/samba
+- Move data bases to /var/lib/samba; important, cause boot script
+ cleans up /var/lock/samba
+- Move pid files to /var/run/samba
+- Link against cups library
+- Use build root
+- Rename subpackage smbclnt to samba-client
+- Move /usr/share/doc/packages/samba to package samba-client
+- Move /usr/lib/samba/scripts to /usr/share/samba/scripts
+- Move /usr/lib/samba/codepages to /usr/share/samba/codepages
+- Move /usr/lib/samba/swat to /usr/share/samba/swat
+- Move /usr/lib/samba/VFS/* to /usr/lib/samba
+- Remove smb.conf from package samba, kept in samba-client
+- Remove redundant html documentation of man pages
+- Remove superfluous install and uninstall scripts
+- Add example configuration file /etc/samba/smbusers
+- Update to 2.2.1a: fixes bug with too strict name handling while adding
+ a machine into a domain
+- Update to 2.2.1: add pam password changing and pam restrictions code;
+ printer driver management improvements (delete driver); fix for Samba
+ running on top of Linux VFAT ftruncate bug
+* Tue Aug 14 2001 - ro@suse.de
+- Don't use absolute paths to PAM modules in PAM config files
+* Wed Jun 27 2001 - ro@suse.de
+- re-added the libtoolize to make it build
+* Tue Jun 26 2001 - lmuelle@suse.de
+- Update to 2.2.0a fixes remote file create/ append bug. This may
+ only happen by '%%m' macro usage for the 'log file' command.
+- spec and dif cleanup
+- Include VFS module support.
+* Wed Jun 13 2001 - ro@suse.de
+- fix to build with new autoconf
+* Wed May 30 2001 - ro@suse.de
+- config-dist.sh: accept any kernel version on s390
+* Thu May 10 2001 - bodammer@suse.de
+- initscript fix: don't start smbd in runlevel 2 [bug #8046]
+- some additional files included to doc (COPYING, README, ..)
+* Wed May 09 2001 - uli@suse.de
+- bzipped tarball
+* Tue May 08 2001 - schwab@suse.de
+- Don't use _syscallX.
+* Mon Apr 30 2001 - ro@suse.de
+- added config-dist.sh to build only on 2.4 machines
+ (samba configure seems braindead enough to check
+ the running kernel)
+* Mon Apr 30 2001 - ro@suse.de
+- removed kerberos support: does not work as expected
+* Tue Apr 24 2001 - lemsi@suse.de
+- for 7.2 we have added some kerbereos 5 support
+* Tue Apr 24 2001 - lemsi@suse.de
+- new version samba 2.2
+- new spec file with more functions for configure
+- libnss_winbind.so support for /etc/nsswich.conf
+* Wed Apr 18 2001 - lemsi@suse.de
+- new security fixes and version 2.0.8 for 6.3, 6.4, 7.0, 7.1
+* Tue Apr 17 2001 - lemsi@suse.de
+- new rcsmb script
+- include security fixes
+* Fri Mar 09 2001 - ro@suse.de
+- don't mess with os_install_post
+* Fri Feb 23 2001 - ro@suse.de
+- added readline/readline-devel to neededforbuild (split from bash)
+* Wed Feb 07 2001 - schwab@suse.de
+- Fix LFS support in client.
+* Mon Feb 05 2001 - schwab@suse.de
+- Compile with -D_GNU_SOURCE and -D_LARGEFILE64_SOURCE to get missing
+ declarations.
+- Include <sys/types.h> when checking for ino64_t.
+- Include <crypt.h> for crypt declaration.
+* Wed Jan 31 2001 - lemsi@suse.de
+- added codepages in smbclnt-subpackage
+- changed german coments to english coments
+* Wed Jan 03 2001 - lemsi@suse.de
+- changed in the share section the path /cd to /cdrom
+- added smb.conf to the smbclnt-subpackage
+* Tue Nov 28 2000 - kukuk@suse.de
+- Fix init scripts and move them to /etc/init.d
+- Fix post/postun section for subpackages
+* Fri Nov 24 2000 - bodammer@suse.de
+- rcscript update
+* Mon Aug 28 2000 - choeger@suse.de
+- changed $* to "$@" in mount.smbfs to make it also
+ possible to mount shares with spaces
+* Mon Jul 31 2000 - choeger@suse.de
+- improvement for rcsmb
+- fix for spec-file to compile with NIS netgroups
+* Thu Jul 20 2000 - choeger@suse.de
+- added smbfs initscript that has been removed
+ by an error
+* Tue Jul 11 2000 - choeger@suse.de
+- split package into client and server parts
+ client package name: smbclnt
+* Wed Apr 26 2000 - choeger@suse.de
+- new version, 2.0.7
+* Thu Apr 06 2000 - ro@suse.de
+- removed pam,cracklib from neededforbuild: build handles this
+* Wed Apr 05 2000 - bk@suse.de
+- s390 team added config.{sub,guess} update macro for s390
+* Mon Mar 27 2000 - choeger@suse.de
+- fixed bug in specfile
+ the multilined configure call missed a "\" :-(
+* Thu Mar 09 2000 - choeger@suse.de
+- fixed typo in specfile
+* Wed Mar 01 2000 - choeger@suse.de
+- added %%{_mandir}
+* Tue Feb 08 2000 - choeger@suse.de
+- removed /sbin/init.d/smbfs because it is no longer needed
+* Mon Jan 03 2000 - choeger@suse.de
+- bugfix for ipc.c
+ to make roaming profiles work again.
+* Tue Nov 30 1999 - choeger@suse.de
+- changed kernel oplocks = off to
+ kernel oplocks = false
+* Tue Nov 16 1999 - choeger@suse.de
+- added kernel oplocks = off in smb.conf
+* Fri Nov 12 1999 - choeger@suse.de
+- new version, 2.0.6
+* Fri Nov 05 1999 - choeger@suse.de
+- Fix for the smbmount lost-connection problem
+ _seems_ to work...
+* Fri Oct 29 1999 - choeger@suse.de
+- removed comment sign in /etc/inetd.conf for swat
+* Mon Sep 13 1999 - bs@suse.de
+- ran old prepare_spec on spec file to switch to new prepare_spec.
+* Tue Aug 10 1999 - fehr@suse.de
+- set execute permissions for mksmbpasswd.sh and changesmbpasswd.sh
+* Thu Jul 29 1999 - fehr@suse.de
+- fixed typo in /sbin/init.d/smbfs
+* Thu Jul 22 1999 - fehr@suse.de
+- changed to new version 2.0.5a
+* Wed Jul 21 1999 - fehr@suse.de
+- changed to new version 2.0.5
+* Tue Jul 20 1999 - fehr@suse.de
+- install /sbin/init.d/smbfs
+- changed to new version 2.0.5pre4
+* Mon Jul 19 1999 - fehr@suse.de
+- add /sbin/init.d/smbfs
+- changed to new version 2.0.5pre3
+* Fri Jul 02 1999 - fehr@suse.de
+- removed "umount -a -t smbfs" from start sscript
+* Tue Jun 22 1999 - kukuk@suse.de
+- 2.0.4b changed default values, enable PAM again
+* Fri Jun 18 1999 - kukuk@suse.de
+- changed to new version 2.0.4b
+* Mon Jun 14 1999 - kukuk@suse.de
+- Enable PAM, add samba.pamd
+* Mon May 03 1999 - fehr@suse.de
+- add umount -a -t smbfs to shutdown sequence of samba
+* Thu Mar 11 1999 - ro@suse.de
+- smbmount: define NR_OPEN to 1024 if undefined (GLIBC-2.1)
+* Wed Mar 10 1999 - choeger@suse.de
+- some enhancements for smb.conf
+* Wed Mar 10 1999 - choeger@suse.de
+- new version 2.0.3 and smbmount now seems to work
+* Tue Mar 09 1999 - ro@suse.de
+- use samba-2.0.2 for STABLE
+- use smbfs-2.1 with kernel 2.2.2
+* Sun Feb 28 1999 - ro@suse.de
+- for glibc-2.1 strncat uses strcat for one subcase, so don't
+ redefine strcat to "ERROR" for glibc-2.1
+* Mon Feb 15 1999 - fehr@suse.de
+- fix for umount problem from Volker
+* Tue Feb 09 1999 - fehr@suse.de
+- changed to version 2.0.2 of samba
+* Fri Jan 15 1999 - bs@suse.de
+- replaced /sbin/init.d/smb with newer style version (again)
+* Fri Jan 15 1999 - fehr@suse.de
+- switched to new version 2.0.0
+* Wed Jan 13 1999 - bs@suse.de
+- fixed entry in inetd.conf
+* Wed Jan 13 1999 - bs@suse.de
+- replaced /sbin/init.d/smb with newer style version
+* Mon Jan 11 1999 - vl@suse.de
+- make 2.0.0beta5 package of samba
+* Mon Aug 24 1998 - vl@suse.de
+- changed to version 1.9.18p10
+* Mon Jun 29 1998 - vl@suse.de
+- changed to version 1.9.18p8
+* Mon Apr 20 1998 - vl@suse.de
+- changed to version 1.9.18p4
+* Thu Feb 19 1998 - vl@suse.de
+- changed to version 1.9.18p3
+* Tue Feb 03 1998 - vl@suse.de
+- changed to version 1.9.18p2
+- fixed some problems in spec-file, some files were missing :-(
+- fixed smbfs-2.0.2/Makefile.Linux
+* Tue Jan 13 1998 - vl@suse.de
+- changed to version 1.9.18p1
+* Fri Jan 09 1998 - vl@suse.de
+- changed to version 1.9.18
+* Tue Dec 02 1997 - bs@suse.de
+- disable samba by default in /etc/rc.config
+* Mon Oct 06 1997 - fehr@suse.de
+- package prepared for automatic building
+* Mon Sep 29 1997 - fehr@suse.de
+- updated to version 1.9.17p2 due to security hole.
+* Wed Jul 16 1997 - fehr@suse.de
+- add fillup-template for rc.config and install it in doinst.sh
+* Fri Jun 27 1997 - bs@suse.de
+- update to smbfs-2.0.2, due to security hole.
+* Tue Jun 17 1997 - fehr@suse.de
+- changed init-skript to recognize entry START_SMB of rc.config
+* Mon Jun 02 1997 - vl@suse.de
+- update to version 1.9.16p11
+- Starting Samba from /sbin/init.d, not from inetd.conf
+* Sun Feb 02 1997 - vl@suse.de
+- update to version 1.9.16p10
+- Adapted /etc/smb.conf.sample to 4.4.1 manual
+* Thu Jan 02 1997 - florian@suse.de
+- update to version 1.9.16p9
+- configuration file is now /etc/smb.conf
+- smbd and nmbd are now in /usr/sbin
+- added start-script /sbin/init.d/smb and entry in /etc/rc.config
+* Thu Jan 02 1997 - florian@suse.de
+- Update auf neue Version 1.9.16p6.
diff --git a/packaging/SuSE/8.0/smb.conf b/packaging/SuSE/8.0/smb.conf
new file mode 100755
index 00000000000..a6018253ee0
--- /dev/null
+++ b/packaging/SuSE/8.0/smb.conf
@@ -0,0 +1,120 @@
+#
+# /etc/samba/smb.conf ist the main samba configuration file. Cf. the
+# manual page of smb.conf and the included documantation in
+# /usr/share/doc/packages/samba in order to understand the options
+# listed here and many more features.
+#
+# Lines in this example which starts with ; and # are ignored comment
+# ones. # indicates a comment and ; a deactivated example line.
+#
+# We suggest to use the command 'testparm' after any changes you made.
+#
+# Copyright (c) 1999 - 2001 SuSE GmbH Nuernberg, Germany.
+#
+# Please send bugfixes or comments to feedback@suse.de.
+#
+[global]
+ workgroup = TUX-NET
+ os level = 2
+
+ security = user
+ encrypt passwords = Yes
+ guest account = Nobody
+ map to guest = Bad User
+# This tells samba to use the file smbusers for user mapping.
+; username map = /etc/samba/smbusers
+
+# This tells samba to write log files per machine.
+; log file = /var/log/samba/%m
+# This sets an alternate log level. Default is 2.
+; log level = 3
+
+# Uncomment the following, if you want to use an existing NT-Server to
+# authenticate users, but don't forget that you also have to create them
+# locally!
+; security = server
+; password server = 192.168.1.10
+
+ printing = LPRNG
+ printcap name = /etc/printcap
+ load printers = Yes
+
+# These settings are a suggestion for a local network. Cf. section
+# 'socket options' in the man page of smb.conf and socket(7).
+ socket options = SO_KEEPALIVE IPTOS_LOWDELAY TCP_NODELAY
+
+# Uncomment this, if you want to integrate your server
+# into an existing net e.g. with NT-WS to prevent nettraffic
+; local master = No
+
+# Please uncomment the following entry and replace the ip number and
+# netmask with the values of your network interface configuration.
+; interfaces = 192.168.1.1/255.255.255.0
+
+# If you want Samba to act as a wins server, please set
+# 'wins support' to yes.
+ wins support = No
+
+# If you want Samba to use an existing wins server, please uncomment the
+# following line and replace the dummy with the wins server's ip number.
+; wins server = 192.168.1.1
+
+# Set these two parameters to your DOS code page and appropriate UNIX
+# character set. These values are for west European languages (Latin-9)
+# UNIX character and MS-DOS Latin 1 code page.
+ character set = ISO8859-15
+ client code page = 850
+
+# This is a simple measure against Nimba Worm. Cf. README.Win32-Viruses
+ veto files = /*.eml/*.nws/riched20.dll/*.{*}/
+
+# Do you wan't samba to act as a logon-server for your windows 95/98
+# clients, so uncomment the following:
+; domain logons = Yes
+; domain master = Yes
+# For a specific logon script per user
+; logon script = %U.bat
+# For a specific logon script per machine
+; logon script = %m.bat
+
+# Where to store the logon scripts.
+;[netlogon]
+; comment = Network Logon Service
+; path = /var/lib/samba/netlogon
+
+# Where profiles of Windows 9x systems are stored.
+# First example for a centralized place.
+; logon home = \\%L\profiles\%U
+# Second example for a subdirectory of the users home.
+; logon home = \\%L\%U\profile
+# Where profiles of Windows NT systems are stored.
+; logon path = \\%L\profiles\%U
+
+# Extra share for profiles. Default is the home of the user.
+;[profiles]
+; comment = Network Profiles Service
+; path = /var/lib/samba/profiles
+; browseable = No
+
+[homes]
+ comment = Home Directories
+ read only = No
+ create mask = 0640
+ directory mask = 0750
+ browseable = No
+
+# The following share gives all users access to the Server's CD drive,
+# assuming it is mounted under /media/cdrom. To enable this share,
+# please remove the semicolons before the lines
+;[cdrom]
+; comment = Linux CD-ROM
+; path = /media/cdrom
+; locking = No
+
+[printers]
+ comment = All Printers
+ path = /var/tmp
+ create mask = 0600
+ printable = Yes
+ browseable = No
+
diff --git a/packaging/SuSE/8.0/smbpasswd b/packaging/SuSE/8.0/smbpasswd
new file mode 100755
index 00000000000..6f0c5cbec19
--- /dev/null
+++ b/packaging/SuSE/8.0/smbpasswd
@@ -0,0 +1,5 @@
+# This file is the authentication source for samba. You add password
+# information with the smbpasswd or smbadduser command.
+#
+# Cf. section 'encrypt passwords' in the manual page of smb.conf for
+# more information.
diff --git a/packaging/SuSE/8.0/smbusers b/packaging/SuSE/8.0/smbusers
new file mode 100755
index 00000000000..1dfa63fe01d
--- /dev/null
+++ b/packaging/SuSE/8.0/smbusers
@@ -0,0 +1,8 @@
+# This file allows you to map usernames from the clients to the server.
+# Unix_name = SMB_name1 SMB_name2 ...
+#
+# Cf. section 'username map' in the manual page of smb.conf for more
+# information.
+
+;root = administrator admin
+;nobody = guest pcguest smbguest
diff --git a/packaging/SuSE/README b/packaging/SuSE/README
deleted file mode 100644
index 5d0af9944aa..00000000000
--- a/packaging/SuSE/README
+++ /dev/null
@@ -1,18 +0,0 @@
-Date: March 29, 2003
-
-Note: The current packaging files are NOT officially supported files.
----------------------------------------------------------------------
-
-While the SPEC file shows who the original author was, these files imply no warranty of
-fitness what so ever. These files are NOT official SuSE files and are NOT supported by
-them. If you have ANY problems with the use of these files then please email jht@samba.org
-and NOT SuSE support.
-
-
-These files may be used to build Samba-3.0 packages for SuSE Linux 8.1 and/or for
-UnitedLinux 1.0 systems.
-
-Note2: You most likely will need to update to heimdal-0.5.1 or later if you intend to
-use any Kerberos functionality.
-
-- John T.
diff --git a/packaging/SuSE/samba-3.0.0.files.tar.bz2 b/packaging/SuSE/samba-3.0.0.files.tar.bz2
deleted file mode 100644
index 1e8fc9baf0c..00000000000
--- a/packaging/SuSE/samba-3.0.0.files.tar.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/SuSE/samba-mutual-auth.diff b/packaging/SuSE/samba-mutual-auth.diff
deleted file mode 100644
index 865f91682a3..00000000000
--- a/packaging/SuSE/samba-mutual-auth.diff
+++ /dev/null
@@ -1,247 +0,0 @@
---- source/configure.in 22 Feb 2003 12:19:18 -0000 1.409
-+++ source/configure.in 24 Feb 2003 06:04:25 -0000
-@@ -627,6 +627,15 @@
- fi
-
- ############################################
-+# support for using Kerberos keytab instead of secrets database
-+
-+AC_ARG_ENABLE(keytab,
-+[ --enable-keytab Turn on support for Kerberos keytabs in lieu of secrets DB (default=no)],
-+ [if eval "test x$enable_keytab = xyes"; then
-+ AC_DEFINE(USE_KEYTAB,1,[Use Kerberos keytab])
-+ fi])
-+
-+############################################
- # we need dlopen/dlclose/dlsym/dlerror for PAM, the password database plugins and the plugin loading code
- AC_SEARCH_LIBS(dlopen, [dl])
- # dlopen/dlclose/dlsym/dlerror will be checked again later and defines will be set then
---- source/passdb/secrets.c 1 Feb 2003 04:39:15 -0000 1.54
-+++ source/passdb/secrets.c 24 Feb 2003 06:04:26 -0000
-@@ -221,6 +221,72 @@
- return True;
- }
-
-+#ifdef USE_KEYTAB
-+/************************************************************************
-+ Read local secret from the keytab
-+************************************************************************/
-+
-+static BOOL secrets_fetch_keytab_password(uint8 ret_pwd[16], time_t *pass_last_set_time)
-+{
-+ char spn[MAXHOSTNAMELEN + 2], *p;
-+ krb5_context context;
-+ krb5_error_code ret;
-+ krb5_principal princ;
-+ krb5_keyblock *key;
-+
-+ ret = krb5_init_context(&context);
-+ if (ret) {
-+ DEBUG(1, ("secrets_fetch_keytab_password: failed to initialize Kerberos context\n"));
-+ return False;
-+ }
-+
-+ spn[sizeof(spn) - 1] = '\0';
-+ if (gethostname(spn, sizeof(spn) - 2) < 0) {
-+ DEBUG(1, ("secrets_fetch_keytab_password: could not determine local hostname\n"));
-+ krb5_free_context(context);
-+ return False;
-+ }
-+
-+ for (p = spn; *p && *p != '.'; p++)
-+ *p = toupper(*p);
-+ *p++ = '$';
-+ *p = '\0';
-+
-+ ret = krb5_parse_name(context, spn, &princ);
-+ if (ret) {
-+ DEBUG(1, ("secrets_fetch_keytab_password: failed to parse name %s\n", spn));
-+ krb5_free_context(context);
-+ return False;
-+ }
-+
-+#ifdef ENCTYPE_ARCFOUR_HMAC
-+ ret = krb5_kt_read_service_key(context, NULL, princ, 0, ENCTYPE_ARCFOUR_HMAC, &key);
-+#elif defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
-+ ret = krb5_kt_read_service_key(context, NULL, princ, 0, ENCTYPE_ARCFOUR_HMAC_MD5, &key);
-+#else
-+#error ENCTYPE_ARCFOUR_HMAC or ENCTYPE_ARCFOUR_HMAC_MD5 required for keytab secret storage
-+#endif
-+ if (ret) {
-+ DEBUG(1, ("secrets_fetch_keytab_password: failed to read secret for %s\n", spn));
-+ krb5_free_context(context);
-+ return False;
-+ }
-+ if (key->keyvalue.length != 16) {
-+ DEBUG(1, ("secrets_fetch_keytab_password: key is incorrect length\n"));
-+ krb5_free_context(context);
-+ return False;
-+ }
-+
-+ memcpy(ret_pwd, key->keyvalue.data, key->keyvalue.length);
-+ time(pass_last_set_time); /* XXX */
-+
-+ krb5_free_keyblock(context, key);
-+ krb5_free_context(context);
-+
-+ return True;
-+}
-+#endif /* USE_KEYTAB */
-+
- /************************************************************************
- Routine to get the trust account password for a domain.
- The user of this function must have locked the trust password file using
-@@ -243,6 +309,12 @@
- pass_last_set_time = 0;
- return True;
- }
-+
-+#ifdef USE_KEYTAB
-+ if (is_myworkgroup(domain)) {
-+ return secrets_fetch_keytab_password(ret_pwd, pass_last_set_time);
-+ }
-+#endif /* USE_KEYTAB */
-
- if (!(pass = secrets_fetch(trust_keystr(domain), &size))) {
- DEBUG(5, ("secrets_fetch failed!\n"));
-
---- source/libsmb/clikrb5.c 2003-07-02 00:32:55.000000000 +0200
-+++ source/libsmb/clikrb5.c 2003-07-02 00:37:22.000000000 +0200
-@@ -316,11 +316,13 @@
- krb5_enctype enc_types[] = {
- #ifdef ENCTYPE_ARCFOUR_HMAC
- ENCTYPE_ARCFOUR_HMAC,
-+#elif defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
-+ ENCTYPE_ARCFOUR_HMAC_MD5,
- #endif
- ENCTYPE_DES_CBC_MD5,
- ENCTYPE_DES_CBC_CRC,
- ENCTYPE_NULL};
--
-+
- retval = krb5_init_context(&context);
- if (retval) {
- DEBUG(1,("krb5_init_context failed (%s)\n",
-@@ -367,24 +369,26 @@
-
- BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
- {
--#ifdef ENCTYPE_ARCFOUR_HMAC
- krb5_keyblock *skey;
--#endif
- BOOL ret = False;
-
- memset(session_key, 0, 16);
-
--#ifdef ENCTYPE_ARCFOUR_HMAC
-+#if defined(ENCTYPE_ARCFOUR_HMAC) || defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
- if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) {
- if (KRB5_KEY_TYPE(skey) ==
-+# ifdef ENCTYPE_ARCFOUR_HMAC
- ENCTYPE_ARCFOUR_HMAC
-+# else
-+ ENCTYPE_ARCFOUR_HMAC_MD5
-+# endif /* ENCTYPE_ARCFOUR_HMAC */
- && KRB5_KEY_LENGTH(skey) == 16) {
- memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
- ret = True;
- }
- krb5_free_keyblock(context, skey);
- }
--#endif /* ENCTYPE_ARCFOUR_HMAC */
-+#endif /* ENCTYPE_ARCFOUR_HMAC || HAVE_ENCTYPE_ARCFOUR_HMAC_MD5 */
-
- return ret;
- }
-@@ -395,5 +399,12 @@
- DEBUG(0,("NO KERBEROS SUPPORT\n"));
- return data_blob(NULL, 0);
- }
-+BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16])
-+ {
-+ DEBUG(0,("NO KERBEROS SUPPORT\n"));
-+ memset(session_key, 0, 16);
-+ return False;
-+ }
-+ //#endif
-
- #endif
---- source/libads/kerberos_verify.c 2003-06-28 23:40:55.000000000 +0200
-+++ source/libads/kerberos_verify.c 2003-07-02 00:50:13.000000000 +0200
-@@ -38,7 +38,9 @@
- krb5_keytab keytab = NULL;
- krb5_data packet;
- krb5_ticket *tkt = NULL;
-- int ret, i;
-+ int ret;
-+#ifndef USE_KEYTAB
-+ int i;
- krb5_keyblock * key;
- krb5_principal host_princ;
- char *host_princ_s;
-@@ -46,8 +48,10 @@
- char *password_s;
- krb5_data password;
- krb5_enctype *enctypes = NULL;
-+#endif /* USE_KEYTAB */
- BOOL auth_ok = False;
-
-+#ifndef USE_KEYTAB
- if (!secrets_init()) {
- DEBUG(1,("secrets_init failed\n"));
- return NT_STATUS_LOGON_FAILURE;
-@@ -61,6 +65,7 @@
-
- password.data = password_s;
- password.length = strlen(password_s);
-+#endif /* USE_KEYTAB */
-
- ret = krb5_init_context(&context);
- if (ret) {
-@@ -82,7 +87,16 @@
- DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
- return NT_STATUS_LOGON_FAILURE;
- }
-+#ifdef USE_KEYTAB
-+ packet.length = ticket->length;
-+ packet.data = (krb5_pointer)ticket->data;
-
-+ if (!(ret = krb5_rd_req(context, &auth_context, &packet,
-+ NULL, keytab, NULL, &tkt))) {
-+ auth_ok = True;
-+ }
-+
-+#else
- fstrcpy(myname, global_myname());
- strlower(myname);
- asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
-@@ -121,6 +135,9 @@
- }
- }
-
-+ SAFE_FREE(key);
-+#endif /* USE_KEYTAB */
-+
- if (!auth_ok) {
- DEBUG(3,("krb5_rd_req with auth failed (%s)\n",
- error_message(ret)));
---- source/Makefile.in 2003-07-01 23:35:49.000000000 +0200
-+++ source/Makefile.in 2003-07-02 01:20:09.000000000 +0200
-@@ -806,7 +806,7 @@
-
- bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
-- @$(CC) $(FLAGS) -o $@ $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS)
-+ @$(CC) $(FLAGS) -o $@ $(IDMAP_LIBS) $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(KRB5LIBS)
-
- bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
-@@ -1062,7 +1062,7 @@
-
- bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
-- @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
-+ @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
-
- bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
- $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
diff --git a/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2 b/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2
deleted file mode 100755
index 2680bed82f0..00000000000
--- a/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/SuSE/samba3-3.0.0-Makefiles-heimdal.diff b/packaging/SuSE/samba3-3.0.0-Makefiles-heimdal.diff
deleted file mode 100644
index 13da47e7409..00000000000
--- a/packaging/SuSE/samba3-3.0.0-Makefiles-heimdal.diff
+++ /dev/null
@@ -1,22 +0,0 @@
---- examples/pdb/Makefile Thu Sep 5 02:11:41 2002
-+++ examples/pdb/Makefile Thu Sep 5 02:11:59 2002
-@@ -8,7 +8,7 @@
- SAMBA_INCL = ../../source/include
- UBIQX_SRC = ../../source/ubiqx
- SMBWR_SRC = ../../source/smbwrapper
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -I/usr/include/heimdal
- PDB_OBJS = pdb_test.so
-
- # Default target
---- examples/VFS/Makefile.in 2003-06-04 15:13:41.000000000 +0200
-+++ examples/VFS/Makefile.in 2003-06-04 22:07:03.000000000 +0200
-@@ -7,7 +7,7 @@
- SAMBA_SOURCE = @SAMBA_SOURCE@
- SHLIBEXT = @SHLIBEXT@
- OBJEXT = @OBJEXT@
--FLAGS = $(CFLAGS) -Iinclude -I$(SAMBA_SOURCE)/include -I$(SAMBA_SOURCE)/ubiqx -I$(SAMBA_SOURCE)/smbwrapper -I. $(CPPFLAGS) -I$(SAMBA_SOURCE)
-+FLAGS = $(CFLAGS) -Iinclude -I$(SAMBA_SOURCE)/include -I$(SAMBA_SOURCE)/ubiqx -I$(SAMBA_SOURCE)/smbwrapper -I. $(CPPFLAGS) -I$(SAMBA_SOURCE) -I/usr/include/heimdal
-
-
- prefix = @prefix@
diff --git a/packaging/SuSE/samba3-3.0.0-heimdal-06.diff b/packaging/SuSE/samba3-3.0.0-heimdal-06.diff
deleted file mode 100644
index 87dd3e1824c..00000000000
--- a/packaging/SuSE/samba3-3.0.0-heimdal-06.diff
+++ /dev/null
@@ -1,14 +0,0 @@
---- source/include/ads.h 2003-06-10 08:51:03.000000000 +0200
-+++ source/include/ads.h 2003-06-22 23:14:24.000000000 +0200
-@@ -215,9 +215,11 @@
- #define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
- #endif
-
-+#if 0
- /* The older versions of heimdal that don't have this
- define don't seem to use it anyway. I'm told they
- always use a subkey */
- #ifndef AP_OPTS_USE_SUBKEY
- #define AP_OPTS_USE_SUBKEY 0
- #endif
-+#endif
diff --git a/packaging/SuSE/samba3-3.0.0-pdb.diff b/packaging/SuSE/samba3-3.0.0-pdb.diff
deleted file mode 100644
index 0c811b57c52..00000000000
--- a/packaging/SuSE/samba3-3.0.0-pdb.diff
+++ /dev/null
@@ -1,13 +0,0 @@
---- examples/pdb/pdb_test.c 26 Sep 2002 18:37:54 -0000 1.1.2.3
-+++ examples/pdb/pdb_test.c 22 Apr 2003 20:06:31 -0000
-@@ -142,8 +142,6 @@
- int init_module(void);
-
- int init_module() {
-- if(smb_register_passdb("testsam", testsam_init, PASSDB_INTERFACE_VERSION))
-- return 0;
--
-- return 1;
-+ smb_register_passdb(PASSDB_INTERFACE_VERSION, "testsam", testsam_init);
-+ return True;
- }
diff --git a/packaging/SuSE/samba3-Makefile.diff b/packaging/SuSE/samba3-Makefile.diff
deleted file mode 100644
index bc1ad142d9f..00000000000
--- a/packaging/SuSE/samba3-Makefile.diff
+++ /dev/null
@@ -1,16 +0,0 @@
---- source/Makefile.in 2003-04-23 10:43:06.000000000 +0200
-+++ source/Makefile.in 2003-04-23 10:45:39.000000000 +0200
-@@ -673,6 +673,13 @@
- @echo "Using FLAGS = $(FLAGS)"
- @echo " FLAGS32 = $(FLAGS32)"
- @echo " LIBS = $(LIBS)"
-+ @echo " TERMLIBS = $(TERMLIBS)"
-+ @echo " PRINTLIBS = $(PRINTLIBS)"
-+ @echo " AUTHLIBS = $(AUTHLIBS)"
-+ @echo " ACLLIBS = $(ACLLIBS)"
-+ @echo " PASSDBLIBS = $(PASSDBLIBS)"
-+ @echo " ADSLIBS = $(ADSLIBS)"
-+ @echo " KRB5LIBS = $(KRB5_LIBS)"
- @echo " LDSHFLAGS = $(LDSHFLAGS)"
- @echo " LDFLAGS = $(LDFLAGS)"
-
diff --git a/packaging/SuSE/samba3-com_err.diff b/packaging/SuSE/samba3-com_err.diff
deleted file mode 100644
index c5d04cebe19..00000000000
--- a/packaging/SuSE/samba3-com_err.diff
+++ /dev/null
@@ -1,60 +0,0 @@
---- source/libads/kerberos.c 23 Oct 2002 00:02:26 -0000 1.18
-+++ source/libads/kerberos.c 1 Jul 2003 21:30:17 -0000
-@@ -126,6 +126,7 @@
- return KRB5_LIBOS_CANTREADPWD;
- }
-
-+ initialize_krb5_error_table();
- ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset);
-
- if (ret) {
---- source/libads/kerberos_verify.c 6 Jun 2003 14:53:22 -0000 1.10.2.1
-+++ source/libads/kerberos_verify.c 1 Jul 2003 21:30:17 -0000
-@@ -62,6 +62,7 @@
- password.data = password_s;
- password.length = strlen(password_s);
-
-+ initialize_krb5_error_table();
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
---- source/libads/krb5_setpw.c 6 Jun 2003 14:53:22 -0000 1.16.2.1
-+++ source/libads/krb5_setpw.c 1 Jul 2003 21:30:17 -0000
-@@ -470,6 +470,7 @@
- krb5_creds creds, *credsp;
- krb5_ccache ccache;
-
-+ initialize_krb5_error_table();
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
-@@ -584,6 +585,7 @@
- krb5_creds creds;
- char *chpw_princ = NULL, *password;
-
-+ initialize_krb5_error_table();
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
---- source/libsmb/clikrb5.c 1 Jul 2003 14:40:37 -0000 1.36.2.2
-+++ source/libsmb/clikrb5.c 1 Jul 2003 21:30:20 -0000
-@@ -320,7 +320,8 @@
- ENCTYPE_DES_CBC_MD5,
- ENCTYPE_DES_CBC_CRC,
- ENCTYPE_NULL};
--
-+
-+ initialize_krb5_error_table();
- retval = krb5_init_context(&context);
- if (retval) {
- DEBUG(1,("krb5_init_context failed (%s)\n",
---- source/utils/net_lookup.c 1 Jul 2003 14:40:47 -0000 1.8.2.1
-+++ source/utils/net_lookup.c 1 Jul 2003 21:30:24 -0000
-@@ -177,6 +177,7 @@
- krb5_data realm;
- char **realms;
-
-+ initialize_krb5_error_table();
- rc = krb5_init_context(&ctx);
- if (rc) {
- DEBUG(1,("krb5_init_context failed (%s)\n",
diff --git a/packaging/SuSE/samba3-net_ads_password.diff b/packaging/SuSE/samba3-net_ads_password.diff
deleted file mode 100644
index cc800fb7bfd..00000000000
--- a/packaging/SuSE/samba3-net_ads_password.diff
+++ /dev/null
@@ -1,58 +0,0 @@
-Index: source/utils/net_ads.c
-===================================================================
-RCS file: /cvsroot/samba/source/utils/net_ads.c,v
-retrieving revision 1.37.2.22
-diff -u -r1.37.2.22 net_ads.c
---- source/utils/net_ads.c 10 Jun 2003 04:15:55 -0000 1.37.2.22
-+++ source/utils/net_ads.c 20 Jun 2003 19:59:36 -0000
-@@ -44,9 +44,9 @@
- "\n\tdump the machine account details to stdout\n"
- "\nnet ads lookup"\
- "\n\tperform a CLDAP search on the server\n"
--"\nnet ads password <username@realm> -Uadmin_username@realm%%admin_pass"\
-+"\nnet ads password <username@realm> <password> -Uadmin_username@realm%%admin_pass"\
- "\n\tchange a user's password using an admin account"\
--"\n\t(note: use realm in UPPERCASE)\n"\
-+"\n\t(note: use realm in UPPERCASE, prompts if password is obmitted)\n"\
- "\nnet ads changetrustpw"\
- "\n\tchange the trust account password of this machine in the AD tree\n"\
- "\nnet ads printer [info | publish | remove] <printername> <servername>"\
-@@ -909,7 +909,7 @@
- }
-
-
-- if (argc != 1) {
-+ if (argc < 1) {
- d_printf("ERROR: You must say which username to change password for\n");
- return -1;
- }
-@@ -941,22 +941,24 @@
- return -1;
- }
-
-- asprintf(&prompt, "Enter new password for %s:", user);
--
-- new_password = getpass(prompt);
-+ if (argv[1]) {
-+ new_password = (char *)argv[1];
-+ } else {
-+ asprintf(&prompt, "Enter new password for %s:", user);
-+ new_password = getpass(prompt);
-+ free(prompt);
-+ }
-
- ret = kerberos_set_password(ads->auth.kdc_server, auth_principal,
- auth_password, user, new_password, ads->auth.time_offset);
- if (!ADS_ERR_OK(ret)) {
- d_printf("Password change failed :-( ...\n");
- ads_destroy(&ads);
-- free(prompt);
- return -1;
- }
-
- d_printf("Password change for %s completed.\n", user);
- ads_destroy(&ads);
-- free(prompt);
-
- return 0;
- }
diff --git a/packaging/SuSE/samba3-smbwrapper.diff b/packaging/SuSE/samba3-smbwrapper.diff
deleted file mode 100644
index 0f7b391de0d..00000000000
--- a/packaging/SuSE/samba3-smbwrapper.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- source/smbwrapper/smbsh.c.orig 2003-05-04 19:47:39.000000000 +0200
-+++ source/smbwrapper/smbsh.c 2003-05-04 19:47:47.000000000 +0200
-@@ -36,7 +36,7 @@
- int main(int argc, char *argv[])
- {
- char *p, *u;
-- const char *libd = dyn_BINDIR;
-+ const char *libd = dyn_LIBDIR;
- pstring line, wd;
- int opt;
- extern char *optarg;
diff --git a/packaging/SuSE/samba3-vscan.diff b/packaging/SuSE/samba3-vscan.diff
deleted file mode 100644
index 330b470af2c..00000000000
--- a/packaging/SuSE/samba3-vscan.diff
+++ /dev/null
@@ -1,269 +0,0 @@
---- examples/VFS/samba-vscan-0.3.2b/fprot/Makefile 2003-01-14 00:42:15.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/fprot/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -14,7 +14,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- VFS_OBJS = vscan-fprotd.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c $(SMBVS_GLB)/vscan-fileaccesslog.c vscan-fprotd.c vscan-fprotd_core.c vscan-fprotd.h vscan-fprotd_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fileaccesslog.lo vscan-fprotd.lo vscan-fprotd_core.lo
---- examples/VFS/samba-vscan-0.3.2b/fprot/vscan-fprotd.c 2003-02-21 21:37:44.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/fprot/vscan-fprotd.c 2003-04-09 20:25:25.000000000 +0200
-@@ -432,14 +432,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* virus found, deny acces */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
---- examples/VFS/samba-vscan-0.3.2b/fprot/vscan-fprotd_core.c 2003-01-25 18:40:57.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/fprot/vscan-fprotd_core.c 2003-04-09 20:23:31.000000000 +0200
-@@ -110,7 +110,7 @@
- pstring fprotdCommand; /* the command line to be send to daemon */
- char *str;
- FILE *fpin, *fpout;
-- bool received_data = FALSE; /* indicates, if any response from deamon was received */
-+ bool received_data = False; /* indicates, if any response from deamon was received */
-
- /* open stream sockets */
- fpin = fdopen(sockfd, "r");
-@@ -159,7 +159,7 @@
-
- while ( (fgets(recvline, MAXLINE, fpin)) != NULL ) {
-
-- received_data = TRUE;
-+ received_data = True;
-
- /* ignore the HTTP response header, remove any leading
- white spaces */
---- examples/VFS/samba-vscan-0.3.2b/icap/Makefile 2003-01-30 00:53:02.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/icap/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- VFS_OBJS = vscan-icap.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c $(SMBVS_GLB)/vscan-fileaccesslog.c vscan-icap.c vscan-icap_core.c vscan-icap.h vscan-icap_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fileaccesslog.lo vscan-icap.lo vscan-icap_core.lo
---- examples/VFS/samba-vscan-0.3.2b/icap/vscan-icap.c 2003-02-21 21:37:50.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/icap/vscan-icap.c 2003-04-09 20:32:20.000000000 +0200
-@@ -413,14 +413,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* virus found, deny acces */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
---- examples/VFS/samba-vscan-0.3.2b/icap/vscan-icap_core.c 2003-01-15 00:19:18.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/icap/vscan-icap_core.c 2003-04-09 20:30:56.000000000 +0200
-@@ -114,8 +114,8 @@
- char buf[BUFLEN];
- char recvline[MAXLINE + 1];
- char *str;
-- bool first_line = FALSE; /* first line we've received? */
-- bool infected = FALSE; /* an infected found? */
-+ bool first_line = False; /* first line we've received? */
-+ bool infected = False; /* an infected found? */
-
-
- /* get file length */
-@@ -213,7 +213,7 @@
- /* set line buffering */
- setvbuf(fpin, (char *)NULL, _IOLBF, 0);
-
-- first_line = TRUE;
-+ first_line = True;
- while ( (fgets(recvline, MAXLINE, fpin)) != NULL ) {
- str = recvline;
- if ( first_line ) {
-@@ -226,7 +226,7 @@
- return(0);
- }
- else if ( strncmp("403", str, 3) == 0 ) {
-- infected = TRUE;
-+ infected = True;
- } else {
- if ( verbose_file_logging )
- vscan_syslog("ERROR: file %s not found, not readable or an error occured", scan_file);
-@@ -241,7 +241,7 @@
- return(-1);
- }
-
-- first_line = FALSE;
-+ first_line = False;
- }
- if ( infected ) {
- if ( strncmp("X-Infection-Found", str, 17) == 0 ) {
---- examples/VFS/samba-vscan-0.3.2b/include/vscan-global.h 2002-11-25 16:48:10.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/include/vscan-global.h 2003-04-09 20:21:37.000000000 +0200
-@@ -93,7 +93,7 @@
- */
-
- #ifndef SAMBA_VERSION_MAJOR
--# define SAMBA_VERSION_MAJOR 2
-+# define SAMBA_VERSION_MAJOR 3
- #endif
-
- #ifndef SAMBA_VERSION_MINOR
---- examples/VFS/samba-vscan-0.3.2b/kaspersky/Makefile 2003-02-20 15:41:32.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/kaspersky/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -23,9 +23,9 @@
- VFS_OBJS = vscan-kavp.so
-
- ifdef USE_DEBUG
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- else
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- endif
-
- ifndef USE_KAVPSHAREDLIB
---- examples/VFS/samba-vscan-0.3.2b/mks/Makefile 2003-01-19 18:09:53.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/mks/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -16,10 +16,10 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
-
- ifdef USE_INCLMKSDLIB
--CFLAGS=-I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_USE_INCL_MKSD_LIB=1 -fPIC
-+CFLAGS=-I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_USE_INCL_MKSD_LIB=1 -fPIC -I/usr/include/heimdal
- endif
-
- VFS_OBJS = vscan-mksd.so
---- examples/VFS/samba-vscan-0.3.2b/mks/vscan-mksd.c 2003-02-21 21:37:50.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/mks/vscan-mksd.c 2003-04-09 20:38:16.000000000 +0200
-@@ -393,14 +393,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* virus found, deny acces */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
---- examples/VFS/samba-vscan-0.3.2b/openantivirus/Makefile 2003-01-30 00:53:08.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/openantivirus/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- VFS_OBJS = vscan-oav.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c $(SMBVS_GLB)/vscan-fileaccesslog.c vscan-oav.c vscan-oav_core.c vscan-oav.h vscan-oav_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fileaccesslog.lo vscan-oav.lo vscan-oav_core.lo
---- examples/VFS/samba-vscan-0.3.2b/openantivirus/vscan-oav.c 2003-02-21 21:37:51.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/openantivirus/vscan-oav.c 2003-04-09 20:40:53.000000000 +0200
-@@ -417,14 +417,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* virus found, deny acces */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
---- examples/VFS/samba-vscan-0.3.2b/sophos/Makefile 2003-01-30 00:53:08.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/sophos/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- VFS_OBJS = vscan-sophos.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c $(SMBVS_GLB)/vscan-fileaccesslog.c vscan-sophos.c vscan-sophos_core.c vscan-sophos.h vscan-sophos_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fileaccesslog.lo vscan-sophos.lo vscan-sophos_core.lo
---- examples/VFS/samba-vscan-0.3.2b/sophos/vscan-sophos.c 2003-02-21 21:37:51.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/sophos/vscan-sophos.c 2003-04-09 20:43:11.000000000 +0200
-@@ -399,14 +399,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* deny access */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
---- examples/VFS/samba-vscan-0.3.2b/trend/Makefile 2003-01-30 01:03:38.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/trend/Makefile 2003-04-09 20:21:37.000000000 +0200
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/usr/include/heimdal
- VFS_OBJS = vscan-trend.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c $(SMBVS_GLB)/vscan-fileaccesslog.c vscan-trend.c vscan-trend_core.c vscan-trend.h vscan-trend_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fileaccesslog.lo vscan-trend.lo vscan-trend_core.lo
---- examples/VFS/samba-vscan-0.3.2b/trend/vscan-trend.c 2003-02-21 21:37:52.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.2b/trend/vscan-trend.c 2003-04-09 20:46:07.000000000 +0200
-@@ -409,14 +409,14 @@
- rc = vscan_do_infected_file_action(&default_vfs_ops, conn, filepath, quarantine_dir, quarantine_prefix, infected_file_action);
-
- /* add/update file. mark file as infected! */
-- lrufiles_add(filepath, stat_buf.st_mtime, TRUE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, True);
-
- /* deny access */
- errno = EACCES;
- return -1;
- } else if ( retval == 0 ) {
- /* file is clean, add to lrufiles */
-- lrufiles_add(filepath, stat_buf.st_mtime, FALSE);
-+ lrufiles_add(filepath, stat_buf.st_mtime, False);
- }
- }
-
diff --git a/packaging/SuSE/samba3.spec b/packaging/SuSE/samba3.spec
deleted file mode 100644
index 37d8a4d36f8..00000000000
--- a/packaging/SuSE/samba3.spec
+++ /dev/null
@@ -1,766 +0,0 @@
-#
-# spec file for package samba3 (Version 3.0.0rc1cvs)
-#
-# Copyright (c) 2003 SuSE Linux AG, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
-#
-# Please submit bugfixes or comments via http://www.suse.de/feedback/
-#
-# Note: The Samba3 tarball should be called: samba3-3.0.0.tar.bz2
-#
-
-# neededforbuild XFree86-libs autoconf automake cups-devel cups-libs dialog docbook-utils docbook-xsl-stylesheets docbook_4 ed freetype2 ghostscript-fonts-std ghostscript-library ghostscript-x11 glib heimdal heimdal-devel heimdal-lib iso_ent libacl libacl-devel libattr libattr-devel libgimpprint libpng libtiff libxml2 libxml2-devel libxslt mysql-devel mysql-shared openldap2 openldap2-client openldap2-devel openssl openssl-devel popt popt-devel python python-devel readline readline-devel te_etex te_latex te_pdf tetex xmlcharent
-# usedforbuild aaa_base acl attr bash bind9-utils bison coreutils cpio cpp cvs cyrus-sasl2 db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv kbd less libacl libattr libgcc libstdc++ libxcrypt m4 make man mktemp modutils ncurses ncurses-devel net-tools netcfg pam pam-devel pam-modules patch permissions ps rcs readline sed sendmail shadow strace syslogd sysvinit tar texinfo timezone unzip util-linux vim zlib zlib-devel XFree86-libs autoconf automake binutils bzip2 cracklib cups-devel cups-libs dialog docbook-utils docbook-xsl-stylesheets docbook_4 ed freetype2 gcc gdbm gettext ghostscript-fonts-std ghostscript-library ghostscript-x11 glib heimdal heimdal-devel heimdal-lib iso_ent libacl-devel libattr-devel libgimpprint libpng libtiff libtool libxml2 libxml2-devel libxslt mysql-devel mysql-shared openldap2 openldap2-client openldap2-devel openssl openssl-devel perl popt popt-devel python python-devel readline-devel rpm te_ams te_etex te_latex te_pdf tetex xmlcharent
-
-Name: samba3
-Vendor: Samba Team
-License: GPL
-Group: Productivity/Networking/Samba
-Url: http://www.samba.org
-Provides: samba smbfs samba3
-Requires: samba3-client
-Obsoletes: samba-classic samba-ldap
-Autoreqprov: on
-%define krb_heimdal_05 0
-%define new_heimdal /opt/heimdal
-%define new_sasl /opt/sasl
-%define new_openldap /opt/openldap
-%define new_glibc 0
-Version: 3.0.0
-Release: %(date +%%j)
-%define head 0
-%define samba_ver 3.0.0
-%define samba_release 0
-%define ul_version 0
-%define suse_ver 820
-%define python_ver python2.2
-%if %{suse_ver} > 810
-%define new_glibc 1
-%endif
-%if %{suse_ver} > 821
-%define python_ver python2.3
-%endif
-%define make_cifsvfs 1
-%define make_devel 0
-%define make_doc 0
-%define make_python 1
-%define make_shared_mod 0
-%define make_smbwrap 1
-# vscan has not yet updated to the new vfs-api
-%define make_vscan 0
-%define make_wrepld 1
-%define use_keytab 0
-Summary: samba3
-Source: %{name}-%{version}.tar.bz2
-Source10: %{name}-%{version}.files.tar.bz2
-Source50: samba-vscan-%{vscan_ver}.tar.bz2
-Patch1: %{name}-%{version}-Makefiles-heimdal.diff
-Patch2: samba-mutual-auth.diff
-Patch29: %{name}-com_err.diff
-Patch30: %{name}-%{version}-heimdal-06.diff
-Patch31: %{name}-%{version}-pdb.diff
-Patch32: %{name}-net_ads_password.diff
-Patch33: %{name}-Makefile.diff
-Patch34: %{name}-smbwrapper.diff
-Patch51: %{name}-vscan.diff
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-%define DOCDIR %{_defaultdocdir}/%{name}
-%define DOCBOOKDIR %{_defaultdocdir}/%{name}/docbook
-%define SWATDIR %{_datadir}/samba/swat
-%define vscan_ver 0.3.2b
-%define vscan_modules fprot icap mks openantivirus sophos trend
-#not pdb_nisplussam
-%define pdb_modules pdb_xml,pdb_mysql,pdb_ldap,pdb_smbpasswd,pdb_tdbsam,pdb_unix,pdb_guest,pdb_nisplussam
-%define rpc_modules rpc_lsa,rpc_samr,rpc_reg,rpc_wks,rpc_net,rpc_dfs,rpc_srv,rpc_spoolss
-%define auth_modules auth_rhosts,auth_sam,auth_unix,auth_winbind,auth_server,auth_domain,auth_builtin
-%define vfs_modules vfs_recycle,vfs_audit,vfs_extd_audit,vfs_netatalk,vfs_fake_perms
-%define idmap_modules idmap_winbind,idmap_ldap,idmap_tdb
-%define charset_modules charset_weird
-%package client
-Summary: samba3-client
-Autoreqprov: on
-Requires: cups-libs
-Obsoletes: smbclnt samba-classic-client samba-ldap-client
-Provides: samba-client samba3-client
-Group: Productivity/Networking/Samba
-%package winbind
-Requires: samba-client samba
-Summary: samba3-winbind
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%package utils
-Summary: samba3-utils
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%package doc
-Summary: samba3-doc
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%package docbook
-Summary: samba3-docbook
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%package pdb
-Summary: samba3-pdb
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%if %{make_cifsvfs}
-%package cifsmount
-Summary: samba3-cifsmount
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-Url: http://us1.samba.org/samba/Linux_CIFS_client.html
-%endif
-%if %{make_vscan}
-%package vscan
-Summary: samba3-vscan
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-Version: 0.3.2a
-Release: 0
-Url: http://www.openantivirus.org/
-%endif
-%if %{make_wrepld}
-%package wrepld
-Summary: samba3-wrepld
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%endif
-%if %{make_python}
-%package python
-Summary: samba3-python
-Autoreqprov: on
-Group: Productivity/Networking/Samba
-%endif
-%package -n libsmbclient
-Summary: Samba client library
-Autoreqprov: on
-Group: System/Libraries
-%package -n libsmbclient-devel
-Summary: Libraries and header files to develop programs with smbclient support
-Autoreqprov: on
-Group: Development/Libraries/C and C++
-%prep
-[ $RPM_BUILD_ROOT = "/" ] && (echo "your buildroot is /" && exit 0) || rm -rf $RPM_BUILD_ROOT
-mkdir $RPM_BUILD_ROOT
-%setup -n %{name}-%{samba_ver}
-%setup -T -D -a 50
-cp -ar samba-vscan-%{vscan_ver} examples/VFS/
-# untar my configs
-%setup -T -D -a 10
-###########
-### PATCHES
-###########
-# Makefiles-heimdal.diff
-%patch1
-%if %{use_keytab}
-# luke howards keytab-patch
-%patch2
-%endif
-# some com_err fixes
-%patch29
-%if %{suse_ver} > 821
-%patch30
-%endif
-# vscan patch
-%patch51
-# net ads password
-%patch32
-# temp Makefile (show more libs)
-%patch33
-# temp pdb-test.c
-%patch31
-# smbwrapper should use LIBDIR not BINDIR
-%patch34
-#find . -name CVS -print | xargs rm -rf
-#find . -name ".cvsignore" -print | xargs rm -rf
-find . -name "*.gd" -print | xargs rm -rvf
-find . -name "*.orig" -print | xargs rm -rvf
-%if %{ul_version} >= 1
- echo '#define VERSION "%samba_ver-UL"' > source/include/version.h
-%else
- echo '#define VERSION "%samba_ver-SuSE"' > source/include/version.h
-%endif
-
-%build %{name}-%{samba_ver}
-%{?suse_update_config:%{suse_update_config -f}}
-cd source
-./autogen.sh
-export CFLAGS="$RPM_OPT_FLAGS -Wall -O -D_GNU_SOURCE -D_LARGEFILE64_SOURCE"
-# debugging symbols
-%if %{make_devel}
-export CFLAGS="$RPM_OPT_FLAGS -g -Wall -O -D_GNU_SOURCE -D_LARGEFILE64_SOURCE"
-%endif
-%if %{krb_heimdal_05}
-export CFLAGS="$CFLAGS -I./include -I%{new_heimdal}/include "
-export CFLAGS="$CFLAGS -I%{new_openldap}/include "
-export CFLAGS="$CFLAGS -I%{new_sasl}/include "
-export LDFLAGS="$LDFLAGS -Wl,-rpath %{new_heimdal}/lib"
-export LDFLAGS="$LDFLAGS -Wl,-rpath %{new_openldap}/lib"
-export LDFLAGS="$LDFLAGS -Wl,-rpath %{new_sasl}/lib"
-%endif
-%ifarch ppc64
-export CFLAGS="$CFLAGS -mminimal-toc"
-%endif
-CONF_OPTS="\
- --enable-cups \
- --libdir=/usr/lib/samba \
- --localstatedir=/var/lib/samba \
- --mandir=%{_mandir} \
- --prefix=/usr \
- --sbindir=/usr/sbin \
- --sysconfdir=/etc/samba \
- --with-acl-support \
- --with-automount \
- --with-configdir=/etc/samba \
- --with-lockdir=/var/lib/samba \
- --with-logfilebase=/var/log/samba \
- --with-msdfs \
- --with-pam \
- --with-pam_smbpass \
- --with-piddir=/var/run/samba \
- --with-privatedir=/etc/samba \
- --with-quotas \
- --with-smbmount \
- --with-swatdir=/usr/share/samba/swat \
- --with-syslog \
- --with-utmp \
- --with-vfs \
- --with-winbind \
- --with-tdbsam \
- --with-expsam=xml,mysql \
- --with-profiling-data \
-%if %{use_keytab}
- --enable-keytab \
-%endif
-%if %{make_smbwrap}
- --with-smbwrapper \
-%endif
-%if %{make_python}
- --with-python=%{python_ver} \
-%endif
-%if %{make_shared_mod}
- --with-shared-modules=%{pdb_modules},%{rpc_modules} \
-%endif
-%if %{make_devel}
- --enable-developer \
- --enable-krb5developer \
-%endif
-"
-# --with-nisplus-home \
-# make sure we have a chance to find the krb5-config-tool
-export PATH="$PATH:/usr/lib/heimdal/bin"
-./configure $CONF_OPTS
-make \
- all \
- torture \
- nsswitch/libnss_wins.so \
- debug2html \
- libsmbclient \
- everything \
- bin/editreg
-# everything = nsswitch smbwrapper smbtorture debug2html smbfilter nsswitch/libnss_wins.so
-make modules
-make -C tdb tdbdump tdbtest tdbtool tdbtorture
-make talloctort
-%if %{make_wrepld}
-make bin/wrepld
-%endif
-%if %{make_doc}
-pushd `pwd`
-cd ../docs/docbook
-autoconf -f
-./configure
-# gracefully ignore errors...
-make -i manpages html html-single pdf htmlfaq htmlman
-# ps is not necessary, txt neither
-# everything = manpages ps pdf html-single html htmlman txt htmlfaq
-popd
-%endif
-# make examples in VFS,PDB
-pushd `pwd`
-cd ../examples/VFS/
-sh -x autogen.sh
-./configure
-popd
-EXAMPLEDIRS="pdb VFS"
-for i in $EXAMPLEDIRS; do make -C ../examples/$i; done
-%if %{make_vscan}
-export USE_KAVPSHAREDLIB=0
-export USE_INCLMKSDLIB=1
-for module in %{vscan_modules}; do
- make -C ../examples/VFS/samba-vscan-%{vscan_ver}/${module};
-done
-%endif
-%if %{make_python}
-make python_ext
-%endif
-%if %{make_cifsvfs}
-cd client
-export CFLAGS="$RPM_OPT_FLAGS -Wall -O -D_GNU_SOURCE -D_LARGEFILE64_SOURCE"
-gcc mount.cifs.c -o mount.cifs
-cd ..
-%endif
-
-%install
-mkdir -p \
- $RPM_BUILD_ROOT/%{DOCDIR} \
- $RPM_BUILD_ROOT/%{DOCDIR}-vscan \
- $RPM_BUILD_ROOT/%{DOCDIR}/docbook \
- $RPM_BUILD_ROOT/etc/{pam.d,init.d,samba} \
- $RPM_BUILD_ROOT/lib/security \
- $RPM_BUILD_ROOT/sbin \
- $RPM_BUILD_ROOT/usr/include \
- $RPM_BUILD_ROOT/usr/lib/%{python_ver}/lib-dynload \
- $RPM_BUILD_ROOT/usr/lib/samba/{vfs,pdb,vscan,rpc,auth,charset,idmap} \
- $RPM_BUILD_ROOT/usr/share/{man,samba/swat} \
- $RPM_BUILD_ROOT/usr/{bin,sbin} \
- $RPM_BUILD_ROOT/var/adm \
- $RPM_BUILD_ROOT/var/lib/samba/{netlogon,drivers/{W32X86,WIN40,W32ALPHA,W32MIPS,W32PPC},profiles} \
- $RPM_BUILD_ROOT/var/log/samba \
- $RPM_BUILD_ROOT/var/run/samba \
- $RPM_BUILD_ROOT/var/spool/samba
-cd source/
-make install \
- LIBDIR=$RPM_BUILD_ROOT/usr/lib/samba \
- LOGFILEBASE=$RPM_BUILD_ROOT/var/log/samba \
- CONFIGFILE=$RPM_BUILD_ROOT/etc/samba/smb.conf \
- LMHOSTSFILE=$RPM_BUILD_ROOT/etc/samba/lmhosts \
- SWATDIR=$RPM_BUILD_ROOT/usr/share/samba/swat \
- SBINDIR=$RPM_BUILD_ROOT/usr/sbin \
- LOCKDIR=$RPM_BUILD_ROOT/var/lib/samba \
- DRIVERFILE=$RPM_BUILD_ROOT/etc/samba/printers.def \
- BINDIR=$RPM_BUILD_ROOT/usr/bin \
- SMB_PASSWD_FILE=$RPM_BUILD_ROOT/etc/samba/smbpasswd \
- MANDIR=$RPM_BUILD_ROOT/usr/share/man
-make installmodules \
- LIBDIR=$RPM_BUILD_ROOT/usr/lib/samba
-cd ..
-# utility scripts
-%if %{head}
-scripts="creategroup cvslog.pl scancvslog.pl"
-%else
-scripts="scancvslog.pl"
-%endif
-mkdir -p examples/scripts
-for i in $scripts; do
- cp -a source/script/$i examples/scripts/
-done
-# configuration files
-%if %{ul_version} >= 1
- SUFFIX="UnitedLinux"
-%else
- SUFFIX="SuSE"
-%endif
-cat smb.conf.vendor | egrep -v '(^$$|^#)' > smb.conf
-mv smb.conf.vendor examples/smb.conf.${SUFFIX}
-install -m 644 smb.conf* $RPM_BUILD_ROOT/etc/samba/
-install -m 644 lmhosts $RPM_BUILD_ROOT/etc/samba/
-install -m 644 smbusers $RPM_BUILD_ROOT/etc/samba/
-install -m 600 smbpasswd -o root -g root $RPM_BUILD_ROOT/etc/samba/
-install -m 600 smbfstab -o root -g root $RPM_BUILD_ROOT/etc/samba/
-# pam
-install -m 644 samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
-# sambamount
-ln -sf /usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
-#cifsmount
-%if %{make_cifsvfs}
-install -m755 source/client/mount.cifs $RPM_BUILD_ROOT/sbin
-%endif
-# start scripts
-install rc.smb $RPM_BUILD_ROOT/etc/init.d/smb
-ln -sf ../../etc/init.d/smb $RPM_BUILD_ROOT/usr/sbin/rcsmb
-install rc.nmb $RPM_BUILD_ROOT/etc/init.d/nmb
-ln -sf ../../etc/init.d/nmb $RPM_BUILD_ROOT/usr/sbin/rcnmb
-install rc.smbfs $RPM_BUILD_ROOT/etc/init.d/smbfs
-ln -sf ../../etc/init.d/smbfs $RPM_BUILD_ROOT/usr/sbin/rcsmbfs
-install rc.winbind $RPM_BUILD_ROOT/etc/init.d/winbind
-ln -sf ../../etc/init.d/winbind $RPM_BUILD_ROOT/usr/sbin/rcwinbind
-%if %{make_wrepld}
-install rc.wrepl $RPM_BUILD_ROOT/etc/init.d/wrepl
-ln -sf ../../etc/init.d/wrepl $RPM_BUILD_ROOT/usr/sbin/rcwrepl
-cp -a source/bin/wrepld $RPM_BUILD_ROOT/usr/sbin/
-%endif
-# libnss_wins.so
-cp source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/lib/libnss_wins.so.2
-ln -sf /lib/libnss_wins.so.2 $RPM_BUILD_ROOT/lib/libnss_wins.so
-# winbind stuff
-cp -a source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/lib/security/
-cp -a source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/lib/libnss_winbind.so.2
-cp -a source/bin/winbindd $RPM_BUILD_ROOT/usr/sbin/
-ln -s /lib/libnss_winbind.so.2 $RPM_BUILD_ROOT/lib/libnss_winbind.so
-# pam_smbpass
-cp -a source/bin/pam_smbpass.so $RPM_BUILD_ROOT/lib/security/
-# smbfilter
-cp -a source/bin/smbfilter $RPM_BUILD_ROOT/usr/bin/
-# editreg
-cp -a source/bin/editreg $RPM_BUILD_ROOT/usr/bin/
-# install libsmbclient
-install -m0755 source/bin/libsmbclient.a $RPM_BUILD_ROOT/%{_libdir}
-install -m0755 source/bin/libsmbclient.so $RPM_BUILD_ROOT/%{_libdir}/libsmbclient.so.0
-ln -s /usr/lib/libsmbclient.so.0 $RPM_BUILD_ROOT/%{_libdir}/libsmbclient.so
-install -m0644 source/include/libsmbclient.h $RPM_BUILD_ROOT/%{_includedir}
-# install nsswitch-headers (for squid, etc.)
-mkdir -p $RPM_BUILD_ROOT/%{_includedir}/samba/nsswitch
-cp source/nsswitch/*.h $RPM_BUILD_ROOT/%{_includedir}/samba/nsswitch/
-# install smbtorture and other test-programs
-install -m0755 source/bin/smbtorture $RPM_BUILD_ROOT/usr/bin/
-install -m0755 source/bin/talloctort $RPM_BUILD_ROOT/usr/bin/
-install -m0755 source/bin/{msgtest,masktest,locktest*} $RPM_BUILD_ROOT/usr/bin/
-install -m0755 source/bin/{vfstest,nsstest} $RPM_BUILD_ROOT/usr/bin/
-# install tdb tools
-install -m0755 source/tdb/{tdbdump,tdbtest,tdbtool,tdbtorture} $RPM_BUILD_ROOT/usr/bin/
-# install VFS-modules
-install -m0755 examples/VFS/*.so $RPM_BUILD_ROOT/%{_libdir}/samba/vfs/
-# install PDB-modules
-install -m0755 examples/pdb/pdb_test.so $RPM_BUILD_ROOT/%{_libdir}/samba/pdb/
-%if %{make_vscan}
-# install VSCAN-vfs-modules
-install -m0755 examples/VFS/samba-vscan-%{vscan_ver}/*/*.so $RPM_BUILD_ROOT/%{_libdir}/samba/vscan/
-%endif
-# make examples clean
-VFS="$RPM_BUILD_DIR/%{name}-%{samba_ver}/examples/VFS"
-VSCAN="$VFS/samba-vscan-%{vscan_ver}"
-PDB="$RPM_BUILD_DIR/%{name}-%{samba_ver}/examples/pdb"
-dirs="$PDB $SAM $VFS"
-(for i in $dirs; do make -C $i clean; done)
-%if %{make_vscan}
-(for i in %{vscan_modules}; do make -C $VSCAN/$i clean; done)
-%endif
-# install python
-%if %{make_python}
-cp -a source/build/lib.*/samba $RPM_BUILD_ROOT/usr/lib/%{python_ver}/lib-dynload/
-find source/python -name CVS -print | xargs rm -rf
-find source/python -name ".cvsignore" -print | xargs rm -rf
-%endif
-# whats this ?
-install -m0755 source/bin/debug2html $RPM_BUILD_ROOT/usr/bin/
-# install smbwrapper
-%if %{make_smbwrap}
-install -m0755 source/bin/smbwrapper.so $RPM_BUILD_ROOT/%{_libdir}/samba/
-install -m0755 source/bin/smbsh $RPM_BUILD_ROOT/usr/bin/
-%endif
-##############
-# cleanup docs
-##############
-#chmod 644 `find docs examples -type f`
-#chmod 755 `find docs examples -type d`
-#find . -name CVS -print | xargs rm -rf
-#find . -name ".cvsignore" -print | xargs rm -rf
-mv COPYING Manifest README Read-Manifest-Now Roadmap WHATSNEW.txt $RPM_BUILD_ROOT/%{DOCDIR}/
-cp source/msdfs/README $RPM_BUILD_ROOT/%{DOCDIR}/README.msdfs
-cp source/smbwrapper/README $RPM_BUILD_ROOT/%{DOCDIR}/README.smbwrapper
-%if %{ul_version} >= 1
- SUFFIX="UnitedLinux"
-%else
- SUFFIX="SuSE"
-%endif
-cp README.vendor ${RPM_BUILD_ROOT}/%{DOCDIR}/README.${SUFFIX}
-# pam_smbpass is missing
-cp -a source/pam_smbpass/samples examples/pam_smbpass/
-cp -a source/pam_smbpass/{CHANGELOG,INSTALL,README,TODO} examples/pam_smbpass/
-# prepare docbook package
-cp -a docs/docbook/* $RPM_BUILD_ROOT/%{DOCBOOKDIR}
-#make -C $RPM_BUILD_ROOT/%{DOCBOOKDIR} clean
-rm -rf $RPM_BUILD_ROOT/%{DOCBOOKDIR}/autom4te.cache
-rm -rf $RPM_BUILD_ROOT/%{DOCBOOKDIR}/config.*
-# this is empty
-rm -rf docs/yodldocs
-rm -rf examples/VFS/samba-vscan-%{vscan_ver}
-# zip manpages at least
-gzip -f docs/manpages/*.[1-9]
-cp -a docs/* $RPM_BUILD_ROOT/%{DOCDIR}
-cp -a examples/ $RPM_BUILD_ROOT/%{DOCDIR}
-# save space...
-rm -r $RPM_BUILD_ROOT/%{SWATDIR}/using_samba
-ln -s %{DOCDIR}/htmldocs/using_samba $RPM_BUILD_ROOT/%{SWATDIR}
-# hm...
-cp $RPM_BUILD_ROOT/%{SWATDIR}/help/welcome.html $RPM_BUILD_ROOT/%{DOCDIR}/htmldocs/
-rm -r $RPM_BUILD_ROOT/%{SWATDIR}/help
-ln -s %{DOCDIR}/htmldocs $RPM_BUILD_ROOT/%{SWATDIR}/help
-# remove cvs
-find $RPM_BUILD_ROOT/%{DOCDIR} -name CVS -print | xargs rm -rf
-find $RPM_BUILD_ROOT/%{DOCDIR} -name ".cvsignore" -print | xargs rm -rf
-# finally build a file-list
-for file in $( find ${RPM_BUILD_ROOT}%{DOCDIR} -maxdepth 1); do
- # exclude %{DOCDIR} and docbook
- case "${file#${RPM_BUILD_ROOT}}" in
- %{DOCDIR}|%{DOCDIR}/docbook) continue ;;
- esac
- echo "%doc ${file#${RPM_BUILD_ROOT}}" >> ${RPM_BUILD_DIR}/%{name}-%{samba_ver}/filelist-doc
-done
-
-%post
-%{fillup_and_insserv smb}
-mkdir -p $RPM_BUILD_ROOT/var/adm/notify/messages
-cat << EOF > var/adm/notify/messages/samba-notify
-Achtung!
-This is %{name}-%{samba_ver}. Please do not run on production systems.
-You have been warned.
-EOF
-
-%post client
-%{fillup_and_insserv -fpy smbfs}
-%{fillup_only -ans samba client}
-
-%post winbind
-%{fillup_and_insserv winbind}
-
-%postun
-%{insserv_cleanup}
-
-%postun client
-%{insserv_cleanup}
-
-%postun winbind
-%{insserv_cleanup}
-
-%clean
-#make -C source realclean
-
-%files
-#/usr/bin/addtosmbpass
-#/usr/bin/convert_smbpasswd
-%dir /etc/samba
-%dir /usr/lib/samba
-%config /etc/init.d/nmb
-%config /etc/init.d/smb
-%config /etc/pam.d/samba
-%config(noreplace) /etc/samba/smbpasswd
-%config(noreplace) /etc/samba/smbusers
-%doc %{_mandir}/man1/smbcontrol.1.gz
-%doc %{_mandir}/man1/smbstatus.1.gz
-%doc %{_mandir}/man1/testparm.1.gz
-%doc %{_mandir}/man1/testprns.1.gz
-%doc %{_mandir}/man5/smbpasswd.5.gz
-%doc %{_mandir}/man7/samba.7.gz
-%doc %{_mandir}/man8/nmbd.8.gz
-%doc %{_mandir}/man8/pdbedit.8.gz
-%doc %{_mandir}/man8/smbd.8.gz
-%doc %{_mandir}/man8/smbpasswd.8.gz
-%doc %{_mandir}/man8/swat.8.gz
-%doc %{_mandir}/man8/tdbbackup.8.gz
-%{_includedir}/samba
-/lib/security/pam_smbpass.so
-/usr/bin/pdbedit
-/usr/bin/smbcontrol
-/usr/bin/smbpasswd
-/usr/bin/smbstatus
-/usr/bin/tdbbackup
-/usr/bin/tdbdump
-/usr/bin/tdbtest
-/usr/bin/tdbtool
-/usr/bin/testparm
-/usr/bin/testprns
-/usr/lib/samba/rpc
-/usr/lib/samba/vfs
-/usr/sbin/nmbd
-/usr/sbin/rcnmb
-/usr/sbin/rcsmb
-/usr/sbin/smbd
-/usr/sbin/swat
-/usr/share/samba
-/var/lib/samba
-/var/log/samba
-/var/run/samba
-/var/spool/samba
-
-%files client
-%config /etc/init.d/smbfs
-%config(noreplace) /etc/samba/lmhosts
-%config(noreplace) /etc/samba/smb.conf
-%config(noreplace) /etc/samba/smbfstab
-%dir /etc/samba
-%dir /usr/lib/samba
-%doc %{_mandir}/man1/editreg.1.gz
-%doc %{_mandir}/man1/findsmb.1.gz
-%doc %{_mandir}/man1/nmblookup.1.gz
-%doc %{_mandir}/man1/profiles.1.gz
-%doc %{_mandir}/man1/rpcclient.1.gz
-%doc %{_mandir}/man1/smbcacls.1.gz
-%doc %{_mandir}/man1/smbclient.1.gz
-%doc %{_mandir}/man1/smbcquotas.1.gz
-%doc %{_mandir}/man1/smbtar.1.gz
-%doc %{_mandir}/man1/smbtree.1.gz
-%doc %{_mandir}/man5/lmhosts.5.gz
-%doc %{_mandir}/man5/smb.conf.5.gz
-%doc %{_mandir}/man7/Samba.7.gz
-%doc %{_mandir}/man8/net.8.gz
-%doc %{_mandir}/man8/smbmnt.8.gz
-%doc %{_mandir}/man8/smbmount.8.gz
-%doc %{_mandir}/man8/smbspool.8.gz
-%doc %{_mandir}/man8/smbumount.8.gz
-/sbin/mount.smbfs
-/usr/bin/editreg
-/usr/bin/findsmb
-/usr/bin/net
-/usr/bin/nmblookup
-/usr/bin/profiles
-/usr/bin/rpcclient
-/usr/bin/smbcacls
-/usr/bin/smbclient
-/usr/bin/smbcquotas
-/usr/bin/smbfilter
-/usr/bin/smbmnt
-/usr/bin/smbmount
-/usr/bin/smbspool
-/usr/bin/smbtar
-/usr/bin/smbtree
-/usr/bin/smbumount
-/usr/lib/samba/lowcase.dat
-/usr/lib/samba/upcase.dat
-/usr/lib/samba/valid.dat
-/usr/sbin/rcsmbfs
-%if %{make_smbwrap}
-/usr/bin/smbsh
-%doc %{_mandir}/man1/smbsh.1.gz
-/usr/lib/samba/smbwrapper.so
-%endif
-
-%files winbind
-%config /etc/init.d/winbind
-%config(noreplace) /etc/samba/smb.conf
-%dir /etc/samba
-%doc %{_mandir}/man1/wbinfo.1.gz
-%doc %{_mandir}/man8/winbindd.8.gz
-%doc %{_mandir}/man1/ntlm_auth.1.gz
-/lib/libnss_winbind.so*
-/lib/libnss_wins.so*
-/lib/security/pam_winbind.so
-/usr/bin/ntlm_auth
-/usr/bin/wbinfo
-/usr/sbin/rcwinbind
-/usr/sbin/winbindd
-
-%files utils
-%doc %{_mandir}/man1/vfstest.1.gz
-/usr/bin/debug2html
-/usr/bin/locktest
-/usr/bin/locktest2
-/usr/bin/masktest
-/usr/bin/msgtest
-/usr/bin/nsstest
-/usr/bin/smbtorture
-/usr/bin/talloctort
-/usr/bin/tdbtorture
-/usr/bin/vfstest
-
-%files doc -f filelist-doc
-%dir /usr/share/doc/packages/samba3
-
-%files docbook
-%docdir %{DOCBOOKDIR}
-%{DOCBOOKDIR}
-%dir /usr/share/doc/packages/samba3
-
-%files pdb
-/usr/lib/samba/pdb
-%doc examples/pdb/{Makefile,README,pdb_test.c}
-%doc examples/pdb/{mysql/mysql.dump,mysql/smb.conf}
-%if %{make_cifsvfs}
-
-%files cifsmount
-/sbin/mount.cifs
-%endif
-%if %{make_wrepld}
-
-%files wrepld
-%config /etc/init.d/wrepl
-/usr/sbin/rcwrepl
-/usr/sbin/wrepld
-%endif
-%if %{make_vscan}
-
-%files vscan
-/usr/lib/samba/vscan
-%doc samba-vscan-%{vscan_ver}/{AUTHORS,COPYING,ChangeLog,FAQ,NEWS,README,TODO}
-%endif
-%if %{make_python}
-
-%files python
-%doc source/python/README
-%doc source/python/examples
-%doc source/python/gprinterdata
-%doc source/python/gtdbtool
-%doc source/python/gtkdictbrowser.py
-/usr/lib/%{python_ver}/lib-dynload/samba
-%endif
-
-%files -n libsmbclient
-%{_libdir}/libsmbclient.so.*
-
-%files -n libsmbclient-devel
-%{_includedir}/libsmbclient.h
-%{_libdir}/libsmbclient.a
-%{_libdir}/libsmbclient.so
-
-%description
-samba3
-
-
-%description client
-samba3-client
-
-
-%description winbind
-samba3-winbind
-
-
-%description utils
-samba3-utils
-
-
-%description doc
-samba3-doc
-
-
-%description docbook
-samba3-docbook
-
-
-%description pdb
-samba3-pdb
-
-%if %{make_cifsvfs}
-
-%description cifsmount
-samba3-cifsmount
-
-%endif
-%if %{make_vscan}
-
-%description vscan
-samba3-vscan
-
-%endif
-%if %{make_python}
-
-%description python
-samba3-python
-
-%endif
-%if %{make_wrepld}
-
-%description wrepld
-samba3-wrepld
-
-%endif
-
-%description -n libsmbclient
-This package includes the libsmbclient library.
-
-Authors:
---------
- The Samba Team <samba@samba.org>
-
-
-%description -n libsmbclient-devel
-This package contains static libraries and header files needed to develop
-programs which make use of the smbclient programming interface.
-
-Authors:
---------
- The Samba Team <samba@samba.org>
-
-
diff --git a/packaging/bin/update-pkginfo b/packaging/bin/update-pkginfo
index 47f3c3c306b..8432173cc88 100755
--- a/packaging/bin/update-pkginfo
+++ b/packaging/bin/update-pkginfo
@@ -8,9 +8,13 @@ if [ $# -ne 2 ]; then
exit 1
fi
-for f in `du -a | awk '{print $2}' | grep \.tmpl$`; do
- f2=`echo $f | sed s/.tmpl//g`
- echo $f2
- sed -e s/PVERSION/$VERSION/g -e s/PRELEASE/$RELEASE/g < $f > $f2
+for f in */*/*.tmpl; do
+ f2=`echo $f | sed s/.tmpl//g`
+ echo $f2
+ sed -e s/PVERSION/$VERSION/g -e s/PRELEASE/$RELEASE/g < $f > $f2
+done
+for f in */*.tmpl; do
+ f2=`echo $f | sed s/.tmpl//g`
+ echo $f2
+ sed -e s/PVERSION/$VERSION/g -e s/PRELEASE/$RELEASE/g < $f > $f2
done
-
diff --git a/pcp/Makefile b/pcp/Makefile
index e4b5fb75064..e01731b2565 100644
--- a/pcp/Makefile
+++ b/pcp/Makefile
@@ -47,9 +47,7 @@ CFLAGS = $(DEBUG)
LDOPTS =
LDLIBS = -lpcp_pmda -lpcp
DSOOPTS = -shared
-LDIRT = profile.h metrics.h so_locations *.log help.dir help.pag *.pmda_$(IAM).so
-
-PROFILEHEADER = ../source/include/smbprofile.h
+LDIRT = metrics.h so_locations *.log help.dir help.pag *.pmda_$(IAM).so
INSTALL = install
CC = cc
@@ -67,8 +65,5 @@ $(LIBTARGET): profile.h metrics.h $(CFILES)
metrics.h: profile.h mkheader.pl
./mkheader.pl
-profile.h: $(PROFILEHEADER)
- ln -s $(PROFILEHEADER) $@
-
clobber clean:
rm -f $(LDIRT) $(TARGETS)
diff --git a/pcp/README b/pcp/README
index 97d8125a53e..5a58626a97b 100644
--- a/pcp/README
+++ b/pcp/README
@@ -3,7 +3,7 @@ samba PMDA
This PMDA is a sample that illustrates how a simple samba monitor
PMDA might be constructed, using a shared memory segment to transfer
-information about transaction activity from the smb daemon.
+information about transaction activity from the smb and nmbd daemons.
Note:
This PMDA may be remade from source and hence requires
@@ -77,11 +77,14 @@ De-installation
Making something happen
=======================
-The application "smbd" updates the shared memory segment to add
-profile information about smbd. By default updating is disabled.
+Samba must have been compiled with profiling data collection enabled.
+Use the --with-profiling-data option for configure to enable this feature.
+
+The applications "nmbd" and "smbd" update the shared memory segment to add
+profile information about nmbd and smbd. By default updating is disabled.
To start updating of the shared memory segment you need to run the
-smbcontrol command to turn on profiling for one or more smbd processes
-(see the man page for smbcontrol).
+smbcontrol command to turn on profiling for nmbd or one or more smbd
+processes (see the man page for smbcontrol).
diff --git a/source/.dmallocrc b/source/.dmallocrc
deleted file mode 100644
index 5e5c45e1244..00000000000
--- a/source/.dmallocrc
+++ /dev/null
@@ -1,2 +0,0 @@
-samba allow-free-null, log-stats, log-non-free, log-trans, \
- check-fence, check-heap, check-lists, error-abort \ No newline at end of file
diff --git a/source/.indent.pro b/source/.indent.pro
new file mode 100755
index 00000000000..43948ca263d
--- /dev/null
+++ b/source/.indent.pro
@@ -0,0 +1,14 @@
+-cli8 -cbi0 -bli0 -bl -i8 -npsl -npcs -bbo -ncs -hnl
+-T BOOL
+-T pstring
+-T fstring
+-T tdb_len
+-T tdb_off
+-T uint32
+-T uint16
+-T uint8
+-T LDAPDB
+-T PLDAPDB
+-T POLICY_HND
+-T UNISTR2
+-T DOM_SID
diff --git a/source/Makefile.in b/source/Makefile.in
index d1007e4e484..584911e7594 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -1,39 +1,26 @@
-#########################################################################
+##########################################################################
# Makefile.in for Samba - rewritten for autoconf support
# Copyright Andrew Tridgell 1992-1998
-# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
-# Copyright Andrew Bartlett 2002
-# Copyright (C) 2003 Jim McDonough <jmcd@us.ibm.com>
-# Copyright (C) 2002-2003 Jelmer Vernooij <jelmer@samba.org>
###########################################################################
prefix=@prefix@
exec_prefix=@exec_prefix@
+mandir=@mandir@
+sysconfdir=@sysconfdir@
LIBS=@LIBS@
+LDAPLIBS=@LDAPLIBS@
CC=@CC@
-SHLD=@SHLD@
+SHLD=@SHLD@
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
-EXEEXT=@EXEEXT@
LDFLAGS=@LDFLAGS@
-AR=@AR@
-LDSHFLAGS=@LDSHFLAGS@ @LDFLAGS@
-WINBIND_NSS_LDSHFLAGS=@WINBIND_NSS_LDSHFLAGS@ @LDFLAGS@
AWK=@AWK@
DYNEXP=@DYNEXP@
-PYTHON=@PYTHON@
-PERL=@PERL@
+EXEEXT=@EXEEXT@
TERMLDFLAGS=@TERMLDFLAGS@
TERMLIBS=@TERMLIBS@
-PRINT_LIBS=@PRINT_LIBS@
-AUTH_LIBS=@AUTH_LIBS@
-ACL_LIBS=@ACL_LIBS@
-PASSDB_LIBS=@PASSDB_LIBS@
-IDMAP_LIBS=@IDMAP_LIBS@
-KRB5LIBS=@KRB5_LIBS@
-LDAP_LIBS=@LDAP_LIBS@
LINK=$(CC) $(FLAGS) $(LDFLAGS)
@@ -42,34 +29,21 @@ INSTALLCLIENTCMD_SH=@INSTALLCLIENTCMD_SH@
INSTALLCLIENTCMD_A=@INSTALLCLIENTCMD_A@
VPATH=@srcdir@
-srcdir=@abs_srcdir@
-builddir=@abs_builddir@
+srcdir=@srcdir@
+builddir=@builddir@
+top_builddir=.
SHELL=/bin/sh
-DESTDIR=/
-
-# XXX: Perhaps this should be @SHELL@ instead -- apparently autoconf
-# will search for a POSIX-compliant shell, and that might not be
-# /bin/sh on some platforms. I guess it's not a big problem -- mbp
-
-# See the autoconf manual "Installation Directory Variables" for a
-# discussion of the subtle use of these variables.
BASEDIR= @prefix@
BINDIR = @bindir@
+DATADIR = @datadir@
# sbindir is mapped to bindir when compiling SAMBA in 2.0.x compatibility mode.
SBINDIR = @sbindir@
LIBDIR = @libdir@
-VFSLIBDIR = $(LIBDIR)/vfs
-PDBLIBDIR = $(LIBDIR)/pdb
-RPCLIBDIR = $(LIBDIR)/rpc
-IDMAPLIBDIR = $(LIBDIR)/idmap
-CHARSETLIBDIR = $(LIBDIR)/charset
-AUTHLIBDIR = $(LIBDIR)/auth
-CONFIGLIBDIR = $(LIBDIR)/config
-CONFIGDIR = @configdir@
VARDIR = @localstatedir@
+CONFIGDIR = @configdir@
MANDIR = @mandir@
-DATADIR = @datadir@
+INCLUDEDIR = @includedir@
# The permissions to give the executables
INSTALLPERMS = 0755
@@ -80,12 +54,13 @@ INSTALLPERMS = 0755
LOGFILEBASE = @logfilebase@
CONFIGFILE = $(CONFIGDIR)/smb.conf
LMHOSTSFILE = $(CONFIGDIR)/lmhosts
-
+DRIVERFILE = $(CONFIGDIR)/printers.def
+PASSWD_PROGRAM = @passwd_program@
# This is where smbpasswd et al go
PRIVATEDIR = @privatedir@
SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd
-PRIVATE_DIR = $(PRIVATEDIR)
+TDB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd.tdb
# This is where SWAT images and help files go
SWATDIR = @swatdir@
@@ -93,305 +68,158 @@ SWATDIR = @swatdir@
# the directory where lock files go
LOCKDIR = @lockdir@
-# the directory where pid files go
+# the directorty where pid files go
PIDDIR = @piddir@
-# man pages language(s)
-man_langs = "@manlangs@"
-LIBSMBCLIENT=bin/libsmbclient.a @LIBSMBCLIENT_SHARED@
+# libsmbclient support here
+BLDSHARED = @BLDSHARED@
LIBSMBCLIENT_MAJOR=0
LIBSMBCLIENT_MINOR=1
-
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper -I. $(CPPFLAGS) -I$(srcdir)
-FLAGS2 =
-FLAGS3 =
-FLAGS4 =
-FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4)
-FLAGS = $(ISA) $(FLAGS5)
-
-PASSWD_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" -DPRIVATE_DIR=\"$(PRIVATE_DIR)\"
-PATH_FLAGS1 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DSBINDIR=\"$(SBINDIR)\"
-PATH_FLAGS2 = $(PATH_FLAGS1) -DBINDIR=\"$(BINDIR)\" -DDRIVERFILE=\"$(DRIVERFILE)\"
-PATH_FLAGS3 = $(PATH_FLAGS2) -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
-PATH_FLAGS4 = $(PATH_FLAGS3) -DSWATDIR=\"$(SWATDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DPIDDIR=\"$(PIDDIR)\"
-PATH_FLAGS5 = $(PATH_FLAGS4) -DLIBDIR=\"$(LIBDIR)\" \
- -DLOGFILEBASE=\"$(LOGFILEBASE)\" -DSHLIBEXT=\"@SHLIBEXT@\"
-PATH_FLAGS6 = $(PATH_FLAGS5) -DCONFIGDIR=\"$(CONFIGDIR)\"
-PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS)
-
-# Note that all executable programs now provide for an optional executable suffix.
-
-SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@
-
-BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
- bin/testparm@EXEEXT@ bin/testprns@EXEEXT@ bin/smbstatus@EXEEXT@
-BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \
- bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/tdbdump@EXEEXT@
-BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
- bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \
- bin/smbcquotas@EXEEXT@
-
-# editreg removed from standard build until it is portable. It needs a major rewrite to
-# achieve this (tridge)
-# bin/editreg@EXEEXT@
-
-TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \
- bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \
- bin/locktest2@EXEEXT@ bin/nsstest@EXEEXT@ bin/vfstest@EXEEXT@
-
-BIN_PROGS = $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) @EXTRA_BIN_PROGS@
-
-EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ bin/talloctort@EXEEXT@ \
- bin/log2pcap@EXEEXT@
-
-SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@
-
-SCRIPTS = $(srcdir)/script/smbtar $(builddir)/script/findsmb
-
-VFS_MODULES = @VFS_MODULES@
-PDB_MODULES = @PDB_MODULES@
-RPC_MODULES = @RPC_MODULES@
-IDMAP_MODULES = @IDMAP_MODULES@
-CHARSET_MODULES = @CHARSET_MODULES@
-AUTH_MODULES = @AUTH_MODULES@
-CONFIG_MODULES = @CONFIG_MODULES@
-MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) $(CONFIG_MODULES)
+# The directory where code page definition files go
+CODEPAGEDIR = @codepagedir@
+
+# The current codepage definition list.
+CODEPAGELIST= 437 737 775 850 852 861 932 866 949 950 936 1251 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI8-R 857 ISO8859-9 \
+ ISO8859-13 ISO8859-15 1125 KOI8-U
+
+PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" -DTDB_PASSWD_FILE=\"$(TDB_PASSWD_FILE)\"
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DLOGFILEBASE=\"$(LOGFILEBASE)\"
+FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
+FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
+FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DPIDDIR=\"$(PIDDIR)\" -DLIBDIR=\"$(LIBDIR)\"
+FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
+FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS)
+FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS)
+
+WINBIND_PROGS = @WINBIND_TARGETS@
+WINBIND_SPROGS = @WINBIND_STARGETS@
+WINBIND_PAM_PROGS = @WINBIND_PAM_TARGETS@
+WINBIND_LPROGS = @WINBIND_LTARGETS@
+
+SPROGS = bin/smbd$(EXEEXT) bin/nmbd$(EXEEXT) bin/swat$(EXEEXT)
+PROGS1 = bin/smbclient$(EXEEXT) bin/smbspool$(EXEEXT) bin/testparm$(EXEEXT) bin/testprns$(EXEEXT) bin/smbstatus$(EXEEXT) \
+ bin/smbcontrol$(EXEEXT) bin/tdbbackup$(EXEEXT) bin/make_printerdef$(EXEEXT) @RUNPROG@
+PROGS2 = bin/smbpasswd$(EXEEXT) bin/make_smbcodepage$(EXEEXT) bin/rpcclient$(EXEEXT) bin/make_unicodemap$(EXEEXT) \
+ bin/smbcacls$(EXEEXT) @WRAPPROG@ @WRAP@ @WRAP32@ @PAM_MOD@ @PDBEDIT@ @LIBSMBCLIENT@
+MPROGS = @MPROGS@
+LPROGS = $(WINBIND_PAM_PROGS) $(WINBIND_LPROGS)
+PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup$(EXEEXT)
+TORTURE_PROGS = bin/smbtorture$(EXEEXT) bin/msgtest$(EXEEXT) bin/masktest$(EXEEXT) bin/locktest$(EXEEXT) bin/locktest2$(EXEEXT)
+SHLIBS = @LIBSMBCLIENT@
+
+SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/findsmb
+
+QUOTAOBJS=@QUOTAOBJS@
######################################################################
# object file lists
######################################################################
TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o
-TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o tdb/tdbback.o
+TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o
-SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@
-
-LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \
- lib/getsmbpass.o lib/interface.o lib/md4.o \
- lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o \
+LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
+ lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \
+ lib/interfaces.o lib/pidfile.o lib/replace.o \
lib/signal.o lib/system.o lib/sendfile.o lib/time.o \
- lib/ufc.o lib/genrand.o lib/username.o \
- lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \
- lib/bitmap.o lib/crc32.o lib/snprintf.o lib/dprintf.o \
- lib/xfile.o lib/wins_srv.o \
- lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \
- lib/util_unistr.o lib/util_file.o lib/data_blob.o \
- lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
+ lib/ufc.o lib/genrand.o lib/username.o lib/util_getent.o lib/access.o lib/smbrun.o \
+ lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \
+ lib/util_str.o lib/util_sid.o \
+ lib/util_unistr.o lib/util_file.o \
+ lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
- lib/ms_fnmatch.o lib/select.o lib/messages.o \
- lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
- lib/md5.o lib/hmacmd5.o lib/iconv.o \
- nsswitch/wb_client.o nsswitch/wb_common.o \
- lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
- lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
- lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
- lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o \
- lib/genparser.o lib/genparser_samba.o
-
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
-
-LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
+ lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \
+ lib/pam_errors.o nsswitch/wb_client.o nsswitch/wb_common.o $(TDB_OBJ)
READLINE_OBJ = lib/readline.o
-# Also depends on $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
-# Be sure to include them into your application
-POPT_LIB_OBJ = lib/popt_common.o
-
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
- ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o
-
-PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o param/modconf.o
-
-KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o
-
-LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \
- libads/krb5_setpw.o libads/ldap_user.o \
- libads/ads_struct.o \
- libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \
- libads/ads_ldap.o libads/authdata.o
+ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o ubiqx/debugparse.o
-LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o
-
-SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o
-
-LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \
- libsmb/namequery.o libsmb/conncache.o
-
-LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlm_check.o \
- libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o
+PARAM_OBJ = param/loadparm.o param/params.o
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
- libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \
- libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
- libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
- libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
- libsmb/clistr.o lib/util_seaccess.o \
- libsmb/cliquota.o libsmb/clifsinfo.o \
- libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
- libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
- libsmb/doserr.o \
- $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
-
-LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
- rpc_client/cli_netlogon.o rpc_client/cli_srvsvc.o \
- rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \
- rpc_client/cli_reg.o rpc_client/cli_pipe.o \
- rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
- rpc_client/cli_ds.o rpc_client/cli_echo.o \
- rpc_client/cli_shutdown.o rpc_client/cli_epmapper.o
-
-REGOBJS_OBJ = registry/reg_objects.o
-REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
- registry/reg_db.o
-
-RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o
-
-RPC_NETLOG_OBJ = rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o
-
-RPC_SAMR_OBJ = rpc_server/srv_samr.o rpc_server/srv_samr_nt.o \
- rpc_server/srv_samr_util.o
-
-RPC_REG_OBJ = rpc_server/srv_reg.o rpc_server/srv_reg_nt.o
-
-RPC_LSA_DS_OBJ = rpc_server/srv_lsa_ds.o rpc_server/srv_lsa_ds_nt.o
-
-RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
-
-RPC_WKS_OBJ = rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
-
-RPC_DFS_OBJ = rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
-RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
-
-RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
- rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
-
-RPC_ECHO_OBJ = rpc_server/srv_echo.o rpc_server/srv_echo_nt.o
-
-RPC_EPMAPPER_OBJ = rpc_server/srv_epmapper.o rpc_server/srv_epmapper_nt.o
-
-RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ)
+ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
+ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
+ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
+ libsmb/namequery.o libsmb/nmblib.o libsmb/clistr.o \
+ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
+ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
+ libsmb/clioplock.o libsmb/errormap.o libsmb/doserr.o \
+ libsmb/passchange.o libsmb/unexpected.o $(RPC_PARSE_OBJ1) \
+ libsmb/namecache.o
+
+LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \
+ libsmb/cli_netlogon.o libsmb/cli_srvsvc.o libsmb/cli_dfs.o \
+ libsmb/cli_reg.o \
+ rpc_client/cli_pipe.o libsmb/cli_pipe_util.o
+
+RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
+ rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o \
+ rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o rpc_server/srv_reg_nt.o \
+ rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \
+ rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \
+ rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \
+ rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o rpc_client/cli_spoolss_notify.o
# this includes only the low level parse code, not stuff
# that requires knowledge of security contexts
RPC_PARSE_OBJ1 = rpc_parse/parse_prs.o rpc_parse/parse_sec.o \
- rpc_parse/parse_misc.o
+ rpc_parse/parse_misc.o
RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \
rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
- rpc_parse/parse_wks.o rpc_parse/parse_ds.o \
- rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
- rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
- rpc_parse/parse_epmapper.o $(REGOBJS_OBJ)
-
-
-RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
-
-LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o smbd/tdbutil.o
-
-GUMS_OBJ = sam/gums.o sam/gums_api.o sam/gums_helper.o @GUMS_STATIC@
+ rpc_parse/parse_wks.o \
+ rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o
-PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
+RPC_CLIENT_OBJ = rpc_client/cli_netlogon.o rpc_client/cli_pipe.o \
+ rpc_client/cli_login.o \
+ rpc_client/cli_trust.o
-PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
- passdb/util_sam_sid.o passdb/pdb_compat.o \
- passdb/privileges.o passdb/lookup_sid.o \
- passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o
+LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
-XML_OBJ = passdb/pdb_xml.o
-MYSQL_OBJ = passdb/pdb_mysql.o
-PGSQL_OBJ = passdb/pdb_pgsql.o
-DEVEL_HELP_WEIRD_OBJ = modules/weird.o
-CP850_OBJ = modules/CP850.o
-CP437_OBJ = modules/CP437.o
-CHARSET_MACOSXFS_OBJ = modules/charset_macosxfs.o
-
-GROUPDB_OBJ = groupdb/mapping.o
+PASSDB_OBJ = passdb/passdb.o passdb/secrets.o \
+ passdb/pass_check.o passdb/smbpassfile.o \
+ passdb/machine_sid.o passdb/pdb_smbpasswd.o \
+ passdb/pampass.o passdb/pdb_tdb.o passdb/pdb_ldap.o \
+ passdb/pdb_nisplus.o
PROFILE_OBJ = profile/profile.o
-PROFILES_OBJ = utils/profiles.o
-EDITREG_OBJ = utils/editreg.o
OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o
-VFS_AUDIT_OBJ = modules/vfs_audit.o
-VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
-VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o
-VFS_RECYCLE_OBJ = modules/vfs_recycle.o
-VFS_NETATALK_OBJ = modules/vfs_netatalk.o
-VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o
-VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
-VFS_CAP_OBJ = modules/vfs_cap.o
-VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
-VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
-VFS_AFSACL_OBJ = modules/vfs_afsacl.o
-
-PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
-
-SLCACHE_OBJ = libsmb/samlogon_cache.o
-
-DCUTIL_OBJ = libsmb/namequery_dc.o libsmb/trustdom_cache.o libsmb/trusts_util.o
-
-AUTH_BUILTIN_OBJ = auth/auth_builtin.o
-AUTH_DOMAIN_OBJ = auth/auth_domain.o
-AUTH_SAM_OBJ = auth/auth_sam.o
-AUTH_RHOSTS_OBJ = auth/auth_rhosts.o
-AUTH_SERVER_OBJ = auth/auth_server.o
-AUTH_UNIX_OBJ = auth/auth_unix.o
-AUTH_WINBIND_OBJ = auth/auth_winbind.o
-
-AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \
- auth/auth_ntlmssp.o \
- $(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
-
-MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
-
-CONFIG_LDAP_OBJ = param/config_ldap.o
-
-SMBD_OBJ_MAIN = smbd/server.o
-
-BUILDOPT_OBJ = smbd/build_options.o
-
-SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
- smbd/utmp.o smbd/session.o \
- smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
- smbd/ipc.o smbd/lanman.o smbd/negprot.o \
- smbd/message.o smbd/nttrans.o smbd/pipes.o \
- smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \
- smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
- smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \
- smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
- smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
- smbd/process.o smbd/service.o smbd/error.o \
- printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
- lib/sysquotas_xfs.o lib/sysquotas_4A.o \
- smbd/change_trust_pw.o smbd/fake_file.o \
- smbd/quotas.o smbd/ntquotas.o lib/afs.o smbd/msdfs.o \
- lib/afs_settoken.o \
- $(MANGLE_OBJ) @VFS_STATIC@
-
-SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
- $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
- $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
- $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
- $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
- $(LIBMSRPC_OBJ) \
- $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
- $(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
+SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
+ smbd/utmp.o smbd/session.o \
+ smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
+ smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/mangle_hash2.o smbd/mangle_hash.o \
+ smbd/mangle_map.o smbd/negprot.o smbd/message.o smbd/nttrans.o smbd/pipes.o \
+ smbd/reply.o smbd/trans2.o smbd/uid.o \
+ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
+ smbd/blocking.o smbd/sec_ctx.o \
+ smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
+ smbd/posix_acls.o lib/sysacls.o \
+ smbd/process.o smbd/service.o smbd/error.o \
+ printing/printfsp.o lib/util_seaccess.o \
+ libsmb/cli_pipe_util.o
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
- printing/print_cups.o printing/print_generic.o \
- printing/lpq_parse.o printing/load.o
+ printing/print_cups.o printing/print_generic.o \
+ printing/lpq_parse.o printing/load.o
+
+PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o
+
+MSDFS_OBJ = msdfs/msdfs.o
+
+SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
+ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(RPC_CLIENT_OBJ) \
+ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
+ $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) $(NOTIFY_OBJ)
-PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o printing/notify.o \
- printing/printing_db.o
-SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
nmbd/nmbd_browsesync.o nmbd/nmbd_elections.o \
@@ -405,232 +233,162 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
-NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
+ $(PROFILE_OBJ) $(LIB_OBJ)
-WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
- wrepld/partners.o
+SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
+ web/swat.o $(PRINTING_OBJ) $(LIBSMB_OBJ) $(LOCKING_OBJ) \
+ $(PARAM_OBJ) $(PASSDB_OBJ) $(RPC_PARSE_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \
- $(LIBSAMBA_OBJ)
+SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
+ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
-SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
- web/swat.o web/neg_lang.o
+MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
- $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
- $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \
- libsmb/passchange.o lib/dummyroot.o
+MAKE_UNICODEMAP_OBJ = utils/make_unicodemap.o $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(SECRETS_OBJ) $(LIBSAMBA_OBJ) lib/dummyroot.o libsmb/errormap.o
-
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
- printing/notify.o printing/printing_db.o lib/dummyroot.o libsmb/errormap.o
-
-SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
TESTPARM_OBJ = utils/testparm.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
+ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
- $(LIB_NONSMBD_OBJ)
-
-SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o $(PARAM_OBJ) $(SECRETS_OBJ) \
- $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
- $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) lib/dummyroot.o
+ $(LIB_OBJ)
-PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
+SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \
+ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
+ $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ) \
+ libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_pipe_util.o
-SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ) $(SECRETS_OBJ)
+PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ)
RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
- rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
- rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
- rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
- rpcclient/display_sec.o rpcclient/cmd_ds.o \
- rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o \
- rpcclient/cmd_epmapper.o
-
+ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
+ rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
+ rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
+ rpc_client/cli_login.o rpc_client/cli_netlogon.o \
+ rpcclient/display_sec.o
+
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
- $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
- $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
+ $(READLINE_OBJ)
-PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \
- nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \
- lib/snprintf.@PICSUFFIX@
+PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
-SMBW_OBJ1 = smbwrapper/smbw.o \
+SMBW_OBJ = smbwrapper/smbw.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
smbwrapper/realcalls.o smbwrapper/shared.o \
- smbwrapper/smbw_cache.o
-
-SMBW_OBJ = $(SMBW_OBJ1) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
-
-SMBWRAPPER_OBJ1 = smbwrapper/wrapped.o
-
-SMBWRAPPER_OBJ = $(SMBW_OBJ) $(SMBWRAPPER_OBJ1)
-
-LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
- libsmb/libsmb_cache.o \
- $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
- $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ)
+ $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-# This shared library is intended for linking with unit test programs
-# to test Samba internals. It's called libbigballofmud.so to
-# discourage casual usage.
+SMBWRAPPER_OBJ = $(SMBW_OBJ) smbwrapper/wrapped.o
-LIBBIGBALLOFMUD_MAJOR = 0
+LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o $(LIB_OBJ) $(LIBSMB_OBJ) \
+ $(PARAM_OBJ) $(UBIQX_OBJ)
-LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
- $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
- $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
+CLIENT_OBJ = client/client.o client/clitar.o \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+ $(READLINE_OBJ)
-LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
-
-CLIENT_OBJ1 = client/client.o client/clitar.o
-
-CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
- $(READLINE_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
-
-NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
- utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
- utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
- utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
- utils/net_status.o utils/net_privileges.o
-
-NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
- $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
- $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o \
- lib/afs.o lib/afs_settoken.o
-
-CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
+CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
MOUNT_OBJ = client/smbmount.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
-
-MNT_OBJ = client/smbmnt.o lib/version.o lib/snprintf.o
-
-UMOUNT_OBJ = client/smbumount.o
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
-NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBNMB_OBJ) \
- $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
+MNT_OBJ = client/smbmnt.o \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
-SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
- torture/denytest.o torture/mangle_test.o
+UMOUNT_OBJ = client/smbumount.o \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
-SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \
+ $(LIBSMB_OBJ) $(LIB_OBJ)
-MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+SMBTORTURE_OBJ = utils/torture.o utils/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+MASKTEST_OBJ = utils/masktest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) lib/dummyroot.o
+MSGTEST_OBJ = utils/msgtest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+LOCKTEST_OBJ = utils/locktest.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ)
+NSSTEST_OBJ = utils/nsstest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
+SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
+ $(LIBMSRPC_OBJ)
-LOG2PCAP_OBJ = utils/log2pcaphex.o
-LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) lib/dummyroot.o
+LOCKTEST2_OBJ = utils/locktest2.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
- $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ)
-
-SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
- $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
-
-TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ)
-
-RPCTORTURE_OBJ = torture/rpctorture.o \
+RPCTORTURE_OBJ = utils/rpctorture.o \
rpcclient/display.o \
rpcclient/cmd_lsarpc.o \
rpcclient/cmd_wkssvc.o \
rpcclient/cmd_samr.o \
rpcclient/cmd_srvsvc.o \
rpcclient/cmd_netlogon.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
- $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ)
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+ $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
-DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
+RPCCHECK_OBJ = utils/rpccheck.o \
+ $(LIB_OBJ) $(RPC_PARSE_OBJ) \
+ $(UBIQX_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ)
-SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ)
+DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
-PROTO_OBJ = $(SMBD_OBJ_MAIN) \
- $(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
- $(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
- $(LIBMSRPC_OBJ) $(RPC_CLIENT_OBJ) \
- $(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \
- $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
- $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
- $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
- $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
- $(RPC_LSA_DS_OBJ) $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) \
- $(RPC_SPOOLSS_OBJ) $(RPC_ECHO_OBJ) $(RPC_EPMAPPER_OBJ) \
- $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o libsmb/passchange.o
+SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
-WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
- $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
+PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
+ $(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ) $(RPCCLIENT_OBJ1) \
+ $(RPC_CLIENT_OBJ) $(LIBMSRPC_OBJ)
-WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@)
+NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ)
+NSS_OBJ = $(NSS_OBJ_0:.o=.po)
-PICOBJS = $(SMBWRAPPER_OBJ:.o=.@PICSUFFIX@)
-LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
+PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
+PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
- pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
- lib/dummyroot.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(UBIQX_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
-
-PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
-
-IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@
+ pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
+ lib/debug.o lib/util_sid.o lib/messages.o lib/util_str.o \
+ lib/wins_srv.o lib/substitute.o lib/select.o lib/util.o \
+ nsswitch/wb_client.o nsswitch/wb_common.o lib/system.o \
+ lib/charset.o lib/util_file.o lib/kanji.o lib/genrand.o \
+ lib/username.o lib/util_getent.o lib/charcnv.o lib/time.o lib/md4.o \
+ lib/util_unistr.o lib/signal.o lib/talloc.o lib/ms_fnmatch.o \
+ lib/util_sock.o lib/smbrun.o lib/util_sec.o lib/snprintf.o \
+ ubiqx/ubi_sLinkList.o libsmb/smbencrypt.o libsmb/smbdes.o \
+ smbd/ssl.o lib/access.o \
+ lib/interfaces.o $(PARAM_OBJ) $(TDB_OBJ) $(PASSDB_OBJ)
+
+PAM_SMBPASS_OBJ = $(PAM_SMBPASS_OBJ_0:.o=.po)
+LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.po)
WINBINDD_OBJ1 = \
nsswitch/winbindd.o \
nsswitch/winbindd_user.o \
nsswitch/winbindd_group.o \
+ nsswitch/winbindd_idmap.o \
nsswitch/winbindd_util.o \
nsswitch/winbindd_cache.o \
nsswitch/winbindd_pam.o \
@@ -638,93 +396,85 @@ WINBINDD_OBJ1 = \
nsswitch/winbindd_misc.o \
nsswitch/winbindd_cm.o \
nsswitch/winbindd_wins.o \
- nsswitch/winbindd_rpc.o \
- nsswitch/winbindd_ads.o \
- nsswitch/winbindd_passdb.o \
- nsswitch/winbindd_dual.o \
- nsswitch/winbindd_acct.o
+ nsswitch/winbindd_rpc.o
+
+NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \
+ smbd/password.o smbd/utmp.o smbd/session.o smbd/uid.o smbd/sec_ctx.o \
+ rpc_client/cli_netlogon.o rpc_client/cli_login.o \
+ smbd/chgpasswd.o
WINBINDD_OBJ = \
- $(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(WINBINDD_OBJ1) $(NOPROTO_OBJ) $(PASSDB_OBJ) \
+ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
- $(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
- $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
- $(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o \
- lib/afs.o lib/afs_settoken.o
+ $(GROUPDB_OBJ) $(PROFILE_OBJ) \
+ $(NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ)
-WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) lib/afs_settoken.o
+WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o \
+ passdb/secrets.o
-WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@
+WINBIND_NSS_OBJ = nsswitch/winbind_nss.o nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@
-WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.@PICSUFFIX@) lib/snprintf.@PICSUFFIX@
+WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po)
POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
- popt/popthelp.o popt/poptparse.o
-
-TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o lib/snprintf.o $(TDBBASE_OBJ)
+ popt/popthelp.o popt/poptparse.o
-TDBDUMP_OBJ = tdb/tdbdump.o $(TDBBASE_OBJ)
+TDBBACKUP_OBJ = tdb/tdbbackup.o $(TDBBASE_OBJ)
-NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
- libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
- libads/kerberos_verify.o $(SECRETS_OBJ) lib/server_mutex.o \
- libads/authdata.o rpc_parse/parse_prs.o rpc_parse/parse_misc.o \
- libsmb/doserr.o
+TDBDUMP_OBJ = tdb/tdbdump.o $(TDBBASE_OBJ)
######################################################################
# now the rules...
######################################################################
-all : SHOWFLAGS proto_exists $(SBIN_PROGS) $(BIN_PROGS) $(SHLIBS) \
- $(MODULES) @EXTRA_ALL_TARGETS@
-pam_smbpass : SHOWFLAGS bin/pam_smbpass.@SHLIBEXT@
+all : CHECK $(SPROGS) $(PROGS) $(WINBIND_PROGS) $(WINBIND_SPROGS) $(LPROGS)
-smbwrapper : SHOWFLAGS @SMBWRAPPER@
+# The following "everything" is NOT needed except by Samba developers - so do not use this!
+everything : CHECK $(SPROGS) $(PROGS) $(SHLIBS) nsswitch smbwrapper smbtorture debug2html smbfilter
-torture : SHOWFLAGS $(TORTURE_PROGS)
+pam_smbpass : CHECK bin/pam_smbpass.@SHLIBEXT@
-smbtorture : SHOWFLAGS bin/smbtorture@EXEEXT@
+smbwrapper : CHECK @WRAPPROG@ @WRAP@ @WRAP32@
-masktest : SHOWFLAGS bin/masktest@EXEEXT@
+libsmbclient : CHECK bin/libsmbclient.a @LIBSMBCLIENT_SHARED@
-msgtest : SHOWFLAGS bin/msgtest@EXEEXT@
+torture : CHECK $(TORTURE_PROGS)
-locktest : SHOWFLAGS bin/locktest@EXEEXT@
+smbtorture : CHECK bin/smbtorture$(EXEEXT)
+bin/smbtorture : CHECK bin/smbtorture$(EXEEXT)
-smbcacls : SHOWFLAGS bin/smbcacls@EXEEXT@
+masktest : CHECK bin/masktest$(EXEEXT)
-smbcquotas : SHOWFLAGS bin/smbcquotas@EXEEXT@
+msgtest : CHECK bin/msgtest$(EXEEXT)
-locktest2 : SHOWFLAGS bin/locktest2@EXEEXT@
+locktest : CHECK bin/locktest$(EXEEXT)
-rpctorture : SHOWFLAGS bin/rpctorture@EXEEXT@
+smbcacls : CHECK bin/smbcacls$(EXEEXT)
-debug2html : SHOWFLAGS bin/debug2html@EXEEXT@
+locktest2 : CHECK bin/locktest2$(EXEEXT)
-smbfilter : SHOWFLAGS bin/smbfilter@EXEEXT@
+rpctorture : CHECK bin/rpctorture$(EXEEXT)
-talloctort : SHOWFLAGS bin/talloctort@EXEEXT@
+bin/rpccheck$(EXEEXT): $(RPCCHECK_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(RPCCHECK_OBJ) $(LDFLAGS) $(LIBS)
-nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ @WINBIND_NSS@ \
- @WINBIND_WINS_NSS@ nsswitch/pam_winbind.@SHLIBEXT@
+debug2html : CHECK bin/debug2html$(EXEEXT)
-wins : SHOWFLAGS @WINBIND_WINS_NSS@
+smbfilter : CHECK bin/smbfilter$(EXEEXT)
-modules: SHOWFLAGS proto_exists $(MODULES)
+nsswitch : CHECK $(WINBIND_PROGS) $(WINBIND_SPROGS) $(LPROGS)
-everything: all libsmbclient debug2html smbfilter talloctort modules torture \
- $(EVERYTHING_PROGS)
+wins : CHECK nsswitch/libnss_wins.@SHLIBEXT@
.SUFFIXES:
-.SUFFIXES: .c .o .@PICSUFFIX@ .lo
+.SUFFIXES: .c .o .po .po32 .lo
-SHOWFLAGS:
+CHECK:
@echo "Using FLAGS = $(FLAGS)"
- @echo " LIBS = $(LIBS)"
- @echo " LDSHFLAGS = $(LDSHFLAGS)"
- @echo " LDFLAGS = $(LDFLAGS)"
+ @echo "Using FLAGS32 = $(FLAGS32)"
+ @echo "Using LIBS = $(LIBS)"
MAKEDIR = || exec false; \
if test -d "$$dir"; then :; else \
@@ -734,7 +484,7 @@ MAKEDIR = || exec false; \
mkdir "$$dir" || \
exec false; fi || exec false
-.c.o:
+.c.o:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
@echo Compiling $*.c
@@ -742,742 +492,283 @@ MAKEDIR = || exec false; \
-o $@
@BROKEN_CC@ -mv `echo $@ | sed 's%^.*/%%g'` $@
-# this adds support for precompiled headers. To use it, install a snapshot
-# of gcc-3.4 and run 'make pch' before you do the main build.
-pch:
- rm -f $(srcdir)/include/includes.h.gch
- $(CC) -I. -I$(srcdir) $(FLAGS) -c $(srcdir)/include/includes.h -o $(srcdir)/include/includes.h.gch
-
-# These dependencies are only approximately correct: we want to make
-# sure Samba's paths are updated if ./configure is re-run. Really it
-# would be nice if "make prefix=/opt/samba all" also rebuilt things,
-# but since we also require "make install prefix=/opt/samba" *not* to
-# rebuild it's a bit hard.
-
-dynconfig.o: dynconfig.c Makefile
- @echo Compiling $*.c
- @$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
-
-dynconfig.@PICSUFFIX@: dynconfig.c Makefile
+.c.po:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAGS@
- @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
-
-lib/version.o: lib/version.c include/version.h
- @echo Compiling $*.c
- @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
-
-lib/version.@PICSUFFIX@: lib/version.c include/version.h
- @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
- dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAGS@
- @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
-
-smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h
- @echo Compiling $*.c
- @$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
-
-smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk
- @echo Generating $@
- @dir=smbd $(MAKEDIR) && $(AWK) -f $(srcdir)/script/mkbuildoptions.awk > $(builddir)/smbd/build_options.c < $(srcdir)/include/config.h.in
-
-.c.@PICSUFFIX@:
+ @echo Compiling $*.c with @PICFLAG@
+ @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< \
+ -o $*.@PICSUFFIX@
+@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@.o
+ @mv $*.po.o $@
+
+# this is for IRIX
+.c.po32:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
- @echo Compiling $*.c with @PICFLAGS@
- @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@
+ @echo Compiling $*.c with @PICFLAG@ and -32
+ @$(CC) -32 -I. -I$(srcdir) $(FLAGS32) @PICFLAG@ -c $< \
+ -o $*.po32.o
+@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po32$$%.o%'` $@.o
+ @mv $*.po32.o $@
bin/.dummy:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then :; else \
dir=bin $(MAKEDIR); fi
@: >> $@ || : > $@ # what a fancy emoticon!
-bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
- $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
- $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@
-
-bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbd$(EXEEXT): $(SMBD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(WREPL_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy
+bin/nmbd$(EXEEXT): $(NMBD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \
- $(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(LIBS)
-bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
+bin/swat$(EXEEXT): $(SWAT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
- $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \
- $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
+bin/rpcclient$(EXEEXT): $(RPCCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(LDAPLIBS)
-bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbclient$(EXEEXT): $(CLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS)
-bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbspool$(EXEEXT): $(CUPS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PROFILES_OBJ) $(LDFLAGS) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS)
-bin/editreg@EXEEXT@: $(EDITREG_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbmount$(EXEEXT): $(MOUNT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(EDITREG_OBJ) $(LDFLAGS) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbspool@EXEEXT@: $(CUPS_OBJ) bin/.dummy
+bin/smbmnt$(EXEEXT): $(MNT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MNT_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbmount@EXEEXT@: $(MOUNT_OBJ) bin/.dummy
+bin/smbumount$(EXEEXT): $(UMOUNT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbmnt@EXEEXT@: $(MNT_OBJ) bin/.dummy
+bin/testparm$(EXEEXT): $(TESTPARM_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MNT_OBJ) $(LDFLAGS)
+ @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbumount@EXEEXT@: $(UMOUNT_OBJ) bin/.dummy
+bin/testprns$(EXEEXT): $(TESTPRNS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(LDFLAGS)
+ @$(CC) $(FLAGS) -o $@ $(TESTPRNS_OBJ) $(LDFLAGS) $(LIBS)
-bin/testparm@EXEEXT@: $(TESTPARM_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbstatus$(EXEEXT): $(STATUS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(LIBS)
-bin/testprns@EXEEXT@: $(TESTPRNS_OBJ) bin/.dummy
+bin/smbcontrol$(EXEEXT): $(SMBCONTROL_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TESTPRNS_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) $(LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbstatus@EXEEXT@: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbpasswd$(EXEEXT): $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
- @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy
+bin/pdbedit$(EXEEXT): $(PDBEDIT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) \
- $(LDFLAGS) $(LIBS) \
- @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
+bin/make_smbcodepage$(EXEEXT): $(MAKE_SMBCODEPAGE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MAKE_SMBCODEPAGE_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
+bin/make_unicodemap$(EXEEXT): $(MAKE_UNICODEMAP_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \
- $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MAKE_UNICODEMAP_OBJ) $(LDFLAGS) $(LIBS)
-bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
+bin/nmblookup$(EXEEXT): $(NMBLOOKUP_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbget@EXEEXT@: $(SMBGET_OBJ) @BUILD_POPT@ bin/.dummy
+bin/make_printerdef$(EXEEXT): $(MAKE_PRINTERDEF_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MAKE_PRINTERDEF_OBJ) $(LDFLAGS) $(LIBS)
-bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
+bin/smbtorture$(EXEEXT): $(SMBTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(LIBS)
-bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy
+bin/masktest$(EXEEXT): $(MASKTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbtorture@EXEEXT@: $(SMBTORTURE_OBJ) bin/.dummy
+bin/msgtest$(EXEEXT): $(MSGTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(SECRETS_OBJ)
+ @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS)
-bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy
+bin/smbcacls$(EXEEXT): $(SMBCACLS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) $(LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-bin/masktest@EXEEXT@: $(MASKTEST_OBJ) bin/.dummy
+bin/locktest$(EXEEXT): $(LOCKTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(SECRETS_OBJ)
+ @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS)
-bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy
+bin/locktest2$(EXEEXT): $(LOCKTEST2_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy
+bin/nsstest$(EXEEXT): $(NSSTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy
+bin/rpctorture$(EXEEXT): $(RPCTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS)
-bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/nsstest@EXEEXT@: $(NSSTEST_OBJ) bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/vfstest@EXEEXT@: $(VFSTEST_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@
-
-bin/log2pcap@EXEEXT@: $(LOG2PCAP_OBJ) @BUILD_POPT@ bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) @POPTLIBS@ $(LIBS)
-
-bin/locktest2@EXEEXT@: $(LOCKTEST2_OBJ) bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/rpctorture@EXEEXT@: $(RPCTORTURE_OBJ) bin/.dummy
- @echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy
+bin/debug2html$(EXEEXT): $(DEBUG2HTML_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
+bin/smbfilter$(EXEEXT): $(SMBFILTER_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS)
-bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
+bin/smbw_sample$(EXEEXT): $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS)
-bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy
+bin/smbsh$(EXEEXT): $(SMBSH_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(LIBS)
bin/smbwrapper.@SHLIBEXT@: $(PICOBJS) bin/.dummy
@echo Linking shared library $@
- @$(SHLD) $(LDSHFLAGS) -o $@ $(PICOBJS) $(LIBS) \
- $(KRB5LIBS) $(LDAP_LIBS) \
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(PICOBJS) $(LDFLAGS) $(LIBS) \
+ @SONAMEFLAG@`basename $@`
+
+bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32) bin/.dummy
+ @echo Linking shared library $@
+ @$(SHLD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LDFLAGS) $(LIBS) \
@SONAMEFLAG@`basename $@`
-bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS)
+bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS) bin/.dummy
@echo Linking libsmbclient shared library $@
- @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(DYNEXP) $(LIBS) \
- $(KRB5LIBS) $(LDAP_LIBS) \
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \
@SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR)
-bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS)
+bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS) bin/.dummy
@echo Linking libsmbclient non-shared library $@
@-$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS)
-# This is probably wrong for anything other than the GNU linker.
-bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
- @echo Linking bigballofmud shared library $@
- @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \
- $(PASSDB_LIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
- @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR)
- ln -snf libbigballofmud.so bin/libbigballofmud.so.0
-
-# It would be nice to build a static bigballofmud too, but when I try
-# I get linker errors about dl_open and similar things. I'm not sure if
-# it can be fixed or if they just can't be called from a static
-# library.
-
-libsmbclient: $(LIBSMBCLIENT)
-
-bin/librpc_lsarpc.@SHLIBEXT@: $(RPC_LSA_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_LSA_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_samr.@SHLIBEXT@: $(RPC_SAMR_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SAMR_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_srvsvc.@SHLIBEXT@: $(RPC_SVC_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVC_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_wkssvc.@SHLIBEXT@: $(RPC_WKS_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_WKS_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_NETLOGON.@SHLIBEXT@: $(RPC_NETLOG_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_NETLOG_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_winreg.@SHLIBEXT@: $(RPC_REG_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_REG_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_lsa_ds.@SHLIBEXT@: $(RPC_LSA_DS_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_LSA_DS_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_spoolss.@SHLIBEXT@: $(RPC_SPOOLSS_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SPOOLSS_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_netdfs.@SHLIBEXT@: $(RPC_DFS_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_DFS_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
-bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_ECHO_OBJ) -lc \
+bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_OBJ) bin/.dummy
+ @echo Linking shared library $@
+ $(SHLD) @LDSHFLAGS@ -o $@ $(PAM_SMBPASS_OBJ) $(LDFLAGS) -lpam $(DYNEXP) $(LIBS) $(LDAPLIBS) -lc \
@SONAMEFLAG@`basename $@`
-bin/librpc_epmapper.@SHLIBEXT@: $(RPC_EPMAPPER_OBJ)
+nsswitch/libnss_wins.so: $(NSS_OBJ)
@echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_EPMAPPER_OBJ) -lc \
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(NSS_OBJ) -lc \
@SONAMEFLAG@`basename $@`
-bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
- @echo "Linking $@"
- @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS)
-
-# Please don't add .o files to libnss_winbind, libnss_wins, or the pam_winbind
-# libraries. Add to the appropriate PICOBJ variable instead.
-
-@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
- @echo "Linking $@"
- @$(SHLD) $(WINBIND_NSS_LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) \
- @WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@`
+bin/winbindd$(EXEEXT): $(WINBINDD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) $(LDAPLIBS)
-@WINBIND_WINS_NSS@: $(WINBIND_WINS_NSS_PICOBJS)
+nsswitch/libns_winbind.so: $(WINBIND_NSS_PICOBJS)
@echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) \
- $(LDAP_LIBS) $(KRB5LIBS) -lc \
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(WINBIND_NSS_PICOBJS) @WINBIND_NSS_EXTRA_LIBS@ \
@SONAMEFLAG@`basename $@`
-nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_PICOBJ) bin/.dummy
+nsswitch/libnss_winbind.so: $(WINBIND_NSS_PICOBJS)
@echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_PICOBJ) \
- @SONAMEFLAG@`basename $@` -lpam
-
-bin/rhosts.@SHLIBEXT@: $(AUTH_RHOSTS_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_RHOSTS_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/builtin.@SHLIBEXT@: $(AUTH_BUILTIN_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_BUILTIN_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/domain.@SHLIBEXT@: $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/smbserver.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/winbind.@SHLIBEXT@: $(AUTH_WINBIND_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_WINBIND_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/unix.@SHLIBEXT@: $(AUTH_UNIX_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_UNIX_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/sam.@SHLIBEXT@: $(AUTH_SAM_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SAM_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
-
-bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(MYSQL_OBJ:.o=.@PICSUFFIX@) @MYSQL_LIBS@ \
- @SONAMEFLAG@`basename $@`
-
-bin/pgsql.@SHLIBEXT@: $(PGSQL_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(PGSQL_OBJ:.o=.@PICSUFFIX@) @PGSQL_LIBS@ \
- @SONAMEFLAG@`basename $@`
-
-bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.@PICSUFFIX@
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) $(LDAP_LIBS) -o $@ passdb/pdb_ldap.@PICSUFFIX@ \
- @SONAMEFLAG@`basename $@`
-
-bin/tdbsam.@SHLIBEXT@: passdb/pdb_tdb.@PICSUFFIX@
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_tdb.@PICSUFFIX@ \
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(WINBIND_NSS_PICOBJS) @WINBIND_NSS_EXTRA_LIBS@ \
@SONAMEFLAG@`basename $@`
-bin/smbpasswd.@SHLIBEXT@: passdb/pdb_smbpasswd.@PICSUFFIX@
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_smbpasswd.@PICSUFFIX@ \
- @SONAMEFLAG@`basename $@`
-
-bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/CP850.@SHLIBEXT@: $(CP850_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(CP850_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/macosxfs.@SHLIBEXT@: $(CHARSET_MACOSXFS_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(CHARSET_MACOSXFS_OBJ:.o=.@PICSUFFIX@) \
- -framework CoreFoundation @SONAMEFLAG@`basename $@`
-
-bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.@PICSUFFIX@) @XML_LIBS@ \
- @SONAMEFLAG@`basename $@`
-
-bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXTD_AUDIT_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_RECYCLE_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/netatalk.@SHLIBEXT@: $(VFS_NETATALK_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_NETATALK_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/default_quota.@SHLIBEXT@: $(VFS_DEFAULT_QUOTA_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_DEFAULT_QUOTA_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/shadow_copy.@SHLIBEXT@: $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_SHADOW_COPY_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/expand_msdfs.@SHLIBEXT@: $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@) \
- @SONAMEFLAG@`basename $@`
-
-bin/config_ldap.@SHLIBEXT@: $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@) \
- @SMBLDAP@ @LDAP_LIBS@ @SONAMEFLAG@`basename $@`
-
-bin/afsacl.@SHLIBEXT@: $(VFS_AFSACL_OBJ:.o=.po)
- @echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AFSACL_OBJ:.o=.po) \
- @SONAMEFLAG@`basename $@`
-
-bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
+nsswitch/pam_winbind.so: $(PAM_WINBIND_OBJ)
@echo Linking $@
- @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(PAM_WINBIND_OBJ) \
+ @SONAMEFLAG@`basename $@`
-bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
+bin/wbinfo$(EXEEXT): $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) \
+ $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(LINK) -o $@ $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(UBIQX_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
-
-bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
- @echo "Linking shared library $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc $(LDAP_LIBS) $(KRB5LIBS)
+ @$(LINK) -o $@ $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) \
+ $(UBIQX_OBJ) $(LIBS) @BUILD_POPT@
-bin/libmsrpc.a: $(LIBMSRPC_PICOBJ)
- @-$(AR) -rc $@ $(LIBMSRPC_PICOBJ)
-
-bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy
+bin/tdbbackup$(EXEEXT): $(TDBBACKUP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(TDBBACKUP_OBJ)
-bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy
+bin/tdbdump$(EXEEXT): $(TDBDUMP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(TDBDUMP_OBJ)
-bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
- $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud
-
-bin/t_strstr@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o
- $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud
-
-bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o
- $(CC) $(FLAGS) -o $@ torture/t_stringoverflow.o -L./bin -lbigballofmud
-
-bin/t_doschar@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_doschar.o
- $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_doschar.o -L ./bin -lbigballofmud
-bin/t_push_ucs2@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_push_ucs2.o
- $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_push_ucs2.o -L ./bin -lbigballofmud
-
-bin/t_snprintf@EXEEXT@: lib/snprintf.c
- $(CC) $(FLAGS) -o $@ -DTEST_SNPRINTF lib/snprintf.c -lm
-install: installbin installman installscripts installdat installswat installmodules @INSTALLCLIENT@
-
-install-everything: install installmodules
-
-# DESTDIR is used here to prevent packagers wasting their time
-# duplicating the Makefile. Remove it and you will have the privelege
-# of package each samba release for muliple versions of multiple
-# distributions and operating systems, or at least supplying patches
-# to all the packaging files required for this, prior to committing
-# the removal of DESTDIR. Do not remove it even though you think it
-# is not used
+install: installbin installman installscripts installcp installswat
installdirs:
- @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(PRIVATEDIR) $(DESTDIR)$(PIDDIR) $(DESTDIR)$(LOCKDIR) $(DESTDIR)$(MANDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(BASEDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(SBINDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(BINDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(LIBDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(VARDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(PIDDIR)
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$(CODEPAGEDIR)
installservers: all installdirs
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SBIN_PROGS)
+ @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SPROGS)
installbin: all installdirs
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SBIN_PROGS)
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(BIN_PROGS)
-
-
-# Some symlinks are required for the 'probing' of modules.
-# This mechanism should go at some point..
-installmodules: modules installdirs
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(VFS_MODULES)
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(PDB_MODULES)
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(RPCLIBDIR) $(RPC_MODULES)
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES)
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES)
- @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES)
- @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@
- @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) rhosts.@SHLIBEXT@ hostsequiv.@SHLIBEXT@
- @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) sam.@SHLIBEXT@ sam_ignoredomain.@SHLIBEXT@
- @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) domain.@SHLIBEXT@ trustdomain.@SHLIBEXT@ ntdomain.@SHLIBEXT@
- @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) builtin.@SHLIBEXT@ guest.@SHLIBEXT@ fixed_challenge.@SHLIBEXT@ name_to_ntstatus.@SHLIBEXT@
+ @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SPROGS) $(WINBIND_SPROGS)
+ @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(PROGS) $(WINBIND_PROGS)
installscripts: installdirs
@$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS)
-installdat: installdirs
- @$(SHELL) $(srcdir)/script/installdat.sh $(DESTDIR)$(LIBDIR) $(srcdir)
+installcp: installdirs installbin
+ @$(SHELL) $(srcdir)/script/installcp.sh $(srcdir) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(CODEPAGEDIR) $(DESTDIR)$(BINDIR) $(CODEPAGELIST)
-installmsg: installdirs
- @$(SHELL) $(srcdir)/script/installmsg.sh $(DESTDIR)$(LIBDIR) $(srcdir)
-
-installswat: installdirs installmsg
+installswat: installdirs
@$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir)
-installclientlib: installdirs libsmbclient
- @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/lib
- -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@ $(DESTDIR)${prefix}/lib
- -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a $(DESTDIR)${prefix}/lib
- @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/include
- -$(INSTALLCMD) $(srcdir)/include/libsmbclient.h $(DESTDIR)${prefix}/include
-
-# Python extensions
-
-PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
- $(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
-
-PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
-
-python_ext: $(PYTHON_PICOBJS)
- @if test -z "$(PYTHON)"; then \
- echo Use the option --with-python to configure python; \
- exit 1; \
- fi
- PYTHON_OBJS="$(PYTHON_PICOBJS)" \
- PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \
- LIBS="$(LDFLAGS) $(LIBS) $(PASSDB_LIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAP_LIBS)" \
- $(PYTHON) python/setup.py build
-
-python_install: $(PYTHON_PICOBJS)
- @if test -z "$(PYTHON)"; then \
- echo Use the option --with-python to configure python; \
- exit 1; \
- fi
- PYTHON_OBJS="$(PYTHON_PICOBJS)" \
- PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS)" \
- LIBS="$(LDFLAGS) $(LIBS)" \
- $(PYTHON) python/setup.py install
-
-python_clean:
- @-if test -n "$(PYTHON)"; then $(PYTHON) python/setup.py clean; fi
+installclientlib:
+ -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@
+ -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a
+ -$(INSTALLCMD) -d ${prefix}/include
+ -$(INSTALLCMD) include/libsmbclient.h ${prefix}/include
# revert to the previously installed version
revert:
- @$(SHELL) $(srcdir)/script/revert.sh $(SBINDIR) $(SBIN_PROGS)
- @$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(BIN_PROGS) $(SCRIPTS)
-
-installman: installdirs
- @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs) "@ROFF@"
+ @$(SHELL) $(srcdir)/script/revert.sh $(DESTDIR)$(SBINDIR) $(SPROGS) ${WINBIND_SPROGS}
+ @$(SHELL) $(srcdir)/script/revert.sh $(DESTDIR)$(BINDIR) $(PROGS) $(SCRIPTS) ${WINBIND_PROGS}
-.PHONY: showlayout
+installman:
+ @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) "@ROFF@"
-showlayout:
- @echo "Samba will be installed into:"
- @echo " basedir: $(BASEDIR)"
- @echo " bindir: $(BINDIR)"
- @echo " sbindir: $(SBINDIR)"
- @echo " libdir: $(LIBDIR)"
- @echo " vardir: $(VARDIR)"
- @echo " mandir: $(MANDIR)"
- @echo " privatedir: $(PRIVATE_DIR)"
- @echo " configdir: $(CONFIGDIR)"
- @echo " lockdir: $(LOCKDIR)"
- @echo " piddir: $(PIDDIR)"
- @echo " swatdir: $(SWATDIR)"
-
-
-uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules
+uninstall: uninstallman uninstallbin uninstallscripts uninstallcp
uninstallman:
- @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs)
+ @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir)
uninstallbin:
- @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(SBIN_PROGS)
- @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(BIN_PROGS)
-
-uninstallmodules:
- @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(DESTDIR)$(VFS_MODULES)
- @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(DESTDIR)$(PDB_MODULES)
- @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(RPCLIBDIR) $(DESTDIR)$(RPC_MODULES)
- @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(DESTDIR)$(CHARSET_MODULES)
- @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(DESTDIR)$(AUTH_MODULES)
+ @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(SPROGS) $(WINBIND_SPROGS)
+ @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(PROGS) $(WINBIND_PROGS)
uninstallscripts:
@$(SHELL) $(srcdir)/script/uninstallscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS)
-# Toplevel clean files
-TOPFILES=dynconfig.o dynconfig.@PICSUFFIX@
-
-clean: delheaders python_clean
- -rm -f core */*~ *~ */*.o */*.@PICSUFFIX@ */*.@SHLIBEXT@ \
- $(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) \
- $(LIBSMBCLIENT) $(EVERYTHING_PROGS) .headers.stamp
-
-# Making this target will just make sure that the prototype files
-# exist, not necessarily that they are up to date. Since they're
-# removed by "make clean" this will always be run when you do anything
-# afterwards.
-proto_exists: include/proto.h include/wrepld_proto.h include/build_env.h \
- nsswitch/winbindd_proto.h web/swat_proto.h \
- client/client_proto.h utils/net_proto.h smbd/build_options.c
-
-delheaders:
- @echo Removing prototype headers
- @rm -f include/proto.h include/build_env.h include/wrepld_proto.h \
- nsswitch/winbindd_proto.h web/swat_proto.h \
- client/client_proto.h utils/net_proto.h \
- smbd/build_options.c
-
-MKPROTO_SH = $(srcdir)/script/mkproto.sh
-
-include/proto.h: smbd/build_options.c
- @echo Building include/proto.h
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _PROTO_H_ $(builddir)/include/proto.h \
- $(PROTO_OBJ)
-
-include/build_env.h: script/build_env.sh
- @echo Building include/build_env.h
- @$(SHELL) $(srcdir)/script/build_env.sh $(srcdir) $(builddir) $(CC) \
- > $(builddir)/include/build_env.h
-
-include/wrepld_proto.h:
- @echo Building include/wrepld_proto.h
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _WREPLD_PROTO_H_ $(builddir)/include/wrepld_proto.h \
- $(WREPL_OBJ1)
-
-nsswitch/winbindd_proto.h:
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _WINBINDD_PROTO_H_ $(builddir)/nsswitch/winbindd_proto.h \
- $(WINBINDD_OBJ1)
-
-web/swat_proto.h:
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _SWAT_PROTO_H_ $(builddir)/web/swat_proto.h \
- $(SWAT_OBJ1)
-
-client/client_proto.h:
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _CLIENT_PROTO_H_ $(builddir)/client/client_proto.h \
- $(CLIENT_OBJ1)
-
-utils/net_proto.h:
- @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \
- -h _NET_PROTO_H_ $(builddir)/utils/net_proto.h \
- $(NET_OBJ1)
-
-include/tdbsam2_parse_info.h:
- @if test -n "$(PERL)"; then \
- cd $(srcdir) && @PERL@ -w script/genstruct.pl \
- -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \
- include/gums.h; \
- else \
- echo Unable to build $@, continuing; \
- fi
-
-# "make headers" or "make proto" calls a subshell because we need to
-# make sure these commands are executed in sequence even for a
-# parallel make.
-headers:
- $(MAKE) delheaders; \
- $(MAKE) smbd/build_options.c; \
- $(MAKE) include/proto.h; \
- $(MAKE) include/build_env.h; \
- $(MAKE) include/wrepld_proto.h; \
- $(MAKE) nsswitch/winbindd_proto.h; \
- $(MAKE) web/swat_proto.h; \
- $(MAKE) client/client_proto.h; \
- $(MAKE) utils/net_proto.h;
-
-prebuiltheaders:
- $(MAKE) include/tdbsam2_parse_info.h
-
-genparse: prebuiltheaders
-
-proto: headers
-
-.PHONY: headers proto
+uninstallcp:
+ @$(SHELL) $(srcdir)/script/uninstallcp.sh $(DESTDIR)$(CODEPAGEDIR) $(CODEPAGELIST)
+
+clean:
+ -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@* */*.a
+
+winbindd_proto:
+ @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
+ -h _WINBINDD_PROTO_H_ nsswitch/winbindd_proto.h \
+ $(WINBINDD_OBJ1)
+
+proto:
+ @echo rebuilding include/proto.h
+ @cd $(srcdir) && $(AWK) -f script/mkproto.awk `echo $(PROTO_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/proto.h
etags:
etags `find $(srcdir) -name "*.[ch]" | grep -v /CVS/`
@@ -1485,19 +776,15 @@ etags:
ctags:
ctags `find $(srcdir) -name "*.[ch]" | grep -v /CVS/`
-realclean: clean delheaders
- -rm -f config.log bin/.dummy script/findsmb
+realclean: clean
+ -rm -f config.log $(PROGS) $(SPROGS) $(WINBIND_PROGS) $(WINBIND_SPROGS) $(LPROGS) bin/.dummy
+ -rm -f bin/*
+ -rmdir bin
distclean: realclean
- -rm -f include/stamp-h
-rm -f include/config.h Makefile
-rm -f config.status config.cache so_locations
- -rm -rf .deps TAGS
-
-realdistclean: distclean
- -rm -f include/config.h.in
- -rm -f include/version.h
- -rm -f configure
+ -rm -rf .deps
# this target is really just for my use. It only works on a limited
# range of machines and is used to produce a list of potentially
@@ -1510,30 +797,10 @@ finddead:
# when configure.in is updated, reconfigure
$(srcdir)/configure: $(srcdir)/configure.in
- @echo "WARNING: you need to rerun ./autogen.sh"
+ @echo "WARNING: you need to rerun autoconf"
config.status: $(srcdir)/configure
- @echo "WARNING: you need to run ./configure"
+ @echo "WARNING: you need to run configure"
Makefile: $(srcdir)/Makefile.in config.status
@echo "WARNING: you need to run ./config.status"
-
-######################################################################
-# Samba Testing Framework
-
-# FIXME: LD_LIBRARY_PATH is not portable, but in the absence of
-# libtool I don't know a better way to do it. Perhaps we should fix
-# libbigballofmud to link statically?
-
-check: check-programs
- LD_LIBRARY_PATH="`pwd`/bin:$$LD_LIBRARY_PATH" \
- PATH="`pwd`/bin:$$PATH" \
- python stf/standardcheck.py; \
- if test -n "$(PYTHON)"; then \
- python stf/pythoncheck.py; \
- fi
-
-# These are called by the test suite and need to be built before
-# running it. For the time being we don't build all of BIN_PROGS,
-# because they're not all needed.
-check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf
diff --git a/source/VERSION b/source/VERSION
deleted file mode 100644
index ff04f37c881..00000000000
--- a/source/VERSION
+++ /dev/null
@@ -1,81 +0,0 @@
-########################################################
-# SAMBA Version #
-# #
-# script/mkversion.sh #
-# will use this file to create #
-# include/version.h #
-# #
-########################################################
-
-########################################################
-# This are the main SAMBA version numbers #
-# #
-# <MAJOR>.<MINOR>.<RELEASE> #
-# #
-# e.g. SAMBA_VERSION_MAJOR=3 #
-# SAMBA_VERSION_MINOR=0 #
-# SAMBA_VERSION_RELEASE=0 #
-# -> "3.0.0" #
-########################################################
-SAMBA_VERSION_MAJOR=3
-SAMBA_VERSION_MINOR=1
-SAMBA_VERSION_RELEASE=0
-
-########################################################
-# For 'pre' releases the version will be #
-# #
-# <MAJOR>.<MINOR>.<RELEASE>pre<PRE_RELEASE> #
-# #
-# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
-# -> "2.2.9pre1" #
-########################################################
-SAMBA_VERSION_PRE_RELEASE=
-
-########################################################
-# For 'rc' releases the version will be #
-# #
-# <MAJOR>.<MINOR>.<RELEASE>rc<RC_RELEASE> #
-# #
-# e.g. SAMBA_VERSION_RC_RELEASE=1 #
-# -> "3.0.0rc1" #
-########################################################
-SAMBA_VERSION_RC_RELEASE=
-
-########################################################
-# To mark SVN snapshots this should be set to 'yes' #
-# in the development BRANCH, and set to 'no' only in #
-# the SAMBA_X_X_RELEASE BRANCH #
-# #
-# <MAJOR>.<MINOR>.<RELEASE>[...]cvs #
-# #
-# e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes #
-# -> "3.0.0-SVN-build-199" #
-########################################################
-SAMBA_VERSION_IS_SVN_SNAPSHOT=yes
-
-########################################################
-# This can be set by vendors if they want... #
-# This can be a string constant or a function which #
-# returns a string (const char *) #
-# #
-# <MAJOR>.<MINOR>.<RELEASE>[...]-<VENDOR_SUFFIX> #
-# #
-# Note the '-' is automaticaly added #
-# #
-# e.g. SAMBA_VERSION_VENDOR_SUFFIX="VendorVersion" #
-# -> "CVS 3.0.0rc2-VendorVersion" #
-# #
-# Note: If you want to use a function, #
-# then patch lib/version.c and add this function #
-# there, because the symbol must be available in #
-# binary. #
-# #
-# const char *vendor_version(void) #
-# { #
-# return "VendorVersion"; #
-# } #
-# #
-# e.g. SAMBA_VERSION_VENDOR_SUFFIX=vendor_version() #
-# -> "CVS 3.0.0rc2-VendorVersion" #
-########################################################
-SAMBA_VERSION_VENDOR_SUFFIX=
diff --git a/source/acconfig.h b/source/acconfig.h
new file mode 100755
index 00000000000..e347cdbda1f
--- /dev/null
+++ b/source/acconfig.h
@@ -0,0 +1,227 @@
+#undef HAVE_VOLATILE
+#undef HAVE_BROKEN_READDIR
+#undef HAVE_C99_VSNPRINTF
+#undef HAVE_ERRNO_DECL
+#undef HAVE_LONGLONG
+#undef HAVE_OFF64_T
+#undef HAVE_REMSH
+#undef HAVE_UNSIGNED_CHAR
+#undef HAVE_UTIMBUF
+#undef HAVE_SIG_ATOMIC_T_TYPE
+#undef HAVE_SOCKLEN_T_TYPE
+#undef ssize_t
+#undef ino_t
+#undef ssize_t
+#undef loff_t
+#undef offset_t
+#undef aclent_t
+#undef wchar_t
+#undef HAVE_CONNECT
+#undef HAVE_SHORT_INO_T
+#undef WITH_SMBWRAPPER
+#undef WITH_AFS
+#undef WITH_DFS
+#undef SUNOS5
+#undef SUNOS4
+#undef LINUX
+#undef AIX
+#undef BSD
+#undef IRIX
+#undef IRIX6
+#undef HPUX
+#undef QNX
+#undef SCO
+#undef OSF1
+#undef NEXT2
+#undef RELIANTUNIX
+#undef HAVE_MMAP
+#undef HAVE_FCNTL_LOCK
+#undef HAVE_FTRUNCATE_EXTEND
+#undef FTRUNCATE_NEEDS_ROOT
+#undef HAVE_TRAPDOOR_UID
+#undef HAVE_ROOT
+#undef HAVE_GETTIMEOFDAY_TZ
+#undef HAVE_SOCK_SIN_LEN
+#undef STAT_READ_FILSYS
+#undef STAT_STATFS2_BSIZE
+#undef STAT_STATFS2_FSIZE
+#undef STAT_STATFS2_FS_DATA
+#undef STAT_STATFS3_OSF1
+#undef STAT_STATFS4
+#undef STAT_STATVFS
+#undef STAT_STATVFS64
+#undef HAVE_IFACE_AIX
+#undef HAVE_IFACE_IFCONF
+#undef HAVE_IFACE_IFREQ
+#undef HAVE_CRYPT
+#undef HAVE_PUTPRPWNAM
+#undef HAVE_SET_AUTH_PARAMETERS
+#undef WITH_SYSLOG
+#undef WITH_PROFILE
+#undef WITH_SSL
+#undef WITH_LDAP
+#undef WITH_NISPLUS
+#undef WITH_TDBPWD
+#undef WITH_PAM
+#undef WITH_PAM_SMBPASS
+#undef WITH_NISPLUS_HOME
+#undef WITH_AUTOMOUNT
+#undef WITH_SMBMOUNT
+#undef HAVE_BROKEN_GETGROUPS
+#undef REPLACE_GETPASS
+#undef REPLACE_INET_NTOA
+#undef HAVE_FILE_MACRO
+#undef HAVE_FUNCTION_MACRO
+#undef HAVE_VA_COPY
+#undef HAVE_SETRESUID_DECL
+#undef HAVE_SETRESUID
+#undef WITH_NETATALK
+#undef WITH_UTMP
+#undef WITH_MSDFS
+#undef WITH_VFS
+#undef HAVE_INO64_T
+#undef HAVE_DEV64_T
+#undef HAVE_STRUCT_FLOCK64
+#undef SIZEOF_INO_T
+#undef SIZEOF_OFF_T
+#undef STAT_STATVFS64
+#undef HAVE_LIBREADLINE
+#undef HAVE_KERNEL_SHARE_MODES
+#undef HAVE_KERNEL_OPLOCKS_IRIX
+#undef HAVE_KERNEL_OPLOCKS_LINUX
+#undef HAVE_KERNEL_CHANGE_NOTIFY
+#undef HAVE_IRIX_SPECIFIC_CAPABILITIES
+#undef HAVE_INT16_FROM_RPC_RPC_H
+#undef HAVE_UINT16_FROM_RPC_RPC_H
+#undef HAVE_INT32_FROM_RPC_RPC_H
+#undef HAVE_UINT32_FROM_RPC_RPC_H
+#undef KRB4_AUTH
+#undef KRB5_AUTH
+#undef SEEKDIR_RETURNS_VOID
+#undef HAVE_DIRENT_D_OFF
+#undef HAVE_GETSPNAM
+#undef HAVE_BIGCRYPT
+#undef HAVE_GETPRPWNAM
+#undef HAVE_FSTAT64
+#undef HAVE_LSTAT64
+#undef HAVE_STAT64
+#undef HAVE_SETRESGID
+#undef HAVE_SETRESGID_DECL
+#undef HAVE_SHADOW_H
+#undef HAVE_MEMSET
+#undef HAVE_STRCASECMP
+#undef HAVE_STRUCT_DIRENT64
+#undef HAVE_TRUNCATED_SALT
+#undef BROKEN_NISPLUS_INCLUDE_FILES
+#undef HAVE_RPC_AUTH_ERROR_CONFLICT
+#undef HAVE_EXPLICIT_LARGEFILE_SUPPORT
+#undef USE_BOTH_CRYPT_CALLS
+#undef HAVE_BROKEN_FCNTL64_LOCKS
+#undef HAVE_SECURE_MKSTEMP
+#undef HAVE_FNMATCH
+#undef USE_SETEUID
+#undef USE_SETRESUID
+#undef USE_SETREUID
+#undef USE_SETUIDX
+#undef HAVE_DLOPEN
+#undef HAVE_DLCLOSE
+#undef HAVE_DLSYM
+#undef HAVE_DLERROR
+#undef SYSCONF_SC_NGROUPS_MAX
+#undef HAVE_UT_UT_NAME
+#undef HAVE_UT_UT_USER
+#undef HAVE_UT_UT_ID
+#undef HAVE_UT_UT_HOST
+#undef HAVE_UT_UT_TIME
+#undef HAVE_UT_UT_TV
+#undef HAVE_UT_UT_TYPE
+#undef HAVE_UT_UT_PID
+#undef HAVE_UT_UT_EXIT
+#undef HAVE_UT_UT_ADDR
+#undef HAVE_UX_UT_SYSLEN
+#undef PUTUTLINE_RETURNS_UTMP
+#undef COMPILER_SUPPORTS_LL
+#undef HAVE_YP_GET_DEFAULT_DOMAIN
+#undef USE_SPINLOCKS
+#undef SPARC_SPINLOCKS
+#undef INTEL_SPINLOCKS
+#undef MIPS_SPINLOCKS
+#undef POWERPC_SPINLOCKS
+#undef HAVE_POSIX_ACLS
+#undef HAVE_ACL_GET_PERM_NP
+#undef HAVE_UNIXWARE_ACLS
+#undef HAVE_SOLARIS_ACLS
+#undef HAVE_HPUX_ACLS
+#undef HAVE_IRIX_ACLS
+#undef HAVE_AIX_ACLS
+#undef HAVE_TRU64_ACLS
+#undef HAVE_NO_ACLS
+#undef HAVE_LIBPAM
+#undef HAVE_ASPRINTF_DECL
+#undef HAVE_VASPRINTF_DECL
+#undef HAVE_SNPRINTF_DECL
+#undef HAVE_VSNPRINTF_DECL
+#undef HAVE_UNIXSOCKET
+#undef MMAP_BLACKLIST
+#undef HAVE_CUPS
+#undef WITH_LDAP_SAM
+#undef WITH_NISPLUS_SAM
+#undef WITH_SMBPASSWD_SAM
+#undef WITH_TDB_SAM
+#undef LINUX_QUOTAS_1
+#undef LINUX_QUOTAS_2
+#undef BROKEN_REDHAT_7_SYSTEM_HEADERS
+#undef HAVE_IMMEDIATE_STRUCTURES
+#undef HAVE_STAT_ST_BLOCKS
+#undef STAT_ST_BLOCKSIZE
+#undef HAVE_DEVICE_MAJOR_FN
+#undef HAVE_DEVICE_MINOR_FN
+#undef HAVE_MAKEDEV_FN
+#undef HAVE_GETGROUPS_TOO_MANY_EGIDS
+#undef HAVE_PASSWD_PW_COMMENT
+#undef HAVE_PASSWD_PW_AGE
+#undef HAVE_STAT_ST_BLKSIZE
+#undef WITH_WINBIND_AUTH_CRAP
+#undef WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK
+
+/*
+ * Add these definitions to allow VFS modules to
+ * see the CPPFLAGS defines.
+ */
+#ifndef _HPUX_SOURCE
+#undef _HPUX_SOURCE
+#endif
+#ifndef _POSIX_SOURCE
+#undef _POSIX_SOURCE
+#endif
+#ifndef _LARGEFILE64_SOURCE
+#undef _LARGEFILE64_SOURCE
+#endif
+#ifndef _ALIGNMENT_REQUIRED
+#undef _ALIGNMENT_REQUIRED
+#endif
+#ifndef _MAX_ALIGNMENT
+#undef _MAX_ALIGNMENT
+#endif
+#ifndef _LARGE_FILES
+#undef _LARGE_FILES
+#endif
+#ifndef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+#ifndef _GNU_SOURCE
+#undef _GNU_SOURCE
+#endif
+#undef HAVE_SENDFILE
+#undef HAVE_SENDFILE64
+#undef LINUX_SENDFILE_API
+#undef LINUX_BROKEN_SENDFILE_API
+#undef WITH_SENDFILE
+#undef FREEBSD_SENDFILE_API
+#undef HPUX_SENDFILE_API
+#undef HAVE_SENDFILEV
+#undef HAVE_SENDFILEV64
+#undef SOLARIS_SENDFILE_API
+#undef LDAP_SET_REBIND_PROC_ARGS
+#undef POSIX_ACL_NEEDS_MASK
+#undef BROKEN_GETGRNAM
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index 6de11953b44..4ae5336a4bf 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -32,49 +32,10 @@ AC_DEFUN(AC_DIRENT_D_OFF,
#include <dirent.h>], [struct dirent d; d.d_off;],
ac_cv_dirent_d_off=yes, ac_cv_dirent_d_off=no)])
if test $ac_cv_dirent_d_off = yes; then
- AC_DEFINE(HAVE_DIRENT_D_OFF,1,[Whether dirent has a d_off member])
+ AC_DEFINE(HAVE_DIRENT_D_OFF)
fi
])
-dnl Mark specified module as shared
-dnl SMB_MODULE(name,static_files,shared_files,subsystem,whatif-static,whatif-shared)
-AC_DEFUN(SMB_MODULE,
-[
- AC_MSG_CHECKING([how to build $1])
- if test "$[MODULE_][$1]"; then
- DEST=$[MODULE_][$1]
- elif test "$[MODULE_]translit([$4], [A-Z], [a-z])" -a "$[MODULE_DEFAULT_][$1]"; then
- DEST=$[MODULE_]translit([$4], [A-Z], [a-z])
- else
- DEST=$[MODULE_DEFAULT_][$1]
- fi
-
- if test x"$DEST" = xSHARED; then
- AC_DEFINE([$1][_init], [init_module], [Whether to build $1 as shared module])
- $4_MODULES="$$4_MODULES $3"
- AC_MSG_RESULT([shared])
- [$6]
- string_shared_modules="$string_shared_modules $1"
- elif test x"$DEST" = xSTATIC; then
- [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init();"
- string_static_modules="$string_static_modules $1"
- $4_STATIC="$$4_STATIC $2"
- AC_SUBST($4_STATIC)
- [$5]
- AC_MSG_RESULT([static])
- else
- string_ignored_modules="$string_ignored_modules $1"
- AC_MSG_RESULT([not])
- fi
-])
-
-AC_DEFUN(SMB_SUBSYSTEM,
-[
- AC_SUBST($1_STATIC)
- AC_SUBST($1_MODULES)
- AC_DEFINE_UNQUOTED([static_init_]translit([$1], [A-Z], [a-z]), [{$init_static_modules_]translit([$1], [A-Z], [a-z])[}], [Static init functions])
- ifelse([$2], , :, [rm -f $2])
-])
dnl AC_PROG_CC_FLAG(flag)
AC_DEFUN(AC_PROG_CC_FLAG,
@@ -97,7 +58,7 @@ AC_DEFUN(AC_HAVE_DECL,
AC_TRY_COMPILE([$2],[int i = (int)$1],
ac_cv_have_$1_decl=yes,ac_cv_have_$1_decl=no)])
if test x"$ac_cv_have_$1_decl" = x"yes"; then
- AC_DEFINE([HAVE_]translit([$1], [a-z], [A-Z])[_DECL],1,[Whether $1() is available])
+ AC_DEFINE([HAVE_]translit([$1], [a-z], [A-Z])[_DECL])
fi
])
@@ -114,113 +75,6 @@ AC_DEFUN(AC_LIBTESTFUNC,
esac
])
-# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION],
-# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
-# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES])
-# ------------------------------------------------------
-#
-# Use a cache variable name containing both the library and function name,
-# because the test really is for library $1 defining function $3, not
-# just for library $1. Separate tests with the same $1 and different $3s
-# may have different results.
-#
-# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3])
-# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give
-# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence
-# the AS_LITERAL_IF indirection.
-#
-# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally,
-# whatever the FUNCTION, in addition to not being a *S macro. Note
-# that the cache does depend upon the function we are looking for.
-#
-# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just
-# `ac_save_LIBS': there are many macros which don't want to see `LIBS'
-# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'.
-# And ``ac_save_LIBS' is too tempting a name, so let's leave them some
-# freedom.
-AC_DEFUN([AC_CHECK_LIB_EXT],
-[
-AH_CHECK_LIB_EXT([$1])
-ac_check_lib_ext_save_LIBS=$LIBS
-LIBS="-l$1 $$2 $7 $LIBS"
-AS_LITERAL_IF([$1],
- [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])],
- [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl
-
-m4_ifval([$3],
- [
- AH_CHECK_FUNC_EXT([$3])
- AS_LITERAL_IF([$1],
- [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])],
- [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl
- AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func,
- [AC_TRY_LINK_FUNC($3,
- [AS_VAR_SET(ac_Lib_func, yes);
- AS_VAR_SET(ac_Lib_ext, yes)],
- [AS_VAR_SET(ac_Lib_func, no);
- AS_VAR_SET(ac_Lib_ext, no)])
- ])
- AS_IF([test AS_VAR_GET(ac_Lib_func) = yes],
- [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl
- AS_VAR_POPDEF([ac_Lib_func])dnl
- ],[
- AC_CACHE_CHECK([for -l$1], ac_Lib_ext,
- [AC_TRY_LINK_FUNC([main],
- [AS_VAR_SET(ac_Lib_ext, yes)],
- [AS_VAR_SET(ac_Lib_ext, no)])
- ])
- ])
-LIBS=$ac_check_lib_ext_save_LIBS
-
-AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes],
- [m4_default([$4],
- [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
- case "$$2" in
- *-l$1*)
- ;;
- *)
- $2="-l$1 $$2"
- ;;
- esac])
- [$6]
- ],
- [$5])dnl
-AS_VAR_POPDEF([ac_Lib_ext])dnl
-])# AC_CHECK_LIB_EXT
-
-# AH_CHECK_LIB_EXT(LIBNAME)
-# ---------------------
-m4_define([AH_CHECK_LIB_EXT],
-[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1),
- [Define to 1 if you have the `]$1[' library (-l]$1[).])])
-
-# AC_CHECK_FUNCS_EXT(FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-# -----------------------------------------------------------------
-dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable.
-dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE)
-AC_DEFUN([AC_CHECK_FUNC_EXT],
-[
- AH_CHECK_FUNC_EXT($1)
- ac_check_func_ext_save_LIBS=$LIBS
- LIBS="$2 $LIBS"
- AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl
- AC_CACHE_CHECK([for $1], ac_var,
- [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])],
- [AS_VAR_SET(ac_var, yes)],
- [AS_VAR_SET(ac_var, no)])])
- LIBS=$ac_check_func_ext_save_LIBS
- AS_IF([test AS_VAR_GET(ac_var) = yes],
- [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3],
- [$4])dnl
-AS_VAR_POPDEF([ac_var])dnl
-])# AC_CHECK_FUNC
-
-# AH_CHECK_FUNC_EXT(FUNCNAME)
-# ---------------------
-m4_define([AH_CHECK_FUNC_EXT],
-[AH_TEMPLATE(AS_TR_CPP(HAVE_$1),
- [Define to 1 if you have the `]$1[' function.])])
-
dnl Define an AC_DEFINE with ifndef guard.
dnl AC_N_DEFINE(VARIABLE [, VALUE])
define(AC_N_DEFINE,
@@ -249,527 +103,3 @@ else
ac_cv_prog_gnu_ld=no
fi])
])
-
-# Configure paths for LIBXML2
-# Toshio Kuratomi 2001-04-21
-# Adapted from:
-# Configure paths for GLIB
-# Owen Taylor 97-11-3
-
-dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for XML, and define XML_CFLAGS and XML_LIBS
-dnl
-AC_DEFUN(AM_PATH_XML2,[
-AC_ARG_WITH(xml-prefix,
- [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
- xml_config_prefix="$withval", xml_config_prefix="")
-AC_ARG_WITH(xml-exec-prefix,
- [ --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
- xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
-AC_ARG_ENABLE(xmltest,
- [ --disable-xmltest Do not try to compile and run a test LIBXML program],,
- enable_xmltest=yes)
-
- if test x$xml_config_exec_prefix != x ; then
- xml_config_args="$xml_config_args --exec-prefix=$xml_config_exec_prefix"
- if test x${XML2_CONFIG+set} != xset ; then
- XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
- fi
- fi
- if test x$xml_config_prefix != x ; then
- xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
- if test x${XML2_CONFIG+set} != xset ; then
- XML2_CONFIG=$xml_config_prefix/bin/xml2-config
- fi
- fi
-
- AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
- min_xml_version=ifelse([$1], ,2.0.0,[$1])
- AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
- no_xml=""
- if test "$XML2_CONFIG" = "no" ; then
- no_xml=yes
- else
- XML_CFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
- XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
- xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
- xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
- xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
- if test "x$enable_xmltest" = "xyes" ; then
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $XML_CFLAGS"
- LIBS="$XML_LIBS $LIBS"
-dnl
-dnl Now check if the installed libxml is sufficiently new.
-dnl (Also sanity checks the results of xml2-config to some extent)
-dnl
- rm -f conf.xmltest
- AC_TRY_RUN([
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <libxml/xmlversion.h>
-
-int
-main()
-{
- int xml_major_version, xml_minor_version, xml_micro_version;
- int major, minor, micro;
- char *tmp_version;
-
- system("touch conf.xmltest");
-
- /* Capture xml2-config output via autoconf/configure variables */
- /* HP/UX 9 (%@#!) writes to sscanf strings */
- tmp_version = (char *)strdup("$min_xml_version");
- if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
- printf("%s, bad version string from xml2-config\n", "$min_xml_version");
- exit(1);
- }
- free(tmp_version);
-
- /* Capture the version information from the header files */
- tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
- if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
- printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
- exit(1);
- }
- free(tmp_version);
-
- /* Compare xml2-config output to the libxml headers */
- if ((xml_major_version != $xml_config_major_version) ||
- (xml_minor_version != $xml_config_minor_version) ||
- (xml_micro_version != $xml_config_micro_version))
- {
- printf("*** libxml header files (version %d.%d.%d) do not match\n",
- xml_major_version, xml_minor_version, xml_micro_version);
- printf("*** xml2-config (version %d.%d.%d)\n",
- $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
- return 1;
- }
-/* Compare the headers to the library to make sure we match */
- /* Less than ideal -- doesn't provide us with return value feedback,
- * only exits if there's a serious mismatch between header and library.
- */
- LIBXML_TEST_VERSION;
-
- /* Test that the library is greater than our minimum version */
- if ((xml_major_version > major) ||
- ((xml_major_version == major) && (xml_minor_version > minor)) ||
- ((xml_major_version == major) && (xml_minor_version == minor) &&
- (xml_micro_version >= micro)))
- {
- return 0;
- }
- else
- {
- printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
- xml_major_version, xml_minor_version, xml_micro_version);
- printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
- major, minor, micro);
- printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
- printf("***\n");
- printf("*** If you have already installed a sufficiently new version, this error\n");
- printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
- printf("*** being found. The easiest way to fix this is to remove the old version\n");
- printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
- printf("*** correct copy of xml2-config. (In this case, you will have to\n");
- printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
- printf("*** so that the correct libraries are found at run-time))\n");
- }
- return 1;
-}
-],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- fi
- fi
-
- if test "x$no_xml" = x ; then
- AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
- ifelse([$2], , :, [$2])
- else
- AC_MSG_RESULT(no)
- if test "$XML2_CONFIG" = "no" ; then
- echo "*** The xml2-config script installed by LIBXML could not be found"
- echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
- echo "*** your path, or set the XML2_CONFIG environment variable to the"
- echo "*** full path to xml2-config."
- else
- if test -f conf.xmltest ; then
- :
- else
- echo "*** Could not run libxml test program, checking why..."
- CFLAGS="$CFLAGS $XML_CFLAGS"
- LIBS="$LIBS $XML_LIBS"
- AC_TRY_LINK([
-#include <libxml/xmlversion.h>
-#include <stdio.h>
-], [ LIBXML_TEST_VERSION; return 0;],
- [ echo "*** The test program compiled, but did not run. This usually means"
- echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
- echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
- echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
- echo "*** to the installed location Also, make sure you have run ldconfig if that"
- echo "*** is required on your system"
- echo "***"
- echo "*** If you have an old version installed, it is best to remove it, although"
- echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
- [ echo "*** The test program failed to compile or link. See the file config.log for the"
- echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
- echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
- echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- fi
- fi
-
- XML_CFLAGS=""
- XML_LIBS=""
- ifelse([$3], , :, [$3])
- fi
- AC_SUBST(XML_CFLAGS)
- AC_SUBST(XML_LIBS)
- rm -f conf.xmltest
-])
-
-# =========================================================================
-# AM_PATH_MYSQL : MySQL library
-
-dnl AM_PATH_MYSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for MYSQL, and define MYSQL_CFLAGS and MYSQL_LIBS
-dnl
-AC_DEFUN(AM_PATH_MYSQL,
-[dnl
-dnl Get the cflags and libraries from the mysql_config script
-dnl
-AC_ARG_WITH(mysql-prefix,[ --with-mysql-prefix=PFX Prefix where MYSQL is installed (optional)],
- mysql_prefix="$withval", mysql_prefix="")
-AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where MYSQL is installed (optional)],
- mysql_exec_prefix="$withval", mysql_exec_prefix="")
-
- if test x$mysql_exec_prefix != x ; then
- mysql_args="$mysql_args --exec-prefix=$mysql_exec_prefix"
- if test x${MYSQL_CONFIG+set} != xset ; then
- MYSQL_CONFIG=$mysql_exec_prefix/bin/mysql_config
- fi
- fi
- if test x$mysql_prefix != x ; then
- mysql_args="$mysql_args --prefix=$mysql_prefix"
- if test x${MYSQL_CONFIG+set} != xset ; then
- MYSQL_CONFIG=$mysql_prefix/bin/mysql_config
- fi
- fi
-
- AC_REQUIRE([AC_CANONICAL_TARGET])
- AC_PATH_PROG(MYSQL_CONFIG, mysql_config, no)
- AC_MSG_CHECKING(for MYSQL)
- no_mysql=""
- if test "$MYSQL_CONFIG" = "no" ; then
- MYSQL_CFLAGS=""
- MYSQL_LIBS=""
- AC_MSG_RESULT(no)
- ifelse([$2], , :, [$2])
- else
- MYSQL_CFLAGS=`$MYSQL_CONFIG $mysqlconf_args --cflags | sed -e "s/'//g"`
- MYSQL_LIBS=`$MYSQL_CONFIG $mysqlconf_args --libs | sed -e "s/'//g"`
- AC_MSG_RESULT(yes)
- ifelse([$1], , :, [$1])
- fi
- AC_SUBST(MYSQL_CFLAGS)
- AC_SUBST(MYSQL_LIBS)
-])
-
-# =========================================================================
-# AM_PATH_PGSQL : pgSQL library
-
-dnl AM_PATH_PGSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for PGSQL, and define PGSQL_CFLAGS and PGSQL_LIBS
-dnl
-AC_DEFUN(AM_PATH_PGSQL,
-[dnl
-dnl Get the cflags and libraries from the pg_config script
-dnl
-AC_ARG_WITH(pgsql-prefix,[ --with-pgsql-prefix=PFX Prefix where PostgreSQL is installed (optional)],
- pgsql_prefix="$withval", pgsql_prefix="")
-AC_ARG_WITH(pgsql-exec-prefix,[ --with-pgsql-exec-prefix=PFX Exec prefix where PostgreSQL is installed (optional)],
- pgsql_exec_prefix="$withval", pgsql_exec_prefix="")
-
- if test x$pgsql_exec_prefix != x ; then
- if test x${PGSQL_CONFIG+set} != xset ; then
- PGSQL_CONFIG=$pgsql_exec_prefix/bin/pg_config
- fi
- fi
- if test x$pgsql_prefix != x ; then
- if test x${PGSQL_CONFIG+set} != xset ; then
- PGSQL_CONFIG=$pgsql_prefix/bin/pg_config
- fi
- fi
-
- AC_REQUIRE([AC_CANONICAL_TARGET])
- AC_PATH_PROG(PGSQL_CONFIG, pg_config, no, [$PATH:/usr/lib/postgresql/bin])
- AC_MSG_CHECKING(for PGSQL)
- no_pgsql=""
- if test "$PGSQL_CONFIG" = "no" ; then
- PGSQL_CFLAGS=""
- PGSQL_LIBS=""
- AC_MSG_RESULT(no)
- ifelse([$2], , :, [$2])
- else
- PGSQL_CFLAGS=-I`$PGSQL_CONFIG --includedir`
- PGSQL_LIBS="-lpq -L`$PGSQL_CONFIG --libdir`"
- AC_MSG_RESULT(yes)
- ifelse([$1], , :, [$1])
- fi
- AC_SUBST(PGSQL_CFLAGS)
- AC_SUBST(PGSQL_LIBS)
-])
-
-dnl Removes -I/usr/include/? from given variable
-AC_DEFUN(CFLAGS_REMOVE_USR_INCLUDE,[
- ac_new_flags=""
- for i in [$]$1; do
- case [$]i in
- -I/usr/include|-I/usr/include/) ;;
- *) ac_new_flags="[$]ac_new_flags [$]i" ;;
- esac
- done
- $1=[$]ac_new_flags
-])
-
-dnl Removes -L/usr/lib/? from given variable
-AC_DEFUN(LIB_REMOVE_USR_LIB,[
- ac_new_flags=""
- for i in [$]$1; do
- case [$]i in
- -L/usr/lib|-L/usr/lib/) ;;
- *) ac_new_flags="[$]ac_new_flags [$]i" ;;
- esac
- done
- $1=[$]ac_new_flags
-])
-
-dnl From Bruno Haible.
-
-AC_DEFUN(jm_ICONV,
-[
- dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
- dnl those with the standalone portable libiconv installed).
- AC_MSG_CHECKING(for iconv in $1)
- jm_cv_func_iconv="no"
- jm_cv_lib_iconv=""
- jm_cv_giconv=no
- jm_save_LIBS="$LIBS"
- LIBS="$LIBS -lbiconv"
- AC_TRY_LINK([#include <stdlib.h>
-#include <biconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_func_iconv=yes
- jm_cv_biconv=yes
- jm_cv_include="biconv.h"
- jm_cv_lib_iconv="biconv")
- LIBS="$jm_save_LIBS"
-
- dnl Check for include in funny place but no lib needed
- if test "$jm_cv_func_iconv" != yes; then
- AC_TRY_LINK([#include <stdlib.h>
-#include <giconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_func_iconv=yes
- jm_cv_include="giconv.h"
- jm_cv_giconv="yes"
- jm_cv_lib_iconv="")
-
- dnl Standard iconv.h include, lib in glibc or libc ...
- if test "$jm_cv_func_iconv" != yes; then
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_include="iconv.h"
- jm_cv_func_iconv=yes
- jm_cv_lib_iconv="")
-
- if test "$jm_cv_lib_iconv" != yes; then
- jm_save_LIBS="$LIBS"
- LIBS="$LIBS -lgiconv"
- AC_TRY_LINK([#include <stdlib.h>
-#include <giconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_lib_iconv=yes
- jm_cv_func_iconv=yes
- jm_cv_include="giconv.h"
- jm_cv_giconv=yes
- jm_cv_lib_iconv="giconv")
-
- LIBS="$jm_save_LIBS"
-
- if test "$jm_cv_func_iconv" != yes; then
- jm_save_LIBS="$LIBS"
- LIBS="$LIBS -liconv"
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_include="iconv.h"
- jm_cv_func_iconv=yes
- jm_cv_lib_iconv="iconv")
- LIBS="$jm_save_LIBS"
- fi
- fi
- fi
- fi
- if test "$jm_cv_func_iconv" = yes; then
- if test "$jm_cv_giconv" = yes; then
- AC_DEFINE(HAVE_GICONV, 1, [What header to include for iconv() function: giconv.h])
- AC_MSG_RESULT(yes)
- ICONV_FOUND=yes
- else
- if test "$jm_cv_biconv" = yes; then
- AC_DEFINE(HAVE_BICONV, 1, [What header to include for iconv() function: biconv.h])
- AC_MSG_RESULT(yes)
- ICONV_FOUND=yes
- else
- AC_DEFINE(HAVE_ICONV, 1, [What header to include for iconv() function: iconv.h])
- AC_MSG_RESULT(yes)
- ICONV_FOUND=yes
- fi
- fi
- else
- AC_MSG_RESULT(no)
- fi
-])
-
-AC_DEFUN(rjs_CHARSET,[
- dnl Find out if we can convert from $1 to UCS2-LE
- AC_MSG_CHECKING([can we convert from $1 to UCS2-LE?])
- AC_TRY_RUN([
-#include <$jm_cv_include>
-main(){
- iconv_t cd = iconv_open("$1", "UCS-2LE");
- if (cd == 0 || cd == (iconv_t)-1) {
- return -1;
- }
- return 0;
-}
- ],ICONV_CHARSET=$1,ICONV_CHARSET=no,ICONV_CHARSET=cross)
- AC_MSG_RESULT($ICONV_CHARSET)
-])
-
-dnl CFLAGS_ADD_DIR(CFLAGS, $INCDIR)
-dnl This function doesn't add -I/usr/include into CFLAGS
-AC_DEFUN(CFLAGS_ADD_DIR,[
-if test "$2" != "/usr/include" ; then
- $1="$$1 -I$2"
-fi
-])
-
-dnl LIB_ADD_DIR(LDFLAGS, $LIBDIR)
-dnl This function doesn't add -L/usr/lib into LDFLAGS
-AC_DEFUN(LIB_ADD_DIR,[
-if test "$2" != "/usr/lib" ; then
- $1="$$1 -L$2"
-fi
-])
-
-dnl AC_ENABLE_SHARED - implement the --enable-shared flag
-dnl Usage: AC_ENABLE_SHARED[(DEFAULT)]
-dnl Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
-dnl `yes'.
-AC_DEFUN([AC_ENABLE_SHARED],
-[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE(shared,
-changequote(<<, >>)dnl
-<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
-changequote([, ])dnl
-[p=${PACKAGE-default}
-case $enableval in
-yes) enable_shared=yes ;;
-no) enable_shared=no ;;
-*)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
-
- done
- IFS="$ac_save_ifs"
- ;;
-esac],
-enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
-])
-
-dnl AC_ENABLE_STATIC - implement the --enable-static flag
-dnl Usage: AC_ENABLE_STATIC[(DEFAULT)]
-dnl Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
-dnl `yes'.
-AC_DEFUN([AC_ENABLE_STATIC],
-[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE(static,
-changequote(<<, >>)dnl
-<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
-changequote([, ])dnl
-[p=${PACKAGE-default}
-case $enableval in
-yes) enable_static=yes ;;
-no) enable_static=no ;;
-*)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac],
-enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
-])
-
-dnl AC_DISABLE_STATIC - set the default static flag to --disable-static
-AC_DEFUN([AC_DISABLE_STATIC],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_STATIC(no)])
-
-dnl AC_TRY_RUN_STRICT(PROGRAM,CFLAGS,CPPFLAGS,LDFLAGS,
-dnl [ACTION-IF-TRUE],[ACTION-IF-FALSE],
-dnl [ACTION-IF-CROSS-COMPILING = RUNTIME-ERROR])
-AC_DEFUN( [AC_TRY_RUN_STRICT],
-[
- old_CFLAGS="$CFLAGS";
- CFLAGS="$2";
- export CFLAGS;
- old_CPPFLAGS="$CPPFLAGS";
- CPPFLAGS="$3";
- export CPPFLAGS;
- old_LDFLAGS="$LDFLAGS";
- LDFLAGS="$4";
- export LDFLAGS;
- AC_TRY_RUN([$1],[$5],[$6],[$7]);
- CFLAGS="$old_CFLAGS";
- old_CFLAGS="";
- export CFLAGS;
- CPPFLAGS="$old_CPPFLAGS";
- old_CPPFLAGS="";
- export CPPFLAGS;
- LDFLAGS="$old_LDFLAGS";
- old_LDFLAGS="";
- export LDFLAGS;
-])
diff --git a/source/aparser/parser.c b/source/aparser/parser.c
index 0c7153e1fb7..c2348b84f96 100644
--- a/source/aparser/parser.c
+++ b/source/aparser/parser.c
@@ -460,12 +460,8 @@ realloc some memory for a parse structure
********************************************************************/
BOOL io_realloc(char *name, io_struct *ps, void **ptr, unsigned size)
{
- BOOL ret = True;
- void *tp;
-
- tp = (void *)Realloc(*ptr, size);
- if (tp) *ptr = tp;
- else ret = False;
- return ret;
+ (*ptr) = (void *)Realloc(*ptr, size);
+ if (*ptr) return True;
+ return False;
}
diff --git a/source/aparser/parser.h b/source/aparser/parser.h
index 319aeb5d138..28317b9e007 100644
--- a/source/aparser/parser.h
+++ b/source/aparser/parser.h
@@ -40,7 +40,7 @@ typedef uint16 ZUSTRING;
#ifndef _PSTRING
#define PSTRING_LEN 1024
-#define FSTRING_LEN 128
+#define FSTRING_LEN 256
typedef char pstring[PSTRING_LEN];
typedef char fstring[FSTRING_LEN];
@@ -52,7 +52,7 @@ typedef char fstring[FSTRING_LEN];
#define True 1
/* zero a structure given a pointer to the structure */
-#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
+#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
#define MAX_UNISTRLEN 256
#define MAX_STRINGLEN 256
diff --git a/source/architecture.doc b/source/architecture.doc
new file mode 100755
index 00000000000..eb29792bea0
--- /dev/null
+++ b/source/architecture.doc
@@ -0,0 +1,134 @@
+Samba Architecture
+------------------
+
+First preliminary version Dan Shearer Nov 97
+Quickly scrabbled together from odd bits of mail and memory. Please update.
+
+This document gives a general overview of how Samba works
+internally. The Samba Team has tried to come up with a model which is
+the best possible compromise between elegance, portability, security
+and the constraints imposed by the very messy SMB and CIFS
+protocol.
+
+It also tries to answer some of the frequently asked questions such as:
+
+ * Is Samba secure when running on Unix? The xyz platform?
+ What about the root priveliges issue?
+
+ * Pros and cons of multithreading in various parts of Samba
+
+ * Why not have a separate process for name resolution, WINS,
+ and browsing?
+
+
+Multithreading and Samba
+------------------------
+
+People sometimes tout threads as a uniformly good thing. They are very
+nice in their place but are quite inappropriate for smbd. nmbd is
+another matter, and multi-threading it would be very nice.
+
+The short version is that smbd is not multithreaded, and alternative
+servers that take this approach under Unix (such as Syntax, at the
+time of writing) suffer tremendous performance penalties and are less
+robust. nmbd is not threaded either, but this is because it is not
+possible to do it while keeping code consistent and portable across 35
+or more platforms. (This drawback also applies to threading smbd.)
+
+The longer versions is that there are very good reasons for not making
+smbd multi-threaded. Multi-threading would actually make Samba much
+slower, less scalable, less portable and much less robust. The fact
+that we use a separate process for each connection is one of Samba's
+biggest advantages.
+
+Threading smbd
+--------------
+
+A few problems that would arise from a threaded smbd are:
+
+0) It's not only to create threads instead of processes, but you
+ must care about all variables if they have to be thread specific
+ (currently they would be global).
+
+1) if one thread dies (eg. a seg fault) then all threads die. We can
+immediately throw robustness out the window.
+
+2) many of the system calls we make are blocking. Non-blocking
+equivalents of many calls are either not available or are awkward (and
+slow) to use. So while we block in one thread all clients are
+waiting. Imagine if one share is a slow NFS filesystem and the others
+are fast, we will end up slowing all clients to the speed of NFS.
+
+3) you can't run as a different uid in different threads. This means
+we would have to switch uid/gid on _every_ SMB packet. It would be
+horrendously slow.
+
+4) the per process file descriptor limit would mean that we could only
+support a limited number of clients.
+
+5) we couldn't use the system locking calls as the locking context of
+fcntl() is a process, not a thread.
+
+Threading nmbd
+--------------
+
+This would be ideal, but gets sunk by portability requirements.
+
+Andrew tried to write a test threads library for nmbd that used only
+ansi-C constructs (using setjmp and longjmp). Unfortunately some OSes
+defeat this by restricting longjmp to calling addresses that are
+shallower than the current address on the stack (apparently AIX does
+this). This makes a truly portable threads library impossible. So to
+support all our current platforms we would have to code nmbd both with
+and without threads, and as the real aim of threads is to make the
+code clearer we would not have gained anything. (it is a myth that
+threads make things faster. threading is like recursion, it can make
+things clear but the same thing can always be done faster by some
+other method)
+
+Chris tried to spec out a general design that would abstract threading
+vs separate processes (vs other methods?) and make them accessible
+through some general API. This doesn't work because of the data
+sharing requirements of the protocol (packets in the future depending
+on packets now, etc.) At least, the code would work but would be very
+clumsy, and besides the fork() type model would never work on Unix. (Is there an OS that it would work on, for nmbd?)
+
+A fork() is cheap, but not nearly cheap enough to do on every UDP
+packet that arrives. Having a pool of processes is possible but is
+nasty to program cleanly due to the enormous amount of shared data (in
+complex structures) between the processes. We can't rely on each
+platform having a shared memory system.
+
+nbmd Design
+-----------
+
+Originally Andrew used recursion to simulate a multi-threaded
+environment, which use the stack enormously and made for really
+confusing debugging sessions. Luke Leighton rewrote it to use a
+queuing system that keeps state information on each packet. The
+first version used a single structure which was used by all the
+pending states. As the initialisation of this structure was
+done by adding arguments, as the functionality developed, it got
+pretty messy. So, it was replaced with a higher-order function
+and a pointer to a user-defined memory block. This suddenly
+made things much simpler: large numbers of functions could be
+made static, and modularised. This is the same principle as used
+in NT's kernel, and achieves the same effect as threads, but in
+a single process.
+
+Then Jeremy rewrote nmbd. The packet data in nmbd isn't what's on the
+wire. It's a nice format that is very amenable to processing but still
+keeps the idea of a distinct packet. See "struct packet_struct" in
+nameserv.h. It has all the detail but none of the on-the-wire
+mess. This makes it ideal for using in disk or memory-based databases
+for browsing and WINS support.
+
+nmbd now consists of a series of modules. It...
+
+
+Samba Design and Security
+-------------------------
+
+Why Isn't nmbd Multiple Daemons?
+--------------------------------
+
diff --git a/source/auth/auth.c b/source/auth/auth.c
deleted file mode 100644
index 1b49699fbca..00000000000
--- a/source/auth/auth.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2001-2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-static struct auth_init_function_entry *backends = NULL;
-
-static struct auth_init_function_entry *auth_find_backend_entry(const char *name);
-
-NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init)
-{
- struct auth_init_function_entry *entry = backends;
-
- if (version != AUTH_INTERFACE_VERSION) {
- DEBUG(0,("Can't register auth_method!\n"
- "You tried to register an auth module with AUTH_INTERFACE_VERSION %d, while this version of samba uses %d\n",
- version,AUTH_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !init) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5,("Attempting to register auth backend %s\n", name));
-
- if (auth_find_backend_entry(name)) {
- DEBUG(0,("There already is an auth method registered with the name %s!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct auth_init_function_entry));
- entry->name = smb_xstrdup(name);
- entry->init = init;
-
- DLIST_ADD(backends, entry);
- DEBUG(5,("Successfully added auth method '%s'\n", name));
- return NT_STATUS_OK;
-}
-
-static struct auth_init_function_entry *auth_find_backend_entry(const char *name)
-{
- struct auth_init_function_entry *entry = backends;
-
- while(entry) {
- if (strcmp(entry->name, name)==0) return entry;
- entry = entry->next;
- }
-
- return NULL;
-}
-
-/****************************************************************************
- Try to get a challenge out of the various authentication modules.
- Returns a const char of length 8 bytes.
-****************************************************************************/
-
-static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
-{
- DATA_BLOB challenge = data_blob(NULL, 0);
- const char *challenge_set_by = NULL;
- auth_methods *auth_method;
- TALLOC_CTX *mem_ctx;
-
- if (auth_context->challenge.length) {
- DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n",
- auth_context->challenge_set_by));
- return auth_context->challenge.data;
- }
-
- auth_context->challenge_may_be_modified = False;
-
- for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next) {
- if (auth_method->get_chal == NULL) {
- DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
- continue;
- }
-
- DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name));
- if (challenge_set_by != NULL) {
- DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authentication method %s has already specified a challenge. Challenge by %s ignored.\n",
- challenge_set_by, auth_method->name));
- continue;
- }
-
- mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name);
- if (!mem_ctx) {
- smb_panic("talloc_init() failed!");
- }
-
- challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
- if (!challenge.length) {
- DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
- auth_method->name));
- } else {
- DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
- auth_context->challenge = challenge;
- challenge_set_by = auth_method->name;
- auth_context->challenge_set_method = auth_method;
- }
- talloc_destroy(mem_ctx);
- }
-
- if (!challenge_set_by) {
- uchar chal[8];
-
- generate_random_buffer(chal, sizeof(chal), False);
- auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
- chal, sizeof(chal));
-
- challenge_set_by = "random";
- auth_context->challenge_may_be_modified = True;
- }
-
- DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
- DEBUG(5, ("challenge is: \n"));
- dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
-
- SMB_ASSERT(auth_context->challenge.length == 8);
-
- auth_context->challenge_set_by=challenge_set_by;
-
- return auth_context->challenge.data;
-}
-
-
-/**
- * Check user is in correct domain (if required)
- *
- * @param user Only used to fill in the debug message
- *
- * @param domain The domain to be verified
- *
- * @return True if the user can connect with that domain,
- * False otherwise.
-**/
-
-static BOOL check_domain_match(const char *user, const char *domain)
-{
- /*
- * If we aren't serving to trusted domains, we must make sure that
- * the validation request comes from an account in the same domain
- * as the Samba server
- */
-
- if (!lp_allow_trusted_domains() &&
- !(strequal("", domain) ||
- strequal(lp_workgroup(), domain) ||
- is_myname(domain))) {
- DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
- return False;
- } else {
- return True;
- }
-}
-
-/**
- * Check a user's Plaintext, LM or NTLM password.
- *
- * Check a user's password, as given in the user_info struct and return various
- * interesting details in the server_info struct.
- *
- * This function does NOT need to be in a become_root()/unbecome_root() pair
- * as it makes the calls itself when needed.
- *
- * The return value takes precedence over the contents of the server_info
- * struct. When the return is other than NT_STATUS_OK the contents
- * of that structure is undefined.
- *
- * @param user_info Contains the user supplied components, including the passwords.
- * Must be created with make_user_info() or one of its wrappers.
- *
- * @param auth_context Supplies the challenges and some other data.
- * Must be created with make_auth_context(), and the challenges should be
- * filled in, either at creation or by calling the challenge geneation
- * function auth_get_challenge().
- *
- * @param server_info If successful, contains information about the authentication,
- * including a SAM_ACCOUNT struct describing the user.
- *
- * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
- *
- **/
-
-static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
- const struct auth_usersupplied_info *user_info,
- struct auth_serversupplied_info **server_info)
-{
- /* if all the modules say 'not for me' this is reasonable */
- NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
- const char *unix_username;
- auth_methods *auth_method;
- TALLOC_CTX *mem_ctx;
-
- if (!user_info || !auth_context || !server_info)
- return NT_STATUS_LOGON_FAILURE;
-
- DEBUG(3, ("check_ntlm_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n",
- user_info->client_domain.str, user_info->smb_name.str, user_info->wksta_name.str));
-
- DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n",
- user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
-
- if (auth_context->challenge.length != 8) {
- DEBUG(0, ("check_ntlm_password: Invalid challenge stored for this auth context - cannot continue\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- if (auth_context->challenge_set_by)
- DEBUG(10, ("check_ntlm_password: auth_context challenge created by %s\n",
- auth_context->challenge_set_by));
-
- DEBUG(10, ("challenge is: \n"));
- dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("user_info has passwords of length %d and %d\n",
- user_info->lm_resp.length, user_info->nt_resp.length));
- DEBUG(100, ("lm:\n"));
- dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
- DEBUG(100, ("nt:\n"));
- dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
-#endif
-
- /* This needs to be sorted: If it doesn't match, what should we do? */
- if (!check_domain_match(user_info->smb_name.str, user_info->domain.str))
- return NT_STATUS_LOGON_FAILURE;
-
- for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
- NTSTATUS result;
-
- mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
- user_info->domain.str, user_info->smb_name.str);
-
- result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
-
- /* check if the module did anything */
- if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ) {
- DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name));
- talloc_destroy(mem_ctx);
- continue;
- }
-
- nt_status = result;
-
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n",
- auth_method->name, user_info->smb_name.str));
- } else {
- DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n",
- auth_method->name, user_info->smb_name.str, nt_errstr(nt_status)));
- }
-
- talloc_destroy(mem_ctx);
-
- if ( NT_STATUS_IS_OK(nt_status))
- {
- break;
- }
- }
-
- if (NT_STATUS_IS_OK(nt_status)) {
- unix_username = (*server_info)->unix_name;
- if (!(*server_info)->guest) {
- /* We might not be root if we are an RPC call */
- become_root();
- nt_status = smb_pam_accountcheck(unix_username);
- unbecome_root();
-
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n",
- unix_username));
- } else {
- DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] FAILED with error %s\n",
- unix_username, nt_errstr(nt_status)));
- }
- }
-
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG((*server_info)->guest ? 5 : 2,
- ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
- (*server_info)->guest ? "guest " : "",
- user_info->smb_name.str,
- user_info->internal_username.str,
- unix_username));
- }
- }
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n",
- user_info->smb_name.str, user_info->internal_username.str,
- nt_errstr(nt_status)));
- ZERO_STRUCTP(server_info);
- }
- return nt_status;
-}
-
-/***************************************************************************
- Clear out a auth_context, and destroy the attached TALLOC_CTX
-***************************************************************************/
-
-static void free_auth_context(struct auth_context **auth_context)
-{
- auth_methods *auth_method;
-
- if (*auth_context) {
- /* Free private data of context's authentication methods */
- for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) {
- if (auth_method->free_private_data) {
- auth_method->free_private_data (&auth_method->private_data);
- auth_method->private_data = NULL;
- }
- }
-
- talloc_destroy((*auth_context)->mem_ctx);
- *auth_context = NULL;
- }
-}
-
-/***************************************************************************
- Make a auth_info struct
-***************************************************************************/
-
-static NTSTATUS make_auth_context(struct auth_context **auth_context)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("authentication context");
-
- *auth_context = talloc(mem_ctx, sizeof(**auth_context));
- if (!*auth_context) {
- DEBUG(0,("make_auth_context: talloc failed!\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP(*auth_context);
-
- (*auth_context)->mem_ctx = mem_ctx;
- (*auth_context)->check_ntlm_password = check_ntlm_password;
- (*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
- (*auth_context)->free = free_auth_context;
-
- return NT_STATUS_OK;
-}
-
-BOOL load_auth_module(struct auth_context *auth_context,
- const char *module, auth_methods **ret)
-{
- static BOOL initialised_static_modules = False;
-
- struct auth_init_function_entry *entry;
- char *module_name = smb_xstrdup(module);
- char *module_params = NULL;
- char *p;
- BOOL good = False;
-
- /* Initialise static modules if not done so yet */
- if(!initialised_static_modules) {
- static_init_auth;
- initialised_static_modules = True;
- }
-
- DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n",
- module));
-
- p = strchr(module_name, ':');
- if (p) {
- *p = 0;
- module_params = p+1;
- trim_char(module_params, ' ', ' ');
- }
-
- trim_char(module_name, ' ', ' ');
-
- entry = auth_find_backend_entry(module_name);
-
- if (entry == NULL) {
- if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) {
- entry = auth_find_backend_entry(module_name);
- }
- }
-
- if (entry != NULL) {
- if (!NT_STATUS_IS_OK(entry->init(auth_context, module_params, ret))) {
- DEBUG(0,("load_auth_module: auth method %s did not correctly init\n",
- module_name));
- } else {
- DEBUG(5,("load_auth_module: auth method %s has a valid init\n",
- module_name));
- good = True;
- }
- } else {
- DEBUG(0,("load_auth_module: can't find auth method %s!\n", module_name));
- }
-
- SAFE_FREE(module_name);
- return good;
-}
-
-/***************************************************************************
- Make a auth_info struct for the auth subsystem
-***************************************************************************/
-
-static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list)
-{
- auth_methods *list = NULL;
- auth_methods *t = NULL;
- auth_methods *tmp;
- NTSTATUS nt_status;
-
- if (!text_list) {
- DEBUG(2,("make_auth_context_text_list: No auth method list!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
- return nt_status;
-
- for (;*text_list; text_list++) {
- if (load_auth_module(*auth_context, *text_list, &t)) {
- DLIST_ADD_END(list, t, tmp);
- }
- }
-
- (*auth_context)->auth_method_list = list;
-
- return nt_status;
-}
-
-/***************************************************************************
- Make a auth_context struct for the auth subsystem
-***************************************************************************/
-
-NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
-{
- char **auth_method_list = NULL;
- NTSTATUS nt_status;
-
- if (lp_auth_methods() && !str_list_copy(&auth_method_list, lp_auth_methods())) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (auth_method_list == NULL) {
- switch (lp_security())
- {
- case SEC_DOMAIN:
- DEBUG(5,("Making default auth method list for security=domain\n"));
- auth_method_list = str_list_make("guest sam winbind:ntdomain", NULL);
- break;
- case SEC_SERVER:
- DEBUG(5,("Making default auth method list for security=server\n"));
- auth_method_list = str_list_make("guest sam smbserver", NULL);
- break;
- case SEC_USER:
- if (lp_encrypted_passwords()) {
- if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
- DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam winbind:trustdomain", NULL);
- } else {
- DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam", NULL);
- }
- } else {
- DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix", NULL);
- }
- break;
- case SEC_SHARE:
- if (lp_encrypted_passwords()) {
- DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam", NULL);
- } else {
- DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix", NULL);
- }
- break;
- case SEC_ADS:
- DEBUG(5,("Making default auth method list for security=ADS\n"));
- auth_method_list = str_list_make("guest sam winbind:ntdomain", NULL);
- break;
- default:
- DEBUG(5,("Unknown auth method!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
- DEBUG(5,("Using specified auth order\n"));
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) {
- str_list_free(&auth_method_list);
- return nt_status;
- }
-
- str_list_free(&auth_method_list);
- return nt_status;
-}
-
-/***************************************************************************
- Make a auth_info struct with a fixed challenge
-***************************************************************************/
-
-NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[8])
-{
- NTSTATUS nt_status;
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
- return nt_status;
- }
-
- (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
- (*auth_context)->challenge_set_by = "fixed";
- return nt_status;
-}
-
-
diff --git a/source/auth/auth_builtin.c b/source/auth/auth_builtin.c
deleted file mode 100644
index 96c2221652e..00000000000
--- a/source/auth/auth_builtin.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Generic authentication types
- Copyright (C) Andrew Bartlett 2001-2002
- Copyright (C) Jelmer Vernooij 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/**
- * Return a guest logon for guest users (username = "")
- *
- * Typically used as the first module in the auth chain, this allows
- * guest logons to be dealt with in one place. Non-guest logons 'fail'
- * and pass onto the next module.
- **/
-
-static NTSTATUS check_guest_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- /* mark this as 'not for me' */
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
-
- if (!(user_info->internal_username.str
- && *user_info->internal_username.str)) {
- nt_status = make_server_info_guest(server_info);
- }
-
- return nt_status;
-}
-
-/* Guest modules initialisation */
-
-static NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method))
- return NT_STATUS_NO_MEMORY;
-
- (*auth_method)->auth = check_guest_security;
- (*auth_method)->name = "guest";
- return NT_STATUS_OK;
-}
-
-#ifdef DEVELOPER
-/**
- * Return an error based on username
- *
- * This function allows the testing of obsure errors, as well as the generation
- * of NT_STATUS -> DOS error mapping tables.
- *
- * This module is of no value to end-users.
- *
- * The password is ignored.
- *
- * @return An NTSTATUS value based on the username
- **/
-
-static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status;
- fstring user;
- long error_num;
- fstrcpy(user, user_info->smb_name.str);
-
- if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) {
- strupper_m(user);
- return nt_status_string_to_code(user);
- }
-
- strlower_m(user);
- error_num = strtoul(user, NULL, 16);
-
- DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num));
-
- nt_status = NT_STATUS(error_num);
-
- return nt_status;
-}
-
-/** Module initialisation function */
-
-static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method))
- return NT_STATUS_NO_MEMORY;
-
- (*auth_method)->auth = check_name_to_ntstatus_security;
- (*auth_method)->name = "name_to_ntstatus";
- return NT_STATUS_OK;
-}
-
-/**
- * Return a 'fixed' challenge instead of a variable one.
- *
- * The idea of this function is to make packet snifs consistant
- * with a fixed challenge, so as to aid debugging.
- *
- * This module is of no value to end-users.
- *
- * This module does not actually authenticate the user, but
- * just pretenteds to need a specified challenge.
- * This module removes *all* security from the challenge-response system
- *
- * @return NT_STATUS_UNSUCCESSFUL
- **/
-
-static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************************
- Get the challenge out of a password server.
-****************************************************************************/
-
-static DATA_BLOB auth_get_fixed_challenge(const struct auth_context *auth_context,
- void **my_private_data,
- TALLOC_CTX *mem_ctx)
-{
- const char *challenge = "I am a teapot";
- return data_blob(challenge, 8);
-}
-
-
-/** Module initailisation function */
-
-static NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method))
- return NT_STATUS_NO_MEMORY;
-
- (*auth_method)->auth = check_fixed_challenge_security;
- (*auth_method)->get_chal = auth_get_fixed_challenge;
- (*auth_method)->name = "fixed_challenge";
- return NT_STATUS_OK;
-}
-#endif /* DEVELOPER */
-
-NTSTATUS auth_builtin_init(void)
-{
- smb_register_auth(AUTH_INTERFACE_VERSION, "guest", auth_init_guest);
-#ifdef DEVELOPER
- smb_register_auth(AUTH_INTERFACE_VERSION, "fixed_challenge", auth_init_fixed_challenge);
- smb_register_auth(AUTH_INTERFACE_VERSION, "name_to_ntstatus", auth_init_name_to_ntstatus);
-#endif
- return NT_STATUS_OK;
-}
diff --git a/source/auth/auth_compat.c b/source/auth/auth_compat.c
deleted file mode 100644
index a70f1e98b72..00000000000
--- a/source/auth/auth_compat.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2001-2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/****************************************************************************
- COMPATIBILITY INTERFACES:
- ***************************************************************************/
-
-/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash
-return True if the password is correct, False otherwise
-****************************************************************************/
-
-NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info)
-{
- struct auth_context *plaintext_auth_context = NULL;
- auth_usersupplied_info *user_info = NULL;
- const uint8 *chal;
- NTSTATUS nt_status;
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
- return nt_status;
- }
-
- chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
-
- if (!make_user_info_for_reply(&user_info,
- smb_name, lp_workgroup(), chal,
- plaintext_password)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
- user_info, server_info);
-
- (plaintext_auth_context->free)(&plaintext_auth_context);
- free_user_info(&user_info);
- return nt_status;
-}
-
-static NTSTATUS pass_check_smb(const char *smb_name,
- const char *domain,
- DATA_BLOB lm_pwd,
- DATA_BLOB nt_pwd,
- DATA_BLOB plaintext_password,
- BOOL encrypted)
-
-{
- NTSTATUS nt_status;
- extern struct auth_context *negprot_global_auth_context;
- auth_serversupplied_info *server_info = NULL;
- if (encrypted) {
- auth_usersupplied_info *user_info = NULL;
- make_user_info_for_reply_enc(&user_info, smb_name,
- domain,
- lm_pwd,
- nt_pwd);
- nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
- user_info, &server_info);
- free_user_info(&user_info);
- } else {
- nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info);
- }
- free_server_info(&server_info);
- return nt_status;
-}
-
-/****************************************************************************
-check if a username/password pair is ok via the auth subsystem.
-return True if the password is correct, False otherwise
-****************************************************************************/
-BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
-{
-
- DATA_BLOB null_password = data_blob(NULL, 0);
- extern BOOL global_encrypted_passwords_negotiated;
- BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
-
- if (encrypted) {
- /*
- * The password could be either NTLM or plain LM. Try NTLM first,
- * but fall-through as required.
- * NTLMv2 makes no sense here.
- */
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
- return True;
- }
-
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
- return True;
- }
- } else {
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
- return True;
- }
- }
-
- return False;
-}
-
-
diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
deleted file mode 100644
index fdff0b52f96..00000000000
--- a/source/auth/auth_domain.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Authenticate against a remote domain
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-extern BOOL global_machine_password_needs_changing;
-
-/**
- * Connect to a remote server for (inter)domain security authenticaion.
- *
- * @param cli the cli to return containing the active connection
- * @param server either a machine name or text IP address to
- * connect to.
- * @param setup_creds_as domain account to setup credentials as
- * @param sec_chan a switch value to distinguish between domain
- * member and interdomain authentication
- * @param trust_passwd the trust password to establish the
- * credentials with.
- *
- **/
-
-static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
- const char *domain, const char *dc_name,
- struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- const unsigned char *trust_passwd,
- BOOL *retry)
-{
- NTSTATUS result;
-
- /* TODO: Send a SAMLOGON request to determine whether this is a valid
- logonserver. We can avoid a 30-second timeout if the DC is down
- if the SAMLOGON request fails as it is only over UDP. */
-
- /* we use a mutex to prevent two connections at once - when a
- Win2k PDC get two connections where one hasn't completed a
- session setup yet it will send a TCP reset to the first
- connection (tridge) */
-
- /*
- * With NT4.x DC's *all* authentication must be serialized to avoid
- * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
- */
-
- if (!grab_server_mutex(dc_name))
- return NT_STATUS_NO_LOGON_SERVERS;
-
- /* Attempt connection */
- *retry = True;
- result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0,
- "IPC$", "IPC", "", "", "", 0, Undefined, retry);
-
- if (!NT_STATUS_IS_OK(result)) {
- /* map to something more useful */
- if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
- result = NT_STATUS_NO_LOGON_SERVERS;
- }
-
- release_server_mutex();
- return result;
- }
-
- /*
- * We now have an anonymous connection to IPC$ on the domain password server.
- */
-
- /*
- * Even if the connect succeeds we need to setup the netlogon
- * pipe here. We do this as we may just have changed the domain
- * account password on the PDC and yet we may be talking to
- * a BDC that doesn't have this replicated yet. In this case
- * a successful connect to a DC needs to take the netlogon connect
- * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
- */
-
- if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
- DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
- cli_shutdown(*cli);
- release_server_mutex();
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as);
-
- /* This must be the remote domain (not ours) for schannel */
-
- fstrcpy( (*cli)->domain, domain );
-
- result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
-%s. Error was : %s.\n", dc_name, nt_errstr(result)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
- cli_shutdown(*cli);
- release_server_mutex();
- return result;
- }
-
- /* We exit here with the mutex *locked*. JRA */
-
- return NT_STATUS_OK;
-}
-
-/***********************************************************************
- Do the same as security=server, but using NT Domain calls and a session
- key from the machine password. If the server parameter is specified
- use it, otherwise figure out a server from the 'password server' param.
-************************************************************************/
-
-static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- const char *domain,
- uchar chal[8],
- auth_serversupplied_info **server_info,
- const char *dc_name, struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- unsigned char trust_passwd[16],
- time_t last_change_time)
-{
- NET_USER_INFO_3 info3;
- struct cli_state *cli = NULL;
- NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
- int i;
- BOOL retry = True;
-
- /*
- * At this point, smb_apasswd points to the lanman response to
- * the challenge in local_challenge, and smb_ntpasswd points to
- * the NT response to the challenge in local_challenge. Ship
- * these over the secure channel to a domain controller and
- * see if they were valid.
- */
-
- /* rety loop for robustness */
-
- for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
- nt_status = connect_to_domain_password_server(&cli, domain, dc_name,
- dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry);
- }
-
- if ( !NT_STATUS_IS_OK(nt_status) ) {
- DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
- return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE;
- }
- return nt_status;
- }
-
- ZERO_STRUCT(info3);
-
- /*
- * If this call succeeds, we now have lots of info about the user
- * in the info3 structure.
- */
-
- nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
- NULL, user_info->smb_name.str, user_info->domain.str,
- user_info->wksta_name.str, chal, user_info->lm_resp,
- user_info->nt_resp, &info3);
-
- /* let go as soon as possible so we avoid any potential deadlocks
- with winbind lookup up users or groups */
-
- release_server_mutex();
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("domain_client_validate: unable to validate password "
- "for user %s in domain %s to Domain controller %s. "
- "Error was %s.\n", user_info->smb_name.str,
- user_info->domain.str, cli->srv_name_slash,
- nt_errstr(nt_status)));
-
- /* map to something more useful */
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {
- nt_status = NT_STATUS_NO_LOGON_SERVERS;
- }
- } else {
- nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
- user_info->smb_name.str, domain, server_info, &info3);
- netsamlogon_cache_store( mem_ctx, &info3 );
- }
-
-#if 0
- /*
- * We don't actually need to do this - plus it fails currently with
- * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
- * send here. JRA.
- */
-
- if (NT_STATUS_IS_OK(status)) {
- if(cli_nt_logoff(&cli, &ctr) == False) {
- DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
- nt_status = NT_STATUS_LOGON_FAILURE;
- }
- }
-#endif /* 0 */
-
- /* Note - once the cli stream is shutdown the mem_ctx used
- to allocate the other_sids and gids structures has been deleted - so
- these pointers are no longer valid..... */
-
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
- cli_shutdown(cli);
- return nt_status;
-}
-
-/****************************************************************************
- Check for a valid username and password in security=domain mode.
-****************************************************************************/
-
-static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- unsigned char trust_passwd[16];
- time_t last_change_time;
- const char *domain = lp_workgroup();
- uint32 sec_channel_type = 0;
- fstring dc_name;
- struct in_addr dc_ip;
-
- if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
- DEBUG(0,("check_ntdomain_security: Configuration error! Cannot use "
- "ntdomain auth method when not a member of a domain.\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!user_info || !server_info || !auth_context) {
- DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
- */
-
- if(strequal(get_global_sam_name(), user_info->domain.str)) {
- DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- /*
- * Get the machine account password for our primary domain
- * No need to become_root() as secrets_init() is done at startup.
- */
-
- if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type))
- {
- DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
- /* Test if machine password has expired and needs to be changed */
- if (lp_machine_password_timeout()) {
- if (last_change_time > 0 &&
- time(NULL) > (last_change_time +
- lp_machine_password_timeout())) {
- global_machine_password_needs_changing = True;
- }
- }
-
- /* we need our DC to send the net_sam_logon() request to */
-
- if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
- DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n",
- user_info->domain.str));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- nt_status = domain_client_validate(mem_ctx, user_info, domain,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- global_myname(), sec_channel_type,trust_passwd, last_change_time);
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->name = "ntdomain";
- (*auth_method)->auth = check_ntdomain_security;
- return NT_STATUS_OK;
-}
-
-
-/****************************************************************************
- Check for a valid username and password in a trusted domain
-****************************************************************************/
-
-static NTSTATUS check_trustdomain_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- unsigned char trust_md4_password[16];
- char *trust_password;
- time_t last_change_time;
- DOM_SID sid;
- fstring dc_name;
- struct in_addr dc_ip;
-
- if (!user_info || !server_info || !auth_context) {
- DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * Check that the requested domain is not our own machine name or domain name.
- */
-
- if( strequal(get_global_sam_name(), user_info->domain.str)) {
- DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n",
- user_info->domain.str));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- /* No point is bothering if this is not a trusted domain.
- This return makes "map to guest = bad user" work again.
- The logic is that if we know nothing about the domain, that
- user is known to us and does not exist */
-
- if ( !is_trusted_domain( user_info->domain.str ) )
- return NT_STATUS_NOT_IMPLEMENTED;
-
- /*
- * Get the trusted account password for the trusted domain
- * No need to become_root() as secrets_init() is done at startup.
- */
-
- if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time))
- {
- DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password));
-#endif
- E_md4hash(trust_password, trust_md4_password);
- SAFE_FREE(trust_password);
-
-#if 0
- /* Test if machine password is expired and need to be changed */
- if (time(NULL) > last_change_time + lp_machine_password_timeout())
- {
- global_machine_password_needs_changing = True;
- }
-#endif
-
- /* use get_dc_name() for consistency even through we know that it will be
- a netbios name */
-
- if ( !get_dc_name(user_info->domain.str, NULL, dc_name, &dc_ip) ) {
- DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
- user_info->domain.str));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->name = "trustdomain";
- (*auth_method)->auth = check_trustdomain_security;
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_domain_init(void)
-{
- smb_register_auth(AUTH_INTERFACE_VERSION, "trustdomain", auth_init_trustdomain);
- smb_register_auth(AUTH_INTERFACE_VERSION, "ntdomain", auth_init_ntdomain);
- return NT_STATUS_OK;
-}
diff --git a/source/auth/auth_ntlmssp.c b/source/auth/auth_ntlmssp.c
deleted file mode 100644
index 4b425056b11..00000000000
--- a/source/auth/auth_ntlmssp.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- handle NLTMSSP, server side
-
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett 2001-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * Return the challenge as determined by the authentication subsystem
- * @return an 8 byte random challenge
- */
-
-static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
-{
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
- return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context);
-}
-
-/**
- * Some authentication methods 'fix' the challenge, so we may not be able to set it
- *
- * @return If the effective challenge used by the auth subsystem may be modified
- */
-static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
-{
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
- struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
-
- return auth_context->challenge_may_be_modified;
-}
-
-/**
- * NTLM2 authentication modifies the effective challange,
- * @param challenge The new challenge value
- */
-static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
-{
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
- struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
-
- SMB_ASSERT(challenge->length == 8);
-
- auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
- challenge->data, challenge->length);
-
- auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
-
- DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
- DEBUG(5, ("challenge is: \n"));
- dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
- return NT_STATUS_OK;
-}
-
-/**
- * Check the password on an NTLMSSP login.
- *
- * Return the session keys used on the connection.
- */
-
-static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
-{
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
- auth_usersupplied_info *user_info = NULL;
- NTSTATUS nt_status;
-
- /* the client has given us its machine name (which we otherwise would not get on port 445).
- we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
-
- set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True);
-
- /* setup the string used by %U */
- /* sub_set_smb_name checks for weird internally */
- sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
-
- reload_services(True);
-
- nt_status = make_user_info_map(&user_info,
- auth_ntlmssp_state->ntlmssp_state->user,
- auth_ntlmssp_state->ntlmssp_state->domain,
- auth_ntlmssp_state->ntlmssp_state->workstation,
- auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL,
- auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL,
- NULL, NULL, NULL,
- True);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context,
- user_info, &auth_ntlmssp_state->server_info);
-
- free_user_info(&user_info);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
- if (auth_ntlmssp_state->server_info->user_session_key.length) {
- DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->user_session_key.length));
- *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
- auth_ntlmssp_state->server_info->user_session_key.data,
- auth_ntlmssp_state->server_info->user_session_key.length);
- }
- if (auth_ntlmssp_state->server_info->lm_session_key.length) {
- DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length));
- *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
- auth_ntlmssp_state->server_info->lm_session_key.data,
- auth_ntlmssp_state->server_info->lm_session_key.length);
- }
- return nt_status;
-}
-
-NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
-{
- NTSTATUS nt_status;
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("AUTH NTLMSSP context");
-
- *auth_ntlmssp_state = talloc_zero(mem_ctx, sizeof(**auth_ntlmssp_state));
- if (!*auth_ntlmssp_state) {
- DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*auth_ntlmssp_state);
-
- (*auth_ntlmssp_state)->mem_ctx = mem_ctx;
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) {
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) {
- return nt_status;
- }
-
- (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state);
- (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
- (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
- (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
- (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
- (*auth_ntlmssp_state)->ntlmssp_state->server_role = lp_server_role();
-
- return NT_STATUS_OK;
-}
-
-void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
-{
- TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
-
- if ((*auth_ntlmssp_state)->ntlmssp_state) {
- ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
- }
- if ((*auth_ntlmssp_state)->auth_context) {
- ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
- }
- if ((*auth_ntlmssp_state)->server_info) {
- free_server_info(&(*auth_ntlmssp_state)->server_info);
- }
- talloc_destroy(mem_ctx);
- *auth_ntlmssp_state = NULL;
-}
-
-NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state,
- const DATA_BLOB request, DATA_BLOB *reply)
-{
- return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
-}
diff --git a/source/auth/auth_rhosts.c b/source/auth/auth_rhosts.c
deleted file mode 100644
index b295df9328f..00000000000
--- a/source/auth/auth_rhosts.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Main SMB reply routines
- Copyright (C) Andrew Tridgell 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/****************************************************************************
- Read the a hosts.equiv or .rhosts file and check if it
- allows this user from this machine.
-****************************************************************************/
-
-static BOOL check_user_equiv(const char *user, const char *remote, const char *equiv_file)
-{
- int plus_allowed = 1;
- char *file_host;
- char *file_user;
- char **lines = file_lines_load(equiv_file, NULL);
- int i;
-
- DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
- if (! lines) return False;
- for (i=0; lines[i]; i++) {
- char *buf = lines[i];
- trim_char(buf,' ',' ');
-
- if (buf[0] != '#' && buf[0] != '\n')
- {
- BOOL is_group = False;
- int plus = 1;
- char *bp = buf;
- if (strcmp(buf, "NO_PLUS\n") == 0)
- {
- DEBUG(6, ("check_user_equiv NO_PLUS\n"));
- plus_allowed = 0;
- }
- else {
- if (buf[0] == '+')
- {
- bp++;
- if (*bp == '\n' && plus_allowed)
- {
- /* a bare plus means everbody allowed */
- DEBUG(6, ("check_user_equiv everybody allowed\n"));
- file_lines_free(lines);
- return True;
- }
- }
- else if (buf[0] == '-')
- {
- bp++;
- plus = 0;
- }
- if (*bp == '@')
- {
- is_group = True;
- bp++;
- }
- file_host = strtok(bp, " \t\n");
- file_user = strtok(NULL, " \t\n");
- DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)",
- file_user ? file_user : "(null)" ));
- if (file_host && *file_host)
- {
- BOOL host_ok = False;
-
-#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
- if (is_group)
- {
- static char *mydomain = NULL;
- if (!mydomain)
- yp_get_default_domain(&mydomain);
- if (mydomain && innetgr(file_host,remote,user,mydomain))
- host_ok = True;
- }
-#else
- if (is_group)
- {
- DEBUG(1,("Netgroups not configured\n"));
- continue;
- }
-#endif
-
- /* is it this host */
- /* the fact that remote has come from a call of gethostbyaddr
- * means that it may have the fully qualified domain name
- * so we could look up the file version to get it into
- * a canonical form, but I would rather just type it
- * in full in the equiv file
- */
- if (!host_ok && !is_group && strequal(remote, file_host))
- host_ok = True;
-
- if (!host_ok)
- continue;
-
- /* is it this user */
- if (file_user == 0 || strequal(user, file_user))
- {
- DEBUG(5, ("check_user_equiv matched %s%s %s\n",
- (plus ? "+" : "-"), file_host,
- (file_user ? file_user : "")));
- file_lines_free(lines);
- return (plus ? True : False);
- }
- }
- }
- }
- }
- file_lines_free(lines);
- return False;
-}
-
-/****************************************************************************
-check for a possible hosts equiv or rhosts entry for the user
-****************************************************************************/
-
-static BOOL check_hosts_equiv(SAM_ACCOUNT *account)
-{
- uid_t uid;
- char *fname = NULL;
-
- fname = lp_hosts_equiv();
- if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(account), &uid)))
- return False;
-
- /* note: don't allow hosts.equiv on root */
- if (fname && *fname && uid != 0) {
- if (check_user_equiv(pdb_get_username(account),client_name(),fname))
- return True;
- }
-
- return False;
-}
-
-
-/****************************************************************************
- Check for a valid .rhosts/hosts.equiv entry for this user
-****************************************************************************/
-
-static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status;
- SAM_ACCOUNT *account = NULL;
- if (!NT_STATUS_IS_OK(nt_status =
- auth_get_sam_account(user_info->internal_username.str,
- &account))) {
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER))
- nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
- }
-
- if (check_hosts_equiv(account)) {
- nt_status = make_server_info_sam(server_info, account);
- } else {
- pdb_free_sam(&account);
- nt_status = NT_STATUS_NOT_IMPLEMENTED;
- }
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_hostsequiv_security;
- (*auth_method)->name = "hostsequiv";
- return NT_STATUS_OK;
-}
-
-
-/****************************************************************************
- Check for a valid .rhosts/hosts.equiv entry for this user
-****************************************************************************/
-
-static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status;
- SAM_ACCOUNT *account = NULL;
- pstring rhostsfile;
- const char *home;
-
- if (!NT_STATUS_IS_OK(nt_status =
- auth_get_sam_account(user_info->internal_username.str,
- &account))) {
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER))
- nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
- }
-
- home = pdb_get_unix_homedir(account);
-
- if (home) {
- slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
- become_root();
- if (check_user_equiv(pdb_get_username(account),client_name(),rhostsfile)) {
- nt_status = make_server_info_sam(server_info, account);
- } else {
- pdb_free_sam(&account);
- }
- unbecome_root();
- } else {
- pdb_free_sam(&account);
- nt_status = NT_STATUS_NOT_IMPLEMENTED;
- }
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_rhosts_security;
- (*auth_method)->name = "rhosts";
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_rhosts_init(void)
-{
- smb_register_auth(AUTH_INTERFACE_VERSION, "rhosts", auth_init_rhosts);
- smb_register_auth(AUTH_INTERFACE_VERSION, "hostsequiv", auth_init_hostsequiv);
- return NT_STATUS_OK;
-}
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
deleted file mode 100644
index 2f9ff6265c9..00000000000
--- a/source/auth/auth_sam.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Andrew Bartlett 2001-2003
- Copyright (C) Gerald Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/****************************************************************************
- Do a specific test for an smb password being correct, given a smb_password and
- the lanman and NT responses.
-****************************************************************************/
-
-static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
- TALLOC_CTX *mem_ctx,
- SAM_ACCOUNT *sampass,
- const auth_usersupplied_info *user_info,
- DATA_BLOB *user_sess_key,
- DATA_BLOB *lm_sess_key)
-{
- uint16 acct_ctrl;
- const uint8 *lm_pw, *nt_pw;
- const char *username = pdb_get_username(sampass);
-
- acct_ctrl = pdb_get_acct_ctrl(sampass);
- if (acct_ctrl & ACB_PWNOTREQ) {
- if (lp_null_passwords()) {
- DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username));
- return NT_STATUS_LOGON_FAILURE;
- }
- }
-
- lm_pw = pdb_get_lanman_passwd(sampass);
- nt_pw = pdb_get_nt_passwd(sampass);
-
- return ntlm_password_check(mem_ctx, &auth_context->challenge,
- &user_info->lm_resp, &user_info->nt_resp,
- &user_info->lm_interactive_pwd, &user_info->nt_interactive_pwd,
- username,
- user_info->smb_name.str,
- user_info->client_domain.str,
- lm_pw, nt_pw, user_sess_key, lm_sess_key);
-}
-
-
-/****************************************************************************
- Do a specific test for a SAM_ACCOUNT being vaild for this connection
- (ie not disabled, expired and the like).
-****************************************************************************/
-
-static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
- SAM_ACCOUNT *sampass,
- const auth_usersupplied_info *user_info)
-{
- uint16 acct_ctrl = pdb_get_acct_ctrl(sampass);
- char *workstation_list;
- time_t kickoff_time;
-
- DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass)));
-
- /* Quit if the account was disabled. */
- if (acct_ctrl & ACB_DISABLED) {
- DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass)));
- return NT_STATUS_ACCOUNT_DISABLED;
- }
-
- /* Quit if the account was locked out. */
- if (acct_ctrl & ACB_AUTOLOCK) {
- DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass)));
- return NT_STATUS_ACCOUNT_LOCKED_OUT;
- }
-
- /* Test account expire time */
-
- kickoff_time = pdb_get_kickoff_time(sampass);
- if (kickoff_time != 0 && time(NULL) > kickoff_time) {
- DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass)));
- DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time));
- return NT_STATUS_ACCOUNT_EXPIRED;
- }
-
- if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
- time_t must_change_time = pdb_get_pass_must_change_time(sampass);
- time_t last_set_time = pdb_get_pass_last_set_time(sampass);
-
- /* check for immediate expiry "must change at next logon" */
- if (must_change_time == 0 && last_set_time != 0) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
- return NT_STATUS_PASSWORD_MUST_CHANGE;
- }
-
- /* check for expired password */
- if (must_change_time < time(NULL) && must_change_time != 0) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
- DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
- return NT_STATUS_PASSWORD_EXPIRED;
- }
- }
-
- /* Test workstation. Workstation list is comma separated. */
-
- workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass));
- if (!workstation_list)
- return NT_STATUS_NO_MEMORY;
-
- if (*workstation_list) {
- BOOL invalid_ws = True;
- const char *s = workstation_list;
-
- fstring tok;
-
- while (next_token(&s, tok, ",", sizeof(tok))) {
- DEBUG(10,("sam_account_ok: checking for workstation match %s and %s (len=%d)\n",
- tok, user_info->wksta_name.str, user_info->wksta_name.len));
- if(strequal(tok, user_info->wksta_name.str)) {
- invalid_ws = False;
- break;
- }
- }
-
- if (invalid_ws)
- return NT_STATUS_INVALID_WORKSTATION;
- }
-
- if (acct_ctrl & ACB_DOMTRUST) {
- DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
- return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
- }
-
- if (acct_ctrl & ACB_SVRTRUST) {
- DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass)));
- return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
- }
-
- if (acct_ctrl & ACB_WSTRUST) {
- DEBUG(4,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass)));
- return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
- }
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash supplied in the user_info structure
-return an NT_STATUS constant.
-****************************************************************************/
-
-static NTSTATUS check_sam_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- SAM_ACCOUNT *sampass=NULL;
- BOOL ret;
- NTSTATUS nt_status;
- DATA_BLOB user_sess_key = data_blob(NULL, 0);
- DATA_BLOB lm_sess_key = data_blob(NULL, 0);
- BOOL updated_autolock = False, updated_badpw = False;
-
- if (!user_info || !auth_context) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Can't use the talloc version here, because the returned struct gets
- kept on the server_info */
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
- return nt_status;
- }
-
- /* get the account information */
-
- become_root();
- ret = pdb_getsampwnam(sampass, user_info->internal_username.str);
- unbecome_root();
-
- if (ret == False) {
- DEBUG(3,("check_sam_security: Couldn't find user '%s' in passdb file.\n", user_info->internal_username.str));
- pdb_free_sam(&sampass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- /* see if autolock flag needs to be updated */
- if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL)
- pdb_update_autolock_flag(sampass, &updated_autolock);
- /* Quit if the account was locked out. */
- if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
- DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", pdb_get_username(sampass)));
- return NT_STATUS_ACCOUNT_LOCKED_OUT;
- }
-
- nt_status = sam_password_ok(auth_context, mem_ctx, sampass,
- user_info, &user_sess_key, &lm_sess_key);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
- pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {
- pdb_increment_bad_password_count(sampass);
- updated_badpw = True;
- } else {
- pdb_update_bad_password_count(sampass,
- &updated_badpw);
- }
- if (updated_autolock || updated_badpw){
- become_root();
- if(!pdb_update_sam_account(sampass))
- DEBUG(1, ("Failed to modify entry.\n"));
- unbecome_root();
- }
- pdb_free_sam(&sampass);
- return nt_status;
- }
-
- if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
- (pdb_get_bad_password_count(sampass) > 0)){
- pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
- pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
- updated_badpw = True;
- }
-
- if (updated_autolock || updated_badpw){
- become_root();
- if(!pdb_update_sam_account(sampass))
- DEBUG(1, ("Failed to modify entry.\n"));
- unbecome_root();
- }
-
- nt_status = sam_account_ok(mem_ctx, sampass, user_info);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- pdb_free_sam(&sampass);
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_server_info_sam(server_info, sampass))) {
- DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
- return nt_status;
- }
-
- (*server_info)->user_session_key = user_sess_key;
- (*server_info)->lm_session_key = lm_sess_key;
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_sam_security;
- (*auth_method)->name = "sam_ignoredomain";
- return NT_STATUS_OK;
-}
-
-
-/****************************************************************************
-Check SAM security (above) but with a few extra checks.
-****************************************************************************/
-
-static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- BOOL is_local_name, is_my_domain;
-
- if (!user_info || !auth_context) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
- is_local_name = is_myname(user_info->domain.str);
- is_my_domain = strequal(user_info->domain.str, lp_workgroup());
-
- /* check whether or not we service this domain/workgroup name */
-
- switch ( lp_server_role() ) {
- case ROLE_STANDALONE:
- case ROLE_DOMAIN_MEMBER:
- if ( !is_local_name ) {
- DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
- user_info->domain.str, (lp_server_role() == ROLE_DOMAIN_MEMBER
- ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- if ( !is_local_name && !is_my_domain ) {
- DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
- user_info->domain.str));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
- default: /* name is ok */
- break;
- }
-
- return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_samstrict_security;
- (*auth_method)->name = "sam";
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_sam_init(void)
-{
- smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
- smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
- return NT_STATUS_OK;
-}
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
deleted file mode 100644
index bc611ec229b..00000000000
--- a/source/auth/auth_server.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Authenticate to a remote server
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-extern userdom_struct current_user_info;
-
-/****************************************************************************
- Support for server level security.
-****************************************************************************/
-
-static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
-{
- struct cli_state *cli = NULL;
- fstring desthost;
- struct in_addr dest_ip;
- const char *p;
- char *pserver;
- BOOL connected_ok = False;
-
- if (!(cli = cli_initialise(cli)))
- return NULL;
-
- /* security = server just can't function with spnego */
- cli->use_spnego = False;
-
- pserver = talloc_strdup(mem_ctx, lp_passwordserver());
- p = pserver;
-
- while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
- standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost));
- strupper_m(desthost);
-
- if(!resolve_name( desthost, &dest_ip, 0x20)) {
- DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
- continue;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
- continue;
- }
-
- /* we use a mutex to prevent two connections at once - when a
- Win2k PDC get two connections where one hasn't completed a
- session setup yet it will send a TCP reset to the first
- connection (tridge) */
-
- if (!grab_server_mutex(desthost)) {
- return NULL;
- }
-
- if (cli_connect(cli, desthost, &dest_ip)) {
- DEBUG(3,("connected to password server %s\n",desthost));
- connected_ok = True;
- break;
- }
- }
-
- if (!connected_ok) {
- release_server_mutex();
- DEBUG(0,("password server not available\n"));
- cli_shutdown(cli);
- return NULL;
- }
-
- if (!attempt_netbios_session_request(cli, global_myname(),
- desthost, &dest_ip)) {
- release_server_mutex();
- DEBUG(1,("password server fails session request\n"));
- cli_shutdown(cli);
- return NULL;
- }
-
- if (strequal(desthost,myhostname())) {
- exit_server("Password server loop!");
- }
-
- DEBUG(3,("got session\n"));
-
- if (!cli_negprot(cli)) {
- DEBUG(1,("%s rejected the negprot\n",desthost));
- release_server_mutex();
- cli_shutdown(cli);
- return NULL;
- }
-
- if (cli->protocol < PROTOCOL_LANMAN2 ||
- !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
- DEBUG(1,("%s isn't in user level security mode\n",desthost));
- release_server_mutex();
- cli_shutdown(cli);
- return NULL;
- }
-
- /* Get the first session setup done quickly, to avoid silly
- Win2k bugs. (The next connection to the server will kill
- this one...
- */
-
- if (!cli_session_setup(cli, "", "", 0, "", 0,
- "")) {
- DEBUG(0,("%s rejected the initial session setup (%s)\n",
- desthost, cli_errstr(cli)));
- release_server_mutex();
- cli_shutdown(cli);
- return NULL;
- }
-
- release_server_mutex();
-
- DEBUG(3,("password server OK\n"));
-
- return cli;
-}
-
-/****************************************************************************
- Clean up our allocated cli.
-****************************************************************************/
-
-static void free_server_private_data(void **private_data_pointer)
-{
- struct cli_state **cli = (struct cli_state **)private_data_pointer;
- if (*cli && (*cli)->initialised) {
- DEBUG(10, ("Shutting down smbserver connection\n"));
- cli_shutdown(*cli);
- }
- *private_data_pointer = NULL;
-}
-
-/****************************************************************************
- Send a 'keepalive' packet down the cli pipe.
-****************************************************************************/
-
-static void send_server_keepalive(void **private_data_pointer)
-{
- /* also send a keepalive to the password server if its still
- connected */
- if (private_data_pointer) {
- struct cli_state *cli = (struct cli_state *)(*private_data_pointer);
- if (cli && cli->initialised) {
- if (!send_keepalive(cli->fd)) {
- DEBUG( 2, ( "send_server_keepalive: password server keepalive failed.\n"));
- cli_shutdown(cli);
- *private_data_pointer = NULL;
- }
- }
- }
-}
-
-/****************************************************************************
- Get the challenge out of a password server.
-****************************************************************************/
-
-static DATA_BLOB auth_get_challenge_server(const struct auth_context *auth_context,
- void **my_private_data,
- TALLOC_CTX *mem_ctx)
-{
- struct cli_state *cli = server_cryptkey(mem_ctx);
-
- if (cli) {
- DEBUG(3,("using password server validation\n"));
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
- /* We can't work with unencrypted password servers
- unless 'encrypt passwords = no' */
- DEBUG(5,("make_auth_info_server: Server is unencrypted, no challenge available..\n"));
-
- /* However, it is still a perfectly fine connection
- to pass that unencrypted password over */
- *my_private_data = (void *)cli;
- return data_blob(NULL, 0);
-
- } else if (cli->secblob.length < 8) {
- /* We can't do much if we don't get a full challenge */
- DEBUG(2,("make_auth_info_server: Didn't receive a full challenge from server\n"));
- cli_shutdown(cli);
- return data_blob(NULL, 0);
- }
-
- *my_private_data = (void *)cli;
-
- /* The return must be allocated on the caller's mem_ctx, as our own will be
- destoyed just after the call. */
- return data_blob_talloc(auth_context->mem_ctx, cli->secblob.data,8);
- } else {
- return data_blob(NULL, 0);
- }
-}
-
-
-/****************************************************************************
- Check for a valid username and password in security=server mode.
- - Validate a password with the password server.
-****************************************************************************/
-
-static NTSTATUS check_smbserver_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- struct cli_state *cli;
- static unsigned char badpass[24];
- static fstring baduser;
- static BOOL tested_password_server = False;
- static BOOL bad_password_server = False;
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- BOOL locally_made_cli = False;
-
- /*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
- */
-
- if(is_myname(user_info->domain.str)) {
- DEBUG(3,("check_smbserver_security: Requested domain was for this machine.\n"));
- return nt_status;
- }
-
- cli = my_private_data;
-
- if (cli) {
- } else {
- cli = server_cryptkey(mem_ctx);
- locally_made_cli = True;
- }
-
- if (!cli || !cli->initialised) {
- DEBUG(1,("password server is not connected (cli not initilised)\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
- if (user_info->encrypted) {
- DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost));
- return NT_STATUS_LOGON_FAILURE;
- }
- } else {
- if (memcmp(cli->secblob.data, auth_context->challenge.data, 8) != 0) {
- DEBUG(1,("the challenge that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
- return NT_STATUS_LOGON_FAILURE;
- }
- }
-
- if(badpass[0] == 0)
- memset(badpass, 0x1f, sizeof(badpass));
-
- if((user_info->nt_resp.length == sizeof(badpass)) &&
- !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) {
- /*
- * Very unlikely, our random bad password is the same as the users
- * password.
- */
- memset(badpass, badpass[0]+1, sizeof(badpass));
- }
-
- if(baduser[0] == 0) {
- fstrcpy(baduser, INVALID_USER_PREFIX);
- fstrcat(baduser, global_myname());
- }
-
- /*
- * Attempt a session setup with a totally incorrect password.
- * If this succeeds with the guest bit *NOT* set then the password
- * server is broken and is not correctly setting the guest bit. We
- * need to detect this as some versions of NT4.x are broken. JRA.
- */
-
- /* I sure as hell hope that there aren't servers out there that take
- * NTLMv2 and have this bug, as we don't test for that...
- * - abartlet@samba.org
- */
-
- if ((!tested_password_server) && (lp_paranoid_server_security())) {
- if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass),
- (char *)badpass, sizeof(badpass), user_info->domain.str)) {
-
- /*
- * We connected to the password server so we
- * can say we've tested it.
- */
- tested_password_server = True;
-
- if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) {
- DEBUG(0,("server_validate: password server %s allows users as non-guest \
-with a bad password.\n", cli->desthost));
- DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \
-use this machine as the password server.\n"));
- cli_ulogoff(cli);
-
- /*
- * Password server has the bug.
- */
- bad_password_server = True;
- return NT_STATUS_LOGON_FAILURE;
- }
- cli_ulogoff(cli);
- }
- } else {
-
- /*
- * We have already tested the password server.
- * Fail immediately if it has the bug.
- */
-
- if(bad_password_server) {
- DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \
-with a bad password.\n", cli->desthost));
- DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \
-use this machine as the password server.\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
- }
-
- /*
- * Now we know the password server will correctly set the guest bit, or is
- * not guest enabled, we can try with the real password.
- */
-
- if (!user_info->encrypted) {
- /* Plaintext available */
- if (!cli_session_setup(cli, user_info->smb_name.str,
- (char *)user_info->plaintext_password.data,
- user_info->plaintext_password.length,
- NULL, 0,
- user_info->domain.str)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- /* Make this cli_nt_error() when the conversion is in */
- nt_status = cli_nt_error(cli);
- } else {
- nt_status = NT_STATUS_OK;
- }
- } else {
- if (!cli_session_setup(cli, user_info->smb_name.str,
- (char *)user_info->lm_resp.data,
- user_info->lm_resp.length,
- (char *)user_info->nt_resp.data,
- user_info->nt_resp.length,
- user_info->domain.str)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- /* Make this cli_nt_error() when the conversion is in */
- nt_status = cli_nt_error(cli);
- } else {
- nt_status = NT_STATUS_OK;
- }
- }
-
- /* if logged in as guest then reject */
- if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {
- DEBUG(1,("password server %s gave us guest only\n", cli->desthost));
- nt_status = NT_STATUS_LOGON_FAILURE;
- }
-
- cli_ulogoff(cli);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- fstring real_username;
- struct passwd *pass;
-
- if ( (pass = smb_getpwnam( user_info->internal_username.str,
- real_username, True )) != NULL )
- {
- nt_status = make_server_info_pw(server_info, pass->pw_name, pass);
- }
- else
- {
- nt_status = NT_STATUS_NO_SUCH_USER;
- }
- }
-
- if (locally_made_cli) {
- cli_shutdown(cli);
- }
-
- return(nt_status);
-}
-
-static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
- (*auth_method)->name = "smbserver";
- (*auth_method)->auth = check_smbserver_security;
- (*auth_method)->get_chal = auth_get_challenge_server;
- (*auth_method)->send_keepalive = send_server_keepalive;
- (*auth_method)->free_private_data = free_server_private_data;
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_server_init(void)
-{
- return smb_register_auth(AUTH_INTERFACE_VERSION, "smbserver", auth_init_smbserver);
-}
diff --git a/source/auth/auth_unix.c b/source/auth/auth_unix.c
deleted file mode 100644
index f744cba0c43..00000000000
--- a/source/auth/auth_unix.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/**
- * update the encrypted smbpasswd file from the plaintext username and password
- *
- * this ugly hack needs to die, but not quite yet, I think people still use it...
- **/
-static BOOL update_smbpassword_file(const char *user, const char *password)
-{
- SAM_ACCOUNT *sampass = NULL;
- BOOL ret;
-
- pdb_init_sam(&sampass);
-
- become_root();
- ret = pdb_getsampwnam(sampass, user);
- unbecome_root();
-
- if(ret == False) {
- DEBUG(0,("pdb_getsampwnam returned NULL\n"));
- pdb_free_sam(&sampass);
- return False;
- }
-
- /*
- * Remove the account disabled flag - we are updating the
- * users password from a login.
- */
- if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {
- pdb_free_sam(&sampass);
- return False;
- }
-
- if (!pdb_set_plaintext_passwd (sampass, password)) {
- pdb_free_sam(&sampass);
- return False;
- }
-
- /* Now write it into the file. */
- become_root();
-
- ret = pdb_update_sam_account (sampass);
-
- unbecome_root();
-
- if (ret) {
- DEBUG(3,("pdb_update_sam_account returned %d\n",ret));
- }
-
- pdb_free_sam(&sampass);
- return ret;
-}
-
-
-/** Check a plaintext username/password
- *
- * Cannot deal with an encrupted password in any manner whatsoever,
- * unless the account has a null password.
- **/
-
-static NTSTATUS check_unix_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status;
- struct passwd *pass = NULL;
-
- become_root();
- pass = Get_Pwnam(user_info->internal_username.str);
-
-
- /** @todo This call assumes a ASCII password, no charset transformation is
- done. We may need to revisit this **/
- nt_status = pass_check(pass,
- pass ? pass->pw_name : user_info->internal_username.str,
- (char *)user_info->plaintext_password.data,
- user_info->plaintext_password.length-1,
- lp_update_encrypted() ?
- update_smbpassword_file : NULL,
- True);
-
- unbecome_root();
-
- if (NT_STATUS_IS_OK(nt_status)) {
- if (pass) {
- make_server_info_pw(server_info, pass->pw_name, pass);
- } else {
- /* we need to do somthing more useful here */
- nt_status = NT_STATUS_NO_SUCH_USER;
- }
- }
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->name = "unix";
- (*auth_method)->auth = check_unix_security;
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_unix_init(void)
-{
- return smb_register_auth(AUTH_INTERFACE_VERSION, "unix", auth_init_unix);
-}
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
deleted file mode 100644
index 1ff25f1c31d..00000000000
--- a/source/auth/auth_util.c
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Authentication utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jeremy Allison 2000-2001
- Copyright (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Network;
-extern DOM_SID global_sid_Builtin_Guests;
-extern DOM_SID global_sid_Authenticated_Users;
-
-
-/****************************************************************************
- Create a UNIX user on demand.
-****************************************************************************/
-
-static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
-{
- pstring add_script;
- int ret;
-
- pstrcpy(add_script, lp_adduser_script());
- if (! *add_script)
- return -1;
- all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
- if (domain)
- all_string_sub(add_script, "%D", domain, sizeof(pstring));
- if (homedir)
- all_string_sub(add_script, "%H", homedir, sizeof(pstring));
- ret = smbrun(add_script,NULL);
- DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
- return ret;
-}
-
-/****************************************************************************
- Add and Delete UNIX users on demand, based on NTSTATUS codes.
- We don't care about RID's here so ignore.
-****************************************************************************/
-
-void auth_add_user_script(const char *domain, const char *username)
-{
- uint32 rid;
- /*
- * User validated ok against Domain controller.
- * If the admin wants us to try and create a UNIX
- * user on the fly, do so.
- */
-
- if ( *lp_adduser_script() )
- smb_create_user(domain, username, NULL);
- else {
- DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
-
- /* should never get here is we a re a domain member running winbindd
- However, a host set for 'security = server' might run winbindd for
- account allocation */
-
- if ( !winbind_create_user(username, NULL) ) {
- DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
- rid = 0;
- }
- }
-}
-
-/****************************************************************************
- Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
- unix info.
-****************************************************************************/
-
-NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
-{
- BOOL pdb_ret;
- NTSTATUS nt_status;
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
- return nt_status;
- }
-
- become_root();
- pdb_ret = pdb_getsampwnam(*account, user);
- unbecome_root();
-
- if (!pdb_ret) {
-
- struct passwd *pass = Get_Pwnam(user);
- if (!pass)
- return NT_STATUS_NO_SUCH_USER;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
- return nt_status;
- }
- }
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data structure
-****************************************************************************/
-
-static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *internal_username,
- const char *client_domain,
- const char *domain,
- const char *wksta_name,
- DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
- DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
- DATA_BLOB *plaintext,
- BOOL encrypted)
-{
-
- DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
-
- *user_info = malloc(sizeof(**user_info));
- if (!user_info) {
- DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*user_info);
-
- DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
-
- (*user_info)->smb_name.str = strdup(smb_name);
- if ((*user_info)->smb_name.str) {
- (*user_info)->smb_name.len = strlen(smb_name);
- } else {
- free_user_info(user_info);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*user_info)->internal_username.str = strdup(internal_username);
- if ((*user_info)->internal_username.str) {
- (*user_info)->internal_username.len = strlen(internal_username);
- } else {
- free_user_info(user_info);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*user_info)->domain.str = strdup(domain);
- if ((*user_info)->domain.str) {
- (*user_info)->domain.len = strlen(domain);
- } else {
- free_user_info(user_info);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*user_info)->client_domain.str = strdup(client_domain);
- if ((*user_info)->client_domain.str) {
- (*user_info)->client_domain.len = strlen(client_domain);
- } else {
- free_user_info(user_info);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*user_info)->wksta_name.str = strdup(wksta_name);
- if ((*user_info)->wksta_name.str) {
- (*user_info)->wksta_name.len = strlen(wksta_name);
- } else {
- free_user_info(user_info);
- return NT_STATUS_NO_MEMORY;
- }
-
- DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
-
- if (lm_pwd)
- (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
- if (nt_pwd)
- (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
- if (lm_interactive_pwd)
- (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
- if (nt_interactive_pwd)
- (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
-
- if (plaintext)
- (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
-
- (*user_info)->encrypted = encrypted;
-
- DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data structure after appropriate mapping.
-****************************************************************************/
-
-NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- const char *wksta_name,
- DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
- DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
- DATA_BLOB *plaintext,
- BOOL encrypted)
-{
- const char *domain;
- fstring internal_username;
- fstrcpy(internal_username, smb_name);
- map_username(internal_username);
-
- DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
- client_domain, smb_name, wksta_name));
-
- /* don't allow "" as a domain, fixes a Win9X bug
- where it doens't supply a domain for logon script
- 'net use' commands. */
-
- if ( *client_domain )
- domain = client_domain;
- else
- domain = lp_workgroup();
-
- /* do what win2k does. Always map unknown domains to our own
- and let the "passdb backend" handle unknown users. */
-
- if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
- domain = get_default_sam_name();
-
- /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
-
- return make_user_info(user_info, smb_name, internal_username,
- client_domain, domain, wksta_name,
- lm_pwd, nt_pwd,
- lm_interactive_pwd, nt_interactive_pwd,
- plaintext, encrypted);
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data, making the DATA_BLOBs here.
- Decrypt and encrypt the passwords.
-****************************************************************************/
-
-BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- const char *wksta_name,
- const uchar *lm_network_pwd, int lm_pwd_len,
- const uchar *nt_network_pwd, int nt_pwd_len)
-{
- BOOL ret;
- NTSTATUS nt_status;
- DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
- DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
-
- nt_status = make_user_info_map(user_info,
- smb_name, client_domain,
- wksta_name,
- lm_pwd_len ? &lm_blob : NULL,
- nt_pwd_len ? &nt_blob : NULL,
- NULL, NULL, NULL,
- True);
-
- ret = NT_STATUS_IS_OK(nt_status) ? True : False;
-
- data_blob_free(&lm_blob);
- data_blob_free(&nt_blob);
- return ret;
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data, making the DATA_BLOBs here.
- Decrypt and encrypt the passwords.
-****************************************************************************/
-
-BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- const char *wksta_name,
- const uchar chal[8],
- const uchar lm_interactive_pwd[16],
- const uchar nt_interactive_pwd[16],
- const uchar *dc_sess_key)
-{
- char lm_pwd[16];
- char nt_pwd[16];
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
- unsigned char key[16];
-
- ZERO_STRUCT(key);
- memcpy(key, dc_sess_key, 8);
-
- if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
- if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("key:"));
- dump_data(100, (char *)key, sizeof(key));
-
- DEBUG(100,("lm owf password:"));
- dump_data(100, lm_pwd, sizeof(lm_pwd));
-
- DEBUG(100,("nt owf password:"));
- dump_data(100, nt_pwd, sizeof(nt_pwd));
-#endif
-
- if (lm_interactive_pwd)
- SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
-
- if (nt_interactive_pwd)
- SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("decrypt of lm owf password:"));
- dump_data(100, lm_pwd, sizeof(lm_pwd));
-
- DEBUG(100,("decrypt of nt owf password:"));
- dump_data(100, nt_pwd, sizeof(nt_pwd));
-#endif
-
- if (lm_interactive_pwd)
- SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
-
- if (nt_interactive_pwd)
- SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
-
- /* Password info paranoia */
- ZERO_STRUCT(key);
-
- {
- BOOL ret;
- NTSTATUS nt_status;
- DATA_BLOB local_lm_blob;
- DATA_BLOB local_nt_blob;
-
- DATA_BLOB lm_interactive_blob;
- DATA_BLOB nt_interactive_blob;
-
- if (lm_interactive_pwd) {
- local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
- lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
- ZERO_STRUCT(lm_pwd);
- }
-
- if (nt_interactive_pwd) {
- local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
- nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
- ZERO_STRUCT(nt_pwd);
- }
-
- nt_status = make_user_info_map(user_info,
- smb_name, client_domain,
- wksta_name,
- lm_interactive_pwd ? &local_lm_blob : NULL,
- nt_interactive_pwd ? &local_nt_blob : NULL,
- lm_interactive_pwd ? &lm_interactive_blob : NULL,
- nt_interactive_pwd ? &nt_interactive_blob : NULL,
- NULL,
- True);
-
- ret = NT_STATUS_IS_OK(nt_status) ? True : False;
- data_blob_free(&local_lm_blob);
- data_blob_free(&local_nt_blob);
- data_blob_free(&lm_interactive_blob);
- data_blob_free(&nt_interactive_blob);
- return ret;
- }
-}
-
-
-/****************************************************************************
- Create an auth_usersupplied_data structure
-****************************************************************************/
-
-BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- const uint8 chal[8],
- DATA_BLOB plaintext_password)
-{
-
- DATA_BLOB local_lm_blob;
- DATA_BLOB local_nt_blob;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- /*
- * Not encrypted - do so.
- */
-
- DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
-
- if (plaintext_password.data) {
- unsigned char local_lm_response[24];
-
-#ifdef DEBUG_PASSWORD
- DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
- dump_data(100, plaintext_password.data, plaintext_password.length);
-#endif
-
- SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
- local_lm_blob = data_blob(local_lm_response, 24);
-
- /* We can't do an NT hash here, as the password needs to be
- case insensitive */
- local_nt_blob = data_blob(NULL, 0);
-
- } else {
- local_lm_blob = data_blob(NULL, 0);
- local_nt_blob = data_blob(NULL, 0);
- }
-
- ret = make_user_info_map(user_info, smb_name,
- client_domain,
- get_remote_machine_name(),
- local_lm_blob.data ? &local_lm_blob : NULL,
- local_nt_blob.data ? &local_nt_blob : NULL,
- NULL, NULL,
- plaintext_password.data ? &plaintext_password : NULL,
- False);
-
- data_blob_free(&local_lm_blob);
- return NT_STATUS_IS_OK(ret) ? True : False;
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data structure
-****************************************************************************/
-
-NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- DATA_BLOB lm_resp, DATA_BLOB nt_resp)
-{
- return make_user_info_map(user_info, smb_name,
- client_domain,
- get_remote_machine_name(),
- lm_resp.data ? &lm_resp : NULL,
- nt_resp.data ? &nt_resp : NULL,
- NULL, NULL, NULL,
- True);
-}
-
-/****************************************************************************
- Create a guest user_info blob, for anonymous authenticaion.
-****************************************************************************/
-
-BOOL make_user_info_guest(auth_usersupplied_info **user_info)
-{
- NTSTATUS nt_status;
-
- nt_status = make_user_info(user_info,
- "","",
- "","",
- "",
- NULL, NULL,
- NULL, NULL,
- NULL,
- True);
-
- return NT_STATUS_IS_OK(nt_status) ? True : False;
-}
-
-/****************************************************************************
- prints a NT_USER_TOKEN to debug output.
-****************************************************************************/
-
-void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
-{
- fstring sid_str;
- size_t i;
-
- if (!token) {
- DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
- return;
- }
-
- DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
- sid_to_string(sid_str, &token->user_sids[0]) ));
- DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
- for (i = 0; i < token->num_sids; i++)
- DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
- sid_to_string(sid_str, &token->user_sids[i])));
-}
-
-/****************************************************************************
- prints a UNIX 'token' to debug output.
-****************************************************************************/
-
-void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups)
-{
- int i;
- DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid));
-
- DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups));
- for (i = 0; i < n_groups; i++)
- DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
- (long int)groups[i]));
-}
-
-/****************************************************************************
- Create the SID list for this user.
-****************************************************************************/
-
-static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid,
- int n_groupSIDs, DOM_SID *groupSIDs,
- BOOL is_guest, NT_USER_TOKEN **token)
-{
- NTSTATUS nt_status = NT_STATUS_OK;
- NT_USER_TOKEN *ptoken;
- int i;
- int sid_ndx;
-
- if ((ptoken = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) {
- DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
- nt_status = NT_STATUS_NO_MEMORY;
- return nt_status;
- }
-
- ZERO_STRUCTP(ptoken);
-
- ptoken->num_sids = n_groupSIDs + 5;
-
- if ((ptoken->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
- DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
- nt_status = NT_STATUS_NO_MEMORY;
- return nt_status;
- }
-
- memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids);
-
- /*
- * Note - user SID *MUST* be first in token !
- * se_access_check depends on this.
- *
- * Primary group SID is second in token. Convention.
- */
-
- sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid);
- if (group_sid)
- sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid);
-
- /*
- * Finally add the "standard" SIDs.
- * The only difference between guest and "anonymous" (which we
- * don't really support) is the addition of Authenticated_Users.
- */
-
- sid_copy(&ptoken->user_sids[2], &global_sid_World);
- sid_copy(&ptoken->user_sids[3], &global_sid_Network);
-
- if (is_guest)
- sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
- else
- sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users);
-
- sid_ndx = 5; /* next available spot */
-
- for (i = 0; i < n_groupSIDs; i++) {
- size_t check_sid_idx;
- for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
- if (sid_equal(&ptoken->user_sids[check_sid_idx],
- &groupSIDs[i])) {
- break;
- }
- }
-
- if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
- sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
- } else {
- ptoken->num_sids--;
- }
- }
-
- debug_nt_user_token(DBGC_AUTH, 10, ptoken);
-
- *token = ptoken;
-
- return nt_status;
-}
-
-/****************************************************************************
- Create the SID list for this user.
-****************************************************************************/
-
-NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest)
-{
- DOM_SID user_sid;
- DOM_SID group_sid;
- DOM_SID *group_sids;
- NT_USER_TOKEN *token;
- int i;
-
- if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
- return NULL;
- }
- if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
- return NULL;
- }
-
- group_sids = malloc(sizeof(DOM_SID) * ngroups);
- if (!group_sids) {
- DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
- return NULL;
- }
-
- for (i = 0; i < ngroups; i++) {
- if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
- DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
- SAFE_FREE(group_sids);
- return NULL;
- }
- }
-
- if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid,
- ngroups, group_sids, is_guest, &token))) {
- SAFE_FREE(group_sids);
- return NULL;
- }
-
- SAFE_FREE(group_sids);
-
- return token;
-}
-
-/******************************************************************************
- * this function returns the groups (SIDs) of the local SAM the user is in.
- * If this samba server is a DC of the domain the user belongs to, it returns
- * both domain groups and local / builtin groups. If the user is in a trusted
- * domain, or samba is a member server of a domain, then this function returns
- * local and builtin groups the user is a member of.
- *
- * currently this is a hack, as there is no sam implementation that is capable
- * of groups.
- *
- * NOTE!! This function will fail if you pass in a winbind user without
- * the domain --jerry
- ******************************************************************************/
-
-static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
- int *n_groups, DOM_SID **groups, gid_t **unix_groups)
-{
- int n_unix_groups;
- int i;
-
- *n_groups = 0;
- *groups = NULL;
-
- /* Try winbind first */
-
- if ( strchr(username, *lp_winbind_separator()) ) {
- n_unix_groups = winbind_getgroups( username, unix_groups );
-
- DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username,
- n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
-
- if ( n_unix_groups == -1 )
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
- }
- else {
- /* fallback to getgrouplist() */
-
- n_unix_groups = groups_max();
-
- if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) {
- DEBUG(0, ("get_user_groups: Out of memory allocating unix group list\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
-
- gid_t *groups_tmp;
-
- groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups);
-
- if (!groups_tmp) {
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_MEMORY;
- }
- *unix_groups = groups_tmp;
-
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
- }
- }
- }
-
- debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
-
- /* now setup the space for storing the SIDS */
-
- if (n_unix_groups > 0) {
-
- *groups = malloc(sizeof(DOM_SID) * n_unix_groups);
-
- if (!*groups) {
- DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_MEMORY;
- }
- }
-
- *n_groups = n_unix_groups;
-
- for (i = 0; i < *n_groups; i++) {
- if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
- DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
- (long int)(*unix_groups)[i+1]));
- SAFE_FREE(*groups);
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER;
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Make a user_info struct
-***************************************************************************/
-
-static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
-{
- *server_info = malloc(sizeof(**server_info));
- if (!*server_info) {
- DEBUG(0,("make_server_info: malloc failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP(*server_info);
-
- /* Initialise the uid and gid values to something non-zero
- which may save us from giving away root access if there
- is a bug in allocating these fields. */
-
- (*server_info)->uid = -1;
- (*server_info)->gid = -1;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
-Fill a server_info struct from a SAM_ACCOUNT with their groups
-***************************************************************************/
-
-static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
- const char * unix_username,
- SAM_ACCOUNT *sampass,
- uid_t uid, gid_t gid)
-{
- NTSTATUS nt_status;
- const DOM_SID *user_sid = pdb_get_user_sid(sampass);
- const DOM_SID *group_sid = pdb_get_group_sid(sampass);
- int n_groupSIDs = 0;
- DOM_SID *groupSIDs = NULL;
- gid_t *unix_groups = NULL;
- NT_USER_TOKEN *token;
- BOOL is_guest;
- uint32 rid;
-
- nt_status = get_user_groups(unix_username, uid, gid,
- &n_groupSIDs, &groupSIDs, &unix_groups);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(4,("get_user_groups_from_local_sam failed\n"));
- free_server_info(server_info);
- return nt_status;
- }
-
- is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST);
-
- if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid,
- n_groupSIDs, groupSIDs, is_guest,
- &token)))
- {
- DEBUG(4,("create_nt_user_token failed\n"));
- SAFE_FREE(groupSIDs);
- SAFE_FREE(unix_groups);
- free_server_info(server_info);
- return nt_status;
- }
-
- SAFE_FREE(groupSIDs);
-
- (*server_info)->n_groups = n_groupSIDs;
- (*server_info)->groups = unix_groups;
- (*server_info)->ptok = token;
-
- return nt_status;
-}
-
-/***************************************************************************
-Fill a server_info struct from a SAM_ACCOUNT with its privileges
-***************************************************************************/
-
-static NTSTATUS add_privileges(auth_serversupplied_info **server_info)
-{
- PRIVILEGE_SET *privs = NULL;
-
- init_privilege(&privs);
-
- become_root();
- if (!NT_STATUS_IS_OK(pdb_get_privilege_set((*server_info)->ptok->user_sids, (*server_info)->ptok->num_sids, privs)))
- DEBUG(1, ("Could not add privileges\n"));
-
- unbecome_root();
-
- (*server_info)->privs = privs;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Make (and fill) a user_info struct from a SAM_ACCOUNT
-***************************************************************************/
-
-NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
- SAM_ACCOUNT *sampass)
-{
- NTSTATUS nt_status;
- struct passwd *pwd;
-
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
- return nt_status;
-
- (*server_info)->sam_account = sampass;
-
- if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
- DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
- pdb_get_username(sampass)));
- free_server_info(server_info);
- return NT_STATUS_NO_SUCH_USER;
- }
- (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
- (*server_info)->gid = pwd->pw_gid;
- (*server_info)->uid = pwd->pw_uid;
-
- passwd_free(&pwd);
-
- if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
- sampass,
- (*server_info)->uid,
- (*server_info)->gid)))
- {
- free_server_info(server_info);
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = add_privileges(server_info))) {
- free_server_info(server_info);
- return nt_status;
- }
-
- (*server_info)->sam_fill_level = SAM_FILL_ALL;
- DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
- pdb_get_username(sampass),
- (*server_info)->unix_name));
-
- return nt_status;
-}
-
-/***************************************************************************
- Make (and fill) a user_info struct from a 'struct passwd' by conversion
- to a SAM_ACCOUNT
-***************************************************************************/
-
-NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
- char *unix_username,
- struct passwd *pwd)
-{
- NTSTATUS nt_status;
- SAM_ACCOUNT *sampass = NULL;
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
- return nt_status;
- }
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
- return nt_status;
- }
-
- (*server_info)->sam_account = sampass;
-
- if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
- sampass, pwd->pw_uid, pwd->pw_gid)))
- {
- return nt_status;
- }
-
- (*server_info)->unix_name = smb_xstrdup(unix_username);
-
- (*server_info)->sam_fill_level = SAM_FILL_ALL;
- (*server_info)->uid = pwd->pw_uid;
- (*server_info)->gid = pwd->pw_gid;
- return nt_status;
-}
-
-/***************************************************************************
- Make (and fill) a user_info struct for a guest login.
-***************************************************************************/
-
-NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status;
- SAM_ACCOUNT *sampass = NULL;
- DOM_SID guest_sid;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
- return nt_status;
- }
-
- sid_copy(&guest_sid, get_global_sam_sid());
- sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
-
- become_root();
- if (!pdb_getsampwsid(sampass, &guest_sid)) {
- unbecome_root();
- return NT_STATUS_NO_SUCH_USER;
- }
- unbecome_root();
-
- nt_status = make_server_info_sam(server_info, sampass);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- static const char zeros[16];
- (*server_info)->guest = True;
-
- /* annoying, but the Guest really does have a session key,
- and it is all zeros! */
- (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
- (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
- }
-
- return nt_status;
-}
-
-/***************************************************************************
- Purely internal function for make_server_info_info3
- Fill the sam account from getpwnam
-***************************************************************************/
-static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *username,
- char **found_username,
- uid_t *uid, gid_t *gid,
- SAM_ACCOUNT **sam_account)
-{
- fstring dom_user;
- fstring real_username;
- struct passwd *passwd;
-
- fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(),
- username);
-
- /* get the passwd struct but don't create the user if he/she
- does not exist. We were explicitly called from a following
- a winbindd authentication request so we should assume that
- nss_winbindd is working */
-
- if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
- return NT_STATUS_NO_SUCH_USER;
-
- *uid = passwd->pw_uid;
- *gid = passwd->pw_gid;
-
- /* This is pointless -- there is no suport for differing
- unix and windows names. Make sure to always store the
- one we actually looked up and succeeded. Have I mentioned
- why I hate the 'winbind use default domain' parameter?
- --jerry */
-
- *found_username = talloc_strdup( mem_ctx, real_username );
-
- DEBUG(5,("fill_sam_account: located username was [%s]\n",
- *found_username));
-
- return pdb_init_sam_pw(sam_account, passwd);
-}
-
-/****************************************************************************
- Wrapper to allow the getpwnam() call to strip the domain name and
- try again in case a local UNIX user is already there. Also run through
- the username if we fallback to the username only.
- ****************************************************************************/
-
-struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
-{
- struct passwd *pw = NULL;
- char *p;
- fstring mapped_username;
- fstring strip_username;
-
- /* we only save a copy of the username it has been mangled
- by winbindd use default domain */
-
- save_username[0] = '\0';
-
- /* save a local copy of the username and run it through the
- username map */
-
- fstrcpy( mapped_username, domuser );
- map_username( mapped_username );
-
- p = strchr_m( mapped_username, *lp_winbind_separator() );
-
- /* code for a DOMAIN\user string */
-
- if ( p ) {
- pw = Get_Pwnam( domuser );
- if ( pw ) {
- /* make sure we get the case of the username correct */
- /* work around 'winbind use default domain = yes' */
-
- if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
- char *domain;
-
- domain = mapped_username;
- *p = '\0';
- fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
- }
- else
- fstrcpy( save_username, pw->pw_name );
-
- /* whew -- done! */
- return pw;
- }
-
- /* setup for lookup of just the username */
- /* remember that p and mapped_username are overlapping memory */
-
- p++;
- fstrcpy( strip_username, p );
- fstrcpy( mapped_username, strip_username );
- }
-
- /* just lookup a plain username */
-
- pw = Get_Pwnam(mapped_username);
-
- /* Create local user if requested. */
-
- if ( !pw && create ) {
- /* Don't add a machine account. */
- if (mapped_username[strlen(mapped_username)-1] == '$')
- return NULL;
-
- auth_add_user_script(NULL, mapped_username);
- pw = Get_Pwnam(mapped_username);
- }
-
- /* one last check for a valid passwd struct */
-
- if ( pw )
- fstrcpy( save_username, pw->pw_name );
-
- return pw;
-}
-
-/***************************************************************************
- Make a server_info struct from the info3 returned by a domain logon
-***************************************************************************/
-
-NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
- const char *internal_username,
- const char *sent_nt_username,
- const char *domain,
- auth_serversupplied_info **server_info,
- NET_USER_INFO_3 *info3)
-{
- static const char zeros[16];
-
- NTSTATUS nt_status = NT_STATUS_OK;
- char *found_username;
- const char *nt_domain;
- const char *nt_username;
-
- SAM_ACCOUNT *sam_account = NULL;
- DOM_SID user_sid;
- DOM_SID group_sid;
-
- uid_t uid;
- gid_t gid;
-
- int n_lgroupSIDs;
- DOM_SID *lgroupSIDs = NULL;
-
- gid_t *unix_groups = NULL;
- NT_USER_TOKEN *token;
-
- DOM_SID *all_group_SIDs;
- size_t i;
-
- /*
- Here is where we should check the list of
- trusted domains, and verify that the SID
- matches.
- */
-
- sid_copy(&user_sid, &info3->dom_sid.sid);
- if (!sid_append_rid(&user_sid, info3->user_rid)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- sid_copy(&group_sid, &info3->dom_sid.sid);
- if (!sid_append_rid(&group_sid, info3->group_rid)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
- /* If the server didn't give us one, just use the one we sent them */
- nt_username = sent_nt_username;
- }
-
- if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
- /* If the server didn't give us one, just use the one we sent them */
- nt_domain = domain;
- }
-
- /* try to fill the SAM account.. If getpwnam() fails, then try the
- add user script (2.2.x behavior) */
-
- nt_status = fill_sam_account(mem_ctx, nt_domain, internal_username,
- &found_username, &uid, &gid, &sam_account);
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
- DEBUG(3,("User %s does not exist, trying to add it\n",
- internal_username));
- auth_add_user_script(nt_domain, internal_username);
- nt_status = fill_sam_account(mem_ctx, nt_domain,
- internal_username, &found_username,
- &uid, &gid, &sam_account);
- }
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
- return nt_status;
- }
-
- if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
- PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
- DEBUG(4, ("make_server_info failed!\n"));
- pdb_free_sam(&sam_account);
- return nt_status;
- }
-
- /* save this here to _net_sam_logon() doesn't fail (it assumes a
- valid SAM_ACCOUNT) */
-
- (*server_info)->sam_account = sam_account;
-
- (*server_info)->unix_name = smb_xstrdup(found_username);
-
- /* Fill in the unix info we found on the way */
-
- (*server_info)->sam_fill_level = SAM_FILL_ALL;
- (*server_info)->uid = uid;
- (*server_info)->gid = gid;
-
- /* Store the user group information in the server_info
- returned to the caller. */
-
- nt_status = get_user_groups((*server_info)->unix_name,
- uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
-
- if ( !NT_STATUS_IS_OK(nt_status) ) {
- DEBUG(4,("get_user_groups failed\n"));
- return nt_status;
- }
-
- (*server_info)->groups = unix_groups;
- (*server_info)->n_groups = n_lgroupSIDs;
-
- /* Create a 'combined' list of all SIDs we might want in the SD */
-
- all_group_SIDs = malloc(sizeof(DOM_SID) * (info3->num_groups2 +info3->num_other_sids));
-
- if (!all_group_SIDs) {
- DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
- SAFE_FREE(lgroupSIDs);
- free_server_info(server_info);
- return NT_STATUS_NO_MEMORY;
- }
-
-#if 0 /* JERRY -- no such thing as local groups in current code */
- /* Copy the 'local' sids */
- memcpy(all_group_SIDs, lgroupSIDs, sizeof(DOM_SID) * n_lgroupSIDs);
- SAFE_FREE(lgroupSIDs);
-#endif
-
- /* and create (by appending rids) the 'domain' sids */
-
- for (i = 0; i < info3->num_groups2; i++) {
-
- sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
-
- if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
-
- nt_status = NT_STATUS_INVALID_PARAMETER;
-
- DEBUG(3,("could not append additional group rid 0x%x\n",
- info3->gids[i].g_rid));
-
- SAFE_FREE(lgroupSIDs);
- free_server_info(server_info);
-
- return nt_status;
-
- }
- }
-
- /* Copy 'other' sids. We need to do sid filtering here to
- prevent possible elevation of privileges. See:
-
- http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
- */
-
- for (i = 0; i < info3->num_other_sids; i++) {
- sid_copy(&all_group_SIDs[info3->num_groups2 + i],
- &info3->other_sids[i].sid);
- }
-
- /* Where are the 'global' sids... */
-
- /* can the user be guest? if yes, where is it stored? */
-
- nt_status = create_nt_user_token(&user_sid, &group_sid,
- info3->num_groups2 + info3->num_other_sids,
- all_group_SIDs, False, &token);
-
- if ( !NT_STATUS_IS_OK(nt_status) ) {
- DEBUG(4,("create_nt_user_token failed\n"));
- SAFE_FREE(all_group_SIDs);
- free_server_info(server_info);
- return nt_status;
- }
-
- (*server_info)->ptok = token;
-
- SAFE_FREE(all_group_SIDs);
-
- /* ensure we are never given NULL session keys */
-
- if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
- (*server_info)->user_session_key = data_blob(NULL, 0);
- } else {
- (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
- }
-
- if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) {
- (*server_info)->lm_session_key = data_blob(NULL, 0);
- } else {
- (*server_info)->lm_session_key = data_blob(info3->padding, 16);
- }
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Free a user_info struct
-***************************************************************************/
-
-void free_user_info(auth_usersupplied_info **user_info)
-{
- DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
- if (*user_info != NULL) {
- if ((*user_info)->smb_name.str) {
- DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
- }
- SAFE_FREE((*user_info)->smb_name.str);
- SAFE_FREE((*user_info)->internal_username.str);
- SAFE_FREE((*user_info)->client_domain.str);
- SAFE_FREE((*user_info)->domain.str);
- SAFE_FREE((*user_info)->wksta_name.str);
- data_blob_free(&(*user_info)->lm_resp);
- data_blob_free(&(*user_info)->nt_resp);
- data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
- data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
- data_blob_clear_free(&(*user_info)->plaintext_password);
- ZERO_STRUCT(**user_info);
- }
- SAFE_FREE(*user_info);
-}
-
-/***************************************************************************
- Clear out a server_info struct that has been allocated
-***************************************************************************/
-
-void free_server_info(auth_serversupplied_info **server_info)
-{
- DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
- if (*server_info != NULL) {
- pdb_free_sam(&(*server_info)->sam_account);
-
- /* call pam_end here, unless we know we are keeping it */
- delete_nt_token( &(*server_info)->ptok );
- SAFE_FREE((*server_info)->groups);
- SAFE_FREE((*server_info)->unix_name);
- data_blob_free(&(*server_info)->lm_session_key);
- data_blob_free(&(*server_info)->user_session_key);
- ZERO_STRUCT(**server_info);
- }
- SAFE_FREE(*server_info);
-}
-
-/***************************************************************************
- Make an auth_methods struct
-***************************************************************************/
-
-BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
-{
- if (!auth_context) {
- smb_panic("no auth_context supplied to make_auth_methods()!\n");
- }
-
- if (!auth_method) {
- smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
- }
-
- *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
- if (!*auth_method) {
- DEBUG(0,("make_auth_method: malloc failed!\n"));
- return False;
- }
- ZERO_STRUCTP(*auth_method);
-
- return True;
-}
-
-/****************************************************************************
- Delete a SID token.
-****************************************************************************/
-
-void delete_nt_token(NT_USER_TOKEN **pptoken)
-{
- if (*pptoken) {
- NT_USER_TOKEN *ptoken = *pptoken;
- SAFE_FREE( ptoken->user_sids );
- ZERO_STRUCTP(ptoken);
- }
- SAFE_FREE(*pptoken);
-}
-
-/****************************************************************************
- Duplicate a SID token.
-****************************************************************************/
-
-NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
-{
- NT_USER_TOKEN *token;
-
- if (!ptoken)
- return NULL;
-
- if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
- return NULL;
-
- ZERO_STRUCTP(token);
-
- if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
- SAFE_FREE(token);
- return NULL;
- }
-
- token->num_sids = ptoken->num_sids;
-
- return token;
-}
-
-/**
- * Verify whether or not given domain is trusted.
- *
- * @param domain_name name of the domain to be verified
- * @return true if domain is one of the trusted once or
- * false if otherwise
- **/
-
-BOOL is_trusted_domain(const char* dom_name)
-{
- DOM_SID trustdom_sid;
- char *pass = NULL;
- time_t lct;
- BOOL ret;
-
- /* no trusted domains for a standalone server */
-
- if ( lp_server_role() == ROLE_STANDALONE )
- return False;
-
- /* if we are a DC, then check for a direct trust relationships */
-
- if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
- become_root();
- ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
- unbecome_root();
- SAFE_FREE(pass);
- if (ret)
- return True;
- }
- else {
- /* if winbindd is not up and we are a domain member) then we need to update the
- trustdom_cache ourselves */
-
- if ( !winbind_ping() )
- update_trustdom_cache();
- }
-
- /* now the trustdom cache should be available a DC could still
- * have a transitive trust so fall back to the cache of trusted
- * domains (like a domain member would use */
-
- if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
- return True;
- }
-
- return False;
-}
-
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
deleted file mode 100644
index 0e2820313e3..00000000000
--- a/source/auth/auth_winbind.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind authentication mechnism
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Bartlett 2001 - 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
-{
- uint8 *info3_ndr;
- size_t len = response->length - sizeof(struct winbindd_response);
- prs_struct ps;
- if (len > 0) {
- info3_ndr = response->extra_data;
- if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- prs_copy_data_in(&ps, (char *)info3_ndr, len);
- prs_set_offset(&ps,0);
- if (!net_io_user_info3("", info3, &ps, 1, 3)) {
- DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- prs_mem_free(&ps);
-
- return NT_STATUS_OK;
- } else {
- DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-}
-
-/* Authenticate a user with a challenge/response */
-
-static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- NTSTATUS nt_status;
- NET_USER_INFO_3 info3;
-
- if (!user_info) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!auth_context) {
- DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
- user_info->internal_username.str));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (strequal(user_info->domain.str, get_global_sam_name())) {
- DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
- user_info->domain.str));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.flags = WBFLAG_PAM_INFO3_NDR;
-
- push_utf8_fstring(request.data.auth_crap.user,
- user_info->smb_name.str);
- push_utf8_fstring(request.data.auth_crap.domain,
- user_info->domain.str);
- push_utf8_fstring(request.data.auth_crap.workstation,
- user_info->wksta_name.str);
-
- memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
-
- request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length,
- sizeof(request.data.auth_crap.lm_resp));
- request.data.auth_crap.nt_resp_len = MIN(user_info->nt_resp.length,
- sizeof(request.data.auth_crap.nt_resp));
-
- memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data,
- request.data.auth_crap.lm_resp_len);
- memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data,
- request.data.auth_crap.nt_resp_len);
-
- /* we are contacting the privileged pipe */
- become_root();
- result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
- unbecome_root();
-
- if ( result == NSS_STATUS_UNAVAIL ) {
- struct auth_methods *auth_method = my_private_data;
-
- if ( auth_method )
- return auth_method->auth(auth_context, auth_method->private_data,
- mem_ctx, user_info, server_info);
- else
- /* log an error since this should not happen */
- DEBUG(0,("check_winbind_security: ERROR! my_private_data == NULL!\n"));
- }
-
- nt_status = NT_STATUS(response.data.auth.nt_status);
-
- if (result == NSS_STATUS_SUCCESS && response.extra_data) {
- if (NT_STATUS_IS_OK(nt_status)) {
-
- if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3)))
- {
- nt_status = make_server_info_info3(mem_ctx,
- user_info->internal_username.str,
- user_info->smb_name.str, user_info->domain.str,
- server_info, &info3);
- }
-
- }
- } else if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = NT_STATUS_NO_LOGON_SERVERS;
- }
-
- return nt_status;
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->name = "winbind";
- (*auth_method)->auth = check_winbind_security;
-
- if (param && *param) {
- /* we load the 'fallback' module - if winbind isn't here, call this
- module */
- if (!load_auth_module(auth_context, param, (auth_methods **)&(*auth_method)->private_data)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- }
- return NT_STATUS_OK;
-}
-
-NTSTATUS auth_winbind_init(void)
-{
- return smb_register_auth(AUTH_INTERFACE_VERSION, "winbind", auth_init_winbind);
-}
diff --git a/source/auth/pampass.c b/source/auth/pampass.c
index 3239686a20d..018eae3a07e 100644
--- a/source/auth/pampass.c
+++ b/source/auth/pampass.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.
PAM Password checking
Copyright (C) Andrew Tridgell 1992-2001
Copyright (C) John H Terpsta 1999-2001
@@ -29,9 +30,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
#ifdef WITH_PAM
/*******************************************************************
@@ -65,7 +63,7 @@ typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_resp
PAM error handler.
*********************************************************************/
-static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, const char *msg, int dbglvl)
+static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl)
{
if( pam_error != PAM_SUCCESS) {
@@ -83,11 +81,9 @@ static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, const char
*********************************************************************/
static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
- const char *msg, int dbglvl,
+ char *msg, int dbglvl,
NTSTATUS *nt_status)
{
- *nt_status = pam_to_nt_status(pam_error);
-
if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
return True;
@@ -186,7 +182,7 @@ static void special_char_sub(char *buf)
static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass)
{
- fstring_sub(buf, "%u", username);
+ pstring_sub(buf, "%u", username);
all_string_sub(buf, "%o", oldpass, sizeof(fstring));
all_string_sub(buf, "%n", newpass, sizeof(fstring));
}
@@ -229,8 +225,8 @@ static struct chat_struct *make_pw_chat(char *p)
special_char_sub(prompt);
fstrcpy(t->prompt, prompt);
- strlower_m(t->prompt);
- trim_char(t->prompt, ' ', ' ');
+ strlower(t->prompt);
+ trim_string(t->prompt, " ", " ");
if (!next_token(&p, reply, NULL, sizeof(fstring)))
break;
@@ -240,8 +236,8 @@ static struct chat_struct *make_pw_chat(char *p)
special_char_sub(reply);
fstrcpy(t->reply, reply);
- strlower_m(t->reply);
- trim_char(t->reply, ' ', ' ');
+ strlower(t->reply);
+ trim_string(t->reply, " ", " ");
}
return list;
@@ -304,7 +300,7 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_ON:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- trim_char(current_prompt, ' ', ' ');
+ trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: trying to match |%s| to |%s|\n",
@@ -335,7 +331,7 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_OFF:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- trim_char(current_prompt, ' ', ' ');
+ trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: trying to match |%s| to |%s|\n",
@@ -497,7 +493,7 @@ static BOOL smb_pam_start(pam_handle_t **pamh, const char *user, const char *rho
/*
* PAM Authentication Handler
*/
-static NTSTATUS smb_pam_auth(pam_handle_t *pamh, const char *user)
+static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user)
{
int pam_error;
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -512,27 +508,35 @@ static NTSTATUS smb_pam_auth(pam_handle_t *pamh, const char *user)
switch( pam_error ){
case PAM_AUTH_ERR:
DEBUG(2, ("smb_pam_auth: PAM: Athentication Error for user %s\n", user));
+ nt_status = NT_STATUS_WRONG_PASSWORD;
break;
case PAM_CRED_INSUFFICIENT:
DEBUG(2, ("smb_pam_auth: PAM: Insufficient Credentials for user %s\n", user));
+ nt_status = NT_STATUS_INSUFFICIENT_LOGON_INFO;
break;
case PAM_AUTHINFO_UNAVAIL:
DEBUG(2, ("smb_pam_auth: PAM: Authentication Information Unavailable for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
break;
case PAM_USER_UNKNOWN:
DEBUG(2, ("smb_pam_auth: PAM: Username %s NOT known to Authentication system\n", user));
+ nt_status = NT_STATUS_NO_SUCH_USER;
break;
case PAM_MAXTRIES:
DEBUG(2, ("smb_pam_auth: PAM: One or more authentication modules reports user limit for user %s exceeeded\n", user));
+ nt_status = NT_STATUS_REMOTE_SESSION_LIMIT;
break;
case PAM_ABORT:
DEBUG(0, ("smb_pam_auth: PAM: One or more PAM modules failed to load for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user));
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
break;
}
@@ -553,23 +557,30 @@ static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user)
switch( pam_error ) {
case PAM_AUTHTOK_EXPIRED:
DEBUG(2, ("smb_pam_account: PAM: User %s is valid but password is expired\n", user));
+ nt_status = NT_STATUS_PASSWORD_EXPIRED;
break;
case PAM_ACCT_EXPIRED:
DEBUG(2, ("smb_pam_account: PAM: User %s no longer permitted to access system\n", user));
+ nt_status = NT_STATUS_ACCOUNT_EXPIRED;
break;
case PAM_AUTH_ERR:
DEBUG(2, ("smb_pam_account: PAM: There was an authentication error for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
break;
case PAM_PERM_DENIED:
DEBUG(0, ("smb_pam_account: PAM: User %s is NOT permitted to access system at this time\n", user));
+ nt_status = NT_STATUS_ACCOUNT_RESTRICTION;
break;
case PAM_USER_UNKNOWN:
DEBUG(0, ("smb_pam_account: PAM: User \"%s\" is NOT known to account management\n", user));
+ nt_status = NT_STATUS_NO_SUCH_USER;
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user));
+ nt_status = NT_STATUS_OK;
break;
default:
+ nt_status = NT_STATUS_ACCOUNT_DISABLED;
DEBUG(0, ("smb_pam_account: PAM: UNKNOWN PAM ERROR (%d) during Account Management for User: %s\n", pam_error, user));
break;
}
@@ -582,7 +593,7 @@ static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user)
* PAM Credential Setting
*/
-static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user)
+static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user)
{
int pam_error;
NTSTATUS nt_status = NT_STATUS_NO_TOKEN;
@@ -597,21 +608,27 @@ static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user)
switch( pam_error ) {
case PAM_CRED_UNAVAIL:
DEBUG(0, ("smb_pam_setcred: PAM: Credentials not found for user:%s\n", user ));
+ nt_status = NT_STATUS_NO_TOKEN;
break;
case PAM_CRED_EXPIRED:
DEBUG(0, ("smb_pam_setcred: PAM: Credentials for user: \"%s\" EXPIRED!\n", user ));
+ nt_status = NT_STATUS_PASSWORD_EXPIRED;
break;
case PAM_USER_UNKNOWN:
DEBUG(0, ("smb_pam_setcred: PAM: User: \"%s\" is NOT known so can not set credentials!\n", user ));
+ nt_status = NT_STATUS_NO_SUCH_USER;
break;
case PAM_CRED_ERR:
DEBUG(0, ("smb_pam_setcred: PAM: Unknown setcredentials error - unable to set credentials for %s\n", user ));
+ nt_status = NT_STATUS_LOGON_FAILURE;
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user));
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user));
+ nt_status = NT_STATUS_NO_TOKEN;
break;
}
@@ -622,7 +639,7 @@ static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user)
/*
* PAM Internal Session Handler
*/
-static BOOL smb_internal_pam_session(pam_handle_t *pamh, const char *user, const char *tty, BOOL flag)
+static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag)
{
int pam_error;
@@ -788,7 +805,7 @@ NTSTATUS smb_pam_accountcheck(const char * user)
* PAM Password Validation Suite
*/
-NTSTATUS smb_pam_passcheck(const char * user, const char * password)
+NTSTATUS smb_pam_passcheck(char * user, char * password)
{
pam_handle_t *pamh = NULL;
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c
index 1ac8c1815a6..68f0566aee7 100644
--- a/source/auth/pass_check.c
+++ b/source/auth/pass_check.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Password checking
Copyright (C) Andrew Tridgell 1992-1998
@@ -23,15 +24,10 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
/* these are kept here to keep the string_combinations function simple */
static fstring this_user;
-#if !defined(WITH_PAM)
static fstring this_salt;
static fstring this_crypted;
-#endif
#ifdef WITH_AFS
@@ -372,6 +368,122 @@ void dfs_unlogin(void)
}
#endif
+#ifdef KRB5_AUTH
+
+#include <krb5.h>
+
+/*******************************************************************
+check on Kerberos authentication
+********************************************************************/
+static BOOL krb5_auth(char *user, char *password)
+{
+ krb5_data tgtname = {
+ 0,
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME
+ };
+ krb5_context kcontext;
+ krb5_principal kprinc;
+ krb5_principal server;
+ krb5_creds kcreds;
+ int options = 0;
+ krb5_address **addrs = (krb5_address **) 0;
+ krb5_preauthtype *preauth = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_timestamp now;
+ krb5_ccache ccache = NULL;
+ int retval;
+ char *name;
+
+ if (retval = krb5_init_context(&kcontext))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_timeofday(kcontext, &now))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_cc_default(kcontext, &ccache))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_parse_name(kcontext, user, &kprinc))
+ {
+ return (False);
+ }
+
+ ZERO_STRUCT(kcreds);
+
+ kcreds.client = kprinc;
+
+ if ((retval = krb5_build_principal_ext(kcontext, &server,
+ krb5_princ_realm(kcontext,
+ kprinc)->
+ length,
+ krb5_princ_realm(kcontext,
+ kprinc)->data,
+ tgtname.length, tgtname.data,
+ krb5_princ_realm(kcontext,
+ kprinc)->
+ length,
+ krb5_princ_realm(kcontext,
+ kprinc)->data,
+ 0)))
+ {
+ return (False);
+ }
+
+ kcreds.server = server;
+
+ retval = krb5_get_in_tkt_with_password(kcontext,
+ options,
+ addrs,
+ NULL,
+ preauth,
+ password, 0, &kcreds, 0);
+
+ if (retval)
+ {
+ return (False);
+ }
+
+ return (True);
+}
+#endif /* KRB5_AUTH */
+
+#ifdef KRB4_AUTH
+#include <krb.h>
+
+/*******************************************************************
+check on Kerberos authentication
+********************************************************************/
+static BOOL krb4_auth(char *user, char *password)
+{
+ char realm[REALM_SZ];
+ char tkfile[MAXPATHLEN];
+
+ if (krb_get_lrealm(realm, 1) != KSUCCESS)
+ {
+ (void)safe_strcpy(realm, KRB_REALM, sizeof(realm) - 1);
+ }
+
+ (void)slprintf(tkfile, sizeof(tkfile) - 1, "/tmp/samba_tkt_%d",
+ (int)sys_getpid());
+
+ krb_set_tkt_string(tkfile);
+ if (krb_verify_user(user, "", realm, password, 0, "rmcd") == KSUCCESS)
+ {
+ unlink(tkfile);
+ return 1;
+ }
+ unlink(tkfile);
+ return 0;
+}
+#endif /* KRB4_AUTH */
+
#ifdef LINUX_BIGCRYPT
/****************************************************************************
an enhanced crypt for Linux to handle password longer than 8 characters
@@ -436,12 +548,11 @@ try all combinations with N uppercase letters.
offset is the first char to try and change (start with 0)
it assumes the string starts lowercased
****************************************************************************/
-static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *),
+static BOOL string_combinations2(char *s, int offset, BOOL (*fn) (char *),
int N)
{
int len = strlen(s);
int i;
- NTSTATUS nt_status;
#ifdef PASSWORD_LENGTH
len = MIN(len, PASSWORD_LENGTH);
@@ -455,12 +566,11 @@ static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const
if (!islower(c))
continue;
s[i] = toupper(c);
- if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) {
- return (nt_status);
- }
+ if (string_combinations2(s, i + 1, fn, N - 1))
+ return (True);
s[i] = c;
}
- return (NT_STATUS_WRONG_PASSWORD);
+ return (False);
}
/****************************************************************************
@@ -470,76 +580,71 @@ try all combinations with up to N uppercase letters.
offset is the first char to try and change (start with 0)
it assumes the string starts lowercased
****************************************************************************/
-static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N)
+static BOOL string_combinations(char *s, BOOL (*fn) (char *), int N)
{
int n;
- NTSTATUS nt_status;
for (n = 1; n <= N; n++)
- if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, 0, fn, n), NT_STATUS_WRONG_PASSWORD))
- return nt_status;
- return NT_STATUS_WRONG_PASSWORD;
+ if (string_combinations2(s, 0, fn, n))
+ return (True);
+ return (False);
}
/****************************************************************************
core of password checking routine
****************************************************************************/
-static NTSTATUS password_check(const char *password)
+static BOOL password_check(char *password)
{
-#ifdef WITH_PAM
- return smb_pam_passcheck(this_user, password);
-#else
- BOOL ret;
+#ifdef WITH_PAM
+ return (NT_STATUS_IS_OK(smb_pam_passcheck(this_user, password)));
+#endif /* WITH_PAM */
#ifdef WITH_AFS
if (afs_auth(this_user, password))
- return NT_STATUS_OK;
+ return (True);
#endif /* WITH_AFS */
#ifdef WITH_DFS
if (dfs_auth(this_user, password))
- return NT_STATUS_OK;
+ return (True);
#endif /* WITH_DFS */
+#ifdef KRB5_AUTH
+ if (krb5_auth(this_user, password))
+ return (True);
+#endif /* KRB5_AUTH */
+
+#ifdef KRB4_AUTH
+ if (krb4_auth(this_user, password))
+ return (True);
+#endif /* KRB4_AUTH */
+
#ifdef OSF1_ENH_SEC
-
- ret = (strcmp(osf1_bigcrypt(password, this_salt),
- this_crypted) == 0);
- if (!ret) {
- DEBUG(2,
- ("OSF1_ENH_SEC failed. Trying normal crypt.\n"));
- ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
- }
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
+ {
+ BOOL ret =
+ (strcmp
+ (osf1_bigcrypt(password, this_salt),
+ this_crypted) == 0);
+ if (!ret) {
+ DEBUG(2,
+ ("OSF1_ENH_SEC failed. Trying normal crypt.\n"));
+ ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+ }
+ return ret;
}
-
#endif /* OSF1_ENH_SEC */
-
+
#ifdef ULTRIX_AUTH
- ret = (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
- }
-
+ return (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
#endif /* ULTRIX_AUTH */
-
+
#ifdef LINUX_BIGCRYPT
- ret = (linux_bigcrypt(password, this_salt, this_crypted));
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
- }
+ return (linux_bigcrypt(password, this_salt, this_crypted));
#endif /* LINUX_BIGCRYPT */
-
+
#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
-
+
/*
* Some systems have bigcrypt in the C library but might not
* actually use it for the password hashes (HPUX 10.20) is
@@ -548,68 +653,61 @@ static NTSTATUS password_check(const char *password)
*/
if (strcmp(bigcrypt(password, this_salt), this_crypted) == 0)
- return NT_STATUS_OK;
+ return True;
else
- ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
- }
+ return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
-
+
#ifdef HAVE_BIGCRYPT
- ret = (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
- }
+ return (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
#endif /* HAVE_BIGCRYPT */
-
+
#ifndef HAVE_CRYPT
DEBUG(1, ("Warning - no crypt available\n"));
- return NT_STATUS_LOGON_FAILURE;
+ return (False);
#else /* HAVE_CRYPT */
- ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
- if (ret) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_WRONG_PASSWORD;
- }
+ return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
#endif /* HAVE_CRYPT */
#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
-#endif /* WITH_PAM */
}
/****************************************************************************
-CHECK if a username/password is OK
+check if a username/password is OK
the function pointer fn() points to a function to call when a successful
match is found and is used to update the encrypted password file
-return NT_STATUS_OK on correct match, appropriate error otherwise
+return True on correct match, False otherwise
****************************************************************************/
-NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password,
- int pwlen, BOOL (*fn) (const char *, const char *), BOOL run_cracker)
+BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
+ BOOL (*fn) (char *, char *))
{
pstring pass2;
int level = lp_passwordlevel();
+ struct passwd *pass = NULL;
- NTSTATUS nt_status;
+ if (password)
+ password[pwlen] = 0;
#if DEBUG_PASSWORD
DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password));
#endif
if (!password)
- return NT_STATUS_LOGON_FAILURE;
+ return (False);
if (((!*password) || (!pwlen)) && !lp_null_passwords())
- return NT_STATUS_LOGON_FAILURE;
+ return (False);
+
+ if (pwd && !user) {
+ pass = (struct passwd *)pwd;
+ user = pass->pw_name;
+ } else {
+ pass = Get_Pwnam(user, True);
+ }
-#if defined(WITH_PAM)
+#ifdef WITH_PAM
/*
* If we're using PAM we want to short-circuit all the
@@ -626,16 +724,9 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
if (!pass) {
DEBUG(3, ("Couldn't find user %s\n", user));
- return NT_STATUS_NO_SUCH_USER;
+ return (False);
}
-
- /* Copy into global for the convenience of looping code */
- /* Also the place to keep the 'password' no matter what
- crazy struct it started in... */
- fstrcpy(this_crypted, pass->pw_passwd);
- fstrcpy(this_salt, pass->pw_passwd);
-
#ifdef HAVE_GETSPNAM
{
struct spwd *spass;
@@ -646,10 +737,8 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
perhaps for IPC password changing requests */
spass = getspnam(pass->pw_name);
- if (spass && spass->sp_pwdp) {
- fstrcpy(this_crypted, spass->sp_pwdp);
- fstrcpy(this_salt, spass->sp_pwdp);
- }
+ if (spass && spass->sp_pwdp)
+ pstrcpy(pass->pw_passwd, spass->sp_pwdp);
}
#elif defined(IA_UINFO)
{
@@ -667,16 +756,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
{
struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
if (pr_pw && pr_pw->ufld.fd_encrypt)
- fstrcpy(this_crypted, pr_pw->ufld.fd_encrypt);
- }
-#endif
-
-#ifdef HAVE_GETPWANAM
- {
- struct passwd_adjunct *pwret;
- pwret = getpwanam(s);
- if (pwret && pwret->pwa_passwd)
- fstrcpy(this_crypted, pwret->pwa_passwd);
+ pstrcpy(pass->pw_passwd, pr_pw->ufld.fd_encrypt);
}
#endif
@@ -687,8 +767,8 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
user));
mypasswd = getprpwnam(user);
if (mypasswd) {
- fstrcpy(this_user, mypasswd->ufld.fd_name);
- fstrcpy(this_crypted, mypasswd->ufld.fd_encrypt);
+ fstrcpy(pass->pw_name, mypasswd->ufld.fd_name);
+ fstrcpy(pass->pw_passwd, mypasswd->ufld.fd_encrypt);
} else {
DEBUG(5,
("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
@@ -701,83 +781,85 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
{
AUTHORIZATION *ap = getauthuid(pass->pw_uid);
if (ap) {
- fstrcpy(this_crypted, ap->a_password);
+ fstrcpy(pass->pw_passwd, ap->a_password);
endauthent();
}
}
#endif
+ /* extract relevant info */
+ fstrcpy(this_user, pass->pw_name);
+ fstrcpy(this_salt, pass->pw_passwd);
+
#if defined(HAVE_TRUNCATED_SALT)
/* crypt on some platforms (HPUX in particular)
won't work with more than 2 salt characters. */
this_salt[2] = 0;
#endif
+ fstrcpy(this_crypted, pass->pw_passwd);
+
if (!*this_crypted) {
if (!lp_null_passwords()) {
DEBUG(2, ("Disallowing %s with null password\n",
this_user));
- return NT_STATUS_LOGON_FAILURE;
+ return (False);
}
if (!*password) {
DEBUG(3,
("Allowing access to %s with null password\n",
this_user));
- return NT_STATUS_OK;
+ return (True);
}
}
-#endif /* defined(WITH_PAM) */
+#endif /* WITH_PAM */
/* try it as it came to us */
- nt_status = password_check(password);
- if NT_STATUS_IS_OK(nt_status) {
- if (fn) {
- fn(user, password);
- }
- return (nt_status);
- } else if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
- /* No point continuing if its not the password thats to blame (ie PAM disabled). */
- return (nt_status);
- }
-
- if (!run_cracker) {
- return (nt_status);
+ if (password_check(password)) {
+ if (fn)
+ fn(user, password);
+ return (True);
}
/* if the password was given to us with mixed case then we don't
- * need to proceed as we know it hasn't been case modified by the
- * client */
+ need to proceed as we know it hasn't been case modified by the
+ client */
if (strhasupper(password) && strhaslower(password)) {
- return nt_status;
+ return (False);
}
/* make a copy of it */
- pstrcpy(pass2, password);
+ StrnCpy(pass2, password, sizeof(pass2) - 1);
/* try all lowercase if it's currently all uppercase */
- if (strhasupper(pass2)) {
- strlower_m(pass2);
- if NT_STATUS_IS_OK(nt_status = password_check(pass2)) {
- if (fn)
- fn(user, pass2);
- return (nt_status);
+ if (strhasupper(password)) {
+ strlower(password);
+ if (password_check(password)) {
+ if (fn)
+ fn(user, password);
+ return (True);
}
}
/* give up? */
if (level < 1) {
- return NT_STATUS_WRONG_PASSWORD;
+ /* restore it */
+ fstrcpy(password, pass2);
+ return (False);
}
/* last chance - all combinations of up to level chars upper! */
- strlower_m(pass2);
-
- if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) {
- if (fn)
- fn(user, pass2);
- return nt_status;
- }
-
- return NT_STATUS_WRONG_PASSWORD;
+ strlower(password);
+
+ if (string_combinations(password, password_check, level)) {
+ if (fn)
+ fn(user, password);
+ return (True);
+ }
+
+ /* restore it */
+ fstrcpy(password, pass2);
+
+ return (False);
}
diff --git a/source/autogen.sh b/source/autogen.sh
deleted file mode 100755
index 922cad8e613..00000000000
--- a/source/autogen.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/sh
-
-# Run this script to build samba from SVN.
-
-## insert all possible names (only works with
-## autoconf 2.x
-TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50"
-TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50"
-
-AUTOHEADERFOUND="0"
-AUTOCONFFOUND="0"
-
-
-##
-## Look for autoheader
-##
-for i in $TESTAUTOHEADER; do
- if which $i > /dev/null 2>&1; then
- if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
- AUTOHEADER=$i
- AUTOHEADERFOUND="1"
- break
- fi
- fi
-done
-
-##
-## Look for autoconf
-##
-
-for i in $TESTAUTOCONF; do
- if which $i > /dev/null 2>&1; then
- if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
- AUTOCONF=$i
- AUTOCONFFOUND="1"
- break
- fi
- fi
-done
-
-
-##
-## do we have it?
-##
-if [ "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0" ]; then
- echo "$0: need autoconf 2.53 or later to build samba from SVN" >&2
- exit 1
-fi
-
-echo "$0: running script/mkversion.sh"
-./script/mkversion.sh || exit 1
-
-rm -rf autom4te*.cache
-
-echo "$0: running $AUTOHEADER"
-$AUTOHEADER || exit 1
-
-echo "$0: running $AUTOCONF"
-$AUTOCONF || exit 1
-
-rm -rf autom4te*.cache
-
-echo "Now run ./configure and then make."
-exit 0
-
diff --git a/source/change-log b/source/change-log
deleted file mode 100644
index 1f7798b541f..00000000000
--- a/source/change-log
+++ /dev/null
@@ -1,1878 +0,0 @@
-SUPERCEDED Change Log for Samba
-^^^^^^^^^^
-
-Unless otherwise attributed, all changes were made by
-Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.org.
-
-NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER
-
-NOTE: From now on the cvs.log file will be used to give a complete log of
-changes to samba. This change-log is now obsolete.
-
-1.5.00 announced to mailing list
-
-1.5.01 1/12/93
- - configuration through makefile only
- - fixed silly bug that made the client not accept dir's from
- the server
- - tested and updated include files for ultrix, aix and solaris
- - several things fixed thanks to pierson@ketje.enet.dec.com
- who provided invaluable help and advice.
-
-1.5.02 1/12/93
- - added username option to services file so connection
- as non guest from lanmanager is possible
- - made server abort when it can't read/write on a socket
- - added logging to client
-
-1.5.03 2/12/93
- - printing now works
- - fixed a minor bug to do with hidden and system attributes
-
-1.5.04 2/12/93
- - added reduce_name() call to fill in security hole.
- - cleanup up debug stuff a little
-
-1.5.05 2/12/93
- - fixed bug in reduce_name that affects services with base paths
- that have a soft link in them.
-
-1.5.06 3/12/93
- - used the reserved server field in the search status to hold the
- directory pointer. This allows lots of directories to be open
- at once by clients without stuffing things up.
- - preserved all the client reserved bytes in the search status
- in case they actually use them. Hopefully this will fix the annoying
- empty directory dir bug. (it does)
-
-1.5.07 3/12/93
- - fixed silly bug that caused volume ids to appear twice
- - fixed a wrote-too-few bug in smb_send()
-
-1.5.08 3/12/93
- - did the SMBsearch properly. It can now handle recursive searches.
- In order to keep the required dir info I encode the dirptr and
- the current dir offset (from telldir) into 5 bytes by using a table
- on the last 7 bits of the first byte. The first bit is always on
- as this byte must by != 0
- This is all put in the "server reserved" search field.
-
-1.5.09 5/12/93
- - added a prototype nameserver. It's broken but can at least interpret
- incoming packets.
- - minor fixes to the server and client
-
-
-1.5.10 5/12/93
- - fixed silly unsigned/signed char bug that made dosshell noot see all files
- - added nmbd to Makefile
-
-1.5.11 6/12/93
- - made the volume label appear as the service name, rather than "Remote"
- - made the nmbd actually work (a little) for lanman for dos
-
-1.5.12 7/12/93
- - fixed broadcasting in the nameserver
- - the smbd now correctly sets the pid and uid
- - nmbd now seems to work enough to satisfy the MS client.
-
-
-1.5.13 7/12/93
- - fixed a silly bug that truncated filenames
- - added -B option to nameserver to specify bcast address
- - added -R option to nameserver to prevent name registering
- - fixed minor read() bug. Does this fix the "cmp" bug?
-
-1.5.14 8/12/93
- - fixed a bug in send_login() in the client. Thanks to
- tim.hudson@gslmail.mincom.oz.au for pointing this out.
- - changed name_mangle() to pad to minimum of 32 bytes with spaces
- - changed the returned buffer size in reply_connect() to not
- count the 4 byte length field. This fixes the "can execute" bug
- and the "comp" bug
- - once again re-wrote the directory pointer handling code.
- now "tree" works correctly
-
-1.5.15 9/12/93
- - fixed name mangle bug introduced in 1.5.14 which stopped
- nameserver from working
-
-1.5.16 9/12/93
- - arrgh. another silly bug in name_mangle() causes the client to die.
-
-
-1.5.17 13/12/93
- - some cosmetic cleanups to the code
- - changed make_connection not to lower case the password (thanks
- to bryan@alex.com)
- - fixed accept() bug not initialising in_addrlen (thanks to
- bogstad@cs.jhu.edu)
- - fixed cd bug in client.c (thanks to joergs@toppoint.de)
- - lots of fixes to the nameserver to read_socket and
- associated routines. It should now correctly reply to the originating
- address and use the correct broadcast.
- (thanks to troyer@saifr00.ateng.az.honeywell.com)
- - SVR4 patches from mark@scot1.ucsalf.ac.uk
- - changed the default BUFFER_SIZE to 0xFFFF
-
-1.5.18 15/12/93
- - minor fix to reply_printqueue() to zero data buffer array.
- - added print command to client.
- - fixed minor bug in cmd_put() in client where a handle could
- be closed without being previously opened.
- - minor cleanups to the client
- - minor solaris fixes from lonnie@itg.ti.com
- - SYSV, shadow password and dfree() fixes from mark@scot1.ucsalf.ac.uk
- - fixed reply_delete() to not delete read-only files
- - fixed infinite loop in reply_delete on "del ."
- Thanks to mark@scot1.ucsalf.ac.uk for pointing this out.
- - posix mode definitions and changes from mark@scot1.ucsalf.ac.uk
-
-
-1.5.19 18/12/93
- - another very minor fix to dfree().
- - minor change to SVR4 makefile entry from rossw@march.co.uk
- - changed reply_open not to open directories, this fixes the
- "copy .." bug pointed out by mark@scot1.ucsalf.ac.uk
- - changed dos_mode() so it doesn't return hidden and system info
- on directories.
- - changed get_dir_entry() not to descend into proc/self under linux
- control this with the DONT_DESCEND define in includes.h
- - changed smb_setlen() to add in the SMB id. (thanks
- to troyer@saifr00.ateng.az.honeywell.com)
- - fixed minor bug in reply_dir() so it won't return a ACCESS_DENIED
- when searching a directory that is unreadable
- - removed second stat() from get_dir_entry() (speed up)
- - made null searches close the dirptr (fixes big filesystem problem)
- - fixed clean_name for cd .. (from magnus@axiom.se)
-
-
-1.5.20 28/12/93
- - added debug statement in case of SMBcreate with volid set (leefi@microsoft.com)
- - fixed a bug in dptr_close() so it sets the next_key to a better
- value, this fixes a annoying dir bug
- - LOTS of changes from jeremy@netcom.com (Jeremy Allison). This
- makes it possible to at least connect to a NT server with the client
- and also fixes up much of the socket/process code. This also includes
- stuff for compiling on a sun386
- - got the client working with the Syntax server (a commercial
- smb-based server). This required a few minor changes so the xmit
- sizes were negotiated properly.
- - added support for OSF1, tested on a DEC3000/400 alpha.
- - fixed the ifconf support under ultrix
-
-1.5.21 31/12/93
- - minor cosmetic change to reduce_name()
- - changes for HPUX from ppk@atk.tpo.fi (Pasi Kaara)
- - minor fix to nameserver
- - revamped configuration file format. It now takes a Windows-style
- (.INI style) configuration file. See the file services for
- full details of the format. New files: loadparm.c, loadparm.h,
- params.c, params.h, testparm.c. Several changes to smb.h, local.h,
- server.c, Makefile. The services structure is no longer visible
- to the rest of the system. (Karl Auer)
- - added ability to specify a print command on a per service basis
- and globally via the configuration file. Also allows guest account
- to be specified in the configuration file. Made appropriate changes
- to server.c so that these data items are obtained from the config
- module rather than from hardcoded strings (though the hardcoded
- strings are still the source of the defaults). (Karl Auer)
- - renamed old-style configuration file to services.old (Karl Auer)
- - changed README to reflect new configuration details. (Karl Auer)
- - removed an item from the bugs wishlist (now supplied!) (Karl Auer)
- - protected smb.h against multiple compilation. (Karl Auer)
- - protected local.h against multiple compilation. (Karl Auer)
- - made config stuff do dynamic allocation
- - added "homes" capability
- - added create_mask to each service in config
-
-1.5.22 3/1/94
- - added "root dir" option for extra security
- - added -n option to client (useful for OS/2)
- - changed operation of -n to nameserver to be more useful
- - patches from Jeremy Allison (jeremy@netcom.com)
- fixing bug in set_message(), fixing up wait3() for SYSV,
- making cd check the path in the client, allowing fetching to stdin
- in client, and enhancing prompt in client to include directory.
- - made the -D become_daemon() actually detach from the tty. This
- may need tuning for different flavors of unix.
- - added "dont descend" option to each service to prevent infinite
- loops on recursive filesystems.
- - updated README to add "running as a daemon" and a simple
- smb.conf file.
- - HP/UX fixes from ppk@atk.tpo.fi
- - made lock calls only if opened with write enabled, as pointed out
- by gadams@ddrive.demon.co.uk
-
-1.5.23 4/1/94
- - minor fix to logging of data in receive_smb(). It used to
- miss the last 4 bytes of packets.
- - added the pid,uid and mid fields to the negotiation phase of
- the client.
- - made client able to print from stdin
- - added password on command line for client
- - created a sample printcap input filter "smbprint"
- - several fixes to client to work with OS/2
- - added mput, mget, prompt and lcd to client
-
-1.5.24 5/1/94
- - a resend of 1.5.23 as I managed to not include the new
- prompt, mput and mget code.
-
-1.5.25 7/1/94
- - change -B on nameserver so it can override the broadcast address
- - minor changes to printing in client so OS/2 server can handle it.
- - fixed reply_access() where OK was not being initialised
- - added "max xmit" to global parameters.
- - changed create to open with O_RDWR instead of O_WRONLY
- - added printmode command to client
- - made help return extra help on a specified command in client
- - fixed return code in chkpath
- - added "recurse" and "lowercase" options to client
- - fixed some error codes from server
- - added -I option to client
- - fix for become_daemon() for HPUX from ppk@atk.tpo.fi
- - added "hosts allow" and "hosts deny" to server
- - added keepalives to server
- - added "access" feature to testparam
- - NetBSD patches from sreiz@aie.nl
-
-1.5.26 8/1/94
- - changed semantics of hosts access code to do more sensible defaults
- when either of "hosts allow" or "hosts deny" is blank
- - added the SO_KEEPALIVE option to configurations of sockets in the
- server
- - made some of the SVAL fns into macros to keep fussy compilers from
- complaining
- - fixed several null pointer bugs in check_access(). These bugs
- made 1.5.25 unuseable for many people.
- - fixed null pointer reference of lp_dontdescend()
- - reload services file after each new connection.
-
-1.5.27 11/1/94
- - fixed opening mode for reply_open() in server
- - patches from Jeremy Allison (jeremy@netcom.com) to support the
- "core+" protocol. The patches also inclued some other features, such
- as a new read_with_timeout() call (used by SMBreadbraw), and auto
- detection of the need to create a socket.
- - changed the default KEEPALIVE value to 0, as it caused
- problems with Lanmanager.
- - added tar capability to client when getting files
- - altered unix_mode() to return x bits for directories
- - fixed bug in trim_string()
-
-1.5.28 12/1/94
- - cleaned up the debug levels a little so debug level 1 is a practical
- level for general use
- - fixed a bug in add_a_service() where a freed pointer was referenced. Thanks
- to bryan@alex.com for finding the bug.
- - fixed bug in time structure handling in server and client. Thanks to
- bryan@alex.com for pointing out the bug.
-
-
-1.5.29 15/1/94
- - fixed a silly bug in reply_open(). Thanks to
- jeremy@netcom.com for pointing this out.
- - fixed debug levels in client to be more sensible
- - added raw read to client
- - added -B option to client
- - fixed several bugs in the client, mostly to do with the tar option
- - added -E option to client
-
-1.5.30 16/1/94
- - added lots of prototypes so compilers don't complain
- - fixed minor bug in reply_rename() (thanks to ppk@atk.tpo.fi)
- - added more support for LANMAN1.0 protocol.
- - added SESSION SETUP AND X call
- - added READ AND X call
- - added TREE CONNECT AND X call
- - added support for setbuffer for HPUX (thanks to ppk@atk.tpo.fi)
-
-1.5.31 29/1/94
- - added support for user level security in smbclient eg:
- smbclient "\\SERVER\SHARE" -U USERNAME%PASSWORD
- - added error message decode as per SMB File Sharing
- protocol extensions. (thanks to merik@blackadder.dsh.oz.au)
- - added selection masks to smbclient that recurse down directory
- tree. eg: mget *.* with recurse and mask *.c on will retrieve all
- *.c files in the tree.
- - patches for FreeBSD from kuku@acds.physik.rwth-aachen.de
- - changed reduce_name() to trim ./ from front of strings and / from
- back
- - fixed a nasty bug in trim_string().
- - numerous small changes to lots of stuff that I didn't
- document while I was doing them. Sorry :-(
- - slightly updated sockspy
-
- - The following was done by Karl Auer (Karl.Auer@anu.edu.au)
- - added processing in configuration file of a [printers] section. Allows
- connection to any printer specified in /etc/printcap (or the file
- specified in the global parameter 'printcap name').
- - added full processing of 'available' flag to configuration file. A
- service can now be 'turned off' by specifying 'available = no'. Of
- dubious utility.
- - added 'printcap =' parameter to [global] section in the configuration
- file. This allows the normal /etc/printcap to be bypassed when
- checking printer names for dynamic printer connections via [printers].
- - added 'printer name =' parameters to both the [global] section and
- services sections of the configuration file. This allows the printer
- name only to be set, without having to specify an entire print
- command.
- - added some synonyms: 'writable' and 'write ok' have the opposite sense
- to 'read only'. 'public' may be used instead of 'guest ok'. 'printer'
- may be used instead of 'printer name'. 'printable' is the same as
- 'print ok'. 'root' may be used instead of 'root dir' or 'root
- directory'.
- - added lots more detail to the sample configuration file to take
- account of the above.
- - many minor fixes to internal documentation in the configuration
- sources.
- - also - Man pages!
-
-
-1.5.32 3/2/94
- - addition of smbd, smbclient and testparm man pages
- from Karl Auer
- - zombie process fix from lendecke@namu01.gwdg.de
- - added capability to nmbd to serve names available
- via gethostbyname().
-
-1.5.33 3/2/94
- - fixed up getting of netmask so it works on more unix variants
- - added -N option to nmbd
- - changed GMT diff calculation. need to check it's right for
- lots of OSes
- - fixed a bug in read_and_X() and chain_reply() chaining now
- seems to work correctly
-
-1.5.34 4/2/94
- - fixed bug in client that meant it couldn't get/put files from WfWg
- - fixed a bug in the server that caused lpr to return -1 under sunos
- - fixed a few errors in the hosts allow section of the
- smb.conf.5 manual page and added examples
-
-1.5.35 6/2/1994
- - minor bugfix in reduce_name().
- - changed width of "size" in client during a dir
- - patches for NEXT (among other things) from lendecke@namu01.gwdg.de
- - added -a switch to server, and made default action to append
- to log file
- - added deadtime options to [global] section for timing out
- dead connections to the smbd.
- - HPUX changes from Pasi.Kaara@atk.tpo.fi
- - made use of unsigned char more consistent
- - changed the way of getting the default username and host in the
- client
- - made LANMAN1 default to on in the client, off in server.
- Use -DLANMAN1=1 to make it on in both.
- - lots of casts and cleanups for various operating systems
- - changes to the Makefile from Karl to auto-instal the man pages
- - added a short history of the project to the distribution
-
-1.5.36 15/2/94
- - fixed minor bug in Debug() (thanks to Pasi.Kaara@atk.tpo.fi)
- - fixed bug in server.c so -a wasn't accepted.
- - minor fixes to the client
- - added hosts file to name server (-H option)
- - added -G option for groups to nameserver
- - cleanups and additions from Jeremy Allison, taking us
- closer to LANMAN1.0. In particular the locking code was cleaned up
- considerably.
-
-1.5.37 16/2/94
- - fixed bug introduced in 1.5.36 which disabled SMBcreate
-
-1.5.38 18/2/94
- - fixed get_broadcast() for ultrix (fix from iversen@dsfys1.fi.uib.no)
- - added automatic group registration
- - fixed bug in registration code
- - made nmbd work better with WfWg, and probably others
- - updated the man pages to include the new nmbd options.
- - minor updates to the README
- - fixed double log_out() in send_packet().
- - fixed bug in smbclient so that "dir" didn't work correctly
- with pathworks
- - possibly fixed bug in server that led to "abort retry ignore" from
- pathworks client when doing a "dir".
- - changed behaviour of smbclient login slightly, to try a
- blank password in SMBtcon if the right password fails, and a
- session setup has succeeded. Some clients seem to use a blank
- one if a session setup has succeeded.
- - ISC patches from imb@asstdc.scgt.oz.au
- - the client now tries to do name registration using a unicast.
- Let me know if this helps anyone.
- - tried to add a "contributed" line to each OS in the Makefile.
-
-1.5.39 18/2/94
- - fixed silly C code that only worked with some compilers
- - fixed another silly bug in nameserv.c that caused it to seg fault
-
-1.5.40 21/2/94
- - removed the from (IP) message so people don't worry about 0.0.0.0,
- it's redundant anyway.
- - changed the client so the crypt key isn't printed
- - changed the structure of switch_message() to use a list of functions.
- This improves the debug info.
- - made SMBopen ignore supplied attribute as per X/Open spec
- - made SMBopen fail if file doesn't exist in all cases. Let me know
- if this breaks something. It is implied in the X/Open spec. This
- fixes the pkzip bug.
- - added dptr_demote() to replace dptr_close() to try and fix
- pathworks dir bug. This has the potential disadvantage of
- leaving lots of open file descriptors.
- - changed mask_match to disallow two .s in a name
-
-1.5.41 2/3/94
- - added "dfree command" global option to smbd to support an
- external "disk free" executable (typically a script). This gets
- around the problem of getting disk free info reliably on lots
- of systems.
- - added ffirst and fclose to client
- - simple SYSVR4 patch from mark@scot1.ucsalf.ac.uk
- - added better uid/gid reporting for debugging purposes
- - several changes to the logon procedure for the client, so hopefully
- it will connect correctly to a wider range of servers.
- - server should no longer crash if it can't open the debug
- file (thanks to MGK@newton.npl.co.uk)
- - added the THANKS file.
-
-1.5.42 6/3/94
- - lots of changes from Jeremy Allison, implementing more of
- the LANMAN1.0 protocol, and fixing a few bugs.
- - fixed delete bug, so hopefully wildcards are correct now
- - pcap changes from Martin Kiff so non-aliased printers in
- /etc/printcap are recognised
- - wrote announce file ready for 1.6
- - re-wrote browse code in client (still doesn't work)
- - updates to man-pages from Karl Auer
- - made raw packet dumps mode 0600 and only if -dA is given
- - changed socket code to use utility functions in util.c
-
-1.6.00 17/3/94
- - made server always return to original directory (rather than /)
- - fixed bug in params.c that caused a seg fault if no parms in a
- section
- - minor clean ups for clean compile under solaris
- - solaris fix for running from inetd from Karl Auer
- - fixes for dfree() under solaris
- - minor changes that might help BSDI
- - changes to the Makefile, manual-pages and sample config file from
- Karl Auer
- - fixed dfree for Ultrix
-
-1.6.01 19/3/94
- - fixed setatr bug that allowed directories to be unusable
-
-1.6.02 27/3/94
- - added timestamps to connection message in log
- - added idle timeout of 10 minutes to name server
- - made HAVE_SYSCONF==0 the default in includes.h
- - made the client not register by default
- - ISC patches from imb@asstdc.scgt.oz.au
- - GetWd() cache code from Martin Kiff
- - rewrote the locking code in terms of fcntl() calls.
- - fixed "can't delete directory" bug
- - added code to close old dirptrs for duplicate searches
- - removed exchange_uids() and the access() call and replaced them.
-
-1.6.03 28/3/94
- - tried to clean up the time handling a little (local vs gmt time)
- - added debug level global to server config
- - added protocol level global to server config
- - added SMBecho command to server
- - included Karl Auers SMBGuide in the distribution.
-
-1.6.04 31/3/94
- - fixed time zeroing bug in smb_close and smb_setatr
- - re-wrote the username/password handling to be more flexible
- - added "guest only" service setting to smb.conf
- - updated man pages for new username/password handling
- - fixed parse bug in reply_tconX
- - improved error return code from tcon
- - several changes to fix printing from WfWg
-
-1.6.05 2/4/94
- - changed the name of the whole package to Samba
- - removed SMBexit call from client to stop exiting error message
- - added interpret_addr() call to replace inet_addr() so
- a hostname can be used whenever a IP is required
-
-1.6.06 8/4/94
- - added random tid choice to reduce problem of clients not
- detecting a server disconnection.
- - made client not report spurious time from CORE or COREPLUS server.
- - minor HPUX fix from gunjkoa@dep.sa.gov.au
- - turned off GETWD_CACHE until we track down a minor bug in it
-
-1.6.07: 10/4/94
- - added helpful error messages to connection failure in client.
- - fixed problem with mput in client
- - changed server to allow guest-only sesssetup messages with any
- password. Control this with GUEST_SESSION_SETUP in local.h.
- - minor change to session setup handling in make_connection()
- - added check for right number of \s in the client.
- - made the server not exit on last close if the deadtime is != 0
- - added malloc and realloc wrappers. enable them with -DWRAP_MALLOC=1
- - if smbd is started with a debug level of 10 or greater it creates
- a log file ending in the process number
-
-1.6.08: 18/4/94
- - updated the THANKS file
- - changes from marcel@fanout.et.tudelft.nl (Marcel Mol) for AMPM
- times and error report on connect().
- - made the get_myname() routine discard any part after the first '.'
- - added a wrapper for free from Martin Kiff
- - added simpleminded code to handle trapdoor uid systems (untested)
- - added Martin Kiffs "paranoid" getwd code.
- - added default MAXPATHLEN if undefined of 1024
- - made get_broadcast() continue to get netmask if it can't get
- broadcast (suggestion from Hannu Martikk)
- - replaced fchmod() calls with chmod() to satisfy some unixes
-
-
-
-1.6.09: 4/5/94
- - changed perror() calls to strerror() in server.c
- - fix for dfree on OSF1 from
- Maximilian Errath (errath@balu.kfunigraz.ac.at)
- - fixed server time reporting for protocol >= LANMAN1
- - fixed TimeDiff() for machines without TIMEZONE or TIMELOCAL
- (thanks to Vesa S{rkel{ <vesku@rankki.kcl.fi>)
- - added SYSV defs to AIX and HPUX to fix "memory" problem
- (actually a signal problem).
- - added version to client banner in log file
- - Ultrix patches from Vesa S{rkel{ <vesku@rankki.kcl.fi>
- - added ! command to client for executing shell commands
- - fixed ERRnofids bug in server
- - fixed name_equal bug
- (thanks to cjkiick@flinx.b11.ingr.com (Chris Kiick))
- - wrapped gethostbyname() with Get_Hostbyname() to prevent
- case sensitive problems on name lookups
- - limit printer tmp filename to 14 chars
- (from Paul Thomas Mahoney <ptm@xact1.xact.com>)
- - added ability to understand 64 bit file times
- (thanks to davidb@ndl.co.uk (David Boreham))
- - added Gwt_Pwnam() wrapper to cover server case-sensitivity
- problems (suggestion from J.M.OConnor@massey.ac.nz (John O'Connor))
- - changed the setuid() calls to try and work for more systems
- without breaking the ones it currently works for
- - added version number to usage()
- (suggestion from peter@prospect.anprod.csiro.au)
- - added "security=" option for share or user level security
- - allowed multiple usernames in "user=" field
- - changed display method for recursive dorectory listings
- - switched client to use long filenames where supported
- - added speed reporting to client transfers
- - several NT fixes to server from jra@vantive.com (Jeremy Allison)
- - ISC fixes from ptm@xact.demon.co.uk (Paul Mahoney)
- - fix to README from grif@cs.ucr.edu (Michael A. Griffith)
- - default netmask and broadcast from Ian A Young <iay@threel.co.uk>
- - changed default of is_locked() on fcntl() error.
- - fixed bug in read_with_timeout() that could cause a runaway
- smbd process.
- - fixed findnext bug for long filenames in client
- - changed default protocol level to LANMAN1
- - change default reported security level to SHARE.
- - changed password_ok() so that if pwdauth() fails it tries
- with standard crypt.
- - added "translate" command to the client to do CR/LF translation
- for printing, and add a form feed at the end.
- (thanks to mh2620@sarek.sbc.com (Mark A. Horstman ) )
- - added "locking=yes/no" toggle for each service
- - SCO unix patches from Heinz Mauelshagen (mauelsha@ez.da.telekom.de)
-
-1.6.10: 7/5/94
- - fixed important bug in readbraw/writebraw
- - added -A option to client
- - fixed delete bug on long filenames (untested). Thanks to
- Stefan Wessels <SWESSELS@dos-lan.cs.up.ac.za>
- - neatened up the byte swapping code
-
-1.6.11: 3/6/94
- - fixed bug in client in receive_trans2_response() that caused
- some strange behaviour with LANMAN2.
- - fixed some offset/alignment problems with lockingX (thanks to
- Jeremy Allison)
- - allow locking on O_RDONLY files. Thanks to Martin N Dey <mnd@netmgrs.co.uk>
- - fixed del bug in client thanks to paulzn@olivetti.nl (Paul van der Zwan)
- - fixed multiple user= bug thanks to MDGrosen@spectron.COM (Mark Grosen)
- - added translate ability for all files. Thanks to mh2620@sarek.sbc.com (Mark A. Horstman )
- - mask out negative lock offsets. Thanks to bgm@atml.co.uk (Barry G Merrick)
- - more attempts to get the structure alignment better for some machines
- - cleaned up the machine dependencies a little
- - ISC fixes from Paul Thomas Mahoney <ptm@xact1.xact.com>
- - enabled printing with a SMBclose and SMBwrite for NT
- thanks to jkf@frisky.Franz.COM (Sean Foderaro)
- - SGI changes from Michael Chua <lpc@solomon.technet.sg>
- - CLIX patches from cjkiick@ingr.com
- - NEXT2 and NEXT3_0 patches from Brad Greer (brad@cac.washington.edu)
- - BSDI changes from tomh@metrics.com (Tom Haapanen)
- - SCO patches from John Owens (john@micros.com)
- - fix psz bug in pcap.c (thanks to Karl Auer)
- - added widelinks option (global and per service). Suggestion from
- Karl Auer. Defaults to True.
- - made locking able to be global or local (default is give by global)
- - added check_name() to dir listings
- - added "packet size" option to globals. default to 32767. This
- "fixes" a WfWg bug (thanks to Karl Auer)
- - fixes for getattrE and setattrE and minor fix in util.c from Jeremy Allison.
- - Karl updated the man pages o be current
- - disabled writebraw and readbraw until a possible bug can be investigated further
-
-1.7.00: 14/7/94
- - added session_users list, to overcome problem of missing usernames in SMBTconX.
- - added term support to the client
- - added "default service"
- - fork for print so user is not root
- - added name mangling to 8.3 (rudimentary)
- - fixed bug in in_group()
- - changed to use gid in place of egid
- - fixed client connection to OS/2 (1.3 + lanman2.2) and long filenames
- - added patches from mcochran@wellfeet.com (Marc Cochran)
- these implement scope ids and fix some udp bugs. It means
- the -L option to nmbd now works.
- - made nmbd respond to incoming port rather than only 137
- - made wide links refuse .. components
- - fixed "dir foo." bug to stop it showing "foo.???"
- - improved name mangling (added stack)
- - added valid FNUM check to most calls
- - fixed important do_put bug in the client
- - added magic scripts to the server
- - re-enabled getwd_cache code
- - added optional agressive password checking
- - removed dptr_closepath from SMBsearch to try and stop "dos for loop"
- bug
- - DGUX patches from ross@augie.insci.com (ross andrus)
- - updated the README and THANKS file.
- - added node status request to -L option of nmbd
- - stripped trailing spaces in mask_match() (thanks to mike hench hench@cae.uwm.edu)
- - added COREPLUS style print queue reporting and "lpq command"
- in globals.
- - cleaned up date handling and fixed byte order dependancy on dates
- in SMBgetattrE.
- - cleaned up the password handling and added "password level" with
- the possability of checking all case combinations up to N upper
- case chars.
- - changed to use recvfrom only on udp ports (fixed read raw!)
- - added TCB password support for SCO (thanks to lance@fox.com)
- - updated README, THANKS and announce files.
- - fixed timezone reporting to be signed (thanks to noses@oink.rhein.de)
- - disabled max packet as it could cause problems with WfWg (no longer
- needed now readraw is "fixed")
- - changed from creat() to open() in mktemp and mknew.
- - changed umask handling
- - sped up nmbd by making it cache names
- - changed idle timeout on nmbd to 2 mins
- - Netbsd changes from noses@oink.rhein.de
- - released alpha2
- - added name timeout to nmbd
- - changed bind port retry in nmbd
- - added Limitations sections to README
- - fixed two . in is_83()
- - fixed compilations warnings in util.c (thanks to njw@cpsg.com.au)
- - made [homes] honour multiple user list
- - fixed mask match bug introduced in alpha1
- - added "mangled stack" option for stack size
- - added mangled stack promotion
- - released alpha3
- - netbsd-1.0 fix for statfs().
- - added null_string to util.c to reduce memory usage
- - changed the way directory structures are put together
- - added smbrun for system() requests
- - changed maxmux to 0 in hope of avoiding mpx commands problem
- - fixed zero response length for session keepalives
- - removed called name from session users list
- - added F_RDLCK support to try and handle locks on readonly files
- - made directory creation honour the lowercase flag in client (thanks
- to charlie@edina.demon.co.uk)
- - made checksum for mangling independant of extension if extension is
- lowercase
- - added ability to rename files with different extension, preserving
- root name
- - released alpha4
- - better command line error checking in client
- - changed all debug statements to new format
- - fixed delete error code reporting
- - released alpha5
- - added mangled name support to wildcard delete in server
- - fixed mask bug in SMBsearch
- - cleaned up prototypes
- - released alpha6
- - fixed important bug in session_setup which made WfWg freeze
- (maxmux was 0 - this bug was introduced in alpha4)
- - released alpha7
- - two printing bug fixes thanks to bgm@atml.co.uk (Barry G Merrick)
- - uid fix to smbrun (thanks to larry@witch.mitra.com)
- - man page updates from Karl Auer
- - FAQ file from Karl Auer
- - released alpha8
- - fixed read-only flag in dos_mode() for non writeable services
- - fixed error code reporting in open() and openX().
- - minor secureware fix from (thanks to lance@fox.com)
- - released alpha9
- - casting cleanups for memcpy().
- - cleaned up error code names to be more consistant
-
-1.7.01: 17/7/94
- - minor man page fix from baeder@cadence.com (Scott Baeder)
- - changed usage() error message in client
- - made nmbd not exit if can't register own name
- - made nmbd only register if running as a daemon
- - fixed stdout problem in smbrun by closing stdin/stdout/stderr
- - minor fix to lmhosts parsing
-
-
-1.7.02: 20/7/94
- - made nmbd not call get_broadcast if both -B and -N are used (thanks
- to Chris Woodrow <Chris.Woodrow@actrix.gen.nz>)
- - disabled GETWD_CACHE again
- - fixed INCLUDES list in Makefile to add version.h (thanks to
- jimw@PE-Nelson.COM (Jim Watt))
- - made checkname do a become user if it hasn't already done so.
- - added consistancy check to become_user().
- - removed mask extension expansion from SMBsearch
- - small change to chkpth
- - fix to snum select for lpq status (thanks to Rafi Sadowsky
- rafi@tavor.openu.ac.il)
- - changed daemon to is_daemon for NetBSD (thanks to noses@oink.rhein.de)
- - removed STAFS3 stuff for NETBSD_1_0
-
-
-1.7.03: 29/7/94
- - updated docs for new distribution structure
- - made getatr return 0 size for directories (thanks to Bernd Esser
- esser@pib1.physik.uni-bonn.de)
- - added valid dos filename checks from Stefan Wessels
- (swessels@cs.up.ac.za)
- - added trimming of . in hostnames to -S mode of nmbd
- - removed become_user() and OPEN_CNUM calls. Now make them
- in switch_message instead which simplifies a lot of code.
- - added GETFNUM macro to make chain_fnum more consistant and
- reliable.
- - added flags to protocol structures to simplify CAN_WRITE and AS_USER
- checking
- - added getwd cache boolean option to globals
- - added fclose() to lpq status routine thanks to
- dgb900@durras.anu.edu.au (David Baldwin)
- - added "only user" option, to limit connection usernames to those
- in the user= line
- - changed to badpath from badfile in chkpath despite specs (following
- what WfWg does). This fixes "file not found" error in copy command.
- Thanks to rwa@aber.ac.uk for pointing out the bug
- - changes for apollo from Stephen C. Steel <steve@qv3donald.LeidenUniv.nl>
- - more changes for Apollo from jmi@csd.cri.dk (John Mills)
- - released alpha release
- - added FTRUNCATE_CAN_EXTEND=0 as default to fix problem with word6.
- Possibly not needed on many OSes? Thanks to Charlie Hussey
- charlie@edina.demon.co.uk
- - started adding max connections code
- - much improved group handling contributed by
- Ian Heath (ih@ecs.soton.ac.uk)
-
-1.7.04: 29/7/94
- - fixed one line bug in SMBopenX that got error code wrong.
-
-1.7.05: 2/8/94
- - added UNIXERROR() macro to get error code from unix errno.
- - fixed lpq status for MSTCPB3
- - added @ option for user= line to lookup groups in group file
- - added become_user optimisation and process timeout (thanks to
- Jeanette Pauline Middelink (middelin@calvin.iaf.nl)
- - added malloc optimisation in readbraw
- - released alpha
- - patches for OSF1 enhanced security from Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - made level 2 a more useful debug level (less guff)
- - added "max connections" and "lock dir" options to allow
- limiting of the number of connections to a service at one time.
- - released alpha2
- - updated man pages
- - released alpha3
- - added read prediction code for better read performance
- - released alpha4
- - minor tuning to receive_smb()
- - changed the order of mangled stack checking
- - bug fix in read_predict().
- - released alpha5
- - minor search optimisation
- - fixed keep alive bug in writebraw and in readbraw in the client
- - released alpha6
- - disabled writeraw by default pending a bug fix
- - added profiling code (off by default)
- - minor delete tuning
-
-
-1.7.06: 4/8/94
- - OSF1 crypt fix thanks to Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - ifdef'd EDQUOT in case you don't have it (thanks to Paul Blackman <ictinus@Lake.canberra.edu.au>)
- - tidied up UNIXERROR stuff to work on more systems.
- - made Makefile more sophisticated and added "make revert"
-
-1.7.07: 4/8/94
- - fixed one line fatal bug in receive_smb. Thanks to bruce@pixar.com
-
-1.7.08: 2/9/94
- - initgroups call for SCO from lance@fox.com
- - code cleanups from cap@isac.hces.com (Simon Casady)
- - use full pathname in print command construction
- - ISC includes fix from Martin Tomes <mt00@ecl.etherm.co.uk>
- - added GID_TYPE define to cope with ultrix. Thanks to
- brad@cac.washington.edu
- - added umask call to main in server
- - fixed several minor problems with the max connections
- code. Thanks to lehmann@klizix.mpi-stuttgart.mpg.de (Arno Lehmann).
- - fixed filetime in writeclose. Thanks to Andreas Bahrdt
- <100321.2431@compuserve.com>
- - df fix for large disks from Andreas Bahrdt
- - getpwanam support from horn@mickey.jsc.nasa.gov
- - clean name change from Bernd Esser
- <be@syli30.physik.uni-bonn.de>
- - released alpha1
- - more locking changes to fix Excel problem
- - released alpha3
- - another minor locking change
- - smarter masking in the locking code. Excel now apparently works.
- - minor FAQ updates
- - changed max connections refusal error to access denied.
- - added queue command to client to show the print queue
- - changed some print queue reporting stuff
-
-1.8.0: 14/10/94
- - added international chars to valid_dos_char(). Thanks
- to Daniel.Grandjean@dgr.epfl.ch
- - volume label fix
- - released alpha1
- - important off by 4 fix in the server
- - readbraw size adaption in the client
- - released alpha2
- - wait3 cast for NeXt fixed. Thanks to dbrandon@politics.tamu.edu.
- - man page fix for max xmit. Thanks to mmoore@wexford (Mike Moore)
- - is_8_3() fixes from Jochen Roderburg <Roderburg@rrz.Uni-Koeln.DE>
- - list_match() fix from jkf@soton.ac.uk
- - statfs3 fix for BSDI from dan@supra.com
- - changed file open/close/read in server in preparation for mmap()
- based IO.
- - added mmap() support for reading files in the server. Optional
- at compile time. Thanks to suggestion from Roger Binns <rogerb@x.co.uk>
- - mmap bug fixes
- - added __SAMBA__ name in nmbd
- - major changes for support of lanman2 and long filenames from
- Jeremy Allison (jeremy@netcom.com)
- - lseek optimisation. Thanks to Linus Torvalds.
- - released alpha4
- - date patches for lanman2 from Jeremy Allison
- - added protocol aliases to handle WfWg (untested)
- - allow for zero params or data in reply_trans2
- - small lanman2 patches from jeremy
- - more prototype additions for clean compilation
- - postscript patches from tim@fsg.com
- - more lanman2 patches from Jeremy
- - added null ioctl support
- - kanji patches from fujita@ainix.isac.co.jp
- - released alpha6
- - disallowed null password access (thanks to Birger Kraegelin krg@iitb.fhg.de)
- - Makefile fix for ultrix from andrew@d2bsys.demon.co.uk (Andrew Stirling)
- - added per-service mangled names
- - totally re-vamped loadparm.c
- - added "mangling char" parameter
- - released alpha7
- - added "default case = lower|upper" service option
- - change mangling char to a service parameter
- - ultrix enhanced security patch from steven@gopher.dosli.govt.nz
- - more changes to loadparm.c
- - printer name always set in [printers]
- - string_free() fix thanks to jef_iwaniw@pts.mot.com
- - changed group handling to be faster and work for large numbers
- of groups
- - added dynamic gid_t type determination
- - released alpha8
- - fixed become_user() problem for services with invalid
- directories
- - added "invalid users" list on per service basis
- - fixed pointer problems in alpha8 (thanks to murnaghant@a1uproar.yuppy.rdgmts.MTS.dec.com)
- - fixed some date setting problems
- - trans2 fixes from jeremy to stop infinite directory listings of
- long filenames
- - "standard input" lpq patch from root@tlspu.demon.co.uk (Adrian Hungate)
- - changed password checking to check session list and validated ids
- before user list
- - split off password functions into password.c
- - added hosts equiv and rhosts code (thanks to Tim Murnaghan <murnaghant@a1uproar.yuppy.hhl.MTS.dec.com>)
- - released alpha11
- - added "newer" command to the client
- - attempt at aix trapdoor uid workaround
- - released alpha12
- - minor trans2 bugfix
- - added ufc crypt (fast crypt) support. Thanks to suggestion from
- forrest d whitcher <fw@world.std.com>
- - socket() fix for getting bcast and netmask thanks to
- Brian.Onn@Canada.Sun.COM
- - added beginnings of IPC and named pipe support in the server
- - changed file structure a bit, creating reply.c
- - finished print queue support for lanman1
- - changed default protocol to LANMAN2
- - released alpha13
- - logged IPC connects at a higher debug level
- - added netgroup support to hosts equiv search
- - disallowed root access though hosts.equiv (thanks to Colin.Dean@Smallworld.co.uk)
- - kanji and password handling fixes from fujita@ainix.isac.co.jp
- - several bug fixes for lanman and other things from
- esser@pib1.physik.uni-bonn.de (Bernd Esser)
- - updated man pages, README and announce files.
- - released 1.8.00alpha1
- - reply_close() time change fix from Andreas Bahrdt <100321.2431@compuserve.com>
- - added valid users list to compliment invalid users list.
- - aix fixes from tomc@osi.curtin.edu.au (Tom Crawley)
- - changed testparm output format
- - support for getting time from the server (nearly untested)
- - fixed device type error for wild device ????
- - fixed groups problem when in 0 groups
- - more IPC fixups
- - added support for "net view \\server" command to list
- available services (like browsing)
- - released 1.8.00alpha2
- - changed port choice for nmbd -L
- - added -L option to client to view share list on a host
- - bug fixes for NetShareEnum code
- - added "server string" option
- - changed default print file name to include remote machine name.
- - added hooks for browsing in nmbd
- - added browsing to nmbd
- - freebsd fixed from Steve Sims SimsS@Infi.Net
- - got rid of tell()
- - added subnet browsing with the S option in lmhosts
- - made smbd prime nmbd with a 1 byte dgram
- - added REUSADDR to open_socket_in() thanks to peter@ifm.liu.se
-
-
-1.8.01: 18/10/94
-
- - auto add group "LANGROUP" if no group specified in nmbd
- - made nmbd more responsive at startup
- - lots of cleanups and consistancy checks
- - added -C option to nmbd to set "machine comment".
- - fixed postscript option
- - force print_file in print_open()
- - restructured the browsing a little
- - casesignames fix for lanman-dos
- - auto-load home directory from session setup
- - changed to StrnCpy() for safety
- - fixed "out of file descriptors" bug in the client (a WfWg bug?)
-
-
-1.8.02: 22/10/94
- - fixed uppercase username problem
- - added "hide dot files" option
- - changed auto debug log in nmbd
- - added LMHOSTS to Makefile
- - added M flag in lmhosts to specify own netbios name
- - added "load printers" option to auto-load all printers
- - substitution of %p in lpq command
- - substitution of %h and %v in server string and -C option of
- nmbd
- - string substitions substitute all occurances of a pattern
- - added casesignames global option
- - fix for man pages thanks to David Gardiner <dgardine@cssip.edu.au>
- - changed debug options a bit
- - added default for lpq command and lpr command
- - changed default shell path to /bin/sh
- - forced lpq under api to run as root - should speed things up
- - added "group" option to force group of a connection
- - added "read list" and "write list" options
- - added max mux option - seems to fix NT browsing?
- - added "mangled map" option thanks to
- Martin.Tomes@uk.co.eurotherm.controls
- - separated mangling functions into mangle.c
- - allowed all dos chars in mangled names
- - apollo changes from Helmut Buchsbaum <buc@eze22.siemens.co.at>
- - password changing code from Bob Nance <Bob.Nance@niehs.nih.gov>
- it doesn't quite work yet, but it's a start (disabled by default)
-
-
-1.8.03: 25/10/94
- - made auto loaded services browsable as per default service
- so you can hide homes but keep home directories.
- - changed check_name() to handle "direct to network" printing
- - auto 3 minute deadtime if all connections are closed. This
- prevents restart when polling the print queue.
- - fix for newer command in client from Rich-Hoesly@uai.com
- - changed connection recording method
- - added the program smbstatus
- - changed timeout mechanism
- - "null passwords" option from Pim Zandbergen <pim@cti-software.nl>
- - made new files with casesignames=False set their case to the default
- case.
- - fixed problem of uppercasing first letter of printers in printcap
- - debug level fixes in trans2 from jimw@PE-Nelson.COM (Jim Watt)
- - made null printer default to lp
-
-1.8.04: 27/10/94
- - added OS2.txt from riiber@oslonett.no
- - another "auto services" fix. A silly strtok() bug :-(
- - fixed the status locking and max connections (broken in 1.8.03)
- - released alpha1
- - added gets_slash so lines can be continued in smb.conf and
- lmhosts
- - browse list bugfix
- - default to "load printers=yes"
- - rewrote pcap.c
- - intergraph bugfix from tarjeij@ulrik.uio.no
- - changed properties flags in nmbd (to fix NT print browsing)
- - allowed very long lines in printcap parsing.
-
-1.8.05: 28/10/94
- - lanman2 fix from Jeremy
-
-1.9.00: 22/1/95
- - only add home if not already there.
- - added ulogoffX support
- - PTR_DIFF() cleanups
- - fixed a bug that caused STATUS..LCK to grow very large
- - changed mangling to handle names ending in . a little better
- - added "strip dot" option
- - SGI and setgroups() fix from bill@sg25.npt.nuwc.navy.mil
- - fixed password preservation in password_ok() (again?)
- - unink fix from emer@vssad.enet.dec.com (Joel S. Emer)
- - changed username part of spool filename to max 10 chars (from 6)
- - magic script fix from beverly@datacube.com (Beverly Brown)
- - reply_special() fix from Peter Brouwer <pb@apd.dec.com>
- - stopped nmbd from listening on 138. It didn't seem to help much.
- - clix fixes from ttj@sknsws61.sjo.statkart.no
- - fixed select behaviour under Linux
- - man page fix from Robin Cutshaw <robin@intercore.com>
- - ISC block size fix from ralf@rbsoft.sdata.de (Ralf Beck)
- - ISC fixes from Martin.Tomes@controls.eurotherm.co.uk
- - attrib bit fix in smbclient (pointed out by Rich-Hoesly@uai.com)
- - japanese extensions from fujita@ainix.isac.co.jp (Takashi
- Fujita) and ouki@gssm.otuska.tsukuba.ac.jp.
- - SCO patches from Stephen.Rothwell@pd.necisa.oz.au
- - changed the system commands to redirect stderr
- - changed default printername to service name for all print ops
- - added ability to delete print queue entries
- - added warning if you try to print without -P in smbclient
- - INTERACTIVE patches from cardinal@settimo.italtel.it
- - patch to handle spaces in group names from GJC@vax1.village.com
- (GEORGE J. CARRETTE)
- - lockingX fix from stefank@esi.COM.AU (Stefan Kjellberg)
- - some fairly radical changes to filename handling. We can now
- handle mixed case filenames properly
- - released alpha2
- - added sysv printing support and improved bsd support
- - changed the user that does print queues and lprm jobs
- - return code support in the client from doylen@nbslib.isc-br.com (Doyle Nickless)
- - added "strict locking" option. Defaults to no.
-
- - added -I switch to nmbd
- - fixed DEV bug thanks to Dirk.DeWachter@rug.ac.be
- - use pw_encrypt() for shadow passords in Linux (from begemot@begemot.iko.kharkov.ua (Dmitry Gorodchanin))
- - disabled read prediction by default
- - added varient handling code to ipc.c for printQ and printDel.
- - released alpha5
- - AUX patches from root@dolphin.csudh.edu
- - struct timeval fix from gkb1@york.ac.uk
- - patches to merge ISC and INTERACTIVE from pim@cti-software.nl
- - changed to "printing ="
- - fixed problem with long print queues.
- - fixed node status request in nmbd to go to non bcast
- - made default path in services /tmp if not specified
- - added %u in passwd program
- - fixed up the password changing code for Linux
- - no guest sess setup when user level security
- - changed timeouts to kill dirptrs so cdroms can be unmounted
- - added auto-reload of smb.conf if changed
- - added SIGHUP to reload the config files
- - added -M option to nmbd to search for a master browser
- - added support for continue bit in trans2findnext
- - changed to dynamic strings in some more structures
- - changed default deadtime to 30 minutes
- - cleaned up the memory swapping code a bit
- - updated the man pages somewhat
- - added %m and %u in the "path=" of services
- - released alpha6
- - simple testing and fixups for solaris, sunos, aix, ultrix and
- osf/1 (this is all I have access to).
- - fixed chdir bug
- - added hashing to cnum selection
- - released alpha7
- - fixed printing bug
- - reduced chance of "hung" smbd with dead client
- - fixed do_match() bug (recently introduced)
- - released alpha8
- - nameserver fix from W.J.M.vGeest@et.tudelft.nl (W.J.M. van Geest)
- - rewrote readbraw to try and overlap reads with writes
- - client optimisations
- - rewrote getwd cache and enabled it by default
- - added partial smb packet reads (hopefully faster writes)
- - added log file and log level options (with subs)
- - added "read size" option
- - tried setting some more socket options
- - can use subs in "config file=" and will auto-reload
- - added "include" options, with some subs
- - finally got print manager working with NT
- - auto-respond in nmbd to non-broadcast (auto WINS server, no -A
- needed)
- - released alpha10
- - auto-delet unused services when reloading
- - fixed auto-deletion
- - fixed long names in printing
- - fixed double loading of services file
- - added printer file name support
- - reformatted man pages for better www conversion
- - renamed to 1.9.00.
- - added support for RNetServerGetInfo and NetWkstaGetInfo API's
- - updated the docs a bit
- - released alpha1
- - added -M -
- - changed nmbd announce interval to 10 mins in outgoing packets
- - hopefully fixed idle timeout reconnects
- - strupper all command lines in nmbd
- - added %a substitution for "remote architecture"
- - added "Samba" protocol (same as lanman2)
- - added "security = SERVER"
- - released alpha2
- - lowercase password fix
- - fixed connect path length bug (thanks to JOHN YTSENG
- <jtseng@cory.EECS.Berkeley.EDU>)
- - added subs on "password server".
- - fixed printing filename bug from smbclient
- - disk quotas and hpux printing support from Dirk.DeWachter@rug.ac.be
- - Makefile patches from pappinm@ayr_srv2.nth.dpi.qld.gov.au
- - AFS patches from Mike Allard (mgrmja@nextwork.rose-hulman.edu)
- - fixed grp name = server name problem
- - man page updates from Charlie Brady (charlieb@budge.apana.org.au)
- - fixed file search bug by adding "finished" flag
- - added "max log size". Suggestion from Mark Hastings <mark.hastings@gain.com>
- - released alpha3
- - changed the read/write routines to handle partial read/writes
- - released alpha4
- - changed "guest account" to per-service
- - changed so "guest ok" allows access to the guest account,
- not the "user=" line
- - changed default readsize to 2048
- - try bind to 137 in nmbd if possible
- - added server lookup to -L option in smbclient (gets list of servers)
- - added -M switch to smbclient for sending winpopup messages
- - released alpha5
- - FAQ updates from Paul Blackman ictinus@lake.canberra.edu.au
-
-1.9.01: 23/1/95
- - changed comment in print Q info to service rather than server comment
- - fixed smbclient -L to NT when in user level security mode
- - hopefully finally fixed NT print manager problems
- - added informative messages during smbclient -M
- - added node status replies to nmbd
- - changed the lock offset fixup calculation to be more friendly
- to dumb lockd daemons.
- - added sigbus and sigsegv handlers to catch any silly errors and
- print a message
- - added message receipt to smbd and "message command =" option
-
-1.9.02: 25/1/95
- - added argv/argc mangling for people who start the server the
- wrong way.
- - some man page updates
- - added "revalidate" option
- - added hosts allow/deny access check to messaging access
- - added timeouts in the client
- - added check for existance of smbrun binary
- - man page updates from Colin.Dean@Smallworld.co.uk
- - freebsd patches from dfr@render.com
- - added mask sanity check in SMBsearch
- - added more useful substitutions (%S, %P, %I and %T)
- - added "exec =" option to execute commands on each connection
-
-1.9.03: 13/3/95
- - added "socket options" option
- - close base fd's (0,1 and 2)
- - use dup(0) for inetd operation
- - better detection of is_daemon
- - hopefully finally fixed silly put bug that gave the wrong
- date on files.
- - fixed segv in readbraw bug
- - added improved checing for invalid (or null) print file name
- - several patches from ad@papyrus.hamburg.com (Andreas Degert)
- - fixed slow logout bug in smbclient
- - fixed automounter problems
- - added subs on lock dir
- - BSDI patch from John.Terpstra@Aquasoft.com.au
- - added separate nmb and smb logfile entries in the Makefile
- - fixed return code error in open calls
- - added simple status display of printer in lpq parsing
- - rewrote the directory handling to avoid seekdir (added dir.c)
- - added uid=65535 check (thanks to grant@gear.torque.net)
- - enhanced transfer_file() to add header (used in readbraw)
- - reply_special bugfix from ferret@pc8871.seqeb.gov.au
- - added HAVE_PATHCONF
- - RiscIX patches from Jim Barry <jim@ilp.com> and
- Charles Gay-Jones <charlie@ilp.com>
- - CLIX patches from ttj@sknsws61.sjo.statkart.no
- - fixed aix lpq parser from kvintus@acd.com
- - added substitutions to "include="
- - M88K_S3 patches from tonyb@plaza.ds.adp.com (Tony D. Birnseth)
- - fixed mangled stack problem
- - added code to handle broken readdir() setups on solaris
- - initgroups() fix from jarit@to.icl.fi
- - dgux dfree fix from listwork@cloud9.net
- - dnix support from Peter Olsson <pol@leissner.se>
- - getgrgid() patch from tpg@bailey.com (Tom Gall)
- - Makefile patch from obrien@Sea.Legent.com (David O'Brien)
- - password changing fixes from Dirk.DeWachter@rug.ac.be
- - minor man page updates
- - tried to enhance the read prediction code a little bit
-
-1.9.04: 16/3/95
- - a bit better handling of global include lists
- - fixed GSTRING bug in loadparm.c (affected "socket options =")
- - fixed broken lpq parsing code (recent bug).
- Thanks to Dirk.DeWachter@rug.ac.be
-
-1.9.05: 20/3/95
- - improved mget in client to take multiple arguments and default
- to *.*
- - socket option fixes for both nmbd and smbd
- - changed the byteorder handling scheme to be more portable (and
- faster)
- - lint cleanups from kast@kcs.planet.net (Robert Kast)
- - added crude segv, sigbus and sighup recovery to nmbd
- - rewrote lanman2_match to be closer to NT and WfWg behaviour
- - Cray support from velo@sesun3.epfl.ch (Martin Ouwehand)
- - "admin users" patch from Tim Leamy <tcleamy@ucdavis.edu>
- - released alpha1
- - added samba.7 man page
- - no chdir when doing non AS_USER protocols
- - become_guest() returns true in trapdoor uid system
- - added more sophisticated segv/sigbus reporting (Linux only)
- - released alpha2
- - minor code cleanups (output of -Wall)
- - smbprint fix from James Dryfoos <dryfoos@ll.mit.edu>
- - improved testparm a little
- - updated INSTALL.txt a little
-
-
-1.9.06: 21/3/95
- - added %S substitution to users, valid users and invalid
- users. This is useful for [homes].
- - split off printing routines into printing.c and more dir
- commands into dir.c
- - postexec patch from jpm@gin.Mens.DE (Jan-Piet Mens)
- - smbstatus updates from jpm@gin.Mens.DE (Jan-Piet Mens)
- - reload sighup after use
- - fixed name ptr offset bug
- - added %f in print commands
- - fixed byte ordering in nmbd which caused browsing to fail in
- 1.9.05
-
-1.9.07: 22/3/95
- - important directory listing fix
- - allowed path= in [homes] section
- - printer status patches from Dirk.DeWachter@rug.ac.be
-
-1.9.08: 24/3/95
- - fixed . and .. in root dir for lanman2
- - better default comment in [homes]
- - added time stamping to directory entries
- - check directory access at connection time
- - rlimit code from loebach@homer.atria.com (Thomas M. Loebach)
- - fixed home dir default comment
- - totally rewrote dptr handling to overcome a persistant bug
- - added [globals] as well as [global]
-
-1.9.09: 30/3/95
- - fixed static string bug in nmbd
- - better null password handling
- - split CFLAGS in Makefile
- - fixed typo in smbclient messaging
- - made home dir not inherit path from [global]
- - standard input printing patch from xiao@ic.ac.uk
- - added O_CREAT to all print opens (bug in Win95)
- - use /proc for process_exists under Linux and solaris
- - fixed another segv problem in readbraw
- - fixed volume label problem
- - lots of changes to try and support the NT1 protocol
- - released alpha1
- - fixed session setup bug with NT in NT1 protocol
- - released alpha2
- - fixed "get" bug in smbclient that affected NT3.5
- - added SO_KEEPALIVE as a default socket option in smbd
- - changed some error codes to match those that NT 3.5 produces
- - updated trans2 with some new calls for Win95 and WinNT (better
- long file support)
- - released alpha3
- - fixed "nmbd -D -b" timeouts
- - added IS_LONG_NAME flag to getattr in NT1
- - added the NT qfileinfo trans2 commands
- - merged qpathinfo with qfileinfo
- - changed idling technique to try and be more friendly to
- clients
- - merged setfileinfo with setpathinfo and updated them with the NT fns
- - improved read prediction a lot
- - added read prediction to readbraw
- - improved fault reporting (last packet dump)
-
-1.9.10: 30/3/95
- - fixed read prediction+readbraw bug for read/write files
-
-1.9.11: 9/4/95
- - fixed trans2 qpathinfo bug
- - fixed bug with % in service name when doing print queue requests
- - default readsize now 16K
- - minor read prediction changes
- - fixed status initialisation in print queue reporting
- - fixed const compile problem for hpux
- - minor SMBread fix from Volker Lendecke <lendecke@namu01.gwdg.de>
- - removed space after -P in print commands (for fussy systems)
- - disabled level2 of setfilepathinfo
- - changed to a single read dir model, saving all dir names in
- the Dir structure
- - disabled NT protocols in the client due to reported problems
- - fixed QUERY_FS_VOLUME_INFO which caused Win95 to hang on drive
- properties
- - minor lseek bug fix
- - fixed up keepalives
- - new timezone handling code (hopefully better!)
- from steve@qv3pluto.LeidenUniv.nl
- - BSDI interface patch from jrb@csi.compuserve.com
- - gettimeofday changes from Roger Binns <rogerb@x.co.uk>
- - added smbrun option
- - added "root preexec" and "root postexec" options
-
-1.9.12: 12/4/95
- - hopefully fixed some recently introduced NT problems
- - fixed a unlink error code problem
- - minor testparm fix
- - fixed silly error messages about comments in config files
- - added "valid chars" option for other languages
-
-1.9.13: 28/4/95
- - patches from David O'Brien (obrien@Sea.Legent.com) improving the
- netgroup suport, and adding the "map archive" option, as well as
- other minor cleanups.
- - tried to add info level 3 and 4 support for OS/2
- - default deadtime set to 0 as in docs
- - cleaned up the trans2 code a little
- - cleaned up the Makefile a little
- - added charset.c and charset.h
- - expanded "valid chars" option to handle case mapping
- - lots of changes to try and get timezones right
- - released alpha1
- - win95 fixups
- - released alpha2
- - added %H substitution (gives home directory)
- - nameserv.c cleanups and minor bug fixes
- - redid the browse hook logic
- - fixed daylight saving time offset for logfile messages
- - added name cacheing to nmbd
- - added send counts to node status in nmbd
- - added STRICT_TIMEZONES compile time option (very computationally
- expensive)
- - removed the partial read code
- - cleaned up the permission checking a lot
- - added share modes (DENY_READ, DENY_WRITE, DENY_ALL, DENY_NONE,
- DENY_FCB and DENY_DOS)
- - added "share modes" option
- - cleaned up the file open calls
- - released alpha4
- - fixed important one line bug in open_file()
- - trans2 client fix from lendecke@namu01.gwdg.de
- - netgroup patche from David O'Brien (obrien@Sea.Legent.com)
- - case sensitive fix from lenneis@statrix2.wu-wien.ac.at (Joerg Lenneis)
- - got long filenames working from Win95 dos prompt
- - added "workgroup=" option
- - added "username map" option including multiple maps, group maps etc
- - fixed password server for NT1 protocol and made it more robust
- - changed unix_mode() to add IWUSR to read-only directories. This
- is much closer to what clients expect.
- - added preservation of unused permission bits when a chmod() is
- called from a client.
- - made static those fns that could be
- - fixed typo in access.c (thanks to Andrew J Cole
- <A.J.Cole@cbl.leeds.ac.uk>)
- - added %d substitution for process id
- (thanks to lenneis@statrix2.wu-wien.ac.at (Joerg Lenneis))
- - changed share error code to ERRbadshare
- - added locked files list to smbstatus if share modes is enabled
- - changed DENY_DOS to allow read by other tasks
- - added shared_pending checks to server
- - preserverd all possible permission bits during a chmod, and
- fixed a trans2 chmod bug
- - open /dev/null to use up first 3 fds, in an attempt to stop rogue
- library routines from causing havoc
- - fixed NT username problem when in server security
- - added "force user" and "force group" options
- - cleaned up some of the IPC calls a bit
- - added writeraw to the client and cleaned up write raw in the server
- - osf1 big-crypt bugfix from Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - hopefully better disk-full checking
- - next uid bugfix from patrick@graphics.cornell.edu
- - changed share modes so lock directory doesn't need to be world
- writeable
- - enabled write-raw by default
- - added server_info() in client
- - added level checks in some ipc calls
- - added defines for the important timeouts in local.h
- - added print queue deletion to smbclient (untested)
- - removed the sysconf() calls
- - optimised writebraw a bit
- - fixed some file deletion problems
- - added total_data check for extended attribs in trans2 (for OS/2)
- - fixed broadcast reply bug in nmbd
- - added careful core dumping code
- - added faster password level searches (suggestion
- by lydick@cvpsun104.csc.ti.com (Dan Lydick))
-
-
-1.9.14: 22/9/95
- - fixed up level 3 and 4 trans2 requests for OS/2
- - minor optimisations in a few places
- - cleaned up the closing of low fds a bit
- - added SO_REUSEADDR to socket as a daemon
- - override aDIR bit for directories in dos_chmod()
- - SGI5 fixes from ymd@biosym.com (Yuri Diomin)
- - bsize sanity check and removed sunos force to 1k
- - force the create mode to be at least 0700
- - SCO and freebsd include changes from Peter Olsson
- <pol@leissner.se>
- - check with FQDN in access.c (thanks to Arne Ansper <arne@ioc.ee>)
- - default broadcast for dnix from Peter Olsson <pol@leissner.se>
- - solaris patches from Ronald Guilmette <rfg@segfault.us.com>
- - added EXDEV handling
- - small AFS Makefile patch from mgrlhc@nextwork.rose-hulman.edu
- - hopefully fixed the Win95 dates to work in other than my
- timezone
- - attempted alignment fixups (to speed up memcpy)
- - added some DCE/DFS support (thanks to Jim Doyle <doyle@oec.com>)
- - added fix so that root doesn't have special privilages to open
- readonly files for writing (but admin users do). This fixes the MS
- office install problem.
- - fixed trans2 response bug in client
- - got dual names working for NT
- - enabled lock_and_read in NT protocol
- - added %L macro for "local machine"
- - changed dfree reporting to use "sectors per unit"
- - fixed "not enough memory" bug in MS print manger by limiting
- share name length in share enum.
- - "short preserve case" option from Rabin Ezra (rabin@acm.org)
- - added archive option to client
- - changed openX in client to be able to open hidden and system files
- - added "sync always" option
- - rewrote writebmpx and readbmpx
- - added auto string_sub_basic to all loadparm strings
- - lots of nmbd fixups (add registration, refresh etc)
- - released alpha1
- - added smbtar patches from Ricky Poulten (poultenr@logica.co.uk)
- - added a lpq cache and the "lpq cache time" option
- - released alpha 2
- - sun includes fix from Kimmo Suominen <kim@deshaw.com>
- - change nmbd -L lookup type to workstation from server
- - added min print space option
- - added user and group names to smbstatus (thanks to
- davide.migliavacca@inferentia.it)
- - fixed %f in print command bug (thanks to huver@amgraf.com)
- - added wildcard support to SMBmv
- - misc patches from David Elm (delm@hookup.net)
- - changed default of "share modes" to yes
- - changed default of "status" to yes
- - aix qconfig parsing from Jean-Pierre.Boulard@univ-rennes1.fr
- - more long_date fixups
- - added wildcards to nmbd
- - extensive changes to ipc.c and miscellaneous other changes
- from ad@papyrus.hamburg.com (Andreas Degert). Should especially
- help OS/2 users
- - added name release to nmbd
- - relesed alpha4
- - fixed "SOLARIS" to SUNOS5 in Makefile
- - several minor fixups to get it to compile on aix, osf1, ultrix,
- solaris and sunos
- - released alpha5
- - minor bug fixes and cleanups in ipc.c
- - fixed "only user" bug
- - changed lpq to report guest queue entries as sesssetup_user to
- allow for deletion by windows
- - released alpha6
- - added __SAMBA__ as type 0 in nmbd (was type 20)
- - fixed null print job bug
- - added 8 char warnings to testparm and smbclient
- - changed to 8 char limit for names in pcap.c
- - added linked list of config files to detect all date changes
- that require a reload
- - simplified pcap guessing heuristics
- - added space trimming to the name mapping
- - updated Get_Pwnam to add allow_change field for username mapping
- - fixed MemMove bug (thanks to mass@tanner.com (Massimo
- Sivilotti))
- - released alpha7
- - rewrote MemMove to be a little more efficient
- - ipc va_arg bug fix from djg@tas.com (Dave Gesswein)
- - added check for illegal chars in long filenames
- - fixed name cache init bug in nmbd
- - Convex patches from Victor Balashov <balashov@cv.jinr.dubna.su>
- - timestring() bugfix from staale@spacetec.no
- - changed %H to give path of forced user if one is set
- - added quoting to smbclient to allow spaces in filenames
- - convex and other patches from Ulrich Hahn
- <ulrich.hahn@zdv.uni-tuebingen.de>
- - released alpha8
- - fixed rename directory bug
- - nmbd wins fix from Maximilian Errath <errath@balu.kfunigraz.ac.at>
- - client and AFS changes + password.c reorganisation + "more" and
- "pwd" commands in client from Todd j. Derr (tjd@smi.med.pitt.edu)
- - fixed several nmbd bugs
- - released alpha9
- - fixed another "cd" bug in smbclient
- - password encryption from Jeremy Allison
- - added "passwd chat" option and chat interpretation code
- - added "smb passwd file" option
- - released alpha10
- - cleaned up chgpasswd.c a little
- - portability changes to the encryption handling code
- - added password encryption to smbclient
- - fixed a share level security encryption bug
- - added "ENCRYPTION.txt" document
- - released alpha11
- - added code to detect a password server loop
- - fixed typo in chkpath in client.c that broken cd (again)
- - LINUX_BIGCRYPT from marsj@ida.liu.se
- - AFS password fixup from jbushey@primenet.com (Jeffrey G. Bushey)
- - iso/8859-1 charcnv patches from Dan.Oscarsson@malmo.trab.se
- - strtok/user_in_list fix from roderich@nodebonn.muc.bmw.de
- - NETGROUP patches from J.W.Schilperoort@research.ptt.nl
- - trim_string patch from J.W.Schilperoort@research.ptt.nl
- - fixed problem with files with no extension getting mixed up
- - ipc bugfix for print job deletion from Rainer Leberle <rleberle@auspex.de>
- - released alpha12
- - pwlen fix in NETGROUP from Andrew J Cole <A.J.Cole@cbl.leeds.ac.uk>
- - lots of uid and encryption changes from Jeremy Allison. WinDD
- should now work.
- - released alpha13
- - fixed max_xmit bug in client
- - select fix in server (fixed critical drive errors under ISC)
- - released alpha14
- - wildcard fix from Jeremy
- - changes to make IPC code more robust
- - small select loop change to reduce cleaning of share files
- - vtp, altos and mktime patches from Christian A. Lademann
- <cal@zls.com>
- - EEXIST bugfix in server.c
- - changed mangled map to apply in all cases
- - released alpha15
- - fixed fcb open permissions (should mean apps know when a file is
- read only)
- - released alpha16
- - client help formatting fix and docs fix from Peter Jones
- <thanatos@drealm.org>
- - added a directory cache
- - use /proc whenever possible for pid detection
- - TCSANOW fix in getsmbpasswd from roderich@nodebonn.muc.bmw.de
- - fixed default printing mode for sysv systems
- - make client always expand mask
- - more minor IPC fixups
- - pyramid makefile entry from jeffrey@itm.org
- - client fixups for passlen, maxvcs and session redirect from
- Charles Hoch <hoch@hplcgh.hpl.hp.com>
- - finally fixed important IPC bug (varargs bug with int16)
- - quota patches from Dirk.DeWachter@rug.ac.be
- - print queue cache changes (per service) and print queue priority
- additions from Dirk.DeWachter@rug.ac.be
- - new japanese patches (incomplete) from
- fujita@ainix.isac.co.jp (Takashi Fujita)
- - moved a lot more functions into system.c via wrappers
- - changed a lot of the connection refused error codes to be more
- informative (or at least different)
- - released alpha17
- - changed error return code from cannor chdir() in make_connection
- - fixed realloc() bug in printing.c
- - fixed invalid username bug in sesssetupX
- - released alpha18
- - made default service change name to asked for service (idea
- from Ian McEwan <ijm@doc.ic.ac.uk>)
- - fixed "guest only" bug
- - sambatar patches from Ricky
- - printing.c patches from Dirk.DeWachter@rug.ac.be
- - rewrote become_user()
- - sunos5 patch from Niels.Baggesen@uni-c.dk
- - more japanese extensions patches from fujita@ainix.isac.co.jp
- - released alpha20
- - added force_user to conn struct
-
-
-1.9.15: 14/11/95
- - removed bcast override from workgroup announce in nmbd
- - aix patch, added NO_SYSMOUNTH, from
- lionel leston <102624.346@compuserve.com>
- - quick fix in lp_string() to try and stop some core dumps
- - added uid cache in connections structure
- to make user level security faster
- - changed dos_mode() to show read-only on read-only shares only if
- user w bit not set
- - added check to stop exit_server() looping
- - core dump fix in string_sub()
- - fix client bug for long dirs in NT1 mode.
- Thanks to Erwin Authried (erwin@ws1.atv.tuwien.ac.at)
- - switched to a safer (but probably slower) readbraw implementation
- - released p1
- - readbraw fix from Stefaan.Eeckels@eunet.lu
- - fixed groups bug when user is in 1 group
- - fixed NT1 dir bug
- - changed default protocol in client to NT1
- - changed trans2 to not return both names in long listing if long
- name is 8.3
- - made stat of "" return RONLY if not writeable drive
- - wrapped strcpy() to stop nulls propogating (hack)
- - made rename and unlink look at share locks on file
- - clitar memory leak fix from jjm@jjm.com
- - added -p option to smbstatus to list smbd processes
- - added rename to the client
- - released p2
- - fixed SMBmv for case where the destination exists
- - man page patch from michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
- - once again redid the time handling, but finally explained what
- is going on, this is written up in TIME.txt. The "kludge-GMT" used
- by NT is a bastard and led to a lot of the confusion
- - kanji patch from fujita@ainix.isac.co.jp (Takashi Fujita)
- - is08859-1 patches from eauth@mail.cso.co.at
- - starting rewriting nmbd, new nmbd is nmbd2, old one still around
- for time being
- - released p3
- - rewrote more of nmbd2 to use new structures
- - CLIX patches from Jason.J.Faultless@bechtel.btx400.co.uk
- - DirCacheFlush() bugfix from Michael Joosten
- <joost@ori.cadlab.de>. This bug explains a lot of the crashes.
- - fixed a bug in ChDir() that caused reversion to / in some
- situations
- - ipc fix from Magnus Hyllander <mhy@os.se>
- - released p4
- - smbpasswd fix from Jeremy
- - compilation fixes from Magnus Hyllander <mhy@os.se>
- - added NetServerEnum to ipc.c (needed for master browser stuff)
- - Makefile fix from Gunther Mayer <gmayer@physik.uni-kl.de>
- - cleanups for clean compile on several OSes
- - added browse mastering code
- - started integration with smb.conf for nmbd2
- - released p5
- - fixed death_time (should be t+ttl*3)
- - fixed non-removal of dead servers
- - added smbstatus -u patch from oskarh@spornet.is (Oskar Hannesson)
- - NETGROUP fix from J.W.Schilperoort@research.kpn.com
- - select and NO_SETGROUPS patches from lennylim@netcom.com (Lenny
- Lim)
- - added LINKS_READ_ONLY define in dos_mode() for LM/X
- compatability
- - "dir a.c" bug fixed thanks to roderich@nodebonn.muc.bmw.de
- (Roderich Schupp)
- - job cancel fix in client from peo@mtek.chalmers.se
- - changed nmbd2 to nmbd
- - fixed "dir a*" under trans2 lookups
- - added StrnCaseCmp()
- - updated docs a bit for new browsing stuff
- - updated INSTALL.txt
- - hopefully fixed server level security with WfWg
-
-1.9.15 (patches):
- - major/minor fix for solaris from Jeroen Schipper
- <Jeroen.Schipper@let.ruu.nl>
- - fixed critical bug in directory listings
- - released p1
- - fixed one of the causes of "out of memory" while browsing
- - fixed manpage install script (Paul Blackman)
- - added DNS failures to name cache
- - fixed writebmpx bug (affects OS/2)
- - misc OS/2 fixes, mostly for EA handling
- - added SMBcopy
- - added "max ttl" option
- - arch detection patch from Bas Laarhoven <bas@vimec.nl>
- - released p2
- - another OS/2 fix - the level 4 getpathinfo for EAs
- - added "alternate permissions" option
- - changed client to parse destination names into name + domain
- - fixed problem with PrimaryGroup and lmhosts loading
- - added domain master ability to nmbd
- - added "domain master" option
- - added "domain controller" option and code
- - pwd fix to client from Erik Devriendt (de@te6.siemens.be)
- - fixed problem in smbmv that led to ar not working in mks
- - added transs2
- - released p3
- - updated email addresses
- - fix for innetgr from Olaf Seibert (rhialto@polder.ubc.kun.nl)
- - client translate fix from bandc@dircon.co.uk
- - netbsd bcast fix from from Olaf Seibert (rhialto@polder.ubc.kun.nl)
- - syslog code from Alex Nash <alex@fa.tca.com>
- - strip dot fix from Arne Ansper <arne@ioc.ee>
- - added addtosmbpass + man page from
- michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
- - pcap fix for AIX from Jon Christiansen <jchristi@sctcorp.com>
- - fixed servertype bug in remote announcements
- - fixed up illegal name checks (should also be faster)
- - kanji patches from fujita@ainix.isac.co.jp (Takashi Fujita)
- - fixed bug handling non-encrypted passwords
- - released p4
- - fixed makefile for addtosmbpass
- - DCE/DFS fixes from John Brezak (brezak@ch.hp.com)
- - client patch for partial command matching from Andrew Wiseman
- <bandc@dircon.co.uk>
- - made is_8_3() handle full paths
- - rewrote open_file_shared() with help from Charles Hoch
- <hoch@hplcgh.hpl.hp.com>
- - changed syslog to handle interactive programs
- - fixed syslog problem with full path in argv[0]
- - illegal name fixup for kanji from fujita@ainix.isac.co.jp
- - fixed server level security to allow fallback to encryption
- - changed reply_read() and reply_lockread() to ignore clients
- smb_bufsize in order to handle broken lanman clients
- - fixed NT wildcard problem with old style programs
- - man page patches from "John M. Sellens"
- <jmsellen@watdragon.uwaterloo.ca>
- - partially documented the "character set" option
- - changed default for MAXDIR to 64
- - changed default DPTR idle time to 120
- - released p5
- - QNX patches from eldo@invisa.satlink.net (Eldo Loguzzo)
- - made nmbd use the "max log size" option and changed log handling
- code a bit
- - sunos patches, remote protocol (%R) addition and arch detection
- changes to stop compiler warning from Timothy Hunt <tim@fsg.com>
- - fixed become_user() bug that led to incorrect permissions in
- some situations.
- - released p6
- - is_8_3() fix from Charles Hoch <hoch@hplcgh.hpl.hp.com>
- - nmblib bugfix from gmk@mhcnet.att.com (George Kull)
- - aix pcap fix from Jon Christiansen <jchristi@sctcorp.com>
- - added explicit sig_pipe() in server.c
- - added domain logins option (not fully implemented)
- - added HAVE_GMTOFF code
- - got rid of PM_MAXLINE
- - minor client fix from goggi@eflir (Garðar Georg Nielsen)
- - added SIGCLD_IGNORE for HPUX (from Tor Lillqvist
- <tml@hemuli.tte.vtt.fi>)
- - OSF/1 lpq patch from scooter@GENE.COM (Scooter Morris)
- - NeXT patches from pmarcos@next.com (Paul Marcos)
- - dstdiff patch to stop infinite loop from Erwin Authried (eauth@cso.co.at)
- - password server option can now take a list of password servers
- - patches to let samba run on OS/2 from Jason Rumney <jasonr@pec.co.nz>
- - added domain logon and logon script suport
- - SCO openserver 5 patches from Scott Michel <scottm@intime.intime.com>
- - Makefile changes from Marty Leisner <leisner@sdsp.mc.xerox.com>
- - chgpasswd changes from Roman Dumych <roman@nyxis.unibase.com>
- for SVR4
- - GUEST_SESSSETUP change from David.Chappell@mail.cc.trincoll.edu
- - released p7
- - moved SO_REUSEADDR before bind() (thanks to Thomas Bellman
- <tbe@ivab.se>)
- - added more flexible GUEST_SESSSETUP to local.h and restored
- pre-p7 behaviour as default
- - released p8
-
-1.9.16:
- - Makefile fix from Marty Leisner <leisner@sdsp.mc.xerox.com>
- - added %g and %G substitutions
- - changed IDLE_CLOSED_TIMEOUT to 60
- - fixed the "admin user" status in domain logons
- - hpux 10 "trusted security" patches from David-Michael Lincke
- (dlincke@sgcl1.unisg.ch)
- - added nmb lookups to client from Adrian Hill <Adrian.Hill@softimage.co.uk>
- - svr4 pause/resume printing patch from Brendan O'Dea (bod@tyndall.com.au)
- - fixed master announcement thanks to Luke Leighton <rah14@dial.pipex.com>
- - changed srcdir usage in Makefile to be friendly to more systems
- - NT4 alignment patches from Jeremy Allison (jra@vantive.com)
- - updated share mode code for new spec
- - minor client bugfix (for smbclient '\\\')
- - fix for level 260 when magling disabled. From Martin Tomes
- <Martin.Tomes@ecl.etherm.co.uk>
- - SMBtranss2 fix for OS/2 from Jeremy Allison
- - profiles fixup from Timm Wetzel <twetzel@cage.mpibpc.gwdg.de>
- - man page updates from Dirk.DeWachter@rug.ac.be
- - nmbsync fix from Andy Whitcroft <andy@soi.city.ac.uk>
- - Lynx patches from Manfred Woelfel <woelfel@hpesco1.fzk.de>
- - new smbtar stuff from Ricky
- - changed to share mode DENY_NONE for tar
- - fixed -D option of smbclient when in tar mode
- - added aARCH to open modes
- - added code to cope with select/read errors
- - fixed blank browse entries after smb.conf reread
- - integrated new browse stuff from Luke into ipc.c
- - added workgroup list to smbclient -L
- - improved archive attribute handling in close_file() and
- write_file()
- - smbtar fixes from Martin.Kraemer@mch.sni.de
- - Linux quota patch from xeno@mix.hsv.no
- - try to work around NT passlen2 problem in session setup
- - released alpha1
-
-NOTE: From now on the cvs.log file will be used to give a complete log of
-changes to samba. This change-log is now obsolete.
-
-
-==========
-todo:
-
-
-64 bit longs and IP addresses may give problems with unsigned longs?
-
-set archive bit whenever file is modified??
-
-fix man page dates
-
-reply only to own workgroup in server enum
-
-patch to compile with g++ and possibly solaris c++
-
-nmbd needs to keep browse list uptodate by talking to the master if it loses
-an election as others may still think its a valid backup and use it to get
-lists.
-
-leftover lock files can end up belonging to non-smbd processes after a reboot.
-
-hosts allow in nmbd
-
-hosts allow cache
-
-add password command in smbclient
-
-drag long filename to samba under os/2 gives short name
-
-document max ttl option
-
-dup/close 0 for getopt?
-
-implement SMBmove ??
-
-add option to print more info about locked files (full path, share name
-etc)
-
-very slow listing CD, perhaps because of order of stat and readdir or add
-masking to opendir?
-
-protocol drop back in client to avoid openX etc.
-
-handle exported fat drives to a long filename capable client
-
-add check for existance of lpq commands etc (use stat?)
-
-get rid of the silly +4 and -4 by removing NBT stuff
-
-write-only shares
-
-document cnvchar stuff
-
-allow smbd to serve user and group lists to win95
-
-document homes behaviour with WinDD
-
-add "hide file = *.o" "hide dir = .Foo*" "show file = xx*" type options.
-
-ALLOW_PASSWORD_CHANGE only compiles/works on some systems
-
-weird foooooooo/open.exe bug on NT
-
-%a detection can't detect Win95 versus WinNT
-
-reverse mangled maps, so (*.html *.htm) works for new files.
-
-install problems with w95. could be some sort of race?
-
-more efficient Files[] structure to handle thousands of open files
-
-lpd stuff:
- Tony Aiuto (tony@ics.com)
-
-make max disk size local
-
diff --git a/source/client/client.c b/source/client/client.c
index f2f43656cbb..d95281e936f 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB client
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Simo Sorce 2001-2002
- Copyright (C) Jelmer Vernooij 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,44 +22,47 @@
#define NO_SYSLOG
#include "includes.h"
-#include "../client/client_proto.h"
+
#ifndef REGISTER
#define REGISTER 0
#endif
struct cli_state *cli;
extern BOOL in_client;
-static int port = 0;
+extern BOOL AllowDebugChange;
+static int port = SMB_PORT;
pstring cur_dir = "\\";
-static pstring cd_path = "";
+pstring cd_path = "";
static pstring service;
static pstring desthost;
-static pstring username;
+extern pstring global_myname;
static pstring password;
-static BOOL use_kerberos;
+static pstring username;
+static pstring workgroup;
+static char *cmdstr;
static BOOL got_pass;
-static BOOL grepable=False;
-static char *cmdstr = NULL;
-
static int io_bufsize = 64512;
static int name_type = 0x20;
static int max_protocol = PROTOCOL_NT1;
+extern pstring user_socket_options;
-static int process_tok(pstring tok);
-static int cmd_help(void);
+static int process_tok(fstring tok);
+static void cmd_help(void);
/* 30 second timeout on most commands */
#define CLIENT_TIMEOUT (30*1000)
#define SHORT_TIMEOUT (5*1000)
+int timeout_msec = 0;
+
/* value for unused fid field in trans2 secondary request */
#define FID_UNUSED (0xFFFF)
time_t newer_than = 0;
-static int archive_level = 0;
+int archive_level = 0;
-static BOOL translation = False;
+BOOL translation = False;
static BOOL have_ip;
@@ -71,42 +73,38 @@ extern BOOL tar_reset;
/* clitar bits end */
-static BOOL prompt = True;
+BOOL prompt = True;
-static int printmode = 1;
+int printmode = 1;
static BOOL recurse = False;
BOOL lowercase = False;
-static struct in_addr dest_ip;
+struct in_addr dest_ip;
#define SEPARATORS " \t\n\r"
-static BOOL abort_mget = True;
+BOOL abort_mget = True;
-static pstring fileselection = "";
+pstring fileselection = "";
extern file_info def_finfo;
/* timing globals */
-SMB_BIG_UINT get_total_size = 0;
+off_t get_total_size = 0;
unsigned int get_total_time_ms = 0;
-static SMB_BIG_UINT put_total_size = 0;
-static unsigned int put_total_time_ms = 0;
+off_t put_total_size = 0;
+unsigned int put_total_time_ms = 0;
/* totals globals */
static double dir_total;
#define USENMB
-/* some forward declarations */
-static struct cli_state *do_connect(const char *server, const char *share);
-
/****************************************************************************
- Write to a local file with CR/LF->LF translation if appropriate. Return the
- number taken from the buffer. This may not equal the number written.
+write to a local file with CR/LF->LF translation if appropriate. return the
+number taken from the buffer. This may not equal the number written.
****************************************************************************/
-
static int writefile(int f, char *b, int n)
{
int i;
@@ -131,21 +129,20 @@ static int writefile(int f, char *b, int n)
}
/****************************************************************************
- Read from a file with LF->CR/LF translation if appropriate. Return the
- number read. read approx n bytes.
+ read from a file with LF->CR/LF translation if appropriate. return the
+ number read. read approx n bytes.
****************************************************************************/
-
-static int readfile(char *b, int n, XFILE *f)
+static int readfile(char *b, int size, int n, FILE *f)
{
int i;
int c;
- if (!translation)
- return x_fread(b,1,n,f);
+ if (!translation || (size != 1))
+ return(fread(b,size,n,f));
i = 0;
while (i < (n - 1) && (i < BUFFER_SIZE)) {
- if ((c = x_getc(f)) == EOF) {
+ if ((c = getc(f)) == EOF) {
break;
}
@@ -159,22 +156,22 @@ static int readfile(char *b, int n, XFILE *f)
return(i);
}
+
/****************************************************************************
- Send a message.
+send a message
****************************************************************************/
-
static void send_message(void)
{
int total_len = 0;
int grp_id;
if (!cli_message_start(cli, desthost, username, &grp_id)) {
- d_printf("message start: %s\n", cli_errstr(cli));
+ DEBUG(0,("message start: %s\n", cli_errstr(cli)));
return;
}
- d_printf("Connected. Type your message, ending it with a Control-D\n");
+ printf("Connected. Type your message, ending it with a Control-D\n");
while (!feof(stdin) && total_len < 1600) {
int maxlen = MIN(1600 - total_len,127);
@@ -190,8 +187,15 @@ static void send_message(void)
msg[l] = c;
}
+ /*
+ * The message is in UNIX codepage format. Convert to
+ * DOS before sending.
+ */
+
+ unix_to_dos(msg);
+
if (!cli_message_text(cli, msg, l, grp_id)) {
- d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
+ printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
return;
}
@@ -199,51 +203,48 @@ static void send_message(void)
}
if (total_len >= 1600)
- d_printf("the message was truncated to 1600 bytes\n");
+ printf("the message was truncated to 1600 bytes\n");
else
- d_printf("sent %d bytes\n",total_len);
+ printf("sent %d bytes\n",total_len);
if (!cli_message_end(cli, grp_id)) {
- d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));
+ printf("SMBsendend failed (%s)\n",cli_errstr(cli));
return;
}
}
+
+
/****************************************************************************
- Check the space on a device.
+check the space on a device
****************************************************************************/
-
-static int do_dskattr(void)
+static void do_dskattr(void)
{
int total, bsize, avail;
if (!cli_dskattr(cli, &bsize, &total, &avail)) {
- d_printf("Error in dskattr: %s\n",cli_errstr(cli));
- return 1;
+ DEBUG(0,("Error in dskattr: %s\n",cli_errstr(cli)));
+ return;
}
- d_printf("\n\t\t%d blocks of size %d. %d blocks available\n",
- total, bsize, avail);
-
- return 0;
+ DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
+ total, bsize, avail));
}
/****************************************************************************
- Show cd/pwd.
+show cd/pwd
****************************************************************************/
-
-static int cmd_pwd(void)
+static void cmd_pwd(void)
{
- d_printf("Current directory is %s",service);
- d_printf("%s\n",cur_dir);
- return 0;
+ DEBUG(0,("Current directory is %s",service));
+ DEBUG(0,("%s\n",cur_dir));
}
+
/****************************************************************************
- Change directory - inner section.
+change directory - inner section
****************************************************************************/
-
-static int do_cd(char *newdir)
+static void do_cd(char *newdir)
{
char *p = newdir;
pstring saved_dir;
@@ -268,41 +269,34 @@ static int do_cd(char *newdir)
if (!strequal(cur_dir,"\\")) {
if (!cli_chkpath(cli, dname)) {
- d_printf("cd %s: %s\n", dname, cli_errstr(cli));
+ DEBUG(0,("cd %s: %s\n", dname, cli_errstr(cli)));
pstrcpy(cur_dir,saved_dir);
}
}
pstrcpy(cd_path,cur_dir);
-
- return 0;
}
/****************************************************************************
- Change directory.
+change directory
****************************************************************************/
-
-static int cmd_cd(void)
+static void cmd_cd(void)
{
- pstring buf;
- int rc = 0;
+ fstring buf;
- if (next_token_nr(NULL,buf,NULL,sizeof(buf)))
- rc = do_cd(buf);
+ if (next_token(NULL,buf,NULL,sizeof(buf)))
+ do_cd(buf);
else
- d_printf("Current directory is %s\n",cur_dir);
-
- return rc;
+ DEBUG(0,("Current directory is %s\n",cur_dir));
}
-/*******************************************************************
- Decide if a file should be operated on.
-********************************************************************/
+/*******************************************************************
+ decide if a file should be operated on
+ ********************************************************************/
static BOOL do_this_one(file_info *finfo)
{
- if (finfo->mode & aDIR)
- return(True);
+ if (finfo->mode & aDIR) return(True);
if (*fileselection &&
!mask_match(finfo->name,fileselection,False)) {
@@ -324,26 +318,25 @@ static BOOL do_this_one(file_info *finfo)
}
/****************************************************************************
- Display info about a file.
-****************************************************************************/
-
+ display info about a file
+ ****************************************************************************/
static void display_finfo(file_info *finfo)
{
if (do_this_one(finfo)) {
time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
- d_printf(" %-30s%7.7s %8.0f %s",
+ DEBUG(0,(" %-30s%7.7s %8.0f %s",
finfo->name,
attrib_string(finfo->mode),
(double)finfo->size,
- asctime(LocalTime(&t)));
+ asctime(LocalTime(&t))));
dir_total += finfo->size;
}
}
-/****************************************************************************
- Accumulate size of a file.
-****************************************************************************/
+/****************************************************************************
+ accumulate size of a file
+ ****************************************************************************/
static void do_du(file_info *finfo)
{
if (do_this_one(finfo)) {
@@ -360,8 +353,8 @@ static long do_list_queue_end = 0;
static void (*do_list_fn)(file_info *);
/****************************************************************************
- Functions for do_list_queue.
-****************************************************************************/
+functions for do_list_queue
+ ****************************************************************************/
/*
* The do_list_queue is a NUL-separated list of strings stored in a
@@ -374,10 +367,10 @@ static void (*do_list_fn)(file_info *);
* Functions check to ensure that do_list_queue is non-NULL before
* accessing it.
*/
-
static void reset_do_list_queue(void)
{
SAFE_FREE(do_list_queue);
+ do_list_queue = 0;
do_list_queue_size = 0;
do_list_queue_start = 0;
do_list_queue_end = 0;
@@ -389,8 +382,8 @@ static void init_do_list_queue(void)
do_list_queue_size = 1024;
do_list_queue = malloc(do_list_queue_size);
if (do_list_queue == 0) {
- d_printf("malloc fail for size %d\n",
- (int)do_list_queue_size);
+ DEBUG(0,("malloc fail for size %d\n",
+ (int)do_list_queue_size));
reset_do_list_queue();
} else {
memset(do_list_queue, 0, do_list_queue_size);
@@ -403,11 +396,14 @@ static void adjust_do_list_queue(void)
* If the starting point of the queue is more than half way through,
* move everything toward the beginning.
*/
- if (do_list_queue && (do_list_queue_start == do_list_queue_end)) {
+ if (do_list_queue && (do_list_queue_start == do_list_queue_end))
+ {
DEBUG(4,("do_list_queue is empty\n"));
do_list_queue_start = do_list_queue_end = 0;
*do_list_queue = '\0';
- } else if (do_list_queue_start > (do_list_queue_size / 2)) {
+ }
+ else if (do_list_queue_start > (do_list_queue_size / 2))
+ {
DEBUG(4,("sliding do_list_queue backward\n"));
memmove(do_list_queue,
do_list_queue + do_list_queue_start,
@@ -415,20 +411,23 @@ static void adjust_do_list_queue(void)
do_list_queue_end -= do_list_queue_start;
do_list_queue_start = 0;
}
+
}
static void add_to_do_list_queue(const char* entry)
{
char *dlq;
+
long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
- while (new_end > do_list_queue_size) {
+ while (new_end > do_list_queue_size)
+ {
do_list_queue_size *= 2;
DEBUG(4,("enlarging do_list_queue to %d\n",
(int)do_list_queue_size));
dlq = Realloc(do_list_queue, do_list_queue_size);
- if (! dlq) {
- d_printf("failure enlarging do_list_queue to %d bytes\n",
- (int)do_list_queue_size);
+ if (!dlq) {
+ DEBUG(0,("failure enlarging do_list_queue to %d bytes\n",
+ (int)do_list_queue_size));
reset_do_list_queue();
} else {
do_list_queue = dlq;
@@ -436,9 +435,9 @@ static void add_to_do_list_queue(const char* entry)
0, do_list_queue_size / 2);
}
}
- if (do_list_queue) {
- safe_strcpy_base(do_list_queue + do_list_queue_end,
- entry, do_list_queue, do_list_queue_size);
+ if (do_list_queue)
+ {
+ pstrcpy(do_list_queue + do_list_queue_end, entry);
do_list_queue_end = new_end;
DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",
entry, (int)do_list_queue_start, (int)do_list_queue_end));
@@ -452,7 +451,8 @@ static char *do_list_queue_head(void)
static void remove_do_list_queue_head(void)
{
- if (do_list_queue_end > do_list_queue_start) {
+ if (do_list_queue_end > do_list_queue_start)
+ {
do_list_queue_start += strlen(do_list_queue_head()) + 1;
adjust_do_list_queue();
DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",
@@ -466,9 +466,8 @@ static int do_list_queue_empty(void)
}
/****************************************************************************
- A helper for do_list.
-****************************************************************************/
-
+a helper for do_list
+ ****************************************************************************/
static void do_list_helper(file_info *f, const char *mask, void *state)
{
if (f->mode & aDIR) {
@@ -481,15 +480,9 @@ static void do_list_helper(file_info *f, const char *mask, void *state)
pstring mask2;
char *p;
- if (!f->name[0]) {
- d_printf("Empty dir name returned. Possible server misconfiguration.\n");
- return;
- }
-
pstrcpy(mask2, mask);
- p = strrchr_m(mask2,'\\');
- if (!p)
- return;
+ p = strrchr(mask2,'\\');
+ if (!p) return;
p[1] = 0;
pstrcat(mask2, f->name);
pstrcat(mask2,"\\*");
@@ -503,15 +496,16 @@ static void do_list_helper(file_info *f, const char *mask, void *state)
}
}
-/****************************************************************************
- A wrapper around cli_list that adds recursion.
-****************************************************************************/
+/****************************************************************************
+a wrapper around cli_list that adds recursion
+ ****************************************************************************/
void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
{
static int in_do_list = 0;
- if (in_do_list && rec) {
+ if (in_do_list && rec)
+ {
fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");
exit(1);
}
@@ -522,11 +516,13 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
do_list_dirs = dirs;
do_list_fn = fn;
- if (rec) {
+ if (rec)
+ {
init_do_list_queue();
add_to_do_list_queue(mask);
- while (! do_list_queue_empty()) {
+ while (! do_list_queue_empty())
+ {
/*
* Need to copy head so that it doesn't become
* invalid inside the call to cli_list. This
@@ -538,25 +534,31 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
pstrcpy(head, do_list_queue_head());
cli_list(cli, head, attribute, do_list_helper, NULL);
remove_do_list_queue_head();
- if ((! do_list_queue_empty()) && (fn == display_finfo)) {
+ if ((! do_list_queue_empty()) && (fn == display_finfo))
+ {
char* next_file = do_list_queue_head();
char* save_ch = 0;
if ((strlen(next_file) >= 2) &&
(next_file[strlen(next_file) - 1] == '*') &&
- (next_file[strlen(next_file) - 2] == '\\')) {
+ (next_file[strlen(next_file) - 2] == '\\'))
+ {
save_ch = next_file +
strlen(next_file) - 2;
*save_ch = '\0';
}
- d_printf("\n%s\n",next_file);
- if (save_ch) {
+ DEBUG(0,("\n%s\n",next_file));
+ if (save_ch)
+ {
*save_ch = '\\';
}
}
}
- } else {
- if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1) {
- d_printf("%s listing %s\n", cli_errstr(cli), mask);
+ }
+ else
+ {
+ if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1)
+ {
+ DEBUG(0, ("%s listing %s\n", cli_errstr(cli), mask));
}
}
@@ -565,63 +567,55 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
}
/****************************************************************************
- Get a directory listing.
-****************************************************************************/
-
-static int cmd_dir(void)
+ get a directory listing
+ ****************************************************************************/
+static void cmd_dir(void)
{
uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
pstring mask;
- pstring buf;
+ fstring buf;
char *p=buf;
- int rc;
dir_total = 0;
- if (strcmp(cur_dir, "\\") != 0) {
- pstrcpy(mask,cur_dir);
- if(mask[strlen(mask)-1]!='\\')
- pstrcat(mask,"\\");
- } else {
- *mask = '\0';
- }
+ pstrcpy(mask,cur_dir);
+ if(mask[strlen(mask)-1]!='\\')
+ pstrcat(mask,"\\");
- if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (next_token(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
if (*p == '\\')
pstrcpy(mask,p);
else
pstrcat(mask,p);
- } else {
+ }
+ else {
pstrcat(mask,"*");
}
do_list(mask, attribute, display_finfo, recurse, True);
- rc = do_dskattr();
+ do_dskattr();
DEBUG(3, ("Total bytes listed: %.0f\n", dir_total));
-
- return rc;
}
-/****************************************************************************
- Get a directory listing.
-****************************************************************************/
-static int cmd_du(void)
+/****************************************************************************
+ get a directory listing
+ ****************************************************************************/
+static void cmd_du(void)
{
uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
pstring mask;
- pstring buf;
+ fstring buf;
char *p=buf;
- int rc;
dir_total = 0;
pstrcpy(mask,cur_dir);
if(mask[strlen(mask)-1]!='\\')
pstrcat(mask,"\\");
- if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (next_token(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
if (*p == '\\')
pstrcpy(mask,p);
@@ -633,110 +627,90 @@ static int cmd_du(void)
do_list(mask, attribute, do_du, recurse, True);
- rc = do_dskattr();
-
- d_printf("Total number of bytes: %.0f\n", dir_total);
+ do_dskattr();
- return rc;
+ DEBUG(0, ("Total number of bytes: %.0f\n", dir_total));
}
-/****************************************************************************
- Get a file from rname to lname
-****************************************************************************/
-static int do_get(char *rname, char *lname, BOOL reget)
+/****************************************************************************
+ get a file from rname to lname
+ ****************************************************************************/
+static void do_get(char *rname,char *lname)
{
- int handle = 0, fnum;
+ int handle=0,fnum;
BOOL newhandle = False;
char *data;
struct timeval tp_start;
int read_size = io_bufsize;
uint16 attr;
- size_t size;
- off_t start = 0;
- off_t nread = 0;
- int rc = 0;
+ size_t old_size = 0;
+ SMB_BIG_UINT size = 0;
+ SMB_BIG_UINT nread = 0;
GetTimeOfDay(&tp_start);
if (lowercase) {
- strlower_m(lname);
+ strlower(lname);
}
fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
if (fnum == -1) {
- d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
- return 1;
+ DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),rname));
+ return;
}
if(!strcmp(lname,"-")) {
handle = fileno(stdout);
} else {
- if (reget) {
- handle = sys_open(lname, O_WRONLY|O_CREAT, 0644);
- if (handle >= 0) {
- start = sys_lseek(handle, 0, SEEK_END);
- if (start == -1) {
- d_printf("Error seeking local file\n");
- return 1;
- }
- }
- } else {
- handle = sys_open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
- }
+ handle = sys_open(lname,O_WRONLY|O_CREAT|O_TRUNC,0644);
newhandle = True;
}
if (handle < 0) {
- d_printf("Error opening local file %s\n",lname);
- return 1;
+ DEBUG(0,("Error opening local file %s\n",lname));
+ return;
}
-
if (!cli_qfileinfo(cli, fnum,
- &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
+ &attr, &old_size, NULL, NULL, NULL, NULL, NULL) &&
!cli_getattrE(cli, fnum,
&attr, &size, NULL, NULL, NULL)) {
- d_printf("getattrib: %s\n",cli_errstr(cli));
- return 1;
+ DEBUG(0,("getattrib: %s\n",cli_errstr(cli)));
+ return;
}
DEBUG(2,("getting file %s of size %.0f as %s ",
rname, (double)size, lname));
if(!(data = (char *)malloc(read_size))) {
- d_printf("malloc fail for size %d\n", read_size);
+ DEBUG(0,("malloc fail for size %d\n", read_size));
cli_close(cli, fnum);
- return 1;
+ return;
}
while (1) {
- int n = cli_read(cli, fnum, data, nread + start, read_size);
+ int n = cli_read(cli, fnum, data, nread, read_size);
- if (n <= 0)
- break;
+ if (n <= 0) break;
if (writefile(handle,data, n) != n) {
- d_printf("Error writing local file\n");
- rc = 1;
+ DEBUG(0,("Error writing local file\n"));
break;
}
nread += n;
}
- if (nread + start < size) {
+ if (nread < size) {
DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
- rname, (long)nread));
-
- rc = 1;
+ rname, (long)nread));
}
SAFE_FREE(data);
if (!cli_close(cli, fnum)) {
- d_printf("Error %s closing remote file\n",cli_errstr(cli));
- rc = 1;
+ DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
}
if (newhandle) {
@@ -762,15 +736,13 @@ static int do_get(char *rname, char *lname, BOOL reget)
nread / (1.024*this_time + 1.0e-4),
get_total_size / (1.024*get_total_time_ms)));
}
-
- return rc;
}
-/****************************************************************************
- Get a file.
-****************************************************************************/
-static int cmd_get(void)
+/****************************************************************************
+ get a file
+ ****************************************************************************/
+static void cmd_get(void)
{
pstring lname;
pstring rname;
@@ -781,22 +753,22 @@ static int cmd_get(void)
p = rname + strlen(rname);
- if (!next_token_nr(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
- d_printf("get <filename>\n");
- return 1;
+ if (!next_token(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
+ DEBUG(0,("get <filename>\n"));
+ return;
}
pstrcpy(lname,p);
dos_clean_name(rname);
- next_token_nr(NULL,lname,NULL,sizeof(lname));
+ next_token(NULL,lname,NULL,sizeof(lname));
- return do_get(rname, lname, False);
+ do_get(rname, lname);
}
-/****************************************************************************
- Do an mget operation on one file.
-****************************************************************************/
+/****************************************************************************
+ do a mget operation on one file
+ ****************************************************************************/
static void do_mget(file_info *finfo)
{
pstring rname;
@@ -808,7 +780,7 @@ static void do_mget(file_info *finfo)
return;
if (abort_mget) {
- d_printf("mget aborted\n");
+ DEBUG(0,("mget aborted\n"));
return;
}
@@ -819,13 +791,12 @@ static void do_mget(file_info *finfo)
slprintf(quest,sizeof(pstring)-1,
"Get file %s? ",finfo->name);
- if (prompt && !yesno(quest))
- return;
+ if (prompt && !yesno(quest)) return;
if (!(finfo->mode & aDIR)) {
pstrcpy(rname,cur_dir);
pstrcat(rname,finfo->name);
- do_get(rname, finfo->name, False);
+ do_get(rname,finfo->name);
return;
}
@@ -837,17 +808,17 @@ static void do_mget(file_info *finfo)
unix_format(finfo->name);
if (lowercase)
- strlower_m(finfo->name);
+ strlower(finfo->name);
if (!directory_exist(finfo->name,NULL) &&
mkdir(finfo->name,0777) != 0) {
- d_printf("failed to create directory %s\n",finfo->name);
+ DEBUG(0,("failed to create directory %s\n",finfo->name));
pstrcpy(cur_dir,saved_curdir);
return;
}
if (chdir(finfo->name) != 0) {
- d_printf("failed to chdir to directory %s\n",finfo->name);
+ DEBUG(0,("failed to chdir to directory %s\n",finfo->name));
pstrcpy(cur_dir,saved_curdir);
return;
}
@@ -860,36 +831,35 @@ static void do_mget(file_info *finfo)
pstrcpy(cur_dir,saved_curdir);
}
+
/****************************************************************************
- View the file using the pager.
+view the file using the pager
****************************************************************************/
-
-static int cmd_more(void)
+static void cmd_more(void)
{
- pstring rname,lname,pager_cmd;
+ fstring rname,lname,pager_cmd;
char *pager;
int fd;
- int rc = 0;
- pstrcpy(rname,cur_dir);
- pstrcat(rname,"\\");
+ fstrcpy(rname,cur_dir);
+ fstrcat(rname,"\\");
slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir());
fd = smb_mkstemp(lname);
if (fd == -1) {
- d_printf("failed to create temporary file for more\n");
- return 1;
+ DEBUG(0,("failed to create temporary file for more\n"));
+ return;
}
close(fd);
- if (!next_token_nr(NULL,rname+strlen(rname),NULL,sizeof(rname)-strlen(rname))) {
- d_printf("more <filename>\n");
+ if (!next_token(NULL,rname+strlen(rname),NULL,sizeof(rname)-strlen(rname))) {
+ DEBUG(0,("more <filename>\n"));
unlink(lname);
- return 1;
+ return;
}
dos_clean_name(rname);
- rc = do_get(rname, lname, False);
+ do_get(rname,lname);
pager=getenv("PAGER");
@@ -897,19 +867,18 @@ static int cmd_more(void)
"%s %s",(pager? pager:PAGER), lname);
system(pager_cmd);
unlink(lname);
-
- return rc;
}
+
+
/****************************************************************************
- Do a mget command.
+do a mget command
****************************************************************************/
-
-static int cmd_mget(void)
+static void cmd_mget(void)
{
uint16 attribute = aSYSTEM | aHIDDEN;
pstring mget_mask;
- pstring buf;
+ fstring buf;
char *p=buf;
*mget_mask = 0;
@@ -919,7 +888,7 @@ static int cmd_mget(void)
abort_mget = False;
- while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
+ while (next_token(NULL,p,NULL,sizeof(buf))) {
pstrcpy(mget_mask,cur_dir);
if(mget_mask[strlen(mget_mask)-1]!='\\')
pstrcat(mget_mask,"\\");
@@ -938,19 +907,17 @@ static int cmd_mget(void)
pstrcat(mget_mask,"*");
do_list(mget_mask, attribute,do_mget,False,True);
}
-
- return 0;
}
+
/****************************************************************************
- Make a directory of name "name".
+make a directory of name "name"
****************************************************************************/
-
static BOOL do_mkdir(char *name)
{
if (!cli_mkdir(cli, name)) {
- d_printf("%s making remote directory %s\n",
- cli_errstr(cli),name);
+ DEBUG(0,("%s making remote directory %s\n",
+ cli_errstr(cli),name));
return(False);
}
@@ -963,13 +930,12 @@ static BOOL do_mkdir(char *name)
static BOOL do_altname(char *name)
{
- pstring altname;
+ fstring altname;
if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) {
- d_printf("%s getting alt name for %s\n",
- cli_errstr(cli),name);
+ DEBUG(0,("%s getting alt name for %s\n", cli_errstr(cli),name));
return(False);
}
- d_printf("%s\n", altname);
+ DEBUG(0,("%s\n", altname));
return(True);
}
@@ -977,31 +943,28 @@ static BOOL do_altname(char *name)
/****************************************************************************
Exit client.
****************************************************************************/
-
-static int cmd_quit(void)
+static void cmd_quit(void)
{
cli_shutdown(cli);
exit(0);
- /* NOTREACHED */
- return 0;
}
-/****************************************************************************
- Make a directory.
-****************************************************************************/
-static int cmd_mkdir(void)
+/****************************************************************************
+ make a directory
+ ****************************************************************************/
+static void cmd_mkdir(void)
{
pstring mask;
- pstring buf;
+ fstring buf;
char *p=buf;
pstrcpy(mask,cur_dir);
- if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
+ if (!next_token(NULL,p,NULL,sizeof(buf))) {
if (!recurse)
- d_printf("mkdir <dirname>\n");
- return 1;
+ DEBUG(0,("mkdir <dirname>\n"));
+ return;
}
pstrcat(mask,p);
@@ -1011,7 +974,7 @@ static int cmd_mkdir(void)
*ddir2 = 0;
pstrcpy(ddir,mask);
- trim_char(ddir,'.','\0');
+ trim_string(ddir,".",NULL);
p = strtok(ddir,"/\\");
while (p) {
pstrcat(ddir2,p);
@@ -1024,117 +987,89 @@ static int cmd_mkdir(void)
} else {
do_mkdir(mask);
}
-
- return 0;
}
/****************************************************************************
- Show alt name.
-****************************************************************************/
+ show alt name
+ ****************************************************************************/
-static int cmd_altname(void)
+static void cmd_altname(void)
{
pstring name;
- pstring buf;
+ fstring buf;
char *p=buf;
-
+
pstrcpy(name,cur_dir);
- if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
- d_printf("altname <file>\n");
- return 1;
+ if (!next_token(NULL,p,NULL,sizeof(buf))) {
+ DEBUG(0,("altname <file>\n"));
+ return;
}
pstrcat(name,p);
do_altname(name);
-
- return 0;
}
/****************************************************************************
- Put a single file.
-****************************************************************************/
-
-static int do_put(char *rname, char *lname, BOOL reput)
+ put a single file
+ ****************************************************************************/
+static void do_put(char *rname,char *lname)
{
int fnum;
- XFILE *f;
- size_t start = 0;
- off_t nread = 0;
- char *buf = NULL;
- int maxwrite = io_bufsize;
- int rc = 0;
+ FILE *f;
+ off_t nread=0;
+ char *buf=NULL;
+ int maxwrite=io_bufsize;
struct timeval tp_start;
GetTimeOfDay(&tp_start);
- if (reput) {
- fnum = cli_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE);
- if (fnum >= 0) {
- if (!cli_qfileinfo(cli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) &&
- !cli_getattrE(cli, fnum, NULL, &start, NULL, NULL, NULL)) {
- d_printf("getattrib: %s\n",cli_errstr(cli));
- return 1;
- }
- }
- } else {
- fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
- }
+ fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
if (fnum == -1) {
- d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
- return 1;
+ DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),rname));
+ return;
}
/* allow files to be piped into smbclient
- jdblair 24.jun.98
-
- Note that in this case this function will exit(0) rather
- than returning. */
+ jdblair 24.jun.98 */
if (!strcmp(lname, "-")) {
- f = x_stdin;
+ f = stdin;
/* size of file is not known */
} else {
- f = x_fopen(lname,O_RDONLY, 0);
- if (f && reput) {
- if (x_tseek(f, start, SEEK_SET) == -1) {
- d_printf("Error seeking local file\n");
- return 1;
- }
- }
+ f = sys_fopen(lname,"r");
}
if (!f) {
- d_printf("Error opening local file %s\n",lname);
- return 1;
+ DEBUG(0,("Error opening local file %s\n",lname));
+ return;
}
+
DEBUG(1,("putting file %s as %s ",lname,
rname));
buf = (char *)malloc(maxwrite);
if (!buf) {
- d_printf("ERROR: Not enough memory!\n");
- return 1;
+ DEBUG(0, ("ERROR: Not enough memory!\n"));
+ return;
}
- while (!x_feof(f)) {
+ while (!feof(f)) {
int n = maxwrite;
int ret;
- if ((n = readfile(buf,n,f)) < 1) {
- if((n == 0) && x_feof(f))
+ if ((n = readfile(buf,1,n,f)) < 1) {
+ if((n == 0) && feof(f))
break; /* Empty local file. */
- d_printf("Error reading local file: %s\n", strerror(errno));
- rc = 1;
+ DEBUG(0,("Error reading local file: %s\n", strerror(errno) ));
break;
}
- ret = cli_write(cli, fnum, 0, buf, nread + start, n);
+ ret = cli_write(cli, fnum, 0, buf, nread, n);
if (n != ret) {
- d_printf("Error writing file: %s\n", cli_errstr(cli));
- rc = 1;
+ DEBUG(0,("Error writing file: %s\n", cli_errstr(cli)));
break;
}
@@ -1142,17 +1077,14 @@ static int do_put(char *rname, char *lname, BOOL reput)
}
if (!cli_close(cli, fnum)) {
- d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
- x_fclose(f);
+ DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),rname));
+ fclose(f);
SAFE_FREE(buf);
- return 1;
+ return;
}
- if (f != x_stdin) {
- x_fclose(f);
- }
-
+ fclose(f);
SAFE_FREE(buf);
{
@@ -1171,35 +1103,34 @@ static int do_put(char *rname, char *lname, BOOL reput)
put_total_size / (1.024*put_total_time_ms)));
}
- if (f == x_stdin) {
+ if (f == stdin) {
cli_shutdown(cli);
exit(0);
}
-
- return rc;
}
-/****************************************************************************
- Put a file.
-****************************************************************************/
+
-static int cmd_put(void)
+/****************************************************************************
+ put a file
+ ****************************************************************************/
+static void cmd_put(void)
{
pstring lname;
pstring rname;
- pstring buf;
+ fstring buf;
char *p=buf;
pstrcpy(rname,cur_dir);
pstrcat(rname,"\\");
- if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
- d_printf("put <filename>\n");
- return 1;
+ if (!next_token(NULL,p,NULL,sizeof(buf))) {
+ DEBUG(0,("put <filename>\n"));
+ return;
}
pstrcpy(lname,p);
- if (next_token_nr(NULL,p,NULL,sizeof(buf)))
+ if (next_token(NULL,p,NULL,sizeof(buf)))
pstrcat(rname,p);
else
pstrcat(rname,lname);
@@ -1212,16 +1143,16 @@ static int cmd_put(void)
jdblair, 24.jun.98 */
if (!file_exist(lname,&st) &&
(strcmp(lname,"-"))) {
- d_printf("%s does not exist\n",lname);
- return 1;
+ DEBUG(0,("%s does not exist\n",lname));
+ return;
}
}
- return do_put(rname, lname, False);
+ do_put(rname,lname);
}
/*************************************
- File list structure.
+ File list structure
*************************************/
static struct file_list {
@@ -1231,14 +1162,15 @@ static struct file_list {
} *file_list;
/****************************************************************************
- Free a file_list structure.
+ Free a file_list structure
****************************************************************************/
static void free_file_list (struct file_list * list)
{
struct file_list *tmp;
- while (list) {
+ while (list)
+ {
tmp = list;
DLIST_REMOVE(list, list);
SAFE_FREE(tmp->file_path);
@@ -1247,10 +1179,9 @@ static void free_file_list (struct file_list * list)
}
/****************************************************************************
- Seek in a directory/file list until you get something that doesn't start with
- the specified name.
-****************************************************************************/
-
+ seek in a directory/file list until you get something that doesn't start with
+ the specified name
+ ****************************************************************************/
static BOOL seek_list(struct file_list *list, char *name)
{
while (list) {
@@ -1265,22 +1196,18 @@ static BOOL seek_list(struct file_list *list, char *name)
}
/****************************************************************************
- Set the file selection mask.
-****************************************************************************/
-
-static int cmd_select(void)
+ set the file selection mask
+ ****************************************************************************/
+static void cmd_select(void)
{
pstrcpy(fileselection,"");
- next_token_nr(NULL,fileselection,NULL,sizeof(fileselection));
-
- return 0;
+ next_token(NULL,fileselection,NULL,sizeof(fileselection));
}
/****************************************************************************
Recursive file matching function act as find
match must be always set to True when calling this function
****************************************************************************/
-
static int file_find(struct file_list **list, const char *directory,
const char *expression, BOOL match)
{
@@ -1290,24 +1217,21 @@ static int file_find(struct file_list **list, const char *directory,
int ret;
char *path;
BOOL isdir;
- const char *dname;
+ char *dname;
dir = opendir(directory);
- if (!dir)
- return -1;
+ if (!dir) return -1;
while ((dname = readdirname(dir))) {
- if (!strcmp("..", dname))
- continue;
- if (!strcmp(".", dname))
- continue;
+ if (!strcmp("..", dname)) continue;
+ if (!strcmp(".", dname)) continue;
if (asprintf(&path, "%s/%s", directory, dname) <= 0) {
continue;
}
isdir = False;
- if (!match || !gen_fnmatch(expression, dname)) {
+ if (!match || !ms_fnmatch(expression, dname)) {
if (recurse) {
ret = stat(path, &statbuf);
if (ret == 0) {
@@ -1316,7 +1240,7 @@ static int file_find(struct file_list **list, const char *directory,
ret = file_find(list, path, expression, False);
}
} else {
- d_printf("file_find: cannot stat file %s\n", path);
+ DEBUG(0,("file_find: cannot stat file %s\n", path));
}
if (ret == -1) {
@@ -1327,7 +1251,7 @@ static int file_find(struct file_list **list, const char *directory,
}
entry = (struct file_list *) malloc(sizeof (struct file_list));
if (!entry) {
- d_printf("Out of memory in file_find\n");
+ DEBUG(0,("Out of memory in file_find\n"));
closedir(dir);
return -1;
}
@@ -1344,15 +1268,14 @@ static int file_find(struct file_list **list, const char *directory,
}
/****************************************************************************
- mput some files.
-****************************************************************************/
-
-static int cmd_mput(void)
+ mput some files
+ ****************************************************************************/
+static void cmd_mput(void)
{
- pstring buf;
+ fstring buf;
char *p=buf;
- while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
+ while (next_token(NULL,p,NULL,sizeof(buf))) {
int ret;
struct file_list *temp_list;
char *quest, *lname, *rname;
@@ -1390,7 +1313,7 @@ static int cmd_mput(void)
break;
} else { /* Yes */
SAFE_FREE(rname);
- if(asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
+ if (asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
dos_format(rname);
if (!cli_chkpath(cli, rname) &&
!do_mkdir(rname)) {
@@ -1415,70 +1338,64 @@ static int cmd_mput(void)
dos_format(rname);
- do_put(rname, lname, False);
+ do_put(rname, lname);
}
free_file_list(file_list);
SAFE_FREE(quest);
SAFE_FREE(lname);
SAFE_FREE(rname);
}
-
- return 0;
}
-/****************************************************************************
- Cancel a print job.
-****************************************************************************/
-static int do_cancel(int job)
+/****************************************************************************
+ cancel a print job
+ ****************************************************************************/
+static void do_cancel(int job)
{
if (cli_printjob_del(cli, job)) {
- d_printf("Job %d cancelled\n",job);
- return 0;
+ printf("Job %d cancelled\n",job);
} else {
- d_printf("Error cancelling job %d : %s\n",job,cli_errstr(cli));
- return 1;
+ printf("Error cancelling job %d : %s\n",job,cli_errstr(cli));
}
}
-/****************************************************************************
- Cancel a print job.
-****************************************************************************/
-static int cmd_cancel(void)
+/****************************************************************************
+ cancel a print job
+ ****************************************************************************/
+static void cmd_cancel(void)
{
- pstring buf;
+ fstring buf;
int job;
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("cancel <jobid> ...\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+ printf("cancel <jobid> ...\n");
+ return;
}
do {
job = atoi(buf);
do_cancel(job);
- } while (next_token_nr(NULL,buf,NULL,sizeof(buf)));
-
- return 0;
+ } while (next_token(NULL,buf,NULL,sizeof(buf)));
}
-/****************************************************************************
- Print a file.
-****************************************************************************/
-static int cmd_print(void)
+/****************************************************************************
+ print a file
+ ****************************************************************************/
+static void cmd_print(void)
{
pstring lname;
pstring rname;
char *p;
- if (!next_token_nr(NULL,lname,NULL, sizeof(lname))) {
- d_printf("print <filename>\n");
- return 1;
+ if (!next_token(NULL,lname,NULL, sizeof(lname))) {
+ DEBUG(0,("print <filename>\n"));
+ return;
}
pstrcpy(rname,lname);
- p = strrchr_m(rname,'/');
+ p = strrchr(rname,'/');
if (p) {
slprintf(rname, sizeof(rname)-1, "%s-%d", p+1, (int)sys_getpid());
}
@@ -1487,33 +1404,29 @@ static int cmd_print(void)
slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)sys_getpid());
}
- return do_put(rname, lname, False);
+ do_put(rname, lname);
}
+
/****************************************************************************
- Show a print queue entry.
+ show a print queue entry
****************************************************************************/
-
static void queue_fn(struct print_job_info *p)
{
- d_printf("%-6d %-9d %s\n", (int)p->id, (int)p->size, p->name);
+ DEBUG(0,("%-6d %-9d %s\n", (int)p->id, (int)p->size, p->name));
}
/****************************************************************************
- Show a print queue.
+ show a print queue
****************************************************************************/
-
-static int cmd_queue(void)
+static void cmd_queue(void)
{
- cli_print_queue(cli, queue_fn);
-
- return 0;
+ cli_print_queue(cli, queue_fn);
}
/****************************************************************************
- Delete some files.
+delete some files
****************************************************************************/
-
static void do_del(file_info *finfo)
{
pstring mask;
@@ -1525,18 +1438,17 @@ static void do_del(file_info *finfo)
return;
if (!cli_unlink(cli, mask)) {
- d_printf("%s deleting remote file %s\n",cli_errstr(cli),mask);
+ DEBUG(0,("%s deleting remote file %s\n",cli_errstr(cli),mask));
}
}
/****************************************************************************
- Delete some files.
+delete some files
****************************************************************************/
-
-static int cmd_del(void)
+static void cmd_del(void)
{
pstring mask;
- pstring buf;
+ fstring buf;
uint16 attribute = aSYSTEM | aHIDDEN;
if (recurse)
@@ -1544,191 +1456,178 @@ static int cmd_del(void)
pstrcpy(mask,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("del <filename>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0,("del <filename>\n"));
+ return;
}
pstrcat(mask,buf);
do_list(mask, attribute,do_del,False,False);
-
- return 0;
}
/****************************************************************************
****************************************************************************/
-
-static int cmd_open(void)
+static void cmd_open(void)
{
pstring mask;
- pstring buf;
+ fstring buf;
pstrcpy(mask,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("open <filename>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0,("open <filename>\n"));
+ return;
}
pstrcat(mask,buf);
cli_open(cli, mask, O_RDWR, DENY_ALL);
-
- return 0;
}
/****************************************************************************
- Remove a directory.
+remove a directory
****************************************************************************/
-
-static int cmd_rmdir(void)
+static void cmd_rmdir(void)
{
pstring mask;
- pstring buf;
+ fstring buf;
pstrcpy(mask,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("rmdir <dirname>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0,("rmdir <dirname>\n"));
+ return;
}
pstrcat(mask,buf);
if (!cli_rmdir(cli, mask)) {
- d_printf("%s removing remote directory file %s\n",
- cli_errstr(cli),mask);
- }
-
- return 0;
+ DEBUG(0,("%s removing remote directory file %s\n",
+ cli_errstr(cli),mask));
+ }
}
/****************************************************************************
UNIX hardlink.
****************************************************************************/
-static int cmd_link(void)
+static void cmd_link(void)
{
- pstring oldname,newname;
- pstring buf,buf2;
+ pstring src,dest;
+ fstring buf,buf2;
if (!SERVER_HAS_UNIX_CIFS(cli)) {
- d_printf("Server doesn't support UNIX CIFS calls.\n");
- return 1;
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
}
- pstrcpy(oldname,cur_dir);
- pstrcpy(newname,cur_dir);
+ pstrcpy(src,cur_dir);
+ pstrcpy(dest,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
- d_printf("link <oldname> <newname>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("link <src> <dest>\n"));
+ return;
}
- pstrcat(oldname,buf);
- pstrcat(newname,buf2);
+ pstrcat(src,buf);
+ pstrcat(dest,buf2);
- if (!cli_unix_hardlink(cli, oldname, newname)) {
- d_printf("%s linking files (%s -> %s)\n", cli_errstr(cli), newname, oldname);
- return 1;
+ if (!cli_unix_hardlink(cli, src, dest)) {
+ DEBUG(0,("%s linking files (%s -> %s)\n",
+ cli_errstr(cli), src, dest));
+ return;
}
-
- return 0;
}
/****************************************************************************
UNIX symlink.
****************************************************************************/
-static int cmd_symlink(void)
+static void cmd_symlink(void)
{
- pstring oldname,newname;
- pstring buf,buf2;
+ pstring src,dest;
+ fstring buf,buf2;
if (!SERVER_HAS_UNIX_CIFS(cli)) {
- d_printf("Server doesn't support UNIX CIFS calls.\n");
- return 1;
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
}
- pstrcpy(oldname,cur_dir);
- pstrcpy(newname,cur_dir);
+ pstrcpy(src,cur_dir);
+ pstrcpy(dest,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
- d_printf("symlink <oldname> <newname>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("symlink <src> <dest>\n"));
+ return;
}
- pstrcat(oldname,buf);
- pstrcat(newname,buf2);
-
- if (!cli_unix_symlink(cli, oldname, newname)) {
- d_printf("%s symlinking files (%s -> %s)\n",
- cli_errstr(cli), newname, oldname);
- return 1;
- }
+ pstrcat(src,buf);
+ pstrcat(dest,buf2);
- return 0;
+ if (!cli_unix_symlink(cli, src, dest)) {
+ DEBUG(0,("%s symlinking files (%s -> %s)\n",
+ cli_errstr(cli), src, dest));
+ return;
+ }
}
/****************************************************************************
UNIX chmod.
****************************************************************************/
-static int cmd_chmod(void)
+static void cmd_chmod(void)
{
pstring src;
mode_t mode;
- pstring buf, buf2;
+ fstring buf, buf2;
if (!SERVER_HAS_UNIX_CIFS(cli)) {
- d_printf("Server doesn't support UNIX CIFS calls.\n");
- return 1;
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
}
pstrcpy(src,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
- d_printf("chmod mode file\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("chmod mode file\n"));
+ return;
}
mode = (mode_t)strtol(buf, NULL, 8);
pstrcat(src,buf2);
if (!cli_unix_chmod(cli, src, mode)) {
- d_printf("%s chmod file %s 0%o\n",
- cli_errstr(cli), src, (unsigned int)mode);
- return 1;
- }
-
- return 0;
+ DEBUG(0,("%s chmod file %s 0%o\n",
+ cli_errstr(cli), src, (unsigned int)mode));
+ return;
+ }
}
/****************************************************************************
UNIX chown.
****************************************************************************/
-static int cmd_chown(void)
+static void cmd_chown(void)
{
pstring src;
uid_t uid;
gid_t gid;
- pstring buf, buf2, buf3;
+ fstring buf, buf2, buf3;
if (!SERVER_HAS_UNIX_CIFS(cli)) {
- d_printf("Server doesn't support UNIX CIFS calls.\n");
- return 1;
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
}
pstrcpy(src,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2)) ||
- !next_token_nr(NULL,buf3,NULL, sizeof(buf3))) {
- d_printf("chown uid gid file\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2)) ||
+ !next_token(NULL,buf3,NULL, sizeof(buf3))) {
+ DEBUG(0,("chown uid gid file\n"));
+ return;
}
uid = (uid_t)atoi(buf);
@@ -1736,95 +1635,59 @@ static int cmd_chown(void)
pstrcat(src,buf3);
if (!cli_unix_chown(cli, src, uid, gid)) {
- d_printf("%s chown file %s uid=%d, gid=%d\n",
- cli_errstr(cli), src, (int)uid, (int)gid);
- return 1;
+ DEBUG(0,("%s chown file %s uid=%d, gid=%d\n",
+ cli_errstr(cli), src, (int)uid, (int)gid));
+ return;
}
-
- return 0;
}
/****************************************************************************
- Rename some file.
+rename some files
****************************************************************************/
-
-static int cmd_rename(void)
+static void cmd_rename(void)
{
pstring src,dest;
- pstring buf,buf2;
+ fstring buf,buf2;
pstrcpy(src,cur_dir);
pstrcpy(dest,cur_dir);
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
- d_printf("rename <src> <dest>\n");
- return 1;
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("rename <src> <dest>\n"));
+ return;
}
pstrcat(src,buf);
pstrcat(dest,buf2);
if (!cli_rename(cli, src, dest)) {
- d_printf("%s renaming files\n",cli_errstr(cli));
- return 1;
- }
-
- return 0;
+ DEBUG(0,("%s renaming files\n",cli_errstr(cli)));
+ return;
+ }
}
-/****************************************************************************
- Hard link files using the NT call.
-****************************************************************************/
-
-static int cmd_hardlink(void)
-{
- pstring src,dest;
- pstring buf,buf2;
-
- pstrcpy(src,cur_dir);
- pstrcpy(dest,cur_dir);
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
- !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
- d_printf("hardlink <src> <dest>\n");
- return 1;
- }
-
- pstrcat(src,buf);
- pstrcat(dest,buf2);
-
- if (!cli_nt_hardlink(cli, src, dest)) {
- d_printf("%s doing an NT hard link of files\n",cli_errstr(cli));
- return 1;
- }
-
- return 0;
-}
/****************************************************************************
- Toggle the prompt flag.
+toggle the prompt flag
****************************************************************************/
-
-static int cmd_prompt(void)
+static void cmd_prompt(void)
{
prompt = !prompt;
DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
-
- return 1;
}
+
/****************************************************************************
- Set the newer than time.
+set the newer than time
****************************************************************************/
-
-static int cmd_newer(void)
+static void cmd_newer(void)
{
- pstring buf;
+ fstring buf;
BOOL ok;
SMB_STRUCT_STAT sbuf;
- ok = next_token_nr(NULL,buf,NULL,sizeof(buf));
+ ok = next_token(NULL,buf,NULL,sizeof(buf));
if (ok && (sys_stat(buf,&sbuf) == 0)) {
newer_than = sbuf.st_mtime;
DEBUG(1,("Getting files newer than %s",
@@ -1833,77 +1696,64 @@ static int cmd_newer(void)
newer_than = 0;
}
- if (ok && newer_than == 0) {
- d_printf("Error setting newer-than time\n");
- return 1;
- }
-
- return 0;
+ if (ok && newer_than == 0)
+ DEBUG(0,("Error setting newer-than time\n"));
}
/****************************************************************************
- Set the archive level.
+set the archive level
****************************************************************************/
-
-static int cmd_archive(void)
+static void cmd_archive(void)
{
- pstring buf;
+ fstring buf;
- if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (next_token(NULL,buf,NULL,sizeof(buf))) {
archive_level = atoi(buf);
} else
- d_printf("Archive level is %d\n",archive_level);
-
- return 0;
+ DEBUG(0,("Archive level is %d\n",archive_level));
}
/****************************************************************************
- Toggle the lowercaseflag.
+toggle the lowercaseflag
****************************************************************************/
-
-static int cmd_lowercase(void)
+static void cmd_lowercase(void)
{
lowercase = !lowercase;
DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
-
- return 0;
}
+
+
+
/****************************************************************************
- Toggle the recurse flag.
+toggle the recurse flag
****************************************************************************/
-
-static int cmd_recurse(void)
+static void cmd_recurse(void)
{
recurse = !recurse;
DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
-
- return 0;
}
/****************************************************************************
- Toggle the translate flag.
+toggle the translate flag
****************************************************************************/
-
-static int cmd_translate(void)
+static void cmd_translate(void)
{
translation = !translation;
DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
translation?"on":"off"));
-
- return 0;
}
+
/****************************************************************************
- Do a printmode command.
+do a printmode command
****************************************************************************/
-
-static int cmd_printmode(void)
+static void cmd_printmode(void)
{
fstring buf;
fstring mode;
- if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (next_token(NULL,buf,NULL,sizeof(buf))) {
if (strequal(buf,"text")) {
printmode = 0;
} else {
@@ -1914,7 +1764,8 @@ static int cmd_printmode(void)
}
}
- switch(printmode) {
+ switch(printmode)
+ {
case 0:
fstrcpy(mode,"text");
break;
@@ -1924,96 +1775,27 @@ static int cmd_printmode(void)
default:
slprintf(mode,sizeof(mode)-1,"%d",printmode);
break;
- }
+ }
DEBUG(2,("the printmode is now %s\n",mode));
-
- return 0;
}
/****************************************************************************
- Do the lcd command.
- ****************************************************************************/
-
-static int cmd_lcd(void)
+do the lcd command
+****************************************************************************/
+static void cmd_lcd(void)
{
- pstring buf;
+ fstring buf;
pstring d;
- if (next_token_nr(NULL,buf,NULL,sizeof(buf)))
+ if (next_token(NULL,buf,NULL,sizeof(buf)))
chdir(buf);
DEBUG(2,("the local directory is now %s\n",sys_getwd(d)));
-
- return 0;
-}
-
-/****************************************************************************
- Get a file restarting at end of local file.
- ****************************************************************************/
-
-static int cmd_reget(void)
-{
- pstring local_name;
- pstring remote_name;
- char *p;
-
- pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, "\\");
-
- p = remote_name + strlen(remote_name);
-
- if (!next_token_nr(NULL, p, NULL, sizeof(remote_name) - strlen(remote_name))) {
- d_printf("reget <filename>\n");
- return 1;
- }
- pstrcpy(local_name, p);
- dos_clean_name(remote_name);
-
- next_token_nr(NULL, local_name, NULL, sizeof(local_name));
-
- return do_get(remote_name, local_name, True);
}
/****************************************************************************
- Put a file restarting at end of local file.
- ****************************************************************************/
-
-static int cmd_reput(void)
-{
- pstring local_name;
- pstring remote_name;
- pstring buf;
- char *p = buf;
- SMB_STRUCT_STAT st;
-
- pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, "\\");
-
- if (!next_token_nr(NULL, p, NULL, sizeof(buf))) {
- d_printf("reput <filename>\n");
- return 1;
- }
- pstrcpy(local_name, p);
-
- if (!file_exist(local_name, &st)) {
- d_printf("%s does not exist\n", local_name);
- return 1;
- }
-
- if (next_token_nr(NULL, p, NULL, sizeof(buf)))
- pstrcat(remote_name, p);
- else
- pstrcat(remote_name, local_name);
-
- dos_clean_name(remote_name);
-
- return do_put(remote_name, local_name, True);
-}
-
-/****************************************************************************
- List a share name.
- ****************************************************************************/
-
+list a share name
+****************************************************************************/
static void browse_fn(const char *name, uint32 m,
const char *comment, void *state)
{
@@ -2032,129 +1814,54 @@ static void browse_fn(const char *name, uint32 m,
case STYPE_IPC:
fstrcpy(typestr,"IPC"); break;
}
- /* FIXME: If the remote machine returns non-ascii characters
- in any of these fields, they can corrupt the output. We
- should remove them. */
- if (!grepable) {
- d_printf("\t%-15s %-10.10s%s\n",
- name,typestr,comment);
- } else {
- d_printf ("%s|%s|%s\n",typestr,name,comment);
- }
+
+ printf("\t%-15.15s%-10.10s%s\n",
+ name, typestr,comment);
}
+
/****************************************************************************
- Try and browse available connections on a host.
+try and browse available connections on a host
****************************************************************************/
-
static BOOL browse_host(BOOL sort)
{
int ret;
- if (!grepable) {
- d_printf("\n\tSharename Type Comment\n");
- d_printf("\t--------- ---- -------\n");
- }
+
+ printf("\n\tSharename Type Comment\n");
+ printf("\t--------- ---- -------\n");
if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1)
- d_printf("Error returning browse list: %s\n", cli_errstr(cli));
+ printf("Error returning browse list: %s\n", cli_errstr(cli));
return (ret != -1);
}
/****************************************************************************
- List a server name.
+list a server name
****************************************************************************/
-
static void server_fn(const char *name, uint32 m,
const char *comment, void *state)
{
-
- if (!grepable){
- d_printf("\t%-16s %s\n", name, comment);
- } else {
- d_printf("%s|%s|%s\n",(char *)state, name, comment);
- }
+ printf("\t%-16.16s %s\n", name, comment);
}
/****************************************************************************
- Try and browse available connections on a host.
+try and browse available connections on a host
****************************************************************************/
-
-static BOOL list_servers(const char *wk_grp)
-{
- if (!cli->server_domain)
- return False;
-
- if (!grepable) {
- d_printf("\n\tServer Comment\n");
- d_printf("\t--------- -------\n");
- };
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn,
- "Server");
-
- if (!grepable) {
- d_printf("\n\tWorkgroup Master\n");
- d_printf("\t--------- -------\n");
- };
-
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM,
- server_fn, "Workgroup");
- return True;
-}
-
-/****************************************************************************
- Print or set current VUID
-****************************************************************************/
-
-static int cmd_vuid(void)
-{
- fstring buf;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("Current VUID is %d\n", cli->vuid);
- return 0;
- }
-
- cli->vuid = atoi(buf);
- return 0;
-}
-
-/****************************************************************************
- Setup a new VUID, by issuing a session setup
-****************************************************************************/
-
-static int cmd_logon(void)
+static BOOL list_servers(char *wk_grp)
{
- pstring l_username, l_password;
- pstring buf,buf2;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- d_printf("logon <username> [<password>]\n");
- return 0;
- }
+ if (!cli->server_domain) return False;
- pstrcpy(l_username, buf);
+ printf("\n\tServer Comment\n");
+ printf("\t--------- -------\n");
- if (!next_token_nr(NULL,buf2,NULL,sizeof(buf))) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(l_password, pass);
- got_pass = 1;
- }
- } else {
- pstrcpy(l_password, buf2);
- }
+ cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL);
- if (!cli_session_setup(cli, l_username,
- l_password, strlen(l_password),
- l_password, strlen(l_password),
- lp_workgroup())) {
- d_printf("session setup failed: %s\n", cli_errstr(cli));
- return -1;
- }
+ printf("\n\tWorkgroup Master\n");
+ printf("\t--------- -------\n");
- d_printf("Current VUID is %d\n", cli->vuid);
- return 0;
+ cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL);
+ return True;
}
/* Some constants for completing filename arguments */
@@ -2168,13 +1875,14 @@ static int cmd_logon(void)
* field is NULL, and NULL in that field is used in process_tok()
* (below) to indicate the end of the list. crh
*/
-static struct
+struct
{
const char *name;
- int (*fn)(void);
+ void (*fn)(void);
const char *description;
- char compl_args[2]; /* Completion argument info */
-} commands[] = {
+ const char compl_args[2]; /* Completion argument info */
+} commands[] =
+{
{"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}},
{"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
@@ -2188,11 +1896,10 @@ static struct
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
- {"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
{"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
- {"link",cmd_link,"<oldname> <newname> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"link",cmd_link,"<src> <dest> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}},
{"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},
{"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
@@ -2213,30 +1920,26 @@ static struct
{"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
{"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},
- {"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
{"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
- {"reput",cmd_reput,"<local name> [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}},
{"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
{"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
{"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
- {"symlink",cmd_symlink,"<oldname> <newname> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"symlink",cmd_symlink,"<src> <dest> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}},
{"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
{"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
- {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
- {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}},
- {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
-
+ {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
+
/* Yes, this must be here, see crh's comment above. */
{"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
- {NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}}
+ {"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
-/*******************************************************************
- Lookup a command string in the list of commands, including
- abbreviations.
-******************************************************************/
-static int process_tok(pstring tok)
+/*******************************************************************
+ lookup a command string in the list of commands, including
+ abbreviations
+ ******************************************************************/
+static int process_tok(fstring tok)
{
int i = 0, matches = 0;
int cmd=0;
@@ -2263,59 +1966,54 @@ static int process_tok(pstring tok)
}
/****************************************************************************
- Help.
+help
****************************************************************************/
-
-static int cmd_help(void)
+static void cmd_help(void)
{
int i=0,j;
- pstring buf;
+ fstring buf;
- if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (next_token(NULL,buf,NULL,sizeof(buf))) {
if ((i = process_tok(buf)) >= 0)
- d_printf("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);
+ DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
} else {
while (commands[i].description) {
for (j=0; commands[i].description && (j<5); j++) {
- d_printf("%-15s",commands[i].name);
+ DEBUG(0,("%-15s",commands[i].name));
i++;
}
- d_printf("\n");
+ DEBUG(0,("\n"));
}
}
- return 0;
}
/****************************************************************************
- Process a -c command string.
+process a -c command string
****************************************************************************/
-
-static int process_command_string(char *cmd)
+static void process_command_string(char *cmd)
{
pstring line;
const char *ptr;
- int rc = 0;
/* establish the connection if not already */
if (!cli) {
cli = do_connect(desthost, service);
if (!cli)
- return 0;
+ return;
}
while (cmd[0] != '\0') {
char *p;
- pstring tok;
+ fstring tok;
int i;
- if ((p = strchr_m(cmd, ';')) == 0) {
+ if ((p = strchr(cmd, ';')) == 0) {
strncpy(line, cmd, 999);
line[1000] = '\0';
cmd += strlen(cmd);
} else {
- if (p - cmd > 999)
- p = cmd + 999;
+ if (p - cmd > 999) p = cmd + 999;
strncpy(line, cmd, p - cmd);
line[p - cmd] = '\0';
cmd = p + 1;
@@ -2323,205 +2021,56 @@ static int process_command_string(char *cmd)
/* and get the first part of the command */
ptr = line;
- if (!next_token_nr(&ptr,tok,NULL,sizeof(tok))) continue;
+ if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
if ((i = process_tok(tok)) >= 0) {
- rc = commands[i].fn();
+ commands[i].fn();
} else if (i == -2) {
- d_printf("%s: command abbreviation ambiguous\n",tok);
+ DEBUG(0,("%s: command abbreviation ambiguous\n",tok));
} else {
- d_printf("%s: command not found\n",tok);
+ DEBUG(0,("%s: command not found\n",tok));
}
}
-
- return rc;
}
+/****************************************************************************
+handle completion of commands for readline
+****************************************************************************/
+static char **completion_fn(const char *text, int start, int end)
+{
#define MAX_COMPLETIONS 100
-
-typedef struct {
- pstring dirmask;
char **matches;
- int count, samelen;
- const char *text;
- int len;
-} completion_remote_t;
+ int i, count=0;
-static void completion_remote_filter(file_info *f, const char *mask, void *state)
-{
- completion_remote_t *info = (completion_remote_t *)state;
+ /* for words not at the start of the line fallback to filename completion */
+ if (start) return NULL;
- if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (strcmp(f->name, ".") != 0) && (strcmp(f->name, "..") != 0)) {
- if ((info->dirmask[0] == 0) && !(f->mode & aDIR))
- info->matches[info->count] = strdup(f->name);
- else {
- pstring tmp;
+ matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
+ if (!matches) return NULL;
- if (info->dirmask[0] != 0)
- pstrcpy(tmp, info->dirmask);
- else
- tmp[0] = 0;
- pstrcat(tmp, f->name);
- if (f->mode & aDIR)
- pstrcat(tmp, "/");
- info->matches[info->count] = strdup(tmp);
- }
- if (info->matches[info->count] == NULL)
- return;
- if (f->mode & aDIR)
- smb_readline_ca_char(0);
+ matches[count++] = strdup(text);
+ if (!matches[0]) return NULL;
- if (info->count == 1)
- info->samelen = strlen(info->matches[info->count]);
- else
- while (strncmp(info->matches[info->count], info->matches[info->count-1], info->samelen) != 0)
- info->samelen--;
- info->count++;
+ for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) {
+ if (strncmp(text, commands[i].name, strlen(text)) == 0) {
+ matches[count] = strdup(commands[i].name);
+ if (!matches[count]) return NULL;
+ count++;
+ }
}
-}
-static char **remote_completion(const char *text, int len)
-{
- pstring dirmask;
- int i;
- completion_remote_t info = { "", NULL, 1, 0, NULL, 0 };
-
- /* can't have non-static intialisation on Sun CC, so do it
- at run time here */
- info.samelen = len;
- info.text = text;
- info.len = len;
-
- if (len >= PATH_MAX)
- return(NULL);
-
- info.matches = (char **)malloc(sizeof(info.matches[0])*MAX_COMPLETIONS);
- if (!info.matches) return NULL;
- info.matches[0] = NULL;
-
- for (i = len-1; i >= 0; i--)
- if ((text[i] == '/') || (text[i] == '\\'))
- break;
- info.text = text+i+1;
- info.samelen = info.len = len-i-1;
-
- if (i > 0) {
- strncpy(info.dirmask, text, i+1);
- info.dirmask[i+1] = 0;
- pstr_sprintf(dirmask, "%s%*s*", cur_dir, i-1, text);
- } else
- pstr_sprintf(dirmask, "%s*", cur_dir);
-
- if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0)
- goto cleanup;
-
- if (info.count == 2)
- info.matches[0] = strdup(info.matches[1]);
- else {
- info.matches[0] = malloc(info.samelen+1);
- if (!info.matches[0])
- goto cleanup;
- strncpy(info.matches[0], info.matches[1], info.samelen);
- info.matches[0][info.samelen] = 0;
+ if (count == 2) {
+ SAFE_FREE(matches[0]);
+ matches[0] = strdup(matches[1]);
}
- info.matches[info.count] = NULL;
- return info.matches;
-
-cleanup:
- for (i = 0; i < info.count; i++)
- free(info.matches[i]);
- free(info.matches);
- return NULL;
+ matches[count] = NULL;
+ return matches;
}
-static char **completion_fn(const char *text, int start, int end)
-{
- smb_readline_ca_char(' ');
-
- if (start) {
- const char *buf, *sp;
- int i;
- char compl_type;
-
- buf = smb_readline_get_line_buffer();
- if (buf == NULL)
- return NULL;
-
- sp = strchr(buf, ' ');
- if (sp == NULL)
- return NULL;
-
- for (i = 0; commands[i].name; i++)
- if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0))
- break;
- if (commands[i].name == NULL)
- return NULL;
-
- while (*sp == ' ')
- sp++;
-
- if (sp == (buf + start))
- compl_type = commands[i].compl_args[0];
- else
- compl_type = commands[i].compl_args[1];
-
- if (compl_type == COMPL_REMOTE)
- return remote_completion(text, end - start);
- else /* fall back to local filename completion */
- return NULL;
- } else {
- char **matches;
- int i, len, samelen, count=1;
-
- matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
- if (!matches) return NULL;
- matches[0] = NULL;
-
- len = strlen(text);
- for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) {
- if (strncmp(text, commands[i].name, len) == 0) {
- matches[count] = strdup(commands[i].name);
- if (!matches[count])
- goto cleanup;
- if (count == 1)
- samelen = strlen(matches[count]);
- else
- while (strncmp(matches[count], matches[count-1], samelen) != 0)
- samelen--;
- count++;
- }
- }
-
- switch (count) {
- case 0: /* should never happen */
- case 1:
- goto cleanup;
- case 2:
- matches[0] = strdup(matches[1]);
- break;
- default:
- matches[0] = malloc(samelen+1);
- if (!matches[0])
- goto cleanup;
- strncpy(matches[0], matches[1], samelen);
- matches[0][samelen] = 0;
- }
- matches[count] = NULL;
- return matches;
-
-cleanup:
- for (i = 0; i < count; i++)
- free(matches[i]);
-
- free(matches);
- return NULL;
- }
-}
/****************************************************************************
- Make sure we swallow keepalives during idle time.
+make sure we swallow keepalives during idle time
****************************************************************************/
-
static void readline_callback(void)
{
fd_set fds;
@@ -2531,13 +2080,11 @@ static void readline_callback(void)
t = time(NULL);
- if (t - last_t < 5)
- return;
+ if (t - last_t < 5) return;
last_t = t;
again:
-
if (cli->fd == -1)
return;
@@ -2560,28 +2107,25 @@ static void readline_callback(void)
cli_chkpath(cli, "\\");
}
+
/****************************************************************************
- Process commands on stdin.
+process commands on stdin
****************************************************************************/
-
static void process_stdin(void)
{
const char *ptr;
while (1) {
- pstring tok;
- pstring the_prompt;
- char *cline;
- pstring line;
+ fstring tok;
+ fstring the_prompt;
+ char *line;
int i;
/* display a prompt */
slprintf(the_prompt, sizeof(the_prompt)-1, "smb: %s> ", cur_dir);
- cline = smb_readline(the_prompt, readline_callback, completion_fn);
-
- if (!cline) break;
-
- pstrcpy(line, cline);
+ line = smb_readline(the_prompt, readline_callback, completion_fn);
+
+ if (!line) break;
/* special case - first char is ! */
if (*line == '!') {
@@ -2591,37 +2135,37 @@ static void process_stdin(void)
/* and get the first part of the command */
ptr = line;
- if (!next_token_nr(&ptr,tok,NULL,sizeof(tok))) continue;
+ if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
if ((i = process_tok(tok)) >= 0) {
commands[i].fn();
} else if (i == -2) {
- d_printf("%s: command abbreviation ambiguous\n",tok);
+ DEBUG(0,("%s: command abbreviation ambiguous\n",tok));
} else {
- d_printf("%s: command not found\n",tok);
+ DEBUG(0,("%s: command not found\n",tok));
}
}
}
+
/*****************************************************
- Return a connection to a server.
+return a connection to a server
*******************************************************/
-
-static struct cli_state *do_connect(const char *server, const char *share)
+struct cli_state *do_connect(const char *server, const char *share)
{
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n;
struct in_addr ip;
- pstring servicename;
+ fstring servicename;
char *sharename;
/* make a copy so we don't modify the global string 'service' */
- pstrcpy(servicename, share);
+ safe_strcpy(servicename, share, sizeof(servicename)-1);
sharename = servicename;
if (*sharename == '\\') {
server = sharename+2;
- sharename = strchr_m(server,'\\');
+ sharename = strchr(server,'\\');
if (!sharename) return NULL;
*sharename = 0;
sharename++;
@@ -2631,7 +2175,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
zero_ip(&ip);
- make_nmb_name(&calling, global_myname(), 0x0);
+ make_nmb_name(&calling, global_myname, 0x0);
make_nmb_name(&called , server, name_type);
again:
@@ -2639,23 +2183,22 @@ static struct cli_state *do_connect(const char *server, const char *share)
if (have_ip) ip = dest_ip;
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) ||
+ if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) == 0) ||
!cli_connect(c, server_n, &ip)) {
- d_printf("Connection to %s failed\n", server_n);
+ DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
c->protocol = max_protocol;
- c->use_kerberos = use_kerberos;
- cli_setup_signing_state(c, cmdline_auth_info.signing_state);
-
+ if (timeout_msec)
+ c->timeout = timeout_msec;
if (!cli_session_request(c, &calling, &called)) {
char *p;
- d_printf("session request to %s failed (%s)\n",
- called.name, cli_errstr(c));
+ DEBUG(0,("session request to %s failed (%s)\n",
+ called.name, cli_errstr(c)));
cli_shutdown(c);
- if ((p=strchr_m(called.name, '.'))) {
+ if ((p=strchr(called.name, '.'))) {
*p = 0;
goto again;
}
@@ -2669,7 +2212,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
DEBUG(4,(" session request ok\n"));
if (!cli_negprot(c)) {
- d_printf("protocol negotiation failed\n");
+ DEBUG(0,("protocol negotiation failed\n"));
cli_shutdown(c);
return NULL;
}
@@ -2678,39 +2221,40 @@ static struct cli_state *do_connect(const char *server, const char *share)
char *pass = getpass("Password: ");
if (pass) {
pstrcpy(password, pass);
- got_pass = 1;
}
}
if (!cli_session_setup(c, username,
password, strlen(password),
password, strlen(password),
- lp_workgroup())) {
+ workgroup)) {
/* if a password was not supplied then try again with a null username */
- if (password[0] || !username[0] || use_kerberos ||
- !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) {
- d_printf("session setup failed: %s\n", cli_errstr(c));
- if (NT_STATUS_V(cli_nt_error(c)) ==
- NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
- d_printf("did you forget to run kinit?\n");
+ if (password[0] || !username[0] ||
+ !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
+ DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
return NULL;
}
- d_printf("Anonymous login successful\n");
+ DEBUG(0,("Anonymous login successful\n"));
}
- if (*c->server_domain) {
+ /*
+ * These next two lines are needed to emulate
+ * old client behaviour for people who have
+ * scripts based on client output.
+ * QUESTION ? Do we want to have a 'client compatibility
+ * mode to turn these on/off ? JRA.
+ */
+
+ if (*c->server_domain || *c->server_os || *c->server_type)
DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
c->server_domain,c->server_os,c->server_type));
- } else if (*c->server_os || *c->server_type){
- DEBUG(1,("OS=[%s] Server=[%s]\n",
- c->server_os,c->server_type));
- }
+
DEBUG(4,(" session setup ok\n"));
if (!cli_send_tconX(c, sharename, "?????",
password, strlen(password)+1)) {
- d_printf("tree connect failed: %s\n", cli_errstr(c));
+ DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
return NULL;
}
@@ -2720,59 +2264,136 @@ static struct cli_state *do_connect(const char *server, const char *share)
return c;
}
+
/****************************************************************************
- Process commands from the client.
+ process commands from the client
****************************************************************************/
-
-static int process(char *base_directory)
+static BOOL process(char *base_directory)
{
- int rc = 0;
-
cli = do_connect(desthost, service);
if (!cli) {
- return 1;
+ return(False);
}
if (*base_directory) do_cd(base_directory);
if (cmdstr) {
- rc = process_command_string(cmdstr);
+ process_command_string(cmdstr);
} else {
process_stdin();
}
cli_shutdown(cli);
- return rc;
+ return(True);
}
/****************************************************************************
- Handle a -L query.
+usage on the program
****************************************************************************/
-
-static int do_host_query(char *query_host)
+static void usage(char *pname)
{
- cli = do_connect(query_host, "IPC$");
- if (!cli)
- return 1;
+ DEBUG(0,("Usage: %s service <password> [options]", pname));
- browse_host(True);
+ DEBUG(0,("\nVersion %s\n",VERSION));
+ DEBUG(0,("\t-s smb.conf pathname to smb.conf file\n"));
+ DEBUG(0,("\t-O socket_options socket options to use\n"));
+ DEBUG(0,("\t-R name resolve order use these name resolution services only\n"));
+ DEBUG(0,("\t-M host send a winpopup message to the host\n"));
+ DEBUG(0,("\t-i scope use this NetBIOS scope\n"));
+ DEBUG(0,("\t-N don't ask for a password\n"));
+ DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
+ DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
+ DEBUG(0,("\t-P connect to service as a printer\n"));
+ DEBUG(0,("\t-p port connect to the specified port\n"));
+ DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
+ DEBUG(0,("\t-h Print this help message.\n"));
+ DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
+ DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
+ DEBUG(0,("\t-U username set the network username\n"));
+ DEBUG(0,("\t-L host get a list of shares available on a host\n"));
+ DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
+ DEBUG(0,("\t-m max protocol set the max protocol level\n"));
+ DEBUG(0,("\t-A filename get the credentials from a file\n"));
+ DEBUG(0,("\t-W workgroup set the workgroup name\n"));
+ DEBUG(0,("\t-T<c|x>IXFqgbNan command line tar\n"));
+ DEBUG(0,("\t-D directory start from directory\n"));
+ DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
+ DEBUG(0,("\t-b xmit/send buffer changes the transmit/send buffer (default: 65520)\n"));
+ DEBUG(0,("\n"));
+}
- if (port != 139) {
- /* Workgroups simply don't make sense over anything
- else but port 139... */
+/****************************************************************************
+get a password from a a file or file descriptor
+exit on failure
+****************************************************************************/
+static void get_password_file(void)
+{
+ int fd = -1;
+ char *p;
+ BOOL close_it = False;
+ pstring spec;
+ char pass[128];
+
+ if ((p = getenv("PASSWD_FD")) != NULL) {
+ pstrcpy(spec, "descriptor ");
+ pstrcat(spec, p);
+ sscanf(p, "%d", &fd);
+ close_it = False;
+ } else if ((p = getenv("PASSWD_FILE")) != NULL) {
+ fd = sys_open(p, O_RDONLY, 0);
+ pstrcpy(spec, p);
+ if (fd < 0) {
+ fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
+ spec, strerror(errno));
+ exit(1);
+ }
+ close_it = True;
+ }
- cli_shutdown(cli);
- port = 139;
- cli = do_connect(query_host, "IPC$");
+ for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
+ p && p - pass < sizeof(pass);) {
+ switch (read(fd, p, 1)) {
+ case 1:
+ if (*p != '\n' && *p != '\0') {
+ *++p = '\0'; /* advance p, and null-terminate pass */
+ break;
+ }
+ case 0:
+ if (p - pass) {
+ *p = '\0'; /* null-terminate it, just in case... */
+ p = NULL; /* then force the loop condition to become false */
+ break;
+ } else {
+ fprintf(stderr, "Error reading password from file %s: %s\n",
+ spec, "empty password\n");
+ exit(1);
+ }
+
+ default:
+ fprintf(stderr, "Error reading password from file %s: %s\n",
+ spec, strerror(errno));
+ exit(1);
+ }
}
+ pstrcpy(password, pass);
+ if (close_it)
+ close(fd);
+}
+
- if (cli == NULL) {
- d_printf("NetBIOS over TCP disabled -- no workgroup available\n");
+
+/****************************************************************************
+handle a -L query
+****************************************************************************/
+static int do_host_query(char *query_host)
+{
+ cli = do_connect(query_host, "IPC$");
+ if (!cli)
return 1;
- }
- list_servers(lp_workgroup());
+ browse_host(True);
+ list_servers(workgroup);
cli_shutdown(cli);
@@ -2781,9 +2402,8 @@ static int do_host_query(char *query_host)
/****************************************************************************
- Handle a tar operation.
+handle a tar operation
****************************************************************************/
-
static int do_tar_op(char *base_directory)
{
int ret;
@@ -2814,27 +2434,30 @@ static int do_message_op(void)
{
struct in_addr ip;
struct nmb_name called, calling;
- fstring server_name;
- char name_type_hex[10];
- make_nmb_name(&calling, global_myname(), 0x0);
- make_nmb_name(&called , desthost, name_type);
+ zero_ip(&ip);
- fstrcpy(server_name, desthost);
- snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
- fstrcat(server_name, name_type_hex);
+ make_nmb_name(&calling, global_myname, 0x0);
+ make_nmb_name(&called , desthost, name_type);
- zero_ip(&ip);
- if (have_ip) ip = dest_ip;
+ zero_ip(&ip);
+ if (have_ip)
+ ip = dest_ip;
+ else if (name_type != 0x20) {
+ /* We must do our own resolve name here as the nametype is #0x3, not #0x20. */
+ if (!resolve_name(desthost, &ip, name_type)) {
+ DEBUG(0,("Cannot resolve name %s#0x%x\n", desthost, name_type));
+ return 1;
+ }
+ }
- if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) != port) ||
- !cli_connect(cli, server_name, &ip)) {
- d_printf("Connection to %s failed\n", desthost);
+ if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) == 0) || !cli_connect(cli, desthost, &ip)) {
+ DEBUG(0,("Connection to %s failed\n", desthost));
return 1;
}
if (!cli_session_request(cli, &calling, &called)) {
- d_printf("session request failed\n");
+ DEBUG(0,("session request failed\n"));
cli_shutdown(cli);
return 1;
}
@@ -2849,44 +2472,22 @@ static int do_message_op(void)
/****************************************************************************
main program
****************************************************************************/
-
int main(int argc,char *argv[])
{
- extern BOOL AllowDebugChange;
- extern BOOL override_logfile;
- pstring base_directory;
+ fstring base_directory;
+ char *pname = argv[0];
int opt;
+ extern FILE *dbf;
+ extern char *optarg;
+ extern int optind;
pstring query_host;
BOOL message = False;
extern char tar_type;
+ static pstring servicesf = CONFIGFILE;
pstring term_code;
- static const char *new_name_resolve_order = NULL;
- poptContext pc;
+ pstring new_name_resolve_order;
+ pstring logfile;
char *p;
- int rc = 0;
- fstring new_workgroup;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
-
- { "name-resolve", 'R', POPT_ARG_STRING, &new_name_resolve_order, 'R', "Use these name resolution services only", "NAME-RESOLVE-ORDER" },
- { "message", 'M', POPT_ARG_STRING, NULL, 'M', "Send message", "HOST" },
- { "ip-address", 'I', POPT_ARG_STRING, NULL, 'I', "Use this IP to connect to", "IP" },
- { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" },
- { "list", 'L', POPT_ARG_STRING, NULL, 'L', "Get a list of shares available on a host", "HOST" },
- { "terminal", 't', POPT_ARG_STRING, NULL, 't', "Terminal I/O code {sjis|euc|jis7|jis8|junet|hex}", "CODE" },
- { "max-protocol", 'm', POPT_ARG_STRING, NULL, 'm', "Set the max protocol level", "LEVEL" },
- { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" },
- { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" },
- { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" },
- { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" },
- { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" },
- { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" },
- POPT_COMMON_SAMBA
- POPT_COMMON_CONNECTION
- POPT_COMMON_CREDENTIALS
- POPT_TABLEEND
- };
-
#ifdef KANJI
pstrcpy(term_code, KANJI);
@@ -2896,155 +2497,322 @@ static int do_message_op(void)
*query_host = 0;
*base_directory = 0;
-
- /* initialize the workgroup name so we can determine whether or
- not it was set by a command line option */
-
- set_global_myworkgroup( "" );
- /* set default debug level to 0 regardless of what smb.conf sets */
- setup_logging( "smbclient", True );
- DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
- dbf = x_stderr;
- x_setbuf( x_stderr, NULL );
+ *new_name_resolve_order = 0;
+
+ DEBUGLEVEL = 2;
+ AllowDebugChange = False;
+
+ setup_logging(pname,True);
- pc = poptGetContext("smbclient", argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
- poptSetOtherOptionHelp(pc, "service <password>");
+ /*
+ * If the -E option is given, be careful not to clobber stdout
+ * before processing the options. 28.Feb.99, richard@hacom.nl.
+ * Also pre-parse the -s option to get the service file name.
+ */
+
+ for (opt = 1; opt < argc; opt++) {
+ if (strcmp(argv[opt], "-E") == 0)
+ dbf = stderr;
+ else if(strncmp(argv[opt], "-s", 2) == 0) {
+ if(argv[opt][2] != '\0')
+ pstrcpy(servicesf, &argv[opt][2]);
+ else if(argv[opt+1] != NULL) {
+ /*
+ * At least one more arg left.
+ */
+ pstrcpy(servicesf, argv[opt+1]);
+ } else {
+ usage(pname);
+ exit(1);
+ }
+ }
+ else if(strncmp(argv[opt], "-d", 2) == 0) {
+ if(argv[opt][2] != '\0') {
+ if (argv[opt][2] == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(&argv[opt][2]);
+ } else if(argv[opt+1] != NULL) {
+ /*
+ * At least one more arg left.
+ */
+ if (argv[opt+1][0] == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(argv[opt+1]);
+ } else {
+ usage(pname);
+ exit(1);
+ }
+ }
+ }
+
+ TimeInit();
+ charset_initialise();
in_client = True; /* Make sure that we tell lp_load we are */
- while ((opt = poptGetNextOpt(pc)) != -1) {
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+ }
+
+ codepage_initialise(lp_client_code_page());
+
+#ifdef WITH_SSL
+ sslutil_init(0);
+#endif
+
+ pstrcpy(workgroup,lp_workgroup());
+
+ load_interfaces();
+
+ if (getenv("USER")) {
+ pstrcpy(username,getenv("USER"));
+
+ /* modification to support userid%passwd syntax in the USER var
+ 25.Aug.97, jdblair@uab.edu */
+
+ if ((p=strchr(username,'%'))) {
+ *p = 0;
+ pstrcpy(password,p+1);
+ got_pass = True;
+ memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+ }
+ strupper(username);
+ }
+
+ /* modification to support PASSWD environmental var
+ 25.Aug.97, jdblair@uab.edu */
+ if (getenv("PASSWD")) {
+ pstrcpy(password,getenv("PASSWD"));
+ got_pass = True;
+ }
+
+ if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
+ get_password_file();
+ got_pass = True;
+ }
+
+ if (*username == 0 && getenv("LOGNAME")) {
+ pstrcpy(username,getenv("LOGNAME"));
+ strupper(username);
+ }
+
+ if (*username == 0) {
+ pstrcpy(username,"GUEST");
+ }
+
+ if (argc < 2) {
+ usage(pname);
+ exit(1);
+ }
+
+ if (*argv[1] != '-') {
+ pstrcpy(service,argv[1]);
+ /* Convert any '/' characters in the service name to '\' characters */
+ string_replace( service, '/','\\');
+ argc--;
+ argv++;
+
+ if (count_chars(service,'\\') < 3) {
+ usage(pname);
+ printf("\n%s: Not enough '\\' characters in service\n",service);
+ exit(1);
+ }
+
+ if (argc > 1 && (*argv[1] != '-')) {
+ got_pass = True;
+ pstrcpy(password,argv[1]);
+ memset(argv[1],'X',strlen(argv[1]));
+ argc--;
+ argv++;
+ }
+ }
+
+ while ((opt =
+ getopt(argc, argv,"s:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:b:A:z:")) != EOF) {
switch (opt) {
+ case 'z':
+ timeout_msec = atoi(optarg);
+ break;
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
+ case 'O':
+ pstrcpy(user_socket_options,optarg);
+ break;
+ case 'R':
+ pstrcpy(new_name_resolve_order, optarg);
+ break;
case 'M':
- /* Messages are sent to NetBIOS name type 0x3
- * (Messenger Service). Make sure we default
- * to port 139 instead of port 445. srl,crh
- */
- name_type = 0x03;
- pstrcpy(desthost,poptGetOptArg(pc));
- if( 0 == port )
- port = 139;
- message = True;
- break;
+ name_type = 0x03; /* messages are sent to NetBIOS name type 0x3 */
+ pstrcpy(desthost,optarg);
+ message = True;
+ break;
+ case 'i':
+ {
+ extern pstring global_scope;
+ pstrcpy(global_scope,optarg);
+ strupper(global_scope);
+ }
+ break;
+ case 'N':
+ got_pass = True;
+ break;
+ case 'n':
+ pstrcpy(global_myname,optarg);
+ break;
+ case 'd':
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 'P':
+ /* not needed anymore */
+ break;
+ case 'p':
+ port = atoi(optarg);
+ break;
+ case 'l':
+ slprintf(logfile,sizeof(logfile)-1, "%s.client",optarg);
+ lp_set_logfile(logfile);
+ break;
+ case 'h':
+ usage(pname);
+ exit(0);
+ break;
case 'I':
{
- dest_ip = *interpret_addr2(poptGetOptArg(pc));
+ dest_ip = *interpret_addr2(optarg);
if (is_zero_ip(dest_ip))
exit(1);
have_ip = True;
}
break;
case 'E':
- dbf = x_stderr;
- display_set_stderr();
+ dbf = stderr;
+ break;
+ case 'U':
+ {
+ char *lp;
+ pstrcpy(username,optarg);
+ if ((lp=strchr(username,'%'))) {
+ *lp = 0;
+ pstrcpy(password,lp+1);
+ got_pass = True;
+ memset(strchr(optarg,'%')+1,'X',strlen(password));
+ }
+ }
+ break;
+
+ case 'A':
+ {
+ FILE *auth;
+ fstring buf;
+ uint16 len = 0;
+ char *ptr, *val, *param;
+
+ if ((auth=sys_fopen(optarg, "r")) == NULL)
+ {
+ /* fail if we can't open the credentials file */
+ DEBUG(0,("ERROR: Unable to open credentials file!\n"));
+ exit (-1);
+ }
+
+ while (!feof(auth))
+ {
+ /* get a line from the file */
+ if (!fgets (buf, sizeof(buf), auth))
+ continue;
+ len = strlen(buf);
+
+ if ((len) && (buf[len-1]=='\n'))
+ {
+ buf[len-1] = '\0';
+ len--;
+ }
+ if (len == 0)
+ continue;
+
+ /* break up the line into parameter & value.
+ will need to eat a little whitespace possibly */
+ param = buf;
+ if (!(ptr = strchr (buf, '=')))
+ continue;
+ val = ptr+1;
+ *ptr = '\0';
+
+ /* eat leading white space */
+ while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
+ val++;
+
+ if (strwicmp("password", param) == 0)
+ {
+ pstrcpy(password, val);
+ got_pass = True;
+ }
+ else if (strwicmp("username", param) == 0)
+ pstrcpy(username, val);
+ else if (strwicmp("domain", param) == 0)
+ pstrcpy(workgroup,val);
+ memset(buf, 0, sizeof(buf));
+ }
+ fclose(auth);
+ }
break;
case 'L':
- pstrcpy(query_host, poptGetOptArg(pc));
+ p = optarg;
+ while(*p == '\\' || *p == '/')
+ p++;
+ pstrcpy(query_host,p);
break;
case 't':
- pstrcpy(term_code, poptGetOptArg(pc));
+ pstrcpy(term_code, optarg);
break;
case 'm':
- max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);
+ max_protocol = interpret_protocol(optarg, max_protocol);
+ break;
+ case 'W':
+ pstrcpy(workgroup,optarg);
break;
case 'T':
- /* We must use old option processing for this. Find the
- * position of the -T option in the raw argv[]. */
- {
- int i, optnum;
- for (i = 1; i < argc; i++) {
- if (strncmp("-T", argv[i],2)==0)
- break;
- }
- i++;
- if (!(optnum = tar_parseargs(argc, argv, poptGetOptArg(pc), i))) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
- /* Now we must eat (optnum - i) options - they have
- * been processed by tar_parseargs().
- */
- optnum -= i;
- for (i = 0; i < optnum; i++)
- poptGetOptArg(pc);
+ if (!tar_parseargs(argc, argv, optarg, optind)) {
+ usage(pname);
+ exit(1);
}
break;
case 'D':
- pstrcpy(base_directory,poptGetOptArg(pc));
+ pstrcpy(base_directory,optarg);
break;
- case 'g':
- grepable=True;
+ case 'c':
+ cmdstr = optarg;
break;
- }
- }
-
- poptGetArg(pc);
-
- /*
- * Don't load debug level from smb.conf. It should be
- * set by cmdline arg or remain default (0)
- */
- AllowDebugChange = False;
-
- /* save the workgroup...
-
- FIXME!! do we need to do this for other options as well
- (or maybe a generic way to keep lp_load() from overwriting
- everything)? */
-
- fstrcpy( new_workgroup, lp_workgroup() );
-
- if ( override_logfile )
- setup_logging( lp_logfile(), False );
-
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
- fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n",
- argv[0], dyn_CONFIGFILE);
- }
-
- load_interfaces();
-
- if ( strlen(new_workgroup) != 0 )
- set_global_myworkgroup( new_workgroup );
-
- if(poptPeekArg(pc)) {
- pstrcpy(service,poptGetArg(pc));
- /* Convert any '/' characters in the service name to '\' characters */
- string_replace(service, '/','\\');
-
- if (count_chars(service,'\\') < 3) {
- d_printf("\n%s: Not enough '\\' characters in service\n",service);
- poptPrintUsage(pc, stderr, 0);
+ case 'b':
+ io_bufsize = MAX(1, atoi(optarg));
+ break;
+ default:
+ usage(pname);
exit(1);
}
}
- if (poptPeekArg(pc) && !cmdline_auth_info.got_pass) {
- cmdline_auth_info.got_pass = True;
- pstrcpy(cmdline_auth_info.password,poptGetArg(pc));
- }
-
- init_names();
+ get_myname((*global_myname)?NULL:global_myname);
- if(new_name_resolve_order)
+ if(*new_name_resolve_order)
lp_set_name_resolve_order(new_name_resolve_order);
+ if (*term_code)
+ interpret_coding_system(term_code);
+
if (!tar_type && !*query_host && !*service && !message) {
- poptPrintUsage(pc, stderr, 0);
+ usage(pname);
exit(1);
}
- poptFreeContext(pc);
-
- pstrcpy(username, cmdline_auth_info.username);
- pstrcpy(password, cmdline_auth_info.password);
-
- use_kerberos = cmdline_auth_info.use_kerberos;
- got_pass = cmdline_auth_info.got_pass;
-
- DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING));
+ DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
if (tar_type) {
if (cmdstr)
@@ -3052,34 +2820,23 @@ static int do_message_op(void)
return do_tar_op(base_directory);
}
- if (*query_host) {
- char *qhost = query_host;
- char *slash;
-
- while (*qhost == '\\' || *qhost == '/')
- qhost++;
-
- if ((slash = strchr_m(qhost, '/'))
- || (slash = strchr_m(qhost, '\\'))) {
- *slash = 0;
- }
-
- if ((p=strchr_m(qhost, '#'))) {
- *p = 0;
- p++;
- sscanf(p, "%x", &name_type);
- }
+ if ((p=strchr(query_host,'#'))) {
+ *p = 0;
+ p++;
+ sscanf(p, "%x", &name_type);
+ }
- return do_host_query(qhost);
+ if (*query_host) {
+ return do_host_query(query_host);
}
if (message) {
return do_message_op();
}
- if (process(base_directory)) {
- return 1;
+ if (!process(base_directory)) {
+ return(1);
}
- return rc;
+ return(0);
}
diff --git a/source/client/clitar.c b/source/client/clitar.c
index e43b3e4cc50..80b1d472758 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Tar Extensions
Copyright (C) Ricky Poulten 1995-1998
Copyright (C) Richard Sharpe 1998
@@ -37,33 +38,39 @@
#include "includes.h"
#include "clitar.h"
-#include "../client/client_proto.h"
static int clipfind(char **aret, int ret, char *tok);
typedef struct file_info_struct file_info2;
-struct file_info_struct {
- SMB_BIG_UINT size;
- uint16 mode;
- uid_t uid;
- gid_t gid;
- /* These times are normally kept in GMT */
- time_t mtime;
- time_t atime;
- time_t ctime;
- char *name; /* This is dynamically allocate */
-
- file_info2 *next, *prev; /* Used in the stack ... */
+struct file_info_struct
+{
+ SMB_BIG_UINT size;
+ uint16 mode;
+ uid_t uid;
+ gid_t gid;
+ /* These times are normally kept in GMT */
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ char *name; /* This is dynamically allocate */
+
+ file_info2 *next, *prev; /* Used in the stack ... */
+
};
-typedef struct {
- file_info2 *top;
- int items;
+typedef struct
+{
+ file_info2 *top;
+ int items;
+
} stack;
+stack dir_stack = {NULL, 0}; /* Want an empty stack */
+
#define SEPARATORS " \t\n\r"
extern struct cli_state *cli;
+extern FILE *dbf;
/* These defines are for the do_setrattr routine, to indicate
* setting and reseting of file attributes in the function call */
@@ -80,25 +87,25 @@ static char *tarbuf, *buffer_p;
static int tp, ntarf, tbufsiz;
static double ttarf;
/* Incremental mode */
-static BOOL tar_inc=False;
+BOOL tar_inc=False;
/* Reset archive bit */
-static BOOL tar_reset=False;
+BOOL tar_reset=False;
/* Include / exclude mode (true=include, false=exclude) */
-static BOOL tar_excl=True;
+BOOL tar_excl=True;
/* use regular expressions for search on file names */
-static BOOL tar_re_search=False;
+BOOL tar_re_search=False;
#ifdef HAVE_REGEX_H
regex_t *preg;
#endif
/* Do not dump anything, just calculate sizes */
-static BOOL dry_run=False;
+BOOL dry_run=False;
/* Dump files with System attribute */
-static BOOL tar_system=True;
+BOOL tar_system=True;
/* Dump files with Hidden attribute */
-static BOOL tar_hidden=True;
+BOOL tar_hidden=True;
/* Be noisy - make a catalogue */
-static BOOL tar_noisy=True;
-static BOOL tar_real_noisy=False; /* Don't want to be really noisy by default */
+BOOL tar_noisy=True;
+BOOL tar_real_noisy=False; /* Don't want to be really noisy by default */
char tar_type='\0';
static char **cliplist=NULL;
@@ -111,18 +118,19 @@ extern uint16 cnum;
extern BOOL readbraw_supported;
extern int max_xmit;
extern pstring cur_dir;
-extern int get_total_time_ms;
-extern int get_total_size;
+extern unsigned int get_total_time_ms;
+extern off_t get_total_size;
+extern int Protocol;
-static int blocksize=20;
-static int tarhandle;
+int blocksize=20;
+int tarhandle;
static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
const char *amode, unsigned char ftype);
static void do_atar(char *rname,char *lname,file_info *finfo1);
static void do_tar(file_info *finfo);
static void oct_it(SMB_BIG_UINT value, int ndgs, char *p);
-static void fixtarname(char *tptr, const char *fp, size_t l);
+static void fixtarname(char *tptr, const char *fp, int l);
static int dotarbuf(int f, char *b, int n);
static void dozerobuf(int f, int n);
static void dotareof(int f);
@@ -141,337 +149,344 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first);
/*******************************************************************
Create a string of size size+1 (for the null)
*******************************************************************/
-
static char *string_create_s(int size)
{
- char *tmp;
+ char *tmp;
- tmp = (char *)malloc(size+1);
+ tmp = (char *)malloc(size+1);
- if (tmp == NULL) {
- DEBUG(0, ("Out of memory in string_create_s\n"));
- }
+ if (tmp == NULL) {
+
+ DEBUG(0, ("Out of memory in string_create_s\n"));
+
+ }
+
+ return(tmp);
- return(tmp);
}
/****************************************************************************
Write a tar header to buffer
****************************************************************************/
-
-static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
+static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
const char *amode, unsigned char ftype)
{
- union hblock hb;
- int i, chk, l;
- char *jp;
+ union hblock hb;
+ int i, chk, l;
+ char *jp;
- DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
+ DEBUG(5, ("WriteTarHdr, Type = %c, Size = %.0f, Name = %s\n", ftype, (double)size, aname));
- memset(hb.dummy, 0, sizeof(hb.dummy));
+ memset(hb.dummy, 0, sizeof(hb.dummy));
- l=strlen(aname);
- /* We will be prepending a '.' in fixtarheader so use +2 to
- * take care of the . and terminating zero. JRA.
- */
- if (l+2 >= NAMSIZ) {
- /* write a GNU tar style long header */
- char *b;
- b = (char *)malloc(l+TBLOCK+100);
- if (!b) {
- DEBUG(0,("out of memory\n"));
- exit(1);
- }
- writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
- memset(b, 0, l+TBLOCK+100);
- fixtarname(b, aname, l+2);
- i = strlen(b)+1;
- DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
- dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
- SAFE_FREE(b);
- }
-
- fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2);
-
- if (lowercase)
- strlower_m(hb.dbuf.name);
-
- /* write out a "standard" tar format header */
-
- hb.dbuf.name[NAMSIZ-1]='\0';
- safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
- oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
- if (size > (SMB_BIG_UINT)077777777777LL) {
-
- /* This is a non-POSIX compatible extention to store files
- greater than 8GB. */
-
- memset(hb.dbuf.size, 0, 4);
- hb.dbuf.size[0]=128;
- for (i = 8, jp=(char*)&size; i; i--)
- hb.dbuf.size[i+3] = *(jp++);
- }
- oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
- memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
- memset(hb.dbuf.linkname, 0, NAMSIZ);
- hb.dbuf.linkflag=ftype;
+ l=strlen(aname);
+ if (l >= NAMSIZ - 1) {
+ /* write a GNU tar style long header */
+ char *b;
+ b = (char *)malloc(l+TBLOCK+100);
+ if (!b) {
+ DEBUG(0,("out of memory\n"));
+ exit(1);
+ }
+ writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
+ memset(b, 0, l+TBLOCK+100);
+ fixtarname(b, aname, l);
+ i = strlen(b)+1;
+ DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
+ dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
+ SAFE_FREE(b);
+ }
+
+ /* use l + 1 to do the null too */
+ fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
+
+ if (lowercase)
+ strlower(hb.dbuf.name);
+
+ /* write out a "standard" tar format header */
+
+ hb.dbuf.name[NAMSIZ-1]='\0';
+ safe_strcpy(hb.dbuf.mode, amode, strlen(amode));
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
+ oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
+ oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
+ memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
+ memset(hb.dbuf.linkname, 0, NAMSIZ);
+ hb.dbuf.linkflag=ftype;
- for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;)
- chk+=(0xFF & *jp++);
+ for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++);
- oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
- hb.dbuf.chksum[6] = '\0';
+ oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
+ hb.dbuf.chksum[6] = '\0';
- (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
+ (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
}
/****************************************************************************
Read a tar header into a hblock structure, and validate
***************************************************************************/
-
static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
{
- long chk, fchk;
- int i;
- char *jp;
+ long chk, fchk;
+ int i;
+ char *jp;
- /*
- * read in a "standard" tar format header - we're not that interested
- * in that many fields, though
- */
+ /*
+ * read in a "standard" tar format header - we're not that interested
+ * in that many fields, though
+ */
- /* check the checksum */
- for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;)
- chk+=(0xFF & *jp++);
+ /* check the checksum */
+ for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++);
- if (chk == 0)
- return chk;
+ if (chk == 0)
+ return chk;
- /* compensate for blanks in chksum header */
- for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
- chk-=(0xFF & *jp++);
+ /* compensate for blanks in chksum header */
+ for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
+ chk-=(0xFF & *jp++);
- chk += ' ' * sizeof(hb->dbuf.chksum);
+ chk += ' ' * sizeof(hb->dbuf.chksum);
- fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
+ fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
- DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
- chk, fchk, hb->dbuf.chksum));
+ DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
+ chk, fchk, hb->dbuf.chksum));
- if (fchk != chk) {
- DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
- dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
- return -1;
- }
+ if (fchk != chk)
+ {
+ DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
+ dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
+ return -1;
+ }
- if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
- DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
- return(-1);
- }
+ if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
- safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3);
-
- /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
- unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
- strlen(hb->dbuf.name) + 1, True);
-
- /* can't handle some links at present */
- if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
- if (hb->dbuf.linkflag == 0) {
- DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
- finfo->name));
- } else {
- if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
- /* Do nothing here at the moment. do_tarput will handle this
- as long as the longlink gets back to it, as it has to advance
- the buffer pointer, etc */
- } else {
- DEBUG(0, ("this tar file appears to contain some kind \
-of link other than a GNUtar Longlink - ignoring\n"));
- return -2;
- }
- }
- }
-
- if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
- (*(finfo->name+strlen(finfo->name)-1) == '\\')) {
- finfo->mode=aDIR;
- } else {
- finfo->mode=0; /* we don't care about mode at the moment, we'll
- * just make it a regular file */
- }
+ DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
+ return(-1);
+
+ }
- /*
- * Bug fix by richard@sj.co.uk
- *
- * REC: restore times correctly (as does tar)
- * We only get the modification time of the file; set the creation time
- * from the mod. time, and the access time to current time
- */
- finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
- finfo->atime = time(NULL);
- finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
-
- return True;
+ safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3);
+
+ /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
+ unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
+ strlen(hb->dbuf.name) + 1, True);
+
+ /* can't handle some links at present */
+ if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
+ if (hb->dbuf.linkflag == 0) {
+ DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
+ finfo->name));
+ } else {
+ if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
+ /* Do nothing here at the moment. do_tarput will handle this
+ as long as the longlink gets back to it, as it has to advance
+ the buffer pointer, etc */
+
+ } else {
+ DEBUG(0, ("this tar file appears to contain some kind of link other than a GNUtar Longlink - ignoring\n"));
+ return -2;
+ }
+ }
+ }
+
+ if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR)
+ || (*(finfo->name+strlen(finfo->name)-1) == '\\'))
+ {
+ finfo->mode=aDIR;
+ }
+ else
+ finfo->mode=0; /* we don't care about mode at the moment, we'll
+ * just make it a regular file */
+ /*
+ * Bug fix by richard@sj.co.uk
+ *
+ * REC: restore times correctly (as does tar)
+ * We only get the modification time of the file; set the creation time
+ * from the mod. time, and the access time to current time
+ */
+ finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
+ finfo->atime = time(NULL);
+ finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
+
+ return True;
}
/****************************************************************************
Write out the tar buffer to tape or wherever
****************************************************************************/
-
static int dotarbuf(int f, char *b, int n)
{
- int fail=1, writ=n;
-
- if (dry_run) {
- return writ;
- }
- /* This routine and the next one should be the only ones that do write()s */
- if (tp + n >= tbufsiz) {
- int diff;
-
- diff=tbufsiz-tp;
- memcpy(tarbuf + tp, b, diff);
- fail=fail && (1+write(f, tarbuf, tbufsiz));
- n-=diff;
- b+=diff;
- tp=0;
-
- while (n >= tbufsiz) {
- fail=fail && (1 + write(f, b, tbufsiz));
- n-=tbufsiz;
- b+=tbufsiz;
- }
- }
-
- if (n>0) {
- memcpy(tarbuf+tp, b, n);
- tp+=n;
+ int fail=1, writ=n;
+
+ if (dry_run) {
+ return writ;
+ }
+ /* This routine and the next one should be the only ones that do write()s */
+ if (tp + n >= tbufsiz)
+ {
+ int diff;
+
+ diff=tbufsiz-tp;
+ memcpy(tarbuf + tp, b, diff);
+ fail=fail && (1+write(f, tarbuf, tbufsiz));
+ n-=diff;
+ b+=diff;
+ tp=0;
+
+ while (n >= tbufsiz)
+ {
+ fail=fail && (1 + write(f, b, tbufsiz));
+ n-=tbufsiz;
+ b+=tbufsiz;
}
+ }
+ if (n>0) {
+ memcpy(tarbuf+tp, b, n);
+ tp+=n;
+ }
- return(fail ? writ : 0);
+ return(fail ? writ : 0);
}
/****************************************************************************
Write zeros to buffer / tape
****************************************************************************/
-
static void dozerobuf(int f, int n)
{
- /* short routine just to write out n zeros to buffer -
- * used to round files to nearest block
- * and to do tar EOFs */
+ /* short routine just to write out n zeros to buffer -
+ * used to round files to nearest block
+ * and to do tar EOFs */
- if (dry_run)
- return;
+ if (dry_run)
+ return;
- if (n+tp >= tbufsiz) {
- memset(tarbuf+tp, 0, tbufsiz-tp);
- write(f, tarbuf, tbufsiz);
- memset(tarbuf, 0, (tp+=n-tbufsiz));
- } else {
- memset(tarbuf+tp, 0, n);
- tp+=n;
- }
+ if (n+tp >= tbufsiz)
+ {
+ memset(tarbuf+tp, 0, tbufsiz-tp);
+
+ write(f, tarbuf, tbufsiz);
+ memset(tarbuf, 0, (tp+=n-tbufsiz));
+ }
+ else
+ {
+ memset(tarbuf+tp, 0, n);
+ tp+=n;
+ }
}
/****************************************************************************
Malloc tape buffer
****************************************************************************/
-
static void initarbuf(void)
{
- /* initialize tar buffer */
- tbufsiz=blocksize*TBLOCK;
- tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */
+ /* initialize tar buffer */
+ tbufsiz=blocksize*TBLOCK;
+ tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */
- /* reset tar buffer pointer and tar file counter and total dumped */
- tp=0; ntarf=0; ttarf=0;
+ /* reset tar buffer pointer and tar file counter and total dumped */
+ tp=0; ntarf=0; ttarf=0;
}
/****************************************************************************
Write two zero blocks at end of file
****************************************************************************/
-
static void dotareof(int f)
{
- SMB_STRUCT_STAT stbuf;
- /* Two zero blocks at end of file, write out full buffer */
+ SMB_STRUCT_STAT stbuf;
+ /* Two zero blocks at end of file, write out full buffer */
- if (dry_run)
- return;
+ if (dry_run)
+ return;
- (void) dozerobuf(f, TBLOCK);
- (void) dozerobuf(f, TBLOCK);
+ (void) dozerobuf(f, TBLOCK);
+ (void) dozerobuf(f, TBLOCK);
- if (sys_fstat(f, &stbuf) == -1) {
- DEBUG(0, ("Couldn't stat file handle\n"));
- return;
- }
+ if (sys_fstat(f, &stbuf) == -1)
+ {
+ DEBUG(0, ("Couldn't stat file handle\n"));
+ return;
+ }
- /* Could be a pipe, in which case S_ISREG should fail,
- * and we should write out at full size */
- if (tp > 0)
- write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
+ /* Could be a pipe, in which case S_ISREG should fail,
+ * and we should write out at full size */
+ if (tp > 0) write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
}
/****************************************************************************
(Un)mangle DOS pathname, make nonabsolute
****************************************************************************/
-
-static void fixtarname(char *tptr, const char *fp, size_t l)
+static void fixtarname(char *tptr, const char *fp, int l)
{
- /* add a '.' to start of file name, convert from ugly dos \'s in path
- * to lovely unix /'s :-} */
- *tptr++='.';
- l--;
-
- StrnCpy(tptr, fp, l-1);
- string_replace(tptr, '\\', '/');
+ /* add a '.' to start of file name, convert from ugly dos \'s in path
+ * to lovely unix /'s :-} */
+
+ *tptr++='.';
+
+ while (l > 0) {
+ int skip = get_character_len(*fp);
+ if(skip != 0) {
+ if (skip == 2) {
+ *tptr++ = *fp++;
+ *tptr++ = *fp++;
+ l -= 2;
+ } else if (skip == 1) {
+ *tptr++ = *fp++;
+ l--;
+ }
+ } else if (*fp == '\\') {
+ *tptr++ = '/';
+ fp++;
+ l--;
+ } else {
+ *tptr++ = *fp++;
+ l--;
+ }
+ }
}
/****************************************************************************
Convert from decimal to octal string
****************************************************************************/
-
static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
{
- /* Converts long to octal string, pads with leading zeros */
+ /* Converts long to octal string, pads with leading zeros */
- /* skip final null, but do final space */
- --ndgs;
- p[--ndgs] = ' ';
+ /* skip final null, but do final space */
+ --ndgs;
+ p[--ndgs] = ' ';
- /* Loop does at least one digit */
- do {
- p[--ndgs] = '0' + (char) (value & 7);
- value >>= 3;
- } while (ndgs > 0 && value != 0);
+ /* Loop does at least one digit */
+ do {
+ p[--ndgs] = '0' + (char) (value & 7);
+ value >>= 3;
+ }
+ while (ndgs > 0 && value != 0);
- /* Do leading zeros */
- while (ndgs > 0)
- p[--ndgs] = '0';
+ /* Do leading zeros */
+ while (ndgs > 0)
+ p[--ndgs] = '0';
}
/****************************************************************************
Convert from octal string to long
***************************************************************************/
-
static long unoct(char *p, int ndgs)
{
- long value=0;
- /* Converts octal string to long, ignoring any non-digit */
+ long value=0;
+ /* Converts octal string to long, ignoring any non-digit */
- while (--ndgs) {
- if (isdigit((int)*p))
- value = (value << 3) | (long) (*p - '0');
+ while (--ndgs)
+ {
+ if (isdigit((int)*p))
+ value = (value << 3) | (long) (*p - '0');
- p++;
- }
+ p++;
+ }
- return value;
+ return value;
}
/****************************************************************************
@@ -479,86 +494,90 @@ Compare two strings in a slash insensitive way, allowing s1 to match s2
if s1 is an "initial" string (up to directory marker). Thus, if s2 is
a file in any subdirectory of s1, declare a match.
***************************************************************************/
-
static int strslashcmp(char *s1, char *s2)
{
- char *s1_0=s1;
+ char *s1_0=s1;
- while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) ||
- (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
- s1++; s2++;
- }
+ while(*s1 && *s2 &&
+ (*s1 == *s2
+ || tolower(*s1) == tolower(*s2)
+ || (*s1 == '\\' && *s2=='/')
+ || (*s1 == '/' && *s2=='\\'))) {
+ s1++; s2++;
+ }
- /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
- string of s2.
- */
- if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\'))
- return 0;
+ /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
+ string of s2.
+ */
+ if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0;
- /* ignore trailing slash on s1 */
- if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1))
- return 0;
+ /* ignore trailing slash on s1 */
+ if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
- /* check for s1 is an "initial" string of s2 */
- if ((*s2 == '/' || *s2 == '\\') && !*s1)
- return 0;
+ /* check for s1 is an "initial" string of s2 */
+ if (*s2 == '/' || *s2 == '\\') return 0;
- return *s1-*s2;
+ return *s1-*s2;
}
+
/****************************************************************************
Ensure a remote path exists (make if necessary)
***************************************************************************/
-
static BOOL ensurepath(char *fname)
{
- /* *must* be called with buffer ready malloc'ed */
- /* ensures path exists */
+ /* *must* be called with buffer ready malloc'ed */
+ /* ensures path exists */
- char *partpath, *ffname;
- char *p=fname, *basehack;
+ char *partpath, *ffname;
+ char *p=fname, *basehack;
- DEBUG(5, ( "Ensurepath called with: %s\n", fname));
+ DEBUG(5, ( "Ensurepath called with: %s\n", fname));
- partpath = string_create_s(strlen(fname));
- ffname = string_create_s(strlen(fname));
+ partpath = string_create_s(strlen(fname));
+ ffname = string_create_s(strlen(fname));
- if ((partpath == NULL) || (ffname == NULL)){
- DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
- return(False);
- }
+ if ((partpath == NULL) || (ffname == NULL)){
- *partpath = 0;
+ DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
+ return(False);
- /* fname copied to ffname so can strtok */
+ }
- safe_strcpy(ffname, fname, strlen(fname));
+ *partpath = 0;
- /* do a `basename' on ffname, so don't try and make file name directory */
- if ((basehack=strrchr_m(ffname, '\\')) == NULL)
- return True;
- else
- *basehack='\0';
+ /* fname copied to ffname so can strtok */
- p=strtok(ffname, "\\");
+ safe_strcpy(ffname, fname, strlen(fname));
- while (p) {
- safe_strcat(partpath, p, strlen(fname) + 1);
+ /* do a `basename' on ffname, so don't try and make file name directory */
+ if ((basehack=strrchr(ffname, '\\')) == NULL)
+ return True;
+ else
+ *basehack='\0';
- if (!cli_chkpath(cli, partpath)) {
- if (!cli_mkdir(cli, partpath)) {
- DEBUG(0, ("Error mkdirhiering\n"));
- return False;
- } else {
- DEBUG(3, ("mkdirhiering %s\n", partpath));
- }
- }
+ p=strtok(ffname, "\\");
- safe_strcat(partpath, "\\", strlen(fname) + 1);
- p = strtok(NULL,"/\\");
- }
+ while (p)
+ {
+ safe_strcat(partpath, p, strlen(fname) + 1);
- return True;
+ if (!cli_chkpath(cli, partpath)) {
+ if (!cli_mkdir(cli, partpath))
+ {
+ DEBUG(0, ("Error mkdirhiering\n"));
+ return False;
+ }
+ else
+ DEBUG(3, ("mkdirhiering %s\n", partpath));
+
+ }
+
+ safe_strcat(partpath, "\\", strlen(fname) + 1);
+ p = strtok(NULL,"/\\");
+ }
+
+ return True;
}
static int padit(char *buf, int bufsize, int padsize)
@@ -577,6 +596,7 @@ static int padit(char *buf, int bufsize, int padsize)
return berr;
}
+
static void do_setrattr(char *name, uint16 attr, int set)
{
uint16 oldattr;
@@ -594,347 +614,382 @@ static void do_setrattr(char *name, uint16 attr, int set)
}
}
+
/****************************************************************************
append one remote file to the tar file
***************************************************************************/
-
static void do_atar(char *rname,char *lname,file_info *finfo1)
{
- int fnum;
- SMB_BIG_UINT nread=0;
- char ftype;
- file_info2 finfo;
- BOOL close_done = False;
- BOOL shallitime=True;
- char data[65520];
- int read_size = 65520;
- int datalen=0;
-
- struct timeval tp_start;
-
- GetTimeOfDay(&tp_start);
-
- ftype = '0'; /* An ordinary file ... */
-
- if (finfo1) {
- finfo.size = finfo1 -> size;
- finfo.mode = finfo1 -> mode;
- finfo.uid = finfo1 -> uid;
- finfo.gid = finfo1 -> gid;
- finfo.mtime = finfo1 -> mtime;
- finfo.atime = finfo1 -> atime;
- finfo.ctime = finfo1 -> ctime;
- finfo.name = finfo1 -> name;
- } else {
- finfo.size = def_finfo.size;
- finfo.mode = def_finfo.mode;
- finfo.uid = def_finfo.uid;
- finfo.gid = def_finfo.gid;
- finfo.mtime = def_finfo.mtime;
- finfo.atime = def_finfo.atime;
- finfo.ctime = def_finfo.ctime;
- finfo.name = def_finfo.name;
- }
-
- if (dry_run) {
- DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name,
- (double)finfo.size));
- shallitime=0;
- ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
- ntarf++;
- return;
- }
-
- fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
-
- dos_clean_name(rname);
-
- if (fnum == -1) {
- DEBUG(0,("%s opening remote file %s (%s)\n",
- cli_errstr(cli),rname, cur_dir));
- return;
- }
-
- finfo.name = string_create_s(strlen(rname));
- if (finfo.name == NULL) {
- DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
- return;
- }
-
- safe_strcpy(finfo.name,rname, strlen(rname));
- if (!finfo1) {
- if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
- DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
- return;
- }
- finfo.ctime = finfo.mtime;
- }
-
- DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
-
- if (tar_inc && !(finfo.mode & aARCH)) {
- DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
- shallitime=0;
- } else if (!tar_system && (finfo.mode & aSYSTEM)) {
- DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
- shallitime=0;
- } else if (!tar_hidden && (finfo.mode & aHIDDEN)) {
- DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
- shallitime=0;
- } else {
- DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
- finfo.name, (double)finfo.size, lname));
+ int fnum;
+ SMB_BIG_UINT nread=0;
+ char ftype;
+ file_info2 finfo;
+ BOOL close_done = False;
+ BOOL shallitime=True;
+ char data[65520];
+ int read_size = 65520;
+ int datalen=0;
+
+ struct timeval tp_start;
+ GetTimeOfDay(&tp_start);
+
+ ftype = '0'; /* An ordinary file ... */
+
+ if (finfo1) {
+ finfo.size = finfo1 -> size;
+ finfo.mode = finfo1 -> mode;
+ finfo.uid = finfo1 -> uid;
+ finfo.gid = finfo1 -> gid;
+ finfo.mtime = finfo1 -> mtime;
+ finfo.atime = finfo1 -> atime;
+ finfo.ctime = finfo1 -> ctime;
+ finfo.name = finfo1 -> name;
+ }
+ else {
+ finfo.size = def_finfo.size;
+ finfo.mode = def_finfo.mode;
+ finfo.uid = def_finfo.uid;
+ finfo.gid = def_finfo.gid;
+ finfo.mtime = def_finfo.mtime;
+ finfo.atime = def_finfo.atime;
+ finfo.ctime = def_finfo.ctime;
+ finfo.name = def_finfo.name;
+ }
+
+ if (dry_run)
+ {
+ DEBUG(3,("skipping file %s of size %12.0f bytes\n",
+ finfo.name,
+ (double)finfo.size));
+ shallitime=0;
+ ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+ ntarf++;
+ return;
+ }
+
+ fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
+
+ dos_clean_name(rname);
+
+ if (fnum == -1) {
+ DEBUG(0,("%s opening remote file %s (%s)\n",
+ cli_errstr(cli),rname, cur_dir));
+ return;
+ }
+
+ finfo.name = string_create_s(strlen(rname));
+ if (finfo.name == NULL) {
+ DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
+ return;
+ }
+
+ safe_strcpy(finfo.name,rname, strlen(rname));
+ if (!finfo1) {
+ if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
+ DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
+ return;
+ }
+ finfo.ctime = finfo.mtime;
+ }
+
+ DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
+
+ if (tar_inc && !(finfo.mode & aARCH))
+ {
+ DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
+ shallitime=0;
+ }
+ else if (!tar_system && (finfo.mode & aSYSTEM))
+ {
+ DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
+ shallitime=0;
+ }
+ else if (!tar_hidden && (finfo.mode & aHIDDEN))
+ {
+ DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
+ shallitime=0;
+ }
+ else
+ {
+ DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
+ finfo.name,
+ (double)finfo.size,
+ lname));
- /* write a tar header, don't bother with mode - just set to 100644 */
- writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
+ /* write a tar header, don't bother with mode - just set to 100644 */
+ writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
- while (nread < finfo.size && !close_done) {
+ while (nread < finfo.size && !close_done) {
- DEBUG(3,("nread=%.0f\n",(double)nread));
+ DEBUG(3,("nread=%.0f\n",(double)nread));
- datalen = cli_read(cli, fnum, data, nread, read_size);
+ datalen = cli_read(cli, fnum, data, nread, read_size);
- if (datalen == -1) {
- DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
- break;
- }
+ if (datalen == -1) {
+ DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
+ break;
+ }
- nread += datalen;
-
- /* if file size has increased since we made file size query, truncate
- read so tar header for this file will be correct.
- */
-
- if (nread > finfo.size) {
- datalen -= nread - finfo.size;
- DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
- finfo.name, (double)finfo.size));
- }
-
- /* add received bits of file to buffer - dotarbuf will
- * write out in 512 byte intervals */
-
- if (dotarbuf(tarhandle,data,datalen) != datalen) {
- DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
- break;
- }
+ nread += datalen;
+
+ /* if file size has increased since we made file size query, truncate
+ read so tar header for this file will be correct.
+ */
+
+ if (nread > finfo.size) {
+ datalen -= nread - finfo.size;
+ DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo.name, (double)finfo.size));
+ }
+
+ /* add received bits of file to buffer - dotarbuf will
+ * write out in 512 byte intervals */
+ if (dotarbuf(tarhandle,data,datalen) != datalen) {
+ DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
+ break;
+ }
- if (datalen == 0) {
- DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
- break;
- }
-
- datalen=0;
- }
-
- /* pad tar file with zero's if we couldn't get entire file */
- if (nread < finfo.size) {
- DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
- (double)finfo.size, (int)nread));
- if (padit(data, sizeof(data), finfo.size - nread))
- DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
- }
-
- /* round tar file to nearest block */
- if (finfo.size % TBLOCK)
- dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
+ if (datalen == 0) {
+ DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
+ break;
+ }
+
+ datalen=0;
+ }
+
+ /* pad tar file with zero's if we couldn't get entire file */
+ if (nread < finfo.size) {
+ DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%.0f\n", (double)finfo.size, (double)nread));
+ if (padit(data, sizeof(data), finfo.size - nread))
+ DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+ }
+
+ /* round tar file to nearest block */
+ if (finfo.size % TBLOCK)
+ dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
- ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
- ntarf++;
- }
+ ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+ ntarf++;
+ }
- cli_close(cli, fnum);
+ cli_close(cli, fnum);
- if (shallitime) {
- struct timeval tp_end;
- int this_time;
+ if (shallitime)
+ {
+ struct timeval tp_end;
+ int this_time;
- /* if shallitime is true then we didn't skip */
- if (tar_reset && !dry_run)
- (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
+ /* if shallitime is true then we didn't skip */
+ if (tar_reset && !dry_run)
+ (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
- GetTimeOfDay(&tp_end);
- this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000;
- get_total_time_ms += this_time;
- get_total_size += finfo.size;
-
- if (tar_noisy) {
- DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
- (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
- finfo.name));
- }
-
- /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
- DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
- finfo.size / MAX(0.001, (1.024*this_time)),
- get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
+ GetTimeOfDay(&tp_end);
+ this_time =
+ (tp_end.tv_sec - tp_start.tv_sec)*1000 +
+ (tp_end.tv_usec - tp_start.tv_usec)/1000;
+ get_total_time_ms += this_time;
+ get_total_size += finfo.size;
+
+ if (tar_noisy)
+ {
+ DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
+ (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ finfo.name));
}
+
+ /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
+ DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
+ finfo.size / MAX(0.001, (1.024*this_time)),
+ get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
+ }
}
/****************************************************************************
Append single file to tar file (or not)
***************************************************************************/
-
static void do_tar(file_info *finfo)
{
- pstring rname;
+ pstring rname;
- if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
- return;
+ if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
+ return;
- /* Is it on the exclude list ? */
- if (!tar_excl && clipn) {
- pstring exclaim;
+ /* Is it on the exclude list ? */
+ if (!tar_excl && clipn) {
+ pstring exclaim;
- DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
+ DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
- pstrcpy(exclaim, cur_dir);
- *(exclaim+strlen(exclaim)-1)='\0';
+ safe_strcpy(exclaim, cur_dir, sizeof(pstring));
+ *(exclaim+strlen(exclaim)-1)='\0';
- pstrcat(exclaim, "\\");
- pstrcat(exclaim, finfo->name);
+ safe_strcat(exclaim, "\\", sizeof(pstring));
+ safe_strcat(exclaim, finfo->name, sizeof(exclaim));
- DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
+ DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
- if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
+ if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
#ifdef HAVE_REGEX_H
- (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) {
+ (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) {
#else
- (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
+ (tar_re_search && mask_match(exclaim, cliplist[0], True))) {
#endif
- DEBUG(3,("Skipping file %s\n", exclaim));
- return;
- }
- }
-
- if (finfo->mode & aDIR) {
- pstring saved_curdir;
- pstring mtar_mask;
-
- pstrcpy(saved_curdir, cur_dir);
-
- DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \
-strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
- (int)sizeof(cur_dir), (int)strlen(cur_dir),
- (int)strlen(finfo->name), finfo->name, cur_dir));
-
- pstrcat(cur_dir,finfo->name);
- pstrcat(cur_dir,"\\");
-
- DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
-
- /* write a tar directory, don't bother with mode - just set it to
- * 40755 */
- writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
- if (tar_noisy) {
- DEBUG(0,(" directory %s\n", cur_dir));
- }
- ntarf++; /* Make sure we have a file on there */
- pstrcpy(mtar_mask,cur_dir);
- pstrcat(mtar_mask,"*");
- DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
- do_list(mtar_mask, attribute, do_tar, False, True);
- pstrcpy(cur_dir,saved_curdir);
- } else {
- pstrcpy(rname,cur_dir);
- pstrcat(rname,finfo->name);
- do_atar(rname,finfo->name,finfo);
- }
+ DEBUG(3,("Skipping file %s\n", exclaim));
+ return;
+ }
+ }
+
+ if (finfo->mode & aDIR)
+ {
+ pstring saved_curdir;
+ pstring mtar_mask;
+
+ safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
+
+ DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
+
+ safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
+ safe_strcat(cur_dir,"\\", sizeof(cur_dir));
+
+ DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
+
+ /* write a tar directory, don't bother with mode - just set it to
+ * 40755 */
+ writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
+ if (tar_noisy) {
+ DEBUG(0,(" directory %s\n", cur_dir));
+ }
+ ntarf++; /* Make sure we have a file on there */
+ safe_strcpy(mtar_mask,cur_dir, sizeof(pstring));
+ safe_strcat(mtar_mask,"*", sizeof(pstring));
+ DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
+ do_list(mtar_mask, attribute, do_tar, False, True);
+ safe_strcpy(cur_dir,saved_curdir, sizeof(pstring));
+ }
+ else
+ {
+ safe_strcpy(rname,cur_dir, sizeof(pstring));
+ safe_strcat(rname,finfo->name, sizeof(pstring));
+ do_atar(rname,finfo->name,finfo);
+ }
}
/****************************************************************************
Convert from UNIX to DOS file names
***************************************************************************/
-
static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
{
- /* remove '.' from start of file name, convert from unix /'s to
- * dos \'s in path. Kill any absolute path names. But only if first!
- */
-
- DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l));
-
- if (first) {
- if (*fp == '.') {
- fp++;
- l--;
- }
- if (*fp == '\\' || *fp == '/') {
- fp++;
- l--;
- }
- }
-
- safe_strcpy(tptr, fp, l);
- string_replace(tptr, '/', '\\');
+ /* remove '.' from start of file name, convert from unix /'s to
+ * dos \'s in path. Kill any absolute path names. But only if first!
+ */
+
+ DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l));
+
+ if (first) {
+ if (*fp == '.') {
+ fp++;
+ l--;
+ }
+ if (*fp == '\\' || *fp == '/') {
+ fp++;
+ l--;
+ }
+ }
+
+ while (l > 0) {
+ int skip = get_character_len(*fp);
+ if(skip != 0) {
+ if (skip == 2) {
+ *tptr++ = *fp++;
+ *tptr++ = *fp++;
+ l -= 2;
+ } else if (skip == 1) {
+ *tptr++ = *fp++;
+ l--;
+ }
+ } else if (*fp == '/') {
+ *tptr++ = '\\';
+ fp++;
+ l--;
+ } else {
+ *tptr++ = *fp++;
+ l--;
+ }
+ }
}
+
/****************************************************************************
Move to the next block in the buffer, which may mean read in another set of
blocks. FIXME, we should allow more than one block to be skipped.
****************************************************************************/
-
static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
{
- int bufread, total = 0;
-
- DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
- *bufferp += TBLOCK;
- total = TBLOCK;
-
- if (*bufferp >= (ltarbuf + bufsiz)) {
-
- DEBUG(5, ("Reading more data into ltarbuf ...\n"));
-
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where read can return short if coming from
- * a pipe.
- */
-
- bufread = read(tarhandle, ltarbuf, bufsiz);
- total = bufread;
-
- while (total < bufsiz) {
- if (bufread < 0) { /* An error, return false */
- return (total > 0 ? -2 : bufread);
- }
- if (bufread == 0) {
- if (total <= 0) {
- return -2;
- }
- break;
- }
- bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
- total += bufread;
- }
-
- DEBUG(5, ("Total bytes read ... %i\n", total));
-
- *bufferp = ltarbuf;
- }
+ int bufread, total = 0;
+
+ DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
+ *bufferp += TBLOCK;
+ total = TBLOCK;
+
+ if (*bufferp >= (ltarbuf + bufsiz)) {
+
+ DEBUG(5, ("Reading more data into ltarbuf ...\n"));
+
+ /*
+ * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
+ * Fixes bug where read can return short if coming from
+ * a pipe.
+ */
+
+ bufread = read(tarhandle, ltarbuf, bufsiz);
+ total = bufread;
+
+ while (total < bufsiz) {
+ if (bufread < 0) { /* An error, return false */
+ return (total > 0 ? -2 : bufread);
+ }
+ if (bufread == 0) {
+ if (total <= 0) {
+ return -2;
+ }
+ break;
+ }
+ bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
+ total += bufread;
+ }
+
+ DEBUG(5, ("Total bytes read ... %i\n", total));
+
+ *bufferp = ltarbuf;
+
+ }
+
+ return(total);
- return(total);
}
/* Skip a file, even if it includes a long file name? */
static int skip_file(int skipsize)
{
- int dsize = skipsize;
+ int dsize = skipsize;
- DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
+ DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
- /* FIXME, we should skip more than one block at a time */
+ /* FIXME, we should skip more than one block at a time */
- while (dsize > 0) {
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return(False);
- }
- dsize -= TBLOCK;
- }
+ while (dsize > 0) {
+
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return(False);
+
+ }
- return(True);
+ dsize -= TBLOCK;
+
+ }
+
+ return(True);
}
/*************************************************************
@@ -945,94 +1000,103 @@ static int skip_file(int skipsize)
static int get_file(file_info2 finfo)
{
- int fnum = -1, pos = 0, dsize = 0, bpos = 0;
- SMB_BIG_UINT rsize = 0;
+ int fnum = -1, pos = 0, dsize = 0, bpos = 0;
+ SMB_BIG_UINT rsize = 0;
- DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
+ DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
- if (ensurepath(finfo.name) &&
- (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
- DEBUG(0, ("abandoning restore\n"));
- return(False);
- }
+ if (ensurepath(finfo.name) &&
+ (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
+ DEBUG(0, ("abandoning restore\n"));
+ return(False);
+ }
- /* read the blocks from the tar file and write to the remote file */
+ /* read the blocks from the tar file and write to the remote file */
- rsize = finfo.size; /* This is how much to write */
+ rsize = finfo.size; /* This is how much to write */
- while (rsize > 0) {
+ while (rsize > 0) {
- /* We can only write up to the end of the buffer */
- dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
- dsize = MIN(dsize, rsize); /* Should be only what is left */
- DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
+ /* We can only write up to the end of the buffer */
- if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
- DEBUG(0, ("Error writing remote file\n"));
- return 0;
- }
+ dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
+ dsize = MIN(dsize, rsize); /* Should be only what is left */
+ DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
- rsize -= dsize;
- pos += dsize;
+ if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
+ DEBUG(0, ("Error writing remote file\n"));
+ return 0;
+ }
- /* Now figure out how much to move in the buffer */
+ rsize -= dsize;
+ pos += dsize;
- /* FIXME, we should skip more than one block at a time */
+ /* Now figure out how much to move in the buffer */
- /* First, skip any initial part of the part written that is left over */
- /* from the end of the first TBLOCK */
+ /* FIXME, we should skip more than one block at a time */
- if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
- dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */
- bpos = 0;
+ /* First, skip any initial part of the part written that is left over */
+ /* from the end of the first TBLOCK */
- if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return False;
- }
- }
+ if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
- * If the file being extracted is an exact multiple of
- * TBLOCK bytes then we don't want to extract the next
- * block from the tarfile here, as it will be done in
- * the caller of get_file().
- */
+ dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */
+ bpos = 0;
- while (((rsize != 0) && (dsize >= TBLOCK)) ||
- ((rsize == 0) && (dsize > TBLOCK))) {
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return False;
- if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return False;
- }
+ }
- dsize -= TBLOCK;
- }
- bpos = dsize;
- }
+ }
- /* Now close the file ... */
+ /*
+ * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
+ * If the file being extracted is an exact multiple of
+ * TBLOCK bytes then we don't want to extract the next
+ * block from the tarfile here, as it will be done in
+ * the caller of get_file().
+ */
- if (!cli_close(cli, fnum)) {
- DEBUG(0, ("Error closing remote file\n"));
- return(False);
- }
+ while (((rsize != 0) && (dsize >= TBLOCK)) ||
+ ((rsize == 0) && (dsize > TBLOCK))) {
- /* Now we update the creation date ... */
- DEBUG(5, ("Updating creation date on %s\n", finfo.name));
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return False;
+ }
- if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
- if (tar_real_noisy) {
- DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
- /*return(False); */ /* Ignore, as Win95 does not allow changes */
- }
- }
+ dsize -= TBLOCK;
+ }
+
+ bpos = dsize;
+
+ }
+
+ /* Now close the file ... */
+
+ if (!cli_close(cli, fnum)) {
+ DEBUG(0, ("Error closing remote file\n"));
+ return(False);
+ }
+
+ /* Now we update the creation date ... */
+
+ DEBUG(5, ("Updating creation date on %s\n", finfo.name));
- ntarf++;
- DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
- return(True);
+ if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
+ if (tar_real_noisy) {
+ DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
+ /*return(False); */ /* Ignore, as Win95 does not allow changes */
+ }
+ }
+
+ ntarf++;
+
+ DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
+
+ return(True);
}
/* Create a directory. We just ensure that the path exists and return as there
@@ -1040,169 +1104,214 @@ static int get_file(file_info2 finfo)
*/
static int get_dir(file_info2 finfo)
{
- DEBUG(0, ("restore directory %s\n", finfo.name));
- if (!ensurepath(finfo.name)) {
- DEBUG(0, ("Problems creating directory\n"));
- return(False);
- }
- ntarf++;
- return(True);
-}
+ DEBUG(0, ("restore directory %s\n", finfo.name));
+
+ if (!ensurepath(finfo.name)) {
+
+ DEBUG(0, ("Problems creating directory\n"));
+ return(False);
+ }
+
+ ntarf++;
+ return(True);
+
+}
/* Get a file with a long file name ... first file has file name, next file
has the data. We only want the long file name, as the loop in do_tarput
will deal with the rest.
*/
-static char *get_longfilename(file_info2 finfo)
+static char * get_longfilename(file_info2 finfo)
{
- /* finfo.size here is the length of the filename as written by the "/./@LongLink" name
- * header call. */
- int namesize = finfo.size + strlen(cur_dir) + 2;
- char *longname = malloc(namesize);
- int offset = 0, left = finfo.size;
- BOOL first = True;
-
- DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
- DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
-
- if (longname == NULL) {
- DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize));
- return(NULL);
- }
+ int namesize = strlen(finfo.name) + strlen(cur_dir) + 2;
+ char *longname = malloc(namesize);
+ SMB_BIG_INT offset = 0, left = finfo.size;
+ BOOL first = True;
- /* First, add cur_dir to the long file name */
+ DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
+ DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
- if (strlen(cur_dir) > 0) {
- strncpy(longname, cur_dir, namesize);
- offset = strlen(cur_dir);
- }
+ if (longname == NULL) {
- /* Loop through the blocks picking up the name */
+ DEBUG(0, ("could not allocate buffer of size %d for longname\n",
+ namesize));
+ return(NULL);
+ }
- while (left > 0) {
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return(NULL);
- }
+ /* First, add cur_dir to the long file name */
- unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
- DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
+ if (strlen(cur_dir) > 0) {
+ strncpy(longname, cur_dir, namesize);
+ offset = strlen(cur_dir);
+ }
- offset += TBLOCK;
- left -= TBLOCK;
- }
+ /* Loop through the blocks picking up the name */
+
+ while (left > 0) {
+
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return(NULL);
+
+ }
+
+ unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
+ DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
+
+ offset += TBLOCK;
+ left -= TBLOCK;
+
+ }
+
+ return(longname);
- return(longname);
}
static void do_tarput(void)
{
- file_info2 finfo;
- struct timeval tp_start;
- char *longfilename = NULL, linkflag;
- int skip = False;
-
- GetTimeOfDay(&tp_start);
- DEBUG(5, ("RJS do_tarput called ...\n"));
-
- buffer_p = tarbuf + tbufsiz; /* init this to force first read */
-
- /* Now read through those files ... */
- while (True) {
- /* Get us to the next block, or the first block first time around */
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return;
- }
-
- DEBUG(5, ("Reading the next header ...\n"));
-
- switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
- case -2: /* Hmm, not good, but not fatal */
- DEBUG(0, ("Skipping %s...\n", finfo.name));
- if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) {
- DEBUG(0, ("Short file, bailing out...\n"));
- return;
- }
- break;
-
- case -1:
- DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
- return;
-
- case 0: /* chksum is zero - looks like an EOF */
- DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
- return; /* Hmmm, bad here ... */
-
- default:
- /* No action */
- break;
- }
-
- /* Now, do we have a long file name? */
- if (longfilename != NULL) {
- SAFE_FREE(finfo.name); /* Free the space already allocated */
- finfo.name = longfilename;
- longfilename = NULL;
- }
-
- /* Well, now we have a header, process the file ... */
- /* Should we skip the file? We have the long name as well here */
- skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) ||
+ file_info2 finfo;
+ struct timeval tp_start;
+ char *longfilename = NULL, linkflag;
+ int skip = False;
+
+ GetTimeOfDay(&tp_start);
+
+ DEBUG(5, ("RJS do_tarput called ...\n"));
+
+ buffer_p = tarbuf + tbufsiz; /* init this to force first read */
+
+ /* Now read through those files ... */
+
+ while (True) {
+
+ /* Get us to the next block, or the first block first time around */
+
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+
+ return;
+
+ }
+
+ DEBUG(5, ("Reading the next header ...\n"));
+
+ switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
+
+ case -2: /* Hmm, not good, but not fatal */
+ DEBUG(0, ("Skipping %s...\n", finfo.name));
+ if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) &&
+ !skip_file(finfo.size)) {
+
+ DEBUG(0, ("Short file, bailing out...\n"));
+ return;
+
+ }
+
+ break;
+
+ case -1:
+ DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
+ return;
+
+ case 0: /* chksum is zero - looks like an EOF */
+ DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
+ return; /* Hmmm, bad here ... */
+
+ default:
+ /* No action */
+
+ break;
+
+ }
+
+ /* Now, do we have a long file name? */
+
+ if (longfilename != NULL) {
+
+ SAFE_FREE(finfo.name); /* Free the space already allocated */
+ finfo.name = longfilename;
+ longfilename = NULL;
+
+ }
+
+ /* Well, now we have a header, process the file ... */
+
+ /* Should we skip the file? We have the long name as well here */
+
+ skip = clipn &&
+ ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl)
#ifdef HAVE_REGEX_H
- (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
+ || (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
#else
- (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True)));
+ || (tar_re_search && mask_match(finfo.name, cliplist[0], True)));
#endif
- DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
- if (skip) {
- skip_file(finfo.size);
- continue;
- }
-
- /* We only get this far if we should process the file */
- linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
- switch (linkflag) {
- case '0': /* Should use symbolic names--FIXME */
- /*
- * Skip to the next block first, so we can get the file, FIXME, should
- * be in get_file ...
- * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where file size in tarfile is zero.
- */
- if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
- DEBUG(0, ("Short file, bailing out...\n"));
- return;
- }
- if (!get_file(finfo)) {
- DEBUG(0, ("Abandoning restore\n"));
- return;
- }
- break;
- case '5':
- if (!get_dir(finfo)) {
- DEBUG(0, ("Abandoning restore \n"));
- return;
- }
- break;
- case 'L':
- longfilename = get_longfilename(finfo);
- if (!longfilename) {
- DEBUG(0, ("abandoning restore\n"));
- return;
- }
- DEBUG(5, ("Long file name: %s\n", longfilename));
- break;
-
- default:
- skip_file(finfo.size); /* Don't handle these yet */
- break;
- }
- }
+ DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
+
+ if (skip) {
+
+ skip_file(finfo.size);
+ continue;
+
+ }
+
+ /* We only get this far if we should process the file */
+ linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
+
+ switch (linkflag) {
+
+ case '0': /* Should use symbolic names--FIXME */
+
+ /*
+ * Skip to the next block first, so we can get the file, FIXME, should
+ * be in get_file ...
+ * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
+ * Fixes bug where file size in tarfile is zero.
+ */
+
+ if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+ DEBUG(0, ("Short file, bailing out...\n"));
+ return;
+ }
+ if (!get_file(finfo)) {
+ DEBUG(0, ("Abandoning restore\n"));
+ return;
+
+ }
+ break;
+
+ case '5':
+ if (!get_dir(finfo)) {
+ DEBUG(0, ("Abandoning restore \n"));
+ return;
+ }
+ break;
+
+ case 'L':
+ longfilename = get_longfilename(finfo);
+ if (!longfilename) {
+ DEBUG(0, ("abandoning restore\n"));
+ return;
+
+ }
+ DEBUG(5, ("Long file name: %s\n", longfilename));
+ break;
+
+ default:
+ skip_file(finfo.size); /* Don't handle these yet */
+ break;
+
+ }
+
+ }
+
+
}
+
/*
* samba interactive commands
*/
@@ -1210,598 +1319,571 @@ static void do_tarput(void)
/****************************************************************************
Blocksize command
***************************************************************************/
-
-int cmd_block(void)
+void cmd_block(void)
{
- fstring buf;
- int block;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- DEBUG(0, ("blocksize <n>\n"));
- return 1;
- }
-
- block=atoi(buf);
- if (block < 0 || block > 65535) {
- DEBUG(0, ("blocksize out of range"));
- return 1;
- }
-
- blocksize=block;
- DEBUG(2,("blocksize is now %d\n", blocksize));
-
- return 0;
+ fstring buf;
+ int block;
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)))
+ {
+ DEBUG(0, ("blocksize <n>\n"));
+ return;
+ }
+
+ block=atoi(buf);
+ if (block < 0 || block > 65535)
+ {
+ DEBUG(0, ("blocksize out of range"));
+ return;
+ }
+
+ blocksize=block;
+ DEBUG(2,("blocksize is now %d\n", blocksize));
}
/****************************************************************************
command to set incremental / reset mode
***************************************************************************/
-
-int cmd_tarmode(void)
+void cmd_tarmode(void)
{
- fstring buf;
-
- while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- if (strequal(buf, "full"))
- tar_inc=False;
- else if (strequal(buf, "inc"))
- tar_inc=True;
- else if (strequal(buf, "reset"))
- tar_reset=True;
- else if (strequal(buf, "noreset"))
- tar_reset=False;
- else if (strequal(buf, "system"))
- tar_system=True;
- else if (strequal(buf, "nosystem"))
- tar_system=False;
- else if (strequal(buf, "hidden"))
- tar_hidden=True;
- else if (strequal(buf, "nohidden"))
- tar_hidden=False;
- else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
- tar_noisy=True;
- else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
- tar_noisy=False;
- else
- DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
- }
+ fstring buf;
+
+ while (next_token(NULL,buf,NULL,sizeof(buf))) {
+ if (strequal(buf, "full"))
+ tar_inc=False;
+ else if (strequal(buf, "inc"))
+ tar_inc=True;
+ else if (strequal(buf, "reset"))
+ tar_reset=True;
+ else if (strequal(buf, "noreset"))
+ tar_reset=False;
+ else if (strequal(buf, "system"))
+ tar_system=True;
+ else if (strequal(buf, "nosystem"))
+ tar_system=False;
+ else if (strequal(buf, "hidden"))
+ tar_hidden=True;
+ else if (strequal(buf, "nohidden"))
+ tar_hidden=False;
+ else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
+ tar_noisy=True;
+ else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
+ tar_noisy=False;
+ else DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
+ }
+
+ DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
+ tar_inc ? "incremental" : "full",
+ tar_system ? "system" : "nosystem",
+ tar_hidden ? "hidden" : "nohidden",
+ tar_reset ? "reset" : "noreset",
+ tar_noisy ? "verbose" : "quiet"));
- DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
- tar_inc ? "incremental" : "full",
- tar_system ? "system" : "nosystem",
- tar_hidden ? "hidden" : "nohidden",
- tar_reset ? "reset" : "noreset",
- tar_noisy ? "verbose" : "quiet"));
- return 0;
}
/****************************************************************************
Feeble attrib command
***************************************************************************/
-
-int cmd_setmode(void)
+void cmd_setmode(void)
{
- char *q;
- fstring buf;
- pstring fname;
- uint16 attra[2];
- int direct=1;
-
- attra[0] = attra[1] = 0;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return 1;
- }
-
- pstrcpy(fname, cur_dir);
- pstrcat(fname, buf);
-
- while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- q=buf;
-
- while(*q) {
- switch (*q++) {
- case '+':
- direct=1;
- break;
- case '-':
- direct=0;
- break;
- case 'r':
- attra[direct]|=aRONLY;
- break;
- case 'h':
- attra[direct]|=aHIDDEN;
- break;
- case 's':
- attra[direct]|=aSYSTEM;
- break;
- case 'a':
- attra[direct]|=aARCH;
- break;
- default:
- DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return 1;
- }
- }
- }
-
- if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) {
- DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return 1;
- }
-
- DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
- do_setrattr(fname, attra[ATTRSET], ATTRSET);
- do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
- return 0;
+ char *q;
+ fstring buf;
+ pstring fname;
+ uint16 attra[2];
+ int direct=1;
+
+ attra[0] = attra[1] = 0;
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)))
+ {
+ DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
+ return;
+ }
+
+ safe_strcpy(fname, cur_dir, sizeof(pstring));
+ safe_strcat(fname, buf, sizeof(pstring));
+
+ while (next_token(NULL,buf,NULL,sizeof(buf))) {
+ q=buf;
+
+ while(*q)
+ switch (*q++) {
+ case '+': direct=1;
+ break;
+ case '-': direct=0;
+ break;
+ case 'r': attra[direct]|=aRONLY;
+ break;
+ case 'h': attra[direct]|=aHIDDEN;
+ break;
+ case 's': attra[direct]|=aSYSTEM;
+ break;
+ case 'a': attra[direct]|=aARCH;
+ break;
+ default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
+ return;
+ }
+ }
+
+ if (attra[ATTRSET]==0 && attra[ATTRRESET]==0)
+ {
+ DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
+ return;
+ }
+
+ DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
+ do_setrattr(fname, attra[ATTRSET], ATTRSET);
+ do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
}
/****************************************************************************
Principal command for creating / extracting
***************************************************************************/
-
-int cmd_tar(void)
+void cmd_tar(void)
{
- fstring buf;
- char **argl;
- int argcl;
+ fstring buf;
+ char **argl;
+ int argcl;
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
- return 1;
- }
+ if (!next_token(NULL,buf,NULL,sizeof(buf)))
+ {
+ DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
+ return;
+ }
- argl=toktocliplist(&argcl, NULL);
- if (!tar_parseargs(argcl, argl, buf, 0))
- return 1;
+ argl=toktocliplist(&argcl, NULL);
+ if (!tar_parseargs(argcl, argl, buf, 0))
+ return;
- process_tar();
- SAFE_FREE(argl);
- return 0;
+ process_tar();
+
+ SAFE_FREE(argl);
}
/****************************************************************************
Command line (option) version
***************************************************************************/
-
int process_tar(void)
{
- initarbuf();
- switch(tar_type) {
- case 'x':
+ initarbuf();
+ switch(tar_type) {
+ case 'x':
#if 0
- do_tarput2();
+ do_tarput2();
#else
- do_tarput();
+ do_tarput();
#endif
- SAFE_FREE(tarbuf);
- close(tarhandle);
- break;
- case 'r':
- case 'c':
- if (clipn && tar_excl) {
- int i;
- pstring tarmac;
-
- for (i=0; i<clipn; i++) {
- DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
-
- if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
- *(cliplist[i]+strlen(cliplist[i])-1)='\0';
- }
+ SAFE_FREE(tarbuf);
+ close(tarhandle);
+ break;
+ case 'r':
+ case 'c':
+ if (clipn && tar_excl) {
+ int i;
+ pstring tarmac;
+
+ for (i=0; i<clipn; i++) {
+ DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
+
+ if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
+ *(cliplist[i]+strlen(cliplist[i])-1)='\0';
+ }
- if (strrchr_m(cliplist[i], '\\')) {
- pstring saved_dir;
+ if (strrchr(cliplist[i], '\\')) {
+ pstring saved_dir;
- pstrcpy(saved_dir, cur_dir);
+ safe_strcpy(saved_dir, cur_dir, sizeof(pstring));
- if (*cliplist[i]=='\\') {
- pstrcpy(tarmac, cliplist[i]);
- } else {
- pstrcpy(tarmac, cur_dir);
- pstrcat(tarmac, cliplist[i]);
- }
- pstrcpy(cur_dir, tarmac);
- *(strrchr_m(cur_dir, '\\')+1)='\0';
-
- DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
- do_list(tarmac,attribute,do_tar, False, True);
- pstrcpy(cur_dir,saved_dir);
- } else {
- pstrcpy(tarmac, cur_dir);
- pstrcat(tarmac, cliplist[i]);
- DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
- do_list(tarmac,attribute,do_tar, False, True);
- }
- }
- } else {
- pstring mask;
- pstrcpy(mask,cur_dir);
- DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
- pstrcat(mask,"\\*");
- do_list(mask,attribute,do_tar,False, True);
- }
+ if (*cliplist[i]=='\\') {
+ safe_strcpy(tarmac, cliplist[i], sizeof(pstring));
+ } else {
+ safe_strcpy(tarmac, cur_dir, sizeof(pstring));
+ safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ }
+ safe_strcpy(cur_dir, tarmac, sizeof(pstring));
+ *(strrchr(cur_dir, '\\')+1)='\0';
+
+ DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
+ do_list(tarmac,attribute,do_tar, False, True);
+ safe_strcpy(cur_dir,saved_dir, sizeof(pstring));
+ } else {
+ safe_strcpy(tarmac, cur_dir, sizeof(pstring));
+ safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
+ do_list(tarmac,attribute,do_tar, False, True);
+ }
+ }
+ } else {
+ pstring mask;
+ safe_strcpy(mask,cur_dir, sizeof(pstring));
+ DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
+ safe_strcat(mask,"\\*", sizeof(pstring));
+ do_list(mask,attribute,do_tar,False, True);
+ }
- if (ntarf)
- dotareof(tarhandle);
- close(tarhandle);
- SAFE_FREE(tarbuf);
+ if (ntarf) dotareof(tarhandle);
+ close(tarhandle);
+ SAFE_FREE(tarbuf);
- DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
- DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
- break;
- }
-
- if (must_free_cliplist) {
- int i;
- for (i = 0; i < clipn; ++i) {
- SAFE_FREE(cliplist[i]);
- }
- SAFE_FREE(cliplist);
- cliplist = NULL;
- clipn = 0;
- must_free_cliplist = False;
- }
- return(0);
+ DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
+ DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
+ break;
+ }
+
+ if (must_free_cliplist) {
+ int i;
+ for (i = 0; i < clipn; ++i) {
+ SAFE_FREE(cliplist[i]);
+ }
+ SAFE_FREE(cliplist);
+ cliplist = NULL;
+ clipn = 0;
+ must_free_cliplist = False;
+ }
+
+ return(0);
}
/****************************************************************************
Find a token (filename) in a clip list
***************************************************************************/
-
static int clipfind(char **aret, int ret, char *tok)
{
- if (aret==NULL)
- return 0;
+ if (aret==NULL) return 0;
- /* ignore leading slashes or dots in token */
- while(strchr_m("/\\.", *tok))
- tok++;
+ /* ignore leading slashes or dots in token */
+ while(strchr("/\\.", *tok)) tok++;
- while(ret--) {
- char *pkey=*aret++;
+ while(ret--) {
+ char *pkey=*aret++;
- /* ignore leading slashes or dots in list */
- while(strchr_m("/\\.", *pkey))
- pkey++;
+ /* ignore leading slashes or dots in list */
+ while(strchr("/\\.", *pkey)) pkey++;
- if (!strslashcmp(pkey, tok))
- return 1;
- }
- return 0;
+ if (!strslashcmp(pkey, tok)) return 1;
+ }
+
+ return 0;
}
/****************************************************************************
Read list of files to include from the file and initialize cliplist
accordingly.
***************************************************************************/
-
static int read_inclusion_file(char *filename)
{
- XFILE *inclusion = NULL;
- char buf[PATH_MAX + 1];
- char *inclusion_buffer = NULL;
- int inclusion_buffer_size = 0;
- int inclusion_buffer_sofar = 0;
- char *p;
- char *tmpstr;
- int i;
- int error = 0;
-
- clipn = 0;
- buf[PATH_MAX] = '\0'; /* guarantee null-termination */
- if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
- /* XXX It would be better to include a reason for failure, but without
- * autoconf, it's hard to use strerror, sys_errlist, etc.
- */
- DEBUG(0,("Unable to open inclusion file %s\n", filename));
- return 0;
- }
-
- while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
- if (inclusion_buffer == NULL) {
- inclusion_buffer_size = 1024;
- if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) {
- DEBUG(0,("failure allocating buffer to read inclusion file\n"));
- error = 1;
- break;
- }
- }
+ FILE *inclusion = NULL;
+ char buf[MAXPATHLEN + 1];
+ char *inclusion_buffer = NULL;
+ int inclusion_buffer_size = 0;
+ int inclusion_buffer_sofar = 0;
+ char *p;
+ char *tmpstr;
+ int i;
+ int error = 0;
+
+ clipn = 0;
+ buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */
+ if ((inclusion = sys_fopen(filename, "r")) == NULL) {
+ /* XXX It would be better to include a reason for failure, but without
+ * autoconf, it's hard to use strerror, sys_errlist, etc.
+ */
+ DEBUG(0,("Unable to open inclusion file %s\n", filename));
+ return 0;
+ }
+
+ while ((! error) && (fgets(buf, sizeof(buf)-1, inclusion))) {
+ if (inclusion_buffer == NULL) {
+ inclusion_buffer_size = 1024;
+ if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) {
+ DEBUG(0,("failure allocating buffer to read inclusion file\n"));
+ error = 1;
+ break;
+ }
+ }
- if (buf[strlen(buf)-1] == '\n') {
- buf[strlen(buf)-1] = '\0';
- }
+ if (buf[strlen(buf)-1] == '\n') {
+ buf[strlen(buf)-1] = '\0';
+ }
- if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
- char *ib;
- inclusion_buffer_size *= 2;
- ib = Realloc(inclusion_buffer,inclusion_buffer_size);
- if (! ib) {
- DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
- inclusion_buffer_size));
- error = 1;
- break;
- } else {
- inclusion_buffer = ib;
- }
- }
+ if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
+ char *ib;
+ inclusion_buffer_size *= 2;
+ ib = Realloc(inclusion_buffer,inclusion_buffer_size);
+ if (! ib) {
+ DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", inclusion_buffer_size));
+ error = 1;
+ break;
+ } else
+ inclusion_buffer = ib;
+ }
- safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
- inclusion_buffer_sofar += strlen(buf) + 1;
- clipn++;
- }
- x_fclose(inclusion);
-
- if (! error) {
- /* Allocate an array of clipn + 1 char*'s for cliplist */
- cliplist = malloc((clipn + 1) * sizeof(char *));
- if (cliplist == NULL) {
- DEBUG(0,("failure allocating memory for cliplist\n"));
- error = 1;
- } else {
- cliplist[clipn] = NULL;
- p = inclusion_buffer;
- for (i = 0; (! error) && (i < clipn); i++) {
- /* set current item to NULL so array will be null-terminated even if
- * malloc fails below. */
- cliplist[i] = NULL;
- if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) {
- DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
- error = 1;
- } else {
- unfixtarname(tmpstr, p, strlen(p) + 1, True);
- cliplist[i] = tmpstr;
- if ((p = strchr_m(p, '\000')) == NULL) {
- DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
- abort();
- }
- }
- ++p;
- }
- must_free_cliplist = True;
- }
- }
-
- SAFE_FREE(inclusion_buffer);
- if (error) {
- if (cliplist) {
- char **pp;
- /* We know cliplist is always null-terminated */
- for (pp = cliplist; *pp; ++pp) {
- SAFE_FREE(*pp);
- }
- SAFE_FREE(cliplist);
- cliplist = NULL;
- must_free_cliplist = False;
- }
- return 0;
+ safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
+ inclusion_buffer_sofar += strlen(buf) + 1;
+ clipn++;
+ }
+ fclose(inclusion);
+
+ if (! error) {
+ /* Allocate an array of clipn + 1 char*'s for cliplist */
+ cliplist = malloc((clipn + 1) * sizeof(char *));
+ if (cliplist == NULL) {
+ DEBUG(0,("failure allocating memory for cliplist\n"));
+ error = 1;
+ } else {
+ cliplist[clipn] = NULL;
+ p = inclusion_buffer;
+ for (i = 0; (! error) && (i < clipn); i++) {
+ /* set current item to NULL so array will be null-terminated even if
+ * malloc fails below. */
+ cliplist[i] = NULL;
+ if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) {
+ DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
+ error = 1;
+ } else {
+ unfixtarname(tmpstr, p, strlen(p) + 1, True);
+ cliplist[i] = tmpstr;
+ if ((p = strchr(p, '\000')) == NULL) {
+ DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
+ abort();
+ }
}
+ ++p;
+ }
+ must_free_cliplist = True;
+ }
+ }
+
+ if (inclusion_buffer) {
+ SAFE_FREE(inclusion_buffer);
+ }
+ if (error) {
+ if (cliplist) {
+ char **pp;
+ /* We know cliplist is always null-terminated */
+ for (pp = cliplist; *pp; ++pp) {
+ SAFE_FREE(*pp);
+ }
+ SAFE_FREE(cliplist);
+ cliplist = NULL;
+ must_free_cliplist = False;
+ }
+ return 0;
+ }
- /* cliplist and its elements are freed at the end of process_tar. */
- return 1;
+ /* cliplist and its elements are freed at the end of process_tar. */
+ return 1;
}
/****************************************************************************
Parse tar arguments. Sets tar_type, tar_excl, etc.
***************************************************************************/
-
-int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
+int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind)
{
- int newOptind = Optind;
- char tar_clipfl='\0';
-
- /* Reset back to defaults - could be from interactive version
- * reset mode and archive mode left as they are though
- */
- tar_type='\0';
- tar_excl=True;
- dry_run=False;
-
- while (*Optarg) {
- switch(*Optarg++) {
- case 'c':
- tar_type='c';
- break;
- case 'x':
- if (tar_type=='c') {
- printf("Tar must be followed by only one of c or x.\n");
- return 0;
- }
- tar_type='x';
- break;
- case 'b':
- if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
- DEBUG(0,("Option b must be followed by valid blocksize\n"));
- return 0;
- } else {
- Optind++;
- newOptind++;
- }
- break;
- case 'g':
- tar_inc=True;
- break;
- case 'N':
- if (Optind>=argc) {
- DEBUG(0,("Option N must be followed by valid file name\n"));
- return 0;
- } else {
- SMB_STRUCT_STAT stbuf;
- extern time_t newer_than;
+ char tar_clipfl='\0';
+
+ /* Reset back to defaults - could be from interactive version
+ * reset mode and archive mode left as they are though
+ */
+ tar_type='\0';
+ tar_excl=True;
+ dry_run=False;
+
+ while (*Optarg)
+ switch(*Optarg++) {
+ case 'c':
+ tar_type='c';
+ break;
+ case 'x':
+ if (tar_type=='c') {
+ printf("Tar must be followed by only one of c or x.\n");
+ return 0;
+ }
+ tar_type='x';
+ break;
+ case 'b':
+ if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
+ DEBUG(0,("Option b must be followed by valid blocksize\n"));
+ return 0;
+ } else {
+ Optind++;
+ }
+ break;
+ case 'g':
+ tar_inc=True;
+ break;
+ case 'N':
+ if (Optind>=argc) {
+ DEBUG(0,("Option N must be followed by valid file name\n"));
+ return 0;
+ } else {
+ SMB_STRUCT_STAT stbuf;
+ extern time_t newer_than;
- if (sys_stat(argv[Optind], &stbuf) == 0) {
- newer_than = stbuf.st_mtime;
- DEBUG(1,("Getting files newer than %s",
- asctime(LocalTime(&newer_than))));
- newOptind++;
- Optind++;
- } else {
- DEBUG(0,("Error setting newer-than time\n"));
- return 0;
- }
- }
- break;
- case 'a':
- tar_reset=True;
- break;
- case 'q':
- tar_noisy=False;
- break;
- case 'I':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='I';
- break;
- case 'X':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='X';
- break;
- case 'F':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='F';
- break;
- case 'r':
- DEBUG(0, ("tar_re_search set\n"));
- tar_re_search = True;
- break;
- case 'n':
- if (tar_type == 'c') {
- DEBUG(0, ("dry_run set\n"));
- dry_run = True;
- } else {
- DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
- return 0;
- }
- break;
- default:
- DEBUG(0,("Unknown tar option\n"));
- return 0;
- }
- }
-
- if (!tar_type) {
- printf("Option T must be followed by one of c or x.\n");
- return 0;
- }
-
- /* tar_excl is true if cliplist lists files to be included.
- * Both 'I' and 'F' mean include. */
- tar_excl=tar_clipfl!='X';
-
- if (tar_clipfl=='F') {
- if (argc-Optind-1 != 1) {
- DEBUG(0,("Option F must be followed by exactly one filename.\n"));
- return 0;
- }
- newOptind++;
- Optind++;
- if (! read_inclusion_file(argv[Optind])) {
- return 0;
- }
- } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
- char *tmpstr;
- char **tmplist;
- int clipcount;
-
- cliplist=argv+Optind+1;
- clipn=argc-Optind-1;
- clipcount = clipn;
-
- if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) {
- DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));
- return 0;
- }
-
- for (clipcount = 0; clipcount < clipn; clipcount++) {
-
- DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
-
- if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) {
- DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));
- return 0;
- }
-
- unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
- tmplist[clipcount] = tmpstr;
- DEBUG(5, ("Processed an item, %s\n", tmpstr));
-
- DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
- }
-
- cliplist = tmplist;
- must_free_cliplist = True;
-
- newOptind += clipn;
+ if (sys_stat(dos_to_unix_static(argv[Optind]), &stbuf) == 0) {
+ newer_than = stbuf.st_mtime;
+ DEBUG(1,("Getting files newer than %s",
+ asctime(LocalTime(&newer_than))));
+ Optind++;
+ } else {
+ DEBUG(0,("Error setting newer-than time\n"));
+ return 0;
}
-
- if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */
+ }
+ break;
+ case 'a':
+ tar_reset=True;
+ break;
+ case 'q':
+ tar_noisy=False;
+ break;
+ case 'I':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='I';
+ break;
+ case 'X':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='X';
+ break;
+ case 'F':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='F';
+ break;
+ case 'r':
+ DEBUG(0, ("tar_re_search set\n"));
+ tar_re_search = True;
+ break;
+ case 'n':
+ if (tar_type == 'c') {
+ DEBUG(0, ("dry_run set\n"));
+ dry_run = True;
+ } else {
+ DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
+ return 0;
+ }
+ break;
+ default:
+ DEBUG(0,("Unknown tar option\n"));
+ return 0;
+ }
+
+ if (!tar_type) {
+ printf("Option T must be followed by one of c or x.\n");
+ return 0;
+ }
+
+ /* tar_excl is true if cliplist lists files to be included.
+ * Both 'I' and 'F' mean include. */
+ tar_excl=tar_clipfl!='X';
+
+ if (tar_clipfl=='F') {
+ if (argc-Optind-1 != 1) {
+ DEBUG(0,("Option F must be followed by exactly one filename.\n"));
+ return 0;
+ }
+ if (! read_inclusion_file(argv[Optind+1])) {
+ return 0;
+ }
+ } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
+ char *tmpstr;
+ char **tmplist;
+ int clipcount;
+
+ cliplist=argv+Optind+1;
+ clipn=argc-Optind-1;
+ clipcount = clipn;
+
+ if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) {
+ DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n",
+ clipn)
+ );
+ return 0;
+ }
+
+ for (clipcount = 0; clipcount < clipn; clipcount++) {
+
+ DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
+
+ if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) {
+ DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n",
+ clipcount)
+ );
+ return 0;
+ }
+ unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
+ tmplist[clipcount] = tmpstr;
+ DEBUG(5, ("Processed an item, %s\n", tmpstr));
+
+ DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
+ }
+ cliplist = tmplist;
+ must_free_cliplist = True;
+ }
+
+ if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */
#ifdef HAVE_REGEX_H
- int errcode;
+ int errcode;
- if ((preg = (regex_t *)malloc(65536)) == NULL) {
+ if ((preg = (regex_t *)malloc(65536)) == NULL) {
- DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
- return;
- }
+ DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
+ return;
- if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) {
- char errstr[1024];
- size_t errlen;
+ }
- errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1);
- DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr));
- return;
- }
-#endif
+ if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) {
+ char errstr[1024];
+ size_t errlen;
- clipn=argc-Optind-1;
- cliplist=argv+Optind+1;
- newOptind += clipn;
- }
+ errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1);
+
+ DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr));
+ return;
- if (Optind>=argc || !strcmp(argv[Optind], "-")) {
- /* Sets tar handle to either 0 or 1, as appropriate */
- tarhandle=(tar_type=='c');
- /*
- * Make sure that dbf points to stderr if we are using stdout for
- * tar output
- */
- if (tarhandle == 1) {
- dbf = x_stderr;
- }
- if (!argv[Optind]) {
- DEBUG(0,("Must specify tar filename\n"));
- return 0;
- }
- if (!strcmp(argv[Optind], "-")) {
- newOptind++;
- }
+ }
+#endif
- } else {
- if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) {
- if (!dry_run) {
- DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
- dry_run = True;
- }
- tarhandle=-1;
- } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
- || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {
- DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno)));
- return(0);
- }
- newOptind++;
+ clipn=argc-Optind-1;
+ cliplist=argv+Optind+1;
+
+ }
+
+ if (Optind>=argc || !strcmp(argv[Optind], "-")) {
+ /* Sets tar handle to either 0 or 1, as appropriate */
+ tarhandle=(tar_type=='c');
+ /*
+ * Make sure that dbf points to stderr if we are using stdout for
+ * tar output
+ */
+ if (tarhandle == 1)
+ dbf = stderr;
+ } else {
+ if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0))
+ {
+ if (!dry_run) {
+ DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
+ dry_run = True;
}
+ tarhandle=-1;
+ } else
+ if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
+ || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0))
+ {
+ DEBUG(0,("Error opening local file %s - %s\n",
+ argv[Optind], strerror(errno)));
+ return(0);
+ }
+ }
- return newOptind;
+ return 1;
}
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
deleted file mode 100755
index ad202d1da10..00000000000
--- a/source/client/mount.cifs.c
+++ /dev/null
@@ -1,916 +0,0 @@
-/*
- Mount helper utility for Linux CIFS VFS (virtual filesystem) client
- Copyright (C) 2003 Steve French (sfrench@us.ibm.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <errno.h>
-#include <netdb.h>
-#include <string.h>
-#include <mntent.h>
-#include <fcntl.h>
-
-#define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "2"
-
-#ifndef MOUNT_CIFS_VENDOR_SUFFIX
-#define MOUNT_CIFS_VENDOR_SUFFIX ""
-#endif
-
-#ifndef MS_MOVE
-#define MS_MOVE 8192
-#endif
-
-char * thisprogram;
-int verboseflag = 0;
-static int got_password = 0;
-static int got_user = 0;
-static int got_domain = 0;
-static int got_ip = 0;
-static int got_unc = 0;
-static int got_uid = 0;
-static int got_gid = 0;
-static char * user_name = NULL;
-char * mountpassword = NULL;
-
-
-/* BB finish BB
-
- cifs_umount
- open nofollow - avoid symlink exposure?
- get owner of dir see if matches self or if root
- call system(umount argv) etc.
-
-BB end finish BB */
-
-static void mount_cifs_usage(void)
-{
- printf("\nUsage: %s <remotetarget> <dir> -o <options>\n", thisprogram);
- printf("\nMount the remote target, specified as a UNC name,");
- printf(" to a local directory.\n\nOptions:\n");
- printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
- printf("\nOther less commonly used options are described in the manual page");
- printf("\n\tman 8 mount.cifs\n");
- printf("\nTo display the version number of the mount helper:");
- printf("\n\t%s -V\n",thisprogram);
-
- if(mountpassword) {
- memset(mountpassword,0,64);
- free(mountpassword);
- }
- exit(1);
-}
-
-/* caller frees username if necessary */
-static char * getusername(void) {
- char *username = NULL;
- struct passwd *password = getpwuid(getuid());
-
- if (password) {
- username = password->pw_name;
- }
- return username;
-}
-
-char * parse_cifs_url(char * unc_name)
-{
- printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name);
- return NULL;
-}
-
-static int open_cred_file(char * file_name)
-{
- char * line_buf;
- char * temp_val;
- FILE * fs;
- int i, length;
- fs = fopen(file_name,"r");
- if(fs == NULL)
- return errno;
- line_buf = malloc(4096);
- if(line_buf == NULL)
- return -ENOMEM;
-
- while(fgets(line_buf,4096,fs)) {
- /* parse line from credential file */
-
- /* eat leading white space */
- for(i=0;i<4086;i++) {
- if((line_buf[i] != ' ') && (line_buf[i] != '\t'))
- break;
- /* if whitespace - skip past it */
- }
- if (strncasecmp("username",line_buf+i,8) == 0) {
- temp_val = strchr(line_buf + i,'=');
- if(temp_val) {
- /* go past equals sign */
- temp_val++;
- for(length = 0;length<4087;length++) {
- if(temp_val[length] == '\n')
- break;
- }
- if(length > 4086) {
- printf("mount.cifs failed due to malformed username in credentials file");
- memset(line_buf,0,4096);
- if(mountpassword) {
- memset(mountpassword,0,64);
- }
- exit(1);
- } else {
- got_user = 1;
- user_name = calloc(1 + length,1);
- /* BB adding free of user_name string before exit,
- not really necessary but would be cleaner */
- strncpy(user_name,temp_val, length);
- }
- }
- } else if (strncasecmp("password",line_buf+i,8) == 0) {
- temp_val = strchr(line_buf+i,'=');
- if(temp_val) {
- /* go past equals sign */
- temp_val++;
- for(length = 0;length<65;length++) {
- if(temp_val[length] == '\n')
- break;
- }
- if(length > 64) {
- printf("mount.cifs failed: password in credentials file too long\n");
- memset(line_buf,0, 4096);
- if(mountpassword) {
- memset(mountpassword,0,64);
- }
- exit(1);
- } else {
- if(mountpassword == NULL) {
- mountpassword = calloc(65,1);
- } else
- memset(mountpassword,0,64);
- if(mountpassword) {
- /* BB add handling for commas in password here */
- strncpy(mountpassword,temp_val,length);
- got_password = 1;
- }
- }
- }
- }
- }
- fclose(fs);
- if(line_buf) {
- memset(line_buf,0,4096);
- free(line_buf);
- }
- return 0;
-}
-
-static int get_password_from_file(int file_descript, char * filename)
-{
- int rc = 0;
- int i;
- char c;
-
- if(mountpassword == NULL)
- mountpassword = calloc(65,1);
- else
- memset(mountpassword, 0, 64);
-
- if(filename != NULL) {
- file_descript = open(filename, O_RDONLY);
- if(file_descript < 0) {
- printf("mount.cifs failed. %s attempting to open password file %s\n",
- strerror(errno),filename);
- exit(1);
- }
- }
- /* else file already open and fd provided */
-
- for(i=0;i<64;i++) {
- rc = read(file_descript,&c,1);
- if(rc < 0) {
- printf("mount.cifs failed. Error %s reading password file\n",strerror(errno));
- memset(mountpassword,0,64);
- if(filename != NULL)
- close(file_descript);
- exit(1);
- } else if(rc == 0) {
- if(mountpassword[0] == 0) {
- if(verboseflag)
- printf("\nWarning: null password used since cifs password file empty");
- }
- break;
- } else /* read valid character */ {
- if((c == 0) || (c == '\n')) {
- break;
- } else
- mountpassword[i] = c;
- }
- }
- if((i == 64) && (verboseflag)) {
- printf("\nWarning: password longer than 64 characters specified in cifs password file");
- }
- got_password = 1;
- if(filename != NULL) {
- close(file_descript);
- }
-
- return rc;
-}
-
-static int parse_options(char * options, int * filesys_flags)
-{
- char * data;
- char * percent_char = 0;
- char * value = 0;
- char * next_keyword = 0;
- int rc = 0;
-
- if (!options)
- return 1;
- else
- data = options;
-
- if(verboseflag)
- printf("\n parsing options: %s", options);
-
-/* while ((data = strsep(&options, ",")) != NULL) { */
- while(data != NULL) {
- /* check if ends with trailing comma */
- if(*data == 0)
- break;
-
- /* format is keyword=value,keyword2=value2,keyword3=value3 etc.) */
- /* data = next keyword */
- /* value = next value ie stuff after equal sign */
-
- next_keyword = strchr(data,',');
-
- /* temporarily null terminate end of keyword=value pair */
- if(next_keyword)
- *next_keyword = 0;
-
- /* if (!*data)
- continue; */
-
- /* temporarily null terminate keyword to make keyword and value distinct */
- if ((value = strchr(data, '=')) != NULL) {
- *value = '\0';
- value++;
- }
-
- if (strncmp(data, "user", 4) == 0) {
- if (!value || !*value) {
- printf("invalid or missing username\n");
- return 1; /* needs_arg; */
- }
- if (strnlen(value, 260) < 260) {
- got_user=1;
- percent_char = strchr(value,'%');
- if(percent_char) {
- *percent_char = ',';
- if(mountpassword == NULL)
- mountpassword = calloc(65,1);
- if(mountpassword) {
- if(got_password)
- printf("\nmount.cifs warning - password specified twice\n");
- got_password = 1;
- percent_char++;
- strncpy(mountpassword, percent_char,64);
- /* remove password from username */
- while(*percent_char != 0) {
- *percent_char = ',';
- percent_char++;
- }
- }
- }
- } else {
- printf("username too long\n");
- return 1;
- }
- } else if (strncmp(data, "pass", 4) == 0) {
- if (!value || !*value) {
- if(got_password) {
- printf("\npassword specified twice, ignoring second\n");
- } else
- got_password = 1;
- } else if (strnlen(value, 17) < 17) {
- if(got_password)
- printf("\nmount.cifs warning - password specified twice\n");
- got_password = 1;
- } else {
- printf("password too long\n");
- return 1;
- }
- } else if (strncmp(data, "ip", 2) == 0) {
- if (!value || !*value) {
- printf("target ip address argument missing");
- } else if (strnlen(value, 35) < 35) {
- got_ip = 1;
- } else {
- printf("ip address too long\n");
- return 1;
- }
- } else if ((strncmp(data, "unc", 3) == 0)
- || (strncmp(data, "target", 6) == 0)
- || (strncmp(data, "path", 4) == 0)) {
- if (!value || !*value) {
- printf("invalid path to network resource\n");
- return 1; /* needs_arg; */
- } else if(strnlen(value,5) < 5) {
- printf("UNC name too short");
- }
-
- if (strnlen(value, 300) < 300) {
- got_unc = 1;
- if (strncmp(value, "//", 2) == 0) {
- if(got_unc)
- printf("unc name specified twice, ignoring second\n");
- else
- got_unc = 1;
- } else if (strncmp(value, "\\\\", 2) != 0) {
- printf("UNC Path does not begin with // or \\\\ \n");
- return 1;
- } else {
- if(got_unc)
- printf("unc name specified twice, ignoring second\n");
- else
- got_unc = 1;
- }
- } else {
- printf("CIFS: UNC name too long\n");
- return 1;
- }
- } else if ((strncmp(data, "domain", 3) == 0)
- || (strncmp(data, "workgroup", 5) == 0)) {
- if (!value || !*value) {
- printf("CIFS: invalid domain name\n");
- return 1; /* needs_arg; */
- }
- if (strnlen(value, 65) < 65) {
- got_domain = 1;
- } else {
- printf("domain name too long\n");
- return 1;
- }
- } else if (strncmp(data, "cred", 4) == 0) {
- if (value && *value) {
- rc = open_cred_file(value);
- if(rc) {
- printf("error %d opening credential file %s\n",rc, value);
- return 1;
- }
- } else {
- printf("invalid credential file name specified\n");
- return 1;
- }
- } else if (strncmp(data, "uid", 3) == 0) {
- if (value && *value) {
- got_uid = 1;
- }
- } else if (strncmp(data, "gid", 3) == 0) {
- if (value && *value) {
- got_gid = 1;
- }
- /* fmask and dmask synonyms for people used to smbfs syntax */
- } else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) {
- if (!value || !*value) {
- printf ("Option '%s' requires a numerical argument\n", data);
- return 1;
- }
-
- if (value[0] != '0') {
- printf ("WARNING: '%s' not expressed in octal.\n", data);
- }
-
- if (strcmp (data, "fmask") == 0) {
- printf ("WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n");
- data = "file_mode"; /* BB fix this */
- }
- } else if (strcmp(data, "dir_mode") == 0 || strcmp(data, "dmask")==0) {
- if (!value || !*value) {
- printf ("Option '%s' requires a numerical argument\n", data);
- return 1;
- }
-
- if (value[0] != '0') {
- printf ("WARNING: '%s' not expressed in octal.\n", data);
- }
-
- if (strcmp (data, "dmask") == 0) {
- printf ("WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n");
- data = "dir_mode";
- }
- /* the following eight mount options should be
- stripped out from what is passed into the kernel
- since these eight options are best passed as the
- mount flags rather than redundantly to the kernel
- and could generate spurious warnings depending on the
- level of the corresponding cifs vfs kernel code */
- } else if (strncmp(data, "nosuid", 6) == 0) {
- *filesys_flags |= MS_NOSUID;
- } else if (strncmp(data, "suid", 4) == 0) {
- *filesys_flags &= ~MS_NOSUID;
- } else if (strncmp(data, "nodev", 5) == 0) {
- *filesys_flags |= MS_NODEV;
- } else if (strncmp(data, "dev", 3) == 0) {
- *filesys_flags &= ~MS_NODEV;
- } else if (strncmp(data, "noexec", 6) == 0) {
- *filesys_flags |= MS_NOEXEC;
- } else if (strncmp(data, "exec", 4) == 0) {
- *filesys_flags &= ~MS_NOEXEC;
- } else if (strncmp(data, "guest", 5) == 0) {
- got_password=1;
- } else if (strncmp(data, "ro", 2) == 0) {
- *filesys_flags |= MS_RDONLY;
- } else if (strncmp(data, "rw", 2) == 0) {
- *filesys_flags &= ~MS_RDONLY;
- } /* else if (strnicmp(data, "port", 4) == 0) {
- if (value && *value) {
- vol->port =
- simple_strtoul(value, &value, 0);
- }
- } else if (strnicmp(data, "rsize", 5) == 0) {
- if (value && *value) {
- vol->rsize =
- simple_strtoul(value, &value, 0);
- }
- } else if (strnicmp(data, "wsize", 5) == 0) {
- if (value && *value) {
- vol->wsize =
- simple_strtoul(value, &value, 0);
- }
- } else if (strnicmp(data, "version", 3) == 0) {
- } else {
- printf("CIFS: Unknown mount option %s\n",data);
- } */ /* nothing to do on those four mount options above.
- Just pass to kernel and ignore them here */
-
- /* move to next option */
- data = next_keyword+1;
-
- /* put overwritten equals sign back */
- if(value) {
- value--;
- *value = '=';
- }
-
- /* put previous overwritten comma back */
- if(next_keyword)
- *next_keyword = ',';
- else
- data = 0;
- }
- return 0;
-}
-
-/* Note that caller frees the returned buffer if necessary */
-char * parse_server(char * unc_name)
-{
- int length = strnlen(unc_name,1024);
- char * share;
- char * ipaddress_string = NULL;
- struct hostent * host_entry;
- struct in_addr server_ipaddr;
- int rc;
-
- if(length > 1023) {
- printf("mount error: UNC name too long");
- return 0;
- }
- if (strncasecmp("cifs://",unc_name,7) == 0)
- return parse_cifs_url(unc_name+7);
- if (strncasecmp("smb://",unc_name,6) == 0) {
- return parse_cifs_url(unc_name+6);
- }
-
- if(length < 3) {
- /* BB add code to find DFS root here */
- printf("\nMounting the DFS root for domain not implemented yet");
- return 0;
- } else {
- if(strncmp(unc_name,"//",2) && strncmp(unc_name,"\\\\",2)) {
- printf("mount error: improperly formatted UNC name.");
- printf(" %s does not begin with \\\\ or //\n",unc_name);
- return 0;
- } else {
- unc_name[0] = '\\';
- unc_name[0] = '/';
- unc_name[1] = '/';
- unc_name += 2;
- if ((share = strchr(unc_name, '/')) ||
- (share = strchr(unc_name,'\\'))) {
- *share = 0; /* temporarily terminate the string */
- share += 1;
- host_entry = gethostbyname(unc_name);
- *(share - 1) = '/'; /* put the slash back */
-/* rc = getipnodebyname(unc_name, AF_INET, AT_ADDRCONFIG ,&rc);*/
- if(host_entry == NULL) {
- printf("mount error: could not find target server. TCP name %s not found ", unc_name);
- printf(" rc = %d\n",rc);
- return 0;
- }
- else {
- /* BB should we pass an alternate version of the share name as Unicode */
- /* BB what about ipv6? BB */
- /* BB add retries with alternate servers in list */
-
- memcpy(&server_ipaddr.s_addr, host_entry->h_addr, 4);
-
- ipaddress_string = inet_ntoa(server_ipaddr);
- if(ipaddress_string == NULL) {
- printf("mount error: could not get valid ip address for target server\n");
- return 0;
- }
- return ipaddress_string;
- }
- } else {
- /* BB add code to find DFS root (send null path on get DFS Referral to specified server here */
- printf("Mounting the DFS root for a particular server not implemented yet\n");
- return 0;
- }
- }
- }
-}
-
-static struct option longopts[] = {
- { "all", 0, 0, 'a' },
- { "help",0, 0, 'h' },
- { "move",0, 0, 'm' },
- { "bind",0, 0, 'b' },
- { "read-only", 0, 0, 'r' },
- { "ro", 0, 0, 'r' },
- { "verbose", 0, 0, 'v' },
- { "version", 0, 0, 'V' },
- { "read-write", 0, 0, 'w' },
- { "rw", 0, 0, 'w' },
- { "options", 1, 0, 'o' },
- { "type", 1, 0, 't' },
- { "rsize",1, 0, 'R' },
- { "wsize",1, 0, 'W' },
- { "uid", 1, 0, '1'},
- { "gid", 1, 0, '2'},
- { "user",1,0,'u'},
- { "username",1,0,'u'},
- { "dom",1,0,'d'},
- { "domain",1,0,'d'},
- { "password",1,0,'p'},
- { "pass",1,0,'p'},
- { "credentials",1,0,'c'},
- { "port",1,0,'P'},
- /* { "uuid",1,0,'U'}, */ /* BB unimplemented */
- { NULL, 0, 0, 0 }
-};
-
-int main(int argc, char ** argv)
-{
- int c;
- int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */
- char * orgoptions = NULL;
- char * share_name = NULL;
- char * domain_name = NULL;
- char * ipaddr = NULL;
- char * uuid = NULL;
- char * mountpoint;
- char * options;
- char * resolved_path;
- char * temp;
- int rc;
- int rsize = 0;
- int wsize = 0;
- int nomtab = 0;
- int uid = 0;
- int gid = 0;
- int optlen = 0;
- int orgoptlen = 0;
- struct stat statbuf;
- struct utsname sysinfo;
- struct mntent mountent;
- FILE * pmntfile;
-
- /* setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE); */
-
- if(argc && argv) {
- thisprogram = argv[0];
- }
- if(thisprogram == NULL)
- thisprogram = "mount.cifs";
-
- uname(&sysinfo);
- /* BB add workstation name and domain and pass down */
-
-/* #ifdef _GNU_SOURCE
- printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname);
-#endif */
-
- share_name = argv[1];
- mountpoint = argv[2];
-
- /* add sharename in opts string as unc= parm */
-
- while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:",
- longopts, NULL)) != -1) {
- switch (c) {
-/* No code to do the following options yet */
-/* case 'l':
- list_with_volumelabel = 1;
- break;
- case 'L':
- volumelabel = optarg;
- break; */
-/* case 'a':
- ++mount_all;
- break; */
-
- case '?':
- case 'h': /* help */
- mount_cifs_usage ();
- exit(1);
- case 'n':
- ++nomtab;
- break;
- case 'b':
- flags |= MS_BIND;
- break;
- case 'm':
- flags |= MS_MOVE;
- break;
- case 'o':
- orgoptions = strdup(optarg);
- break;
- case 'r': /* mount readonly */
- flags |= MS_RDONLY;
- break;
- case 'U':
- uuid = optarg;
- break;
- case 'v':
- ++verboseflag;
- break;
- case 'V':
- printf ("mount.cifs version: %s.%s%s\n",
- MOUNT_CIFS_VERSION_MAJOR,
- MOUNT_CIFS_VERSION_MINOR,
- MOUNT_CIFS_VENDOR_SUFFIX);
- if(mountpassword) {
- memset(mountpassword,0,64);
- }
- exit (0);
- case 'w':
- flags &= ~MS_RDONLY;
- break;
- case 'R':
- rsize = atoi(optarg) ;
- break;
- case 'W':
- wsize = atoi(optarg);
- break;
- case '1':
- uid = atoi(optarg);
- break;
- case '2':
- gid = atoi(optarg);
- break;
- case 'u':
- got_user = 1;
- user_name = optarg;
- break;
- case 'd':
- domain_name = optarg;
- break;
- case 'p':
- if(mountpassword == NULL)
- mountpassword = calloc(65,1);
- if(mountpassword) {
- got_password = 1;
- strncpy(mountpassword,optarg,64);
- }
- break;
- case 't':
- break;
- default:
- printf("unknown mount option %c\n",c);
- mount_cifs_usage();
- exit(1);
- }
- }
-
- if(argc < 3)
- mount_cifs_usage();
-
- if (getenv("PASSWD")) {
- if(mountpassword == NULL)
- mountpassword = calloc(65,1);
- if(mountpassword) {
- strncpy(mountpassword,getenv("PASSWD"),64);
- got_password = 1;
- }
- } else if (getenv("PASSWD_FD")) {
- get_password_from_file(atoi(getenv("PASSWD_FD")),NULL);
- } else if (getenv("PASSWD_FILE")) {
- get_password_from_file(0, getenv("PASSWD_FILE"));
- }
-
- ipaddr = parse_server(share_name);
-
- if(ipaddr == NULL)
- return -1;
-
- if (orgoptions && parse_options(orgoptions, &flags))
- return -1;
-
- /* BB save off path and pop after mount returns? */
- resolved_path = malloc(PATH_MAX+1);
- if(resolved_path) {
- /* Note that if we can not canonicalize the name, we get
- another chance to see if it is valid when we chdir to it */
- if (realpath(mountpoint, resolved_path)) {
- mountpoint = resolved_path;
- }
- }
- if(chdir(mountpoint)) {
- printf("mount error: can not change directory into mount target %s\n",mountpoint);
- return -1;
- }
-
- if(stat (".", &statbuf)) {
- printf("mount error: mount point %s does not exist\n",mountpoint);
- return -1;
- }
-
- if (S_ISDIR(statbuf.st_mode) == 0) {
- printf("mount error: mount point %s is not a directory\n",mountpoint);
- return -1;
- }
-
- if((getuid() != 0) && (geteuid() == 0)) {
- if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) {
-#ifndef CIFS_ALLOW_USR_SUID
- /* Do not allow user mounts to control suid flag
- for mount unless explicitly built that way */
- flags |= MS_NOSUID | MS_NODEV;
-#endif
- } else {
- printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n");
- return -1;
- }
- }
-
- if(got_user == 0)
- user_name = getusername();
-
- if(got_password == 0) {
- mountpassword = getpass("Password: "); /* BB obsolete */
- got_password = 1;
- }
- /* FIXME launch daemon (handles dfs name resolution and credential change)
- remember to clear parms and overwrite password field before launching */
- if(orgoptions) {
- optlen = strlen(orgoptions);
- orgoptlen = optlen;
- } else
- optlen = 0;
- if(share_name)
- optlen += strlen(share_name) + 4;
- if(user_name)
- optlen += strlen(user_name) + 6;
- if(ipaddr)
- optlen += strlen(ipaddr) + 4;
- if(mountpassword)
- optlen += strlen(mountpassword) + 6;
- options = malloc(optlen + 10);
-
- if(options == NULL) {
- printf("Could not allocate memory for mount options\n");
- return -1;
- }
-
-
- options[0] = 0;
- strncat(options,"unc=",4);
- strcat(options,share_name);
- /* scan backwards and reverse direction of slash */
- temp = strrchr(options, '/');
- if(temp > options + 6)
- *temp = '\\';
- if(ipaddr) {
- strncat(options,",ip=",4);
- strcat(options,ipaddr);
- }
- if(user_name) {
- strncat(options,",user=",6);
- strcat(options,user_name);
- }
- if(mountpassword) {
- strncat(options,",pass=",6);
- strcat(options,mountpassword);
- }
- strncat(options,",ver=",5);
- strcat(options,MOUNT_CIFS_VERSION_MAJOR);
-
- if(orgoptions) {
- strcat(options,",");
- strcat(options,orgoptions);
- }
- if(verboseflag)
- printf("\nmount.cifs kernel mount options %s \n",options);
- if(mount(share_name, mountpoint, "cifs", flags, options)) {
- /* remember to kill daemon on error */
- switch (errno) {
- case 0:
- printf("mount failed but no error number set\n");
- break;
- case ENODEV:
- printf("mount error: cifs filesystem not supported by the system\n");
- break;
- default:
- printf("mount error %d = %s\n",errno,strerror(errno));
- }
- printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
- if(mountpassword) {
- memset(mountpassword,0,64);
- }
- return -1;
- } else {
- pmntfile = setmntent(MOUNTED, "a+");
- if(pmntfile) {
- mountent.mnt_fsname = share_name;
- mountent.mnt_dir = mountpoint;
- mountent.mnt_type = "cifs";
- mountent.mnt_opts = malloc(200);
- if(mountent.mnt_opts) {
- memset(mountent.mnt_opts,0,200);
- if(flags & MS_RDONLY)
- strcat(mountent.mnt_opts,"ro");
- else
- strcat(mountent.mnt_opts,"rw");
- if(flags & MS_MANDLOCK)
- strcat(mountent.mnt_opts,",mand");
- else
- strcat(mountent.mnt_opts,",nomand");
- if(flags & MS_NOEXEC)
- strcat(mountent.mnt_opts,",noexec");
- if(flags & MS_NOSUID)
- strcat(mountent.mnt_opts,",nosuid");
- if(flags & MS_NODEV)
- strcat(mountent.mnt_opts,",nodev");
- if(flags & MS_SYNCHRONOUS)
- strcat(mountent.mnt_opts,",synch");
- }
- mountent.mnt_freq = 0;
- mountent.mnt_passno = 0;
- rc = addmntent(pmntfile,&mountent);
- endmntent(pmntfile);
- if(mountent.mnt_opts)
- free(mountent.mnt_opts);
- } else {
- printf("could not update mount table\n");
- }
- }
- if(mountpassword) {
- memset(mountpassword,0,64);
- free(mountpassword);
- }
-
- if(options) {
- memset(options,0,optlen);
- free(options);
- }
-
- if(orgoptions) {
- memset(orgoptions,0,orgoptlen);
- free(orgoptions);
- }
- if(resolved_path) {
- free(resolved_path);
- }
-
- return 0;
-}
-
diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c
index 753a31c3139..36248987b1e 100644
--- a/source/client/smbmnt.c
+++ b/source/client/smbmnt.c
@@ -38,7 +38,7 @@ help(void)
{
printf("\n");
printf("Usage: smbmnt mount-point [options]\n");
- printf("Version %s\n\n",SAMBA_VERSION_STRING);
+ printf("Version %s\n\n",VERSION);
printf("-s share share name on server\n"
"-r mount read-only\n"
"-u uid mount as uid\n"
@@ -94,9 +94,9 @@ parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
static char *
fullpath(const char *p)
{
- char path[PATH_MAX+1];
+ char path[MAXPATHLEN];
- if (strlen(p) > PATH_MAX) {
+ if (strlen(p) > MAXPATHLEN-1) {
return NULL;
}
@@ -111,13 +111,13 @@ fullpath(const char *p)
OK then we change into that directory - this prevents race conditions */
static int mount_ok(char *mount_point)
{
- struct stat st;
+ SMB_STRUCT_STAT st;
if (chdir(mount_point) != 0) {
return -1;
}
- if (stat(".", &st) != 0) {
+ if (sys_stat(".", &st) != 0) {
return -1;
}
@@ -148,8 +148,8 @@ do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data)
uname(&uts);
release = uts.release;
- major = strtok(release, ".");
- minor = strtok(NULL, ".");
+ major = strsep(&release, ".");
+ minor = strsep(&release, ".");
if (major && minor && atoi(major) == 2 && atoi(minor) < 4) {
/* < 2.4, assume struct */
data1 = (char *) data;
@@ -240,7 +240,7 @@ do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data)
data.dir_mode |= S_IXOTH;
}
- flags = MS_MGC_VAL | MS_NOSUID | MS_NODEV;
+ flags = MS_MGC_VAL;
if (mount_ro) flags |= MS_RDONLY;
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 04bb103dae2..40e21e1eb1d 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0.
SMBFS mount program
Copyright (C) Andrew Tridgell 1999
@@ -28,6 +29,8 @@
extern BOOL in_client;
extern pstring user_socket_options;
+extern BOOL append_log;
+extern fstring remote_machine;
static pstring credentials;
static pstring my_netbios_name;
@@ -40,19 +43,13 @@ static pstring options;
static struct in_addr dest_ip;
static BOOL have_ip;
-static int smb_port = 0;
-static BOOL got_user;
+static int smb_port = 139;
static BOOL got_pass;
static uid_t mount_uid;
static gid_t mount_gid;
static int mount_ro;
static unsigned mount_fmask;
static unsigned mount_dmask;
-static BOOL use_kerberos;
-/* TODO: Add code to detect smbfs version in kernel */
-static BOOL status32_smbfs = False;
-static BOOL smbfs_has_unicode = False;
-static BOOL smbfs_has_lfs = False;
static void usage(void);
@@ -84,12 +81,8 @@ static void daemonize(void)
}
break;
}
-
/* If we get here - the child exited with some error status */
- if (WIFSIGNALED(status))
- exit(128 + WTERMSIG(status));
- else
- exit(WEXITSTATUS(status));
+ exit(status);
}
signal( SIGTERM, SIG_DFL );
@@ -118,7 +111,8 @@ static void usr1_handler(int x)
/*****************************************************
return a connection to a server
*******************************************************/
-static struct cli_state *do_connection(char *the_service)
+
+static struct cli_state *do_connection(char *svc_name)
{
struct cli_state *c;
struct nmb_name called, calling;
@@ -127,13 +121,13 @@ static struct cli_state *do_connection(char *the_service)
pstring server;
char *share;
- if (the_service[0] != '\\' || the_service[1] != '\\') {
+ if (svc_name[0] != '\\' || svc_name[1] != '\\') {
usage();
exit(1);
}
- pstrcpy(server, the_service+2);
- share = strchr_m(server,'\\');
+ pstrcpy(server, svc_name+2);
+ share = strchr(server,'\\');
if (!share) {
usage();
exit(1);
@@ -147,35 +141,25 @@ static struct cli_state *do_connection(char *the_service)
make_nmb_name(&called , server, 0x20);
again:
- zero_ip(&ip);
+ zero_ip(&ip);
if (have_ip) ip = dest_ip;
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
+ if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) == 0) ||
!cli_connect(c, server_n, &ip)) {
- DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
+ DEBUG(0,("%d: Connection to %s failed\n", getpid(), server_n));
if (c) {
cli_shutdown(c);
}
return NULL;
}
- /* SPNEGO doesn't work till we get NTSTATUS error support */
- /* But it is REQUIRED for kerberos authentication */
- if(!use_kerberos) c->use_spnego = False;
-
- /* The kernel doesn't yet know how to sign it's packets */
- c->sign_info.allow_smb_signing = False;
-
- /* Use kerberos authentication if specified */
- c->use_kerberos = use_kerberos;
-
if (!cli_session_request(c, &calling, &called)) {
char *p;
DEBUG(0,("%d: session request to %s failed (%s)\n",
- sys_getpid(), called.name, cli_errstr(c)));
+ getpid(), called.name, cli_errstr(c)));
cli_shutdown(c);
- if ((p=strchr_m(called.name, '.'))) {
+ if ((p=strchr(called.name, '.'))) {
*p = 0;
goto again;
}
@@ -186,10 +170,10 @@ static struct cli_state *do_connection(char *the_service)
return NULL;
}
- DEBUG(4,("%d: session request ok\n", sys_getpid()));
+ DEBUG(4,("%d: session request ok\n", getpid()));
if (!cli_negprot(c)) {
- DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
+ DEBUG(0,("%d: protocol negotiation failed\n", getpid()));
cli_shutdown(c);
return NULL;
}
@@ -202,44 +186,37 @@ static struct cli_state *do_connection(char *the_service)
}
/* This should be right for current smbfs. Future versions will support
- large files as well as unicode and oplocks. */
- c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS);
- if (!smbfs_has_lfs)
- c->capabilities &= ~CAP_LARGE_FILES;
- if (!smbfs_has_unicode)
- c->capabilities &= ~CAP_UNICODE;
- if (!status32_smbfs) {
- c->capabilities &= ~CAP_STATUS32;
- c->force_dos_errors = True;
- }
-
+ large files as well as unicode and oplocks. */
+ c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
+ CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
+ c->force_dos_errors = True;
if (!cli_session_setup(c, username,
password, strlen(password),
password, strlen(password),
workgroup)) {
/* if a password was not supplied then try again with a
- null username */
+ null username */
if (password[0] || !username[0] ||
- !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
+ !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
DEBUG(0,("%d: session setup failed: %s\n",
- sys_getpid(), cli_errstr(c)));
+ getpid(), cli_errstr(c)));
cli_shutdown(c);
return NULL;
}
DEBUG(0,("Anonymous login successful\n"));
}
- DEBUG(4,("%d: session setup ok\n", sys_getpid()));
+ DEBUG(4,("%d: session setup ok\n", getpid()));
if (!cli_send_tconX(c, share, "?????",
password, strlen(password)+1)) {
DEBUG(0,("%d: tree connect failed: %s\n",
- sys_getpid(), cli_errstr(c)));
+ getpid(), cli_errstr(c)));
cli_shutdown(c);
return NULL;
}
- DEBUG(4,("%d: tconx ok\n", sys_getpid()));
+ DEBUG(4,("%d: tconx ok\n", getpid()));
got_pass = True;
@@ -269,12 +246,12 @@ static void smb_umount(char *mount_point)
*/
if (umount(mount_point) != 0) {
DEBUG(0,("%d: Could not umount %s: %s\n",
- sys_getpid(), mount_point, strerror(errno)));
+ getpid(), mount_point, strerror(errno)));
return;
}
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
- DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
+ DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", getpid()));
return;
}
@@ -282,7 +259,7 @@ static void smb_umount(char *mount_point)
if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
- sys_getpid(), strerror(errno)));
+ getpid(), strerror(errno)));
return;
}
@@ -290,7 +267,7 @@ static void smb_umount(char *mount_point)
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
- sys_getpid(), strerror(errno)));
+ getpid(), strerror(errno)));
endmntent(mtab);
return;
}
@@ -305,7 +282,7 @@ static void smb_umount(char *mount_point)
if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
DEBUG(0,("%d: Error changing mode of %s: %s\n",
- sys_getpid(), MOUNTED_TMP, strerror(errno)));
+ getpid(), MOUNTED_TMP, strerror(errno)));
return;
}
@@ -313,12 +290,12 @@ static void smb_umount(char *mount_point)
if (rename(MOUNTED_TMP, MOUNTED) < 0) {
DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
- sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
+ getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
return;
}
if (unlink(MOUNTED"~") == -1) {
- DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
+ DEBUG(0,("%d: Can't remove "MOUNTED"~", getpid()));
return;
}
}
@@ -330,7 +307,7 @@ static void smb_umount(char *mount_point)
* not exit after open_sockets() or send_login() errors,
* as the smbfs mount would then have no way to recover.
*/
-static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
+static void send_fs_socket(char *svc_name, char *mount_point, struct cli_state *c)
{
int fd, closed = 0, res = 1;
pid_t parentpid = getppid();
@@ -341,7 +318,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
while (1) {
if ((fd = open(mount_point, O_RDONLY)) < 0) {
DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
- sys_getpid(), mount_point));
+ getpid(), mount_point));
break;
}
@@ -361,7 +338,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
if (res != 0) {
DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
- sys_getpid(), res));
+ getpid(), res));
close(fd);
break;
}
@@ -383,7 +360,6 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
If we don't do this we will "leak" sockets and memory on
each reconnection we have to make. */
- c->smb_rw_error = DO_NOT_DO_TDIS;
cli_shutdown(c);
c = NULL;
@@ -400,10 +376,11 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
}
/* here we are no longer interactive */
- set_remote_machine_name("smbmount", False); /* sneaky ... */
+ pstrcpy(remote_machine, "smbmount"); /* sneaky ... */
setup_logging("mount.smbfs", False);
+ append_log = True;
reopen_logs();
- DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
+ DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", svc_name, getpid()));
closed = 1;
}
@@ -413,23 +390,23 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
while (!c) {
CatchSignal(SIGUSR1, &usr1_handler);
pause();
- DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
- c = do_connection(the_service);
+ DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", getpid()));
+ c = do_connection(svc_name);
}
}
smb_umount(mount_point);
- DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
+ DEBUG(2,("mount.smbfs[%d]: exit\n", getpid()));
exit(1);
}
-/**
- * Mount a smbfs
- **/
+/****************************************************************************
+mount smbfs
+****************************************************************************/
static void init_mount(void)
{
- char mount_point[PATH_MAX+1];
+ char mount_point[MAXPATHLEN+1];
pstring tmp;
pstring svc2;
struct cli_state *c;
@@ -496,22 +473,13 @@ static void init_mount(void)
}
if (sys_fork() == 0) {
- char *smbmnt_path;
-
- asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
-
- if (file_exist(smbmnt_path, NULL)) {
- execv(smbmnt_path, args);
- fprintf(stderr,
- "smbfs/init_mount: execv of %s failed. Error was %s.",
- smbmnt_path, strerror(errno));
+ if (file_exist(BINDIR "/smbmnt", NULL)) {
+ execv(BINDIR "/smbmnt", args);
+ fprintf(stderr,"execv of %s failed. Error was %s.", BINDIR "/smbmnt", strerror(errno));
} else {
execvp("smbmnt", args);
- fprintf(stderr,
- "smbfs/init_mount: execv of %s failed. Error was %s.",
- "smbmnt", strerror(errno));
+ fprintf(stderr,"execvp of smbmnt failed. Error was %s.", strerror(errno) );
}
- free(smbmnt_path);
exit(1);
}
@@ -525,9 +493,6 @@ static void init_mount(void)
fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
/* FIXME: do some proper error handling */
exit(1);
- } else if (WIFSIGNALED(status)) {
- fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
- exit(1);
}
/* Ok... This is the rubicon for that mount point... At any point
@@ -647,9 +612,8 @@ static void read_credentials_file(char *filename)
pstrcpy(password, val);
got_pass = True;
}
- else if (strwicmp("username", param) == 0) {
+ else if (strwicmp("username", param) == 0)
pstrcpy(username, val);
- }
memset(buf, 0, sizeof(buf));
}
@@ -664,14 +628,13 @@ static void usage(void)
{
printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
- printf("Version %s\n\n",SAMBA_VERSION_STRING);
+ printf("Version %s\n\n",VERSION);
printf(
"Options:\n\
username=<arg> SMB username\n\
password=<arg> SMB password\n\
credentials=<filename> file with username/password\n\
- krb use kerberos (active directory)\n\
netbiosname=<arg> source NetBIOS name\n\
uid=<arg> mount uid or username\n\
gid=<arg> mount gid or groupname\n\
@@ -685,8 +648,6 @@ static void usage(void)
scope=<arg> NetBIOS scope\n\
iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
codepage=<arg> server codepage (cp850)\n\
- unicode use unicode when communicating with server\n\
- lfs large file system support\n\
ttl=<arg> dircache time to live\n\
guest don't prompt for a password\n\
ro mount read-only\n\
@@ -713,19 +674,9 @@ static void parse_mount_smb(int argc, char **argv)
char *opteq;
extern char *optarg;
int val;
+ extern pstring global_scope;
char *p;
- /* FIXME: This function can silently fail if the arguments are
- * not in the expected order.
-
- > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
- > requires that one gives "-o" before further options like username=...
- > . Without -o, the username=.. setting is *silently* ignored. I've
- > spent about an hour trying to find out why I couldn't log in now..
-
- */
-
-
if (argc < 2 || argv[1][0] == '-') {
usage();
exit(1);
@@ -753,22 +704,21 @@ static void parse_mount_smb(int argc, char **argv)
*/
for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
DEBUG(3, ("opts: %s\n", opts));
- if ((opteq = strchr_m(opts, '='))) {
+ if ((opteq = strchr(opts, '='))) {
val = atoi(opteq + 1);
*opteq = '\0';
if (!strcmp(opts, "username") ||
!strcmp(opts, "logon")) {
char *lp;
- got_user = True;
pstrcpy(username,opteq+1);
- if ((lp=strchr_m(username,'%'))) {
+ if ((lp=strchr(username,'%'))) {
*lp = 0;
pstrcpy(password,lp+1);
got_pass = True;
- memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
+ memset(strchr(opteq+1,'%')+1,'X',strlen(password));
}
- if ((lp=strchr_m(username,'/'))) {
+ if ((lp=strchr(username,'/'))) {
*lp = 0;
pstrcpy(workgroup,lp+1);
}
@@ -805,7 +755,7 @@ static void parse_mount_smb(int argc, char **argv)
} else if(!strcmp(opts, "sockopt")) {
pstrcpy(user_socket_options,opteq+1);
} else if(!strcmp(opts, "scope")) {
- set_global_scope(opteq+1);
+ pstrcpy(global_scope,opteq+1);
} else {
slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
p += strlen(p);
@@ -818,24 +768,10 @@ static void parse_mount_smb(int argc, char **argv)
} else if(!strcmp(opts, "guest")) {
*password = '\0';
got_pass = True;
- } else if(!strcmp(opts, "krb")) {
-#ifdef HAVE_KRB5
-
- use_kerberos = True;
- if(!status32_smbfs)
- fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
-#else
- fprintf(stderr,"No kerberos support compiled in\n");
- exit(1);
-#endif
} else if(!strcmp(opts, "rw")) {
mount_ro = 0;
} else if(!strcmp(opts, "ro")) {
mount_ro = 1;
- } else if(!strcmp(opts, "unicode")) {
- smbfs_has_unicode = True;
- } else if(!strcmp(opts, "lfs")) {
- smbfs_has_lfs = True;
} else {
strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
p += strlen(opts);
@@ -863,6 +799,7 @@ static void parse_mount_smb(int argc, char **argv)
{
extern char *optarg;
extern int optind;
+ static pstring servicesf = CONFIGFILE;
char *p;
DEBUGLEVEL = 1;
@@ -870,29 +807,21 @@ static void parse_mount_smb(int argc, char **argv)
/* here we are interactive, even if run from autofs */
setup_logging("mount.smbfs",True);
-#if 0 /* JRA - Urban says not needed ? */
- /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
- is to not announce any unicode capabilities as current smbfs does
- not support it. */
- p = getenv("CLI_FORCE_ASCII");
- if (p && !strcmp(p, "false"))
- unsetenv("CLI_FORCE_ASCII");
- else
- setenv("CLI_FORCE_ASCII", "true", 1);
-#endif
-
+ TimeInit();
+ charset_initialise();
+
in_client = True; /* Make sure that we tell lp_load we are */
if (getenv("USER")) {
pstrcpy(username,getenv("USER"));
- if ((p=strchr_m(username,'%'))) {
+ if ((p=strchr(username,'%'))) {
*p = 0;
pstrcpy(password,p+1);
got_pass = True;
- memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
+ memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
}
- strupper_m(username);
+ strupper(username);
}
if (getenv("PASSWD")) {
@@ -909,22 +838,20 @@ static void parse_mount_smb(int argc, char **argv)
pstrcpy(username,getenv("LOGNAME"));
}
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
+ if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n",
- dyn_CONFIGFILE);
+ servicesf);
}
parse_mount_smb(argc, argv);
- if (use_kerberos && !got_user) {
- got_pass = True;
- }
-
if (*credentials != 0) {
read_credentials_file(credentials);
}
- DEBUG(3,("mount.smbfs started (version %s)\n", SAMBA_VERSION_STRING));
+ DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
+
+ codepage_initialise(lp_client_code_page());
if (*workgroup == 0) {
pstrcpy(workgroup,lp_workgroup());
@@ -934,7 +861,7 @@ static void parse_mount_smb(int argc, char **argv)
if (!*my_netbios_name) {
pstrcpy(my_netbios_name, myhostname());
}
- strupper_m(my_netbios_name);
+ strupper(my_netbios_name);
init_mount();
return 0;
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index 5daefec5a55..38543e53abd 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -1,9 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0.
SMB backend for the Common UNIX Printing System ("CUPS")
Copyright 1999 by Easy Software Products
Copyright Andrew Tridgell 1994-1998
- Copyright Andrew Bartlett 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@ extern BOOL in_client; /* Boolean for client library */
*/
static void list_devices(void);
-static struct cli_state *smb_connect(const char *, const char *, const char *, const char *, const char *);
+static struct cli_state *smb_connect(char *, char *, char *, char *, char *);
static int smb_print(struct cli_state *, char *, FILE *);
@@ -52,11 +52,11 @@ static int smb_print(struct cli_state *, char *, FILE *);
int copies; /* Number of copies */
char uri[1024], /* URI */
*sep, /* Pointer to separator */
- *password; /* Password */
- const char *username, /* Username */
+ *username, /* Username */
+ *password, /* Password */
+ *workgroup, /* Workgroup */
*server, /* Server name */
*printer; /* Printer name */
- const char *workgroup; /* Workgroup */
FILE *fp; /* File to print */
int status=0; /* Status of LPD job */
struct cli_state *cli; /* SMB interface */
@@ -133,7 +133,7 @@ static int smb_print(struct cli_state *, char *, FILE *);
* Extract the destination from the URI...
*/
- if ((sep = strrchr_m(uri, '@')) != NULL)
+ if ((sep = strrchr(uri, '@')) != NULL)
{
username = uri + 6;
*sep++ = '\0';
@@ -144,7 +144,7 @@ static int smb_print(struct cli_state *, char *, FILE *);
* Extract password as needed...
*/
- if ((password = strchr_m(username, ':')) != NULL)
+ if ((password = strchr(username, ':')) != NULL)
*password++ = '\0';
else
password = "";
@@ -156,7 +156,7 @@ static int smb_print(struct cli_state *, char *, FILE *);
server = uri + 6;
}
- if ((sep = strchr_m(server, '/')) == NULL)
+ if ((sep = strchr(server, '/')) == NULL)
{
fputs("ERROR: Bad URI - need printer name!\n", stderr);
return (1);
@@ -165,7 +165,7 @@ static int smb_print(struct cli_state *, char *, FILE *);
*sep++ = '\0';
printer = sep;
- if ((sep = strchr_m(printer, '/')) != NULL)
+ if ((sep = strchr(printer, '/')) != NULL)
{
/*
* Convert to smb://[username:password@]workgroup/server/printer...
@@ -186,17 +186,22 @@ static int smb_print(struct cli_state *, char *, FILE *);
setup_logging("smbspool", True);
+ TimeInit();
+ charset_initialise();
+
in_client = True; /* Make sure that we tell lp_load we are */
- if (!lp_load(dyn_CONFIGFILE, True, False, False))
+ if (!lp_load(CONFIGFILE, True, False, False))
{
- fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+ fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", CONFIGFILE);
return (1);
}
if (workgroup == NULL)
workgroup = lp_workgroup();
+ codepage_initialise(lp_client_code_page());
+
load_interfaces();
do
@@ -265,34 +270,94 @@ list_devices(void)
*/
static struct cli_state * /* O - SMB connection */
-smb_connect(const char *workgroup, /* I - Workgroup */
- const char *server, /* I - Server */
- const char *share, /* I - Printer */
- const char *username, /* I - Username */
- const char *password) /* I - Password */
+smb_connect(char *workgroup, /* I - Workgroup */
+ char *server, /* I - Server */
+ char *share, /* I - Printer */
+ char *username, /* I - Username */
+ char *password) /* I - Password */
{
struct cli_state *c; /* New connection */
+ struct nmb_name called, /* NMB name of server */
+ calling; /* NMB name of client */
+ struct in_addr ip; /* IP address of server */
pstring myname; /* Client name */
- NTSTATUS nt_status;
+
/*
* Get the names and addresses of the client and server...
*/
get_myname(myname);
-
- nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????",
- username, workgroup, password, 0, Undefined, NULL);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status));
- return NULL;
+
+ zero_ip(&ip);
+
+ make_nmb_name(&calling, myname, 0x0);
+ make_nmb_name(&called, server, 0x20);
+
+ /*
+ * Open a new connection to the SMB server...
+ */
+
+ if ((c = cli_initialise(NULL)) == NULL)
+ {
+ fputs("ERROR: cli_initialise() failed...\n", stderr);
+ return (NULL);
+ }
+
+ if (!cli_set_port(c, SMB_PORT))
+ {
+ fputs("ERROR: cli_set_port() failed...\n", stderr);
+ cli_shutdown(c);
+ return (NULL);
+ }
+
+ if (!cli_connect(c, server, &ip))
+ {
+ fputs("ERROR: cli_connect() failed...\n", stderr);
+ cli_shutdown(c);
+ return (NULL);
+ }
+
+ if (!cli_session_request(c, &calling, &called))
+ {
+ fputs("ERROR: cli_session_request() failed...\n", stderr);
+ cli_shutdown(c);
+ return (NULL);
+ }
+
+ if (!cli_negprot(c))
+ {
+ fputs("ERROR: SMB protocol negotiation failed\n", stderr);
+ cli_shutdown(c);
+ return (NULL);
}
- /*
- * Return the new connection...
- */
-
+ /*
+ * Do password stuff...
+ */
+
+ if (!cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup))
+ {
+ fprintf(stderr, "ERROR: SMB session setup failed: %s\n", cli_errstr(c));
+ cli_shutdown(c);
+ return (NULL);
+ }
+
+ if (!cli_send_tconX(c, share, "?????",
+ password, strlen(password)+1))
+ {
+ fprintf(stderr, "ERROR: SMB tree connect failed: %s\n", cli_errstr(c));
+ cli_shutdown(c);
+ return (NULL);
+ }
+
+ /*
+ * Return the new connection...
+ */
+
return (c);
}
diff --git a/source/client/smbumount.c b/source/client/smbumount.c
index 9ea3083a6f9..2c2243528d6 100644
--- a/source/client/smbumount.c
+++ b/source/client/smbumount.c
@@ -15,6 +15,10 @@
#include <linux/smb_mount.h>
#include <linux/smb_fs.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
/* This is a (hopefully) temporary hack due to the fact that
sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
This may change in the future and smb.h may get fixed in the
@@ -31,6 +35,7 @@ static void
usage(void)
{
printf("usage: smbumount mountpoint\n");
+ printf("Version: %s\n", VERSION);
}
static int
@@ -42,9 +47,9 @@ umount_ok(const char *mount_point)
__kernel_uid_t mount_uid;
if (fid == -1) {
- fprintf(stderr, "Could not open %s: %s\n",
- mount_point, strerror(errno));
- return -1;
+ /* fprintf(stderr, "Could not open %s: %s\n",
+ mount_point, strerror(errno)); */
+ return 1; /* maybe try again */
}
if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
@@ -64,6 +69,92 @@ umount_ok(const char *mount_point)
return 0;
}
+#define MAX_READLINKS 32
+/* myrealpath from mount, it could get REAL path under a broken connection */
+char *myrealpath(const char *path, char *resolved_path, int maxreslth)
+{
+ int readlinks = 0,m,n;
+ char *npath,*buf;
+ char link_path[PATH_MAX + 1];
+
+ npath = resolved_path;
+
+ if(*path != '/')
+ {
+ if(!getcwd(npath, maxreslth - 2))
+ return NULL;
+ npath += strlen(npath);
+ if(npath[-1] != '/')
+ *(npath++) = '/';
+ else
+ {
+ *npath++ = '/';
+ path++;
+ }
+ }
+
+ while(*path != '\0')
+ {
+ if(*path == '/')
+ {
+ path++;
+ continue;
+ }
+ if(*path == '.' && (path[1] == '\0' || path[1] == '/'))
+ {
+ path++;
+ continue;
+ }
+ if(*path == '.' && path[1] == '.' &&
+ (path[2] == '\0' || path[2] == '/'))
+ {
+ path += 2;
+ while(npath > resolved_path + 1 &&
+ (--npath)[-1] != '/');
+ continue;
+ }
+ while(*path != '\0' && *path != '/')
+ {
+ if(npath-resolved_path > maxreslth - 2)
+ return NULL;
+ *npath++ = *path++;
+ }
+ if(readlinks++ > MAX_READLINKS)
+ return NULL;
+ *npath = '\0';
+ n = readlink(resolved_path, link_path, PATH_MAX);
+ if(n < 0)
+ {
+ if(errno != EINVAL) return NULL;
+ }
+ else
+ {
+ link_path[n] = '\0';
+ if(*link_path == '/')
+ npath = resolved_path;
+ else while(*(--npath) != '/');
+ m = strlen(path);
+ if((buf = malloc(m + n + 1)) == NULL)
+ {
+ fprintf(stderr,"Not enough memory.\n");
+ return NULL;
+ }
+ memcpy(buf, link_path, n);
+ memcpy(buf + n, path, m + 1);
+ path = buf;
+ }
+ *npath++ = '/';
+ }
+ if(npath != resolved_path + 1)
+ {
+ while(npath > resolved_path && npath[-1] == '/')
+ npath--;
+ if(npath == resolved_path) return NULL;
+ }
+ *npath = '\0';
+ return resolved_path;
+}
+
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
@@ -72,7 +163,8 @@ umount_ok(const char *mount_point)
static char *
canonicalize (char *path)
{
- char *canonical = malloc (PATH_MAX + 1);
+ char *npath,*canonical = malloc (PATH_MAX + 1);
+ int i;
if (!canonical) {
fprintf(stderr, "Error! Not enough memory!\n");
@@ -86,12 +178,18 @@ canonicalize (char *path)
if (path == NULL)
return NULL;
-
- if (realpath (path, canonical))
+
+/* if (realpath (path, canonical)) */
+ if(myrealpath(path, canonical, PATH_MAX))
return canonical;
- strncpy (canonical, path, PATH_MAX);
- canonical[PATH_MAX] = '\0';
+ pstrcpy (canonical, path);
+ if((i = strlen(canonical)) > 1 && i <= PATH_MAX)
+ {
+ path = canonical + i;
+ while(*(--path) == '/')
+ *path = '\0';
+ }
return canonical;
}
@@ -122,14 +220,34 @@ main(int argc, char *argv[])
exit(1);
}
- if (umount_ok(mount_point) != 0) {
- exit(1);
+ if ((fd = umount_ok(mount_point)) != 0) {
+ if(fd == 1)
+ {
+ if((fd = umount_ok(mount_point)) != 0)
+ {
+ if(fd == 1)
+ {
+ fprintf(stderr, "Could not open %s: %s\n",
+ mount_point, strerror(errno));
+ }
+ exit(1);
+ }
+ }
+ else exit(1);
}
+#if !defined(MNT_DETACH)
+ #define MNT_DETACH 2
+#endif
+
if (umount(mount_point) != 0) {
- fprintf(stderr, "Could not umount %s: %s\n",
- mount_point, strerror(errno));
- exit(1);
+ /* fprintf(stderr, "Could not umount %s: %s\n,Trying lazy umount.\n",
+ mount_point, strerror(errno)); */
+ if(umount2(mount_point,MNT_DETACH) != 0)
+ {
+ fprintf(stderr, "Lazy umount failed.\n");
+ return 1;
+ }
}
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
diff --git a/source/client/tree.c b/source/client/tree.c
deleted file mode 100644
index 97ad7742e31..00000000000
--- a/source/client/tree.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB client GTK+ tree-based application
- Copyright (C) Andrew Tridgell 1998
- Copyright (C) Richard Sharpe 2001
- Copyright (C) John Terpstra 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* example-gtk+ application, ripped off from the gtk+ tree.c sample */
-
-#include <stdio.h>
-#include <errno.h>
-#include <gtk/gtk.h>
-#include "libsmbclient.h"
-
-static GtkWidget *clist;
-
-struct tree_data {
-
- guint32 type; /* Type of tree item, an SMBC_TYPE */
- char name[256]; /* May need to change this later */
-
-};
-
-static void tree_error_message(gchar *message) {
-
- GtkWidget *dialog, *label, *okay_button;
-
- /* Create the widgets */
-
- dialog = gtk_dialog_new();
- gtk_window_set_modal(GTK_WINDOW(dialog), True);
- label = gtk_label_new (message);
- okay_button = gtk_button_new_with_label("Okay");
-
- /* Ensure that the dialog box is destroyed when the user clicks ok. */
-
- gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
- GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
- okay_button);
-
- /* Add the label, and show everything we've added to the dialog. */
-
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
- label);
- gtk_widget_show_all (dialog);
-}
-
-/*
- * We are given a widget, and we want to retrieve its URL so we
- * can do a directory listing.
- *
- * We walk back up the tree, picking up pieces until we hit a server or
- * workgroup type and return a path from there
- */
-
-static pstring path_string;
-
-char *get_path(GtkWidget *item)
-{
- GtkWidget *p = item;
- struct tree_data *pd;
- char *comps[1024]; /* We keep pointers to the components here */
- int i = 0, j, level,type;
-
- /* Walk back up the tree, getting the private data */
-
- level = GTK_TREE(item->parent)->level;
-
- /* Pick up this item's component info */
-
- pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(item));
-
- comps[i++] = pd->name;
- type = pd->type;
-
- while (level > 0 && type != SMBC_SERVER && type != SMBC_WORKGROUP) {
-
- /* Find the parent and extract the data etc ... */
-
- p = GTK_WIDGET(p->parent);
- p = GTK_WIDGET(GTK_TREE(p)->tree_owner);
-
- pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(p));
-
- level = GTK_TREE(item->parent)->level;
-
- comps[i++] = pd->name;
- type = pd->type;
-
- }
-
- /*
- * Got a list of comps now, should check that we did not hit a workgroup
- * when we got other things as well ... Later
- *
- * Now, build the path
- */
-
- pstrcpy( path_string, "smb:/" );
-
- for (j = i - 1; j >= 0; j--) {
-
- strncat(path_string, "/", sizeof(path_string) - strlen(path_string));
- strncat(path_string, comps[j], sizeof(path_string) - strlen(path_string));
-
- }
-
- fprintf(stdout, "Path string = %s\n", path_string);
-
- return path_string;
-
-}
-
-struct tree_data *make_tree_data(guint32 type, const char *name)
-{
- struct tree_data *p = (struct tree_data *)malloc(sizeof(struct tree_data));
-
- if (p) {
-
- p->type = type;
- strncpy(p->name, name, sizeof(p->name));
-
- }
-
- return p;
-
-}
-
-/* Note that this is called every time the user clicks on an item,
- whether it is already selected or not. */
-static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
- GtkWidget *subtree)
-{
- gint dh, err, dirlen;
- char dirbuf[512];
- struct smbc_dirent *dirp;
- struct stat st1;
- pstring path, path1;
-
- g_print ("select_child called for root tree %p, subtree %p, child %p\n",
- root_tree, subtree, child);
-
- /* Now, figure out what it is, and display it in the clist ... */
-
- gtk_clist_clear(GTK_CLIST(clist)); /* Clear the CLIST */
-
- /* Now, get the private data for the subtree */
-
- strncpy(path, get_path(child), 1024);
-
- if ((dh = smbc_opendir(path)) < 0) { /* Handle error */
-
- g_print("cb_select_child: Could not open dir %s, %s\n", path,
- strerror(errno));
-
- gtk_main_quit();
-
- return;
-
- }
-
- while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
- sizeof(dirbuf))) != 0) {
-
- if (err < 0) {
-
- g_print("cb_select_child: Could not read dir %s, %s\n", path,
- strerror(errno));
-
- gtk_main_quit();
-
- return;
-
- }
-
- dirp = (struct smbc_dirent *)dirbuf;
-
- while (err > 0) {
- gchar col1[128], col2[128], col3[128], col4[128];
- gchar *rowdata[4] = {col1, col2, col3, col4};
-
- dirlen = dirp->dirlen;
-
- /* Format each of the items ... */
-
- strncpy(col1, dirp->name, 128);
-
- col2[0] = col3[0] = col4[0] = (char)0;
-
- switch (dirp->smbc_type) {
-
- case SMBC_WORKGROUP:
-
- break;
-
- case SMBC_SERVER:
-
- strncpy(col2, (dirp->comment?dirp->comment:""), 128);
-
- break;
-
- case SMBC_FILE_SHARE:
-
- strncpy(col2, (dirp->comment?dirp->comment:""), 128);
-
- break;
-
- case SMBC_PRINTER_SHARE:
-
- strncpy(col2, (dirp->comment?dirp->comment:""), 128);
- break;
-
- case SMBC_COMMS_SHARE:
-
- break;
-
- case SMBC_IPC_SHARE:
-
- break;
-
- case SMBC_DIR:
- case SMBC_FILE:
-
- /* Get stats on the file/dir and see what we have */
-
- if ((strcmp(dirp->name, ".") != 0) &&
- (strcmp(dirp->name, "..") != 0)) {
-
- strncpy(path1, path, sizeof(path1));
- strncat(path1, "/", sizeof(path) - strlen(path));
- strncat(path1, dirp->name, sizeof(path) - strlen(path));
-
- if (smbc_stat(path1, &st1) < 0) {
-
- if (errno != EBUSY) {
-
- g_print("cb_select_child: Could not stat file %s, %s\n", path1,
- strerror(errno));
-
- gtk_main_quit();
-
- return;
-
- }
- else {
-
- strncpy(col2, "Device or resource busy", sizeof(col2));
-
- }
- }
- else {
- /* Now format each of the relevant things ... */
-
- snprintf(col2, sizeof(col2), "%c%c%c%c%c%c%c%c%c(%0X)",
- (st1.st_mode&S_IRUSR?'r':'-'),
- (st1.st_mode&S_IWUSR?'w':'-'),
- (st1.st_mode&S_IXUSR?'x':'-'),
- (st1.st_mode&S_IRGRP?'r':'-'),
- (st1.st_mode&S_IWGRP?'w':'-'),
- (st1.st_mode&S_IXGRP?'x':'-'),
- (st1.st_mode&S_IROTH?'r':'-'),
- (st1.st_mode&S_IWOTH?'w':'-'),
- (st1.st_mode&S_IXOTH?'x':'-'),
- st1.st_mode);
- snprintf(col3, sizeof(col3), "%u", st1.st_size);
- snprintf(col4, sizeof(col4), "%s", ctime(&st1.st_mtime));
- }
- }
-
- break;
-
- default:
-
- break;
- }
-
- gtk_clist_append(GTK_CLIST(clist), rowdata);
-
- (char *)dirp += dirlen;
- err -= dirlen;
-
- }
-
- }
-
-}
-
-/* Note that this is never called */
-static void cb_unselect_child( GtkWidget *root_tree,
- GtkWidget *child,
- GtkWidget *subtree )
-{
- g_print ("unselect_child called for root tree %p, subtree %p, child %p\n",
- root_tree, subtree, child);
-}
-
-/* for all the GtkItem:: and GtkTreeItem:: signals */
-static void cb_itemsignal( GtkWidget *item,
- gchar *signame )
-{
- GtkWidget *real_tree, *aitem, *subtree;
- gchar *name;
- GtkLabel *label;
- gint dh, err, dirlen, level;
- char dirbuf[512];
- struct smbc_dirent *dirp;
-
- label = GTK_LABEL (GTK_BIN (item)->child);
- /* Get the text of the label */
- gtk_label_get (label, &name);
-
- level = GTK_TREE(item->parent)->level;
-
- /* Get the level of the tree which the item is in */
- g_print ("%s called for item %s->%p, level %d\n", signame, name,
- item, GTK_TREE (item->parent)->level);
-
- real_tree = GTK_TREE_ITEM_SUBTREE(item); /* Get the subtree */
-
- if (strncmp(signame, "expand", 6) == 0) { /* Expand called */
- char server[128];
-
- if ((dh = smbc_opendir(get_path(item))) < 0) { /* Handle error */
- gchar errmsg[256];
-
- g_print("cb_itemsignal: Could not open dir %s, %s\n", get_path(item),
- strerror(errno));
-
- slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not open dir %s, %s\n", get_path(item), strerror(errno));
-
- tree_error_message(errmsg);
-
- /* gtk_main_quit();*/
-
- return;
-
- }
-
- while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
- sizeof(dirbuf))) != 0) {
-
- if (err < 0) { /* An error, report it */
- gchar errmsg[256];
-
- g_print("cb_itemsignal: Could not read dir smbc://, %s\n",
- strerror(errno));
-
- slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not read dir smbc://, %s\n", strerror(errno));
-
- tree_error_message(errmsg);
-
- /* gtk_main_quit();*/
-
- return;
-
- }
-
- dirp = (struct smbc_dirent *)dirbuf;
-
- while (err > 0) {
- struct tree_data *my_data;
-
- dirlen = dirp->dirlen;
-
- my_data = make_tree_data(dirp->smbc_type, dirp->name);
-
- if (!my_data) {
-
- g_print("Could not allocate space for tree_data: %s\n",
- dirp->name);
-
- gtk_main_quit();
- return;
-
- }
-
- aitem = gtk_tree_item_new_with_label(dirp->name);
-
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(aitem), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(aitem), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(aitem), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(aitem), "expand",
- GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
- gtk_signal_connect (GTK_OBJECT(aitem), "collapse",
- GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
- /* Add it to the parent tree */
- gtk_tree_append (GTK_TREE(real_tree), aitem);
-
- gtk_widget_show (aitem);
-
- gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data);
-
- fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
-
- if (dirp->smbc_type != SMBC_FILE &&
- dirp->smbc_type != SMBC_IPC_SHARE &&
- (strcmp(dirp->name, ".") != 0) &&
- (strcmp(dirp->name, "..") !=0)){
-
- subtree = gtk_tree_new();
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree);
-
- gtk_signal_connect(GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), real_tree);
- gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
-
- }
-
- (char *)dirp += dirlen;
- err -= dirlen;
-
- }
-
- }
-
- smbc_closedir(dh);
-
- }
- else if (strncmp(signame, "collapse", 8) == 0) {
- GtkWidget *subtree = gtk_tree_new();
-
- gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children);
-
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
-
- gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), real_tree);
- gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
-
- }
-
-}
-
-static void cb_selection_changed( GtkWidget *tree )
-{
- GList *i;
-
- g_print ("selection_change called for tree %p\n", tree);
- g_print ("selected objects are:\n");
-
- i = GTK_TREE_SELECTION(tree);
- while (i){
- gchar *name;
- GtkLabel *label;
- GtkWidget *item;
-
- /* Get a GtkWidget pointer from the list node */
- item = GTK_WIDGET (i->data);
- label = GTK_LABEL (GTK_BIN (item)->child);
- gtk_label_get (label, &name);
- g_print ("\t%s on level %d\n", name, GTK_TREE
- (item->parent)->level);
- i = i->next;
- }
-}
-
-/*
- * Expand or collapse the whole network ...
- */
-static void cb_wholenet(GtkWidget *item, gchar *signame)
-{
- GtkWidget *real_tree, *aitem, *subtree;
- gchar *name;
- GtkLabel *label;
- gint dh, err, dirlen;
- char dirbuf[512];
- struct smbc_dirent *dirp;
-
- label = GTK_LABEL (GTK_BIN (item)->child);
- gtk_label_get (label, &name);
- g_print ("%s called for item %s->%p, level %d\n", signame, name,
- item, GTK_TREE (item->parent)->level);
-
- real_tree = GTK_TREE_ITEM_SUBTREE(item); /* Get the subtree */
-
- if (strncmp(signame, "expand", 6) == 0) { /* Expand called */
-
- if ((dh = smbc_opendir("smb://")) < 0) { /* Handle error */
-
- g_print("cb_wholenet: Could not open dir smbc://, %s\n",
- strerror(errno));
-
- gtk_main_quit();
-
- return;
-
- }
-
- while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
- sizeof(dirbuf))) != 0) {
-
- if (err < 0) { /* An error, report it */
-
- g_print("cb_wholenet: Could not read dir smbc://, %s\n",
- strerror(errno));
-
- gtk_main_quit();
-
- return;
-
- }
-
- dirp = (struct smbc_dirent *)dirbuf;
-
- while (err > 0) {
- struct tree_data *my_data;
-
- dirlen = dirp->dirlen;
-
- my_data = make_tree_data(dirp->smbc_type, dirp->name);
-
- aitem = gtk_tree_item_new_with_label(dirp->name);
-
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(aitem), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(aitem), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(aitem), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(aitem), "expand",
- GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
- gtk_signal_connect (GTK_OBJECT(aitem), "collapse",
- GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
-
- gtk_tree_append (GTK_TREE(real_tree), aitem);
- /* Show it - this can be done at any time */
- gtk_widget_show (aitem);
-
- gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data);
-
- fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
-
- subtree = gtk_tree_new();
-
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree);
-
- gtk_signal_connect(GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), real_tree);
- gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
-
- (char *)dirp += dirlen;
- err -= dirlen;
-
- }
-
- }
-
- smbc_closedir(dh);
-
- }
- else { /* Must be collapse ... FIXME ... */
- GtkWidget *subtree = gtk_tree_new();
-
- gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children);
-
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
-
- gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), real_tree);
- gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
-
-
- }
-
-}
-
-/* Should put up a dialog box to ask the user for username and password */
-
-static void
-auth_fn(const char *server, const char *share,
- char *workgroup, int wgmaxlen, char *username, int unmaxlen,
- char *password, int pwmaxlen)
-{
-
- strncpy(username, "test", unmaxlen);
- strncpy(password, "test", pwmaxlen);
-
-}
-
-static char *col_titles[] = {
- "Name", "Attributes", "Size", "Modification Date",
-};
-
-int main( int argc,
- char *argv[] )
-{
- GtkWidget *window, *scrolled_win, *scrolled_win2, *tree;
- GtkWidget *subtree, *item, *main_hbox, *r_pane, *l_pane;
- gint err, dh;
- gint i;
- char dirbuf[512];
- struct smbc_dirent *dirp;
-
- gtk_init (&argc, &argv);
-
- /* Init the smbclient library */
-
- err = smbc_init(auth_fn, 10);
-
- /* Print an error response ... */
-
- if (err < 0) {
-
- fprintf(stderr, "smbc_init returned %s (%i)\nDo you have a ~/.smb/smb.conf file?\n", strerror(errno), errno);
- exit(1);
-
- }
-
- /* a generic toplevel window */
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_name(window, "main browser window");
- gtk_signal_connect (GTK_OBJECT(window), "delete_event",
- GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
- gtk_window_set_title(GTK_WINDOW(window), "The Linux Windows Network Browser");
- gtk_widget_set_usize(GTK_WIDGET(window), 750, -1);
- gtk_container_set_border_width (GTK_CONTAINER(window), 5);
-
- gtk_widget_show (window);
-
- /* A container for the two panes ... */
-
- main_hbox = gtk_hbox_new(FALSE, 1);
- gtk_container_border_width(GTK_CONTAINER(main_hbox), 1);
- gtk_container_add(GTK_CONTAINER(window), main_hbox);
-
- gtk_widget_show(main_hbox);
-
- l_pane = gtk_hpaned_new();
- gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
- r_pane = gtk_hpaned_new();
- gtk_paned_gutter_size(GTK_PANED(r_pane), (GTK_PANED(r_pane))->handle_size);
- gtk_container_add(GTK_CONTAINER(main_hbox), l_pane);
- gtk_widget_show(l_pane);
-
- /* A generic scrolled window */
- scrolled_win = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_set_usize (scrolled_win, 150, 200);
- gtk_container_add (GTK_CONTAINER(l_pane), scrolled_win);
- gtk_widget_show (scrolled_win);
-
- /* Another generic scrolled window */
- scrolled_win2 = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win2),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_set_usize (scrolled_win2, 150, 200);
- gtk_paned_add2 (GTK_PANED(l_pane), scrolled_win2);
- gtk_widget_show (scrolled_win2);
-
- /* Create the root tree */
- tree = gtk_tree_new();
- g_print ("root tree is %p\n", tree);
- /* connect all GtkTree:: signals */
- gtk_signal_connect (GTK_OBJECT(tree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), tree);
- gtk_signal_connect (GTK_OBJECT(tree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), tree);
- gtk_signal_connect (GTK_OBJECT(tree), "selection_changed",
- GTK_SIGNAL_FUNC(cb_selection_changed), tree);
- /* Add it to the scrolled window */
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_win),
- tree);
- /* Set the selection mode */
- gtk_tree_set_selection_mode (GTK_TREE(tree),
- GTK_SELECTION_MULTIPLE);
- /* Show it */
- gtk_widget_show (tree);
-
- /* Now, create a clist and attach it to the second pane */
-
- clist = gtk_clist_new_with_titles(4, col_titles);
-
- gtk_container_add (GTK_CONTAINER(scrolled_win2), clist);
-
- gtk_widget_show(clist);
-
- /* Now, build the top level display ... */
-
- if ((dh = smbc_opendir("smb:///")) < 0) {
-
- fprintf(stderr, "Could not list default workgroup: smb:///: %s\n",
- strerror(errno));
-
- exit(1);
-
- }
-
- /* Create a tree item for Whole Network */
-
- item = gtk_tree_item_new_with_label ("Whole Network");
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(item), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(item), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(item), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(item), "expand",
- GTK_SIGNAL_FUNC(cb_wholenet), "expand");
- gtk_signal_connect (GTK_OBJECT(item), "collapse",
- GTK_SIGNAL_FUNC(cb_wholenet), "collapse");
- /* Add it to the parent tree */
- gtk_tree_append (GTK_TREE(tree), item);
- /* Show it - this can be done at any time */
- gtk_widget_show (item);
-
- subtree = gtk_tree_new(); /* A subtree for Whole Network */
-
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
-
- gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), tree);
- gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), tree);
-
- /* Now, get the items in smb:/// and add them to the tree */
-
- dirp = (struct smbc_dirent *)dirbuf;
-
- while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
- sizeof(dirbuf))) != 0) {
-
- if (err < 0) { /* Handle the error */
-
- fprintf(stderr, "Could not read directory for smbc:///: %s\n",
- strerror(errno));
-
- exit(1);
-
- }
-
- fprintf(stdout, "Dir len: %u\n", err);
-
- while (err > 0) { /* Extract each entry and make a sub-tree */
- struct tree_data *my_data;
- int dirlen = dirp->dirlen;
-
- my_data = make_tree_data(dirp->smbc_type, dirp->name);
-
- item = gtk_tree_item_new_with_label(dirp->name);
- /* Connect all GtkItem:: and GtkTreeItem:: signals */
- gtk_signal_connect (GTK_OBJECT(item), "select",
- GTK_SIGNAL_FUNC(cb_itemsignal), "select");
- gtk_signal_connect (GTK_OBJECT(item), "deselect",
- GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
- gtk_signal_connect (GTK_OBJECT(item), "toggle",
- GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
- gtk_signal_connect (GTK_OBJECT(item), "expand",
- GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
- gtk_signal_connect (GTK_OBJECT(item), "collapse",
- GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
- /* Add it to the parent tree */
- gtk_tree_append (GTK_TREE(tree), item);
- /* Show it - this can be done at any time */
- gtk_widget_show (item);
-
- gtk_object_set_user_data(GTK_OBJECT(item), (gpointer)my_data);
-
- fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
-
- subtree = gtk_tree_new();
-
- gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
-
- gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
- GTK_SIGNAL_FUNC(cb_select_child), tree);
- gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
- GTK_SIGNAL_FUNC(cb_unselect_child), tree);
-
- (char *)dirp += dirlen;
- err -= dirlen;
-
- }
-
- }
-
- smbc_closedir(dh); /* FIXME, check for error :-) */
-
- /* Show the window and loop endlessly */
- gtk_main();
- return 0;
-}
-/* example-end */
diff --git a/source/codepages/CP1125.TXT b/source/codepages/CP1125.TXT
new file mode 100755
index 00000000000..fbf4ad2951d
--- /dev/null
+++ b/source/codepages/CP1125.TXT
@@ -0,0 +1,263 @@
+#
+# DOS Ukrainian (RUSCII, cp1125) to UNICODE translation table
+#
+# Based on cp866u_uni.tbl from lynx 2.8.2 distribution
+# by porokh
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x0410 #CYRILLIC CAPITAL LETTER A
+0x81 0x0411 #CYRILLIC CAPITAL LETTER BE
+0x82 0x0412 #CYRILLIC CAPITAL LETTER VE
+0x83 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0x84 0x0414 #CYRILLIC CAPITAL LETTER DE
+0x85 0x0415 #CYRILLIC CAPITAL LETTER IE
+0x86 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0x87 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0x88 0x0418 #CYRILLIC CAPITAL LETTER I
+0x89 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0x8a 0x041a #CYRILLIC CAPITAL LETTER KA
+0x8b 0x041b #CYRILLIC CAPITAL LETTER EL
+0x8c 0x041c #CYRILLIC CAPITAL LETTER EM
+0x8d 0x041d #CYRILLIC CAPITAL LETTER EN
+0x8e 0x041e #CYRILLIC CAPITAL LETTER O
+0x8f 0x041f #CYRILLIC CAPITAL LETTER PE
+0x90 0x0420 #CYRILLIC CAPITAL LETTER ER
+0x91 0x0421 #CYRILLIC CAPITAL LETTER ES
+0x92 0x0422 #CYRILLIC CAPITAL LETTER TE
+0x93 0x0423 #CYRILLIC CAPITAL LETTER U
+0x94 0x0424 #CYRILLIC CAPITAL LETTER EF
+0x95 0x0425 #CYRILLIC CAPITAL LETTER HA
+0x96 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0x97 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0x98 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0x99 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0x9a 0x042a #CYRILLIC CAPITAL LETTER HARD SIGN
+0x9b 0x042b #CYRILLIC CAPITAL LETTER YERU
+0x9c 0x042c #CYRILLIC CAPITAL LETTER SOFT SIGN
+0x9d 0x042d #CYRILLIC CAPITAL LETTER E
+0x9e 0x042e #CYRILLIC CAPITAL LETTER YU
+0x9f 0x042f #CYRILLIC CAPITAL LETTER YA
+0xa0 0x0430 #CYRILLIC SMALL LETTER A
+0xa1 0x0431 #CYRILLIC SMALL LETTER BE
+0xa2 0x0432 #CYRILLIC SMALL LETTER VE
+0xa3 0x0433 #CYRILLIC SMALL LETTER GHE
+0xa4 0x0434 #CYRILLIC SMALL LETTER DE
+0xa5 0x0435 #CYRILLIC SMALL LETTER IE
+0xa6 0x0436 #CYRILLIC SMALL LETTER ZHE
+0xa7 0x0437 #CYRILLIC SMALL LETTER ZE
+0xa8 0x0438 #CYRILLIC SMALL LETTER I
+0xa9 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0xaa 0x043a #CYRILLIC SMALL LETTER KA
+0xab 0x043b #CYRILLIC SMALL LETTER EL
+0xac 0x043c #CYRILLIC SMALL LETTER EM
+0xad 0x043d #CYRILLIC SMALL LETTER EN
+0xae 0x043e #CYRILLIC SMALL LETTER O
+0xaf 0x043f #CYRILLIC SMALL LETTER PE
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x0440 #CYRILLIC SMALL LETTER ER
+0xe1 0x0441 #CYRILLIC SMALL LETTER ES
+0xe2 0x0442 #CYRILLIC SMALL LETTER TE
+0xe3 0x0443 #CYRILLIC SMALL LETTER U
+0xe4 0x0444 #CYRILLIC SMALL LETTER EF
+0xe5 0x0445 #CYRILLIC SMALL LETTER HA
+0xe6 0x0446 #CYRILLIC SMALL LETTER TSE
+0xe7 0x0447 #CYRILLIC SMALL LETTER CHE
+0xe8 0x0448 #CYRILLIC SMALL LETTER SHA
+0xe9 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0xea 0x044a #CYRILLIC SMALL LETTER HARD SIGN
+0xeb 0x044b #CYRILLIC SMALL LETTER YERU
+0xec 0x044c #CYRILLIC SMALL LETTER SOFT SIGN
+0xed 0x044d #CYRILLIC SMALL LETTER E
+0xee 0x044e #CYRILLIC SMALL LETTER YU
+0xef 0x044f #CYRILLIC SMALL LETTER YA
+0xf0 0x0401 #CYRILLIC CAPITAL LETTER IO
+0xf1 0x0451 #CYRILLIC SMALL LETTER IO
+0xf2 0x0490 #CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0xf3 0x0491 #CYRILLIC SMALL LETTER GHE WITH UPTURN
+0xf4 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xf5 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE
+0xf6 0x0406 #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xf7 0x0456 #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xf8 0x0407 #CYRILLIC CAPITAL LETTER YI
+0xf9 0x0457 #CYRILLIC SMALL LETTER YI
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x221a #SQUARE ROOT
+0xfc 0x2116 #NUMERO SIGN
+0xfd 0x00a4 #CURRENCY SIGN
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+
diff --git a/source/codepages/CP1251.TXT b/source/codepages/CP1251.TXT
new file mode 100755
index 00000000000..f6876e6d639
--- /dev/null
+++ b/source/codepages/CP1251.TXT
@@ -0,0 +1,274 @@
+#
+# Name: cp1251 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.01
+# Table format: Format A
+# Date: 04/15/98
+#
+# Contact: cpxlate@microsoft.com
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp1251 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp1251 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0A 0x000A #LINE FEED
+0x0B 0x000B #VERTICAL TABULATION
+0x0C 0x000C #FORM FEED
+0x0D 0x000D #CARRIAGE RETURN
+0x0E 0x000E #SHIFT OUT
+0x0F 0x000F #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1A 0x001A #SUBSTITUTE
+0x1B 0x001B #ESCAPE
+0x1C 0x001C #FILE SEPARATOR
+0x1D 0x001D #GROUP SEPARATOR
+0x1E 0x001E #RECORD SEPARATOR
+0x1F 0x001F #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2A 0x002A #ASTERISK
+0x2B 0x002B #PLUS SIGN
+0x2C 0x002C #COMMA
+0x2D 0x002D #HYPHEN-MINUS
+0x2E 0x002E #FULL STOP
+0x2F 0x002F #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3A 0x003A #COLON
+0x3B 0x003B #SEMICOLON
+0x3C 0x003C #LESS-THAN SIGN
+0x3D 0x003D #EQUALS SIGN
+0x3E 0x003E #GREATER-THAN SIGN
+0x3F 0x003F #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4A 0x004A #LATIN CAPITAL LETTER J
+0x4B 0x004B #LATIN CAPITAL LETTER K
+0x4C 0x004C #LATIN CAPITAL LETTER L
+0x4D 0x004D #LATIN CAPITAL LETTER M
+0x4E 0x004E #LATIN CAPITAL LETTER N
+0x4F 0x004F #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5A 0x005A #LATIN CAPITAL LETTER Z
+0x5B 0x005B #LEFT SQUARE BRACKET
+0x5C 0x005C #REVERSE SOLIDUS
+0x5D 0x005D #RIGHT SQUARE BRACKET
+0x5E 0x005E #CIRCUMFLEX ACCENT
+0x5F 0x005F #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6A 0x006A #LATIN SMALL LETTER J
+0x6B 0x006B #LATIN SMALL LETTER K
+0x6C 0x006C #LATIN SMALL LETTER L
+0x6D 0x006D #LATIN SMALL LETTER M
+0x6E 0x006E #LATIN SMALL LETTER N
+0x6F 0x006F #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7A 0x007A #LATIN SMALL LETTER Z
+0x7B 0x007B #LEFT CURLY BRACKET
+0x7C 0x007C #VERTICAL LINE
+0x7D 0x007D #RIGHT CURLY BRACKET
+0x7E 0x007E #TILDE
+0x7F 0x007F #DELETE
+0x80 0x0402 #CYRILLIC CAPITAL LETTER DJE
+0x81 0x0403 #CYRILLIC CAPITAL LETTER GJE
+0x82 0x201A #SINGLE LOW-9 QUOTATION MARK
+0x83 0x0453 #CYRILLIC SMALL LETTER GJE
+0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK
+0x85 0x2026 #HORIZONTAL ELLIPSIS
+0x86 0x2020 #DAGGER
+0x87 0x2021 #DOUBLE DAGGER
+0x88 0x20AC #EURO SIGN
+0x89 0x2030 #PER MILLE SIGN
+0x8A 0x0409 #CYRILLIC CAPITAL LETTER LJE
+0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C 0x040A #CYRILLIC CAPITAL LETTER NJE
+0x8D 0x040C #CYRILLIC CAPITAL LETTER KJE
+0x8E 0x040B #CYRILLIC CAPITAL LETTER TSHE
+0x8F 0x040F #CYRILLIC CAPITAL LETTER DZHE
+0x90 0x0452 #CYRILLIC SMALL LETTER DJE
+0x91 0x2018 #LEFT SINGLE QUOTATION MARK
+0x92 0x2019 #RIGHT SINGLE QUOTATION MARK
+0x93 0x201C #LEFT DOUBLE QUOTATION MARK
+0x94 0x201D #RIGHT DOUBLE QUOTATION MARK
+0x95 0x2022 #BULLET
+0x96 0x2013 #EN DASH
+0x97 0x2014 #EM DASH
+0x98 #UNDEFINED
+0x99 0x2122 #TRADE MARK SIGN
+0x9A 0x0459 #CYRILLIC SMALL LETTER LJE
+0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C 0x045A #CYRILLIC SMALL LETTER NJE
+0x9D 0x045C #CYRILLIC SMALL LETTER KJE
+0x9E 0x045B #CYRILLIC SMALL LETTER TSHE
+0x9F 0x045F #CYRILLIC SMALL LETTER DZHE
+0xA0 0x00A0 #NO-BREAK SPACE
+0xA1 0x040E #CYRILLIC CAPITAL LETTER SHORT U
+0xA2 0x045E #CYRILLIC SMALL LETTER SHORT U
+0xA3 0x0408 #CYRILLIC CAPITAL LETTER JE
+0xA4 0x00A4 #CURRENCY SIGN
+0xA5 0x0490 #CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0xA6 0x00A6 #BROKEN BAR
+0xA7 0x00A7 #SECTION SIGN
+0xA8 0x0401 #CYRILLIC CAPITAL LETTER IO
+0xA9 0x00A9 #COPYRIGHT SIGN
+0xAA 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC #NOT SIGN
+0xAD 0x00AD #SOFT HYPHEN
+0xAE 0x00AE #REGISTERED SIGN
+0xAF 0x0407 #CYRILLIC CAPITAL LETTER YI
+0xB0 0x00B0 #DEGREE SIGN
+0xB1 0x00B1 #PLUS-MINUS SIGN
+0xB2 0x0406 #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xB3 0x0456 #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xB4 0x0491 #CYRILLIC SMALL LETTER GHE WITH UPTURN
+0xB5 0x00B5 #MICRO SIGN
+0xB6 0x00B6 #PILCROW SIGN
+0xB7 0x00B7 #MIDDLE DOT
+0xB8 0x0451 #CYRILLIC SMALL LETTER IO
+0xB9 0x2116 #NUMERO SIGN
+0xBA 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE
+0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x0458 #CYRILLIC SMALL LETTER JE
+0xBD 0x0405 #CYRILLIC CAPITAL LETTER DZE
+0xBE 0x0455 #CYRILLIC SMALL LETTER DZE
+0xBF 0x0457 #CYRILLIC SMALL LETTER YI
+0xC0 0x0410 #CYRILLIC CAPITAL LETTER A
+0xC1 0x0411 #CYRILLIC CAPITAL LETTER BE
+0xC2 0x0412 #CYRILLIC CAPITAL LETTER VE
+0xC3 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0xC4 0x0414 #CYRILLIC CAPITAL LETTER DE
+0xC5 0x0415 #CYRILLIC CAPITAL LETTER IE
+0xC6 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0xC7 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0xC8 0x0418 #CYRILLIC CAPITAL LETTER I
+0xC9 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0xCA 0x041A #CYRILLIC CAPITAL LETTER KA
+0xCB 0x041B #CYRILLIC CAPITAL LETTER EL
+0xCC 0x041C #CYRILLIC CAPITAL LETTER EM
+0xCD 0x041D #CYRILLIC CAPITAL LETTER EN
+0xCE 0x041E #CYRILLIC CAPITAL LETTER O
+0xCF 0x041F #CYRILLIC CAPITAL LETTER PE
+0xD0 0x0420 #CYRILLIC CAPITAL LETTER ER
+0xD1 0x0421 #CYRILLIC CAPITAL LETTER ES
+0xD2 0x0422 #CYRILLIC CAPITAL LETTER TE
+0xD3 0x0423 #CYRILLIC CAPITAL LETTER U
+0xD4 0x0424 #CYRILLIC CAPITAL LETTER EF
+0xD5 0x0425 #CYRILLIC CAPITAL LETTER HA
+0xD6 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0xD7 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0xD8 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0xD9 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0xDA 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN
+0xDB 0x042B #CYRILLIC CAPITAL LETTER YERU
+0xDC 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN
+0xDD 0x042D #CYRILLIC CAPITAL LETTER E
+0xDE 0x042E #CYRILLIC CAPITAL LETTER YU
+0xDF 0x042F #CYRILLIC CAPITAL LETTER YA
+0xE0 0x0430 #CYRILLIC SMALL LETTER A
+0xE1 0x0431 #CYRILLIC SMALL LETTER BE
+0xE2 0x0432 #CYRILLIC SMALL LETTER VE
+0xE3 0x0433 #CYRILLIC SMALL LETTER GHE
+0xE4 0x0434 #CYRILLIC SMALL LETTER DE
+0xE5 0x0435 #CYRILLIC SMALL LETTER IE
+0xE6 0x0436 #CYRILLIC SMALL LETTER ZHE
+0xE7 0x0437 #CYRILLIC SMALL LETTER ZE
+0xE8 0x0438 #CYRILLIC SMALL LETTER I
+0xE9 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0xEA 0x043A #CYRILLIC SMALL LETTER KA
+0xEB 0x043B #CYRILLIC SMALL LETTER EL
+0xEC 0x043C #CYRILLIC SMALL LETTER EM
+0xED 0x043D #CYRILLIC SMALL LETTER EN
+0xEE 0x043E #CYRILLIC SMALL LETTER O
+0xEF 0x043F #CYRILLIC SMALL LETTER PE
+0xF0 0x0440 #CYRILLIC SMALL LETTER ER
+0xF1 0x0441 #CYRILLIC SMALL LETTER ES
+0xF2 0x0442 #CYRILLIC SMALL LETTER TE
+0xF3 0x0443 #CYRILLIC SMALL LETTER U
+0xF4 0x0444 #CYRILLIC SMALL LETTER EF
+0xF5 0x0445 #CYRILLIC SMALL LETTER HA
+0xF6 0x0446 #CYRILLIC SMALL LETTER TSE
+0xF7 0x0447 #CYRILLIC SMALL LETTER CHE
+0xF8 0x0448 #CYRILLIC SMALL LETTER SHA
+0xF9 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0xFA 0x044A #CYRILLIC SMALL LETTER HARD SIGN
+0xFB 0x044B #CYRILLIC SMALL LETTER YERU
+0xFC 0x044C #CYRILLIC SMALL LETTER SOFT SIGN
+0xFD 0x044D #CYRILLIC SMALL LETTER E
+0xFE 0x044E #CYRILLIC SMALL LETTER YU
+0xFF 0x044F #CYRILLIC SMALL LETTER YA
diff --git a/source/codepages/CP437.TXT b/source/codepages/CP437.TXT
new file mode 100755
index 00000000000..479076f4296
--- /dev/null
+++ b/source/codepages/CP437.TXT
@@ -0,0 +1,274 @@
+#
+# Name: cp437_DOSLatinUS to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp437_DOSLatinUS code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp437_DOSLatinUS order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE
+0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE
+0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA
+0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS
+0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE
+0x8b 0x00ef #LATIN SMALL LETTER I WITH DIAERESIS
+0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d 0x00ec #LATIN SMALL LETTER I WITH GRAVE
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x00e6 #LATIN SMALL LIGATURE AE
+0x92 0x00c6 #LATIN CAPITAL LIGATURE AE
+0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x00f2 #LATIN SMALL LETTER O WITH GRAVE
+0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97 0x00f9 #LATIN SMALL LETTER U WITH GRAVE
+0x98 0x00ff #LATIN SMALL LETTER Y WITH DIAERESIS
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x00a2 #CENT SIGN
+0x9c 0x00a3 #POUND SIGN
+0x9d 0x00a5 #YEN SIGN
+0x9e 0x20a7 #PESETA SIGN
+0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK
+0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE
+0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE
+0xa6 0x00aa #FEMININE ORDINAL INDICATOR
+0xa7 0x00ba #MASCULINE ORDINAL INDICATOR
+0xa8 0x00bf #INVERTED QUESTION MARK
+0xa9 0x2310 #REVERSED NOT SIGN
+0xaa 0x00ac #NOT SIGN
+0xab 0x00bd #VULGAR FRACTION ONE HALF
+0xac 0x00bc #VULGAR FRACTION ONE QUARTER
+0xad 0x00a1 #INVERTED EXCLAMATION MARK
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x03b1 #GREEK SMALL LETTER ALPHA
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x0393 #GREEK CAPITAL LETTER GAMMA
+0xe3 0x03c0 #GREEK SMALL LETTER PI
+0xe4 0x03a3 #GREEK CAPITAL LETTER SIGMA
+0xe5 0x03c3 #GREEK SMALL LETTER SIGMA
+0xe6 0x00b5 #MICRO SIGN
+0xe7 0x03c4 #GREEK SMALL LETTER TAU
+0xe8 0x03a6 #GREEK CAPITAL LETTER PHI
+0xe9 0x0398 #GREEK CAPITAL LETTER THETA
+0xea 0x03a9 #GREEK CAPITAL LETTER OMEGA
+0xeb 0x03b4 #GREEK SMALL LETTER DELTA
+0xec 0x221e #INFINITY
+0xed 0x03c6 #GREEK SMALL LETTER PHI
+0xee 0x03b5 #GREEK SMALL LETTER EPSILON
+0xef 0x2229 #INTERSECTION
+0xf0 0x2261 #IDENTICAL TO
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x2265 #GREATER-THAN OR EQUAL TO
+0xf3 0x2264 #LESS-THAN OR EQUAL TO
+0xf4 0x2320 #TOP HALF INTEGRAL
+0xf5 0x2321 #BOTTOM HALF INTEGRAL
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x2248 #ALMOST EQUAL TO
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x2219 #BULLET OPERATOR
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x221a #SQUARE ROOT
+0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+ \ No newline at end of file
diff --git a/source/codepages/CP737.TXT b/source/codepages/CP737.TXT
new file mode 100755
index 00000000000..68f3d379550
--- /dev/null
+++ b/source/codepages/CP737.TXT
@@ -0,0 +1,274 @@
+#
+# Name: cp737_DOSGreek to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp737_DOSGreek code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp737_DOSGreek order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x0391 #GREEK CAPITAL LETTER ALPHA
+0x81 0x0392 #GREEK CAPITAL LETTER BETA
+0x82 0x0393 #GREEK CAPITAL LETTER GAMMA
+0x83 0x0394 #GREEK CAPITAL LETTER DELTA
+0x84 0x0395 #GREEK CAPITAL LETTER EPSILON
+0x85 0x0396 #GREEK CAPITAL LETTER ZETA
+0x86 0x0397 #GREEK CAPITAL LETTER ETA
+0x87 0x0398 #GREEK CAPITAL LETTER THETA
+0x88 0x0399 #GREEK CAPITAL LETTER IOTA
+0x89 0x039a #GREEK CAPITAL LETTER KAPPA
+0x8a 0x039b #GREEK CAPITAL LETTER LAMDA
+0x8b 0x039c #GREEK CAPITAL LETTER MU
+0x8c 0x039d #GREEK CAPITAL LETTER NU
+0x8d 0x039e #GREEK CAPITAL LETTER XI
+0x8e 0x039f #GREEK CAPITAL LETTER OMICRON
+0x8f 0x03a0 #GREEK CAPITAL LETTER PI
+0x90 0x03a1 #GREEK CAPITAL LETTER RHO
+0x91 0x03a3 #GREEK CAPITAL LETTER SIGMA
+0x92 0x03a4 #GREEK CAPITAL LETTER TAU
+0x93 0x03a5 #GREEK CAPITAL LETTER UPSILON
+0x94 0x03a6 #GREEK CAPITAL LETTER PHI
+0x95 0x03a7 #GREEK CAPITAL LETTER CHI
+0x96 0x03a8 #GREEK CAPITAL LETTER PSI
+0x97 0x03a9 #GREEK CAPITAL LETTER OMEGA
+0x98 0x03b1 #GREEK SMALL LETTER ALPHA
+0x99 0x03b2 #GREEK SMALL LETTER BETA
+0x9a 0x03b3 #GREEK SMALL LETTER GAMMA
+0x9b 0x03b4 #GREEK SMALL LETTER DELTA
+0x9c 0x03b5 #GREEK SMALL LETTER EPSILON
+0x9d 0x03b6 #GREEK SMALL LETTER ZETA
+0x9e 0x03b7 #GREEK SMALL LETTER ETA
+0x9f 0x03b8 #GREEK SMALL LETTER THETA
+0xa0 0x03b9 #GREEK SMALL LETTER IOTA
+0xa1 0x03ba #GREEK SMALL LETTER KAPPA
+0xa2 0x03bb #GREEK SMALL LETTER LAMDA
+0xa3 0x03bc #GREEK SMALL LETTER MU
+0xa4 0x03bd #GREEK SMALL LETTER NU
+0xa5 0x03be #GREEK SMALL LETTER XI
+0xa6 0x03bf #GREEK SMALL LETTER OMICRON
+0xa7 0x03c0 #GREEK SMALL LETTER PI
+0xa8 0x03c1 #GREEK SMALL LETTER RHO
+0xa9 0x03c3 #GREEK SMALL LETTER SIGMA
+0xaa 0x03c2 #GREEK SMALL LETTER FINAL SIGMA
+0xab 0x03c4 #GREEK SMALL LETTER TAU
+0xac 0x03c5 #GREEK SMALL LETTER UPSILON
+0xad 0x03c6 #GREEK SMALL LETTER PHI
+0xae 0x03c7 #GREEK SMALL LETTER CHI
+0xaf 0x03c8 #GREEK SMALL LETTER PSI
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x03c9 #GREEK SMALL LETTER OMEGA
+0xe1 0x03ac #GREEK SMALL LETTER ALPHA WITH TONOS
+0xe2 0x03ad #GREEK SMALL LETTER EPSILON WITH TONOS
+0xe3 0x03ae #GREEK SMALL LETTER ETA WITH TONOS
+0xe4 0x03ca #GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xe5 0x03af #GREEK SMALL LETTER IOTA WITH TONOS
+0xe6 0x03cc #GREEK SMALL LETTER OMICRON WITH TONOS
+0xe7 0x03cd #GREEK SMALL LETTER UPSILON WITH TONOS
+0xe8 0x03cb #GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xe9 0x03ce #GREEK SMALL LETTER OMEGA WITH TONOS
+0xea 0x0386 #GREEK CAPITAL LETTER ALPHA WITH TONOS
+0xeb 0x0388 #GREEK CAPITAL LETTER EPSILON WITH TONOS
+0xec 0x0389 #GREEK CAPITAL LETTER ETA WITH TONOS
+0xed 0x038a #GREEK CAPITAL LETTER IOTA WITH TONOS
+0xee 0x038c #GREEK CAPITAL LETTER OMICRON WITH TONOS
+0xef 0x038e #GREEK CAPITAL LETTER UPSILON WITH TONOS
+0xf0 0x038f #GREEK CAPITAL LETTER OMEGA WITH TONOS
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x2265 #GREATER-THAN OR EQUAL TO
+0xf3 0x2264 #LESS-THAN OR EQUAL TO
+0xf4 0x03aa #GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0xf5 0x03ab #GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x2248 #ALMOST EQUAL TO
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x2219 #BULLET OPERATOR
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x221a #SQUARE ROOT
+0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+ \ No newline at end of file
diff --git a/source/codepages/CP775.TXT b/source/codepages/CP775.TXT
new file mode 100755
index 00000000000..bdf0aa97f22
--- /dev/null
+++ b/source/codepages/CP775.TXT
@@ -0,0 +1,273 @@
+#
+# Name: cp775_DOSBaltic to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 01/08/2001
+# Authors: Toomas Soome <tsoome@ut.ee>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp775_DOSBaltic code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp775_DOSBaltic order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x0101 #LATIN SMALL LETTER A WITH MACRON
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x0123 #LATIN SMALL LETTER G WITH CEDILLA
+0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE
+0x87 0x0107 #LATIN SMALL LETTER C WITH ACUTE
+0x88 0x0142 #LATIN SMALL LETTER L WITH STROKE
+0x89 0x0113 #LATIN SMALL LETTER E WITH MACRON
+0x8a 0x0156 #LATIN CAPITAL LETTER R WITH CEDILLA
+0x8b 0x0157 #LATIN SMALL LETTER R WITH CEDILLA
+0x8c 0x012b #LATIN SMALL LETTER I WITH MACRON
+0x8d 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x00e6 #LATIN SMALL LIGATURE AE
+0x92 0x00c6 #LATIN CAPITAL LIGATURE AE
+0x93 0x014d #LATIN SMALL LETTER O WITH MACRON
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x0122 #LATIN CAPITAL LETTER G WITH CEDILLA
+0x96 0x00a2 #CENT SIGN
+0x97 0x015a #LATIN CAPITAL LETTER S WITH ACUTE
+0x98 0x015b #LATIN SMALL LETTER S WITH ACUTE
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x00f8 #LATIN SMALL LETTER O WITH STROKE
+0x9c 0x00a3 #POUND SIGN
+0x9d 0x00d8 #LATIN CAPITAL LETTER O WITH STROKE
+0x9e 0x00d7 #MULTIPLICATION SIGN
+0x9f 0x00a4 #CURRENCY SIGN
+0xa0 0x0100 #LATIN CAPITAL LETTER A WITH MACRON
+0xa1 0x012a #LATIN CAPITAL LETTER I WITH MACRON
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x017b #LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xa4 0x017c #LATIN SMALL LETTER Z WITH DOT ABOVE
+0xa5 0x017a #LATIN SMALL LETTER Z WITH ACUTE
+0xa6 0x201d #RIGHT DOUBLE QUOTATION MARK
+0xa7 0x00a6 #BROKEN BAR
+0xa8 0x00a9 #COPYRIGHT SIGN
+0xa9 0x00ae #REGISTERED SIGN
+0xaa 0x00ac #NOT SIGN
+0xab 0x00bd #VULGAR FRACTION ONE HALF
+0xac 0x00bc #VULGAR FRACTION ONE QUARTER
+0xad 0x0141 #LATIN CAPITAL LETTER L WITH STROKE
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK
+0xb6 0x010c #LATIN CAPITAL LETTER C WITH CARON
+0xb7 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK
+0xb8 0x0116 #LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x012e #LATIN CAPITAL LETTER I WITH OGONEK
+0xbe 0x0160 #LATIN CAPITAL LETTER S WITH CARON
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x0172 #LATIN CAPITAL LETTER U WITH OGONEK
+0xc7 0x016a #LATIN CAPITAL LETTER U WITH MACRON
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x017d #LATIN CAPITAL LETTER Z WITH CARON
+0xd0 0x0105 #LATIN SMALL LETTER A WITH OGONEK
+0xd1 0x010d #LATIN SMALL LETTER C WITH CARON
+0xd2 0x0119 #LATIN SMALL LETTER E WITH OGONEK
+0xd3 0x0117 #LATIN SMALL LETTER E WITH DOT ABOVE
+0xd4 0x012f #LATIN SMALL LETTER I WITH OGONEK
+0xd5 0x0161 #LATIN SMALL LETTER S WITH CARON
+0xd6 0x0173 #LATIN SMALL LETTER U WITH OGONEK
+0xd7 0x016b #LATIN SMALL LETTER U WITH MACRON
+0xd8 0x017e #LATIN SMALL LETTER Z WITH CARON
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x014c #LATIN CAPITAL LETTER O WITH MACRON
+0xe3 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE
+0xe4 0x00f5 #LATIN SMALL LETTER O WITH TILDE
+0xe5 0x00d5 #LATIN CAPITAL LETTER O WITH TILDE
+0xe6 0x00b5 #MICRO SIGN
+0xe7 0x0144 #LATIN SMALL LETTER N WITH ACUTE
+0xe8 0x0136 #LATIN CAPITAL LETTER K WITH CEDILLA
+0xe9 0x0137 #LATIN SMALL LETTER K WITH CEDILLA
+0xea 0x013b #LATIN CAPITAL LETTER L WITH CEDILLA
+0xeb 0x013c #LATIN SMALL LETTER L WITH CEDILLA
+0xec 0x0146 #LATIN SMALL LETTER N WITH CEDILLA
+0xed 0x0112 #LATIN CAPITAL LETTER E WITH MACRON
+0xee 0x0145 #LATIN CAPITAL LETTER N WITH CEDILLA
+0xef 0x2019 #RIGHT SINGLE QUOTATION MARK
+0xf0 0x00ad #SOFT HYPHEN
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x201c #LEFT DOUBLE QUOTATION MARK
+0xf3 0x00be #VULGAR FRACTION THREE QUARTERS
+0xf4 0x00b6 #PILCROW SIGN
+0xf5 0x00a7 #SECTION SIGN
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x201e #DOUBLE LOW-9 QUOTATION MARK
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x2219 #BULLET OPERATOR
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x00b9 #SUPERSCRIPT ONE
+0xfc 0x00b3 #SUPERSCRIPT THREE
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+
diff --git a/source/codepages/CP850.TXT b/source/codepages/CP850.TXT
new file mode 100755
index 00000000000..312e4394421
--- /dev/null
+++ b/source/codepages/CP850.TXT
@@ -0,0 +1,274 @@
+#
+# Name: cp850_DOSLatin1 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp850_DOSLatin1 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp850_DOSLatin1 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE
+0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE
+0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA
+0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS
+0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE
+0x8b 0x00ef #LATIN SMALL LETTER I WITH DIAERESIS
+0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d 0x00ec #LATIN SMALL LETTER I WITH GRAVE
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x00e6 #LATIN SMALL LIGATURE AE
+0x92 0x00c6 #LATIN CAPITAL LIGATURE AE
+0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x00f2 #LATIN SMALL LETTER O WITH GRAVE
+0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97 0x00f9 #LATIN SMALL LETTER U WITH GRAVE
+0x98 0x00ff #LATIN SMALL LETTER Y WITH DIAERESIS
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x00f8 #LATIN SMALL LETTER O WITH STROKE
+0x9c 0x00a3 #POUND SIGN
+0x9d 0x00d8 #LATIN CAPITAL LETTER O WITH STROKE
+0x9e 0x00d7 #MULTIPLICATION SIGN
+0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK
+0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE
+0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE
+0xa6 0x00aa #FEMININE ORDINAL INDICATOR
+0xa7 0x00ba #MASCULINE ORDINAL INDICATOR
+0xa8 0x00bf #INVERTED QUESTION MARK
+0xa9 0x00ae #REGISTERED SIGN
+0xaa 0x00ac #NOT SIGN
+0xab 0x00bd #VULGAR FRACTION ONE HALF
+0xac 0x00bc #VULGAR FRACTION ONE QUARTER
+0xad 0x00a1 #INVERTED EXCLAMATION MARK
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE
+0xb6 0x00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7 0x00c0 #LATIN CAPITAL LETTER A WITH GRAVE
+0xb8 0x00a9 #COPYRIGHT SIGN
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x00a2 #CENT SIGN
+0xbe 0x00a5 #YEN SIGN
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x00e3 #LATIN SMALL LETTER A WITH TILDE
+0xc7 0x00c3 #LATIN CAPITAL LETTER A WITH TILDE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x00a4 #CURRENCY SIGN
+0xd0 0x00f0 #LATIN SMALL LETTER ETH
+0xd1 0x00d0 #LATIN CAPITAL LETTER ETH
+0xd2 0x00ca #LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xd3 0x00cb #LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4 0x00c8 #LATIN CAPITAL LETTER E WITH GRAVE
+0xd5 0x0131 #LATIN SMALL LETTER DOTLESS I
+0xd6 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE
+0xd7 0x00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8 0x00cf #LATIN CAPITAL LETTER I WITH DIAERESIS
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x00a6 #BROKEN BAR
+0xde 0x00cc #LATIN CAPITAL LETTER I WITH GRAVE
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3 0x00d2 #LATIN CAPITAL LETTER O WITH GRAVE
+0xe4 0x00f5 #LATIN SMALL LETTER O WITH TILDE
+0xe5 0x00d5 #LATIN CAPITAL LETTER O WITH TILDE
+0xe6 0x00b5 #MICRO SIGN
+0xe7 0x00fe #LATIN SMALL LETTER THORN
+0xe8 0x00de #LATIN CAPITAL LETTER THORN
+0xe9 0x00da #LATIN CAPITAL LETTER U WITH ACUTE
+0xea 0x00db #LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xeb 0x00d9 #LATIN CAPITAL LETTER U WITH GRAVE
+0xec 0x00fd #LATIN SMALL LETTER Y WITH ACUTE
+0xed 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE
+0xee 0x00af #MACRON
+0xef 0x00b4 #ACUTE ACCENT
+0xf0 0x00ad #SOFT HYPHEN
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x2017 #DOUBLE LOW LINE
+0xf3 0x00be #VULGAR FRACTION THREE QUARTERS
+0xf4 0x00b6 #PILCROW SIGN
+0xf5 0x00a7 #SECTION SIGN
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x00b8 #CEDILLA
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x00a8 #DIAERESIS
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x00b9 #SUPERSCRIPT ONE
+0xfc 0x00b3 #SUPERSCRIPT THREE
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+ \ No newline at end of file
diff --git a/source/codepages/CP852.TXT b/source/codepages/CP852.TXT
new file mode 100755
index 00000000000..bae9e7ad30f
--- /dev/null
+++ b/source/codepages/CP852.TXT
@@ -0,0 +1,274 @@
+#
+# Name: cp852_DOSLatin2 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp852_DOSLatin2 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp852_DOSLatin2 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x016f #LATIN SMALL LETTER U WITH RING ABOVE
+0x86 0x0107 #LATIN SMALL LETTER C WITH ACUTE
+0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA
+0x88 0x0142 #LATIN SMALL LETTER L WITH STROKE
+0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS
+0x8a 0x0150 #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0x8b 0x0151 #LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x0139 #LATIN CAPITAL LETTER L WITH ACUTE
+0x92 0x013a #LATIN SMALL LETTER L WITH ACUTE
+0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x013d #LATIN CAPITAL LETTER L WITH CARON
+0x96 0x013e #LATIN SMALL LETTER L WITH CARON
+0x97 0x015a #LATIN CAPITAL LETTER S WITH ACUTE
+0x98 0x015b #LATIN SMALL LETTER S WITH ACUTE
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x0164 #LATIN CAPITAL LETTER T WITH CARON
+0x9c 0x0165 #LATIN SMALL LETTER T WITH CARON
+0x9d 0x0141 #LATIN CAPITAL LETTER L WITH STROKE
+0x9e 0x00d7 #MULTIPLICATION SIGN
+0x9f 0x010d #LATIN SMALL LETTER C WITH CARON
+0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK
+0xa5 0x0105 #LATIN SMALL LETTER A WITH OGONEK
+0xa6 0x017d #LATIN CAPITAL LETTER Z WITH CARON
+0xa7 0x017e #LATIN SMALL LETTER Z WITH CARON
+0xa8 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK
+0xa9 0x0119 #LATIN SMALL LETTER E WITH OGONEK
+0xaa 0x00ac #NOT SIGN
+0xab 0x017a #LATIN SMALL LETTER Z WITH ACUTE
+0xac 0x010c #LATIN CAPITAL LETTER C WITH CARON
+0xad 0x015f #LATIN SMALL LETTER S WITH CEDILLA
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE
+0xb6 0x00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7 0x011a #LATIN CAPITAL LETTER E WITH CARON
+0xb8 0x015e #LATIN CAPITAL LETTER S WITH CEDILLA
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x017b #LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xbe 0x017c #LATIN SMALL LETTER Z WITH DOT ABOVE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x0102 #LATIN CAPITAL LETTER A WITH BREVE
+0xc7 0x0103 #LATIN SMALL LETTER A WITH BREVE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x00a4 #CURRENCY SIGN
+0xd0 0x0111 #LATIN SMALL LETTER D WITH STROKE
+0xd1 0x0110 #LATIN CAPITAL LETTER D WITH STROKE
+0xd2 0x010e #LATIN CAPITAL LETTER D WITH CARON
+0xd3 0x00cb #LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4 0x010f #LATIN SMALL LETTER D WITH CARON
+0xd5 0x0147 #LATIN CAPITAL LETTER N WITH CARON
+0xd6 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE
+0xd7 0x00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8 0x011b #LATIN SMALL LETTER E WITH CARON
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x0162 #LATIN CAPITAL LETTER T WITH CEDILLA
+0xde 0x016e #LATIN CAPITAL LETTER U WITH RING ABOVE
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE
+0xe4 0x0144 #LATIN SMALL LETTER N WITH ACUTE
+0xe5 0x0148 #LATIN SMALL LETTER N WITH CARON
+0xe6 0x0160 #LATIN CAPITAL LETTER S WITH CARON
+0xe7 0x0161 #LATIN SMALL LETTER S WITH CARON
+0xe8 0x0154 #LATIN CAPITAL LETTER R WITH ACUTE
+0xe9 0x00da #LATIN CAPITAL LETTER U WITH ACUTE
+0xea 0x0155 #LATIN SMALL LETTER R WITH ACUTE
+0xeb 0x0170 #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xec 0x00fd #LATIN SMALL LETTER Y WITH ACUTE
+0xed 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE
+0xee 0x0163 #LATIN SMALL LETTER T WITH CEDILLA
+0xef 0x00b4 #ACUTE ACCENT
+0xf0 0x00ad #SOFT HYPHEN
+0xf1 0x02dd #DOUBLE ACUTE ACCENT
+0xf2 0x02db #OGONEK
+0xf3 0x02c7 #CARON
+0xf4 0x02d8 #BREVE
+0xf5 0x00a7 #SECTION SIGN
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x00b8 #CEDILLA
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x00a8 #DIAERESIS
+0xfa 0x02d9 #DOT ABOVE
+0xfb 0x0171 #LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xfc 0x0158 #LATIN CAPITAL LETTER R WITH CARON
+0xfd 0x0159 #LATIN SMALL LETTER R WITH CARON
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+ \ No newline at end of file
diff --git a/source/codepages/CP857.TXT b/source/codepages/CP857.TXT
new file mode 100755
index 00000000000..57206c4efcc
--- /dev/null
+++ b/source/codepages/CP857.TXT
@@ -0,0 +1,273 @@
+#
+# Name: cp857_DOSLatin5 to Unicode table
+# Unicode version: 2.0
+# Table version: 0.01
+# Table format: Format A
+# Date: 01/05/2001
+# Authors: Deniz Akkus <akkus@alum.mit.edu>
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp857_DOSLatin5 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp857_DOSLatin5 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE
+0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE
+0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA
+0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS
+0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE
+0x8b 0x00ef #LATIN SMALL LETTER I WITH DIAERESIS
+0x8c 0x00ee #LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d 0x0131 #LATIN SMALL LETTER DOTLESS I
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x00e6 #LATIN SMALL LIGATURE AE
+0x92 0x00c6 #LATIN CAPITAL LIGATURE AE
+0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x00f2 #LATIN SMALL LETTER O WITH GRAVE
+0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97 0x00f9 #LATIN SMALL LETTER U WITH GRAVE
+0x98 0x0130 #LATIN CAPITAL LETTER I WITH DOT ABOVE
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x00f8 #LATIN SMALL LETTER O WITH STROKE
+0x9c 0x00a3 #POUND SIGN
+0x9d 0x00d8 #LATIN CAPITAL LETTER O WITH STROKE
+0x9e 0x015e #LATIN CAPITAL LETTER S WITH CEDILLA
+0x9f 0x015f #LATIN SMALL LETTER S WITH CEDILLA
+0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x00f1 #LATIN SMALL LETTER N WITH TILDE
+0xa5 0x00d1 #LATIN CAPITAL LETTER N WITH TILDE
+0xa6 0x011e #LATIN CAPITAL LETTER G WITH BREVE
+0xa7 0x011f #LATIN SMALL LETTER G WITH BREVE
+0xa8 0x00bf #INVERTED QUESTION MARK
+0xa9 0x00ae #REGISTERED SIGN
+0xaa 0x00ac #NOT SIGN
+0xab 0x00bd #VULGAR FRACTION ONE HALF
+0xac 0x00bc #VULGAR FRACTION ONE QUARTER
+0xad 0x00a1 #INVERTED EXCLAMATION MARK
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE
+0xb6 0x00c2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7 0x00c0 #LATIN CAPITAL LETTER A WITH GRAVE
+0xb8 0x00a9 #COPYRIGHT SIGN
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x00a2 #CENT SIGN
+0xbe 0x00a5 #YEN SIGN
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x00e3 #LATIN SMALL LETTER A WITH TILDE
+0xc7 0x00c3 #LATIN CAPITAL LETTER A WITH TILDE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x00a4 #CURRENCY SIGN
+0xd0 0x00ba #MASCULINE ORDINAL INDICATOR
+0xd1 0x00aa #FEMININE ORDINAL INDICATOR
+0xd2 0x00ca #LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xd3 0x00cb #LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4 0x00c8 #LATIN CAPITAL LETTER E WITH GRAVE
+0xd5 0x0131 #LATIN SMALL LETTER DOTLESS I
+0xd6 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE
+0xd7 0x00ce #LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8 0x00cf #LATIN CAPITAL LETTER I WITH DIAERESIS
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x00a6 #BROKEN BAR
+0xde 0x00cc #LATIN CAPITAL LETTER I WITH GRAVE
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3 0x00d2 #LATIN CAPITAL LETTER O WITH GRAVE
+0xe4 0x00f5 #LATIN SMALL LETTER O WITH TILDE
+0xe5 0x00d5 #LATIN CAPITAL LETTER O WITH TILDE
+0xe6 0x00b5 #MICRO SIGN
+0xe7 0x00fe #LATIN SMALL LETTER THORN
+0xe8 0x00d7 #MULTIPLICATION SIGN
+0xe9 0x00da #LATIN CAPITAL LETTER U WITH ACUTE
+0xea 0x00db #LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xeb 0x00d9 #LATIN CAPITAL LETTER U WITH GRAVE
+0xec 0x00ec #LATIN SMALL LETTER I WITH GRAVE
+0xed 0x00ff #LATIN SMALL LETTER Y WITH DIARESIS
+0xee 0x00af #MACRON
+0xef 0x00b4 #ACUTE ACCENT
+0xf0 0x00ad #SOFT HYPHEN
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x2017 #DOUBLE LOW LINE
+0xf3 0x00be #VULGAR FRACTION THREE QUARTERS
+0xf4 0x00b6 #PILCROW SIGN
+0xf5 0x00a7 #SECTION SIGN
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x00b8 #CEDILLA
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x00a8 #DIAERESIS
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x00b9 #SUPERSCRIPT ONE
+0xfc 0x00b3 #SUPERSCRIPT THREE
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
diff --git a/source/codepages/CP861.TXT b/source/codepages/CP861.TXT
new file mode 100755
index 00000000000..5a50e4e4976
--- /dev/null
+++ b/source/codepages/CP861.TXT
@@ -0,0 +1,275 @@
+#
+# Name: cp861_DOSIcelandic to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp861_DOSIcelandic code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp861_DOSIcelandic order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x00c7 #LATIN CAPITAL LETTER C WITH CEDILLA
+0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS
+0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE
+0x83 0x00e2 #LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS
+0x85 0x00e0 #LATIN SMALL LETTER A WITH GRAVE
+0x86 0x00e5 #LATIN SMALL LETTER A WITH RING ABOVE
+0x87 0x00e7 #LATIN SMALL LETTER C WITH CEDILLA
+0x88 0x00ea #LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89 0x00eb #LATIN SMALL LETTER E WITH DIAERESIS
+0x8a 0x00e8 #LATIN SMALL LETTER E WITH GRAVE
+0x8b 0x00d0 #LATIN CAPITAL LETTER ETH
+0x8c 0x00f0 #LATIN SMALL LETTER ETH
+0x8d 0x00de #LATIN CAPITAL LETTER THORN
+0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f 0x00c5 #LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE
+0x91 0x00e6 #LATIN SMALL LIGATURE AE
+0x92 0x00c6 #LATIN CAPITAL LIGATURE AE
+0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS
+0x95 0x00fe #LATIN SMALL LETTER THORN
+0x96 0x00fb #LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE
+0x98 0x00fd #LATIN SMALL LETTER Y WITH ACUTE
+0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b 0x00f8 #LATIN SMALL LETTER O WITH STROKE
+0x9c 0x00a3 #POUND SIGN
+0x9d 0x00d8 #LATIN CAPITAL LETTER O WITH STROKE
+0x9e 0x20a7 #PESETA SIGN
+0x9f 0x0192 #LATIN SMALL LETTER F WITH HOOK
+0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE
+0xa5 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE
+0xa6 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE
+0xa7 0x00da #LATIN CAPITAL LETTER U WITH ACUTE
+0xa8 0x00bf #INVERTED QUESTION MARK
+0xa9 0x2310 #REVERSED NOT SIGN
+0xaa 0x00ac #NOT SIGN
+0xab 0x00bd #VULGAR FRACTION ONE HALF
+0xac 0x00bc #VULGAR FRACTION ONE QUARTER
+0xad 0x00a1 #INVERTED EXCLAMATION MARK
+0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x03b1 #GREEK SMALL LETTER ALPHA
+0xe1 0x00df #LATIN SMALL LETTER SHARP S
+0xe2 0x0393 #GREEK CAPITAL LETTER GAMMA
+0xe3 0x03c0 #GREEK SMALL LETTER PI
+0xe4 0x03a3 #GREEK CAPITAL LETTER SIGMA
+0xe5 0x03c3 #GREEK SMALL LETTER SIGMA
+0xe6 0x00b5 #MICRO SIGN
+0xe7 0x03c4 #GREEK SMALL LETTER TAU
+0xe8 0x03a6 #GREEK CAPITAL LETTER PHI
+0xe9 0x0398 #GREEK CAPITAL LETTER THETA
+0xea 0x03a9 #GREEK CAPITAL LETTER OMEGA
+0xeb 0x03b4 #GREEK SMALL LETTER DELTA
+0xec 0x221e #INFINITY
+0xed 0x03c6 #GREEK SMALL LETTER PHI
+0xee 0x03b5 #GREEK SMALL LETTER EPSILON
+0xef 0x2229 #INTERSECTION
+0xf0 0x2261 #IDENTICAL TO
+0xf1 0x00b1 #PLUS-MINUS SIGN
+0xf2 0x2265 #GREATER-THAN OR EQUAL TO
+0xf3 0x2264 #LESS-THAN OR EQUAL TO
+0xf4 0x2320 #TOP HALF INTEGRAL
+0xf5 0x2321 #BOTTOM HALF INTEGRAL
+0xf6 0x00f7 #DIVISION SIGN
+0xf7 0x2248 #ALMOST EQUAL TO
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x2219 #BULLET OPERATOR
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x221a #SQUARE ROOT
+0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N
+0xfd 0x00b2 #SUPERSCRIPT TWO
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+
+ \ No newline at end of file
diff --git a/source/codepages/CP862.TXT b/source/codepages/CP862.TXT
new file mode 100755
index 00000000000..6700a942c19
--- /dev/null
+++ b/source/codepages/CP862.TXT
@@ -0,0 +1,270 @@
+#
+# Name: cp862_Hewbrew to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 02/14/02
+# Authors: Alexander Bokovoy <ab@alt-linux.org>
+# General notes: generated from /usr/share/i18n/charmaps/IBM862
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp862_Hewbrew code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+0x00 0x0000 # NULL (NUL)
+0x01 0x0001 # START OF HEADING (SOH)
+0x02 0x0002 # START OF TEXT (STX)
+0x03 0x0003 # END OF TEXT (ETX)
+0x04 0x0004 # END OF TRANSMISSION (EOT)
+0x05 0x0005 # ENQUIRY (ENQ)
+0x06 0x0006 # ACKNOWLEDGE (ACK)
+0x07 0x0007 # BELL (BEL)
+0x08 0x0008 # BACKSPACE (BS)
+0x09 0x0009 # CHARACTER TABULATION (HT)
+0x0a 0x000A # LINE FEED (LF)
+0x0b 0x000B # LINE TABULATION (VT)
+0x0c 0x000C # FORM FEED (FF)
+0x0d 0x000D # CARRIAGE RETURN (CR)
+0x0e 0x000E # SHIFT OUT (SO)
+0x0f 0x000F # SHIFT IN (SI)
+0x10 0x0010 # DATALINK ESCAPE (DLE)
+0x11 0x0011 # DEVICE CONTROL ONE (DC1)
+0x12 0x0012 # DEVICE CONTROL TWO (DC2)
+0x13 0x0013 # DEVICE CONTROL THREE (DC3)
+0x14 0x0014 # DEVICE CONTROL FOUR (DC4)
+0x15 0x0015 # NEGATIVE ACKNOWLEDGE (NAK)
+0x16 0x0016 # SYNCHRONOUS IDLE (SYN)
+0x17 0x0017 # END OF TRANSMISSION BLOCK (ETB)
+0x18 0x0018 # CANCEL (CAN)
+0x19 0x0019 # END OF MEDIUM (EM)
+0x1a 0x001A # SUBSTITUTE (SUB)
+0x1b 0x001B # ESCAPE (ESC)
+0x1c 0x001C # FILE SEPARATOR (IS4)
+0x1d 0x001D # GROUP SEPARATOR (IS3)
+0x1e 0x001E # RECORD SEPARATOR (IS2)
+0x1f 0x001F # UNIT SEPARATOR (IS1)
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2a 0x002A # ASTERISK
+0x2b 0x002B # PLUS SIGN
+0x2c 0x002C # COMMA
+0x2d 0x002D # HYPHEN-MINUS
+0x2e 0x002E # FULL STOP
+0x2f 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3a 0x003A # COLON
+0x3b 0x003B # SEMICOLON
+0x3c 0x003C # LESS-THAN SIGN
+0x3d 0x003D # EQUALS SIGN
+0x3e 0x003E # GREATER-THAN SIGN
+0x3f 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4a 0x004A # LATIN CAPITAL LETTER J
+0x4b 0x004B # LATIN CAPITAL LETTER K
+0x4c 0x004C # LATIN CAPITAL LETTER L
+0x4d 0x004D # LATIN CAPITAL LETTER M
+0x4e 0x004E # LATIN CAPITAL LETTER N
+0x4f 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5a 0x005A # LATIN CAPITAL LETTER Z
+0x5b 0x005B # LEFT SQUARE BRACKET
+0x5c 0x005C # REVERSE SOLIDUS
+0x5d 0x005D # RIGHT SQUARE BRACKET
+0x5e 0x005E # CIRCUMFLEX ACCENT
+0x5f 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6a 0x006A # LATIN SMALL LETTER J
+0x6b 0x006B # LATIN SMALL LETTER K
+0x6c 0x006C # LATIN SMALL LETTER L
+0x6d 0x006D # LATIN SMALL LETTER M
+0x6e 0x006E # LATIN SMALL LETTER N
+0x6f 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7a 0x007A # LATIN SMALL LETTER Z
+0x7b 0x007B # LEFT CURLY BRACKET
+0x7c 0x007C # VERTICAL LINE
+0x7d 0x007D # RIGHT CURLY BRACKET
+0x7e 0x007E # TILDE
+0x7f 0x007F # DELETE (DEL)
+0x80 0x05D0 # HEBREW LETTER ALEF
+0x81 0x05D1 # HEBREW LETTER BET
+0x82 0x05D2 # HEBREW LETTER GIMEL
+0x83 0x05D3 # HEBREW LETTER DALET
+0x84 0x05D4 # HEBREW LETTER HE
+0x85 0x05D5 # HEBREW LETTER VAV
+0x86 0x05D6 # HEBREW LETTER ZAYIN
+0x87 0x05D7 # HEBREW LETTER HET
+0x88 0x05D8 # HEBREW LETTER TET
+0x89 0x05D9 # HEBREW LETTER YOD
+0x8a 0x05DA # HEBREW LETTER FINAL KAF
+0x8b 0x05DB # HEBREW LETTER KAF
+0x8c 0x05DC # HEBREW LETTER LAMED
+0x8d 0x05DD # HEBREW LETTER FINAL MEM
+0x8e 0x05DE # HEBREW LETTER MEM
+0x8f 0x05DF # HEBREW LETTER FINAL NUN
+0x90 0x05E0 # HEBREW LETTER NUN
+0x91 0x05E1 # HEBREW LETTER SAMEKH
+0x92 0x05E2 # HEBREW LETTER AYIN
+0x93 0x05E3 # HEBREW LETTER FINAL PE
+0x94 0x05E4 # HEBREW LETTER PE
+0x95 0x05E5 # HEBREW LETTER FINAL TSADI
+0x96 0x05E6 # HEBREW LETTER TSADI
+0x97 0x05E7 # HEBREW LETTER QOF
+0x98 0x05E8 # HEBREW LETTER RESH
+0x99 0x05E9 # HEBREW LETTER SHIN
+0x9a 0x05EA # HEBREW LETTER TAV
+0x9b 0x00A2 # CENT SIGN
+0x9c 0x00A3 # POUND SIGN
+0x9d 0x00A5 # YEN SIGN
+0x9e 0x20A7 # PESETA SIGN
+0x9f 0x0192 # LATIN SMALL LETTER F WITH HOOK
+0xa0 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
+0xa1 0x00ED # LATIN SMALL LETTER I WITH ACUTE
+0xa2 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xa3 0x00FA # LATIN SMALL LETTER U WITH ACUTE
+0xa4 0x00F1 # LATIN SMALL LETTER N WITH TILDE
+0xa5 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE
+0xa6 0x00AA # FEMININE ORDINAL INDICATOR
+0xa7 0x00BA # MASCULINE ORDINAL INDICATOR
+0xa8 0x00BF # INVERTED QUESTION MARK
+0xa9 0x2310 # REVERSED NOT SIGN
+0xaa 0x00AC # NOT SIGN
+0xab 0x00BD # VULGAR FRACTION ONE HALF
+0xac 0x00BC # VULGAR FRACTION ONE QUARTER
+0xad 0x00A1 # INVERTED EXCLAMATION MARK
+0xae 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0 0x2591 # LIGHT SHADE
+0xb1 0x2592 # MEDIUM SHADE
+0xb2 0x2593 # DARK SHADE
+0xb3 0x2502 # BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 # BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255C # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256B # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 # FULL BLOCK
+0xdc 0x2584 # LOWER HALF BLOCK
+0xdd 0x258C # LEFT HALF BLOCK
+0xde 0x2590 # RIGHT HALF BLOCK
+0xdf 0x2580 # UPPER HALF BLOCK
+0xe0 0x03B1 # GREEK SMALL LETTER ALPHA
+0xe1 0x00DF # LATIN SMALL LETTER SHARP S (German)
+0xe2 0x0393 # GREEK CAPITAL LETTER GAMMA
+0xe3 0x03C0 # GREEK SMALL LETTER PI
+0xe4 0x03A3 # GREEK CAPITAL LETTER SIGMA
+0xe5 0x03C3 # GREEK SMALL LETTER SIGMA
+0xe6 0x00B5 # MICRO SIGN
+0xe7 0x03C4 # GREEK SMALL LETTER TAU
+0xe8 0x03A6 # GREEK CAPITAL LETTER PHI
+0xe9 0x0398 # GREEK CAPITAL LETTER THETA
+0xea 0x03A9 # GREEK CAPITAL LETTER OMEGA
+0xeb 0x03B4 # GREEK SMALL LETTER DELTA
+0xec 0x221E # INFINITY
+0xed 0x03C6 # GREEK SMALL LETTER PHI
+0xee 0x03B5 # GREEK SMALL LETTER EPSILON
+0xef 0x2229 # INTERSECTION
+0xf0 0x2261 # IDENTICAL TO
+0xf1 0x00B1 # PLUS-MINUS SIGN
+0xf2 0x2265 # GREATER-THAN OR EQUAL TO
+0xf3 0x2264 # LESS-THAN OR EQUAL TO
+0xf4 0x2320 # TOP HALF INTEGRAL
+0xf5 0x2321 # BOTTOM HALF INTEGRAL
+0xf6 0x00F7 # DIVISION SIGN
+0xf7 0x2248 # ALMOST EQUAL TO
+0xf8 0x00B0 # DEGREE SIGN
+0xf9 0x2219 # BULLET OPERATOR
+0xfa 0x00B7 # MIDDLE DOT
+0xfb 0x221A # SQUARE ROOT
+0xfc 0x207F # SUPERSCRIPT LATIN SMALL LETTER N
+0xfd 0x00B2 # SUPERSCRIPT TWO
+0xfe 0x25A0 # BLACK SQUARE
+0xff 0x00A0 # NO-BREAK SPACE
diff --git a/source/codepages/CP866.TXT b/source/codepages/CP866.TXT
new file mode 100755
index 00000000000..25b831a7fc3
--- /dev/null
+++ b/source/codepages/CP866.TXT
@@ -0,0 +1,275 @@
+#
+# Name: cp866_DOSCyrillicRussian to Unicode table
+# Unicode version: 2.0
+# Table version: 2.00
+# Table format: Format A
+# Date: 04/24/96
+# Authors: Lori Brownell <loribr@microsoft.com>
+# K.D. Chang <a-kchang@microsoft.com>
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp866_DOSCyrillicRussian code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp866_DOSCyrillicRussian order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0a 0x000a #LINE FEED
+0x0b 0x000b #VERTICAL TABULATION
+0x0c 0x000c #FORM FEED
+0x0d 0x000d #CARRIAGE RETURN
+0x0e 0x000e #SHIFT OUT
+0x0f 0x000f #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1a 0x001a #SUBSTITUTE
+0x1b 0x001b #ESCAPE
+0x1c 0x001c #FILE SEPARATOR
+0x1d 0x001d #GROUP SEPARATOR
+0x1e 0x001e #RECORD SEPARATOR
+0x1f 0x001f #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2a 0x002a #ASTERISK
+0x2b 0x002b #PLUS SIGN
+0x2c 0x002c #COMMA
+0x2d 0x002d #HYPHEN-MINUS
+0x2e 0x002e #FULL STOP
+0x2f 0x002f #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3a 0x003a #COLON
+0x3b 0x003b #SEMICOLON
+0x3c 0x003c #LESS-THAN SIGN
+0x3d 0x003d #EQUALS SIGN
+0x3e 0x003e #GREATER-THAN SIGN
+0x3f 0x003f #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4a 0x004a #LATIN CAPITAL LETTER J
+0x4b 0x004b #LATIN CAPITAL LETTER K
+0x4c 0x004c #LATIN CAPITAL LETTER L
+0x4d 0x004d #LATIN CAPITAL LETTER M
+0x4e 0x004e #LATIN CAPITAL LETTER N
+0x4f 0x004f #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5a 0x005a #LATIN CAPITAL LETTER Z
+0x5b 0x005b #LEFT SQUARE BRACKET
+0x5c 0x005c #REVERSE SOLIDUS
+0x5d 0x005d #RIGHT SQUARE BRACKET
+0x5e 0x005e #CIRCUMFLEX ACCENT
+0x5f 0x005f #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6a 0x006a #LATIN SMALL LETTER J
+0x6b 0x006b #LATIN SMALL LETTER K
+0x6c 0x006c #LATIN SMALL LETTER L
+0x6d 0x006d #LATIN SMALL LETTER M
+0x6e 0x006e #LATIN SMALL LETTER N
+0x6f 0x006f #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7a 0x007a #LATIN SMALL LETTER Z
+0x7b 0x007b #LEFT CURLY BRACKET
+0x7c 0x007c #VERTICAL LINE
+0x7d 0x007d #RIGHT CURLY BRACKET
+0x7e 0x007e #TILDE
+0x7f 0x007f #DELETE
+0x80 0x0410 #CYRILLIC CAPITAL LETTER A
+0x81 0x0411 #CYRILLIC CAPITAL LETTER BE
+0x82 0x0412 #CYRILLIC CAPITAL LETTER VE
+0x83 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0x84 0x0414 #CYRILLIC CAPITAL LETTER DE
+0x85 0x0415 #CYRILLIC CAPITAL LETTER IE
+0x86 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0x87 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0x88 0x0418 #CYRILLIC CAPITAL LETTER I
+0x89 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0x8a 0x041a #CYRILLIC CAPITAL LETTER KA
+0x8b 0x041b #CYRILLIC CAPITAL LETTER EL
+0x8c 0x041c #CYRILLIC CAPITAL LETTER EM
+0x8d 0x041d #CYRILLIC CAPITAL LETTER EN
+0x8e 0x041e #CYRILLIC CAPITAL LETTER O
+0x8f 0x041f #CYRILLIC CAPITAL LETTER PE
+0x90 0x0420 #CYRILLIC CAPITAL LETTER ER
+0x91 0x0421 #CYRILLIC CAPITAL LETTER ES
+0x92 0x0422 #CYRILLIC CAPITAL LETTER TE
+0x93 0x0423 #CYRILLIC CAPITAL LETTER U
+0x94 0x0424 #CYRILLIC CAPITAL LETTER EF
+0x95 0x0425 #CYRILLIC CAPITAL LETTER HA
+0x96 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0x97 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0x98 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0x99 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0x9a 0x042a #CYRILLIC CAPITAL LETTER HARD SIGN
+0x9b 0x042b #CYRILLIC CAPITAL LETTER YERU
+0x9c 0x042c #CYRILLIC CAPITAL LETTER SOFT SIGN
+0x9d 0x042d #CYRILLIC CAPITAL LETTER E
+0x9e 0x042e #CYRILLIC CAPITAL LETTER YU
+0x9f 0x042f #CYRILLIC CAPITAL LETTER YA
+0xa0 0x0430 #CYRILLIC SMALL LETTER A
+0xa1 0x0431 #CYRILLIC SMALL LETTER BE
+0xa2 0x0432 #CYRILLIC SMALL LETTER VE
+0xa3 0x0433 #CYRILLIC SMALL LETTER GHE
+0xa4 0x0434 #CYRILLIC SMALL LETTER DE
+0xa5 0x0435 #CYRILLIC SMALL LETTER IE
+0xa6 0x0436 #CYRILLIC SMALL LETTER ZHE
+0xa7 0x0437 #CYRILLIC SMALL LETTER ZE
+0xa8 0x0438 #CYRILLIC SMALL LETTER I
+0xa9 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0xaa 0x043a #CYRILLIC SMALL LETTER KA
+0xab 0x043b #CYRILLIC SMALL LETTER EL
+0xac 0x043c #CYRILLIC SMALL LETTER EM
+0xad 0x043d #CYRILLIC SMALL LETTER EN
+0xae 0x043e #CYRILLIC SMALL LETTER O
+0xaf 0x043f #CYRILLIC SMALL LETTER PE
+0xb0 0x2591 #LIGHT SHADE
+0xb1 0x2592 #MEDIUM SHADE
+0xb2 0x2593 #DARK SHADE
+0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb 0x2588 #FULL BLOCK
+0xdc 0x2584 #LOWER HALF BLOCK
+0xdd 0x258c #LEFT HALF BLOCK
+0xde 0x2590 #RIGHT HALF BLOCK
+0xdf 0x2580 #UPPER HALF BLOCK
+0xe0 0x0440 #CYRILLIC SMALL LETTER ER
+0xe1 0x0441 #CYRILLIC SMALL LETTER ES
+0xe2 0x0442 #CYRILLIC SMALL LETTER TE
+0xe3 0x0443 #CYRILLIC SMALL LETTER U
+0xe4 0x0444 #CYRILLIC SMALL LETTER EF
+0xe5 0x0445 #CYRILLIC SMALL LETTER HA
+0xe6 0x0446 #CYRILLIC SMALL LETTER TSE
+0xe7 0x0447 #CYRILLIC SMALL LETTER CHE
+0xe8 0x0448 #CYRILLIC SMALL LETTER SHA
+0xe9 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0xea 0x044a #CYRILLIC SMALL LETTER HARD SIGN
+0xeb 0x044b #CYRILLIC SMALL LETTER YERU
+0xec 0x044c #CYRILLIC SMALL LETTER SOFT SIGN
+0xed 0x044d #CYRILLIC SMALL LETTER E
+0xee 0x044e #CYRILLIC SMALL LETTER YU
+0xef 0x044f #CYRILLIC SMALL LETTER YA
+0xf0 0x0401 #CYRILLIC CAPITAL LETTER IO
+0xf1 0x0451 #CYRILLIC SMALL LETTER IO
+0xf2 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xf3 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE
+0xf4 0x0407 #CYRILLIC CAPITAL LETTER YI
+0xf5 0x0457 #CYRILLIC SMALL LETTER YI
+0xf6 0x040e #CYRILLIC CAPITAL LETTER SHORT U
+0xf7 0x045e #CYRILLIC SMALL LETTER SHORT U
+0xf8 0x00b0 #DEGREE SIGN
+0xf9 0x2219 #BULLET OPERATOR
+0xfa 0x00b7 #MIDDLE DOT
+0xfb 0x221a #SQUARE ROOT
+0xfc 0x2116 #NUMERO SIGN
+0xfd 0x00a4 #CURRENCY SIGN
+0xfe 0x25a0 #BLACK SQUARE
+0xff 0x00a0 #NO-BREAK SPACE
+
+ \ No newline at end of file
diff --git a/source/codepages/CP932.TXT b/source/codepages/CP932.TXT
new file mode 100755
index 00000000000..aeea43fc689
--- /dev/null
+++ b/source/codepages/CP932.TXT
@@ -0,0 +1,9881 @@
+#
+# Name: cp932 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.01
+# Table format: Format A
+# Date: 04/15/98
+#
+# Contact: cpxlate@microsoft.com
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp932 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp932 order
+#
+# these chars are listed first to correct Unicode to CP mapping
+# by Hiroshi MIURA, <miura@blue.gr.jp> 03/14/00
+#
+0x8790 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x8791 0x2261 #IDENTICAL TO
+0x8792 0x222B #INTEGRAL
+0x8795 0x221A #SQUARE ROOT
+0x8796 0x22A5 #UP TACK
+0x8797 0x2220 #ANGLE
+0x879A 0x2235 #BECAUSE
+0x879B 0x2229 #INTERSECTION
+0x879C 0x222A #UNION
+0xEEF9 0xFFE2 #FULLWIDTH NOT SIGN
+0xFA54 0xFFE2 #FULLWIDTH NOT SIGN
+0xFA5B 0x2235 #BECAUSE
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0A 0x000A #LINE FEED
+0x0B 0x000B #VERTICAL TABULATION
+0x0C 0x000C #FORM FEED
+0x0D 0x000D #CARRIAGE RETURN
+0x0E 0x000E #SHIFT OUT
+0x0F 0x000F #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1A 0x001A #SUBSTITUTE
+0x1B 0x001B #ESCAPE
+0x1C 0x001C #FILE SEPARATOR
+0x1D 0x001D #GROUP SEPARATOR
+0x1E 0x001E #RECORD SEPARATOR
+0x1F 0x001F #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2A 0x002A #ASTERISK
+0x2B 0x002B #PLUS SIGN
+0x2C 0x002C #COMMA
+0x2D 0x002D #HYPHEN-MINUS
+0x2E 0x002E #FULL STOP
+0x2F 0x002F #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3A 0x003A #COLON
+0x3B 0x003B #SEMICOLON
+0x3C 0x003C #LESS-THAN SIGN
+0x3D 0x003D #EQUALS SIGN
+0x3E 0x003E #GREATER-THAN SIGN
+0x3F 0x003F #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4A 0x004A #LATIN CAPITAL LETTER J
+0x4B 0x004B #LATIN CAPITAL LETTER K
+0x4C 0x004C #LATIN CAPITAL LETTER L
+0x4D 0x004D #LATIN CAPITAL LETTER M
+0x4E 0x004E #LATIN CAPITAL LETTER N
+0x4F 0x004F #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5A 0x005A #LATIN CAPITAL LETTER Z
+0x5B 0x005B #LEFT SQUARE BRACKET
+0x5C 0x005C #REVERSE SOLIDUS
+0x5D 0x005D #RIGHT SQUARE BRACKET
+0x5E 0x005E #CIRCUMFLEX ACCENT
+0x5F 0x005F #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6A 0x006A #LATIN SMALL LETTER J
+0x6B 0x006B #LATIN SMALL LETTER K
+0x6C 0x006C #LATIN SMALL LETTER L
+0x6D 0x006D #LATIN SMALL LETTER M
+0x6E 0x006E #LATIN SMALL LETTER N
+0x6F 0x006F #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7A 0x007A #LATIN SMALL LETTER Z
+0x7B 0x007B #LEFT CURLY BRACKET
+0x7C 0x007C #VERTICAL LINE
+0x7D 0x007D #RIGHT CURLY BRACKET
+0x7E 0x007E #TILDE
+0x7F 0x007F #DELETE
+0x80 #UNDEFINED
+0x81 #DBCS LEAD BYTE
+0x82 #DBCS LEAD BYTE
+0x83 #DBCS LEAD BYTE
+0x84 #DBCS LEAD BYTE
+0x85 #DBCS LEAD BYTE
+0x86 #DBCS LEAD BYTE
+0x87 #DBCS LEAD BYTE
+0x88 #DBCS LEAD BYTE
+0x89 #DBCS LEAD BYTE
+0x8A #DBCS LEAD BYTE
+0x8B #DBCS LEAD BYTE
+0x8C #DBCS LEAD BYTE
+0x8D #DBCS LEAD BYTE
+0x8E #DBCS LEAD BYTE
+0x8F #DBCS LEAD BYTE
+0x90 #DBCS LEAD BYTE
+0x91 #DBCS LEAD BYTE
+0x92 #DBCS LEAD BYTE
+0x93 #DBCS LEAD BYTE
+0x94 #DBCS LEAD BYTE
+0x95 #DBCS LEAD BYTE
+0x96 #DBCS LEAD BYTE
+0x97 #DBCS LEAD BYTE
+0x98 #DBCS LEAD BYTE
+0x99 #DBCS LEAD BYTE
+0x9A #DBCS LEAD BYTE
+0x9B #DBCS LEAD BYTE
+0x9C #DBCS LEAD BYTE
+0x9D #DBCS LEAD BYTE
+0x9E #DBCS LEAD BYTE
+0x9F #DBCS LEAD BYTE
+0xA0 #UNDEFINED
+0xA1 0xFF61 #HALFWIDTH IDEOGRAPHIC FULL STOP
+0xA2 0xFF62 #HALFWIDTH LEFT CORNER BRACKET
+0xA3 0xFF63 #HALFWIDTH RIGHT CORNER BRACKET
+0xA4 0xFF64 #HALFWIDTH IDEOGRAPHIC COMMA
+0xA5 0xFF65 #HALFWIDTH KATAKANA MIDDLE DOT
+0xA6 0xFF66 #HALFWIDTH KATAKANA LETTER WO
+0xA7 0xFF67 #HALFWIDTH KATAKANA LETTER SMALL A
+0xA8 0xFF68 #HALFWIDTH KATAKANA LETTER SMALL I
+0xA9 0xFF69 #HALFWIDTH KATAKANA LETTER SMALL U
+0xAA 0xFF6A #HALFWIDTH KATAKANA LETTER SMALL E
+0xAB 0xFF6B #HALFWIDTH KATAKANA LETTER SMALL O
+0xAC 0xFF6C #HALFWIDTH KATAKANA LETTER SMALL YA
+0xAD 0xFF6D #HALFWIDTH KATAKANA LETTER SMALL YU
+0xAE 0xFF6E #HALFWIDTH KATAKANA LETTER SMALL YO
+0xAF 0xFF6F #HALFWIDTH KATAKANA LETTER SMALL TU
+0xB0 0xFF70 #HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xB1 0xFF71 #HALFWIDTH KATAKANA LETTER A
+0xB2 0xFF72 #HALFWIDTH KATAKANA LETTER I
+0xB3 0xFF73 #HALFWIDTH KATAKANA LETTER U
+0xB4 0xFF74 #HALFWIDTH KATAKANA LETTER E
+0xB5 0xFF75 #HALFWIDTH KATAKANA LETTER O
+0xB6 0xFF76 #HALFWIDTH KATAKANA LETTER KA
+0xB7 0xFF77 #HALFWIDTH KATAKANA LETTER KI
+0xB8 0xFF78 #HALFWIDTH KATAKANA LETTER KU
+0xB9 0xFF79 #HALFWIDTH KATAKANA LETTER KE
+0xBA 0xFF7A #HALFWIDTH KATAKANA LETTER KO
+0xBB 0xFF7B #HALFWIDTH KATAKANA LETTER SA
+0xBC 0xFF7C #HALFWIDTH KATAKANA LETTER SI
+0xBD 0xFF7D #HALFWIDTH KATAKANA LETTER SU
+0xBE 0xFF7E #HALFWIDTH KATAKANA LETTER SE
+0xBF 0xFF7F #HALFWIDTH KATAKANA LETTER SO
+0xC0 0xFF80 #HALFWIDTH KATAKANA LETTER TA
+0xC1 0xFF81 #HALFWIDTH KATAKANA LETTER TI
+0xC2 0xFF82 #HALFWIDTH KATAKANA LETTER TU
+0xC3 0xFF83 #HALFWIDTH KATAKANA LETTER TE
+0xC4 0xFF84 #HALFWIDTH KATAKANA LETTER TO
+0xC5 0xFF85 #HALFWIDTH KATAKANA LETTER NA
+0xC6 0xFF86 #HALFWIDTH KATAKANA LETTER NI
+0xC7 0xFF87 #HALFWIDTH KATAKANA LETTER NU
+0xC8 0xFF88 #HALFWIDTH KATAKANA LETTER NE
+0xC9 0xFF89 #HALFWIDTH KATAKANA LETTER NO
+0xCA 0xFF8A #HALFWIDTH KATAKANA LETTER HA
+0xCB 0xFF8B #HALFWIDTH KATAKANA LETTER HI
+0xCC 0xFF8C #HALFWIDTH KATAKANA LETTER HU
+0xCD 0xFF8D #HALFWIDTH KATAKANA LETTER HE
+0xCE 0xFF8E #HALFWIDTH KATAKANA LETTER HO
+0xCF 0xFF8F #HALFWIDTH KATAKANA LETTER MA
+0xD0 0xFF90 #HALFWIDTH KATAKANA LETTER MI
+0xD1 0xFF91 #HALFWIDTH KATAKANA LETTER MU
+0xD2 0xFF92 #HALFWIDTH KATAKANA LETTER ME
+0xD3 0xFF93 #HALFWIDTH KATAKANA LETTER MO
+0xD4 0xFF94 #HALFWIDTH KATAKANA LETTER YA
+0xD5 0xFF95 #HALFWIDTH KATAKANA LETTER YU
+0xD6 0xFF96 #HALFWIDTH KATAKANA LETTER YO
+0xD7 0xFF97 #HALFWIDTH KATAKANA LETTER RA
+0xD8 0xFF98 #HALFWIDTH KATAKANA LETTER RI
+0xD9 0xFF99 #HALFWIDTH KATAKANA LETTER RU
+0xDA 0xFF9A #HALFWIDTH KATAKANA LETTER RE
+0xDB 0xFF9B #HALFWIDTH KATAKANA LETTER RO
+0xDC 0xFF9C #HALFWIDTH KATAKANA LETTER WA
+0xDD 0xFF9D #HALFWIDTH KATAKANA LETTER N
+0xDE 0xFF9E #HALFWIDTH KATAKANA VOICED SOUND MARK
+0xDF 0xFF9F #HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+0xE0 #DBCS LEAD BYTE
+0xE1 #DBCS LEAD BYTE
+0xE2 #DBCS LEAD BYTE
+0xE3 #DBCS LEAD BYTE
+0xE4 #DBCS LEAD BYTE
+0xE5 #DBCS LEAD BYTE
+0xE6 #DBCS LEAD BYTE
+0xE7 #DBCS LEAD BYTE
+0xE8 #DBCS LEAD BYTE
+0xE9 #DBCS LEAD BYTE
+0xEA #DBCS LEAD BYTE
+0xEB #DBCS LEAD BYTE
+0xEC #DBCS LEAD BYTE
+0xED #DBCS LEAD BYTE
+0xEE #DBCS LEAD BYTE
+0xEF #DBCS LEAD BYTE
+0xF0 #DBCS LEAD BYTE
+0xF1 #DBCS LEAD BYTE
+0xF2 #DBCS LEAD BYTE
+0xF3 #DBCS LEAD BYTE
+0xF4 #DBCS LEAD BYTE
+0xF5 #DBCS LEAD BYTE
+0xF6 #DBCS LEAD BYTE
+0xF7 #DBCS LEAD BYTE
+0xF8 #DBCS LEAD BYTE
+0xF9 #DBCS LEAD BYTE
+0xFA #DBCS LEAD BYTE
+0xFB #DBCS LEAD BYTE
+0xFC #DBCS LEAD BYTE
+0xFD #UNDEFINED
+0xFE #UNDEFINED
+0xFF #UNDEFINED
+0x8140 0x3000 #IDEOGRAPHIC SPACE
+0x8141 0x3001 #IDEOGRAPHIC COMMA
+0x8142 0x3002 #IDEOGRAPHIC FULL STOP
+0x8143 0xFF0C #FULLWIDTH COMMA
+0x8144 0xFF0E #FULLWIDTH FULL STOP
+0x8145 0x30FB #KATAKANA MIDDLE DOT
+0x8146 0xFF1A #FULLWIDTH COLON
+0x8147 0xFF1B #FULLWIDTH SEMICOLON
+0x8148 0xFF1F #FULLWIDTH QUESTION MARK
+0x8149 0xFF01 #FULLWIDTH EXCLAMATION MARK
+0x814A 0x309B #KATAKANA-HIRAGANA VOICED SOUND MARK
+0x814B 0x309C #KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0x814C 0x00B4 #ACUTE ACCENT
+0x814D 0xFF40 #FULLWIDTH GRAVE ACCENT
+0x814E 0x00A8 #DIAERESIS
+0x814F 0xFF3E #FULLWIDTH CIRCUMFLEX ACCENT
+0x8150 0xFFE3 #FULLWIDTH MACRON
+0x8151 0xFF3F #FULLWIDTH LOW LINE
+0x8152 0x30FD #KATAKANA ITERATION MARK
+0x8153 0x30FE #KATAKANA VOICED ITERATION MARK
+0x8154 0x309D #HIRAGANA ITERATION MARK
+0x8155 0x309E #HIRAGANA VOICED ITERATION MARK
+0x8156 0x3003 #DITTO MARK
+0x8157 0x4EDD #CJK UNIFIED IDEOGRAPH
+0x8158 0x3005 #IDEOGRAPHIC ITERATION MARK
+0x8159 0x3006 #IDEOGRAPHIC CLOSING MARK
+0x815A 0x3007 #IDEOGRAPHIC NUMBER ZERO
+0x815B 0x30FC #KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0x815C 0x2015 #HORIZONTAL BAR
+0x815D 0x2010 #HYPHEN
+0x815E 0xFF0F #FULLWIDTH SOLIDUS
+0x815F 0xFF3C #FULLWIDTH REVERSE SOLIDUS
+0x8160 0xFF5E #FULLWIDTH TILDE
+0x8161 0x2225 #PARALLEL TO
+0x8162 0xFF5C #FULLWIDTH VERTICAL LINE
+0x8163 0x2026 #HORIZONTAL ELLIPSIS
+0x8164 0x2025 #TWO DOT LEADER
+0x8165 0x2018 #LEFT SINGLE QUOTATION MARK
+0x8166 0x2019 #RIGHT SINGLE QUOTATION MARK
+0x8167 0x201C #LEFT DOUBLE QUOTATION MARK
+0x8168 0x201D #RIGHT DOUBLE QUOTATION MARK
+0x8169 0xFF08 #FULLWIDTH LEFT PARENTHESIS
+0x816A 0xFF09 #FULLWIDTH RIGHT PARENTHESIS
+0x816B 0x3014 #LEFT TORTOISE SHELL BRACKET
+0x816C 0x3015 #RIGHT TORTOISE SHELL BRACKET
+0x816D 0xFF3B #FULLWIDTH LEFT SQUARE BRACKET
+0x816E 0xFF3D #FULLWIDTH RIGHT SQUARE BRACKET
+0x816F 0xFF5B #FULLWIDTH LEFT CURLY BRACKET
+0x8170 0xFF5D #FULLWIDTH RIGHT CURLY BRACKET
+0x8171 0x3008 #LEFT ANGLE BRACKET
+0x8172 0x3009 #RIGHT ANGLE BRACKET
+0x8173 0x300A #LEFT DOUBLE ANGLE BRACKET
+0x8174 0x300B #RIGHT DOUBLE ANGLE BRACKET
+0x8175 0x300C #LEFT CORNER BRACKET
+0x8176 0x300D #RIGHT CORNER BRACKET
+0x8177 0x300E #LEFT WHITE CORNER BRACKET
+0x8178 0x300F #RIGHT WHITE CORNER BRACKET
+0x8179 0x3010 #LEFT BLACK LENTICULAR BRACKET
+0x817A 0x3011 #RIGHT BLACK LENTICULAR BRACKET
+0x817B 0xFF0B #FULLWIDTH PLUS SIGN
+0x817C 0xFF0D #FULLWIDTH HYPHEN-MINUS
+0x817D 0x00B1 #PLUS-MINUS SIGN
+0x817E 0x00D7 #MULTIPLICATION SIGN
+0x8180 0x00F7 #DIVISION SIGN
+0x8181 0xFF1D #FULLWIDTH EQUALS SIGN
+0x8182 0x2260 #NOT EQUAL TO
+0x8183 0xFF1C #FULLWIDTH LESS-THAN SIGN
+0x8184 0xFF1E #FULLWIDTH GREATER-THAN SIGN
+0x8185 0x2266 #LESS-THAN OVER EQUAL TO
+0x8186 0x2267 #GREATER-THAN OVER EQUAL TO
+0x8187 0x221E #INFINITY
+0x8188 0x2234 #THEREFORE
+0x8189 0x2642 #MALE SIGN
+0x818A 0x2640 #FEMALE SIGN
+0x818B 0x00B0 #DEGREE SIGN
+0x818C 0x2032 #PRIME
+0x818D 0x2033 #DOUBLE PRIME
+0x818E 0x2103 #DEGREE CELSIUS
+0x818F 0xFFE5 #FULLWIDTH YEN SIGN
+0x8190 0xFF04 #FULLWIDTH DOLLAR SIGN
+0x8191 0xFFE0 #FULLWIDTH CENT SIGN
+0x8192 0xFFE1 #FULLWIDTH POUND SIGN
+0x8193 0xFF05 #FULLWIDTH PERCENT SIGN
+0x8194 0xFF03 #FULLWIDTH NUMBER SIGN
+0x8195 0xFF06 #FULLWIDTH AMPERSAND
+0x8196 0xFF0A #FULLWIDTH ASTERISK
+0x8197 0xFF20 #FULLWIDTH COMMERCIAL AT
+0x8198 0x00A7 #SECTION SIGN
+0x8199 0x2606 #WHITE STAR
+0x819A 0x2605 #BLACK STAR
+0x819B 0x25CB #WHITE CIRCLE
+0x819C 0x25CF #BLACK CIRCLE
+0x819D 0x25CE #BULLSEYE
+0x819E 0x25C7 #WHITE DIAMOND
+0x819F 0x25C6 #BLACK DIAMOND
+0x81A0 0x25A1 #WHITE SQUARE
+0x81A1 0x25A0 #BLACK SQUARE
+0x81A2 0x25B3 #WHITE UP-POINTING TRIANGLE
+0x81A3 0x25B2 #BLACK UP-POINTING TRIANGLE
+0x81A4 0x25BD #WHITE DOWN-POINTING TRIANGLE
+0x81A5 0x25BC #BLACK DOWN-POINTING TRIANGLE
+0x81A6 0x203B #REFERENCE MARK
+0x81A7 0x3012 #POSTAL MARK
+0x81A8 0x2192 #RIGHTWARDS ARROW
+0x81A9 0x2190 #LEFTWARDS ARROW
+0x81AA 0x2191 #UPWARDS ARROW
+0x81AB 0x2193 #DOWNWARDS ARROW
+0x81AC 0x3013 #GETA MARK
+0x81B8 0x2208 #ELEMENT OF
+0x81B9 0x220B #CONTAINS AS MEMBER
+0x81BA 0x2286 #SUBSET OF OR EQUAL TO
+0x81BB 0x2287 #SUPERSET OF OR EQUAL TO
+0x81BC 0x2282 #SUBSET OF
+0x81BD 0x2283 #SUPERSET OF
+0x81BE 0x222A #UNION
+0x81BF 0x2229 #INTERSECTION
+0x81C8 0x2227 #LOGICAL AND
+0x81C9 0x2228 #LOGICAL OR
+0x81CA 0xFFE2 #FULLWIDTH NOT SIGN
+0x81CB 0x21D2 #RIGHTWARDS DOUBLE ARROW
+0x81CC 0x21D4 #LEFT RIGHT DOUBLE ARROW
+0x81CD 0x2200 #FOR ALL
+0x81CE 0x2203 #THERE EXISTS
+0x81DA 0x2220 #ANGLE
+0x81DB 0x22A5 #UP TACK
+0x81DC 0x2312 #ARC
+0x81DD 0x2202 #PARTIAL DIFFERENTIAL
+0x81DE 0x2207 #NABLA
+0x81DF 0x2261 #IDENTICAL TO
+0x81E0 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x81E1 0x226A #MUCH LESS-THAN
+0x81E2 0x226B #MUCH GREATER-THAN
+0x81E3 0x221A #SQUARE ROOT
+0x81E4 0x223D #REVERSED TILDE
+0x81E5 0x221D #PROPORTIONAL TO
+0x81E6 0x2235 #BECAUSE
+0x81E7 0x222B #INTEGRAL
+0x81E8 0x222C #DOUBLE INTEGRAL
+0x81F0 0x212B #ANGSTROM SIGN
+0x81F1 0x2030 #PER MILLE SIGN
+0x81F2 0x266F #MUSIC SHARP SIGN
+0x81F3 0x266D #MUSIC FLAT SIGN
+0x81F4 0x266A #EIGHTH NOTE
+0x81F5 0x2020 #DAGGER
+0x81F6 0x2021 #DOUBLE DAGGER
+0x81F7 0x00B6 #PILCROW SIGN
+0x81FC 0x25EF #LARGE CIRCLE
+0x824F 0xFF10 #FULLWIDTH DIGIT ZERO
+0x8250 0xFF11 #FULLWIDTH DIGIT ONE
+0x8251 0xFF12 #FULLWIDTH DIGIT TWO
+0x8252 0xFF13 #FULLWIDTH DIGIT THREE
+0x8253 0xFF14 #FULLWIDTH DIGIT FOUR
+0x8254 0xFF15 #FULLWIDTH DIGIT FIVE
+0x8255 0xFF16 #FULLWIDTH DIGIT SIX
+0x8256 0xFF17 #FULLWIDTH DIGIT SEVEN
+0x8257 0xFF18 #FULLWIDTH DIGIT EIGHT
+0x8258 0xFF19 #FULLWIDTH DIGIT NINE
+0x8260 0xFF21 #FULLWIDTH LATIN CAPITAL LETTER A
+0x8261 0xFF22 #FULLWIDTH LATIN CAPITAL LETTER B
+0x8262 0xFF23 #FULLWIDTH LATIN CAPITAL LETTER C
+0x8263 0xFF24 #FULLWIDTH LATIN CAPITAL LETTER D
+0x8264 0xFF25 #FULLWIDTH LATIN CAPITAL LETTER E
+0x8265 0xFF26 #FULLWIDTH LATIN CAPITAL LETTER F
+0x8266 0xFF27 #FULLWIDTH LATIN CAPITAL LETTER G
+0x8267 0xFF28 #FULLWIDTH LATIN CAPITAL LETTER H
+0x8268 0xFF29 #FULLWIDTH LATIN CAPITAL LETTER I
+0x8269 0xFF2A #FULLWIDTH LATIN CAPITAL LETTER J
+0x826A 0xFF2B #FULLWIDTH LATIN CAPITAL LETTER K
+0x826B 0xFF2C #FULLWIDTH LATIN CAPITAL LETTER L
+0x826C 0xFF2D #FULLWIDTH LATIN CAPITAL LETTER M
+0x826D 0xFF2E #FULLWIDTH LATIN CAPITAL LETTER N
+0x826E 0xFF2F #FULLWIDTH LATIN CAPITAL LETTER O
+0x826F 0xFF30 #FULLWIDTH LATIN CAPITAL LETTER P
+0x8270 0xFF31 #FULLWIDTH LATIN CAPITAL LETTER Q
+0x8271 0xFF32 #FULLWIDTH LATIN CAPITAL LETTER R
+0x8272 0xFF33 #FULLWIDTH LATIN CAPITAL LETTER S
+0x8273 0xFF34 #FULLWIDTH LATIN CAPITAL LETTER T
+0x8274 0xFF35 #FULLWIDTH LATIN CAPITAL LETTER U
+0x8275 0xFF36 #FULLWIDTH LATIN CAPITAL LETTER V
+0x8276 0xFF37 #FULLWIDTH LATIN CAPITAL LETTER W
+0x8277 0xFF38 #FULLWIDTH LATIN CAPITAL LETTER X
+0x8278 0xFF39 #FULLWIDTH LATIN CAPITAL LETTER Y
+0x8279 0xFF3A #FULLWIDTH LATIN CAPITAL LETTER Z
+0x8281 0xFF41 #FULLWIDTH LATIN SMALL LETTER A
+0x8282 0xFF42 #FULLWIDTH LATIN SMALL LETTER B
+0x8283 0xFF43 #FULLWIDTH LATIN SMALL LETTER C
+0x8284 0xFF44 #FULLWIDTH LATIN SMALL LETTER D
+0x8285 0xFF45 #FULLWIDTH LATIN SMALL LETTER E
+0x8286 0xFF46 #FULLWIDTH LATIN SMALL LETTER F
+0x8287 0xFF47 #FULLWIDTH LATIN SMALL LETTER G
+0x8288 0xFF48 #FULLWIDTH LATIN SMALL LETTER H
+0x8289 0xFF49 #FULLWIDTH LATIN SMALL LETTER I
+0x828A 0xFF4A #FULLWIDTH LATIN SMALL LETTER J
+0x828B 0xFF4B #FULLWIDTH LATIN SMALL LETTER K
+0x828C 0xFF4C #FULLWIDTH LATIN SMALL LETTER L
+0x828D 0xFF4D #FULLWIDTH LATIN SMALL LETTER M
+0x828E 0xFF4E #FULLWIDTH LATIN SMALL LETTER N
+0x828F 0xFF4F #FULLWIDTH LATIN SMALL LETTER O
+0x8290 0xFF50 #FULLWIDTH LATIN SMALL LETTER P
+0x8291 0xFF51 #FULLWIDTH LATIN SMALL LETTER Q
+0x8292 0xFF52 #FULLWIDTH LATIN SMALL LETTER R
+0x8293 0xFF53 #FULLWIDTH LATIN SMALL LETTER S
+0x8294 0xFF54 #FULLWIDTH LATIN SMALL LETTER T
+0x8295 0xFF55 #FULLWIDTH LATIN SMALL LETTER U
+0x8296 0xFF56 #FULLWIDTH LATIN SMALL LETTER V
+0x8297 0xFF57 #FULLWIDTH LATIN SMALL LETTER W
+0x8298 0xFF58 #FULLWIDTH LATIN SMALL LETTER X
+0x8299 0xFF59 #FULLWIDTH LATIN SMALL LETTER Y
+0x829A 0xFF5A #FULLWIDTH LATIN SMALL LETTER Z
+0x829F 0x3041 #HIRAGANA LETTER SMALL A
+0x82A0 0x3042 #HIRAGANA LETTER A
+0x82A1 0x3043 #HIRAGANA LETTER SMALL I
+0x82A2 0x3044 #HIRAGANA LETTER I
+0x82A3 0x3045 #HIRAGANA LETTER SMALL U
+0x82A4 0x3046 #HIRAGANA LETTER U
+0x82A5 0x3047 #HIRAGANA LETTER SMALL E
+0x82A6 0x3048 #HIRAGANA LETTER E
+0x82A7 0x3049 #HIRAGANA LETTER SMALL O
+0x82A8 0x304A #HIRAGANA LETTER O
+0x82A9 0x304B #HIRAGANA LETTER KA
+0x82AA 0x304C #HIRAGANA LETTER GA
+0x82AB 0x304D #HIRAGANA LETTER KI
+0x82AC 0x304E #HIRAGANA LETTER GI
+0x82AD 0x304F #HIRAGANA LETTER KU
+0x82AE 0x3050 #HIRAGANA LETTER GU
+0x82AF 0x3051 #HIRAGANA LETTER KE
+0x82B0 0x3052 #HIRAGANA LETTER GE
+0x82B1 0x3053 #HIRAGANA LETTER KO
+0x82B2 0x3054 #HIRAGANA LETTER GO
+0x82B3 0x3055 #HIRAGANA LETTER SA
+0x82B4 0x3056 #HIRAGANA LETTER ZA
+0x82B5 0x3057 #HIRAGANA LETTER SI
+0x82B6 0x3058 #HIRAGANA LETTER ZI
+0x82B7 0x3059 #HIRAGANA LETTER SU
+0x82B8 0x305A #HIRAGANA LETTER ZU
+0x82B9 0x305B #HIRAGANA LETTER SE
+0x82BA 0x305C #HIRAGANA LETTER ZE
+0x82BB 0x305D #HIRAGANA LETTER SO
+0x82BC 0x305E #HIRAGANA LETTER ZO
+0x82BD 0x305F #HIRAGANA LETTER TA
+0x82BE 0x3060 #HIRAGANA LETTER DA
+0x82BF 0x3061 #HIRAGANA LETTER TI
+0x82C0 0x3062 #HIRAGANA LETTER DI
+0x82C1 0x3063 #HIRAGANA LETTER SMALL TU
+0x82C2 0x3064 #HIRAGANA LETTER TU
+0x82C3 0x3065 #HIRAGANA LETTER DU
+0x82C4 0x3066 #HIRAGANA LETTER TE
+0x82C5 0x3067 #HIRAGANA LETTER DE
+0x82C6 0x3068 #HIRAGANA LETTER TO
+0x82C7 0x3069 #HIRAGANA LETTER DO
+0x82C8 0x306A #HIRAGANA LETTER NA
+0x82C9 0x306B #HIRAGANA LETTER NI
+0x82CA 0x306C #HIRAGANA LETTER NU
+0x82CB 0x306D #HIRAGANA LETTER NE
+0x82CC 0x306E #HIRAGANA LETTER NO
+0x82CD 0x306F #HIRAGANA LETTER HA
+0x82CE 0x3070 #HIRAGANA LETTER BA
+0x82CF 0x3071 #HIRAGANA LETTER PA
+0x82D0 0x3072 #HIRAGANA LETTER HI
+0x82D1 0x3073 #HIRAGANA LETTER BI
+0x82D2 0x3074 #HIRAGANA LETTER PI
+0x82D3 0x3075 #HIRAGANA LETTER HU
+0x82D4 0x3076 #HIRAGANA LETTER BU
+0x82D5 0x3077 #HIRAGANA LETTER PU
+0x82D6 0x3078 #HIRAGANA LETTER HE
+0x82D7 0x3079 #HIRAGANA LETTER BE
+0x82D8 0x307A #HIRAGANA LETTER PE
+0x82D9 0x307B #HIRAGANA LETTER HO
+0x82DA 0x307C #HIRAGANA LETTER BO
+0x82DB 0x307D #HIRAGANA LETTER PO
+0x82DC 0x307E #HIRAGANA LETTER MA
+0x82DD 0x307F #HIRAGANA LETTER MI
+0x82DE 0x3080 #HIRAGANA LETTER MU
+0x82DF 0x3081 #HIRAGANA LETTER ME
+0x82E0 0x3082 #HIRAGANA LETTER MO
+0x82E1 0x3083 #HIRAGANA LETTER SMALL YA
+0x82E2 0x3084 #HIRAGANA LETTER YA
+0x82E3 0x3085 #HIRAGANA LETTER SMALL YU
+0x82E4 0x3086 #HIRAGANA LETTER YU
+0x82E5 0x3087 #HIRAGANA LETTER SMALL YO
+0x82E6 0x3088 #HIRAGANA LETTER YO
+0x82E7 0x3089 #HIRAGANA LETTER RA
+0x82E8 0x308A #HIRAGANA LETTER RI
+0x82E9 0x308B #HIRAGANA LETTER RU
+0x82EA 0x308C #HIRAGANA LETTER RE
+0x82EB 0x308D #HIRAGANA LETTER RO
+0x82EC 0x308E #HIRAGANA LETTER SMALL WA
+0x82ED 0x308F #HIRAGANA LETTER WA
+0x82EE 0x3090 #HIRAGANA LETTER WI
+0x82EF 0x3091 #HIRAGANA LETTER WE
+0x82F0 0x3092 #HIRAGANA LETTER WO
+0x82F1 0x3093 #HIRAGANA LETTER N
+0x8340 0x30A1 #KATAKANA LETTER SMALL A
+0x8341 0x30A2 #KATAKANA LETTER A
+0x8342 0x30A3 #KATAKANA LETTER SMALL I
+0x8343 0x30A4 #KATAKANA LETTER I
+0x8344 0x30A5 #KATAKANA LETTER SMALL U
+0x8345 0x30A6 #KATAKANA LETTER U
+0x8346 0x30A7 #KATAKANA LETTER SMALL E
+0x8347 0x30A8 #KATAKANA LETTER E
+0x8348 0x30A9 #KATAKANA LETTER SMALL O
+0x8349 0x30AA #KATAKANA LETTER O
+0x834A 0x30AB #KATAKANA LETTER KA
+0x834B 0x30AC #KATAKANA LETTER GA
+0x834C 0x30AD #KATAKANA LETTER KI
+0x834D 0x30AE #KATAKANA LETTER GI
+0x834E 0x30AF #KATAKANA LETTER KU
+0x834F 0x30B0 #KATAKANA LETTER GU
+0x8350 0x30B1 #KATAKANA LETTER KE
+0x8351 0x30B2 #KATAKANA LETTER GE
+0x8352 0x30B3 #KATAKANA LETTER KO
+0x8353 0x30B4 #KATAKANA LETTER GO
+0x8354 0x30B5 #KATAKANA LETTER SA
+0x8355 0x30B6 #KATAKANA LETTER ZA
+0x8356 0x30B7 #KATAKANA LETTER SI
+0x8357 0x30B8 #KATAKANA LETTER ZI
+0x8358 0x30B9 #KATAKANA LETTER SU
+0x8359 0x30BA #KATAKANA LETTER ZU
+0x835A 0x30BB #KATAKANA LETTER SE
+0x835B 0x30BC #KATAKANA LETTER ZE
+0x835C 0x30BD #KATAKANA LETTER SO
+0x835D 0x30BE #KATAKANA LETTER ZO
+0x835E 0x30BF #KATAKANA LETTER TA
+0x835F 0x30C0 #KATAKANA LETTER DA
+0x8360 0x30C1 #KATAKANA LETTER TI
+0x8361 0x30C2 #KATAKANA LETTER DI
+0x8362 0x30C3 #KATAKANA LETTER SMALL TU
+0x8363 0x30C4 #KATAKANA LETTER TU
+0x8364 0x30C5 #KATAKANA LETTER DU
+0x8365 0x30C6 #KATAKANA LETTER TE
+0x8366 0x30C7 #KATAKANA LETTER DE
+0x8367 0x30C8 #KATAKANA LETTER TO
+0x8368 0x30C9 #KATAKANA LETTER DO
+0x8369 0x30CA #KATAKANA LETTER NA
+0x836A 0x30CB #KATAKANA LETTER NI
+0x836B 0x30CC #KATAKANA LETTER NU
+0x836C 0x30CD #KATAKANA LETTER NE
+0x836D 0x30CE #KATAKANA LETTER NO
+0x836E 0x30CF #KATAKANA LETTER HA
+0x836F 0x30D0 #KATAKANA LETTER BA
+0x8370 0x30D1 #KATAKANA LETTER PA
+0x8371 0x30D2 #KATAKANA LETTER HI
+0x8372 0x30D3 #KATAKANA LETTER BI
+0x8373 0x30D4 #KATAKANA LETTER PI
+0x8374 0x30D5 #KATAKANA LETTER HU
+0x8375 0x30D6 #KATAKANA LETTER BU
+0x8376 0x30D7 #KATAKANA LETTER PU
+0x8377 0x30D8 #KATAKANA LETTER HE
+0x8378 0x30D9 #KATAKANA LETTER BE
+0x8379 0x30DA #KATAKANA LETTER PE
+0x837A 0x30DB #KATAKANA LETTER HO
+0x837B 0x30DC #KATAKANA LETTER BO
+0x837C 0x30DD #KATAKANA LETTER PO
+0x837D 0x30DE #KATAKANA LETTER MA
+0x837E 0x30DF #KATAKANA LETTER MI
+0x8380 0x30E0 #KATAKANA LETTER MU
+0x8381 0x30E1 #KATAKANA LETTER ME
+0x8382 0x30E2 #KATAKANA LETTER MO
+0x8383 0x30E3 #KATAKANA LETTER SMALL YA
+0x8384 0x30E4 #KATAKANA LETTER YA
+0x8385 0x30E5 #KATAKANA LETTER SMALL YU
+0x8386 0x30E6 #KATAKANA LETTER YU
+0x8387 0x30E7 #KATAKANA LETTER SMALL YO
+0x8388 0x30E8 #KATAKANA LETTER YO
+0x8389 0x30E9 #KATAKANA LETTER RA
+0x838A 0x30EA #KATAKANA LETTER RI
+0x838B 0x30EB #KATAKANA LETTER RU
+0x838C 0x30EC #KATAKANA LETTER RE
+0x838D 0x30ED #KATAKANA LETTER RO
+0x838E 0x30EE #KATAKANA LETTER SMALL WA
+0x838F 0x30EF #KATAKANA LETTER WA
+0x8390 0x30F0 #KATAKANA LETTER WI
+0x8391 0x30F1 #KATAKANA LETTER WE
+0x8392 0x30F2 #KATAKANA LETTER WO
+0x8393 0x30F3 #KATAKANA LETTER N
+0x8394 0x30F4 #KATAKANA LETTER VU
+0x8395 0x30F5 #KATAKANA LETTER SMALL KA
+0x8396 0x30F6 #KATAKANA LETTER SMALL KE
+0x839F 0x0391 #GREEK CAPITAL LETTER ALPHA
+0x83A0 0x0392 #GREEK CAPITAL LETTER BETA
+0x83A1 0x0393 #GREEK CAPITAL LETTER GAMMA
+0x83A2 0x0394 #GREEK CAPITAL LETTER DELTA
+0x83A3 0x0395 #GREEK CAPITAL LETTER EPSILON
+0x83A4 0x0396 #GREEK CAPITAL LETTER ZETA
+0x83A5 0x0397 #GREEK CAPITAL LETTER ETA
+0x83A6 0x0398 #GREEK CAPITAL LETTER THETA
+0x83A7 0x0399 #GREEK CAPITAL LETTER IOTA
+0x83A8 0x039A #GREEK CAPITAL LETTER KAPPA
+0x83A9 0x039B #GREEK CAPITAL LETTER LAMDA
+0x83AA 0x039C #GREEK CAPITAL LETTER MU
+0x83AB 0x039D #GREEK CAPITAL LETTER NU
+0x83AC 0x039E #GREEK CAPITAL LETTER XI
+0x83AD 0x039F #GREEK CAPITAL LETTER OMICRON
+0x83AE 0x03A0 #GREEK CAPITAL LETTER PI
+0x83AF 0x03A1 #GREEK CAPITAL LETTER RHO
+0x83B0 0x03A3 #GREEK CAPITAL LETTER SIGMA
+0x83B1 0x03A4 #GREEK CAPITAL LETTER TAU
+0x83B2 0x03A5 #GREEK CAPITAL LETTER UPSILON
+0x83B3 0x03A6 #GREEK CAPITAL LETTER PHI
+0x83B4 0x03A7 #GREEK CAPITAL LETTER CHI
+0x83B5 0x03A8 #GREEK CAPITAL LETTER PSI
+0x83B6 0x03A9 #GREEK CAPITAL LETTER OMEGA
+0x83BF 0x03B1 #GREEK SMALL LETTER ALPHA
+0x83C0 0x03B2 #GREEK SMALL LETTER BETA
+0x83C1 0x03B3 #GREEK SMALL LETTER GAMMA
+0x83C2 0x03B4 #GREEK SMALL LETTER DELTA
+0x83C3 0x03B5 #GREEK SMALL LETTER EPSILON
+0x83C4 0x03B6 #GREEK SMALL LETTER ZETA
+0x83C5 0x03B7 #GREEK SMALL LETTER ETA
+0x83C6 0x03B8 #GREEK SMALL LETTER THETA
+0x83C7 0x03B9 #GREEK SMALL LETTER IOTA
+0x83C8 0x03BA #GREEK SMALL LETTER KAPPA
+0x83C9 0x03BB #GREEK SMALL LETTER LAMDA
+0x83CA 0x03BC #GREEK SMALL LETTER MU
+0x83CB 0x03BD #GREEK SMALL LETTER NU
+0x83CC 0x03BE #GREEK SMALL LETTER XI
+0x83CD 0x03BF #GREEK SMALL LETTER OMICRON
+0x83CE 0x03C0 #GREEK SMALL LETTER PI
+0x83CF 0x03C1 #GREEK SMALL LETTER RHO
+0x83D0 0x03C3 #GREEK SMALL LETTER SIGMA
+0x83D1 0x03C4 #GREEK SMALL LETTER TAU
+0x83D2 0x03C5 #GREEK SMALL LETTER UPSILON
+0x83D3 0x03C6 #GREEK SMALL LETTER PHI
+0x83D4 0x03C7 #GREEK SMALL LETTER CHI
+0x83D5 0x03C8 #GREEK SMALL LETTER PSI
+0x83D6 0x03C9 #GREEK SMALL LETTER OMEGA
+0x8440 0x0410 #CYRILLIC CAPITAL LETTER A
+0x8441 0x0411 #CYRILLIC CAPITAL LETTER BE
+0x8442 0x0412 #CYRILLIC CAPITAL LETTER VE
+0x8443 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0x8444 0x0414 #CYRILLIC CAPITAL LETTER DE
+0x8445 0x0415 #CYRILLIC CAPITAL LETTER IE
+0x8446 0x0401 #CYRILLIC CAPITAL LETTER IO
+0x8447 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0x8448 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0x8449 0x0418 #CYRILLIC CAPITAL LETTER I
+0x844A 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0x844B 0x041A #CYRILLIC CAPITAL LETTER KA
+0x844C 0x041B #CYRILLIC CAPITAL LETTER EL
+0x844D 0x041C #CYRILLIC CAPITAL LETTER EM
+0x844E 0x041D #CYRILLIC CAPITAL LETTER EN
+0x844F 0x041E #CYRILLIC CAPITAL LETTER O
+0x8450 0x041F #CYRILLIC CAPITAL LETTER PE
+0x8451 0x0420 #CYRILLIC CAPITAL LETTER ER
+0x8452 0x0421 #CYRILLIC CAPITAL LETTER ES
+0x8453 0x0422 #CYRILLIC CAPITAL LETTER TE
+0x8454 0x0423 #CYRILLIC CAPITAL LETTER U
+0x8455 0x0424 #CYRILLIC CAPITAL LETTER EF
+0x8456 0x0425 #CYRILLIC CAPITAL LETTER HA
+0x8457 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0x8458 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0x8459 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0x845A 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0x845B 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN
+0x845C 0x042B #CYRILLIC CAPITAL LETTER YERU
+0x845D 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN
+0x845E 0x042D #CYRILLIC CAPITAL LETTER E
+0x845F 0x042E #CYRILLIC CAPITAL LETTER YU
+0x8460 0x042F #CYRILLIC CAPITAL LETTER YA
+0x8470 0x0430 #CYRILLIC SMALL LETTER A
+0x8471 0x0431 #CYRILLIC SMALL LETTER BE
+0x8472 0x0432 #CYRILLIC SMALL LETTER VE
+0x8473 0x0433 #CYRILLIC SMALL LETTER GHE
+0x8474 0x0434 #CYRILLIC SMALL LETTER DE
+0x8475 0x0435 #CYRILLIC SMALL LETTER IE
+0x8476 0x0451 #CYRILLIC SMALL LETTER IO
+0x8477 0x0436 #CYRILLIC SMALL LETTER ZHE
+0x8478 0x0437 #CYRILLIC SMALL LETTER ZE
+0x8479 0x0438 #CYRILLIC SMALL LETTER I
+0x847A 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0x847B 0x043A #CYRILLIC SMALL LETTER KA
+0x847C 0x043B #CYRILLIC SMALL LETTER EL
+0x847D 0x043C #CYRILLIC SMALL LETTER EM
+0x847E 0x043D #CYRILLIC SMALL LETTER EN
+0x8480 0x043E #CYRILLIC SMALL LETTER O
+0x8481 0x043F #CYRILLIC SMALL LETTER PE
+0x8482 0x0440 #CYRILLIC SMALL LETTER ER
+0x8483 0x0441 #CYRILLIC SMALL LETTER ES
+0x8484 0x0442 #CYRILLIC SMALL LETTER TE
+0x8485 0x0443 #CYRILLIC SMALL LETTER U
+0x8486 0x0444 #CYRILLIC SMALL LETTER EF
+0x8487 0x0445 #CYRILLIC SMALL LETTER HA
+0x8488 0x0446 #CYRILLIC SMALL LETTER TSE
+0x8489 0x0447 #CYRILLIC SMALL LETTER CHE
+0x848A 0x0448 #CYRILLIC SMALL LETTER SHA
+0x848B 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0x848C 0x044A #CYRILLIC SMALL LETTER HARD SIGN
+0x848D 0x044B #CYRILLIC SMALL LETTER YERU
+0x848E 0x044C #CYRILLIC SMALL LETTER SOFT SIGN
+0x848F 0x044D #CYRILLIC SMALL LETTER E
+0x8490 0x044E #CYRILLIC SMALL LETTER YU
+0x8491 0x044F #CYRILLIC SMALL LETTER YA
+0x849F 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0x84A0 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0x84A1 0x250C #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x84A2 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84A3 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0x84A4 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0x84A5 0x251C #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x84A6 0x252C #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x84A7 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x84A8 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x84A9 0x253C #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x84AA 0x2501 #BOX DRAWINGS HEAVY HORIZONTAL
+0x84AB 0x2503 #BOX DRAWINGS HEAVY VERTICAL
+0x84AC 0x250F #BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x84AD 0x2513 #BOX DRAWINGS HEAVY DOWN AND LEFT
+0x84AE 0x251B #BOX DRAWINGS HEAVY UP AND LEFT
+0x84AF 0x2517 #BOX DRAWINGS HEAVY UP AND RIGHT
+0x84B0 0x2523 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x84B1 0x2533 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x84B2 0x252B #BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x84B3 0x253B #BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x84B4 0x254B #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x84B5 0x2520 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x84B6 0x252F #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x84B7 0x2528 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x84B8 0x2537 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x84B9 0x253F #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x84BA 0x251D #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x84BB 0x2530 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x84BC 0x2525 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x84BD 0x2538 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x84BE 0x2542 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x8740 0x2460 #CIRCLED DIGIT ONE
+0x8741 0x2461 #CIRCLED DIGIT TWO
+0x8742 0x2462 #CIRCLED DIGIT THREE
+0x8743 0x2463 #CIRCLED DIGIT FOUR
+0x8744 0x2464 #CIRCLED DIGIT FIVE
+0x8745 0x2465 #CIRCLED DIGIT SIX
+0x8746 0x2466 #CIRCLED DIGIT SEVEN
+0x8747 0x2467 #CIRCLED DIGIT EIGHT
+0x8748 0x2468 #CIRCLED DIGIT NINE
+0x8749 0x2469 #CIRCLED NUMBER TEN
+0x874A 0x246A #CIRCLED NUMBER ELEVEN
+0x874B 0x246B #CIRCLED NUMBER TWELVE
+0x874C 0x246C #CIRCLED NUMBER THIRTEEN
+0x874D 0x246D #CIRCLED NUMBER FOURTEEN
+0x874E 0x246E #CIRCLED NUMBER FIFTEEN
+0x874F 0x246F #CIRCLED NUMBER SIXTEEN
+0x8750 0x2470 #CIRCLED NUMBER SEVENTEEN
+0x8751 0x2471 #CIRCLED NUMBER EIGHTEEN
+0x8752 0x2472 #CIRCLED NUMBER NINETEEN
+0x8753 0x2473 #CIRCLED NUMBER TWENTY
+0x8754 0x2160 #ROMAN NUMERAL ONE
+0x8755 0x2161 #ROMAN NUMERAL TWO
+0x8756 0x2162 #ROMAN NUMERAL THREE
+0x8757 0x2163 #ROMAN NUMERAL FOUR
+0x8758 0x2164 #ROMAN NUMERAL FIVE
+0x8759 0x2165 #ROMAN NUMERAL SIX
+0x875A 0x2166 #ROMAN NUMERAL SEVEN
+0x875B 0x2167 #ROMAN NUMERAL EIGHT
+0x875C 0x2168 #ROMAN NUMERAL NINE
+0x875D 0x2169 #ROMAN NUMERAL TEN
+0x875F 0x3349 #SQUARE MIRI
+0x8760 0x3314 #SQUARE KIRO
+0x8761 0x3322 #SQUARE SENTI
+0x8762 0x334D #SQUARE MEETORU
+0x8763 0x3318 #SQUARE GURAMU
+0x8764 0x3327 #SQUARE TON
+0x8765 0x3303 #SQUARE AARU
+0x8766 0x3336 #SQUARE HEKUTAARU
+0x8767 0x3351 #SQUARE RITTORU
+0x8768 0x3357 #SQUARE WATTO
+0x8769 0x330D #SQUARE KARORII
+0x876A 0x3326 #SQUARE DORU
+0x876B 0x3323 #SQUARE SENTO
+0x876C 0x332B #SQUARE PAASENTO
+0x876D 0x334A #SQUARE MIRIBAARU
+0x876E 0x333B #SQUARE PEEZI
+0x876F 0x339C #SQUARE MM
+0x8770 0x339D #SQUARE CM
+0x8771 0x339E #SQUARE KM
+0x8772 0x338E #SQUARE MG
+0x8773 0x338F #SQUARE KG
+0x8774 0x33C4 #SQUARE CC
+0x8775 0x33A1 #SQUARE M SQUARED
+0x877E 0x337B #SQUARE ERA NAME HEISEI
+0x8780 0x301D #REVERSED DOUBLE PRIME QUOTATION MARK
+0x8781 0x301F #LOW DOUBLE PRIME QUOTATION MARK
+0x8782 0x2116 #NUMERO SIGN
+0x8783 0x33CD #SQUARE KK
+0x8784 0x2121 #TELEPHONE SIGN
+0x8785 0x32A4 #CIRCLED IDEOGRAPH HIGH
+0x8786 0x32A5 #CIRCLED IDEOGRAPH CENTRE
+0x8787 0x32A6 #CIRCLED IDEOGRAPH LOW
+0x8788 0x32A7 #CIRCLED IDEOGRAPH LEFT
+0x8789 0x32A8 #CIRCLED IDEOGRAPH RIGHT
+0x878A 0x3231 #PARENTHESIZED IDEOGRAPH STOCK
+0x878B 0x3232 #PARENTHESIZED IDEOGRAPH HAVE
+0x878C 0x3239 #PARENTHESIZED IDEOGRAPH REPRESENT
+0x878D 0x337E #SQUARE ERA NAME MEIZI
+0x878E 0x337D #SQUARE ERA NAME TAISYOU
+0x878F 0x337C #SQUARE ERA NAME SYOUWA
+0x8793 0x222E #CONTOUR INTEGRAL
+0x8794 0x2211 #N-ARY SUMMATION
+0x8798 0x221F #RIGHT ANGLE
+0x8799 0x22BF #RIGHT TRIANGLE
+0x889F 0x4E9C #CJK UNIFIED IDEOGRAPH
+0x88A0 0x5516 #CJK UNIFIED IDEOGRAPH
+0x88A1 0x5A03 #CJK UNIFIED IDEOGRAPH
+0x88A2 0x963F #CJK UNIFIED IDEOGRAPH
+0x88A3 0x54C0 #CJK UNIFIED IDEOGRAPH
+0x88A4 0x611B #CJK UNIFIED IDEOGRAPH
+0x88A5 0x6328 #CJK UNIFIED IDEOGRAPH
+0x88A6 0x59F6 #CJK UNIFIED IDEOGRAPH
+0x88A7 0x9022 #CJK UNIFIED IDEOGRAPH
+0x88A8 0x8475 #CJK UNIFIED IDEOGRAPH
+0x88A9 0x831C #CJK UNIFIED IDEOGRAPH
+0x88AA 0x7A50 #CJK UNIFIED IDEOGRAPH
+0x88AB 0x60AA #CJK UNIFIED IDEOGRAPH
+0x88AC 0x63E1 #CJK UNIFIED IDEOGRAPH
+0x88AD 0x6E25 #CJK UNIFIED IDEOGRAPH
+0x88AE 0x65ED #CJK UNIFIED IDEOGRAPH
+0x88AF 0x8466 #CJK UNIFIED IDEOGRAPH
+0x88B0 0x82A6 #CJK UNIFIED IDEOGRAPH
+0x88B1 0x9BF5 #CJK UNIFIED IDEOGRAPH
+0x88B2 0x6893 #CJK UNIFIED IDEOGRAPH
+0x88B3 0x5727 #CJK UNIFIED IDEOGRAPH
+0x88B4 0x65A1 #CJK UNIFIED IDEOGRAPH
+0x88B5 0x6271 #CJK UNIFIED IDEOGRAPH
+0x88B6 0x5B9B #CJK UNIFIED IDEOGRAPH
+0x88B7 0x59D0 #CJK UNIFIED IDEOGRAPH
+0x88B8 0x867B #CJK UNIFIED IDEOGRAPH
+0x88B9 0x98F4 #CJK UNIFIED IDEOGRAPH
+0x88BA 0x7D62 #CJK UNIFIED IDEOGRAPH
+0x88BB 0x7DBE #CJK UNIFIED IDEOGRAPH
+0x88BC 0x9B8E #CJK UNIFIED IDEOGRAPH
+0x88BD 0x6216 #CJK UNIFIED IDEOGRAPH
+0x88BE 0x7C9F #CJK UNIFIED IDEOGRAPH
+0x88BF 0x88B7 #CJK UNIFIED IDEOGRAPH
+0x88C0 0x5B89 #CJK UNIFIED IDEOGRAPH
+0x88C1 0x5EB5 #CJK UNIFIED IDEOGRAPH
+0x88C2 0x6309 #CJK UNIFIED IDEOGRAPH
+0x88C3 0x6697 #CJK UNIFIED IDEOGRAPH
+0x88C4 0x6848 #CJK UNIFIED IDEOGRAPH
+0x88C5 0x95C7 #CJK UNIFIED IDEOGRAPH
+0x88C6 0x978D #CJK UNIFIED IDEOGRAPH
+0x88C7 0x674F #CJK UNIFIED IDEOGRAPH
+0x88C8 0x4EE5 #CJK UNIFIED IDEOGRAPH
+0x88C9 0x4F0A #CJK UNIFIED IDEOGRAPH
+0x88CA 0x4F4D #CJK UNIFIED IDEOGRAPH
+0x88CB 0x4F9D #CJK UNIFIED IDEOGRAPH
+0x88CC 0x5049 #CJK UNIFIED IDEOGRAPH
+0x88CD 0x56F2 #CJK UNIFIED IDEOGRAPH
+0x88CE 0x5937 #CJK UNIFIED IDEOGRAPH
+0x88CF 0x59D4 #CJK UNIFIED IDEOGRAPH
+0x88D0 0x5A01 #CJK UNIFIED IDEOGRAPH
+0x88D1 0x5C09 #CJK UNIFIED IDEOGRAPH
+0x88D2 0x60DF #CJK UNIFIED IDEOGRAPH
+0x88D3 0x610F #CJK UNIFIED IDEOGRAPH
+0x88D4 0x6170 #CJK UNIFIED IDEOGRAPH
+0x88D5 0x6613 #CJK UNIFIED IDEOGRAPH
+0x88D6 0x6905 #CJK UNIFIED IDEOGRAPH
+0x88D7 0x70BA #CJK UNIFIED IDEOGRAPH
+0x88D8 0x754F #CJK UNIFIED IDEOGRAPH
+0x88D9 0x7570 #CJK UNIFIED IDEOGRAPH
+0x88DA 0x79FB #CJK UNIFIED IDEOGRAPH
+0x88DB 0x7DAD #CJK UNIFIED IDEOGRAPH
+0x88DC 0x7DEF #CJK UNIFIED IDEOGRAPH
+0x88DD 0x80C3 #CJK UNIFIED IDEOGRAPH
+0x88DE 0x840E #CJK UNIFIED IDEOGRAPH
+0x88DF 0x8863 #CJK UNIFIED IDEOGRAPH
+0x88E0 0x8B02 #CJK UNIFIED IDEOGRAPH
+0x88E1 0x9055 #CJK UNIFIED IDEOGRAPH
+0x88E2 0x907A #CJK UNIFIED IDEOGRAPH
+0x88E3 0x533B #CJK UNIFIED IDEOGRAPH
+0x88E4 0x4E95 #CJK UNIFIED IDEOGRAPH
+0x88E5 0x4EA5 #CJK UNIFIED IDEOGRAPH
+0x88E6 0x57DF #CJK UNIFIED IDEOGRAPH
+0x88E7 0x80B2 #CJK UNIFIED IDEOGRAPH
+0x88E8 0x90C1 #CJK UNIFIED IDEOGRAPH
+0x88E9 0x78EF #CJK UNIFIED IDEOGRAPH
+0x88EA 0x4E00 #CJK UNIFIED IDEOGRAPH
+0x88EB 0x58F1 #CJK UNIFIED IDEOGRAPH
+0x88EC 0x6EA2 #CJK UNIFIED IDEOGRAPH
+0x88ED 0x9038 #CJK UNIFIED IDEOGRAPH
+0x88EE 0x7A32 #CJK UNIFIED IDEOGRAPH
+0x88EF 0x8328 #CJK UNIFIED IDEOGRAPH
+0x88F0 0x828B #CJK UNIFIED IDEOGRAPH
+0x88F1 0x9C2F #CJK UNIFIED IDEOGRAPH
+0x88F2 0x5141 #CJK UNIFIED IDEOGRAPH
+0x88F3 0x5370 #CJK UNIFIED IDEOGRAPH
+0x88F4 0x54BD #CJK UNIFIED IDEOGRAPH
+0x88F5 0x54E1 #CJK UNIFIED IDEOGRAPH
+0x88F6 0x56E0 #CJK UNIFIED IDEOGRAPH
+0x88F7 0x59FB #CJK UNIFIED IDEOGRAPH
+0x88F8 0x5F15 #CJK UNIFIED IDEOGRAPH
+0x88F9 0x98F2 #CJK UNIFIED IDEOGRAPH
+0x88FA 0x6DEB #CJK UNIFIED IDEOGRAPH
+0x88FB 0x80E4 #CJK UNIFIED IDEOGRAPH
+0x88FC 0x852D #CJK UNIFIED IDEOGRAPH
+0x8940 0x9662 #CJK UNIFIED IDEOGRAPH
+0x8941 0x9670 #CJK UNIFIED IDEOGRAPH
+0x8942 0x96A0 #CJK UNIFIED IDEOGRAPH
+0x8943 0x97FB #CJK UNIFIED IDEOGRAPH
+0x8944 0x540B #CJK UNIFIED IDEOGRAPH
+0x8945 0x53F3 #CJK UNIFIED IDEOGRAPH
+0x8946 0x5B87 #CJK UNIFIED IDEOGRAPH
+0x8947 0x70CF #CJK UNIFIED IDEOGRAPH
+0x8948 0x7FBD #CJK UNIFIED IDEOGRAPH
+0x8949 0x8FC2 #CJK UNIFIED IDEOGRAPH
+0x894A 0x96E8 #CJK UNIFIED IDEOGRAPH
+0x894B 0x536F #CJK UNIFIED IDEOGRAPH
+0x894C 0x9D5C #CJK UNIFIED IDEOGRAPH
+0x894D 0x7ABA #CJK UNIFIED IDEOGRAPH
+0x894E 0x4E11 #CJK UNIFIED IDEOGRAPH
+0x894F 0x7893 #CJK UNIFIED IDEOGRAPH
+0x8950 0x81FC #CJK UNIFIED IDEOGRAPH
+0x8951 0x6E26 #CJK UNIFIED IDEOGRAPH
+0x8952 0x5618 #CJK UNIFIED IDEOGRAPH
+0x8953 0x5504 #CJK UNIFIED IDEOGRAPH
+0x8954 0x6B1D #CJK UNIFIED IDEOGRAPH
+0x8955 0x851A #CJK UNIFIED IDEOGRAPH
+0x8956 0x9C3B #CJK UNIFIED IDEOGRAPH
+0x8957 0x59E5 #CJK UNIFIED IDEOGRAPH
+0x8958 0x53A9 #CJK UNIFIED IDEOGRAPH
+0x8959 0x6D66 #CJK UNIFIED IDEOGRAPH
+0x895A 0x74DC #CJK UNIFIED IDEOGRAPH
+0x895B 0x958F #CJK UNIFIED IDEOGRAPH
+0x895C 0x5642 #CJK UNIFIED IDEOGRAPH
+0x895D 0x4E91 #CJK UNIFIED IDEOGRAPH
+0x895E 0x904B #CJK UNIFIED IDEOGRAPH
+0x895F 0x96F2 #CJK UNIFIED IDEOGRAPH
+0x8960 0x834F #CJK UNIFIED IDEOGRAPH
+0x8961 0x990C #CJK UNIFIED IDEOGRAPH
+0x8962 0x53E1 #CJK UNIFIED IDEOGRAPH
+0x8963 0x55B6 #CJK UNIFIED IDEOGRAPH
+0x8964 0x5B30 #CJK UNIFIED IDEOGRAPH
+0x8965 0x5F71 #CJK UNIFIED IDEOGRAPH
+0x8966 0x6620 #CJK UNIFIED IDEOGRAPH
+0x8967 0x66F3 #CJK UNIFIED IDEOGRAPH
+0x8968 0x6804 #CJK UNIFIED IDEOGRAPH
+0x8969 0x6C38 #CJK UNIFIED IDEOGRAPH
+0x896A 0x6CF3 #CJK UNIFIED IDEOGRAPH
+0x896B 0x6D29 #CJK UNIFIED IDEOGRAPH
+0x896C 0x745B #CJK UNIFIED IDEOGRAPH
+0x896D 0x76C8 #CJK UNIFIED IDEOGRAPH
+0x896E 0x7A4E #CJK UNIFIED IDEOGRAPH
+0x896F 0x9834 #CJK UNIFIED IDEOGRAPH
+0x8970 0x82F1 #CJK UNIFIED IDEOGRAPH
+0x8971 0x885B #CJK UNIFIED IDEOGRAPH
+0x8972 0x8A60 #CJK UNIFIED IDEOGRAPH
+0x8973 0x92ED #CJK UNIFIED IDEOGRAPH
+0x8974 0x6DB2 #CJK UNIFIED IDEOGRAPH
+0x8975 0x75AB #CJK UNIFIED IDEOGRAPH
+0x8976 0x76CA #CJK UNIFIED IDEOGRAPH
+0x8977 0x99C5 #CJK UNIFIED IDEOGRAPH
+0x8978 0x60A6 #CJK UNIFIED IDEOGRAPH
+0x8979 0x8B01 #CJK UNIFIED IDEOGRAPH
+0x897A 0x8D8A #CJK UNIFIED IDEOGRAPH
+0x897B 0x95B2 #CJK UNIFIED IDEOGRAPH
+0x897C 0x698E #CJK UNIFIED IDEOGRAPH
+0x897D 0x53AD #CJK UNIFIED IDEOGRAPH
+0x897E 0x5186 #CJK UNIFIED IDEOGRAPH
+0x8980 0x5712 #CJK UNIFIED IDEOGRAPH
+0x8981 0x5830 #CJK UNIFIED IDEOGRAPH
+0x8982 0x5944 #CJK UNIFIED IDEOGRAPH
+0x8983 0x5BB4 #CJK UNIFIED IDEOGRAPH
+0x8984 0x5EF6 #CJK UNIFIED IDEOGRAPH
+0x8985 0x6028 #CJK UNIFIED IDEOGRAPH
+0x8986 0x63A9 #CJK UNIFIED IDEOGRAPH
+0x8987 0x63F4 #CJK UNIFIED IDEOGRAPH
+0x8988 0x6CBF #CJK UNIFIED IDEOGRAPH
+0x8989 0x6F14 #CJK UNIFIED IDEOGRAPH
+0x898A 0x708E #CJK UNIFIED IDEOGRAPH
+0x898B 0x7114 #CJK UNIFIED IDEOGRAPH
+0x898C 0x7159 #CJK UNIFIED IDEOGRAPH
+0x898D 0x71D5 #CJK UNIFIED IDEOGRAPH
+0x898E 0x733F #CJK UNIFIED IDEOGRAPH
+0x898F 0x7E01 #CJK UNIFIED IDEOGRAPH
+0x8990 0x8276 #CJK UNIFIED IDEOGRAPH
+0x8991 0x82D1 #CJK UNIFIED IDEOGRAPH
+0x8992 0x8597 #CJK UNIFIED IDEOGRAPH
+0x8993 0x9060 #CJK UNIFIED IDEOGRAPH
+0x8994 0x925B #CJK UNIFIED IDEOGRAPH
+0x8995 0x9D1B #CJK UNIFIED IDEOGRAPH
+0x8996 0x5869 #CJK UNIFIED IDEOGRAPH
+0x8997 0x65BC #CJK UNIFIED IDEOGRAPH
+0x8998 0x6C5A #CJK UNIFIED IDEOGRAPH
+0x8999 0x7525 #CJK UNIFIED IDEOGRAPH
+0x899A 0x51F9 #CJK UNIFIED IDEOGRAPH
+0x899B 0x592E #CJK UNIFIED IDEOGRAPH
+0x899C 0x5965 #CJK UNIFIED IDEOGRAPH
+0x899D 0x5F80 #CJK UNIFIED IDEOGRAPH
+0x899E 0x5FDC #CJK UNIFIED IDEOGRAPH
+0x899F 0x62BC #CJK UNIFIED IDEOGRAPH
+0x89A0 0x65FA #CJK UNIFIED IDEOGRAPH
+0x89A1 0x6A2A #CJK UNIFIED IDEOGRAPH
+0x89A2 0x6B27 #CJK UNIFIED IDEOGRAPH
+0x89A3 0x6BB4 #CJK UNIFIED IDEOGRAPH
+0x89A4 0x738B #CJK UNIFIED IDEOGRAPH
+0x89A5 0x7FC1 #CJK UNIFIED IDEOGRAPH
+0x89A6 0x8956 #CJK UNIFIED IDEOGRAPH
+0x89A7 0x9D2C #CJK UNIFIED IDEOGRAPH
+0x89A8 0x9D0E #CJK UNIFIED IDEOGRAPH
+0x89A9 0x9EC4 #CJK UNIFIED IDEOGRAPH
+0x89AA 0x5CA1 #CJK UNIFIED IDEOGRAPH
+0x89AB 0x6C96 #CJK UNIFIED IDEOGRAPH
+0x89AC 0x837B #CJK UNIFIED IDEOGRAPH
+0x89AD 0x5104 #CJK UNIFIED IDEOGRAPH
+0x89AE 0x5C4B #CJK UNIFIED IDEOGRAPH
+0x89AF 0x61B6 #CJK UNIFIED IDEOGRAPH
+0x89B0 0x81C6 #CJK UNIFIED IDEOGRAPH
+0x89B1 0x6876 #CJK UNIFIED IDEOGRAPH
+0x89B2 0x7261 #CJK UNIFIED IDEOGRAPH
+0x89B3 0x4E59 #CJK UNIFIED IDEOGRAPH
+0x89B4 0x4FFA #CJK UNIFIED IDEOGRAPH
+0x89B5 0x5378 #CJK UNIFIED IDEOGRAPH
+0x89B6 0x6069 #CJK UNIFIED IDEOGRAPH
+0x89B7 0x6E29 #CJK UNIFIED IDEOGRAPH
+0x89B8 0x7A4F #CJK UNIFIED IDEOGRAPH
+0x89B9 0x97F3 #CJK UNIFIED IDEOGRAPH
+0x89BA 0x4E0B #CJK UNIFIED IDEOGRAPH
+0x89BB 0x5316 #CJK UNIFIED IDEOGRAPH
+0x89BC 0x4EEE #CJK UNIFIED IDEOGRAPH
+0x89BD 0x4F55 #CJK UNIFIED IDEOGRAPH
+0x89BE 0x4F3D #CJK UNIFIED IDEOGRAPH
+0x89BF 0x4FA1 #CJK UNIFIED IDEOGRAPH
+0x89C0 0x4F73 #CJK UNIFIED IDEOGRAPH
+0x89C1 0x52A0 #CJK UNIFIED IDEOGRAPH
+0x89C2 0x53EF #CJK UNIFIED IDEOGRAPH
+0x89C3 0x5609 #CJK UNIFIED IDEOGRAPH
+0x89C4 0x590F #CJK UNIFIED IDEOGRAPH
+0x89C5 0x5AC1 #CJK UNIFIED IDEOGRAPH
+0x89C6 0x5BB6 #CJK UNIFIED IDEOGRAPH
+0x89C7 0x5BE1 #CJK UNIFIED IDEOGRAPH
+0x89C8 0x79D1 #CJK UNIFIED IDEOGRAPH
+0x89C9 0x6687 #CJK UNIFIED IDEOGRAPH
+0x89CA 0x679C #CJK UNIFIED IDEOGRAPH
+0x89CB 0x67B6 #CJK UNIFIED IDEOGRAPH
+0x89CC 0x6B4C #CJK UNIFIED IDEOGRAPH
+0x89CD 0x6CB3 #CJK UNIFIED IDEOGRAPH
+0x89CE 0x706B #CJK UNIFIED IDEOGRAPH
+0x89CF 0x73C2 #CJK UNIFIED IDEOGRAPH
+0x89D0 0x798D #CJK UNIFIED IDEOGRAPH
+0x89D1 0x79BE #CJK UNIFIED IDEOGRAPH
+0x89D2 0x7A3C #CJK UNIFIED IDEOGRAPH
+0x89D3 0x7B87 #CJK UNIFIED IDEOGRAPH
+0x89D4 0x82B1 #CJK UNIFIED IDEOGRAPH
+0x89D5 0x82DB #CJK UNIFIED IDEOGRAPH
+0x89D6 0x8304 #CJK UNIFIED IDEOGRAPH
+0x89D7 0x8377 #CJK UNIFIED IDEOGRAPH
+0x89D8 0x83EF #CJK UNIFIED IDEOGRAPH
+0x89D9 0x83D3 #CJK UNIFIED IDEOGRAPH
+0x89DA 0x8766 #CJK UNIFIED IDEOGRAPH
+0x89DB 0x8AB2 #CJK UNIFIED IDEOGRAPH
+0x89DC 0x5629 #CJK UNIFIED IDEOGRAPH
+0x89DD 0x8CA8 #CJK UNIFIED IDEOGRAPH
+0x89DE 0x8FE6 #CJK UNIFIED IDEOGRAPH
+0x89DF 0x904E #CJK UNIFIED IDEOGRAPH
+0x89E0 0x971E #CJK UNIFIED IDEOGRAPH
+0x89E1 0x868A #CJK UNIFIED IDEOGRAPH
+0x89E2 0x4FC4 #CJK UNIFIED IDEOGRAPH
+0x89E3 0x5CE8 #CJK UNIFIED IDEOGRAPH
+0x89E4 0x6211 #CJK UNIFIED IDEOGRAPH
+0x89E5 0x7259 #CJK UNIFIED IDEOGRAPH
+0x89E6 0x753B #CJK UNIFIED IDEOGRAPH
+0x89E7 0x81E5 #CJK UNIFIED IDEOGRAPH
+0x89E8 0x82BD #CJK UNIFIED IDEOGRAPH
+0x89E9 0x86FE #CJK UNIFIED IDEOGRAPH
+0x89EA 0x8CC0 #CJK UNIFIED IDEOGRAPH
+0x89EB 0x96C5 #CJK UNIFIED IDEOGRAPH
+0x89EC 0x9913 #CJK UNIFIED IDEOGRAPH
+0x89ED 0x99D5 #CJK UNIFIED IDEOGRAPH
+0x89EE 0x4ECB #CJK UNIFIED IDEOGRAPH
+0x89EF 0x4F1A #CJK UNIFIED IDEOGRAPH
+0x89F0 0x89E3 #CJK UNIFIED IDEOGRAPH
+0x89F1 0x56DE #CJK UNIFIED IDEOGRAPH
+0x89F2 0x584A #CJK UNIFIED IDEOGRAPH
+0x89F3 0x58CA #CJK UNIFIED IDEOGRAPH
+0x89F4 0x5EFB #CJK UNIFIED IDEOGRAPH
+0x89F5 0x5FEB #CJK UNIFIED IDEOGRAPH
+0x89F6 0x602A #CJK UNIFIED IDEOGRAPH
+0x89F7 0x6094 #CJK UNIFIED IDEOGRAPH
+0x89F8 0x6062 #CJK UNIFIED IDEOGRAPH
+0x89F9 0x61D0 #CJK UNIFIED IDEOGRAPH
+0x89FA 0x6212 #CJK UNIFIED IDEOGRAPH
+0x89FB 0x62D0 #CJK UNIFIED IDEOGRAPH
+0x89FC 0x6539 #CJK UNIFIED IDEOGRAPH
+0x8A40 0x9B41 #CJK UNIFIED IDEOGRAPH
+0x8A41 0x6666 #CJK UNIFIED IDEOGRAPH
+0x8A42 0x68B0 #CJK UNIFIED IDEOGRAPH
+0x8A43 0x6D77 #CJK UNIFIED IDEOGRAPH
+0x8A44 0x7070 #CJK UNIFIED IDEOGRAPH
+0x8A45 0x754C #CJK UNIFIED IDEOGRAPH
+0x8A46 0x7686 #CJK UNIFIED IDEOGRAPH
+0x8A47 0x7D75 #CJK UNIFIED IDEOGRAPH
+0x8A48 0x82A5 #CJK UNIFIED IDEOGRAPH
+0x8A49 0x87F9 #CJK UNIFIED IDEOGRAPH
+0x8A4A 0x958B #CJK UNIFIED IDEOGRAPH
+0x8A4B 0x968E #CJK UNIFIED IDEOGRAPH
+0x8A4C 0x8C9D #CJK UNIFIED IDEOGRAPH
+0x8A4D 0x51F1 #CJK UNIFIED IDEOGRAPH
+0x8A4E 0x52BE #CJK UNIFIED IDEOGRAPH
+0x8A4F 0x5916 #CJK UNIFIED IDEOGRAPH
+0x8A50 0x54B3 #CJK UNIFIED IDEOGRAPH
+0x8A51 0x5BB3 #CJK UNIFIED IDEOGRAPH
+0x8A52 0x5D16 #CJK UNIFIED IDEOGRAPH
+0x8A53 0x6168 #CJK UNIFIED IDEOGRAPH
+0x8A54 0x6982 #CJK UNIFIED IDEOGRAPH
+0x8A55 0x6DAF #CJK UNIFIED IDEOGRAPH
+0x8A56 0x788D #CJK UNIFIED IDEOGRAPH
+0x8A57 0x84CB #CJK UNIFIED IDEOGRAPH
+0x8A58 0x8857 #CJK UNIFIED IDEOGRAPH
+0x8A59 0x8A72 #CJK UNIFIED IDEOGRAPH
+0x8A5A 0x93A7 #CJK UNIFIED IDEOGRAPH
+0x8A5B 0x9AB8 #CJK UNIFIED IDEOGRAPH
+0x8A5C 0x6D6C #CJK UNIFIED IDEOGRAPH
+0x8A5D 0x99A8 #CJK UNIFIED IDEOGRAPH
+0x8A5E 0x86D9 #CJK UNIFIED IDEOGRAPH
+0x8A5F 0x57A3 #CJK UNIFIED IDEOGRAPH
+0x8A60 0x67FF #CJK UNIFIED IDEOGRAPH
+0x8A61 0x86CE #CJK UNIFIED IDEOGRAPH
+0x8A62 0x920E #CJK UNIFIED IDEOGRAPH
+0x8A63 0x5283 #CJK UNIFIED IDEOGRAPH
+0x8A64 0x5687 #CJK UNIFIED IDEOGRAPH
+0x8A65 0x5404 #CJK UNIFIED IDEOGRAPH
+0x8A66 0x5ED3 #CJK UNIFIED IDEOGRAPH
+0x8A67 0x62E1 #CJK UNIFIED IDEOGRAPH
+0x8A68 0x64B9 #CJK UNIFIED IDEOGRAPH
+0x8A69 0x683C #CJK UNIFIED IDEOGRAPH
+0x8A6A 0x6838 #CJK UNIFIED IDEOGRAPH
+0x8A6B 0x6BBB #CJK UNIFIED IDEOGRAPH
+0x8A6C 0x7372 #CJK UNIFIED IDEOGRAPH
+0x8A6D 0x78BA #CJK UNIFIED IDEOGRAPH
+0x8A6E 0x7A6B #CJK UNIFIED IDEOGRAPH
+0x8A6F 0x899A #CJK UNIFIED IDEOGRAPH
+0x8A70 0x89D2 #CJK UNIFIED IDEOGRAPH
+0x8A71 0x8D6B #CJK UNIFIED IDEOGRAPH
+0x8A72 0x8F03 #CJK UNIFIED IDEOGRAPH
+0x8A73 0x90ED #CJK UNIFIED IDEOGRAPH
+0x8A74 0x95A3 #CJK UNIFIED IDEOGRAPH
+0x8A75 0x9694 #CJK UNIFIED IDEOGRAPH
+0x8A76 0x9769 #CJK UNIFIED IDEOGRAPH
+0x8A77 0x5B66 #CJK UNIFIED IDEOGRAPH
+0x8A78 0x5CB3 #CJK UNIFIED IDEOGRAPH
+0x8A79 0x697D #CJK UNIFIED IDEOGRAPH
+0x8A7A 0x984D #CJK UNIFIED IDEOGRAPH
+0x8A7B 0x984E #CJK UNIFIED IDEOGRAPH
+0x8A7C 0x639B #CJK UNIFIED IDEOGRAPH
+0x8A7D 0x7B20 #CJK UNIFIED IDEOGRAPH
+0x8A7E 0x6A2B #CJK UNIFIED IDEOGRAPH
+0x8A80 0x6A7F #CJK UNIFIED IDEOGRAPH
+0x8A81 0x68B6 #CJK UNIFIED IDEOGRAPH
+0x8A82 0x9C0D #CJK UNIFIED IDEOGRAPH
+0x8A83 0x6F5F #CJK UNIFIED IDEOGRAPH
+0x8A84 0x5272 #CJK UNIFIED IDEOGRAPH
+0x8A85 0x559D #CJK UNIFIED IDEOGRAPH
+0x8A86 0x6070 #CJK UNIFIED IDEOGRAPH
+0x8A87 0x62EC #CJK UNIFIED IDEOGRAPH
+0x8A88 0x6D3B #CJK UNIFIED IDEOGRAPH
+0x8A89 0x6E07 #CJK UNIFIED IDEOGRAPH
+0x8A8A 0x6ED1 #CJK UNIFIED IDEOGRAPH
+0x8A8B 0x845B #CJK UNIFIED IDEOGRAPH
+0x8A8C 0x8910 #CJK UNIFIED IDEOGRAPH
+0x8A8D 0x8F44 #CJK UNIFIED IDEOGRAPH
+0x8A8E 0x4E14 #CJK UNIFIED IDEOGRAPH
+0x8A8F 0x9C39 #CJK UNIFIED IDEOGRAPH
+0x8A90 0x53F6 #CJK UNIFIED IDEOGRAPH
+0x8A91 0x691B #CJK UNIFIED IDEOGRAPH
+0x8A92 0x6A3A #CJK UNIFIED IDEOGRAPH
+0x8A93 0x9784 #CJK UNIFIED IDEOGRAPH
+0x8A94 0x682A #CJK UNIFIED IDEOGRAPH
+0x8A95 0x515C #CJK UNIFIED IDEOGRAPH
+0x8A96 0x7AC3 #CJK UNIFIED IDEOGRAPH
+0x8A97 0x84B2 #CJK UNIFIED IDEOGRAPH
+0x8A98 0x91DC #CJK UNIFIED IDEOGRAPH
+0x8A99 0x938C #CJK UNIFIED IDEOGRAPH
+0x8A9A 0x565B #CJK UNIFIED IDEOGRAPH
+0x8A9B 0x9D28 #CJK UNIFIED IDEOGRAPH
+0x8A9C 0x6822 #CJK UNIFIED IDEOGRAPH
+0x8A9D 0x8305 #CJK UNIFIED IDEOGRAPH
+0x8A9E 0x8431 #CJK UNIFIED IDEOGRAPH
+0x8A9F 0x7CA5 #CJK UNIFIED IDEOGRAPH
+0x8AA0 0x5208 #CJK UNIFIED IDEOGRAPH
+0x8AA1 0x82C5 #CJK UNIFIED IDEOGRAPH
+0x8AA2 0x74E6 #CJK UNIFIED IDEOGRAPH
+0x8AA3 0x4E7E #CJK UNIFIED IDEOGRAPH
+0x8AA4 0x4F83 #CJK UNIFIED IDEOGRAPH
+0x8AA5 0x51A0 #CJK UNIFIED IDEOGRAPH
+0x8AA6 0x5BD2 #CJK UNIFIED IDEOGRAPH
+0x8AA7 0x520A #CJK UNIFIED IDEOGRAPH
+0x8AA8 0x52D8 #CJK UNIFIED IDEOGRAPH
+0x8AA9 0x52E7 #CJK UNIFIED IDEOGRAPH
+0x8AAA 0x5DFB #CJK UNIFIED IDEOGRAPH
+0x8AAB 0x559A #CJK UNIFIED IDEOGRAPH
+0x8AAC 0x582A #CJK UNIFIED IDEOGRAPH
+0x8AAD 0x59E6 #CJK UNIFIED IDEOGRAPH
+0x8AAE 0x5B8C #CJK UNIFIED IDEOGRAPH
+0x8AAF 0x5B98 #CJK UNIFIED IDEOGRAPH
+0x8AB0 0x5BDB #CJK UNIFIED IDEOGRAPH
+0x8AB1 0x5E72 #CJK UNIFIED IDEOGRAPH
+0x8AB2 0x5E79 #CJK UNIFIED IDEOGRAPH
+0x8AB3 0x60A3 #CJK UNIFIED IDEOGRAPH
+0x8AB4 0x611F #CJK UNIFIED IDEOGRAPH
+0x8AB5 0x6163 #CJK UNIFIED IDEOGRAPH
+0x8AB6 0x61BE #CJK UNIFIED IDEOGRAPH
+0x8AB7 0x63DB #CJK UNIFIED IDEOGRAPH
+0x8AB8 0x6562 #CJK UNIFIED IDEOGRAPH
+0x8AB9 0x67D1 #CJK UNIFIED IDEOGRAPH
+0x8ABA 0x6853 #CJK UNIFIED IDEOGRAPH
+0x8ABB 0x68FA #CJK UNIFIED IDEOGRAPH
+0x8ABC 0x6B3E #CJK UNIFIED IDEOGRAPH
+0x8ABD 0x6B53 #CJK UNIFIED IDEOGRAPH
+0x8ABE 0x6C57 #CJK UNIFIED IDEOGRAPH
+0x8ABF 0x6F22 #CJK UNIFIED IDEOGRAPH
+0x8AC0 0x6F97 #CJK UNIFIED IDEOGRAPH
+0x8AC1 0x6F45 #CJK UNIFIED IDEOGRAPH
+0x8AC2 0x74B0 #CJK UNIFIED IDEOGRAPH
+0x8AC3 0x7518 #CJK UNIFIED IDEOGRAPH
+0x8AC4 0x76E3 #CJK UNIFIED IDEOGRAPH
+0x8AC5 0x770B #CJK UNIFIED IDEOGRAPH
+0x8AC6 0x7AFF #CJK UNIFIED IDEOGRAPH
+0x8AC7 0x7BA1 #CJK UNIFIED IDEOGRAPH
+0x8AC8 0x7C21 #CJK UNIFIED IDEOGRAPH
+0x8AC9 0x7DE9 #CJK UNIFIED IDEOGRAPH
+0x8ACA 0x7F36 #CJK UNIFIED IDEOGRAPH
+0x8ACB 0x7FF0 #CJK UNIFIED IDEOGRAPH
+0x8ACC 0x809D #CJK UNIFIED IDEOGRAPH
+0x8ACD 0x8266 #CJK UNIFIED IDEOGRAPH
+0x8ACE 0x839E #CJK UNIFIED IDEOGRAPH
+0x8ACF 0x89B3 #CJK UNIFIED IDEOGRAPH
+0x8AD0 0x8ACC #CJK UNIFIED IDEOGRAPH
+0x8AD1 0x8CAB #CJK UNIFIED IDEOGRAPH
+0x8AD2 0x9084 #CJK UNIFIED IDEOGRAPH
+0x8AD3 0x9451 #CJK UNIFIED IDEOGRAPH
+0x8AD4 0x9593 #CJK UNIFIED IDEOGRAPH
+0x8AD5 0x9591 #CJK UNIFIED IDEOGRAPH
+0x8AD6 0x95A2 #CJK UNIFIED IDEOGRAPH
+0x8AD7 0x9665 #CJK UNIFIED IDEOGRAPH
+0x8AD8 0x97D3 #CJK UNIFIED IDEOGRAPH
+0x8AD9 0x9928 #CJK UNIFIED IDEOGRAPH
+0x8ADA 0x8218 #CJK UNIFIED IDEOGRAPH
+0x8ADB 0x4E38 #CJK UNIFIED IDEOGRAPH
+0x8ADC 0x542B #CJK UNIFIED IDEOGRAPH
+0x8ADD 0x5CB8 #CJK UNIFIED IDEOGRAPH
+0x8ADE 0x5DCC #CJK UNIFIED IDEOGRAPH
+0x8ADF 0x73A9 #CJK UNIFIED IDEOGRAPH
+0x8AE0 0x764C #CJK UNIFIED IDEOGRAPH
+0x8AE1 0x773C #CJK UNIFIED IDEOGRAPH
+0x8AE2 0x5CA9 #CJK UNIFIED IDEOGRAPH
+0x8AE3 0x7FEB #CJK UNIFIED IDEOGRAPH
+0x8AE4 0x8D0B #CJK UNIFIED IDEOGRAPH
+0x8AE5 0x96C1 #CJK UNIFIED IDEOGRAPH
+0x8AE6 0x9811 #CJK UNIFIED IDEOGRAPH
+0x8AE7 0x9854 #CJK UNIFIED IDEOGRAPH
+0x8AE8 0x9858 #CJK UNIFIED IDEOGRAPH
+0x8AE9 0x4F01 #CJK UNIFIED IDEOGRAPH
+0x8AEA 0x4F0E #CJK UNIFIED IDEOGRAPH
+0x8AEB 0x5371 #CJK UNIFIED IDEOGRAPH
+0x8AEC 0x559C #CJK UNIFIED IDEOGRAPH
+0x8AED 0x5668 #CJK UNIFIED IDEOGRAPH
+0x8AEE 0x57FA #CJK UNIFIED IDEOGRAPH
+0x8AEF 0x5947 #CJK UNIFIED IDEOGRAPH
+0x8AF0 0x5B09 #CJK UNIFIED IDEOGRAPH
+0x8AF1 0x5BC4 #CJK UNIFIED IDEOGRAPH
+0x8AF2 0x5C90 #CJK UNIFIED IDEOGRAPH
+0x8AF3 0x5E0C #CJK UNIFIED IDEOGRAPH
+0x8AF4 0x5E7E #CJK UNIFIED IDEOGRAPH
+0x8AF5 0x5FCC #CJK UNIFIED IDEOGRAPH
+0x8AF6 0x63EE #CJK UNIFIED IDEOGRAPH
+0x8AF7 0x673A #CJK UNIFIED IDEOGRAPH
+0x8AF8 0x65D7 #CJK UNIFIED IDEOGRAPH
+0x8AF9 0x65E2 #CJK UNIFIED IDEOGRAPH
+0x8AFA 0x671F #CJK UNIFIED IDEOGRAPH
+0x8AFB 0x68CB #CJK UNIFIED IDEOGRAPH
+0x8AFC 0x68C4 #CJK UNIFIED IDEOGRAPH
+0x8B40 0x6A5F #CJK UNIFIED IDEOGRAPH
+0x8B41 0x5E30 #CJK UNIFIED IDEOGRAPH
+0x8B42 0x6BC5 #CJK UNIFIED IDEOGRAPH
+0x8B43 0x6C17 #CJK UNIFIED IDEOGRAPH
+0x8B44 0x6C7D #CJK UNIFIED IDEOGRAPH
+0x8B45 0x757F #CJK UNIFIED IDEOGRAPH
+0x8B46 0x7948 #CJK UNIFIED IDEOGRAPH
+0x8B47 0x5B63 #CJK UNIFIED IDEOGRAPH
+0x8B48 0x7A00 #CJK UNIFIED IDEOGRAPH
+0x8B49 0x7D00 #CJK UNIFIED IDEOGRAPH
+0x8B4A 0x5FBD #CJK UNIFIED IDEOGRAPH
+0x8B4B 0x898F #CJK UNIFIED IDEOGRAPH
+0x8B4C 0x8A18 #CJK UNIFIED IDEOGRAPH
+0x8B4D 0x8CB4 #CJK UNIFIED IDEOGRAPH
+0x8B4E 0x8D77 #CJK UNIFIED IDEOGRAPH
+0x8B4F 0x8ECC #CJK UNIFIED IDEOGRAPH
+0x8B50 0x8F1D #CJK UNIFIED IDEOGRAPH
+0x8B51 0x98E2 #CJK UNIFIED IDEOGRAPH
+0x8B52 0x9A0E #CJK UNIFIED IDEOGRAPH
+0x8B53 0x9B3C #CJK UNIFIED IDEOGRAPH
+0x8B54 0x4E80 #CJK UNIFIED IDEOGRAPH
+0x8B55 0x507D #CJK UNIFIED IDEOGRAPH
+0x8B56 0x5100 #CJK UNIFIED IDEOGRAPH
+0x8B57 0x5993 #CJK UNIFIED IDEOGRAPH
+0x8B58 0x5B9C #CJK UNIFIED IDEOGRAPH
+0x8B59 0x622F #CJK UNIFIED IDEOGRAPH
+0x8B5A 0x6280 #CJK UNIFIED IDEOGRAPH
+0x8B5B 0x64EC #CJK UNIFIED IDEOGRAPH
+0x8B5C 0x6B3A #CJK UNIFIED IDEOGRAPH
+0x8B5D 0x72A0 #CJK UNIFIED IDEOGRAPH
+0x8B5E 0x7591 #CJK UNIFIED IDEOGRAPH
+0x8B5F 0x7947 #CJK UNIFIED IDEOGRAPH
+0x8B60 0x7FA9 #CJK UNIFIED IDEOGRAPH
+0x8B61 0x87FB #CJK UNIFIED IDEOGRAPH
+0x8B62 0x8ABC #CJK UNIFIED IDEOGRAPH
+0x8B63 0x8B70 #CJK UNIFIED IDEOGRAPH
+0x8B64 0x63AC #CJK UNIFIED IDEOGRAPH
+0x8B65 0x83CA #CJK UNIFIED IDEOGRAPH
+0x8B66 0x97A0 #CJK UNIFIED IDEOGRAPH
+0x8B67 0x5409 #CJK UNIFIED IDEOGRAPH
+0x8B68 0x5403 #CJK UNIFIED IDEOGRAPH
+0x8B69 0x55AB #CJK UNIFIED IDEOGRAPH
+0x8B6A 0x6854 #CJK UNIFIED IDEOGRAPH
+0x8B6B 0x6A58 #CJK UNIFIED IDEOGRAPH
+0x8B6C 0x8A70 #CJK UNIFIED IDEOGRAPH
+0x8B6D 0x7827 #CJK UNIFIED IDEOGRAPH
+0x8B6E 0x6775 #CJK UNIFIED IDEOGRAPH
+0x8B6F 0x9ECD #CJK UNIFIED IDEOGRAPH
+0x8B70 0x5374 #CJK UNIFIED IDEOGRAPH
+0x8B71 0x5BA2 #CJK UNIFIED IDEOGRAPH
+0x8B72 0x811A #CJK UNIFIED IDEOGRAPH
+0x8B73 0x8650 #CJK UNIFIED IDEOGRAPH
+0x8B74 0x9006 #CJK UNIFIED IDEOGRAPH
+0x8B75 0x4E18 #CJK UNIFIED IDEOGRAPH
+0x8B76 0x4E45 #CJK UNIFIED IDEOGRAPH
+0x8B77 0x4EC7 #CJK UNIFIED IDEOGRAPH
+0x8B78 0x4F11 #CJK UNIFIED IDEOGRAPH
+0x8B79 0x53CA #CJK UNIFIED IDEOGRAPH
+0x8B7A 0x5438 #CJK UNIFIED IDEOGRAPH
+0x8B7B 0x5BAE #CJK UNIFIED IDEOGRAPH
+0x8B7C 0x5F13 #CJK UNIFIED IDEOGRAPH
+0x8B7D 0x6025 #CJK UNIFIED IDEOGRAPH
+0x8B7E 0x6551 #CJK UNIFIED IDEOGRAPH
+0x8B80 0x673D #CJK UNIFIED IDEOGRAPH
+0x8B81 0x6C42 #CJK UNIFIED IDEOGRAPH
+0x8B82 0x6C72 #CJK UNIFIED IDEOGRAPH
+0x8B83 0x6CE3 #CJK UNIFIED IDEOGRAPH
+0x8B84 0x7078 #CJK UNIFIED IDEOGRAPH
+0x8B85 0x7403 #CJK UNIFIED IDEOGRAPH
+0x8B86 0x7A76 #CJK UNIFIED IDEOGRAPH
+0x8B87 0x7AAE #CJK UNIFIED IDEOGRAPH
+0x8B88 0x7B08 #CJK UNIFIED IDEOGRAPH
+0x8B89 0x7D1A #CJK UNIFIED IDEOGRAPH
+0x8B8A 0x7CFE #CJK UNIFIED IDEOGRAPH
+0x8B8B 0x7D66 #CJK UNIFIED IDEOGRAPH
+0x8B8C 0x65E7 #CJK UNIFIED IDEOGRAPH
+0x8B8D 0x725B #CJK UNIFIED IDEOGRAPH
+0x8B8E 0x53BB #CJK UNIFIED IDEOGRAPH
+0x8B8F 0x5C45 #CJK UNIFIED IDEOGRAPH
+0x8B90 0x5DE8 #CJK UNIFIED IDEOGRAPH
+0x8B91 0x62D2 #CJK UNIFIED IDEOGRAPH
+0x8B92 0x62E0 #CJK UNIFIED IDEOGRAPH
+0x8B93 0x6319 #CJK UNIFIED IDEOGRAPH
+0x8B94 0x6E20 #CJK UNIFIED IDEOGRAPH
+0x8B95 0x865A #CJK UNIFIED IDEOGRAPH
+0x8B96 0x8A31 #CJK UNIFIED IDEOGRAPH
+0x8B97 0x8DDD #CJK UNIFIED IDEOGRAPH
+0x8B98 0x92F8 #CJK UNIFIED IDEOGRAPH
+0x8B99 0x6F01 #CJK UNIFIED IDEOGRAPH
+0x8B9A 0x79A6 #CJK UNIFIED IDEOGRAPH
+0x8B9B 0x9B5A #CJK UNIFIED IDEOGRAPH
+0x8B9C 0x4EA8 #CJK UNIFIED IDEOGRAPH
+0x8B9D 0x4EAB #CJK UNIFIED IDEOGRAPH
+0x8B9E 0x4EAC #CJK UNIFIED IDEOGRAPH
+0x8B9F 0x4F9B #CJK UNIFIED IDEOGRAPH
+0x8BA0 0x4FA0 #CJK UNIFIED IDEOGRAPH
+0x8BA1 0x50D1 #CJK UNIFIED IDEOGRAPH
+0x8BA2 0x5147 #CJK UNIFIED IDEOGRAPH
+0x8BA3 0x7AF6 #CJK UNIFIED IDEOGRAPH
+0x8BA4 0x5171 #CJK UNIFIED IDEOGRAPH
+0x8BA5 0x51F6 #CJK UNIFIED IDEOGRAPH
+0x8BA6 0x5354 #CJK UNIFIED IDEOGRAPH
+0x8BA7 0x5321 #CJK UNIFIED IDEOGRAPH
+0x8BA8 0x537F #CJK UNIFIED IDEOGRAPH
+0x8BA9 0x53EB #CJK UNIFIED IDEOGRAPH
+0x8BAA 0x55AC #CJK UNIFIED IDEOGRAPH
+0x8BAB 0x5883 #CJK UNIFIED IDEOGRAPH
+0x8BAC 0x5CE1 #CJK UNIFIED IDEOGRAPH
+0x8BAD 0x5F37 #CJK UNIFIED IDEOGRAPH
+0x8BAE 0x5F4A #CJK UNIFIED IDEOGRAPH
+0x8BAF 0x602F #CJK UNIFIED IDEOGRAPH
+0x8BB0 0x6050 #CJK UNIFIED IDEOGRAPH
+0x8BB1 0x606D #CJK UNIFIED IDEOGRAPH
+0x8BB2 0x631F #CJK UNIFIED IDEOGRAPH
+0x8BB3 0x6559 #CJK UNIFIED IDEOGRAPH
+0x8BB4 0x6A4B #CJK UNIFIED IDEOGRAPH
+0x8BB5 0x6CC1 #CJK UNIFIED IDEOGRAPH
+0x8BB6 0x72C2 #CJK UNIFIED IDEOGRAPH
+0x8BB7 0x72ED #CJK UNIFIED IDEOGRAPH
+0x8BB8 0x77EF #CJK UNIFIED IDEOGRAPH
+0x8BB9 0x80F8 #CJK UNIFIED IDEOGRAPH
+0x8BBA 0x8105 #CJK UNIFIED IDEOGRAPH
+0x8BBB 0x8208 #CJK UNIFIED IDEOGRAPH
+0x8BBC 0x854E #CJK UNIFIED IDEOGRAPH
+0x8BBD 0x90F7 #CJK UNIFIED IDEOGRAPH
+0x8BBE 0x93E1 #CJK UNIFIED IDEOGRAPH
+0x8BBF 0x97FF #CJK UNIFIED IDEOGRAPH
+0x8BC0 0x9957 #CJK UNIFIED IDEOGRAPH
+0x8BC1 0x9A5A #CJK UNIFIED IDEOGRAPH
+0x8BC2 0x4EF0 #CJK UNIFIED IDEOGRAPH
+0x8BC3 0x51DD #CJK UNIFIED IDEOGRAPH
+0x8BC4 0x5C2D #CJK UNIFIED IDEOGRAPH
+0x8BC5 0x6681 #CJK UNIFIED IDEOGRAPH
+0x8BC6 0x696D #CJK UNIFIED IDEOGRAPH
+0x8BC7 0x5C40 #CJK UNIFIED IDEOGRAPH
+0x8BC8 0x66F2 #CJK UNIFIED IDEOGRAPH
+0x8BC9 0x6975 #CJK UNIFIED IDEOGRAPH
+0x8BCA 0x7389 #CJK UNIFIED IDEOGRAPH
+0x8BCB 0x6850 #CJK UNIFIED IDEOGRAPH
+0x8BCC 0x7C81 #CJK UNIFIED IDEOGRAPH
+0x8BCD 0x50C5 #CJK UNIFIED IDEOGRAPH
+0x8BCE 0x52E4 #CJK UNIFIED IDEOGRAPH
+0x8BCF 0x5747 #CJK UNIFIED IDEOGRAPH
+0x8BD0 0x5DFE #CJK UNIFIED IDEOGRAPH
+0x8BD1 0x9326 #CJK UNIFIED IDEOGRAPH
+0x8BD2 0x65A4 #CJK UNIFIED IDEOGRAPH
+0x8BD3 0x6B23 #CJK UNIFIED IDEOGRAPH
+0x8BD4 0x6B3D #CJK UNIFIED IDEOGRAPH
+0x8BD5 0x7434 #CJK UNIFIED IDEOGRAPH
+0x8BD6 0x7981 #CJK UNIFIED IDEOGRAPH
+0x8BD7 0x79BD #CJK UNIFIED IDEOGRAPH
+0x8BD8 0x7B4B #CJK UNIFIED IDEOGRAPH
+0x8BD9 0x7DCA #CJK UNIFIED IDEOGRAPH
+0x8BDA 0x82B9 #CJK UNIFIED IDEOGRAPH
+0x8BDB 0x83CC #CJK UNIFIED IDEOGRAPH
+0x8BDC 0x887F #CJK UNIFIED IDEOGRAPH
+0x8BDD 0x895F #CJK UNIFIED IDEOGRAPH
+0x8BDE 0x8B39 #CJK UNIFIED IDEOGRAPH
+0x8BDF 0x8FD1 #CJK UNIFIED IDEOGRAPH
+0x8BE0 0x91D1 #CJK UNIFIED IDEOGRAPH
+0x8BE1 0x541F #CJK UNIFIED IDEOGRAPH
+0x8BE2 0x9280 #CJK UNIFIED IDEOGRAPH
+0x8BE3 0x4E5D #CJK UNIFIED IDEOGRAPH
+0x8BE4 0x5036 #CJK UNIFIED IDEOGRAPH
+0x8BE5 0x53E5 #CJK UNIFIED IDEOGRAPH
+0x8BE6 0x533A #CJK UNIFIED IDEOGRAPH
+0x8BE7 0x72D7 #CJK UNIFIED IDEOGRAPH
+0x8BE8 0x7396 #CJK UNIFIED IDEOGRAPH
+0x8BE9 0x77E9 #CJK UNIFIED IDEOGRAPH
+0x8BEA 0x82E6 #CJK UNIFIED IDEOGRAPH
+0x8BEB 0x8EAF #CJK UNIFIED IDEOGRAPH
+0x8BEC 0x99C6 #CJK UNIFIED IDEOGRAPH
+0x8BED 0x99C8 #CJK UNIFIED IDEOGRAPH
+0x8BEE 0x99D2 #CJK UNIFIED IDEOGRAPH
+0x8BEF 0x5177 #CJK UNIFIED IDEOGRAPH
+0x8BF0 0x611A #CJK UNIFIED IDEOGRAPH
+0x8BF1 0x865E #CJK UNIFIED IDEOGRAPH
+0x8BF2 0x55B0 #CJK UNIFIED IDEOGRAPH
+0x8BF3 0x7A7A #CJK UNIFIED IDEOGRAPH
+0x8BF4 0x5076 #CJK UNIFIED IDEOGRAPH
+0x8BF5 0x5BD3 #CJK UNIFIED IDEOGRAPH
+0x8BF6 0x9047 #CJK UNIFIED IDEOGRAPH
+0x8BF7 0x9685 #CJK UNIFIED IDEOGRAPH
+0x8BF8 0x4E32 #CJK UNIFIED IDEOGRAPH
+0x8BF9 0x6ADB #CJK UNIFIED IDEOGRAPH
+0x8BFA 0x91E7 #CJK UNIFIED IDEOGRAPH
+0x8BFB 0x5C51 #CJK UNIFIED IDEOGRAPH
+0x8BFC 0x5C48 #CJK UNIFIED IDEOGRAPH
+0x8C40 0x6398 #CJK UNIFIED IDEOGRAPH
+0x8C41 0x7A9F #CJK UNIFIED IDEOGRAPH
+0x8C42 0x6C93 #CJK UNIFIED IDEOGRAPH
+0x8C43 0x9774 #CJK UNIFIED IDEOGRAPH
+0x8C44 0x8F61 #CJK UNIFIED IDEOGRAPH
+0x8C45 0x7AAA #CJK UNIFIED IDEOGRAPH
+0x8C46 0x718A #CJK UNIFIED IDEOGRAPH
+0x8C47 0x9688 #CJK UNIFIED IDEOGRAPH
+0x8C48 0x7C82 #CJK UNIFIED IDEOGRAPH
+0x8C49 0x6817 #CJK UNIFIED IDEOGRAPH
+0x8C4A 0x7E70 #CJK UNIFIED IDEOGRAPH
+0x8C4B 0x6851 #CJK UNIFIED IDEOGRAPH
+0x8C4C 0x936C #CJK UNIFIED IDEOGRAPH
+0x8C4D 0x52F2 #CJK UNIFIED IDEOGRAPH
+0x8C4E 0x541B #CJK UNIFIED IDEOGRAPH
+0x8C4F 0x85AB #CJK UNIFIED IDEOGRAPH
+0x8C50 0x8A13 #CJK UNIFIED IDEOGRAPH
+0x8C51 0x7FA4 #CJK UNIFIED IDEOGRAPH
+0x8C52 0x8ECD #CJK UNIFIED IDEOGRAPH
+0x8C53 0x90E1 #CJK UNIFIED IDEOGRAPH
+0x8C54 0x5366 #CJK UNIFIED IDEOGRAPH
+0x8C55 0x8888 #CJK UNIFIED IDEOGRAPH
+0x8C56 0x7941 #CJK UNIFIED IDEOGRAPH
+0x8C57 0x4FC2 #CJK UNIFIED IDEOGRAPH
+0x8C58 0x50BE #CJK UNIFIED IDEOGRAPH
+0x8C59 0x5211 #CJK UNIFIED IDEOGRAPH
+0x8C5A 0x5144 #CJK UNIFIED IDEOGRAPH
+0x8C5B 0x5553 #CJK UNIFIED IDEOGRAPH
+0x8C5C 0x572D #CJK UNIFIED IDEOGRAPH
+0x8C5D 0x73EA #CJK UNIFIED IDEOGRAPH
+0x8C5E 0x578B #CJK UNIFIED IDEOGRAPH
+0x8C5F 0x5951 #CJK UNIFIED IDEOGRAPH
+0x8C60 0x5F62 #CJK UNIFIED IDEOGRAPH
+0x8C61 0x5F84 #CJK UNIFIED IDEOGRAPH
+0x8C62 0x6075 #CJK UNIFIED IDEOGRAPH
+0x8C63 0x6176 #CJK UNIFIED IDEOGRAPH
+0x8C64 0x6167 #CJK UNIFIED IDEOGRAPH
+0x8C65 0x61A9 #CJK UNIFIED IDEOGRAPH
+0x8C66 0x63B2 #CJK UNIFIED IDEOGRAPH
+0x8C67 0x643A #CJK UNIFIED IDEOGRAPH
+0x8C68 0x656C #CJK UNIFIED IDEOGRAPH
+0x8C69 0x666F #CJK UNIFIED IDEOGRAPH
+0x8C6A 0x6842 #CJK UNIFIED IDEOGRAPH
+0x8C6B 0x6E13 #CJK UNIFIED IDEOGRAPH
+0x8C6C 0x7566 #CJK UNIFIED IDEOGRAPH
+0x8C6D 0x7A3D #CJK UNIFIED IDEOGRAPH
+0x8C6E 0x7CFB #CJK UNIFIED IDEOGRAPH
+0x8C6F 0x7D4C #CJK UNIFIED IDEOGRAPH
+0x8C70 0x7D99 #CJK UNIFIED IDEOGRAPH
+0x8C71 0x7E4B #CJK UNIFIED IDEOGRAPH
+0x8C72 0x7F6B #CJK UNIFIED IDEOGRAPH
+0x8C73 0x830E #CJK UNIFIED IDEOGRAPH
+0x8C74 0x834A #CJK UNIFIED IDEOGRAPH
+0x8C75 0x86CD #CJK UNIFIED IDEOGRAPH
+0x8C76 0x8A08 #CJK UNIFIED IDEOGRAPH
+0x8C77 0x8A63 #CJK UNIFIED IDEOGRAPH
+0x8C78 0x8B66 #CJK UNIFIED IDEOGRAPH
+0x8C79 0x8EFD #CJK UNIFIED IDEOGRAPH
+0x8C7A 0x981A #CJK UNIFIED IDEOGRAPH
+0x8C7B 0x9D8F #CJK UNIFIED IDEOGRAPH
+0x8C7C 0x82B8 #CJK UNIFIED IDEOGRAPH
+0x8C7D 0x8FCE #CJK UNIFIED IDEOGRAPH
+0x8C7E 0x9BE8 #CJK UNIFIED IDEOGRAPH
+0x8C80 0x5287 #CJK UNIFIED IDEOGRAPH
+0x8C81 0x621F #CJK UNIFIED IDEOGRAPH
+0x8C82 0x6483 #CJK UNIFIED IDEOGRAPH
+0x8C83 0x6FC0 #CJK UNIFIED IDEOGRAPH
+0x8C84 0x9699 #CJK UNIFIED IDEOGRAPH
+0x8C85 0x6841 #CJK UNIFIED IDEOGRAPH
+0x8C86 0x5091 #CJK UNIFIED IDEOGRAPH
+0x8C87 0x6B20 #CJK UNIFIED IDEOGRAPH
+0x8C88 0x6C7A #CJK UNIFIED IDEOGRAPH
+0x8C89 0x6F54 #CJK UNIFIED IDEOGRAPH
+0x8C8A 0x7A74 #CJK UNIFIED IDEOGRAPH
+0x8C8B 0x7D50 #CJK UNIFIED IDEOGRAPH
+0x8C8C 0x8840 #CJK UNIFIED IDEOGRAPH
+0x8C8D 0x8A23 #CJK UNIFIED IDEOGRAPH
+0x8C8E 0x6708 #CJK UNIFIED IDEOGRAPH
+0x8C8F 0x4EF6 #CJK UNIFIED IDEOGRAPH
+0x8C90 0x5039 #CJK UNIFIED IDEOGRAPH
+0x8C91 0x5026 #CJK UNIFIED IDEOGRAPH
+0x8C92 0x5065 #CJK UNIFIED IDEOGRAPH
+0x8C93 0x517C #CJK UNIFIED IDEOGRAPH
+0x8C94 0x5238 #CJK UNIFIED IDEOGRAPH
+0x8C95 0x5263 #CJK UNIFIED IDEOGRAPH
+0x8C96 0x55A7 #CJK UNIFIED IDEOGRAPH
+0x8C97 0x570F #CJK UNIFIED IDEOGRAPH
+0x8C98 0x5805 #CJK UNIFIED IDEOGRAPH
+0x8C99 0x5ACC #CJK UNIFIED IDEOGRAPH
+0x8C9A 0x5EFA #CJK UNIFIED IDEOGRAPH
+0x8C9B 0x61B2 #CJK UNIFIED IDEOGRAPH
+0x8C9C 0x61F8 #CJK UNIFIED IDEOGRAPH
+0x8C9D 0x62F3 #CJK UNIFIED IDEOGRAPH
+0x8C9E 0x6372 #CJK UNIFIED IDEOGRAPH
+0x8C9F 0x691C #CJK UNIFIED IDEOGRAPH
+0x8CA0 0x6A29 #CJK UNIFIED IDEOGRAPH
+0x8CA1 0x727D #CJK UNIFIED IDEOGRAPH
+0x8CA2 0x72AC #CJK UNIFIED IDEOGRAPH
+0x8CA3 0x732E #CJK UNIFIED IDEOGRAPH
+0x8CA4 0x7814 #CJK UNIFIED IDEOGRAPH
+0x8CA5 0x786F #CJK UNIFIED IDEOGRAPH
+0x8CA6 0x7D79 #CJK UNIFIED IDEOGRAPH
+0x8CA7 0x770C #CJK UNIFIED IDEOGRAPH
+0x8CA8 0x80A9 #CJK UNIFIED IDEOGRAPH
+0x8CA9 0x898B #CJK UNIFIED IDEOGRAPH
+0x8CAA 0x8B19 #CJK UNIFIED IDEOGRAPH
+0x8CAB 0x8CE2 #CJK UNIFIED IDEOGRAPH
+0x8CAC 0x8ED2 #CJK UNIFIED IDEOGRAPH
+0x8CAD 0x9063 #CJK UNIFIED IDEOGRAPH
+0x8CAE 0x9375 #CJK UNIFIED IDEOGRAPH
+0x8CAF 0x967A #CJK UNIFIED IDEOGRAPH
+0x8CB0 0x9855 #CJK UNIFIED IDEOGRAPH
+0x8CB1 0x9A13 #CJK UNIFIED IDEOGRAPH
+0x8CB2 0x9E78 #CJK UNIFIED IDEOGRAPH
+0x8CB3 0x5143 #CJK UNIFIED IDEOGRAPH
+0x8CB4 0x539F #CJK UNIFIED IDEOGRAPH
+0x8CB5 0x53B3 #CJK UNIFIED IDEOGRAPH
+0x8CB6 0x5E7B #CJK UNIFIED IDEOGRAPH
+0x8CB7 0x5F26 #CJK UNIFIED IDEOGRAPH
+0x8CB8 0x6E1B #CJK UNIFIED IDEOGRAPH
+0x8CB9 0x6E90 #CJK UNIFIED IDEOGRAPH
+0x8CBA 0x7384 #CJK UNIFIED IDEOGRAPH
+0x8CBB 0x73FE #CJK UNIFIED IDEOGRAPH
+0x8CBC 0x7D43 #CJK UNIFIED IDEOGRAPH
+0x8CBD 0x8237 #CJK UNIFIED IDEOGRAPH
+0x8CBE 0x8A00 #CJK UNIFIED IDEOGRAPH
+0x8CBF 0x8AFA #CJK UNIFIED IDEOGRAPH
+0x8CC0 0x9650 #CJK UNIFIED IDEOGRAPH
+0x8CC1 0x4E4E #CJK UNIFIED IDEOGRAPH
+0x8CC2 0x500B #CJK UNIFIED IDEOGRAPH
+0x8CC3 0x53E4 #CJK UNIFIED IDEOGRAPH
+0x8CC4 0x547C #CJK UNIFIED IDEOGRAPH
+0x8CC5 0x56FA #CJK UNIFIED IDEOGRAPH
+0x8CC6 0x59D1 #CJK UNIFIED IDEOGRAPH
+0x8CC7 0x5B64 #CJK UNIFIED IDEOGRAPH
+0x8CC8 0x5DF1 #CJK UNIFIED IDEOGRAPH
+0x8CC9 0x5EAB #CJK UNIFIED IDEOGRAPH
+0x8CCA 0x5F27 #CJK UNIFIED IDEOGRAPH
+0x8CCB 0x6238 #CJK UNIFIED IDEOGRAPH
+0x8CCC 0x6545 #CJK UNIFIED IDEOGRAPH
+0x8CCD 0x67AF #CJK UNIFIED IDEOGRAPH
+0x8CCE 0x6E56 #CJK UNIFIED IDEOGRAPH
+0x8CCF 0x72D0 #CJK UNIFIED IDEOGRAPH
+0x8CD0 0x7CCA #CJK UNIFIED IDEOGRAPH
+0x8CD1 0x88B4 #CJK UNIFIED IDEOGRAPH
+0x8CD2 0x80A1 #CJK UNIFIED IDEOGRAPH
+0x8CD3 0x80E1 #CJK UNIFIED IDEOGRAPH
+0x8CD4 0x83F0 #CJK UNIFIED IDEOGRAPH
+0x8CD5 0x864E #CJK UNIFIED IDEOGRAPH
+0x8CD6 0x8A87 #CJK UNIFIED IDEOGRAPH
+0x8CD7 0x8DE8 #CJK UNIFIED IDEOGRAPH
+0x8CD8 0x9237 #CJK UNIFIED IDEOGRAPH
+0x8CD9 0x96C7 #CJK UNIFIED IDEOGRAPH
+0x8CDA 0x9867 #CJK UNIFIED IDEOGRAPH
+0x8CDB 0x9F13 #CJK UNIFIED IDEOGRAPH
+0x8CDC 0x4E94 #CJK UNIFIED IDEOGRAPH
+0x8CDD 0x4E92 #CJK UNIFIED IDEOGRAPH
+0x8CDE 0x4F0D #CJK UNIFIED IDEOGRAPH
+0x8CDF 0x5348 #CJK UNIFIED IDEOGRAPH
+0x8CE0 0x5449 #CJK UNIFIED IDEOGRAPH
+0x8CE1 0x543E #CJK UNIFIED IDEOGRAPH
+0x8CE2 0x5A2F #CJK UNIFIED IDEOGRAPH
+0x8CE3 0x5F8C #CJK UNIFIED IDEOGRAPH
+0x8CE4 0x5FA1 #CJK UNIFIED IDEOGRAPH
+0x8CE5 0x609F #CJK UNIFIED IDEOGRAPH
+0x8CE6 0x68A7 #CJK UNIFIED IDEOGRAPH
+0x8CE7 0x6A8E #CJK UNIFIED IDEOGRAPH
+0x8CE8 0x745A #CJK UNIFIED IDEOGRAPH
+0x8CE9 0x7881 #CJK UNIFIED IDEOGRAPH
+0x8CEA 0x8A9E #CJK UNIFIED IDEOGRAPH
+0x8CEB 0x8AA4 #CJK UNIFIED IDEOGRAPH
+0x8CEC 0x8B77 #CJK UNIFIED IDEOGRAPH
+0x8CED 0x9190 #CJK UNIFIED IDEOGRAPH
+0x8CEE 0x4E5E #CJK UNIFIED IDEOGRAPH
+0x8CEF 0x9BC9 #CJK UNIFIED IDEOGRAPH
+0x8CF0 0x4EA4 #CJK UNIFIED IDEOGRAPH
+0x8CF1 0x4F7C #CJK UNIFIED IDEOGRAPH
+0x8CF2 0x4FAF #CJK UNIFIED IDEOGRAPH
+0x8CF3 0x5019 #CJK UNIFIED IDEOGRAPH
+0x8CF4 0x5016 #CJK UNIFIED IDEOGRAPH
+0x8CF5 0x5149 #CJK UNIFIED IDEOGRAPH
+0x8CF6 0x516C #CJK UNIFIED IDEOGRAPH
+0x8CF7 0x529F #CJK UNIFIED IDEOGRAPH
+0x8CF8 0x52B9 #CJK UNIFIED IDEOGRAPH
+0x8CF9 0x52FE #CJK UNIFIED IDEOGRAPH
+0x8CFA 0x539A #CJK UNIFIED IDEOGRAPH
+0x8CFB 0x53E3 #CJK UNIFIED IDEOGRAPH
+0x8CFC 0x5411 #CJK UNIFIED IDEOGRAPH
+0x8D40 0x540E #CJK UNIFIED IDEOGRAPH
+0x8D41 0x5589 #CJK UNIFIED IDEOGRAPH
+0x8D42 0x5751 #CJK UNIFIED IDEOGRAPH
+0x8D43 0x57A2 #CJK UNIFIED IDEOGRAPH
+0x8D44 0x597D #CJK UNIFIED IDEOGRAPH
+0x8D45 0x5B54 #CJK UNIFIED IDEOGRAPH
+0x8D46 0x5B5D #CJK UNIFIED IDEOGRAPH
+0x8D47 0x5B8F #CJK UNIFIED IDEOGRAPH
+0x8D48 0x5DE5 #CJK UNIFIED IDEOGRAPH
+0x8D49 0x5DE7 #CJK UNIFIED IDEOGRAPH
+0x8D4A 0x5DF7 #CJK UNIFIED IDEOGRAPH
+0x8D4B 0x5E78 #CJK UNIFIED IDEOGRAPH
+0x8D4C 0x5E83 #CJK UNIFIED IDEOGRAPH
+0x8D4D 0x5E9A #CJK UNIFIED IDEOGRAPH
+0x8D4E 0x5EB7 #CJK UNIFIED IDEOGRAPH
+0x8D4F 0x5F18 #CJK UNIFIED IDEOGRAPH
+0x8D50 0x6052 #CJK UNIFIED IDEOGRAPH
+0x8D51 0x614C #CJK UNIFIED IDEOGRAPH
+0x8D52 0x6297 #CJK UNIFIED IDEOGRAPH
+0x8D53 0x62D8 #CJK UNIFIED IDEOGRAPH
+0x8D54 0x63A7 #CJK UNIFIED IDEOGRAPH
+0x8D55 0x653B #CJK UNIFIED IDEOGRAPH
+0x8D56 0x6602 #CJK UNIFIED IDEOGRAPH
+0x8D57 0x6643 #CJK UNIFIED IDEOGRAPH
+0x8D58 0x66F4 #CJK UNIFIED IDEOGRAPH
+0x8D59 0x676D #CJK UNIFIED IDEOGRAPH
+0x8D5A 0x6821 #CJK UNIFIED IDEOGRAPH
+0x8D5B 0x6897 #CJK UNIFIED IDEOGRAPH
+0x8D5C 0x69CB #CJK UNIFIED IDEOGRAPH
+0x8D5D 0x6C5F #CJK UNIFIED IDEOGRAPH
+0x8D5E 0x6D2A #CJK UNIFIED IDEOGRAPH
+0x8D5F 0x6D69 #CJK UNIFIED IDEOGRAPH
+0x8D60 0x6E2F #CJK UNIFIED IDEOGRAPH
+0x8D61 0x6E9D #CJK UNIFIED IDEOGRAPH
+0x8D62 0x7532 #CJK UNIFIED IDEOGRAPH
+0x8D63 0x7687 #CJK UNIFIED IDEOGRAPH
+0x8D64 0x786C #CJK UNIFIED IDEOGRAPH
+0x8D65 0x7A3F #CJK UNIFIED IDEOGRAPH
+0x8D66 0x7CE0 #CJK UNIFIED IDEOGRAPH
+0x8D67 0x7D05 #CJK UNIFIED IDEOGRAPH
+0x8D68 0x7D18 #CJK UNIFIED IDEOGRAPH
+0x8D69 0x7D5E #CJK UNIFIED IDEOGRAPH
+0x8D6A 0x7DB1 #CJK UNIFIED IDEOGRAPH
+0x8D6B 0x8015 #CJK UNIFIED IDEOGRAPH
+0x8D6C 0x8003 #CJK UNIFIED IDEOGRAPH
+0x8D6D 0x80AF #CJK UNIFIED IDEOGRAPH
+0x8D6E 0x80B1 #CJK UNIFIED IDEOGRAPH
+0x8D6F 0x8154 #CJK UNIFIED IDEOGRAPH
+0x8D70 0x818F #CJK UNIFIED IDEOGRAPH
+0x8D71 0x822A #CJK UNIFIED IDEOGRAPH
+0x8D72 0x8352 #CJK UNIFIED IDEOGRAPH
+0x8D73 0x884C #CJK UNIFIED IDEOGRAPH
+0x8D74 0x8861 #CJK UNIFIED IDEOGRAPH
+0x8D75 0x8B1B #CJK UNIFIED IDEOGRAPH
+0x8D76 0x8CA2 #CJK UNIFIED IDEOGRAPH
+0x8D77 0x8CFC #CJK UNIFIED IDEOGRAPH
+0x8D78 0x90CA #CJK UNIFIED IDEOGRAPH
+0x8D79 0x9175 #CJK UNIFIED IDEOGRAPH
+0x8D7A 0x9271 #CJK UNIFIED IDEOGRAPH
+0x8D7B 0x783F #CJK UNIFIED IDEOGRAPH
+0x8D7C 0x92FC #CJK UNIFIED IDEOGRAPH
+0x8D7D 0x95A4 #CJK UNIFIED IDEOGRAPH
+0x8D7E 0x964D #CJK UNIFIED IDEOGRAPH
+0x8D80 0x9805 #CJK UNIFIED IDEOGRAPH
+0x8D81 0x9999 #CJK UNIFIED IDEOGRAPH
+0x8D82 0x9AD8 #CJK UNIFIED IDEOGRAPH
+0x8D83 0x9D3B #CJK UNIFIED IDEOGRAPH
+0x8D84 0x525B #CJK UNIFIED IDEOGRAPH
+0x8D85 0x52AB #CJK UNIFIED IDEOGRAPH
+0x8D86 0x53F7 #CJK UNIFIED IDEOGRAPH
+0x8D87 0x5408 #CJK UNIFIED IDEOGRAPH
+0x8D88 0x58D5 #CJK UNIFIED IDEOGRAPH
+0x8D89 0x62F7 #CJK UNIFIED IDEOGRAPH
+0x8D8A 0x6FE0 #CJK UNIFIED IDEOGRAPH
+0x8D8B 0x8C6A #CJK UNIFIED IDEOGRAPH
+0x8D8C 0x8F5F #CJK UNIFIED IDEOGRAPH
+0x8D8D 0x9EB9 #CJK UNIFIED IDEOGRAPH
+0x8D8E 0x514B #CJK UNIFIED IDEOGRAPH
+0x8D8F 0x523B #CJK UNIFIED IDEOGRAPH
+0x8D90 0x544A #CJK UNIFIED IDEOGRAPH
+0x8D91 0x56FD #CJK UNIFIED IDEOGRAPH
+0x8D92 0x7A40 #CJK UNIFIED IDEOGRAPH
+0x8D93 0x9177 #CJK UNIFIED IDEOGRAPH
+0x8D94 0x9D60 #CJK UNIFIED IDEOGRAPH
+0x8D95 0x9ED2 #CJK UNIFIED IDEOGRAPH
+0x8D96 0x7344 #CJK UNIFIED IDEOGRAPH
+0x8D97 0x6F09 #CJK UNIFIED IDEOGRAPH
+0x8D98 0x8170 #CJK UNIFIED IDEOGRAPH
+0x8D99 0x7511 #CJK UNIFIED IDEOGRAPH
+0x8D9A 0x5FFD #CJK UNIFIED IDEOGRAPH
+0x8D9B 0x60DA #CJK UNIFIED IDEOGRAPH
+0x8D9C 0x9AA8 #CJK UNIFIED IDEOGRAPH
+0x8D9D 0x72DB #CJK UNIFIED IDEOGRAPH
+0x8D9E 0x8FBC #CJK UNIFIED IDEOGRAPH
+0x8D9F 0x6B64 #CJK UNIFIED IDEOGRAPH
+0x8DA0 0x9803 #CJK UNIFIED IDEOGRAPH
+0x8DA1 0x4ECA #CJK UNIFIED IDEOGRAPH
+0x8DA2 0x56F0 #CJK UNIFIED IDEOGRAPH
+0x8DA3 0x5764 #CJK UNIFIED IDEOGRAPH
+0x8DA4 0x58BE #CJK UNIFIED IDEOGRAPH
+0x8DA5 0x5A5A #CJK UNIFIED IDEOGRAPH
+0x8DA6 0x6068 #CJK UNIFIED IDEOGRAPH
+0x8DA7 0x61C7 #CJK UNIFIED IDEOGRAPH
+0x8DA8 0x660F #CJK UNIFIED IDEOGRAPH
+0x8DA9 0x6606 #CJK UNIFIED IDEOGRAPH
+0x8DAA 0x6839 #CJK UNIFIED IDEOGRAPH
+0x8DAB 0x68B1 #CJK UNIFIED IDEOGRAPH
+0x8DAC 0x6DF7 #CJK UNIFIED IDEOGRAPH
+0x8DAD 0x75D5 #CJK UNIFIED IDEOGRAPH
+0x8DAE 0x7D3A #CJK UNIFIED IDEOGRAPH
+0x8DAF 0x826E #CJK UNIFIED IDEOGRAPH
+0x8DB0 0x9B42 #CJK UNIFIED IDEOGRAPH
+0x8DB1 0x4E9B #CJK UNIFIED IDEOGRAPH
+0x8DB2 0x4F50 #CJK UNIFIED IDEOGRAPH
+0x8DB3 0x53C9 #CJK UNIFIED IDEOGRAPH
+0x8DB4 0x5506 #CJK UNIFIED IDEOGRAPH
+0x8DB5 0x5D6F #CJK UNIFIED IDEOGRAPH
+0x8DB6 0x5DE6 #CJK UNIFIED IDEOGRAPH
+0x8DB7 0x5DEE #CJK UNIFIED IDEOGRAPH
+0x8DB8 0x67FB #CJK UNIFIED IDEOGRAPH
+0x8DB9 0x6C99 #CJK UNIFIED IDEOGRAPH
+0x8DBA 0x7473 #CJK UNIFIED IDEOGRAPH
+0x8DBB 0x7802 #CJK UNIFIED IDEOGRAPH
+0x8DBC 0x8A50 #CJK UNIFIED IDEOGRAPH
+0x8DBD 0x9396 #CJK UNIFIED IDEOGRAPH
+0x8DBE 0x88DF #CJK UNIFIED IDEOGRAPH
+0x8DBF 0x5750 #CJK UNIFIED IDEOGRAPH
+0x8DC0 0x5EA7 #CJK UNIFIED IDEOGRAPH
+0x8DC1 0x632B #CJK UNIFIED IDEOGRAPH
+0x8DC2 0x50B5 #CJK UNIFIED IDEOGRAPH
+0x8DC3 0x50AC #CJK UNIFIED IDEOGRAPH
+0x8DC4 0x518D #CJK UNIFIED IDEOGRAPH
+0x8DC5 0x6700 #CJK UNIFIED IDEOGRAPH
+0x8DC6 0x54C9 #CJK UNIFIED IDEOGRAPH
+0x8DC7 0x585E #CJK UNIFIED IDEOGRAPH
+0x8DC8 0x59BB #CJK UNIFIED IDEOGRAPH
+0x8DC9 0x5BB0 #CJK UNIFIED IDEOGRAPH
+0x8DCA 0x5F69 #CJK UNIFIED IDEOGRAPH
+0x8DCB 0x624D #CJK UNIFIED IDEOGRAPH
+0x8DCC 0x63A1 #CJK UNIFIED IDEOGRAPH
+0x8DCD 0x683D #CJK UNIFIED IDEOGRAPH
+0x8DCE 0x6B73 #CJK UNIFIED IDEOGRAPH
+0x8DCF 0x6E08 #CJK UNIFIED IDEOGRAPH
+0x8DD0 0x707D #CJK UNIFIED IDEOGRAPH
+0x8DD1 0x91C7 #CJK UNIFIED IDEOGRAPH
+0x8DD2 0x7280 #CJK UNIFIED IDEOGRAPH
+0x8DD3 0x7815 #CJK UNIFIED IDEOGRAPH
+0x8DD4 0x7826 #CJK UNIFIED IDEOGRAPH
+0x8DD5 0x796D #CJK UNIFIED IDEOGRAPH
+0x8DD6 0x658E #CJK UNIFIED IDEOGRAPH
+0x8DD7 0x7D30 #CJK UNIFIED IDEOGRAPH
+0x8DD8 0x83DC #CJK UNIFIED IDEOGRAPH
+0x8DD9 0x88C1 #CJK UNIFIED IDEOGRAPH
+0x8DDA 0x8F09 #CJK UNIFIED IDEOGRAPH
+0x8DDB 0x969B #CJK UNIFIED IDEOGRAPH
+0x8DDC 0x5264 #CJK UNIFIED IDEOGRAPH
+0x8DDD 0x5728 #CJK UNIFIED IDEOGRAPH
+0x8DDE 0x6750 #CJK UNIFIED IDEOGRAPH
+0x8DDF 0x7F6A #CJK UNIFIED IDEOGRAPH
+0x8DE0 0x8CA1 #CJK UNIFIED IDEOGRAPH
+0x8DE1 0x51B4 #CJK UNIFIED IDEOGRAPH
+0x8DE2 0x5742 #CJK UNIFIED IDEOGRAPH
+0x8DE3 0x962A #CJK UNIFIED IDEOGRAPH
+0x8DE4 0x583A #CJK UNIFIED IDEOGRAPH
+0x8DE5 0x698A #CJK UNIFIED IDEOGRAPH
+0x8DE6 0x80B4 #CJK UNIFIED IDEOGRAPH
+0x8DE7 0x54B2 #CJK UNIFIED IDEOGRAPH
+0x8DE8 0x5D0E #CJK UNIFIED IDEOGRAPH
+0x8DE9 0x57FC #CJK UNIFIED IDEOGRAPH
+0x8DEA 0x7895 #CJK UNIFIED IDEOGRAPH
+0x8DEB 0x9DFA #CJK UNIFIED IDEOGRAPH
+0x8DEC 0x4F5C #CJK UNIFIED IDEOGRAPH
+0x8DED 0x524A #CJK UNIFIED IDEOGRAPH
+0x8DEE 0x548B #CJK UNIFIED IDEOGRAPH
+0x8DEF 0x643E #CJK UNIFIED IDEOGRAPH
+0x8DF0 0x6628 #CJK UNIFIED IDEOGRAPH
+0x8DF1 0x6714 #CJK UNIFIED IDEOGRAPH
+0x8DF2 0x67F5 #CJK UNIFIED IDEOGRAPH
+0x8DF3 0x7A84 #CJK UNIFIED IDEOGRAPH
+0x8DF4 0x7B56 #CJK UNIFIED IDEOGRAPH
+0x8DF5 0x7D22 #CJK UNIFIED IDEOGRAPH
+0x8DF6 0x932F #CJK UNIFIED IDEOGRAPH
+0x8DF7 0x685C #CJK UNIFIED IDEOGRAPH
+0x8DF8 0x9BAD #CJK UNIFIED IDEOGRAPH
+0x8DF9 0x7B39 #CJK UNIFIED IDEOGRAPH
+0x8DFA 0x5319 #CJK UNIFIED IDEOGRAPH
+0x8DFB 0x518A #CJK UNIFIED IDEOGRAPH
+0x8DFC 0x5237 #CJK UNIFIED IDEOGRAPH
+0x8E40 0x5BDF #CJK UNIFIED IDEOGRAPH
+0x8E41 0x62F6 #CJK UNIFIED IDEOGRAPH
+0x8E42 0x64AE #CJK UNIFIED IDEOGRAPH
+0x8E43 0x64E6 #CJK UNIFIED IDEOGRAPH
+0x8E44 0x672D #CJK UNIFIED IDEOGRAPH
+0x8E45 0x6BBA #CJK UNIFIED IDEOGRAPH
+0x8E46 0x85A9 #CJK UNIFIED IDEOGRAPH
+0x8E47 0x96D1 #CJK UNIFIED IDEOGRAPH
+0x8E48 0x7690 #CJK UNIFIED IDEOGRAPH
+0x8E49 0x9BD6 #CJK UNIFIED IDEOGRAPH
+0x8E4A 0x634C #CJK UNIFIED IDEOGRAPH
+0x8E4B 0x9306 #CJK UNIFIED IDEOGRAPH
+0x8E4C 0x9BAB #CJK UNIFIED IDEOGRAPH
+0x8E4D 0x76BF #CJK UNIFIED IDEOGRAPH
+0x8E4E 0x6652 #CJK UNIFIED IDEOGRAPH
+0x8E4F 0x4E09 #CJK UNIFIED IDEOGRAPH
+0x8E50 0x5098 #CJK UNIFIED IDEOGRAPH
+0x8E51 0x53C2 #CJK UNIFIED IDEOGRAPH
+0x8E52 0x5C71 #CJK UNIFIED IDEOGRAPH
+0x8E53 0x60E8 #CJK UNIFIED IDEOGRAPH
+0x8E54 0x6492 #CJK UNIFIED IDEOGRAPH
+0x8E55 0x6563 #CJK UNIFIED IDEOGRAPH
+0x8E56 0x685F #CJK UNIFIED IDEOGRAPH
+0x8E57 0x71E6 #CJK UNIFIED IDEOGRAPH
+0x8E58 0x73CA #CJK UNIFIED IDEOGRAPH
+0x8E59 0x7523 #CJK UNIFIED IDEOGRAPH
+0x8E5A 0x7B97 #CJK UNIFIED IDEOGRAPH
+0x8E5B 0x7E82 #CJK UNIFIED IDEOGRAPH
+0x8E5C 0x8695 #CJK UNIFIED IDEOGRAPH
+0x8E5D 0x8B83 #CJK UNIFIED IDEOGRAPH
+0x8E5E 0x8CDB #CJK UNIFIED IDEOGRAPH
+0x8E5F 0x9178 #CJK UNIFIED IDEOGRAPH
+0x8E60 0x9910 #CJK UNIFIED IDEOGRAPH
+0x8E61 0x65AC #CJK UNIFIED IDEOGRAPH
+0x8E62 0x66AB #CJK UNIFIED IDEOGRAPH
+0x8E63 0x6B8B #CJK UNIFIED IDEOGRAPH
+0x8E64 0x4ED5 #CJK UNIFIED IDEOGRAPH
+0x8E65 0x4ED4 #CJK UNIFIED IDEOGRAPH
+0x8E66 0x4F3A #CJK UNIFIED IDEOGRAPH
+0x8E67 0x4F7F #CJK UNIFIED IDEOGRAPH
+0x8E68 0x523A #CJK UNIFIED IDEOGRAPH
+0x8E69 0x53F8 #CJK UNIFIED IDEOGRAPH
+0x8E6A 0x53F2 #CJK UNIFIED IDEOGRAPH
+0x8E6B 0x55E3 #CJK UNIFIED IDEOGRAPH
+0x8E6C 0x56DB #CJK UNIFIED IDEOGRAPH
+0x8E6D 0x58EB #CJK UNIFIED IDEOGRAPH
+0x8E6E 0x59CB #CJK UNIFIED IDEOGRAPH
+0x8E6F 0x59C9 #CJK UNIFIED IDEOGRAPH
+0x8E70 0x59FF #CJK UNIFIED IDEOGRAPH
+0x8E71 0x5B50 #CJK UNIFIED IDEOGRAPH
+0x8E72 0x5C4D #CJK UNIFIED IDEOGRAPH
+0x8E73 0x5E02 #CJK UNIFIED IDEOGRAPH
+0x8E74 0x5E2B #CJK UNIFIED IDEOGRAPH
+0x8E75 0x5FD7 #CJK UNIFIED IDEOGRAPH
+0x8E76 0x601D #CJK UNIFIED IDEOGRAPH
+0x8E77 0x6307 #CJK UNIFIED IDEOGRAPH
+0x8E78 0x652F #CJK UNIFIED IDEOGRAPH
+0x8E79 0x5B5C #CJK UNIFIED IDEOGRAPH
+0x8E7A 0x65AF #CJK UNIFIED IDEOGRAPH
+0x8E7B 0x65BD #CJK UNIFIED IDEOGRAPH
+0x8E7C 0x65E8 #CJK UNIFIED IDEOGRAPH
+0x8E7D 0x679D #CJK UNIFIED IDEOGRAPH
+0x8E7E 0x6B62 #CJK UNIFIED IDEOGRAPH
+0x8E80 0x6B7B #CJK UNIFIED IDEOGRAPH
+0x8E81 0x6C0F #CJK UNIFIED IDEOGRAPH
+0x8E82 0x7345 #CJK UNIFIED IDEOGRAPH
+0x8E83 0x7949 #CJK UNIFIED IDEOGRAPH
+0x8E84 0x79C1 #CJK UNIFIED IDEOGRAPH
+0x8E85 0x7CF8 #CJK UNIFIED IDEOGRAPH
+0x8E86 0x7D19 #CJK UNIFIED IDEOGRAPH
+0x8E87 0x7D2B #CJK UNIFIED IDEOGRAPH
+0x8E88 0x80A2 #CJK UNIFIED IDEOGRAPH
+0x8E89 0x8102 #CJK UNIFIED IDEOGRAPH
+0x8E8A 0x81F3 #CJK UNIFIED IDEOGRAPH
+0x8E8B 0x8996 #CJK UNIFIED IDEOGRAPH
+0x8E8C 0x8A5E #CJK UNIFIED IDEOGRAPH
+0x8E8D 0x8A69 #CJK UNIFIED IDEOGRAPH
+0x8E8E 0x8A66 #CJK UNIFIED IDEOGRAPH
+0x8E8F 0x8A8C #CJK UNIFIED IDEOGRAPH
+0x8E90 0x8AEE #CJK UNIFIED IDEOGRAPH
+0x8E91 0x8CC7 #CJK UNIFIED IDEOGRAPH
+0x8E92 0x8CDC #CJK UNIFIED IDEOGRAPH
+0x8E93 0x96CC #CJK UNIFIED IDEOGRAPH
+0x8E94 0x98FC #CJK UNIFIED IDEOGRAPH
+0x8E95 0x6B6F #CJK UNIFIED IDEOGRAPH
+0x8E96 0x4E8B #CJK UNIFIED IDEOGRAPH
+0x8E97 0x4F3C #CJK UNIFIED IDEOGRAPH
+0x8E98 0x4F8D #CJK UNIFIED IDEOGRAPH
+0x8E99 0x5150 #CJK UNIFIED IDEOGRAPH
+0x8E9A 0x5B57 #CJK UNIFIED IDEOGRAPH
+0x8E9B 0x5BFA #CJK UNIFIED IDEOGRAPH
+0x8E9C 0x6148 #CJK UNIFIED IDEOGRAPH
+0x8E9D 0x6301 #CJK UNIFIED IDEOGRAPH
+0x8E9E 0x6642 #CJK UNIFIED IDEOGRAPH
+0x8E9F 0x6B21 #CJK UNIFIED IDEOGRAPH
+0x8EA0 0x6ECB #CJK UNIFIED IDEOGRAPH
+0x8EA1 0x6CBB #CJK UNIFIED IDEOGRAPH
+0x8EA2 0x723E #CJK UNIFIED IDEOGRAPH
+0x8EA3 0x74BD #CJK UNIFIED IDEOGRAPH
+0x8EA4 0x75D4 #CJK UNIFIED IDEOGRAPH
+0x8EA5 0x78C1 #CJK UNIFIED IDEOGRAPH
+0x8EA6 0x793A #CJK UNIFIED IDEOGRAPH
+0x8EA7 0x800C #CJK UNIFIED IDEOGRAPH
+0x8EA8 0x8033 #CJK UNIFIED IDEOGRAPH
+0x8EA9 0x81EA #CJK UNIFIED IDEOGRAPH
+0x8EAA 0x8494 #CJK UNIFIED IDEOGRAPH
+0x8EAB 0x8F9E #CJK UNIFIED IDEOGRAPH
+0x8EAC 0x6C50 #CJK UNIFIED IDEOGRAPH
+0x8EAD 0x9E7F #CJK UNIFIED IDEOGRAPH
+0x8EAE 0x5F0F #CJK UNIFIED IDEOGRAPH
+0x8EAF 0x8B58 #CJK UNIFIED IDEOGRAPH
+0x8EB0 0x9D2B #CJK UNIFIED IDEOGRAPH
+0x8EB1 0x7AFA #CJK UNIFIED IDEOGRAPH
+0x8EB2 0x8EF8 #CJK UNIFIED IDEOGRAPH
+0x8EB3 0x5B8D #CJK UNIFIED IDEOGRAPH
+0x8EB4 0x96EB #CJK UNIFIED IDEOGRAPH
+0x8EB5 0x4E03 #CJK UNIFIED IDEOGRAPH
+0x8EB6 0x53F1 #CJK UNIFIED IDEOGRAPH
+0x8EB7 0x57F7 #CJK UNIFIED IDEOGRAPH
+0x8EB8 0x5931 #CJK UNIFIED IDEOGRAPH
+0x8EB9 0x5AC9 #CJK UNIFIED IDEOGRAPH
+0x8EBA 0x5BA4 #CJK UNIFIED IDEOGRAPH
+0x8EBB 0x6089 #CJK UNIFIED IDEOGRAPH
+0x8EBC 0x6E7F #CJK UNIFIED IDEOGRAPH
+0x8EBD 0x6F06 #CJK UNIFIED IDEOGRAPH
+0x8EBE 0x75BE #CJK UNIFIED IDEOGRAPH
+0x8EBF 0x8CEA #CJK UNIFIED IDEOGRAPH
+0x8EC0 0x5B9F #CJK UNIFIED IDEOGRAPH
+0x8EC1 0x8500 #CJK UNIFIED IDEOGRAPH
+0x8EC2 0x7BE0 #CJK UNIFIED IDEOGRAPH
+0x8EC3 0x5072 #CJK UNIFIED IDEOGRAPH
+0x8EC4 0x67F4 #CJK UNIFIED IDEOGRAPH
+0x8EC5 0x829D #CJK UNIFIED IDEOGRAPH
+0x8EC6 0x5C61 #CJK UNIFIED IDEOGRAPH
+0x8EC7 0x854A #CJK UNIFIED IDEOGRAPH
+0x8EC8 0x7E1E #CJK UNIFIED IDEOGRAPH
+0x8EC9 0x820E #CJK UNIFIED IDEOGRAPH
+0x8ECA 0x5199 #CJK UNIFIED IDEOGRAPH
+0x8ECB 0x5C04 #CJK UNIFIED IDEOGRAPH
+0x8ECC 0x6368 #CJK UNIFIED IDEOGRAPH
+0x8ECD 0x8D66 #CJK UNIFIED IDEOGRAPH
+0x8ECE 0x659C #CJK UNIFIED IDEOGRAPH
+0x8ECF 0x716E #CJK UNIFIED IDEOGRAPH
+0x8ED0 0x793E #CJK UNIFIED IDEOGRAPH
+0x8ED1 0x7D17 #CJK UNIFIED IDEOGRAPH
+0x8ED2 0x8005 #CJK UNIFIED IDEOGRAPH
+0x8ED3 0x8B1D #CJK UNIFIED IDEOGRAPH
+0x8ED4 0x8ECA #CJK UNIFIED IDEOGRAPH
+0x8ED5 0x906E #CJK UNIFIED IDEOGRAPH
+0x8ED6 0x86C7 #CJK UNIFIED IDEOGRAPH
+0x8ED7 0x90AA #CJK UNIFIED IDEOGRAPH
+0x8ED8 0x501F #CJK UNIFIED IDEOGRAPH
+0x8ED9 0x52FA #CJK UNIFIED IDEOGRAPH
+0x8EDA 0x5C3A #CJK UNIFIED IDEOGRAPH
+0x8EDB 0x6753 #CJK UNIFIED IDEOGRAPH
+0x8EDC 0x707C #CJK UNIFIED IDEOGRAPH
+0x8EDD 0x7235 #CJK UNIFIED IDEOGRAPH
+0x8EDE 0x914C #CJK UNIFIED IDEOGRAPH
+0x8EDF 0x91C8 #CJK UNIFIED IDEOGRAPH
+0x8EE0 0x932B #CJK UNIFIED IDEOGRAPH
+0x8EE1 0x82E5 #CJK UNIFIED IDEOGRAPH
+0x8EE2 0x5BC2 #CJK UNIFIED IDEOGRAPH
+0x8EE3 0x5F31 #CJK UNIFIED IDEOGRAPH
+0x8EE4 0x60F9 #CJK UNIFIED IDEOGRAPH
+0x8EE5 0x4E3B #CJK UNIFIED IDEOGRAPH
+0x8EE6 0x53D6 #CJK UNIFIED IDEOGRAPH
+0x8EE7 0x5B88 #CJK UNIFIED IDEOGRAPH
+0x8EE8 0x624B #CJK UNIFIED IDEOGRAPH
+0x8EE9 0x6731 #CJK UNIFIED IDEOGRAPH
+0x8EEA 0x6B8A #CJK UNIFIED IDEOGRAPH
+0x8EEB 0x72E9 #CJK UNIFIED IDEOGRAPH
+0x8EEC 0x73E0 #CJK UNIFIED IDEOGRAPH
+0x8EED 0x7A2E #CJK UNIFIED IDEOGRAPH
+0x8EEE 0x816B #CJK UNIFIED IDEOGRAPH
+0x8EEF 0x8DA3 #CJK UNIFIED IDEOGRAPH
+0x8EF0 0x9152 #CJK UNIFIED IDEOGRAPH
+0x8EF1 0x9996 #CJK UNIFIED IDEOGRAPH
+0x8EF2 0x5112 #CJK UNIFIED IDEOGRAPH
+0x8EF3 0x53D7 #CJK UNIFIED IDEOGRAPH
+0x8EF4 0x546A #CJK UNIFIED IDEOGRAPH
+0x8EF5 0x5BFF #CJK UNIFIED IDEOGRAPH
+0x8EF6 0x6388 #CJK UNIFIED IDEOGRAPH
+0x8EF7 0x6A39 #CJK UNIFIED IDEOGRAPH
+0x8EF8 0x7DAC #CJK UNIFIED IDEOGRAPH
+0x8EF9 0x9700 #CJK UNIFIED IDEOGRAPH
+0x8EFA 0x56DA #CJK UNIFIED IDEOGRAPH
+0x8EFB 0x53CE #CJK UNIFIED IDEOGRAPH
+0x8EFC 0x5468 #CJK UNIFIED IDEOGRAPH
+0x8F40 0x5B97 #CJK UNIFIED IDEOGRAPH
+0x8F41 0x5C31 #CJK UNIFIED IDEOGRAPH
+0x8F42 0x5DDE #CJK UNIFIED IDEOGRAPH
+0x8F43 0x4FEE #CJK UNIFIED IDEOGRAPH
+0x8F44 0x6101 #CJK UNIFIED IDEOGRAPH
+0x8F45 0x62FE #CJK UNIFIED IDEOGRAPH
+0x8F46 0x6D32 #CJK UNIFIED IDEOGRAPH
+0x8F47 0x79C0 #CJK UNIFIED IDEOGRAPH
+0x8F48 0x79CB #CJK UNIFIED IDEOGRAPH
+0x8F49 0x7D42 #CJK UNIFIED IDEOGRAPH
+0x8F4A 0x7E4D #CJK UNIFIED IDEOGRAPH
+0x8F4B 0x7FD2 #CJK UNIFIED IDEOGRAPH
+0x8F4C 0x81ED #CJK UNIFIED IDEOGRAPH
+0x8F4D 0x821F #CJK UNIFIED IDEOGRAPH
+0x8F4E 0x8490 #CJK UNIFIED IDEOGRAPH
+0x8F4F 0x8846 #CJK UNIFIED IDEOGRAPH
+0x8F50 0x8972 #CJK UNIFIED IDEOGRAPH
+0x8F51 0x8B90 #CJK UNIFIED IDEOGRAPH
+0x8F52 0x8E74 #CJK UNIFIED IDEOGRAPH
+0x8F53 0x8F2F #CJK UNIFIED IDEOGRAPH
+0x8F54 0x9031 #CJK UNIFIED IDEOGRAPH
+0x8F55 0x914B #CJK UNIFIED IDEOGRAPH
+0x8F56 0x916C #CJK UNIFIED IDEOGRAPH
+0x8F57 0x96C6 #CJK UNIFIED IDEOGRAPH
+0x8F58 0x919C #CJK UNIFIED IDEOGRAPH
+0x8F59 0x4EC0 #CJK UNIFIED IDEOGRAPH
+0x8F5A 0x4F4F #CJK UNIFIED IDEOGRAPH
+0x8F5B 0x5145 #CJK UNIFIED IDEOGRAPH
+0x8F5C 0x5341 #CJK UNIFIED IDEOGRAPH
+0x8F5D 0x5F93 #CJK UNIFIED IDEOGRAPH
+0x8F5E 0x620E #CJK UNIFIED IDEOGRAPH
+0x8F5F 0x67D4 #CJK UNIFIED IDEOGRAPH
+0x8F60 0x6C41 #CJK UNIFIED IDEOGRAPH
+0x8F61 0x6E0B #CJK UNIFIED IDEOGRAPH
+0x8F62 0x7363 #CJK UNIFIED IDEOGRAPH
+0x8F63 0x7E26 #CJK UNIFIED IDEOGRAPH
+0x8F64 0x91CD #CJK UNIFIED IDEOGRAPH
+0x8F65 0x9283 #CJK UNIFIED IDEOGRAPH
+0x8F66 0x53D4 #CJK UNIFIED IDEOGRAPH
+0x8F67 0x5919 #CJK UNIFIED IDEOGRAPH
+0x8F68 0x5BBF #CJK UNIFIED IDEOGRAPH
+0x8F69 0x6DD1 #CJK UNIFIED IDEOGRAPH
+0x8F6A 0x795D #CJK UNIFIED IDEOGRAPH
+0x8F6B 0x7E2E #CJK UNIFIED IDEOGRAPH
+0x8F6C 0x7C9B #CJK UNIFIED IDEOGRAPH
+0x8F6D 0x587E #CJK UNIFIED IDEOGRAPH
+0x8F6E 0x719F #CJK UNIFIED IDEOGRAPH
+0x8F6F 0x51FA #CJK UNIFIED IDEOGRAPH
+0x8F70 0x8853 #CJK UNIFIED IDEOGRAPH
+0x8F71 0x8FF0 #CJK UNIFIED IDEOGRAPH
+0x8F72 0x4FCA #CJK UNIFIED IDEOGRAPH
+0x8F73 0x5CFB #CJK UNIFIED IDEOGRAPH
+0x8F74 0x6625 #CJK UNIFIED IDEOGRAPH
+0x8F75 0x77AC #CJK UNIFIED IDEOGRAPH
+0x8F76 0x7AE3 #CJK UNIFIED IDEOGRAPH
+0x8F77 0x821C #CJK UNIFIED IDEOGRAPH
+0x8F78 0x99FF #CJK UNIFIED IDEOGRAPH
+0x8F79 0x51C6 #CJK UNIFIED IDEOGRAPH
+0x8F7A 0x5FAA #CJK UNIFIED IDEOGRAPH
+0x8F7B 0x65EC #CJK UNIFIED IDEOGRAPH
+0x8F7C 0x696F #CJK UNIFIED IDEOGRAPH
+0x8F7D 0x6B89 #CJK UNIFIED IDEOGRAPH
+0x8F7E 0x6DF3 #CJK UNIFIED IDEOGRAPH
+0x8F80 0x6E96 #CJK UNIFIED IDEOGRAPH
+0x8F81 0x6F64 #CJK UNIFIED IDEOGRAPH
+0x8F82 0x76FE #CJK UNIFIED IDEOGRAPH
+0x8F83 0x7D14 #CJK UNIFIED IDEOGRAPH
+0x8F84 0x5DE1 #CJK UNIFIED IDEOGRAPH
+0x8F85 0x9075 #CJK UNIFIED IDEOGRAPH
+0x8F86 0x9187 #CJK UNIFIED IDEOGRAPH
+0x8F87 0x9806 #CJK UNIFIED IDEOGRAPH
+0x8F88 0x51E6 #CJK UNIFIED IDEOGRAPH
+0x8F89 0x521D #CJK UNIFIED IDEOGRAPH
+0x8F8A 0x6240 #CJK UNIFIED IDEOGRAPH
+0x8F8B 0x6691 #CJK UNIFIED IDEOGRAPH
+0x8F8C 0x66D9 #CJK UNIFIED IDEOGRAPH
+0x8F8D 0x6E1A #CJK UNIFIED IDEOGRAPH
+0x8F8E 0x5EB6 #CJK UNIFIED IDEOGRAPH
+0x8F8F 0x7DD2 #CJK UNIFIED IDEOGRAPH
+0x8F90 0x7F72 #CJK UNIFIED IDEOGRAPH
+0x8F91 0x66F8 #CJK UNIFIED IDEOGRAPH
+0x8F92 0x85AF #CJK UNIFIED IDEOGRAPH
+0x8F93 0x85F7 #CJK UNIFIED IDEOGRAPH
+0x8F94 0x8AF8 #CJK UNIFIED IDEOGRAPH
+0x8F95 0x52A9 #CJK UNIFIED IDEOGRAPH
+0x8F96 0x53D9 #CJK UNIFIED IDEOGRAPH
+0x8F97 0x5973 #CJK UNIFIED IDEOGRAPH
+0x8F98 0x5E8F #CJK UNIFIED IDEOGRAPH
+0x8F99 0x5F90 #CJK UNIFIED IDEOGRAPH
+0x8F9A 0x6055 #CJK UNIFIED IDEOGRAPH
+0x8F9B 0x92E4 #CJK UNIFIED IDEOGRAPH
+0x8F9C 0x9664 #CJK UNIFIED IDEOGRAPH
+0x8F9D 0x50B7 #CJK UNIFIED IDEOGRAPH
+0x8F9E 0x511F #CJK UNIFIED IDEOGRAPH
+0x8F9F 0x52DD #CJK UNIFIED IDEOGRAPH
+0x8FA0 0x5320 #CJK UNIFIED IDEOGRAPH
+0x8FA1 0x5347 #CJK UNIFIED IDEOGRAPH
+0x8FA2 0x53EC #CJK UNIFIED IDEOGRAPH
+0x8FA3 0x54E8 #CJK UNIFIED IDEOGRAPH
+0x8FA4 0x5546 #CJK UNIFIED IDEOGRAPH
+0x8FA5 0x5531 #CJK UNIFIED IDEOGRAPH
+0x8FA6 0x5617 #CJK UNIFIED IDEOGRAPH
+0x8FA7 0x5968 #CJK UNIFIED IDEOGRAPH
+0x8FA8 0x59BE #CJK UNIFIED IDEOGRAPH
+0x8FA9 0x5A3C #CJK UNIFIED IDEOGRAPH
+0x8FAA 0x5BB5 #CJK UNIFIED IDEOGRAPH
+0x8FAB 0x5C06 #CJK UNIFIED IDEOGRAPH
+0x8FAC 0x5C0F #CJK UNIFIED IDEOGRAPH
+0x8FAD 0x5C11 #CJK UNIFIED IDEOGRAPH
+0x8FAE 0x5C1A #CJK UNIFIED IDEOGRAPH
+0x8FAF 0x5E84 #CJK UNIFIED IDEOGRAPH
+0x8FB0 0x5E8A #CJK UNIFIED IDEOGRAPH
+0x8FB1 0x5EE0 #CJK UNIFIED IDEOGRAPH
+0x8FB2 0x5F70 #CJK UNIFIED IDEOGRAPH
+0x8FB3 0x627F #CJK UNIFIED IDEOGRAPH
+0x8FB4 0x6284 #CJK UNIFIED IDEOGRAPH
+0x8FB5 0x62DB #CJK UNIFIED IDEOGRAPH
+0x8FB6 0x638C #CJK UNIFIED IDEOGRAPH
+0x8FB7 0x6377 #CJK UNIFIED IDEOGRAPH
+0x8FB8 0x6607 #CJK UNIFIED IDEOGRAPH
+0x8FB9 0x660C #CJK UNIFIED IDEOGRAPH
+0x8FBA 0x662D #CJK UNIFIED IDEOGRAPH
+0x8FBB 0x6676 #CJK UNIFIED IDEOGRAPH
+0x8FBC 0x677E #CJK UNIFIED IDEOGRAPH
+0x8FBD 0x68A2 #CJK UNIFIED IDEOGRAPH
+0x8FBE 0x6A1F #CJK UNIFIED IDEOGRAPH
+0x8FBF 0x6A35 #CJK UNIFIED IDEOGRAPH
+0x8FC0 0x6CBC #CJK UNIFIED IDEOGRAPH
+0x8FC1 0x6D88 #CJK UNIFIED IDEOGRAPH
+0x8FC2 0x6E09 #CJK UNIFIED IDEOGRAPH
+0x8FC3 0x6E58 #CJK UNIFIED IDEOGRAPH
+0x8FC4 0x713C #CJK UNIFIED IDEOGRAPH
+0x8FC5 0x7126 #CJK UNIFIED IDEOGRAPH
+0x8FC6 0x7167 #CJK UNIFIED IDEOGRAPH
+0x8FC7 0x75C7 #CJK UNIFIED IDEOGRAPH
+0x8FC8 0x7701 #CJK UNIFIED IDEOGRAPH
+0x8FC9 0x785D #CJK UNIFIED IDEOGRAPH
+0x8FCA 0x7901 #CJK UNIFIED IDEOGRAPH
+0x8FCB 0x7965 #CJK UNIFIED IDEOGRAPH
+0x8FCC 0x79F0 #CJK UNIFIED IDEOGRAPH
+0x8FCD 0x7AE0 #CJK UNIFIED IDEOGRAPH
+0x8FCE 0x7B11 #CJK UNIFIED IDEOGRAPH
+0x8FCF 0x7CA7 #CJK UNIFIED IDEOGRAPH
+0x8FD0 0x7D39 #CJK UNIFIED IDEOGRAPH
+0x8FD1 0x8096 #CJK UNIFIED IDEOGRAPH
+0x8FD2 0x83D6 #CJK UNIFIED IDEOGRAPH
+0x8FD3 0x848B #CJK UNIFIED IDEOGRAPH
+0x8FD4 0x8549 #CJK UNIFIED IDEOGRAPH
+0x8FD5 0x885D #CJK UNIFIED IDEOGRAPH
+0x8FD6 0x88F3 #CJK UNIFIED IDEOGRAPH
+0x8FD7 0x8A1F #CJK UNIFIED IDEOGRAPH
+0x8FD8 0x8A3C #CJK UNIFIED IDEOGRAPH
+0x8FD9 0x8A54 #CJK UNIFIED IDEOGRAPH
+0x8FDA 0x8A73 #CJK UNIFIED IDEOGRAPH
+0x8FDB 0x8C61 #CJK UNIFIED IDEOGRAPH
+0x8FDC 0x8CDE #CJK UNIFIED IDEOGRAPH
+0x8FDD 0x91A4 #CJK UNIFIED IDEOGRAPH
+0x8FDE 0x9266 #CJK UNIFIED IDEOGRAPH
+0x8FDF 0x937E #CJK UNIFIED IDEOGRAPH
+0x8FE0 0x9418 #CJK UNIFIED IDEOGRAPH
+0x8FE1 0x969C #CJK UNIFIED IDEOGRAPH
+0x8FE2 0x9798 #CJK UNIFIED IDEOGRAPH
+0x8FE3 0x4E0A #CJK UNIFIED IDEOGRAPH
+0x8FE4 0x4E08 #CJK UNIFIED IDEOGRAPH
+0x8FE5 0x4E1E #CJK UNIFIED IDEOGRAPH
+0x8FE6 0x4E57 #CJK UNIFIED IDEOGRAPH
+0x8FE7 0x5197 #CJK UNIFIED IDEOGRAPH
+0x8FE8 0x5270 #CJK UNIFIED IDEOGRAPH
+0x8FE9 0x57CE #CJK UNIFIED IDEOGRAPH
+0x8FEA 0x5834 #CJK UNIFIED IDEOGRAPH
+0x8FEB 0x58CC #CJK UNIFIED IDEOGRAPH
+0x8FEC 0x5B22 #CJK UNIFIED IDEOGRAPH
+0x8FED 0x5E38 #CJK UNIFIED IDEOGRAPH
+0x8FEE 0x60C5 #CJK UNIFIED IDEOGRAPH
+0x8FEF 0x64FE #CJK UNIFIED IDEOGRAPH
+0x8FF0 0x6761 #CJK UNIFIED IDEOGRAPH
+0x8FF1 0x6756 #CJK UNIFIED IDEOGRAPH
+0x8FF2 0x6D44 #CJK UNIFIED IDEOGRAPH
+0x8FF3 0x72B6 #CJK UNIFIED IDEOGRAPH
+0x8FF4 0x7573 #CJK UNIFIED IDEOGRAPH
+0x8FF5 0x7A63 #CJK UNIFIED IDEOGRAPH
+0x8FF6 0x84B8 #CJK UNIFIED IDEOGRAPH
+0x8FF7 0x8B72 #CJK UNIFIED IDEOGRAPH
+0x8FF8 0x91B8 #CJK UNIFIED IDEOGRAPH
+0x8FF9 0x9320 #CJK UNIFIED IDEOGRAPH
+0x8FFA 0x5631 #CJK UNIFIED IDEOGRAPH
+0x8FFB 0x57F4 #CJK UNIFIED IDEOGRAPH
+0x8FFC 0x98FE #CJK UNIFIED IDEOGRAPH
+0x9040 0x62ED #CJK UNIFIED IDEOGRAPH
+0x9041 0x690D #CJK UNIFIED IDEOGRAPH
+0x9042 0x6B96 #CJK UNIFIED IDEOGRAPH
+0x9043 0x71ED #CJK UNIFIED IDEOGRAPH
+0x9044 0x7E54 #CJK UNIFIED IDEOGRAPH
+0x9045 0x8077 #CJK UNIFIED IDEOGRAPH
+0x9046 0x8272 #CJK UNIFIED IDEOGRAPH
+0x9047 0x89E6 #CJK UNIFIED IDEOGRAPH
+0x9048 0x98DF #CJK UNIFIED IDEOGRAPH
+0x9049 0x8755 #CJK UNIFIED IDEOGRAPH
+0x904A 0x8FB1 #CJK UNIFIED IDEOGRAPH
+0x904B 0x5C3B #CJK UNIFIED IDEOGRAPH
+0x904C 0x4F38 #CJK UNIFIED IDEOGRAPH
+0x904D 0x4FE1 #CJK UNIFIED IDEOGRAPH
+0x904E 0x4FB5 #CJK UNIFIED IDEOGRAPH
+0x904F 0x5507 #CJK UNIFIED IDEOGRAPH
+0x9050 0x5A20 #CJK UNIFIED IDEOGRAPH
+0x9051 0x5BDD #CJK UNIFIED IDEOGRAPH
+0x9052 0x5BE9 #CJK UNIFIED IDEOGRAPH
+0x9053 0x5FC3 #CJK UNIFIED IDEOGRAPH
+0x9054 0x614E #CJK UNIFIED IDEOGRAPH
+0x9055 0x632F #CJK UNIFIED IDEOGRAPH
+0x9056 0x65B0 #CJK UNIFIED IDEOGRAPH
+0x9057 0x664B #CJK UNIFIED IDEOGRAPH
+0x9058 0x68EE #CJK UNIFIED IDEOGRAPH
+0x9059 0x699B #CJK UNIFIED IDEOGRAPH
+0x905A 0x6D78 #CJK UNIFIED IDEOGRAPH
+0x905B 0x6DF1 #CJK UNIFIED IDEOGRAPH
+0x905C 0x7533 #CJK UNIFIED IDEOGRAPH
+0x905D 0x75B9 #CJK UNIFIED IDEOGRAPH
+0x905E 0x771F #CJK UNIFIED IDEOGRAPH
+0x905F 0x795E #CJK UNIFIED IDEOGRAPH
+0x9060 0x79E6 #CJK UNIFIED IDEOGRAPH
+0x9061 0x7D33 #CJK UNIFIED IDEOGRAPH
+0x9062 0x81E3 #CJK UNIFIED IDEOGRAPH
+0x9063 0x82AF #CJK UNIFIED IDEOGRAPH
+0x9064 0x85AA #CJK UNIFIED IDEOGRAPH
+0x9065 0x89AA #CJK UNIFIED IDEOGRAPH
+0x9066 0x8A3A #CJK UNIFIED IDEOGRAPH
+0x9067 0x8EAB #CJK UNIFIED IDEOGRAPH
+0x9068 0x8F9B #CJK UNIFIED IDEOGRAPH
+0x9069 0x9032 #CJK UNIFIED IDEOGRAPH
+0x906A 0x91DD #CJK UNIFIED IDEOGRAPH
+0x906B 0x9707 #CJK UNIFIED IDEOGRAPH
+0x906C 0x4EBA #CJK UNIFIED IDEOGRAPH
+0x906D 0x4EC1 #CJK UNIFIED IDEOGRAPH
+0x906E 0x5203 #CJK UNIFIED IDEOGRAPH
+0x906F 0x5875 #CJK UNIFIED IDEOGRAPH
+0x9070 0x58EC #CJK UNIFIED IDEOGRAPH
+0x9071 0x5C0B #CJK UNIFIED IDEOGRAPH
+0x9072 0x751A #CJK UNIFIED IDEOGRAPH
+0x9073 0x5C3D #CJK UNIFIED IDEOGRAPH
+0x9074 0x814E #CJK UNIFIED IDEOGRAPH
+0x9075 0x8A0A #CJK UNIFIED IDEOGRAPH
+0x9076 0x8FC5 #CJK UNIFIED IDEOGRAPH
+0x9077 0x9663 #CJK UNIFIED IDEOGRAPH
+0x9078 0x976D #CJK UNIFIED IDEOGRAPH
+0x9079 0x7B25 #CJK UNIFIED IDEOGRAPH
+0x907A 0x8ACF #CJK UNIFIED IDEOGRAPH
+0x907B 0x9808 #CJK UNIFIED IDEOGRAPH
+0x907C 0x9162 #CJK UNIFIED IDEOGRAPH
+0x907D 0x56F3 #CJK UNIFIED IDEOGRAPH
+0x907E 0x53A8 #CJK UNIFIED IDEOGRAPH
+0x9080 0x9017 #CJK UNIFIED IDEOGRAPH
+0x9081 0x5439 #CJK UNIFIED IDEOGRAPH
+0x9082 0x5782 #CJK UNIFIED IDEOGRAPH
+0x9083 0x5E25 #CJK UNIFIED IDEOGRAPH
+0x9084 0x63A8 #CJK UNIFIED IDEOGRAPH
+0x9085 0x6C34 #CJK UNIFIED IDEOGRAPH
+0x9086 0x708A #CJK UNIFIED IDEOGRAPH
+0x9087 0x7761 #CJK UNIFIED IDEOGRAPH
+0x9088 0x7C8B #CJK UNIFIED IDEOGRAPH
+0x9089 0x7FE0 #CJK UNIFIED IDEOGRAPH
+0x908A 0x8870 #CJK UNIFIED IDEOGRAPH
+0x908B 0x9042 #CJK UNIFIED IDEOGRAPH
+0x908C 0x9154 #CJK UNIFIED IDEOGRAPH
+0x908D 0x9310 #CJK UNIFIED IDEOGRAPH
+0x908E 0x9318 #CJK UNIFIED IDEOGRAPH
+0x908F 0x968F #CJK UNIFIED IDEOGRAPH
+0x9090 0x745E #CJK UNIFIED IDEOGRAPH
+0x9091 0x9AC4 #CJK UNIFIED IDEOGRAPH
+0x9092 0x5D07 #CJK UNIFIED IDEOGRAPH
+0x9093 0x5D69 #CJK UNIFIED IDEOGRAPH
+0x9094 0x6570 #CJK UNIFIED IDEOGRAPH
+0x9095 0x67A2 #CJK UNIFIED IDEOGRAPH
+0x9096 0x8DA8 #CJK UNIFIED IDEOGRAPH
+0x9097 0x96DB #CJK UNIFIED IDEOGRAPH
+0x9098 0x636E #CJK UNIFIED IDEOGRAPH
+0x9099 0x6749 #CJK UNIFIED IDEOGRAPH
+0x909A 0x6919 #CJK UNIFIED IDEOGRAPH
+0x909B 0x83C5 #CJK UNIFIED IDEOGRAPH
+0x909C 0x9817 #CJK UNIFIED IDEOGRAPH
+0x909D 0x96C0 #CJK UNIFIED IDEOGRAPH
+0x909E 0x88FE #CJK UNIFIED IDEOGRAPH
+0x909F 0x6F84 #CJK UNIFIED IDEOGRAPH
+0x90A0 0x647A #CJK UNIFIED IDEOGRAPH
+0x90A1 0x5BF8 #CJK UNIFIED IDEOGRAPH
+0x90A2 0x4E16 #CJK UNIFIED IDEOGRAPH
+0x90A3 0x702C #CJK UNIFIED IDEOGRAPH
+0x90A4 0x755D #CJK UNIFIED IDEOGRAPH
+0x90A5 0x662F #CJK UNIFIED IDEOGRAPH
+0x90A6 0x51C4 #CJK UNIFIED IDEOGRAPH
+0x90A7 0x5236 #CJK UNIFIED IDEOGRAPH
+0x90A8 0x52E2 #CJK UNIFIED IDEOGRAPH
+0x90A9 0x59D3 #CJK UNIFIED IDEOGRAPH
+0x90AA 0x5F81 #CJK UNIFIED IDEOGRAPH
+0x90AB 0x6027 #CJK UNIFIED IDEOGRAPH
+0x90AC 0x6210 #CJK UNIFIED IDEOGRAPH
+0x90AD 0x653F #CJK UNIFIED IDEOGRAPH
+0x90AE 0x6574 #CJK UNIFIED IDEOGRAPH
+0x90AF 0x661F #CJK UNIFIED IDEOGRAPH
+0x90B0 0x6674 #CJK UNIFIED IDEOGRAPH
+0x90B1 0x68F2 #CJK UNIFIED IDEOGRAPH
+0x90B2 0x6816 #CJK UNIFIED IDEOGRAPH
+0x90B3 0x6B63 #CJK UNIFIED IDEOGRAPH
+0x90B4 0x6E05 #CJK UNIFIED IDEOGRAPH
+0x90B5 0x7272 #CJK UNIFIED IDEOGRAPH
+0x90B6 0x751F #CJK UNIFIED IDEOGRAPH
+0x90B7 0x76DB #CJK UNIFIED IDEOGRAPH
+0x90B8 0x7CBE #CJK UNIFIED IDEOGRAPH
+0x90B9 0x8056 #CJK UNIFIED IDEOGRAPH
+0x90BA 0x58F0 #CJK UNIFIED IDEOGRAPH
+0x90BB 0x88FD #CJK UNIFIED IDEOGRAPH
+0x90BC 0x897F #CJK UNIFIED IDEOGRAPH
+0x90BD 0x8AA0 #CJK UNIFIED IDEOGRAPH
+0x90BE 0x8A93 #CJK UNIFIED IDEOGRAPH
+0x90BF 0x8ACB #CJK UNIFIED IDEOGRAPH
+0x90C0 0x901D #CJK UNIFIED IDEOGRAPH
+0x90C1 0x9192 #CJK UNIFIED IDEOGRAPH
+0x90C2 0x9752 #CJK UNIFIED IDEOGRAPH
+0x90C3 0x9759 #CJK UNIFIED IDEOGRAPH
+0x90C4 0x6589 #CJK UNIFIED IDEOGRAPH
+0x90C5 0x7A0E #CJK UNIFIED IDEOGRAPH
+0x90C6 0x8106 #CJK UNIFIED IDEOGRAPH
+0x90C7 0x96BB #CJK UNIFIED IDEOGRAPH
+0x90C8 0x5E2D #CJK UNIFIED IDEOGRAPH
+0x90C9 0x60DC #CJK UNIFIED IDEOGRAPH
+0x90CA 0x621A #CJK UNIFIED IDEOGRAPH
+0x90CB 0x65A5 #CJK UNIFIED IDEOGRAPH
+0x90CC 0x6614 #CJK UNIFIED IDEOGRAPH
+0x90CD 0x6790 #CJK UNIFIED IDEOGRAPH
+0x90CE 0x77F3 #CJK UNIFIED IDEOGRAPH
+0x90CF 0x7A4D #CJK UNIFIED IDEOGRAPH
+0x90D0 0x7C4D #CJK UNIFIED IDEOGRAPH
+0x90D1 0x7E3E #CJK UNIFIED IDEOGRAPH
+0x90D2 0x810A #CJK UNIFIED IDEOGRAPH
+0x90D3 0x8CAC #CJK UNIFIED IDEOGRAPH
+0x90D4 0x8D64 #CJK UNIFIED IDEOGRAPH
+0x90D5 0x8DE1 #CJK UNIFIED IDEOGRAPH
+0x90D6 0x8E5F #CJK UNIFIED IDEOGRAPH
+0x90D7 0x78A9 #CJK UNIFIED IDEOGRAPH
+0x90D8 0x5207 #CJK UNIFIED IDEOGRAPH
+0x90D9 0x62D9 #CJK UNIFIED IDEOGRAPH
+0x90DA 0x63A5 #CJK UNIFIED IDEOGRAPH
+0x90DB 0x6442 #CJK UNIFIED IDEOGRAPH
+0x90DC 0x6298 #CJK UNIFIED IDEOGRAPH
+0x90DD 0x8A2D #CJK UNIFIED IDEOGRAPH
+0x90DE 0x7A83 #CJK UNIFIED IDEOGRAPH
+0x90DF 0x7BC0 #CJK UNIFIED IDEOGRAPH
+0x90E0 0x8AAC #CJK UNIFIED IDEOGRAPH
+0x90E1 0x96EA #CJK UNIFIED IDEOGRAPH
+0x90E2 0x7D76 #CJK UNIFIED IDEOGRAPH
+0x90E3 0x820C #CJK UNIFIED IDEOGRAPH
+0x90E4 0x8749 #CJK UNIFIED IDEOGRAPH
+0x90E5 0x4ED9 #CJK UNIFIED IDEOGRAPH
+0x90E6 0x5148 #CJK UNIFIED IDEOGRAPH
+0x90E7 0x5343 #CJK UNIFIED IDEOGRAPH
+0x90E8 0x5360 #CJK UNIFIED IDEOGRAPH
+0x90E9 0x5BA3 #CJK UNIFIED IDEOGRAPH
+0x90EA 0x5C02 #CJK UNIFIED IDEOGRAPH
+0x90EB 0x5C16 #CJK UNIFIED IDEOGRAPH
+0x90EC 0x5DDD #CJK UNIFIED IDEOGRAPH
+0x90ED 0x6226 #CJK UNIFIED IDEOGRAPH
+0x90EE 0x6247 #CJK UNIFIED IDEOGRAPH
+0x90EF 0x64B0 #CJK UNIFIED IDEOGRAPH
+0x90F0 0x6813 #CJK UNIFIED IDEOGRAPH
+0x90F1 0x6834 #CJK UNIFIED IDEOGRAPH
+0x90F2 0x6CC9 #CJK UNIFIED IDEOGRAPH
+0x90F3 0x6D45 #CJK UNIFIED IDEOGRAPH
+0x90F4 0x6D17 #CJK UNIFIED IDEOGRAPH
+0x90F5 0x67D3 #CJK UNIFIED IDEOGRAPH
+0x90F6 0x6F5C #CJK UNIFIED IDEOGRAPH
+0x90F7 0x714E #CJK UNIFIED IDEOGRAPH
+0x90F8 0x717D #CJK UNIFIED IDEOGRAPH
+0x90F9 0x65CB #CJK UNIFIED IDEOGRAPH
+0x90FA 0x7A7F #CJK UNIFIED IDEOGRAPH
+0x90FB 0x7BAD #CJK UNIFIED IDEOGRAPH
+0x90FC 0x7DDA #CJK UNIFIED IDEOGRAPH
+0x9140 0x7E4A #CJK UNIFIED IDEOGRAPH
+0x9141 0x7FA8 #CJK UNIFIED IDEOGRAPH
+0x9142 0x817A #CJK UNIFIED IDEOGRAPH
+0x9143 0x821B #CJK UNIFIED IDEOGRAPH
+0x9144 0x8239 #CJK UNIFIED IDEOGRAPH
+0x9145 0x85A6 #CJK UNIFIED IDEOGRAPH
+0x9146 0x8A6E #CJK UNIFIED IDEOGRAPH
+0x9147 0x8CCE #CJK UNIFIED IDEOGRAPH
+0x9148 0x8DF5 #CJK UNIFIED IDEOGRAPH
+0x9149 0x9078 #CJK UNIFIED IDEOGRAPH
+0x914A 0x9077 #CJK UNIFIED IDEOGRAPH
+0x914B 0x92AD #CJK UNIFIED IDEOGRAPH
+0x914C 0x9291 #CJK UNIFIED IDEOGRAPH
+0x914D 0x9583 #CJK UNIFIED IDEOGRAPH
+0x914E 0x9BAE #CJK UNIFIED IDEOGRAPH
+0x914F 0x524D #CJK UNIFIED IDEOGRAPH
+0x9150 0x5584 #CJK UNIFIED IDEOGRAPH
+0x9151 0x6F38 #CJK UNIFIED IDEOGRAPH
+0x9152 0x7136 #CJK UNIFIED IDEOGRAPH
+0x9153 0x5168 #CJK UNIFIED IDEOGRAPH
+0x9154 0x7985 #CJK UNIFIED IDEOGRAPH
+0x9155 0x7E55 #CJK UNIFIED IDEOGRAPH
+0x9156 0x81B3 #CJK UNIFIED IDEOGRAPH
+0x9157 0x7CCE #CJK UNIFIED IDEOGRAPH
+0x9158 0x564C #CJK UNIFIED IDEOGRAPH
+0x9159 0x5851 #CJK UNIFIED IDEOGRAPH
+0x915A 0x5CA8 #CJK UNIFIED IDEOGRAPH
+0x915B 0x63AA #CJK UNIFIED IDEOGRAPH
+0x915C 0x66FE #CJK UNIFIED IDEOGRAPH
+0x915D 0x66FD #CJK UNIFIED IDEOGRAPH
+0x915E 0x695A #CJK UNIFIED IDEOGRAPH
+0x915F 0x72D9 #CJK UNIFIED IDEOGRAPH
+0x9160 0x758F #CJK UNIFIED IDEOGRAPH
+0x9161 0x758E #CJK UNIFIED IDEOGRAPH
+0x9162 0x790E #CJK UNIFIED IDEOGRAPH
+0x9163 0x7956 #CJK UNIFIED IDEOGRAPH
+0x9164 0x79DF #CJK UNIFIED IDEOGRAPH
+0x9165 0x7C97 #CJK UNIFIED IDEOGRAPH
+0x9166 0x7D20 #CJK UNIFIED IDEOGRAPH
+0x9167 0x7D44 #CJK UNIFIED IDEOGRAPH
+0x9168 0x8607 #CJK UNIFIED IDEOGRAPH
+0x9169 0x8A34 #CJK UNIFIED IDEOGRAPH
+0x916A 0x963B #CJK UNIFIED IDEOGRAPH
+0x916B 0x9061 #CJK UNIFIED IDEOGRAPH
+0x916C 0x9F20 #CJK UNIFIED IDEOGRAPH
+0x916D 0x50E7 #CJK UNIFIED IDEOGRAPH
+0x916E 0x5275 #CJK UNIFIED IDEOGRAPH
+0x916F 0x53CC #CJK UNIFIED IDEOGRAPH
+0x9170 0x53E2 #CJK UNIFIED IDEOGRAPH
+0x9171 0x5009 #CJK UNIFIED IDEOGRAPH
+0x9172 0x55AA #CJK UNIFIED IDEOGRAPH
+0x9173 0x58EE #CJK UNIFIED IDEOGRAPH
+0x9174 0x594F #CJK UNIFIED IDEOGRAPH
+0x9175 0x723D #CJK UNIFIED IDEOGRAPH
+0x9176 0x5B8B #CJK UNIFIED IDEOGRAPH
+0x9177 0x5C64 #CJK UNIFIED IDEOGRAPH
+0x9178 0x531D #CJK UNIFIED IDEOGRAPH
+0x9179 0x60E3 #CJK UNIFIED IDEOGRAPH
+0x917A 0x60F3 #CJK UNIFIED IDEOGRAPH
+0x917B 0x635C #CJK UNIFIED IDEOGRAPH
+0x917C 0x6383 #CJK UNIFIED IDEOGRAPH
+0x917D 0x633F #CJK UNIFIED IDEOGRAPH
+0x917E 0x63BB #CJK UNIFIED IDEOGRAPH
+0x9180 0x64CD #CJK UNIFIED IDEOGRAPH
+0x9181 0x65E9 #CJK UNIFIED IDEOGRAPH
+0x9182 0x66F9 #CJK UNIFIED IDEOGRAPH
+0x9183 0x5DE3 #CJK UNIFIED IDEOGRAPH
+0x9184 0x69CD #CJK UNIFIED IDEOGRAPH
+0x9185 0x69FD #CJK UNIFIED IDEOGRAPH
+0x9186 0x6F15 #CJK UNIFIED IDEOGRAPH
+0x9187 0x71E5 #CJK UNIFIED IDEOGRAPH
+0x9188 0x4E89 #CJK UNIFIED IDEOGRAPH
+0x9189 0x75E9 #CJK UNIFIED IDEOGRAPH
+0x918A 0x76F8 #CJK UNIFIED IDEOGRAPH
+0x918B 0x7A93 #CJK UNIFIED IDEOGRAPH
+0x918C 0x7CDF #CJK UNIFIED IDEOGRAPH
+0x918D 0x7DCF #CJK UNIFIED IDEOGRAPH
+0x918E 0x7D9C #CJK UNIFIED IDEOGRAPH
+0x918F 0x8061 #CJK UNIFIED IDEOGRAPH
+0x9190 0x8349 #CJK UNIFIED IDEOGRAPH
+0x9191 0x8358 #CJK UNIFIED IDEOGRAPH
+0x9192 0x846C #CJK UNIFIED IDEOGRAPH
+0x9193 0x84BC #CJK UNIFIED IDEOGRAPH
+0x9194 0x85FB #CJK UNIFIED IDEOGRAPH
+0x9195 0x88C5 #CJK UNIFIED IDEOGRAPH
+0x9196 0x8D70 #CJK UNIFIED IDEOGRAPH
+0x9197 0x9001 #CJK UNIFIED IDEOGRAPH
+0x9198 0x906D #CJK UNIFIED IDEOGRAPH
+0x9199 0x9397 #CJK UNIFIED IDEOGRAPH
+0x919A 0x971C #CJK UNIFIED IDEOGRAPH
+0x919B 0x9A12 #CJK UNIFIED IDEOGRAPH
+0x919C 0x50CF #CJK UNIFIED IDEOGRAPH
+0x919D 0x5897 #CJK UNIFIED IDEOGRAPH
+0x919E 0x618E #CJK UNIFIED IDEOGRAPH
+0x919F 0x81D3 #CJK UNIFIED IDEOGRAPH
+0x91A0 0x8535 #CJK UNIFIED IDEOGRAPH
+0x91A1 0x8D08 #CJK UNIFIED IDEOGRAPH
+0x91A2 0x9020 #CJK UNIFIED IDEOGRAPH
+0x91A3 0x4FC3 #CJK UNIFIED IDEOGRAPH
+0x91A4 0x5074 #CJK UNIFIED IDEOGRAPH
+0x91A5 0x5247 #CJK UNIFIED IDEOGRAPH
+0x91A6 0x5373 #CJK UNIFIED IDEOGRAPH
+0x91A7 0x606F #CJK UNIFIED IDEOGRAPH
+0x91A8 0x6349 #CJK UNIFIED IDEOGRAPH
+0x91A9 0x675F #CJK UNIFIED IDEOGRAPH
+0x91AA 0x6E2C #CJK UNIFIED IDEOGRAPH
+0x91AB 0x8DB3 #CJK UNIFIED IDEOGRAPH
+0x91AC 0x901F #CJK UNIFIED IDEOGRAPH
+0x91AD 0x4FD7 #CJK UNIFIED IDEOGRAPH
+0x91AE 0x5C5E #CJK UNIFIED IDEOGRAPH
+0x91AF 0x8CCA #CJK UNIFIED IDEOGRAPH
+0x91B0 0x65CF #CJK UNIFIED IDEOGRAPH
+0x91B1 0x7D9A #CJK UNIFIED IDEOGRAPH
+0x91B2 0x5352 #CJK UNIFIED IDEOGRAPH
+0x91B3 0x8896 #CJK UNIFIED IDEOGRAPH
+0x91B4 0x5176 #CJK UNIFIED IDEOGRAPH
+0x91B5 0x63C3 #CJK UNIFIED IDEOGRAPH
+0x91B6 0x5B58 #CJK UNIFIED IDEOGRAPH
+0x91B7 0x5B6B #CJK UNIFIED IDEOGRAPH
+0x91B8 0x5C0A #CJK UNIFIED IDEOGRAPH
+0x91B9 0x640D #CJK UNIFIED IDEOGRAPH
+0x91BA 0x6751 #CJK UNIFIED IDEOGRAPH
+0x91BB 0x905C #CJK UNIFIED IDEOGRAPH
+0x91BC 0x4ED6 #CJK UNIFIED IDEOGRAPH
+0x91BD 0x591A #CJK UNIFIED IDEOGRAPH
+0x91BE 0x592A #CJK UNIFIED IDEOGRAPH
+0x91BF 0x6C70 #CJK UNIFIED IDEOGRAPH
+0x91C0 0x8A51 #CJK UNIFIED IDEOGRAPH
+0x91C1 0x553E #CJK UNIFIED IDEOGRAPH
+0x91C2 0x5815 #CJK UNIFIED IDEOGRAPH
+0x91C3 0x59A5 #CJK UNIFIED IDEOGRAPH
+0x91C4 0x60F0 #CJK UNIFIED IDEOGRAPH
+0x91C5 0x6253 #CJK UNIFIED IDEOGRAPH
+0x91C6 0x67C1 #CJK UNIFIED IDEOGRAPH
+0x91C7 0x8235 #CJK UNIFIED IDEOGRAPH
+0x91C8 0x6955 #CJK UNIFIED IDEOGRAPH
+0x91C9 0x9640 #CJK UNIFIED IDEOGRAPH
+0x91CA 0x99C4 #CJK UNIFIED IDEOGRAPH
+0x91CB 0x9A28 #CJK UNIFIED IDEOGRAPH
+0x91CC 0x4F53 #CJK UNIFIED IDEOGRAPH
+0x91CD 0x5806 #CJK UNIFIED IDEOGRAPH
+0x91CE 0x5BFE #CJK UNIFIED IDEOGRAPH
+0x91CF 0x8010 #CJK UNIFIED IDEOGRAPH
+0x91D0 0x5CB1 #CJK UNIFIED IDEOGRAPH
+0x91D1 0x5E2F #CJK UNIFIED IDEOGRAPH
+0x91D2 0x5F85 #CJK UNIFIED IDEOGRAPH
+0x91D3 0x6020 #CJK UNIFIED IDEOGRAPH
+0x91D4 0x614B #CJK UNIFIED IDEOGRAPH
+0x91D5 0x6234 #CJK UNIFIED IDEOGRAPH
+0x91D6 0x66FF #CJK UNIFIED IDEOGRAPH
+0x91D7 0x6CF0 #CJK UNIFIED IDEOGRAPH
+0x91D8 0x6EDE #CJK UNIFIED IDEOGRAPH
+0x91D9 0x80CE #CJK UNIFIED IDEOGRAPH
+0x91DA 0x817F #CJK UNIFIED IDEOGRAPH
+0x91DB 0x82D4 #CJK UNIFIED IDEOGRAPH
+0x91DC 0x888B #CJK UNIFIED IDEOGRAPH
+0x91DD 0x8CB8 #CJK UNIFIED IDEOGRAPH
+0x91DE 0x9000 #CJK UNIFIED IDEOGRAPH
+0x91DF 0x902E #CJK UNIFIED IDEOGRAPH
+0x91E0 0x968A #CJK UNIFIED IDEOGRAPH
+0x91E1 0x9EDB #CJK UNIFIED IDEOGRAPH
+0x91E2 0x9BDB #CJK UNIFIED IDEOGRAPH
+0x91E3 0x4EE3 #CJK UNIFIED IDEOGRAPH
+0x91E4 0x53F0 #CJK UNIFIED IDEOGRAPH
+0x91E5 0x5927 #CJK UNIFIED IDEOGRAPH
+0x91E6 0x7B2C #CJK UNIFIED IDEOGRAPH
+0x91E7 0x918D #CJK UNIFIED IDEOGRAPH
+0x91E8 0x984C #CJK UNIFIED IDEOGRAPH
+0x91E9 0x9DF9 #CJK UNIFIED IDEOGRAPH
+0x91EA 0x6EDD #CJK UNIFIED IDEOGRAPH
+0x91EB 0x7027 #CJK UNIFIED IDEOGRAPH
+0x91EC 0x5353 #CJK UNIFIED IDEOGRAPH
+0x91ED 0x5544 #CJK UNIFIED IDEOGRAPH
+0x91EE 0x5B85 #CJK UNIFIED IDEOGRAPH
+0x91EF 0x6258 #CJK UNIFIED IDEOGRAPH
+0x91F0 0x629E #CJK UNIFIED IDEOGRAPH
+0x91F1 0x62D3 #CJK UNIFIED IDEOGRAPH
+0x91F2 0x6CA2 #CJK UNIFIED IDEOGRAPH
+0x91F3 0x6FEF #CJK UNIFIED IDEOGRAPH
+0x91F4 0x7422 #CJK UNIFIED IDEOGRAPH
+0x91F5 0x8A17 #CJK UNIFIED IDEOGRAPH
+0x91F6 0x9438 #CJK UNIFIED IDEOGRAPH
+0x91F7 0x6FC1 #CJK UNIFIED IDEOGRAPH
+0x91F8 0x8AFE #CJK UNIFIED IDEOGRAPH
+0x91F9 0x8338 #CJK UNIFIED IDEOGRAPH
+0x91FA 0x51E7 #CJK UNIFIED IDEOGRAPH
+0x91FB 0x86F8 #CJK UNIFIED IDEOGRAPH
+0x91FC 0x53EA #CJK UNIFIED IDEOGRAPH
+0x9240 0x53E9 #CJK UNIFIED IDEOGRAPH
+0x9241 0x4F46 #CJK UNIFIED IDEOGRAPH
+0x9242 0x9054 #CJK UNIFIED IDEOGRAPH
+0x9243 0x8FB0 #CJK UNIFIED IDEOGRAPH
+0x9244 0x596A #CJK UNIFIED IDEOGRAPH
+0x9245 0x8131 #CJK UNIFIED IDEOGRAPH
+0x9246 0x5DFD #CJK UNIFIED IDEOGRAPH
+0x9247 0x7AEA #CJK UNIFIED IDEOGRAPH
+0x9248 0x8FBF #CJK UNIFIED IDEOGRAPH
+0x9249 0x68DA #CJK UNIFIED IDEOGRAPH
+0x924A 0x8C37 #CJK UNIFIED IDEOGRAPH
+0x924B 0x72F8 #CJK UNIFIED IDEOGRAPH
+0x924C 0x9C48 #CJK UNIFIED IDEOGRAPH
+0x924D 0x6A3D #CJK UNIFIED IDEOGRAPH
+0x924E 0x8AB0 #CJK UNIFIED IDEOGRAPH
+0x924F 0x4E39 #CJK UNIFIED IDEOGRAPH
+0x9250 0x5358 #CJK UNIFIED IDEOGRAPH
+0x9251 0x5606 #CJK UNIFIED IDEOGRAPH
+0x9252 0x5766 #CJK UNIFIED IDEOGRAPH
+0x9253 0x62C5 #CJK UNIFIED IDEOGRAPH
+0x9254 0x63A2 #CJK UNIFIED IDEOGRAPH
+0x9255 0x65E6 #CJK UNIFIED IDEOGRAPH
+0x9256 0x6B4E #CJK UNIFIED IDEOGRAPH
+0x9257 0x6DE1 #CJK UNIFIED IDEOGRAPH
+0x9258 0x6E5B #CJK UNIFIED IDEOGRAPH
+0x9259 0x70AD #CJK UNIFIED IDEOGRAPH
+0x925A 0x77ED #CJK UNIFIED IDEOGRAPH
+0x925B 0x7AEF #CJK UNIFIED IDEOGRAPH
+0x925C 0x7BAA #CJK UNIFIED IDEOGRAPH
+0x925D 0x7DBB #CJK UNIFIED IDEOGRAPH
+0x925E 0x803D #CJK UNIFIED IDEOGRAPH
+0x925F 0x80C6 #CJK UNIFIED IDEOGRAPH
+0x9260 0x86CB #CJK UNIFIED IDEOGRAPH
+0x9261 0x8A95 #CJK UNIFIED IDEOGRAPH
+0x9262 0x935B #CJK UNIFIED IDEOGRAPH
+0x9263 0x56E3 #CJK UNIFIED IDEOGRAPH
+0x9264 0x58C7 #CJK UNIFIED IDEOGRAPH
+0x9265 0x5F3E #CJK UNIFIED IDEOGRAPH
+0x9266 0x65AD #CJK UNIFIED IDEOGRAPH
+0x9267 0x6696 #CJK UNIFIED IDEOGRAPH
+0x9268 0x6A80 #CJK UNIFIED IDEOGRAPH
+0x9269 0x6BB5 #CJK UNIFIED IDEOGRAPH
+0x926A 0x7537 #CJK UNIFIED IDEOGRAPH
+0x926B 0x8AC7 #CJK UNIFIED IDEOGRAPH
+0x926C 0x5024 #CJK UNIFIED IDEOGRAPH
+0x926D 0x77E5 #CJK UNIFIED IDEOGRAPH
+0x926E 0x5730 #CJK UNIFIED IDEOGRAPH
+0x926F 0x5F1B #CJK UNIFIED IDEOGRAPH
+0x9270 0x6065 #CJK UNIFIED IDEOGRAPH
+0x9271 0x667A #CJK UNIFIED IDEOGRAPH
+0x9272 0x6C60 #CJK UNIFIED IDEOGRAPH
+0x9273 0x75F4 #CJK UNIFIED IDEOGRAPH
+0x9274 0x7A1A #CJK UNIFIED IDEOGRAPH
+0x9275 0x7F6E #CJK UNIFIED IDEOGRAPH
+0x9276 0x81F4 #CJK UNIFIED IDEOGRAPH
+0x9277 0x8718 #CJK UNIFIED IDEOGRAPH
+0x9278 0x9045 #CJK UNIFIED IDEOGRAPH
+0x9279 0x99B3 #CJK UNIFIED IDEOGRAPH
+0x927A 0x7BC9 #CJK UNIFIED IDEOGRAPH
+0x927B 0x755C #CJK UNIFIED IDEOGRAPH
+0x927C 0x7AF9 #CJK UNIFIED IDEOGRAPH
+0x927D 0x7B51 #CJK UNIFIED IDEOGRAPH
+0x927E 0x84C4 #CJK UNIFIED IDEOGRAPH
+0x9280 0x9010 #CJK UNIFIED IDEOGRAPH
+0x9281 0x79E9 #CJK UNIFIED IDEOGRAPH
+0x9282 0x7A92 #CJK UNIFIED IDEOGRAPH
+0x9283 0x8336 #CJK UNIFIED IDEOGRAPH
+0x9284 0x5AE1 #CJK UNIFIED IDEOGRAPH
+0x9285 0x7740 #CJK UNIFIED IDEOGRAPH
+0x9286 0x4E2D #CJK UNIFIED IDEOGRAPH
+0x9287 0x4EF2 #CJK UNIFIED IDEOGRAPH
+0x9288 0x5B99 #CJK UNIFIED IDEOGRAPH
+0x9289 0x5FE0 #CJK UNIFIED IDEOGRAPH
+0x928A 0x62BD #CJK UNIFIED IDEOGRAPH
+0x928B 0x663C #CJK UNIFIED IDEOGRAPH
+0x928C 0x67F1 #CJK UNIFIED IDEOGRAPH
+0x928D 0x6CE8 #CJK UNIFIED IDEOGRAPH
+0x928E 0x866B #CJK UNIFIED IDEOGRAPH
+0x928F 0x8877 #CJK UNIFIED IDEOGRAPH
+0x9290 0x8A3B #CJK UNIFIED IDEOGRAPH
+0x9291 0x914E #CJK UNIFIED IDEOGRAPH
+0x9292 0x92F3 #CJK UNIFIED IDEOGRAPH
+0x9293 0x99D0 #CJK UNIFIED IDEOGRAPH
+0x9294 0x6A17 #CJK UNIFIED IDEOGRAPH
+0x9295 0x7026 #CJK UNIFIED IDEOGRAPH
+0x9296 0x732A #CJK UNIFIED IDEOGRAPH
+0x9297 0x82E7 #CJK UNIFIED IDEOGRAPH
+0x9298 0x8457 #CJK UNIFIED IDEOGRAPH
+0x9299 0x8CAF #CJK UNIFIED IDEOGRAPH
+0x929A 0x4E01 #CJK UNIFIED IDEOGRAPH
+0x929B 0x5146 #CJK UNIFIED IDEOGRAPH
+0x929C 0x51CB #CJK UNIFIED IDEOGRAPH
+0x929D 0x558B #CJK UNIFIED IDEOGRAPH
+0x929E 0x5BF5 #CJK UNIFIED IDEOGRAPH
+0x929F 0x5E16 #CJK UNIFIED IDEOGRAPH
+0x92A0 0x5E33 #CJK UNIFIED IDEOGRAPH
+0x92A1 0x5E81 #CJK UNIFIED IDEOGRAPH
+0x92A2 0x5F14 #CJK UNIFIED IDEOGRAPH
+0x92A3 0x5F35 #CJK UNIFIED IDEOGRAPH
+0x92A4 0x5F6B #CJK UNIFIED IDEOGRAPH
+0x92A5 0x5FB4 #CJK UNIFIED IDEOGRAPH
+0x92A6 0x61F2 #CJK UNIFIED IDEOGRAPH
+0x92A7 0x6311 #CJK UNIFIED IDEOGRAPH
+0x92A8 0x66A2 #CJK UNIFIED IDEOGRAPH
+0x92A9 0x671D #CJK UNIFIED IDEOGRAPH
+0x92AA 0x6F6E #CJK UNIFIED IDEOGRAPH
+0x92AB 0x7252 #CJK UNIFIED IDEOGRAPH
+0x92AC 0x753A #CJK UNIFIED IDEOGRAPH
+0x92AD 0x773A #CJK UNIFIED IDEOGRAPH
+0x92AE 0x8074 #CJK UNIFIED IDEOGRAPH
+0x92AF 0x8139 #CJK UNIFIED IDEOGRAPH
+0x92B0 0x8178 #CJK UNIFIED IDEOGRAPH
+0x92B1 0x8776 #CJK UNIFIED IDEOGRAPH
+0x92B2 0x8ABF #CJK UNIFIED IDEOGRAPH
+0x92B3 0x8ADC #CJK UNIFIED IDEOGRAPH
+0x92B4 0x8D85 #CJK UNIFIED IDEOGRAPH
+0x92B5 0x8DF3 #CJK UNIFIED IDEOGRAPH
+0x92B6 0x929A #CJK UNIFIED IDEOGRAPH
+0x92B7 0x9577 #CJK UNIFIED IDEOGRAPH
+0x92B8 0x9802 #CJK UNIFIED IDEOGRAPH
+0x92B9 0x9CE5 #CJK UNIFIED IDEOGRAPH
+0x92BA 0x52C5 #CJK UNIFIED IDEOGRAPH
+0x92BB 0x6357 #CJK UNIFIED IDEOGRAPH
+0x92BC 0x76F4 #CJK UNIFIED IDEOGRAPH
+0x92BD 0x6715 #CJK UNIFIED IDEOGRAPH
+0x92BE 0x6C88 #CJK UNIFIED IDEOGRAPH
+0x92BF 0x73CD #CJK UNIFIED IDEOGRAPH
+0x92C0 0x8CC3 #CJK UNIFIED IDEOGRAPH
+0x92C1 0x93AE #CJK UNIFIED IDEOGRAPH
+0x92C2 0x9673 #CJK UNIFIED IDEOGRAPH
+0x92C3 0x6D25 #CJK UNIFIED IDEOGRAPH
+0x92C4 0x589C #CJK UNIFIED IDEOGRAPH
+0x92C5 0x690E #CJK UNIFIED IDEOGRAPH
+0x92C6 0x69CC #CJK UNIFIED IDEOGRAPH
+0x92C7 0x8FFD #CJK UNIFIED IDEOGRAPH
+0x92C8 0x939A #CJK UNIFIED IDEOGRAPH
+0x92C9 0x75DB #CJK UNIFIED IDEOGRAPH
+0x92CA 0x901A #CJK UNIFIED IDEOGRAPH
+0x92CB 0x585A #CJK UNIFIED IDEOGRAPH
+0x92CC 0x6802 #CJK UNIFIED IDEOGRAPH
+0x92CD 0x63B4 #CJK UNIFIED IDEOGRAPH
+0x92CE 0x69FB #CJK UNIFIED IDEOGRAPH
+0x92CF 0x4F43 #CJK UNIFIED IDEOGRAPH
+0x92D0 0x6F2C #CJK UNIFIED IDEOGRAPH
+0x92D1 0x67D8 #CJK UNIFIED IDEOGRAPH
+0x92D2 0x8FBB #CJK UNIFIED IDEOGRAPH
+0x92D3 0x8526 #CJK UNIFIED IDEOGRAPH
+0x92D4 0x7DB4 #CJK UNIFIED IDEOGRAPH
+0x92D5 0x9354 #CJK UNIFIED IDEOGRAPH
+0x92D6 0x693F #CJK UNIFIED IDEOGRAPH
+0x92D7 0x6F70 #CJK UNIFIED IDEOGRAPH
+0x92D8 0x576A #CJK UNIFIED IDEOGRAPH
+0x92D9 0x58F7 #CJK UNIFIED IDEOGRAPH
+0x92DA 0x5B2C #CJK UNIFIED IDEOGRAPH
+0x92DB 0x7D2C #CJK UNIFIED IDEOGRAPH
+0x92DC 0x722A #CJK UNIFIED IDEOGRAPH
+0x92DD 0x540A #CJK UNIFIED IDEOGRAPH
+0x92DE 0x91E3 #CJK UNIFIED IDEOGRAPH
+0x92DF 0x9DB4 #CJK UNIFIED IDEOGRAPH
+0x92E0 0x4EAD #CJK UNIFIED IDEOGRAPH
+0x92E1 0x4F4E #CJK UNIFIED IDEOGRAPH
+0x92E2 0x505C #CJK UNIFIED IDEOGRAPH
+0x92E3 0x5075 #CJK UNIFIED IDEOGRAPH
+0x92E4 0x5243 #CJK UNIFIED IDEOGRAPH
+0x92E5 0x8C9E #CJK UNIFIED IDEOGRAPH
+0x92E6 0x5448 #CJK UNIFIED IDEOGRAPH
+0x92E7 0x5824 #CJK UNIFIED IDEOGRAPH
+0x92E8 0x5B9A #CJK UNIFIED IDEOGRAPH
+0x92E9 0x5E1D #CJK UNIFIED IDEOGRAPH
+0x92EA 0x5E95 #CJK UNIFIED IDEOGRAPH
+0x92EB 0x5EAD #CJK UNIFIED IDEOGRAPH
+0x92EC 0x5EF7 #CJK UNIFIED IDEOGRAPH
+0x92ED 0x5F1F #CJK UNIFIED IDEOGRAPH
+0x92EE 0x608C #CJK UNIFIED IDEOGRAPH
+0x92EF 0x62B5 #CJK UNIFIED IDEOGRAPH
+0x92F0 0x633A #CJK UNIFIED IDEOGRAPH
+0x92F1 0x63D0 #CJK UNIFIED IDEOGRAPH
+0x92F2 0x68AF #CJK UNIFIED IDEOGRAPH
+0x92F3 0x6C40 #CJK UNIFIED IDEOGRAPH
+0x92F4 0x7887 #CJK UNIFIED IDEOGRAPH
+0x92F5 0x798E #CJK UNIFIED IDEOGRAPH
+0x92F6 0x7A0B #CJK UNIFIED IDEOGRAPH
+0x92F7 0x7DE0 #CJK UNIFIED IDEOGRAPH
+0x92F8 0x8247 #CJK UNIFIED IDEOGRAPH
+0x92F9 0x8A02 #CJK UNIFIED IDEOGRAPH
+0x92FA 0x8AE6 #CJK UNIFIED IDEOGRAPH
+0x92FB 0x8E44 #CJK UNIFIED IDEOGRAPH
+0x92FC 0x9013 #CJK UNIFIED IDEOGRAPH
+0x9340 0x90B8 #CJK UNIFIED IDEOGRAPH
+0x9341 0x912D #CJK UNIFIED IDEOGRAPH
+0x9342 0x91D8 #CJK UNIFIED IDEOGRAPH
+0x9343 0x9F0E #CJK UNIFIED IDEOGRAPH
+0x9344 0x6CE5 #CJK UNIFIED IDEOGRAPH
+0x9345 0x6458 #CJK UNIFIED IDEOGRAPH
+0x9346 0x64E2 #CJK UNIFIED IDEOGRAPH
+0x9347 0x6575 #CJK UNIFIED IDEOGRAPH
+0x9348 0x6EF4 #CJK UNIFIED IDEOGRAPH
+0x9349 0x7684 #CJK UNIFIED IDEOGRAPH
+0x934A 0x7B1B #CJK UNIFIED IDEOGRAPH
+0x934B 0x9069 #CJK UNIFIED IDEOGRAPH
+0x934C 0x93D1 #CJK UNIFIED IDEOGRAPH
+0x934D 0x6EBA #CJK UNIFIED IDEOGRAPH
+0x934E 0x54F2 #CJK UNIFIED IDEOGRAPH
+0x934F 0x5FB9 #CJK UNIFIED IDEOGRAPH
+0x9350 0x64A4 #CJK UNIFIED IDEOGRAPH
+0x9351 0x8F4D #CJK UNIFIED IDEOGRAPH
+0x9352 0x8FED #CJK UNIFIED IDEOGRAPH
+0x9353 0x9244 #CJK UNIFIED IDEOGRAPH
+0x9354 0x5178 #CJK UNIFIED IDEOGRAPH
+0x9355 0x586B #CJK UNIFIED IDEOGRAPH
+0x9356 0x5929 #CJK UNIFIED IDEOGRAPH
+0x9357 0x5C55 #CJK UNIFIED IDEOGRAPH
+0x9358 0x5E97 #CJK UNIFIED IDEOGRAPH
+0x9359 0x6DFB #CJK UNIFIED IDEOGRAPH
+0x935A 0x7E8F #CJK UNIFIED IDEOGRAPH
+0x935B 0x751C #CJK UNIFIED IDEOGRAPH
+0x935C 0x8CBC #CJK UNIFIED IDEOGRAPH
+0x935D 0x8EE2 #CJK UNIFIED IDEOGRAPH
+0x935E 0x985B #CJK UNIFIED IDEOGRAPH
+0x935F 0x70B9 #CJK UNIFIED IDEOGRAPH
+0x9360 0x4F1D #CJK UNIFIED IDEOGRAPH
+0x9361 0x6BBF #CJK UNIFIED IDEOGRAPH
+0x9362 0x6FB1 #CJK UNIFIED IDEOGRAPH
+0x9363 0x7530 #CJK UNIFIED IDEOGRAPH
+0x9364 0x96FB #CJK UNIFIED IDEOGRAPH
+0x9365 0x514E #CJK UNIFIED IDEOGRAPH
+0x9366 0x5410 #CJK UNIFIED IDEOGRAPH
+0x9367 0x5835 #CJK UNIFIED IDEOGRAPH
+0x9368 0x5857 #CJK UNIFIED IDEOGRAPH
+0x9369 0x59AC #CJK UNIFIED IDEOGRAPH
+0x936A 0x5C60 #CJK UNIFIED IDEOGRAPH
+0x936B 0x5F92 #CJK UNIFIED IDEOGRAPH
+0x936C 0x6597 #CJK UNIFIED IDEOGRAPH
+0x936D 0x675C #CJK UNIFIED IDEOGRAPH
+0x936E 0x6E21 #CJK UNIFIED IDEOGRAPH
+0x936F 0x767B #CJK UNIFIED IDEOGRAPH
+0x9370 0x83DF #CJK UNIFIED IDEOGRAPH
+0x9371 0x8CED #CJK UNIFIED IDEOGRAPH
+0x9372 0x9014 #CJK UNIFIED IDEOGRAPH
+0x9373 0x90FD #CJK UNIFIED IDEOGRAPH
+0x9374 0x934D #CJK UNIFIED IDEOGRAPH
+0x9375 0x7825 #CJK UNIFIED IDEOGRAPH
+0x9376 0x783A #CJK UNIFIED IDEOGRAPH
+0x9377 0x52AA #CJK UNIFIED IDEOGRAPH
+0x9378 0x5EA6 #CJK UNIFIED IDEOGRAPH
+0x9379 0x571F #CJK UNIFIED IDEOGRAPH
+0x937A 0x5974 #CJK UNIFIED IDEOGRAPH
+0x937B 0x6012 #CJK UNIFIED IDEOGRAPH
+0x937C 0x5012 #CJK UNIFIED IDEOGRAPH
+0x937D 0x515A #CJK UNIFIED IDEOGRAPH
+0x937E 0x51AC #CJK UNIFIED IDEOGRAPH
+0x9380 0x51CD #CJK UNIFIED IDEOGRAPH
+0x9381 0x5200 #CJK UNIFIED IDEOGRAPH
+0x9382 0x5510 #CJK UNIFIED IDEOGRAPH
+0x9383 0x5854 #CJK UNIFIED IDEOGRAPH
+0x9384 0x5858 #CJK UNIFIED IDEOGRAPH
+0x9385 0x5957 #CJK UNIFIED IDEOGRAPH
+0x9386 0x5B95 #CJK UNIFIED IDEOGRAPH
+0x9387 0x5CF6 #CJK UNIFIED IDEOGRAPH
+0x9388 0x5D8B #CJK UNIFIED IDEOGRAPH
+0x9389 0x60BC #CJK UNIFIED IDEOGRAPH
+0x938A 0x6295 #CJK UNIFIED IDEOGRAPH
+0x938B 0x642D #CJK UNIFIED IDEOGRAPH
+0x938C 0x6771 #CJK UNIFIED IDEOGRAPH
+0x938D 0x6843 #CJK UNIFIED IDEOGRAPH
+0x938E 0x68BC #CJK UNIFIED IDEOGRAPH
+0x938F 0x68DF #CJK UNIFIED IDEOGRAPH
+0x9390 0x76D7 #CJK UNIFIED IDEOGRAPH
+0x9391 0x6DD8 #CJK UNIFIED IDEOGRAPH
+0x9392 0x6E6F #CJK UNIFIED IDEOGRAPH
+0x9393 0x6D9B #CJK UNIFIED IDEOGRAPH
+0x9394 0x706F #CJK UNIFIED IDEOGRAPH
+0x9395 0x71C8 #CJK UNIFIED IDEOGRAPH
+0x9396 0x5F53 #CJK UNIFIED IDEOGRAPH
+0x9397 0x75D8 #CJK UNIFIED IDEOGRAPH
+0x9398 0x7977 #CJK UNIFIED IDEOGRAPH
+0x9399 0x7B49 #CJK UNIFIED IDEOGRAPH
+0x939A 0x7B54 #CJK UNIFIED IDEOGRAPH
+0x939B 0x7B52 #CJK UNIFIED IDEOGRAPH
+0x939C 0x7CD6 #CJK UNIFIED IDEOGRAPH
+0x939D 0x7D71 #CJK UNIFIED IDEOGRAPH
+0x939E 0x5230 #CJK UNIFIED IDEOGRAPH
+0x939F 0x8463 #CJK UNIFIED IDEOGRAPH
+0x93A0 0x8569 #CJK UNIFIED IDEOGRAPH
+0x93A1 0x85E4 #CJK UNIFIED IDEOGRAPH
+0x93A2 0x8A0E #CJK UNIFIED IDEOGRAPH
+0x93A3 0x8B04 #CJK UNIFIED IDEOGRAPH
+0x93A4 0x8C46 #CJK UNIFIED IDEOGRAPH
+0x93A5 0x8E0F #CJK UNIFIED IDEOGRAPH
+0x93A6 0x9003 #CJK UNIFIED IDEOGRAPH
+0x93A7 0x900F #CJK UNIFIED IDEOGRAPH
+0x93A8 0x9419 #CJK UNIFIED IDEOGRAPH
+0x93A9 0x9676 #CJK UNIFIED IDEOGRAPH
+0x93AA 0x982D #CJK UNIFIED IDEOGRAPH
+0x93AB 0x9A30 #CJK UNIFIED IDEOGRAPH
+0x93AC 0x95D8 #CJK UNIFIED IDEOGRAPH
+0x93AD 0x50CD #CJK UNIFIED IDEOGRAPH
+0x93AE 0x52D5 #CJK UNIFIED IDEOGRAPH
+0x93AF 0x540C #CJK UNIFIED IDEOGRAPH
+0x93B0 0x5802 #CJK UNIFIED IDEOGRAPH
+0x93B1 0x5C0E #CJK UNIFIED IDEOGRAPH
+0x93B2 0x61A7 #CJK UNIFIED IDEOGRAPH
+0x93B3 0x649E #CJK UNIFIED IDEOGRAPH
+0x93B4 0x6D1E #CJK UNIFIED IDEOGRAPH
+0x93B5 0x77B3 #CJK UNIFIED IDEOGRAPH
+0x93B6 0x7AE5 #CJK UNIFIED IDEOGRAPH
+0x93B7 0x80F4 #CJK UNIFIED IDEOGRAPH
+0x93B8 0x8404 #CJK UNIFIED IDEOGRAPH
+0x93B9 0x9053 #CJK UNIFIED IDEOGRAPH
+0x93BA 0x9285 #CJK UNIFIED IDEOGRAPH
+0x93BB 0x5CE0 #CJK UNIFIED IDEOGRAPH
+0x93BC 0x9D07 #CJK UNIFIED IDEOGRAPH
+0x93BD 0x533F #CJK UNIFIED IDEOGRAPH
+0x93BE 0x5F97 #CJK UNIFIED IDEOGRAPH
+0x93BF 0x5FB3 #CJK UNIFIED IDEOGRAPH
+0x93C0 0x6D9C #CJK UNIFIED IDEOGRAPH
+0x93C1 0x7279 #CJK UNIFIED IDEOGRAPH
+0x93C2 0x7763 #CJK UNIFIED IDEOGRAPH
+0x93C3 0x79BF #CJK UNIFIED IDEOGRAPH
+0x93C4 0x7BE4 #CJK UNIFIED IDEOGRAPH
+0x93C5 0x6BD2 #CJK UNIFIED IDEOGRAPH
+0x93C6 0x72EC #CJK UNIFIED IDEOGRAPH
+0x93C7 0x8AAD #CJK UNIFIED IDEOGRAPH
+0x93C8 0x6803 #CJK UNIFIED IDEOGRAPH
+0x93C9 0x6A61 #CJK UNIFIED IDEOGRAPH
+0x93CA 0x51F8 #CJK UNIFIED IDEOGRAPH
+0x93CB 0x7A81 #CJK UNIFIED IDEOGRAPH
+0x93CC 0x6934 #CJK UNIFIED IDEOGRAPH
+0x93CD 0x5C4A #CJK UNIFIED IDEOGRAPH
+0x93CE 0x9CF6 #CJK UNIFIED IDEOGRAPH
+0x93CF 0x82EB #CJK UNIFIED IDEOGRAPH
+0x93D0 0x5BC5 #CJK UNIFIED IDEOGRAPH
+0x93D1 0x9149 #CJK UNIFIED IDEOGRAPH
+0x93D2 0x701E #CJK UNIFIED IDEOGRAPH
+0x93D3 0x5678 #CJK UNIFIED IDEOGRAPH
+0x93D4 0x5C6F #CJK UNIFIED IDEOGRAPH
+0x93D5 0x60C7 #CJK UNIFIED IDEOGRAPH
+0x93D6 0x6566 #CJK UNIFIED IDEOGRAPH
+0x93D7 0x6C8C #CJK UNIFIED IDEOGRAPH
+0x93D8 0x8C5A #CJK UNIFIED IDEOGRAPH
+0x93D9 0x9041 #CJK UNIFIED IDEOGRAPH
+0x93DA 0x9813 #CJK UNIFIED IDEOGRAPH
+0x93DB 0x5451 #CJK UNIFIED IDEOGRAPH
+0x93DC 0x66C7 #CJK UNIFIED IDEOGRAPH
+0x93DD 0x920D #CJK UNIFIED IDEOGRAPH
+0x93DE 0x5948 #CJK UNIFIED IDEOGRAPH
+0x93DF 0x90A3 #CJK UNIFIED IDEOGRAPH
+0x93E0 0x5185 #CJK UNIFIED IDEOGRAPH
+0x93E1 0x4E4D #CJK UNIFIED IDEOGRAPH
+0x93E2 0x51EA #CJK UNIFIED IDEOGRAPH
+0x93E3 0x8599 #CJK UNIFIED IDEOGRAPH
+0x93E4 0x8B0E #CJK UNIFIED IDEOGRAPH
+0x93E5 0x7058 #CJK UNIFIED IDEOGRAPH
+0x93E6 0x637A #CJK UNIFIED IDEOGRAPH
+0x93E7 0x934B #CJK UNIFIED IDEOGRAPH
+0x93E8 0x6962 #CJK UNIFIED IDEOGRAPH
+0x93E9 0x99B4 #CJK UNIFIED IDEOGRAPH
+0x93EA 0x7E04 #CJK UNIFIED IDEOGRAPH
+0x93EB 0x7577 #CJK UNIFIED IDEOGRAPH
+0x93EC 0x5357 #CJK UNIFIED IDEOGRAPH
+0x93ED 0x6960 #CJK UNIFIED IDEOGRAPH
+0x93EE 0x8EDF #CJK UNIFIED IDEOGRAPH
+0x93EF 0x96E3 #CJK UNIFIED IDEOGRAPH
+0x93F0 0x6C5D #CJK UNIFIED IDEOGRAPH
+0x93F1 0x4E8C #CJK UNIFIED IDEOGRAPH
+0x93F2 0x5C3C #CJK UNIFIED IDEOGRAPH
+0x93F3 0x5F10 #CJK UNIFIED IDEOGRAPH
+0x93F4 0x8FE9 #CJK UNIFIED IDEOGRAPH
+0x93F5 0x5302 #CJK UNIFIED IDEOGRAPH
+0x93F6 0x8CD1 #CJK UNIFIED IDEOGRAPH
+0x93F7 0x8089 #CJK UNIFIED IDEOGRAPH
+0x93F8 0x8679 #CJK UNIFIED IDEOGRAPH
+0x93F9 0x5EFF #CJK UNIFIED IDEOGRAPH
+0x93FA 0x65E5 #CJK UNIFIED IDEOGRAPH
+0x93FB 0x4E73 #CJK UNIFIED IDEOGRAPH
+0x93FC 0x5165 #CJK UNIFIED IDEOGRAPH
+0x9440 0x5982 #CJK UNIFIED IDEOGRAPH
+0x9441 0x5C3F #CJK UNIFIED IDEOGRAPH
+0x9442 0x97EE #CJK UNIFIED IDEOGRAPH
+0x9443 0x4EFB #CJK UNIFIED IDEOGRAPH
+0x9444 0x598A #CJK UNIFIED IDEOGRAPH
+0x9445 0x5FCD #CJK UNIFIED IDEOGRAPH
+0x9446 0x8A8D #CJK UNIFIED IDEOGRAPH
+0x9447 0x6FE1 #CJK UNIFIED IDEOGRAPH
+0x9448 0x79B0 #CJK UNIFIED IDEOGRAPH
+0x9449 0x7962 #CJK UNIFIED IDEOGRAPH
+0x944A 0x5BE7 #CJK UNIFIED IDEOGRAPH
+0x944B 0x8471 #CJK UNIFIED IDEOGRAPH
+0x944C 0x732B #CJK UNIFIED IDEOGRAPH
+0x944D 0x71B1 #CJK UNIFIED IDEOGRAPH
+0x944E 0x5E74 #CJK UNIFIED IDEOGRAPH
+0x944F 0x5FF5 #CJK UNIFIED IDEOGRAPH
+0x9450 0x637B #CJK UNIFIED IDEOGRAPH
+0x9451 0x649A #CJK UNIFIED IDEOGRAPH
+0x9452 0x71C3 #CJK UNIFIED IDEOGRAPH
+0x9453 0x7C98 #CJK UNIFIED IDEOGRAPH
+0x9454 0x4E43 #CJK UNIFIED IDEOGRAPH
+0x9455 0x5EFC #CJK UNIFIED IDEOGRAPH
+0x9456 0x4E4B #CJK UNIFIED IDEOGRAPH
+0x9457 0x57DC #CJK UNIFIED IDEOGRAPH
+0x9458 0x56A2 #CJK UNIFIED IDEOGRAPH
+0x9459 0x60A9 #CJK UNIFIED IDEOGRAPH
+0x945A 0x6FC3 #CJK UNIFIED IDEOGRAPH
+0x945B 0x7D0D #CJK UNIFIED IDEOGRAPH
+0x945C 0x80FD #CJK UNIFIED IDEOGRAPH
+0x945D 0x8133 #CJK UNIFIED IDEOGRAPH
+0x945E 0x81BF #CJK UNIFIED IDEOGRAPH
+0x945F 0x8FB2 #CJK UNIFIED IDEOGRAPH
+0x9460 0x8997 #CJK UNIFIED IDEOGRAPH
+0x9461 0x86A4 #CJK UNIFIED IDEOGRAPH
+0x9462 0x5DF4 #CJK UNIFIED IDEOGRAPH
+0x9463 0x628A #CJK UNIFIED IDEOGRAPH
+0x9464 0x64AD #CJK UNIFIED IDEOGRAPH
+0x9465 0x8987 #CJK UNIFIED IDEOGRAPH
+0x9466 0x6777 #CJK UNIFIED IDEOGRAPH
+0x9467 0x6CE2 #CJK UNIFIED IDEOGRAPH
+0x9468 0x6D3E #CJK UNIFIED IDEOGRAPH
+0x9469 0x7436 #CJK UNIFIED IDEOGRAPH
+0x946A 0x7834 #CJK UNIFIED IDEOGRAPH
+0x946B 0x5A46 #CJK UNIFIED IDEOGRAPH
+0x946C 0x7F75 #CJK UNIFIED IDEOGRAPH
+0x946D 0x82AD #CJK UNIFIED IDEOGRAPH
+0x946E 0x99AC #CJK UNIFIED IDEOGRAPH
+0x946F 0x4FF3 #CJK UNIFIED IDEOGRAPH
+0x9470 0x5EC3 #CJK UNIFIED IDEOGRAPH
+0x9471 0x62DD #CJK UNIFIED IDEOGRAPH
+0x9472 0x6392 #CJK UNIFIED IDEOGRAPH
+0x9473 0x6557 #CJK UNIFIED IDEOGRAPH
+0x9474 0x676F #CJK UNIFIED IDEOGRAPH
+0x9475 0x76C3 #CJK UNIFIED IDEOGRAPH
+0x9476 0x724C #CJK UNIFIED IDEOGRAPH
+0x9477 0x80CC #CJK UNIFIED IDEOGRAPH
+0x9478 0x80BA #CJK UNIFIED IDEOGRAPH
+0x9479 0x8F29 #CJK UNIFIED IDEOGRAPH
+0x947A 0x914D #CJK UNIFIED IDEOGRAPH
+0x947B 0x500D #CJK UNIFIED IDEOGRAPH
+0x947C 0x57F9 #CJK UNIFIED IDEOGRAPH
+0x947D 0x5A92 #CJK UNIFIED IDEOGRAPH
+0x947E 0x6885 #CJK UNIFIED IDEOGRAPH
+0x9480 0x6973 #CJK UNIFIED IDEOGRAPH
+0x9481 0x7164 #CJK UNIFIED IDEOGRAPH
+0x9482 0x72FD #CJK UNIFIED IDEOGRAPH
+0x9483 0x8CB7 #CJK UNIFIED IDEOGRAPH
+0x9484 0x58F2 #CJK UNIFIED IDEOGRAPH
+0x9485 0x8CE0 #CJK UNIFIED IDEOGRAPH
+0x9486 0x966A #CJK UNIFIED IDEOGRAPH
+0x9487 0x9019 #CJK UNIFIED IDEOGRAPH
+0x9488 0x877F #CJK UNIFIED IDEOGRAPH
+0x9489 0x79E4 #CJK UNIFIED IDEOGRAPH
+0x948A 0x77E7 #CJK UNIFIED IDEOGRAPH
+0x948B 0x8429 #CJK UNIFIED IDEOGRAPH
+0x948C 0x4F2F #CJK UNIFIED IDEOGRAPH
+0x948D 0x5265 #CJK UNIFIED IDEOGRAPH
+0x948E 0x535A #CJK UNIFIED IDEOGRAPH
+0x948F 0x62CD #CJK UNIFIED IDEOGRAPH
+0x9490 0x67CF #CJK UNIFIED IDEOGRAPH
+0x9491 0x6CCA #CJK UNIFIED IDEOGRAPH
+0x9492 0x767D #CJK UNIFIED IDEOGRAPH
+0x9493 0x7B94 #CJK UNIFIED IDEOGRAPH
+0x9494 0x7C95 #CJK UNIFIED IDEOGRAPH
+0x9495 0x8236 #CJK UNIFIED IDEOGRAPH
+0x9496 0x8584 #CJK UNIFIED IDEOGRAPH
+0x9497 0x8FEB #CJK UNIFIED IDEOGRAPH
+0x9498 0x66DD #CJK UNIFIED IDEOGRAPH
+0x9499 0x6F20 #CJK UNIFIED IDEOGRAPH
+0x949A 0x7206 #CJK UNIFIED IDEOGRAPH
+0x949B 0x7E1B #CJK UNIFIED IDEOGRAPH
+0x949C 0x83AB #CJK UNIFIED IDEOGRAPH
+0x949D 0x99C1 #CJK UNIFIED IDEOGRAPH
+0x949E 0x9EA6 #CJK UNIFIED IDEOGRAPH
+0x949F 0x51FD #CJK UNIFIED IDEOGRAPH
+0x94A0 0x7BB1 #CJK UNIFIED IDEOGRAPH
+0x94A1 0x7872 #CJK UNIFIED IDEOGRAPH
+0x94A2 0x7BB8 #CJK UNIFIED IDEOGRAPH
+0x94A3 0x8087 #CJK UNIFIED IDEOGRAPH
+0x94A4 0x7B48 #CJK UNIFIED IDEOGRAPH
+0x94A5 0x6AE8 #CJK UNIFIED IDEOGRAPH
+0x94A6 0x5E61 #CJK UNIFIED IDEOGRAPH
+0x94A7 0x808C #CJK UNIFIED IDEOGRAPH
+0x94A8 0x7551 #CJK UNIFIED IDEOGRAPH
+0x94A9 0x7560 #CJK UNIFIED IDEOGRAPH
+0x94AA 0x516B #CJK UNIFIED IDEOGRAPH
+0x94AB 0x9262 #CJK UNIFIED IDEOGRAPH
+0x94AC 0x6E8C #CJK UNIFIED IDEOGRAPH
+0x94AD 0x767A #CJK UNIFIED IDEOGRAPH
+0x94AE 0x9197 #CJK UNIFIED IDEOGRAPH
+0x94AF 0x9AEA #CJK UNIFIED IDEOGRAPH
+0x94B0 0x4F10 #CJK UNIFIED IDEOGRAPH
+0x94B1 0x7F70 #CJK UNIFIED IDEOGRAPH
+0x94B2 0x629C #CJK UNIFIED IDEOGRAPH
+0x94B3 0x7B4F #CJK UNIFIED IDEOGRAPH
+0x94B4 0x95A5 #CJK UNIFIED IDEOGRAPH
+0x94B5 0x9CE9 #CJK UNIFIED IDEOGRAPH
+0x94B6 0x567A #CJK UNIFIED IDEOGRAPH
+0x94B7 0x5859 #CJK UNIFIED IDEOGRAPH
+0x94B8 0x86E4 #CJK UNIFIED IDEOGRAPH
+0x94B9 0x96BC #CJK UNIFIED IDEOGRAPH
+0x94BA 0x4F34 #CJK UNIFIED IDEOGRAPH
+0x94BB 0x5224 #CJK UNIFIED IDEOGRAPH
+0x94BC 0x534A #CJK UNIFIED IDEOGRAPH
+0x94BD 0x53CD #CJK UNIFIED IDEOGRAPH
+0x94BE 0x53DB #CJK UNIFIED IDEOGRAPH
+0x94BF 0x5E06 #CJK UNIFIED IDEOGRAPH
+0x94C0 0x642C #CJK UNIFIED IDEOGRAPH
+0x94C1 0x6591 #CJK UNIFIED IDEOGRAPH
+0x94C2 0x677F #CJK UNIFIED IDEOGRAPH
+0x94C3 0x6C3E #CJK UNIFIED IDEOGRAPH
+0x94C4 0x6C4E #CJK UNIFIED IDEOGRAPH
+0x94C5 0x7248 #CJK UNIFIED IDEOGRAPH
+0x94C6 0x72AF #CJK UNIFIED IDEOGRAPH
+0x94C7 0x73ED #CJK UNIFIED IDEOGRAPH
+0x94C8 0x7554 #CJK UNIFIED IDEOGRAPH
+0x94C9 0x7E41 #CJK UNIFIED IDEOGRAPH
+0x94CA 0x822C #CJK UNIFIED IDEOGRAPH
+0x94CB 0x85E9 #CJK UNIFIED IDEOGRAPH
+0x94CC 0x8CA9 #CJK UNIFIED IDEOGRAPH
+0x94CD 0x7BC4 #CJK UNIFIED IDEOGRAPH
+0x94CE 0x91C6 #CJK UNIFIED IDEOGRAPH
+0x94CF 0x7169 #CJK UNIFIED IDEOGRAPH
+0x94D0 0x9812 #CJK UNIFIED IDEOGRAPH
+0x94D1 0x98EF #CJK UNIFIED IDEOGRAPH
+0x94D2 0x633D #CJK UNIFIED IDEOGRAPH
+0x94D3 0x6669 #CJK UNIFIED IDEOGRAPH
+0x94D4 0x756A #CJK UNIFIED IDEOGRAPH
+0x94D5 0x76E4 #CJK UNIFIED IDEOGRAPH
+0x94D6 0x78D0 #CJK UNIFIED IDEOGRAPH
+0x94D7 0x8543 #CJK UNIFIED IDEOGRAPH
+0x94D8 0x86EE #CJK UNIFIED IDEOGRAPH
+0x94D9 0x532A #CJK UNIFIED IDEOGRAPH
+0x94DA 0x5351 #CJK UNIFIED IDEOGRAPH
+0x94DB 0x5426 #CJK UNIFIED IDEOGRAPH
+0x94DC 0x5983 #CJK UNIFIED IDEOGRAPH
+0x94DD 0x5E87 #CJK UNIFIED IDEOGRAPH
+0x94DE 0x5F7C #CJK UNIFIED IDEOGRAPH
+0x94DF 0x60B2 #CJK UNIFIED IDEOGRAPH
+0x94E0 0x6249 #CJK UNIFIED IDEOGRAPH
+0x94E1 0x6279 #CJK UNIFIED IDEOGRAPH
+0x94E2 0x62AB #CJK UNIFIED IDEOGRAPH
+0x94E3 0x6590 #CJK UNIFIED IDEOGRAPH
+0x94E4 0x6BD4 #CJK UNIFIED IDEOGRAPH
+0x94E5 0x6CCC #CJK UNIFIED IDEOGRAPH
+0x94E6 0x75B2 #CJK UNIFIED IDEOGRAPH
+0x94E7 0x76AE #CJK UNIFIED IDEOGRAPH
+0x94E8 0x7891 #CJK UNIFIED IDEOGRAPH
+0x94E9 0x79D8 #CJK UNIFIED IDEOGRAPH
+0x94EA 0x7DCB #CJK UNIFIED IDEOGRAPH
+0x94EB 0x7F77 #CJK UNIFIED IDEOGRAPH
+0x94EC 0x80A5 #CJK UNIFIED IDEOGRAPH
+0x94ED 0x88AB #CJK UNIFIED IDEOGRAPH
+0x94EE 0x8AB9 #CJK UNIFIED IDEOGRAPH
+0x94EF 0x8CBB #CJK UNIFIED IDEOGRAPH
+0x94F0 0x907F #CJK UNIFIED IDEOGRAPH
+0x94F1 0x975E #CJK UNIFIED IDEOGRAPH
+0x94F2 0x98DB #CJK UNIFIED IDEOGRAPH
+0x94F3 0x6A0B #CJK UNIFIED IDEOGRAPH
+0x94F4 0x7C38 #CJK UNIFIED IDEOGRAPH
+0x94F5 0x5099 #CJK UNIFIED IDEOGRAPH
+0x94F6 0x5C3E #CJK UNIFIED IDEOGRAPH
+0x94F7 0x5FAE #CJK UNIFIED IDEOGRAPH
+0x94F8 0x6787 #CJK UNIFIED IDEOGRAPH
+0x94F9 0x6BD8 #CJK UNIFIED IDEOGRAPH
+0x94FA 0x7435 #CJK UNIFIED IDEOGRAPH
+0x94FB 0x7709 #CJK UNIFIED IDEOGRAPH
+0x94FC 0x7F8E #CJK UNIFIED IDEOGRAPH
+0x9540 0x9F3B #CJK UNIFIED IDEOGRAPH
+0x9541 0x67CA #CJK UNIFIED IDEOGRAPH
+0x9542 0x7A17 #CJK UNIFIED IDEOGRAPH
+0x9543 0x5339 #CJK UNIFIED IDEOGRAPH
+0x9544 0x758B #CJK UNIFIED IDEOGRAPH
+0x9545 0x9AED #CJK UNIFIED IDEOGRAPH
+0x9546 0x5F66 #CJK UNIFIED IDEOGRAPH
+0x9547 0x819D #CJK UNIFIED IDEOGRAPH
+0x9548 0x83F1 #CJK UNIFIED IDEOGRAPH
+0x9549 0x8098 #CJK UNIFIED IDEOGRAPH
+0x954A 0x5F3C #CJK UNIFIED IDEOGRAPH
+0x954B 0x5FC5 #CJK UNIFIED IDEOGRAPH
+0x954C 0x7562 #CJK UNIFIED IDEOGRAPH
+0x954D 0x7B46 #CJK UNIFIED IDEOGRAPH
+0x954E 0x903C #CJK UNIFIED IDEOGRAPH
+0x954F 0x6867 #CJK UNIFIED IDEOGRAPH
+0x9550 0x59EB #CJK UNIFIED IDEOGRAPH
+0x9551 0x5A9B #CJK UNIFIED IDEOGRAPH
+0x9552 0x7D10 #CJK UNIFIED IDEOGRAPH
+0x9553 0x767E #CJK UNIFIED IDEOGRAPH
+0x9554 0x8B2C #CJK UNIFIED IDEOGRAPH
+0x9555 0x4FF5 #CJK UNIFIED IDEOGRAPH
+0x9556 0x5F6A #CJK UNIFIED IDEOGRAPH
+0x9557 0x6A19 #CJK UNIFIED IDEOGRAPH
+0x9558 0x6C37 #CJK UNIFIED IDEOGRAPH
+0x9559 0x6F02 #CJK UNIFIED IDEOGRAPH
+0x955A 0x74E2 #CJK UNIFIED IDEOGRAPH
+0x955B 0x7968 #CJK UNIFIED IDEOGRAPH
+0x955C 0x8868 #CJK UNIFIED IDEOGRAPH
+0x955D 0x8A55 #CJK UNIFIED IDEOGRAPH
+0x955E 0x8C79 #CJK UNIFIED IDEOGRAPH
+0x955F 0x5EDF #CJK UNIFIED IDEOGRAPH
+0x9560 0x63CF #CJK UNIFIED IDEOGRAPH
+0x9561 0x75C5 #CJK UNIFIED IDEOGRAPH
+0x9562 0x79D2 #CJK UNIFIED IDEOGRAPH
+0x9563 0x82D7 #CJK UNIFIED IDEOGRAPH
+0x9564 0x9328 #CJK UNIFIED IDEOGRAPH
+0x9565 0x92F2 #CJK UNIFIED IDEOGRAPH
+0x9566 0x849C #CJK UNIFIED IDEOGRAPH
+0x9567 0x86ED #CJK UNIFIED IDEOGRAPH
+0x9568 0x9C2D #CJK UNIFIED IDEOGRAPH
+0x9569 0x54C1 #CJK UNIFIED IDEOGRAPH
+0x956A 0x5F6C #CJK UNIFIED IDEOGRAPH
+0x956B 0x658C #CJK UNIFIED IDEOGRAPH
+0x956C 0x6D5C #CJK UNIFIED IDEOGRAPH
+0x956D 0x7015 #CJK UNIFIED IDEOGRAPH
+0x956E 0x8CA7 #CJK UNIFIED IDEOGRAPH
+0x956F 0x8CD3 #CJK UNIFIED IDEOGRAPH
+0x9570 0x983B #CJK UNIFIED IDEOGRAPH
+0x9571 0x654F #CJK UNIFIED IDEOGRAPH
+0x9572 0x74F6 #CJK UNIFIED IDEOGRAPH
+0x9573 0x4E0D #CJK UNIFIED IDEOGRAPH
+0x9574 0x4ED8 #CJK UNIFIED IDEOGRAPH
+0x9575 0x57E0 #CJK UNIFIED IDEOGRAPH
+0x9576 0x592B #CJK UNIFIED IDEOGRAPH
+0x9577 0x5A66 #CJK UNIFIED IDEOGRAPH
+0x9578 0x5BCC #CJK UNIFIED IDEOGRAPH
+0x9579 0x51A8 #CJK UNIFIED IDEOGRAPH
+0x957A 0x5E03 #CJK UNIFIED IDEOGRAPH
+0x957B 0x5E9C #CJK UNIFIED IDEOGRAPH
+0x957C 0x6016 #CJK UNIFIED IDEOGRAPH
+0x957D 0x6276 #CJK UNIFIED IDEOGRAPH
+0x957E 0x6577 #CJK UNIFIED IDEOGRAPH
+0x9580 0x65A7 #CJK UNIFIED IDEOGRAPH
+0x9581 0x666E #CJK UNIFIED IDEOGRAPH
+0x9582 0x6D6E #CJK UNIFIED IDEOGRAPH
+0x9583 0x7236 #CJK UNIFIED IDEOGRAPH
+0x9584 0x7B26 #CJK UNIFIED IDEOGRAPH
+0x9585 0x8150 #CJK UNIFIED IDEOGRAPH
+0x9586 0x819A #CJK UNIFIED IDEOGRAPH
+0x9587 0x8299 #CJK UNIFIED IDEOGRAPH
+0x9588 0x8B5C #CJK UNIFIED IDEOGRAPH
+0x9589 0x8CA0 #CJK UNIFIED IDEOGRAPH
+0x958A 0x8CE6 #CJK UNIFIED IDEOGRAPH
+0x958B 0x8D74 #CJK UNIFIED IDEOGRAPH
+0x958C 0x961C #CJK UNIFIED IDEOGRAPH
+0x958D 0x9644 #CJK UNIFIED IDEOGRAPH
+0x958E 0x4FAE #CJK UNIFIED IDEOGRAPH
+0x958F 0x64AB #CJK UNIFIED IDEOGRAPH
+0x9590 0x6B66 #CJK UNIFIED IDEOGRAPH
+0x9591 0x821E #CJK UNIFIED IDEOGRAPH
+0x9592 0x8461 #CJK UNIFIED IDEOGRAPH
+0x9593 0x856A #CJK UNIFIED IDEOGRAPH
+0x9594 0x90E8 #CJK UNIFIED IDEOGRAPH
+0x9595 0x5C01 #CJK UNIFIED IDEOGRAPH
+0x9596 0x6953 #CJK UNIFIED IDEOGRAPH
+0x9597 0x98A8 #CJK UNIFIED IDEOGRAPH
+0x9598 0x847A #CJK UNIFIED IDEOGRAPH
+0x9599 0x8557 #CJK UNIFIED IDEOGRAPH
+0x959A 0x4F0F #CJK UNIFIED IDEOGRAPH
+0x959B 0x526F #CJK UNIFIED IDEOGRAPH
+0x959C 0x5FA9 #CJK UNIFIED IDEOGRAPH
+0x959D 0x5E45 #CJK UNIFIED IDEOGRAPH
+0x959E 0x670D #CJK UNIFIED IDEOGRAPH
+0x959F 0x798F #CJK UNIFIED IDEOGRAPH
+0x95A0 0x8179 #CJK UNIFIED IDEOGRAPH
+0x95A1 0x8907 #CJK UNIFIED IDEOGRAPH
+0x95A2 0x8986 #CJK UNIFIED IDEOGRAPH
+0x95A3 0x6DF5 #CJK UNIFIED IDEOGRAPH
+0x95A4 0x5F17 #CJK UNIFIED IDEOGRAPH
+0x95A5 0x6255 #CJK UNIFIED IDEOGRAPH
+0x95A6 0x6CB8 #CJK UNIFIED IDEOGRAPH
+0x95A7 0x4ECF #CJK UNIFIED IDEOGRAPH
+0x95A8 0x7269 #CJK UNIFIED IDEOGRAPH
+0x95A9 0x9B92 #CJK UNIFIED IDEOGRAPH
+0x95AA 0x5206 #CJK UNIFIED IDEOGRAPH
+0x95AB 0x543B #CJK UNIFIED IDEOGRAPH
+0x95AC 0x5674 #CJK UNIFIED IDEOGRAPH
+0x95AD 0x58B3 #CJK UNIFIED IDEOGRAPH
+0x95AE 0x61A4 #CJK UNIFIED IDEOGRAPH
+0x95AF 0x626E #CJK UNIFIED IDEOGRAPH
+0x95B0 0x711A #CJK UNIFIED IDEOGRAPH
+0x95B1 0x596E #CJK UNIFIED IDEOGRAPH
+0x95B2 0x7C89 #CJK UNIFIED IDEOGRAPH
+0x95B3 0x7CDE #CJK UNIFIED IDEOGRAPH
+0x95B4 0x7D1B #CJK UNIFIED IDEOGRAPH
+0x95B5 0x96F0 #CJK UNIFIED IDEOGRAPH
+0x95B6 0x6587 #CJK UNIFIED IDEOGRAPH
+0x95B7 0x805E #CJK UNIFIED IDEOGRAPH
+0x95B8 0x4E19 #CJK UNIFIED IDEOGRAPH
+0x95B9 0x4F75 #CJK UNIFIED IDEOGRAPH
+0x95BA 0x5175 #CJK UNIFIED IDEOGRAPH
+0x95BB 0x5840 #CJK UNIFIED IDEOGRAPH
+0x95BC 0x5E63 #CJK UNIFIED IDEOGRAPH
+0x95BD 0x5E73 #CJK UNIFIED IDEOGRAPH
+0x95BE 0x5F0A #CJK UNIFIED IDEOGRAPH
+0x95BF 0x67C4 #CJK UNIFIED IDEOGRAPH
+0x95C0 0x4E26 #CJK UNIFIED IDEOGRAPH
+0x95C1 0x853D #CJK UNIFIED IDEOGRAPH
+0x95C2 0x9589 #CJK UNIFIED IDEOGRAPH
+0x95C3 0x965B #CJK UNIFIED IDEOGRAPH
+0x95C4 0x7C73 #CJK UNIFIED IDEOGRAPH
+0x95C5 0x9801 #CJK UNIFIED IDEOGRAPH
+0x95C6 0x50FB #CJK UNIFIED IDEOGRAPH
+0x95C7 0x58C1 #CJK UNIFIED IDEOGRAPH
+0x95C8 0x7656 #CJK UNIFIED IDEOGRAPH
+0x95C9 0x78A7 #CJK UNIFIED IDEOGRAPH
+0x95CA 0x5225 #CJK UNIFIED IDEOGRAPH
+0x95CB 0x77A5 #CJK UNIFIED IDEOGRAPH
+0x95CC 0x8511 #CJK UNIFIED IDEOGRAPH
+0x95CD 0x7B86 #CJK UNIFIED IDEOGRAPH
+0x95CE 0x504F #CJK UNIFIED IDEOGRAPH
+0x95CF 0x5909 #CJK UNIFIED IDEOGRAPH
+0x95D0 0x7247 #CJK UNIFIED IDEOGRAPH
+0x95D1 0x7BC7 #CJK UNIFIED IDEOGRAPH
+0x95D2 0x7DE8 #CJK UNIFIED IDEOGRAPH
+0x95D3 0x8FBA #CJK UNIFIED IDEOGRAPH
+0x95D4 0x8FD4 #CJK UNIFIED IDEOGRAPH
+0x95D5 0x904D #CJK UNIFIED IDEOGRAPH
+0x95D6 0x4FBF #CJK UNIFIED IDEOGRAPH
+0x95D7 0x52C9 #CJK UNIFIED IDEOGRAPH
+0x95D8 0x5A29 #CJK UNIFIED IDEOGRAPH
+0x95D9 0x5F01 #CJK UNIFIED IDEOGRAPH
+0x95DA 0x97AD #CJK UNIFIED IDEOGRAPH
+0x95DB 0x4FDD #CJK UNIFIED IDEOGRAPH
+0x95DC 0x8217 #CJK UNIFIED IDEOGRAPH
+0x95DD 0x92EA #CJK UNIFIED IDEOGRAPH
+0x95DE 0x5703 #CJK UNIFIED IDEOGRAPH
+0x95DF 0x6355 #CJK UNIFIED IDEOGRAPH
+0x95E0 0x6B69 #CJK UNIFIED IDEOGRAPH
+0x95E1 0x752B #CJK UNIFIED IDEOGRAPH
+0x95E2 0x88DC #CJK UNIFIED IDEOGRAPH
+0x95E3 0x8F14 #CJK UNIFIED IDEOGRAPH
+0x95E4 0x7A42 #CJK UNIFIED IDEOGRAPH
+0x95E5 0x52DF #CJK UNIFIED IDEOGRAPH
+0x95E6 0x5893 #CJK UNIFIED IDEOGRAPH
+0x95E7 0x6155 #CJK UNIFIED IDEOGRAPH
+0x95E8 0x620A #CJK UNIFIED IDEOGRAPH
+0x95E9 0x66AE #CJK UNIFIED IDEOGRAPH
+0x95EA 0x6BCD #CJK UNIFIED IDEOGRAPH
+0x95EB 0x7C3F #CJK UNIFIED IDEOGRAPH
+0x95EC 0x83E9 #CJK UNIFIED IDEOGRAPH
+0x95ED 0x5023 #CJK UNIFIED IDEOGRAPH
+0x95EE 0x4FF8 #CJK UNIFIED IDEOGRAPH
+0x95EF 0x5305 #CJK UNIFIED IDEOGRAPH
+0x95F0 0x5446 #CJK UNIFIED IDEOGRAPH
+0x95F1 0x5831 #CJK UNIFIED IDEOGRAPH
+0x95F2 0x5949 #CJK UNIFIED IDEOGRAPH
+0x95F3 0x5B9D #CJK UNIFIED IDEOGRAPH
+0x95F4 0x5CF0 #CJK UNIFIED IDEOGRAPH
+0x95F5 0x5CEF #CJK UNIFIED IDEOGRAPH
+0x95F6 0x5D29 #CJK UNIFIED IDEOGRAPH
+0x95F7 0x5E96 #CJK UNIFIED IDEOGRAPH
+0x95F8 0x62B1 #CJK UNIFIED IDEOGRAPH
+0x95F9 0x6367 #CJK UNIFIED IDEOGRAPH
+0x95FA 0x653E #CJK UNIFIED IDEOGRAPH
+0x95FB 0x65B9 #CJK UNIFIED IDEOGRAPH
+0x95FC 0x670B #CJK UNIFIED IDEOGRAPH
+0x9640 0x6CD5 #CJK UNIFIED IDEOGRAPH
+0x9641 0x6CE1 #CJK UNIFIED IDEOGRAPH
+0x9642 0x70F9 #CJK UNIFIED IDEOGRAPH
+0x9643 0x7832 #CJK UNIFIED IDEOGRAPH
+0x9644 0x7E2B #CJK UNIFIED IDEOGRAPH
+0x9645 0x80DE #CJK UNIFIED IDEOGRAPH
+0x9646 0x82B3 #CJK UNIFIED IDEOGRAPH
+0x9647 0x840C #CJK UNIFIED IDEOGRAPH
+0x9648 0x84EC #CJK UNIFIED IDEOGRAPH
+0x9649 0x8702 #CJK UNIFIED IDEOGRAPH
+0x964A 0x8912 #CJK UNIFIED IDEOGRAPH
+0x964B 0x8A2A #CJK UNIFIED IDEOGRAPH
+0x964C 0x8C4A #CJK UNIFIED IDEOGRAPH
+0x964D 0x90A6 #CJK UNIFIED IDEOGRAPH
+0x964E 0x92D2 #CJK UNIFIED IDEOGRAPH
+0x964F 0x98FD #CJK UNIFIED IDEOGRAPH
+0x9650 0x9CF3 #CJK UNIFIED IDEOGRAPH
+0x9651 0x9D6C #CJK UNIFIED IDEOGRAPH
+0x9652 0x4E4F #CJK UNIFIED IDEOGRAPH
+0x9653 0x4EA1 #CJK UNIFIED IDEOGRAPH
+0x9654 0x508D #CJK UNIFIED IDEOGRAPH
+0x9655 0x5256 #CJK UNIFIED IDEOGRAPH
+0x9656 0x574A #CJK UNIFIED IDEOGRAPH
+0x9657 0x59A8 #CJK UNIFIED IDEOGRAPH
+0x9658 0x5E3D #CJK UNIFIED IDEOGRAPH
+0x9659 0x5FD8 #CJK UNIFIED IDEOGRAPH
+0x965A 0x5FD9 #CJK UNIFIED IDEOGRAPH
+0x965B 0x623F #CJK UNIFIED IDEOGRAPH
+0x965C 0x66B4 #CJK UNIFIED IDEOGRAPH
+0x965D 0x671B #CJK UNIFIED IDEOGRAPH
+0x965E 0x67D0 #CJK UNIFIED IDEOGRAPH
+0x965F 0x68D2 #CJK UNIFIED IDEOGRAPH
+0x9660 0x5192 #CJK UNIFIED IDEOGRAPH
+0x9661 0x7D21 #CJK UNIFIED IDEOGRAPH
+0x9662 0x80AA #CJK UNIFIED IDEOGRAPH
+0x9663 0x81A8 #CJK UNIFIED IDEOGRAPH
+0x9664 0x8B00 #CJK UNIFIED IDEOGRAPH
+0x9665 0x8C8C #CJK UNIFIED IDEOGRAPH
+0x9666 0x8CBF #CJK UNIFIED IDEOGRAPH
+0x9667 0x927E #CJK UNIFIED IDEOGRAPH
+0x9668 0x9632 #CJK UNIFIED IDEOGRAPH
+0x9669 0x5420 #CJK UNIFIED IDEOGRAPH
+0x966A 0x982C #CJK UNIFIED IDEOGRAPH
+0x966B 0x5317 #CJK UNIFIED IDEOGRAPH
+0x966C 0x50D5 #CJK UNIFIED IDEOGRAPH
+0x966D 0x535C #CJK UNIFIED IDEOGRAPH
+0x966E 0x58A8 #CJK UNIFIED IDEOGRAPH
+0x966F 0x64B2 #CJK UNIFIED IDEOGRAPH
+0x9670 0x6734 #CJK UNIFIED IDEOGRAPH
+0x9671 0x7267 #CJK UNIFIED IDEOGRAPH
+0x9672 0x7766 #CJK UNIFIED IDEOGRAPH
+0x9673 0x7A46 #CJK UNIFIED IDEOGRAPH
+0x9674 0x91E6 #CJK UNIFIED IDEOGRAPH
+0x9675 0x52C3 #CJK UNIFIED IDEOGRAPH
+0x9676 0x6CA1 #CJK UNIFIED IDEOGRAPH
+0x9677 0x6B86 #CJK UNIFIED IDEOGRAPH
+0x9678 0x5800 #CJK UNIFIED IDEOGRAPH
+0x9679 0x5E4C #CJK UNIFIED IDEOGRAPH
+0x967A 0x5954 #CJK UNIFIED IDEOGRAPH
+0x967B 0x672C #CJK UNIFIED IDEOGRAPH
+0x967C 0x7FFB #CJK UNIFIED IDEOGRAPH
+0x967D 0x51E1 #CJK UNIFIED IDEOGRAPH
+0x967E 0x76C6 #CJK UNIFIED IDEOGRAPH
+0x9680 0x6469 #CJK UNIFIED IDEOGRAPH
+0x9681 0x78E8 #CJK UNIFIED IDEOGRAPH
+0x9682 0x9B54 #CJK UNIFIED IDEOGRAPH
+0x9683 0x9EBB #CJK UNIFIED IDEOGRAPH
+0x9684 0x57CB #CJK UNIFIED IDEOGRAPH
+0x9685 0x59B9 #CJK UNIFIED IDEOGRAPH
+0x9686 0x6627 #CJK UNIFIED IDEOGRAPH
+0x9687 0x679A #CJK UNIFIED IDEOGRAPH
+0x9688 0x6BCE #CJK UNIFIED IDEOGRAPH
+0x9689 0x54E9 #CJK UNIFIED IDEOGRAPH
+0x968A 0x69D9 #CJK UNIFIED IDEOGRAPH
+0x968B 0x5E55 #CJK UNIFIED IDEOGRAPH
+0x968C 0x819C #CJK UNIFIED IDEOGRAPH
+0x968D 0x6795 #CJK UNIFIED IDEOGRAPH
+0x968E 0x9BAA #CJK UNIFIED IDEOGRAPH
+0x968F 0x67FE #CJK UNIFIED IDEOGRAPH
+0x9690 0x9C52 #CJK UNIFIED IDEOGRAPH
+0x9691 0x685D #CJK UNIFIED IDEOGRAPH
+0x9692 0x4EA6 #CJK UNIFIED IDEOGRAPH
+0x9693 0x4FE3 #CJK UNIFIED IDEOGRAPH
+0x9694 0x53C8 #CJK UNIFIED IDEOGRAPH
+0x9695 0x62B9 #CJK UNIFIED IDEOGRAPH
+0x9696 0x672B #CJK UNIFIED IDEOGRAPH
+0x9697 0x6CAB #CJK UNIFIED IDEOGRAPH
+0x9698 0x8FC4 #CJK UNIFIED IDEOGRAPH
+0x9699 0x4FAD #CJK UNIFIED IDEOGRAPH
+0x969A 0x7E6D #CJK UNIFIED IDEOGRAPH
+0x969B 0x9EBF #CJK UNIFIED IDEOGRAPH
+0x969C 0x4E07 #CJK UNIFIED IDEOGRAPH
+0x969D 0x6162 #CJK UNIFIED IDEOGRAPH
+0x969E 0x6E80 #CJK UNIFIED IDEOGRAPH
+0x969F 0x6F2B #CJK UNIFIED IDEOGRAPH
+0x96A0 0x8513 #CJK UNIFIED IDEOGRAPH
+0x96A1 0x5473 #CJK UNIFIED IDEOGRAPH
+0x96A2 0x672A #CJK UNIFIED IDEOGRAPH
+0x96A3 0x9B45 #CJK UNIFIED IDEOGRAPH
+0x96A4 0x5DF3 #CJK UNIFIED IDEOGRAPH
+0x96A5 0x7B95 #CJK UNIFIED IDEOGRAPH
+0x96A6 0x5CAC #CJK UNIFIED IDEOGRAPH
+0x96A7 0x5BC6 #CJK UNIFIED IDEOGRAPH
+0x96A8 0x871C #CJK UNIFIED IDEOGRAPH
+0x96A9 0x6E4A #CJK UNIFIED IDEOGRAPH
+0x96AA 0x84D1 #CJK UNIFIED IDEOGRAPH
+0x96AB 0x7A14 #CJK UNIFIED IDEOGRAPH
+0x96AC 0x8108 #CJK UNIFIED IDEOGRAPH
+0x96AD 0x5999 #CJK UNIFIED IDEOGRAPH
+0x96AE 0x7C8D #CJK UNIFIED IDEOGRAPH
+0x96AF 0x6C11 #CJK UNIFIED IDEOGRAPH
+0x96B0 0x7720 #CJK UNIFIED IDEOGRAPH
+0x96B1 0x52D9 #CJK UNIFIED IDEOGRAPH
+0x96B2 0x5922 #CJK UNIFIED IDEOGRAPH
+0x96B3 0x7121 #CJK UNIFIED IDEOGRAPH
+0x96B4 0x725F #CJK UNIFIED IDEOGRAPH
+0x96B5 0x77DB #CJK UNIFIED IDEOGRAPH
+0x96B6 0x9727 #CJK UNIFIED IDEOGRAPH
+0x96B7 0x9D61 #CJK UNIFIED IDEOGRAPH
+0x96B8 0x690B #CJK UNIFIED IDEOGRAPH
+0x96B9 0x5A7F #CJK UNIFIED IDEOGRAPH
+0x96BA 0x5A18 #CJK UNIFIED IDEOGRAPH
+0x96BB 0x51A5 #CJK UNIFIED IDEOGRAPH
+0x96BC 0x540D #CJK UNIFIED IDEOGRAPH
+0x96BD 0x547D #CJK UNIFIED IDEOGRAPH
+0x96BE 0x660E #CJK UNIFIED IDEOGRAPH
+0x96BF 0x76DF #CJK UNIFIED IDEOGRAPH
+0x96C0 0x8FF7 #CJK UNIFIED IDEOGRAPH
+0x96C1 0x9298 #CJK UNIFIED IDEOGRAPH
+0x96C2 0x9CF4 #CJK UNIFIED IDEOGRAPH
+0x96C3 0x59EA #CJK UNIFIED IDEOGRAPH
+0x96C4 0x725D #CJK UNIFIED IDEOGRAPH
+0x96C5 0x6EC5 #CJK UNIFIED IDEOGRAPH
+0x96C6 0x514D #CJK UNIFIED IDEOGRAPH
+0x96C7 0x68C9 #CJK UNIFIED IDEOGRAPH
+0x96C8 0x7DBF #CJK UNIFIED IDEOGRAPH
+0x96C9 0x7DEC #CJK UNIFIED IDEOGRAPH
+0x96CA 0x9762 #CJK UNIFIED IDEOGRAPH
+0x96CB 0x9EBA #CJK UNIFIED IDEOGRAPH
+0x96CC 0x6478 #CJK UNIFIED IDEOGRAPH
+0x96CD 0x6A21 #CJK UNIFIED IDEOGRAPH
+0x96CE 0x8302 #CJK UNIFIED IDEOGRAPH
+0x96CF 0x5984 #CJK UNIFIED IDEOGRAPH
+0x96D0 0x5B5F #CJK UNIFIED IDEOGRAPH
+0x96D1 0x6BDB #CJK UNIFIED IDEOGRAPH
+0x96D2 0x731B #CJK UNIFIED IDEOGRAPH
+0x96D3 0x76F2 #CJK UNIFIED IDEOGRAPH
+0x96D4 0x7DB2 #CJK UNIFIED IDEOGRAPH
+0x96D5 0x8017 #CJK UNIFIED IDEOGRAPH
+0x96D6 0x8499 #CJK UNIFIED IDEOGRAPH
+0x96D7 0x5132 #CJK UNIFIED IDEOGRAPH
+0x96D8 0x6728 #CJK UNIFIED IDEOGRAPH
+0x96D9 0x9ED9 #CJK UNIFIED IDEOGRAPH
+0x96DA 0x76EE #CJK UNIFIED IDEOGRAPH
+0x96DB 0x6762 #CJK UNIFIED IDEOGRAPH
+0x96DC 0x52FF #CJK UNIFIED IDEOGRAPH
+0x96DD 0x9905 #CJK UNIFIED IDEOGRAPH
+0x96DE 0x5C24 #CJK UNIFIED IDEOGRAPH
+0x96DF 0x623B #CJK UNIFIED IDEOGRAPH
+0x96E0 0x7C7E #CJK UNIFIED IDEOGRAPH
+0x96E1 0x8CB0 #CJK UNIFIED IDEOGRAPH
+0x96E2 0x554F #CJK UNIFIED IDEOGRAPH
+0x96E3 0x60B6 #CJK UNIFIED IDEOGRAPH
+0x96E4 0x7D0B #CJK UNIFIED IDEOGRAPH
+0x96E5 0x9580 #CJK UNIFIED IDEOGRAPH
+0x96E6 0x5301 #CJK UNIFIED IDEOGRAPH
+0x96E7 0x4E5F #CJK UNIFIED IDEOGRAPH
+0x96E8 0x51B6 #CJK UNIFIED IDEOGRAPH
+0x96E9 0x591C #CJK UNIFIED IDEOGRAPH
+0x96EA 0x723A #CJK UNIFIED IDEOGRAPH
+0x96EB 0x8036 #CJK UNIFIED IDEOGRAPH
+0x96EC 0x91CE #CJK UNIFIED IDEOGRAPH
+0x96ED 0x5F25 #CJK UNIFIED IDEOGRAPH
+0x96EE 0x77E2 #CJK UNIFIED IDEOGRAPH
+0x96EF 0x5384 #CJK UNIFIED IDEOGRAPH
+0x96F0 0x5F79 #CJK UNIFIED IDEOGRAPH
+0x96F1 0x7D04 #CJK UNIFIED IDEOGRAPH
+0x96F2 0x85AC #CJK UNIFIED IDEOGRAPH
+0x96F3 0x8A33 #CJK UNIFIED IDEOGRAPH
+0x96F4 0x8E8D #CJK UNIFIED IDEOGRAPH
+0x96F5 0x9756 #CJK UNIFIED IDEOGRAPH
+0x96F6 0x67F3 #CJK UNIFIED IDEOGRAPH
+0x96F7 0x85AE #CJK UNIFIED IDEOGRAPH
+0x96F8 0x9453 #CJK UNIFIED IDEOGRAPH
+0x96F9 0x6109 #CJK UNIFIED IDEOGRAPH
+0x96FA 0x6108 #CJK UNIFIED IDEOGRAPH
+0x96FB 0x6CB9 #CJK UNIFIED IDEOGRAPH
+0x96FC 0x7652 #CJK UNIFIED IDEOGRAPH
+0x9740 0x8AED #CJK UNIFIED IDEOGRAPH
+0x9741 0x8F38 #CJK UNIFIED IDEOGRAPH
+0x9742 0x552F #CJK UNIFIED IDEOGRAPH
+0x9743 0x4F51 #CJK UNIFIED IDEOGRAPH
+0x9744 0x512A #CJK UNIFIED IDEOGRAPH
+0x9745 0x52C7 #CJK UNIFIED IDEOGRAPH
+0x9746 0x53CB #CJK UNIFIED IDEOGRAPH
+0x9747 0x5BA5 #CJK UNIFIED IDEOGRAPH
+0x9748 0x5E7D #CJK UNIFIED IDEOGRAPH
+0x9749 0x60A0 #CJK UNIFIED IDEOGRAPH
+0x974A 0x6182 #CJK UNIFIED IDEOGRAPH
+0x974B 0x63D6 #CJK UNIFIED IDEOGRAPH
+0x974C 0x6709 #CJK UNIFIED IDEOGRAPH
+0x974D 0x67DA #CJK UNIFIED IDEOGRAPH
+0x974E 0x6E67 #CJK UNIFIED IDEOGRAPH
+0x974F 0x6D8C #CJK UNIFIED IDEOGRAPH
+0x9750 0x7336 #CJK UNIFIED IDEOGRAPH
+0x9751 0x7337 #CJK UNIFIED IDEOGRAPH
+0x9752 0x7531 #CJK UNIFIED IDEOGRAPH
+0x9753 0x7950 #CJK UNIFIED IDEOGRAPH
+0x9754 0x88D5 #CJK UNIFIED IDEOGRAPH
+0x9755 0x8A98 #CJK UNIFIED IDEOGRAPH
+0x9756 0x904A #CJK UNIFIED IDEOGRAPH
+0x9757 0x9091 #CJK UNIFIED IDEOGRAPH
+0x9758 0x90F5 #CJK UNIFIED IDEOGRAPH
+0x9759 0x96C4 #CJK UNIFIED IDEOGRAPH
+0x975A 0x878D #CJK UNIFIED IDEOGRAPH
+0x975B 0x5915 #CJK UNIFIED IDEOGRAPH
+0x975C 0x4E88 #CJK UNIFIED IDEOGRAPH
+0x975D 0x4F59 #CJK UNIFIED IDEOGRAPH
+0x975E 0x4E0E #CJK UNIFIED IDEOGRAPH
+0x975F 0x8A89 #CJK UNIFIED IDEOGRAPH
+0x9760 0x8F3F #CJK UNIFIED IDEOGRAPH
+0x9761 0x9810 #CJK UNIFIED IDEOGRAPH
+0x9762 0x50AD #CJK UNIFIED IDEOGRAPH
+0x9763 0x5E7C #CJK UNIFIED IDEOGRAPH
+0x9764 0x5996 #CJK UNIFIED IDEOGRAPH
+0x9765 0x5BB9 #CJK UNIFIED IDEOGRAPH
+0x9766 0x5EB8 #CJK UNIFIED IDEOGRAPH
+0x9767 0x63DA #CJK UNIFIED IDEOGRAPH
+0x9768 0x63FA #CJK UNIFIED IDEOGRAPH
+0x9769 0x64C1 #CJK UNIFIED IDEOGRAPH
+0x976A 0x66DC #CJK UNIFIED IDEOGRAPH
+0x976B 0x694A #CJK UNIFIED IDEOGRAPH
+0x976C 0x69D8 #CJK UNIFIED IDEOGRAPH
+0x976D 0x6D0B #CJK UNIFIED IDEOGRAPH
+0x976E 0x6EB6 #CJK UNIFIED IDEOGRAPH
+0x976F 0x7194 #CJK UNIFIED IDEOGRAPH
+0x9770 0x7528 #CJK UNIFIED IDEOGRAPH
+0x9771 0x7AAF #CJK UNIFIED IDEOGRAPH
+0x9772 0x7F8A #CJK UNIFIED IDEOGRAPH
+0x9773 0x8000 #CJK UNIFIED IDEOGRAPH
+0x9774 0x8449 #CJK UNIFIED IDEOGRAPH
+0x9775 0x84C9 #CJK UNIFIED IDEOGRAPH
+0x9776 0x8981 #CJK UNIFIED IDEOGRAPH
+0x9777 0x8B21 #CJK UNIFIED IDEOGRAPH
+0x9778 0x8E0A #CJK UNIFIED IDEOGRAPH
+0x9779 0x9065 #CJK UNIFIED IDEOGRAPH
+0x977A 0x967D #CJK UNIFIED IDEOGRAPH
+0x977B 0x990A #CJK UNIFIED IDEOGRAPH
+0x977C 0x617E #CJK UNIFIED IDEOGRAPH
+0x977D 0x6291 #CJK UNIFIED IDEOGRAPH
+0x977E 0x6B32 #CJK UNIFIED IDEOGRAPH
+0x9780 0x6C83 #CJK UNIFIED IDEOGRAPH
+0x9781 0x6D74 #CJK UNIFIED IDEOGRAPH
+0x9782 0x7FCC #CJK UNIFIED IDEOGRAPH
+0x9783 0x7FFC #CJK UNIFIED IDEOGRAPH
+0x9784 0x6DC0 #CJK UNIFIED IDEOGRAPH
+0x9785 0x7F85 #CJK UNIFIED IDEOGRAPH
+0x9786 0x87BA #CJK UNIFIED IDEOGRAPH
+0x9787 0x88F8 #CJK UNIFIED IDEOGRAPH
+0x9788 0x6765 #CJK UNIFIED IDEOGRAPH
+0x9789 0x83B1 #CJK UNIFIED IDEOGRAPH
+0x978A 0x983C #CJK UNIFIED IDEOGRAPH
+0x978B 0x96F7 #CJK UNIFIED IDEOGRAPH
+0x978C 0x6D1B #CJK UNIFIED IDEOGRAPH
+0x978D 0x7D61 #CJK UNIFIED IDEOGRAPH
+0x978E 0x843D #CJK UNIFIED IDEOGRAPH
+0x978F 0x916A #CJK UNIFIED IDEOGRAPH
+0x9790 0x4E71 #CJK UNIFIED IDEOGRAPH
+0x9791 0x5375 #CJK UNIFIED IDEOGRAPH
+0x9792 0x5D50 #CJK UNIFIED IDEOGRAPH
+0x9793 0x6B04 #CJK UNIFIED IDEOGRAPH
+0x9794 0x6FEB #CJK UNIFIED IDEOGRAPH
+0x9795 0x85CD #CJK UNIFIED IDEOGRAPH
+0x9796 0x862D #CJK UNIFIED IDEOGRAPH
+0x9797 0x89A7 #CJK UNIFIED IDEOGRAPH
+0x9798 0x5229 #CJK UNIFIED IDEOGRAPH
+0x9799 0x540F #CJK UNIFIED IDEOGRAPH
+0x979A 0x5C65 #CJK UNIFIED IDEOGRAPH
+0x979B 0x674E #CJK UNIFIED IDEOGRAPH
+0x979C 0x68A8 #CJK UNIFIED IDEOGRAPH
+0x979D 0x7406 #CJK UNIFIED IDEOGRAPH
+0x979E 0x7483 #CJK UNIFIED IDEOGRAPH
+0x979F 0x75E2 #CJK UNIFIED IDEOGRAPH
+0x97A0 0x88CF #CJK UNIFIED IDEOGRAPH
+0x97A1 0x88E1 #CJK UNIFIED IDEOGRAPH
+0x97A2 0x91CC #CJK UNIFIED IDEOGRAPH
+0x97A3 0x96E2 #CJK UNIFIED IDEOGRAPH
+0x97A4 0x9678 #CJK UNIFIED IDEOGRAPH
+0x97A5 0x5F8B #CJK UNIFIED IDEOGRAPH
+0x97A6 0x7387 #CJK UNIFIED IDEOGRAPH
+0x97A7 0x7ACB #CJK UNIFIED IDEOGRAPH
+0x97A8 0x844E #CJK UNIFIED IDEOGRAPH
+0x97A9 0x63A0 #CJK UNIFIED IDEOGRAPH
+0x97AA 0x7565 #CJK UNIFIED IDEOGRAPH
+0x97AB 0x5289 #CJK UNIFIED IDEOGRAPH
+0x97AC 0x6D41 #CJK UNIFIED IDEOGRAPH
+0x97AD 0x6E9C #CJK UNIFIED IDEOGRAPH
+0x97AE 0x7409 #CJK UNIFIED IDEOGRAPH
+0x97AF 0x7559 #CJK UNIFIED IDEOGRAPH
+0x97B0 0x786B #CJK UNIFIED IDEOGRAPH
+0x97B1 0x7C92 #CJK UNIFIED IDEOGRAPH
+0x97B2 0x9686 #CJK UNIFIED IDEOGRAPH
+0x97B3 0x7ADC #CJK UNIFIED IDEOGRAPH
+0x97B4 0x9F8D #CJK UNIFIED IDEOGRAPH
+0x97B5 0x4FB6 #CJK UNIFIED IDEOGRAPH
+0x97B6 0x616E #CJK UNIFIED IDEOGRAPH
+0x97B7 0x65C5 #CJK UNIFIED IDEOGRAPH
+0x97B8 0x865C #CJK UNIFIED IDEOGRAPH
+0x97B9 0x4E86 #CJK UNIFIED IDEOGRAPH
+0x97BA 0x4EAE #CJK UNIFIED IDEOGRAPH
+0x97BB 0x50DA #CJK UNIFIED IDEOGRAPH
+0x97BC 0x4E21 #CJK UNIFIED IDEOGRAPH
+0x97BD 0x51CC #CJK UNIFIED IDEOGRAPH
+0x97BE 0x5BEE #CJK UNIFIED IDEOGRAPH
+0x97BF 0x6599 #CJK UNIFIED IDEOGRAPH
+0x97C0 0x6881 #CJK UNIFIED IDEOGRAPH
+0x97C1 0x6DBC #CJK UNIFIED IDEOGRAPH
+0x97C2 0x731F #CJK UNIFIED IDEOGRAPH
+0x97C3 0x7642 #CJK UNIFIED IDEOGRAPH
+0x97C4 0x77AD #CJK UNIFIED IDEOGRAPH
+0x97C5 0x7A1C #CJK UNIFIED IDEOGRAPH
+0x97C6 0x7CE7 #CJK UNIFIED IDEOGRAPH
+0x97C7 0x826F #CJK UNIFIED IDEOGRAPH
+0x97C8 0x8AD2 #CJK UNIFIED IDEOGRAPH
+0x97C9 0x907C #CJK UNIFIED IDEOGRAPH
+0x97CA 0x91CF #CJK UNIFIED IDEOGRAPH
+0x97CB 0x9675 #CJK UNIFIED IDEOGRAPH
+0x97CC 0x9818 #CJK UNIFIED IDEOGRAPH
+0x97CD 0x529B #CJK UNIFIED IDEOGRAPH
+0x97CE 0x7DD1 #CJK UNIFIED IDEOGRAPH
+0x97CF 0x502B #CJK UNIFIED IDEOGRAPH
+0x97D0 0x5398 #CJK UNIFIED IDEOGRAPH
+0x97D1 0x6797 #CJK UNIFIED IDEOGRAPH
+0x97D2 0x6DCB #CJK UNIFIED IDEOGRAPH
+0x97D3 0x71D0 #CJK UNIFIED IDEOGRAPH
+0x97D4 0x7433 #CJK UNIFIED IDEOGRAPH
+0x97D5 0x81E8 #CJK UNIFIED IDEOGRAPH
+0x97D6 0x8F2A #CJK UNIFIED IDEOGRAPH
+0x97D7 0x96A3 #CJK UNIFIED IDEOGRAPH
+0x97D8 0x9C57 #CJK UNIFIED IDEOGRAPH
+0x97D9 0x9E9F #CJK UNIFIED IDEOGRAPH
+0x97DA 0x7460 #CJK UNIFIED IDEOGRAPH
+0x97DB 0x5841 #CJK UNIFIED IDEOGRAPH
+0x97DC 0x6D99 #CJK UNIFIED IDEOGRAPH
+0x97DD 0x7D2F #CJK UNIFIED IDEOGRAPH
+0x97DE 0x985E #CJK UNIFIED IDEOGRAPH
+0x97DF 0x4EE4 #CJK UNIFIED IDEOGRAPH
+0x97E0 0x4F36 #CJK UNIFIED IDEOGRAPH
+0x97E1 0x4F8B #CJK UNIFIED IDEOGRAPH
+0x97E2 0x51B7 #CJK UNIFIED IDEOGRAPH
+0x97E3 0x52B1 #CJK UNIFIED IDEOGRAPH
+0x97E4 0x5DBA #CJK UNIFIED IDEOGRAPH
+0x97E5 0x601C #CJK UNIFIED IDEOGRAPH
+0x97E6 0x73B2 #CJK UNIFIED IDEOGRAPH
+0x97E7 0x793C #CJK UNIFIED IDEOGRAPH
+0x97E8 0x82D3 #CJK UNIFIED IDEOGRAPH
+0x97E9 0x9234 #CJK UNIFIED IDEOGRAPH
+0x97EA 0x96B7 #CJK UNIFIED IDEOGRAPH
+0x97EB 0x96F6 #CJK UNIFIED IDEOGRAPH
+0x97EC 0x970A #CJK UNIFIED IDEOGRAPH
+0x97ED 0x9E97 #CJK UNIFIED IDEOGRAPH
+0x97EE 0x9F62 #CJK UNIFIED IDEOGRAPH
+0x97EF 0x66A6 #CJK UNIFIED IDEOGRAPH
+0x97F0 0x6B74 #CJK UNIFIED IDEOGRAPH
+0x97F1 0x5217 #CJK UNIFIED IDEOGRAPH
+0x97F2 0x52A3 #CJK UNIFIED IDEOGRAPH
+0x97F3 0x70C8 #CJK UNIFIED IDEOGRAPH
+0x97F4 0x88C2 #CJK UNIFIED IDEOGRAPH
+0x97F5 0x5EC9 #CJK UNIFIED IDEOGRAPH
+0x97F6 0x604B #CJK UNIFIED IDEOGRAPH
+0x97F7 0x6190 #CJK UNIFIED IDEOGRAPH
+0x97F8 0x6F23 #CJK UNIFIED IDEOGRAPH
+0x97F9 0x7149 #CJK UNIFIED IDEOGRAPH
+0x97FA 0x7C3E #CJK UNIFIED IDEOGRAPH
+0x97FB 0x7DF4 #CJK UNIFIED IDEOGRAPH
+0x97FC 0x806F #CJK UNIFIED IDEOGRAPH
+0x9840 0x84EE #CJK UNIFIED IDEOGRAPH
+0x9841 0x9023 #CJK UNIFIED IDEOGRAPH
+0x9842 0x932C #CJK UNIFIED IDEOGRAPH
+0x9843 0x5442 #CJK UNIFIED IDEOGRAPH
+0x9844 0x9B6F #CJK UNIFIED IDEOGRAPH
+0x9845 0x6AD3 #CJK UNIFIED IDEOGRAPH
+0x9846 0x7089 #CJK UNIFIED IDEOGRAPH
+0x9847 0x8CC2 #CJK UNIFIED IDEOGRAPH
+0x9848 0x8DEF #CJK UNIFIED IDEOGRAPH
+0x9849 0x9732 #CJK UNIFIED IDEOGRAPH
+0x984A 0x52B4 #CJK UNIFIED IDEOGRAPH
+0x984B 0x5A41 #CJK UNIFIED IDEOGRAPH
+0x984C 0x5ECA #CJK UNIFIED IDEOGRAPH
+0x984D 0x5F04 #CJK UNIFIED IDEOGRAPH
+0x984E 0x6717 #CJK UNIFIED IDEOGRAPH
+0x984F 0x697C #CJK UNIFIED IDEOGRAPH
+0x9850 0x6994 #CJK UNIFIED IDEOGRAPH
+0x9851 0x6D6A #CJK UNIFIED IDEOGRAPH
+0x9852 0x6F0F #CJK UNIFIED IDEOGRAPH
+0x9853 0x7262 #CJK UNIFIED IDEOGRAPH
+0x9854 0x72FC #CJK UNIFIED IDEOGRAPH
+0x9855 0x7BED #CJK UNIFIED IDEOGRAPH
+0x9856 0x8001 #CJK UNIFIED IDEOGRAPH
+0x9857 0x807E #CJK UNIFIED IDEOGRAPH
+0x9858 0x874B #CJK UNIFIED IDEOGRAPH
+0x9859 0x90CE #CJK UNIFIED IDEOGRAPH
+0x985A 0x516D #CJK UNIFIED IDEOGRAPH
+0x985B 0x9E93 #CJK UNIFIED IDEOGRAPH
+0x985C 0x7984 #CJK UNIFIED IDEOGRAPH
+0x985D 0x808B #CJK UNIFIED IDEOGRAPH
+0x985E 0x9332 #CJK UNIFIED IDEOGRAPH
+0x985F 0x8AD6 #CJK UNIFIED IDEOGRAPH
+0x9860 0x502D #CJK UNIFIED IDEOGRAPH
+0x9861 0x548C #CJK UNIFIED IDEOGRAPH
+0x9862 0x8A71 #CJK UNIFIED IDEOGRAPH
+0x9863 0x6B6A #CJK UNIFIED IDEOGRAPH
+0x9864 0x8CC4 #CJK UNIFIED IDEOGRAPH
+0x9865 0x8107 #CJK UNIFIED IDEOGRAPH
+0x9866 0x60D1 #CJK UNIFIED IDEOGRAPH
+0x9867 0x67A0 #CJK UNIFIED IDEOGRAPH
+0x9868 0x9DF2 #CJK UNIFIED IDEOGRAPH
+0x9869 0x4E99 #CJK UNIFIED IDEOGRAPH
+0x986A 0x4E98 #CJK UNIFIED IDEOGRAPH
+0x986B 0x9C10 #CJK UNIFIED IDEOGRAPH
+0x986C 0x8A6B #CJK UNIFIED IDEOGRAPH
+0x986D 0x85C1 #CJK UNIFIED IDEOGRAPH
+0x986E 0x8568 #CJK UNIFIED IDEOGRAPH
+0x986F 0x6900 #CJK UNIFIED IDEOGRAPH
+0x9870 0x6E7E #CJK UNIFIED IDEOGRAPH
+0x9871 0x7897 #CJK UNIFIED IDEOGRAPH
+0x9872 0x8155 #CJK UNIFIED IDEOGRAPH
+0x989F 0x5F0C #CJK UNIFIED IDEOGRAPH
+0x98A0 0x4E10 #CJK UNIFIED IDEOGRAPH
+0x98A1 0x4E15 #CJK UNIFIED IDEOGRAPH
+0x98A2 0x4E2A #CJK UNIFIED IDEOGRAPH
+0x98A3 0x4E31 #CJK UNIFIED IDEOGRAPH
+0x98A4 0x4E36 #CJK UNIFIED IDEOGRAPH
+0x98A5 0x4E3C #CJK UNIFIED IDEOGRAPH
+0x98A6 0x4E3F #CJK UNIFIED IDEOGRAPH
+0x98A7 0x4E42 #CJK UNIFIED IDEOGRAPH
+0x98A8 0x4E56 #CJK UNIFIED IDEOGRAPH
+0x98A9 0x4E58 #CJK UNIFIED IDEOGRAPH
+0x98AA 0x4E82 #CJK UNIFIED IDEOGRAPH
+0x98AB 0x4E85 #CJK UNIFIED IDEOGRAPH
+0x98AC 0x8C6B #CJK UNIFIED IDEOGRAPH
+0x98AD 0x4E8A #CJK UNIFIED IDEOGRAPH
+0x98AE 0x8212 #CJK UNIFIED IDEOGRAPH
+0x98AF 0x5F0D #CJK UNIFIED IDEOGRAPH
+0x98B0 0x4E8E #CJK UNIFIED IDEOGRAPH
+0x98B1 0x4E9E #CJK UNIFIED IDEOGRAPH
+0x98B2 0x4E9F #CJK UNIFIED IDEOGRAPH
+0x98B3 0x4EA0 #CJK UNIFIED IDEOGRAPH
+0x98B4 0x4EA2 #CJK UNIFIED IDEOGRAPH
+0x98B5 0x4EB0 #CJK UNIFIED IDEOGRAPH
+0x98B6 0x4EB3 #CJK UNIFIED IDEOGRAPH
+0x98B7 0x4EB6 #CJK UNIFIED IDEOGRAPH
+0x98B8 0x4ECE #CJK UNIFIED IDEOGRAPH
+0x98B9 0x4ECD #CJK UNIFIED IDEOGRAPH
+0x98BA 0x4EC4 #CJK UNIFIED IDEOGRAPH
+0x98BB 0x4EC6 #CJK UNIFIED IDEOGRAPH
+0x98BC 0x4EC2 #CJK UNIFIED IDEOGRAPH
+0x98BD 0x4ED7 #CJK UNIFIED IDEOGRAPH
+0x98BE 0x4EDE #CJK UNIFIED IDEOGRAPH
+0x98BF 0x4EED #CJK UNIFIED IDEOGRAPH
+0x98C0 0x4EDF #CJK UNIFIED IDEOGRAPH
+0x98C1 0x4EF7 #CJK UNIFIED IDEOGRAPH
+0x98C2 0x4F09 #CJK UNIFIED IDEOGRAPH
+0x98C3 0x4F5A #CJK UNIFIED IDEOGRAPH
+0x98C4 0x4F30 #CJK UNIFIED IDEOGRAPH
+0x98C5 0x4F5B #CJK UNIFIED IDEOGRAPH
+0x98C6 0x4F5D #CJK UNIFIED IDEOGRAPH
+0x98C7 0x4F57 #CJK UNIFIED IDEOGRAPH
+0x98C8 0x4F47 #CJK UNIFIED IDEOGRAPH
+0x98C9 0x4F76 #CJK UNIFIED IDEOGRAPH
+0x98CA 0x4F88 #CJK UNIFIED IDEOGRAPH
+0x98CB 0x4F8F #CJK UNIFIED IDEOGRAPH
+0x98CC 0x4F98 #CJK UNIFIED IDEOGRAPH
+0x98CD 0x4F7B #CJK UNIFIED IDEOGRAPH
+0x98CE 0x4F69 #CJK UNIFIED IDEOGRAPH
+0x98CF 0x4F70 #CJK UNIFIED IDEOGRAPH
+0x98D0 0x4F91 #CJK UNIFIED IDEOGRAPH
+0x98D1 0x4F6F #CJK UNIFIED IDEOGRAPH
+0x98D2 0x4F86 #CJK UNIFIED IDEOGRAPH
+0x98D3 0x4F96 #CJK UNIFIED IDEOGRAPH
+0x98D4 0x5118 #CJK UNIFIED IDEOGRAPH
+0x98D5 0x4FD4 #CJK UNIFIED IDEOGRAPH
+0x98D6 0x4FDF #CJK UNIFIED IDEOGRAPH
+0x98D7 0x4FCE #CJK UNIFIED IDEOGRAPH
+0x98D8 0x4FD8 #CJK UNIFIED IDEOGRAPH
+0x98D9 0x4FDB #CJK UNIFIED IDEOGRAPH
+0x98DA 0x4FD1 #CJK UNIFIED IDEOGRAPH
+0x98DB 0x4FDA #CJK UNIFIED IDEOGRAPH
+0x98DC 0x4FD0 #CJK UNIFIED IDEOGRAPH
+0x98DD 0x4FE4 #CJK UNIFIED IDEOGRAPH
+0x98DE 0x4FE5 #CJK UNIFIED IDEOGRAPH
+0x98DF 0x501A #CJK UNIFIED IDEOGRAPH
+0x98E0 0x5028 #CJK UNIFIED IDEOGRAPH
+0x98E1 0x5014 #CJK UNIFIED IDEOGRAPH
+0x98E2 0x502A #CJK UNIFIED IDEOGRAPH
+0x98E3 0x5025 #CJK UNIFIED IDEOGRAPH
+0x98E4 0x5005 #CJK UNIFIED IDEOGRAPH
+0x98E5 0x4F1C #CJK UNIFIED IDEOGRAPH
+0x98E6 0x4FF6 #CJK UNIFIED IDEOGRAPH
+0x98E7 0x5021 #CJK UNIFIED IDEOGRAPH
+0x98E8 0x5029 #CJK UNIFIED IDEOGRAPH
+0x98E9 0x502C #CJK UNIFIED IDEOGRAPH
+0x98EA 0x4FFE #CJK UNIFIED IDEOGRAPH
+0x98EB 0x4FEF #CJK UNIFIED IDEOGRAPH
+0x98EC 0x5011 #CJK UNIFIED IDEOGRAPH
+0x98ED 0x5006 #CJK UNIFIED IDEOGRAPH
+0x98EE 0x5043 #CJK UNIFIED IDEOGRAPH
+0x98EF 0x5047 #CJK UNIFIED IDEOGRAPH
+0x98F0 0x6703 #CJK UNIFIED IDEOGRAPH
+0x98F1 0x5055 #CJK UNIFIED IDEOGRAPH
+0x98F2 0x5050 #CJK UNIFIED IDEOGRAPH
+0x98F3 0x5048 #CJK UNIFIED IDEOGRAPH
+0x98F4 0x505A #CJK UNIFIED IDEOGRAPH
+0x98F5 0x5056 #CJK UNIFIED IDEOGRAPH
+0x98F6 0x506C #CJK UNIFIED IDEOGRAPH
+0x98F7 0x5078 #CJK UNIFIED IDEOGRAPH
+0x98F8 0x5080 #CJK UNIFIED IDEOGRAPH
+0x98F9 0x509A #CJK UNIFIED IDEOGRAPH
+0x98FA 0x5085 #CJK UNIFIED IDEOGRAPH
+0x98FB 0x50B4 #CJK UNIFIED IDEOGRAPH
+0x98FC 0x50B2 #CJK UNIFIED IDEOGRAPH
+0x9940 0x50C9 #CJK UNIFIED IDEOGRAPH
+0x9941 0x50CA #CJK UNIFIED IDEOGRAPH
+0x9942 0x50B3 #CJK UNIFIED IDEOGRAPH
+0x9943 0x50C2 #CJK UNIFIED IDEOGRAPH
+0x9944 0x50D6 #CJK UNIFIED IDEOGRAPH
+0x9945 0x50DE #CJK UNIFIED IDEOGRAPH
+0x9946 0x50E5 #CJK UNIFIED IDEOGRAPH
+0x9947 0x50ED #CJK UNIFIED IDEOGRAPH
+0x9948 0x50E3 #CJK UNIFIED IDEOGRAPH
+0x9949 0x50EE #CJK UNIFIED IDEOGRAPH
+0x994A 0x50F9 #CJK UNIFIED IDEOGRAPH
+0x994B 0x50F5 #CJK UNIFIED IDEOGRAPH
+0x994C 0x5109 #CJK UNIFIED IDEOGRAPH
+0x994D 0x5101 #CJK UNIFIED IDEOGRAPH
+0x994E 0x5102 #CJK UNIFIED IDEOGRAPH
+0x994F 0x5116 #CJK UNIFIED IDEOGRAPH
+0x9950 0x5115 #CJK UNIFIED IDEOGRAPH
+0x9951 0x5114 #CJK UNIFIED IDEOGRAPH
+0x9952 0x511A #CJK UNIFIED IDEOGRAPH
+0x9953 0x5121 #CJK UNIFIED IDEOGRAPH
+0x9954 0x513A #CJK UNIFIED IDEOGRAPH
+0x9955 0x5137 #CJK UNIFIED IDEOGRAPH
+0x9956 0x513C #CJK UNIFIED IDEOGRAPH
+0x9957 0x513B #CJK UNIFIED IDEOGRAPH
+0x9958 0x513F #CJK UNIFIED IDEOGRAPH
+0x9959 0x5140 #CJK UNIFIED IDEOGRAPH
+0x995A 0x5152 #CJK UNIFIED IDEOGRAPH
+0x995B 0x514C #CJK UNIFIED IDEOGRAPH
+0x995C 0x5154 #CJK UNIFIED IDEOGRAPH
+0x995D 0x5162 #CJK UNIFIED IDEOGRAPH
+0x995E 0x7AF8 #CJK UNIFIED IDEOGRAPH
+0x995F 0x5169 #CJK UNIFIED IDEOGRAPH
+0x9960 0x516A #CJK UNIFIED IDEOGRAPH
+0x9961 0x516E #CJK UNIFIED IDEOGRAPH
+0x9962 0x5180 #CJK UNIFIED IDEOGRAPH
+0x9963 0x5182 #CJK UNIFIED IDEOGRAPH
+0x9964 0x56D8 #CJK UNIFIED IDEOGRAPH
+0x9965 0x518C #CJK UNIFIED IDEOGRAPH
+0x9966 0x5189 #CJK UNIFIED IDEOGRAPH
+0x9967 0x518F #CJK UNIFIED IDEOGRAPH
+0x9968 0x5191 #CJK UNIFIED IDEOGRAPH
+0x9969 0x5193 #CJK UNIFIED IDEOGRAPH
+0x996A 0x5195 #CJK UNIFIED IDEOGRAPH
+0x996B 0x5196 #CJK UNIFIED IDEOGRAPH
+0x996C 0x51A4 #CJK UNIFIED IDEOGRAPH
+0x996D 0x51A6 #CJK UNIFIED IDEOGRAPH
+0x996E 0x51A2 #CJK UNIFIED IDEOGRAPH
+0x996F 0x51A9 #CJK UNIFIED IDEOGRAPH
+0x9970 0x51AA #CJK UNIFIED IDEOGRAPH
+0x9971 0x51AB #CJK UNIFIED IDEOGRAPH
+0x9972 0x51B3 #CJK UNIFIED IDEOGRAPH
+0x9973 0x51B1 #CJK UNIFIED IDEOGRAPH
+0x9974 0x51B2 #CJK UNIFIED IDEOGRAPH
+0x9975 0x51B0 #CJK UNIFIED IDEOGRAPH
+0x9976 0x51B5 #CJK UNIFIED IDEOGRAPH
+0x9977 0x51BD #CJK UNIFIED IDEOGRAPH
+0x9978 0x51C5 #CJK UNIFIED IDEOGRAPH
+0x9979 0x51C9 #CJK UNIFIED IDEOGRAPH
+0x997A 0x51DB #CJK UNIFIED IDEOGRAPH
+0x997B 0x51E0 #CJK UNIFIED IDEOGRAPH
+0x997C 0x8655 #CJK UNIFIED IDEOGRAPH
+0x997D 0x51E9 #CJK UNIFIED IDEOGRAPH
+0x997E 0x51ED #CJK UNIFIED IDEOGRAPH
+0x9980 0x51F0 #CJK UNIFIED IDEOGRAPH
+0x9981 0x51F5 #CJK UNIFIED IDEOGRAPH
+0x9982 0x51FE #CJK UNIFIED IDEOGRAPH
+0x9983 0x5204 #CJK UNIFIED IDEOGRAPH
+0x9984 0x520B #CJK UNIFIED IDEOGRAPH
+0x9985 0x5214 #CJK UNIFIED IDEOGRAPH
+0x9986 0x520E #CJK UNIFIED IDEOGRAPH
+0x9987 0x5227 #CJK UNIFIED IDEOGRAPH
+0x9988 0x522A #CJK UNIFIED IDEOGRAPH
+0x9989 0x522E #CJK UNIFIED IDEOGRAPH
+0x998A 0x5233 #CJK UNIFIED IDEOGRAPH
+0x998B 0x5239 #CJK UNIFIED IDEOGRAPH
+0x998C 0x524F #CJK UNIFIED IDEOGRAPH
+0x998D 0x5244 #CJK UNIFIED IDEOGRAPH
+0x998E 0x524B #CJK UNIFIED IDEOGRAPH
+0x998F 0x524C #CJK UNIFIED IDEOGRAPH
+0x9990 0x525E #CJK UNIFIED IDEOGRAPH
+0x9991 0x5254 #CJK UNIFIED IDEOGRAPH
+0x9992 0x526A #CJK UNIFIED IDEOGRAPH
+0x9993 0x5274 #CJK UNIFIED IDEOGRAPH
+0x9994 0x5269 #CJK UNIFIED IDEOGRAPH
+0x9995 0x5273 #CJK UNIFIED IDEOGRAPH
+0x9996 0x527F #CJK UNIFIED IDEOGRAPH
+0x9997 0x527D #CJK UNIFIED IDEOGRAPH
+0x9998 0x528D #CJK UNIFIED IDEOGRAPH
+0x9999 0x5294 #CJK UNIFIED IDEOGRAPH
+0x999A 0x5292 #CJK UNIFIED IDEOGRAPH
+0x999B 0x5271 #CJK UNIFIED IDEOGRAPH
+0x999C 0x5288 #CJK UNIFIED IDEOGRAPH
+0x999D 0x5291 #CJK UNIFIED IDEOGRAPH
+0x999E 0x8FA8 #CJK UNIFIED IDEOGRAPH
+0x999F 0x8FA7 #CJK UNIFIED IDEOGRAPH
+0x99A0 0x52AC #CJK UNIFIED IDEOGRAPH
+0x99A1 0x52AD #CJK UNIFIED IDEOGRAPH
+0x99A2 0x52BC #CJK UNIFIED IDEOGRAPH
+0x99A3 0x52B5 #CJK UNIFIED IDEOGRAPH
+0x99A4 0x52C1 #CJK UNIFIED IDEOGRAPH
+0x99A5 0x52CD #CJK UNIFIED IDEOGRAPH
+0x99A6 0x52D7 #CJK UNIFIED IDEOGRAPH
+0x99A7 0x52DE #CJK UNIFIED IDEOGRAPH
+0x99A8 0x52E3 #CJK UNIFIED IDEOGRAPH
+0x99A9 0x52E6 #CJK UNIFIED IDEOGRAPH
+0x99AA 0x98ED #CJK UNIFIED IDEOGRAPH
+0x99AB 0x52E0 #CJK UNIFIED IDEOGRAPH
+0x99AC 0x52F3 #CJK UNIFIED IDEOGRAPH
+0x99AD 0x52F5 #CJK UNIFIED IDEOGRAPH
+0x99AE 0x52F8 #CJK UNIFIED IDEOGRAPH
+0x99AF 0x52F9 #CJK UNIFIED IDEOGRAPH
+0x99B0 0x5306 #CJK UNIFIED IDEOGRAPH
+0x99B1 0x5308 #CJK UNIFIED IDEOGRAPH
+0x99B2 0x7538 #CJK UNIFIED IDEOGRAPH
+0x99B3 0x530D #CJK UNIFIED IDEOGRAPH
+0x99B4 0x5310 #CJK UNIFIED IDEOGRAPH
+0x99B5 0x530F #CJK UNIFIED IDEOGRAPH
+0x99B6 0x5315 #CJK UNIFIED IDEOGRAPH
+0x99B7 0x531A #CJK UNIFIED IDEOGRAPH
+0x99B8 0x5323 #CJK UNIFIED IDEOGRAPH
+0x99B9 0x532F #CJK UNIFIED IDEOGRAPH
+0x99BA 0x5331 #CJK UNIFIED IDEOGRAPH
+0x99BB 0x5333 #CJK UNIFIED IDEOGRAPH
+0x99BC 0x5338 #CJK UNIFIED IDEOGRAPH
+0x99BD 0x5340 #CJK UNIFIED IDEOGRAPH
+0x99BE 0x5346 #CJK UNIFIED IDEOGRAPH
+0x99BF 0x5345 #CJK UNIFIED IDEOGRAPH
+0x99C0 0x4E17 #CJK UNIFIED IDEOGRAPH
+0x99C1 0x5349 #CJK UNIFIED IDEOGRAPH
+0x99C2 0x534D #CJK UNIFIED IDEOGRAPH
+0x99C3 0x51D6 #CJK UNIFIED IDEOGRAPH
+0x99C4 0x535E #CJK UNIFIED IDEOGRAPH
+0x99C5 0x5369 #CJK UNIFIED IDEOGRAPH
+0x99C6 0x536E #CJK UNIFIED IDEOGRAPH
+0x99C7 0x5918 #CJK UNIFIED IDEOGRAPH
+0x99C8 0x537B #CJK UNIFIED IDEOGRAPH
+0x99C9 0x5377 #CJK UNIFIED IDEOGRAPH
+0x99CA 0x5382 #CJK UNIFIED IDEOGRAPH
+0x99CB 0x5396 #CJK UNIFIED IDEOGRAPH
+0x99CC 0x53A0 #CJK UNIFIED IDEOGRAPH
+0x99CD 0x53A6 #CJK UNIFIED IDEOGRAPH
+0x99CE 0x53A5 #CJK UNIFIED IDEOGRAPH
+0x99CF 0x53AE #CJK UNIFIED IDEOGRAPH
+0x99D0 0x53B0 #CJK UNIFIED IDEOGRAPH
+0x99D1 0x53B6 #CJK UNIFIED IDEOGRAPH
+0x99D2 0x53C3 #CJK UNIFIED IDEOGRAPH
+0x99D3 0x7C12 #CJK UNIFIED IDEOGRAPH
+0x99D4 0x96D9 #CJK UNIFIED IDEOGRAPH
+0x99D5 0x53DF #CJK UNIFIED IDEOGRAPH
+0x99D6 0x66FC #CJK UNIFIED IDEOGRAPH
+0x99D7 0x71EE #CJK UNIFIED IDEOGRAPH
+0x99D8 0x53EE #CJK UNIFIED IDEOGRAPH
+0x99D9 0x53E8 #CJK UNIFIED IDEOGRAPH
+0x99DA 0x53ED #CJK UNIFIED IDEOGRAPH
+0x99DB 0x53FA #CJK UNIFIED IDEOGRAPH
+0x99DC 0x5401 #CJK UNIFIED IDEOGRAPH
+0x99DD 0x543D #CJK UNIFIED IDEOGRAPH
+0x99DE 0x5440 #CJK UNIFIED IDEOGRAPH
+0x99DF 0x542C #CJK UNIFIED IDEOGRAPH
+0x99E0 0x542D #CJK UNIFIED IDEOGRAPH
+0x99E1 0x543C #CJK UNIFIED IDEOGRAPH
+0x99E2 0x542E #CJK UNIFIED IDEOGRAPH
+0x99E3 0x5436 #CJK UNIFIED IDEOGRAPH
+0x99E4 0x5429 #CJK UNIFIED IDEOGRAPH
+0x99E5 0x541D #CJK UNIFIED IDEOGRAPH
+0x99E6 0x544E #CJK UNIFIED IDEOGRAPH
+0x99E7 0x548F #CJK UNIFIED IDEOGRAPH
+0x99E8 0x5475 #CJK UNIFIED IDEOGRAPH
+0x99E9 0x548E #CJK UNIFIED IDEOGRAPH
+0x99EA 0x545F #CJK UNIFIED IDEOGRAPH
+0x99EB 0x5471 #CJK UNIFIED IDEOGRAPH
+0x99EC 0x5477 #CJK UNIFIED IDEOGRAPH
+0x99ED 0x5470 #CJK UNIFIED IDEOGRAPH
+0x99EE 0x5492 #CJK UNIFIED IDEOGRAPH
+0x99EF 0x547B #CJK UNIFIED IDEOGRAPH
+0x99F0 0x5480 #CJK UNIFIED IDEOGRAPH
+0x99F1 0x5476 #CJK UNIFIED IDEOGRAPH
+0x99F2 0x5484 #CJK UNIFIED IDEOGRAPH
+0x99F3 0x5490 #CJK UNIFIED IDEOGRAPH
+0x99F4 0x5486 #CJK UNIFIED IDEOGRAPH
+0x99F5 0x54C7 #CJK UNIFIED IDEOGRAPH
+0x99F6 0x54A2 #CJK UNIFIED IDEOGRAPH
+0x99F7 0x54B8 #CJK UNIFIED IDEOGRAPH
+0x99F8 0x54A5 #CJK UNIFIED IDEOGRAPH
+0x99F9 0x54AC #CJK UNIFIED IDEOGRAPH
+0x99FA 0x54C4 #CJK UNIFIED IDEOGRAPH
+0x99FB 0x54C8 #CJK UNIFIED IDEOGRAPH
+0x99FC 0x54A8 #CJK UNIFIED IDEOGRAPH
+0x9A40 0x54AB #CJK UNIFIED IDEOGRAPH
+0x9A41 0x54C2 #CJK UNIFIED IDEOGRAPH
+0x9A42 0x54A4 #CJK UNIFIED IDEOGRAPH
+0x9A43 0x54BE #CJK UNIFIED IDEOGRAPH
+0x9A44 0x54BC #CJK UNIFIED IDEOGRAPH
+0x9A45 0x54D8 #CJK UNIFIED IDEOGRAPH
+0x9A46 0x54E5 #CJK UNIFIED IDEOGRAPH
+0x9A47 0x54E6 #CJK UNIFIED IDEOGRAPH
+0x9A48 0x550F #CJK UNIFIED IDEOGRAPH
+0x9A49 0x5514 #CJK UNIFIED IDEOGRAPH
+0x9A4A 0x54FD #CJK UNIFIED IDEOGRAPH
+0x9A4B 0x54EE #CJK UNIFIED IDEOGRAPH
+0x9A4C 0x54ED #CJK UNIFIED IDEOGRAPH
+0x9A4D 0x54FA #CJK UNIFIED IDEOGRAPH
+0x9A4E 0x54E2 #CJK UNIFIED IDEOGRAPH
+0x9A4F 0x5539 #CJK UNIFIED IDEOGRAPH
+0x9A50 0x5540 #CJK UNIFIED IDEOGRAPH
+0x9A51 0x5563 #CJK UNIFIED IDEOGRAPH
+0x9A52 0x554C #CJK UNIFIED IDEOGRAPH
+0x9A53 0x552E #CJK UNIFIED IDEOGRAPH
+0x9A54 0x555C #CJK UNIFIED IDEOGRAPH
+0x9A55 0x5545 #CJK UNIFIED IDEOGRAPH
+0x9A56 0x5556 #CJK UNIFIED IDEOGRAPH
+0x9A57 0x5557 #CJK UNIFIED IDEOGRAPH
+0x9A58 0x5538 #CJK UNIFIED IDEOGRAPH
+0x9A59 0x5533 #CJK UNIFIED IDEOGRAPH
+0x9A5A 0x555D #CJK UNIFIED IDEOGRAPH
+0x9A5B 0x5599 #CJK UNIFIED IDEOGRAPH
+0x9A5C 0x5580 #CJK UNIFIED IDEOGRAPH
+0x9A5D 0x54AF #CJK UNIFIED IDEOGRAPH
+0x9A5E 0x558A #CJK UNIFIED IDEOGRAPH
+0x9A5F 0x559F #CJK UNIFIED IDEOGRAPH
+0x9A60 0x557B #CJK UNIFIED IDEOGRAPH
+0x9A61 0x557E #CJK UNIFIED IDEOGRAPH
+0x9A62 0x5598 #CJK UNIFIED IDEOGRAPH
+0x9A63 0x559E #CJK UNIFIED IDEOGRAPH
+0x9A64 0x55AE #CJK UNIFIED IDEOGRAPH
+0x9A65 0x557C #CJK UNIFIED IDEOGRAPH
+0x9A66 0x5583 #CJK UNIFIED IDEOGRAPH
+0x9A67 0x55A9 #CJK UNIFIED IDEOGRAPH
+0x9A68 0x5587 #CJK UNIFIED IDEOGRAPH
+0x9A69 0x55A8 #CJK UNIFIED IDEOGRAPH
+0x9A6A 0x55DA #CJK UNIFIED IDEOGRAPH
+0x9A6B 0x55C5 #CJK UNIFIED IDEOGRAPH
+0x9A6C 0x55DF #CJK UNIFIED IDEOGRAPH
+0x9A6D 0x55C4 #CJK UNIFIED IDEOGRAPH
+0x9A6E 0x55DC #CJK UNIFIED IDEOGRAPH
+0x9A6F 0x55E4 #CJK UNIFIED IDEOGRAPH
+0x9A70 0x55D4 #CJK UNIFIED IDEOGRAPH
+0x9A71 0x5614 #CJK UNIFIED IDEOGRAPH
+0x9A72 0x55F7 #CJK UNIFIED IDEOGRAPH
+0x9A73 0x5616 #CJK UNIFIED IDEOGRAPH
+0x9A74 0x55FE #CJK UNIFIED IDEOGRAPH
+0x9A75 0x55FD #CJK UNIFIED IDEOGRAPH
+0x9A76 0x561B #CJK UNIFIED IDEOGRAPH
+0x9A77 0x55F9 #CJK UNIFIED IDEOGRAPH
+0x9A78 0x564E #CJK UNIFIED IDEOGRAPH
+0x9A79 0x5650 #CJK UNIFIED IDEOGRAPH
+0x9A7A 0x71DF #CJK UNIFIED IDEOGRAPH
+0x9A7B 0x5634 #CJK UNIFIED IDEOGRAPH
+0x9A7C 0x5636 #CJK UNIFIED IDEOGRAPH
+0x9A7D 0x5632 #CJK UNIFIED IDEOGRAPH
+0x9A7E 0x5638 #CJK UNIFIED IDEOGRAPH
+0x9A80 0x566B #CJK UNIFIED IDEOGRAPH
+0x9A81 0x5664 #CJK UNIFIED IDEOGRAPH
+0x9A82 0x562F #CJK UNIFIED IDEOGRAPH
+0x9A83 0x566C #CJK UNIFIED IDEOGRAPH
+0x9A84 0x566A #CJK UNIFIED IDEOGRAPH
+0x9A85 0x5686 #CJK UNIFIED IDEOGRAPH
+0x9A86 0x5680 #CJK UNIFIED IDEOGRAPH
+0x9A87 0x568A #CJK UNIFIED IDEOGRAPH
+0x9A88 0x56A0 #CJK UNIFIED IDEOGRAPH
+0x9A89 0x5694 #CJK UNIFIED IDEOGRAPH
+0x9A8A 0x568F #CJK UNIFIED IDEOGRAPH
+0x9A8B 0x56A5 #CJK UNIFIED IDEOGRAPH
+0x9A8C 0x56AE #CJK UNIFIED IDEOGRAPH
+0x9A8D 0x56B6 #CJK UNIFIED IDEOGRAPH
+0x9A8E 0x56B4 #CJK UNIFIED IDEOGRAPH
+0x9A8F 0x56C2 #CJK UNIFIED IDEOGRAPH
+0x9A90 0x56BC #CJK UNIFIED IDEOGRAPH
+0x9A91 0x56C1 #CJK UNIFIED IDEOGRAPH
+0x9A92 0x56C3 #CJK UNIFIED IDEOGRAPH
+0x9A93 0x56C0 #CJK UNIFIED IDEOGRAPH
+0x9A94 0x56C8 #CJK UNIFIED IDEOGRAPH
+0x9A95 0x56CE #CJK UNIFIED IDEOGRAPH
+0x9A96 0x56D1 #CJK UNIFIED IDEOGRAPH
+0x9A97 0x56D3 #CJK UNIFIED IDEOGRAPH
+0x9A98 0x56D7 #CJK UNIFIED IDEOGRAPH
+0x9A99 0x56EE #CJK UNIFIED IDEOGRAPH
+0x9A9A 0x56F9 #CJK UNIFIED IDEOGRAPH
+0x9A9B 0x5700 #CJK UNIFIED IDEOGRAPH
+0x9A9C 0x56FF #CJK UNIFIED IDEOGRAPH
+0x9A9D 0x5704 #CJK UNIFIED IDEOGRAPH
+0x9A9E 0x5709 #CJK UNIFIED IDEOGRAPH
+0x9A9F 0x5708 #CJK UNIFIED IDEOGRAPH
+0x9AA0 0x570B #CJK UNIFIED IDEOGRAPH
+0x9AA1 0x570D #CJK UNIFIED IDEOGRAPH
+0x9AA2 0x5713 #CJK UNIFIED IDEOGRAPH
+0x9AA3 0x5718 #CJK UNIFIED IDEOGRAPH
+0x9AA4 0x5716 #CJK UNIFIED IDEOGRAPH
+0x9AA5 0x55C7 #CJK UNIFIED IDEOGRAPH
+0x9AA6 0x571C #CJK UNIFIED IDEOGRAPH
+0x9AA7 0x5726 #CJK UNIFIED IDEOGRAPH
+0x9AA8 0x5737 #CJK UNIFIED IDEOGRAPH
+0x9AA9 0x5738 #CJK UNIFIED IDEOGRAPH
+0x9AAA 0x574E #CJK UNIFIED IDEOGRAPH
+0x9AAB 0x573B #CJK UNIFIED IDEOGRAPH
+0x9AAC 0x5740 #CJK UNIFIED IDEOGRAPH
+0x9AAD 0x574F #CJK UNIFIED IDEOGRAPH
+0x9AAE 0x5769 #CJK UNIFIED IDEOGRAPH
+0x9AAF 0x57C0 #CJK UNIFIED IDEOGRAPH
+0x9AB0 0x5788 #CJK UNIFIED IDEOGRAPH
+0x9AB1 0x5761 #CJK UNIFIED IDEOGRAPH
+0x9AB2 0x577F #CJK UNIFIED IDEOGRAPH
+0x9AB3 0x5789 #CJK UNIFIED IDEOGRAPH
+0x9AB4 0x5793 #CJK UNIFIED IDEOGRAPH
+0x9AB5 0x57A0 #CJK UNIFIED IDEOGRAPH
+0x9AB6 0x57B3 #CJK UNIFIED IDEOGRAPH
+0x9AB7 0x57A4 #CJK UNIFIED IDEOGRAPH
+0x9AB8 0x57AA #CJK UNIFIED IDEOGRAPH
+0x9AB9 0x57B0 #CJK UNIFIED IDEOGRAPH
+0x9ABA 0x57C3 #CJK UNIFIED IDEOGRAPH
+0x9ABB 0x57C6 #CJK UNIFIED IDEOGRAPH
+0x9ABC 0x57D4 #CJK UNIFIED IDEOGRAPH
+0x9ABD 0x57D2 #CJK UNIFIED IDEOGRAPH
+0x9ABE 0x57D3 #CJK UNIFIED IDEOGRAPH
+0x9ABF 0x580A #CJK UNIFIED IDEOGRAPH
+0x9AC0 0x57D6 #CJK UNIFIED IDEOGRAPH
+0x9AC1 0x57E3 #CJK UNIFIED IDEOGRAPH
+0x9AC2 0x580B #CJK UNIFIED IDEOGRAPH
+0x9AC3 0x5819 #CJK UNIFIED IDEOGRAPH
+0x9AC4 0x581D #CJK UNIFIED IDEOGRAPH
+0x9AC5 0x5872 #CJK UNIFIED IDEOGRAPH
+0x9AC6 0x5821 #CJK UNIFIED IDEOGRAPH
+0x9AC7 0x5862 #CJK UNIFIED IDEOGRAPH
+0x9AC8 0x584B #CJK UNIFIED IDEOGRAPH
+0x9AC9 0x5870 #CJK UNIFIED IDEOGRAPH
+0x9ACA 0x6BC0 #CJK UNIFIED IDEOGRAPH
+0x9ACB 0x5852 #CJK UNIFIED IDEOGRAPH
+0x9ACC 0x583D #CJK UNIFIED IDEOGRAPH
+0x9ACD 0x5879 #CJK UNIFIED IDEOGRAPH
+0x9ACE 0x5885 #CJK UNIFIED IDEOGRAPH
+0x9ACF 0x58B9 #CJK UNIFIED IDEOGRAPH
+0x9AD0 0x589F #CJK UNIFIED IDEOGRAPH
+0x9AD1 0x58AB #CJK UNIFIED IDEOGRAPH
+0x9AD2 0x58BA #CJK UNIFIED IDEOGRAPH
+0x9AD3 0x58DE #CJK UNIFIED IDEOGRAPH
+0x9AD4 0x58BB #CJK UNIFIED IDEOGRAPH
+0x9AD5 0x58B8 #CJK UNIFIED IDEOGRAPH
+0x9AD6 0x58AE #CJK UNIFIED IDEOGRAPH
+0x9AD7 0x58C5 #CJK UNIFIED IDEOGRAPH
+0x9AD8 0x58D3 #CJK UNIFIED IDEOGRAPH
+0x9AD9 0x58D1 #CJK UNIFIED IDEOGRAPH
+0x9ADA 0x58D7 #CJK UNIFIED IDEOGRAPH
+0x9ADB 0x58D9 #CJK UNIFIED IDEOGRAPH
+0x9ADC 0x58D8 #CJK UNIFIED IDEOGRAPH
+0x9ADD 0x58E5 #CJK UNIFIED IDEOGRAPH
+0x9ADE 0x58DC #CJK UNIFIED IDEOGRAPH
+0x9ADF 0x58E4 #CJK UNIFIED IDEOGRAPH
+0x9AE0 0x58DF #CJK UNIFIED IDEOGRAPH
+0x9AE1 0x58EF #CJK UNIFIED IDEOGRAPH
+0x9AE2 0x58FA #CJK UNIFIED IDEOGRAPH
+0x9AE3 0x58F9 #CJK UNIFIED IDEOGRAPH
+0x9AE4 0x58FB #CJK UNIFIED IDEOGRAPH
+0x9AE5 0x58FC #CJK UNIFIED IDEOGRAPH
+0x9AE6 0x58FD #CJK UNIFIED IDEOGRAPH
+0x9AE7 0x5902 #CJK UNIFIED IDEOGRAPH
+0x9AE8 0x590A #CJK UNIFIED IDEOGRAPH
+0x9AE9 0x5910 #CJK UNIFIED IDEOGRAPH
+0x9AEA 0x591B #CJK UNIFIED IDEOGRAPH
+0x9AEB 0x68A6 #CJK UNIFIED IDEOGRAPH
+0x9AEC 0x5925 #CJK UNIFIED IDEOGRAPH
+0x9AED 0x592C #CJK UNIFIED IDEOGRAPH
+0x9AEE 0x592D #CJK UNIFIED IDEOGRAPH
+0x9AEF 0x5932 #CJK UNIFIED IDEOGRAPH
+0x9AF0 0x5938 #CJK UNIFIED IDEOGRAPH
+0x9AF1 0x593E #CJK UNIFIED IDEOGRAPH
+0x9AF2 0x7AD2 #CJK UNIFIED IDEOGRAPH
+0x9AF3 0x5955 #CJK UNIFIED IDEOGRAPH
+0x9AF4 0x5950 #CJK UNIFIED IDEOGRAPH
+0x9AF5 0x594E #CJK UNIFIED IDEOGRAPH
+0x9AF6 0x595A #CJK UNIFIED IDEOGRAPH
+0x9AF7 0x5958 #CJK UNIFIED IDEOGRAPH
+0x9AF8 0x5962 #CJK UNIFIED IDEOGRAPH
+0x9AF9 0x5960 #CJK UNIFIED IDEOGRAPH
+0x9AFA 0x5967 #CJK UNIFIED IDEOGRAPH
+0x9AFB 0x596C #CJK UNIFIED IDEOGRAPH
+0x9AFC 0x5969 #CJK UNIFIED IDEOGRAPH
+0x9B40 0x5978 #CJK UNIFIED IDEOGRAPH
+0x9B41 0x5981 #CJK UNIFIED IDEOGRAPH
+0x9B42 0x599D #CJK UNIFIED IDEOGRAPH
+0x9B43 0x4F5E #CJK UNIFIED IDEOGRAPH
+0x9B44 0x4FAB #CJK UNIFIED IDEOGRAPH
+0x9B45 0x59A3 #CJK UNIFIED IDEOGRAPH
+0x9B46 0x59B2 #CJK UNIFIED IDEOGRAPH
+0x9B47 0x59C6 #CJK UNIFIED IDEOGRAPH
+0x9B48 0x59E8 #CJK UNIFIED IDEOGRAPH
+0x9B49 0x59DC #CJK UNIFIED IDEOGRAPH
+0x9B4A 0x598D #CJK UNIFIED IDEOGRAPH
+0x9B4B 0x59D9 #CJK UNIFIED IDEOGRAPH
+0x9B4C 0x59DA #CJK UNIFIED IDEOGRAPH
+0x9B4D 0x5A25 #CJK UNIFIED IDEOGRAPH
+0x9B4E 0x5A1F #CJK UNIFIED IDEOGRAPH
+0x9B4F 0x5A11 #CJK UNIFIED IDEOGRAPH
+0x9B50 0x5A1C #CJK UNIFIED IDEOGRAPH
+0x9B51 0x5A09 #CJK UNIFIED IDEOGRAPH
+0x9B52 0x5A1A #CJK UNIFIED IDEOGRAPH
+0x9B53 0x5A40 #CJK UNIFIED IDEOGRAPH
+0x9B54 0x5A6C #CJK UNIFIED IDEOGRAPH
+0x9B55 0x5A49 #CJK UNIFIED IDEOGRAPH
+0x9B56 0x5A35 #CJK UNIFIED IDEOGRAPH
+0x9B57 0x5A36 #CJK UNIFIED IDEOGRAPH
+0x9B58 0x5A62 #CJK UNIFIED IDEOGRAPH
+0x9B59 0x5A6A #CJK UNIFIED IDEOGRAPH
+0x9B5A 0x5A9A #CJK UNIFIED IDEOGRAPH
+0x9B5B 0x5ABC #CJK UNIFIED IDEOGRAPH
+0x9B5C 0x5ABE #CJK UNIFIED IDEOGRAPH
+0x9B5D 0x5ACB #CJK UNIFIED IDEOGRAPH
+0x9B5E 0x5AC2 #CJK UNIFIED IDEOGRAPH
+0x9B5F 0x5ABD #CJK UNIFIED IDEOGRAPH
+0x9B60 0x5AE3 #CJK UNIFIED IDEOGRAPH
+0x9B61 0x5AD7 #CJK UNIFIED IDEOGRAPH
+0x9B62 0x5AE6 #CJK UNIFIED IDEOGRAPH
+0x9B63 0x5AE9 #CJK UNIFIED IDEOGRAPH
+0x9B64 0x5AD6 #CJK UNIFIED IDEOGRAPH
+0x9B65 0x5AFA #CJK UNIFIED IDEOGRAPH
+0x9B66 0x5AFB #CJK UNIFIED IDEOGRAPH
+0x9B67 0x5B0C #CJK UNIFIED IDEOGRAPH
+0x9B68 0x5B0B #CJK UNIFIED IDEOGRAPH
+0x9B69 0x5B16 #CJK UNIFIED IDEOGRAPH
+0x9B6A 0x5B32 #CJK UNIFIED IDEOGRAPH
+0x9B6B 0x5AD0 #CJK UNIFIED IDEOGRAPH
+0x9B6C 0x5B2A #CJK UNIFIED IDEOGRAPH
+0x9B6D 0x5B36 #CJK UNIFIED IDEOGRAPH
+0x9B6E 0x5B3E #CJK UNIFIED IDEOGRAPH
+0x9B6F 0x5B43 #CJK UNIFIED IDEOGRAPH
+0x9B70 0x5B45 #CJK UNIFIED IDEOGRAPH
+0x9B71 0x5B40 #CJK UNIFIED IDEOGRAPH
+0x9B72 0x5B51 #CJK UNIFIED IDEOGRAPH
+0x9B73 0x5B55 #CJK UNIFIED IDEOGRAPH
+0x9B74 0x5B5A #CJK UNIFIED IDEOGRAPH
+0x9B75 0x5B5B #CJK UNIFIED IDEOGRAPH
+0x9B76 0x5B65 #CJK UNIFIED IDEOGRAPH
+0x9B77 0x5B69 #CJK UNIFIED IDEOGRAPH
+0x9B78 0x5B70 #CJK UNIFIED IDEOGRAPH
+0x9B79 0x5B73 #CJK UNIFIED IDEOGRAPH
+0x9B7A 0x5B75 #CJK UNIFIED IDEOGRAPH
+0x9B7B 0x5B78 #CJK UNIFIED IDEOGRAPH
+0x9B7C 0x6588 #CJK UNIFIED IDEOGRAPH
+0x9B7D 0x5B7A #CJK UNIFIED IDEOGRAPH
+0x9B7E 0x5B80 #CJK UNIFIED IDEOGRAPH
+0x9B80 0x5B83 #CJK UNIFIED IDEOGRAPH
+0x9B81 0x5BA6 #CJK UNIFIED IDEOGRAPH
+0x9B82 0x5BB8 #CJK UNIFIED IDEOGRAPH
+0x9B83 0x5BC3 #CJK UNIFIED IDEOGRAPH
+0x9B84 0x5BC7 #CJK UNIFIED IDEOGRAPH
+0x9B85 0x5BC9 #CJK UNIFIED IDEOGRAPH
+0x9B86 0x5BD4 #CJK UNIFIED IDEOGRAPH
+0x9B87 0x5BD0 #CJK UNIFIED IDEOGRAPH
+0x9B88 0x5BE4 #CJK UNIFIED IDEOGRAPH
+0x9B89 0x5BE6 #CJK UNIFIED IDEOGRAPH
+0x9B8A 0x5BE2 #CJK UNIFIED IDEOGRAPH
+0x9B8B 0x5BDE #CJK UNIFIED IDEOGRAPH
+0x9B8C 0x5BE5 #CJK UNIFIED IDEOGRAPH
+0x9B8D 0x5BEB #CJK UNIFIED IDEOGRAPH
+0x9B8E 0x5BF0 #CJK UNIFIED IDEOGRAPH
+0x9B8F 0x5BF6 #CJK UNIFIED IDEOGRAPH
+0x9B90 0x5BF3 #CJK UNIFIED IDEOGRAPH
+0x9B91 0x5C05 #CJK UNIFIED IDEOGRAPH
+0x9B92 0x5C07 #CJK UNIFIED IDEOGRAPH
+0x9B93 0x5C08 #CJK UNIFIED IDEOGRAPH
+0x9B94 0x5C0D #CJK UNIFIED IDEOGRAPH
+0x9B95 0x5C13 #CJK UNIFIED IDEOGRAPH
+0x9B96 0x5C20 #CJK UNIFIED IDEOGRAPH
+0x9B97 0x5C22 #CJK UNIFIED IDEOGRAPH
+0x9B98 0x5C28 #CJK UNIFIED IDEOGRAPH
+0x9B99 0x5C38 #CJK UNIFIED IDEOGRAPH
+0x9B9A 0x5C39 #CJK UNIFIED IDEOGRAPH
+0x9B9B 0x5C41 #CJK UNIFIED IDEOGRAPH
+0x9B9C 0x5C46 #CJK UNIFIED IDEOGRAPH
+0x9B9D 0x5C4E #CJK UNIFIED IDEOGRAPH
+0x9B9E 0x5C53 #CJK UNIFIED IDEOGRAPH
+0x9B9F 0x5C50 #CJK UNIFIED IDEOGRAPH
+0x9BA0 0x5C4F #CJK UNIFIED IDEOGRAPH
+0x9BA1 0x5B71 #CJK UNIFIED IDEOGRAPH
+0x9BA2 0x5C6C #CJK UNIFIED IDEOGRAPH
+0x9BA3 0x5C6E #CJK UNIFIED IDEOGRAPH
+0x9BA4 0x4E62 #CJK UNIFIED IDEOGRAPH
+0x9BA5 0x5C76 #CJK UNIFIED IDEOGRAPH
+0x9BA6 0x5C79 #CJK UNIFIED IDEOGRAPH
+0x9BA7 0x5C8C #CJK UNIFIED IDEOGRAPH
+0x9BA8 0x5C91 #CJK UNIFIED IDEOGRAPH
+0x9BA9 0x5C94 #CJK UNIFIED IDEOGRAPH
+0x9BAA 0x599B #CJK UNIFIED IDEOGRAPH
+0x9BAB 0x5CAB #CJK UNIFIED IDEOGRAPH
+0x9BAC 0x5CBB #CJK UNIFIED IDEOGRAPH
+0x9BAD 0x5CB6 #CJK UNIFIED IDEOGRAPH
+0x9BAE 0x5CBC #CJK UNIFIED IDEOGRAPH
+0x9BAF 0x5CB7 #CJK UNIFIED IDEOGRAPH
+0x9BB0 0x5CC5 #CJK UNIFIED IDEOGRAPH
+0x9BB1 0x5CBE #CJK UNIFIED IDEOGRAPH
+0x9BB2 0x5CC7 #CJK UNIFIED IDEOGRAPH
+0x9BB3 0x5CD9 #CJK UNIFIED IDEOGRAPH
+0x9BB4 0x5CE9 #CJK UNIFIED IDEOGRAPH
+0x9BB5 0x5CFD #CJK UNIFIED IDEOGRAPH
+0x9BB6 0x5CFA #CJK UNIFIED IDEOGRAPH
+0x9BB7 0x5CED #CJK UNIFIED IDEOGRAPH
+0x9BB8 0x5D8C #CJK UNIFIED IDEOGRAPH
+0x9BB9 0x5CEA #CJK UNIFIED IDEOGRAPH
+0x9BBA 0x5D0B #CJK UNIFIED IDEOGRAPH
+0x9BBB 0x5D15 #CJK UNIFIED IDEOGRAPH
+0x9BBC 0x5D17 #CJK UNIFIED IDEOGRAPH
+0x9BBD 0x5D5C #CJK UNIFIED IDEOGRAPH
+0x9BBE 0x5D1F #CJK UNIFIED IDEOGRAPH
+0x9BBF 0x5D1B #CJK UNIFIED IDEOGRAPH
+0x9BC0 0x5D11 #CJK UNIFIED IDEOGRAPH
+0x9BC1 0x5D14 #CJK UNIFIED IDEOGRAPH
+0x9BC2 0x5D22 #CJK UNIFIED IDEOGRAPH
+0x9BC3 0x5D1A #CJK UNIFIED IDEOGRAPH
+0x9BC4 0x5D19 #CJK UNIFIED IDEOGRAPH
+0x9BC5 0x5D18 #CJK UNIFIED IDEOGRAPH
+0x9BC6 0x5D4C #CJK UNIFIED IDEOGRAPH
+0x9BC7 0x5D52 #CJK UNIFIED IDEOGRAPH
+0x9BC8 0x5D4E #CJK UNIFIED IDEOGRAPH
+0x9BC9 0x5D4B #CJK UNIFIED IDEOGRAPH
+0x9BCA 0x5D6C #CJK UNIFIED IDEOGRAPH
+0x9BCB 0x5D73 #CJK UNIFIED IDEOGRAPH
+0x9BCC 0x5D76 #CJK UNIFIED IDEOGRAPH
+0x9BCD 0x5D87 #CJK UNIFIED IDEOGRAPH
+0x9BCE 0x5D84 #CJK UNIFIED IDEOGRAPH
+0x9BCF 0x5D82 #CJK UNIFIED IDEOGRAPH
+0x9BD0 0x5DA2 #CJK UNIFIED IDEOGRAPH
+0x9BD1 0x5D9D #CJK UNIFIED IDEOGRAPH
+0x9BD2 0x5DAC #CJK UNIFIED IDEOGRAPH
+0x9BD3 0x5DAE #CJK UNIFIED IDEOGRAPH
+0x9BD4 0x5DBD #CJK UNIFIED IDEOGRAPH
+0x9BD5 0x5D90 #CJK UNIFIED IDEOGRAPH
+0x9BD6 0x5DB7 #CJK UNIFIED IDEOGRAPH
+0x9BD7 0x5DBC #CJK UNIFIED IDEOGRAPH
+0x9BD8 0x5DC9 #CJK UNIFIED IDEOGRAPH
+0x9BD9 0x5DCD #CJK UNIFIED IDEOGRAPH
+0x9BDA 0x5DD3 #CJK UNIFIED IDEOGRAPH
+0x9BDB 0x5DD2 #CJK UNIFIED IDEOGRAPH
+0x9BDC 0x5DD6 #CJK UNIFIED IDEOGRAPH
+0x9BDD 0x5DDB #CJK UNIFIED IDEOGRAPH
+0x9BDE 0x5DEB #CJK UNIFIED IDEOGRAPH
+0x9BDF 0x5DF2 #CJK UNIFIED IDEOGRAPH
+0x9BE0 0x5DF5 #CJK UNIFIED IDEOGRAPH
+0x9BE1 0x5E0B #CJK UNIFIED IDEOGRAPH
+0x9BE2 0x5E1A #CJK UNIFIED IDEOGRAPH
+0x9BE3 0x5E19 #CJK UNIFIED IDEOGRAPH
+0x9BE4 0x5E11 #CJK UNIFIED IDEOGRAPH
+0x9BE5 0x5E1B #CJK UNIFIED IDEOGRAPH
+0x9BE6 0x5E36 #CJK UNIFIED IDEOGRAPH
+0x9BE7 0x5E37 #CJK UNIFIED IDEOGRAPH
+0x9BE8 0x5E44 #CJK UNIFIED IDEOGRAPH
+0x9BE9 0x5E43 #CJK UNIFIED IDEOGRAPH
+0x9BEA 0x5E40 #CJK UNIFIED IDEOGRAPH
+0x9BEB 0x5E4E #CJK UNIFIED IDEOGRAPH
+0x9BEC 0x5E57 #CJK UNIFIED IDEOGRAPH
+0x9BED 0x5E54 #CJK UNIFIED IDEOGRAPH
+0x9BEE 0x5E5F #CJK UNIFIED IDEOGRAPH
+0x9BEF 0x5E62 #CJK UNIFIED IDEOGRAPH
+0x9BF0 0x5E64 #CJK UNIFIED IDEOGRAPH
+0x9BF1 0x5E47 #CJK UNIFIED IDEOGRAPH
+0x9BF2 0x5E75 #CJK UNIFIED IDEOGRAPH
+0x9BF3 0x5E76 #CJK UNIFIED IDEOGRAPH
+0x9BF4 0x5E7A #CJK UNIFIED IDEOGRAPH
+0x9BF5 0x9EBC #CJK UNIFIED IDEOGRAPH
+0x9BF6 0x5E7F #CJK UNIFIED IDEOGRAPH
+0x9BF7 0x5EA0 #CJK UNIFIED IDEOGRAPH
+0x9BF8 0x5EC1 #CJK UNIFIED IDEOGRAPH
+0x9BF9 0x5EC2 #CJK UNIFIED IDEOGRAPH
+0x9BFA 0x5EC8 #CJK UNIFIED IDEOGRAPH
+0x9BFB 0x5ED0 #CJK UNIFIED IDEOGRAPH
+0x9BFC 0x5ECF #CJK UNIFIED IDEOGRAPH
+0x9C40 0x5ED6 #CJK UNIFIED IDEOGRAPH
+0x9C41 0x5EE3 #CJK UNIFIED IDEOGRAPH
+0x9C42 0x5EDD #CJK UNIFIED IDEOGRAPH
+0x9C43 0x5EDA #CJK UNIFIED IDEOGRAPH
+0x9C44 0x5EDB #CJK UNIFIED IDEOGRAPH
+0x9C45 0x5EE2 #CJK UNIFIED IDEOGRAPH
+0x9C46 0x5EE1 #CJK UNIFIED IDEOGRAPH
+0x9C47 0x5EE8 #CJK UNIFIED IDEOGRAPH
+0x9C48 0x5EE9 #CJK UNIFIED IDEOGRAPH
+0x9C49 0x5EEC #CJK UNIFIED IDEOGRAPH
+0x9C4A 0x5EF1 #CJK UNIFIED IDEOGRAPH
+0x9C4B 0x5EF3 #CJK UNIFIED IDEOGRAPH
+0x9C4C 0x5EF0 #CJK UNIFIED IDEOGRAPH
+0x9C4D 0x5EF4 #CJK UNIFIED IDEOGRAPH
+0x9C4E 0x5EF8 #CJK UNIFIED IDEOGRAPH
+0x9C4F 0x5EFE #CJK UNIFIED IDEOGRAPH
+0x9C50 0x5F03 #CJK UNIFIED IDEOGRAPH
+0x9C51 0x5F09 #CJK UNIFIED IDEOGRAPH
+0x9C52 0x5F5D #CJK UNIFIED IDEOGRAPH
+0x9C53 0x5F5C #CJK UNIFIED IDEOGRAPH
+0x9C54 0x5F0B #CJK UNIFIED IDEOGRAPH
+0x9C55 0x5F11 #CJK UNIFIED IDEOGRAPH
+0x9C56 0x5F16 #CJK UNIFIED IDEOGRAPH
+0x9C57 0x5F29 #CJK UNIFIED IDEOGRAPH
+0x9C58 0x5F2D #CJK UNIFIED IDEOGRAPH
+0x9C59 0x5F38 #CJK UNIFIED IDEOGRAPH
+0x9C5A 0x5F41 #CJK UNIFIED IDEOGRAPH
+0x9C5B 0x5F48 #CJK UNIFIED IDEOGRAPH
+0x9C5C 0x5F4C #CJK UNIFIED IDEOGRAPH
+0x9C5D 0x5F4E #CJK UNIFIED IDEOGRAPH
+0x9C5E 0x5F2F #CJK UNIFIED IDEOGRAPH
+0x9C5F 0x5F51 #CJK UNIFIED IDEOGRAPH
+0x9C60 0x5F56 #CJK UNIFIED IDEOGRAPH
+0x9C61 0x5F57 #CJK UNIFIED IDEOGRAPH
+0x9C62 0x5F59 #CJK UNIFIED IDEOGRAPH
+0x9C63 0x5F61 #CJK UNIFIED IDEOGRAPH
+0x9C64 0x5F6D #CJK UNIFIED IDEOGRAPH
+0x9C65 0x5F73 #CJK UNIFIED IDEOGRAPH
+0x9C66 0x5F77 #CJK UNIFIED IDEOGRAPH
+0x9C67 0x5F83 #CJK UNIFIED IDEOGRAPH
+0x9C68 0x5F82 #CJK UNIFIED IDEOGRAPH
+0x9C69 0x5F7F #CJK UNIFIED IDEOGRAPH
+0x9C6A 0x5F8A #CJK UNIFIED IDEOGRAPH
+0x9C6B 0x5F88 #CJK UNIFIED IDEOGRAPH
+0x9C6C 0x5F91 #CJK UNIFIED IDEOGRAPH
+0x9C6D 0x5F87 #CJK UNIFIED IDEOGRAPH
+0x9C6E 0x5F9E #CJK UNIFIED IDEOGRAPH
+0x9C6F 0x5F99 #CJK UNIFIED IDEOGRAPH
+0x9C70 0x5F98 #CJK UNIFIED IDEOGRAPH
+0x9C71 0x5FA0 #CJK UNIFIED IDEOGRAPH
+0x9C72 0x5FA8 #CJK UNIFIED IDEOGRAPH
+0x9C73 0x5FAD #CJK UNIFIED IDEOGRAPH
+0x9C74 0x5FBC #CJK UNIFIED IDEOGRAPH
+0x9C75 0x5FD6 #CJK UNIFIED IDEOGRAPH
+0x9C76 0x5FFB #CJK UNIFIED IDEOGRAPH
+0x9C77 0x5FE4 #CJK UNIFIED IDEOGRAPH
+0x9C78 0x5FF8 #CJK UNIFIED IDEOGRAPH
+0x9C79 0x5FF1 #CJK UNIFIED IDEOGRAPH
+0x9C7A 0x5FDD #CJK UNIFIED IDEOGRAPH
+0x9C7B 0x60B3 #CJK UNIFIED IDEOGRAPH
+0x9C7C 0x5FFF #CJK UNIFIED IDEOGRAPH
+0x9C7D 0x6021 #CJK UNIFIED IDEOGRAPH
+0x9C7E 0x6060 #CJK UNIFIED IDEOGRAPH
+0x9C80 0x6019 #CJK UNIFIED IDEOGRAPH
+0x9C81 0x6010 #CJK UNIFIED IDEOGRAPH
+0x9C82 0x6029 #CJK UNIFIED IDEOGRAPH
+0x9C83 0x600E #CJK UNIFIED IDEOGRAPH
+0x9C84 0x6031 #CJK UNIFIED IDEOGRAPH
+0x9C85 0x601B #CJK UNIFIED IDEOGRAPH
+0x9C86 0x6015 #CJK UNIFIED IDEOGRAPH
+0x9C87 0x602B #CJK UNIFIED IDEOGRAPH
+0x9C88 0x6026 #CJK UNIFIED IDEOGRAPH
+0x9C89 0x600F #CJK UNIFIED IDEOGRAPH
+0x9C8A 0x603A #CJK UNIFIED IDEOGRAPH
+0x9C8B 0x605A #CJK UNIFIED IDEOGRAPH
+0x9C8C 0x6041 #CJK UNIFIED IDEOGRAPH
+0x9C8D 0x606A #CJK UNIFIED IDEOGRAPH
+0x9C8E 0x6077 #CJK UNIFIED IDEOGRAPH
+0x9C8F 0x605F #CJK UNIFIED IDEOGRAPH
+0x9C90 0x604A #CJK UNIFIED IDEOGRAPH
+0x9C91 0x6046 #CJK UNIFIED IDEOGRAPH
+0x9C92 0x604D #CJK UNIFIED IDEOGRAPH
+0x9C93 0x6063 #CJK UNIFIED IDEOGRAPH
+0x9C94 0x6043 #CJK UNIFIED IDEOGRAPH
+0x9C95 0x6064 #CJK UNIFIED IDEOGRAPH
+0x9C96 0x6042 #CJK UNIFIED IDEOGRAPH
+0x9C97 0x606C #CJK UNIFIED IDEOGRAPH
+0x9C98 0x606B #CJK UNIFIED IDEOGRAPH
+0x9C99 0x6059 #CJK UNIFIED IDEOGRAPH
+0x9C9A 0x6081 #CJK UNIFIED IDEOGRAPH
+0x9C9B 0x608D #CJK UNIFIED IDEOGRAPH
+0x9C9C 0x60E7 #CJK UNIFIED IDEOGRAPH
+0x9C9D 0x6083 #CJK UNIFIED IDEOGRAPH
+0x9C9E 0x609A #CJK UNIFIED IDEOGRAPH
+0x9C9F 0x6084 #CJK UNIFIED IDEOGRAPH
+0x9CA0 0x609B #CJK UNIFIED IDEOGRAPH
+0x9CA1 0x6096 #CJK UNIFIED IDEOGRAPH
+0x9CA2 0x6097 #CJK UNIFIED IDEOGRAPH
+0x9CA3 0x6092 #CJK UNIFIED IDEOGRAPH
+0x9CA4 0x60A7 #CJK UNIFIED IDEOGRAPH
+0x9CA5 0x608B #CJK UNIFIED IDEOGRAPH
+0x9CA6 0x60E1 #CJK UNIFIED IDEOGRAPH
+0x9CA7 0x60B8 #CJK UNIFIED IDEOGRAPH
+0x9CA8 0x60E0 #CJK UNIFIED IDEOGRAPH
+0x9CA9 0x60D3 #CJK UNIFIED IDEOGRAPH
+0x9CAA 0x60B4 #CJK UNIFIED IDEOGRAPH
+0x9CAB 0x5FF0 #CJK UNIFIED IDEOGRAPH
+0x9CAC 0x60BD #CJK UNIFIED IDEOGRAPH
+0x9CAD 0x60C6 #CJK UNIFIED IDEOGRAPH
+0x9CAE 0x60B5 #CJK UNIFIED IDEOGRAPH
+0x9CAF 0x60D8 #CJK UNIFIED IDEOGRAPH
+0x9CB0 0x614D #CJK UNIFIED IDEOGRAPH
+0x9CB1 0x6115 #CJK UNIFIED IDEOGRAPH
+0x9CB2 0x6106 #CJK UNIFIED IDEOGRAPH
+0x9CB3 0x60F6 #CJK UNIFIED IDEOGRAPH
+0x9CB4 0x60F7 #CJK UNIFIED IDEOGRAPH
+0x9CB5 0x6100 #CJK UNIFIED IDEOGRAPH
+0x9CB6 0x60F4 #CJK UNIFIED IDEOGRAPH
+0x9CB7 0x60FA #CJK UNIFIED IDEOGRAPH
+0x9CB8 0x6103 #CJK UNIFIED IDEOGRAPH
+0x9CB9 0x6121 #CJK UNIFIED IDEOGRAPH
+0x9CBA 0x60FB #CJK UNIFIED IDEOGRAPH
+0x9CBB 0x60F1 #CJK UNIFIED IDEOGRAPH
+0x9CBC 0x610D #CJK UNIFIED IDEOGRAPH
+0x9CBD 0x610E #CJK UNIFIED IDEOGRAPH
+0x9CBE 0x6147 #CJK UNIFIED IDEOGRAPH
+0x9CBF 0x613E #CJK UNIFIED IDEOGRAPH
+0x9CC0 0x6128 #CJK UNIFIED IDEOGRAPH
+0x9CC1 0x6127 #CJK UNIFIED IDEOGRAPH
+0x9CC2 0x614A #CJK UNIFIED IDEOGRAPH
+0x9CC3 0x613F #CJK UNIFIED IDEOGRAPH
+0x9CC4 0x613C #CJK UNIFIED IDEOGRAPH
+0x9CC5 0x612C #CJK UNIFIED IDEOGRAPH
+0x9CC6 0x6134 #CJK UNIFIED IDEOGRAPH
+0x9CC7 0x613D #CJK UNIFIED IDEOGRAPH
+0x9CC8 0x6142 #CJK UNIFIED IDEOGRAPH
+0x9CC9 0x6144 #CJK UNIFIED IDEOGRAPH
+0x9CCA 0x6173 #CJK UNIFIED IDEOGRAPH
+0x9CCB 0x6177 #CJK UNIFIED IDEOGRAPH
+0x9CCC 0x6158 #CJK UNIFIED IDEOGRAPH
+0x9CCD 0x6159 #CJK UNIFIED IDEOGRAPH
+0x9CCE 0x615A #CJK UNIFIED IDEOGRAPH
+0x9CCF 0x616B #CJK UNIFIED IDEOGRAPH
+0x9CD0 0x6174 #CJK UNIFIED IDEOGRAPH
+0x9CD1 0x616F #CJK UNIFIED IDEOGRAPH
+0x9CD2 0x6165 #CJK UNIFIED IDEOGRAPH
+0x9CD3 0x6171 #CJK UNIFIED IDEOGRAPH
+0x9CD4 0x615F #CJK UNIFIED IDEOGRAPH
+0x9CD5 0x615D #CJK UNIFIED IDEOGRAPH
+0x9CD6 0x6153 #CJK UNIFIED IDEOGRAPH
+0x9CD7 0x6175 #CJK UNIFIED IDEOGRAPH
+0x9CD8 0x6199 #CJK UNIFIED IDEOGRAPH
+0x9CD9 0x6196 #CJK UNIFIED IDEOGRAPH
+0x9CDA 0x6187 #CJK UNIFIED IDEOGRAPH
+0x9CDB 0x61AC #CJK UNIFIED IDEOGRAPH
+0x9CDC 0x6194 #CJK UNIFIED IDEOGRAPH
+0x9CDD 0x619A #CJK UNIFIED IDEOGRAPH
+0x9CDE 0x618A #CJK UNIFIED IDEOGRAPH
+0x9CDF 0x6191 #CJK UNIFIED IDEOGRAPH
+0x9CE0 0x61AB #CJK UNIFIED IDEOGRAPH
+0x9CE1 0x61AE #CJK UNIFIED IDEOGRAPH
+0x9CE2 0x61CC #CJK UNIFIED IDEOGRAPH
+0x9CE3 0x61CA #CJK UNIFIED IDEOGRAPH
+0x9CE4 0x61C9 #CJK UNIFIED IDEOGRAPH
+0x9CE5 0x61F7 #CJK UNIFIED IDEOGRAPH
+0x9CE6 0x61C8 #CJK UNIFIED IDEOGRAPH
+0x9CE7 0x61C3 #CJK UNIFIED IDEOGRAPH
+0x9CE8 0x61C6 #CJK UNIFIED IDEOGRAPH
+0x9CE9 0x61BA #CJK UNIFIED IDEOGRAPH
+0x9CEA 0x61CB #CJK UNIFIED IDEOGRAPH
+0x9CEB 0x7F79 #CJK UNIFIED IDEOGRAPH
+0x9CEC 0x61CD #CJK UNIFIED IDEOGRAPH
+0x9CED 0x61E6 #CJK UNIFIED IDEOGRAPH
+0x9CEE 0x61E3 #CJK UNIFIED IDEOGRAPH
+0x9CEF 0x61F6 #CJK UNIFIED IDEOGRAPH
+0x9CF0 0x61FA #CJK UNIFIED IDEOGRAPH
+0x9CF1 0x61F4 #CJK UNIFIED IDEOGRAPH
+0x9CF2 0x61FF #CJK UNIFIED IDEOGRAPH
+0x9CF3 0x61FD #CJK UNIFIED IDEOGRAPH
+0x9CF4 0x61FC #CJK UNIFIED IDEOGRAPH
+0x9CF5 0x61FE #CJK UNIFIED IDEOGRAPH
+0x9CF6 0x6200 #CJK UNIFIED IDEOGRAPH
+0x9CF7 0x6208 #CJK UNIFIED IDEOGRAPH
+0x9CF8 0x6209 #CJK UNIFIED IDEOGRAPH
+0x9CF9 0x620D #CJK UNIFIED IDEOGRAPH
+0x9CFA 0x620C #CJK UNIFIED IDEOGRAPH
+0x9CFB 0x6214 #CJK UNIFIED IDEOGRAPH
+0x9CFC 0x621B #CJK UNIFIED IDEOGRAPH
+0x9D40 0x621E #CJK UNIFIED IDEOGRAPH
+0x9D41 0x6221 #CJK UNIFIED IDEOGRAPH
+0x9D42 0x622A #CJK UNIFIED IDEOGRAPH
+0x9D43 0x622E #CJK UNIFIED IDEOGRAPH
+0x9D44 0x6230 #CJK UNIFIED IDEOGRAPH
+0x9D45 0x6232 #CJK UNIFIED IDEOGRAPH
+0x9D46 0x6233 #CJK UNIFIED IDEOGRAPH
+0x9D47 0x6241 #CJK UNIFIED IDEOGRAPH
+0x9D48 0x624E #CJK UNIFIED IDEOGRAPH
+0x9D49 0x625E #CJK UNIFIED IDEOGRAPH
+0x9D4A 0x6263 #CJK UNIFIED IDEOGRAPH
+0x9D4B 0x625B #CJK UNIFIED IDEOGRAPH
+0x9D4C 0x6260 #CJK UNIFIED IDEOGRAPH
+0x9D4D 0x6268 #CJK UNIFIED IDEOGRAPH
+0x9D4E 0x627C #CJK UNIFIED IDEOGRAPH
+0x9D4F 0x6282 #CJK UNIFIED IDEOGRAPH
+0x9D50 0x6289 #CJK UNIFIED IDEOGRAPH
+0x9D51 0x627E #CJK UNIFIED IDEOGRAPH
+0x9D52 0x6292 #CJK UNIFIED IDEOGRAPH
+0x9D53 0x6293 #CJK UNIFIED IDEOGRAPH
+0x9D54 0x6296 #CJK UNIFIED IDEOGRAPH
+0x9D55 0x62D4 #CJK UNIFIED IDEOGRAPH
+0x9D56 0x6283 #CJK UNIFIED IDEOGRAPH
+0x9D57 0x6294 #CJK UNIFIED IDEOGRAPH
+0x9D58 0x62D7 #CJK UNIFIED IDEOGRAPH
+0x9D59 0x62D1 #CJK UNIFIED IDEOGRAPH
+0x9D5A 0x62BB #CJK UNIFIED IDEOGRAPH
+0x9D5B 0x62CF #CJK UNIFIED IDEOGRAPH
+0x9D5C 0x62FF #CJK UNIFIED IDEOGRAPH
+0x9D5D 0x62C6 #CJK UNIFIED IDEOGRAPH
+0x9D5E 0x64D4 #CJK UNIFIED IDEOGRAPH
+0x9D5F 0x62C8 #CJK UNIFIED IDEOGRAPH
+0x9D60 0x62DC #CJK UNIFIED IDEOGRAPH
+0x9D61 0x62CC #CJK UNIFIED IDEOGRAPH
+0x9D62 0x62CA #CJK UNIFIED IDEOGRAPH
+0x9D63 0x62C2 #CJK UNIFIED IDEOGRAPH
+0x9D64 0x62C7 #CJK UNIFIED IDEOGRAPH
+0x9D65 0x629B #CJK UNIFIED IDEOGRAPH
+0x9D66 0x62C9 #CJK UNIFIED IDEOGRAPH
+0x9D67 0x630C #CJK UNIFIED IDEOGRAPH
+0x9D68 0x62EE #CJK UNIFIED IDEOGRAPH
+0x9D69 0x62F1 #CJK UNIFIED IDEOGRAPH
+0x9D6A 0x6327 #CJK UNIFIED IDEOGRAPH
+0x9D6B 0x6302 #CJK UNIFIED IDEOGRAPH
+0x9D6C 0x6308 #CJK UNIFIED IDEOGRAPH
+0x9D6D 0x62EF #CJK UNIFIED IDEOGRAPH
+0x9D6E 0x62F5 #CJK UNIFIED IDEOGRAPH
+0x9D6F 0x6350 #CJK UNIFIED IDEOGRAPH
+0x9D70 0x633E #CJK UNIFIED IDEOGRAPH
+0x9D71 0x634D #CJK UNIFIED IDEOGRAPH
+0x9D72 0x641C #CJK UNIFIED IDEOGRAPH
+0x9D73 0x634F #CJK UNIFIED IDEOGRAPH
+0x9D74 0x6396 #CJK UNIFIED IDEOGRAPH
+0x9D75 0x638E #CJK UNIFIED IDEOGRAPH
+0x9D76 0x6380 #CJK UNIFIED IDEOGRAPH
+0x9D77 0x63AB #CJK UNIFIED IDEOGRAPH
+0x9D78 0x6376 #CJK UNIFIED IDEOGRAPH
+0x9D79 0x63A3 #CJK UNIFIED IDEOGRAPH
+0x9D7A 0x638F #CJK UNIFIED IDEOGRAPH
+0x9D7B 0x6389 #CJK UNIFIED IDEOGRAPH
+0x9D7C 0x639F #CJK UNIFIED IDEOGRAPH
+0x9D7D 0x63B5 #CJK UNIFIED IDEOGRAPH
+0x9D7E 0x636B #CJK UNIFIED IDEOGRAPH
+0x9D80 0x6369 #CJK UNIFIED IDEOGRAPH
+0x9D81 0x63BE #CJK UNIFIED IDEOGRAPH
+0x9D82 0x63E9 #CJK UNIFIED IDEOGRAPH
+0x9D83 0x63C0 #CJK UNIFIED IDEOGRAPH
+0x9D84 0x63C6 #CJK UNIFIED IDEOGRAPH
+0x9D85 0x63E3 #CJK UNIFIED IDEOGRAPH
+0x9D86 0x63C9 #CJK UNIFIED IDEOGRAPH
+0x9D87 0x63D2 #CJK UNIFIED IDEOGRAPH
+0x9D88 0x63F6 #CJK UNIFIED IDEOGRAPH
+0x9D89 0x63C4 #CJK UNIFIED IDEOGRAPH
+0x9D8A 0x6416 #CJK UNIFIED IDEOGRAPH
+0x9D8B 0x6434 #CJK UNIFIED IDEOGRAPH
+0x9D8C 0x6406 #CJK UNIFIED IDEOGRAPH
+0x9D8D 0x6413 #CJK UNIFIED IDEOGRAPH
+0x9D8E 0x6426 #CJK UNIFIED IDEOGRAPH
+0x9D8F 0x6436 #CJK UNIFIED IDEOGRAPH
+0x9D90 0x651D #CJK UNIFIED IDEOGRAPH
+0x9D91 0x6417 #CJK UNIFIED IDEOGRAPH
+0x9D92 0x6428 #CJK UNIFIED IDEOGRAPH
+0x9D93 0x640F #CJK UNIFIED IDEOGRAPH
+0x9D94 0x6467 #CJK UNIFIED IDEOGRAPH
+0x9D95 0x646F #CJK UNIFIED IDEOGRAPH
+0x9D96 0x6476 #CJK UNIFIED IDEOGRAPH
+0x9D97 0x644E #CJK UNIFIED IDEOGRAPH
+0x9D98 0x652A #CJK UNIFIED IDEOGRAPH
+0x9D99 0x6495 #CJK UNIFIED IDEOGRAPH
+0x9D9A 0x6493 #CJK UNIFIED IDEOGRAPH
+0x9D9B 0x64A5 #CJK UNIFIED IDEOGRAPH
+0x9D9C 0x64A9 #CJK UNIFIED IDEOGRAPH
+0x9D9D 0x6488 #CJK UNIFIED IDEOGRAPH
+0x9D9E 0x64BC #CJK UNIFIED IDEOGRAPH
+0x9D9F 0x64DA #CJK UNIFIED IDEOGRAPH
+0x9DA0 0x64D2 #CJK UNIFIED IDEOGRAPH
+0x9DA1 0x64C5 #CJK UNIFIED IDEOGRAPH
+0x9DA2 0x64C7 #CJK UNIFIED IDEOGRAPH
+0x9DA3 0x64BB #CJK UNIFIED IDEOGRAPH
+0x9DA4 0x64D8 #CJK UNIFIED IDEOGRAPH
+0x9DA5 0x64C2 #CJK UNIFIED IDEOGRAPH
+0x9DA6 0x64F1 #CJK UNIFIED IDEOGRAPH
+0x9DA7 0x64E7 #CJK UNIFIED IDEOGRAPH
+0x9DA8 0x8209 #CJK UNIFIED IDEOGRAPH
+0x9DA9 0x64E0 #CJK UNIFIED IDEOGRAPH
+0x9DAA 0x64E1 #CJK UNIFIED IDEOGRAPH
+0x9DAB 0x62AC #CJK UNIFIED IDEOGRAPH
+0x9DAC 0x64E3 #CJK UNIFIED IDEOGRAPH
+0x9DAD 0x64EF #CJK UNIFIED IDEOGRAPH
+0x9DAE 0x652C #CJK UNIFIED IDEOGRAPH
+0x9DAF 0x64F6 #CJK UNIFIED IDEOGRAPH
+0x9DB0 0x64F4 #CJK UNIFIED IDEOGRAPH
+0x9DB1 0x64F2 #CJK UNIFIED IDEOGRAPH
+0x9DB2 0x64FA #CJK UNIFIED IDEOGRAPH
+0x9DB3 0x6500 #CJK UNIFIED IDEOGRAPH
+0x9DB4 0x64FD #CJK UNIFIED IDEOGRAPH
+0x9DB5 0x6518 #CJK UNIFIED IDEOGRAPH
+0x9DB6 0x651C #CJK UNIFIED IDEOGRAPH
+0x9DB7 0x6505 #CJK UNIFIED IDEOGRAPH
+0x9DB8 0x6524 #CJK UNIFIED IDEOGRAPH
+0x9DB9 0x6523 #CJK UNIFIED IDEOGRAPH
+0x9DBA 0x652B #CJK UNIFIED IDEOGRAPH
+0x9DBB 0x6534 #CJK UNIFIED IDEOGRAPH
+0x9DBC 0x6535 #CJK UNIFIED IDEOGRAPH
+0x9DBD 0x6537 #CJK UNIFIED IDEOGRAPH
+0x9DBE 0x6536 #CJK UNIFIED IDEOGRAPH
+0x9DBF 0x6538 #CJK UNIFIED IDEOGRAPH
+0x9DC0 0x754B #CJK UNIFIED IDEOGRAPH
+0x9DC1 0x6548 #CJK UNIFIED IDEOGRAPH
+0x9DC2 0x6556 #CJK UNIFIED IDEOGRAPH
+0x9DC3 0x6555 #CJK UNIFIED IDEOGRAPH
+0x9DC4 0x654D #CJK UNIFIED IDEOGRAPH
+0x9DC5 0x6558 #CJK UNIFIED IDEOGRAPH
+0x9DC6 0x655E #CJK UNIFIED IDEOGRAPH
+0x9DC7 0x655D #CJK UNIFIED IDEOGRAPH
+0x9DC8 0x6572 #CJK UNIFIED IDEOGRAPH
+0x9DC9 0x6578 #CJK UNIFIED IDEOGRAPH
+0x9DCA 0x6582 #CJK UNIFIED IDEOGRAPH
+0x9DCB 0x6583 #CJK UNIFIED IDEOGRAPH
+0x9DCC 0x8B8A #CJK UNIFIED IDEOGRAPH
+0x9DCD 0x659B #CJK UNIFIED IDEOGRAPH
+0x9DCE 0x659F #CJK UNIFIED IDEOGRAPH
+0x9DCF 0x65AB #CJK UNIFIED IDEOGRAPH
+0x9DD0 0x65B7 #CJK UNIFIED IDEOGRAPH
+0x9DD1 0x65C3 #CJK UNIFIED IDEOGRAPH
+0x9DD2 0x65C6 #CJK UNIFIED IDEOGRAPH
+0x9DD3 0x65C1 #CJK UNIFIED IDEOGRAPH
+0x9DD4 0x65C4 #CJK UNIFIED IDEOGRAPH
+0x9DD5 0x65CC #CJK UNIFIED IDEOGRAPH
+0x9DD6 0x65D2 #CJK UNIFIED IDEOGRAPH
+0x9DD7 0x65DB #CJK UNIFIED IDEOGRAPH
+0x9DD8 0x65D9 #CJK UNIFIED IDEOGRAPH
+0x9DD9 0x65E0 #CJK UNIFIED IDEOGRAPH
+0x9DDA 0x65E1 #CJK UNIFIED IDEOGRAPH
+0x9DDB 0x65F1 #CJK UNIFIED IDEOGRAPH
+0x9DDC 0x6772 #CJK UNIFIED IDEOGRAPH
+0x9DDD 0x660A #CJK UNIFIED IDEOGRAPH
+0x9DDE 0x6603 #CJK UNIFIED IDEOGRAPH
+0x9DDF 0x65FB #CJK UNIFIED IDEOGRAPH
+0x9DE0 0x6773 #CJK UNIFIED IDEOGRAPH
+0x9DE1 0x6635 #CJK UNIFIED IDEOGRAPH
+0x9DE2 0x6636 #CJK UNIFIED IDEOGRAPH
+0x9DE3 0x6634 #CJK UNIFIED IDEOGRAPH
+0x9DE4 0x661C #CJK UNIFIED IDEOGRAPH
+0x9DE5 0x664F #CJK UNIFIED IDEOGRAPH
+0x9DE6 0x6644 #CJK UNIFIED IDEOGRAPH
+0x9DE7 0x6649 #CJK UNIFIED IDEOGRAPH
+0x9DE8 0x6641 #CJK UNIFIED IDEOGRAPH
+0x9DE9 0x665E #CJK UNIFIED IDEOGRAPH
+0x9DEA 0x665D #CJK UNIFIED IDEOGRAPH
+0x9DEB 0x6664 #CJK UNIFIED IDEOGRAPH
+0x9DEC 0x6667 #CJK UNIFIED IDEOGRAPH
+0x9DED 0x6668 #CJK UNIFIED IDEOGRAPH
+0x9DEE 0x665F #CJK UNIFIED IDEOGRAPH
+0x9DEF 0x6662 #CJK UNIFIED IDEOGRAPH
+0x9DF0 0x6670 #CJK UNIFIED IDEOGRAPH
+0x9DF1 0x6683 #CJK UNIFIED IDEOGRAPH
+0x9DF2 0x6688 #CJK UNIFIED IDEOGRAPH
+0x9DF3 0x668E #CJK UNIFIED IDEOGRAPH
+0x9DF4 0x6689 #CJK UNIFIED IDEOGRAPH
+0x9DF5 0x6684 #CJK UNIFIED IDEOGRAPH
+0x9DF6 0x6698 #CJK UNIFIED IDEOGRAPH
+0x9DF7 0x669D #CJK UNIFIED IDEOGRAPH
+0x9DF8 0x66C1 #CJK UNIFIED IDEOGRAPH
+0x9DF9 0x66B9 #CJK UNIFIED IDEOGRAPH
+0x9DFA 0x66C9 #CJK UNIFIED IDEOGRAPH
+0x9DFB 0x66BE #CJK UNIFIED IDEOGRAPH
+0x9DFC 0x66BC #CJK UNIFIED IDEOGRAPH
+0x9E40 0x66C4 #CJK UNIFIED IDEOGRAPH
+0x9E41 0x66B8 #CJK UNIFIED IDEOGRAPH
+0x9E42 0x66D6 #CJK UNIFIED IDEOGRAPH
+0x9E43 0x66DA #CJK UNIFIED IDEOGRAPH
+0x9E44 0x66E0 #CJK UNIFIED IDEOGRAPH
+0x9E45 0x663F #CJK UNIFIED IDEOGRAPH
+0x9E46 0x66E6 #CJK UNIFIED IDEOGRAPH
+0x9E47 0x66E9 #CJK UNIFIED IDEOGRAPH
+0x9E48 0x66F0 #CJK UNIFIED IDEOGRAPH
+0x9E49 0x66F5 #CJK UNIFIED IDEOGRAPH
+0x9E4A 0x66F7 #CJK UNIFIED IDEOGRAPH
+0x9E4B 0x670F #CJK UNIFIED IDEOGRAPH
+0x9E4C 0x6716 #CJK UNIFIED IDEOGRAPH
+0x9E4D 0x671E #CJK UNIFIED IDEOGRAPH
+0x9E4E 0x6726 #CJK UNIFIED IDEOGRAPH
+0x9E4F 0x6727 #CJK UNIFIED IDEOGRAPH
+0x9E50 0x9738 #CJK UNIFIED IDEOGRAPH
+0x9E51 0x672E #CJK UNIFIED IDEOGRAPH
+0x9E52 0x673F #CJK UNIFIED IDEOGRAPH
+0x9E53 0x6736 #CJK UNIFIED IDEOGRAPH
+0x9E54 0x6741 #CJK UNIFIED IDEOGRAPH
+0x9E55 0x6738 #CJK UNIFIED IDEOGRAPH
+0x9E56 0x6737 #CJK UNIFIED IDEOGRAPH
+0x9E57 0x6746 #CJK UNIFIED IDEOGRAPH
+0x9E58 0x675E #CJK UNIFIED IDEOGRAPH
+0x9E59 0x6760 #CJK UNIFIED IDEOGRAPH
+0x9E5A 0x6759 #CJK UNIFIED IDEOGRAPH
+0x9E5B 0x6763 #CJK UNIFIED IDEOGRAPH
+0x9E5C 0x6764 #CJK UNIFIED IDEOGRAPH
+0x9E5D 0x6789 #CJK UNIFIED IDEOGRAPH
+0x9E5E 0x6770 #CJK UNIFIED IDEOGRAPH
+0x9E5F 0x67A9 #CJK UNIFIED IDEOGRAPH
+0x9E60 0x677C #CJK UNIFIED IDEOGRAPH
+0x9E61 0x676A #CJK UNIFIED IDEOGRAPH
+0x9E62 0x678C #CJK UNIFIED IDEOGRAPH
+0x9E63 0x678B #CJK UNIFIED IDEOGRAPH
+0x9E64 0x67A6 #CJK UNIFIED IDEOGRAPH
+0x9E65 0x67A1 #CJK UNIFIED IDEOGRAPH
+0x9E66 0x6785 #CJK UNIFIED IDEOGRAPH
+0x9E67 0x67B7 #CJK UNIFIED IDEOGRAPH
+0x9E68 0x67EF #CJK UNIFIED IDEOGRAPH
+0x9E69 0x67B4 #CJK UNIFIED IDEOGRAPH
+0x9E6A 0x67EC #CJK UNIFIED IDEOGRAPH
+0x9E6B 0x67B3 #CJK UNIFIED IDEOGRAPH
+0x9E6C 0x67E9 #CJK UNIFIED IDEOGRAPH
+0x9E6D 0x67B8 #CJK UNIFIED IDEOGRAPH
+0x9E6E 0x67E4 #CJK UNIFIED IDEOGRAPH
+0x9E6F 0x67DE #CJK UNIFIED IDEOGRAPH
+0x9E70 0x67DD #CJK UNIFIED IDEOGRAPH
+0x9E71 0x67E2 #CJK UNIFIED IDEOGRAPH
+0x9E72 0x67EE #CJK UNIFIED IDEOGRAPH
+0x9E73 0x67B9 #CJK UNIFIED IDEOGRAPH
+0x9E74 0x67CE #CJK UNIFIED IDEOGRAPH
+0x9E75 0x67C6 #CJK UNIFIED IDEOGRAPH
+0x9E76 0x67E7 #CJK UNIFIED IDEOGRAPH
+0x9E77 0x6A9C #CJK UNIFIED IDEOGRAPH
+0x9E78 0x681E #CJK UNIFIED IDEOGRAPH
+0x9E79 0x6846 #CJK UNIFIED IDEOGRAPH
+0x9E7A 0x6829 #CJK UNIFIED IDEOGRAPH
+0x9E7B 0x6840 #CJK UNIFIED IDEOGRAPH
+0x9E7C 0x684D #CJK UNIFIED IDEOGRAPH
+0x9E7D 0x6832 #CJK UNIFIED IDEOGRAPH
+0x9E7E 0x684E #CJK UNIFIED IDEOGRAPH
+0x9E80 0x68B3 #CJK UNIFIED IDEOGRAPH
+0x9E81 0x682B #CJK UNIFIED IDEOGRAPH
+0x9E82 0x6859 #CJK UNIFIED IDEOGRAPH
+0x9E83 0x6863 #CJK UNIFIED IDEOGRAPH
+0x9E84 0x6877 #CJK UNIFIED IDEOGRAPH
+0x9E85 0x687F #CJK UNIFIED IDEOGRAPH
+0x9E86 0x689F #CJK UNIFIED IDEOGRAPH
+0x9E87 0x688F #CJK UNIFIED IDEOGRAPH
+0x9E88 0x68AD #CJK UNIFIED IDEOGRAPH
+0x9E89 0x6894 #CJK UNIFIED IDEOGRAPH
+0x9E8A 0x689D #CJK UNIFIED IDEOGRAPH
+0x9E8B 0x689B #CJK UNIFIED IDEOGRAPH
+0x9E8C 0x6883 #CJK UNIFIED IDEOGRAPH
+0x9E8D 0x6AAE #CJK UNIFIED IDEOGRAPH
+0x9E8E 0x68B9 #CJK UNIFIED IDEOGRAPH
+0x9E8F 0x6874 #CJK UNIFIED IDEOGRAPH
+0x9E90 0x68B5 #CJK UNIFIED IDEOGRAPH
+0x9E91 0x68A0 #CJK UNIFIED IDEOGRAPH
+0x9E92 0x68BA #CJK UNIFIED IDEOGRAPH
+0x9E93 0x690F #CJK UNIFIED IDEOGRAPH
+0x9E94 0x688D #CJK UNIFIED IDEOGRAPH
+0x9E95 0x687E #CJK UNIFIED IDEOGRAPH
+0x9E96 0x6901 #CJK UNIFIED IDEOGRAPH
+0x9E97 0x68CA #CJK UNIFIED IDEOGRAPH
+0x9E98 0x6908 #CJK UNIFIED IDEOGRAPH
+0x9E99 0x68D8 #CJK UNIFIED IDEOGRAPH
+0x9E9A 0x6922 #CJK UNIFIED IDEOGRAPH
+0x9E9B 0x6926 #CJK UNIFIED IDEOGRAPH
+0x9E9C 0x68E1 #CJK UNIFIED IDEOGRAPH
+0x9E9D 0x690C #CJK UNIFIED IDEOGRAPH
+0x9E9E 0x68CD #CJK UNIFIED IDEOGRAPH
+0x9E9F 0x68D4 #CJK UNIFIED IDEOGRAPH
+0x9EA0 0x68E7 #CJK UNIFIED IDEOGRAPH
+0x9EA1 0x68D5 #CJK UNIFIED IDEOGRAPH
+0x9EA2 0x6936 #CJK UNIFIED IDEOGRAPH
+0x9EA3 0x6912 #CJK UNIFIED IDEOGRAPH
+0x9EA4 0x6904 #CJK UNIFIED IDEOGRAPH
+0x9EA5 0x68D7 #CJK UNIFIED IDEOGRAPH
+0x9EA6 0x68E3 #CJK UNIFIED IDEOGRAPH
+0x9EA7 0x6925 #CJK UNIFIED IDEOGRAPH
+0x9EA8 0x68F9 #CJK UNIFIED IDEOGRAPH
+0x9EA9 0x68E0 #CJK UNIFIED IDEOGRAPH
+0x9EAA 0x68EF #CJK UNIFIED IDEOGRAPH
+0x9EAB 0x6928 #CJK UNIFIED IDEOGRAPH
+0x9EAC 0x692A #CJK UNIFIED IDEOGRAPH
+0x9EAD 0x691A #CJK UNIFIED IDEOGRAPH
+0x9EAE 0x6923 #CJK UNIFIED IDEOGRAPH
+0x9EAF 0x6921 #CJK UNIFIED IDEOGRAPH
+0x9EB0 0x68C6 #CJK UNIFIED IDEOGRAPH
+0x9EB1 0x6979 #CJK UNIFIED IDEOGRAPH
+0x9EB2 0x6977 #CJK UNIFIED IDEOGRAPH
+0x9EB3 0x695C #CJK UNIFIED IDEOGRAPH
+0x9EB4 0x6978 #CJK UNIFIED IDEOGRAPH
+0x9EB5 0x696B #CJK UNIFIED IDEOGRAPH
+0x9EB6 0x6954 #CJK UNIFIED IDEOGRAPH
+0x9EB7 0x697E #CJK UNIFIED IDEOGRAPH
+0x9EB8 0x696E #CJK UNIFIED IDEOGRAPH
+0x9EB9 0x6939 #CJK UNIFIED IDEOGRAPH
+0x9EBA 0x6974 #CJK UNIFIED IDEOGRAPH
+0x9EBB 0x693D #CJK UNIFIED IDEOGRAPH
+0x9EBC 0x6959 #CJK UNIFIED IDEOGRAPH
+0x9EBD 0x6930 #CJK UNIFIED IDEOGRAPH
+0x9EBE 0x6961 #CJK UNIFIED IDEOGRAPH
+0x9EBF 0x695E #CJK UNIFIED IDEOGRAPH
+0x9EC0 0x695D #CJK UNIFIED IDEOGRAPH
+0x9EC1 0x6981 #CJK UNIFIED IDEOGRAPH
+0x9EC2 0x696A #CJK UNIFIED IDEOGRAPH
+0x9EC3 0x69B2 #CJK UNIFIED IDEOGRAPH
+0x9EC4 0x69AE #CJK UNIFIED IDEOGRAPH
+0x9EC5 0x69D0 #CJK UNIFIED IDEOGRAPH
+0x9EC6 0x69BF #CJK UNIFIED IDEOGRAPH
+0x9EC7 0x69C1 #CJK UNIFIED IDEOGRAPH
+0x9EC8 0x69D3 #CJK UNIFIED IDEOGRAPH
+0x9EC9 0x69BE #CJK UNIFIED IDEOGRAPH
+0x9ECA 0x69CE #CJK UNIFIED IDEOGRAPH
+0x9ECB 0x5BE8 #CJK UNIFIED IDEOGRAPH
+0x9ECC 0x69CA #CJK UNIFIED IDEOGRAPH
+0x9ECD 0x69DD #CJK UNIFIED IDEOGRAPH
+0x9ECE 0x69BB #CJK UNIFIED IDEOGRAPH
+0x9ECF 0x69C3 #CJK UNIFIED IDEOGRAPH
+0x9ED0 0x69A7 #CJK UNIFIED IDEOGRAPH
+0x9ED1 0x6A2E #CJK UNIFIED IDEOGRAPH
+0x9ED2 0x6991 #CJK UNIFIED IDEOGRAPH
+0x9ED3 0x69A0 #CJK UNIFIED IDEOGRAPH
+0x9ED4 0x699C #CJK UNIFIED IDEOGRAPH
+0x9ED5 0x6995 #CJK UNIFIED IDEOGRAPH
+0x9ED6 0x69B4 #CJK UNIFIED IDEOGRAPH
+0x9ED7 0x69DE #CJK UNIFIED IDEOGRAPH
+0x9ED8 0x69E8 #CJK UNIFIED IDEOGRAPH
+0x9ED9 0x6A02 #CJK UNIFIED IDEOGRAPH
+0x9EDA 0x6A1B #CJK UNIFIED IDEOGRAPH
+0x9EDB 0x69FF #CJK UNIFIED IDEOGRAPH
+0x9EDC 0x6B0A #CJK UNIFIED IDEOGRAPH
+0x9EDD 0x69F9 #CJK UNIFIED IDEOGRAPH
+0x9EDE 0x69F2 #CJK UNIFIED IDEOGRAPH
+0x9EDF 0x69E7 #CJK UNIFIED IDEOGRAPH
+0x9EE0 0x6A05 #CJK UNIFIED IDEOGRAPH
+0x9EE1 0x69B1 #CJK UNIFIED IDEOGRAPH
+0x9EE2 0x6A1E #CJK UNIFIED IDEOGRAPH
+0x9EE3 0x69ED #CJK UNIFIED IDEOGRAPH
+0x9EE4 0x6A14 #CJK UNIFIED IDEOGRAPH
+0x9EE5 0x69EB #CJK UNIFIED IDEOGRAPH
+0x9EE6 0x6A0A #CJK UNIFIED IDEOGRAPH
+0x9EE7 0x6A12 #CJK UNIFIED IDEOGRAPH
+0x9EE8 0x6AC1 #CJK UNIFIED IDEOGRAPH
+0x9EE9 0x6A23 #CJK UNIFIED IDEOGRAPH
+0x9EEA 0x6A13 #CJK UNIFIED IDEOGRAPH
+0x9EEB 0x6A44 #CJK UNIFIED IDEOGRAPH
+0x9EEC 0x6A0C #CJK UNIFIED IDEOGRAPH
+0x9EED 0x6A72 #CJK UNIFIED IDEOGRAPH
+0x9EEE 0x6A36 #CJK UNIFIED IDEOGRAPH
+0x9EEF 0x6A78 #CJK UNIFIED IDEOGRAPH
+0x9EF0 0x6A47 #CJK UNIFIED IDEOGRAPH
+0x9EF1 0x6A62 #CJK UNIFIED IDEOGRAPH
+0x9EF2 0x6A59 #CJK UNIFIED IDEOGRAPH
+0x9EF3 0x6A66 #CJK UNIFIED IDEOGRAPH
+0x9EF4 0x6A48 #CJK UNIFIED IDEOGRAPH
+0x9EF5 0x6A38 #CJK UNIFIED IDEOGRAPH
+0x9EF6 0x6A22 #CJK UNIFIED IDEOGRAPH
+0x9EF7 0x6A90 #CJK UNIFIED IDEOGRAPH
+0x9EF8 0x6A8D #CJK UNIFIED IDEOGRAPH
+0x9EF9 0x6AA0 #CJK UNIFIED IDEOGRAPH
+0x9EFA 0x6A84 #CJK UNIFIED IDEOGRAPH
+0x9EFB 0x6AA2 #CJK UNIFIED IDEOGRAPH
+0x9EFC 0x6AA3 #CJK UNIFIED IDEOGRAPH
+0x9F40 0x6A97 #CJK UNIFIED IDEOGRAPH
+0x9F41 0x8617 #CJK UNIFIED IDEOGRAPH
+0x9F42 0x6ABB #CJK UNIFIED IDEOGRAPH
+0x9F43 0x6AC3 #CJK UNIFIED IDEOGRAPH
+0x9F44 0x6AC2 #CJK UNIFIED IDEOGRAPH
+0x9F45 0x6AB8 #CJK UNIFIED IDEOGRAPH
+0x9F46 0x6AB3 #CJK UNIFIED IDEOGRAPH
+0x9F47 0x6AAC #CJK UNIFIED IDEOGRAPH
+0x9F48 0x6ADE #CJK UNIFIED IDEOGRAPH
+0x9F49 0x6AD1 #CJK UNIFIED IDEOGRAPH
+0x9F4A 0x6ADF #CJK UNIFIED IDEOGRAPH
+0x9F4B 0x6AAA #CJK UNIFIED IDEOGRAPH
+0x9F4C 0x6ADA #CJK UNIFIED IDEOGRAPH
+0x9F4D 0x6AEA #CJK UNIFIED IDEOGRAPH
+0x9F4E 0x6AFB #CJK UNIFIED IDEOGRAPH
+0x9F4F 0x6B05 #CJK UNIFIED IDEOGRAPH
+0x9F50 0x8616 #CJK UNIFIED IDEOGRAPH
+0x9F51 0x6AFA #CJK UNIFIED IDEOGRAPH
+0x9F52 0x6B12 #CJK UNIFIED IDEOGRAPH
+0x9F53 0x6B16 #CJK UNIFIED IDEOGRAPH
+0x9F54 0x9B31 #CJK UNIFIED IDEOGRAPH
+0x9F55 0x6B1F #CJK UNIFIED IDEOGRAPH
+0x9F56 0x6B38 #CJK UNIFIED IDEOGRAPH
+0x9F57 0x6B37 #CJK UNIFIED IDEOGRAPH
+0x9F58 0x76DC #CJK UNIFIED IDEOGRAPH
+0x9F59 0x6B39 #CJK UNIFIED IDEOGRAPH
+0x9F5A 0x98EE #CJK UNIFIED IDEOGRAPH
+0x9F5B 0x6B47 #CJK UNIFIED IDEOGRAPH
+0x9F5C 0x6B43 #CJK UNIFIED IDEOGRAPH
+0x9F5D 0x6B49 #CJK UNIFIED IDEOGRAPH
+0x9F5E 0x6B50 #CJK UNIFIED IDEOGRAPH
+0x9F5F 0x6B59 #CJK UNIFIED IDEOGRAPH
+0x9F60 0x6B54 #CJK UNIFIED IDEOGRAPH
+0x9F61 0x6B5B #CJK UNIFIED IDEOGRAPH
+0x9F62 0x6B5F #CJK UNIFIED IDEOGRAPH
+0x9F63 0x6B61 #CJK UNIFIED IDEOGRAPH
+0x9F64 0x6B78 #CJK UNIFIED IDEOGRAPH
+0x9F65 0x6B79 #CJK UNIFIED IDEOGRAPH
+0x9F66 0x6B7F #CJK UNIFIED IDEOGRAPH
+0x9F67 0x6B80 #CJK UNIFIED IDEOGRAPH
+0x9F68 0x6B84 #CJK UNIFIED IDEOGRAPH
+0x9F69 0x6B83 #CJK UNIFIED IDEOGRAPH
+0x9F6A 0x6B8D #CJK UNIFIED IDEOGRAPH
+0x9F6B 0x6B98 #CJK UNIFIED IDEOGRAPH
+0x9F6C 0x6B95 #CJK UNIFIED IDEOGRAPH
+0x9F6D 0x6B9E #CJK UNIFIED IDEOGRAPH
+0x9F6E 0x6BA4 #CJK UNIFIED IDEOGRAPH
+0x9F6F 0x6BAA #CJK UNIFIED IDEOGRAPH
+0x9F70 0x6BAB #CJK UNIFIED IDEOGRAPH
+0x9F71 0x6BAF #CJK UNIFIED IDEOGRAPH
+0x9F72 0x6BB2 #CJK UNIFIED IDEOGRAPH
+0x9F73 0x6BB1 #CJK UNIFIED IDEOGRAPH
+0x9F74 0x6BB3 #CJK UNIFIED IDEOGRAPH
+0x9F75 0x6BB7 #CJK UNIFIED IDEOGRAPH
+0x9F76 0x6BBC #CJK UNIFIED IDEOGRAPH
+0x9F77 0x6BC6 #CJK UNIFIED IDEOGRAPH
+0x9F78 0x6BCB #CJK UNIFIED IDEOGRAPH
+0x9F79 0x6BD3 #CJK UNIFIED IDEOGRAPH
+0x9F7A 0x6BDF #CJK UNIFIED IDEOGRAPH
+0x9F7B 0x6BEC #CJK UNIFIED IDEOGRAPH
+0x9F7C 0x6BEB #CJK UNIFIED IDEOGRAPH
+0x9F7D 0x6BF3 #CJK UNIFIED IDEOGRAPH
+0x9F7E 0x6BEF #CJK UNIFIED IDEOGRAPH
+0x9F80 0x9EBE #CJK UNIFIED IDEOGRAPH
+0x9F81 0x6C08 #CJK UNIFIED IDEOGRAPH
+0x9F82 0x6C13 #CJK UNIFIED IDEOGRAPH
+0x9F83 0x6C14 #CJK UNIFIED IDEOGRAPH
+0x9F84 0x6C1B #CJK UNIFIED IDEOGRAPH
+0x9F85 0x6C24 #CJK UNIFIED IDEOGRAPH
+0x9F86 0x6C23 #CJK UNIFIED IDEOGRAPH
+0x9F87 0x6C5E #CJK UNIFIED IDEOGRAPH
+0x9F88 0x6C55 #CJK UNIFIED IDEOGRAPH
+0x9F89 0x6C62 #CJK UNIFIED IDEOGRAPH
+0x9F8A 0x6C6A #CJK UNIFIED IDEOGRAPH
+0x9F8B 0x6C82 #CJK UNIFIED IDEOGRAPH
+0x9F8C 0x6C8D #CJK UNIFIED IDEOGRAPH
+0x9F8D 0x6C9A #CJK UNIFIED IDEOGRAPH
+0x9F8E 0x6C81 #CJK UNIFIED IDEOGRAPH
+0x9F8F 0x6C9B #CJK UNIFIED IDEOGRAPH
+0x9F90 0x6C7E #CJK UNIFIED IDEOGRAPH
+0x9F91 0x6C68 #CJK UNIFIED IDEOGRAPH
+0x9F92 0x6C73 #CJK UNIFIED IDEOGRAPH
+0x9F93 0x6C92 #CJK UNIFIED IDEOGRAPH
+0x9F94 0x6C90 #CJK UNIFIED IDEOGRAPH
+0x9F95 0x6CC4 #CJK UNIFIED IDEOGRAPH
+0x9F96 0x6CF1 #CJK UNIFIED IDEOGRAPH
+0x9F97 0x6CD3 #CJK UNIFIED IDEOGRAPH
+0x9F98 0x6CBD #CJK UNIFIED IDEOGRAPH
+0x9F99 0x6CD7 #CJK UNIFIED IDEOGRAPH
+0x9F9A 0x6CC5 #CJK UNIFIED IDEOGRAPH
+0x9F9B 0x6CDD #CJK UNIFIED IDEOGRAPH
+0x9F9C 0x6CAE #CJK UNIFIED IDEOGRAPH
+0x9F9D 0x6CB1 #CJK UNIFIED IDEOGRAPH
+0x9F9E 0x6CBE #CJK UNIFIED IDEOGRAPH
+0x9F9F 0x6CBA #CJK UNIFIED IDEOGRAPH
+0x9FA0 0x6CDB #CJK UNIFIED IDEOGRAPH
+0x9FA1 0x6CEF #CJK UNIFIED IDEOGRAPH
+0x9FA2 0x6CD9 #CJK UNIFIED IDEOGRAPH
+0x9FA3 0x6CEA #CJK UNIFIED IDEOGRAPH
+0x9FA4 0x6D1F #CJK UNIFIED IDEOGRAPH
+0x9FA5 0x884D #CJK UNIFIED IDEOGRAPH
+0x9FA6 0x6D36 #CJK UNIFIED IDEOGRAPH
+0x9FA7 0x6D2B #CJK UNIFIED IDEOGRAPH
+0x9FA8 0x6D3D #CJK UNIFIED IDEOGRAPH
+0x9FA9 0x6D38 #CJK UNIFIED IDEOGRAPH
+0x9FAA 0x6D19 #CJK UNIFIED IDEOGRAPH
+0x9FAB 0x6D35 #CJK UNIFIED IDEOGRAPH
+0x9FAC 0x6D33 #CJK UNIFIED IDEOGRAPH
+0x9FAD 0x6D12 #CJK UNIFIED IDEOGRAPH
+0x9FAE 0x6D0C #CJK UNIFIED IDEOGRAPH
+0x9FAF 0x6D63 #CJK UNIFIED IDEOGRAPH
+0x9FB0 0x6D93 #CJK UNIFIED IDEOGRAPH
+0x9FB1 0x6D64 #CJK UNIFIED IDEOGRAPH
+0x9FB2 0x6D5A #CJK UNIFIED IDEOGRAPH
+0x9FB3 0x6D79 #CJK UNIFIED IDEOGRAPH
+0x9FB4 0x6D59 #CJK UNIFIED IDEOGRAPH
+0x9FB5 0x6D8E #CJK UNIFIED IDEOGRAPH
+0x9FB6 0x6D95 #CJK UNIFIED IDEOGRAPH
+0x9FB7 0x6FE4 #CJK UNIFIED IDEOGRAPH
+0x9FB8 0x6D85 #CJK UNIFIED IDEOGRAPH
+0x9FB9 0x6DF9 #CJK UNIFIED IDEOGRAPH
+0x9FBA 0x6E15 #CJK UNIFIED IDEOGRAPH
+0x9FBB 0x6E0A #CJK UNIFIED IDEOGRAPH
+0x9FBC 0x6DB5 #CJK UNIFIED IDEOGRAPH
+0x9FBD 0x6DC7 #CJK UNIFIED IDEOGRAPH
+0x9FBE 0x6DE6 #CJK UNIFIED IDEOGRAPH
+0x9FBF 0x6DB8 #CJK UNIFIED IDEOGRAPH
+0x9FC0 0x6DC6 #CJK UNIFIED IDEOGRAPH
+0x9FC1 0x6DEC #CJK UNIFIED IDEOGRAPH
+0x9FC2 0x6DDE #CJK UNIFIED IDEOGRAPH
+0x9FC3 0x6DCC #CJK UNIFIED IDEOGRAPH
+0x9FC4 0x6DE8 #CJK UNIFIED IDEOGRAPH
+0x9FC5 0x6DD2 #CJK UNIFIED IDEOGRAPH
+0x9FC6 0x6DC5 #CJK UNIFIED IDEOGRAPH
+0x9FC7 0x6DFA #CJK UNIFIED IDEOGRAPH
+0x9FC8 0x6DD9 #CJK UNIFIED IDEOGRAPH
+0x9FC9 0x6DE4 #CJK UNIFIED IDEOGRAPH
+0x9FCA 0x6DD5 #CJK UNIFIED IDEOGRAPH
+0x9FCB 0x6DEA #CJK UNIFIED IDEOGRAPH
+0x9FCC 0x6DEE #CJK UNIFIED IDEOGRAPH
+0x9FCD 0x6E2D #CJK UNIFIED IDEOGRAPH
+0x9FCE 0x6E6E #CJK UNIFIED IDEOGRAPH
+0x9FCF 0x6E2E #CJK UNIFIED IDEOGRAPH
+0x9FD0 0x6E19 #CJK UNIFIED IDEOGRAPH
+0x9FD1 0x6E72 #CJK UNIFIED IDEOGRAPH
+0x9FD2 0x6E5F #CJK UNIFIED IDEOGRAPH
+0x9FD3 0x6E3E #CJK UNIFIED IDEOGRAPH
+0x9FD4 0x6E23 #CJK UNIFIED IDEOGRAPH
+0x9FD5 0x6E6B #CJK UNIFIED IDEOGRAPH
+0x9FD6 0x6E2B #CJK UNIFIED IDEOGRAPH
+0x9FD7 0x6E76 #CJK UNIFIED IDEOGRAPH
+0x9FD8 0x6E4D #CJK UNIFIED IDEOGRAPH
+0x9FD9 0x6E1F #CJK UNIFIED IDEOGRAPH
+0x9FDA 0x6E43 #CJK UNIFIED IDEOGRAPH
+0x9FDB 0x6E3A #CJK UNIFIED IDEOGRAPH
+0x9FDC 0x6E4E #CJK UNIFIED IDEOGRAPH
+0x9FDD 0x6E24 #CJK UNIFIED IDEOGRAPH
+0x9FDE 0x6EFF #CJK UNIFIED IDEOGRAPH
+0x9FDF 0x6E1D #CJK UNIFIED IDEOGRAPH
+0x9FE0 0x6E38 #CJK UNIFIED IDEOGRAPH
+0x9FE1 0x6E82 #CJK UNIFIED IDEOGRAPH
+0x9FE2 0x6EAA #CJK UNIFIED IDEOGRAPH
+0x9FE3 0x6E98 #CJK UNIFIED IDEOGRAPH
+0x9FE4 0x6EC9 #CJK UNIFIED IDEOGRAPH
+0x9FE5 0x6EB7 #CJK UNIFIED IDEOGRAPH
+0x9FE6 0x6ED3 #CJK UNIFIED IDEOGRAPH
+0x9FE7 0x6EBD #CJK UNIFIED IDEOGRAPH
+0x9FE8 0x6EAF #CJK UNIFIED IDEOGRAPH
+0x9FE9 0x6EC4 #CJK UNIFIED IDEOGRAPH
+0x9FEA 0x6EB2 #CJK UNIFIED IDEOGRAPH
+0x9FEB 0x6ED4 #CJK UNIFIED IDEOGRAPH
+0x9FEC 0x6ED5 #CJK UNIFIED IDEOGRAPH
+0x9FED 0x6E8F #CJK UNIFIED IDEOGRAPH
+0x9FEE 0x6EA5 #CJK UNIFIED IDEOGRAPH
+0x9FEF 0x6EC2 #CJK UNIFIED IDEOGRAPH
+0x9FF0 0x6E9F #CJK UNIFIED IDEOGRAPH
+0x9FF1 0x6F41 #CJK UNIFIED IDEOGRAPH
+0x9FF2 0x6F11 #CJK UNIFIED IDEOGRAPH
+0x9FF3 0x704C #CJK UNIFIED IDEOGRAPH
+0x9FF4 0x6EEC #CJK UNIFIED IDEOGRAPH
+0x9FF5 0x6EF8 #CJK UNIFIED IDEOGRAPH
+0x9FF6 0x6EFE #CJK UNIFIED IDEOGRAPH
+0x9FF7 0x6F3F #CJK UNIFIED IDEOGRAPH
+0x9FF8 0x6EF2 #CJK UNIFIED IDEOGRAPH
+0x9FF9 0x6F31 #CJK UNIFIED IDEOGRAPH
+0x9FFA 0x6EEF #CJK UNIFIED IDEOGRAPH
+0x9FFB 0x6F32 #CJK UNIFIED IDEOGRAPH
+0x9FFC 0x6ECC #CJK UNIFIED IDEOGRAPH
+0xE040 0x6F3E #CJK UNIFIED IDEOGRAPH
+0xE041 0x6F13 #CJK UNIFIED IDEOGRAPH
+0xE042 0x6EF7 #CJK UNIFIED IDEOGRAPH
+0xE043 0x6F86 #CJK UNIFIED IDEOGRAPH
+0xE044 0x6F7A #CJK UNIFIED IDEOGRAPH
+0xE045 0x6F78 #CJK UNIFIED IDEOGRAPH
+0xE046 0x6F81 #CJK UNIFIED IDEOGRAPH
+0xE047 0x6F80 #CJK UNIFIED IDEOGRAPH
+0xE048 0x6F6F #CJK UNIFIED IDEOGRAPH
+0xE049 0x6F5B #CJK UNIFIED IDEOGRAPH
+0xE04A 0x6FF3 #CJK UNIFIED IDEOGRAPH
+0xE04B 0x6F6D #CJK UNIFIED IDEOGRAPH
+0xE04C 0x6F82 #CJK UNIFIED IDEOGRAPH
+0xE04D 0x6F7C #CJK UNIFIED IDEOGRAPH
+0xE04E 0x6F58 #CJK UNIFIED IDEOGRAPH
+0xE04F 0x6F8E #CJK UNIFIED IDEOGRAPH
+0xE050 0x6F91 #CJK UNIFIED IDEOGRAPH
+0xE051 0x6FC2 #CJK UNIFIED IDEOGRAPH
+0xE052 0x6F66 #CJK UNIFIED IDEOGRAPH
+0xE053 0x6FB3 #CJK UNIFIED IDEOGRAPH
+0xE054 0x6FA3 #CJK UNIFIED IDEOGRAPH
+0xE055 0x6FA1 #CJK UNIFIED IDEOGRAPH
+0xE056 0x6FA4 #CJK UNIFIED IDEOGRAPH
+0xE057 0x6FB9 #CJK UNIFIED IDEOGRAPH
+0xE058 0x6FC6 #CJK UNIFIED IDEOGRAPH
+0xE059 0x6FAA #CJK UNIFIED IDEOGRAPH
+0xE05A 0x6FDF #CJK UNIFIED IDEOGRAPH
+0xE05B 0x6FD5 #CJK UNIFIED IDEOGRAPH
+0xE05C 0x6FEC #CJK UNIFIED IDEOGRAPH
+0xE05D 0x6FD4 #CJK UNIFIED IDEOGRAPH
+0xE05E 0x6FD8 #CJK UNIFIED IDEOGRAPH
+0xE05F 0x6FF1 #CJK UNIFIED IDEOGRAPH
+0xE060 0x6FEE #CJK UNIFIED IDEOGRAPH
+0xE061 0x6FDB #CJK UNIFIED IDEOGRAPH
+0xE062 0x7009 #CJK UNIFIED IDEOGRAPH
+0xE063 0x700B #CJK UNIFIED IDEOGRAPH
+0xE064 0x6FFA #CJK UNIFIED IDEOGRAPH
+0xE065 0x7011 #CJK UNIFIED IDEOGRAPH
+0xE066 0x7001 #CJK UNIFIED IDEOGRAPH
+0xE067 0x700F #CJK UNIFIED IDEOGRAPH
+0xE068 0x6FFE #CJK UNIFIED IDEOGRAPH
+0xE069 0x701B #CJK UNIFIED IDEOGRAPH
+0xE06A 0x701A #CJK UNIFIED IDEOGRAPH
+0xE06B 0x6F74 #CJK UNIFIED IDEOGRAPH
+0xE06C 0x701D #CJK UNIFIED IDEOGRAPH
+0xE06D 0x7018 #CJK UNIFIED IDEOGRAPH
+0xE06E 0x701F #CJK UNIFIED IDEOGRAPH
+0xE06F 0x7030 #CJK UNIFIED IDEOGRAPH
+0xE070 0x703E #CJK UNIFIED IDEOGRAPH
+0xE071 0x7032 #CJK UNIFIED IDEOGRAPH
+0xE072 0x7051 #CJK UNIFIED IDEOGRAPH
+0xE073 0x7063 #CJK UNIFIED IDEOGRAPH
+0xE074 0x7099 #CJK UNIFIED IDEOGRAPH
+0xE075 0x7092 #CJK UNIFIED IDEOGRAPH
+0xE076 0x70AF #CJK UNIFIED IDEOGRAPH
+0xE077 0x70F1 #CJK UNIFIED IDEOGRAPH
+0xE078 0x70AC #CJK UNIFIED IDEOGRAPH
+0xE079 0x70B8 #CJK UNIFIED IDEOGRAPH
+0xE07A 0x70B3 #CJK UNIFIED IDEOGRAPH
+0xE07B 0x70AE #CJK UNIFIED IDEOGRAPH
+0xE07C 0x70DF #CJK UNIFIED IDEOGRAPH
+0xE07D 0x70CB #CJK UNIFIED IDEOGRAPH
+0xE07E 0x70DD #CJK UNIFIED IDEOGRAPH
+0xE080 0x70D9 #CJK UNIFIED IDEOGRAPH
+0xE081 0x7109 #CJK UNIFIED IDEOGRAPH
+0xE082 0x70FD #CJK UNIFIED IDEOGRAPH
+0xE083 0x711C #CJK UNIFIED IDEOGRAPH
+0xE084 0x7119 #CJK UNIFIED IDEOGRAPH
+0xE085 0x7165 #CJK UNIFIED IDEOGRAPH
+0xE086 0x7155 #CJK UNIFIED IDEOGRAPH
+0xE087 0x7188 #CJK UNIFIED IDEOGRAPH
+0xE088 0x7166 #CJK UNIFIED IDEOGRAPH
+0xE089 0x7162 #CJK UNIFIED IDEOGRAPH
+0xE08A 0x714C #CJK UNIFIED IDEOGRAPH
+0xE08B 0x7156 #CJK UNIFIED IDEOGRAPH
+0xE08C 0x716C #CJK UNIFIED IDEOGRAPH
+0xE08D 0x718F #CJK UNIFIED IDEOGRAPH
+0xE08E 0x71FB #CJK UNIFIED IDEOGRAPH
+0xE08F 0x7184 #CJK UNIFIED IDEOGRAPH
+0xE090 0x7195 #CJK UNIFIED IDEOGRAPH
+0xE091 0x71A8 #CJK UNIFIED IDEOGRAPH
+0xE092 0x71AC #CJK UNIFIED IDEOGRAPH
+0xE093 0x71D7 #CJK UNIFIED IDEOGRAPH
+0xE094 0x71B9 #CJK UNIFIED IDEOGRAPH
+0xE095 0x71BE #CJK UNIFIED IDEOGRAPH
+0xE096 0x71D2 #CJK UNIFIED IDEOGRAPH
+0xE097 0x71C9 #CJK UNIFIED IDEOGRAPH
+0xE098 0x71D4 #CJK UNIFIED IDEOGRAPH
+0xE099 0x71CE #CJK UNIFIED IDEOGRAPH
+0xE09A 0x71E0 #CJK UNIFIED IDEOGRAPH
+0xE09B 0x71EC #CJK UNIFIED IDEOGRAPH
+0xE09C 0x71E7 #CJK UNIFIED IDEOGRAPH
+0xE09D 0x71F5 #CJK UNIFIED IDEOGRAPH
+0xE09E 0x71FC #CJK UNIFIED IDEOGRAPH
+0xE09F 0x71F9 #CJK UNIFIED IDEOGRAPH
+0xE0A0 0x71FF #CJK UNIFIED IDEOGRAPH
+0xE0A1 0x720D #CJK UNIFIED IDEOGRAPH
+0xE0A2 0x7210 #CJK UNIFIED IDEOGRAPH
+0xE0A3 0x721B #CJK UNIFIED IDEOGRAPH
+0xE0A4 0x7228 #CJK UNIFIED IDEOGRAPH
+0xE0A5 0x722D #CJK UNIFIED IDEOGRAPH
+0xE0A6 0x722C #CJK UNIFIED IDEOGRAPH
+0xE0A7 0x7230 #CJK UNIFIED IDEOGRAPH
+0xE0A8 0x7232 #CJK UNIFIED IDEOGRAPH
+0xE0A9 0x723B #CJK UNIFIED IDEOGRAPH
+0xE0AA 0x723C #CJK UNIFIED IDEOGRAPH
+0xE0AB 0x723F #CJK UNIFIED IDEOGRAPH
+0xE0AC 0x7240 #CJK UNIFIED IDEOGRAPH
+0xE0AD 0x7246 #CJK UNIFIED IDEOGRAPH
+0xE0AE 0x724B #CJK UNIFIED IDEOGRAPH
+0xE0AF 0x7258 #CJK UNIFIED IDEOGRAPH
+0xE0B0 0x7274 #CJK UNIFIED IDEOGRAPH
+0xE0B1 0x727E #CJK UNIFIED IDEOGRAPH
+0xE0B2 0x7282 #CJK UNIFIED IDEOGRAPH
+0xE0B3 0x7281 #CJK UNIFIED IDEOGRAPH
+0xE0B4 0x7287 #CJK UNIFIED IDEOGRAPH
+0xE0B5 0x7292 #CJK UNIFIED IDEOGRAPH
+0xE0B6 0x7296 #CJK UNIFIED IDEOGRAPH
+0xE0B7 0x72A2 #CJK UNIFIED IDEOGRAPH
+0xE0B8 0x72A7 #CJK UNIFIED IDEOGRAPH
+0xE0B9 0x72B9 #CJK UNIFIED IDEOGRAPH
+0xE0BA 0x72B2 #CJK UNIFIED IDEOGRAPH
+0xE0BB 0x72C3 #CJK UNIFIED IDEOGRAPH
+0xE0BC 0x72C6 #CJK UNIFIED IDEOGRAPH
+0xE0BD 0x72C4 #CJK UNIFIED IDEOGRAPH
+0xE0BE 0x72CE #CJK UNIFIED IDEOGRAPH
+0xE0BF 0x72D2 #CJK UNIFIED IDEOGRAPH
+0xE0C0 0x72E2 #CJK UNIFIED IDEOGRAPH
+0xE0C1 0x72E0 #CJK UNIFIED IDEOGRAPH
+0xE0C2 0x72E1 #CJK UNIFIED IDEOGRAPH
+0xE0C3 0x72F9 #CJK UNIFIED IDEOGRAPH
+0xE0C4 0x72F7 #CJK UNIFIED IDEOGRAPH
+0xE0C5 0x500F #CJK UNIFIED IDEOGRAPH
+0xE0C6 0x7317 #CJK UNIFIED IDEOGRAPH
+0xE0C7 0x730A #CJK UNIFIED IDEOGRAPH
+0xE0C8 0x731C #CJK UNIFIED IDEOGRAPH
+0xE0C9 0x7316 #CJK UNIFIED IDEOGRAPH
+0xE0CA 0x731D #CJK UNIFIED IDEOGRAPH
+0xE0CB 0x7334 #CJK UNIFIED IDEOGRAPH
+0xE0CC 0x732F #CJK UNIFIED IDEOGRAPH
+0xE0CD 0x7329 #CJK UNIFIED IDEOGRAPH
+0xE0CE 0x7325 #CJK UNIFIED IDEOGRAPH
+0xE0CF 0x733E #CJK UNIFIED IDEOGRAPH
+0xE0D0 0x734E #CJK UNIFIED IDEOGRAPH
+0xE0D1 0x734F #CJK UNIFIED IDEOGRAPH
+0xE0D2 0x9ED8 #CJK UNIFIED IDEOGRAPH
+0xE0D3 0x7357 #CJK UNIFIED IDEOGRAPH
+0xE0D4 0x736A #CJK UNIFIED IDEOGRAPH
+0xE0D5 0x7368 #CJK UNIFIED IDEOGRAPH
+0xE0D6 0x7370 #CJK UNIFIED IDEOGRAPH
+0xE0D7 0x7378 #CJK UNIFIED IDEOGRAPH
+0xE0D8 0x7375 #CJK UNIFIED IDEOGRAPH
+0xE0D9 0x737B #CJK UNIFIED IDEOGRAPH
+0xE0DA 0x737A #CJK UNIFIED IDEOGRAPH
+0xE0DB 0x73C8 #CJK UNIFIED IDEOGRAPH
+0xE0DC 0x73B3 #CJK UNIFIED IDEOGRAPH
+0xE0DD 0x73CE #CJK UNIFIED IDEOGRAPH
+0xE0DE 0x73BB #CJK UNIFIED IDEOGRAPH
+0xE0DF 0x73C0 #CJK UNIFIED IDEOGRAPH
+0xE0E0 0x73E5 #CJK UNIFIED IDEOGRAPH
+0xE0E1 0x73EE #CJK UNIFIED IDEOGRAPH
+0xE0E2 0x73DE #CJK UNIFIED IDEOGRAPH
+0xE0E3 0x74A2 #CJK UNIFIED IDEOGRAPH
+0xE0E4 0x7405 #CJK UNIFIED IDEOGRAPH
+0xE0E5 0x746F #CJK UNIFIED IDEOGRAPH
+0xE0E6 0x7425 #CJK UNIFIED IDEOGRAPH
+0xE0E7 0x73F8 #CJK UNIFIED IDEOGRAPH
+0xE0E8 0x7432 #CJK UNIFIED IDEOGRAPH
+0xE0E9 0x743A #CJK UNIFIED IDEOGRAPH
+0xE0EA 0x7455 #CJK UNIFIED IDEOGRAPH
+0xE0EB 0x743F #CJK UNIFIED IDEOGRAPH
+0xE0EC 0x745F #CJK UNIFIED IDEOGRAPH
+0xE0ED 0x7459 #CJK UNIFIED IDEOGRAPH
+0xE0EE 0x7441 #CJK UNIFIED IDEOGRAPH
+0xE0EF 0x745C #CJK UNIFIED IDEOGRAPH
+0xE0F0 0x7469 #CJK UNIFIED IDEOGRAPH
+0xE0F1 0x7470 #CJK UNIFIED IDEOGRAPH
+0xE0F2 0x7463 #CJK UNIFIED IDEOGRAPH
+0xE0F3 0x746A #CJK UNIFIED IDEOGRAPH
+0xE0F4 0x7476 #CJK UNIFIED IDEOGRAPH
+0xE0F5 0x747E #CJK UNIFIED IDEOGRAPH
+0xE0F6 0x748B #CJK UNIFIED IDEOGRAPH
+0xE0F7 0x749E #CJK UNIFIED IDEOGRAPH
+0xE0F8 0x74A7 #CJK UNIFIED IDEOGRAPH
+0xE0F9 0x74CA #CJK UNIFIED IDEOGRAPH
+0xE0FA 0x74CF #CJK UNIFIED IDEOGRAPH
+0xE0FB 0x74D4 #CJK UNIFIED IDEOGRAPH
+0xE0FC 0x73F1 #CJK UNIFIED IDEOGRAPH
+0xE140 0x74E0 #CJK UNIFIED IDEOGRAPH
+0xE141 0x74E3 #CJK UNIFIED IDEOGRAPH
+0xE142 0x74E7 #CJK UNIFIED IDEOGRAPH
+0xE143 0x74E9 #CJK UNIFIED IDEOGRAPH
+0xE144 0x74EE #CJK UNIFIED IDEOGRAPH
+0xE145 0x74F2 #CJK UNIFIED IDEOGRAPH
+0xE146 0x74F0 #CJK UNIFIED IDEOGRAPH
+0xE147 0x74F1 #CJK UNIFIED IDEOGRAPH
+0xE148 0x74F8 #CJK UNIFIED IDEOGRAPH
+0xE149 0x74F7 #CJK UNIFIED IDEOGRAPH
+0xE14A 0x7504 #CJK UNIFIED IDEOGRAPH
+0xE14B 0x7503 #CJK UNIFIED IDEOGRAPH
+0xE14C 0x7505 #CJK UNIFIED IDEOGRAPH
+0xE14D 0x750C #CJK UNIFIED IDEOGRAPH
+0xE14E 0x750E #CJK UNIFIED IDEOGRAPH
+0xE14F 0x750D #CJK UNIFIED IDEOGRAPH
+0xE150 0x7515 #CJK UNIFIED IDEOGRAPH
+0xE151 0x7513 #CJK UNIFIED IDEOGRAPH
+0xE152 0x751E #CJK UNIFIED IDEOGRAPH
+0xE153 0x7526 #CJK UNIFIED IDEOGRAPH
+0xE154 0x752C #CJK UNIFIED IDEOGRAPH
+0xE155 0x753C #CJK UNIFIED IDEOGRAPH
+0xE156 0x7544 #CJK UNIFIED IDEOGRAPH
+0xE157 0x754D #CJK UNIFIED IDEOGRAPH
+0xE158 0x754A #CJK UNIFIED IDEOGRAPH
+0xE159 0x7549 #CJK UNIFIED IDEOGRAPH
+0xE15A 0x755B #CJK UNIFIED IDEOGRAPH
+0xE15B 0x7546 #CJK UNIFIED IDEOGRAPH
+0xE15C 0x755A #CJK UNIFIED IDEOGRAPH
+0xE15D 0x7569 #CJK UNIFIED IDEOGRAPH
+0xE15E 0x7564 #CJK UNIFIED IDEOGRAPH
+0xE15F 0x7567 #CJK UNIFIED IDEOGRAPH
+0xE160 0x756B #CJK UNIFIED IDEOGRAPH
+0xE161 0x756D #CJK UNIFIED IDEOGRAPH
+0xE162 0x7578 #CJK UNIFIED IDEOGRAPH
+0xE163 0x7576 #CJK UNIFIED IDEOGRAPH
+0xE164 0x7586 #CJK UNIFIED IDEOGRAPH
+0xE165 0x7587 #CJK UNIFIED IDEOGRAPH
+0xE166 0x7574 #CJK UNIFIED IDEOGRAPH
+0xE167 0x758A #CJK UNIFIED IDEOGRAPH
+0xE168 0x7589 #CJK UNIFIED IDEOGRAPH
+0xE169 0x7582 #CJK UNIFIED IDEOGRAPH
+0xE16A 0x7594 #CJK UNIFIED IDEOGRAPH
+0xE16B 0x759A #CJK UNIFIED IDEOGRAPH
+0xE16C 0x759D #CJK UNIFIED IDEOGRAPH
+0xE16D 0x75A5 #CJK UNIFIED IDEOGRAPH
+0xE16E 0x75A3 #CJK UNIFIED IDEOGRAPH
+0xE16F 0x75C2 #CJK UNIFIED IDEOGRAPH
+0xE170 0x75B3 #CJK UNIFIED IDEOGRAPH
+0xE171 0x75C3 #CJK UNIFIED IDEOGRAPH
+0xE172 0x75B5 #CJK UNIFIED IDEOGRAPH
+0xE173 0x75BD #CJK UNIFIED IDEOGRAPH
+0xE174 0x75B8 #CJK UNIFIED IDEOGRAPH
+0xE175 0x75BC #CJK UNIFIED IDEOGRAPH
+0xE176 0x75B1 #CJK UNIFIED IDEOGRAPH
+0xE177 0x75CD #CJK UNIFIED IDEOGRAPH
+0xE178 0x75CA #CJK UNIFIED IDEOGRAPH
+0xE179 0x75D2 #CJK UNIFIED IDEOGRAPH
+0xE17A 0x75D9 #CJK UNIFIED IDEOGRAPH
+0xE17B 0x75E3 #CJK UNIFIED IDEOGRAPH
+0xE17C 0x75DE #CJK UNIFIED IDEOGRAPH
+0xE17D 0x75FE #CJK UNIFIED IDEOGRAPH
+0xE17E 0x75FF #CJK UNIFIED IDEOGRAPH
+0xE180 0x75FC #CJK UNIFIED IDEOGRAPH
+0xE181 0x7601 #CJK UNIFIED IDEOGRAPH
+0xE182 0x75F0 #CJK UNIFIED IDEOGRAPH
+0xE183 0x75FA #CJK UNIFIED IDEOGRAPH
+0xE184 0x75F2 #CJK UNIFIED IDEOGRAPH
+0xE185 0x75F3 #CJK UNIFIED IDEOGRAPH
+0xE186 0x760B #CJK UNIFIED IDEOGRAPH
+0xE187 0x760D #CJK UNIFIED IDEOGRAPH
+0xE188 0x7609 #CJK UNIFIED IDEOGRAPH
+0xE189 0x761F #CJK UNIFIED IDEOGRAPH
+0xE18A 0x7627 #CJK UNIFIED IDEOGRAPH
+0xE18B 0x7620 #CJK UNIFIED IDEOGRAPH
+0xE18C 0x7621 #CJK UNIFIED IDEOGRAPH
+0xE18D 0x7622 #CJK UNIFIED IDEOGRAPH
+0xE18E 0x7624 #CJK UNIFIED IDEOGRAPH
+0xE18F 0x7634 #CJK UNIFIED IDEOGRAPH
+0xE190 0x7630 #CJK UNIFIED IDEOGRAPH
+0xE191 0x763B #CJK UNIFIED IDEOGRAPH
+0xE192 0x7647 #CJK UNIFIED IDEOGRAPH
+0xE193 0x7648 #CJK UNIFIED IDEOGRAPH
+0xE194 0x7646 #CJK UNIFIED IDEOGRAPH
+0xE195 0x765C #CJK UNIFIED IDEOGRAPH
+0xE196 0x7658 #CJK UNIFIED IDEOGRAPH
+0xE197 0x7661 #CJK UNIFIED IDEOGRAPH
+0xE198 0x7662 #CJK UNIFIED IDEOGRAPH
+0xE199 0x7668 #CJK UNIFIED IDEOGRAPH
+0xE19A 0x7669 #CJK UNIFIED IDEOGRAPH
+0xE19B 0x766A #CJK UNIFIED IDEOGRAPH
+0xE19C 0x7667 #CJK UNIFIED IDEOGRAPH
+0xE19D 0x766C #CJK UNIFIED IDEOGRAPH
+0xE19E 0x7670 #CJK UNIFIED IDEOGRAPH
+0xE19F 0x7672 #CJK UNIFIED IDEOGRAPH
+0xE1A0 0x7676 #CJK UNIFIED IDEOGRAPH
+0xE1A1 0x7678 #CJK UNIFIED IDEOGRAPH
+0xE1A2 0x767C #CJK UNIFIED IDEOGRAPH
+0xE1A3 0x7680 #CJK UNIFIED IDEOGRAPH
+0xE1A4 0x7683 #CJK UNIFIED IDEOGRAPH
+0xE1A5 0x7688 #CJK UNIFIED IDEOGRAPH
+0xE1A6 0x768B #CJK UNIFIED IDEOGRAPH
+0xE1A7 0x768E #CJK UNIFIED IDEOGRAPH
+0xE1A8 0x7696 #CJK UNIFIED IDEOGRAPH
+0xE1A9 0x7693 #CJK UNIFIED IDEOGRAPH
+0xE1AA 0x7699 #CJK UNIFIED IDEOGRAPH
+0xE1AB 0x769A #CJK UNIFIED IDEOGRAPH
+0xE1AC 0x76B0 #CJK UNIFIED IDEOGRAPH
+0xE1AD 0x76B4 #CJK UNIFIED IDEOGRAPH
+0xE1AE 0x76B8 #CJK UNIFIED IDEOGRAPH
+0xE1AF 0x76B9 #CJK UNIFIED IDEOGRAPH
+0xE1B0 0x76BA #CJK UNIFIED IDEOGRAPH
+0xE1B1 0x76C2 #CJK UNIFIED IDEOGRAPH
+0xE1B2 0x76CD #CJK UNIFIED IDEOGRAPH
+0xE1B3 0x76D6 #CJK UNIFIED IDEOGRAPH
+0xE1B4 0x76D2 #CJK UNIFIED IDEOGRAPH
+0xE1B5 0x76DE #CJK UNIFIED IDEOGRAPH
+0xE1B6 0x76E1 #CJK UNIFIED IDEOGRAPH
+0xE1B7 0x76E5 #CJK UNIFIED IDEOGRAPH
+0xE1B8 0x76E7 #CJK UNIFIED IDEOGRAPH
+0xE1B9 0x76EA #CJK UNIFIED IDEOGRAPH
+0xE1BA 0x862F #CJK UNIFIED IDEOGRAPH
+0xE1BB 0x76FB #CJK UNIFIED IDEOGRAPH
+0xE1BC 0x7708 #CJK UNIFIED IDEOGRAPH
+0xE1BD 0x7707 #CJK UNIFIED IDEOGRAPH
+0xE1BE 0x7704 #CJK UNIFIED IDEOGRAPH
+0xE1BF 0x7729 #CJK UNIFIED IDEOGRAPH
+0xE1C0 0x7724 #CJK UNIFIED IDEOGRAPH
+0xE1C1 0x771E #CJK UNIFIED IDEOGRAPH
+0xE1C2 0x7725 #CJK UNIFIED IDEOGRAPH
+0xE1C3 0x7726 #CJK UNIFIED IDEOGRAPH
+0xE1C4 0x771B #CJK UNIFIED IDEOGRAPH
+0xE1C5 0x7737 #CJK UNIFIED IDEOGRAPH
+0xE1C6 0x7738 #CJK UNIFIED IDEOGRAPH
+0xE1C7 0x7747 #CJK UNIFIED IDEOGRAPH
+0xE1C8 0x775A #CJK UNIFIED IDEOGRAPH
+0xE1C9 0x7768 #CJK UNIFIED IDEOGRAPH
+0xE1CA 0x776B #CJK UNIFIED IDEOGRAPH
+0xE1CB 0x775B #CJK UNIFIED IDEOGRAPH
+0xE1CC 0x7765 #CJK UNIFIED IDEOGRAPH
+0xE1CD 0x777F #CJK UNIFIED IDEOGRAPH
+0xE1CE 0x777E #CJK UNIFIED IDEOGRAPH
+0xE1CF 0x7779 #CJK UNIFIED IDEOGRAPH
+0xE1D0 0x778E #CJK UNIFIED IDEOGRAPH
+0xE1D1 0x778B #CJK UNIFIED IDEOGRAPH
+0xE1D2 0x7791 #CJK UNIFIED IDEOGRAPH
+0xE1D3 0x77A0 #CJK UNIFIED IDEOGRAPH
+0xE1D4 0x779E #CJK UNIFIED IDEOGRAPH
+0xE1D5 0x77B0 #CJK UNIFIED IDEOGRAPH
+0xE1D6 0x77B6 #CJK UNIFIED IDEOGRAPH
+0xE1D7 0x77B9 #CJK UNIFIED IDEOGRAPH
+0xE1D8 0x77BF #CJK UNIFIED IDEOGRAPH
+0xE1D9 0x77BC #CJK UNIFIED IDEOGRAPH
+0xE1DA 0x77BD #CJK UNIFIED IDEOGRAPH
+0xE1DB 0x77BB #CJK UNIFIED IDEOGRAPH
+0xE1DC 0x77C7 #CJK UNIFIED IDEOGRAPH
+0xE1DD 0x77CD #CJK UNIFIED IDEOGRAPH
+0xE1DE 0x77D7 #CJK UNIFIED IDEOGRAPH
+0xE1DF 0x77DA #CJK UNIFIED IDEOGRAPH
+0xE1E0 0x77DC #CJK UNIFIED IDEOGRAPH
+0xE1E1 0x77E3 #CJK UNIFIED IDEOGRAPH
+0xE1E2 0x77EE #CJK UNIFIED IDEOGRAPH
+0xE1E3 0x77FC #CJK UNIFIED IDEOGRAPH
+0xE1E4 0x780C #CJK UNIFIED IDEOGRAPH
+0xE1E5 0x7812 #CJK UNIFIED IDEOGRAPH
+0xE1E6 0x7926 #CJK UNIFIED IDEOGRAPH
+0xE1E7 0x7820 #CJK UNIFIED IDEOGRAPH
+0xE1E8 0x792A #CJK UNIFIED IDEOGRAPH
+0xE1E9 0x7845 #CJK UNIFIED IDEOGRAPH
+0xE1EA 0x788E #CJK UNIFIED IDEOGRAPH
+0xE1EB 0x7874 #CJK UNIFIED IDEOGRAPH
+0xE1EC 0x7886 #CJK UNIFIED IDEOGRAPH
+0xE1ED 0x787C #CJK UNIFIED IDEOGRAPH
+0xE1EE 0x789A #CJK UNIFIED IDEOGRAPH
+0xE1EF 0x788C #CJK UNIFIED IDEOGRAPH
+0xE1F0 0x78A3 #CJK UNIFIED IDEOGRAPH
+0xE1F1 0x78B5 #CJK UNIFIED IDEOGRAPH
+0xE1F2 0x78AA #CJK UNIFIED IDEOGRAPH
+0xE1F3 0x78AF #CJK UNIFIED IDEOGRAPH
+0xE1F4 0x78D1 #CJK UNIFIED IDEOGRAPH
+0xE1F5 0x78C6 #CJK UNIFIED IDEOGRAPH
+0xE1F6 0x78CB #CJK UNIFIED IDEOGRAPH
+0xE1F7 0x78D4 #CJK UNIFIED IDEOGRAPH
+0xE1F8 0x78BE #CJK UNIFIED IDEOGRAPH
+0xE1F9 0x78BC #CJK UNIFIED IDEOGRAPH
+0xE1FA 0x78C5 #CJK UNIFIED IDEOGRAPH
+0xE1FB 0x78CA #CJK UNIFIED IDEOGRAPH
+0xE1FC 0x78EC #CJK UNIFIED IDEOGRAPH
+0xE240 0x78E7 #CJK UNIFIED IDEOGRAPH
+0xE241 0x78DA #CJK UNIFIED IDEOGRAPH
+0xE242 0x78FD #CJK UNIFIED IDEOGRAPH
+0xE243 0x78F4 #CJK UNIFIED IDEOGRAPH
+0xE244 0x7907 #CJK UNIFIED IDEOGRAPH
+0xE245 0x7912 #CJK UNIFIED IDEOGRAPH
+0xE246 0x7911 #CJK UNIFIED IDEOGRAPH
+0xE247 0x7919 #CJK UNIFIED IDEOGRAPH
+0xE248 0x792C #CJK UNIFIED IDEOGRAPH
+0xE249 0x792B #CJK UNIFIED IDEOGRAPH
+0xE24A 0x7940 #CJK UNIFIED IDEOGRAPH
+0xE24B 0x7960 #CJK UNIFIED IDEOGRAPH
+0xE24C 0x7957 #CJK UNIFIED IDEOGRAPH
+0xE24D 0x795F #CJK UNIFIED IDEOGRAPH
+0xE24E 0x795A #CJK UNIFIED IDEOGRAPH
+0xE24F 0x7955 #CJK UNIFIED IDEOGRAPH
+0xE250 0x7953 #CJK UNIFIED IDEOGRAPH
+0xE251 0x797A #CJK UNIFIED IDEOGRAPH
+0xE252 0x797F #CJK UNIFIED IDEOGRAPH
+0xE253 0x798A #CJK UNIFIED IDEOGRAPH
+0xE254 0x799D #CJK UNIFIED IDEOGRAPH
+0xE255 0x79A7 #CJK UNIFIED IDEOGRAPH
+0xE256 0x9F4B #CJK UNIFIED IDEOGRAPH
+0xE257 0x79AA #CJK UNIFIED IDEOGRAPH
+0xE258 0x79AE #CJK UNIFIED IDEOGRAPH
+0xE259 0x79B3 #CJK UNIFIED IDEOGRAPH
+0xE25A 0x79B9 #CJK UNIFIED IDEOGRAPH
+0xE25B 0x79BA #CJK UNIFIED IDEOGRAPH
+0xE25C 0x79C9 #CJK UNIFIED IDEOGRAPH
+0xE25D 0x79D5 #CJK UNIFIED IDEOGRAPH
+0xE25E 0x79E7 #CJK UNIFIED IDEOGRAPH
+0xE25F 0x79EC #CJK UNIFIED IDEOGRAPH
+0xE260 0x79E1 #CJK UNIFIED IDEOGRAPH
+0xE261 0x79E3 #CJK UNIFIED IDEOGRAPH
+0xE262 0x7A08 #CJK UNIFIED IDEOGRAPH
+0xE263 0x7A0D #CJK UNIFIED IDEOGRAPH
+0xE264 0x7A18 #CJK UNIFIED IDEOGRAPH
+0xE265 0x7A19 #CJK UNIFIED IDEOGRAPH
+0xE266 0x7A20 #CJK UNIFIED IDEOGRAPH
+0xE267 0x7A1F #CJK UNIFIED IDEOGRAPH
+0xE268 0x7980 #CJK UNIFIED IDEOGRAPH
+0xE269 0x7A31 #CJK UNIFIED IDEOGRAPH
+0xE26A 0x7A3B #CJK UNIFIED IDEOGRAPH
+0xE26B 0x7A3E #CJK UNIFIED IDEOGRAPH
+0xE26C 0x7A37 #CJK UNIFIED IDEOGRAPH
+0xE26D 0x7A43 #CJK UNIFIED IDEOGRAPH
+0xE26E 0x7A57 #CJK UNIFIED IDEOGRAPH
+0xE26F 0x7A49 #CJK UNIFIED IDEOGRAPH
+0xE270 0x7A61 #CJK UNIFIED IDEOGRAPH
+0xE271 0x7A62 #CJK UNIFIED IDEOGRAPH
+0xE272 0x7A69 #CJK UNIFIED IDEOGRAPH
+0xE273 0x9F9D #CJK UNIFIED IDEOGRAPH
+0xE274 0x7A70 #CJK UNIFIED IDEOGRAPH
+0xE275 0x7A79 #CJK UNIFIED IDEOGRAPH
+0xE276 0x7A7D #CJK UNIFIED IDEOGRAPH
+0xE277 0x7A88 #CJK UNIFIED IDEOGRAPH
+0xE278 0x7A97 #CJK UNIFIED IDEOGRAPH
+0xE279 0x7A95 #CJK UNIFIED IDEOGRAPH
+0xE27A 0x7A98 #CJK UNIFIED IDEOGRAPH
+0xE27B 0x7A96 #CJK UNIFIED IDEOGRAPH
+0xE27C 0x7AA9 #CJK UNIFIED IDEOGRAPH
+0xE27D 0x7AC8 #CJK UNIFIED IDEOGRAPH
+0xE27E 0x7AB0 #CJK UNIFIED IDEOGRAPH
+0xE280 0x7AB6 #CJK UNIFIED IDEOGRAPH
+0xE281 0x7AC5 #CJK UNIFIED IDEOGRAPH
+0xE282 0x7AC4 #CJK UNIFIED IDEOGRAPH
+0xE283 0x7ABF #CJK UNIFIED IDEOGRAPH
+0xE284 0x9083 #CJK UNIFIED IDEOGRAPH
+0xE285 0x7AC7 #CJK UNIFIED IDEOGRAPH
+0xE286 0x7ACA #CJK UNIFIED IDEOGRAPH
+0xE287 0x7ACD #CJK UNIFIED IDEOGRAPH
+0xE288 0x7ACF #CJK UNIFIED IDEOGRAPH
+0xE289 0x7AD5 #CJK UNIFIED IDEOGRAPH
+0xE28A 0x7AD3 #CJK UNIFIED IDEOGRAPH
+0xE28B 0x7AD9 #CJK UNIFIED IDEOGRAPH
+0xE28C 0x7ADA #CJK UNIFIED IDEOGRAPH
+0xE28D 0x7ADD #CJK UNIFIED IDEOGRAPH
+0xE28E 0x7AE1 #CJK UNIFIED IDEOGRAPH
+0xE28F 0x7AE2 #CJK UNIFIED IDEOGRAPH
+0xE290 0x7AE6 #CJK UNIFIED IDEOGRAPH
+0xE291 0x7AED #CJK UNIFIED IDEOGRAPH
+0xE292 0x7AF0 #CJK UNIFIED IDEOGRAPH
+0xE293 0x7B02 #CJK UNIFIED IDEOGRAPH
+0xE294 0x7B0F #CJK UNIFIED IDEOGRAPH
+0xE295 0x7B0A #CJK UNIFIED IDEOGRAPH
+0xE296 0x7B06 #CJK UNIFIED IDEOGRAPH
+0xE297 0x7B33 #CJK UNIFIED IDEOGRAPH
+0xE298 0x7B18 #CJK UNIFIED IDEOGRAPH
+0xE299 0x7B19 #CJK UNIFIED IDEOGRAPH
+0xE29A 0x7B1E #CJK UNIFIED IDEOGRAPH
+0xE29B 0x7B35 #CJK UNIFIED IDEOGRAPH
+0xE29C 0x7B28 #CJK UNIFIED IDEOGRAPH
+0xE29D 0x7B36 #CJK UNIFIED IDEOGRAPH
+0xE29E 0x7B50 #CJK UNIFIED IDEOGRAPH
+0xE29F 0x7B7A #CJK UNIFIED IDEOGRAPH
+0xE2A0 0x7B04 #CJK UNIFIED IDEOGRAPH
+0xE2A1 0x7B4D #CJK UNIFIED IDEOGRAPH
+0xE2A2 0x7B0B #CJK UNIFIED IDEOGRAPH
+0xE2A3 0x7B4C #CJK UNIFIED IDEOGRAPH
+0xE2A4 0x7B45 #CJK UNIFIED IDEOGRAPH
+0xE2A5 0x7B75 #CJK UNIFIED IDEOGRAPH
+0xE2A6 0x7B65 #CJK UNIFIED IDEOGRAPH
+0xE2A7 0x7B74 #CJK UNIFIED IDEOGRAPH
+0xE2A8 0x7B67 #CJK UNIFIED IDEOGRAPH
+0xE2A9 0x7B70 #CJK UNIFIED IDEOGRAPH
+0xE2AA 0x7B71 #CJK UNIFIED IDEOGRAPH
+0xE2AB 0x7B6C #CJK UNIFIED IDEOGRAPH
+0xE2AC 0x7B6E #CJK UNIFIED IDEOGRAPH
+0xE2AD 0x7B9D #CJK UNIFIED IDEOGRAPH
+0xE2AE 0x7B98 #CJK UNIFIED IDEOGRAPH
+0xE2AF 0x7B9F #CJK UNIFIED IDEOGRAPH
+0xE2B0 0x7B8D #CJK UNIFIED IDEOGRAPH
+0xE2B1 0x7B9C #CJK UNIFIED IDEOGRAPH
+0xE2B2 0x7B9A #CJK UNIFIED IDEOGRAPH
+0xE2B3 0x7B8B #CJK UNIFIED IDEOGRAPH
+0xE2B4 0x7B92 #CJK UNIFIED IDEOGRAPH
+0xE2B5 0x7B8F #CJK UNIFIED IDEOGRAPH
+0xE2B6 0x7B5D #CJK UNIFIED IDEOGRAPH
+0xE2B7 0x7B99 #CJK UNIFIED IDEOGRAPH
+0xE2B8 0x7BCB #CJK UNIFIED IDEOGRAPH
+0xE2B9 0x7BC1 #CJK UNIFIED IDEOGRAPH
+0xE2BA 0x7BCC #CJK UNIFIED IDEOGRAPH
+0xE2BB 0x7BCF #CJK UNIFIED IDEOGRAPH
+0xE2BC 0x7BB4 #CJK UNIFIED IDEOGRAPH
+0xE2BD 0x7BC6 #CJK UNIFIED IDEOGRAPH
+0xE2BE 0x7BDD #CJK UNIFIED IDEOGRAPH
+0xE2BF 0x7BE9 #CJK UNIFIED IDEOGRAPH
+0xE2C0 0x7C11 #CJK UNIFIED IDEOGRAPH
+0xE2C1 0x7C14 #CJK UNIFIED IDEOGRAPH
+0xE2C2 0x7BE6 #CJK UNIFIED IDEOGRAPH
+0xE2C3 0x7BE5 #CJK UNIFIED IDEOGRAPH
+0xE2C4 0x7C60 #CJK UNIFIED IDEOGRAPH
+0xE2C5 0x7C00 #CJK UNIFIED IDEOGRAPH
+0xE2C6 0x7C07 #CJK UNIFIED IDEOGRAPH
+0xE2C7 0x7C13 #CJK UNIFIED IDEOGRAPH
+0xE2C8 0x7BF3 #CJK UNIFIED IDEOGRAPH
+0xE2C9 0x7BF7 #CJK UNIFIED IDEOGRAPH
+0xE2CA 0x7C17 #CJK UNIFIED IDEOGRAPH
+0xE2CB 0x7C0D #CJK UNIFIED IDEOGRAPH
+0xE2CC 0x7BF6 #CJK UNIFIED IDEOGRAPH
+0xE2CD 0x7C23 #CJK UNIFIED IDEOGRAPH
+0xE2CE 0x7C27 #CJK UNIFIED IDEOGRAPH
+0xE2CF 0x7C2A #CJK UNIFIED IDEOGRAPH
+0xE2D0 0x7C1F #CJK UNIFIED IDEOGRAPH
+0xE2D1 0x7C37 #CJK UNIFIED IDEOGRAPH
+0xE2D2 0x7C2B #CJK UNIFIED IDEOGRAPH
+0xE2D3 0x7C3D #CJK UNIFIED IDEOGRAPH
+0xE2D4 0x7C4C #CJK UNIFIED IDEOGRAPH
+0xE2D5 0x7C43 #CJK UNIFIED IDEOGRAPH
+0xE2D6 0x7C54 #CJK UNIFIED IDEOGRAPH
+0xE2D7 0x7C4F #CJK UNIFIED IDEOGRAPH
+0xE2D8 0x7C40 #CJK UNIFIED IDEOGRAPH
+0xE2D9 0x7C50 #CJK UNIFIED IDEOGRAPH
+0xE2DA 0x7C58 #CJK UNIFIED IDEOGRAPH
+0xE2DB 0x7C5F #CJK UNIFIED IDEOGRAPH
+0xE2DC 0x7C64 #CJK UNIFIED IDEOGRAPH
+0xE2DD 0x7C56 #CJK UNIFIED IDEOGRAPH
+0xE2DE 0x7C65 #CJK UNIFIED IDEOGRAPH
+0xE2DF 0x7C6C #CJK UNIFIED IDEOGRAPH
+0xE2E0 0x7C75 #CJK UNIFIED IDEOGRAPH
+0xE2E1 0x7C83 #CJK UNIFIED IDEOGRAPH
+0xE2E2 0x7C90 #CJK UNIFIED IDEOGRAPH
+0xE2E3 0x7CA4 #CJK UNIFIED IDEOGRAPH
+0xE2E4 0x7CAD #CJK UNIFIED IDEOGRAPH
+0xE2E5 0x7CA2 #CJK UNIFIED IDEOGRAPH
+0xE2E6 0x7CAB #CJK UNIFIED IDEOGRAPH
+0xE2E7 0x7CA1 #CJK UNIFIED IDEOGRAPH
+0xE2E8 0x7CA8 #CJK UNIFIED IDEOGRAPH
+0xE2E9 0x7CB3 #CJK UNIFIED IDEOGRAPH
+0xE2EA 0x7CB2 #CJK UNIFIED IDEOGRAPH
+0xE2EB 0x7CB1 #CJK UNIFIED IDEOGRAPH
+0xE2EC 0x7CAE #CJK UNIFIED IDEOGRAPH
+0xE2ED 0x7CB9 #CJK UNIFIED IDEOGRAPH
+0xE2EE 0x7CBD #CJK UNIFIED IDEOGRAPH
+0xE2EF 0x7CC0 #CJK UNIFIED IDEOGRAPH
+0xE2F0 0x7CC5 #CJK UNIFIED IDEOGRAPH
+0xE2F1 0x7CC2 #CJK UNIFIED IDEOGRAPH
+0xE2F2 0x7CD8 #CJK UNIFIED IDEOGRAPH
+0xE2F3 0x7CD2 #CJK UNIFIED IDEOGRAPH
+0xE2F4 0x7CDC #CJK UNIFIED IDEOGRAPH
+0xE2F5 0x7CE2 #CJK UNIFIED IDEOGRAPH
+0xE2F6 0x9B3B #CJK UNIFIED IDEOGRAPH
+0xE2F7 0x7CEF #CJK UNIFIED IDEOGRAPH
+0xE2F8 0x7CF2 #CJK UNIFIED IDEOGRAPH
+0xE2F9 0x7CF4 #CJK UNIFIED IDEOGRAPH
+0xE2FA 0x7CF6 #CJK UNIFIED IDEOGRAPH
+0xE2FB 0x7CFA #CJK UNIFIED IDEOGRAPH
+0xE2FC 0x7D06 #CJK UNIFIED IDEOGRAPH
+0xE340 0x7D02 #CJK UNIFIED IDEOGRAPH
+0xE341 0x7D1C #CJK UNIFIED IDEOGRAPH
+0xE342 0x7D15 #CJK UNIFIED IDEOGRAPH
+0xE343 0x7D0A #CJK UNIFIED IDEOGRAPH
+0xE344 0x7D45 #CJK UNIFIED IDEOGRAPH
+0xE345 0x7D4B #CJK UNIFIED IDEOGRAPH
+0xE346 0x7D2E #CJK UNIFIED IDEOGRAPH
+0xE347 0x7D32 #CJK UNIFIED IDEOGRAPH
+0xE348 0x7D3F #CJK UNIFIED IDEOGRAPH
+0xE349 0x7D35 #CJK UNIFIED IDEOGRAPH
+0xE34A 0x7D46 #CJK UNIFIED IDEOGRAPH
+0xE34B 0x7D73 #CJK UNIFIED IDEOGRAPH
+0xE34C 0x7D56 #CJK UNIFIED IDEOGRAPH
+0xE34D 0x7D4E #CJK UNIFIED IDEOGRAPH
+0xE34E 0x7D72 #CJK UNIFIED IDEOGRAPH
+0xE34F 0x7D68 #CJK UNIFIED IDEOGRAPH
+0xE350 0x7D6E #CJK UNIFIED IDEOGRAPH
+0xE351 0x7D4F #CJK UNIFIED IDEOGRAPH
+0xE352 0x7D63 #CJK UNIFIED IDEOGRAPH
+0xE353 0x7D93 #CJK UNIFIED IDEOGRAPH
+0xE354 0x7D89 #CJK UNIFIED IDEOGRAPH
+0xE355 0x7D5B #CJK UNIFIED IDEOGRAPH
+0xE356 0x7D8F #CJK UNIFIED IDEOGRAPH
+0xE357 0x7D7D #CJK UNIFIED IDEOGRAPH
+0xE358 0x7D9B #CJK UNIFIED IDEOGRAPH
+0xE359 0x7DBA #CJK UNIFIED IDEOGRAPH
+0xE35A 0x7DAE #CJK UNIFIED IDEOGRAPH
+0xE35B 0x7DA3 #CJK UNIFIED IDEOGRAPH
+0xE35C 0x7DB5 #CJK UNIFIED IDEOGRAPH
+0xE35D 0x7DC7 #CJK UNIFIED IDEOGRAPH
+0xE35E 0x7DBD #CJK UNIFIED IDEOGRAPH
+0xE35F 0x7DAB #CJK UNIFIED IDEOGRAPH
+0xE360 0x7E3D #CJK UNIFIED IDEOGRAPH
+0xE361 0x7DA2 #CJK UNIFIED IDEOGRAPH
+0xE362 0x7DAF #CJK UNIFIED IDEOGRAPH
+0xE363 0x7DDC #CJK UNIFIED IDEOGRAPH
+0xE364 0x7DB8 #CJK UNIFIED IDEOGRAPH
+0xE365 0x7D9F #CJK UNIFIED IDEOGRAPH
+0xE366 0x7DB0 #CJK UNIFIED IDEOGRAPH
+0xE367 0x7DD8 #CJK UNIFIED IDEOGRAPH
+0xE368 0x7DDD #CJK UNIFIED IDEOGRAPH
+0xE369 0x7DE4 #CJK UNIFIED IDEOGRAPH
+0xE36A 0x7DDE #CJK UNIFIED IDEOGRAPH
+0xE36B 0x7DFB #CJK UNIFIED IDEOGRAPH
+0xE36C 0x7DF2 #CJK UNIFIED IDEOGRAPH
+0xE36D 0x7DE1 #CJK UNIFIED IDEOGRAPH
+0xE36E 0x7E05 #CJK UNIFIED IDEOGRAPH
+0xE36F 0x7E0A #CJK UNIFIED IDEOGRAPH
+0xE370 0x7E23 #CJK UNIFIED IDEOGRAPH
+0xE371 0x7E21 #CJK UNIFIED IDEOGRAPH
+0xE372 0x7E12 #CJK UNIFIED IDEOGRAPH
+0xE373 0x7E31 #CJK UNIFIED IDEOGRAPH
+0xE374 0x7E1F #CJK UNIFIED IDEOGRAPH
+0xE375 0x7E09 #CJK UNIFIED IDEOGRAPH
+0xE376 0x7E0B #CJK UNIFIED IDEOGRAPH
+0xE377 0x7E22 #CJK UNIFIED IDEOGRAPH
+0xE378 0x7E46 #CJK UNIFIED IDEOGRAPH
+0xE379 0x7E66 #CJK UNIFIED IDEOGRAPH
+0xE37A 0x7E3B #CJK UNIFIED IDEOGRAPH
+0xE37B 0x7E35 #CJK UNIFIED IDEOGRAPH
+0xE37C 0x7E39 #CJK UNIFIED IDEOGRAPH
+0xE37D 0x7E43 #CJK UNIFIED IDEOGRAPH
+0xE37E 0x7E37 #CJK UNIFIED IDEOGRAPH
+0xE380 0x7E32 #CJK UNIFIED IDEOGRAPH
+0xE381 0x7E3A #CJK UNIFIED IDEOGRAPH
+0xE382 0x7E67 #CJK UNIFIED IDEOGRAPH
+0xE383 0x7E5D #CJK UNIFIED IDEOGRAPH
+0xE384 0x7E56 #CJK UNIFIED IDEOGRAPH
+0xE385 0x7E5E #CJK UNIFIED IDEOGRAPH
+0xE386 0x7E59 #CJK UNIFIED IDEOGRAPH
+0xE387 0x7E5A #CJK UNIFIED IDEOGRAPH
+0xE388 0x7E79 #CJK UNIFIED IDEOGRAPH
+0xE389 0x7E6A #CJK UNIFIED IDEOGRAPH
+0xE38A 0x7E69 #CJK UNIFIED IDEOGRAPH
+0xE38B 0x7E7C #CJK UNIFIED IDEOGRAPH
+0xE38C 0x7E7B #CJK UNIFIED IDEOGRAPH
+0xE38D 0x7E83 #CJK UNIFIED IDEOGRAPH
+0xE38E 0x7DD5 #CJK UNIFIED IDEOGRAPH
+0xE38F 0x7E7D #CJK UNIFIED IDEOGRAPH
+0xE390 0x8FAE #CJK UNIFIED IDEOGRAPH
+0xE391 0x7E7F #CJK UNIFIED IDEOGRAPH
+0xE392 0x7E88 #CJK UNIFIED IDEOGRAPH
+0xE393 0x7E89 #CJK UNIFIED IDEOGRAPH
+0xE394 0x7E8C #CJK UNIFIED IDEOGRAPH
+0xE395 0x7E92 #CJK UNIFIED IDEOGRAPH
+0xE396 0x7E90 #CJK UNIFIED IDEOGRAPH
+0xE397 0x7E93 #CJK UNIFIED IDEOGRAPH
+0xE398 0x7E94 #CJK UNIFIED IDEOGRAPH
+0xE399 0x7E96 #CJK UNIFIED IDEOGRAPH
+0xE39A 0x7E8E #CJK UNIFIED IDEOGRAPH
+0xE39B 0x7E9B #CJK UNIFIED IDEOGRAPH
+0xE39C 0x7E9C #CJK UNIFIED IDEOGRAPH
+0xE39D 0x7F38 #CJK UNIFIED IDEOGRAPH
+0xE39E 0x7F3A #CJK UNIFIED IDEOGRAPH
+0xE39F 0x7F45 #CJK UNIFIED IDEOGRAPH
+0xE3A0 0x7F4C #CJK UNIFIED IDEOGRAPH
+0xE3A1 0x7F4D #CJK UNIFIED IDEOGRAPH
+0xE3A2 0x7F4E #CJK UNIFIED IDEOGRAPH
+0xE3A3 0x7F50 #CJK UNIFIED IDEOGRAPH
+0xE3A4 0x7F51 #CJK UNIFIED IDEOGRAPH
+0xE3A5 0x7F55 #CJK UNIFIED IDEOGRAPH
+0xE3A6 0x7F54 #CJK UNIFIED IDEOGRAPH
+0xE3A7 0x7F58 #CJK UNIFIED IDEOGRAPH
+0xE3A8 0x7F5F #CJK UNIFIED IDEOGRAPH
+0xE3A9 0x7F60 #CJK UNIFIED IDEOGRAPH
+0xE3AA 0x7F68 #CJK UNIFIED IDEOGRAPH
+0xE3AB 0x7F69 #CJK UNIFIED IDEOGRAPH
+0xE3AC 0x7F67 #CJK UNIFIED IDEOGRAPH
+0xE3AD 0x7F78 #CJK UNIFIED IDEOGRAPH
+0xE3AE 0x7F82 #CJK UNIFIED IDEOGRAPH
+0xE3AF 0x7F86 #CJK UNIFIED IDEOGRAPH
+0xE3B0 0x7F83 #CJK UNIFIED IDEOGRAPH
+0xE3B1 0x7F88 #CJK UNIFIED IDEOGRAPH
+0xE3B2 0x7F87 #CJK UNIFIED IDEOGRAPH
+0xE3B3 0x7F8C #CJK UNIFIED IDEOGRAPH
+0xE3B4 0x7F94 #CJK UNIFIED IDEOGRAPH
+0xE3B5 0x7F9E #CJK UNIFIED IDEOGRAPH
+0xE3B6 0x7F9D #CJK UNIFIED IDEOGRAPH
+0xE3B7 0x7F9A #CJK UNIFIED IDEOGRAPH
+0xE3B8 0x7FA3 #CJK UNIFIED IDEOGRAPH
+0xE3B9 0x7FAF #CJK UNIFIED IDEOGRAPH
+0xE3BA 0x7FB2 #CJK UNIFIED IDEOGRAPH
+0xE3BB 0x7FB9 #CJK UNIFIED IDEOGRAPH
+0xE3BC 0x7FAE #CJK UNIFIED IDEOGRAPH
+0xE3BD 0x7FB6 #CJK UNIFIED IDEOGRAPH
+0xE3BE 0x7FB8 #CJK UNIFIED IDEOGRAPH
+0xE3BF 0x8B71 #CJK UNIFIED IDEOGRAPH
+0xE3C0 0x7FC5 #CJK UNIFIED IDEOGRAPH
+0xE3C1 0x7FC6 #CJK UNIFIED IDEOGRAPH
+0xE3C2 0x7FCA #CJK UNIFIED IDEOGRAPH
+0xE3C3 0x7FD5 #CJK UNIFIED IDEOGRAPH
+0xE3C4 0x7FD4 #CJK UNIFIED IDEOGRAPH
+0xE3C5 0x7FE1 #CJK UNIFIED IDEOGRAPH
+0xE3C6 0x7FE6 #CJK UNIFIED IDEOGRAPH
+0xE3C7 0x7FE9 #CJK UNIFIED IDEOGRAPH
+0xE3C8 0x7FF3 #CJK UNIFIED IDEOGRAPH
+0xE3C9 0x7FF9 #CJK UNIFIED IDEOGRAPH
+0xE3CA 0x98DC #CJK UNIFIED IDEOGRAPH
+0xE3CB 0x8006 #CJK UNIFIED IDEOGRAPH
+0xE3CC 0x8004 #CJK UNIFIED IDEOGRAPH
+0xE3CD 0x800B #CJK UNIFIED IDEOGRAPH
+0xE3CE 0x8012 #CJK UNIFIED IDEOGRAPH
+0xE3CF 0x8018 #CJK UNIFIED IDEOGRAPH
+0xE3D0 0x8019 #CJK UNIFIED IDEOGRAPH
+0xE3D1 0x801C #CJK UNIFIED IDEOGRAPH
+0xE3D2 0x8021 #CJK UNIFIED IDEOGRAPH
+0xE3D3 0x8028 #CJK UNIFIED IDEOGRAPH
+0xE3D4 0x803F #CJK UNIFIED IDEOGRAPH
+0xE3D5 0x803B #CJK UNIFIED IDEOGRAPH
+0xE3D6 0x804A #CJK UNIFIED IDEOGRAPH
+0xE3D7 0x8046 #CJK UNIFIED IDEOGRAPH
+0xE3D8 0x8052 #CJK UNIFIED IDEOGRAPH
+0xE3D9 0x8058 #CJK UNIFIED IDEOGRAPH
+0xE3DA 0x805A #CJK UNIFIED IDEOGRAPH
+0xE3DB 0x805F #CJK UNIFIED IDEOGRAPH
+0xE3DC 0x8062 #CJK UNIFIED IDEOGRAPH
+0xE3DD 0x8068 #CJK UNIFIED IDEOGRAPH
+0xE3DE 0x8073 #CJK UNIFIED IDEOGRAPH
+0xE3DF 0x8072 #CJK UNIFIED IDEOGRAPH
+0xE3E0 0x8070 #CJK UNIFIED IDEOGRAPH
+0xE3E1 0x8076 #CJK UNIFIED IDEOGRAPH
+0xE3E2 0x8079 #CJK UNIFIED IDEOGRAPH
+0xE3E3 0x807D #CJK UNIFIED IDEOGRAPH
+0xE3E4 0x807F #CJK UNIFIED IDEOGRAPH
+0xE3E5 0x8084 #CJK UNIFIED IDEOGRAPH
+0xE3E6 0x8086 #CJK UNIFIED IDEOGRAPH
+0xE3E7 0x8085 #CJK UNIFIED IDEOGRAPH
+0xE3E8 0x809B #CJK UNIFIED IDEOGRAPH
+0xE3E9 0x8093 #CJK UNIFIED IDEOGRAPH
+0xE3EA 0x809A #CJK UNIFIED IDEOGRAPH
+0xE3EB 0x80AD #CJK UNIFIED IDEOGRAPH
+0xE3EC 0x5190 #CJK UNIFIED IDEOGRAPH
+0xE3ED 0x80AC #CJK UNIFIED IDEOGRAPH
+0xE3EE 0x80DB #CJK UNIFIED IDEOGRAPH
+0xE3EF 0x80E5 #CJK UNIFIED IDEOGRAPH
+0xE3F0 0x80D9 #CJK UNIFIED IDEOGRAPH
+0xE3F1 0x80DD #CJK UNIFIED IDEOGRAPH
+0xE3F2 0x80C4 #CJK UNIFIED IDEOGRAPH
+0xE3F3 0x80DA #CJK UNIFIED IDEOGRAPH
+0xE3F4 0x80D6 #CJK UNIFIED IDEOGRAPH
+0xE3F5 0x8109 #CJK UNIFIED IDEOGRAPH
+0xE3F6 0x80EF #CJK UNIFIED IDEOGRAPH
+0xE3F7 0x80F1 #CJK UNIFIED IDEOGRAPH
+0xE3F8 0x811B #CJK UNIFIED IDEOGRAPH
+0xE3F9 0x8129 #CJK UNIFIED IDEOGRAPH
+0xE3FA 0x8123 #CJK UNIFIED IDEOGRAPH
+0xE3FB 0x812F #CJK UNIFIED IDEOGRAPH
+0xE3FC 0x814B #CJK UNIFIED IDEOGRAPH
+0xE440 0x968B #CJK UNIFIED IDEOGRAPH
+0xE441 0x8146 #CJK UNIFIED IDEOGRAPH
+0xE442 0x813E #CJK UNIFIED IDEOGRAPH
+0xE443 0x8153 #CJK UNIFIED IDEOGRAPH
+0xE444 0x8151 #CJK UNIFIED IDEOGRAPH
+0xE445 0x80FC #CJK UNIFIED IDEOGRAPH
+0xE446 0x8171 #CJK UNIFIED IDEOGRAPH
+0xE447 0x816E #CJK UNIFIED IDEOGRAPH
+0xE448 0x8165 #CJK UNIFIED IDEOGRAPH
+0xE449 0x8166 #CJK UNIFIED IDEOGRAPH
+0xE44A 0x8174 #CJK UNIFIED IDEOGRAPH
+0xE44B 0x8183 #CJK UNIFIED IDEOGRAPH
+0xE44C 0x8188 #CJK UNIFIED IDEOGRAPH
+0xE44D 0x818A #CJK UNIFIED IDEOGRAPH
+0xE44E 0x8180 #CJK UNIFIED IDEOGRAPH
+0xE44F 0x8182 #CJK UNIFIED IDEOGRAPH
+0xE450 0x81A0 #CJK UNIFIED IDEOGRAPH
+0xE451 0x8195 #CJK UNIFIED IDEOGRAPH
+0xE452 0x81A4 #CJK UNIFIED IDEOGRAPH
+0xE453 0x81A3 #CJK UNIFIED IDEOGRAPH
+0xE454 0x815F #CJK UNIFIED IDEOGRAPH
+0xE455 0x8193 #CJK UNIFIED IDEOGRAPH
+0xE456 0x81A9 #CJK UNIFIED IDEOGRAPH
+0xE457 0x81B0 #CJK UNIFIED IDEOGRAPH
+0xE458 0x81B5 #CJK UNIFIED IDEOGRAPH
+0xE459 0x81BE #CJK UNIFIED IDEOGRAPH
+0xE45A 0x81B8 #CJK UNIFIED IDEOGRAPH
+0xE45B 0x81BD #CJK UNIFIED IDEOGRAPH
+0xE45C 0x81C0 #CJK UNIFIED IDEOGRAPH
+0xE45D 0x81C2 #CJK UNIFIED IDEOGRAPH
+0xE45E 0x81BA #CJK UNIFIED IDEOGRAPH
+0xE45F 0x81C9 #CJK UNIFIED IDEOGRAPH
+0xE460 0x81CD #CJK UNIFIED IDEOGRAPH
+0xE461 0x81D1 #CJK UNIFIED IDEOGRAPH
+0xE462 0x81D9 #CJK UNIFIED IDEOGRAPH
+0xE463 0x81D8 #CJK UNIFIED IDEOGRAPH
+0xE464 0x81C8 #CJK UNIFIED IDEOGRAPH
+0xE465 0x81DA #CJK UNIFIED IDEOGRAPH
+0xE466 0x81DF #CJK UNIFIED IDEOGRAPH
+0xE467 0x81E0 #CJK UNIFIED IDEOGRAPH
+0xE468 0x81E7 #CJK UNIFIED IDEOGRAPH
+0xE469 0x81FA #CJK UNIFIED IDEOGRAPH
+0xE46A 0x81FB #CJK UNIFIED IDEOGRAPH
+0xE46B 0x81FE #CJK UNIFIED IDEOGRAPH
+0xE46C 0x8201 #CJK UNIFIED IDEOGRAPH
+0xE46D 0x8202 #CJK UNIFIED IDEOGRAPH
+0xE46E 0x8205 #CJK UNIFIED IDEOGRAPH
+0xE46F 0x8207 #CJK UNIFIED IDEOGRAPH
+0xE470 0x820A #CJK UNIFIED IDEOGRAPH
+0xE471 0x820D #CJK UNIFIED IDEOGRAPH
+0xE472 0x8210 #CJK UNIFIED IDEOGRAPH
+0xE473 0x8216 #CJK UNIFIED IDEOGRAPH
+0xE474 0x8229 #CJK UNIFIED IDEOGRAPH
+0xE475 0x822B #CJK UNIFIED IDEOGRAPH
+0xE476 0x8238 #CJK UNIFIED IDEOGRAPH
+0xE477 0x8233 #CJK UNIFIED IDEOGRAPH
+0xE478 0x8240 #CJK UNIFIED IDEOGRAPH
+0xE479 0x8259 #CJK UNIFIED IDEOGRAPH
+0xE47A 0x8258 #CJK UNIFIED IDEOGRAPH
+0xE47B 0x825D #CJK UNIFIED IDEOGRAPH
+0xE47C 0x825A #CJK UNIFIED IDEOGRAPH
+0xE47D 0x825F #CJK UNIFIED IDEOGRAPH
+0xE47E 0x8264 #CJK UNIFIED IDEOGRAPH
+0xE480 0x8262 #CJK UNIFIED IDEOGRAPH
+0xE481 0x8268 #CJK UNIFIED IDEOGRAPH
+0xE482 0x826A #CJK UNIFIED IDEOGRAPH
+0xE483 0x826B #CJK UNIFIED IDEOGRAPH
+0xE484 0x822E #CJK UNIFIED IDEOGRAPH
+0xE485 0x8271 #CJK UNIFIED IDEOGRAPH
+0xE486 0x8277 #CJK UNIFIED IDEOGRAPH
+0xE487 0x8278 #CJK UNIFIED IDEOGRAPH
+0xE488 0x827E #CJK UNIFIED IDEOGRAPH
+0xE489 0x828D #CJK UNIFIED IDEOGRAPH
+0xE48A 0x8292 #CJK UNIFIED IDEOGRAPH
+0xE48B 0x82AB #CJK UNIFIED IDEOGRAPH
+0xE48C 0x829F #CJK UNIFIED IDEOGRAPH
+0xE48D 0x82BB #CJK UNIFIED IDEOGRAPH
+0xE48E 0x82AC #CJK UNIFIED IDEOGRAPH
+0xE48F 0x82E1 #CJK UNIFIED IDEOGRAPH
+0xE490 0x82E3 #CJK UNIFIED IDEOGRAPH
+0xE491 0x82DF #CJK UNIFIED IDEOGRAPH
+0xE492 0x82D2 #CJK UNIFIED IDEOGRAPH
+0xE493 0x82F4 #CJK UNIFIED IDEOGRAPH
+0xE494 0x82F3 #CJK UNIFIED IDEOGRAPH
+0xE495 0x82FA #CJK UNIFIED IDEOGRAPH
+0xE496 0x8393 #CJK UNIFIED IDEOGRAPH
+0xE497 0x8303 #CJK UNIFIED IDEOGRAPH
+0xE498 0x82FB #CJK UNIFIED IDEOGRAPH
+0xE499 0x82F9 #CJK UNIFIED IDEOGRAPH
+0xE49A 0x82DE #CJK UNIFIED IDEOGRAPH
+0xE49B 0x8306 #CJK UNIFIED IDEOGRAPH
+0xE49C 0x82DC #CJK UNIFIED IDEOGRAPH
+0xE49D 0x8309 #CJK UNIFIED IDEOGRAPH
+0xE49E 0x82D9 #CJK UNIFIED IDEOGRAPH
+0xE49F 0x8335 #CJK UNIFIED IDEOGRAPH
+0xE4A0 0x8334 #CJK UNIFIED IDEOGRAPH
+0xE4A1 0x8316 #CJK UNIFIED IDEOGRAPH
+0xE4A2 0x8332 #CJK UNIFIED IDEOGRAPH
+0xE4A3 0x8331 #CJK UNIFIED IDEOGRAPH
+0xE4A4 0x8340 #CJK UNIFIED IDEOGRAPH
+0xE4A5 0x8339 #CJK UNIFIED IDEOGRAPH
+0xE4A6 0x8350 #CJK UNIFIED IDEOGRAPH
+0xE4A7 0x8345 #CJK UNIFIED IDEOGRAPH
+0xE4A8 0x832F #CJK UNIFIED IDEOGRAPH
+0xE4A9 0x832B #CJK UNIFIED IDEOGRAPH
+0xE4AA 0x8317 #CJK UNIFIED IDEOGRAPH
+0xE4AB 0x8318 #CJK UNIFIED IDEOGRAPH
+0xE4AC 0x8385 #CJK UNIFIED IDEOGRAPH
+0xE4AD 0x839A #CJK UNIFIED IDEOGRAPH
+0xE4AE 0x83AA #CJK UNIFIED IDEOGRAPH
+0xE4AF 0x839F #CJK UNIFIED IDEOGRAPH
+0xE4B0 0x83A2 #CJK UNIFIED IDEOGRAPH
+0xE4B1 0x8396 #CJK UNIFIED IDEOGRAPH
+0xE4B2 0x8323 #CJK UNIFIED IDEOGRAPH
+0xE4B3 0x838E #CJK UNIFIED IDEOGRAPH
+0xE4B4 0x8387 #CJK UNIFIED IDEOGRAPH
+0xE4B5 0x838A #CJK UNIFIED IDEOGRAPH
+0xE4B6 0x837C #CJK UNIFIED IDEOGRAPH
+0xE4B7 0x83B5 #CJK UNIFIED IDEOGRAPH
+0xE4B8 0x8373 #CJK UNIFIED IDEOGRAPH
+0xE4B9 0x8375 #CJK UNIFIED IDEOGRAPH
+0xE4BA 0x83A0 #CJK UNIFIED IDEOGRAPH
+0xE4BB 0x8389 #CJK UNIFIED IDEOGRAPH
+0xE4BC 0x83A8 #CJK UNIFIED IDEOGRAPH
+0xE4BD 0x83F4 #CJK UNIFIED IDEOGRAPH
+0xE4BE 0x8413 #CJK UNIFIED IDEOGRAPH
+0xE4BF 0x83EB #CJK UNIFIED IDEOGRAPH
+0xE4C0 0x83CE #CJK UNIFIED IDEOGRAPH
+0xE4C1 0x83FD #CJK UNIFIED IDEOGRAPH
+0xE4C2 0x8403 #CJK UNIFIED IDEOGRAPH
+0xE4C3 0x83D8 #CJK UNIFIED IDEOGRAPH
+0xE4C4 0x840B #CJK UNIFIED IDEOGRAPH
+0xE4C5 0x83C1 #CJK UNIFIED IDEOGRAPH
+0xE4C6 0x83F7 #CJK UNIFIED IDEOGRAPH
+0xE4C7 0x8407 #CJK UNIFIED IDEOGRAPH
+0xE4C8 0x83E0 #CJK UNIFIED IDEOGRAPH
+0xE4C9 0x83F2 #CJK UNIFIED IDEOGRAPH
+0xE4CA 0x840D #CJK UNIFIED IDEOGRAPH
+0xE4CB 0x8422 #CJK UNIFIED IDEOGRAPH
+0xE4CC 0x8420 #CJK UNIFIED IDEOGRAPH
+0xE4CD 0x83BD #CJK UNIFIED IDEOGRAPH
+0xE4CE 0x8438 #CJK UNIFIED IDEOGRAPH
+0xE4CF 0x8506 #CJK UNIFIED IDEOGRAPH
+0xE4D0 0x83FB #CJK UNIFIED IDEOGRAPH
+0xE4D1 0x846D #CJK UNIFIED IDEOGRAPH
+0xE4D2 0x842A #CJK UNIFIED IDEOGRAPH
+0xE4D3 0x843C #CJK UNIFIED IDEOGRAPH
+0xE4D4 0x855A #CJK UNIFIED IDEOGRAPH
+0xE4D5 0x8484 #CJK UNIFIED IDEOGRAPH
+0xE4D6 0x8477 #CJK UNIFIED IDEOGRAPH
+0xE4D7 0x846B #CJK UNIFIED IDEOGRAPH
+0xE4D8 0x84AD #CJK UNIFIED IDEOGRAPH
+0xE4D9 0x846E #CJK UNIFIED IDEOGRAPH
+0xE4DA 0x8482 #CJK UNIFIED IDEOGRAPH
+0xE4DB 0x8469 #CJK UNIFIED IDEOGRAPH
+0xE4DC 0x8446 #CJK UNIFIED IDEOGRAPH
+0xE4DD 0x842C #CJK UNIFIED IDEOGRAPH
+0xE4DE 0x846F #CJK UNIFIED IDEOGRAPH
+0xE4DF 0x8479 #CJK UNIFIED IDEOGRAPH
+0xE4E0 0x8435 #CJK UNIFIED IDEOGRAPH
+0xE4E1 0x84CA #CJK UNIFIED IDEOGRAPH
+0xE4E2 0x8462 #CJK UNIFIED IDEOGRAPH
+0xE4E3 0x84B9 #CJK UNIFIED IDEOGRAPH
+0xE4E4 0x84BF #CJK UNIFIED IDEOGRAPH
+0xE4E5 0x849F #CJK UNIFIED IDEOGRAPH
+0xE4E6 0x84D9 #CJK UNIFIED IDEOGRAPH
+0xE4E7 0x84CD #CJK UNIFIED IDEOGRAPH
+0xE4E8 0x84BB #CJK UNIFIED IDEOGRAPH
+0xE4E9 0x84DA #CJK UNIFIED IDEOGRAPH
+0xE4EA 0x84D0 #CJK UNIFIED IDEOGRAPH
+0xE4EB 0x84C1 #CJK UNIFIED IDEOGRAPH
+0xE4EC 0x84C6 #CJK UNIFIED IDEOGRAPH
+0xE4ED 0x84D6 #CJK UNIFIED IDEOGRAPH
+0xE4EE 0x84A1 #CJK UNIFIED IDEOGRAPH
+0xE4EF 0x8521 #CJK UNIFIED IDEOGRAPH
+0xE4F0 0x84FF #CJK UNIFIED IDEOGRAPH
+0xE4F1 0x84F4 #CJK UNIFIED IDEOGRAPH
+0xE4F2 0x8517 #CJK UNIFIED IDEOGRAPH
+0xE4F3 0x8518 #CJK UNIFIED IDEOGRAPH
+0xE4F4 0x852C #CJK UNIFIED IDEOGRAPH
+0xE4F5 0x851F #CJK UNIFIED IDEOGRAPH
+0xE4F6 0x8515 #CJK UNIFIED IDEOGRAPH
+0xE4F7 0x8514 #CJK UNIFIED IDEOGRAPH
+0xE4F8 0x84FC #CJK UNIFIED IDEOGRAPH
+0xE4F9 0x8540 #CJK UNIFIED IDEOGRAPH
+0xE4FA 0x8563 #CJK UNIFIED IDEOGRAPH
+0xE4FB 0x8558 #CJK UNIFIED IDEOGRAPH
+0xE4FC 0x8548 #CJK UNIFIED IDEOGRAPH
+0xE540 0x8541 #CJK UNIFIED IDEOGRAPH
+0xE541 0x8602 #CJK UNIFIED IDEOGRAPH
+0xE542 0x854B #CJK UNIFIED IDEOGRAPH
+0xE543 0x8555 #CJK UNIFIED IDEOGRAPH
+0xE544 0x8580 #CJK UNIFIED IDEOGRAPH
+0xE545 0x85A4 #CJK UNIFIED IDEOGRAPH
+0xE546 0x8588 #CJK UNIFIED IDEOGRAPH
+0xE547 0x8591 #CJK UNIFIED IDEOGRAPH
+0xE548 0x858A #CJK UNIFIED IDEOGRAPH
+0xE549 0x85A8 #CJK UNIFIED IDEOGRAPH
+0xE54A 0x856D #CJK UNIFIED IDEOGRAPH
+0xE54B 0x8594 #CJK UNIFIED IDEOGRAPH
+0xE54C 0x859B #CJK UNIFIED IDEOGRAPH
+0xE54D 0x85EA #CJK UNIFIED IDEOGRAPH
+0xE54E 0x8587 #CJK UNIFIED IDEOGRAPH
+0xE54F 0x859C #CJK UNIFIED IDEOGRAPH
+0xE550 0x8577 #CJK UNIFIED IDEOGRAPH
+0xE551 0x857E #CJK UNIFIED IDEOGRAPH
+0xE552 0x8590 #CJK UNIFIED IDEOGRAPH
+0xE553 0x85C9 #CJK UNIFIED IDEOGRAPH
+0xE554 0x85BA #CJK UNIFIED IDEOGRAPH
+0xE555 0x85CF #CJK UNIFIED IDEOGRAPH
+0xE556 0x85B9 #CJK UNIFIED IDEOGRAPH
+0xE557 0x85D0 #CJK UNIFIED IDEOGRAPH
+0xE558 0x85D5 #CJK UNIFIED IDEOGRAPH
+0xE559 0x85DD #CJK UNIFIED IDEOGRAPH
+0xE55A 0x85E5 #CJK UNIFIED IDEOGRAPH
+0xE55B 0x85DC #CJK UNIFIED IDEOGRAPH
+0xE55C 0x85F9 #CJK UNIFIED IDEOGRAPH
+0xE55D 0x860A #CJK UNIFIED IDEOGRAPH
+0xE55E 0x8613 #CJK UNIFIED IDEOGRAPH
+0xE55F 0x860B #CJK UNIFIED IDEOGRAPH
+0xE560 0x85FE #CJK UNIFIED IDEOGRAPH
+0xE561 0x85FA #CJK UNIFIED IDEOGRAPH
+0xE562 0x8606 #CJK UNIFIED IDEOGRAPH
+0xE563 0x8622 #CJK UNIFIED IDEOGRAPH
+0xE564 0x861A #CJK UNIFIED IDEOGRAPH
+0xE565 0x8630 #CJK UNIFIED IDEOGRAPH
+0xE566 0x863F #CJK UNIFIED IDEOGRAPH
+0xE567 0x864D #CJK UNIFIED IDEOGRAPH
+0xE568 0x4E55 #CJK UNIFIED IDEOGRAPH
+0xE569 0x8654 #CJK UNIFIED IDEOGRAPH
+0xE56A 0x865F #CJK UNIFIED IDEOGRAPH
+0xE56B 0x8667 #CJK UNIFIED IDEOGRAPH
+0xE56C 0x8671 #CJK UNIFIED IDEOGRAPH
+0xE56D 0x8693 #CJK UNIFIED IDEOGRAPH
+0xE56E 0x86A3 #CJK UNIFIED IDEOGRAPH
+0xE56F 0x86A9 #CJK UNIFIED IDEOGRAPH
+0xE570 0x86AA #CJK UNIFIED IDEOGRAPH
+0xE571 0x868B #CJK UNIFIED IDEOGRAPH
+0xE572 0x868C #CJK UNIFIED IDEOGRAPH
+0xE573 0x86B6 #CJK UNIFIED IDEOGRAPH
+0xE574 0x86AF #CJK UNIFIED IDEOGRAPH
+0xE575 0x86C4 #CJK UNIFIED IDEOGRAPH
+0xE576 0x86C6 #CJK UNIFIED IDEOGRAPH
+0xE577 0x86B0 #CJK UNIFIED IDEOGRAPH
+0xE578 0x86C9 #CJK UNIFIED IDEOGRAPH
+0xE579 0x8823 #CJK UNIFIED IDEOGRAPH
+0xE57A 0x86AB #CJK UNIFIED IDEOGRAPH
+0xE57B 0x86D4 #CJK UNIFIED IDEOGRAPH
+0xE57C 0x86DE #CJK UNIFIED IDEOGRAPH
+0xE57D 0x86E9 #CJK UNIFIED IDEOGRAPH
+0xE57E 0x86EC #CJK UNIFIED IDEOGRAPH
+0xE580 0x86DF #CJK UNIFIED IDEOGRAPH
+0xE581 0x86DB #CJK UNIFIED IDEOGRAPH
+0xE582 0x86EF #CJK UNIFIED IDEOGRAPH
+0xE583 0x8712 #CJK UNIFIED IDEOGRAPH
+0xE584 0x8706 #CJK UNIFIED IDEOGRAPH
+0xE585 0x8708 #CJK UNIFIED IDEOGRAPH
+0xE586 0x8700 #CJK UNIFIED IDEOGRAPH
+0xE587 0x8703 #CJK UNIFIED IDEOGRAPH
+0xE588 0x86FB #CJK UNIFIED IDEOGRAPH
+0xE589 0x8711 #CJK UNIFIED IDEOGRAPH
+0xE58A 0x8709 #CJK UNIFIED IDEOGRAPH
+0xE58B 0x870D #CJK UNIFIED IDEOGRAPH
+0xE58C 0x86F9 #CJK UNIFIED IDEOGRAPH
+0xE58D 0x870A #CJK UNIFIED IDEOGRAPH
+0xE58E 0x8734 #CJK UNIFIED IDEOGRAPH
+0xE58F 0x873F #CJK UNIFIED IDEOGRAPH
+0xE590 0x8737 #CJK UNIFIED IDEOGRAPH
+0xE591 0x873B #CJK UNIFIED IDEOGRAPH
+0xE592 0x8725 #CJK UNIFIED IDEOGRAPH
+0xE593 0x8729 #CJK UNIFIED IDEOGRAPH
+0xE594 0x871A #CJK UNIFIED IDEOGRAPH
+0xE595 0x8760 #CJK UNIFIED IDEOGRAPH
+0xE596 0x875F #CJK UNIFIED IDEOGRAPH
+0xE597 0x8778 #CJK UNIFIED IDEOGRAPH
+0xE598 0x874C #CJK UNIFIED IDEOGRAPH
+0xE599 0x874E #CJK UNIFIED IDEOGRAPH
+0xE59A 0x8774 #CJK UNIFIED IDEOGRAPH
+0xE59B 0x8757 #CJK UNIFIED IDEOGRAPH
+0xE59C 0x8768 #CJK UNIFIED IDEOGRAPH
+0xE59D 0x876E #CJK UNIFIED IDEOGRAPH
+0xE59E 0x8759 #CJK UNIFIED IDEOGRAPH
+0xE59F 0x8753 #CJK UNIFIED IDEOGRAPH
+0xE5A0 0x8763 #CJK UNIFIED IDEOGRAPH
+0xE5A1 0x876A #CJK UNIFIED IDEOGRAPH
+0xE5A2 0x8805 #CJK UNIFIED IDEOGRAPH
+0xE5A3 0x87A2 #CJK UNIFIED IDEOGRAPH
+0xE5A4 0x879F #CJK UNIFIED IDEOGRAPH
+0xE5A5 0x8782 #CJK UNIFIED IDEOGRAPH
+0xE5A6 0x87AF #CJK UNIFIED IDEOGRAPH
+0xE5A7 0x87CB #CJK UNIFIED IDEOGRAPH
+0xE5A8 0x87BD #CJK UNIFIED IDEOGRAPH
+0xE5A9 0x87C0 #CJK UNIFIED IDEOGRAPH
+0xE5AA 0x87D0 #CJK UNIFIED IDEOGRAPH
+0xE5AB 0x96D6 #CJK UNIFIED IDEOGRAPH
+0xE5AC 0x87AB #CJK UNIFIED IDEOGRAPH
+0xE5AD 0x87C4 #CJK UNIFIED IDEOGRAPH
+0xE5AE 0x87B3 #CJK UNIFIED IDEOGRAPH
+0xE5AF 0x87C7 #CJK UNIFIED IDEOGRAPH
+0xE5B0 0x87C6 #CJK UNIFIED IDEOGRAPH
+0xE5B1 0x87BB #CJK UNIFIED IDEOGRAPH
+0xE5B2 0x87EF #CJK UNIFIED IDEOGRAPH
+0xE5B3 0x87F2 #CJK UNIFIED IDEOGRAPH
+0xE5B4 0x87E0 #CJK UNIFIED IDEOGRAPH
+0xE5B5 0x880F #CJK UNIFIED IDEOGRAPH
+0xE5B6 0x880D #CJK UNIFIED IDEOGRAPH
+0xE5B7 0x87FE #CJK UNIFIED IDEOGRAPH
+0xE5B8 0x87F6 #CJK UNIFIED IDEOGRAPH
+0xE5B9 0x87F7 #CJK UNIFIED IDEOGRAPH
+0xE5BA 0x880E #CJK UNIFIED IDEOGRAPH
+0xE5BB 0x87D2 #CJK UNIFIED IDEOGRAPH
+0xE5BC 0x8811 #CJK UNIFIED IDEOGRAPH
+0xE5BD 0x8816 #CJK UNIFIED IDEOGRAPH
+0xE5BE 0x8815 #CJK UNIFIED IDEOGRAPH
+0xE5BF 0x8822 #CJK UNIFIED IDEOGRAPH
+0xE5C0 0x8821 #CJK UNIFIED IDEOGRAPH
+0xE5C1 0x8831 #CJK UNIFIED IDEOGRAPH
+0xE5C2 0x8836 #CJK UNIFIED IDEOGRAPH
+0xE5C3 0x8839 #CJK UNIFIED IDEOGRAPH
+0xE5C4 0x8827 #CJK UNIFIED IDEOGRAPH
+0xE5C5 0x883B #CJK UNIFIED IDEOGRAPH
+0xE5C6 0x8844 #CJK UNIFIED IDEOGRAPH
+0xE5C7 0x8842 #CJK UNIFIED IDEOGRAPH
+0xE5C8 0x8852 #CJK UNIFIED IDEOGRAPH
+0xE5C9 0x8859 #CJK UNIFIED IDEOGRAPH
+0xE5CA 0x885E #CJK UNIFIED IDEOGRAPH
+0xE5CB 0x8862 #CJK UNIFIED IDEOGRAPH
+0xE5CC 0x886B #CJK UNIFIED IDEOGRAPH
+0xE5CD 0x8881 #CJK UNIFIED IDEOGRAPH
+0xE5CE 0x887E #CJK UNIFIED IDEOGRAPH
+0xE5CF 0x889E #CJK UNIFIED IDEOGRAPH
+0xE5D0 0x8875 #CJK UNIFIED IDEOGRAPH
+0xE5D1 0x887D #CJK UNIFIED IDEOGRAPH
+0xE5D2 0x88B5 #CJK UNIFIED IDEOGRAPH
+0xE5D3 0x8872 #CJK UNIFIED IDEOGRAPH
+0xE5D4 0x8882 #CJK UNIFIED IDEOGRAPH
+0xE5D5 0x8897 #CJK UNIFIED IDEOGRAPH
+0xE5D6 0x8892 #CJK UNIFIED IDEOGRAPH
+0xE5D7 0x88AE #CJK UNIFIED IDEOGRAPH
+0xE5D8 0x8899 #CJK UNIFIED IDEOGRAPH
+0xE5D9 0x88A2 #CJK UNIFIED IDEOGRAPH
+0xE5DA 0x888D #CJK UNIFIED IDEOGRAPH
+0xE5DB 0x88A4 #CJK UNIFIED IDEOGRAPH
+0xE5DC 0x88B0 #CJK UNIFIED IDEOGRAPH
+0xE5DD 0x88BF #CJK UNIFIED IDEOGRAPH
+0xE5DE 0x88B1 #CJK UNIFIED IDEOGRAPH
+0xE5DF 0x88C3 #CJK UNIFIED IDEOGRAPH
+0xE5E0 0x88C4 #CJK UNIFIED IDEOGRAPH
+0xE5E1 0x88D4 #CJK UNIFIED IDEOGRAPH
+0xE5E2 0x88D8 #CJK UNIFIED IDEOGRAPH
+0xE5E3 0x88D9 #CJK UNIFIED IDEOGRAPH
+0xE5E4 0x88DD #CJK UNIFIED IDEOGRAPH
+0xE5E5 0x88F9 #CJK UNIFIED IDEOGRAPH
+0xE5E6 0x8902 #CJK UNIFIED IDEOGRAPH
+0xE5E7 0x88FC #CJK UNIFIED IDEOGRAPH
+0xE5E8 0x88F4 #CJK UNIFIED IDEOGRAPH
+0xE5E9 0x88E8 #CJK UNIFIED IDEOGRAPH
+0xE5EA 0x88F2 #CJK UNIFIED IDEOGRAPH
+0xE5EB 0x8904 #CJK UNIFIED IDEOGRAPH
+0xE5EC 0x890C #CJK UNIFIED IDEOGRAPH
+0xE5ED 0x890A #CJK UNIFIED IDEOGRAPH
+0xE5EE 0x8913 #CJK UNIFIED IDEOGRAPH
+0xE5EF 0x8943 #CJK UNIFIED IDEOGRAPH
+0xE5F0 0x891E #CJK UNIFIED IDEOGRAPH
+0xE5F1 0x8925 #CJK UNIFIED IDEOGRAPH
+0xE5F2 0x892A #CJK UNIFIED IDEOGRAPH
+0xE5F3 0x892B #CJK UNIFIED IDEOGRAPH
+0xE5F4 0x8941 #CJK UNIFIED IDEOGRAPH
+0xE5F5 0x8944 #CJK UNIFIED IDEOGRAPH
+0xE5F6 0x893B #CJK UNIFIED IDEOGRAPH
+0xE5F7 0x8936 #CJK UNIFIED IDEOGRAPH
+0xE5F8 0x8938 #CJK UNIFIED IDEOGRAPH
+0xE5F9 0x894C #CJK UNIFIED IDEOGRAPH
+0xE5FA 0x891D #CJK UNIFIED IDEOGRAPH
+0xE5FB 0x8960 #CJK UNIFIED IDEOGRAPH
+0xE5FC 0x895E #CJK UNIFIED IDEOGRAPH
+0xE640 0x8966 #CJK UNIFIED IDEOGRAPH
+0xE641 0x8964 #CJK UNIFIED IDEOGRAPH
+0xE642 0x896D #CJK UNIFIED IDEOGRAPH
+0xE643 0x896A #CJK UNIFIED IDEOGRAPH
+0xE644 0x896F #CJK UNIFIED IDEOGRAPH
+0xE645 0x8974 #CJK UNIFIED IDEOGRAPH
+0xE646 0x8977 #CJK UNIFIED IDEOGRAPH
+0xE647 0x897E #CJK UNIFIED IDEOGRAPH
+0xE648 0x8983 #CJK UNIFIED IDEOGRAPH
+0xE649 0x8988 #CJK UNIFIED IDEOGRAPH
+0xE64A 0x898A #CJK UNIFIED IDEOGRAPH
+0xE64B 0x8993 #CJK UNIFIED IDEOGRAPH
+0xE64C 0x8998 #CJK UNIFIED IDEOGRAPH
+0xE64D 0x89A1 #CJK UNIFIED IDEOGRAPH
+0xE64E 0x89A9 #CJK UNIFIED IDEOGRAPH
+0xE64F 0x89A6 #CJK UNIFIED IDEOGRAPH
+0xE650 0x89AC #CJK UNIFIED IDEOGRAPH
+0xE651 0x89AF #CJK UNIFIED IDEOGRAPH
+0xE652 0x89B2 #CJK UNIFIED IDEOGRAPH
+0xE653 0x89BA #CJK UNIFIED IDEOGRAPH
+0xE654 0x89BD #CJK UNIFIED IDEOGRAPH
+0xE655 0x89BF #CJK UNIFIED IDEOGRAPH
+0xE656 0x89C0 #CJK UNIFIED IDEOGRAPH
+0xE657 0x89DA #CJK UNIFIED IDEOGRAPH
+0xE658 0x89DC #CJK UNIFIED IDEOGRAPH
+0xE659 0x89DD #CJK UNIFIED IDEOGRAPH
+0xE65A 0x89E7 #CJK UNIFIED IDEOGRAPH
+0xE65B 0x89F4 #CJK UNIFIED IDEOGRAPH
+0xE65C 0x89F8 #CJK UNIFIED IDEOGRAPH
+0xE65D 0x8A03 #CJK UNIFIED IDEOGRAPH
+0xE65E 0x8A16 #CJK UNIFIED IDEOGRAPH
+0xE65F 0x8A10 #CJK UNIFIED IDEOGRAPH
+0xE660 0x8A0C #CJK UNIFIED IDEOGRAPH
+0xE661 0x8A1B #CJK UNIFIED IDEOGRAPH
+0xE662 0x8A1D #CJK UNIFIED IDEOGRAPH
+0xE663 0x8A25 #CJK UNIFIED IDEOGRAPH
+0xE664 0x8A36 #CJK UNIFIED IDEOGRAPH
+0xE665 0x8A41 #CJK UNIFIED IDEOGRAPH
+0xE666 0x8A5B #CJK UNIFIED IDEOGRAPH
+0xE667 0x8A52 #CJK UNIFIED IDEOGRAPH
+0xE668 0x8A46 #CJK UNIFIED IDEOGRAPH
+0xE669 0x8A48 #CJK UNIFIED IDEOGRAPH
+0xE66A 0x8A7C #CJK UNIFIED IDEOGRAPH
+0xE66B 0x8A6D #CJK UNIFIED IDEOGRAPH
+0xE66C 0x8A6C #CJK UNIFIED IDEOGRAPH
+0xE66D 0x8A62 #CJK UNIFIED IDEOGRAPH
+0xE66E 0x8A85 #CJK UNIFIED IDEOGRAPH
+0xE66F 0x8A82 #CJK UNIFIED IDEOGRAPH
+0xE670 0x8A84 #CJK UNIFIED IDEOGRAPH
+0xE671 0x8AA8 #CJK UNIFIED IDEOGRAPH
+0xE672 0x8AA1 #CJK UNIFIED IDEOGRAPH
+0xE673 0x8A91 #CJK UNIFIED IDEOGRAPH
+0xE674 0x8AA5 #CJK UNIFIED IDEOGRAPH
+0xE675 0x8AA6 #CJK UNIFIED IDEOGRAPH
+0xE676 0x8A9A #CJK UNIFIED IDEOGRAPH
+0xE677 0x8AA3 #CJK UNIFIED IDEOGRAPH
+0xE678 0x8AC4 #CJK UNIFIED IDEOGRAPH
+0xE679 0x8ACD #CJK UNIFIED IDEOGRAPH
+0xE67A 0x8AC2 #CJK UNIFIED IDEOGRAPH
+0xE67B 0x8ADA #CJK UNIFIED IDEOGRAPH
+0xE67C 0x8AEB #CJK UNIFIED IDEOGRAPH
+0xE67D 0x8AF3 #CJK UNIFIED IDEOGRAPH
+0xE67E 0x8AE7 #CJK UNIFIED IDEOGRAPH
+0xE680 0x8AE4 #CJK UNIFIED IDEOGRAPH
+0xE681 0x8AF1 #CJK UNIFIED IDEOGRAPH
+0xE682 0x8B14 #CJK UNIFIED IDEOGRAPH
+0xE683 0x8AE0 #CJK UNIFIED IDEOGRAPH
+0xE684 0x8AE2 #CJK UNIFIED IDEOGRAPH
+0xE685 0x8AF7 #CJK UNIFIED IDEOGRAPH
+0xE686 0x8ADE #CJK UNIFIED IDEOGRAPH
+0xE687 0x8ADB #CJK UNIFIED IDEOGRAPH
+0xE688 0x8B0C #CJK UNIFIED IDEOGRAPH
+0xE689 0x8B07 #CJK UNIFIED IDEOGRAPH
+0xE68A 0x8B1A #CJK UNIFIED IDEOGRAPH
+0xE68B 0x8AE1 #CJK UNIFIED IDEOGRAPH
+0xE68C 0x8B16 #CJK UNIFIED IDEOGRAPH
+0xE68D 0x8B10 #CJK UNIFIED IDEOGRAPH
+0xE68E 0x8B17 #CJK UNIFIED IDEOGRAPH
+0xE68F 0x8B20 #CJK UNIFIED IDEOGRAPH
+0xE690 0x8B33 #CJK UNIFIED IDEOGRAPH
+0xE691 0x97AB #CJK UNIFIED IDEOGRAPH
+0xE692 0x8B26 #CJK UNIFIED IDEOGRAPH
+0xE693 0x8B2B #CJK UNIFIED IDEOGRAPH
+0xE694 0x8B3E #CJK UNIFIED IDEOGRAPH
+0xE695 0x8B28 #CJK UNIFIED IDEOGRAPH
+0xE696 0x8B41 #CJK UNIFIED IDEOGRAPH
+0xE697 0x8B4C #CJK UNIFIED IDEOGRAPH
+0xE698 0x8B4F #CJK UNIFIED IDEOGRAPH
+0xE699 0x8B4E #CJK UNIFIED IDEOGRAPH
+0xE69A 0x8B49 #CJK UNIFIED IDEOGRAPH
+0xE69B 0x8B56 #CJK UNIFIED IDEOGRAPH
+0xE69C 0x8B5B #CJK UNIFIED IDEOGRAPH
+0xE69D 0x8B5A #CJK UNIFIED IDEOGRAPH
+0xE69E 0x8B6B #CJK UNIFIED IDEOGRAPH
+0xE69F 0x8B5F #CJK UNIFIED IDEOGRAPH
+0xE6A0 0x8B6C #CJK UNIFIED IDEOGRAPH
+0xE6A1 0x8B6F #CJK UNIFIED IDEOGRAPH
+0xE6A2 0x8B74 #CJK UNIFIED IDEOGRAPH
+0xE6A3 0x8B7D #CJK UNIFIED IDEOGRAPH
+0xE6A4 0x8B80 #CJK UNIFIED IDEOGRAPH
+0xE6A5 0x8B8C #CJK UNIFIED IDEOGRAPH
+0xE6A6 0x8B8E #CJK UNIFIED IDEOGRAPH
+0xE6A7 0x8B92 #CJK UNIFIED IDEOGRAPH
+0xE6A8 0x8B93 #CJK UNIFIED IDEOGRAPH
+0xE6A9 0x8B96 #CJK UNIFIED IDEOGRAPH
+0xE6AA 0x8B99 #CJK UNIFIED IDEOGRAPH
+0xE6AB 0x8B9A #CJK UNIFIED IDEOGRAPH
+0xE6AC 0x8C3A #CJK UNIFIED IDEOGRAPH
+0xE6AD 0x8C41 #CJK UNIFIED IDEOGRAPH
+0xE6AE 0x8C3F #CJK UNIFIED IDEOGRAPH
+0xE6AF 0x8C48 #CJK UNIFIED IDEOGRAPH
+0xE6B0 0x8C4C #CJK UNIFIED IDEOGRAPH
+0xE6B1 0x8C4E #CJK UNIFIED IDEOGRAPH
+0xE6B2 0x8C50 #CJK UNIFIED IDEOGRAPH
+0xE6B3 0x8C55 #CJK UNIFIED IDEOGRAPH
+0xE6B4 0x8C62 #CJK UNIFIED IDEOGRAPH
+0xE6B5 0x8C6C #CJK UNIFIED IDEOGRAPH
+0xE6B6 0x8C78 #CJK UNIFIED IDEOGRAPH
+0xE6B7 0x8C7A #CJK UNIFIED IDEOGRAPH
+0xE6B8 0x8C82 #CJK UNIFIED IDEOGRAPH
+0xE6B9 0x8C89 #CJK UNIFIED IDEOGRAPH
+0xE6BA 0x8C85 #CJK UNIFIED IDEOGRAPH
+0xE6BB 0x8C8A #CJK UNIFIED IDEOGRAPH
+0xE6BC 0x8C8D #CJK UNIFIED IDEOGRAPH
+0xE6BD 0x8C8E #CJK UNIFIED IDEOGRAPH
+0xE6BE 0x8C94 #CJK UNIFIED IDEOGRAPH
+0xE6BF 0x8C7C #CJK UNIFIED IDEOGRAPH
+0xE6C0 0x8C98 #CJK UNIFIED IDEOGRAPH
+0xE6C1 0x621D #CJK UNIFIED IDEOGRAPH
+0xE6C2 0x8CAD #CJK UNIFIED IDEOGRAPH
+0xE6C3 0x8CAA #CJK UNIFIED IDEOGRAPH
+0xE6C4 0x8CBD #CJK UNIFIED IDEOGRAPH
+0xE6C5 0x8CB2 #CJK UNIFIED IDEOGRAPH
+0xE6C6 0x8CB3 #CJK UNIFIED IDEOGRAPH
+0xE6C7 0x8CAE #CJK UNIFIED IDEOGRAPH
+0xE6C8 0x8CB6 #CJK UNIFIED IDEOGRAPH
+0xE6C9 0x8CC8 #CJK UNIFIED IDEOGRAPH
+0xE6CA 0x8CC1 #CJK UNIFIED IDEOGRAPH
+0xE6CB 0x8CE4 #CJK UNIFIED IDEOGRAPH
+0xE6CC 0x8CE3 #CJK UNIFIED IDEOGRAPH
+0xE6CD 0x8CDA #CJK UNIFIED IDEOGRAPH
+0xE6CE 0x8CFD #CJK UNIFIED IDEOGRAPH
+0xE6CF 0x8CFA #CJK UNIFIED IDEOGRAPH
+0xE6D0 0x8CFB #CJK UNIFIED IDEOGRAPH
+0xE6D1 0x8D04 #CJK UNIFIED IDEOGRAPH
+0xE6D2 0x8D05 #CJK UNIFIED IDEOGRAPH
+0xE6D3 0x8D0A #CJK UNIFIED IDEOGRAPH
+0xE6D4 0x8D07 #CJK UNIFIED IDEOGRAPH
+0xE6D5 0x8D0F #CJK UNIFIED IDEOGRAPH
+0xE6D6 0x8D0D #CJK UNIFIED IDEOGRAPH
+0xE6D7 0x8D10 #CJK UNIFIED IDEOGRAPH
+0xE6D8 0x9F4E #CJK UNIFIED IDEOGRAPH
+0xE6D9 0x8D13 #CJK UNIFIED IDEOGRAPH
+0xE6DA 0x8CCD #CJK UNIFIED IDEOGRAPH
+0xE6DB 0x8D14 #CJK UNIFIED IDEOGRAPH
+0xE6DC 0x8D16 #CJK UNIFIED IDEOGRAPH
+0xE6DD 0x8D67 #CJK UNIFIED IDEOGRAPH
+0xE6DE 0x8D6D #CJK UNIFIED IDEOGRAPH
+0xE6DF 0x8D71 #CJK UNIFIED IDEOGRAPH
+0xE6E0 0x8D73 #CJK UNIFIED IDEOGRAPH
+0xE6E1 0x8D81 #CJK UNIFIED IDEOGRAPH
+0xE6E2 0x8D99 #CJK UNIFIED IDEOGRAPH
+0xE6E3 0x8DC2 #CJK UNIFIED IDEOGRAPH
+0xE6E4 0x8DBE #CJK UNIFIED IDEOGRAPH
+0xE6E5 0x8DBA #CJK UNIFIED IDEOGRAPH
+0xE6E6 0x8DCF #CJK UNIFIED IDEOGRAPH
+0xE6E7 0x8DDA #CJK UNIFIED IDEOGRAPH
+0xE6E8 0x8DD6 #CJK UNIFIED IDEOGRAPH
+0xE6E9 0x8DCC #CJK UNIFIED IDEOGRAPH
+0xE6EA 0x8DDB #CJK UNIFIED IDEOGRAPH
+0xE6EB 0x8DCB #CJK UNIFIED IDEOGRAPH
+0xE6EC 0x8DEA #CJK UNIFIED IDEOGRAPH
+0xE6ED 0x8DEB #CJK UNIFIED IDEOGRAPH
+0xE6EE 0x8DDF #CJK UNIFIED IDEOGRAPH
+0xE6EF 0x8DE3 #CJK UNIFIED IDEOGRAPH
+0xE6F0 0x8DFC #CJK UNIFIED IDEOGRAPH
+0xE6F1 0x8E08 #CJK UNIFIED IDEOGRAPH
+0xE6F2 0x8E09 #CJK UNIFIED IDEOGRAPH
+0xE6F3 0x8DFF #CJK UNIFIED IDEOGRAPH
+0xE6F4 0x8E1D #CJK UNIFIED IDEOGRAPH
+0xE6F5 0x8E1E #CJK UNIFIED IDEOGRAPH
+0xE6F6 0x8E10 #CJK UNIFIED IDEOGRAPH
+0xE6F7 0x8E1F #CJK UNIFIED IDEOGRAPH
+0xE6F8 0x8E42 #CJK UNIFIED IDEOGRAPH
+0xE6F9 0x8E35 #CJK UNIFIED IDEOGRAPH
+0xE6FA 0x8E30 #CJK UNIFIED IDEOGRAPH
+0xE6FB 0x8E34 #CJK UNIFIED IDEOGRAPH
+0xE6FC 0x8E4A #CJK UNIFIED IDEOGRAPH
+0xE740 0x8E47 #CJK UNIFIED IDEOGRAPH
+0xE741 0x8E49 #CJK UNIFIED IDEOGRAPH
+0xE742 0x8E4C #CJK UNIFIED IDEOGRAPH
+0xE743 0x8E50 #CJK UNIFIED IDEOGRAPH
+0xE744 0x8E48 #CJK UNIFIED IDEOGRAPH
+0xE745 0x8E59 #CJK UNIFIED IDEOGRAPH
+0xE746 0x8E64 #CJK UNIFIED IDEOGRAPH
+0xE747 0x8E60 #CJK UNIFIED IDEOGRAPH
+0xE748 0x8E2A #CJK UNIFIED IDEOGRAPH
+0xE749 0x8E63 #CJK UNIFIED IDEOGRAPH
+0xE74A 0x8E55 #CJK UNIFIED IDEOGRAPH
+0xE74B 0x8E76 #CJK UNIFIED IDEOGRAPH
+0xE74C 0x8E72 #CJK UNIFIED IDEOGRAPH
+0xE74D 0x8E7C #CJK UNIFIED IDEOGRAPH
+0xE74E 0x8E81 #CJK UNIFIED IDEOGRAPH
+0xE74F 0x8E87 #CJK UNIFIED IDEOGRAPH
+0xE750 0x8E85 #CJK UNIFIED IDEOGRAPH
+0xE751 0x8E84 #CJK UNIFIED IDEOGRAPH
+0xE752 0x8E8B #CJK UNIFIED IDEOGRAPH
+0xE753 0x8E8A #CJK UNIFIED IDEOGRAPH
+0xE754 0x8E93 #CJK UNIFIED IDEOGRAPH
+0xE755 0x8E91 #CJK UNIFIED IDEOGRAPH
+0xE756 0x8E94 #CJK UNIFIED IDEOGRAPH
+0xE757 0x8E99 #CJK UNIFIED IDEOGRAPH
+0xE758 0x8EAA #CJK UNIFIED IDEOGRAPH
+0xE759 0x8EA1 #CJK UNIFIED IDEOGRAPH
+0xE75A 0x8EAC #CJK UNIFIED IDEOGRAPH
+0xE75B 0x8EB0 #CJK UNIFIED IDEOGRAPH
+0xE75C 0x8EC6 #CJK UNIFIED IDEOGRAPH
+0xE75D 0x8EB1 #CJK UNIFIED IDEOGRAPH
+0xE75E 0x8EBE #CJK UNIFIED IDEOGRAPH
+0xE75F 0x8EC5 #CJK UNIFIED IDEOGRAPH
+0xE760 0x8EC8 #CJK UNIFIED IDEOGRAPH
+0xE761 0x8ECB #CJK UNIFIED IDEOGRAPH
+0xE762 0x8EDB #CJK UNIFIED IDEOGRAPH
+0xE763 0x8EE3 #CJK UNIFIED IDEOGRAPH
+0xE764 0x8EFC #CJK UNIFIED IDEOGRAPH
+0xE765 0x8EFB #CJK UNIFIED IDEOGRAPH
+0xE766 0x8EEB #CJK UNIFIED IDEOGRAPH
+0xE767 0x8EFE #CJK UNIFIED IDEOGRAPH
+0xE768 0x8F0A #CJK UNIFIED IDEOGRAPH
+0xE769 0x8F05 #CJK UNIFIED IDEOGRAPH
+0xE76A 0x8F15 #CJK UNIFIED IDEOGRAPH
+0xE76B 0x8F12 #CJK UNIFIED IDEOGRAPH
+0xE76C 0x8F19 #CJK UNIFIED IDEOGRAPH
+0xE76D 0x8F13 #CJK UNIFIED IDEOGRAPH
+0xE76E 0x8F1C #CJK UNIFIED IDEOGRAPH
+0xE76F 0x8F1F #CJK UNIFIED IDEOGRAPH
+0xE770 0x8F1B #CJK UNIFIED IDEOGRAPH
+0xE771 0x8F0C #CJK UNIFIED IDEOGRAPH
+0xE772 0x8F26 #CJK UNIFIED IDEOGRAPH
+0xE773 0x8F33 #CJK UNIFIED IDEOGRAPH
+0xE774 0x8F3B #CJK UNIFIED IDEOGRAPH
+0xE775 0x8F39 #CJK UNIFIED IDEOGRAPH
+0xE776 0x8F45 #CJK UNIFIED IDEOGRAPH
+0xE777 0x8F42 #CJK UNIFIED IDEOGRAPH
+0xE778 0x8F3E #CJK UNIFIED IDEOGRAPH
+0xE779 0x8F4C #CJK UNIFIED IDEOGRAPH
+0xE77A 0x8F49 #CJK UNIFIED IDEOGRAPH
+0xE77B 0x8F46 #CJK UNIFIED IDEOGRAPH
+0xE77C 0x8F4E #CJK UNIFIED IDEOGRAPH
+0xE77D 0x8F57 #CJK UNIFIED IDEOGRAPH
+0xE77E 0x8F5C #CJK UNIFIED IDEOGRAPH
+0xE780 0x8F62 #CJK UNIFIED IDEOGRAPH
+0xE781 0x8F63 #CJK UNIFIED IDEOGRAPH
+0xE782 0x8F64 #CJK UNIFIED IDEOGRAPH
+0xE783 0x8F9C #CJK UNIFIED IDEOGRAPH
+0xE784 0x8F9F #CJK UNIFIED IDEOGRAPH
+0xE785 0x8FA3 #CJK UNIFIED IDEOGRAPH
+0xE786 0x8FAD #CJK UNIFIED IDEOGRAPH
+0xE787 0x8FAF #CJK UNIFIED IDEOGRAPH
+0xE788 0x8FB7 #CJK UNIFIED IDEOGRAPH
+0xE789 0x8FDA #CJK UNIFIED IDEOGRAPH
+0xE78A 0x8FE5 #CJK UNIFIED IDEOGRAPH
+0xE78B 0x8FE2 #CJK UNIFIED IDEOGRAPH
+0xE78C 0x8FEA #CJK UNIFIED IDEOGRAPH
+0xE78D 0x8FEF #CJK UNIFIED IDEOGRAPH
+0xE78E 0x9087 #CJK UNIFIED IDEOGRAPH
+0xE78F 0x8FF4 #CJK UNIFIED IDEOGRAPH
+0xE790 0x9005 #CJK UNIFIED IDEOGRAPH
+0xE791 0x8FF9 #CJK UNIFIED IDEOGRAPH
+0xE792 0x8FFA #CJK UNIFIED IDEOGRAPH
+0xE793 0x9011 #CJK UNIFIED IDEOGRAPH
+0xE794 0x9015 #CJK UNIFIED IDEOGRAPH
+0xE795 0x9021 #CJK UNIFIED IDEOGRAPH
+0xE796 0x900D #CJK UNIFIED IDEOGRAPH
+0xE797 0x901E #CJK UNIFIED IDEOGRAPH
+0xE798 0x9016 #CJK UNIFIED IDEOGRAPH
+0xE799 0x900B #CJK UNIFIED IDEOGRAPH
+0xE79A 0x9027 #CJK UNIFIED IDEOGRAPH
+0xE79B 0x9036 #CJK UNIFIED IDEOGRAPH
+0xE79C 0x9035 #CJK UNIFIED IDEOGRAPH
+0xE79D 0x9039 #CJK UNIFIED IDEOGRAPH
+0xE79E 0x8FF8 #CJK UNIFIED IDEOGRAPH
+0xE79F 0x904F #CJK UNIFIED IDEOGRAPH
+0xE7A0 0x9050 #CJK UNIFIED IDEOGRAPH
+0xE7A1 0x9051 #CJK UNIFIED IDEOGRAPH
+0xE7A2 0x9052 #CJK UNIFIED IDEOGRAPH
+0xE7A3 0x900E #CJK UNIFIED IDEOGRAPH
+0xE7A4 0x9049 #CJK UNIFIED IDEOGRAPH
+0xE7A5 0x903E #CJK UNIFIED IDEOGRAPH
+0xE7A6 0x9056 #CJK UNIFIED IDEOGRAPH
+0xE7A7 0x9058 #CJK UNIFIED IDEOGRAPH
+0xE7A8 0x905E #CJK UNIFIED IDEOGRAPH
+0xE7A9 0x9068 #CJK UNIFIED IDEOGRAPH
+0xE7AA 0x906F #CJK UNIFIED IDEOGRAPH
+0xE7AB 0x9076 #CJK UNIFIED IDEOGRAPH
+0xE7AC 0x96A8 #CJK UNIFIED IDEOGRAPH
+0xE7AD 0x9072 #CJK UNIFIED IDEOGRAPH
+0xE7AE 0x9082 #CJK UNIFIED IDEOGRAPH
+0xE7AF 0x907D #CJK UNIFIED IDEOGRAPH
+0xE7B0 0x9081 #CJK UNIFIED IDEOGRAPH
+0xE7B1 0x9080 #CJK UNIFIED IDEOGRAPH
+0xE7B2 0x908A #CJK UNIFIED IDEOGRAPH
+0xE7B3 0x9089 #CJK UNIFIED IDEOGRAPH
+0xE7B4 0x908F #CJK UNIFIED IDEOGRAPH
+0xE7B5 0x90A8 #CJK UNIFIED IDEOGRAPH
+0xE7B6 0x90AF #CJK UNIFIED IDEOGRAPH
+0xE7B7 0x90B1 #CJK UNIFIED IDEOGRAPH
+0xE7B8 0x90B5 #CJK UNIFIED IDEOGRAPH
+0xE7B9 0x90E2 #CJK UNIFIED IDEOGRAPH
+0xE7BA 0x90E4 #CJK UNIFIED IDEOGRAPH
+0xE7BB 0x6248 #CJK UNIFIED IDEOGRAPH
+0xE7BC 0x90DB #CJK UNIFIED IDEOGRAPH
+0xE7BD 0x9102 #CJK UNIFIED IDEOGRAPH
+0xE7BE 0x9112 #CJK UNIFIED IDEOGRAPH
+0xE7BF 0x9119 #CJK UNIFIED IDEOGRAPH
+0xE7C0 0x9132 #CJK UNIFIED IDEOGRAPH
+0xE7C1 0x9130 #CJK UNIFIED IDEOGRAPH
+0xE7C2 0x914A #CJK UNIFIED IDEOGRAPH
+0xE7C3 0x9156 #CJK UNIFIED IDEOGRAPH
+0xE7C4 0x9158 #CJK UNIFIED IDEOGRAPH
+0xE7C5 0x9163 #CJK UNIFIED IDEOGRAPH
+0xE7C6 0x9165 #CJK UNIFIED IDEOGRAPH
+0xE7C7 0x9169 #CJK UNIFIED IDEOGRAPH
+0xE7C8 0x9173 #CJK UNIFIED IDEOGRAPH
+0xE7C9 0x9172 #CJK UNIFIED IDEOGRAPH
+0xE7CA 0x918B #CJK UNIFIED IDEOGRAPH
+0xE7CB 0x9189 #CJK UNIFIED IDEOGRAPH
+0xE7CC 0x9182 #CJK UNIFIED IDEOGRAPH
+0xE7CD 0x91A2 #CJK UNIFIED IDEOGRAPH
+0xE7CE 0x91AB #CJK UNIFIED IDEOGRAPH
+0xE7CF 0x91AF #CJK UNIFIED IDEOGRAPH
+0xE7D0 0x91AA #CJK UNIFIED IDEOGRAPH
+0xE7D1 0x91B5 #CJK UNIFIED IDEOGRAPH
+0xE7D2 0x91B4 #CJK UNIFIED IDEOGRAPH
+0xE7D3 0x91BA #CJK UNIFIED IDEOGRAPH
+0xE7D4 0x91C0 #CJK UNIFIED IDEOGRAPH
+0xE7D5 0x91C1 #CJK UNIFIED IDEOGRAPH
+0xE7D6 0x91C9 #CJK UNIFIED IDEOGRAPH
+0xE7D7 0x91CB #CJK UNIFIED IDEOGRAPH
+0xE7D8 0x91D0 #CJK UNIFIED IDEOGRAPH
+0xE7D9 0x91D6 #CJK UNIFIED IDEOGRAPH
+0xE7DA 0x91DF #CJK UNIFIED IDEOGRAPH
+0xE7DB 0x91E1 #CJK UNIFIED IDEOGRAPH
+0xE7DC 0x91DB #CJK UNIFIED IDEOGRAPH
+0xE7DD 0x91FC #CJK UNIFIED IDEOGRAPH
+0xE7DE 0x91F5 #CJK UNIFIED IDEOGRAPH
+0xE7DF 0x91F6 #CJK UNIFIED IDEOGRAPH
+0xE7E0 0x921E #CJK UNIFIED IDEOGRAPH
+0xE7E1 0x91FF #CJK UNIFIED IDEOGRAPH
+0xE7E2 0x9214 #CJK UNIFIED IDEOGRAPH
+0xE7E3 0x922C #CJK UNIFIED IDEOGRAPH
+0xE7E4 0x9215 #CJK UNIFIED IDEOGRAPH
+0xE7E5 0x9211 #CJK UNIFIED IDEOGRAPH
+0xE7E6 0x925E #CJK UNIFIED IDEOGRAPH
+0xE7E7 0x9257 #CJK UNIFIED IDEOGRAPH
+0xE7E8 0x9245 #CJK UNIFIED IDEOGRAPH
+0xE7E9 0x9249 #CJK UNIFIED IDEOGRAPH
+0xE7EA 0x9264 #CJK UNIFIED IDEOGRAPH
+0xE7EB 0x9248 #CJK UNIFIED IDEOGRAPH
+0xE7EC 0x9295 #CJK UNIFIED IDEOGRAPH
+0xE7ED 0x923F #CJK UNIFIED IDEOGRAPH
+0xE7EE 0x924B #CJK UNIFIED IDEOGRAPH
+0xE7EF 0x9250 #CJK UNIFIED IDEOGRAPH
+0xE7F0 0x929C #CJK UNIFIED IDEOGRAPH
+0xE7F1 0x9296 #CJK UNIFIED IDEOGRAPH
+0xE7F2 0x9293 #CJK UNIFIED IDEOGRAPH
+0xE7F3 0x929B #CJK UNIFIED IDEOGRAPH
+0xE7F4 0x925A #CJK UNIFIED IDEOGRAPH
+0xE7F5 0x92CF #CJK UNIFIED IDEOGRAPH
+0xE7F6 0x92B9 #CJK UNIFIED IDEOGRAPH
+0xE7F7 0x92B7 #CJK UNIFIED IDEOGRAPH
+0xE7F8 0x92E9 #CJK UNIFIED IDEOGRAPH
+0xE7F9 0x930F #CJK UNIFIED IDEOGRAPH
+0xE7FA 0x92FA #CJK UNIFIED IDEOGRAPH
+0xE7FB 0x9344 #CJK UNIFIED IDEOGRAPH
+0xE7FC 0x932E #CJK UNIFIED IDEOGRAPH
+0xE840 0x9319 #CJK UNIFIED IDEOGRAPH
+0xE841 0x9322 #CJK UNIFIED IDEOGRAPH
+0xE842 0x931A #CJK UNIFIED IDEOGRAPH
+0xE843 0x9323 #CJK UNIFIED IDEOGRAPH
+0xE844 0x933A #CJK UNIFIED IDEOGRAPH
+0xE845 0x9335 #CJK UNIFIED IDEOGRAPH
+0xE846 0x933B #CJK UNIFIED IDEOGRAPH
+0xE847 0x935C #CJK UNIFIED IDEOGRAPH
+0xE848 0x9360 #CJK UNIFIED IDEOGRAPH
+0xE849 0x937C #CJK UNIFIED IDEOGRAPH
+0xE84A 0x936E #CJK UNIFIED IDEOGRAPH
+0xE84B 0x9356 #CJK UNIFIED IDEOGRAPH
+0xE84C 0x93B0 #CJK UNIFIED IDEOGRAPH
+0xE84D 0x93AC #CJK UNIFIED IDEOGRAPH
+0xE84E 0x93AD #CJK UNIFIED IDEOGRAPH
+0xE84F 0x9394 #CJK UNIFIED IDEOGRAPH
+0xE850 0x93B9 #CJK UNIFIED IDEOGRAPH
+0xE851 0x93D6 #CJK UNIFIED IDEOGRAPH
+0xE852 0x93D7 #CJK UNIFIED IDEOGRAPH
+0xE853 0x93E8 #CJK UNIFIED IDEOGRAPH
+0xE854 0x93E5 #CJK UNIFIED IDEOGRAPH
+0xE855 0x93D8 #CJK UNIFIED IDEOGRAPH
+0xE856 0x93C3 #CJK UNIFIED IDEOGRAPH
+0xE857 0x93DD #CJK UNIFIED IDEOGRAPH
+0xE858 0x93D0 #CJK UNIFIED IDEOGRAPH
+0xE859 0x93C8 #CJK UNIFIED IDEOGRAPH
+0xE85A 0x93E4 #CJK UNIFIED IDEOGRAPH
+0xE85B 0x941A #CJK UNIFIED IDEOGRAPH
+0xE85C 0x9414 #CJK UNIFIED IDEOGRAPH
+0xE85D 0x9413 #CJK UNIFIED IDEOGRAPH
+0xE85E 0x9403 #CJK UNIFIED IDEOGRAPH
+0xE85F 0x9407 #CJK UNIFIED IDEOGRAPH
+0xE860 0x9410 #CJK UNIFIED IDEOGRAPH
+0xE861 0x9436 #CJK UNIFIED IDEOGRAPH
+0xE862 0x942B #CJK UNIFIED IDEOGRAPH
+0xE863 0x9435 #CJK UNIFIED IDEOGRAPH
+0xE864 0x9421 #CJK UNIFIED IDEOGRAPH
+0xE865 0x943A #CJK UNIFIED IDEOGRAPH
+0xE866 0x9441 #CJK UNIFIED IDEOGRAPH
+0xE867 0x9452 #CJK UNIFIED IDEOGRAPH
+0xE868 0x9444 #CJK UNIFIED IDEOGRAPH
+0xE869 0x945B #CJK UNIFIED IDEOGRAPH
+0xE86A 0x9460 #CJK UNIFIED IDEOGRAPH
+0xE86B 0x9462 #CJK UNIFIED IDEOGRAPH
+0xE86C 0x945E #CJK UNIFIED IDEOGRAPH
+0xE86D 0x946A #CJK UNIFIED IDEOGRAPH
+0xE86E 0x9229 #CJK UNIFIED IDEOGRAPH
+0xE86F 0x9470 #CJK UNIFIED IDEOGRAPH
+0xE870 0x9475 #CJK UNIFIED IDEOGRAPH
+0xE871 0x9477 #CJK UNIFIED IDEOGRAPH
+0xE872 0x947D #CJK UNIFIED IDEOGRAPH
+0xE873 0x945A #CJK UNIFIED IDEOGRAPH
+0xE874 0x947C #CJK UNIFIED IDEOGRAPH
+0xE875 0x947E #CJK UNIFIED IDEOGRAPH
+0xE876 0x9481 #CJK UNIFIED IDEOGRAPH
+0xE877 0x947F #CJK UNIFIED IDEOGRAPH
+0xE878 0x9582 #CJK UNIFIED IDEOGRAPH
+0xE879 0x9587 #CJK UNIFIED IDEOGRAPH
+0xE87A 0x958A #CJK UNIFIED IDEOGRAPH
+0xE87B 0x9594 #CJK UNIFIED IDEOGRAPH
+0xE87C 0x9596 #CJK UNIFIED IDEOGRAPH
+0xE87D 0x9598 #CJK UNIFIED IDEOGRAPH
+0xE87E 0x9599 #CJK UNIFIED IDEOGRAPH
+0xE880 0x95A0 #CJK UNIFIED IDEOGRAPH
+0xE881 0x95A8 #CJK UNIFIED IDEOGRAPH
+0xE882 0x95A7 #CJK UNIFIED IDEOGRAPH
+0xE883 0x95AD #CJK UNIFIED IDEOGRAPH
+0xE884 0x95BC #CJK UNIFIED IDEOGRAPH
+0xE885 0x95BB #CJK UNIFIED IDEOGRAPH
+0xE886 0x95B9 #CJK UNIFIED IDEOGRAPH
+0xE887 0x95BE #CJK UNIFIED IDEOGRAPH
+0xE888 0x95CA #CJK UNIFIED IDEOGRAPH
+0xE889 0x6FF6 #CJK UNIFIED IDEOGRAPH
+0xE88A 0x95C3 #CJK UNIFIED IDEOGRAPH
+0xE88B 0x95CD #CJK UNIFIED IDEOGRAPH
+0xE88C 0x95CC #CJK UNIFIED IDEOGRAPH
+0xE88D 0x95D5 #CJK UNIFIED IDEOGRAPH
+0xE88E 0x95D4 #CJK UNIFIED IDEOGRAPH
+0xE88F 0x95D6 #CJK UNIFIED IDEOGRAPH
+0xE890 0x95DC #CJK UNIFIED IDEOGRAPH
+0xE891 0x95E1 #CJK UNIFIED IDEOGRAPH
+0xE892 0x95E5 #CJK UNIFIED IDEOGRAPH
+0xE893 0x95E2 #CJK UNIFIED IDEOGRAPH
+0xE894 0x9621 #CJK UNIFIED IDEOGRAPH
+0xE895 0x9628 #CJK UNIFIED IDEOGRAPH
+0xE896 0x962E #CJK UNIFIED IDEOGRAPH
+0xE897 0x962F #CJK UNIFIED IDEOGRAPH
+0xE898 0x9642 #CJK UNIFIED IDEOGRAPH
+0xE899 0x964C #CJK UNIFIED IDEOGRAPH
+0xE89A 0x964F #CJK UNIFIED IDEOGRAPH
+0xE89B 0x964B #CJK UNIFIED IDEOGRAPH
+0xE89C 0x9677 #CJK UNIFIED IDEOGRAPH
+0xE89D 0x965C #CJK UNIFIED IDEOGRAPH
+0xE89E 0x965E #CJK UNIFIED IDEOGRAPH
+0xE89F 0x965D #CJK UNIFIED IDEOGRAPH
+0xE8A0 0x965F #CJK UNIFIED IDEOGRAPH
+0xE8A1 0x9666 #CJK UNIFIED IDEOGRAPH
+0xE8A2 0x9672 #CJK UNIFIED IDEOGRAPH
+0xE8A3 0x966C #CJK UNIFIED IDEOGRAPH
+0xE8A4 0x968D #CJK UNIFIED IDEOGRAPH
+0xE8A5 0x9698 #CJK UNIFIED IDEOGRAPH
+0xE8A6 0x9695 #CJK UNIFIED IDEOGRAPH
+0xE8A7 0x9697 #CJK UNIFIED IDEOGRAPH
+0xE8A8 0x96AA #CJK UNIFIED IDEOGRAPH
+0xE8A9 0x96A7 #CJK UNIFIED IDEOGRAPH
+0xE8AA 0x96B1 #CJK UNIFIED IDEOGRAPH
+0xE8AB 0x96B2 #CJK UNIFIED IDEOGRAPH
+0xE8AC 0x96B0 #CJK UNIFIED IDEOGRAPH
+0xE8AD 0x96B4 #CJK UNIFIED IDEOGRAPH
+0xE8AE 0x96B6 #CJK UNIFIED IDEOGRAPH
+0xE8AF 0x96B8 #CJK UNIFIED IDEOGRAPH
+0xE8B0 0x96B9 #CJK UNIFIED IDEOGRAPH
+0xE8B1 0x96CE #CJK UNIFIED IDEOGRAPH
+0xE8B2 0x96CB #CJK UNIFIED IDEOGRAPH
+0xE8B3 0x96C9 #CJK UNIFIED IDEOGRAPH
+0xE8B4 0x96CD #CJK UNIFIED IDEOGRAPH
+0xE8B5 0x894D #CJK UNIFIED IDEOGRAPH
+0xE8B6 0x96DC #CJK UNIFIED IDEOGRAPH
+0xE8B7 0x970D #CJK UNIFIED IDEOGRAPH
+0xE8B8 0x96D5 #CJK UNIFIED IDEOGRAPH
+0xE8B9 0x96F9 #CJK UNIFIED IDEOGRAPH
+0xE8BA 0x9704 #CJK UNIFIED IDEOGRAPH
+0xE8BB 0x9706 #CJK UNIFIED IDEOGRAPH
+0xE8BC 0x9708 #CJK UNIFIED IDEOGRAPH
+0xE8BD 0x9713 #CJK UNIFIED IDEOGRAPH
+0xE8BE 0x970E #CJK UNIFIED IDEOGRAPH
+0xE8BF 0x9711 #CJK UNIFIED IDEOGRAPH
+0xE8C0 0x970F #CJK UNIFIED IDEOGRAPH
+0xE8C1 0x9716 #CJK UNIFIED IDEOGRAPH
+0xE8C2 0x9719 #CJK UNIFIED IDEOGRAPH
+0xE8C3 0x9724 #CJK UNIFIED IDEOGRAPH
+0xE8C4 0x972A #CJK UNIFIED IDEOGRAPH
+0xE8C5 0x9730 #CJK UNIFIED IDEOGRAPH
+0xE8C6 0x9739 #CJK UNIFIED IDEOGRAPH
+0xE8C7 0x973D #CJK UNIFIED IDEOGRAPH
+0xE8C8 0x973E #CJK UNIFIED IDEOGRAPH
+0xE8C9 0x9744 #CJK UNIFIED IDEOGRAPH
+0xE8CA 0x9746 #CJK UNIFIED IDEOGRAPH
+0xE8CB 0x9748 #CJK UNIFIED IDEOGRAPH
+0xE8CC 0x9742 #CJK UNIFIED IDEOGRAPH
+0xE8CD 0x9749 #CJK UNIFIED IDEOGRAPH
+0xE8CE 0x975C #CJK UNIFIED IDEOGRAPH
+0xE8CF 0x9760 #CJK UNIFIED IDEOGRAPH
+0xE8D0 0x9764 #CJK UNIFIED IDEOGRAPH
+0xE8D1 0x9766 #CJK UNIFIED IDEOGRAPH
+0xE8D2 0x9768 #CJK UNIFIED IDEOGRAPH
+0xE8D3 0x52D2 #CJK UNIFIED IDEOGRAPH
+0xE8D4 0x976B #CJK UNIFIED IDEOGRAPH
+0xE8D5 0x9771 #CJK UNIFIED IDEOGRAPH
+0xE8D6 0x9779 #CJK UNIFIED IDEOGRAPH
+0xE8D7 0x9785 #CJK UNIFIED IDEOGRAPH
+0xE8D8 0x977C #CJK UNIFIED IDEOGRAPH
+0xE8D9 0x9781 #CJK UNIFIED IDEOGRAPH
+0xE8DA 0x977A #CJK UNIFIED IDEOGRAPH
+0xE8DB 0x9786 #CJK UNIFIED IDEOGRAPH
+0xE8DC 0x978B #CJK UNIFIED IDEOGRAPH
+0xE8DD 0x978F #CJK UNIFIED IDEOGRAPH
+0xE8DE 0x9790 #CJK UNIFIED IDEOGRAPH
+0xE8DF 0x979C #CJK UNIFIED IDEOGRAPH
+0xE8E0 0x97A8 #CJK UNIFIED IDEOGRAPH
+0xE8E1 0x97A6 #CJK UNIFIED IDEOGRAPH
+0xE8E2 0x97A3 #CJK UNIFIED IDEOGRAPH
+0xE8E3 0x97B3 #CJK UNIFIED IDEOGRAPH
+0xE8E4 0x97B4 #CJK UNIFIED IDEOGRAPH
+0xE8E5 0x97C3 #CJK UNIFIED IDEOGRAPH
+0xE8E6 0x97C6 #CJK UNIFIED IDEOGRAPH
+0xE8E7 0x97C8 #CJK UNIFIED IDEOGRAPH
+0xE8E8 0x97CB #CJK UNIFIED IDEOGRAPH
+0xE8E9 0x97DC #CJK UNIFIED IDEOGRAPH
+0xE8EA 0x97ED #CJK UNIFIED IDEOGRAPH
+0xE8EB 0x9F4F #CJK UNIFIED IDEOGRAPH
+0xE8EC 0x97F2 #CJK UNIFIED IDEOGRAPH
+0xE8ED 0x7ADF #CJK UNIFIED IDEOGRAPH
+0xE8EE 0x97F6 #CJK UNIFIED IDEOGRAPH
+0xE8EF 0x97F5 #CJK UNIFIED IDEOGRAPH
+0xE8F0 0x980F #CJK UNIFIED IDEOGRAPH
+0xE8F1 0x980C #CJK UNIFIED IDEOGRAPH
+0xE8F2 0x9838 #CJK UNIFIED IDEOGRAPH
+0xE8F3 0x9824 #CJK UNIFIED IDEOGRAPH
+0xE8F4 0x9821 #CJK UNIFIED IDEOGRAPH
+0xE8F5 0x9837 #CJK UNIFIED IDEOGRAPH
+0xE8F6 0x983D #CJK UNIFIED IDEOGRAPH
+0xE8F7 0x9846 #CJK UNIFIED IDEOGRAPH
+0xE8F8 0x984F #CJK UNIFIED IDEOGRAPH
+0xE8F9 0x984B #CJK UNIFIED IDEOGRAPH
+0xE8FA 0x986B #CJK UNIFIED IDEOGRAPH
+0xE8FB 0x986F #CJK UNIFIED IDEOGRAPH
+0xE8FC 0x9870 #CJK UNIFIED IDEOGRAPH
+0xE940 0x9871 #CJK UNIFIED IDEOGRAPH
+0xE941 0x9874 #CJK UNIFIED IDEOGRAPH
+0xE942 0x9873 #CJK UNIFIED IDEOGRAPH
+0xE943 0x98AA #CJK UNIFIED IDEOGRAPH
+0xE944 0x98AF #CJK UNIFIED IDEOGRAPH
+0xE945 0x98B1 #CJK UNIFIED IDEOGRAPH
+0xE946 0x98B6 #CJK UNIFIED IDEOGRAPH
+0xE947 0x98C4 #CJK UNIFIED IDEOGRAPH
+0xE948 0x98C3 #CJK UNIFIED IDEOGRAPH
+0xE949 0x98C6 #CJK UNIFIED IDEOGRAPH
+0xE94A 0x98E9 #CJK UNIFIED IDEOGRAPH
+0xE94B 0x98EB #CJK UNIFIED IDEOGRAPH
+0xE94C 0x9903 #CJK UNIFIED IDEOGRAPH
+0xE94D 0x9909 #CJK UNIFIED IDEOGRAPH
+0xE94E 0x9912 #CJK UNIFIED IDEOGRAPH
+0xE94F 0x9914 #CJK UNIFIED IDEOGRAPH
+0xE950 0x9918 #CJK UNIFIED IDEOGRAPH
+0xE951 0x9921 #CJK UNIFIED IDEOGRAPH
+0xE952 0x991D #CJK UNIFIED IDEOGRAPH
+0xE953 0x991E #CJK UNIFIED IDEOGRAPH
+0xE954 0x9924 #CJK UNIFIED IDEOGRAPH
+0xE955 0x9920 #CJK UNIFIED IDEOGRAPH
+0xE956 0x992C #CJK UNIFIED IDEOGRAPH
+0xE957 0x992E #CJK UNIFIED IDEOGRAPH
+0xE958 0x993D #CJK UNIFIED IDEOGRAPH
+0xE959 0x993E #CJK UNIFIED IDEOGRAPH
+0xE95A 0x9942 #CJK UNIFIED IDEOGRAPH
+0xE95B 0x9949 #CJK UNIFIED IDEOGRAPH
+0xE95C 0x9945 #CJK UNIFIED IDEOGRAPH
+0xE95D 0x9950 #CJK UNIFIED IDEOGRAPH
+0xE95E 0x994B #CJK UNIFIED IDEOGRAPH
+0xE95F 0x9951 #CJK UNIFIED IDEOGRAPH
+0xE960 0x9952 #CJK UNIFIED IDEOGRAPH
+0xE961 0x994C #CJK UNIFIED IDEOGRAPH
+0xE962 0x9955 #CJK UNIFIED IDEOGRAPH
+0xE963 0x9997 #CJK UNIFIED IDEOGRAPH
+0xE964 0x9998 #CJK UNIFIED IDEOGRAPH
+0xE965 0x99A5 #CJK UNIFIED IDEOGRAPH
+0xE966 0x99AD #CJK UNIFIED IDEOGRAPH
+0xE967 0x99AE #CJK UNIFIED IDEOGRAPH
+0xE968 0x99BC #CJK UNIFIED IDEOGRAPH
+0xE969 0x99DF #CJK UNIFIED IDEOGRAPH
+0xE96A 0x99DB #CJK UNIFIED IDEOGRAPH
+0xE96B 0x99DD #CJK UNIFIED IDEOGRAPH
+0xE96C 0x99D8 #CJK UNIFIED IDEOGRAPH
+0xE96D 0x99D1 #CJK UNIFIED IDEOGRAPH
+0xE96E 0x99ED #CJK UNIFIED IDEOGRAPH
+0xE96F 0x99EE #CJK UNIFIED IDEOGRAPH
+0xE970 0x99F1 #CJK UNIFIED IDEOGRAPH
+0xE971 0x99F2 #CJK UNIFIED IDEOGRAPH
+0xE972 0x99FB #CJK UNIFIED IDEOGRAPH
+0xE973 0x99F8 #CJK UNIFIED IDEOGRAPH
+0xE974 0x9A01 #CJK UNIFIED IDEOGRAPH
+0xE975 0x9A0F #CJK UNIFIED IDEOGRAPH
+0xE976 0x9A05 #CJK UNIFIED IDEOGRAPH
+0xE977 0x99E2 #CJK UNIFIED IDEOGRAPH
+0xE978 0x9A19 #CJK UNIFIED IDEOGRAPH
+0xE979 0x9A2B #CJK UNIFIED IDEOGRAPH
+0xE97A 0x9A37 #CJK UNIFIED IDEOGRAPH
+0xE97B 0x9A45 #CJK UNIFIED IDEOGRAPH
+0xE97C 0x9A42 #CJK UNIFIED IDEOGRAPH
+0xE97D 0x9A40 #CJK UNIFIED IDEOGRAPH
+0xE97E 0x9A43 #CJK UNIFIED IDEOGRAPH
+0xE980 0x9A3E #CJK UNIFIED IDEOGRAPH
+0xE981 0x9A55 #CJK UNIFIED IDEOGRAPH
+0xE982 0x9A4D #CJK UNIFIED IDEOGRAPH
+0xE983 0x9A5B #CJK UNIFIED IDEOGRAPH
+0xE984 0x9A57 #CJK UNIFIED IDEOGRAPH
+0xE985 0x9A5F #CJK UNIFIED IDEOGRAPH
+0xE986 0x9A62 #CJK UNIFIED IDEOGRAPH
+0xE987 0x9A65 #CJK UNIFIED IDEOGRAPH
+0xE988 0x9A64 #CJK UNIFIED IDEOGRAPH
+0xE989 0x9A69 #CJK UNIFIED IDEOGRAPH
+0xE98A 0x9A6B #CJK UNIFIED IDEOGRAPH
+0xE98B 0x9A6A #CJK UNIFIED IDEOGRAPH
+0xE98C 0x9AAD #CJK UNIFIED IDEOGRAPH
+0xE98D 0x9AB0 #CJK UNIFIED IDEOGRAPH
+0xE98E 0x9ABC #CJK UNIFIED IDEOGRAPH
+0xE98F 0x9AC0 #CJK UNIFIED IDEOGRAPH
+0xE990 0x9ACF #CJK UNIFIED IDEOGRAPH
+0xE991 0x9AD1 #CJK UNIFIED IDEOGRAPH
+0xE992 0x9AD3 #CJK UNIFIED IDEOGRAPH
+0xE993 0x9AD4 #CJK UNIFIED IDEOGRAPH
+0xE994 0x9ADE #CJK UNIFIED IDEOGRAPH
+0xE995 0x9ADF #CJK UNIFIED IDEOGRAPH
+0xE996 0x9AE2 #CJK UNIFIED IDEOGRAPH
+0xE997 0x9AE3 #CJK UNIFIED IDEOGRAPH
+0xE998 0x9AE6 #CJK UNIFIED IDEOGRAPH
+0xE999 0x9AEF #CJK UNIFIED IDEOGRAPH
+0xE99A 0x9AEB #CJK UNIFIED IDEOGRAPH
+0xE99B 0x9AEE #CJK UNIFIED IDEOGRAPH
+0xE99C 0x9AF4 #CJK UNIFIED IDEOGRAPH
+0xE99D 0x9AF1 #CJK UNIFIED IDEOGRAPH
+0xE99E 0x9AF7 #CJK UNIFIED IDEOGRAPH
+0xE99F 0x9AFB #CJK UNIFIED IDEOGRAPH
+0xE9A0 0x9B06 #CJK UNIFIED IDEOGRAPH
+0xE9A1 0x9B18 #CJK UNIFIED IDEOGRAPH
+0xE9A2 0x9B1A #CJK UNIFIED IDEOGRAPH
+0xE9A3 0x9B1F #CJK UNIFIED IDEOGRAPH
+0xE9A4 0x9B22 #CJK UNIFIED IDEOGRAPH
+0xE9A5 0x9B23 #CJK UNIFIED IDEOGRAPH
+0xE9A6 0x9B25 #CJK UNIFIED IDEOGRAPH
+0xE9A7 0x9B27 #CJK UNIFIED IDEOGRAPH
+0xE9A8 0x9B28 #CJK UNIFIED IDEOGRAPH
+0xE9A9 0x9B29 #CJK UNIFIED IDEOGRAPH
+0xE9AA 0x9B2A #CJK UNIFIED IDEOGRAPH
+0xE9AB 0x9B2E #CJK UNIFIED IDEOGRAPH
+0xE9AC 0x9B2F #CJK UNIFIED IDEOGRAPH
+0xE9AD 0x9B32 #CJK UNIFIED IDEOGRAPH
+0xE9AE 0x9B44 #CJK UNIFIED IDEOGRAPH
+0xE9AF 0x9B43 #CJK UNIFIED IDEOGRAPH
+0xE9B0 0x9B4F #CJK UNIFIED IDEOGRAPH
+0xE9B1 0x9B4D #CJK UNIFIED IDEOGRAPH
+0xE9B2 0x9B4E #CJK UNIFIED IDEOGRAPH
+0xE9B3 0x9B51 #CJK UNIFIED IDEOGRAPH
+0xE9B4 0x9B58 #CJK UNIFIED IDEOGRAPH
+0xE9B5 0x9B74 #CJK UNIFIED IDEOGRAPH
+0xE9B6 0x9B93 #CJK UNIFIED IDEOGRAPH
+0xE9B7 0x9B83 #CJK UNIFIED IDEOGRAPH
+0xE9B8 0x9B91 #CJK UNIFIED IDEOGRAPH
+0xE9B9 0x9B96 #CJK UNIFIED IDEOGRAPH
+0xE9BA 0x9B97 #CJK UNIFIED IDEOGRAPH
+0xE9BB 0x9B9F #CJK UNIFIED IDEOGRAPH
+0xE9BC 0x9BA0 #CJK UNIFIED IDEOGRAPH
+0xE9BD 0x9BA8 #CJK UNIFIED IDEOGRAPH
+0xE9BE 0x9BB4 #CJK UNIFIED IDEOGRAPH
+0xE9BF 0x9BC0 #CJK UNIFIED IDEOGRAPH
+0xE9C0 0x9BCA #CJK UNIFIED IDEOGRAPH
+0xE9C1 0x9BB9 #CJK UNIFIED IDEOGRAPH
+0xE9C2 0x9BC6 #CJK UNIFIED IDEOGRAPH
+0xE9C3 0x9BCF #CJK UNIFIED IDEOGRAPH
+0xE9C4 0x9BD1 #CJK UNIFIED IDEOGRAPH
+0xE9C5 0x9BD2 #CJK UNIFIED IDEOGRAPH
+0xE9C6 0x9BE3 #CJK UNIFIED IDEOGRAPH
+0xE9C7 0x9BE2 #CJK UNIFIED IDEOGRAPH
+0xE9C8 0x9BE4 #CJK UNIFIED IDEOGRAPH
+0xE9C9 0x9BD4 #CJK UNIFIED IDEOGRAPH
+0xE9CA 0x9BE1 #CJK UNIFIED IDEOGRAPH
+0xE9CB 0x9C3A #CJK UNIFIED IDEOGRAPH
+0xE9CC 0x9BF2 #CJK UNIFIED IDEOGRAPH
+0xE9CD 0x9BF1 #CJK UNIFIED IDEOGRAPH
+0xE9CE 0x9BF0 #CJK UNIFIED IDEOGRAPH
+0xE9CF 0x9C15 #CJK UNIFIED IDEOGRAPH
+0xE9D0 0x9C14 #CJK UNIFIED IDEOGRAPH
+0xE9D1 0x9C09 #CJK UNIFIED IDEOGRAPH
+0xE9D2 0x9C13 #CJK UNIFIED IDEOGRAPH
+0xE9D3 0x9C0C #CJK UNIFIED IDEOGRAPH
+0xE9D4 0x9C06 #CJK UNIFIED IDEOGRAPH
+0xE9D5 0x9C08 #CJK UNIFIED IDEOGRAPH
+0xE9D6 0x9C12 #CJK UNIFIED IDEOGRAPH
+0xE9D7 0x9C0A #CJK UNIFIED IDEOGRAPH
+0xE9D8 0x9C04 #CJK UNIFIED IDEOGRAPH
+0xE9D9 0x9C2E #CJK UNIFIED IDEOGRAPH
+0xE9DA 0x9C1B #CJK UNIFIED IDEOGRAPH
+0xE9DB 0x9C25 #CJK UNIFIED IDEOGRAPH
+0xE9DC 0x9C24 #CJK UNIFIED IDEOGRAPH
+0xE9DD 0x9C21 #CJK UNIFIED IDEOGRAPH
+0xE9DE 0x9C30 #CJK UNIFIED IDEOGRAPH
+0xE9DF 0x9C47 #CJK UNIFIED IDEOGRAPH
+0xE9E0 0x9C32 #CJK UNIFIED IDEOGRAPH
+0xE9E1 0x9C46 #CJK UNIFIED IDEOGRAPH
+0xE9E2 0x9C3E #CJK UNIFIED IDEOGRAPH
+0xE9E3 0x9C5A #CJK UNIFIED IDEOGRAPH
+0xE9E4 0x9C60 #CJK UNIFIED IDEOGRAPH
+0xE9E5 0x9C67 #CJK UNIFIED IDEOGRAPH
+0xE9E6 0x9C76 #CJK UNIFIED IDEOGRAPH
+0xE9E7 0x9C78 #CJK UNIFIED IDEOGRAPH
+0xE9E8 0x9CE7 #CJK UNIFIED IDEOGRAPH
+0xE9E9 0x9CEC #CJK UNIFIED IDEOGRAPH
+0xE9EA 0x9CF0 #CJK UNIFIED IDEOGRAPH
+0xE9EB 0x9D09 #CJK UNIFIED IDEOGRAPH
+0xE9EC 0x9D08 #CJK UNIFIED IDEOGRAPH
+0xE9ED 0x9CEB #CJK UNIFIED IDEOGRAPH
+0xE9EE 0x9D03 #CJK UNIFIED IDEOGRAPH
+0xE9EF 0x9D06 #CJK UNIFIED IDEOGRAPH
+0xE9F0 0x9D2A #CJK UNIFIED IDEOGRAPH
+0xE9F1 0x9D26 #CJK UNIFIED IDEOGRAPH
+0xE9F2 0x9DAF #CJK UNIFIED IDEOGRAPH
+0xE9F3 0x9D23 #CJK UNIFIED IDEOGRAPH
+0xE9F4 0x9D1F #CJK UNIFIED IDEOGRAPH
+0xE9F5 0x9D44 #CJK UNIFIED IDEOGRAPH
+0xE9F6 0x9D15 #CJK UNIFIED IDEOGRAPH
+0xE9F7 0x9D12 #CJK UNIFIED IDEOGRAPH
+0xE9F8 0x9D41 #CJK UNIFIED IDEOGRAPH
+0xE9F9 0x9D3F #CJK UNIFIED IDEOGRAPH
+0xE9FA 0x9D3E #CJK UNIFIED IDEOGRAPH
+0xE9FB 0x9D46 #CJK UNIFIED IDEOGRAPH
+0xE9FC 0x9D48 #CJK UNIFIED IDEOGRAPH
+0xEA40 0x9D5D #CJK UNIFIED IDEOGRAPH
+0xEA41 0x9D5E #CJK UNIFIED IDEOGRAPH
+0xEA42 0x9D64 #CJK UNIFIED IDEOGRAPH
+0xEA43 0x9D51 #CJK UNIFIED IDEOGRAPH
+0xEA44 0x9D50 #CJK UNIFIED IDEOGRAPH
+0xEA45 0x9D59 #CJK UNIFIED IDEOGRAPH
+0xEA46 0x9D72 #CJK UNIFIED IDEOGRAPH
+0xEA47 0x9D89 #CJK UNIFIED IDEOGRAPH
+0xEA48 0x9D87 #CJK UNIFIED IDEOGRAPH
+0xEA49 0x9DAB #CJK UNIFIED IDEOGRAPH
+0xEA4A 0x9D6F #CJK UNIFIED IDEOGRAPH
+0xEA4B 0x9D7A #CJK UNIFIED IDEOGRAPH
+0xEA4C 0x9D9A #CJK UNIFIED IDEOGRAPH
+0xEA4D 0x9DA4 #CJK UNIFIED IDEOGRAPH
+0xEA4E 0x9DA9 #CJK UNIFIED IDEOGRAPH
+0xEA4F 0x9DB2 #CJK UNIFIED IDEOGRAPH
+0xEA50 0x9DC4 #CJK UNIFIED IDEOGRAPH
+0xEA51 0x9DC1 #CJK UNIFIED IDEOGRAPH
+0xEA52 0x9DBB #CJK UNIFIED IDEOGRAPH
+0xEA53 0x9DB8 #CJK UNIFIED IDEOGRAPH
+0xEA54 0x9DBA #CJK UNIFIED IDEOGRAPH
+0xEA55 0x9DC6 #CJK UNIFIED IDEOGRAPH
+0xEA56 0x9DCF #CJK UNIFIED IDEOGRAPH
+0xEA57 0x9DC2 #CJK UNIFIED IDEOGRAPH
+0xEA58 0x9DD9 #CJK UNIFIED IDEOGRAPH
+0xEA59 0x9DD3 #CJK UNIFIED IDEOGRAPH
+0xEA5A 0x9DF8 #CJK UNIFIED IDEOGRAPH
+0xEA5B 0x9DE6 #CJK UNIFIED IDEOGRAPH
+0xEA5C 0x9DED #CJK UNIFIED IDEOGRAPH
+0xEA5D 0x9DEF #CJK UNIFIED IDEOGRAPH
+0xEA5E 0x9DFD #CJK UNIFIED IDEOGRAPH
+0xEA5F 0x9E1A #CJK UNIFIED IDEOGRAPH
+0xEA60 0x9E1B #CJK UNIFIED IDEOGRAPH
+0xEA61 0x9E1E #CJK UNIFIED IDEOGRAPH
+0xEA62 0x9E75 #CJK UNIFIED IDEOGRAPH
+0xEA63 0x9E79 #CJK UNIFIED IDEOGRAPH
+0xEA64 0x9E7D #CJK UNIFIED IDEOGRAPH
+0xEA65 0x9E81 #CJK UNIFIED IDEOGRAPH
+0xEA66 0x9E88 #CJK UNIFIED IDEOGRAPH
+0xEA67 0x9E8B #CJK UNIFIED IDEOGRAPH
+0xEA68 0x9E8C #CJK UNIFIED IDEOGRAPH
+0xEA69 0x9E92 #CJK UNIFIED IDEOGRAPH
+0xEA6A 0x9E95 #CJK UNIFIED IDEOGRAPH
+0xEA6B 0x9E91 #CJK UNIFIED IDEOGRAPH
+0xEA6C 0x9E9D #CJK UNIFIED IDEOGRAPH
+0xEA6D 0x9EA5 #CJK UNIFIED IDEOGRAPH
+0xEA6E 0x9EA9 #CJK UNIFIED IDEOGRAPH
+0xEA6F 0x9EB8 #CJK UNIFIED IDEOGRAPH
+0xEA70 0x9EAA #CJK UNIFIED IDEOGRAPH
+0xEA71 0x9EAD #CJK UNIFIED IDEOGRAPH
+0xEA72 0x9761 #CJK UNIFIED IDEOGRAPH
+0xEA73 0x9ECC #CJK UNIFIED IDEOGRAPH
+0xEA74 0x9ECE #CJK UNIFIED IDEOGRAPH
+0xEA75 0x9ECF #CJK UNIFIED IDEOGRAPH
+0xEA76 0x9ED0 #CJK UNIFIED IDEOGRAPH
+0xEA77 0x9ED4 #CJK UNIFIED IDEOGRAPH
+0xEA78 0x9EDC #CJK UNIFIED IDEOGRAPH
+0xEA79 0x9EDE #CJK UNIFIED IDEOGRAPH
+0xEA7A 0x9EDD #CJK UNIFIED IDEOGRAPH
+0xEA7B 0x9EE0 #CJK UNIFIED IDEOGRAPH
+0xEA7C 0x9EE5 #CJK UNIFIED IDEOGRAPH
+0xEA7D 0x9EE8 #CJK UNIFIED IDEOGRAPH
+0xEA7E 0x9EEF #CJK UNIFIED IDEOGRAPH
+0xEA80 0x9EF4 #CJK UNIFIED IDEOGRAPH
+0xEA81 0x9EF6 #CJK UNIFIED IDEOGRAPH
+0xEA82 0x9EF7 #CJK UNIFIED IDEOGRAPH
+0xEA83 0x9EF9 #CJK UNIFIED IDEOGRAPH
+0xEA84 0x9EFB #CJK UNIFIED IDEOGRAPH
+0xEA85 0x9EFC #CJK UNIFIED IDEOGRAPH
+0xEA86 0x9EFD #CJK UNIFIED IDEOGRAPH
+0xEA87 0x9F07 #CJK UNIFIED IDEOGRAPH
+0xEA88 0x9F08 #CJK UNIFIED IDEOGRAPH
+0xEA89 0x76B7 #CJK UNIFIED IDEOGRAPH
+0xEA8A 0x9F15 #CJK UNIFIED IDEOGRAPH
+0xEA8B 0x9F21 #CJK UNIFIED IDEOGRAPH
+0xEA8C 0x9F2C #CJK UNIFIED IDEOGRAPH
+0xEA8D 0x9F3E #CJK UNIFIED IDEOGRAPH
+0xEA8E 0x9F4A #CJK UNIFIED IDEOGRAPH
+0xEA8F 0x9F52 #CJK UNIFIED IDEOGRAPH
+0xEA90 0x9F54 #CJK UNIFIED IDEOGRAPH
+0xEA91 0x9F63 #CJK UNIFIED IDEOGRAPH
+0xEA92 0x9F5F #CJK UNIFIED IDEOGRAPH
+0xEA93 0x9F60 #CJK UNIFIED IDEOGRAPH
+0xEA94 0x9F61 #CJK UNIFIED IDEOGRAPH
+0xEA95 0x9F66 #CJK UNIFIED IDEOGRAPH
+0xEA96 0x9F67 #CJK UNIFIED IDEOGRAPH
+0xEA97 0x9F6C #CJK UNIFIED IDEOGRAPH
+0xEA98 0x9F6A #CJK UNIFIED IDEOGRAPH
+0xEA99 0x9F77 #CJK UNIFIED IDEOGRAPH
+0xEA9A 0x9F72 #CJK UNIFIED IDEOGRAPH
+0xEA9B 0x9F76 #CJK UNIFIED IDEOGRAPH
+0xEA9C 0x9F95 #CJK UNIFIED IDEOGRAPH
+0xEA9D 0x9F9C #CJK UNIFIED IDEOGRAPH
+0xEA9E 0x9FA0 #CJK UNIFIED IDEOGRAPH
+0xEA9F 0x582F #CJK UNIFIED IDEOGRAPH
+0xEAA0 0x69C7 #CJK UNIFIED IDEOGRAPH
+0xEAA1 0x9059 #CJK UNIFIED IDEOGRAPH
+0xEAA2 0x7464 #CJK UNIFIED IDEOGRAPH
+0xEAA3 0x51DC #CJK UNIFIED IDEOGRAPH
+0xEAA4 0x7199 #CJK UNIFIED IDEOGRAPH
+0xED40 0x7E8A #CJK UNIFIED IDEOGRAPH
+0xED41 0x891C #CJK UNIFIED IDEOGRAPH
+0xED42 0x9348 #CJK UNIFIED IDEOGRAPH
+0xED43 0x9288 #CJK UNIFIED IDEOGRAPH
+0xED44 0x84DC #CJK UNIFIED IDEOGRAPH
+0xED45 0x4FC9 #CJK UNIFIED IDEOGRAPH
+0xED46 0x70BB #CJK UNIFIED IDEOGRAPH
+0xED47 0x6631 #CJK UNIFIED IDEOGRAPH
+0xED48 0x68C8 #CJK UNIFIED IDEOGRAPH
+0xED49 0x92F9 #CJK UNIFIED IDEOGRAPH
+0xED4A 0x66FB #CJK UNIFIED IDEOGRAPH
+0xED4B 0x5F45 #CJK UNIFIED IDEOGRAPH
+0xED4C 0x4E28 #CJK UNIFIED IDEOGRAPH
+0xED4D 0x4EE1 #CJK UNIFIED IDEOGRAPH
+0xED4E 0x4EFC #CJK UNIFIED IDEOGRAPH
+0xED4F 0x4F00 #CJK UNIFIED IDEOGRAPH
+0xED50 0x4F03 #CJK UNIFIED IDEOGRAPH
+0xED51 0x4F39 #CJK UNIFIED IDEOGRAPH
+0xED52 0x4F56 #CJK UNIFIED IDEOGRAPH
+0xED53 0x4F92 #CJK UNIFIED IDEOGRAPH
+0xED54 0x4F8A #CJK UNIFIED IDEOGRAPH
+0xED55 0x4F9A #CJK UNIFIED IDEOGRAPH
+0xED56 0x4F94 #CJK UNIFIED IDEOGRAPH
+0xED57 0x4FCD #CJK UNIFIED IDEOGRAPH
+0xED58 0x5040 #CJK UNIFIED IDEOGRAPH
+0xED59 0x5022 #CJK UNIFIED IDEOGRAPH
+0xED5A 0x4FFF #CJK UNIFIED IDEOGRAPH
+0xED5B 0x501E #CJK UNIFIED IDEOGRAPH
+0xED5C 0x5046 #CJK UNIFIED IDEOGRAPH
+0xED5D 0x5070 #CJK UNIFIED IDEOGRAPH
+0xED5E 0x5042 #CJK UNIFIED IDEOGRAPH
+0xED5F 0x5094 #CJK UNIFIED IDEOGRAPH
+0xED60 0x50F4 #CJK UNIFIED IDEOGRAPH
+0xED61 0x50D8 #CJK UNIFIED IDEOGRAPH
+0xED62 0x514A #CJK UNIFIED IDEOGRAPH
+0xED63 0x5164 #CJK UNIFIED IDEOGRAPH
+0xED64 0x519D #CJK UNIFIED IDEOGRAPH
+0xED65 0x51BE #CJK UNIFIED IDEOGRAPH
+0xED66 0x51EC #CJK UNIFIED IDEOGRAPH
+0xED67 0x5215 #CJK UNIFIED IDEOGRAPH
+0xED68 0x529C #CJK UNIFIED IDEOGRAPH
+0xED69 0x52A6 #CJK UNIFIED IDEOGRAPH
+0xED6A 0x52C0 #CJK UNIFIED IDEOGRAPH
+0xED6B 0x52DB #CJK UNIFIED IDEOGRAPH
+0xED6C 0x5300 #CJK UNIFIED IDEOGRAPH
+0xED6D 0x5307 #CJK UNIFIED IDEOGRAPH
+0xED6E 0x5324 #CJK UNIFIED IDEOGRAPH
+0xED6F 0x5372 #CJK UNIFIED IDEOGRAPH
+0xED70 0x5393 #CJK UNIFIED IDEOGRAPH
+0xED71 0x53B2 #CJK UNIFIED IDEOGRAPH
+0xED72 0x53DD #CJK UNIFIED IDEOGRAPH
+0xED73 0xFA0E #CJK COMPATIBILITY IDEOGRAPH
+0xED74 0x549C #CJK UNIFIED IDEOGRAPH
+0xED75 0x548A #CJK UNIFIED IDEOGRAPH
+0xED76 0x54A9 #CJK UNIFIED IDEOGRAPH
+0xED77 0x54FF #CJK UNIFIED IDEOGRAPH
+0xED78 0x5586 #CJK UNIFIED IDEOGRAPH
+0xED79 0x5759 #CJK UNIFIED IDEOGRAPH
+0xED7A 0x5765 #CJK UNIFIED IDEOGRAPH
+0xED7B 0x57AC #CJK UNIFIED IDEOGRAPH
+0xED7C 0x57C8 #CJK UNIFIED IDEOGRAPH
+0xED7D 0x57C7 #CJK UNIFIED IDEOGRAPH
+0xED7E 0xFA0F #CJK COMPATIBILITY IDEOGRAPH
+0xED80 0xFA10 #CJK COMPATIBILITY IDEOGRAPH
+0xED81 0x589E #CJK UNIFIED IDEOGRAPH
+0xED82 0x58B2 #CJK UNIFIED IDEOGRAPH
+0xED83 0x590B #CJK UNIFIED IDEOGRAPH
+0xED84 0x5953 #CJK UNIFIED IDEOGRAPH
+0xED85 0x595B #CJK UNIFIED IDEOGRAPH
+0xED86 0x595D #CJK UNIFIED IDEOGRAPH
+0xED87 0x5963 #CJK UNIFIED IDEOGRAPH
+0xED88 0x59A4 #CJK UNIFIED IDEOGRAPH
+0xED89 0x59BA #CJK UNIFIED IDEOGRAPH
+0xED8A 0x5B56 #CJK UNIFIED IDEOGRAPH
+0xED8B 0x5BC0 #CJK UNIFIED IDEOGRAPH
+0xED8C 0x752F #CJK UNIFIED IDEOGRAPH
+0xED8D 0x5BD8 #CJK UNIFIED IDEOGRAPH
+0xED8E 0x5BEC #CJK UNIFIED IDEOGRAPH
+0xED8F 0x5C1E #CJK UNIFIED IDEOGRAPH
+0xED90 0x5CA6 #CJK UNIFIED IDEOGRAPH
+0xED91 0x5CBA #CJK UNIFIED IDEOGRAPH
+0xED92 0x5CF5 #CJK UNIFIED IDEOGRAPH
+0xED93 0x5D27 #CJK UNIFIED IDEOGRAPH
+0xED94 0x5D53 #CJK UNIFIED IDEOGRAPH
+0xED95 0xFA11 #CJK COMPATIBILITY IDEOGRAPH
+0xED96 0x5D42 #CJK UNIFIED IDEOGRAPH
+0xED97 0x5D6D #CJK UNIFIED IDEOGRAPH
+0xED98 0x5DB8 #CJK UNIFIED IDEOGRAPH
+0xED99 0x5DB9 #CJK UNIFIED IDEOGRAPH
+0xED9A 0x5DD0 #CJK UNIFIED IDEOGRAPH
+0xED9B 0x5F21 #CJK UNIFIED IDEOGRAPH
+0xED9C 0x5F34 #CJK UNIFIED IDEOGRAPH
+0xED9D 0x5F67 #CJK UNIFIED IDEOGRAPH
+0xED9E 0x5FB7 #CJK UNIFIED IDEOGRAPH
+0xED9F 0x5FDE #CJK UNIFIED IDEOGRAPH
+0xEDA0 0x605D #CJK UNIFIED IDEOGRAPH
+0xEDA1 0x6085 #CJK UNIFIED IDEOGRAPH
+0xEDA2 0x608A #CJK UNIFIED IDEOGRAPH
+0xEDA3 0x60DE #CJK UNIFIED IDEOGRAPH
+0xEDA4 0x60D5 #CJK UNIFIED IDEOGRAPH
+0xEDA5 0x6120 #CJK UNIFIED IDEOGRAPH
+0xEDA6 0x60F2 #CJK UNIFIED IDEOGRAPH
+0xEDA7 0x6111 #CJK UNIFIED IDEOGRAPH
+0xEDA8 0x6137 #CJK UNIFIED IDEOGRAPH
+0xEDA9 0x6130 #CJK UNIFIED IDEOGRAPH
+0xEDAA 0x6198 #CJK UNIFIED IDEOGRAPH
+0xEDAB 0x6213 #CJK UNIFIED IDEOGRAPH
+0xEDAC 0x62A6 #CJK UNIFIED IDEOGRAPH
+0xEDAD 0x63F5 #CJK UNIFIED IDEOGRAPH
+0xEDAE 0x6460 #CJK UNIFIED IDEOGRAPH
+0xEDAF 0x649D #CJK UNIFIED IDEOGRAPH
+0xEDB0 0x64CE #CJK UNIFIED IDEOGRAPH
+0xEDB1 0x654E #CJK UNIFIED IDEOGRAPH
+0xEDB2 0x6600 #CJK UNIFIED IDEOGRAPH
+0xEDB3 0x6615 #CJK UNIFIED IDEOGRAPH
+0xEDB4 0x663B #CJK UNIFIED IDEOGRAPH
+0xEDB5 0x6609 #CJK UNIFIED IDEOGRAPH
+0xEDB6 0x662E #CJK UNIFIED IDEOGRAPH
+0xEDB7 0x661E #CJK UNIFIED IDEOGRAPH
+0xEDB8 0x6624 #CJK UNIFIED IDEOGRAPH
+0xEDB9 0x6665 #CJK UNIFIED IDEOGRAPH
+0xEDBA 0x6657 #CJK UNIFIED IDEOGRAPH
+0xEDBB 0x6659 #CJK UNIFIED IDEOGRAPH
+0xEDBC 0xFA12 #CJK COMPATIBILITY IDEOGRAPH
+0xEDBD 0x6673 #CJK UNIFIED IDEOGRAPH
+0xEDBE 0x6699 #CJK UNIFIED IDEOGRAPH
+0xEDBF 0x66A0 #CJK UNIFIED IDEOGRAPH
+0xEDC0 0x66B2 #CJK UNIFIED IDEOGRAPH
+0xEDC1 0x66BF #CJK UNIFIED IDEOGRAPH
+0xEDC2 0x66FA #CJK UNIFIED IDEOGRAPH
+0xEDC3 0x670E #CJK UNIFIED IDEOGRAPH
+0xEDC4 0xF929 #CJK COMPATIBILITY IDEOGRAPH
+0xEDC5 0x6766 #CJK UNIFIED IDEOGRAPH
+0xEDC6 0x67BB #CJK UNIFIED IDEOGRAPH
+0xEDC7 0x6852 #CJK UNIFIED IDEOGRAPH
+0xEDC8 0x67C0 #CJK UNIFIED IDEOGRAPH
+0xEDC9 0x6801 #CJK UNIFIED IDEOGRAPH
+0xEDCA 0x6844 #CJK UNIFIED IDEOGRAPH
+0xEDCB 0x68CF #CJK UNIFIED IDEOGRAPH
+0xEDCC 0xFA13 #CJK COMPATIBILITY IDEOGRAPH
+0xEDCD 0x6968 #CJK UNIFIED IDEOGRAPH
+0xEDCE 0xFA14 #CJK COMPATIBILITY IDEOGRAPH
+0xEDCF 0x6998 #CJK UNIFIED IDEOGRAPH
+0xEDD0 0x69E2 #CJK UNIFIED IDEOGRAPH
+0xEDD1 0x6A30 #CJK UNIFIED IDEOGRAPH
+0xEDD2 0x6A6B #CJK UNIFIED IDEOGRAPH
+0xEDD3 0x6A46 #CJK UNIFIED IDEOGRAPH
+0xEDD4 0x6A73 #CJK UNIFIED IDEOGRAPH
+0xEDD5 0x6A7E #CJK UNIFIED IDEOGRAPH
+0xEDD6 0x6AE2 #CJK UNIFIED IDEOGRAPH
+0xEDD7 0x6AE4 #CJK UNIFIED IDEOGRAPH
+0xEDD8 0x6BD6 #CJK UNIFIED IDEOGRAPH
+0xEDD9 0x6C3F #CJK UNIFIED IDEOGRAPH
+0xEDDA 0x6C5C #CJK UNIFIED IDEOGRAPH
+0xEDDB 0x6C86 #CJK UNIFIED IDEOGRAPH
+0xEDDC 0x6C6F #CJK UNIFIED IDEOGRAPH
+0xEDDD 0x6CDA #CJK UNIFIED IDEOGRAPH
+0xEDDE 0x6D04 #CJK UNIFIED IDEOGRAPH
+0xEDDF 0x6D87 #CJK UNIFIED IDEOGRAPH
+0xEDE0 0x6D6F #CJK UNIFIED IDEOGRAPH
+0xEDE1 0x6D96 #CJK UNIFIED IDEOGRAPH
+0xEDE2 0x6DAC #CJK UNIFIED IDEOGRAPH
+0xEDE3 0x6DCF #CJK UNIFIED IDEOGRAPH
+0xEDE4 0x6DF8 #CJK UNIFIED IDEOGRAPH
+0xEDE5 0x6DF2 #CJK UNIFIED IDEOGRAPH
+0xEDE6 0x6DFC #CJK UNIFIED IDEOGRAPH
+0xEDE7 0x6E39 #CJK UNIFIED IDEOGRAPH
+0xEDE8 0x6E5C #CJK UNIFIED IDEOGRAPH
+0xEDE9 0x6E27 #CJK UNIFIED IDEOGRAPH
+0xEDEA 0x6E3C #CJK UNIFIED IDEOGRAPH
+0xEDEB 0x6EBF #CJK UNIFIED IDEOGRAPH
+0xEDEC 0x6F88 #CJK UNIFIED IDEOGRAPH
+0xEDED 0x6FB5 #CJK UNIFIED IDEOGRAPH
+0xEDEE 0x6FF5 #CJK UNIFIED IDEOGRAPH
+0xEDEF 0x7005 #CJK UNIFIED IDEOGRAPH
+0xEDF0 0x7007 #CJK UNIFIED IDEOGRAPH
+0xEDF1 0x7028 #CJK UNIFIED IDEOGRAPH
+0xEDF2 0x7085 #CJK UNIFIED IDEOGRAPH
+0xEDF3 0x70AB #CJK UNIFIED IDEOGRAPH
+0xEDF4 0x710F #CJK UNIFIED IDEOGRAPH
+0xEDF5 0x7104 #CJK UNIFIED IDEOGRAPH
+0xEDF6 0x715C #CJK UNIFIED IDEOGRAPH
+0xEDF7 0x7146 #CJK UNIFIED IDEOGRAPH
+0xEDF8 0x7147 #CJK UNIFIED IDEOGRAPH
+0xEDF9 0xFA15 #CJK COMPATIBILITY IDEOGRAPH
+0xEDFA 0x71C1 #CJK UNIFIED IDEOGRAPH
+0xEDFB 0x71FE #CJK UNIFIED IDEOGRAPH
+0xEDFC 0x72B1 #CJK UNIFIED IDEOGRAPH
+0xEE40 0x72BE #CJK UNIFIED IDEOGRAPH
+0xEE41 0x7324 #CJK UNIFIED IDEOGRAPH
+0xEE42 0xFA16 #CJK COMPATIBILITY IDEOGRAPH
+0xEE43 0x7377 #CJK UNIFIED IDEOGRAPH
+0xEE44 0x73BD #CJK UNIFIED IDEOGRAPH
+0xEE45 0x73C9 #CJK UNIFIED IDEOGRAPH
+0xEE46 0x73D6 #CJK UNIFIED IDEOGRAPH
+0xEE47 0x73E3 #CJK UNIFIED IDEOGRAPH
+0xEE48 0x73D2 #CJK UNIFIED IDEOGRAPH
+0xEE49 0x7407 #CJK UNIFIED IDEOGRAPH
+0xEE4A 0x73F5 #CJK UNIFIED IDEOGRAPH
+0xEE4B 0x7426 #CJK UNIFIED IDEOGRAPH
+0xEE4C 0x742A #CJK UNIFIED IDEOGRAPH
+0xEE4D 0x7429 #CJK UNIFIED IDEOGRAPH
+0xEE4E 0x742E #CJK UNIFIED IDEOGRAPH
+0xEE4F 0x7462 #CJK UNIFIED IDEOGRAPH
+0xEE50 0x7489 #CJK UNIFIED IDEOGRAPH
+0xEE51 0x749F #CJK UNIFIED IDEOGRAPH
+0xEE52 0x7501 #CJK UNIFIED IDEOGRAPH
+0xEE53 0x756F #CJK UNIFIED IDEOGRAPH
+0xEE54 0x7682 #CJK UNIFIED IDEOGRAPH
+0xEE55 0x769C #CJK UNIFIED IDEOGRAPH
+0xEE56 0x769E #CJK UNIFIED IDEOGRAPH
+0xEE57 0x769B #CJK UNIFIED IDEOGRAPH
+0xEE58 0x76A6 #CJK UNIFIED IDEOGRAPH
+0xEE59 0xFA17 #CJK COMPATIBILITY IDEOGRAPH
+0xEE5A 0x7746 #CJK UNIFIED IDEOGRAPH
+0xEE5B 0x52AF #CJK UNIFIED IDEOGRAPH
+0xEE5C 0x7821 #CJK UNIFIED IDEOGRAPH
+0xEE5D 0x784E #CJK UNIFIED IDEOGRAPH
+0xEE5E 0x7864 #CJK UNIFIED IDEOGRAPH
+0xEE5F 0x787A #CJK UNIFIED IDEOGRAPH
+0xEE60 0x7930 #CJK UNIFIED IDEOGRAPH
+0xEE61 0xFA18 #CJK COMPATIBILITY IDEOGRAPH
+0xEE62 0xFA19 #CJK COMPATIBILITY IDEOGRAPH
+0xEE63 0xFA1A #CJK COMPATIBILITY IDEOGRAPH
+0xEE64 0x7994 #CJK UNIFIED IDEOGRAPH
+0xEE65 0xFA1B #CJK COMPATIBILITY IDEOGRAPH
+0xEE66 0x799B #CJK UNIFIED IDEOGRAPH
+0xEE67 0x7AD1 #CJK UNIFIED IDEOGRAPH
+0xEE68 0x7AE7 #CJK UNIFIED IDEOGRAPH
+0xEE69 0xFA1C #CJK COMPATIBILITY IDEOGRAPH
+0xEE6A 0x7AEB #CJK UNIFIED IDEOGRAPH
+0xEE6B 0x7B9E #CJK UNIFIED IDEOGRAPH
+0xEE6C 0xFA1D #CJK COMPATIBILITY IDEOGRAPH
+0xEE6D 0x7D48 #CJK UNIFIED IDEOGRAPH
+0xEE6E 0x7D5C #CJK UNIFIED IDEOGRAPH
+0xEE6F 0x7DB7 #CJK UNIFIED IDEOGRAPH
+0xEE70 0x7DA0 #CJK UNIFIED IDEOGRAPH
+0xEE71 0x7DD6 #CJK UNIFIED IDEOGRAPH
+0xEE72 0x7E52 #CJK UNIFIED IDEOGRAPH
+0xEE73 0x7F47 #CJK UNIFIED IDEOGRAPH
+0xEE74 0x7FA1 #CJK UNIFIED IDEOGRAPH
+0xEE75 0xFA1E #CJK COMPATIBILITY IDEOGRAPH
+0xEE76 0x8301 #CJK UNIFIED IDEOGRAPH
+0xEE77 0x8362 #CJK UNIFIED IDEOGRAPH
+0xEE78 0x837F #CJK UNIFIED IDEOGRAPH
+0xEE79 0x83C7 #CJK UNIFIED IDEOGRAPH
+0xEE7A 0x83F6 #CJK UNIFIED IDEOGRAPH
+0xEE7B 0x8448 #CJK UNIFIED IDEOGRAPH
+0xEE7C 0x84B4 #CJK UNIFIED IDEOGRAPH
+0xEE7D 0x8553 #CJK UNIFIED IDEOGRAPH
+0xEE7E 0x8559 #CJK UNIFIED IDEOGRAPH
+0xEE80 0x856B #CJK UNIFIED IDEOGRAPH
+0xEE81 0xFA1F #CJK COMPATIBILITY IDEOGRAPH
+0xEE82 0x85B0 #CJK UNIFIED IDEOGRAPH
+0xEE83 0xFA20 #CJK COMPATIBILITY IDEOGRAPH
+0xEE84 0xFA21 #CJK COMPATIBILITY IDEOGRAPH
+0xEE85 0x8807 #CJK UNIFIED IDEOGRAPH
+0xEE86 0x88F5 #CJK UNIFIED IDEOGRAPH
+0xEE87 0x8A12 #CJK UNIFIED IDEOGRAPH
+0xEE88 0x8A37 #CJK UNIFIED IDEOGRAPH
+0xEE89 0x8A79 #CJK UNIFIED IDEOGRAPH
+0xEE8A 0x8AA7 #CJK UNIFIED IDEOGRAPH
+0xEE8B 0x8ABE #CJK UNIFIED IDEOGRAPH
+0xEE8C 0x8ADF #CJK UNIFIED IDEOGRAPH
+0xEE8D 0xFA22 #CJK COMPATIBILITY IDEOGRAPH
+0xEE8E 0x8AF6 #CJK UNIFIED IDEOGRAPH
+0xEE8F 0x8B53 #CJK UNIFIED IDEOGRAPH
+0xEE90 0x8B7F #CJK UNIFIED IDEOGRAPH
+0xEE91 0x8CF0 #CJK UNIFIED IDEOGRAPH
+0xEE92 0x8CF4 #CJK UNIFIED IDEOGRAPH
+0xEE93 0x8D12 #CJK UNIFIED IDEOGRAPH
+0xEE94 0x8D76 #CJK UNIFIED IDEOGRAPH
+0xEE95 0xFA23 #CJK COMPATIBILITY IDEOGRAPH
+0xEE96 0x8ECF #CJK UNIFIED IDEOGRAPH
+0xEE97 0xFA24 #CJK COMPATIBILITY IDEOGRAPH
+0xEE98 0xFA25 #CJK COMPATIBILITY IDEOGRAPH
+0xEE99 0x9067 #CJK UNIFIED IDEOGRAPH
+0xEE9A 0x90DE #CJK UNIFIED IDEOGRAPH
+0xEE9B 0xFA26 #CJK COMPATIBILITY IDEOGRAPH
+0xEE9C 0x9115 #CJK UNIFIED IDEOGRAPH
+0xEE9D 0x9127 #CJK UNIFIED IDEOGRAPH
+0xEE9E 0x91DA #CJK UNIFIED IDEOGRAPH
+0xEE9F 0x91D7 #CJK UNIFIED IDEOGRAPH
+0xEEA0 0x91DE #CJK UNIFIED IDEOGRAPH
+0xEEA1 0x91ED #CJK UNIFIED IDEOGRAPH
+0xEEA2 0x91EE #CJK UNIFIED IDEOGRAPH
+0xEEA3 0x91E4 #CJK UNIFIED IDEOGRAPH
+0xEEA4 0x91E5 #CJK UNIFIED IDEOGRAPH
+0xEEA5 0x9206 #CJK UNIFIED IDEOGRAPH
+0xEEA6 0x9210 #CJK UNIFIED IDEOGRAPH
+0xEEA7 0x920A #CJK UNIFIED IDEOGRAPH
+0xEEA8 0x923A #CJK UNIFIED IDEOGRAPH
+0xEEA9 0x9240 #CJK UNIFIED IDEOGRAPH
+0xEEAA 0x923C #CJK UNIFIED IDEOGRAPH
+0xEEAB 0x924E #CJK UNIFIED IDEOGRAPH
+0xEEAC 0x9259 #CJK UNIFIED IDEOGRAPH
+0xEEAD 0x9251 #CJK UNIFIED IDEOGRAPH
+0xEEAE 0x9239 #CJK UNIFIED IDEOGRAPH
+0xEEAF 0x9267 #CJK UNIFIED IDEOGRAPH
+0xEEB0 0x92A7 #CJK UNIFIED IDEOGRAPH
+0xEEB1 0x9277 #CJK UNIFIED IDEOGRAPH
+0xEEB2 0x9278 #CJK UNIFIED IDEOGRAPH
+0xEEB3 0x92E7 #CJK UNIFIED IDEOGRAPH
+0xEEB4 0x92D7 #CJK UNIFIED IDEOGRAPH
+0xEEB5 0x92D9 #CJK UNIFIED IDEOGRAPH
+0xEEB6 0x92D0 #CJK UNIFIED IDEOGRAPH
+0xEEB7 0xFA27 #CJK COMPATIBILITY IDEOGRAPH
+0xEEB8 0x92D5 #CJK UNIFIED IDEOGRAPH
+0xEEB9 0x92E0 #CJK UNIFIED IDEOGRAPH
+0xEEBA 0x92D3 #CJK UNIFIED IDEOGRAPH
+0xEEBB 0x9325 #CJK UNIFIED IDEOGRAPH
+0xEEBC 0x9321 #CJK UNIFIED IDEOGRAPH
+0xEEBD 0x92FB #CJK UNIFIED IDEOGRAPH
+0xEEBE 0xFA28 #CJK COMPATIBILITY IDEOGRAPH
+0xEEBF 0x931E #CJK UNIFIED IDEOGRAPH
+0xEEC0 0x92FF #CJK UNIFIED IDEOGRAPH
+0xEEC1 0x931D #CJK UNIFIED IDEOGRAPH
+0xEEC2 0x9302 #CJK UNIFIED IDEOGRAPH
+0xEEC3 0x9370 #CJK UNIFIED IDEOGRAPH
+0xEEC4 0x9357 #CJK UNIFIED IDEOGRAPH
+0xEEC5 0x93A4 #CJK UNIFIED IDEOGRAPH
+0xEEC6 0x93C6 #CJK UNIFIED IDEOGRAPH
+0xEEC7 0x93DE #CJK UNIFIED IDEOGRAPH
+0xEEC8 0x93F8 #CJK UNIFIED IDEOGRAPH
+0xEEC9 0x9431 #CJK UNIFIED IDEOGRAPH
+0xEECA 0x9445 #CJK UNIFIED IDEOGRAPH
+0xEECB 0x9448 #CJK UNIFIED IDEOGRAPH
+0xEECC 0x9592 #CJK UNIFIED IDEOGRAPH
+0xEECD 0xF9DC #CJK COMPATIBILITY IDEOGRAPH
+0xEECE 0xFA29 #CJK COMPATIBILITY IDEOGRAPH
+0xEECF 0x969D #CJK UNIFIED IDEOGRAPH
+0xEED0 0x96AF #CJK UNIFIED IDEOGRAPH
+0xEED1 0x9733 #CJK UNIFIED IDEOGRAPH
+0xEED2 0x973B #CJK UNIFIED IDEOGRAPH
+0xEED3 0x9743 #CJK UNIFIED IDEOGRAPH
+0xEED4 0x974D #CJK UNIFIED IDEOGRAPH
+0xEED5 0x974F #CJK UNIFIED IDEOGRAPH
+0xEED6 0x9751 #CJK UNIFIED IDEOGRAPH
+0xEED7 0x9755 #CJK UNIFIED IDEOGRAPH
+0xEED8 0x9857 #CJK UNIFIED IDEOGRAPH
+0xEED9 0x9865 #CJK UNIFIED IDEOGRAPH
+0xEEDA 0xFA2A #CJK COMPATIBILITY IDEOGRAPH
+0xEEDB 0xFA2B #CJK COMPATIBILITY IDEOGRAPH
+0xEEDC 0x9927 #CJK UNIFIED IDEOGRAPH
+0xEEDD 0xFA2C #CJK COMPATIBILITY IDEOGRAPH
+0xEEDE 0x999E #CJK UNIFIED IDEOGRAPH
+0xEEDF 0x9A4E #CJK UNIFIED IDEOGRAPH
+0xEEE0 0x9AD9 #CJK UNIFIED IDEOGRAPH
+0xEEE1 0x9ADC #CJK UNIFIED IDEOGRAPH
+0xEEE2 0x9B75 #CJK UNIFIED IDEOGRAPH
+0xEEE3 0x9B72 #CJK UNIFIED IDEOGRAPH
+0xEEE4 0x9B8F #CJK UNIFIED IDEOGRAPH
+0xEEE5 0x9BB1 #CJK UNIFIED IDEOGRAPH
+0xEEE6 0x9BBB #CJK UNIFIED IDEOGRAPH
+0xEEE7 0x9C00 #CJK UNIFIED IDEOGRAPH
+0xEEE8 0x9D70 #CJK UNIFIED IDEOGRAPH
+0xEEE9 0x9D6B #CJK UNIFIED IDEOGRAPH
+0xEEEA 0xFA2D #CJK COMPATIBILITY IDEOGRAPH
+0xEEEB 0x9E19 #CJK UNIFIED IDEOGRAPH
+0xEEEC 0x9ED1 #CJK UNIFIED IDEOGRAPH
+0xEEEF 0x2170 #SMALL ROMAN NUMERAL ONE
+0xEEF0 0x2171 #SMALL ROMAN NUMERAL TWO
+0xEEF1 0x2172 #SMALL ROMAN NUMERAL THREE
+0xEEF2 0x2173 #SMALL ROMAN NUMERAL FOUR
+0xEEF3 0x2174 #SMALL ROMAN NUMERAL FIVE
+0xEEF4 0x2175 #SMALL ROMAN NUMERAL SIX
+0xEEF5 0x2176 #SMALL ROMAN NUMERAL SEVEN
+0xEEF6 0x2177 #SMALL ROMAN NUMERAL EIGHT
+0xEEF7 0x2178 #SMALL ROMAN NUMERAL NINE
+0xEEF8 0x2179 #SMALL ROMAN NUMERAL TEN
+0xEEFA 0xFFE4 #FULLWIDTH BROKEN BAR
+0xEEFB 0xFF07 #FULLWIDTH APOSTROPHE
+0xEEFC 0xFF02 #FULLWIDTH QUOTATION MARK
+0xF040 0xE000 #USER DEFINED CHAR
+0xF041 0xE001 #USER DEFINED CHAR
+0xF042 0xE002 #USER DEFINED CHAR
+0xF043 0xE003 #USER DEFINED CHAR
+0xF044 0xE004 #USER DEFINED CHAR
+0xF045 0xE005 #USER DEFINED CHAR
+0xF046 0xE006 #USER DEFINED CHAR
+0xF047 0xE007 #USER DEFINED CHAR
+0xF048 0xE008 #USER DEFINED CHAR
+0xF049 0xE009 #USER DEFINED CHAR
+0xF04A 0xE00A #USER DEFINED CHAR
+0xF04B 0xE00B #USER DEFINED CHAR
+0xF04C 0xE00C #USER DEFINED CHAR
+0xF04D 0xE00D #USER DEFINED CHAR
+0xF04E 0xE00E #USER DEFINED CHAR
+0xF04F 0xE00F #USER DEFINED CHAR
+0xF050 0xE010 #USER DEFINED CHAR
+0xF051 0xE011 #USER DEFINED CHAR
+0xF052 0xE012 #USER DEFINED CHAR
+0xF053 0xE013 #USER DEFINED CHAR
+0xF054 0xE014 #USER DEFINED CHAR
+0xF055 0xE015 #USER DEFINED CHAR
+0xF056 0xE016 #USER DEFINED CHAR
+0xF057 0xE017 #USER DEFINED CHAR
+0xF058 0xE018 #USER DEFINED CHAR
+0xF059 0xE019 #USER DEFINED CHAR
+0xF05A 0xE01A #USER DEFINED CHAR
+0xF05B 0xE01B #USER DEFINED CHAR
+0xF05C 0xE01C #USER DEFINED CHAR
+0xF05D 0xE01D #USER DEFINED CHAR
+0xF05E 0xE01E #USER DEFINED CHAR
+0xF05F 0xE01F #USER DEFINED CHAR
+0xF060 0xE020 #USER DEFINED CHAR
+0xF061 0xE021 #USER DEFINED CHAR
+0xF062 0xE022 #USER DEFINED CHAR
+0xF063 0xE023 #USER DEFINED CHAR
+0xF064 0xE024 #USER DEFINED CHAR
+0xF065 0xE025 #USER DEFINED CHAR
+0xF066 0xE026 #USER DEFINED CHAR
+0xF067 0xE027 #USER DEFINED CHAR
+0xF068 0xE028 #USER DEFINED CHAR
+0xF069 0xE029 #USER DEFINED CHAR
+0xF06A 0xE02A #USER DEFINED CHAR
+0xF06B 0xE02B #USER DEFINED CHAR
+0xF06C 0xE02C #USER DEFINED CHAR
+0xF06D 0xE02D #USER DEFINED CHAR
+0xF06E 0xE02E #USER DEFINED CHAR
+0xF06F 0xE02F #USER DEFINED CHAR
+0xF070 0xE030 #USER DEFINED CHAR
+0xF071 0xE031 #USER DEFINED CHAR
+0xF072 0xE032 #USER DEFINED CHAR
+0xF073 0xE033 #USER DEFINED CHAR
+0xF074 0xE034 #USER DEFINED CHAR
+0xF075 0xE035 #USER DEFINED CHAR
+0xF076 0xE036 #USER DEFINED CHAR
+0xF077 0xE037 #USER DEFINED CHAR
+0xF078 0xE038 #USER DEFINED CHAR
+0xF079 0xE039 #USER DEFINED CHAR
+0xF07A 0xE03A #USER DEFINED CHAR
+0xF07B 0xE03B #USER DEFINED CHAR
+0xF07C 0xE03C #USER DEFINED CHAR
+0xF07D 0xE03D #USER DEFINED CHAR
+0xF07E 0xE03E #USER DEFINED CHAR
+0xF080 0xE03F #USER DEFINED CHAR
+0xF081 0xE040 #USER DEFINED CHAR
+0xF082 0xE041 #USER DEFINED CHAR
+0xF083 0xE042 #USER DEFINED CHAR
+0xF084 0xE043 #USER DEFINED CHAR
+0xF085 0xE044 #USER DEFINED CHAR
+0xF086 0xE045 #USER DEFINED CHAR
+0xF087 0xE046 #USER DEFINED CHAR
+0xF088 0xE047 #USER DEFINED CHAR
+0xF089 0xE048 #USER DEFINED CHAR
+0xF08A 0xE049 #USER DEFINED CHAR
+0xF08B 0xE04A #USER DEFINED CHAR
+0xF08C 0xE04B #USER DEFINED CHAR
+0xF08D 0xE04C #USER DEFINED CHAR
+0xF08E 0xE04D #USER DEFINED CHAR
+0xF08F 0xE04E #USER DEFINED CHAR
+0xF090 0xE04F #USER DEFINED CHAR
+0xF091 0xE050 #USER DEFINED CHAR
+0xF092 0xE051 #USER DEFINED CHAR
+0xF093 0xE052 #USER DEFINED CHAR
+0xF094 0xE053 #USER DEFINED CHAR
+0xF095 0xE054 #USER DEFINED CHAR
+0xF096 0xE055 #USER DEFINED CHAR
+0xF097 0xE056 #USER DEFINED CHAR
+0xF098 0xE057 #USER DEFINED CHAR
+0xF099 0xE058 #USER DEFINED CHAR
+0xF09A 0xE059 #USER DEFINED CHAR
+0xF09B 0xE05A #USER DEFINED CHAR
+0xF09C 0xE05B #USER DEFINED CHAR
+0xF09D 0xE05C #USER DEFINED CHAR
+0xF09E 0xE05D #USER DEFINED CHAR
+0xF09F 0xE05E #USER DEFINED CHAR
+0xF0A0 0xE05F #USER DEFINED CHAR
+0xF0A1 0xE060 #USER DEFINED CHAR
+0xF0A2 0xE061 #USER DEFINED CHAR
+0xF0A3 0xE062 #USER DEFINED CHAR
+0xF0A4 0xE063 #USER DEFINED CHAR
+0xF0A5 0xE064 #USER DEFINED CHAR
+0xF0A6 0xE065 #USER DEFINED CHAR
+0xF0A7 0xE066 #USER DEFINED CHAR
+0xF0A8 0xE067 #USER DEFINED CHAR
+0xF0A9 0xE068 #USER DEFINED CHAR
+0xF0AA 0xE069 #USER DEFINED CHAR
+0xF0AB 0xE06A #USER DEFINED CHAR
+0xF0AC 0xE06B #USER DEFINED CHAR
+0xF0AD 0xE06C #USER DEFINED CHAR
+0xF0AE 0xE06D #USER DEFINED CHAR
+0xF0AF 0xE06E #USER DEFINED CHAR
+0xF0B0 0xE06F #USER DEFINED CHAR
+0xF0B1 0xE070 #USER DEFINED CHAR
+0xF0B2 0xE071 #USER DEFINED CHAR
+0xF0B3 0xE072 #USER DEFINED CHAR
+0xF0B4 0xE073 #USER DEFINED CHAR
+0xF0B5 0xE074 #USER DEFINED CHAR
+0xF0B6 0xE075 #USER DEFINED CHAR
+0xF0B7 0xE076 #USER DEFINED CHAR
+0xF0B8 0xE077 #USER DEFINED CHAR
+0xF0B9 0xE078 #USER DEFINED CHAR
+0xF0BA 0xE079 #USER DEFINED CHAR
+0xF0BB 0xE07A #USER DEFINED CHAR
+0xF0BC 0xE07B #USER DEFINED CHAR
+0xF0BD 0xE07C #USER DEFINED CHAR
+0xF0BE 0xE07D #USER DEFINED CHAR
+0xF0BF 0xE07E #USER DEFINED CHAR
+0xF0C0 0xE07F #USER DEFINED CHAR
+0xF0C1 0xE080 #USER DEFINED CHAR
+0xF0C2 0xE081 #USER DEFINED CHAR
+0xF0C3 0xE082 #USER DEFINED CHAR
+0xF0C4 0xE083 #USER DEFINED CHAR
+0xF0C5 0xE084 #USER DEFINED CHAR
+0xF0C6 0xE085 #USER DEFINED CHAR
+0xF0C7 0xE086 #USER DEFINED CHAR
+0xF0C8 0xE087 #USER DEFINED CHAR
+0xF0C9 0xE088 #USER DEFINED CHAR
+0xF0CA 0xE089 #USER DEFINED CHAR
+0xF0CB 0xE08A #USER DEFINED CHAR
+0xF0CC 0xE08B #USER DEFINED CHAR
+0xF0CD 0xE08C #USER DEFINED CHAR
+0xF0CE 0xE08D #USER DEFINED CHAR
+0xF0CF 0xE08E #USER DEFINED CHAR
+0xF0D0 0xE08F #USER DEFINED CHAR
+0xF0D1 0xE090 #USER DEFINED CHAR
+0xF0D2 0xE091 #USER DEFINED CHAR
+0xF0D3 0xE092 #USER DEFINED CHAR
+0xF0D4 0xE093 #USER DEFINED CHAR
+0xF0D5 0xE094 #USER DEFINED CHAR
+0xF0D6 0xE095 #USER DEFINED CHAR
+0xF0D7 0xE096 #USER DEFINED CHAR
+0xF0D8 0xE097 #USER DEFINED CHAR
+0xF0D9 0xE098 #USER DEFINED CHAR
+0xF0DA 0xE099 #USER DEFINED CHAR
+0xF0DB 0xE09A #USER DEFINED CHAR
+0xF0DC 0xE09B #USER DEFINED CHAR
+0xF0DD 0xE09C #USER DEFINED CHAR
+0xF0DE 0xE09D #USER DEFINED CHAR
+0xF0DF 0xE09E #USER DEFINED CHAR
+0xF0E0 0xE09F #USER DEFINED CHAR
+0xF0E1 0xE0A0 #USER DEFINED CHAR
+0xF0E2 0xE0A1 #USER DEFINED CHAR
+0xF0E3 0xE0A2 #USER DEFINED CHAR
+0xF0E4 0xE0A3 #USER DEFINED CHAR
+0xF0E5 0xE0A4 #USER DEFINED CHAR
+0xF0E6 0xE0A5 #USER DEFINED CHAR
+0xF0E7 0xE0A6 #USER DEFINED CHAR
+0xF0E8 0xE0A7 #USER DEFINED CHAR
+0xF0E9 0xE0A8 #USER DEFINED CHAR
+0xF0EA 0xE0A9 #USER DEFINED CHAR
+0xF0EB 0xE0AA #USER DEFINED CHAR
+0xF0EC 0xE0AB #USER DEFINED CHAR
+0xF0ED 0xE0AC #USER DEFINED CHAR
+0xF0EE 0xE0AD #USER DEFINED CHAR
+0xF0EF 0xE0AE #USER DEFINED CHAR
+0xF0F0 0xE0AF #USER DEFINED CHAR
+0xF0F1 0xE0B0 #USER DEFINED CHAR
+0xF0F2 0xE0B1 #USER DEFINED CHAR
+0xF0F3 0xE0B2 #USER DEFINED CHAR
+0xF0F4 0xE0B3 #USER DEFINED CHAR
+0xF0F5 0xE0B4 #USER DEFINED CHAR
+0xF0F6 0xE0B5 #USER DEFINED CHAR
+0xF0F7 0xE0B6 #USER DEFINED CHAR
+0xF0F8 0xE0B7 #USER DEFINED CHAR
+0xF0F9 0xE0B8 #USER DEFINED CHAR
+0xF0FA 0xE0B9 #USER DEFINED CHAR
+0xF0FB 0xE0BA #USER DEFINED CHAR
+0xF0FC 0xE0BB #USER DEFINED CHAR
+0xF140 0xE0BC #USER DEFINED CHAR
+0xF141 0xE0BD #USER DEFINED CHAR
+0xF142 0xE0BE #USER DEFINED CHAR
+0xF143 0xE0BF #USER DEFINED CHAR
+0xF144 0xE0C0 #USER DEFINED CHAR
+0xF145 0xE0C1 #USER DEFINED CHAR
+0xF146 0xE0C2 #USER DEFINED CHAR
+0xF147 0xE0C3 #USER DEFINED CHAR
+0xF148 0xE0C4 #USER DEFINED CHAR
+0xF149 0xE0C5 #USER DEFINED CHAR
+0xF14A 0xE0C6 #USER DEFINED CHAR
+0xF14B 0xE0C7 #USER DEFINED CHAR
+0xF14C 0xE0C8 #USER DEFINED CHAR
+0xF14D 0xE0C9 #USER DEFINED CHAR
+0xF14E 0xE0CA #USER DEFINED CHAR
+0xF14F 0xE0CB #USER DEFINED CHAR
+0xF150 0xE0CC #USER DEFINED CHAR
+0xF151 0xE0CD #USER DEFINED CHAR
+0xF152 0xE0CE #USER DEFINED CHAR
+0xF153 0xE0CF #USER DEFINED CHAR
+0xF154 0xE0D0 #USER DEFINED CHAR
+0xF155 0xE0D1 #USER DEFINED CHAR
+0xF156 0xE0D2 #USER DEFINED CHAR
+0xF157 0xE0D3 #USER DEFINED CHAR
+0xF158 0xE0D4 #USER DEFINED CHAR
+0xF159 0xE0D5 #USER DEFINED CHAR
+0xF15A 0xE0D6 #USER DEFINED CHAR
+0xF15B 0xE0D7 #USER DEFINED CHAR
+0xF15C 0xE0D8 #USER DEFINED CHAR
+0xF15D 0xE0D9 #USER DEFINED CHAR
+0xF15E 0xE0DA #USER DEFINED CHAR
+0xF15F 0xE0DB #USER DEFINED CHAR
+0xF160 0xE0DC #USER DEFINED CHAR
+0xF161 0xE0DD #USER DEFINED CHAR
+0xF162 0xE0DE #USER DEFINED CHAR
+0xF163 0xE0DF #USER DEFINED CHAR
+0xF164 0xE0E0 #USER DEFINED CHAR
+0xF165 0xE0E1 #USER DEFINED CHAR
+0xF166 0xE0E2 #USER DEFINED CHAR
+0xF167 0xE0E3 #USER DEFINED CHAR
+0xF168 0xE0E4 #USER DEFINED CHAR
+0xF169 0xE0E5 #USER DEFINED CHAR
+0xF16A 0xE0E6 #USER DEFINED CHAR
+0xF16B 0xE0E7 #USER DEFINED CHAR
+0xF16C 0xE0E8 #USER DEFINED CHAR
+0xF16D 0xE0E9 #USER DEFINED CHAR
+0xF16E 0xE0EA #USER DEFINED CHAR
+0xF16F 0xE0EB #USER DEFINED CHAR
+0xF170 0xE0EC #USER DEFINED CHAR
+0xF171 0xE0ED #USER DEFINED CHAR
+0xF172 0xE0EE #USER DEFINED CHAR
+0xF173 0xE0EF #USER DEFINED CHAR
+0xF174 0xE0F0 #USER DEFINED CHAR
+0xF175 0xE0F1 #USER DEFINED CHAR
+0xF176 0xE0F2 #USER DEFINED CHAR
+0xF177 0xE0F3 #USER DEFINED CHAR
+0xF178 0xE0F4 #USER DEFINED CHAR
+0xF179 0xE0F5 #USER DEFINED CHAR
+0xF17A 0xE0F6 #USER DEFINED CHAR
+0xF17B 0xE0F7 #USER DEFINED CHAR
+0xF17C 0xE0F8 #USER DEFINED CHAR
+0xF17D 0xE0F9 #USER DEFINED CHAR
+0xF17E 0xE0FA #USER DEFINED CHAR
+0xF180 0xE0FB #USER DEFINED CHAR
+0xF181 0xE0FC #USER DEFINED CHAR
+0xF182 0xE0FD #USER DEFINED CHAR
+0xF183 0xE0FE #USER DEFINED CHAR
+0xF184 0xE0FF #USER DEFINED CHAR
+0xF185 0xE100 #USER DEFINED CHAR
+0xF186 0xE101 #USER DEFINED CHAR
+0xF187 0xE102 #USER DEFINED CHAR
+0xF188 0xE103 #USER DEFINED CHAR
+0xF189 0xE104 #USER DEFINED CHAR
+0xF18A 0xE105 #USER DEFINED CHAR
+0xF18B 0xE106 #USER DEFINED CHAR
+0xF18C 0xE107 #USER DEFINED CHAR
+0xF18D 0xE108 #USER DEFINED CHAR
+0xF18E 0xE109 #USER DEFINED CHAR
+0xF18F 0xE10A #USER DEFINED CHAR
+0xF190 0xE10B #USER DEFINED CHAR
+0xF191 0xE10C #USER DEFINED CHAR
+0xF192 0xE10D #USER DEFINED CHAR
+0xF193 0xE10E #USER DEFINED CHAR
+0xF194 0xE10F #USER DEFINED CHAR
+0xF195 0xE110 #USER DEFINED CHAR
+0xF196 0xE111 #USER DEFINED CHAR
+0xF197 0xE112 #USER DEFINED CHAR
+0xF198 0xE113 #USER DEFINED CHAR
+0xF199 0xE114 #USER DEFINED CHAR
+0xF19A 0xE115 #USER DEFINED CHAR
+0xF19B 0xE116 #USER DEFINED CHAR
+0xF19C 0xE117 #USER DEFINED CHAR
+0xF19D 0xE118 #USER DEFINED CHAR
+0xF19E 0xE119 #USER DEFINED CHAR
+0xF19F 0xE11A #USER DEFINED CHAR
+0xF1A0 0xE11B #USER DEFINED CHAR
+0xF1A1 0xE11C #USER DEFINED CHAR
+0xF1A2 0xE11D #USER DEFINED CHAR
+0xF1A3 0xE11E #USER DEFINED CHAR
+0xF1A4 0xE11F #USER DEFINED CHAR
+0xF1A5 0xE120 #USER DEFINED CHAR
+0xF1A6 0xE121 #USER DEFINED CHAR
+0xF1A7 0xE122 #USER DEFINED CHAR
+0xF1A8 0xE123 #USER DEFINED CHAR
+0xF1A9 0xE124 #USER DEFINED CHAR
+0xF1AA 0xE125 #USER DEFINED CHAR
+0xF1AB 0xE126 #USER DEFINED CHAR
+0xF1AC 0xE127 #USER DEFINED CHAR
+0xF1AD 0xE128 #USER DEFINED CHAR
+0xF1AE 0xE129 #USER DEFINED CHAR
+0xF1AF 0xE12A #USER DEFINED CHAR
+0xF1B0 0xE12B #USER DEFINED CHAR
+0xF1B1 0xE12C #USER DEFINED CHAR
+0xF1B2 0xE12D #USER DEFINED CHAR
+0xF1B3 0xE12E #USER DEFINED CHAR
+0xF1B4 0xE12F #USER DEFINED CHAR
+0xF1B5 0xE130 #USER DEFINED CHAR
+0xF1B6 0xE131 #USER DEFINED CHAR
+0xF1B7 0xE132 #USER DEFINED CHAR
+0xF1B8 0xE133 #USER DEFINED CHAR
+0xF1B9 0xE134 #USER DEFINED CHAR
+0xF1BA 0xE135 #USER DEFINED CHAR
+0xF1BB 0xE136 #USER DEFINED CHAR
+0xF1BC 0xE137 #USER DEFINED CHAR
+0xF1BD 0xE138 #USER DEFINED CHAR
+0xF1BE 0xE139 #USER DEFINED CHAR
+0xF1BF 0xE13A #USER DEFINED CHAR
+0xF1C0 0xE13B #USER DEFINED CHAR
+0xF1C1 0xE13C #USER DEFINED CHAR
+0xF1C2 0xE13D #USER DEFINED CHAR
+0xF1C3 0xE13E #USER DEFINED CHAR
+0xF1C4 0xE13F #USER DEFINED CHAR
+0xF1C5 0xE140 #USER DEFINED CHAR
+0xF1C6 0xE141 #USER DEFINED CHAR
+0xF1C7 0xE142 #USER DEFINED CHAR
+0xF1C8 0xE143 #USER DEFINED CHAR
+0xF1C9 0xE144 #USER DEFINED CHAR
+0xF1CA 0xE145 #USER DEFINED CHAR
+0xF1CB 0xE146 #USER DEFINED CHAR
+0xF1CC 0xE147 #USER DEFINED CHAR
+0xF1CD 0xE148 #USER DEFINED CHAR
+0xF1CE 0xE149 #USER DEFINED CHAR
+0xF1CF 0xE14A #USER DEFINED CHAR
+0xF1D0 0xE14B #USER DEFINED CHAR
+0xF1D1 0xE14C #USER DEFINED CHAR
+0xF1D2 0xE14D #USER DEFINED CHAR
+0xF1D3 0xE14E #USER DEFINED CHAR
+0xF1D4 0xE14F #USER DEFINED CHAR
+0xF1D5 0xE150 #USER DEFINED CHAR
+0xF1D6 0xE151 #USER DEFINED CHAR
+0xF1D7 0xE152 #USER DEFINED CHAR
+0xF1D8 0xE153 #USER DEFINED CHAR
+0xF1D9 0xE154 #USER DEFINED CHAR
+0xF1DA 0xE155 #USER DEFINED CHAR
+0xF1DB 0xE156 #USER DEFINED CHAR
+0xF1DC 0xE157 #USER DEFINED CHAR
+0xF1DD 0xE158 #USER DEFINED CHAR
+0xF1DE 0xE159 #USER DEFINED CHAR
+0xF1DF 0xE15A #USER DEFINED CHAR
+0xF1E0 0xE15B #USER DEFINED CHAR
+0xF1E1 0xE15C #USER DEFINED CHAR
+0xF1E2 0xE15D #USER DEFINED CHAR
+0xF1E3 0xE15E #USER DEFINED CHAR
+0xF1E4 0xE15F #USER DEFINED CHAR
+0xF1E5 0xE160 #USER DEFINED CHAR
+0xF1E6 0xE161 #USER DEFINED CHAR
+0xF1E7 0xE162 #USER DEFINED CHAR
+0xF1E8 0xE163 #USER DEFINED CHAR
+0xF1E9 0xE164 #USER DEFINED CHAR
+0xF1EA 0xE165 #USER DEFINED CHAR
+0xF1EB 0xE166 #USER DEFINED CHAR
+0xF1EC 0xE167 #USER DEFINED CHAR
+0xF1ED 0xE168 #USER DEFINED CHAR
+0xF1EE 0xE169 #USER DEFINED CHAR
+0xF1EF 0xE16A #USER DEFINED CHAR
+0xF1F0 0xE16B #USER DEFINED CHAR
+0xF1F1 0xE16C #USER DEFINED CHAR
+0xF1F2 0xE16D #USER DEFINED CHAR
+0xF1F3 0xE16E #USER DEFINED CHAR
+0xF1F4 0xE16F #USER DEFINED CHAR
+0xF1F5 0xE170 #USER DEFINED CHAR
+0xF1F6 0xE171 #USER DEFINED CHAR
+0xF1F7 0xE172 #USER DEFINED CHAR
+0xF1F8 0xE173 #USER DEFINED CHAR
+0xF1F9 0xE174 #USER DEFINED CHAR
+0xF1FA 0xE175 #USER DEFINED CHAR
+0xF1FB 0xE176 #USER DEFINED CHAR
+0xF1FC 0xE177 #USER DEFINED CHAR
+0xF240 0xE178 #USER DEFINED CHAR
+0xF241 0xE179 #USER DEFINED CHAR
+0xF242 0xE17A #USER DEFINED CHAR
+0xF243 0xE17B #USER DEFINED CHAR
+0xF244 0xE17C #USER DEFINED CHAR
+0xF245 0xE17D #USER DEFINED CHAR
+0xF246 0xE17E #USER DEFINED CHAR
+0xF247 0xE17F #USER DEFINED CHAR
+0xF248 0xE180 #USER DEFINED CHAR
+0xF249 0xE181 #USER DEFINED CHAR
+0xF24A 0xE182 #USER DEFINED CHAR
+0xF24B 0xE183 #USER DEFINED CHAR
+0xF24C 0xE184 #USER DEFINED CHAR
+0xF24D 0xE185 #USER DEFINED CHAR
+0xF24E 0xE186 #USER DEFINED CHAR
+0xF24F 0xE187 #USER DEFINED CHAR
+0xF250 0xE188 #USER DEFINED CHAR
+0xF251 0xE189 #USER DEFINED CHAR
+0xF252 0xE18A #USER DEFINED CHAR
+0xF253 0xE18B #USER DEFINED CHAR
+0xF254 0xE18C #USER DEFINED CHAR
+0xF255 0xE18D #USER DEFINED CHAR
+0xF256 0xE18E #USER DEFINED CHAR
+0xF257 0xE18F #USER DEFINED CHAR
+0xF258 0xE190 #USER DEFINED CHAR
+0xF259 0xE191 #USER DEFINED CHAR
+0xF25A 0xE192 #USER DEFINED CHAR
+0xF25B 0xE193 #USER DEFINED CHAR
+0xF25C 0xE194 #USER DEFINED CHAR
+0xF25D 0xE195 #USER DEFINED CHAR
+0xF25E 0xE196 #USER DEFINED CHAR
+0xF25F 0xE197 #USER DEFINED CHAR
+0xF260 0xE198 #USER DEFINED CHAR
+0xF261 0xE199 #USER DEFINED CHAR
+0xF262 0xE19A #USER DEFINED CHAR
+0xF263 0xE19B #USER DEFINED CHAR
+0xF264 0xE19C #USER DEFINED CHAR
+0xF265 0xE19D #USER DEFINED CHAR
+0xF266 0xE19E #USER DEFINED CHAR
+0xF267 0xE19F #USER DEFINED CHAR
+0xF268 0xE1A0 #USER DEFINED CHAR
+0xF269 0xE1A1 #USER DEFINED CHAR
+0xF26A 0xE1A2 #USER DEFINED CHAR
+0xF26B 0xE1A3 #USER DEFINED CHAR
+0xF26C 0xE1A4 #USER DEFINED CHAR
+0xF26D 0xE1A5 #USER DEFINED CHAR
+0xF26E 0xE1A6 #USER DEFINED CHAR
+0xF26F 0xE1A7 #USER DEFINED CHAR
+0xF270 0xE1A8 #USER DEFINED CHAR
+0xF271 0xE1A9 #USER DEFINED CHAR
+0xF272 0xE1AA #USER DEFINED CHAR
+0xF273 0xE1AB #USER DEFINED CHAR
+0xF274 0xE1AC #USER DEFINED CHAR
+0xF275 0xE1AD #USER DEFINED CHAR
+0xF276 0xE1AE #USER DEFINED CHAR
+0xF277 0xE1AF #USER DEFINED CHAR
+0xF278 0xE1B0 #USER DEFINED CHAR
+0xF279 0xE1B1 #USER DEFINED CHAR
+0xF27A 0xE1B2 #USER DEFINED CHAR
+0xF27B 0xE1B3 #USER DEFINED CHAR
+0xF27C 0xE1B4 #USER DEFINED CHAR
+0xF27D 0xE1B5 #USER DEFINED CHAR
+0xF27E 0xE1B6 #USER DEFINED CHAR
+0xF280 0xE1B7 #USER DEFINED CHAR
+0xF281 0xE1B8 #USER DEFINED CHAR
+0xF282 0xE1B9 #USER DEFINED CHAR
+0xF283 0xE1BA #USER DEFINED CHAR
+0xF284 0xE1BB #USER DEFINED CHAR
+0xF285 0xE1BC #USER DEFINED CHAR
+0xF286 0xE1BD #USER DEFINED CHAR
+0xF287 0xE1BE #USER DEFINED CHAR
+0xF288 0xE1BF #USER DEFINED CHAR
+0xF289 0xE1C0 #USER DEFINED CHAR
+0xF28A 0xE1C1 #USER DEFINED CHAR
+0xF28B 0xE1C2 #USER DEFINED CHAR
+0xF28C 0xE1C3 #USER DEFINED CHAR
+0xF28D 0xE1C4 #USER DEFINED CHAR
+0xF28E 0xE1C5 #USER DEFINED CHAR
+0xF28F 0xE1C6 #USER DEFINED CHAR
+0xF290 0xE1C7 #USER DEFINED CHAR
+0xF291 0xE1C8 #USER DEFINED CHAR
+0xF292 0xE1C9 #USER DEFINED CHAR
+0xF293 0xE1CA #USER DEFINED CHAR
+0xF294 0xE1CB #USER DEFINED CHAR
+0xF295 0xE1CC #USER DEFINED CHAR
+0xF296 0xE1CD #USER DEFINED CHAR
+0xF297 0xE1CE #USER DEFINED CHAR
+0xF298 0xE1CF #USER DEFINED CHAR
+0xF299 0xE1D0 #USER DEFINED CHAR
+0xF29A 0xE1D1 #USER DEFINED CHAR
+0xF29B 0xE1D2 #USER DEFINED CHAR
+0xF29C 0xE1D3 #USER DEFINED CHAR
+0xF29D 0xE1D4 #USER DEFINED CHAR
+0xF29E 0xE1D5 #USER DEFINED CHAR
+0xF29F 0xE1D6 #USER DEFINED CHAR
+0xF2A0 0xE1D7 #USER DEFINED CHAR
+0xF2A1 0xE1D8 #USER DEFINED CHAR
+0xF2A2 0xE1D9 #USER DEFINED CHAR
+0xF2A3 0xE1DA #USER DEFINED CHAR
+0xF2A4 0xE1DB #USER DEFINED CHAR
+0xF2A5 0xE1DC #USER DEFINED CHAR
+0xF2A6 0xE1DD #USER DEFINED CHAR
+0xF2A7 0xE1DE #USER DEFINED CHAR
+0xF2A8 0xE1DF #USER DEFINED CHAR
+0xF2A9 0xE1E0 #USER DEFINED CHAR
+0xF2AA 0xE1E1 #USER DEFINED CHAR
+0xF2AB 0xE1E2 #USER DEFINED CHAR
+0xF2AC 0xE1E3 #USER DEFINED CHAR
+0xF2AD 0xE1E4 #USER DEFINED CHAR
+0xF2AE 0xE1E5 #USER DEFINED CHAR
+0xF2AF 0xE1E6 #USER DEFINED CHAR
+0xF2B0 0xE1E7 #USER DEFINED CHAR
+0xF2B1 0xE1E8 #USER DEFINED CHAR
+0xF2B2 0xE1E9 #USER DEFINED CHAR
+0xF2B3 0xE1EA #USER DEFINED CHAR
+0xF2B4 0xE1EB #USER DEFINED CHAR
+0xF2B5 0xE1EC #USER DEFINED CHAR
+0xF2B6 0xE1ED #USER DEFINED CHAR
+0xF2B7 0xE1EE #USER DEFINED CHAR
+0xF2B8 0xE1EF #USER DEFINED CHAR
+0xF2B9 0xE1F0 #USER DEFINED CHAR
+0xF2BA 0xE1F1 #USER DEFINED CHAR
+0xF2BB 0xE1F2 #USER DEFINED CHAR
+0xF2BC 0xE1F3 #USER DEFINED CHAR
+0xF2BD 0xE1F4 #USER DEFINED CHAR
+0xF2BE 0xE1F5 #USER DEFINED CHAR
+0xF2BF 0xE1F6 #USER DEFINED CHAR
+0xF2C0 0xE1F7 #USER DEFINED CHAR
+0xF2C1 0xE1F8 #USER DEFINED CHAR
+0xF2C2 0xE1F9 #USER DEFINED CHAR
+0xF2C3 0xE1FA #USER DEFINED CHAR
+0xF2C4 0xE1FB #USER DEFINED CHAR
+0xF2C5 0xE1FC #USER DEFINED CHAR
+0xF2C6 0xE1FD #USER DEFINED CHAR
+0xF2C7 0xE1FE #USER DEFINED CHAR
+0xF2C8 0xE1FF #USER DEFINED CHAR
+0xF2C9 0xE200 #USER DEFINED CHAR
+0xF2CA 0xE201 #USER DEFINED CHAR
+0xF2CB 0xE202 #USER DEFINED CHAR
+0xF2CC 0xE203 #USER DEFINED CHAR
+0xF2CD 0xE204 #USER DEFINED CHAR
+0xF2CE 0xE205 #USER DEFINED CHAR
+0xF2CF 0xE206 #USER DEFINED CHAR
+0xF2D0 0xE207 #USER DEFINED CHAR
+0xF2D1 0xE208 #USER DEFINED CHAR
+0xF2D2 0xE209 #USER DEFINED CHAR
+0xF2D3 0xE20A #USER DEFINED CHAR
+0xF2D4 0xE20B #USER DEFINED CHAR
+0xF2D5 0xE20C #USER DEFINED CHAR
+0xF2D6 0xE20D #USER DEFINED CHAR
+0xF2D7 0xE20E #USER DEFINED CHAR
+0xF2D8 0xE20F #USER DEFINED CHAR
+0xF2D9 0xE210 #USER DEFINED CHAR
+0xF2DA 0xE211 #USER DEFINED CHAR
+0xF2DB 0xE212 #USER DEFINED CHAR
+0xF2DC 0xE213 #USER DEFINED CHAR
+0xF2DD 0xE214 #USER DEFINED CHAR
+0xF2DE 0xE215 #USER DEFINED CHAR
+0xF2DF 0xE216 #USER DEFINED CHAR
+0xF2E0 0xE217 #USER DEFINED CHAR
+0xF2E1 0xE218 #USER DEFINED CHAR
+0xF2E2 0xE219 #USER DEFINED CHAR
+0xF2E3 0xE21A #USER DEFINED CHAR
+0xF2E4 0xE21B #USER DEFINED CHAR
+0xF2E5 0xE21C #USER DEFINED CHAR
+0xF2E6 0xE21D #USER DEFINED CHAR
+0xF2E7 0xE21E #USER DEFINED CHAR
+0xF2E8 0xE21F #USER DEFINED CHAR
+0xF2E9 0xE220 #USER DEFINED CHAR
+0xF2EA 0xE221 #USER DEFINED CHAR
+0xF2EB 0xE222 #USER DEFINED CHAR
+0xF2EC 0xE223 #USER DEFINED CHAR
+0xF2ED 0xE224 #USER DEFINED CHAR
+0xF2EE 0xE225 #USER DEFINED CHAR
+0xF2EF 0xE226 #USER DEFINED CHAR
+0xF2F0 0xE227 #USER DEFINED CHAR
+0xF2F1 0xE228 #USER DEFINED CHAR
+0xF2F2 0xE229 #USER DEFINED CHAR
+0xF2F3 0xE22A #USER DEFINED CHAR
+0xF2F4 0xE22B #USER DEFINED CHAR
+0xF2F5 0xE22C #USER DEFINED CHAR
+0xF2F6 0xE22D #USER DEFINED CHAR
+0xF2F7 0xE22E #USER DEFINED CHAR
+0xF2F8 0xE22F #USER DEFINED CHAR
+0xF2F9 0xE230 #USER DEFINED CHAR
+0xF2FA 0xE231 #USER DEFINED CHAR
+0xF2FB 0xE232 #USER DEFINED CHAR
+0xF2FC 0xE233 #USER DEFINED CHAR
+0xF340 0xE234 #USER DEFINED CHAR
+0xF341 0xE235 #USER DEFINED CHAR
+0xF342 0xE236 #USER DEFINED CHAR
+0xF343 0xE237 #USER DEFINED CHAR
+0xF344 0xE238 #USER DEFINED CHAR
+0xF345 0xE239 #USER DEFINED CHAR
+0xF346 0xE23A #USER DEFINED CHAR
+0xF347 0xE23B #USER DEFINED CHAR
+0xF348 0xE23C #USER DEFINED CHAR
+0xF349 0xE23D #USER DEFINED CHAR
+0xF34A 0xE23E #USER DEFINED CHAR
+0xF34B 0xE23F #USER DEFINED CHAR
+0xF34C 0xE240 #USER DEFINED CHAR
+0xF34D 0xE241 #USER DEFINED CHAR
+0xF34E 0xE242 #USER DEFINED CHAR
+0xF34F 0xE243 #USER DEFINED CHAR
+0xF350 0xE244 #USER DEFINED CHAR
+0xF351 0xE245 #USER DEFINED CHAR
+0xF352 0xE246 #USER DEFINED CHAR
+0xF353 0xE247 #USER DEFINED CHAR
+0xF354 0xE248 #USER DEFINED CHAR
+0xF355 0xE249 #USER DEFINED CHAR
+0xF356 0xE24A #USER DEFINED CHAR
+0xF357 0xE24B #USER DEFINED CHAR
+0xF358 0xE24C #USER DEFINED CHAR
+0xF359 0xE24D #USER DEFINED CHAR
+0xF35A 0xE24E #USER DEFINED CHAR
+0xF35B 0xE24F #USER DEFINED CHAR
+0xF35C 0xE250 #USER DEFINED CHAR
+0xF35D 0xE251 #USER DEFINED CHAR
+0xF35E 0xE252 #USER DEFINED CHAR
+0xF35F 0xE253 #USER DEFINED CHAR
+0xF360 0xE254 #USER DEFINED CHAR
+0xF361 0xE255 #USER DEFINED CHAR
+0xF362 0xE256 #USER DEFINED CHAR
+0xF363 0xE257 #USER DEFINED CHAR
+0xF364 0xE258 #USER DEFINED CHAR
+0xF365 0xE259 #USER DEFINED CHAR
+0xF366 0xE25A #USER DEFINED CHAR
+0xF367 0xE25B #USER DEFINED CHAR
+0xF368 0xE25C #USER DEFINED CHAR
+0xF369 0xE25D #USER DEFINED CHAR
+0xF36A 0xE25E #USER DEFINED CHAR
+0xF36B 0xE25F #USER DEFINED CHAR
+0xF36C 0xE260 #USER DEFINED CHAR
+0xF36D 0xE261 #USER DEFINED CHAR
+0xF36E 0xE262 #USER DEFINED CHAR
+0xF36F 0xE263 #USER DEFINED CHAR
+0xF370 0xE264 #USER DEFINED CHAR
+0xF371 0xE265 #USER DEFINED CHAR
+0xF372 0xE266 #USER DEFINED CHAR
+0xF373 0xE267 #USER DEFINED CHAR
+0xF374 0xE268 #USER DEFINED CHAR
+0xF375 0xE269 #USER DEFINED CHAR
+0xF376 0xE26A #USER DEFINED CHAR
+0xF377 0xE26B #USER DEFINED CHAR
+0xF378 0xE26C #USER DEFINED CHAR
+0xF379 0xE26D #USER DEFINED CHAR
+0xF37A 0xE26E #USER DEFINED CHAR
+0xF37B 0xE26F #USER DEFINED CHAR
+0xF37C 0xE270 #USER DEFINED CHAR
+0xF37D 0xE271 #USER DEFINED CHAR
+0xF37E 0xE272 #USER DEFINED CHAR
+0xF380 0xE273 #USER DEFINED CHAR
+0xF381 0xE274 #USER DEFINED CHAR
+0xF382 0xE275 #USER DEFINED CHAR
+0xF383 0xE276 #USER DEFINED CHAR
+0xF384 0xE277 #USER DEFINED CHAR
+0xF385 0xE278 #USER DEFINED CHAR
+0xF386 0xE279 #USER DEFINED CHAR
+0xF387 0xE27A #USER DEFINED CHAR
+0xF388 0xE27B #USER DEFINED CHAR
+0xF389 0xE27C #USER DEFINED CHAR
+0xF38A 0xE27D #USER DEFINED CHAR
+0xF38B 0xE27E #USER DEFINED CHAR
+0xF38C 0xE27F #USER DEFINED CHAR
+0xF38D 0xE280 #USER DEFINED CHAR
+0xF38E 0xE281 #USER DEFINED CHAR
+0xF38F 0xE282 #USER DEFINED CHAR
+0xF390 0xE283 #USER DEFINED CHAR
+0xF391 0xE284 #USER DEFINED CHAR
+0xF392 0xE285 #USER DEFINED CHAR
+0xF393 0xE286 #USER DEFINED CHAR
+0xF394 0xE287 #USER DEFINED CHAR
+0xF395 0xE288 #USER DEFINED CHAR
+0xF396 0xE289 #USER DEFINED CHAR
+0xF397 0xE28A #USER DEFINED CHAR
+0xF398 0xE28B #USER DEFINED CHAR
+0xF399 0xE28C #USER DEFINED CHAR
+0xF39A 0xE28D #USER DEFINED CHAR
+0xF39B 0xE28E #USER DEFINED CHAR
+0xF39C 0xE28F #USER DEFINED CHAR
+0xF39D 0xE290 #USER DEFINED CHAR
+0xF39E 0xE291 #USER DEFINED CHAR
+0xF39F 0xE292 #USER DEFINED CHAR
+0xF3A0 0xE293 #USER DEFINED CHAR
+0xF3A1 0xE294 #USER DEFINED CHAR
+0xF3A2 0xE295 #USER DEFINED CHAR
+0xF3A3 0xE296 #USER DEFINED CHAR
+0xF3A4 0xE297 #USER DEFINED CHAR
+0xF3A5 0xE298 #USER DEFINED CHAR
+0xF3A6 0xE299 #USER DEFINED CHAR
+0xF3A7 0xE29A #USER DEFINED CHAR
+0xF3A8 0xE29B #USER DEFINED CHAR
+0xF3A9 0xE29C #USER DEFINED CHAR
+0xF3AA 0xE29D #USER DEFINED CHAR
+0xF3AB 0xE29E #USER DEFINED CHAR
+0xF3AC 0xE29F #USER DEFINED CHAR
+0xF3AD 0xE2A0 #USER DEFINED CHAR
+0xF3AE 0xE2A1 #USER DEFINED CHAR
+0xF3AF 0xE2A2 #USER DEFINED CHAR
+0xF3B0 0xE2A3 #USER DEFINED CHAR
+0xF3B1 0xE2A4 #USER DEFINED CHAR
+0xF3B2 0xE2A5 #USER DEFINED CHAR
+0xF3B3 0xE2A6 #USER DEFINED CHAR
+0xF3B4 0xE2A7 #USER DEFINED CHAR
+0xF3B5 0xE2A8 #USER DEFINED CHAR
+0xF3B6 0xE2A9 #USER DEFINED CHAR
+0xF3B7 0xE2AA #USER DEFINED CHAR
+0xF3B8 0xE2AB #USER DEFINED CHAR
+0xF3B9 0xE2AC #USER DEFINED CHAR
+0xF3BA 0xE2AD #USER DEFINED CHAR
+0xF3BB 0xE2AE #USER DEFINED CHAR
+0xF3BC 0xE2AF #USER DEFINED CHAR
+0xF3BD 0xE2B0 #USER DEFINED CHAR
+0xF3BE 0xE2B1 #USER DEFINED CHAR
+0xF3BF 0xE2B2 #USER DEFINED CHAR
+0xF3C0 0xE2B3 #USER DEFINED CHAR
+0xF3C1 0xE2B4 #USER DEFINED CHAR
+0xF3C2 0xE2B5 #USER DEFINED CHAR
+0xF3C3 0xE2B6 #USER DEFINED CHAR
+0xF3C4 0xE2B7 #USER DEFINED CHAR
+0xF3C5 0xE2B8 #USER DEFINED CHAR
+0xF3C6 0xE2B9 #USER DEFINED CHAR
+0xF3C7 0xE2BA #USER DEFINED CHAR
+0xF3C8 0xE2BB #USER DEFINED CHAR
+0xF3C9 0xE2BC #USER DEFINED CHAR
+0xF3CA 0xE2BD #USER DEFINED CHAR
+0xF3CB 0xE2BE #USER DEFINED CHAR
+0xF3CC 0xE2BF #USER DEFINED CHAR
+0xF3CD 0xE2C0 #USER DEFINED CHAR
+0xF3CE 0xE2C1 #USER DEFINED CHAR
+0xF3CF 0xE2C2 #USER DEFINED CHAR
+0xF3D0 0xE2C3 #USER DEFINED CHAR
+0xF3D1 0xE2C4 #USER DEFINED CHAR
+0xF3D2 0xE2C5 #USER DEFINED CHAR
+0xF3D3 0xE2C6 #USER DEFINED CHAR
+0xF3D4 0xE2C7 #USER DEFINED CHAR
+0xF3D5 0xE2C8 #USER DEFINED CHAR
+0xF3D6 0xE2C9 #USER DEFINED CHAR
+0xF3D7 0xE2CA #USER DEFINED CHAR
+0xF3D8 0xE2CB #USER DEFINED CHAR
+0xF3D9 0xE2CC #USER DEFINED CHAR
+0xF3DA 0xE2CD #USER DEFINED CHAR
+0xF3DB 0xE2CE #USER DEFINED CHAR
+0xF3DC 0xE2CF #USER DEFINED CHAR
+0xF3DD 0xE2D0 #USER DEFINED CHAR
+0xF3DE 0xE2D1 #USER DEFINED CHAR
+0xF3DF 0xE2D2 #USER DEFINED CHAR
+0xF3E0 0xE2D3 #USER DEFINED CHAR
+0xF3E1 0xE2D4 #USER DEFINED CHAR
+0xF3E2 0xE2D5 #USER DEFINED CHAR
+0xF3E3 0xE2D6 #USER DEFINED CHAR
+0xF3E4 0xE2D7 #USER DEFINED CHAR
+0xF3E5 0xE2D8 #USER DEFINED CHAR
+0xF3E6 0xE2D9 #USER DEFINED CHAR
+0xF3E7 0xE2DA #USER DEFINED CHAR
+0xF3E8 0xE2DB #USER DEFINED CHAR
+0xF3E9 0xE2DC #USER DEFINED CHAR
+0xF3EA 0xE2DD #USER DEFINED CHAR
+0xF3EB 0xE2DE #USER DEFINED CHAR
+0xF3EC 0xE2DF #USER DEFINED CHAR
+0xF3ED 0xE2E0 #USER DEFINED CHAR
+0xF3EE 0xE2E1 #USER DEFINED CHAR
+0xF3EF 0xE2E2 #USER DEFINED CHAR
+0xF3F0 0xE2E3 #USER DEFINED CHAR
+0xF3F1 0xE2E4 #USER DEFINED CHAR
+0xF3F2 0xE2E5 #USER DEFINED CHAR
+0xF3F3 0xE2E6 #USER DEFINED CHAR
+0xF3F4 0xE2E7 #USER DEFINED CHAR
+0xF3F5 0xE2E8 #USER DEFINED CHAR
+0xF3F6 0xE2E9 #USER DEFINED CHAR
+0xF3F7 0xE2EA #USER DEFINED CHAR
+0xF3F8 0xE2EB #USER DEFINED CHAR
+0xF3F9 0xE2EC #USER DEFINED CHAR
+0xF3FA 0xE2ED #USER DEFINED CHAR
+0xF3FB 0xE2EE #USER DEFINED CHAR
+0xF3FC 0xE2EF #USER DEFINED CHAR
+0xF440 0xE2F0 #USER DEFINED CHAR
+0xF441 0xE2F1 #USER DEFINED CHAR
+0xF442 0xE2F2 #USER DEFINED CHAR
+0xF443 0xE2F3 #USER DEFINED CHAR
+0xF444 0xE2F4 #USER DEFINED CHAR
+0xF445 0xE2F5 #USER DEFINED CHAR
+0xF446 0xE2F6 #USER DEFINED CHAR
+0xF447 0xE2F7 #USER DEFINED CHAR
+0xF448 0xE2F8 #USER DEFINED CHAR
+0xF449 0xE2F9 #USER DEFINED CHAR
+0xF44A 0xE2FA #USER DEFINED CHAR
+0xF44B 0xE2FB #USER DEFINED CHAR
+0xF44C 0xE2FC #USER DEFINED CHAR
+0xF44D 0xE2FD #USER DEFINED CHAR
+0xF44E 0xE2FE #USER DEFINED CHAR
+0xF44F 0xE2FF #USER DEFINED CHAR
+0xF450 0xE300 #USER DEFINED CHAR
+0xF451 0xE301 #USER DEFINED CHAR
+0xF452 0xE302 #USER DEFINED CHAR
+0xF453 0xE303 #USER DEFINED CHAR
+0xF454 0xE304 #USER DEFINED CHAR
+0xF455 0xE305 #USER DEFINED CHAR
+0xF456 0xE306 #USER DEFINED CHAR
+0xF457 0xE307 #USER DEFINED CHAR
+0xF458 0xE308 #USER DEFINED CHAR
+0xF459 0xE309 #USER DEFINED CHAR
+0xF45A 0xE30A #USER DEFINED CHAR
+0xF45B 0xE30B #USER DEFINED CHAR
+0xF45C 0xE30C #USER DEFINED CHAR
+0xF45D 0xE30D #USER DEFINED CHAR
+0xF45E 0xE30E #USER DEFINED CHAR
+0xF45F 0xE30F #USER DEFINED CHAR
+0xF460 0xE310 #USER DEFINED CHAR
+0xF461 0xE311 #USER DEFINED CHAR
+0xF462 0xE312 #USER DEFINED CHAR
+0xF463 0xE313 #USER DEFINED CHAR
+0xF464 0xE314 #USER DEFINED CHAR
+0xF465 0xE315 #USER DEFINED CHAR
+0xF466 0xE316 #USER DEFINED CHAR
+0xF467 0xE317 #USER DEFINED CHAR
+0xF468 0xE318 #USER DEFINED CHAR
+0xF469 0xE319 #USER DEFINED CHAR
+0xF46A 0xE31A #USER DEFINED CHAR
+0xF46B 0xE31B #USER DEFINED CHAR
+0xF46C 0xE31C #USER DEFINED CHAR
+0xF46D 0xE31D #USER DEFINED CHAR
+0xF46E 0xE31E #USER DEFINED CHAR
+0xF46F 0xE31F #USER DEFINED CHAR
+0xF470 0xE320 #USER DEFINED CHAR
+0xF471 0xE321 #USER DEFINED CHAR
+0xF472 0xE322 #USER DEFINED CHAR
+0xF473 0xE323 #USER DEFINED CHAR
+0xF474 0xE324 #USER DEFINED CHAR
+0xF475 0xE325 #USER DEFINED CHAR
+0xF476 0xE326 #USER DEFINED CHAR
+0xF477 0xE327 #USER DEFINED CHAR
+0xF478 0xE328 #USER DEFINED CHAR
+0xF479 0xE329 #USER DEFINED CHAR
+0xF47A 0xE32A #USER DEFINED CHAR
+0xF47B 0xE32B #USER DEFINED CHAR
+0xF47C 0xE32C #USER DEFINED CHAR
+0xF47D 0xE32D #USER DEFINED CHAR
+0xF47E 0xE32E #USER DEFINED CHAR
+0xF480 0xE32F #USER DEFINED CHAR
+0xF481 0xE330 #USER DEFINED CHAR
+0xF482 0xE331 #USER DEFINED CHAR
+0xF483 0xE332 #USER DEFINED CHAR
+0xF484 0xE333 #USER DEFINED CHAR
+0xF485 0xE334 #USER DEFINED CHAR
+0xF486 0xE335 #USER DEFINED CHAR
+0xF487 0xE336 #USER DEFINED CHAR
+0xF488 0xE337 #USER DEFINED CHAR
+0xF489 0xE338 #USER DEFINED CHAR
+0xF48A 0xE339 #USER DEFINED CHAR
+0xF48B 0xE33A #USER DEFINED CHAR
+0xF48C 0xE33B #USER DEFINED CHAR
+0xF48D 0xE33C #USER DEFINED CHAR
+0xF48E 0xE33D #USER DEFINED CHAR
+0xF48F 0xE33E #USER DEFINED CHAR
+0xF490 0xE33F #USER DEFINED CHAR
+0xF491 0xE340 #USER DEFINED CHAR
+0xF492 0xE341 #USER DEFINED CHAR
+0xF493 0xE342 #USER DEFINED CHAR
+0xF494 0xE343 #USER DEFINED CHAR
+0xF495 0xE344 #USER DEFINED CHAR
+0xF496 0xE345 #USER DEFINED CHAR
+0xF497 0xE346 #USER DEFINED CHAR
+0xF498 0xE347 #USER DEFINED CHAR
+0xF499 0xE348 #USER DEFINED CHAR
+0xF49A 0xE349 #USER DEFINED CHAR
+0xF49B 0xE34A #USER DEFINED CHAR
+0xF49C 0xE34B #USER DEFINED CHAR
+0xF49D 0xE34C #USER DEFINED CHAR
+0xF49E 0xE34D #USER DEFINED CHAR
+0xF49F 0xE34E #USER DEFINED CHAR
+0xF4A0 0xE34F #USER DEFINED CHAR
+0xF4A1 0xE350 #USER DEFINED CHAR
+0xF4A2 0xE351 #USER DEFINED CHAR
+0xF4A3 0xE352 #USER DEFINED CHAR
+0xF4A4 0xE353 #USER DEFINED CHAR
+0xF4A5 0xE354 #USER DEFINED CHAR
+0xF4A6 0xE355 #USER DEFINED CHAR
+0xF4A7 0xE356 #USER DEFINED CHAR
+0xF4A8 0xE357 #USER DEFINED CHAR
+0xF4A9 0xE358 #USER DEFINED CHAR
+0xF4AA 0xE359 #USER DEFINED CHAR
+0xF4AB 0xE35A #USER DEFINED CHAR
+0xF4AC 0xE35B #USER DEFINED CHAR
+0xF4AD 0xE35C #USER DEFINED CHAR
+0xF4AE 0xE35D #USER DEFINED CHAR
+0xF4AF 0xE35E #USER DEFINED CHAR
+0xF4B0 0xE35F #USER DEFINED CHAR
+0xF4B1 0xE360 #USER DEFINED CHAR
+0xF4B2 0xE361 #USER DEFINED CHAR
+0xF4B3 0xE362 #USER DEFINED CHAR
+0xF4B4 0xE363 #USER DEFINED CHAR
+0xF4B5 0xE364 #USER DEFINED CHAR
+0xF4B6 0xE365 #USER DEFINED CHAR
+0xF4B7 0xE366 #USER DEFINED CHAR
+0xF4B8 0xE367 #USER DEFINED CHAR
+0xF4B9 0xE368 #USER DEFINED CHAR
+0xF4BA 0xE369 #USER DEFINED CHAR
+0xF4BB 0xE36A #USER DEFINED CHAR
+0xF4BC 0xE36B #USER DEFINED CHAR
+0xF4BD 0xE36C #USER DEFINED CHAR
+0xF4BE 0xE36D #USER DEFINED CHAR
+0xF4BF 0xE36E #USER DEFINED CHAR
+0xF4C0 0xE36F #USER DEFINED CHAR
+0xF4C1 0xE370 #USER DEFINED CHAR
+0xF4C2 0xE371 #USER DEFINED CHAR
+0xF4C3 0xE372 #USER DEFINED CHAR
+0xF4C4 0xE373 #USER DEFINED CHAR
+0xF4C5 0xE374 #USER DEFINED CHAR
+0xF4C6 0xE375 #USER DEFINED CHAR
+0xF4C7 0xE376 #USER DEFINED CHAR
+0xF4C8 0xE377 #USER DEFINED CHAR
+0xF4C9 0xE378 #USER DEFINED CHAR
+0xF4CA 0xE379 #USER DEFINED CHAR
+0xF4CB 0xE37A #USER DEFINED CHAR
+0xF4CC 0xE37B #USER DEFINED CHAR
+0xF4CD 0xE37C #USER DEFINED CHAR
+0xF4CE 0xE37D #USER DEFINED CHAR
+0xF4CF 0xE37E #USER DEFINED CHAR
+0xF4D0 0xE37F #USER DEFINED CHAR
+0xF4D1 0xE380 #USER DEFINED CHAR
+0xF4D2 0xE381 #USER DEFINED CHAR
+0xF4D3 0xE382 #USER DEFINED CHAR
+0xF4D4 0xE383 #USER DEFINED CHAR
+0xF4D5 0xE384 #USER DEFINED CHAR
+0xF4D6 0xE385 #USER DEFINED CHAR
+0xF4D7 0xE386 #USER DEFINED CHAR
+0xF4D8 0xE387 #USER DEFINED CHAR
+0xF4D9 0xE388 #USER DEFINED CHAR
+0xF4DA 0xE389 #USER DEFINED CHAR
+0xF4DB 0xE38A #USER DEFINED CHAR
+0xF4DC 0xE38B #USER DEFINED CHAR
+0xF4DD 0xE38C #USER DEFINED CHAR
+0xF4DE 0xE38D #USER DEFINED CHAR
+0xF4DF 0xE38E #USER DEFINED CHAR
+0xF4E0 0xE38F #USER DEFINED CHAR
+0xF4E1 0xE390 #USER DEFINED CHAR
+0xF4E2 0xE391 #USER DEFINED CHAR
+0xF4E3 0xE392 #USER DEFINED CHAR
+0xF4E4 0xE393 #USER DEFINED CHAR
+0xF4E5 0xE394 #USER DEFINED CHAR
+0xF4E6 0xE395 #USER DEFINED CHAR
+0xF4E7 0xE396 #USER DEFINED CHAR
+0xF4E8 0xE397 #USER DEFINED CHAR
+0xF4E9 0xE398 #USER DEFINED CHAR
+0xF4EA 0xE399 #USER DEFINED CHAR
+0xF4EB 0xE39A #USER DEFINED CHAR
+0xF4EC 0xE39B #USER DEFINED CHAR
+0xF4ED 0xE39C #USER DEFINED CHAR
+0xF4EE 0xE39D #USER DEFINED CHAR
+0xF4EF 0xE39E #USER DEFINED CHAR
+0xF4F0 0xE39F #USER DEFINED CHAR
+0xF4F1 0xE3A0 #USER DEFINED CHAR
+0xF4F2 0xE3A1 #USER DEFINED CHAR
+0xF4F3 0xE3A2 #USER DEFINED CHAR
+0xF4F4 0xE3A3 #USER DEFINED CHAR
+0xF4F5 0xE3A4 #USER DEFINED CHAR
+0xF4F6 0xE3A5 #USER DEFINED CHAR
+0xF4F7 0xE3A6 #USER DEFINED CHAR
+0xF4F8 0xE3A7 #USER DEFINED CHAR
+0xF4F9 0xE3A8 #USER DEFINED CHAR
+0xF4FA 0xE3A9 #USER DEFINED CHAR
+0xF4FB 0xE3AA #USER DEFINED CHAR
+0xF4FC 0xE3AB #USER DEFINED CHAR
+0xF540 0xE3AC #USER DEFINED CHAR
+0xF541 0xE3AD #USER DEFINED CHAR
+0xF542 0xE3AE #USER DEFINED CHAR
+0xF543 0xE3AF #USER DEFINED CHAR
+0xF544 0xE3B0 #USER DEFINED CHAR
+0xF545 0xE3B1 #USER DEFINED CHAR
+0xF546 0xE3B2 #USER DEFINED CHAR
+0xF547 0xE3B3 #USER DEFINED CHAR
+0xF548 0xE3B4 #USER DEFINED CHAR
+0xF549 0xE3B5 #USER DEFINED CHAR
+0xF54A 0xE3B6 #USER DEFINED CHAR
+0xF54B 0xE3B7 #USER DEFINED CHAR
+0xF54C 0xE3B8 #USER DEFINED CHAR
+0xF54D 0xE3B9 #USER DEFINED CHAR
+0xF54E 0xE3BA #USER DEFINED CHAR
+0xF54F 0xE3BB #USER DEFINED CHAR
+0xF550 0xE3BC #USER DEFINED CHAR
+0xF551 0xE3BD #USER DEFINED CHAR
+0xF552 0xE3BE #USER DEFINED CHAR
+0xF553 0xE3BF #USER DEFINED CHAR
+0xF554 0xE3C0 #USER DEFINED CHAR
+0xF555 0xE3C1 #USER DEFINED CHAR
+0xF556 0xE3C2 #USER DEFINED CHAR
+0xF557 0xE3C3 #USER DEFINED CHAR
+0xF558 0xE3C4 #USER DEFINED CHAR
+0xF559 0xE3C5 #USER DEFINED CHAR
+0xF55A 0xE3C6 #USER DEFINED CHAR
+0xF55B 0xE3C7 #USER DEFINED CHAR
+0xF55C 0xE3C8 #USER DEFINED CHAR
+0xF55D 0xE3C9 #USER DEFINED CHAR
+0xF55E 0xE3CA #USER DEFINED CHAR
+0xF55F 0xE3CB #USER DEFINED CHAR
+0xF560 0xE3CC #USER DEFINED CHAR
+0xF561 0xE3CD #USER DEFINED CHAR
+0xF562 0xE3CE #USER DEFINED CHAR
+0xF563 0xE3CF #USER DEFINED CHAR
+0xF564 0xE3D0 #USER DEFINED CHAR
+0xF565 0xE3D1 #USER DEFINED CHAR
+0xF566 0xE3D2 #USER DEFINED CHAR
+0xF567 0xE3D3 #USER DEFINED CHAR
+0xF568 0xE3D4 #USER DEFINED CHAR
+0xF569 0xE3D5 #USER DEFINED CHAR
+0xF56A 0xE3D6 #USER DEFINED CHAR
+0xF56B 0xE3D7 #USER DEFINED CHAR
+0xF56C 0xE3D8 #USER DEFINED CHAR
+0xF56D 0xE3D9 #USER DEFINED CHAR
+0xF56E 0xE3DA #USER DEFINED CHAR
+0xF56F 0xE3DB #USER DEFINED CHAR
+0xF570 0xE3DC #USER DEFINED CHAR
+0xF571 0xE3DD #USER DEFINED CHAR
+0xF572 0xE3DE #USER DEFINED CHAR
+0xF573 0xE3DF #USER DEFINED CHAR
+0xF574 0xE3E0 #USER DEFINED CHAR
+0xF575 0xE3E1 #USER DEFINED CHAR
+0xF576 0xE3E2 #USER DEFINED CHAR
+0xF577 0xE3E3 #USER DEFINED CHAR
+0xF578 0xE3E4 #USER DEFINED CHAR
+0xF579 0xE3E5 #USER DEFINED CHAR
+0xF57A 0xE3E6 #USER DEFINED CHAR
+0xF57B 0xE3E7 #USER DEFINED CHAR
+0xF57C 0xE3E8 #USER DEFINED CHAR
+0xF57D 0xE3E9 #USER DEFINED CHAR
+0xF57E 0xE3EA #USER DEFINED CHAR
+0xF580 0xE3EB #USER DEFINED CHAR
+0xF581 0xE3EC #USER DEFINED CHAR
+0xF582 0xE3ED #USER DEFINED CHAR
+0xF583 0xE3EE #USER DEFINED CHAR
+0xF584 0xE3EF #USER DEFINED CHAR
+0xF585 0xE3F0 #USER DEFINED CHAR
+0xF586 0xE3F1 #USER DEFINED CHAR
+0xF587 0xE3F2 #USER DEFINED CHAR
+0xF588 0xE3F3 #USER DEFINED CHAR
+0xF589 0xE3F4 #USER DEFINED CHAR
+0xF58A 0xE3F5 #USER DEFINED CHAR
+0xF58B 0xE3F6 #USER DEFINED CHAR
+0xF58C 0xE3F7 #USER DEFINED CHAR
+0xF58D 0xE3F8 #USER DEFINED CHAR
+0xF58E 0xE3F9 #USER DEFINED CHAR
+0xF58F 0xE3FA #USER DEFINED CHAR
+0xF590 0xE3FB #USER DEFINED CHAR
+0xF591 0xE3FC #USER DEFINED CHAR
+0xF592 0xE3FD #USER DEFINED CHAR
+0xF593 0xE3FE #USER DEFINED CHAR
+0xF594 0xE3FF #USER DEFINED CHAR
+0xF595 0xE400 #USER DEFINED CHAR
+0xF596 0xE401 #USER DEFINED CHAR
+0xF597 0xE402 #USER DEFINED CHAR
+0xF598 0xE403 #USER DEFINED CHAR
+0xF599 0xE404 #USER DEFINED CHAR
+0xF59A 0xE405 #USER DEFINED CHAR
+0xF59B 0xE406 #USER DEFINED CHAR
+0xF59C 0xE407 #USER DEFINED CHAR
+0xF59D 0xE408 #USER DEFINED CHAR
+0xF59E 0xE409 #USER DEFINED CHAR
+0xF59F 0xE40A #USER DEFINED CHAR
+0xF5A0 0xE40B #USER DEFINED CHAR
+0xF5A1 0xE40C #USER DEFINED CHAR
+0xF5A2 0xE40D #USER DEFINED CHAR
+0xF5A3 0xE40E #USER DEFINED CHAR
+0xF5A4 0xE40F #USER DEFINED CHAR
+0xF5A5 0xE410 #USER DEFINED CHAR
+0xF5A6 0xE411 #USER DEFINED CHAR
+0xF5A7 0xE412 #USER DEFINED CHAR
+0xF5A8 0xE413 #USER DEFINED CHAR
+0xF5A9 0xE414 #USER DEFINED CHAR
+0xF5AA 0xE415 #USER DEFINED CHAR
+0xF5AB 0xE416 #USER DEFINED CHAR
+0xF5AC 0xE417 #USER DEFINED CHAR
+0xF5AD 0xE418 #USER DEFINED CHAR
+0xF5AE 0xE419 #USER DEFINED CHAR
+0xF5AF 0xE41A #USER DEFINED CHAR
+0xF5B0 0xE41B #USER DEFINED CHAR
+0xF5B1 0xE41C #USER DEFINED CHAR
+0xF5B2 0xE41D #USER DEFINED CHAR
+0xF5B3 0xE41E #USER DEFINED CHAR
+0xF5B4 0xE41F #USER DEFINED CHAR
+0xF5B5 0xE420 #USER DEFINED CHAR
+0xF5B6 0xE421 #USER DEFINED CHAR
+0xF5B7 0xE422 #USER DEFINED CHAR
+0xF5B8 0xE423 #USER DEFINED CHAR
+0xF5B9 0xE424 #USER DEFINED CHAR
+0xF5BA 0xE425 #USER DEFINED CHAR
+0xF5BB 0xE426 #USER DEFINED CHAR
+0xF5BC 0xE427 #USER DEFINED CHAR
+0xF5BD 0xE428 #USER DEFINED CHAR
+0xF5BE 0xE429 #USER DEFINED CHAR
+0xF5BF 0xE42A #USER DEFINED CHAR
+0xF5C0 0xE42B #USER DEFINED CHAR
+0xF5C1 0xE42C #USER DEFINED CHAR
+0xF5C2 0xE42D #USER DEFINED CHAR
+0xF5C3 0xE42E #USER DEFINED CHAR
+0xF5C4 0xE42F #USER DEFINED CHAR
+0xF5C5 0xE430 #USER DEFINED CHAR
+0xF5C6 0xE431 #USER DEFINED CHAR
+0xF5C7 0xE432 #USER DEFINED CHAR
+0xF5C8 0xE433 #USER DEFINED CHAR
+0xF5C9 0xE434 #USER DEFINED CHAR
+0xF5CA 0xE435 #USER DEFINED CHAR
+0xF5CB 0xE436 #USER DEFINED CHAR
+0xF5CC 0xE437 #USER DEFINED CHAR
+0xF5CD 0xE438 #USER DEFINED CHAR
+0xF5CE 0xE439 #USER DEFINED CHAR
+0xF5CF 0xE43A #USER DEFINED CHAR
+0xF5D0 0xE43B #USER DEFINED CHAR
+0xF5D1 0xE43C #USER DEFINED CHAR
+0xF5D2 0xE43D #USER DEFINED CHAR
+0xF5D3 0xE43E #USER DEFINED CHAR
+0xF5D4 0xE43F #USER DEFINED CHAR
+0xF5D5 0xE440 #USER DEFINED CHAR
+0xF5D6 0xE441 #USER DEFINED CHAR
+0xF5D7 0xE442 #USER DEFINED CHAR
+0xF5D8 0xE443 #USER DEFINED CHAR
+0xF5D9 0xE444 #USER DEFINED CHAR
+0xF5DA 0xE445 #USER DEFINED CHAR
+0xF5DB 0xE446 #USER DEFINED CHAR
+0xF5DC 0xE447 #USER DEFINED CHAR
+0xF5DD 0xE448 #USER DEFINED CHAR
+0xF5DE 0xE449 #USER DEFINED CHAR
+0xF5DF 0xE44A #USER DEFINED CHAR
+0xF5E0 0xE44B #USER DEFINED CHAR
+0xF5E1 0xE44C #USER DEFINED CHAR
+0xF5E2 0xE44D #USER DEFINED CHAR
+0xF5E3 0xE44E #USER DEFINED CHAR
+0xF5E4 0xE44F #USER DEFINED CHAR
+0xF5E5 0xE450 #USER DEFINED CHAR
+0xF5E6 0xE451 #USER DEFINED CHAR
+0xF5E7 0xE452 #USER DEFINED CHAR
+0xF5E8 0xE453 #USER DEFINED CHAR
+0xF5E9 0xE454 #USER DEFINED CHAR
+0xF5EA 0xE455 #USER DEFINED CHAR
+0xF5EB 0xE456 #USER DEFINED CHAR
+0xF5EC 0xE457 #USER DEFINED CHAR
+0xF5ED 0xE458 #USER DEFINED CHAR
+0xF5EE 0xE459 #USER DEFINED CHAR
+0xF5EF 0xE45A #USER DEFINED CHAR
+0xF5F0 0xE45B #USER DEFINED CHAR
+0xF5F1 0xE45C #USER DEFINED CHAR
+0xF5F2 0xE45D #USER DEFINED CHAR
+0xF5F3 0xE45E #USER DEFINED CHAR
+0xF5F4 0xE45F #USER DEFINED CHAR
+0xF5F5 0xE460 #USER DEFINED CHAR
+0xF5F6 0xE461 #USER DEFINED CHAR
+0xF5F7 0xE462 #USER DEFINED CHAR
+0xF5F8 0xE463 #USER DEFINED CHAR
+0xF5F9 0xE464 #USER DEFINED CHAR
+0xF5FA 0xE465 #USER DEFINED CHAR
+0xF5FB 0xE466 #USER DEFINED CHAR
+0xF5FC 0xE467 #USER DEFINED CHAR
+0xF640 0xE468 #USER DEFINED CHAR
+0xF641 0xE469 #USER DEFINED CHAR
+0xF642 0xE46A #USER DEFINED CHAR
+0xF643 0xE46B #USER DEFINED CHAR
+0xF644 0xE46C #USER DEFINED CHAR
+0xF645 0xE46D #USER DEFINED CHAR
+0xF646 0xE46E #USER DEFINED CHAR
+0xF647 0xE46F #USER DEFINED CHAR
+0xF648 0xE470 #USER DEFINED CHAR
+0xF649 0xE471 #USER DEFINED CHAR
+0xF64A 0xE472 #USER DEFINED CHAR
+0xF64B 0xE473 #USER DEFINED CHAR
+0xF64C 0xE474 #USER DEFINED CHAR
+0xF64D 0xE475 #USER DEFINED CHAR
+0xF64E 0xE476 #USER DEFINED CHAR
+0xF64F 0xE477 #USER DEFINED CHAR
+0xF650 0xE478 #USER DEFINED CHAR
+0xF651 0xE479 #USER DEFINED CHAR
+0xF652 0xE47A #USER DEFINED CHAR
+0xF653 0xE47B #USER DEFINED CHAR
+0xF654 0xE47C #USER DEFINED CHAR
+0xF655 0xE47D #USER DEFINED CHAR
+0xF656 0xE47E #USER DEFINED CHAR
+0xF657 0xE47F #USER DEFINED CHAR
+0xF658 0xE480 #USER DEFINED CHAR
+0xF659 0xE481 #USER DEFINED CHAR
+0xF65A 0xE482 #USER DEFINED CHAR
+0xF65B 0xE483 #USER DEFINED CHAR
+0xF65C 0xE484 #USER DEFINED CHAR
+0xF65D 0xE485 #USER DEFINED CHAR
+0xF65E 0xE486 #USER DEFINED CHAR
+0xF65F 0xE487 #USER DEFINED CHAR
+0xF660 0xE488 #USER DEFINED CHAR
+0xF661 0xE489 #USER DEFINED CHAR
+0xF662 0xE48A #USER DEFINED CHAR
+0xF663 0xE48B #USER DEFINED CHAR
+0xF664 0xE48C #USER DEFINED CHAR
+0xF665 0xE48D #USER DEFINED CHAR
+0xF666 0xE48E #USER DEFINED CHAR
+0xF667 0xE48F #USER DEFINED CHAR
+0xF668 0xE490 #USER DEFINED CHAR
+0xF669 0xE491 #USER DEFINED CHAR
+0xF66A 0xE492 #USER DEFINED CHAR
+0xF66B 0xE493 #USER DEFINED CHAR
+0xF66C 0xE494 #USER DEFINED CHAR
+0xF66D 0xE495 #USER DEFINED CHAR
+0xF66E 0xE496 #USER DEFINED CHAR
+0xF66F 0xE497 #USER DEFINED CHAR
+0xF670 0xE498 #USER DEFINED CHAR
+0xF671 0xE499 #USER DEFINED CHAR
+0xF672 0xE49A #USER DEFINED CHAR
+0xF673 0xE49B #USER DEFINED CHAR
+0xF674 0xE49C #USER DEFINED CHAR
+0xF675 0xE49D #USER DEFINED CHAR
+0xF676 0xE49E #USER DEFINED CHAR
+0xF677 0xE49F #USER DEFINED CHAR
+0xF678 0xE4A0 #USER DEFINED CHAR
+0xF679 0xE4A1 #USER DEFINED CHAR
+0xF67A 0xE4A2 #USER DEFINED CHAR
+0xF67B 0xE4A3 #USER DEFINED CHAR
+0xF67C 0xE4A4 #USER DEFINED CHAR
+0xF67D 0xE4A5 #USER DEFINED CHAR
+0xF67E 0xE4A6 #USER DEFINED CHAR
+0xF680 0xE4A7 #USER DEFINED CHAR
+0xF681 0xE4A8 #USER DEFINED CHAR
+0xF682 0xE4A9 #USER DEFINED CHAR
+0xF683 0xE4AA #USER DEFINED CHAR
+0xF684 0xE4AB #USER DEFINED CHAR
+0xF685 0xE4AC #USER DEFINED CHAR
+0xF686 0xE4AD #USER DEFINED CHAR
+0xF687 0xE4AE #USER DEFINED CHAR
+0xF688 0xE4AF #USER DEFINED CHAR
+0xF689 0xE4B0 #USER DEFINED CHAR
+0xF68A 0xE4B1 #USER DEFINED CHAR
+0xF68B 0xE4B2 #USER DEFINED CHAR
+0xF68C 0xE4B3 #USER DEFINED CHAR
+0xF68D 0xE4B4 #USER DEFINED CHAR
+0xF68E 0xE4B5 #USER DEFINED CHAR
+0xF68F 0xE4B6 #USER DEFINED CHAR
+0xF690 0xE4B7 #USER DEFINED CHAR
+0xF691 0xE4B8 #USER DEFINED CHAR
+0xF692 0xE4B9 #USER DEFINED CHAR
+0xF693 0xE4BA #USER DEFINED CHAR
+0xF694 0xE4BB #USER DEFINED CHAR
+0xF695 0xE4BC #USER DEFINED CHAR
+0xF696 0xE4BD #USER DEFINED CHAR
+0xF697 0xE4BE #USER DEFINED CHAR
+0xF698 0xE4BF #USER DEFINED CHAR
+0xF699 0xE4C0 #USER DEFINED CHAR
+0xF69A 0xE4C1 #USER DEFINED CHAR
+0xF69B 0xE4C2 #USER DEFINED CHAR
+0xF69C 0xE4C3 #USER DEFINED CHAR
+0xF69D 0xE4C4 #USER DEFINED CHAR
+0xF69E 0xE4C5 #USER DEFINED CHAR
+0xF69F 0xE4C6 #USER DEFINED CHAR
+0xF6A0 0xE4C7 #USER DEFINED CHAR
+0xF6A1 0xE4C8 #USER DEFINED CHAR
+0xF6A2 0xE4C9 #USER DEFINED CHAR
+0xF6A3 0xE4CA #USER DEFINED CHAR
+0xF6A4 0xE4CB #USER DEFINED CHAR
+0xF6A5 0xE4CC #USER DEFINED CHAR
+0xF6A6 0xE4CD #USER DEFINED CHAR
+0xF6A7 0xE4CE #USER DEFINED CHAR
+0xF6A8 0xE4CF #USER DEFINED CHAR
+0xF6A9 0xE4D0 #USER DEFINED CHAR
+0xF6AA 0xE4D1 #USER DEFINED CHAR
+0xF6AB 0xE4D2 #USER DEFINED CHAR
+0xF6AC 0xE4D3 #USER DEFINED CHAR
+0xF6AD 0xE4D4 #USER DEFINED CHAR
+0xF6AE 0xE4D5 #USER DEFINED CHAR
+0xF6AF 0xE4D6 #USER DEFINED CHAR
+0xF6B0 0xE4D7 #USER DEFINED CHAR
+0xF6B1 0xE4D8 #USER DEFINED CHAR
+0xF6B2 0xE4D9 #USER DEFINED CHAR
+0xF6B3 0xE4DA #USER DEFINED CHAR
+0xF6B4 0xE4DB #USER DEFINED CHAR
+0xF6B5 0xE4DC #USER DEFINED CHAR
+0xF6B6 0xE4DD #USER DEFINED CHAR
+0xF6B7 0xE4DE #USER DEFINED CHAR
+0xF6B8 0xE4DF #USER DEFINED CHAR
+0xF6B9 0xE4E0 #USER DEFINED CHAR
+0xF6BA 0xE4E1 #USER DEFINED CHAR
+0xF6BB 0xE4E2 #USER DEFINED CHAR
+0xF6BC 0xE4E3 #USER DEFINED CHAR
+0xF6BD 0xE4E4 #USER DEFINED CHAR
+0xF6BE 0xE4E5 #USER DEFINED CHAR
+0xF6BF 0xE4E6 #USER DEFINED CHAR
+0xF6C0 0xE4E7 #USER DEFINED CHAR
+0xF6C1 0xE4E8 #USER DEFINED CHAR
+0xF6C2 0xE4E9 #USER DEFINED CHAR
+0xF6C3 0xE4EA #USER DEFINED CHAR
+0xF6C4 0xE4EB #USER DEFINED CHAR
+0xF6C5 0xE4EC #USER DEFINED CHAR
+0xF6C6 0xE4ED #USER DEFINED CHAR
+0xF6C7 0xE4EE #USER DEFINED CHAR
+0xF6C8 0xE4EF #USER DEFINED CHAR
+0xF6C9 0xE4F0 #USER DEFINED CHAR
+0xF6CA 0xE4F1 #USER DEFINED CHAR
+0xF6CB 0xE4F2 #USER DEFINED CHAR
+0xF6CC 0xE4F3 #USER DEFINED CHAR
+0xF6CD 0xE4F4 #USER DEFINED CHAR
+0xF6CE 0xE4F5 #USER DEFINED CHAR
+0xF6CF 0xE4F6 #USER DEFINED CHAR
+0xF6D0 0xE4F7 #USER DEFINED CHAR
+0xF6D1 0xE4F8 #USER DEFINED CHAR
+0xF6D2 0xE4F9 #USER DEFINED CHAR
+0xF6D3 0xE4FA #USER DEFINED CHAR
+0xF6D4 0xE4FB #USER DEFINED CHAR
+0xF6D5 0xE4FC #USER DEFINED CHAR
+0xF6D6 0xE4FD #USER DEFINED CHAR
+0xF6D7 0xE4FE #USER DEFINED CHAR
+0xF6D8 0xE4FF #USER DEFINED CHAR
+0xF6D9 0xE500 #USER DEFINED CHAR
+0xF6DA 0xE501 #USER DEFINED CHAR
+0xF6DB 0xE502 #USER DEFINED CHAR
+0xF6DC 0xE503 #USER DEFINED CHAR
+0xF6DD 0xE504 #USER DEFINED CHAR
+0xF6DE 0xE505 #USER DEFINED CHAR
+0xF6DF 0xE506 #USER DEFINED CHAR
+0xF6E0 0xE507 #USER DEFINED CHAR
+0xF6E1 0xE508 #USER DEFINED CHAR
+0xF6E2 0xE509 #USER DEFINED CHAR
+0xF6E3 0xE50A #USER DEFINED CHAR
+0xF6E4 0xE50B #USER DEFINED CHAR
+0xF6E5 0xE50C #USER DEFINED CHAR
+0xF6E6 0xE50D #USER DEFINED CHAR
+0xF6E7 0xE50E #USER DEFINED CHAR
+0xF6E8 0xE50F #USER DEFINED CHAR
+0xF6E9 0xE510 #USER DEFINED CHAR
+0xF6EA 0xE511 #USER DEFINED CHAR
+0xF6EB 0xE512 #USER DEFINED CHAR
+0xF6EC 0xE513 #USER DEFINED CHAR
+0xF6ED 0xE514 #USER DEFINED CHAR
+0xF6EE 0xE515 #USER DEFINED CHAR
+0xF6EF 0xE516 #USER DEFINED CHAR
+0xF6F0 0xE517 #USER DEFINED CHAR
+0xF6F1 0xE518 #USER DEFINED CHAR
+0xF6F2 0xE519 #USER DEFINED CHAR
+0xF6F3 0xE51A #USER DEFINED CHAR
+0xF6F4 0xE51B #USER DEFINED CHAR
+0xF6F5 0xE51C #USER DEFINED CHAR
+0xF6F6 0xE51D #USER DEFINED CHAR
+0xF6F7 0xE51E #USER DEFINED CHAR
+0xF6F8 0xE51F #USER DEFINED CHAR
+0xF6F9 0xE520 #USER DEFINED CHAR
+0xF6FA 0xE521 #USER DEFINED CHAR
+0xF6FB 0xE522 #USER DEFINED CHAR
+0xF6FC 0xE523 #USER DEFINED CHAR
+0xF740 0xE524 #USER DEFINED CHAR
+0xF741 0xE525 #USER DEFINED CHAR
+0xF742 0xE526 #USER DEFINED CHAR
+0xF743 0xE527 #USER DEFINED CHAR
+0xF744 0xE528 #USER DEFINED CHAR
+0xF745 0xE529 #USER DEFINED CHAR
+0xF746 0xE52A #USER DEFINED CHAR
+0xF747 0xE52B #USER DEFINED CHAR
+0xF748 0xE52C #USER DEFINED CHAR
+0xF749 0xE52D #USER DEFINED CHAR
+0xF74A 0xE52E #USER DEFINED CHAR
+0xF74B 0xE52F #USER DEFINED CHAR
+0xF74C 0xE530 #USER DEFINED CHAR
+0xF74D 0xE531 #USER DEFINED CHAR
+0xF74E 0xE532 #USER DEFINED CHAR
+0xF74F 0xE533 #USER DEFINED CHAR
+0xF750 0xE534 #USER DEFINED CHAR
+0xF751 0xE535 #USER DEFINED CHAR
+0xF752 0xE536 #USER DEFINED CHAR
+0xF753 0xE537 #USER DEFINED CHAR
+0xF754 0xE538 #USER DEFINED CHAR
+0xF755 0xE539 #USER DEFINED CHAR
+0xF756 0xE53A #USER DEFINED CHAR
+0xF757 0xE53B #USER DEFINED CHAR
+0xF758 0xE53C #USER DEFINED CHAR
+0xF759 0xE53D #USER DEFINED CHAR
+0xF75A 0xE53E #USER DEFINED CHAR
+0xF75B 0xE53F #USER DEFINED CHAR
+0xF75C 0xE540 #USER DEFINED CHAR
+0xF75D 0xE541 #USER DEFINED CHAR
+0xF75E 0xE542 #USER DEFINED CHAR
+0xF75F 0xE543 #USER DEFINED CHAR
+0xF760 0xE544 #USER DEFINED CHAR
+0xF761 0xE545 #USER DEFINED CHAR
+0xF762 0xE546 #USER DEFINED CHAR
+0xF763 0xE547 #USER DEFINED CHAR
+0xF764 0xE548 #USER DEFINED CHAR
+0xF765 0xE549 #USER DEFINED CHAR
+0xF766 0xE54A #USER DEFINED CHAR
+0xF767 0xE54B #USER DEFINED CHAR
+0xF768 0xE54C #USER DEFINED CHAR
+0xF769 0xE54D #USER DEFINED CHAR
+0xF76A 0xE54E #USER DEFINED CHAR
+0xF76B 0xE54F #USER DEFINED CHAR
+0xF76C 0xE550 #USER DEFINED CHAR
+0xF76D 0xE551 #USER DEFINED CHAR
+0xF76E 0xE552 #USER DEFINED CHAR
+0xF76F 0xE553 #USER DEFINED CHAR
+0xF770 0xE554 #USER DEFINED CHAR
+0xF771 0xE555 #USER DEFINED CHAR
+0xF772 0xE556 #USER DEFINED CHAR
+0xF773 0xE557 #USER DEFINED CHAR
+0xF774 0xE558 #USER DEFINED CHAR
+0xF775 0xE559 #USER DEFINED CHAR
+0xF776 0xE55A #USER DEFINED CHAR
+0xF777 0xE55B #USER DEFINED CHAR
+0xF778 0xE55C #USER DEFINED CHAR
+0xF779 0xE55D #USER DEFINED CHAR
+0xF77A 0xE55E #USER DEFINED CHAR
+0xF77B 0xE55F #USER DEFINED CHAR
+0xF77C 0xE560 #USER DEFINED CHAR
+0xF77D 0xE561 #USER DEFINED CHAR
+0xF77E 0xE562 #USER DEFINED CHAR
+0xF780 0xE563 #USER DEFINED CHAR
+0xF781 0xE564 #USER DEFINED CHAR
+0xF782 0xE565 #USER DEFINED CHAR
+0xF783 0xE566 #USER DEFINED CHAR
+0xF784 0xE567 #USER DEFINED CHAR
+0xF785 0xE568 #USER DEFINED CHAR
+0xF786 0xE569 #USER DEFINED CHAR
+0xF787 0xE56A #USER DEFINED CHAR
+0xF788 0xE56B #USER DEFINED CHAR
+0xF789 0xE56C #USER DEFINED CHAR
+0xF78A 0xE56D #USER DEFINED CHAR
+0xF78B 0xE56E #USER DEFINED CHAR
+0xF78C 0xE56F #USER DEFINED CHAR
+0xF78D 0xE570 #USER DEFINED CHAR
+0xF78E 0xE571 #USER DEFINED CHAR
+0xF78F 0xE572 #USER DEFINED CHAR
+0xF790 0xE573 #USER DEFINED CHAR
+0xF791 0xE574 #USER DEFINED CHAR
+0xF792 0xE575 #USER DEFINED CHAR
+0xF793 0xE576 #USER DEFINED CHAR
+0xF794 0xE577 #USER DEFINED CHAR
+0xF795 0xE578 #USER DEFINED CHAR
+0xF796 0xE579 #USER DEFINED CHAR
+0xF797 0xE57A #USER DEFINED CHAR
+0xF798 0xE57B #USER DEFINED CHAR
+0xF799 0xE57C #USER DEFINED CHAR
+0xF79A 0xE57D #USER DEFINED CHAR
+0xF79B 0xE57E #USER DEFINED CHAR
+0xF79C 0xE57F #USER DEFINED CHAR
+0xF79D 0xE580 #USER DEFINED CHAR
+0xF79E 0xE581 #USER DEFINED CHAR
+0xF79F 0xE582 #USER DEFINED CHAR
+0xF7A0 0xE583 #USER DEFINED CHAR
+0xF7A1 0xE584 #USER DEFINED CHAR
+0xF7A2 0xE585 #USER DEFINED CHAR
+0xF7A3 0xE586 #USER DEFINED CHAR
+0xF7A4 0xE587 #USER DEFINED CHAR
+0xF7A5 0xE588 #USER DEFINED CHAR
+0xF7A6 0xE589 #USER DEFINED CHAR
+0xF7A7 0xE58A #USER DEFINED CHAR
+0xF7A8 0xE58B #USER DEFINED CHAR
+0xF7A9 0xE58C #USER DEFINED CHAR
+0xF7AA 0xE58D #USER DEFINED CHAR
+0xF7AB 0xE58E #USER DEFINED CHAR
+0xF7AC 0xE58F #USER DEFINED CHAR
+0xF7AD 0xE590 #USER DEFINED CHAR
+0xF7AE 0xE591 #USER DEFINED CHAR
+0xF7AF 0xE592 #USER DEFINED CHAR
+0xF7B0 0xE593 #USER DEFINED CHAR
+0xF7B1 0xE594 #USER DEFINED CHAR
+0xF7B2 0xE595 #USER DEFINED CHAR
+0xF7B3 0xE596 #USER DEFINED CHAR
+0xF7B4 0xE597 #USER DEFINED CHAR
+0xF7B5 0xE598 #USER DEFINED CHAR
+0xF7B6 0xE599 #USER DEFINED CHAR
+0xF7B7 0xE59A #USER DEFINED CHAR
+0xF7B8 0xE59B #USER DEFINED CHAR
+0xF7B9 0xE59C #USER DEFINED CHAR
+0xF7BA 0xE59D #USER DEFINED CHAR
+0xF7BB 0xE59E #USER DEFINED CHAR
+0xF7BC 0xE59F #USER DEFINED CHAR
+0xF7BD 0xE5A0 #USER DEFINED CHAR
+0xF7BE 0xE5A1 #USER DEFINED CHAR
+0xF7BF 0xE5A2 #USER DEFINED CHAR
+0xF7C0 0xE5A3 #USER DEFINED CHAR
+0xF7C1 0xE5A4 #USER DEFINED CHAR
+0xF7C2 0xE5A5 #USER DEFINED CHAR
+0xF7C3 0xE5A6 #USER DEFINED CHAR
+0xF7C4 0xE5A7 #USER DEFINED CHAR
+0xF7C5 0xE5A8 #USER DEFINED CHAR
+0xF7C6 0xE5A9 #USER DEFINED CHAR
+0xF7C7 0xE5AA #USER DEFINED CHAR
+0xF7C8 0xE5AB #USER DEFINED CHAR
+0xF7C9 0xE5AC #USER DEFINED CHAR
+0xF7CA 0xE5AD #USER DEFINED CHAR
+0xF7CB 0xE5AE #USER DEFINED CHAR
+0xF7CC 0xE5AF #USER DEFINED CHAR
+0xF7CD 0xE5B0 #USER DEFINED CHAR
+0xF7CE 0xE5B1 #USER DEFINED CHAR
+0xF7CF 0xE5B2 #USER DEFINED CHAR
+0xF7D0 0xE5B3 #USER DEFINED CHAR
+0xF7D1 0xE5B4 #USER DEFINED CHAR
+0xF7D2 0xE5B5 #USER DEFINED CHAR
+0xF7D3 0xE5B6 #USER DEFINED CHAR
+0xF7D4 0xE5B7 #USER DEFINED CHAR
+0xF7D5 0xE5B8 #USER DEFINED CHAR
+0xF7D6 0xE5B9 #USER DEFINED CHAR
+0xF7D7 0xE5BA #USER DEFINED CHAR
+0xF7D8 0xE5BB #USER DEFINED CHAR
+0xF7D9 0xE5BC #USER DEFINED CHAR
+0xF7DA 0xE5BD #USER DEFINED CHAR
+0xF7DB 0xE5BE #USER DEFINED CHAR
+0xF7DC 0xE5BF #USER DEFINED CHAR
+0xF7DD 0xE5C0 #USER DEFINED CHAR
+0xF7DE 0xE5C1 #USER DEFINED CHAR
+0xF7DF 0xE5C2 #USER DEFINED CHAR
+0xF7E0 0xE5C3 #USER DEFINED CHAR
+0xF7E1 0xE5C4 #USER DEFINED CHAR
+0xF7E2 0xE5C5 #USER DEFINED CHAR
+0xF7E3 0xE5C6 #USER DEFINED CHAR
+0xF7E4 0xE5C7 #USER DEFINED CHAR
+0xF7E5 0xE5C8 #USER DEFINED CHAR
+0xF7E6 0xE5C9 #USER DEFINED CHAR
+0xF7E7 0xE5CA #USER DEFINED CHAR
+0xF7E8 0xE5CB #USER DEFINED CHAR
+0xF7E9 0xE5CC #USER DEFINED CHAR
+0xF7EA 0xE5CD #USER DEFINED CHAR
+0xF7EB 0xE5CE #USER DEFINED CHAR
+0xF7EC 0xE5CF #USER DEFINED CHAR
+0xF7ED 0xE5D0 #USER DEFINED CHAR
+0xF7EE 0xE5D1 #USER DEFINED CHAR
+0xF7EF 0xE5D2 #USER DEFINED CHAR
+0xF7F0 0xE5D3 #USER DEFINED CHAR
+0xF7F1 0xE5D4 #USER DEFINED CHAR
+0xF7F2 0xE5D5 #USER DEFINED CHAR
+0xF7F3 0xE5D6 #USER DEFINED CHAR
+0xF7F4 0xE5D7 #USER DEFINED CHAR
+0xF7F5 0xE5D8 #USER DEFINED CHAR
+0xF7F6 0xE5D9 #USER DEFINED CHAR
+0xF7F7 0xE5DA #USER DEFINED CHAR
+0xF7F8 0xE5DB #USER DEFINED CHAR
+0xF7F9 0xE5DC #USER DEFINED CHAR
+0xF7FA 0xE5DD #USER DEFINED CHAR
+0xF7FB 0xE5DE #USER DEFINED CHAR
+0xF7FC 0xE5DF #USER DEFINED CHAR
+0xF840 0xE5E0 #USER DEFINED CHAR
+0xF841 0xE5E1 #USER DEFINED CHAR
+0xF842 0xE5E2 #USER DEFINED CHAR
+0xF843 0xE5E3 #USER DEFINED CHAR
+0xF844 0xE5E4 #USER DEFINED CHAR
+0xF845 0xE5E5 #USER DEFINED CHAR
+0xF846 0xE5E6 #USER DEFINED CHAR
+0xF847 0xE5E7 #USER DEFINED CHAR
+0xF848 0xE5E8 #USER DEFINED CHAR
+0xF849 0xE5E9 #USER DEFINED CHAR
+0xF84A 0xE5EA #USER DEFINED CHAR
+0xF84B 0xE5EB #USER DEFINED CHAR
+0xF84C 0xE5EC #USER DEFINED CHAR
+0xF84D 0xE5ED #USER DEFINED CHAR
+0xF84E 0xE5EE #USER DEFINED CHAR
+0xF84F 0xE5EF #USER DEFINED CHAR
+0xF850 0xE5F0 #USER DEFINED CHAR
+0xF851 0xE5F1 #USER DEFINED CHAR
+0xF852 0xE5F2 #USER DEFINED CHAR
+0xF853 0xE5F3 #USER DEFINED CHAR
+0xF854 0xE5F4 #USER DEFINED CHAR
+0xF855 0xE5F5 #USER DEFINED CHAR
+0xF856 0xE5F6 #USER DEFINED CHAR
+0xF857 0xE5F7 #USER DEFINED CHAR
+0xF858 0xE5F8 #USER DEFINED CHAR
+0xF859 0xE5F9 #USER DEFINED CHAR
+0xF85A 0xE5FA #USER DEFINED CHAR
+0xF85B 0xE5FB #USER DEFINED CHAR
+0xF85C 0xE5FC #USER DEFINED CHAR
+0xF85D 0xE5FD #USER DEFINED CHAR
+0xF85E 0xE5FE #USER DEFINED CHAR
+0xF85F 0xE5FF #USER DEFINED CHAR
+0xF860 0xE600 #USER DEFINED CHAR
+0xF861 0xE601 #USER DEFINED CHAR
+0xF862 0xE602 #USER DEFINED CHAR
+0xF863 0xE603 #USER DEFINED CHAR
+0xF864 0xE604 #USER DEFINED CHAR
+0xF865 0xE605 #USER DEFINED CHAR
+0xF866 0xE606 #USER DEFINED CHAR
+0xF867 0xE607 #USER DEFINED CHAR
+0xF868 0xE608 #USER DEFINED CHAR
+0xF869 0xE609 #USER DEFINED CHAR
+0xF86A 0xE60A #USER DEFINED CHAR
+0xF86B 0xE60B #USER DEFINED CHAR
+0xF86C 0xE60C #USER DEFINED CHAR
+0xF86D 0xE60D #USER DEFINED CHAR
+0xF86E 0xE60E #USER DEFINED CHAR
+0xF86F 0xE60F #USER DEFINED CHAR
+0xF870 0xE610 #USER DEFINED CHAR
+0xF871 0xE611 #USER DEFINED CHAR
+0xF872 0xE612 #USER DEFINED CHAR
+0xF873 0xE613 #USER DEFINED CHAR
+0xF874 0xE614 #USER DEFINED CHAR
+0xF875 0xE615 #USER DEFINED CHAR
+0xF876 0xE616 #USER DEFINED CHAR
+0xF877 0xE617 #USER DEFINED CHAR
+0xF878 0xE618 #USER DEFINED CHAR
+0xF879 0xE619 #USER DEFINED CHAR
+0xF87A 0xE61A #USER DEFINED CHAR
+0xF87B 0xE61B #USER DEFINED CHAR
+0xF87C 0xE61C #USER DEFINED CHAR
+0xF87D 0xE61D #USER DEFINED CHAR
+0xF87E 0xE61E #USER DEFINED CHAR
+0xF880 0xE61F #USER DEFINED CHAR
+0xF881 0xE620 #USER DEFINED CHAR
+0xF882 0xE621 #USER DEFINED CHAR
+0xF883 0xE622 #USER DEFINED CHAR
+0xF884 0xE623 #USER DEFINED CHAR
+0xF885 0xE624 #USER DEFINED CHAR
+0xF886 0xE625 #USER DEFINED CHAR
+0xF887 0xE626 #USER DEFINED CHAR
+0xF888 0xE627 #USER DEFINED CHAR
+0xF889 0xE628 #USER DEFINED CHAR
+0xF88A 0xE629 #USER DEFINED CHAR
+0xF88B 0xE62A #USER DEFINED CHAR
+0xF88C 0xE62B #USER DEFINED CHAR
+0xF88D 0xE62C #USER DEFINED CHAR
+0xF88E 0xE62D #USER DEFINED CHAR
+0xF88F 0xE62E #USER DEFINED CHAR
+0xF890 0xE62F #USER DEFINED CHAR
+0xF891 0xE630 #USER DEFINED CHAR
+0xF892 0xE631 #USER DEFINED CHAR
+0xF893 0xE632 #USER DEFINED CHAR
+0xF894 0xE633 #USER DEFINED CHAR
+0xF895 0xE634 #USER DEFINED CHAR
+0xF896 0xE635 #USER DEFINED CHAR
+0xF897 0xE636 #USER DEFINED CHAR
+0xF898 0xE637 #USER DEFINED CHAR
+0xF899 0xE638 #USER DEFINED CHAR
+0xF89A 0xE639 #USER DEFINED CHAR
+0xF89B 0xE63A #USER DEFINED CHAR
+0xF89C 0xE63B #USER DEFINED CHAR
+0xF89D 0xE63C #USER DEFINED CHAR
+0xF89E 0xE63D #USER DEFINED CHAR
+0xF89F 0xE63E #USER DEFINED CHAR
+0xF8A0 0xE63F #USER DEFINED CHAR
+0xF8A1 0xE640 #USER DEFINED CHAR
+0xF8A2 0xE641 #USER DEFINED CHAR
+0xF8A3 0xE642 #USER DEFINED CHAR
+0xF8A4 0xE643 #USER DEFINED CHAR
+0xF8A5 0xE644 #USER DEFINED CHAR
+0xF8A6 0xE645 #USER DEFINED CHAR
+0xF8A7 0xE646 #USER DEFINED CHAR
+0xF8A8 0xE647 #USER DEFINED CHAR
+0xF8A9 0xE648 #USER DEFINED CHAR
+0xF8AA 0xE649 #USER DEFINED CHAR
+0xF8AB 0xE64A #USER DEFINED CHAR
+0xF8AC 0xE64B #USER DEFINED CHAR
+0xF8AD 0xE64C #USER DEFINED CHAR
+0xF8AE 0xE64D #USER DEFINED CHAR
+0xF8AF 0xE64E #USER DEFINED CHAR
+0xF8B0 0xE64F #USER DEFINED CHAR
+0xF8B1 0xE650 #USER DEFINED CHAR
+0xF8B2 0xE651 #USER DEFINED CHAR
+0xF8B3 0xE652 #USER DEFINED CHAR
+0xF8B4 0xE653 #USER DEFINED CHAR
+0xF8B5 0xE654 #USER DEFINED CHAR
+0xF8B6 0xE655 #USER DEFINED CHAR
+0xF8B7 0xE656 #USER DEFINED CHAR
+0xF8B8 0xE657 #USER DEFINED CHAR
+0xF8B9 0xE658 #USER DEFINED CHAR
+0xF8BA 0xE659 #USER DEFINED CHAR
+0xF8BB 0xE65A #USER DEFINED CHAR
+0xF8BC 0xE65B #USER DEFINED CHAR
+0xF8BD 0xE65C #USER DEFINED CHAR
+0xF8BE 0xE65D #USER DEFINED CHAR
+0xF8BF 0xE65E #USER DEFINED CHAR
+0xF8C0 0xE65F #USER DEFINED CHAR
+0xF8C1 0xE660 #USER DEFINED CHAR
+0xF8C2 0xE661 #USER DEFINED CHAR
+0xF8C3 0xE662 #USER DEFINED CHAR
+0xF8C4 0xE663 #USER DEFINED CHAR
+0xF8C5 0xE664 #USER DEFINED CHAR
+0xF8C6 0xE665 #USER DEFINED CHAR
+0xF8C7 0xE666 #USER DEFINED CHAR
+0xF8C8 0xE667 #USER DEFINED CHAR
+0xF8C9 0xE668 #USER DEFINED CHAR
+0xF8CA 0xE669 #USER DEFINED CHAR
+0xF8CB 0xE66A #USER DEFINED CHAR
+0xF8CC 0xE66B #USER DEFINED CHAR
+0xF8CD 0xE66C #USER DEFINED CHAR
+0xF8CE 0xE66D #USER DEFINED CHAR
+0xF8CF 0xE66E #USER DEFINED CHAR
+0xF8D0 0xE66F #USER DEFINED CHAR
+0xF8D1 0xE670 #USER DEFINED CHAR
+0xF8D2 0xE671 #USER DEFINED CHAR
+0xF8D3 0xE672 #USER DEFINED CHAR
+0xF8D4 0xE673 #USER DEFINED CHAR
+0xF8D5 0xE674 #USER DEFINED CHAR
+0xF8D6 0xE675 #USER DEFINED CHAR
+0xF8D7 0xE676 #USER DEFINED CHAR
+0xF8D8 0xE677 #USER DEFINED CHAR
+0xF8D9 0xE678 #USER DEFINED CHAR
+0xF8DA 0xE679 #USER DEFINED CHAR
+0xF8DB 0xE67A #USER DEFINED CHAR
+0xF8DC 0xE67B #USER DEFINED CHAR
+0xF8DD 0xE67C #USER DEFINED CHAR
+0xF8DE 0xE67D #USER DEFINED CHAR
+0xF8DF 0xE67E #USER DEFINED CHAR
+0xF8E0 0xE67F #USER DEFINED CHAR
+0xF8E1 0xE680 #USER DEFINED CHAR
+0xF8E2 0xE681 #USER DEFINED CHAR
+0xF8E3 0xE682 #USER DEFINED CHAR
+0xF8E4 0xE683 #USER DEFINED CHAR
+0xF8E5 0xE684 #USER DEFINED CHAR
+0xF8E6 0xE685 #USER DEFINED CHAR
+0xF8E7 0xE686 #USER DEFINED CHAR
+0xF8E8 0xE687 #USER DEFINED CHAR
+0xF8E9 0xE688 #USER DEFINED CHAR
+0xF8EA 0xE689 #USER DEFINED CHAR
+0xF8EB 0xE68A #USER DEFINED CHAR
+0xF8EC 0xE68B #USER DEFINED CHAR
+0xF8ED 0xE68C #USER DEFINED CHAR
+0xF8EE 0xE68D #USER DEFINED CHAR
+0xF8EF 0xE68E #USER DEFINED CHAR
+0xF8F0 0xE68F #USER DEFINED CHAR
+0xF8F1 0xE690 #USER DEFINED CHAR
+0xF8F2 0xE691 #USER DEFINED CHAR
+0xF8F3 0xE692 #USER DEFINED CHAR
+0xF8F4 0xE693 #USER DEFINED CHAR
+0xF8F5 0xE694 #USER DEFINED CHAR
+0xF8F6 0xE695 #USER DEFINED CHAR
+0xF8F7 0xE696 #USER DEFINED CHAR
+0xF8F8 0xE697 #USER DEFINED CHAR
+0xF8F9 0xE698 #USER DEFINED CHAR
+0xF8FA 0xE699 #USER DEFINED CHAR
+0xF8FB 0xE69A #USER DEFINED CHAR
+0xF8FC 0xE69B #USER DEFINED CHAR
+0xF940 0xE69C #USER DEFINED CHAR
+0xF941 0xE69D #USER DEFINED CHAR
+0xF942 0xE69E #USER DEFINED CHAR
+0xF943 0xE69F #USER DEFINED CHAR
+0xF944 0xE6A0 #USER DEFINED CHAR
+0xF945 0xE6A1 #USER DEFINED CHAR
+0xF946 0xE6A2 #USER DEFINED CHAR
+0xF947 0xE6A3 #USER DEFINED CHAR
+0xF948 0xE6A4 #USER DEFINED CHAR
+0xF949 0xE6A5 #USER DEFINED CHAR
+0xF94A 0xE6A6 #USER DEFINED CHAR
+0xF94B 0xE6A7 #USER DEFINED CHAR
+0xF94C 0xE6A8 #USER DEFINED CHAR
+0xF94D 0xE6A9 #USER DEFINED CHAR
+0xF94E 0xE6AA #USER DEFINED CHAR
+0xF94F 0xE6AB #USER DEFINED CHAR
+0xF950 0xE6AC #USER DEFINED CHAR
+0xF951 0xE6AD #USER DEFINED CHAR
+0xF952 0xE6AE #USER DEFINED CHAR
+0xF953 0xE6AF #USER DEFINED CHAR
+0xF954 0xE6B0 #USER DEFINED CHAR
+0xF955 0xE6B1 #USER DEFINED CHAR
+0xF956 0xE6B2 #USER DEFINED CHAR
+0xF957 0xE6B3 #USER DEFINED CHAR
+0xF958 0xE6B4 #USER DEFINED CHAR
+0xF959 0xE6B5 #USER DEFINED CHAR
+0xF95A 0xE6B6 #USER DEFINED CHAR
+0xF95B 0xE6B7 #USER DEFINED CHAR
+0xF95C 0xE6B8 #USER DEFINED CHAR
+0xF95D 0xE6B9 #USER DEFINED CHAR
+0xF95E 0xE6BA #USER DEFINED CHAR
+0xF95F 0xE6BB #USER DEFINED CHAR
+0xF960 0xE6BC #USER DEFINED CHAR
+0xF961 0xE6BD #USER DEFINED CHAR
+0xF962 0xE6BE #USER DEFINED CHAR
+0xF963 0xE6BF #USER DEFINED CHAR
+0xF964 0xE6C0 #USER DEFINED CHAR
+0xF965 0xE6C1 #USER DEFINED CHAR
+0xF966 0xE6C2 #USER DEFINED CHAR
+0xF967 0xE6C3 #USER DEFINED CHAR
+0xF968 0xE6C4 #USER DEFINED CHAR
+0xF969 0xE6C5 #USER DEFINED CHAR
+0xF96A 0xE6C6 #USER DEFINED CHAR
+0xF96B 0xE6C7 #USER DEFINED CHAR
+0xF96C 0xE6C8 #USER DEFINED CHAR
+0xF96D 0xE6C9 #USER DEFINED CHAR
+0xF96E 0xE6CA #USER DEFINED CHAR
+0xF96F 0xE6CB #USER DEFINED CHAR
+0xF970 0xE6CC #USER DEFINED CHAR
+0xF971 0xE6CD #USER DEFINED CHAR
+0xF972 0xE6CE #USER DEFINED CHAR
+0xF973 0xE6CF #USER DEFINED CHAR
+0xF974 0xE6D0 #USER DEFINED CHAR
+0xF975 0xE6D1 #USER DEFINED CHAR
+0xF976 0xE6D2 #USER DEFINED CHAR
+0xF977 0xE6D3 #USER DEFINED CHAR
+0xF978 0xE6D4 #USER DEFINED CHAR
+0xF979 0xE6D5 #USER DEFINED CHAR
+0xF97A 0xE6D6 #USER DEFINED CHAR
+0xF97B 0xE6D7 #USER DEFINED CHAR
+0xF97C 0xE6D8 #USER DEFINED CHAR
+0xF97D 0xE6D9 #USER DEFINED CHAR
+0xF97E 0xE6DA #USER DEFINED CHAR
+0xF980 0xE6DB #USER DEFINED CHAR
+0xF981 0xE6DC #USER DEFINED CHAR
+0xF982 0xE6DD #USER DEFINED CHAR
+0xF983 0xE6DE #USER DEFINED CHAR
+0xF984 0xE6DF #USER DEFINED CHAR
+0xF985 0xE6E0 #USER DEFINED CHAR
+0xF986 0xE6E1 #USER DEFINED CHAR
+0xF987 0xE6E2 #USER DEFINED CHAR
+0xF988 0xE6E3 #USER DEFINED CHAR
+0xF989 0xE6E4 #USER DEFINED CHAR
+0xF98A 0xE6E5 #USER DEFINED CHAR
+0xF98B 0xE6E6 #USER DEFINED CHAR
+0xF98C 0xE6E7 #USER DEFINED CHAR
+0xF98D 0xE6E8 #USER DEFINED CHAR
+0xF98E 0xE6E9 #USER DEFINED CHAR
+0xF98F 0xE6EA #USER DEFINED CHAR
+0xF990 0xE6EB #USER DEFINED CHAR
+0xF991 0xE6EC #USER DEFINED CHAR
+0xF992 0xE6ED #USER DEFINED CHAR
+0xF993 0xE6EE #USER DEFINED CHAR
+0xF994 0xE6EF #USER DEFINED CHAR
+0xF995 0xE6F0 #USER DEFINED CHAR
+0xF996 0xE6F1 #USER DEFINED CHAR
+0xF997 0xE6F2 #USER DEFINED CHAR
+0xF998 0xE6F3 #USER DEFINED CHAR
+0xF999 0xE6F4 #USER DEFINED CHAR
+0xF99A 0xE6F5 #USER DEFINED CHAR
+0xF99B 0xE6F6 #USER DEFINED CHAR
+0xF99C 0xE6F7 #USER DEFINED CHAR
+0xF99D 0xE6F8 #USER DEFINED CHAR
+0xF99E 0xE6F9 #USER DEFINED CHAR
+0xF99F 0xE6FA #USER DEFINED CHAR
+0xF9A0 0xE6FB #USER DEFINED CHAR
+0xF9A1 0xE6FC #USER DEFINED CHAR
+0xF9A2 0xE6FD #USER DEFINED CHAR
+0xF9A3 0xE6FE #USER DEFINED CHAR
+0xF9A4 0xE6FF #USER DEFINED CHAR
+0xF9A5 0xE700 #USER DEFINED CHAR
+0xF9A6 0xE701 #USER DEFINED CHAR
+0xF9A7 0xE702 #USER DEFINED CHAR
+0xF9A8 0xE703 #USER DEFINED CHAR
+0xF9A9 0xE704 #USER DEFINED CHAR
+0xF9AA 0xE705 #USER DEFINED CHAR
+0xF9AB 0xE706 #USER DEFINED CHAR
+0xF9AC 0xE707 #USER DEFINED CHAR
+0xF9AD 0xE708 #USER DEFINED CHAR
+0xF9AE 0xE709 #USER DEFINED CHAR
+0xF9AF 0xE70A #USER DEFINED CHAR
+0xF9B0 0xE70B #USER DEFINED CHAR
+0xF9B1 0xE70C #USER DEFINED CHAR
+0xF9B2 0xE70D #USER DEFINED CHAR
+0xF9B3 0xE70E #USER DEFINED CHAR
+0xF9B4 0xE70F #USER DEFINED CHAR
+0xF9B5 0xE710 #USER DEFINED CHAR
+0xF9B6 0xE711 #USER DEFINED CHAR
+0xF9B7 0xE712 #USER DEFINED CHAR
+0xF9B8 0xE713 #USER DEFINED CHAR
+0xF9B9 0xE714 #USER DEFINED CHAR
+0xF9BA 0xE715 #USER DEFINED CHAR
+0xF9BB 0xE716 #USER DEFINED CHAR
+0xF9BC 0xE717 #USER DEFINED CHAR
+0xF9BD 0xE718 #USER DEFINED CHAR
+0xF9BE 0xE719 #USER DEFINED CHAR
+0xF9BF 0xE71A #USER DEFINED CHAR
+0xF9C0 0xE71B #USER DEFINED CHAR
+0xF9C1 0xE71C #USER DEFINED CHAR
+0xF9C2 0xE71D #USER DEFINED CHAR
+0xF9C3 0xE71E #USER DEFINED CHAR
+0xF9C4 0xE71F #USER DEFINED CHAR
+0xF9C5 0xE720 #USER DEFINED CHAR
+0xF9C6 0xE721 #USER DEFINED CHAR
+0xF9C7 0xE722 #USER DEFINED CHAR
+0xF9C8 0xE723 #USER DEFINED CHAR
+0xF9C9 0xE724 #USER DEFINED CHAR
+0xF9CA 0xE725 #USER DEFINED CHAR
+0xF9CB 0xE726 #USER DEFINED CHAR
+0xF9CC 0xE727 #USER DEFINED CHAR
+0xF9CD 0xE728 #USER DEFINED CHAR
+0xF9CE 0xE729 #USER DEFINED CHAR
+0xF9CF 0xE72A #USER DEFINED CHAR
+0xF9D0 0xE72B #USER DEFINED CHAR
+0xF9D1 0xE72C #USER DEFINED CHAR
+0xF9D2 0xE72D #USER DEFINED CHAR
+0xF9D3 0xE72E #USER DEFINED CHAR
+0xF9D4 0xE72F #USER DEFINED CHAR
+0xF9D5 0xE730 #USER DEFINED CHAR
+0xF9D6 0xE731 #USER DEFINED CHAR
+0xF9D7 0xE732 #USER DEFINED CHAR
+0xF9D8 0xE733 #USER DEFINED CHAR
+0xF9D9 0xE734 #USER DEFINED CHAR
+0xF9DA 0xE735 #USER DEFINED CHAR
+0xF9DB 0xE736 #USER DEFINED CHAR
+0xF9DC 0xE737 #USER DEFINED CHAR
+0xF9DD 0xE738 #USER DEFINED CHAR
+0xF9DE 0xE739 #USER DEFINED CHAR
+0xF9DF 0xE73A #USER DEFINED CHAR
+0xF9E0 0xE73B #USER DEFINED CHAR
+0xF9E1 0xE73C #USER DEFINED CHAR
+0xF9E2 0xE73D #USER DEFINED CHAR
+0xF9E3 0xE73E #USER DEFINED CHAR
+0xF9E4 0xE73F #USER DEFINED CHAR
+0xF9E5 0xE740 #USER DEFINED CHAR
+0xF9E6 0xE741 #USER DEFINED CHAR
+0xF9E7 0xE742 #USER DEFINED CHAR
+0xF9E8 0xE743 #USER DEFINED CHAR
+0xF9E9 0xE744 #USER DEFINED CHAR
+0xF9EA 0xE745 #USER DEFINED CHAR
+0xF9EB 0xE746 #USER DEFINED CHAR
+0xF9EC 0xE747 #USER DEFINED CHAR
+0xF9ED 0xE748 #USER DEFINED CHAR
+0xF9EE 0xE749 #USER DEFINED CHAR
+0xF9EF 0xE74A #USER DEFINED CHAR
+0xF9F0 0xE74B #USER DEFINED CHAR
+0xF9F1 0xE74C #USER DEFINED CHAR
+0xF9F2 0xE74D #USER DEFINED CHAR
+0xF9F3 0xE74E #USER DEFINED CHAR
+0xF9F4 0xE74F #USER DEFINED CHAR
+0xF9F5 0xE750 #USER DEFINED CHAR
+0xF9F6 0xE751 #USER DEFINED CHAR
+0xF9F7 0xE752 #USER DEFINED CHAR
+0xF9F8 0xE753 #USER DEFINED CHAR
+0xF9F9 0xE754 #USER DEFINED CHAR
+0xF9FA 0xE755 #USER DEFINED CHAR
+0xF9FB 0xE756 #USER DEFINED CHAR
+0xF9FC 0xE757 #USER DEFINED CHAR
+0xFA40 0x2170 #SMALL ROMAN NUMERAL ONE
+0xFA41 0x2171 #SMALL ROMAN NUMERAL TWO
+0xFA42 0x2172 #SMALL ROMAN NUMERAL THREE
+0xFA43 0x2173 #SMALL ROMAN NUMERAL FOUR
+0xFA44 0x2174 #SMALL ROMAN NUMERAL FIVE
+0xFA45 0x2175 #SMALL ROMAN NUMERAL SIX
+0xFA46 0x2176 #SMALL ROMAN NUMERAL SEVEN
+0xFA47 0x2177 #SMALL ROMAN NUMERAL EIGHT
+0xFA48 0x2178 #SMALL ROMAN NUMERAL NINE
+0xFA49 0x2179 #SMALL ROMAN NUMERAL TEN
+0xFA4A 0x2160 #ROMAN NUMERAL ONE
+0xFA4B 0x2161 #ROMAN NUMERAL TWO
+0xFA4C 0x2162 #ROMAN NUMERAL THREE
+0xFA4D 0x2163 #ROMAN NUMERAL FOUR
+0xFA4E 0x2164 #ROMAN NUMERAL FIVE
+0xFA4F 0x2165 #ROMAN NUMERAL SIX
+0xFA50 0x2166 #ROMAN NUMERAL SEVEN
+0xFA51 0x2167 #ROMAN NUMERAL EIGHT
+0xFA52 0x2168 #ROMAN NUMERAL NINE
+0xFA53 0x2169 #ROMAN NUMERAL TEN
+0xFA55 0xFFE4 #FULLWIDTH BROKEN BAR
+0xFA56 0xFF07 #FULLWIDTH APOSTROPHE
+0xFA57 0xFF02 #FULLWIDTH QUOTATION MARK
+0xFA58 0x3231 #PARENTHESIZED IDEOGRAPH STOCK
+0xFA59 0x2116 #NUMERO SIGN
+0xFA5A 0x2121 #TELEPHONE SIGN
+0xFA5C 0x7E8A #CJK UNIFIED IDEOGRAPH
+0xFA5D 0x891C #CJK UNIFIED IDEOGRAPH
+0xFA5E 0x9348 #CJK UNIFIED IDEOGRAPH
+0xFA5F 0x9288 #CJK UNIFIED IDEOGRAPH
+0xFA60 0x84DC #CJK UNIFIED IDEOGRAPH
+0xFA61 0x4FC9 #CJK UNIFIED IDEOGRAPH
+0xFA62 0x70BB #CJK UNIFIED IDEOGRAPH
+0xFA63 0x6631 #CJK UNIFIED IDEOGRAPH
+0xFA64 0x68C8 #CJK UNIFIED IDEOGRAPH
+0xFA65 0x92F9 #CJK UNIFIED IDEOGRAPH
+0xFA66 0x66FB #CJK UNIFIED IDEOGRAPH
+0xFA67 0x5F45 #CJK UNIFIED IDEOGRAPH
+0xFA68 0x4E28 #CJK UNIFIED IDEOGRAPH
+0xFA69 0x4EE1 #CJK UNIFIED IDEOGRAPH
+0xFA6A 0x4EFC #CJK UNIFIED IDEOGRAPH
+0xFA6B 0x4F00 #CJK UNIFIED IDEOGRAPH
+0xFA6C 0x4F03 #CJK UNIFIED IDEOGRAPH
+0xFA6D 0x4F39 #CJK UNIFIED IDEOGRAPH
+0xFA6E 0x4F56 #CJK UNIFIED IDEOGRAPH
+0xFA6F 0x4F92 #CJK UNIFIED IDEOGRAPH
+0xFA70 0x4F8A #CJK UNIFIED IDEOGRAPH
+0xFA71 0x4F9A #CJK UNIFIED IDEOGRAPH
+0xFA72 0x4F94 #CJK UNIFIED IDEOGRAPH
+0xFA73 0x4FCD #CJK UNIFIED IDEOGRAPH
+0xFA74 0x5040 #CJK UNIFIED IDEOGRAPH
+0xFA75 0x5022 #CJK UNIFIED IDEOGRAPH
+0xFA76 0x4FFF #CJK UNIFIED IDEOGRAPH
+0xFA77 0x501E #CJK UNIFIED IDEOGRAPH
+0xFA78 0x5046 #CJK UNIFIED IDEOGRAPH
+0xFA79 0x5070 #CJK UNIFIED IDEOGRAPH
+0xFA7A 0x5042 #CJK UNIFIED IDEOGRAPH
+0xFA7B 0x5094 #CJK UNIFIED IDEOGRAPH
+0xFA7C 0x50F4 #CJK UNIFIED IDEOGRAPH
+0xFA7D 0x50D8 #CJK UNIFIED IDEOGRAPH
+0xFA7E 0x514A #CJK UNIFIED IDEOGRAPH
+0xFA80 0x5164 #CJK UNIFIED IDEOGRAPH
+0xFA81 0x519D #CJK UNIFIED IDEOGRAPH
+0xFA82 0x51BE #CJK UNIFIED IDEOGRAPH
+0xFA83 0x51EC #CJK UNIFIED IDEOGRAPH
+0xFA84 0x5215 #CJK UNIFIED IDEOGRAPH
+0xFA85 0x529C #CJK UNIFIED IDEOGRAPH
+0xFA86 0x52A6 #CJK UNIFIED IDEOGRAPH
+0xFA87 0x52C0 #CJK UNIFIED IDEOGRAPH
+0xFA88 0x52DB #CJK UNIFIED IDEOGRAPH
+0xFA89 0x5300 #CJK UNIFIED IDEOGRAPH
+0xFA8A 0x5307 #CJK UNIFIED IDEOGRAPH
+0xFA8B 0x5324 #CJK UNIFIED IDEOGRAPH
+0xFA8C 0x5372 #CJK UNIFIED IDEOGRAPH
+0xFA8D 0x5393 #CJK UNIFIED IDEOGRAPH
+0xFA8E 0x53B2 #CJK UNIFIED IDEOGRAPH
+0xFA8F 0x53DD #CJK UNIFIED IDEOGRAPH
+0xFA90 0xFA0E #CJK COMPATIBILITY IDEOGRAPH
+0xFA91 0x549C #CJK UNIFIED IDEOGRAPH
+0xFA92 0x548A #CJK UNIFIED IDEOGRAPH
+0xFA93 0x54A9 #CJK UNIFIED IDEOGRAPH
+0xFA94 0x54FF #CJK UNIFIED IDEOGRAPH
+0xFA95 0x5586 #CJK UNIFIED IDEOGRAPH
+0xFA96 0x5759 #CJK UNIFIED IDEOGRAPH
+0xFA97 0x5765 #CJK UNIFIED IDEOGRAPH
+0xFA98 0x57AC #CJK UNIFIED IDEOGRAPH
+0xFA99 0x57C8 #CJK UNIFIED IDEOGRAPH
+0xFA9A 0x57C7 #CJK UNIFIED IDEOGRAPH
+0xFA9B 0xFA0F #CJK COMPATIBILITY IDEOGRAPH
+0xFA9C 0xFA10 #CJK COMPATIBILITY IDEOGRAPH
+0xFA9D 0x589E #CJK UNIFIED IDEOGRAPH
+0xFA9E 0x58B2 #CJK UNIFIED IDEOGRAPH
+0xFA9F 0x590B #CJK UNIFIED IDEOGRAPH
+0xFAA0 0x5953 #CJK UNIFIED IDEOGRAPH
+0xFAA1 0x595B #CJK UNIFIED IDEOGRAPH
+0xFAA2 0x595D #CJK UNIFIED IDEOGRAPH
+0xFAA3 0x5963 #CJK UNIFIED IDEOGRAPH
+0xFAA4 0x59A4 #CJK UNIFIED IDEOGRAPH
+0xFAA5 0x59BA #CJK UNIFIED IDEOGRAPH
+0xFAA6 0x5B56 #CJK UNIFIED IDEOGRAPH
+0xFAA7 0x5BC0 #CJK UNIFIED IDEOGRAPH
+0xFAA8 0x752F #CJK UNIFIED IDEOGRAPH
+0xFAA9 0x5BD8 #CJK UNIFIED IDEOGRAPH
+0xFAAA 0x5BEC #CJK UNIFIED IDEOGRAPH
+0xFAAB 0x5C1E #CJK UNIFIED IDEOGRAPH
+0xFAAC 0x5CA6 #CJK UNIFIED IDEOGRAPH
+0xFAAD 0x5CBA #CJK UNIFIED IDEOGRAPH
+0xFAAE 0x5CF5 #CJK UNIFIED IDEOGRAPH
+0xFAAF 0x5D27 #CJK UNIFIED IDEOGRAPH
+0xFAB0 0x5D53 #CJK UNIFIED IDEOGRAPH
+0xFAB1 0xFA11 #CJK COMPATIBILITY IDEOGRAPH
+0xFAB2 0x5D42 #CJK UNIFIED IDEOGRAPH
+0xFAB3 0x5D6D #CJK UNIFIED IDEOGRAPH
+0xFAB4 0x5DB8 #CJK UNIFIED IDEOGRAPH
+0xFAB5 0x5DB9 #CJK UNIFIED IDEOGRAPH
+0xFAB6 0x5DD0 #CJK UNIFIED IDEOGRAPH
+0xFAB7 0x5F21 #CJK UNIFIED IDEOGRAPH
+0xFAB8 0x5F34 #CJK UNIFIED IDEOGRAPH
+0xFAB9 0x5F67 #CJK UNIFIED IDEOGRAPH
+0xFABA 0x5FB7 #CJK UNIFIED IDEOGRAPH
+0xFABB 0x5FDE #CJK UNIFIED IDEOGRAPH
+0xFABC 0x605D #CJK UNIFIED IDEOGRAPH
+0xFABD 0x6085 #CJK UNIFIED IDEOGRAPH
+0xFABE 0x608A #CJK UNIFIED IDEOGRAPH
+0xFABF 0x60DE #CJK UNIFIED IDEOGRAPH
+0xFAC0 0x60D5 #CJK UNIFIED IDEOGRAPH
+0xFAC1 0x6120 #CJK UNIFIED IDEOGRAPH
+0xFAC2 0x60F2 #CJK UNIFIED IDEOGRAPH
+0xFAC3 0x6111 #CJK UNIFIED IDEOGRAPH
+0xFAC4 0x6137 #CJK UNIFIED IDEOGRAPH
+0xFAC5 0x6130 #CJK UNIFIED IDEOGRAPH
+0xFAC6 0x6198 #CJK UNIFIED IDEOGRAPH
+0xFAC7 0x6213 #CJK UNIFIED IDEOGRAPH
+0xFAC8 0x62A6 #CJK UNIFIED IDEOGRAPH
+0xFAC9 0x63F5 #CJK UNIFIED IDEOGRAPH
+0xFACA 0x6460 #CJK UNIFIED IDEOGRAPH
+0xFACB 0x649D #CJK UNIFIED IDEOGRAPH
+0xFACC 0x64CE #CJK UNIFIED IDEOGRAPH
+0xFACD 0x654E #CJK UNIFIED IDEOGRAPH
+0xFACE 0x6600 #CJK UNIFIED IDEOGRAPH
+0xFACF 0x6615 #CJK UNIFIED IDEOGRAPH
+0xFAD0 0x663B #CJK UNIFIED IDEOGRAPH
+0xFAD1 0x6609 #CJK UNIFIED IDEOGRAPH
+0xFAD2 0x662E #CJK UNIFIED IDEOGRAPH
+0xFAD3 0x661E #CJK UNIFIED IDEOGRAPH
+0xFAD4 0x6624 #CJK UNIFIED IDEOGRAPH
+0xFAD5 0x6665 #CJK UNIFIED IDEOGRAPH
+0xFAD6 0x6657 #CJK UNIFIED IDEOGRAPH
+0xFAD7 0x6659 #CJK UNIFIED IDEOGRAPH
+0xFAD8 0xFA12 #CJK COMPATIBILITY IDEOGRAPH
+0xFAD9 0x6673 #CJK UNIFIED IDEOGRAPH
+0xFADA 0x6699 #CJK UNIFIED IDEOGRAPH
+0xFADB 0x66A0 #CJK UNIFIED IDEOGRAPH
+0xFADC 0x66B2 #CJK UNIFIED IDEOGRAPH
+0xFADD 0x66BF #CJK UNIFIED IDEOGRAPH
+0xFADE 0x66FA #CJK UNIFIED IDEOGRAPH
+0xFADF 0x670E #CJK UNIFIED IDEOGRAPH
+0xFAE0 0xF929 #CJK COMPATIBILITY IDEOGRAPH
+0xFAE1 0x6766 #CJK UNIFIED IDEOGRAPH
+0xFAE2 0x67BB #CJK UNIFIED IDEOGRAPH
+0xFAE3 0x6852 #CJK UNIFIED IDEOGRAPH
+0xFAE4 0x67C0 #CJK UNIFIED IDEOGRAPH
+0xFAE5 0x6801 #CJK UNIFIED IDEOGRAPH
+0xFAE6 0x6844 #CJK UNIFIED IDEOGRAPH
+0xFAE7 0x68CF #CJK UNIFIED IDEOGRAPH
+0xFAE8 0xFA13 #CJK COMPATIBILITY IDEOGRAPH
+0xFAE9 0x6968 #CJK UNIFIED IDEOGRAPH
+0xFAEA 0xFA14 #CJK COMPATIBILITY IDEOGRAPH
+0xFAEB 0x6998 #CJK UNIFIED IDEOGRAPH
+0xFAEC 0x69E2 #CJK UNIFIED IDEOGRAPH
+0xFAED 0x6A30 #CJK UNIFIED IDEOGRAPH
+0xFAEE 0x6A6B #CJK UNIFIED IDEOGRAPH
+0xFAEF 0x6A46 #CJK UNIFIED IDEOGRAPH
+0xFAF0 0x6A73 #CJK UNIFIED IDEOGRAPH
+0xFAF1 0x6A7E #CJK UNIFIED IDEOGRAPH
+0xFAF2 0x6AE2 #CJK UNIFIED IDEOGRAPH
+0xFAF3 0x6AE4 #CJK UNIFIED IDEOGRAPH
+0xFAF4 0x6BD6 #CJK UNIFIED IDEOGRAPH
+0xFAF5 0x6C3F #CJK UNIFIED IDEOGRAPH
+0xFAF6 0x6C5C #CJK UNIFIED IDEOGRAPH
+0xFAF7 0x6C86 #CJK UNIFIED IDEOGRAPH
+0xFAF8 0x6C6F #CJK UNIFIED IDEOGRAPH
+0xFAF9 0x6CDA #CJK UNIFIED IDEOGRAPH
+0xFAFA 0x6D04 #CJK UNIFIED IDEOGRAPH
+0xFAFB 0x6D87 #CJK UNIFIED IDEOGRAPH
+0xFAFC 0x6D6F #CJK UNIFIED IDEOGRAPH
+0xFB40 0x6D96 #CJK UNIFIED IDEOGRAPH
+0xFB41 0x6DAC #CJK UNIFIED IDEOGRAPH
+0xFB42 0x6DCF #CJK UNIFIED IDEOGRAPH
+0xFB43 0x6DF8 #CJK UNIFIED IDEOGRAPH
+0xFB44 0x6DF2 #CJK UNIFIED IDEOGRAPH
+0xFB45 0x6DFC #CJK UNIFIED IDEOGRAPH
+0xFB46 0x6E39 #CJK UNIFIED IDEOGRAPH
+0xFB47 0x6E5C #CJK UNIFIED IDEOGRAPH
+0xFB48 0x6E27 #CJK UNIFIED IDEOGRAPH
+0xFB49 0x6E3C #CJK UNIFIED IDEOGRAPH
+0xFB4A 0x6EBF #CJK UNIFIED IDEOGRAPH
+0xFB4B 0x6F88 #CJK UNIFIED IDEOGRAPH
+0xFB4C 0x6FB5 #CJK UNIFIED IDEOGRAPH
+0xFB4D 0x6FF5 #CJK UNIFIED IDEOGRAPH
+0xFB4E 0x7005 #CJK UNIFIED IDEOGRAPH
+0xFB4F 0x7007 #CJK UNIFIED IDEOGRAPH
+0xFB50 0x7028 #CJK UNIFIED IDEOGRAPH
+0xFB51 0x7085 #CJK UNIFIED IDEOGRAPH
+0xFB52 0x70AB #CJK UNIFIED IDEOGRAPH
+0xFB53 0x710F #CJK UNIFIED IDEOGRAPH
+0xFB54 0x7104 #CJK UNIFIED IDEOGRAPH
+0xFB55 0x715C #CJK UNIFIED IDEOGRAPH
+0xFB56 0x7146 #CJK UNIFIED IDEOGRAPH
+0xFB57 0x7147 #CJK UNIFIED IDEOGRAPH
+0xFB58 0xFA15 #CJK COMPATIBILITY IDEOGRAPH
+0xFB59 0x71C1 #CJK UNIFIED IDEOGRAPH
+0xFB5A 0x71FE #CJK UNIFIED IDEOGRAPH
+0xFB5B 0x72B1 #CJK UNIFIED IDEOGRAPH
+0xFB5C 0x72BE #CJK UNIFIED IDEOGRAPH
+0xFB5D 0x7324 #CJK UNIFIED IDEOGRAPH
+0xFB5E 0xFA16 #CJK COMPATIBILITY IDEOGRAPH
+0xFB5F 0x7377 #CJK UNIFIED IDEOGRAPH
+0xFB60 0x73BD #CJK UNIFIED IDEOGRAPH
+0xFB61 0x73C9 #CJK UNIFIED IDEOGRAPH
+0xFB62 0x73D6 #CJK UNIFIED IDEOGRAPH
+0xFB63 0x73E3 #CJK UNIFIED IDEOGRAPH
+0xFB64 0x73D2 #CJK UNIFIED IDEOGRAPH
+0xFB65 0x7407 #CJK UNIFIED IDEOGRAPH
+0xFB66 0x73F5 #CJK UNIFIED IDEOGRAPH
+0xFB67 0x7426 #CJK UNIFIED IDEOGRAPH
+0xFB68 0x742A #CJK UNIFIED IDEOGRAPH
+0xFB69 0x7429 #CJK UNIFIED IDEOGRAPH
+0xFB6A 0x742E #CJK UNIFIED IDEOGRAPH
+0xFB6B 0x7462 #CJK UNIFIED IDEOGRAPH
+0xFB6C 0x7489 #CJK UNIFIED IDEOGRAPH
+0xFB6D 0x749F #CJK UNIFIED IDEOGRAPH
+0xFB6E 0x7501 #CJK UNIFIED IDEOGRAPH
+0xFB6F 0x756F #CJK UNIFIED IDEOGRAPH
+0xFB70 0x7682 #CJK UNIFIED IDEOGRAPH
+0xFB71 0x769C #CJK UNIFIED IDEOGRAPH
+0xFB72 0x769E #CJK UNIFIED IDEOGRAPH
+0xFB73 0x769B #CJK UNIFIED IDEOGRAPH
+0xFB74 0x76A6 #CJK UNIFIED IDEOGRAPH
+0xFB75 0xFA17 #CJK COMPATIBILITY IDEOGRAPH
+0xFB76 0x7746 #CJK UNIFIED IDEOGRAPH
+0xFB77 0x52AF #CJK UNIFIED IDEOGRAPH
+0xFB78 0x7821 #CJK UNIFIED IDEOGRAPH
+0xFB79 0x784E #CJK UNIFIED IDEOGRAPH
+0xFB7A 0x7864 #CJK UNIFIED IDEOGRAPH
+0xFB7B 0x787A #CJK UNIFIED IDEOGRAPH
+0xFB7C 0x7930 #CJK UNIFIED IDEOGRAPH
+0xFB7D 0xFA18 #CJK COMPATIBILITY IDEOGRAPH
+0xFB7E 0xFA19 #CJK COMPATIBILITY IDEOGRAPH
+0xFB80 0xFA1A #CJK COMPATIBILITY IDEOGRAPH
+0xFB81 0x7994 #CJK UNIFIED IDEOGRAPH
+0xFB82 0xFA1B #CJK COMPATIBILITY IDEOGRAPH
+0xFB83 0x799B #CJK UNIFIED IDEOGRAPH
+0xFB84 0x7AD1 #CJK UNIFIED IDEOGRAPH
+0xFB85 0x7AE7 #CJK UNIFIED IDEOGRAPH
+0xFB86 0xFA1C #CJK COMPATIBILITY IDEOGRAPH
+0xFB87 0x7AEB #CJK UNIFIED IDEOGRAPH
+0xFB88 0x7B9E #CJK UNIFIED IDEOGRAPH
+0xFB89 0xFA1D #CJK COMPATIBILITY IDEOGRAPH
+0xFB8A 0x7D48 #CJK UNIFIED IDEOGRAPH
+0xFB8B 0x7D5C #CJK UNIFIED IDEOGRAPH
+0xFB8C 0x7DB7 #CJK UNIFIED IDEOGRAPH
+0xFB8D 0x7DA0 #CJK UNIFIED IDEOGRAPH
+0xFB8E 0x7DD6 #CJK UNIFIED IDEOGRAPH
+0xFB8F 0x7E52 #CJK UNIFIED IDEOGRAPH
+0xFB90 0x7F47 #CJK UNIFIED IDEOGRAPH
+0xFB91 0x7FA1 #CJK UNIFIED IDEOGRAPH
+0xFB92 0xFA1E #CJK COMPATIBILITY IDEOGRAPH
+0xFB93 0x8301 #CJK UNIFIED IDEOGRAPH
+0xFB94 0x8362 #CJK UNIFIED IDEOGRAPH
+0xFB95 0x837F #CJK UNIFIED IDEOGRAPH
+0xFB96 0x83C7 #CJK UNIFIED IDEOGRAPH
+0xFB97 0x83F6 #CJK UNIFIED IDEOGRAPH
+0xFB98 0x8448 #CJK UNIFIED IDEOGRAPH
+0xFB99 0x84B4 #CJK UNIFIED IDEOGRAPH
+0xFB9A 0x8553 #CJK UNIFIED IDEOGRAPH
+0xFB9B 0x8559 #CJK UNIFIED IDEOGRAPH
+0xFB9C 0x856B #CJK UNIFIED IDEOGRAPH
+0xFB9D 0xFA1F #CJK COMPATIBILITY IDEOGRAPH
+0xFB9E 0x85B0 #CJK UNIFIED IDEOGRAPH
+0xFB9F 0xFA20 #CJK COMPATIBILITY IDEOGRAPH
+0xFBA0 0xFA21 #CJK COMPATIBILITY IDEOGRAPH
+0xFBA1 0x8807 #CJK UNIFIED IDEOGRAPH
+0xFBA2 0x88F5 #CJK UNIFIED IDEOGRAPH
+0xFBA3 0x8A12 #CJK UNIFIED IDEOGRAPH
+0xFBA4 0x8A37 #CJK UNIFIED IDEOGRAPH
+0xFBA5 0x8A79 #CJK UNIFIED IDEOGRAPH
+0xFBA6 0x8AA7 #CJK UNIFIED IDEOGRAPH
+0xFBA7 0x8ABE #CJK UNIFIED IDEOGRAPH
+0xFBA8 0x8ADF #CJK UNIFIED IDEOGRAPH
+0xFBA9 0xFA22 #CJK COMPATIBILITY IDEOGRAPH
+0xFBAA 0x8AF6 #CJK UNIFIED IDEOGRAPH
+0xFBAB 0x8B53 #CJK UNIFIED IDEOGRAPH
+0xFBAC 0x8B7F #CJK UNIFIED IDEOGRAPH
+0xFBAD 0x8CF0 #CJK UNIFIED IDEOGRAPH
+0xFBAE 0x8CF4 #CJK UNIFIED IDEOGRAPH
+0xFBAF 0x8D12 #CJK UNIFIED IDEOGRAPH
+0xFBB0 0x8D76 #CJK UNIFIED IDEOGRAPH
+0xFBB1 0xFA23 #CJK COMPATIBILITY IDEOGRAPH
+0xFBB2 0x8ECF #CJK UNIFIED IDEOGRAPH
+0xFBB3 0xFA24 #CJK COMPATIBILITY IDEOGRAPH
+0xFBB4 0xFA25 #CJK COMPATIBILITY IDEOGRAPH
+0xFBB5 0x9067 #CJK UNIFIED IDEOGRAPH
+0xFBB6 0x90DE #CJK UNIFIED IDEOGRAPH
+0xFBB7 0xFA26 #CJK COMPATIBILITY IDEOGRAPH
+0xFBB8 0x9115 #CJK UNIFIED IDEOGRAPH
+0xFBB9 0x9127 #CJK UNIFIED IDEOGRAPH
+0xFBBA 0x91DA #CJK UNIFIED IDEOGRAPH
+0xFBBB 0x91D7 #CJK UNIFIED IDEOGRAPH
+0xFBBC 0x91DE #CJK UNIFIED IDEOGRAPH
+0xFBBD 0x91ED #CJK UNIFIED IDEOGRAPH
+0xFBBE 0x91EE #CJK UNIFIED IDEOGRAPH
+0xFBBF 0x91E4 #CJK UNIFIED IDEOGRAPH
+0xFBC0 0x91E5 #CJK UNIFIED IDEOGRAPH
+0xFBC1 0x9206 #CJK UNIFIED IDEOGRAPH
+0xFBC2 0x9210 #CJK UNIFIED IDEOGRAPH
+0xFBC3 0x920A #CJK UNIFIED IDEOGRAPH
+0xFBC4 0x923A #CJK UNIFIED IDEOGRAPH
+0xFBC5 0x9240 #CJK UNIFIED IDEOGRAPH
+0xFBC6 0x923C #CJK UNIFIED IDEOGRAPH
+0xFBC7 0x924E #CJK UNIFIED IDEOGRAPH
+0xFBC8 0x9259 #CJK UNIFIED IDEOGRAPH
+0xFBC9 0x9251 #CJK UNIFIED IDEOGRAPH
+0xFBCA 0x9239 #CJK UNIFIED IDEOGRAPH
+0xFBCB 0x9267 #CJK UNIFIED IDEOGRAPH
+0xFBCC 0x92A7 #CJK UNIFIED IDEOGRAPH
+0xFBCD 0x9277 #CJK UNIFIED IDEOGRAPH
+0xFBCE 0x9278 #CJK UNIFIED IDEOGRAPH
+0xFBCF 0x92E7 #CJK UNIFIED IDEOGRAPH
+0xFBD0 0x92D7 #CJK UNIFIED IDEOGRAPH
+0xFBD1 0x92D9 #CJK UNIFIED IDEOGRAPH
+0xFBD2 0x92D0 #CJK UNIFIED IDEOGRAPH
+0xFBD3 0xFA27 #CJK COMPATIBILITY IDEOGRAPH
+0xFBD4 0x92D5 #CJK UNIFIED IDEOGRAPH
+0xFBD5 0x92E0 #CJK UNIFIED IDEOGRAPH
+0xFBD6 0x92D3 #CJK UNIFIED IDEOGRAPH
+0xFBD7 0x9325 #CJK UNIFIED IDEOGRAPH
+0xFBD8 0x9321 #CJK UNIFIED IDEOGRAPH
+0xFBD9 0x92FB #CJK UNIFIED IDEOGRAPH
+0xFBDA 0xFA28 #CJK COMPATIBILITY IDEOGRAPH
+0xFBDB 0x931E #CJK UNIFIED IDEOGRAPH
+0xFBDC 0x92FF #CJK UNIFIED IDEOGRAPH
+0xFBDD 0x931D #CJK UNIFIED IDEOGRAPH
+0xFBDE 0x9302 #CJK UNIFIED IDEOGRAPH
+0xFBDF 0x9370 #CJK UNIFIED IDEOGRAPH
+0xFBE0 0x9357 #CJK UNIFIED IDEOGRAPH
+0xFBE1 0x93A4 #CJK UNIFIED IDEOGRAPH
+0xFBE2 0x93C6 #CJK UNIFIED IDEOGRAPH
+0xFBE3 0x93DE #CJK UNIFIED IDEOGRAPH
+0xFBE4 0x93F8 #CJK UNIFIED IDEOGRAPH
+0xFBE5 0x9431 #CJK UNIFIED IDEOGRAPH
+0xFBE6 0x9445 #CJK UNIFIED IDEOGRAPH
+0xFBE7 0x9448 #CJK UNIFIED IDEOGRAPH
+0xFBE8 0x9592 #CJK UNIFIED IDEOGRAPH
+0xFBE9 0xF9DC #CJK COMPATIBILITY IDEOGRAPH
+0xFBEA 0xFA29 #CJK COMPATIBILITY IDEOGRAPH
+0xFBEB 0x969D #CJK UNIFIED IDEOGRAPH
+0xFBEC 0x96AF #CJK UNIFIED IDEOGRAPH
+0xFBED 0x9733 #CJK UNIFIED IDEOGRAPH
+0xFBEE 0x973B #CJK UNIFIED IDEOGRAPH
+0xFBEF 0x9743 #CJK UNIFIED IDEOGRAPH
+0xFBF0 0x974D #CJK UNIFIED IDEOGRAPH
+0xFBF1 0x974F #CJK UNIFIED IDEOGRAPH
+0xFBF2 0x9751 #CJK UNIFIED IDEOGRAPH
+0xFBF3 0x9755 #CJK UNIFIED IDEOGRAPH
+0xFBF4 0x9857 #CJK UNIFIED IDEOGRAPH
+0xFBF5 0x9865 #CJK UNIFIED IDEOGRAPH
+0xFBF6 0xFA2A #CJK COMPATIBILITY IDEOGRAPH
+0xFBF7 0xFA2B #CJK COMPATIBILITY IDEOGRAPH
+0xFBF8 0x9927 #CJK UNIFIED IDEOGRAPH
+0xFBF9 0xFA2C #CJK COMPATIBILITY IDEOGRAPH
+0xFBFA 0x999E #CJK UNIFIED IDEOGRAPH
+0xFBFB 0x9A4E #CJK UNIFIED IDEOGRAPH
+0xFBFC 0x9AD9 #CJK UNIFIED IDEOGRAPH
+0xFC40 0x9ADC #CJK UNIFIED IDEOGRAPH
+0xFC41 0x9B75 #CJK UNIFIED IDEOGRAPH
+0xFC42 0x9B72 #CJK UNIFIED IDEOGRAPH
+0xFC43 0x9B8F #CJK UNIFIED IDEOGRAPH
+0xFC44 0x9BB1 #CJK UNIFIED IDEOGRAPH
+0xFC45 0x9BBB #CJK UNIFIED IDEOGRAPH
+0xFC46 0x9C00 #CJK UNIFIED IDEOGRAPH
+0xFC47 0x9D70 #CJK UNIFIED IDEOGRAPH
+0xFC48 0x9D6B #CJK UNIFIED IDEOGRAPH
+0xFC49 0xFA2D #CJK COMPATIBILITY IDEOGRAPH
+0xFC4A 0x9E19 #CJK UNIFIED IDEOGRAPH
+0xFC4B 0x9ED1 #CJK UNIFIED IDEOGRAPH
diff --git a/source/codepages/CP936.TXT b/source/codepages/CP936.TXT
new file mode 100755
index 00000000000..efaa1da4f25
--- /dev/null
+++ b/source/codepages/CP936.TXT
@@ -0,0 +1,22065 @@
+#
+# Name: cp936 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.01
+# Table format: Format A
+# Date: 04/15/98
+#
+# Contact: cpxlate@microsoft.com
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp936 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp936 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0A 0x000A #LINE FEED
+0x0B 0x000B #VERTICAL TABULATION
+0x0C 0x000C #FORM FEED
+0x0D 0x000D #CARRIAGE RETURN
+0x0E 0x000E #SHIFT OUT
+0x0F 0x000F #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1A 0x001A #SUBSTITUTE
+0x1B 0x001B #ESCAPE
+0x1C 0x001C #FILE SEPARATOR
+0x1D 0x001D #GROUP SEPARATOR
+0x1E 0x001E #RECORD SEPARATOR
+0x1F 0x001F #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2A 0x002A #ASTERISK
+0x2B 0x002B #PLUS SIGN
+0x2C 0x002C #COMMA
+0x2D 0x002D #HYPHEN-MINUS
+0x2E 0x002E #FULL STOP
+0x2F 0x002F #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3A 0x003A #COLON
+0x3B 0x003B #SEMICOLON
+0x3C 0x003C #LESS-THAN SIGN
+0x3D 0x003D #EQUALS SIGN
+0x3E 0x003E #GREATER-THAN SIGN
+0x3F 0x003F #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4A 0x004A #LATIN CAPITAL LETTER J
+0x4B 0x004B #LATIN CAPITAL LETTER K
+0x4C 0x004C #LATIN CAPITAL LETTER L
+0x4D 0x004D #LATIN CAPITAL LETTER M
+0x4E 0x004E #LATIN CAPITAL LETTER N
+0x4F 0x004F #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5A 0x005A #LATIN CAPITAL LETTER Z
+0x5B 0x005B #LEFT SQUARE BRACKET
+0x5C 0x005C #REVERSE SOLIDUS
+0x5D 0x005D #RIGHT SQUARE BRACKET
+0x5E 0x005E #CIRCUMFLEX ACCENT
+0x5F 0x005F #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6A 0x006A #LATIN SMALL LETTER J
+0x6B 0x006B #LATIN SMALL LETTER K
+0x6C 0x006C #LATIN SMALL LETTER L
+0x6D 0x006D #LATIN SMALL LETTER M
+0x6E 0x006E #LATIN SMALL LETTER N
+0x6F 0x006F #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7A 0x007A #LATIN SMALL LETTER Z
+0x7B 0x007B #LEFT CURLY BRACKET
+0x7C 0x007C #VERTICAL LINE
+0x7D 0x007D #RIGHT CURLY BRACKET
+0x7E 0x007E #TILDE
+0x7F 0x007F #DELETE
+0x80 #UNDEFINED
+0x81 #DBCS LEAD BYTE
+0x82 #DBCS LEAD BYTE
+0x83 #DBCS LEAD BYTE
+0x84 #DBCS LEAD BYTE
+0x85 #DBCS LEAD BYTE
+0x86 #DBCS LEAD BYTE
+0x87 #DBCS LEAD BYTE
+0x88 #DBCS LEAD BYTE
+0x89 #DBCS LEAD BYTE
+0x8A #DBCS LEAD BYTE
+0x8B #DBCS LEAD BYTE
+0x8C #DBCS LEAD BYTE
+0x8D #DBCS LEAD BYTE
+0x8E #DBCS LEAD BYTE
+0x8F #DBCS LEAD BYTE
+0x90 #DBCS LEAD BYTE
+0x91 #DBCS LEAD BYTE
+0x92 #DBCS LEAD BYTE
+0x93 #DBCS LEAD BYTE
+0x94 #DBCS LEAD BYTE
+0x95 #DBCS LEAD BYTE
+0x96 #DBCS LEAD BYTE
+0x97 #DBCS LEAD BYTE
+0x98 #DBCS LEAD BYTE
+0x99 #DBCS LEAD BYTE
+0x9A #DBCS LEAD BYTE
+0x9B #DBCS LEAD BYTE
+0x9C #DBCS LEAD BYTE
+0x9D #DBCS LEAD BYTE
+0x9E #DBCS LEAD BYTE
+0x9F #DBCS LEAD BYTE
+0xA0 #DBCS LEAD BYTE
+0xA1 #DBCS LEAD BYTE
+0xA2 #DBCS LEAD BYTE
+0xA3 #DBCS LEAD BYTE
+0xA4 #DBCS LEAD BYTE
+0xA5 #DBCS LEAD BYTE
+0xA6 #DBCS LEAD BYTE
+0xA7 #DBCS LEAD BYTE
+0xA8 #DBCS LEAD BYTE
+0xA9 #DBCS LEAD BYTE
+0xAA #DBCS LEAD BYTE
+0xAB #DBCS LEAD BYTE
+0xAC #DBCS LEAD BYTE
+0xAD #DBCS LEAD BYTE
+0xAE #DBCS LEAD BYTE
+0xAF #DBCS LEAD BYTE
+0xB0 #DBCS LEAD BYTE
+0xB1 #DBCS LEAD BYTE
+0xB2 #DBCS LEAD BYTE
+0xB3 #DBCS LEAD BYTE
+0xB4 #DBCS LEAD BYTE
+0xB5 #DBCS LEAD BYTE
+0xB6 #DBCS LEAD BYTE
+0xB7 #DBCS LEAD BYTE
+0xB8 #DBCS LEAD BYTE
+0xB9 #DBCS LEAD BYTE
+0xBA #DBCS LEAD BYTE
+0xBB #DBCS LEAD BYTE
+0xBC #DBCS LEAD BYTE
+0xBD #DBCS LEAD BYTE
+0xBE #DBCS LEAD BYTE
+0xBF #DBCS LEAD BYTE
+0xC0 #DBCS LEAD BYTE
+0xC1 #DBCS LEAD BYTE
+0xC2 #DBCS LEAD BYTE
+0xC3 #DBCS LEAD BYTE
+0xC4 #DBCS LEAD BYTE
+0xC5 #DBCS LEAD BYTE
+0xC6 #DBCS LEAD BYTE
+0xC7 #DBCS LEAD BYTE
+0xC8 #DBCS LEAD BYTE
+0xC9 #DBCS LEAD BYTE
+0xCA #DBCS LEAD BYTE
+0xCB #DBCS LEAD BYTE
+0xCC #DBCS LEAD BYTE
+0xCD #DBCS LEAD BYTE
+0xCE #DBCS LEAD BYTE
+0xCF #DBCS LEAD BYTE
+0xD0 #DBCS LEAD BYTE
+0xD1 #DBCS LEAD BYTE
+0xD2 #DBCS LEAD BYTE
+0xD3 #DBCS LEAD BYTE
+0xD4 #DBCS LEAD BYTE
+0xD5 #DBCS LEAD BYTE
+0xD6 #DBCS LEAD BYTE
+0xD7 #DBCS LEAD BYTE
+0xD8 #DBCS LEAD BYTE
+0xD9 #DBCS LEAD BYTE
+0xDA #DBCS LEAD BYTE
+0xDB #DBCS LEAD BYTE
+0xDC #DBCS LEAD BYTE
+0xDD #DBCS LEAD BYTE
+0xDE #DBCS LEAD BYTE
+0xDF #DBCS LEAD BYTE
+0xE0 #DBCS LEAD BYTE
+0xE1 #DBCS LEAD BYTE
+0xE2 #DBCS LEAD BYTE
+0xE3 #DBCS LEAD BYTE
+0xE4 #DBCS LEAD BYTE
+0xE5 #DBCS LEAD BYTE
+0xE6 #DBCS LEAD BYTE
+0xE7 #DBCS LEAD BYTE
+0xE8 #DBCS LEAD BYTE
+0xE9 #DBCS LEAD BYTE
+0xEA #DBCS LEAD BYTE
+0xEB #DBCS LEAD BYTE
+0xEC #DBCS LEAD BYTE
+0xED #DBCS LEAD BYTE
+0xEE #DBCS LEAD BYTE
+0xEF #DBCS LEAD BYTE
+0xF0 #DBCS LEAD BYTE
+0xF1 #DBCS LEAD BYTE
+0xF2 #DBCS LEAD BYTE
+0xF3 #DBCS LEAD BYTE
+0xF4 #DBCS LEAD BYTE
+0xF5 #DBCS LEAD BYTE
+0xF6 #DBCS LEAD BYTE
+0xF7 #DBCS LEAD BYTE
+0xF8 #DBCS LEAD BYTE
+0xF9 #DBCS LEAD BYTE
+0xFA #DBCS LEAD BYTE
+0xFB #DBCS LEAD BYTE
+0xFC #DBCS LEAD BYTE
+0xFD #DBCS LEAD BYTE
+0xFE #DBCS LEAD BYTE
+0xFF #UNDEFINED
+0x8140 0x4E02 #CJK UNIFIED IDEOGRAPH
+0x8141 0x4E04 #CJK UNIFIED IDEOGRAPH
+0x8142 0x4E05 #CJK UNIFIED IDEOGRAPH
+0x8143 0x4E06 #CJK UNIFIED IDEOGRAPH
+0x8144 0x4E0F #CJK UNIFIED IDEOGRAPH
+0x8145 0x4E12 #CJK UNIFIED IDEOGRAPH
+0x8146 0x4E17 #CJK UNIFIED IDEOGRAPH
+0x8147 0x4E1F #CJK UNIFIED IDEOGRAPH
+0x8148 0x4E20 #CJK UNIFIED IDEOGRAPH
+0x8149 0x4E21 #CJK UNIFIED IDEOGRAPH
+0x814A 0x4E23 #CJK UNIFIED IDEOGRAPH
+0x814B 0x4E26 #CJK UNIFIED IDEOGRAPH
+0x814C 0x4E29 #CJK UNIFIED IDEOGRAPH
+0x814D 0x4E2E #CJK UNIFIED IDEOGRAPH
+0x814E 0x4E2F #CJK UNIFIED IDEOGRAPH
+0x814F 0x4E31 #CJK UNIFIED IDEOGRAPH
+0x8150 0x4E33 #CJK UNIFIED IDEOGRAPH
+0x8151 0x4E35 #CJK UNIFIED IDEOGRAPH
+0x8152 0x4E37 #CJK UNIFIED IDEOGRAPH
+0x8153 0x4E3C #CJK UNIFIED IDEOGRAPH
+0x8154 0x4E40 #CJK UNIFIED IDEOGRAPH
+0x8155 0x4E41 #CJK UNIFIED IDEOGRAPH
+0x8156 0x4E42 #CJK UNIFIED IDEOGRAPH
+0x8157 0x4E44 #CJK UNIFIED IDEOGRAPH
+0x8158 0x4E46 #CJK UNIFIED IDEOGRAPH
+0x8159 0x4E4A #CJK UNIFIED IDEOGRAPH
+0x815A 0x4E51 #CJK UNIFIED IDEOGRAPH
+0x815B 0x4E55 #CJK UNIFIED IDEOGRAPH
+0x815C 0x4E57 #CJK UNIFIED IDEOGRAPH
+0x815D 0x4E5A #CJK UNIFIED IDEOGRAPH
+0x815E 0x4E5B #CJK UNIFIED IDEOGRAPH
+0x815F 0x4E62 #CJK UNIFIED IDEOGRAPH
+0x8160 0x4E63 #CJK UNIFIED IDEOGRAPH
+0x8161 0x4E64 #CJK UNIFIED IDEOGRAPH
+0x8162 0x4E65 #CJK UNIFIED IDEOGRAPH
+0x8163 0x4E67 #CJK UNIFIED IDEOGRAPH
+0x8164 0x4E68 #CJK UNIFIED IDEOGRAPH
+0x8165 0x4E6A #CJK UNIFIED IDEOGRAPH
+0x8166 0x4E6B #CJK UNIFIED IDEOGRAPH
+0x8167 0x4E6C #CJK UNIFIED IDEOGRAPH
+0x8168 0x4E6D #CJK UNIFIED IDEOGRAPH
+0x8169 0x4E6E #CJK UNIFIED IDEOGRAPH
+0x816A 0x4E6F #CJK UNIFIED IDEOGRAPH
+0x816B 0x4E72 #CJK UNIFIED IDEOGRAPH
+0x816C 0x4E74 #CJK UNIFIED IDEOGRAPH
+0x816D 0x4E75 #CJK UNIFIED IDEOGRAPH
+0x816E 0x4E76 #CJK UNIFIED IDEOGRAPH
+0x816F 0x4E77 #CJK UNIFIED IDEOGRAPH
+0x8170 0x4E78 #CJK UNIFIED IDEOGRAPH
+0x8171 0x4E79 #CJK UNIFIED IDEOGRAPH
+0x8172 0x4E7A #CJK UNIFIED IDEOGRAPH
+0x8173 0x4E7B #CJK UNIFIED IDEOGRAPH
+0x8174 0x4E7C #CJK UNIFIED IDEOGRAPH
+0x8175 0x4E7D #CJK UNIFIED IDEOGRAPH
+0x8176 0x4E7F #CJK UNIFIED IDEOGRAPH
+0x8177 0x4E80 #CJK UNIFIED IDEOGRAPH
+0x8178 0x4E81 #CJK UNIFIED IDEOGRAPH
+0x8179 0x4E82 #CJK UNIFIED IDEOGRAPH
+0x817A 0x4E83 #CJK UNIFIED IDEOGRAPH
+0x817B 0x4E84 #CJK UNIFIED IDEOGRAPH
+0x817C 0x4E85 #CJK UNIFIED IDEOGRAPH
+0x817D 0x4E87 #CJK UNIFIED IDEOGRAPH
+0x817E 0x4E8A #CJK UNIFIED IDEOGRAPH
+0x8180 0x4E90 #CJK UNIFIED IDEOGRAPH
+0x8181 0x4E96 #CJK UNIFIED IDEOGRAPH
+0x8182 0x4E97 #CJK UNIFIED IDEOGRAPH
+0x8183 0x4E99 #CJK UNIFIED IDEOGRAPH
+0x8184 0x4E9C #CJK UNIFIED IDEOGRAPH
+0x8185 0x4E9D #CJK UNIFIED IDEOGRAPH
+0x8186 0x4E9E #CJK UNIFIED IDEOGRAPH
+0x8187 0x4EA3 #CJK UNIFIED IDEOGRAPH
+0x8188 0x4EAA #CJK UNIFIED IDEOGRAPH
+0x8189 0x4EAF #CJK UNIFIED IDEOGRAPH
+0x818A 0x4EB0 #CJK UNIFIED IDEOGRAPH
+0x818B 0x4EB1 #CJK UNIFIED IDEOGRAPH
+0x818C 0x4EB4 #CJK UNIFIED IDEOGRAPH
+0x818D 0x4EB6 #CJK UNIFIED IDEOGRAPH
+0x818E 0x4EB7 #CJK UNIFIED IDEOGRAPH
+0x818F 0x4EB8 #CJK UNIFIED IDEOGRAPH
+0x8190 0x4EB9 #CJK UNIFIED IDEOGRAPH
+0x8191 0x4EBC #CJK UNIFIED IDEOGRAPH
+0x8192 0x4EBD #CJK UNIFIED IDEOGRAPH
+0x8193 0x4EBE #CJK UNIFIED IDEOGRAPH
+0x8194 0x4EC8 #CJK UNIFIED IDEOGRAPH
+0x8195 0x4ECC #CJK UNIFIED IDEOGRAPH
+0x8196 0x4ECF #CJK UNIFIED IDEOGRAPH
+0x8197 0x4ED0 #CJK UNIFIED IDEOGRAPH
+0x8198 0x4ED2 #CJK UNIFIED IDEOGRAPH
+0x8199 0x4EDA #CJK UNIFIED IDEOGRAPH
+0x819A 0x4EDB #CJK UNIFIED IDEOGRAPH
+0x819B 0x4EDC #CJK UNIFIED IDEOGRAPH
+0x819C 0x4EE0 #CJK UNIFIED IDEOGRAPH
+0x819D 0x4EE2 #CJK UNIFIED IDEOGRAPH
+0x819E 0x4EE6 #CJK UNIFIED IDEOGRAPH
+0x819F 0x4EE7 #CJK UNIFIED IDEOGRAPH
+0x81A0 0x4EE9 #CJK UNIFIED IDEOGRAPH
+0x81A1 0x4EED #CJK UNIFIED IDEOGRAPH
+0x81A2 0x4EEE #CJK UNIFIED IDEOGRAPH
+0x81A3 0x4EEF #CJK UNIFIED IDEOGRAPH
+0x81A4 0x4EF1 #CJK UNIFIED IDEOGRAPH
+0x81A5 0x4EF4 #CJK UNIFIED IDEOGRAPH
+0x81A6 0x4EF8 #CJK UNIFIED IDEOGRAPH
+0x81A7 0x4EF9 #CJK UNIFIED IDEOGRAPH
+0x81A8 0x4EFA #CJK UNIFIED IDEOGRAPH
+0x81A9 0x4EFC #CJK UNIFIED IDEOGRAPH
+0x81AA 0x4EFE #CJK UNIFIED IDEOGRAPH
+0x81AB 0x4F00 #CJK UNIFIED IDEOGRAPH
+0x81AC 0x4F02 #CJK UNIFIED IDEOGRAPH
+0x81AD 0x4F03 #CJK UNIFIED IDEOGRAPH
+0x81AE 0x4F04 #CJK UNIFIED IDEOGRAPH
+0x81AF 0x4F05 #CJK UNIFIED IDEOGRAPH
+0x81B0 0x4F06 #CJK UNIFIED IDEOGRAPH
+0x81B1 0x4F07 #CJK UNIFIED IDEOGRAPH
+0x81B2 0x4F08 #CJK UNIFIED IDEOGRAPH
+0x81B3 0x4F0B #CJK UNIFIED IDEOGRAPH
+0x81B4 0x4F0C #CJK UNIFIED IDEOGRAPH
+0x81B5 0x4F12 #CJK UNIFIED IDEOGRAPH
+0x81B6 0x4F13 #CJK UNIFIED IDEOGRAPH
+0x81B7 0x4F14 #CJK UNIFIED IDEOGRAPH
+0x81B8 0x4F15 #CJK UNIFIED IDEOGRAPH
+0x81B9 0x4F16 #CJK UNIFIED IDEOGRAPH
+0x81BA 0x4F1C #CJK UNIFIED IDEOGRAPH
+0x81BB 0x4F1D #CJK UNIFIED IDEOGRAPH
+0x81BC 0x4F21 #CJK UNIFIED IDEOGRAPH
+0x81BD 0x4F23 #CJK UNIFIED IDEOGRAPH
+0x81BE 0x4F28 #CJK UNIFIED IDEOGRAPH
+0x81BF 0x4F29 #CJK UNIFIED IDEOGRAPH
+0x81C0 0x4F2C #CJK UNIFIED IDEOGRAPH
+0x81C1 0x4F2D #CJK UNIFIED IDEOGRAPH
+0x81C2 0x4F2E #CJK UNIFIED IDEOGRAPH
+0x81C3 0x4F31 #CJK UNIFIED IDEOGRAPH
+0x81C4 0x4F33 #CJK UNIFIED IDEOGRAPH
+0x81C5 0x4F35 #CJK UNIFIED IDEOGRAPH
+0x81C6 0x4F37 #CJK UNIFIED IDEOGRAPH
+0x81C7 0x4F39 #CJK UNIFIED IDEOGRAPH
+0x81C8 0x4F3B #CJK UNIFIED IDEOGRAPH
+0x81C9 0x4F3E #CJK UNIFIED IDEOGRAPH
+0x81CA 0x4F3F #CJK UNIFIED IDEOGRAPH
+0x81CB 0x4F40 #CJK UNIFIED IDEOGRAPH
+0x81CC 0x4F41 #CJK UNIFIED IDEOGRAPH
+0x81CD 0x4F42 #CJK UNIFIED IDEOGRAPH
+0x81CE 0x4F44 #CJK UNIFIED IDEOGRAPH
+0x81CF 0x4F45 #CJK UNIFIED IDEOGRAPH
+0x81D0 0x4F47 #CJK UNIFIED IDEOGRAPH
+0x81D1 0x4F48 #CJK UNIFIED IDEOGRAPH
+0x81D2 0x4F49 #CJK UNIFIED IDEOGRAPH
+0x81D3 0x4F4A #CJK UNIFIED IDEOGRAPH
+0x81D4 0x4F4B #CJK UNIFIED IDEOGRAPH
+0x81D5 0x4F4C #CJK UNIFIED IDEOGRAPH
+0x81D6 0x4F52 #CJK UNIFIED IDEOGRAPH
+0x81D7 0x4F54 #CJK UNIFIED IDEOGRAPH
+0x81D8 0x4F56 #CJK UNIFIED IDEOGRAPH
+0x81D9 0x4F61 #CJK UNIFIED IDEOGRAPH
+0x81DA 0x4F62 #CJK UNIFIED IDEOGRAPH
+0x81DB 0x4F66 #CJK UNIFIED IDEOGRAPH
+0x81DC 0x4F68 #CJK UNIFIED IDEOGRAPH
+0x81DD 0x4F6A #CJK UNIFIED IDEOGRAPH
+0x81DE 0x4F6B #CJK UNIFIED IDEOGRAPH
+0x81DF 0x4F6D #CJK UNIFIED IDEOGRAPH
+0x81E0 0x4F6E #CJK UNIFIED IDEOGRAPH
+0x81E1 0x4F71 #CJK UNIFIED IDEOGRAPH
+0x81E2 0x4F72 #CJK UNIFIED IDEOGRAPH
+0x81E3 0x4F75 #CJK UNIFIED IDEOGRAPH
+0x81E4 0x4F77 #CJK UNIFIED IDEOGRAPH
+0x81E5 0x4F78 #CJK UNIFIED IDEOGRAPH
+0x81E6 0x4F79 #CJK UNIFIED IDEOGRAPH
+0x81E7 0x4F7A #CJK UNIFIED IDEOGRAPH
+0x81E8 0x4F7D #CJK UNIFIED IDEOGRAPH
+0x81E9 0x4F80 #CJK UNIFIED IDEOGRAPH
+0x81EA 0x4F81 #CJK UNIFIED IDEOGRAPH
+0x81EB 0x4F82 #CJK UNIFIED IDEOGRAPH
+0x81EC 0x4F85 #CJK UNIFIED IDEOGRAPH
+0x81ED 0x4F86 #CJK UNIFIED IDEOGRAPH
+0x81EE 0x4F87 #CJK UNIFIED IDEOGRAPH
+0x81EF 0x4F8A #CJK UNIFIED IDEOGRAPH
+0x81F0 0x4F8C #CJK UNIFIED IDEOGRAPH
+0x81F1 0x4F8E #CJK UNIFIED IDEOGRAPH
+0x81F2 0x4F90 #CJK UNIFIED IDEOGRAPH
+0x81F3 0x4F92 #CJK UNIFIED IDEOGRAPH
+0x81F4 0x4F93 #CJK UNIFIED IDEOGRAPH
+0x81F5 0x4F95 #CJK UNIFIED IDEOGRAPH
+0x81F6 0x4F96 #CJK UNIFIED IDEOGRAPH
+0x81F7 0x4F98 #CJK UNIFIED IDEOGRAPH
+0x81F8 0x4F99 #CJK UNIFIED IDEOGRAPH
+0x81F9 0x4F9A #CJK UNIFIED IDEOGRAPH
+0x81FA 0x4F9C #CJK UNIFIED IDEOGRAPH
+0x81FB 0x4F9E #CJK UNIFIED IDEOGRAPH
+0x81FC 0x4F9F #CJK UNIFIED IDEOGRAPH
+0x81FD 0x4FA1 #CJK UNIFIED IDEOGRAPH
+0x81FE 0x4FA2 #CJK UNIFIED IDEOGRAPH
+0x8240 0x4FA4 #CJK UNIFIED IDEOGRAPH
+0x8241 0x4FAB #CJK UNIFIED IDEOGRAPH
+0x8242 0x4FAD #CJK UNIFIED IDEOGRAPH
+0x8243 0x4FB0 #CJK UNIFIED IDEOGRAPH
+0x8244 0x4FB1 #CJK UNIFIED IDEOGRAPH
+0x8245 0x4FB2 #CJK UNIFIED IDEOGRAPH
+0x8246 0x4FB3 #CJK UNIFIED IDEOGRAPH
+0x8247 0x4FB4 #CJK UNIFIED IDEOGRAPH
+0x8248 0x4FB6 #CJK UNIFIED IDEOGRAPH
+0x8249 0x4FB7 #CJK UNIFIED IDEOGRAPH
+0x824A 0x4FB8 #CJK UNIFIED IDEOGRAPH
+0x824B 0x4FB9 #CJK UNIFIED IDEOGRAPH
+0x824C 0x4FBA #CJK UNIFIED IDEOGRAPH
+0x824D 0x4FBB #CJK UNIFIED IDEOGRAPH
+0x824E 0x4FBC #CJK UNIFIED IDEOGRAPH
+0x824F 0x4FBD #CJK UNIFIED IDEOGRAPH
+0x8250 0x4FBE #CJK UNIFIED IDEOGRAPH
+0x8251 0x4FC0 #CJK UNIFIED IDEOGRAPH
+0x8252 0x4FC1 #CJK UNIFIED IDEOGRAPH
+0x8253 0x4FC2 #CJK UNIFIED IDEOGRAPH
+0x8254 0x4FC6 #CJK UNIFIED IDEOGRAPH
+0x8255 0x4FC7 #CJK UNIFIED IDEOGRAPH
+0x8256 0x4FC8 #CJK UNIFIED IDEOGRAPH
+0x8257 0x4FC9 #CJK UNIFIED IDEOGRAPH
+0x8258 0x4FCB #CJK UNIFIED IDEOGRAPH
+0x8259 0x4FCC #CJK UNIFIED IDEOGRAPH
+0x825A 0x4FCD #CJK UNIFIED IDEOGRAPH
+0x825B 0x4FD2 #CJK UNIFIED IDEOGRAPH
+0x825C 0x4FD3 #CJK UNIFIED IDEOGRAPH
+0x825D 0x4FD4 #CJK UNIFIED IDEOGRAPH
+0x825E 0x4FD5 #CJK UNIFIED IDEOGRAPH
+0x825F 0x4FD6 #CJK UNIFIED IDEOGRAPH
+0x8260 0x4FD9 #CJK UNIFIED IDEOGRAPH
+0x8261 0x4FDB #CJK UNIFIED IDEOGRAPH
+0x8262 0x4FE0 #CJK UNIFIED IDEOGRAPH
+0x8263 0x4FE2 #CJK UNIFIED IDEOGRAPH
+0x8264 0x4FE4 #CJK UNIFIED IDEOGRAPH
+0x8265 0x4FE5 #CJK UNIFIED IDEOGRAPH
+0x8266 0x4FE7 #CJK UNIFIED IDEOGRAPH
+0x8267 0x4FEB #CJK UNIFIED IDEOGRAPH
+0x8268 0x4FEC #CJK UNIFIED IDEOGRAPH
+0x8269 0x4FF0 #CJK UNIFIED IDEOGRAPH
+0x826A 0x4FF2 #CJK UNIFIED IDEOGRAPH
+0x826B 0x4FF4 #CJK UNIFIED IDEOGRAPH
+0x826C 0x4FF5 #CJK UNIFIED IDEOGRAPH
+0x826D 0x4FF6 #CJK UNIFIED IDEOGRAPH
+0x826E 0x4FF7 #CJK UNIFIED IDEOGRAPH
+0x826F 0x4FF9 #CJK UNIFIED IDEOGRAPH
+0x8270 0x4FFB #CJK UNIFIED IDEOGRAPH
+0x8271 0x4FFC #CJK UNIFIED IDEOGRAPH
+0x8272 0x4FFD #CJK UNIFIED IDEOGRAPH
+0x8273 0x4FFF #CJK UNIFIED IDEOGRAPH
+0x8274 0x5000 #CJK UNIFIED IDEOGRAPH
+0x8275 0x5001 #CJK UNIFIED IDEOGRAPH
+0x8276 0x5002 #CJK UNIFIED IDEOGRAPH
+0x8277 0x5003 #CJK UNIFIED IDEOGRAPH
+0x8278 0x5004 #CJK UNIFIED IDEOGRAPH
+0x8279 0x5005 #CJK UNIFIED IDEOGRAPH
+0x827A 0x5006 #CJK UNIFIED IDEOGRAPH
+0x827B 0x5007 #CJK UNIFIED IDEOGRAPH
+0x827C 0x5008 #CJK UNIFIED IDEOGRAPH
+0x827D 0x5009 #CJK UNIFIED IDEOGRAPH
+0x827E 0x500A #CJK UNIFIED IDEOGRAPH
+0x8280 0x500B #CJK UNIFIED IDEOGRAPH
+0x8281 0x500E #CJK UNIFIED IDEOGRAPH
+0x8282 0x5010 #CJK UNIFIED IDEOGRAPH
+0x8283 0x5011 #CJK UNIFIED IDEOGRAPH
+0x8284 0x5013 #CJK UNIFIED IDEOGRAPH
+0x8285 0x5015 #CJK UNIFIED IDEOGRAPH
+0x8286 0x5016 #CJK UNIFIED IDEOGRAPH
+0x8287 0x5017 #CJK UNIFIED IDEOGRAPH
+0x8288 0x501B #CJK UNIFIED IDEOGRAPH
+0x8289 0x501D #CJK UNIFIED IDEOGRAPH
+0x828A 0x501E #CJK UNIFIED IDEOGRAPH
+0x828B 0x5020 #CJK UNIFIED IDEOGRAPH
+0x828C 0x5022 #CJK UNIFIED IDEOGRAPH
+0x828D 0x5023 #CJK UNIFIED IDEOGRAPH
+0x828E 0x5024 #CJK UNIFIED IDEOGRAPH
+0x828F 0x5027 #CJK UNIFIED IDEOGRAPH
+0x8290 0x502B #CJK UNIFIED IDEOGRAPH
+0x8291 0x502F #CJK UNIFIED IDEOGRAPH
+0x8292 0x5030 #CJK UNIFIED IDEOGRAPH
+0x8293 0x5031 #CJK UNIFIED IDEOGRAPH
+0x8294 0x5032 #CJK UNIFIED IDEOGRAPH
+0x8295 0x5033 #CJK UNIFIED IDEOGRAPH
+0x8296 0x5034 #CJK UNIFIED IDEOGRAPH
+0x8297 0x5035 #CJK UNIFIED IDEOGRAPH
+0x8298 0x5036 #CJK UNIFIED IDEOGRAPH
+0x8299 0x5037 #CJK UNIFIED IDEOGRAPH
+0x829A 0x5038 #CJK UNIFIED IDEOGRAPH
+0x829B 0x5039 #CJK UNIFIED IDEOGRAPH
+0x829C 0x503B #CJK UNIFIED IDEOGRAPH
+0x829D 0x503D #CJK UNIFIED IDEOGRAPH
+0x829E 0x503F #CJK UNIFIED IDEOGRAPH
+0x829F 0x5040 #CJK UNIFIED IDEOGRAPH
+0x82A0 0x5041 #CJK UNIFIED IDEOGRAPH
+0x82A1 0x5042 #CJK UNIFIED IDEOGRAPH
+0x82A2 0x5044 #CJK UNIFIED IDEOGRAPH
+0x82A3 0x5045 #CJK UNIFIED IDEOGRAPH
+0x82A4 0x5046 #CJK UNIFIED IDEOGRAPH
+0x82A5 0x5049 #CJK UNIFIED IDEOGRAPH
+0x82A6 0x504A #CJK UNIFIED IDEOGRAPH
+0x82A7 0x504B #CJK UNIFIED IDEOGRAPH
+0x82A8 0x504D #CJK UNIFIED IDEOGRAPH
+0x82A9 0x5050 #CJK UNIFIED IDEOGRAPH
+0x82AA 0x5051 #CJK UNIFIED IDEOGRAPH
+0x82AB 0x5052 #CJK UNIFIED IDEOGRAPH
+0x82AC 0x5053 #CJK UNIFIED IDEOGRAPH
+0x82AD 0x5054 #CJK UNIFIED IDEOGRAPH
+0x82AE 0x5056 #CJK UNIFIED IDEOGRAPH
+0x82AF 0x5057 #CJK UNIFIED IDEOGRAPH
+0x82B0 0x5058 #CJK UNIFIED IDEOGRAPH
+0x82B1 0x5059 #CJK UNIFIED IDEOGRAPH
+0x82B2 0x505B #CJK UNIFIED IDEOGRAPH
+0x82B3 0x505D #CJK UNIFIED IDEOGRAPH
+0x82B4 0x505E #CJK UNIFIED IDEOGRAPH
+0x82B5 0x505F #CJK UNIFIED IDEOGRAPH
+0x82B6 0x5060 #CJK UNIFIED IDEOGRAPH
+0x82B7 0x5061 #CJK UNIFIED IDEOGRAPH
+0x82B8 0x5062 #CJK UNIFIED IDEOGRAPH
+0x82B9 0x5063 #CJK UNIFIED IDEOGRAPH
+0x82BA 0x5064 #CJK UNIFIED IDEOGRAPH
+0x82BB 0x5066 #CJK UNIFIED IDEOGRAPH
+0x82BC 0x5067 #CJK UNIFIED IDEOGRAPH
+0x82BD 0x5068 #CJK UNIFIED IDEOGRAPH
+0x82BE 0x5069 #CJK UNIFIED IDEOGRAPH
+0x82BF 0x506A #CJK UNIFIED IDEOGRAPH
+0x82C0 0x506B #CJK UNIFIED IDEOGRAPH
+0x82C1 0x506D #CJK UNIFIED IDEOGRAPH
+0x82C2 0x506E #CJK UNIFIED IDEOGRAPH
+0x82C3 0x506F #CJK UNIFIED IDEOGRAPH
+0x82C4 0x5070 #CJK UNIFIED IDEOGRAPH
+0x82C5 0x5071 #CJK UNIFIED IDEOGRAPH
+0x82C6 0x5072 #CJK UNIFIED IDEOGRAPH
+0x82C7 0x5073 #CJK UNIFIED IDEOGRAPH
+0x82C8 0x5074 #CJK UNIFIED IDEOGRAPH
+0x82C9 0x5075 #CJK UNIFIED IDEOGRAPH
+0x82CA 0x5078 #CJK UNIFIED IDEOGRAPH
+0x82CB 0x5079 #CJK UNIFIED IDEOGRAPH
+0x82CC 0x507A #CJK UNIFIED IDEOGRAPH
+0x82CD 0x507C #CJK UNIFIED IDEOGRAPH
+0x82CE 0x507D #CJK UNIFIED IDEOGRAPH
+0x82CF 0x5081 #CJK UNIFIED IDEOGRAPH
+0x82D0 0x5082 #CJK UNIFIED IDEOGRAPH
+0x82D1 0x5083 #CJK UNIFIED IDEOGRAPH
+0x82D2 0x5084 #CJK UNIFIED IDEOGRAPH
+0x82D3 0x5086 #CJK UNIFIED IDEOGRAPH
+0x82D4 0x5087 #CJK UNIFIED IDEOGRAPH
+0x82D5 0x5089 #CJK UNIFIED IDEOGRAPH
+0x82D6 0x508A #CJK UNIFIED IDEOGRAPH
+0x82D7 0x508B #CJK UNIFIED IDEOGRAPH
+0x82D8 0x508C #CJK UNIFIED IDEOGRAPH
+0x82D9 0x508E #CJK UNIFIED IDEOGRAPH
+0x82DA 0x508F #CJK UNIFIED IDEOGRAPH
+0x82DB 0x5090 #CJK UNIFIED IDEOGRAPH
+0x82DC 0x5091 #CJK UNIFIED IDEOGRAPH
+0x82DD 0x5092 #CJK UNIFIED IDEOGRAPH
+0x82DE 0x5093 #CJK UNIFIED IDEOGRAPH
+0x82DF 0x5094 #CJK UNIFIED IDEOGRAPH
+0x82E0 0x5095 #CJK UNIFIED IDEOGRAPH
+0x82E1 0x5096 #CJK UNIFIED IDEOGRAPH
+0x82E2 0x5097 #CJK UNIFIED IDEOGRAPH
+0x82E3 0x5098 #CJK UNIFIED IDEOGRAPH
+0x82E4 0x5099 #CJK UNIFIED IDEOGRAPH
+0x82E5 0x509A #CJK UNIFIED IDEOGRAPH
+0x82E6 0x509B #CJK UNIFIED IDEOGRAPH
+0x82E7 0x509C #CJK UNIFIED IDEOGRAPH
+0x82E8 0x509D #CJK UNIFIED IDEOGRAPH
+0x82E9 0x509E #CJK UNIFIED IDEOGRAPH
+0x82EA 0x509F #CJK UNIFIED IDEOGRAPH
+0x82EB 0x50A0 #CJK UNIFIED IDEOGRAPH
+0x82EC 0x50A1 #CJK UNIFIED IDEOGRAPH
+0x82ED 0x50A2 #CJK UNIFIED IDEOGRAPH
+0x82EE 0x50A4 #CJK UNIFIED IDEOGRAPH
+0x82EF 0x50A6 #CJK UNIFIED IDEOGRAPH
+0x82F0 0x50AA #CJK UNIFIED IDEOGRAPH
+0x82F1 0x50AB #CJK UNIFIED IDEOGRAPH
+0x82F2 0x50AD #CJK UNIFIED IDEOGRAPH
+0x82F3 0x50AE #CJK UNIFIED IDEOGRAPH
+0x82F4 0x50AF #CJK UNIFIED IDEOGRAPH
+0x82F5 0x50B0 #CJK UNIFIED IDEOGRAPH
+0x82F6 0x50B1 #CJK UNIFIED IDEOGRAPH
+0x82F7 0x50B3 #CJK UNIFIED IDEOGRAPH
+0x82F8 0x50B4 #CJK UNIFIED IDEOGRAPH
+0x82F9 0x50B5 #CJK UNIFIED IDEOGRAPH
+0x82FA 0x50B6 #CJK UNIFIED IDEOGRAPH
+0x82FB 0x50B7 #CJK UNIFIED IDEOGRAPH
+0x82FC 0x50B8 #CJK UNIFIED IDEOGRAPH
+0x82FD 0x50B9 #CJK UNIFIED IDEOGRAPH
+0x82FE 0x50BC #CJK UNIFIED IDEOGRAPH
+0x8340 0x50BD #CJK UNIFIED IDEOGRAPH
+0x8341 0x50BE #CJK UNIFIED IDEOGRAPH
+0x8342 0x50BF #CJK UNIFIED IDEOGRAPH
+0x8343 0x50C0 #CJK UNIFIED IDEOGRAPH
+0x8344 0x50C1 #CJK UNIFIED IDEOGRAPH
+0x8345 0x50C2 #CJK UNIFIED IDEOGRAPH
+0x8346 0x50C3 #CJK UNIFIED IDEOGRAPH
+0x8347 0x50C4 #CJK UNIFIED IDEOGRAPH
+0x8348 0x50C5 #CJK UNIFIED IDEOGRAPH
+0x8349 0x50C6 #CJK UNIFIED IDEOGRAPH
+0x834A 0x50C7 #CJK UNIFIED IDEOGRAPH
+0x834B 0x50C8 #CJK UNIFIED IDEOGRAPH
+0x834C 0x50C9 #CJK UNIFIED IDEOGRAPH
+0x834D 0x50CA #CJK UNIFIED IDEOGRAPH
+0x834E 0x50CB #CJK UNIFIED IDEOGRAPH
+0x834F 0x50CC #CJK UNIFIED IDEOGRAPH
+0x8350 0x50CD #CJK UNIFIED IDEOGRAPH
+0x8351 0x50CE #CJK UNIFIED IDEOGRAPH
+0x8352 0x50D0 #CJK UNIFIED IDEOGRAPH
+0x8353 0x50D1 #CJK UNIFIED IDEOGRAPH
+0x8354 0x50D2 #CJK UNIFIED IDEOGRAPH
+0x8355 0x50D3 #CJK UNIFIED IDEOGRAPH
+0x8356 0x50D4 #CJK UNIFIED IDEOGRAPH
+0x8357 0x50D5 #CJK UNIFIED IDEOGRAPH
+0x8358 0x50D7 #CJK UNIFIED IDEOGRAPH
+0x8359 0x50D8 #CJK UNIFIED IDEOGRAPH
+0x835A 0x50D9 #CJK UNIFIED IDEOGRAPH
+0x835B 0x50DB #CJK UNIFIED IDEOGRAPH
+0x835C 0x50DC #CJK UNIFIED IDEOGRAPH
+0x835D 0x50DD #CJK UNIFIED IDEOGRAPH
+0x835E 0x50DE #CJK UNIFIED IDEOGRAPH
+0x835F 0x50DF #CJK UNIFIED IDEOGRAPH
+0x8360 0x50E0 #CJK UNIFIED IDEOGRAPH
+0x8361 0x50E1 #CJK UNIFIED IDEOGRAPH
+0x8362 0x50E2 #CJK UNIFIED IDEOGRAPH
+0x8363 0x50E3 #CJK UNIFIED IDEOGRAPH
+0x8364 0x50E4 #CJK UNIFIED IDEOGRAPH
+0x8365 0x50E5 #CJK UNIFIED IDEOGRAPH
+0x8366 0x50E8 #CJK UNIFIED IDEOGRAPH
+0x8367 0x50E9 #CJK UNIFIED IDEOGRAPH
+0x8368 0x50EA #CJK UNIFIED IDEOGRAPH
+0x8369 0x50EB #CJK UNIFIED IDEOGRAPH
+0x836A 0x50EF #CJK UNIFIED IDEOGRAPH
+0x836B 0x50F0 #CJK UNIFIED IDEOGRAPH
+0x836C 0x50F1 #CJK UNIFIED IDEOGRAPH
+0x836D 0x50F2 #CJK UNIFIED IDEOGRAPH
+0x836E 0x50F4 #CJK UNIFIED IDEOGRAPH
+0x836F 0x50F6 #CJK UNIFIED IDEOGRAPH
+0x8370 0x50F7 #CJK UNIFIED IDEOGRAPH
+0x8371 0x50F8 #CJK UNIFIED IDEOGRAPH
+0x8372 0x50F9 #CJK UNIFIED IDEOGRAPH
+0x8373 0x50FA #CJK UNIFIED IDEOGRAPH
+0x8374 0x50FC #CJK UNIFIED IDEOGRAPH
+0x8375 0x50FD #CJK UNIFIED IDEOGRAPH
+0x8376 0x50FE #CJK UNIFIED IDEOGRAPH
+0x8377 0x50FF #CJK UNIFIED IDEOGRAPH
+0x8378 0x5100 #CJK UNIFIED IDEOGRAPH
+0x8379 0x5101 #CJK UNIFIED IDEOGRAPH
+0x837A 0x5102 #CJK UNIFIED IDEOGRAPH
+0x837B 0x5103 #CJK UNIFIED IDEOGRAPH
+0x837C 0x5104 #CJK UNIFIED IDEOGRAPH
+0x837D 0x5105 #CJK UNIFIED IDEOGRAPH
+0x837E 0x5108 #CJK UNIFIED IDEOGRAPH
+0x8380 0x5109 #CJK UNIFIED IDEOGRAPH
+0x8381 0x510A #CJK UNIFIED IDEOGRAPH
+0x8382 0x510C #CJK UNIFIED IDEOGRAPH
+0x8383 0x510D #CJK UNIFIED IDEOGRAPH
+0x8384 0x510E #CJK UNIFIED IDEOGRAPH
+0x8385 0x510F #CJK UNIFIED IDEOGRAPH
+0x8386 0x5110 #CJK UNIFIED IDEOGRAPH
+0x8387 0x5111 #CJK UNIFIED IDEOGRAPH
+0x8388 0x5113 #CJK UNIFIED IDEOGRAPH
+0x8389 0x5114 #CJK UNIFIED IDEOGRAPH
+0x838A 0x5115 #CJK UNIFIED IDEOGRAPH
+0x838B 0x5116 #CJK UNIFIED IDEOGRAPH
+0x838C 0x5117 #CJK UNIFIED IDEOGRAPH
+0x838D 0x5118 #CJK UNIFIED IDEOGRAPH
+0x838E 0x5119 #CJK UNIFIED IDEOGRAPH
+0x838F 0x511A #CJK UNIFIED IDEOGRAPH
+0x8390 0x511B #CJK UNIFIED IDEOGRAPH
+0x8391 0x511C #CJK UNIFIED IDEOGRAPH
+0x8392 0x511D #CJK UNIFIED IDEOGRAPH
+0x8393 0x511E #CJK UNIFIED IDEOGRAPH
+0x8394 0x511F #CJK UNIFIED IDEOGRAPH
+0x8395 0x5120 #CJK UNIFIED IDEOGRAPH
+0x8396 0x5122 #CJK UNIFIED IDEOGRAPH
+0x8397 0x5123 #CJK UNIFIED IDEOGRAPH
+0x8398 0x5124 #CJK UNIFIED IDEOGRAPH
+0x8399 0x5125 #CJK UNIFIED IDEOGRAPH
+0x839A 0x5126 #CJK UNIFIED IDEOGRAPH
+0x839B 0x5127 #CJK UNIFIED IDEOGRAPH
+0x839C 0x5128 #CJK UNIFIED IDEOGRAPH
+0x839D 0x5129 #CJK UNIFIED IDEOGRAPH
+0x839E 0x512A #CJK UNIFIED IDEOGRAPH
+0x839F 0x512B #CJK UNIFIED IDEOGRAPH
+0x83A0 0x512C #CJK UNIFIED IDEOGRAPH
+0x83A1 0x512D #CJK UNIFIED IDEOGRAPH
+0x83A2 0x512E #CJK UNIFIED IDEOGRAPH
+0x83A3 0x512F #CJK UNIFIED IDEOGRAPH
+0x83A4 0x5130 #CJK UNIFIED IDEOGRAPH
+0x83A5 0x5131 #CJK UNIFIED IDEOGRAPH
+0x83A6 0x5132 #CJK UNIFIED IDEOGRAPH
+0x83A7 0x5133 #CJK UNIFIED IDEOGRAPH
+0x83A8 0x5134 #CJK UNIFIED IDEOGRAPH
+0x83A9 0x5135 #CJK UNIFIED IDEOGRAPH
+0x83AA 0x5136 #CJK UNIFIED IDEOGRAPH
+0x83AB 0x5137 #CJK UNIFIED IDEOGRAPH
+0x83AC 0x5138 #CJK UNIFIED IDEOGRAPH
+0x83AD 0x5139 #CJK UNIFIED IDEOGRAPH
+0x83AE 0x513A #CJK UNIFIED IDEOGRAPH
+0x83AF 0x513B #CJK UNIFIED IDEOGRAPH
+0x83B0 0x513C #CJK UNIFIED IDEOGRAPH
+0x83B1 0x513D #CJK UNIFIED IDEOGRAPH
+0x83B2 0x513E #CJK UNIFIED IDEOGRAPH
+0x83B3 0x5142 #CJK UNIFIED IDEOGRAPH
+0x83B4 0x5147 #CJK UNIFIED IDEOGRAPH
+0x83B5 0x514A #CJK UNIFIED IDEOGRAPH
+0x83B6 0x514C #CJK UNIFIED IDEOGRAPH
+0x83B7 0x514E #CJK UNIFIED IDEOGRAPH
+0x83B8 0x514F #CJK UNIFIED IDEOGRAPH
+0x83B9 0x5150 #CJK UNIFIED IDEOGRAPH
+0x83BA 0x5152 #CJK UNIFIED IDEOGRAPH
+0x83BB 0x5153 #CJK UNIFIED IDEOGRAPH
+0x83BC 0x5157 #CJK UNIFIED IDEOGRAPH
+0x83BD 0x5158 #CJK UNIFIED IDEOGRAPH
+0x83BE 0x5159 #CJK UNIFIED IDEOGRAPH
+0x83BF 0x515B #CJK UNIFIED IDEOGRAPH
+0x83C0 0x515D #CJK UNIFIED IDEOGRAPH
+0x83C1 0x515E #CJK UNIFIED IDEOGRAPH
+0x83C2 0x515F #CJK UNIFIED IDEOGRAPH
+0x83C3 0x5160 #CJK UNIFIED IDEOGRAPH
+0x83C4 0x5161 #CJK UNIFIED IDEOGRAPH
+0x83C5 0x5163 #CJK UNIFIED IDEOGRAPH
+0x83C6 0x5164 #CJK UNIFIED IDEOGRAPH
+0x83C7 0x5166 #CJK UNIFIED IDEOGRAPH
+0x83C8 0x5167 #CJK UNIFIED IDEOGRAPH
+0x83C9 0x5169 #CJK UNIFIED IDEOGRAPH
+0x83CA 0x516A #CJK UNIFIED IDEOGRAPH
+0x83CB 0x516F #CJK UNIFIED IDEOGRAPH
+0x83CC 0x5172 #CJK UNIFIED IDEOGRAPH
+0x83CD 0x517A #CJK UNIFIED IDEOGRAPH
+0x83CE 0x517E #CJK UNIFIED IDEOGRAPH
+0x83CF 0x517F #CJK UNIFIED IDEOGRAPH
+0x83D0 0x5183 #CJK UNIFIED IDEOGRAPH
+0x83D1 0x5184 #CJK UNIFIED IDEOGRAPH
+0x83D2 0x5186 #CJK UNIFIED IDEOGRAPH
+0x83D3 0x5187 #CJK UNIFIED IDEOGRAPH
+0x83D4 0x518A #CJK UNIFIED IDEOGRAPH
+0x83D5 0x518B #CJK UNIFIED IDEOGRAPH
+0x83D6 0x518E #CJK UNIFIED IDEOGRAPH
+0x83D7 0x518F #CJK UNIFIED IDEOGRAPH
+0x83D8 0x5190 #CJK UNIFIED IDEOGRAPH
+0x83D9 0x5191 #CJK UNIFIED IDEOGRAPH
+0x83DA 0x5193 #CJK UNIFIED IDEOGRAPH
+0x83DB 0x5194 #CJK UNIFIED IDEOGRAPH
+0x83DC 0x5198 #CJK UNIFIED IDEOGRAPH
+0x83DD 0x519A #CJK UNIFIED IDEOGRAPH
+0x83DE 0x519D #CJK UNIFIED IDEOGRAPH
+0x83DF 0x519E #CJK UNIFIED IDEOGRAPH
+0x83E0 0x519F #CJK UNIFIED IDEOGRAPH
+0x83E1 0x51A1 #CJK UNIFIED IDEOGRAPH
+0x83E2 0x51A3 #CJK UNIFIED IDEOGRAPH
+0x83E3 0x51A6 #CJK UNIFIED IDEOGRAPH
+0x83E4 0x51A7 #CJK UNIFIED IDEOGRAPH
+0x83E5 0x51A8 #CJK UNIFIED IDEOGRAPH
+0x83E6 0x51A9 #CJK UNIFIED IDEOGRAPH
+0x83E7 0x51AA #CJK UNIFIED IDEOGRAPH
+0x83E8 0x51AD #CJK UNIFIED IDEOGRAPH
+0x83E9 0x51AE #CJK UNIFIED IDEOGRAPH
+0x83EA 0x51B4 #CJK UNIFIED IDEOGRAPH
+0x83EB 0x51B8 #CJK UNIFIED IDEOGRAPH
+0x83EC 0x51B9 #CJK UNIFIED IDEOGRAPH
+0x83ED 0x51BA #CJK UNIFIED IDEOGRAPH
+0x83EE 0x51BE #CJK UNIFIED IDEOGRAPH
+0x83EF 0x51BF #CJK UNIFIED IDEOGRAPH
+0x83F0 0x51C1 #CJK UNIFIED IDEOGRAPH
+0x83F1 0x51C2 #CJK UNIFIED IDEOGRAPH
+0x83F2 0x51C3 #CJK UNIFIED IDEOGRAPH
+0x83F3 0x51C5 #CJK UNIFIED IDEOGRAPH
+0x83F4 0x51C8 #CJK UNIFIED IDEOGRAPH
+0x83F5 0x51CA #CJK UNIFIED IDEOGRAPH
+0x83F6 0x51CD #CJK UNIFIED IDEOGRAPH
+0x83F7 0x51CE #CJK UNIFIED IDEOGRAPH
+0x83F8 0x51D0 #CJK UNIFIED IDEOGRAPH
+0x83F9 0x51D2 #CJK UNIFIED IDEOGRAPH
+0x83FA 0x51D3 #CJK UNIFIED IDEOGRAPH
+0x83FB 0x51D4 #CJK UNIFIED IDEOGRAPH
+0x83FC 0x51D5 #CJK UNIFIED IDEOGRAPH
+0x83FD 0x51D6 #CJK UNIFIED IDEOGRAPH
+0x83FE 0x51D7 #CJK UNIFIED IDEOGRAPH
+0x8440 0x51D8 #CJK UNIFIED IDEOGRAPH
+0x8441 0x51D9 #CJK UNIFIED IDEOGRAPH
+0x8442 0x51DA #CJK UNIFIED IDEOGRAPH
+0x8443 0x51DC #CJK UNIFIED IDEOGRAPH
+0x8444 0x51DE #CJK UNIFIED IDEOGRAPH
+0x8445 0x51DF #CJK UNIFIED IDEOGRAPH
+0x8446 0x51E2 #CJK UNIFIED IDEOGRAPH
+0x8447 0x51E3 #CJK UNIFIED IDEOGRAPH
+0x8448 0x51E5 #CJK UNIFIED IDEOGRAPH
+0x8449 0x51E6 #CJK UNIFIED IDEOGRAPH
+0x844A 0x51E7 #CJK UNIFIED IDEOGRAPH
+0x844B 0x51E8 #CJK UNIFIED IDEOGRAPH
+0x844C 0x51E9 #CJK UNIFIED IDEOGRAPH
+0x844D 0x51EA #CJK UNIFIED IDEOGRAPH
+0x844E 0x51EC #CJK UNIFIED IDEOGRAPH
+0x844F 0x51EE #CJK UNIFIED IDEOGRAPH
+0x8450 0x51F1 #CJK UNIFIED IDEOGRAPH
+0x8451 0x51F2 #CJK UNIFIED IDEOGRAPH
+0x8452 0x51F4 #CJK UNIFIED IDEOGRAPH
+0x8453 0x51F7 #CJK UNIFIED IDEOGRAPH
+0x8454 0x51FE #CJK UNIFIED IDEOGRAPH
+0x8455 0x5204 #CJK UNIFIED IDEOGRAPH
+0x8456 0x5205 #CJK UNIFIED IDEOGRAPH
+0x8457 0x5209 #CJK UNIFIED IDEOGRAPH
+0x8458 0x520B #CJK UNIFIED IDEOGRAPH
+0x8459 0x520C #CJK UNIFIED IDEOGRAPH
+0x845A 0x520F #CJK UNIFIED IDEOGRAPH
+0x845B 0x5210 #CJK UNIFIED IDEOGRAPH
+0x845C 0x5213 #CJK UNIFIED IDEOGRAPH
+0x845D 0x5214 #CJK UNIFIED IDEOGRAPH
+0x845E 0x5215 #CJK UNIFIED IDEOGRAPH
+0x845F 0x521C #CJK UNIFIED IDEOGRAPH
+0x8460 0x521E #CJK UNIFIED IDEOGRAPH
+0x8461 0x521F #CJK UNIFIED IDEOGRAPH
+0x8462 0x5221 #CJK UNIFIED IDEOGRAPH
+0x8463 0x5222 #CJK UNIFIED IDEOGRAPH
+0x8464 0x5223 #CJK UNIFIED IDEOGRAPH
+0x8465 0x5225 #CJK UNIFIED IDEOGRAPH
+0x8466 0x5226 #CJK UNIFIED IDEOGRAPH
+0x8467 0x5227 #CJK UNIFIED IDEOGRAPH
+0x8468 0x522A #CJK UNIFIED IDEOGRAPH
+0x8469 0x522C #CJK UNIFIED IDEOGRAPH
+0x846A 0x522F #CJK UNIFIED IDEOGRAPH
+0x846B 0x5231 #CJK UNIFIED IDEOGRAPH
+0x846C 0x5232 #CJK UNIFIED IDEOGRAPH
+0x846D 0x5234 #CJK UNIFIED IDEOGRAPH
+0x846E 0x5235 #CJK UNIFIED IDEOGRAPH
+0x846F 0x523C #CJK UNIFIED IDEOGRAPH
+0x8470 0x523E #CJK UNIFIED IDEOGRAPH
+0x8471 0x5244 #CJK UNIFIED IDEOGRAPH
+0x8472 0x5245 #CJK UNIFIED IDEOGRAPH
+0x8473 0x5246 #CJK UNIFIED IDEOGRAPH
+0x8474 0x5247 #CJK UNIFIED IDEOGRAPH
+0x8475 0x5248 #CJK UNIFIED IDEOGRAPH
+0x8476 0x5249 #CJK UNIFIED IDEOGRAPH
+0x8477 0x524B #CJK UNIFIED IDEOGRAPH
+0x8478 0x524E #CJK UNIFIED IDEOGRAPH
+0x8479 0x524F #CJK UNIFIED IDEOGRAPH
+0x847A 0x5252 #CJK UNIFIED IDEOGRAPH
+0x847B 0x5253 #CJK UNIFIED IDEOGRAPH
+0x847C 0x5255 #CJK UNIFIED IDEOGRAPH
+0x847D 0x5257 #CJK UNIFIED IDEOGRAPH
+0x847E 0x5258 #CJK UNIFIED IDEOGRAPH
+0x8480 0x5259 #CJK UNIFIED IDEOGRAPH
+0x8481 0x525A #CJK UNIFIED IDEOGRAPH
+0x8482 0x525B #CJK UNIFIED IDEOGRAPH
+0x8483 0x525D #CJK UNIFIED IDEOGRAPH
+0x8484 0x525F #CJK UNIFIED IDEOGRAPH
+0x8485 0x5260 #CJK UNIFIED IDEOGRAPH
+0x8486 0x5262 #CJK UNIFIED IDEOGRAPH
+0x8487 0x5263 #CJK UNIFIED IDEOGRAPH
+0x8488 0x5264 #CJK UNIFIED IDEOGRAPH
+0x8489 0x5266 #CJK UNIFIED IDEOGRAPH
+0x848A 0x5268 #CJK UNIFIED IDEOGRAPH
+0x848B 0x526B #CJK UNIFIED IDEOGRAPH
+0x848C 0x526C #CJK UNIFIED IDEOGRAPH
+0x848D 0x526D #CJK UNIFIED IDEOGRAPH
+0x848E 0x526E #CJK UNIFIED IDEOGRAPH
+0x848F 0x5270 #CJK UNIFIED IDEOGRAPH
+0x8490 0x5271 #CJK UNIFIED IDEOGRAPH
+0x8491 0x5273 #CJK UNIFIED IDEOGRAPH
+0x8492 0x5274 #CJK UNIFIED IDEOGRAPH
+0x8493 0x5275 #CJK UNIFIED IDEOGRAPH
+0x8494 0x5276 #CJK UNIFIED IDEOGRAPH
+0x8495 0x5277 #CJK UNIFIED IDEOGRAPH
+0x8496 0x5278 #CJK UNIFIED IDEOGRAPH
+0x8497 0x5279 #CJK UNIFIED IDEOGRAPH
+0x8498 0x527A #CJK UNIFIED IDEOGRAPH
+0x8499 0x527B #CJK UNIFIED IDEOGRAPH
+0x849A 0x527C #CJK UNIFIED IDEOGRAPH
+0x849B 0x527E #CJK UNIFIED IDEOGRAPH
+0x849C 0x5280 #CJK UNIFIED IDEOGRAPH
+0x849D 0x5283 #CJK UNIFIED IDEOGRAPH
+0x849E 0x5284 #CJK UNIFIED IDEOGRAPH
+0x849F 0x5285 #CJK UNIFIED IDEOGRAPH
+0x84A0 0x5286 #CJK UNIFIED IDEOGRAPH
+0x84A1 0x5287 #CJK UNIFIED IDEOGRAPH
+0x84A2 0x5289 #CJK UNIFIED IDEOGRAPH
+0x84A3 0x528A #CJK UNIFIED IDEOGRAPH
+0x84A4 0x528B #CJK UNIFIED IDEOGRAPH
+0x84A5 0x528C #CJK UNIFIED IDEOGRAPH
+0x84A6 0x528D #CJK UNIFIED IDEOGRAPH
+0x84A7 0x528E #CJK UNIFIED IDEOGRAPH
+0x84A8 0x528F #CJK UNIFIED IDEOGRAPH
+0x84A9 0x5291 #CJK UNIFIED IDEOGRAPH
+0x84AA 0x5292 #CJK UNIFIED IDEOGRAPH
+0x84AB 0x5294 #CJK UNIFIED IDEOGRAPH
+0x84AC 0x5295 #CJK UNIFIED IDEOGRAPH
+0x84AD 0x5296 #CJK UNIFIED IDEOGRAPH
+0x84AE 0x5297 #CJK UNIFIED IDEOGRAPH
+0x84AF 0x5298 #CJK UNIFIED IDEOGRAPH
+0x84B0 0x5299 #CJK UNIFIED IDEOGRAPH
+0x84B1 0x529A #CJK UNIFIED IDEOGRAPH
+0x84B2 0x529C #CJK UNIFIED IDEOGRAPH
+0x84B3 0x52A4 #CJK UNIFIED IDEOGRAPH
+0x84B4 0x52A5 #CJK UNIFIED IDEOGRAPH
+0x84B5 0x52A6 #CJK UNIFIED IDEOGRAPH
+0x84B6 0x52A7 #CJK UNIFIED IDEOGRAPH
+0x84B7 0x52AE #CJK UNIFIED IDEOGRAPH
+0x84B8 0x52AF #CJK UNIFIED IDEOGRAPH
+0x84B9 0x52B0 #CJK UNIFIED IDEOGRAPH
+0x84BA 0x52B4 #CJK UNIFIED IDEOGRAPH
+0x84BB 0x52B5 #CJK UNIFIED IDEOGRAPH
+0x84BC 0x52B6 #CJK UNIFIED IDEOGRAPH
+0x84BD 0x52B7 #CJK UNIFIED IDEOGRAPH
+0x84BE 0x52B8 #CJK UNIFIED IDEOGRAPH
+0x84BF 0x52B9 #CJK UNIFIED IDEOGRAPH
+0x84C0 0x52BA #CJK UNIFIED IDEOGRAPH
+0x84C1 0x52BB #CJK UNIFIED IDEOGRAPH
+0x84C2 0x52BC #CJK UNIFIED IDEOGRAPH
+0x84C3 0x52BD #CJK UNIFIED IDEOGRAPH
+0x84C4 0x52C0 #CJK UNIFIED IDEOGRAPH
+0x84C5 0x52C1 #CJK UNIFIED IDEOGRAPH
+0x84C6 0x52C2 #CJK UNIFIED IDEOGRAPH
+0x84C7 0x52C4 #CJK UNIFIED IDEOGRAPH
+0x84C8 0x52C5 #CJK UNIFIED IDEOGRAPH
+0x84C9 0x52C6 #CJK UNIFIED IDEOGRAPH
+0x84CA 0x52C8 #CJK UNIFIED IDEOGRAPH
+0x84CB 0x52CA #CJK UNIFIED IDEOGRAPH
+0x84CC 0x52CC #CJK UNIFIED IDEOGRAPH
+0x84CD 0x52CD #CJK UNIFIED IDEOGRAPH
+0x84CE 0x52CE #CJK UNIFIED IDEOGRAPH
+0x84CF 0x52CF #CJK UNIFIED IDEOGRAPH
+0x84D0 0x52D1 #CJK UNIFIED IDEOGRAPH
+0x84D1 0x52D3 #CJK UNIFIED IDEOGRAPH
+0x84D2 0x52D4 #CJK UNIFIED IDEOGRAPH
+0x84D3 0x52D5 #CJK UNIFIED IDEOGRAPH
+0x84D4 0x52D7 #CJK UNIFIED IDEOGRAPH
+0x84D5 0x52D9 #CJK UNIFIED IDEOGRAPH
+0x84D6 0x52DA #CJK UNIFIED IDEOGRAPH
+0x84D7 0x52DB #CJK UNIFIED IDEOGRAPH
+0x84D8 0x52DC #CJK UNIFIED IDEOGRAPH
+0x84D9 0x52DD #CJK UNIFIED IDEOGRAPH
+0x84DA 0x52DE #CJK UNIFIED IDEOGRAPH
+0x84DB 0x52E0 #CJK UNIFIED IDEOGRAPH
+0x84DC 0x52E1 #CJK UNIFIED IDEOGRAPH
+0x84DD 0x52E2 #CJK UNIFIED IDEOGRAPH
+0x84DE 0x52E3 #CJK UNIFIED IDEOGRAPH
+0x84DF 0x52E5 #CJK UNIFIED IDEOGRAPH
+0x84E0 0x52E6 #CJK UNIFIED IDEOGRAPH
+0x84E1 0x52E7 #CJK UNIFIED IDEOGRAPH
+0x84E2 0x52E8 #CJK UNIFIED IDEOGRAPH
+0x84E3 0x52E9 #CJK UNIFIED IDEOGRAPH
+0x84E4 0x52EA #CJK UNIFIED IDEOGRAPH
+0x84E5 0x52EB #CJK UNIFIED IDEOGRAPH
+0x84E6 0x52EC #CJK UNIFIED IDEOGRAPH
+0x84E7 0x52ED #CJK UNIFIED IDEOGRAPH
+0x84E8 0x52EE #CJK UNIFIED IDEOGRAPH
+0x84E9 0x52EF #CJK UNIFIED IDEOGRAPH
+0x84EA 0x52F1 #CJK UNIFIED IDEOGRAPH
+0x84EB 0x52F2 #CJK UNIFIED IDEOGRAPH
+0x84EC 0x52F3 #CJK UNIFIED IDEOGRAPH
+0x84ED 0x52F4 #CJK UNIFIED IDEOGRAPH
+0x84EE 0x52F5 #CJK UNIFIED IDEOGRAPH
+0x84EF 0x52F6 #CJK UNIFIED IDEOGRAPH
+0x84F0 0x52F7 #CJK UNIFIED IDEOGRAPH
+0x84F1 0x52F8 #CJK UNIFIED IDEOGRAPH
+0x84F2 0x52FB #CJK UNIFIED IDEOGRAPH
+0x84F3 0x52FC #CJK UNIFIED IDEOGRAPH
+0x84F4 0x52FD #CJK UNIFIED IDEOGRAPH
+0x84F5 0x5301 #CJK UNIFIED IDEOGRAPH
+0x84F6 0x5302 #CJK UNIFIED IDEOGRAPH
+0x84F7 0x5303 #CJK UNIFIED IDEOGRAPH
+0x84F8 0x5304 #CJK UNIFIED IDEOGRAPH
+0x84F9 0x5307 #CJK UNIFIED IDEOGRAPH
+0x84FA 0x5309 #CJK UNIFIED IDEOGRAPH
+0x84FB 0x530A #CJK UNIFIED IDEOGRAPH
+0x84FC 0x530B #CJK UNIFIED IDEOGRAPH
+0x84FD 0x530C #CJK UNIFIED IDEOGRAPH
+0x84FE 0x530E #CJK UNIFIED IDEOGRAPH
+0x8540 0x5311 #CJK UNIFIED IDEOGRAPH
+0x8541 0x5312 #CJK UNIFIED IDEOGRAPH
+0x8542 0x5313 #CJK UNIFIED IDEOGRAPH
+0x8543 0x5314 #CJK UNIFIED IDEOGRAPH
+0x8544 0x5318 #CJK UNIFIED IDEOGRAPH
+0x8545 0x531B #CJK UNIFIED IDEOGRAPH
+0x8546 0x531C #CJK UNIFIED IDEOGRAPH
+0x8547 0x531E #CJK UNIFIED IDEOGRAPH
+0x8548 0x531F #CJK UNIFIED IDEOGRAPH
+0x8549 0x5322 #CJK UNIFIED IDEOGRAPH
+0x854A 0x5324 #CJK UNIFIED IDEOGRAPH
+0x854B 0x5325 #CJK UNIFIED IDEOGRAPH
+0x854C 0x5327 #CJK UNIFIED IDEOGRAPH
+0x854D 0x5328 #CJK UNIFIED IDEOGRAPH
+0x854E 0x5329 #CJK UNIFIED IDEOGRAPH
+0x854F 0x532B #CJK UNIFIED IDEOGRAPH
+0x8550 0x532C #CJK UNIFIED IDEOGRAPH
+0x8551 0x532D #CJK UNIFIED IDEOGRAPH
+0x8552 0x532F #CJK UNIFIED IDEOGRAPH
+0x8553 0x5330 #CJK UNIFIED IDEOGRAPH
+0x8554 0x5331 #CJK UNIFIED IDEOGRAPH
+0x8555 0x5332 #CJK UNIFIED IDEOGRAPH
+0x8556 0x5333 #CJK UNIFIED IDEOGRAPH
+0x8557 0x5334 #CJK UNIFIED IDEOGRAPH
+0x8558 0x5335 #CJK UNIFIED IDEOGRAPH
+0x8559 0x5336 #CJK UNIFIED IDEOGRAPH
+0x855A 0x5337 #CJK UNIFIED IDEOGRAPH
+0x855B 0x5338 #CJK UNIFIED IDEOGRAPH
+0x855C 0x533C #CJK UNIFIED IDEOGRAPH
+0x855D 0x533D #CJK UNIFIED IDEOGRAPH
+0x855E 0x5340 #CJK UNIFIED IDEOGRAPH
+0x855F 0x5342 #CJK UNIFIED IDEOGRAPH
+0x8560 0x5344 #CJK UNIFIED IDEOGRAPH
+0x8561 0x5346 #CJK UNIFIED IDEOGRAPH
+0x8562 0x534B #CJK UNIFIED IDEOGRAPH
+0x8563 0x534C #CJK UNIFIED IDEOGRAPH
+0x8564 0x534D #CJK UNIFIED IDEOGRAPH
+0x8565 0x5350 #CJK UNIFIED IDEOGRAPH
+0x8566 0x5354 #CJK UNIFIED IDEOGRAPH
+0x8567 0x5358 #CJK UNIFIED IDEOGRAPH
+0x8568 0x5359 #CJK UNIFIED IDEOGRAPH
+0x8569 0x535B #CJK UNIFIED IDEOGRAPH
+0x856A 0x535D #CJK UNIFIED IDEOGRAPH
+0x856B 0x5365 #CJK UNIFIED IDEOGRAPH
+0x856C 0x5368 #CJK UNIFIED IDEOGRAPH
+0x856D 0x536A #CJK UNIFIED IDEOGRAPH
+0x856E 0x536C #CJK UNIFIED IDEOGRAPH
+0x856F 0x536D #CJK UNIFIED IDEOGRAPH
+0x8570 0x5372 #CJK UNIFIED IDEOGRAPH
+0x8571 0x5376 #CJK UNIFIED IDEOGRAPH
+0x8572 0x5379 #CJK UNIFIED IDEOGRAPH
+0x8573 0x537B #CJK UNIFIED IDEOGRAPH
+0x8574 0x537C #CJK UNIFIED IDEOGRAPH
+0x8575 0x537D #CJK UNIFIED IDEOGRAPH
+0x8576 0x537E #CJK UNIFIED IDEOGRAPH
+0x8577 0x5380 #CJK UNIFIED IDEOGRAPH
+0x8578 0x5381 #CJK UNIFIED IDEOGRAPH
+0x8579 0x5383 #CJK UNIFIED IDEOGRAPH
+0x857A 0x5387 #CJK UNIFIED IDEOGRAPH
+0x857B 0x5388 #CJK UNIFIED IDEOGRAPH
+0x857C 0x538A #CJK UNIFIED IDEOGRAPH
+0x857D 0x538E #CJK UNIFIED IDEOGRAPH
+0x857E 0x538F #CJK UNIFIED IDEOGRAPH
+0x8580 0x5390 #CJK UNIFIED IDEOGRAPH
+0x8581 0x5391 #CJK UNIFIED IDEOGRAPH
+0x8582 0x5392 #CJK UNIFIED IDEOGRAPH
+0x8583 0x5393 #CJK UNIFIED IDEOGRAPH
+0x8584 0x5394 #CJK UNIFIED IDEOGRAPH
+0x8585 0x5396 #CJK UNIFIED IDEOGRAPH
+0x8586 0x5397 #CJK UNIFIED IDEOGRAPH
+0x8587 0x5399 #CJK UNIFIED IDEOGRAPH
+0x8588 0x539B #CJK UNIFIED IDEOGRAPH
+0x8589 0x539C #CJK UNIFIED IDEOGRAPH
+0x858A 0x539E #CJK UNIFIED IDEOGRAPH
+0x858B 0x53A0 #CJK UNIFIED IDEOGRAPH
+0x858C 0x53A1 #CJK UNIFIED IDEOGRAPH
+0x858D 0x53A4 #CJK UNIFIED IDEOGRAPH
+0x858E 0x53A7 #CJK UNIFIED IDEOGRAPH
+0x858F 0x53AA #CJK UNIFIED IDEOGRAPH
+0x8590 0x53AB #CJK UNIFIED IDEOGRAPH
+0x8591 0x53AC #CJK UNIFIED IDEOGRAPH
+0x8592 0x53AD #CJK UNIFIED IDEOGRAPH
+0x8593 0x53AF #CJK UNIFIED IDEOGRAPH
+0x8594 0x53B0 #CJK UNIFIED IDEOGRAPH
+0x8595 0x53B1 #CJK UNIFIED IDEOGRAPH
+0x8596 0x53B2 #CJK UNIFIED IDEOGRAPH
+0x8597 0x53B3 #CJK UNIFIED IDEOGRAPH
+0x8598 0x53B4 #CJK UNIFIED IDEOGRAPH
+0x8599 0x53B5 #CJK UNIFIED IDEOGRAPH
+0x859A 0x53B7 #CJK UNIFIED IDEOGRAPH
+0x859B 0x53B8 #CJK UNIFIED IDEOGRAPH
+0x859C 0x53B9 #CJK UNIFIED IDEOGRAPH
+0x859D 0x53BA #CJK UNIFIED IDEOGRAPH
+0x859E 0x53BC #CJK UNIFIED IDEOGRAPH
+0x859F 0x53BD #CJK UNIFIED IDEOGRAPH
+0x85A0 0x53BE #CJK UNIFIED IDEOGRAPH
+0x85A1 0x53C0 #CJK UNIFIED IDEOGRAPH
+0x85A2 0x53C3 #CJK UNIFIED IDEOGRAPH
+0x85A3 0x53C4 #CJK UNIFIED IDEOGRAPH
+0x85A4 0x53C5 #CJK UNIFIED IDEOGRAPH
+0x85A5 0x53C6 #CJK UNIFIED IDEOGRAPH
+0x85A6 0x53C7 #CJK UNIFIED IDEOGRAPH
+0x85A7 0x53CE #CJK UNIFIED IDEOGRAPH
+0x85A8 0x53CF #CJK UNIFIED IDEOGRAPH
+0x85A9 0x53D0 #CJK UNIFIED IDEOGRAPH
+0x85AA 0x53D2 #CJK UNIFIED IDEOGRAPH
+0x85AB 0x53D3 #CJK UNIFIED IDEOGRAPH
+0x85AC 0x53D5 #CJK UNIFIED IDEOGRAPH
+0x85AD 0x53DA #CJK UNIFIED IDEOGRAPH
+0x85AE 0x53DC #CJK UNIFIED IDEOGRAPH
+0x85AF 0x53DD #CJK UNIFIED IDEOGRAPH
+0x85B0 0x53DE #CJK UNIFIED IDEOGRAPH
+0x85B1 0x53E1 #CJK UNIFIED IDEOGRAPH
+0x85B2 0x53E2 #CJK UNIFIED IDEOGRAPH
+0x85B3 0x53E7 #CJK UNIFIED IDEOGRAPH
+0x85B4 0x53F4 #CJK UNIFIED IDEOGRAPH
+0x85B5 0x53FA #CJK UNIFIED IDEOGRAPH
+0x85B6 0x53FE #CJK UNIFIED IDEOGRAPH
+0x85B7 0x53FF #CJK UNIFIED IDEOGRAPH
+0x85B8 0x5400 #CJK UNIFIED IDEOGRAPH
+0x85B9 0x5402 #CJK UNIFIED IDEOGRAPH
+0x85BA 0x5405 #CJK UNIFIED IDEOGRAPH
+0x85BB 0x5407 #CJK UNIFIED IDEOGRAPH
+0x85BC 0x540B #CJK UNIFIED IDEOGRAPH
+0x85BD 0x5414 #CJK UNIFIED IDEOGRAPH
+0x85BE 0x5418 #CJK UNIFIED IDEOGRAPH
+0x85BF 0x5419 #CJK UNIFIED IDEOGRAPH
+0x85C0 0x541A #CJK UNIFIED IDEOGRAPH
+0x85C1 0x541C #CJK UNIFIED IDEOGRAPH
+0x85C2 0x5422 #CJK UNIFIED IDEOGRAPH
+0x85C3 0x5424 #CJK UNIFIED IDEOGRAPH
+0x85C4 0x5425 #CJK UNIFIED IDEOGRAPH
+0x85C5 0x542A #CJK UNIFIED IDEOGRAPH
+0x85C6 0x5430 #CJK UNIFIED IDEOGRAPH
+0x85C7 0x5433 #CJK UNIFIED IDEOGRAPH
+0x85C8 0x5436 #CJK UNIFIED IDEOGRAPH
+0x85C9 0x5437 #CJK UNIFIED IDEOGRAPH
+0x85CA 0x543A #CJK UNIFIED IDEOGRAPH
+0x85CB 0x543D #CJK UNIFIED IDEOGRAPH
+0x85CC 0x543F #CJK UNIFIED IDEOGRAPH
+0x85CD 0x5441 #CJK UNIFIED IDEOGRAPH
+0x85CE 0x5442 #CJK UNIFIED IDEOGRAPH
+0x85CF 0x5444 #CJK UNIFIED IDEOGRAPH
+0x85D0 0x5445 #CJK UNIFIED IDEOGRAPH
+0x85D1 0x5447 #CJK UNIFIED IDEOGRAPH
+0x85D2 0x5449 #CJK UNIFIED IDEOGRAPH
+0x85D3 0x544C #CJK UNIFIED IDEOGRAPH
+0x85D4 0x544D #CJK UNIFIED IDEOGRAPH
+0x85D5 0x544E #CJK UNIFIED IDEOGRAPH
+0x85D6 0x544F #CJK UNIFIED IDEOGRAPH
+0x85D7 0x5451 #CJK UNIFIED IDEOGRAPH
+0x85D8 0x545A #CJK UNIFIED IDEOGRAPH
+0x85D9 0x545D #CJK UNIFIED IDEOGRAPH
+0x85DA 0x545E #CJK UNIFIED IDEOGRAPH
+0x85DB 0x545F #CJK UNIFIED IDEOGRAPH
+0x85DC 0x5460 #CJK UNIFIED IDEOGRAPH
+0x85DD 0x5461 #CJK UNIFIED IDEOGRAPH
+0x85DE 0x5463 #CJK UNIFIED IDEOGRAPH
+0x85DF 0x5465 #CJK UNIFIED IDEOGRAPH
+0x85E0 0x5467 #CJK UNIFIED IDEOGRAPH
+0x85E1 0x5469 #CJK UNIFIED IDEOGRAPH
+0x85E2 0x546A #CJK UNIFIED IDEOGRAPH
+0x85E3 0x546B #CJK UNIFIED IDEOGRAPH
+0x85E4 0x546C #CJK UNIFIED IDEOGRAPH
+0x85E5 0x546D #CJK UNIFIED IDEOGRAPH
+0x85E6 0x546E #CJK UNIFIED IDEOGRAPH
+0x85E7 0x546F #CJK UNIFIED IDEOGRAPH
+0x85E8 0x5470 #CJK UNIFIED IDEOGRAPH
+0x85E9 0x5474 #CJK UNIFIED IDEOGRAPH
+0x85EA 0x5479 #CJK UNIFIED IDEOGRAPH
+0x85EB 0x547A #CJK UNIFIED IDEOGRAPH
+0x85EC 0x547E #CJK UNIFIED IDEOGRAPH
+0x85ED 0x547F #CJK UNIFIED IDEOGRAPH
+0x85EE 0x5481 #CJK UNIFIED IDEOGRAPH
+0x85EF 0x5483 #CJK UNIFIED IDEOGRAPH
+0x85F0 0x5485 #CJK UNIFIED IDEOGRAPH
+0x85F1 0x5487 #CJK UNIFIED IDEOGRAPH
+0x85F2 0x5488 #CJK UNIFIED IDEOGRAPH
+0x85F3 0x5489 #CJK UNIFIED IDEOGRAPH
+0x85F4 0x548A #CJK UNIFIED IDEOGRAPH
+0x85F5 0x548D #CJK UNIFIED IDEOGRAPH
+0x85F6 0x5491 #CJK UNIFIED IDEOGRAPH
+0x85F7 0x5493 #CJK UNIFIED IDEOGRAPH
+0x85F8 0x5497 #CJK UNIFIED IDEOGRAPH
+0x85F9 0x5498 #CJK UNIFIED IDEOGRAPH
+0x85FA 0x549C #CJK UNIFIED IDEOGRAPH
+0x85FB 0x549E #CJK UNIFIED IDEOGRAPH
+0x85FC 0x549F #CJK UNIFIED IDEOGRAPH
+0x85FD 0x54A0 #CJK UNIFIED IDEOGRAPH
+0x85FE 0x54A1 #CJK UNIFIED IDEOGRAPH
+0x8640 0x54A2 #CJK UNIFIED IDEOGRAPH
+0x8641 0x54A5 #CJK UNIFIED IDEOGRAPH
+0x8642 0x54AE #CJK UNIFIED IDEOGRAPH
+0x8643 0x54B0 #CJK UNIFIED IDEOGRAPH
+0x8644 0x54B2 #CJK UNIFIED IDEOGRAPH
+0x8645 0x54B5 #CJK UNIFIED IDEOGRAPH
+0x8646 0x54B6 #CJK UNIFIED IDEOGRAPH
+0x8647 0x54B7 #CJK UNIFIED IDEOGRAPH
+0x8648 0x54B9 #CJK UNIFIED IDEOGRAPH
+0x8649 0x54BA #CJK UNIFIED IDEOGRAPH
+0x864A 0x54BC #CJK UNIFIED IDEOGRAPH
+0x864B 0x54BE #CJK UNIFIED IDEOGRAPH
+0x864C 0x54C3 #CJK UNIFIED IDEOGRAPH
+0x864D 0x54C5 #CJK UNIFIED IDEOGRAPH
+0x864E 0x54CA #CJK UNIFIED IDEOGRAPH
+0x864F 0x54CB #CJK UNIFIED IDEOGRAPH
+0x8650 0x54D6 #CJK UNIFIED IDEOGRAPH
+0x8651 0x54D8 #CJK UNIFIED IDEOGRAPH
+0x8652 0x54DB #CJK UNIFIED IDEOGRAPH
+0x8653 0x54E0 #CJK UNIFIED IDEOGRAPH
+0x8654 0x54E1 #CJK UNIFIED IDEOGRAPH
+0x8655 0x54E2 #CJK UNIFIED IDEOGRAPH
+0x8656 0x54E3 #CJK UNIFIED IDEOGRAPH
+0x8657 0x54E4 #CJK UNIFIED IDEOGRAPH
+0x8658 0x54EB #CJK UNIFIED IDEOGRAPH
+0x8659 0x54EC #CJK UNIFIED IDEOGRAPH
+0x865A 0x54EF #CJK UNIFIED IDEOGRAPH
+0x865B 0x54F0 #CJK UNIFIED IDEOGRAPH
+0x865C 0x54F1 #CJK UNIFIED IDEOGRAPH
+0x865D 0x54F4 #CJK UNIFIED IDEOGRAPH
+0x865E 0x54F5 #CJK UNIFIED IDEOGRAPH
+0x865F 0x54F6 #CJK UNIFIED IDEOGRAPH
+0x8660 0x54F7 #CJK UNIFIED IDEOGRAPH
+0x8661 0x54F8 #CJK UNIFIED IDEOGRAPH
+0x8662 0x54F9 #CJK UNIFIED IDEOGRAPH
+0x8663 0x54FB #CJK UNIFIED IDEOGRAPH
+0x8664 0x54FE #CJK UNIFIED IDEOGRAPH
+0x8665 0x5500 #CJK UNIFIED IDEOGRAPH
+0x8666 0x5502 #CJK UNIFIED IDEOGRAPH
+0x8667 0x5503 #CJK UNIFIED IDEOGRAPH
+0x8668 0x5504 #CJK UNIFIED IDEOGRAPH
+0x8669 0x5505 #CJK UNIFIED IDEOGRAPH
+0x866A 0x5508 #CJK UNIFIED IDEOGRAPH
+0x866B 0x550A #CJK UNIFIED IDEOGRAPH
+0x866C 0x550B #CJK UNIFIED IDEOGRAPH
+0x866D 0x550C #CJK UNIFIED IDEOGRAPH
+0x866E 0x550D #CJK UNIFIED IDEOGRAPH
+0x866F 0x550E #CJK UNIFIED IDEOGRAPH
+0x8670 0x5512 #CJK UNIFIED IDEOGRAPH
+0x8671 0x5513 #CJK UNIFIED IDEOGRAPH
+0x8672 0x5515 #CJK UNIFIED IDEOGRAPH
+0x8673 0x5516 #CJK UNIFIED IDEOGRAPH
+0x8674 0x5517 #CJK UNIFIED IDEOGRAPH
+0x8675 0x5518 #CJK UNIFIED IDEOGRAPH
+0x8676 0x5519 #CJK UNIFIED IDEOGRAPH
+0x8677 0x551A #CJK UNIFIED IDEOGRAPH
+0x8678 0x551C #CJK UNIFIED IDEOGRAPH
+0x8679 0x551D #CJK UNIFIED IDEOGRAPH
+0x867A 0x551E #CJK UNIFIED IDEOGRAPH
+0x867B 0x551F #CJK UNIFIED IDEOGRAPH
+0x867C 0x5521 #CJK UNIFIED IDEOGRAPH
+0x867D 0x5525 #CJK UNIFIED IDEOGRAPH
+0x867E 0x5526 #CJK UNIFIED IDEOGRAPH
+0x8680 0x5528 #CJK UNIFIED IDEOGRAPH
+0x8681 0x5529 #CJK UNIFIED IDEOGRAPH
+0x8682 0x552B #CJK UNIFIED IDEOGRAPH
+0x8683 0x552D #CJK UNIFIED IDEOGRAPH
+0x8684 0x5532 #CJK UNIFIED IDEOGRAPH
+0x8685 0x5534 #CJK UNIFIED IDEOGRAPH
+0x8686 0x5535 #CJK UNIFIED IDEOGRAPH
+0x8687 0x5536 #CJK UNIFIED IDEOGRAPH
+0x8688 0x5538 #CJK UNIFIED IDEOGRAPH
+0x8689 0x5539 #CJK UNIFIED IDEOGRAPH
+0x868A 0x553A #CJK UNIFIED IDEOGRAPH
+0x868B 0x553B #CJK UNIFIED IDEOGRAPH
+0x868C 0x553D #CJK UNIFIED IDEOGRAPH
+0x868D 0x5540 #CJK UNIFIED IDEOGRAPH
+0x868E 0x5542 #CJK UNIFIED IDEOGRAPH
+0x868F 0x5545 #CJK UNIFIED IDEOGRAPH
+0x8690 0x5547 #CJK UNIFIED IDEOGRAPH
+0x8691 0x5548 #CJK UNIFIED IDEOGRAPH
+0x8692 0x554B #CJK UNIFIED IDEOGRAPH
+0x8693 0x554C #CJK UNIFIED IDEOGRAPH
+0x8694 0x554D #CJK UNIFIED IDEOGRAPH
+0x8695 0x554E #CJK UNIFIED IDEOGRAPH
+0x8696 0x554F #CJK UNIFIED IDEOGRAPH
+0x8697 0x5551 #CJK UNIFIED IDEOGRAPH
+0x8698 0x5552 #CJK UNIFIED IDEOGRAPH
+0x8699 0x5553 #CJK UNIFIED IDEOGRAPH
+0x869A 0x5554 #CJK UNIFIED IDEOGRAPH
+0x869B 0x5557 #CJK UNIFIED IDEOGRAPH
+0x869C 0x5558 #CJK UNIFIED IDEOGRAPH
+0x869D 0x5559 #CJK UNIFIED IDEOGRAPH
+0x869E 0x555A #CJK UNIFIED IDEOGRAPH
+0x869F 0x555B #CJK UNIFIED IDEOGRAPH
+0x86A0 0x555D #CJK UNIFIED IDEOGRAPH
+0x86A1 0x555E #CJK UNIFIED IDEOGRAPH
+0x86A2 0x555F #CJK UNIFIED IDEOGRAPH
+0x86A3 0x5560 #CJK UNIFIED IDEOGRAPH
+0x86A4 0x5562 #CJK UNIFIED IDEOGRAPH
+0x86A5 0x5563 #CJK UNIFIED IDEOGRAPH
+0x86A6 0x5568 #CJK UNIFIED IDEOGRAPH
+0x86A7 0x5569 #CJK UNIFIED IDEOGRAPH
+0x86A8 0x556B #CJK UNIFIED IDEOGRAPH
+0x86A9 0x556F #CJK UNIFIED IDEOGRAPH
+0x86AA 0x5570 #CJK UNIFIED IDEOGRAPH
+0x86AB 0x5571 #CJK UNIFIED IDEOGRAPH
+0x86AC 0x5572 #CJK UNIFIED IDEOGRAPH
+0x86AD 0x5573 #CJK UNIFIED IDEOGRAPH
+0x86AE 0x5574 #CJK UNIFIED IDEOGRAPH
+0x86AF 0x5579 #CJK UNIFIED IDEOGRAPH
+0x86B0 0x557A #CJK UNIFIED IDEOGRAPH
+0x86B1 0x557D #CJK UNIFIED IDEOGRAPH
+0x86B2 0x557F #CJK UNIFIED IDEOGRAPH
+0x86B3 0x5585 #CJK UNIFIED IDEOGRAPH
+0x86B4 0x5586 #CJK UNIFIED IDEOGRAPH
+0x86B5 0x558C #CJK UNIFIED IDEOGRAPH
+0x86B6 0x558D #CJK UNIFIED IDEOGRAPH
+0x86B7 0x558E #CJK UNIFIED IDEOGRAPH
+0x86B8 0x5590 #CJK UNIFIED IDEOGRAPH
+0x86B9 0x5592 #CJK UNIFIED IDEOGRAPH
+0x86BA 0x5593 #CJK UNIFIED IDEOGRAPH
+0x86BB 0x5595 #CJK UNIFIED IDEOGRAPH
+0x86BC 0x5596 #CJK UNIFIED IDEOGRAPH
+0x86BD 0x5597 #CJK UNIFIED IDEOGRAPH
+0x86BE 0x559A #CJK UNIFIED IDEOGRAPH
+0x86BF 0x559B #CJK UNIFIED IDEOGRAPH
+0x86C0 0x559E #CJK UNIFIED IDEOGRAPH
+0x86C1 0x55A0 #CJK UNIFIED IDEOGRAPH
+0x86C2 0x55A1 #CJK UNIFIED IDEOGRAPH
+0x86C3 0x55A2 #CJK UNIFIED IDEOGRAPH
+0x86C4 0x55A3 #CJK UNIFIED IDEOGRAPH
+0x86C5 0x55A4 #CJK UNIFIED IDEOGRAPH
+0x86C6 0x55A5 #CJK UNIFIED IDEOGRAPH
+0x86C7 0x55A6 #CJK UNIFIED IDEOGRAPH
+0x86C8 0x55A8 #CJK UNIFIED IDEOGRAPH
+0x86C9 0x55A9 #CJK UNIFIED IDEOGRAPH
+0x86CA 0x55AA #CJK UNIFIED IDEOGRAPH
+0x86CB 0x55AB #CJK UNIFIED IDEOGRAPH
+0x86CC 0x55AC #CJK UNIFIED IDEOGRAPH
+0x86CD 0x55AD #CJK UNIFIED IDEOGRAPH
+0x86CE 0x55AE #CJK UNIFIED IDEOGRAPH
+0x86CF 0x55AF #CJK UNIFIED IDEOGRAPH
+0x86D0 0x55B0 #CJK UNIFIED IDEOGRAPH
+0x86D1 0x55B2 #CJK UNIFIED IDEOGRAPH
+0x86D2 0x55B4 #CJK UNIFIED IDEOGRAPH
+0x86D3 0x55B6 #CJK UNIFIED IDEOGRAPH
+0x86D4 0x55B8 #CJK UNIFIED IDEOGRAPH
+0x86D5 0x55BA #CJK UNIFIED IDEOGRAPH
+0x86D6 0x55BC #CJK UNIFIED IDEOGRAPH
+0x86D7 0x55BF #CJK UNIFIED IDEOGRAPH
+0x86D8 0x55C0 #CJK UNIFIED IDEOGRAPH
+0x86D9 0x55C1 #CJK UNIFIED IDEOGRAPH
+0x86DA 0x55C2 #CJK UNIFIED IDEOGRAPH
+0x86DB 0x55C3 #CJK UNIFIED IDEOGRAPH
+0x86DC 0x55C6 #CJK UNIFIED IDEOGRAPH
+0x86DD 0x55C7 #CJK UNIFIED IDEOGRAPH
+0x86DE 0x55C8 #CJK UNIFIED IDEOGRAPH
+0x86DF 0x55CA #CJK UNIFIED IDEOGRAPH
+0x86E0 0x55CB #CJK UNIFIED IDEOGRAPH
+0x86E1 0x55CE #CJK UNIFIED IDEOGRAPH
+0x86E2 0x55CF #CJK UNIFIED IDEOGRAPH
+0x86E3 0x55D0 #CJK UNIFIED IDEOGRAPH
+0x86E4 0x55D5 #CJK UNIFIED IDEOGRAPH
+0x86E5 0x55D7 #CJK UNIFIED IDEOGRAPH
+0x86E6 0x55D8 #CJK UNIFIED IDEOGRAPH
+0x86E7 0x55D9 #CJK UNIFIED IDEOGRAPH
+0x86E8 0x55DA #CJK UNIFIED IDEOGRAPH
+0x86E9 0x55DB #CJK UNIFIED IDEOGRAPH
+0x86EA 0x55DE #CJK UNIFIED IDEOGRAPH
+0x86EB 0x55E0 #CJK UNIFIED IDEOGRAPH
+0x86EC 0x55E2 #CJK UNIFIED IDEOGRAPH
+0x86ED 0x55E7 #CJK UNIFIED IDEOGRAPH
+0x86EE 0x55E9 #CJK UNIFIED IDEOGRAPH
+0x86EF 0x55ED #CJK UNIFIED IDEOGRAPH
+0x86F0 0x55EE #CJK UNIFIED IDEOGRAPH
+0x86F1 0x55F0 #CJK UNIFIED IDEOGRAPH
+0x86F2 0x55F1 #CJK UNIFIED IDEOGRAPH
+0x86F3 0x55F4 #CJK UNIFIED IDEOGRAPH
+0x86F4 0x55F6 #CJK UNIFIED IDEOGRAPH
+0x86F5 0x55F8 #CJK UNIFIED IDEOGRAPH
+0x86F6 0x55F9 #CJK UNIFIED IDEOGRAPH
+0x86F7 0x55FA #CJK UNIFIED IDEOGRAPH
+0x86F8 0x55FB #CJK UNIFIED IDEOGRAPH
+0x86F9 0x55FC #CJK UNIFIED IDEOGRAPH
+0x86FA 0x55FF #CJK UNIFIED IDEOGRAPH
+0x86FB 0x5602 #CJK UNIFIED IDEOGRAPH
+0x86FC 0x5603 #CJK UNIFIED IDEOGRAPH
+0x86FD 0x5604 #CJK UNIFIED IDEOGRAPH
+0x86FE 0x5605 #CJK UNIFIED IDEOGRAPH
+0x8740 0x5606 #CJK UNIFIED IDEOGRAPH
+0x8741 0x5607 #CJK UNIFIED IDEOGRAPH
+0x8742 0x560A #CJK UNIFIED IDEOGRAPH
+0x8743 0x560B #CJK UNIFIED IDEOGRAPH
+0x8744 0x560D #CJK UNIFIED IDEOGRAPH
+0x8745 0x5610 #CJK UNIFIED IDEOGRAPH
+0x8746 0x5611 #CJK UNIFIED IDEOGRAPH
+0x8747 0x5612 #CJK UNIFIED IDEOGRAPH
+0x8748 0x5613 #CJK UNIFIED IDEOGRAPH
+0x8749 0x5614 #CJK UNIFIED IDEOGRAPH
+0x874A 0x5615 #CJK UNIFIED IDEOGRAPH
+0x874B 0x5616 #CJK UNIFIED IDEOGRAPH
+0x874C 0x5617 #CJK UNIFIED IDEOGRAPH
+0x874D 0x5619 #CJK UNIFIED IDEOGRAPH
+0x874E 0x561A #CJK UNIFIED IDEOGRAPH
+0x874F 0x561C #CJK UNIFIED IDEOGRAPH
+0x8750 0x561D #CJK UNIFIED IDEOGRAPH
+0x8751 0x5620 #CJK UNIFIED IDEOGRAPH
+0x8752 0x5621 #CJK UNIFIED IDEOGRAPH
+0x8753 0x5622 #CJK UNIFIED IDEOGRAPH
+0x8754 0x5625 #CJK UNIFIED IDEOGRAPH
+0x8755 0x5626 #CJK UNIFIED IDEOGRAPH
+0x8756 0x5628 #CJK UNIFIED IDEOGRAPH
+0x8757 0x5629 #CJK UNIFIED IDEOGRAPH
+0x8758 0x562A #CJK UNIFIED IDEOGRAPH
+0x8759 0x562B #CJK UNIFIED IDEOGRAPH
+0x875A 0x562E #CJK UNIFIED IDEOGRAPH
+0x875B 0x562F #CJK UNIFIED IDEOGRAPH
+0x875C 0x5630 #CJK UNIFIED IDEOGRAPH
+0x875D 0x5633 #CJK UNIFIED IDEOGRAPH
+0x875E 0x5635 #CJK UNIFIED IDEOGRAPH
+0x875F 0x5637 #CJK UNIFIED IDEOGRAPH
+0x8760 0x5638 #CJK UNIFIED IDEOGRAPH
+0x8761 0x563A #CJK UNIFIED IDEOGRAPH
+0x8762 0x563C #CJK UNIFIED IDEOGRAPH
+0x8763 0x563D #CJK UNIFIED IDEOGRAPH
+0x8764 0x563E #CJK UNIFIED IDEOGRAPH
+0x8765 0x5640 #CJK UNIFIED IDEOGRAPH
+0x8766 0x5641 #CJK UNIFIED IDEOGRAPH
+0x8767 0x5642 #CJK UNIFIED IDEOGRAPH
+0x8768 0x5643 #CJK UNIFIED IDEOGRAPH
+0x8769 0x5644 #CJK UNIFIED IDEOGRAPH
+0x876A 0x5645 #CJK UNIFIED IDEOGRAPH
+0x876B 0x5646 #CJK UNIFIED IDEOGRAPH
+0x876C 0x5647 #CJK UNIFIED IDEOGRAPH
+0x876D 0x5648 #CJK UNIFIED IDEOGRAPH
+0x876E 0x5649 #CJK UNIFIED IDEOGRAPH
+0x876F 0x564A #CJK UNIFIED IDEOGRAPH
+0x8770 0x564B #CJK UNIFIED IDEOGRAPH
+0x8771 0x564F #CJK UNIFIED IDEOGRAPH
+0x8772 0x5650 #CJK UNIFIED IDEOGRAPH
+0x8773 0x5651 #CJK UNIFIED IDEOGRAPH
+0x8774 0x5652 #CJK UNIFIED IDEOGRAPH
+0x8775 0x5653 #CJK UNIFIED IDEOGRAPH
+0x8776 0x5655 #CJK UNIFIED IDEOGRAPH
+0x8777 0x5656 #CJK UNIFIED IDEOGRAPH
+0x8778 0x565A #CJK UNIFIED IDEOGRAPH
+0x8779 0x565B #CJK UNIFIED IDEOGRAPH
+0x877A 0x565D #CJK UNIFIED IDEOGRAPH
+0x877B 0x565E #CJK UNIFIED IDEOGRAPH
+0x877C 0x565F #CJK UNIFIED IDEOGRAPH
+0x877D 0x5660 #CJK UNIFIED IDEOGRAPH
+0x877E 0x5661 #CJK UNIFIED IDEOGRAPH
+0x8780 0x5663 #CJK UNIFIED IDEOGRAPH
+0x8781 0x5665 #CJK UNIFIED IDEOGRAPH
+0x8782 0x5666 #CJK UNIFIED IDEOGRAPH
+0x8783 0x5667 #CJK UNIFIED IDEOGRAPH
+0x8784 0x566D #CJK UNIFIED IDEOGRAPH
+0x8785 0x566E #CJK UNIFIED IDEOGRAPH
+0x8786 0x566F #CJK UNIFIED IDEOGRAPH
+0x8787 0x5670 #CJK UNIFIED IDEOGRAPH
+0x8788 0x5672 #CJK UNIFIED IDEOGRAPH
+0x8789 0x5673 #CJK UNIFIED IDEOGRAPH
+0x878A 0x5674 #CJK UNIFIED IDEOGRAPH
+0x878B 0x5675 #CJK UNIFIED IDEOGRAPH
+0x878C 0x5677 #CJK UNIFIED IDEOGRAPH
+0x878D 0x5678 #CJK UNIFIED IDEOGRAPH
+0x878E 0x5679 #CJK UNIFIED IDEOGRAPH
+0x878F 0x567A #CJK UNIFIED IDEOGRAPH
+0x8790 0x567D #CJK UNIFIED IDEOGRAPH
+0x8791 0x567E #CJK UNIFIED IDEOGRAPH
+0x8792 0x567F #CJK UNIFIED IDEOGRAPH
+0x8793 0x5680 #CJK UNIFIED IDEOGRAPH
+0x8794 0x5681 #CJK UNIFIED IDEOGRAPH
+0x8795 0x5682 #CJK UNIFIED IDEOGRAPH
+0x8796 0x5683 #CJK UNIFIED IDEOGRAPH
+0x8797 0x5684 #CJK UNIFIED IDEOGRAPH
+0x8798 0x5687 #CJK UNIFIED IDEOGRAPH
+0x8799 0x5688 #CJK UNIFIED IDEOGRAPH
+0x879A 0x5689 #CJK UNIFIED IDEOGRAPH
+0x879B 0x568A #CJK UNIFIED IDEOGRAPH
+0x879C 0x568B #CJK UNIFIED IDEOGRAPH
+0x879D 0x568C #CJK UNIFIED IDEOGRAPH
+0x879E 0x568D #CJK UNIFIED IDEOGRAPH
+0x879F 0x5690 #CJK UNIFIED IDEOGRAPH
+0x87A0 0x5691 #CJK UNIFIED IDEOGRAPH
+0x87A1 0x5692 #CJK UNIFIED IDEOGRAPH
+0x87A2 0x5694 #CJK UNIFIED IDEOGRAPH
+0x87A3 0x5695 #CJK UNIFIED IDEOGRAPH
+0x87A4 0x5696 #CJK UNIFIED IDEOGRAPH
+0x87A5 0x5697 #CJK UNIFIED IDEOGRAPH
+0x87A6 0x5698 #CJK UNIFIED IDEOGRAPH
+0x87A7 0x5699 #CJK UNIFIED IDEOGRAPH
+0x87A8 0x569A #CJK UNIFIED IDEOGRAPH
+0x87A9 0x569B #CJK UNIFIED IDEOGRAPH
+0x87AA 0x569C #CJK UNIFIED IDEOGRAPH
+0x87AB 0x569D #CJK UNIFIED IDEOGRAPH
+0x87AC 0x569E #CJK UNIFIED IDEOGRAPH
+0x87AD 0x569F #CJK UNIFIED IDEOGRAPH
+0x87AE 0x56A0 #CJK UNIFIED IDEOGRAPH
+0x87AF 0x56A1 #CJK UNIFIED IDEOGRAPH
+0x87B0 0x56A2 #CJK UNIFIED IDEOGRAPH
+0x87B1 0x56A4 #CJK UNIFIED IDEOGRAPH
+0x87B2 0x56A5 #CJK UNIFIED IDEOGRAPH
+0x87B3 0x56A6 #CJK UNIFIED IDEOGRAPH
+0x87B4 0x56A7 #CJK UNIFIED IDEOGRAPH
+0x87B5 0x56A8 #CJK UNIFIED IDEOGRAPH
+0x87B6 0x56A9 #CJK UNIFIED IDEOGRAPH
+0x87B7 0x56AA #CJK UNIFIED IDEOGRAPH
+0x87B8 0x56AB #CJK UNIFIED IDEOGRAPH
+0x87B9 0x56AC #CJK UNIFIED IDEOGRAPH
+0x87BA 0x56AD #CJK UNIFIED IDEOGRAPH
+0x87BB 0x56AE #CJK UNIFIED IDEOGRAPH
+0x87BC 0x56B0 #CJK UNIFIED IDEOGRAPH
+0x87BD 0x56B1 #CJK UNIFIED IDEOGRAPH
+0x87BE 0x56B2 #CJK UNIFIED IDEOGRAPH
+0x87BF 0x56B3 #CJK UNIFIED IDEOGRAPH
+0x87C0 0x56B4 #CJK UNIFIED IDEOGRAPH
+0x87C1 0x56B5 #CJK UNIFIED IDEOGRAPH
+0x87C2 0x56B6 #CJK UNIFIED IDEOGRAPH
+0x87C3 0x56B8 #CJK UNIFIED IDEOGRAPH
+0x87C4 0x56B9 #CJK UNIFIED IDEOGRAPH
+0x87C5 0x56BA #CJK UNIFIED IDEOGRAPH
+0x87C6 0x56BB #CJK UNIFIED IDEOGRAPH
+0x87C7 0x56BD #CJK UNIFIED IDEOGRAPH
+0x87C8 0x56BE #CJK UNIFIED IDEOGRAPH
+0x87C9 0x56BF #CJK UNIFIED IDEOGRAPH
+0x87CA 0x56C0 #CJK UNIFIED IDEOGRAPH
+0x87CB 0x56C1 #CJK UNIFIED IDEOGRAPH
+0x87CC 0x56C2 #CJK UNIFIED IDEOGRAPH
+0x87CD 0x56C3 #CJK UNIFIED IDEOGRAPH
+0x87CE 0x56C4 #CJK UNIFIED IDEOGRAPH
+0x87CF 0x56C5 #CJK UNIFIED IDEOGRAPH
+0x87D0 0x56C6 #CJK UNIFIED IDEOGRAPH
+0x87D1 0x56C7 #CJK UNIFIED IDEOGRAPH
+0x87D2 0x56C8 #CJK UNIFIED IDEOGRAPH
+0x87D3 0x56C9 #CJK UNIFIED IDEOGRAPH
+0x87D4 0x56CB #CJK UNIFIED IDEOGRAPH
+0x87D5 0x56CC #CJK UNIFIED IDEOGRAPH
+0x87D6 0x56CD #CJK UNIFIED IDEOGRAPH
+0x87D7 0x56CE #CJK UNIFIED IDEOGRAPH
+0x87D8 0x56CF #CJK UNIFIED IDEOGRAPH
+0x87D9 0x56D0 #CJK UNIFIED IDEOGRAPH
+0x87DA 0x56D1 #CJK UNIFIED IDEOGRAPH
+0x87DB 0x56D2 #CJK UNIFIED IDEOGRAPH
+0x87DC 0x56D3 #CJK UNIFIED IDEOGRAPH
+0x87DD 0x56D5 #CJK UNIFIED IDEOGRAPH
+0x87DE 0x56D6 #CJK UNIFIED IDEOGRAPH
+0x87DF 0x56D8 #CJK UNIFIED IDEOGRAPH
+0x87E0 0x56D9 #CJK UNIFIED IDEOGRAPH
+0x87E1 0x56DC #CJK UNIFIED IDEOGRAPH
+0x87E2 0x56E3 #CJK UNIFIED IDEOGRAPH
+0x87E3 0x56E5 #CJK UNIFIED IDEOGRAPH
+0x87E4 0x56E6 #CJK UNIFIED IDEOGRAPH
+0x87E5 0x56E7 #CJK UNIFIED IDEOGRAPH
+0x87E6 0x56E8 #CJK UNIFIED IDEOGRAPH
+0x87E7 0x56E9 #CJK UNIFIED IDEOGRAPH
+0x87E8 0x56EA #CJK UNIFIED IDEOGRAPH
+0x87E9 0x56EC #CJK UNIFIED IDEOGRAPH
+0x87EA 0x56EE #CJK UNIFIED IDEOGRAPH
+0x87EB 0x56EF #CJK UNIFIED IDEOGRAPH
+0x87EC 0x56F2 #CJK UNIFIED IDEOGRAPH
+0x87ED 0x56F3 #CJK UNIFIED IDEOGRAPH
+0x87EE 0x56F6 #CJK UNIFIED IDEOGRAPH
+0x87EF 0x56F7 #CJK UNIFIED IDEOGRAPH
+0x87F0 0x56F8 #CJK UNIFIED IDEOGRAPH
+0x87F1 0x56FB #CJK UNIFIED IDEOGRAPH
+0x87F2 0x56FC #CJK UNIFIED IDEOGRAPH
+0x87F3 0x5700 #CJK UNIFIED IDEOGRAPH
+0x87F4 0x5701 #CJK UNIFIED IDEOGRAPH
+0x87F5 0x5702 #CJK UNIFIED IDEOGRAPH
+0x87F6 0x5705 #CJK UNIFIED IDEOGRAPH
+0x87F7 0x5707 #CJK UNIFIED IDEOGRAPH
+0x87F8 0x570B #CJK UNIFIED IDEOGRAPH
+0x87F9 0x570C #CJK UNIFIED IDEOGRAPH
+0x87FA 0x570D #CJK UNIFIED IDEOGRAPH
+0x87FB 0x570E #CJK UNIFIED IDEOGRAPH
+0x87FC 0x570F #CJK UNIFIED IDEOGRAPH
+0x87FD 0x5710 #CJK UNIFIED IDEOGRAPH
+0x87FE 0x5711 #CJK UNIFIED IDEOGRAPH
+0x8840 0x5712 #CJK UNIFIED IDEOGRAPH
+0x8841 0x5713 #CJK UNIFIED IDEOGRAPH
+0x8842 0x5714 #CJK UNIFIED IDEOGRAPH
+0x8843 0x5715 #CJK UNIFIED IDEOGRAPH
+0x8844 0x5716 #CJK UNIFIED IDEOGRAPH
+0x8845 0x5717 #CJK UNIFIED IDEOGRAPH
+0x8846 0x5718 #CJK UNIFIED IDEOGRAPH
+0x8847 0x5719 #CJK UNIFIED IDEOGRAPH
+0x8848 0x571A #CJK UNIFIED IDEOGRAPH
+0x8849 0x571B #CJK UNIFIED IDEOGRAPH
+0x884A 0x571D #CJK UNIFIED IDEOGRAPH
+0x884B 0x571E #CJK UNIFIED IDEOGRAPH
+0x884C 0x5720 #CJK UNIFIED IDEOGRAPH
+0x884D 0x5721 #CJK UNIFIED IDEOGRAPH
+0x884E 0x5722 #CJK UNIFIED IDEOGRAPH
+0x884F 0x5724 #CJK UNIFIED IDEOGRAPH
+0x8850 0x5725 #CJK UNIFIED IDEOGRAPH
+0x8851 0x5726 #CJK UNIFIED IDEOGRAPH
+0x8852 0x5727 #CJK UNIFIED IDEOGRAPH
+0x8853 0x572B #CJK UNIFIED IDEOGRAPH
+0x8854 0x5731 #CJK UNIFIED IDEOGRAPH
+0x8855 0x5732 #CJK UNIFIED IDEOGRAPH
+0x8856 0x5734 #CJK UNIFIED IDEOGRAPH
+0x8857 0x5735 #CJK UNIFIED IDEOGRAPH
+0x8858 0x5736 #CJK UNIFIED IDEOGRAPH
+0x8859 0x5737 #CJK UNIFIED IDEOGRAPH
+0x885A 0x5738 #CJK UNIFIED IDEOGRAPH
+0x885B 0x573C #CJK UNIFIED IDEOGRAPH
+0x885C 0x573D #CJK UNIFIED IDEOGRAPH
+0x885D 0x573F #CJK UNIFIED IDEOGRAPH
+0x885E 0x5741 #CJK UNIFIED IDEOGRAPH
+0x885F 0x5743 #CJK UNIFIED IDEOGRAPH
+0x8860 0x5744 #CJK UNIFIED IDEOGRAPH
+0x8861 0x5745 #CJK UNIFIED IDEOGRAPH
+0x8862 0x5746 #CJK UNIFIED IDEOGRAPH
+0x8863 0x5748 #CJK UNIFIED IDEOGRAPH
+0x8864 0x5749 #CJK UNIFIED IDEOGRAPH
+0x8865 0x574B #CJK UNIFIED IDEOGRAPH
+0x8866 0x5752 #CJK UNIFIED IDEOGRAPH
+0x8867 0x5753 #CJK UNIFIED IDEOGRAPH
+0x8868 0x5754 #CJK UNIFIED IDEOGRAPH
+0x8869 0x5755 #CJK UNIFIED IDEOGRAPH
+0x886A 0x5756 #CJK UNIFIED IDEOGRAPH
+0x886B 0x5758 #CJK UNIFIED IDEOGRAPH
+0x886C 0x5759 #CJK UNIFIED IDEOGRAPH
+0x886D 0x5762 #CJK UNIFIED IDEOGRAPH
+0x886E 0x5763 #CJK UNIFIED IDEOGRAPH
+0x886F 0x5765 #CJK UNIFIED IDEOGRAPH
+0x8870 0x5767 #CJK UNIFIED IDEOGRAPH
+0x8871 0x576C #CJK UNIFIED IDEOGRAPH
+0x8872 0x576E #CJK UNIFIED IDEOGRAPH
+0x8873 0x5770 #CJK UNIFIED IDEOGRAPH
+0x8874 0x5771 #CJK UNIFIED IDEOGRAPH
+0x8875 0x5772 #CJK UNIFIED IDEOGRAPH
+0x8876 0x5774 #CJK UNIFIED IDEOGRAPH
+0x8877 0x5775 #CJK UNIFIED IDEOGRAPH
+0x8878 0x5778 #CJK UNIFIED IDEOGRAPH
+0x8879 0x5779 #CJK UNIFIED IDEOGRAPH
+0x887A 0x577A #CJK UNIFIED IDEOGRAPH
+0x887B 0x577D #CJK UNIFIED IDEOGRAPH
+0x887C 0x577E #CJK UNIFIED IDEOGRAPH
+0x887D 0x577F #CJK UNIFIED IDEOGRAPH
+0x887E 0x5780 #CJK UNIFIED IDEOGRAPH
+0x8880 0x5781 #CJK UNIFIED IDEOGRAPH
+0x8881 0x5787 #CJK UNIFIED IDEOGRAPH
+0x8882 0x5788 #CJK UNIFIED IDEOGRAPH
+0x8883 0x5789 #CJK UNIFIED IDEOGRAPH
+0x8884 0x578A #CJK UNIFIED IDEOGRAPH
+0x8885 0x578D #CJK UNIFIED IDEOGRAPH
+0x8886 0x578E #CJK UNIFIED IDEOGRAPH
+0x8887 0x578F #CJK UNIFIED IDEOGRAPH
+0x8888 0x5790 #CJK UNIFIED IDEOGRAPH
+0x8889 0x5791 #CJK UNIFIED IDEOGRAPH
+0x888A 0x5794 #CJK UNIFIED IDEOGRAPH
+0x888B 0x5795 #CJK UNIFIED IDEOGRAPH
+0x888C 0x5796 #CJK UNIFIED IDEOGRAPH
+0x888D 0x5797 #CJK UNIFIED IDEOGRAPH
+0x888E 0x5798 #CJK UNIFIED IDEOGRAPH
+0x888F 0x5799 #CJK UNIFIED IDEOGRAPH
+0x8890 0x579A #CJK UNIFIED IDEOGRAPH
+0x8891 0x579C #CJK UNIFIED IDEOGRAPH
+0x8892 0x579D #CJK UNIFIED IDEOGRAPH
+0x8893 0x579E #CJK UNIFIED IDEOGRAPH
+0x8894 0x579F #CJK UNIFIED IDEOGRAPH
+0x8895 0x57A5 #CJK UNIFIED IDEOGRAPH
+0x8896 0x57A8 #CJK UNIFIED IDEOGRAPH
+0x8897 0x57AA #CJK UNIFIED IDEOGRAPH
+0x8898 0x57AC #CJK UNIFIED IDEOGRAPH
+0x8899 0x57AF #CJK UNIFIED IDEOGRAPH
+0x889A 0x57B0 #CJK UNIFIED IDEOGRAPH
+0x889B 0x57B1 #CJK UNIFIED IDEOGRAPH
+0x889C 0x57B3 #CJK UNIFIED IDEOGRAPH
+0x889D 0x57B5 #CJK UNIFIED IDEOGRAPH
+0x889E 0x57B6 #CJK UNIFIED IDEOGRAPH
+0x889F 0x57B7 #CJK UNIFIED IDEOGRAPH
+0x88A0 0x57B9 #CJK UNIFIED IDEOGRAPH
+0x88A1 0x57BA #CJK UNIFIED IDEOGRAPH
+0x88A2 0x57BB #CJK UNIFIED IDEOGRAPH
+0x88A3 0x57BC #CJK UNIFIED IDEOGRAPH
+0x88A4 0x57BD #CJK UNIFIED IDEOGRAPH
+0x88A5 0x57BE #CJK UNIFIED IDEOGRAPH
+0x88A6 0x57BF #CJK UNIFIED IDEOGRAPH
+0x88A7 0x57C0 #CJK UNIFIED IDEOGRAPH
+0x88A8 0x57C1 #CJK UNIFIED IDEOGRAPH
+0x88A9 0x57C4 #CJK UNIFIED IDEOGRAPH
+0x88AA 0x57C5 #CJK UNIFIED IDEOGRAPH
+0x88AB 0x57C6 #CJK UNIFIED IDEOGRAPH
+0x88AC 0x57C7 #CJK UNIFIED IDEOGRAPH
+0x88AD 0x57C8 #CJK UNIFIED IDEOGRAPH
+0x88AE 0x57C9 #CJK UNIFIED IDEOGRAPH
+0x88AF 0x57CA #CJK UNIFIED IDEOGRAPH
+0x88B0 0x57CC #CJK UNIFIED IDEOGRAPH
+0x88B1 0x57CD #CJK UNIFIED IDEOGRAPH
+0x88B2 0x57D0 #CJK UNIFIED IDEOGRAPH
+0x88B3 0x57D1 #CJK UNIFIED IDEOGRAPH
+0x88B4 0x57D3 #CJK UNIFIED IDEOGRAPH
+0x88B5 0x57D6 #CJK UNIFIED IDEOGRAPH
+0x88B6 0x57D7 #CJK UNIFIED IDEOGRAPH
+0x88B7 0x57DB #CJK UNIFIED IDEOGRAPH
+0x88B8 0x57DC #CJK UNIFIED IDEOGRAPH
+0x88B9 0x57DE #CJK UNIFIED IDEOGRAPH
+0x88BA 0x57E1 #CJK UNIFIED IDEOGRAPH
+0x88BB 0x57E2 #CJK UNIFIED IDEOGRAPH
+0x88BC 0x57E3 #CJK UNIFIED IDEOGRAPH
+0x88BD 0x57E5 #CJK UNIFIED IDEOGRAPH
+0x88BE 0x57E6 #CJK UNIFIED IDEOGRAPH
+0x88BF 0x57E7 #CJK UNIFIED IDEOGRAPH
+0x88C0 0x57E8 #CJK UNIFIED IDEOGRAPH
+0x88C1 0x57E9 #CJK UNIFIED IDEOGRAPH
+0x88C2 0x57EA #CJK UNIFIED IDEOGRAPH
+0x88C3 0x57EB #CJK UNIFIED IDEOGRAPH
+0x88C4 0x57EC #CJK UNIFIED IDEOGRAPH
+0x88C5 0x57EE #CJK UNIFIED IDEOGRAPH
+0x88C6 0x57F0 #CJK UNIFIED IDEOGRAPH
+0x88C7 0x57F1 #CJK UNIFIED IDEOGRAPH
+0x88C8 0x57F2 #CJK UNIFIED IDEOGRAPH
+0x88C9 0x57F3 #CJK UNIFIED IDEOGRAPH
+0x88CA 0x57F5 #CJK UNIFIED IDEOGRAPH
+0x88CB 0x57F6 #CJK UNIFIED IDEOGRAPH
+0x88CC 0x57F7 #CJK UNIFIED IDEOGRAPH
+0x88CD 0x57FB #CJK UNIFIED IDEOGRAPH
+0x88CE 0x57FC #CJK UNIFIED IDEOGRAPH
+0x88CF 0x57FE #CJK UNIFIED IDEOGRAPH
+0x88D0 0x57FF #CJK UNIFIED IDEOGRAPH
+0x88D1 0x5801 #CJK UNIFIED IDEOGRAPH
+0x88D2 0x5803 #CJK UNIFIED IDEOGRAPH
+0x88D3 0x5804 #CJK UNIFIED IDEOGRAPH
+0x88D4 0x5805 #CJK UNIFIED IDEOGRAPH
+0x88D5 0x5808 #CJK UNIFIED IDEOGRAPH
+0x88D6 0x5809 #CJK UNIFIED IDEOGRAPH
+0x88D7 0x580A #CJK UNIFIED IDEOGRAPH
+0x88D8 0x580C #CJK UNIFIED IDEOGRAPH
+0x88D9 0x580E #CJK UNIFIED IDEOGRAPH
+0x88DA 0x580F #CJK UNIFIED IDEOGRAPH
+0x88DB 0x5810 #CJK UNIFIED IDEOGRAPH
+0x88DC 0x5812 #CJK UNIFIED IDEOGRAPH
+0x88DD 0x5813 #CJK UNIFIED IDEOGRAPH
+0x88DE 0x5814 #CJK UNIFIED IDEOGRAPH
+0x88DF 0x5816 #CJK UNIFIED IDEOGRAPH
+0x88E0 0x5817 #CJK UNIFIED IDEOGRAPH
+0x88E1 0x5818 #CJK UNIFIED IDEOGRAPH
+0x88E2 0x581A #CJK UNIFIED IDEOGRAPH
+0x88E3 0x581B #CJK UNIFIED IDEOGRAPH
+0x88E4 0x581C #CJK UNIFIED IDEOGRAPH
+0x88E5 0x581D #CJK UNIFIED IDEOGRAPH
+0x88E6 0x581F #CJK UNIFIED IDEOGRAPH
+0x88E7 0x5822 #CJK UNIFIED IDEOGRAPH
+0x88E8 0x5823 #CJK UNIFIED IDEOGRAPH
+0x88E9 0x5825 #CJK UNIFIED IDEOGRAPH
+0x88EA 0x5826 #CJK UNIFIED IDEOGRAPH
+0x88EB 0x5827 #CJK UNIFIED IDEOGRAPH
+0x88EC 0x5828 #CJK UNIFIED IDEOGRAPH
+0x88ED 0x5829 #CJK UNIFIED IDEOGRAPH
+0x88EE 0x582B #CJK UNIFIED IDEOGRAPH
+0x88EF 0x582C #CJK UNIFIED IDEOGRAPH
+0x88F0 0x582D #CJK UNIFIED IDEOGRAPH
+0x88F1 0x582E #CJK UNIFIED IDEOGRAPH
+0x88F2 0x582F #CJK UNIFIED IDEOGRAPH
+0x88F3 0x5831 #CJK UNIFIED IDEOGRAPH
+0x88F4 0x5832 #CJK UNIFIED IDEOGRAPH
+0x88F5 0x5833 #CJK UNIFIED IDEOGRAPH
+0x88F6 0x5834 #CJK UNIFIED IDEOGRAPH
+0x88F7 0x5836 #CJK UNIFIED IDEOGRAPH
+0x88F8 0x5837 #CJK UNIFIED IDEOGRAPH
+0x88F9 0x5838 #CJK UNIFIED IDEOGRAPH
+0x88FA 0x5839 #CJK UNIFIED IDEOGRAPH
+0x88FB 0x583A #CJK UNIFIED IDEOGRAPH
+0x88FC 0x583B #CJK UNIFIED IDEOGRAPH
+0x88FD 0x583C #CJK UNIFIED IDEOGRAPH
+0x88FE 0x583D #CJK UNIFIED IDEOGRAPH
+0x8940 0x583E #CJK UNIFIED IDEOGRAPH
+0x8941 0x583F #CJK UNIFIED IDEOGRAPH
+0x8942 0x5840 #CJK UNIFIED IDEOGRAPH
+0x8943 0x5841 #CJK UNIFIED IDEOGRAPH
+0x8944 0x5842 #CJK UNIFIED IDEOGRAPH
+0x8945 0x5843 #CJK UNIFIED IDEOGRAPH
+0x8946 0x5845 #CJK UNIFIED IDEOGRAPH
+0x8947 0x5846 #CJK UNIFIED IDEOGRAPH
+0x8948 0x5847 #CJK UNIFIED IDEOGRAPH
+0x8949 0x5848 #CJK UNIFIED IDEOGRAPH
+0x894A 0x5849 #CJK UNIFIED IDEOGRAPH
+0x894B 0x584A #CJK UNIFIED IDEOGRAPH
+0x894C 0x584B #CJK UNIFIED IDEOGRAPH
+0x894D 0x584E #CJK UNIFIED IDEOGRAPH
+0x894E 0x584F #CJK UNIFIED IDEOGRAPH
+0x894F 0x5850 #CJK UNIFIED IDEOGRAPH
+0x8950 0x5852 #CJK UNIFIED IDEOGRAPH
+0x8951 0x5853 #CJK UNIFIED IDEOGRAPH
+0x8952 0x5855 #CJK UNIFIED IDEOGRAPH
+0x8953 0x5856 #CJK UNIFIED IDEOGRAPH
+0x8954 0x5857 #CJK UNIFIED IDEOGRAPH
+0x8955 0x5859 #CJK UNIFIED IDEOGRAPH
+0x8956 0x585A #CJK UNIFIED IDEOGRAPH
+0x8957 0x585B #CJK UNIFIED IDEOGRAPH
+0x8958 0x585C #CJK UNIFIED IDEOGRAPH
+0x8959 0x585D #CJK UNIFIED IDEOGRAPH
+0x895A 0x585F #CJK UNIFIED IDEOGRAPH
+0x895B 0x5860 #CJK UNIFIED IDEOGRAPH
+0x895C 0x5861 #CJK UNIFIED IDEOGRAPH
+0x895D 0x5862 #CJK UNIFIED IDEOGRAPH
+0x895E 0x5863 #CJK UNIFIED IDEOGRAPH
+0x895F 0x5864 #CJK UNIFIED IDEOGRAPH
+0x8960 0x5866 #CJK UNIFIED IDEOGRAPH
+0x8961 0x5867 #CJK UNIFIED IDEOGRAPH
+0x8962 0x5868 #CJK UNIFIED IDEOGRAPH
+0x8963 0x5869 #CJK UNIFIED IDEOGRAPH
+0x8964 0x586A #CJK UNIFIED IDEOGRAPH
+0x8965 0x586D #CJK UNIFIED IDEOGRAPH
+0x8966 0x586E #CJK UNIFIED IDEOGRAPH
+0x8967 0x586F #CJK UNIFIED IDEOGRAPH
+0x8968 0x5870 #CJK UNIFIED IDEOGRAPH
+0x8969 0x5871 #CJK UNIFIED IDEOGRAPH
+0x896A 0x5872 #CJK UNIFIED IDEOGRAPH
+0x896B 0x5873 #CJK UNIFIED IDEOGRAPH
+0x896C 0x5874 #CJK UNIFIED IDEOGRAPH
+0x896D 0x5875 #CJK UNIFIED IDEOGRAPH
+0x896E 0x5876 #CJK UNIFIED IDEOGRAPH
+0x896F 0x5877 #CJK UNIFIED IDEOGRAPH
+0x8970 0x5878 #CJK UNIFIED IDEOGRAPH
+0x8971 0x5879 #CJK UNIFIED IDEOGRAPH
+0x8972 0x587A #CJK UNIFIED IDEOGRAPH
+0x8973 0x587B #CJK UNIFIED IDEOGRAPH
+0x8974 0x587C #CJK UNIFIED IDEOGRAPH
+0x8975 0x587D #CJK UNIFIED IDEOGRAPH
+0x8976 0x587F #CJK UNIFIED IDEOGRAPH
+0x8977 0x5882 #CJK UNIFIED IDEOGRAPH
+0x8978 0x5884 #CJK UNIFIED IDEOGRAPH
+0x8979 0x5886 #CJK UNIFIED IDEOGRAPH
+0x897A 0x5887 #CJK UNIFIED IDEOGRAPH
+0x897B 0x5888 #CJK UNIFIED IDEOGRAPH
+0x897C 0x588A #CJK UNIFIED IDEOGRAPH
+0x897D 0x588B #CJK UNIFIED IDEOGRAPH
+0x897E 0x588C #CJK UNIFIED IDEOGRAPH
+0x8980 0x588D #CJK UNIFIED IDEOGRAPH
+0x8981 0x588E #CJK UNIFIED IDEOGRAPH
+0x8982 0x588F #CJK UNIFIED IDEOGRAPH
+0x8983 0x5890 #CJK UNIFIED IDEOGRAPH
+0x8984 0x5891 #CJK UNIFIED IDEOGRAPH
+0x8985 0x5894 #CJK UNIFIED IDEOGRAPH
+0x8986 0x5895 #CJK UNIFIED IDEOGRAPH
+0x8987 0x5896 #CJK UNIFIED IDEOGRAPH
+0x8988 0x5897 #CJK UNIFIED IDEOGRAPH
+0x8989 0x5898 #CJK UNIFIED IDEOGRAPH
+0x898A 0x589B #CJK UNIFIED IDEOGRAPH
+0x898B 0x589C #CJK UNIFIED IDEOGRAPH
+0x898C 0x589D #CJK UNIFIED IDEOGRAPH
+0x898D 0x58A0 #CJK UNIFIED IDEOGRAPH
+0x898E 0x58A1 #CJK UNIFIED IDEOGRAPH
+0x898F 0x58A2 #CJK UNIFIED IDEOGRAPH
+0x8990 0x58A3 #CJK UNIFIED IDEOGRAPH
+0x8991 0x58A4 #CJK UNIFIED IDEOGRAPH
+0x8992 0x58A5 #CJK UNIFIED IDEOGRAPH
+0x8993 0x58A6 #CJK UNIFIED IDEOGRAPH
+0x8994 0x58A7 #CJK UNIFIED IDEOGRAPH
+0x8995 0x58AA #CJK UNIFIED IDEOGRAPH
+0x8996 0x58AB #CJK UNIFIED IDEOGRAPH
+0x8997 0x58AC #CJK UNIFIED IDEOGRAPH
+0x8998 0x58AD #CJK UNIFIED IDEOGRAPH
+0x8999 0x58AE #CJK UNIFIED IDEOGRAPH
+0x899A 0x58AF #CJK UNIFIED IDEOGRAPH
+0x899B 0x58B0 #CJK UNIFIED IDEOGRAPH
+0x899C 0x58B1 #CJK UNIFIED IDEOGRAPH
+0x899D 0x58B2 #CJK UNIFIED IDEOGRAPH
+0x899E 0x58B3 #CJK UNIFIED IDEOGRAPH
+0x899F 0x58B4 #CJK UNIFIED IDEOGRAPH
+0x89A0 0x58B5 #CJK UNIFIED IDEOGRAPH
+0x89A1 0x58B6 #CJK UNIFIED IDEOGRAPH
+0x89A2 0x58B7 #CJK UNIFIED IDEOGRAPH
+0x89A3 0x58B8 #CJK UNIFIED IDEOGRAPH
+0x89A4 0x58B9 #CJK UNIFIED IDEOGRAPH
+0x89A5 0x58BA #CJK UNIFIED IDEOGRAPH
+0x89A6 0x58BB #CJK UNIFIED IDEOGRAPH
+0x89A7 0x58BD #CJK UNIFIED IDEOGRAPH
+0x89A8 0x58BE #CJK UNIFIED IDEOGRAPH
+0x89A9 0x58BF #CJK UNIFIED IDEOGRAPH
+0x89AA 0x58C0 #CJK UNIFIED IDEOGRAPH
+0x89AB 0x58C2 #CJK UNIFIED IDEOGRAPH
+0x89AC 0x58C3 #CJK UNIFIED IDEOGRAPH
+0x89AD 0x58C4 #CJK UNIFIED IDEOGRAPH
+0x89AE 0x58C6 #CJK UNIFIED IDEOGRAPH
+0x89AF 0x58C7 #CJK UNIFIED IDEOGRAPH
+0x89B0 0x58C8 #CJK UNIFIED IDEOGRAPH
+0x89B1 0x58C9 #CJK UNIFIED IDEOGRAPH
+0x89B2 0x58CA #CJK UNIFIED IDEOGRAPH
+0x89B3 0x58CB #CJK UNIFIED IDEOGRAPH
+0x89B4 0x58CC #CJK UNIFIED IDEOGRAPH
+0x89B5 0x58CD #CJK UNIFIED IDEOGRAPH
+0x89B6 0x58CE #CJK UNIFIED IDEOGRAPH
+0x89B7 0x58CF #CJK UNIFIED IDEOGRAPH
+0x89B8 0x58D0 #CJK UNIFIED IDEOGRAPH
+0x89B9 0x58D2 #CJK UNIFIED IDEOGRAPH
+0x89BA 0x58D3 #CJK UNIFIED IDEOGRAPH
+0x89BB 0x58D4 #CJK UNIFIED IDEOGRAPH
+0x89BC 0x58D6 #CJK UNIFIED IDEOGRAPH
+0x89BD 0x58D7 #CJK UNIFIED IDEOGRAPH
+0x89BE 0x58D8 #CJK UNIFIED IDEOGRAPH
+0x89BF 0x58D9 #CJK UNIFIED IDEOGRAPH
+0x89C0 0x58DA #CJK UNIFIED IDEOGRAPH
+0x89C1 0x58DB #CJK UNIFIED IDEOGRAPH
+0x89C2 0x58DC #CJK UNIFIED IDEOGRAPH
+0x89C3 0x58DD #CJK UNIFIED IDEOGRAPH
+0x89C4 0x58DE #CJK UNIFIED IDEOGRAPH
+0x89C5 0x58DF #CJK UNIFIED IDEOGRAPH
+0x89C6 0x58E0 #CJK UNIFIED IDEOGRAPH
+0x89C7 0x58E1 #CJK UNIFIED IDEOGRAPH
+0x89C8 0x58E2 #CJK UNIFIED IDEOGRAPH
+0x89C9 0x58E3 #CJK UNIFIED IDEOGRAPH
+0x89CA 0x58E5 #CJK UNIFIED IDEOGRAPH
+0x89CB 0x58E6 #CJK UNIFIED IDEOGRAPH
+0x89CC 0x58E7 #CJK UNIFIED IDEOGRAPH
+0x89CD 0x58E8 #CJK UNIFIED IDEOGRAPH
+0x89CE 0x58E9 #CJK UNIFIED IDEOGRAPH
+0x89CF 0x58EA #CJK UNIFIED IDEOGRAPH
+0x89D0 0x58ED #CJK UNIFIED IDEOGRAPH
+0x89D1 0x58EF #CJK UNIFIED IDEOGRAPH
+0x89D2 0x58F1 #CJK UNIFIED IDEOGRAPH
+0x89D3 0x58F2 #CJK UNIFIED IDEOGRAPH
+0x89D4 0x58F4 #CJK UNIFIED IDEOGRAPH
+0x89D5 0x58F5 #CJK UNIFIED IDEOGRAPH
+0x89D6 0x58F7 #CJK UNIFIED IDEOGRAPH
+0x89D7 0x58F8 #CJK UNIFIED IDEOGRAPH
+0x89D8 0x58FA #CJK UNIFIED IDEOGRAPH
+0x89D9 0x58FB #CJK UNIFIED IDEOGRAPH
+0x89DA 0x58FC #CJK UNIFIED IDEOGRAPH
+0x89DB 0x58FD #CJK UNIFIED IDEOGRAPH
+0x89DC 0x58FE #CJK UNIFIED IDEOGRAPH
+0x89DD 0x58FF #CJK UNIFIED IDEOGRAPH
+0x89DE 0x5900 #CJK UNIFIED IDEOGRAPH
+0x89DF 0x5901 #CJK UNIFIED IDEOGRAPH
+0x89E0 0x5903 #CJK UNIFIED IDEOGRAPH
+0x89E1 0x5905 #CJK UNIFIED IDEOGRAPH
+0x89E2 0x5906 #CJK UNIFIED IDEOGRAPH
+0x89E3 0x5908 #CJK UNIFIED IDEOGRAPH
+0x89E4 0x5909 #CJK UNIFIED IDEOGRAPH
+0x89E5 0x590A #CJK UNIFIED IDEOGRAPH
+0x89E6 0x590B #CJK UNIFIED IDEOGRAPH
+0x89E7 0x590C #CJK UNIFIED IDEOGRAPH
+0x89E8 0x590E #CJK UNIFIED IDEOGRAPH
+0x89E9 0x5910 #CJK UNIFIED IDEOGRAPH
+0x89EA 0x5911 #CJK UNIFIED IDEOGRAPH
+0x89EB 0x5912 #CJK UNIFIED IDEOGRAPH
+0x89EC 0x5913 #CJK UNIFIED IDEOGRAPH
+0x89ED 0x5917 #CJK UNIFIED IDEOGRAPH
+0x89EE 0x5918 #CJK UNIFIED IDEOGRAPH
+0x89EF 0x591B #CJK UNIFIED IDEOGRAPH
+0x89F0 0x591D #CJK UNIFIED IDEOGRAPH
+0x89F1 0x591E #CJK UNIFIED IDEOGRAPH
+0x89F2 0x5920 #CJK UNIFIED IDEOGRAPH
+0x89F3 0x5921 #CJK UNIFIED IDEOGRAPH
+0x89F4 0x5922 #CJK UNIFIED IDEOGRAPH
+0x89F5 0x5923 #CJK UNIFIED IDEOGRAPH
+0x89F6 0x5926 #CJK UNIFIED IDEOGRAPH
+0x89F7 0x5928 #CJK UNIFIED IDEOGRAPH
+0x89F8 0x592C #CJK UNIFIED IDEOGRAPH
+0x89F9 0x5930 #CJK UNIFIED IDEOGRAPH
+0x89FA 0x5932 #CJK UNIFIED IDEOGRAPH
+0x89FB 0x5933 #CJK UNIFIED IDEOGRAPH
+0x89FC 0x5935 #CJK UNIFIED IDEOGRAPH
+0x89FD 0x5936 #CJK UNIFIED IDEOGRAPH
+0x89FE 0x593B #CJK UNIFIED IDEOGRAPH
+0x8A40 0x593D #CJK UNIFIED IDEOGRAPH
+0x8A41 0x593E #CJK UNIFIED IDEOGRAPH
+0x8A42 0x593F #CJK UNIFIED IDEOGRAPH
+0x8A43 0x5940 #CJK UNIFIED IDEOGRAPH
+0x8A44 0x5943 #CJK UNIFIED IDEOGRAPH
+0x8A45 0x5945 #CJK UNIFIED IDEOGRAPH
+0x8A46 0x5946 #CJK UNIFIED IDEOGRAPH
+0x8A47 0x594A #CJK UNIFIED IDEOGRAPH
+0x8A48 0x594C #CJK UNIFIED IDEOGRAPH
+0x8A49 0x594D #CJK UNIFIED IDEOGRAPH
+0x8A4A 0x5950 #CJK UNIFIED IDEOGRAPH
+0x8A4B 0x5952 #CJK UNIFIED IDEOGRAPH
+0x8A4C 0x5953 #CJK UNIFIED IDEOGRAPH
+0x8A4D 0x5959 #CJK UNIFIED IDEOGRAPH
+0x8A4E 0x595B #CJK UNIFIED IDEOGRAPH
+0x8A4F 0x595C #CJK UNIFIED IDEOGRAPH
+0x8A50 0x595D #CJK UNIFIED IDEOGRAPH
+0x8A51 0x595E #CJK UNIFIED IDEOGRAPH
+0x8A52 0x595F #CJK UNIFIED IDEOGRAPH
+0x8A53 0x5961 #CJK UNIFIED IDEOGRAPH
+0x8A54 0x5963 #CJK UNIFIED IDEOGRAPH
+0x8A55 0x5964 #CJK UNIFIED IDEOGRAPH
+0x8A56 0x5966 #CJK UNIFIED IDEOGRAPH
+0x8A57 0x5967 #CJK UNIFIED IDEOGRAPH
+0x8A58 0x5968 #CJK UNIFIED IDEOGRAPH
+0x8A59 0x5969 #CJK UNIFIED IDEOGRAPH
+0x8A5A 0x596A #CJK UNIFIED IDEOGRAPH
+0x8A5B 0x596B #CJK UNIFIED IDEOGRAPH
+0x8A5C 0x596C #CJK UNIFIED IDEOGRAPH
+0x8A5D 0x596D #CJK UNIFIED IDEOGRAPH
+0x8A5E 0x596E #CJK UNIFIED IDEOGRAPH
+0x8A5F 0x596F #CJK UNIFIED IDEOGRAPH
+0x8A60 0x5970 #CJK UNIFIED IDEOGRAPH
+0x8A61 0x5971 #CJK UNIFIED IDEOGRAPH
+0x8A62 0x5972 #CJK UNIFIED IDEOGRAPH
+0x8A63 0x5975 #CJK UNIFIED IDEOGRAPH
+0x8A64 0x5977 #CJK UNIFIED IDEOGRAPH
+0x8A65 0x597A #CJK UNIFIED IDEOGRAPH
+0x8A66 0x597B #CJK UNIFIED IDEOGRAPH
+0x8A67 0x597C #CJK UNIFIED IDEOGRAPH
+0x8A68 0x597E #CJK UNIFIED IDEOGRAPH
+0x8A69 0x597F #CJK UNIFIED IDEOGRAPH
+0x8A6A 0x5980 #CJK UNIFIED IDEOGRAPH
+0x8A6B 0x5985 #CJK UNIFIED IDEOGRAPH
+0x8A6C 0x5989 #CJK UNIFIED IDEOGRAPH
+0x8A6D 0x598B #CJK UNIFIED IDEOGRAPH
+0x8A6E 0x598C #CJK UNIFIED IDEOGRAPH
+0x8A6F 0x598E #CJK UNIFIED IDEOGRAPH
+0x8A70 0x598F #CJK UNIFIED IDEOGRAPH
+0x8A71 0x5990 #CJK UNIFIED IDEOGRAPH
+0x8A72 0x5991 #CJK UNIFIED IDEOGRAPH
+0x8A73 0x5994 #CJK UNIFIED IDEOGRAPH
+0x8A74 0x5995 #CJK UNIFIED IDEOGRAPH
+0x8A75 0x5998 #CJK UNIFIED IDEOGRAPH
+0x8A76 0x599A #CJK UNIFIED IDEOGRAPH
+0x8A77 0x599B #CJK UNIFIED IDEOGRAPH
+0x8A78 0x599C #CJK UNIFIED IDEOGRAPH
+0x8A79 0x599D #CJK UNIFIED IDEOGRAPH
+0x8A7A 0x599F #CJK UNIFIED IDEOGRAPH
+0x8A7B 0x59A0 #CJK UNIFIED IDEOGRAPH
+0x8A7C 0x59A1 #CJK UNIFIED IDEOGRAPH
+0x8A7D 0x59A2 #CJK UNIFIED IDEOGRAPH
+0x8A7E 0x59A6 #CJK UNIFIED IDEOGRAPH
+0x8A80 0x59A7 #CJK UNIFIED IDEOGRAPH
+0x8A81 0x59AC #CJK UNIFIED IDEOGRAPH
+0x8A82 0x59AD #CJK UNIFIED IDEOGRAPH
+0x8A83 0x59B0 #CJK UNIFIED IDEOGRAPH
+0x8A84 0x59B1 #CJK UNIFIED IDEOGRAPH
+0x8A85 0x59B3 #CJK UNIFIED IDEOGRAPH
+0x8A86 0x59B4 #CJK UNIFIED IDEOGRAPH
+0x8A87 0x59B5 #CJK UNIFIED IDEOGRAPH
+0x8A88 0x59B6 #CJK UNIFIED IDEOGRAPH
+0x8A89 0x59B7 #CJK UNIFIED IDEOGRAPH
+0x8A8A 0x59B8 #CJK UNIFIED IDEOGRAPH
+0x8A8B 0x59BA #CJK UNIFIED IDEOGRAPH
+0x8A8C 0x59BC #CJK UNIFIED IDEOGRAPH
+0x8A8D 0x59BD #CJK UNIFIED IDEOGRAPH
+0x8A8E 0x59BF #CJK UNIFIED IDEOGRAPH
+0x8A8F 0x59C0 #CJK UNIFIED IDEOGRAPH
+0x8A90 0x59C1 #CJK UNIFIED IDEOGRAPH
+0x8A91 0x59C2 #CJK UNIFIED IDEOGRAPH
+0x8A92 0x59C3 #CJK UNIFIED IDEOGRAPH
+0x8A93 0x59C4 #CJK UNIFIED IDEOGRAPH
+0x8A94 0x59C5 #CJK UNIFIED IDEOGRAPH
+0x8A95 0x59C7 #CJK UNIFIED IDEOGRAPH
+0x8A96 0x59C8 #CJK UNIFIED IDEOGRAPH
+0x8A97 0x59C9 #CJK UNIFIED IDEOGRAPH
+0x8A98 0x59CC #CJK UNIFIED IDEOGRAPH
+0x8A99 0x59CD #CJK UNIFIED IDEOGRAPH
+0x8A9A 0x59CE #CJK UNIFIED IDEOGRAPH
+0x8A9B 0x59CF #CJK UNIFIED IDEOGRAPH
+0x8A9C 0x59D5 #CJK UNIFIED IDEOGRAPH
+0x8A9D 0x59D6 #CJK UNIFIED IDEOGRAPH
+0x8A9E 0x59D9 #CJK UNIFIED IDEOGRAPH
+0x8A9F 0x59DB #CJK UNIFIED IDEOGRAPH
+0x8AA0 0x59DE #CJK UNIFIED IDEOGRAPH
+0x8AA1 0x59DF #CJK UNIFIED IDEOGRAPH
+0x8AA2 0x59E0 #CJK UNIFIED IDEOGRAPH
+0x8AA3 0x59E1 #CJK UNIFIED IDEOGRAPH
+0x8AA4 0x59E2 #CJK UNIFIED IDEOGRAPH
+0x8AA5 0x59E4 #CJK UNIFIED IDEOGRAPH
+0x8AA6 0x59E6 #CJK UNIFIED IDEOGRAPH
+0x8AA7 0x59E7 #CJK UNIFIED IDEOGRAPH
+0x8AA8 0x59E9 #CJK UNIFIED IDEOGRAPH
+0x8AA9 0x59EA #CJK UNIFIED IDEOGRAPH
+0x8AAA 0x59EB #CJK UNIFIED IDEOGRAPH
+0x8AAB 0x59ED #CJK UNIFIED IDEOGRAPH
+0x8AAC 0x59EE #CJK UNIFIED IDEOGRAPH
+0x8AAD 0x59EF #CJK UNIFIED IDEOGRAPH
+0x8AAE 0x59F0 #CJK UNIFIED IDEOGRAPH
+0x8AAF 0x59F1 #CJK UNIFIED IDEOGRAPH
+0x8AB0 0x59F2 #CJK UNIFIED IDEOGRAPH
+0x8AB1 0x59F3 #CJK UNIFIED IDEOGRAPH
+0x8AB2 0x59F4 #CJK UNIFIED IDEOGRAPH
+0x8AB3 0x59F5 #CJK UNIFIED IDEOGRAPH
+0x8AB4 0x59F6 #CJK UNIFIED IDEOGRAPH
+0x8AB5 0x59F7 #CJK UNIFIED IDEOGRAPH
+0x8AB6 0x59F8 #CJK UNIFIED IDEOGRAPH
+0x8AB7 0x59FA #CJK UNIFIED IDEOGRAPH
+0x8AB8 0x59FC #CJK UNIFIED IDEOGRAPH
+0x8AB9 0x59FD #CJK UNIFIED IDEOGRAPH
+0x8ABA 0x59FE #CJK UNIFIED IDEOGRAPH
+0x8ABB 0x5A00 #CJK UNIFIED IDEOGRAPH
+0x8ABC 0x5A02 #CJK UNIFIED IDEOGRAPH
+0x8ABD 0x5A0A #CJK UNIFIED IDEOGRAPH
+0x8ABE 0x5A0B #CJK UNIFIED IDEOGRAPH
+0x8ABF 0x5A0D #CJK UNIFIED IDEOGRAPH
+0x8AC0 0x5A0E #CJK UNIFIED IDEOGRAPH
+0x8AC1 0x5A0F #CJK UNIFIED IDEOGRAPH
+0x8AC2 0x5A10 #CJK UNIFIED IDEOGRAPH
+0x8AC3 0x5A12 #CJK UNIFIED IDEOGRAPH
+0x8AC4 0x5A14 #CJK UNIFIED IDEOGRAPH
+0x8AC5 0x5A15 #CJK UNIFIED IDEOGRAPH
+0x8AC6 0x5A16 #CJK UNIFIED IDEOGRAPH
+0x8AC7 0x5A17 #CJK UNIFIED IDEOGRAPH
+0x8AC8 0x5A19 #CJK UNIFIED IDEOGRAPH
+0x8AC9 0x5A1A #CJK UNIFIED IDEOGRAPH
+0x8ACA 0x5A1B #CJK UNIFIED IDEOGRAPH
+0x8ACB 0x5A1D #CJK UNIFIED IDEOGRAPH
+0x8ACC 0x5A1E #CJK UNIFIED IDEOGRAPH
+0x8ACD 0x5A21 #CJK UNIFIED IDEOGRAPH
+0x8ACE 0x5A22 #CJK UNIFIED IDEOGRAPH
+0x8ACF 0x5A24 #CJK UNIFIED IDEOGRAPH
+0x8AD0 0x5A26 #CJK UNIFIED IDEOGRAPH
+0x8AD1 0x5A27 #CJK UNIFIED IDEOGRAPH
+0x8AD2 0x5A28 #CJK UNIFIED IDEOGRAPH
+0x8AD3 0x5A2A #CJK UNIFIED IDEOGRAPH
+0x8AD4 0x5A2B #CJK UNIFIED IDEOGRAPH
+0x8AD5 0x5A2C #CJK UNIFIED IDEOGRAPH
+0x8AD6 0x5A2D #CJK UNIFIED IDEOGRAPH
+0x8AD7 0x5A2E #CJK UNIFIED IDEOGRAPH
+0x8AD8 0x5A2F #CJK UNIFIED IDEOGRAPH
+0x8AD9 0x5A30 #CJK UNIFIED IDEOGRAPH
+0x8ADA 0x5A33 #CJK UNIFIED IDEOGRAPH
+0x8ADB 0x5A35 #CJK UNIFIED IDEOGRAPH
+0x8ADC 0x5A37 #CJK UNIFIED IDEOGRAPH
+0x8ADD 0x5A38 #CJK UNIFIED IDEOGRAPH
+0x8ADE 0x5A39 #CJK UNIFIED IDEOGRAPH
+0x8ADF 0x5A3A #CJK UNIFIED IDEOGRAPH
+0x8AE0 0x5A3B #CJK UNIFIED IDEOGRAPH
+0x8AE1 0x5A3D #CJK UNIFIED IDEOGRAPH
+0x8AE2 0x5A3E #CJK UNIFIED IDEOGRAPH
+0x8AE3 0x5A3F #CJK UNIFIED IDEOGRAPH
+0x8AE4 0x5A41 #CJK UNIFIED IDEOGRAPH
+0x8AE5 0x5A42 #CJK UNIFIED IDEOGRAPH
+0x8AE6 0x5A43 #CJK UNIFIED IDEOGRAPH
+0x8AE7 0x5A44 #CJK UNIFIED IDEOGRAPH
+0x8AE8 0x5A45 #CJK UNIFIED IDEOGRAPH
+0x8AE9 0x5A47 #CJK UNIFIED IDEOGRAPH
+0x8AEA 0x5A48 #CJK UNIFIED IDEOGRAPH
+0x8AEB 0x5A4B #CJK UNIFIED IDEOGRAPH
+0x8AEC 0x5A4C #CJK UNIFIED IDEOGRAPH
+0x8AED 0x5A4D #CJK UNIFIED IDEOGRAPH
+0x8AEE 0x5A4E #CJK UNIFIED IDEOGRAPH
+0x8AEF 0x5A4F #CJK UNIFIED IDEOGRAPH
+0x8AF0 0x5A50 #CJK UNIFIED IDEOGRAPH
+0x8AF1 0x5A51 #CJK UNIFIED IDEOGRAPH
+0x8AF2 0x5A52 #CJK UNIFIED IDEOGRAPH
+0x8AF3 0x5A53 #CJK UNIFIED IDEOGRAPH
+0x8AF4 0x5A54 #CJK UNIFIED IDEOGRAPH
+0x8AF5 0x5A56 #CJK UNIFIED IDEOGRAPH
+0x8AF6 0x5A57 #CJK UNIFIED IDEOGRAPH
+0x8AF7 0x5A58 #CJK UNIFIED IDEOGRAPH
+0x8AF8 0x5A59 #CJK UNIFIED IDEOGRAPH
+0x8AF9 0x5A5B #CJK UNIFIED IDEOGRAPH
+0x8AFA 0x5A5C #CJK UNIFIED IDEOGRAPH
+0x8AFB 0x5A5D #CJK UNIFIED IDEOGRAPH
+0x8AFC 0x5A5E #CJK UNIFIED IDEOGRAPH
+0x8AFD 0x5A5F #CJK UNIFIED IDEOGRAPH
+0x8AFE 0x5A60 #CJK UNIFIED IDEOGRAPH
+0x8B40 0x5A61 #CJK UNIFIED IDEOGRAPH
+0x8B41 0x5A63 #CJK UNIFIED IDEOGRAPH
+0x8B42 0x5A64 #CJK UNIFIED IDEOGRAPH
+0x8B43 0x5A65 #CJK UNIFIED IDEOGRAPH
+0x8B44 0x5A66 #CJK UNIFIED IDEOGRAPH
+0x8B45 0x5A68 #CJK UNIFIED IDEOGRAPH
+0x8B46 0x5A69 #CJK UNIFIED IDEOGRAPH
+0x8B47 0x5A6B #CJK UNIFIED IDEOGRAPH
+0x8B48 0x5A6C #CJK UNIFIED IDEOGRAPH
+0x8B49 0x5A6D #CJK UNIFIED IDEOGRAPH
+0x8B4A 0x5A6E #CJK UNIFIED IDEOGRAPH
+0x8B4B 0x5A6F #CJK UNIFIED IDEOGRAPH
+0x8B4C 0x5A70 #CJK UNIFIED IDEOGRAPH
+0x8B4D 0x5A71 #CJK UNIFIED IDEOGRAPH
+0x8B4E 0x5A72 #CJK UNIFIED IDEOGRAPH
+0x8B4F 0x5A73 #CJK UNIFIED IDEOGRAPH
+0x8B50 0x5A78 #CJK UNIFIED IDEOGRAPH
+0x8B51 0x5A79 #CJK UNIFIED IDEOGRAPH
+0x8B52 0x5A7B #CJK UNIFIED IDEOGRAPH
+0x8B53 0x5A7C #CJK UNIFIED IDEOGRAPH
+0x8B54 0x5A7D #CJK UNIFIED IDEOGRAPH
+0x8B55 0x5A7E #CJK UNIFIED IDEOGRAPH
+0x8B56 0x5A80 #CJK UNIFIED IDEOGRAPH
+0x8B57 0x5A81 #CJK UNIFIED IDEOGRAPH
+0x8B58 0x5A82 #CJK UNIFIED IDEOGRAPH
+0x8B59 0x5A83 #CJK UNIFIED IDEOGRAPH
+0x8B5A 0x5A84 #CJK UNIFIED IDEOGRAPH
+0x8B5B 0x5A85 #CJK UNIFIED IDEOGRAPH
+0x8B5C 0x5A86 #CJK UNIFIED IDEOGRAPH
+0x8B5D 0x5A87 #CJK UNIFIED IDEOGRAPH
+0x8B5E 0x5A88 #CJK UNIFIED IDEOGRAPH
+0x8B5F 0x5A89 #CJK UNIFIED IDEOGRAPH
+0x8B60 0x5A8A #CJK UNIFIED IDEOGRAPH
+0x8B61 0x5A8B #CJK UNIFIED IDEOGRAPH
+0x8B62 0x5A8C #CJK UNIFIED IDEOGRAPH
+0x8B63 0x5A8D #CJK UNIFIED IDEOGRAPH
+0x8B64 0x5A8E #CJK UNIFIED IDEOGRAPH
+0x8B65 0x5A8F #CJK UNIFIED IDEOGRAPH
+0x8B66 0x5A90 #CJK UNIFIED IDEOGRAPH
+0x8B67 0x5A91 #CJK UNIFIED IDEOGRAPH
+0x8B68 0x5A93 #CJK UNIFIED IDEOGRAPH
+0x8B69 0x5A94 #CJK UNIFIED IDEOGRAPH
+0x8B6A 0x5A95 #CJK UNIFIED IDEOGRAPH
+0x8B6B 0x5A96 #CJK UNIFIED IDEOGRAPH
+0x8B6C 0x5A97 #CJK UNIFIED IDEOGRAPH
+0x8B6D 0x5A98 #CJK UNIFIED IDEOGRAPH
+0x8B6E 0x5A99 #CJK UNIFIED IDEOGRAPH
+0x8B6F 0x5A9C #CJK UNIFIED IDEOGRAPH
+0x8B70 0x5A9D #CJK UNIFIED IDEOGRAPH
+0x8B71 0x5A9E #CJK UNIFIED IDEOGRAPH
+0x8B72 0x5A9F #CJK UNIFIED IDEOGRAPH
+0x8B73 0x5AA0 #CJK UNIFIED IDEOGRAPH
+0x8B74 0x5AA1 #CJK UNIFIED IDEOGRAPH
+0x8B75 0x5AA2 #CJK UNIFIED IDEOGRAPH
+0x8B76 0x5AA3 #CJK UNIFIED IDEOGRAPH
+0x8B77 0x5AA4 #CJK UNIFIED IDEOGRAPH
+0x8B78 0x5AA5 #CJK UNIFIED IDEOGRAPH
+0x8B79 0x5AA6 #CJK UNIFIED IDEOGRAPH
+0x8B7A 0x5AA7 #CJK UNIFIED IDEOGRAPH
+0x8B7B 0x5AA8 #CJK UNIFIED IDEOGRAPH
+0x8B7C 0x5AA9 #CJK UNIFIED IDEOGRAPH
+0x8B7D 0x5AAB #CJK UNIFIED IDEOGRAPH
+0x8B7E 0x5AAC #CJK UNIFIED IDEOGRAPH
+0x8B80 0x5AAD #CJK UNIFIED IDEOGRAPH
+0x8B81 0x5AAE #CJK UNIFIED IDEOGRAPH
+0x8B82 0x5AAF #CJK UNIFIED IDEOGRAPH
+0x8B83 0x5AB0 #CJK UNIFIED IDEOGRAPH
+0x8B84 0x5AB1 #CJK UNIFIED IDEOGRAPH
+0x8B85 0x5AB4 #CJK UNIFIED IDEOGRAPH
+0x8B86 0x5AB6 #CJK UNIFIED IDEOGRAPH
+0x8B87 0x5AB7 #CJK UNIFIED IDEOGRAPH
+0x8B88 0x5AB9 #CJK UNIFIED IDEOGRAPH
+0x8B89 0x5ABA #CJK UNIFIED IDEOGRAPH
+0x8B8A 0x5ABB #CJK UNIFIED IDEOGRAPH
+0x8B8B 0x5ABC #CJK UNIFIED IDEOGRAPH
+0x8B8C 0x5ABD #CJK UNIFIED IDEOGRAPH
+0x8B8D 0x5ABF #CJK UNIFIED IDEOGRAPH
+0x8B8E 0x5AC0 #CJK UNIFIED IDEOGRAPH
+0x8B8F 0x5AC3 #CJK UNIFIED IDEOGRAPH
+0x8B90 0x5AC4 #CJK UNIFIED IDEOGRAPH
+0x8B91 0x5AC5 #CJK UNIFIED IDEOGRAPH
+0x8B92 0x5AC6 #CJK UNIFIED IDEOGRAPH
+0x8B93 0x5AC7 #CJK UNIFIED IDEOGRAPH
+0x8B94 0x5AC8 #CJK UNIFIED IDEOGRAPH
+0x8B95 0x5ACA #CJK UNIFIED IDEOGRAPH
+0x8B96 0x5ACB #CJK UNIFIED IDEOGRAPH
+0x8B97 0x5ACD #CJK UNIFIED IDEOGRAPH
+0x8B98 0x5ACE #CJK UNIFIED IDEOGRAPH
+0x8B99 0x5ACF #CJK UNIFIED IDEOGRAPH
+0x8B9A 0x5AD0 #CJK UNIFIED IDEOGRAPH
+0x8B9B 0x5AD1 #CJK UNIFIED IDEOGRAPH
+0x8B9C 0x5AD3 #CJK UNIFIED IDEOGRAPH
+0x8B9D 0x5AD5 #CJK UNIFIED IDEOGRAPH
+0x8B9E 0x5AD7 #CJK UNIFIED IDEOGRAPH
+0x8B9F 0x5AD9 #CJK UNIFIED IDEOGRAPH
+0x8BA0 0x5ADA #CJK UNIFIED IDEOGRAPH
+0x8BA1 0x5ADB #CJK UNIFIED IDEOGRAPH
+0x8BA2 0x5ADD #CJK UNIFIED IDEOGRAPH
+0x8BA3 0x5ADE #CJK UNIFIED IDEOGRAPH
+0x8BA4 0x5ADF #CJK UNIFIED IDEOGRAPH
+0x8BA5 0x5AE2 #CJK UNIFIED IDEOGRAPH
+0x8BA6 0x5AE4 #CJK UNIFIED IDEOGRAPH
+0x8BA7 0x5AE5 #CJK UNIFIED IDEOGRAPH
+0x8BA8 0x5AE7 #CJK UNIFIED IDEOGRAPH
+0x8BA9 0x5AE8 #CJK UNIFIED IDEOGRAPH
+0x8BAA 0x5AEA #CJK UNIFIED IDEOGRAPH
+0x8BAB 0x5AEC #CJK UNIFIED IDEOGRAPH
+0x8BAC 0x5AED #CJK UNIFIED IDEOGRAPH
+0x8BAD 0x5AEE #CJK UNIFIED IDEOGRAPH
+0x8BAE 0x5AEF #CJK UNIFIED IDEOGRAPH
+0x8BAF 0x5AF0 #CJK UNIFIED IDEOGRAPH
+0x8BB0 0x5AF2 #CJK UNIFIED IDEOGRAPH
+0x8BB1 0x5AF3 #CJK UNIFIED IDEOGRAPH
+0x8BB2 0x5AF4 #CJK UNIFIED IDEOGRAPH
+0x8BB3 0x5AF5 #CJK UNIFIED IDEOGRAPH
+0x8BB4 0x5AF6 #CJK UNIFIED IDEOGRAPH
+0x8BB5 0x5AF7 #CJK UNIFIED IDEOGRAPH
+0x8BB6 0x5AF8 #CJK UNIFIED IDEOGRAPH
+0x8BB7 0x5AF9 #CJK UNIFIED IDEOGRAPH
+0x8BB8 0x5AFA #CJK UNIFIED IDEOGRAPH
+0x8BB9 0x5AFB #CJK UNIFIED IDEOGRAPH
+0x8BBA 0x5AFC #CJK UNIFIED IDEOGRAPH
+0x8BBB 0x5AFD #CJK UNIFIED IDEOGRAPH
+0x8BBC 0x5AFE #CJK UNIFIED IDEOGRAPH
+0x8BBD 0x5AFF #CJK UNIFIED IDEOGRAPH
+0x8BBE 0x5B00 #CJK UNIFIED IDEOGRAPH
+0x8BBF 0x5B01 #CJK UNIFIED IDEOGRAPH
+0x8BC0 0x5B02 #CJK UNIFIED IDEOGRAPH
+0x8BC1 0x5B03 #CJK UNIFIED IDEOGRAPH
+0x8BC2 0x5B04 #CJK UNIFIED IDEOGRAPH
+0x8BC3 0x5B05 #CJK UNIFIED IDEOGRAPH
+0x8BC4 0x5B06 #CJK UNIFIED IDEOGRAPH
+0x8BC5 0x5B07 #CJK UNIFIED IDEOGRAPH
+0x8BC6 0x5B08 #CJK UNIFIED IDEOGRAPH
+0x8BC7 0x5B0A #CJK UNIFIED IDEOGRAPH
+0x8BC8 0x5B0B #CJK UNIFIED IDEOGRAPH
+0x8BC9 0x5B0C #CJK UNIFIED IDEOGRAPH
+0x8BCA 0x5B0D #CJK UNIFIED IDEOGRAPH
+0x8BCB 0x5B0E #CJK UNIFIED IDEOGRAPH
+0x8BCC 0x5B0F #CJK UNIFIED IDEOGRAPH
+0x8BCD 0x5B10 #CJK UNIFIED IDEOGRAPH
+0x8BCE 0x5B11 #CJK UNIFIED IDEOGRAPH
+0x8BCF 0x5B12 #CJK UNIFIED IDEOGRAPH
+0x8BD0 0x5B13 #CJK UNIFIED IDEOGRAPH
+0x8BD1 0x5B14 #CJK UNIFIED IDEOGRAPH
+0x8BD2 0x5B15 #CJK UNIFIED IDEOGRAPH
+0x8BD3 0x5B18 #CJK UNIFIED IDEOGRAPH
+0x8BD4 0x5B19 #CJK UNIFIED IDEOGRAPH
+0x8BD5 0x5B1A #CJK UNIFIED IDEOGRAPH
+0x8BD6 0x5B1B #CJK UNIFIED IDEOGRAPH
+0x8BD7 0x5B1C #CJK UNIFIED IDEOGRAPH
+0x8BD8 0x5B1D #CJK UNIFIED IDEOGRAPH
+0x8BD9 0x5B1E #CJK UNIFIED IDEOGRAPH
+0x8BDA 0x5B1F #CJK UNIFIED IDEOGRAPH
+0x8BDB 0x5B20 #CJK UNIFIED IDEOGRAPH
+0x8BDC 0x5B21 #CJK UNIFIED IDEOGRAPH
+0x8BDD 0x5B22 #CJK UNIFIED IDEOGRAPH
+0x8BDE 0x5B23 #CJK UNIFIED IDEOGRAPH
+0x8BDF 0x5B24 #CJK UNIFIED IDEOGRAPH
+0x8BE0 0x5B25 #CJK UNIFIED IDEOGRAPH
+0x8BE1 0x5B26 #CJK UNIFIED IDEOGRAPH
+0x8BE2 0x5B27 #CJK UNIFIED IDEOGRAPH
+0x8BE3 0x5B28 #CJK UNIFIED IDEOGRAPH
+0x8BE4 0x5B29 #CJK UNIFIED IDEOGRAPH
+0x8BE5 0x5B2A #CJK UNIFIED IDEOGRAPH
+0x8BE6 0x5B2B #CJK UNIFIED IDEOGRAPH
+0x8BE7 0x5B2C #CJK UNIFIED IDEOGRAPH
+0x8BE8 0x5B2D #CJK UNIFIED IDEOGRAPH
+0x8BE9 0x5B2E #CJK UNIFIED IDEOGRAPH
+0x8BEA 0x5B2F #CJK UNIFIED IDEOGRAPH
+0x8BEB 0x5B30 #CJK UNIFIED IDEOGRAPH
+0x8BEC 0x5B31 #CJK UNIFIED IDEOGRAPH
+0x8BED 0x5B33 #CJK UNIFIED IDEOGRAPH
+0x8BEE 0x5B35 #CJK UNIFIED IDEOGRAPH
+0x8BEF 0x5B36 #CJK UNIFIED IDEOGRAPH
+0x8BF0 0x5B38 #CJK UNIFIED IDEOGRAPH
+0x8BF1 0x5B39 #CJK UNIFIED IDEOGRAPH
+0x8BF2 0x5B3A #CJK UNIFIED IDEOGRAPH
+0x8BF3 0x5B3B #CJK UNIFIED IDEOGRAPH
+0x8BF4 0x5B3C #CJK UNIFIED IDEOGRAPH
+0x8BF5 0x5B3D #CJK UNIFIED IDEOGRAPH
+0x8BF6 0x5B3E #CJK UNIFIED IDEOGRAPH
+0x8BF7 0x5B3F #CJK UNIFIED IDEOGRAPH
+0x8BF8 0x5B41 #CJK UNIFIED IDEOGRAPH
+0x8BF9 0x5B42 #CJK UNIFIED IDEOGRAPH
+0x8BFA 0x5B43 #CJK UNIFIED IDEOGRAPH
+0x8BFB 0x5B44 #CJK UNIFIED IDEOGRAPH
+0x8BFC 0x5B45 #CJK UNIFIED IDEOGRAPH
+0x8BFD 0x5B46 #CJK UNIFIED IDEOGRAPH
+0x8BFE 0x5B47 #CJK UNIFIED IDEOGRAPH
+0x8C40 0x5B48 #CJK UNIFIED IDEOGRAPH
+0x8C41 0x5B49 #CJK UNIFIED IDEOGRAPH
+0x8C42 0x5B4A #CJK UNIFIED IDEOGRAPH
+0x8C43 0x5B4B #CJK UNIFIED IDEOGRAPH
+0x8C44 0x5B4C #CJK UNIFIED IDEOGRAPH
+0x8C45 0x5B4D #CJK UNIFIED IDEOGRAPH
+0x8C46 0x5B4E #CJK UNIFIED IDEOGRAPH
+0x8C47 0x5B4F #CJK UNIFIED IDEOGRAPH
+0x8C48 0x5B52 #CJK UNIFIED IDEOGRAPH
+0x8C49 0x5B56 #CJK UNIFIED IDEOGRAPH
+0x8C4A 0x5B5E #CJK UNIFIED IDEOGRAPH
+0x8C4B 0x5B60 #CJK UNIFIED IDEOGRAPH
+0x8C4C 0x5B61 #CJK UNIFIED IDEOGRAPH
+0x8C4D 0x5B67 #CJK UNIFIED IDEOGRAPH
+0x8C4E 0x5B68 #CJK UNIFIED IDEOGRAPH
+0x8C4F 0x5B6B #CJK UNIFIED IDEOGRAPH
+0x8C50 0x5B6D #CJK UNIFIED IDEOGRAPH
+0x8C51 0x5B6E #CJK UNIFIED IDEOGRAPH
+0x8C52 0x5B6F #CJK UNIFIED IDEOGRAPH
+0x8C53 0x5B72 #CJK UNIFIED IDEOGRAPH
+0x8C54 0x5B74 #CJK UNIFIED IDEOGRAPH
+0x8C55 0x5B76 #CJK UNIFIED IDEOGRAPH
+0x8C56 0x5B77 #CJK UNIFIED IDEOGRAPH
+0x8C57 0x5B78 #CJK UNIFIED IDEOGRAPH
+0x8C58 0x5B79 #CJK UNIFIED IDEOGRAPH
+0x8C59 0x5B7B #CJK UNIFIED IDEOGRAPH
+0x8C5A 0x5B7C #CJK UNIFIED IDEOGRAPH
+0x8C5B 0x5B7E #CJK UNIFIED IDEOGRAPH
+0x8C5C 0x5B7F #CJK UNIFIED IDEOGRAPH
+0x8C5D 0x5B82 #CJK UNIFIED IDEOGRAPH
+0x8C5E 0x5B86 #CJK UNIFIED IDEOGRAPH
+0x8C5F 0x5B8A #CJK UNIFIED IDEOGRAPH
+0x8C60 0x5B8D #CJK UNIFIED IDEOGRAPH
+0x8C61 0x5B8E #CJK UNIFIED IDEOGRAPH
+0x8C62 0x5B90 #CJK UNIFIED IDEOGRAPH
+0x8C63 0x5B91 #CJK UNIFIED IDEOGRAPH
+0x8C64 0x5B92 #CJK UNIFIED IDEOGRAPH
+0x8C65 0x5B94 #CJK UNIFIED IDEOGRAPH
+0x8C66 0x5B96 #CJK UNIFIED IDEOGRAPH
+0x8C67 0x5B9F #CJK UNIFIED IDEOGRAPH
+0x8C68 0x5BA7 #CJK UNIFIED IDEOGRAPH
+0x8C69 0x5BA8 #CJK UNIFIED IDEOGRAPH
+0x8C6A 0x5BA9 #CJK UNIFIED IDEOGRAPH
+0x8C6B 0x5BAC #CJK UNIFIED IDEOGRAPH
+0x8C6C 0x5BAD #CJK UNIFIED IDEOGRAPH
+0x8C6D 0x5BAE #CJK UNIFIED IDEOGRAPH
+0x8C6E 0x5BAF #CJK UNIFIED IDEOGRAPH
+0x8C6F 0x5BB1 #CJK UNIFIED IDEOGRAPH
+0x8C70 0x5BB2 #CJK UNIFIED IDEOGRAPH
+0x8C71 0x5BB7 #CJK UNIFIED IDEOGRAPH
+0x8C72 0x5BBA #CJK UNIFIED IDEOGRAPH
+0x8C73 0x5BBB #CJK UNIFIED IDEOGRAPH
+0x8C74 0x5BBC #CJK UNIFIED IDEOGRAPH
+0x8C75 0x5BC0 #CJK UNIFIED IDEOGRAPH
+0x8C76 0x5BC1 #CJK UNIFIED IDEOGRAPH
+0x8C77 0x5BC3 #CJK UNIFIED IDEOGRAPH
+0x8C78 0x5BC8 #CJK UNIFIED IDEOGRAPH
+0x8C79 0x5BC9 #CJK UNIFIED IDEOGRAPH
+0x8C7A 0x5BCA #CJK UNIFIED IDEOGRAPH
+0x8C7B 0x5BCB #CJK UNIFIED IDEOGRAPH
+0x8C7C 0x5BCD #CJK UNIFIED IDEOGRAPH
+0x8C7D 0x5BCE #CJK UNIFIED IDEOGRAPH
+0x8C7E 0x5BCF #CJK UNIFIED IDEOGRAPH
+0x8C80 0x5BD1 #CJK UNIFIED IDEOGRAPH
+0x8C81 0x5BD4 #CJK UNIFIED IDEOGRAPH
+0x8C82 0x5BD5 #CJK UNIFIED IDEOGRAPH
+0x8C83 0x5BD6 #CJK UNIFIED IDEOGRAPH
+0x8C84 0x5BD7 #CJK UNIFIED IDEOGRAPH
+0x8C85 0x5BD8 #CJK UNIFIED IDEOGRAPH
+0x8C86 0x5BD9 #CJK UNIFIED IDEOGRAPH
+0x8C87 0x5BDA #CJK UNIFIED IDEOGRAPH
+0x8C88 0x5BDB #CJK UNIFIED IDEOGRAPH
+0x8C89 0x5BDC #CJK UNIFIED IDEOGRAPH
+0x8C8A 0x5BE0 #CJK UNIFIED IDEOGRAPH
+0x8C8B 0x5BE2 #CJK UNIFIED IDEOGRAPH
+0x8C8C 0x5BE3 #CJK UNIFIED IDEOGRAPH
+0x8C8D 0x5BE6 #CJK UNIFIED IDEOGRAPH
+0x8C8E 0x5BE7 #CJK UNIFIED IDEOGRAPH
+0x8C8F 0x5BE9 #CJK UNIFIED IDEOGRAPH
+0x8C90 0x5BEA #CJK UNIFIED IDEOGRAPH
+0x8C91 0x5BEB #CJK UNIFIED IDEOGRAPH
+0x8C92 0x5BEC #CJK UNIFIED IDEOGRAPH
+0x8C93 0x5BED #CJK UNIFIED IDEOGRAPH
+0x8C94 0x5BEF #CJK UNIFIED IDEOGRAPH
+0x8C95 0x5BF1 #CJK UNIFIED IDEOGRAPH
+0x8C96 0x5BF2 #CJK UNIFIED IDEOGRAPH
+0x8C97 0x5BF3 #CJK UNIFIED IDEOGRAPH
+0x8C98 0x5BF4 #CJK UNIFIED IDEOGRAPH
+0x8C99 0x5BF5 #CJK UNIFIED IDEOGRAPH
+0x8C9A 0x5BF6 #CJK UNIFIED IDEOGRAPH
+0x8C9B 0x5BF7 #CJK UNIFIED IDEOGRAPH
+0x8C9C 0x5BFD #CJK UNIFIED IDEOGRAPH
+0x8C9D 0x5BFE #CJK UNIFIED IDEOGRAPH
+0x8C9E 0x5C00 #CJK UNIFIED IDEOGRAPH
+0x8C9F 0x5C02 #CJK UNIFIED IDEOGRAPH
+0x8CA0 0x5C03 #CJK UNIFIED IDEOGRAPH
+0x8CA1 0x5C05 #CJK UNIFIED IDEOGRAPH
+0x8CA2 0x5C07 #CJK UNIFIED IDEOGRAPH
+0x8CA3 0x5C08 #CJK UNIFIED IDEOGRAPH
+0x8CA4 0x5C0B #CJK UNIFIED IDEOGRAPH
+0x8CA5 0x5C0C #CJK UNIFIED IDEOGRAPH
+0x8CA6 0x5C0D #CJK UNIFIED IDEOGRAPH
+0x8CA7 0x5C0E #CJK UNIFIED IDEOGRAPH
+0x8CA8 0x5C10 #CJK UNIFIED IDEOGRAPH
+0x8CA9 0x5C12 #CJK UNIFIED IDEOGRAPH
+0x8CAA 0x5C13 #CJK UNIFIED IDEOGRAPH
+0x8CAB 0x5C17 #CJK UNIFIED IDEOGRAPH
+0x8CAC 0x5C19 #CJK UNIFIED IDEOGRAPH
+0x8CAD 0x5C1B #CJK UNIFIED IDEOGRAPH
+0x8CAE 0x5C1E #CJK UNIFIED IDEOGRAPH
+0x8CAF 0x5C1F #CJK UNIFIED IDEOGRAPH
+0x8CB0 0x5C20 #CJK UNIFIED IDEOGRAPH
+0x8CB1 0x5C21 #CJK UNIFIED IDEOGRAPH
+0x8CB2 0x5C23 #CJK UNIFIED IDEOGRAPH
+0x8CB3 0x5C26 #CJK UNIFIED IDEOGRAPH
+0x8CB4 0x5C28 #CJK UNIFIED IDEOGRAPH
+0x8CB5 0x5C29 #CJK UNIFIED IDEOGRAPH
+0x8CB6 0x5C2A #CJK UNIFIED IDEOGRAPH
+0x8CB7 0x5C2B #CJK UNIFIED IDEOGRAPH
+0x8CB8 0x5C2D #CJK UNIFIED IDEOGRAPH
+0x8CB9 0x5C2E #CJK UNIFIED IDEOGRAPH
+0x8CBA 0x5C2F #CJK UNIFIED IDEOGRAPH
+0x8CBB 0x5C30 #CJK UNIFIED IDEOGRAPH
+0x8CBC 0x5C32 #CJK UNIFIED IDEOGRAPH
+0x8CBD 0x5C33 #CJK UNIFIED IDEOGRAPH
+0x8CBE 0x5C35 #CJK UNIFIED IDEOGRAPH
+0x8CBF 0x5C36 #CJK UNIFIED IDEOGRAPH
+0x8CC0 0x5C37 #CJK UNIFIED IDEOGRAPH
+0x8CC1 0x5C43 #CJK UNIFIED IDEOGRAPH
+0x8CC2 0x5C44 #CJK UNIFIED IDEOGRAPH
+0x8CC3 0x5C46 #CJK UNIFIED IDEOGRAPH
+0x8CC4 0x5C47 #CJK UNIFIED IDEOGRAPH
+0x8CC5 0x5C4C #CJK UNIFIED IDEOGRAPH
+0x8CC6 0x5C4D #CJK UNIFIED IDEOGRAPH
+0x8CC7 0x5C52 #CJK UNIFIED IDEOGRAPH
+0x8CC8 0x5C53 #CJK UNIFIED IDEOGRAPH
+0x8CC9 0x5C54 #CJK UNIFIED IDEOGRAPH
+0x8CCA 0x5C56 #CJK UNIFIED IDEOGRAPH
+0x8CCB 0x5C57 #CJK UNIFIED IDEOGRAPH
+0x8CCC 0x5C58 #CJK UNIFIED IDEOGRAPH
+0x8CCD 0x5C5A #CJK UNIFIED IDEOGRAPH
+0x8CCE 0x5C5B #CJK UNIFIED IDEOGRAPH
+0x8CCF 0x5C5C #CJK UNIFIED IDEOGRAPH
+0x8CD0 0x5C5D #CJK UNIFIED IDEOGRAPH
+0x8CD1 0x5C5F #CJK UNIFIED IDEOGRAPH
+0x8CD2 0x5C62 #CJK UNIFIED IDEOGRAPH
+0x8CD3 0x5C64 #CJK UNIFIED IDEOGRAPH
+0x8CD4 0x5C67 #CJK UNIFIED IDEOGRAPH
+0x8CD5 0x5C68 #CJK UNIFIED IDEOGRAPH
+0x8CD6 0x5C69 #CJK UNIFIED IDEOGRAPH
+0x8CD7 0x5C6A #CJK UNIFIED IDEOGRAPH
+0x8CD8 0x5C6B #CJK UNIFIED IDEOGRAPH
+0x8CD9 0x5C6C #CJK UNIFIED IDEOGRAPH
+0x8CDA 0x5C6D #CJK UNIFIED IDEOGRAPH
+0x8CDB 0x5C70 #CJK UNIFIED IDEOGRAPH
+0x8CDC 0x5C72 #CJK UNIFIED IDEOGRAPH
+0x8CDD 0x5C73 #CJK UNIFIED IDEOGRAPH
+0x8CDE 0x5C74 #CJK UNIFIED IDEOGRAPH
+0x8CDF 0x5C75 #CJK UNIFIED IDEOGRAPH
+0x8CE0 0x5C76 #CJK UNIFIED IDEOGRAPH
+0x8CE1 0x5C77 #CJK UNIFIED IDEOGRAPH
+0x8CE2 0x5C78 #CJK UNIFIED IDEOGRAPH
+0x8CE3 0x5C7B #CJK UNIFIED IDEOGRAPH
+0x8CE4 0x5C7C #CJK UNIFIED IDEOGRAPH
+0x8CE5 0x5C7D #CJK UNIFIED IDEOGRAPH
+0x8CE6 0x5C7E #CJK UNIFIED IDEOGRAPH
+0x8CE7 0x5C80 #CJK UNIFIED IDEOGRAPH
+0x8CE8 0x5C83 #CJK UNIFIED IDEOGRAPH
+0x8CE9 0x5C84 #CJK UNIFIED IDEOGRAPH
+0x8CEA 0x5C85 #CJK UNIFIED IDEOGRAPH
+0x8CEB 0x5C86 #CJK UNIFIED IDEOGRAPH
+0x8CEC 0x5C87 #CJK UNIFIED IDEOGRAPH
+0x8CED 0x5C89 #CJK UNIFIED IDEOGRAPH
+0x8CEE 0x5C8A #CJK UNIFIED IDEOGRAPH
+0x8CEF 0x5C8B #CJK UNIFIED IDEOGRAPH
+0x8CF0 0x5C8E #CJK UNIFIED IDEOGRAPH
+0x8CF1 0x5C8F #CJK UNIFIED IDEOGRAPH
+0x8CF2 0x5C92 #CJK UNIFIED IDEOGRAPH
+0x8CF3 0x5C93 #CJK UNIFIED IDEOGRAPH
+0x8CF4 0x5C95 #CJK UNIFIED IDEOGRAPH
+0x8CF5 0x5C9D #CJK UNIFIED IDEOGRAPH
+0x8CF6 0x5C9E #CJK UNIFIED IDEOGRAPH
+0x8CF7 0x5C9F #CJK UNIFIED IDEOGRAPH
+0x8CF8 0x5CA0 #CJK UNIFIED IDEOGRAPH
+0x8CF9 0x5CA1 #CJK UNIFIED IDEOGRAPH
+0x8CFA 0x5CA4 #CJK UNIFIED IDEOGRAPH
+0x8CFB 0x5CA5 #CJK UNIFIED IDEOGRAPH
+0x8CFC 0x5CA6 #CJK UNIFIED IDEOGRAPH
+0x8CFD 0x5CA7 #CJK UNIFIED IDEOGRAPH
+0x8CFE 0x5CA8 #CJK UNIFIED IDEOGRAPH
+0x8D40 0x5CAA #CJK UNIFIED IDEOGRAPH
+0x8D41 0x5CAE #CJK UNIFIED IDEOGRAPH
+0x8D42 0x5CAF #CJK UNIFIED IDEOGRAPH
+0x8D43 0x5CB0 #CJK UNIFIED IDEOGRAPH
+0x8D44 0x5CB2 #CJK UNIFIED IDEOGRAPH
+0x8D45 0x5CB4 #CJK UNIFIED IDEOGRAPH
+0x8D46 0x5CB6 #CJK UNIFIED IDEOGRAPH
+0x8D47 0x5CB9 #CJK UNIFIED IDEOGRAPH
+0x8D48 0x5CBA #CJK UNIFIED IDEOGRAPH
+0x8D49 0x5CBB #CJK UNIFIED IDEOGRAPH
+0x8D4A 0x5CBC #CJK UNIFIED IDEOGRAPH
+0x8D4B 0x5CBE #CJK UNIFIED IDEOGRAPH
+0x8D4C 0x5CC0 #CJK UNIFIED IDEOGRAPH
+0x8D4D 0x5CC2 #CJK UNIFIED IDEOGRAPH
+0x8D4E 0x5CC3 #CJK UNIFIED IDEOGRAPH
+0x8D4F 0x5CC5 #CJK UNIFIED IDEOGRAPH
+0x8D50 0x5CC6 #CJK UNIFIED IDEOGRAPH
+0x8D51 0x5CC7 #CJK UNIFIED IDEOGRAPH
+0x8D52 0x5CC8 #CJK UNIFIED IDEOGRAPH
+0x8D53 0x5CC9 #CJK UNIFIED IDEOGRAPH
+0x8D54 0x5CCA #CJK UNIFIED IDEOGRAPH
+0x8D55 0x5CCC #CJK UNIFIED IDEOGRAPH
+0x8D56 0x5CCD #CJK UNIFIED IDEOGRAPH
+0x8D57 0x5CCE #CJK UNIFIED IDEOGRAPH
+0x8D58 0x5CCF #CJK UNIFIED IDEOGRAPH
+0x8D59 0x5CD0 #CJK UNIFIED IDEOGRAPH
+0x8D5A 0x5CD1 #CJK UNIFIED IDEOGRAPH
+0x8D5B 0x5CD3 #CJK UNIFIED IDEOGRAPH
+0x8D5C 0x5CD4 #CJK UNIFIED IDEOGRAPH
+0x8D5D 0x5CD5 #CJK UNIFIED IDEOGRAPH
+0x8D5E 0x5CD6 #CJK UNIFIED IDEOGRAPH
+0x8D5F 0x5CD7 #CJK UNIFIED IDEOGRAPH
+0x8D60 0x5CD8 #CJK UNIFIED IDEOGRAPH
+0x8D61 0x5CDA #CJK UNIFIED IDEOGRAPH
+0x8D62 0x5CDB #CJK UNIFIED IDEOGRAPH
+0x8D63 0x5CDC #CJK UNIFIED IDEOGRAPH
+0x8D64 0x5CDD #CJK UNIFIED IDEOGRAPH
+0x8D65 0x5CDE #CJK UNIFIED IDEOGRAPH
+0x8D66 0x5CDF #CJK UNIFIED IDEOGRAPH
+0x8D67 0x5CE0 #CJK UNIFIED IDEOGRAPH
+0x8D68 0x5CE2 #CJK UNIFIED IDEOGRAPH
+0x8D69 0x5CE3 #CJK UNIFIED IDEOGRAPH
+0x8D6A 0x5CE7 #CJK UNIFIED IDEOGRAPH
+0x8D6B 0x5CE9 #CJK UNIFIED IDEOGRAPH
+0x8D6C 0x5CEB #CJK UNIFIED IDEOGRAPH
+0x8D6D 0x5CEC #CJK UNIFIED IDEOGRAPH
+0x8D6E 0x5CEE #CJK UNIFIED IDEOGRAPH
+0x8D6F 0x5CEF #CJK UNIFIED IDEOGRAPH
+0x8D70 0x5CF1 #CJK UNIFIED IDEOGRAPH
+0x8D71 0x5CF2 #CJK UNIFIED IDEOGRAPH
+0x8D72 0x5CF3 #CJK UNIFIED IDEOGRAPH
+0x8D73 0x5CF4 #CJK UNIFIED IDEOGRAPH
+0x8D74 0x5CF5 #CJK UNIFIED IDEOGRAPH
+0x8D75 0x5CF6 #CJK UNIFIED IDEOGRAPH
+0x8D76 0x5CF7 #CJK UNIFIED IDEOGRAPH
+0x8D77 0x5CF8 #CJK UNIFIED IDEOGRAPH
+0x8D78 0x5CF9 #CJK UNIFIED IDEOGRAPH
+0x8D79 0x5CFA #CJK UNIFIED IDEOGRAPH
+0x8D7A 0x5CFC #CJK UNIFIED IDEOGRAPH
+0x8D7B 0x5CFD #CJK UNIFIED IDEOGRAPH
+0x8D7C 0x5CFE #CJK UNIFIED IDEOGRAPH
+0x8D7D 0x5CFF #CJK UNIFIED IDEOGRAPH
+0x8D7E 0x5D00 #CJK UNIFIED IDEOGRAPH
+0x8D80 0x5D01 #CJK UNIFIED IDEOGRAPH
+0x8D81 0x5D04 #CJK UNIFIED IDEOGRAPH
+0x8D82 0x5D05 #CJK UNIFIED IDEOGRAPH
+0x8D83 0x5D08 #CJK UNIFIED IDEOGRAPH
+0x8D84 0x5D09 #CJK UNIFIED IDEOGRAPH
+0x8D85 0x5D0A #CJK UNIFIED IDEOGRAPH
+0x8D86 0x5D0B #CJK UNIFIED IDEOGRAPH
+0x8D87 0x5D0C #CJK UNIFIED IDEOGRAPH
+0x8D88 0x5D0D #CJK UNIFIED IDEOGRAPH
+0x8D89 0x5D0F #CJK UNIFIED IDEOGRAPH
+0x8D8A 0x5D10 #CJK UNIFIED IDEOGRAPH
+0x8D8B 0x5D11 #CJK UNIFIED IDEOGRAPH
+0x8D8C 0x5D12 #CJK UNIFIED IDEOGRAPH
+0x8D8D 0x5D13 #CJK UNIFIED IDEOGRAPH
+0x8D8E 0x5D15 #CJK UNIFIED IDEOGRAPH
+0x8D8F 0x5D17 #CJK UNIFIED IDEOGRAPH
+0x8D90 0x5D18 #CJK UNIFIED IDEOGRAPH
+0x8D91 0x5D19 #CJK UNIFIED IDEOGRAPH
+0x8D92 0x5D1A #CJK UNIFIED IDEOGRAPH
+0x8D93 0x5D1C #CJK UNIFIED IDEOGRAPH
+0x8D94 0x5D1D #CJK UNIFIED IDEOGRAPH
+0x8D95 0x5D1F #CJK UNIFIED IDEOGRAPH
+0x8D96 0x5D20 #CJK UNIFIED IDEOGRAPH
+0x8D97 0x5D21 #CJK UNIFIED IDEOGRAPH
+0x8D98 0x5D22 #CJK UNIFIED IDEOGRAPH
+0x8D99 0x5D23 #CJK UNIFIED IDEOGRAPH
+0x8D9A 0x5D25 #CJK UNIFIED IDEOGRAPH
+0x8D9B 0x5D28 #CJK UNIFIED IDEOGRAPH
+0x8D9C 0x5D2A #CJK UNIFIED IDEOGRAPH
+0x8D9D 0x5D2B #CJK UNIFIED IDEOGRAPH
+0x8D9E 0x5D2C #CJK UNIFIED IDEOGRAPH
+0x8D9F 0x5D2F #CJK UNIFIED IDEOGRAPH
+0x8DA0 0x5D30 #CJK UNIFIED IDEOGRAPH
+0x8DA1 0x5D31 #CJK UNIFIED IDEOGRAPH
+0x8DA2 0x5D32 #CJK UNIFIED IDEOGRAPH
+0x8DA3 0x5D33 #CJK UNIFIED IDEOGRAPH
+0x8DA4 0x5D35 #CJK UNIFIED IDEOGRAPH
+0x8DA5 0x5D36 #CJK UNIFIED IDEOGRAPH
+0x8DA6 0x5D37 #CJK UNIFIED IDEOGRAPH
+0x8DA7 0x5D38 #CJK UNIFIED IDEOGRAPH
+0x8DA8 0x5D39 #CJK UNIFIED IDEOGRAPH
+0x8DA9 0x5D3A #CJK UNIFIED IDEOGRAPH
+0x8DAA 0x5D3B #CJK UNIFIED IDEOGRAPH
+0x8DAB 0x5D3C #CJK UNIFIED IDEOGRAPH
+0x8DAC 0x5D3F #CJK UNIFIED IDEOGRAPH
+0x8DAD 0x5D40 #CJK UNIFIED IDEOGRAPH
+0x8DAE 0x5D41 #CJK UNIFIED IDEOGRAPH
+0x8DAF 0x5D42 #CJK UNIFIED IDEOGRAPH
+0x8DB0 0x5D43 #CJK UNIFIED IDEOGRAPH
+0x8DB1 0x5D44 #CJK UNIFIED IDEOGRAPH
+0x8DB2 0x5D45 #CJK UNIFIED IDEOGRAPH
+0x8DB3 0x5D46 #CJK UNIFIED IDEOGRAPH
+0x8DB4 0x5D48 #CJK UNIFIED IDEOGRAPH
+0x8DB5 0x5D49 #CJK UNIFIED IDEOGRAPH
+0x8DB6 0x5D4D #CJK UNIFIED IDEOGRAPH
+0x8DB7 0x5D4E #CJK UNIFIED IDEOGRAPH
+0x8DB8 0x5D4F #CJK UNIFIED IDEOGRAPH
+0x8DB9 0x5D50 #CJK UNIFIED IDEOGRAPH
+0x8DBA 0x5D51 #CJK UNIFIED IDEOGRAPH
+0x8DBB 0x5D52 #CJK UNIFIED IDEOGRAPH
+0x8DBC 0x5D53 #CJK UNIFIED IDEOGRAPH
+0x8DBD 0x5D54 #CJK UNIFIED IDEOGRAPH
+0x8DBE 0x5D55 #CJK UNIFIED IDEOGRAPH
+0x8DBF 0x5D56 #CJK UNIFIED IDEOGRAPH
+0x8DC0 0x5D57 #CJK UNIFIED IDEOGRAPH
+0x8DC1 0x5D59 #CJK UNIFIED IDEOGRAPH
+0x8DC2 0x5D5A #CJK UNIFIED IDEOGRAPH
+0x8DC3 0x5D5C #CJK UNIFIED IDEOGRAPH
+0x8DC4 0x5D5E #CJK UNIFIED IDEOGRAPH
+0x8DC5 0x5D5F #CJK UNIFIED IDEOGRAPH
+0x8DC6 0x5D60 #CJK UNIFIED IDEOGRAPH
+0x8DC7 0x5D61 #CJK UNIFIED IDEOGRAPH
+0x8DC8 0x5D62 #CJK UNIFIED IDEOGRAPH
+0x8DC9 0x5D63 #CJK UNIFIED IDEOGRAPH
+0x8DCA 0x5D64 #CJK UNIFIED IDEOGRAPH
+0x8DCB 0x5D65 #CJK UNIFIED IDEOGRAPH
+0x8DCC 0x5D66 #CJK UNIFIED IDEOGRAPH
+0x8DCD 0x5D67 #CJK UNIFIED IDEOGRAPH
+0x8DCE 0x5D68 #CJK UNIFIED IDEOGRAPH
+0x8DCF 0x5D6A #CJK UNIFIED IDEOGRAPH
+0x8DD0 0x5D6D #CJK UNIFIED IDEOGRAPH
+0x8DD1 0x5D6E #CJK UNIFIED IDEOGRAPH
+0x8DD2 0x5D70 #CJK UNIFIED IDEOGRAPH
+0x8DD3 0x5D71 #CJK UNIFIED IDEOGRAPH
+0x8DD4 0x5D72 #CJK UNIFIED IDEOGRAPH
+0x8DD5 0x5D73 #CJK UNIFIED IDEOGRAPH
+0x8DD6 0x5D75 #CJK UNIFIED IDEOGRAPH
+0x8DD7 0x5D76 #CJK UNIFIED IDEOGRAPH
+0x8DD8 0x5D77 #CJK UNIFIED IDEOGRAPH
+0x8DD9 0x5D78 #CJK UNIFIED IDEOGRAPH
+0x8DDA 0x5D79 #CJK UNIFIED IDEOGRAPH
+0x8DDB 0x5D7A #CJK UNIFIED IDEOGRAPH
+0x8DDC 0x5D7B #CJK UNIFIED IDEOGRAPH
+0x8DDD 0x5D7C #CJK UNIFIED IDEOGRAPH
+0x8DDE 0x5D7D #CJK UNIFIED IDEOGRAPH
+0x8DDF 0x5D7E #CJK UNIFIED IDEOGRAPH
+0x8DE0 0x5D7F #CJK UNIFIED IDEOGRAPH
+0x8DE1 0x5D80 #CJK UNIFIED IDEOGRAPH
+0x8DE2 0x5D81 #CJK UNIFIED IDEOGRAPH
+0x8DE3 0x5D83 #CJK UNIFIED IDEOGRAPH
+0x8DE4 0x5D84 #CJK UNIFIED IDEOGRAPH
+0x8DE5 0x5D85 #CJK UNIFIED IDEOGRAPH
+0x8DE6 0x5D86 #CJK UNIFIED IDEOGRAPH
+0x8DE7 0x5D87 #CJK UNIFIED IDEOGRAPH
+0x8DE8 0x5D88 #CJK UNIFIED IDEOGRAPH
+0x8DE9 0x5D89 #CJK UNIFIED IDEOGRAPH
+0x8DEA 0x5D8A #CJK UNIFIED IDEOGRAPH
+0x8DEB 0x5D8B #CJK UNIFIED IDEOGRAPH
+0x8DEC 0x5D8C #CJK UNIFIED IDEOGRAPH
+0x8DED 0x5D8D #CJK UNIFIED IDEOGRAPH
+0x8DEE 0x5D8E #CJK UNIFIED IDEOGRAPH
+0x8DEF 0x5D8F #CJK UNIFIED IDEOGRAPH
+0x8DF0 0x5D90 #CJK UNIFIED IDEOGRAPH
+0x8DF1 0x5D91 #CJK UNIFIED IDEOGRAPH
+0x8DF2 0x5D92 #CJK UNIFIED IDEOGRAPH
+0x8DF3 0x5D93 #CJK UNIFIED IDEOGRAPH
+0x8DF4 0x5D94 #CJK UNIFIED IDEOGRAPH
+0x8DF5 0x5D95 #CJK UNIFIED IDEOGRAPH
+0x8DF6 0x5D96 #CJK UNIFIED IDEOGRAPH
+0x8DF7 0x5D97 #CJK UNIFIED IDEOGRAPH
+0x8DF8 0x5D98 #CJK UNIFIED IDEOGRAPH
+0x8DF9 0x5D9A #CJK UNIFIED IDEOGRAPH
+0x8DFA 0x5D9B #CJK UNIFIED IDEOGRAPH
+0x8DFB 0x5D9C #CJK UNIFIED IDEOGRAPH
+0x8DFC 0x5D9E #CJK UNIFIED IDEOGRAPH
+0x8DFD 0x5D9F #CJK UNIFIED IDEOGRAPH
+0x8DFE 0x5DA0 #CJK UNIFIED IDEOGRAPH
+0x8E40 0x5DA1 #CJK UNIFIED IDEOGRAPH
+0x8E41 0x5DA2 #CJK UNIFIED IDEOGRAPH
+0x8E42 0x5DA3 #CJK UNIFIED IDEOGRAPH
+0x8E43 0x5DA4 #CJK UNIFIED IDEOGRAPH
+0x8E44 0x5DA5 #CJK UNIFIED IDEOGRAPH
+0x8E45 0x5DA6 #CJK UNIFIED IDEOGRAPH
+0x8E46 0x5DA7 #CJK UNIFIED IDEOGRAPH
+0x8E47 0x5DA8 #CJK UNIFIED IDEOGRAPH
+0x8E48 0x5DA9 #CJK UNIFIED IDEOGRAPH
+0x8E49 0x5DAA #CJK UNIFIED IDEOGRAPH
+0x8E4A 0x5DAB #CJK UNIFIED IDEOGRAPH
+0x8E4B 0x5DAC #CJK UNIFIED IDEOGRAPH
+0x8E4C 0x5DAD #CJK UNIFIED IDEOGRAPH
+0x8E4D 0x5DAE #CJK UNIFIED IDEOGRAPH
+0x8E4E 0x5DAF #CJK UNIFIED IDEOGRAPH
+0x8E4F 0x5DB0 #CJK UNIFIED IDEOGRAPH
+0x8E50 0x5DB1 #CJK UNIFIED IDEOGRAPH
+0x8E51 0x5DB2 #CJK UNIFIED IDEOGRAPH
+0x8E52 0x5DB3 #CJK UNIFIED IDEOGRAPH
+0x8E53 0x5DB4 #CJK UNIFIED IDEOGRAPH
+0x8E54 0x5DB5 #CJK UNIFIED IDEOGRAPH
+0x8E55 0x5DB6 #CJK UNIFIED IDEOGRAPH
+0x8E56 0x5DB8 #CJK UNIFIED IDEOGRAPH
+0x8E57 0x5DB9 #CJK UNIFIED IDEOGRAPH
+0x8E58 0x5DBA #CJK UNIFIED IDEOGRAPH
+0x8E59 0x5DBB #CJK UNIFIED IDEOGRAPH
+0x8E5A 0x5DBC #CJK UNIFIED IDEOGRAPH
+0x8E5B 0x5DBD #CJK UNIFIED IDEOGRAPH
+0x8E5C 0x5DBE #CJK UNIFIED IDEOGRAPH
+0x8E5D 0x5DBF #CJK UNIFIED IDEOGRAPH
+0x8E5E 0x5DC0 #CJK UNIFIED IDEOGRAPH
+0x8E5F 0x5DC1 #CJK UNIFIED IDEOGRAPH
+0x8E60 0x5DC2 #CJK UNIFIED IDEOGRAPH
+0x8E61 0x5DC3 #CJK UNIFIED IDEOGRAPH
+0x8E62 0x5DC4 #CJK UNIFIED IDEOGRAPH
+0x8E63 0x5DC6 #CJK UNIFIED IDEOGRAPH
+0x8E64 0x5DC7 #CJK UNIFIED IDEOGRAPH
+0x8E65 0x5DC8 #CJK UNIFIED IDEOGRAPH
+0x8E66 0x5DC9 #CJK UNIFIED IDEOGRAPH
+0x8E67 0x5DCA #CJK UNIFIED IDEOGRAPH
+0x8E68 0x5DCB #CJK UNIFIED IDEOGRAPH
+0x8E69 0x5DCC #CJK UNIFIED IDEOGRAPH
+0x8E6A 0x5DCE #CJK UNIFIED IDEOGRAPH
+0x8E6B 0x5DCF #CJK UNIFIED IDEOGRAPH
+0x8E6C 0x5DD0 #CJK UNIFIED IDEOGRAPH
+0x8E6D 0x5DD1 #CJK UNIFIED IDEOGRAPH
+0x8E6E 0x5DD2 #CJK UNIFIED IDEOGRAPH
+0x8E6F 0x5DD3 #CJK UNIFIED IDEOGRAPH
+0x8E70 0x5DD4 #CJK UNIFIED IDEOGRAPH
+0x8E71 0x5DD5 #CJK UNIFIED IDEOGRAPH
+0x8E72 0x5DD6 #CJK UNIFIED IDEOGRAPH
+0x8E73 0x5DD7 #CJK UNIFIED IDEOGRAPH
+0x8E74 0x5DD8 #CJK UNIFIED IDEOGRAPH
+0x8E75 0x5DD9 #CJK UNIFIED IDEOGRAPH
+0x8E76 0x5DDA #CJK UNIFIED IDEOGRAPH
+0x8E77 0x5DDC #CJK UNIFIED IDEOGRAPH
+0x8E78 0x5DDF #CJK UNIFIED IDEOGRAPH
+0x8E79 0x5DE0 #CJK UNIFIED IDEOGRAPH
+0x8E7A 0x5DE3 #CJK UNIFIED IDEOGRAPH
+0x8E7B 0x5DE4 #CJK UNIFIED IDEOGRAPH
+0x8E7C 0x5DEA #CJK UNIFIED IDEOGRAPH
+0x8E7D 0x5DEC #CJK UNIFIED IDEOGRAPH
+0x8E7E 0x5DED #CJK UNIFIED IDEOGRAPH
+0x8E80 0x5DF0 #CJK UNIFIED IDEOGRAPH
+0x8E81 0x5DF5 #CJK UNIFIED IDEOGRAPH
+0x8E82 0x5DF6 #CJK UNIFIED IDEOGRAPH
+0x8E83 0x5DF8 #CJK UNIFIED IDEOGRAPH
+0x8E84 0x5DF9 #CJK UNIFIED IDEOGRAPH
+0x8E85 0x5DFA #CJK UNIFIED IDEOGRAPH
+0x8E86 0x5DFB #CJK UNIFIED IDEOGRAPH
+0x8E87 0x5DFC #CJK UNIFIED IDEOGRAPH
+0x8E88 0x5DFF #CJK UNIFIED IDEOGRAPH
+0x8E89 0x5E00 #CJK UNIFIED IDEOGRAPH
+0x8E8A 0x5E04 #CJK UNIFIED IDEOGRAPH
+0x8E8B 0x5E07 #CJK UNIFIED IDEOGRAPH
+0x8E8C 0x5E09 #CJK UNIFIED IDEOGRAPH
+0x8E8D 0x5E0A #CJK UNIFIED IDEOGRAPH
+0x8E8E 0x5E0B #CJK UNIFIED IDEOGRAPH
+0x8E8F 0x5E0D #CJK UNIFIED IDEOGRAPH
+0x8E90 0x5E0E #CJK UNIFIED IDEOGRAPH
+0x8E91 0x5E12 #CJK UNIFIED IDEOGRAPH
+0x8E92 0x5E13 #CJK UNIFIED IDEOGRAPH
+0x8E93 0x5E17 #CJK UNIFIED IDEOGRAPH
+0x8E94 0x5E1E #CJK UNIFIED IDEOGRAPH
+0x8E95 0x5E1F #CJK UNIFIED IDEOGRAPH
+0x8E96 0x5E20 #CJK UNIFIED IDEOGRAPH
+0x8E97 0x5E21 #CJK UNIFIED IDEOGRAPH
+0x8E98 0x5E22 #CJK UNIFIED IDEOGRAPH
+0x8E99 0x5E23 #CJK UNIFIED IDEOGRAPH
+0x8E9A 0x5E24 #CJK UNIFIED IDEOGRAPH
+0x8E9B 0x5E25 #CJK UNIFIED IDEOGRAPH
+0x8E9C 0x5E28 #CJK UNIFIED IDEOGRAPH
+0x8E9D 0x5E29 #CJK UNIFIED IDEOGRAPH
+0x8E9E 0x5E2A #CJK UNIFIED IDEOGRAPH
+0x8E9F 0x5E2B #CJK UNIFIED IDEOGRAPH
+0x8EA0 0x5E2C #CJK UNIFIED IDEOGRAPH
+0x8EA1 0x5E2F #CJK UNIFIED IDEOGRAPH
+0x8EA2 0x5E30 #CJK UNIFIED IDEOGRAPH
+0x8EA3 0x5E32 #CJK UNIFIED IDEOGRAPH
+0x8EA4 0x5E33 #CJK UNIFIED IDEOGRAPH
+0x8EA5 0x5E34 #CJK UNIFIED IDEOGRAPH
+0x8EA6 0x5E35 #CJK UNIFIED IDEOGRAPH
+0x8EA7 0x5E36 #CJK UNIFIED IDEOGRAPH
+0x8EA8 0x5E39 #CJK UNIFIED IDEOGRAPH
+0x8EA9 0x5E3A #CJK UNIFIED IDEOGRAPH
+0x8EAA 0x5E3E #CJK UNIFIED IDEOGRAPH
+0x8EAB 0x5E3F #CJK UNIFIED IDEOGRAPH
+0x8EAC 0x5E40 #CJK UNIFIED IDEOGRAPH
+0x8EAD 0x5E41 #CJK UNIFIED IDEOGRAPH
+0x8EAE 0x5E43 #CJK UNIFIED IDEOGRAPH
+0x8EAF 0x5E46 #CJK UNIFIED IDEOGRAPH
+0x8EB0 0x5E47 #CJK UNIFIED IDEOGRAPH
+0x8EB1 0x5E48 #CJK UNIFIED IDEOGRAPH
+0x8EB2 0x5E49 #CJK UNIFIED IDEOGRAPH
+0x8EB3 0x5E4A #CJK UNIFIED IDEOGRAPH
+0x8EB4 0x5E4B #CJK UNIFIED IDEOGRAPH
+0x8EB5 0x5E4D #CJK UNIFIED IDEOGRAPH
+0x8EB6 0x5E4E #CJK UNIFIED IDEOGRAPH
+0x8EB7 0x5E4F #CJK UNIFIED IDEOGRAPH
+0x8EB8 0x5E50 #CJK UNIFIED IDEOGRAPH
+0x8EB9 0x5E51 #CJK UNIFIED IDEOGRAPH
+0x8EBA 0x5E52 #CJK UNIFIED IDEOGRAPH
+0x8EBB 0x5E53 #CJK UNIFIED IDEOGRAPH
+0x8EBC 0x5E56 #CJK UNIFIED IDEOGRAPH
+0x8EBD 0x5E57 #CJK UNIFIED IDEOGRAPH
+0x8EBE 0x5E58 #CJK UNIFIED IDEOGRAPH
+0x8EBF 0x5E59 #CJK UNIFIED IDEOGRAPH
+0x8EC0 0x5E5A #CJK UNIFIED IDEOGRAPH
+0x8EC1 0x5E5C #CJK UNIFIED IDEOGRAPH
+0x8EC2 0x5E5D #CJK UNIFIED IDEOGRAPH
+0x8EC3 0x5E5F #CJK UNIFIED IDEOGRAPH
+0x8EC4 0x5E60 #CJK UNIFIED IDEOGRAPH
+0x8EC5 0x5E63 #CJK UNIFIED IDEOGRAPH
+0x8EC6 0x5E64 #CJK UNIFIED IDEOGRAPH
+0x8EC7 0x5E65 #CJK UNIFIED IDEOGRAPH
+0x8EC8 0x5E66 #CJK UNIFIED IDEOGRAPH
+0x8EC9 0x5E67 #CJK UNIFIED IDEOGRAPH
+0x8ECA 0x5E68 #CJK UNIFIED IDEOGRAPH
+0x8ECB 0x5E69 #CJK UNIFIED IDEOGRAPH
+0x8ECC 0x5E6A #CJK UNIFIED IDEOGRAPH
+0x8ECD 0x5E6B #CJK UNIFIED IDEOGRAPH
+0x8ECE 0x5E6C #CJK UNIFIED IDEOGRAPH
+0x8ECF 0x5E6D #CJK UNIFIED IDEOGRAPH
+0x8ED0 0x5E6E #CJK UNIFIED IDEOGRAPH
+0x8ED1 0x5E6F #CJK UNIFIED IDEOGRAPH
+0x8ED2 0x5E70 #CJK UNIFIED IDEOGRAPH
+0x8ED3 0x5E71 #CJK UNIFIED IDEOGRAPH
+0x8ED4 0x5E75 #CJK UNIFIED IDEOGRAPH
+0x8ED5 0x5E77 #CJK UNIFIED IDEOGRAPH
+0x8ED6 0x5E79 #CJK UNIFIED IDEOGRAPH
+0x8ED7 0x5E7E #CJK UNIFIED IDEOGRAPH
+0x8ED8 0x5E81 #CJK UNIFIED IDEOGRAPH
+0x8ED9 0x5E82 #CJK UNIFIED IDEOGRAPH
+0x8EDA 0x5E83 #CJK UNIFIED IDEOGRAPH
+0x8EDB 0x5E85 #CJK UNIFIED IDEOGRAPH
+0x8EDC 0x5E88 #CJK UNIFIED IDEOGRAPH
+0x8EDD 0x5E89 #CJK UNIFIED IDEOGRAPH
+0x8EDE 0x5E8C #CJK UNIFIED IDEOGRAPH
+0x8EDF 0x5E8D #CJK UNIFIED IDEOGRAPH
+0x8EE0 0x5E8E #CJK UNIFIED IDEOGRAPH
+0x8EE1 0x5E92 #CJK UNIFIED IDEOGRAPH
+0x8EE2 0x5E98 #CJK UNIFIED IDEOGRAPH
+0x8EE3 0x5E9B #CJK UNIFIED IDEOGRAPH
+0x8EE4 0x5E9D #CJK UNIFIED IDEOGRAPH
+0x8EE5 0x5EA1 #CJK UNIFIED IDEOGRAPH
+0x8EE6 0x5EA2 #CJK UNIFIED IDEOGRAPH
+0x8EE7 0x5EA3 #CJK UNIFIED IDEOGRAPH
+0x8EE8 0x5EA4 #CJK UNIFIED IDEOGRAPH
+0x8EE9 0x5EA8 #CJK UNIFIED IDEOGRAPH
+0x8EEA 0x5EA9 #CJK UNIFIED IDEOGRAPH
+0x8EEB 0x5EAA #CJK UNIFIED IDEOGRAPH
+0x8EEC 0x5EAB #CJK UNIFIED IDEOGRAPH
+0x8EED 0x5EAC #CJK UNIFIED IDEOGRAPH
+0x8EEE 0x5EAE #CJK UNIFIED IDEOGRAPH
+0x8EEF 0x5EAF #CJK UNIFIED IDEOGRAPH
+0x8EF0 0x5EB0 #CJK UNIFIED IDEOGRAPH
+0x8EF1 0x5EB1 #CJK UNIFIED IDEOGRAPH
+0x8EF2 0x5EB2 #CJK UNIFIED IDEOGRAPH
+0x8EF3 0x5EB4 #CJK UNIFIED IDEOGRAPH
+0x8EF4 0x5EBA #CJK UNIFIED IDEOGRAPH
+0x8EF5 0x5EBB #CJK UNIFIED IDEOGRAPH
+0x8EF6 0x5EBC #CJK UNIFIED IDEOGRAPH
+0x8EF7 0x5EBD #CJK UNIFIED IDEOGRAPH
+0x8EF8 0x5EBF #CJK UNIFIED IDEOGRAPH
+0x8EF9 0x5EC0 #CJK UNIFIED IDEOGRAPH
+0x8EFA 0x5EC1 #CJK UNIFIED IDEOGRAPH
+0x8EFB 0x5EC2 #CJK UNIFIED IDEOGRAPH
+0x8EFC 0x5EC3 #CJK UNIFIED IDEOGRAPH
+0x8EFD 0x5EC4 #CJK UNIFIED IDEOGRAPH
+0x8EFE 0x5EC5 #CJK UNIFIED IDEOGRAPH
+0x8F40 0x5EC6 #CJK UNIFIED IDEOGRAPH
+0x8F41 0x5EC7 #CJK UNIFIED IDEOGRAPH
+0x8F42 0x5EC8 #CJK UNIFIED IDEOGRAPH
+0x8F43 0x5ECB #CJK UNIFIED IDEOGRAPH
+0x8F44 0x5ECC #CJK UNIFIED IDEOGRAPH
+0x8F45 0x5ECD #CJK UNIFIED IDEOGRAPH
+0x8F46 0x5ECE #CJK UNIFIED IDEOGRAPH
+0x8F47 0x5ECF #CJK UNIFIED IDEOGRAPH
+0x8F48 0x5ED0 #CJK UNIFIED IDEOGRAPH
+0x8F49 0x5ED4 #CJK UNIFIED IDEOGRAPH
+0x8F4A 0x5ED5 #CJK UNIFIED IDEOGRAPH
+0x8F4B 0x5ED7 #CJK UNIFIED IDEOGRAPH
+0x8F4C 0x5ED8 #CJK UNIFIED IDEOGRAPH
+0x8F4D 0x5ED9 #CJK UNIFIED IDEOGRAPH
+0x8F4E 0x5EDA #CJK UNIFIED IDEOGRAPH
+0x8F4F 0x5EDC #CJK UNIFIED IDEOGRAPH
+0x8F50 0x5EDD #CJK UNIFIED IDEOGRAPH
+0x8F51 0x5EDE #CJK UNIFIED IDEOGRAPH
+0x8F52 0x5EDF #CJK UNIFIED IDEOGRAPH
+0x8F53 0x5EE0 #CJK UNIFIED IDEOGRAPH
+0x8F54 0x5EE1 #CJK UNIFIED IDEOGRAPH
+0x8F55 0x5EE2 #CJK UNIFIED IDEOGRAPH
+0x8F56 0x5EE3 #CJK UNIFIED IDEOGRAPH
+0x8F57 0x5EE4 #CJK UNIFIED IDEOGRAPH
+0x8F58 0x5EE5 #CJK UNIFIED IDEOGRAPH
+0x8F59 0x5EE6 #CJK UNIFIED IDEOGRAPH
+0x8F5A 0x5EE7 #CJK UNIFIED IDEOGRAPH
+0x8F5B 0x5EE9 #CJK UNIFIED IDEOGRAPH
+0x8F5C 0x5EEB #CJK UNIFIED IDEOGRAPH
+0x8F5D 0x5EEC #CJK UNIFIED IDEOGRAPH
+0x8F5E 0x5EED #CJK UNIFIED IDEOGRAPH
+0x8F5F 0x5EEE #CJK UNIFIED IDEOGRAPH
+0x8F60 0x5EEF #CJK UNIFIED IDEOGRAPH
+0x8F61 0x5EF0 #CJK UNIFIED IDEOGRAPH
+0x8F62 0x5EF1 #CJK UNIFIED IDEOGRAPH
+0x8F63 0x5EF2 #CJK UNIFIED IDEOGRAPH
+0x8F64 0x5EF3 #CJK UNIFIED IDEOGRAPH
+0x8F65 0x5EF5 #CJK UNIFIED IDEOGRAPH
+0x8F66 0x5EF8 #CJK UNIFIED IDEOGRAPH
+0x8F67 0x5EF9 #CJK UNIFIED IDEOGRAPH
+0x8F68 0x5EFB #CJK UNIFIED IDEOGRAPH
+0x8F69 0x5EFC #CJK UNIFIED IDEOGRAPH
+0x8F6A 0x5EFD #CJK UNIFIED IDEOGRAPH
+0x8F6B 0x5F05 #CJK UNIFIED IDEOGRAPH
+0x8F6C 0x5F06 #CJK UNIFIED IDEOGRAPH
+0x8F6D 0x5F07 #CJK UNIFIED IDEOGRAPH
+0x8F6E 0x5F09 #CJK UNIFIED IDEOGRAPH
+0x8F6F 0x5F0C #CJK UNIFIED IDEOGRAPH
+0x8F70 0x5F0D #CJK UNIFIED IDEOGRAPH
+0x8F71 0x5F0E #CJK UNIFIED IDEOGRAPH
+0x8F72 0x5F10 #CJK UNIFIED IDEOGRAPH
+0x8F73 0x5F12 #CJK UNIFIED IDEOGRAPH
+0x8F74 0x5F14 #CJK UNIFIED IDEOGRAPH
+0x8F75 0x5F16 #CJK UNIFIED IDEOGRAPH
+0x8F76 0x5F19 #CJK UNIFIED IDEOGRAPH
+0x8F77 0x5F1A #CJK UNIFIED IDEOGRAPH
+0x8F78 0x5F1C #CJK UNIFIED IDEOGRAPH
+0x8F79 0x5F1D #CJK UNIFIED IDEOGRAPH
+0x8F7A 0x5F1E #CJK UNIFIED IDEOGRAPH
+0x8F7B 0x5F21 #CJK UNIFIED IDEOGRAPH
+0x8F7C 0x5F22 #CJK UNIFIED IDEOGRAPH
+0x8F7D 0x5F23 #CJK UNIFIED IDEOGRAPH
+0x8F7E 0x5F24 #CJK UNIFIED IDEOGRAPH
+0x8F80 0x5F28 #CJK UNIFIED IDEOGRAPH
+0x8F81 0x5F2B #CJK UNIFIED IDEOGRAPH
+0x8F82 0x5F2C #CJK UNIFIED IDEOGRAPH
+0x8F83 0x5F2E #CJK UNIFIED IDEOGRAPH
+0x8F84 0x5F30 #CJK UNIFIED IDEOGRAPH
+0x8F85 0x5F32 #CJK UNIFIED IDEOGRAPH
+0x8F86 0x5F33 #CJK UNIFIED IDEOGRAPH
+0x8F87 0x5F34 #CJK UNIFIED IDEOGRAPH
+0x8F88 0x5F35 #CJK UNIFIED IDEOGRAPH
+0x8F89 0x5F36 #CJK UNIFIED IDEOGRAPH
+0x8F8A 0x5F37 #CJK UNIFIED IDEOGRAPH
+0x8F8B 0x5F38 #CJK UNIFIED IDEOGRAPH
+0x8F8C 0x5F3B #CJK UNIFIED IDEOGRAPH
+0x8F8D 0x5F3D #CJK UNIFIED IDEOGRAPH
+0x8F8E 0x5F3E #CJK UNIFIED IDEOGRAPH
+0x8F8F 0x5F3F #CJK UNIFIED IDEOGRAPH
+0x8F90 0x5F41 #CJK UNIFIED IDEOGRAPH
+0x8F91 0x5F42 #CJK UNIFIED IDEOGRAPH
+0x8F92 0x5F43 #CJK UNIFIED IDEOGRAPH
+0x8F93 0x5F44 #CJK UNIFIED IDEOGRAPH
+0x8F94 0x5F45 #CJK UNIFIED IDEOGRAPH
+0x8F95 0x5F46 #CJK UNIFIED IDEOGRAPH
+0x8F96 0x5F47 #CJK UNIFIED IDEOGRAPH
+0x8F97 0x5F48 #CJK UNIFIED IDEOGRAPH
+0x8F98 0x5F49 #CJK UNIFIED IDEOGRAPH
+0x8F99 0x5F4A #CJK UNIFIED IDEOGRAPH
+0x8F9A 0x5F4B #CJK UNIFIED IDEOGRAPH
+0x8F9B 0x5F4C #CJK UNIFIED IDEOGRAPH
+0x8F9C 0x5F4D #CJK UNIFIED IDEOGRAPH
+0x8F9D 0x5F4E #CJK UNIFIED IDEOGRAPH
+0x8F9E 0x5F4F #CJK UNIFIED IDEOGRAPH
+0x8F9F 0x5F51 #CJK UNIFIED IDEOGRAPH
+0x8FA0 0x5F54 #CJK UNIFIED IDEOGRAPH
+0x8FA1 0x5F59 #CJK UNIFIED IDEOGRAPH
+0x8FA2 0x5F5A #CJK UNIFIED IDEOGRAPH
+0x8FA3 0x5F5B #CJK UNIFIED IDEOGRAPH
+0x8FA4 0x5F5C #CJK UNIFIED IDEOGRAPH
+0x8FA5 0x5F5E #CJK UNIFIED IDEOGRAPH
+0x8FA6 0x5F5F #CJK UNIFIED IDEOGRAPH
+0x8FA7 0x5F60 #CJK UNIFIED IDEOGRAPH
+0x8FA8 0x5F63 #CJK UNIFIED IDEOGRAPH
+0x8FA9 0x5F65 #CJK UNIFIED IDEOGRAPH
+0x8FAA 0x5F67 #CJK UNIFIED IDEOGRAPH
+0x8FAB 0x5F68 #CJK UNIFIED IDEOGRAPH
+0x8FAC 0x5F6B #CJK UNIFIED IDEOGRAPH
+0x8FAD 0x5F6E #CJK UNIFIED IDEOGRAPH
+0x8FAE 0x5F6F #CJK UNIFIED IDEOGRAPH
+0x8FAF 0x5F72 #CJK UNIFIED IDEOGRAPH
+0x8FB0 0x5F74 #CJK UNIFIED IDEOGRAPH
+0x8FB1 0x5F75 #CJK UNIFIED IDEOGRAPH
+0x8FB2 0x5F76 #CJK UNIFIED IDEOGRAPH
+0x8FB3 0x5F78 #CJK UNIFIED IDEOGRAPH
+0x8FB4 0x5F7A #CJK UNIFIED IDEOGRAPH
+0x8FB5 0x5F7D #CJK UNIFIED IDEOGRAPH
+0x8FB6 0x5F7E #CJK UNIFIED IDEOGRAPH
+0x8FB7 0x5F7F #CJK UNIFIED IDEOGRAPH
+0x8FB8 0x5F83 #CJK UNIFIED IDEOGRAPH
+0x8FB9 0x5F86 #CJK UNIFIED IDEOGRAPH
+0x8FBA 0x5F8D #CJK UNIFIED IDEOGRAPH
+0x8FBB 0x5F8E #CJK UNIFIED IDEOGRAPH
+0x8FBC 0x5F8F #CJK UNIFIED IDEOGRAPH
+0x8FBD 0x5F91 #CJK UNIFIED IDEOGRAPH
+0x8FBE 0x5F93 #CJK UNIFIED IDEOGRAPH
+0x8FBF 0x5F94 #CJK UNIFIED IDEOGRAPH
+0x8FC0 0x5F96 #CJK UNIFIED IDEOGRAPH
+0x8FC1 0x5F9A #CJK UNIFIED IDEOGRAPH
+0x8FC2 0x5F9B #CJK UNIFIED IDEOGRAPH
+0x8FC3 0x5F9D #CJK UNIFIED IDEOGRAPH
+0x8FC4 0x5F9E #CJK UNIFIED IDEOGRAPH
+0x8FC5 0x5F9F #CJK UNIFIED IDEOGRAPH
+0x8FC6 0x5FA0 #CJK UNIFIED IDEOGRAPH
+0x8FC7 0x5FA2 #CJK UNIFIED IDEOGRAPH
+0x8FC8 0x5FA3 #CJK UNIFIED IDEOGRAPH
+0x8FC9 0x5FA4 #CJK UNIFIED IDEOGRAPH
+0x8FCA 0x5FA5 #CJK UNIFIED IDEOGRAPH
+0x8FCB 0x5FA6 #CJK UNIFIED IDEOGRAPH
+0x8FCC 0x5FA7 #CJK UNIFIED IDEOGRAPH
+0x8FCD 0x5FA9 #CJK UNIFIED IDEOGRAPH
+0x8FCE 0x5FAB #CJK UNIFIED IDEOGRAPH
+0x8FCF 0x5FAC #CJK UNIFIED IDEOGRAPH
+0x8FD0 0x5FAF #CJK UNIFIED IDEOGRAPH
+0x8FD1 0x5FB0 #CJK UNIFIED IDEOGRAPH
+0x8FD2 0x5FB1 #CJK UNIFIED IDEOGRAPH
+0x8FD3 0x5FB2 #CJK UNIFIED IDEOGRAPH
+0x8FD4 0x5FB3 #CJK UNIFIED IDEOGRAPH
+0x8FD5 0x5FB4 #CJK UNIFIED IDEOGRAPH
+0x8FD6 0x5FB6 #CJK UNIFIED IDEOGRAPH
+0x8FD7 0x5FB8 #CJK UNIFIED IDEOGRAPH
+0x8FD8 0x5FB9 #CJK UNIFIED IDEOGRAPH
+0x8FD9 0x5FBA #CJK UNIFIED IDEOGRAPH
+0x8FDA 0x5FBB #CJK UNIFIED IDEOGRAPH
+0x8FDB 0x5FBE #CJK UNIFIED IDEOGRAPH
+0x8FDC 0x5FBF #CJK UNIFIED IDEOGRAPH
+0x8FDD 0x5FC0 #CJK UNIFIED IDEOGRAPH
+0x8FDE 0x5FC1 #CJK UNIFIED IDEOGRAPH
+0x8FDF 0x5FC2 #CJK UNIFIED IDEOGRAPH
+0x8FE0 0x5FC7 #CJK UNIFIED IDEOGRAPH
+0x8FE1 0x5FC8 #CJK UNIFIED IDEOGRAPH
+0x8FE2 0x5FCA #CJK UNIFIED IDEOGRAPH
+0x8FE3 0x5FCB #CJK UNIFIED IDEOGRAPH
+0x8FE4 0x5FCE #CJK UNIFIED IDEOGRAPH
+0x8FE5 0x5FD3 #CJK UNIFIED IDEOGRAPH
+0x8FE6 0x5FD4 #CJK UNIFIED IDEOGRAPH
+0x8FE7 0x5FD5 #CJK UNIFIED IDEOGRAPH
+0x8FE8 0x5FDA #CJK UNIFIED IDEOGRAPH
+0x8FE9 0x5FDB #CJK UNIFIED IDEOGRAPH
+0x8FEA 0x5FDC #CJK UNIFIED IDEOGRAPH
+0x8FEB 0x5FDE #CJK UNIFIED IDEOGRAPH
+0x8FEC 0x5FDF #CJK UNIFIED IDEOGRAPH
+0x8FED 0x5FE2 #CJK UNIFIED IDEOGRAPH
+0x8FEE 0x5FE3 #CJK UNIFIED IDEOGRAPH
+0x8FEF 0x5FE5 #CJK UNIFIED IDEOGRAPH
+0x8FF0 0x5FE6 #CJK UNIFIED IDEOGRAPH
+0x8FF1 0x5FE8 #CJK UNIFIED IDEOGRAPH
+0x8FF2 0x5FE9 #CJK UNIFIED IDEOGRAPH
+0x8FF3 0x5FEC #CJK UNIFIED IDEOGRAPH
+0x8FF4 0x5FEF #CJK UNIFIED IDEOGRAPH
+0x8FF5 0x5FF0 #CJK UNIFIED IDEOGRAPH
+0x8FF6 0x5FF2 #CJK UNIFIED IDEOGRAPH
+0x8FF7 0x5FF3 #CJK UNIFIED IDEOGRAPH
+0x8FF8 0x5FF4 #CJK UNIFIED IDEOGRAPH
+0x8FF9 0x5FF6 #CJK UNIFIED IDEOGRAPH
+0x8FFA 0x5FF7 #CJK UNIFIED IDEOGRAPH
+0x8FFB 0x5FF9 #CJK UNIFIED IDEOGRAPH
+0x8FFC 0x5FFA #CJK UNIFIED IDEOGRAPH
+0x8FFD 0x5FFC #CJK UNIFIED IDEOGRAPH
+0x8FFE 0x6007 #CJK UNIFIED IDEOGRAPH
+0x9040 0x6008 #CJK UNIFIED IDEOGRAPH
+0x9041 0x6009 #CJK UNIFIED IDEOGRAPH
+0x9042 0x600B #CJK UNIFIED IDEOGRAPH
+0x9043 0x600C #CJK UNIFIED IDEOGRAPH
+0x9044 0x6010 #CJK UNIFIED IDEOGRAPH
+0x9045 0x6011 #CJK UNIFIED IDEOGRAPH
+0x9046 0x6013 #CJK UNIFIED IDEOGRAPH
+0x9047 0x6017 #CJK UNIFIED IDEOGRAPH
+0x9048 0x6018 #CJK UNIFIED IDEOGRAPH
+0x9049 0x601A #CJK UNIFIED IDEOGRAPH
+0x904A 0x601E #CJK UNIFIED IDEOGRAPH
+0x904B 0x601F #CJK UNIFIED IDEOGRAPH
+0x904C 0x6022 #CJK UNIFIED IDEOGRAPH
+0x904D 0x6023 #CJK UNIFIED IDEOGRAPH
+0x904E 0x6024 #CJK UNIFIED IDEOGRAPH
+0x904F 0x602C #CJK UNIFIED IDEOGRAPH
+0x9050 0x602D #CJK UNIFIED IDEOGRAPH
+0x9051 0x602E #CJK UNIFIED IDEOGRAPH
+0x9052 0x6030 #CJK UNIFIED IDEOGRAPH
+0x9053 0x6031 #CJK UNIFIED IDEOGRAPH
+0x9054 0x6032 #CJK UNIFIED IDEOGRAPH
+0x9055 0x6033 #CJK UNIFIED IDEOGRAPH
+0x9056 0x6034 #CJK UNIFIED IDEOGRAPH
+0x9057 0x6036 #CJK UNIFIED IDEOGRAPH
+0x9058 0x6037 #CJK UNIFIED IDEOGRAPH
+0x9059 0x6038 #CJK UNIFIED IDEOGRAPH
+0x905A 0x6039 #CJK UNIFIED IDEOGRAPH
+0x905B 0x603A #CJK UNIFIED IDEOGRAPH
+0x905C 0x603D #CJK UNIFIED IDEOGRAPH
+0x905D 0x603E #CJK UNIFIED IDEOGRAPH
+0x905E 0x6040 #CJK UNIFIED IDEOGRAPH
+0x905F 0x6044 #CJK UNIFIED IDEOGRAPH
+0x9060 0x6045 #CJK UNIFIED IDEOGRAPH
+0x9061 0x6046 #CJK UNIFIED IDEOGRAPH
+0x9062 0x6047 #CJK UNIFIED IDEOGRAPH
+0x9063 0x6048 #CJK UNIFIED IDEOGRAPH
+0x9064 0x6049 #CJK UNIFIED IDEOGRAPH
+0x9065 0x604A #CJK UNIFIED IDEOGRAPH
+0x9066 0x604C #CJK UNIFIED IDEOGRAPH
+0x9067 0x604E #CJK UNIFIED IDEOGRAPH
+0x9068 0x604F #CJK UNIFIED IDEOGRAPH
+0x9069 0x6051 #CJK UNIFIED IDEOGRAPH
+0x906A 0x6053 #CJK UNIFIED IDEOGRAPH
+0x906B 0x6054 #CJK UNIFIED IDEOGRAPH
+0x906C 0x6056 #CJK UNIFIED IDEOGRAPH
+0x906D 0x6057 #CJK UNIFIED IDEOGRAPH
+0x906E 0x6058 #CJK UNIFIED IDEOGRAPH
+0x906F 0x605B #CJK UNIFIED IDEOGRAPH
+0x9070 0x605C #CJK UNIFIED IDEOGRAPH
+0x9071 0x605E #CJK UNIFIED IDEOGRAPH
+0x9072 0x605F #CJK UNIFIED IDEOGRAPH
+0x9073 0x6060 #CJK UNIFIED IDEOGRAPH
+0x9074 0x6061 #CJK UNIFIED IDEOGRAPH
+0x9075 0x6065 #CJK UNIFIED IDEOGRAPH
+0x9076 0x6066 #CJK UNIFIED IDEOGRAPH
+0x9077 0x606E #CJK UNIFIED IDEOGRAPH
+0x9078 0x6071 #CJK UNIFIED IDEOGRAPH
+0x9079 0x6072 #CJK UNIFIED IDEOGRAPH
+0x907A 0x6074 #CJK UNIFIED IDEOGRAPH
+0x907B 0x6075 #CJK UNIFIED IDEOGRAPH
+0x907C 0x6077 #CJK UNIFIED IDEOGRAPH
+0x907D 0x607E #CJK UNIFIED IDEOGRAPH
+0x907E 0x6080 #CJK UNIFIED IDEOGRAPH
+0x9080 0x6081 #CJK UNIFIED IDEOGRAPH
+0x9081 0x6082 #CJK UNIFIED IDEOGRAPH
+0x9082 0x6085 #CJK UNIFIED IDEOGRAPH
+0x9083 0x6086 #CJK UNIFIED IDEOGRAPH
+0x9084 0x6087 #CJK UNIFIED IDEOGRAPH
+0x9085 0x6088 #CJK UNIFIED IDEOGRAPH
+0x9086 0x608A #CJK UNIFIED IDEOGRAPH
+0x9087 0x608B #CJK UNIFIED IDEOGRAPH
+0x9088 0x608E #CJK UNIFIED IDEOGRAPH
+0x9089 0x608F #CJK UNIFIED IDEOGRAPH
+0x908A 0x6090 #CJK UNIFIED IDEOGRAPH
+0x908B 0x6091 #CJK UNIFIED IDEOGRAPH
+0x908C 0x6093 #CJK UNIFIED IDEOGRAPH
+0x908D 0x6095 #CJK UNIFIED IDEOGRAPH
+0x908E 0x6097 #CJK UNIFIED IDEOGRAPH
+0x908F 0x6098 #CJK UNIFIED IDEOGRAPH
+0x9090 0x6099 #CJK UNIFIED IDEOGRAPH
+0x9091 0x609C #CJK UNIFIED IDEOGRAPH
+0x9092 0x609E #CJK UNIFIED IDEOGRAPH
+0x9093 0x60A1 #CJK UNIFIED IDEOGRAPH
+0x9094 0x60A2 #CJK UNIFIED IDEOGRAPH
+0x9095 0x60A4 #CJK UNIFIED IDEOGRAPH
+0x9096 0x60A5 #CJK UNIFIED IDEOGRAPH
+0x9097 0x60A7 #CJK UNIFIED IDEOGRAPH
+0x9098 0x60A9 #CJK UNIFIED IDEOGRAPH
+0x9099 0x60AA #CJK UNIFIED IDEOGRAPH
+0x909A 0x60AE #CJK UNIFIED IDEOGRAPH
+0x909B 0x60B0 #CJK UNIFIED IDEOGRAPH
+0x909C 0x60B3 #CJK UNIFIED IDEOGRAPH
+0x909D 0x60B5 #CJK UNIFIED IDEOGRAPH
+0x909E 0x60B6 #CJK UNIFIED IDEOGRAPH
+0x909F 0x60B7 #CJK UNIFIED IDEOGRAPH
+0x90A0 0x60B9 #CJK UNIFIED IDEOGRAPH
+0x90A1 0x60BA #CJK UNIFIED IDEOGRAPH
+0x90A2 0x60BD #CJK UNIFIED IDEOGRAPH
+0x90A3 0x60BE #CJK UNIFIED IDEOGRAPH
+0x90A4 0x60BF #CJK UNIFIED IDEOGRAPH
+0x90A5 0x60C0 #CJK UNIFIED IDEOGRAPH
+0x90A6 0x60C1 #CJK UNIFIED IDEOGRAPH
+0x90A7 0x60C2 #CJK UNIFIED IDEOGRAPH
+0x90A8 0x60C3 #CJK UNIFIED IDEOGRAPH
+0x90A9 0x60C4 #CJK UNIFIED IDEOGRAPH
+0x90AA 0x60C7 #CJK UNIFIED IDEOGRAPH
+0x90AB 0x60C8 #CJK UNIFIED IDEOGRAPH
+0x90AC 0x60C9 #CJK UNIFIED IDEOGRAPH
+0x90AD 0x60CC #CJK UNIFIED IDEOGRAPH
+0x90AE 0x60CD #CJK UNIFIED IDEOGRAPH
+0x90AF 0x60CE #CJK UNIFIED IDEOGRAPH
+0x90B0 0x60CF #CJK UNIFIED IDEOGRAPH
+0x90B1 0x60D0 #CJK UNIFIED IDEOGRAPH
+0x90B2 0x60D2 #CJK UNIFIED IDEOGRAPH
+0x90B3 0x60D3 #CJK UNIFIED IDEOGRAPH
+0x90B4 0x60D4 #CJK UNIFIED IDEOGRAPH
+0x90B5 0x60D6 #CJK UNIFIED IDEOGRAPH
+0x90B6 0x60D7 #CJK UNIFIED IDEOGRAPH
+0x90B7 0x60D9 #CJK UNIFIED IDEOGRAPH
+0x90B8 0x60DB #CJK UNIFIED IDEOGRAPH
+0x90B9 0x60DE #CJK UNIFIED IDEOGRAPH
+0x90BA 0x60E1 #CJK UNIFIED IDEOGRAPH
+0x90BB 0x60E2 #CJK UNIFIED IDEOGRAPH
+0x90BC 0x60E3 #CJK UNIFIED IDEOGRAPH
+0x90BD 0x60E4 #CJK UNIFIED IDEOGRAPH
+0x90BE 0x60E5 #CJK UNIFIED IDEOGRAPH
+0x90BF 0x60EA #CJK UNIFIED IDEOGRAPH
+0x90C0 0x60F1 #CJK UNIFIED IDEOGRAPH
+0x90C1 0x60F2 #CJK UNIFIED IDEOGRAPH
+0x90C2 0x60F5 #CJK UNIFIED IDEOGRAPH
+0x90C3 0x60F7 #CJK UNIFIED IDEOGRAPH
+0x90C4 0x60F8 #CJK UNIFIED IDEOGRAPH
+0x90C5 0x60FB #CJK UNIFIED IDEOGRAPH
+0x90C6 0x60FC #CJK UNIFIED IDEOGRAPH
+0x90C7 0x60FD #CJK UNIFIED IDEOGRAPH
+0x90C8 0x60FE #CJK UNIFIED IDEOGRAPH
+0x90C9 0x60FF #CJK UNIFIED IDEOGRAPH
+0x90CA 0x6102 #CJK UNIFIED IDEOGRAPH
+0x90CB 0x6103 #CJK UNIFIED IDEOGRAPH
+0x90CC 0x6104 #CJK UNIFIED IDEOGRAPH
+0x90CD 0x6105 #CJK UNIFIED IDEOGRAPH
+0x90CE 0x6107 #CJK UNIFIED IDEOGRAPH
+0x90CF 0x610A #CJK UNIFIED IDEOGRAPH
+0x90D0 0x610B #CJK UNIFIED IDEOGRAPH
+0x90D1 0x610C #CJK UNIFIED IDEOGRAPH
+0x90D2 0x6110 #CJK UNIFIED IDEOGRAPH
+0x90D3 0x6111 #CJK UNIFIED IDEOGRAPH
+0x90D4 0x6112 #CJK UNIFIED IDEOGRAPH
+0x90D5 0x6113 #CJK UNIFIED IDEOGRAPH
+0x90D6 0x6114 #CJK UNIFIED IDEOGRAPH
+0x90D7 0x6116 #CJK UNIFIED IDEOGRAPH
+0x90D8 0x6117 #CJK UNIFIED IDEOGRAPH
+0x90D9 0x6118 #CJK UNIFIED IDEOGRAPH
+0x90DA 0x6119 #CJK UNIFIED IDEOGRAPH
+0x90DB 0x611B #CJK UNIFIED IDEOGRAPH
+0x90DC 0x611C #CJK UNIFIED IDEOGRAPH
+0x90DD 0x611D #CJK UNIFIED IDEOGRAPH
+0x90DE 0x611E #CJK UNIFIED IDEOGRAPH
+0x90DF 0x6121 #CJK UNIFIED IDEOGRAPH
+0x90E0 0x6122 #CJK UNIFIED IDEOGRAPH
+0x90E1 0x6125 #CJK UNIFIED IDEOGRAPH
+0x90E2 0x6128 #CJK UNIFIED IDEOGRAPH
+0x90E3 0x6129 #CJK UNIFIED IDEOGRAPH
+0x90E4 0x612A #CJK UNIFIED IDEOGRAPH
+0x90E5 0x612C #CJK UNIFIED IDEOGRAPH
+0x90E6 0x612D #CJK UNIFIED IDEOGRAPH
+0x90E7 0x612E #CJK UNIFIED IDEOGRAPH
+0x90E8 0x612F #CJK UNIFIED IDEOGRAPH
+0x90E9 0x6130 #CJK UNIFIED IDEOGRAPH
+0x90EA 0x6131 #CJK UNIFIED IDEOGRAPH
+0x90EB 0x6132 #CJK UNIFIED IDEOGRAPH
+0x90EC 0x6133 #CJK UNIFIED IDEOGRAPH
+0x90ED 0x6134 #CJK UNIFIED IDEOGRAPH
+0x90EE 0x6135 #CJK UNIFIED IDEOGRAPH
+0x90EF 0x6136 #CJK UNIFIED IDEOGRAPH
+0x90F0 0x6137 #CJK UNIFIED IDEOGRAPH
+0x90F1 0x6138 #CJK UNIFIED IDEOGRAPH
+0x90F2 0x6139 #CJK UNIFIED IDEOGRAPH
+0x90F3 0x613A #CJK UNIFIED IDEOGRAPH
+0x90F4 0x613B #CJK UNIFIED IDEOGRAPH
+0x90F5 0x613C #CJK UNIFIED IDEOGRAPH
+0x90F6 0x613D #CJK UNIFIED IDEOGRAPH
+0x90F7 0x613E #CJK UNIFIED IDEOGRAPH
+0x90F8 0x6140 #CJK UNIFIED IDEOGRAPH
+0x90F9 0x6141 #CJK UNIFIED IDEOGRAPH
+0x90FA 0x6142 #CJK UNIFIED IDEOGRAPH
+0x90FB 0x6143 #CJK UNIFIED IDEOGRAPH
+0x90FC 0x6144 #CJK UNIFIED IDEOGRAPH
+0x90FD 0x6145 #CJK UNIFIED IDEOGRAPH
+0x90FE 0x6146 #CJK UNIFIED IDEOGRAPH
+0x9140 0x6147 #CJK UNIFIED IDEOGRAPH
+0x9141 0x6149 #CJK UNIFIED IDEOGRAPH
+0x9142 0x614B #CJK UNIFIED IDEOGRAPH
+0x9143 0x614D #CJK UNIFIED IDEOGRAPH
+0x9144 0x614F #CJK UNIFIED IDEOGRAPH
+0x9145 0x6150 #CJK UNIFIED IDEOGRAPH
+0x9146 0x6152 #CJK UNIFIED IDEOGRAPH
+0x9147 0x6153 #CJK UNIFIED IDEOGRAPH
+0x9148 0x6154 #CJK UNIFIED IDEOGRAPH
+0x9149 0x6156 #CJK UNIFIED IDEOGRAPH
+0x914A 0x6157 #CJK UNIFIED IDEOGRAPH
+0x914B 0x6158 #CJK UNIFIED IDEOGRAPH
+0x914C 0x6159 #CJK UNIFIED IDEOGRAPH
+0x914D 0x615A #CJK UNIFIED IDEOGRAPH
+0x914E 0x615B #CJK UNIFIED IDEOGRAPH
+0x914F 0x615C #CJK UNIFIED IDEOGRAPH
+0x9150 0x615E #CJK UNIFIED IDEOGRAPH
+0x9151 0x615F #CJK UNIFIED IDEOGRAPH
+0x9152 0x6160 #CJK UNIFIED IDEOGRAPH
+0x9153 0x6161 #CJK UNIFIED IDEOGRAPH
+0x9154 0x6163 #CJK UNIFIED IDEOGRAPH
+0x9155 0x6164 #CJK UNIFIED IDEOGRAPH
+0x9156 0x6165 #CJK UNIFIED IDEOGRAPH
+0x9157 0x6166 #CJK UNIFIED IDEOGRAPH
+0x9158 0x6169 #CJK UNIFIED IDEOGRAPH
+0x9159 0x616A #CJK UNIFIED IDEOGRAPH
+0x915A 0x616B #CJK UNIFIED IDEOGRAPH
+0x915B 0x616C #CJK UNIFIED IDEOGRAPH
+0x915C 0x616D #CJK UNIFIED IDEOGRAPH
+0x915D 0x616E #CJK UNIFIED IDEOGRAPH
+0x915E 0x616F #CJK UNIFIED IDEOGRAPH
+0x915F 0x6171 #CJK UNIFIED IDEOGRAPH
+0x9160 0x6172 #CJK UNIFIED IDEOGRAPH
+0x9161 0x6173 #CJK UNIFIED IDEOGRAPH
+0x9162 0x6174 #CJK UNIFIED IDEOGRAPH
+0x9163 0x6176 #CJK UNIFIED IDEOGRAPH
+0x9164 0x6178 #CJK UNIFIED IDEOGRAPH
+0x9165 0x6179 #CJK UNIFIED IDEOGRAPH
+0x9166 0x617A #CJK UNIFIED IDEOGRAPH
+0x9167 0x617B #CJK UNIFIED IDEOGRAPH
+0x9168 0x617C #CJK UNIFIED IDEOGRAPH
+0x9169 0x617D #CJK UNIFIED IDEOGRAPH
+0x916A 0x617E #CJK UNIFIED IDEOGRAPH
+0x916B 0x617F #CJK UNIFIED IDEOGRAPH
+0x916C 0x6180 #CJK UNIFIED IDEOGRAPH
+0x916D 0x6181 #CJK UNIFIED IDEOGRAPH
+0x916E 0x6182 #CJK UNIFIED IDEOGRAPH
+0x916F 0x6183 #CJK UNIFIED IDEOGRAPH
+0x9170 0x6184 #CJK UNIFIED IDEOGRAPH
+0x9171 0x6185 #CJK UNIFIED IDEOGRAPH
+0x9172 0x6186 #CJK UNIFIED IDEOGRAPH
+0x9173 0x6187 #CJK UNIFIED IDEOGRAPH
+0x9174 0x6188 #CJK UNIFIED IDEOGRAPH
+0x9175 0x6189 #CJK UNIFIED IDEOGRAPH
+0x9176 0x618A #CJK UNIFIED IDEOGRAPH
+0x9177 0x618C #CJK UNIFIED IDEOGRAPH
+0x9178 0x618D #CJK UNIFIED IDEOGRAPH
+0x9179 0x618F #CJK UNIFIED IDEOGRAPH
+0x917A 0x6190 #CJK UNIFIED IDEOGRAPH
+0x917B 0x6191 #CJK UNIFIED IDEOGRAPH
+0x917C 0x6192 #CJK UNIFIED IDEOGRAPH
+0x917D 0x6193 #CJK UNIFIED IDEOGRAPH
+0x917E 0x6195 #CJK UNIFIED IDEOGRAPH
+0x9180 0x6196 #CJK UNIFIED IDEOGRAPH
+0x9181 0x6197 #CJK UNIFIED IDEOGRAPH
+0x9182 0x6198 #CJK UNIFIED IDEOGRAPH
+0x9183 0x6199 #CJK UNIFIED IDEOGRAPH
+0x9184 0x619A #CJK UNIFIED IDEOGRAPH
+0x9185 0x619B #CJK UNIFIED IDEOGRAPH
+0x9186 0x619C #CJK UNIFIED IDEOGRAPH
+0x9187 0x619E #CJK UNIFIED IDEOGRAPH
+0x9188 0x619F #CJK UNIFIED IDEOGRAPH
+0x9189 0x61A0 #CJK UNIFIED IDEOGRAPH
+0x918A 0x61A1 #CJK UNIFIED IDEOGRAPH
+0x918B 0x61A2 #CJK UNIFIED IDEOGRAPH
+0x918C 0x61A3 #CJK UNIFIED IDEOGRAPH
+0x918D 0x61A4 #CJK UNIFIED IDEOGRAPH
+0x918E 0x61A5 #CJK UNIFIED IDEOGRAPH
+0x918F 0x61A6 #CJK UNIFIED IDEOGRAPH
+0x9190 0x61AA #CJK UNIFIED IDEOGRAPH
+0x9191 0x61AB #CJK UNIFIED IDEOGRAPH
+0x9192 0x61AD #CJK UNIFIED IDEOGRAPH
+0x9193 0x61AE #CJK UNIFIED IDEOGRAPH
+0x9194 0x61AF #CJK UNIFIED IDEOGRAPH
+0x9195 0x61B0 #CJK UNIFIED IDEOGRAPH
+0x9196 0x61B1 #CJK UNIFIED IDEOGRAPH
+0x9197 0x61B2 #CJK UNIFIED IDEOGRAPH
+0x9198 0x61B3 #CJK UNIFIED IDEOGRAPH
+0x9199 0x61B4 #CJK UNIFIED IDEOGRAPH
+0x919A 0x61B5 #CJK UNIFIED IDEOGRAPH
+0x919B 0x61B6 #CJK UNIFIED IDEOGRAPH
+0x919C 0x61B8 #CJK UNIFIED IDEOGRAPH
+0x919D 0x61B9 #CJK UNIFIED IDEOGRAPH
+0x919E 0x61BA #CJK UNIFIED IDEOGRAPH
+0x919F 0x61BB #CJK UNIFIED IDEOGRAPH
+0x91A0 0x61BC #CJK UNIFIED IDEOGRAPH
+0x91A1 0x61BD #CJK UNIFIED IDEOGRAPH
+0x91A2 0x61BF #CJK UNIFIED IDEOGRAPH
+0x91A3 0x61C0 #CJK UNIFIED IDEOGRAPH
+0x91A4 0x61C1 #CJK UNIFIED IDEOGRAPH
+0x91A5 0x61C3 #CJK UNIFIED IDEOGRAPH
+0x91A6 0x61C4 #CJK UNIFIED IDEOGRAPH
+0x91A7 0x61C5 #CJK UNIFIED IDEOGRAPH
+0x91A8 0x61C6 #CJK UNIFIED IDEOGRAPH
+0x91A9 0x61C7 #CJK UNIFIED IDEOGRAPH
+0x91AA 0x61C9 #CJK UNIFIED IDEOGRAPH
+0x91AB 0x61CC #CJK UNIFIED IDEOGRAPH
+0x91AC 0x61CD #CJK UNIFIED IDEOGRAPH
+0x91AD 0x61CE #CJK UNIFIED IDEOGRAPH
+0x91AE 0x61CF #CJK UNIFIED IDEOGRAPH
+0x91AF 0x61D0 #CJK UNIFIED IDEOGRAPH
+0x91B0 0x61D3 #CJK UNIFIED IDEOGRAPH
+0x91B1 0x61D5 #CJK UNIFIED IDEOGRAPH
+0x91B2 0x61D6 #CJK UNIFIED IDEOGRAPH
+0x91B3 0x61D7 #CJK UNIFIED IDEOGRAPH
+0x91B4 0x61D8 #CJK UNIFIED IDEOGRAPH
+0x91B5 0x61D9 #CJK UNIFIED IDEOGRAPH
+0x91B6 0x61DA #CJK UNIFIED IDEOGRAPH
+0x91B7 0x61DB #CJK UNIFIED IDEOGRAPH
+0x91B8 0x61DC #CJK UNIFIED IDEOGRAPH
+0x91B9 0x61DD #CJK UNIFIED IDEOGRAPH
+0x91BA 0x61DE #CJK UNIFIED IDEOGRAPH
+0x91BB 0x61DF #CJK UNIFIED IDEOGRAPH
+0x91BC 0x61E0 #CJK UNIFIED IDEOGRAPH
+0x91BD 0x61E1 #CJK UNIFIED IDEOGRAPH
+0x91BE 0x61E2 #CJK UNIFIED IDEOGRAPH
+0x91BF 0x61E3 #CJK UNIFIED IDEOGRAPH
+0x91C0 0x61E4 #CJK UNIFIED IDEOGRAPH
+0x91C1 0x61E5 #CJK UNIFIED IDEOGRAPH
+0x91C2 0x61E7 #CJK UNIFIED IDEOGRAPH
+0x91C3 0x61E8 #CJK UNIFIED IDEOGRAPH
+0x91C4 0x61E9 #CJK UNIFIED IDEOGRAPH
+0x91C5 0x61EA #CJK UNIFIED IDEOGRAPH
+0x91C6 0x61EB #CJK UNIFIED IDEOGRAPH
+0x91C7 0x61EC #CJK UNIFIED IDEOGRAPH
+0x91C8 0x61ED #CJK UNIFIED IDEOGRAPH
+0x91C9 0x61EE #CJK UNIFIED IDEOGRAPH
+0x91CA 0x61EF #CJK UNIFIED IDEOGRAPH
+0x91CB 0x61F0 #CJK UNIFIED IDEOGRAPH
+0x91CC 0x61F1 #CJK UNIFIED IDEOGRAPH
+0x91CD 0x61F2 #CJK UNIFIED IDEOGRAPH
+0x91CE 0x61F3 #CJK UNIFIED IDEOGRAPH
+0x91CF 0x61F4 #CJK UNIFIED IDEOGRAPH
+0x91D0 0x61F6 #CJK UNIFIED IDEOGRAPH
+0x91D1 0x61F7 #CJK UNIFIED IDEOGRAPH
+0x91D2 0x61F8 #CJK UNIFIED IDEOGRAPH
+0x91D3 0x61F9 #CJK UNIFIED IDEOGRAPH
+0x91D4 0x61FA #CJK UNIFIED IDEOGRAPH
+0x91D5 0x61FB #CJK UNIFIED IDEOGRAPH
+0x91D6 0x61FC #CJK UNIFIED IDEOGRAPH
+0x91D7 0x61FD #CJK UNIFIED IDEOGRAPH
+0x91D8 0x61FE #CJK UNIFIED IDEOGRAPH
+0x91D9 0x6200 #CJK UNIFIED IDEOGRAPH
+0x91DA 0x6201 #CJK UNIFIED IDEOGRAPH
+0x91DB 0x6202 #CJK UNIFIED IDEOGRAPH
+0x91DC 0x6203 #CJK UNIFIED IDEOGRAPH
+0x91DD 0x6204 #CJK UNIFIED IDEOGRAPH
+0x91DE 0x6205 #CJK UNIFIED IDEOGRAPH
+0x91DF 0x6207 #CJK UNIFIED IDEOGRAPH
+0x91E0 0x6209 #CJK UNIFIED IDEOGRAPH
+0x91E1 0x6213 #CJK UNIFIED IDEOGRAPH
+0x91E2 0x6214 #CJK UNIFIED IDEOGRAPH
+0x91E3 0x6219 #CJK UNIFIED IDEOGRAPH
+0x91E4 0x621C #CJK UNIFIED IDEOGRAPH
+0x91E5 0x621D #CJK UNIFIED IDEOGRAPH
+0x91E6 0x621E #CJK UNIFIED IDEOGRAPH
+0x91E7 0x6220 #CJK UNIFIED IDEOGRAPH
+0x91E8 0x6223 #CJK UNIFIED IDEOGRAPH
+0x91E9 0x6226 #CJK UNIFIED IDEOGRAPH
+0x91EA 0x6227 #CJK UNIFIED IDEOGRAPH
+0x91EB 0x6228 #CJK UNIFIED IDEOGRAPH
+0x91EC 0x6229 #CJK UNIFIED IDEOGRAPH
+0x91ED 0x622B #CJK UNIFIED IDEOGRAPH
+0x91EE 0x622D #CJK UNIFIED IDEOGRAPH
+0x91EF 0x622F #CJK UNIFIED IDEOGRAPH
+0x91F0 0x6230 #CJK UNIFIED IDEOGRAPH
+0x91F1 0x6231 #CJK UNIFIED IDEOGRAPH
+0x91F2 0x6232 #CJK UNIFIED IDEOGRAPH
+0x91F3 0x6235 #CJK UNIFIED IDEOGRAPH
+0x91F4 0x6236 #CJK UNIFIED IDEOGRAPH
+0x91F5 0x6238 #CJK UNIFIED IDEOGRAPH
+0x91F6 0x6239 #CJK UNIFIED IDEOGRAPH
+0x91F7 0x623A #CJK UNIFIED IDEOGRAPH
+0x91F8 0x623B #CJK UNIFIED IDEOGRAPH
+0x91F9 0x623C #CJK UNIFIED IDEOGRAPH
+0x91FA 0x6242 #CJK UNIFIED IDEOGRAPH
+0x91FB 0x6244 #CJK UNIFIED IDEOGRAPH
+0x91FC 0x6245 #CJK UNIFIED IDEOGRAPH
+0x91FD 0x6246 #CJK UNIFIED IDEOGRAPH
+0x91FE 0x624A #CJK UNIFIED IDEOGRAPH
+0x9240 0x624F #CJK UNIFIED IDEOGRAPH
+0x9241 0x6250 #CJK UNIFIED IDEOGRAPH
+0x9242 0x6255 #CJK UNIFIED IDEOGRAPH
+0x9243 0x6256 #CJK UNIFIED IDEOGRAPH
+0x9244 0x6257 #CJK UNIFIED IDEOGRAPH
+0x9245 0x6259 #CJK UNIFIED IDEOGRAPH
+0x9246 0x625A #CJK UNIFIED IDEOGRAPH
+0x9247 0x625C #CJK UNIFIED IDEOGRAPH
+0x9248 0x625D #CJK UNIFIED IDEOGRAPH
+0x9249 0x625E #CJK UNIFIED IDEOGRAPH
+0x924A 0x625F #CJK UNIFIED IDEOGRAPH
+0x924B 0x6260 #CJK UNIFIED IDEOGRAPH
+0x924C 0x6261 #CJK UNIFIED IDEOGRAPH
+0x924D 0x6262 #CJK UNIFIED IDEOGRAPH
+0x924E 0x6264 #CJK UNIFIED IDEOGRAPH
+0x924F 0x6265 #CJK UNIFIED IDEOGRAPH
+0x9250 0x6268 #CJK UNIFIED IDEOGRAPH
+0x9251 0x6271 #CJK UNIFIED IDEOGRAPH
+0x9252 0x6272 #CJK UNIFIED IDEOGRAPH
+0x9253 0x6274 #CJK UNIFIED IDEOGRAPH
+0x9254 0x6275 #CJK UNIFIED IDEOGRAPH
+0x9255 0x6277 #CJK UNIFIED IDEOGRAPH
+0x9256 0x6278 #CJK UNIFIED IDEOGRAPH
+0x9257 0x627A #CJK UNIFIED IDEOGRAPH
+0x9258 0x627B #CJK UNIFIED IDEOGRAPH
+0x9259 0x627D #CJK UNIFIED IDEOGRAPH
+0x925A 0x6281 #CJK UNIFIED IDEOGRAPH
+0x925B 0x6282 #CJK UNIFIED IDEOGRAPH
+0x925C 0x6283 #CJK UNIFIED IDEOGRAPH
+0x925D 0x6285 #CJK UNIFIED IDEOGRAPH
+0x925E 0x6286 #CJK UNIFIED IDEOGRAPH
+0x925F 0x6287 #CJK UNIFIED IDEOGRAPH
+0x9260 0x6288 #CJK UNIFIED IDEOGRAPH
+0x9261 0x628B #CJK UNIFIED IDEOGRAPH
+0x9262 0x628C #CJK UNIFIED IDEOGRAPH
+0x9263 0x628D #CJK UNIFIED IDEOGRAPH
+0x9264 0x628E #CJK UNIFIED IDEOGRAPH
+0x9265 0x628F #CJK UNIFIED IDEOGRAPH
+0x9266 0x6290 #CJK UNIFIED IDEOGRAPH
+0x9267 0x6294 #CJK UNIFIED IDEOGRAPH
+0x9268 0x6299 #CJK UNIFIED IDEOGRAPH
+0x9269 0x629C #CJK UNIFIED IDEOGRAPH
+0x926A 0x629D #CJK UNIFIED IDEOGRAPH
+0x926B 0x629E #CJK UNIFIED IDEOGRAPH
+0x926C 0x62A3 #CJK UNIFIED IDEOGRAPH
+0x926D 0x62A6 #CJK UNIFIED IDEOGRAPH
+0x926E 0x62A7 #CJK UNIFIED IDEOGRAPH
+0x926F 0x62A9 #CJK UNIFIED IDEOGRAPH
+0x9270 0x62AA #CJK UNIFIED IDEOGRAPH
+0x9271 0x62AD #CJK UNIFIED IDEOGRAPH
+0x9272 0x62AE #CJK UNIFIED IDEOGRAPH
+0x9273 0x62AF #CJK UNIFIED IDEOGRAPH
+0x9274 0x62B0 #CJK UNIFIED IDEOGRAPH
+0x9275 0x62B2 #CJK UNIFIED IDEOGRAPH
+0x9276 0x62B3 #CJK UNIFIED IDEOGRAPH
+0x9277 0x62B4 #CJK UNIFIED IDEOGRAPH
+0x9278 0x62B6 #CJK UNIFIED IDEOGRAPH
+0x9279 0x62B7 #CJK UNIFIED IDEOGRAPH
+0x927A 0x62B8 #CJK UNIFIED IDEOGRAPH
+0x927B 0x62BA #CJK UNIFIED IDEOGRAPH
+0x927C 0x62BE #CJK UNIFIED IDEOGRAPH
+0x927D 0x62C0 #CJK UNIFIED IDEOGRAPH
+0x927E 0x62C1 #CJK UNIFIED IDEOGRAPH
+0x9280 0x62C3 #CJK UNIFIED IDEOGRAPH
+0x9281 0x62CB #CJK UNIFIED IDEOGRAPH
+0x9282 0x62CF #CJK UNIFIED IDEOGRAPH
+0x9283 0x62D1 #CJK UNIFIED IDEOGRAPH
+0x9284 0x62D5 #CJK UNIFIED IDEOGRAPH
+0x9285 0x62DD #CJK UNIFIED IDEOGRAPH
+0x9286 0x62DE #CJK UNIFIED IDEOGRAPH
+0x9287 0x62E0 #CJK UNIFIED IDEOGRAPH
+0x9288 0x62E1 #CJK UNIFIED IDEOGRAPH
+0x9289 0x62E4 #CJK UNIFIED IDEOGRAPH
+0x928A 0x62EA #CJK UNIFIED IDEOGRAPH
+0x928B 0x62EB #CJK UNIFIED IDEOGRAPH
+0x928C 0x62F0 #CJK UNIFIED IDEOGRAPH
+0x928D 0x62F2 #CJK UNIFIED IDEOGRAPH
+0x928E 0x62F5 #CJK UNIFIED IDEOGRAPH
+0x928F 0x62F8 #CJK UNIFIED IDEOGRAPH
+0x9290 0x62F9 #CJK UNIFIED IDEOGRAPH
+0x9291 0x62FA #CJK UNIFIED IDEOGRAPH
+0x9292 0x62FB #CJK UNIFIED IDEOGRAPH
+0x9293 0x6300 #CJK UNIFIED IDEOGRAPH
+0x9294 0x6303 #CJK UNIFIED IDEOGRAPH
+0x9295 0x6304 #CJK UNIFIED IDEOGRAPH
+0x9296 0x6305 #CJK UNIFIED IDEOGRAPH
+0x9297 0x6306 #CJK UNIFIED IDEOGRAPH
+0x9298 0x630A #CJK UNIFIED IDEOGRAPH
+0x9299 0x630B #CJK UNIFIED IDEOGRAPH
+0x929A 0x630C #CJK UNIFIED IDEOGRAPH
+0x929B 0x630D #CJK UNIFIED IDEOGRAPH
+0x929C 0x630F #CJK UNIFIED IDEOGRAPH
+0x929D 0x6310 #CJK UNIFIED IDEOGRAPH
+0x929E 0x6312 #CJK UNIFIED IDEOGRAPH
+0x929F 0x6313 #CJK UNIFIED IDEOGRAPH
+0x92A0 0x6314 #CJK UNIFIED IDEOGRAPH
+0x92A1 0x6315 #CJK UNIFIED IDEOGRAPH
+0x92A2 0x6317 #CJK UNIFIED IDEOGRAPH
+0x92A3 0x6318 #CJK UNIFIED IDEOGRAPH
+0x92A4 0x6319 #CJK UNIFIED IDEOGRAPH
+0x92A5 0x631C #CJK UNIFIED IDEOGRAPH
+0x92A6 0x6326 #CJK UNIFIED IDEOGRAPH
+0x92A7 0x6327 #CJK UNIFIED IDEOGRAPH
+0x92A8 0x6329 #CJK UNIFIED IDEOGRAPH
+0x92A9 0x632C #CJK UNIFIED IDEOGRAPH
+0x92AA 0x632D #CJK UNIFIED IDEOGRAPH
+0x92AB 0x632E #CJK UNIFIED IDEOGRAPH
+0x92AC 0x6330 #CJK UNIFIED IDEOGRAPH
+0x92AD 0x6331 #CJK UNIFIED IDEOGRAPH
+0x92AE 0x6333 #CJK UNIFIED IDEOGRAPH
+0x92AF 0x6334 #CJK UNIFIED IDEOGRAPH
+0x92B0 0x6335 #CJK UNIFIED IDEOGRAPH
+0x92B1 0x6336 #CJK UNIFIED IDEOGRAPH
+0x92B2 0x6337 #CJK UNIFIED IDEOGRAPH
+0x92B3 0x6338 #CJK UNIFIED IDEOGRAPH
+0x92B4 0x633B #CJK UNIFIED IDEOGRAPH
+0x92B5 0x633C #CJK UNIFIED IDEOGRAPH
+0x92B6 0x633E #CJK UNIFIED IDEOGRAPH
+0x92B7 0x633F #CJK UNIFIED IDEOGRAPH
+0x92B8 0x6340 #CJK UNIFIED IDEOGRAPH
+0x92B9 0x6341 #CJK UNIFIED IDEOGRAPH
+0x92BA 0x6344 #CJK UNIFIED IDEOGRAPH
+0x92BB 0x6347 #CJK UNIFIED IDEOGRAPH
+0x92BC 0x6348 #CJK UNIFIED IDEOGRAPH
+0x92BD 0x634A #CJK UNIFIED IDEOGRAPH
+0x92BE 0x6351 #CJK UNIFIED IDEOGRAPH
+0x92BF 0x6352 #CJK UNIFIED IDEOGRAPH
+0x92C0 0x6353 #CJK UNIFIED IDEOGRAPH
+0x92C1 0x6354 #CJK UNIFIED IDEOGRAPH
+0x92C2 0x6356 #CJK UNIFIED IDEOGRAPH
+0x92C3 0x6357 #CJK UNIFIED IDEOGRAPH
+0x92C4 0x6358 #CJK UNIFIED IDEOGRAPH
+0x92C5 0x6359 #CJK UNIFIED IDEOGRAPH
+0x92C6 0x635A #CJK UNIFIED IDEOGRAPH
+0x92C7 0x635B #CJK UNIFIED IDEOGRAPH
+0x92C8 0x635C #CJK UNIFIED IDEOGRAPH
+0x92C9 0x635D #CJK UNIFIED IDEOGRAPH
+0x92CA 0x6360 #CJK UNIFIED IDEOGRAPH
+0x92CB 0x6364 #CJK UNIFIED IDEOGRAPH
+0x92CC 0x6365 #CJK UNIFIED IDEOGRAPH
+0x92CD 0x6366 #CJK UNIFIED IDEOGRAPH
+0x92CE 0x6368 #CJK UNIFIED IDEOGRAPH
+0x92CF 0x636A #CJK UNIFIED IDEOGRAPH
+0x92D0 0x636B #CJK UNIFIED IDEOGRAPH
+0x92D1 0x636C #CJK UNIFIED IDEOGRAPH
+0x92D2 0x636F #CJK UNIFIED IDEOGRAPH
+0x92D3 0x6370 #CJK UNIFIED IDEOGRAPH
+0x92D4 0x6372 #CJK UNIFIED IDEOGRAPH
+0x92D5 0x6373 #CJK UNIFIED IDEOGRAPH
+0x92D6 0x6374 #CJK UNIFIED IDEOGRAPH
+0x92D7 0x6375 #CJK UNIFIED IDEOGRAPH
+0x92D8 0x6378 #CJK UNIFIED IDEOGRAPH
+0x92D9 0x6379 #CJK UNIFIED IDEOGRAPH
+0x92DA 0x637C #CJK UNIFIED IDEOGRAPH
+0x92DB 0x637D #CJK UNIFIED IDEOGRAPH
+0x92DC 0x637E #CJK UNIFIED IDEOGRAPH
+0x92DD 0x637F #CJK UNIFIED IDEOGRAPH
+0x92DE 0x6381 #CJK UNIFIED IDEOGRAPH
+0x92DF 0x6383 #CJK UNIFIED IDEOGRAPH
+0x92E0 0x6384 #CJK UNIFIED IDEOGRAPH
+0x92E1 0x6385 #CJK UNIFIED IDEOGRAPH
+0x92E2 0x6386 #CJK UNIFIED IDEOGRAPH
+0x92E3 0x638B #CJK UNIFIED IDEOGRAPH
+0x92E4 0x638D #CJK UNIFIED IDEOGRAPH
+0x92E5 0x6391 #CJK UNIFIED IDEOGRAPH
+0x92E6 0x6393 #CJK UNIFIED IDEOGRAPH
+0x92E7 0x6394 #CJK UNIFIED IDEOGRAPH
+0x92E8 0x6395 #CJK UNIFIED IDEOGRAPH
+0x92E9 0x6397 #CJK UNIFIED IDEOGRAPH
+0x92EA 0x6399 #CJK UNIFIED IDEOGRAPH
+0x92EB 0x639A #CJK UNIFIED IDEOGRAPH
+0x92EC 0x639B #CJK UNIFIED IDEOGRAPH
+0x92ED 0x639C #CJK UNIFIED IDEOGRAPH
+0x92EE 0x639D #CJK UNIFIED IDEOGRAPH
+0x92EF 0x639E #CJK UNIFIED IDEOGRAPH
+0x92F0 0x639F #CJK UNIFIED IDEOGRAPH
+0x92F1 0x63A1 #CJK UNIFIED IDEOGRAPH
+0x92F2 0x63A4 #CJK UNIFIED IDEOGRAPH
+0x92F3 0x63A6 #CJK UNIFIED IDEOGRAPH
+0x92F4 0x63AB #CJK UNIFIED IDEOGRAPH
+0x92F5 0x63AF #CJK UNIFIED IDEOGRAPH
+0x92F6 0x63B1 #CJK UNIFIED IDEOGRAPH
+0x92F7 0x63B2 #CJK UNIFIED IDEOGRAPH
+0x92F8 0x63B5 #CJK UNIFIED IDEOGRAPH
+0x92F9 0x63B6 #CJK UNIFIED IDEOGRAPH
+0x92FA 0x63B9 #CJK UNIFIED IDEOGRAPH
+0x92FB 0x63BB #CJK UNIFIED IDEOGRAPH
+0x92FC 0x63BD #CJK UNIFIED IDEOGRAPH
+0x92FD 0x63BF #CJK UNIFIED IDEOGRAPH
+0x92FE 0x63C0 #CJK UNIFIED IDEOGRAPH
+0x9340 0x63C1 #CJK UNIFIED IDEOGRAPH
+0x9341 0x63C2 #CJK UNIFIED IDEOGRAPH
+0x9342 0x63C3 #CJK UNIFIED IDEOGRAPH
+0x9343 0x63C5 #CJK UNIFIED IDEOGRAPH
+0x9344 0x63C7 #CJK UNIFIED IDEOGRAPH
+0x9345 0x63C8 #CJK UNIFIED IDEOGRAPH
+0x9346 0x63CA #CJK UNIFIED IDEOGRAPH
+0x9347 0x63CB #CJK UNIFIED IDEOGRAPH
+0x9348 0x63CC #CJK UNIFIED IDEOGRAPH
+0x9349 0x63D1 #CJK UNIFIED IDEOGRAPH
+0x934A 0x63D3 #CJK UNIFIED IDEOGRAPH
+0x934B 0x63D4 #CJK UNIFIED IDEOGRAPH
+0x934C 0x63D5 #CJK UNIFIED IDEOGRAPH
+0x934D 0x63D7 #CJK UNIFIED IDEOGRAPH
+0x934E 0x63D8 #CJK UNIFIED IDEOGRAPH
+0x934F 0x63D9 #CJK UNIFIED IDEOGRAPH
+0x9350 0x63DA #CJK UNIFIED IDEOGRAPH
+0x9351 0x63DB #CJK UNIFIED IDEOGRAPH
+0x9352 0x63DC #CJK UNIFIED IDEOGRAPH
+0x9353 0x63DD #CJK UNIFIED IDEOGRAPH
+0x9354 0x63DF #CJK UNIFIED IDEOGRAPH
+0x9355 0x63E2 #CJK UNIFIED IDEOGRAPH
+0x9356 0x63E4 #CJK UNIFIED IDEOGRAPH
+0x9357 0x63E5 #CJK UNIFIED IDEOGRAPH
+0x9358 0x63E6 #CJK UNIFIED IDEOGRAPH
+0x9359 0x63E7 #CJK UNIFIED IDEOGRAPH
+0x935A 0x63E8 #CJK UNIFIED IDEOGRAPH
+0x935B 0x63EB #CJK UNIFIED IDEOGRAPH
+0x935C 0x63EC #CJK UNIFIED IDEOGRAPH
+0x935D 0x63EE #CJK UNIFIED IDEOGRAPH
+0x935E 0x63EF #CJK UNIFIED IDEOGRAPH
+0x935F 0x63F0 #CJK UNIFIED IDEOGRAPH
+0x9360 0x63F1 #CJK UNIFIED IDEOGRAPH
+0x9361 0x63F3 #CJK UNIFIED IDEOGRAPH
+0x9362 0x63F5 #CJK UNIFIED IDEOGRAPH
+0x9363 0x63F7 #CJK UNIFIED IDEOGRAPH
+0x9364 0x63F9 #CJK UNIFIED IDEOGRAPH
+0x9365 0x63FA #CJK UNIFIED IDEOGRAPH
+0x9366 0x63FB #CJK UNIFIED IDEOGRAPH
+0x9367 0x63FC #CJK UNIFIED IDEOGRAPH
+0x9368 0x63FE #CJK UNIFIED IDEOGRAPH
+0x9369 0x6403 #CJK UNIFIED IDEOGRAPH
+0x936A 0x6404 #CJK UNIFIED IDEOGRAPH
+0x936B 0x6406 #CJK UNIFIED IDEOGRAPH
+0x936C 0x6407 #CJK UNIFIED IDEOGRAPH
+0x936D 0x6408 #CJK UNIFIED IDEOGRAPH
+0x936E 0x6409 #CJK UNIFIED IDEOGRAPH
+0x936F 0x640A #CJK UNIFIED IDEOGRAPH
+0x9370 0x640D #CJK UNIFIED IDEOGRAPH
+0x9371 0x640E #CJK UNIFIED IDEOGRAPH
+0x9372 0x6411 #CJK UNIFIED IDEOGRAPH
+0x9373 0x6412 #CJK UNIFIED IDEOGRAPH
+0x9374 0x6415 #CJK UNIFIED IDEOGRAPH
+0x9375 0x6416 #CJK UNIFIED IDEOGRAPH
+0x9376 0x6417 #CJK UNIFIED IDEOGRAPH
+0x9377 0x6418 #CJK UNIFIED IDEOGRAPH
+0x9378 0x6419 #CJK UNIFIED IDEOGRAPH
+0x9379 0x641A #CJK UNIFIED IDEOGRAPH
+0x937A 0x641D #CJK UNIFIED IDEOGRAPH
+0x937B 0x641F #CJK UNIFIED IDEOGRAPH
+0x937C 0x6422 #CJK UNIFIED IDEOGRAPH
+0x937D 0x6423 #CJK UNIFIED IDEOGRAPH
+0x937E 0x6424 #CJK UNIFIED IDEOGRAPH
+0x9380 0x6425 #CJK UNIFIED IDEOGRAPH
+0x9381 0x6427 #CJK UNIFIED IDEOGRAPH
+0x9382 0x6428 #CJK UNIFIED IDEOGRAPH
+0x9383 0x6429 #CJK UNIFIED IDEOGRAPH
+0x9384 0x642B #CJK UNIFIED IDEOGRAPH
+0x9385 0x642E #CJK UNIFIED IDEOGRAPH
+0x9386 0x642F #CJK UNIFIED IDEOGRAPH
+0x9387 0x6430 #CJK UNIFIED IDEOGRAPH
+0x9388 0x6431 #CJK UNIFIED IDEOGRAPH
+0x9389 0x6432 #CJK UNIFIED IDEOGRAPH
+0x938A 0x6433 #CJK UNIFIED IDEOGRAPH
+0x938B 0x6435 #CJK UNIFIED IDEOGRAPH
+0x938C 0x6436 #CJK UNIFIED IDEOGRAPH
+0x938D 0x6437 #CJK UNIFIED IDEOGRAPH
+0x938E 0x6438 #CJK UNIFIED IDEOGRAPH
+0x938F 0x6439 #CJK UNIFIED IDEOGRAPH
+0x9390 0x643B #CJK UNIFIED IDEOGRAPH
+0x9391 0x643C #CJK UNIFIED IDEOGRAPH
+0x9392 0x643E #CJK UNIFIED IDEOGRAPH
+0x9393 0x6440 #CJK UNIFIED IDEOGRAPH
+0x9394 0x6442 #CJK UNIFIED IDEOGRAPH
+0x9395 0x6443 #CJK UNIFIED IDEOGRAPH
+0x9396 0x6449 #CJK UNIFIED IDEOGRAPH
+0x9397 0x644B #CJK UNIFIED IDEOGRAPH
+0x9398 0x644C #CJK UNIFIED IDEOGRAPH
+0x9399 0x644D #CJK UNIFIED IDEOGRAPH
+0x939A 0x644E #CJK UNIFIED IDEOGRAPH
+0x939B 0x644F #CJK UNIFIED IDEOGRAPH
+0x939C 0x6450 #CJK UNIFIED IDEOGRAPH
+0x939D 0x6451 #CJK UNIFIED IDEOGRAPH
+0x939E 0x6453 #CJK UNIFIED IDEOGRAPH
+0x939F 0x6455 #CJK UNIFIED IDEOGRAPH
+0x93A0 0x6456 #CJK UNIFIED IDEOGRAPH
+0x93A1 0x6457 #CJK UNIFIED IDEOGRAPH
+0x93A2 0x6459 #CJK UNIFIED IDEOGRAPH
+0x93A3 0x645A #CJK UNIFIED IDEOGRAPH
+0x93A4 0x645B #CJK UNIFIED IDEOGRAPH
+0x93A5 0x645C #CJK UNIFIED IDEOGRAPH
+0x93A6 0x645D #CJK UNIFIED IDEOGRAPH
+0x93A7 0x645F #CJK UNIFIED IDEOGRAPH
+0x93A8 0x6460 #CJK UNIFIED IDEOGRAPH
+0x93A9 0x6461 #CJK UNIFIED IDEOGRAPH
+0x93AA 0x6462 #CJK UNIFIED IDEOGRAPH
+0x93AB 0x6463 #CJK UNIFIED IDEOGRAPH
+0x93AC 0x6464 #CJK UNIFIED IDEOGRAPH
+0x93AD 0x6465 #CJK UNIFIED IDEOGRAPH
+0x93AE 0x6466 #CJK UNIFIED IDEOGRAPH
+0x93AF 0x6468 #CJK UNIFIED IDEOGRAPH
+0x93B0 0x646A #CJK UNIFIED IDEOGRAPH
+0x93B1 0x646B #CJK UNIFIED IDEOGRAPH
+0x93B2 0x646C #CJK UNIFIED IDEOGRAPH
+0x93B3 0x646E #CJK UNIFIED IDEOGRAPH
+0x93B4 0x646F #CJK UNIFIED IDEOGRAPH
+0x93B5 0x6470 #CJK UNIFIED IDEOGRAPH
+0x93B6 0x6471 #CJK UNIFIED IDEOGRAPH
+0x93B7 0x6472 #CJK UNIFIED IDEOGRAPH
+0x93B8 0x6473 #CJK UNIFIED IDEOGRAPH
+0x93B9 0x6474 #CJK UNIFIED IDEOGRAPH
+0x93BA 0x6475 #CJK UNIFIED IDEOGRAPH
+0x93BB 0x6476 #CJK UNIFIED IDEOGRAPH
+0x93BC 0x6477 #CJK UNIFIED IDEOGRAPH
+0x93BD 0x647B #CJK UNIFIED IDEOGRAPH
+0x93BE 0x647C #CJK UNIFIED IDEOGRAPH
+0x93BF 0x647D #CJK UNIFIED IDEOGRAPH
+0x93C0 0x647E #CJK UNIFIED IDEOGRAPH
+0x93C1 0x647F #CJK UNIFIED IDEOGRAPH
+0x93C2 0x6480 #CJK UNIFIED IDEOGRAPH
+0x93C3 0x6481 #CJK UNIFIED IDEOGRAPH
+0x93C4 0x6483 #CJK UNIFIED IDEOGRAPH
+0x93C5 0x6486 #CJK UNIFIED IDEOGRAPH
+0x93C6 0x6488 #CJK UNIFIED IDEOGRAPH
+0x93C7 0x6489 #CJK UNIFIED IDEOGRAPH
+0x93C8 0x648A #CJK UNIFIED IDEOGRAPH
+0x93C9 0x648B #CJK UNIFIED IDEOGRAPH
+0x93CA 0x648C #CJK UNIFIED IDEOGRAPH
+0x93CB 0x648D #CJK UNIFIED IDEOGRAPH
+0x93CC 0x648E #CJK UNIFIED IDEOGRAPH
+0x93CD 0x648F #CJK UNIFIED IDEOGRAPH
+0x93CE 0x6490 #CJK UNIFIED IDEOGRAPH
+0x93CF 0x6493 #CJK UNIFIED IDEOGRAPH
+0x93D0 0x6494 #CJK UNIFIED IDEOGRAPH
+0x93D1 0x6497 #CJK UNIFIED IDEOGRAPH
+0x93D2 0x6498 #CJK UNIFIED IDEOGRAPH
+0x93D3 0x649A #CJK UNIFIED IDEOGRAPH
+0x93D4 0x649B #CJK UNIFIED IDEOGRAPH
+0x93D5 0x649C #CJK UNIFIED IDEOGRAPH
+0x93D6 0x649D #CJK UNIFIED IDEOGRAPH
+0x93D7 0x649F #CJK UNIFIED IDEOGRAPH
+0x93D8 0x64A0 #CJK UNIFIED IDEOGRAPH
+0x93D9 0x64A1 #CJK UNIFIED IDEOGRAPH
+0x93DA 0x64A2 #CJK UNIFIED IDEOGRAPH
+0x93DB 0x64A3 #CJK UNIFIED IDEOGRAPH
+0x93DC 0x64A5 #CJK UNIFIED IDEOGRAPH
+0x93DD 0x64A6 #CJK UNIFIED IDEOGRAPH
+0x93DE 0x64A7 #CJK UNIFIED IDEOGRAPH
+0x93DF 0x64A8 #CJK UNIFIED IDEOGRAPH
+0x93E0 0x64AA #CJK UNIFIED IDEOGRAPH
+0x93E1 0x64AB #CJK UNIFIED IDEOGRAPH
+0x93E2 0x64AF #CJK UNIFIED IDEOGRAPH
+0x93E3 0x64B1 #CJK UNIFIED IDEOGRAPH
+0x93E4 0x64B2 #CJK UNIFIED IDEOGRAPH
+0x93E5 0x64B3 #CJK UNIFIED IDEOGRAPH
+0x93E6 0x64B4 #CJK UNIFIED IDEOGRAPH
+0x93E7 0x64B6 #CJK UNIFIED IDEOGRAPH
+0x93E8 0x64B9 #CJK UNIFIED IDEOGRAPH
+0x93E9 0x64BB #CJK UNIFIED IDEOGRAPH
+0x93EA 0x64BD #CJK UNIFIED IDEOGRAPH
+0x93EB 0x64BE #CJK UNIFIED IDEOGRAPH
+0x93EC 0x64BF #CJK UNIFIED IDEOGRAPH
+0x93ED 0x64C1 #CJK UNIFIED IDEOGRAPH
+0x93EE 0x64C3 #CJK UNIFIED IDEOGRAPH
+0x93EF 0x64C4 #CJK UNIFIED IDEOGRAPH
+0x93F0 0x64C6 #CJK UNIFIED IDEOGRAPH
+0x93F1 0x64C7 #CJK UNIFIED IDEOGRAPH
+0x93F2 0x64C8 #CJK UNIFIED IDEOGRAPH
+0x93F3 0x64C9 #CJK UNIFIED IDEOGRAPH
+0x93F4 0x64CA #CJK UNIFIED IDEOGRAPH
+0x93F5 0x64CB #CJK UNIFIED IDEOGRAPH
+0x93F6 0x64CC #CJK UNIFIED IDEOGRAPH
+0x93F7 0x64CF #CJK UNIFIED IDEOGRAPH
+0x93F8 0x64D1 #CJK UNIFIED IDEOGRAPH
+0x93F9 0x64D3 #CJK UNIFIED IDEOGRAPH
+0x93FA 0x64D4 #CJK UNIFIED IDEOGRAPH
+0x93FB 0x64D5 #CJK UNIFIED IDEOGRAPH
+0x93FC 0x64D6 #CJK UNIFIED IDEOGRAPH
+0x93FD 0x64D9 #CJK UNIFIED IDEOGRAPH
+0x93FE 0x64DA #CJK UNIFIED IDEOGRAPH
+0x9440 0x64DB #CJK UNIFIED IDEOGRAPH
+0x9441 0x64DC #CJK UNIFIED IDEOGRAPH
+0x9442 0x64DD #CJK UNIFIED IDEOGRAPH
+0x9443 0x64DF #CJK UNIFIED IDEOGRAPH
+0x9444 0x64E0 #CJK UNIFIED IDEOGRAPH
+0x9445 0x64E1 #CJK UNIFIED IDEOGRAPH
+0x9446 0x64E3 #CJK UNIFIED IDEOGRAPH
+0x9447 0x64E5 #CJK UNIFIED IDEOGRAPH
+0x9448 0x64E7 #CJK UNIFIED IDEOGRAPH
+0x9449 0x64E8 #CJK UNIFIED IDEOGRAPH
+0x944A 0x64E9 #CJK UNIFIED IDEOGRAPH
+0x944B 0x64EA #CJK UNIFIED IDEOGRAPH
+0x944C 0x64EB #CJK UNIFIED IDEOGRAPH
+0x944D 0x64EC #CJK UNIFIED IDEOGRAPH
+0x944E 0x64ED #CJK UNIFIED IDEOGRAPH
+0x944F 0x64EE #CJK UNIFIED IDEOGRAPH
+0x9450 0x64EF #CJK UNIFIED IDEOGRAPH
+0x9451 0x64F0 #CJK UNIFIED IDEOGRAPH
+0x9452 0x64F1 #CJK UNIFIED IDEOGRAPH
+0x9453 0x64F2 #CJK UNIFIED IDEOGRAPH
+0x9454 0x64F3 #CJK UNIFIED IDEOGRAPH
+0x9455 0x64F4 #CJK UNIFIED IDEOGRAPH
+0x9456 0x64F5 #CJK UNIFIED IDEOGRAPH
+0x9457 0x64F6 #CJK UNIFIED IDEOGRAPH
+0x9458 0x64F7 #CJK UNIFIED IDEOGRAPH
+0x9459 0x64F8 #CJK UNIFIED IDEOGRAPH
+0x945A 0x64F9 #CJK UNIFIED IDEOGRAPH
+0x945B 0x64FA #CJK UNIFIED IDEOGRAPH
+0x945C 0x64FB #CJK UNIFIED IDEOGRAPH
+0x945D 0x64FC #CJK UNIFIED IDEOGRAPH
+0x945E 0x64FD #CJK UNIFIED IDEOGRAPH
+0x945F 0x64FE #CJK UNIFIED IDEOGRAPH
+0x9460 0x64FF #CJK UNIFIED IDEOGRAPH
+0x9461 0x6501 #CJK UNIFIED IDEOGRAPH
+0x9462 0x6502 #CJK UNIFIED IDEOGRAPH
+0x9463 0x6503 #CJK UNIFIED IDEOGRAPH
+0x9464 0x6504 #CJK UNIFIED IDEOGRAPH
+0x9465 0x6505 #CJK UNIFIED IDEOGRAPH
+0x9466 0x6506 #CJK UNIFIED IDEOGRAPH
+0x9467 0x6507 #CJK UNIFIED IDEOGRAPH
+0x9468 0x6508 #CJK UNIFIED IDEOGRAPH
+0x9469 0x650A #CJK UNIFIED IDEOGRAPH
+0x946A 0x650B #CJK UNIFIED IDEOGRAPH
+0x946B 0x650C #CJK UNIFIED IDEOGRAPH
+0x946C 0x650D #CJK UNIFIED IDEOGRAPH
+0x946D 0x650E #CJK UNIFIED IDEOGRAPH
+0x946E 0x650F #CJK UNIFIED IDEOGRAPH
+0x946F 0x6510 #CJK UNIFIED IDEOGRAPH
+0x9470 0x6511 #CJK UNIFIED IDEOGRAPH
+0x9471 0x6513 #CJK UNIFIED IDEOGRAPH
+0x9472 0x6514 #CJK UNIFIED IDEOGRAPH
+0x9473 0x6515 #CJK UNIFIED IDEOGRAPH
+0x9474 0x6516 #CJK UNIFIED IDEOGRAPH
+0x9475 0x6517 #CJK UNIFIED IDEOGRAPH
+0x9476 0x6519 #CJK UNIFIED IDEOGRAPH
+0x9477 0x651A #CJK UNIFIED IDEOGRAPH
+0x9478 0x651B #CJK UNIFIED IDEOGRAPH
+0x9479 0x651C #CJK UNIFIED IDEOGRAPH
+0x947A 0x651D #CJK UNIFIED IDEOGRAPH
+0x947B 0x651E #CJK UNIFIED IDEOGRAPH
+0x947C 0x651F #CJK UNIFIED IDEOGRAPH
+0x947D 0x6520 #CJK UNIFIED IDEOGRAPH
+0x947E 0x6521 #CJK UNIFIED IDEOGRAPH
+0x9480 0x6522 #CJK UNIFIED IDEOGRAPH
+0x9481 0x6523 #CJK UNIFIED IDEOGRAPH
+0x9482 0x6524 #CJK UNIFIED IDEOGRAPH
+0x9483 0x6526 #CJK UNIFIED IDEOGRAPH
+0x9484 0x6527 #CJK UNIFIED IDEOGRAPH
+0x9485 0x6528 #CJK UNIFIED IDEOGRAPH
+0x9486 0x6529 #CJK UNIFIED IDEOGRAPH
+0x9487 0x652A #CJK UNIFIED IDEOGRAPH
+0x9488 0x652C #CJK UNIFIED IDEOGRAPH
+0x9489 0x652D #CJK UNIFIED IDEOGRAPH
+0x948A 0x6530 #CJK UNIFIED IDEOGRAPH
+0x948B 0x6531 #CJK UNIFIED IDEOGRAPH
+0x948C 0x6532 #CJK UNIFIED IDEOGRAPH
+0x948D 0x6533 #CJK UNIFIED IDEOGRAPH
+0x948E 0x6537 #CJK UNIFIED IDEOGRAPH
+0x948F 0x653A #CJK UNIFIED IDEOGRAPH
+0x9490 0x653C #CJK UNIFIED IDEOGRAPH
+0x9491 0x653D #CJK UNIFIED IDEOGRAPH
+0x9492 0x6540 #CJK UNIFIED IDEOGRAPH
+0x9493 0x6541 #CJK UNIFIED IDEOGRAPH
+0x9494 0x6542 #CJK UNIFIED IDEOGRAPH
+0x9495 0x6543 #CJK UNIFIED IDEOGRAPH
+0x9496 0x6544 #CJK UNIFIED IDEOGRAPH
+0x9497 0x6546 #CJK UNIFIED IDEOGRAPH
+0x9498 0x6547 #CJK UNIFIED IDEOGRAPH
+0x9499 0x654A #CJK UNIFIED IDEOGRAPH
+0x949A 0x654B #CJK UNIFIED IDEOGRAPH
+0x949B 0x654D #CJK UNIFIED IDEOGRAPH
+0x949C 0x654E #CJK UNIFIED IDEOGRAPH
+0x949D 0x6550 #CJK UNIFIED IDEOGRAPH
+0x949E 0x6552 #CJK UNIFIED IDEOGRAPH
+0x949F 0x6553 #CJK UNIFIED IDEOGRAPH
+0x94A0 0x6554 #CJK UNIFIED IDEOGRAPH
+0x94A1 0x6557 #CJK UNIFIED IDEOGRAPH
+0x94A2 0x6558 #CJK UNIFIED IDEOGRAPH
+0x94A3 0x655A #CJK UNIFIED IDEOGRAPH
+0x94A4 0x655C #CJK UNIFIED IDEOGRAPH
+0x94A5 0x655F #CJK UNIFIED IDEOGRAPH
+0x94A6 0x6560 #CJK UNIFIED IDEOGRAPH
+0x94A7 0x6561 #CJK UNIFIED IDEOGRAPH
+0x94A8 0x6564 #CJK UNIFIED IDEOGRAPH
+0x94A9 0x6565 #CJK UNIFIED IDEOGRAPH
+0x94AA 0x6567 #CJK UNIFIED IDEOGRAPH
+0x94AB 0x6568 #CJK UNIFIED IDEOGRAPH
+0x94AC 0x6569 #CJK UNIFIED IDEOGRAPH
+0x94AD 0x656A #CJK UNIFIED IDEOGRAPH
+0x94AE 0x656D #CJK UNIFIED IDEOGRAPH
+0x94AF 0x656E #CJK UNIFIED IDEOGRAPH
+0x94B0 0x656F #CJK UNIFIED IDEOGRAPH
+0x94B1 0x6571 #CJK UNIFIED IDEOGRAPH
+0x94B2 0x6573 #CJK UNIFIED IDEOGRAPH
+0x94B3 0x6575 #CJK UNIFIED IDEOGRAPH
+0x94B4 0x6576 #CJK UNIFIED IDEOGRAPH
+0x94B5 0x6578 #CJK UNIFIED IDEOGRAPH
+0x94B6 0x6579 #CJK UNIFIED IDEOGRAPH
+0x94B7 0x657A #CJK UNIFIED IDEOGRAPH
+0x94B8 0x657B #CJK UNIFIED IDEOGRAPH
+0x94B9 0x657C #CJK UNIFIED IDEOGRAPH
+0x94BA 0x657D #CJK UNIFIED IDEOGRAPH
+0x94BB 0x657E #CJK UNIFIED IDEOGRAPH
+0x94BC 0x657F #CJK UNIFIED IDEOGRAPH
+0x94BD 0x6580 #CJK UNIFIED IDEOGRAPH
+0x94BE 0x6581 #CJK UNIFIED IDEOGRAPH
+0x94BF 0x6582 #CJK UNIFIED IDEOGRAPH
+0x94C0 0x6583 #CJK UNIFIED IDEOGRAPH
+0x94C1 0x6584 #CJK UNIFIED IDEOGRAPH
+0x94C2 0x6585 #CJK UNIFIED IDEOGRAPH
+0x94C3 0x6586 #CJK UNIFIED IDEOGRAPH
+0x94C4 0x6588 #CJK UNIFIED IDEOGRAPH
+0x94C5 0x6589 #CJK UNIFIED IDEOGRAPH
+0x94C6 0x658A #CJK UNIFIED IDEOGRAPH
+0x94C7 0x658D #CJK UNIFIED IDEOGRAPH
+0x94C8 0x658E #CJK UNIFIED IDEOGRAPH
+0x94C9 0x658F #CJK UNIFIED IDEOGRAPH
+0x94CA 0x6592 #CJK UNIFIED IDEOGRAPH
+0x94CB 0x6594 #CJK UNIFIED IDEOGRAPH
+0x94CC 0x6595 #CJK UNIFIED IDEOGRAPH
+0x94CD 0x6596 #CJK UNIFIED IDEOGRAPH
+0x94CE 0x6598 #CJK UNIFIED IDEOGRAPH
+0x94CF 0x659A #CJK UNIFIED IDEOGRAPH
+0x94D0 0x659D #CJK UNIFIED IDEOGRAPH
+0x94D1 0x659E #CJK UNIFIED IDEOGRAPH
+0x94D2 0x65A0 #CJK UNIFIED IDEOGRAPH
+0x94D3 0x65A2 #CJK UNIFIED IDEOGRAPH
+0x94D4 0x65A3 #CJK UNIFIED IDEOGRAPH
+0x94D5 0x65A6 #CJK UNIFIED IDEOGRAPH
+0x94D6 0x65A8 #CJK UNIFIED IDEOGRAPH
+0x94D7 0x65AA #CJK UNIFIED IDEOGRAPH
+0x94D8 0x65AC #CJK UNIFIED IDEOGRAPH
+0x94D9 0x65AE #CJK UNIFIED IDEOGRAPH
+0x94DA 0x65B1 #CJK UNIFIED IDEOGRAPH
+0x94DB 0x65B2 #CJK UNIFIED IDEOGRAPH
+0x94DC 0x65B3 #CJK UNIFIED IDEOGRAPH
+0x94DD 0x65B4 #CJK UNIFIED IDEOGRAPH
+0x94DE 0x65B5 #CJK UNIFIED IDEOGRAPH
+0x94DF 0x65B6 #CJK UNIFIED IDEOGRAPH
+0x94E0 0x65B7 #CJK UNIFIED IDEOGRAPH
+0x94E1 0x65B8 #CJK UNIFIED IDEOGRAPH
+0x94E2 0x65BA #CJK UNIFIED IDEOGRAPH
+0x94E3 0x65BB #CJK UNIFIED IDEOGRAPH
+0x94E4 0x65BE #CJK UNIFIED IDEOGRAPH
+0x94E5 0x65BF #CJK UNIFIED IDEOGRAPH
+0x94E6 0x65C0 #CJK UNIFIED IDEOGRAPH
+0x94E7 0x65C2 #CJK UNIFIED IDEOGRAPH
+0x94E8 0x65C7 #CJK UNIFIED IDEOGRAPH
+0x94E9 0x65C8 #CJK UNIFIED IDEOGRAPH
+0x94EA 0x65C9 #CJK UNIFIED IDEOGRAPH
+0x94EB 0x65CA #CJK UNIFIED IDEOGRAPH
+0x94EC 0x65CD #CJK UNIFIED IDEOGRAPH
+0x94ED 0x65D0 #CJK UNIFIED IDEOGRAPH
+0x94EE 0x65D1 #CJK UNIFIED IDEOGRAPH
+0x94EF 0x65D3 #CJK UNIFIED IDEOGRAPH
+0x94F0 0x65D4 #CJK UNIFIED IDEOGRAPH
+0x94F1 0x65D5 #CJK UNIFIED IDEOGRAPH
+0x94F2 0x65D8 #CJK UNIFIED IDEOGRAPH
+0x94F3 0x65D9 #CJK UNIFIED IDEOGRAPH
+0x94F4 0x65DA #CJK UNIFIED IDEOGRAPH
+0x94F5 0x65DB #CJK UNIFIED IDEOGRAPH
+0x94F6 0x65DC #CJK UNIFIED IDEOGRAPH
+0x94F7 0x65DD #CJK UNIFIED IDEOGRAPH
+0x94F8 0x65DE #CJK UNIFIED IDEOGRAPH
+0x94F9 0x65DF #CJK UNIFIED IDEOGRAPH
+0x94FA 0x65E1 #CJK UNIFIED IDEOGRAPH
+0x94FB 0x65E3 #CJK UNIFIED IDEOGRAPH
+0x94FC 0x65E4 #CJK UNIFIED IDEOGRAPH
+0x94FD 0x65EA #CJK UNIFIED IDEOGRAPH
+0x94FE 0x65EB #CJK UNIFIED IDEOGRAPH
+0x9540 0x65F2 #CJK UNIFIED IDEOGRAPH
+0x9541 0x65F3 #CJK UNIFIED IDEOGRAPH
+0x9542 0x65F4 #CJK UNIFIED IDEOGRAPH
+0x9543 0x65F5 #CJK UNIFIED IDEOGRAPH
+0x9544 0x65F8 #CJK UNIFIED IDEOGRAPH
+0x9545 0x65F9 #CJK UNIFIED IDEOGRAPH
+0x9546 0x65FB #CJK UNIFIED IDEOGRAPH
+0x9547 0x65FC #CJK UNIFIED IDEOGRAPH
+0x9548 0x65FD #CJK UNIFIED IDEOGRAPH
+0x9549 0x65FE #CJK UNIFIED IDEOGRAPH
+0x954A 0x65FF #CJK UNIFIED IDEOGRAPH
+0x954B 0x6601 #CJK UNIFIED IDEOGRAPH
+0x954C 0x6604 #CJK UNIFIED IDEOGRAPH
+0x954D 0x6605 #CJK UNIFIED IDEOGRAPH
+0x954E 0x6607 #CJK UNIFIED IDEOGRAPH
+0x954F 0x6608 #CJK UNIFIED IDEOGRAPH
+0x9550 0x6609 #CJK UNIFIED IDEOGRAPH
+0x9551 0x660B #CJK UNIFIED IDEOGRAPH
+0x9552 0x660D #CJK UNIFIED IDEOGRAPH
+0x9553 0x6610 #CJK UNIFIED IDEOGRAPH
+0x9554 0x6611 #CJK UNIFIED IDEOGRAPH
+0x9555 0x6612 #CJK UNIFIED IDEOGRAPH
+0x9556 0x6616 #CJK UNIFIED IDEOGRAPH
+0x9557 0x6617 #CJK UNIFIED IDEOGRAPH
+0x9558 0x6618 #CJK UNIFIED IDEOGRAPH
+0x9559 0x661A #CJK UNIFIED IDEOGRAPH
+0x955A 0x661B #CJK UNIFIED IDEOGRAPH
+0x955B 0x661C #CJK UNIFIED IDEOGRAPH
+0x955C 0x661E #CJK UNIFIED IDEOGRAPH
+0x955D 0x6621 #CJK UNIFIED IDEOGRAPH
+0x955E 0x6622 #CJK UNIFIED IDEOGRAPH
+0x955F 0x6623 #CJK UNIFIED IDEOGRAPH
+0x9560 0x6624 #CJK UNIFIED IDEOGRAPH
+0x9561 0x6626 #CJK UNIFIED IDEOGRAPH
+0x9562 0x6629 #CJK UNIFIED IDEOGRAPH
+0x9563 0x662A #CJK UNIFIED IDEOGRAPH
+0x9564 0x662B #CJK UNIFIED IDEOGRAPH
+0x9565 0x662C #CJK UNIFIED IDEOGRAPH
+0x9566 0x662E #CJK UNIFIED IDEOGRAPH
+0x9567 0x6630 #CJK UNIFIED IDEOGRAPH
+0x9568 0x6632 #CJK UNIFIED IDEOGRAPH
+0x9569 0x6633 #CJK UNIFIED IDEOGRAPH
+0x956A 0x6637 #CJK UNIFIED IDEOGRAPH
+0x956B 0x6638 #CJK UNIFIED IDEOGRAPH
+0x956C 0x6639 #CJK UNIFIED IDEOGRAPH
+0x956D 0x663A #CJK UNIFIED IDEOGRAPH
+0x956E 0x663B #CJK UNIFIED IDEOGRAPH
+0x956F 0x663D #CJK UNIFIED IDEOGRAPH
+0x9570 0x663F #CJK UNIFIED IDEOGRAPH
+0x9571 0x6640 #CJK UNIFIED IDEOGRAPH
+0x9572 0x6642 #CJK UNIFIED IDEOGRAPH
+0x9573 0x6644 #CJK UNIFIED IDEOGRAPH
+0x9574 0x6645 #CJK UNIFIED IDEOGRAPH
+0x9575 0x6646 #CJK UNIFIED IDEOGRAPH
+0x9576 0x6647 #CJK UNIFIED IDEOGRAPH
+0x9577 0x6648 #CJK UNIFIED IDEOGRAPH
+0x9578 0x6649 #CJK UNIFIED IDEOGRAPH
+0x9579 0x664A #CJK UNIFIED IDEOGRAPH
+0x957A 0x664D #CJK UNIFIED IDEOGRAPH
+0x957B 0x664E #CJK UNIFIED IDEOGRAPH
+0x957C 0x6650 #CJK UNIFIED IDEOGRAPH
+0x957D 0x6651 #CJK UNIFIED IDEOGRAPH
+0x957E 0x6658 #CJK UNIFIED IDEOGRAPH
+0x9580 0x6659 #CJK UNIFIED IDEOGRAPH
+0x9581 0x665B #CJK UNIFIED IDEOGRAPH
+0x9582 0x665C #CJK UNIFIED IDEOGRAPH
+0x9583 0x665D #CJK UNIFIED IDEOGRAPH
+0x9584 0x665E #CJK UNIFIED IDEOGRAPH
+0x9585 0x6660 #CJK UNIFIED IDEOGRAPH
+0x9586 0x6662 #CJK UNIFIED IDEOGRAPH
+0x9587 0x6663 #CJK UNIFIED IDEOGRAPH
+0x9588 0x6665 #CJK UNIFIED IDEOGRAPH
+0x9589 0x6667 #CJK UNIFIED IDEOGRAPH
+0x958A 0x6669 #CJK UNIFIED IDEOGRAPH
+0x958B 0x666A #CJK UNIFIED IDEOGRAPH
+0x958C 0x666B #CJK UNIFIED IDEOGRAPH
+0x958D 0x666C #CJK UNIFIED IDEOGRAPH
+0x958E 0x666D #CJK UNIFIED IDEOGRAPH
+0x958F 0x6671 #CJK UNIFIED IDEOGRAPH
+0x9590 0x6672 #CJK UNIFIED IDEOGRAPH
+0x9591 0x6673 #CJK UNIFIED IDEOGRAPH
+0x9592 0x6675 #CJK UNIFIED IDEOGRAPH
+0x9593 0x6678 #CJK UNIFIED IDEOGRAPH
+0x9594 0x6679 #CJK UNIFIED IDEOGRAPH
+0x9595 0x667B #CJK UNIFIED IDEOGRAPH
+0x9596 0x667C #CJK UNIFIED IDEOGRAPH
+0x9597 0x667D #CJK UNIFIED IDEOGRAPH
+0x9598 0x667F #CJK UNIFIED IDEOGRAPH
+0x9599 0x6680 #CJK UNIFIED IDEOGRAPH
+0x959A 0x6681 #CJK UNIFIED IDEOGRAPH
+0x959B 0x6683 #CJK UNIFIED IDEOGRAPH
+0x959C 0x6685 #CJK UNIFIED IDEOGRAPH
+0x959D 0x6686 #CJK UNIFIED IDEOGRAPH
+0x959E 0x6688 #CJK UNIFIED IDEOGRAPH
+0x959F 0x6689 #CJK UNIFIED IDEOGRAPH
+0x95A0 0x668A #CJK UNIFIED IDEOGRAPH
+0x95A1 0x668B #CJK UNIFIED IDEOGRAPH
+0x95A2 0x668D #CJK UNIFIED IDEOGRAPH
+0x95A3 0x668E #CJK UNIFIED IDEOGRAPH
+0x95A4 0x668F #CJK UNIFIED IDEOGRAPH
+0x95A5 0x6690 #CJK UNIFIED IDEOGRAPH
+0x95A6 0x6692 #CJK UNIFIED IDEOGRAPH
+0x95A7 0x6693 #CJK UNIFIED IDEOGRAPH
+0x95A8 0x6694 #CJK UNIFIED IDEOGRAPH
+0x95A9 0x6695 #CJK UNIFIED IDEOGRAPH
+0x95AA 0x6698 #CJK UNIFIED IDEOGRAPH
+0x95AB 0x6699 #CJK UNIFIED IDEOGRAPH
+0x95AC 0x669A #CJK UNIFIED IDEOGRAPH
+0x95AD 0x669B #CJK UNIFIED IDEOGRAPH
+0x95AE 0x669C #CJK UNIFIED IDEOGRAPH
+0x95AF 0x669E #CJK UNIFIED IDEOGRAPH
+0x95B0 0x669F #CJK UNIFIED IDEOGRAPH
+0x95B1 0x66A0 #CJK UNIFIED IDEOGRAPH
+0x95B2 0x66A1 #CJK UNIFIED IDEOGRAPH
+0x95B3 0x66A2 #CJK UNIFIED IDEOGRAPH
+0x95B4 0x66A3 #CJK UNIFIED IDEOGRAPH
+0x95B5 0x66A4 #CJK UNIFIED IDEOGRAPH
+0x95B6 0x66A5 #CJK UNIFIED IDEOGRAPH
+0x95B7 0x66A6 #CJK UNIFIED IDEOGRAPH
+0x95B8 0x66A9 #CJK UNIFIED IDEOGRAPH
+0x95B9 0x66AA #CJK UNIFIED IDEOGRAPH
+0x95BA 0x66AB #CJK UNIFIED IDEOGRAPH
+0x95BB 0x66AC #CJK UNIFIED IDEOGRAPH
+0x95BC 0x66AD #CJK UNIFIED IDEOGRAPH
+0x95BD 0x66AF #CJK UNIFIED IDEOGRAPH
+0x95BE 0x66B0 #CJK UNIFIED IDEOGRAPH
+0x95BF 0x66B1 #CJK UNIFIED IDEOGRAPH
+0x95C0 0x66B2 #CJK UNIFIED IDEOGRAPH
+0x95C1 0x66B3 #CJK UNIFIED IDEOGRAPH
+0x95C2 0x66B5 #CJK UNIFIED IDEOGRAPH
+0x95C3 0x66B6 #CJK UNIFIED IDEOGRAPH
+0x95C4 0x66B7 #CJK UNIFIED IDEOGRAPH
+0x95C5 0x66B8 #CJK UNIFIED IDEOGRAPH
+0x95C6 0x66BA #CJK UNIFIED IDEOGRAPH
+0x95C7 0x66BB #CJK UNIFIED IDEOGRAPH
+0x95C8 0x66BC #CJK UNIFIED IDEOGRAPH
+0x95C9 0x66BD #CJK UNIFIED IDEOGRAPH
+0x95CA 0x66BF #CJK UNIFIED IDEOGRAPH
+0x95CB 0x66C0 #CJK UNIFIED IDEOGRAPH
+0x95CC 0x66C1 #CJK UNIFIED IDEOGRAPH
+0x95CD 0x66C2 #CJK UNIFIED IDEOGRAPH
+0x95CE 0x66C3 #CJK UNIFIED IDEOGRAPH
+0x95CF 0x66C4 #CJK UNIFIED IDEOGRAPH
+0x95D0 0x66C5 #CJK UNIFIED IDEOGRAPH
+0x95D1 0x66C6 #CJK UNIFIED IDEOGRAPH
+0x95D2 0x66C7 #CJK UNIFIED IDEOGRAPH
+0x95D3 0x66C8 #CJK UNIFIED IDEOGRAPH
+0x95D4 0x66C9 #CJK UNIFIED IDEOGRAPH
+0x95D5 0x66CA #CJK UNIFIED IDEOGRAPH
+0x95D6 0x66CB #CJK UNIFIED IDEOGRAPH
+0x95D7 0x66CC #CJK UNIFIED IDEOGRAPH
+0x95D8 0x66CD #CJK UNIFIED IDEOGRAPH
+0x95D9 0x66CE #CJK UNIFIED IDEOGRAPH
+0x95DA 0x66CF #CJK UNIFIED IDEOGRAPH
+0x95DB 0x66D0 #CJK UNIFIED IDEOGRAPH
+0x95DC 0x66D1 #CJK UNIFIED IDEOGRAPH
+0x95DD 0x66D2 #CJK UNIFIED IDEOGRAPH
+0x95DE 0x66D3 #CJK UNIFIED IDEOGRAPH
+0x95DF 0x66D4 #CJK UNIFIED IDEOGRAPH
+0x95E0 0x66D5 #CJK UNIFIED IDEOGRAPH
+0x95E1 0x66D6 #CJK UNIFIED IDEOGRAPH
+0x95E2 0x66D7 #CJK UNIFIED IDEOGRAPH
+0x95E3 0x66D8 #CJK UNIFIED IDEOGRAPH
+0x95E4 0x66DA #CJK UNIFIED IDEOGRAPH
+0x95E5 0x66DE #CJK UNIFIED IDEOGRAPH
+0x95E6 0x66DF #CJK UNIFIED IDEOGRAPH
+0x95E7 0x66E0 #CJK UNIFIED IDEOGRAPH
+0x95E8 0x66E1 #CJK UNIFIED IDEOGRAPH
+0x95E9 0x66E2 #CJK UNIFIED IDEOGRAPH
+0x95EA 0x66E3 #CJK UNIFIED IDEOGRAPH
+0x95EB 0x66E4 #CJK UNIFIED IDEOGRAPH
+0x95EC 0x66E5 #CJK UNIFIED IDEOGRAPH
+0x95ED 0x66E7 #CJK UNIFIED IDEOGRAPH
+0x95EE 0x66E8 #CJK UNIFIED IDEOGRAPH
+0x95EF 0x66EA #CJK UNIFIED IDEOGRAPH
+0x95F0 0x66EB #CJK UNIFIED IDEOGRAPH
+0x95F1 0x66EC #CJK UNIFIED IDEOGRAPH
+0x95F2 0x66ED #CJK UNIFIED IDEOGRAPH
+0x95F3 0x66EE #CJK UNIFIED IDEOGRAPH
+0x95F4 0x66EF #CJK UNIFIED IDEOGRAPH
+0x95F5 0x66F1 #CJK UNIFIED IDEOGRAPH
+0x95F6 0x66F5 #CJK UNIFIED IDEOGRAPH
+0x95F7 0x66F6 #CJK UNIFIED IDEOGRAPH
+0x95F8 0x66F8 #CJK UNIFIED IDEOGRAPH
+0x95F9 0x66FA #CJK UNIFIED IDEOGRAPH
+0x95FA 0x66FB #CJK UNIFIED IDEOGRAPH
+0x95FB 0x66FD #CJK UNIFIED IDEOGRAPH
+0x95FC 0x6701 #CJK UNIFIED IDEOGRAPH
+0x95FD 0x6702 #CJK UNIFIED IDEOGRAPH
+0x95FE 0x6703 #CJK UNIFIED IDEOGRAPH
+0x9640 0x6704 #CJK UNIFIED IDEOGRAPH
+0x9641 0x6705 #CJK UNIFIED IDEOGRAPH
+0x9642 0x6706 #CJK UNIFIED IDEOGRAPH
+0x9643 0x6707 #CJK UNIFIED IDEOGRAPH
+0x9644 0x670C #CJK UNIFIED IDEOGRAPH
+0x9645 0x670E #CJK UNIFIED IDEOGRAPH
+0x9646 0x670F #CJK UNIFIED IDEOGRAPH
+0x9647 0x6711 #CJK UNIFIED IDEOGRAPH
+0x9648 0x6712 #CJK UNIFIED IDEOGRAPH
+0x9649 0x6713 #CJK UNIFIED IDEOGRAPH
+0x964A 0x6716 #CJK UNIFIED IDEOGRAPH
+0x964B 0x6718 #CJK UNIFIED IDEOGRAPH
+0x964C 0x6719 #CJK UNIFIED IDEOGRAPH
+0x964D 0x671A #CJK UNIFIED IDEOGRAPH
+0x964E 0x671C #CJK UNIFIED IDEOGRAPH
+0x964F 0x671E #CJK UNIFIED IDEOGRAPH
+0x9650 0x6720 #CJK UNIFIED IDEOGRAPH
+0x9651 0x6721 #CJK UNIFIED IDEOGRAPH
+0x9652 0x6722 #CJK UNIFIED IDEOGRAPH
+0x9653 0x6723 #CJK UNIFIED IDEOGRAPH
+0x9654 0x6724 #CJK UNIFIED IDEOGRAPH
+0x9655 0x6725 #CJK UNIFIED IDEOGRAPH
+0x9656 0x6727 #CJK UNIFIED IDEOGRAPH
+0x9657 0x6729 #CJK UNIFIED IDEOGRAPH
+0x9658 0x672E #CJK UNIFIED IDEOGRAPH
+0x9659 0x6730 #CJK UNIFIED IDEOGRAPH
+0x965A 0x6732 #CJK UNIFIED IDEOGRAPH
+0x965B 0x6733 #CJK UNIFIED IDEOGRAPH
+0x965C 0x6736 #CJK UNIFIED IDEOGRAPH
+0x965D 0x6737 #CJK UNIFIED IDEOGRAPH
+0x965E 0x6738 #CJK UNIFIED IDEOGRAPH
+0x965F 0x6739 #CJK UNIFIED IDEOGRAPH
+0x9660 0x673B #CJK UNIFIED IDEOGRAPH
+0x9661 0x673C #CJK UNIFIED IDEOGRAPH
+0x9662 0x673E #CJK UNIFIED IDEOGRAPH
+0x9663 0x673F #CJK UNIFIED IDEOGRAPH
+0x9664 0x6741 #CJK UNIFIED IDEOGRAPH
+0x9665 0x6744 #CJK UNIFIED IDEOGRAPH
+0x9666 0x6745 #CJK UNIFIED IDEOGRAPH
+0x9667 0x6747 #CJK UNIFIED IDEOGRAPH
+0x9668 0x674A #CJK UNIFIED IDEOGRAPH
+0x9669 0x674B #CJK UNIFIED IDEOGRAPH
+0x966A 0x674D #CJK UNIFIED IDEOGRAPH
+0x966B 0x6752 #CJK UNIFIED IDEOGRAPH
+0x966C 0x6754 #CJK UNIFIED IDEOGRAPH
+0x966D 0x6755 #CJK UNIFIED IDEOGRAPH
+0x966E 0x6757 #CJK UNIFIED IDEOGRAPH
+0x966F 0x6758 #CJK UNIFIED IDEOGRAPH
+0x9670 0x6759 #CJK UNIFIED IDEOGRAPH
+0x9671 0x675A #CJK UNIFIED IDEOGRAPH
+0x9672 0x675B #CJK UNIFIED IDEOGRAPH
+0x9673 0x675D #CJK UNIFIED IDEOGRAPH
+0x9674 0x6762 #CJK UNIFIED IDEOGRAPH
+0x9675 0x6763 #CJK UNIFIED IDEOGRAPH
+0x9676 0x6764 #CJK UNIFIED IDEOGRAPH
+0x9677 0x6766 #CJK UNIFIED IDEOGRAPH
+0x9678 0x6767 #CJK UNIFIED IDEOGRAPH
+0x9679 0x676B #CJK UNIFIED IDEOGRAPH
+0x967A 0x676C #CJK UNIFIED IDEOGRAPH
+0x967B 0x676E #CJK UNIFIED IDEOGRAPH
+0x967C 0x6771 #CJK UNIFIED IDEOGRAPH
+0x967D 0x6774 #CJK UNIFIED IDEOGRAPH
+0x967E 0x6776 #CJK UNIFIED IDEOGRAPH
+0x9680 0x6778 #CJK UNIFIED IDEOGRAPH
+0x9681 0x6779 #CJK UNIFIED IDEOGRAPH
+0x9682 0x677A #CJK UNIFIED IDEOGRAPH
+0x9683 0x677B #CJK UNIFIED IDEOGRAPH
+0x9684 0x677D #CJK UNIFIED IDEOGRAPH
+0x9685 0x6780 #CJK UNIFIED IDEOGRAPH
+0x9686 0x6782 #CJK UNIFIED IDEOGRAPH
+0x9687 0x6783 #CJK UNIFIED IDEOGRAPH
+0x9688 0x6785 #CJK UNIFIED IDEOGRAPH
+0x9689 0x6786 #CJK UNIFIED IDEOGRAPH
+0x968A 0x6788 #CJK UNIFIED IDEOGRAPH
+0x968B 0x678A #CJK UNIFIED IDEOGRAPH
+0x968C 0x678C #CJK UNIFIED IDEOGRAPH
+0x968D 0x678D #CJK UNIFIED IDEOGRAPH
+0x968E 0x678E #CJK UNIFIED IDEOGRAPH
+0x968F 0x678F #CJK UNIFIED IDEOGRAPH
+0x9690 0x6791 #CJK UNIFIED IDEOGRAPH
+0x9691 0x6792 #CJK UNIFIED IDEOGRAPH
+0x9692 0x6793 #CJK UNIFIED IDEOGRAPH
+0x9693 0x6794 #CJK UNIFIED IDEOGRAPH
+0x9694 0x6796 #CJK UNIFIED IDEOGRAPH
+0x9695 0x6799 #CJK UNIFIED IDEOGRAPH
+0x9696 0x679B #CJK UNIFIED IDEOGRAPH
+0x9697 0x679F #CJK UNIFIED IDEOGRAPH
+0x9698 0x67A0 #CJK UNIFIED IDEOGRAPH
+0x9699 0x67A1 #CJK UNIFIED IDEOGRAPH
+0x969A 0x67A4 #CJK UNIFIED IDEOGRAPH
+0x969B 0x67A6 #CJK UNIFIED IDEOGRAPH
+0x969C 0x67A9 #CJK UNIFIED IDEOGRAPH
+0x969D 0x67AC #CJK UNIFIED IDEOGRAPH
+0x969E 0x67AE #CJK UNIFIED IDEOGRAPH
+0x969F 0x67B1 #CJK UNIFIED IDEOGRAPH
+0x96A0 0x67B2 #CJK UNIFIED IDEOGRAPH
+0x96A1 0x67B4 #CJK UNIFIED IDEOGRAPH
+0x96A2 0x67B9 #CJK UNIFIED IDEOGRAPH
+0x96A3 0x67BA #CJK UNIFIED IDEOGRAPH
+0x96A4 0x67BB #CJK UNIFIED IDEOGRAPH
+0x96A5 0x67BC #CJK UNIFIED IDEOGRAPH
+0x96A6 0x67BD #CJK UNIFIED IDEOGRAPH
+0x96A7 0x67BE #CJK UNIFIED IDEOGRAPH
+0x96A8 0x67BF #CJK UNIFIED IDEOGRAPH
+0x96A9 0x67C0 #CJK UNIFIED IDEOGRAPH
+0x96AA 0x67C2 #CJK UNIFIED IDEOGRAPH
+0x96AB 0x67C5 #CJK UNIFIED IDEOGRAPH
+0x96AC 0x67C6 #CJK UNIFIED IDEOGRAPH
+0x96AD 0x67C7 #CJK UNIFIED IDEOGRAPH
+0x96AE 0x67C8 #CJK UNIFIED IDEOGRAPH
+0x96AF 0x67C9 #CJK UNIFIED IDEOGRAPH
+0x96B0 0x67CA #CJK UNIFIED IDEOGRAPH
+0x96B1 0x67CB #CJK UNIFIED IDEOGRAPH
+0x96B2 0x67CC #CJK UNIFIED IDEOGRAPH
+0x96B3 0x67CD #CJK UNIFIED IDEOGRAPH
+0x96B4 0x67CE #CJK UNIFIED IDEOGRAPH
+0x96B5 0x67D5 #CJK UNIFIED IDEOGRAPH
+0x96B6 0x67D6 #CJK UNIFIED IDEOGRAPH
+0x96B7 0x67D7 #CJK UNIFIED IDEOGRAPH
+0x96B8 0x67DB #CJK UNIFIED IDEOGRAPH
+0x96B9 0x67DF #CJK UNIFIED IDEOGRAPH
+0x96BA 0x67E1 #CJK UNIFIED IDEOGRAPH
+0x96BB 0x67E3 #CJK UNIFIED IDEOGRAPH
+0x96BC 0x67E4 #CJK UNIFIED IDEOGRAPH
+0x96BD 0x67E6 #CJK UNIFIED IDEOGRAPH
+0x96BE 0x67E7 #CJK UNIFIED IDEOGRAPH
+0x96BF 0x67E8 #CJK UNIFIED IDEOGRAPH
+0x96C0 0x67EA #CJK UNIFIED IDEOGRAPH
+0x96C1 0x67EB #CJK UNIFIED IDEOGRAPH
+0x96C2 0x67ED #CJK UNIFIED IDEOGRAPH
+0x96C3 0x67EE #CJK UNIFIED IDEOGRAPH
+0x96C4 0x67F2 #CJK UNIFIED IDEOGRAPH
+0x96C5 0x67F5 #CJK UNIFIED IDEOGRAPH
+0x96C6 0x67F6 #CJK UNIFIED IDEOGRAPH
+0x96C7 0x67F7 #CJK UNIFIED IDEOGRAPH
+0x96C8 0x67F8 #CJK UNIFIED IDEOGRAPH
+0x96C9 0x67F9 #CJK UNIFIED IDEOGRAPH
+0x96CA 0x67FA #CJK UNIFIED IDEOGRAPH
+0x96CB 0x67FB #CJK UNIFIED IDEOGRAPH
+0x96CC 0x67FC #CJK UNIFIED IDEOGRAPH
+0x96CD 0x67FE #CJK UNIFIED IDEOGRAPH
+0x96CE 0x6801 #CJK UNIFIED IDEOGRAPH
+0x96CF 0x6802 #CJK UNIFIED IDEOGRAPH
+0x96D0 0x6803 #CJK UNIFIED IDEOGRAPH
+0x96D1 0x6804 #CJK UNIFIED IDEOGRAPH
+0x96D2 0x6806 #CJK UNIFIED IDEOGRAPH
+0x96D3 0x680D #CJK UNIFIED IDEOGRAPH
+0x96D4 0x6810 #CJK UNIFIED IDEOGRAPH
+0x96D5 0x6812 #CJK UNIFIED IDEOGRAPH
+0x96D6 0x6814 #CJK UNIFIED IDEOGRAPH
+0x96D7 0x6815 #CJK UNIFIED IDEOGRAPH
+0x96D8 0x6818 #CJK UNIFIED IDEOGRAPH
+0x96D9 0x6819 #CJK UNIFIED IDEOGRAPH
+0x96DA 0x681A #CJK UNIFIED IDEOGRAPH
+0x96DB 0x681B #CJK UNIFIED IDEOGRAPH
+0x96DC 0x681C #CJK UNIFIED IDEOGRAPH
+0x96DD 0x681E #CJK UNIFIED IDEOGRAPH
+0x96DE 0x681F #CJK UNIFIED IDEOGRAPH
+0x96DF 0x6820 #CJK UNIFIED IDEOGRAPH
+0x96E0 0x6822 #CJK UNIFIED IDEOGRAPH
+0x96E1 0x6823 #CJK UNIFIED IDEOGRAPH
+0x96E2 0x6824 #CJK UNIFIED IDEOGRAPH
+0x96E3 0x6825 #CJK UNIFIED IDEOGRAPH
+0x96E4 0x6826 #CJK UNIFIED IDEOGRAPH
+0x96E5 0x6827 #CJK UNIFIED IDEOGRAPH
+0x96E6 0x6828 #CJK UNIFIED IDEOGRAPH
+0x96E7 0x682B #CJK UNIFIED IDEOGRAPH
+0x96E8 0x682C #CJK UNIFIED IDEOGRAPH
+0x96E9 0x682D #CJK UNIFIED IDEOGRAPH
+0x96EA 0x682E #CJK UNIFIED IDEOGRAPH
+0x96EB 0x682F #CJK UNIFIED IDEOGRAPH
+0x96EC 0x6830 #CJK UNIFIED IDEOGRAPH
+0x96ED 0x6831 #CJK UNIFIED IDEOGRAPH
+0x96EE 0x6834 #CJK UNIFIED IDEOGRAPH
+0x96EF 0x6835 #CJK UNIFIED IDEOGRAPH
+0x96F0 0x6836 #CJK UNIFIED IDEOGRAPH
+0x96F1 0x683A #CJK UNIFIED IDEOGRAPH
+0x96F2 0x683B #CJK UNIFIED IDEOGRAPH
+0x96F3 0x683F #CJK UNIFIED IDEOGRAPH
+0x96F4 0x6847 #CJK UNIFIED IDEOGRAPH
+0x96F5 0x684B #CJK UNIFIED IDEOGRAPH
+0x96F6 0x684D #CJK UNIFIED IDEOGRAPH
+0x96F7 0x684F #CJK UNIFIED IDEOGRAPH
+0x96F8 0x6852 #CJK UNIFIED IDEOGRAPH
+0x96F9 0x6856 #CJK UNIFIED IDEOGRAPH
+0x96FA 0x6857 #CJK UNIFIED IDEOGRAPH
+0x96FB 0x6858 #CJK UNIFIED IDEOGRAPH
+0x96FC 0x6859 #CJK UNIFIED IDEOGRAPH
+0x96FD 0x685A #CJK UNIFIED IDEOGRAPH
+0x96FE 0x685B #CJK UNIFIED IDEOGRAPH
+0x9740 0x685C #CJK UNIFIED IDEOGRAPH
+0x9741 0x685D #CJK UNIFIED IDEOGRAPH
+0x9742 0x685E #CJK UNIFIED IDEOGRAPH
+0x9743 0x685F #CJK UNIFIED IDEOGRAPH
+0x9744 0x686A #CJK UNIFIED IDEOGRAPH
+0x9745 0x686C #CJK UNIFIED IDEOGRAPH
+0x9746 0x686D #CJK UNIFIED IDEOGRAPH
+0x9747 0x686E #CJK UNIFIED IDEOGRAPH
+0x9748 0x686F #CJK UNIFIED IDEOGRAPH
+0x9749 0x6870 #CJK UNIFIED IDEOGRAPH
+0x974A 0x6871 #CJK UNIFIED IDEOGRAPH
+0x974B 0x6872 #CJK UNIFIED IDEOGRAPH
+0x974C 0x6873 #CJK UNIFIED IDEOGRAPH
+0x974D 0x6875 #CJK UNIFIED IDEOGRAPH
+0x974E 0x6878 #CJK UNIFIED IDEOGRAPH
+0x974F 0x6879 #CJK UNIFIED IDEOGRAPH
+0x9750 0x687A #CJK UNIFIED IDEOGRAPH
+0x9751 0x687B #CJK UNIFIED IDEOGRAPH
+0x9752 0x687C #CJK UNIFIED IDEOGRAPH
+0x9753 0x687D #CJK UNIFIED IDEOGRAPH
+0x9754 0x687E #CJK UNIFIED IDEOGRAPH
+0x9755 0x687F #CJK UNIFIED IDEOGRAPH
+0x9756 0x6880 #CJK UNIFIED IDEOGRAPH
+0x9757 0x6882 #CJK UNIFIED IDEOGRAPH
+0x9758 0x6884 #CJK UNIFIED IDEOGRAPH
+0x9759 0x6887 #CJK UNIFIED IDEOGRAPH
+0x975A 0x6888 #CJK UNIFIED IDEOGRAPH
+0x975B 0x6889 #CJK UNIFIED IDEOGRAPH
+0x975C 0x688A #CJK UNIFIED IDEOGRAPH
+0x975D 0x688B #CJK UNIFIED IDEOGRAPH
+0x975E 0x688C #CJK UNIFIED IDEOGRAPH
+0x975F 0x688D #CJK UNIFIED IDEOGRAPH
+0x9760 0x688E #CJK UNIFIED IDEOGRAPH
+0x9761 0x6890 #CJK UNIFIED IDEOGRAPH
+0x9762 0x6891 #CJK UNIFIED IDEOGRAPH
+0x9763 0x6892 #CJK UNIFIED IDEOGRAPH
+0x9764 0x6894 #CJK UNIFIED IDEOGRAPH
+0x9765 0x6895 #CJK UNIFIED IDEOGRAPH
+0x9766 0x6896 #CJK UNIFIED IDEOGRAPH
+0x9767 0x6898 #CJK UNIFIED IDEOGRAPH
+0x9768 0x6899 #CJK UNIFIED IDEOGRAPH
+0x9769 0x689A #CJK UNIFIED IDEOGRAPH
+0x976A 0x689B #CJK UNIFIED IDEOGRAPH
+0x976B 0x689C #CJK UNIFIED IDEOGRAPH
+0x976C 0x689D #CJK UNIFIED IDEOGRAPH
+0x976D 0x689E #CJK UNIFIED IDEOGRAPH
+0x976E 0x689F #CJK UNIFIED IDEOGRAPH
+0x976F 0x68A0 #CJK UNIFIED IDEOGRAPH
+0x9770 0x68A1 #CJK UNIFIED IDEOGRAPH
+0x9771 0x68A3 #CJK UNIFIED IDEOGRAPH
+0x9772 0x68A4 #CJK UNIFIED IDEOGRAPH
+0x9773 0x68A5 #CJK UNIFIED IDEOGRAPH
+0x9774 0x68A9 #CJK UNIFIED IDEOGRAPH
+0x9775 0x68AA #CJK UNIFIED IDEOGRAPH
+0x9776 0x68AB #CJK UNIFIED IDEOGRAPH
+0x9777 0x68AC #CJK UNIFIED IDEOGRAPH
+0x9778 0x68AE #CJK UNIFIED IDEOGRAPH
+0x9779 0x68B1 #CJK UNIFIED IDEOGRAPH
+0x977A 0x68B2 #CJK UNIFIED IDEOGRAPH
+0x977B 0x68B4 #CJK UNIFIED IDEOGRAPH
+0x977C 0x68B6 #CJK UNIFIED IDEOGRAPH
+0x977D 0x68B7 #CJK UNIFIED IDEOGRAPH
+0x977E 0x68B8 #CJK UNIFIED IDEOGRAPH
+0x9780 0x68B9 #CJK UNIFIED IDEOGRAPH
+0x9781 0x68BA #CJK UNIFIED IDEOGRAPH
+0x9782 0x68BB #CJK UNIFIED IDEOGRAPH
+0x9783 0x68BC #CJK UNIFIED IDEOGRAPH
+0x9784 0x68BD #CJK UNIFIED IDEOGRAPH
+0x9785 0x68BE #CJK UNIFIED IDEOGRAPH
+0x9786 0x68BF #CJK UNIFIED IDEOGRAPH
+0x9787 0x68C1 #CJK UNIFIED IDEOGRAPH
+0x9788 0x68C3 #CJK UNIFIED IDEOGRAPH
+0x9789 0x68C4 #CJK UNIFIED IDEOGRAPH
+0x978A 0x68C5 #CJK UNIFIED IDEOGRAPH
+0x978B 0x68C6 #CJK UNIFIED IDEOGRAPH
+0x978C 0x68C7 #CJK UNIFIED IDEOGRAPH
+0x978D 0x68C8 #CJK UNIFIED IDEOGRAPH
+0x978E 0x68CA #CJK UNIFIED IDEOGRAPH
+0x978F 0x68CC #CJK UNIFIED IDEOGRAPH
+0x9790 0x68CE #CJK UNIFIED IDEOGRAPH
+0x9791 0x68CF #CJK UNIFIED IDEOGRAPH
+0x9792 0x68D0 #CJK UNIFIED IDEOGRAPH
+0x9793 0x68D1 #CJK UNIFIED IDEOGRAPH
+0x9794 0x68D3 #CJK UNIFIED IDEOGRAPH
+0x9795 0x68D4 #CJK UNIFIED IDEOGRAPH
+0x9796 0x68D6 #CJK UNIFIED IDEOGRAPH
+0x9797 0x68D7 #CJK UNIFIED IDEOGRAPH
+0x9798 0x68D9 #CJK UNIFIED IDEOGRAPH
+0x9799 0x68DB #CJK UNIFIED IDEOGRAPH
+0x979A 0x68DC #CJK UNIFIED IDEOGRAPH
+0x979B 0x68DD #CJK UNIFIED IDEOGRAPH
+0x979C 0x68DE #CJK UNIFIED IDEOGRAPH
+0x979D 0x68DF #CJK UNIFIED IDEOGRAPH
+0x979E 0x68E1 #CJK UNIFIED IDEOGRAPH
+0x979F 0x68E2 #CJK UNIFIED IDEOGRAPH
+0x97A0 0x68E4 #CJK UNIFIED IDEOGRAPH
+0x97A1 0x68E5 #CJK UNIFIED IDEOGRAPH
+0x97A2 0x68E6 #CJK UNIFIED IDEOGRAPH
+0x97A3 0x68E7 #CJK UNIFIED IDEOGRAPH
+0x97A4 0x68E8 #CJK UNIFIED IDEOGRAPH
+0x97A5 0x68E9 #CJK UNIFIED IDEOGRAPH
+0x97A6 0x68EA #CJK UNIFIED IDEOGRAPH
+0x97A7 0x68EB #CJK UNIFIED IDEOGRAPH
+0x97A8 0x68EC #CJK UNIFIED IDEOGRAPH
+0x97A9 0x68ED #CJK UNIFIED IDEOGRAPH
+0x97AA 0x68EF #CJK UNIFIED IDEOGRAPH
+0x97AB 0x68F2 #CJK UNIFIED IDEOGRAPH
+0x97AC 0x68F3 #CJK UNIFIED IDEOGRAPH
+0x97AD 0x68F4 #CJK UNIFIED IDEOGRAPH
+0x97AE 0x68F6 #CJK UNIFIED IDEOGRAPH
+0x97AF 0x68F7 #CJK UNIFIED IDEOGRAPH
+0x97B0 0x68F8 #CJK UNIFIED IDEOGRAPH
+0x97B1 0x68FB #CJK UNIFIED IDEOGRAPH
+0x97B2 0x68FD #CJK UNIFIED IDEOGRAPH
+0x97B3 0x68FE #CJK UNIFIED IDEOGRAPH
+0x97B4 0x68FF #CJK UNIFIED IDEOGRAPH
+0x97B5 0x6900 #CJK UNIFIED IDEOGRAPH
+0x97B6 0x6902 #CJK UNIFIED IDEOGRAPH
+0x97B7 0x6903 #CJK UNIFIED IDEOGRAPH
+0x97B8 0x6904 #CJK UNIFIED IDEOGRAPH
+0x97B9 0x6906 #CJK UNIFIED IDEOGRAPH
+0x97BA 0x6907 #CJK UNIFIED IDEOGRAPH
+0x97BB 0x6908 #CJK UNIFIED IDEOGRAPH
+0x97BC 0x6909 #CJK UNIFIED IDEOGRAPH
+0x97BD 0x690A #CJK UNIFIED IDEOGRAPH
+0x97BE 0x690C #CJK UNIFIED IDEOGRAPH
+0x97BF 0x690F #CJK UNIFIED IDEOGRAPH
+0x97C0 0x6911 #CJK UNIFIED IDEOGRAPH
+0x97C1 0x6913 #CJK UNIFIED IDEOGRAPH
+0x97C2 0x6914 #CJK UNIFIED IDEOGRAPH
+0x97C3 0x6915 #CJK UNIFIED IDEOGRAPH
+0x97C4 0x6916 #CJK UNIFIED IDEOGRAPH
+0x97C5 0x6917 #CJK UNIFIED IDEOGRAPH
+0x97C6 0x6918 #CJK UNIFIED IDEOGRAPH
+0x97C7 0x6919 #CJK UNIFIED IDEOGRAPH
+0x97C8 0x691A #CJK UNIFIED IDEOGRAPH
+0x97C9 0x691B #CJK UNIFIED IDEOGRAPH
+0x97CA 0x691C #CJK UNIFIED IDEOGRAPH
+0x97CB 0x691D #CJK UNIFIED IDEOGRAPH
+0x97CC 0x691E #CJK UNIFIED IDEOGRAPH
+0x97CD 0x6921 #CJK UNIFIED IDEOGRAPH
+0x97CE 0x6922 #CJK UNIFIED IDEOGRAPH
+0x97CF 0x6923 #CJK UNIFIED IDEOGRAPH
+0x97D0 0x6925 #CJK UNIFIED IDEOGRAPH
+0x97D1 0x6926 #CJK UNIFIED IDEOGRAPH
+0x97D2 0x6927 #CJK UNIFIED IDEOGRAPH
+0x97D3 0x6928 #CJK UNIFIED IDEOGRAPH
+0x97D4 0x6929 #CJK UNIFIED IDEOGRAPH
+0x97D5 0x692A #CJK UNIFIED IDEOGRAPH
+0x97D6 0x692B #CJK UNIFIED IDEOGRAPH
+0x97D7 0x692C #CJK UNIFIED IDEOGRAPH
+0x97D8 0x692E #CJK UNIFIED IDEOGRAPH
+0x97D9 0x692F #CJK UNIFIED IDEOGRAPH
+0x97DA 0x6931 #CJK UNIFIED IDEOGRAPH
+0x97DB 0x6932 #CJK UNIFIED IDEOGRAPH
+0x97DC 0x6933 #CJK UNIFIED IDEOGRAPH
+0x97DD 0x6935 #CJK UNIFIED IDEOGRAPH
+0x97DE 0x6936 #CJK UNIFIED IDEOGRAPH
+0x97DF 0x6937 #CJK UNIFIED IDEOGRAPH
+0x97E0 0x6938 #CJK UNIFIED IDEOGRAPH
+0x97E1 0x693A #CJK UNIFIED IDEOGRAPH
+0x97E2 0x693B #CJK UNIFIED IDEOGRAPH
+0x97E3 0x693C #CJK UNIFIED IDEOGRAPH
+0x97E4 0x693E #CJK UNIFIED IDEOGRAPH
+0x97E5 0x6940 #CJK UNIFIED IDEOGRAPH
+0x97E6 0x6941 #CJK UNIFIED IDEOGRAPH
+0x97E7 0x6943 #CJK UNIFIED IDEOGRAPH
+0x97E8 0x6944 #CJK UNIFIED IDEOGRAPH
+0x97E9 0x6945 #CJK UNIFIED IDEOGRAPH
+0x97EA 0x6946 #CJK UNIFIED IDEOGRAPH
+0x97EB 0x6947 #CJK UNIFIED IDEOGRAPH
+0x97EC 0x6948 #CJK UNIFIED IDEOGRAPH
+0x97ED 0x6949 #CJK UNIFIED IDEOGRAPH
+0x97EE 0x694A #CJK UNIFIED IDEOGRAPH
+0x97EF 0x694B #CJK UNIFIED IDEOGRAPH
+0x97F0 0x694C #CJK UNIFIED IDEOGRAPH
+0x97F1 0x694D #CJK UNIFIED IDEOGRAPH
+0x97F2 0x694E #CJK UNIFIED IDEOGRAPH
+0x97F3 0x694F #CJK UNIFIED IDEOGRAPH
+0x97F4 0x6950 #CJK UNIFIED IDEOGRAPH
+0x97F5 0x6951 #CJK UNIFIED IDEOGRAPH
+0x97F6 0x6952 #CJK UNIFIED IDEOGRAPH
+0x97F7 0x6953 #CJK UNIFIED IDEOGRAPH
+0x97F8 0x6955 #CJK UNIFIED IDEOGRAPH
+0x97F9 0x6956 #CJK UNIFIED IDEOGRAPH
+0x97FA 0x6958 #CJK UNIFIED IDEOGRAPH
+0x97FB 0x6959 #CJK UNIFIED IDEOGRAPH
+0x97FC 0x695B #CJK UNIFIED IDEOGRAPH
+0x97FD 0x695C #CJK UNIFIED IDEOGRAPH
+0x97FE 0x695F #CJK UNIFIED IDEOGRAPH
+0x9840 0x6961 #CJK UNIFIED IDEOGRAPH
+0x9841 0x6962 #CJK UNIFIED IDEOGRAPH
+0x9842 0x6964 #CJK UNIFIED IDEOGRAPH
+0x9843 0x6965 #CJK UNIFIED IDEOGRAPH
+0x9844 0x6967 #CJK UNIFIED IDEOGRAPH
+0x9845 0x6968 #CJK UNIFIED IDEOGRAPH
+0x9846 0x6969 #CJK UNIFIED IDEOGRAPH
+0x9847 0x696A #CJK UNIFIED IDEOGRAPH
+0x9848 0x696C #CJK UNIFIED IDEOGRAPH
+0x9849 0x696D #CJK UNIFIED IDEOGRAPH
+0x984A 0x696F #CJK UNIFIED IDEOGRAPH
+0x984B 0x6970 #CJK UNIFIED IDEOGRAPH
+0x984C 0x6972 #CJK UNIFIED IDEOGRAPH
+0x984D 0x6973 #CJK UNIFIED IDEOGRAPH
+0x984E 0x6974 #CJK UNIFIED IDEOGRAPH
+0x984F 0x6975 #CJK UNIFIED IDEOGRAPH
+0x9850 0x6976 #CJK UNIFIED IDEOGRAPH
+0x9851 0x697A #CJK UNIFIED IDEOGRAPH
+0x9852 0x697B #CJK UNIFIED IDEOGRAPH
+0x9853 0x697D #CJK UNIFIED IDEOGRAPH
+0x9854 0x697E #CJK UNIFIED IDEOGRAPH
+0x9855 0x697F #CJK UNIFIED IDEOGRAPH
+0x9856 0x6981 #CJK UNIFIED IDEOGRAPH
+0x9857 0x6983 #CJK UNIFIED IDEOGRAPH
+0x9858 0x6985 #CJK UNIFIED IDEOGRAPH
+0x9859 0x698A #CJK UNIFIED IDEOGRAPH
+0x985A 0x698B #CJK UNIFIED IDEOGRAPH
+0x985B 0x698C #CJK UNIFIED IDEOGRAPH
+0x985C 0x698E #CJK UNIFIED IDEOGRAPH
+0x985D 0x698F #CJK UNIFIED IDEOGRAPH
+0x985E 0x6990 #CJK UNIFIED IDEOGRAPH
+0x985F 0x6991 #CJK UNIFIED IDEOGRAPH
+0x9860 0x6992 #CJK UNIFIED IDEOGRAPH
+0x9861 0x6993 #CJK UNIFIED IDEOGRAPH
+0x9862 0x6996 #CJK UNIFIED IDEOGRAPH
+0x9863 0x6997 #CJK UNIFIED IDEOGRAPH
+0x9864 0x6999 #CJK UNIFIED IDEOGRAPH
+0x9865 0x699A #CJK UNIFIED IDEOGRAPH
+0x9866 0x699D #CJK UNIFIED IDEOGRAPH
+0x9867 0x699E #CJK UNIFIED IDEOGRAPH
+0x9868 0x699F #CJK UNIFIED IDEOGRAPH
+0x9869 0x69A0 #CJK UNIFIED IDEOGRAPH
+0x986A 0x69A1 #CJK UNIFIED IDEOGRAPH
+0x986B 0x69A2 #CJK UNIFIED IDEOGRAPH
+0x986C 0x69A3 #CJK UNIFIED IDEOGRAPH
+0x986D 0x69A4 #CJK UNIFIED IDEOGRAPH
+0x986E 0x69A5 #CJK UNIFIED IDEOGRAPH
+0x986F 0x69A6 #CJK UNIFIED IDEOGRAPH
+0x9870 0x69A9 #CJK UNIFIED IDEOGRAPH
+0x9871 0x69AA #CJK UNIFIED IDEOGRAPH
+0x9872 0x69AC #CJK UNIFIED IDEOGRAPH
+0x9873 0x69AE #CJK UNIFIED IDEOGRAPH
+0x9874 0x69AF #CJK UNIFIED IDEOGRAPH
+0x9875 0x69B0 #CJK UNIFIED IDEOGRAPH
+0x9876 0x69B2 #CJK UNIFIED IDEOGRAPH
+0x9877 0x69B3 #CJK UNIFIED IDEOGRAPH
+0x9878 0x69B5 #CJK UNIFIED IDEOGRAPH
+0x9879 0x69B6 #CJK UNIFIED IDEOGRAPH
+0x987A 0x69B8 #CJK UNIFIED IDEOGRAPH
+0x987B 0x69B9 #CJK UNIFIED IDEOGRAPH
+0x987C 0x69BA #CJK UNIFIED IDEOGRAPH
+0x987D 0x69BC #CJK UNIFIED IDEOGRAPH
+0x987E 0x69BD #CJK UNIFIED IDEOGRAPH
+0x9880 0x69BE #CJK UNIFIED IDEOGRAPH
+0x9881 0x69BF #CJK UNIFIED IDEOGRAPH
+0x9882 0x69C0 #CJK UNIFIED IDEOGRAPH
+0x9883 0x69C2 #CJK UNIFIED IDEOGRAPH
+0x9884 0x69C3 #CJK UNIFIED IDEOGRAPH
+0x9885 0x69C4 #CJK UNIFIED IDEOGRAPH
+0x9886 0x69C5 #CJK UNIFIED IDEOGRAPH
+0x9887 0x69C6 #CJK UNIFIED IDEOGRAPH
+0x9888 0x69C7 #CJK UNIFIED IDEOGRAPH
+0x9889 0x69C8 #CJK UNIFIED IDEOGRAPH
+0x988A 0x69C9 #CJK UNIFIED IDEOGRAPH
+0x988B 0x69CB #CJK UNIFIED IDEOGRAPH
+0x988C 0x69CD #CJK UNIFIED IDEOGRAPH
+0x988D 0x69CF #CJK UNIFIED IDEOGRAPH
+0x988E 0x69D1 #CJK UNIFIED IDEOGRAPH
+0x988F 0x69D2 #CJK UNIFIED IDEOGRAPH
+0x9890 0x69D3 #CJK UNIFIED IDEOGRAPH
+0x9891 0x69D5 #CJK UNIFIED IDEOGRAPH
+0x9892 0x69D6 #CJK UNIFIED IDEOGRAPH
+0x9893 0x69D7 #CJK UNIFIED IDEOGRAPH
+0x9894 0x69D8 #CJK UNIFIED IDEOGRAPH
+0x9895 0x69D9 #CJK UNIFIED IDEOGRAPH
+0x9896 0x69DA #CJK UNIFIED IDEOGRAPH
+0x9897 0x69DC #CJK UNIFIED IDEOGRAPH
+0x9898 0x69DD #CJK UNIFIED IDEOGRAPH
+0x9899 0x69DE #CJK UNIFIED IDEOGRAPH
+0x989A 0x69E1 #CJK UNIFIED IDEOGRAPH
+0x989B 0x69E2 #CJK UNIFIED IDEOGRAPH
+0x989C 0x69E3 #CJK UNIFIED IDEOGRAPH
+0x989D 0x69E4 #CJK UNIFIED IDEOGRAPH
+0x989E 0x69E5 #CJK UNIFIED IDEOGRAPH
+0x989F 0x69E6 #CJK UNIFIED IDEOGRAPH
+0x98A0 0x69E7 #CJK UNIFIED IDEOGRAPH
+0x98A1 0x69E8 #CJK UNIFIED IDEOGRAPH
+0x98A2 0x69E9 #CJK UNIFIED IDEOGRAPH
+0x98A3 0x69EA #CJK UNIFIED IDEOGRAPH
+0x98A4 0x69EB #CJK UNIFIED IDEOGRAPH
+0x98A5 0x69EC #CJK UNIFIED IDEOGRAPH
+0x98A6 0x69EE #CJK UNIFIED IDEOGRAPH
+0x98A7 0x69EF #CJK UNIFIED IDEOGRAPH
+0x98A8 0x69F0 #CJK UNIFIED IDEOGRAPH
+0x98A9 0x69F1 #CJK UNIFIED IDEOGRAPH
+0x98AA 0x69F3 #CJK UNIFIED IDEOGRAPH
+0x98AB 0x69F4 #CJK UNIFIED IDEOGRAPH
+0x98AC 0x69F5 #CJK UNIFIED IDEOGRAPH
+0x98AD 0x69F6 #CJK UNIFIED IDEOGRAPH
+0x98AE 0x69F7 #CJK UNIFIED IDEOGRAPH
+0x98AF 0x69F8 #CJK UNIFIED IDEOGRAPH
+0x98B0 0x69F9 #CJK UNIFIED IDEOGRAPH
+0x98B1 0x69FA #CJK UNIFIED IDEOGRAPH
+0x98B2 0x69FB #CJK UNIFIED IDEOGRAPH
+0x98B3 0x69FC #CJK UNIFIED IDEOGRAPH
+0x98B4 0x69FE #CJK UNIFIED IDEOGRAPH
+0x98B5 0x6A00 #CJK UNIFIED IDEOGRAPH
+0x98B6 0x6A01 #CJK UNIFIED IDEOGRAPH
+0x98B7 0x6A02 #CJK UNIFIED IDEOGRAPH
+0x98B8 0x6A03 #CJK UNIFIED IDEOGRAPH
+0x98B9 0x6A04 #CJK UNIFIED IDEOGRAPH
+0x98BA 0x6A05 #CJK UNIFIED IDEOGRAPH
+0x98BB 0x6A06 #CJK UNIFIED IDEOGRAPH
+0x98BC 0x6A07 #CJK UNIFIED IDEOGRAPH
+0x98BD 0x6A08 #CJK UNIFIED IDEOGRAPH
+0x98BE 0x6A09 #CJK UNIFIED IDEOGRAPH
+0x98BF 0x6A0B #CJK UNIFIED IDEOGRAPH
+0x98C0 0x6A0C #CJK UNIFIED IDEOGRAPH
+0x98C1 0x6A0D #CJK UNIFIED IDEOGRAPH
+0x98C2 0x6A0E #CJK UNIFIED IDEOGRAPH
+0x98C3 0x6A0F #CJK UNIFIED IDEOGRAPH
+0x98C4 0x6A10 #CJK UNIFIED IDEOGRAPH
+0x98C5 0x6A11 #CJK UNIFIED IDEOGRAPH
+0x98C6 0x6A12 #CJK UNIFIED IDEOGRAPH
+0x98C7 0x6A13 #CJK UNIFIED IDEOGRAPH
+0x98C8 0x6A14 #CJK UNIFIED IDEOGRAPH
+0x98C9 0x6A15 #CJK UNIFIED IDEOGRAPH
+0x98CA 0x6A16 #CJK UNIFIED IDEOGRAPH
+0x98CB 0x6A19 #CJK UNIFIED IDEOGRAPH
+0x98CC 0x6A1A #CJK UNIFIED IDEOGRAPH
+0x98CD 0x6A1B #CJK UNIFIED IDEOGRAPH
+0x98CE 0x6A1C #CJK UNIFIED IDEOGRAPH
+0x98CF 0x6A1D #CJK UNIFIED IDEOGRAPH
+0x98D0 0x6A1E #CJK UNIFIED IDEOGRAPH
+0x98D1 0x6A20 #CJK UNIFIED IDEOGRAPH
+0x98D2 0x6A22 #CJK UNIFIED IDEOGRAPH
+0x98D3 0x6A23 #CJK UNIFIED IDEOGRAPH
+0x98D4 0x6A24 #CJK UNIFIED IDEOGRAPH
+0x98D5 0x6A25 #CJK UNIFIED IDEOGRAPH
+0x98D6 0x6A26 #CJK UNIFIED IDEOGRAPH
+0x98D7 0x6A27 #CJK UNIFIED IDEOGRAPH
+0x98D8 0x6A29 #CJK UNIFIED IDEOGRAPH
+0x98D9 0x6A2B #CJK UNIFIED IDEOGRAPH
+0x98DA 0x6A2C #CJK UNIFIED IDEOGRAPH
+0x98DB 0x6A2D #CJK UNIFIED IDEOGRAPH
+0x98DC 0x6A2E #CJK UNIFIED IDEOGRAPH
+0x98DD 0x6A30 #CJK UNIFIED IDEOGRAPH
+0x98DE 0x6A32 #CJK UNIFIED IDEOGRAPH
+0x98DF 0x6A33 #CJK UNIFIED IDEOGRAPH
+0x98E0 0x6A34 #CJK UNIFIED IDEOGRAPH
+0x98E1 0x6A36 #CJK UNIFIED IDEOGRAPH
+0x98E2 0x6A37 #CJK UNIFIED IDEOGRAPH
+0x98E3 0x6A38 #CJK UNIFIED IDEOGRAPH
+0x98E4 0x6A39 #CJK UNIFIED IDEOGRAPH
+0x98E5 0x6A3A #CJK UNIFIED IDEOGRAPH
+0x98E6 0x6A3B #CJK UNIFIED IDEOGRAPH
+0x98E7 0x6A3C #CJK UNIFIED IDEOGRAPH
+0x98E8 0x6A3F #CJK UNIFIED IDEOGRAPH
+0x98E9 0x6A40 #CJK UNIFIED IDEOGRAPH
+0x98EA 0x6A41 #CJK UNIFIED IDEOGRAPH
+0x98EB 0x6A42 #CJK UNIFIED IDEOGRAPH
+0x98EC 0x6A43 #CJK UNIFIED IDEOGRAPH
+0x98ED 0x6A45 #CJK UNIFIED IDEOGRAPH
+0x98EE 0x6A46 #CJK UNIFIED IDEOGRAPH
+0x98EF 0x6A48 #CJK UNIFIED IDEOGRAPH
+0x98F0 0x6A49 #CJK UNIFIED IDEOGRAPH
+0x98F1 0x6A4A #CJK UNIFIED IDEOGRAPH
+0x98F2 0x6A4B #CJK UNIFIED IDEOGRAPH
+0x98F3 0x6A4C #CJK UNIFIED IDEOGRAPH
+0x98F4 0x6A4D #CJK UNIFIED IDEOGRAPH
+0x98F5 0x6A4E #CJK UNIFIED IDEOGRAPH
+0x98F6 0x6A4F #CJK UNIFIED IDEOGRAPH
+0x98F7 0x6A51 #CJK UNIFIED IDEOGRAPH
+0x98F8 0x6A52 #CJK UNIFIED IDEOGRAPH
+0x98F9 0x6A53 #CJK UNIFIED IDEOGRAPH
+0x98FA 0x6A54 #CJK UNIFIED IDEOGRAPH
+0x98FB 0x6A55 #CJK UNIFIED IDEOGRAPH
+0x98FC 0x6A56 #CJK UNIFIED IDEOGRAPH
+0x98FD 0x6A57 #CJK UNIFIED IDEOGRAPH
+0x98FE 0x6A5A #CJK UNIFIED IDEOGRAPH
+0x9940 0x6A5C #CJK UNIFIED IDEOGRAPH
+0x9941 0x6A5D #CJK UNIFIED IDEOGRAPH
+0x9942 0x6A5E #CJK UNIFIED IDEOGRAPH
+0x9943 0x6A5F #CJK UNIFIED IDEOGRAPH
+0x9944 0x6A60 #CJK UNIFIED IDEOGRAPH
+0x9945 0x6A62 #CJK UNIFIED IDEOGRAPH
+0x9946 0x6A63 #CJK UNIFIED IDEOGRAPH
+0x9947 0x6A64 #CJK UNIFIED IDEOGRAPH
+0x9948 0x6A66 #CJK UNIFIED IDEOGRAPH
+0x9949 0x6A67 #CJK UNIFIED IDEOGRAPH
+0x994A 0x6A68 #CJK UNIFIED IDEOGRAPH
+0x994B 0x6A69 #CJK UNIFIED IDEOGRAPH
+0x994C 0x6A6A #CJK UNIFIED IDEOGRAPH
+0x994D 0x6A6B #CJK UNIFIED IDEOGRAPH
+0x994E 0x6A6C #CJK UNIFIED IDEOGRAPH
+0x994F 0x6A6D #CJK UNIFIED IDEOGRAPH
+0x9950 0x6A6E #CJK UNIFIED IDEOGRAPH
+0x9951 0x6A6F #CJK UNIFIED IDEOGRAPH
+0x9952 0x6A70 #CJK UNIFIED IDEOGRAPH
+0x9953 0x6A72 #CJK UNIFIED IDEOGRAPH
+0x9954 0x6A73 #CJK UNIFIED IDEOGRAPH
+0x9955 0x6A74 #CJK UNIFIED IDEOGRAPH
+0x9956 0x6A75 #CJK UNIFIED IDEOGRAPH
+0x9957 0x6A76 #CJK UNIFIED IDEOGRAPH
+0x9958 0x6A77 #CJK UNIFIED IDEOGRAPH
+0x9959 0x6A78 #CJK UNIFIED IDEOGRAPH
+0x995A 0x6A7A #CJK UNIFIED IDEOGRAPH
+0x995B 0x6A7B #CJK UNIFIED IDEOGRAPH
+0x995C 0x6A7D #CJK UNIFIED IDEOGRAPH
+0x995D 0x6A7E #CJK UNIFIED IDEOGRAPH
+0x995E 0x6A7F #CJK UNIFIED IDEOGRAPH
+0x995F 0x6A81 #CJK UNIFIED IDEOGRAPH
+0x9960 0x6A82 #CJK UNIFIED IDEOGRAPH
+0x9961 0x6A83 #CJK UNIFIED IDEOGRAPH
+0x9962 0x6A85 #CJK UNIFIED IDEOGRAPH
+0x9963 0x6A86 #CJK UNIFIED IDEOGRAPH
+0x9964 0x6A87 #CJK UNIFIED IDEOGRAPH
+0x9965 0x6A88 #CJK UNIFIED IDEOGRAPH
+0x9966 0x6A89 #CJK UNIFIED IDEOGRAPH
+0x9967 0x6A8A #CJK UNIFIED IDEOGRAPH
+0x9968 0x6A8B #CJK UNIFIED IDEOGRAPH
+0x9969 0x6A8C #CJK UNIFIED IDEOGRAPH
+0x996A 0x6A8D #CJK UNIFIED IDEOGRAPH
+0x996B 0x6A8F #CJK UNIFIED IDEOGRAPH
+0x996C 0x6A92 #CJK UNIFIED IDEOGRAPH
+0x996D 0x6A93 #CJK UNIFIED IDEOGRAPH
+0x996E 0x6A94 #CJK UNIFIED IDEOGRAPH
+0x996F 0x6A95 #CJK UNIFIED IDEOGRAPH
+0x9970 0x6A96 #CJK UNIFIED IDEOGRAPH
+0x9971 0x6A98 #CJK UNIFIED IDEOGRAPH
+0x9972 0x6A99 #CJK UNIFIED IDEOGRAPH
+0x9973 0x6A9A #CJK UNIFIED IDEOGRAPH
+0x9974 0x6A9B #CJK UNIFIED IDEOGRAPH
+0x9975 0x6A9C #CJK UNIFIED IDEOGRAPH
+0x9976 0x6A9D #CJK UNIFIED IDEOGRAPH
+0x9977 0x6A9E #CJK UNIFIED IDEOGRAPH
+0x9978 0x6A9F #CJK UNIFIED IDEOGRAPH
+0x9979 0x6AA1 #CJK UNIFIED IDEOGRAPH
+0x997A 0x6AA2 #CJK UNIFIED IDEOGRAPH
+0x997B 0x6AA3 #CJK UNIFIED IDEOGRAPH
+0x997C 0x6AA4 #CJK UNIFIED IDEOGRAPH
+0x997D 0x6AA5 #CJK UNIFIED IDEOGRAPH
+0x997E 0x6AA6 #CJK UNIFIED IDEOGRAPH
+0x9980 0x6AA7 #CJK UNIFIED IDEOGRAPH
+0x9981 0x6AA8 #CJK UNIFIED IDEOGRAPH
+0x9982 0x6AAA #CJK UNIFIED IDEOGRAPH
+0x9983 0x6AAD #CJK UNIFIED IDEOGRAPH
+0x9984 0x6AAE #CJK UNIFIED IDEOGRAPH
+0x9985 0x6AAF #CJK UNIFIED IDEOGRAPH
+0x9986 0x6AB0 #CJK UNIFIED IDEOGRAPH
+0x9987 0x6AB1 #CJK UNIFIED IDEOGRAPH
+0x9988 0x6AB2 #CJK UNIFIED IDEOGRAPH
+0x9989 0x6AB3 #CJK UNIFIED IDEOGRAPH
+0x998A 0x6AB4 #CJK UNIFIED IDEOGRAPH
+0x998B 0x6AB5 #CJK UNIFIED IDEOGRAPH
+0x998C 0x6AB6 #CJK UNIFIED IDEOGRAPH
+0x998D 0x6AB7 #CJK UNIFIED IDEOGRAPH
+0x998E 0x6AB8 #CJK UNIFIED IDEOGRAPH
+0x998F 0x6AB9 #CJK UNIFIED IDEOGRAPH
+0x9990 0x6ABA #CJK UNIFIED IDEOGRAPH
+0x9991 0x6ABB #CJK UNIFIED IDEOGRAPH
+0x9992 0x6ABC #CJK UNIFIED IDEOGRAPH
+0x9993 0x6ABD #CJK UNIFIED IDEOGRAPH
+0x9994 0x6ABE #CJK UNIFIED IDEOGRAPH
+0x9995 0x6ABF #CJK UNIFIED IDEOGRAPH
+0x9996 0x6AC0 #CJK UNIFIED IDEOGRAPH
+0x9997 0x6AC1 #CJK UNIFIED IDEOGRAPH
+0x9998 0x6AC2 #CJK UNIFIED IDEOGRAPH
+0x9999 0x6AC3 #CJK UNIFIED IDEOGRAPH
+0x999A 0x6AC4 #CJK UNIFIED IDEOGRAPH
+0x999B 0x6AC5 #CJK UNIFIED IDEOGRAPH
+0x999C 0x6AC6 #CJK UNIFIED IDEOGRAPH
+0x999D 0x6AC7 #CJK UNIFIED IDEOGRAPH
+0x999E 0x6AC8 #CJK UNIFIED IDEOGRAPH
+0x999F 0x6AC9 #CJK UNIFIED IDEOGRAPH
+0x99A0 0x6ACA #CJK UNIFIED IDEOGRAPH
+0x99A1 0x6ACB #CJK UNIFIED IDEOGRAPH
+0x99A2 0x6ACC #CJK UNIFIED IDEOGRAPH
+0x99A3 0x6ACD #CJK UNIFIED IDEOGRAPH
+0x99A4 0x6ACE #CJK UNIFIED IDEOGRAPH
+0x99A5 0x6ACF #CJK UNIFIED IDEOGRAPH
+0x99A6 0x6AD0 #CJK UNIFIED IDEOGRAPH
+0x99A7 0x6AD1 #CJK UNIFIED IDEOGRAPH
+0x99A8 0x6AD2 #CJK UNIFIED IDEOGRAPH
+0x99A9 0x6AD3 #CJK UNIFIED IDEOGRAPH
+0x99AA 0x6AD4 #CJK UNIFIED IDEOGRAPH
+0x99AB 0x6AD5 #CJK UNIFIED IDEOGRAPH
+0x99AC 0x6AD6 #CJK UNIFIED IDEOGRAPH
+0x99AD 0x6AD7 #CJK UNIFIED IDEOGRAPH
+0x99AE 0x6AD8 #CJK UNIFIED IDEOGRAPH
+0x99AF 0x6AD9 #CJK UNIFIED IDEOGRAPH
+0x99B0 0x6ADA #CJK UNIFIED IDEOGRAPH
+0x99B1 0x6ADB #CJK UNIFIED IDEOGRAPH
+0x99B2 0x6ADC #CJK UNIFIED IDEOGRAPH
+0x99B3 0x6ADD #CJK UNIFIED IDEOGRAPH
+0x99B4 0x6ADE #CJK UNIFIED IDEOGRAPH
+0x99B5 0x6ADF #CJK UNIFIED IDEOGRAPH
+0x99B6 0x6AE0 #CJK UNIFIED IDEOGRAPH
+0x99B7 0x6AE1 #CJK UNIFIED IDEOGRAPH
+0x99B8 0x6AE2 #CJK UNIFIED IDEOGRAPH
+0x99B9 0x6AE3 #CJK UNIFIED IDEOGRAPH
+0x99BA 0x6AE4 #CJK UNIFIED IDEOGRAPH
+0x99BB 0x6AE5 #CJK UNIFIED IDEOGRAPH
+0x99BC 0x6AE6 #CJK UNIFIED IDEOGRAPH
+0x99BD 0x6AE7 #CJK UNIFIED IDEOGRAPH
+0x99BE 0x6AE8 #CJK UNIFIED IDEOGRAPH
+0x99BF 0x6AE9 #CJK UNIFIED IDEOGRAPH
+0x99C0 0x6AEA #CJK UNIFIED IDEOGRAPH
+0x99C1 0x6AEB #CJK UNIFIED IDEOGRAPH
+0x99C2 0x6AEC #CJK UNIFIED IDEOGRAPH
+0x99C3 0x6AED #CJK UNIFIED IDEOGRAPH
+0x99C4 0x6AEE #CJK UNIFIED IDEOGRAPH
+0x99C5 0x6AEF #CJK UNIFIED IDEOGRAPH
+0x99C6 0x6AF0 #CJK UNIFIED IDEOGRAPH
+0x99C7 0x6AF1 #CJK UNIFIED IDEOGRAPH
+0x99C8 0x6AF2 #CJK UNIFIED IDEOGRAPH
+0x99C9 0x6AF3 #CJK UNIFIED IDEOGRAPH
+0x99CA 0x6AF4 #CJK UNIFIED IDEOGRAPH
+0x99CB 0x6AF5 #CJK UNIFIED IDEOGRAPH
+0x99CC 0x6AF6 #CJK UNIFIED IDEOGRAPH
+0x99CD 0x6AF7 #CJK UNIFIED IDEOGRAPH
+0x99CE 0x6AF8 #CJK UNIFIED IDEOGRAPH
+0x99CF 0x6AF9 #CJK UNIFIED IDEOGRAPH
+0x99D0 0x6AFA #CJK UNIFIED IDEOGRAPH
+0x99D1 0x6AFB #CJK UNIFIED IDEOGRAPH
+0x99D2 0x6AFC #CJK UNIFIED IDEOGRAPH
+0x99D3 0x6AFD #CJK UNIFIED IDEOGRAPH
+0x99D4 0x6AFE #CJK UNIFIED IDEOGRAPH
+0x99D5 0x6AFF #CJK UNIFIED IDEOGRAPH
+0x99D6 0x6B00 #CJK UNIFIED IDEOGRAPH
+0x99D7 0x6B01 #CJK UNIFIED IDEOGRAPH
+0x99D8 0x6B02 #CJK UNIFIED IDEOGRAPH
+0x99D9 0x6B03 #CJK UNIFIED IDEOGRAPH
+0x99DA 0x6B04 #CJK UNIFIED IDEOGRAPH
+0x99DB 0x6B05 #CJK UNIFIED IDEOGRAPH
+0x99DC 0x6B06 #CJK UNIFIED IDEOGRAPH
+0x99DD 0x6B07 #CJK UNIFIED IDEOGRAPH
+0x99DE 0x6B08 #CJK UNIFIED IDEOGRAPH
+0x99DF 0x6B09 #CJK UNIFIED IDEOGRAPH
+0x99E0 0x6B0A #CJK UNIFIED IDEOGRAPH
+0x99E1 0x6B0B #CJK UNIFIED IDEOGRAPH
+0x99E2 0x6B0C #CJK UNIFIED IDEOGRAPH
+0x99E3 0x6B0D #CJK UNIFIED IDEOGRAPH
+0x99E4 0x6B0E #CJK UNIFIED IDEOGRAPH
+0x99E5 0x6B0F #CJK UNIFIED IDEOGRAPH
+0x99E6 0x6B10 #CJK UNIFIED IDEOGRAPH
+0x99E7 0x6B11 #CJK UNIFIED IDEOGRAPH
+0x99E8 0x6B12 #CJK UNIFIED IDEOGRAPH
+0x99E9 0x6B13 #CJK UNIFIED IDEOGRAPH
+0x99EA 0x6B14 #CJK UNIFIED IDEOGRAPH
+0x99EB 0x6B15 #CJK UNIFIED IDEOGRAPH
+0x99EC 0x6B16 #CJK UNIFIED IDEOGRAPH
+0x99ED 0x6B17 #CJK UNIFIED IDEOGRAPH
+0x99EE 0x6B18 #CJK UNIFIED IDEOGRAPH
+0x99EF 0x6B19 #CJK UNIFIED IDEOGRAPH
+0x99F0 0x6B1A #CJK UNIFIED IDEOGRAPH
+0x99F1 0x6B1B #CJK UNIFIED IDEOGRAPH
+0x99F2 0x6B1C #CJK UNIFIED IDEOGRAPH
+0x99F3 0x6B1D #CJK UNIFIED IDEOGRAPH
+0x99F4 0x6B1E #CJK UNIFIED IDEOGRAPH
+0x99F5 0x6B1F #CJK UNIFIED IDEOGRAPH
+0x99F6 0x6B25 #CJK UNIFIED IDEOGRAPH
+0x99F7 0x6B26 #CJK UNIFIED IDEOGRAPH
+0x99F8 0x6B28 #CJK UNIFIED IDEOGRAPH
+0x99F9 0x6B29 #CJK UNIFIED IDEOGRAPH
+0x99FA 0x6B2A #CJK UNIFIED IDEOGRAPH
+0x99FB 0x6B2B #CJK UNIFIED IDEOGRAPH
+0x99FC 0x6B2C #CJK UNIFIED IDEOGRAPH
+0x99FD 0x6B2D #CJK UNIFIED IDEOGRAPH
+0x99FE 0x6B2E #CJK UNIFIED IDEOGRAPH
+0x9A40 0x6B2F #CJK UNIFIED IDEOGRAPH
+0x9A41 0x6B30 #CJK UNIFIED IDEOGRAPH
+0x9A42 0x6B31 #CJK UNIFIED IDEOGRAPH
+0x9A43 0x6B33 #CJK UNIFIED IDEOGRAPH
+0x9A44 0x6B34 #CJK UNIFIED IDEOGRAPH
+0x9A45 0x6B35 #CJK UNIFIED IDEOGRAPH
+0x9A46 0x6B36 #CJK UNIFIED IDEOGRAPH
+0x9A47 0x6B38 #CJK UNIFIED IDEOGRAPH
+0x9A48 0x6B3B #CJK UNIFIED IDEOGRAPH
+0x9A49 0x6B3C #CJK UNIFIED IDEOGRAPH
+0x9A4A 0x6B3D #CJK UNIFIED IDEOGRAPH
+0x9A4B 0x6B3F #CJK UNIFIED IDEOGRAPH
+0x9A4C 0x6B40 #CJK UNIFIED IDEOGRAPH
+0x9A4D 0x6B41 #CJK UNIFIED IDEOGRAPH
+0x9A4E 0x6B42 #CJK UNIFIED IDEOGRAPH
+0x9A4F 0x6B44 #CJK UNIFIED IDEOGRAPH
+0x9A50 0x6B45 #CJK UNIFIED IDEOGRAPH
+0x9A51 0x6B48 #CJK UNIFIED IDEOGRAPH
+0x9A52 0x6B4A #CJK UNIFIED IDEOGRAPH
+0x9A53 0x6B4B #CJK UNIFIED IDEOGRAPH
+0x9A54 0x6B4D #CJK UNIFIED IDEOGRAPH
+0x9A55 0x6B4E #CJK UNIFIED IDEOGRAPH
+0x9A56 0x6B4F #CJK UNIFIED IDEOGRAPH
+0x9A57 0x6B50 #CJK UNIFIED IDEOGRAPH
+0x9A58 0x6B51 #CJK UNIFIED IDEOGRAPH
+0x9A59 0x6B52 #CJK UNIFIED IDEOGRAPH
+0x9A5A 0x6B53 #CJK UNIFIED IDEOGRAPH
+0x9A5B 0x6B54 #CJK UNIFIED IDEOGRAPH
+0x9A5C 0x6B55 #CJK UNIFIED IDEOGRAPH
+0x9A5D 0x6B56 #CJK UNIFIED IDEOGRAPH
+0x9A5E 0x6B57 #CJK UNIFIED IDEOGRAPH
+0x9A5F 0x6B58 #CJK UNIFIED IDEOGRAPH
+0x9A60 0x6B5A #CJK UNIFIED IDEOGRAPH
+0x9A61 0x6B5B #CJK UNIFIED IDEOGRAPH
+0x9A62 0x6B5C #CJK UNIFIED IDEOGRAPH
+0x9A63 0x6B5D #CJK UNIFIED IDEOGRAPH
+0x9A64 0x6B5E #CJK UNIFIED IDEOGRAPH
+0x9A65 0x6B5F #CJK UNIFIED IDEOGRAPH
+0x9A66 0x6B60 #CJK UNIFIED IDEOGRAPH
+0x9A67 0x6B61 #CJK UNIFIED IDEOGRAPH
+0x9A68 0x6B68 #CJK UNIFIED IDEOGRAPH
+0x9A69 0x6B69 #CJK UNIFIED IDEOGRAPH
+0x9A6A 0x6B6B #CJK UNIFIED IDEOGRAPH
+0x9A6B 0x6B6C #CJK UNIFIED IDEOGRAPH
+0x9A6C 0x6B6D #CJK UNIFIED IDEOGRAPH
+0x9A6D 0x6B6E #CJK UNIFIED IDEOGRAPH
+0x9A6E 0x6B6F #CJK UNIFIED IDEOGRAPH
+0x9A6F 0x6B70 #CJK UNIFIED IDEOGRAPH
+0x9A70 0x6B71 #CJK UNIFIED IDEOGRAPH
+0x9A71 0x6B72 #CJK UNIFIED IDEOGRAPH
+0x9A72 0x6B73 #CJK UNIFIED IDEOGRAPH
+0x9A73 0x6B74 #CJK UNIFIED IDEOGRAPH
+0x9A74 0x6B75 #CJK UNIFIED IDEOGRAPH
+0x9A75 0x6B76 #CJK UNIFIED IDEOGRAPH
+0x9A76 0x6B77 #CJK UNIFIED IDEOGRAPH
+0x9A77 0x6B78 #CJK UNIFIED IDEOGRAPH
+0x9A78 0x6B7A #CJK UNIFIED IDEOGRAPH
+0x9A79 0x6B7D #CJK UNIFIED IDEOGRAPH
+0x9A7A 0x6B7E #CJK UNIFIED IDEOGRAPH
+0x9A7B 0x6B7F #CJK UNIFIED IDEOGRAPH
+0x9A7C 0x6B80 #CJK UNIFIED IDEOGRAPH
+0x9A7D 0x6B85 #CJK UNIFIED IDEOGRAPH
+0x9A7E 0x6B88 #CJK UNIFIED IDEOGRAPH
+0x9A80 0x6B8C #CJK UNIFIED IDEOGRAPH
+0x9A81 0x6B8E #CJK UNIFIED IDEOGRAPH
+0x9A82 0x6B8F #CJK UNIFIED IDEOGRAPH
+0x9A83 0x6B90 #CJK UNIFIED IDEOGRAPH
+0x9A84 0x6B91 #CJK UNIFIED IDEOGRAPH
+0x9A85 0x6B94 #CJK UNIFIED IDEOGRAPH
+0x9A86 0x6B95 #CJK UNIFIED IDEOGRAPH
+0x9A87 0x6B97 #CJK UNIFIED IDEOGRAPH
+0x9A88 0x6B98 #CJK UNIFIED IDEOGRAPH
+0x9A89 0x6B99 #CJK UNIFIED IDEOGRAPH
+0x9A8A 0x6B9C #CJK UNIFIED IDEOGRAPH
+0x9A8B 0x6B9D #CJK UNIFIED IDEOGRAPH
+0x9A8C 0x6B9E #CJK UNIFIED IDEOGRAPH
+0x9A8D 0x6B9F #CJK UNIFIED IDEOGRAPH
+0x9A8E 0x6BA0 #CJK UNIFIED IDEOGRAPH
+0x9A8F 0x6BA2 #CJK UNIFIED IDEOGRAPH
+0x9A90 0x6BA3 #CJK UNIFIED IDEOGRAPH
+0x9A91 0x6BA4 #CJK UNIFIED IDEOGRAPH
+0x9A92 0x6BA5 #CJK UNIFIED IDEOGRAPH
+0x9A93 0x6BA6 #CJK UNIFIED IDEOGRAPH
+0x9A94 0x6BA7 #CJK UNIFIED IDEOGRAPH
+0x9A95 0x6BA8 #CJK UNIFIED IDEOGRAPH
+0x9A96 0x6BA9 #CJK UNIFIED IDEOGRAPH
+0x9A97 0x6BAB #CJK UNIFIED IDEOGRAPH
+0x9A98 0x6BAC #CJK UNIFIED IDEOGRAPH
+0x9A99 0x6BAD #CJK UNIFIED IDEOGRAPH
+0x9A9A 0x6BAE #CJK UNIFIED IDEOGRAPH
+0x9A9B 0x6BAF #CJK UNIFIED IDEOGRAPH
+0x9A9C 0x6BB0 #CJK UNIFIED IDEOGRAPH
+0x9A9D 0x6BB1 #CJK UNIFIED IDEOGRAPH
+0x9A9E 0x6BB2 #CJK UNIFIED IDEOGRAPH
+0x9A9F 0x6BB6 #CJK UNIFIED IDEOGRAPH
+0x9AA0 0x6BB8 #CJK UNIFIED IDEOGRAPH
+0x9AA1 0x6BB9 #CJK UNIFIED IDEOGRAPH
+0x9AA2 0x6BBA #CJK UNIFIED IDEOGRAPH
+0x9AA3 0x6BBB #CJK UNIFIED IDEOGRAPH
+0x9AA4 0x6BBC #CJK UNIFIED IDEOGRAPH
+0x9AA5 0x6BBD #CJK UNIFIED IDEOGRAPH
+0x9AA6 0x6BBE #CJK UNIFIED IDEOGRAPH
+0x9AA7 0x6BC0 #CJK UNIFIED IDEOGRAPH
+0x9AA8 0x6BC3 #CJK UNIFIED IDEOGRAPH
+0x9AA9 0x6BC4 #CJK UNIFIED IDEOGRAPH
+0x9AAA 0x6BC6 #CJK UNIFIED IDEOGRAPH
+0x9AAB 0x6BC7 #CJK UNIFIED IDEOGRAPH
+0x9AAC 0x6BC8 #CJK UNIFIED IDEOGRAPH
+0x9AAD 0x6BC9 #CJK UNIFIED IDEOGRAPH
+0x9AAE 0x6BCA #CJK UNIFIED IDEOGRAPH
+0x9AAF 0x6BCC #CJK UNIFIED IDEOGRAPH
+0x9AB0 0x6BCE #CJK UNIFIED IDEOGRAPH
+0x9AB1 0x6BD0 #CJK UNIFIED IDEOGRAPH
+0x9AB2 0x6BD1 #CJK UNIFIED IDEOGRAPH
+0x9AB3 0x6BD8 #CJK UNIFIED IDEOGRAPH
+0x9AB4 0x6BDA #CJK UNIFIED IDEOGRAPH
+0x9AB5 0x6BDC #CJK UNIFIED IDEOGRAPH
+0x9AB6 0x6BDD #CJK UNIFIED IDEOGRAPH
+0x9AB7 0x6BDE #CJK UNIFIED IDEOGRAPH
+0x9AB8 0x6BDF #CJK UNIFIED IDEOGRAPH
+0x9AB9 0x6BE0 #CJK UNIFIED IDEOGRAPH
+0x9ABA 0x6BE2 #CJK UNIFIED IDEOGRAPH
+0x9ABB 0x6BE3 #CJK UNIFIED IDEOGRAPH
+0x9ABC 0x6BE4 #CJK UNIFIED IDEOGRAPH
+0x9ABD 0x6BE5 #CJK UNIFIED IDEOGRAPH
+0x9ABE 0x6BE6 #CJK UNIFIED IDEOGRAPH
+0x9ABF 0x6BE7 #CJK UNIFIED IDEOGRAPH
+0x9AC0 0x6BE8 #CJK UNIFIED IDEOGRAPH
+0x9AC1 0x6BE9 #CJK UNIFIED IDEOGRAPH
+0x9AC2 0x6BEC #CJK UNIFIED IDEOGRAPH
+0x9AC3 0x6BED #CJK UNIFIED IDEOGRAPH
+0x9AC4 0x6BEE #CJK UNIFIED IDEOGRAPH
+0x9AC5 0x6BF0 #CJK UNIFIED IDEOGRAPH
+0x9AC6 0x6BF1 #CJK UNIFIED IDEOGRAPH
+0x9AC7 0x6BF2 #CJK UNIFIED IDEOGRAPH
+0x9AC8 0x6BF4 #CJK UNIFIED IDEOGRAPH
+0x9AC9 0x6BF6 #CJK UNIFIED IDEOGRAPH
+0x9ACA 0x6BF7 #CJK UNIFIED IDEOGRAPH
+0x9ACB 0x6BF8 #CJK UNIFIED IDEOGRAPH
+0x9ACC 0x6BFA #CJK UNIFIED IDEOGRAPH
+0x9ACD 0x6BFB #CJK UNIFIED IDEOGRAPH
+0x9ACE 0x6BFC #CJK UNIFIED IDEOGRAPH
+0x9ACF 0x6BFE #CJK UNIFIED IDEOGRAPH
+0x9AD0 0x6BFF #CJK UNIFIED IDEOGRAPH
+0x9AD1 0x6C00 #CJK UNIFIED IDEOGRAPH
+0x9AD2 0x6C01 #CJK UNIFIED IDEOGRAPH
+0x9AD3 0x6C02 #CJK UNIFIED IDEOGRAPH
+0x9AD4 0x6C03 #CJK UNIFIED IDEOGRAPH
+0x9AD5 0x6C04 #CJK UNIFIED IDEOGRAPH
+0x9AD6 0x6C08 #CJK UNIFIED IDEOGRAPH
+0x9AD7 0x6C09 #CJK UNIFIED IDEOGRAPH
+0x9AD8 0x6C0A #CJK UNIFIED IDEOGRAPH
+0x9AD9 0x6C0B #CJK UNIFIED IDEOGRAPH
+0x9ADA 0x6C0C #CJK UNIFIED IDEOGRAPH
+0x9ADB 0x6C0E #CJK UNIFIED IDEOGRAPH
+0x9ADC 0x6C12 #CJK UNIFIED IDEOGRAPH
+0x9ADD 0x6C17 #CJK UNIFIED IDEOGRAPH
+0x9ADE 0x6C1C #CJK UNIFIED IDEOGRAPH
+0x9ADF 0x6C1D #CJK UNIFIED IDEOGRAPH
+0x9AE0 0x6C1E #CJK UNIFIED IDEOGRAPH
+0x9AE1 0x6C20 #CJK UNIFIED IDEOGRAPH
+0x9AE2 0x6C23 #CJK UNIFIED IDEOGRAPH
+0x9AE3 0x6C25 #CJK UNIFIED IDEOGRAPH
+0x9AE4 0x6C2B #CJK UNIFIED IDEOGRAPH
+0x9AE5 0x6C2C #CJK UNIFIED IDEOGRAPH
+0x9AE6 0x6C2D #CJK UNIFIED IDEOGRAPH
+0x9AE7 0x6C31 #CJK UNIFIED IDEOGRAPH
+0x9AE8 0x6C33 #CJK UNIFIED IDEOGRAPH
+0x9AE9 0x6C36 #CJK UNIFIED IDEOGRAPH
+0x9AEA 0x6C37 #CJK UNIFIED IDEOGRAPH
+0x9AEB 0x6C39 #CJK UNIFIED IDEOGRAPH
+0x9AEC 0x6C3A #CJK UNIFIED IDEOGRAPH
+0x9AED 0x6C3B #CJK UNIFIED IDEOGRAPH
+0x9AEE 0x6C3C #CJK UNIFIED IDEOGRAPH
+0x9AEF 0x6C3E #CJK UNIFIED IDEOGRAPH
+0x9AF0 0x6C3F #CJK UNIFIED IDEOGRAPH
+0x9AF1 0x6C43 #CJK UNIFIED IDEOGRAPH
+0x9AF2 0x6C44 #CJK UNIFIED IDEOGRAPH
+0x9AF3 0x6C45 #CJK UNIFIED IDEOGRAPH
+0x9AF4 0x6C48 #CJK UNIFIED IDEOGRAPH
+0x9AF5 0x6C4B #CJK UNIFIED IDEOGRAPH
+0x9AF6 0x6C4C #CJK UNIFIED IDEOGRAPH
+0x9AF7 0x6C4D #CJK UNIFIED IDEOGRAPH
+0x9AF8 0x6C4E #CJK UNIFIED IDEOGRAPH
+0x9AF9 0x6C4F #CJK UNIFIED IDEOGRAPH
+0x9AFA 0x6C51 #CJK UNIFIED IDEOGRAPH
+0x9AFB 0x6C52 #CJK UNIFIED IDEOGRAPH
+0x9AFC 0x6C53 #CJK UNIFIED IDEOGRAPH
+0x9AFD 0x6C56 #CJK UNIFIED IDEOGRAPH
+0x9AFE 0x6C58 #CJK UNIFIED IDEOGRAPH
+0x9B40 0x6C59 #CJK UNIFIED IDEOGRAPH
+0x9B41 0x6C5A #CJK UNIFIED IDEOGRAPH
+0x9B42 0x6C62 #CJK UNIFIED IDEOGRAPH
+0x9B43 0x6C63 #CJK UNIFIED IDEOGRAPH
+0x9B44 0x6C65 #CJK UNIFIED IDEOGRAPH
+0x9B45 0x6C66 #CJK UNIFIED IDEOGRAPH
+0x9B46 0x6C67 #CJK UNIFIED IDEOGRAPH
+0x9B47 0x6C6B #CJK UNIFIED IDEOGRAPH
+0x9B48 0x6C6C #CJK UNIFIED IDEOGRAPH
+0x9B49 0x6C6D #CJK UNIFIED IDEOGRAPH
+0x9B4A 0x6C6E #CJK UNIFIED IDEOGRAPH
+0x9B4B 0x6C6F #CJK UNIFIED IDEOGRAPH
+0x9B4C 0x6C71 #CJK UNIFIED IDEOGRAPH
+0x9B4D 0x6C73 #CJK UNIFIED IDEOGRAPH
+0x9B4E 0x6C75 #CJK UNIFIED IDEOGRAPH
+0x9B4F 0x6C77 #CJK UNIFIED IDEOGRAPH
+0x9B50 0x6C78 #CJK UNIFIED IDEOGRAPH
+0x9B51 0x6C7A #CJK UNIFIED IDEOGRAPH
+0x9B52 0x6C7B #CJK UNIFIED IDEOGRAPH
+0x9B53 0x6C7C #CJK UNIFIED IDEOGRAPH
+0x9B54 0x6C7F #CJK UNIFIED IDEOGRAPH
+0x9B55 0x6C80 #CJK UNIFIED IDEOGRAPH
+0x9B56 0x6C84 #CJK UNIFIED IDEOGRAPH
+0x9B57 0x6C87 #CJK UNIFIED IDEOGRAPH
+0x9B58 0x6C8A #CJK UNIFIED IDEOGRAPH
+0x9B59 0x6C8B #CJK UNIFIED IDEOGRAPH
+0x9B5A 0x6C8D #CJK UNIFIED IDEOGRAPH
+0x9B5B 0x6C8E #CJK UNIFIED IDEOGRAPH
+0x9B5C 0x6C91 #CJK UNIFIED IDEOGRAPH
+0x9B5D 0x6C92 #CJK UNIFIED IDEOGRAPH
+0x9B5E 0x6C95 #CJK UNIFIED IDEOGRAPH
+0x9B5F 0x6C96 #CJK UNIFIED IDEOGRAPH
+0x9B60 0x6C97 #CJK UNIFIED IDEOGRAPH
+0x9B61 0x6C98 #CJK UNIFIED IDEOGRAPH
+0x9B62 0x6C9A #CJK UNIFIED IDEOGRAPH
+0x9B63 0x6C9C #CJK UNIFIED IDEOGRAPH
+0x9B64 0x6C9D #CJK UNIFIED IDEOGRAPH
+0x9B65 0x6C9E #CJK UNIFIED IDEOGRAPH
+0x9B66 0x6CA0 #CJK UNIFIED IDEOGRAPH
+0x9B67 0x6CA2 #CJK UNIFIED IDEOGRAPH
+0x9B68 0x6CA8 #CJK UNIFIED IDEOGRAPH
+0x9B69 0x6CAC #CJK UNIFIED IDEOGRAPH
+0x9B6A 0x6CAF #CJK UNIFIED IDEOGRAPH
+0x9B6B 0x6CB0 #CJK UNIFIED IDEOGRAPH
+0x9B6C 0x6CB4 #CJK UNIFIED IDEOGRAPH
+0x9B6D 0x6CB5 #CJK UNIFIED IDEOGRAPH
+0x9B6E 0x6CB6 #CJK UNIFIED IDEOGRAPH
+0x9B6F 0x6CB7 #CJK UNIFIED IDEOGRAPH
+0x9B70 0x6CBA #CJK UNIFIED IDEOGRAPH
+0x9B71 0x6CC0 #CJK UNIFIED IDEOGRAPH
+0x9B72 0x6CC1 #CJK UNIFIED IDEOGRAPH
+0x9B73 0x6CC2 #CJK UNIFIED IDEOGRAPH
+0x9B74 0x6CC3 #CJK UNIFIED IDEOGRAPH
+0x9B75 0x6CC6 #CJK UNIFIED IDEOGRAPH
+0x9B76 0x6CC7 #CJK UNIFIED IDEOGRAPH
+0x9B77 0x6CC8 #CJK UNIFIED IDEOGRAPH
+0x9B78 0x6CCB #CJK UNIFIED IDEOGRAPH
+0x9B79 0x6CCD #CJK UNIFIED IDEOGRAPH
+0x9B7A 0x6CCE #CJK UNIFIED IDEOGRAPH
+0x9B7B 0x6CCF #CJK UNIFIED IDEOGRAPH
+0x9B7C 0x6CD1 #CJK UNIFIED IDEOGRAPH
+0x9B7D 0x6CD2 #CJK UNIFIED IDEOGRAPH
+0x9B7E 0x6CD8 #CJK UNIFIED IDEOGRAPH
+0x9B80 0x6CD9 #CJK UNIFIED IDEOGRAPH
+0x9B81 0x6CDA #CJK UNIFIED IDEOGRAPH
+0x9B82 0x6CDC #CJK UNIFIED IDEOGRAPH
+0x9B83 0x6CDD #CJK UNIFIED IDEOGRAPH
+0x9B84 0x6CDF #CJK UNIFIED IDEOGRAPH
+0x9B85 0x6CE4 #CJK UNIFIED IDEOGRAPH
+0x9B86 0x6CE6 #CJK UNIFIED IDEOGRAPH
+0x9B87 0x6CE7 #CJK UNIFIED IDEOGRAPH
+0x9B88 0x6CE9 #CJK UNIFIED IDEOGRAPH
+0x9B89 0x6CEC #CJK UNIFIED IDEOGRAPH
+0x9B8A 0x6CED #CJK UNIFIED IDEOGRAPH
+0x9B8B 0x6CF2 #CJK UNIFIED IDEOGRAPH
+0x9B8C 0x6CF4 #CJK UNIFIED IDEOGRAPH
+0x9B8D 0x6CF9 #CJK UNIFIED IDEOGRAPH
+0x9B8E 0x6CFF #CJK UNIFIED IDEOGRAPH
+0x9B8F 0x6D00 #CJK UNIFIED IDEOGRAPH
+0x9B90 0x6D02 #CJK UNIFIED IDEOGRAPH
+0x9B91 0x6D03 #CJK UNIFIED IDEOGRAPH
+0x9B92 0x6D05 #CJK UNIFIED IDEOGRAPH
+0x9B93 0x6D06 #CJK UNIFIED IDEOGRAPH
+0x9B94 0x6D08 #CJK UNIFIED IDEOGRAPH
+0x9B95 0x6D09 #CJK UNIFIED IDEOGRAPH
+0x9B96 0x6D0A #CJK UNIFIED IDEOGRAPH
+0x9B97 0x6D0D #CJK UNIFIED IDEOGRAPH
+0x9B98 0x6D0F #CJK UNIFIED IDEOGRAPH
+0x9B99 0x6D10 #CJK UNIFIED IDEOGRAPH
+0x9B9A 0x6D11 #CJK UNIFIED IDEOGRAPH
+0x9B9B 0x6D13 #CJK UNIFIED IDEOGRAPH
+0x9B9C 0x6D14 #CJK UNIFIED IDEOGRAPH
+0x9B9D 0x6D15 #CJK UNIFIED IDEOGRAPH
+0x9B9E 0x6D16 #CJK UNIFIED IDEOGRAPH
+0x9B9F 0x6D18 #CJK UNIFIED IDEOGRAPH
+0x9BA0 0x6D1C #CJK UNIFIED IDEOGRAPH
+0x9BA1 0x6D1D #CJK UNIFIED IDEOGRAPH
+0x9BA2 0x6D1F #CJK UNIFIED IDEOGRAPH
+0x9BA3 0x6D20 #CJK UNIFIED IDEOGRAPH
+0x9BA4 0x6D21 #CJK UNIFIED IDEOGRAPH
+0x9BA5 0x6D22 #CJK UNIFIED IDEOGRAPH
+0x9BA6 0x6D23 #CJK UNIFIED IDEOGRAPH
+0x9BA7 0x6D24 #CJK UNIFIED IDEOGRAPH
+0x9BA8 0x6D26 #CJK UNIFIED IDEOGRAPH
+0x9BA9 0x6D28 #CJK UNIFIED IDEOGRAPH
+0x9BAA 0x6D29 #CJK UNIFIED IDEOGRAPH
+0x9BAB 0x6D2C #CJK UNIFIED IDEOGRAPH
+0x9BAC 0x6D2D #CJK UNIFIED IDEOGRAPH
+0x9BAD 0x6D2F #CJK UNIFIED IDEOGRAPH
+0x9BAE 0x6D30 #CJK UNIFIED IDEOGRAPH
+0x9BAF 0x6D34 #CJK UNIFIED IDEOGRAPH
+0x9BB0 0x6D36 #CJK UNIFIED IDEOGRAPH
+0x9BB1 0x6D37 #CJK UNIFIED IDEOGRAPH
+0x9BB2 0x6D38 #CJK UNIFIED IDEOGRAPH
+0x9BB3 0x6D3A #CJK UNIFIED IDEOGRAPH
+0x9BB4 0x6D3F #CJK UNIFIED IDEOGRAPH
+0x9BB5 0x6D40 #CJK UNIFIED IDEOGRAPH
+0x9BB6 0x6D42 #CJK UNIFIED IDEOGRAPH
+0x9BB7 0x6D44 #CJK UNIFIED IDEOGRAPH
+0x9BB8 0x6D49 #CJK UNIFIED IDEOGRAPH
+0x9BB9 0x6D4C #CJK UNIFIED IDEOGRAPH
+0x9BBA 0x6D50 #CJK UNIFIED IDEOGRAPH
+0x9BBB 0x6D55 #CJK UNIFIED IDEOGRAPH
+0x9BBC 0x6D56 #CJK UNIFIED IDEOGRAPH
+0x9BBD 0x6D57 #CJK UNIFIED IDEOGRAPH
+0x9BBE 0x6D58 #CJK UNIFIED IDEOGRAPH
+0x9BBF 0x6D5B #CJK UNIFIED IDEOGRAPH
+0x9BC0 0x6D5D #CJK UNIFIED IDEOGRAPH
+0x9BC1 0x6D5F #CJK UNIFIED IDEOGRAPH
+0x9BC2 0x6D61 #CJK UNIFIED IDEOGRAPH
+0x9BC3 0x6D62 #CJK UNIFIED IDEOGRAPH
+0x9BC4 0x6D64 #CJK UNIFIED IDEOGRAPH
+0x9BC5 0x6D65 #CJK UNIFIED IDEOGRAPH
+0x9BC6 0x6D67 #CJK UNIFIED IDEOGRAPH
+0x9BC7 0x6D68 #CJK UNIFIED IDEOGRAPH
+0x9BC8 0x6D6B #CJK UNIFIED IDEOGRAPH
+0x9BC9 0x6D6C #CJK UNIFIED IDEOGRAPH
+0x9BCA 0x6D6D #CJK UNIFIED IDEOGRAPH
+0x9BCB 0x6D70 #CJK UNIFIED IDEOGRAPH
+0x9BCC 0x6D71 #CJK UNIFIED IDEOGRAPH
+0x9BCD 0x6D72 #CJK UNIFIED IDEOGRAPH
+0x9BCE 0x6D73 #CJK UNIFIED IDEOGRAPH
+0x9BCF 0x6D75 #CJK UNIFIED IDEOGRAPH
+0x9BD0 0x6D76 #CJK UNIFIED IDEOGRAPH
+0x9BD1 0x6D79 #CJK UNIFIED IDEOGRAPH
+0x9BD2 0x6D7A #CJK UNIFIED IDEOGRAPH
+0x9BD3 0x6D7B #CJK UNIFIED IDEOGRAPH
+0x9BD4 0x6D7D #CJK UNIFIED IDEOGRAPH
+0x9BD5 0x6D7E #CJK UNIFIED IDEOGRAPH
+0x9BD6 0x6D7F #CJK UNIFIED IDEOGRAPH
+0x9BD7 0x6D80 #CJK UNIFIED IDEOGRAPH
+0x9BD8 0x6D81 #CJK UNIFIED IDEOGRAPH
+0x9BD9 0x6D83 #CJK UNIFIED IDEOGRAPH
+0x9BDA 0x6D84 #CJK UNIFIED IDEOGRAPH
+0x9BDB 0x6D86 #CJK UNIFIED IDEOGRAPH
+0x9BDC 0x6D87 #CJK UNIFIED IDEOGRAPH
+0x9BDD 0x6D8A #CJK UNIFIED IDEOGRAPH
+0x9BDE 0x6D8B #CJK UNIFIED IDEOGRAPH
+0x9BDF 0x6D8D #CJK UNIFIED IDEOGRAPH
+0x9BE0 0x6D8F #CJK UNIFIED IDEOGRAPH
+0x9BE1 0x6D90 #CJK UNIFIED IDEOGRAPH
+0x9BE2 0x6D92 #CJK UNIFIED IDEOGRAPH
+0x9BE3 0x6D96 #CJK UNIFIED IDEOGRAPH
+0x9BE4 0x6D97 #CJK UNIFIED IDEOGRAPH
+0x9BE5 0x6D98 #CJK UNIFIED IDEOGRAPH
+0x9BE6 0x6D99 #CJK UNIFIED IDEOGRAPH
+0x9BE7 0x6D9A #CJK UNIFIED IDEOGRAPH
+0x9BE8 0x6D9C #CJK UNIFIED IDEOGRAPH
+0x9BE9 0x6DA2 #CJK UNIFIED IDEOGRAPH
+0x9BEA 0x6DA5 #CJK UNIFIED IDEOGRAPH
+0x9BEB 0x6DAC #CJK UNIFIED IDEOGRAPH
+0x9BEC 0x6DAD #CJK UNIFIED IDEOGRAPH
+0x9BED 0x6DB0 #CJK UNIFIED IDEOGRAPH
+0x9BEE 0x6DB1 #CJK UNIFIED IDEOGRAPH
+0x9BEF 0x6DB3 #CJK UNIFIED IDEOGRAPH
+0x9BF0 0x6DB4 #CJK UNIFIED IDEOGRAPH
+0x9BF1 0x6DB6 #CJK UNIFIED IDEOGRAPH
+0x9BF2 0x6DB7 #CJK UNIFIED IDEOGRAPH
+0x9BF3 0x6DB9 #CJK UNIFIED IDEOGRAPH
+0x9BF4 0x6DBA #CJK UNIFIED IDEOGRAPH
+0x9BF5 0x6DBB #CJK UNIFIED IDEOGRAPH
+0x9BF6 0x6DBC #CJK UNIFIED IDEOGRAPH
+0x9BF7 0x6DBD #CJK UNIFIED IDEOGRAPH
+0x9BF8 0x6DBE #CJK UNIFIED IDEOGRAPH
+0x9BF9 0x6DC1 #CJK UNIFIED IDEOGRAPH
+0x9BFA 0x6DC2 #CJK UNIFIED IDEOGRAPH
+0x9BFB 0x6DC3 #CJK UNIFIED IDEOGRAPH
+0x9BFC 0x6DC8 #CJK UNIFIED IDEOGRAPH
+0x9BFD 0x6DC9 #CJK UNIFIED IDEOGRAPH
+0x9BFE 0x6DCA #CJK UNIFIED IDEOGRAPH
+0x9C40 0x6DCD #CJK UNIFIED IDEOGRAPH
+0x9C41 0x6DCE #CJK UNIFIED IDEOGRAPH
+0x9C42 0x6DCF #CJK UNIFIED IDEOGRAPH
+0x9C43 0x6DD0 #CJK UNIFIED IDEOGRAPH
+0x9C44 0x6DD2 #CJK UNIFIED IDEOGRAPH
+0x9C45 0x6DD3 #CJK UNIFIED IDEOGRAPH
+0x9C46 0x6DD4 #CJK UNIFIED IDEOGRAPH
+0x9C47 0x6DD5 #CJK UNIFIED IDEOGRAPH
+0x9C48 0x6DD7 #CJK UNIFIED IDEOGRAPH
+0x9C49 0x6DDA #CJK UNIFIED IDEOGRAPH
+0x9C4A 0x6DDB #CJK UNIFIED IDEOGRAPH
+0x9C4B 0x6DDC #CJK UNIFIED IDEOGRAPH
+0x9C4C 0x6DDF #CJK UNIFIED IDEOGRAPH
+0x9C4D 0x6DE2 #CJK UNIFIED IDEOGRAPH
+0x9C4E 0x6DE3 #CJK UNIFIED IDEOGRAPH
+0x9C4F 0x6DE5 #CJK UNIFIED IDEOGRAPH
+0x9C50 0x6DE7 #CJK UNIFIED IDEOGRAPH
+0x9C51 0x6DE8 #CJK UNIFIED IDEOGRAPH
+0x9C52 0x6DE9 #CJK UNIFIED IDEOGRAPH
+0x9C53 0x6DEA #CJK UNIFIED IDEOGRAPH
+0x9C54 0x6DED #CJK UNIFIED IDEOGRAPH
+0x9C55 0x6DEF #CJK UNIFIED IDEOGRAPH
+0x9C56 0x6DF0 #CJK UNIFIED IDEOGRAPH
+0x9C57 0x6DF2 #CJK UNIFIED IDEOGRAPH
+0x9C58 0x6DF4 #CJK UNIFIED IDEOGRAPH
+0x9C59 0x6DF5 #CJK UNIFIED IDEOGRAPH
+0x9C5A 0x6DF6 #CJK UNIFIED IDEOGRAPH
+0x9C5B 0x6DF8 #CJK UNIFIED IDEOGRAPH
+0x9C5C 0x6DFA #CJK UNIFIED IDEOGRAPH
+0x9C5D 0x6DFD #CJK UNIFIED IDEOGRAPH
+0x9C5E 0x6DFE #CJK UNIFIED IDEOGRAPH
+0x9C5F 0x6DFF #CJK UNIFIED IDEOGRAPH
+0x9C60 0x6E00 #CJK UNIFIED IDEOGRAPH
+0x9C61 0x6E01 #CJK UNIFIED IDEOGRAPH
+0x9C62 0x6E02 #CJK UNIFIED IDEOGRAPH
+0x9C63 0x6E03 #CJK UNIFIED IDEOGRAPH
+0x9C64 0x6E04 #CJK UNIFIED IDEOGRAPH
+0x9C65 0x6E06 #CJK UNIFIED IDEOGRAPH
+0x9C66 0x6E07 #CJK UNIFIED IDEOGRAPH
+0x9C67 0x6E08 #CJK UNIFIED IDEOGRAPH
+0x9C68 0x6E09 #CJK UNIFIED IDEOGRAPH
+0x9C69 0x6E0B #CJK UNIFIED IDEOGRAPH
+0x9C6A 0x6E0F #CJK UNIFIED IDEOGRAPH
+0x9C6B 0x6E12 #CJK UNIFIED IDEOGRAPH
+0x9C6C 0x6E13 #CJK UNIFIED IDEOGRAPH
+0x9C6D 0x6E15 #CJK UNIFIED IDEOGRAPH
+0x9C6E 0x6E18 #CJK UNIFIED IDEOGRAPH
+0x9C6F 0x6E19 #CJK UNIFIED IDEOGRAPH
+0x9C70 0x6E1B #CJK UNIFIED IDEOGRAPH
+0x9C71 0x6E1C #CJK UNIFIED IDEOGRAPH
+0x9C72 0x6E1E #CJK UNIFIED IDEOGRAPH
+0x9C73 0x6E1F #CJK UNIFIED IDEOGRAPH
+0x9C74 0x6E22 #CJK UNIFIED IDEOGRAPH
+0x9C75 0x6E26 #CJK UNIFIED IDEOGRAPH
+0x9C76 0x6E27 #CJK UNIFIED IDEOGRAPH
+0x9C77 0x6E28 #CJK UNIFIED IDEOGRAPH
+0x9C78 0x6E2A #CJK UNIFIED IDEOGRAPH
+0x9C79 0x6E2C #CJK UNIFIED IDEOGRAPH
+0x9C7A 0x6E2E #CJK UNIFIED IDEOGRAPH
+0x9C7B 0x6E30 #CJK UNIFIED IDEOGRAPH
+0x9C7C 0x6E31 #CJK UNIFIED IDEOGRAPH
+0x9C7D 0x6E33 #CJK UNIFIED IDEOGRAPH
+0x9C7E 0x6E35 #CJK UNIFIED IDEOGRAPH
+0x9C80 0x6E36 #CJK UNIFIED IDEOGRAPH
+0x9C81 0x6E37 #CJK UNIFIED IDEOGRAPH
+0x9C82 0x6E39 #CJK UNIFIED IDEOGRAPH
+0x9C83 0x6E3B #CJK UNIFIED IDEOGRAPH
+0x9C84 0x6E3C #CJK UNIFIED IDEOGRAPH
+0x9C85 0x6E3D #CJK UNIFIED IDEOGRAPH
+0x9C86 0x6E3E #CJK UNIFIED IDEOGRAPH
+0x9C87 0x6E3F #CJK UNIFIED IDEOGRAPH
+0x9C88 0x6E40 #CJK UNIFIED IDEOGRAPH
+0x9C89 0x6E41 #CJK UNIFIED IDEOGRAPH
+0x9C8A 0x6E42 #CJK UNIFIED IDEOGRAPH
+0x9C8B 0x6E45 #CJK UNIFIED IDEOGRAPH
+0x9C8C 0x6E46 #CJK UNIFIED IDEOGRAPH
+0x9C8D 0x6E47 #CJK UNIFIED IDEOGRAPH
+0x9C8E 0x6E48 #CJK UNIFIED IDEOGRAPH
+0x9C8F 0x6E49 #CJK UNIFIED IDEOGRAPH
+0x9C90 0x6E4A #CJK UNIFIED IDEOGRAPH
+0x9C91 0x6E4B #CJK UNIFIED IDEOGRAPH
+0x9C92 0x6E4C #CJK UNIFIED IDEOGRAPH
+0x9C93 0x6E4F #CJK UNIFIED IDEOGRAPH
+0x9C94 0x6E50 #CJK UNIFIED IDEOGRAPH
+0x9C95 0x6E51 #CJK UNIFIED IDEOGRAPH
+0x9C96 0x6E52 #CJK UNIFIED IDEOGRAPH
+0x9C97 0x6E55 #CJK UNIFIED IDEOGRAPH
+0x9C98 0x6E57 #CJK UNIFIED IDEOGRAPH
+0x9C99 0x6E59 #CJK UNIFIED IDEOGRAPH
+0x9C9A 0x6E5A #CJK UNIFIED IDEOGRAPH
+0x9C9B 0x6E5C #CJK UNIFIED IDEOGRAPH
+0x9C9C 0x6E5D #CJK UNIFIED IDEOGRAPH
+0x9C9D 0x6E5E #CJK UNIFIED IDEOGRAPH
+0x9C9E 0x6E60 #CJK UNIFIED IDEOGRAPH
+0x9C9F 0x6E61 #CJK UNIFIED IDEOGRAPH
+0x9CA0 0x6E62 #CJK UNIFIED IDEOGRAPH
+0x9CA1 0x6E63 #CJK UNIFIED IDEOGRAPH
+0x9CA2 0x6E64 #CJK UNIFIED IDEOGRAPH
+0x9CA3 0x6E65 #CJK UNIFIED IDEOGRAPH
+0x9CA4 0x6E66 #CJK UNIFIED IDEOGRAPH
+0x9CA5 0x6E67 #CJK UNIFIED IDEOGRAPH
+0x9CA6 0x6E68 #CJK UNIFIED IDEOGRAPH
+0x9CA7 0x6E69 #CJK UNIFIED IDEOGRAPH
+0x9CA8 0x6E6A #CJK UNIFIED IDEOGRAPH
+0x9CA9 0x6E6C #CJK UNIFIED IDEOGRAPH
+0x9CAA 0x6E6D #CJK UNIFIED IDEOGRAPH
+0x9CAB 0x6E6F #CJK UNIFIED IDEOGRAPH
+0x9CAC 0x6E70 #CJK UNIFIED IDEOGRAPH
+0x9CAD 0x6E71 #CJK UNIFIED IDEOGRAPH
+0x9CAE 0x6E72 #CJK UNIFIED IDEOGRAPH
+0x9CAF 0x6E73 #CJK UNIFIED IDEOGRAPH
+0x9CB0 0x6E74 #CJK UNIFIED IDEOGRAPH
+0x9CB1 0x6E75 #CJK UNIFIED IDEOGRAPH
+0x9CB2 0x6E76 #CJK UNIFIED IDEOGRAPH
+0x9CB3 0x6E77 #CJK UNIFIED IDEOGRAPH
+0x9CB4 0x6E78 #CJK UNIFIED IDEOGRAPH
+0x9CB5 0x6E79 #CJK UNIFIED IDEOGRAPH
+0x9CB6 0x6E7A #CJK UNIFIED IDEOGRAPH
+0x9CB7 0x6E7B #CJK UNIFIED IDEOGRAPH
+0x9CB8 0x6E7C #CJK UNIFIED IDEOGRAPH
+0x9CB9 0x6E7D #CJK UNIFIED IDEOGRAPH
+0x9CBA 0x6E80 #CJK UNIFIED IDEOGRAPH
+0x9CBB 0x6E81 #CJK UNIFIED IDEOGRAPH
+0x9CBC 0x6E82 #CJK UNIFIED IDEOGRAPH
+0x9CBD 0x6E84 #CJK UNIFIED IDEOGRAPH
+0x9CBE 0x6E87 #CJK UNIFIED IDEOGRAPH
+0x9CBF 0x6E88 #CJK UNIFIED IDEOGRAPH
+0x9CC0 0x6E8A #CJK UNIFIED IDEOGRAPH
+0x9CC1 0x6E8B #CJK UNIFIED IDEOGRAPH
+0x9CC2 0x6E8C #CJK UNIFIED IDEOGRAPH
+0x9CC3 0x6E8D #CJK UNIFIED IDEOGRAPH
+0x9CC4 0x6E8E #CJK UNIFIED IDEOGRAPH
+0x9CC5 0x6E91 #CJK UNIFIED IDEOGRAPH
+0x9CC6 0x6E92 #CJK UNIFIED IDEOGRAPH
+0x9CC7 0x6E93 #CJK UNIFIED IDEOGRAPH
+0x9CC8 0x6E94 #CJK UNIFIED IDEOGRAPH
+0x9CC9 0x6E95 #CJK UNIFIED IDEOGRAPH
+0x9CCA 0x6E96 #CJK UNIFIED IDEOGRAPH
+0x9CCB 0x6E97 #CJK UNIFIED IDEOGRAPH
+0x9CCC 0x6E99 #CJK UNIFIED IDEOGRAPH
+0x9CCD 0x6E9A #CJK UNIFIED IDEOGRAPH
+0x9CCE 0x6E9B #CJK UNIFIED IDEOGRAPH
+0x9CCF 0x6E9D #CJK UNIFIED IDEOGRAPH
+0x9CD0 0x6E9E #CJK UNIFIED IDEOGRAPH
+0x9CD1 0x6EA0 #CJK UNIFIED IDEOGRAPH
+0x9CD2 0x6EA1 #CJK UNIFIED IDEOGRAPH
+0x9CD3 0x6EA3 #CJK UNIFIED IDEOGRAPH
+0x9CD4 0x6EA4 #CJK UNIFIED IDEOGRAPH
+0x9CD5 0x6EA6 #CJK UNIFIED IDEOGRAPH
+0x9CD6 0x6EA8 #CJK UNIFIED IDEOGRAPH
+0x9CD7 0x6EA9 #CJK UNIFIED IDEOGRAPH
+0x9CD8 0x6EAB #CJK UNIFIED IDEOGRAPH
+0x9CD9 0x6EAC #CJK UNIFIED IDEOGRAPH
+0x9CDA 0x6EAD #CJK UNIFIED IDEOGRAPH
+0x9CDB 0x6EAE #CJK UNIFIED IDEOGRAPH
+0x9CDC 0x6EB0 #CJK UNIFIED IDEOGRAPH
+0x9CDD 0x6EB3 #CJK UNIFIED IDEOGRAPH
+0x9CDE 0x6EB5 #CJK UNIFIED IDEOGRAPH
+0x9CDF 0x6EB8 #CJK UNIFIED IDEOGRAPH
+0x9CE0 0x6EB9 #CJK UNIFIED IDEOGRAPH
+0x9CE1 0x6EBC #CJK UNIFIED IDEOGRAPH
+0x9CE2 0x6EBE #CJK UNIFIED IDEOGRAPH
+0x9CE3 0x6EBF #CJK UNIFIED IDEOGRAPH
+0x9CE4 0x6EC0 #CJK UNIFIED IDEOGRAPH
+0x9CE5 0x6EC3 #CJK UNIFIED IDEOGRAPH
+0x9CE6 0x6EC4 #CJK UNIFIED IDEOGRAPH
+0x9CE7 0x6EC5 #CJK UNIFIED IDEOGRAPH
+0x9CE8 0x6EC6 #CJK UNIFIED IDEOGRAPH
+0x9CE9 0x6EC8 #CJK UNIFIED IDEOGRAPH
+0x9CEA 0x6EC9 #CJK UNIFIED IDEOGRAPH
+0x9CEB 0x6ECA #CJK UNIFIED IDEOGRAPH
+0x9CEC 0x6ECC #CJK UNIFIED IDEOGRAPH
+0x9CED 0x6ECD #CJK UNIFIED IDEOGRAPH
+0x9CEE 0x6ECE #CJK UNIFIED IDEOGRAPH
+0x9CEF 0x6ED0 #CJK UNIFIED IDEOGRAPH
+0x9CF0 0x6ED2 #CJK UNIFIED IDEOGRAPH
+0x9CF1 0x6ED6 #CJK UNIFIED IDEOGRAPH
+0x9CF2 0x6ED8 #CJK UNIFIED IDEOGRAPH
+0x9CF3 0x6ED9 #CJK UNIFIED IDEOGRAPH
+0x9CF4 0x6EDB #CJK UNIFIED IDEOGRAPH
+0x9CF5 0x6EDC #CJK UNIFIED IDEOGRAPH
+0x9CF6 0x6EDD #CJK UNIFIED IDEOGRAPH
+0x9CF7 0x6EE3 #CJK UNIFIED IDEOGRAPH
+0x9CF8 0x6EE7 #CJK UNIFIED IDEOGRAPH
+0x9CF9 0x6EEA #CJK UNIFIED IDEOGRAPH
+0x9CFA 0x6EEB #CJK UNIFIED IDEOGRAPH
+0x9CFB 0x6EEC #CJK UNIFIED IDEOGRAPH
+0x9CFC 0x6EED #CJK UNIFIED IDEOGRAPH
+0x9CFD 0x6EEE #CJK UNIFIED IDEOGRAPH
+0x9CFE 0x6EEF #CJK UNIFIED IDEOGRAPH
+0x9D40 0x6EF0 #CJK UNIFIED IDEOGRAPH
+0x9D41 0x6EF1 #CJK UNIFIED IDEOGRAPH
+0x9D42 0x6EF2 #CJK UNIFIED IDEOGRAPH
+0x9D43 0x6EF3 #CJK UNIFIED IDEOGRAPH
+0x9D44 0x6EF5 #CJK UNIFIED IDEOGRAPH
+0x9D45 0x6EF6 #CJK UNIFIED IDEOGRAPH
+0x9D46 0x6EF7 #CJK UNIFIED IDEOGRAPH
+0x9D47 0x6EF8 #CJK UNIFIED IDEOGRAPH
+0x9D48 0x6EFA #CJK UNIFIED IDEOGRAPH
+0x9D49 0x6EFB #CJK UNIFIED IDEOGRAPH
+0x9D4A 0x6EFC #CJK UNIFIED IDEOGRAPH
+0x9D4B 0x6EFD #CJK UNIFIED IDEOGRAPH
+0x9D4C 0x6EFE #CJK UNIFIED IDEOGRAPH
+0x9D4D 0x6EFF #CJK UNIFIED IDEOGRAPH
+0x9D4E 0x6F00 #CJK UNIFIED IDEOGRAPH
+0x9D4F 0x6F01 #CJK UNIFIED IDEOGRAPH
+0x9D50 0x6F03 #CJK UNIFIED IDEOGRAPH
+0x9D51 0x6F04 #CJK UNIFIED IDEOGRAPH
+0x9D52 0x6F05 #CJK UNIFIED IDEOGRAPH
+0x9D53 0x6F07 #CJK UNIFIED IDEOGRAPH
+0x9D54 0x6F08 #CJK UNIFIED IDEOGRAPH
+0x9D55 0x6F0A #CJK UNIFIED IDEOGRAPH
+0x9D56 0x6F0B #CJK UNIFIED IDEOGRAPH
+0x9D57 0x6F0C #CJK UNIFIED IDEOGRAPH
+0x9D58 0x6F0D #CJK UNIFIED IDEOGRAPH
+0x9D59 0x6F0E #CJK UNIFIED IDEOGRAPH
+0x9D5A 0x6F10 #CJK UNIFIED IDEOGRAPH
+0x9D5B 0x6F11 #CJK UNIFIED IDEOGRAPH
+0x9D5C 0x6F12 #CJK UNIFIED IDEOGRAPH
+0x9D5D 0x6F16 #CJK UNIFIED IDEOGRAPH
+0x9D5E 0x6F17 #CJK UNIFIED IDEOGRAPH
+0x9D5F 0x6F18 #CJK UNIFIED IDEOGRAPH
+0x9D60 0x6F19 #CJK UNIFIED IDEOGRAPH
+0x9D61 0x6F1A #CJK UNIFIED IDEOGRAPH
+0x9D62 0x6F1B #CJK UNIFIED IDEOGRAPH
+0x9D63 0x6F1C #CJK UNIFIED IDEOGRAPH
+0x9D64 0x6F1D #CJK UNIFIED IDEOGRAPH
+0x9D65 0x6F1E #CJK UNIFIED IDEOGRAPH
+0x9D66 0x6F1F #CJK UNIFIED IDEOGRAPH
+0x9D67 0x6F21 #CJK UNIFIED IDEOGRAPH
+0x9D68 0x6F22 #CJK UNIFIED IDEOGRAPH
+0x9D69 0x6F23 #CJK UNIFIED IDEOGRAPH
+0x9D6A 0x6F25 #CJK UNIFIED IDEOGRAPH
+0x9D6B 0x6F26 #CJK UNIFIED IDEOGRAPH
+0x9D6C 0x6F27 #CJK UNIFIED IDEOGRAPH
+0x9D6D 0x6F28 #CJK UNIFIED IDEOGRAPH
+0x9D6E 0x6F2C #CJK UNIFIED IDEOGRAPH
+0x9D6F 0x6F2E #CJK UNIFIED IDEOGRAPH
+0x9D70 0x6F30 #CJK UNIFIED IDEOGRAPH
+0x9D71 0x6F32 #CJK UNIFIED IDEOGRAPH
+0x9D72 0x6F34 #CJK UNIFIED IDEOGRAPH
+0x9D73 0x6F35 #CJK UNIFIED IDEOGRAPH
+0x9D74 0x6F37 #CJK UNIFIED IDEOGRAPH
+0x9D75 0x6F38 #CJK UNIFIED IDEOGRAPH
+0x9D76 0x6F39 #CJK UNIFIED IDEOGRAPH
+0x9D77 0x6F3A #CJK UNIFIED IDEOGRAPH
+0x9D78 0x6F3B #CJK UNIFIED IDEOGRAPH
+0x9D79 0x6F3C #CJK UNIFIED IDEOGRAPH
+0x9D7A 0x6F3D #CJK UNIFIED IDEOGRAPH
+0x9D7B 0x6F3F #CJK UNIFIED IDEOGRAPH
+0x9D7C 0x6F40 #CJK UNIFIED IDEOGRAPH
+0x9D7D 0x6F41 #CJK UNIFIED IDEOGRAPH
+0x9D7E 0x6F42 #CJK UNIFIED IDEOGRAPH
+0x9D80 0x6F43 #CJK UNIFIED IDEOGRAPH
+0x9D81 0x6F44 #CJK UNIFIED IDEOGRAPH
+0x9D82 0x6F45 #CJK UNIFIED IDEOGRAPH
+0x9D83 0x6F48 #CJK UNIFIED IDEOGRAPH
+0x9D84 0x6F49 #CJK UNIFIED IDEOGRAPH
+0x9D85 0x6F4A #CJK UNIFIED IDEOGRAPH
+0x9D86 0x6F4C #CJK UNIFIED IDEOGRAPH
+0x9D87 0x6F4E #CJK UNIFIED IDEOGRAPH
+0x9D88 0x6F4F #CJK UNIFIED IDEOGRAPH
+0x9D89 0x6F50 #CJK UNIFIED IDEOGRAPH
+0x9D8A 0x6F51 #CJK UNIFIED IDEOGRAPH
+0x9D8B 0x6F52 #CJK UNIFIED IDEOGRAPH
+0x9D8C 0x6F53 #CJK UNIFIED IDEOGRAPH
+0x9D8D 0x6F54 #CJK UNIFIED IDEOGRAPH
+0x9D8E 0x6F55 #CJK UNIFIED IDEOGRAPH
+0x9D8F 0x6F56 #CJK UNIFIED IDEOGRAPH
+0x9D90 0x6F57 #CJK UNIFIED IDEOGRAPH
+0x9D91 0x6F59 #CJK UNIFIED IDEOGRAPH
+0x9D92 0x6F5A #CJK UNIFIED IDEOGRAPH
+0x9D93 0x6F5B #CJK UNIFIED IDEOGRAPH
+0x9D94 0x6F5D #CJK UNIFIED IDEOGRAPH
+0x9D95 0x6F5F #CJK UNIFIED IDEOGRAPH
+0x9D96 0x6F60 #CJK UNIFIED IDEOGRAPH
+0x9D97 0x6F61 #CJK UNIFIED IDEOGRAPH
+0x9D98 0x6F63 #CJK UNIFIED IDEOGRAPH
+0x9D99 0x6F64 #CJK UNIFIED IDEOGRAPH
+0x9D9A 0x6F65 #CJK UNIFIED IDEOGRAPH
+0x9D9B 0x6F67 #CJK UNIFIED IDEOGRAPH
+0x9D9C 0x6F68 #CJK UNIFIED IDEOGRAPH
+0x9D9D 0x6F69 #CJK UNIFIED IDEOGRAPH
+0x9D9E 0x6F6A #CJK UNIFIED IDEOGRAPH
+0x9D9F 0x6F6B #CJK UNIFIED IDEOGRAPH
+0x9DA0 0x6F6C #CJK UNIFIED IDEOGRAPH
+0x9DA1 0x6F6F #CJK UNIFIED IDEOGRAPH
+0x9DA2 0x6F70 #CJK UNIFIED IDEOGRAPH
+0x9DA3 0x6F71 #CJK UNIFIED IDEOGRAPH
+0x9DA4 0x6F73 #CJK UNIFIED IDEOGRAPH
+0x9DA5 0x6F75 #CJK UNIFIED IDEOGRAPH
+0x9DA6 0x6F76 #CJK UNIFIED IDEOGRAPH
+0x9DA7 0x6F77 #CJK UNIFIED IDEOGRAPH
+0x9DA8 0x6F79 #CJK UNIFIED IDEOGRAPH
+0x9DA9 0x6F7B #CJK UNIFIED IDEOGRAPH
+0x9DAA 0x6F7D #CJK UNIFIED IDEOGRAPH
+0x9DAB 0x6F7E #CJK UNIFIED IDEOGRAPH
+0x9DAC 0x6F7F #CJK UNIFIED IDEOGRAPH
+0x9DAD 0x6F80 #CJK UNIFIED IDEOGRAPH
+0x9DAE 0x6F81 #CJK UNIFIED IDEOGRAPH
+0x9DAF 0x6F82 #CJK UNIFIED IDEOGRAPH
+0x9DB0 0x6F83 #CJK UNIFIED IDEOGRAPH
+0x9DB1 0x6F85 #CJK UNIFIED IDEOGRAPH
+0x9DB2 0x6F86 #CJK UNIFIED IDEOGRAPH
+0x9DB3 0x6F87 #CJK UNIFIED IDEOGRAPH
+0x9DB4 0x6F8A #CJK UNIFIED IDEOGRAPH
+0x9DB5 0x6F8B #CJK UNIFIED IDEOGRAPH
+0x9DB6 0x6F8F #CJK UNIFIED IDEOGRAPH
+0x9DB7 0x6F90 #CJK UNIFIED IDEOGRAPH
+0x9DB8 0x6F91 #CJK UNIFIED IDEOGRAPH
+0x9DB9 0x6F92 #CJK UNIFIED IDEOGRAPH
+0x9DBA 0x6F93 #CJK UNIFIED IDEOGRAPH
+0x9DBB 0x6F94 #CJK UNIFIED IDEOGRAPH
+0x9DBC 0x6F95 #CJK UNIFIED IDEOGRAPH
+0x9DBD 0x6F96 #CJK UNIFIED IDEOGRAPH
+0x9DBE 0x6F97 #CJK UNIFIED IDEOGRAPH
+0x9DBF 0x6F98 #CJK UNIFIED IDEOGRAPH
+0x9DC0 0x6F99 #CJK UNIFIED IDEOGRAPH
+0x9DC1 0x6F9A #CJK UNIFIED IDEOGRAPH
+0x9DC2 0x6F9B #CJK UNIFIED IDEOGRAPH
+0x9DC3 0x6F9D #CJK UNIFIED IDEOGRAPH
+0x9DC4 0x6F9E #CJK UNIFIED IDEOGRAPH
+0x9DC5 0x6F9F #CJK UNIFIED IDEOGRAPH
+0x9DC6 0x6FA0 #CJK UNIFIED IDEOGRAPH
+0x9DC7 0x6FA2 #CJK UNIFIED IDEOGRAPH
+0x9DC8 0x6FA3 #CJK UNIFIED IDEOGRAPH
+0x9DC9 0x6FA4 #CJK UNIFIED IDEOGRAPH
+0x9DCA 0x6FA5 #CJK UNIFIED IDEOGRAPH
+0x9DCB 0x6FA6 #CJK UNIFIED IDEOGRAPH
+0x9DCC 0x6FA8 #CJK UNIFIED IDEOGRAPH
+0x9DCD 0x6FA9 #CJK UNIFIED IDEOGRAPH
+0x9DCE 0x6FAA #CJK UNIFIED IDEOGRAPH
+0x9DCF 0x6FAB #CJK UNIFIED IDEOGRAPH
+0x9DD0 0x6FAC #CJK UNIFIED IDEOGRAPH
+0x9DD1 0x6FAD #CJK UNIFIED IDEOGRAPH
+0x9DD2 0x6FAE #CJK UNIFIED IDEOGRAPH
+0x9DD3 0x6FAF #CJK UNIFIED IDEOGRAPH
+0x9DD4 0x6FB0 #CJK UNIFIED IDEOGRAPH
+0x9DD5 0x6FB1 #CJK UNIFIED IDEOGRAPH
+0x9DD6 0x6FB2 #CJK UNIFIED IDEOGRAPH
+0x9DD7 0x6FB4 #CJK UNIFIED IDEOGRAPH
+0x9DD8 0x6FB5 #CJK UNIFIED IDEOGRAPH
+0x9DD9 0x6FB7 #CJK UNIFIED IDEOGRAPH
+0x9DDA 0x6FB8 #CJK UNIFIED IDEOGRAPH
+0x9DDB 0x6FBA #CJK UNIFIED IDEOGRAPH
+0x9DDC 0x6FBB #CJK UNIFIED IDEOGRAPH
+0x9DDD 0x6FBC #CJK UNIFIED IDEOGRAPH
+0x9DDE 0x6FBD #CJK UNIFIED IDEOGRAPH
+0x9DDF 0x6FBE #CJK UNIFIED IDEOGRAPH
+0x9DE0 0x6FBF #CJK UNIFIED IDEOGRAPH
+0x9DE1 0x6FC1 #CJK UNIFIED IDEOGRAPH
+0x9DE2 0x6FC3 #CJK UNIFIED IDEOGRAPH
+0x9DE3 0x6FC4 #CJK UNIFIED IDEOGRAPH
+0x9DE4 0x6FC5 #CJK UNIFIED IDEOGRAPH
+0x9DE5 0x6FC6 #CJK UNIFIED IDEOGRAPH
+0x9DE6 0x6FC7 #CJK UNIFIED IDEOGRAPH
+0x9DE7 0x6FC8 #CJK UNIFIED IDEOGRAPH
+0x9DE8 0x6FCA #CJK UNIFIED IDEOGRAPH
+0x9DE9 0x6FCB #CJK UNIFIED IDEOGRAPH
+0x9DEA 0x6FCC #CJK UNIFIED IDEOGRAPH
+0x9DEB 0x6FCD #CJK UNIFIED IDEOGRAPH
+0x9DEC 0x6FCE #CJK UNIFIED IDEOGRAPH
+0x9DED 0x6FCF #CJK UNIFIED IDEOGRAPH
+0x9DEE 0x6FD0 #CJK UNIFIED IDEOGRAPH
+0x9DEF 0x6FD3 #CJK UNIFIED IDEOGRAPH
+0x9DF0 0x6FD4 #CJK UNIFIED IDEOGRAPH
+0x9DF1 0x6FD5 #CJK UNIFIED IDEOGRAPH
+0x9DF2 0x6FD6 #CJK UNIFIED IDEOGRAPH
+0x9DF3 0x6FD7 #CJK UNIFIED IDEOGRAPH
+0x9DF4 0x6FD8 #CJK UNIFIED IDEOGRAPH
+0x9DF5 0x6FD9 #CJK UNIFIED IDEOGRAPH
+0x9DF6 0x6FDA #CJK UNIFIED IDEOGRAPH
+0x9DF7 0x6FDB #CJK UNIFIED IDEOGRAPH
+0x9DF8 0x6FDC #CJK UNIFIED IDEOGRAPH
+0x9DF9 0x6FDD #CJK UNIFIED IDEOGRAPH
+0x9DFA 0x6FDF #CJK UNIFIED IDEOGRAPH
+0x9DFB 0x6FE2 #CJK UNIFIED IDEOGRAPH
+0x9DFC 0x6FE3 #CJK UNIFIED IDEOGRAPH
+0x9DFD 0x6FE4 #CJK UNIFIED IDEOGRAPH
+0x9DFE 0x6FE5 #CJK UNIFIED IDEOGRAPH
+0x9E40 0x6FE6 #CJK UNIFIED IDEOGRAPH
+0x9E41 0x6FE7 #CJK UNIFIED IDEOGRAPH
+0x9E42 0x6FE8 #CJK UNIFIED IDEOGRAPH
+0x9E43 0x6FE9 #CJK UNIFIED IDEOGRAPH
+0x9E44 0x6FEA #CJK UNIFIED IDEOGRAPH
+0x9E45 0x6FEB #CJK UNIFIED IDEOGRAPH
+0x9E46 0x6FEC #CJK UNIFIED IDEOGRAPH
+0x9E47 0x6FED #CJK UNIFIED IDEOGRAPH
+0x9E48 0x6FF0 #CJK UNIFIED IDEOGRAPH
+0x9E49 0x6FF1 #CJK UNIFIED IDEOGRAPH
+0x9E4A 0x6FF2 #CJK UNIFIED IDEOGRAPH
+0x9E4B 0x6FF3 #CJK UNIFIED IDEOGRAPH
+0x9E4C 0x6FF4 #CJK UNIFIED IDEOGRAPH
+0x9E4D 0x6FF5 #CJK UNIFIED IDEOGRAPH
+0x9E4E 0x6FF6 #CJK UNIFIED IDEOGRAPH
+0x9E4F 0x6FF7 #CJK UNIFIED IDEOGRAPH
+0x9E50 0x6FF8 #CJK UNIFIED IDEOGRAPH
+0x9E51 0x6FF9 #CJK UNIFIED IDEOGRAPH
+0x9E52 0x6FFA #CJK UNIFIED IDEOGRAPH
+0x9E53 0x6FFB #CJK UNIFIED IDEOGRAPH
+0x9E54 0x6FFC #CJK UNIFIED IDEOGRAPH
+0x9E55 0x6FFD #CJK UNIFIED IDEOGRAPH
+0x9E56 0x6FFE #CJK UNIFIED IDEOGRAPH
+0x9E57 0x6FFF #CJK UNIFIED IDEOGRAPH
+0x9E58 0x7000 #CJK UNIFIED IDEOGRAPH
+0x9E59 0x7001 #CJK UNIFIED IDEOGRAPH
+0x9E5A 0x7002 #CJK UNIFIED IDEOGRAPH
+0x9E5B 0x7003 #CJK UNIFIED IDEOGRAPH
+0x9E5C 0x7004 #CJK UNIFIED IDEOGRAPH
+0x9E5D 0x7005 #CJK UNIFIED IDEOGRAPH
+0x9E5E 0x7006 #CJK UNIFIED IDEOGRAPH
+0x9E5F 0x7007 #CJK UNIFIED IDEOGRAPH
+0x9E60 0x7008 #CJK UNIFIED IDEOGRAPH
+0x9E61 0x7009 #CJK UNIFIED IDEOGRAPH
+0x9E62 0x700A #CJK UNIFIED IDEOGRAPH
+0x9E63 0x700B #CJK UNIFIED IDEOGRAPH
+0x9E64 0x700C #CJK UNIFIED IDEOGRAPH
+0x9E65 0x700D #CJK UNIFIED IDEOGRAPH
+0x9E66 0x700E #CJK UNIFIED IDEOGRAPH
+0x9E67 0x700F #CJK UNIFIED IDEOGRAPH
+0x9E68 0x7010 #CJK UNIFIED IDEOGRAPH
+0x9E69 0x7012 #CJK UNIFIED IDEOGRAPH
+0x9E6A 0x7013 #CJK UNIFIED IDEOGRAPH
+0x9E6B 0x7014 #CJK UNIFIED IDEOGRAPH
+0x9E6C 0x7015 #CJK UNIFIED IDEOGRAPH
+0x9E6D 0x7016 #CJK UNIFIED IDEOGRAPH
+0x9E6E 0x7017 #CJK UNIFIED IDEOGRAPH
+0x9E6F 0x7018 #CJK UNIFIED IDEOGRAPH
+0x9E70 0x7019 #CJK UNIFIED IDEOGRAPH
+0x9E71 0x701C #CJK UNIFIED IDEOGRAPH
+0x9E72 0x701D #CJK UNIFIED IDEOGRAPH
+0x9E73 0x701E #CJK UNIFIED IDEOGRAPH
+0x9E74 0x701F #CJK UNIFIED IDEOGRAPH
+0x9E75 0x7020 #CJK UNIFIED IDEOGRAPH
+0x9E76 0x7021 #CJK UNIFIED IDEOGRAPH
+0x9E77 0x7022 #CJK UNIFIED IDEOGRAPH
+0x9E78 0x7024 #CJK UNIFIED IDEOGRAPH
+0x9E79 0x7025 #CJK UNIFIED IDEOGRAPH
+0x9E7A 0x7026 #CJK UNIFIED IDEOGRAPH
+0x9E7B 0x7027 #CJK UNIFIED IDEOGRAPH
+0x9E7C 0x7028 #CJK UNIFIED IDEOGRAPH
+0x9E7D 0x7029 #CJK UNIFIED IDEOGRAPH
+0x9E7E 0x702A #CJK UNIFIED IDEOGRAPH
+0x9E80 0x702B #CJK UNIFIED IDEOGRAPH
+0x9E81 0x702C #CJK UNIFIED IDEOGRAPH
+0x9E82 0x702D #CJK UNIFIED IDEOGRAPH
+0x9E83 0x702E #CJK UNIFIED IDEOGRAPH
+0x9E84 0x702F #CJK UNIFIED IDEOGRAPH
+0x9E85 0x7030 #CJK UNIFIED IDEOGRAPH
+0x9E86 0x7031 #CJK UNIFIED IDEOGRAPH
+0x9E87 0x7032 #CJK UNIFIED IDEOGRAPH
+0x9E88 0x7033 #CJK UNIFIED IDEOGRAPH
+0x9E89 0x7034 #CJK UNIFIED IDEOGRAPH
+0x9E8A 0x7036 #CJK UNIFIED IDEOGRAPH
+0x9E8B 0x7037 #CJK UNIFIED IDEOGRAPH
+0x9E8C 0x7038 #CJK UNIFIED IDEOGRAPH
+0x9E8D 0x703A #CJK UNIFIED IDEOGRAPH
+0x9E8E 0x703B #CJK UNIFIED IDEOGRAPH
+0x9E8F 0x703C #CJK UNIFIED IDEOGRAPH
+0x9E90 0x703D #CJK UNIFIED IDEOGRAPH
+0x9E91 0x703E #CJK UNIFIED IDEOGRAPH
+0x9E92 0x703F #CJK UNIFIED IDEOGRAPH
+0x9E93 0x7040 #CJK UNIFIED IDEOGRAPH
+0x9E94 0x7041 #CJK UNIFIED IDEOGRAPH
+0x9E95 0x7042 #CJK UNIFIED IDEOGRAPH
+0x9E96 0x7043 #CJK UNIFIED IDEOGRAPH
+0x9E97 0x7044 #CJK UNIFIED IDEOGRAPH
+0x9E98 0x7045 #CJK UNIFIED IDEOGRAPH
+0x9E99 0x7046 #CJK UNIFIED IDEOGRAPH
+0x9E9A 0x7047 #CJK UNIFIED IDEOGRAPH
+0x9E9B 0x7048 #CJK UNIFIED IDEOGRAPH
+0x9E9C 0x7049 #CJK UNIFIED IDEOGRAPH
+0x9E9D 0x704A #CJK UNIFIED IDEOGRAPH
+0x9E9E 0x704B #CJK UNIFIED IDEOGRAPH
+0x9E9F 0x704D #CJK UNIFIED IDEOGRAPH
+0x9EA0 0x704E #CJK UNIFIED IDEOGRAPH
+0x9EA1 0x7050 #CJK UNIFIED IDEOGRAPH
+0x9EA2 0x7051 #CJK UNIFIED IDEOGRAPH
+0x9EA3 0x7052 #CJK UNIFIED IDEOGRAPH
+0x9EA4 0x7053 #CJK UNIFIED IDEOGRAPH
+0x9EA5 0x7054 #CJK UNIFIED IDEOGRAPH
+0x9EA6 0x7055 #CJK UNIFIED IDEOGRAPH
+0x9EA7 0x7056 #CJK UNIFIED IDEOGRAPH
+0x9EA8 0x7057 #CJK UNIFIED IDEOGRAPH
+0x9EA9 0x7058 #CJK UNIFIED IDEOGRAPH
+0x9EAA 0x7059 #CJK UNIFIED IDEOGRAPH
+0x9EAB 0x705A #CJK UNIFIED IDEOGRAPH
+0x9EAC 0x705B #CJK UNIFIED IDEOGRAPH
+0x9EAD 0x705C #CJK UNIFIED IDEOGRAPH
+0x9EAE 0x705D #CJK UNIFIED IDEOGRAPH
+0x9EAF 0x705F #CJK UNIFIED IDEOGRAPH
+0x9EB0 0x7060 #CJK UNIFIED IDEOGRAPH
+0x9EB1 0x7061 #CJK UNIFIED IDEOGRAPH
+0x9EB2 0x7062 #CJK UNIFIED IDEOGRAPH
+0x9EB3 0x7063 #CJK UNIFIED IDEOGRAPH
+0x9EB4 0x7064 #CJK UNIFIED IDEOGRAPH
+0x9EB5 0x7065 #CJK UNIFIED IDEOGRAPH
+0x9EB6 0x7066 #CJK UNIFIED IDEOGRAPH
+0x9EB7 0x7067 #CJK UNIFIED IDEOGRAPH
+0x9EB8 0x7068 #CJK UNIFIED IDEOGRAPH
+0x9EB9 0x7069 #CJK UNIFIED IDEOGRAPH
+0x9EBA 0x706A #CJK UNIFIED IDEOGRAPH
+0x9EBB 0x706E #CJK UNIFIED IDEOGRAPH
+0x9EBC 0x7071 #CJK UNIFIED IDEOGRAPH
+0x9EBD 0x7072 #CJK UNIFIED IDEOGRAPH
+0x9EBE 0x7073 #CJK UNIFIED IDEOGRAPH
+0x9EBF 0x7074 #CJK UNIFIED IDEOGRAPH
+0x9EC0 0x7077 #CJK UNIFIED IDEOGRAPH
+0x9EC1 0x7079 #CJK UNIFIED IDEOGRAPH
+0x9EC2 0x707A #CJK UNIFIED IDEOGRAPH
+0x9EC3 0x707B #CJK UNIFIED IDEOGRAPH
+0x9EC4 0x707D #CJK UNIFIED IDEOGRAPH
+0x9EC5 0x7081 #CJK UNIFIED IDEOGRAPH
+0x9EC6 0x7082 #CJK UNIFIED IDEOGRAPH
+0x9EC7 0x7083 #CJK UNIFIED IDEOGRAPH
+0x9EC8 0x7084 #CJK UNIFIED IDEOGRAPH
+0x9EC9 0x7086 #CJK UNIFIED IDEOGRAPH
+0x9ECA 0x7087 #CJK UNIFIED IDEOGRAPH
+0x9ECB 0x7088 #CJK UNIFIED IDEOGRAPH
+0x9ECC 0x708B #CJK UNIFIED IDEOGRAPH
+0x9ECD 0x708C #CJK UNIFIED IDEOGRAPH
+0x9ECE 0x708D #CJK UNIFIED IDEOGRAPH
+0x9ECF 0x708F #CJK UNIFIED IDEOGRAPH
+0x9ED0 0x7090 #CJK UNIFIED IDEOGRAPH
+0x9ED1 0x7091 #CJK UNIFIED IDEOGRAPH
+0x9ED2 0x7093 #CJK UNIFIED IDEOGRAPH
+0x9ED3 0x7097 #CJK UNIFIED IDEOGRAPH
+0x9ED4 0x7098 #CJK UNIFIED IDEOGRAPH
+0x9ED5 0x709A #CJK UNIFIED IDEOGRAPH
+0x9ED6 0x709B #CJK UNIFIED IDEOGRAPH
+0x9ED7 0x709E #CJK UNIFIED IDEOGRAPH
+0x9ED8 0x709F #CJK UNIFIED IDEOGRAPH
+0x9ED9 0x70A0 #CJK UNIFIED IDEOGRAPH
+0x9EDA 0x70A1 #CJK UNIFIED IDEOGRAPH
+0x9EDB 0x70A2 #CJK UNIFIED IDEOGRAPH
+0x9EDC 0x70A3 #CJK UNIFIED IDEOGRAPH
+0x9EDD 0x70A4 #CJK UNIFIED IDEOGRAPH
+0x9EDE 0x70A5 #CJK UNIFIED IDEOGRAPH
+0x9EDF 0x70A6 #CJK UNIFIED IDEOGRAPH
+0x9EE0 0x70A7 #CJK UNIFIED IDEOGRAPH
+0x9EE1 0x70A8 #CJK UNIFIED IDEOGRAPH
+0x9EE2 0x70A9 #CJK UNIFIED IDEOGRAPH
+0x9EE3 0x70AA #CJK UNIFIED IDEOGRAPH
+0x9EE4 0x70B0 #CJK UNIFIED IDEOGRAPH
+0x9EE5 0x70B2 #CJK UNIFIED IDEOGRAPH
+0x9EE6 0x70B4 #CJK UNIFIED IDEOGRAPH
+0x9EE7 0x70B5 #CJK UNIFIED IDEOGRAPH
+0x9EE8 0x70B6 #CJK UNIFIED IDEOGRAPH
+0x9EE9 0x70BA #CJK UNIFIED IDEOGRAPH
+0x9EEA 0x70BE #CJK UNIFIED IDEOGRAPH
+0x9EEB 0x70BF #CJK UNIFIED IDEOGRAPH
+0x9EEC 0x70C4 #CJK UNIFIED IDEOGRAPH
+0x9EED 0x70C5 #CJK UNIFIED IDEOGRAPH
+0x9EEE 0x70C6 #CJK UNIFIED IDEOGRAPH
+0x9EEF 0x70C7 #CJK UNIFIED IDEOGRAPH
+0x9EF0 0x70C9 #CJK UNIFIED IDEOGRAPH
+0x9EF1 0x70CB #CJK UNIFIED IDEOGRAPH
+0x9EF2 0x70CC #CJK UNIFIED IDEOGRAPH
+0x9EF3 0x70CD #CJK UNIFIED IDEOGRAPH
+0x9EF4 0x70CE #CJK UNIFIED IDEOGRAPH
+0x9EF5 0x70CF #CJK UNIFIED IDEOGRAPH
+0x9EF6 0x70D0 #CJK UNIFIED IDEOGRAPH
+0x9EF7 0x70D1 #CJK UNIFIED IDEOGRAPH
+0x9EF8 0x70D2 #CJK UNIFIED IDEOGRAPH
+0x9EF9 0x70D3 #CJK UNIFIED IDEOGRAPH
+0x9EFA 0x70D4 #CJK UNIFIED IDEOGRAPH
+0x9EFB 0x70D5 #CJK UNIFIED IDEOGRAPH
+0x9EFC 0x70D6 #CJK UNIFIED IDEOGRAPH
+0x9EFD 0x70D7 #CJK UNIFIED IDEOGRAPH
+0x9EFE 0x70DA #CJK UNIFIED IDEOGRAPH
+0x9F40 0x70DC #CJK UNIFIED IDEOGRAPH
+0x9F41 0x70DD #CJK UNIFIED IDEOGRAPH
+0x9F42 0x70DE #CJK UNIFIED IDEOGRAPH
+0x9F43 0x70E0 #CJK UNIFIED IDEOGRAPH
+0x9F44 0x70E1 #CJK UNIFIED IDEOGRAPH
+0x9F45 0x70E2 #CJK UNIFIED IDEOGRAPH
+0x9F46 0x70E3 #CJK UNIFIED IDEOGRAPH
+0x9F47 0x70E5 #CJK UNIFIED IDEOGRAPH
+0x9F48 0x70EA #CJK UNIFIED IDEOGRAPH
+0x9F49 0x70EE #CJK UNIFIED IDEOGRAPH
+0x9F4A 0x70F0 #CJK UNIFIED IDEOGRAPH
+0x9F4B 0x70F1 #CJK UNIFIED IDEOGRAPH
+0x9F4C 0x70F2 #CJK UNIFIED IDEOGRAPH
+0x9F4D 0x70F3 #CJK UNIFIED IDEOGRAPH
+0x9F4E 0x70F4 #CJK UNIFIED IDEOGRAPH
+0x9F4F 0x70F5 #CJK UNIFIED IDEOGRAPH
+0x9F50 0x70F6 #CJK UNIFIED IDEOGRAPH
+0x9F51 0x70F8 #CJK UNIFIED IDEOGRAPH
+0x9F52 0x70FA #CJK UNIFIED IDEOGRAPH
+0x9F53 0x70FB #CJK UNIFIED IDEOGRAPH
+0x9F54 0x70FC #CJK UNIFIED IDEOGRAPH
+0x9F55 0x70FE #CJK UNIFIED IDEOGRAPH
+0x9F56 0x70FF #CJK UNIFIED IDEOGRAPH
+0x9F57 0x7100 #CJK UNIFIED IDEOGRAPH
+0x9F58 0x7101 #CJK UNIFIED IDEOGRAPH
+0x9F59 0x7102 #CJK UNIFIED IDEOGRAPH
+0x9F5A 0x7103 #CJK UNIFIED IDEOGRAPH
+0x9F5B 0x7104 #CJK UNIFIED IDEOGRAPH
+0x9F5C 0x7105 #CJK UNIFIED IDEOGRAPH
+0x9F5D 0x7106 #CJK UNIFIED IDEOGRAPH
+0x9F5E 0x7107 #CJK UNIFIED IDEOGRAPH
+0x9F5F 0x7108 #CJK UNIFIED IDEOGRAPH
+0x9F60 0x710B #CJK UNIFIED IDEOGRAPH
+0x9F61 0x710C #CJK UNIFIED IDEOGRAPH
+0x9F62 0x710D #CJK UNIFIED IDEOGRAPH
+0x9F63 0x710E #CJK UNIFIED IDEOGRAPH
+0x9F64 0x710F #CJK UNIFIED IDEOGRAPH
+0x9F65 0x7111 #CJK UNIFIED IDEOGRAPH
+0x9F66 0x7112 #CJK UNIFIED IDEOGRAPH
+0x9F67 0x7114 #CJK UNIFIED IDEOGRAPH
+0x9F68 0x7117 #CJK UNIFIED IDEOGRAPH
+0x9F69 0x711B #CJK UNIFIED IDEOGRAPH
+0x9F6A 0x711C #CJK UNIFIED IDEOGRAPH
+0x9F6B 0x711D #CJK UNIFIED IDEOGRAPH
+0x9F6C 0x711E #CJK UNIFIED IDEOGRAPH
+0x9F6D 0x711F #CJK UNIFIED IDEOGRAPH
+0x9F6E 0x7120 #CJK UNIFIED IDEOGRAPH
+0x9F6F 0x7121 #CJK UNIFIED IDEOGRAPH
+0x9F70 0x7122 #CJK UNIFIED IDEOGRAPH
+0x9F71 0x7123 #CJK UNIFIED IDEOGRAPH
+0x9F72 0x7124 #CJK UNIFIED IDEOGRAPH
+0x9F73 0x7125 #CJK UNIFIED IDEOGRAPH
+0x9F74 0x7127 #CJK UNIFIED IDEOGRAPH
+0x9F75 0x7128 #CJK UNIFIED IDEOGRAPH
+0x9F76 0x7129 #CJK UNIFIED IDEOGRAPH
+0x9F77 0x712A #CJK UNIFIED IDEOGRAPH
+0x9F78 0x712B #CJK UNIFIED IDEOGRAPH
+0x9F79 0x712C #CJK UNIFIED IDEOGRAPH
+0x9F7A 0x712D #CJK UNIFIED IDEOGRAPH
+0x9F7B 0x712E #CJK UNIFIED IDEOGRAPH
+0x9F7C 0x7132 #CJK UNIFIED IDEOGRAPH
+0x9F7D 0x7133 #CJK UNIFIED IDEOGRAPH
+0x9F7E 0x7134 #CJK UNIFIED IDEOGRAPH
+0x9F80 0x7135 #CJK UNIFIED IDEOGRAPH
+0x9F81 0x7137 #CJK UNIFIED IDEOGRAPH
+0x9F82 0x7138 #CJK UNIFIED IDEOGRAPH
+0x9F83 0x7139 #CJK UNIFIED IDEOGRAPH
+0x9F84 0x713A #CJK UNIFIED IDEOGRAPH
+0x9F85 0x713B #CJK UNIFIED IDEOGRAPH
+0x9F86 0x713C #CJK UNIFIED IDEOGRAPH
+0x9F87 0x713D #CJK UNIFIED IDEOGRAPH
+0x9F88 0x713E #CJK UNIFIED IDEOGRAPH
+0x9F89 0x713F #CJK UNIFIED IDEOGRAPH
+0x9F8A 0x7140 #CJK UNIFIED IDEOGRAPH
+0x9F8B 0x7141 #CJK UNIFIED IDEOGRAPH
+0x9F8C 0x7142 #CJK UNIFIED IDEOGRAPH
+0x9F8D 0x7143 #CJK UNIFIED IDEOGRAPH
+0x9F8E 0x7144 #CJK UNIFIED IDEOGRAPH
+0x9F8F 0x7146 #CJK UNIFIED IDEOGRAPH
+0x9F90 0x7147 #CJK UNIFIED IDEOGRAPH
+0x9F91 0x7148 #CJK UNIFIED IDEOGRAPH
+0x9F92 0x7149 #CJK UNIFIED IDEOGRAPH
+0x9F93 0x714B #CJK UNIFIED IDEOGRAPH
+0x9F94 0x714D #CJK UNIFIED IDEOGRAPH
+0x9F95 0x714F #CJK UNIFIED IDEOGRAPH
+0x9F96 0x7150 #CJK UNIFIED IDEOGRAPH
+0x9F97 0x7151 #CJK UNIFIED IDEOGRAPH
+0x9F98 0x7152 #CJK UNIFIED IDEOGRAPH
+0x9F99 0x7153 #CJK UNIFIED IDEOGRAPH
+0x9F9A 0x7154 #CJK UNIFIED IDEOGRAPH
+0x9F9B 0x7155 #CJK UNIFIED IDEOGRAPH
+0x9F9C 0x7156 #CJK UNIFIED IDEOGRAPH
+0x9F9D 0x7157 #CJK UNIFIED IDEOGRAPH
+0x9F9E 0x7158 #CJK UNIFIED IDEOGRAPH
+0x9F9F 0x7159 #CJK UNIFIED IDEOGRAPH
+0x9FA0 0x715A #CJK UNIFIED IDEOGRAPH
+0x9FA1 0x715B #CJK UNIFIED IDEOGRAPH
+0x9FA2 0x715D #CJK UNIFIED IDEOGRAPH
+0x9FA3 0x715F #CJK UNIFIED IDEOGRAPH
+0x9FA4 0x7160 #CJK UNIFIED IDEOGRAPH
+0x9FA5 0x7161 #CJK UNIFIED IDEOGRAPH
+0x9FA6 0x7162 #CJK UNIFIED IDEOGRAPH
+0x9FA7 0x7163 #CJK UNIFIED IDEOGRAPH
+0x9FA8 0x7165 #CJK UNIFIED IDEOGRAPH
+0x9FA9 0x7169 #CJK UNIFIED IDEOGRAPH
+0x9FAA 0x716A #CJK UNIFIED IDEOGRAPH
+0x9FAB 0x716B #CJK UNIFIED IDEOGRAPH
+0x9FAC 0x716C #CJK UNIFIED IDEOGRAPH
+0x9FAD 0x716D #CJK UNIFIED IDEOGRAPH
+0x9FAE 0x716F #CJK UNIFIED IDEOGRAPH
+0x9FAF 0x7170 #CJK UNIFIED IDEOGRAPH
+0x9FB0 0x7171 #CJK UNIFIED IDEOGRAPH
+0x9FB1 0x7174 #CJK UNIFIED IDEOGRAPH
+0x9FB2 0x7175 #CJK UNIFIED IDEOGRAPH
+0x9FB3 0x7176 #CJK UNIFIED IDEOGRAPH
+0x9FB4 0x7177 #CJK UNIFIED IDEOGRAPH
+0x9FB5 0x7179 #CJK UNIFIED IDEOGRAPH
+0x9FB6 0x717B #CJK UNIFIED IDEOGRAPH
+0x9FB7 0x717C #CJK UNIFIED IDEOGRAPH
+0x9FB8 0x717E #CJK UNIFIED IDEOGRAPH
+0x9FB9 0x717F #CJK UNIFIED IDEOGRAPH
+0x9FBA 0x7180 #CJK UNIFIED IDEOGRAPH
+0x9FBB 0x7181 #CJK UNIFIED IDEOGRAPH
+0x9FBC 0x7182 #CJK UNIFIED IDEOGRAPH
+0x9FBD 0x7183 #CJK UNIFIED IDEOGRAPH
+0x9FBE 0x7185 #CJK UNIFIED IDEOGRAPH
+0x9FBF 0x7186 #CJK UNIFIED IDEOGRAPH
+0x9FC0 0x7187 #CJK UNIFIED IDEOGRAPH
+0x9FC1 0x7188 #CJK UNIFIED IDEOGRAPH
+0x9FC2 0x7189 #CJK UNIFIED IDEOGRAPH
+0x9FC3 0x718B #CJK UNIFIED IDEOGRAPH
+0x9FC4 0x718C #CJK UNIFIED IDEOGRAPH
+0x9FC5 0x718D #CJK UNIFIED IDEOGRAPH
+0x9FC6 0x718E #CJK UNIFIED IDEOGRAPH
+0x9FC7 0x7190 #CJK UNIFIED IDEOGRAPH
+0x9FC8 0x7191 #CJK UNIFIED IDEOGRAPH
+0x9FC9 0x7192 #CJK UNIFIED IDEOGRAPH
+0x9FCA 0x7193 #CJK UNIFIED IDEOGRAPH
+0x9FCB 0x7195 #CJK UNIFIED IDEOGRAPH
+0x9FCC 0x7196 #CJK UNIFIED IDEOGRAPH
+0x9FCD 0x7197 #CJK UNIFIED IDEOGRAPH
+0x9FCE 0x719A #CJK UNIFIED IDEOGRAPH
+0x9FCF 0x719B #CJK UNIFIED IDEOGRAPH
+0x9FD0 0x719C #CJK UNIFIED IDEOGRAPH
+0x9FD1 0x719D #CJK UNIFIED IDEOGRAPH
+0x9FD2 0x719E #CJK UNIFIED IDEOGRAPH
+0x9FD3 0x71A1 #CJK UNIFIED IDEOGRAPH
+0x9FD4 0x71A2 #CJK UNIFIED IDEOGRAPH
+0x9FD5 0x71A3 #CJK UNIFIED IDEOGRAPH
+0x9FD6 0x71A4 #CJK UNIFIED IDEOGRAPH
+0x9FD7 0x71A5 #CJK UNIFIED IDEOGRAPH
+0x9FD8 0x71A6 #CJK UNIFIED IDEOGRAPH
+0x9FD9 0x71A7 #CJK UNIFIED IDEOGRAPH
+0x9FDA 0x71A9 #CJK UNIFIED IDEOGRAPH
+0x9FDB 0x71AA #CJK UNIFIED IDEOGRAPH
+0x9FDC 0x71AB #CJK UNIFIED IDEOGRAPH
+0x9FDD 0x71AD #CJK UNIFIED IDEOGRAPH
+0x9FDE 0x71AE #CJK UNIFIED IDEOGRAPH
+0x9FDF 0x71AF #CJK UNIFIED IDEOGRAPH
+0x9FE0 0x71B0 #CJK UNIFIED IDEOGRAPH
+0x9FE1 0x71B1 #CJK UNIFIED IDEOGRAPH
+0x9FE2 0x71B2 #CJK UNIFIED IDEOGRAPH
+0x9FE3 0x71B4 #CJK UNIFIED IDEOGRAPH
+0x9FE4 0x71B6 #CJK UNIFIED IDEOGRAPH
+0x9FE5 0x71B7 #CJK UNIFIED IDEOGRAPH
+0x9FE6 0x71B8 #CJK UNIFIED IDEOGRAPH
+0x9FE7 0x71BA #CJK UNIFIED IDEOGRAPH
+0x9FE8 0x71BB #CJK UNIFIED IDEOGRAPH
+0x9FE9 0x71BC #CJK UNIFIED IDEOGRAPH
+0x9FEA 0x71BD #CJK UNIFIED IDEOGRAPH
+0x9FEB 0x71BE #CJK UNIFIED IDEOGRAPH
+0x9FEC 0x71BF #CJK UNIFIED IDEOGRAPH
+0x9FED 0x71C0 #CJK UNIFIED IDEOGRAPH
+0x9FEE 0x71C1 #CJK UNIFIED IDEOGRAPH
+0x9FEF 0x71C2 #CJK UNIFIED IDEOGRAPH
+0x9FF0 0x71C4 #CJK UNIFIED IDEOGRAPH
+0x9FF1 0x71C5 #CJK UNIFIED IDEOGRAPH
+0x9FF2 0x71C6 #CJK UNIFIED IDEOGRAPH
+0x9FF3 0x71C7 #CJK UNIFIED IDEOGRAPH
+0x9FF4 0x71C8 #CJK UNIFIED IDEOGRAPH
+0x9FF5 0x71C9 #CJK UNIFIED IDEOGRAPH
+0x9FF6 0x71CA #CJK UNIFIED IDEOGRAPH
+0x9FF7 0x71CB #CJK UNIFIED IDEOGRAPH
+0x9FF8 0x71CC #CJK UNIFIED IDEOGRAPH
+0x9FF9 0x71CD #CJK UNIFIED IDEOGRAPH
+0x9FFA 0x71CF #CJK UNIFIED IDEOGRAPH
+0x9FFB 0x71D0 #CJK UNIFIED IDEOGRAPH
+0x9FFC 0x71D1 #CJK UNIFIED IDEOGRAPH
+0x9FFD 0x71D2 #CJK UNIFIED IDEOGRAPH
+0x9FFE 0x71D3 #CJK UNIFIED IDEOGRAPH
+0xA040 0x71D6 #CJK UNIFIED IDEOGRAPH
+0xA041 0x71D7 #CJK UNIFIED IDEOGRAPH
+0xA042 0x71D8 #CJK UNIFIED IDEOGRAPH
+0xA043 0x71D9 #CJK UNIFIED IDEOGRAPH
+0xA044 0x71DA #CJK UNIFIED IDEOGRAPH
+0xA045 0x71DB #CJK UNIFIED IDEOGRAPH
+0xA046 0x71DC #CJK UNIFIED IDEOGRAPH
+0xA047 0x71DD #CJK UNIFIED IDEOGRAPH
+0xA048 0x71DE #CJK UNIFIED IDEOGRAPH
+0xA049 0x71DF #CJK UNIFIED IDEOGRAPH
+0xA04A 0x71E1 #CJK UNIFIED IDEOGRAPH
+0xA04B 0x71E2 #CJK UNIFIED IDEOGRAPH
+0xA04C 0x71E3 #CJK UNIFIED IDEOGRAPH
+0xA04D 0x71E4 #CJK UNIFIED IDEOGRAPH
+0xA04E 0x71E6 #CJK UNIFIED IDEOGRAPH
+0xA04F 0x71E8 #CJK UNIFIED IDEOGRAPH
+0xA050 0x71E9 #CJK UNIFIED IDEOGRAPH
+0xA051 0x71EA #CJK UNIFIED IDEOGRAPH
+0xA052 0x71EB #CJK UNIFIED IDEOGRAPH
+0xA053 0x71EC #CJK UNIFIED IDEOGRAPH
+0xA054 0x71ED #CJK UNIFIED IDEOGRAPH
+0xA055 0x71EF #CJK UNIFIED IDEOGRAPH
+0xA056 0x71F0 #CJK UNIFIED IDEOGRAPH
+0xA057 0x71F1 #CJK UNIFIED IDEOGRAPH
+0xA058 0x71F2 #CJK UNIFIED IDEOGRAPH
+0xA059 0x71F3 #CJK UNIFIED IDEOGRAPH
+0xA05A 0x71F4 #CJK UNIFIED IDEOGRAPH
+0xA05B 0x71F5 #CJK UNIFIED IDEOGRAPH
+0xA05C 0x71F6 #CJK UNIFIED IDEOGRAPH
+0xA05D 0x71F7 #CJK UNIFIED IDEOGRAPH
+0xA05E 0x71F8 #CJK UNIFIED IDEOGRAPH
+0xA05F 0x71FA #CJK UNIFIED IDEOGRAPH
+0xA060 0x71FB #CJK UNIFIED IDEOGRAPH
+0xA061 0x71FC #CJK UNIFIED IDEOGRAPH
+0xA062 0x71FD #CJK UNIFIED IDEOGRAPH
+0xA063 0x71FE #CJK UNIFIED IDEOGRAPH
+0xA064 0x71FF #CJK UNIFIED IDEOGRAPH
+0xA065 0x7200 #CJK UNIFIED IDEOGRAPH
+0xA066 0x7201 #CJK UNIFIED IDEOGRAPH
+0xA067 0x7202 #CJK UNIFIED IDEOGRAPH
+0xA068 0x7203 #CJK UNIFIED IDEOGRAPH
+0xA069 0x7204 #CJK UNIFIED IDEOGRAPH
+0xA06A 0x7205 #CJK UNIFIED IDEOGRAPH
+0xA06B 0x7207 #CJK UNIFIED IDEOGRAPH
+0xA06C 0x7208 #CJK UNIFIED IDEOGRAPH
+0xA06D 0x7209 #CJK UNIFIED IDEOGRAPH
+0xA06E 0x720A #CJK UNIFIED IDEOGRAPH
+0xA06F 0x720B #CJK UNIFIED IDEOGRAPH
+0xA070 0x720C #CJK UNIFIED IDEOGRAPH
+0xA071 0x720D #CJK UNIFIED IDEOGRAPH
+0xA072 0x720E #CJK UNIFIED IDEOGRAPH
+0xA073 0x720F #CJK UNIFIED IDEOGRAPH
+0xA074 0x7210 #CJK UNIFIED IDEOGRAPH
+0xA075 0x7211 #CJK UNIFIED IDEOGRAPH
+0xA076 0x7212 #CJK UNIFIED IDEOGRAPH
+0xA077 0x7213 #CJK UNIFIED IDEOGRAPH
+0xA078 0x7214 #CJK UNIFIED IDEOGRAPH
+0xA079 0x7215 #CJK UNIFIED IDEOGRAPH
+0xA07A 0x7216 #CJK UNIFIED IDEOGRAPH
+0xA07B 0x7217 #CJK UNIFIED IDEOGRAPH
+0xA07C 0x7218 #CJK UNIFIED IDEOGRAPH
+0xA07D 0x7219 #CJK UNIFIED IDEOGRAPH
+0xA07E 0x721A #CJK UNIFIED IDEOGRAPH
+0xA080 0x721B #CJK UNIFIED IDEOGRAPH
+0xA081 0x721C #CJK UNIFIED IDEOGRAPH
+0xA082 0x721E #CJK UNIFIED IDEOGRAPH
+0xA083 0x721F #CJK UNIFIED IDEOGRAPH
+0xA084 0x7220 #CJK UNIFIED IDEOGRAPH
+0xA085 0x7221 #CJK UNIFIED IDEOGRAPH
+0xA086 0x7222 #CJK UNIFIED IDEOGRAPH
+0xA087 0x7223 #CJK UNIFIED IDEOGRAPH
+0xA088 0x7224 #CJK UNIFIED IDEOGRAPH
+0xA089 0x7225 #CJK UNIFIED IDEOGRAPH
+0xA08A 0x7226 #CJK UNIFIED IDEOGRAPH
+0xA08B 0x7227 #CJK UNIFIED IDEOGRAPH
+0xA08C 0x7229 #CJK UNIFIED IDEOGRAPH
+0xA08D 0x722B #CJK UNIFIED IDEOGRAPH
+0xA08E 0x722D #CJK UNIFIED IDEOGRAPH
+0xA08F 0x722E #CJK UNIFIED IDEOGRAPH
+0xA090 0x722F #CJK UNIFIED IDEOGRAPH
+0xA091 0x7232 #CJK UNIFIED IDEOGRAPH
+0xA092 0x7233 #CJK UNIFIED IDEOGRAPH
+0xA093 0x7234 #CJK UNIFIED IDEOGRAPH
+0xA094 0x723A #CJK UNIFIED IDEOGRAPH
+0xA095 0x723C #CJK UNIFIED IDEOGRAPH
+0xA096 0x723E #CJK UNIFIED IDEOGRAPH
+0xA097 0x7240 #CJK UNIFIED IDEOGRAPH
+0xA098 0x7241 #CJK UNIFIED IDEOGRAPH
+0xA099 0x7242 #CJK UNIFIED IDEOGRAPH
+0xA09A 0x7243 #CJK UNIFIED IDEOGRAPH
+0xA09B 0x7244 #CJK UNIFIED IDEOGRAPH
+0xA09C 0x7245 #CJK UNIFIED IDEOGRAPH
+0xA09D 0x7246 #CJK UNIFIED IDEOGRAPH
+0xA09E 0x7249 #CJK UNIFIED IDEOGRAPH
+0xA09F 0x724A #CJK UNIFIED IDEOGRAPH
+0xA0A0 0x724B #CJK UNIFIED IDEOGRAPH
+0xA0A1 0x724E #CJK UNIFIED IDEOGRAPH
+0xA0A2 0x724F #CJK UNIFIED IDEOGRAPH
+0xA0A3 0x7250 #CJK UNIFIED IDEOGRAPH
+0xA0A4 0x7251 #CJK UNIFIED IDEOGRAPH
+0xA0A5 0x7253 #CJK UNIFIED IDEOGRAPH
+0xA0A6 0x7254 #CJK UNIFIED IDEOGRAPH
+0xA0A7 0x7255 #CJK UNIFIED IDEOGRAPH
+0xA0A8 0x7257 #CJK UNIFIED IDEOGRAPH
+0xA0A9 0x7258 #CJK UNIFIED IDEOGRAPH
+0xA0AA 0x725A #CJK UNIFIED IDEOGRAPH
+0xA0AB 0x725C #CJK UNIFIED IDEOGRAPH
+0xA0AC 0x725E #CJK UNIFIED IDEOGRAPH
+0xA0AD 0x7260 #CJK UNIFIED IDEOGRAPH
+0xA0AE 0x7263 #CJK UNIFIED IDEOGRAPH
+0xA0AF 0x7264 #CJK UNIFIED IDEOGRAPH
+0xA0B0 0x7265 #CJK UNIFIED IDEOGRAPH
+0xA0B1 0x7268 #CJK UNIFIED IDEOGRAPH
+0xA0B2 0x726A #CJK UNIFIED IDEOGRAPH
+0xA0B3 0x726B #CJK UNIFIED IDEOGRAPH
+0xA0B4 0x726C #CJK UNIFIED IDEOGRAPH
+0xA0B5 0x726D #CJK UNIFIED IDEOGRAPH
+0xA0B6 0x7270 #CJK UNIFIED IDEOGRAPH
+0xA0B7 0x7271 #CJK UNIFIED IDEOGRAPH
+0xA0B8 0x7273 #CJK UNIFIED IDEOGRAPH
+0xA0B9 0x7274 #CJK UNIFIED IDEOGRAPH
+0xA0BA 0x7276 #CJK UNIFIED IDEOGRAPH
+0xA0BB 0x7277 #CJK UNIFIED IDEOGRAPH
+0xA0BC 0x7278 #CJK UNIFIED IDEOGRAPH
+0xA0BD 0x727B #CJK UNIFIED IDEOGRAPH
+0xA0BE 0x727C #CJK UNIFIED IDEOGRAPH
+0xA0BF 0x727D #CJK UNIFIED IDEOGRAPH
+0xA0C0 0x7282 #CJK UNIFIED IDEOGRAPH
+0xA0C1 0x7283 #CJK UNIFIED IDEOGRAPH
+0xA0C2 0x7285 #CJK UNIFIED IDEOGRAPH
+0xA0C3 0x7286 #CJK UNIFIED IDEOGRAPH
+0xA0C4 0x7287 #CJK UNIFIED IDEOGRAPH
+0xA0C5 0x7288 #CJK UNIFIED IDEOGRAPH
+0xA0C6 0x7289 #CJK UNIFIED IDEOGRAPH
+0xA0C7 0x728C #CJK UNIFIED IDEOGRAPH
+0xA0C8 0x728E #CJK UNIFIED IDEOGRAPH
+0xA0C9 0x7290 #CJK UNIFIED IDEOGRAPH
+0xA0CA 0x7291 #CJK UNIFIED IDEOGRAPH
+0xA0CB 0x7293 #CJK UNIFIED IDEOGRAPH
+0xA0CC 0x7294 #CJK UNIFIED IDEOGRAPH
+0xA0CD 0x7295 #CJK UNIFIED IDEOGRAPH
+0xA0CE 0x7296 #CJK UNIFIED IDEOGRAPH
+0xA0CF 0x7297 #CJK UNIFIED IDEOGRAPH
+0xA0D0 0x7298 #CJK UNIFIED IDEOGRAPH
+0xA0D1 0x7299 #CJK UNIFIED IDEOGRAPH
+0xA0D2 0x729A #CJK UNIFIED IDEOGRAPH
+0xA0D3 0x729B #CJK UNIFIED IDEOGRAPH
+0xA0D4 0x729C #CJK UNIFIED IDEOGRAPH
+0xA0D5 0x729D #CJK UNIFIED IDEOGRAPH
+0xA0D6 0x729E #CJK UNIFIED IDEOGRAPH
+0xA0D7 0x72A0 #CJK UNIFIED IDEOGRAPH
+0xA0D8 0x72A1 #CJK UNIFIED IDEOGRAPH
+0xA0D9 0x72A2 #CJK UNIFIED IDEOGRAPH
+0xA0DA 0x72A3 #CJK UNIFIED IDEOGRAPH
+0xA0DB 0x72A4 #CJK UNIFIED IDEOGRAPH
+0xA0DC 0x72A5 #CJK UNIFIED IDEOGRAPH
+0xA0DD 0x72A6 #CJK UNIFIED IDEOGRAPH
+0xA0DE 0x72A7 #CJK UNIFIED IDEOGRAPH
+0xA0DF 0x72A8 #CJK UNIFIED IDEOGRAPH
+0xA0E0 0x72A9 #CJK UNIFIED IDEOGRAPH
+0xA0E1 0x72AA #CJK UNIFIED IDEOGRAPH
+0xA0E2 0x72AB #CJK UNIFIED IDEOGRAPH
+0xA0E3 0x72AE #CJK UNIFIED IDEOGRAPH
+0xA0E4 0x72B1 #CJK UNIFIED IDEOGRAPH
+0xA0E5 0x72B2 #CJK UNIFIED IDEOGRAPH
+0xA0E6 0x72B3 #CJK UNIFIED IDEOGRAPH
+0xA0E7 0x72B5 #CJK UNIFIED IDEOGRAPH
+0xA0E8 0x72BA #CJK UNIFIED IDEOGRAPH
+0xA0E9 0x72BB #CJK UNIFIED IDEOGRAPH
+0xA0EA 0x72BC #CJK UNIFIED IDEOGRAPH
+0xA0EB 0x72BD #CJK UNIFIED IDEOGRAPH
+0xA0EC 0x72BE #CJK UNIFIED IDEOGRAPH
+0xA0ED 0x72BF #CJK UNIFIED IDEOGRAPH
+0xA0EE 0x72C0 #CJK UNIFIED IDEOGRAPH
+0xA0EF 0x72C5 #CJK UNIFIED IDEOGRAPH
+0xA0F0 0x72C6 #CJK UNIFIED IDEOGRAPH
+0xA0F1 0x72C7 #CJK UNIFIED IDEOGRAPH
+0xA0F2 0x72C9 #CJK UNIFIED IDEOGRAPH
+0xA0F3 0x72CA #CJK UNIFIED IDEOGRAPH
+0xA0F4 0x72CB #CJK UNIFIED IDEOGRAPH
+0xA0F5 0x72CC #CJK UNIFIED IDEOGRAPH
+0xA0F6 0x72CF #CJK UNIFIED IDEOGRAPH
+0xA0F7 0x72D1 #CJK UNIFIED IDEOGRAPH
+0xA0F8 0x72D3 #CJK UNIFIED IDEOGRAPH
+0xA0F9 0x72D4 #CJK UNIFIED IDEOGRAPH
+0xA0FA 0x72D5 #CJK UNIFIED IDEOGRAPH
+0xA0FB 0x72D6 #CJK UNIFIED IDEOGRAPH
+0xA0FC 0x72D8 #CJK UNIFIED IDEOGRAPH
+0xA0FD 0x72DA #CJK UNIFIED IDEOGRAPH
+0xA0FE 0x72DB #CJK UNIFIED IDEOGRAPH
+0xA1A1 0x3000 #IDEOGRAPHIC SPACE
+0xA1A2 0x3001 #IDEOGRAPHIC COMMA
+0xA1A3 0x3002 #IDEOGRAPHIC FULL STOP
+0xA1A4 0x00B7 #MIDDLE DOT
+0xA1A5 0x02C9 #MODIFIER LETTER MACRON
+0xA1A6 0x02C7 #CARON
+0xA1A7 0x00A8 #DIAERESIS
+0xA1A8 0x3003 #DITTO MARK
+0xA1A9 0x3005 #IDEOGRAPHIC ITERATION MARK
+0xA1AA 0x2014 #EM DASH
+0xA1AB 0xFF5E #FULLWIDTH TILDE
+0xA1AC 0x2016 #DOUBLE VERTICAL LINE
+0xA1AD 0x2026 #HORIZONTAL ELLIPSIS
+0xA1AE 0x2018 #LEFT SINGLE QUOTATION MARK
+0xA1AF 0x2019 #RIGHT SINGLE QUOTATION MARK
+0xA1B0 0x201C #LEFT DOUBLE QUOTATION MARK
+0xA1B1 0x201D #RIGHT DOUBLE QUOTATION MARK
+0xA1B2 0x3014 #LEFT TORTOISE SHELL BRACKET
+0xA1B3 0x3015 #RIGHT TORTOISE SHELL BRACKET
+0xA1B4 0x3008 #LEFT ANGLE BRACKET
+0xA1B5 0x3009 #RIGHT ANGLE BRACKET
+0xA1B6 0x300A #LEFT DOUBLE ANGLE BRACKET
+0xA1B7 0x300B #RIGHT DOUBLE ANGLE BRACKET
+0xA1B8 0x300C #LEFT CORNER BRACKET
+0xA1B9 0x300D #RIGHT CORNER BRACKET
+0xA1BA 0x300E #LEFT WHITE CORNER BRACKET
+0xA1BB 0x300F #RIGHT WHITE CORNER BRACKET
+0xA1BC 0x3016 #LEFT WHITE LENTICULAR BRACKET
+0xA1BD 0x3017 #RIGHT WHITE LENTICULAR BRACKET
+0xA1BE 0x3010 #LEFT BLACK LENTICULAR BRACKET
+0xA1BF 0x3011 #RIGHT BLACK LENTICULAR BRACKET
+0xA1C0 0x00B1 #PLUS-MINUS SIGN
+0xA1C1 0x00D7 #MULTIPLICATION SIGN
+0xA1C2 0x00F7 #DIVISION SIGN
+0xA1C3 0x2236 #RATIO
+0xA1C4 0x2227 #LOGICAL AND
+0xA1C5 0x2228 #LOGICAL OR
+0xA1C6 0x2211 #N-ARY SUMMATION
+0xA1C7 0x220F #N-ARY PRODUCT
+0xA1C8 0x222A #UNION
+0xA1C9 0x2229 #INTERSECTION
+0xA1CA 0x2208 #ELEMENT OF
+0xA1CB 0x2237 #PROPORTION
+0xA1CC 0x221A #SQUARE ROOT
+0xA1CD 0x22A5 #UP TACK
+0xA1CE 0x2225 #PARALLEL TO
+0xA1CF 0x2220 #ANGLE
+0xA1D0 0x2312 #ARC
+0xA1D1 0x2299 #CIRCLED DOT OPERATOR
+0xA1D2 0x222B #INTEGRAL
+0xA1D3 0x222E #CONTOUR INTEGRAL
+0xA1D4 0x2261 #IDENTICAL TO
+0xA1D5 0x224C #ALL EQUAL TO
+0xA1D6 0x2248 #ALMOST EQUAL TO
+0xA1D7 0x223D #REVERSED TILDE
+0xA1D8 0x221D #PROPORTIONAL TO
+0xA1D9 0x2260 #NOT EQUAL TO
+0xA1DA 0x226E #NOT LESS-THAN
+0xA1DB 0x226F #NOT GREATER-THAN
+0xA1DC 0x2264 #LESS-THAN OR EQUAL TO
+0xA1DD 0x2265 #GREATER-THAN OR EQUAL TO
+0xA1DE 0x221E #INFINITY
+0xA1DF 0x2235 #BECAUSE
+0xA1E0 0x2234 #THEREFORE
+0xA1E1 0x2642 #MALE SIGN
+0xA1E2 0x2640 #FEMALE SIGN
+0xA1E3 0x00B0 #DEGREE SIGN
+0xA1E4 0x2032 #PRIME
+0xA1E5 0x2033 #DOUBLE PRIME
+0xA1E6 0x2103 #DEGREE CELSIUS
+0xA1E7 0xFF04 #FULLWIDTH DOLLAR SIGN
+0xA1E8 0x00A4 #CURRENCY SIGN
+0xA1E9 0xFFE0 #FULLWIDTH CENT SIGN
+0xA1EA 0xFFE1 #FULLWIDTH POUND SIGN
+0xA1EB 0x2030 #PER MILLE SIGN
+0xA1EC 0x00A7 #SECTION SIGN
+0xA1ED 0x2116 #NUMERO SIGN
+0xA1EE 0x2606 #WHITE STAR
+0xA1EF 0x2605 #BLACK STAR
+0xA1F0 0x25CB #WHITE CIRCLE
+0xA1F1 0x25CF #BLACK CIRCLE
+0xA1F2 0x25CE #BULLSEYE
+0xA1F3 0x25C7 #WHITE DIAMOND
+0xA1F4 0x25C6 #BLACK DIAMOND
+0xA1F5 0x25A1 #WHITE SQUARE
+0xA1F6 0x25A0 #BLACK SQUARE
+0xA1F7 0x25B3 #WHITE UP-POINTING TRIANGLE
+0xA1F8 0x25B2 #BLACK UP-POINTING TRIANGLE
+0xA1F9 0x203B #REFERENCE MARK
+0xA1FA 0x2192 #RIGHTWARDS ARROW
+0xA1FB 0x2190 #LEFTWARDS ARROW
+0xA1FC 0x2191 #UPWARDS ARROW
+0xA1FD 0x2193 #DOWNWARDS ARROW
+0xA1FE 0x3013 #GETA MARK
+0xA2A1 0x2170 #SMALL ROMAN NUMERAL ONE
+0xA2A2 0x2171 #SMALL ROMAN NUMERAL TWO
+0xA2A3 0x2172 #SMALL ROMAN NUMERAL THREE
+0xA2A4 0x2173 #SMALL ROMAN NUMERAL FOUR
+0xA2A5 0x2174 #SMALL ROMAN NUMERAL FIVE
+0xA2A6 0x2175 #SMALL ROMAN NUMERAL SIX
+0xA2A7 0x2176 #SMALL ROMAN NUMERAL SEVEN
+0xA2A8 0x2177 #SMALL ROMAN NUMERAL EIGHT
+0xA2A9 0x2178 #SMALL ROMAN NUMERAL NINE
+0xA2AA 0x2179 #SMALL ROMAN NUMERAL TEN
+0xA2B1 0x2488 #DIGIT ONE FULL STOP
+0xA2B2 0x2489 #DIGIT TWO FULL STOP
+0xA2B3 0x248A #DIGIT THREE FULL STOP
+0xA2B4 0x248B #DIGIT FOUR FULL STOP
+0xA2B5 0x248C #DIGIT FIVE FULL STOP
+0xA2B6 0x248D #DIGIT SIX FULL STOP
+0xA2B7 0x248E #DIGIT SEVEN FULL STOP
+0xA2B8 0x248F #DIGIT EIGHT FULL STOP
+0xA2B9 0x2490 #DIGIT NINE FULL STOP
+0xA2BA 0x2491 #NUMBER TEN FULL STOP
+0xA2BB 0x2492 #NUMBER ELEVEN FULL STOP
+0xA2BC 0x2493 #NUMBER TWELVE FULL STOP
+0xA2BD 0x2494 #NUMBER THIRTEEN FULL STOP
+0xA2BE 0x2495 #NUMBER FOURTEEN FULL STOP
+0xA2BF 0x2496 #NUMBER FIFTEEN FULL STOP
+0xA2C0 0x2497 #NUMBER SIXTEEN FULL STOP
+0xA2C1 0x2498 #NUMBER SEVENTEEN FULL STOP
+0xA2C2 0x2499 #NUMBER EIGHTEEN FULL STOP
+0xA2C3 0x249A #NUMBER NINETEEN FULL STOP
+0xA2C4 0x249B #NUMBER TWENTY FULL STOP
+0xA2C5 0x2474 #PARENTHESIZED DIGIT ONE
+0xA2C6 0x2475 #PARENTHESIZED DIGIT TWO
+0xA2C7 0x2476 #PARENTHESIZED DIGIT THREE
+0xA2C8 0x2477 #PARENTHESIZED DIGIT FOUR
+0xA2C9 0x2478 #PARENTHESIZED DIGIT FIVE
+0xA2CA 0x2479 #PARENTHESIZED DIGIT SIX
+0xA2CB 0x247A #PARENTHESIZED DIGIT SEVEN
+0xA2CC 0x247B #PARENTHESIZED DIGIT EIGHT
+0xA2CD 0x247C #PARENTHESIZED DIGIT NINE
+0xA2CE 0x247D #PARENTHESIZED NUMBER TEN
+0xA2CF 0x247E #PARENTHESIZED NUMBER ELEVEN
+0xA2D0 0x247F #PARENTHESIZED NUMBER TWELVE
+0xA2D1 0x2480 #PARENTHESIZED NUMBER THIRTEEN
+0xA2D2 0x2481 #PARENTHESIZED NUMBER FOURTEEN
+0xA2D3 0x2482 #PARENTHESIZED NUMBER FIFTEEN
+0xA2D4 0x2483 #PARENTHESIZED NUMBER SIXTEEN
+0xA2D5 0x2484 #PARENTHESIZED NUMBER SEVENTEEN
+0xA2D6 0x2485 #PARENTHESIZED NUMBER EIGHTEEN
+0xA2D7 0x2486 #PARENTHESIZED NUMBER NINETEEN
+0xA2D8 0x2487 #PARENTHESIZED NUMBER TWENTY
+0xA2D9 0x2460 #CIRCLED DIGIT ONE
+0xA2DA 0x2461 #CIRCLED DIGIT TWO
+0xA2DB 0x2462 #CIRCLED DIGIT THREE
+0xA2DC 0x2463 #CIRCLED DIGIT FOUR
+0xA2DD 0x2464 #CIRCLED DIGIT FIVE
+0xA2DE 0x2465 #CIRCLED DIGIT SIX
+0xA2DF 0x2466 #CIRCLED DIGIT SEVEN
+0xA2E0 0x2467 #CIRCLED DIGIT EIGHT
+0xA2E1 0x2468 #CIRCLED DIGIT NINE
+0xA2E2 0x2469 #CIRCLED NUMBER TEN
+0xA2E5 0x3220 #PARENTHESIZED IDEOGRAPH ONE
+0xA2E6 0x3221 #PARENTHESIZED IDEOGRAPH TWO
+0xA2E7 0x3222 #PARENTHESIZED IDEOGRAPH THREE
+0xA2E8 0x3223 #PARENTHESIZED IDEOGRAPH FOUR
+0xA2E9 0x3224 #PARENTHESIZED IDEOGRAPH FIVE
+0xA2EA 0x3225 #PARENTHESIZED IDEOGRAPH SIX
+0xA2EB 0x3226 #PARENTHESIZED IDEOGRAPH SEVEN
+0xA2EC 0x3227 #PARENTHESIZED IDEOGRAPH EIGHT
+0xA2ED 0x3228 #PARENTHESIZED IDEOGRAPH NINE
+0xA2EE 0x3229 #PARENTHESIZED IDEOGRAPH TEN
+0xA2F1 0x2160 #ROMAN NUMERAL ONE
+0xA2F2 0x2161 #ROMAN NUMERAL TWO
+0xA2F3 0x2162 #ROMAN NUMERAL THREE
+0xA2F4 0x2163 #ROMAN NUMERAL FOUR
+0xA2F5 0x2164 #ROMAN NUMERAL FIVE
+0xA2F6 0x2165 #ROMAN NUMERAL SIX
+0xA2F7 0x2166 #ROMAN NUMERAL SEVEN
+0xA2F8 0x2167 #ROMAN NUMERAL EIGHT
+0xA2F9 0x2168 #ROMAN NUMERAL NINE
+0xA2FA 0x2169 #ROMAN NUMERAL TEN
+0xA2FB 0x216A #ROMAN NUMERAL ELEVEN
+0xA2FC 0x216B #ROMAN NUMERAL TWELVE
+0xA3A1 0xFF01 #FULLWIDTH EXCLAMATION MARK
+0xA3A2 0xFF02 #FULLWIDTH QUOTATION MARK
+0xA3A3 0xFF03 #FULLWIDTH NUMBER SIGN
+0xA3A4 0xFFE5 #FULLWIDTH YEN SIGN
+0xA3A5 0xFF05 #FULLWIDTH PERCENT SIGN
+0xA3A6 0xFF06 #FULLWIDTH AMPERSAND
+0xA3A7 0xFF07 #FULLWIDTH APOSTROPHE
+0xA3A8 0xFF08 #FULLWIDTH LEFT PARENTHESIS
+0xA3A9 0xFF09 #FULLWIDTH RIGHT PARENTHESIS
+0xA3AA 0xFF0A #FULLWIDTH ASTERISK
+0xA3AB 0xFF0B #FULLWIDTH PLUS SIGN
+0xA3AC 0xFF0C #FULLWIDTH COMMA
+0xA3AD 0xFF0D #FULLWIDTH HYPHEN-MINUS
+0xA3AE 0xFF0E #FULLWIDTH FULL STOP
+0xA3AF 0xFF0F #FULLWIDTH SOLIDUS
+0xA3B0 0xFF10 #FULLWIDTH DIGIT ZERO
+0xA3B1 0xFF11 #FULLWIDTH DIGIT ONE
+0xA3B2 0xFF12 #FULLWIDTH DIGIT TWO
+0xA3B3 0xFF13 #FULLWIDTH DIGIT THREE
+0xA3B4 0xFF14 #FULLWIDTH DIGIT FOUR
+0xA3B5 0xFF15 #FULLWIDTH DIGIT FIVE
+0xA3B6 0xFF16 #FULLWIDTH DIGIT SIX
+0xA3B7 0xFF17 #FULLWIDTH DIGIT SEVEN
+0xA3B8 0xFF18 #FULLWIDTH DIGIT EIGHT
+0xA3B9 0xFF19 #FULLWIDTH DIGIT NINE
+0xA3BA 0xFF1A #FULLWIDTH COLON
+0xA3BB 0xFF1B #FULLWIDTH SEMICOLON
+0xA3BC 0xFF1C #FULLWIDTH LESS-THAN SIGN
+0xA3BD 0xFF1D #FULLWIDTH EQUALS SIGN
+0xA3BE 0xFF1E #FULLWIDTH GREATER-THAN SIGN
+0xA3BF 0xFF1F #FULLWIDTH QUESTION MARK
+0xA3C0 0xFF20 #FULLWIDTH COMMERCIAL AT
+0xA3C1 0xFF21 #FULLWIDTH LATIN CAPITAL LETTER A
+0xA3C2 0xFF22 #FULLWIDTH LATIN CAPITAL LETTER B
+0xA3C3 0xFF23 #FULLWIDTH LATIN CAPITAL LETTER C
+0xA3C4 0xFF24 #FULLWIDTH LATIN CAPITAL LETTER D
+0xA3C5 0xFF25 #FULLWIDTH LATIN CAPITAL LETTER E
+0xA3C6 0xFF26 #FULLWIDTH LATIN CAPITAL LETTER F
+0xA3C7 0xFF27 #FULLWIDTH LATIN CAPITAL LETTER G
+0xA3C8 0xFF28 #FULLWIDTH LATIN CAPITAL LETTER H
+0xA3C9 0xFF29 #FULLWIDTH LATIN CAPITAL LETTER I
+0xA3CA 0xFF2A #FULLWIDTH LATIN CAPITAL LETTER J
+0xA3CB 0xFF2B #FULLWIDTH LATIN CAPITAL LETTER K
+0xA3CC 0xFF2C #FULLWIDTH LATIN CAPITAL LETTER L
+0xA3CD 0xFF2D #FULLWIDTH LATIN CAPITAL LETTER M
+0xA3CE 0xFF2E #FULLWIDTH LATIN CAPITAL LETTER N
+0xA3CF 0xFF2F #FULLWIDTH LATIN CAPITAL LETTER O
+0xA3D0 0xFF30 #FULLWIDTH LATIN CAPITAL LETTER P
+0xA3D1 0xFF31 #FULLWIDTH LATIN CAPITAL LETTER Q
+0xA3D2 0xFF32 #FULLWIDTH LATIN CAPITAL LETTER R
+0xA3D3 0xFF33 #FULLWIDTH LATIN CAPITAL LETTER S
+0xA3D4 0xFF34 #FULLWIDTH LATIN CAPITAL LETTER T
+0xA3D5 0xFF35 #FULLWIDTH LATIN CAPITAL LETTER U
+0xA3D6 0xFF36 #FULLWIDTH LATIN CAPITAL LETTER V
+0xA3D7 0xFF37 #FULLWIDTH LATIN CAPITAL LETTER W
+0xA3D8 0xFF38 #FULLWIDTH LATIN CAPITAL LETTER X
+0xA3D9 0xFF39 #FULLWIDTH LATIN CAPITAL LETTER Y
+0xA3DA 0xFF3A #FULLWIDTH LATIN CAPITAL LETTER Z
+0xA3DB 0xFF3B #FULLWIDTH LEFT SQUARE BRACKET
+0xA3DC 0xFF3C #FULLWIDTH REVERSE SOLIDUS
+0xA3DD 0xFF3D #FULLWIDTH RIGHT SQUARE BRACKET
+0xA3DE 0xFF3E #FULLWIDTH CIRCUMFLEX ACCENT
+0xA3DF 0xFF3F #FULLWIDTH LOW LINE
+0xA3E0 0xFF40 #FULLWIDTH GRAVE ACCENT
+0xA3E1 0xFF41 #FULLWIDTH LATIN SMALL LETTER A
+0xA3E2 0xFF42 #FULLWIDTH LATIN SMALL LETTER B
+0xA3E3 0xFF43 #FULLWIDTH LATIN SMALL LETTER C
+0xA3E4 0xFF44 #FULLWIDTH LATIN SMALL LETTER D
+0xA3E5 0xFF45 #FULLWIDTH LATIN SMALL LETTER E
+0xA3E6 0xFF46 #FULLWIDTH LATIN SMALL LETTER F
+0xA3E7 0xFF47 #FULLWIDTH LATIN SMALL LETTER G
+0xA3E8 0xFF48 #FULLWIDTH LATIN SMALL LETTER H
+0xA3E9 0xFF49 #FULLWIDTH LATIN SMALL LETTER I
+0xA3EA 0xFF4A #FULLWIDTH LATIN SMALL LETTER J
+0xA3EB 0xFF4B #FULLWIDTH LATIN SMALL LETTER K
+0xA3EC 0xFF4C #FULLWIDTH LATIN SMALL LETTER L
+0xA3ED 0xFF4D #FULLWIDTH LATIN SMALL LETTER M
+0xA3EE 0xFF4E #FULLWIDTH LATIN SMALL LETTER N
+0xA3EF 0xFF4F #FULLWIDTH LATIN SMALL LETTER O
+0xA3F0 0xFF50 #FULLWIDTH LATIN SMALL LETTER P
+0xA3F1 0xFF51 #FULLWIDTH LATIN SMALL LETTER Q
+0xA3F2 0xFF52 #FULLWIDTH LATIN SMALL LETTER R
+0xA3F3 0xFF53 #FULLWIDTH LATIN SMALL LETTER S
+0xA3F4 0xFF54 #FULLWIDTH LATIN SMALL LETTER T
+0xA3F5 0xFF55 #FULLWIDTH LATIN SMALL LETTER U
+0xA3F6 0xFF56 #FULLWIDTH LATIN SMALL LETTER V
+0xA3F7 0xFF57 #FULLWIDTH LATIN SMALL LETTER W
+0xA3F8 0xFF58 #FULLWIDTH LATIN SMALL LETTER X
+0xA3F9 0xFF59 #FULLWIDTH LATIN SMALL LETTER Y
+0xA3FA 0xFF5A #FULLWIDTH LATIN SMALL LETTER Z
+0xA3FB 0xFF5B #FULLWIDTH LEFT CURLY BRACKET
+0xA3FC 0xFF5C #FULLWIDTH VERTICAL LINE
+0xA3FD 0xFF5D #FULLWIDTH RIGHT CURLY BRACKET
+0xA3FE 0xFFE3 #FULLWIDTH MACRON
+0xA4A1 0x3041 #HIRAGANA LETTER SMALL A
+0xA4A2 0x3042 #HIRAGANA LETTER A
+0xA4A3 0x3043 #HIRAGANA LETTER SMALL I
+0xA4A4 0x3044 #HIRAGANA LETTER I
+0xA4A5 0x3045 #HIRAGANA LETTER SMALL U
+0xA4A6 0x3046 #HIRAGANA LETTER U
+0xA4A7 0x3047 #HIRAGANA LETTER SMALL E
+0xA4A8 0x3048 #HIRAGANA LETTER E
+0xA4A9 0x3049 #HIRAGANA LETTER SMALL O
+0xA4AA 0x304A #HIRAGANA LETTER O
+0xA4AB 0x304B #HIRAGANA LETTER KA
+0xA4AC 0x304C #HIRAGANA LETTER GA
+0xA4AD 0x304D #HIRAGANA LETTER KI
+0xA4AE 0x304E #HIRAGANA LETTER GI
+0xA4AF 0x304F #HIRAGANA LETTER KU
+0xA4B0 0x3050 #HIRAGANA LETTER GU
+0xA4B1 0x3051 #HIRAGANA LETTER KE
+0xA4B2 0x3052 #HIRAGANA LETTER GE
+0xA4B3 0x3053 #HIRAGANA LETTER KO
+0xA4B4 0x3054 #HIRAGANA LETTER GO
+0xA4B5 0x3055 #HIRAGANA LETTER SA
+0xA4B6 0x3056 #HIRAGANA LETTER ZA
+0xA4B7 0x3057 #HIRAGANA LETTER SI
+0xA4B8 0x3058 #HIRAGANA LETTER ZI
+0xA4B9 0x3059 #HIRAGANA LETTER SU
+0xA4BA 0x305A #HIRAGANA LETTER ZU
+0xA4BB 0x305B #HIRAGANA LETTER SE
+0xA4BC 0x305C #HIRAGANA LETTER ZE
+0xA4BD 0x305D #HIRAGANA LETTER SO
+0xA4BE 0x305E #HIRAGANA LETTER ZO
+0xA4BF 0x305F #HIRAGANA LETTER TA
+0xA4C0 0x3060 #HIRAGANA LETTER DA
+0xA4C1 0x3061 #HIRAGANA LETTER TI
+0xA4C2 0x3062 #HIRAGANA LETTER DI
+0xA4C3 0x3063 #HIRAGANA LETTER SMALL TU
+0xA4C4 0x3064 #HIRAGANA LETTER TU
+0xA4C5 0x3065 #HIRAGANA LETTER DU
+0xA4C6 0x3066 #HIRAGANA LETTER TE
+0xA4C7 0x3067 #HIRAGANA LETTER DE
+0xA4C8 0x3068 #HIRAGANA LETTER TO
+0xA4C9 0x3069 #HIRAGANA LETTER DO
+0xA4CA 0x306A #HIRAGANA LETTER NA
+0xA4CB 0x306B #HIRAGANA LETTER NI
+0xA4CC 0x306C #HIRAGANA LETTER NU
+0xA4CD 0x306D #HIRAGANA LETTER NE
+0xA4CE 0x306E #HIRAGANA LETTER NO
+0xA4CF 0x306F #HIRAGANA LETTER HA
+0xA4D0 0x3070 #HIRAGANA LETTER BA
+0xA4D1 0x3071 #HIRAGANA LETTER PA
+0xA4D2 0x3072 #HIRAGANA LETTER HI
+0xA4D3 0x3073 #HIRAGANA LETTER BI
+0xA4D4 0x3074 #HIRAGANA LETTER PI
+0xA4D5 0x3075 #HIRAGANA LETTER HU
+0xA4D6 0x3076 #HIRAGANA LETTER BU
+0xA4D7 0x3077 #HIRAGANA LETTER PU
+0xA4D8 0x3078 #HIRAGANA LETTER HE
+0xA4D9 0x3079 #HIRAGANA LETTER BE
+0xA4DA 0x307A #HIRAGANA LETTER PE
+0xA4DB 0x307B #HIRAGANA LETTER HO
+0xA4DC 0x307C #HIRAGANA LETTER BO
+0xA4DD 0x307D #HIRAGANA LETTER PO
+0xA4DE 0x307E #HIRAGANA LETTER MA
+0xA4DF 0x307F #HIRAGANA LETTER MI
+0xA4E0 0x3080 #HIRAGANA LETTER MU
+0xA4E1 0x3081 #HIRAGANA LETTER ME
+0xA4E2 0x3082 #HIRAGANA LETTER MO
+0xA4E3 0x3083 #HIRAGANA LETTER SMALL YA
+0xA4E4 0x3084 #HIRAGANA LETTER YA
+0xA4E5 0x3085 #HIRAGANA LETTER SMALL YU
+0xA4E6 0x3086 #HIRAGANA LETTER YU
+0xA4E7 0x3087 #HIRAGANA LETTER SMALL YO
+0xA4E8 0x3088 #HIRAGANA LETTER YO
+0xA4E9 0x3089 #HIRAGANA LETTER RA
+0xA4EA 0x308A #HIRAGANA LETTER RI
+0xA4EB 0x308B #HIRAGANA LETTER RU
+0xA4EC 0x308C #HIRAGANA LETTER RE
+0xA4ED 0x308D #HIRAGANA LETTER RO
+0xA4EE 0x308E #HIRAGANA LETTER SMALL WA
+0xA4EF 0x308F #HIRAGANA LETTER WA
+0xA4F0 0x3090 #HIRAGANA LETTER WI
+0xA4F1 0x3091 #HIRAGANA LETTER WE
+0xA4F2 0x3092 #HIRAGANA LETTER WO
+0xA4F3 0x3093 #HIRAGANA LETTER N
+0xA5A1 0x30A1 #KATAKANA LETTER SMALL A
+0xA5A2 0x30A2 #KATAKANA LETTER A
+0xA5A3 0x30A3 #KATAKANA LETTER SMALL I
+0xA5A4 0x30A4 #KATAKANA LETTER I
+0xA5A5 0x30A5 #KATAKANA LETTER SMALL U
+0xA5A6 0x30A6 #KATAKANA LETTER U
+0xA5A7 0x30A7 #KATAKANA LETTER SMALL E
+0xA5A8 0x30A8 #KATAKANA LETTER E
+0xA5A9 0x30A9 #KATAKANA LETTER SMALL O
+0xA5AA 0x30AA #KATAKANA LETTER O
+0xA5AB 0x30AB #KATAKANA LETTER KA
+0xA5AC 0x30AC #KATAKANA LETTER GA
+0xA5AD 0x30AD #KATAKANA LETTER KI
+0xA5AE 0x30AE #KATAKANA LETTER GI
+0xA5AF 0x30AF #KATAKANA LETTER KU
+0xA5B0 0x30B0 #KATAKANA LETTER GU
+0xA5B1 0x30B1 #KATAKANA LETTER KE
+0xA5B2 0x30B2 #KATAKANA LETTER GE
+0xA5B3 0x30B3 #KATAKANA LETTER KO
+0xA5B4 0x30B4 #KATAKANA LETTER GO
+0xA5B5 0x30B5 #KATAKANA LETTER SA
+0xA5B6 0x30B6 #KATAKANA LETTER ZA
+0xA5B7 0x30B7 #KATAKANA LETTER SI
+0xA5B8 0x30B8 #KATAKANA LETTER ZI
+0xA5B9 0x30B9 #KATAKANA LETTER SU
+0xA5BA 0x30BA #KATAKANA LETTER ZU
+0xA5BB 0x30BB #KATAKANA LETTER SE
+0xA5BC 0x30BC #KATAKANA LETTER ZE
+0xA5BD 0x30BD #KATAKANA LETTER SO
+0xA5BE 0x30BE #KATAKANA LETTER ZO
+0xA5BF 0x30BF #KATAKANA LETTER TA
+0xA5C0 0x30C0 #KATAKANA LETTER DA
+0xA5C1 0x30C1 #KATAKANA LETTER TI
+0xA5C2 0x30C2 #KATAKANA LETTER DI
+0xA5C3 0x30C3 #KATAKANA LETTER SMALL TU
+0xA5C4 0x30C4 #KATAKANA LETTER TU
+0xA5C5 0x30C5 #KATAKANA LETTER DU
+0xA5C6 0x30C6 #KATAKANA LETTER TE
+0xA5C7 0x30C7 #KATAKANA LETTER DE
+0xA5C8 0x30C8 #KATAKANA LETTER TO
+0xA5C9 0x30C9 #KATAKANA LETTER DO
+0xA5CA 0x30CA #KATAKANA LETTER NA
+0xA5CB 0x30CB #KATAKANA LETTER NI
+0xA5CC 0x30CC #KATAKANA LETTER NU
+0xA5CD 0x30CD #KATAKANA LETTER NE
+0xA5CE 0x30CE #KATAKANA LETTER NO
+0xA5CF 0x30CF #KATAKANA LETTER HA
+0xA5D0 0x30D0 #KATAKANA LETTER BA
+0xA5D1 0x30D1 #KATAKANA LETTER PA
+0xA5D2 0x30D2 #KATAKANA LETTER HI
+0xA5D3 0x30D3 #KATAKANA LETTER BI
+0xA5D4 0x30D4 #KATAKANA LETTER PI
+0xA5D5 0x30D5 #KATAKANA LETTER HU
+0xA5D6 0x30D6 #KATAKANA LETTER BU
+0xA5D7 0x30D7 #KATAKANA LETTER PU
+0xA5D8 0x30D8 #KATAKANA LETTER HE
+0xA5D9 0x30D9 #KATAKANA LETTER BE
+0xA5DA 0x30DA #KATAKANA LETTER PE
+0xA5DB 0x30DB #KATAKANA LETTER HO
+0xA5DC 0x30DC #KATAKANA LETTER BO
+0xA5DD 0x30DD #KATAKANA LETTER PO
+0xA5DE 0x30DE #KATAKANA LETTER MA
+0xA5DF 0x30DF #KATAKANA LETTER MI
+0xA5E0 0x30E0 #KATAKANA LETTER MU
+0xA5E1 0x30E1 #KATAKANA LETTER ME
+0xA5E2 0x30E2 #KATAKANA LETTER MO
+0xA5E3 0x30E3 #KATAKANA LETTER SMALL YA
+0xA5E4 0x30E4 #KATAKANA LETTER YA
+0xA5E5 0x30E5 #KATAKANA LETTER SMALL YU
+0xA5E6 0x30E6 #KATAKANA LETTER YU
+0xA5E7 0x30E7 #KATAKANA LETTER SMALL YO
+0xA5E8 0x30E8 #KATAKANA LETTER YO
+0xA5E9 0x30E9 #KATAKANA LETTER RA
+0xA5EA 0x30EA #KATAKANA LETTER RI
+0xA5EB 0x30EB #KATAKANA LETTER RU
+0xA5EC 0x30EC #KATAKANA LETTER RE
+0xA5ED 0x30ED #KATAKANA LETTER RO
+0xA5EE 0x30EE #KATAKANA LETTER SMALL WA
+0xA5EF 0x30EF #KATAKANA LETTER WA
+0xA5F0 0x30F0 #KATAKANA LETTER WI
+0xA5F1 0x30F1 #KATAKANA LETTER WE
+0xA5F2 0x30F2 #KATAKANA LETTER WO
+0xA5F3 0x30F3 #KATAKANA LETTER N
+0xA5F4 0x30F4 #KATAKANA LETTER VU
+0xA5F5 0x30F5 #KATAKANA LETTER SMALL KA
+0xA5F6 0x30F6 #KATAKANA LETTER SMALL KE
+0xA6A1 0x0391 #GREEK CAPITAL LETTER ALPHA
+0xA6A2 0x0392 #GREEK CAPITAL LETTER BETA
+0xA6A3 0x0393 #GREEK CAPITAL LETTER GAMMA
+0xA6A4 0x0394 #GREEK CAPITAL LETTER DELTA
+0xA6A5 0x0395 #GREEK CAPITAL LETTER EPSILON
+0xA6A6 0x0396 #GREEK CAPITAL LETTER ZETA
+0xA6A7 0x0397 #GREEK CAPITAL LETTER ETA
+0xA6A8 0x0398 #GREEK CAPITAL LETTER THETA
+0xA6A9 0x0399 #GREEK CAPITAL LETTER IOTA
+0xA6AA 0x039A #GREEK CAPITAL LETTER KAPPA
+0xA6AB 0x039B #GREEK CAPITAL LETTER LAMDA
+0xA6AC 0x039C #GREEK CAPITAL LETTER MU
+0xA6AD 0x039D #GREEK CAPITAL LETTER NU
+0xA6AE 0x039E #GREEK CAPITAL LETTER XI
+0xA6AF 0x039F #GREEK CAPITAL LETTER OMICRON
+0xA6B0 0x03A0 #GREEK CAPITAL LETTER PI
+0xA6B1 0x03A1 #GREEK CAPITAL LETTER RHO
+0xA6B2 0x03A3 #GREEK CAPITAL LETTER SIGMA
+0xA6B3 0x03A4 #GREEK CAPITAL LETTER TAU
+0xA6B4 0x03A5 #GREEK CAPITAL LETTER UPSILON
+0xA6B5 0x03A6 #GREEK CAPITAL LETTER PHI
+0xA6B6 0x03A7 #GREEK CAPITAL LETTER CHI
+0xA6B7 0x03A8 #GREEK CAPITAL LETTER PSI
+0xA6B8 0x03A9 #GREEK CAPITAL LETTER OMEGA
+0xA6C1 0x03B1 #GREEK SMALL LETTER ALPHA
+0xA6C2 0x03B2 #GREEK SMALL LETTER BETA
+0xA6C3 0x03B3 #GREEK SMALL LETTER GAMMA
+0xA6C4 0x03B4 #GREEK SMALL LETTER DELTA
+0xA6C5 0x03B5 #GREEK SMALL LETTER EPSILON
+0xA6C6 0x03B6 #GREEK SMALL LETTER ZETA
+0xA6C7 0x03B7 #GREEK SMALL LETTER ETA
+0xA6C8 0x03B8 #GREEK SMALL LETTER THETA
+0xA6C9 0x03B9 #GREEK SMALL LETTER IOTA
+0xA6CA 0x03BA #GREEK SMALL LETTER KAPPA
+0xA6CB 0x03BB #GREEK SMALL LETTER LAMDA
+0xA6CC 0x03BC #GREEK SMALL LETTER MU
+0xA6CD 0x03BD #GREEK SMALL LETTER NU
+0xA6CE 0x03BE #GREEK SMALL LETTER XI
+0xA6CF 0x03BF #GREEK SMALL LETTER OMICRON
+0xA6D0 0x03C0 #GREEK SMALL LETTER PI
+0xA6D1 0x03C1 #GREEK SMALL LETTER RHO
+0xA6D2 0x03C3 #GREEK SMALL LETTER SIGMA
+0xA6D3 0x03C4 #GREEK SMALL LETTER TAU
+0xA6D4 0x03C5 #GREEK SMALL LETTER UPSILON
+0xA6D5 0x03C6 #GREEK SMALL LETTER PHI
+0xA6D6 0x03C7 #GREEK SMALL LETTER CHI
+0xA6D7 0x03C8 #GREEK SMALL LETTER PSI
+0xA6D8 0x03C9 #GREEK SMALL LETTER OMEGA
+0xA6E0 0xFE35 #PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+0xA6E1 0xFE36 #PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+0xA6E2 0xFE39 #PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+0xA6E3 0xFE3A #PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+0xA6E4 0xFE3F #PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+0xA6E5 0xFE40 #PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+0xA6E6 0xFE3D #PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+0xA6E7 0xFE3E #PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+0xA6E8 0xFE41 #PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+0xA6E9 0xFE42 #PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+0xA6EA 0xFE43 #PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+0xA6EB 0xFE44 #PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+0xA6EE 0xFE3B #PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+0xA6EF 0xFE3C #PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+0xA6F0 0xFE37 #PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+0xA6F1 0xFE38 #PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+0xA6F2 0xFE31 #PRESENTATION FORM FOR VERTICAL EM DASH
+0xA6F4 0xFE33 #PRESENTATION FORM FOR VERTICAL LOW LINE
+0xA6F5 0xFE34 #PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+0xA7A1 0x0410 #CYRILLIC CAPITAL LETTER A
+0xA7A2 0x0411 #CYRILLIC CAPITAL LETTER BE
+0xA7A3 0x0412 #CYRILLIC CAPITAL LETTER VE
+0xA7A4 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0xA7A5 0x0414 #CYRILLIC CAPITAL LETTER DE
+0xA7A6 0x0415 #CYRILLIC CAPITAL LETTER IE
+0xA7A7 0x0401 #CYRILLIC CAPITAL LETTER IO
+0xA7A8 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0xA7A9 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0xA7AA 0x0418 #CYRILLIC CAPITAL LETTER I
+0xA7AB 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0xA7AC 0x041A #CYRILLIC CAPITAL LETTER KA
+0xA7AD 0x041B #CYRILLIC CAPITAL LETTER EL
+0xA7AE 0x041C #CYRILLIC CAPITAL LETTER EM
+0xA7AF 0x041D #CYRILLIC CAPITAL LETTER EN
+0xA7B0 0x041E #CYRILLIC CAPITAL LETTER O
+0xA7B1 0x041F #CYRILLIC CAPITAL LETTER PE
+0xA7B2 0x0420 #CYRILLIC CAPITAL LETTER ER
+0xA7B3 0x0421 #CYRILLIC CAPITAL LETTER ES
+0xA7B4 0x0422 #CYRILLIC CAPITAL LETTER TE
+0xA7B5 0x0423 #CYRILLIC CAPITAL LETTER U
+0xA7B6 0x0424 #CYRILLIC CAPITAL LETTER EF
+0xA7B7 0x0425 #CYRILLIC CAPITAL LETTER HA
+0xA7B8 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0xA7B9 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0xA7BA 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0xA7BB 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0xA7BC 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN
+0xA7BD 0x042B #CYRILLIC CAPITAL LETTER YERU
+0xA7BE 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN
+0xA7BF 0x042D #CYRILLIC CAPITAL LETTER E
+0xA7C0 0x042E #CYRILLIC CAPITAL LETTER YU
+0xA7C1 0x042F #CYRILLIC CAPITAL LETTER YA
+0xA7D1 0x0430 #CYRILLIC SMALL LETTER A
+0xA7D2 0x0431 #CYRILLIC SMALL LETTER BE
+0xA7D3 0x0432 #CYRILLIC SMALL LETTER VE
+0xA7D4 0x0433 #CYRILLIC SMALL LETTER GHE
+0xA7D5 0x0434 #CYRILLIC SMALL LETTER DE
+0xA7D6 0x0435 #CYRILLIC SMALL LETTER IE
+0xA7D7 0x0451 #CYRILLIC SMALL LETTER IO
+0xA7D8 0x0436 #CYRILLIC SMALL LETTER ZHE
+0xA7D9 0x0437 #CYRILLIC SMALL LETTER ZE
+0xA7DA 0x0438 #CYRILLIC SMALL LETTER I
+0xA7DB 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0xA7DC 0x043A #CYRILLIC SMALL LETTER KA
+0xA7DD 0x043B #CYRILLIC SMALL LETTER EL
+0xA7DE 0x043C #CYRILLIC SMALL LETTER EM
+0xA7DF 0x043D #CYRILLIC SMALL LETTER EN
+0xA7E0 0x043E #CYRILLIC SMALL LETTER O
+0xA7E1 0x043F #CYRILLIC SMALL LETTER PE
+0xA7E2 0x0440 #CYRILLIC SMALL LETTER ER
+0xA7E3 0x0441 #CYRILLIC SMALL LETTER ES
+0xA7E4 0x0442 #CYRILLIC SMALL LETTER TE
+0xA7E5 0x0443 #CYRILLIC SMALL LETTER U
+0xA7E6 0x0444 #CYRILLIC SMALL LETTER EF
+0xA7E7 0x0445 #CYRILLIC SMALL LETTER HA
+0xA7E8 0x0446 #CYRILLIC SMALL LETTER TSE
+0xA7E9 0x0447 #CYRILLIC SMALL LETTER CHE
+0xA7EA 0x0448 #CYRILLIC SMALL LETTER SHA
+0xA7EB 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0xA7EC 0x044A #CYRILLIC SMALL LETTER HARD SIGN
+0xA7ED 0x044B #CYRILLIC SMALL LETTER YERU
+0xA7EE 0x044C #CYRILLIC SMALL LETTER SOFT SIGN
+0xA7EF 0x044D #CYRILLIC SMALL LETTER E
+0xA7F0 0x044E #CYRILLIC SMALL LETTER YU
+0xA7F1 0x044F #CYRILLIC SMALL LETTER YA
+0xA840 0x02CA #MODIFIER LETTER ACUTE ACCENT
+0xA841 0x02CB #MODIFIER LETTER GRAVE ACCENT
+0xA842 0x02D9 #DOT ABOVE
+0xA843 0x2013 #EN DASH
+0xA844 0x2015 #HORIZONTAL BAR
+0xA845 0x2025 #TWO DOT LEADER
+0xA846 0x2035 #REVERSED PRIME
+0xA847 0x2105 #CARE OF
+0xA848 0x2109 #DEGREE FAHRENHEIT
+0xA849 0x2196 #NORTH WEST ARROW
+0xA84A 0x2197 #NORTH EAST ARROW
+0xA84B 0x2198 #SOUTH EAST ARROW
+0xA84C 0x2199 #SOUTH WEST ARROW
+0xA84D 0x2215 #DIVISION SLASH
+0xA84E 0x221F #RIGHT ANGLE
+0xA84F 0x2223 #DIVIDES
+0xA850 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA851 0x2266 #LESS-THAN OVER EQUAL TO
+0xA852 0x2267 #GREATER-THAN OVER EQUAL TO
+0xA853 0x22BF #RIGHT TRIANGLE
+0xA854 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xA855 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xA856 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xA857 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xA858 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xA859 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xA85A 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xA85B 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xA85C 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xA85D 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xA85E 0x255A #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xA85F 0x255B #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xA860 0x255C #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xA861 0x255D #BOX DRAWINGS DOUBLE UP AND LEFT
+0xA862 0x255E #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xA863 0x255F #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xA864 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xA865 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xA866 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xA867 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xA868 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xA869 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xA86A 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xA86B 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xA86C 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xA86D 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xA86E 0x256A #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xA86F 0x256B #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xA870 0x256C #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xA871 0x256D #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xA872 0x256E #BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xA873 0x256F #BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xA874 0x2570 #BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xA875 0x2571 #BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+0xA876 0x2572 #BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+0xA877 0x2573 #BOX DRAWINGS LIGHT DIAGONAL CROSS
+0xA878 0x2581 #LOWER ONE EIGHTH BLOCK
+0xA879 0x2582 #LOWER ONE QUARTER BLOCK
+0xA87A 0x2583 #LOWER THREE EIGHTHS BLOCK
+0xA87B 0x2584 #LOWER HALF BLOCK
+0xA87C 0x2585 #LOWER FIVE EIGHTHS BLOCK
+0xA87D 0x2586 #LOWER THREE QUARTERS BLOCK
+0xA87E 0x2587 #LOWER SEVEN EIGHTHS BLOCK
+0xA880 0x2588 #FULL BLOCK
+0xA881 0x2589 #LEFT SEVEN EIGHTHS BLOCK
+0xA882 0x258A #LEFT THREE QUARTERS BLOCK
+0xA883 0x258B #LEFT FIVE EIGHTHS BLOCK
+0xA884 0x258C #LEFT HALF BLOCK
+0xA885 0x258D #LEFT THREE EIGHTHS BLOCK
+0xA886 0x258E #LEFT ONE QUARTER BLOCK
+0xA887 0x258F #LEFT ONE EIGHTH BLOCK
+0xA888 0x2593 #DARK SHADE
+0xA889 0x2594 #UPPER ONE EIGHTH BLOCK
+0xA88A 0x2595 #RIGHT ONE EIGHTH BLOCK
+0xA88B 0x25BC #BLACK DOWN-POINTING TRIANGLE
+0xA88C 0x25BD #WHITE DOWN-POINTING TRIANGLE
+0xA88D 0x25E2 #BLACK LOWER RIGHT TRIANGLE
+0xA88E 0x25E3 #BLACK LOWER LEFT TRIANGLE
+0xA88F 0x25E4 #BLACK UPPER LEFT TRIANGLE
+0xA890 0x25E5 #BLACK UPPER RIGHT TRIANGLE
+0xA891 0x2609 #SUN
+0xA892 0x2295 #CIRCLED PLUS
+0xA893 0x3012 #POSTAL MARK
+0xA894 0x301D #REVERSED DOUBLE PRIME QUOTATION MARK
+0xA895 0x301E #DOUBLE PRIME QUOTATION MARK
+0xA8A1 0x0101 #LATIN SMALL LETTER A WITH MACRON
+0xA8A2 0x00E1 #LATIN SMALL LETTER A WITH ACUTE
+0xA8A3 0x01CE #LATIN SMALL LETTER A WITH CARON
+0xA8A4 0x00E0 #LATIN SMALL LETTER A WITH GRAVE
+0xA8A5 0x0113 #LATIN SMALL LETTER E WITH MACRON
+0xA8A6 0x00E9 #LATIN SMALL LETTER E WITH ACUTE
+0xA8A7 0x011B #LATIN SMALL LETTER E WITH CARON
+0xA8A8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE
+0xA8A9 0x012B #LATIN SMALL LETTER I WITH MACRON
+0xA8AA 0x00ED #LATIN SMALL LETTER I WITH ACUTE
+0xA8AB 0x01D0 #LATIN SMALL LETTER I WITH CARON
+0xA8AC 0x00EC #LATIN SMALL LETTER I WITH GRAVE
+0xA8AD 0x014D #LATIN SMALL LETTER O WITH MACRON
+0xA8AE 0x00F3 #LATIN SMALL LETTER O WITH ACUTE
+0xA8AF 0x01D2 #LATIN SMALL LETTER O WITH CARON
+0xA8B0 0x00F2 #LATIN SMALL LETTER O WITH GRAVE
+0xA8B1 0x016B #LATIN SMALL LETTER U WITH MACRON
+0xA8B2 0x00FA #LATIN SMALL LETTER U WITH ACUTE
+0xA8B3 0x01D4 #LATIN SMALL LETTER U WITH CARON
+0xA8B4 0x00F9 #LATIN SMALL LETTER U WITH GRAVE
+0xA8B5 0x01D6 #LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0xA8B6 0x01D8 #LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0xA8B7 0x01DA #LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0xA8B8 0x01DC #LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0xA8B9 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS
+0xA8BA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xA8BB 0x0251 #LATIN SMALL LETTER ALPHA
+0xA8BD 0x0144 #LATIN SMALL LETTER N WITH ACUTE
+0xA8BE 0x0148 #LATIN SMALL LETTER N WITH CARON
+0xA8C0 0x0261 #LATIN SMALL LETTER SCRIPT G
+0xA8C5 0x3105 #BOPOMOFO LETTER B
+0xA8C6 0x3106 #BOPOMOFO LETTER P
+0xA8C7 0x3107 #BOPOMOFO LETTER M
+0xA8C8 0x3108 #BOPOMOFO LETTER F
+0xA8C9 0x3109 #BOPOMOFO LETTER D
+0xA8CA 0x310A #BOPOMOFO LETTER T
+0xA8CB 0x310B #BOPOMOFO LETTER N
+0xA8CC 0x310C #BOPOMOFO LETTER L
+0xA8CD 0x310D #BOPOMOFO LETTER G
+0xA8CE 0x310E #BOPOMOFO LETTER K
+0xA8CF 0x310F #BOPOMOFO LETTER H
+0xA8D0 0x3110 #BOPOMOFO LETTER J
+0xA8D1 0x3111 #BOPOMOFO LETTER Q
+0xA8D2 0x3112 #BOPOMOFO LETTER X
+0xA8D3 0x3113 #BOPOMOFO LETTER ZH
+0xA8D4 0x3114 #BOPOMOFO LETTER CH
+0xA8D5 0x3115 #BOPOMOFO LETTER SH
+0xA8D6 0x3116 #BOPOMOFO LETTER R
+0xA8D7 0x3117 #BOPOMOFO LETTER Z
+0xA8D8 0x3118 #BOPOMOFO LETTER C
+0xA8D9 0x3119 #BOPOMOFO LETTER S
+0xA8DA 0x311A #BOPOMOFO LETTER A
+0xA8DB 0x311B #BOPOMOFO LETTER O
+0xA8DC 0x311C #BOPOMOFO LETTER E
+0xA8DD 0x311D #BOPOMOFO LETTER EH
+0xA8DE 0x311E #BOPOMOFO LETTER AI
+0xA8DF 0x311F #BOPOMOFO LETTER EI
+0xA8E0 0x3120 #BOPOMOFO LETTER AU
+0xA8E1 0x3121 #BOPOMOFO LETTER OU
+0xA8E2 0x3122 #BOPOMOFO LETTER AN
+0xA8E3 0x3123 #BOPOMOFO LETTER EN
+0xA8E4 0x3124 #BOPOMOFO LETTER ANG
+0xA8E5 0x3125 #BOPOMOFO LETTER ENG
+0xA8E6 0x3126 #BOPOMOFO LETTER ER
+0xA8E7 0x3127 #BOPOMOFO LETTER I
+0xA8E8 0x3128 #BOPOMOFO LETTER U
+0xA8E9 0x3129 #BOPOMOFO LETTER IU
+0xA940 0x3021 #HANGZHOU NUMERAL ONE
+0xA941 0x3022 #HANGZHOU NUMERAL TWO
+0xA942 0x3023 #HANGZHOU NUMERAL THREE
+0xA943 0x3024 #HANGZHOU NUMERAL FOUR
+0xA944 0x3025 #HANGZHOU NUMERAL FIVE
+0xA945 0x3026 #HANGZHOU NUMERAL SIX
+0xA946 0x3027 #HANGZHOU NUMERAL SEVEN
+0xA947 0x3028 #HANGZHOU NUMERAL EIGHT
+0xA948 0x3029 #HANGZHOU NUMERAL NINE
+0xA949 0x32A3 #CIRCLED IDEOGRAPH CORRECT
+0xA94A 0x338E #SQUARE MG
+0xA94B 0x338F #SQUARE KG
+0xA94C 0x339C #SQUARE MM
+0xA94D 0x339D #SQUARE CM
+0xA94E 0x339E #SQUARE KM
+0xA94F 0x33A1 #SQUARE M SQUARED
+0xA950 0x33C4 #SQUARE CC
+0xA951 0x33CE #SQUARE KM CAPITAL
+0xA952 0x33D1 #SQUARE LN
+0xA953 0x33D2 #SQUARE LOG
+0xA954 0x33D5 #SQUARE MIL
+0xA955 0xFE30 #PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+0xA956 0xFFE2 #FULLWIDTH NOT SIGN
+0xA957 0xFFE4 #FULLWIDTH BROKEN BAR
+0xA959 0x2121 #TELEPHONE SIGN
+0xA95A 0x3231 #PARENTHESIZED IDEOGRAPH STOCK
+0xA95C 0x2010 #HYPHEN
+0xA960 0x30FC #KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xA961 0x309B #KATAKANA-HIRAGANA VOICED SOUND MARK
+0xA962 0x309C #KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0xA963 0x30FD #KATAKANA ITERATION MARK
+0xA964 0x30FE #KATAKANA VOICED ITERATION MARK
+0xA965 0x3006 #IDEOGRAPHIC CLOSING MARK
+0xA966 0x309D #HIRAGANA ITERATION MARK
+0xA967 0x309E #HIRAGANA VOICED ITERATION MARK
+0xA968 0xFE49 #DASHED OVERLINE
+0xA969 0xFE4A #CENTRELINE OVERLINE
+0xA96A 0xFE4B #WAVY OVERLINE
+0xA96B 0xFE4C #DOUBLE WAVY OVERLINE
+0xA96C 0xFE4D #DASHED LOW LINE
+0xA96D 0xFE4E #CENTRELINE LOW LINE
+0xA96E 0xFE4F #WAVY LOW LINE
+0xA96F 0xFE50 #SMALL COMMA
+0xA970 0xFE51 #SMALL IDEOGRAPHIC COMMA
+0xA971 0xFE52 #SMALL FULL STOP
+0xA972 0xFE54 #SMALL SEMICOLON
+0xA973 0xFE55 #SMALL COLON
+0xA974 0xFE56 #SMALL QUESTION MARK
+0xA975 0xFE57 #SMALL EXCLAMATION MARK
+0xA976 0xFE59 #SMALL LEFT PARENTHESIS
+0xA977 0xFE5A #SMALL RIGHT PARENTHESIS
+0xA978 0xFE5B #SMALL LEFT CURLY BRACKET
+0xA979 0xFE5C #SMALL RIGHT CURLY BRACKET
+0xA97A 0xFE5D #SMALL LEFT TORTOISE SHELL BRACKET
+0xA97B 0xFE5E #SMALL RIGHT TORTOISE SHELL BRACKET
+0xA97C 0xFE5F #SMALL NUMBER SIGN
+0xA97D 0xFE60 #SMALL AMPERSAND
+0xA97E 0xFE61 #SMALL ASTERISK
+0xA980 0xFE62 #SMALL PLUS SIGN
+0xA981 0xFE63 #SMALL HYPHEN-MINUS
+0xA982 0xFE64 #SMALL LESS-THAN SIGN
+0xA983 0xFE65 #SMALL GREATER-THAN SIGN
+0xA984 0xFE66 #SMALL EQUALS SIGN
+0xA985 0xFE68 #SMALL REVERSE SOLIDUS
+0xA986 0xFE69 #SMALL DOLLAR SIGN
+0xA987 0xFE6A #SMALL PERCENT SIGN
+0xA988 0xFE6B #SMALL COMMERCIAL AT
+0xA996 0x3007 #IDEOGRAPHIC NUMBER ZERO
+0xA9A4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xA9A5 0x2501 #BOX DRAWINGS HEAVY HORIZONTAL
+0xA9A6 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xA9A7 0x2503 #BOX DRAWINGS HEAVY VERTICAL
+0xA9A8 0x2504 #BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+0xA9A9 0x2505 #BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
+0xA9AA 0x2506 #BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
+0xA9AB 0x2507 #BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
+0xA9AC 0x2508 #BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
+0xA9AD 0x2509 #BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
+0xA9AE 0x250A #BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+0xA9AF 0x250B #BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+0xA9B0 0x250C #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA9B1 0x250D #BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0xA9B2 0x250E #BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0xA9B3 0x250F #BOX DRAWINGS HEAVY DOWN AND RIGHT
+0xA9B4 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA9B5 0x2511 #BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0xA9B6 0x2512 #BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0xA9B7 0x2513 #BOX DRAWINGS HEAVY DOWN AND LEFT
+0xA9B8 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xA9B9 0x2515 #BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0xA9BA 0x2516 #BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0xA9BB 0x2517 #BOX DRAWINGS HEAVY UP AND RIGHT
+0xA9BC 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xA9BD 0x2519 #BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0xA9BE 0x251A #BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0xA9BF 0x251B #BOX DRAWINGS HEAVY UP AND LEFT
+0xA9C0 0x251C #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA9C1 0x251D #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0xA9C2 0x251E #BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0xA9C3 0x251F #BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0xA9C4 0x2520 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0xA9C5 0x2521 #BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0xA9C6 0x2522 #BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0xA9C7 0x2523 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0xA9C8 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA9C9 0x2525 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0xA9CA 0x2526 #BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0xA9CB 0x2527 #BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0xA9CC 0x2528 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0xA9CD 0x2529 #BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0xA9CE 0x252A #BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0xA9CF 0x252B #BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0xA9D0 0x252C #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA9D1 0x252D #BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0xA9D2 0x252E #BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0xA9D3 0x252F #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0xA9D4 0x2530 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0xA9D5 0x2531 #BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0xA9D6 0x2532 #BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0xA9D7 0x2533 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0xA9D8 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA9D9 0x2535 #BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0xA9DA 0x2536 #BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0xA9DB 0x2537 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0xA9DC 0x2538 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0xA9DD 0x2539 #BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0xA9DE 0x253A #BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0xA9DF 0x253B #BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0xA9E0 0x253C #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA9E1 0x253D #BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0xA9E2 0x253E #BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0xA9E3 0x253F #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0xA9E4 0x2540 #BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0xA9E5 0x2541 #BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0xA9E6 0x2542 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0xA9E7 0x2543 #BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0xA9E8 0x2544 #BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0xA9E9 0x2545 #BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0xA9EA 0x2546 #BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0xA9EB 0x2547 #BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0xA9EC 0x2548 #BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0xA9ED 0x2549 #BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0xA9EE 0x254A #BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0xA9EF 0x254B #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0xAA40 0x72DC #CJK UNIFIED IDEOGRAPH
+0xAA41 0x72DD #CJK UNIFIED IDEOGRAPH
+0xAA42 0x72DF #CJK UNIFIED IDEOGRAPH
+0xAA43 0x72E2 #CJK UNIFIED IDEOGRAPH
+0xAA44 0x72E3 #CJK UNIFIED IDEOGRAPH
+0xAA45 0x72E4 #CJK UNIFIED IDEOGRAPH
+0xAA46 0x72E5 #CJK UNIFIED IDEOGRAPH
+0xAA47 0x72E6 #CJK UNIFIED IDEOGRAPH
+0xAA48 0x72E7 #CJK UNIFIED IDEOGRAPH
+0xAA49 0x72EA #CJK UNIFIED IDEOGRAPH
+0xAA4A 0x72EB #CJK UNIFIED IDEOGRAPH
+0xAA4B 0x72F5 #CJK UNIFIED IDEOGRAPH
+0xAA4C 0x72F6 #CJK UNIFIED IDEOGRAPH
+0xAA4D 0x72F9 #CJK UNIFIED IDEOGRAPH
+0xAA4E 0x72FD #CJK UNIFIED IDEOGRAPH
+0xAA4F 0x72FE #CJK UNIFIED IDEOGRAPH
+0xAA50 0x72FF #CJK UNIFIED IDEOGRAPH
+0xAA51 0x7300 #CJK UNIFIED IDEOGRAPH
+0xAA52 0x7302 #CJK UNIFIED IDEOGRAPH
+0xAA53 0x7304 #CJK UNIFIED IDEOGRAPH
+0xAA54 0x7305 #CJK UNIFIED IDEOGRAPH
+0xAA55 0x7306 #CJK UNIFIED IDEOGRAPH
+0xAA56 0x7307 #CJK UNIFIED IDEOGRAPH
+0xAA57 0x7308 #CJK UNIFIED IDEOGRAPH
+0xAA58 0x7309 #CJK UNIFIED IDEOGRAPH
+0xAA59 0x730B #CJK UNIFIED IDEOGRAPH
+0xAA5A 0x730C #CJK UNIFIED IDEOGRAPH
+0xAA5B 0x730D #CJK UNIFIED IDEOGRAPH
+0xAA5C 0x730F #CJK UNIFIED IDEOGRAPH
+0xAA5D 0x7310 #CJK UNIFIED IDEOGRAPH
+0xAA5E 0x7311 #CJK UNIFIED IDEOGRAPH
+0xAA5F 0x7312 #CJK UNIFIED IDEOGRAPH
+0xAA60 0x7314 #CJK UNIFIED IDEOGRAPH
+0xAA61 0x7318 #CJK UNIFIED IDEOGRAPH
+0xAA62 0x7319 #CJK UNIFIED IDEOGRAPH
+0xAA63 0x731A #CJK UNIFIED IDEOGRAPH
+0xAA64 0x731F #CJK UNIFIED IDEOGRAPH
+0xAA65 0x7320 #CJK UNIFIED IDEOGRAPH
+0xAA66 0x7323 #CJK UNIFIED IDEOGRAPH
+0xAA67 0x7324 #CJK UNIFIED IDEOGRAPH
+0xAA68 0x7326 #CJK UNIFIED IDEOGRAPH
+0xAA69 0x7327 #CJK UNIFIED IDEOGRAPH
+0xAA6A 0x7328 #CJK UNIFIED IDEOGRAPH
+0xAA6B 0x732D #CJK UNIFIED IDEOGRAPH
+0xAA6C 0x732F #CJK UNIFIED IDEOGRAPH
+0xAA6D 0x7330 #CJK UNIFIED IDEOGRAPH
+0xAA6E 0x7332 #CJK UNIFIED IDEOGRAPH
+0xAA6F 0x7333 #CJK UNIFIED IDEOGRAPH
+0xAA70 0x7335 #CJK UNIFIED IDEOGRAPH
+0xAA71 0x7336 #CJK UNIFIED IDEOGRAPH
+0xAA72 0x733A #CJK UNIFIED IDEOGRAPH
+0xAA73 0x733B #CJK UNIFIED IDEOGRAPH
+0xAA74 0x733C #CJK UNIFIED IDEOGRAPH
+0xAA75 0x733D #CJK UNIFIED IDEOGRAPH
+0xAA76 0x7340 #CJK UNIFIED IDEOGRAPH
+0xAA77 0x7341 #CJK UNIFIED IDEOGRAPH
+0xAA78 0x7342 #CJK UNIFIED IDEOGRAPH
+0xAA79 0x7343 #CJK UNIFIED IDEOGRAPH
+0xAA7A 0x7344 #CJK UNIFIED IDEOGRAPH
+0xAA7B 0x7345 #CJK UNIFIED IDEOGRAPH
+0xAA7C 0x7346 #CJK UNIFIED IDEOGRAPH
+0xAA7D 0x7347 #CJK UNIFIED IDEOGRAPH
+0xAA7E 0x7348 #CJK UNIFIED IDEOGRAPH
+0xAA80 0x7349 #CJK UNIFIED IDEOGRAPH
+0xAA81 0x734A #CJK UNIFIED IDEOGRAPH
+0xAA82 0x734B #CJK UNIFIED IDEOGRAPH
+0xAA83 0x734C #CJK UNIFIED IDEOGRAPH
+0xAA84 0x734E #CJK UNIFIED IDEOGRAPH
+0xAA85 0x734F #CJK UNIFIED IDEOGRAPH
+0xAA86 0x7351 #CJK UNIFIED IDEOGRAPH
+0xAA87 0x7353 #CJK UNIFIED IDEOGRAPH
+0xAA88 0x7354 #CJK UNIFIED IDEOGRAPH
+0xAA89 0x7355 #CJK UNIFIED IDEOGRAPH
+0xAA8A 0x7356 #CJK UNIFIED IDEOGRAPH
+0xAA8B 0x7358 #CJK UNIFIED IDEOGRAPH
+0xAA8C 0x7359 #CJK UNIFIED IDEOGRAPH
+0xAA8D 0x735A #CJK UNIFIED IDEOGRAPH
+0xAA8E 0x735B #CJK UNIFIED IDEOGRAPH
+0xAA8F 0x735C #CJK UNIFIED IDEOGRAPH
+0xAA90 0x735D #CJK UNIFIED IDEOGRAPH
+0xAA91 0x735E #CJK UNIFIED IDEOGRAPH
+0xAA92 0x735F #CJK UNIFIED IDEOGRAPH
+0xAA93 0x7361 #CJK UNIFIED IDEOGRAPH
+0xAA94 0x7362 #CJK UNIFIED IDEOGRAPH
+0xAA95 0x7363 #CJK UNIFIED IDEOGRAPH
+0xAA96 0x7364 #CJK UNIFIED IDEOGRAPH
+0xAA97 0x7365 #CJK UNIFIED IDEOGRAPH
+0xAA98 0x7366 #CJK UNIFIED IDEOGRAPH
+0xAA99 0x7367 #CJK UNIFIED IDEOGRAPH
+0xAA9A 0x7368 #CJK UNIFIED IDEOGRAPH
+0xAA9B 0x7369 #CJK UNIFIED IDEOGRAPH
+0xAA9C 0x736A #CJK UNIFIED IDEOGRAPH
+0xAA9D 0x736B #CJK UNIFIED IDEOGRAPH
+0xAA9E 0x736E #CJK UNIFIED IDEOGRAPH
+0xAA9F 0x7370 #CJK UNIFIED IDEOGRAPH
+0xAAA0 0x7371 #CJK UNIFIED IDEOGRAPH
+0xAB40 0x7372 #CJK UNIFIED IDEOGRAPH
+0xAB41 0x7373 #CJK UNIFIED IDEOGRAPH
+0xAB42 0x7374 #CJK UNIFIED IDEOGRAPH
+0xAB43 0x7375 #CJK UNIFIED IDEOGRAPH
+0xAB44 0x7376 #CJK UNIFIED IDEOGRAPH
+0xAB45 0x7377 #CJK UNIFIED IDEOGRAPH
+0xAB46 0x7378 #CJK UNIFIED IDEOGRAPH
+0xAB47 0x7379 #CJK UNIFIED IDEOGRAPH
+0xAB48 0x737A #CJK UNIFIED IDEOGRAPH
+0xAB49 0x737B #CJK UNIFIED IDEOGRAPH
+0xAB4A 0x737C #CJK UNIFIED IDEOGRAPH
+0xAB4B 0x737D #CJK UNIFIED IDEOGRAPH
+0xAB4C 0x737F #CJK UNIFIED IDEOGRAPH
+0xAB4D 0x7380 #CJK UNIFIED IDEOGRAPH
+0xAB4E 0x7381 #CJK UNIFIED IDEOGRAPH
+0xAB4F 0x7382 #CJK UNIFIED IDEOGRAPH
+0xAB50 0x7383 #CJK UNIFIED IDEOGRAPH
+0xAB51 0x7385 #CJK UNIFIED IDEOGRAPH
+0xAB52 0x7386 #CJK UNIFIED IDEOGRAPH
+0xAB53 0x7388 #CJK UNIFIED IDEOGRAPH
+0xAB54 0x738A #CJK UNIFIED IDEOGRAPH
+0xAB55 0x738C #CJK UNIFIED IDEOGRAPH
+0xAB56 0x738D #CJK UNIFIED IDEOGRAPH
+0xAB57 0x738F #CJK UNIFIED IDEOGRAPH
+0xAB58 0x7390 #CJK UNIFIED IDEOGRAPH
+0xAB59 0x7392 #CJK UNIFIED IDEOGRAPH
+0xAB5A 0x7393 #CJK UNIFIED IDEOGRAPH
+0xAB5B 0x7394 #CJK UNIFIED IDEOGRAPH
+0xAB5C 0x7395 #CJK UNIFIED IDEOGRAPH
+0xAB5D 0x7397 #CJK UNIFIED IDEOGRAPH
+0xAB5E 0x7398 #CJK UNIFIED IDEOGRAPH
+0xAB5F 0x7399 #CJK UNIFIED IDEOGRAPH
+0xAB60 0x739A #CJK UNIFIED IDEOGRAPH
+0xAB61 0x739C #CJK UNIFIED IDEOGRAPH
+0xAB62 0x739D #CJK UNIFIED IDEOGRAPH
+0xAB63 0x739E #CJK UNIFIED IDEOGRAPH
+0xAB64 0x73A0 #CJK UNIFIED IDEOGRAPH
+0xAB65 0x73A1 #CJK UNIFIED IDEOGRAPH
+0xAB66 0x73A3 #CJK UNIFIED IDEOGRAPH
+0xAB67 0x73A4 #CJK UNIFIED IDEOGRAPH
+0xAB68 0x73A5 #CJK UNIFIED IDEOGRAPH
+0xAB69 0x73A6 #CJK UNIFIED IDEOGRAPH
+0xAB6A 0x73A7 #CJK UNIFIED IDEOGRAPH
+0xAB6B 0x73A8 #CJK UNIFIED IDEOGRAPH
+0xAB6C 0x73AA #CJK UNIFIED IDEOGRAPH
+0xAB6D 0x73AC #CJK UNIFIED IDEOGRAPH
+0xAB6E 0x73AD #CJK UNIFIED IDEOGRAPH
+0xAB6F 0x73B1 #CJK UNIFIED IDEOGRAPH
+0xAB70 0x73B4 #CJK UNIFIED IDEOGRAPH
+0xAB71 0x73B5 #CJK UNIFIED IDEOGRAPH
+0xAB72 0x73B6 #CJK UNIFIED IDEOGRAPH
+0xAB73 0x73B8 #CJK UNIFIED IDEOGRAPH
+0xAB74 0x73B9 #CJK UNIFIED IDEOGRAPH
+0xAB75 0x73BC #CJK UNIFIED IDEOGRAPH
+0xAB76 0x73BD #CJK UNIFIED IDEOGRAPH
+0xAB77 0x73BE #CJK UNIFIED IDEOGRAPH
+0xAB78 0x73BF #CJK UNIFIED IDEOGRAPH
+0xAB79 0x73C1 #CJK UNIFIED IDEOGRAPH
+0xAB7A 0x73C3 #CJK UNIFIED IDEOGRAPH
+0xAB7B 0x73C4 #CJK UNIFIED IDEOGRAPH
+0xAB7C 0x73C5 #CJK UNIFIED IDEOGRAPH
+0xAB7D 0x73C6 #CJK UNIFIED IDEOGRAPH
+0xAB7E 0x73C7 #CJK UNIFIED IDEOGRAPH
+0xAB80 0x73CB #CJK UNIFIED IDEOGRAPH
+0xAB81 0x73CC #CJK UNIFIED IDEOGRAPH
+0xAB82 0x73CE #CJK UNIFIED IDEOGRAPH
+0xAB83 0x73D2 #CJK UNIFIED IDEOGRAPH
+0xAB84 0x73D3 #CJK UNIFIED IDEOGRAPH
+0xAB85 0x73D4 #CJK UNIFIED IDEOGRAPH
+0xAB86 0x73D5 #CJK UNIFIED IDEOGRAPH
+0xAB87 0x73D6 #CJK UNIFIED IDEOGRAPH
+0xAB88 0x73D7 #CJK UNIFIED IDEOGRAPH
+0xAB89 0x73D8 #CJK UNIFIED IDEOGRAPH
+0xAB8A 0x73DA #CJK UNIFIED IDEOGRAPH
+0xAB8B 0x73DB #CJK UNIFIED IDEOGRAPH
+0xAB8C 0x73DC #CJK UNIFIED IDEOGRAPH
+0xAB8D 0x73DD #CJK UNIFIED IDEOGRAPH
+0xAB8E 0x73DF #CJK UNIFIED IDEOGRAPH
+0xAB8F 0x73E1 #CJK UNIFIED IDEOGRAPH
+0xAB90 0x73E2 #CJK UNIFIED IDEOGRAPH
+0xAB91 0x73E3 #CJK UNIFIED IDEOGRAPH
+0xAB92 0x73E4 #CJK UNIFIED IDEOGRAPH
+0xAB93 0x73E6 #CJK UNIFIED IDEOGRAPH
+0xAB94 0x73E8 #CJK UNIFIED IDEOGRAPH
+0xAB95 0x73EA #CJK UNIFIED IDEOGRAPH
+0xAB96 0x73EB #CJK UNIFIED IDEOGRAPH
+0xAB97 0x73EC #CJK UNIFIED IDEOGRAPH
+0xAB98 0x73EE #CJK UNIFIED IDEOGRAPH
+0xAB99 0x73EF #CJK UNIFIED IDEOGRAPH
+0xAB9A 0x73F0 #CJK UNIFIED IDEOGRAPH
+0xAB9B 0x73F1 #CJK UNIFIED IDEOGRAPH
+0xAB9C 0x73F3 #CJK UNIFIED IDEOGRAPH
+0xAB9D 0x73F4 #CJK UNIFIED IDEOGRAPH
+0xAB9E 0x73F5 #CJK UNIFIED IDEOGRAPH
+0xAB9F 0x73F6 #CJK UNIFIED IDEOGRAPH
+0xABA0 0x73F7 #CJK UNIFIED IDEOGRAPH
+0xAC40 0x73F8 #CJK UNIFIED IDEOGRAPH
+0xAC41 0x73F9 #CJK UNIFIED IDEOGRAPH
+0xAC42 0x73FA #CJK UNIFIED IDEOGRAPH
+0xAC43 0x73FB #CJK UNIFIED IDEOGRAPH
+0xAC44 0x73FC #CJK UNIFIED IDEOGRAPH
+0xAC45 0x73FD #CJK UNIFIED IDEOGRAPH
+0xAC46 0x73FE #CJK UNIFIED IDEOGRAPH
+0xAC47 0x73FF #CJK UNIFIED IDEOGRAPH
+0xAC48 0x7400 #CJK UNIFIED IDEOGRAPH
+0xAC49 0x7401 #CJK UNIFIED IDEOGRAPH
+0xAC4A 0x7402 #CJK UNIFIED IDEOGRAPH
+0xAC4B 0x7404 #CJK UNIFIED IDEOGRAPH
+0xAC4C 0x7407 #CJK UNIFIED IDEOGRAPH
+0xAC4D 0x7408 #CJK UNIFIED IDEOGRAPH
+0xAC4E 0x740B #CJK UNIFIED IDEOGRAPH
+0xAC4F 0x740C #CJK UNIFIED IDEOGRAPH
+0xAC50 0x740D #CJK UNIFIED IDEOGRAPH
+0xAC51 0x740E #CJK UNIFIED IDEOGRAPH
+0xAC52 0x7411 #CJK UNIFIED IDEOGRAPH
+0xAC53 0x7412 #CJK UNIFIED IDEOGRAPH
+0xAC54 0x7413 #CJK UNIFIED IDEOGRAPH
+0xAC55 0x7414 #CJK UNIFIED IDEOGRAPH
+0xAC56 0x7415 #CJK UNIFIED IDEOGRAPH
+0xAC57 0x7416 #CJK UNIFIED IDEOGRAPH
+0xAC58 0x7417 #CJK UNIFIED IDEOGRAPH
+0xAC59 0x7418 #CJK UNIFIED IDEOGRAPH
+0xAC5A 0x7419 #CJK UNIFIED IDEOGRAPH
+0xAC5B 0x741C #CJK UNIFIED IDEOGRAPH
+0xAC5C 0x741D #CJK UNIFIED IDEOGRAPH
+0xAC5D 0x741E #CJK UNIFIED IDEOGRAPH
+0xAC5E 0x741F #CJK UNIFIED IDEOGRAPH
+0xAC5F 0x7420 #CJK UNIFIED IDEOGRAPH
+0xAC60 0x7421 #CJK UNIFIED IDEOGRAPH
+0xAC61 0x7423 #CJK UNIFIED IDEOGRAPH
+0xAC62 0x7424 #CJK UNIFIED IDEOGRAPH
+0xAC63 0x7427 #CJK UNIFIED IDEOGRAPH
+0xAC64 0x7429 #CJK UNIFIED IDEOGRAPH
+0xAC65 0x742B #CJK UNIFIED IDEOGRAPH
+0xAC66 0x742D #CJK UNIFIED IDEOGRAPH
+0xAC67 0x742F #CJK UNIFIED IDEOGRAPH
+0xAC68 0x7431 #CJK UNIFIED IDEOGRAPH
+0xAC69 0x7432 #CJK UNIFIED IDEOGRAPH
+0xAC6A 0x7437 #CJK UNIFIED IDEOGRAPH
+0xAC6B 0x7438 #CJK UNIFIED IDEOGRAPH
+0xAC6C 0x7439 #CJK UNIFIED IDEOGRAPH
+0xAC6D 0x743A #CJK UNIFIED IDEOGRAPH
+0xAC6E 0x743B #CJK UNIFIED IDEOGRAPH
+0xAC6F 0x743D #CJK UNIFIED IDEOGRAPH
+0xAC70 0x743E #CJK UNIFIED IDEOGRAPH
+0xAC71 0x743F #CJK UNIFIED IDEOGRAPH
+0xAC72 0x7440 #CJK UNIFIED IDEOGRAPH
+0xAC73 0x7442 #CJK UNIFIED IDEOGRAPH
+0xAC74 0x7443 #CJK UNIFIED IDEOGRAPH
+0xAC75 0x7444 #CJK UNIFIED IDEOGRAPH
+0xAC76 0x7445 #CJK UNIFIED IDEOGRAPH
+0xAC77 0x7446 #CJK UNIFIED IDEOGRAPH
+0xAC78 0x7447 #CJK UNIFIED IDEOGRAPH
+0xAC79 0x7448 #CJK UNIFIED IDEOGRAPH
+0xAC7A 0x7449 #CJK UNIFIED IDEOGRAPH
+0xAC7B 0x744A #CJK UNIFIED IDEOGRAPH
+0xAC7C 0x744B #CJK UNIFIED IDEOGRAPH
+0xAC7D 0x744C #CJK UNIFIED IDEOGRAPH
+0xAC7E 0x744D #CJK UNIFIED IDEOGRAPH
+0xAC80 0x744E #CJK UNIFIED IDEOGRAPH
+0xAC81 0x744F #CJK UNIFIED IDEOGRAPH
+0xAC82 0x7450 #CJK UNIFIED IDEOGRAPH
+0xAC83 0x7451 #CJK UNIFIED IDEOGRAPH
+0xAC84 0x7452 #CJK UNIFIED IDEOGRAPH
+0xAC85 0x7453 #CJK UNIFIED IDEOGRAPH
+0xAC86 0x7454 #CJK UNIFIED IDEOGRAPH
+0xAC87 0x7456 #CJK UNIFIED IDEOGRAPH
+0xAC88 0x7458 #CJK UNIFIED IDEOGRAPH
+0xAC89 0x745D #CJK UNIFIED IDEOGRAPH
+0xAC8A 0x7460 #CJK UNIFIED IDEOGRAPH
+0xAC8B 0x7461 #CJK UNIFIED IDEOGRAPH
+0xAC8C 0x7462 #CJK UNIFIED IDEOGRAPH
+0xAC8D 0x7463 #CJK UNIFIED IDEOGRAPH
+0xAC8E 0x7464 #CJK UNIFIED IDEOGRAPH
+0xAC8F 0x7465 #CJK UNIFIED IDEOGRAPH
+0xAC90 0x7466 #CJK UNIFIED IDEOGRAPH
+0xAC91 0x7467 #CJK UNIFIED IDEOGRAPH
+0xAC92 0x7468 #CJK UNIFIED IDEOGRAPH
+0xAC93 0x7469 #CJK UNIFIED IDEOGRAPH
+0xAC94 0x746A #CJK UNIFIED IDEOGRAPH
+0xAC95 0x746B #CJK UNIFIED IDEOGRAPH
+0xAC96 0x746C #CJK UNIFIED IDEOGRAPH
+0xAC97 0x746E #CJK UNIFIED IDEOGRAPH
+0xAC98 0x746F #CJK UNIFIED IDEOGRAPH
+0xAC99 0x7471 #CJK UNIFIED IDEOGRAPH
+0xAC9A 0x7472 #CJK UNIFIED IDEOGRAPH
+0xAC9B 0x7473 #CJK UNIFIED IDEOGRAPH
+0xAC9C 0x7474 #CJK UNIFIED IDEOGRAPH
+0xAC9D 0x7475 #CJK UNIFIED IDEOGRAPH
+0xAC9E 0x7478 #CJK UNIFIED IDEOGRAPH
+0xAC9F 0x7479 #CJK UNIFIED IDEOGRAPH
+0xACA0 0x747A #CJK UNIFIED IDEOGRAPH
+0xAD40 0x747B #CJK UNIFIED IDEOGRAPH
+0xAD41 0x747C #CJK UNIFIED IDEOGRAPH
+0xAD42 0x747D #CJK UNIFIED IDEOGRAPH
+0xAD43 0x747F #CJK UNIFIED IDEOGRAPH
+0xAD44 0x7482 #CJK UNIFIED IDEOGRAPH
+0xAD45 0x7484 #CJK UNIFIED IDEOGRAPH
+0xAD46 0x7485 #CJK UNIFIED IDEOGRAPH
+0xAD47 0x7486 #CJK UNIFIED IDEOGRAPH
+0xAD48 0x7488 #CJK UNIFIED IDEOGRAPH
+0xAD49 0x7489 #CJK UNIFIED IDEOGRAPH
+0xAD4A 0x748A #CJK UNIFIED IDEOGRAPH
+0xAD4B 0x748C #CJK UNIFIED IDEOGRAPH
+0xAD4C 0x748D #CJK UNIFIED IDEOGRAPH
+0xAD4D 0x748F #CJK UNIFIED IDEOGRAPH
+0xAD4E 0x7491 #CJK UNIFIED IDEOGRAPH
+0xAD4F 0x7492 #CJK UNIFIED IDEOGRAPH
+0xAD50 0x7493 #CJK UNIFIED IDEOGRAPH
+0xAD51 0x7494 #CJK UNIFIED IDEOGRAPH
+0xAD52 0x7495 #CJK UNIFIED IDEOGRAPH
+0xAD53 0x7496 #CJK UNIFIED IDEOGRAPH
+0xAD54 0x7497 #CJK UNIFIED IDEOGRAPH
+0xAD55 0x7498 #CJK UNIFIED IDEOGRAPH
+0xAD56 0x7499 #CJK UNIFIED IDEOGRAPH
+0xAD57 0x749A #CJK UNIFIED IDEOGRAPH
+0xAD58 0x749B #CJK UNIFIED IDEOGRAPH
+0xAD59 0x749D #CJK UNIFIED IDEOGRAPH
+0xAD5A 0x749F #CJK UNIFIED IDEOGRAPH
+0xAD5B 0x74A0 #CJK UNIFIED IDEOGRAPH
+0xAD5C 0x74A1 #CJK UNIFIED IDEOGRAPH
+0xAD5D 0x74A2 #CJK UNIFIED IDEOGRAPH
+0xAD5E 0x74A3 #CJK UNIFIED IDEOGRAPH
+0xAD5F 0x74A4 #CJK UNIFIED IDEOGRAPH
+0xAD60 0x74A5 #CJK UNIFIED IDEOGRAPH
+0xAD61 0x74A6 #CJK UNIFIED IDEOGRAPH
+0xAD62 0x74AA #CJK UNIFIED IDEOGRAPH
+0xAD63 0x74AB #CJK UNIFIED IDEOGRAPH
+0xAD64 0x74AC #CJK UNIFIED IDEOGRAPH
+0xAD65 0x74AD #CJK UNIFIED IDEOGRAPH
+0xAD66 0x74AE #CJK UNIFIED IDEOGRAPH
+0xAD67 0x74AF #CJK UNIFIED IDEOGRAPH
+0xAD68 0x74B0 #CJK UNIFIED IDEOGRAPH
+0xAD69 0x74B1 #CJK UNIFIED IDEOGRAPH
+0xAD6A 0x74B2 #CJK UNIFIED IDEOGRAPH
+0xAD6B 0x74B3 #CJK UNIFIED IDEOGRAPH
+0xAD6C 0x74B4 #CJK UNIFIED IDEOGRAPH
+0xAD6D 0x74B5 #CJK UNIFIED IDEOGRAPH
+0xAD6E 0x74B6 #CJK UNIFIED IDEOGRAPH
+0xAD6F 0x74B7 #CJK UNIFIED IDEOGRAPH
+0xAD70 0x74B8 #CJK UNIFIED IDEOGRAPH
+0xAD71 0x74B9 #CJK UNIFIED IDEOGRAPH
+0xAD72 0x74BB #CJK UNIFIED IDEOGRAPH
+0xAD73 0x74BC #CJK UNIFIED IDEOGRAPH
+0xAD74 0x74BD #CJK UNIFIED IDEOGRAPH
+0xAD75 0x74BE #CJK UNIFIED IDEOGRAPH
+0xAD76 0x74BF #CJK UNIFIED IDEOGRAPH
+0xAD77 0x74C0 #CJK UNIFIED IDEOGRAPH
+0xAD78 0x74C1 #CJK UNIFIED IDEOGRAPH
+0xAD79 0x74C2 #CJK UNIFIED IDEOGRAPH
+0xAD7A 0x74C3 #CJK UNIFIED IDEOGRAPH
+0xAD7B 0x74C4 #CJK UNIFIED IDEOGRAPH
+0xAD7C 0x74C5 #CJK UNIFIED IDEOGRAPH
+0xAD7D 0x74C6 #CJK UNIFIED IDEOGRAPH
+0xAD7E 0x74C7 #CJK UNIFIED IDEOGRAPH
+0xAD80 0x74C8 #CJK UNIFIED IDEOGRAPH
+0xAD81 0x74C9 #CJK UNIFIED IDEOGRAPH
+0xAD82 0x74CA #CJK UNIFIED IDEOGRAPH
+0xAD83 0x74CB #CJK UNIFIED IDEOGRAPH
+0xAD84 0x74CC #CJK UNIFIED IDEOGRAPH
+0xAD85 0x74CD #CJK UNIFIED IDEOGRAPH
+0xAD86 0x74CE #CJK UNIFIED IDEOGRAPH
+0xAD87 0x74CF #CJK UNIFIED IDEOGRAPH
+0xAD88 0x74D0 #CJK UNIFIED IDEOGRAPH
+0xAD89 0x74D1 #CJK UNIFIED IDEOGRAPH
+0xAD8A 0x74D3 #CJK UNIFIED IDEOGRAPH
+0xAD8B 0x74D4 #CJK UNIFIED IDEOGRAPH
+0xAD8C 0x74D5 #CJK UNIFIED IDEOGRAPH
+0xAD8D 0x74D6 #CJK UNIFIED IDEOGRAPH
+0xAD8E 0x74D7 #CJK UNIFIED IDEOGRAPH
+0xAD8F 0x74D8 #CJK UNIFIED IDEOGRAPH
+0xAD90 0x74D9 #CJK UNIFIED IDEOGRAPH
+0xAD91 0x74DA #CJK UNIFIED IDEOGRAPH
+0xAD92 0x74DB #CJK UNIFIED IDEOGRAPH
+0xAD93 0x74DD #CJK UNIFIED IDEOGRAPH
+0xAD94 0x74DF #CJK UNIFIED IDEOGRAPH
+0xAD95 0x74E1 #CJK UNIFIED IDEOGRAPH
+0xAD96 0x74E5 #CJK UNIFIED IDEOGRAPH
+0xAD97 0x74E7 #CJK UNIFIED IDEOGRAPH
+0xAD98 0x74E8 #CJK UNIFIED IDEOGRAPH
+0xAD99 0x74E9 #CJK UNIFIED IDEOGRAPH
+0xAD9A 0x74EA #CJK UNIFIED IDEOGRAPH
+0xAD9B 0x74EB #CJK UNIFIED IDEOGRAPH
+0xAD9C 0x74EC #CJK UNIFIED IDEOGRAPH
+0xAD9D 0x74ED #CJK UNIFIED IDEOGRAPH
+0xAD9E 0x74F0 #CJK UNIFIED IDEOGRAPH
+0xAD9F 0x74F1 #CJK UNIFIED IDEOGRAPH
+0xADA0 0x74F2 #CJK UNIFIED IDEOGRAPH
+0xAE40 0x74F3 #CJK UNIFIED IDEOGRAPH
+0xAE41 0x74F5 #CJK UNIFIED IDEOGRAPH
+0xAE42 0x74F8 #CJK UNIFIED IDEOGRAPH
+0xAE43 0x74F9 #CJK UNIFIED IDEOGRAPH
+0xAE44 0x74FA #CJK UNIFIED IDEOGRAPH
+0xAE45 0x74FB #CJK UNIFIED IDEOGRAPH
+0xAE46 0x74FC #CJK UNIFIED IDEOGRAPH
+0xAE47 0x74FD #CJK UNIFIED IDEOGRAPH
+0xAE48 0x74FE #CJK UNIFIED IDEOGRAPH
+0xAE49 0x7500 #CJK UNIFIED IDEOGRAPH
+0xAE4A 0x7501 #CJK UNIFIED IDEOGRAPH
+0xAE4B 0x7502 #CJK UNIFIED IDEOGRAPH
+0xAE4C 0x7503 #CJK UNIFIED IDEOGRAPH
+0xAE4D 0x7505 #CJK UNIFIED IDEOGRAPH
+0xAE4E 0x7506 #CJK UNIFIED IDEOGRAPH
+0xAE4F 0x7507 #CJK UNIFIED IDEOGRAPH
+0xAE50 0x7508 #CJK UNIFIED IDEOGRAPH
+0xAE51 0x7509 #CJK UNIFIED IDEOGRAPH
+0xAE52 0x750A #CJK UNIFIED IDEOGRAPH
+0xAE53 0x750B #CJK UNIFIED IDEOGRAPH
+0xAE54 0x750C #CJK UNIFIED IDEOGRAPH
+0xAE55 0x750E #CJK UNIFIED IDEOGRAPH
+0xAE56 0x7510 #CJK UNIFIED IDEOGRAPH
+0xAE57 0x7512 #CJK UNIFIED IDEOGRAPH
+0xAE58 0x7514 #CJK UNIFIED IDEOGRAPH
+0xAE59 0x7515 #CJK UNIFIED IDEOGRAPH
+0xAE5A 0x7516 #CJK UNIFIED IDEOGRAPH
+0xAE5B 0x7517 #CJK UNIFIED IDEOGRAPH
+0xAE5C 0x751B #CJK UNIFIED IDEOGRAPH
+0xAE5D 0x751D #CJK UNIFIED IDEOGRAPH
+0xAE5E 0x751E #CJK UNIFIED IDEOGRAPH
+0xAE5F 0x7520 #CJK UNIFIED IDEOGRAPH
+0xAE60 0x7521 #CJK UNIFIED IDEOGRAPH
+0xAE61 0x7522 #CJK UNIFIED IDEOGRAPH
+0xAE62 0x7523 #CJK UNIFIED IDEOGRAPH
+0xAE63 0x7524 #CJK UNIFIED IDEOGRAPH
+0xAE64 0x7526 #CJK UNIFIED IDEOGRAPH
+0xAE65 0x7527 #CJK UNIFIED IDEOGRAPH
+0xAE66 0x752A #CJK UNIFIED IDEOGRAPH
+0xAE67 0x752E #CJK UNIFIED IDEOGRAPH
+0xAE68 0x7534 #CJK UNIFIED IDEOGRAPH
+0xAE69 0x7536 #CJK UNIFIED IDEOGRAPH
+0xAE6A 0x7539 #CJK UNIFIED IDEOGRAPH
+0xAE6B 0x753C #CJK UNIFIED IDEOGRAPH
+0xAE6C 0x753D #CJK UNIFIED IDEOGRAPH
+0xAE6D 0x753F #CJK UNIFIED IDEOGRAPH
+0xAE6E 0x7541 #CJK UNIFIED IDEOGRAPH
+0xAE6F 0x7542 #CJK UNIFIED IDEOGRAPH
+0xAE70 0x7543 #CJK UNIFIED IDEOGRAPH
+0xAE71 0x7544 #CJK UNIFIED IDEOGRAPH
+0xAE72 0x7546 #CJK UNIFIED IDEOGRAPH
+0xAE73 0x7547 #CJK UNIFIED IDEOGRAPH
+0xAE74 0x7549 #CJK UNIFIED IDEOGRAPH
+0xAE75 0x754A #CJK UNIFIED IDEOGRAPH
+0xAE76 0x754D #CJK UNIFIED IDEOGRAPH
+0xAE77 0x7550 #CJK UNIFIED IDEOGRAPH
+0xAE78 0x7551 #CJK UNIFIED IDEOGRAPH
+0xAE79 0x7552 #CJK UNIFIED IDEOGRAPH
+0xAE7A 0x7553 #CJK UNIFIED IDEOGRAPH
+0xAE7B 0x7555 #CJK UNIFIED IDEOGRAPH
+0xAE7C 0x7556 #CJK UNIFIED IDEOGRAPH
+0xAE7D 0x7557 #CJK UNIFIED IDEOGRAPH
+0xAE7E 0x7558 #CJK UNIFIED IDEOGRAPH
+0xAE80 0x755D #CJK UNIFIED IDEOGRAPH
+0xAE81 0x755E #CJK UNIFIED IDEOGRAPH
+0xAE82 0x755F #CJK UNIFIED IDEOGRAPH
+0xAE83 0x7560 #CJK UNIFIED IDEOGRAPH
+0xAE84 0x7561 #CJK UNIFIED IDEOGRAPH
+0xAE85 0x7562 #CJK UNIFIED IDEOGRAPH
+0xAE86 0x7563 #CJK UNIFIED IDEOGRAPH
+0xAE87 0x7564 #CJK UNIFIED IDEOGRAPH
+0xAE88 0x7567 #CJK UNIFIED IDEOGRAPH
+0xAE89 0x7568 #CJK UNIFIED IDEOGRAPH
+0xAE8A 0x7569 #CJK UNIFIED IDEOGRAPH
+0xAE8B 0x756B #CJK UNIFIED IDEOGRAPH
+0xAE8C 0x756C #CJK UNIFIED IDEOGRAPH
+0xAE8D 0x756D #CJK UNIFIED IDEOGRAPH
+0xAE8E 0x756E #CJK UNIFIED IDEOGRAPH
+0xAE8F 0x756F #CJK UNIFIED IDEOGRAPH
+0xAE90 0x7570 #CJK UNIFIED IDEOGRAPH
+0xAE91 0x7571 #CJK UNIFIED IDEOGRAPH
+0xAE92 0x7573 #CJK UNIFIED IDEOGRAPH
+0xAE93 0x7575 #CJK UNIFIED IDEOGRAPH
+0xAE94 0x7576 #CJK UNIFIED IDEOGRAPH
+0xAE95 0x7577 #CJK UNIFIED IDEOGRAPH
+0xAE96 0x757A #CJK UNIFIED IDEOGRAPH
+0xAE97 0x757B #CJK UNIFIED IDEOGRAPH
+0xAE98 0x757C #CJK UNIFIED IDEOGRAPH
+0xAE99 0x757D #CJK UNIFIED IDEOGRAPH
+0xAE9A 0x757E #CJK UNIFIED IDEOGRAPH
+0xAE9B 0x7580 #CJK UNIFIED IDEOGRAPH
+0xAE9C 0x7581 #CJK UNIFIED IDEOGRAPH
+0xAE9D 0x7582 #CJK UNIFIED IDEOGRAPH
+0xAE9E 0x7584 #CJK UNIFIED IDEOGRAPH
+0xAE9F 0x7585 #CJK UNIFIED IDEOGRAPH
+0xAEA0 0x7587 #CJK UNIFIED IDEOGRAPH
+0xAF40 0x7588 #CJK UNIFIED IDEOGRAPH
+0xAF41 0x7589 #CJK UNIFIED IDEOGRAPH
+0xAF42 0x758A #CJK UNIFIED IDEOGRAPH
+0xAF43 0x758C #CJK UNIFIED IDEOGRAPH
+0xAF44 0x758D #CJK UNIFIED IDEOGRAPH
+0xAF45 0x758E #CJK UNIFIED IDEOGRAPH
+0xAF46 0x7590 #CJK UNIFIED IDEOGRAPH
+0xAF47 0x7593 #CJK UNIFIED IDEOGRAPH
+0xAF48 0x7595 #CJK UNIFIED IDEOGRAPH
+0xAF49 0x7598 #CJK UNIFIED IDEOGRAPH
+0xAF4A 0x759B #CJK UNIFIED IDEOGRAPH
+0xAF4B 0x759C #CJK UNIFIED IDEOGRAPH
+0xAF4C 0x759E #CJK UNIFIED IDEOGRAPH
+0xAF4D 0x75A2 #CJK UNIFIED IDEOGRAPH
+0xAF4E 0x75A6 #CJK UNIFIED IDEOGRAPH
+0xAF4F 0x75A7 #CJK UNIFIED IDEOGRAPH
+0xAF50 0x75A8 #CJK UNIFIED IDEOGRAPH
+0xAF51 0x75A9 #CJK UNIFIED IDEOGRAPH
+0xAF52 0x75AA #CJK UNIFIED IDEOGRAPH
+0xAF53 0x75AD #CJK UNIFIED IDEOGRAPH
+0xAF54 0x75B6 #CJK UNIFIED IDEOGRAPH
+0xAF55 0x75B7 #CJK UNIFIED IDEOGRAPH
+0xAF56 0x75BA #CJK UNIFIED IDEOGRAPH
+0xAF57 0x75BB #CJK UNIFIED IDEOGRAPH
+0xAF58 0x75BF #CJK UNIFIED IDEOGRAPH
+0xAF59 0x75C0 #CJK UNIFIED IDEOGRAPH
+0xAF5A 0x75C1 #CJK UNIFIED IDEOGRAPH
+0xAF5B 0x75C6 #CJK UNIFIED IDEOGRAPH
+0xAF5C 0x75CB #CJK UNIFIED IDEOGRAPH
+0xAF5D 0x75CC #CJK UNIFIED IDEOGRAPH
+0xAF5E 0x75CE #CJK UNIFIED IDEOGRAPH
+0xAF5F 0x75CF #CJK UNIFIED IDEOGRAPH
+0xAF60 0x75D0 #CJK UNIFIED IDEOGRAPH
+0xAF61 0x75D1 #CJK UNIFIED IDEOGRAPH
+0xAF62 0x75D3 #CJK UNIFIED IDEOGRAPH
+0xAF63 0x75D7 #CJK UNIFIED IDEOGRAPH
+0xAF64 0x75D9 #CJK UNIFIED IDEOGRAPH
+0xAF65 0x75DA #CJK UNIFIED IDEOGRAPH
+0xAF66 0x75DC #CJK UNIFIED IDEOGRAPH
+0xAF67 0x75DD #CJK UNIFIED IDEOGRAPH
+0xAF68 0x75DF #CJK UNIFIED IDEOGRAPH
+0xAF69 0x75E0 #CJK UNIFIED IDEOGRAPH
+0xAF6A 0x75E1 #CJK UNIFIED IDEOGRAPH
+0xAF6B 0x75E5 #CJK UNIFIED IDEOGRAPH
+0xAF6C 0x75E9 #CJK UNIFIED IDEOGRAPH
+0xAF6D 0x75EC #CJK UNIFIED IDEOGRAPH
+0xAF6E 0x75ED #CJK UNIFIED IDEOGRAPH
+0xAF6F 0x75EE #CJK UNIFIED IDEOGRAPH
+0xAF70 0x75EF #CJK UNIFIED IDEOGRAPH
+0xAF71 0x75F2 #CJK UNIFIED IDEOGRAPH
+0xAF72 0x75F3 #CJK UNIFIED IDEOGRAPH
+0xAF73 0x75F5 #CJK UNIFIED IDEOGRAPH
+0xAF74 0x75F6 #CJK UNIFIED IDEOGRAPH
+0xAF75 0x75F7 #CJK UNIFIED IDEOGRAPH
+0xAF76 0x75F8 #CJK UNIFIED IDEOGRAPH
+0xAF77 0x75FA #CJK UNIFIED IDEOGRAPH
+0xAF78 0x75FB #CJK UNIFIED IDEOGRAPH
+0xAF79 0x75FD #CJK UNIFIED IDEOGRAPH
+0xAF7A 0x75FE #CJK UNIFIED IDEOGRAPH
+0xAF7B 0x7602 #CJK UNIFIED IDEOGRAPH
+0xAF7C 0x7604 #CJK UNIFIED IDEOGRAPH
+0xAF7D 0x7606 #CJK UNIFIED IDEOGRAPH
+0xAF7E 0x7607 #CJK UNIFIED IDEOGRAPH
+0xAF80 0x7608 #CJK UNIFIED IDEOGRAPH
+0xAF81 0x7609 #CJK UNIFIED IDEOGRAPH
+0xAF82 0x760B #CJK UNIFIED IDEOGRAPH
+0xAF83 0x760D #CJK UNIFIED IDEOGRAPH
+0xAF84 0x760E #CJK UNIFIED IDEOGRAPH
+0xAF85 0x760F #CJK UNIFIED IDEOGRAPH
+0xAF86 0x7611 #CJK UNIFIED IDEOGRAPH
+0xAF87 0x7612 #CJK UNIFIED IDEOGRAPH
+0xAF88 0x7613 #CJK UNIFIED IDEOGRAPH
+0xAF89 0x7614 #CJK UNIFIED IDEOGRAPH
+0xAF8A 0x7616 #CJK UNIFIED IDEOGRAPH
+0xAF8B 0x761A #CJK UNIFIED IDEOGRAPH
+0xAF8C 0x761C #CJK UNIFIED IDEOGRAPH
+0xAF8D 0x761D #CJK UNIFIED IDEOGRAPH
+0xAF8E 0x761E #CJK UNIFIED IDEOGRAPH
+0xAF8F 0x7621 #CJK UNIFIED IDEOGRAPH
+0xAF90 0x7623 #CJK UNIFIED IDEOGRAPH
+0xAF91 0x7627 #CJK UNIFIED IDEOGRAPH
+0xAF92 0x7628 #CJK UNIFIED IDEOGRAPH
+0xAF93 0x762C #CJK UNIFIED IDEOGRAPH
+0xAF94 0x762E #CJK UNIFIED IDEOGRAPH
+0xAF95 0x762F #CJK UNIFIED IDEOGRAPH
+0xAF96 0x7631 #CJK UNIFIED IDEOGRAPH
+0xAF97 0x7632 #CJK UNIFIED IDEOGRAPH
+0xAF98 0x7636 #CJK UNIFIED IDEOGRAPH
+0xAF99 0x7637 #CJK UNIFIED IDEOGRAPH
+0xAF9A 0x7639 #CJK UNIFIED IDEOGRAPH
+0xAF9B 0x763A #CJK UNIFIED IDEOGRAPH
+0xAF9C 0x763B #CJK UNIFIED IDEOGRAPH
+0xAF9D 0x763D #CJK UNIFIED IDEOGRAPH
+0xAF9E 0x7641 #CJK UNIFIED IDEOGRAPH
+0xAF9F 0x7642 #CJK UNIFIED IDEOGRAPH
+0xAFA0 0x7644 #CJK UNIFIED IDEOGRAPH
+0xB040 0x7645 #CJK UNIFIED IDEOGRAPH
+0xB041 0x7646 #CJK UNIFIED IDEOGRAPH
+0xB042 0x7647 #CJK UNIFIED IDEOGRAPH
+0xB043 0x7648 #CJK UNIFIED IDEOGRAPH
+0xB044 0x7649 #CJK UNIFIED IDEOGRAPH
+0xB045 0x764A #CJK UNIFIED IDEOGRAPH
+0xB046 0x764B #CJK UNIFIED IDEOGRAPH
+0xB047 0x764E #CJK UNIFIED IDEOGRAPH
+0xB048 0x764F #CJK UNIFIED IDEOGRAPH
+0xB049 0x7650 #CJK UNIFIED IDEOGRAPH
+0xB04A 0x7651 #CJK UNIFIED IDEOGRAPH
+0xB04B 0x7652 #CJK UNIFIED IDEOGRAPH
+0xB04C 0x7653 #CJK UNIFIED IDEOGRAPH
+0xB04D 0x7655 #CJK UNIFIED IDEOGRAPH
+0xB04E 0x7657 #CJK UNIFIED IDEOGRAPH
+0xB04F 0x7658 #CJK UNIFIED IDEOGRAPH
+0xB050 0x7659 #CJK UNIFIED IDEOGRAPH
+0xB051 0x765A #CJK UNIFIED IDEOGRAPH
+0xB052 0x765B #CJK UNIFIED IDEOGRAPH
+0xB053 0x765D #CJK UNIFIED IDEOGRAPH
+0xB054 0x765F #CJK UNIFIED IDEOGRAPH
+0xB055 0x7660 #CJK UNIFIED IDEOGRAPH
+0xB056 0x7661 #CJK UNIFIED IDEOGRAPH
+0xB057 0x7662 #CJK UNIFIED IDEOGRAPH
+0xB058 0x7664 #CJK UNIFIED IDEOGRAPH
+0xB059 0x7665 #CJK UNIFIED IDEOGRAPH
+0xB05A 0x7666 #CJK UNIFIED IDEOGRAPH
+0xB05B 0x7667 #CJK UNIFIED IDEOGRAPH
+0xB05C 0x7668 #CJK UNIFIED IDEOGRAPH
+0xB05D 0x7669 #CJK UNIFIED IDEOGRAPH
+0xB05E 0x766A #CJK UNIFIED IDEOGRAPH
+0xB05F 0x766C #CJK UNIFIED IDEOGRAPH
+0xB060 0x766D #CJK UNIFIED IDEOGRAPH
+0xB061 0x766E #CJK UNIFIED IDEOGRAPH
+0xB062 0x7670 #CJK UNIFIED IDEOGRAPH
+0xB063 0x7671 #CJK UNIFIED IDEOGRAPH
+0xB064 0x7672 #CJK UNIFIED IDEOGRAPH
+0xB065 0x7673 #CJK UNIFIED IDEOGRAPH
+0xB066 0x7674 #CJK UNIFIED IDEOGRAPH
+0xB067 0x7675 #CJK UNIFIED IDEOGRAPH
+0xB068 0x7676 #CJK UNIFIED IDEOGRAPH
+0xB069 0x7677 #CJK UNIFIED IDEOGRAPH
+0xB06A 0x7679 #CJK UNIFIED IDEOGRAPH
+0xB06B 0x767A #CJK UNIFIED IDEOGRAPH
+0xB06C 0x767C #CJK UNIFIED IDEOGRAPH
+0xB06D 0x767F #CJK UNIFIED IDEOGRAPH
+0xB06E 0x7680 #CJK UNIFIED IDEOGRAPH
+0xB06F 0x7681 #CJK UNIFIED IDEOGRAPH
+0xB070 0x7683 #CJK UNIFIED IDEOGRAPH
+0xB071 0x7685 #CJK UNIFIED IDEOGRAPH
+0xB072 0x7689 #CJK UNIFIED IDEOGRAPH
+0xB073 0x768A #CJK UNIFIED IDEOGRAPH
+0xB074 0x768C #CJK UNIFIED IDEOGRAPH
+0xB075 0x768D #CJK UNIFIED IDEOGRAPH
+0xB076 0x768F #CJK UNIFIED IDEOGRAPH
+0xB077 0x7690 #CJK UNIFIED IDEOGRAPH
+0xB078 0x7692 #CJK UNIFIED IDEOGRAPH
+0xB079 0x7694 #CJK UNIFIED IDEOGRAPH
+0xB07A 0x7695 #CJK UNIFIED IDEOGRAPH
+0xB07B 0x7697 #CJK UNIFIED IDEOGRAPH
+0xB07C 0x7698 #CJK UNIFIED IDEOGRAPH
+0xB07D 0x769A #CJK UNIFIED IDEOGRAPH
+0xB07E 0x769B #CJK UNIFIED IDEOGRAPH
+0xB080 0x769C #CJK UNIFIED IDEOGRAPH
+0xB081 0x769D #CJK UNIFIED IDEOGRAPH
+0xB082 0x769E #CJK UNIFIED IDEOGRAPH
+0xB083 0x769F #CJK UNIFIED IDEOGRAPH
+0xB084 0x76A0 #CJK UNIFIED IDEOGRAPH
+0xB085 0x76A1 #CJK UNIFIED IDEOGRAPH
+0xB086 0x76A2 #CJK UNIFIED IDEOGRAPH
+0xB087 0x76A3 #CJK UNIFIED IDEOGRAPH
+0xB088 0x76A5 #CJK UNIFIED IDEOGRAPH
+0xB089 0x76A6 #CJK UNIFIED IDEOGRAPH
+0xB08A 0x76A7 #CJK UNIFIED IDEOGRAPH
+0xB08B 0x76A8 #CJK UNIFIED IDEOGRAPH
+0xB08C 0x76A9 #CJK UNIFIED IDEOGRAPH
+0xB08D 0x76AA #CJK UNIFIED IDEOGRAPH
+0xB08E 0x76AB #CJK UNIFIED IDEOGRAPH
+0xB08F 0x76AC #CJK UNIFIED IDEOGRAPH
+0xB090 0x76AD #CJK UNIFIED IDEOGRAPH
+0xB091 0x76AF #CJK UNIFIED IDEOGRAPH
+0xB092 0x76B0 #CJK UNIFIED IDEOGRAPH
+0xB093 0x76B3 #CJK UNIFIED IDEOGRAPH
+0xB094 0x76B5 #CJK UNIFIED IDEOGRAPH
+0xB095 0x76B6 #CJK UNIFIED IDEOGRAPH
+0xB096 0x76B7 #CJK UNIFIED IDEOGRAPH
+0xB097 0x76B8 #CJK UNIFIED IDEOGRAPH
+0xB098 0x76B9 #CJK UNIFIED IDEOGRAPH
+0xB099 0x76BA #CJK UNIFIED IDEOGRAPH
+0xB09A 0x76BB #CJK UNIFIED IDEOGRAPH
+0xB09B 0x76BC #CJK UNIFIED IDEOGRAPH
+0xB09C 0x76BD #CJK UNIFIED IDEOGRAPH
+0xB09D 0x76BE #CJK UNIFIED IDEOGRAPH
+0xB09E 0x76C0 #CJK UNIFIED IDEOGRAPH
+0xB09F 0x76C1 #CJK UNIFIED IDEOGRAPH
+0xB0A0 0x76C3 #CJK UNIFIED IDEOGRAPH
+0xB0A1 0x554A #CJK UNIFIED IDEOGRAPH
+0xB0A2 0x963F #CJK UNIFIED IDEOGRAPH
+0xB0A3 0x57C3 #CJK UNIFIED IDEOGRAPH
+0xB0A4 0x6328 #CJK UNIFIED IDEOGRAPH
+0xB0A5 0x54CE #CJK UNIFIED IDEOGRAPH
+0xB0A6 0x5509 #CJK UNIFIED IDEOGRAPH
+0xB0A7 0x54C0 #CJK UNIFIED IDEOGRAPH
+0xB0A8 0x7691 #CJK UNIFIED IDEOGRAPH
+0xB0A9 0x764C #CJK UNIFIED IDEOGRAPH
+0xB0AA 0x853C #CJK UNIFIED IDEOGRAPH
+0xB0AB 0x77EE #CJK UNIFIED IDEOGRAPH
+0xB0AC 0x827E #CJK UNIFIED IDEOGRAPH
+0xB0AD 0x788D #CJK UNIFIED IDEOGRAPH
+0xB0AE 0x7231 #CJK UNIFIED IDEOGRAPH
+0xB0AF 0x9698 #CJK UNIFIED IDEOGRAPH
+0xB0B0 0x978D #CJK UNIFIED IDEOGRAPH
+0xB0B1 0x6C28 #CJK UNIFIED IDEOGRAPH
+0xB0B2 0x5B89 #CJK UNIFIED IDEOGRAPH
+0xB0B3 0x4FFA #CJK UNIFIED IDEOGRAPH
+0xB0B4 0x6309 #CJK UNIFIED IDEOGRAPH
+0xB0B5 0x6697 #CJK UNIFIED IDEOGRAPH
+0xB0B6 0x5CB8 #CJK UNIFIED IDEOGRAPH
+0xB0B7 0x80FA #CJK UNIFIED IDEOGRAPH
+0xB0B8 0x6848 #CJK UNIFIED IDEOGRAPH
+0xB0B9 0x80AE #CJK UNIFIED IDEOGRAPH
+0xB0BA 0x6602 #CJK UNIFIED IDEOGRAPH
+0xB0BB 0x76CE #CJK UNIFIED IDEOGRAPH
+0xB0BC 0x51F9 #CJK UNIFIED IDEOGRAPH
+0xB0BD 0x6556 #CJK UNIFIED IDEOGRAPH
+0xB0BE 0x71AC #CJK UNIFIED IDEOGRAPH
+0xB0BF 0x7FF1 #CJK UNIFIED IDEOGRAPH
+0xB0C0 0x8884 #CJK UNIFIED IDEOGRAPH
+0xB0C1 0x50B2 #CJK UNIFIED IDEOGRAPH
+0xB0C2 0x5965 #CJK UNIFIED IDEOGRAPH
+0xB0C3 0x61CA #CJK UNIFIED IDEOGRAPH
+0xB0C4 0x6FB3 #CJK UNIFIED IDEOGRAPH
+0xB0C5 0x82AD #CJK UNIFIED IDEOGRAPH
+0xB0C6 0x634C #CJK UNIFIED IDEOGRAPH
+0xB0C7 0x6252 #CJK UNIFIED IDEOGRAPH
+0xB0C8 0x53ED #CJK UNIFIED IDEOGRAPH
+0xB0C9 0x5427 #CJK UNIFIED IDEOGRAPH
+0xB0CA 0x7B06 #CJK UNIFIED IDEOGRAPH
+0xB0CB 0x516B #CJK UNIFIED IDEOGRAPH
+0xB0CC 0x75A4 #CJK UNIFIED IDEOGRAPH
+0xB0CD 0x5DF4 #CJK UNIFIED IDEOGRAPH
+0xB0CE 0x62D4 #CJK UNIFIED IDEOGRAPH
+0xB0CF 0x8DCB #CJK UNIFIED IDEOGRAPH
+0xB0D0 0x9776 #CJK UNIFIED IDEOGRAPH
+0xB0D1 0x628A #CJK UNIFIED IDEOGRAPH
+0xB0D2 0x8019 #CJK UNIFIED IDEOGRAPH
+0xB0D3 0x575D #CJK UNIFIED IDEOGRAPH
+0xB0D4 0x9738 #CJK UNIFIED IDEOGRAPH
+0xB0D5 0x7F62 #CJK UNIFIED IDEOGRAPH
+0xB0D6 0x7238 #CJK UNIFIED IDEOGRAPH
+0xB0D7 0x767D #CJK UNIFIED IDEOGRAPH
+0xB0D8 0x67CF #CJK UNIFIED IDEOGRAPH
+0xB0D9 0x767E #CJK UNIFIED IDEOGRAPH
+0xB0DA 0x6446 #CJK UNIFIED IDEOGRAPH
+0xB0DB 0x4F70 #CJK UNIFIED IDEOGRAPH
+0xB0DC 0x8D25 #CJK UNIFIED IDEOGRAPH
+0xB0DD 0x62DC #CJK UNIFIED IDEOGRAPH
+0xB0DE 0x7A17 #CJK UNIFIED IDEOGRAPH
+0xB0DF 0x6591 #CJK UNIFIED IDEOGRAPH
+0xB0E0 0x73ED #CJK UNIFIED IDEOGRAPH
+0xB0E1 0x642C #CJK UNIFIED IDEOGRAPH
+0xB0E2 0x6273 #CJK UNIFIED IDEOGRAPH
+0xB0E3 0x822C #CJK UNIFIED IDEOGRAPH
+0xB0E4 0x9881 #CJK UNIFIED IDEOGRAPH
+0xB0E5 0x677F #CJK UNIFIED IDEOGRAPH
+0xB0E6 0x7248 #CJK UNIFIED IDEOGRAPH
+0xB0E7 0x626E #CJK UNIFIED IDEOGRAPH
+0xB0E8 0x62CC #CJK UNIFIED IDEOGRAPH
+0xB0E9 0x4F34 #CJK UNIFIED IDEOGRAPH
+0xB0EA 0x74E3 #CJK UNIFIED IDEOGRAPH
+0xB0EB 0x534A #CJK UNIFIED IDEOGRAPH
+0xB0EC 0x529E #CJK UNIFIED IDEOGRAPH
+0xB0ED 0x7ECA #CJK UNIFIED IDEOGRAPH
+0xB0EE 0x90A6 #CJK UNIFIED IDEOGRAPH
+0xB0EF 0x5E2E #CJK UNIFIED IDEOGRAPH
+0xB0F0 0x6886 #CJK UNIFIED IDEOGRAPH
+0xB0F1 0x699C #CJK UNIFIED IDEOGRAPH
+0xB0F2 0x8180 #CJK UNIFIED IDEOGRAPH
+0xB0F3 0x7ED1 #CJK UNIFIED IDEOGRAPH
+0xB0F4 0x68D2 #CJK UNIFIED IDEOGRAPH
+0xB0F5 0x78C5 #CJK UNIFIED IDEOGRAPH
+0xB0F6 0x868C #CJK UNIFIED IDEOGRAPH
+0xB0F7 0x9551 #CJK UNIFIED IDEOGRAPH
+0xB0F8 0x508D #CJK UNIFIED IDEOGRAPH
+0xB0F9 0x8C24 #CJK UNIFIED IDEOGRAPH
+0xB0FA 0x82DE #CJK UNIFIED IDEOGRAPH
+0xB0FB 0x80DE #CJK UNIFIED IDEOGRAPH
+0xB0FC 0x5305 #CJK UNIFIED IDEOGRAPH
+0xB0FD 0x8912 #CJK UNIFIED IDEOGRAPH
+0xB0FE 0x5265 #CJK UNIFIED IDEOGRAPH
+0xB140 0x76C4 #CJK UNIFIED IDEOGRAPH
+0xB141 0x76C7 #CJK UNIFIED IDEOGRAPH
+0xB142 0x76C9 #CJK UNIFIED IDEOGRAPH
+0xB143 0x76CB #CJK UNIFIED IDEOGRAPH
+0xB144 0x76CC #CJK UNIFIED IDEOGRAPH
+0xB145 0x76D3 #CJK UNIFIED IDEOGRAPH
+0xB146 0x76D5 #CJK UNIFIED IDEOGRAPH
+0xB147 0x76D9 #CJK UNIFIED IDEOGRAPH
+0xB148 0x76DA #CJK UNIFIED IDEOGRAPH
+0xB149 0x76DC #CJK UNIFIED IDEOGRAPH
+0xB14A 0x76DD #CJK UNIFIED IDEOGRAPH
+0xB14B 0x76DE #CJK UNIFIED IDEOGRAPH
+0xB14C 0x76E0 #CJK UNIFIED IDEOGRAPH
+0xB14D 0x76E1 #CJK UNIFIED IDEOGRAPH
+0xB14E 0x76E2 #CJK UNIFIED IDEOGRAPH
+0xB14F 0x76E3 #CJK UNIFIED IDEOGRAPH
+0xB150 0x76E4 #CJK UNIFIED IDEOGRAPH
+0xB151 0x76E6 #CJK UNIFIED IDEOGRAPH
+0xB152 0x76E7 #CJK UNIFIED IDEOGRAPH
+0xB153 0x76E8 #CJK UNIFIED IDEOGRAPH
+0xB154 0x76E9 #CJK UNIFIED IDEOGRAPH
+0xB155 0x76EA #CJK UNIFIED IDEOGRAPH
+0xB156 0x76EB #CJK UNIFIED IDEOGRAPH
+0xB157 0x76EC #CJK UNIFIED IDEOGRAPH
+0xB158 0x76ED #CJK UNIFIED IDEOGRAPH
+0xB159 0x76F0 #CJK UNIFIED IDEOGRAPH
+0xB15A 0x76F3 #CJK UNIFIED IDEOGRAPH
+0xB15B 0x76F5 #CJK UNIFIED IDEOGRAPH
+0xB15C 0x76F6 #CJK UNIFIED IDEOGRAPH
+0xB15D 0x76F7 #CJK UNIFIED IDEOGRAPH
+0xB15E 0x76FA #CJK UNIFIED IDEOGRAPH
+0xB15F 0x76FB #CJK UNIFIED IDEOGRAPH
+0xB160 0x76FD #CJK UNIFIED IDEOGRAPH
+0xB161 0x76FF #CJK UNIFIED IDEOGRAPH
+0xB162 0x7700 #CJK UNIFIED IDEOGRAPH
+0xB163 0x7702 #CJK UNIFIED IDEOGRAPH
+0xB164 0x7703 #CJK UNIFIED IDEOGRAPH
+0xB165 0x7705 #CJK UNIFIED IDEOGRAPH
+0xB166 0x7706 #CJK UNIFIED IDEOGRAPH
+0xB167 0x770A #CJK UNIFIED IDEOGRAPH
+0xB168 0x770C #CJK UNIFIED IDEOGRAPH
+0xB169 0x770E #CJK UNIFIED IDEOGRAPH
+0xB16A 0x770F #CJK UNIFIED IDEOGRAPH
+0xB16B 0x7710 #CJK UNIFIED IDEOGRAPH
+0xB16C 0x7711 #CJK UNIFIED IDEOGRAPH
+0xB16D 0x7712 #CJK UNIFIED IDEOGRAPH
+0xB16E 0x7713 #CJK UNIFIED IDEOGRAPH
+0xB16F 0x7714 #CJK UNIFIED IDEOGRAPH
+0xB170 0x7715 #CJK UNIFIED IDEOGRAPH
+0xB171 0x7716 #CJK UNIFIED IDEOGRAPH
+0xB172 0x7717 #CJK UNIFIED IDEOGRAPH
+0xB173 0x7718 #CJK UNIFIED IDEOGRAPH
+0xB174 0x771B #CJK UNIFIED IDEOGRAPH
+0xB175 0x771C #CJK UNIFIED IDEOGRAPH
+0xB176 0x771D #CJK UNIFIED IDEOGRAPH
+0xB177 0x771E #CJK UNIFIED IDEOGRAPH
+0xB178 0x7721 #CJK UNIFIED IDEOGRAPH
+0xB179 0x7723 #CJK UNIFIED IDEOGRAPH
+0xB17A 0x7724 #CJK UNIFIED IDEOGRAPH
+0xB17B 0x7725 #CJK UNIFIED IDEOGRAPH
+0xB17C 0x7727 #CJK UNIFIED IDEOGRAPH
+0xB17D 0x772A #CJK UNIFIED IDEOGRAPH
+0xB17E 0x772B #CJK UNIFIED IDEOGRAPH
+0xB180 0x772C #CJK UNIFIED IDEOGRAPH
+0xB181 0x772E #CJK UNIFIED IDEOGRAPH
+0xB182 0x7730 #CJK UNIFIED IDEOGRAPH
+0xB183 0x7731 #CJK UNIFIED IDEOGRAPH
+0xB184 0x7732 #CJK UNIFIED IDEOGRAPH
+0xB185 0x7733 #CJK UNIFIED IDEOGRAPH
+0xB186 0x7734 #CJK UNIFIED IDEOGRAPH
+0xB187 0x7739 #CJK UNIFIED IDEOGRAPH
+0xB188 0x773B #CJK UNIFIED IDEOGRAPH
+0xB189 0x773D #CJK UNIFIED IDEOGRAPH
+0xB18A 0x773E #CJK UNIFIED IDEOGRAPH
+0xB18B 0x773F #CJK UNIFIED IDEOGRAPH
+0xB18C 0x7742 #CJK UNIFIED IDEOGRAPH
+0xB18D 0x7744 #CJK UNIFIED IDEOGRAPH
+0xB18E 0x7745 #CJK UNIFIED IDEOGRAPH
+0xB18F 0x7746 #CJK UNIFIED IDEOGRAPH
+0xB190 0x7748 #CJK UNIFIED IDEOGRAPH
+0xB191 0x7749 #CJK UNIFIED IDEOGRAPH
+0xB192 0x774A #CJK UNIFIED IDEOGRAPH
+0xB193 0x774B #CJK UNIFIED IDEOGRAPH
+0xB194 0x774C #CJK UNIFIED IDEOGRAPH
+0xB195 0x774D #CJK UNIFIED IDEOGRAPH
+0xB196 0x774E #CJK UNIFIED IDEOGRAPH
+0xB197 0x774F #CJK UNIFIED IDEOGRAPH
+0xB198 0x7752 #CJK UNIFIED IDEOGRAPH
+0xB199 0x7753 #CJK UNIFIED IDEOGRAPH
+0xB19A 0x7754 #CJK UNIFIED IDEOGRAPH
+0xB19B 0x7755 #CJK UNIFIED IDEOGRAPH
+0xB19C 0x7756 #CJK UNIFIED IDEOGRAPH
+0xB19D 0x7757 #CJK UNIFIED IDEOGRAPH
+0xB19E 0x7758 #CJK UNIFIED IDEOGRAPH
+0xB19F 0x7759 #CJK UNIFIED IDEOGRAPH
+0xB1A0 0x775C #CJK UNIFIED IDEOGRAPH
+0xB1A1 0x8584 #CJK UNIFIED IDEOGRAPH
+0xB1A2 0x96F9 #CJK UNIFIED IDEOGRAPH
+0xB1A3 0x4FDD #CJK UNIFIED IDEOGRAPH
+0xB1A4 0x5821 #CJK UNIFIED IDEOGRAPH
+0xB1A5 0x9971 #CJK UNIFIED IDEOGRAPH
+0xB1A6 0x5B9D #CJK UNIFIED IDEOGRAPH
+0xB1A7 0x62B1 #CJK UNIFIED IDEOGRAPH
+0xB1A8 0x62A5 #CJK UNIFIED IDEOGRAPH
+0xB1A9 0x66B4 #CJK UNIFIED IDEOGRAPH
+0xB1AA 0x8C79 #CJK UNIFIED IDEOGRAPH
+0xB1AB 0x9C8D #CJK UNIFIED IDEOGRAPH
+0xB1AC 0x7206 #CJK UNIFIED IDEOGRAPH
+0xB1AD 0x676F #CJK UNIFIED IDEOGRAPH
+0xB1AE 0x7891 #CJK UNIFIED IDEOGRAPH
+0xB1AF 0x60B2 #CJK UNIFIED IDEOGRAPH
+0xB1B0 0x5351 #CJK UNIFIED IDEOGRAPH
+0xB1B1 0x5317 #CJK UNIFIED IDEOGRAPH
+0xB1B2 0x8F88 #CJK UNIFIED IDEOGRAPH
+0xB1B3 0x80CC #CJK UNIFIED IDEOGRAPH
+0xB1B4 0x8D1D #CJK UNIFIED IDEOGRAPH
+0xB1B5 0x94A1 #CJK UNIFIED IDEOGRAPH
+0xB1B6 0x500D #CJK UNIFIED IDEOGRAPH
+0xB1B7 0x72C8 #CJK UNIFIED IDEOGRAPH
+0xB1B8 0x5907 #CJK UNIFIED IDEOGRAPH
+0xB1B9 0x60EB #CJK UNIFIED IDEOGRAPH
+0xB1BA 0x7119 #CJK UNIFIED IDEOGRAPH
+0xB1BB 0x88AB #CJK UNIFIED IDEOGRAPH
+0xB1BC 0x5954 #CJK UNIFIED IDEOGRAPH
+0xB1BD 0x82EF #CJK UNIFIED IDEOGRAPH
+0xB1BE 0x672C #CJK UNIFIED IDEOGRAPH
+0xB1BF 0x7B28 #CJK UNIFIED IDEOGRAPH
+0xB1C0 0x5D29 #CJK UNIFIED IDEOGRAPH
+0xB1C1 0x7EF7 #CJK UNIFIED IDEOGRAPH
+0xB1C2 0x752D #CJK UNIFIED IDEOGRAPH
+0xB1C3 0x6CF5 #CJK UNIFIED IDEOGRAPH
+0xB1C4 0x8E66 #CJK UNIFIED IDEOGRAPH
+0xB1C5 0x8FF8 #CJK UNIFIED IDEOGRAPH
+0xB1C6 0x903C #CJK UNIFIED IDEOGRAPH
+0xB1C7 0x9F3B #CJK UNIFIED IDEOGRAPH
+0xB1C8 0x6BD4 #CJK UNIFIED IDEOGRAPH
+0xB1C9 0x9119 #CJK UNIFIED IDEOGRAPH
+0xB1CA 0x7B14 #CJK UNIFIED IDEOGRAPH
+0xB1CB 0x5F7C #CJK UNIFIED IDEOGRAPH
+0xB1CC 0x78A7 #CJK UNIFIED IDEOGRAPH
+0xB1CD 0x84D6 #CJK UNIFIED IDEOGRAPH
+0xB1CE 0x853D #CJK UNIFIED IDEOGRAPH
+0xB1CF 0x6BD5 #CJK UNIFIED IDEOGRAPH
+0xB1D0 0x6BD9 #CJK UNIFIED IDEOGRAPH
+0xB1D1 0x6BD6 #CJK UNIFIED IDEOGRAPH
+0xB1D2 0x5E01 #CJK UNIFIED IDEOGRAPH
+0xB1D3 0x5E87 #CJK UNIFIED IDEOGRAPH
+0xB1D4 0x75F9 #CJK UNIFIED IDEOGRAPH
+0xB1D5 0x95ED #CJK UNIFIED IDEOGRAPH
+0xB1D6 0x655D #CJK UNIFIED IDEOGRAPH
+0xB1D7 0x5F0A #CJK UNIFIED IDEOGRAPH
+0xB1D8 0x5FC5 #CJK UNIFIED IDEOGRAPH
+0xB1D9 0x8F9F #CJK UNIFIED IDEOGRAPH
+0xB1DA 0x58C1 #CJK UNIFIED IDEOGRAPH
+0xB1DB 0x81C2 #CJK UNIFIED IDEOGRAPH
+0xB1DC 0x907F #CJK UNIFIED IDEOGRAPH
+0xB1DD 0x965B #CJK UNIFIED IDEOGRAPH
+0xB1DE 0x97AD #CJK UNIFIED IDEOGRAPH
+0xB1DF 0x8FB9 #CJK UNIFIED IDEOGRAPH
+0xB1E0 0x7F16 #CJK UNIFIED IDEOGRAPH
+0xB1E1 0x8D2C #CJK UNIFIED IDEOGRAPH
+0xB1E2 0x6241 #CJK UNIFIED IDEOGRAPH
+0xB1E3 0x4FBF #CJK UNIFIED IDEOGRAPH
+0xB1E4 0x53D8 #CJK UNIFIED IDEOGRAPH
+0xB1E5 0x535E #CJK UNIFIED IDEOGRAPH
+0xB1E6 0x8FA8 #CJK UNIFIED IDEOGRAPH
+0xB1E7 0x8FA9 #CJK UNIFIED IDEOGRAPH
+0xB1E8 0x8FAB #CJK UNIFIED IDEOGRAPH
+0xB1E9 0x904D #CJK UNIFIED IDEOGRAPH
+0xB1EA 0x6807 #CJK UNIFIED IDEOGRAPH
+0xB1EB 0x5F6A #CJK UNIFIED IDEOGRAPH
+0xB1EC 0x8198 #CJK UNIFIED IDEOGRAPH
+0xB1ED 0x8868 #CJK UNIFIED IDEOGRAPH
+0xB1EE 0x9CD6 #CJK UNIFIED IDEOGRAPH
+0xB1EF 0x618B #CJK UNIFIED IDEOGRAPH
+0xB1F0 0x522B #CJK UNIFIED IDEOGRAPH
+0xB1F1 0x762A #CJK UNIFIED IDEOGRAPH
+0xB1F2 0x5F6C #CJK UNIFIED IDEOGRAPH
+0xB1F3 0x658C #CJK UNIFIED IDEOGRAPH
+0xB1F4 0x6FD2 #CJK UNIFIED IDEOGRAPH
+0xB1F5 0x6EE8 #CJK UNIFIED IDEOGRAPH
+0xB1F6 0x5BBE #CJK UNIFIED IDEOGRAPH
+0xB1F7 0x6448 #CJK UNIFIED IDEOGRAPH
+0xB1F8 0x5175 #CJK UNIFIED IDEOGRAPH
+0xB1F9 0x51B0 #CJK UNIFIED IDEOGRAPH
+0xB1FA 0x67C4 #CJK UNIFIED IDEOGRAPH
+0xB1FB 0x4E19 #CJK UNIFIED IDEOGRAPH
+0xB1FC 0x79C9 #CJK UNIFIED IDEOGRAPH
+0xB1FD 0x997C #CJK UNIFIED IDEOGRAPH
+0xB1FE 0x70B3 #CJK UNIFIED IDEOGRAPH
+0xB240 0x775D #CJK UNIFIED IDEOGRAPH
+0xB241 0x775E #CJK UNIFIED IDEOGRAPH
+0xB242 0x775F #CJK UNIFIED IDEOGRAPH
+0xB243 0x7760 #CJK UNIFIED IDEOGRAPH
+0xB244 0x7764 #CJK UNIFIED IDEOGRAPH
+0xB245 0x7767 #CJK UNIFIED IDEOGRAPH
+0xB246 0x7769 #CJK UNIFIED IDEOGRAPH
+0xB247 0x776A #CJK UNIFIED IDEOGRAPH
+0xB248 0x776D #CJK UNIFIED IDEOGRAPH
+0xB249 0x776E #CJK UNIFIED IDEOGRAPH
+0xB24A 0x776F #CJK UNIFIED IDEOGRAPH
+0xB24B 0x7770 #CJK UNIFIED IDEOGRAPH
+0xB24C 0x7771 #CJK UNIFIED IDEOGRAPH
+0xB24D 0x7772 #CJK UNIFIED IDEOGRAPH
+0xB24E 0x7773 #CJK UNIFIED IDEOGRAPH
+0xB24F 0x7774 #CJK UNIFIED IDEOGRAPH
+0xB250 0x7775 #CJK UNIFIED IDEOGRAPH
+0xB251 0x7776 #CJK UNIFIED IDEOGRAPH
+0xB252 0x7777 #CJK UNIFIED IDEOGRAPH
+0xB253 0x7778 #CJK UNIFIED IDEOGRAPH
+0xB254 0x777A #CJK UNIFIED IDEOGRAPH
+0xB255 0x777B #CJK UNIFIED IDEOGRAPH
+0xB256 0x777C #CJK UNIFIED IDEOGRAPH
+0xB257 0x7781 #CJK UNIFIED IDEOGRAPH
+0xB258 0x7782 #CJK UNIFIED IDEOGRAPH
+0xB259 0x7783 #CJK UNIFIED IDEOGRAPH
+0xB25A 0x7786 #CJK UNIFIED IDEOGRAPH
+0xB25B 0x7787 #CJK UNIFIED IDEOGRAPH
+0xB25C 0x7788 #CJK UNIFIED IDEOGRAPH
+0xB25D 0x7789 #CJK UNIFIED IDEOGRAPH
+0xB25E 0x778A #CJK UNIFIED IDEOGRAPH
+0xB25F 0x778B #CJK UNIFIED IDEOGRAPH
+0xB260 0x778F #CJK UNIFIED IDEOGRAPH
+0xB261 0x7790 #CJK UNIFIED IDEOGRAPH
+0xB262 0x7793 #CJK UNIFIED IDEOGRAPH
+0xB263 0x7794 #CJK UNIFIED IDEOGRAPH
+0xB264 0x7795 #CJK UNIFIED IDEOGRAPH
+0xB265 0x7796 #CJK UNIFIED IDEOGRAPH
+0xB266 0x7797 #CJK UNIFIED IDEOGRAPH
+0xB267 0x7798 #CJK UNIFIED IDEOGRAPH
+0xB268 0x7799 #CJK UNIFIED IDEOGRAPH
+0xB269 0x779A #CJK UNIFIED IDEOGRAPH
+0xB26A 0x779B #CJK UNIFIED IDEOGRAPH
+0xB26B 0x779C #CJK UNIFIED IDEOGRAPH
+0xB26C 0x779D #CJK UNIFIED IDEOGRAPH
+0xB26D 0x779E #CJK UNIFIED IDEOGRAPH
+0xB26E 0x77A1 #CJK UNIFIED IDEOGRAPH
+0xB26F 0x77A3 #CJK UNIFIED IDEOGRAPH
+0xB270 0x77A4 #CJK UNIFIED IDEOGRAPH
+0xB271 0x77A6 #CJK UNIFIED IDEOGRAPH
+0xB272 0x77A8 #CJK UNIFIED IDEOGRAPH
+0xB273 0x77AB #CJK UNIFIED IDEOGRAPH
+0xB274 0x77AD #CJK UNIFIED IDEOGRAPH
+0xB275 0x77AE #CJK UNIFIED IDEOGRAPH
+0xB276 0x77AF #CJK UNIFIED IDEOGRAPH
+0xB277 0x77B1 #CJK UNIFIED IDEOGRAPH
+0xB278 0x77B2 #CJK UNIFIED IDEOGRAPH
+0xB279 0x77B4 #CJK UNIFIED IDEOGRAPH
+0xB27A 0x77B6 #CJK UNIFIED IDEOGRAPH
+0xB27B 0x77B7 #CJK UNIFIED IDEOGRAPH
+0xB27C 0x77B8 #CJK UNIFIED IDEOGRAPH
+0xB27D 0x77B9 #CJK UNIFIED IDEOGRAPH
+0xB27E 0x77BA #CJK UNIFIED IDEOGRAPH
+0xB280 0x77BC #CJK UNIFIED IDEOGRAPH
+0xB281 0x77BE #CJK UNIFIED IDEOGRAPH
+0xB282 0x77C0 #CJK UNIFIED IDEOGRAPH
+0xB283 0x77C1 #CJK UNIFIED IDEOGRAPH
+0xB284 0x77C2 #CJK UNIFIED IDEOGRAPH
+0xB285 0x77C3 #CJK UNIFIED IDEOGRAPH
+0xB286 0x77C4 #CJK UNIFIED IDEOGRAPH
+0xB287 0x77C5 #CJK UNIFIED IDEOGRAPH
+0xB288 0x77C6 #CJK UNIFIED IDEOGRAPH
+0xB289 0x77C7 #CJK UNIFIED IDEOGRAPH
+0xB28A 0x77C8 #CJK UNIFIED IDEOGRAPH
+0xB28B 0x77C9 #CJK UNIFIED IDEOGRAPH
+0xB28C 0x77CA #CJK UNIFIED IDEOGRAPH
+0xB28D 0x77CB #CJK UNIFIED IDEOGRAPH
+0xB28E 0x77CC #CJK UNIFIED IDEOGRAPH
+0xB28F 0x77CE #CJK UNIFIED IDEOGRAPH
+0xB290 0x77CF #CJK UNIFIED IDEOGRAPH
+0xB291 0x77D0 #CJK UNIFIED IDEOGRAPH
+0xB292 0x77D1 #CJK UNIFIED IDEOGRAPH
+0xB293 0x77D2 #CJK UNIFIED IDEOGRAPH
+0xB294 0x77D3 #CJK UNIFIED IDEOGRAPH
+0xB295 0x77D4 #CJK UNIFIED IDEOGRAPH
+0xB296 0x77D5 #CJK UNIFIED IDEOGRAPH
+0xB297 0x77D6 #CJK UNIFIED IDEOGRAPH
+0xB298 0x77D8 #CJK UNIFIED IDEOGRAPH
+0xB299 0x77D9 #CJK UNIFIED IDEOGRAPH
+0xB29A 0x77DA #CJK UNIFIED IDEOGRAPH
+0xB29B 0x77DD #CJK UNIFIED IDEOGRAPH
+0xB29C 0x77DE #CJK UNIFIED IDEOGRAPH
+0xB29D 0x77DF #CJK UNIFIED IDEOGRAPH
+0xB29E 0x77E0 #CJK UNIFIED IDEOGRAPH
+0xB29F 0x77E1 #CJK UNIFIED IDEOGRAPH
+0xB2A0 0x77E4 #CJK UNIFIED IDEOGRAPH
+0xB2A1 0x75C5 #CJK UNIFIED IDEOGRAPH
+0xB2A2 0x5E76 #CJK UNIFIED IDEOGRAPH
+0xB2A3 0x73BB #CJK UNIFIED IDEOGRAPH
+0xB2A4 0x83E0 #CJK UNIFIED IDEOGRAPH
+0xB2A5 0x64AD #CJK UNIFIED IDEOGRAPH
+0xB2A6 0x62E8 #CJK UNIFIED IDEOGRAPH
+0xB2A7 0x94B5 #CJK UNIFIED IDEOGRAPH
+0xB2A8 0x6CE2 #CJK UNIFIED IDEOGRAPH
+0xB2A9 0x535A #CJK UNIFIED IDEOGRAPH
+0xB2AA 0x52C3 #CJK UNIFIED IDEOGRAPH
+0xB2AB 0x640F #CJK UNIFIED IDEOGRAPH
+0xB2AC 0x94C2 #CJK UNIFIED IDEOGRAPH
+0xB2AD 0x7B94 #CJK UNIFIED IDEOGRAPH
+0xB2AE 0x4F2F #CJK UNIFIED IDEOGRAPH
+0xB2AF 0x5E1B #CJK UNIFIED IDEOGRAPH
+0xB2B0 0x8236 #CJK UNIFIED IDEOGRAPH
+0xB2B1 0x8116 #CJK UNIFIED IDEOGRAPH
+0xB2B2 0x818A #CJK UNIFIED IDEOGRAPH
+0xB2B3 0x6E24 #CJK UNIFIED IDEOGRAPH
+0xB2B4 0x6CCA #CJK UNIFIED IDEOGRAPH
+0xB2B5 0x9A73 #CJK UNIFIED IDEOGRAPH
+0xB2B6 0x6355 #CJK UNIFIED IDEOGRAPH
+0xB2B7 0x535C #CJK UNIFIED IDEOGRAPH
+0xB2B8 0x54FA #CJK UNIFIED IDEOGRAPH
+0xB2B9 0x8865 #CJK UNIFIED IDEOGRAPH
+0xB2BA 0x57E0 #CJK UNIFIED IDEOGRAPH
+0xB2BB 0x4E0D #CJK UNIFIED IDEOGRAPH
+0xB2BC 0x5E03 #CJK UNIFIED IDEOGRAPH
+0xB2BD 0x6B65 #CJK UNIFIED IDEOGRAPH
+0xB2BE 0x7C3F #CJK UNIFIED IDEOGRAPH
+0xB2BF 0x90E8 #CJK UNIFIED IDEOGRAPH
+0xB2C0 0x6016 #CJK UNIFIED IDEOGRAPH
+0xB2C1 0x64E6 #CJK UNIFIED IDEOGRAPH
+0xB2C2 0x731C #CJK UNIFIED IDEOGRAPH
+0xB2C3 0x88C1 #CJK UNIFIED IDEOGRAPH
+0xB2C4 0x6750 #CJK UNIFIED IDEOGRAPH
+0xB2C5 0x624D #CJK UNIFIED IDEOGRAPH
+0xB2C6 0x8D22 #CJK UNIFIED IDEOGRAPH
+0xB2C7 0x776C #CJK UNIFIED IDEOGRAPH
+0xB2C8 0x8E29 #CJK UNIFIED IDEOGRAPH
+0xB2C9 0x91C7 #CJK UNIFIED IDEOGRAPH
+0xB2CA 0x5F69 #CJK UNIFIED IDEOGRAPH
+0xB2CB 0x83DC #CJK UNIFIED IDEOGRAPH
+0xB2CC 0x8521 #CJK UNIFIED IDEOGRAPH
+0xB2CD 0x9910 #CJK UNIFIED IDEOGRAPH
+0xB2CE 0x53C2 #CJK UNIFIED IDEOGRAPH
+0xB2CF 0x8695 #CJK UNIFIED IDEOGRAPH
+0xB2D0 0x6B8B #CJK UNIFIED IDEOGRAPH
+0xB2D1 0x60ED #CJK UNIFIED IDEOGRAPH
+0xB2D2 0x60E8 #CJK UNIFIED IDEOGRAPH
+0xB2D3 0x707F #CJK UNIFIED IDEOGRAPH
+0xB2D4 0x82CD #CJK UNIFIED IDEOGRAPH
+0xB2D5 0x8231 #CJK UNIFIED IDEOGRAPH
+0xB2D6 0x4ED3 #CJK UNIFIED IDEOGRAPH
+0xB2D7 0x6CA7 #CJK UNIFIED IDEOGRAPH
+0xB2D8 0x85CF #CJK UNIFIED IDEOGRAPH
+0xB2D9 0x64CD #CJK UNIFIED IDEOGRAPH
+0xB2DA 0x7CD9 #CJK UNIFIED IDEOGRAPH
+0xB2DB 0x69FD #CJK UNIFIED IDEOGRAPH
+0xB2DC 0x66F9 #CJK UNIFIED IDEOGRAPH
+0xB2DD 0x8349 #CJK UNIFIED IDEOGRAPH
+0xB2DE 0x5395 #CJK UNIFIED IDEOGRAPH
+0xB2DF 0x7B56 #CJK UNIFIED IDEOGRAPH
+0xB2E0 0x4FA7 #CJK UNIFIED IDEOGRAPH
+0xB2E1 0x518C #CJK UNIFIED IDEOGRAPH
+0xB2E2 0x6D4B #CJK UNIFIED IDEOGRAPH
+0xB2E3 0x5C42 #CJK UNIFIED IDEOGRAPH
+0xB2E4 0x8E6D #CJK UNIFIED IDEOGRAPH
+0xB2E5 0x63D2 #CJK UNIFIED IDEOGRAPH
+0xB2E6 0x53C9 #CJK UNIFIED IDEOGRAPH
+0xB2E7 0x832C #CJK UNIFIED IDEOGRAPH
+0xB2E8 0x8336 #CJK UNIFIED IDEOGRAPH
+0xB2E9 0x67E5 #CJK UNIFIED IDEOGRAPH
+0xB2EA 0x78B4 #CJK UNIFIED IDEOGRAPH
+0xB2EB 0x643D #CJK UNIFIED IDEOGRAPH
+0xB2EC 0x5BDF #CJK UNIFIED IDEOGRAPH
+0xB2ED 0x5C94 #CJK UNIFIED IDEOGRAPH
+0xB2EE 0x5DEE #CJK UNIFIED IDEOGRAPH
+0xB2EF 0x8BE7 #CJK UNIFIED IDEOGRAPH
+0xB2F0 0x62C6 #CJK UNIFIED IDEOGRAPH
+0xB2F1 0x67F4 #CJK UNIFIED IDEOGRAPH
+0xB2F2 0x8C7A #CJK UNIFIED IDEOGRAPH
+0xB2F3 0x6400 #CJK UNIFIED IDEOGRAPH
+0xB2F4 0x63BA #CJK UNIFIED IDEOGRAPH
+0xB2F5 0x8749 #CJK UNIFIED IDEOGRAPH
+0xB2F6 0x998B #CJK UNIFIED IDEOGRAPH
+0xB2F7 0x8C17 #CJK UNIFIED IDEOGRAPH
+0xB2F8 0x7F20 #CJK UNIFIED IDEOGRAPH
+0xB2F9 0x94F2 #CJK UNIFIED IDEOGRAPH
+0xB2FA 0x4EA7 #CJK UNIFIED IDEOGRAPH
+0xB2FB 0x9610 #CJK UNIFIED IDEOGRAPH
+0xB2FC 0x98A4 #CJK UNIFIED IDEOGRAPH
+0xB2FD 0x660C #CJK UNIFIED IDEOGRAPH
+0xB2FE 0x7316 #CJK UNIFIED IDEOGRAPH
+0xB340 0x77E6 #CJK UNIFIED IDEOGRAPH
+0xB341 0x77E8 #CJK UNIFIED IDEOGRAPH
+0xB342 0x77EA #CJK UNIFIED IDEOGRAPH
+0xB343 0x77EF #CJK UNIFIED IDEOGRAPH
+0xB344 0x77F0 #CJK UNIFIED IDEOGRAPH
+0xB345 0x77F1 #CJK UNIFIED IDEOGRAPH
+0xB346 0x77F2 #CJK UNIFIED IDEOGRAPH
+0xB347 0x77F4 #CJK UNIFIED IDEOGRAPH
+0xB348 0x77F5 #CJK UNIFIED IDEOGRAPH
+0xB349 0x77F7 #CJK UNIFIED IDEOGRAPH
+0xB34A 0x77F9 #CJK UNIFIED IDEOGRAPH
+0xB34B 0x77FA #CJK UNIFIED IDEOGRAPH
+0xB34C 0x77FB #CJK UNIFIED IDEOGRAPH
+0xB34D 0x77FC #CJK UNIFIED IDEOGRAPH
+0xB34E 0x7803 #CJK UNIFIED IDEOGRAPH
+0xB34F 0x7804 #CJK UNIFIED IDEOGRAPH
+0xB350 0x7805 #CJK UNIFIED IDEOGRAPH
+0xB351 0x7806 #CJK UNIFIED IDEOGRAPH
+0xB352 0x7807 #CJK UNIFIED IDEOGRAPH
+0xB353 0x7808 #CJK UNIFIED IDEOGRAPH
+0xB354 0x780A #CJK UNIFIED IDEOGRAPH
+0xB355 0x780B #CJK UNIFIED IDEOGRAPH
+0xB356 0x780E #CJK UNIFIED IDEOGRAPH
+0xB357 0x780F #CJK UNIFIED IDEOGRAPH
+0xB358 0x7810 #CJK UNIFIED IDEOGRAPH
+0xB359 0x7813 #CJK UNIFIED IDEOGRAPH
+0xB35A 0x7815 #CJK UNIFIED IDEOGRAPH
+0xB35B 0x7819 #CJK UNIFIED IDEOGRAPH
+0xB35C 0x781B #CJK UNIFIED IDEOGRAPH
+0xB35D 0x781E #CJK UNIFIED IDEOGRAPH
+0xB35E 0x7820 #CJK UNIFIED IDEOGRAPH
+0xB35F 0x7821 #CJK UNIFIED IDEOGRAPH
+0xB360 0x7822 #CJK UNIFIED IDEOGRAPH
+0xB361 0x7824 #CJK UNIFIED IDEOGRAPH
+0xB362 0x7828 #CJK UNIFIED IDEOGRAPH
+0xB363 0x782A #CJK UNIFIED IDEOGRAPH
+0xB364 0x782B #CJK UNIFIED IDEOGRAPH
+0xB365 0x782E #CJK UNIFIED IDEOGRAPH
+0xB366 0x782F #CJK UNIFIED IDEOGRAPH
+0xB367 0x7831 #CJK UNIFIED IDEOGRAPH
+0xB368 0x7832 #CJK UNIFIED IDEOGRAPH
+0xB369 0x7833 #CJK UNIFIED IDEOGRAPH
+0xB36A 0x7835 #CJK UNIFIED IDEOGRAPH
+0xB36B 0x7836 #CJK UNIFIED IDEOGRAPH
+0xB36C 0x783D #CJK UNIFIED IDEOGRAPH
+0xB36D 0x783F #CJK UNIFIED IDEOGRAPH
+0xB36E 0x7841 #CJK UNIFIED IDEOGRAPH
+0xB36F 0x7842 #CJK UNIFIED IDEOGRAPH
+0xB370 0x7843 #CJK UNIFIED IDEOGRAPH
+0xB371 0x7844 #CJK UNIFIED IDEOGRAPH
+0xB372 0x7846 #CJK UNIFIED IDEOGRAPH
+0xB373 0x7848 #CJK UNIFIED IDEOGRAPH
+0xB374 0x7849 #CJK UNIFIED IDEOGRAPH
+0xB375 0x784A #CJK UNIFIED IDEOGRAPH
+0xB376 0x784B #CJK UNIFIED IDEOGRAPH
+0xB377 0x784D #CJK UNIFIED IDEOGRAPH
+0xB378 0x784F #CJK UNIFIED IDEOGRAPH
+0xB379 0x7851 #CJK UNIFIED IDEOGRAPH
+0xB37A 0x7853 #CJK UNIFIED IDEOGRAPH
+0xB37B 0x7854 #CJK UNIFIED IDEOGRAPH
+0xB37C 0x7858 #CJK UNIFIED IDEOGRAPH
+0xB37D 0x7859 #CJK UNIFIED IDEOGRAPH
+0xB37E 0x785A #CJK UNIFIED IDEOGRAPH
+0xB380 0x785B #CJK UNIFIED IDEOGRAPH
+0xB381 0x785C #CJK UNIFIED IDEOGRAPH
+0xB382 0x785E #CJK UNIFIED IDEOGRAPH
+0xB383 0x785F #CJK UNIFIED IDEOGRAPH
+0xB384 0x7860 #CJK UNIFIED IDEOGRAPH
+0xB385 0x7861 #CJK UNIFIED IDEOGRAPH
+0xB386 0x7862 #CJK UNIFIED IDEOGRAPH
+0xB387 0x7863 #CJK UNIFIED IDEOGRAPH
+0xB388 0x7864 #CJK UNIFIED IDEOGRAPH
+0xB389 0x7865 #CJK UNIFIED IDEOGRAPH
+0xB38A 0x7866 #CJK UNIFIED IDEOGRAPH
+0xB38B 0x7867 #CJK UNIFIED IDEOGRAPH
+0xB38C 0x7868 #CJK UNIFIED IDEOGRAPH
+0xB38D 0x7869 #CJK UNIFIED IDEOGRAPH
+0xB38E 0x786F #CJK UNIFIED IDEOGRAPH
+0xB38F 0x7870 #CJK UNIFIED IDEOGRAPH
+0xB390 0x7871 #CJK UNIFIED IDEOGRAPH
+0xB391 0x7872 #CJK UNIFIED IDEOGRAPH
+0xB392 0x7873 #CJK UNIFIED IDEOGRAPH
+0xB393 0x7874 #CJK UNIFIED IDEOGRAPH
+0xB394 0x7875 #CJK UNIFIED IDEOGRAPH
+0xB395 0x7876 #CJK UNIFIED IDEOGRAPH
+0xB396 0x7878 #CJK UNIFIED IDEOGRAPH
+0xB397 0x7879 #CJK UNIFIED IDEOGRAPH
+0xB398 0x787A #CJK UNIFIED IDEOGRAPH
+0xB399 0x787B #CJK UNIFIED IDEOGRAPH
+0xB39A 0x787D #CJK UNIFIED IDEOGRAPH
+0xB39B 0x787E #CJK UNIFIED IDEOGRAPH
+0xB39C 0x787F #CJK UNIFIED IDEOGRAPH
+0xB39D 0x7880 #CJK UNIFIED IDEOGRAPH
+0xB39E 0x7881 #CJK UNIFIED IDEOGRAPH
+0xB39F 0x7882 #CJK UNIFIED IDEOGRAPH
+0xB3A0 0x7883 #CJK UNIFIED IDEOGRAPH
+0xB3A1 0x573A #CJK UNIFIED IDEOGRAPH
+0xB3A2 0x5C1D #CJK UNIFIED IDEOGRAPH
+0xB3A3 0x5E38 #CJK UNIFIED IDEOGRAPH
+0xB3A4 0x957F #CJK UNIFIED IDEOGRAPH
+0xB3A5 0x507F #CJK UNIFIED IDEOGRAPH
+0xB3A6 0x80A0 #CJK UNIFIED IDEOGRAPH
+0xB3A7 0x5382 #CJK UNIFIED IDEOGRAPH
+0xB3A8 0x655E #CJK UNIFIED IDEOGRAPH
+0xB3A9 0x7545 #CJK UNIFIED IDEOGRAPH
+0xB3AA 0x5531 #CJK UNIFIED IDEOGRAPH
+0xB3AB 0x5021 #CJK UNIFIED IDEOGRAPH
+0xB3AC 0x8D85 #CJK UNIFIED IDEOGRAPH
+0xB3AD 0x6284 #CJK UNIFIED IDEOGRAPH
+0xB3AE 0x949E #CJK UNIFIED IDEOGRAPH
+0xB3AF 0x671D #CJK UNIFIED IDEOGRAPH
+0xB3B0 0x5632 #CJK UNIFIED IDEOGRAPH
+0xB3B1 0x6F6E #CJK UNIFIED IDEOGRAPH
+0xB3B2 0x5DE2 #CJK UNIFIED IDEOGRAPH
+0xB3B3 0x5435 #CJK UNIFIED IDEOGRAPH
+0xB3B4 0x7092 #CJK UNIFIED IDEOGRAPH
+0xB3B5 0x8F66 #CJK UNIFIED IDEOGRAPH
+0xB3B6 0x626F #CJK UNIFIED IDEOGRAPH
+0xB3B7 0x64A4 #CJK UNIFIED IDEOGRAPH
+0xB3B8 0x63A3 #CJK UNIFIED IDEOGRAPH
+0xB3B9 0x5F7B #CJK UNIFIED IDEOGRAPH
+0xB3BA 0x6F88 #CJK UNIFIED IDEOGRAPH
+0xB3BB 0x90F4 #CJK UNIFIED IDEOGRAPH
+0xB3BC 0x81E3 #CJK UNIFIED IDEOGRAPH
+0xB3BD 0x8FB0 #CJK UNIFIED IDEOGRAPH
+0xB3BE 0x5C18 #CJK UNIFIED IDEOGRAPH
+0xB3BF 0x6668 #CJK UNIFIED IDEOGRAPH
+0xB3C0 0x5FF1 #CJK UNIFIED IDEOGRAPH
+0xB3C1 0x6C89 #CJK UNIFIED IDEOGRAPH
+0xB3C2 0x9648 #CJK UNIFIED IDEOGRAPH
+0xB3C3 0x8D81 #CJK UNIFIED IDEOGRAPH
+0xB3C4 0x886C #CJK UNIFIED IDEOGRAPH
+0xB3C5 0x6491 #CJK UNIFIED IDEOGRAPH
+0xB3C6 0x79F0 #CJK UNIFIED IDEOGRAPH
+0xB3C7 0x57CE #CJK UNIFIED IDEOGRAPH
+0xB3C8 0x6A59 #CJK UNIFIED IDEOGRAPH
+0xB3C9 0x6210 #CJK UNIFIED IDEOGRAPH
+0xB3CA 0x5448 #CJK UNIFIED IDEOGRAPH
+0xB3CB 0x4E58 #CJK UNIFIED IDEOGRAPH
+0xB3CC 0x7A0B #CJK UNIFIED IDEOGRAPH
+0xB3CD 0x60E9 #CJK UNIFIED IDEOGRAPH
+0xB3CE 0x6F84 #CJK UNIFIED IDEOGRAPH
+0xB3CF 0x8BDA #CJK UNIFIED IDEOGRAPH
+0xB3D0 0x627F #CJK UNIFIED IDEOGRAPH
+0xB3D1 0x901E #CJK UNIFIED IDEOGRAPH
+0xB3D2 0x9A8B #CJK UNIFIED IDEOGRAPH
+0xB3D3 0x79E4 #CJK UNIFIED IDEOGRAPH
+0xB3D4 0x5403 #CJK UNIFIED IDEOGRAPH
+0xB3D5 0x75F4 #CJK UNIFIED IDEOGRAPH
+0xB3D6 0x6301 #CJK UNIFIED IDEOGRAPH
+0xB3D7 0x5319 #CJK UNIFIED IDEOGRAPH
+0xB3D8 0x6C60 #CJK UNIFIED IDEOGRAPH
+0xB3D9 0x8FDF #CJK UNIFIED IDEOGRAPH
+0xB3DA 0x5F1B #CJK UNIFIED IDEOGRAPH
+0xB3DB 0x9A70 #CJK UNIFIED IDEOGRAPH
+0xB3DC 0x803B #CJK UNIFIED IDEOGRAPH
+0xB3DD 0x9F7F #CJK UNIFIED IDEOGRAPH
+0xB3DE 0x4F88 #CJK UNIFIED IDEOGRAPH
+0xB3DF 0x5C3A #CJK UNIFIED IDEOGRAPH
+0xB3E0 0x8D64 #CJK UNIFIED IDEOGRAPH
+0xB3E1 0x7FC5 #CJK UNIFIED IDEOGRAPH
+0xB3E2 0x65A5 #CJK UNIFIED IDEOGRAPH
+0xB3E3 0x70BD #CJK UNIFIED IDEOGRAPH
+0xB3E4 0x5145 #CJK UNIFIED IDEOGRAPH
+0xB3E5 0x51B2 #CJK UNIFIED IDEOGRAPH
+0xB3E6 0x866B #CJK UNIFIED IDEOGRAPH
+0xB3E7 0x5D07 #CJK UNIFIED IDEOGRAPH
+0xB3E8 0x5BA0 #CJK UNIFIED IDEOGRAPH
+0xB3E9 0x62BD #CJK UNIFIED IDEOGRAPH
+0xB3EA 0x916C #CJK UNIFIED IDEOGRAPH
+0xB3EB 0x7574 #CJK UNIFIED IDEOGRAPH
+0xB3EC 0x8E0C #CJK UNIFIED IDEOGRAPH
+0xB3ED 0x7A20 #CJK UNIFIED IDEOGRAPH
+0xB3EE 0x6101 #CJK UNIFIED IDEOGRAPH
+0xB3EF 0x7B79 #CJK UNIFIED IDEOGRAPH
+0xB3F0 0x4EC7 #CJK UNIFIED IDEOGRAPH
+0xB3F1 0x7EF8 #CJK UNIFIED IDEOGRAPH
+0xB3F2 0x7785 #CJK UNIFIED IDEOGRAPH
+0xB3F3 0x4E11 #CJK UNIFIED IDEOGRAPH
+0xB3F4 0x81ED #CJK UNIFIED IDEOGRAPH
+0xB3F5 0x521D #CJK UNIFIED IDEOGRAPH
+0xB3F6 0x51FA #CJK UNIFIED IDEOGRAPH
+0xB3F7 0x6A71 #CJK UNIFIED IDEOGRAPH
+0xB3F8 0x53A8 #CJK UNIFIED IDEOGRAPH
+0xB3F9 0x8E87 #CJK UNIFIED IDEOGRAPH
+0xB3FA 0x9504 #CJK UNIFIED IDEOGRAPH
+0xB3FB 0x96CF #CJK UNIFIED IDEOGRAPH
+0xB3FC 0x6EC1 #CJK UNIFIED IDEOGRAPH
+0xB3FD 0x9664 #CJK UNIFIED IDEOGRAPH
+0xB3FE 0x695A #CJK UNIFIED IDEOGRAPH
+0xB440 0x7884 #CJK UNIFIED IDEOGRAPH
+0xB441 0x7885 #CJK UNIFIED IDEOGRAPH
+0xB442 0x7886 #CJK UNIFIED IDEOGRAPH
+0xB443 0x7888 #CJK UNIFIED IDEOGRAPH
+0xB444 0x788A #CJK UNIFIED IDEOGRAPH
+0xB445 0x788B #CJK UNIFIED IDEOGRAPH
+0xB446 0x788F #CJK UNIFIED IDEOGRAPH
+0xB447 0x7890 #CJK UNIFIED IDEOGRAPH
+0xB448 0x7892 #CJK UNIFIED IDEOGRAPH
+0xB449 0x7894 #CJK UNIFIED IDEOGRAPH
+0xB44A 0x7895 #CJK UNIFIED IDEOGRAPH
+0xB44B 0x7896 #CJK UNIFIED IDEOGRAPH
+0xB44C 0x7899 #CJK UNIFIED IDEOGRAPH
+0xB44D 0x789D #CJK UNIFIED IDEOGRAPH
+0xB44E 0x789E #CJK UNIFIED IDEOGRAPH
+0xB44F 0x78A0 #CJK UNIFIED IDEOGRAPH
+0xB450 0x78A2 #CJK UNIFIED IDEOGRAPH
+0xB451 0x78A4 #CJK UNIFIED IDEOGRAPH
+0xB452 0x78A6 #CJK UNIFIED IDEOGRAPH
+0xB453 0x78A8 #CJK UNIFIED IDEOGRAPH
+0xB454 0x78A9 #CJK UNIFIED IDEOGRAPH
+0xB455 0x78AA #CJK UNIFIED IDEOGRAPH
+0xB456 0x78AB #CJK UNIFIED IDEOGRAPH
+0xB457 0x78AC #CJK UNIFIED IDEOGRAPH
+0xB458 0x78AD #CJK UNIFIED IDEOGRAPH
+0xB459 0x78AE #CJK UNIFIED IDEOGRAPH
+0xB45A 0x78AF #CJK UNIFIED IDEOGRAPH
+0xB45B 0x78B5 #CJK UNIFIED IDEOGRAPH
+0xB45C 0x78B6 #CJK UNIFIED IDEOGRAPH
+0xB45D 0x78B7 #CJK UNIFIED IDEOGRAPH
+0xB45E 0x78B8 #CJK UNIFIED IDEOGRAPH
+0xB45F 0x78BA #CJK UNIFIED IDEOGRAPH
+0xB460 0x78BB #CJK UNIFIED IDEOGRAPH
+0xB461 0x78BC #CJK UNIFIED IDEOGRAPH
+0xB462 0x78BD #CJK UNIFIED IDEOGRAPH
+0xB463 0x78BF #CJK UNIFIED IDEOGRAPH
+0xB464 0x78C0 #CJK UNIFIED IDEOGRAPH
+0xB465 0x78C2 #CJK UNIFIED IDEOGRAPH
+0xB466 0x78C3 #CJK UNIFIED IDEOGRAPH
+0xB467 0x78C4 #CJK UNIFIED IDEOGRAPH
+0xB468 0x78C6 #CJK UNIFIED IDEOGRAPH
+0xB469 0x78C7 #CJK UNIFIED IDEOGRAPH
+0xB46A 0x78C8 #CJK UNIFIED IDEOGRAPH
+0xB46B 0x78CC #CJK UNIFIED IDEOGRAPH
+0xB46C 0x78CD #CJK UNIFIED IDEOGRAPH
+0xB46D 0x78CE #CJK UNIFIED IDEOGRAPH
+0xB46E 0x78CF #CJK UNIFIED IDEOGRAPH
+0xB46F 0x78D1 #CJK UNIFIED IDEOGRAPH
+0xB470 0x78D2 #CJK UNIFIED IDEOGRAPH
+0xB471 0x78D3 #CJK UNIFIED IDEOGRAPH
+0xB472 0x78D6 #CJK UNIFIED IDEOGRAPH
+0xB473 0x78D7 #CJK UNIFIED IDEOGRAPH
+0xB474 0x78D8 #CJK UNIFIED IDEOGRAPH
+0xB475 0x78DA #CJK UNIFIED IDEOGRAPH
+0xB476 0x78DB #CJK UNIFIED IDEOGRAPH
+0xB477 0x78DC #CJK UNIFIED IDEOGRAPH
+0xB478 0x78DD #CJK UNIFIED IDEOGRAPH
+0xB479 0x78DE #CJK UNIFIED IDEOGRAPH
+0xB47A 0x78DF #CJK UNIFIED IDEOGRAPH
+0xB47B 0x78E0 #CJK UNIFIED IDEOGRAPH
+0xB47C 0x78E1 #CJK UNIFIED IDEOGRAPH
+0xB47D 0x78E2 #CJK UNIFIED IDEOGRAPH
+0xB47E 0x78E3 #CJK UNIFIED IDEOGRAPH
+0xB480 0x78E4 #CJK UNIFIED IDEOGRAPH
+0xB481 0x78E5 #CJK UNIFIED IDEOGRAPH
+0xB482 0x78E6 #CJK UNIFIED IDEOGRAPH
+0xB483 0x78E7 #CJK UNIFIED IDEOGRAPH
+0xB484 0x78E9 #CJK UNIFIED IDEOGRAPH
+0xB485 0x78EA #CJK UNIFIED IDEOGRAPH
+0xB486 0x78EB #CJK UNIFIED IDEOGRAPH
+0xB487 0x78ED #CJK UNIFIED IDEOGRAPH
+0xB488 0x78EE #CJK UNIFIED IDEOGRAPH
+0xB489 0x78EF #CJK UNIFIED IDEOGRAPH
+0xB48A 0x78F0 #CJK UNIFIED IDEOGRAPH
+0xB48B 0x78F1 #CJK UNIFIED IDEOGRAPH
+0xB48C 0x78F3 #CJK UNIFIED IDEOGRAPH
+0xB48D 0x78F5 #CJK UNIFIED IDEOGRAPH
+0xB48E 0x78F6 #CJK UNIFIED IDEOGRAPH
+0xB48F 0x78F8 #CJK UNIFIED IDEOGRAPH
+0xB490 0x78F9 #CJK UNIFIED IDEOGRAPH
+0xB491 0x78FB #CJK UNIFIED IDEOGRAPH
+0xB492 0x78FC #CJK UNIFIED IDEOGRAPH
+0xB493 0x78FD #CJK UNIFIED IDEOGRAPH
+0xB494 0x78FE #CJK UNIFIED IDEOGRAPH
+0xB495 0x78FF #CJK UNIFIED IDEOGRAPH
+0xB496 0x7900 #CJK UNIFIED IDEOGRAPH
+0xB497 0x7902 #CJK UNIFIED IDEOGRAPH
+0xB498 0x7903 #CJK UNIFIED IDEOGRAPH
+0xB499 0x7904 #CJK UNIFIED IDEOGRAPH
+0xB49A 0x7906 #CJK UNIFIED IDEOGRAPH
+0xB49B 0x7907 #CJK UNIFIED IDEOGRAPH
+0xB49C 0x7908 #CJK UNIFIED IDEOGRAPH
+0xB49D 0x7909 #CJK UNIFIED IDEOGRAPH
+0xB49E 0x790A #CJK UNIFIED IDEOGRAPH
+0xB49F 0x790B #CJK UNIFIED IDEOGRAPH
+0xB4A0 0x790C #CJK UNIFIED IDEOGRAPH
+0xB4A1 0x7840 #CJK UNIFIED IDEOGRAPH
+0xB4A2 0x50A8 #CJK UNIFIED IDEOGRAPH
+0xB4A3 0x77D7 #CJK UNIFIED IDEOGRAPH
+0xB4A4 0x6410 #CJK UNIFIED IDEOGRAPH
+0xB4A5 0x89E6 #CJK UNIFIED IDEOGRAPH
+0xB4A6 0x5904 #CJK UNIFIED IDEOGRAPH
+0xB4A7 0x63E3 #CJK UNIFIED IDEOGRAPH
+0xB4A8 0x5DDD #CJK UNIFIED IDEOGRAPH
+0xB4A9 0x7A7F #CJK UNIFIED IDEOGRAPH
+0xB4AA 0x693D #CJK UNIFIED IDEOGRAPH
+0xB4AB 0x4F20 #CJK UNIFIED IDEOGRAPH
+0xB4AC 0x8239 #CJK UNIFIED IDEOGRAPH
+0xB4AD 0x5598 #CJK UNIFIED IDEOGRAPH
+0xB4AE 0x4E32 #CJK UNIFIED IDEOGRAPH
+0xB4AF 0x75AE #CJK UNIFIED IDEOGRAPH
+0xB4B0 0x7A97 #CJK UNIFIED IDEOGRAPH
+0xB4B1 0x5E62 #CJK UNIFIED IDEOGRAPH
+0xB4B2 0x5E8A #CJK UNIFIED IDEOGRAPH
+0xB4B3 0x95EF #CJK UNIFIED IDEOGRAPH
+0xB4B4 0x521B #CJK UNIFIED IDEOGRAPH
+0xB4B5 0x5439 #CJK UNIFIED IDEOGRAPH
+0xB4B6 0x708A #CJK UNIFIED IDEOGRAPH
+0xB4B7 0x6376 #CJK UNIFIED IDEOGRAPH
+0xB4B8 0x9524 #CJK UNIFIED IDEOGRAPH
+0xB4B9 0x5782 #CJK UNIFIED IDEOGRAPH
+0xB4BA 0x6625 #CJK UNIFIED IDEOGRAPH
+0xB4BB 0x693F #CJK UNIFIED IDEOGRAPH
+0xB4BC 0x9187 #CJK UNIFIED IDEOGRAPH
+0xB4BD 0x5507 #CJK UNIFIED IDEOGRAPH
+0xB4BE 0x6DF3 #CJK UNIFIED IDEOGRAPH
+0xB4BF 0x7EAF #CJK UNIFIED IDEOGRAPH
+0xB4C0 0x8822 #CJK UNIFIED IDEOGRAPH
+0xB4C1 0x6233 #CJK UNIFIED IDEOGRAPH
+0xB4C2 0x7EF0 #CJK UNIFIED IDEOGRAPH
+0xB4C3 0x75B5 #CJK UNIFIED IDEOGRAPH
+0xB4C4 0x8328 #CJK UNIFIED IDEOGRAPH
+0xB4C5 0x78C1 #CJK UNIFIED IDEOGRAPH
+0xB4C6 0x96CC #CJK UNIFIED IDEOGRAPH
+0xB4C7 0x8F9E #CJK UNIFIED IDEOGRAPH
+0xB4C8 0x6148 #CJK UNIFIED IDEOGRAPH
+0xB4C9 0x74F7 #CJK UNIFIED IDEOGRAPH
+0xB4CA 0x8BCD #CJK UNIFIED IDEOGRAPH
+0xB4CB 0x6B64 #CJK UNIFIED IDEOGRAPH
+0xB4CC 0x523A #CJK UNIFIED IDEOGRAPH
+0xB4CD 0x8D50 #CJK UNIFIED IDEOGRAPH
+0xB4CE 0x6B21 #CJK UNIFIED IDEOGRAPH
+0xB4CF 0x806A #CJK UNIFIED IDEOGRAPH
+0xB4D0 0x8471 #CJK UNIFIED IDEOGRAPH
+0xB4D1 0x56F1 #CJK UNIFIED IDEOGRAPH
+0xB4D2 0x5306 #CJK UNIFIED IDEOGRAPH
+0xB4D3 0x4ECE #CJK UNIFIED IDEOGRAPH
+0xB4D4 0x4E1B #CJK UNIFIED IDEOGRAPH
+0xB4D5 0x51D1 #CJK UNIFIED IDEOGRAPH
+0xB4D6 0x7C97 #CJK UNIFIED IDEOGRAPH
+0xB4D7 0x918B #CJK UNIFIED IDEOGRAPH
+0xB4D8 0x7C07 #CJK UNIFIED IDEOGRAPH
+0xB4D9 0x4FC3 #CJK UNIFIED IDEOGRAPH
+0xB4DA 0x8E7F #CJK UNIFIED IDEOGRAPH
+0xB4DB 0x7BE1 #CJK UNIFIED IDEOGRAPH
+0xB4DC 0x7A9C #CJK UNIFIED IDEOGRAPH
+0xB4DD 0x6467 #CJK UNIFIED IDEOGRAPH
+0xB4DE 0x5D14 #CJK UNIFIED IDEOGRAPH
+0xB4DF 0x50AC #CJK UNIFIED IDEOGRAPH
+0xB4E0 0x8106 #CJK UNIFIED IDEOGRAPH
+0xB4E1 0x7601 #CJK UNIFIED IDEOGRAPH
+0xB4E2 0x7CB9 #CJK UNIFIED IDEOGRAPH
+0xB4E3 0x6DEC #CJK UNIFIED IDEOGRAPH
+0xB4E4 0x7FE0 #CJK UNIFIED IDEOGRAPH
+0xB4E5 0x6751 #CJK UNIFIED IDEOGRAPH
+0xB4E6 0x5B58 #CJK UNIFIED IDEOGRAPH
+0xB4E7 0x5BF8 #CJK UNIFIED IDEOGRAPH
+0xB4E8 0x78CB #CJK UNIFIED IDEOGRAPH
+0xB4E9 0x64AE #CJK UNIFIED IDEOGRAPH
+0xB4EA 0x6413 #CJK UNIFIED IDEOGRAPH
+0xB4EB 0x63AA #CJK UNIFIED IDEOGRAPH
+0xB4EC 0x632B #CJK UNIFIED IDEOGRAPH
+0xB4ED 0x9519 #CJK UNIFIED IDEOGRAPH
+0xB4EE 0x642D #CJK UNIFIED IDEOGRAPH
+0xB4EF 0x8FBE #CJK UNIFIED IDEOGRAPH
+0xB4F0 0x7B54 #CJK UNIFIED IDEOGRAPH
+0xB4F1 0x7629 #CJK UNIFIED IDEOGRAPH
+0xB4F2 0x6253 #CJK UNIFIED IDEOGRAPH
+0xB4F3 0x5927 #CJK UNIFIED IDEOGRAPH
+0xB4F4 0x5446 #CJK UNIFIED IDEOGRAPH
+0xB4F5 0x6B79 #CJK UNIFIED IDEOGRAPH
+0xB4F6 0x50A3 #CJK UNIFIED IDEOGRAPH
+0xB4F7 0x6234 #CJK UNIFIED IDEOGRAPH
+0xB4F8 0x5E26 #CJK UNIFIED IDEOGRAPH
+0xB4F9 0x6B86 #CJK UNIFIED IDEOGRAPH
+0xB4FA 0x4EE3 #CJK UNIFIED IDEOGRAPH
+0xB4FB 0x8D37 #CJK UNIFIED IDEOGRAPH
+0xB4FC 0x888B #CJK UNIFIED IDEOGRAPH
+0xB4FD 0x5F85 #CJK UNIFIED IDEOGRAPH
+0xB4FE 0x902E #CJK UNIFIED IDEOGRAPH
+0xB540 0x790D #CJK UNIFIED IDEOGRAPH
+0xB541 0x790E #CJK UNIFIED IDEOGRAPH
+0xB542 0x790F #CJK UNIFIED IDEOGRAPH
+0xB543 0x7910 #CJK UNIFIED IDEOGRAPH
+0xB544 0x7911 #CJK UNIFIED IDEOGRAPH
+0xB545 0x7912 #CJK UNIFIED IDEOGRAPH
+0xB546 0x7914 #CJK UNIFIED IDEOGRAPH
+0xB547 0x7915 #CJK UNIFIED IDEOGRAPH
+0xB548 0x7916 #CJK UNIFIED IDEOGRAPH
+0xB549 0x7917 #CJK UNIFIED IDEOGRAPH
+0xB54A 0x7918 #CJK UNIFIED IDEOGRAPH
+0xB54B 0x7919 #CJK UNIFIED IDEOGRAPH
+0xB54C 0x791A #CJK UNIFIED IDEOGRAPH
+0xB54D 0x791B #CJK UNIFIED IDEOGRAPH
+0xB54E 0x791C #CJK UNIFIED IDEOGRAPH
+0xB54F 0x791D #CJK UNIFIED IDEOGRAPH
+0xB550 0x791F #CJK UNIFIED IDEOGRAPH
+0xB551 0x7920 #CJK UNIFIED IDEOGRAPH
+0xB552 0x7921 #CJK UNIFIED IDEOGRAPH
+0xB553 0x7922 #CJK UNIFIED IDEOGRAPH
+0xB554 0x7923 #CJK UNIFIED IDEOGRAPH
+0xB555 0x7925 #CJK UNIFIED IDEOGRAPH
+0xB556 0x7926 #CJK UNIFIED IDEOGRAPH
+0xB557 0x7927 #CJK UNIFIED IDEOGRAPH
+0xB558 0x7928 #CJK UNIFIED IDEOGRAPH
+0xB559 0x7929 #CJK UNIFIED IDEOGRAPH
+0xB55A 0x792A #CJK UNIFIED IDEOGRAPH
+0xB55B 0x792B #CJK UNIFIED IDEOGRAPH
+0xB55C 0x792C #CJK UNIFIED IDEOGRAPH
+0xB55D 0x792D #CJK UNIFIED IDEOGRAPH
+0xB55E 0x792E #CJK UNIFIED IDEOGRAPH
+0xB55F 0x792F #CJK UNIFIED IDEOGRAPH
+0xB560 0x7930 #CJK UNIFIED IDEOGRAPH
+0xB561 0x7931 #CJK UNIFIED IDEOGRAPH
+0xB562 0x7932 #CJK UNIFIED IDEOGRAPH
+0xB563 0x7933 #CJK UNIFIED IDEOGRAPH
+0xB564 0x7935 #CJK UNIFIED IDEOGRAPH
+0xB565 0x7936 #CJK UNIFIED IDEOGRAPH
+0xB566 0x7937 #CJK UNIFIED IDEOGRAPH
+0xB567 0x7938 #CJK UNIFIED IDEOGRAPH
+0xB568 0x7939 #CJK UNIFIED IDEOGRAPH
+0xB569 0x793D #CJK UNIFIED IDEOGRAPH
+0xB56A 0x793F #CJK UNIFIED IDEOGRAPH
+0xB56B 0x7942 #CJK UNIFIED IDEOGRAPH
+0xB56C 0x7943 #CJK UNIFIED IDEOGRAPH
+0xB56D 0x7944 #CJK UNIFIED IDEOGRAPH
+0xB56E 0x7945 #CJK UNIFIED IDEOGRAPH
+0xB56F 0x7947 #CJK UNIFIED IDEOGRAPH
+0xB570 0x794A #CJK UNIFIED IDEOGRAPH
+0xB571 0x794B #CJK UNIFIED IDEOGRAPH
+0xB572 0x794C #CJK UNIFIED IDEOGRAPH
+0xB573 0x794D #CJK UNIFIED IDEOGRAPH
+0xB574 0x794E #CJK UNIFIED IDEOGRAPH
+0xB575 0x794F #CJK UNIFIED IDEOGRAPH
+0xB576 0x7950 #CJK UNIFIED IDEOGRAPH
+0xB577 0x7951 #CJK UNIFIED IDEOGRAPH
+0xB578 0x7952 #CJK UNIFIED IDEOGRAPH
+0xB579 0x7954 #CJK UNIFIED IDEOGRAPH
+0xB57A 0x7955 #CJK UNIFIED IDEOGRAPH
+0xB57B 0x7958 #CJK UNIFIED IDEOGRAPH
+0xB57C 0x7959 #CJK UNIFIED IDEOGRAPH
+0xB57D 0x7961 #CJK UNIFIED IDEOGRAPH
+0xB57E 0x7963 #CJK UNIFIED IDEOGRAPH
+0xB580 0x7964 #CJK UNIFIED IDEOGRAPH
+0xB581 0x7966 #CJK UNIFIED IDEOGRAPH
+0xB582 0x7969 #CJK UNIFIED IDEOGRAPH
+0xB583 0x796A #CJK UNIFIED IDEOGRAPH
+0xB584 0x796B #CJK UNIFIED IDEOGRAPH
+0xB585 0x796C #CJK UNIFIED IDEOGRAPH
+0xB586 0x796E #CJK UNIFIED IDEOGRAPH
+0xB587 0x7970 #CJK UNIFIED IDEOGRAPH
+0xB588 0x7971 #CJK UNIFIED IDEOGRAPH
+0xB589 0x7972 #CJK UNIFIED IDEOGRAPH
+0xB58A 0x7973 #CJK UNIFIED IDEOGRAPH
+0xB58B 0x7974 #CJK UNIFIED IDEOGRAPH
+0xB58C 0x7975 #CJK UNIFIED IDEOGRAPH
+0xB58D 0x7976 #CJK UNIFIED IDEOGRAPH
+0xB58E 0x7979 #CJK UNIFIED IDEOGRAPH
+0xB58F 0x797B #CJK UNIFIED IDEOGRAPH
+0xB590 0x797C #CJK UNIFIED IDEOGRAPH
+0xB591 0x797D #CJK UNIFIED IDEOGRAPH
+0xB592 0x797E #CJK UNIFIED IDEOGRAPH
+0xB593 0x797F #CJK UNIFIED IDEOGRAPH
+0xB594 0x7982 #CJK UNIFIED IDEOGRAPH
+0xB595 0x7983 #CJK UNIFIED IDEOGRAPH
+0xB596 0x7986 #CJK UNIFIED IDEOGRAPH
+0xB597 0x7987 #CJK UNIFIED IDEOGRAPH
+0xB598 0x7988 #CJK UNIFIED IDEOGRAPH
+0xB599 0x7989 #CJK UNIFIED IDEOGRAPH
+0xB59A 0x798B #CJK UNIFIED IDEOGRAPH
+0xB59B 0x798C #CJK UNIFIED IDEOGRAPH
+0xB59C 0x798D #CJK UNIFIED IDEOGRAPH
+0xB59D 0x798E #CJK UNIFIED IDEOGRAPH
+0xB59E 0x7990 #CJK UNIFIED IDEOGRAPH
+0xB59F 0x7991 #CJK UNIFIED IDEOGRAPH
+0xB5A0 0x7992 #CJK UNIFIED IDEOGRAPH
+0xB5A1 0x6020 #CJK UNIFIED IDEOGRAPH
+0xB5A2 0x803D #CJK UNIFIED IDEOGRAPH
+0xB5A3 0x62C5 #CJK UNIFIED IDEOGRAPH
+0xB5A4 0x4E39 #CJK UNIFIED IDEOGRAPH
+0xB5A5 0x5355 #CJK UNIFIED IDEOGRAPH
+0xB5A6 0x90F8 #CJK UNIFIED IDEOGRAPH
+0xB5A7 0x63B8 #CJK UNIFIED IDEOGRAPH
+0xB5A8 0x80C6 #CJK UNIFIED IDEOGRAPH
+0xB5A9 0x65E6 #CJK UNIFIED IDEOGRAPH
+0xB5AA 0x6C2E #CJK UNIFIED IDEOGRAPH
+0xB5AB 0x4F46 #CJK UNIFIED IDEOGRAPH
+0xB5AC 0x60EE #CJK UNIFIED IDEOGRAPH
+0xB5AD 0x6DE1 #CJK UNIFIED IDEOGRAPH
+0xB5AE 0x8BDE #CJK UNIFIED IDEOGRAPH
+0xB5AF 0x5F39 #CJK UNIFIED IDEOGRAPH
+0xB5B0 0x86CB #CJK UNIFIED IDEOGRAPH
+0xB5B1 0x5F53 #CJK UNIFIED IDEOGRAPH
+0xB5B2 0x6321 #CJK UNIFIED IDEOGRAPH
+0xB5B3 0x515A #CJK UNIFIED IDEOGRAPH
+0xB5B4 0x8361 #CJK UNIFIED IDEOGRAPH
+0xB5B5 0x6863 #CJK UNIFIED IDEOGRAPH
+0xB5B6 0x5200 #CJK UNIFIED IDEOGRAPH
+0xB5B7 0x6363 #CJK UNIFIED IDEOGRAPH
+0xB5B8 0x8E48 #CJK UNIFIED IDEOGRAPH
+0xB5B9 0x5012 #CJK UNIFIED IDEOGRAPH
+0xB5BA 0x5C9B #CJK UNIFIED IDEOGRAPH
+0xB5BB 0x7977 #CJK UNIFIED IDEOGRAPH
+0xB5BC 0x5BFC #CJK UNIFIED IDEOGRAPH
+0xB5BD 0x5230 #CJK UNIFIED IDEOGRAPH
+0xB5BE 0x7A3B #CJK UNIFIED IDEOGRAPH
+0xB5BF 0x60BC #CJK UNIFIED IDEOGRAPH
+0xB5C0 0x9053 #CJK UNIFIED IDEOGRAPH
+0xB5C1 0x76D7 #CJK UNIFIED IDEOGRAPH
+0xB5C2 0x5FB7 #CJK UNIFIED IDEOGRAPH
+0xB5C3 0x5F97 #CJK UNIFIED IDEOGRAPH
+0xB5C4 0x7684 #CJK UNIFIED IDEOGRAPH
+0xB5C5 0x8E6C #CJK UNIFIED IDEOGRAPH
+0xB5C6 0x706F #CJK UNIFIED IDEOGRAPH
+0xB5C7 0x767B #CJK UNIFIED IDEOGRAPH
+0xB5C8 0x7B49 #CJK UNIFIED IDEOGRAPH
+0xB5C9 0x77AA #CJK UNIFIED IDEOGRAPH
+0xB5CA 0x51F3 #CJK UNIFIED IDEOGRAPH
+0xB5CB 0x9093 #CJK UNIFIED IDEOGRAPH
+0xB5CC 0x5824 #CJK UNIFIED IDEOGRAPH
+0xB5CD 0x4F4E #CJK UNIFIED IDEOGRAPH
+0xB5CE 0x6EF4 #CJK UNIFIED IDEOGRAPH
+0xB5CF 0x8FEA #CJK UNIFIED IDEOGRAPH
+0xB5D0 0x654C #CJK UNIFIED IDEOGRAPH
+0xB5D1 0x7B1B #CJK UNIFIED IDEOGRAPH
+0xB5D2 0x72C4 #CJK UNIFIED IDEOGRAPH
+0xB5D3 0x6DA4 #CJK UNIFIED IDEOGRAPH
+0xB5D4 0x7FDF #CJK UNIFIED IDEOGRAPH
+0xB5D5 0x5AE1 #CJK UNIFIED IDEOGRAPH
+0xB5D6 0x62B5 #CJK UNIFIED IDEOGRAPH
+0xB5D7 0x5E95 #CJK UNIFIED IDEOGRAPH
+0xB5D8 0x5730 #CJK UNIFIED IDEOGRAPH
+0xB5D9 0x8482 #CJK UNIFIED IDEOGRAPH
+0xB5DA 0x7B2C #CJK UNIFIED IDEOGRAPH
+0xB5DB 0x5E1D #CJK UNIFIED IDEOGRAPH
+0xB5DC 0x5F1F #CJK UNIFIED IDEOGRAPH
+0xB5DD 0x9012 #CJK UNIFIED IDEOGRAPH
+0xB5DE 0x7F14 #CJK UNIFIED IDEOGRAPH
+0xB5DF 0x98A0 #CJK UNIFIED IDEOGRAPH
+0xB5E0 0x6382 #CJK UNIFIED IDEOGRAPH
+0xB5E1 0x6EC7 #CJK UNIFIED IDEOGRAPH
+0xB5E2 0x7898 #CJK UNIFIED IDEOGRAPH
+0xB5E3 0x70B9 #CJK UNIFIED IDEOGRAPH
+0xB5E4 0x5178 #CJK UNIFIED IDEOGRAPH
+0xB5E5 0x975B #CJK UNIFIED IDEOGRAPH
+0xB5E6 0x57AB #CJK UNIFIED IDEOGRAPH
+0xB5E7 0x7535 #CJK UNIFIED IDEOGRAPH
+0xB5E8 0x4F43 #CJK UNIFIED IDEOGRAPH
+0xB5E9 0x7538 #CJK UNIFIED IDEOGRAPH
+0xB5EA 0x5E97 #CJK UNIFIED IDEOGRAPH
+0xB5EB 0x60E6 #CJK UNIFIED IDEOGRAPH
+0xB5EC 0x5960 #CJK UNIFIED IDEOGRAPH
+0xB5ED 0x6DC0 #CJK UNIFIED IDEOGRAPH
+0xB5EE 0x6BBF #CJK UNIFIED IDEOGRAPH
+0xB5EF 0x7889 #CJK UNIFIED IDEOGRAPH
+0xB5F0 0x53FC #CJK UNIFIED IDEOGRAPH
+0xB5F1 0x96D5 #CJK UNIFIED IDEOGRAPH
+0xB5F2 0x51CB #CJK UNIFIED IDEOGRAPH
+0xB5F3 0x5201 #CJK UNIFIED IDEOGRAPH
+0xB5F4 0x6389 #CJK UNIFIED IDEOGRAPH
+0xB5F5 0x540A #CJK UNIFIED IDEOGRAPH
+0xB5F6 0x9493 #CJK UNIFIED IDEOGRAPH
+0xB5F7 0x8C03 #CJK UNIFIED IDEOGRAPH
+0xB5F8 0x8DCC #CJK UNIFIED IDEOGRAPH
+0xB5F9 0x7239 #CJK UNIFIED IDEOGRAPH
+0xB5FA 0x789F #CJK UNIFIED IDEOGRAPH
+0xB5FB 0x8776 #CJK UNIFIED IDEOGRAPH
+0xB5FC 0x8FED #CJK UNIFIED IDEOGRAPH
+0xB5FD 0x8C0D #CJK UNIFIED IDEOGRAPH
+0xB5FE 0x53E0 #CJK UNIFIED IDEOGRAPH
+0xB640 0x7993 #CJK UNIFIED IDEOGRAPH
+0xB641 0x7994 #CJK UNIFIED IDEOGRAPH
+0xB642 0x7995 #CJK UNIFIED IDEOGRAPH
+0xB643 0x7996 #CJK UNIFIED IDEOGRAPH
+0xB644 0x7997 #CJK UNIFIED IDEOGRAPH
+0xB645 0x7998 #CJK UNIFIED IDEOGRAPH
+0xB646 0x7999 #CJK UNIFIED IDEOGRAPH
+0xB647 0x799B #CJK UNIFIED IDEOGRAPH
+0xB648 0x799C #CJK UNIFIED IDEOGRAPH
+0xB649 0x799D #CJK UNIFIED IDEOGRAPH
+0xB64A 0x799E #CJK UNIFIED IDEOGRAPH
+0xB64B 0x799F #CJK UNIFIED IDEOGRAPH
+0xB64C 0x79A0 #CJK UNIFIED IDEOGRAPH
+0xB64D 0x79A1 #CJK UNIFIED IDEOGRAPH
+0xB64E 0x79A2 #CJK UNIFIED IDEOGRAPH
+0xB64F 0x79A3 #CJK UNIFIED IDEOGRAPH
+0xB650 0x79A4 #CJK UNIFIED IDEOGRAPH
+0xB651 0x79A5 #CJK UNIFIED IDEOGRAPH
+0xB652 0x79A6 #CJK UNIFIED IDEOGRAPH
+0xB653 0x79A8 #CJK UNIFIED IDEOGRAPH
+0xB654 0x79A9 #CJK UNIFIED IDEOGRAPH
+0xB655 0x79AA #CJK UNIFIED IDEOGRAPH
+0xB656 0x79AB #CJK UNIFIED IDEOGRAPH
+0xB657 0x79AC #CJK UNIFIED IDEOGRAPH
+0xB658 0x79AD #CJK UNIFIED IDEOGRAPH
+0xB659 0x79AE #CJK UNIFIED IDEOGRAPH
+0xB65A 0x79AF #CJK UNIFIED IDEOGRAPH
+0xB65B 0x79B0 #CJK UNIFIED IDEOGRAPH
+0xB65C 0x79B1 #CJK UNIFIED IDEOGRAPH
+0xB65D 0x79B2 #CJK UNIFIED IDEOGRAPH
+0xB65E 0x79B4 #CJK UNIFIED IDEOGRAPH
+0xB65F 0x79B5 #CJK UNIFIED IDEOGRAPH
+0xB660 0x79B6 #CJK UNIFIED IDEOGRAPH
+0xB661 0x79B7 #CJK UNIFIED IDEOGRAPH
+0xB662 0x79B8 #CJK UNIFIED IDEOGRAPH
+0xB663 0x79BC #CJK UNIFIED IDEOGRAPH
+0xB664 0x79BF #CJK UNIFIED IDEOGRAPH
+0xB665 0x79C2 #CJK UNIFIED IDEOGRAPH
+0xB666 0x79C4 #CJK UNIFIED IDEOGRAPH
+0xB667 0x79C5 #CJK UNIFIED IDEOGRAPH
+0xB668 0x79C7 #CJK UNIFIED IDEOGRAPH
+0xB669 0x79C8 #CJK UNIFIED IDEOGRAPH
+0xB66A 0x79CA #CJK UNIFIED IDEOGRAPH
+0xB66B 0x79CC #CJK UNIFIED IDEOGRAPH
+0xB66C 0x79CE #CJK UNIFIED IDEOGRAPH
+0xB66D 0x79CF #CJK UNIFIED IDEOGRAPH
+0xB66E 0x79D0 #CJK UNIFIED IDEOGRAPH
+0xB66F 0x79D3 #CJK UNIFIED IDEOGRAPH
+0xB670 0x79D4 #CJK UNIFIED IDEOGRAPH
+0xB671 0x79D6 #CJK UNIFIED IDEOGRAPH
+0xB672 0x79D7 #CJK UNIFIED IDEOGRAPH
+0xB673 0x79D9 #CJK UNIFIED IDEOGRAPH
+0xB674 0x79DA #CJK UNIFIED IDEOGRAPH
+0xB675 0x79DB #CJK UNIFIED IDEOGRAPH
+0xB676 0x79DC #CJK UNIFIED IDEOGRAPH
+0xB677 0x79DD #CJK UNIFIED IDEOGRAPH
+0xB678 0x79DE #CJK UNIFIED IDEOGRAPH
+0xB679 0x79E0 #CJK UNIFIED IDEOGRAPH
+0xB67A 0x79E1 #CJK UNIFIED IDEOGRAPH
+0xB67B 0x79E2 #CJK UNIFIED IDEOGRAPH
+0xB67C 0x79E5 #CJK UNIFIED IDEOGRAPH
+0xB67D 0x79E8 #CJK UNIFIED IDEOGRAPH
+0xB67E 0x79EA #CJK UNIFIED IDEOGRAPH
+0xB680 0x79EC #CJK UNIFIED IDEOGRAPH
+0xB681 0x79EE #CJK UNIFIED IDEOGRAPH
+0xB682 0x79F1 #CJK UNIFIED IDEOGRAPH
+0xB683 0x79F2 #CJK UNIFIED IDEOGRAPH
+0xB684 0x79F3 #CJK UNIFIED IDEOGRAPH
+0xB685 0x79F4 #CJK UNIFIED IDEOGRAPH
+0xB686 0x79F5 #CJK UNIFIED IDEOGRAPH
+0xB687 0x79F6 #CJK UNIFIED IDEOGRAPH
+0xB688 0x79F7 #CJK UNIFIED IDEOGRAPH
+0xB689 0x79F9 #CJK UNIFIED IDEOGRAPH
+0xB68A 0x79FA #CJK UNIFIED IDEOGRAPH
+0xB68B 0x79FC #CJK UNIFIED IDEOGRAPH
+0xB68C 0x79FE #CJK UNIFIED IDEOGRAPH
+0xB68D 0x79FF #CJK UNIFIED IDEOGRAPH
+0xB68E 0x7A01 #CJK UNIFIED IDEOGRAPH
+0xB68F 0x7A04 #CJK UNIFIED IDEOGRAPH
+0xB690 0x7A05 #CJK UNIFIED IDEOGRAPH
+0xB691 0x7A07 #CJK UNIFIED IDEOGRAPH
+0xB692 0x7A08 #CJK UNIFIED IDEOGRAPH
+0xB693 0x7A09 #CJK UNIFIED IDEOGRAPH
+0xB694 0x7A0A #CJK UNIFIED IDEOGRAPH
+0xB695 0x7A0C #CJK UNIFIED IDEOGRAPH
+0xB696 0x7A0F #CJK UNIFIED IDEOGRAPH
+0xB697 0x7A10 #CJK UNIFIED IDEOGRAPH
+0xB698 0x7A11 #CJK UNIFIED IDEOGRAPH
+0xB699 0x7A12 #CJK UNIFIED IDEOGRAPH
+0xB69A 0x7A13 #CJK UNIFIED IDEOGRAPH
+0xB69B 0x7A15 #CJK UNIFIED IDEOGRAPH
+0xB69C 0x7A16 #CJK UNIFIED IDEOGRAPH
+0xB69D 0x7A18 #CJK UNIFIED IDEOGRAPH
+0xB69E 0x7A19 #CJK UNIFIED IDEOGRAPH
+0xB69F 0x7A1B #CJK UNIFIED IDEOGRAPH
+0xB6A0 0x7A1C #CJK UNIFIED IDEOGRAPH
+0xB6A1 0x4E01 #CJK UNIFIED IDEOGRAPH
+0xB6A2 0x76EF #CJK UNIFIED IDEOGRAPH
+0xB6A3 0x53EE #CJK UNIFIED IDEOGRAPH
+0xB6A4 0x9489 #CJK UNIFIED IDEOGRAPH
+0xB6A5 0x9876 #CJK UNIFIED IDEOGRAPH
+0xB6A6 0x9F0E #CJK UNIFIED IDEOGRAPH
+0xB6A7 0x952D #CJK UNIFIED IDEOGRAPH
+0xB6A8 0x5B9A #CJK UNIFIED IDEOGRAPH
+0xB6A9 0x8BA2 #CJK UNIFIED IDEOGRAPH
+0xB6AA 0x4E22 #CJK UNIFIED IDEOGRAPH
+0xB6AB 0x4E1C #CJK UNIFIED IDEOGRAPH
+0xB6AC 0x51AC #CJK UNIFIED IDEOGRAPH
+0xB6AD 0x8463 #CJK UNIFIED IDEOGRAPH
+0xB6AE 0x61C2 #CJK UNIFIED IDEOGRAPH
+0xB6AF 0x52A8 #CJK UNIFIED IDEOGRAPH
+0xB6B0 0x680B #CJK UNIFIED IDEOGRAPH
+0xB6B1 0x4F97 #CJK UNIFIED IDEOGRAPH
+0xB6B2 0x606B #CJK UNIFIED IDEOGRAPH
+0xB6B3 0x51BB #CJK UNIFIED IDEOGRAPH
+0xB6B4 0x6D1E #CJK UNIFIED IDEOGRAPH
+0xB6B5 0x515C #CJK UNIFIED IDEOGRAPH
+0xB6B6 0x6296 #CJK UNIFIED IDEOGRAPH
+0xB6B7 0x6597 #CJK UNIFIED IDEOGRAPH
+0xB6B8 0x9661 #CJK UNIFIED IDEOGRAPH
+0xB6B9 0x8C46 #CJK UNIFIED IDEOGRAPH
+0xB6BA 0x9017 #CJK UNIFIED IDEOGRAPH
+0xB6BB 0x75D8 #CJK UNIFIED IDEOGRAPH
+0xB6BC 0x90FD #CJK UNIFIED IDEOGRAPH
+0xB6BD 0x7763 #CJK UNIFIED IDEOGRAPH
+0xB6BE 0x6BD2 #CJK UNIFIED IDEOGRAPH
+0xB6BF 0x728A #CJK UNIFIED IDEOGRAPH
+0xB6C0 0x72EC #CJK UNIFIED IDEOGRAPH
+0xB6C1 0x8BFB #CJK UNIFIED IDEOGRAPH
+0xB6C2 0x5835 #CJK UNIFIED IDEOGRAPH
+0xB6C3 0x7779 #CJK UNIFIED IDEOGRAPH
+0xB6C4 0x8D4C #CJK UNIFIED IDEOGRAPH
+0xB6C5 0x675C #CJK UNIFIED IDEOGRAPH
+0xB6C6 0x9540 #CJK UNIFIED IDEOGRAPH
+0xB6C7 0x809A #CJK UNIFIED IDEOGRAPH
+0xB6C8 0x5EA6 #CJK UNIFIED IDEOGRAPH
+0xB6C9 0x6E21 #CJK UNIFIED IDEOGRAPH
+0xB6CA 0x5992 #CJK UNIFIED IDEOGRAPH
+0xB6CB 0x7AEF #CJK UNIFIED IDEOGRAPH
+0xB6CC 0x77ED #CJK UNIFIED IDEOGRAPH
+0xB6CD 0x953B #CJK UNIFIED IDEOGRAPH
+0xB6CE 0x6BB5 #CJK UNIFIED IDEOGRAPH
+0xB6CF 0x65AD #CJK UNIFIED IDEOGRAPH
+0xB6D0 0x7F0E #CJK UNIFIED IDEOGRAPH
+0xB6D1 0x5806 #CJK UNIFIED IDEOGRAPH
+0xB6D2 0x5151 #CJK UNIFIED IDEOGRAPH
+0xB6D3 0x961F #CJK UNIFIED IDEOGRAPH
+0xB6D4 0x5BF9 #CJK UNIFIED IDEOGRAPH
+0xB6D5 0x58A9 #CJK UNIFIED IDEOGRAPH
+0xB6D6 0x5428 #CJK UNIFIED IDEOGRAPH
+0xB6D7 0x8E72 #CJK UNIFIED IDEOGRAPH
+0xB6D8 0x6566 #CJK UNIFIED IDEOGRAPH
+0xB6D9 0x987F #CJK UNIFIED IDEOGRAPH
+0xB6DA 0x56E4 #CJK UNIFIED IDEOGRAPH
+0xB6DB 0x949D #CJK UNIFIED IDEOGRAPH
+0xB6DC 0x76FE #CJK UNIFIED IDEOGRAPH
+0xB6DD 0x9041 #CJK UNIFIED IDEOGRAPH
+0xB6DE 0x6387 #CJK UNIFIED IDEOGRAPH
+0xB6DF 0x54C6 #CJK UNIFIED IDEOGRAPH
+0xB6E0 0x591A #CJK UNIFIED IDEOGRAPH
+0xB6E1 0x593A #CJK UNIFIED IDEOGRAPH
+0xB6E2 0x579B #CJK UNIFIED IDEOGRAPH
+0xB6E3 0x8EB2 #CJK UNIFIED IDEOGRAPH
+0xB6E4 0x6735 #CJK UNIFIED IDEOGRAPH
+0xB6E5 0x8DFA #CJK UNIFIED IDEOGRAPH
+0xB6E6 0x8235 #CJK UNIFIED IDEOGRAPH
+0xB6E7 0x5241 #CJK UNIFIED IDEOGRAPH
+0xB6E8 0x60F0 #CJK UNIFIED IDEOGRAPH
+0xB6E9 0x5815 #CJK UNIFIED IDEOGRAPH
+0xB6EA 0x86FE #CJK UNIFIED IDEOGRAPH
+0xB6EB 0x5CE8 #CJK UNIFIED IDEOGRAPH
+0xB6EC 0x9E45 #CJK UNIFIED IDEOGRAPH
+0xB6ED 0x4FC4 #CJK UNIFIED IDEOGRAPH
+0xB6EE 0x989D #CJK UNIFIED IDEOGRAPH
+0xB6EF 0x8BB9 #CJK UNIFIED IDEOGRAPH
+0xB6F0 0x5A25 #CJK UNIFIED IDEOGRAPH
+0xB6F1 0x6076 #CJK UNIFIED IDEOGRAPH
+0xB6F2 0x5384 #CJK UNIFIED IDEOGRAPH
+0xB6F3 0x627C #CJK UNIFIED IDEOGRAPH
+0xB6F4 0x904F #CJK UNIFIED IDEOGRAPH
+0xB6F5 0x9102 #CJK UNIFIED IDEOGRAPH
+0xB6F6 0x997F #CJK UNIFIED IDEOGRAPH
+0xB6F7 0x6069 #CJK UNIFIED IDEOGRAPH
+0xB6F8 0x800C #CJK UNIFIED IDEOGRAPH
+0xB6F9 0x513F #CJK UNIFIED IDEOGRAPH
+0xB6FA 0x8033 #CJK UNIFIED IDEOGRAPH
+0xB6FB 0x5C14 #CJK UNIFIED IDEOGRAPH
+0xB6FC 0x9975 #CJK UNIFIED IDEOGRAPH
+0xB6FD 0x6D31 #CJK UNIFIED IDEOGRAPH
+0xB6FE 0x4E8C #CJK UNIFIED IDEOGRAPH
+0xB740 0x7A1D #CJK UNIFIED IDEOGRAPH
+0xB741 0x7A1F #CJK UNIFIED IDEOGRAPH
+0xB742 0x7A21 #CJK UNIFIED IDEOGRAPH
+0xB743 0x7A22 #CJK UNIFIED IDEOGRAPH
+0xB744 0x7A24 #CJK UNIFIED IDEOGRAPH
+0xB745 0x7A25 #CJK UNIFIED IDEOGRAPH
+0xB746 0x7A26 #CJK UNIFIED IDEOGRAPH
+0xB747 0x7A27 #CJK UNIFIED IDEOGRAPH
+0xB748 0x7A28 #CJK UNIFIED IDEOGRAPH
+0xB749 0x7A29 #CJK UNIFIED IDEOGRAPH
+0xB74A 0x7A2A #CJK UNIFIED IDEOGRAPH
+0xB74B 0x7A2B #CJK UNIFIED IDEOGRAPH
+0xB74C 0x7A2C #CJK UNIFIED IDEOGRAPH
+0xB74D 0x7A2D #CJK UNIFIED IDEOGRAPH
+0xB74E 0x7A2E #CJK UNIFIED IDEOGRAPH
+0xB74F 0x7A2F #CJK UNIFIED IDEOGRAPH
+0xB750 0x7A30 #CJK UNIFIED IDEOGRAPH
+0xB751 0x7A31 #CJK UNIFIED IDEOGRAPH
+0xB752 0x7A32 #CJK UNIFIED IDEOGRAPH
+0xB753 0x7A34 #CJK UNIFIED IDEOGRAPH
+0xB754 0x7A35 #CJK UNIFIED IDEOGRAPH
+0xB755 0x7A36 #CJK UNIFIED IDEOGRAPH
+0xB756 0x7A38 #CJK UNIFIED IDEOGRAPH
+0xB757 0x7A3A #CJK UNIFIED IDEOGRAPH
+0xB758 0x7A3E #CJK UNIFIED IDEOGRAPH
+0xB759 0x7A40 #CJK UNIFIED IDEOGRAPH
+0xB75A 0x7A41 #CJK UNIFIED IDEOGRAPH
+0xB75B 0x7A42 #CJK UNIFIED IDEOGRAPH
+0xB75C 0x7A43 #CJK UNIFIED IDEOGRAPH
+0xB75D 0x7A44 #CJK UNIFIED IDEOGRAPH
+0xB75E 0x7A45 #CJK UNIFIED IDEOGRAPH
+0xB75F 0x7A47 #CJK UNIFIED IDEOGRAPH
+0xB760 0x7A48 #CJK UNIFIED IDEOGRAPH
+0xB761 0x7A49 #CJK UNIFIED IDEOGRAPH
+0xB762 0x7A4A #CJK UNIFIED IDEOGRAPH
+0xB763 0x7A4B #CJK UNIFIED IDEOGRAPH
+0xB764 0x7A4C #CJK UNIFIED IDEOGRAPH
+0xB765 0x7A4D #CJK UNIFIED IDEOGRAPH
+0xB766 0x7A4E #CJK UNIFIED IDEOGRAPH
+0xB767 0x7A4F #CJK UNIFIED IDEOGRAPH
+0xB768 0x7A50 #CJK UNIFIED IDEOGRAPH
+0xB769 0x7A52 #CJK UNIFIED IDEOGRAPH
+0xB76A 0x7A53 #CJK UNIFIED IDEOGRAPH
+0xB76B 0x7A54 #CJK UNIFIED IDEOGRAPH
+0xB76C 0x7A55 #CJK UNIFIED IDEOGRAPH
+0xB76D 0x7A56 #CJK UNIFIED IDEOGRAPH
+0xB76E 0x7A58 #CJK UNIFIED IDEOGRAPH
+0xB76F 0x7A59 #CJK UNIFIED IDEOGRAPH
+0xB770 0x7A5A #CJK UNIFIED IDEOGRAPH
+0xB771 0x7A5B #CJK UNIFIED IDEOGRAPH
+0xB772 0x7A5C #CJK UNIFIED IDEOGRAPH
+0xB773 0x7A5D #CJK UNIFIED IDEOGRAPH
+0xB774 0x7A5E #CJK UNIFIED IDEOGRAPH
+0xB775 0x7A5F #CJK UNIFIED IDEOGRAPH
+0xB776 0x7A60 #CJK UNIFIED IDEOGRAPH
+0xB777 0x7A61 #CJK UNIFIED IDEOGRAPH
+0xB778 0x7A62 #CJK UNIFIED IDEOGRAPH
+0xB779 0x7A63 #CJK UNIFIED IDEOGRAPH
+0xB77A 0x7A64 #CJK UNIFIED IDEOGRAPH
+0xB77B 0x7A65 #CJK UNIFIED IDEOGRAPH
+0xB77C 0x7A66 #CJK UNIFIED IDEOGRAPH
+0xB77D 0x7A67 #CJK UNIFIED IDEOGRAPH
+0xB77E 0x7A68 #CJK UNIFIED IDEOGRAPH
+0xB780 0x7A69 #CJK UNIFIED IDEOGRAPH
+0xB781 0x7A6A #CJK UNIFIED IDEOGRAPH
+0xB782 0x7A6B #CJK UNIFIED IDEOGRAPH
+0xB783 0x7A6C #CJK UNIFIED IDEOGRAPH
+0xB784 0x7A6D #CJK UNIFIED IDEOGRAPH
+0xB785 0x7A6E #CJK UNIFIED IDEOGRAPH
+0xB786 0x7A6F #CJK UNIFIED IDEOGRAPH
+0xB787 0x7A71 #CJK UNIFIED IDEOGRAPH
+0xB788 0x7A72 #CJK UNIFIED IDEOGRAPH
+0xB789 0x7A73 #CJK UNIFIED IDEOGRAPH
+0xB78A 0x7A75 #CJK UNIFIED IDEOGRAPH
+0xB78B 0x7A7B #CJK UNIFIED IDEOGRAPH
+0xB78C 0x7A7C #CJK UNIFIED IDEOGRAPH
+0xB78D 0x7A7D #CJK UNIFIED IDEOGRAPH
+0xB78E 0x7A7E #CJK UNIFIED IDEOGRAPH
+0xB78F 0x7A82 #CJK UNIFIED IDEOGRAPH
+0xB790 0x7A85 #CJK UNIFIED IDEOGRAPH
+0xB791 0x7A87 #CJK UNIFIED IDEOGRAPH
+0xB792 0x7A89 #CJK UNIFIED IDEOGRAPH
+0xB793 0x7A8A #CJK UNIFIED IDEOGRAPH
+0xB794 0x7A8B #CJK UNIFIED IDEOGRAPH
+0xB795 0x7A8C #CJK UNIFIED IDEOGRAPH
+0xB796 0x7A8E #CJK UNIFIED IDEOGRAPH
+0xB797 0x7A8F #CJK UNIFIED IDEOGRAPH
+0xB798 0x7A90 #CJK UNIFIED IDEOGRAPH
+0xB799 0x7A93 #CJK UNIFIED IDEOGRAPH
+0xB79A 0x7A94 #CJK UNIFIED IDEOGRAPH
+0xB79B 0x7A99 #CJK UNIFIED IDEOGRAPH
+0xB79C 0x7A9A #CJK UNIFIED IDEOGRAPH
+0xB79D 0x7A9B #CJK UNIFIED IDEOGRAPH
+0xB79E 0x7A9E #CJK UNIFIED IDEOGRAPH
+0xB79F 0x7AA1 #CJK UNIFIED IDEOGRAPH
+0xB7A0 0x7AA2 #CJK UNIFIED IDEOGRAPH
+0xB7A1 0x8D30 #CJK UNIFIED IDEOGRAPH
+0xB7A2 0x53D1 #CJK UNIFIED IDEOGRAPH
+0xB7A3 0x7F5A #CJK UNIFIED IDEOGRAPH
+0xB7A4 0x7B4F #CJK UNIFIED IDEOGRAPH
+0xB7A5 0x4F10 #CJK UNIFIED IDEOGRAPH
+0xB7A6 0x4E4F #CJK UNIFIED IDEOGRAPH
+0xB7A7 0x9600 #CJK UNIFIED IDEOGRAPH
+0xB7A8 0x6CD5 #CJK UNIFIED IDEOGRAPH
+0xB7A9 0x73D0 #CJK UNIFIED IDEOGRAPH
+0xB7AA 0x85E9 #CJK UNIFIED IDEOGRAPH
+0xB7AB 0x5E06 #CJK UNIFIED IDEOGRAPH
+0xB7AC 0x756A #CJK UNIFIED IDEOGRAPH
+0xB7AD 0x7FFB #CJK UNIFIED IDEOGRAPH
+0xB7AE 0x6A0A #CJK UNIFIED IDEOGRAPH
+0xB7AF 0x77FE #CJK UNIFIED IDEOGRAPH
+0xB7B0 0x9492 #CJK UNIFIED IDEOGRAPH
+0xB7B1 0x7E41 #CJK UNIFIED IDEOGRAPH
+0xB7B2 0x51E1 #CJK UNIFIED IDEOGRAPH
+0xB7B3 0x70E6 #CJK UNIFIED IDEOGRAPH
+0xB7B4 0x53CD #CJK UNIFIED IDEOGRAPH
+0xB7B5 0x8FD4 #CJK UNIFIED IDEOGRAPH
+0xB7B6 0x8303 #CJK UNIFIED IDEOGRAPH
+0xB7B7 0x8D29 #CJK UNIFIED IDEOGRAPH
+0xB7B8 0x72AF #CJK UNIFIED IDEOGRAPH
+0xB7B9 0x996D #CJK UNIFIED IDEOGRAPH
+0xB7BA 0x6CDB #CJK UNIFIED IDEOGRAPH
+0xB7BB 0x574A #CJK UNIFIED IDEOGRAPH
+0xB7BC 0x82B3 #CJK UNIFIED IDEOGRAPH
+0xB7BD 0x65B9 #CJK UNIFIED IDEOGRAPH
+0xB7BE 0x80AA #CJK UNIFIED IDEOGRAPH
+0xB7BF 0x623F #CJK UNIFIED IDEOGRAPH
+0xB7C0 0x9632 #CJK UNIFIED IDEOGRAPH
+0xB7C1 0x59A8 #CJK UNIFIED IDEOGRAPH
+0xB7C2 0x4EFF #CJK UNIFIED IDEOGRAPH
+0xB7C3 0x8BBF #CJK UNIFIED IDEOGRAPH
+0xB7C4 0x7EBA #CJK UNIFIED IDEOGRAPH
+0xB7C5 0x653E #CJK UNIFIED IDEOGRAPH
+0xB7C6 0x83F2 #CJK UNIFIED IDEOGRAPH
+0xB7C7 0x975E #CJK UNIFIED IDEOGRAPH
+0xB7C8 0x5561 #CJK UNIFIED IDEOGRAPH
+0xB7C9 0x98DE #CJK UNIFIED IDEOGRAPH
+0xB7CA 0x80A5 #CJK UNIFIED IDEOGRAPH
+0xB7CB 0x532A #CJK UNIFIED IDEOGRAPH
+0xB7CC 0x8BFD #CJK UNIFIED IDEOGRAPH
+0xB7CD 0x5420 #CJK UNIFIED IDEOGRAPH
+0xB7CE 0x80BA #CJK UNIFIED IDEOGRAPH
+0xB7CF 0x5E9F #CJK UNIFIED IDEOGRAPH
+0xB7D0 0x6CB8 #CJK UNIFIED IDEOGRAPH
+0xB7D1 0x8D39 #CJK UNIFIED IDEOGRAPH
+0xB7D2 0x82AC #CJK UNIFIED IDEOGRAPH
+0xB7D3 0x915A #CJK UNIFIED IDEOGRAPH
+0xB7D4 0x5429 #CJK UNIFIED IDEOGRAPH
+0xB7D5 0x6C1B #CJK UNIFIED IDEOGRAPH
+0xB7D6 0x5206 #CJK UNIFIED IDEOGRAPH
+0xB7D7 0x7EB7 #CJK UNIFIED IDEOGRAPH
+0xB7D8 0x575F #CJK UNIFIED IDEOGRAPH
+0xB7D9 0x711A #CJK UNIFIED IDEOGRAPH
+0xB7DA 0x6C7E #CJK UNIFIED IDEOGRAPH
+0xB7DB 0x7C89 #CJK UNIFIED IDEOGRAPH
+0xB7DC 0x594B #CJK UNIFIED IDEOGRAPH
+0xB7DD 0x4EFD #CJK UNIFIED IDEOGRAPH
+0xB7DE 0x5FFF #CJK UNIFIED IDEOGRAPH
+0xB7DF 0x6124 #CJK UNIFIED IDEOGRAPH
+0xB7E0 0x7CAA #CJK UNIFIED IDEOGRAPH
+0xB7E1 0x4E30 #CJK UNIFIED IDEOGRAPH
+0xB7E2 0x5C01 #CJK UNIFIED IDEOGRAPH
+0xB7E3 0x67AB #CJK UNIFIED IDEOGRAPH
+0xB7E4 0x8702 #CJK UNIFIED IDEOGRAPH
+0xB7E5 0x5CF0 #CJK UNIFIED IDEOGRAPH
+0xB7E6 0x950B #CJK UNIFIED IDEOGRAPH
+0xB7E7 0x98CE #CJK UNIFIED IDEOGRAPH
+0xB7E8 0x75AF #CJK UNIFIED IDEOGRAPH
+0xB7E9 0x70FD #CJK UNIFIED IDEOGRAPH
+0xB7EA 0x9022 #CJK UNIFIED IDEOGRAPH
+0xB7EB 0x51AF #CJK UNIFIED IDEOGRAPH
+0xB7EC 0x7F1D #CJK UNIFIED IDEOGRAPH
+0xB7ED 0x8BBD #CJK UNIFIED IDEOGRAPH
+0xB7EE 0x5949 #CJK UNIFIED IDEOGRAPH
+0xB7EF 0x51E4 #CJK UNIFIED IDEOGRAPH
+0xB7F0 0x4F5B #CJK UNIFIED IDEOGRAPH
+0xB7F1 0x5426 #CJK UNIFIED IDEOGRAPH
+0xB7F2 0x592B #CJK UNIFIED IDEOGRAPH
+0xB7F3 0x6577 #CJK UNIFIED IDEOGRAPH
+0xB7F4 0x80A4 #CJK UNIFIED IDEOGRAPH
+0xB7F5 0x5B75 #CJK UNIFIED IDEOGRAPH
+0xB7F6 0x6276 #CJK UNIFIED IDEOGRAPH
+0xB7F7 0x62C2 #CJK UNIFIED IDEOGRAPH
+0xB7F8 0x8F90 #CJK UNIFIED IDEOGRAPH
+0xB7F9 0x5E45 #CJK UNIFIED IDEOGRAPH
+0xB7FA 0x6C1F #CJK UNIFIED IDEOGRAPH
+0xB7FB 0x7B26 #CJK UNIFIED IDEOGRAPH
+0xB7FC 0x4F0F #CJK UNIFIED IDEOGRAPH
+0xB7FD 0x4FD8 #CJK UNIFIED IDEOGRAPH
+0xB7FE 0x670D #CJK UNIFIED IDEOGRAPH
+0xB840 0x7AA3 #CJK UNIFIED IDEOGRAPH
+0xB841 0x7AA4 #CJK UNIFIED IDEOGRAPH
+0xB842 0x7AA7 #CJK UNIFIED IDEOGRAPH
+0xB843 0x7AA9 #CJK UNIFIED IDEOGRAPH
+0xB844 0x7AAA #CJK UNIFIED IDEOGRAPH
+0xB845 0x7AAB #CJK UNIFIED IDEOGRAPH
+0xB846 0x7AAE #CJK UNIFIED IDEOGRAPH
+0xB847 0x7AAF #CJK UNIFIED IDEOGRAPH
+0xB848 0x7AB0 #CJK UNIFIED IDEOGRAPH
+0xB849 0x7AB1 #CJK UNIFIED IDEOGRAPH
+0xB84A 0x7AB2 #CJK UNIFIED IDEOGRAPH
+0xB84B 0x7AB4 #CJK UNIFIED IDEOGRAPH
+0xB84C 0x7AB5 #CJK UNIFIED IDEOGRAPH
+0xB84D 0x7AB6 #CJK UNIFIED IDEOGRAPH
+0xB84E 0x7AB7 #CJK UNIFIED IDEOGRAPH
+0xB84F 0x7AB8 #CJK UNIFIED IDEOGRAPH
+0xB850 0x7AB9 #CJK UNIFIED IDEOGRAPH
+0xB851 0x7ABA #CJK UNIFIED IDEOGRAPH
+0xB852 0x7ABB #CJK UNIFIED IDEOGRAPH
+0xB853 0x7ABC #CJK UNIFIED IDEOGRAPH
+0xB854 0x7ABD #CJK UNIFIED IDEOGRAPH
+0xB855 0x7ABE #CJK UNIFIED IDEOGRAPH
+0xB856 0x7AC0 #CJK UNIFIED IDEOGRAPH
+0xB857 0x7AC1 #CJK UNIFIED IDEOGRAPH
+0xB858 0x7AC2 #CJK UNIFIED IDEOGRAPH
+0xB859 0x7AC3 #CJK UNIFIED IDEOGRAPH
+0xB85A 0x7AC4 #CJK UNIFIED IDEOGRAPH
+0xB85B 0x7AC5 #CJK UNIFIED IDEOGRAPH
+0xB85C 0x7AC6 #CJK UNIFIED IDEOGRAPH
+0xB85D 0x7AC7 #CJK UNIFIED IDEOGRAPH
+0xB85E 0x7AC8 #CJK UNIFIED IDEOGRAPH
+0xB85F 0x7AC9 #CJK UNIFIED IDEOGRAPH
+0xB860 0x7ACA #CJK UNIFIED IDEOGRAPH
+0xB861 0x7ACC #CJK UNIFIED IDEOGRAPH
+0xB862 0x7ACD #CJK UNIFIED IDEOGRAPH
+0xB863 0x7ACE #CJK UNIFIED IDEOGRAPH
+0xB864 0x7ACF #CJK UNIFIED IDEOGRAPH
+0xB865 0x7AD0 #CJK UNIFIED IDEOGRAPH
+0xB866 0x7AD1 #CJK UNIFIED IDEOGRAPH
+0xB867 0x7AD2 #CJK UNIFIED IDEOGRAPH
+0xB868 0x7AD3 #CJK UNIFIED IDEOGRAPH
+0xB869 0x7AD4 #CJK UNIFIED IDEOGRAPH
+0xB86A 0x7AD5 #CJK UNIFIED IDEOGRAPH
+0xB86B 0x7AD7 #CJK UNIFIED IDEOGRAPH
+0xB86C 0x7AD8 #CJK UNIFIED IDEOGRAPH
+0xB86D 0x7ADA #CJK UNIFIED IDEOGRAPH
+0xB86E 0x7ADB #CJK UNIFIED IDEOGRAPH
+0xB86F 0x7ADC #CJK UNIFIED IDEOGRAPH
+0xB870 0x7ADD #CJK UNIFIED IDEOGRAPH
+0xB871 0x7AE1 #CJK UNIFIED IDEOGRAPH
+0xB872 0x7AE2 #CJK UNIFIED IDEOGRAPH
+0xB873 0x7AE4 #CJK UNIFIED IDEOGRAPH
+0xB874 0x7AE7 #CJK UNIFIED IDEOGRAPH
+0xB875 0x7AE8 #CJK UNIFIED IDEOGRAPH
+0xB876 0x7AE9 #CJK UNIFIED IDEOGRAPH
+0xB877 0x7AEA #CJK UNIFIED IDEOGRAPH
+0xB878 0x7AEB #CJK UNIFIED IDEOGRAPH
+0xB879 0x7AEC #CJK UNIFIED IDEOGRAPH
+0xB87A 0x7AEE #CJK UNIFIED IDEOGRAPH
+0xB87B 0x7AF0 #CJK UNIFIED IDEOGRAPH
+0xB87C 0x7AF1 #CJK UNIFIED IDEOGRAPH
+0xB87D 0x7AF2 #CJK UNIFIED IDEOGRAPH
+0xB87E 0x7AF3 #CJK UNIFIED IDEOGRAPH
+0xB880 0x7AF4 #CJK UNIFIED IDEOGRAPH
+0xB881 0x7AF5 #CJK UNIFIED IDEOGRAPH
+0xB882 0x7AF6 #CJK UNIFIED IDEOGRAPH
+0xB883 0x7AF7 #CJK UNIFIED IDEOGRAPH
+0xB884 0x7AF8 #CJK UNIFIED IDEOGRAPH
+0xB885 0x7AFB #CJK UNIFIED IDEOGRAPH
+0xB886 0x7AFC #CJK UNIFIED IDEOGRAPH
+0xB887 0x7AFE #CJK UNIFIED IDEOGRAPH
+0xB888 0x7B00 #CJK UNIFIED IDEOGRAPH
+0xB889 0x7B01 #CJK UNIFIED IDEOGRAPH
+0xB88A 0x7B02 #CJK UNIFIED IDEOGRAPH
+0xB88B 0x7B05 #CJK UNIFIED IDEOGRAPH
+0xB88C 0x7B07 #CJK UNIFIED IDEOGRAPH
+0xB88D 0x7B09 #CJK UNIFIED IDEOGRAPH
+0xB88E 0x7B0C #CJK UNIFIED IDEOGRAPH
+0xB88F 0x7B0D #CJK UNIFIED IDEOGRAPH
+0xB890 0x7B0E #CJK UNIFIED IDEOGRAPH
+0xB891 0x7B10 #CJK UNIFIED IDEOGRAPH
+0xB892 0x7B12 #CJK UNIFIED IDEOGRAPH
+0xB893 0x7B13 #CJK UNIFIED IDEOGRAPH
+0xB894 0x7B16 #CJK UNIFIED IDEOGRAPH
+0xB895 0x7B17 #CJK UNIFIED IDEOGRAPH
+0xB896 0x7B18 #CJK UNIFIED IDEOGRAPH
+0xB897 0x7B1A #CJK UNIFIED IDEOGRAPH
+0xB898 0x7B1C #CJK UNIFIED IDEOGRAPH
+0xB899 0x7B1D #CJK UNIFIED IDEOGRAPH
+0xB89A 0x7B1F #CJK UNIFIED IDEOGRAPH
+0xB89B 0x7B21 #CJK UNIFIED IDEOGRAPH
+0xB89C 0x7B22 #CJK UNIFIED IDEOGRAPH
+0xB89D 0x7B23 #CJK UNIFIED IDEOGRAPH
+0xB89E 0x7B27 #CJK UNIFIED IDEOGRAPH
+0xB89F 0x7B29 #CJK UNIFIED IDEOGRAPH
+0xB8A0 0x7B2D #CJK UNIFIED IDEOGRAPH
+0xB8A1 0x6D6E #CJK UNIFIED IDEOGRAPH
+0xB8A2 0x6DAA #CJK UNIFIED IDEOGRAPH
+0xB8A3 0x798F #CJK UNIFIED IDEOGRAPH
+0xB8A4 0x88B1 #CJK UNIFIED IDEOGRAPH
+0xB8A5 0x5F17 #CJK UNIFIED IDEOGRAPH
+0xB8A6 0x752B #CJK UNIFIED IDEOGRAPH
+0xB8A7 0x629A #CJK UNIFIED IDEOGRAPH
+0xB8A8 0x8F85 #CJK UNIFIED IDEOGRAPH
+0xB8A9 0x4FEF #CJK UNIFIED IDEOGRAPH
+0xB8AA 0x91DC #CJK UNIFIED IDEOGRAPH
+0xB8AB 0x65A7 #CJK UNIFIED IDEOGRAPH
+0xB8AC 0x812F #CJK UNIFIED IDEOGRAPH
+0xB8AD 0x8151 #CJK UNIFIED IDEOGRAPH
+0xB8AE 0x5E9C #CJK UNIFIED IDEOGRAPH
+0xB8AF 0x8150 #CJK UNIFIED IDEOGRAPH
+0xB8B0 0x8D74 #CJK UNIFIED IDEOGRAPH
+0xB8B1 0x526F #CJK UNIFIED IDEOGRAPH
+0xB8B2 0x8986 #CJK UNIFIED IDEOGRAPH
+0xB8B3 0x8D4B #CJK UNIFIED IDEOGRAPH
+0xB8B4 0x590D #CJK UNIFIED IDEOGRAPH
+0xB8B5 0x5085 #CJK UNIFIED IDEOGRAPH
+0xB8B6 0x4ED8 #CJK UNIFIED IDEOGRAPH
+0xB8B7 0x961C #CJK UNIFIED IDEOGRAPH
+0xB8B8 0x7236 #CJK UNIFIED IDEOGRAPH
+0xB8B9 0x8179 #CJK UNIFIED IDEOGRAPH
+0xB8BA 0x8D1F #CJK UNIFIED IDEOGRAPH
+0xB8BB 0x5BCC #CJK UNIFIED IDEOGRAPH
+0xB8BC 0x8BA3 #CJK UNIFIED IDEOGRAPH
+0xB8BD 0x9644 #CJK UNIFIED IDEOGRAPH
+0xB8BE 0x5987 #CJK UNIFIED IDEOGRAPH
+0xB8BF 0x7F1A #CJK UNIFIED IDEOGRAPH
+0xB8C0 0x5490 #CJK UNIFIED IDEOGRAPH
+0xB8C1 0x5676 #CJK UNIFIED IDEOGRAPH
+0xB8C2 0x560E #CJK UNIFIED IDEOGRAPH
+0xB8C3 0x8BE5 #CJK UNIFIED IDEOGRAPH
+0xB8C4 0x6539 #CJK UNIFIED IDEOGRAPH
+0xB8C5 0x6982 #CJK UNIFIED IDEOGRAPH
+0xB8C6 0x9499 #CJK UNIFIED IDEOGRAPH
+0xB8C7 0x76D6 #CJK UNIFIED IDEOGRAPH
+0xB8C8 0x6E89 #CJK UNIFIED IDEOGRAPH
+0xB8C9 0x5E72 #CJK UNIFIED IDEOGRAPH
+0xB8CA 0x7518 #CJK UNIFIED IDEOGRAPH
+0xB8CB 0x6746 #CJK UNIFIED IDEOGRAPH
+0xB8CC 0x67D1 #CJK UNIFIED IDEOGRAPH
+0xB8CD 0x7AFF #CJK UNIFIED IDEOGRAPH
+0xB8CE 0x809D #CJK UNIFIED IDEOGRAPH
+0xB8CF 0x8D76 #CJK UNIFIED IDEOGRAPH
+0xB8D0 0x611F #CJK UNIFIED IDEOGRAPH
+0xB8D1 0x79C6 #CJK UNIFIED IDEOGRAPH
+0xB8D2 0x6562 #CJK UNIFIED IDEOGRAPH
+0xB8D3 0x8D63 #CJK UNIFIED IDEOGRAPH
+0xB8D4 0x5188 #CJK UNIFIED IDEOGRAPH
+0xB8D5 0x521A #CJK UNIFIED IDEOGRAPH
+0xB8D6 0x94A2 #CJK UNIFIED IDEOGRAPH
+0xB8D7 0x7F38 #CJK UNIFIED IDEOGRAPH
+0xB8D8 0x809B #CJK UNIFIED IDEOGRAPH
+0xB8D9 0x7EB2 #CJK UNIFIED IDEOGRAPH
+0xB8DA 0x5C97 #CJK UNIFIED IDEOGRAPH
+0xB8DB 0x6E2F #CJK UNIFIED IDEOGRAPH
+0xB8DC 0x6760 #CJK UNIFIED IDEOGRAPH
+0xB8DD 0x7BD9 #CJK UNIFIED IDEOGRAPH
+0xB8DE 0x768B #CJK UNIFIED IDEOGRAPH
+0xB8DF 0x9AD8 #CJK UNIFIED IDEOGRAPH
+0xB8E0 0x818F #CJK UNIFIED IDEOGRAPH
+0xB8E1 0x7F94 #CJK UNIFIED IDEOGRAPH
+0xB8E2 0x7CD5 #CJK UNIFIED IDEOGRAPH
+0xB8E3 0x641E #CJK UNIFIED IDEOGRAPH
+0xB8E4 0x9550 #CJK UNIFIED IDEOGRAPH
+0xB8E5 0x7A3F #CJK UNIFIED IDEOGRAPH
+0xB8E6 0x544A #CJK UNIFIED IDEOGRAPH
+0xB8E7 0x54E5 #CJK UNIFIED IDEOGRAPH
+0xB8E8 0x6B4C #CJK UNIFIED IDEOGRAPH
+0xB8E9 0x6401 #CJK UNIFIED IDEOGRAPH
+0xB8EA 0x6208 #CJK UNIFIED IDEOGRAPH
+0xB8EB 0x9E3D #CJK UNIFIED IDEOGRAPH
+0xB8EC 0x80F3 #CJK UNIFIED IDEOGRAPH
+0xB8ED 0x7599 #CJK UNIFIED IDEOGRAPH
+0xB8EE 0x5272 #CJK UNIFIED IDEOGRAPH
+0xB8EF 0x9769 #CJK UNIFIED IDEOGRAPH
+0xB8F0 0x845B #CJK UNIFIED IDEOGRAPH
+0xB8F1 0x683C #CJK UNIFIED IDEOGRAPH
+0xB8F2 0x86E4 #CJK UNIFIED IDEOGRAPH
+0xB8F3 0x9601 #CJK UNIFIED IDEOGRAPH
+0xB8F4 0x9694 #CJK UNIFIED IDEOGRAPH
+0xB8F5 0x94EC #CJK UNIFIED IDEOGRAPH
+0xB8F6 0x4E2A #CJK UNIFIED IDEOGRAPH
+0xB8F7 0x5404 #CJK UNIFIED IDEOGRAPH
+0xB8F8 0x7ED9 #CJK UNIFIED IDEOGRAPH
+0xB8F9 0x6839 #CJK UNIFIED IDEOGRAPH
+0xB8FA 0x8DDF #CJK UNIFIED IDEOGRAPH
+0xB8FB 0x8015 #CJK UNIFIED IDEOGRAPH
+0xB8FC 0x66F4 #CJK UNIFIED IDEOGRAPH
+0xB8FD 0x5E9A #CJK UNIFIED IDEOGRAPH
+0xB8FE 0x7FB9 #CJK UNIFIED IDEOGRAPH
+0xB940 0x7B2F #CJK UNIFIED IDEOGRAPH
+0xB941 0x7B30 #CJK UNIFIED IDEOGRAPH
+0xB942 0x7B32 #CJK UNIFIED IDEOGRAPH
+0xB943 0x7B34 #CJK UNIFIED IDEOGRAPH
+0xB944 0x7B35 #CJK UNIFIED IDEOGRAPH
+0xB945 0x7B36 #CJK UNIFIED IDEOGRAPH
+0xB946 0x7B37 #CJK UNIFIED IDEOGRAPH
+0xB947 0x7B39 #CJK UNIFIED IDEOGRAPH
+0xB948 0x7B3B #CJK UNIFIED IDEOGRAPH
+0xB949 0x7B3D #CJK UNIFIED IDEOGRAPH
+0xB94A 0x7B3F #CJK UNIFIED IDEOGRAPH
+0xB94B 0x7B40 #CJK UNIFIED IDEOGRAPH
+0xB94C 0x7B41 #CJK UNIFIED IDEOGRAPH
+0xB94D 0x7B42 #CJK UNIFIED IDEOGRAPH
+0xB94E 0x7B43 #CJK UNIFIED IDEOGRAPH
+0xB94F 0x7B44 #CJK UNIFIED IDEOGRAPH
+0xB950 0x7B46 #CJK UNIFIED IDEOGRAPH
+0xB951 0x7B48 #CJK UNIFIED IDEOGRAPH
+0xB952 0x7B4A #CJK UNIFIED IDEOGRAPH
+0xB953 0x7B4D #CJK UNIFIED IDEOGRAPH
+0xB954 0x7B4E #CJK UNIFIED IDEOGRAPH
+0xB955 0x7B53 #CJK UNIFIED IDEOGRAPH
+0xB956 0x7B55 #CJK UNIFIED IDEOGRAPH
+0xB957 0x7B57 #CJK UNIFIED IDEOGRAPH
+0xB958 0x7B59 #CJK UNIFIED IDEOGRAPH
+0xB959 0x7B5C #CJK UNIFIED IDEOGRAPH
+0xB95A 0x7B5E #CJK UNIFIED IDEOGRAPH
+0xB95B 0x7B5F #CJK UNIFIED IDEOGRAPH
+0xB95C 0x7B61 #CJK UNIFIED IDEOGRAPH
+0xB95D 0x7B63 #CJK UNIFIED IDEOGRAPH
+0xB95E 0x7B64 #CJK UNIFIED IDEOGRAPH
+0xB95F 0x7B65 #CJK UNIFIED IDEOGRAPH
+0xB960 0x7B66 #CJK UNIFIED IDEOGRAPH
+0xB961 0x7B67 #CJK UNIFIED IDEOGRAPH
+0xB962 0x7B68 #CJK UNIFIED IDEOGRAPH
+0xB963 0x7B69 #CJK UNIFIED IDEOGRAPH
+0xB964 0x7B6A #CJK UNIFIED IDEOGRAPH
+0xB965 0x7B6B #CJK UNIFIED IDEOGRAPH
+0xB966 0x7B6C #CJK UNIFIED IDEOGRAPH
+0xB967 0x7B6D #CJK UNIFIED IDEOGRAPH
+0xB968 0x7B6F #CJK UNIFIED IDEOGRAPH
+0xB969 0x7B70 #CJK UNIFIED IDEOGRAPH
+0xB96A 0x7B73 #CJK UNIFIED IDEOGRAPH
+0xB96B 0x7B74 #CJK UNIFIED IDEOGRAPH
+0xB96C 0x7B76 #CJK UNIFIED IDEOGRAPH
+0xB96D 0x7B78 #CJK UNIFIED IDEOGRAPH
+0xB96E 0x7B7A #CJK UNIFIED IDEOGRAPH
+0xB96F 0x7B7C #CJK UNIFIED IDEOGRAPH
+0xB970 0x7B7D #CJK UNIFIED IDEOGRAPH
+0xB971 0x7B7F #CJK UNIFIED IDEOGRAPH
+0xB972 0x7B81 #CJK UNIFIED IDEOGRAPH
+0xB973 0x7B82 #CJK UNIFIED IDEOGRAPH
+0xB974 0x7B83 #CJK UNIFIED IDEOGRAPH
+0xB975 0x7B84 #CJK UNIFIED IDEOGRAPH
+0xB976 0x7B86 #CJK UNIFIED IDEOGRAPH
+0xB977 0x7B87 #CJK UNIFIED IDEOGRAPH
+0xB978 0x7B88 #CJK UNIFIED IDEOGRAPH
+0xB979 0x7B89 #CJK UNIFIED IDEOGRAPH
+0xB97A 0x7B8A #CJK UNIFIED IDEOGRAPH
+0xB97B 0x7B8B #CJK UNIFIED IDEOGRAPH
+0xB97C 0x7B8C #CJK UNIFIED IDEOGRAPH
+0xB97D 0x7B8E #CJK UNIFIED IDEOGRAPH
+0xB97E 0x7B8F #CJK UNIFIED IDEOGRAPH
+0xB980 0x7B91 #CJK UNIFIED IDEOGRAPH
+0xB981 0x7B92 #CJK UNIFIED IDEOGRAPH
+0xB982 0x7B93 #CJK UNIFIED IDEOGRAPH
+0xB983 0x7B96 #CJK UNIFIED IDEOGRAPH
+0xB984 0x7B98 #CJK UNIFIED IDEOGRAPH
+0xB985 0x7B99 #CJK UNIFIED IDEOGRAPH
+0xB986 0x7B9A #CJK UNIFIED IDEOGRAPH
+0xB987 0x7B9B #CJK UNIFIED IDEOGRAPH
+0xB988 0x7B9E #CJK UNIFIED IDEOGRAPH
+0xB989 0x7B9F #CJK UNIFIED IDEOGRAPH
+0xB98A 0x7BA0 #CJK UNIFIED IDEOGRAPH
+0xB98B 0x7BA3 #CJK UNIFIED IDEOGRAPH
+0xB98C 0x7BA4 #CJK UNIFIED IDEOGRAPH
+0xB98D 0x7BA5 #CJK UNIFIED IDEOGRAPH
+0xB98E 0x7BAE #CJK UNIFIED IDEOGRAPH
+0xB98F 0x7BAF #CJK UNIFIED IDEOGRAPH
+0xB990 0x7BB0 #CJK UNIFIED IDEOGRAPH
+0xB991 0x7BB2 #CJK UNIFIED IDEOGRAPH
+0xB992 0x7BB3 #CJK UNIFIED IDEOGRAPH
+0xB993 0x7BB5 #CJK UNIFIED IDEOGRAPH
+0xB994 0x7BB6 #CJK UNIFIED IDEOGRAPH
+0xB995 0x7BB7 #CJK UNIFIED IDEOGRAPH
+0xB996 0x7BB9 #CJK UNIFIED IDEOGRAPH
+0xB997 0x7BBA #CJK UNIFIED IDEOGRAPH
+0xB998 0x7BBB #CJK UNIFIED IDEOGRAPH
+0xB999 0x7BBC #CJK UNIFIED IDEOGRAPH
+0xB99A 0x7BBD #CJK UNIFIED IDEOGRAPH
+0xB99B 0x7BBE #CJK UNIFIED IDEOGRAPH
+0xB99C 0x7BBF #CJK UNIFIED IDEOGRAPH
+0xB99D 0x7BC0 #CJK UNIFIED IDEOGRAPH
+0xB99E 0x7BC2 #CJK UNIFIED IDEOGRAPH
+0xB99F 0x7BC3 #CJK UNIFIED IDEOGRAPH
+0xB9A0 0x7BC4 #CJK UNIFIED IDEOGRAPH
+0xB9A1 0x57C2 #CJK UNIFIED IDEOGRAPH
+0xB9A2 0x803F #CJK UNIFIED IDEOGRAPH
+0xB9A3 0x6897 #CJK UNIFIED IDEOGRAPH
+0xB9A4 0x5DE5 #CJK UNIFIED IDEOGRAPH
+0xB9A5 0x653B #CJK UNIFIED IDEOGRAPH
+0xB9A6 0x529F #CJK UNIFIED IDEOGRAPH
+0xB9A7 0x606D #CJK UNIFIED IDEOGRAPH
+0xB9A8 0x9F9A #CJK UNIFIED IDEOGRAPH
+0xB9A9 0x4F9B #CJK UNIFIED IDEOGRAPH
+0xB9AA 0x8EAC #CJK UNIFIED IDEOGRAPH
+0xB9AB 0x516C #CJK UNIFIED IDEOGRAPH
+0xB9AC 0x5BAB #CJK UNIFIED IDEOGRAPH
+0xB9AD 0x5F13 #CJK UNIFIED IDEOGRAPH
+0xB9AE 0x5DE9 #CJK UNIFIED IDEOGRAPH
+0xB9AF 0x6C5E #CJK UNIFIED IDEOGRAPH
+0xB9B0 0x62F1 #CJK UNIFIED IDEOGRAPH
+0xB9B1 0x8D21 #CJK UNIFIED IDEOGRAPH
+0xB9B2 0x5171 #CJK UNIFIED IDEOGRAPH
+0xB9B3 0x94A9 #CJK UNIFIED IDEOGRAPH
+0xB9B4 0x52FE #CJK UNIFIED IDEOGRAPH
+0xB9B5 0x6C9F #CJK UNIFIED IDEOGRAPH
+0xB9B6 0x82DF #CJK UNIFIED IDEOGRAPH
+0xB9B7 0x72D7 #CJK UNIFIED IDEOGRAPH
+0xB9B8 0x57A2 #CJK UNIFIED IDEOGRAPH
+0xB9B9 0x6784 #CJK UNIFIED IDEOGRAPH
+0xB9BA 0x8D2D #CJK UNIFIED IDEOGRAPH
+0xB9BB 0x591F #CJK UNIFIED IDEOGRAPH
+0xB9BC 0x8F9C #CJK UNIFIED IDEOGRAPH
+0xB9BD 0x83C7 #CJK UNIFIED IDEOGRAPH
+0xB9BE 0x5495 #CJK UNIFIED IDEOGRAPH
+0xB9BF 0x7B8D #CJK UNIFIED IDEOGRAPH
+0xB9C0 0x4F30 #CJK UNIFIED IDEOGRAPH
+0xB9C1 0x6CBD #CJK UNIFIED IDEOGRAPH
+0xB9C2 0x5B64 #CJK UNIFIED IDEOGRAPH
+0xB9C3 0x59D1 #CJK UNIFIED IDEOGRAPH
+0xB9C4 0x9F13 #CJK UNIFIED IDEOGRAPH
+0xB9C5 0x53E4 #CJK UNIFIED IDEOGRAPH
+0xB9C6 0x86CA #CJK UNIFIED IDEOGRAPH
+0xB9C7 0x9AA8 #CJK UNIFIED IDEOGRAPH
+0xB9C8 0x8C37 #CJK UNIFIED IDEOGRAPH
+0xB9C9 0x80A1 #CJK UNIFIED IDEOGRAPH
+0xB9CA 0x6545 #CJK UNIFIED IDEOGRAPH
+0xB9CB 0x987E #CJK UNIFIED IDEOGRAPH
+0xB9CC 0x56FA #CJK UNIFIED IDEOGRAPH
+0xB9CD 0x96C7 #CJK UNIFIED IDEOGRAPH
+0xB9CE 0x522E #CJK UNIFIED IDEOGRAPH
+0xB9CF 0x74DC #CJK UNIFIED IDEOGRAPH
+0xB9D0 0x5250 #CJK UNIFIED IDEOGRAPH
+0xB9D1 0x5BE1 #CJK UNIFIED IDEOGRAPH
+0xB9D2 0x6302 #CJK UNIFIED IDEOGRAPH
+0xB9D3 0x8902 #CJK UNIFIED IDEOGRAPH
+0xB9D4 0x4E56 #CJK UNIFIED IDEOGRAPH
+0xB9D5 0x62D0 #CJK UNIFIED IDEOGRAPH
+0xB9D6 0x602A #CJK UNIFIED IDEOGRAPH
+0xB9D7 0x68FA #CJK UNIFIED IDEOGRAPH
+0xB9D8 0x5173 #CJK UNIFIED IDEOGRAPH
+0xB9D9 0x5B98 #CJK UNIFIED IDEOGRAPH
+0xB9DA 0x51A0 #CJK UNIFIED IDEOGRAPH
+0xB9DB 0x89C2 #CJK UNIFIED IDEOGRAPH
+0xB9DC 0x7BA1 #CJK UNIFIED IDEOGRAPH
+0xB9DD 0x9986 #CJK UNIFIED IDEOGRAPH
+0xB9DE 0x7F50 #CJK UNIFIED IDEOGRAPH
+0xB9DF 0x60EF #CJK UNIFIED IDEOGRAPH
+0xB9E0 0x704C #CJK UNIFIED IDEOGRAPH
+0xB9E1 0x8D2F #CJK UNIFIED IDEOGRAPH
+0xB9E2 0x5149 #CJK UNIFIED IDEOGRAPH
+0xB9E3 0x5E7F #CJK UNIFIED IDEOGRAPH
+0xB9E4 0x901B #CJK UNIFIED IDEOGRAPH
+0xB9E5 0x7470 #CJK UNIFIED IDEOGRAPH
+0xB9E6 0x89C4 #CJK UNIFIED IDEOGRAPH
+0xB9E7 0x572D #CJK UNIFIED IDEOGRAPH
+0xB9E8 0x7845 #CJK UNIFIED IDEOGRAPH
+0xB9E9 0x5F52 #CJK UNIFIED IDEOGRAPH
+0xB9EA 0x9F9F #CJK UNIFIED IDEOGRAPH
+0xB9EB 0x95FA #CJK UNIFIED IDEOGRAPH
+0xB9EC 0x8F68 #CJK UNIFIED IDEOGRAPH
+0xB9ED 0x9B3C #CJK UNIFIED IDEOGRAPH
+0xB9EE 0x8BE1 #CJK UNIFIED IDEOGRAPH
+0xB9EF 0x7678 #CJK UNIFIED IDEOGRAPH
+0xB9F0 0x6842 #CJK UNIFIED IDEOGRAPH
+0xB9F1 0x67DC #CJK UNIFIED IDEOGRAPH
+0xB9F2 0x8DEA #CJK UNIFIED IDEOGRAPH
+0xB9F3 0x8D35 #CJK UNIFIED IDEOGRAPH
+0xB9F4 0x523D #CJK UNIFIED IDEOGRAPH
+0xB9F5 0x8F8A #CJK UNIFIED IDEOGRAPH
+0xB9F6 0x6EDA #CJK UNIFIED IDEOGRAPH
+0xB9F7 0x68CD #CJK UNIFIED IDEOGRAPH
+0xB9F8 0x9505 #CJK UNIFIED IDEOGRAPH
+0xB9F9 0x90ED #CJK UNIFIED IDEOGRAPH
+0xB9FA 0x56FD #CJK UNIFIED IDEOGRAPH
+0xB9FB 0x679C #CJK UNIFIED IDEOGRAPH
+0xB9FC 0x88F9 #CJK UNIFIED IDEOGRAPH
+0xB9FD 0x8FC7 #CJK UNIFIED IDEOGRAPH
+0xB9FE 0x54C8 #CJK UNIFIED IDEOGRAPH
+0xBA40 0x7BC5 #CJK UNIFIED IDEOGRAPH
+0xBA41 0x7BC8 #CJK UNIFIED IDEOGRAPH
+0xBA42 0x7BC9 #CJK UNIFIED IDEOGRAPH
+0xBA43 0x7BCA #CJK UNIFIED IDEOGRAPH
+0xBA44 0x7BCB #CJK UNIFIED IDEOGRAPH
+0xBA45 0x7BCD #CJK UNIFIED IDEOGRAPH
+0xBA46 0x7BCE #CJK UNIFIED IDEOGRAPH
+0xBA47 0x7BCF #CJK UNIFIED IDEOGRAPH
+0xBA48 0x7BD0 #CJK UNIFIED IDEOGRAPH
+0xBA49 0x7BD2 #CJK UNIFIED IDEOGRAPH
+0xBA4A 0x7BD4 #CJK UNIFIED IDEOGRAPH
+0xBA4B 0x7BD5 #CJK UNIFIED IDEOGRAPH
+0xBA4C 0x7BD6 #CJK UNIFIED IDEOGRAPH
+0xBA4D 0x7BD7 #CJK UNIFIED IDEOGRAPH
+0xBA4E 0x7BD8 #CJK UNIFIED IDEOGRAPH
+0xBA4F 0x7BDB #CJK UNIFIED IDEOGRAPH
+0xBA50 0x7BDC #CJK UNIFIED IDEOGRAPH
+0xBA51 0x7BDE #CJK UNIFIED IDEOGRAPH
+0xBA52 0x7BDF #CJK UNIFIED IDEOGRAPH
+0xBA53 0x7BE0 #CJK UNIFIED IDEOGRAPH
+0xBA54 0x7BE2 #CJK UNIFIED IDEOGRAPH
+0xBA55 0x7BE3 #CJK UNIFIED IDEOGRAPH
+0xBA56 0x7BE4 #CJK UNIFIED IDEOGRAPH
+0xBA57 0x7BE7 #CJK UNIFIED IDEOGRAPH
+0xBA58 0x7BE8 #CJK UNIFIED IDEOGRAPH
+0xBA59 0x7BE9 #CJK UNIFIED IDEOGRAPH
+0xBA5A 0x7BEB #CJK UNIFIED IDEOGRAPH
+0xBA5B 0x7BEC #CJK UNIFIED IDEOGRAPH
+0xBA5C 0x7BED #CJK UNIFIED IDEOGRAPH
+0xBA5D 0x7BEF #CJK UNIFIED IDEOGRAPH
+0xBA5E 0x7BF0 #CJK UNIFIED IDEOGRAPH
+0xBA5F 0x7BF2 #CJK UNIFIED IDEOGRAPH
+0xBA60 0x7BF3 #CJK UNIFIED IDEOGRAPH
+0xBA61 0x7BF4 #CJK UNIFIED IDEOGRAPH
+0xBA62 0x7BF5 #CJK UNIFIED IDEOGRAPH
+0xBA63 0x7BF6 #CJK UNIFIED IDEOGRAPH
+0xBA64 0x7BF8 #CJK UNIFIED IDEOGRAPH
+0xBA65 0x7BF9 #CJK UNIFIED IDEOGRAPH
+0xBA66 0x7BFA #CJK UNIFIED IDEOGRAPH
+0xBA67 0x7BFB #CJK UNIFIED IDEOGRAPH
+0xBA68 0x7BFD #CJK UNIFIED IDEOGRAPH
+0xBA69 0x7BFF #CJK UNIFIED IDEOGRAPH
+0xBA6A 0x7C00 #CJK UNIFIED IDEOGRAPH
+0xBA6B 0x7C01 #CJK UNIFIED IDEOGRAPH
+0xBA6C 0x7C02 #CJK UNIFIED IDEOGRAPH
+0xBA6D 0x7C03 #CJK UNIFIED IDEOGRAPH
+0xBA6E 0x7C04 #CJK UNIFIED IDEOGRAPH
+0xBA6F 0x7C05 #CJK UNIFIED IDEOGRAPH
+0xBA70 0x7C06 #CJK UNIFIED IDEOGRAPH
+0xBA71 0x7C08 #CJK UNIFIED IDEOGRAPH
+0xBA72 0x7C09 #CJK UNIFIED IDEOGRAPH
+0xBA73 0x7C0A #CJK UNIFIED IDEOGRAPH
+0xBA74 0x7C0D #CJK UNIFIED IDEOGRAPH
+0xBA75 0x7C0E #CJK UNIFIED IDEOGRAPH
+0xBA76 0x7C10 #CJK UNIFIED IDEOGRAPH
+0xBA77 0x7C11 #CJK UNIFIED IDEOGRAPH
+0xBA78 0x7C12 #CJK UNIFIED IDEOGRAPH
+0xBA79 0x7C13 #CJK UNIFIED IDEOGRAPH
+0xBA7A 0x7C14 #CJK UNIFIED IDEOGRAPH
+0xBA7B 0x7C15 #CJK UNIFIED IDEOGRAPH
+0xBA7C 0x7C17 #CJK UNIFIED IDEOGRAPH
+0xBA7D 0x7C18 #CJK UNIFIED IDEOGRAPH
+0xBA7E 0x7C19 #CJK UNIFIED IDEOGRAPH
+0xBA80 0x7C1A #CJK UNIFIED IDEOGRAPH
+0xBA81 0x7C1B #CJK UNIFIED IDEOGRAPH
+0xBA82 0x7C1C #CJK UNIFIED IDEOGRAPH
+0xBA83 0x7C1D #CJK UNIFIED IDEOGRAPH
+0xBA84 0x7C1E #CJK UNIFIED IDEOGRAPH
+0xBA85 0x7C20 #CJK UNIFIED IDEOGRAPH
+0xBA86 0x7C21 #CJK UNIFIED IDEOGRAPH
+0xBA87 0x7C22 #CJK UNIFIED IDEOGRAPH
+0xBA88 0x7C23 #CJK UNIFIED IDEOGRAPH
+0xBA89 0x7C24 #CJK UNIFIED IDEOGRAPH
+0xBA8A 0x7C25 #CJK UNIFIED IDEOGRAPH
+0xBA8B 0x7C28 #CJK UNIFIED IDEOGRAPH
+0xBA8C 0x7C29 #CJK UNIFIED IDEOGRAPH
+0xBA8D 0x7C2B #CJK UNIFIED IDEOGRAPH
+0xBA8E 0x7C2C #CJK UNIFIED IDEOGRAPH
+0xBA8F 0x7C2D #CJK UNIFIED IDEOGRAPH
+0xBA90 0x7C2E #CJK UNIFIED IDEOGRAPH
+0xBA91 0x7C2F #CJK UNIFIED IDEOGRAPH
+0xBA92 0x7C30 #CJK UNIFIED IDEOGRAPH
+0xBA93 0x7C31 #CJK UNIFIED IDEOGRAPH
+0xBA94 0x7C32 #CJK UNIFIED IDEOGRAPH
+0xBA95 0x7C33 #CJK UNIFIED IDEOGRAPH
+0xBA96 0x7C34 #CJK UNIFIED IDEOGRAPH
+0xBA97 0x7C35 #CJK UNIFIED IDEOGRAPH
+0xBA98 0x7C36 #CJK UNIFIED IDEOGRAPH
+0xBA99 0x7C37 #CJK UNIFIED IDEOGRAPH
+0xBA9A 0x7C39 #CJK UNIFIED IDEOGRAPH
+0xBA9B 0x7C3A #CJK UNIFIED IDEOGRAPH
+0xBA9C 0x7C3B #CJK UNIFIED IDEOGRAPH
+0xBA9D 0x7C3C #CJK UNIFIED IDEOGRAPH
+0xBA9E 0x7C3D #CJK UNIFIED IDEOGRAPH
+0xBA9F 0x7C3E #CJK UNIFIED IDEOGRAPH
+0xBAA0 0x7C42 #CJK UNIFIED IDEOGRAPH
+0xBAA1 0x9AB8 #CJK UNIFIED IDEOGRAPH
+0xBAA2 0x5B69 #CJK UNIFIED IDEOGRAPH
+0xBAA3 0x6D77 #CJK UNIFIED IDEOGRAPH
+0xBAA4 0x6C26 #CJK UNIFIED IDEOGRAPH
+0xBAA5 0x4EA5 #CJK UNIFIED IDEOGRAPH
+0xBAA6 0x5BB3 #CJK UNIFIED IDEOGRAPH
+0xBAA7 0x9A87 #CJK UNIFIED IDEOGRAPH
+0xBAA8 0x9163 #CJK UNIFIED IDEOGRAPH
+0xBAA9 0x61A8 #CJK UNIFIED IDEOGRAPH
+0xBAAA 0x90AF #CJK UNIFIED IDEOGRAPH
+0xBAAB 0x97E9 #CJK UNIFIED IDEOGRAPH
+0xBAAC 0x542B #CJK UNIFIED IDEOGRAPH
+0xBAAD 0x6DB5 #CJK UNIFIED IDEOGRAPH
+0xBAAE 0x5BD2 #CJK UNIFIED IDEOGRAPH
+0xBAAF 0x51FD #CJK UNIFIED IDEOGRAPH
+0xBAB0 0x558A #CJK UNIFIED IDEOGRAPH
+0xBAB1 0x7F55 #CJK UNIFIED IDEOGRAPH
+0xBAB2 0x7FF0 #CJK UNIFIED IDEOGRAPH
+0xBAB3 0x64BC #CJK UNIFIED IDEOGRAPH
+0xBAB4 0x634D #CJK UNIFIED IDEOGRAPH
+0xBAB5 0x65F1 #CJK UNIFIED IDEOGRAPH
+0xBAB6 0x61BE #CJK UNIFIED IDEOGRAPH
+0xBAB7 0x608D #CJK UNIFIED IDEOGRAPH
+0xBAB8 0x710A #CJK UNIFIED IDEOGRAPH
+0xBAB9 0x6C57 #CJK UNIFIED IDEOGRAPH
+0xBABA 0x6C49 #CJK UNIFIED IDEOGRAPH
+0xBABB 0x592F #CJK UNIFIED IDEOGRAPH
+0xBABC 0x676D #CJK UNIFIED IDEOGRAPH
+0xBABD 0x822A #CJK UNIFIED IDEOGRAPH
+0xBABE 0x58D5 #CJK UNIFIED IDEOGRAPH
+0xBABF 0x568E #CJK UNIFIED IDEOGRAPH
+0xBAC0 0x8C6A #CJK UNIFIED IDEOGRAPH
+0xBAC1 0x6BEB #CJK UNIFIED IDEOGRAPH
+0xBAC2 0x90DD #CJK UNIFIED IDEOGRAPH
+0xBAC3 0x597D #CJK UNIFIED IDEOGRAPH
+0xBAC4 0x8017 #CJK UNIFIED IDEOGRAPH
+0xBAC5 0x53F7 #CJK UNIFIED IDEOGRAPH
+0xBAC6 0x6D69 #CJK UNIFIED IDEOGRAPH
+0xBAC7 0x5475 #CJK UNIFIED IDEOGRAPH
+0xBAC8 0x559D #CJK UNIFIED IDEOGRAPH
+0xBAC9 0x8377 #CJK UNIFIED IDEOGRAPH
+0xBACA 0x83CF #CJK UNIFIED IDEOGRAPH
+0xBACB 0x6838 #CJK UNIFIED IDEOGRAPH
+0xBACC 0x79BE #CJK UNIFIED IDEOGRAPH
+0xBACD 0x548C #CJK UNIFIED IDEOGRAPH
+0xBACE 0x4F55 #CJK UNIFIED IDEOGRAPH
+0xBACF 0x5408 #CJK UNIFIED IDEOGRAPH
+0xBAD0 0x76D2 #CJK UNIFIED IDEOGRAPH
+0xBAD1 0x8C89 #CJK UNIFIED IDEOGRAPH
+0xBAD2 0x9602 #CJK UNIFIED IDEOGRAPH
+0xBAD3 0x6CB3 #CJK UNIFIED IDEOGRAPH
+0xBAD4 0x6DB8 #CJK UNIFIED IDEOGRAPH
+0xBAD5 0x8D6B #CJK UNIFIED IDEOGRAPH
+0xBAD6 0x8910 #CJK UNIFIED IDEOGRAPH
+0xBAD7 0x9E64 #CJK UNIFIED IDEOGRAPH
+0xBAD8 0x8D3A #CJK UNIFIED IDEOGRAPH
+0xBAD9 0x563F #CJK UNIFIED IDEOGRAPH
+0xBADA 0x9ED1 #CJK UNIFIED IDEOGRAPH
+0xBADB 0x75D5 #CJK UNIFIED IDEOGRAPH
+0xBADC 0x5F88 #CJK UNIFIED IDEOGRAPH
+0xBADD 0x72E0 #CJK UNIFIED IDEOGRAPH
+0xBADE 0x6068 #CJK UNIFIED IDEOGRAPH
+0xBADF 0x54FC #CJK UNIFIED IDEOGRAPH
+0xBAE0 0x4EA8 #CJK UNIFIED IDEOGRAPH
+0xBAE1 0x6A2A #CJK UNIFIED IDEOGRAPH
+0xBAE2 0x8861 #CJK UNIFIED IDEOGRAPH
+0xBAE3 0x6052 #CJK UNIFIED IDEOGRAPH
+0xBAE4 0x8F70 #CJK UNIFIED IDEOGRAPH
+0xBAE5 0x54C4 #CJK UNIFIED IDEOGRAPH
+0xBAE6 0x70D8 #CJK UNIFIED IDEOGRAPH
+0xBAE7 0x8679 #CJK UNIFIED IDEOGRAPH
+0xBAE8 0x9E3F #CJK UNIFIED IDEOGRAPH
+0xBAE9 0x6D2A #CJK UNIFIED IDEOGRAPH
+0xBAEA 0x5B8F #CJK UNIFIED IDEOGRAPH
+0xBAEB 0x5F18 #CJK UNIFIED IDEOGRAPH
+0xBAEC 0x7EA2 #CJK UNIFIED IDEOGRAPH
+0xBAED 0x5589 #CJK UNIFIED IDEOGRAPH
+0xBAEE 0x4FAF #CJK UNIFIED IDEOGRAPH
+0xBAEF 0x7334 #CJK UNIFIED IDEOGRAPH
+0xBAF0 0x543C #CJK UNIFIED IDEOGRAPH
+0xBAF1 0x539A #CJK UNIFIED IDEOGRAPH
+0xBAF2 0x5019 #CJK UNIFIED IDEOGRAPH
+0xBAF3 0x540E #CJK UNIFIED IDEOGRAPH
+0xBAF4 0x547C #CJK UNIFIED IDEOGRAPH
+0xBAF5 0x4E4E #CJK UNIFIED IDEOGRAPH
+0xBAF6 0x5FFD #CJK UNIFIED IDEOGRAPH
+0xBAF7 0x745A #CJK UNIFIED IDEOGRAPH
+0xBAF8 0x58F6 #CJK UNIFIED IDEOGRAPH
+0xBAF9 0x846B #CJK UNIFIED IDEOGRAPH
+0xBAFA 0x80E1 #CJK UNIFIED IDEOGRAPH
+0xBAFB 0x8774 #CJK UNIFIED IDEOGRAPH
+0xBAFC 0x72D0 #CJK UNIFIED IDEOGRAPH
+0xBAFD 0x7CCA #CJK UNIFIED IDEOGRAPH
+0xBAFE 0x6E56 #CJK UNIFIED IDEOGRAPH
+0xBB40 0x7C43 #CJK UNIFIED IDEOGRAPH
+0xBB41 0x7C44 #CJK UNIFIED IDEOGRAPH
+0xBB42 0x7C45 #CJK UNIFIED IDEOGRAPH
+0xBB43 0x7C46 #CJK UNIFIED IDEOGRAPH
+0xBB44 0x7C47 #CJK UNIFIED IDEOGRAPH
+0xBB45 0x7C48 #CJK UNIFIED IDEOGRAPH
+0xBB46 0x7C49 #CJK UNIFIED IDEOGRAPH
+0xBB47 0x7C4A #CJK UNIFIED IDEOGRAPH
+0xBB48 0x7C4B #CJK UNIFIED IDEOGRAPH
+0xBB49 0x7C4C #CJK UNIFIED IDEOGRAPH
+0xBB4A 0x7C4E #CJK UNIFIED IDEOGRAPH
+0xBB4B 0x7C4F #CJK UNIFIED IDEOGRAPH
+0xBB4C 0x7C50 #CJK UNIFIED IDEOGRAPH
+0xBB4D 0x7C51 #CJK UNIFIED IDEOGRAPH
+0xBB4E 0x7C52 #CJK UNIFIED IDEOGRAPH
+0xBB4F 0x7C53 #CJK UNIFIED IDEOGRAPH
+0xBB50 0x7C54 #CJK UNIFIED IDEOGRAPH
+0xBB51 0x7C55 #CJK UNIFIED IDEOGRAPH
+0xBB52 0x7C56 #CJK UNIFIED IDEOGRAPH
+0xBB53 0x7C57 #CJK UNIFIED IDEOGRAPH
+0xBB54 0x7C58 #CJK UNIFIED IDEOGRAPH
+0xBB55 0x7C59 #CJK UNIFIED IDEOGRAPH
+0xBB56 0x7C5A #CJK UNIFIED IDEOGRAPH
+0xBB57 0x7C5B #CJK UNIFIED IDEOGRAPH
+0xBB58 0x7C5C #CJK UNIFIED IDEOGRAPH
+0xBB59 0x7C5D #CJK UNIFIED IDEOGRAPH
+0xBB5A 0x7C5E #CJK UNIFIED IDEOGRAPH
+0xBB5B 0x7C5F #CJK UNIFIED IDEOGRAPH
+0xBB5C 0x7C60 #CJK UNIFIED IDEOGRAPH
+0xBB5D 0x7C61 #CJK UNIFIED IDEOGRAPH
+0xBB5E 0x7C62 #CJK UNIFIED IDEOGRAPH
+0xBB5F 0x7C63 #CJK UNIFIED IDEOGRAPH
+0xBB60 0x7C64 #CJK UNIFIED IDEOGRAPH
+0xBB61 0x7C65 #CJK UNIFIED IDEOGRAPH
+0xBB62 0x7C66 #CJK UNIFIED IDEOGRAPH
+0xBB63 0x7C67 #CJK UNIFIED IDEOGRAPH
+0xBB64 0x7C68 #CJK UNIFIED IDEOGRAPH
+0xBB65 0x7C69 #CJK UNIFIED IDEOGRAPH
+0xBB66 0x7C6A #CJK UNIFIED IDEOGRAPH
+0xBB67 0x7C6B #CJK UNIFIED IDEOGRAPH
+0xBB68 0x7C6C #CJK UNIFIED IDEOGRAPH
+0xBB69 0x7C6D #CJK UNIFIED IDEOGRAPH
+0xBB6A 0x7C6E #CJK UNIFIED IDEOGRAPH
+0xBB6B 0x7C6F #CJK UNIFIED IDEOGRAPH
+0xBB6C 0x7C70 #CJK UNIFIED IDEOGRAPH
+0xBB6D 0x7C71 #CJK UNIFIED IDEOGRAPH
+0xBB6E 0x7C72 #CJK UNIFIED IDEOGRAPH
+0xBB6F 0x7C75 #CJK UNIFIED IDEOGRAPH
+0xBB70 0x7C76 #CJK UNIFIED IDEOGRAPH
+0xBB71 0x7C77 #CJK UNIFIED IDEOGRAPH
+0xBB72 0x7C78 #CJK UNIFIED IDEOGRAPH
+0xBB73 0x7C79 #CJK UNIFIED IDEOGRAPH
+0xBB74 0x7C7A #CJK UNIFIED IDEOGRAPH
+0xBB75 0x7C7E #CJK UNIFIED IDEOGRAPH
+0xBB76 0x7C7F #CJK UNIFIED IDEOGRAPH
+0xBB77 0x7C80 #CJK UNIFIED IDEOGRAPH
+0xBB78 0x7C81 #CJK UNIFIED IDEOGRAPH
+0xBB79 0x7C82 #CJK UNIFIED IDEOGRAPH
+0xBB7A 0x7C83 #CJK UNIFIED IDEOGRAPH
+0xBB7B 0x7C84 #CJK UNIFIED IDEOGRAPH
+0xBB7C 0x7C85 #CJK UNIFIED IDEOGRAPH
+0xBB7D 0x7C86 #CJK UNIFIED IDEOGRAPH
+0xBB7E 0x7C87 #CJK UNIFIED IDEOGRAPH
+0xBB80 0x7C88 #CJK UNIFIED IDEOGRAPH
+0xBB81 0x7C8A #CJK UNIFIED IDEOGRAPH
+0xBB82 0x7C8B #CJK UNIFIED IDEOGRAPH
+0xBB83 0x7C8C #CJK UNIFIED IDEOGRAPH
+0xBB84 0x7C8D #CJK UNIFIED IDEOGRAPH
+0xBB85 0x7C8E #CJK UNIFIED IDEOGRAPH
+0xBB86 0x7C8F #CJK UNIFIED IDEOGRAPH
+0xBB87 0x7C90 #CJK UNIFIED IDEOGRAPH
+0xBB88 0x7C93 #CJK UNIFIED IDEOGRAPH
+0xBB89 0x7C94 #CJK UNIFIED IDEOGRAPH
+0xBB8A 0x7C96 #CJK UNIFIED IDEOGRAPH
+0xBB8B 0x7C99 #CJK UNIFIED IDEOGRAPH
+0xBB8C 0x7C9A #CJK UNIFIED IDEOGRAPH
+0xBB8D 0x7C9B #CJK UNIFIED IDEOGRAPH
+0xBB8E 0x7CA0 #CJK UNIFIED IDEOGRAPH
+0xBB8F 0x7CA1 #CJK UNIFIED IDEOGRAPH
+0xBB90 0x7CA3 #CJK UNIFIED IDEOGRAPH
+0xBB91 0x7CA6 #CJK UNIFIED IDEOGRAPH
+0xBB92 0x7CA7 #CJK UNIFIED IDEOGRAPH
+0xBB93 0x7CA8 #CJK UNIFIED IDEOGRAPH
+0xBB94 0x7CA9 #CJK UNIFIED IDEOGRAPH
+0xBB95 0x7CAB #CJK UNIFIED IDEOGRAPH
+0xBB96 0x7CAC #CJK UNIFIED IDEOGRAPH
+0xBB97 0x7CAD #CJK UNIFIED IDEOGRAPH
+0xBB98 0x7CAF #CJK UNIFIED IDEOGRAPH
+0xBB99 0x7CB0 #CJK UNIFIED IDEOGRAPH
+0xBB9A 0x7CB4 #CJK UNIFIED IDEOGRAPH
+0xBB9B 0x7CB5 #CJK UNIFIED IDEOGRAPH
+0xBB9C 0x7CB6 #CJK UNIFIED IDEOGRAPH
+0xBB9D 0x7CB7 #CJK UNIFIED IDEOGRAPH
+0xBB9E 0x7CB8 #CJK UNIFIED IDEOGRAPH
+0xBB9F 0x7CBA #CJK UNIFIED IDEOGRAPH
+0xBBA0 0x7CBB #CJK UNIFIED IDEOGRAPH
+0xBBA1 0x5F27 #CJK UNIFIED IDEOGRAPH
+0xBBA2 0x864E #CJK UNIFIED IDEOGRAPH
+0xBBA3 0x552C #CJK UNIFIED IDEOGRAPH
+0xBBA4 0x62A4 #CJK UNIFIED IDEOGRAPH
+0xBBA5 0x4E92 #CJK UNIFIED IDEOGRAPH
+0xBBA6 0x6CAA #CJK UNIFIED IDEOGRAPH
+0xBBA7 0x6237 #CJK UNIFIED IDEOGRAPH
+0xBBA8 0x82B1 #CJK UNIFIED IDEOGRAPH
+0xBBA9 0x54D7 #CJK UNIFIED IDEOGRAPH
+0xBBAA 0x534E #CJK UNIFIED IDEOGRAPH
+0xBBAB 0x733E #CJK UNIFIED IDEOGRAPH
+0xBBAC 0x6ED1 #CJK UNIFIED IDEOGRAPH
+0xBBAD 0x753B #CJK UNIFIED IDEOGRAPH
+0xBBAE 0x5212 #CJK UNIFIED IDEOGRAPH
+0xBBAF 0x5316 #CJK UNIFIED IDEOGRAPH
+0xBBB0 0x8BDD #CJK UNIFIED IDEOGRAPH
+0xBBB1 0x69D0 #CJK UNIFIED IDEOGRAPH
+0xBBB2 0x5F8A #CJK UNIFIED IDEOGRAPH
+0xBBB3 0x6000 #CJK UNIFIED IDEOGRAPH
+0xBBB4 0x6DEE #CJK UNIFIED IDEOGRAPH
+0xBBB5 0x574F #CJK UNIFIED IDEOGRAPH
+0xBBB6 0x6B22 #CJK UNIFIED IDEOGRAPH
+0xBBB7 0x73AF #CJK UNIFIED IDEOGRAPH
+0xBBB8 0x6853 #CJK UNIFIED IDEOGRAPH
+0xBBB9 0x8FD8 #CJK UNIFIED IDEOGRAPH
+0xBBBA 0x7F13 #CJK UNIFIED IDEOGRAPH
+0xBBBB 0x6362 #CJK UNIFIED IDEOGRAPH
+0xBBBC 0x60A3 #CJK UNIFIED IDEOGRAPH
+0xBBBD 0x5524 #CJK UNIFIED IDEOGRAPH
+0xBBBE 0x75EA #CJK UNIFIED IDEOGRAPH
+0xBBBF 0x8C62 #CJK UNIFIED IDEOGRAPH
+0xBBC0 0x7115 #CJK UNIFIED IDEOGRAPH
+0xBBC1 0x6DA3 #CJK UNIFIED IDEOGRAPH
+0xBBC2 0x5BA6 #CJK UNIFIED IDEOGRAPH
+0xBBC3 0x5E7B #CJK UNIFIED IDEOGRAPH
+0xBBC4 0x8352 #CJK UNIFIED IDEOGRAPH
+0xBBC5 0x614C #CJK UNIFIED IDEOGRAPH
+0xBBC6 0x9EC4 #CJK UNIFIED IDEOGRAPH
+0xBBC7 0x78FA #CJK UNIFIED IDEOGRAPH
+0xBBC8 0x8757 #CJK UNIFIED IDEOGRAPH
+0xBBC9 0x7C27 #CJK UNIFIED IDEOGRAPH
+0xBBCA 0x7687 #CJK UNIFIED IDEOGRAPH
+0xBBCB 0x51F0 #CJK UNIFIED IDEOGRAPH
+0xBBCC 0x60F6 #CJK UNIFIED IDEOGRAPH
+0xBBCD 0x714C #CJK UNIFIED IDEOGRAPH
+0xBBCE 0x6643 #CJK UNIFIED IDEOGRAPH
+0xBBCF 0x5E4C #CJK UNIFIED IDEOGRAPH
+0xBBD0 0x604D #CJK UNIFIED IDEOGRAPH
+0xBBD1 0x8C0E #CJK UNIFIED IDEOGRAPH
+0xBBD2 0x7070 #CJK UNIFIED IDEOGRAPH
+0xBBD3 0x6325 #CJK UNIFIED IDEOGRAPH
+0xBBD4 0x8F89 #CJK UNIFIED IDEOGRAPH
+0xBBD5 0x5FBD #CJK UNIFIED IDEOGRAPH
+0xBBD6 0x6062 #CJK UNIFIED IDEOGRAPH
+0xBBD7 0x86D4 #CJK UNIFIED IDEOGRAPH
+0xBBD8 0x56DE #CJK UNIFIED IDEOGRAPH
+0xBBD9 0x6BC1 #CJK UNIFIED IDEOGRAPH
+0xBBDA 0x6094 #CJK UNIFIED IDEOGRAPH
+0xBBDB 0x6167 #CJK UNIFIED IDEOGRAPH
+0xBBDC 0x5349 #CJK UNIFIED IDEOGRAPH
+0xBBDD 0x60E0 #CJK UNIFIED IDEOGRAPH
+0xBBDE 0x6666 #CJK UNIFIED IDEOGRAPH
+0xBBDF 0x8D3F #CJK UNIFIED IDEOGRAPH
+0xBBE0 0x79FD #CJK UNIFIED IDEOGRAPH
+0xBBE1 0x4F1A #CJK UNIFIED IDEOGRAPH
+0xBBE2 0x70E9 #CJK UNIFIED IDEOGRAPH
+0xBBE3 0x6C47 #CJK UNIFIED IDEOGRAPH
+0xBBE4 0x8BB3 #CJK UNIFIED IDEOGRAPH
+0xBBE5 0x8BF2 #CJK UNIFIED IDEOGRAPH
+0xBBE6 0x7ED8 #CJK UNIFIED IDEOGRAPH
+0xBBE7 0x8364 #CJK UNIFIED IDEOGRAPH
+0xBBE8 0x660F #CJK UNIFIED IDEOGRAPH
+0xBBE9 0x5A5A #CJK UNIFIED IDEOGRAPH
+0xBBEA 0x9B42 #CJK UNIFIED IDEOGRAPH
+0xBBEB 0x6D51 #CJK UNIFIED IDEOGRAPH
+0xBBEC 0x6DF7 #CJK UNIFIED IDEOGRAPH
+0xBBED 0x8C41 #CJK UNIFIED IDEOGRAPH
+0xBBEE 0x6D3B #CJK UNIFIED IDEOGRAPH
+0xBBEF 0x4F19 #CJK UNIFIED IDEOGRAPH
+0xBBF0 0x706B #CJK UNIFIED IDEOGRAPH
+0xBBF1 0x83B7 #CJK UNIFIED IDEOGRAPH
+0xBBF2 0x6216 #CJK UNIFIED IDEOGRAPH
+0xBBF3 0x60D1 #CJK UNIFIED IDEOGRAPH
+0xBBF4 0x970D #CJK UNIFIED IDEOGRAPH
+0xBBF5 0x8D27 #CJK UNIFIED IDEOGRAPH
+0xBBF6 0x7978 #CJK UNIFIED IDEOGRAPH
+0xBBF7 0x51FB #CJK UNIFIED IDEOGRAPH
+0xBBF8 0x573E #CJK UNIFIED IDEOGRAPH
+0xBBF9 0x57FA #CJK UNIFIED IDEOGRAPH
+0xBBFA 0x673A #CJK UNIFIED IDEOGRAPH
+0xBBFB 0x7578 #CJK UNIFIED IDEOGRAPH
+0xBBFC 0x7A3D #CJK UNIFIED IDEOGRAPH
+0xBBFD 0x79EF #CJK UNIFIED IDEOGRAPH
+0xBBFE 0x7B95 #CJK UNIFIED IDEOGRAPH
+0xBC40 0x7CBF #CJK UNIFIED IDEOGRAPH
+0xBC41 0x7CC0 #CJK UNIFIED IDEOGRAPH
+0xBC42 0x7CC2 #CJK UNIFIED IDEOGRAPH
+0xBC43 0x7CC3 #CJK UNIFIED IDEOGRAPH
+0xBC44 0x7CC4 #CJK UNIFIED IDEOGRAPH
+0xBC45 0x7CC6 #CJK UNIFIED IDEOGRAPH
+0xBC46 0x7CC9 #CJK UNIFIED IDEOGRAPH
+0xBC47 0x7CCB #CJK UNIFIED IDEOGRAPH
+0xBC48 0x7CCE #CJK UNIFIED IDEOGRAPH
+0xBC49 0x7CCF #CJK UNIFIED IDEOGRAPH
+0xBC4A 0x7CD0 #CJK UNIFIED IDEOGRAPH
+0xBC4B 0x7CD1 #CJK UNIFIED IDEOGRAPH
+0xBC4C 0x7CD2 #CJK UNIFIED IDEOGRAPH
+0xBC4D 0x7CD3 #CJK UNIFIED IDEOGRAPH
+0xBC4E 0x7CD4 #CJK UNIFIED IDEOGRAPH
+0xBC4F 0x7CD8 #CJK UNIFIED IDEOGRAPH
+0xBC50 0x7CDA #CJK UNIFIED IDEOGRAPH
+0xBC51 0x7CDB #CJK UNIFIED IDEOGRAPH
+0xBC52 0x7CDD #CJK UNIFIED IDEOGRAPH
+0xBC53 0x7CDE #CJK UNIFIED IDEOGRAPH
+0xBC54 0x7CE1 #CJK UNIFIED IDEOGRAPH
+0xBC55 0x7CE2 #CJK UNIFIED IDEOGRAPH
+0xBC56 0x7CE3 #CJK UNIFIED IDEOGRAPH
+0xBC57 0x7CE4 #CJK UNIFIED IDEOGRAPH
+0xBC58 0x7CE5 #CJK UNIFIED IDEOGRAPH
+0xBC59 0x7CE6 #CJK UNIFIED IDEOGRAPH
+0xBC5A 0x7CE7 #CJK UNIFIED IDEOGRAPH
+0xBC5B 0x7CE9 #CJK UNIFIED IDEOGRAPH
+0xBC5C 0x7CEA #CJK UNIFIED IDEOGRAPH
+0xBC5D 0x7CEB #CJK UNIFIED IDEOGRAPH
+0xBC5E 0x7CEC #CJK UNIFIED IDEOGRAPH
+0xBC5F 0x7CED #CJK UNIFIED IDEOGRAPH
+0xBC60 0x7CEE #CJK UNIFIED IDEOGRAPH
+0xBC61 0x7CF0 #CJK UNIFIED IDEOGRAPH
+0xBC62 0x7CF1 #CJK UNIFIED IDEOGRAPH
+0xBC63 0x7CF2 #CJK UNIFIED IDEOGRAPH
+0xBC64 0x7CF3 #CJK UNIFIED IDEOGRAPH
+0xBC65 0x7CF4 #CJK UNIFIED IDEOGRAPH
+0xBC66 0x7CF5 #CJK UNIFIED IDEOGRAPH
+0xBC67 0x7CF6 #CJK UNIFIED IDEOGRAPH
+0xBC68 0x7CF7 #CJK UNIFIED IDEOGRAPH
+0xBC69 0x7CF9 #CJK UNIFIED IDEOGRAPH
+0xBC6A 0x7CFA #CJK UNIFIED IDEOGRAPH
+0xBC6B 0x7CFC #CJK UNIFIED IDEOGRAPH
+0xBC6C 0x7CFD #CJK UNIFIED IDEOGRAPH
+0xBC6D 0x7CFE #CJK UNIFIED IDEOGRAPH
+0xBC6E 0x7CFF #CJK UNIFIED IDEOGRAPH
+0xBC6F 0x7D00 #CJK UNIFIED IDEOGRAPH
+0xBC70 0x7D01 #CJK UNIFIED IDEOGRAPH
+0xBC71 0x7D02 #CJK UNIFIED IDEOGRAPH
+0xBC72 0x7D03 #CJK UNIFIED IDEOGRAPH
+0xBC73 0x7D04 #CJK UNIFIED IDEOGRAPH
+0xBC74 0x7D05 #CJK UNIFIED IDEOGRAPH
+0xBC75 0x7D06 #CJK UNIFIED IDEOGRAPH
+0xBC76 0x7D07 #CJK UNIFIED IDEOGRAPH
+0xBC77 0x7D08 #CJK UNIFIED IDEOGRAPH
+0xBC78 0x7D09 #CJK UNIFIED IDEOGRAPH
+0xBC79 0x7D0B #CJK UNIFIED IDEOGRAPH
+0xBC7A 0x7D0C #CJK UNIFIED IDEOGRAPH
+0xBC7B 0x7D0D #CJK UNIFIED IDEOGRAPH
+0xBC7C 0x7D0E #CJK UNIFIED IDEOGRAPH
+0xBC7D 0x7D0F #CJK UNIFIED IDEOGRAPH
+0xBC7E 0x7D10 #CJK UNIFIED IDEOGRAPH
+0xBC80 0x7D11 #CJK UNIFIED IDEOGRAPH
+0xBC81 0x7D12 #CJK UNIFIED IDEOGRAPH
+0xBC82 0x7D13 #CJK UNIFIED IDEOGRAPH
+0xBC83 0x7D14 #CJK UNIFIED IDEOGRAPH
+0xBC84 0x7D15 #CJK UNIFIED IDEOGRAPH
+0xBC85 0x7D16 #CJK UNIFIED IDEOGRAPH
+0xBC86 0x7D17 #CJK UNIFIED IDEOGRAPH
+0xBC87 0x7D18 #CJK UNIFIED IDEOGRAPH
+0xBC88 0x7D19 #CJK UNIFIED IDEOGRAPH
+0xBC89 0x7D1A #CJK UNIFIED IDEOGRAPH
+0xBC8A 0x7D1B #CJK UNIFIED IDEOGRAPH
+0xBC8B 0x7D1C #CJK UNIFIED IDEOGRAPH
+0xBC8C 0x7D1D #CJK UNIFIED IDEOGRAPH
+0xBC8D 0x7D1E #CJK UNIFIED IDEOGRAPH
+0xBC8E 0x7D1F #CJK UNIFIED IDEOGRAPH
+0xBC8F 0x7D21 #CJK UNIFIED IDEOGRAPH
+0xBC90 0x7D23 #CJK UNIFIED IDEOGRAPH
+0xBC91 0x7D24 #CJK UNIFIED IDEOGRAPH
+0xBC92 0x7D25 #CJK UNIFIED IDEOGRAPH
+0xBC93 0x7D26 #CJK UNIFIED IDEOGRAPH
+0xBC94 0x7D28 #CJK UNIFIED IDEOGRAPH
+0xBC95 0x7D29 #CJK UNIFIED IDEOGRAPH
+0xBC96 0x7D2A #CJK UNIFIED IDEOGRAPH
+0xBC97 0x7D2C #CJK UNIFIED IDEOGRAPH
+0xBC98 0x7D2D #CJK UNIFIED IDEOGRAPH
+0xBC99 0x7D2E #CJK UNIFIED IDEOGRAPH
+0xBC9A 0x7D30 #CJK UNIFIED IDEOGRAPH
+0xBC9B 0x7D31 #CJK UNIFIED IDEOGRAPH
+0xBC9C 0x7D32 #CJK UNIFIED IDEOGRAPH
+0xBC9D 0x7D33 #CJK UNIFIED IDEOGRAPH
+0xBC9E 0x7D34 #CJK UNIFIED IDEOGRAPH
+0xBC9F 0x7D35 #CJK UNIFIED IDEOGRAPH
+0xBCA0 0x7D36 #CJK UNIFIED IDEOGRAPH
+0xBCA1 0x808C #CJK UNIFIED IDEOGRAPH
+0xBCA2 0x9965 #CJK UNIFIED IDEOGRAPH
+0xBCA3 0x8FF9 #CJK UNIFIED IDEOGRAPH
+0xBCA4 0x6FC0 #CJK UNIFIED IDEOGRAPH
+0xBCA5 0x8BA5 #CJK UNIFIED IDEOGRAPH
+0xBCA6 0x9E21 #CJK UNIFIED IDEOGRAPH
+0xBCA7 0x59EC #CJK UNIFIED IDEOGRAPH
+0xBCA8 0x7EE9 #CJK UNIFIED IDEOGRAPH
+0xBCA9 0x7F09 #CJK UNIFIED IDEOGRAPH
+0xBCAA 0x5409 #CJK UNIFIED IDEOGRAPH
+0xBCAB 0x6781 #CJK UNIFIED IDEOGRAPH
+0xBCAC 0x68D8 #CJK UNIFIED IDEOGRAPH
+0xBCAD 0x8F91 #CJK UNIFIED IDEOGRAPH
+0xBCAE 0x7C4D #CJK UNIFIED IDEOGRAPH
+0xBCAF 0x96C6 #CJK UNIFIED IDEOGRAPH
+0xBCB0 0x53CA #CJK UNIFIED IDEOGRAPH
+0xBCB1 0x6025 #CJK UNIFIED IDEOGRAPH
+0xBCB2 0x75BE #CJK UNIFIED IDEOGRAPH
+0xBCB3 0x6C72 #CJK UNIFIED IDEOGRAPH
+0xBCB4 0x5373 #CJK UNIFIED IDEOGRAPH
+0xBCB5 0x5AC9 #CJK UNIFIED IDEOGRAPH
+0xBCB6 0x7EA7 #CJK UNIFIED IDEOGRAPH
+0xBCB7 0x6324 #CJK UNIFIED IDEOGRAPH
+0xBCB8 0x51E0 #CJK UNIFIED IDEOGRAPH
+0xBCB9 0x810A #CJK UNIFIED IDEOGRAPH
+0xBCBA 0x5DF1 #CJK UNIFIED IDEOGRAPH
+0xBCBB 0x84DF #CJK UNIFIED IDEOGRAPH
+0xBCBC 0x6280 #CJK UNIFIED IDEOGRAPH
+0xBCBD 0x5180 #CJK UNIFIED IDEOGRAPH
+0xBCBE 0x5B63 #CJK UNIFIED IDEOGRAPH
+0xBCBF 0x4F0E #CJK UNIFIED IDEOGRAPH
+0xBCC0 0x796D #CJK UNIFIED IDEOGRAPH
+0xBCC1 0x5242 #CJK UNIFIED IDEOGRAPH
+0xBCC2 0x60B8 #CJK UNIFIED IDEOGRAPH
+0xBCC3 0x6D4E #CJK UNIFIED IDEOGRAPH
+0xBCC4 0x5BC4 #CJK UNIFIED IDEOGRAPH
+0xBCC5 0x5BC2 #CJK UNIFIED IDEOGRAPH
+0xBCC6 0x8BA1 #CJK UNIFIED IDEOGRAPH
+0xBCC7 0x8BB0 #CJK UNIFIED IDEOGRAPH
+0xBCC8 0x65E2 #CJK UNIFIED IDEOGRAPH
+0xBCC9 0x5FCC #CJK UNIFIED IDEOGRAPH
+0xBCCA 0x9645 #CJK UNIFIED IDEOGRAPH
+0xBCCB 0x5993 #CJK UNIFIED IDEOGRAPH
+0xBCCC 0x7EE7 #CJK UNIFIED IDEOGRAPH
+0xBCCD 0x7EAA #CJK UNIFIED IDEOGRAPH
+0xBCCE 0x5609 #CJK UNIFIED IDEOGRAPH
+0xBCCF 0x67B7 #CJK UNIFIED IDEOGRAPH
+0xBCD0 0x5939 #CJK UNIFIED IDEOGRAPH
+0xBCD1 0x4F73 #CJK UNIFIED IDEOGRAPH
+0xBCD2 0x5BB6 #CJK UNIFIED IDEOGRAPH
+0xBCD3 0x52A0 #CJK UNIFIED IDEOGRAPH
+0xBCD4 0x835A #CJK UNIFIED IDEOGRAPH
+0xBCD5 0x988A #CJK UNIFIED IDEOGRAPH
+0xBCD6 0x8D3E #CJK UNIFIED IDEOGRAPH
+0xBCD7 0x7532 #CJK UNIFIED IDEOGRAPH
+0xBCD8 0x94BE #CJK UNIFIED IDEOGRAPH
+0xBCD9 0x5047 #CJK UNIFIED IDEOGRAPH
+0xBCDA 0x7A3C #CJK UNIFIED IDEOGRAPH
+0xBCDB 0x4EF7 #CJK UNIFIED IDEOGRAPH
+0xBCDC 0x67B6 #CJK UNIFIED IDEOGRAPH
+0xBCDD 0x9A7E #CJK UNIFIED IDEOGRAPH
+0xBCDE 0x5AC1 #CJK UNIFIED IDEOGRAPH
+0xBCDF 0x6B7C #CJK UNIFIED IDEOGRAPH
+0xBCE0 0x76D1 #CJK UNIFIED IDEOGRAPH
+0xBCE1 0x575A #CJK UNIFIED IDEOGRAPH
+0xBCE2 0x5C16 #CJK UNIFIED IDEOGRAPH
+0xBCE3 0x7B3A #CJK UNIFIED IDEOGRAPH
+0xBCE4 0x95F4 #CJK UNIFIED IDEOGRAPH
+0xBCE5 0x714E #CJK UNIFIED IDEOGRAPH
+0xBCE6 0x517C #CJK UNIFIED IDEOGRAPH
+0xBCE7 0x80A9 #CJK UNIFIED IDEOGRAPH
+0xBCE8 0x8270 #CJK UNIFIED IDEOGRAPH
+0xBCE9 0x5978 #CJK UNIFIED IDEOGRAPH
+0xBCEA 0x7F04 #CJK UNIFIED IDEOGRAPH
+0xBCEB 0x8327 #CJK UNIFIED IDEOGRAPH
+0xBCEC 0x68C0 #CJK UNIFIED IDEOGRAPH
+0xBCED 0x67EC #CJK UNIFIED IDEOGRAPH
+0xBCEE 0x78B1 #CJK UNIFIED IDEOGRAPH
+0xBCEF 0x7877 #CJK UNIFIED IDEOGRAPH
+0xBCF0 0x62E3 #CJK UNIFIED IDEOGRAPH
+0xBCF1 0x6361 #CJK UNIFIED IDEOGRAPH
+0xBCF2 0x7B80 #CJK UNIFIED IDEOGRAPH
+0xBCF3 0x4FED #CJK UNIFIED IDEOGRAPH
+0xBCF4 0x526A #CJK UNIFIED IDEOGRAPH
+0xBCF5 0x51CF #CJK UNIFIED IDEOGRAPH
+0xBCF6 0x8350 #CJK UNIFIED IDEOGRAPH
+0xBCF7 0x69DB #CJK UNIFIED IDEOGRAPH
+0xBCF8 0x9274 #CJK UNIFIED IDEOGRAPH
+0xBCF9 0x8DF5 #CJK UNIFIED IDEOGRAPH
+0xBCFA 0x8D31 #CJK UNIFIED IDEOGRAPH
+0xBCFB 0x89C1 #CJK UNIFIED IDEOGRAPH
+0xBCFC 0x952E #CJK UNIFIED IDEOGRAPH
+0xBCFD 0x7BAD #CJK UNIFIED IDEOGRAPH
+0xBCFE 0x4EF6 #CJK UNIFIED IDEOGRAPH
+0xBD40 0x7D37 #CJK UNIFIED IDEOGRAPH
+0xBD41 0x7D38 #CJK UNIFIED IDEOGRAPH
+0xBD42 0x7D39 #CJK UNIFIED IDEOGRAPH
+0xBD43 0x7D3A #CJK UNIFIED IDEOGRAPH
+0xBD44 0x7D3B #CJK UNIFIED IDEOGRAPH
+0xBD45 0x7D3C #CJK UNIFIED IDEOGRAPH
+0xBD46 0x7D3D #CJK UNIFIED IDEOGRAPH
+0xBD47 0x7D3E #CJK UNIFIED IDEOGRAPH
+0xBD48 0x7D3F #CJK UNIFIED IDEOGRAPH
+0xBD49 0x7D40 #CJK UNIFIED IDEOGRAPH
+0xBD4A 0x7D41 #CJK UNIFIED IDEOGRAPH
+0xBD4B 0x7D42 #CJK UNIFIED IDEOGRAPH
+0xBD4C 0x7D43 #CJK UNIFIED IDEOGRAPH
+0xBD4D 0x7D44 #CJK UNIFIED IDEOGRAPH
+0xBD4E 0x7D45 #CJK UNIFIED IDEOGRAPH
+0xBD4F 0x7D46 #CJK UNIFIED IDEOGRAPH
+0xBD50 0x7D47 #CJK UNIFIED IDEOGRAPH
+0xBD51 0x7D48 #CJK UNIFIED IDEOGRAPH
+0xBD52 0x7D49 #CJK UNIFIED IDEOGRAPH
+0xBD53 0x7D4A #CJK UNIFIED IDEOGRAPH
+0xBD54 0x7D4B #CJK UNIFIED IDEOGRAPH
+0xBD55 0x7D4C #CJK UNIFIED IDEOGRAPH
+0xBD56 0x7D4D #CJK UNIFIED IDEOGRAPH
+0xBD57 0x7D4E #CJK UNIFIED IDEOGRAPH
+0xBD58 0x7D4F #CJK UNIFIED IDEOGRAPH
+0xBD59 0x7D50 #CJK UNIFIED IDEOGRAPH
+0xBD5A 0x7D51 #CJK UNIFIED IDEOGRAPH
+0xBD5B 0x7D52 #CJK UNIFIED IDEOGRAPH
+0xBD5C 0x7D53 #CJK UNIFIED IDEOGRAPH
+0xBD5D 0x7D54 #CJK UNIFIED IDEOGRAPH
+0xBD5E 0x7D55 #CJK UNIFIED IDEOGRAPH
+0xBD5F 0x7D56 #CJK UNIFIED IDEOGRAPH
+0xBD60 0x7D57 #CJK UNIFIED IDEOGRAPH
+0xBD61 0x7D58 #CJK UNIFIED IDEOGRAPH
+0xBD62 0x7D59 #CJK UNIFIED IDEOGRAPH
+0xBD63 0x7D5A #CJK UNIFIED IDEOGRAPH
+0xBD64 0x7D5B #CJK UNIFIED IDEOGRAPH
+0xBD65 0x7D5C #CJK UNIFIED IDEOGRAPH
+0xBD66 0x7D5D #CJK UNIFIED IDEOGRAPH
+0xBD67 0x7D5E #CJK UNIFIED IDEOGRAPH
+0xBD68 0x7D5F #CJK UNIFIED IDEOGRAPH
+0xBD69 0x7D60 #CJK UNIFIED IDEOGRAPH
+0xBD6A 0x7D61 #CJK UNIFIED IDEOGRAPH
+0xBD6B 0x7D62 #CJK UNIFIED IDEOGRAPH
+0xBD6C 0x7D63 #CJK UNIFIED IDEOGRAPH
+0xBD6D 0x7D64 #CJK UNIFIED IDEOGRAPH
+0xBD6E 0x7D65 #CJK UNIFIED IDEOGRAPH
+0xBD6F 0x7D66 #CJK UNIFIED IDEOGRAPH
+0xBD70 0x7D67 #CJK UNIFIED IDEOGRAPH
+0xBD71 0x7D68 #CJK UNIFIED IDEOGRAPH
+0xBD72 0x7D69 #CJK UNIFIED IDEOGRAPH
+0xBD73 0x7D6A #CJK UNIFIED IDEOGRAPH
+0xBD74 0x7D6B #CJK UNIFIED IDEOGRAPH
+0xBD75 0x7D6C #CJK UNIFIED IDEOGRAPH
+0xBD76 0x7D6D #CJK UNIFIED IDEOGRAPH
+0xBD77 0x7D6F #CJK UNIFIED IDEOGRAPH
+0xBD78 0x7D70 #CJK UNIFIED IDEOGRAPH
+0xBD79 0x7D71 #CJK UNIFIED IDEOGRAPH
+0xBD7A 0x7D72 #CJK UNIFIED IDEOGRAPH
+0xBD7B 0x7D73 #CJK UNIFIED IDEOGRAPH
+0xBD7C 0x7D74 #CJK UNIFIED IDEOGRAPH
+0xBD7D 0x7D75 #CJK UNIFIED IDEOGRAPH
+0xBD7E 0x7D76 #CJK UNIFIED IDEOGRAPH
+0xBD80 0x7D78 #CJK UNIFIED IDEOGRAPH
+0xBD81 0x7D79 #CJK UNIFIED IDEOGRAPH
+0xBD82 0x7D7A #CJK UNIFIED IDEOGRAPH
+0xBD83 0x7D7B #CJK UNIFIED IDEOGRAPH
+0xBD84 0x7D7C #CJK UNIFIED IDEOGRAPH
+0xBD85 0x7D7D #CJK UNIFIED IDEOGRAPH
+0xBD86 0x7D7E #CJK UNIFIED IDEOGRAPH
+0xBD87 0x7D7F #CJK UNIFIED IDEOGRAPH
+0xBD88 0x7D80 #CJK UNIFIED IDEOGRAPH
+0xBD89 0x7D81 #CJK UNIFIED IDEOGRAPH
+0xBD8A 0x7D82 #CJK UNIFIED IDEOGRAPH
+0xBD8B 0x7D83 #CJK UNIFIED IDEOGRAPH
+0xBD8C 0x7D84 #CJK UNIFIED IDEOGRAPH
+0xBD8D 0x7D85 #CJK UNIFIED IDEOGRAPH
+0xBD8E 0x7D86 #CJK UNIFIED IDEOGRAPH
+0xBD8F 0x7D87 #CJK UNIFIED IDEOGRAPH
+0xBD90 0x7D88 #CJK UNIFIED IDEOGRAPH
+0xBD91 0x7D89 #CJK UNIFIED IDEOGRAPH
+0xBD92 0x7D8A #CJK UNIFIED IDEOGRAPH
+0xBD93 0x7D8B #CJK UNIFIED IDEOGRAPH
+0xBD94 0x7D8C #CJK UNIFIED IDEOGRAPH
+0xBD95 0x7D8D #CJK UNIFIED IDEOGRAPH
+0xBD96 0x7D8E #CJK UNIFIED IDEOGRAPH
+0xBD97 0x7D8F #CJK UNIFIED IDEOGRAPH
+0xBD98 0x7D90 #CJK UNIFIED IDEOGRAPH
+0xBD99 0x7D91 #CJK UNIFIED IDEOGRAPH
+0xBD9A 0x7D92 #CJK UNIFIED IDEOGRAPH
+0xBD9B 0x7D93 #CJK UNIFIED IDEOGRAPH
+0xBD9C 0x7D94 #CJK UNIFIED IDEOGRAPH
+0xBD9D 0x7D95 #CJK UNIFIED IDEOGRAPH
+0xBD9E 0x7D96 #CJK UNIFIED IDEOGRAPH
+0xBD9F 0x7D97 #CJK UNIFIED IDEOGRAPH
+0xBDA0 0x7D98 #CJK UNIFIED IDEOGRAPH
+0xBDA1 0x5065 #CJK UNIFIED IDEOGRAPH
+0xBDA2 0x8230 #CJK UNIFIED IDEOGRAPH
+0xBDA3 0x5251 #CJK UNIFIED IDEOGRAPH
+0xBDA4 0x996F #CJK UNIFIED IDEOGRAPH
+0xBDA5 0x6E10 #CJK UNIFIED IDEOGRAPH
+0xBDA6 0x6E85 #CJK UNIFIED IDEOGRAPH
+0xBDA7 0x6DA7 #CJK UNIFIED IDEOGRAPH
+0xBDA8 0x5EFA #CJK UNIFIED IDEOGRAPH
+0xBDA9 0x50F5 #CJK UNIFIED IDEOGRAPH
+0xBDAA 0x59DC #CJK UNIFIED IDEOGRAPH
+0xBDAB 0x5C06 #CJK UNIFIED IDEOGRAPH
+0xBDAC 0x6D46 #CJK UNIFIED IDEOGRAPH
+0xBDAD 0x6C5F #CJK UNIFIED IDEOGRAPH
+0xBDAE 0x7586 #CJK UNIFIED IDEOGRAPH
+0xBDAF 0x848B #CJK UNIFIED IDEOGRAPH
+0xBDB0 0x6868 #CJK UNIFIED IDEOGRAPH
+0xBDB1 0x5956 #CJK UNIFIED IDEOGRAPH
+0xBDB2 0x8BB2 #CJK UNIFIED IDEOGRAPH
+0xBDB3 0x5320 #CJK UNIFIED IDEOGRAPH
+0xBDB4 0x9171 #CJK UNIFIED IDEOGRAPH
+0xBDB5 0x964D #CJK UNIFIED IDEOGRAPH
+0xBDB6 0x8549 #CJK UNIFIED IDEOGRAPH
+0xBDB7 0x6912 #CJK UNIFIED IDEOGRAPH
+0xBDB8 0x7901 #CJK UNIFIED IDEOGRAPH
+0xBDB9 0x7126 #CJK UNIFIED IDEOGRAPH
+0xBDBA 0x80F6 #CJK UNIFIED IDEOGRAPH
+0xBDBB 0x4EA4 #CJK UNIFIED IDEOGRAPH
+0xBDBC 0x90CA #CJK UNIFIED IDEOGRAPH
+0xBDBD 0x6D47 #CJK UNIFIED IDEOGRAPH
+0xBDBE 0x9A84 #CJK UNIFIED IDEOGRAPH
+0xBDBF 0x5A07 #CJK UNIFIED IDEOGRAPH
+0xBDC0 0x56BC #CJK UNIFIED IDEOGRAPH
+0xBDC1 0x6405 #CJK UNIFIED IDEOGRAPH
+0xBDC2 0x94F0 #CJK UNIFIED IDEOGRAPH
+0xBDC3 0x77EB #CJK UNIFIED IDEOGRAPH
+0xBDC4 0x4FA5 #CJK UNIFIED IDEOGRAPH
+0xBDC5 0x811A #CJK UNIFIED IDEOGRAPH
+0xBDC6 0x72E1 #CJK UNIFIED IDEOGRAPH
+0xBDC7 0x89D2 #CJK UNIFIED IDEOGRAPH
+0xBDC8 0x997A #CJK UNIFIED IDEOGRAPH
+0xBDC9 0x7F34 #CJK UNIFIED IDEOGRAPH
+0xBDCA 0x7EDE #CJK UNIFIED IDEOGRAPH
+0xBDCB 0x527F #CJK UNIFIED IDEOGRAPH
+0xBDCC 0x6559 #CJK UNIFIED IDEOGRAPH
+0xBDCD 0x9175 #CJK UNIFIED IDEOGRAPH
+0xBDCE 0x8F7F #CJK UNIFIED IDEOGRAPH
+0xBDCF 0x8F83 #CJK UNIFIED IDEOGRAPH
+0xBDD0 0x53EB #CJK UNIFIED IDEOGRAPH
+0xBDD1 0x7A96 #CJK UNIFIED IDEOGRAPH
+0xBDD2 0x63ED #CJK UNIFIED IDEOGRAPH
+0xBDD3 0x63A5 #CJK UNIFIED IDEOGRAPH
+0xBDD4 0x7686 #CJK UNIFIED IDEOGRAPH
+0xBDD5 0x79F8 #CJK UNIFIED IDEOGRAPH
+0xBDD6 0x8857 #CJK UNIFIED IDEOGRAPH
+0xBDD7 0x9636 #CJK UNIFIED IDEOGRAPH
+0xBDD8 0x622A #CJK UNIFIED IDEOGRAPH
+0xBDD9 0x52AB #CJK UNIFIED IDEOGRAPH
+0xBDDA 0x8282 #CJK UNIFIED IDEOGRAPH
+0xBDDB 0x6854 #CJK UNIFIED IDEOGRAPH
+0xBDDC 0x6770 #CJK UNIFIED IDEOGRAPH
+0xBDDD 0x6377 #CJK UNIFIED IDEOGRAPH
+0xBDDE 0x776B #CJK UNIFIED IDEOGRAPH
+0xBDDF 0x7AED #CJK UNIFIED IDEOGRAPH
+0xBDE0 0x6D01 #CJK UNIFIED IDEOGRAPH
+0xBDE1 0x7ED3 #CJK UNIFIED IDEOGRAPH
+0xBDE2 0x89E3 #CJK UNIFIED IDEOGRAPH
+0xBDE3 0x59D0 #CJK UNIFIED IDEOGRAPH
+0xBDE4 0x6212 #CJK UNIFIED IDEOGRAPH
+0xBDE5 0x85C9 #CJK UNIFIED IDEOGRAPH
+0xBDE6 0x82A5 #CJK UNIFIED IDEOGRAPH
+0xBDE7 0x754C #CJK UNIFIED IDEOGRAPH
+0xBDE8 0x501F #CJK UNIFIED IDEOGRAPH
+0xBDE9 0x4ECB #CJK UNIFIED IDEOGRAPH
+0xBDEA 0x75A5 #CJK UNIFIED IDEOGRAPH
+0xBDEB 0x8BEB #CJK UNIFIED IDEOGRAPH
+0xBDEC 0x5C4A #CJK UNIFIED IDEOGRAPH
+0xBDED 0x5DFE #CJK UNIFIED IDEOGRAPH
+0xBDEE 0x7B4B #CJK UNIFIED IDEOGRAPH
+0xBDEF 0x65A4 #CJK UNIFIED IDEOGRAPH
+0xBDF0 0x91D1 #CJK UNIFIED IDEOGRAPH
+0xBDF1 0x4ECA #CJK UNIFIED IDEOGRAPH
+0xBDF2 0x6D25 #CJK UNIFIED IDEOGRAPH
+0xBDF3 0x895F #CJK UNIFIED IDEOGRAPH
+0xBDF4 0x7D27 #CJK UNIFIED IDEOGRAPH
+0xBDF5 0x9526 #CJK UNIFIED IDEOGRAPH
+0xBDF6 0x4EC5 #CJK UNIFIED IDEOGRAPH
+0xBDF7 0x8C28 #CJK UNIFIED IDEOGRAPH
+0xBDF8 0x8FDB #CJK UNIFIED IDEOGRAPH
+0xBDF9 0x9773 #CJK UNIFIED IDEOGRAPH
+0xBDFA 0x664B #CJK UNIFIED IDEOGRAPH
+0xBDFB 0x7981 #CJK UNIFIED IDEOGRAPH
+0xBDFC 0x8FD1 #CJK UNIFIED IDEOGRAPH
+0xBDFD 0x70EC #CJK UNIFIED IDEOGRAPH
+0xBDFE 0x6D78 #CJK UNIFIED IDEOGRAPH
+0xBE40 0x7D99 #CJK UNIFIED IDEOGRAPH
+0xBE41 0x7D9A #CJK UNIFIED IDEOGRAPH
+0xBE42 0x7D9B #CJK UNIFIED IDEOGRAPH
+0xBE43 0x7D9C #CJK UNIFIED IDEOGRAPH
+0xBE44 0x7D9D #CJK UNIFIED IDEOGRAPH
+0xBE45 0x7D9E #CJK UNIFIED IDEOGRAPH
+0xBE46 0x7D9F #CJK UNIFIED IDEOGRAPH
+0xBE47 0x7DA0 #CJK UNIFIED IDEOGRAPH
+0xBE48 0x7DA1 #CJK UNIFIED IDEOGRAPH
+0xBE49 0x7DA2 #CJK UNIFIED IDEOGRAPH
+0xBE4A 0x7DA3 #CJK UNIFIED IDEOGRAPH
+0xBE4B 0x7DA4 #CJK UNIFIED IDEOGRAPH
+0xBE4C 0x7DA5 #CJK UNIFIED IDEOGRAPH
+0xBE4D 0x7DA7 #CJK UNIFIED IDEOGRAPH
+0xBE4E 0x7DA8 #CJK UNIFIED IDEOGRAPH
+0xBE4F 0x7DA9 #CJK UNIFIED IDEOGRAPH
+0xBE50 0x7DAA #CJK UNIFIED IDEOGRAPH
+0xBE51 0x7DAB #CJK UNIFIED IDEOGRAPH
+0xBE52 0x7DAC #CJK UNIFIED IDEOGRAPH
+0xBE53 0x7DAD #CJK UNIFIED IDEOGRAPH
+0xBE54 0x7DAF #CJK UNIFIED IDEOGRAPH
+0xBE55 0x7DB0 #CJK UNIFIED IDEOGRAPH
+0xBE56 0x7DB1 #CJK UNIFIED IDEOGRAPH
+0xBE57 0x7DB2 #CJK UNIFIED IDEOGRAPH
+0xBE58 0x7DB3 #CJK UNIFIED IDEOGRAPH
+0xBE59 0x7DB4 #CJK UNIFIED IDEOGRAPH
+0xBE5A 0x7DB5 #CJK UNIFIED IDEOGRAPH
+0xBE5B 0x7DB6 #CJK UNIFIED IDEOGRAPH
+0xBE5C 0x7DB7 #CJK UNIFIED IDEOGRAPH
+0xBE5D 0x7DB8 #CJK UNIFIED IDEOGRAPH
+0xBE5E 0x7DB9 #CJK UNIFIED IDEOGRAPH
+0xBE5F 0x7DBA #CJK UNIFIED IDEOGRAPH
+0xBE60 0x7DBB #CJK UNIFIED IDEOGRAPH
+0xBE61 0x7DBC #CJK UNIFIED IDEOGRAPH
+0xBE62 0x7DBD #CJK UNIFIED IDEOGRAPH
+0xBE63 0x7DBE #CJK UNIFIED IDEOGRAPH
+0xBE64 0x7DBF #CJK UNIFIED IDEOGRAPH
+0xBE65 0x7DC0 #CJK UNIFIED IDEOGRAPH
+0xBE66 0x7DC1 #CJK UNIFIED IDEOGRAPH
+0xBE67 0x7DC2 #CJK UNIFIED IDEOGRAPH
+0xBE68 0x7DC3 #CJK UNIFIED IDEOGRAPH
+0xBE69 0x7DC4 #CJK UNIFIED IDEOGRAPH
+0xBE6A 0x7DC5 #CJK UNIFIED IDEOGRAPH
+0xBE6B 0x7DC6 #CJK UNIFIED IDEOGRAPH
+0xBE6C 0x7DC7 #CJK UNIFIED IDEOGRAPH
+0xBE6D 0x7DC8 #CJK UNIFIED IDEOGRAPH
+0xBE6E 0x7DC9 #CJK UNIFIED IDEOGRAPH
+0xBE6F 0x7DCA #CJK UNIFIED IDEOGRAPH
+0xBE70 0x7DCB #CJK UNIFIED IDEOGRAPH
+0xBE71 0x7DCC #CJK UNIFIED IDEOGRAPH
+0xBE72 0x7DCD #CJK UNIFIED IDEOGRAPH
+0xBE73 0x7DCE #CJK UNIFIED IDEOGRAPH
+0xBE74 0x7DCF #CJK UNIFIED IDEOGRAPH
+0xBE75 0x7DD0 #CJK UNIFIED IDEOGRAPH
+0xBE76 0x7DD1 #CJK UNIFIED IDEOGRAPH
+0xBE77 0x7DD2 #CJK UNIFIED IDEOGRAPH
+0xBE78 0x7DD3 #CJK UNIFIED IDEOGRAPH
+0xBE79 0x7DD4 #CJK UNIFIED IDEOGRAPH
+0xBE7A 0x7DD5 #CJK UNIFIED IDEOGRAPH
+0xBE7B 0x7DD6 #CJK UNIFIED IDEOGRAPH
+0xBE7C 0x7DD7 #CJK UNIFIED IDEOGRAPH
+0xBE7D 0x7DD8 #CJK UNIFIED IDEOGRAPH
+0xBE7E 0x7DD9 #CJK UNIFIED IDEOGRAPH
+0xBE80 0x7DDA #CJK UNIFIED IDEOGRAPH
+0xBE81 0x7DDB #CJK UNIFIED IDEOGRAPH
+0xBE82 0x7DDC #CJK UNIFIED IDEOGRAPH
+0xBE83 0x7DDD #CJK UNIFIED IDEOGRAPH
+0xBE84 0x7DDE #CJK UNIFIED IDEOGRAPH
+0xBE85 0x7DDF #CJK UNIFIED IDEOGRAPH
+0xBE86 0x7DE0 #CJK UNIFIED IDEOGRAPH
+0xBE87 0x7DE1 #CJK UNIFIED IDEOGRAPH
+0xBE88 0x7DE2 #CJK UNIFIED IDEOGRAPH
+0xBE89 0x7DE3 #CJK UNIFIED IDEOGRAPH
+0xBE8A 0x7DE4 #CJK UNIFIED IDEOGRAPH
+0xBE8B 0x7DE5 #CJK UNIFIED IDEOGRAPH
+0xBE8C 0x7DE6 #CJK UNIFIED IDEOGRAPH
+0xBE8D 0x7DE7 #CJK UNIFIED IDEOGRAPH
+0xBE8E 0x7DE8 #CJK UNIFIED IDEOGRAPH
+0xBE8F 0x7DE9 #CJK UNIFIED IDEOGRAPH
+0xBE90 0x7DEA #CJK UNIFIED IDEOGRAPH
+0xBE91 0x7DEB #CJK UNIFIED IDEOGRAPH
+0xBE92 0x7DEC #CJK UNIFIED IDEOGRAPH
+0xBE93 0x7DED #CJK UNIFIED IDEOGRAPH
+0xBE94 0x7DEE #CJK UNIFIED IDEOGRAPH
+0xBE95 0x7DEF #CJK UNIFIED IDEOGRAPH
+0xBE96 0x7DF0 #CJK UNIFIED IDEOGRAPH
+0xBE97 0x7DF1 #CJK UNIFIED IDEOGRAPH
+0xBE98 0x7DF2 #CJK UNIFIED IDEOGRAPH
+0xBE99 0x7DF3 #CJK UNIFIED IDEOGRAPH
+0xBE9A 0x7DF4 #CJK UNIFIED IDEOGRAPH
+0xBE9B 0x7DF5 #CJK UNIFIED IDEOGRAPH
+0xBE9C 0x7DF6 #CJK UNIFIED IDEOGRAPH
+0xBE9D 0x7DF7 #CJK UNIFIED IDEOGRAPH
+0xBE9E 0x7DF8 #CJK UNIFIED IDEOGRAPH
+0xBE9F 0x7DF9 #CJK UNIFIED IDEOGRAPH
+0xBEA0 0x7DFA #CJK UNIFIED IDEOGRAPH
+0xBEA1 0x5C3D #CJK UNIFIED IDEOGRAPH
+0xBEA2 0x52B2 #CJK UNIFIED IDEOGRAPH
+0xBEA3 0x8346 #CJK UNIFIED IDEOGRAPH
+0xBEA4 0x5162 #CJK UNIFIED IDEOGRAPH
+0xBEA5 0x830E #CJK UNIFIED IDEOGRAPH
+0xBEA6 0x775B #CJK UNIFIED IDEOGRAPH
+0xBEA7 0x6676 #CJK UNIFIED IDEOGRAPH
+0xBEA8 0x9CB8 #CJK UNIFIED IDEOGRAPH
+0xBEA9 0x4EAC #CJK UNIFIED IDEOGRAPH
+0xBEAA 0x60CA #CJK UNIFIED IDEOGRAPH
+0xBEAB 0x7CBE #CJK UNIFIED IDEOGRAPH
+0xBEAC 0x7CB3 #CJK UNIFIED IDEOGRAPH
+0xBEAD 0x7ECF #CJK UNIFIED IDEOGRAPH
+0xBEAE 0x4E95 #CJK UNIFIED IDEOGRAPH
+0xBEAF 0x8B66 #CJK UNIFIED IDEOGRAPH
+0xBEB0 0x666F #CJK UNIFIED IDEOGRAPH
+0xBEB1 0x9888 #CJK UNIFIED IDEOGRAPH
+0xBEB2 0x9759 #CJK UNIFIED IDEOGRAPH
+0xBEB3 0x5883 #CJK UNIFIED IDEOGRAPH
+0xBEB4 0x656C #CJK UNIFIED IDEOGRAPH
+0xBEB5 0x955C #CJK UNIFIED IDEOGRAPH
+0xBEB6 0x5F84 #CJK UNIFIED IDEOGRAPH
+0xBEB7 0x75C9 #CJK UNIFIED IDEOGRAPH
+0xBEB8 0x9756 #CJK UNIFIED IDEOGRAPH
+0xBEB9 0x7ADF #CJK UNIFIED IDEOGRAPH
+0xBEBA 0x7ADE #CJK UNIFIED IDEOGRAPH
+0xBEBB 0x51C0 #CJK UNIFIED IDEOGRAPH
+0xBEBC 0x70AF #CJK UNIFIED IDEOGRAPH
+0xBEBD 0x7A98 #CJK UNIFIED IDEOGRAPH
+0xBEBE 0x63EA #CJK UNIFIED IDEOGRAPH
+0xBEBF 0x7A76 #CJK UNIFIED IDEOGRAPH
+0xBEC0 0x7EA0 #CJK UNIFIED IDEOGRAPH
+0xBEC1 0x7396 #CJK UNIFIED IDEOGRAPH
+0xBEC2 0x97ED #CJK UNIFIED IDEOGRAPH
+0xBEC3 0x4E45 #CJK UNIFIED IDEOGRAPH
+0xBEC4 0x7078 #CJK UNIFIED IDEOGRAPH
+0xBEC5 0x4E5D #CJK UNIFIED IDEOGRAPH
+0xBEC6 0x9152 #CJK UNIFIED IDEOGRAPH
+0xBEC7 0x53A9 #CJK UNIFIED IDEOGRAPH
+0xBEC8 0x6551 #CJK UNIFIED IDEOGRAPH
+0xBEC9 0x65E7 #CJK UNIFIED IDEOGRAPH
+0xBECA 0x81FC #CJK UNIFIED IDEOGRAPH
+0xBECB 0x8205 #CJK UNIFIED IDEOGRAPH
+0xBECC 0x548E #CJK UNIFIED IDEOGRAPH
+0xBECD 0x5C31 #CJK UNIFIED IDEOGRAPH
+0xBECE 0x759A #CJK UNIFIED IDEOGRAPH
+0xBECF 0x97A0 #CJK UNIFIED IDEOGRAPH
+0xBED0 0x62D8 #CJK UNIFIED IDEOGRAPH
+0xBED1 0x72D9 #CJK UNIFIED IDEOGRAPH
+0xBED2 0x75BD #CJK UNIFIED IDEOGRAPH
+0xBED3 0x5C45 #CJK UNIFIED IDEOGRAPH
+0xBED4 0x9A79 #CJK UNIFIED IDEOGRAPH
+0xBED5 0x83CA #CJK UNIFIED IDEOGRAPH
+0xBED6 0x5C40 #CJK UNIFIED IDEOGRAPH
+0xBED7 0x5480 #CJK UNIFIED IDEOGRAPH
+0xBED8 0x77E9 #CJK UNIFIED IDEOGRAPH
+0xBED9 0x4E3E #CJK UNIFIED IDEOGRAPH
+0xBEDA 0x6CAE #CJK UNIFIED IDEOGRAPH
+0xBEDB 0x805A #CJK UNIFIED IDEOGRAPH
+0xBEDC 0x62D2 #CJK UNIFIED IDEOGRAPH
+0xBEDD 0x636E #CJK UNIFIED IDEOGRAPH
+0xBEDE 0x5DE8 #CJK UNIFIED IDEOGRAPH
+0xBEDF 0x5177 #CJK UNIFIED IDEOGRAPH
+0xBEE0 0x8DDD #CJK UNIFIED IDEOGRAPH
+0xBEE1 0x8E1E #CJK UNIFIED IDEOGRAPH
+0xBEE2 0x952F #CJK UNIFIED IDEOGRAPH
+0xBEE3 0x4FF1 #CJK UNIFIED IDEOGRAPH
+0xBEE4 0x53E5 #CJK UNIFIED IDEOGRAPH
+0xBEE5 0x60E7 #CJK UNIFIED IDEOGRAPH
+0xBEE6 0x70AC #CJK UNIFIED IDEOGRAPH
+0xBEE7 0x5267 #CJK UNIFIED IDEOGRAPH
+0xBEE8 0x6350 #CJK UNIFIED IDEOGRAPH
+0xBEE9 0x9E43 #CJK UNIFIED IDEOGRAPH
+0xBEEA 0x5A1F #CJK UNIFIED IDEOGRAPH
+0xBEEB 0x5026 #CJK UNIFIED IDEOGRAPH
+0xBEEC 0x7737 #CJK UNIFIED IDEOGRAPH
+0xBEED 0x5377 #CJK UNIFIED IDEOGRAPH
+0xBEEE 0x7EE2 #CJK UNIFIED IDEOGRAPH
+0xBEEF 0x6485 #CJK UNIFIED IDEOGRAPH
+0xBEF0 0x652B #CJK UNIFIED IDEOGRAPH
+0xBEF1 0x6289 #CJK UNIFIED IDEOGRAPH
+0xBEF2 0x6398 #CJK UNIFIED IDEOGRAPH
+0xBEF3 0x5014 #CJK UNIFIED IDEOGRAPH
+0xBEF4 0x7235 #CJK UNIFIED IDEOGRAPH
+0xBEF5 0x89C9 #CJK UNIFIED IDEOGRAPH
+0xBEF6 0x51B3 #CJK UNIFIED IDEOGRAPH
+0xBEF7 0x8BC0 #CJK UNIFIED IDEOGRAPH
+0xBEF8 0x7EDD #CJK UNIFIED IDEOGRAPH
+0xBEF9 0x5747 #CJK UNIFIED IDEOGRAPH
+0xBEFA 0x83CC #CJK UNIFIED IDEOGRAPH
+0xBEFB 0x94A7 #CJK UNIFIED IDEOGRAPH
+0xBEFC 0x519B #CJK UNIFIED IDEOGRAPH
+0xBEFD 0x541B #CJK UNIFIED IDEOGRAPH
+0xBEFE 0x5CFB #CJK UNIFIED IDEOGRAPH
+0xBF40 0x7DFB #CJK UNIFIED IDEOGRAPH
+0xBF41 0x7DFC #CJK UNIFIED IDEOGRAPH
+0xBF42 0x7DFD #CJK UNIFIED IDEOGRAPH
+0xBF43 0x7DFE #CJK UNIFIED IDEOGRAPH
+0xBF44 0x7DFF #CJK UNIFIED IDEOGRAPH
+0xBF45 0x7E00 #CJK UNIFIED IDEOGRAPH
+0xBF46 0x7E01 #CJK UNIFIED IDEOGRAPH
+0xBF47 0x7E02 #CJK UNIFIED IDEOGRAPH
+0xBF48 0x7E03 #CJK UNIFIED IDEOGRAPH
+0xBF49 0x7E04 #CJK UNIFIED IDEOGRAPH
+0xBF4A 0x7E05 #CJK UNIFIED IDEOGRAPH
+0xBF4B 0x7E06 #CJK UNIFIED IDEOGRAPH
+0xBF4C 0x7E07 #CJK UNIFIED IDEOGRAPH
+0xBF4D 0x7E08 #CJK UNIFIED IDEOGRAPH
+0xBF4E 0x7E09 #CJK UNIFIED IDEOGRAPH
+0xBF4F 0x7E0A #CJK UNIFIED IDEOGRAPH
+0xBF50 0x7E0B #CJK UNIFIED IDEOGRAPH
+0xBF51 0x7E0C #CJK UNIFIED IDEOGRAPH
+0xBF52 0x7E0D #CJK UNIFIED IDEOGRAPH
+0xBF53 0x7E0E #CJK UNIFIED IDEOGRAPH
+0xBF54 0x7E0F #CJK UNIFIED IDEOGRAPH
+0xBF55 0x7E10 #CJK UNIFIED IDEOGRAPH
+0xBF56 0x7E11 #CJK UNIFIED IDEOGRAPH
+0xBF57 0x7E12 #CJK UNIFIED IDEOGRAPH
+0xBF58 0x7E13 #CJK UNIFIED IDEOGRAPH
+0xBF59 0x7E14 #CJK UNIFIED IDEOGRAPH
+0xBF5A 0x7E15 #CJK UNIFIED IDEOGRAPH
+0xBF5B 0x7E16 #CJK UNIFIED IDEOGRAPH
+0xBF5C 0x7E17 #CJK UNIFIED IDEOGRAPH
+0xBF5D 0x7E18 #CJK UNIFIED IDEOGRAPH
+0xBF5E 0x7E19 #CJK UNIFIED IDEOGRAPH
+0xBF5F 0x7E1A #CJK UNIFIED IDEOGRAPH
+0xBF60 0x7E1B #CJK UNIFIED IDEOGRAPH
+0xBF61 0x7E1C #CJK UNIFIED IDEOGRAPH
+0xBF62 0x7E1D #CJK UNIFIED IDEOGRAPH
+0xBF63 0x7E1E #CJK UNIFIED IDEOGRAPH
+0xBF64 0x7E1F #CJK UNIFIED IDEOGRAPH
+0xBF65 0x7E20 #CJK UNIFIED IDEOGRAPH
+0xBF66 0x7E21 #CJK UNIFIED IDEOGRAPH
+0xBF67 0x7E22 #CJK UNIFIED IDEOGRAPH
+0xBF68 0x7E23 #CJK UNIFIED IDEOGRAPH
+0xBF69 0x7E24 #CJK UNIFIED IDEOGRAPH
+0xBF6A 0x7E25 #CJK UNIFIED IDEOGRAPH
+0xBF6B 0x7E26 #CJK UNIFIED IDEOGRAPH
+0xBF6C 0x7E27 #CJK UNIFIED IDEOGRAPH
+0xBF6D 0x7E28 #CJK UNIFIED IDEOGRAPH
+0xBF6E 0x7E29 #CJK UNIFIED IDEOGRAPH
+0xBF6F 0x7E2A #CJK UNIFIED IDEOGRAPH
+0xBF70 0x7E2B #CJK UNIFIED IDEOGRAPH
+0xBF71 0x7E2C #CJK UNIFIED IDEOGRAPH
+0xBF72 0x7E2D #CJK UNIFIED IDEOGRAPH
+0xBF73 0x7E2E #CJK UNIFIED IDEOGRAPH
+0xBF74 0x7E2F #CJK UNIFIED IDEOGRAPH
+0xBF75 0x7E30 #CJK UNIFIED IDEOGRAPH
+0xBF76 0x7E31 #CJK UNIFIED IDEOGRAPH
+0xBF77 0x7E32 #CJK UNIFIED IDEOGRAPH
+0xBF78 0x7E33 #CJK UNIFIED IDEOGRAPH
+0xBF79 0x7E34 #CJK UNIFIED IDEOGRAPH
+0xBF7A 0x7E35 #CJK UNIFIED IDEOGRAPH
+0xBF7B 0x7E36 #CJK UNIFIED IDEOGRAPH
+0xBF7C 0x7E37 #CJK UNIFIED IDEOGRAPH
+0xBF7D 0x7E38 #CJK UNIFIED IDEOGRAPH
+0xBF7E 0x7E39 #CJK UNIFIED IDEOGRAPH
+0xBF80 0x7E3A #CJK UNIFIED IDEOGRAPH
+0xBF81 0x7E3C #CJK UNIFIED IDEOGRAPH
+0xBF82 0x7E3D #CJK UNIFIED IDEOGRAPH
+0xBF83 0x7E3E #CJK UNIFIED IDEOGRAPH
+0xBF84 0x7E3F #CJK UNIFIED IDEOGRAPH
+0xBF85 0x7E40 #CJK UNIFIED IDEOGRAPH
+0xBF86 0x7E42 #CJK UNIFIED IDEOGRAPH
+0xBF87 0x7E43 #CJK UNIFIED IDEOGRAPH
+0xBF88 0x7E44 #CJK UNIFIED IDEOGRAPH
+0xBF89 0x7E45 #CJK UNIFIED IDEOGRAPH
+0xBF8A 0x7E46 #CJK UNIFIED IDEOGRAPH
+0xBF8B 0x7E48 #CJK UNIFIED IDEOGRAPH
+0xBF8C 0x7E49 #CJK UNIFIED IDEOGRAPH
+0xBF8D 0x7E4A #CJK UNIFIED IDEOGRAPH
+0xBF8E 0x7E4B #CJK UNIFIED IDEOGRAPH
+0xBF8F 0x7E4C #CJK UNIFIED IDEOGRAPH
+0xBF90 0x7E4D #CJK UNIFIED IDEOGRAPH
+0xBF91 0x7E4E #CJK UNIFIED IDEOGRAPH
+0xBF92 0x7E4F #CJK UNIFIED IDEOGRAPH
+0xBF93 0x7E50 #CJK UNIFIED IDEOGRAPH
+0xBF94 0x7E51 #CJK UNIFIED IDEOGRAPH
+0xBF95 0x7E52 #CJK UNIFIED IDEOGRAPH
+0xBF96 0x7E53 #CJK UNIFIED IDEOGRAPH
+0xBF97 0x7E54 #CJK UNIFIED IDEOGRAPH
+0xBF98 0x7E55 #CJK UNIFIED IDEOGRAPH
+0xBF99 0x7E56 #CJK UNIFIED IDEOGRAPH
+0xBF9A 0x7E57 #CJK UNIFIED IDEOGRAPH
+0xBF9B 0x7E58 #CJK UNIFIED IDEOGRAPH
+0xBF9C 0x7E59 #CJK UNIFIED IDEOGRAPH
+0xBF9D 0x7E5A #CJK UNIFIED IDEOGRAPH
+0xBF9E 0x7E5B #CJK UNIFIED IDEOGRAPH
+0xBF9F 0x7E5C #CJK UNIFIED IDEOGRAPH
+0xBFA0 0x7E5D #CJK UNIFIED IDEOGRAPH
+0xBFA1 0x4FCA #CJK UNIFIED IDEOGRAPH
+0xBFA2 0x7AE3 #CJK UNIFIED IDEOGRAPH
+0xBFA3 0x6D5A #CJK UNIFIED IDEOGRAPH
+0xBFA4 0x90E1 #CJK UNIFIED IDEOGRAPH
+0xBFA5 0x9A8F #CJK UNIFIED IDEOGRAPH
+0xBFA6 0x5580 #CJK UNIFIED IDEOGRAPH
+0xBFA7 0x5496 #CJK UNIFIED IDEOGRAPH
+0xBFA8 0x5361 #CJK UNIFIED IDEOGRAPH
+0xBFA9 0x54AF #CJK UNIFIED IDEOGRAPH
+0xBFAA 0x5F00 #CJK UNIFIED IDEOGRAPH
+0xBFAB 0x63E9 #CJK UNIFIED IDEOGRAPH
+0xBFAC 0x6977 #CJK UNIFIED IDEOGRAPH
+0xBFAD 0x51EF #CJK UNIFIED IDEOGRAPH
+0xBFAE 0x6168 #CJK UNIFIED IDEOGRAPH
+0xBFAF 0x520A #CJK UNIFIED IDEOGRAPH
+0xBFB0 0x582A #CJK UNIFIED IDEOGRAPH
+0xBFB1 0x52D8 #CJK UNIFIED IDEOGRAPH
+0xBFB2 0x574E #CJK UNIFIED IDEOGRAPH
+0xBFB3 0x780D #CJK UNIFIED IDEOGRAPH
+0xBFB4 0x770B #CJK UNIFIED IDEOGRAPH
+0xBFB5 0x5EB7 #CJK UNIFIED IDEOGRAPH
+0xBFB6 0x6177 #CJK UNIFIED IDEOGRAPH
+0xBFB7 0x7CE0 #CJK UNIFIED IDEOGRAPH
+0xBFB8 0x625B #CJK UNIFIED IDEOGRAPH
+0xBFB9 0x6297 #CJK UNIFIED IDEOGRAPH
+0xBFBA 0x4EA2 #CJK UNIFIED IDEOGRAPH
+0xBFBB 0x7095 #CJK UNIFIED IDEOGRAPH
+0xBFBC 0x8003 #CJK UNIFIED IDEOGRAPH
+0xBFBD 0x62F7 #CJK UNIFIED IDEOGRAPH
+0xBFBE 0x70E4 #CJK UNIFIED IDEOGRAPH
+0xBFBF 0x9760 #CJK UNIFIED IDEOGRAPH
+0xBFC0 0x5777 #CJK UNIFIED IDEOGRAPH
+0xBFC1 0x82DB #CJK UNIFIED IDEOGRAPH
+0xBFC2 0x67EF #CJK UNIFIED IDEOGRAPH
+0xBFC3 0x68F5 #CJK UNIFIED IDEOGRAPH
+0xBFC4 0x78D5 #CJK UNIFIED IDEOGRAPH
+0xBFC5 0x9897 #CJK UNIFIED IDEOGRAPH
+0xBFC6 0x79D1 #CJK UNIFIED IDEOGRAPH
+0xBFC7 0x58F3 #CJK UNIFIED IDEOGRAPH
+0xBFC8 0x54B3 #CJK UNIFIED IDEOGRAPH
+0xBFC9 0x53EF #CJK UNIFIED IDEOGRAPH
+0xBFCA 0x6E34 #CJK UNIFIED IDEOGRAPH
+0xBFCB 0x514B #CJK UNIFIED IDEOGRAPH
+0xBFCC 0x523B #CJK UNIFIED IDEOGRAPH
+0xBFCD 0x5BA2 #CJK UNIFIED IDEOGRAPH
+0xBFCE 0x8BFE #CJK UNIFIED IDEOGRAPH
+0xBFCF 0x80AF #CJK UNIFIED IDEOGRAPH
+0xBFD0 0x5543 #CJK UNIFIED IDEOGRAPH
+0xBFD1 0x57A6 #CJK UNIFIED IDEOGRAPH
+0xBFD2 0x6073 #CJK UNIFIED IDEOGRAPH
+0xBFD3 0x5751 #CJK UNIFIED IDEOGRAPH
+0xBFD4 0x542D #CJK UNIFIED IDEOGRAPH
+0xBFD5 0x7A7A #CJK UNIFIED IDEOGRAPH
+0xBFD6 0x6050 #CJK UNIFIED IDEOGRAPH
+0xBFD7 0x5B54 #CJK UNIFIED IDEOGRAPH
+0xBFD8 0x63A7 #CJK UNIFIED IDEOGRAPH
+0xBFD9 0x62A0 #CJK UNIFIED IDEOGRAPH
+0xBFDA 0x53E3 #CJK UNIFIED IDEOGRAPH
+0xBFDB 0x6263 #CJK UNIFIED IDEOGRAPH
+0xBFDC 0x5BC7 #CJK UNIFIED IDEOGRAPH
+0xBFDD 0x67AF #CJK UNIFIED IDEOGRAPH
+0xBFDE 0x54ED #CJK UNIFIED IDEOGRAPH
+0xBFDF 0x7A9F #CJK UNIFIED IDEOGRAPH
+0xBFE0 0x82E6 #CJK UNIFIED IDEOGRAPH
+0xBFE1 0x9177 #CJK UNIFIED IDEOGRAPH
+0xBFE2 0x5E93 #CJK UNIFIED IDEOGRAPH
+0xBFE3 0x88E4 #CJK UNIFIED IDEOGRAPH
+0xBFE4 0x5938 #CJK UNIFIED IDEOGRAPH
+0xBFE5 0x57AE #CJK UNIFIED IDEOGRAPH
+0xBFE6 0x630E #CJK UNIFIED IDEOGRAPH
+0xBFE7 0x8DE8 #CJK UNIFIED IDEOGRAPH
+0xBFE8 0x80EF #CJK UNIFIED IDEOGRAPH
+0xBFE9 0x5757 #CJK UNIFIED IDEOGRAPH
+0xBFEA 0x7B77 #CJK UNIFIED IDEOGRAPH
+0xBFEB 0x4FA9 #CJK UNIFIED IDEOGRAPH
+0xBFEC 0x5FEB #CJK UNIFIED IDEOGRAPH
+0xBFED 0x5BBD #CJK UNIFIED IDEOGRAPH
+0xBFEE 0x6B3E #CJK UNIFIED IDEOGRAPH
+0xBFEF 0x5321 #CJK UNIFIED IDEOGRAPH
+0xBFF0 0x7B50 #CJK UNIFIED IDEOGRAPH
+0xBFF1 0x72C2 #CJK UNIFIED IDEOGRAPH
+0xBFF2 0x6846 #CJK UNIFIED IDEOGRAPH
+0xBFF3 0x77FF #CJK UNIFIED IDEOGRAPH
+0xBFF4 0x7736 #CJK UNIFIED IDEOGRAPH
+0xBFF5 0x65F7 #CJK UNIFIED IDEOGRAPH
+0xBFF6 0x51B5 #CJK UNIFIED IDEOGRAPH
+0xBFF7 0x4E8F #CJK UNIFIED IDEOGRAPH
+0xBFF8 0x76D4 #CJK UNIFIED IDEOGRAPH
+0xBFF9 0x5CBF #CJK UNIFIED IDEOGRAPH
+0xBFFA 0x7AA5 #CJK UNIFIED IDEOGRAPH
+0xBFFB 0x8475 #CJK UNIFIED IDEOGRAPH
+0xBFFC 0x594E #CJK UNIFIED IDEOGRAPH
+0xBFFD 0x9B41 #CJK UNIFIED IDEOGRAPH
+0xBFFE 0x5080 #CJK UNIFIED IDEOGRAPH
+0xC040 0x7E5E #CJK UNIFIED IDEOGRAPH
+0xC041 0x7E5F #CJK UNIFIED IDEOGRAPH
+0xC042 0x7E60 #CJK UNIFIED IDEOGRAPH
+0xC043 0x7E61 #CJK UNIFIED IDEOGRAPH
+0xC044 0x7E62 #CJK UNIFIED IDEOGRAPH
+0xC045 0x7E63 #CJK UNIFIED IDEOGRAPH
+0xC046 0x7E64 #CJK UNIFIED IDEOGRAPH
+0xC047 0x7E65 #CJK UNIFIED IDEOGRAPH
+0xC048 0x7E66 #CJK UNIFIED IDEOGRAPH
+0xC049 0x7E67 #CJK UNIFIED IDEOGRAPH
+0xC04A 0x7E68 #CJK UNIFIED IDEOGRAPH
+0xC04B 0x7E69 #CJK UNIFIED IDEOGRAPH
+0xC04C 0x7E6A #CJK UNIFIED IDEOGRAPH
+0xC04D 0x7E6B #CJK UNIFIED IDEOGRAPH
+0xC04E 0x7E6C #CJK UNIFIED IDEOGRAPH
+0xC04F 0x7E6D #CJK UNIFIED IDEOGRAPH
+0xC050 0x7E6E #CJK UNIFIED IDEOGRAPH
+0xC051 0x7E6F #CJK UNIFIED IDEOGRAPH
+0xC052 0x7E70 #CJK UNIFIED IDEOGRAPH
+0xC053 0x7E71 #CJK UNIFIED IDEOGRAPH
+0xC054 0x7E72 #CJK UNIFIED IDEOGRAPH
+0xC055 0x7E73 #CJK UNIFIED IDEOGRAPH
+0xC056 0x7E74 #CJK UNIFIED IDEOGRAPH
+0xC057 0x7E75 #CJK UNIFIED IDEOGRAPH
+0xC058 0x7E76 #CJK UNIFIED IDEOGRAPH
+0xC059 0x7E77 #CJK UNIFIED IDEOGRAPH
+0xC05A 0x7E78 #CJK UNIFIED IDEOGRAPH
+0xC05B 0x7E79 #CJK UNIFIED IDEOGRAPH
+0xC05C 0x7E7A #CJK UNIFIED IDEOGRAPH
+0xC05D 0x7E7B #CJK UNIFIED IDEOGRAPH
+0xC05E 0x7E7C #CJK UNIFIED IDEOGRAPH
+0xC05F 0x7E7D #CJK UNIFIED IDEOGRAPH
+0xC060 0x7E7E #CJK UNIFIED IDEOGRAPH
+0xC061 0x7E7F #CJK UNIFIED IDEOGRAPH
+0xC062 0x7E80 #CJK UNIFIED IDEOGRAPH
+0xC063 0x7E81 #CJK UNIFIED IDEOGRAPH
+0xC064 0x7E83 #CJK UNIFIED IDEOGRAPH
+0xC065 0x7E84 #CJK UNIFIED IDEOGRAPH
+0xC066 0x7E85 #CJK UNIFIED IDEOGRAPH
+0xC067 0x7E86 #CJK UNIFIED IDEOGRAPH
+0xC068 0x7E87 #CJK UNIFIED IDEOGRAPH
+0xC069 0x7E88 #CJK UNIFIED IDEOGRAPH
+0xC06A 0x7E89 #CJK UNIFIED IDEOGRAPH
+0xC06B 0x7E8A #CJK UNIFIED IDEOGRAPH
+0xC06C 0x7E8B #CJK UNIFIED IDEOGRAPH
+0xC06D 0x7E8C #CJK UNIFIED IDEOGRAPH
+0xC06E 0x7E8D #CJK UNIFIED IDEOGRAPH
+0xC06F 0x7E8E #CJK UNIFIED IDEOGRAPH
+0xC070 0x7E8F #CJK UNIFIED IDEOGRAPH
+0xC071 0x7E90 #CJK UNIFIED IDEOGRAPH
+0xC072 0x7E91 #CJK UNIFIED IDEOGRAPH
+0xC073 0x7E92 #CJK UNIFIED IDEOGRAPH
+0xC074 0x7E93 #CJK UNIFIED IDEOGRAPH
+0xC075 0x7E94 #CJK UNIFIED IDEOGRAPH
+0xC076 0x7E95 #CJK UNIFIED IDEOGRAPH
+0xC077 0x7E96 #CJK UNIFIED IDEOGRAPH
+0xC078 0x7E97 #CJK UNIFIED IDEOGRAPH
+0xC079 0x7E98 #CJK UNIFIED IDEOGRAPH
+0xC07A 0x7E99 #CJK UNIFIED IDEOGRAPH
+0xC07B 0x7E9A #CJK UNIFIED IDEOGRAPH
+0xC07C 0x7E9C #CJK UNIFIED IDEOGRAPH
+0xC07D 0x7E9D #CJK UNIFIED IDEOGRAPH
+0xC07E 0x7E9E #CJK UNIFIED IDEOGRAPH
+0xC080 0x7EAE #CJK UNIFIED IDEOGRAPH
+0xC081 0x7EB4 #CJK UNIFIED IDEOGRAPH
+0xC082 0x7EBB #CJK UNIFIED IDEOGRAPH
+0xC083 0x7EBC #CJK UNIFIED IDEOGRAPH
+0xC084 0x7ED6 #CJK UNIFIED IDEOGRAPH
+0xC085 0x7EE4 #CJK UNIFIED IDEOGRAPH
+0xC086 0x7EEC #CJK UNIFIED IDEOGRAPH
+0xC087 0x7EF9 #CJK UNIFIED IDEOGRAPH
+0xC088 0x7F0A #CJK UNIFIED IDEOGRAPH
+0xC089 0x7F10 #CJK UNIFIED IDEOGRAPH
+0xC08A 0x7F1E #CJK UNIFIED IDEOGRAPH
+0xC08B 0x7F37 #CJK UNIFIED IDEOGRAPH
+0xC08C 0x7F39 #CJK UNIFIED IDEOGRAPH
+0xC08D 0x7F3B #CJK UNIFIED IDEOGRAPH
+0xC08E 0x7F3C #CJK UNIFIED IDEOGRAPH
+0xC08F 0x7F3D #CJK UNIFIED IDEOGRAPH
+0xC090 0x7F3E #CJK UNIFIED IDEOGRAPH
+0xC091 0x7F3F #CJK UNIFIED IDEOGRAPH
+0xC092 0x7F40 #CJK UNIFIED IDEOGRAPH
+0xC093 0x7F41 #CJK UNIFIED IDEOGRAPH
+0xC094 0x7F43 #CJK UNIFIED IDEOGRAPH
+0xC095 0x7F46 #CJK UNIFIED IDEOGRAPH
+0xC096 0x7F47 #CJK UNIFIED IDEOGRAPH
+0xC097 0x7F48 #CJK UNIFIED IDEOGRAPH
+0xC098 0x7F49 #CJK UNIFIED IDEOGRAPH
+0xC099 0x7F4A #CJK UNIFIED IDEOGRAPH
+0xC09A 0x7F4B #CJK UNIFIED IDEOGRAPH
+0xC09B 0x7F4C #CJK UNIFIED IDEOGRAPH
+0xC09C 0x7F4D #CJK UNIFIED IDEOGRAPH
+0xC09D 0x7F4E #CJK UNIFIED IDEOGRAPH
+0xC09E 0x7F4F #CJK UNIFIED IDEOGRAPH
+0xC09F 0x7F52 #CJK UNIFIED IDEOGRAPH
+0xC0A0 0x7F53 #CJK UNIFIED IDEOGRAPH
+0xC0A1 0x9988 #CJK UNIFIED IDEOGRAPH
+0xC0A2 0x6127 #CJK UNIFIED IDEOGRAPH
+0xC0A3 0x6E83 #CJK UNIFIED IDEOGRAPH
+0xC0A4 0x5764 #CJK UNIFIED IDEOGRAPH
+0xC0A5 0x6606 #CJK UNIFIED IDEOGRAPH
+0xC0A6 0x6346 #CJK UNIFIED IDEOGRAPH
+0xC0A7 0x56F0 #CJK UNIFIED IDEOGRAPH
+0xC0A8 0x62EC #CJK UNIFIED IDEOGRAPH
+0xC0A9 0x6269 #CJK UNIFIED IDEOGRAPH
+0xC0AA 0x5ED3 #CJK UNIFIED IDEOGRAPH
+0xC0AB 0x9614 #CJK UNIFIED IDEOGRAPH
+0xC0AC 0x5783 #CJK UNIFIED IDEOGRAPH
+0xC0AD 0x62C9 #CJK UNIFIED IDEOGRAPH
+0xC0AE 0x5587 #CJK UNIFIED IDEOGRAPH
+0xC0AF 0x8721 #CJK UNIFIED IDEOGRAPH
+0xC0B0 0x814A #CJK UNIFIED IDEOGRAPH
+0xC0B1 0x8FA3 #CJK UNIFIED IDEOGRAPH
+0xC0B2 0x5566 #CJK UNIFIED IDEOGRAPH
+0xC0B3 0x83B1 #CJK UNIFIED IDEOGRAPH
+0xC0B4 0x6765 #CJK UNIFIED IDEOGRAPH
+0xC0B5 0x8D56 #CJK UNIFIED IDEOGRAPH
+0xC0B6 0x84DD #CJK UNIFIED IDEOGRAPH
+0xC0B7 0x5A6A #CJK UNIFIED IDEOGRAPH
+0xC0B8 0x680F #CJK UNIFIED IDEOGRAPH
+0xC0B9 0x62E6 #CJK UNIFIED IDEOGRAPH
+0xC0BA 0x7BEE #CJK UNIFIED IDEOGRAPH
+0xC0BB 0x9611 #CJK UNIFIED IDEOGRAPH
+0xC0BC 0x5170 #CJK UNIFIED IDEOGRAPH
+0xC0BD 0x6F9C #CJK UNIFIED IDEOGRAPH
+0xC0BE 0x8C30 #CJK UNIFIED IDEOGRAPH
+0xC0BF 0x63FD #CJK UNIFIED IDEOGRAPH
+0xC0C0 0x89C8 #CJK UNIFIED IDEOGRAPH
+0xC0C1 0x61D2 #CJK UNIFIED IDEOGRAPH
+0xC0C2 0x7F06 #CJK UNIFIED IDEOGRAPH
+0xC0C3 0x70C2 #CJK UNIFIED IDEOGRAPH
+0xC0C4 0x6EE5 #CJK UNIFIED IDEOGRAPH
+0xC0C5 0x7405 #CJK UNIFIED IDEOGRAPH
+0xC0C6 0x6994 #CJK UNIFIED IDEOGRAPH
+0xC0C7 0x72FC #CJK UNIFIED IDEOGRAPH
+0xC0C8 0x5ECA #CJK UNIFIED IDEOGRAPH
+0xC0C9 0x90CE #CJK UNIFIED IDEOGRAPH
+0xC0CA 0x6717 #CJK UNIFIED IDEOGRAPH
+0xC0CB 0x6D6A #CJK UNIFIED IDEOGRAPH
+0xC0CC 0x635E #CJK UNIFIED IDEOGRAPH
+0xC0CD 0x52B3 #CJK UNIFIED IDEOGRAPH
+0xC0CE 0x7262 #CJK UNIFIED IDEOGRAPH
+0xC0CF 0x8001 #CJK UNIFIED IDEOGRAPH
+0xC0D0 0x4F6C #CJK UNIFIED IDEOGRAPH
+0xC0D1 0x59E5 #CJK UNIFIED IDEOGRAPH
+0xC0D2 0x916A #CJK UNIFIED IDEOGRAPH
+0xC0D3 0x70D9 #CJK UNIFIED IDEOGRAPH
+0xC0D4 0x6D9D #CJK UNIFIED IDEOGRAPH
+0xC0D5 0x52D2 #CJK UNIFIED IDEOGRAPH
+0xC0D6 0x4E50 #CJK UNIFIED IDEOGRAPH
+0xC0D7 0x96F7 #CJK UNIFIED IDEOGRAPH
+0xC0D8 0x956D #CJK UNIFIED IDEOGRAPH
+0xC0D9 0x857E #CJK UNIFIED IDEOGRAPH
+0xC0DA 0x78CA #CJK UNIFIED IDEOGRAPH
+0xC0DB 0x7D2F #CJK UNIFIED IDEOGRAPH
+0xC0DC 0x5121 #CJK UNIFIED IDEOGRAPH
+0xC0DD 0x5792 #CJK UNIFIED IDEOGRAPH
+0xC0DE 0x64C2 #CJK UNIFIED IDEOGRAPH
+0xC0DF 0x808B #CJK UNIFIED IDEOGRAPH
+0xC0E0 0x7C7B #CJK UNIFIED IDEOGRAPH
+0xC0E1 0x6CEA #CJK UNIFIED IDEOGRAPH
+0xC0E2 0x68F1 #CJK UNIFIED IDEOGRAPH
+0xC0E3 0x695E #CJK UNIFIED IDEOGRAPH
+0xC0E4 0x51B7 #CJK UNIFIED IDEOGRAPH
+0xC0E5 0x5398 #CJK UNIFIED IDEOGRAPH
+0xC0E6 0x68A8 #CJK UNIFIED IDEOGRAPH
+0xC0E7 0x7281 #CJK UNIFIED IDEOGRAPH
+0xC0E8 0x9ECE #CJK UNIFIED IDEOGRAPH
+0xC0E9 0x7BF1 #CJK UNIFIED IDEOGRAPH
+0xC0EA 0x72F8 #CJK UNIFIED IDEOGRAPH
+0xC0EB 0x79BB #CJK UNIFIED IDEOGRAPH
+0xC0EC 0x6F13 #CJK UNIFIED IDEOGRAPH
+0xC0ED 0x7406 #CJK UNIFIED IDEOGRAPH
+0xC0EE 0x674E #CJK UNIFIED IDEOGRAPH
+0xC0EF 0x91CC #CJK UNIFIED IDEOGRAPH
+0xC0F0 0x9CA4 #CJK UNIFIED IDEOGRAPH
+0xC0F1 0x793C #CJK UNIFIED IDEOGRAPH
+0xC0F2 0x8389 #CJK UNIFIED IDEOGRAPH
+0xC0F3 0x8354 #CJK UNIFIED IDEOGRAPH
+0xC0F4 0x540F #CJK UNIFIED IDEOGRAPH
+0xC0F5 0x6817 #CJK UNIFIED IDEOGRAPH
+0xC0F6 0x4E3D #CJK UNIFIED IDEOGRAPH
+0xC0F7 0x5389 #CJK UNIFIED IDEOGRAPH
+0xC0F8 0x52B1 #CJK UNIFIED IDEOGRAPH
+0xC0F9 0x783E #CJK UNIFIED IDEOGRAPH
+0xC0FA 0x5386 #CJK UNIFIED IDEOGRAPH
+0xC0FB 0x5229 #CJK UNIFIED IDEOGRAPH
+0xC0FC 0x5088 #CJK UNIFIED IDEOGRAPH
+0xC0FD 0x4F8B #CJK UNIFIED IDEOGRAPH
+0xC0FE 0x4FD0 #CJK UNIFIED IDEOGRAPH
+0xC140 0x7F56 #CJK UNIFIED IDEOGRAPH
+0xC141 0x7F59 #CJK UNIFIED IDEOGRAPH
+0xC142 0x7F5B #CJK UNIFIED IDEOGRAPH
+0xC143 0x7F5C #CJK UNIFIED IDEOGRAPH
+0xC144 0x7F5D #CJK UNIFIED IDEOGRAPH
+0xC145 0x7F5E #CJK UNIFIED IDEOGRAPH
+0xC146 0x7F60 #CJK UNIFIED IDEOGRAPH
+0xC147 0x7F63 #CJK UNIFIED IDEOGRAPH
+0xC148 0x7F64 #CJK UNIFIED IDEOGRAPH
+0xC149 0x7F65 #CJK UNIFIED IDEOGRAPH
+0xC14A 0x7F66 #CJK UNIFIED IDEOGRAPH
+0xC14B 0x7F67 #CJK UNIFIED IDEOGRAPH
+0xC14C 0x7F6B #CJK UNIFIED IDEOGRAPH
+0xC14D 0x7F6C #CJK UNIFIED IDEOGRAPH
+0xC14E 0x7F6D #CJK UNIFIED IDEOGRAPH
+0xC14F 0x7F6F #CJK UNIFIED IDEOGRAPH
+0xC150 0x7F70 #CJK UNIFIED IDEOGRAPH
+0xC151 0x7F73 #CJK UNIFIED IDEOGRAPH
+0xC152 0x7F75 #CJK UNIFIED IDEOGRAPH
+0xC153 0x7F76 #CJK UNIFIED IDEOGRAPH
+0xC154 0x7F77 #CJK UNIFIED IDEOGRAPH
+0xC155 0x7F78 #CJK UNIFIED IDEOGRAPH
+0xC156 0x7F7A #CJK UNIFIED IDEOGRAPH
+0xC157 0x7F7B #CJK UNIFIED IDEOGRAPH
+0xC158 0x7F7C #CJK UNIFIED IDEOGRAPH
+0xC159 0x7F7D #CJK UNIFIED IDEOGRAPH
+0xC15A 0x7F7F #CJK UNIFIED IDEOGRAPH
+0xC15B 0x7F80 #CJK UNIFIED IDEOGRAPH
+0xC15C 0x7F82 #CJK UNIFIED IDEOGRAPH
+0xC15D 0x7F83 #CJK UNIFIED IDEOGRAPH
+0xC15E 0x7F84 #CJK UNIFIED IDEOGRAPH
+0xC15F 0x7F85 #CJK UNIFIED IDEOGRAPH
+0xC160 0x7F86 #CJK UNIFIED IDEOGRAPH
+0xC161 0x7F87 #CJK UNIFIED IDEOGRAPH
+0xC162 0x7F88 #CJK UNIFIED IDEOGRAPH
+0xC163 0x7F89 #CJK UNIFIED IDEOGRAPH
+0xC164 0x7F8B #CJK UNIFIED IDEOGRAPH
+0xC165 0x7F8D #CJK UNIFIED IDEOGRAPH
+0xC166 0x7F8F #CJK UNIFIED IDEOGRAPH
+0xC167 0x7F90 #CJK UNIFIED IDEOGRAPH
+0xC168 0x7F91 #CJK UNIFIED IDEOGRAPH
+0xC169 0x7F92 #CJK UNIFIED IDEOGRAPH
+0xC16A 0x7F93 #CJK UNIFIED IDEOGRAPH
+0xC16B 0x7F95 #CJK UNIFIED IDEOGRAPH
+0xC16C 0x7F96 #CJK UNIFIED IDEOGRAPH
+0xC16D 0x7F97 #CJK UNIFIED IDEOGRAPH
+0xC16E 0x7F98 #CJK UNIFIED IDEOGRAPH
+0xC16F 0x7F99 #CJK UNIFIED IDEOGRAPH
+0xC170 0x7F9B #CJK UNIFIED IDEOGRAPH
+0xC171 0x7F9C #CJK UNIFIED IDEOGRAPH
+0xC172 0x7FA0 #CJK UNIFIED IDEOGRAPH
+0xC173 0x7FA2 #CJK UNIFIED IDEOGRAPH
+0xC174 0x7FA3 #CJK UNIFIED IDEOGRAPH
+0xC175 0x7FA5 #CJK UNIFIED IDEOGRAPH
+0xC176 0x7FA6 #CJK UNIFIED IDEOGRAPH
+0xC177 0x7FA8 #CJK UNIFIED IDEOGRAPH
+0xC178 0x7FA9 #CJK UNIFIED IDEOGRAPH
+0xC179 0x7FAA #CJK UNIFIED IDEOGRAPH
+0xC17A 0x7FAB #CJK UNIFIED IDEOGRAPH
+0xC17B 0x7FAC #CJK UNIFIED IDEOGRAPH
+0xC17C 0x7FAD #CJK UNIFIED IDEOGRAPH
+0xC17D 0x7FAE #CJK UNIFIED IDEOGRAPH
+0xC17E 0x7FB1 #CJK UNIFIED IDEOGRAPH
+0xC180 0x7FB3 #CJK UNIFIED IDEOGRAPH
+0xC181 0x7FB4 #CJK UNIFIED IDEOGRAPH
+0xC182 0x7FB5 #CJK UNIFIED IDEOGRAPH
+0xC183 0x7FB6 #CJK UNIFIED IDEOGRAPH
+0xC184 0x7FB7 #CJK UNIFIED IDEOGRAPH
+0xC185 0x7FBA #CJK UNIFIED IDEOGRAPH
+0xC186 0x7FBB #CJK UNIFIED IDEOGRAPH
+0xC187 0x7FBE #CJK UNIFIED IDEOGRAPH
+0xC188 0x7FC0 #CJK UNIFIED IDEOGRAPH
+0xC189 0x7FC2 #CJK UNIFIED IDEOGRAPH
+0xC18A 0x7FC3 #CJK UNIFIED IDEOGRAPH
+0xC18B 0x7FC4 #CJK UNIFIED IDEOGRAPH
+0xC18C 0x7FC6 #CJK UNIFIED IDEOGRAPH
+0xC18D 0x7FC7 #CJK UNIFIED IDEOGRAPH
+0xC18E 0x7FC8 #CJK UNIFIED IDEOGRAPH
+0xC18F 0x7FC9 #CJK UNIFIED IDEOGRAPH
+0xC190 0x7FCB #CJK UNIFIED IDEOGRAPH
+0xC191 0x7FCD #CJK UNIFIED IDEOGRAPH
+0xC192 0x7FCF #CJK UNIFIED IDEOGRAPH
+0xC193 0x7FD0 #CJK UNIFIED IDEOGRAPH
+0xC194 0x7FD1 #CJK UNIFIED IDEOGRAPH
+0xC195 0x7FD2 #CJK UNIFIED IDEOGRAPH
+0xC196 0x7FD3 #CJK UNIFIED IDEOGRAPH
+0xC197 0x7FD6 #CJK UNIFIED IDEOGRAPH
+0xC198 0x7FD7 #CJK UNIFIED IDEOGRAPH
+0xC199 0x7FD9 #CJK UNIFIED IDEOGRAPH
+0xC19A 0x7FDA #CJK UNIFIED IDEOGRAPH
+0xC19B 0x7FDB #CJK UNIFIED IDEOGRAPH
+0xC19C 0x7FDC #CJK UNIFIED IDEOGRAPH
+0xC19D 0x7FDD #CJK UNIFIED IDEOGRAPH
+0xC19E 0x7FDE #CJK UNIFIED IDEOGRAPH
+0xC19F 0x7FE2 #CJK UNIFIED IDEOGRAPH
+0xC1A0 0x7FE3 #CJK UNIFIED IDEOGRAPH
+0xC1A1 0x75E2 #CJK UNIFIED IDEOGRAPH
+0xC1A2 0x7ACB #CJK UNIFIED IDEOGRAPH
+0xC1A3 0x7C92 #CJK UNIFIED IDEOGRAPH
+0xC1A4 0x6CA5 #CJK UNIFIED IDEOGRAPH
+0xC1A5 0x96B6 #CJK UNIFIED IDEOGRAPH
+0xC1A6 0x529B #CJK UNIFIED IDEOGRAPH
+0xC1A7 0x7483 #CJK UNIFIED IDEOGRAPH
+0xC1A8 0x54E9 #CJK UNIFIED IDEOGRAPH
+0xC1A9 0x4FE9 #CJK UNIFIED IDEOGRAPH
+0xC1AA 0x8054 #CJK UNIFIED IDEOGRAPH
+0xC1AB 0x83B2 #CJK UNIFIED IDEOGRAPH
+0xC1AC 0x8FDE #CJK UNIFIED IDEOGRAPH
+0xC1AD 0x9570 #CJK UNIFIED IDEOGRAPH
+0xC1AE 0x5EC9 #CJK UNIFIED IDEOGRAPH
+0xC1AF 0x601C #CJK UNIFIED IDEOGRAPH
+0xC1B0 0x6D9F #CJK UNIFIED IDEOGRAPH
+0xC1B1 0x5E18 #CJK UNIFIED IDEOGRAPH
+0xC1B2 0x655B #CJK UNIFIED IDEOGRAPH
+0xC1B3 0x8138 #CJK UNIFIED IDEOGRAPH
+0xC1B4 0x94FE #CJK UNIFIED IDEOGRAPH
+0xC1B5 0x604B #CJK UNIFIED IDEOGRAPH
+0xC1B6 0x70BC #CJK UNIFIED IDEOGRAPH
+0xC1B7 0x7EC3 #CJK UNIFIED IDEOGRAPH
+0xC1B8 0x7CAE #CJK UNIFIED IDEOGRAPH
+0xC1B9 0x51C9 #CJK UNIFIED IDEOGRAPH
+0xC1BA 0x6881 #CJK UNIFIED IDEOGRAPH
+0xC1BB 0x7CB1 #CJK UNIFIED IDEOGRAPH
+0xC1BC 0x826F #CJK UNIFIED IDEOGRAPH
+0xC1BD 0x4E24 #CJK UNIFIED IDEOGRAPH
+0xC1BE 0x8F86 #CJK UNIFIED IDEOGRAPH
+0xC1BF 0x91CF #CJK UNIFIED IDEOGRAPH
+0xC1C0 0x667E #CJK UNIFIED IDEOGRAPH
+0xC1C1 0x4EAE #CJK UNIFIED IDEOGRAPH
+0xC1C2 0x8C05 #CJK UNIFIED IDEOGRAPH
+0xC1C3 0x64A9 #CJK UNIFIED IDEOGRAPH
+0xC1C4 0x804A #CJK UNIFIED IDEOGRAPH
+0xC1C5 0x50DA #CJK UNIFIED IDEOGRAPH
+0xC1C6 0x7597 #CJK UNIFIED IDEOGRAPH
+0xC1C7 0x71CE #CJK UNIFIED IDEOGRAPH
+0xC1C8 0x5BE5 #CJK UNIFIED IDEOGRAPH
+0xC1C9 0x8FBD #CJK UNIFIED IDEOGRAPH
+0xC1CA 0x6F66 #CJK UNIFIED IDEOGRAPH
+0xC1CB 0x4E86 #CJK UNIFIED IDEOGRAPH
+0xC1CC 0x6482 #CJK UNIFIED IDEOGRAPH
+0xC1CD 0x9563 #CJK UNIFIED IDEOGRAPH
+0xC1CE 0x5ED6 #CJK UNIFIED IDEOGRAPH
+0xC1CF 0x6599 #CJK UNIFIED IDEOGRAPH
+0xC1D0 0x5217 #CJK UNIFIED IDEOGRAPH
+0xC1D1 0x88C2 #CJK UNIFIED IDEOGRAPH
+0xC1D2 0x70C8 #CJK UNIFIED IDEOGRAPH
+0xC1D3 0x52A3 #CJK UNIFIED IDEOGRAPH
+0xC1D4 0x730E #CJK UNIFIED IDEOGRAPH
+0xC1D5 0x7433 #CJK UNIFIED IDEOGRAPH
+0xC1D6 0x6797 #CJK UNIFIED IDEOGRAPH
+0xC1D7 0x78F7 #CJK UNIFIED IDEOGRAPH
+0xC1D8 0x9716 #CJK UNIFIED IDEOGRAPH
+0xC1D9 0x4E34 #CJK UNIFIED IDEOGRAPH
+0xC1DA 0x90BB #CJK UNIFIED IDEOGRAPH
+0xC1DB 0x9CDE #CJK UNIFIED IDEOGRAPH
+0xC1DC 0x6DCB #CJK UNIFIED IDEOGRAPH
+0xC1DD 0x51DB #CJK UNIFIED IDEOGRAPH
+0xC1DE 0x8D41 #CJK UNIFIED IDEOGRAPH
+0xC1DF 0x541D #CJK UNIFIED IDEOGRAPH
+0xC1E0 0x62CE #CJK UNIFIED IDEOGRAPH
+0xC1E1 0x73B2 #CJK UNIFIED IDEOGRAPH
+0xC1E2 0x83F1 #CJK UNIFIED IDEOGRAPH
+0xC1E3 0x96F6 #CJK UNIFIED IDEOGRAPH
+0xC1E4 0x9F84 #CJK UNIFIED IDEOGRAPH
+0xC1E5 0x94C3 #CJK UNIFIED IDEOGRAPH
+0xC1E6 0x4F36 #CJK UNIFIED IDEOGRAPH
+0xC1E7 0x7F9A #CJK UNIFIED IDEOGRAPH
+0xC1E8 0x51CC #CJK UNIFIED IDEOGRAPH
+0xC1E9 0x7075 #CJK UNIFIED IDEOGRAPH
+0xC1EA 0x9675 #CJK UNIFIED IDEOGRAPH
+0xC1EB 0x5CAD #CJK UNIFIED IDEOGRAPH
+0xC1EC 0x9886 #CJK UNIFIED IDEOGRAPH
+0xC1ED 0x53E6 #CJK UNIFIED IDEOGRAPH
+0xC1EE 0x4EE4 #CJK UNIFIED IDEOGRAPH
+0xC1EF 0x6E9C #CJK UNIFIED IDEOGRAPH
+0xC1F0 0x7409 #CJK UNIFIED IDEOGRAPH
+0xC1F1 0x69B4 #CJK UNIFIED IDEOGRAPH
+0xC1F2 0x786B #CJK UNIFIED IDEOGRAPH
+0xC1F3 0x998F #CJK UNIFIED IDEOGRAPH
+0xC1F4 0x7559 #CJK UNIFIED IDEOGRAPH
+0xC1F5 0x5218 #CJK UNIFIED IDEOGRAPH
+0xC1F6 0x7624 #CJK UNIFIED IDEOGRAPH
+0xC1F7 0x6D41 #CJK UNIFIED IDEOGRAPH
+0xC1F8 0x67F3 #CJK UNIFIED IDEOGRAPH
+0xC1F9 0x516D #CJK UNIFIED IDEOGRAPH
+0xC1FA 0x9F99 #CJK UNIFIED IDEOGRAPH
+0xC1FB 0x804B #CJK UNIFIED IDEOGRAPH
+0xC1FC 0x5499 #CJK UNIFIED IDEOGRAPH
+0xC1FD 0x7B3C #CJK UNIFIED IDEOGRAPH
+0xC1FE 0x7ABF #CJK UNIFIED IDEOGRAPH
+0xC240 0x7FE4 #CJK UNIFIED IDEOGRAPH
+0xC241 0x7FE7 #CJK UNIFIED IDEOGRAPH
+0xC242 0x7FE8 #CJK UNIFIED IDEOGRAPH
+0xC243 0x7FEA #CJK UNIFIED IDEOGRAPH
+0xC244 0x7FEB #CJK UNIFIED IDEOGRAPH
+0xC245 0x7FEC #CJK UNIFIED IDEOGRAPH
+0xC246 0x7FED #CJK UNIFIED IDEOGRAPH
+0xC247 0x7FEF #CJK UNIFIED IDEOGRAPH
+0xC248 0x7FF2 #CJK UNIFIED IDEOGRAPH
+0xC249 0x7FF4 #CJK UNIFIED IDEOGRAPH
+0xC24A 0x7FF5 #CJK UNIFIED IDEOGRAPH
+0xC24B 0x7FF6 #CJK UNIFIED IDEOGRAPH
+0xC24C 0x7FF7 #CJK UNIFIED IDEOGRAPH
+0xC24D 0x7FF8 #CJK UNIFIED IDEOGRAPH
+0xC24E 0x7FF9 #CJK UNIFIED IDEOGRAPH
+0xC24F 0x7FFA #CJK UNIFIED IDEOGRAPH
+0xC250 0x7FFD #CJK UNIFIED IDEOGRAPH
+0xC251 0x7FFE #CJK UNIFIED IDEOGRAPH
+0xC252 0x7FFF #CJK UNIFIED IDEOGRAPH
+0xC253 0x8002 #CJK UNIFIED IDEOGRAPH
+0xC254 0x8007 #CJK UNIFIED IDEOGRAPH
+0xC255 0x8008 #CJK UNIFIED IDEOGRAPH
+0xC256 0x8009 #CJK UNIFIED IDEOGRAPH
+0xC257 0x800A #CJK UNIFIED IDEOGRAPH
+0xC258 0x800E #CJK UNIFIED IDEOGRAPH
+0xC259 0x800F #CJK UNIFIED IDEOGRAPH
+0xC25A 0x8011 #CJK UNIFIED IDEOGRAPH
+0xC25B 0x8013 #CJK UNIFIED IDEOGRAPH
+0xC25C 0x801A #CJK UNIFIED IDEOGRAPH
+0xC25D 0x801B #CJK UNIFIED IDEOGRAPH
+0xC25E 0x801D #CJK UNIFIED IDEOGRAPH
+0xC25F 0x801E #CJK UNIFIED IDEOGRAPH
+0xC260 0x801F #CJK UNIFIED IDEOGRAPH
+0xC261 0x8021 #CJK UNIFIED IDEOGRAPH
+0xC262 0x8023 #CJK UNIFIED IDEOGRAPH
+0xC263 0x8024 #CJK UNIFIED IDEOGRAPH
+0xC264 0x802B #CJK UNIFIED IDEOGRAPH
+0xC265 0x802C #CJK UNIFIED IDEOGRAPH
+0xC266 0x802D #CJK UNIFIED IDEOGRAPH
+0xC267 0x802E #CJK UNIFIED IDEOGRAPH
+0xC268 0x802F #CJK UNIFIED IDEOGRAPH
+0xC269 0x8030 #CJK UNIFIED IDEOGRAPH
+0xC26A 0x8032 #CJK UNIFIED IDEOGRAPH
+0xC26B 0x8034 #CJK UNIFIED IDEOGRAPH
+0xC26C 0x8039 #CJK UNIFIED IDEOGRAPH
+0xC26D 0x803A #CJK UNIFIED IDEOGRAPH
+0xC26E 0x803C #CJK UNIFIED IDEOGRAPH
+0xC26F 0x803E #CJK UNIFIED IDEOGRAPH
+0xC270 0x8040 #CJK UNIFIED IDEOGRAPH
+0xC271 0x8041 #CJK UNIFIED IDEOGRAPH
+0xC272 0x8044 #CJK UNIFIED IDEOGRAPH
+0xC273 0x8045 #CJK UNIFIED IDEOGRAPH
+0xC274 0x8047 #CJK UNIFIED IDEOGRAPH
+0xC275 0x8048 #CJK UNIFIED IDEOGRAPH
+0xC276 0x8049 #CJK UNIFIED IDEOGRAPH
+0xC277 0x804E #CJK UNIFIED IDEOGRAPH
+0xC278 0x804F #CJK UNIFIED IDEOGRAPH
+0xC279 0x8050 #CJK UNIFIED IDEOGRAPH
+0xC27A 0x8051 #CJK UNIFIED IDEOGRAPH
+0xC27B 0x8053 #CJK UNIFIED IDEOGRAPH
+0xC27C 0x8055 #CJK UNIFIED IDEOGRAPH
+0xC27D 0x8056 #CJK UNIFIED IDEOGRAPH
+0xC27E 0x8057 #CJK UNIFIED IDEOGRAPH
+0xC280 0x8059 #CJK UNIFIED IDEOGRAPH
+0xC281 0x805B #CJK UNIFIED IDEOGRAPH
+0xC282 0x805C #CJK UNIFIED IDEOGRAPH
+0xC283 0x805D #CJK UNIFIED IDEOGRAPH
+0xC284 0x805E #CJK UNIFIED IDEOGRAPH
+0xC285 0x805F #CJK UNIFIED IDEOGRAPH
+0xC286 0x8060 #CJK UNIFIED IDEOGRAPH
+0xC287 0x8061 #CJK UNIFIED IDEOGRAPH
+0xC288 0x8062 #CJK UNIFIED IDEOGRAPH
+0xC289 0x8063 #CJK UNIFIED IDEOGRAPH
+0xC28A 0x8064 #CJK UNIFIED IDEOGRAPH
+0xC28B 0x8065 #CJK UNIFIED IDEOGRAPH
+0xC28C 0x8066 #CJK UNIFIED IDEOGRAPH
+0xC28D 0x8067 #CJK UNIFIED IDEOGRAPH
+0xC28E 0x8068 #CJK UNIFIED IDEOGRAPH
+0xC28F 0x806B #CJK UNIFIED IDEOGRAPH
+0xC290 0x806C #CJK UNIFIED IDEOGRAPH
+0xC291 0x806D #CJK UNIFIED IDEOGRAPH
+0xC292 0x806E #CJK UNIFIED IDEOGRAPH
+0xC293 0x806F #CJK UNIFIED IDEOGRAPH
+0xC294 0x8070 #CJK UNIFIED IDEOGRAPH
+0xC295 0x8072 #CJK UNIFIED IDEOGRAPH
+0xC296 0x8073 #CJK UNIFIED IDEOGRAPH
+0xC297 0x8074 #CJK UNIFIED IDEOGRAPH
+0xC298 0x8075 #CJK UNIFIED IDEOGRAPH
+0xC299 0x8076 #CJK UNIFIED IDEOGRAPH
+0xC29A 0x8077 #CJK UNIFIED IDEOGRAPH
+0xC29B 0x8078 #CJK UNIFIED IDEOGRAPH
+0xC29C 0x8079 #CJK UNIFIED IDEOGRAPH
+0xC29D 0x807A #CJK UNIFIED IDEOGRAPH
+0xC29E 0x807B #CJK UNIFIED IDEOGRAPH
+0xC29F 0x807C #CJK UNIFIED IDEOGRAPH
+0xC2A0 0x807D #CJK UNIFIED IDEOGRAPH
+0xC2A1 0x9686 #CJK UNIFIED IDEOGRAPH
+0xC2A2 0x5784 #CJK UNIFIED IDEOGRAPH
+0xC2A3 0x62E2 #CJK UNIFIED IDEOGRAPH
+0xC2A4 0x9647 #CJK UNIFIED IDEOGRAPH
+0xC2A5 0x697C #CJK UNIFIED IDEOGRAPH
+0xC2A6 0x5A04 #CJK UNIFIED IDEOGRAPH
+0xC2A7 0x6402 #CJK UNIFIED IDEOGRAPH
+0xC2A8 0x7BD3 #CJK UNIFIED IDEOGRAPH
+0xC2A9 0x6F0F #CJK UNIFIED IDEOGRAPH
+0xC2AA 0x964B #CJK UNIFIED IDEOGRAPH
+0xC2AB 0x82A6 #CJK UNIFIED IDEOGRAPH
+0xC2AC 0x5362 #CJK UNIFIED IDEOGRAPH
+0xC2AD 0x9885 #CJK UNIFIED IDEOGRAPH
+0xC2AE 0x5E90 #CJK UNIFIED IDEOGRAPH
+0xC2AF 0x7089 #CJK UNIFIED IDEOGRAPH
+0xC2B0 0x63B3 #CJK UNIFIED IDEOGRAPH
+0xC2B1 0x5364 #CJK UNIFIED IDEOGRAPH
+0xC2B2 0x864F #CJK UNIFIED IDEOGRAPH
+0xC2B3 0x9C81 #CJK UNIFIED IDEOGRAPH
+0xC2B4 0x9E93 #CJK UNIFIED IDEOGRAPH
+0xC2B5 0x788C #CJK UNIFIED IDEOGRAPH
+0xC2B6 0x9732 #CJK UNIFIED IDEOGRAPH
+0xC2B7 0x8DEF #CJK UNIFIED IDEOGRAPH
+0xC2B8 0x8D42 #CJK UNIFIED IDEOGRAPH
+0xC2B9 0x9E7F #CJK UNIFIED IDEOGRAPH
+0xC2BA 0x6F5E #CJK UNIFIED IDEOGRAPH
+0xC2BB 0x7984 #CJK UNIFIED IDEOGRAPH
+0xC2BC 0x5F55 #CJK UNIFIED IDEOGRAPH
+0xC2BD 0x9646 #CJK UNIFIED IDEOGRAPH
+0xC2BE 0x622E #CJK UNIFIED IDEOGRAPH
+0xC2BF 0x9A74 #CJK UNIFIED IDEOGRAPH
+0xC2C0 0x5415 #CJK UNIFIED IDEOGRAPH
+0xC2C1 0x94DD #CJK UNIFIED IDEOGRAPH
+0xC2C2 0x4FA3 #CJK UNIFIED IDEOGRAPH
+0xC2C3 0x65C5 #CJK UNIFIED IDEOGRAPH
+0xC2C4 0x5C65 #CJK UNIFIED IDEOGRAPH
+0xC2C5 0x5C61 #CJK UNIFIED IDEOGRAPH
+0xC2C6 0x7F15 #CJK UNIFIED IDEOGRAPH
+0xC2C7 0x8651 #CJK UNIFIED IDEOGRAPH
+0xC2C8 0x6C2F #CJK UNIFIED IDEOGRAPH
+0xC2C9 0x5F8B #CJK UNIFIED IDEOGRAPH
+0xC2CA 0x7387 #CJK UNIFIED IDEOGRAPH
+0xC2CB 0x6EE4 #CJK UNIFIED IDEOGRAPH
+0xC2CC 0x7EFF #CJK UNIFIED IDEOGRAPH
+0xC2CD 0x5CE6 #CJK UNIFIED IDEOGRAPH
+0xC2CE 0x631B #CJK UNIFIED IDEOGRAPH
+0xC2CF 0x5B6A #CJK UNIFIED IDEOGRAPH
+0xC2D0 0x6EE6 #CJK UNIFIED IDEOGRAPH
+0xC2D1 0x5375 #CJK UNIFIED IDEOGRAPH
+0xC2D2 0x4E71 #CJK UNIFIED IDEOGRAPH
+0xC2D3 0x63A0 #CJK UNIFIED IDEOGRAPH
+0xC2D4 0x7565 #CJK UNIFIED IDEOGRAPH
+0xC2D5 0x62A1 #CJK UNIFIED IDEOGRAPH
+0xC2D6 0x8F6E #CJK UNIFIED IDEOGRAPH
+0xC2D7 0x4F26 #CJK UNIFIED IDEOGRAPH
+0xC2D8 0x4ED1 #CJK UNIFIED IDEOGRAPH
+0xC2D9 0x6CA6 #CJK UNIFIED IDEOGRAPH
+0xC2DA 0x7EB6 #CJK UNIFIED IDEOGRAPH
+0xC2DB 0x8BBA #CJK UNIFIED IDEOGRAPH
+0xC2DC 0x841D #CJK UNIFIED IDEOGRAPH
+0xC2DD 0x87BA #CJK UNIFIED IDEOGRAPH
+0xC2DE 0x7F57 #CJK UNIFIED IDEOGRAPH
+0xC2DF 0x903B #CJK UNIFIED IDEOGRAPH
+0xC2E0 0x9523 #CJK UNIFIED IDEOGRAPH
+0xC2E1 0x7BA9 #CJK UNIFIED IDEOGRAPH
+0xC2E2 0x9AA1 #CJK UNIFIED IDEOGRAPH
+0xC2E3 0x88F8 #CJK UNIFIED IDEOGRAPH
+0xC2E4 0x843D #CJK UNIFIED IDEOGRAPH
+0xC2E5 0x6D1B #CJK UNIFIED IDEOGRAPH
+0xC2E6 0x9A86 #CJK UNIFIED IDEOGRAPH
+0xC2E7 0x7EDC #CJK UNIFIED IDEOGRAPH
+0xC2E8 0x5988 #CJK UNIFIED IDEOGRAPH
+0xC2E9 0x9EBB #CJK UNIFIED IDEOGRAPH
+0xC2EA 0x739B #CJK UNIFIED IDEOGRAPH
+0xC2EB 0x7801 #CJK UNIFIED IDEOGRAPH
+0xC2EC 0x8682 #CJK UNIFIED IDEOGRAPH
+0xC2ED 0x9A6C #CJK UNIFIED IDEOGRAPH
+0xC2EE 0x9A82 #CJK UNIFIED IDEOGRAPH
+0xC2EF 0x561B #CJK UNIFIED IDEOGRAPH
+0xC2F0 0x5417 #CJK UNIFIED IDEOGRAPH
+0xC2F1 0x57CB #CJK UNIFIED IDEOGRAPH
+0xC2F2 0x4E70 #CJK UNIFIED IDEOGRAPH
+0xC2F3 0x9EA6 #CJK UNIFIED IDEOGRAPH
+0xC2F4 0x5356 #CJK UNIFIED IDEOGRAPH
+0xC2F5 0x8FC8 #CJK UNIFIED IDEOGRAPH
+0xC2F6 0x8109 #CJK UNIFIED IDEOGRAPH
+0xC2F7 0x7792 #CJK UNIFIED IDEOGRAPH
+0xC2F8 0x9992 #CJK UNIFIED IDEOGRAPH
+0xC2F9 0x86EE #CJK UNIFIED IDEOGRAPH
+0xC2FA 0x6EE1 #CJK UNIFIED IDEOGRAPH
+0xC2FB 0x8513 #CJK UNIFIED IDEOGRAPH
+0xC2FC 0x66FC #CJK UNIFIED IDEOGRAPH
+0xC2FD 0x6162 #CJK UNIFIED IDEOGRAPH
+0xC2FE 0x6F2B #CJK UNIFIED IDEOGRAPH
+0xC340 0x807E #CJK UNIFIED IDEOGRAPH
+0xC341 0x8081 #CJK UNIFIED IDEOGRAPH
+0xC342 0x8082 #CJK UNIFIED IDEOGRAPH
+0xC343 0x8085 #CJK UNIFIED IDEOGRAPH
+0xC344 0x8088 #CJK UNIFIED IDEOGRAPH
+0xC345 0x808A #CJK UNIFIED IDEOGRAPH
+0xC346 0x808D #CJK UNIFIED IDEOGRAPH
+0xC347 0x808E #CJK UNIFIED IDEOGRAPH
+0xC348 0x808F #CJK UNIFIED IDEOGRAPH
+0xC349 0x8090 #CJK UNIFIED IDEOGRAPH
+0xC34A 0x8091 #CJK UNIFIED IDEOGRAPH
+0xC34B 0x8092 #CJK UNIFIED IDEOGRAPH
+0xC34C 0x8094 #CJK UNIFIED IDEOGRAPH
+0xC34D 0x8095 #CJK UNIFIED IDEOGRAPH
+0xC34E 0x8097 #CJK UNIFIED IDEOGRAPH
+0xC34F 0x8099 #CJK UNIFIED IDEOGRAPH
+0xC350 0x809E #CJK UNIFIED IDEOGRAPH
+0xC351 0x80A3 #CJK UNIFIED IDEOGRAPH
+0xC352 0x80A6 #CJK UNIFIED IDEOGRAPH
+0xC353 0x80A7 #CJK UNIFIED IDEOGRAPH
+0xC354 0x80A8 #CJK UNIFIED IDEOGRAPH
+0xC355 0x80AC #CJK UNIFIED IDEOGRAPH
+0xC356 0x80B0 #CJK UNIFIED IDEOGRAPH
+0xC357 0x80B3 #CJK UNIFIED IDEOGRAPH
+0xC358 0x80B5 #CJK UNIFIED IDEOGRAPH
+0xC359 0x80B6 #CJK UNIFIED IDEOGRAPH
+0xC35A 0x80B8 #CJK UNIFIED IDEOGRAPH
+0xC35B 0x80B9 #CJK UNIFIED IDEOGRAPH
+0xC35C 0x80BB #CJK UNIFIED IDEOGRAPH
+0xC35D 0x80C5 #CJK UNIFIED IDEOGRAPH
+0xC35E 0x80C7 #CJK UNIFIED IDEOGRAPH
+0xC35F 0x80C8 #CJK UNIFIED IDEOGRAPH
+0xC360 0x80C9 #CJK UNIFIED IDEOGRAPH
+0xC361 0x80CA #CJK UNIFIED IDEOGRAPH
+0xC362 0x80CB #CJK UNIFIED IDEOGRAPH
+0xC363 0x80CF #CJK UNIFIED IDEOGRAPH
+0xC364 0x80D0 #CJK UNIFIED IDEOGRAPH
+0xC365 0x80D1 #CJK UNIFIED IDEOGRAPH
+0xC366 0x80D2 #CJK UNIFIED IDEOGRAPH
+0xC367 0x80D3 #CJK UNIFIED IDEOGRAPH
+0xC368 0x80D4 #CJK UNIFIED IDEOGRAPH
+0xC369 0x80D5 #CJK UNIFIED IDEOGRAPH
+0xC36A 0x80D8 #CJK UNIFIED IDEOGRAPH
+0xC36B 0x80DF #CJK UNIFIED IDEOGRAPH
+0xC36C 0x80E0 #CJK UNIFIED IDEOGRAPH
+0xC36D 0x80E2 #CJK UNIFIED IDEOGRAPH
+0xC36E 0x80E3 #CJK UNIFIED IDEOGRAPH
+0xC36F 0x80E6 #CJK UNIFIED IDEOGRAPH
+0xC370 0x80EE #CJK UNIFIED IDEOGRAPH
+0xC371 0x80F5 #CJK UNIFIED IDEOGRAPH
+0xC372 0x80F7 #CJK UNIFIED IDEOGRAPH
+0xC373 0x80F9 #CJK UNIFIED IDEOGRAPH
+0xC374 0x80FB #CJK UNIFIED IDEOGRAPH
+0xC375 0x80FE #CJK UNIFIED IDEOGRAPH
+0xC376 0x80FF #CJK UNIFIED IDEOGRAPH
+0xC377 0x8100 #CJK UNIFIED IDEOGRAPH
+0xC378 0x8101 #CJK UNIFIED IDEOGRAPH
+0xC379 0x8103 #CJK UNIFIED IDEOGRAPH
+0xC37A 0x8104 #CJK UNIFIED IDEOGRAPH
+0xC37B 0x8105 #CJK UNIFIED IDEOGRAPH
+0xC37C 0x8107 #CJK UNIFIED IDEOGRAPH
+0xC37D 0x8108 #CJK UNIFIED IDEOGRAPH
+0xC37E 0x810B #CJK UNIFIED IDEOGRAPH
+0xC380 0x810C #CJK UNIFIED IDEOGRAPH
+0xC381 0x8115 #CJK UNIFIED IDEOGRAPH
+0xC382 0x8117 #CJK UNIFIED IDEOGRAPH
+0xC383 0x8119 #CJK UNIFIED IDEOGRAPH
+0xC384 0x811B #CJK UNIFIED IDEOGRAPH
+0xC385 0x811C #CJK UNIFIED IDEOGRAPH
+0xC386 0x811D #CJK UNIFIED IDEOGRAPH
+0xC387 0x811F #CJK UNIFIED IDEOGRAPH
+0xC388 0x8120 #CJK UNIFIED IDEOGRAPH
+0xC389 0x8121 #CJK UNIFIED IDEOGRAPH
+0xC38A 0x8122 #CJK UNIFIED IDEOGRAPH
+0xC38B 0x8123 #CJK UNIFIED IDEOGRAPH
+0xC38C 0x8124 #CJK UNIFIED IDEOGRAPH
+0xC38D 0x8125 #CJK UNIFIED IDEOGRAPH
+0xC38E 0x8126 #CJK UNIFIED IDEOGRAPH
+0xC38F 0x8127 #CJK UNIFIED IDEOGRAPH
+0xC390 0x8128 #CJK UNIFIED IDEOGRAPH
+0xC391 0x8129 #CJK UNIFIED IDEOGRAPH
+0xC392 0x812A #CJK UNIFIED IDEOGRAPH
+0xC393 0x812B #CJK UNIFIED IDEOGRAPH
+0xC394 0x812D #CJK UNIFIED IDEOGRAPH
+0xC395 0x812E #CJK UNIFIED IDEOGRAPH
+0xC396 0x8130 #CJK UNIFIED IDEOGRAPH
+0xC397 0x8133 #CJK UNIFIED IDEOGRAPH
+0xC398 0x8134 #CJK UNIFIED IDEOGRAPH
+0xC399 0x8135 #CJK UNIFIED IDEOGRAPH
+0xC39A 0x8137 #CJK UNIFIED IDEOGRAPH
+0xC39B 0x8139 #CJK UNIFIED IDEOGRAPH
+0xC39C 0x813A #CJK UNIFIED IDEOGRAPH
+0xC39D 0x813B #CJK UNIFIED IDEOGRAPH
+0xC39E 0x813C #CJK UNIFIED IDEOGRAPH
+0xC39F 0x813D #CJK UNIFIED IDEOGRAPH
+0xC3A0 0x813F #CJK UNIFIED IDEOGRAPH
+0xC3A1 0x8C29 #CJK UNIFIED IDEOGRAPH
+0xC3A2 0x8292 #CJK UNIFIED IDEOGRAPH
+0xC3A3 0x832B #CJK UNIFIED IDEOGRAPH
+0xC3A4 0x76F2 #CJK UNIFIED IDEOGRAPH
+0xC3A5 0x6C13 #CJK UNIFIED IDEOGRAPH
+0xC3A6 0x5FD9 #CJK UNIFIED IDEOGRAPH
+0xC3A7 0x83BD #CJK UNIFIED IDEOGRAPH
+0xC3A8 0x732B #CJK UNIFIED IDEOGRAPH
+0xC3A9 0x8305 #CJK UNIFIED IDEOGRAPH
+0xC3AA 0x951A #CJK UNIFIED IDEOGRAPH
+0xC3AB 0x6BDB #CJK UNIFIED IDEOGRAPH
+0xC3AC 0x77DB #CJK UNIFIED IDEOGRAPH
+0xC3AD 0x94C6 #CJK UNIFIED IDEOGRAPH
+0xC3AE 0x536F #CJK UNIFIED IDEOGRAPH
+0xC3AF 0x8302 #CJK UNIFIED IDEOGRAPH
+0xC3B0 0x5192 #CJK UNIFIED IDEOGRAPH
+0xC3B1 0x5E3D #CJK UNIFIED IDEOGRAPH
+0xC3B2 0x8C8C #CJK UNIFIED IDEOGRAPH
+0xC3B3 0x8D38 #CJK UNIFIED IDEOGRAPH
+0xC3B4 0x4E48 #CJK UNIFIED IDEOGRAPH
+0xC3B5 0x73AB #CJK UNIFIED IDEOGRAPH
+0xC3B6 0x679A #CJK UNIFIED IDEOGRAPH
+0xC3B7 0x6885 #CJK UNIFIED IDEOGRAPH
+0xC3B8 0x9176 #CJK UNIFIED IDEOGRAPH
+0xC3B9 0x9709 #CJK UNIFIED IDEOGRAPH
+0xC3BA 0x7164 #CJK UNIFIED IDEOGRAPH
+0xC3BB 0x6CA1 #CJK UNIFIED IDEOGRAPH
+0xC3BC 0x7709 #CJK UNIFIED IDEOGRAPH
+0xC3BD 0x5A92 #CJK UNIFIED IDEOGRAPH
+0xC3BE 0x9541 #CJK UNIFIED IDEOGRAPH
+0xC3BF 0x6BCF #CJK UNIFIED IDEOGRAPH
+0xC3C0 0x7F8E #CJK UNIFIED IDEOGRAPH
+0xC3C1 0x6627 #CJK UNIFIED IDEOGRAPH
+0xC3C2 0x5BD0 #CJK UNIFIED IDEOGRAPH
+0xC3C3 0x59B9 #CJK UNIFIED IDEOGRAPH
+0xC3C4 0x5A9A #CJK UNIFIED IDEOGRAPH
+0xC3C5 0x95E8 #CJK UNIFIED IDEOGRAPH
+0xC3C6 0x95F7 #CJK UNIFIED IDEOGRAPH
+0xC3C7 0x4EEC #CJK UNIFIED IDEOGRAPH
+0xC3C8 0x840C #CJK UNIFIED IDEOGRAPH
+0xC3C9 0x8499 #CJK UNIFIED IDEOGRAPH
+0xC3CA 0x6AAC #CJK UNIFIED IDEOGRAPH
+0xC3CB 0x76DF #CJK UNIFIED IDEOGRAPH
+0xC3CC 0x9530 #CJK UNIFIED IDEOGRAPH
+0xC3CD 0x731B #CJK UNIFIED IDEOGRAPH
+0xC3CE 0x68A6 #CJK UNIFIED IDEOGRAPH
+0xC3CF 0x5B5F #CJK UNIFIED IDEOGRAPH
+0xC3D0 0x772F #CJK UNIFIED IDEOGRAPH
+0xC3D1 0x919A #CJK UNIFIED IDEOGRAPH
+0xC3D2 0x9761 #CJK UNIFIED IDEOGRAPH
+0xC3D3 0x7CDC #CJK UNIFIED IDEOGRAPH
+0xC3D4 0x8FF7 #CJK UNIFIED IDEOGRAPH
+0xC3D5 0x8C1C #CJK UNIFIED IDEOGRAPH
+0xC3D6 0x5F25 #CJK UNIFIED IDEOGRAPH
+0xC3D7 0x7C73 #CJK UNIFIED IDEOGRAPH
+0xC3D8 0x79D8 #CJK UNIFIED IDEOGRAPH
+0xC3D9 0x89C5 #CJK UNIFIED IDEOGRAPH
+0xC3DA 0x6CCC #CJK UNIFIED IDEOGRAPH
+0xC3DB 0x871C #CJK UNIFIED IDEOGRAPH
+0xC3DC 0x5BC6 #CJK UNIFIED IDEOGRAPH
+0xC3DD 0x5E42 #CJK UNIFIED IDEOGRAPH
+0xC3DE 0x68C9 #CJK UNIFIED IDEOGRAPH
+0xC3DF 0x7720 #CJK UNIFIED IDEOGRAPH
+0xC3E0 0x7EF5 #CJK UNIFIED IDEOGRAPH
+0xC3E1 0x5195 #CJK UNIFIED IDEOGRAPH
+0xC3E2 0x514D #CJK UNIFIED IDEOGRAPH
+0xC3E3 0x52C9 #CJK UNIFIED IDEOGRAPH
+0xC3E4 0x5A29 #CJK UNIFIED IDEOGRAPH
+0xC3E5 0x7F05 #CJK UNIFIED IDEOGRAPH
+0xC3E6 0x9762 #CJK UNIFIED IDEOGRAPH
+0xC3E7 0x82D7 #CJK UNIFIED IDEOGRAPH
+0xC3E8 0x63CF #CJK UNIFIED IDEOGRAPH
+0xC3E9 0x7784 #CJK UNIFIED IDEOGRAPH
+0xC3EA 0x85D0 #CJK UNIFIED IDEOGRAPH
+0xC3EB 0x79D2 #CJK UNIFIED IDEOGRAPH
+0xC3EC 0x6E3A #CJK UNIFIED IDEOGRAPH
+0xC3ED 0x5E99 #CJK UNIFIED IDEOGRAPH
+0xC3EE 0x5999 #CJK UNIFIED IDEOGRAPH
+0xC3EF 0x8511 #CJK UNIFIED IDEOGRAPH
+0xC3F0 0x706D #CJK UNIFIED IDEOGRAPH
+0xC3F1 0x6C11 #CJK UNIFIED IDEOGRAPH
+0xC3F2 0x62BF #CJK UNIFIED IDEOGRAPH
+0xC3F3 0x76BF #CJK UNIFIED IDEOGRAPH
+0xC3F4 0x654F #CJK UNIFIED IDEOGRAPH
+0xC3F5 0x60AF #CJK UNIFIED IDEOGRAPH
+0xC3F6 0x95FD #CJK UNIFIED IDEOGRAPH
+0xC3F7 0x660E #CJK UNIFIED IDEOGRAPH
+0xC3F8 0x879F #CJK UNIFIED IDEOGRAPH
+0xC3F9 0x9E23 #CJK UNIFIED IDEOGRAPH
+0xC3FA 0x94ED #CJK UNIFIED IDEOGRAPH
+0xC3FB 0x540D #CJK UNIFIED IDEOGRAPH
+0xC3FC 0x547D #CJK UNIFIED IDEOGRAPH
+0xC3FD 0x8C2C #CJK UNIFIED IDEOGRAPH
+0xC3FE 0x6478 #CJK UNIFIED IDEOGRAPH
+0xC440 0x8140 #CJK UNIFIED IDEOGRAPH
+0xC441 0x8141 #CJK UNIFIED IDEOGRAPH
+0xC442 0x8142 #CJK UNIFIED IDEOGRAPH
+0xC443 0x8143 #CJK UNIFIED IDEOGRAPH
+0xC444 0x8144 #CJK UNIFIED IDEOGRAPH
+0xC445 0x8145 #CJK UNIFIED IDEOGRAPH
+0xC446 0x8147 #CJK UNIFIED IDEOGRAPH
+0xC447 0x8149 #CJK UNIFIED IDEOGRAPH
+0xC448 0x814D #CJK UNIFIED IDEOGRAPH
+0xC449 0x814E #CJK UNIFIED IDEOGRAPH
+0xC44A 0x814F #CJK UNIFIED IDEOGRAPH
+0xC44B 0x8152 #CJK UNIFIED IDEOGRAPH
+0xC44C 0x8156 #CJK UNIFIED IDEOGRAPH
+0xC44D 0x8157 #CJK UNIFIED IDEOGRAPH
+0xC44E 0x8158 #CJK UNIFIED IDEOGRAPH
+0xC44F 0x815B #CJK UNIFIED IDEOGRAPH
+0xC450 0x815C #CJK UNIFIED IDEOGRAPH
+0xC451 0x815D #CJK UNIFIED IDEOGRAPH
+0xC452 0x815E #CJK UNIFIED IDEOGRAPH
+0xC453 0x815F #CJK UNIFIED IDEOGRAPH
+0xC454 0x8161 #CJK UNIFIED IDEOGRAPH
+0xC455 0x8162 #CJK UNIFIED IDEOGRAPH
+0xC456 0x8163 #CJK UNIFIED IDEOGRAPH
+0xC457 0x8164 #CJK UNIFIED IDEOGRAPH
+0xC458 0x8166 #CJK UNIFIED IDEOGRAPH
+0xC459 0x8168 #CJK UNIFIED IDEOGRAPH
+0xC45A 0x816A #CJK UNIFIED IDEOGRAPH
+0xC45B 0x816B #CJK UNIFIED IDEOGRAPH
+0xC45C 0x816C #CJK UNIFIED IDEOGRAPH
+0xC45D 0x816F #CJK UNIFIED IDEOGRAPH
+0xC45E 0x8172 #CJK UNIFIED IDEOGRAPH
+0xC45F 0x8173 #CJK UNIFIED IDEOGRAPH
+0xC460 0x8175 #CJK UNIFIED IDEOGRAPH
+0xC461 0x8176 #CJK UNIFIED IDEOGRAPH
+0xC462 0x8177 #CJK UNIFIED IDEOGRAPH
+0xC463 0x8178 #CJK UNIFIED IDEOGRAPH
+0xC464 0x8181 #CJK UNIFIED IDEOGRAPH
+0xC465 0x8183 #CJK UNIFIED IDEOGRAPH
+0xC466 0x8184 #CJK UNIFIED IDEOGRAPH
+0xC467 0x8185 #CJK UNIFIED IDEOGRAPH
+0xC468 0x8186 #CJK UNIFIED IDEOGRAPH
+0xC469 0x8187 #CJK UNIFIED IDEOGRAPH
+0xC46A 0x8189 #CJK UNIFIED IDEOGRAPH
+0xC46B 0x818B #CJK UNIFIED IDEOGRAPH
+0xC46C 0x818C #CJK UNIFIED IDEOGRAPH
+0xC46D 0x818D #CJK UNIFIED IDEOGRAPH
+0xC46E 0x818E #CJK UNIFIED IDEOGRAPH
+0xC46F 0x8190 #CJK UNIFIED IDEOGRAPH
+0xC470 0x8192 #CJK UNIFIED IDEOGRAPH
+0xC471 0x8193 #CJK UNIFIED IDEOGRAPH
+0xC472 0x8194 #CJK UNIFIED IDEOGRAPH
+0xC473 0x8195 #CJK UNIFIED IDEOGRAPH
+0xC474 0x8196 #CJK UNIFIED IDEOGRAPH
+0xC475 0x8197 #CJK UNIFIED IDEOGRAPH
+0xC476 0x8199 #CJK UNIFIED IDEOGRAPH
+0xC477 0x819A #CJK UNIFIED IDEOGRAPH
+0xC478 0x819E #CJK UNIFIED IDEOGRAPH
+0xC479 0x819F #CJK UNIFIED IDEOGRAPH
+0xC47A 0x81A0 #CJK UNIFIED IDEOGRAPH
+0xC47B 0x81A1 #CJK UNIFIED IDEOGRAPH
+0xC47C 0x81A2 #CJK UNIFIED IDEOGRAPH
+0xC47D 0x81A4 #CJK UNIFIED IDEOGRAPH
+0xC47E 0x81A5 #CJK UNIFIED IDEOGRAPH
+0xC480 0x81A7 #CJK UNIFIED IDEOGRAPH
+0xC481 0x81A9 #CJK UNIFIED IDEOGRAPH
+0xC482 0x81AB #CJK UNIFIED IDEOGRAPH
+0xC483 0x81AC #CJK UNIFIED IDEOGRAPH
+0xC484 0x81AD #CJK UNIFIED IDEOGRAPH
+0xC485 0x81AE #CJK UNIFIED IDEOGRAPH
+0xC486 0x81AF #CJK UNIFIED IDEOGRAPH
+0xC487 0x81B0 #CJK UNIFIED IDEOGRAPH
+0xC488 0x81B1 #CJK UNIFIED IDEOGRAPH
+0xC489 0x81B2 #CJK UNIFIED IDEOGRAPH
+0xC48A 0x81B4 #CJK UNIFIED IDEOGRAPH
+0xC48B 0x81B5 #CJK UNIFIED IDEOGRAPH
+0xC48C 0x81B6 #CJK UNIFIED IDEOGRAPH
+0xC48D 0x81B7 #CJK UNIFIED IDEOGRAPH
+0xC48E 0x81B8 #CJK UNIFIED IDEOGRAPH
+0xC48F 0x81B9 #CJK UNIFIED IDEOGRAPH
+0xC490 0x81BC #CJK UNIFIED IDEOGRAPH
+0xC491 0x81BD #CJK UNIFIED IDEOGRAPH
+0xC492 0x81BE #CJK UNIFIED IDEOGRAPH
+0xC493 0x81BF #CJK UNIFIED IDEOGRAPH
+0xC494 0x81C4 #CJK UNIFIED IDEOGRAPH
+0xC495 0x81C5 #CJK UNIFIED IDEOGRAPH
+0xC496 0x81C7 #CJK UNIFIED IDEOGRAPH
+0xC497 0x81C8 #CJK UNIFIED IDEOGRAPH
+0xC498 0x81C9 #CJK UNIFIED IDEOGRAPH
+0xC499 0x81CB #CJK UNIFIED IDEOGRAPH
+0xC49A 0x81CD #CJK UNIFIED IDEOGRAPH
+0xC49B 0x81CE #CJK UNIFIED IDEOGRAPH
+0xC49C 0x81CF #CJK UNIFIED IDEOGRAPH
+0xC49D 0x81D0 #CJK UNIFIED IDEOGRAPH
+0xC49E 0x81D1 #CJK UNIFIED IDEOGRAPH
+0xC49F 0x81D2 #CJK UNIFIED IDEOGRAPH
+0xC4A0 0x81D3 #CJK UNIFIED IDEOGRAPH
+0xC4A1 0x6479 #CJK UNIFIED IDEOGRAPH
+0xC4A2 0x8611 #CJK UNIFIED IDEOGRAPH
+0xC4A3 0x6A21 #CJK UNIFIED IDEOGRAPH
+0xC4A4 0x819C #CJK UNIFIED IDEOGRAPH
+0xC4A5 0x78E8 #CJK UNIFIED IDEOGRAPH
+0xC4A6 0x6469 #CJK UNIFIED IDEOGRAPH
+0xC4A7 0x9B54 #CJK UNIFIED IDEOGRAPH
+0xC4A8 0x62B9 #CJK UNIFIED IDEOGRAPH
+0xC4A9 0x672B #CJK UNIFIED IDEOGRAPH
+0xC4AA 0x83AB #CJK UNIFIED IDEOGRAPH
+0xC4AB 0x58A8 #CJK UNIFIED IDEOGRAPH
+0xC4AC 0x9ED8 #CJK UNIFIED IDEOGRAPH
+0xC4AD 0x6CAB #CJK UNIFIED IDEOGRAPH
+0xC4AE 0x6F20 #CJK UNIFIED IDEOGRAPH
+0xC4AF 0x5BDE #CJK UNIFIED IDEOGRAPH
+0xC4B0 0x964C #CJK UNIFIED IDEOGRAPH
+0xC4B1 0x8C0B #CJK UNIFIED IDEOGRAPH
+0xC4B2 0x725F #CJK UNIFIED IDEOGRAPH
+0xC4B3 0x67D0 #CJK UNIFIED IDEOGRAPH
+0xC4B4 0x62C7 #CJK UNIFIED IDEOGRAPH
+0xC4B5 0x7261 #CJK UNIFIED IDEOGRAPH
+0xC4B6 0x4EA9 #CJK UNIFIED IDEOGRAPH
+0xC4B7 0x59C6 #CJK UNIFIED IDEOGRAPH
+0xC4B8 0x6BCD #CJK UNIFIED IDEOGRAPH
+0xC4B9 0x5893 #CJK UNIFIED IDEOGRAPH
+0xC4BA 0x66AE #CJK UNIFIED IDEOGRAPH
+0xC4BB 0x5E55 #CJK UNIFIED IDEOGRAPH
+0xC4BC 0x52DF #CJK UNIFIED IDEOGRAPH
+0xC4BD 0x6155 #CJK UNIFIED IDEOGRAPH
+0xC4BE 0x6728 #CJK UNIFIED IDEOGRAPH
+0xC4BF 0x76EE #CJK UNIFIED IDEOGRAPH
+0xC4C0 0x7766 #CJK UNIFIED IDEOGRAPH
+0xC4C1 0x7267 #CJK UNIFIED IDEOGRAPH
+0xC4C2 0x7A46 #CJK UNIFIED IDEOGRAPH
+0xC4C3 0x62FF #CJK UNIFIED IDEOGRAPH
+0xC4C4 0x54EA #CJK UNIFIED IDEOGRAPH
+0xC4C5 0x5450 #CJK UNIFIED IDEOGRAPH
+0xC4C6 0x94A0 #CJK UNIFIED IDEOGRAPH
+0xC4C7 0x90A3 #CJK UNIFIED IDEOGRAPH
+0xC4C8 0x5A1C #CJK UNIFIED IDEOGRAPH
+0xC4C9 0x7EB3 #CJK UNIFIED IDEOGRAPH
+0xC4CA 0x6C16 #CJK UNIFIED IDEOGRAPH
+0xC4CB 0x4E43 #CJK UNIFIED IDEOGRAPH
+0xC4CC 0x5976 #CJK UNIFIED IDEOGRAPH
+0xC4CD 0x8010 #CJK UNIFIED IDEOGRAPH
+0xC4CE 0x5948 #CJK UNIFIED IDEOGRAPH
+0xC4CF 0x5357 #CJK UNIFIED IDEOGRAPH
+0xC4D0 0x7537 #CJK UNIFIED IDEOGRAPH
+0xC4D1 0x96BE #CJK UNIFIED IDEOGRAPH
+0xC4D2 0x56CA #CJK UNIFIED IDEOGRAPH
+0xC4D3 0x6320 #CJK UNIFIED IDEOGRAPH
+0xC4D4 0x8111 #CJK UNIFIED IDEOGRAPH
+0xC4D5 0x607C #CJK UNIFIED IDEOGRAPH
+0xC4D6 0x95F9 #CJK UNIFIED IDEOGRAPH
+0xC4D7 0x6DD6 #CJK UNIFIED IDEOGRAPH
+0xC4D8 0x5462 #CJK UNIFIED IDEOGRAPH
+0xC4D9 0x9981 #CJK UNIFIED IDEOGRAPH
+0xC4DA 0x5185 #CJK UNIFIED IDEOGRAPH
+0xC4DB 0x5AE9 #CJK UNIFIED IDEOGRAPH
+0xC4DC 0x80FD #CJK UNIFIED IDEOGRAPH
+0xC4DD 0x59AE #CJK UNIFIED IDEOGRAPH
+0xC4DE 0x9713 #CJK UNIFIED IDEOGRAPH
+0xC4DF 0x502A #CJK UNIFIED IDEOGRAPH
+0xC4E0 0x6CE5 #CJK UNIFIED IDEOGRAPH
+0xC4E1 0x5C3C #CJK UNIFIED IDEOGRAPH
+0xC4E2 0x62DF #CJK UNIFIED IDEOGRAPH
+0xC4E3 0x4F60 #CJK UNIFIED IDEOGRAPH
+0xC4E4 0x533F #CJK UNIFIED IDEOGRAPH
+0xC4E5 0x817B #CJK UNIFIED IDEOGRAPH
+0xC4E6 0x9006 #CJK UNIFIED IDEOGRAPH
+0xC4E7 0x6EBA #CJK UNIFIED IDEOGRAPH
+0xC4E8 0x852B #CJK UNIFIED IDEOGRAPH
+0xC4E9 0x62C8 #CJK UNIFIED IDEOGRAPH
+0xC4EA 0x5E74 #CJK UNIFIED IDEOGRAPH
+0xC4EB 0x78BE #CJK UNIFIED IDEOGRAPH
+0xC4EC 0x64B5 #CJK UNIFIED IDEOGRAPH
+0xC4ED 0x637B #CJK UNIFIED IDEOGRAPH
+0xC4EE 0x5FF5 #CJK UNIFIED IDEOGRAPH
+0xC4EF 0x5A18 #CJK UNIFIED IDEOGRAPH
+0xC4F0 0x917F #CJK UNIFIED IDEOGRAPH
+0xC4F1 0x9E1F #CJK UNIFIED IDEOGRAPH
+0xC4F2 0x5C3F #CJK UNIFIED IDEOGRAPH
+0xC4F3 0x634F #CJK UNIFIED IDEOGRAPH
+0xC4F4 0x8042 #CJK UNIFIED IDEOGRAPH
+0xC4F5 0x5B7D #CJK UNIFIED IDEOGRAPH
+0xC4F6 0x556E #CJK UNIFIED IDEOGRAPH
+0xC4F7 0x954A #CJK UNIFIED IDEOGRAPH
+0xC4F8 0x954D #CJK UNIFIED IDEOGRAPH
+0xC4F9 0x6D85 #CJK UNIFIED IDEOGRAPH
+0xC4FA 0x60A8 #CJK UNIFIED IDEOGRAPH
+0xC4FB 0x67E0 #CJK UNIFIED IDEOGRAPH
+0xC4FC 0x72DE #CJK UNIFIED IDEOGRAPH
+0xC4FD 0x51DD #CJK UNIFIED IDEOGRAPH
+0xC4FE 0x5B81 #CJK UNIFIED IDEOGRAPH
+0xC540 0x81D4 #CJK UNIFIED IDEOGRAPH
+0xC541 0x81D5 #CJK UNIFIED IDEOGRAPH
+0xC542 0x81D6 #CJK UNIFIED IDEOGRAPH
+0xC543 0x81D7 #CJK UNIFIED IDEOGRAPH
+0xC544 0x81D8 #CJK UNIFIED IDEOGRAPH
+0xC545 0x81D9 #CJK UNIFIED IDEOGRAPH
+0xC546 0x81DA #CJK UNIFIED IDEOGRAPH
+0xC547 0x81DB #CJK UNIFIED IDEOGRAPH
+0xC548 0x81DC #CJK UNIFIED IDEOGRAPH
+0xC549 0x81DD #CJK UNIFIED IDEOGRAPH
+0xC54A 0x81DE #CJK UNIFIED IDEOGRAPH
+0xC54B 0x81DF #CJK UNIFIED IDEOGRAPH
+0xC54C 0x81E0 #CJK UNIFIED IDEOGRAPH
+0xC54D 0x81E1 #CJK UNIFIED IDEOGRAPH
+0xC54E 0x81E2 #CJK UNIFIED IDEOGRAPH
+0xC54F 0x81E4 #CJK UNIFIED IDEOGRAPH
+0xC550 0x81E5 #CJK UNIFIED IDEOGRAPH
+0xC551 0x81E6 #CJK UNIFIED IDEOGRAPH
+0xC552 0x81E8 #CJK UNIFIED IDEOGRAPH
+0xC553 0x81E9 #CJK UNIFIED IDEOGRAPH
+0xC554 0x81EB #CJK UNIFIED IDEOGRAPH
+0xC555 0x81EE #CJK UNIFIED IDEOGRAPH
+0xC556 0x81EF #CJK UNIFIED IDEOGRAPH
+0xC557 0x81F0 #CJK UNIFIED IDEOGRAPH
+0xC558 0x81F1 #CJK UNIFIED IDEOGRAPH
+0xC559 0x81F2 #CJK UNIFIED IDEOGRAPH
+0xC55A 0x81F5 #CJK UNIFIED IDEOGRAPH
+0xC55B 0x81F6 #CJK UNIFIED IDEOGRAPH
+0xC55C 0x81F7 #CJK UNIFIED IDEOGRAPH
+0xC55D 0x81F8 #CJK UNIFIED IDEOGRAPH
+0xC55E 0x81F9 #CJK UNIFIED IDEOGRAPH
+0xC55F 0x81FA #CJK UNIFIED IDEOGRAPH
+0xC560 0x81FD #CJK UNIFIED IDEOGRAPH
+0xC561 0x81FF #CJK UNIFIED IDEOGRAPH
+0xC562 0x8203 #CJK UNIFIED IDEOGRAPH
+0xC563 0x8207 #CJK UNIFIED IDEOGRAPH
+0xC564 0x8208 #CJK UNIFIED IDEOGRAPH
+0xC565 0x8209 #CJK UNIFIED IDEOGRAPH
+0xC566 0x820A #CJK UNIFIED IDEOGRAPH
+0xC567 0x820B #CJK UNIFIED IDEOGRAPH
+0xC568 0x820E #CJK UNIFIED IDEOGRAPH
+0xC569 0x820F #CJK UNIFIED IDEOGRAPH
+0xC56A 0x8211 #CJK UNIFIED IDEOGRAPH
+0xC56B 0x8213 #CJK UNIFIED IDEOGRAPH
+0xC56C 0x8215 #CJK UNIFIED IDEOGRAPH
+0xC56D 0x8216 #CJK UNIFIED IDEOGRAPH
+0xC56E 0x8217 #CJK UNIFIED IDEOGRAPH
+0xC56F 0x8218 #CJK UNIFIED IDEOGRAPH
+0xC570 0x8219 #CJK UNIFIED IDEOGRAPH
+0xC571 0x821A #CJK UNIFIED IDEOGRAPH
+0xC572 0x821D #CJK UNIFIED IDEOGRAPH
+0xC573 0x8220 #CJK UNIFIED IDEOGRAPH
+0xC574 0x8224 #CJK UNIFIED IDEOGRAPH
+0xC575 0x8225 #CJK UNIFIED IDEOGRAPH
+0xC576 0x8226 #CJK UNIFIED IDEOGRAPH
+0xC577 0x8227 #CJK UNIFIED IDEOGRAPH
+0xC578 0x8229 #CJK UNIFIED IDEOGRAPH
+0xC579 0x822E #CJK UNIFIED IDEOGRAPH
+0xC57A 0x8232 #CJK UNIFIED IDEOGRAPH
+0xC57B 0x823A #CJK UNIFIED IDEOGRAPH
+0xC57C 0x823C #CJK UNIFIED IDEOGRAPH
+0xC57D 0x823D #CJK UNIFIED IDEOGRAPH
+0xC57E 0x823F #CJK UNIFIED IDEOGRAPH
+0xC580 0x8240 #CJK UNIFIED IDEOGRAPH
+0xC581 0x8241 #CJK UNIFIED IDEOGRAPH
+0xC582 0x8242 #CJK UNIFIED IDEOGRAPH
+0xC583 0x8243 #CJK UNIFIED IDEOGRAPH
+0xC584 0x8245 #CJK UNIFIED IDEOGRAPH
+0xC585 0x8246 #CJK UNIFIED IDEOGRAPH
+0xC586 0x8248 #CJK UNIFIED IDEOGRAPH
+0xC587 0x824A #CJK UNIFIED IDEOGRAPH
+0xC588 0x824C #CJK UNIFIED IDEOGRAPH
+0xC589 0x824D #CJK UNIFIED IDEOGRAPH
+0xC58A 0x824E #CJK UNIFIED IDEOGRAPH
+0xC58B 0x8250 #CJK UNIFIED IDEOGRAPH
+0xC58C 0x8251 #CJK UNIFIED IDEOGRAPH
+0xC58D 0x8252 #CJK UNIFIED IDEOGRAPH
+0xC58E 0x8253 #CJK UNIFIED IDEOGRAPH
+0xC58F 0x8254 #CJK UNIFIED IDEOGRAPH
+0xC590 0x8255 #CJK UNIFIED IDEOGRAPH
+0xC591 0x8256 #CJK UNIFIED IDEOGRAPH
+0xC592 0x8257 #CJK UNIFIED IDEOGRAPH
+0xC593 0x8259 #CJK UNIFIED IDEOGRAPH
+0xC594 0x825B #CJK UNIFIED IDEOGRAPH
+0xC595 0x825C #CJK UNIFIED IDEOGRAPH
+0xC596 0x825D #CJK UNIFIED IDEOGRAPH
+0xC597 0x825E #CJK UNIFIED IDEOGRAPH
+0xC598 0x8260 #CJK UNIFIED IDEOGRAPH
+0xC599 0x8261 #CJK UNIFIED IDEOGRAPH
+0xC59A 0x8262 #CJK UNIFIED IDEOGRAPH
+0xC59B 0x8263 #CJK UNIFIED IDEOGRAPH
+0xC59C 0x8264 #CJK UNIFIED IDEOGRAPH
+0xC59D 0x8265 #CJK UNIFIED IDEOGRAPH
+0xC59E 0x8266 #CJK UNIFIED IDEOGRAPH
+0xC59F 0x8267 #CJK UNIFIED IDEOGRAPH
+0xC5A0 0x8269 #CJK UNIFIED IDEOGRAPH
+0xC5A1 0x62E7 #CJK UNIFIED IDEOGRAPH
+0xC5A2 0x6CDE #CJK UNIFIED IDEOGRAPH
+0xC5A3 0x725B #CJK UNIFIED IDEOGRAPH
+0xC5A4 0x626D #CJK UNIFIED IDEOGRAPH
+0xC5A5 0x94AE #CJK UNIFIED IDEOGRAPH
+0xC5A6 0x7EBD #CJK UNIFIED IDEOGRAPH
+0xC5A7 0x8113 #CJK UNIFIED IDEOGRAPH
+0xC5A8 0x6D53 #CJK UNIFIED IDEOGRAPH
+0xC5A9 0x519C #CJK UNIFIED IDEOGRAPH
+0xC5AA 0x5F04 #CJK UNIFIED IDEOGRAPH
+0xC5AB 0x5974 #CJK UNIFIED IDEOGRAPH
+0xC5AC 0x52AA #CJK UNIFIED IDEOGRAPH
+0xC5AD 0x6012 #CJK UNIFIED IDEOGRAPH
+0xC5AE 0x5973 #CJK UNIFIED IDEOGRAPH
+0xC5AF 0x6696 #CJK UNIFIED IDEOGRAPH
+0xC5B0 0x8650 #CJK UNIFIED IDEOGRAPH
+0xC5B1 0x759F #CJK UNIFIED IDEOGRAPH
+0xC5B2 0x632A #CJK UNIFIED IDEOGRAPH
+0xC5B3 0x61E6 #CJK UNIFIED IDEOGRAPH
+0xC5B4 0x7CEF #CJK UNIFIED IDEOGRAPH
+0xC5B5 0x8BFA #CJK UNIFIED IDEOGRAPH
+0xC5B6 0x54E6 #CJK UNIFIED IDEOGRAPH
+0xC5B7 0x6B27 #CJK UNIFIED IDEOGRAPH
+0xC5B8 0x9E25 #CJK UNIFIED IDEOGRAPH
+0xC5B9 0x6BB4 #CJK UNIFIED IDEOGRAPH
+0xC5BA 0x85D5 #CJK UNIFIED IDEOGRAPH
+0xC5BB 0x5455 #CJK UNIFIED IDEOGRAPH
+0xC5BC 0x5076 #CJK UNIFIED IDEOGRAPH
+0xC5BD 0x6CA4 #CJK UNIFIED IDEOGRAPH
+0xC5BE 0x556A #CJK UNIFIED IDEOGRAPH
+0xC5BF 0x8DB4 #CJK UNIFIED IDEOGRAPH
+0xC5C0 0x722C #CJK UNIFIED IDEOGRAPH
+0xC5C1 0x5E15 #CJK UNIFIED IDEOGRAPH
+0xC5C2 0x6015 #CJK UNIFIED IDEOGRAPH
+0xC5C3 0x7436 #CJK UNIFIED IDEOGRAPH
+0xC5C4 0x62CD #CJK UNIFIED IDEOGRAPH
+0xC5C5 0x6392 #CJK UNIFIED IDEOGRAPH
+0xC5C6 0x724C #CJK UNIFIED IDEOGRAPH
+0xC5C7 0x5F98 #CJK UNIFIED IDEOGRAPH
+0xC5C8 0x6E43 #CJK UNIFIED IDEOGRAPH
+0xC5C9 0x6D3E #CJK UNIFIED IDEOGRAPH
+0xC5CA 0x6500 #CJK UNIFIED IDEOGRAPH
+0xC5CB 0x6F58 #CJK UNIFIED IDEOGRAPH
+0xC5CC 0x76D8 #CJK UNIFIED IDEOGRAPH
+0xC5CD 0x78D0 #CJK UNIFIED IDEOGRAPH
+0xC5CE 0x76FC #CJK UNIFIED IDEOGRAPH
+0xC5CF 0x7554 #CJK UNIFIED IDEOGRAPH
+0xC5D0 0x5224 #CJK UNIFIED IDEOGRAPH
+0xC5D1 0x53DB #CJK UNIFIED IDEOGRAPH
+0xC5D2 0x4E53 #CJK UNIFIED IDEOGRAPH
+0xC5D3 0x5E9E #CJK UNIFIED IDEOGRAPH
+0xC5D4 0x65C1 #CJK UNIFIED IDEOGRAPH
+0xC5D5 0x802A #CJK UNIFIED IDEOGRAPH
+0xC5D6 0x80D6 #CJK UNIFIED IDEOGRAPH
+0xC5D7 0x629B #CJK UNIFIED IDEOGRAPH
+0xC5D8 0x5486 #CJK UNIFIED IDEOGRAPH
+0xC5D9 0x5228 #CJK UNIFIED IDEOGRAPH
+0xC5DA 0x70AE #CJK UNIFIED IDEOGRAPH
+0xC5DB 0x888D #CJK UNIFIED IDEOGRAPH
+0xC5DC 0x8DD1 #CJK UNIFIED IDEOGRAPH
+0xC5DD 0x6CE1 #CJK UNIFIED IDEOGRAPH
+0xC5DE 0x5478 #CJK UNIFIED IDEOGRAPH
+0xC5DF 0x80DA #CJK UNIFIED IDEOGRAPH
+0xC5E0 0x57F9 #CJK UNIFIED IDEOGRAPH
+0xC5E1 0x88F4 #CJK UNIFIED IDEOGRAPH
+0xC5E2 0x8D54 #CJK UNIFIED IDEOGRAPH
+0xC5E3 0x966A #CJK UNIFIED IDEOGRAPH
+0xC5E4 0x914D #CJK UNIFIED IDEOGRAPH
+0xC5E5 0x4F69 #CJK UNIFIED IDEOGRAPH
+0xC5E6 0x6C9B #CJK UNIFIED IDEOGRAPH
+0xC5E7 0x55B7 #CJK UNIFIED IDEOGRAPH
+0xC5E8 0x76C6 #CJK UNIFIED IDEOGRAPH
+0xC5E9 0x7830 #CJK UNIFIED IDEOGRAPH
+0xC5EA 0x62A8 #CJK UNIFIED IDEOGRAPH
+0xC5EB 0x70F9 #CJK UNIFIED IDEOGRAPH
+0xC5EC 0x6F8E #CJK UNIFIED IDEOGRAPH
+0xC5ED 0x5F6D #CJK UNIFIED IDEOGRAPH
+0xC5EE 0x84EC #CJK UNIFIED IDEOGRAPH
+0xC5EF 0x68DA #CJK UNIFIED IDEOGRAPH
+0xC5F0 0x787C #CJK UNIFIED IDEOGRAPH
+0xC5F1 0x7BF7 #CJK UNIFIED IDEOGRAPH
+0xC5F2 0x81A8 #CJK UNIFIED IDEOGRAPH
+0xC5F3 0x670B #CJK UNIFIED IDEOGRAPH
+0xC5F4 0x9E4F #CJK UNIFIED IDEOGRAPH
+0xC5F5 0x6367 #CJK UNIFIED IDEOGRAPH
+0xC5F6 0x78B0 #CJK UNIFIED IDEOGRAPH
+0xC5F7 0x576F #CJK UNIFIED IDEOGRAPH
+0xC5F8 0x7812 #CJK UNIFIED IDEOGRAPH
+0xC5F9 0x9739 #CJK UNIFIED IDEOGRAPH
+0xC5FA 0x6279 #CJK UNIFIED IDEOGRAPH
+0xC5FB 0x62AB #CJK UNIFIED IDEOGRAPH
+0xC5FC 0x5288 #CJK UNIFIED IDEOGRAPH
+0xC5FD 0x7435 #CJK UNIFIED IDEOGRAPH
+0xC5FE 0x6BD7 #CJK UNIFIED IDEOGRAPH
+0xC640 0x826A #CJK UNIFIED IDEOGRAPH
+0xC641 0x826B #CJK UNIFIED IDEOGRAPH
+0xC642 0x826C #CJK UNIFIED IDEOGRAPH
+0xC643 0x826D #CJK UNIFIED IDEOGRAPH
+0xC644 0x8271 #CJK UNIFIED IDEOGRAPH
+0xC645 0x8275 #CJK UNIFIED IDEOGRAPH
+0xC646 0x8276 #CJK UNIFIED IDEOGRAPH
+0xC647 0x8277 #CJK UNIFIED IDEOGRAPH
+0xC648 0x8278 #CJK UNIFIED IDEOGRAPH
+0xC649 0x827B #CJK UNIFIED IDEOGRAPH
+0xC64A 0x827C #CJK UNIFIED IDEOGRAPH
+0xC64B 0x8280 #CJK UNIFIED IDEOGRAPH
+0xC64C 0x8281 #CJK UNIFIED IDEOGRAPH
+0xC64D 0x8283 #CJK UNIFIED IDEOGRAPH
+0xC64E 0x8285 #CJK UNIFIED IDEOGRAPH
+0xC64F 0x8286 #CJK UNIFIED IDEOGRAPH
+0xC650 0x8287 #CJK UNIFIED IDEOGRAPH
+0xC651 0x8289 #CJK UNIFIED IDEOGRAPH
+0xC652 0x828C #CJK UNIFIED IDEOGRAPH
+0xC653 0x8290 #CJK UNIFIED IDEOGRAPH
+0xC654 0x8293 #CJK UNIFIED IDEOGRAPH
+0xC655 0x8294 #CJK UNIFIED IDEOGRAPH
+0xC656 0x8295 #CJK UNIFIED IDEOGRAPH
+0xC657 0x8296 #CJK UNIFIED IDEOGRAPH
+0xC658 0x829A #CJK UNIFIED IDEOGRAPH
+0xC659 0x829B #CJK UNIFIED IDEOGRAPH
+0xC65A 0x829E #CJK UNIFIED IDEOGRAPH
+0xC65B 0x82A0 #CJK UNIFIED IDEOGRAPH
+0xC65C 0x82A2 #CJK UNIFIED IDEOGRAPH
+0xC65D 0x82A3 #CJK UNIFIED IDEOGRAPH
+0xC65E 0x82A7 #CJK UNIFIED IDEOGRAPH
+0xC65F 0x82B2 #CJK UNIFIED IDEOGRAPH
+0xC660 0x82B5 #CJK UNIFIED IDEOGRAPH
+0xC661 0x82B6 #CJK UNIFIED IDEOGRAPH
+0xC662 0x82BA #CJK UNIFIED IDEOGRAPH
+0xC663 0x82BB #CJK UNIFIED IDEOGRAPH
+0xC664 0x82BC #CJK UNIFIED IDEOGRAPH
+0xC665 0x82BF #CJK UNIFIED IDEOGRAPH
+0xC666 0x82C0 #CJK UNIFIED IDEOGRAPH
+0xC667 0x82C2 #CJK UNIFIED IDEOGRAPH
+0xC668 0x82C3 #CJK UNIFIED IDEOGRAPH
+0xC669 0x82C5 #CJK UNIFIED IDEOGRAPH
+0xC66A 0x82C6 #CJK UNIFIED IDEOGRAPH
+0xC66B 0x82C9 #CJK UNIFIED IDEOGRAPH
+0xC66C 0x82D0 #CJK UNIFIED IDEOGRAPH
+0xC66D 0x82D6 #CJK UNIFIED IDEOGRAPH
+0xC66E 0x82D9 #CJK UNIFIED IDEOGRAPH
+0xC66F 0x82DA #CJK UNIFIED IDEOGRAPH
+0xC670 0x82DD #CJK UNIFIED IDEOGRAPH
+0xC671 0x82E2 #CJK UNIFIED IDEOGRAPH
+0xC672 0x82E7 #CJK UNIFIED IDEOGRAPH
+0xC673 0x82E8 #CJK UNIFIED IDEOGRAPH
+0xC674 0x82E9 #CJK UNIFIED IDEOGRAPH
+0xC675 0x82EA #CJK UNIFIED IDEOGRAPH
+0xC676 0x82EC #CJK UNIFIED IDEOGRAPH
+0xC677 0x82ED #CJK UNIFIED IDEOGRAPH
+0xC678 0x82EE #CJK UNIFIED IDEOGRAPH
+0xC679 0x82F0 #CJK UNIFIED IDEOGRAPH
+0xC67A 0x82F2 #CJK UNIFIED IDEOGRAPH
+0xC67B 0x82F3 #CJK UNIFIED IDEOGRAPH
+0xC67C 0x82F5 #CJK UNIFIED IDEOGRAPH
+0xC67D 0x82F6 #CJK UNIFIED IDEOGRAPH
+0xC67E 0x82F8 #CJK UNIFIED IDEOGRAPH
+0xC680 0x82FA #CJK UNIFIED IDEOGRAPH
+0xC681 0x82FC #CJK UNIFIED IDEOGRAPH
+0xC682 0x82FD #CJK UNIFIED IDEOGRAPH
+0xC683 0x82FE #CJK UNIFIED IDEOGRAPH
+0xC684 0x82FF #CJK UNIFIED IDEOGRAPH
+0xC685 0x8300 #CJK UNIFIED IDEOGRAPH
+0xC686 0x830A #CJK UNIFIED IDEOGRAPH
+0xC687 0x830B #CJK UNIFIED IDEOGRAPH
+0xC688 0x830D #CJK UNIFIED IDEOGRAPH
+0xC689 0x8310 #CJK UNIFIED IDEOGRAPH
+0xC68A 0x8312 #CJK UNIFIED IDEOGRAPH
+0xC68B 0x8313 #CJK UNIFIED IDEOGRAPH
+0xC68C 0x8316 #CJK UNIFIED IDEOGRAPH
+0xC68D 0x8318 #CJK UNIFIED IDEOGRAPH
+0xC68E 0x8319 #CJK UNIFIED IDEOGRAPH
+0xC68F 0x831D #CJK UNIFIED IDEOGRAPH
+0xC690 0x831E #CJK UNIFIED IDEOGRAPH
+0xC691 0x831F #CJK UNIFIED IDEOGRAPH
+0xC692 0x8320 #CJK UNIFIED IDEOGRAPH
+0xC693 0x8321 #CJK UNIFIED IDEOGRAPH
+0xC694 0x8322 #CJK UNIFIED IDEOGRAPH
+0xC695 0x8323 #CJK UNIFIED IDEOGRAPH
+0xC696 0x8324 #CJK UNIFIED IDEOGRAPH
+0xC697 0x8325 #CJK UNIFIED IDEOGRAPH
+0xC698 0x8326 #CJK UNIFIED IDEOGRAPH
+0xC699 0x8329 #CJK UNIFIED IDEOGRAPH
+0xC69A 0x832A #CJK UNIFIED IDEOGRAPH
+0xC69B 0x832E #CJK UNIFIED IDEOGRAPH
+0xC69C 0x8330 #CJK UNIFIED IDEOGRAPH
+0xC69D 0x8332 #CJK UNIFIED IDEOGRAPH
+0xC69E 0x8337 #CJK UNIFIED IDEOGRAPH
+0xC69F 0x833B #CJK UNIFIED IDEOGRAPH
+0xC6A0 0x833D #CJK UNIFIED IDEOGRAPH
+0xC6A1 0x5564 #CJK UNIFIED IDEOGRAPH
+0xC6A2 0x813E #CJK UNIFIED IDEOGRAPH
+0xC6A3 0x75B2 #CJK UNIFIED IDEOGRAPH
+0xC6A4 0x76AE #CJK UNIFIED IDEOGRAPH
+0xC6A5 0x5339 #CJK UNIFIED IDEOGRAPH
+0xC6A6 0x75DE #CJK UNIFIED IDEOGRAPH
+0xC6A7 0x50FB #CJK UNIFIED IDEOGRAPH
+0xC6A8 0x5C41 #CJK UNIFIED IDEOGRAPH
+0xC6A9 0x8B6C #CJK UNIFIED IDEOGRAPH
+0xC6AA 0x7BC7 #CJK UNIFIED IDEOGRAPH
+0xC6AB 0x504F #CJK UNIFIED IDEOGRAPH
+0xC6AC 0x7247 #CJK UNIFIED IDEOGRAPH
+0xC6AD 0x9A97 #CJK UNIFIED IDEOGRAPH
+0xC6AE 0x98D8 #CJK UNIFIED IDEOGRAPH
+0xC6AF 0x6F02 #CJK UNIFIED IDEOGRAPH
+0xC6B0 0x74E2 #CJK UNIFIED IDEOGRAPH
+0xC6B1 0x7968 #CJK UNIFIED IDEOGRAPH
+0xC6B2 0x6487 #CJK UNIFIED IDEOGRAPH
+0xC6B3 0x77A5 #CJK UNIFIED IDEOGRAPH
+0xC6B4 0x62FC #CJK UNIFIED IDEOGRAPH
+0xC6B5 0x9891 #CJK UNIFIED IDEOGRAPH
+0xC6B6 0x8D2B #CJK UNIFIED IDEOGRAPH
+0xC6B7 0x54C1 #CJK UNIFIED IDEOGRAPH
+0xC6B8 0x8058 #CJK UNIFIED IDEOGRAPH
+0xC6B9 0x4E52 #CJK UNIFIED IDEOGRAPH
+0xC6BA 0x576A #CJK UNIFIED IDEOGRAPH
+0xC6BB 0x82F9 #CJK UNIFIED IDEOGRAPH
+0xC6BC 0x840D #CJK UNIFIED IDEOGRAPH
+0xC6BD 0x5E73 #CJK UNIFIED IDEOGRAPH
+0xC6BE 0x51ED #CJK UNIFIED IDEOGRAPH
+0xC6BF 0x74F6 #CJK UNIFIED IDEOGRAPH
+0xC6C0 0x8BC4 #CJK UNIFIED IDEOGRAPH
+0xC6C1 0x5C4F #CJK UNIFIED IDEOGRAPH
+0xC6C2 0x5761 #CJK UNIFIED IDEOGRAPH
+0xC6C3 0x6CFC #CJK UNIFIED IDEOGRAPH
+0xC6C4 0x9887 #CJK UNIFIED IDEOGRAPH
+0xC6C5 0x5A46 #CJK UNIFIED IDEOGRAPH
+0xC6C6 0x7834 #CJK UNIFIED IDEOGRAPH
+0xC6C7 0x9B44 #CJK UNIFIED IDEOGRAPH
+0xC6C8 0x8FEB #CJK UNIFIED IDEOGRAPH
+0xC6C9 0x7C95 #CJK UNIFIED IDEOGRAPH
+0xC6CA 0x5256 #CJK UNIFIED IDEOGRAPH
+0xC6CB 0x6251 #CJK UNIFIED IDEOGRAPH
+0xC6CC 0x94FA #CJK UNIFIED IDEOGRAPH
+0xC6CD 0x4EC6 #CJK UNIFIED IDEOGRAPH
+0xC6CE 0x8386 #CJK UNIFIED IDEOGRAPH
+0xC6CF 0x8461 #CJK UNIFIED IDEOGRAPH
+0xC6D0 0x83E9 #CJK UNIFIED IDEOGRAPH
+0xC6D1 0x84B2 #CJK UNIFIED IDEOGRAPH
+0xC6D2 0x57D4 #CJK UNIFIED IDEOGRAPH
+0xC6D3 0x6734 #CJK UNIFIED IDEOGRAPH
+0xC6D4 0x5703 #CJK UNIFIED IDEOGRAPH
+0xC6D5 0x666E #CJK UNIFIED IDEOGRAPH
+0xC6D6 0x6D66 #CJK UNIFIED IDEOGRAPH
+0xC6D7 0x8C31 #CJK UNIFIED IDEOGRAPH
+0xC6D8 0x66DD #CJK UNIFIED IDEOGRAPH
+0xC6D9 0x7011 #CJK UNIFIED IDEOGRAPH
+0xC6DA 0x671F #CJK UNIFIED IDEOGRAPH
+0xC6DB 0x6B3A #CJK UNIFIED IDEOGRAPH
+0xC6DC 0x6816 #CJK UNIFIED IDEOGRAPH
+0xC6DD 0x621A #CJK UNIFIED IDEOGRAPH
+0xC6DE 0x59BB #CJK UNIFIED IDEOGRAPH
+0xC6DF 0x4E03 #CJK UNIFIED IDEOGRAPH
+0xC6E0 0x51C4 #CJK UNIFIED IDEOGRAPH
+0xC6E1 0x6F06 #CJK UNIFIED IDEOGRAPH
+0xC6E2 0x67D2 #CJK UNIFIED IDEOGRAPH
+0xC6E3 0x6C8F #CJK UNIFIED IDEOGRAPH
+0xC6E4 0x5176 #CJK UNIFIED IDEOGRAPH
+0xC6E5 0x68CB #CJK UNIFIED IDEOGRAPH
+0xC6E6 0x5947 #CJK UNIFIED IDEOGRAPH
+0xC6E7 0x6B67 #CJK UNIFIED IDEOGRAPH
+0xC6E8 0x7566 #CJK UNIFIED IDEOGRAPH
+0xC6E9 0x5D0E #CJK UNIFIED IDEOGRAPH
+0xC6EA 0x8110 #CJK UNIFIED IDEOGRAPH
+0xC6EB 0x9F50 #CJK UNIFIED IDEOGRAPH
+0xC6EC 0x65D7 #CJK UNIFIED IDEOGRAPH
+0xC6ED 0x7948 #CJK UNIFIED IDEOGRAPH
+0xC6EE 0x7941 #CJK UNIFIED IDEOGRAPH
+0xC6EF 0x9A91 #CJK UNIFIED IDEOGRAPH
+0xC6F0 0x8D77 #CJK UNIFIED IDEOGRAPH
+0xC6F1 0x5C82 #CJK UNIFIED IDEOGRAPH
+0xC6F2 0x4E5E #CJK UNIFIED IDEOGRAPH
+0xC6F3 0x4F01 #CJK UNIFIED IDEOGRAPH
+0xC6F4 0x542F #CJK UNIFIED IDEOGRAPH
+0xC6F5 0x5951 #CJK UNIFIED IDEOGRAPH
+0xC6F6 0x780C #CJK UNIFIED IDEOGRAPH
+0xC6F7 0x5668 #CJK UNIFIED IDEOGRAPH
+0xC6F8 0x6C14 #CJK UNIFIED IDEOGRAPH
+0xC6F9 0x8FC4 #CJK UNIFIED IDEOGRAPH
+0xC6FA 0x5F03 #CJK UNIFIED IDEOGRAPH
+0xC6FB 0x6C7D #CJK UNIFIED IDEOGRAPH
+0xC6FC 0x6CE3 #CJK UNIFIED IDEOGRAPH
+0xC6FD 0x8BAB #CJK UNIFIED IDEOGRAPH
+0xC6FE 0x6390 #CJK UNIFIED IDEOGRAPH
+0xC740 0x833E #CJK UNIFIED IDEOGRAPH
+0xC741 0x833F #CJK UNIFIED IDEOGRAPH
+0xC742 0x8341 #CJK UNIFIED IDEOGRAPH
+0xC743 0x8342 #CJK UNIFIED IDEOGRAPH
+0xC744 0x8344 #CJK UNIFIED IDEOGRAPH
+0xC745 0x8345 #CJK UNIFIED IDEOGRAPH
+0xC746 0x8348 #CJK UNIFIED IDEOGRAPH
+0xC747 0x834A #CJK UNIFIED IDEOGRAPH
+0xC748 0x834B #CJK UNIFIED IDEOGRAPH
+0xC749 0x834C #CJK UNIFIED IDEOGRAPH
+0xC74A 0x834D #CJK UNIFIED IDEOGRAPH
+0xC74B 0x834E #CJK UNIFIED IDEOGRAPH
+0xC74C 0x8353 #CJK UNIFIED IDEOGRAPH
+0xC74D 0x8355 #CJK UNIFIED IDEOGRAPH
+0xC74E 0x8356 #CJK UNIFIED IDEOGRAPH
+0xC74F 0x8357 #CJK UNIFIED IDEOGRAPH
+0xC750 0x8358 #CJK UNIFIED IDEOGRAPH
+0xC751 0x8359 #CJK UNIFIED IDEOGRAPH
+0xC752 0x835D #CJK UNIFIED IDEOGRAPH
+0xC753 0x8362 #CJK UNIFIED IDEOGRAPH
+0xC754 0x8370 #CJK UNIFIED IDEOGRAPH
+0xC755 0x8371 #CJK UNIFIED IDEOGRAPH
+0xC756 0x8372 #CJK UNIFIED IDEOGRAPH
+0xC757 0x8373 #CJK UNIFIED IDEOGRAPH
+0xC758 0x8374 #CJK UNIFIED IDEOGRAPH
+0xC759 0x8375 #CJK UNIFIED IDEOGRAPH
+0xC75A 0x8376 #CJK UNIFIED IDEOGRAPH
+0xC75B 0x8379 #CJK UNIFIED IDEOGRAPH
+0xC75C 0x837A #CJK UNIFIED IDEOGRAPH
+0xC75D 0x837E #CJK UNIFIED IDEOGRAPH
+0xC75E 0x837F #CJK UNIFIED IDEOGRAPH
+0xC75F 0x8380 #CJK UNIFIED IDEOGRAPH
+0xC760 0x8381 #CJK UNIFIED IDEOGRAPH
+0xC761 0x8382 #CJK UNIFIED IDEOGRAPH
+0xC762 0x8383 #CJK UNIFIED IDEOGRAPH
+0xC763 0x8384 #CJK UNIFIED IDEOGRAPH
+0xC764 0x8387 #CJK UNIFIED IDEOGRAPH
+0xC765 0x8388 #CJK UNIFIED IDEOGRAPH
+0xC766 0x838A #CJK UNIFIED IDEOGRAPH
+0xC767 0x838B #CJK UNIFIED IDEOGRAPH
+0xC768 0x838C #CJK UNIFIED IDEOGRAPH
+0xC769 0x838D #CJK UNIFIED IDEOGRAPH
+0xC76A 0x838F #CJK UNIFIED IDEOGRAPH
+0xC76B 0x8390 #CJK UNIFIED IDEOGRAPH
+0xC76C 0x8391 #CJK UNIFIED IDEOGRAPH
+0xC76D 0x8394 #CJK UNIFIED IDEOGRAPH
+0xC76E 0x8395 #CJK UNIFIED IDEOGRAPH
+0xC76F 0x8396 #CJK UNIFIED IDEOGRAPH
+0xC770 0x8397 #CJK UNIFIED IDEOGRAPH
+0xC771 0x8399 #CJK UNIFIED IDEOGRAPH
+0xC772 0x839A #CJK UNIFIED IDEOGRAPH
+0xC773 0x839D #CJK UNIFIED IDEOGRAPH
+0xC774 0x839F #CJK UNIFIED IDEOGRAPH
+0xC775 0x83A1 #CJK UNIFIED IDEOGRAPH
+0xC776 0x83A2 #CJK UNIFIED IDEOGRAPH
+0xC777 0x83A3 #CJK UNIFIED IDEOGRAPH
+0xC778 0x83A4 #CJK UNIFIED IDEOGRAPH
+0xC779 0x83A5 #CJK UNIFIED IDEOGRAPH
+0xC77A 0x83A6 #CJK UNIFIED IDEOGRAPH
+0xC77B 0x83A7 #CJK UNIFIED IDEOGRAPH
+0xC77C 0x83AC #CJK UNIFIED IDEOGRAPH
+0xC77D 0x83AD #CJK UNIFIED IDEOGRAPH
+0xC77E 0x83AE #CJK UNIFIED IDEOGRAPH
+0xC780 0x83AF #CJK UNIFIED IDEOGRAPH
+0xC781 0x83B5 #CJK UNIFIED IDEOGRAPH
+0xC782 0x83BB #CJK UNIFIED IDEOGRAPH
+0xC783 0x83BE #CJK UNIFIED IDEOGRAPH
+0xC784 0x83BF #CJK UNIFIED IDEOGRAPH
+0xC785 0x83C2 #CJK UNIFIED IDEOGRAPH
+0xC786 0x83C3 #CJK UNIFIED IDEOGRAPH
+0xC787 0x83C4 #CJK UNIFIED IDEOGRAPH
+0xC788 0x83C6 #CJK UNIFIED IDEOGRAPH
+0xC789 0x83C8 #CJK UNIFIED IDEOGRAPH
+0xC78A 0x83C9 #CJK UNIFIED IDEOGRAPH
+0xC78B 0x83CB #CJK UNIFIED IDEOGRAPH
+0xC78C 0x83CD #CJK UNIFIED IDEOGRAPH
+0xC78D 0x83CE #CJK UNIFIED IDEOGRAPH
+0xC78E 0x83D0 #CJK UNIFIED IDEOGRAPH
+0xC78F 0x83D1 #CJK UNIFIED IDEOGRAPH
+0xC790 0x83D2 #CJK UNIFIED IDEOGRAPH
+0xC791 0x83D3 #CJK UNIFIED IDEOGRAPH
+0xC792 0x83D5 #CJK UNIFIED IDEOGRAPH
+0xC793 0x83D7 #CJK UNIFIED IDEOGRAPH
+0xC794 0x83D9 #CJK UNIFIED IDEOGRAPH
+0xC795 0x83DA #CJK UNIFIED IDEOGRAPH
+0xC796 0x83DB #CJK UNIFIED IDEOGRAPH
+0xC797 0x83DE #CJK UNIFIED IDEOGRAPH
+0xC798 0x83E2 #CJK UNIFIED IDEOGRAPH
+0xC799 0x83E3 #CJK UNIFIED IDEOGRAPH
+0xC79A 0x83E4 #CJK UNIFIED IDEOGRAPH
+0xC79B 0x83E6 #CJK UNIFIED IDEOGRAPH
+0xC79C 0x83E7 #CJK UNIFIED IDEOGRAPH
+0xC79D 0x83E8 #CJK UNIFIED IDEOGRAPH
+0xC79E 0x83EB #CJK UNIFIED IDEOGRAPH
+0xC79F 0x83EC #CJK UNIFIED IDEOGRAPH
+0xC7A0 0x83ED #CJK UNIFIED IDEOGRAPH
+0xC7A1 0x6070 #CJK UNIFIED IDEOGRAPH
+0xC7A2 0x6D3D #CJK UNIFIED IDEOGRAPH
+0xC7A3 0x7275 #CJK UNIFIED IDEOGRAPH
+0xC7A4 0x6266 #CJK UNIFIED IDEOGRAPH
+0xC7A5 0x948E #CJK UNIFIED IDEOGRAPH
+0xC7A6 0x94C5 #CJK UNIFIED IDEOGRAPH
+0xC7A7 0x5343 #CJK UNIFIED IDEOGRAPH
+0xC7A8 0x8FC1 #CJK UNIFIED IDEOGRAPH
+0xC7A9 0x7B7E #CJK UNIFIED IDEOGRAPH
+0xC7AA 0x4EDF #CJK UNIFIED IDEOGRAPH
+0xC7AB 0x8C26 #CJK UNIFIED IDEOGRAPH
+0xC7AC 0x4E7E #CJK UNIFIED IDEOGRAPH
+0xC7AD 0x9ED4 #CJK UNIFIED IDEOGRAPH
+0xC7AE 0x94B1 #CJK UNIFIED IDEOGRAPH
+0xC7AF 0x94B3 #CJK UNIFIED IDEOGRAPH
+0xC7B0 0x524D #CJK UNIFIED IDEOGRAPH
+0xC7B1 0x6F5C #CJK UNIFIED IDEOGRAPH
+0xC7B2 0x9063 #CJK UNIFIED IDEOGRAPH
+0xC7B3 0x6D45 #CJK UNIFIED IDEOGRAPH
+0xC7B4 0x8C34 #CJK UNIFIED IDEOGRAPH
+0xC7B5 0x5811 #CJK UNIFIED IDEOGRAPH
+0xC7B6 0x5D4C #CJK UNIFIED IDEOGRAPH
+0xC7B7 0x6B20 #CJK UNIFIED IDEOGRAPH
+0xC7B8 0x6B49 #CJK UNIFIED IDEOGRAPH
+0xC7B9 0x67AA #CJK UNIFIED IDEOGRAPH
+0xC7BA 0x545B #CJK UNIFIED IDEOGRAPH
+0xC7BB 0x8154 #CJK UNIFIED IDEOGRAPH
+0xC7BC 0x7F8C #CJK UNIFIED IDEOGRAPH
+0xC7BD 0x5899 #CJK UNIFIED IDEOGRAPH
+0xC7BE 0x8537 #CJK UNIFIED IDEOGRAPH
+0xC7BF 0x5F3A #CJK UNIFIED IDEOGRAPH
+0xC7C0 0x62A2 #CJK UNIFIED IDEOGRAPH
+0xC7C1 0x6A47 #CJK UNIFIED IDEOGRAPH
+0xC7C2 0x9539 #CJK UNIFIED IDEOGRAPH
+0xC7C3 0x6572 #CJK UNIFIED IDEOGRAPH
+0xC7C4 0x6084 #CJK UNIFIED IDEOGRAPH
+0xC7C5 0x6865 #CJK UNIFIED IDEOGRAPH
+0xC7C6 0x77A7 #CJK UNIFIED IDEOGRAPH
+0xC7C7 0x4E54 #CJK UNIFIED IDEOGRAPH
+0xC7C8 0x4FA8 #CJK UNIFIED IDEOGRAPH
+0xC7C9 0x5DE7 #CJK UNIFIED IDEOGRAPH
+0xC7CA 0x9798 #CJK UNIFIED IDEOGRAPH
+0xC7CB 0x64AC #CJK UNIFIED IDEOGRAPH
+0xC7CC 0x7FD8 #CJK UNIFIED IDEOGRAPH
+0xC7CD 0x5CED #CJK UNIFIED IDEOGRAPH
+0xC7CE 0x4FCF #CJK UNIFIED IDEOGRAPH
+0xC7CF 0x7A8D #CJK UNIFIED IDEOGRAPH
+0xC7D0 0x5207 #CJK UNIFIED IDEOGRAPH
+0xC7D1 0x8304 #CJK UNIFIED IDEOGRAPH
+0xC7D2 0x4E14 #CJK UNIFIED IDEOGRAPH
+0xC7D3 0x602F #CJK UNIFIED IDEOGRAPH
+0xC7D4 0x7A83 #CJK UNIFIED IDEOGRAPH
+0xC7D5 0x94A6 #CJK UNIFIED IDEOGRAPH
+0xC7D6 0x4FB5 #CJK UNIFIED IDEOGRAPH
+0xC7D7 0x4EB2 #CJK UNIFIED IDEOGRAPH
+0xC7D8 0x79E6 #CJK UNIFIED IDEOGRAPH
+0xC7D9 0x7434 #CJK UNIFIED IDEOGRAPH
+0xC7DA 0x52E4 #CJK UNIFIED IDEOGRAPH
+0xC7DB 0x82B9 #CJK UNIFIED IDEOGRAPH
+0xC7DC 0x64D2 #CJK UNIFIED IDEOGRAPH
+0xC7DD 0x79BD #CJK UNIFIED IDEOGRAPH
+0xC7DE 0x5BDD #CJK UNIFIED IDEOGRAPH
+0xC7DF 0x6C81 #CJK UNIFIED IDEOGRAPH
+0xC7E0 0x9752 #CJK UNIFIED IDEOGRAPH
+0xC7E1 0x8F7B #CJK UNIFIED IDEOGRAPH
+0xC7E2 0x6C22 #CJK UNIFIED IDEOGRAPH
+0xC7E3 0x503E #CJK UNIFIED IDEOGRAPH
+0xC7E4 0x537F #CJK UNIFIED IDEOGRAPH
+0xC7E5 0x6E05 #CJK UNIFIED IDEOGRAPH
+0xC7E6 0x64CE #CJK UNIFIED IDEOGRAPH
+0xC7E7 0x6674 #CJK UNIFIED IDEOGRAPH
+0xC7E8 0x6C30 #CJK UNIFIED IDEOGRAPH
+0xC7E9 0x60C5 #CJK UNIFIED IDEOGRAPH
+0xC7EA 0x9877 #CJK UNIFIED IDEOGRAPH
+0xC7EB 0x8BF7 #CJK UNIFIED IDEOGRAPH
+0xC7EC 0x5E86 #CJK UNIFIED IDEOGRAPH
+0xC7ED 0x743C #CJK UNIFIED IDEOGRAPH
+0xC7EE 0x7A77 #CJK UNIFIED IDEOGRAPH
+0xC7EF 0x79CB #CJK UNIFIED IDEOGRAPH
+0xC7F0 0x4E18 #CJK UNIFIED IDEOGRAPH
+0xC7F1 0x90B1 #CJK UNIFIED IDEOGRAPH
+0xC7F2 0x7403 #CJK UNIFIED IDEOGRAPH
+0xC7F3 0x6C42 #CJK UNIFIED IDEOGRAPH
+0xC7F4 0x56DA #CJK UNIFIED IDEOGRAPH
+0xC7F5 0x914B #CJK UNIFIED IDEOGRAPH
+0xC7F6 0x6CC5 #CJK UNIFIED IDEOGRAPH
+0xC7F7 0x8D8B #CJK UNIFIED IDEOGRAPH
+0xC7F8 0x533A #CJK UNIFIED IDEOGRAPH
+0xC7F9 0x86C6 #CJK UNIFIED IDEOGRAPH
+0xC7FA 0x66F2 #CJK UNIFIED IDEOGRAPH
+0xC7FB 0x8EAF #CJK UNIFIED IDEOGRAPH
+0xC7FC 0x5C48 #CJK UNIFIED IDEOGRAPH
+0xC7FD 0x9A71 #CJK UNIFIED IDEOGRAPH
+0xC7FE 0x6E20 #CJK UNIFIED IDEOGRAPH
+0xC840 0x83EE #CJK UNIFIED IDEOGRAPH
+0xC841 0x83EF #CJK UNIFIED IDEOGRAPH
+0xC842 0x83F3 #CJK UNIFIED IDEOGRAPH
+0xC843 0x83F4 #CJK UNIFIED IDEOGRAPH
+0xC844 0x83F5 #CJK UNIFIED IDEOGRAPH
+0xC845 0x83F6 #CJK UNIFIED IDEOGRAPH
+0xC846 0x83F7 #CJK UNIFIED IDEOGRAPH
+0xC847 0x83FA #CJK UNIFIED IDEOGRAPH
+0xC848 0x83FB #CJK UNIFIED IDEOGRAPH
+0xC849 0x83FC #CJK UNIFIED IDEOGRAPH
+0xC84A 0x83FE #CJK UNIFIED IDEOGRAPH
+0xC84B 0x83FF #CJK UNIFIED IDEOGRAPH
+0xC84C 0x8400 #CJK UNIFIED IDEOGRAPH
+0xC84D 0x8402 #CJK UNIFIED IDEOGRAPH
+0xC84E 0x8405 #CJK UNIFIED IDEOGRAPH
+0xC84F 0x8407 #CJK UNIFIED IDEOGRAPH
+0xC850 0x8408 #CJK UNIFIED IDEOGRAPH
+0xC851 0x8409 #CJK UNIFIED IDEOGRAPH
+0xC852 0x840A #CJK UNIFIED IDEOGRAPH
+0xC853 0x8410 #CJK UNIFIED IDEOGRAPH
+0xC854 0x8412 #CJK UNIFIED IDEOGRAPH
+0xC855 0x8413 #CJK UNIFIED IDEOGRAPH
+0xC856 0x8414 #CJK UNIFIED IDEOGRAPH
+0xC857 0x8415 #CJK UNIFIED IDEOGRAPH
+0xC858 0x8416 #CJK UNIFIED IDEOGRAPH
+0xC859 0x8417 #CJK UNIFIED IDEOGRAPH
+0xC85A 0x8419 #CJK UNIFIED IDEOGRAPH
+0xC85B 0x841A #CJK UNIFIED IDEOGRAPH
+0xC85C 0x841B #CJK UNIFIED IDEOGRAPH
+0xC85D 0x841E #CJK UNIFIED IDEOGRAPH
+0xC85E 0x841F #CJK UNIFIED IDEOGRAPH
+0xC85F 0x8420 #CJK UNIFIED IDEOGRAPH
+0xC860 0x8421 #CJK UNIFIED IDEOGRAPH
+0xC861 0x8422 #CJK UNIFIED IDEOGRAPH
+0xC862 0x8423 #CJK UNIFIED IDEOGRAPH
+0xC863 0x8429 #CJK UNIFIED IDEOGRAPH
+0xC864 0x842A #CJK UNIFIED IDEOGRAPH
+0xC865 0x842B #CJK UNIFIED IDEOGRAPH
+0xC866 0x842C #CJK UNIFIED IDEOGRAPH
+0xC867 0x842D #CJK UNIFIED IDEOGRAPH
+0xC868 0x842E #CJK UNIFIED IDEOGRAPH
+0xC869 0x842F #CJK UNIFIED IDEOGRAPH
+0xC86A 0x8430 #CJK UNIFIED IDEOGRAPH
+0xC86B 0x8432 #CJK UNIFIED IDEOGRAPH
+0xC86C 0x8433 #CJK UNIFIED IDEOGRAPH
+0xC86D 0x8434 #CJK UNIFIED IDEOGRAPH
+0xC86E 0x8435 #CJK UNIFIED IDEOGRAPH
+0xC86F 0x8436 #CJK UNIFIED IDEOGRAPH
+0xC870 0x8437 #CJK UNIFIED IDEOGRAPH
+0xC871 0x8439 #CJK UNIFIED IDEOGRAPH
+0xC872 0x843A #CJK UNIFIED IDEOGRAPH
+0xC873 0x843B #CJK UNIFIED IDEOGRAPH
+0xC874 0x843E #CJK UNIFIED IDEOGRAPH
+0xC875 0x843F #CJK UNIFIED IDEOGRAPH
+0xC876 0x8440 #CJK UNIFIED IDEOGRAPH
+0xC877 0x8441 #CJK UNIFIED IDEOGRAPH
+0xC878 0x8442 #CJK UNIFIED IDEOGRAPH
+0xC879 0x8443 #CJK UNIFIED IDEOGRAPH
+0xC87A 0x8444 #CJK UNIFIED IDEOGRAPH
+0xC87B 0x8445 #CJK UNIFIED IDEOGRAPH
+0xC87C 0x8447 #CJK UNIFIED IDEOGRAPH
+0xC87D 0x8448 #CJK UNIFIED IDEOGRAPH
+0xC87E 0x8449 #CJK UNIFIED IDEOGRAPH
+0xC880 0x844A #CJK UNIFIED IDEOGRAPH
+0xC881 0x844B #CJK UNIFIED IDEOGRAPH
+0xC882 0x844C #CJK UNIFIED IDEOGRAPH
+0xC883 0x844D #CJK UNIFIED IDEOGRAPH
+0xC884 0x844E #CJK UNIFIED IDEOGRAPH
+0xC885 0x844F #CJK UNIFIED IDEOGRAPH
+0xC886 0x8450 #CJK UNIFIED IDEOGRAPH
+0xC887 0x8452 #CJK UNIFIED IDEOGRAPH
+0xC888 0x8453 #CJK UNIFIED IDEOGRAPH
+0xC889 0x8454 #CJK UNIFIED IDEOGRAPH
+0xC88A 0x8455 #CJK UNIFIED IDEOGRAPH
+0xC88B 0x8456 #CJK UNIFIED IDEOGRAPH
+0xC88C 0x8458 #CJK UNIFIED IDEOGRAPH
+0xC88D 0x845D #CJK UNIFIED IDEOGRAPH
+0xC88E 0x845E #CJK UNIFIED IDEOGRAPH
+0xC88F 0x845F #CJK UNIFIED IDEOGRAPH
+0xC890 0x8460 #CJK UNIFIED IDEOGRAPH
+0xC891 0x8462 #CJK UNIFIED IDEOGRAPH
+0xC892 0x8464 #CJK UNIFIED IDEOGRAPH
+0xC893 0x8465 #CJK UNIFIED IDEOGRAPH
+0xC894 0x8466 #CJK UNIFIED IDEOGRAPH
+0xC895 0x8467 #CJK UNIFIED IDEOGRAPH
+0xC896 0x8468 #CJK UNIFIED IDEOGRAPH
+0xC897 0x846A #CJK UNIFIED IDEOGRAPH
+0xC898 0x846E #CJK UNIFIED IDEOGRAPH
+0xC899 0x846F #CJK UNIFIED IDEOGRAPH
+0xC89A 0x8470 #CJK UNIFIED IDEOGRAPH
+0xC89B 0x8472 #CJK UNIFIED IDEOGRAPH
+0xC89C 0x8474 #CJK UNIFIED IDEOGRAPH
+0xC89D 0x8477 #CJK UNIFIED IDEOGRAPH
+0xC89E 0x8479 #CJK UNIFIED IDEOGRAPH
+0xC89F 0x847B #CJK UNIFIED IDEOGRAPH
+0xC8A0 0x847C #CJK UNIFIED IDEOGRAPH
+0xC8A1 0x53D6 #CJK UNIFIED IDEOGRAPH
+0xC8A2 0x5A36 #CJK UNIFIED IDEOGRAPH
+0xC8A3 0x9F8B #CJK UNIFIED IDEOGRAPH
+0xC8A4 0x8DA3 #CJK UNIFIED IDEOGRAPH
+0xC8A5 0x53BB #CJK UNIFIED IDEOGRAPH
+0xC8A6 0x5708 #CJK UNIFIED IDEOGRAPH
+0xC8A7 0x98A7 #CJK UNIFIED IDEOGRAPH
+0xC8A8 0x6743 #CJK UNIFIED IDEOGRAPH
+0xC8A9 0x919B #CJK UNIFIED IDEOGRAPH
+0xC8AA 0x6CC9 #CJK UNIFIED IDEOGRAPH
+0xC8AB 0x5168 #CJK UNIFIED IDEOGRAPH
+0xC8AC 0x75CA #CJK UNIFIED IDEOGRAPH
+0xC8AD 0x62F3 #CJK UNIFIED IDEOGRAPH
+0xC8AE 0x72AC #CJK UNIFIED IDEOGRAPH
+0xC8AF 0x5238 #CJK UNIFIED IDEOGRAPH
+0xC8B0 0x529D #CJK UNIFIED IDEOGRAPH
+0xC8B1 0x7F3A #CJK UNIFIED IDEOGRAPH
+0xC8B2 0x7094 #CJK UNIFIED IDEOGRAPH
+0xC8B3 0x7638 #CJK UNIFIED IDEOGRAPH
+0xC8B4 0x5374 #CJK UNIFIED IDEOGRAPH
+0xC8B5 0x9E4A #CJK UNIFIED IDEOGRAPH
+0xC8B6 0x69B7 #CJK UNIFIED IDEOGRAPH
+0xC8B7 0x786E #CJK UNIFIED IDEOGRAPH
+0xC8B8 0x96C0 #CJK UNIFIED IDEOGRAPH
+0xC8B9 0x88D9 #CJK UNIFIED IDEOGRAPH
+0xC8BA 0x7FA4 #CJK UNIFIED IDEOGRAPH
+0xC8BB 0x7136 #CJK UNIFIED IDEOGRAPH
+0xC8BC 0x71C3 #CJK UNIFIED IDEOGRAPH
+0xC8BD 0x5189 #CJK UNIFIED IDEOGRAPH
+0xC8BE 0x67D3 #CJK UNIFIED IDEOGRAPH
+0xC8BF 0x74E4 #CJK UNIFIED IDEOGRAPH
+0xC8C0 0x58E4 #CJK UNIFIED IDEOGRAPH
+0xC8C1 0x6518 #CJK UNIFIED IDEOGRAPH
+0xC8C2 0x56B7 #CJK UNIFIED IDEOGRAPH
+0xC8C3 0x8BA9 #CJK UNIFIED IDEOGRAPH
+0xC8C4 0x9976 #CJK UNIFIED IDEOGRAPH
+0xC8C5 0x6270 #CJK UNIFIED IDEOGRAPH
+0xC8C6 0x7ED5 #CJK UNIFIED IDEOGRAPH
+0xC8C7 0x60F9 #CJK UNIFIED IDEOGRAPH
+0xC8C8 0x70ED #CJK UNIFIED IDEOGRAPH
+0xC8C9 0x58EC #CJK UNIFIED IDEOGRAPH
+0xC8CA 0x4EC1 #CJK UNIFIED IDEOGRAPH
+0xC8CB 0x4EBA #CJK UNIFIED IDEOGRAPH
+0xC8CC 0x5FCD #CJK UNIFIED IDEOGRAPH
+0xC8CD 0x97E7 #CJK UNIFIED IDEOGRAPH
+0xC8CE 0x4EFB #CJK UNIFIED IDEOGRAPH
+0xC8CF 0x8BA4 #CJK UNIFIED IDEOGRAPH
+0xC8D0 0x5203 #CJK UNIFIED IDEOGRAPH
+0xC8D1 0x598A #CJK UNIFIED IDEOGRAPH
+0xC8D2 0x7EAB #CJK UNIFIED IDEOGRAPH
+0xC8D3 0x6254 #CJK UNIFIED IDEOGRAPH
+0xC8D4 0x4ECD #CJK UNIFIED IDEOGRAPH
+0xC8D5 0x65E5 #CJK UNIFIED IDEOGRAPH
+0xC8D6 0x620E #CJK UNIFIED IDEOGRAPH
+0xC8D7 0x8338 #CJK UNIFIED IDEOGRAPH
+0xC8D8 0x84C9 #CJK UNIFIED IDEOGRAPH
+0xC8D9 0x8363 #CJK UNIFIED IDEOGRAPH
+0xC8DA 0x878D #CJK UNIFIED IDEOGRAPH
+0xC8DB 0x7194 #CJK UNIFIED IDEOGRAPH
+0xC8DC 0x6EB6 #CJK UNIFIED IDEOGRAPH
+0xC8DD 0x5BB9 #CJK UNIFIED IDEOGRAPH
+0xC8DE 0x7ED2 #CJK UNIFIED IDEOGRAPH
+0xC8DF 0x5197 #CJK UNIFIED IDEOGRAPH
+0xC8E0 0x63C9 #CJK UNIFIED IDEOGRAPH
+0xC8E1 0x67D4 #CJK UNIFIED IDEOGRAPH
+0xC8E2 0x8089 #CJK UNIFIED IDEOGRAPH
+0xC8E3 0x8339 #CJK UNIFIED IDEOGRAPH
+0xC8E4 0x8815 #CJK UNIFIED IDEOGRAPH
+0xC8E5 0x5112 #CJK UNIFIED IDEOGRAPH
+0xC8E6 0x5B7A #CJK UNIFIED IDEOGRAPH
+0xC8E7 0x5982 #CJK UNIFIED IDEOGRAPH
+0xC8E8 0x8FB1 #CJK UNIFIED IDEOGRAPH
+0xC8E9 0x4E73 #CJK UNIFIED IDEOGRAPH
+0xC8EA 0x6C5D #CJK UNIFIED IDEOGRAPH
+0xC8EB 0x5165 #CJK UNIFIED IDEOGRAPH
+0xC8EC 0x8925 #CJK UNIFIED IDEOGRAPH
+0xC8ED 0x8F6F #CJK UNIFIED IDEOGRAPH
+0xC8EE 0x962E #CJK UNIFIED IDEOGRAPH
+0xC8EF 0x854A #CJK UNIFIED IDEOGRAPH
+0xC8F0 0x745E #CJK UNIFIED IDEOGRAPH
+0xC8F1 0x9510 #CJK UNIFIED IDEOGRAPH
+0xC8F2 0x95F0 #CJK UNIFIED IDEOGRAPH
+0xC8F3 0x6DA6 #CJK UNIFIED IDEOGRAPH
+0xC8F4 0x82E5 #CJK UNIFIED IDEOGRAPH
+0xC8F5 0x5F31 #CJK UNIFIED IDEOGRAPH
+0xC8F6 0x6492 #CJK UNIFIED IDEOGRAPH
+0xC8F7 0x6D12 #CJK UNIFIED IDEOGRAPH
+0xC8F8 0x8428 #CJK UNIFIED IDEOGRAPH
+0xC8F9 0x816E #CJK UNIFIED IDEOGRAPH
+0xC8FA 0x9CC3 #CJK UNIFIED IDEOGRAPH
+0xC8FB 0x585E #CJK UNIFIED IDEOGRAPH
+0xC8FC 0x8D5B #CJK UNIFIED IDEOGRAPH
+0xC8FD 0x4E09 #CJK UNIFIED IDEOGRAPH
+0xC8FE 0x53C1 #CJK UNIFIED IDEOGRAPH
+0xC940 0x847D #CJK UNIFIED IDEOGRAPH
+0xC941 0x847E #CJK UNIFIED IDEOGRAPH
+0xC942 0x847F #CJK UNIFIED IDEOGRAPH
+0xC943 0x8480 #CJK UNIFIED IDEOGRAPH
+0xC944 0x8481 #CJK UNIFIED IDEOGRAPH
+0xC945 0x8483 #CJK UNIFIED IDEOGRAPH
+0xC946 0x8484 #CJK UNIFIED IDEOGRAPH
+0xC947 0x8485 #CJK UNIFIED IDEOGRAPH
+0xC948 0x8486 #CJK UNIFIED IDEOGRAPH
+0xC949 0x848A #CJK UNIFIED IDEOGRAPH
+0xC94A 0x848D #CJK UNIFIED IDEOGRAPH
+0xC94B 0x848F #CJK UNIFIED IDEOGRAPH
+0xC94C 0x8490 #CJK UNIFIED IDEOGRAPH
+0xC94D 0x8491 #CJK UNIFIED IDEOGRAPH
+0xC94E 0x8492 #CJK UNIFIED IDEOGRAPH
+0xC94F 0x8493 #CJK UNIFIED IDEOGRAPH
+0xC950 0x8494 #CJK UNIFIED IDEOGRAPH
+0xC951 0x8495 #CJK UNIFIED IDEOGRAPH
+0xC952 0x8496 #CJK UNIFIED IDEOGRAPH
+0xC953 0x8498 #CJK UNIFIED IDEOGRAPH
+0xC954 0x849A #CJK UNIFIED IDEOGRAPH
+0xC955 0x849B #CJK UNIFIED IDEOGRAPH
+0xC956 0x849D #CJK UNIFIED IDEOGRAPH
+0xC957 0x849E #CJK UNIFIED IDEOGRAPH
+0xC958 0x849F #CJK UNIFIED IDEOGRAPH
+0xC959 0x84A0 #CJK UNIFIED IDEOGRAPH
+0xC95A 0x84A2 #CJK UNIFIED IDEOGRAPH
+0xC95B 0x84A3 #CJK UNIFIED IDEOGRAPH
+0xC95C 0x84A4 #CJK UNIFIED IDEOGRAPH
+0xC95D 0x84A5 #CJK UNIFIED IDEOGRAPH
+0xC95E 0x84A6 #CJK UNIFIED IDEOGRAPH
+0xC95F 0x84A7 #CJK UNIFIED IDEOGRAPH
+0xC960 0x84A8 #CJK UNIFIED IDEOGRAPH
+0xC961 0x84A9 #CJK UNIFIED IDEOGRAPH
+0xC962 0x84AA #CJK UNIFIED IDEOGRAPH
+0xC963 0x84AB #CJK UNIFIED IDEOGRAPH
+0xC964 0x84AC #CJK UNIFIED IDEOGRAPH
+0xC965 0x84AD #CJK UNIFIED IDEOGRAPH
+0xC966 0x84AE #CJK UNIFIED IDEOGRAPH
+0xC967 0x84B0 #CJK UNIFIED IDEOGRAPH
+0xC968 0x84B1 #CJK UNIFIED IDEOGRAPH
+0xC969 0x84B3 #CJK UNIFIED IDEOGRAPH
+0xC96A 0x84B5 #CJK UNIFIED IDEOGRAPH
+0xC96B 0x84B6 #CJK UNIFIED IDEOGRAPH
+0xC96C 0x84B7 #CJK UNIFIED IDEOGRAPH
+0xC96D 0x84BB #CJK UNIFIED IDEOGRAPH
+0xC96E 0x84BC #CJK UNIFIED IDEOGRAPH
+0xC96F 0x84BE #CJK UNIFIED IDEOGRAPH
+0xC970 0x84C0 #CJK UNIFIED IDEOGRAPH
+0xC971 0x84C2 #CJK UNIFIED IDEOGRAPH
+0xC972 0x84C3 #CJK UNIFIED IDEOGRAPH
+0xC973 0x84C5 #CJK UNIFIED IDEOGRAPH
+0xC974 0x84C6 #CJK UNIFIED IDEOGRAPH
+0xC975 0x84C7 #CJK UNIFIED IDEOGRAPH
+0xC976 0x84C8 #CJK UNIFIED IDEOGRAPH
+0xC977 0x84CB #CJK UNIFIED IDEOGRAPH
+0xC978 0x84CC #CJK UNIFIED IDEOGRAPH
+0xC979 0x84CE #CJK UNIFIED IDEOGRAPH
+0xC97A 0x84CF #CJK UNIFIED IDEOGRAPH
+0xC97B 0x84D2 #CJK UNIFIED IDEOGRAPH
+0xC97C 0x84D4 #CJK UNIFIED IDEOGRAPH
+0xC97D 0x84D5 #CJK UNIFIED IDEOGRAPH
+0xC97E 0x84D7 #CJK UNIFIED IDEOGRAPH
+0xC980 0x84D8 #CJK UNIFIED IDEOGRAPH
+0xC981 0x84D9 #CJK UNIFIED IDEOGRAPH
+0xC982 0x84DA #CJK UNIFIED IDEOGRAPH
+0xC983 0x84DB #CJK UNIFIED IDEOGRAPH
+0xC984 0x84DC #CJK UNIFIED IDEOGRAPH
+0xC985 0x84DE #CJK UNIFIED IDEOGRAPH
+0xC986 0x84E1 #CJK UNIFIED IDEOGRAPH
+0xC987 0x84E2 #CJK UNIFIED IDEOGRAPH
+0xC988 0x84E4 #CJK UNIFIED IDEOGRAPH
+0xC989 0x84E7 #CJK UNIFIED IDEOGRAPH
+0xC98A 0x84E8 #CJK UNIFIED IDEOGRAPH
+0xC98B 0x84E9 #CJK UNIFIED IDEOGRAPH
+0xC98C 0x84EA #CJK UNIFIED IDEOGRAPH
+0xC98D 0x84EB #CJK UNIFIED IDEOGRAPH
+0xC98E 0x84ED #CJK UNIFIED IDEOGRAPH
+0xC98F 0x84EE #CJK UNIFIED IDEOGRAPH
+0xC990 0x84EF #CJK UNIFIED IDEOGRAPH
+0xC991 0x84F1 #CJK UNIFIED IDEOGRAPH
+0xC992 0x84F2 #CJK UNIFIED IDEOGRAPH
+0xC993 0x84F3 #CJK UNIFIED IDEOGRAPH
+0xC994 0x84F4 #CJK UNIFIED IDEOGRAPH
+0xC995 0x84F5 #CJK UNIFIED IDEOGRAPH
+0xC996 0x84F6 #CJK UNIFIED IDEOGRAPH
+0xC997 0x84F7 #CJK UNIFIED IDEOGRAPH
+0xC998 0x84F8 #CJK UNIFIED IDEOGRAPH
+0xC999 0x84F9 #CJK UNIFIED IDEOGRAPH
+0xC99A 0x84FA #CJK UNIFIED IDEOGRAPH
+0xC99B 0x84FB #CJK UNIFIED IDEOGRAPH
+0xC99C 0x84FD #CJK UNIFIED IDEOGRAPH
+0xC99D 0x84FE #CJK UNIFIED IDEOGRAPH
+0xC99E 0x8500 #CJK UNIFIED IDEOGRAPH
+0xC99F 0x8501 #CJK UNIFIED IDEOGRAPH
+0xC9A0 0x8502 #CJK UNIFIED IDEOGRAPH
+0xC9A1 0x4F1E #CJK UNIFIED IDEOGRAPH
+0xC9A2 0x6563 #CJK UNIFIED IDEOGRAPH
+0xC9A3 0x6851 #CJK UNIFIED IDEOGRAPH
+0xC9A4 0x55D3 #CJK UNIFIED IDEOGRAPH
+0xC9A5 0x4E27 #CJK UNIFIED IDEOGRAPH
+0xC9A6 0x6414 #CJK UNIFIED IDEOGRAPH
+0xC9A7 0x9A9A #CJK UNIFIED IDEOGRAPH
+0xC9A8 0x626B #CJK UNIFIED IDEOGRAPH
+0xC9A9 0x5AC2 #CJK UNIFIED IDEOGRAPH
+0xC9AA 0x745F #CJK UNIFIED IDEOGRAPH
+0xC9AB 0x8272 #CJK UNIFIED IDEOGRAPH
+0xC9AC 0x6DA9 #CJK UNIFIED IDEOGRAPH
+0xC9AD 0x68EE #CJK UNIFIED IDEOGRAPH
+0xC9AE 0x50E7 #CJK UNIFIED IDEOGRAPH
+0xC9AF 0x838E #CJK UNIFIED IDEOGRAPH
+0xC9B0 0x7802 #CJK UNIFIED IDEOGRAPH
+0xC9B1 0x6740 #CJK UNIFIED IDEOGRAPH
+0xC9B2 0x5239 #CJK UNIFIED IDEOGRAPH
+0xC9B3 0x6C99 #CJK UNIFIED IDEOGRAPH
+0xC9B4 0x7EB1 #CJK UNIFIED IDEOGRAPH
+0xC9B5 0x50BB #CJK UNIFIED IDEOGRAPH
+0xC9B6 0x5565 #CJK UNIFIED IDEOGRAPH
+0xC9B7 0x715E #CJK UNIFIED IDEOGRAPH
+0xC9B8 0x7B5B #CJK UNIFIED IDEOGRAPH
+0xC9B9 0x6652 #CJK UNIFIED IDEOGRAPH
+0xC9BA 0x73CA #CJK UNIFIED IDEOGRAPH
+0xC9BB 0x82EB #CJK UNIFIED IDEOGRAPH
+0xC9BC 0x6749 #CJK UNIFIED IDEOGRAPH
+0xC9BD 0x5C71 #CJK UNIFIED IDEOGRAPH
+0xC9BE 0x5220 #CJK UNIFIED IDEOGRAPH
+0xC9BF 0x717D #CJK UNIFIED IDEOGRAPH
+0xC9C0 0x886B #CJK UNIFIED IDEOGRAPH
+0xC9C1 0x95EA #CJK UNIFIED IDEOGRAPH
+0xC9C2 0x9655 #CJK UNIFIED IDEOGRAPH
+0xC9C3 0x64C5 #CJK UNIFIED IDEOGRAPH
+0xC9C4 0x8D61 #CJK UNIFIED IDEOGRAPH
+0xC9C5 0x81B3 #CJK UNIFIED IDEOGRAPH
+0xC9C6 0x5584 #CJK UNIFIED IDEOGRAPH
+0xC9C7 0x6C55 #CJK UNIFIED IDEOGRAPH
+0xC9C8 0x6247 #CJK UNIFIED IDEOGRAPH
+0xC9C9 0x7F2E #CJK UNIFIED IDEOGRAPH
+0xC9CA 0x5892 #CJK UNIFIED IDEOGRAPH
+0xC9CB 0x4F24 #CJK UNIFIED IDEOGRAPH
+0xC9CC 0x5546 #CJK UNIFIED IDEOGRAPH
+0xC9CD 0x8D4F #CJK UNIFIED IDEOGRAPH
+0xC9CE 0x664C #CJK UNIFIED IDEOGRAPH
+0xC9CF 0x4E0A #CJK UNIFIED IDEOGRAPH
+0xC9D0 0x5C1A #CJK UNIFIED IDEOGRAPH
+0xC9D1 0x88F3 #CJK UNIFIED IDEOGRAPH
+0xC9D2 0x68A2 #CJK UNIFIED IDEOGRAPH
+0xC9D3 0x634E #CJK UNIFIED IDEOGRAPH
+0xC9D4 0x7A0D #CJK UNIFIED IDEOGRAPH
+0xC9D5 0x70E7 #CJK UNIFIED IDEOGRAPH
+0xC9D6 0x828D #CJK UNIFIED IDEOGRAPH
+0xC9D7 0x52FA #CJK UNIFIED IDEOGRAPH
+0xC9D8 0x97F6 #CJK UNIFIED IDEOGRAPH
+0xC9D9 0x5C11 #CJK UNIFIED IDEOGRAPH
+0xC9DA 0x54E8 #CJK UNIFIED IDEOGRAPH
+0xC9DB 0x90B5 #CJK UNIFIED IDEOGRAPH
+0xC9DC 0x7ECD #CJK UNIFIED IDEOGRAPH
+0xC9DD 0x5962 #CJK UNIFIED IDEOGRAPH
+0xC9DE 0x8D4A #CJK UNIFIED IDEOGRAPH
+0xC9DF 0x86C7 #CJK UNIFIED IDEOGRAPH
+0xC9E0 0x820C #CJK UNIFIED IDEOGRAPH
+0xC9E1 0x820D #CJK UNIFIED IDEOGRAPH
+0xC9E2 0x8D66 #CJK UNIFIED IDEOGRAPH
+0xC9E3 0x6444 #CJK UNIFIED IDEOGRAPH
+0xC9E4 0x5C04 #CJK UNIFIED IDEOGRAPH
+0xC9E5 0x6151 #CJK UNIFIED IDEOGRAPH
+0xC9E6 0x6D89 #CJK UNIFIED IDEOGRAPH
+0xC9E7 0x793E #CJK UNIFIED IDEOGRAPH
+0xC9E8 0x8BBE #CJK UNIFIED IDEOGRAPH
+0xC9E9 0x7837 #CJK UNIFIED IDEOGRAPH
+0xC9EA 0x7533 #CJK UNIFIED IDEOGRAPH
+0xC9EB 0x547B #CJK UNIFIED IDEOGRAPH
+0xC9EC 0x4F38 #CJK UNIFIED IDEOGRAPH
+0xC9ED 0x8EAB #CJK UNIFIED IDEOGRAPH
+0xC9EE 0x6DF1 #CJK UNIFIED IDEOGRAPH
+0xC9EF 0x5A20 #CJK UNIFIED IDEOGRAPH
+0xC9F0 0x7EC5 #CJK UNIFIED IDEOGRAPH
+0xC9F1 0x795E #CJK UNIFIED IDEOGRAPH
+0xC9F2 0x6C88 #CJK UNIFIED IDEOGRAPH
+0xC9F3 0x5BA1 #CJK UNIFIED IDEOGRAPH
+0xC9F4 0x5A76 #CJK UNIFIED IDEOGRAPH
+0xC9F5 0x751A #CJK UNIFIED IDEOGRAPH
+0xC9F6 0x80BE #CJK UNIFIED IDEOGRAPH
+0xC9F7 0x614E #CJK UNIFIED IDEOGRAPH
+0xC9F8 0x6E17 #CJK UNIFIED IDEOGRAPH
+0xC9F9 0x58F0 #CJK UNIFIED IDEOGRAPH
+0xC9FA 0x751F #CJK UNIFIED IDEOGRAPH
+0xC9FB 0x7525 #CJK UNIFIED IDEOGRAPH
+0xC9FC 0x7272 #CJK UNIFIED IDEOGRAPH
+0xC9FD 0x5347 #CJK UNIFIED IDEOGRAPH
+0xC9FE 0x7EF3 #CJK UNIFIED IDEOGRAPH
+0xCA40 0x8503 #CJK UNIFIED IDEOGRAPH
+0xCA41 0x8504 #CJK UNIFIED IDEOGRAPH
+0xCA42 0x8505 #CJK UNIFIED IDEOGRAPH
+0xCA43 0x8506 #CJK UNIFIED IDEOGRAPH
+0xCA44 0x8507 #CJK UNIFIED IDEOGRAPH
+0xCA45 0x8508 #CJK UNIFIED IDEOGRAPH
+0xCA46 0x8509 #CJK UNIFIED IDEOGRAPH
+0xCA47 0x850A #CJK UNIFIED IDEOGRAPH
+0xCA48 0x850B #CJK UNIFIED IDEOGRAPH
+0xCA49 0x850D #CJK UNIFIED IDEOGRAPH
+0xCA4A 0x850E #CJK UNIFIED IDEOGRAPH
+0xCA4B 0x850F #CJK UNIFIED IDEOGRAPH
+0xCA4C 0x8510 #CJK UNIFIED IDEOGRAPH
+0xCA4D 0x8512 #CJK UNIFIED IDEOGRAPH
+0xCA4E 0x8514 #CJK UNIFIED IDEOGRAPH
+0xCA4F 0x8515 #CJK UNIFIED IDEOGRAPH
+0xCA50 0x8516 #CJK UNIFIED IDEOGRAPH
+0xCA51 0x8518 #CJK UNIFIED IDEOGRAPH
+0xCA52 0x8519 #CJK UNIFIED IDEOGRAPH
+0xCA53 0x851B #CJK UNIFIED IDEOGRAPH
+0xCA54 0x851C #CJK UNIFIED IDEOGRAPH
+0xCA55 0x851D #CJK UNIFIED IDEOGRAPH
+0xCA56 0x851E #CJK UNIFIED IDEOGRAPH
+0xCA57 0x8520 #CJK UNIFIED IDEOGRAPH
+0xCA58 0x8522 #CJK UNIFIED IDEOGRAPH
+0xCA59 0x8523 #CJK UNIFIED IDEOGRAPH
+0xCA5A 0x8524 #CJK UNIFIED IDEOGRAPH
+0xCA5B 0x8525 #CJK UNIFIED IDEOGRAPH
+0xCA5C 0x8526 #CJK UNIFIED IDEOGRAPH
+0xCA5D 0x8527 #CJK UNIFIED IDEOGRAPH
+0xCA5E 0x8528 #CJK UNIFIED IDEOGRAPH
+0xCA5F 0x8529 #CJK UNIFIED IDEOGRAPH
+0xCA60 0x852A #CJK UNIFIED IDEOGRAPH
+0xCA61 0x852D #CJK UNIFIED IDEOGRAPH
+0xCA62 0x852E #CJK UNIFIED IDEOGRAPH
+0xCA63 0x852F #CJK UNIFIED IDEOGRAPH
+0xCA64 0x8530 #CJK UNIFIED IDEOGRAPH
+0xCA65 0x8531 #CJK UNIFIED IDEOGRAPH
+0xCA66 0x8532 #CJK UNIFIED IDEOGRAPH
+0xCA67 0x8533 #CJK UNIFIED IDEOGRAPH
+0xCA68 0x8534 #CJK UNIFIED IDEOGRAPH
+0xCA69 0x8535 #CJK UNIFIED IDEOGRAPH
+0xCA6A 0x8536 #CJK UNIFIED IDEOGRAPH
+0xCA6B 0x853E #CJK UNIFIED IDEOGRAPH
+0xCA6C 0x853F #CJK UNIFIED IDEOGRAPH
+0xCA6D 0x8540 #CJK UNIFIED IDEOGRAPH
+0xCA6E 0x8541 #CJK UNIFIED IDEOGRAPH
+0xCA6F 0x8542 #CJK UNIFIED IDEOGRAPH
+0xCA70 0x8544 #CJK UNIFIED IDEOGRAPH
+0xCA71 0x8545 #CJK UNIFIED IDEOGRAPH
+0xCA72 0x8546 #CJK UNIFIED IDEOGRAPH
+0xCA73 0x8547 #CJK UNIFIED IDEOGRAPH
+0xCA74 0x854B #CJK UNIFIED IDEOGRAPH
+0xCA75 0x854C #CJK UNIFIED IDEOGRAPH
+0xCA76 0x854D #CJK UNIFIED IDEOGRAPH
+0xCA77 0x854E #CJK UNIFIED IDEOGRAPH
+0xCA78 0x854F #CJK UNIFIED IDEOGRAPH
+0xCA79 0x8550 #CJK UNIFIED IDEOGRAPH
+0xCA7A 0x8551 #CJK UNIFIED IDEOGRAPH
+0xCA7B 0x8552 #CJK UNIFIED IDEOGRAPH
+0xCA7C 0x8553 #CJK UNIFIED IDEOGRAPH
+0xCA7D 0x8554 #CJK UNIFIED IDEOGRAPH
+0xCA7E 0x8555 #CJK UNIFIED IDEOGRAPH
+0xCA80 0x8557 #CJK UNIFIED IDEOGRAPH
+0xCA81 0x8558 #CJK UNIFIED IDEOGRAPH
+0xCA82 0x855A #CJK UNIFIED IDEOGRAPH
+0xCA83 0x855B #CJK UNIFIED IDEOGRAPH
+0xCA84 0x855C #CJK UNIFIED IDEOGRAPH
+0xCA85 0x855D #CJK UNIFIED IDEOGRAPH
+0xCA86 0x855F #CJK UNIFIED IDEOGRAPH
+0xCA87 0x8560 #CJK UNIFIED IDEOGRAPH
+0xCA88 0x8561 #CJK UNIFIED IDEOGRAPH
+0xCA89 0x8562 #CJK UNIFIED IDEOGRAPH
+0xCA8A 0x8563 #CJK UNIFIED IDEOGRAPH
+0xCA8B 0x8565 #CJK UNIFIED IDEOGRAPH
+0xCA8C 0x8566 #CJK UNIFIED IDEOGRAPH
+0xCA8D 0x8567 #CJK UNIFIED IDEOGRAPH
+0xCA8E 0x8569 #CJK UNIFIED IDEOGRAPH
+0xCA8F 0x856A #CJK UNIFIED IDEOGRAPH
+0xCA90 0x856B #CJK UNIFIED IDEOGRAPH
+0xCA91 0x856C #CJK UNIFIED IDEOGRAPH
+0xCA92 0x856D #CJK UNIFIED IDEOGRAPH
+0xCA93 0x856E #CJK UNIFIED IDEOGRAPH
+0xCA94 0x856F #CJK UNIFIED IDEOGRAPH
+0xCA95 0x8570 #CJK UNIFIED IDEOGRAPH
+0xCA96 0x8571 #CJK UNIFIED IDEOGRAPH
+0xCA97 0x8573 #CJK UNIFIED IDEOGRAPH
+0xCA98 0x8575 #CJK UNIFIED IDEOGRAPH
+0xCA99 0x8576 #CJK UNIFIED IDEOGRAPH
+0xCA9A 0x8577 #CJK UNIFIED IDEOGRAPH
+0xCA9B 0x8578 #CJK UNIFIED IDEOGRAPH
+0xCA9C 0x857C #CJK UNIFIED IDEOGRAPH
+0xCA9D 0x857D #CJK UNIFIED IDEOGRAPH
+0xCA9E 0x857F #CJK UNIFIED IDEOGRAPH
+0xCA9F 0x8580 #CJK UNIFIED IDEOGRAPH
+0xCAA0 0x8581 #CJK UNIFIED IDEOGRAPH
+0xCAA1 0x7701 #CJK UNIFIED IDEOGRAPH
+0xCAA2 0x76DB #CJK UNIFIED IDEOGRAPH
+0xCAA3 0x5269 #CJK UNIFIED IDEOGRAPH
+0xCAA4 0x80DC #CJK UNIFIED IDEOGRAPH
+0xCAA5 0x5723 #CJK UNIFIED IDEOGRAPH
+0xCAA6 0x5E08 #CJK UNIFIED IDEOGRAPH
+0xCAA7 0x5931 #CJK UNIFIED IDEOGRAPH
+0xCAA8 0x72EE #CJK UNIFIED IDEOGRAPH
+0xCAA9 0x65BD #CJK UNIFIED IDEOGRAPH
+0xCAAA 0x6E7F #CJK UNIFIED IDEOGRAPH
+0xCAAB 0x8BD7 #CJK UNIFIED IDEOGRAPH
+0xCAAC 0x5C38 #CJK UNIFIED IDEOGRAPH
+0xCAAD 0x8671 #CJK UNIFIED IDEOGRAPH
+0xCAAE 0x5341 #CJK UNIFIED IDEOGRAPH
+0xCAAF 0x77F3 #CJK UNIFIED IDEOGRAPH
+0xCAB0 0x62FE #CJK UNIFIED IDEOGRAPH
+0xCAB1 0x65F6 #CJK UNIFIED IDEOGRAPH
+0xCAB2 0x4EC0 #CJK UNIFIED IDEOGRAPH
+0xCAB3 0x98DF #CJK UNIFIED IDEOGRAPH
+0xCAB4 0x8680 #CJK UNIFIED IDEOGRAPH
+0xCAB5 0x5B9E #CJK UNIFIED IDEOGRAPH
+0xCAB6 0x8BC6 #CJK UNIFIED IDEOGRAPH
+0xCAB7 0x53F2 #CJK UNIFIED IDEOGRAPH
+0xCAB8 0x77E2 #CJK UNIFIED IDEOGRAPH
+0xCAB9 0x4F7F #CJK UNIFIED IDEOGRAPH
+0xCABA 0x5C4E #CJK UNIFIED IDEOGRAPH
+0xCABB 0x9A76 #CJK UNIFIED IDEOGRAPH
+0xCABC 0x59CB #CJK UNIFIED IDEOGRAPH
+0xCABD 0x5F0F #CJK UNIFIED IDEOGRAPH
+0xCABE 0x793A #CJK UNIFIED IDEOGRAPH
+0xCABF 0x58EB #CJK UNIFIED IDEOGRAPH
+0xCAC0 0x4E16 #CJK UNIFIED IDEOGRAPH
+0xCAC1 0x67FF #CJK UNIFIED IDEOGRAPH
+0xCAC2 0x4E8B #CJK UNIFIED IDEOGRAPH
+0xCAC3 0x62ED #CJK UNIFIED IDEOGRAPH
+0xCAC4 0x8A93 #CJK UNIFIED IDEOGRAPH
+0xCAC5 0x901D #CJK UNIFIED IDEOGRAPH
+0xCAC6 0x52BF #CJK UNIFIED IDEOGRAPH
+0xCAC7 0x662F #CJK UNIFIED IDEOGRAPH
+0xCAC8 0x55DC #CJK UNIFIED IDEOGRAPH
+0xCAC9 0x566C #CJK UNIFIED IDEOGRAPH
+0xCACA 0x9002 #CJK UNIFIED IDEOGRAPH
+0xCACB 0x4ED5 #CJK UNIFIED IDEOGRAPH
+0xCACC 0x4F8D #CJK UNIFIED IDEOGRAPH
+0xCACD 0x91CA #CJK UNIFIED IDEOGRAPH
+0xCACE 0x9970 #CJK UNIFIED IDEOGRAPH
+0xCACF 0x6C0F #CJK UNIFIED IDEOGRAPH
+0xCAD0 0x5E02 #CJK UNIFIED IDEOGRAPH
+0xCAD1 0x6043 #CJK UNIFIED IDEOGRAPH
+0xCAD2 0x5BA4 #CJK UNIFIED IDEOGRAPH
+0xCAD3 0x89C6 #CJK UNIFIED IDEOGRAPH
+0xCAD4 0x8BD5 #CJK UNIFIED IDEOGRAPH
+0xCAD5 0x6536 #CJK UNIFIED IDEOGRAPH
+0xCAD6 0x624B #CJK UNIFIED IDEOGRAPH
+0xCAD7 0x9996 #CJK UNIFIED IDEOGRAPH
+0xCAD8 0x5B88 #CJK UNIFIED IDEOGRAPH
+0xCAD9 0x5BFF #CJK UNIFIED IDEOGRAPH
+0xCADA 0x6388 #CJK UNIFIED IDEOGRAPH
+0xCADB 0x552E #CJK UNIFIED IDEOGRAPH
+0xCADC 0x53D7 #CJK UNIFIED IDEOGRAPH
+0xCADD 0x7626 #CJK UNIFIED IDEOGRAPH
+0xCADE 0x517D #CJK UNIFIED IDEOGRAPH
+0xCADF 0x852C #CJK UNIFIED IDEOGRAPH
+0xCAE0 0x67A2 #CJK UNIFIED IDEOGRAPH
+0xCAE1 0x68B3 #CJK UNIFIED IDEOGRAPH
+0xCAE2 0x6B8A #CJK UNIFIED IDEOGRAPH
+0xCAE3 0x6292 #CJK UNIFIED IDEOGRAPH
+0xCAE4 0x8F93 #CJK UNIFIED IDEOGRAPH
+0xCAE5 0x53D4 #CJK UNIFIED IDEOGRAPH
+0xCAE6 0x8212 #CJK UNIFIED IDEOGRAPH
+0xCAE7 0x6DD1 #CJK UNIFIED IDEOGRAPH
+0xCAE8 0x758F #CJK UNIFIED IDEOGRAPH
+0xCAE9 0x4E66 #CJK UNIFIED IDEOGRAPH
+0xCAEA 0x8D4E #CJK UNIFIED IDEOGRAPH
+0xCAEB 0x5B70 #CJK UNIFIED IDEOGRAPH
+0xCAEC 0x719F #CJK UNIFIED IDEOGRAPH
+0xCAED 0x85AF #CJK UNIFIED IDEOGRAPH
+0xCAEE 0x6691 #CJK UNIFIED IDEOGRAPH
+0xCAEF 0x66D9 #CJK UNIFIED IDEOGRAPH
+0xCAF0 0x7F72 #CJK UNIFIED IDEOGRAPH
+0xCAF1 0x8700 #CJK UNIFIED IDEOGRAPH
+0xCAF2 0x9ECD #CJK UNIFIED IDEOGRAPH
+0xCAF3 0x9F20 #CJK UNIFIED IDEOGRAPH
+0xCAF4 0x5C5E #CJK UNIFIED IDEOGRAPH
+0xCAF5 0x672F #CJK UNIFIED IDEOGRAPH
+0xCAF6 0x8FF0 #CJK UNIFIED IDEOGRAPH
+0xCAF7 0x6811 #CJK UNIFIED IDEOGRAPH
+0xCAF8 0x675F #CJK UNIFIED IDEOGRAPH
+0xCAF9 0x620D #CJK UNIFIED IDEOGRAPH
+0xCAFA 0x7AD6 #CJK UNIFIED IDEOGRAPH
+0xCAFB 0x5885 #CJK UNIFIED IDEOGRAPH
+0xCAFC 0x5EB6 #CJK UNIFIED IDEOGRAPH
+0xCAFD 0x6570 #CJK UNIFIED IDEOGRAPH
+0xCAFE 0x6F31 #CJK UNIFIED IDEOGRAPH
+0xCB40 0x8582 #CJK UNIFIED IDEOGRAPH
+0xCB41 0x8583 #CJK UNIFIED IDEOGRAPH
+0xCB42 0x8586 #CJK UNIFIED IDEOGRAPH
+0xCB43 0x8588 #CJK UNIFIED IDEOGRAPH
+0xCB44 0x8589 #CJK UNIFIED IDEOGRAPH
+0xCB45 0x858A #CJK UNIFIED IDEOGRAPH
+0xCB46 0x858B #CJK UNIFIED IDEOGRAPH
+0xCB47 0x858C #CJK UNIFIED IDEOGRAPH
+0xCB48 0x858D #CJK UNIFIED IDEOGRAPH
+0xCB49 0x858E #CJK UNIFIED IDEOGRAPH
+0xCB4A 0x8590 #CJK UNIFIED IDEOGRAPH
+0xCB4B 0x8591 #CJK UNIFIED IDEOGRAPH
+0xCB4C 0x8592 #CJK UNIFIED IDEOGRAPH
+0xCB4D 0x8593 #CJK UNIFIED IDEOGRAPH
+0xCB4E 0x8594 #CJK UNIFIED IDEOGRAPH
+0xCB4F 0x8595 #CJK UNIFIED IDEOGRAPH
+0xCB50 0x8596 #CJK UNIFIED IDEOGRAPH
+0xCB51 0x8597 #CJK UNIFIED IDEOGRAPH
+0xCB52 0x8598 #CJK UNIFIED IDEOGRAPH
+0xCB53 0x8599 #CJK UNIFIED IDEOGRAPH
+0xCB54 0x859A #CJK UNIFIED IDEOGRAPH
+0xCB55 0x859D #CJK UNIFIED IDEOGRAPH
+0xCB56 0x859E #CJK UNIFIED IDEOGRAPH
+0xCB57 0x859F #CJK UNIFIED IDEOGRAPH
+0xCB58 0x85A0 #CJK UNIFIED IDEOGRAPH
+0xCB59 0x85A1 #CJK UNIFIED IDEOGRAPH
+0xCB5A 0x85A2 #CJK UNIFIED IDEOGRAPH
+0xCB5B 0x85A3 #CJK UNIFIED IDEOGRAPH
+0xCB5C 0x85A5 #CJK UNIFIED IDEOGRAPH
+0xCB5D 0x85A6 #CJK UNIFIED IDEOGRAPH
+0xCB5E 0x85A7 #CJK UNIFIED IDEOGRAPH
+0xCB5F 0x85A9 #CJK UNIFIED IDEOGRAPH
+0xCB60 0x85AB #CJK UNIFIED IDEOGRAPH
+0xCB61 0x85AC #CJK UNIFIED IDEOGRAPH
+0xCB62 0x85AD #CJK UNIFIED IDEOGRAPH
+0xCB63 0x85B1 #CJK UNIFIED IDEOGRAPH
+0xCB64 0x85B2 #CJK UNIFIED IDEOGRAPH
+0xCB65 0x85B3 #CJK UNIFIED IDEOGRAPH
+0xCB66 0x85B4 #CJK UNIFIED IDEOGRAPH
+0xCB67 0x85B5 #CJK UNIFIED IDEOGRAPH
+0xCB68 0x85B6 #CJK UNIFIED IDEOGRAPH
+0xCB69 0x85B8 #CJK UNIFIED IDEOGRAPH
+0xCB6A 0x85BA #CJK UNIFIED IDEOGRAPH
+0xCB6B 0x85BB #CJK UNIFIED IDEOGRAPH
+0xCB6C 0x85BC #CJK UNIFIED IDEOGRAPH
+0xCB6D 0x85BD #CJK UNIFIED IDEOGRAPH
+0xCB6E 0x85BE #CJK UNIFIED IDEOGRAPH
+0xCB6F 0x85BF #CJK UNIFIED IDEOGRAPH
+0xCB70 0x85C0 #CJK UNIFIED IDEOGRAPH
+0xCB71 0x85C2 #CJK UNIFIED IDEOGRAPH
+0xCB72 0x85C3 #CJK UNIFIED IDEOGRAPH
+0xCB73 0x85C4 #CJK UNIFIED IDEOGRAPH
+0xCB74 0x85C5 #CJK UNIFIED IDEOGRAPH
+0xCB75 0x85C6 #CJK UNIFIED IDEOGRAPH
+0xCB76 0x85C7 #CJK UNIFIED IDEOGRAPH
+0xCB77 0x85C8 #CJK UNIFIED IDEOGRAPH
+0xCB78 0x85CA #CJK UNIFIED IDEOGRAPH
+0xCB79 0x85CB #CJK UNIFIED IDEOGRAPH
+0xCB7A 0x85CC #CJK UNIFIED IDEOGRAPH
+0xCB7B 0x85CD #CJK UNIFIED IDEOGRAPH
+0xCB7C 0x85CE #CJK UNIFIED IDEOGRAPH
+0xCB7D 0x85D1 #CJK UNIFIED IDEOGRAPH
+0xCB7E 0x85D2 #CJK UNIFIED IDEOGRAPH
+0xCB80 0x85D4 #CJK UNIFIED IDEOGRAPH
+0xCB81 0x85D6 #CJK UNIFIED IDEOGRAPH
+0xCB82 0x85D7 #CJK UNIFIED IDEOGRAPH
+0xCB83 0x85D8 #CJK UNIFIED IDEOGRAPH
+0xCB84 0x85D9 #CJK UNIFIED IDEOGRAPH
+0xCB85 0x85DA #CJK UNIFIED IDEOGRAPH
+0xCB86 0x85DB #CJK UNIFIED IDEOGRAPH
+0xCB87 0x85DD #CJK UNIFIED IDEOGRAPH
+0xCB88 0x85DE #CJK UNIFIED IDEOGRAPH
+0xCB89 0x85DF #CJK UNIFIED IDEOGRAPH
+0xCB8A 0x85E0 #CJK UNIFIED IDEOGRAPH
+0xCB8B 0x85E1 #CJK UNIFIED IDEOGRAPH
+0xCB8C 0x85E2 #CJK UNIFIED IDEOGRAPH
+0xCB8D 0x85E3 #CJK UNIFIED IDEOGRAPH
+0xCB8E 0x85E5 #CJK UNIFIED IDEOGRAPH
+0xCB8F 0x85E6 #CJK UNIFIED IDEOGRAPH
+0xCB90 0x85E7 #CJK UNIFIED IDEOGRAPH
+0xCB91 0x85E8 #CJK UNIFIED IDEOGRAPH
+0xCB92 0x85EA #CJK UNIFIED IDEOGRAPH
+0xCB93 0x85EB #CJK UNIFIED IDEOGRAPH
+0xCB94 0x85EC #CJK UNIFIED IDEOGRAPH
+0xCB95 0x85ED #CJK UNIFIED IDEOGRAPH
+0xCB96 0x85EE #CJK UNIFIED IDEOGRAPH
+0xCB97 0x85EF #CJK UNIFIED IDEOGRAPH
+0xCB98 0x85F0 #CJK UNIFIED IDEOGRAPH
+0xCB99 0x85F1 #CJK UNIFIED IDEOGRAPH
+0xCB9A 0x85F2 #CJK UNIFIED IDEOGRAPH
+0xCB9B 0x85F3 #CJK UNIFIED IDEOGRAPH
+0xCB9C 0x85F4 #CJK UNIFIED IDEOGRAPH
+0xCB9D 0x85F5 #CJK UNIFIED IDEOGRAPH
+0xCB9E 0x85F6 #CJK UNIFIED IDEOGRAPH
+0xCB9F 0x85F7 #CJK UNIFIED IDEOGRAPH
+0xCBA0 0x85F8 #CJK UNIFIED IDEOGRAPH
+0xCBA1 0x6055 #CJK UNIFIED IDEOGRAPH
+0xCBA2 0x5237 #CJK UNIFIED IDEOGRAPH
+0xCBA3 0x800D #CJK UNIFIED IDEOGRAPH
+0xCBA4 0x6454 #CJK UNIFIED IDEOGRAPH
+0xCBA5 0x8870 #CJK UNIFIED IDEOGRAPH
+0xCBA6 0x7529 #CJK UNIFIED IDEOGRAPH
+0xCBA7 0x5E05 #CJK UNIFIED IDEOGRAPH
+0xCBA8 0x6813 #CJK UNIFIED IDEOGRAPH
+0xCBA9 0x62F4 #CJK UNIFIED IDEOGRAPH
+0xCBAA 0x971C #CJK UNIFIED IDEOGRAPH
+0xCBAB 0x53CC #CJK UNIFIED IDEOGRAPH
+0xCBAC 0x723D #CJK UNIFIED IDEOGRAPH
+0xCBAD 0x8C01 #CJK UNIFIED IDEOGRAPH
+0xCBAE 0x6C34 #CJK UNIFIED IDEOGRAPH
+0xCBAF 0x7761 #CJK UNIFIED IDEOGRAPH
+0xCBB0 0x7A0E #CJK UNIFIED IDEOGRAPH
+0xCBB1 0x542E #CJK UNIFIED IDEOGRAPH
+0xCBB2 0x77AC #CJK UNIFIED IDEOGRAPH
+0xCBB3 0x987A #CJK UNIFIED IDEOGRAPH
+0xCBB4 0x821C #CJK UNIFIED IDEOGRAPH
+0xCBB5 0x8BF4 #CJK UNIFIED IDEOGRAPH
+0xCBB6 0x7855 #CJK UNIFIED IDEOGRAPH
+0xCBB7 0x6714 #CJK UNIFIED IDEOGRAPH
+0xCBB8 0x70C1 #CJK UNIFIED IDEOGRAPH
+0xCBB9 0x65AF #CJK UNIFIED IDEOGRAPH
+0xCBBA 0x6495 #CJK UNIFIED IDEOGRAPH
+0xCBBB 0x5636 #CJK UNIFIED IDEOGRAPH
+0xCBBC 0x601D #CJK UNIFIED IDEOGRAPH
+0xCBBD 0x79C1 #CJK UNIFIED IDEOGRAPH
+0xCBBE 0x53F8 #CJK UNIFIED IDEOGRAPH
+0xCBBF 0x4E1D #CJK UNIFIED IDEOGRAPH
+0xCBC0 0x6B7B #CJK UNIFIED IDEOGRAPH
+0xCBC1 0x8086 #CJK UNIFIED IDEOGRAPH
+0xCBC2 0x5BFA #CJK UNIFIED IDEOGRAPH
+0xCBC3 0x55E3 #CJK UNIFIED IDEOGRAPH
+0xCBC4 0x56DB #CJK UNIFIED IDEOGRAPH
+0xCBC5 0x4F3A #CJK UNIFIED IDEOGRAPH
+0xCBC6 0x4F3C #CJK UNIFIED IDEOGRAPH
+0xCBC7 0x9972 #CJK UNIFIED IDEOGRAPH
+0xCBC8 0x5DF3 #CJK UNIFIED IDEOGRAPH
+0xCBC9 0x677E #CJK UNIFIED IDEOGRAPH
+0xCBCA 0x8038 #CJK UNIFIED IDEOGRAPH
+0xCBCB 0x6002 #CJK UNIFIED IDEOGRAPH
+0xCBCC 0x9882 #CJK UNIFIED IDEOGRAPH
+0xCBCD 0x9001 #CJK UNIFIED IDEOGRAPH
+0xCBCE 0x5B8B #CJK UNIFIED IDEOGRAPH
+0xCBCF 0x8BBC #CJK UNIFIED IDEOGRAPH
+0xCBD0 0x8BF5 #CJK UNIFIED IDEOGRAPH
+0xCBD1 0x641C #CJK UNIFIED IDEOGRAPH
+0xCBD2 0x8258 #CJK UNIFIED IDEOGRAPH
+0xCBD3 0x64DE #CJK UNIFIED IDEOGRAPH
+0xCBD4 0x55FD #CJK UNIFIED IDEOGRAPH
+0xCBD5 0x82CF #CJK UNIFIED IDEOGRAPH
+0xCBD6 0x9165 #CJK UNIFIED IDEOGRAPH
+0xCBD7 0x4FD7 #CJK UNIFIED IDEOGRAPH
+0xCBD8 0x7D20 #CJK UNIFIED IDEOGRAPH
+0xCBD9 0x901F #CJK UNIFIED IDEOGRAPH
+0xCBDA 0x7C9F #CJK UNIFIED IDEOGRAPH
+0xCBDB 0x50F3 #CJK UNIFIED IDEOGRAPH
+0xCBDC 0x5851 #CJK UNIFIED IDEOGRAPH
+0xCBDD 0x6EAF #CJK UNIFIED IDEOGRAPH
+0xCBDE 0x5BBF #CJK UNIFIED IDEOGRAPH
+0xCBDF 0x8BC9 #CJK UNIFIED IDEOGRAPH
+0xCBE0 0x8083 #CJK UNIFIED IDEOGRAPH
+0xCBE1 0x9178 #CJK UNIFIED IDEOGRAPH
+0xCBE2 0x849C #CJK UNIFIED IDEOGRAPH
+0xCBE3 0x7B97 #CJK UNIFIED IDEOGRAPH
+0xCBE4 0x867D #CJK UNIFIED IDEOGRAPH
+0xCBE5 0x968B #CJK UNIFIED IDEOGRAPH
+0xCBE6 0x968F #CJK UNIFIED IDEOGRAPH
+0xCBE7 0x7EE5 #CJK UNIFIED IDEOGRAPH
+0xCBE8 0x9AD3 #CJK UNIFIED IDEOGRAPH
+0xCBE9 0x788E #CJK UNIFIED IDEOGRAPH
+0xCBEA 0x5C81 #CJK UNIFIED IDEOGRAPH
+0xCBEB 0x7A57 #CJK UNIFIED IDEOGRAPH
+0xCBEC 0x9042 #CJK UNIFIED IDEOGRAPH
+0xCBED 0x96A7 #CJK UNIFIED IDEOGRAPH
+0xCBEE 0x795F #CJK UNIFIED IDEOGRAPH
+0xCBEF 0x5B59 #CJK UNIFIED IDEOGRAPH
+0xCBF0 0x635F #CJK UNIFIED IDEOGRAPH
+0xCBF1 0x7B0B #CJK UNIFIED IDEOGRAPH
+0xCBF2 0x84D1 #CJK UNIFIED IDEOGRAPH
+0xCBF3 0x68AD #CJK UNIFIED IDEOGRAPH
+0xCBF4 0x5506 #CJK UNIFIED IDEOGRAPH
+0xCBF5 0x7F29 #CJK UNIFIED IDEOGRAPH
+0xCBF6 0x7410 #CJK UNIFIED IDEOGRAPH
+0xCBF7 0x7D22 #CJK UNIFIED IDEOGRAPH
+0xCBF8 0x9501 #CJK UNIFIED IDEOGRAPH
+0xCBF9 0x6240 #CJK UNIFIED IDEOGRAPH
+0xCBFA 0x584C #CJK UNIFIED IDEOGRAPH
+0xCBFB 0x4ED6 #CJK UNIFIED IDEOGRAPH
+0xCBFC 0x5B83 #CJK UNIFIED IDEOGRAPH
+0xCBFD 0x5979 #CJK UNIFIED IDEOGRAPH
+0xCBFE 0x5854 #CJK UNIFIED IDEOGRAPH
+0xCC40 0x85F9 #CJK UNIFIED IDEOGRAPH
+0xCC41 0x85FA #CJK UNIFIED IDEOGRAPH
+0xCC42 0x85FC #CJK UNIFIED IDEOGRAPH
+0xCC43 0x85FD #CJK UNIFIED IDEOGRAPH
+0xCC44 0x85FE #CJK UNIFIED IDEOGRAPH
+0xCC45 0x8600 #CJK UNIFIED IDEOGRAPH
+0xCC46 0x8601 #CJK UNIFIED IDEOGRAPH
+0xCC47 0x8602 #CJK UNIFIED IDEOGRAPH
+0xCC48 0x8603 #CJK UNIFIED IDEOGRAPH
+0xCC49 0x8604 #CJK UNIFIED IDEOGRAPH
+0xCC4A 0x8606 #CJK UNIFIED IDEOGRAPH
+0xCC4B 0x8607 #CJK UNIFIED IDEOGRAPH
+0xCC4C 0x8608 #CJK UNIFIED IDEOGRAPH
+0xCC4D 0x8609 #CJK UNIFIED IDEOGRAPH
+0xCC4E 0x860A #CJK UNIFIED IDEOGRAPH
+0xCC4F 0x860B #CJK UNIFIED IDEOGRAPH
+0xCC50 0x860C #CJK UNIFIED IDEOGRAPH
+0xCC51 0x860D #CJK UNIFIED IDEOGRAPH
+0xCC52 0x860E #CJK UNIFIED IDEOGRAPH
+0xCC53 0x860F #CJK UNIFIED IDEOGRAPH
+0xCC54 0x8610 #CJK UNIFIED IDEOGRAPH
+0xCC55 0x8612 #CJK UNIFIED IDEOGRAPH
+0xCC56 0x8613 #CJK UNIFIED IDEOGRAPH
+0xCC57 0x8614 #CJK UNIFIED IDEOGRAPH
+0xCC58 0x8615 #CJK UNIFIED IDEOGRAPH
+0xCC59 0x8617 #CJK UNIFIED IDEOGRAPH
+0xCC5A 0x8618 #CJK UNIFIED IDEOGRAPH
+0xCC5B 0x8619 #CJK UNIFIED IDEOGRAPH
+0xCC5C 0x861A #CJK UNIFIED IDEOGRAPH
+0xCC5D 0x861B #CJK UNIFIED IDEOGRAPH
+0xCC5E 0x861C #CJK UNIFIED IDEOGRAPH
+0xCC5F 0x861D #CJK UNIFIED IDEOGRAPH
+0xCC60 0x861E #CJK UNIFIED IDEOGRAPH
+0xCC61 0x861F #CJK UNIFIED IDEOGRAPH
+0xCC62 0x8620 #CJK UNIFIED IDEOGRAPH
+0xCC63 0x8621 #CJK UNIFIED IDEOGRAPH
+0xCC64 0x8622 #CJK UNIFIED IDEOGRAPH
+0xCC65 0x8623 #CJK UNIFIED IDEOGRAPH
+0xCC66 0x8624 #CJK UNIFIED IDEOGRAPH
+0xCC67 0x8625 #CJK UNIFIED IDEOGRAPH
+0xCC68 0x8626 #CJK UNIFIED IDEOGRAPH
+0xCC69 0x8628 #CJK UNIFIED IDEOGRAPH
+0xCC6A 0x862A #CJK UNIFIED IDEOGRAPH
+0xCC6B 0x862B #CJK UNIFIED IDEOGRAPH
+0xCC6C 0x862C #CJK UNIFIED IDEOGRAPH
+0xCC6D 0x862D #CJK UNIFIED IDEOGRAPH
+0xCC6E 0x862E #CJK UNIFIED IDEOGRAPH
+0xCC6F 0x862F #CJK UNIFIED IDEOGRAPH
+0xCC70 0x8630 #CJK UNIFIED IDEOGRAPH
+0xCC71 0x8631 #CJK UNIFIED IDEOGRAPH
+0xCC72 0x8632 #CJK UNIFIED IDEOGRAPH
+0xCC73 0x8633 #CJK UNIFIED IDEOGRAPH
+0xCC74 0x8634 #CJK UNIFIED IDEOGRAPH
+0xCC75 0x8635 #CJK UNIFIED IDEOGRAPH
+0xCC76 0x8636 #CJK UNIFIED IDEOGRAPH
+0xCC77 0x8637 #CJK UNIFIED IDEOGRAPH
+0xCC78 0x8639 #CJK UNIFIED IDEOGRAPH
+0xCC79 0x863A #CJK UNIFIED IDEOGRAPH
+0xCC7A 0x863B #CJK UNIFIED IDEOGRAPH
+0xCC7B 0x863D #CJK UNIFIED IDEOGRAPH
+0xCC7C 0x863E #CJK UNIFIED IDEOGRAPH
+0xCC7D 0x863F #CJK UNIFIED IDEOGRAPH
+0xCC7E 0x8640 #CJK UNIFIED IDEOGRAPH
+0xCC80 0x8641 #CJK UNIFIED IDEOGRAPH
+0xCC81 0x8642 #CJK UNIFIED IDEOGRAPH
+0xCC82 0x8643 #CJK UNIFIED IDEOGRAPH
+0xCC83 0x8644 #CJK UNIFIED IDEOGRAPH
+0xCC84 0x8645 #CJK UNIFIED IDEOGRAPH
+0xCC85 0x8646 #CJK UNIFIED IDEOGRAPH
+0xCC86 0x8647 #CJK UNIFIED IDEOGRAPH
+0xCC87 0x8648 #CJK UNIFIED IDEOGRAPH
+0xCC88 0x8649 #CJK UNIFIED IDEOGRAPH
+0xCC89 0x864A #CJK UNIFIED IDEOGRAPH
+0xCC8A 0x864B #CJK UNIFIED IDEOGRAPH
+0xCC8B 0x864C #CJK UNIFIED IDEOGRAPH
+0xCC8C 0x8652 #CJK UNIFIED IDEOGRAPH
+0xCC8D 0x8653 #CJK UNIFIED IDEOGRAPH
+0xCC8E 0x8655 #CJK UNIFIED IDEOGRAPH
+0xCC8F 0x8656 #CJK UNIFIED IDEOGRAPH
+0xCC90 0x8657 #CJK UNIFIED IDEOGRAPH
+0xCC91 0x8658 #CJK UNIFIED IDEOGRAPH
+0xCC92 0x8659 #CJK UNIFIED IDEOGRAPH
+0xCC93 0x865B #CJK UNIFIED IDEOGRAPH
+0xCC94 0x865C #CJK UNIFIED IDEOGRAPH
+0xCC95 0x865D #CJK UNIFIED IDEOGRAPH
+0xCC96 0x865F #CJK UNIFIED IDEOGRAPH
+0xCC97 0x8660 #CJK UNIFIED IDEOGRAPH
+0xCC98 0x8661 #CJK UNIFIED IDEOGRAPH
+0xCC99 0x8663 #CJK UNIFIED IDEOGRAPH
+0xCC9A 0x8664 #CJK UNIFIED IDEOGRAPH
+0xCC9B 0x8665 #CJK UNIFIED IDEOGRAPH
+0xCC9C 0x8666 #CJK UNIFIED IDEOGRAPH
+0xCC9D 0x8667 #CJK UNIFIED IDEOGRAPH
+0xCC9E 0x8668 #CJK UNIFIED IDEOGRAPH
+0xCC9F 0x8669 #CJK UNIFIED IDEOGRAPH
+0xCCA0 0x866A #CJK UNIFIED IDEOGRAPH
+0xCCA1 0x736D #CJK UNIFIED IDEOGRAPH
+0xCCA2 0x631E #CJK UNIFIED IDEOGRAPH
+0xCCA3 0x8E4B #CJK UNIFIED IDEOGRAPH
+0xCCA4 0x8E0F #CJK UNIFIED IDEOGRAPH
+0xCCA5 0x80CE #CJK UNIFIED IDEOGRAPH
+0xCCA6 0x82D4 #CJK UNIFIED IDEOGRAPH
+0xCCA7 0x62AC #CJK UNIFIED IDEOGRAPH
+0xCCA8 0x53F0 #CJK UNIFIED IDEOGRAPH
+0xCCA9 0x6CF0 #CJK UNIFIED IDEOGRAPH
+0xCCAA 0x915E #CJK UNIFIED IDEOGRAPH
+0xCCAB 0x592A #CJK UNIFIED IDEOGRAPH
+0xCCAC 0x6001 #CJK UNIFIED IDEOGRAPH
+0xCCAD 0x6C70 #CJK UNIFIED IDEOGRAPH
+0xCCAE 0x574D #CJK UNIFIED IDEOGRAPH
+0xCCAF 0x644A #CJK UNIFIED IDEOGRAPH
+0xCCB0 0x8D2A #CJK UNIFIED IDEOGRAPH
+0xCCB1 0x762B #CJK UNIFIED IDEOGRAPH
+0xCCB2 0x6EE9 #CJK UNIFIED IDEOGRAPH
+0xCCB3 0x575B #CJK UNIFIED IDEOGRAPH
+0xCCB4 0x6A80 #CJK UNIFIED IDEOGRAPH
+0xCCB5 0x75F0 #CJK UNIFIED IDEOGRAPH
+0xCCB6 0x6F6D #CJK UNIFIED IDEOGRAPH
+0xCCB7 0x8C2D #CJK UNIFIED IDEOGRAPH
+0xCCB8 0x8C08 #CJK UNIFIED IDEOGRAPH
+0xCCB9 0x5766 #CJK UNIFIED IDEOGRAPH
+0xCCBA 0x6BEF #CJK UNIFIED IDEOGRAPH
+0xCCBB 0x8892 #CJK UNIFIED IDEOGRAPH
+0xCCBC 0x78B3 #CJK UNIFIED IDEOGRAPH
+0xCCBD 0x63A2 #CJK UNIFIED IDEOGRAPH
+0xCCBE 0x53F9 #CJK UNIFIED IDEOGRAPH
+0xCCBF 0x70AD #CJK UNIFIED IDEOGRAPH
+0xCCC0 0x6C64 #CJK UNIFIED IDEOGRAPH
+0xCCC1 0x5858 #CJK UNIFIED IDEOGRAPH
+0xCCC2 0x642A #CJK UNIFIED IDEOGRAPH
+0xCCC3 0x5802 #CJK UNIFIED IDEOGRAPH
+0xCCC4 0x68E0 #CJK UNIFIED IDEOGRAPH
+0xCCC5 0x819B #CJK UNIFIED IDEOGRAPH
+0xCCC6 0x5510 #CJK UNIFIED IDEOGRAPH
+0xCCC7 0x7CD6 #CJK UNIFIED IDEOGRAPH
+0xCCC8 0x5018 #CJK UNIFIED IDEOGRAPH
+0xCCC9 0x8EBA #CJK UNIFIED IDEOGRAPH
+0xCCCA 0x6DCC #CJK UNIFIED IDEOGRAPH
+0xCCCB 0x8D9F #CJK UNIFIED IDEOGRAPH
+0xCCCC 0x70EB #CJK UNIFIED IDEOGRAPH
+0xCCCD 0x638F #CJK UNIFIED IDEOGRAPH
+0xCCCE 0x6D9B #CJK UNIFIED IDEOGRAPH
+0xCCCF 0x6ED4 #CJK UNIFIED IDEOGRAPH
+0xCCD0 0x7EE6 #CJK UNIFIED IDEOGRAPH
+0xCCD1 0x8404 #CJK UNIFIED IDEOGRAPH
+0xCCD2 0x6843 #CJK UNIFIED IDEOGRAPH
+0xCCD3 0x9003 #CJK UNIFIED IDEOGRAPH
+0xCCD4 0x6DD8 #CJK UNIFIED IDEOGRAPH
+0xCCD5 0x9676 #CJK UNIFIED IDEOGRAPH
+0xCCD6 0x8BA8 #CJK UNIFIED IDEOGRAPH
+0xCCD7 0x5957 #CJK UNIFIED IDEOGRAPH
+0xCCD8 0x7279 #CJK UNIFIED IDEOGRAPH
+0xCCD9 0x85E4 #CJK UNIFIED IDEOGRAPH
+0xCCDA 0x817E #CJK UNIFIED IDEOGRAPH
+0xCCDB 0x75BC #CJK UNIFIED IDEOGRAPH
+0xCCDC 0x8A8A #CJK UNIFIED IDEOGRAPH
+0xCCDD 0x68AF #CJK UNIFIED IDEOGRAPH
+0xCCDE 0x5254 #CJK UNIFIED IDEOGRAPH
+0xCCDF 0x8E22 #CJK UNIFIED IDEOGRAPH
+0xCCE0 0x9511 #CJK UNIFIED IDEOGRAPH
+0xCCE1 0x63D0 #CJK UNIFIED IDEOGRAPH
+0xCCE2 0x9898 #CJK UNIFIED IDEOGRAPH
+0xCCE3 0x8E44 #CJK UNIFIED IDEOGRAPH
+0xCCE4 0x557C #CJK UNIFIED IDEOGRAPH
+0xCCE5 0x4F53 #CJK UNIFIED IDEOGRAPH
+0xCCE6 0x66FF #CJK UNIFIED IDEOGRAPH
+0xCCE7 0x568F #CJK UNIFIED IDEOGRAPH
+0xCCE8 0x60D5 #CJK UNIFIED IDEOGRAPH
+0xCCE9 0x6D95 #CJK UNIFIED IDEOGRAPH
+0xCCEA 0x5243 #CJK UNIFIED IDEOGRAPH
+0xCCEB 0x5C49 #CJK UNIFIED IDEOGRAPH
+0xCCEC 0x5929 #CJK UNIFIED IDEOGRAPH
+0xCCED 0x6DFB #CJK UNIFIED IDEOGRAPH
+0xCCEE 0x586B #CJK UNIFIED IDEOGRAPH
+0xCCEF 0x7530 #CJK UNIFIED IDEOGRAPH
+0xCCF0 0x751C #CJK UNIFIED IDEOGRAPH
+0xCCF1 0x606C #CJK UNIFIED IDEOGRAPH
+0xCCF2 0x8214 #CJK UNIFIED IDEOGRAPH
+0xCCF3 0x8146 #CJK UNIFIED IDEOGRAPH
+0xCCF4 0x6311 #CJK UNIFIED IDEOGRAPH
+0xCCF5 0x6761 #CJK UNIFIED IDEOGRAPH
+0xCCF6 0x8FE2 #CJK UNIFIED IDEOGRAPH
+0xCCF7 0x773A #CJK UNIFIED IDEOGRAPH
+0xCCF8 0x8DF3 #CJK UNIFIED IDEOGRAPH
+0xCCF9 0x8D34 #CJK UNIFIED IDEOGRAPH
+0xCCFA 0x94C1 #CJK UNIFIED IDEOGRAPH
+0xCCFB 0x5E16 #CJK UNIFIED IDEOGRAPH
+0xCCFC 0x5385 #CJK UNIFIED IDEOGRAPH
+0xCCFD 0x542C #CJK UNIFIED IDEOGRAPH
+0xCCFE 0x70C3 #CJK UNIFIED IDEOGRAPH
+0xCD40 0x866D #CJK UNIFIED IDEOGRAPH
+0xCD41 0x866F #CJK UNIFIED IDEOGRAPH
+0xCD42 0x8670 #CJK UNIFIED IDEOGRAPH
+0xCD43 0x8672 #CJK UNIFIED IDEOGRAPH
+0xCD44 0x8673 #CJK UNIFIED IDEOGRAPH
+0xCD45 0x8674 #CJK UNIFIED IDEOGRAPH
+0xCD46 0x8675 #CJK UNIFIED IDEOGRAPH
+0xCD47 0x8676 #CJK UNIFIED IDEOGRAPH
+0xCD48 0x8677 #CJK UNIFIED IDEOGRAPH
+0xCD49 0x8678 #CJK UNIFIED IDEOGRAPH
+0xCD4A 0x8683 #CJK UNIFIED IDEOGRAPH
+0xCD4B 0x8684 #CJK UNIFIED IDEOGRAPH
+0xCD4C 0x8685 #CJK UNIFIED IDEOGRAPH
+0xCD4D 0x8686 #CJK UNIFIED IDEOGRAPH
+0xCD4E 0x8687 #CJK UNIFIED IDEOGRAPH
+0xCD4F 0x8688 #CJK UNIFIED IDEOGRAPH
+0xCD50 0x8689 #CJK UNIFIED IDEOGRAPH
+0xCD51 0x868E #CJK UNIFIED IDEOGRAPH
+0xCD52 0x868F #CJK UNIFIED IDEOGRAPH
+0xCD53 0x8690 #CJK UNIFIED IDEOGRAPH
+0xCD54 0x8691 #CJK UNIFIED IDEOGRAPH
+0xCD55 0x8692 #CJK UNIFIED IDEOGRAPH
+0xCD56 0x8694 #CJK UNIFIED IDEOGRAPH
+0xCD57 0x8696 #CJK UNIFIED IDEOGRAPH
+0xCD58 0x8697 #CJK UNIFIED IDEOGRAPH
+0xCD59 0x8698 #CJK UNIFIED IDEOGRAPH
+0xCD5A 0x8699 #CJK UNIFIED IDEOGRAPH
+0xCD5B 0x869A #CJK UNIFIED IDEOGRAPH
+0xCD5C 0x869B #CJK UNIFIED IDEOGRAPH
+0xCD5D 0x869E #CJK UNIFIED IDEOGRAPH
+0xCD5E 0x869F #CJK UNIFIED IDEOGRAPH
+0xCD5F 0x86A0 #CJK UNIFIED IDEOGRAPH
+0xCD60 0x86A1 #CJK UNIFIED IDEOGRAPH
+0xCD61 0x86A2 #CJK UNIFIED IDEOGRAPH
+0xCD62 0x86A5 #CJK UNIFIED IDEOGRAPH
+0xCD63 0x86A6 #CJK UNIFIED IDEOGRAPH
+0xCD64 0x86AB #CJK UNIFIED IDEOGRAPH
+0xCD65 0x86AD #CJK UNIFIED IDEOGRAPH
+0xCD66 0x86AE #CJK UNIFIED IDEOGRAPH
+0xCD67 0x86B2 #CJK UNIFIED IDEOGRAPH
+0xCD68 0x86B3 #CJK UNIFIED IDEOGRAPH
+0xCD69 0x86B7 #CJK UNIFIED IDEOGRAPH
+0xCD6A 0x86B8 #CJK UNIFIED IDEOGRAPH
+0xCD6B 0x86B9 #CJK UNIFIED IDEOGRAPH
+0xCD6C 0x86BB #CJK UNIFIED IDEOGRAPH
+0xCD6D 0x86BC #CJK UNIFIED IDEOGRAPH
+0xCD6E 0x86BD #CJK UNIFIED IDEOGRAPH
+0xCD6F 0x86BE #CJK UNIFIED IDEOGRAPH
+0xCD70 0x86BF #CJK UNIFIED IDEOGRAPH
+0xCD71 0x86C1 #CJK UNIFIED IDEOGRAPH
+0xCD72 0x86C2 #CJK UNIFIED IDEOGRAPH
+0xCD73 0x86C3 #CJK UNIFIED IDEOGRAPH
+0xCD74 0x86C5 #CJK UNIFIED IDEOGRAPH
+0xCD75 0x86C8 #CJK UNIFIED IDEOGRAPH
+0xCD76 0x86CC #CJK UNIFIED IDEOGRAPH
+0xCD77 0x86CD #CJK UNIFIED IDEOGRAPH
+0xCD78 0x86D2 #CJK UNIFIED IDEOGRAPH
+0xCD79 0x86D3 #CJK UNIFIED IDEOGRAPH
+0xCD7A 0x86D5 #CJK UNIFIED IDEOGRAPH
+0xCD7B 0x86D6 #CJK UNIFIED IDEOGRAPH
+0xCD7C 0x86D7 #CJK UNIFIED IDEOGRAPH
+0xCD7D 0x86DA #CJK UNIFIED IDEOGRAPH
+0xCD7E 0x86DC #CJK UNIFIED IDEOGRAPH
+0xCD80 0x86DD #CJK UNIFIED IDEOGRAPH
+0xCD81 0x86E0 #CJK UNIFIED IDEOGRAPH
+0xCD82 0x86E1 #CJK UNIFIED IDEOGRAPH
+0xCD83 0x86E2 #CJK UNIFIED IDEOGRAPH
+0xCD84 0x86E3 #CJK UNIFIED IDEOGRAPH
+0xCD85 0x86E5 #CJK UNIFIED IDEOGRAPH
+0xCD86 0x86E6 #CJK UNIFIED IDEOGRAPH
+0xCD87 0x86E7 #CJK UNIFIED IDEOGRAPH
+0xCD88 0x86E8 #CJK UNIFIED IDEOGRAPH
+0xCD89 0x86EA #CJK UNIFIED IDEOGRAPH
+0xCD8A 0x86EB #CJK UNIFIED IDEOGRAPH
+0xCD8B 0x86EC #CJK UNIFIED IDEOGRAPH
+0xCD8C 0x86EF #CJK UNIFIED IDEOGRAPH
+0xCD8D 0x86F5 #CJK UNIFIED IDEOGRAPH
+0xCD8E 0x86F6 #CJK UNIFIED IDEOGRAPH
+0xCD8F 0x86F7 #CJK UNIFIED IDEOGRAPH
+0xCD90 0x86FA #CJK UNIFIED IDEOGRAPH
+0xCD91 0x86FB #CJK UNIFIED IDEOGRAPH
+0xCD92 0x86FC #CJK UNIFIED IDEOGRAPH
+0xCD93 0x86FD #CJK UNIFIED IDEOGRAPH
+0xCD94 0x86FF #CJK UNIFIED IDEOGRAPH
+0xCD95 0x8701 #CJK UNIFIED IDEOGRAPH
+0xCD96 0x8704 #CJK UNIFIED IDEOGRAPH
+0xCD97 0x8705 #CJK UNIFIED IDEOGRAPH
+0xCD98 0x8706 #CJK UNIFIED IDEOGRAPH
+0xCD99 0x870B #CJK UNIFIED IDEOGRAPH
+0xCD9A 0x870C #CJK UNIFIED IDEOGRAPH
+0xCD9B 0x870E #CJK UNIFIED IDEOGRAPH
+0xCD9C 0x870F #CJK UNIFIED IDEOGRAPH
+0xCD9D 0x8710 #CJK UNIFIED IDEOGRAPH
+0xCD9E 0x8711 #CJK UNIFIED IDEOGRAPH
+0xCD9F 0x8714 #CJK UNIFIED IDEOGRAPH
+0xCDA0 0x8716 #CJK UNIFIED IDEOGRAPH
+0xCDA1 0x6C40 #CJK UNIFIED IDEOGRAPH
+0xCDA2 0x5EF7 #CJK UNIFIED IDEOGRAPH
+0xCDA3 0x505C #CJK UNIFIED IDEOGRAPH
+0xCDA4 0x4EAD #CJK UNIFIED IDEOGRAPH
+0xCDA5 0x5EAD #CJK UNIFIED IDEOGRAPH
+0xCDA6 0x633A #CJK UNIFIED IDEOGRAPH
+0xCDA7 0x8247 #CJK UNIFIED IDEOGRAPH
+0xCDA8 0x901A #CJK UNIFIED IDEOGRAPH
+0xCDA9 0x6850 #CJK UNIFIED IDEOGRAPH
+0xCDAA 0x916E #CJK UNIFIED IDEOGRAPH
+0xCDAB 0x77B3 #CJK UNIFIED IDEOGRAPH
+0xCDAC 0x540C #CJK UNIFIED IDEOGRAPH
+0xCDAD 0x94DC #CJK UNIFIED IDEOGRAPH
+0xCDAE 0x5F64 #CJK UNIFIED IDEOGRAPH
+0xCDAF 0x7AE5 #CJK UNIFIED IDEOGRAPH
+0xCDB0 0x6876 #CJK UNIFIED IDEOGRAPH
+0xCDB1 0x6345 #CJK UNIFIED IDEOGRAPH
+0xCDB2 0x7B52 #CJK UNIFIED IDEOGRAPH
+0xCDB3 0x7EDF #CJK UNIFIED IDEOGRAPH
+0xCDB4 0x75DB #CJK UNIFIED IDEOGRAPH
+0xCDB5 0x5077 #CJK UNIFIED IDEOGRAPH
+0xCDB6 0x6295 #CJK UNIFIED IDEOGRAPH
+0xCDB7 0x5934 #CJK UNIFIED IDEOGRAPH
+0xCDB8 0x900F #CJK UNIFIED IDEOGRAPH
+0xCDB9 0x51F8 #CJK UNIFIED IDEOGRAPH
+0xCDBA 0x79C3 #CJK UNIFIED IDEOGRAPH
+0xCDBB 0x7A81 #CJK UNIFIED IDEOGRAPH
+0xCDBC 0x56FE #CJK UNIFIED IDEOGRAPH
+0xCDBD 0x5F92 #CJK UNIFIED IDEOGRAPH
+0xCDBE 0x9014 #CJK UNIFIED IDEOGRAPH
+0xCDBF 0x6D82 #CJK UNIFIED IDEOGRAPH
+0xCDC0 0x5C60 #CJK UNIFIED IDEOGRAPH
+0xCDC1 0x571F #CJK UNIFIED IDEOGRAPH
+0xCDC2 0x5410 #CJK UNIFIED IDEOGRAPH
+0xCDC3 0x5154 #CJK UNIFIED IDEOGRAPH
+0xCDC4 0x6E4D #CJK UNIFIED IDEOGRAPH
+0xCDC5 0x56E2 #CJK UNIFIED IDEOGRAPH
+0xCDC6 0x63A8 #CJK UNIFIED IDEOGRAPH
+0xCDC7 0x9893 #CJK UNIFIED IDEOGRAPH
+0xCDC8 0x817F #CJK UNIFIED IDEOGRAPH
+0xCDC9 0x8715 #CJK UNIFIED IDEOGRAPH
+0xCDCA 0x892A #CJK UNIFIED IDEOGRAPH
+0xCDCB 0x9000 #CJK UNIFIED IDEOGRAPH
+0xCDCC 0x541E #CJK UNIFIED IDEOGRAPH
+0xCDCD 0x5C6F #CJK UNIFIED IDEOGRAPH
+0xCDCE 0x81C0 #CJK UNIFIED IDEOGRAPH
+0xCDCF 0x62D6 #CJK UNIFIED IDEOGRAPH
+0xCDD0 0x6258 #CJK UNIFIED IDEOGRAPH
+0xCDD1 0x8131 #CJK UNIFIED IDEOGRAPH
+0xCDD2 0x9E35 #CJK UNIFIED IDEOGRAPH
+0xCDD3 0x9640 #CJK UNIFIED IDEOGRAPH
+0xCDD4 0x9A6E #CJK UNIFIED IDEOGRAPH
+0xCDD5 0x9A7C #CJK UNIFIED IDEOGRAPH
+0xCDD6 0x692D #CJK UNIFIED IDEOGRAPH
+0xCDD7 0x59A5 #CJK UNIFIED IDEOGRAPH
+0xCDD8 0x62D3 #CJK UNIFIED IDEOGRAPH
+0xCDD9 0x553E #CJK UNIFIED IDEOGRAPH
+0xCDDA 0x6316 #CJK UNIFIED IDEOGRAPH
+0xCDDB 0x54C7 #CJK UNIFIED IDEOGRAPH
+0xCDDC 0x86D9 #CJK UNIFIED IDEOGRAPH
+0xCDDD 0x6D3C #CJK UNIFIED IDEOGRAPH
+0xCDDE 0x5A03 #CJK UNIFIED IDEOGRAPH
+0xCDDF 0x74E6 #CJK UNIFIED IDEOGRAPH
+0xCDE0 0x889C #CJK UNIFIED IDEOGRAPH
+0xCDE1 0x6B6A #CJK UNIFIED IDEOGRAPH
+0xCDE2 0x5916 #CJK UNIFIED IDEOGRAPH
+0xCDE3 0x8C4C #CJK UNIFIED IDEOGRAPH
+0xCDE4 0x5F2F #CJK UNIFIED IDEOGRAPH
+0xCDE5 0x6E7E #CJK UNIFIED IDEOGRAPH
+0xCDE6 0x73A9 #CJK UNIFIED IDEOGRAPH
+0xCDE7 0x987D #CJK UNIFIED IDEOGRAPH
+0xCDE8 0x4E38 #CJK UNIFIED IDEOGRAPH
+0xCDE9 0x70F7 #CJK UNIFIED IDEOGRAPH
+0xCDEA 0x5B8C #CJK UNIFIED IDEOGRAPH
+0xCDEB 0x7897 #CJK UNIFIED IDEOGRAPH
+0xCDEC 0x633D #CJK UNIFIED IDEOGRAPH
+0xCDED 0x665A #CJK UNIFIED IDEOGRAPH
+0xCDEE 0x7696 #CJK UNIFIED IDEOGRAPH
+0xCDEF 0x60CB #CJK UNIFIED IDEOGRAPH
+0xCDF0 0x5B9B #CJK UNIFIED IDEOGRAPH
+0xCDF1 0x5A49 #CJK UNIFIED IDEOGRAPH
+0xCDF2 0x4E07 #CJK UNIFIED IDEOGRAPH
+0xCDF3 0x8155 #CJK UNIFIED IDEOGRAPH
+0xCDF4 0x6C6A #CJK UNIFIED IDEOGRAPH
+0xCDF5 0x738B #CJK UNIFIED IDEOGRAPH
+0xCDF6 0x4EA1 #CJK UNIFIED IDEOGRAPH
+0xCDF7 0x6789 #CJK UNIFIED IDEOGRAPH
+0xCDF8 0x7F51 #CJK UNIFIED IDEOGRAPH
+0xCDF9 0x5F80 #CJK UNIFIED IDEOGRAPH
+0xCDFA 0x65FA #CJK UNIFIED IDEOGRAPH
+0xCDFB 0x671B #CJK UNIFIED IDEOGRAPH
+0xCDFC 0x5FD8 #CJK UNIFIED IDEOGRAPH
+0xCDFD 0x5984 #CJK UNIFIED IDEOGRAPH
+0xCDFE 0x5A01 #CJK UNIFIED IDEOGRAPH
+0xCE40 0x8719 #CJK UNIFIED IDEOGRAPH
+0xCE41 0x871B #CJK UNIFIED IDEOGRAPH
+0xCE42 0x871D #CJK UNIFIED IDEOGRAPH
+0xCE43 0x871F #CJK UNIFIED IDEOGRAPH
+0xCE44 0x8720 #CJK UNIFIED IDEOGRAPH
+0xCE45 0x8724 #CJK UNIFIED IDEOGRAPH
+0xCE46 0x8726 #CJK UNIFIED IDEOGRAPH
+0xCE47 0x8727 #CJK UNIFIED IDEOGRAPH
+0xCE48 0x8728 #CJK UNIFIED IDEOGRAPH
+0xCE49 0x872A #CJK UNIFIED IDEOGRAPH
+0xCE4A 0x872B #CJK UNIFIED IDEOGRAPH
+0xCE4B 0x872C #CJK UNIFIED IDEOGRAPH
+0xCE4C 0x872D #CJK UNIFIED IDEOGRAPH
+0xCE4D 0x872F #CJK UNIFIED IDEOGRAPH
+0xCE4E 0x8730 #CJK UNIFIED IDEOGRAPH
+0xCE4F 0x8732 #CJK UNIFIED IDEOGRAPH
+0xCE50 0x8733 #CJK UNIFIED IDEOGRAPH
+0xCE51 0x8735 #CJK UNIFIED IDEOGRAPH
+0xCE52 0x8736 #CJK UNIFIED IDEOGRAPH
+0xCE53 0x8738 #CJK UNIFIED IDEOGRAPH
+0xCE54 0x8739 #CJK UNIFIED IDEOGRAPH
+0xCE55 0x873A #CJK UNIFIED IDEOGRAPH
+0xCE56 0x873C #CJK UNIFIED IDEOGRAPH
+0xCE57 0x873D #CJK UNIFIED IDEOGRAPH
+0xCE58 0x8740 #CJK UNIFIED IDEOGRAPH
+0xCE59 0x8741 #CJK UNIFIED IDEOGRAPH
+0xCE5A 0x8742 #CJK UNIFIED IDEOGRAPH
+0xCE5B 0x8743 #CJK UNIFIED IDEOGRAPH
+0xCE5C 0x8744 #CJK UNIFIED IDEOGRAPH
+0xCE5D 0x8745 #CJK UNIFIED IDEOGRAPH
+0xCE5E 0x8746 #CJK UNIFIED IDEOGRAPH
+0xCE5F 0x874A #CJK UNIFIED IDEOGRAPH
+0xCE60 0x874B #CJK UNIFIED IDEOGRAPH
+0xCE61 0x874D #CJK UNIFIED IDEOGRAPH
+0xCE62 0x874F #CJK UNIFIED IDEOGRAPH
+0xCE63 0x8750 #CJK UNIFIED IDEOGRAPH
+0xCE64 0x8751 #CJK UNIFIED IDEOGRAPH
+0xCE65 0x8752 #CJK UNIFIED IDEOGRAPH
+0xCE66 0x8754 #CJK UNIFIED IDEOGRAPH
+0xCE67 0x8755 #CJK UNIFIED IDEOGRAPH
+0xCE68 0x8756 #CJK UNIFIED IDEOGRAPH
+0xCE69 0x8758 #CJK UNIFIED IDEOGRAPH
+0xCE6A 0x875A #CJK UNIFIED IDEOGRAPH
+0xCE6B 0x875B #CJK UNIFIED IDEOGRAPH
+0xCE6C 0x875C #CJK UNIFIED IDEOGRAPH
+0xCE6D 0x875D #CJK UNIFIED IDEOGRAPH
+0xCE6E 0x875E #CJK UNIFIED IDEOGRAPH
+0xCE6F 0x875F #CJK UNIFIED IDEOGRAPH
+0xCE70 0x8761 #CJK UNIFIED IDEOGRAPH
+0xCE71 0x8762 #CJK UNIFIED IDEOGRAPH
+0xCE72 0x8766 #CJK UNIFIED IDEOGRAPH
+0xCE73 0x8767 #CJK UNIFIED IDEOGRAPH
+0xCE74 0x8768 #CJK UNIFIED IDEOGRAPH
+0xCE75 0x8769 #CJK UNIFIED IDEOGRAPH
+0xCE76 0x876A #CJK UNIFIED IDEOGRAPH
+0xCE77 0x876B #CJK UNIFIED IDEOGRAPH
+0xCE78 0x876C #CJK UNIFIED IDEOGRAPH
+0xCE79 0x876D #CJK UNIFIED IDEOGRAPH
+0xCE7A 0x876F #CJK UNIFIED IDEOGRAPH
+0xCE7B 0x8771 #CJK UNIFIED IDEOGRAPH
+0xCE7C 0x8772 #CJK UNIFIED IDEOGRAPH
+0xCE7D 0x8773 #CJK UNIFIED IDEOGRAPH
+0xCE7E 0x8775 #CJK UNIFIED IDEOGRAPH
+0xCE80 0x8777 #CJK UNIFIED IDEOGRAPH
+0xCE81 0x8778 #CJK UNIFIED IDEOGRAPH
+0xCE82 0x8779 #CJK UNIFIED IDEOGRAPH
+0xCE83 0x877A #CJK UNIFIED IDEOGRAPH
+0xCE84 0x877F #CJK UNIFIED IDEOGRAPH
+0xCE85 0x8780 #CJK UNIFIED IDEOGRAPH
+0xCE86 0x8781 #CJK UNIFIED IDEOGRAPH
+0xCE87 0x8784 #CJK UNIFIED IDEOGRAPH
+0xCE88 0x8786 #CJK UNIFIED IDEOGRAPH
+0xCE89 0x8787 #CJK UNIFIED IDEOGRAPH
+0xCE8A 0x8789 #CJK UNIFIED IDEOGRAPH
+0xCE8B 0x878A #CJK UNIFIED IDEOGRAPH
+0xCE8C 0x878C #CJK UNIFIED IDEOGRAPH
+0xCE8D 0x878E #CJK UNIFIED IDEOGRAPH
+0xCE8E 0x878F #CJK UNIFIED IDEOGRAPH
+0xCE8F 0x8790 #CJK UNIFIED IDEOGRAPH
+0xCE90 0x8791 #CJK UNIFIED IDEOGRAPH
+0xCE91 0x8792 #CJK UNIFIED IDEOGRAPH
+0xCE92 0x8794 #CJK UNIFIED IDEOGRAPH
+0xCE93 0x8795 #CJK UNIFIED IDEOGRAPH
+0xCE94 0x8796 #CJK UNIFIED IDEOGRAPH
+0xCE95 0x8798 #CJK UNIFIED IDEOGRAPH
+0xCE96 0x8799 #CJK UNIFIED IDEOGRAPH
+0xCE97 0x879A #CJK UNIFIED IDEOGRAPH
+0xCE98 0x879B #CJK UNIFIED IDEOGRAPH
+0xCE99 0x879C #CJK UNIFIED IDEOGRAPH
+0xCE9A 0x879D #CJK UNIFIED IDEOGRAPH
+0xCE9B 0x879E #CJK UNIFIED IDEOGRAPH
+0xCE9C 0x87A0 #CJK UNIFIED IDEOGRAPH
+0xCE9D 0x87A1 #CJK UNIFIED IDEOGRAPH
+0xCE9E 0x87A2 #CJK UNIFIED IDEOGRAPH
+0xCE9F 0x87A3 #CJK UNIFIED IDEOGRAPH
+0xCEA0 0x87A4 #CJK UNIFIED IDEOGRAPH
+0xCEA1 0x5DCD #CJK UNIFIED IDEOGRAPH
+0xCEA2 0x5FAE #CJK UNIFIED IDEOGRAPH
+0xCEA3 0x5371 #CJK UNIFIED IDEOGRAPH
+0xCEA4 0x97E6 #CJK UNIFIED IDEOGRAPH
+0xCEA5 0x8FDD #CJK UNIFIED IDEOGRAPH
+0xCEA6 0x6845 #CJK UNIFIED IDEOGRAPH
+0xCEA7 0x56F4 #CJK UNIFIED IDEOGRAPH
+0xCEA8 0x552F #CJK UNIFIED IDEOGRAPH
+0xCEA9 0x60DF #CJK UNIFIED IDEOGRAPH
+0xCEAA 0x4E3A #CJK UNIFIED IDEOGRAPH
+0xCEAB 0x6F4D #CJK UNIFIED IDEOGRAPH
+0xCEAC 0x7EF4 #CJK UNIFIED IDEOGRAPH
+0xCEAD 0x82C7 #CJK UNIFIED IDEOGRAPH
+0xCEAE 0x840E #CJK UNIFIED IDEOGRAPH
+0xCEAF 0x59D4 #CJK UNIFIED IDEOGRAPH
+0xCEB0 0x4F1F #CJK UNIFIED IDEOGRAPH
+0xCEB1 0x4F2A #CJK UNIFIED IDEOGRAPH
+0xCEB2 0x5C3E #CJK UNIFIED IDEOGRAPH
+0xCEB3 0x7EAC #CJK UNIFIED IDEOGRAPH
+0xCEB4 0x672A #CJK UNIFIED IDEOGRAPH
+0xCEB5 0x851A #CJK UNIFIED IDEOGRAPH
+0xCEB6 0x5473 #CJK UNIFIED IDEOGRAPH
+0xCEB7 0x754F #CJK UNIFIED IDEOGRAPH
+0xCEB8 0x80C3 #CJK UNIFIED IDEOGRAPH
+0xCEB9 0x5582 #CJK UNIFIED IDEOGRAPH
+0xCEBA 0x9B4F #CJK UNIFIED IDEOGRAPH
+0xCEBB 0x4F4D #CJK UNIFIED IDEOGRAPH
+0xCEBC 0x6E2D #CJK UNIFIED IDEOGRAPH
+0xCEBD 0x8C13 #CJK UNIFIED IDEOGRAPH
+0xCEBE 0x5C09 #CJK UNIFIED IDEOGRAPH
+0xCEBF 0x6170 #CJK UNIFIED IDEOGRAPH
+0xCEC0 0x536B #CJK UNIFIED IDEOGRAPH
+0xCEC1 0x761F #CJK UNIFIED IDEOGRAPH
+0xCEC2 0x6E29 #CJK UNIFIED IDEOGRAPH
+0xCEC3 0x868A #CJK UNIFIED IDEOGRAPH
+0xCEC4 0x6587 #CJK UNIFIED IDEOGRAPH
+0xCEC5 0x95FB #CJK UNIFIED IDEOGRAPH
+0xCEC6 0x7EB9 #CJK UNIFIED IDEOGRAPH
+0xCEC7 0x543B #CJK UNIFIED IDEOGRAPH
+0xCEC8 0x7A33 #CJK UNIFIED IDEOGRAPH
+0xCEC9 0x7D0A #CJK UNIFIED IDEOGRAPH
+0xCECA 0x95EE #CJK UNIFIED IDEOGRAPH
+0xCECB 0x55E1 #CJK UNIFIED IDEOGRAPH
+0xCECC 0x7FC1 #CJK UNIFIED IDEOGRAPH
+0xCECD 0x74EE #CJK UNIFIED IDEOGRAPH
+0xCECE 0x631D #CJK UNIFIED IDEOGRAPH
+0xCECF 0x8717 #CJK UNIFIED IDEOGRAPH
+0xCED0 0x6DA1 #CJK UNIFIED IDEOGRAPH
+0xCED1 0x7A9D #CJK UNIFIED IDEOGRAPH
+0xCED2 0x6211 #CJK UNIFIED IDEOGRAPH
+0xCED3 0x65A1 #CJK UNIFIED IDEOGRAPH
+0xCED4 0x5367 #CJK UNIFIED IDEOGRAPH
+0xCED5 0x63E1 #CJK UNIFIED IDEOGRAPH
+0xCED6 0x6C83 #CJK UNIFIED IDEOGRAPH
+0xCED7 0x5DEB #CJK UNIFIED IDEOGRAPH
+0xCED8 0x545C #CJK UNIFIED IDEOGRAPH
+0xCED9 0x94A8 #CJK UNIFIED IDEOGRAPH
+0xCEDA 0x4E4C #CJK UNIFIED IDEOGRAPH
+0xCEDB 0x6C61 #CJK UNIFIED IDEOGRAPH
+0xCEDC 0x8BEC #CJK UNIFIED IDEOGRAPH
+0xCEDD 0x5C4B #CJK UNIFIED IDEOGRAPH
+0xCEDE 0x65E0 #CJK UNIFIED IDEOGRAPH
+0xCEDF 0x829C #CJK UNIFIED IDEOGRAPH
+0xCEE0 0x68A7 #CJK UNIFIED IDEOGRAPH
+0xCEE1 0x543E #CJK UNIFIED IDEOGRAPH
+0xCEE2 0x5434 #CJK UNIFIED IDEOGRAPH
+0xCEE3 0x6BCB #CJK UNIFIED IDEOGRAPH
+0xCEE4 0x6B66 #CJK UNIFIED IDEOGRAPH
+0xCEE5 0x4E94 #CJK UNIFIED IDEOGRAPH
+0xCEE6 0x6342 #CJK UNIFIED IDEOGRAPH
+0xCEE7 0x5348 #CJK UNIFIED IDEOGRAPH
+0xCEE8 0x821E #CJK UNIFIED IDEOGRAPH
+0xCEE9 0x4F0D #CJK UNIFIED IDEOGRAPH
+0xCEEA 0x4FAE #CJK UNIFIED IDEOGRAPH
+0xCEEB 0x575E #CJK UNIFIED IDEOGRAPH
+0xCEEC 0x620A #CJK UNIFIED IDEOGRAPH
+0xCEED 0x96FE #CJK UNIFIED IDEOGRAPH
+0xCEEE 0x6664 #CJK UNIFIED IDEOGRAPH
+0xCEEF 0x7269 #CJK UNIFIED IDEOGRAPH
+0xCEF0 0x52FF #CJK UNIFIED IDEOGRAPH
+0xCEF1 0x52A1 #CJK UNIFIED IDEOGRAPH
+0xCEF2 0x609F #CJK UNIFIED IDEOGRAPH
+0xCEF3 0x8BEF #CJK UNIFIED IDEOGRAPH
+0xCEF4 0x6614 #CJK UNIFIED IDEOGRAPH
+0xCEF5 0x7199 #CJK UNIFIED IDEOGRAPH
+0xCEF6 0x6790 #CJK UNIFIED IDEOGRAPH
+0xCEF7 0x897F #CJK UNIFIED IDEOGRAPH
+0xCEF8 0x7852 #CJK UNIFIED IDEOGRAPH
+0xCEF9 0x77FD #CJK UNIFIED IDEOGRAPH
+0xCEFA 0x6670 #CJK UNIFIED IDEOGRAPH
+0xCEFB 0x563B #CJK UNIFIED IDEOGRAPH
+0xCEFC 0x5438 #CJK UNIFIED IDEOGRAPH
+0xCEFD 0x9521 #CJK UNIFIED IDEOGRAPH
+0xCEFE 0x727A #CJK UNIFIED IDEOGRAPH
+0xCF40 0x87A5 #CJK UNIFIED IDEOGRAPH
+0xCF41 0x87A6 #CJK UNIFIED IDEOGRAPH
+0xCF42 0x87A7 #CJK UNIFIED IDEOGRAPH
+0xCF43 0x87A9 #CJK UNIFIED IDEOGRAPH
+0xCF44 0x87AA #CJK UNIFIED IDEOGRAPH
+0xCF45 0x87AE #CJK UNIFIED IDEOGRAPH
+0xCF46 0x87B0 #CJK UNIFIED IDEOGRAPH
+0xCF47 0x87B1 #CJK UNIFIED IDEOGRAPH
+0xCF48 0x87B2 #CJK UNIFIED IDEOGRAPH
+0xCF49 0x87B4 #CJK UNIFIED IDEOGRAPH
+0xCF4A 0x87B6 #CJK UNIFIED IDEOGRAPH
+0xCF4B 0x87B7 #CJK UNIFIED IDEOGRAPH
+0xCF4C 0x87B8 #CJK UNIFIED IDEOGRAPH
+0xCF4D 0x87B9 #CJK UNIFIED IDEOGRAPH
+0xCF4E 0x87BB #CJK UNIFIED IDEOGRAPH
+0xCF4F 0x87BC #CJK UNIFIED IDEOGRAPH
+0xCF50 0x87BE #CJK UNIFIED IDEOGRAPH
+0xCF51 0x87BF #CJK UNIFIED IDEOGRAPH
+0xCF52 0x87C1 #CJK UNIFIED IDEOGRAPH
+0xCF53 0x87C2 #CJK UNIFIED IDEOGRAPH
+0xCF54 0x87C3 #CJK UNIFIED IDEOGRAPH
+0xCF55 0x87C4 #CJK UNIFIED IDEOGRAPH
+0xCF56 0x87C5 #CJK UNIFIED IDEOGRAPH
+0xCF57 0x87C7 #CJK UNIFIED IDEOGRAPH
+0xCF58 0x87C8 #CJK UNIFIED IDEOGRAPH
+0xCF59 0x87C9 #CJK UNIFIED IDEOGRAPH
+0xCF5A 0x87CC #CJK UNIFIED IDEOGRAPH
+0xCF5B 0x87CD #CJK UNIFIED IDEOGRAPH
+0xCF5C 0x87CE #CJK UNIFIED IDEOGRAPH
+0xCF5D 0x87CF #CJK UNIFIED IDEOGRAPH
+0xCF5E 0x87D0 #CJK UNIFIED IDEOGRAPH
+0xCF5F 0x87D4 #CJK UNIFIED IDEOGRAPH
+0xCF60 0x87D5 #CJK UNIFIED IDEOGRAPH
+0xCF61 0x87D6 #CJK UNIFIED IDEOGRAPH
+0xCF62 0x87D7 #CJK UNIFIED IDEOGRAPH
+0xCF63 0x87D8 #CJK UNIFIED IDEOGRAPH
+0xCF64 0x87D9 #CJK UNIFIED IDEOGRAPH
+0xCF65 0x87DA #CJK UNIFIED IDEOGRAPH
+0xCF66 0x87DC #CJK UNIFIED IDEOGRAPH
+0xCF67 0x87DD #CJK UNIFIED IDEOGRAPH
+0xCF68 0x87DE #CJK UNIFIED IDEOGRAPH
+0xCF69 0x87DF #CJK UNIFIED IDEOGRAPH
+0xCF6A 0x87E1 #CJK UNIFIED IDEOGRAPH
+0xCF6B 0x87E2 #CJK UNIFIED IDEOGRAPH
+0xCF6C 0x87E3 #CJK UNIFIED IDEOGRAPH
+0xCF6D 0x87E4 #CJK UNIFIED IDEOGRAPH
+0xCF6E 0x87E6 #CJK UNIFIED IDEOGRAPH
+0xCF6F 0x87E7 #CJK UNIFIED IDEOGRAPH
+0xCF70 0x87E8 #CJK UNIFIED IDEOGRAPH
+0xCF71 0x87E9 #CJK UNIFIED IDEOGRAPH
+0xCF72 0x87EB #CJK UNIFIED IDEOGRAPH
+0xCF73 0x87EC #CJK UNIFIED IDEOGRAPH
+0xCF74 0x87ED #CJK UNIFIED IDEOGRAPH
+0xCF75 0x87EF #CJK UNIFIED IDEOGRAPH
+0xCF76 0x87F0 #CJK UNIFIED IDEOGRAPH
+0xCF77 0x87F1 #CJK UNIFIED IDEOGRAPH
+0xCF78 0x87F2 #CJK UNIFIED IDEOGRAPH
+0xCF79 0x87F3 #CJK UNIFIED IDEOGRAPH
+0xCF7A 0x87F4 #CJK UNIFIED IDEOGRAPH
+0xCF7B 0x87F5 #CJK UNIFIED IDEOGRAPH
+0xCF7C 0x87F6 #CJK UNIFIED IDEOGRAPH
+0xCF7D 0x87F7 #CJK UNIFIED IDEOGRAPH
+0xCF7E 0x87F8 #CJK UNIFIED IDEOGRAPH
+0xCF80 0x87FA #CJK UNIFIED IDEOGRAPH
+0xCF81 0x87FB #CJK UNIFIED IDEOGRAPH
+0xCF82 0x87FC #CJK UNIFIED IDEOGRAPH
+0xCF83 0x87FD #CJK UNIFIED IDEOGRAPH
+0xCF84 0x87FF #CJK UNIFIED IDEOGRAPH
+0xCF85 0x8800 #CJK UNIFIED IDEOGRAPH
+0xCF86 0x8801 #CJK UNIFIED IDEOGRAPH
+0xCF87 0x8802 #CJK UNIFIED IDEOGRAPH
+0xCF88 0x8804 #CJK UNIFIED IDEOGRAPH
+0xCF89 0x8805 #CJK UNIFIED IDEOGRAPH
+0xCF8A 0x8806 #CJK UNIFIED IDEOGRAPH
+0xCF8B 0x8807 #CJK UNIFIED IDEOGRAPH
+0xCF8C 0x8808 #CJK UNIFIED IDEOGRAPH
+0xCF8D 0x8809 #CJK UNIFIED IDEOGRAPH
+0xCF8E 0x880B #CJK UNIFIED IDEOGRAPH
+0xCF8F 0x880C #CJK UNIFIED IDEOGRAPH
+0xCF90 0x880D #CJK UNIFIED IDEOGRAPH
+0xCF91 0x880E #CJK UNIFIED IDEOGRAPH
+0xCF92 0x880F #CJK UNIFIED IDEOGRAPH
+0xCF93 0x8810 #CJK UNIFIED IDEOGRAPH
+0xCF94 0x8811 #CJK UNIFIED IDEOGRAPH
+0xCF95 0x8812 #CJK UNIFIED IDEOGRAPH
+0xCF96 0x8814 #CJK UNIFIED IDEOGRAPH
+0xCF97 0x8817 #CJK UNIFIED IDEOGRAPH
+0xCF98 0x8818 #CJK UNIFIED IDEOGRAPH
+0xCF99 0x8819 #CJK UNIFIED IDEOGRAPH
+0xCF9A 0x881A #CJK UNIFIED IDEOGRAPH
+0xCF9B 0x881C #CJK UNIFIED IDEOGRAPH
+0xCF9C 0x881D #CJK UNIFIED IDEOGRAPH
+0xCF9D 0x881E #CJK UNIFIED IDEOGRAPH
+0xCF9E 0x881F #CJK UNIFIED IDEOGRAPH
+0xCF9F 0x8820 #CJK UNIFIED IDEOGRAPH
+0xCFA0 0x8823 #CJK UNIFIED IDEOGRAPH
+0xCFA1 0x7A00 #CJK UNIFIED IDEOGRAPH
+0xCFA2 0x606F #CJK UNIFIED IDEOGRAPH
+0xCFA3 0x5E0C #CJK UNIFIED IDEOGRAPH
+0xCFA4 0x6089 #CJK UNIFIED IDEOGRAPH
+0xCFA5 0x819D #CJK UNIFIED IDEOGRAPH
+0xCFA6 0x5915 #CJK UNIFIED IDEOGRAPH
+0xCFA7 0x60DC #CJK UNIFIED IDEOGRAPH
+0xCFA8 0x7184 #CJK UNIFIED IDEOGRAPH
+0xCFA9 0x70EF #CJK UNIFIED IDEOGRAPH
+0xCFAA 0x6EAA #CJK UNIFIED IDEOGRAPH
+0xCFAB 0x6C50 #CJK UNIFIED IDEOGRAPH
+0xCFAC 0x7280 #CJK UNIFIED IDEOGRAPH
+0xCFAD 0x6A84 #CJK UNIFIED IDEOGRAPH
+0xCFAE 0x88AD #CJK UNIFIED IDEOGRAPH
+0xCFAF 0x5E2D #CJK UNIFIED IDEOGRAPH
+0xCFB0 0x4E60 #CJK UNIFIED IDEOGRAPH
+0xCFB1 0x5AB3 #CJK UNIFIED IDEOGRAPH
+0xCFB2 0x559C #CJK UNIFIED IDEOGRAPH
+0xCFB3 0x94E3 #CJK UNIFIED IDEOGRAPH
+0xCFB4 0x6D17 #CJK UNIFIED IDEOGRAPH
+0xCFB5 0x7CFB #CJK UNIFIED IDEOGRAPH
+0xCFB6 0x9699 #CJK UNIFIED IDEOGRAPH
+0xCFB7 0x620F #CJK UNIFIED IDEOGRAPH
+0xCFB8 0x7EC6 #CJK UNIFIED IDEOGRAPH
+0xCFB9 0x778E #CJK UNIFIED IDEOGRAPH
+0xCFBA 0x867E #CJK UNIFIED IDEOGRAPH
+0xCFBB 0x5323 #CJK UNIFIED IDEOGRAPH
+0xCFBC 0x971E #CJK UNIFIED IDEOGRAPH
+0xCFBD 0x8F96 #CJK UNIFIED IDEOGRAPH
+0xCFBE 0x6687 #CJK UNIFIED IDEOGRAPH
+0xCFBF 0x5CE1 #CJK UNIFIED IDEOGRAPH
+0xCFC0 0x4FA0 #CJK UNIFIED IDEOGRAPH
+0xCFC1 0x72ED #CJK UNIFIED IDEOGRAPH
+0xCFC2 0x4E0B #CJK UNIFIED IDEOGRAPH
+0xCFC3 0x53A6 #CJK UNIFIED IDEOGRAPH
+0xCFC4 0x590F #CJK UNIFIED IDEOGRAPH
+0xCFC5 0x5413 #CJK UNIFIED IDEOGRAPH
+0xCFC6 0x6380 #CJK UNIFIED IDEOGRAPH
+0xCFC7 0x9528 #CJK UNIFIED IDEOGRAPH
+0xCFC8 0x5148 #CJK UNIFIED IDEOGRAPH
+0xCFC9 0x4ED9 #CJK UNIFIED IDEOGRAPH
+0xCFCA 0x9C9C #CJK UNIFIED IDEOGRAPH
+0xCFCB 0x7EA4 #CJK UNIFIED IDEOGRAPH
+0xCFCC 0x54B8 #CJK UNIFIED IDEOGRAPH
+0xCFCD 0x8D24 #CJK UNIFIED IDEOGRAPH
+0xCFCE 0x8854 #CJK UNIFIED IDEOGRAPH
+0xCFCF 0x8237 #CJK UNIFIED IDEOGRAPH
+0xCFD0 0x95F2 #CJK UNIFIED IDEOGRAPH
+0xCFD1 0x6D8E #CJK UNIFIED IDEOGRAPH
+0xCFD2 0x5F26 #CJK UNIFIED IDEOGRAPH
+0xCFD3 0x5ACC #CJK UNIFIED IDEOGRAPH
+0xCFD4 0x663E #CJK UNIFIED IDEOGRAPH
+0xCFD5 0x9669 #CJK UNIFIED IDEOGRAPH
+0xCFD6 0x73B0 #CJK UNIFIED IDEOGRAPH
+0xCFD7 0x732E #CJK UNIFIED IDEOGRAPH
+0xCFD8 0x53BF #CJK UNIFIED IDEOGRAPH
+0xCFD9 0x817A #CJK UNIFIED IDEOGRAPH
+0xCFDA 0x9985 #CJK UNIFIED IDEOGRAPH
+0xCFDB 0x7FA1 #CJK UNIFIED IDEOGRAPH
+0xCFDC 0x5BAA #CJK UNIFIED IDEOGRAPH
+0xCFDD 0x9677 #CJK UNIFIED IDEOGRAPH
+0xCFDE 0x9650 #CJK UNIFIED IDEOGRAPH
+0xCFDF 0x7EBF #CJK UNIFIED IDEOGRAPH
+0xCFE0 0x76F8 #CJK UNIFIED IDEOGRAPH
+0xCFE1 0x53A2 #CJK UNIFIED IDEOGRAPH
+0xCFE2 0x9576 #CJK UNIFIED IDEOGRAPH
+0xCFE3 0x9999 #CJK UNIFIED IDEOGRAPH
+0xCFE4 0x7BB1 #CJK UNIFIED IDEOGRAPH
+0xCFE5 0x8944 #CJK UNIFIED IDEOGRAPH
+0xCFE6 0x6E58 #CJK UNIFIED IDEOGRAPH
+0xCFE7 0x4E61 #CJK UNIFIED IDEOGRAPH
+0xCFE8 0x7FD4 #CJK UNIFIED IDEOGRAPH
+0xCFE9 0x7965 #CJK UNIFIED IDEOGRAPH
+0xCFEA 0x8BE6 #CJK UNIFIED IDEOGRAPH
+0xCFEB 0x60F3 #CJK UNIFIED IDEOGRAPH
+0xCFEC 0x54CD #CJK UNIFIED IDEOGRAPH
+0xCFED 0x4EAB #CJK UNIFIED IDEOGRAPH
+0xCFEE 0x9879 #CJK UNIFIED IDEOGRAPH
+0xCFEF 0x5DF7 #CJK UNIFIED IDEOGRAPH
+0xCFF0 0x6A61 #CJK UNIFIED IDEOGRAPH
+0xCFF1 0x50CF #CJK UNIFIED IDEOGRAPH
+0xCFF2 0x5411 #CJK UNIFIED IDEOGRAPH
+0xCFF3 0x8C61 #CJK UNIFIED IDEOGRAPH
+0xCFF4 0x8427 #CJK UNIFIED IDEOGRAPH
+0xCFF5 0x785D #CJK UNIFIED IDEOGRAPH
+0xCFF6 0x9704 #CJK UNIFIED IDEOGRAPH
+0xCFF7 0x524A #CJK UNIFIED IDEOGRAPH
+0xCFF8 0x54EE #CJK UNIFIED IDEOGRAPH
+0xCFF9 0x56A3 #CJK UNIFIED IDEOGRAPH
+0xCFFA 0x9500 #CJK UNIFIED IDEOGRAPH
+0xCFFB 0x6D88 #CJK UNIFIED IDEOGRAPH
+0xCFFC 0x5BB5 #CJK UNIFIED IDEOGRAPH
+0xCFFD 0x6DC6 #CJK UNIFIED IDEOGRAPH
+0xCFFE 0x6653 #CJK UNIFIED IDEOGRAPH
+0xD040 0x8824 #CJK UNIFIED IDEOGRAPH
+0xD041 0x8825 #CJK UNIFIED IDEOGRAPH
+0xD042 0x8826 #CJK UNIFIED IDEOGRAPH
+0xD043 0x8827 #CJK UNIFIED IDEOGRAPH
+0xD044 0x8828 #CJK UNIFIED IDEOGRAPH
+0xD045 0x8829 #CJK UNIFIED IDEOGRAPH
+0xD046 0x882A #CJK UNIFIED IDEOGRAPH
+0xD047 0x882B #CJK UNIFIED IDEOGRAPH
+0xD048 0x882C #CJK UNIFIED IDEOGRAPH
+0xD049 0x882D #CJK UNIFIED IDEOGRAPH
+0xD04A 0x882E #CJK UNIFIED IDEOGRAPH
+0xD04B 0x882F #CJK UNIFIED IDEOGRAPH
+0xD04C 0x8830 #CJK UNIFIED IDEOGRAPH
+0xD04D 0x8831 #CJK UNIFIED IDEOGRAPH
+0xD04E 0x8833 #CJK UNIFIED IDEOGRAPH
+0xD04F 0x8834 #CJK UNIFIED IDEOGRAPH
+0xD050 0x8835 #CJK UNIFIED IDEOGRAPH
+0xD051 0x8836 #CJK UNIFIED IDEOGRAPH
+0xD052 0x8837 #CJK UNIFIED IDEOGRAPH
+0xD053 0x8838 #CJK UNIFIED IDEOGRAPH
+0xD054 0x883A #CJK UNIFIED IDEOGRAPH
+0xD055 0x883B #CJK UNIFIED IDEOGRAPH
+0xD056 0x883D #CJK UNIFIED IDEOGRAPH
+0xD057 0x883E #CJK UNIFIED IDEOGRAPH
+0xD058 0x883F #CJK UNIFIED IDEOGRAPH
+0xD059 0x8841 #CJK UNIFIED IDEOGRAPH
+0xD05A 0x8842 #CJK UNIFIED IDEOGRAPH
+0xD05B 0x8843 #CJK UNIFIED IDEOGRAPH
+0xD05C 0x8846 #CJK UNIFIED IDEOGRAPH
+0xD05D 0x8847 #CJK UNIFIED IDEOGRAPH
+0xD05E 0x8848 #CJK UNIFIED IDEOGRAPH
+0xD05F 0x8849 #CJK UNIFIED IDEOGRAPH
+0xD060 0x884A #CJK UNIFIED IDEOGRAPH
+0xD061 0x884B #CJK UNIFIED IDEOGRAPH
+0xD062 0x884E #CJK UNIFIED IDEOGRAPH
+0xD063 0x884F #CJK UNIFIED IDEOGRAPH
+0xD064 0x8850 #CJK UNIFIED IDEOGRAPH
+0xD065 0x8851 #CJK UNIFIED IDEOGRAPH
+0xD066 0x8852 #CJK UNIFIED IDEOGRAPH
+0xD067 0x8853 #CJK UNIFIED IDEOGRAPH
+0xD068 0x8855 #CJK UNIFIED IDEOGRAPH
+0xD069 0x8856 #CJK UNIFIED IDEOGRAPH
+0xD06A 0x8858 #CJK UNIFIED IDEOGRAPH
+0xD06B 0x885A #CJK UNIFIED IDEOGRAPH
+0xD06C 0x885B #CJK UNIFIED IDEOGRAPH
+0xD06D 0x885C #CJK UNIFIED IDEOGRAPH
+0xD06E 0x885D #CJK UNIFIED IDEOGRAPH
+0xD06F 0x885E #CJK UNIFIED IDEOGRAPH
+0xD070 0x885F #CJK UNIFIED IDEOGRAPH
+0xD071 0x8860 #CJK UNIFIED IDEOGRAPH
+0xD072 0x8866 #CJK UNIFIED IDEOGRAPH
+0xD073 0x8867 #CJK UNIFIED IDEOGRAPH
+0xD074 0x886A #CJK UNIFIED IDEOGRAPH
+0xD075 0x886D #CJK UNIFIED IDEOGRAPH
+0xD076 0x886F #CJK UNIFIED IDEOGRAPH
+0xD077 0x8871 #CJK UNIFIED IDEOGRAPH
+0xD078 0x8873 #CJK UNIFIED IDEOGRAPH
+0xD079 0x8874 #CJK UNIFIED IDEOGRAPH
+0xD07A 0x8875 #CJK UNIFIED IDEOGRAPH
+0xD07B 0x8876 #CJK UNIFIED IDEOGRAPH
+0xD07C 0x8878 #CJK UNIFIED IDEOGRAPH
+0xD07D 0x8879 #CJK UNIFIED IDEOGRAPH
+0xD07E 0x887A #CJK UNIFIED IDEOGRAPH
+0xD080 0x887B #CJK UNIFIED IDEOGRAPH
+0xD081 0x887C #CJK UNIFIED IDEOGRAPH
+0xD082 0x8880 #CJK UNIFIED IDEOGRAPH
+0xD083 0x8883 #CJK UNIFIED IDEOGRAPH
+0xD084 0x8886 #CJK UNIFIED IDEOGRAPH
+0xD085 0x8887 #CJK UNIFIED IDEOGRAPH
+0xD086 0x8889 #CJK UNIFIED IDEOGRAPH
+0xD087 0x888A #CJK UNIFIED IDEOGRAPH
+0xD088 0x888C #CJK UNIFIED IDEOGRAPH
+0xD089 0x888E #CJK UNIFIED IDEOGRAPH
+0xD08A 0x888F #CJK UNIFIED IDEOGRAPH
+0xD08B 0x8890 #CJK UNIFIED IDEOGRAPH
+0xD08C 0x8891 #CJK UNIFIED IDEOGRAPH
+0xD08D 0x8893 #CJK UNIFIED IDEOGRAPH
+0xD08E 0x8894 #CJK UNIFIED IDEOGRAPH
+0xD08F 0x8895 #CJK UNIFIED IDEOGRAPH
+0xD090 0x8897 #CJK UNIFIED IDEOGRAPH
+0xD091 0x8898 #CJK UNIFIED IDEOGRAPH
+0xD092 0x8899 #CJK UNIFIED IDEOGRAPH
+0xD093 0x889A #CJK UNIFIED IDEOGRAPH
+0xD094 0x889B #CJK UNIFIED IDEOGRAPH
+0xD095 0x889D #CJK UNIFIED IDEOGRAPH
+0xD096 0x889E #CJK UNIFIED IDEOGRAPH
+0xD097 0x889F #CJK UNIFIED IDEOGRAPH
+0xD098 0x88A0 #CJK UNIFIED IDEOGRAPH
+0xD099 0x88A1 #CJK UNIFIED IDEOGRAPH
+0xD09A 0x88A3 #CJK UNIFIED IDEOGRAPH
+0xD09B 0x88A5 #CJK UNIFIED IDEOGRAPH
+0xD09C 0x88A6 #CJK UNIFIED IDEOGRAPH
+0xD09D 0x88A7 #CJK UNIFIED IDEOGRAPH
+0xD09E 0x88A8 #CJK UNIFIED IDEOGRAPH
+0xD09F 0x88A9 #CJK UNIFIED IDEOGRAPH
+0xD0A0 0x88AA #CJK UNIFIED IDEOGRAPH
+0xD0A1 0x5C0F #CJK UNIFIED IDEOGRAPH
+0xD0A2 0x5B5D #CJK UNIFIED IDEOGRAPH
+0xD0A3 0x6821 #CJK UNIFIED IDEOGRAPH
+0xD0A4 0x8096 #CJK UNIFIED IDEOGRAPH
+0xD0A5 0x5578 #CJK UNIFIED IDEOGRAPH
+0xD0A6 0x7B11 #CJK UNIFIED IDEOGRAPH
+0xD0A7 0x6548 #CJK UNIFIED IDEOGRAPH
+0xD0A8 0x6954 #CJK UNIFIED IDEOGRAPH
+0xD0A9 0x4E9B #CJK UNIFIED IDEOGRAPH
+0xD0AA 0x6B47 #CJK UNIFIED IDEOGRAPH
+0xD0AB 0x874E #CJK UNIFIED IDEOGRAPH
+0xD0AC 0x978B #CJK UNIFIED IDEOGRAPH
+0xD0AD 0x534F #CJK UNIFIED IDEOGRAPH
+0xD0AE 0x631F #CJK UNIFIED IDEOGRAPH
+0xD0AF 0x643A #CJK UNIFIED IDEOGRAPH
+0xD0B0 0x90AA #CJK UNIFIED IDEOGRAPH
+0xD0B1 0x659C #CJK UNIFIED IDEOGRAPH
+0xD0B2 0x80C1 #CJK UNIFIED IDEOGRAPH
+0xD0B3 0x8C10 #CJK UNIFIED IDEOGRAPH
+0xD0B4 0x5199 #CJK UNIFIED IDEOGRAPH
+0xD0B5 0x68B0 #CJK UNIFIED IDEOGRAPH
+0xD0B6 0x5378 #CJK UNIFIED IDEOGRAPH
+0xD0B7 0x87F9 #CJK UNIFIED IDEOGRAPH
+0xD0B8 0x61C8 #CJK UNIFIED IDEOGRAPH
+0xD0B9 0x6CC4 #CJK UNIFIED IDEOGRAPH
+0xD0BA 0x6CFB #CJK UNIFIED IDEOGRAPH
+0xD0BB 0x8C22 #CJK UNIFIED IDEOGRAPH
+0xD0BC 0x5C51 #CJK UNIFIED IDEOGRAPH
+0xD0BD 0x85AA #CJK UNIFIED IDEOGRAPH
+0xD0BE 0x82AF #CJK UNIFIED IDEOGRAPH
+0xD0BF 0x950C #CJK UNIFIED IDEOGRAPH
+0xD0C0 0x6B23 #CJK UNIFIED IDEOGRAPH
+0xD0C1 0x8F9B #CJK UNIFIED IDEOGRAPH
+0xD0C2 0x65B0 #CJK UNIFIED IDEOGRAPH
+0xD0C3 0x5FFB #CJK UNIFIED IDEOGRAPH
+0xD0C4 0x5FC3 #CJK UNIFIED IDEOGRAPH
+0xD0C5 0x4FE1 #CJK UNIFIED IDEOGRAPH
+0xD0C6 0x8845 #CJK UNIFIED IDEOGRAPH
+0xD0C7 0x661F #CJK UNIFIED IDEOGRAPH
+0xD0C8 0x8165 #CJK UNIFIED IDEOGRAPH
+0xD0C9 0x7329 #CJK UNIFIED IDEOGRAPH
+0xD0CA 0x60FA #CJK UNIFIED IDEOGRAPH
+0xD0CB 0x5174 #CJK UNIFIED IDEOGRAPH
+0xD0CC 0x5211 #CJK UNIFIED IDEOGRAPH
+0xD0CD 0x578B #CJK UNIFIED IDEOGRAPH
+0xD0CE 0x5F62 #CJK UNIFIED IDEOGRAPH
+0xD0CF 0x90A2 #CJK UNIFIED IDEOGRAPH
+0xD0D0 0x884C #CJK UNIFIED IDEOGRAPH
+0xD0D1 0x9192 #CJK UNIFIED IDEOGRAPH
+0xD0D2 0x5E78 #CJK UNIFIED IDEOGRAPH
+0xD0D3 0x674F #CJK UNIFIED IDEOGRAPH
+0xD0D4 0x6027 #CJK UNIFIED IDEOGRAPH
+0xD0D5 0x59D3 #CJK UNIFIED IDEOGRAPH
+0xD0D6 0x5144 #CJK UNIFIED IDEOGRAPH
+0xD0D7 0x51F6 #CJK UNIFIED IDEOGRAPH
+0xD0D8 0x80F8 #CJK UNIFIED IDEOGRAPH
+0xD0D9 0x5308 #CJK UNIFIED IDEOGRAPH
+0xD0DA 0x6C79 #CJK UNIFIED IDEOGRAPH
+0xD0DB 0x96C4 #CJK UNIFIED IDEOGRAPH
+0xD0DC 0x718A #CJK UNIFIED IDEOGRAPH
+0xD0DD 0x4F11 #CJK UNIFIED IDEOGRAPH
+0xD0DE 0x4FEE #CJK UNIFIED IDEOGRAPH
+0xD0DF 0x7F9E #CJK UNIFIED IDEOGRAPH
+0xD0E0 0x673D #CJK UNIFIED IDEOGRAPH
+0xD0E1 0x55C5 #CJK UNIFIED IDEOGRAPH
+0xD0E2 0x9508 #CJK UNIFIED IDEOGRAPH
+0xD0E3 0x79C0 #CJK UNIFIED IDEOGRAPH
+0xD0E4 0x8896 #CJK UNIFIED IDEOGRAPH
+0xD0E5 0x7EE3 #CJK UNIFIED IDEOGRAPH
+0xD0E6 0x589F #CJK UNIFIED IDEOGRAPH
+0xD0E7 0x620C #CJK UNIFIED IDEOGRAPH
+0xD0E8 0x9700 #CJK UNIFIED IDEOGRAPH
+0xD0E9 0x865A #CJK UNIFIED IDEOGRAPH
+0xD0EA 0x5618 #CJK UNIFIED IDEOGRAPH
+0xD0EB 0x987B #CJK UNIFIED IDEOGRAPH
+0xD0EC 0x5F90 #CJK UNIFIED IDEOGRAPH
+0xD0ED 0x8BB8 #CJK UNIFIED IDEOGRAPH
+0xD0EE 0x84C4 #CJK UNIFIED IDEOGRAPH
+0xD0EF 0x9157 #CJK UNIFIED IDEOGRAPH
+0xD0F0 0x53D9 #CJK UNIFIED IDEOGRAPH
+0xD0F1 0x65ED #CJK UNIFIED IDEOGRAPH
+0xD0F2 0x5E8F #CJK UNIFIED IDEOGRAPH
+0xD0F3 0x755C #CJK UNIFIED IDEOGRAPH
+0xD0F4 0x6064 #CJK UNIFIED IDEOGRAPH
+0xD0F5 0x7D6E #CJK UNIFIED IDEOGRAPH
+0xD0F6 0x5A7F #CJK UNIFIED IDEOGRAPH
+0xD0F7 0x7EEA #CJK UNIFIED IDEOGRAPH
+0xD0F8 0x7EED #CJK UNIFIED IDEOGRAPH
+0xD0F9 0x8F69 #CJK UNIFIED IDEOGRAPH
+0xD0FA 0x55A7 #CJK UNIFIED IDEOGRAPH
+0xD0FB 0x5BA3 #CJK UNIFIED IDEOGRAPH
+0xD0FC 0x60AC #CJK UNIFIED IDEOGRAPH
+0xD0FD 0x65CB #CJK UNIFIED IDEOGRAPH
+0xD0FE 0x7384 #CJK UNIFIED IDEOGRAPH
+0xD140 0x88AC #CJK UNIFIED IDEOGRAPH
+0xD141 0x88AE #CJK UNIFIED IDEOGRAPH
+0xD142 0x88AF #CJK UNIFIED IDEOGRAPH
+0xD143 0x88B0 #CJK UNIFIED IDEOGRAPH
+0xD144 0x88B2 #CJK UNIFIED IDEOGRAPH
+0xD145 0x88B3 #CJK UNIFIED IDEOGRAPH
+0xD146 0x88B4 #CJK UNIFIED IDEOGRAPH
+0xD147 0x88B5 #CJK UNIFIED IDEOGRAPH
+0xD148 0x88B6 #CJK UNIFIED IDEOGRAPH
+0xD149 0x88B8 #CJK UNIFIED IDEOGRAPH
+0xD14A 0x88B9 #CJK UNIFIED IDEOGRAPH
+0xD14B 0x88BA #CJK UNIFIED IDEOGRAPH
+0xD14C 0x88BB #CJK UNIFIED IDEOGRAPH
+0xD14D 0x88BD #CJK UNIFIED IDEOGRAPH
+0xD14E 0x88BE #CJK UNIFIED IDEOGRAPH
+0xD14F 0x88BF #CJK UNIFIED IDEOGRAPH
+0xD150 0x88C0 #CJK UNIFIED IDEOGRAPH
+0xD151 0x88C3 #CJK UNIFIED IDEOGRAPH
+0xD152 0x88C4 #CJK UNIFIED IDEOGRAPH
+0xD153 0x88C7 #CJK UNIFIED IDEOGRAPH
+0xD154 0x88C8 #CJK UNIFIED IDEOGRAPH
+0xD155 0x88CA #CJK UNIFIED IDEOGRAPH
+0xD156 0x88CB #CJK UNIFIED IDEOGRAPH
+0xD157 0x88CC #CJK UNIFIED IDEOGRAPH
+0xD158 0x88CD #CJK UNIFIED IDEOGRAPH
+0xD159 0x88CF #CJK UNIFIED IDEOGRAPH
+0xD15A 0x88D0 #CJK UNIFIED IDEOGRAPH
+0xD15B 0x88D1 #CJK UNIFIED IDEOGRAPH
+0xD15C 0x88D3 #CJK UNIFIED IDEOGRAPH
+0xD15D 0x88D6 #CJK UNIFIED IDEOGRAPH
+0xD15E 0x88D7 #CJK UNIFIED IDEOGRAPH
+0xD15F 0x88DA #CJK UNIFIED IDEOGRAPH
+0xD160 0x88DB #CJK UNIFIED IDEOGRAPH
+0xD161 0x88DC #CJK UNIFIED IDEOGRAPH
+0xD162 0x88DD #CJK UNIFIED IDEOGRAPH
+0xD163 0x88DE #CJK UNIFIED IDEOGRAPH
+0xD164 0x88E0 #CJK UNIFIED IDEOGRAPH
+0xD165 0x88E1 #CJK UNIFIED IDEOGRAPH
+0xD166 0x88E6 #CJK UNIFIED IDEOGRAPH
+0xD167 0x88E7 #CJK UNIFIED IDEOGRAPH
+0xD168 0x88E9 #CJK UNIFIED IDEOGRAPH
+0xD169 0x88EA #CJK UNIFIED IDEOGRAPH
+0xD16A 0x88EB #CJK UNIFIED IDEOGRAPH
+0xD16B 0x88EC #CJK UNIFIED IDEOGRAPH
+0xD16C 0x88ED #CJK UNIFIED IDEOGRAPH
+0xD16D 0x88EE #CJK UNIFIED IDEOGRAPH
+0xD16E 0x88EF #CJK UNIFIED IDEOGRAPH
+0xD16F 0x88F2 #CJK UNIFIED IDEOGRAPH
+0xD170 0x88F5 #CJK UNIFIED IDEOGRAPH
+0xD171 0x88F6 #CJK UNIFIED IDEOGRAPH
+0xD172 0x88F7 #CJK UNIFIED IDEOGRAPH
+0xD173 0x88FA #CJK UNIFIED IDEOGRAPH
+0xD174 0x88FB #CJK UNIFIED IDEOGRAPH
+0xD175 0x88FD #CJK UNIFIED IDEOGRAPH
+0xD176 0x88FF #CJK UNIFIED IDEOGRAPH
+0xD177 0x8900 #CJK UNIFIED IDEOGRAPH
+0xD178 0x8901 #CJK UNIFIED IDEOGRAPH
+0xD179 0x8903 #CJK UNIFIED IDEOGRAPH
+0xD17A 0x8904 #CJK UNIFIED IDEOGRAPH
+0xD17B 0x8905 #CJK UNIFIED IDEOGRAPH
+0xD17C 0x8906 #CJK UNIFIED IDEOGRAPH
+0xD17D 0x8907 #CJK UNIFIED IDEOGRAPH
+0xD17E 0x8908 #CJK UNIFIED IDEOGRAPH
+0xD180 0x8909 #CJK UNIFIED IDEOGRAPH
+0xD181 0x890B #CJK UNIFIED IDEOGRAPH
+0xD182 0x890C #CJK UNIFIED IDEOGRAPH
+0xD183 0x890D #CJK UNIFIED IDEOGRAPH
+0xD184 0x890E #CJK UNIFIED IDEOGRAPH
+0xD185 0x890F #CJK UNIFIED IDEOGRAPH
+0xD186 0x8911 #CJK UNIFIED IDEOGRAPH
+0xD187 0x8914 #CJK UNIFIED IDEOGRAPH
+0xD188 0x8915 #CJK UNIFIED IDEOGRAPH
+0xD189 0x8916 #CJK UNIFIED IDEOGRAPH
+0xD18A 0x8917 #CJK UNIFIED IDEOGRAPH
+0xD18B 0x8918 #CJK UNIFIED IDEOGRAPH
+0xD18C 0x891C #CJK UNIFIED IDEOGRAPH
+0xD18D 0x891D #CJK UNIFIED IDEOGRAPH
+0xD18E 0x891E #CJK UNIFIED IDEOGRAPH
+0xD18F 0x891F #CJK UNIFIED IDEOGRAPH
+0xD190 0x8920 #CJK UNIFIED IDEOGRAPH
+0xD191 0x8922 #CJK UNIFIED IDEOGRAPH
+0xD192 0x8923 #CJK UNIFIED IDEOGRAPH
+0xD193 0x8924 #CJK UNIFIED IDEOGRAPH
+0xD194 0x8926 #CJK UNIFIED IDEOGRAPH
+0xD195 0x8927 #CJK UNIFIED IDEOGRAPH
+0xD196 0x8928 #CJK UNIFIED IDEOGRAPH
+0xD197 0x8929 #CJK UNIFIED IDEOGRAPH
+0xD198 0x892C #CJK UNIFIED IDEOGRAPH
+0xD199 0x892D #CJK UNIFIED IDEOGRAPH
+0xD19A 0x892E #CJK UNIFIED IDEOGRAPH
+0xD19B 0x892F #CJK UNIFIED IDEOGRAPH
+0xD19C 0x8931 #CJK UNIFIED IDEOGRAPH
+0xD19D 0x8932 #CJK UNIFIED IDEOGRAPH
+0xD19E 0x8933 #CJK UNIFIED IDEOGRAPH
+0xD19F 0x8935 #CJK UNIFIED IDEOGRAPH
+0xD1A0 0x8937 #CJK UNIFIED IDEOGRAPH
+0xD1A1 0x9009 #CJK UNIFIED IDEOGRAPH
+0xD1A2 0x7663 #CJK UNIFIED IDEOGRAPH
+0xD1A3 0x7729 #CJK UNIFIED IDEOGRAPH
+0xD1A4 0x7EDA #CJK UNIFIED IDEOGRAPH
+0xD1A5 0x9774 #CJK UNIFIED IDEOGRAPH
+0xD1A6 0x859B #CJK UNIFIED IDEOGRAPH
+0xD1A7 0x5B66 #CJK UNIFIED IDEOGRAPH
+0xD1A8 0x7A74 #CJK UNIFIED IDEOGRAPH
+0xD1A9 0x96EA #CJK UNIFIED IDEOGRAPH
+0xD1AA 0x8840 #CJK UNIFIED IDEOGRAPH
+0xD1AB 0x52CB #CJK UNIFIED IDEOGRAPH
+0xD1AC 0x718F #CJK UNIFIED IDEOGRAPH
+0xD1AD 0x5FAA #CJK UNIFIED IDEOGRAPH
+0xD1AE 0x65EC #CJK UNIFIED IDEOGRAPH
+0xD1AF 0x8BE2 #CJK UNIFIED IDEOGRAPH
+0xD1B0 0x5BFB #CJK UNIFIED IDEOGRAPH
+0xD1B1 0x9A6F #CJK UNIFIED IDEOGRAPH
+0xD1B2 0x5DE1 #CJK UNIFIED IDEOGRAPH
+0xD1B3 0x6B89 #CJK UNIFIED IDEOGRAPH
+0xD1B4 0x6C5B #CJK UNIFIED IDEOGRAPH
+0xD1B5 0x8BAD #CJK UNIFIED IDEOGRAPH
+0xD1B6 0x8BAF #CJK UNIFIED IDEOGRAPH
+0xD1B7 0x900A #CJK UNIFIED IDEOGRAPH
+0xD1B8 0x8FC5 #CJK UNIFIED IDEOGRAPH
+0xD1B9 0x538B #CJK UNIFIED IDEOGRAPH
+0xD1BA 0x62BC #CJK UNIFIED IDEOGRAPH
+0xD1BB 0x9E26 #CJK UNIFIED IDEOGRAPH
+0xD1BC 0x9E2D #CJK UNIFIED IDEOGRAPH
+0xD1BD 0x5440 #CJK UNIFIED IDEOGRAPH
+0xD1BE 0x4E2B #CJK UNIFIED IDEOGRAPH
+0xD1BF 0x82BD #CJK UNIFIED IDEOGRAPH
+0xD1C0 0x7259 #CJK UNIFIED IDEOGRAPH
+0xD1C1 0x869C #CJK UNIFIED IDEOGRAPH
+0xD1C2 0x5D16 #CJK UNIFIED IDEOGRAPH
+0xD1C3 0x8859 #CJK UNIFIED IDEOGRAPH
+0xD1C4 0x6DAF #CJK UNIFIED IDEOGRAPH
+0xD1C5 0x96C5 #CJK UNIFIED IDEOGRAPH
+0xD1C6 0x54D1 #CJK UNIFIED IDEOGRAPH
+0xD1C7 0x4E9A #CJK UNIFIED IDEOGRAPH
+0xD1C8 0x8BB6 #CJK UNIFIED IDEOGRAPH
+0xD1C9 0x7109 #CJK UNIFIED IDEOGRAPH
+0xD1CA 0x54BD #CJK UNIFIED IDEOGRAPH
+0xD1CB 0x9609 #CJK UNIFIED IDEOGRAPH
+0xD1CC 0x70DF #CJK UNIFIED IDEOGRAPH
+0xD1CD 0x6DF9 #CJK UNIFIED IDEOGRAPH
+0xD1CE 0x76D0 #CJK UNIFIED IDEOGRAPH
+0xD1CF 0x4E25 #CJK UNIFIED IDEOGRAPH
+0xD1D0 0x7814 #CJK UNIFIED IDEOGRAPH
+0xD1D1 0x8712 #CJK UNIFIED IDEOGRAPH
+0xD1D2 0x5CA9 #CJK UNIFIED IDEOGRAPH
+0xD1D3 0x5EF6 #CJK UNIFIED IDEOGRAPH
+0xD1D4 0x8A00 #CJK UNIFIED IDEOGRAPH
+0xD1D5 0x989C #CJK UNIFIED IDEOGRAPH
+0xD1D6 0x960E #CJK UNIFIED IDEOGRAPH
+0xD1D7 0x708E #CJK UNIFIED IDEOGRAPH
+0xD1D8 0x6CBF #CJK UNIFIED IDEOGRAPH
+0xD1D9 0x5944 #CJK UNIFIED IDEOGRAPH
+0xD1DA 0x63A9 #CJK UNIFIED IDEOGRAPH
+0xD1DB 0x773C #CJK UNIFIED IDEOGRAPH
+0xD1DC 0x884D #CJK UNIFIED IDEOGRAPH
+0xD1DD 0x6F14 #CJK UNIFIED IDEOGRAPH
+0xD1DE 0x8273 #CJK UNIFIED IDEOGRAPH
+0xD1DF 0x5830 #CJK UNIFIED IDEOGRAPH
+0xD1E0 0x71D5 #CJK UNIFIED IDEOGRAPH
+0xD1E1 0x538C #CJK UNIFIED IDEOGRAPH
+0xD1E2 0x781A #CJK UNIFIED IDEOGRAPH
+0xD1E3 0x96C1 #CJK UNIFIED IDEOGRAPH
+0xD1E4 0x5501 #CJK UNIFIED IDEOGRAPH
+0xD1E5 0x5F66 #CJK UNIFIED IDEOGRAPH
+0xD1E6 0x7130 #CJK UNIFIED IDEOGRAPH
+0xD1E7 0x5BB4 #CJK UNIFIED IDEOGRAPH
+0xD1E8 0x8C1A #CJK UNIFIED IDEOGRAPH
+0xD1E9 0x9A8C #CJK UNIFIED IDEOGRAPH
+0xD1EA 0x6B83 #CJK UNIFIED IDEOGRAPH
+0xD1EB 0x592E #CJK UNIFIED IDEOGRAPH
+0xD1EC 0x9E2F #CJK UNIFIED IDEOGRAPH
+0xD1ED 0x79E7 #CJK UNIFIED IDEOGRAPH
+0xD1EE 0x6768 #CJK UNIFIED IDEOGRAPH
+0xD1EF 0x626C #CJK UNIFIED IDEOGRAPH
+0xD1F0 0x4F6F #CJK UNIFIED IDEOGRAPH
+0xD1F1 0x75A1 #CJK UNIFIED IDEOGRAPH
+0xD1F2 0x7F8A #CJK UNIFIED IDEOGRAPH
+0xD1F3 0x6D0B #CJK UNIFIED IDEOGRAPH
+0xD1F4 0x9633 #CJK UNIFIED IDEOGRAPH
+0xD1F5 0x6C27 #CJK UNIFIED IDEOGRAPH
+0xD1F6 0x4EF0 #CJK UNIFIED IDEOGRAPH
+0xD1F7 0x75D2 #CJK UNIFIED IDEOGRAPH
+0xD1F8 0x517B #CJK UNIFIED IDEOGRAPH
+0xD1F9 0x6837 #CJK UNIFIED IDEOGRAPH
+0xD1FA 0x6F3E #CJK UNIFIED IDEOGRAPH
+0xD1FB 0x9080 #CJK UNIFIED IDEOGRAPH
+0xD1FC 0x8170 #CJK UNIFIED IDEOGRAPH
+0xD1FD 0x5996 #CJK UNIFIED IDEOGRAPH
+0xD1FE 0x7476 #CJK UNIFIED IDEOGRAPH
+0xD240 0x8938 #CJK UNIFIED IDEOGRAPH
+0xD241 0x8939 #CJK UNIFIED IDEOGRAPH
+0xD242 0x893A #CJK UNIFIED IDEOGRAPH
+0xD243 0x893B #CJK UNIFIED IDEOGRAPH
+0xD244 0x893C #CJK UNIFIED IDEOGRAPH
+0xD245 0x893D #CJK UNIFIED IDEOGRAPH
+0xD246 0x893E #CJK UNIFIED IDEOGRAPH
+0xD247 0x893F #CJK UNIFIED IDEOGRAPH
+0xD248 0x8940 #CJK UNIFIED IDEOGRAPH
+0xD249 0x8942 #CJK UNIFIED IDEOGRAPH
+0xD24A 0x8943 #CJK UNIFIED IDEOGRAPH
+0xD24B 0x8945 #CJK UNIFIED IDEOGRAPH
+0xD24C 0x8946 #CJK UNIFIED IDEOGRAPH
+0xD24D 0x8947 #CJK UNIFIED IDEOGRAPH
+0xD24E 0x8948 #CJK UNIFIED IDEOGRAPH
+0xD24F 0x8949 #CJK UNIFIED IDEOGRAPH
+0xD250 0x894A #CJK UNIFIED IDEOGRAPH
+0xD251 0x894B #CJK UNIFIED IDEOGRAPH
+0xD252 0x894C #CJK UNIFIED IDEOGRAPH
+0xD253 0x894D #CJK UNIFIED IDEOGRAPH
+0xD254 0x894E #CJK UNIFIED IDEOGRAPH
+0xD255 0x894F #CJK UNIFIED IDEOGRAPH
+0xD256 0x8950 #CJK UNIFIED IDEOGRAPH
+0xD257 0x8951 #CJK UNIFIED IDEOGRAPH
+0xD258 0x8952 #CJK UNIFIED IDEOGRAPH
+0xD259 0x8953 #CJK UNIFIED IDEOGRAPH
+0xD25A 0x8954 #CJK UNIFIED IDEOGRAPH
+0xD25B 0x8955 #CJK UNIFIED IDEOGRAPH
+0xD25C 0x8956 #CJK UNIFIED IDEOGRAPH
+0xD25D 0x8957 #CJK UNIFIED IDEOGRAPH
+0xD25E 0x8958 #CJK UNIFIED IDEOGRAPH
+0xD25F 0x8959 #CJK UNIFIED IDEOGRAPH
+0xD260 0x895A #CJK UNIFIED IDEOGRAPH
+0xD261 0x895B #CJK UNIFIED IDEOGRAPH
+0xD262 0x895C #CJK UNIFIED IDEOGRAPH
+0xD263 0x895D #CJK UNIFIED IDEOGRAPH
+0xD264 0x8960 #CJK UNIFIED IDEOGRAPH
+0xD265 0x8961 #CJK UNIFIED IDEOGRAPH
+0xD266 0x8962 #CJK UNIFIED IDEOGRAPH
+0xD267 0x8963 #CJK UNIFIED IDEOGRAPH
+0xD268 0x8964 #CJK UNIFIED IDEOGRAPH
+0xD269 0x8965 #CJK UNIFIED IDEOGRAPH
+0xD26A 0x8967 #CJK UNIFIED IDEOGRAPH
+0xD26B 0x8968 #CJK UNIFIED IDEOGRAPH
+0xD26C 0x8969 #CJK UNIFIED IDEOGRAPH
+0xD26D 0x896A #CJK UNIFIED IDEOGRAPH
+0xD26E 0x896B #CJK UNIFIED IDEOGRAPH
+0xD26F 0x896C #CJK UNIFIED IDEOGRAPH
+0xD270 0x896D #CJK UNIFIED IDEOGRAPH
+0xD271 0x896E #CJK UNIFIED IDEOGRAPH
+0xD272 0x896F #CJK UNIFIED IDEOGRAPH
+0xD273 0x8970 #CJK UNIFIED IDEOGRAPH
+0xD274 0x8971 #CJK UNIFIED IDEOGRAPH
+0xD275 0x8972 #CJK UNIFIED IDEOGRAPH
+0xD276 0x8973 #CJK UNIFIED IDEOGRAPH
+0xD277 0x8974 #CJK UNIFIED IDEOGRAPH
+0xD278 0x8975 #CJK UNIFIED IDEOGRAPH
+0xD279 0x8976 #CJK UNIFIED IDEOGRAPH
+0xD27A 0x8977 #CJK UNIFIED IDEOGRAPH
+0xD27B 0x8978 #CJK UNIFIED IDEOGRAPH
+0xD27C 0x8979 #CJK UNIFIED IDEOGRAPH
+0xD27D 0x897A #CJK UNIFIED IDEOGRAPH
+0xD27E 0x897C #CJK UNIFIED IDEOGRAPH
+0xD280 0x897D #CJK UNIFIED IDEOGRAPH
+0xD281 0x897E #CJK UNIFIED IDEOGRAPH
+0xD282 0x8980 #CJK UNIFIED IDEOGRAPH
+0xD283 0x8982 #CJK UNIFIED IDEOGRAPH
+0xD284 0x8984 #CJK UNIFIED IDEOGRAPH
+0xD285 0x8985 #CJK UNIFIED IDEOGRAPH
+0xD286 0x8987 #CJK UNIFIED IDEOGRAPH
+0xD287 0x8988 #CJK UNIFIED IDEOGRAPH
+0xD288 0x8989 #CJK UNIFIED IDEOGRAPH
+0xD289 0x898A #CJK UNIFIED IDEOGRAPH
+0xD28A 0x898B #CJK UNIFIED IDEOGRAPH
+0xD28B 0x898C #CJK UNIFIED IDEOGRAPH
+0xD28C 0x898D #CJK UNIFIED IDEOGRAPH
+0xD28D 0x898E #CJK UNIFIED IDEOGRAPH
+0xD28E 0x898F #CJK UNIFIED IDEOGRAPH
+0xD28F 0x8990 #CJK UNIFIED IDEOGRAPH
+0xD290 0x8991 #CJK UNIFIED IDEOGRAPH
+0xD291 0x8992 #CJK UNIFIED IDEOGRAPH
+0xD292 0x8993 #CJK UNIFIED IDEOGRAPH
+0xD293 0x8994 #CJK UNIFIED IDEOGRAPH
+0xD294 0x8995 #CJK UNIFIED IDEOGRAPH
+0xD295 0x8996 #CJK UNIFIED IDEOGRAPH
+0xD296 0x8997 #CJK UNIFIED IDEOGRAPH
+0xD297 0x8998 #CJK UNIFIED IDEOGRAPH
+0xD298 0x8999 #CJK UNIFIED IDEOGRAPH
+0xD299 0x899A #CJK UNIFIED IDEOGRAPH
+0xD29A 0x899B #CJK UNIFIED IDEOGRAPH
+0xD29B 0x899C #CJK UNIFIED IDEOGRAPH
+0xD29C 0x899D #CJK UNIFIED IDEOGRAPH
+0xD29D 0x899E #CJK UNIFIED IDEOGRAPH
+0xD29E 0x899F #CJK UNIFIED IDEOGRAPH
+0xD29F 0x89A0 #CJK UNIFIED IDEOGRAPH
+0xD2A0 0x89A1 #CJK UNIFIED IDEOGRAPH
+0xD2A1 0x6447 #CJK UNIFIED IDEOGRAPH
+0xD2A2 0x5C27 #CJK UNIFIED IDEOGRAPH
+0xD2A3 0x9065 #CJK UNIFIED IDEOGRAPH
+0xD2A4 0x7A91 #CJK UNIFIED IDEOGRAPH
+0xD2A5 0x8C23 #CJK UNIFIED IDEOGRAPH
+0xD2A6 0x59DA #CJK UNIFIED IDEOGRAPH
+0xD2A7 0x54AC #CJK UNIFIED IDEOGRAPH
+0xD2A8 0x8200 #CJK UNIFIED IDEOGRAPH
+0xD2A9 0x836F #CJK UNIFIED IDEOGRAPH
+0xD2AA 0x8981 #CJK UNIFIED IDEOGRAPH
+0xD2AB 0x8000 #CJK UNIFIED IDEOGRAPH
+0xD2AC 0x6930 #CJK UNIFIED IDEOGRAPH
+0xD2AD 0x564E #CJK UNIFIED IDEOGRAPH
+0xD2AE 0x8036 #CJK UNIFIED IDEOGRAPH
+0xD2AF 0x7237 #CJK UNIFIED IDEOGRAPH
+0xD2B0 0x91CE #CJK UNIFIED IDEOGRAPH
+0xD2B1 0x51B6 #CJK UNIFIED IDEOGRAPH
+0xD2B2 0x4E5F #CJK UNIFIED IDEOGRAPH
+0xD2B3 0x9875 #CJK UNIFIED IDEOGRAPH
+0xD2B4 0x6396 #CJK UNIFIED IDEOGRAPH
+0xD2B5 0x4E1A #CJK UNIFIED IDEOGRAPH
+0xD2B6 0x53F6 #CJK UNIFIED IDEOGRAPH
+0xD2B7 0x66F3 #CJK UNIFIED IDEOGRAPH
+0xD2B8 0x814B #CJK UNIFIED IDEOGRAPH
+0xD2B9 0x591C #CJK UNIFIED IDEOGRAPH
+0xD2BA 0x6DB2 #CJK UNIFIED IDEOGRAPH
+0xD2BB 0x4E00 #CJK UNIFIED IDEOGRAPH
+0xD2BC 0x58F9 #CJK UNIFIED IDEOGRAPH
+0xD2BD 0x533B #CJK UNIFIED IDEOGRAPH
+0xD2BE 0x63D6 #CJK UNIFIED IDEOGRAPH
+0xD2BF 0x94F1 #CJK UNIFIED IDEOGRAPH
+0xD2C0 0x4F9D #CJK UNIFIED IDEOGRAPH
+0xD2C1 0x4F0A #CJK UNIFIED IDEOGRAPH
+0xD2C2 0x8863 #CJK UNIFIED IDEOGRAPH
+0xD2C3 0x9890 #CJK UNIFIED IDEOGRAPH
+0xD2C4 0x5937 #CJK UNIFIED IDEOGRAPH
+0xD2C5 0x9057 #CJK UNIFIED IDEOGRAPH
+0xD2C6 0x79FB #CJK UNIFIED IDEOGRAPH
+0xD2C7 0x4EEA #CJK UNIFIED IDEOGRAPH
+0xD2C8 0x80F0 #CJK UNIFIED IDEOGRAPH
+0xD2C9 0x7591 #CJK UNIFIED IDEOGRAPH
+0xD2CA 0x6C82 #CJK UNIFIED IDEOGRAPH
+0xD2CB 0x5B9C #CJK UNIFIED IDEOGRAPH
+0xD2CC 0x59E8 #CJK UNIFIED IDEOGRAPH
+0xD2CD 0x5F5D #CJK UNIFIED IDEOGRAPH
+0xD2CE 0x6905 #CJK UNIFIED IDEOGRAPH
+0xD2CF 0x8681 #CJK UNIFIED IDEOGRAPH
+0xD2D0 0x501A #CJK UNIFIED IDEOGRAPH
+0xD2D1 0x5DF2 #CJK UNIFIED IDEOGRAPH
+0xD2D2 0x4E59 #CJK UNIFIED IDEOGRAPH
+0xD2D3 0x77E3 #CJK UNIFIED IDEOGRAPH
+0xD2D4 0x4EE5 #CJK UNIFIED IDEOGRAPH
+0xD2D5 0x827A #CJK UNIFIED IDEOGRAPH
+0xD2D6 0x6291 #CJK UNIFIED IDEOGRAPH
+0xD2D7 0x6613 #CJK UNIFIED IDEOGRAPH
+0xD2D8 0x9091 #CJK UNIFIED IDEOGRAPH
+0xD2D9 0x5C79 #CJK UNIFIED IDEOGRAPH
+0xD2DA 0x4EBF #CJK UNIFIED IDEOGRAPH
+0xD2DB 0x5F79 #CJK UNIFIED IDEOGRAPH
+0xD2DC 0x81C6 #CJK UNIFIED IDEOGRAPH
+0xD2DD 0x9038 #CJK UNIFIED IDEOGRAPH
+0xD2DE 0x8084 #CJK UNIFIED IDEOGRAPH
+0xD2DF 0x75AB #CJK UNIFIED IDEOGRAPH
+0xD2E0 0x4EA6 #CJK UNIFIED IDEOGRAPH
+0xD2E1 0x88D4 #CJK UNIFIED IDEOGRAPH
+0xD2E2 0x610F #CJK UNIFIED IDEOGRAPH
+0xD2E3 0x6BC5 #CJK UNIFIED IDEOGRAPH
+0xD2E4 0x5FC6 #CJK UNIFIED IDEOGRAPH
+0xD2E5 0x4E49 #CJK UNIFIED IDEOGRAPH
+0xD2E6 0x76CA #CJK UNIFIED IDEOGRAPH
+0xD2E7 0x6EA2 #CJK UNIFIED IDEOGRAPH
+0xD2E8 0x8BE3 #CJK UNIFIED IDEOGRAPH
+0xD2E9 0x8BAE #CJK UNIFIED IDEOGRAPH
+0xD2EA 0x8C0A #CJK UNIFIED IDEOGRAPH
+0xD2EB 0x8BD1 #CJK UNIFIED IDEOGRAPH
+0xD2EC 0x5F02 #CJK UNIFIED IDEOGRAPH
+0xD2ED 0x7FFC #CJK UNIFIED IDEOGRAPH
+0xD2EE 0x7FCC #CJK UNIFIED IDEOGRAPH
+0xD2EF 0x7ECE #CJK UNIFIED IDEOGRAPH
+0xD2F0 0x8335 #CJK UNIFIED IDEOGRAPH
+0xD2F1 0x836B #CJK UNIFIED IDEOGRAPH
+0xD2F2 0x56E0 #CJK UNIFIED IDEOGRAPH
+0xD2F3 0x6BB7 #CJK UNIFIED IDEOGRAPH
+0xD2F4 0x97F3 #CJK UNIFIED IDEOGRAPH
+0xD2F5 0x9634 #CJK UNIFIED IDEOGRAPH
+0xD2F6 0x59FB #CJK UNIFIED IDEOGRAPH
+0xD2F7 0x541F #CJK UNIFIED IDEOGRAPH
+0xD2F8 0x94F6 #CJK UNIFIED IDEOGRAPH
+0xD2F9 0x6DEB #CJK UNIFIED IDEOGRAPH
+0xD2FA 0x5BC5 #CJK UNIFIED IDEOGRAPH
+0xD2FB 0x996E #CJK UNIFIED IDEOGRAPH
+0xD2FC 0x5C39 #CJK UNIFIED IDEOGRAPH
+0xD2FD 0x5F15 #CJK UNIFIED IDEOGRAPH
+0xD2FE 0x9690 #CJK UNIFIED IDEOGRAPH
+0xD340 0x89A2 #CJK UNIFIED IDEOGRAPH
+0xD341 0x89A3 #CJK UNIFIED IDEOGRAPH
+0xD342 0x89A4 #CJK UNIFIED IDEOGRAPH
+0xD343 0x89A5 #CJK UNIFIED IDEOGRAPH
+0xD344 0x89A6 #CJK UNIFIED IDEOGRAPH
+0xD345 0x89A7 #CJK UNIFIED IDEOGRAPH
+0xD346 0x89A8 #CJK UNIFIED IDEOGRAPH
+0xD347 0x89A9 #CJK UNIFIED IDEOGRAPH
+0xD348 0x89AA #CJK UNIFIED IDEOGRAPH
+0xD349 0x89AB #CJK UNIFIED IDEOGRAPH
+0xD34A 0x89AC #CJK UNIFIED IDEOGRAPH
+0xD34B 0x89AD #CJK UNIFIED IDEOGRAPH
+0xD34C 0x89AE #CJK UNIFIED IDEOGRAPH
+0xD34D 0x89AF #CJK UNIFIED IDEOGRAPH
+0xD34E 0x89B0 #CJK UNIFIED IDEOGRAPH
+0xD34F 0x89B1 #CJK UNIFIED IDEOGRAPH
+0xD350 0x89B2 #CJK UNIFIED IDEOGRAPH
+0xD351 0x89B3 #CJK UNIFIED IDEOGRAPH
+0xD352 0x89B4 #CJK UNIFIED IDEOGRAPH
+0xD353 0x89B5 #CJK UNIFIED IDEOGRAPH
+0xD354 0x89B6 #CJK UNIFIED IDEOGRAPH
+0xD355 0x89B7 #CJK UNIFIED IDEOGRAPH
+0xD356 0x89B8 #CJK UNIFIED IDEOGRAPH
+0xD357 0x89B9 #CJK UNIFIED IDEOGRAPH
+0xD358 0x89BA #CJK UNIFIED IDEOGRAPH
+0xD359 0x89BB #CJK UNIFIED IDEOGRAPH
+0xD35A 0x89BC #CJK UNIFIED IDEOGRAPH
+0xD35B 0x89BD #CJK UNIFIED IDEOGRAPH
+0xD35C 0x89BE #CJK UNIFIED IDEOGRAPH
+0xD35D 0x89BF #CJK UNIFIED IDEOGRAPH
+0xD35E 0x89C0 #CJK UNIFIED IDEOGRAPH
+0xD35F 0x89C3 #CJK UNIFIED IDEOGRAPH
+0xD360 0x89CD #CJK UNIFIED IDEOGRAPH
+0xD361 0x89D3 #CJK UNIFIED IDEOGRAPH
+0xD362 0x89D4 #CJK UNIFIED IDEOGRAPH
+0xD363 0x89D5 #CJK UNIFIED IDEOGRAPH
+0xD364 0x89D7 #CJK UNIFIED IDEOGRAPH
+0xD365 0x89D8 #CJK UNIFIED IDEOGRAPH
+0xD366 0x89D9 #CJK UNIFIED IDEOGRAPH
+0xD367 0x89DB #CJK UNIFIED IDEOGRAPH
+0xD368 0x89DD #CJK UNIFIED IDEOGRAPH
+0xD369 0x89DF #CJK UNIFIED IDEOGRAPH
+0xD36A 0x89E0 #CJK UNIFIED IDEOGRAPH
+0xD36B 0x89E1 #CJK UNIFIED IDEOGRAPH
+0xD36C 0x89E2 #CJK UNIFIED IDEOGRAPH
+0xD36D 0x89E4 #CJK UNIFIED IDEOGRAPH
+0xD36E 0x89E7 #CJK UNIFIED IDEOGRAPH
+0xD36F 0x89E8 #CJK UNIFIED IDEOGRAPH
+0xD370 0x89E9 #CJK UNIFIED IDEOGRAPH
+0xD371 0x89EA #CJK UNIFIED IDEOGRAPH
+0xD372 0x89EC #CJK UNIFIED IDEOGRAPH
+0xD373 0x89ED #CJK UNIFIED IDEOGRAPH
+0xD374 0x89EE #CJK UNIFIED IDEOGRAPH
+0xD375 0x89F0 #CJK UNIFIED IDEOGRAPH
+0xD376 0x89F1 #CJK UNIFIED IDEOGRAPH
+0xD377 0x89F2 #CJK UNIFIED IDEOGRAPH
+0xD378 0x89F4 #CJK UNIFIED IDEOGRAPH
+0xD379 0x89F5 #CJK UNIFIED IDEOGRAPH
+0xD37A 0x89F6 #CJK UNIFIED IDEOGRAPH
+0xD37B 0x89F7 #CJK UNIFIED IDEOGRAPH
+0xD37C 0x89F8 #CJK UNIFIED IDEOGRAPH
+0xD37D 0x89F9 #CJK UNIFIED IDEOGRAPH
+0xD37E 0x89FA #CJK UNIFIED IDEOGRAPH
+0xD380 0x89FB #CJK UNIFIED IDEOGRAPH
+0xD381 0x89FC #CJK UNIFIED IDEOGRAPH
+0xD382 0x89FD #CJK UNIFIED IDEOGRAPH
+0xD383 0x89FE #CJK UNIFIED IDEOGRAPH
+0xD384 0x89FF #CJK UNIFIED IDEOGRAPH
+0xD385 0x8A01 #CJK UNIFIED IDEOGRAPH
+0xD386 0x8A02 #CJK UNIFIED IDEOGRAPH
+0xD387 0x8A03 #CJK UNIFIED IDEOGRAPH
+0xD388 0x8A04 #CJK UNIFIED IDEOGRAPH
+0xD389 0x8A05 #CJK UNIFIED IDEOGRAPH
+0xD38A 0x8A06 #CJK UNIFIED IDEOGRAPH
+0xD38B 0x8A08 #CJK UNIFIED IDEOGRAPH
+0xD38C 0x8A09 #CJK UNIFIED IDEOGRAPH
+0xD38D 0x8A0A #CJK UNIFIED IDEOGRAPH
+0xD38E 0x8A0B #CJK UNIFIED IDEOGRAPH
+0xD38F 0x8A0C #CJK UNIFIED IDEOGRAPH
+0xD390 0x8A0D #CJK UNIFIED IDEOGRAPH
+0xD391 0x8A0E #CJK UNIFIED IDEOGRAPH
+0xD392 0x8A0F #CJK UNIFIED IDEOGRAPH
+0xD393 0x8A10 #CJK UNIFIED IDEOGRAPH
+0xD394 0x8A11 #CJK UNIFIED IDEOGRAPH
+0xD395 0x8A12 #CJK UNIFIED IDEOGRAPH
+0xD396 0x8A13 #CJK UNIFIED IDEOGRAPH
+0xD397 0x8A14 #CJK UNIFIED IDEOGRAPH
+0xD398 0x8A15 #CJK UNIFIED IDEOGRAPH
+0xD399 0x8A16 #CJK UNIFIED IDEOGRAPH
+0xD39A 0x8A17 #CJK UNIFIED IDEOGRAPH
+0xD39B 0x8A18 #CJK UNIFIED IDEOGRAPH
+0xD39C 0x8A19 #CJK UNIFIED IDEOGRAPH
+0xD39D 0x8A1A #CJK UNIFIED IDEOGRAPH
+0xD39E 0x8A1B #CJK UNIFIED IDEOGRAPH
+0xD39F 0x8A1C #CJK UNIFIED IDEOGRAPH
+0xD3A0 0x8A1D #CJK UNIFIED IDEOGRAPH
+0xD3A1 0x5370 #CJK UNIFIED IDEOGRAPH
+0xD3A2 0x82F1 #CJK UNIFIED IDEOGRAPH
+0xD3A3 0x6A31 #CJK UNIFIED IDEOGRAPH
+0xD3A4 0x5A74 #CJK UNIFIED IDEOGRAPH
+0xD3A5 0x9E70 #CJK UNIFIED IDEOGRAPH
+0xD3A6 0x5E94 #CJK UNIFIED IDEOGRAPH
+0xD3A7 0x7F28 #CJK UNIFIED IDEOGRAPH
+0xD3A8 0x83B9 #CJK UNIFIED IDEOGRAPH
+0xD3A9 0x8424 #CJK UNIFIED IDEOGRAPH
+0xD3AA 0x8425 #CJK UNIFIED IDEOGRAPH
+0xD3AB 0x8367 #CJK UNIFIED IDEOGRAPH
+0xD3AC 0x8747 #CJK UNIFIED IDEOGRAPH
+0xD3AD 0x8FCE #CJK UNIFIED IDEOGRAPH
+0xD3AE 0x8D62 #CJK UNIFIED IDEOGRAPH
+0xD3AF 0x76C8 #CJK UNIFIED IDEOGRAPH
+0xD3B0 0x5F71 #CJK UNIFIED IDEOGRAPH
+0xD3B1 0x9896 #CJK UNIFIED IDEOGRAPH
+0xD3B2 0x786C #CJK UNIFIED IDEOGRAPH
+0xD3B3 0x6620 #CJK UNIFIED IDEOGRAPH
+0xD3B4 0x54DF #CJK UNIFIED IDEOGRAPH
+0xD3B5 0x62E5 #CJK UNIFIED IDEOGRAPH
+0xD3B6 0x4F63 #CJK UNIFIED IDEOGRAPH
+0xD3B7 0x81C3 #CJK UNIFIED IDEOGRAPH
+0xD3B8 0x75C8 #CJK UNIFIED IDEOGRAPH
+0xD3B9 0x5EB8 #CJK UNIFIED IDEOGRAPH
+0xD3BA 0x96CD #CJK UNIFIED IDEOGRAPH
+0xD3BB 0x8E0A #CJK UNIFIED IDEOGRAPH
+0xD3BC 0x86F9 #CJK UNIFIED IDEOGRAPH
+0xD3BD 0x548F #CJK UNIFIED IDEOGRAPH
+0xD3BE 0x6CF3 #CJK UNIFIED IDEOGRAPH
+0xD3BF 0x6D8C #CJK UNIFIED IDEOGRAPH
+0xD3C0 0x6C38 #CJK UNIFIED IDEOGRAPH
+0xD3C1 0x607F #CJK UNIFIED IDEOGRAPH
+0xD3C2 0x52C7 #CJK UNIFIED IDEOGRAPH
+0xD3C3 0x7528 #CJK UNIFIED IDEOGRAPH
+0xD3C4 0x5E7D #CJK UNIFIED IDEOGRAPH
+0xD3C5 0x4F18 #CJK UNIFIED IDEOGRAPH
+0xD3C6 0x60A0 #CJK UNIFIED IDEOGRAPH
+0xD3C7 0x5FE7 #CJK UNIFIED IDEOGRAPH
+0xD3C8 0x5C24 #CJK UNIFIED IDEOGRAPH
+0xD3C9 0x7531 #CJK UNIFIED IDEOGRAPH
+0xD3CA 0x90AE #CJK UNIFIED IDEOGRAPH
+0xD3CB 0x94C0 #CJK UNIFIED IDEOGRAPH
+0xD3CC 0x72B9 #CJK UNIFIED IDEOGRAPH
+0xD3CD 0x6CB9 #CJK UNIFIED IDEOGRAPH
+0xD3CE 0x6E38 #CJK UNIFIED IDEOGRAPH
+0xD3CF 0x9149 #CJK UNIFIED IDEOGRAPH
+0xD3D0 0x6709 #CJK UNIFIED IDEOGRAPH
+0xD3D1 0x53CB #CJK UNIFIED IDEOGRAPH
+0xD3D2 0x53F3 #CJK UNIFIED IDEOGRAPH
+0xD3D3 0x4F51 #CJK UNIFIED IDEOGRAPH
+0xD3D4 0x91C9 #CJK UNIFIED IDEOGRAPH
+0xD3D5 0x8BF1 #CJK UNIFIED IDEOGRAPH
+0xD3D6 0x53C8 #CJK UNIFIED IDEOGRAPH
+0xD3D7 0x5E7C #CJK UNIFIED IDEOGRAPH
+0xD3D8 0x8FC2 #CJK UNIFIED IDEOGRAPH
+0xD3D9 0x6DE4 #CJK UNIFIED IDEOGRAPH
+0xD3DA 0x4E8E #CJK UNIFIED IDEOGRAPH
+0xD3DB 0x76C2 #CJK UNIFIED IDEOGRAPH
+0xD3DC 0x6986 #CJK UNIFIED IDEOGRAPH
+0xD3DD 0x865E #CJK UNIFIED IDEOGRAPH
+0xD3DE 0x611A #CJK UNIFIED IDEOGRAPH
+0xD3DF 0x8206 #CJK UNIFIED IDEOGRAPH
+0xD3E0 0x4F59 #CJK UNIFIED IDEOGRAPH
+0xD3E1 0x4FDE #CJK UNIFIED IDEOGRAPH
+0xD3E2 0x903E #CJK UNIFIED IDEOGRAPH
+0xD3E3 0x9C7C #CJK UNIFIED IDEOGRAPH
+0xD3E4 0x6109 #CJK UNIFIED IDEOGRAPH
+0xD3E5 0x6E1D #CJK UNIFIED IDEOGRAPH
+0xD3E6 0x6E14 #CJK UNIFIED IDEOGRAPH
+0xD3E7 0x9685 #CJK UNIFIED IDEOGRAPH
+0xD3E8 0x4E88 #CJK UNIFIED IDEOGRAPH
+0xD3E9 0x5A31 #CJK UNIFIED IDEOGRAPH
+0xD3EA 0x96E8 #CJK UNIFIED IDEOGRAPH
+0xD3EB 0x4E0E #CJK UNIFIED IDEOGRAPH
+0xD3EC 0x5C7F #CJK UNIFIED IDEOGRAPH
+0xD3ED 0x79B9 #CJK UNIFIED IDEOGRAPH
+0xD3EE 0x5B87 #CJK UNIFIED IDEOGRAPH
+0xD3EF 0x8BED #CJK UNIFIED IDEOGRAPH
+0xD3F0 0x7FBD #CJK UNIFIED IDEOGRAPH
+0xD3F1 0x7389 #CJK UNIFIED IDEOGRAPH
+0xD3F2 0x57DF #CJK UNIFIED IDEOGRAPH
+0xD3F3 0x828B #CJK UNIFIED IDEOGRAPH
+0xD3F4 0x90C1 #CJK UNIFIED IDEOGRAPH
+0xD3F5 0x5401 #CJK UNIFIED IDEOGRAPH
+0xD3F6 0x9047 #CJK UNIFIED IDEOGRAPH
+0xD3F7 0x55BB #CJK UNIFIED IDEOGRAPH
+0xD3F8 0x5CEA #CJK UNIFIED IDEOGRAPH
+0xD3F9 0x5FA1 #CJK UNIFIED IDEOGRAPH
+0xD3FA 0x6108 #CJK UNIFIED IDEOGRAPH
+0xD3FB 0x6B32 #CJK UNIFIED IDEOGRAPH
+0xD3FC 0x72F1 #CJK UNIFIED IDEOGRAPH
+0xD3FD 0x80B2 #CJK UNIFIED IDEOGRAPH
+0xD3FE 0x8A89 #CJK UNIFIED IDEOGRAPH
+0xD440 0x8A1E #CJK UNIFIED IDEOGRAPH
+0xD441 0x8A1F #CJK UNIFIED IDEOGRAPH
+0xD442 0x8A20 #CJK UNIFIED IDEOGRAPH
+0xD443 0x8A21 #CJK UNIFIED IDEOGRAPH
+0xD444 0x8A22 #CJK UNIFIED IDEOGRAPH
+0xD445 0x8A23 #CJK UNIFIED IDEOGRAPH
+0xD446 0x8A24 #CJK UNIFIED IDEOGRAPH
+0xD447 0x8A25 #CJK UNIFIED IDEOGRAPH
+0xD448 0x8A26 #CJK UNIFIED IDEOGRAPH
+0xD449 0x8A27 #CJK UNIFIED IDEOGRAPH
+0xD44A 0x8A28 #CJK UNIFIED IDEOGRAPH
+0xD44B 0x8A29 #CJK UNIFIED IDEOGRAPH
+0xD44C 0x8A2A #CJK UNIFIED IDEOGRAPH
+0xD44D 0x8A2B #CJK UNIFIED IDEOGRAPH
+0xD44E 0x8A2C #CJK UNIFIED IDEOGRAPH
+0xD44F 0x8A2D #CJK UNIFIED IDEOGRAPH
+0xD450 0x8A2E #CJK UNIFIED IDEOGRAPH
+0xD451 0x8A2F #CJK UNIFIED IDEOGRAPH
+0xD452 0x8A30 #CJK UNIFIED IDEOGRAPH
+0xD453 0x8A31 #CJK UNIFIED IDEOGRAPH
+0xD454 0x8A32 #CJK UNIFIED IDEOGRAPH
+0xD455 0x8A33 #CJK UNIFIED IDEOGRAPH
+0xD456 0x8A34 #CJK UNIFIED IDEOGRAPH
+0xD457 0x8A35 #CJK UNIFIED IDEOGRAPH
+0xD458 0x8A36 #CJK UNIFIED IDEOGRAPH
+0xD459 0x8A37 #CJK UNIFIED IDEOGRAPH
+0xD45A 0x8A38 #CJK UNIFIED IDEOGRAPH
+0xD45B 0x8A39 #CJK UNIFIED IDEOGRAPH
+0xD45C 0x8A3A #CJK UNIFIED IDEOGRAPH
+0xD45D 0x8A3B #CJK UNIFIED IDEOGRAPH
+0xD45E 0x8A3C #CJK UNIFIED IDEOGRAPH
+0xD45F 0x8A3D #CJK UNIFIED IDEOGRAPH
+0xD460 0x8A3F #CJK UNIFIED IDEOGRAPH
+0xD461 0x8A40 #CJK UNIFIED IDEOGRAPH
+0xD462 0x8A41 #CJK UNIFIED IDEOGRAPH
+0xD463 0x8A42 #CJK UNIFIED IDEOGRAPH
+0xD464 0x8A43 #CJK UNIFIED IDEOGRAPH
+0xD465 0x8A44 #CJK UNIFIED IDEOGRAPH
+0xD466 0x8A45 #CJK UNIFIED IDEOGRAPH
+0xD467 0x8A46 #CJK UNIFIED IDEOGRAPH
+0xD468 0x8A47 #CJK UNIFIED IDEOGRAPH
+0xD469 0x8A49 #CJK UNIFIED IDEOGRAPH
+0xD46A 0x8A4A #CJK UNIFIED IDEOGRAPH
+0xD46B 0x8A4B #CJK UNIFIED IDEOGRAPH
+0xD46C 0x8A4C #CJK UNIFIED IDEOGRAPH
+0xD46D 0x8A4D #CJK UNIFIED IDEOGRAPH
+0xD46E 0x8A4E #CJK UNIFIED IDEOGRAPH
+0xD46F 0x8A4F #CJK UNIFIED IDEOGRAPH
+0xD470 0x8A50 #CJK UNIFIED IDEOGRAPH
+0xD471 0x8A51 #CJK UNIFIED IDEOGRAPH
+0xD472 0x8A52 #CJK UNIFIED IDEOGRAPH
+0xD473 0x8A53 #CJK UNIFIED IDEOGRAPH
+0xD474 0x8A54 #CJK UNIFIED IDEOGRAPH
+0xD475 0x8A55 #CJK UNIFIED IDEOGRAPH
+0xD476 0x8A56 #CJK UNIFIED IDEOGRAPH
+0xD477 0x8A57 #CJK UNIFIED IDEOGRAPH
+0xD478 0x8A58 #CJK UNIFIED IDEOGRAPH
+0xD479 0x8A59 #CJK UNIFIED IDEOGRAPH
+0xD47A 0x8A5A #CJK UNIFIED IDEOGRAPH
+0xD47B 0x8A5B #CJK UNIFIED IDEOGRAPH
+0xD47C 0x8A5C #CJK UNIFIED IDEOGRAPH
+0xD47D 0x8A5D #CJK UNIFIED IDEOGRAPH
+0xD47E 0x8A5E #CJK UNIFIED IDEOGRAPH
+0xD480 0x8A5F #CJK UNIFIED IDEOGRAPH
+0xD481 0x8A60 #CJK UNIFIED IDEOGRAPH
+0xD482 0x8A61 #CJK UNIFIED IDEOGRAPH
+0xD483 0x8A62 #CJK UNIFIED IDEOGRAPH
+0xD484 0x8A63 #CJK UNIFIED IDEOGRAPH
+0xD485 0x8A64 #CJK UNIFIED IDEOGRAPH
+0xD486 0x8A65 #CJK UNIFIED IDEOGRAPH
+0xD487 0x8A66 #CJK UNIFIED IDEOGRAPH
+0xD488 0x8A67 #CJK UNIFIED IDEOGRAPH
+0xD489 0x8A68 #CJK UNIFIED IDEOGRAPH
+0xD48A 0x8A69 #CJK UNIFIED IDEOGRAPH
+0xD48B 0x8A6A #CJK UNIFIED IDEOGRAPH
+0xD48C 0x8A6B #CJK UNIFIED IDEOGRAPH
+0xD48D 0x8A6C #CJK UNIFIED IDEOGRAPH
+0xD48E 0x8A6D #CJK UNIFIED IDEOGRAPH
+0xD48F 0x8A6E #CJK UNIFIED IDEOGRAPH
+0xD490 0x8A6F #CJK UNIFIED IDEOGRAPH
+0xD491 0x8A70 #CJK UNIFIED IDEOGRAPH
+0xD492 0x8A71 #CJK UNIFIED IDEOGRAPH
+0xD493 0x8A72 #CJK UNIFIED IDEOGRAPH
+0xD494 0x8A73 #CJK UNIFIED IDEOGRAPH
+0xD495 0x8A74 #CJK UNIFIED IDEOGRAPH
+0xD496 0x8A75 #CJK UNIFIED IDEOGRAPH
+0xD497 0x8A76 #CJK UNIFIED IDEOGRAPH
+0xD498 0x8A77 #CJK UNIFIED IDEOGRAPH
+0xD499 0x8A78 #CJK UNIFIED IDEOGRAPH
+0xD49A 0x8A7A #CJK UNIFIED IDEOGRAPH
+0xD49B 0x8A7B #CJK UNIFIED IDEOGRAPH
+0xD49C 0x8A7C #CJK UNIFIED IDEOGRAPH
+0xD49D 0x8A7D #CJK UNIFIED IDEOGRAPH
+0xD49E 0x8A7E #CJK UNIFIED IDEOGRAPH
+0xD49F 0x8A7F #CJK UNIFIED IDEOGRAPH
+0xD4A0 0x8A80 #CJK UNIFIED IDEOGRAPH
+0xD4A1 0x6D74 #CJK UNIFIED IDEOGRAPH
+0xD4A2 0x5BD3 #CJK UNIFIED IDEOGRAPH
+0xD4A3 0x88D5 #CJK UNIFIED IDEOGRAPH
+0xD4A4 0x9884 #CJK UNIFIED IDEOGRAPH
+0xD4A5 0x8C6B #CJK UNIFIED IDEOGRAPH
+0xD4A6 0x9A6D #CJK UNIFIED IDEOGRAPH
+0xD4A7 0x9E33 #CJK UNIFIED IDEOGRAPH
+0xD4A8 0x6E0A #CJK UNIFIED IDEOGRAPH
+0xD4A9 0x51A4 #CJK UNIFIED IDEOGRAPH
+0xD4AA 0x5143 #CJK UNIFIED IDEOGRAPH
+0xD4AB 0x57A3 #CJK UNIFIED IDEOGRAPH
+0xD4AC 0x8881 #CJK UNIFIED IDEOGRAPH
+0xD4AD 0x539F #CJK UNIFIED IDEOGRAPH
+0xD4AE 0x63F4 #CJK UNIFIED IDEOGRAPH
+0xD4AF 0x8F95 #CJK UNIFIED IDEOGRAPH
+0xD4B0 0x56ED #CJK UNIFIED IDEOGRAPH
+0xD4B1 0x5458 #CJK UNIFIED IDEOGRAPH
+0xD4B2 0x5706 #CJK UNIFIED IDEOGRAPH
+0xD4B3 0x733F #CJK UNIFIED IDEOGRAPH
+0xD4B4 0x6E90 #CJK UNIFIED IDEOGRAPH
+0xD4B5 0x7F18 #CJK UNIFIED IDEOGRAPH
+0xD4B6 0x8FDC #CJK UNIFIED IDEOGRAPH
+0xD4B7 0x82D1 #CJK UNIFIED IDEOGRAPH
+0xD4B8 0x613F #CJK UNIFIED IDEOGRAPH
+0xD4B9 0x6028 #CJK UNIFIED IDEOGRAPH
+0xD4BA 0x9662 #CJK UNIFIED IDEOGRAPH
+0xD4BB 0x66F0 #CJK UNIFIED IDEOGRAPH
+0xD4BC 0x7EA6 #CJK UNIFIED IDEOGRAPH
+0xD4BD 0x8D8A #CJK UNIFIED IDEOGRAPH
+0xD4BE 0x8DC3 #CJK UNIFIED IDEOGRAPH
+0xD4BF 0x94A5 #CJK UNIFIED IDEOGRAPH
+0xD4C0 0x5CB3 #CJK UNIFIED IDEOGRAPH
+0xD4C1 0x7CA4 #CJK UNIFIED IDEOGRAPH
+0xD4C2 0x6708 #CJK UNIFIED IDEOGRAPH
+0xD4C3 0x60A6 #CJK UNIFIED IDEOGRAPH
+0xD4C4 0x9605 #CJK UNIFIED IDEOGRAPH
+0xD4C5 0x8018 #CJK UNIFIED IDEOGRAPH
+0xD4C6 0x4E91 #CJK UNIFIED IDEOGRAPH
+0xD4C7 0x90E7 #CJK UNIFIED IDEOGRAPH
+0xD4C8 0x5300 #CJK UNIFIED IDEOGRAPH
+0xD4C9 0x9668 #CJK UNIFIED IDEOGRAPH
+0xD4CA 0x5141 #CJK UNIFIED IDEOGRAPH
+0xD4CB 0x8FD0 #CJK UNIFIED IDEOGRAPH
+0xD4CC 0x8574 #CJK UNIFIED IDEOGRAPH
+0xD4CD 0x915D #CJK UNIFIED IDEOGRAPH
+0xD4CE 0x6655 #CJK UNIFIED IDEOGRAPH
+0xD4CF 0x97F5 #CJK UNIFIED IDEOGRAPH
+0xD4D0 0x5B55 #CJK UNIFIED IDEOGRAPH
+0xD4D1 0x531D #CJK UNIFIED IDEOGRAPH
+0xD4D2 0x7838 #CJK UNIFIED IDEOGRAPH
+0xD4D3 0x6742 #CJK UNIFIED IDEOGRAPH
+0xD4D4 0x683D #CJK UNIFIED IDEOGRAPH
+0xD4D5 0x54C9 #CJK UNIFIED IDEOGRAPH
+0xD4D6 0x707E #CJK UNIFIED IDEOGRAPH
+0xD4D7 0x5BB0 #CJK UNIFIED IDEOGRAPH
+0xD4D8 0x8F7D #CJK UNIFIED IDEOGRAPH
+0xD4D9 0x518D #CJK UNIFIED IDEOGRAPH
+0xD4DA 0x5728 #CJK UNIFIED IDEOGRAPH
+0xD4DB 0x54B1 #CJK UNIFIED IDEOGRAPH
+0xD4DC 0x6512 #CJK UNIFIED IDEOGRAPH
+0xD4DD 0x6682 #CJK UNIFIED IDEOGRAPH
+0xD4DE 0x8D5E #CJK UNIFIED IDEOGRAPH
+0xD4DF 0x8D43 #CJK UNIFIED IDEOGRAPH
+0xD4E0 0x810F #CJK UNIFIED IDEOGRAPH
+0xD4E1 0x846C #CJK UNIFIED IDEOGRAPH
+0xD4E2 0x906D #CJK UNIFIED IDEOGRAPH
+0xD4E3 0x7CDF #CJK UNIFIED IDEOGRAPH
+0xD4E4 0x51FF #CJK UNIFIED IDEOGRAPH
+0xD4E5 0x85FB #CJK UNIFIED IDEOGRAPH
+0xD4E6 0x67A3 #CJK UNIFIED IDEOGRAPH
+0xD4E7 0x65E9 #CJK UNIFIED IDEOGRAPH
+0xD4E8 0x6FA1 #CJK UNIFIED IDEOGRAPH
+0xD4E9 0x86A4 #CJK UNIFIED IDEOGRAPH
+0xD4EA 0x8E81 #CJK UNIFIED IDEOGRAPH
+0xD4EB 0x566A #CJK UNIFIED IDEOGRAPH
+0xD4EC 0x9020 #CJK UNIFIED IDEOGRAPH
+0xD4ED 0x7682 #CJK UNIFIED IDEOGRAPH
+0xD4EE 0x7076 #CJK UNIFIED IDEOGRAPH
+0xD4EF 0x71E5 #CJK UNIFIED IDEOGRAPH
+0xD4F0 0x8D23 #CJK UNIFIED IDEOGRAPH
+0xD4F1 0x62E9 #CJK UNIFIED IDEOGRAPH
+0xD4F2 0x5219 #CJK UNIFIED IDEOGRAPH
+0xD4F3 0x6CFD #CJK UNIFIED IDEOGRAPH
+0xD4F4 0x8D3C #CJK UNIFIED IDEOGRAPH
+0xD4F5 0x600E #CJK UNIFIED IDEOGRAPH
+0xD4F6 0x589E #CJK UNIFIED IDEOGRAPH
+0xD4F7 0x618E #CJK UNIFIED IDEOGRAPH
+0xD4F8 0x66FE #CJK UNIFIED IDEOGRAPH
+0xD4F9 0x8D60 #CJK UNIFIED IDEOGRAPH
+0xD4FA 0x624E #CJK UNIFIED IDEOGRAPH
+0xD4FB 0x55B3 #CJK UNIFIED IDEOGRAPH
+0xD4FC 0x6E23 #CJK UNIFIED IDEOGRAPH
+0xD4FD 0x672D #CJK UNIFIED IDEOGRAPH
+0xD4FE 0x8F67 #CJK UNIFIED IDEOGRAPH
+0xD540 0x8A81 #CJK UNIFIED IDEOGRAPH
+0xD541 0x8A82 #CJK UNIFIED IDEOGRAPH
+0xD542 0x8A83 #CJK UNIFIED IDEOGRAPH
+0xD543 0x8A84 #CJK UNIFIED IDEOGRAPH
+0xD544 0x8A85 #CJK UNIFIED IDEOGRAPH
+0xD545 0x8A86 #CJK UNIFIED IDEOGRAPH
+0xD546 0x8A87 #CJK UNIFIED IDEOGRAPH
+0xD547 0x8A88 #CJK UNIFIED IDEOGRAPH
+0xD548 0x8A8B #CJK UNIFIED IDEOGRAPH
+0xD549 0x8A8C #CJK UNIFIED IDEOGRAPH
+0xD54A 0x8A8D #CJK UNIFIED IDEOGRAPH
+0xD54B 0x8A8E #CJK UNIFIED IDEOGRAPH
+0xD54C 0x8A8F #CJK UNIFIED IDEOGRAPH
+0xD54D 0x8A90 #CJK UNIFIED IDEOGRAPH
+0xD54E 0x8A91 #CJK UNIFIED IDEOGRAPH
+0xD54F 0x8A92 #CJK UNIFIED IDEOGRAPH
+0xD550 0x8A94 #CJK UNIFIED IDEOGRAPH
+0xD551 0x8A95 #CJK UNIFIED IDEOGRAPH
+0xD552 0x8A96 #CJK UNIFIED IDEOGRAPH
+0xD553 0x8A97 #CJK UNIFIED IDEOGRAPH
+0xD554 0x8A98 #CJK UNIFIED IDEOGRAPH
+0xD555 0x8A99 #CJK UNIFIED IDEOGRAPH
+0xD556 0x8A9A #CJK UNIFIED IDEOGRAPH
+0xD557 0x8A9B #CJK UNIFIED IDEOGRAPH
+0xD558 0x8A9C #CJK UNIFIED IDEOGRAPH
+0xD559 0x8A9D #CJK UNIFIED IDEOGRAPH
+0xD55A 0x8A9E #CJK UNIFIED IDEOGRAPH
+0xD55B 0x8A9F #CJK UNIFIED IDEOGRAPH
+0xD55C 0x8AA0 #CJK UNIFIED IDEOGRAPH
+0xD55D 0x8AA1 #CJK UNIFIED IDEOGRAPH
+0xD55E 0x8AA2 #CJK UNIFIED IDEOGRAPH
+0xD55F 0x8AA3 #CJK UNIFIED IDEOGRAPH
+0xD560 0x8AA4 #CJK UNIFIED IDEOGRAPH
+0xD561 0x8AA5 #CJK UNIFIED IDEOGRAPH
+0xD562 0x8AA6 #CJK UNIFIED IDEOGRAPH
+0xD563 0x8AA7 #CJK UNIFIED IDEOGRAPH
+0xD564 0x8AA8 #CJK UNIFIED IDEOGRAPH
+0xD565 0x8AA9 #CJK UNIFIED IDEOGRAPH
+0xD566 0x8AAA #CJK UNIFIED IDEOGRAPH
+0xD567 0x8AAB #CJK UNIFIED IDEOGRAPH
+0xD568 0x8AAC #CJK UNIFIED IDEOGRAPH
+0xD569 0x8AAD #CJK UNIFIED IDEOGRAPH
+0xD56A 0x8AAE #CJK UNIFIED IDEOGRAPH
+0xD56B 0x8AAF #CJK UNIFIED IDEOGRAPH
+0xD56C 0x8AB0 #CJK UNIFIED IDEOGRAPH
+0xD56D 0x8AB1 #CJK UNIFIED IDEOGRAPH
+0xD56E 0x8AB2 #CJK UNIFIED IDEOGRAPH
+0xD56F 0x8AB3 #CJK UNIFIED IDEOGRAPH
+0xD570 0x8AB4 #CJK UNIFIED IDEOGRAPH
+0xD571 0x8AB5 #CJK UNIFIED IDEOGRAPH
+0xD572 0x8AB6 #CJK UNIFIED IDEOGRAPH
+0xD573 0x8AB7 #CJK UNIFIED IDEOGRAPH
+0xD574 0x8AB8 #CJK UNIFIED IDEOGRAPH
+0xD575 0x8AB9 #CJK UNIFIED IDEOGRAPH
+0xD576 0x8ABA #CJK UNIFIED IDEOGRAPH
+0xD577 0x8ABB #CJK UNIFIED IDEOGRAPH
+0xD578 0x8ABC #CJK UNIFIED IDEOGRAPH
+0xD579 0x8ABD #CJK UNIFIED IDEOGRAPH
+0xD57A 0x8ABE #CJK UNIFIED IDEOGRAPH
+0xD57B 0x8ABF #CJK UNIFIED IDEOGRAPH
+0xD57C 0x8AC0 #CJK UNIFIED IDEOGRAPH
+0xD57D 0x8AC1 #CJK UNIFIED IDEOGRAPH
+0xD57E 0x8AC2 #CJK UNIFIED IDEOGRAPH
+0xD580 0x8AC3 #CJK UNIFIED IDEOGRAPH
+0xD581 0x8AC4 #CJK UNIFIED IDEOGRAPH
+0xD582 0x8AC5 #CJK UNIFIED IDEOGRAPH
+0xD583 0x8AC6 #CJK UNIFIED IDEOGRAPH
+0xD584 0x8AC7 #CJK UNIFIED IDEOGRAPH
+0xD585 0x8AC8 #CJK UNIFIED IDEOGRAPH
+0xD586 0x8AC9 #CJK UNIFIED IDEOGRAPH
+0xD587 0x8ACA #CJK UNIFIED IDEOGRAPH
+0xD588 0x8ACB #CJK UNIFIED IDEOGRAPH
+0xD589 0x8ACC #CJK UNIFIED IDEOGRAPH
+0xD58A 0x8ACD #CJK UNIFIED IDEOGRAPH
+0xD58B 0x8ACE #CJK UNIFIED IDEOGRAPH
+0xD58C 0x8ACF #CJK UNIFIED IDEOGRAPH
+0xD58D 0x8AD0 #CJK UNIFIED IDEOGRAPH
+0xD58E 0x8AD1 #CJK UNIFIED IDEOGRAPH
+0xD58F 0x8AD2 #CJK UNIFIED IDEOGRAPH
+0xD590 0x8AD3 #CJK UNIFIED IDEOGRAPH
+0xD591 0x8AD4 #CJK UNIFIED IDEOGRAPH
+0xD592 0x8AD5 #CJK UNIFIED IDEOGRAPH
+0xD593 0x8AD6 #CJK UNIFIED IDEOGRAPH
+0xD594 0x8AD7 #CJK UNIFIED IDEOGRAPH
+0xD595 0x8AD8 #CJK UNIFIED IDEOGRAPH
+0xD596 0x8AD9 #CJK UNIFIED IDEOGRAPH
+0xD597 0x8ADA #CJK UNIFIED IDEOGRAPH
+0xD598 0x8ADB #CJK UNIFIED IDEOGRAPH
+0xD599 0x8ADC #CJK UNIFIED IDEOGRAPH
+0xD59A 0x8ADD #CJK UNIFIED IDEOGRAPH
+0xD59B 0x8ADE #CJK UNIFIED IDEOGRAPH
+0xD59C 0x8ADF #CJK UNIFIED IDEOGRAPH
+0xD59D 0x8AE0 #CJK UNIFIED IDEOGRAPH
+0xD59E 0x8AE1 #CJK UNIFIED IDEOGRAPH
+0xD59F 0x8AE2 #CJK UNIFIED IDEOGRAPH
+0xD5A0 0x8AE3 #CJK UNIFIED IDEOGRAPH
+0xD5A1 0x94E1 #CJK UNIFIED IDEOGRAPH
+0xD5A2 0x95F8 #CJK UNIFIED IDEOGRAPH
+0xD5A3 0x7728 #CJK UNIFIED IDEOGRAPH
+0xD5A4 0x6805 #CJK UNIFIED IDEOGRAPH
+0xD5A5 0x69A8 #CJK UNIFIED IDEOGRAPH
+0xD5A6 0x548B #CJK UNIFIED IDEOGRAPH
+0xD5A7 0x4E4D #CJK UNIFIED IDEOGRAPH
+0xD5A8 0x70B8 #CJK UNIFIED IDEOGRAPH
+0xD5A9 0x8BC8 #CJK UNIFIED IDEOGRAPH
+0xD5AA 0x6458 #CJK UNIFIED IDEOGRAPH
+0xD5AB 0x658B #CJK UNIFIED IDEOGRAPH
+0xD5AC 0x5B85 #CJK UNIFIED IDEOGRAPH
+0xD5AD 0x7A84 #CJK UNIFIED IDEOGRAPH
+0xD5AE 0x503A #CJK UNIFIED IDEOGRAPH
+0xD5AF 0x5BE8 #CJK UNIFIED IDEOGRAPH
+0xD5B0 0x77BB #CJK UNIFIED IDEOGRAPH
+0xD5B1 0x6BE1 #CJK UNIFIED IDEOGRAPH
+0xD5B2 0x8A79 #CJK UNIFIED IDEOGRAPH
+0xD5B3 0x7C98 #CJK UNIFIED IDEOGRAPH
+0xD5B4 0x6CBE #CJK UNIFIED IDEOGRAPH
+0xD5B5 0x76CF #CJK UNIFIED IDEOGRAPH
+0xD5B6 0x65A9 #CJK UNIFIED IDEOGRAPH
+0xD5B7 0x8F97 #CJK UNIFIED IDEOGRAPH
+0xD5B8 0x5D2D #CJK UNIFIED IDEOGRAPH
+0xD5B9 0x5C55 #CJK UNIFIED IDEOGRAPH
+0xD5BA 0x8638 #CJK UNIFIED IDEOGRAPH
+0xD5BB 0x6808 #CJK UNIFIED IDEOGRAPH
+0xD5BC 0x5360 #CJK UNIFIED IDEOGRAPH
+0xD5BD 0x6218 #CJK UNIFIED IDEOGRAPH
+0xD5BE 0x7AD9 #CJK UNIFIED IDEOGRAPH
+0xD5BF 0x6E5B #CJK UNIFIED IDEOGRAPH
+0xD5C0 0x7EFD #CJK UNIFIED IDEOGRAPH
+0xD5C1 0x6A1F #CJK UNIFIED IDEOGRAPH
+0xD5C2 0x7AE0 #CJK UNIFIED IDEOGRAPH
+0xD5C3 0x5F70 #CJK UNIFIED IDEOGRAPH
+0xD5C4 0x6F33 #CJK UNIFIED IDEOGRAPH
+0xD5C5 0x5F20 #CJK UNIFIED IDEOGRAPH
+0xD5C6 0x638C #CJK UNIFIED IDEOGRAPH
+0xD5C7 0x6DA8 #CJK UNIFIED IDEOGRAPH
+0xD5C8 0x6756 #CJK UNIFIED IDEOGRAPH
+0xD5C9 0x4E08 #CJK UNIFIED IDEOGRAPH
+0xD5CA 0x5E10 #CJK UNIFIED IDEOGRAPH
+0xD5CB 0x8D26 #CJK UNIFIED IDEOGRAPH
+0xD5CC 0x4ED7 #CJK UNIFIED IDEOGRAPH
+0xD5CD 0x80C0 #CJK UNIFIED IDEOGRAPH
+0xD5CE 0x7634 #CJK UNIFIED IDEOGRAPH
+0xD5CF 0x969C #CJK UNIFIED IDEOGRAPH
+0xD5D0 0x62DB #CJK UNIFIED IDEOGRAPH
+0xD5D1 0x662D #CJK UNIFIED IDEOGRAPH
+0xD5D2 0x627E #CJK UNIFIED IDEOGRAPH
+0xD5D3 0x6CBC #CJK UNIFIED IDEOGRAPH
+0xD5D4 0x8D75 #CJK UNIFIED IDEOGRAPH
+0xD5D5 0x7167 #CJK UNIFIED IDEOGRAPH
+0xD5D6 0x7F69 #CJK UNIFIED IDEOGRAPH
+0xD5D7 0x5146 #CJK UNIFIED IDEOGRAPH
+0xD5D8 0x8087 #CJK UNIFIED IDEOGRAPH
+0xD5D9 0x53EC #CJK UNIFIED IDEOGRAPH
+0xD5DA 0x906E #CJK UNIFIED IDEOGRAPH
+0xD5DB 0x6298 #CJK UNIFIED IDEOGRAPH
+0xD5DC 0x54F2 #CJK UNIFIED IDEOGRAPH
+0xD5DD 0x86F0 #CJK UNIFIED IDEOGRAPH
+0xD5DE 0x8F99 #CJK UNIFIED IDEOGRAPH
+0xD5DF 0x8005 #CJK UNIFIED IDEOGRAPH
+0xD5E0 0x9517 #CJK UNIFIED IDEOGRAPH
+0xD5E1 0x8517 #CJK UNIFIED IDEOGRAPH
+0xD5E2 0x8FD9 #CJK UNIFIED IDEOGRAPH
+0xD5E3 0x6D59 #CJK UNIFIED IDEOGRAPH
+0xD5E4 0x73CD #CJK UNIFIED IDEOGRAPH
+0xD5E5 0x659F #CJK UNIFIED IDEOGRAPH
+0xD5E6 0x771F #CJK UNIFIED IDEOGRAPH
+0xD5E7 0x7504 #CJK UNIFIED IDEOGRAPH
+0xD5E8 0x7827 #CJK UNIFIED IDEOGRAPH
+0xD5E9 0x81FB #CJK UNIFIED IDEOGRAPH
+0xD5EA 0x8D1E #CJK UNIFIED IDEOGRAPH
+0xD5EB 0x9488 #CJK UNIFIED IDEOGRAPH
+0xD5EC 0x4FA6 #CJK UNIFIED IDEOGRAPH
+0xD5ED 0x6795 #CJK UNIFIED IDEOGRAPH
+0xD5EE 0x75B9 #CJK UNIFIED IDEOGRAPH
+0xD5EF 0x8BCA #CJK UNIFIED IDEOGRAPH
+0xD5F0 0x9707 #CJK UNIFIED IDEOGRAPH
+0xD5F1 0x632F #CJK UNIFIED IDEOGRAPH
+0xD5F2 0x9547 #CJK UNIFIED IDEOGRAPH
+0xD5F3 0x9635 #CJK UNIFIED IDEOGRAPH
+0xD5F4 0x84B8 #CJK UNIFIED IDEOGRAPH
+0xD5F5 0x6323 #CJK UNIFIED IDEOGRAPH
+0xD5F6 0x7741 #CJK UNIFIED IDEOGRAPH
+0xD5F7 0x5F81 #CJK UNIFIED IDEOGRAPH
+0xD5F8 0x72F0 #CJK UNIFIED IDEOGRAPH
+0xD5F9 0x4E89 #CJK UNIFIED IDEOGRAPH
+0xD5FA 0x6014 #CJK UNIFIED IDEOGRAPH
+0xD5FB 0x6574 #CJK UNIFIED IDEOGRAPH
+0xD5FC 0x62EF #CJK UNIFIED IDEOGRAPH
+0xD5FD 0x6B63 #CJK UNIFIED IDEOGRAPH
+0xD5FE 0x653F #CJK UNIFIED IDEOGRAPH
+0xD640 0x8AE4 #CJK UNIFIED IDEOGRAPH
+0xD641 0x8AE5 #CJK UNIFIED IDEOGRAPH
+0xD642 0x8AE6 #CJK UNIFIED IDEOGRAPH
+0xD643 0x8AE7 #CJK UNIFIED IDEOGRAPH
+0xD644 0x8AE8 #CJK UNIFIED IDEOGRAPH
+0xD645 0x8AE9 #CJK UNIFIED IDEOGRAPH
+0xD646 0x8AEA #CJK UNIFIED IDEOGRAPH
+0xD647 0x8AEB #CJK UNIFIED IDEOGRAPH
+0xD648 0x8AEC #CJK UNIFIED IDEOGRAPH
+0xD649 0x8AED #CJK UNIFIED IDEOGRAPH
+0xD64A 0x8AEE #CJK UNIFIED IDEOGRAPH
+0xD64B 0x8AEF #CJK UNIFIED IDEOGRAPH
+0xD64C 0x8AF0 #CJK UNIFIED IDEOGRAPH
+0xD64D 0x8AF1 #CJK UNIFIED IDEOGRAPH
+0xD64E 0x8AF2 #CJK UNIFIED IDEOGRAPH
+0xD64F 0x8AF3 #CJK UNIFIED IDEOGRAPH
+0xD650 0x8AF4 #CJK UNIFIED IDEOGRAPH
+0xD651 0x8AF5 #CJK UNIFIED IDEOGRAPH
+0xD652 0x8AF6 #CJK UNIFIED IDEOGRAPH
+0xD653 0x8AF7 #CJK UNIFIED IDEOGRAPH
+0xD654 0x8AF8 #CJK UNIFIED IDEOGRAPH
+0xD655 0x8AF9 #CJK UNIFIED IDEOGRAPH
+0xD656 0x8AFA #CJK UNIFIED IDEOGRAPH
+0xD657 0x8AFB #CJK UNIFIED IDEOGRAPH
+0xD658 0x8AFC #CJK UNIFIED IDEOGRAPH
+0xD659 0x8AFD #CJK UNIFIED IDEOGRAPH
+0xD65A 0x8AFE #CJK UNIFIED IDEOGRAPH
+0xD65B 0x8AFF #CJK UNIFIED IDEOGRAPH
+0xD65C 0x8B00 #CJK UNIFIED IDEOGRAPH
+0xD65D 0x8B01 #CJK UNIFIED IDEOGRAPH
+0xD65E 0x8B02 #CJK UNIFIED IDEOGRAPH
+0xD65F 0x8B03 #CJK UNIFIED IDEOGRAPH
+0xD660 0x8B04 #CJK UNIFIED IDEOGRAPH
+0xD661 0x8B05 #CJK UNIFIED IDEOGRAPH
+0xD662 0x8B06 #CJK UNIFIED IDEOGRAPH
+0xD663 0x8B08 #CJK UNIFIED IDEOGRAPH
+0xD664 0x8B09 #CJK UNIFIED IDEOGRAPH
+0xD665 0x8B0A #CJK UNIFIED IDEOGRAPH
+0xD666 0x8B0B #CJK UNIFIED IDEOGRAPH
+0xD667 0x8B0C #CJK UNIFIED IDEOGRAPH
+0xD668 0x8B0D #CJK UNIFIED IDEOGRAPH
+0xD669 0x8B0E #CJK UNIFIED IDEOGRAPH
+0xD66A 0x8B0F #CJK UNIFIED IDEOGRAPH
+0xD66B 0x8B10 #CJK UNIFIED IDEOGRAPH
+0xD66C 0x8B11 #CJK UNIFIED IDEOGRAPH
+0xD66D 0x8B12 #CJK UNIFIED IDEOGRAPH
+0xD66E 0x8B13 #CJK UNIFIED IDEOGRAPH
+0xD66F 0x8B14 #CJK UNIFIED IDEOGRAPH
+0xD670 0x8B15 #CJK UNIFIED IDEOGRAPH
+0xD671 0x8B16 #CJK UNIFIED IDEOGRAPH
+0xD672 0x8B17 #CJK UNIFIED IDEOGRAPH
+0xD673 0x8B18 #CJK UNIFIED IDEOGRAPH
+0xD674 0x8B19 #CJK UNIFIED IDEOGRAPH
+0xD675 0x8B1A #CJK UNIFIED IDEOGRAPH
+0xD676 0x8B1B #CJK UNIFIED IDEOGRAPH
+0xD677 0x8B1C #CJK UNIFIED IDEOGRAPH
+0xD678 0x8B1D #CJK UNIFIED IDEOGRAPH
+0xD679 0x8B1E #CJK UNIFIED IDEOGRAPH
+0xD67A 0x8B1F #CJK UNIFIED IDEOGRAPH
+0xD67B 0x8B20 #CJK UNIFIED IDEOGRAPH
+0xD67C 0x8B21 #CJK UNIFIED IDEOGRAPH
+0xD67D 0x8B22 #CJK UNIFIED IDEOGRAPH
+0xD67E 0x8B23 #CJK UNIFIED IDEOGRAPH
+0xD680 0x8B24 #CJK UNIFIED IDEOGRAPH
+0xD681 0x8B25 #CJK UNIFIED IDEOGRAPH
+0xD682 0x8B27 #CJK UNIFIED IDEOGRAPH
+0xD683 0x8B28 #CJK UNIFIED IDEOGRAPH
+0xD684 0x8B29 #CJK UNIFIED IDEOGRAPH
+0xD685 0x8B2A #CJK UNIFIED IDEOGRAPH
+0xD686 0x8B2B #CJK UNIFIED IDEOGRAPH
+0xD687 0x8B2C #CJK UNIFIED IDEOGRAPH
+0xD688 0x8B2D #CJK UNIFIED IDEOGRAPH
+0xD689 0x8B2E #CJK UNIFIED IDEOGRAPH
+0xD68A 0x8B2F #CJK UNIFIED IDEOGRAPH
+0xD68B 0x8B30 #CJK UNIFIED IDEOGRAPH
+0xD68C 0x8B31 #CJK UNIFIED IDEOGRAPH
+0xD68D 0x8B32 #CJK UNIFIED IDEOGRAPH
+0xD68E 0x8B33 #CJK UNIFIED IDEOGRAPH
+0xD68F 0x8B34 #CJK UNIFIED IDEOGRAPH
+0xD690 0x8B35 #CJK UNIFIED IDEOGRAPH
+0xD691 0x8B36 #CJK UNIFIED IDEOGRAPH
+0xD692 0x8B37 #CJK UNIFIED IDEOGRAPH
+0xD693 0x8B38 #CJK UNIFIED IDEOGRAPH
+0xD694 0x8B39 #CJK UNIFIED IDEOGRAPH
+0xD695 0x8B3A #CJK UNIFIED IDEOGRAPH
+0xD696 0x8B3B #CJK UNIFIED IDEOGRAPH
+0xD697 0x8B3C #CJK UNIFIED IDEOGRAPH
+0xD698 0x8B3D #CJK UNIFIED IDEOGRAPH
+0xD699 0x8B3E #CJK UNIFIED IDEOGRAPH
+0xD69A 0x8B3F #CJK UNIFIED IDEOGRAPH
+0xD69B 0x8B40 #CJK UNIFIED IDEOGRAPH
+0xD69C 0x8B41 #CJK UNIFIED IDEOGRAPH
+0xD69D 0x8B42 #CJK UNIFIED IDEOGRAPH
+0xD69E 0x8B43 #CJK UNIFIED IDEOGRAPH
+0xD69F 0x8B44 #CJK UNIFIED IDEOGRAPH
+0xD6A0 0x8B45 #CJK UNIFIED IDEOGRAPH
+0xD6A1 0x5E27 #CJK UNIFIED IDEOGRAPH
+0xD6A2 0x75C7 #CJK UNIFIED IDEOGRAPH
+0xD6A3 0x90D1 #CJK UNIFIED IDEOGRAPH
+0xD6A4 0x8BC1 #CJK UNIFIED IDEOGRAPH
+0xD6A5 0x829D #CJK UNIFIED IDEOGRAPH
+0xD6A6 0x679D #CJK UNIFIED IDEOGRAPH
+0xD6A7 0x652F #CJK UNIFIED IDEOGRAPH
+0xD6A8 0x5431 #CJK UNIFIED IDEOGRAPH
+0xD6A9 0x8718 #CJK UNIFIED IDEOGRAPH
+0xD6AA 0x77E5 #CJK UNIFIED IDEOGRAPH
+0xD6AB 0x80A2 #CJK UNIFIED IDEOGRAPH
+0xD6AC 0x8102 #CJK UNIFIED IDEOGRAPH
+0xD6AD 0x6C41 #CJK UNIFIED IDEOGRAPH
+0xD6AE 0x4E4B #CJK UNIFIED IDEOGRAPH
+0xD6AF 0x7EC7 #CJK UNIFIED IDEOGRAPH
+0xD6B0 0x804C #CJK UNIFIED IDEOGRAPH
+0xD6B1 0x76F4 #CJK UNIFIED IDEOGRAPH
+0xD6B2 0x690D #CJK UNIFIED IDEOGRAPH
+0xD6B3 0x6B96 #CJK UNIFIED IDEOGRAPH
+0xD6B4 0x6267 #CJK UNIFIED IDEOGRAPH
+0xD6B5 0x503C #CJK UNIFIED IDEOGRAPH
+0xD6B6 0x4F84 #CJK UNIFIED IDEOGRAPH
+0xD6B7 0x5740 #CJK UNIFIED IDEOGRAPH
+0xD6B8 0x6307 #CJK UNIFIED IDEOGRAPH
+0xD6B9 0x6B62 #CJK UNIFIED IDEOGRAPH
+0xD6BA 0x8DBE #CJK UNIFIED IDEOGRAPH
+0xD6BB 0x53EA #CJK UNIFIED IDEOGRAPH
+0xD6BC 0x65E8 #CJK UNIFIED IDEOGRAPH
+0xD6BD 0x7EB8 #CJK UNIFIED IDEOGRAPH
+0xD6BE 0x5FD7 #CJK UNIFIED IDEOGRAPH
+0xD6BF 0x631A #CJK UNIFIED IDEOGRAPH
+0xD6C0 0x63B7 #CJK UNIFIED IDEOGRAPH
+0xD6C1 0x81F3 #CJK UNIFIED IDEOGRAPH
+0xD6C2 0x81F4 #CJK UNIFIED IDEOGRAPH
+0xD6C3 0x7F6E #CJK UNIFIED IDEOGRAPH
+0xD6C4 0x5E1C #CJK UNIFIED IDEOGRAPH
+0xD6C5 0x5CD9 #CJK UNIFIED IDEOGRAPH
+0xD6C6 0x5236 #CJK UNIFIED IDEOGRAPH
+0xD6C7 0x667A #CJK UNIFIED IDEOGRAPH
+0xD6C8 0x79E9 #CJK UNIFIED IDEOGRAPH
+0xD6C9 0x7A1A #CJK UNIFIED IDEOGRAPH
+0xD6CA 0x8D28 #CJK UNIFIED IDEOGRAPH
+0xD6CB 0x7099 #CJK UNIFIED IDEOGRAPH
+0xD6CC 0x75D4 #CJK UNIFIED IDEOGRAPH
+0xD6CD 0x6EDE #CJK UNIFIED IDEOGRAPH
+0xD6CE 0x6CBB #CJK UNIFIED IDEOGRAPH
+0xD6CF 0x7A92 #CJK UNIFIED IDEOGRAPH
+0xD6D0 0x4E2D #CJK UNIFIED IDEOGRAPH
+0xD6D1 0x76C5 #CJK UNIFIED IDEOGRAPH
+0xD6D2 0x5FE0 #CJK UNIFIED IDEOGRAPH
+0xD6D3 0x949F #CJK UNIFIED IDEOGRAPH
+0xD6D4 0x8877 #CJK UNIFIED IDEOGRAPH
+0xD6D5 0x7EC8 #CJK UNIFIED IDEOGRAPH
+0xD6D6 0x79CD #CJK UNIFIED IDEOGRAPH
+0xD6D7 0x80BF #CJK UNIFIED IDEOGRAPH
+0xD6D8 0x91CD #CJK UNIFIED IDEOGRAPH
+0xD6D9 0x4EF2 #CJK UNIFIED IDEOGRAPH
+0xD6DA 0x4F17 #CJK UNIFIED IDEOGRAPH
+0xD6DB 0x821F #CJK UNIFIED IDEOGRAPH
+0xD6DC 0x5468 #CJK UNIFIED IDEOGRAPH
+0xD6DD 0x5DDE #CJK UNIFIED IDEOGRAPH
+0xD6DE 0x6D32 #CJK UNIFIED IDEOGRAPH
+0xD6DF 0x8BCC #CJK UNIFIED IDEOGRAPH
+0xD6E0 0x7CA5 #CJK UNIFIED IDEOGRAPH
+0xD6E1 0x8F74 #CJK UNIFIED IDEOGRAPH
+0xD6E2 0x8098 #CJK UNIFIED IDEOGRAPH
+0xD6E3 0x5E1A #CJK UNIFIED IDEOGRAPH
+0xD6E4 0x5492 #CJK UNIFIED IDEOGRAPH
+0xD6E5 0x76B1 #CJK UNIFIED IDEOGRAPH
+0xD6E6 0x5B99 #CJK UNIFIED IDEOGRAPH
+0xD6E7 0x663C #CJK UNIFIED IDEOGRAPH
+0xD6E8 0x9AA4 #CJK UNIFIED IDEOGRAPH
+0xD6E9 0x73E0 #CJK UNIFIED IDEOGRAPH
+0xD6EA 0x682A #CJK UNIFIED IDEOGRAPH
+0xD6EB 0x86DB #CJK UNIFIED IDEOGRAPH
+0xD6EC 0x6731 #CJK UNIFIED IDEOGRAPH
+0xD6ED 0x732A #CJK UNIFIED IDEOGRAPH
+0xD6EE 0x8BF8 #CJK UNIFIED IDEOGRAPH
+0xD6EF 0x8BDB #CJK UNIFIED IDEOGRAPH
+0xD6F0 0x9010 #CJK UNIFIED IDEOGRAPH
+0xD6F1 0x7AF9 #CJK UNIFIED IDEOGRAPH
+0xD6F2 0x70DB #CJK UNIFIED IDEOGRAPH
+0xD6F3 0x716E #CJK UNIFIED IDEOGRAPH
+0xD6F4 0x62C4 #CJK UNIFIED IDEOGRAPH
+0xD6F5 0x77A9 #CJK UNIFIED IDEOGRAPH
+0xD6F6 0x5631 #CJK UNIFIED IDEOGRAPH
+0xD6F7 0x4E3B #CJK UNIFIED IDEOGRAPH
+0xD6F8 0x8457 #CJK UNIFIED IDEOGRAPH
+0xD6F9 0x67F1 #CJK UNIFIED IDEOGRAPH
+0xD6FA 0x52A9 #CJK UNIFIED IDEOGRAPH
+0xD6FB 0x86C0 #CJK UNIFIED IDEOGRAPH
+0xD6FC 0x8D2E #CJK UNIFIED IDEOGRAPH
+0xD6FD 0x94F8 #CJK UNIFIED IDEOGRAPH
+0xD6FE 0x7B51 #CJK UNIFIED IDEOGRAPH
+0xD740 0x8B46 #CJK UNIFIED IDEOGRAPH
+0xD741 0x8B47 #CJK UNIFIED IDEOGRAPH
+0xD742 0x8B48 #CJK UNIFIED IDEOGRAPH
+0xD743 0x8B49 #CJK UNIFIED IDEOGRAPH
+0xD744 0x8B4A #CJK UNIFIED IDEOGRAPH
+0xD745 0x8B4B #CJK UNIFIED IDEOGRAPH
+0xD746 0x8B4C #CJK UNIFIED IDEOGRAPH
+0xD747 0x8B4D #CJK UNIFIED IDEOGRAPH
+0xD748 0x8B4E #CJK UNIFIED IDEOGRAPH
+0xD749 0x8B4F #CJK UNIFIED IDEOGRAPH
+0xD74A 0x8B50 #CJK UNIFIED IDEOGRAPH
+0xD74B 0x8B51 #CJK UNIFIED IDEOGRAPH
+0xD74C 0x8B52 #CJK UNIFIED IDEOGRAPH
+0xD74D 0x8B53 #CJK UNIFIED IDEOGRAPH
+0xD74E 0x8B54 #CJK UNIFIED IDEOGRAPH
+0xD74F 0x8B55 #CJK UNIFIED IDEOGRAPH
+0xD750 0x8B56 #CJK UNIFIED IDEOGRAPH
+0xD751 0x8B57 #CJK UNIFIED IDEOGRAPH
+0xD752 0x8B58 #CJK UNIFIED IDEOGRAPH
+0xD753 0x8B59 #CJK UNIFIED IDEOGRAPH
+0xD754 0x8B5A #CJK UNIFIED IDEOGRAPH
+0xD755 0x8B5B #CJK UNIFIED IDEOGRAPH
+0xD756 0x8B5C #CJK UNIFIED IDEOGRAPH
+0xD757 0x8B5D #CJK UNIFIED IDEOGRAPH
+0xD758 0x8B5E #CJK UNIFIED IDEOGRAPH
+0xD759 0x8B5F #CJK UNIFIED IDEOGRAPH
+0xD75A 0x8B60 #CJK UNIFIED IDEOGRAPH
+0xD75B 0x8B61 #CJK UNIFIED IDEOGRAPH
+0xD75C 0x8B62 #CJK UNIFIED IDEOGRAPH
+0xD75D 0x8B63 #CJK UNIFIED IDEOGRAPH
+0xD75E 0x8B64 #CJK UNIFIED IDEOGRAPH
+0xD75F 0x8B65 #CJK UNIFIED IDEOGRAPH
+0xD760 0x8B67 #CJK UNIFIED IDEOGRAPH
+0xD761 0x8B68 #CJK UNIFIED IDEOGRAPH
+0xD762 0x8B69 #CJK UNIFIED IDEOGRAPH
+0xD763 0x8B6A #CJK UNIFIED IDEOGRAPH
+0xD764 0x8B6B #CJK UNIFIED IDEOGRAPH
+0xD765 0x8B6D #CJK UNIFIED IDEOGRAPH
+0xD766 0x8B6E #CJK UNIFIED IDEOGRAPH
+0xD767 0x8B6F #CJK UNIFIED IDEOGRAPH
+0xD768 0x8B70 #CJK UNIFIED IDEOGRAPH
+0xD769 0x8B71 #CJK UNIFIED IDEOGRAPH
+0xD76A 0x8B72 #CJK UNIFIED IDEOGRAPH
+0xD76B 0x8B73 #CJK UNIFIED IDEOGRAPH
+0xD76C 0x8B74 #CJK UNIFIED IDEOGRAPH
+0xD76D 0x8B75 #CJK UNIFIED IDEOGRAPH
+0xD76E 0x8B76 #CJK UNIFIED IDEOGRAPH
+0xD76F 0x8B77 #CJK UNIFIED IDEOGRAPH
+0xD770 0x8B78 #CJK UNIFIED IDEOGRAPH
+0xD771 0x8B79 #CJK UNIFIED IDEOGRAPH
+0xD772 0x8B7A #CJK UNIFIED IDEOGRAPH
+0xD773 0x8B7B #CJK UNIFIED IDEOGRAPH
+0xD774 0x8B7C #CJK UNIFIED IDEOGRAPH
+0xD775 0x8B7D #CJK UNIFIED IDEOGRAPH
+0xD776 0x8B7E #CJK UNIFIED IDEOGRAPH
+0xD777 0x8B7F #CJK UNIFIED IDEOGRAPH
+0xD778 0x8B80 #CJK UNIFIED IDEOGRAPH
+0xD779 0x8B81 #CJK UNIFIED IDEOGRAPH
+0xD77A 0x8B82 #CJK UNIFIED IDEOGRAPH
+0xD77B 0x8B83 #CJK UNIFIED IDEOGRAPH
+0xD77C 0x8B84 #CJK UNIFIED IDEOGRAPH
+0xD77D 0x8B85 #CJK UNIFIED IDEOGRAPH
+0xD77E 0x8B86 #CJK UNIFIED IDEOGRAPH
+0xD780 0x8B87 #CJK UNIFIED IDEOGRAPH
+0xD781 0x8B88 #CJK UNIFIED IDEOGRAPH
+0xD782 0x8B89 #CJK UNIFIED IDEOGRAPH
+0xD783 0x8B8A #CJK UNIFIED IDEOGRAPH
+0xD784 0x8B8B #CJK UNIFIED IDEOGRAPH
+0xD785 0x8B8C #CJK UNIFIED IDEOGRAPH
+0xD786 0x8B8D #CJK UNIFIED IDEOGRAPH
+0xD787 0x8B8E #CJK UNIFIED IDEOGRAPH
+0xD788 0x8B8F #CJK UNIFIED IDEOGRAPH
+0xD789 0x8B90 #CJK UNIFIED IDEOGRAPH
+0xD78A 0x8B91 #CJK UNIFIED IDEOGRAPH
+0xD78B 0x8B92 #CJK UNIFIED IDEOGRAPH
+0xD78C 0x8B93 #CJK UNIFIED IDEOGRAPH
+0xD78D 0x8B94 #CJK UNIFIED IDEOGRAPH
+0xD78E 0x8B95 #CJK UNIFIED IDEOGRAPH
+0xD78F 0x8B96 #CJK UNIFIED IDEOGRAPH
+0xD790 0x8B97 #CJK UNIFIED IDEOGRAPH
+0xD791 0x8B98 #CJK UNIFIED IDEOGRAPH
+0xD792 0x8B99 #CJK UNIFIED IDEOGRAPH
+0xD793 0x8B9A #CJK UNIFIED IDEOGRAPH
+0xD794 0x8B9B #CJK UNIFIED IDEOGRAPH
+0xD795 0x8B9C #CJK UNIFIED IDEOGRAPH
+0xD796 0x8B9D #CJK UNIFIED IDEOGRAPH
+0xD797 0x8B9E #CJK UNIFIED IDEOGRAPH
+0xD798 0x8B9F #CJK UNIFIED IDEOGRAPH
+0xD799 0x8BAC #CJK UNIFIED IDEOGRAPH
+0xD79A 0x8BB1 #CJK UNIFIED IDEOGRAPH
+0xD79B 0x8BBB #CJK UNIFIED IDEOGRAPH
+0xD79C 0x8BC7 #CJK UNIFIED IDEOGRAPH
+0xD79D 0x8BD0 #CJK UNIFIED IDEOGRAPH
+0xD79E 0x8BEA #CJK UNIFIED IDEOGRAPH
+0xD79F 0x8C09 #CJK UNIFIED IDEOGRAPH
+0xD7A0 0x8C1E #CJK UNIFIED IDEOGRAPH
+0xD7A1 0x4F4F #CJK UNIFIED IDEOGRAPH
+0xD7A2 0x6CE8 #CJK UNIFIED IDEOGRAPH
+0xD7A3 0x795D #CJK UNIFIED IDEOGRAPH
+0xD7A4 0x9A7B #CJK UNIFIED IDEOGRAPH
+0xD7A5 0x6293 #CJK UNIFIED IDEOGRAPH
+0xD7A6 0x722A #CJK UNIFIED IDEOGRAPH
+0xD7A7 0x62FD #CJK UNIFIED IDEOGRAPH
+0xD7A8 0x4E13 #CJK UNIFIED IDEOGRAPH
+0xD7A9 0x7816 #CJK UNIFIED IDEOGRAPH
+0xD7AA 0x8F6C #CJK UNIFIED IDEOGRAPH
+0xD7AB 0x64B0 #CJK UNIFIED IDEOGRAPH
+0xD7AC 0x8D5A #CJK UNIFIED IDEOGRAPH
+0xD7AD 0x7BC6 #CJK UNIFIED IDEOGRAPH
+0xD7AE 0x6869 #CJK UNIFIED IDEOGRAPH
+0xD7AF 0x5E84 #CJK UNIFIED IDEOGRAPH
+0xD7B0 0x88C5 #CJK UNIFIED IDEOGRAPH
+0xD7B1 0x5986 #CJK UNIFIED IDEOGRAPH
+0xD7B2 0x649E #CJK UNIFIED IDEOGRAPH
+0xD7B3 0x58EE #CJK UNIFIED IDEOGRAPH
+0xD7B4 0x72B6 #CJK UNIFIED IDEOGRAPH
+0xD7B5 0x690E #CJK UNIFIED IDEOGRAPH
+0xD7B6 0x9525 #CJK UNIFIED IDEOGRAPH
+0xD7B7 0x8FFD #CJK UNIFIED IDEOGRAPH
+0xD7B8 0x8D58 #CJK UNIFIED IDEOGRAPH
+0xD7B9 0x5760 #CJK UNIFIED IDEOGRAPH
+0xD7BA 0x7F00 #CJK UNIFIED IDEOGRAPH
+0xD7BB 0x8C06 #CJK UNIFIED IDEOGRAPH
+0xD7BC 0x51C6 #CJK UNIFIED IDEOGRAPH
+0xD7BD 0x6349 #CJK UNIFIED IDEOGRAPH
+0xD7BE 0x62D9 #CJK UNIFIED IDEOGRAPH
+0xD7BF 0x5353 #CJK UNIFIED IDEOGRAPH
+0xD7C0 0x684C #CJK UNIFIED IDEOGRAPH
+0xD7C1 0x7422 #CJK UNIFIED IDEOGRAPH
+0xD7C2 0x8301 #CJK UNIFIED IDEOGRAPH
+0xD7C3 0x914C #CJK UNIFIED IDEOGRAPH
+0xD7C4 0x5544 #CJK UNIFIED IDEOGRAPH
+0xD7C5 0x7740 #CJK UNIFIED IDEOGRAPH
+0xD7C6 0x707C #CJK UNIFIED IDEOGRAPH
+0xD7C7 0x6D4A #CJK UNIFIED IDEOGRAPH
+0xD7C8 0x5179 #CJK UNIFIED IDEOGRAPH
+0xD7C9 0x54A8 #CJK UNIFIED IDEOGRAPH
+0xD7CA 0x8D44 #CJK UNIFIED IDEOGRAPH
+0xD7CB 0x59FF #CJK UNIFIED IDEOGRAPH
+0xD7CC 0x6ECB #CJK UNIFIED IDEOGRAPH
+0xD7CD 0x6DC4 #CJK UNIFIED IDEOGRAPH
+0xD7CE 0x5B5C #CJK UNIFIED IDEOGRAPH
+0xD7CF 0x7D2B #CJK UNIFIED IDEOGRAPH
+0xD7D0 0x4ED4 #CJK UNIFIED IDEOGRAPH
+0xD7D1 0x7C7D #CJK UNIFIED IDEOGRAPH
+0xD7D2 0x6ED3 #CJK UNIFIED IDEOGRAPH
+0xD7D3 0x5B50 #CJK UNIFIED IDEOGRAPH
+0xD7D4 0x81EA #CJK UNIFIED IDEOGRAPH
+0xD7D5 0x6E0D #CJK UNIFIED IDEOGRAPH
+0xD7D6 0x5B57 #CJK UNIFIED IDEOGRAPH
+0xD7D7 0x9B03 #CJK UNIFIED IDEOGRAPH
+0xD7D8 0x68D5 #CJK UNIFIED IDEOGRAPH
+0xD7D9 0x8E2A #CJK UNIFIED IDEOGRAPH
+0xD7DA 0x5B97 #CJK UNIFIED IDEOGRAPH
+0xD7DB 0x7EFC #CJK UNIFIED IDEOGRAPH
+0xD7DC 0x603B #CJK UNIFIED IDEOGRAPH
+0xD7DD 0x7EB5 #CJK UNIFIED IDEOGRAPH
+0xD7DE 0x90B9 #CJK UNIFIED IDEOGRAPH
+0xD7DF 0x8D70 #CJK UNIFIED IDEOGRAPH
+0xD7E0 0x594F #CJK UNIFIED IDEOGRAPH
+0xD7E1 0x63CD #CJK UNIFIED IDEOGRAPH
+0xD7E2 0x79DF #CJK UNIFIED IDEOGRAPH
+0xD7E3 0x8DB3 #CJK UNIFIED IDEOGRAPH
+0xD7E4 0x5352 #CJK UNIFIED IDEOGRAPH
+0xD7E5 0x65CF #CJK UNIFIED IDEOGRAPH
+0xD7E6 0x7956 #CJK UNIFIED IDEOGRAPH
+0xD7E7 0x8BC5 #CJK UNIFIED IDEOGRAPH
+0xD7E8 0x963B #CJK UNIFIED IDEOGRAPH
+0xD7E9 0x7EC4 #CJK UNIFIED IDEOGRAPH
+0xD7EA 0x94BB #CJK UNIFIED IDEOGRAPH
+0xD7EB 0x7E82 #CJK UNIFIED IDEOGRAPH
+0xD7EC 0x5634 #CJK UNIFIED IDEOGRAPH
+0xD7ED 0x9189 #CJK UNIFIED IDEOGRAPH
+0xD7EE 0x6700 #CJK UNIFIED IDEOGRAPH
+0xD7EF 0x7F6A #CJK UNIFIED IDEOGRAPH
+0xD7F0 0x5C0A #CJK UNIFIED IDEOGRAPH
+0xD7F1 0x9075 #CJK UNIFIED IDEOGRAPH
+0xD7F2 0x6628 #CJK UNIFIED IDEOGRAPH
+0xD7F3 0x5DE6 #CJK UNIFIED IDEOGRAPH
+0xD7F4 0x4F50 #CJK UNIFIED IDEOGRAPH
+0xD7F5 0x67DE #CJK UNIFIED IDEOGRAPH
+0xD7F6 0x505A #CJK UNIFIED IDEOGRAPH
+0xD7F7 0x4F5C #CJK UNIFIED IDEOGRAPH
+0xD7F8 0x5750 #CJK UNIFIED IDEOGRAPH
+0xD7F9 0x5EA7 #CJK UNIFIED IDEOGRAPH
+0xD840 0x8C38 #CJK UNIFIED IDEOGRAPH
+0xD841 0x8C39 #CJK UNIFIED IDEOGRAPH
+0xD842 0x8C3A #CJK UNIFIED IDEOGRAPH
+0xD843 0x8C3B #CJK UNIFIED IDEOGRAPH
+0xD844 0x8C3C #CJK UNIFIED IDEOGRAPH
+0xD845 0x8C3D #CJK UNIFIED IDEOGRAPH
+0xD846 0x8C3E #CJK UNIFIED IDEOGRAPH
+0xD847 0x8C3F #CJK UNIFIED IDEOGRAPH
+0xD848 0x8C40 #CJK UNIFIED IDEOGRAPH
+0xD849 0x8C42 #CJK UNIFIED IDEOGRAPH
+0xD84A 0x8C43 #CJK UNIFIED IDEOGRAPH
+0xD84B 0x8C44 #CJK UNIFIED IDEOGRAPH
+0xD84C 0x8C45 #CJK UNIFIED IDEOGRAPH
+0xD84D 0x8C48 #CJK UNIFIED IDEOGRAPH
+0xD84E 0x8C4A #CJK UNIFIED IDEOGRAPH
+0xD84F 0x8C4B #CJK UNIFIED IDEOGRAPH
+0xD850 0x8C4D #CJK UNIFIED IDEOGRAPH
+0xD851 0x8C4E #CJK UNIFIED IDEOGRAPH
+0xD852 0x8C4F #CJK UNIFIED IDEOGRAPH
+0xD853 0x8C50 #CJK UNIFIED IDEOGRAPH
+0xD854 0x8C51 #CJK UNIFIED IDEOGRAPH
+0xD855 0x8C52 #CJK UNIFIED IDEOGRAPH
+0xD856 0x8C53 #CJK UNIFIED IDEOGRAPH
+0xD857 0x8C54 #CJK UNIFIED IDEOGRAPH
+0xD858 0x8C56 #CJK UNIFIED IDEOGRAPH
+0xD859 0x8C57 #CJK UNIFIED IDEOGRAPH
+0xD85A 0x8C58 #CJK UNIFIED IDEOGRAPH
+0xD85B 0x8C59 #CJK UNIFIED IDEOGRAPH
+0xD85C 0x8C5B #CJK UNIFIED IDEOGRAPH
+0xD85D 0x8C5C #CJK UNIFIED IDEOGRAPH
+0xD85E 0x8C5D #CJK UNIFIED IDEOGRAPH
+0xD85F 0x8C5E #CJK UNIFIED IDEOGRAPH
+0xD860 0x8C5F #CJK UNIFIED IDEOGRAPH
+0xD861 0x8C60 #CJK UNIFIED IDEOGRAPH
+0xD862 0x8C63 #CJK UNIFIED IDEOGRAPH
+0xD863 0x8C64 #CJK UNIFIED IDEOGRAPH
+0xD864 0x8C65 #CJK UNIFIED IDEOGRAPH
+0xD865 0x8C66 #CJK UNIFIED IDEOGRAPH
+0xD866 0x8C67 #CJK UNIFIED IDEOGRAPH
+0xD867 0x8C68 #CJK UNIFIED IDEOGRAPH
+0xD868 0x8C69 #CJK UNIFIED IDEOGRAPH
+0xD869 0x8C6C #CJK UNIFIED IDEOGRAPH
+0xD86A 0x8C6D #CJK UNIFIED IDEOGRAPH
+0xD86B 0x8C6E #CJK UNIFIED IDEOGRAPH
+0xD86C 0x8C6F #CJK UNIFIED IDEOGRAPH
+0xD86D 0x8C70 #CJK UNIFIED IDEOGRAPH
+0xD86E 0x8C71 #CJK UNIFIED IDEOGRAPH
+0xD86F 0x8C72 #CJK UNIFIED IDEOGRAPH
+0xD870 0x8C74 #CJK UNIFIED IDEOGRAPH
+0xD871 0x8C75 #CJK UNIFIED IDEOGRAPH
+0xD872 0x8C76 #CJK UNIFIED IDEOGRAPH
+0xD873 0x8C77 #CJK UNIFIED IDEOGRAPH
+0xD874 0x8C7B #CJK UNIFIED IDEOGRAPH
+0xD875 0x8C7C #CJK UNIFIED IDEOGRAPH
+0xD876 0x8C7D #CJK UNIFIED IDEOGRAPH
+0xD877 0x8C7E #CJK UNIFIED IDEOGRAPH
+0xD878 0x8C7F #CJK UNIFIED IDEOGRAPH
+0xD879 0x8C80 #CJK UNIFIED IDEOGRAPH
+0xD87A 0x8C81 #CJK UNIFIED IDEOGRAPH
+0xD87B 0x8C83 #CJK UNIFIED IDEOGRAPH
+0xD87C 0x8C84 #CJK UNIFIED IDEOGRAPH
+0xD87D 0x8C86 #CJK UNIFIED IDEOGRAPH
+0xD87E 0x8C87 #CJK UNIFIED IDEOGRAPH
+0xD880 0x8C88 #CJK UNIFIED IDEOGRAPH
+0xD881 0x8C8B #CJK UNIFIED IDEOGRAPH
+0xD882 0x8C8D #CJK UNIFIED IDEOGRAPH
+0xD883 0x8C8E #CJK UNIFIED IDEOGRAPH
+0xD884 0x8C8F #CJK UNIFIED IDEOGRAPH
+0xD885 0x8C90 #CJK UNIFIED IDEOGRAPH
+0xD886 0x8C91 #CJK UNIFIED IDEOGRAPH
+0xD887 0x8C92 #CJK UNIFIED IDEOGRAPH
+0xD888 0x8C93 #CJK UNIFIED IDEOGRAPH
+0xD889 0x8C95 #CJK UNIFIED IDEOGRAPH
+0xD88A 0x8C96 #CJK UNIFIED IDEOGRAPH
+0xD88B 0x8C97 #CJK UNIFIED IDEOGRAPH
+0xD88C 0x8C99 #CJK UNIFIED IDEOGRAPH
+0xD88D 0x8C9A #CJK UNIFIED IDEOGRAPH
+0xD88E 0x8C9B #CJK UNIFIED IDEOGRAPH
+0xD88F 0x8C9C #CJK UNIFIED IDEOGRAPH
+0xD890 0x8C9D #CJK UNIFIED IDEOGRAPH
+0xD891 0x8C9E #CJK UNIFIED IDEOGRAPH
+0xD892 0x8C9F #CJK UNIFIED IDEOGRAPH
+0xD893 0x8CA0 #CJK UNIFIED IDEOGRAPH
+0xD894 0x8CA1 #CJK UNIFIED IDEOGRAPH
+0xD895 0x8CA2 #CJK UNIFIED IDEOGRAPH
+0xD896 0x8CA3 #CJK UNIFIED IDEOGRAPH
+0xD897 0x8CA4 #CJK UNIFIED IDEOGRAPH
+0xD898 0x8CA5 #CJK UNIFIED IDEOGRAPH
+0xD899 0x8CA6 #CJK UNIFIED IDEOGRAPH
+0xD89A 0x8CA7 #CJK UNIFIED IDEOGRAPH
+0xD89B 0x8CA8 #CJK UNIFIED IDEOGRAPH
+0xD89C 0x8CA9 #CJK UNIFIED IDEOGRAPH
+0xD89D 0x8CAA #CJK UNIFIED IDEOGRAPH
+0xD89E 0x8CAB #CJK UNIFIED IDEOGRAPH
+0xD89F 0x8CAC #CJK UNIFIED IDEOGRAPH
+0xD8A0 0x8CAD #CJK UNIFIED IDEOGRAPH
+0xD8A1 0x4E8D #CJK UNIFIED IDEOGRAPH
+0xD8A2 0x4E0C #CJK UNIFIED IDEOGRAPH
+0xD8A3 0x5140 #CJK UNIFIED IDEOGRAPH
+0xD8A4 0x4E10 #CJK UNIFIED IDEOGRAPH
+0xD8A5 0x5EFF #CJK UNIFIED IDEOGRAPH
+0xD8A6 0x5345 #CJK UNIFIED IDEOGRAPH
+0xD8A7 0x4E15 #CJK UNIFIED IDEOGRAPH
+0xD8A8 0x4E98 #CJK UNIFIED IDEOGRAPH
+0xD8A9 0x4E1E #CJK UNIFIED IDEOGRAPH
+0xD8AA 0x9B32 #CJK UNIFIED IDEOGRAPH
+0xD8AB 0x5B6C #CJK UNIFIED IDEOGRAPH
+0xD8AC 0x5669 #CJK UNIFIED IDEOGRAPH
+0xD8AD 0x4E28 #CJK UNIFIED IDEOGRAPH
+0xD8AE 0x79BA #CJK UNIFIED IDEOGRAPH
+0xD8AF 0x4E3F #CJK UNIFIED IDEOGRAPH
+0xD8B0 0x5315 #CJK UNIFIED IDEOGRAPH
+0xD8B1 0x4E47 #CJK UNIFIED IDEOGRAPH
+0xD8B2 0x592D #CJK UNIFIED IDEOGRAPH
+0xD8B3 0x723B #CJK UNIFIED IDEOGRAPH
+0xD8B4 0x536E #CJK UNIFIED IDEOGRAPH
+0xD8B5 0x6C10 #CJK UNIFIED IDEOGRAPH
+0xD8B6 0x56DF #CJK UNIFIED IDEOGRAPH
+0xD8B7 0x80E4 #CJK UNIFIED IDEOGRAPH
+0xD8B8 0x9997 #CJK UNIFIED IDEOGRAPH
+0xD8B9 0x6BD3 #CJK UNIFIED IDEOGRAPH
+0xD8BA 0x777E #CJK UNIFIED IDEOGRAPH
+0xD8BB 0x9F17 #CJK UNIFIED IDEOGRAPH
+0xD8BC 0x4E36 #CJK UNIFIED IDEOGRAPH
+0xD8BD 0x4E9F #CJK UNIFIED IDEOGRAPH
+0xD8BE 0x9F10 #CJK UNIFIED IDEOGRAPH
+0xD8BF 0x4E5C #CJK UNIFIED IDEOGRAPH
+0xD8C0 0x4E69 #CJK UNIFIED IDEOGRAPH
+0xD8C1 0x4E93 #CJK UNIFIED IDEOGRAPH
+0xD8C2 0x8288 #CJK UNIFIED IDEOGRAPH
+0xD8C3 0x5B5B #CJK UNIFIED IDEOGRAPH
+0xD8C4 0x556C #CJK UNIFIED IDEOGRAPH
+0xD8C5 0x560F #CJK UNIFIED IDEOGRAPH
+0xD8C6 0x4EC4 #CJK UNIFIED IDEOGRAPH
+0xD8C7 0x538D #CJK UNIFIED IDEOGRAPH
+0xD8C8 0x539D #CJK UNIFIED IDEOGRAPH
+0xD8C9 0x53A3 #CJK UNIFIED IDEOGRAPH
+0xD8CA 0x53A5 #CJK UNIFIED IDEOGRAPH
+0xD8CB 0x53AE #CJK UNIFIED IDEOGRAPH
+0xD8CC 0x9765 #CJK UNIFIED IDEOGRAPH
+0xD8CD 0x8D5D #CJK UNIFIED IDEOGRAPH
+0xD8CE 0x531A #CJK UNIFIED IDEOGRAPH
+0xD8CF 0x53F5 #CJK UNIFIED IDEOGRAPH
+0xD8D0 0x5326 #CJK UNIFIED IDEOGRAPH
+0xD8D1 0x532E #CJK UNIFIED IDEOGRAPH
+0xD8D2 0x533E #CJK UNIFIED IDEOGRAPH
+0xD8D3 0x8D5C #CJK UNIFIED IDEOGRAPH
+0xD8D4 0x5366 #CJK UNIFIED IDEOGRAPH
+0xD8D5 0x5363 #CJK UNIFIED IDEOGRAPH
+0xD8D6 0x5202 #CJK UNIFIED IDEOGRAPH
+0xD8D7 0x5208 #CJK UNIFIED IDEOGRAPH
+0xD8D8 0x520E #CJK UNIFIED IDEOGRAPH
+0xD8D9 0x522D #CJK UNIFIED IDEOGRAPH
+0xD8DA 0x5233 #CJK UNIFIED IDEOGRAPH
+0xD8DB 0x523F #CJK UNIFIED IDEOGRAPH
+0xD8DC 0x5240 #CJK UNIFIED IDEOGRAPH
+0xD8DD 0x524C #CJK UNIFIED IDEOGRAPH
+0xD8DE 0x525E #CJK UNIFIED IDEOGRAPH
+0xD8DF 0x5261 #CJK UNIFIED IDEOGRAPH
+0xD8E0 0x525C #CJK UNIFIED IDEOGRAPH
+0xD8E1 0x84AF #CJK UNIFIED IDEOGRAPH
+0xD8E2 0x527D #CJK UNIFIED IDEOGRAPH
+0xD8E3 0x5282 #CJK UNIFIED IDEOGRAPH
+0xD8E4 0x5281 #CJK UNIFIED IDEOGRAPH
+0xD8E5 0x5290 #CJK UNIFIED IDEOGRAPH
+0xD8E6 0x5293 #CJK UNIFIED IDEOGRAPH
+0xD8E7 0x5182 #CJK UNIFIED IDEOGRAPH
+0xD8E8 0x7F54 #CJK UNIFIED IDEOGRAPH
+0xD8E9 0x4EBB #CJK UNIFIED IDEOGRAPH
+0xD8EA 0x4EC3 #CJK UNIFIED IDEOGRAPH
+0xD8EB 0x4EC9 #CJK UNIFIED IDEOGRAPH
+0xD8EC 0x4EC2 #CJK UNIFIED IDEOGRAPH
+0xD8ED 0x4EE8 #CJK UNIFIED IDEOGRAPH
+0xD8EE 0x4EE1 #CJK UNIFIED IDEOGRAPH
+0xD8EF 0x4EEB #CJK UNIFIED IDEOGRAPH
+0xD8F0 0x4EDE #CJK UNIFIED IDEOGRAPH
+0xD8F1 0x4F1B #CJK UNIFIED IDEOGRAPH
+0xD8F2 0x4EF3 #CJK UNIFIED IDEOGRAPH
+0xD8F3 0x4F22 #CJK UNIFIED IDEOGRAPH
+0xD8F4 0x4F64 #CJK UNIFIED IDEOGRAPH
+0xD8F5 0x4EF5 #CJK UNIFIED IDEOGRAPH
+0xD8F6 0x4F25 #CJK UNIFIED IDEOGRAPH
+0xD8F7 0x4F27 #CJK UNIFIED IDEOGRAPH
+0xD8F8 0x4F09 #CJK UNIFIED IDEOGRAPH
+0xD8F9 0x4F2B #CJK UNIFIED IDEOGRAPH
+0xD8FA 0x4F5E #CJK UNIFIED IDEOGRAPH
+0xD8FB 0x4F67 #CJK UNIFIED IDEOGRAPH
+0xD8FC 0x6538 #CJK UNIFIED IDEOGRAPH
+0xD8FD 0x4F5A #CJK UNIFIED IDEOGRAPH
+0xD8FE 0x4F5D #CJK UNIFIED IDEOGRAPH
+0xD940 0x8CAE #CJK UNIFIED IDEOGRAPH
+0xD941 0x8CAF #CJK UNIFIED IDEOGRAPH
+0xD942 0x8CB0 #CJK UNIFIED IDEOGRAPH
+0xD943 0x8CB1 #CJK UNIFIED IDEOGRAPH
+0xD944 0x8CB2 #CJK UNIFIED IDEOGRAPH
+0xD945 0x8CB3 #CJK UNIFIED IDEOGRAPH
+0xD946 0x8CB4 #CJK UNIFIED IDEOGRAPH
+0xD947 0x8CB5 #CJK UNIFIED IDEOGRAPH
+0xD948 0x8CB6 #CJK UNIFIED IDEOGRAPH
+0xD949 0x8CB7 #CJK UNIFIED IDEOGRAPH
+0xD94A 0x8CB8 #CJK UNIFIED IDEOGRAPH
+0xD94B 0x8CB9 #CJK UNIFIED IDEOGRAPH
+0xD94C 0x8CBA #CJK UNIFIED IDEOGRAPH
+0xD94D 0x8CBB #CJK UNIFIED IDEOGRAPH
+0xD94E 0x8CBC #CJK UNIFIED IDEOGRAPH
+0xD94F 0x8CBD #CJK UNIFIED IDEOGRAPH
+0xD950 0x8CBE #CJK UNIFIED IDEOGRAPH
+0xD951 0x8CBF #CJK UNIFIED IDEOGRAPH
+0xD952 0x8CC0 #CJK UNIFIED IDEOGRAPH
+0xD953 0x8CC1 #CJK UNIFIED IDEOGRAPH
+0xD954 0x8CC2 #CJK UNIFIED IDEOGRAPH
+0xD955 0x8CC3 #CJK UNIFIED IDEOGRAPH
+0xD956 0x8CC4 #CJK UNIFIED IDEOGRAPH
+0xD957 0x8CC5 #CJK UNIFIED IDEOGRAPH
+0xD958 0x8CC6 #CJK UNIFIED IDEOGRAPH
+0xD959 0x8CC7 #CJK UNIFIED IDEOGRAPH
+0xD95A 0x8CC8 #CJK UNIFIED IDEOGRAPH
+0xD95B 0x8CC9 #CJK UNIFIED IDEOGRAPH
+0xD95C 0x8CCA #CJK UNIFIED IDEOGRAPH
+0xD95D 0x8CCB #CJK UNIFIED IDEOGRAPH
+0xD95E 0x8CCC #CJK UNIFIED IDEOGRAPH
+0xD95F 0x8CCD #CJK UNIFIED IDEOGRAPH
+0xD960 0x8CCE #CJK UNIFIED IDEOGRAPH
+0xD961 0x8CCF #CJK UNIFIED IDEOGRAPH
+0xD962 0x8CD0 #CJK UNIFIED IDEOGRAPH
+0xD963 0x8CD1 #CJK UNIFIED IDEOGRAPH
+0xD964 0x8CD2 #CJK UNIFIED IDEOGRAPH
+0xD965 0x8CD3 #CJK UNIFIED IDEOGRAPH
+0xD966 0x8CD4 #CJK UNIFIED IDEOGRAPH
+0xD967 0x8CD5 #CJK UNIFIED IDEOGRAPH
+0xD968 0x8CD6 #CJK UNIFIED IDEOGRAPH
+0xD969 0x8CD7 #CJK UNIFIED IDEOGRAPH
+0xD96A 0x8CD8 #CJK UNIFIED IDEOGRAPH
+0xD96B 0x8CD9 #CJK UNIFIED IDEOGRAPH
+0xD96C 0x8CDA #CJK UNIFIED IDEOGRAPH
+0xD96D 0x8CDB #CJK UNIFIED IDEOGRAPH
+0xD96E 0x8CDC #CJK UNIFIED IDEOGRAPH
+0xD96F 0x8CDD #CJK UNIFIED IDEOGRAPH
+0xD970 0x8CDE #CJK UNIFIED IDEOGRAPH
+0xD971 0x8CDF #CJK UNIFIED IDEOGRAPH
+0xD972 0x8CE0 #CJK UNIFIED IDEOGRAPH
+0xD973 0x8CE1 #CJK UNIFIED IDEOGRAPH
+0xD974 0x8CE2 #CJK UNIFIED IDEOGRAPH
+0xD975 0x8CE3 #CJK UNIFIED IDEOGRAPH
+0xD976 0x8CE4 #CJK UNIFIED IDEOGRAPH
+0xD977 0x8CE5 #CJK UNIFIED IDEOGRAPH
+0xD978 0x8CE6 #CJK UNIFIED IDEOGRAPH
+0xD979 0x8CE7 #CJK UNIFIED IDEOGRAPH
+0xD97A 0x8CE8 #CJK UNIFIED IDEOGRAPH
+0xD97B 0x8CE9 #CJK UNIFIED IDEOGRAPH
+0xD97C 0x8CEA #CJK UNIFIED IDEOGRAPH
+0xD97D 0x8CEB #CJK UNIFIED IDEOGRAPH
+0xD97E 0x8CEC #CJK UNIFIED IDEOGRAPH
+0xD980 0x8CED #CJK UNIFIED IDEOGRAPH
+0xD981 0x8CEE #CJK UNIFIED IDEOGRAPH
+0xD982 0x8CEF #CJK UNIFIED IDEOGRAPH
+0xD983 0x8CF0 #CJK UNIFIED IDEOGRAPH
+0xD984 0x8CF1 #CJK UNIFIED IDEOGRAPH
+0xD985 0x8CF2 #CJK UNIFIED IDEOGRAPH
+0xD986 0x8CF3 #CJK UNIFIED IDEOGRAPH
+0xD987 0x8CF4 #CJK UNIFIED IDEOGRAPH
+0xD988 0x8CF5 #CJK UNIFIED IDEOGRAPH
+0xD989 0x8CF6 #CJK UNIFIED IDEOGRAPH
+0xD98A 0x8CF7 #CJK UNIFIED IDEOGRAPH
+0xD98B 0x8CF8 #CJK UNIFIED IDEOGRAPH
+0xD98C 0x8CF9 #CJK UNIFIED IDEOGRAPH
+0xD98D 0x8CFA #CJK UNIFIED IDEOGRAPH
+0xD98E 0x8CFB #CJK UNIFIED IDEOGRAPH
+0xD98F 0x8CFC #CJK UNIFIED IDEOGRAPH
+0xD990 0x8CFD #CJK UNIFIED IDEOGRAPH
+0xD991 0x8CFE #CJK UNIFIED IDEOGRAPH
+0xD992 0x8CFF #CJK UNIFIED IDEOGRAPH
+0xD993 0x8D00 #CJK UNIFIED IDEOGRAPH
+0xD994 0x8D01 #CJK UNIFIED IDEOGRAPH
+0xD995 0x8D02 #CJK UNIFIED IDEOGRAPH
+0xD996 0x8D03 #CJK UNIFIED IDEOGRAPH
+0xD997 0x8D04 #CJK UNIFIED IDEOGRAPH
+0xD998 0x8D05 #CJK UNIFIED IDEOGRAPH
+0xD999 0x8D06 #CJK UNIFIED IDEOGRAPH
+0xD99A 0x8D07 #CJK UNIFIED IDEOGRAPH
+0xD99B 0x8D08 #CJK UNIFIED IDEOGRAPH
+0xD99C 0x8D09 #CJK UNIFIED IDEOGRAPH
+0xD99D 0x8D0A #CJK UNIFIED IDEOGRAPH
+0xD99E 0x8D0B #CJK UNIFIED IDEOGRAPH
+0xD99F 0x8D0C #CJK UNIFIED IDEOGRAPH
+0xD9A0 0x8D0D #CJK UNIFIED IDEOGRAPH
+0xD9A1 0x4F5F #CJK UNIFIED IDEOGRAPH
+0xD9A2 0x4F57 #CJK UNIFIED IDEOGRAPH
+0xD9A3 0x4F32 #CJK UNIFIED IDEOGRAPH
+0xD9A4 0x4F3D #CJK UNIFIED IDEOGRAPH
+0xD9A5 0x4F76 #CJK UNIFIED IDEOGRAPH
+0xD9A6 0x4F74 #CJK UNIFIED IDEOGRAPH
+0xD9A7 0x4F91 #CJK UNIFIED IDEOGRAPH
+0xD9A8 0x4F89 #CJK UNIFIED IDEOGRAPH
+0xD9A9 0x4F83 #CJK UNIFIED IDEOGRAPH
+0xD9AA 0x4F8F #CJK UNIFIED IDEOGRAPH
+0xD9AB 0x4F7E #CJK UNIFIED IDEOGRAPH
+0xD9AC 0x4F7B #CJK UNIFIED IDEOGRAPH
+0xD9AD 0x4FAA #CJK UNIFIED IDEOGRAPH
+0xD9AE 0x4F7C #CJK UNIFIED IDEOGRAPH
+0xD9AF 0x4FAC #CJK UNIFIED IDEOGRAPH
+0xD9B0 0x4F94 #CJK UNIFIED IDEOGRAPH
+0xD9B1 0x4FE6 #CJK UNIFIED IDEOGRAPH
+0xD9B2 0x4FE8 #CJK UNIFIED IDEOGRAPH
+0xD9B3 0x4FEA #CJK UNIFIED IDEOGRAPH
+0xD9B4 0x4FC5 #CJK UNIFIED IDEOGRAPH
+0xD9B5 0x4FDA #CJK UNIFIED IDEOGRAPH
+0xD9B6 0x4FE3 #CJK UNIFIED IDEOGRAPH
+0xD9B7 0x4FDC #CJK UNIFIED IDEOGRAPH
+0xD9B8 0x4FD1 #CJK UNIFIED IDEOGRAPH
+0xD9B9 0x4FDF #CJK UNIFIED IDEOGRAPH
+0xD9BA 0x4FF8 #CJK UNIFIED IDEOGRAPH
+0xD9BB 0x5029 #CJK UNIFIED IDEOGRAPH
+0xD9BC 0x504C #CJK UNIFIED IDEOGRAPH
+0xD9BD 0x4FF3 #CJK UNIFIED IDEOGRAPH
+0xD9BE 0x502C #CJK UNIFIED IDEOGRAPH
+0xD9BF 0x500F #CJK UNIFIED IDEOGRAPH
+0xD9C0 0x502E #CJK UNIFIED IDEOGRAPH
+0xD9C1 0x502D #CJK UNIFIED IDEOGRAPH
+0xD9C2 0x4FFE #CJK UNIFIED IDEOGRAPH
+0xD9C3 0x501C #CJK UNIFIED IDEOGRAPH
+0xD9C4 0x500C #CJK UNIFIED IDEOGRAPH
+0xD9C5 0x5025 #CJK UNIFIED IDEOGRAPH
+0xD9C6 0x5028 #CJK UNIFIED IDEOGRAPH
+0xD9C7 0x507E #CJK UNIFIED IDEOGRAPH
+0xD9C8 0x5043 #CJK UNIFIED IDEOGRAPH
+0xD9C9 0x5055 #CJK UNIFIED IDEOGRAPH
+0xD9CA 0x5048 #CJK UNIFIED IDEOGRAPH
+0xD9CB 0x504E #CJK UNIFIED IDEOGRAPH
+0xD9CC 0x506C #CJK UNIFIED IDEOGRAPH
+0xD9CD 0x507B #CJK UNIFIED IDEOGRAPH
+0xD9CE 0x50A5 #CJK UNIFIED IDEOGRAPH
+0xD9CF 0x50A7 #CJK UNIFIED IDEOGRAPH
+0xD9D0 0x50A9 #CJK UNIFIED IDEOGRAPH
+0xD9D1 0x50BA #CJK UNIFIED IDEOGRAPH
+0xD9D2 0x50D6 #CJK UNIFIED IDEOGRAPH
+0xD9D3 0x5106 #CJK UNIFIED IDEOGRAPH
+0xD9D4 0x50ED #CJK UNIFIED IDEOGRAPH
+0xD9D5 0x50EC #CJK UNIFIED IDEOGRAPH
+0xD9D6 0x50E6 #CJK UNIFIED IDEOGRAPH
+0xD9D7 0x50EE #CJK UNIFIED IDEOGRAPH
+0xD9D8 0x5107 #CJK UNIFIED IDEOGRAPH
+0xD9D9 0x510B #CJK UNIFIED IDEOGRAPH
+0xD9DA 0x4EDD #CJK UNIFIED IDEOGRAPH
+0xD9DB 0x6C3D #CJK UNIFIED IDEOGRAPH
+0xD9DC 0x4F58 #CJK UNIFIED IDEOGRAPH
+0xD9DD 0x4F65 #CJK UNIFIED IDEOGRAPH
+0xD9DE 0x4FCE #CJK UNIFIED IDEOGRAPH
+0xD9DF 0x9FA0 #CJK UNIFIED IDEOGRAPH
+0xD9E0 0x6C46 #CJK UNIFIED IDEOGRAPH
+0xD9E1 0x7C74 #CJK UNIFIED IDEOGRAPH
+0xD9E2 0x516E #CJK UNIFIED IDEOGRAPH
+0xD9E3 0x5DFD #CJK UNIFIED IDEOGRAPH
+0xD9E4 0x9EC9 #CJK UNIFIED IDEOGRAPH
+0xD9E5 0x9998 #CJK UNIFIED IDEOGRAPH
+0xD9E6 0x5181 #CJK UNIFIED IDEOGRAPH
+0xD9E7 0x5914 #CJK UNIFIED IDEOGRAPH
+0xD9E8 0x52F9 #CJK UNIFIED IDEOGRAPH
+0xD9E9 0x530D #CJK UNIFIED IDEOGRAPH
+0xD9EA 0x8A07 #CJK UNIFIED IDEOGRAPH
+0xD9EB 0x5310 #CJK UNIFIED IDEOGRAPH
+0xD9EC 0x51EB #CJK UNIFIED IDEOGRAPH
+0xD9ED 0x5919 #CJK UNIFIED IDEOGRAPH
+0xD9EE 0x5155 #CJK UNIFIED IDEOGRAPH
+0xD9EF 0x4EA0 #CJK UNIFIED IDEOGRAPH
+0xD9F0 0x5156 #CJK UNIFIED IDEOGRAPH
+0xD9F1 0x4EB3 #CJK UNIFIED IDEOGRAPH
+0xD9F2 0x886E #CJK UNIFIED IDEOGRAPH
+0xD9F3 0x88A4 #CJK UNIFIED IDEOGRAPH
+0xD9F4 0x4EB5 #CJK UNIFIED IDEOGRAPH
+0xD9F5 0x8114 #CJK UNIFIED IDEOGRAPH
+0xD9F6 0x88D2 #CJK UNIFIED IDEOGRAPH
+0xD9F7 0x7980 #CJK UNIFIED IDEOGRAPH
+0xD9F8 0x5B34 #CJK UNIFIED IDEOGRAPH
+0xD9F9 0x8803 #CJK UNIFIED IDEOGRAPH
+0xD9FA 0x7FB8 #CJK UNIFIED IDEOGRAPH
+0xD9FB 0x51AB #CJK UNIFIED IDEOGRAPH
+0xD9FC 0x51B1 #CJK UNIFIED IDEOGRAPH
+0xD9FD 0x51BD #CJK UNIFIED IDEOGRAPH
+0xD9FE 0x51BC #CJK UNIFIED IDEOGRAPH
+0xDA40 0x8D0E #CJK UNIFIED IDEOGRAPH
+0xDA41 0x8D0F #CJK UNIFIED IDEOGRAPH
+0xDA42 0x8D10 #CJK UNIFIED IDEOGRAPH
+0xDA43 0x8D11 #CJK UNIFIED IDEOGRAPH
+0xDA44 0x8D12 #CJK UNIFIED IDEOGRAPH
+0xDA45 0x8D13 #CJK UNIFIED IDEOGRAPH
+0xDA46 0x8D14 #CJK UNIFIED IDEOGRAPH
+0xDA47 0x8D15 #CJK UNIFIED IDEOGRAPH
+0xDA48 0x8D16 #CJK UNIFIED IDEOGRAPH
+0xDA49 0x8D17 #CJK UNIFIED IDEOGRAPH
+0xDA4A 0x8D18 #CJK UNIFIED IDEOGRAPH
+0xDA4B 0x8D19 #CJK UNIFIED IDEOGRAPH
+0xDA4C 0x8D1A #CJK UNIFIED IDEOGRAPH
+0xDA4D 0x8D1B #CJK UNIFIED IDEOGRAPH
+0xDA4E 0x8D1C #CJK UNIFIED IDEOGRAPH
+0xDA4F 0x8D20 #CJK UNIFIED IDEOGRAPH
+0xDA50 0x8D51 #CJK UNIFIED IDEOGRAPH
+0xDA51 0x8D52 #CJK UNIFIED IDEOGRAPH
+0xDA52 0x8D57 #CJK UNIFIED IDEOGRAPH
+0xDA53 0x8D5F #CJK UNIFIED IDEOGRAPH
+0xDA54 0x8D65 #CJK UNIFIED IDEOGRAPH
+0xDA55 0x8D68 #CJK UNIFIED IDEOGRAPH
+0xDA56 0x8D69 #CJK UNIFIED IDEOGRAPH
+0xDA57 0x8D6A #CJK UNIFIED IDEOGRAPH
+0xDA58 0x8D6C #CJK UNIFIED IDEOGRAPH
+0xDA59 0x8D6E #CJK UNIFIED IDEOGRAPH
+0xDA5A 0x8D6F #CJK UNIFIED IDEOGRAPH
+0xDA5B 0x8D71 #CJK UNIFIED IDEOGRAPH
+0xDA5C 0x8D72 #CJK UNIFIED IDEOGRAPH
+0xDA5D 0x8D78 #CJK UNIFIED IDEOGRAPH
+0xDA5E 0x8D79 #CJK UNIFIED IDEOGRAPH
+0xDA5F 0x8D7A #CJK UNIFIED IDEOGRAPH
+0xDA60 0x8D7B #CJK UNIFIED IDEOGRAPH
+0xDA61 0x8D7C #CJK UNIFIED IDEOGRAPH
+0xDA62 0x8D7D #CJK UNIFIED IDEOGRAPH
+0xDA63 0x8D7E #CJK UNIFIED IDEOGRAPH
+0xDA64 0x8D7F #CJK UNIFIED IDEOGRAPH
+0xDA65 0x8D80 #CJK UNIFIED IDEOGRAPH
+0xDA66 0x8D82 #CJK UNIFIED IDEOGRAPH
+0xDA67 0x8D83 #CJK UNIFIED IDEOGRAPH
+0xDA68 0x8D86 #CJK UNIFIED IDEOGRAPH
+0xDA69 0x8D87 #CJK UNIFIED IDEOGRAPH
+0xDA6A 0x8D88 #CJK UNIFIED IDEOGRAPH
+0xDA6B 0x8D89 #CJK UNIFIED IDEOGRAPH
+0xDA6C 0x8D8C #CJK UNIFIED IDEOGRAPH
+0xDA6D 0x8D8D #CJK UNIFIED IDEOGRAPH
+0xDA6E 0x8D8E #CJK UNIFIED IDEOGRAPH
+0xDA6F 0x8D8F #CJK UNIFIED IDEOGRAPH
+0xDA70 0x8D90 #CJK UNIFIED IDEOGRAPH
+0xDA71 0x8D92 #CJK UNIFIED IDEOGRAPH
+0xDA72 0x8D93 #CJK UNIFIED IDEOGRAPH
+0xDA73 0x8D95 #CJK UNIFIED IDEOGRAPH
+0xDA74 0x8D96 #CJK UNIFIED IDEOGRAPH
+0xDA75 0x8D97 #CJK UNIFIED IDEOGRAPH
+0xDA76 0x8D98 #CJK UNIFIED IDEOGRAPH
+0xDA77 0x8D99 #CJK UNIFIED IDEOGRAPH
+0xDA78 0x8D9A #CJK UNIFIED IDEOGRAPH
+0xDA79 0x8D9B #CJK UNIFIED IDEOGRAPH
+0xDA7A 0x8D9C #CJK UNIFIED IDEOGRAPH
+0xDA7B 0x8D9D #CJK UNIFIED IDEOGRAPH
+0xDA7C 0x8D9E #CJK UNIFIED IDEOGRAPH
+0xDA7D 0x8DA0 #CJK UNIFIED IDEOGRAPH
+0xDA7E 0x8DA1 #CJK UNIFIED IDEOGRAPH
+0xDA80 0x8DA2 #CJK UNIFIED IDEOGRAPH
+0xDA81 0x8DA4 #CJK UNIFIED IDEOGRAPH
+0xDA82 0x8DA5 #CJK UNIFIED IDEOGRAPH
+0xDA83 0x8DA6 #CJK UNIFIED IDEOGRAPH
+0xDA84 0x8DA7 #CJK UNIFIED IDEOGRAPH
+0xDA85 0x8DA8 #CJK UNIFIED IDEOGRAPH
+0xDA86 0x8DA9 #CJK UNIFIED IDEOGRAPH
+0xDA87 0x8DAA #CJK UNIFIED IDEOGRAPH
+0xDA88 0x8DAB #CJK UNIFIED IDEOGRAPH
+0xDA89 0x8DAC #CJK UNIFIED IDEOGRAPH
+0xDA8A 0x8DAD #CJK UNIFIED IDEOGRAPH
+0xDA8B 0x8DAE #CJK UNIFIED IDEOGRAPH
+0xDA8C 0x8DAF #CJK UNIFIED IDEOGRAPH
+0xDA8D 0x8DB0 #CJK UNIFIED IDEOGRAPH
+0xDA8E 0x8DB2 #CJK UNIFIED IDEOGRAPH
+0xDA8F 0x8DB6 #CJK UNIFIED IDEOGRAPH
+0xDA90 0x8DB7 #CJK UNIFIED IDEOGRAPH
+0xDA91 0x8DB9 #CJK UNIFIED IDEOGRAPH
+0xDA92 0x8DBB #CJK UNIFIED IDEOGRAPH
+0xDA93 0x8DBD #CJK UNIFIED IDEOGRAPH
+0xDA94 0x8DC0 #CJK UNIFIED IDEOGRAPH
+0xDA95 0x8DC1 #CJK UNIFIED IDEOGRAPH
+0xDA96 0x8DC2 #CJK UNIFIED IDEOGRAPH
+0xDA97 0x8DC5 #CJK UNIFIED IDEOGRAPH
+0xDA98 0x8DC7 #CJK UNIFIED IDEOGRAPH
+0xDA99 0x8DC8 #CJK UNIFIED IDEOGRAPH
+0xDA9A 0x8DC9 #CJK UNIFIED IDEOGRAPH
+0xDA9B 0x8DCA #CJK UNIFIED IDEOGRAPH
+0xDA9C 0x8DCD #CJK UNIFIED IDEOGRAPH
+0xDA9D 0x8DD0 #CJK UNIFIED IDEOGRAPH
+0xDA9E 0x8DD2 #CJK UNIFIED IDEOGRAPH
+0xDA9F 0x8DD3 #CJK UNIFIED IDEOGRAPH
+0xDAA0 0x8DD4 #CJK UNIFIED IDEOGRAPH
+0xDAA1 0x51C7 #CJK UNIFIED IDEOGRAPH
+0xDAA2 0x5196 #CJK UNIFIED IDEOGRAPH
+0xDAA3 0x51A2 #CJK UNIFIED IDEOGRAPH
+0xDAA4 0x51A5 #CJK UNIFIED IDEOGRAPH
+0xDAA5 0x8BA0 #CJK UNIFIED IDEOGRAPH
+0xDAA6 0x8BA6 #CJK UNIFIED IDEOGRAPH
+0xDAA7 0x8BA7 #CJK UNIFIED IDEOGRAPH
+0xDAA8 0x8BAA #CJK UNIFIED IDEOGRAPH
+0xDAA9 0x8BB4 #CJK UNIFIED IDEOGRAPH
+0xDAAA 0x8BB5 #CJK UNIFIED IDEOGRAPH
+0xDAAB 0x8BB7 #CJK UNIFIED IDEOGRAPH
+0xDAAC 0x8BC2 #CJK UNIFIED IDEOGRAPH
+0xDAAD 0x8BC3 #CJK UNIFIED IDEOGRAPH
+0xDAAE 0x8BCB #CJK UNIFIED IDEOGRAPH
+0xDAAF 0x8BCF #CJK UNIFIED IDEOGRAPH
+0xDAB0 0x8BCE #CJK UNIFIED IDEOGRAPH
+0xDAB1 0x8BD2 #CJK UNIFIED IDEOGRAPH
+0xDAB2 0x8BD3 #CJK UNIFIED IDEOGRAPH
+0xDAB3 0x8BD4 #CJK UNIFIED IDEOGRAPH
+0xDAB4 0x8BD6 #CJK UNIFIED IDEOGRAPH
+0xDAB5 0x8BD8 #CJK UNIFIED IDEOGRAPH
+0xDAB6 0x8BD9 #CJK UNIFIED IDEOGRAPH
+0xDAB7 0x8BDC #CJK UNIFIED IDEOGRAPH
+0xDAB8 0x8BDF #CJK UNIFIED IDEOGRAPH
+0xDAB9 0x8BE0 #CJK UNIFIED IDEOGRAPH
+0xDABA 0x8BE4 #CJK UNIFIED IDEOGRAPH
+0xDABB 0x8BE8 #CJK UNIFIED IDEOGRAPH
+0xDABC 0x8BE9 #CJK UNIFIED IDEOGRAPH
+0xDABD 0x8BEE #CJK UNIFIED IDEOGRAPH
+0xDABE 0x8BF0 #CJK UNIFIED IDEOGRAPH
+0xDABF 0x8BF3 #CJK UNIFIED IDEOGRAPH
+0xDAC0 0x8BF6 #CJK UNIFIED IDEOGRAPH
+0xDAC1 0x8BF9 #CJK UNIFIED IDEOGRAPH
+0xDAC2 0x8BFC #CJK UNIFIED IDEOGRAPH
+0xDAC3 0x8BFF #CJK UNIFIED IDEOGRAPH
+0xDAC4 0x8C00 #CJK UNIFIED IDEOGRAPH
+0xDAC5 0x8C02 #CJK UNIFIED IDEOGRAPH
+0xDAC6 0x8C04 #CJK UNIFIED IDEOGRAPH
+0xDAC7 0x8C07 #CJK UNIFIED IDEOGRAPH
+0xDAC8 0x8C0C #CJK UNIFIED IDEOGRAPH
+0xDAC9 0x8C0F #CJK UNIFIED IDEOGRAPH
+0xDACA 0x8C11 #CJK UNIFIED IDEOGRAPH
+0xDACB 0x8C12 #CJK UNIFIED IDEOGRAPH
+0xDACC 0x8C14 #CJK UNIFIED IDEOGRAPH
+0xDACD 0x8C15 #CJK UNIFIED IDEOGRAPH
+0xDACE 0x8C16 #CJK UNIFIED IDEOGRAPH
+0xDACF 0x8C19 #CJK UNIFIED IDEOGRAPH
+0xDAD0 0x8C1B #CJK UNIFIED IDEOGRAPH
+0xDAD1 0x8C18 #CJK UNIFIED IDEOGRAPH
+0xDAD2 0x8C1D #CJK UNIFIED IDEOGRAPH
+0xDAD3 0x8C1F #CJK UNIFIED IDEOGRAPH
+0xDAD4 0x8C20 #CJK UNIFIED IDEOGRAPH
+0xDAD5 0x8C21 #CJK UNIFIED IDEOGRAPH
+0xDAD6 0x8C25 #CJK UNIFIED IDEOGRAPH
+0xDAD7 0x8C27 #CJK UNIFIED IDEOGRAPH
+0xDAD8 0x8C2A #CJK UNIFIED IDEOGRAPH
+0xDAD9 0x8C2B #CJK UNIFIED IDEOGRAPH
+0xDADA 0x8C2E #CJK UNIFIED IDEOGRAPH
+0xDADB 0x8C2F #CJK UNIFIED IDEOGRAPH
+0xDADC 0x8C32 #CJK UNIFIED IDEOGRAPH
+0xDADD 0x8C33 #CJK UNIFIED IDEOGRAPH
+0xDADE 0x8C35 #CJK UNIFIED IDEOGRAPH
+0xDADF 0x8C36 #CJK UNIFIED IDEOGRAPH
+0xDAE0 0x5369 #CJK UNIFIED IDEOGRAPH
+0xDAE1 0x537A #CJK UNIFIED IDEOGRAPH
+0xDAE2 0x961D #CJK UNIFIED IDEOGRAPH
+0xDAE3 0x9622 #CJK UNIFIED IDEOGRAPH
+0xDAE4 0x9621 #CJK UNIFIED IDEOGRAPH
+0xDAE5 0x9631 #CJK UNIFIED IDEOGRAPH
+0xDAE6 0x962A #CJK UNIFIED IDEOGRAPH
+0xDAE7 0x963D #CJK UNIFIED IDEOGRAPH
+0xDAE8 0x963C #CJK UNIFIED IDEOGRAPH
+0xDAE9 0x9642 #CJK UNIFIED IDEOGRAPH
+0xDAEA 0x9649 #CJK UNIFIED IDEOGRAPH
+0xDAEB 0x9654 #CJK UNIFIED IDEOGRAPH
+0xDAEC 0x965F #CJK UNIFIED IDEOGRAPH
+0xDAED 0x9667 #CJK UNIFIED IDEOGRAPH
+0xDAEE 0x966C #CJK UNIFIED IDEOGRAPH
+0xDAEF 0x9672 #CJK UNIFIED IDEOGRAPH
+0xDAF0 0x9674 #CJK UNIFIED IDEOGRAPH
+0xDAF1 0x9688 #CJK UNIFIED IDEOGRAPH
+0xDAF2 0x968D #CJK UNIFIED IDEOGRAPH
+0xDAF3 0x9697 #CJK UNIFIED IDEOGRAPH
+0xDAF4 0x96B0 #CJK UNIFIED IDEOGRAPH
+0xDAF5 0x9097 #CJK UNIFIED IDEOGRAPH
+0xDAF6 0x909B #CJK UNIFIED IDEOGRAPH
+0xDAF7 0x909D #CJK UNIFIED IDEOGRAPH
+0xDAF8 0x9099 #CJK UNIFIED IDEOGRAPH
+0xDAF9 0x90AC #CJK UNIFIED IDEOGRAPH
+0xDAFA 0x90A1 #CJK UNIFIED IDEOGRAPH
+0xDAFB 0x90B4 #CJK UNIFIED IDEOGRAPH
+0xDAFC 0x90B3 #CJK UNIFIED IDEOGRAPH
+0xDAFD 0x90B6 #CJK UNIFIED IDEOGRAPH
+0xDAFE 0x90BA #CJK UNIFIED IDEOGRAPH
+0xDB40 0x8DD5 #CJK UNIFIED IDEOGRAPH
+0xDB41 0x8DD8 #CJK UNIFIED IDEOGRAPH
+0xDB42 0x8DD9 #CJK UNIFIED IDEOGRAPH
+0xDB43 0x8DDC #CJK UNIFIED IDEOGRAPH
+0xDB44 0x8DE0 #CJK UNIFIED IDEOGRAPH
+0xDB45 0x8DE1 #CJK UNIFIED IDEOGRAPH
+0xDB46 0x8DE2 #CJK UNIFIED IDEOGRAPH
+0xDB47 0x8DE5 #CJK UNIFIED IDEOGRAPH
+0xDB48 0x8DE6 #CJK UNIFIED IDEOGRAPH
+0xDB49 0x8DE7 #CJK UNIFIED IDEOGRAPH
+0xDB4A 0x8DE9 #CJK UNIFIED IDEOGRAPH
+0xDB4B 0x8DED #CJK UNIFIED IDEOGRAPH
+0xDB4C 0x8DEE #CJK UNIFIED IDEOGRAPH
+0xDB4D 0x8DF0 #CJK UNIFIED IDEOGRAPH
+0xDB4E 0x8DF1 #CJK UNIFIED IDEOGRAPH
+0xDB4F 0x8DF2 #CJK UNIFIED IDEOGRAPH
+0xDB50 0x8DF4 #CJK UNIFIED IDEOGRAPH
+0xDB51 0x8DF6 #CJK UNIFIED IDEOGRAPH
+0xDB52 0x8DFC #CJK UNIFIED IDEOGRAPH
+0xDB53 0x8DFE #CJK UNIFIED IDEOGRAPH
+0xDB54 0x8DFF #CJK UNIFIED IDEOGRAPH
+0xDB55 0x8E00 #CJK UNIFIED IDEOGRAPH
+0xDB56 0x8E01 #CJK UNIFIED IDEOGRAPH
+0xDB57 0x8E02 #CJK UNIFIED IDEOGRAPH
+0xDB58 0x8E03 #CJK UNIFIED IDEOGRAPH
+0xDB59 0x8E04 #CJK UNIFIED IDEOGRAPH
+0xDB5A 0x8E06 #CJK UNIFIED IDEOGRAPH
+0xDB5B 0x8E07 #CJK UNIFIED IDEOGRAPH
+0xDB5C 0x8E08 #CJK UNIFIED IDEOGRAPH
+0xDB5D 0x8E0B #CJK UNIFIED IDEOGRAPH
+0xDB5E 0x8E0D #CJK UNIFIED IDEOGRAPH
+0xDB5F 0x8E0E #CJK UNIFIED IDEOGRAPH
+0xDB60 0x8E10 #CJK UNIFIED IDEOGRAPH
+0xDB61 0x8E11 #CJK UNIFIED IDEOGRAPH
+0xDB62 0x8E12 #CJK UNIFIED IDEOGRAPH
+0xDB63 0x8E13 #CJK UNIFIED IDEOGRAPH
+0xDB64 0x8E15 #CJK UNIFIED IDEOGRAPH
+0xDB65 0x8E16 #CJK UNIFIED IDEOGRAPH
+0xDB66 0x8E17 #CJK UNIFIED IDEOGRAPH
+0xDB67 0x8E18 #CJK UNIFIED IDEOGRAPH
+0xDB68 0x8E19 #CJK UNIFIED IDEOGRAPH
+0xDB69 0x8E1A #CJK UNIFIED IDEOGRAPH
+0xDB6A 0x8E1B #CJK UNIFIED IDEOGRAPH
+0xDB6B 0x8E1C #CJK UNIFIED IDEOGRAPH
+0xDB6C 0x8E20 #CJK UNIFIED IDEOGRAPH
+0xDB6D 0x8E21 #CJK UNIFIED IDEOGRAPH
+0xDB6E 0x8E24 #CJK UNIFIED IDEOGRAPH
+0xDB6F 0x8E25 #CJK UNIFIED IDEOGRAPH
+0xDB70 0x8E26 #CJK UNIFIED IDEOGRAPH
+0xDB71 0x8E27 #CJK UNIFIED IDEOGRAPH
+0xDB72 0x8E28 #CJK UNIFIED IDEOGRAPH
+0xDB73 0x8E2B #CJK UNIFIED IDEOGRAPH
+0xDB74 0x8E2D #CJK UNIFIED IDEOGRAPH
+0xDB75 0x8E30 #CJK UNIFIED IDEOGRAPH
+0xDB76 0x8E32 #CJK UNIFIED IDEOGRAPH
+0xDB77 0x8E33 #CJK UNIFIED IDEOGRAPH
+0xDB78 0x8E34 #CJK UNIFIED IDEOGRAPH
+0xDB79 0x8E36 #CJK UNIFIED IDEOGRAPH
+0xDB7A 0x8E37 #CJK UNIFIED IDEOGRAPH
+0xDB7B 0x8E38 #CJK UNIFIED IDEOGRAPH
+0xDB7C 0x8E3B #CJK UNIFIED IDEOGRAPH
+0xDB7D 0x8E3C #CJK UNIFIED IDEOGRAPH
+0xDB7E 0x8E3E #CJK UNIFIED IDEOGRAPH
+0xDB80 0x8E3F #CJK UNIFIED IDEOGRAPH
+0xDB81 0x8E43 #CJK UNIFIED IDEOGRAPH
+0xDB82 0x8E45 #CJK UNIFIED IDEOGRAPH
+0xDB83 0x8E46 #CJK UNIFIED IDEOGRAPH
+0xDB84 0x8E4C #CJK UNIFIED IDEOGRAPH
+0xDB85 0x8E4D #CJK UNIFIED IDEOGRAPH
+0xDB86 0x8E4E #CJK UNIFIED IDEOGRAPH
+0xDB87 0x8E4F #CJK UNIFIED IDEOGRAPH
+0xDB88 0x8E50 #CJK UNIFIED IDEOGRAPH
+0xDB89 0x8E53 #CJK UNIFIED IDEOGRAPH
+0xDB8A 0x8E54 #CJK UNIFIED IDEOGRAPH
+0xDB8B 0x8E55 #CJK UNIFIED IDEOGRAPH
+0xDB8C 0x8E56 #CJK UNIFIED IDEOGRAPH
+0xDB8D 0x8E57 #CJK UNIFIED IDEOGRAPH
+0xDB8E 0x8E58 #CJK UNIFIED IDEOGRAPH
+0xDB8F 0x8E5A #CJK UNIFIED IDEOGRAPH
+0xDB90 0x8E5B #CJK UNIFIED IDEOGRAPH
+0xDB91 0x8E5C #CJK UNIFIED IDEOGRAPH
+0xDB92 0x8E5D #CJK UNIFIED IDEOGRAPH
+0xDB93 0x8E5E #CJK UNIFIED IDEOGRAPH
+0xDB94 0x8E5F #CJK UNIFIED IDEOGRAPH
+0xDB95 0x8E60 #CJK UNIFIED IDEOGRAPH
+0xDB96 0x8E61 #CJK UNIFIED IDEOGRAPH
+0xDB97 0x8E62 #CJK UNIFIED IDEOGRAPH
+0xDB98 0x8E63 #CJK UNIFIED IDEOGRAPH
+0xDB99 0x8E64 #CJK UNIFIED IDEOGRAPH
+0xDB9A 0x8E65 #CJK UNIFIED IDEOGRAPH
+0xDB9B 0x8E67 #CJK UNIFIED IDEOGRAPH
+0xDB9C 0x8E68 #CJK UNIFIED IDEOGRAPH
+0xDB9D 0x8E6A #CJK UNIFIED IDEOGRAPH
+0xDB9E 0x8E6B #CJK UNIFIED IDEOGRAPH
+0xDB9F 0x8E6E #CJK UNIFIED IDEOGRAPH
+0xDBA0 0x8E71 #CJK UNIFIED IDEOGRAPH
+0xDBA1 0x90B8 #CJK UNIFIED IDEOGRAPH
+0xDBA2 0x90B0 #CJK UNIFIED IDEOGRAPH
+0xDBA3 0x90CF #CJK UNIFIED IDEOGRAPH
+0xDBA4 0x90C5 #CJK UNIFIED IDEOGRAPH
+0xDBA5 0x90BE #CJK UNIFIED IDEOGRAPH
+0xDBA6 0x90D0 #CJK UNIFIED IDEOGRAPH
+0xDBA7 0x90C4 #CJK UNIFIED IDEOGRAPH
+0xDBA8 0x90C7 #CJK UNIFIED IDEOGRAPH
+0xDBA9 0x90D3 #CJK UNIFIED IDEOGRAPH
+0xDBAA 0x90E6 #CJK UNIFIED IDEOGRAPH
+0xDBAB 0x90E2 #CJK UNIFIED IDEOGRAPH
+0xDBAC 0x90DC #CJK UNIFIED IDEOGRAPH
+0xDBAD 0x90D7 #CJK UNIFIED IDEOGRAPH
+0xDBAE 0x90DB #CJK UNIFIED IDEOGRAPH
+0xDBAF 0x90EB #CJK UNIFIED IDEOGRAPH
+0xDBB0 0x90EF #CJK UNIFIED IDEOGRAPH
+0xDBB1 0x90FE #CJK UNIFIED IDEOGRAPH
+0xDBB2 0x9104 #CJK UNIFIED IDEOGRAPH
+0xDBB3 0x9122 #CJK UNIFIED IDEOGRAPH
+0xDBB4 0x911E #CJK UNIFIED IDEOGRAPH
+0xDBB5 0x9123 #CJK UNIFIED IDEOGRAPH
+0xDBB6 0x9131 #CJK UNIFIED IDEOGRAPH
+0xDBB7 0x912F #CJK UNIFIED IDEOGRAPH
+0xDBB8 0x9139 #CJK UNIFIED IDEOGRAPH
+0xDBB9 0x9143 #CJK UNIFIED IDEOGRAPH
+0xDBBA 0x9146 #CJK UNIFIED IDEOGRAPH
+0xDBBB 0x520D #CJK UNIFIED IDEOGRAPH
+0xDBBC 0x5942 #CJK UNIFIED IDEOGRAPH
+0xDBBD 0x52A2 #CJK UNIFIED IDEOGRAPH
+0xDBBE 0x52AC #CJK UNIFIED IDEOGRAPH
+0xDBBF 0x52AD #CJK UNIFIED IDEOGRAPH
+0xDBC0 0x52BE #CJK UNIFIED IDEOGRAPH
+0xDBC1 0x54FF #CJK UNIFIED IDEOGRAPH
+0xDBC2 0x52D0 #CJK UNIFIED IDEOGRAPH
+0xDBC3 0x52D6 #CJK UNIFIED IDEOGRAPH
+0xDBC4 0x52F0 #CJK UNIFIED IDEOGRAPH
+0xDBC5 0x53DF #CJK UNIFIED IDEOGRAPH
+0xDBC6 0x71EE #CJK UNIFIED IDEOGRAPH
+0xDBC7 0x77CD #CJK UNIFIED IDEOGRAPH
+0xDBC8 0x5EF4 #CJK UNIFIED IDEOGRAPH
+0xDBC9 0x51F5 #CJK UNIFIED IDEOGRAPH
+0xDBCA 0x51FC #CJK UNIFIED IDEOGRAPH
+0xDBCB 0x9B2F #CJK UNIFIED IDEOGRAPH
+0xDBCC 0x53B6 #CJK UNIFIED IDEOGRAPH
+0xDBCD 0x5F01 #CJK UNIFIED IDEOGRAPH
+0xDBCE 0x755A #CJK UNIFIED IDEOGRAPH
+0xDBCF 0x5DEF #CJK UNIFIED IDEOGRAPH
+0xDBD0 0x574C #CJK UNIFIED IDEOGRAPH
+0xDBD1 0x57A9 #CJK UNIFIED IDEOGRAPH
+0xDBD2 0x57A1 #CJK UNIFIED IDEOGRAPH
+0xDBD3 0x587E #CJK UNIFIED IDEOGRAPH
+0xDBD4 0x58BC #CJK UNIFIED IDEOGRAPH
+0xDBD5 0x58C5 #CJK UNIFIED IDEOGRAPH
+0xDBD6 0x58D1 #CJK UNIFIED IDEOGRAPH
+0xDBD7 0x5729 #CJK UNIFIED IDEOGRAPH
+0xDBD8 0x572C #CJK UNIFIED IDEOGRAPH
+0xDBD9 0x572A #CJK UNIFIED IDEOGRAPH
+0xDBDA 0x5733 #CJK UNIFIED IDEOGRAPH
+0xDBDB 0x5739 #CJK UNIFIED IDEOGRAPH
+0xDBDC 0x572E #CJK UNIFIED IDEOGRAPH
+0xDBDD 0x572F #CJK UNIFIED IDEOGRAPH
+0xDBDE 0x575C #CJK UNIFIED IDEOGRAPH
+0xDBDF 0x573B #CJK UNIFIED IDEOGRAPH
+0xDBE0 0x5742 #CJK UNIFIED IDEOGRAPH
+0xDBE1 0x5769 #CJK UNIFIED IDEOGRAPH
+0xDBE2 0x5785 #CJK UNIFIED IDEOGRAPH
+0xDBE3 0x576B #CJK UNIFIED IDEOGRAPH
+0xDBE4 0x5786 #CJK UNIFIED IDEOGRAPH
+0xDBE5 0x577C #CJK UNIFIED IDEOGRAPH
+0xDBE6 0x577B #CJK UNIFIED IDEOGRAPH
+0xDBE7 0x5768 #CJK UNIFIED IDEOGRAPH
+0xDBE8 0x576D #CJK UNIFIED IDEOGRAPH
+0xDBE9 0x5776 #CJK UNIFIED IDEOGRAPH
+0xDBEA 0x5773 #CJK UNIFIED IDEOGRAPH
+0xDBEB 0x57AD #CJK UNIFIED IDEOGRAPH
+0xDBEC 0x57A4 #CJK UNIFIED IDEOGRAPH
+0xDBED 0x578C #CJK UNIFIED IDEOGRAPH
+0xDBEE 0x57B2 #CJK UNIFIED IDEOGRAPH
+0xDBEF 0x57CF #CJK UNIFIED IDEOGRAPH
+0xDBF0 0x57A7 #CJK UNIFIED IDEOGRAPH
+0xDBF1 0x57B4 #CJK UNIFIED IDEOGRAPH
+0xDBF2 0x5793 #CJK UNIFIED IDEOGRAPH
+0xDBF3 0x57A0 #CJK UNIFIED IDEOGRAPH
+0xDBF4 0x57D5 #CJK UNIFIED IDEOGRAPH
+0xDBF5 0x57D8 #CJK UNIFIED IDEOGRAPH
+0xDBF6 0x57DA #CJK UNIFIED IDEOGRAPH
+0xDBF7 0x57D9 #CJK UNIFIED IDEOGRAPH
+0xDBF8 0x57D2 #CJK UNIFIED IDEOGRAPH
+0xDBF9 0x57B8 #CJK UNIFIED IDEOGRAPH
+0xDBFA 0x57F4 #CJK UNIFIED IDEOGRAPH
+0xDBFB 0x57EF #CJK UNIFIED IDEOGRAPH
+0xDBFC 0x57F8 #CJK UNIFIED IDEOGRAPH
+0xDBFD 0x57E4 #CJK UNIFIED IDEOGRAPH
+0xDBFE 0x57DD #CJK UNIFIED IDEOGRAPH
+0xDC40 0x8E73 #CJK UNIFIED IDEOGRAPH
+0xDC41 0x8E75 #CJK UNIFIED IDEOGRAPH
+0xDC42 0x8E77 #CJK UNIFIED IDEOGRAPH
+0xDC43 0x8E78 #CJK UNIFIED IDEOGRAPH
+0xDC44 0x8E79 #CJK UNIFIED IDEOGRAPH
+0xDC45 0x8E7A #CJK UNIFIED IDEOGRAPH
+0xDC46 0x8E7B #CJK UNIFIED IDEOGRAPH
+0xDC47 0x8E7D #CJK UNIFIED IDEOGRAPH
+0xDC48 0x8E7E #CJK UNIFIED IDEOGRAPH
+0xDC49 0x8E80 #CJK UNIFIED IDEOGRAPH
+0xDC4A 0x8E82 #CJK UNIFIED IDEOGRAPH
+0xDC4B 0x8E83 #CJK UNIFIED IDEOGRAPH
+0xDC4C 0x8E84 #CJK UNIFIED IDEOGRAPH
+0xDC4D 0x8E86 #CJK UNIFIED IDEOGRAPH
+0xDC4E 0x8E88 #CJK UNIFIED IDEOGRAPH
+0xDC4F 0x8E89 #CJK UNIFIED IDEOGRAPH
+0xDC50 0x8E8A #CJK UNIFIED IDEOGRAPH
+0xDC51 0x8E8B #CJK UNIFIED IDEOGRAPH
+0xDC52 0x8E8C #CJK UNIFIED IDEOGRAPH
+0xDC53 0x8E8D #CJK UNIFIED IDEOGRAPH
+0xDC54 0x8E8E #CJK UNIFIED IDEOGRAPH
+0xDC55 0x8E91 #CJK UNIFIED IDEOGRAPH
+0xDC56 0x8E92 #CJK UNIFIED IDEOGRAPH
+0xDC57 0x8E93 #CJK UNIFIED IDEOGRAPH
+0xDC58 0x8E95 #CJK UNIFIED IDEOGRAPH
+0xDC59 0x8E96 #CJK UNIFIED IDEOGRAPH
+0xDC5A 0x8E97 #CJK UNIFIED IDEOGRAPH
+0xDC5B 0x8E98 #CJK UNIFIED IDEOGRAPH
+0xDC5C 0x8E99 #CJK UNIFIED IDEOGRAPH
+0xDC5D 0x8E9A #CJK UNIFIED IDEOGRAPH
+0xDC5E 0x8E9B #CJK UNIFIED IDEOGRAPH
+0xDC5F 0x8E9D #CJK UNIFIED IDEOGRAPH
+0xDC60 0x8E9F #CJK UNIFIED IDEOGRAPH
+0xDC61 0x8EA0 #CJK UNIFIED IDEOGRAPH
+0xDC62 0x8EA1 #CJK UNIFIED IDEOGRAPH
+0xDC63 0x8EA2 #CJK UNIFIED IDEOGRAPH
+0xDC64 0x8EA3 #CJK UNIFIED IDEOGRAPH
+0xDC65 0x8EA4 #CJK UNIFIED IDEOGRAPH
+0xDC66 0x8EA5 #CJK UNIFIED IDEOGRAPH
+0xDC67 0x8EA6 #CJK UNIFIED IDEOGRAPH
+0xDC68 0x8EA7 #CJK UNIFIED IDEOGRAPH
+0xDC69 0x8EA8 #CJK UNIFIED IDEOGRAPH
+0xDC6A 0x8EA9 #CJK UNIFIED IDEOGRAPH
+0xDC6B 0x8EAA #CJK UNIFIED IDEOGRAPH
+0xDC6C 0x8EAD #CJK UNIFIED IDEOGRAPH
+0xDC6D 0x8EAE #CJK UNIFIED IDEOGRAPH
+0xDC6E 0x8EB0 #CJK UNIFIED IDEOGRAPH
+0xDC6F 0x8EB1 #CJK UNIFIED IDEOGRAPH
+0xDC70 0x8EB3 #CJK UNIFIED IDEOGRAPH
+0xDC71 0x8EB4 #CJK UNIFIED IDEOGRAPH
+0xDC72 0x8EB5 #CJK UNIFIED IDEOGRAPH
+0xDC73 0x8EB6 #CJK UNIFIED IDEOGRAPH
+0xDC74 0x8EB7 #CJK UNIFIED IDEOGRAPH
+0xDC75 0x8EB8 #CJK UNIFIED IDEOGRAPH
+0xDC76 0x8EB9 #CJK UNIFIED IDEOGRAPH
+0xDC77 0x8EBB #CJK UNIFIED IDEOGRAPH
+0xDC78 0x8EBC #CJK UNIFIED IDEOGRAPH
+0xDC79 0x8EBD #CJK UNIFIED IDEOGRAPH
+0xDC7A 0x8EBE #CJK UNIFIED IDEOGRAPH
+0xDC7B 0x8EBF #CJK UNIFIED IDEOGRAPH
+0xDC7C 0x8EC0 #CJK UNIFIED IDEOGRAPH
+0xDC7D 0x8EC1 #CJK UNIFIED IDEOGRAPH
+0xDC7E 0x8EC2 #CJK UNIFIED IDEOGRAPH
+0xDC80 0x8EC3 #CJK UNIFIED IDEOGRAPH
+0xDC81 0x8EC4 #CJK UNIFIED IDEOGRAPH
+0xDC82 0x8EC5 #CJK UNIFIED IDEOGRAPH
+0xDC83 0x8EC6 #CJK UNIFIED IDEOGRAPH
+0xDC84 0x8EC7 #CJK UNIFIED IDEOGRAPH
+0xDC85 0x8EC8 #CJK UNIFIED IDEOGRAPH
+0xDC86 0x8EC9 #CJK UNIFIED IDEOGRAPH
+0xDC87 0x8ECA #CJK UNIFIED IDEOGRAPH
+0xDC88 0x8ECB #CJK UNIFIED IDEOGRAPH
+0xDC89 0x8ECC #CJK UNIFIED IDEOGRAPH
+0xDC8A 0x8ECD #CJK UNIFIED IDEOGRAPH
+0xDC8B 0x8ECF #CJK UNIFIED IDEOGRAPH
+0xDC8C 0x8ED0 #CJK UNIFIED IDEOGRAPH
+0xDC8D 0x8ED1 #CJK UNIFIED IDEOGRAPH
+0xDC8E 0x8ED2 #CJK UNIFIED IDEOGRAPH
+0xDC8F 0x8ED3 #CJK UNIFIED IDEOGRAPH
+0xDC90 0x8ED4 #CJK UNIFIED IDEOGRAPH
+0xDC91 0x8ED5 #CJK UNIFIED IDEOGRAPH
+0xDC92 0x8ED6 #CJK UNIFIED IDEOGRAPH
+0xDC93 0x8ED7 #CJK UNIFIED IDEOGRAPH
+0xDC94 0x8ED8 #CJK UNIFIED IDEOGRAPH
+0xDC95 0x8ED9 #CJK UNIFIED IDEOGRAPH
+0xDC96 0x8EDA #CJK UNIFIED IDEOGRAPH
+0xDC97 0x8EDB #CJK UNIFIED IDEOGRAPH
+0xDC98 0x8EDC #CJK UNIFIED IDEOGRAPH
+0xDC99 0x8EDD #CJK UNIFIED IDEOGRAPH
+0xDC9A 0x8EDE #CJK UNIFIED IDEOGRAPH
+0xDC9B 0x8EDF #CJK UNIFIED IDEOGRAPH
+0xDC9C 0x8EE0 #CJK UNIFIED IDEOGRAPH
+0xDC9D 0x8EE1 #CJK UNIFIED IDEOGRAPH
+0xDC9E 0x8EE2 #CJK UNIFIED IDEOGRAPH
+0xDC9F 0x8EE3 #CJK UNIFIED IDEOGRAPH
+0xDCA0 0x8EE4 #CJK UNIFIED IDEOGRAPH
+0xDCA1 0x580B #CJK UNIFIED IDEOGRAPH
+0xDCA2 0x580D #CJK UNIFIED IDEOGRAPH
+0xDCA3 0x57FD #CJK UNIFIED IDEOGRAPH
+0xDCA4 0x57ED #CJK UNIFIED IDEOGRAPH
+0xDCA5 0x5800 #CJK UNIFIED IDEOGRAPH
+0xDCA6 0x581E #CJK UNIFIED IDEOGRAPH
+0xDCA7 0x5819 #CJK UNIFIED IDEOGRAPH
+0xDCA8 0x5844 #CJK UNIFIED IDEOGRAPH
+0xDCA9 0x5820 #CJK UNIFIED IDEOGRAPH
+0xDCAA 0x5865 #CJK UNIFIED IDEOGRAPH
+0xDCAB 0x586C #CJK UNIFIED IDEOGRAPH
+0xDCAC 0x5881 #CJK UNIFIED IDEOGRAPH
+0xDCAD 0x5889 #CJK UNIFIED IDEOGRAPH
+0xDCAE 0x589A #CJK UNIFIED IDEOGRAPH
+0xDCAF 0x5880 #CJK UNIFIED IDEOGRAPH
+0xDCB0 0x99A8 #CJK UNIFIED IDEOGRAPH
+0xDCB1 0x9F19 #CJK UNIFIED IDEOGRAPH
+0xDCB2 0x61FF #CJK UNIFIED IDEOGRAPH
+0xDCB3 0x8279 #CJK UNIFIED IDEOGRAPH
+0xDCB4 0x827D #CJK UNIFIED IDEOGRAPH
+0xDCB5 0x827F #CJK UNIFIED IDEOGRAPH
+0xDCB6 0x828F #CJK UNIFIED IDEOGRAPH
+0xDCB7 0x828A #CJK UNIFIED IDEOGRAPH
+0xDCB8 0x82A8 #CJK UNIFIED IDEOGRAPH
+0xDCB9 0x8284 #CJK UNIFIED IDEOGRAPH
+0xDCBA 0x828E #CJK UNIFIED IDEOGRAPH
+0xDCBB 0x8291 #CJK UNIFIED IDEOGRAPH
+0xDCBC 0x8297 #CJK UNIFIED IDEOGRAPH
+0xDCBD 0x8299 #CJK UNIFIED IDEOGRAPH
+0xDCBE 0x82AB #CJK UNIFIED IDEOGRAPH
+0xDCBF 0x82B8 #CJK UNIFIED IDEOGRAPH
+0xDCC0 0x82BE #CJK UNIFIED IDEOGRAPH
+0xDCC1 0x82B0 #CJK UNIFIED IDEOGRAPH
+0xDCC2 0x82C8 #CJK UNIFIED IDEOGRAPH
+0xDCC3 0x82CA #CJK UNIFIED IDEOGRAPH
+0xDCC4 0x82E3 #CJK UNIFIED IDEOGRAPH
+0xDCC5 0x8298 #CJK UNIFIED IDEOGRAPH
+0xDCC6 0x82B7 #CJK UNIFIED IDEOGRAPH
+0xDCC7 0x82AE #CJK UNIFIED IDEOGRAPH
+0xDCC8 0x82CB #CJK UNIFIED IDEOGRAPH
+0xDCC9 0x82CC #CJK UNIFIED IDEOGRAPH
+0xDCCA 0x82C1 #CJK UNIFIED IDEOGRAPH
+0xDCCB 0x82A9 #CJK UNIFIED IDEOGRAPH
+0xDCCC 0x82B4 #CJK UNIFIED IDEOGRAPH
+0xDCCD 0x82A1 #CJK UNIFIED IDEOGRAPH
+0xDCCE 0x82AA #CJK UNIFIED IDEOGRAPH
+0xDCCF 0x829F #CJK UNIFIED IDEOGRAPH
+0xDCD0 0x82C4 #CJK UNIFIED IDEOGRAPH
+0xDCD1 0x82CE #CJK UNIFIED IDEOGRAPH
+0xDCD2 0x82A4 #CJK UNIFIED IDEOGRAPH
+0xDCD3 0x82E1 #CJK UNIFIED IDEOGRAPH
+0xDCD4 0x8309 #CJK UNIFIED IDEOGRAPH
+0xDCD5 0x82F7 #CJK UNIFIED IDEOGRAPH
+0xDCD6 0x82E4 #CJK UNIFIED IDEOGRAPH
+0xDCD7 0x830F #CJK UNIFIED IDEOGRAPH
+0xDCD8 0x8307 #CJK UNIFIED IDEOGRAPH
+0xDCD9 0x82DC #CJK UNIFIED IDEOGRAPH
+0xDCDA 0x82F4 #CJK UNIFIED IDEOGRAPH
+0xDCDB 0x82D2 #CJK UNIFIED IDEOGRAPH
+0xDCDC 0x82D8 #CJK UNIFIED IDEOGRAPH
+0xDCDD 0x830C #CJK UNIFIED IDEOGRAPH
+0xDCDE 0x82FB #CJK UNIFIED IDEOGRAPH
+0xDCDF 0x82D3 #CJK UNIFIED IDEOGRAPH
+0xDCE0 0x8311 #CJK UNIFIED IDEOGRAPH
+0xDCE1 0x831A #CJK UNIFIED IDEOGRAPH
+0xDCE2 0x8306 #CJK UNIFIED IDEOGRAPH
+0xDCE3 0x8314 #CJK UNIFIED IDEOGRAPH
+0xDCE4 0x8315 #CJK UNIFIED IDEOGRAPH
+0xDCE5 0x82E0 #CJK UNIFIED IDEOGRAPH
+0xDCE6 0x82D5 #CJK UNIFIED IDEOGRAPH
+0xDCE7 0x831C #CJK UNIFIED IDEOGRAPH
+0xDCE8 0x8351 #CJK UNIFIED IDEOGRAPH
+0xDCE9 0x835B #CJK UNIFIED IDEOGRAPH
+0xDCEA 0x835C #CJK UNIFIED IDEOGRAPH
+0xDCEB 0x8308 #CJK UNIFIED IDEOGRAPH
+0xDCEC 0x8392 #CJK UNIFIED IDEOGRAPH
+0xDCED 0x833C #CJK UNIFIED IDEOGRAPH
+0xDCEE 0x8334 #CJK UNIFIED IDEOGRAPH
+0xDCEF 0x8331 #CJK UNIFIED IDEOGRAPH
+0xDCF0 0x839B #CJK UNIFIED IDEOGRAPH
+0xDCF1 0x835E #CJK UNIFIED IDEOGRAPH
+0xDCF2 0x832F #CJK UNIFIED IDEOGRAPH
+0xDCF3 0x834F #CJK UNIFIED IDEOGRAPH
+0xDCF4 0x8347 #CJK UNIFIED IDEOGRAPH
+0xDCF5 0x8343 #CJK UNIFIED IDEOGRAPH
+0xDCF6 0x835F #CJK UNIFIED IDEOGRAPH
+0xDCF7 0x8340 #CJK UNIFIED IDEOGRAPH
+0xDCF8 0x8317 #CJK UNIFIED IDEOGRAPH
+0xDCF9 0x8360 #CJK UNIFIED IDEOGRAPH
+0xDCFA 0x832D #CJK UNIFIED IDEOGRAPH
+0xDCFB 0x833A #CJK UNIFIED IDEOGRAPH
+0xDCFC 0x8333 #CJK UNIFIED IDEOGRAPH
+0xDCFD 0x8366 #CJK UNIFIED IDEOGRAPH
+0xDCFE 0x8365 #CJK UNIFIED IDEOGRAPH
+0xDD40 0x8EE5 #CJK UNIFIED IDEOGRAPH
+0xDD41 0x8EE6 #CJK UNIFIED IDEOGRAPH
+0xDD42 0x8EE7 #CJK UNIFIED IDEOGRAPH
+0xDD43 0x8EE8 #CJK UNIFIED IDEOGRAPH
+0xDD44 0x8EE9 #CJK UNIFIED IDEOGRAPH
+0xDD45 0x8EEA #CJK UNIFIED IDEOGRAPH
+0xDD46 0x8EEB #CJK UNIFIED IDEOGRAPH
+0xDD47 0x8EEC #CJK UNIFIED IDEOGRAPH
+0xDD48 0x8EED #CJK UNIFIED IDEOGRAPH
+0xDD49 0x8EEE #CJK UNIFIED IDEOGRAPH
+0xDD4A 0x8EEF #CJK UNIFIED IDEOGRAPH
+0xDD4B 0x8EF0 #CJK UNIFIED IDEOGRAPH
+0xDD4C 0x8EF1 #CJK UNIFIED IDEOGRAPH
+0xDD4D 0x8EF2 #CJK UNIFIED IDEOGRAPH
+0xDD4E 0x8EF3 #CJK UNIFIED IDEOGRAPH
+0xDD4F 0x8EF4 #CJK UNIFIED IDEOGRAPH
+0xDD50 0x8EF5 #CJK UNIFIED IDEOGRAPH
+0xDD51 0x8EF6 #CJK UNIFIED IDEOGRAPH
+0xDD52 0x8EF7 #CJK UNIFIED IDEOGRAPH
+0xDD53 0x8EF8 #CJK UNIFIED IDEOGRAPH
+0xDD54 0x8EF9 #CJK UNIFIED IDEOGRAPH
+0xDD55 0x8EFA #CJK UNIFIED IDEOGRAPH
+0xDD56 0x8EFB #CJK UNIFIED IDEOGRAPH
+0xDD57 0x8EFC #CJK UNIFIED IDEOGRAPH
+0xDD58 0x8EFD #CJK UNIFIED IDEOGRAPH
+0xDD59 0x8EFE #CJK UNIFIED IDEOGRAPH
+0xDD5A 0x8EFF #CJK UNIFIED IDEOGRAPH
+0xDD5B 0x8F00 #CJK UNIFIED IDEOGRAPH
+0xDD5C 0x8F01 #CJK UNIFIED IDEOGRAPH
+0xDD5D 0x8F02 #CJK UNIFIED IDEOGRAPH
+0xDD5E 0x8F03 #CJK UNIFIED IDEOGRAPH
+0xDD5F 0x8F04 #CJK UNIFIED IDEOGRAPH
+0xDD60 0x8F05 #CJK UNIFIED IDEOGRAPH
+0xDD61 0x8F06 #CJK UNIFIED IDEOGRAPH
+0xDD62 0x8F07 #CJK UNIFIED IDEOGRAPH
+0xDD63 0x8F08 #CJK UNIFIED IDEOGRAPH
+0xDD64 0x8F09 #CJK UNIFIED IDEOGRAPH
+0xDD65 0x8F0A #CJK UNIFIED IDEOGRAPH
+0xDD66 0x8F0B #CJK UNIFIED IDEOGRAPH
+0xDD67 0x8F0C #CJK UNIFIED IDEOGRAPH
+0xDD68 0x8F0D #CJK UNIFIED IDEOGRAPH
+0xDD69 0x8F0E #CJK UNIFIED IDEOGRAPH
+0xDD6A 0x8F0F #CJK UNIFIED IDEOGRAPH
+0xDD6B 0x8F10 #CJK UNIFIED IDEOGRAPH
+0xDD6C 0x8F11 #CJK UNIFIED IDEOGRAPH
+0xDD6D 0x8F12 #CJK UNIFIED IDEOGRAPH
+0xDD6E 0x8F13 #CJK UNIFIED IDEOGRAPH
+0xDD6F 0x8F14 #CJK UNIFIED IDEOGRAPH
+0xDD70 0x8F15 #CJK UNIFIED IDEOGRAPH
+0xDD71 0x8F16 #CJK UNIFIED IDEOGRAPH
+0xDD72 0x8F17 #CJK UNIFIED IDEOGRAPH
+0xDD73 0x8F18 #CJK UNIFIED IDEOGRAPH
+0xDD74 0x8F19 #CJK UNIFIED IDEOGRAPH
+0xDD75 0x8F1A #CJK UNIFIED IDEOGRAPH
+0xDD76 0x8F1B #CJK UNIFIED IDEOGRAPH
+0xDD77 0x8F1C #CJK UNIFIED IDEOGRAPH
+0xDD78 0x8F1D #CJK UNIFIED IDEOGRAPH
+0xDD79 0x8F1E #CJK UNIFIED IDEOGRAPH
+0xDD7A 0x8F1F #CJK UNIFIED IDEOGRAPH
+0xDD7B 0x8F20 #CJK UNIFIED IDEOGRAPH
+0xDD7C 0x8F21 #CJK UNIFIED IDEOGRAPH
+0xDD7D 0x8F22 #CJK UNIFIED IDEOGRAPH
+0xDD7E 0x8F23 #CJK UNIFIED IDEOGRAPH
+0xDD80 0x8F24 #CJK UNIFIED IDEOGRAPH
+0xDD81 0x8F25 #CJK UNIFIED IDEOGRAPH
+0xDD82 0x8F26 #CJK UNIFIED IDEOGRAPH
+0xDD83 0x8F27 #CJK UNIFIED IDEOGRAPH
+0xDD84 0x8F28 #CJK UNIFIED IDEOGRAPH
+0xDD85 0x8F29 #CJK UNIFIED IDEOGRAPH
+0xDD86 0x8F2A #CJK UNIFIED IDEOGRAPH
+0xDD87 0x8F2B #CJK UNIFIED IDEOGRAPH
+0xDD88 0x8F2C #CJK UNIFIED IDEOGRAPH
+0xDD89 0x8F2D #CJK UNIFIED IDEOGRAPH
+0xDD8A 0x8F2E #CJK UNIFIED IDEOGRAPH
+0xDD8B 0x8F2F #CJK UNIFIED IDEOGRAPH
+0xDD8C 0x8F30 #CJK UNIFIED IDEOGRAPH
+0xDD8D 0x8F31 #CJK UNIFIED IDEOGRAPH
+0xDD8E 0x8F32 #CJK UNIFIED IDEOGRAPH
+0xDD8F 0x8F33 #CJK UNIFIED IDEOGRAPH
+0xDD90 0x8F34 #CJK UNIFIED IDEOGRAPH
+0xDD91 0x8F35 #CJK UNIFIED IDEOGRAPH
+0xDD92 0x8F36 #CJK UNIFIED IDEOGRAPH
+0xDD93 0x8F37 #CJK UNIFIED IDEOGRAPH
+0xDD94 0x8F38 #CJK UNIFIED IDEOGRAPH
+0xDD95 0x8F39 #CJK UNIFIED IDEOGRAPH
+0xDD96 0x8F3A #CJK UNIFIED IDEOGRAPH
+0xDD97 0x8F3B #CJK UNIFIED IDEOGRAPH
+0xDD98 0x8F3C #CJK UNIFIED IDEOGRAPH
+0xDD99 0x8F3D #CJK UNIFIED IDEOGRAPH
+0xDD9A 0x8F3E #CJK UNIFIED IDEOGRAPH
+0xDD9B 0x8F3F #CJK UNIFIED IDEOGRAPH
+0xDD9C 0x8F40 #CJK UNIFIED IDEOGRAPH
+0xDD9D 0x8F41 #CJK UNIFIED IDEOGRAPH
+0xDD9E 0x8F42 #CJK UNIFIED IDEOGRAPH
+0xDD9F 0x8F43 #CJK UNIFIED IDEOGRAPH
+0xDDA0 0x8F44 #CJK UNIFIED IDEOGRAPH
+0xDDA1 0x8368 #CJK UNIFIED IDEOGRAPH
+0xDDA2 0x831B #CJK UNIFIED IDEOGRAPH
+0xDDA3 0x8369 #CJK UNIFIED IDEOGRAPH
+0xDDA4 0x836C #CJK UNIFIED IDEOGRAPH
+0xDDA5 0x836A #CJK UNIFIED IDEOGRAPH
+0xDDA6 0x836D #CJK UNIFIED IDEOGRAPH
+0xDDA7 0x836E #CJK UNIFIED IDEOGRAPH
+0xDDA8 0x83B0 #CJK UNIFIED IDEOGRAPH
+0xDDA9 0x8378 #CJK UNIFIED IDEOGRAPH
+0xDDAA 0x83B3 #CJK UNIFIED IDEOGRAPH
+0xDDAB 0x83B4 #CJK UNIFIED IDEOGRAPH
+0xDDAC 0x83A0 #CJK UNIFIED IDEOGRAPH
+0xDDAD 0x83AA #CJK UNIFIED IDEOGRAPH
+0xDDAE 0x8393 #CJK UNIFIED IDEOGRAPH
+0xDDAF 0x839C #CJK UNIFIED IDEOGRAPH
+0xDDB0 0x8385 #CJK UNIFIED IDEOGRAPH
+0xDDB1 0x837C #CJK UNIFIED IDEOGRAPH
+0xDDB2 0x83B6 #CJK UNIFIED IDEOGRAPH
+0xDDB3 0x83A9 #CJK UNIFIED IDEOGRAPH
+0xDDB4 0x837D #CJK UNIFIED IDEOGRAPH
+0xDDB5 0x83B8 #CJK UNIFIED IDEOGRAPH
+0xDDB6 0x837B #CJK UNIFIED IDEOGRAPH
+0xDDB7 0x8398 #CJK UNIFIED IDEOGRAPH
+0xDDB8 0x839E #CJK UNIFIED IDEOGRAPH
+0xDDB9 0x83A8 #CJK UNIFIED IDEOGRAPH
+0xDDBA 0x83BA #CJK UNIFIED IDEOGRAPH
+0xDDBB 0x83BC #CJK UNIFIED IDEOGRAPH
+0xDDBC 0x83C1 #CJK UNIFIED IDEOGRAPH
+0xDDBD 0x8401 #CJK UNIFIED IDEOGRAPH
+0xDDBE 0x83E5 #CJK UNIFIED IDEOGRAPH
+0xDDBF 0x83D8 #CJK UNIFIED IDEOGRAPH
+0xDDC0 0x5807 #CJK UNIFIED IDEOGRAPH
+0xDDC1 0x8418 #CJK UNIFIED IDEOGRAPH
+0xDDC2 0x840B #CJK UNIFIED IDEOGRAPH
+0xDDC3 0x83DD #CJK UNIFIED IDEOGRAPH
+0xDDC4 0x83FD #CJK UNIFIED IDEOGRAPH
+0xDDC5 0x83D6 #CJK UNIFIED IDEOGRAPH
+0xDDC6 0x841C #CJK UNIFIED IDEOGRAPH
+0xDDC7 0x8438 #CJK UNIFIED IDEOGRAPH
+0xDDC8 0x8411 #CJK UNIFIED IDEOGRAPH
+0xDDC9 0x8406 #CJK UNIFIED IDEOGRAPH
+0xDDCA 0x83D4 #CJK UNIFIED IDEOGRAPH
+0xDDCB 0x83DF #CJK UNIFIED IDEOGRAPH
+0xDDCC 0x840F #CJK UNIFIED IDEOGRAPH
+0xDDCD 0x8403 #CJK UNIFIED IDEOGRAPH
+0xDDCE 0x83F8 #CJK UNIFIED IDEOGRAPH
+0xDDCF 0x83F9 #CJK UNIFIED IDEOGRAPH
+0xDDD0 0x83EA #CJK UNIFIED IDEOGRAPH
+0xDDD1 0x83C5 #CJK UNIFIED IDEOGRAPH
+0xDDD2 0x83C0 #CJK UNIFIED IDEOGRAPH
+0xDDD3 0x8426 #CJK UNIFIED IDEOGRAPH
+0xDDD4 0x83F0 #CJK UNIFIED IDEOGRAPH
+0xDDD5 0x83E1 #CJK UNIFIED IDEOGRAPH
+0xDDD6 0x845C #CJK UNIFIED IDEOGRAPH
+0xDDD7 0x8451 #CJK UNIFIED IDEOGRAPH
+0xDDD8 0x845A #CJK UNIFIED IDEOGRAPH
+0xDDD9 0x8459 #CJK UNIFIED IDEOGRAPH
+0xDDDA 0x8473 #CJK UNIFIED IDEOGRAPH
+0xDDDB 0x8487 #CJK UNIFIED IDEOGRAPH
+0xDDDC 0x8488 #CJK UNIFIED IDEOGRAPH
+0xDDDD 0x847A #CJK UNIFIED IDEOGRAPH
+0xDDDE 0x8489 #CJK UNIFIED IDEOGRAPH
+0xDDDF 0x8478 #CJK UNIFIED IDEOGRAPH
+0xDDE0 0x843C #CJK UNIFIED IDEOGRAPH
+0xDDE1 0x8446 #CJK UNIFIED IDEOGRAPH
+0xDDE2 0x8469 #CJK UNIFIED IDEOGRAPH
+0xDDE3 0x8476 #CJK UNIFIED IDEOGRAPH
+0xDDE4 0x848C #CJK UNIFIED IDEOGRAPH
+0xDDE5 0x848E #CJK UNIFIED IDEOGRAPH
+0xDDE6 0x8431 #CJK UNIFIED IDEOGRAPH
+0xDDE7 0x846D #CJK UNIFIED IDEOGRAPH
+0xDDE8 0x84C1 #CJK UNIFIED IDEOGRAPH
+0xDDE9 0x84CD #CJK UNIFIED IDEOGRAPH
+0xDDEA 0x84D0 #CJK UNIFIED IDEOGRAPH
+0xDDEB 0x84E6 #CJK UNIFIED IDEOGRAPH
+0xDDEC 0x84BD #CJK UNIFIED IDEOGRAPH
+0xDDED 0x84D3 #CJK UNIFIED IDEOGRAPH
+0xDDEE 0x84CA #CJK UNIFIED IDEOGRAPH
+0xDDEF 0x84BF #CJK UNIFIED IDEOGRAPH
+0xDDF0 0x84BA #CJK UNIFIED IDEOGRAPH
+0xDDF1 0x84E0 #CJK UNIFIED IDEOGRAPH
+0xDDF2 0x84A1 #CJK UNIFIED IDEOGRAPH
+0xDDF3 0x84B9 #CJK UNIFIED IDEOGRAPH
+0xDDF4 0x84B4 #CJK UNIFIED IDEOGRAPH
+0xDDF5 0x8497 #CJK UNIFIED IDEOGRAPH
+0xDDF6 0x84E5 #CJK UNIFIED IDEOGRAPH
+0xDDF7 0x84E3 #CJK UNIFIED IDEOGRAPH
+0xDDF8 0x850C #CJK UNIFIED IDEOGRAPH
+0xDDF9 0x750D #CJK UNIFIED IDEOGRAPH
+0xDDFA 0x8538 #CJK UNIFIED IDEOGRAPH
+0xDDFB 0x84F0 #CJK UNIFIED IDEOGRAPH
+0xDDFC 0x8539 #CJK UNIFIED IDEOGRAPH
+0xDDFD 0x851F #CJK UNIFIED IDEOGRAPH
+0xDDFE 0x853A #CJK UNIFIED IDEOGRAPH
+0xDE40 0x8F45 #CJK UNIFIED IDEOGRAPH
+0xDE41 0x8F46 #CJK UNIFIED IDEOGRAPH
+0xDE42 0x8F47 #CJK UNIFIED IDEOGRAPH
+0xDE43 0x8F48 #CJK UNIFIED IDEOGRAPH
+0xDE44 0x8F49 #CJK UNIFIED IDEOGRAPH
+0xDE45 0x8F4A #CJK UNIFIED IDEOGRAPH
+0xDE46 0x8F4B #CJK UNIFIED IDEOGRAPH
+0xDE47 0x8F4C #CJK UNIFIED IDEOGRAPH
+0xDE48 0x8F4D #CJK UNIFIED IDEOGRAPH
+0xDE49 0x8F4E #CJK UNIFIED IDEOGRAPH
+0xDE4A 0x8F4F #CJK UNIFIED IDEOGRAPH
+0xDE4B 0x8F50 #CJK UNIFIED IDEOGRAPH
+0xDE4C 0x8F51 #CJK UNIFIED IDEOGRAPH
+0xDE4D 0x8F52 #CJK UNIFIED IDEOGRAPH
+0xDE4E 0x8F53 #CJK UNIFIED IDEOGRAPH
+0xDE4F 0x8F54 #CJK UNIFIED IDEOGRAPH
+0xDE50 0x8F55 #CJK UNIFIED IDEOGRAPH
+0xDE51 0x8F56 #CJK UNIFIED IDEOGRAPH
+0xDE52 0x8F57 #CJK UNIFIED IDEOGRAPH
+0xDE53 0x8F58 #CJK UNIFIED IDEOGRAPH
+0xDE54 0x8F59 #CJK UNIFIED IDEOGRAPH
+0xDE55 0x8F5A #CJK UNIFIED IDEOGRAPH
+0xDE56 0x8F5B #CJK UNIFIED IDEOGRAPH
+0xDE57 0x8F5C #CJK UNIFIED IDEOGRAPH
+0xDE58 0x8F5D #CJK UNIFIED IDEOGRAPH
+0xDE59 0x8F5E #CJK UNIFIED IDEOGRAPH
+0xDE5A 0x8F5F #CJK UNIFIED IDEOGRAPH
+0xDE5B 0x8F60 #CJK UNIFIED IDEOGRAPH
+0xDE5C 0x8F61 #CJK UNIFIED IDEOGRAPH
+0xDE5D 0x8F62 #CJK UNIFIED IDEOGRAPH
+0xDE5E 0x8F63 #CJK UNIFIED IDEOGRAPH
+0xDE5F 0x8F64 #CJK UNIFIED IDEOGRAPH
+0xDE60 0x8F65 #CJK UNIFIED IDEOGRAPH
+0xDE61 0x8F6A #CJK UNIFIED IDEOGRAPH
+0xDE62 0x8F80 #CJK UNIFIED IDEOGRAPH
+0xDE63 0x8F8C #CJK UNIFIED IDEOGRAPH
+0xDE64 0x8F92 #CJK UNIFIED IDEOGRAPH
+0xDE65 0x8F9D #CJK UNIFIED IDEOGRAPH
+0xDE66 0x8FA0 #CJK UNIFIED IDEOGRAPH
+0xDE67 0x8FA1 #CJK UNIFIED IDEOGRAPH
+0xDE68 0x8FA2 #CJK UNIFIED IDEOGRAPH
+0xDE69 0x8FA4 #CJK UNIFIED IDEOGRAPH
+0xDE6A 0x8FA5 #CJK UNIFIED IDEOGRAPH
+0xDE6B 0x8FA6 #CJK UNIFIED IDEOGRAPH
+0xDE6C 0x8FA7 #CJK UNIFIED IDEOGRAPH
+0xDE6D 0x8FAA #CJK UNIFIED IDEOGRAPH
+0xDE6E 0x8FAC #CJK UNIFIED IDEOGRAPH
+0xDE6F 0x8FAD #CJK UNIFIED IDEOGRAPH
+0xDE70 0x8FAE #CJK UNIFIED IDEOGRAPH
+0xDE71 0x8FAF #CJK UNIFIED IDEOGRAPH
+0xDE72 0x8FB2 #CJK UNIFIED IDEOGRAPH
+0xDE73 0x8FB3 #CJK UNIFIED IDEOGRAPH
+0xDE74 0x8FB4 #CJK UNIFIED IDEOGRAPH
+0xDE75 0x8FB5 #CJK UNIFIED IDEOGRAPH
+0xDE76 0x8FB7 #CJK UNIFIED IDEOGRAPH
+0xDE77 0x8FB8 #CJK UNIFIED IDEOGRAPH
+0xDE78 0x8FBA #CJK UNIFIED IDEOGRAPH
+0xDE79 0x8FBB #CJK UNIFIED IDEOGRAPH
+0xDE7A 0x8FBC #CJK UNIFIED IDEOGRAPH
+0xDE7B 0x8FBF #CJK UNIFIED IDEOGRAPH
+0xDE7C 0x8FC0 #CJK UNIFIED IDEOGRAPH
+0xDE7D 0x8FC3 #CJK UNIFIED IDEOGRAPH
+0xDE7E 0x8FC6 #CJK UNIFIED IDEOGRAPH
+0xDE80 0x8FC9 #CJK UNIFIED IDEOGRAPH
+0xDE81 0x8FCA #CJK UNIFIED IDEOGRAPH
+0xDE82 0x8FCB #CJK UNIFIED IDEOGRAPH
+0xDE83 0x8FCC #CJK UNIFIED IDEOGRAPH
+0xDE84 0x8FCD #CJK UNIFIED IDEOGRAPH
+0xDE85 0x8FCF #CJK UNIFIED IDEOGRAPH
+0xDE86 0x8FD2 #CJK UNIFIED IDEOGRAPH
+0xDE87 0x8FD6 #CJK UNIFIED IDEOGRAPH
+0xDE88 0x8FD7 #CJK UNIFIED IDEOGRAPH
+0xDE89 0x8FDA #CJK UNIFIED IDEOGRAPH
+0xDE8A 0x8FE0 #CJK UNIFIED IDEOGRAPH
+0xDE8B 0x8FE1 #CJK UNIFIED IDEOGRAPH
+0xDE8C 0x8FE3 #CJK UNIFIED IDEOGRAPH
+0xDE8D 0x8FE7 #CJK UNIFIED IDEOGRAPH
+0xDE8E 0x8FEC #CJK UNIFIED IDEOGRAPH
+0xDE8F 0x8FEF #CJK UNIFIED IDEOGRAPH
+0xDE90 0x8FF1 #CJK UNIFIED IDEOGRAPH
+0xDE91 0x8FF2 #CJK UNIFIED IDEOGRAPH
+0xDE92 0x8FF4 #CJK UNIFIED IDEOGRAPH
+0xDE93 0x8FF5 #CJK UNIFIED IDEOGRAPH
+0xDE94 0x8FF6 #CJK UNIFIED IDEOGRAPH
+0xDE95 0x8FFA #CJK UNIFIED IDEOGRAPH
+0xDE96 0x8FFB #CJK UNIFIED IDEOGRAPH
+0xDE97 0x8FFC #CJK UNIFIED IDEOGRAPH
+0xDE98 0x8FFE #CJK UNIFIED IDEOGRAPH
+0xDE99 0x8FFF #CJK UNIFIED IDEOGRAPH
+0xDE9A 0x9007 #CJK UNIFIED IDEOGRAPH
+0xDE9B 0x9008 #CJK UNIFIED IDEOGRAPH
+0xDE9C 0x900C #CJK UNIFIED IDEOGRAPH
+0xDE9D 0x900E #CJK UNIFIED IDEOGRAPH
+0xDE9E 0x9013 #CJK UNIFIED IDEOGRAPH
+0xDE9F 0x9015 #CJK UNIFIED IDEOGRAPH
+0xDEA0 0x9018 #CJK UNIFIED IDEOGRAPH
+0xDEA1 0x8556 #CJK UNIFIED IDEOGRAPH
+0xDEA2 0x853B #CJK UNIFIED IDEOGRAPH
+0xDEA3 0x84FF #CJK UNIFIED IDEOGRAPH
+0xDEA4 0x84FC #CJK UNIFIED IDEOGRAPH
+0xDEA5 0x8559 #CJK UNIFIED IDEOGRAPH
+0xDEA6 0x8548 #CJK UNIFIED IDEOGRAPH
+0xDEA7 0x8568 #CJK UNIFIED IDEOGRAPH
+0xDEA8 0x8564 #CJK UNIFIED IDEOGRAPH
+0xDEA9 0x855E #CJK UNIFIED IDEOGRAPH
+0xDEAA 0x857A #CJK UNIFIED IDEOGRAPH
+0xDEAB 0x77A2 #CJK UNIFIED IDEOGRAPH
+0xDEAC 0x8543 #CJK UNIFIED IDEOGRAPH
+0xDEAD 0x8572 #CJK UNIFIED IDEOGRAPH
+0xDEAE 0x857B #CJK UNIFIED IDEOGRAPH
+0xDEAF 0x85A4 #CJK UNIFIED IDEOGRAPH
+0xDEB0 0x85A8 #CJK UNIFIED IDEOGRAPH
+0xDEB1 0x8587 #CJK UNIFIED IDEOGRAPH
+0xDEB2 0x858F #CJK UNIFIED IDEOGRAPH
+0xDEB3 0x8579 #CJK UNIFIED IDEOGRAPH
+0xDEB4 0x85AE #CJK UNIFIED IDEOGRAPH
+0xDEB5 0x859C #CJK UNIFIED IDEOGRAPH
+0xDEB6 0x8585 #CJK UNIFIED IDEOGRAPH
+0xDEB7 0x85B9 #CJK UNIFIED IDEOGRAPH
+0xDEB8 0x85B7 #CJK UNIFIED IDEOGRAPH
+0xDEB9 0x85B0 #CJK UNIFIED IDEOGRAPH
+0xDEBA 0x85D3 #CJK UNIFIED IDEOGRAPH
+0xDEBB 0x85C1 #CJK UNIFIED IDEOGRAPH
+0xDEBC 0x85DC #CJK UNIFIED IDEOGRAPH
+0xDEBD 0x85FF #CJK UNIFIED IDEOGRAPH
+0xDEBE 0x8627 #CJK UNIFIED IDEOGRAPH
+0xDEBF 0x8605 #CJK UNIFIED IDEOGRAPH
+0xDEC0 0x8629 #CJK UNIFIED IDEOGRAPH
+0xDEC1 0x8616 #CJK UNIFIED IDEOGRAPH
+0xDEC2 0x863C #CJK UNIFIED IDEOGRAPH
+0xDEC3 0x5EFE #CJK UNIFIED IDEOGRAPH
+0xDEC4 0x5F08 #CJK UNIFIED IDEOGRAPH
+0xDEC5 0x593C #CJK UNIFIED IDEOGRAPH
+0xDEC6 0x5941 #CJK UNIFIED IDEOGRAPH
+0xDEC7 0x8037 #CJK UNIFIED IDEOGRAPH
+0xDEC8 0x5955 #CJK UNIFIED IDEOGRAPH
+0xDEC9 0x595A #CJK UNIFIED IDEOGRAPH
+0xDECA 0x5958 #CJK UNIFIED IDEOGRAPH
+0xDECB 0x530F #CJK UNIFIED IDEOGRAPH
+0xDECC 0x5C22 #CJK UNIFIED IDEOGRAPH
+0xDECD 0x5C25 #CJK UNIFIED IDEOGRAPH
+0xDECE 0x5C2C #CJK UNIFIED IDEOGRAPH
+0xDECF 0x5C34 #CJK UNIFIED IDEOGRAPH
+0xDED0 0x624C #CJK UNIFIED IDEOGRAPH
+0xDED1 0x626A #CJK UNIFIED IDEOGRAPH
+0xDED2 0x629F #CJK UNIFIED IDEOGRAPH
+0xDED3 0x62BB #CJK UNIFIED IDEOGRAPH
+0xDED4 0x62CA #CJK UNIFIED IDEOGRAPH
+0xDED5 0x62DA #CJK UNIFIED IDEOGRAPH
+0xDED6 0x62D7 #CJK UNIFIED IDEOGRAPH
+0xDED7 0x62EE #CJK UNIFIED IDEOGRAPH
+0xDED8 0x6322 #CJK UNIFIED IDEOGRAPH
+0xDED9 0x62F6 #CJK UNIFIED IDEOGRAPH
+0xDEDA 0x6339 #CJK UNIFIED IDEOGRAPH
+0xDEDB 0x634B #CJK UNIFIED IDEOGRAPH
+0xDEDC 0x6343 #CJK UNIFIED IDEOGRAPH
+0xDEDD 0x63AD #CJK UNIFIED IDEOGRAPH
+0xDEDE 0x63F6 #CJK UNIFIED IDEOGRAPH
+0xDEDF 0x6371 #CJK UNIFIED IDEOGRAPH
+0xDEE0 0x637A #CJK UNIFIED IDEOGRAPH
+0xDEE1 0x638E #CJK UNIFIED IDEOGRAPH
+0xDEE2 0x63B4 #CJK UNIFIED IDEOGRAPH
+0xDEE3 0x636D #CJK UNIFIED IDEOGRAPH
+0xDEE4 0x63AC #CJK UNIFIED IDEOGRAPH
+0xDEE5 0x638A #CJK UNIFIED IDEOGRAPH
+0xDEE6 0x6369 #CJK UNIFIED IDEOGRAPH
+0xDEE7 0x63AE #CJK UNIFIED IDEOGRAPH
+0xDEE8 0x63BC #CJK UNIFIED IDEOGRAPH
+0xDEE9 0x63F2 #CJK UNIFIED IDEOGRAPH
+0xDEEA 0x63F8 #CJK UNIFIED IDEOGRAPH
+0xDEEB 0x63E0 #CJK UNIFIED IDEOGRAPH
+0xDEEC 0x63FF #CJK UNIFIED IDEOGRAPH
+0xDEED 0x63C4 #CJK UNIFIED IDEOGRAPH
+0xDEEE 0x63DE #CJK UNIFIED IDEOGRAPH
+0xDEEF 0x63CE #CJK UNIFIED IDEOGRAPH
+0xDEF0 0x6452 #CJK UNIFIED IDEOGRAPH
+0xDEF1 0x63C6 #CJK UNIFIED IDEOGRAPH
+0xDEF2 0x63BE #CJK UNIFIED IDEOGRAPH
+0xDEF3 0x6445 #CJK UNIFIED IDEOGRAPH
+0xDEF4 0x6441 #CJK UNIFIED IDEOGRAPH
+0xDEF5 0x640B #CJK UNIFIED IDEOGRAPH
+0xDEF6 0x641B #CJK UNIFIED IDEOGRAPH
+0xDEF7 0x6420 #CJK UNIFIED IDEOGRAPH
+0xDEF8 0x640C #CJK UNIFIED IDEOGRAPH
+0xDEF9 0x6426 #CJK UNIFIED IDEOGRAPH
+0xDEFA 0x6421 #CJK UNIFIED IDEOGRAPH
+0xDEFB 0x645E #CJK UNIFIED IDEOGRAPH
+0xDEFC 0x6484 #CJK UNIFIED IDEOGRAPH
+0xDEFD 0x646D #CJK UNIFIED IDEOGRAPH
+0xDEFE 0x6496 #CJK UNIFIED IDEOGRAPH
+0xDF40 0x9019 #CJK UNIFIED IDEOGRAPH
+0xDF41 0x901C #CJK UNIFIED IDEOGRAPH
+0xDF42 0x9023 #CJK UNIFIED IDEOGRAPH
+0xDF43 0x9024 #CJK UNIFIED IDEOGRAPH
+0xDF44 0x9025 #CJK UNIFIED IDEOGRAPH
+0xDF45 0x9027 #CJK UNIFIED IDEOGRAPH
+0xDF46 0x9028 #CJK UNIFIED IDEOGRAPH
+0xDF47 0x9029 #CJK UNIFIED IDEOGRAPH
+0xDF48 0x902A #CJK UNIFIED IDEOGRAPH
+0xDF49 0x902B #CJK UNIFIED IDEOGRAPH
+0xDF4A 0x902C #CJK UNIFIED IDEOGRAPH
+0xDF4B 0x9030 #CJK UNIFIED IDEOGRAPH
+0xDF4C 0x9031 #CJK UNIFIED IDEOGRAPH
+0xDF4D 0x9032 #CJK UNIFIED IDEOGRAPH
+0xDF4E 0x9033 #CJK UNIFIED IDEOGRAPH
+0xDF4F 0x9034 #CJK UNIFIED IDEOGRAPH
+0xDF50 0x9037 #CJK UNIFIED IDEOGRAPH
+0xDF51 0x9039 #CJK UNIFIED IDEOGRAPH
+0xDF52 0x903A #CJK UNIFIED IDEOGRAPH
+0xDF53 0x903D #CJK UNIFIED IDEOGRAPH
+0xDF54 0x903F #CJK UNIFIED IDEOGRAPH
+0xDF55 0x9040 #CJK UNIFIED IDEOGRAPH
+0xDF56 0x9043 #CJK UNIFIED IDEOGRAPH
+0xDF57 0x9045 #CJK UNIFIED IDEOGRAPH
+0xDF58 0x9046 #CJK UNIFIED IDEOGRAPH
+0xDF59 0x9048 #CJK UNIFIED IDEOGRAPH
+0xDF5A 0x9049 #CJK UNIFIED IDEOGRAPH
+0xDF5B 0x904A #CJK UNIFIED IDEOGRAPH
+0xDF5C 0x904B #CJK UNIFIED IDEOGRAPH
+0xDF5D 0x904C #CJK UNIFIED IDEOGRAPH
+0xDF5E 0x904E #CJK UNIFIED IDEOGRAPH
+0xDF5F 0x9054 #CJK UNIFIED IDEOGRAPH
+0xDF60 0x9055 #CJK UNIFIED IDEOGRAPH
+0xDF61 0x9056 #CJK UNIFIED IDEOGRAPH
+0xDF62 0x9059 #CJK UNIFIED IDEOGRAPH
+0xDF63 0x905A #CJK UNIFIED IDEOGRAPH
+0xDF64 0x905C #CJK UNIFIED IDEOGRAPH
+0xDF65 0x905D #CJK UNIFIED IDEOGRAPH
+0xDF66 0x905E #CJK UNIFIED IDEOGRAPH
+0xDF67 0x905F #CJK UNIFIED IDEOGRAPH
+0xDF68 0x9060 #CJK UNIFIED IDEOGRAPH
+0xDF69 0x9061 #CJK UNIFIED IDEOGRAPH
+0xDF6A 0x9064 #CJK UNIFIED IDEOGRAPH
+0xDF6B 0x9066 #CJK UNIFIED IDEOGRAPH
+0xDF6C 0x9067 #CJK UNIFIED IDEOGRAPH
+0xDF6D 0x9069 #CJK UNIFIED IDEOGRAPH
+0xDF6E 0x906A #CJK UNIFIED IDEOGRAPH
+0xDF6F 0x906B #CJK UNIFIED IDEOGRAPH
+0xDF70 0x906C #CJK UNIFIED IDEOGRAPH
+0xDF71 0x906F #CJK UNIFIED IDEOGRAPH
+0xDF72 0x9070 #CJK UNIFIED IDEOGRAPH
+0xDF73 0x9071 #CJK UNIFIED IDEOGRAPH
+0xDF74 0x9072 #CJK UNIFIED IDEOGRAPH
+0xDF75 0x9073 #CJK UNIFIED IDEOGRAPH
+0xDF76 0x9076 #CJK UNIFIED IDEOGRAPH
+0xDF77 0x9077 #CJK UNIFIED IDEOGRAPH
+0xDF78 0x9078 #CJK UNIFIED IDEOGRAPH
+0xDF79 0x9079 #CJK UNIFIED IDEOGRAPH
+0xDF7A 0x907A #CJK UNIFIED IDEOGRAPH
+0xDF7B 0x907B #CJK UNIFIED IDEOGRAPH
+0xDF7C 0x907C #CJK UNIFIED IDEOGRAPH
+0xDF7D 0x907E #CJK UNIFIED IDEOGRAPH
+0xDF7E 0x9081 #CJK UNIFIED IDEOGRAPH
+0xDF80 0x9084 #CJK UNIFIED IDEOGRAPH
+0xDF81 0x9085 #CJK UNIFIED IDEOGRAPH
+0xDF82 0x9086 #CJK UNIFIED IDEOGRAPH
+0xDF83 0x9087 #CJK UNIFIED IDEOGRAPH
+0xDF84 0x9089 #CJK UNIFIED IDEOGRAPH
+0xDF85 0x908A #CJK UNIFIED IDEOGRAPH
+0xDF86 0x908C #CJK UNIFIED IDEOGRAPH
+0xDF87 0x908D #CJK UNIFIED IDEOGRAPH
+0xDF88 0x908E #CJK UNIFIED IDEOGRAPH
+0xDF89 0x908F #CJK UNIFIED IDEOGRAPH
+0xDF8A 0x9090 #CJK UNIFIED IDEOGRAPH
+0xDF8B 0x9092 #CJK UNIFIED IDEOGRAPH
+0xDF8C 0x9094 #CJK UNIFIED IDEOGRAPH
+0xDF8D 0x9096 #CJK UNIFIED IDEOGRAPH
+0xDF8E 0x9098 #CJK UNIFIED IDEOGRAPH
+0xDF8F 0x909A #CJK UNIFIED IDEOGRAPH
+0xDF90 0x909C #CJK UNIFIED IDEOGRAPH
+0xDF91 0x909E #CJK UNIFIED IDEOGRAPH
+0xDF92 0x909F #CJK UNIFIED IDEOGRAPH
+0xDF93 0x90A0 #CJK UNIFIED IDEOGRAPH
+0xDF94 0x90A4 #CJK UNIFIED IDEOGRAPH
+0xDF95 0x90A5 #CJK UNIFIED IDEOGRAPH
+0xDF96 0x90A7 #CJK UNIFIED IDEOGRAPH
+0xDF97 0x90A8 #CJK UNIFIED IDEOGRAPH
+0xDF98 0x90A9 #CJK UNIFIED IDEOGRAPH
+0xDF99 0x90AB #CJK UNIFIED IDEOGRAPH
+0xDF9A 0x90AD #CJK UNIFIED IDEOGRAPH
+0xDF9B 0x90B2 #CJK UNIFIED IDEOGRAPH
+0xDF9C 0x90B7 #CJK UNIFIED IDEOGRAPH
+0xDF9D 0x90BC #CJK UNIFIED IDEOGRAPH
+0xDF9E 0x90BD #CJK UNIFIED IDEOGRAPH
+0xDF9F 0x90BF #CJK UNIFIED IDEOGRAPH
+0xDFA0 0x90C0 #CJK UNIFIED IDEOGRAPH
+0xDFA1 0x647A #CJK UNIFIED IDEOGRAPH
+0xDFA2 0x64B7 #CJK UNIFIED IDEOGRAPH
+0xDFA3 0x64B8 #CJK UNIFIED IDEOGRAPH
+0xDFA4 0x6499 #CJK UNIFIED IDEOGRAPH
+0xDFA5 0x64BA #CJK UNIFIED IDEOGRAPH
+0xDFA6 0x64C0 #CJK UNIFIED IDEOGRAPH
+0xDFA7 0x64D0 #CJK UNIFIED IDEOGRAPH
+0xDFA8 0x64D7 #CJK UNIFIED IDEOGRAPH
+0xDFA9 0x64E4 #CJK UNIFIED IDEOGRAPH
+0xDFAA 0x64E2 #CJK UNIFIED IDEOGRAPH
+0xDFAB 0x6509 #CJK UNIFIED IDEOGRAPH
+0xDFAC 0x6525 #CJK UNIFIED IDEOGRAPH
+0xDFAD 0x652E #CJK UNIFIED IDEOGRAPH
+0xDFAE 0x5F0B #CJK UNIFIED IDEOGRAPH
+0xDFAF 0x5FD2 #CJK UNIFIED IDEOGRAPH
+0xDFB0 0x7519 #CJK UNIFIED IDEOGRAPH
+0xDFB1 0x5F11 #CJK UNIFIED IDEOGRAPH
+0xDFB2 0x535F #CJK UNIFIED IDEOGRAPH
+0xDFB3 0x53F1 #CJK UNIFIED IDEOGRAPH
+0xDFB4 0x53FD #CJK UNIFIED IDEOGRAPH
+0xDFB5 0x53E9 #CJK UNIFIED IDEOGRAPH
+0xDFB6 0x53E8 #CJK UNIFIED IDEOGRAPH
+0xDFB7 0x53FB #CJK UNIFIED IDEOGRAPH
+0xDFB8 0x5412 #CJK UNIFIED IDEOGRAPH
+0xDFB9 0x5416 #CJK UNIFIED IDEOGRAPH
+0xDFBA 0x5406 #CJK UNIFIED IDEOGRAPH
+0xDFBB 0x544B #CJK UNIFIED IDEOGRAPH
+0xDFBC 0x5452 #CJK UNIFIED IDEOGRAPH
+0xDFBD 0x5453 #CJK UNIFIED IDEOGRAPH
+0xDFBE 0x5454 #CJK UNIFIED IDEOGRAPH
+0xDFBF 0x5456 #CJK UNIFIED IDEOGRAPH
+0xDFC0 0x5443 #CJK UNIFIED IDEOGRAPH
+0xDFC1 0x5421 #CJK UNIFIED IDEOGRAPH
+0xDFC2 0x5457 #CJK UNIFIED IDEOGRAPH
+0xDFC3 0x5459 #CJK UNIFIED IDEOGRAPH
+0xDFC4 0x5423 #CJK UNIFIED IDEOGRAPH
+0xDFC5 0x5432 #CJK UNIFIED IDEOGRAPH
+0xDFC6 0x5482 #CJK UNIFIED IDEOGRAPH
+0xDFC7 0x5494 #CJK UNIFIED IDEOGRAPH
+0xDFC8 0x5477 #CJK UNIFIED IDEOGRAPH
+0xDFC9 0x5471 #CJK UNIFIED IDEOGRAPH
+0xDFCA 0x5464 #CJK UNIFIED IDEOGRAPH
+0xDFCB 0x549A #CJK UNIFIED IDEOGRAPH
+0xDFCC 0x549B #CJK UNIFIED IDEOGRAPH
+0xDFCD 0x5484 #CJK UNIFIED IDEOGRAPH
+0xDFCE 0x5476 #CJK UNIFIED IDEOGRAPH
+0xDFCF 0x5466 #CJK UNIFIED IDEOGRAPH
+0xDFD0 0x549D #CJK UNIFIED IDEOGRAPH
+0xDFD1 0x54D0 #CJK UNIFIED IDEOGRAPH
+0xDFD2 0x54AD #CJK UNIFIED IDEOGRAPH
+0xDFD3 0x54C2 #CJK UNIFIED IDEOGRAPH
+0xDFD4 0x54B4 #CJK UNIFIED IDEOGRAPH
+0xDFD5 0x54D2 #CJK UNIFIED IDEOGRAPH
+0xDFD6 0x54A7 #CJK UNIFIED IDEOGRAPH
+0xDFD7 0x54A6 #CJK UNIFIED IDEOGRAPH
+0xDFD8 0x54D3 #CJK UNIFIED IDEOGRAPH
+0xDFD9 0x54D4 #CJK UNIFIED IDEOGRAPH
+0xDFDA 0x5472 #CJK UNIFIED IDEOGRAPH
+0xDFDB 0x54A3 #CJK UNIFIED IDEOGRAPH
+0xDFDC 0x54D5 #CJK UNIFIED IDEOGRAPH
+0xDFDD 0x54BB #CJK UNIFIED IDEOGRAPH
+0xDFDE 0x54BF #CJK UNIFIED IDEOGRAPH
+0xDFDF 0x54CC #CJK UNIFIED IDEOGRAPH
+0xDFE0 0x54D9 #CJK UNIFIED IDEOGRAPH
+0xDFE1 0x54DA #CJK UNIFIED IDEOGRAPH
+0xDFE2 0x54DC #CJK UNIFIED IDEOGRAPH
+0xDFE3 0x54A9 #CJK UNIFIED IDEOGRAPH
+0xDFE4 0x54AA #CJK UNIFIED IDEOGRAPH
+0xDFE5 0x54A4 #CJK UNIFIED IDEOGRAPH
+0xDFE6 0x54DD #CJK UNIFIED IDEOGRAPH
+0xDFE7 0x54CF #CJK UNIFIED IDEOGRAPH
+0xDFE8 0x54DE #CJK UNIFIED IDEOGRAPH
+0xDFE9 0x551B #CJK UNIFIED IDEOGRAPH
+0xDFEA 0x54E7 #CJK UNIFIED IDEOGRAPH
+0xDFEB 0x5520 #CJK UNIFIED IDEOGRAPH
+0xDFEC 0x54FD #CJK UNIFIED IDEOGRAPH
+0xDFED 0x5514 #CJK UNIFIED IDEOGRAPH
+0xDFEE 0x54F3 #CJK UNIFIED IDEOGRAPH
+0xDFEF 0x5522 #CJK UNIFIED IDEOGRAPH
+0xDFF0 0x5523 #CJK UNIFIED IDEOGRAPH
+0xDFF1 0x550F #CJK UNIFIED IDEOGRAPH
+0xDFF2 0x5511 #CJK UNIFIED IDEOGRAPH
+0xDFF3 0x5527 #CJK UNIFIED IDEOGRAPH
+0xDFF4 0x552A #CJK UNIFIED IDEOGRAPH
+0xDFF5 0x5567 #CJK UNIFIED IDEOGRAPH
+0xDFF6 0x558F #CJK UNIFIED IDEOGRAPH
+0xDFF7 0x55B5 #CJK UNIFIED IDEOGRAPH
+0xDFF8 0x5549 #CJK UNIFIED IDEOGRAPH
+0xDFF9 0x556D #CJK UNIFIED IDEOGRAPH
+0xDFFA 0x5541 #CJK UNIFIED IDEOGRAPH
+0xDFFB 0x5555 #CJK UNIFIED IDEOGRAPH
+0xDFFC 0x553F #CJK UNIFIED IDEOGRAPH
+0xDFFD 0x5550 #CJK UNIFIED IDEOGRAPH
+0xDFFE 0x553C #CJK UNIFIED IDEOGRAPH
+0xE040 0x90C2 #CJK UNIFIED IDEOGRAPH
+0xE041 0x90C3 #CJK UNIFIED IDEOGRAPH
+0xE042 0x90C6 #CJK UNIFIED IDEOGRAPH
+0xE043 0x90C8 #CJK UNIFIED IDEOGRAPH
+0xE044 0x90C9 #CJK UNIFIED IDEOGRAPH
+0xE045 0x90CB #CJK UNIFIED IDEOGRAPH
+0xE046 0x90CC #CJK UNIFIED IDEOGRAPH
+0xE047 0x90CD #CJK UNIFIED IDEOGRAPH
+0xE048 0x90D2 #CJK UNIFIED IDEOGRAPH
+0xE049 0x90D4 #CJK UNIFIED IDEOGRAPH
+0xE04A 0x90D5 #CJK UNIFIED IDEOGRAPH
+0xE04B 0x90D6 #CJK UNIFIED IDEOGRAPH
+0xE04C 0x90D8 #CJK UNIFIED IDEOGRAPH
+0xE04D 0x90D9 #CJK UNIFIED IDEOGRAPH
+0xE04E 0x90DA #CJK UNIFIED IDEOGRAPH
+0xE04F 0x90DE #CJK UNIFIED IDEOGRAPH
+0xE050 0x90DF #CJK UNIFIED IDEOGRAPH
+0xE051 0x90E0 #CJK UNIFIED IDEOGRAPH
+0xE052 0x90E3 #CJK UNIFIED IDEOGRAPH
+0xE053 0x90E4 #CJK UNIFIED IDEOGRAPH
+0xE054 0x90E5 #CJK UNIFIED IDEOGRAPH
+0xE055 0x90E9 #CJK UNIFIED IDEOGRAPH
+0xE056 0x90EA #CJK UNIFIED IDEOGRAPH
+0xE057 0x90EC #CJK UNIFIED IDEOGRAPH
+0xE058 0x90EE #CJK UNIFIED IDEOGRAPH
+0xE059 0x90F0 #CJK UNIFIED IDEOGRAPH
+0xE05A 0x90F1 #CJK UNIFIED IDEOGRAPH
+0xE05B 0x90F2 #CJK UNIFIED IDEOGRAPH
+0xE05C 0x90F3 #CJK UNIFIED IDEOGRAPH
+0xE05D 0x90F5 #CJK UNIFIED IDEOGRAPH
+0xE05E 0x90F6 #CJK UNIFIED IDEOGRAPH
+0xE05F 0x90F7 #CJK UNIFIED IDEOGRAPH
+0xE060 0x90F9 #CJK UNIFIED IDEOGRAPH
+0xE061 0x90FA #CJK UNIFIED IDEOGRAPH
+0xE062 0x90FB #CJK UNIFIED IDEOGRAPH
+0xE063 0x90FC #CJK UNIFIED IDEOGRAPH
+0xE064 0x90FF #CJK UNIFIED IDEOGRAPH
+0xE065 0x9100 #CJK UNIFIED IDEOGRAPH
+0xE066 0x9101 #CJK UNIFIED IDEOGRAPH
+0xE067 0x9103 #CJK UNIFIED IDEOGRAPH
+0xE068 0x9105 #CJK UNIFIED IDEOGRAPH
+0xE069 0x9106 #CJK UNIFIED IDEOGRAPH
+0xE06A 0x9107 #CJK UNIFIED IDEOGRAPH
+0xE06B 0x9108 #CJK UNIFIED IDEOGRAPH
+0xE06C 0x9109 #CJK UNIFIED IDEOGRAPH
+0xE06D 0x910A #CJK UNIFIED IDEOGRAPH
+0xE06E 0x910B #CJK UNIFIED IDEOGRAPH
+0xE06F 0x910C #CJK UNIFIED IDEOGRAPH
+0xE070 0x910D #CJK UNIFIED IDEOGRAPH
+0xE071 0x910E #CJK UNIFIED IDEOGRAPH
+0xE072 0x910F #CJK UNIFIED IDEOGRAPH
+0xE073 0x9110 #CJK UNIFIED IDEOGRAPH
+0xE074 0x9111 #CJK UNIFIED IDEOGRAPH
+0xE075 0x9112 #CJK UNIFIED IDEOGRAPH
+0xE076 0x9113 #CJK UNIFIED IDEOGRAPH
+0xE077 0x9114 #CJK UNIFIED IDEOGRAPH
+0xE078 0x9115 #CJK UNIFIED IDEOGRAPH
+0xE079 0x9116 #CJK UNIFIED IDEOGRAPH
+0xE07A 0x9117 #CJK UNIFIED IDEOGRAPH
+0xE07B 0x9118 #CJK UNIFIED IDEOGRAPH
+0xE07C 0x911A #CJK UNIFIED IDEOGRAPH
+0xE07D 0x911B #CJK UNIFIED IDEOGRAPH
+0xE07E 0x911C #CJK UNIFIED IDEOGRAPH
+0xE080 0x911D #CJK UNIFIED IDEOGRAPH
+0xE081 0x911F #CJK UNIFIED IDEOGRAPH
+0xE082 0x9120 #CJK UNIFIED IDEOGRAPH
+0xE083 0x9121 #CJK UNIFIED IDEOGRAPH
+0xE084 0x9124 #CJK UNIFIED IDEOGRAPH
+0xE085 0x9125 #CJK UNIFIED IDEOGRAPH
+0xE086 0x9126 #CJK UNIFIED IDEOGRAPH
+0xE087 0x9127 #CJK UNIFIED IDEOGRAPH
+0xE088 0x9128 #CJK UNIFIED IDEOGRAPH
+0xE089 0x9129 #CJK UNIFIED IDEOGRAPH
+0xE08A 0x912A #CJK UNIFIED IDEOGRAPH
+0xE08B 0x912B #CJK UNIFIED IDEOGRAPH
+0xE08C 0x912C #CJK UNIFIED IDEOGRAPH
+0xE08D 0x912D #CJK UNIFIED IDEOGRAPH
+0xE08E 0x912E #CJK UNIFIED IDEOGRAPH
+0xE08F 0x9130 #CJK UNIFIED IDEOGRAPH
+0xE090 0x9132 #CJK UNIFIED IDEOGRAPH
+0xE091 0x9133 #CJK UNIFIED IDEOGRAPH
+0xE092 0x9134 #CJK UNIFIED IDEOGRAPH
+0xE093 0x9135 #CJK UNIFIED IDEOGRAPH
+0xE094 0x9136 #CJK UNIFIED IDEOGRAPH
+0xE095 0x9137 #CJK UNIFIED IDEOGRAPH
+0xE096 0x9138 #CJK UNIFIED IDEOGRAPH
+0xE097 0x913A #CJK UNIFIED IDEOGRAPH
+0xE098 0x913B #CJK UNIFIED IDEOGRAPH
+0xE099 0x913C #CJK UNIFIED IDEOGRAPH
+0xE09A 0x913D #CJK UNIFIED IDEOGRAPH
+0xE09B 0x913E #CJK UNIFIED IDEOGRAPH
+0xE09C 0x913F #CJK UNIFIED IDEOGRAPH
+0xE09D 0x9140 #CJK UNIFIED IDEOGRAPH
+0xE09E 0x9141 #CJK UNIFIED IDEOGRAPH
+0xE09F 0x9142 #CJK UNIFIED IDEOGRAPH
+0xE0A0 0x9144 #CJK UNIFIED IDEOGRAPH
+0xE0A1 0x5537 #CJK UNIFIED IDEOGRAPH
+0xE0A2 0x5556 #CJK UNIFIED IDEOGRAPH
+0xE0A3 0x5575 #CJK UNIFIED IDEOGRAPH
+0xE0A4 0x5576 #CJK UNIFIED IDEOGRAPH
+0xE0A5 0x5577 #CJK UNIFIED IDEOGRAPH
+0xE0A6 0x5533 #CJK UNIFIED IDEOGRAPH
+0xE0A7 0x5530 #CJK UNIFIED IDEOGRAPH
+0xE0A8 0x555C #CJK UNIFIED IDEOGRAPH
+0xE0A9 0x558B #CJK UNIFIED IDEOGRAPH
+0xE0AA 0x55D2 #CJK UNIFIED IDEOGRAPH
+0xE0AB 0x5583 #CJK UNIFIED IDEOGRAPH
+0xE0AC 0x55B1 #CJK UNIFIED IDEOGRAPH
+0xE0AD 0x55B9 #CJK UNIFIED IDEOGRAPH
+0xE0AE 0x5588 #CJK UNIFIED IDEOGRAPH
+0xE0AF 0x5581 #CJK UNIFIED IDEOGRAPH
+0xE0B0 0x559F #CJK UNIFIED IDEOGRAPH
+0xE0B1 0x557E #CJK UNIFIED IDEOGRAPH
+0xE0B2 0x55D6 #CJK UNIFIED IDEOGRAPH
+0xE0B3 0x5591 #CJK UNIFIED IDEOGRAPH
+0xE0B4 0x557B #CJK UNIFIED IDEOGRAPH
+0xE0B5 0x55DF #CJK UNIFIED IDEOGRAPH
+0xE0B6 0x55BD #CJK UNIFIED IDEOGRAPH
+0xE0B7 0x55BE #CJK UNIFIED IDEOGRAPH
+0xE0B8 0x5594 #CJK UNIFIED IDEOGRAPH
+0xE0B9 0x5599 #CJK UNIFIED IDEOGRAPH
+0xE0BA 0x55EA #CJK UNIFIED IDEOGRAPH
+0xE0BB 0x55F7 #CJK UNIFIED IDEOGRAPH
+0xE0BC 0x55C9 #CJK UNIFIED IDEOGRAPH
+0xE0BD 0x561F #CJK UNIFIED IDEOGRAPH
+0xE0BE 0x55D1 #CJK UNIFIED IDEOGRAPH
+0xE0BF 0x55EB #CJK UNIFIED IDEOGRAPH
+0xE0C0 0x55EC #CJK UNIFIED IDEOGRAPH
+0xE0C1 0x55D4 #CJK UNIFIED IDEOGRAPH
+0xE0C2 0x55E6 #CJK UNIFIED IDEOGRAPH
+0xE0C3 0x55DD #CJK UNIFIED IDEOGRAPH
+0xE0C4 0x55C4 #CJK UNIFIED IDEOGRAPH
+0xE0C5 0x55EF #CJK UNIFIED IDEOGRAPH
+0xE0C6 0x55E5 #CJK UNIFIED IDEOGRAPH
+0xE0C7 0x55F2 #CJK UNIFIED IDEOGRAPH
+0xE0C8 0x55F3 #CJK UNIFIED IDEOGRAPH
+0xE0C9 0x55CC #CJK UNIFIED IDEOGRAPH
+0xE0CA 0x55CD #CJK UNIFIED IDEOGRAPH
+0xE0CB 0x55E8 #CJK UNIFIED IDEOGRAPH
+0xE0CC 0x55F5 #CJK UNIFIED IDEOGRAPH
+0xE0CD 0x55E4 #CJK UNIFIED IDEOGRAPH
+0xE0CE 0x8F94 #CJK UNIFIED IDEOGRAPH
+0xE0CF 0x561E #CJK UNIFIED IDEOGRAPH
+0xE0D0 0x5608 #CJK UNIFIED IDEOGRAPH
+0xE0D1 0x560C #CJK UNIFIED IDEOGRAPH
+0xE0D2 0x5601 #CJK UNIFIED IDEOGRAPH
+0xE0D3 0x5624 #CJK UNIFIED IDEOGRAPH
+0xE0D4 0x5623 #CJK UNIFIED IDEOGRAPH
+0xE0D5 0x55FE #CJK UNIFIED IDEOGRAPH
+0xE0D6 0x5600 #CJK UNIFIED IDEOGRAPH
+0xE0D7 0x5627 #CJK UNIFIED IDEOGRAPH
+0xE0D8 0x562D #CJK UNIFIED IDEOGRAPH
+0xE0D9 0x5658 #CJK UNIFIED IDEOGRAPH
+0xE0DA 0x5639 #CJK UNIFIED IDEOGRAPH
+0xE0DB 0x5657 #CJK UNIFIED IDEOGRAPH
+0xE0DC 0x562C #CJK UNIFIED IDEOGRAPH
+0xE0DD 0x564D #CJK UNIFIED IDEOGRAPH
+0xE0DE 0x5662 #CJK UNIFIED IDEOGRAPH
+0xE0DF 0x5659 #CJK UNIFIED IDEOGRAPH
+0xE0E0 0x565C #CJK UNIFIED IDEOGRAPH
+0xE0E1 0x564C #CJK UNIFIED IDEOGRAPH
+0xE0E2 0x5654 #CJK UNIFIED IDEOGRAPH
+0xE0E3 0x5686 #CJK UNIFIED IDEOGRAPH
+0xE0E4 0x5664 #CJK UNIFIED IDEOGRAPH
+0xE0E5 0x5671 #CJK UNIFIED IDEOGRAPH
+0xE0E6 0x566B #CJK UNIFIED IDEOGRAPH
+0xE0E7 0x567B #CJK UNIFIED IDEOGRAPH
+0xE0E8 0x567C #CJK UNIFIED IDEOGRAPH
+0xE0E9 0x5685 #CJK UNIFIED IDEOGRAPH
+0xE0EA 0x5693 #CJK UNIFIED IDEOGRAPH
+0xE0EB 0x56AF #CJK UNIFIED IDEOGRAPH
+0xE0EC 0x56D4 #CJK UNIFIED IDEOGRAPH
+0xE0ED 0x56D7 #CJK UNIFIED IDEOGRAPH
+0xE0EE 0x56DD #CJK UNIFIED IDEOGRAPH
+0xE0EF 0x56E1 #CJK UNIFIED IDEOGRAPH
+0xE0F0 0x56F5 #CJK UNIFIED IDEOGRAPH
+0xE0F1 0x56EB #CJK UNIFIED IDEOGRAPH
+0xE0F2 0x56F9 #CJK UNIFIED IDEOGRAPH
+0xE0F3 0x56FF #CJK UNIFIED IDEOGRAPH
+0xE0F4 0x5704 #CJK UNIFIED IDEOGRAPH
+0xE0F5 0x570A #CJK UNIFIED IDEOGRAPH
+0xE0F6 0x5709 #CJK UNIFIED IDEOGRAPH
+0xE0F7 0x571C #CJK UNIFIED IDEOGRAPH
+0xE0F8 0x5E0F #CJK UNIFIED IDEOGRAPH
+0xE0F9 0x5E19 #CJK UNIFIED IDEOGRAPH
+0xE0FA 0x5E14 #CJK UNIFIED IDEOGRAPH
+0xE0FB 0x5E11 #CJK UNIFIED IDEOGRAPH
+0xE0FC 0x5E31 #CJK UNIFIED IDEOGRAPH
+0xE0FD 0x5E3B #CJK UNIFIED IDEOGRAPH
+0xE0FE 0x5E3C #CJK UNIFIED IDEOGRAPH
+0xE140 0x9145 #CJK UNIFIED IDEOGRAPH
+0xE141 0x9147 #CJK UNIFIED IDEOGRAPH
+0xE142 0x9148 #CJK UNIFIED IDEOGRAPH
+0xE143 0x9151 #CJK UNIFIED IDEOGRAPH
+0xE144 0x9153 #CJK UNIFIED IDEOGRAPH
+0xE145 0x9154 #CJK UNIFIED IDEOGRAPH
+0xE146 0x9155 #CJK UNIFIED IDEOGRAPH
+0xE147 0x9156 #CJK UNIFIED IDEOGRAPH
+0xE148 0x9158 #CJK UNIFIED IDEOGRAPH
+0xE149 0x9159 #CJK UNIFIED IDEOGRAPH
+0xE14A 0x915B #CJK UNIFIED IDEOGRAPH
+0xE14B 0x915C #CJK UNIFIED IDEOGRAPH
+0xE14C 0x915F #CJK UNIFIED IDEOGRAPH
+0xE14D 0x9160 #CJK UNIFIED IDEOGRAPH
+0xE14E 0x9166 #CJK UNIFIED IDEOGRAPH
+0xE14F 0x9167 #CJK UNIFIED IDEOGRAPH
+0xE150 0x9168 #CJK UNIFIED IDEOGRAPH
+0xE151 0x916B #CJK UNIFIED IDEOGRAPH
+0xE152 0x916D #CJK UNIFIED IDEOGRAPH
+0xE153 0x9173 #CJK UNIFIED IDEOGRAPH
+0xE154 0x917A #CJK UNIFIED IDEOGRAPH
+0xE155 0x917B #CJK UNIFIED IDEOGRAPH
+0xE156 0x917C #CJK UNIFIED IDEOGRAPH
+0xE157 0x9180 #CJK UNIFIED IDEOGRAPH
+0xE158 0x9181 #CJK UNIFIED IDEOGRAPH
+0xE159 0x9182 #CJK UNIFIED IDEOGRAPH
+0xE15A 0x9183 #CJK UNIFIED IDEOGRAPH
+0xE15B 0x9184 #CJK UNIFIED IDEOGRAPH
+0xE15C 0x9186 #CJK UNIFIED IDEOGRAPH
+0xE15D 0x9188 #CJK UNIFIED IDEOGRAPH
+0xE15E 0x918A #CJK UNIFIED IDEOGRAPH
+0xE15F 0x918E #CJK UNIFIED IDEOGRAPH
+0xE160 0x918F #CJK UNIFIED IDEOGRAPH
+0xE161 0x9193 #CJK UNIFIED IDEOGRAPH
+0xE162 0x9194 #CJK UNIFIED IDEOGRAPH
+0xE163 0x9195 #CJK UNIFIED IDEOGRAPH
+0xE164 0x9196 #CJK UNIFIED IDEOGRAPH
+0xE165 0x9197 #CJK UNIFIED IDEOGRAPH
+0xE166 0x9198 #CJK UNIFIED IDEOGRAPH
+0xE167 0x9199 #CJK UNIFIED IDEOGRAPH
+0xE168 0x919C #CJK UNIFIED IDEOGRAPH
+0xE169 0x919D #CJK UNIFIED IDEOGRAPH
+0xE16A 0x919E #CJK UNIFIED IDEOGRAPH
+0xE16B 0x919F #CJK UNIFIED IDEOGRAPH
+0xE16C 0x91A0 #CJK UNIFIED IDEOGRAPH
+0xE16D 0x91A1 #CJK UNIFIED IDEOGRAPH
+0xE16E 0x91A4 #CJK UNIFIED IDEOGRAPH
+0xE16F 0x91A5 #CJK UNIFIED IDEOGRAPH
+0xE170 0x91A6 #CJK UNIFIED IDEOGRAPH
+0xE171 0x91A7 #CJK UNIFIED IDEOGRAPH
+0xE172 0x91A8 #CJK UNIFIED IDEOGRAPH
+0xE173 0x91A9 #CJK UNIFIED IDEOGRAPH
+0xE174 0x91AB #CJK UNIFIED IDEOGRAPH
+0xE175 0x91AC #CJK UNIFIED IDEOGRAPH
+0xE176 0x91B0 #CJK UNIFIED IDEOGRAPH
+0xE177 0x91B1 #CJK UNIFIED IDEOGRAPH
+0xE178 0x91B2 #CJK UNIFIED IDEOGRAPH
+0xE179 0x91B3 #CJK UNIFIED IDEOGRAPH
+0xE17A 0x91B6 #CJK UNIFIED IDEOGRAPH
+0xE17B 0x91B7 #CJK UNIFIED IDEOGRAPH
+0xE17C 0x91B8 #CJK UNIFIED IDEOGRAPH
+0xE17D 0x91B9 #CJK UNIFIED IDEOGRAPH
+0xE17E 0x91BB #CJK UNIFIED IDEOGRAPH
+0xE180 0x91BC #CJK UNIFIED IDEOGRAPH
+0xE181 0x91BD #CJK UNIFIED IDEOGRAPH
+0xE182 0x91BE #CJK UNIFIED IDEOGRAPH
+0xE183 0x91BF #CJK UNIFIED IDEOGRAPH
+0xE184 0x91C0 #CJK UNIFIED IDEOGRAPH
+0xE185 0x91C1 #CJK UNIFIED IDEOGRAPH
+0xE186 0x91C2 #CJK UNIFIED IDEOGRAPH
+0xE187 0x91C3 #CJK UNIFIED IDEOGRAPH
+0xE188 0x91C4 #CJK UNIFIED IDEOGRAPH
+0xE189 0x91C5 #CJK UNIFIED IDEOGRAPH
+0xE18A 0x91C6 #CJK UNIFIED IDEOGRAPH
+0xE18B 0x91C8 #CJK UNIFIED IDEOGRAPH
+0xE18C 0x91CB #CJK UNIFIED IDEOGRAPH
+0xE18D 0x91D0 #CJK UNIFIED IDEOGRAPH
+0xE18E 0x91D2 #CJK UNIFIED IDEOGRAPH
+0xE18F 0x91D3 #CJK UNIFIED IDEOGRAPH
+0xE190 0x91D4 #CJK UNIFIED IDEOGRAPH
+0xE191 0x91D5 #CJK UNIFIED IDEOGRAPH
+0xE192 0x91D6 #CJK UNIFIED IDEOGRAPH
+0xE193 0x91D7 #CJK UNIFIED IDEOGRAPH
+0xE194 0x91D8 #CJK UNIFIED IDEOGRAPH
+0xE195 0x91D9 #CJK UNIFIED IDEOGRAPH
+0xE196 0x91DA #CJK UNIFIED IDEOGRAPH
+0xE197 0x91DB #CJK UNIFIED IDEOGRAPH
+0xE198 0x91DD #CJK UNIFIED IDEOGRAPH
+0xE199 0x91DE #CJK UNIFIED IDEOGRAPH
+0xE19A 0x91DF #CJK UNIFIED IDEOGRAPH
+0xE19B 0x91E0 #CJK UNIFIED IDEOGRAPH
+0xE19C 0x91E1 #CJK UNIFIED IDEOGRAPH
+0xE19D 0x91E2 #CJK UNIFIED IDEOGRAPH
+0xE19E 0x91E3 #CJK UNIFIED IDEOGRAPH
+0xE19F 0x91E4 #CJK UNIFIED IDEOGRAPH
+0xE1A0 0x91E5 #CJK UNIFIED IDEOGRAPH
+0xE1A1 0x5E37 #CJK UNIFIED IDEOGRAPH
+0xE1A2 0x5E44 #CJK UNIFIED IDEOGRAPH
+0xE1A3 0x5E54 #CJK UNIFIED IDEOGRAPH
+0xE1A4 0x5E5B #CJK UNIFIED IDEOGRAPH
+0xE1A5 0x5E5E #CJK UNIFIED IDEOGRAPH
+0xE1A6 0x5E61 #CJK UNIFIED IDEOGRAPH
+0xE1A7 0x5C8C #CJK UNIFIED IDEOGRAPH
+0xE1A8 0x5C7A #CJK UNIFIED IDEOGRAPH
+0xE1A9 0x5C8D #CJK UNIFIED IDEOGRAPH
+0xE1AA 0x5C90 #CJK UNIFIED IDEOGRAPH
+0xE1AB 0x5C96 #CJK UNIFIED IDEOGRAPH
+0xE1AC 0x5C88 #CJK UNIFIED IDEOGRAPH
+0xE1AD 0x5C98 #CJK UNIFIED IDEOGRAPH
+0xE1AE 0x5C99 #CJK UNIFIED IDEOGRAPH
+0xE1AF 0x5C91 #CJK UNIFIED IDEOGRAPH
+0xE1B0 0x5C9A #CJK UNIFIED IDEOGRAPH
+0xE1B1 0x5C9C #CJK UNIFIED IDEOGRAPH
+0xE1B2 0x5CB5 #CJK UNIFIED IDEOGRAPH
+0xE1B3 0x5CA2 #CJK UNIFIED IDEOGRAPH
+0xE1B4 0x5CBD #CJK UNIFIED IDEOGRAPH
+0xE1B5 0x5CAC #CJK UNIFIED IDEOGRAPH
+0xE1B6 0x5CAB #CJK UNIFIED IDEOGRAPH
+0xE1B7 0x5CB1 #CJK UNIFIED IDEOGRAPH
+0xE1B8 0x5CA3 #CJK UNIFIED IDEOGRAPH
+0xE1B9 0x5CC1 #CJK UNIFIED IDEOGRAPH
+0xE1BA 0x5CB7 #CJK UNIFIED IDEOGRAPH
+0xE1BB 0x5CC4 #CJK UNIFIED IDEOGRAPH
+0xE1BC 0x5CD2 #CJK UNIFIED IDEOGRAPH
+0xE1BD 0x5CE4 #CJK UNIFIED IDEOGRAPH
+0xE1BE 0x5CCB #CJK UNIFIED IDEOGRAPH
+0xE1BF 0x5CE5 #CJK UNIFIED IDEOGRAPH
+0xE1C0 0x5D02 #CJK UNIFIED IDEOGRAPH
+0xE1C1 0x5D03 #CJK UNIFIED IDEOGRAPH
+0xE1C2 0x5D27 #CJK UNIFIED IDEOGRAPH
+0xE1C3 0x5D26 #CJK UNIFIED IDEOGRAPH
+0xE1C4 0x5D2E #CJK UNIFIED IDEOGRAPH
+0xE1C5 0x5D24 #CJK UNIFIED IDEOGRAPH
+0xE1C6 0x5D1E #CJK UNIFIED IDEOGRAPH
+0xE1C7 0x5D06 #CJK UNIFIED IDEOGRAPH
+0xE1C8 0x5D1B #CJK UNIFIED IDEOGRAPH
+0xE1C9 0x5D58 #CJK UNIFIED IDEOGRAPH
+0xE1CA 0x5D3E #CJK UNIFIED IDEOGRAPH
+0xE1CB 0x5D34 #CJK UNIFIED IDEOGRAPH
+0xE1CC 0x5D3D #CJK UNIFIED IDEOGRAPH
+0xE1CD 0x5D6C #CJK UNIFIED IDEOGRAPH
+0xE1CE 0x5D5B #CJK UNIFIED IDEOGRAPH
+0xE1CF 0x5D6F #CJK UNIFIED IDEOGRAPH
+0xE1D0 0x5D5D #CJK UNIFIED IDEOGRAPH
+0xE1D1 0x5D6B #CJK UNIFIED IDEOGRAPH
+0xE1D2 0x5D4B #CJK UNIFIED IDEOGRAPH
+0xE1D3 0x5D4A #CJK UNIFIED IDEOGRAPH
+0xE1D4 0x5D69 #CJK UNIFIED IDEOGRAPH
+0xE1D5 0x5D74 #CJK UNIFIED IDEOGRAPH
+0xE1D6 0x5D82 #CJK UNIFIED IDEOGRAPH
+0xE1D7 0x5D99 #CJK UNIFIED IDEOGRAPH
+0xE1D8 0x5D9D #CJK UNIFIED IDEOGRAPH
+0xE1D9 0x8C73 #CJK UNIFIED IDEOGRAPH
+0xE1DA 0x5DB7 #CJK UNIFIED IDEOGRAPH
+0xE1DB 0x5DC5 #CJK UNIFIED IDEOGRAPH
+0xE1DC 0x5F73 #CJK UNIFIED IDEOGRAPH
+0xE1DD 0x5F77 #CJK UNIFIED IDEOGRAPH
+0xE1DE 0x5F82 #CJK UNIFIED IDEOGRAPH
+0xE1DF 0x5F87 #CJK UNIFIED IDEOGRAPH
+0xE1E0 0x5F89 #CJK UNIFIED IDEOGRAPH
+0xE1E1 0x5F8C #CJK UNIFIED IDEOGRAPH
+0xE1E2 0x5F95 #CJK UNIFIED IDEOGRAPH
+0xE1E3 0x5F99 #CJK UNIFIED IDEOGRAPH
+0xE1E4 0x5F9C #CJK UNIFIED IDEOGRAPH
+0xE1E5 0x5FA8 #CJK UNIFIED IDEOGRAPH
+0xE1E6 0x5FAD #CJK UNIFIED IDEOGRAPH
+0xE1E7 0x5FB5 #CJK UNIFIED IDEOGRAPH
+0xE1E8 0x5FBC #CJK UNIFIED IDEOGRAPH
+0xE1E9 0x8862 #CJK UNIFIED IDEOGRAPH
+0xE1EA 0x5F61 #CJK UNIFIED IDEOGRAPH
+0xE1EB 0x72AD #CJK UNIFIED IDEOGRAPH
+0xE1EC 0x72B0 #CJK UNIFIED IDEOGRAPH
+0xE1ED 0x72B4 #CJK UNIFIED IDEOGRAPH
+0xE1EE 0x72B7 #CJK UNIFIED IDEOGRAPH
+0xE1EF 0x72B8 #CJK UNIFIED IDEOGRAPH
+0xE1F0 0x72C3 #CJK UNIFIED IDEOGRAPH
+0xE1F1 0x72C1 #CJK UNIFIED IDEOGRAPH
+0xE1F2 0x72CE #CJK UNIFIED IDEOGRAPH
+0xE1F3 0x72CD #CJK UNIFIED IDEOGRAPH
+0xE1F4 0x72D2 #CJK UNIFIED IDEOGRAPH
+0xE1F5 0x72E8 #CJK UNIFIED IDEOGRAPH
+0xE1F6 0x72EF #CJK UNIFIED IDEOGRAPH
+0xE1F7 0x72E9 #CJK UNIFIED IDEOGRAPH
+0xE1F8 0x72F2 #CJK UNIFIED IDEOGRAPH
+0xE1F9 0x72F4 #CJK UNIFIED IDEOGRAPH
+0xE1FA 0x72F7 #CJK UNIFIED IDEOGRAPH
+0xE1FB 0x7301 #CJK UNIFIED IDEOGRAPH
+0xE1FC 0x72F3 #CJK UNIFIED IDEOGRAPH
+0xE1FD 0x7303 #CJK UNIFIED IDEOGRAPH
+0xE1FE 0x72FA #CJK UNIFIED IDEOGRAPH
+0xE240 0x91E6 #CJK UNIFIED IDEOGRAPH
+0xE241 0x91E7 #CJK UNIFIED IDEOGRAPH
+0xE242 0x91E8 #CJK UNIFIED IDEOGRAPH
+0xE243 0x91E9 #CJK UNIFIED IDEOGRAPH
+0xE244 0x91EA #CJK UNIFIED IDEOGRAPH
+0xE245 0x91EB #CJK UNIFIED IDEOGRAPH
+0xE246 0x91EC #CJK UNIFIED IDEOGRAPH
+0xE247 0x91ED #CJK UNIFIED IDEOGRAPH
+0xE248 0x91EE #CJK UNIFIED IDEOGRAPH
+0xE249 0x91EF #CJK UNIFIED IDEOGRAPH
+0xE24A 0x91F0 #CJK UNIFIED IDEOGRAPH
+0xE24B 0x91F1 #CJK UNIFIED IDEOGRAPH
+0xE24C 0x91F2 #CJK UNIFIED IDEOGRAPH
+0xE24D 0x91F3 #CJK UNIFIED IDEOGRAPH
+0xE24E 0x91F4 #CJK UNIFIED IDEOGRAPH
+0xE24F 0x91F5 #CJK UNIFIED IDEOGRAPH
+0xE250 0x91F6 #CJK UNIFIED IDEOGRAPH
+0xE251 0x91F7 #CJK UNIFIED IDEOGRAPH
+0xE252 0x91F8 #CJK UNIFIED IDEOGRAPH
+0xE253 0x91F9 #CJK UNIFIED IDEOGRAPH
+0xE254 0x91FA #CJK UNIFIED IDEOGRAPH
+0xE255 0x91FB #CJK UNIFIED IDEOGRAPH
+0xE256 0x91FC #CJK UNIFIED IDEOGRAPH
+0xE257 0x91FD #CJK UNIFIED IDEOGRAPH
+0xE258 0x91FE #CJK UNIFIED IDEOGRAPH
+0xE259 0x91FF #CJK UNIFIED IDEOGRAPH
+0xE25A 0x9200 #CJK UNIFIED IDEOGRAPH
+0xE25B 0x9201 #CJK UNIFIED IDEOGRAPH
+0xE25C 0x9202 #CJK UNIFIED IDEOGRAPH
+0xE25D 0x9203 #CJK UNIFIED IDEOGRAPH
+0xE25E 0x9204 #CJK UNIFIED IDEOGRAPH
+0xE25F 0x9205 #CJK UNIFIED IDEOGRAPH
+0xE260 0x9206 #CJK UNIFIED IDEOGRAPH
+0xE261 0x9207 #CJK UNIFIED IDEOGRAPH
+0xE262 0x9208 #CJK UNIFIED IDEOGRAPH
+0xE263 0x9209 #CJK UNIFIED IDEOGRAPH
+0xE264 0x920A #CJK UNIFIED IDEOGRAPH
+0xE265 0x920B #CJK UNIFIED IDEOGRAPH
+0xE266 0x920C #CJK UNIFIED IDEOGRAPH
+0xE267 0x920D #CJK UNIFIED IDEOGRAPH
+0xE268 0x920E #CJK UNIFIED IDEOGRAPH
+0xE269 0x920F #CJK UNIFIED IDEOGRAPH
+0xE26A 0x9210 #CJK UNIFIED IDEOGRAPH
+0xE26B 0x9211 #CJK UNIFIED IDEOGRAPH
+0xE26C 0x9212 #CJK UNIFIED IDEOGRAPH
+0xE26D 0x9213 #CJK UNIFIED IDEOGRAPH
+0xE26E 0x9214 #CJK UNIFIED IDEOGRAPH
+0xE26F 0x9215 #CJK UNIFIED IDEOGRAPH
+0xE270 0x9216 #CJK UNIFIED IDEOGRAPH
+0xE271 0x9217 #CJK UNIFIED IDEOGRAPH
+0xE272 0x9218 #CJK UNIFIED IDEOGRAPH
+0xE273 0x9219 #CJK UNIFIED IDEOGRAPH
+0xE274 0x921A #CJK UNIFIED IDEOGRAPH
+0xE275 0x921B #CJK UNIFIED IDEOGRAPH
+0xE276 0x921C #CJK UNIFIED IDEOGRAPH
+0xE277 0x921D #CJK UNIFIED IDEOGRAPH
+0xE278 0x921E #CJK UNIFIED IDEOGRAPH
+0xE279 0x921F #CJK UNIFIED IDEOGRAPH
+0xE27A 0x9220 #CJK UNIFIED IDEOGRAPH
+0xE27B 0x9221 #CJK UNIFIED IDEOGRAPH
+0xE27C 0x9222 #CJK UNIFIED IDEOGRAPH
+0xE27D 0x9223 #CJK UNIFIED IDEOGRAPH
+0xE27E 0x9224 #CJK UNIFIED IDEOGRAPH
+0xE280 0x9225 #CJK UNIFIED IDEOGRAPH
+0xE281 0x9226 #CJK UNIFIED IDEOGRAPH
+0xE282 0x9227 #CJK UNIFIED IDEOGRAPH
+0xE283 0x9228 #CJK UNIFIED IDEOGRAPH
+0xE284 0x9229 #CJK UNIFIED IDEOGRAPH
+0xE285 0x922A #CJK UNIFIED IDEOGRAPH
+0xE286 0x922B #CJK UNIFIED IDEOGRAPH
+0xE287 0x922C #CJK UNIFIED IDEOGRAPH
+0xE288 0x922D #CJK UNIFIED IDEOGRAPH
+0xE289 0x922E #CJK UNIFIED IDEOGRAPH
+0xE28A 0x922F #CJK UNIFIED IDEOGRAPH
+0xE28B 0x9230 #CJK UNIFIED IDEOGRAPH
+0xE28C 0x9231 #CJK UNIFIED IDEOGRAPH
+0xE28D 0x9232 #CJK UNIFIED IDEOGRAPH
+0xE28E 0x9233 #CJK UNIFIED IDEOGRAPH
+0xE28F 0x9234 #CJK UNIFIED IDEOGRAPH
+0xE290 0x9235 #CJK UNIFIED IDEOGRAPH
+0xE291 0x9236 #CJK UNIFIED IDEOGRAPH
+0xE292 0x9237 #CJK UNIFIED IDEOGRAPH
+0xE293 0x9238 #CJK UNIFIED IDEOGRAPH
+0xE294 0x9239 #CJK UNIFIED IDEOGRAPH
+0xE295 0x923A #CJK UNIFIED IDEOGRAPH
+0xE296 0x923B #CJK UNIFIED IDEOGRAPH
+0xE297 0x923C #CJK UNIFIED IDEOGRAPH
+0xE298 0x923D #CJK UNIFIED IDEOGRAPH
+0xE299 0x923E #CJK UNIFIED IDEOGRAPH
+0xE29A 0x923F #CJK UNIFIED IDEOGRAPH
+0xE29B 0x9240 #CJK UNIFIED IDEOGRAPH
+0xE29C 0x9241 #CJK UNIFIED IDEOGRAPH
+0xE29D 0x9242 #CJK UNIFIED IDEOGRAPH
+0xE29E 0x9243 #CJK UNIFIED IDEOGRAPH
+0xE29F 0x9244 #CJK UNIFIED IDEOGRAPH
+0xE2A0 0x9245 #CJK UNIFIED IDEOGRAPH
+0xE2A1 0x72FB #CJK UNIFIED IDEOGRAPH
+0xE2A2 0x7317 #CJK UNIFIED IDEOGRAPH
+0xE2A3 0x7313 #CJK UNIFIED IDEOGRAPH
+0xE2A4 0x7321 #CJK UNIFIED IDEOGRAPH
+0xE2A5 0x730A #CJK UNIFIED IDEOGRAPH
+0xE2A6 0x731E #CJK UNIFIED IDEOGRAPH
+0xE2A7 0x731D #CJK UNIFIED IDEOGRAPH
+0xE2A8 0x7315 #CJK UNIFIED IDEOGRAPH
+0xE2A9 0x7322 #CJK UNIFIED IDEOGRAPH
+0xE2AA 0x7339 #CJK UNIFIED IDEOGRAPH
+0xE2AB 0x7325 #CJK UNIFIED IDEOGRAPH
+0xE2AC 0x732C #CJK UNIFIED IDEOGRAPH
+0xE2AD 0x7338 #CJK UNIFIED IDEOGRAPH
+0xE2AE 0x7331 #CJK UNIFIED IDEOGRAPH
+0xE2AF 0x7350 #CJK UNIFIED IDEOGRAPH
+0xE2B0 0x734D #CJK UNIFIED IDEOGRAPH
+0xE2B1 0x7357 #CJK UNIFIED IDEOGRAPH
+0xE2B2 0x7360 #CJK UNIFIED IDEOGRAPH
+0xE2B3 0x736C #CJK UNIFIED IDEOGRAPH
+0xE2B4 0x736F #CJK UNIFIED IDEOGRAPH
+0xE2B5 0x737E #CJK UNIFIED IDEOGRAPH
+0xE2B6 0x821B #CJK UNIFIED IDEOGRAPH
+0xE2B7 0x5925 #CJK UNIFIED IDEOGRAPH
+0xE2B8 0x98E7 #CJK UNIFIED IDEOGRAPH
+0xE2B9 0x5924 #CJK UNIFIED IDEOGRAPH
+0xE2BA 0x5902 #CJK UNIFIED IDEOGRAPH
+0xE2BB 0x9963 #CJK UNIFIED IDEOGRAPH
+0xE2BC 0x9967 #CJK UNIFIED IDEOGRAPH
+0xE2BD 0x9968 #CJK UNIFIED IDEOGRAPH
+0xE2BE 0x9969 #CJK UNIFIED IDEOGRAPH
+0xE2BF 0x996A #CJK UNIFIED IDEOGRAPH
+0xE2C0 0x996B #CJK UNIFIED IDEOGRAPH
+0xE2C1 0x996C #CJK UNIFIED IDEOGRAPH
+0xE2C2 0x9974 #CJK UNIFIED IDEOGRAPH
+0xE2C3 0x9977 #CJK UNIFIED IDEOGRAPH
+0xE2C4 0x997D #CJK UNIFIED IDEOGRAPH
+0xE2C5 0x9980 #CJK UNIFIED IDEOGRAPH
+0xE2C6 0x9984 #CJK UNIFIED IDEOGRAPH
+0xE2C7 0x9987 #CJK UNIFIED IDEOGRAPH
+0xE2C8 0x998A #CJK UNIFIED IDEOGRAPH
+0xE2C9 0x998D #CJK UNIFIED IDEOGRAPH
+0xE2CA 0x9990 #CJK UNIFIED IDEOGRAPH
+0xE2CB 0x9991 #CJK UNIFIED IDEOGRAPH
+0xE2CC 0x9993 #CJK UNIFIED IDEOGRAPH
+0xE2CD 0x9994 #CJK UNIFIED IDEOGRAPH
+0xE2CE 0x9995 #CJK UNIFIED IDEOGRAPH
+0xE2CF 0x5E80 #CJK UNIFIED IDEOGRAPH
+0xE2D0 0x5E91 #CJK UNIFIED IDEOGRAPH
+0xE2D1 0x5E8B #CJK UNIFIED IDEOGRAPH
+0xE2D2 0x5E96 #CJK UNIFIED IDEOGRAPH
+0xE2D3 0x5EA5 #CJK UNIFIED IDEOGRAPH
+0xE2D4 0x5EA0 #CJK UNIFIED IDEOGRAPH
+0xE2D5 0x5EB9 #CJK UNIFIED IDEOGRAPH
+0xE2D6 0x5EB5 #CJK UNIFIED IDEOGRAPH
+0xE2D7 0x5EBE #CJK UNIFIED IDEOGRAPH
+0xE2D8 0x5EB3 #CJK UNIFIED IDEOGRAPH
+0xE2D9 0x8D53 #CJK UNIFIED IDEOGRAPH
+0xE2DA 0x5ED2 #CJK UNIFIED IDEOGRAPH
+0xE2DB 0x5ED1 #CJK UNIFIED IDEOGRAPH
+0xE2DC 0x5EDB #CJK UNIFIED IDEOGRAPH
+0xE2DD 0x5EE8 #CJK UNIFIED IDEOGRAPH
+0xE2DE 0x5EEA #CJK UNIFIED IDEOGRAPH
+0xE2DF 0x81BA #CJK UNIFIED IDEOGRAPH
+0xE2E0 0x5FC4 #CJK UNIFIED IDEOGRAPH
+0xE2E1 0x5FC9 #CJK UNIFIED IDEOGRAPH
+0xE2E2 0x5FD6 #CJK UNIFIED IDEOGRAPH
+0xE2E3 0x5FCF #CJK UNIFIED IDEOGRAPH
+0xE2E4 0x6003 #CJK UNIFIED IDEOGRAPH
+0xE2E5 0x5FEE #CJK UNIFIED IDEOGRAPH
+0xE2E6 0x6004 #CJK UNIFIED IDEOGRAPH
+0xE2E7 0x5FE1 #CJK UNIFIED IDEOGRAPH
+0xE2E8 0x5FE4 #CJK UNIFIED IDEOGRAPH
+0xE2E9 0x5FFE #CJK UNIFIED IDEOGRAPH
+0xE2EA 0x6005 #CJK UNIFIED IDEOGRAPH
+0xE2EB 0x6006 #CJK UNIFIED IDEOGRAPH
+0xE2EC 0x5FEA #CJK UNIFIED IDEOGRAPH
+0xE2ED 0x5FED #CJK UNIFIED IDEOGRAPH
+0xE2EE 0x5FF8 #CJK UNIFIED IDEOGRAPH
+0xE2EF 0x6019 #CJK UNIFIED IDEOGRAPH
+0xE2F0 0x6035 #CJK UNIFIED IDEOGRAPH
+0xE2F1 0x6026 #CJK UNIFIED IDEOGRAPH
+0xE2F2 0x601B #CJK UNIFIED IDEOGRAPH
+0xE2F3 0x600F #CJK UNIFIED IDEOGRAPH
+0xE2F4 0x600D #CJK UNIFIED IDEOGRAPH
+0xE2F5 0x6029 #CJK UNIFIED IDEOGRAPH
+0xE2F6 0x602B #CJK UNIFIED IDEOGRAPH
+0xE2F7 0x600A #CJK UNIFIED IDEOGRAPH
+0xE2F8 0x603F #CJK UNIFIED IDEOGRAPH
+0xE2F9 0x6021 #CJK UNIFIED IDEOGRAPH
+0xE2FA 0x6078 #CJK UNIFIED IDEOGRAPH
+0xE2FB 0x6079 #CJK UNIFIED IDEOGRAPH
+0xE2FC 0x607B #CJK UNIFIED IDEOGRAPH
+0xE2FD 0x607A #CJK UNIFIED IDEOGRAPH
+0xE2FE 0x6042 #CJK UNIFIED IDEOGRAPH
+0xE340 0x9246 #CJK UNIFIED IDEOGRAPH
+0xE341 0x9247 #CJK UNIFIED IDEOGRAPH
+0xE342 0x9248 #CJK UNIFIED IDEOGRAPH
+0xE343 0x9249 #CJK UNIFIED IDEOGRAPH
+0xE344 0x924A #CJK UNIFIED IDEOGRAPH
+0xE345 0x924B #CJK UNIFIED IDEOGRAPH
+0xE346 0x924C #CJK UNIFIED IDEOGRAPH
+0xE347 0x924D #CJK UNIFIED IDEOGRAPH
+0xE348 0x924E #CJK UNIFIED IDEOGRAPH
+0xE349 0x924F #CJK UNIFIED IDEOGRAPH
+0xE34A 0x9250 #CJK UNIFIED IDEOGRAPH
+0xE34B 0x9251 #CJK UNIFIED IDEOGRAPH
+0xE34C 0x9252 #CJK UNIFIED IDEOGRAPH
+0xE34D 0x9253 #CJK UNIFIED IDEOGRAPH
+0xE34E 0x9254 #CJK UNIFIED IDEOGRAPH
+0xE34F 0x9255 #CJK UNIFIED IDEOGRAPH
+0xE350 0x9256 #CJK UNIFIED IDEOGRAPH
+0xE351 0x9257 #CJK UNIFIED IDEOGRAPH
+0xE352 0x9258 #CJK UNIFIED IDEOGRAPH
+0xE353 0x9259 #CJK UNIFIED IDEOGRAPH
+0xE354 0x925A #CJK UNIFIED IDEOGRAPH
+0xE355 0x925B #CJK UNIFIED IDEOGRAPH
+0xE356 0x925C #CJK UNIFIED IDEOGRAPH
+0xE357 0x925D #CJK UNIFIED IDEOGRAPH
+0xE358 0x925E #CJK UNIFIED IDEOGRAPH
+0xE359 0x925F #CJK UNIFIED IDEOGRAPH
+0xE35A 0x9260 #CJK UNIFIED IDEOGRAPH
+0xE35B 0x9261 #CJK UNIFIED IDEOGRAPH
+0xE35C 0x9262 #CJK UNIFIED IDEOGRAPH
+0xE35D 0x9263 #CJK UNIFIED IDEOGRAPH
+0xE35E 0x9264 #CJK UNIFIED IDEOGRAPH
+0xE35F 0x9265 #CJK UNIFIED IDEOGRAPH
+0xE360 0x9266 #CJK UNIFIED IDEOGRAPH
+0xE361 0x9267 #CJK UNIFIED IDEOGRAPH
+0xE362 0x9268 #CJK UNIFIED IDEOGRAPH
+0xE363 0x9269 #CJK UNIFIED IDEOGRAPH
+0xE364 0x926A #CJK UNIFIED IDEOGRAPH
+0xE365 0x926B #CJK UNIFIED IDEOGRAPH
+0xE366 0x926C #CJK UNIFIED IDEOGRAPH
+0xE367 0x926D #CJK UNIFIED IDEOGRAPH
+0xE368 0x926E #CJK UNIFIED IDEOGRAPH
+0xE369 0x926F #CJK UNIFIED IDEOGRAPH
+0xE36A 0x9270 #CJK UNIFIED IDEOGRAPH
+0xE36B 0x9271 #CJK UNIFIED IDEOGRAPH
+0xE36C 0x9272 #CJK UNIFIED IDEOGRAPH
+0xE36D 0x9273 #CJK UNIFIED IDEOGRAPH
+0xE36E 0x9275 #CJK UNIFIED IDEOGRAPH
+0xE36F 0x9276 #CJK UNIFIED IDEOGRAPH
+0xE370 0x9277 #CJK UNIFIED IDEOGRAPH
+0xE371 0x9278 #CJK UNIFIED IDEOGRAPH
+0xE372 0x9279 #CJK UNIFIED IDEOGRAPH
+0xE373 0x927A #CJK UNIFIED IDEOGRAPH
+0xE374 0x927B #CJK UNIFIED IDEOGRAPH
+0xE375 0x927C #CJK UNIFIED IDEOGRAPH
+0xE376 0x927D #CJK UNIFIED IDEOGRAPH
+0xE377 0x927E #CJK UNIFIED IDEOGRAPH
+0xE378 0x927F #CJK UNIFIED IDEOGRAPH
+0xE379 0x9280 #CJK UNIFIED IDEOGRAPH
+0xE37A 0x9281 #CJK UNIFIED IDEOGRAPH
+0xE37B 0x9282 #CJK UNIFIED IDEOGRAPH
+0xE37C 0x9283 #CJK UNIFIED IDEOGRAPH
+0xE37D 0x9284 #CJK UNIFIED IDEOGRAPH
+0xE37E 0x9285 #CJK UNIFIED IDEOGRAPH
+0xE380 0x9286 #CJK UNIFIED IDEOGRAPH
+0xE381 0x9287 #CJK UNIFIED IDEOGRAPH
+0xE382 0x9288 #CJK UNIFIED IDEOGRAPH
+0xE383 0x9289 #CJK UNIFIED IDEOGRAPH
+0xE384 0x928A #CJK UNIFIED IDEOGRAPH
+0xE385 0x928B #CJK UNIFIED IDEOGRAPH
+0xE386 0x928C #CJK UNIFIED IDEOGRAPH
+0xE387 0x928D #CJK UNIFIED IDEOGRAPH
+0xE388 0x928F #CJK UNIFIED IDEOGRAPH
+0xE389 0x9290 #CJK UNIFIED IDEOGRAPH
+0xE38A 0x9291 #CJK UNIFIED IDEOGRAPH
+0xE38B 0x9292 #CJK UNIFIED IDEOGRAPH
+0xE38C 0x9293 #CJK UNIFIED IDEOGRAPH
+0xE38D 0x9294 #CJK UNIFIED IDEOGRAPH
+0xE38E 0x9295 #CJK UNIFIED IDEOGRAPH
+0xE38F 0x9296 #CJK UNIFIED IDEOGRAPH
+0xE390 0x9297 #CJK UNIFIED IDEOGRAPH
+0xE391 0x9298 #CJK UNIFIED IDEOGRAPH
+0xE392 0x9299 #CJK UNIFIED IDEOGRAPH
+0xE393 0x929A #CJK UNIFIED IDEOGRAPH
+0xE394 0x929B #CJK UNIFIED IDEOGRAPH
+0xE395 0x929C #CJK UNIFIED IDEOGRAPH
+0xE396 0x929D #CJK UNIFIED IDEOGRAPH
+0xE397 0x929E #CJK UNIFIED IDEOGRAPH
+0xE398 0x929F #CJK UNIFIED IDEOGRAPH
+0xE399 0x92A0 #CJK UNIFIED IDEOGRAPH
+0xE39A 0x92A1 #CJK UNIFIED IDEOGRAPH
+0xE39B 0x92A2 #CJK UNIFIED IDEOGRAPH
+0xE39C 0x92A3 #CJK UNIFIED IDEOGRAPH
+0xE39D 0x92A4 #CJK UNIFIED IDEOGRAPH
+0xE39E 0x92A5 #CJK UNIFIED IDEOGRAPH
+0xE39F 0x92A6 #CJK UNIFIED IDEOGRAPH
+0xE3A0 0x92A7 #CJK UNIFIED IDEOGRAPH
+0xE3A1 0x606A #CJK UNIFIED IDEOGRAPH
+0xE3A2 0x607D #CJK UNIFIED IDEOGRAPH
+0xE3A3 0x6096 #CJK UNIFIED IDEOGRAPH
+0xE3A4 0x609A #CJK UNIFIED IDEOGRAPH
+0xE3A5 0x60AD #CJK UNIFIED IDEOGRAPH
+0xE3A6 0x609D #CJK UNIFIED IDEOGRAPH
+0xE3A7 0x6083 #CJK UNIFIED IDEOGRAPH
+0xE3A8 0x6092 #CJK UNIFIED IDEOGRAPH
+0xE3A9 0x608C #CJK UNIFIED IDEOGRAPH
+0xE3AA 0x609B #CJK UNIFIED IDEOGRAPH
+0xE3AB 0x60EC #CJK UNIFIED IDEOGRAPH
+0xE3AC 0x60BB #CJK UNIFIED IDEOGRAPH
+0xE3AD 0x60B1 #CJK UNIFIED IDEOGRAPH
+0xE3AE 0x60DD #CJK UNIFIED IDEOGRAPH
+0xE3AF 0x60D8 #CJK UNIFIED IDEOGRAPH
+0xE3B0 0x60C6 #CJK UNIFIED IDEOGRAPH
+0xE3B1 0x60DA #CJK UNIFIED IDEOGRAPH
+0xE3B2 0x60B4 #CJK UNIFIED IDEOGRAPH
+0xE3B3 0x6120 #CJK UNIFIED IDEOGRAPH
+0xE3B4 0x6126 #CJK UNIFIED IDEOGRAPH
+0xE3B5 0x6115 #CJK UNIFIED IDEOGRAPH
+0xE3B6 0x6123 #CJK UNIFIED IDEOGRAPH
+0xE3B7 0x60F4 #CJK UNIFIED IDEOGRAPH
+0xE3B8 0x6100 #CJK UNIFIED IDEOGRAPH
+0xE3B9 0x610E #CJK UNIFIED IDEOGRAPH
+0xE3BA 0x612B #CJK UNIFIED IDEOGRAPH
+0xE3BB 0x614A #CJK UNIFIED IDEOGRAPH
+0xE3BC 0x6175 #CJK UNIFIED IDEOGRAPH
+0xE3BD 0x61AC #CJK UNIFIED IDEOGRAPH
+0xE3BE 0x6194 #CJK UNIFIED IDEOGRAPH
+0xE3BF 0x61A7 #CJK UNIFIED IDEOGRAPH
+0xE3C0 0x61B7 #CJK UNIFIED IDEOGRAPH
+0xE3C1 0x61D4 #CJK UNIFIED IDEOGRAPH
+0xE3C2 0x61F5 #CJK UNIFIED IDEOGRAPH
+0xE3C3 0x5FDD #CJK UNIFIED IDEOGRAPH
+0xE3C4 0x96B3 #CJK UNIFIED IDEOGRAPH
+0xE3C5 0x95E9 #CJK UNIFIED IDEOGRAPH
+0xE3C6 0x95EB #CJK UNIFIED IDEOGRAPH
+0xE3C7 0x95F1 #CJK UNIFIED IDEOGRAPH
+0xE3C8 0x95F3 #CJK UNIFIED IDEOGRAPH
+0xE3C9 0x95F5 #CJK UNIFIED IDEOGRAPH
+0xE3CA 0x95F6 #CJK UNIFIED IDEOGRAPH
+0xE3CB 0x95FC #CJK UNIFIED IDEOGRAPH
+0xE3CC 0x95FE #CJK UNIFIED IDEOGRAPH
+0xE3CD 0x9603 #CJK UNIFIED IDEOGRAPH
+0xE3CE 0x9604 #CJK UNIFIED IDEOGRAPH
+0xE3CF 0x9606 #CJK UNIFIED IDEOGRAPH
+0xE3D0 0x9608 #CJK UNIFIED IDEOGRAPH
+0xE3D1 0x960A #CJK UNIFIED IDEOGRAPH
+0xE3D2 0x960B #CJK UNIFIED IDEOGRAPH
+0xE3D3 0x960C #CJK UNIFIED IDEOGRAPH
+0xE3D4 0x960D #CJK UNIFIED IDEOGRAPH
+0xE3D5 0x960F #CJK UNIFIED IDEOGRAPH
+0xE3D6 0x9612 #CJK UNIFIED IDEOGRAPH
+0xE3D7 0x9615 #CJK UNIFIED IDEOGRAPH
+0xE3D8 0x9616 #CJK UNIFIED IDEOGRAPH
+0xE3D9 0x9617 #CJK UNIFIED IDEOGRAPH
+0xE3DA 0x9619 #CJK UNIFIED IDEOGRAPH
+0xE3DB 0x961A #CJK UNIFIED IDEOGRAPH
+0xE3DC 0x4E2C #CJK UNIFIED IDEOGRAPH
+0xE3DD 0x723F #CJK UNIFIED IDEOGRAPH
+0xE3DE 0x6215 #CJK UNIFIED IDEOGRAPH
+0xE3DF 0x6C35 #CJK UNIFIED IDEOGRAPH
+0xE3E0 0x6C54 #CJK UNIFIED IDEOGRAPH
+0xE3E1 0x6C5C #CJK UNIFIED IDEOGRAPH
+0xE3E2 0x6C4A #CJK UNIFIED IDEOGRAPH
+0xE3E3 0x6CA3 #CJK UNIFIED IDEOGRAPH
+0xE3E4 0x6C85 #CJK UNIFIED IDEOGRAPH
+0xE3E5 0x6C90 #CJK UNIFIED IDEOGRAPH
+0xE3E6 0x6C94 #CJK UNIFIED IDEOGRAPH
+0xE3E7 0x6C8C #CJK UNIFIED IDEOGRAPH
+0xE3E8 0x6C68 #CJK UNIFIED IDEOGRAPH
+0xE3E9 0x6C69 #CJK UNIFIED IDEOGRAPH
+0xE3EA 0x6C74 #CJK UNIFIED IDEOGRAPH
+0xE3EB 0x6C76 #CJK UNIFIED IDEOGRAPH
+0xE3EC 0x6C86 #CJK UNIFIED IDEOGRAPH
+0xE3ED 0x6CA9 #CJK UNIFIED IDEOGRAPH
+0xE3EE 0x6CD0 #CJK UNIFIED IDEOGRAPH
+0xE3EF 0x6CD4 #CJK UNIFIED IDEOGRAPH
+0xE3F0 0x6CAD #CJK UNIFIED IDEOGRAPH
+0xE3F1 0x6CF7 #CJK UNIFIED IDEOGRAPH
+0xE3F2 0x6CF8 #CJK UNIFIED IDEOGRAPH
+0xE3F3 0x6CF1 #CJK UNIFIED IDEOGRAPH
+0xE3F4 0x6CD7 #CJK UNIFIED IDEOGRAPH
+0xE3F5 0x6CB2 #CJK UNIFIED IDEOGRAPH
+0xE3F6 0x6CE0 #CJK UNIFIED IDEOGRAPH
+0xE3F7 0x6CD6 #CJK UNIFIED IDEOGRAPH
+0xE3F8 0x6CFA #CJK UNIFIED IDEOGRAPH
+0xE3F9 0x6CEB #CJK UNIFIED IDEOGRAPH
+0xE3FA 0x6CEE #CJK UNIFIED IDEOGRAPH
+0xE3FB 0x6CB1 #CJK UNIFIED IDEOGRAPH
+0xE3FC 0x6CD3 #CJK UNIFIED IDEOGRAPH
+0xE3FD 0x6CEF #CJK UNIFIED IDEOGRAPH
+0xE3FE 0x6CFE #CJK UNIFIED IDEOGRAPH
+0xE440 0x92A8 #CJK UNIFIED IDEOGRAPH
+0xE441 0x92A9 #CJK UNIFIED IDEOGRAPH
+0xE442 0x92AA #CJK UNIFIED IDEOGRAPH
+0xE443 0x92AB #CJK UNIFIED IDEOGRAPH
+0xE444 0x92AC #CJK UNIFIED IDEOGRAPH
+0xE445 0x92AD #CJK UNIFIED IDEOGRAPH
+0xE446 0x92AF #CJK UNIFIED IDEOGRAPH
+0xE447 0x92B0 #CJK UNIFIED IDEOGRAPH
+0xE448 0x92B1 #CJK UNIFIED IDEOGRAPH
+0xE449 0x92B2 #CJK UNIFIED IDEOGRAPH
+0xE44A 0x92B3 #CJK UNIFIED IDEOGRAPH
+0xE44B 0x92B4 #CJK UNIFIED IDEOGRAPH
+0xE44C 0x92B5 #CJK UNIFIED IDEOGRAPH
+0xE44D 0x92B6 #CJK UNIFIED IDEOGRAPH
+0xE44E 0x92B7 #CJK UNIFIED IDEOGRAPH
+0xE44F 0x92B8 #CJK UNIFIED IDEOGRAPH
+0xE450 0x92B9 #CJK UNIFIED IDEOGRAPH
+0xE451 0x92BA #CJK UNIFIED IDEOGRAPH
+0xE452 0x92BB #CJK UNIFIED IDEOGRAPH
+0xE453 0x92BC #CJK UNIFIED IDEOGRAPH
+0xE454 0x92BD #CJK UNIFIED IDEOGRAPH
+0xE455 0x92BE #CJK UNIFIED IDEOGRAPH
+0xE456 0x92BF #CJK UNIFIED IDEOGRAPH
+0xE457 0x92C0 #CJK UNIFIED IDEOGRAPH
+0xE458 0x92C1 #CJK UNIFIED IDEOGRAPH
+0xE459 0x92C2 #CJK UNIFIED IDEOGRAPH
+0xE45A 0x92C3 #CJK UNIFIED IDEOGRAPH
+0xE45B 0x92C4 #CJK UNIFIED IDEOGRAPH
+0xE45C 0x92C5 #CJK UNIFIED IDEOGRAPH
+0xE45D 0x92C6 #CJK UNIFIED IDEOGRAPH
+0xE45E 0x92C7 #CJK UNIFIED IDEOGRAPH
+0xE45F 0x92C9 #CJK UNIFIED IDEOGRAPH
+0xE460 0x92CA #CJK UNIFIED IDEOGRAPH
+0xE461 0x92CB #CJK UNIFIED IDEOGRAPH
+0xE462 0x92CC #CJK UNIFIED IDEOGRAPH
+0xE463 0x92CD #CJK UNIFIED IDEOGRAPH
+0xE464 0x92CE #CJK UNIFIED IDEOGRAPH
+0xE465 0x92CF #CJK UNIFIED IDEOGRAPH
+0xE466 0x92D0 #CJK UNIFIED IDEOGRAPH
+0xE467 0x92D1 #CJK UNIFIED IDEOGRAPH
+0xE468 0x92D2 #CJK UNIFIED IDEOGRAPH
+0xE469 0x92D3 #CJK UNIFIED IDEOGRAPH
+0xE46A 0x92D4 #CJK UNIFIED IDEOGRAPH
+0xE46B 0x92D5 #CJK UNIFIED IDEOGRAPH
+0xE46C 0x92D6 #CJK UNIFIED IDEOGRAPH
+0xE46D 0x92D7 #CJK UNIFIED IDEOGRAPH
+0xE46E 0x92D8 #CJK UNIFIED IDEOGRAPH
+0xE46F 0x92D9 #CJK UNIFIED IDEOGRAPH
+0xE470 0x92DA #CJK UNIFIED IDEOGRAPH
+0xE471 0x92DB #CJK UNIFIED IDEOGRAPH
+0xE472 0x92DC #CJK UNIFIED IDEOGRAPH
+0xE473 0x92DD #CJK UNIFIED IDEOGRAPH
+0xE474 0x92DE #CJK UNIFIED IDEOGRAPH
+0xE475 0x92DF #CJK UNIFIED IDEOGRAPH
+0xE476 0x92E0 #CJK UNIFIED IDEOGRAPH
+0xE477 0x92E1 #CJK UNIFIED IDEOGRAPH
+0xE478 0x92E2 #CJK UNIFIED IDEOGRAPH
+0xE479 0x92E3 #CJK UNIFIED IDEOGRAPH
+0xE47A 0x92E4 #CJK UNIFIED IDEOGRAPH
+0xE47B 0x92E5 #CJK UNIFIED IDEOGRAPH
+0xE47C 0x92E6 #CJK UNIFIED IDEOGRAPH
+0xE47D 0x92E7 #CJK UNIFIED IDEOGRAPH
+0xE47E 0x92E8 #CJK UNIFIED IDEOGRAPH
+0xE480 0x92E9 #CJK UNIFIED IDEOGRAPH
+0xE481 0x92EA #CJK UNIFIED IDEOGRAPH
+0xE482 0x92EB #CJK UNIFIED IDEOGRAPH
+0xE483 0x92EC #CJK UNIFIED IDEOGRAPH
+0xE484 0x92ED #CJK UNIFIED IDEOGRAPH
+0xE485 0x92EE #CJK UNIFIED IDEOGRAPH
+0xE486 0x92EF #CJK UNIFIED IDEOGRAPH
+0xE487 0x92F0 #CJK UNIFIED IDEOGRAPH
+0xE488 0x92F1 #CJK UNIFIED IDEOGRAPH
+0xE489 0x92F2 #CJK UNIFIED IDEOGRAPH
+0xE48A 0x92F3 #CJK UNIFIED IDEOGRAPH
+0xE48B 0x92F4 #CJK UNIFIED IDEOGRAPH
+0xE48C 0x92F5 #CJK UNIFIED IDEOGRAPH
+0xE48D 0x92F6 #CJK UNIFIED IDEOGRAPH
+0xE48E 0x92F7 #CJK UNIFIED IDEOGRAPH
+0xE48F 0x92F8 #CJK UNIFIED IDEOGRAPH
+0xE490 0x92F9 #CJK UNIFIED IDEOGRAPH
+0xE491 0x92FA #CJK UNIFIED IDEOGRAPH
+0xE492 0x92FB #CJK UNIFIED IDEOGRAPH
+0xE493 0x92FC #CJK UNIFIED IDEOGRAPH
+0xE494 0x92FD #CJK UNIFIED IDEOGRAPH
+0xE495 0x92FE #CJK UNIFIED IDEOGRAPH
+0xE496 0x92FF #CJK UNIFIED IDEOGRAPH
+0xE497 0x9300 #CJK UNIFIED IDEOGRAPH
+0xE498 0x9301 #CJK UNIFIED IDEOGRAPH
+0xE499 0x9302 #CJK UNIFIED IDEOGRAPH
+0xE49A 0x9303 #CJK UNIFIED IDEOGRAPH
+0xE49B 0x9304 #CJK UNIFIED IDEOGRAPH
+0xE49C 0x9305 #CJK UNIFIED IDEOGRAPH
+0xE49D 0x9306 #CJK UNIFIED IDEOGRAPH
+0xE49E 0x9307 #CJK UNIFIED IDEOGRAPH
+0xE49F 0x9308 #CJK UNIFIED IDEOGRAPH
+0xE4A0 0x9309 #CJK UNIFIED IDEOGRAPH
+0xE4A1 0x6D39 #CJK UNIFIED IDEOGRAPH
+0xE4A2 0x6D27 #CJK UNIFIED IDEOGRAPH
+0xE4A3 0x6D0C #CJK UNIFIED IDEOGRAPH
+0xE4A4 0x6D43 #CJK UNIFIED IDEOGRAPH
+0xE4A5 0x6D48 #CJK UNIFIED IDEOGRAPH
+0xE4A6 0x6D07 #CJK UNIFIED IDEOGRAPH
+0xE4A7 0x6D04 #CJK UNIFIED IDEOGRAPH
+0xE4A8 0x6D19 #CJK UNIFIED IDEOGRAPH
+0xE4A9 0x6D0E #CJK UNIFIED IDEOGRAPH
+0xE4AA 0x6D2B #CJK UNIFIED IDEOGRAPH
+0xE4AB 0x6D4D #CJK UNIFIED IDEOGRAPH
+0xE4AC 0x6D2E #CJK UNIFIED IDEOGRAPH
+0xE4AD 0x6D35 #CJK UNIFIED IDEOGRAPH
+0xE4AE 0x6D1A #CJK UNIFIED IDEOGRAPH
+0xE4AF 0x6D4F #CJK UNIFIED IDEOGRAPH
+0xE4B0 0x6D52 #CJK UNIFIED IDEOGRAPH
+0xE4B1 0x6D54 #CJK UNIFIED IDEOGRAPH
+0xE4B2 0x6D33 #CJK UNIFIED IDEOGRAPH
+0xE4B3 0x6D91 #CJK UNIFIED IDEOGRAPH
+0xE4B4 0x6D6F #CJK UNIFIED IDEOGRAPH
+0xE4B5 0x6D9E #CJK UNIFIED IDEOGRAPH
+0xE4B6 0x6DA0 #CJK UNIFIED IDEOGRAPH
+0xE4B7 0x6D5E #CJK UNIFIED IDEOGRAPH
+0xE4B8 0x6D93 #CJK UNIFIED IDEOGRAPH
+0xE4B9 0x6D94 #CJK UNIFIED IDEOGRAPH
+0xE4BA 0x6D5C #CJK UNIFIED IDEOGRAPH
+0xE4BB 0x6D60 #CJK UNIFIED IDEOGRAPH
+0xE4BC 0x6D7C #CJK UNIFIED IDEOGRAPH
+0xE4BD 0x6D63 #CJK UNIFIED IDEOGRAPH
+0xE4BE 0x6E1A #CJK UNIFIED IDEOGRAPH
+0xE4BF 0x6DC7 #CJK UNIFIED IDEOGRAPH
+0xE4C0 0x6DC5 #CJK UNIFIED IDEOGRAPH
+0xE4C1 0x6DDE #CJK UNIFIED IDEOGRAPH
+0xE4C2 0x6E0E #CJK UNIFIED IDEOGRAPH
+0xE4C3 0x6DBF #CJK UNIFIED IDEOGRAPH
+0xE4C4 0x6DE0 #CJK UNIFIED IDEOGRAPH
+0xE4C5 0x6E11 #CJK UNIFIED IDEOGRAPH
+0xE4C6 0x6DE6 #CJK UNIFIED IDEOGRAPH
+0xE4C7 0x6DDD #CJK UNIFIED IDEOGRAPH
+0xE4C8 0x6DD9 #CJK UNIFIED IDEOGRAPH
+0xE4C9 0x6E16 #CJK UNIFIED IDEOGRAPH
+0xE4CA 0x6DAB #CJK UNIFIED IDEOGRAPH
+0xE4CB 0x6E0C #CJK UNIFIED IDEOGRAPH
+0xE4CC 0x6DAE #CJK UNIFIED IDEOGRAPH
+0xE4CD 0x6E2B #CJK UNIFIED IDEOGRAPH
+0xE4CE 0x6E6E #CJK UNIFIED IDEOGRAPH
+0xE4CF 0x6E4E #CJK UNIFIED IDEOGRAPH
+0xE4D0 0x6E6B #CJK UNIFIED IDEOGRAPH
+0xE4D1 0x6EB2 #CJK UNIFIED IDEOGRAPH
+0xE4D2 0x6E5F #CJK UNIFIED IDEOGRAPH
+0xE4D3 0x6E86 #CJK UNIFIED IDEOGRAPH
+0xE4D4 0x6E53 #CJK UNIFIED IDEOGRAPH
+0xE4D5 0x6E54 #CJK UNIFIED IDEOGRAPH
+0xE4D6 0x6E32 #CJK UNIFIED IDEOGRAPH
+0xE4D7 0x6E25 #CJK UNIFIED IDEOGRAPH
+0xE4D8 0x6E44 #CJK UNIFIED IDEOGRAPH
+0xE4D9 0x6EDF #CJK UNIFIED IDEOGRAPH
+0xE4DA 0x6EB1 #CJK UNIFIED IDEOGRAPH
+0xE4DB 0x6E98 #CJK UNIFIED IDEOGRAPH
+0xE4DC 0x6EE0 #CJK UNIFIED IDEOGRAPH
+0xE4DD 0x6F2D #CJK UNIFIED IDEOGRAPH
+0xE4DE 0x6EE2 #CJK UNIFIED IDEOGRAPH
+0xE4DF 0x6EA5 #CJK UNIFIED IDEOGRAPH
+0xE4E0 0x6EA7 #CJK UNIFIED IDEOGRAPH
+0xE4E1 0x6EBD #CJK UNIFIED IDEOGRAPH
+0xE4E2 0x6EBB #CJK UNIFIED IDEOGRAPH
+0xE4E3 0x6EB7 #CJK UNIFIED IDEOGRAPH
+0xE4E4 0x6ED7 #CJK UNIFIED IDEOGRAPH
+0xE4E5 0x6EB4 #CJK UNIFIED IDEOGRAPH
+0xE4E6 0x6ECF #CJK UNIFIED IDEOGRAPH
+0xE4E7 0x6E8F #CJK UNIFIED IDEOGRAPH
+0xE4E8 0x6EC2 #CJK UNIFIED IDEOGRAPH
+0xE4E9 0x6E9F #CJK UNIFIED IDEOGRAPH
+0xE4EA 0x6F62 #CJK UNIFIED IDEOGRAPH
+0xE4EB 0x6F46 #CJK UNIFIED IDEOGRAPH
+0xE4EC 0x6F47 #CJK UNIFIED IDEOGRAPH
+0xE4ED 0x6F24 #CJK UNIFIED IDEOGRAPH
+0xE4EE 0x6F15 #CJK UNIFIED IDEOGRAPH
+0xE4EF 0x6EF9 #CJK UNIFIED IDEOGRAPH
+0xE4F0 0x6F2F #CJK UNIFIED IDEOGRAPH
+0xE4F1 0x6F36 #CJK UNIFIED IDEOGRAPH
+0xE4F2 0x6F4B #CJK UNIFIED IDEOGRAPH
+0xE4F3 0x6F74 #CJK UNIFIED IDEOGRAPH
+0xE4F4 0x6F2A #CJK UNIFIED IDEOGRAPH
+0xE4F5 0x6F09 #CJK UNIFIED IDEOGRAPH
+0xE4F6 0x6F29 #CJK UNIFIED IDEOGRAPH
+0xE4F7 0x6F89 #CJK UNIFIED IDEOGRAPH
+0xE4F8 0x6F8D #CJK UNIFIED IDEOGRAPH
+0xE4F9 0x6F8C #CJK UNIFIED IDEOGRAPH
+0xE4FA 0x6F78 #CJK UNIFIED IDEOGRAPH
+0xE4FB 0x6F72 #CJK UNIFIED IDEOGRAPH
+0xE4FC 0x6F7C #CJK UNIFIED IDEOGRAPH
+0xE4FD 0x6F7A #CJK UNIFIED IDEOGRAPH
+0xE4FE 0x6FD1 #CJK UNIFIED IDEOGRAPH
+0xE540 0x930A #CJK UNIFIED IDEOGRAPH
+0xE541 0x930B #CJK UNIFIED IDEOGRAPH
+0xE542 0x930C #CJK UNIFIED IDEOGRAPH
+0xE543 0x930D #CJK UNIFIED IDEOGRAPH
+0xE544 0x930E #CJK UNIFIED IDEOGRAPH
+0xE545 0x930F #CJK UNIFIED IDEOGRAPH
+0xE546 0x9310 #CJK UNIFIED IDEOGRAPH
+0xE547 0x9311 #CJK UNIFIED IDEOGRAPH
+0xE548 0x9312 #CJK UNIFIED IDEOGRAPH
+0xE549 0x9313 #CJK UNIFIED IDEOGRAPH
+0xE54A 0x9314 #CJK UNIFIED IDEOGRAPH
+0xE54B 0x9315 #CJK UNIFIED IDEOGRAPH
+0xE54C 0x9316 #CJK UNIFIED IDEOGRAPH
+0xE54D 0x9317 #CJK UNIFIED IDEOGRAPH
+0xE54E 0x9318 #CJK UNIFIED IDEOGRAPH
+0xE54F 0x9319 #CJK UNIFIED IDEOGRAPH
+0xE550 0x931A #CJK UNIFIED IDEOGRAPH
+0xE551 0x931B #CJK UNIFIED IDEOGRAPH
+0xE552 0x931C #CJK UNIFIED IDEOGRAPH
+0xE553 0x931D #CJK UNIFIED IDEOGRAPH
+0xE554 0x931E #CJK UNIFIED IDEOGRAPH
+0xE555 0x931F #CJK UNIFIED IDEOGRAPH
+0xE556 0x9320 #CJK UNIFIED IDEOGRAPH
+0xE557 0x9321 #CJK UNIFIED IDEOGRAPH
+0xE558 0x9322 #CJK UNIFIED IDEOGRAPH
+0xE559 0x9323 #CJK UNIFIED IDEOGRAPH
+0xE55A 0x9324 #CJK UNIFIED IDEOGRAPH
+0xE55B 0x9325 #CJK UNIFIED IDEOGRAPH
+0xE55C 0x9326 #CJK UNIFIED IDEOGRAPH
+0xE55D 0x9327 #CJK UNIFIED IDEOGRAPH
+0xE55E 0x9328 #CJK UNIFIED IDEOGRAPH
+0xE55F 0x9329 #CJK UNIFIED IDEOGRAPH
+0xE560 0x932A #CJK UNIFIED IDEOGRAPH
+0xE561 0x932B #CJK UNIFIED IDEOGRAPH
+0xE562 0x932C #CJK UNIFIED IDEOGRAPH
+0xE563 0x932D #CJK UNIFIED IDEOGRAPH
+0xE564 0x932E #CJK UNIFIED IDEOGRAPH
+0xE565 0x932F #CJK UNIFIED IDEOGRAPH
+0xE566 0x9330 #CJK UNIFIED IDEOGRAPH
+0xE567 0x9331 #CJK UNIFIED IDEOGRAPH
+0xE568 0x9332 #CJK UNIFIED IDEOGRAPH
+0xE569 0x9333 #CJK UNIFIED IDEOGRAPH
+0xE56A 0x9334 #CJK UNIFIED IDEOGRAPH
+0xE56B 0x9335 #CJK UNIFIED IDEOGRAPH
+0xE56C 0x9336 #CJK UNIFIED IDEOGRAPH
+0xE56D 0x9337 #CJK UNIFIED IDEOGRAPH
+0xE56E 0x9338 #CJK UNIFIED IDEOGRAPH
+0xE56F 0x9339 #CJK UNIFIED IDEOGRAPH
+0xE570 0x933A #CJK UNIFIED IDEOGRAPH
+0xE571 0x933B #CJK UNIFIED IDEOGRAPH
+0xE572 0x933C #CJK UNIFIED IDEOGRAPH
+0xE573 0x933D #CJK UNIFIED IDEOGRAPH
+0xE574 0x933F #CJK UNIFIED IDEOGRAPH
+0xE575 0x9340 #CJK UNIFIED IDEOGRAPH
+0xE576 0x9341 #CJK UNIFIED IDEOGRAPH
+0xE577 0x9342 #CJK UNIFIED IDEOGRAPH
+0xE578 0x9343 #CJK UNIFIED IDEOGRAPH
+0xE579 0x9344 #CJK UNIFIED IDEOGRAPH
+0xE57A 0x9345 #CJK UNIFIED IDEOGRAPH
+0xE57B 0x9346 #CJK UNIFIED IDEOGRAPH
+0xE57C 0x9347 #CJK UNIFIED IDEOGRAPH
+0xE57D 0x9348 #CJK UNIFIED IDEOGRAPH
+0xE57E 0x9349 #CJK UNIFIED IDEOGRAPH
+0xE580 0x934A #CJK UNIFIED IDEOGRAPH
+0xE581 0x934B #CJK UNIFIED IDEOGRAPH
+0xE582 0x934C #CJK UNIFIED IDEOGRAPH
+0xE583 0x934D #CJK UNIFIED IDEOGRAPH
+0xE584 0x934E #CJK UNIFIED IDEOGRAPH
+0xE585 0x934F #CJK UNIFIED IDEOGRAPH
+0xE586 0x9350 #CJK UNIFIED IDEOGRAPH
+0xE587 0x9351 #CJK UNIFIED IDEOGRAPH
+0xE588 0x9352 #CJK UNIFIED IDEOGRAPH
+0xE589 0x9353 #CJK UNIFIED IDEOGRAPH
+0xE58A 0x9354 #CJK UNIFIED IDEOGRAPH
+0xE58B 0x9355 #CJK UNIFIED IDEOGRAPH
+0xE58C 0x9356 #CJK UNIFIED IDEOGRAPH
+0xE58D 0x9357 #CJK UNIFIED IDEOGRAPH
+0xE58E 0x9358 #CJK UNIFIED IDEOGRAPH
+0xE58F 0x9359 #CJK UNIFIED IDEOGRAPH
+0xE590 0x935A #CJK UNIFIED IDEOGRAPH
+0xE591 0x935B #CJK UNIFIED IDEOGRAPH
+0xE592 0x935C #CJK UNIFIED IDEOGRAPH
+0xE593 0x935D #CJK UNIFIED IDEOGRAPH
+0xE594 0x935E #CJK UNIFIED IDEOGRAPH
+0xE595 0x935F #CJK UNIFIED IDEOGRAPH
+0xE596 0x9360 #CJK UNIFIED IDEOGRAPH
+0xE597 0x9361 #CJK UNIFIED IDEOGRAPH
+0xE598 0x9362 #CJK UNIFIED IDEOGRAPH
+0xE599 0x9363 #CJK UNIFIED IDEOGRAPH
+0xE59A 0x9364 #CJK UNIFIED IDEOGRAPH
+0xE59B 0x9365 #CJK UNIFIED IDEOGRAPH
+0xE59C 0x9366 #CJK UNIFIED IDEOGRAPH
+0xE59D 0x9367 #CJK UNIFIED IDEOGRAPH
+0xE59E 0x9368 #CJK UNIFIED IDEOGRAPH
+0xE59F 0x9369 #CJK UNIFIED IDEOGRAPH
+0xE5A0 0x936B #CJK UNIFIED IDEOGRAPH
+0xE5A1 0x6FC9 #CJK UNIFIED IDEOGRAPH
+0xE5A2 0x6FA7 #CJK UNIFIED IDEOGRAPH
+0xE5A3 0x6FB9 #CJK UNIFIED IDEOGRAPH
+0xE5A4 0x6FB6 #CJK UNIFIED IDEOGRAPH
+0xE5A5 0x6FC2 #CJK UNIFIED IDEOGRAPH
+0xE5A6 0x6FE1 #CJK UNIFIED IDEOGRAPH
+0xE5A7 0x6FEE #CJK UNIFIED IDEOGRAPH
+0xE5A8 0x6FDE #CJK UNIFIED IDEOGRAPH
+0xE5A9 0x6FE0 #CJK UNIFIED IDEOGRAPH
+0xE5AA 0x6FEF #CJK UNIFIED IDEOGRAPH
+0xE5AB 0x701A #CJK UNIFIED IDEOGRAPH
+0xE5AC 0x7023 #CJK UNIFIED IDEOGRAPH
+0xE5AD 0x701B #CJK UNIFIED IDEOGRAPH
+0xE5AE 0x7039 #CJK UNIFIED IDEOGRAPH
+0xE5AF 0x7035 #CJK UNIFIED IDEOGRAPH
+0xE5B0 0x704F #CJK UNIFIED IDEOGRAPH
+0xE5B1 0x705E #CJK UNIFIED IDEOGRAPH
+0xE5B2 0x5B80 #CJK UNIFIED IDEOGRAPH
+0xE5B3 0x5B84 #CJK UNIFIED IDEOGRAPH
+0xE5B4 0x5B95 #CJK UNIFIED IDEOGRAPH
+0xE5B5 0x5B93 #CJK UNIFIED IDEOGRAPH
+0xE5B6 0x5BA5 #CJK UNIFIED IDEOGRAPH
+0xE5B7 0x5BB8 #CJK UNIFIED IDEOGRAPH
+0xE5B8 0x752F #CJK UNIFIED IDEOGRAPH
+0xE5B9 0x9A9E #CJK UNIFIED IDEOGRAPH
+0xE5BA 0x6434 #CJK UNIFIED IDEOGRAPH
+0xE5BB 0x5BE4 #CJK UNIFIED IDEOGRAPH
+0xE5BC 0x5BEE #CJK UNIFIED IDEOGRAPH
+0xE5BD 0x8930 #CJK UNIFIED IDEOGRAPH
+0xE5BE 0x5BF0 #CJK UNIFIED IDEOGRAPH
+0xE5BF 0x8E47 #CJK UNIFIED IDEOGRAPH
+0xE5C0 0x8B07 #CJK UNIFIED IDEOGRAPH
+0xE5C1 0x8FB6 #CJK UNIFIED IDEOGRAPH
+0xE5C2 0x8FD3 #CJK UNIFIED IDEOGRAPH
+0xE5C3 0x8FD5 #CJK UNIFIED IDEOGRAPH
+0xE5C4 0x8FE5 #CJK UNIFIED IDEOGRAPH
+0xE5C5 0x8FEE #CJK UNIFIED IDEOGRAPH
+0xE5C6 0x8FE4 #CJK UNIFIED IDEOGRAPH
+0xE5C7 0x8FE9 #CJK UNIFIED IDEOGRAPH
+0xE5C8 0x8FE6 #CJK UNIFIED IDEOGRAPH
+0xE5C9 0x8FF3 #CJK UNIFIED IDEOGRAPH
+0xE5CA 0x8FE8 #CJK UNIFIED IDEOGRAPH
+0xE5CB 0x9005 #CJK UNIFIED IDEOGRAPH
+0xE5CC 0x9004 #CJK UNIFIED IDEOGRAPH
+0xE5CD 0x900B #CJK UNIFIED IDEOGRAPH
+0xE5CE 0x9026 #CJK UNIFIED IDEOGRAPH
+0xE5CF 0x9011 #CJK UNIFIED IDEOGRAPH
+0xE5D0 0x900D #CJK UNIFIED IDEOGRAPH
+0xE5D1 0x9016 #CJK UNIFIED IDEOGRAPH
+0xE5D2 0x9021 #CJK UNIFIED IDEOGRAPH
+0xE5D3 0x9035 #CJK UNIFIED IDEOGRAPH
+0xE5D4 0x9036 #CJK UNIFIED IDEOGRAPH
+0xE5D5 0x902D #CJK UNIFIED IDEOGRAPH
+0xE5D6 0x902F #CJK UNIFIED IDEOGRAPH
+0xE5D7 0x9044 #CJK UNIFIED IDEOGRAPH
+0xE5D8 0x9051 #CJK UNIFIED IDEOGRAPH
+0xE5D9 0x9052 #CJK UNIFIED IDEOGRAPH
+0xE5DA 0x9050 #CJK UNIFIED IDEOGRAPH
+0xE5DB 0x9068 #CJK UNIFIED IDEOGRAPH
+0xE5DC 0x9058 #CJK UNIFIED IDEOGRAPH
+0xE5DD 0x9062 #CJK UNIFIED IDEOGRAPH
+0xE5DE 0x905B #CJK UNIFIED IDEOGRAPH
+0xE5DF 0x66B9 #CJK UNIFIED IDEOGRAPH
+0xE5E0 0x9074 #CJK UNIFIED IDEOGRAPH
+0xE5E1 0x907D #CJK UNIFIED IDEOGRAPH
+0xE5E2 0x9082 #CJK UNIFIED IDEOGRAPH
+0xE5E3 0x9088 #CJK UNIFIED IDEOGRAPH
+0xE5E4 0x9083 #CJK UNIFIED IDEOGRAPH
+0xE5E5 0x908B #CJK UNIFIED IDEOGRAPH
+0xE5E6 0x5F50 #CJK UNIFIED IDEOGRAPH
+0xE5E7 0x5F57 #CJK UNIFIED IDEOGRAPH
+0xE5E8 0x5F56 #CJK UNIFIED IDEOGRAPH
+0xE5E9 0x5F58 #CJK UNIFIED IDEOGRAPH
+0xE5EA 0x5C3B #CJK UNIFIED IDEOGRAPH
+0xE5EB 0x54AB #CJK UNIFIED IDEOGRAPH
+0xE5EC 0x5C50 #CJK UNIFIED IDEOGRAPH
+0xE5ED 0x5C59 #CJK UNIFIED IDEOGRAPH
+0xE5EE 0x5B71 #CJK UNIFIED IDEOGRAPH
+0xE5EF 0x5C63 #CJK UNIFIED IDEOGRAPH
+0xE5F0 0x5C66 #CJK UNIFIED IDEOGRAPH
+0xE5F1 0x7FBC #CJK UNIFIED IDEOGRAPH
+0xE5F2 0x5F2A #CJK UNIFIED IDEOGRAPH
+0xE5F3 0x5F29 #CJK UNIFIED IDEOGRAPH
+0xE5F4 0x5F2D #CJK UNIFIED IDEOGRAPH
+0xE5F5 0x8274 #CJK UNIFIED IDEOGRAPH
+0xE5F6 0x5F3C #CJK UNIFIED IDEOGRAPH
+0xE5F7 0x9B3B #CJK UNIFIED IDEOGRAPH
+0xE5F8 0x5C6E #CJK UNIFIED IDEOGRAPH
+0xE5F9 0x5981 #CJK UNIFIED IDEOGRAPH
+0xE5FA 0x5983 #CJK UNIFIED IDEOGRAPH
+0xE5FB 0x598D #CJK UNIFIED IDEOGRAPH
+0xE5FC 0x59A9 #CJK UNIFIED IDEOGRAPH
+0xE5FD 0x59AA #CJK UNIFIED IDEOGRAPH
+0xE5FE 0x59A3 #CJK UNIFIED IDEOGRAPH
+0xE640 0x936C #CJK UNIFIED IDEOGRAPH
+0xE641 0x936D #CJK UNIFIED IDEOGRAPH
+0xE642 0x936E #CJK UNIFIED IDEOGRAPH
+0xE643 0x936F #CJK UNIFIED IDEOGRAPH
+0xE644 0x9370 #CJK UNIFIED IDEOGRAPH
+0xE645 0x9371 #CJK UNIFIED IDEOGRAPH
+0xE646 0x9372 #CJK UNIFIED IDEOGRAPH
+0xE647 0x9373 #CJK UNIFIED IDEOGRAPH
+0xE648 0x9374 #CJK UNIFIED IDEOGRAPH
+0xE649 0x9375 #CJK UNIFIED IDEOGRAPH
+0xE64A 0x9376 #CJK UNIFIED IDEOGRAPH
+0xE64B 0x9377 #CJK UNIFIED IDEOGRAPH
+0xE64C 0x9378 #CJK UNIFIED IDEOGRAPH
+0xE64D 0x9379 #CJK UNIFIED IDEOGRAPH
+0xE64E 0x937A #CJK UNIFIED IDEOGRAPH
+0xE64F 0x937B #CJK UNIFIED IDEOGRAPH
+0xE650 0x937C #CJK UNIFIED IDEOGRAPH
+0xE651 0x937D #CJK UNIFIED IDEOGRAPH
+0xE652 0x937E #CJK UNIFIED IDEOGRAPH
+0xE653 0x937F #CJK UNIFIED IDEOGRAPH
+0xE654 0x9380 #CJK UNIFIED IDEOGRAPH
+0xE655 0x9381 #CJK UNIFIED IDEOGRAPH
+0xE656 0x9382 #CJK UNIFIED IDEOGRAPH
+0xE657 0x9383 #CJK UNIFIED IDEOGRAPH
+0xE658 0x9384 #CJK UNIFIED IDEOGRAPH
+0xE659 0x9385 #CJK UNIFIED IDEOGRAPH
+0xE65A 0x9386 #CJK UNIFIED IDEOGRAPH
+0xE65B 0x9387 #CJK UNIFIED IDEOGRAPH
+0xE65C 0x9388 #CJK UNIFIED IDEOGRAPH
+0xE65D 0x9389 #CJK UNIFIED IDEOGRAPH
+0xE65E 0x938A #CJK UNIFIED IDEOGRAPH
+0xE65F 0x938B #CJK UNIFIED IDEOGRAPH
+0xE660 0x938C #CJK UNIFIED IDEOGRAPH
+0xE661 0x938D #CJK UNIFIED IDEOGRAPH
+0xE662 0x938E #CJK UNIFIED IDEOGRAPH
+0xE663 0x9390 #CJK UNIFIED IDEOGRAPH
+0xE664 0x9391 #CJK UNIFIED IDEOGRAPH
+0xE665 0x9392 #CJK UNIFIED IDEOGRAPH
+0xE666 0x9393 #CJK UNIFIED IDEOGRAPH
+0xE667 0x9394 #CJK UNIFIED IDEOGRAPH
+0xE668 0x9395 #CJK UNIFIED IDEOGRAPH
+0xE669 0x9396 #CJK UNIFIED IDEOGRAPH
+0xE66A 0x9397 #CJK UNIFIED IDEOGRAPH
+0xE66B 0x9398 #CJK UNIFIED IDEOGRAPH
+0xE66C 0x9399 #CJK UNIFIED IDEOGRAPH
+0xE66D 0x939A #CJK UNIFIED IDEOGRAPH
+0xE66E 0x939B #CJK UNIFIED IDEOGRAPH
+0xE66F 0x939C #CJK UNIFIED IDEOGRAPH
+0xE670 0x939D #CJK UNIFIED IDEOGRAPH
+0xE671 0x939E #CJK UNIFIED IDEOGRAPH
+0xE672 0x939F #CJK UNIFIED IDEOGRAPH
+0xE673 0x93A0 #CJK UNIFIED IDEOGRAPH
+0xE674 0x93A1 #CJK UNIFIED IDEOGRAPH
+0xE675 0x93A2 #CJK UNIFIED IDEOGRAPH
+0xE676 0x93A3 #CJK UNIFIED IDEOGRAPH
+0xE677 0x93A4 #CJK UNIFIED IDEOGRAPH
+0xE678 0x93A5 #CJK UNIFIED IDEOGRAPH
+0xE679 0x93A6 #CJK UNIFIED IDEOGRAPH
+0xE67A 0x93A7 #CJK UNIFIED IDEOGRAPH
+0xE67B 0x93A8 #CJK UNIFIED IDEOGRAPH
+0xE67C 0x93A9 #CJK UNIFIED IDEOGRAPH
+0xE67D 0x93AA #CJK UNIFIED IDEOGRAPH
+0xE67E 0x93AB #CJK UNIFIED IDEOGRAPH
+0xE680 0x93AC #CJK UNIFIED IDEOGRAPH
+0xE681 0x93AD #CJK UNIFIED IDEOGRAPH
+0xE682 0x93AE #CJK UNIFIED IDEOGRAPH
+0xE683 0x93AF #CJK UNIFIED IDEOGRAPH
+0xE684 0x93B0 #CJK UNIFIED IDEOGRAPH
+0xE685 0x93B1 #CJK UNIFIED IDEOGRAPH
+0xE686 0x93B2 #CJK UNIFIED IDEOGRAPH
+0xE687 0x93B3 #CJK UNIFIED IDEOGRAPH
+0xE688 0x93B4 #CJK UNIFIED IDEOGRAPH
+0xE689 0x93B5 #CJK UNIFIED IDEOGRAPH
+0xE68A 0x93B6 #CJK UNIFIED IDEOGRAPH
+0xE68B 0x93B7 #CJK UNIFIED IDEOGRAPH
+0xE68C 0x93B8 #CJK UNIFIED IDEOGRAPH
+0xE68D 0x93B9 #CJK UNIFIED IDEOGRAPH
+0xE68E 0x93BA #CJK UNIFIED IDEOGRAPH
+0xE68F 0x93BB #CJK UNIFIED IDEOGRAPH
+0xE690 0x93BC #CJK UNIFIED IDEOGRAPH
+0xE691 0x93BD #CJK UNIFIED IDEOGRAPH
+0xE692 0x93BE #CJK UNIFIED IDEOGRAPH
+0xE693 0x93BF #CJK UNIFIED IDEOGRAPH
+0xE694 0x93C0 #CJK UNIFIED IDEOGRAPH
+0xE695 0x93C1 #CJK UNIFIED IDEOGRAPH
+0xE696 0x93C2 #CJK UNIFIED IDEOGRAPH
+0xE697 0x93C3 #CJK UNIFIED IDEOGRAPH
+0xE698 0x93C4 #CJK UNIFIED IDEOGRAPH
+0xE699 0x93C5 #CJK UNIFIED IDEOGRAPH
+0xE69A 0x93C6 #CJK UNIFIED IDEOGRAPH
+0xE69B 0x93C7 #CJK UNIFIED IDEOGRAPH
+0xE69C 0x93C8 #CJK UNIFIED IDEOGRAPH
+0xE69D 0x93C9 #CJK UNIFIED IDEOGRAPH
+0xE69E 0x93CB #CJK UNIFIED IDEOGRAPH
+0xE69F 0x93CC #CJK UNIFIED IDEOGRAPH
+0xE6A0 0x93CD #CJK UNIFIED IDEOGRAPH
+0xE6A1 0x5997 #CJK UNIFIED IDEOGRAPH
+0xE6A2 0x59CA #CJK UNIFIED IDEOGRAPH
+0xE6A3 0x59AB #CJK UNIFIED IDEOGRAPH
+0xE6A4 0x599E #CJK UNIFIED IDEOGRAPH
+0xE6A5 0x59A4 #CJK UNIFIED IDEOGRAPH
+0xE6A6 0x59D2 #CJK UNIFIED IDEOGRAPH
+0xE6A7 0x59B2 #CJK UNIFIED IDEOGRAPH
+0xE6A8 0x59AF #CJK UNIFIED IDEOGRAPH
+0xE6A9 0x59D7 #CJK UNIFIED IDEOGRAPH
+0xE6AA 0x59BE #CJK UNIFIED IDEOGRAPH
+0xE6AB 0x5A05 #CJK UNIFIED IDEOGRAPH
+0xE6AC 0x5A06 #CJK UNIFIED IDEOGRAPH
+0xE6AD 0x59DD #CJK UNIFIED IDEOGRAPH
+0xE6AE 0x5A08 #CJK UNIFIED IDEOGRAPH
+0xE6AF 0x59E3 #CJK UNIFIED IDEOGRAPH
+0xE6B0 0x59D8 #CJK UNIFIED IDEOGRAPH
+0xE6B1 0x59F9 #CJK UNIFIED IDEOGRAPH
+0xE6B2 0x5A0C #CJK UNIFIED IDEOGRAPH
+0xE6B3 0x5A09 #CJK UNIFIED IDEOGRAPH
+0xE6B4 0x5A32 #CJK UNIFIED IDEOGRAPH
+0xE6B5 0x5A34 #CJK UNIFIED IDEOGRAPH
+0xE6B6 0x5A11 #CJK UNIFIED IDEOGRAPH
+0xE6B7 0x5A23 #CJK UNIFIED IDEOGRAPH
+0xE6B8 0x5A13 #CJK UNIFIED IDEOGRAPH
+0xE6B9 0x5A40 #CJK UNIFIED IDEOGRAPH
+0xE6BA 0x5A67 #CJK UNIFIED IDEOGRAPH
+0xE6BB 0x5A4A #CJK UNIFIED IDEOGRAPH
+0xE6BC 0x5A55 #CJK UNIFIED IDEOGRAPH
+0xE6BD 0x5A3C #CJK UNIFIED IDEOGRAPH
+0xE6BE 0x5A62 #CJK UNIFIED IDEOGRAPH
+0xE6BF 0x5A75 #CJK UNIFIED IDEOGRAPH
+0xE6C0 0x80EC #CJK UNIFIED IDEOGRAPH
+0xE6C1 0x5AAA #CJK UNIFIED IDEOGRAPH
+0xE6C2 0x5A9B #CJK UNIFIED IDEOGRAPH
+0xE6C3 0x5A77 #CJK UNIFIED IDEOGRAPH
+0xE6C4 0x5A7A #CJK UNIFIED IDEOGRAPH
+0xE6C5 0x5ABE #CJK UNIFIED IDEOGRAPH
+0xE6C6 0x5AEB #CJK UNIFIED IDEOGRAPH
+0xE6C7 0x5AB2 #CJK UNIFIED IDEOGRAPH
+0xE6C8 0x5AD2 #CJK UNIFIED IDEOGRAPH
+0xE6C9 0x5AD4 #CJK UNIFIED IDEOGRAPH
+0xE6CA 0x5AB8 #CJK UNIFIED IDEOGRAPH
+0xE6CB 0x5AE0 #CJK UNIFIED IDEOGRAPH
+0xE6CC 0x5AE3 #CJK UNIFIED IDEOGRAPH
+0xE6CD 0x5AF1 #CJK UNIFIED IDEOGRAPH
+0xE6CE 0x5AD6 #CJK UNIFIED IDEOGRAPH
+0xE6CF 0x5AE6 #CJK UNIFIED IDEOGRAPH
+0xE6D0 0x5AD8 #CJK UNIFIED IDEOGRAPH
+0xE6D1 0x5ADC #CJK UNIFIED IDEOGRAPH
+0xE6D2 0x5B09 #CJK UNIFIED IDEOGRAPH
+0xE6D3 0x5B17 #CJK UNIFIED IDEOGRAPH
+0xE6D4 0x5B16 #CJK UNIFIED IDEOGRAPH
+0xE6D5 0x5B32 #CJK UNIFIED IDEOGRAPH
+0xE6D6 0x5B37 #CJK UNIFIED IDEOGRAPH
+0xE6D7 0x5B40 #CJK UNIFIED IDEOGRAPH
+0xE6D8 0x5C15 #CJK UNIFIED IDEOGRAPH
+0xE6D9 0x5C1C #CJK UNIFIED IDEOGRAPH
+0xE6DA 0x5B5A #CJK UNIFIED IDEOGRAPH
+0xE6DB 0x5B65 #CJK UNIFIED IDEOGRAPH
+0xE6DC 0x5B73 #CJK UNIFIED IDEOGRAPH
+0xE6DD 0x5B51 #CJK UNIFIED IDEOGRAPH
+0xE6DE 0x5B53 #CJK UNIFIED IDEOGRAPH
+0xE6DF 0x5B62 #CJK UNIFIED IDEOGRAPH
+0xE6E0 0x9A75 #CJK UNIFIED IDEOGRAPH
+0xE6E1 0x9A77 #CJK UNIFIED IDEOGRAPH
+0xE6E2 0x9A78 #CJK UNIFIED IDEOGRAPH
+0xE6E3 0x9A7A #CJK UNIFIED IDEOGRAPH
+0xE6E4 0x9A7F #CJK UNIFIED IDEOGRAPH
+0xE6E5 0x9A7D #CJK UNIFIED IDEOGRAPH
+0xE6E6 0x9A80 #CJK UNIFIED IDEOGRAPH
+0xE6E7 0x9A81 #CJK UNIFIED IDEOGRAPH
+0xE6E8 0x9A85 #CJK UNIFIED IDEOGRAPH
+0xE6E9 0x9A88 #CJK UNIFIED IDEOGRAPH
+0xE6EA 0x9A8A #CJK UNIFIED IDEOGRAPH
+0xE6EB 0x9A90 #CJK UNIFIED IDEOGRAPH
+0xE6EC 0x9A92 #CJK UNIFIED IDEOGRAPH
+0xE6ED 0x9A93 #CJK UNIFIED IDEOGRAPH
+0xE6EE 0x9A96 #CJK UNIFIED IDEOGRAPH
+0xE6EF 0x9A98 #CJK UNIFIED IDEOGRAPH
+0xE6F0 0x9A9B #CJK UNIFIED IDEOGRAPH
+0xE6F1 0x9A9C #CJK UNIFIED IDEOGRAPH
+0xE6F2 0x9A9D #CJK UNIFIED IDEOGRAPH
+0xE6F3 0x9A9F #CJK UNIFIED IDEOGRAPH
+0xE6F4 0x9AA0 #CJK UNIFIED IDEOGRAPH
+0xE6F5 0x9AA2 #CJK UNIFIED IDEOGRAPH
+0xE6F6 0x9AA3 #CJK UNIFIED IDEOGRAPH
+0xE6F7 0x9AA5 #CJK UNIFIED IDEOGRAPH
+0xE6F8 0x9AA7 #CJK UNIFIED IDEOGRAPH
+0xE6F9 0x7E9F #CJK UNIFIED IDEOGRAPH
+0xE6FA 0x7EA1 #CJK UNIFIED IDEOGRAPH
+0xE6FB 0x7EA3 #CJK UNIFIED IDEOGRAPH
+0xE6FC 0x7EA5 #CJK UNIFIED IDEOGRAPH
+0xE6FD 0x7EA8 #CJK UNIFIED IDEOGRAPH
+0xE6FE 0x7EA9 #CJK UNIFIED IDEOGRAPH
+0xE740 0x93CE #CJK UNIFIED IDEOGRAPH
+0xE741 0x93CF #CJK UNIFIED IDEOGRAPH
+0xE742 0x93D0 #CJK UNIFIED IDEOGRAPH
+0xE743 0x93D1 #CJK UNIFIED IDEOGRAPH
+0xE744 0x93D2 #CJK UNIFIED IDEOGRAPH
+0xE745 0x93D3 #CJK UNIFIED IDEOGRAPH
+0xE746 0x93D4 #CJK UNIFIED IDEOGRAPH
+0xE747 0x93D5 #CJK UNIFIED IDEOGRAPH
+0xE748 0x93D7 #CJK UNIFIED IDEOGRAPH
+0xE749 0x93D8 #CJK UNIFIED IDEOGRAPH
+0xE74A 0x93D9 #CJK UNIFIED IDEOGRAPH
+0xE74B 0x93DA #CJK UNIFIED IDEOGRAPH
+0xE74C 0x93DB #CJK UNIFIED IDEOGRAPH
+0xE74D 0x93DC #CJK UNIFIED IDEOGRAPH
+0xE74E 0x93DD #CJK UNIFIED IDEOGRAPH
+0xE74F 0x93DE #CJK UNIFIED IDEOGRAPH
+0xE750 0x93DF #CJK UNIFIED IDEOGRAPH
+0xE751 0x93E0 #CJK UNIFIED IDEOGRAPH
+0xE752 0x93E1 #CJK UNIFIED IDEOGRAPH
+0xE753 0x93E2 #CJK UNIFIED IDEOGRAPH
+0xE754 0x93E3 #CJK UNIFIED IDEOGRAPH
+0xE755 0x93E4 #CJK UNIFIED IDEOGRAPH
+0xE756 0x93E5 #CJK UNIFIED IDEOGRAPH
+0xE757 0x93E6 #CJK UNIFIED IDEOGRAPH
+0xE758 0x93E7 #CJK UNIFIED IDEOGRAPH
+0xE759 0x93E8 #CJK UNIFIED IDEOGRAPH
+0xE75A 0x93E9 #CJK UNIFIED IDEOGRAPH
+0xE75B 0x93EA #CJK UNIFIED IDEOGRAPH
+0xE75C 0x93EB #CJK UNIFIED IDEOGRAPH
+0xE75D 0x93EC #CJK UNIFIED IDEOGRAPH
+0xE75E 0x93ED #CJK UNIFIED IDEOGRAPH
+0xE75F 0x93EE #CJK UNIFIED IDEOGRAPH
+0xE760 0x93EF #CJK UNIFIED IDEOGRAPH
+0xE761 0x93F0 #CJK UNIFIED IDEOGRAPH
+0xE762 0x93F1 #CJK UNIFIED IDEOGRAPH
+0xE763 0x93F2 #CJK UNIFIED IDEOGRAPH
+0xE764 0x93F3 #CJK UNIFIED IDEOGRAPH
+0xE765 0x93F4 #CJK UNIFIED IDEOGRAPH
+0xE766 0x93F5 #CJK UNIFIED IDEOGRAPH
+0xE767 0x93F6 #CJK UNIFIED IDEOGRAPH
+0xE768 0x93F7 #CJK UNIFIED IDEOGRAPH
+0xE769 0x93F8 #CJK UNIFIED IDEOGRAPH
+0xE76A 0x93F9 #CJK UNIFIED IDEOGRAPH
+0xE76B 0x93FA #CJK UNIFIED IDEOGRAPH
+0xE76C 0x93FB #CJK UNIFIED IDEOGRAPH
+0xE76D 0x93FC #CJK UNIFIED IDEOGRAPH
+0xE76E 0x93FD #CJK UNIFIED IDEOGRAPH
+0xE76F 0x93FE #CJK UNIFIED IDEOGRAPH
+0xE770 0x93FF #CJK UNIFIED IDEOGRAPH
+0xE771 0x9400 #CJK UNIFIED IDEOGRAPH
+0xE772 0x9401 #CJK UNIFIED IDEOGRAPH
+0xE773 0x9402 #CJK UNIFIED IDEOGRAPH
+0xE774 0x9403 #CJK UNIFIED IDEOGRAPH
+0xE775 0x9404 #CJK UNIFIED IDEOGRAPH
+0xE776 0x9405 #CJK UNIFIED IDEOGRAPH
+0xE777 0x9406 #CJK UNIFIED IDEOGRAPH
+0xE778 0x9407 #CJK UNIFIED IDEOGRAPH
+0xE779 0x9408 #CJK UNIFIED IDEOGRAPH
+0xE77A 0x9409 #CJK UNIFIED IDEOGRAPH
+0xE77B 0x940A #CJK UNIFIED IDEOGRAPH
+0xE77C 0x940B #CJK UNIFIED IDEOGRAPH
+0xE77D 0x940C #CJK UNIFIED IDEOGRAPH
+0xE77E 0x940D #CJK UNIFIED IDEOGRAPH
+0xE780 0x940E #CJK UNIFIED IDEOGRAPH
+0xE781 0x940F #CJK UNIFIED IDEOGRAPH
+0xE782 0x9410 #CJK UNIFIED IDEOGRAPH
+0xE783 0x9411 #CJK UNIFIED IDEOGRAPH
+0xE784 0x9412 #CJK UNIFIED IDEOGRAPH
+0xE785 0x9413 #CJK UNIFIED IDEOGRAPH
+0xE786 0x9414 #CJK UNIFIED IDEOGRAPH
+0xE787 0x9415 #CJK UNIFIED IDEOGRAPH
+0xE788 0x9416 #CJK UNIFIED IDEOGRAPH
+0xE789 0x9417 #CJK UNIFIED IDEOGRAPH
+0xE78A 0x9418 #CJK UNIFIED IDEOGRAPH
+0xE78B 0x9419 #CJK UNIFIED IDEOGRAPH
+0xE78C 0x941A #CJK UNIFIED IDEOGRAPH
+0xE78D 0x941B #CJK UNIFIED IDEOGRAPH
+0xE78E 0x941C #CJK UNIFIED IDEOGRAPH
+0xE78F 0x941D #CJK UNIFIED IDEOGRAPH
+0xE790 0x941E #CJK UNIFIED IDEOGRAPH
+0xE791 0x941F #CJK UNIFIED IDEOGRAPH
+0xE792 0x9420 #CJK UNIFIED IDEOGRAPH
+0xE793 0x9421 #CJK UNIFIED IDEOGRAPH
+0xE794 0x9422 #CJK UNIFIED IDEOGRAPH
+0xE795 0x9423 #CJK UNIFIED IDEOGRAPH
+0xE796 0x9424 #CJK UNIFIED IDEOGRAPH
+0xE797 0x9425 #CJK UNIFIED IDEOGRAPH
+0xE798 0x9426 #CJK UNIFIED IDEOGRAPH
+0xE799 0x9427 #CJK UNIFIED IDEOGRAPH
+0xE79A 0x9428 #CJK UNIFIED IDEOGRAPH
+0xE79B 0x9429 #CJK UNIFIED IDEOGRAPH
+0xE79C 0x942A #CJK UNIFIED IDEOGRAPH
+0xE79D 0x942B #CJK UNIFIED IDEOGRAPH
+0xE79E 0x942C #CJK UNIFIED IDEOGRAPH
+0xE79F 0x942D #CJK UNIFIED IDEOGRAPH
+0xE7A0 0x942E #CJK UNIFIED IDEOGRAPH
+0xE7A1 0x7EAD #CJK UNIFIED IDEOGRAPH
+0xE7A2 0x7EB0 #CJK UNIFIED IDEOGRAPH
+0xE7A3 0x7EBE #CJK UNIFIED IDEOGRAPH
+0xE7A4 0x7EC0 #CJK UNIFIED IDEOGRAPH
+0xE7A5 0x7EC1 #CJK UNIFIED IDEOGRAPH
+0xE7A6 0x7EC2 #CJK UNIFIED IDEOGRAPH
+0xE7A7 0x7EC9 #CJK UNIFIED IDEOGRAPH
+0xE7A8 0x7ECB #CJK UNIFIED IDEOGRAPH
+0xE7A9 0x7ECC #CJK UNIFIED IDEOGRAPH
+0xE7AA 0x7ED0 #CJK UNIFIED IDEOGRAPH
+0xE7AB 0x7ED4 #CJK UNIFIED IDEOGRAPH
+0xE7AC 0x7ED7 #CJK UNIFIED IDEOGRAPH
+0xE7AD 0x7EDB #CJK UNIFIED IDEOGRAPH
+0xE7AE 0x7EE0 #CJK UNIFIED IDEOGRAPH
+0xE7AF 0x7EE1 #CJK UNIFIED IDEOGRAPH
+0xE7B0 0x7EE8 #CJK UNIFIED IDEOGRAPH
+0xE7B1 0x7EEB #CJK UNIFIED IDEOGRAPH
+0xE7B2 0x7EEE #CJK UNIFIED IDEOGRAPH
+0xE7B3 0x7EEF #CJK UNIFIED IDEOGRAPH
+0xE7B4 0x7EF1 #CJK UNIFIED IDEOGRAPH
+0xE7B5 0x7EF2 #CJK UNIFIED IDEOGRAPH
+0xE7B6 0x7F0D #CJK UNIFIED IDEOGRAPH
+0xE7B7 0x7EF6 #CJK UNIFIED IDEOGRAPH
+0xE7B8 0x7EFA #CJK UNIFIED IDEOGRAPH
+0xE7B9 0x7EFB #CJK UNIFIED IDEOGRAPH
+0xE7BA 0x7EFE #CJK UNIFIED IDEOGRAPH
+0xE7BB 0x7F01 #CJK UNIFIED IDEOGRAPH
+0xE7BC 0x7F02 #CJK UNIFIED IDEOGRAPH
+0xE7BD 0x7F03 #CJK UNIFIED IDEOGRAPH
+0xE7BE 0x7F07 #CJK UNIFIED IDEOGRAPH
+0xE7BF 0x7F08 #CJK UNIFIED IDEOGRAPH
+0xE7C0 0x7F0B #CJK UNIFIED IDEOGRAPH
+0xE7C1 0x7F0C #CJK UNIFIED IDEOGRAPH
+0xE7C2 0x7F0F #CJK UNIFIED IDEOGRAPH
+0xE7C3 0x7F11 #CJK UNIFIED IDEOGRAPH
+0xE7C4 0x7F12 #CJK UNIFIED IDEOGRAPH
+0xE7C5 0x7F17 #CJK UNIFIED IDEOGRAPH
+0xE7C6 0x7F19 #CJK UNIFIED IDEOGRAPH
+0xE7C7 0x7F1C #CJK UNIFIED IDEOGRAPH
+0xE7C8 0x7F1B #CJK UNIFIED IDEOGRAPH
+0xE7C9 0x7F1F #CJK UNIFIED IDEOGRAPH
+0xE7CA 0x7F21 #CJK UNIFIED IDEOGRAPH
+0xE7CB 0x7F22 #CJK UNIFIED IDEOGRAPH
+0xE7CC 0x7F23 #CJK UNIFIED IDEOGRAPH
+0xE7CD 0x7F24 #CJK UNIFIED IDEOGRAPH
+0xE7CE 0x7F25 #CJK UNIFIED IDEOGRAPH
+0xE7CF 0x7F26 #CJK UNIFIED IDEOGRAPH
+0xE7D0 0x7F27 #CJK UNIFIED IDEOGRAPH
+0xE7D1 0x7F2A #CJK UNIFIED IDEOGRAPH
+0xE7D2 0x7F2B #CJK UNIFIED IDEOGRAPH
+0xE7D3 0x7F2C #CJK UNIFIED IDEOGRAPH
+0xE7D4 0x7F2D #CJK UNIFIED IDEOGRAPH
+0xE7D5 0x7F2F #CJK UNIFIED IDEOGRAPH
+0xE7D6 0x7F30 #CJK UNIFIED IDEOGRAPH
+0xE7D7 0x7F31 #CJK UNIFIED IDEOGRAPH
+0xE7D8 0x7F32 #CJK UNIFIED IDEOGRAPH
+0xE7D9 0x7F33 #CJK UNIFIED IDEOGRAPH
+0xE7DA 0x7F35 #CJK UNIFIED IDEOGRAPH
+0xE7DB 0x5E7A #CJK UNIFIED IDEOGRAPH
+0xE7DC 0x757F #CJK UNIFIED IDEOGRAPH
+0xE7DD 0x5DDB #CJK UNIFIED IDEOGRAPH
+0xE7DE 0x753E #CJK UNIFIED IDEOGRAPH
+0xE7DF 0x9095 #CJK UNIFIED IDEOGRAPH
+0xE7E0 0x738E #CJK UNIFIED IDEOGRAPH
+0xE7E1 0x7391 #CJK UNIFIED IDEOGRAPH
+0xE7E2 0x73AE #CJK UNIFIED IDEOGRAPH
+0xE7E3 0x73A2 #CJK UNIFIED IDEOGRAPH
+0xE7E4 0x739F #CJK UNIFIED IDEOGRAPH
+0xE7E5 0x73CF #CJK UNIFIED IDEOGRAPH
+0xE7E6 0x73C2 #CJK UNIFIED IDEOGRAPH
+0xE7E7 0x73D1 #CJK UNIFIED IDEOGRAPH
+0xE7E8 0x73B7 #CJK UNIFIED IDEOGRAPH
+0xE7E9 0x73B3 #CJK UNIFIED IDEOGRAPH
+0xE7EA 0x73C0 #CJK UNIFIED IDEOGRAPH
+0xE7EB 0x73C9 #CJK UNIFIED IDEOGRAPH
+0xE7EC 0x73C8 #CJK UNIFIED IDEOGRAPH
+0xE7ED 0x73E5 #CJK UNIFIED IDEOGRAPH
+0xE7EE 0x73D9 #CJK UNIFIED IDEOGRAPH
+0xE7EF 0x987C #CJK UNIFIED IDEOGRAPH
+0xE7F0 0x740A #CJK UNIFIED IDEOGRAPH
+0xE7F1 0x73E9 #CJK UNIFIED IDEOGRAPH
+0xE7F2 0x73E7 #CJK UNIFIED IDEOGRAPH
+0xE7F3 0x73DE #CJK UNIFIED IDEOGRAPH
+0xE7F4 0x73BA #CJK UNIFIED IDEOGRAPH
+0xE7F5 0x73F2 #CJK UNIFIED IDEOGRAPH
+0xE7F6 0x740F #CJK UNIFIED IDEOGRAPH
+0xE7F7 0x742A #CJK UNIFIED IDEOGRAPH
+0xE7F8 0x745B #CJK UNIFIED IDEOGRAPH
+0xE7F9 0x7426 #CJK UNIFIED IDEOGRAPH
+0xE7FA 0x7425 #CJK UNIFIED IDEOGRAPH
+0xE7FB 0x7428 #CJK UNIFIED IDEOGRAPH
+0xE7FC 0x7430 #CJK UNIFIED IDEOGRAPH
+0xE7FD 0x742E #CJK UNIFIED IDEOGRAPH
+0xE7FE 0x742C #CJK UNIFIED IDEOGRAPH
+0xE840 0x942F #CJK UNIFIED IDEOGRAPH
+0xE841 0x9430 #CJK UNIFIED IDEOGRAPH
+0xE842 0x9431 #CJK UNIFIED IDEOGRAPH
+0xE843 0x9432 #CJK UNIFIED IDEOGRAPH
+0xE844 0x9433 #CJK UNIFIED IDEOGRAPH
+0xE845 0x9434 #CJK UNIFIED IDEOGRAPH
+0xE846 0x9435 #CJK UNIFIED IDEOGRAPH
+0xE847 0x9436 #CJK UNIFIED IDEOGRAPH
+0xE848 0x9437 #CJK UNIFIED IDEOGRAPH
+0xE849 0x9438 #CJK UNIFIED IDEOGRAPH
+0xE84A 0x9439 #CJK UNIFIED IDEOGRAPH
+0xE84B 0x943A #CJK UNIFIED IDEOGRAPH
+0xE84C 0x943B #CJK UNIFIED IDEOGRAPH
+0xE84D 0x943C #CJK UNIFIED IDEOGRAPH
+0xE84E 0x943D #CJK UNIFIED IDEOGRAPH
+0xE84F 0x943F #CJK UNIFIED IDEOGRAPH
+0xE850 0x9440 #CJK UNIFIED IDEOGRAPH
+0xE851 0x9441 #CJK UNIFIED IDEOGRAPH
+0xE852 0x9442 #CJK UNIFIED IDEOGRAPH
+0xE853 0x9443 #CJK UNIFIED IDEOGRAPH
+0xE854 0x9444 #CJK UNIFIED IDEOGRAPH
+0xE855 0x9445 #CJK UNIFIED IDEOGRAPH
+0xE856 0x9446 #CJK UNIFIED IDEOGRAPH
+0xE857 0x9447 #CJK UNIFIED IDEOGRAPH
+0xE858 0x9448 #CJK UNIFIED IDEOGRAPH
+0xE859 0x9449 #CJK UNIFIED IDEOGRAPH
+0xE85A 0x944A #CJK UNIFIED IDEOGRAPH
+0xE85B 0x944B #CJK UNIFIED IDEOGRAPH
+0xE85C 0x944C #CJK UNIFIED IDEOGRAPH
+0xE85D 0x944D #CJK UNIFIED IDEOGRAPH
+0xE85E 0x944E #CJK UNIFIED IDEOGRAPH
+0xE85F 0x944F #CJK UNIFIED IDEOGRAPH
+0xE860 0x9450 #CJK UNIFIED IDEOGRAPH
+0xE861 0x9451 #CJK UNIFIED IDEOGRAPH
+0xE862 0x9452 #CJK UNIFIED IDEOGRAPH
+0xE863 0x9453 #CJK UNIFIED IDEOGRAPH
+0xE864 0x9454 #CJK UNIFIED IDEOGRAPH
+0xE865 0x9455 #CJK UNIFIED IDEOGRAPH
+0xE866 0x9456 #CJK UNIFIED IDEOGRAPH
+0xE867 0x9457 #CJK UNIFIED IDEOGRAPH
+0xE868 0x9458 #CJK UNIFIED IDEOGRAPH
+0xE869 0x9459 #CJK UNIFIED IDEOGRAPH
+0xE86A 0x945A #CJK UNIFIED IDEOGRAPH
+0xE86B 0x945B #CJK UNIFIED IDEOGRAPH
+0xE86C 0x945C #CJK UNIFIED IDEOGRAPH
+0xE86D 0x945D #CJK UNIFIED IDEOGRAPH
+0xE86E 0x945E #CJK UNIFIED IDEOGRAPH
+0xE86F 0x945F #CJK UNIFIED IDEOGRAPH
+0xE870 0x9460 #CJK UNIFIED IDEOGRAPH
+0xE871 0x9461 #CJK UNIFIED IDEOGRAPH
+0xE872 0x9462 #CJK UNIFIED IDEOGRAPH
+0xE873 0x9463 #CJK UNIFIED IDEOGRAPH
+0xE874 0x9464 #CJK UNIFIED IDEOGRAPH
+0xE875 0x9465 #CJK UNIFIED IDEOGRAPH
+0xE876 0x9466 #CJK UNIFIED IDEOGRAPH
+0xE877 0x9467 #CJK UNIFIED IDEOGRAPH
+0xE878 0x9468 #CJK UNIFIED IDEOGRAPH
+0xE879 0x9469 #CJK UNIFIED IDEOGRAPH
+0xE87A 0x946A #CJK UNIFIED IDEOGRAPH
+0xE87B 0x946C #CJK UNIFIED IDEOGRAPH
+0xE87C 0x946D #CJK UNIFIED IDEOGRAPH
+0xE87D 0x946E #CJK UNIFIED IDEOGRAPH
+0xE87E 0x946F #CJK UNIFIED IDEOGRAPH
+0xE880 0x9470 #CJK UNIFIED IDEOGRAPH
+0xE881 0x9471 #CJK UNIFIED IDEOGRAPH
+0xE882 0x9472 #CJK UNIFIED IDEOGRAPH
+0xE883 0x9473 #CJK UNIFIED IDEOGRAPH
+0xE884 0x9474 #CJK UNIFIED IDEOGRAPH
+0xE885 0x9475 #CJK UNIFIED IDEOGRAPH
+0xE886 0x9476 #CJK UNIFIED IDEOGRAPH
+0xE887 0x9477 #CJK UNIFIED IDEOGRAPH
+0xE888 0x9478 #CJK UNIFIED IDEOGRAPH
+0xE889 0x9479 #CJK UNIFIED IDEOGRAPH
+0xE88A 0x947A #CJK UNIFIED IDEOGRAPH
+0xE88B 0x947B #CJK UNIFIED IDEOGRAPH
+0xE88C 0x947C #CJK UNIFIED IDEOGRAPH
+0xE88D 0x947D #CJK UNIFIED IDEOGRAPH
+0xE88E 0x947E #CJK UNIFIED IDEOGRAPH
+0xE88F 0x947F #CJK UNIFIED IDEOGRAPH
+0xE890 0x9480 #CJK UNIFIED IDEOGRAPH
+0xE891 0x9481 #CJK UNIFIED IDEOGRAPH
+0xE892 0x9482 #CJK UNIFIED IDEOGRAPH
+0xE893 0x9483 #CJK UNIFIED IDEOGRAPH
+0xE894 0x9484 #CJK UNIFIED IDEOGRAPH
+0xE895 0x9491 #CJK UNIFIED IDEOGRAPH
+0xE896 0x9496 #CJK UNIFIED IDEOGRAPH
+0xE897 0x9498 #CJK UNIFIED IDEOGRAPH
+0xE898 0x94C7 #CJK UNIFIED IDEOGRAPH
+0xE899 0x94CF #CJK UNIFIED IDEOGRAPH
+0xE89A 0x94D3 #CJK UNIFIED IDEOGRAPH
+0xE89B 0x94D4 #CJK UNIFIED IDEOGRAPH
+0xE89C 0x94DA #CJK UNIFIED IDEOGRAPH
+0xE89D 0x94E6 #CJK UNIFIED IDEOGRAPH
+0xE89E 0x94FB #CJK UNIFIED IDEOGRAPH
+0xE89F 0x951C #CJK UNIFIED IDEOGRAPH
+0xE8A0 0x9520 #CJK UNIFIED IDEOGRAPH
+0xE8A1 0x741B #CJK UNIFIED IDEOGRAPH
+0xE8A2 0x741A #CJK UNIFIED IDEOGRAPH
+0xE8A3 0x7441 #CJK UNIFIED IDEOGRAPH
+0xE8A4 0x745C #CJK UNIFIED IDEOGRAPH
+0xE8A5 0x7457 #CJK UNIFIED IDEOGRAPH
+0xE8A6 0x7455 #CJK UNIFIED IDEOGRAPH
+0xE8A7 0x7459 #CJK UNIFIED IDEOGRAPH
+0xE8A8 0x7477 #CJK UNIFIED IDEOGRAPH
+0xE8A9 0x746D #CJK UNIFIED IDEOGRAPH
+0xE8AA 0x747E #CJK UNIFIED IDEOGRAPH
+0xE8AB 0x749C #CJK UNIFIED IDEOGRAPH
+0xE8AC 0x748E #CJK UNIFIED IDEOGRAPH
+0xE8AD 0x7480 #CJK UNIFIED IDEOGRAPH
+0xE8AE 0x7481 #CJK UNIFIED IDEOGRAPH
+0xE8AF 0x7487 #CJK UNIFIED IDEOGRAPH
+0xE8B0 0x748B #CJK UNIFIED IDEOGRAPH
+0xE8B1 0x749E #CJK UNIFIED IDEOGRAPH
+0xE8B2 0x74A8 #CJK UNIFIED IDEOGRAPH
+0xE8B3 0x74A9 #CJK UNIFIED IDEOGRAPH
+0xE8B4 0x7490 #CJK UNIFIED IDEOGRAPH
+0xE8B5 0x74A7 #CJK UNIFIED IDEOGRAPH
+0xE8B6 0x74D2 #CJK UNIFIED IDEOGRAPH
+0xE8B7 0x74BA #CJK UNIFIED IDEOGRAPH
+0xE8B8 0x97EA #CJK UNIFIED IDEOGRAPH
+0xE8B9 0x97EB #CJK UNIFIED IDEOGRAPH
+0xE8BA 0x97EC #CJK UNIFIED IDEOGRAPH
+0xE8BB 0x674C #CJK UNIFIED IDEOGRAPH
+0xE8BC 0x6753 #CJK UNIFIED IDEOGRAPH
+0xE8BD 0x675E #CJK UNIFIED IDEOGRAPH
+0xE8BE 0x6748 #CJK UNIFIED IDEOGRAPH
+0xE8BF 0x6769 #CJK UNIFIED IDEOGRAPH
+0xE8C0 0x67A5 #CJK UNIFIED IDEOGRAPH
+0xE8C1 0x6787 #CJK UNIFIED IDEOGRAPH
+0xE8C2 0x676A #CJK UNIFIED IDEOGRAPH
+0xE8C3 0x6773 #CJK UNIFIED IDEOGRAPH
+0xE8C4 0x6798 #CJK UNIFIED IDEOGRAPH
+0xE8C5 0x67A7 #CJK UNIFIED IDEOGRAPH
+0xE8C6 0x6775 #CJK UNIFIED IDEOGRAPH
+0xE8C7 0x67A8 #CJK UNIFIED IDEOGRAPH
+0xE8C8 0x679E #CJK UNIFIED IDEOGRAPH
+0xE8C9 0x67AD #CJK UNIFIED IDEOGRAPH
+0xE8CA 0x678B #CJK UNIFIED IDEOGRAPH
+0xE8CB 0x6777 #CJK UNIFIED IDEOGRAPH
+0xE8CC 0x677C #CJK UNIFIED IDEOGRAPH
+0xE8CD 0x67F0 #CJK UNIFIED IDEOGRAPH
+0xE8CE 0x6809 #CJK UNIFIED IDEOGRAPH
+0xE8CF 0x67D8 #CJK UNIFIED IDEOGRAPH
+0xE8D0 0x680A #CJK UNIFIED IDEOGRAPH
+0xE8D1 0x67E9 #CJK UNIFIED IDEOGRAPH
+0xE8D2 0x67B0 #CJK UNIFIED IDEOGRAPH
+0xE8D3 0x680C #CJK UNIFIED IDEOGRAPH
+0xE8D4 0x67D9 #CJK UNIFIED IDEOGRAPH
+0xE8D5 0x67B5 #CJK UNIFIED IDEOGRAPH
+0xE8D6 0x67DA #CJK UNIFIED IDEOGRAPH
+0xE8D7 0x67B3 #CJK UNIFIED IDEOGRAPH
+0xE8D8 0x67DD #CJK UNIFIED IDEOGRAPH
+0xE8D9 0x6800 #CJK UNIFIED IDEOGRAPH
+0xE8DA 0x67C3 #CJK UNIFIED IDEOGRAPH
+0xE8DB 0x67B8 #CJK UNIFIED IDEOGRAPH
+0xE8DC 0x67E2 #CJK UNIFIED IDEOGRAPH
+0xE8DD 0x680E #CJK UNIFIED IDEOGRAPH
+0xE8DE 0x67C1 #CJK UNIFIED IDEOGRAPH
+0xE8DF 0x67FD #CJK UNIFIED IDEOGRAPH
+0xE8E0 0x6832 #CJK UNIFIED IDEOGRAPH
+0xE8E1 0x6833 #CJK UNIFIED IDEOGRAPH
+0xE8E2 0x6860 #CJK UNIFIED IDEOGRAPH
+0xE8E3 0x6861 #CJK UNIFIED IDEOGRAPH
+0xE8E4 0x684E #CJK UNIFIED IDEOGRAPH
+0xE8E5 0x6862 #CJK UNIFIED IDEOGRAPH
+0xE8E6 0x6844 #CJK UNIFIED IDEOGRAPH
+0xE8E7 0x6864 #CJK UNIFIED IDEOGRAPH
+0xE8E8 0x6883 #CJK UNIFIED IDEOGRAPH
+0xE8E9 0x681D #CJK UNIFIED IDEOGRAPH
+0xE8EA 0x6855 #CJK UNIFIED IDEOGRAPH
+0xE8EB 0x6866 #CJK UNIFIED IDEOGRAPH
+0xE8EC 0x6841 #CJK UNIFIED IDEOGRAPH
+0xE8ED 0x6867 #CJK UNIFIED IDEOGRAPH
+0xE8EE 0x6840 #CJK UNIFIED IDEOGRAPH
+0xE8EF 0x683E #CJK UNIFIED IDEOGRAPH
+0xE8F0 0x684A #CJK UNIFIED IDEOGRAPH
+0xE8F1 0x6849 #CJK UNIFIED IDEOGRAPH
+0xE8F2 0x6829 #CJK UNIFIED IDEOGRAPH
+0xE8F3 0x68B5 #CJK UNIFIED IDEOGRAPH
+0xE8F4 0x688F #CJK UNIFIED IDEOGRAPH
+0xE8F5 0x6874 #CJK UNIFIED IDEOGRAPH
+0xE8F6 0x6877 #CJK UNIFIED IDEOGRAPH
+0xE8F7 0x6893 #CJK UNIFIED IDEOGRAPH
+0xE8F8 0x686B #CJK UNIFIED IDEOGRAPH
+0xE8F9 0x68C2 #CJK UNIFIED IDEOGRAPH
+0xE8FA 0x696E #CJK UNIFIED IDEOGRAPH
+0xE8FB 0x68FC #CJK UNIFIED IDEOGRAPH
+0xE8FC 0x691F #CJK UNIFIED IDEOGRAPH
+0xE8FD 0x6920 #CJK UNIFIED IDEOGRAPH
+0xE8FE 0x68F9 #CJK UNIFIED IDEOGRAPH
+0xE940 0x9527 #CJK UNIFIED IDEOGRAPH
+0xE941 0x9533 #CJK UNIFIED IDEOGRAPH
+0xE942 0x953D #CJK UNIFIED IDEOGRAPH
+0xE943 0x9543 #CJK UNIFIED IDEOGRAPH
+0xE944 0x9548 #CJK UNIFIED IDEOGRAPH
+0xE945 0x954B #CJK UNIFIED IDEOGRAPH
+0xE946 0x9555 #CJK UNIFIED IDEOGRAPH
+0xE947 0x955A #CJK UNIFIED IDEOGRAPH
+0xE948 0x9560 #CJK UNIFIED IDEOGRAPH
+0xE949 0x956E #CJK UNIFIED IDEOGRAPH
+0xE94A 0x9574 #CJK UNIFIED IDEOGRAPH
+0xE94B 0x9575 #CJK UNIFIED IDEOGRAPH
+0xE94C 0x9577 #CJK UNIFIED IDEOGRAPH
+0xE94D 0x9578 #CJK UNIFIED IDEOGRAPH
+0xE94E 0x9579 #CJK UNIFIED IDEOGRAPH
+0xE94F 0x957A #CJK UNIFIED IDEOGRAPH
+0xE950 0x957B #CJK UNIFIED IDEOGRAPH
+0xE951 0x957C #CJK UNIFIED IDEOGRAPH
+0xE952 0x957D #CJK UNIFIED IDEOGRAPH
+0xE953 0x957E #CJK UNIFIED IDEOGRAPH
+0xE954 0x9580 #CJK UNIFIED IDEOGRAPH
+0xE955 0x9581 #CJK UNIFIED IDEOGRAPH
+0xE956 0x9582 #CJK UNIFIED IDEOGRAPH
+0xE957 0x9583 #CJK UNIFIED IDEOGRAPH
+0xE958 0x9584 #CJK UNIFIED IDEOGRAPH
+0xE959 0x9585 #CJK UNIFIED IDEOGRAPH
+0xE95A 0x9586 #CJK UNIFIED IDEOGRAPH
+0xE95B 0x9587 #CJK UNIFIED IDEOGRAPH
+0xE95C 0x9588 #CJK UNIFIED IDEOGRAPH
+0xE95D 0x9589 #CJK UNIFIED IDEOGRAPH
+0xE95E 0x958A #CJK UNIFIED IDEOGRAPH
+0xE95F 0x958B #CJK UNIFIED IDEOGRAPH
+0xE960 0x958C #CJK UNIFIED IDEOGRAPH
+0xE961 0x958D #CJK UNIFIED IDEOGRAPH
+0xE962 0x958E #CJK UNIFIED IDEOGRAPH
+0xE963 0x958F #CJK UNIFIED IDEOGRAPH
+0xE964 0x9590 #CJK UNIFIED IDEOGRAPH
+0xE965 0x9591 #CJK UNIFIED IDEOGRAPH
+0xE966 0x9592 #CJK UNIFIED IDEOGRAPH
+0xE967 0x9593 #CJK UNIFIED IDEOGRAPH
+0xE968 0x9594 #CJK UNIFIED IDEOGRAPH
+0xE969 0x9595 #CJK UNIFIED IDEOGRAPH
+0xE96A 0x9596 #CJK UNIFIED IDEOGRAPH
+0xE96B 0x9597 #CJK UNIFIED IDEOGRAPH
+0xE96C 0x9598 #CJK UNIFIED IDEOGRAPH
+0xE96D 0x9599 #CJK UNIFIED IDEOGRAPH
+0xE96E 0x959A #CJK UNIFIED IDEOGRAPH
+0xE96F 0x959B #CJK UNIFIED IDEOGRAPH
+0xE970 0x959C #CJK UNIFIED IDEOGRAPH
+0xE971 0x959D #CJK UNIFIED IDEOGRAPH
+0xE972 0x959E #CJK UNIFIED IDEOGRAPH
+0xE973 0x959F #CJK UNIFIED IDEOGRAPH
+0xE974 0x95A0 #CJK UNIFIED IDEOGRAPH
+0xE975 0x95A1 #CJK UNIFIED IDEOGRAPH
+0xE976 0x95A2 #CJK UNIFIED IDEOGRAPH
+0xE977 0x95A3 #CJK UNIFIED IDEOGRAPH
+0xE978 0x95A4 #CJK UNIFIED IDEOGRAPH
+0xE979 0x95A5 #CJK UNIFIED IDEOGRAPH
+0xE97A 0x95A6 #CJK UNIFIED IDEOGRAPH
+0xE97B 0x95A7 #CJK UNIFIED IDEOGRAPH
+0xE97C 0x95A8 #CJK UNIFIED IDEOGRAPH
+0xE97D 0x95A9 #CJK UNIFIED IDEOGRAPH
+0xE97E 0x95AA #CJK UNIFIED IDEOGRAPH
+0xE980 0x95AB #CJK UNIFIED IDEOGRAPH
+0xE981 0x95AC #CJK UNIFIED IDEOGRAPH
+0xE982 0x95AD #CJK UNIFIED IDEOGRAPH
+0xE983 0x95AE #CJK UNIFIED IDEOGRAPH
+0xE984 0x95AF #CJK UNIFIED IDEOGRAPH
+0xE985 0x95B0 #CJK UNIFIED IDEOGRAPH
+0xE986 0x95B1 #CJK UNIFIED IDEOGRAPH
+0xE987 0x95B2 #CJK UNIFIED IDEOGRAPH
+0xE988 0x95B3 #CJK UNIFIED IDEOGRAPH
+0xE989 0x95B4 #CJK UNIFIED IDEOGRAPH
+0xE98A 0x95B5 #CJK UNIFIED IDEOGRAPH
+0xE98B 0x95B6 #CJK UNIFIED IDEOGRAPH
+0xE98C 0x95B7 #CJK UNIFIED IDEOGRAPH
+0xE98D 0x95B8 #CJK UNIFIED IDEOGRAPH
+0xE98E 0x95B9 #CJK UNIFIED IDEOGRAPH
+0xE98F 0x95BA #CJK UNIFIED IDEOGRAPH
+0xE990 0x95BB #CJK UNIFIED IDEOGRAPH
+0xE991 0x95BC #CJK UNIFIED IDEOGRAPH
+0xE992 0x95BD #CJK UNIFIED IDEOGRAPH
+0xE993 0x95BE #CJK UNIFIED IDEOGRAPH
+0xE994 0x95BF #CJK UNIFIED IDEOGRAPH
+0xE995 0x95C0 #CJK UNIFIED IDEOGRAPH
+0xE996 0x95C1 #CJK UNIFIED IDEOGRAPH
+0xE997 0x95C2 #CJK UNIFIED IDEOGRAPH
+0xE998 0x95C3 #CJK UNIFIED IDEOGRAPH
+0xE999 0x95C4 #CJK UNIFIED IDEOGRAPH
+0xE99A 0x95C5 #CJK UNIFIED IDEOGRAPH
+0xE99B 0x95C6 #CJK UNIFIED IDEOGRAPH
+0xE99C 0x95C7 #CJK UNIFIED IDEOGRAPH
+0xE99D 0x95C8 #CJK UNIFIED IDEOGRAPH
+0xE99E 0x95C9 #CJK UNIFIED IDEOGRAPH
+0xE99F 0x95CA #CJK UNIFIED IDEOGRAPH
+0xE9A0 0x95CB #CJK UNIFIED IDEOGRAPH
+0xE9A1 0x6924 #CJK UNIFIED IDEOGRAPH
+0xE9A2 0x68F0 #CJK UNIFIED IDEOGRAPH
+0xE9A3 0x690B #CJK UNIFIED IDEOGRAPH
+0xE9A4 0x6901 #CJK UNIFIED IDEOGRAPH
+0xE9A5 0x6957 #CJK UNIFIED IDEOGRAPH
+0xE9A6 0x68E3 #CJK UNIFIED IDEOGRAPH
+0xE9A7 0x6910 #CJK UNIFIED IDEOGRAPH
+0xE9A8 0x6971 #CJK UNIFIED IDEOGRAPH
+0xE9A9 0x6939 #CJK UNIFIED IDEOGRAPH
+0xE9AA 0x6960 #CJK UNIFIED IDEOGRAPH
+0xE9AB 0x6942 #CJK UNIFIED IDEOGRAPH
+0xE9AC 0x695D #CJK UNIFIED IDEOGRAPH
+0xE9AD 0x6984 #CJK UNIFIED IDEOGRAPH
+0xE9AE 0x696B #CJK UNIFIED IDEOGRAPH
+0xE9AF 0x6980 #CJK UNIFIED IDEOGRAPH
+0xE9B0 0x6998 #CJK UNIFIED IDEOGRAPH
+0xE9B1 0x6978 #CJK UNIFIED IDEOGRAPH
+0xE9B2 0x6934 #CJK UNIFIED IDEOGRAPH
+0xE9B3 0x69CC #CJK UNIFIED IDEOGRAPH
+0xE9B4 0x6987 #CJK UNIFIED IDEOGRAPH
+0xE9B5 0x6988 #CJK UNIFIED IDEOGRAPH
+0xE9B6 0x69CE #CJK UNIFIED IDEOGRAPH
+0xE9B7 0x6989 #CJK UNIFIED IDEOGRAPH
+0xE9B8 0x6966 #CJK UNIFIED IDEOGRAPH
+0xE9B9 0x6963 #CJK UNIFIED IDEOGRAPH
+0xE9BA 0x6979 #CJK UNIFIED IDEOGRAPH
+0xE9BB 0x699B #CJK UNIFIED IDEOGRAPH
+0xE9BC 0x69A7 #CJK UNIFIED IDEOGRAPH
+0xE9BD 0x69BB #CJK UNIFIED IDEOGRAPH
+0xE9BE 0x69AB #CJK UNIFIED IDEOGRAPH
+0xE9BF 0x69AD #CJK UNIFIED IDEOGRAPH
+0xE9C0 0x69D4 #CJK UNIFIED IDEOGRAPH
+0xE9C1 0x69B1 #CJK UNIFIED IDEOGRAPH
+0xE9C2 0x69C1 #CJK UNIFIED IDEOGRAPH
+0xE9C3 0x69CA #CJK UNIFIED IDEOGRAPH
+0xE9C4 0x69DF #CJK UNIFIED IDEOGRAPH
+0xE9C5 0x6995 #CJK UNIFIED IDEOGRAPH
+0xE9C6 0x69E0 #CJK UNIFIED IDEOGRAPH
+0xE9C7 0x698D #CJK UNIFIED IDEOGRAPH
+0xE9C8 0x69FF #CJK UNIFIED IDEOGRAPH
+0xE9C9 0x6A2F #CJK UNIFIED IDEOGRAPH
+0xE9CA 0x69ED #CJK UNIFIED IDEOGRAPH
+0xE9CB 0x6A17 #CJK UNIFIED IDEOGRAPH
+0xE9CC 0x6A18 #CJK UNIFIED IDEOGRAPH
+0xE9CD 0x6A65 #CJK UNIFIED IDEOGRAPH
+0xE9CE 0x69F2 #CJK UNIFIED IDEOGRAPH
+0xE9CF 0x6A44 #CJK UNIFIED IDEOGRAPH
+0xE9D0 0x6A3E #CJK UNIFIED IDEOGRAPH
+0xE9D1 0x6AA0 #CJK UNIFIED IDEOGRAPH
+0xE9D2 0x6A50 #CJK UNIFIED IDEOGRAPH
+0xE9D3 0x6A5B #CJK UNIFIED IDEOGRAPH
+0xE9D4 0x6A35 #CJK UNIFIED IDEOGRAPH
+0xE9D5 0x6A8E #CJK UNIFIED IDEOGRAPH
+0xE9D6 0x6A79 #CJK UNIFIED IDEOGRAPH
+0xE9D7 0x6A3D #CJK UNIFIED IDEOGRAPH
+0xE9D8 0x6A28 #CJK UNIFIED IDEOGRAPH
+0xE9D9 0x6A58 #CJK UNIFIED IDEOGRAPH
+0xE9DA 0x6A7C #CJK UNIFIED IDEOGRAPH
+0xE9DB 0x6A91 #CJK UNIFIED IDEOGRAPH
+0xE9DC 0x6A90 #CJK UNIFIED IDEOGRAPH
+0xE9DD 0x6AA9 #CJK UNIFIED IDEOGRAPH
+0xE9DE 0x6A97 #CJK UNIFIED IDEOGRAPH
+0xE9DF 0x6AAB #CJK UNIFIED IDEOGRAPH
+0xE9E0 0x7337 #CJK UNIFIED IDEOGRAPH
+0xE9E1 0x7352 #CJK UNIFIED IDEOGRAPH
+0xE9E2 0x6B81 #CJK UNIFIED IDEOGRAPH
+0xE9E3 0x6B82 #CJK UNIFIED IDEOGRAPH
+0xE9E4 0x6B87 #CJK UNIFIED IDEOGRAPH
+0xE9E5 0x6B84 #CJK UNIFIED IDEOGRAPH
+0xE9E6 0x6B92 #CJK UNIFIED IDEOGRAPH
+0xE9E7 0x6B93 #CJK UNIFIED IDEOGRAPH
+0xE9E8 0x6B8D #CJK UNIFIED IDEOGRAPH
+0xE9E9 0x6B9A #CJK UNIFIED IDEOGRAPH
+0xE9EA 0x6B9B #CJK UNIFIED IDEOGRAPH
+0xE9EB 0x6BA1 #CJK UNIFIED IDEOGRAPH
+0xE9EC 0x6BAA #CJK UNIFIED IDEOGRAPH
+0xE9ED 0x8F6B #CJK UNIFIED IDEOGRAPH
+0xE9EE 0x8F6D #CJK UNIFIED IDEOGRAPH
+0xE9EF 0x8F71 #CJK UNIFIED IDEOGRAPH
+0xE9F0 0x8F72 #CJK UNIFIED IDEOGRAPH
+0xE9F1 0x8F73 #CJK UNIFIED IDEOGRAPH
+0xE9F2 0x8F75 #CJK UNIFIED IDEOGRAPH
+0xE9F3 0x8F76 #CJK UNIFIED IDEOGRAPH
+0xE9F4 0x8F78 #CJK UNIFIED IDEOGRAPH
+0xE9F5 0x8F77 #CJK UNIFIED IDEOGRAPH
+0xE9F6 0x8F79 #CJK UNIFIED IDEOGRAPH
+0xE9F7 0x8F7A #CJK UNIFIED IDEOGRAPH
+0xE9F8 0x8F7C #CJK UNIFIED IDEOGRAPH
+0xE9F9 0x8F7E #CJK UNIFIED IDEOGRAPH
+0xE9FA 0x8F81 #CJK UNIFIED IDEOGRAPH
+0xE9FB 0x8F82 #CJK UNIFIED IDEOGRAPH
+0xE9FC 0x8F84 #CJK UNIFIED IDEOGRAPH
+0xE9FD 0x8F87 #CJK UNIFIED IDEOGRAPH
+0xE9FE 0x8F8B #CJK UNIFIED IDEOGRAPH
+0xEA40 0x95CC #CJK UNIFIED IDEOGRAPH
+0xEA41 0x95CD #CJK UNIFIED IDEOGRAPH
+0xEA42 0x95CE #CJK UNIFIED IDEOGRAPH
+0xEA43 0x95CF #CJK UNIFIED IDEOGRAPH
+0xEA44 0x95D0 #CJK UNIFIED IDEOGRAPH
+0xEA45 0x95D1 #CJK UNIFIED IDEOGRAPH
+0xEA46 0x95D2 #CJK UNIFIED IDEOGRAPH
+0xEA47 0x95D3 #CJK UNIFIED IDEOGRAPH
+0xEA48 0x95D4 #CJK UNIFIED IDEOGRAPH
+0xEA49 0x95D5 #CJK UNIFIED IDEOGRAPH
+0xEA4A 0x95D6 #CJK UNIFIED IDEOGRAPH
+0xEA4B 0x95D7 #CJK UNIFIED IDEOGRAPH
+0xEA4C 0x95D8 #CJK UNIFIED IDEOGRAPH
+0xEA4D 0x95D9 #CJK UNIFIED IDEOGRAPH
+0xEA4E 0x95DA #CJK UNIFIED IDEOGRAPH
+0xEA4F 0x95DB #CJK UNIFIED IDEOGRAPH
+0xEA50 0x95DC #CJK UNIFIED IDEOGRAPH
+0xEA51 0x95DD #CJK UNIFIED IDEOGRAPH
+0xEA52 0x95DE #CJK UNIFIED IDEOGRAPH
+0xEA53 0x95DF #CJK UNIFIED IDEOGRAPH
+0xEA54 0x95E0 #CJK UNIFIED IDEOGRAPH
+0xEA55 0x95E1 #CJK UNIFIED IDEOGRAPH
+0xEA56 0x95E2 #CJK UNIFIED IDEOGRAPH
+0xEA57 0x95E3 #CJK UNIFIED IDEOGRAPH
+0xEA58 0x95E4 #CJK UNIFIED IDEOGRAPH
+0xEA59 0x95E5 #CJK UNIFIED IDEOGRAPH
+0xEA5A 0x95E6 #CJK UNIFIED IDEOGRAPH
+0xEA5B 0x95E7 #CJK UNIFIED IDEOGRAPH
+0xEA5C 0x95EC #CJK UNIFIED IDEOGRAPH
+0xEA5D 0x95FF #CJK UNIFIED IDEOGRAPH
+0xEA5E 0x9607 #CJK UNIFIED IDEOGRAPH
+0xEA5F 0x9613 #CJK UNIFIED IDEOGRAPH
+0xEA60 0x9618 #CJK UNIFIED IDEOGRAPH
+0xEA61 0x961B #CJK UNIFIED IDEOGRAPH
+0xEA62 0x961E #CJK UNIFIED IDEOGRAPH
+0xEA63 0x9620 #CJK UNIFIED IDEOGRAPH
+0xEA64 0x9623 #CJK UNIFIED IDEOGRAPH
+0xEA65 0x9624 #CJK UNIFIED IDEOGRAPH
+0xEA66 0x9625 #CJK UNIFIED IDEOGRAPH
+0xEA67 0x9626 #CJK UNIFIED IDEOGRAPH
+0xEA68 0x9627 #CJK UNIFIED IDEOGRAPH
+0xEA69 0x9628 #CJK UNIFIED IDEOGRAPH
+0xEA6A 0x9629 #CJK UNIFIED IDEOGRAPH
+0xEA6B 0x962B #CJK UNIFIED IDEOGRAPH
+0xEA6C 0x962C #CJK UNIFIED IDEOGRAPH
+0xEA6D 0x962D #CJK UNIFIED IDEOGRAPH
+0xEA6E 0x962F #CJK UNIFIED IDEOGRAPH
+0xEA6F 0x9630 #CJK UNIFIED IDEOGRAPH
+0xEA70 0x9637 #CJK UNIFIED IDEOGRAPH
+0xEA71 0x9638 #CJK UNIFIED IDEOGRAPH
+0xEA72 0x9639 #CJK UNIFIED IDEOGRAPH
+0xEA73 0x963A #CJK UNIFIED IDEOGRAPH
+0xEA74 0x963E #CJK UNIFIED IDEOGRAPH
+0xEA75 0x9641 #CJK UNIFIED IDEOGRAPH
+0xEA76 0x9643 #CJK UNIFIED IDEOGRAPH
+0xEA77 0x964A #CJK UNIFIED IDEOGRAPH
+0xEA78 0x964E #CJK UNIFIED IDEOGRAPH
+0xEA79 0x964F #CJK UNIFIED IDEOGRAPH
+0xEA7A 0x9651 #CJK UNIFIED IDEOGRAPH
+0xEA7B 0x9652 #CJK UNIFIED IDEOGRAPH
+0xEA7C 0x9653 #CJK UNIFIED IDEOGRAPH
+0xEA7D 0x9656 #CJK UNIFIED IDEOGRAPH
+0xEA7E 0x9657 #CJK UNIFIED IDEOGRAPH
+0xEA80 0x9658 #CJK UNIFIED IDEOGRAPH
+0xEA81 0x9659 #CJK UNIFIED IDEOGRAPH
+0xEA82 0x965A #CJK UNIFIED IDEOGRAPH
+0xEA83 0x965C #CJK UNIFIED IDEOGRAPH
+0xEA84 0x965D #CJK UNIFIED IDEOGRAPH
+0xEA85 0x965E #CJK UNIFIED IDEOGRAPH
+0xEA86 0x9660 #CJK UNIFIED IDEOGRAPH
+0xEA87 0x9663 #CJK UNIFIED IDEOGRAPH
+0xEA88 0x9665 #CJK UNIFIED IDEOGRAPH
+0xEA89 0x9666 #CJK UNIFIED IDEOGRAPH
+0xEA8A 0x966B #CJK UNIFIED IDEOGRAPH
+0xEA8B 0x966D #CJK UNIFIED IDEOGRAPH
+0xEA8C 0x966E #CJK UNIFIED IDEOGRAPH
+0xEA8D 0x966F #CJK UNIFIED IDEOGRAPH
+0xEA8E 0x9670 #CJK UNIFIED IDEOGRAPH
+0xEA8F 0x9671 #CJK UNIFIED IDEOGRAPH
+0xEA90 0x9673 #CJK UNIFIED IDEOGRAPH
+0xEA91 0x9678 #CJK UNIFIED IDEOGRAPH
+0xEA92 0x9679 #CJK UNIFIED IDEOGRAPH
+0xEA93 0x967A #CJK UNIFIED IDEOGRAPH
+0xEA94 0x967B #CJK UNIFIED IDEOGRAPH
+0xEA95 0x967C #CJK UNIFIED IDEOGRAPH
+0xEA96 0x967D #CJK UNIFIED IDEOGRAPH
+0xEA97 0x967E #CJK UNIFIED IDEOGRAPH
+0xEA98 0x967F #CJK UNIFIED IDEOGRAPH
+0xEA99 0x9680 #CJK UNIFIED IDEOGRAPH
+0xEA9A 0x9681 #CJK UNIFIED IDEOGRAPH
+0xEA9B 0x9682 #CJK UNIFIED IDEOGRAPH
+0xEA9C 0x9683 #CJK UNIFIED IDEOGRAPH
+0xEA9D 0x9684 #CJK UNIFIED IDEOGRAPH
+0xEA9E 0x9687 #CJK UNIFIED IDEOGRAPH
+0xEA9F 0x9689 #CJK UNIFIED IDEOGRAPH
+0xEAA0 0x968A #CJK UNIFIED IDEOGRAPH
+0xEAA1 0x8F8D #CJK UNIFIED IDEOGRAPH
+0xEAA2 0x8F8E #CJK UNIFIED IDEOGRAPH
+0xEAA3 0x8F8F #CJK UNIFIED IDEOGRAPH
+0xEAA4 0x8F98 #CJK UNIFIED IDEOGRAPH
+0xEAA5 0x8F9A #CJK UNIFIED IDEOGRAPH
+0xEAA6 0x8ECE #CJK UNIFIED IDEOGRAPH
+0xEAA7 0x620B #CJK UNIFIED IDEOGRAPH
+0xEAA8 0x6217 #CJK UNIFIED IDEOGRAPH
+0xEAA9 0x621B #CJK UNIFIED IDEOGRAPH
+0xEAAA 0x621F #CJK UNIFIED IDEOGRAPH
+0xEAAB 0x6222 #CJK UNIFIED IDEOGRAPH
+0xEAAC 0x6221 #CJK UNIFIED IDEOGRAPH
+0xEAAD 0x6225 #CJK UNIFIED IDEOGRAPH
+0xEAAE 0x6224 #CJK UNIFIED IDEOGRAPH
+0xEAAF 0x622C #CJK UNIFIED IDEOGRAPH
+0xEAB0 0x81E7 #CJK UNIFIED IDEOGRAPH
+0xEAB1 0x74EF #CJK UNIFIED IDEOGRAPH
+0xEAB2 0x74F4 #CJK UNIFIED IDEOGRAPH
+0xEAB3 0x74FF #CJK UNIFIED IDEOGRAPH
+0xEAB4 0x750F #CJK UNIFIED IDEOGRAPH
+0xEAB5 0x7511 #CJK UNIFIED IDEOGRAPH
+0xEAB6 0x7513 #CJK UNIFIED IDEOGRAPH
+0xEAB7 0x6534 #CJK UNIFIED IDEOGRAPH
+0xEAB8 0x65EE #CJK UNIFIED IDEOGRAPH
+0xEAB9 0x65EF #CJK UNIFIED IDEOGRAPH
+0xEABA 0x65F0 #CJK UNIFIED IDEOGRAPH
+0xEABB 0x660A #CJK UNIFIED IDEOGRAPH
+0xEABC 0x6619 #CJK UNIFIED IDEOGRAPH
+0xEABD 0x6772 #CJK UNIFIED IDEOGRAPH
+0xEABE 0x6603 #CJK UNIFIED IDEOGRAPH
+0xEABF 0x6615 #CJK UNIFIED IDEOGRAPH
+0xEAC0 0x6600 #CJK UNIFIED IDEOGRAPH
+0xEAC1 0x7085 #CJK UNIFIED IDEOGRAPH
+0xEAC2 0x66F7 #CJK UNIFIED IDEOGRAPH
+0xEAC3 0x661D #CJK UNIFIED IDEOGRAPH
+0xEAC4 0x6634 #CJK UNIFIED IDEOGRAPH
+0xEAC5 0x6631 #CJK UNIFIED IDEOGRAPH
+0xEAC6 0x6636 #CJK UNIFIED IDEOGRAPH
+0xEAC7 0x6635 #CJK UNIFIED IDEOGRAPH
+0xEAC8 0x8006 #CJK UNIFIED IDEOGRAPH
+0xEAC9 0x665F #CJK UNIFIED IDEOGRAPH
+0xEACA 0x6654 #CJK UNIFIED IDEOGRAPH
+0xEACB 0x6641 #CJK UNIFIED IDEOGRAPH
+0xEACC 0x664F #CJK UNIFIED IDEOGRAPH
+0xEACD 0x6656 #CJK UNIFIED IDEOGRAPH
+0xEACE 0x6661 #CJK UNIFIED IDEOGRAPH
+0xEACF 0x6657 #CJK UNIFIED IDEOGRAPH
+0xEAD0 0x6677 #CJK UNIFIED IDEOGRAPH
+0xEAD1 0x6684 #CJK UNIFIED IDEOGRAPH
+0xEAD2 0x668C #CJK UNIFIED IDEOGRAPH
+0xEAD3 0x66A7 #CJK UNIFIED IDEOGRAPH
+0xEAD4 0x669D #CJK UNIFIED IDEOGRAPH
+0xEAD5 0x66BE #CJK UNIFIED IDEOGRAPH
+0xEAD6 0x66DB #CJK UNIFIED IDEOGRAPH
+0xEAD7 0x66DC #CJK UNIFIED IDEOGRAPH
+0xEAD8 0x66E6 #CJK UNIFIED IDEOGRAPH
+0xEAD9 0x66E9 #CJK UNIFIED IDEOGRAPH
+0xEADA 0x8D32 #CJK UNIFIED IDEOGRAPH
+0xEADB 0x8D33 #CJK UNIFIED IDEOGRAPH
+0xEADC 0x8D36 #CJK UNIFIED IDEOGRAPH
+0xEADD 0x8D3B #CJK UNIFIED IDEOGRAPH
+0xEADE 0x8D3D #CJK UNIFIED IDEOGRAPH
+0xEADF 0x8D40 #CJK UNIFIED IDEOGRAPH
+0xEAE0 0x8D45 #CJK UNIFIED IDEOGRAPH
+0xEAE1 0x8D46 #CJK UNIFIED IDEOGRAPH
+0xEAE2 0x8D48 #CJK UNIFIED IDEOGRAPH
+0xEAE3 0x8D49 #CJK UNIFIED IDEOGRAPH
+0xEAE4 0x8D47 #CJK UNIFIED IDEOGRAPH
+0xEAE5 0x8D4D #CJK UNIFIED IDEOGRAPH
+0xEAE6 0x8D55 #CJK UNIFIED IDEOGRAPH
+0xEAE7 0x8D59 #CJK UNIFIED IDEOGRAPH
+0xEAE8 0x89C7 #CJK UNIFIED IDEOGRAPH
+0xEAE9 0x89CA #CJK UNIFIED IDEOGRAPH
+0xEAEA 0x89CB #CJK UNIFIED IDEOGRAPH
+0xEAEB 0x89CC #CJK UNIFIED IDEOGRAPH
+0xEAEC 0x89CE #CJK UNIFIED IDEOGRAPH
+0xEAED 0x89CF #CJK UNIFIED IDEOGRAPH
+0xEAEE 0x89D0 #CJK UNIFIED IDEOGRAPH
+0xEAEF 0x89D1 #CJK UNIFIED IDEOGRAPH
+0xEAF0 0x726E #CJK UNIFIED IDEOGRAPH
+0xEAF1 0x729F #CJK UNIFIED IDEOGRAPH
+0xEAF2 0x725D #CJK UNIFIED IDEOGRAPH
+0xEAF3 0x7266 #CJK UNIFIED IDEOGRAPH
+0xEAF4 0x726F #CJK UNIFIED IDEOGRAPH
+0xEAF5 0x727E #CJK UNIFIED IDEOGRAPH
+0xEAF6 0x727F #CJK UNIFIED IDEOGRAPH
+0xEAF7 0x7284 #CJK UNIFIED IDEOGRAPH
+0xEAF8 0x728B #CJK UNIFIED IDEOGRAPH
+0xEAF9 0x728D #CJK UNIFIED IDEOGRAPH
+0xEAFA 0x728F #CJK UNIFIED IDEOGRAPH
+0xEAFB 0x7292 #CJK UNIFIED IDEOGRAPH
+0xEAFC 0x6308 #CJK UNIFIED IDEOGRAPH
+0xEAFD 0x6332 #CJK UNIFIED IDEOGRAPH
+0xEAFE 0x63B0 #CJK UNIFIED IDEOGRAPH
+0xEB40 0x968C #CJK UNIFIED IDEOGRAPH
+0xEB41 0x968E #CJK UNIFIED IDEOGRAPH
+0xEB42 0x9691 #CJK UNIFIED IDEOGRAPH
+0xEB43 0x9692 #CJK UNIFIED IDEOGRAPH
+0xEB44 0x9693 #CJK UNIFIED IDEOGRAPH
+0xEB45 0x9695 #CJK UNIFIED IDEOGRAPH
+0xEB46 0x9696 #CJK UNIFIED IDEOGRAPH
+0xEB47 0x969A #CJK UNIFIED IDEOGRAPH
+0xEB48 0x969B #CJK UNIFIED IDEOGRAPH
+0xEB49 0x969D #CJK UNIFIED IDEOGRAPH
+0xEB4A 0x969E #CJK UNIFIED IDEOGRAPH
+0xEB4B 0x969F #CJK UNIFIED IDEOGRAPH
+0xEB4C 0x96A0 #CJK UNIFIED IDEOGRAPH
+0xEB4D 0x96A1 #CJK UNIFIED IDEOGRAPH
+0xEB4E 0x96A2 #CJK UNIFIED IDEOGRAPH
+0xEB4F 0x96A3 #CJK UNIFIED IDEOGRAPH
+0xEB50 0x96A4 #CJK UNIFIED IDEOGRAPH
+0xEB51 0x96A5 #CJK UNIFIED IDEOGRAPH
+0xEB52 0x96A6 #CJK UNIFIED IDEOGRAPH
+0xEB53 0x96A8 #CJK UNIFIED IDEOGRAPH
+0xEB54 0x96A9 #CJK UNIFIED IDEOGRAPH
+0xEB55 0x96AA #CJK UNIFIED IDEOGRAPH
+0xEB56 0x96AB #CJK UNIFIED IDEOGRAPH
+0xEB57 0x96AC #CJK UNIFIED IDEOGRAPH
+0xEB58 0x96AD #CJK UNIFIED IDEOGRAPH
+0xEB59 0x96AE #CJK UNIFIED IDEOGRAPH
+0xEB5A 0x96AF #CJK UNIFIED IDEOGRAPH
+0xEB5B 0x96B1 #CJK UNIFIED IDEOGRAPH
+0xEB5C 0x96B2 #CJK UNIFIED IDEOGRAPH
+0xEB5D 0x96B4 #CJK UNIFIED IDEOGRAPH
+0xEB5E 0x96B5 #CJK UNIFIED IDEOGRAPH
+0xEB5F 0x96B7 #CJK UNIFIED IDEOGRAPH
+0xEB60 0x96B8 #CJK UNIFIED IDEOGRAPH
+0xEB61 0x96BA #CJK UNIFIED IDEOGRAPH
+0xEB62 0x96BB #CJK UNIFIED IDEOGRAPH
+0xEB63 0x96BF #CJK UNIFIED IDEOGRAPH
+0xEB64 0x96C2 #CJK UNIFIED IDEOGRAPH
+0xEB65 0x96C3 #CJK UNIFIED IDEOGRAPH
+0xEB66 0x96C8 #CJK UNIFIED IDEOGRAPH
+0xEB67 0x96CA #CJK UNIFIED IDEOGRAPH
+0xEB68 0x96CB #CJK UNIFIED IDEOGRAPH
+0xEB69 0x96D0 #CJK UNIFIED IDEOGRAPH
+0xEB6A 0x96D1 #CJK UNIFIED IDEOGRAPH
+0xEB6B 0x96D3 #CJK UNIFIED IDEOGRAPH
+0xEB6C 0x96D4 #CJK UNIFIED IDEOGRAPH
+0xEB6D 0x96D6 #CJK UNIFIED IDEOGRAPH
+0xEB6E 0x96D7 #CJK UNIFIED IDEOGRAPH
+0xEB6F 0x96D8 #CJK UNIFIED IDEOGRAPH
+0xEB70 0x96D9 #CJK UNIFIED IDEOGRAPH
+0xEB71 0x96DA #CJK UNIFIED IDEOGRAPH
+0xEB72 0x96DB #CJK UNIFIED IDEOGRAPH
+0xEB73 0x96DC #CJK UNIFIED IDEOGRAPH
+0xEB74 0x96DD #CJK UNIFIED IDEOGRAPH
+0xEB75 0x96DE #CJK UNIFIED IDEOGRAPH
+0xEB76 0x96DF #CJK UNIFIED IDEOGRAPH
+0xEB77 0x96E1 #CJK UNIFIED IDEOGRAPH
+0xEB78 0x96E2 #CJK UNIFIED IDEOGRAPH
+0xEB79 0x96E3 #CJK UNIFIED IDEOGRAPH
+0xEB7A 0x96E4 #CJK UNIFIED IDEOGRAPH
+0xEB7B 0x96E5 #CJK UNIFIED IDEOGRAPH
+0xEB7C 0x96E6 #CJK UNIFIED IDEOGRAPH
+0xEB7D 0x96E7 #CJK UNIFIED IDEOGRAPH
+0xEB7E 0x96EB #CJK UNIFIED IDEOGRAPH
+0xEB80 0x96EC #CJK UNIFIED IDEOGRAPH
+0xEB81 0x96ED #CJK UNIFIED IDEOGRAPH
+0xEB82 0x96EE #CJK UNIFIED IDEOGRAPH
+0xEB83 0x96F0 #CJK UNIFIED IDEOGRAPH
+0xEB84 0x96F1 #CJK UNIFIED IDEOGRAPH
+0xEB85 0x96F2 #CJK UNIFIED IDEOGRAPH
+0xEB86 0x96F4 #CJK UNIFIED IDEOGRAPH
+0xEB87 0x96F5 #CJK UNIFIED IDEOGRAPH
+0xEB88 0x96F8 #CJK UNIFIED IDEOGRAPH
+0xEB89 0x96FA #CJK UNIFIED IDEOGRAPH
+0xEB8A 0x96FB #CJK UNIFIED IDEOGRAPH
+0xEB8B 0x96FC #CJK UNIFIED IDEOGRAPH
+0xEB8C 0x96FD #CJK UNIFIED IDEOGRAPH
+0xEB8D 0x96FF #CJK UNIFIED IDEOGRAPH
+0xEB8E 0x9702 #CJK UNIFIED IDEOGRAPH
+0xEB8F 0x9703 #CJK UNIFIED IDEOGRAPH
+0xEB90 0x9705 #CJK UNIFIED IDEOGRAPH
+0xEB91 0x970A #CJK UNIFIED IDEOGRAPH
+0xEB92 0x970B #CJK UNIFIED IDEOGRAPH
+0xEB93 0x970C #CJK UNIFIED IDEOGRAPH
+0xEB94 0x9710 #CJK UNIFIED IDEOGRAPH
+0xEB95 0x9711 #CJK UNIFIED IDEOGRAPH
+0xEB96 0x9712 #CJK UNIFIED IDEOGRAPH
+0xEB97 0x9714 #CJK UNIFIED IDEOGRAPH
+0xEB98 0x9715 #CJK UNIFIED IDEOGRAPH
+0xEB99 0x9717 #CJK UNIFIED IDEOGRAPH
+0xEB9A 0x9718 #CJK UNIFIED IDEOGRAPH
+0xEB9B 0x9719 #CJK UNIFIED IDEOGRAPH
+0xEB9C 0x971A #CJK UNIFIED IDEOGRAPH
+0xEB9D 0x971B #CJK UNIFIED IDEOGRAPH
+0xEB9E 0x971D #CJK UNIFIED IDEOGRAPH
+0xEB9F 0x971F #CJK UNIFIED IDEOGRAPH
+0xEBA0 0x9720 #CJK UNIFIED IDEOGRAPH
+0xEBA1 0x643F #CJK UNIFIED IDEOGRAPH
+0xEBA2 0x64D8 #CJK UNIFIED IDEOGRAPH
+0xEBA3 0x8004 #CJK UNIFIED IDEOGRAPH
+0xEBA4 0x6BEA #CJK UNIFIED IDEOGRAPH
+0xEBA5 0x6BF3 #CJK UNIFIED IDEOGRAPH
+0xEBA6 0x6BFD #CJK UNIFIED IDEOGRAPH
+0xEBA7 0x6BF5 #CJK UNIFIED IDEOGRAPH
+0xEBA8 0x6BF9 #CJK UNIFIED IDEOGRAPH
+0xEBA9 0x6C05 #CJK UNIFIED IDEOGRAPH
+0xEBAA 0x6C07 #CJK UNIFIED IDEOGRAPH
+0xEBAB 0x6C06 #CJK UNIFIED IDEOGRAPH
+0xEBAC 0x6C0D #CJK UNIFIED IDEOGRAPH
+0xEBAD 0x6C15 #CJK UNIFIED IDEOGRAPH
+0xEBAE 0x6C18 #CJK UNIFIED IDEOGRAPH
+0xEBAF 0x6C19 #CJK UNIFIED IDEOGRAPH
+0xEBB0 0x6C1A #CJK UNIFIED IDEOGRAPH
+0xEBB1 0x6C21 #CJK UNIFIED IDEOGRAPH
+0xEBB2 0x6C29 #CJK UNIFIED IDEOGRAPH
+0xEBB3 0x6C24 #CJK UNIFIED IDEOGRAPH
+0xEBB4 0x6C2A #CJK UNIFIED IDEOGRAPH
+0xEBB5 0x6C32 #CJK UNIFIED IDEOGRAPH
+0xEBB6 0x6535 #CJK UNIFIED IDEOGRAPH
+0xEBB7 0x6555 #CJK UNIFIED IDEOGRAPH
+0xEBB8 0x656B #CJK UNIFIED IDEOGRAPH
+0xEBB9 0x724D #CJK UNIFIED IDEOGRAPH
+0xEBBA 0x7252 #CJK UNIFIED IDEOGRAPH
+0xEBBB 0x7256 #CJK UNIFIED IDEOGRAPH
+0xEBBC 0x7230 #CJK UNIFIED IDEOGRAPH
+0xEBBD 0x8662 #CJK UNIFIED IDEOGRAPH
+0xEBBE 0x5216 #CJK UNIFIED IDEOGRAPH
+0xEBBF 0x809F #CJK UNIFIED IDEOGRAPH
+0xEBC0 0x809C #CJK UNIFIED IDEOGRAPH
+0xEBC1 0x8093 #CJK UNIFIED IDEOGRAPH
+0xEBC2 0x80BC #CJK UNIFIED IDEOGRAPH
+0xEBC3 0x670A #CJK UNIFIED IDEOGRAPH
+0xEBC4 0x80BD #CJK UNIFIED IDEOGRAPH
+0xEBC5 0x80B1 #CJK UNIFIED IDEOGRAPH
+0xEBC6 0x80AB #CJK UNIFIED IDEOGRAPH
+0xEBC7 0x80AD #CJK UNIFIED IDEOGRAPH
+0xEBC8 0x80B4 #CJK UNIFIED IDEOGRAPH
+0xEBC9 0x80B7 #CJK UNIFIED IDEOGRAPH
+0xEBCA 0x80E7 #CJK UNIFIED IDEOGRAPH
+0xEBCB 0x80E8 #CJK UNIFIED IDEOGRAPH
+0xEBCC 0x80E9 #CJK UNIFIED IDEOGRAPH
+0xEBCD 0x80EA #CJK UNIFIED IDEOGRAPH
+0xEBCE 0x80DB #CJK UNIFIED IDEOGRAPH
+0xEBCF 0x80C2 #CJK UNIFIED IDEOGRAPH
+0xEBD0 0x80C4 #CJK UNIFIED IDEOGRAPH
+0xEBD1 0x80D9 #CJK UNIFIED IDEOGRAPH
+0xEBD2 0x80CD #CJK UNIFIED IDEOGRAPH
+0xEBD3 0x80D7 #CJK UNIFIED IDEOGRAPH
+0xEBD4 0x6710 #CJK UNIFIED IDEOGRAPH
+0xEBD5 0x80DD #CJK UNIFIED IDEOGRAPH
+0xEBD6 0x80EB #CJK UNIFIED IDEOGRAPH
+0xEBD7 0x80F1 #CJK UNIFIED IDEOGRAPH
+0xEBD8 0x80F4 #CJK UNIFIED IDEOGRAPH
+0xEBD9 0x80ED #CJK UNIFIED IDEOGRAPH
+0xEBDA 0x810D #CJK UNIFIED IDEOGRAPH
+0xEBDB 0x810E #CJK UNIFIED IDEOGRAPH
+0xEBDC 0x80F2 #CJK UNIFIED IDEOGRAPH
+0xEBDD 0x80FC #CJK UNIFIED IDEOGRAPH
+0xEBDE 0x6715 #CJK UNIFIED IDEOGRAPH
+0xEBDF 0x8112 #CJK UNIFIED IDEOGRAPH
+0xEBE0 0x8C5A #CJK UNIFIED IDEOGRAPH
+0xEBE1 0x8136 #CJK UNIFIED IDEOGRAPH
+0xEBE2 0x811E #CJK UNIFIED IDEOGRAPH
+0xEBE3 0x812C #CJK UNIFIED IDEOGRAPH
+0xEBE4 0x8118 #CJK UNIFIED IDEOGRAPH
+0xEBE5 0x8132 #CJK UNIFIED IDEOGRAPH
+0xEBE6 0x8148 #CJK UNIFIED IDEOGRAPH
+0xEBE7 0x814C #CJK UNIFIED IDEOGRAPH
+0xEBE8 0x8153 #CJK UNIFIED IDEOGRAPH
+0xEBE9 0x8174 #CJK UNIFIED IDEOGRAPH
+0xEBEA 0x8159 #CJK UNIFIED IDEOGRAPH
+0xEBEB 0x815A #CJK UNIFIED IDEOGRAPH
+0xEBEC 0x8171 #CJK UNIFIED IDEOGRAPH
+0xEBED 0x8160 #CJK UNIFIED IDEOGRAPH
+0xEBEE 0x8169 #CJK UNIFIED IDEOGRAPH
+0xEBEF 0x817C #CJK UNIFIED IDEOGRAPH
+0xEBF0 0x817D #CJK UNIFIED IDEOGRAPH
+0xEBF1 0x816D #CJK UNIFIED IDEOGRAPH
+0xEBF2 0x8167 #CJK UNIFIED IDEOGRAPH
+0xEBF3 0x584D #CJK UNIFIED IDEOGRAPH
+0xEBF4 0x5AB5 #CJK UNIFIED IDEOGRAPH
+0xEBF5 0x8188 #CJK UNIFIED IDEOGRAPH
+0xEBF6 0x8182 #CJK UNIFIED IDEOGRAPH
+0xEBF7 0x8191 #CJK UNIFIED IDEOGRAPH
+0xEBF8 0x6ED5 #CJK UNIFIED IDEOGRAPH
+0xEBF9 0x81A3 #CJK UNIFIED IDEOGRAPH
+0xEBFA 0x81AA #CJK UNIFIED IDEOGRAPH
+0xEBFB 0x81CC #CJK UNIFIED IDEOGRAPH
+0xEBFC 0x6726 #CJK UNIFIED IDEOGRAPH
+0xEBFD 0x81CA #CJK UNIFIED IDEOGRAPH
+0xEBFE 0x81BB #CJK UNIFIED IDEOGRAPH
+0xEC40 0x9721 #CJK UNIFIED IDEOGRAPH
+0xEC41 0x9722 #CJK UNIFIED IDEOGRAPH
+0xEC42 0x9723 #CJK UNIFIED IDEOGRAPH
+0xEC43 0x9724 #CJK UNIFIED IDEOGRAPH
+0xEC44 0x9725 #CJK UNIFIED IDEOGRAPH
+0xEC45 0x9726 #CJK UNIFIED IDEOGRAPH
+0xEC46 0x9727 #CJK UNIFIED IDEOGRAPH
+0xEC47 0x9728 #CJK UNIFIED IDEOGRAPH
+0xEC48 0x9729 #CJK UNIFIED IDEOGRAPH
+0xEC49 0x972B #CJK UNIFIED IDEOGRAPH
+0xEC4A 0x972C #CJK UNIFIED IDEOGRAPH
+0xEC4B 0x972E #CJK UNIFIED IDEOGRAPH
+0xEC4C 0x972F #CJK UNIFIED IDEOGRAPH
+0xEC4D 0x9731 #CJK UNIFIED IDEOGRAPH
+0xEC4E 0x9733 #CJK UNIFIED IDEOGRAPH
+0xEC4F 0x9734 #CJK UNIFIED IDEOGRAPH
+0xEC50 0x9735 #CJK UNIFIED IDEOGRAPH
+0xEC51 0x9736 #CJK UNIFIED IDEOGRAPH
+0xEC52 0x9737 #CJK UNIFIED IDEOGRAPH
+0xEC53 0x973A #CJK UNIFIED IDEOGRAPH
+0xEC54 0x973B #CJK UNIFIED IDEOGRAPH
+0xEC55 0x973C #CJK UNIFIED IDEOGRAPH
+0xEC56 0x973D #CJK UNIFIED IDEOGRAPH
+0xEC57 0x973F #CJK UNIFIED IDEOGRAPH
+0xEC58 0x9740 #CJK UNIFIED IDEOGRAPH
+0xEC59 0x9741 #CJK UNIFIED IDEOGRAPH
+0xEC5A 0x9742 #CJK UNIFIED IDEOGRAPH
+0xEC5B 0x9743 #CJK UNIFIED IDEOGRAPH
+0xEC5C 0x9744 #CJK UNIFIED IDEOGRAPH
+0xEC5D 0x9745 #CJK UNIFIED IDEOGRAPH
+0xEC5E 0x9746 #CJK UNIFIED IDEOGRAPH
+0xEC5F 0x9747 #CJK UNIFIED IDEOGRAPH
+0xEC60 0x9748 #CJK UNIFIED IDEOGRAPH
+0xEC61 0x9749 #CJK UNIFIED IDEOGRAPH
+0xEC62 0x974A #CJK UNIFIED IDEOGRAPH
+0xEC63 0x974B #CJK UNIFIED IDEOGRAPH
+0xEC64 0x974C #CJK UNIFIED IDEOGRAPH
+0xEC65 0x974D #CJK UNIFIED IDEOGRAPH
+0xEC66 0x974E #CJK UNIFIED IDEOGRAPH
+0xEC67 0x974F #CJK UNIFIED IDEOGRAPH
+0xEC68 0x9750 #CJK UNIFIED IDEOGRAPH
+0xEC69 0x9751 #CJK UNIFIED IDEOGRAPH
+0xEC6A 0x9754 #CJK UNIFIED IDEOGRAPH
+0xEC6B 0x9755 #CJK UNIFIED IDEOGRAPH
+0xEC6C 0x9757 #CJK UNIFIED IDEOGRAPH
+0xEC6D 0x9758 #CJK UNIFIED IDEOGRAPH
+0xEC6E 0x975A #CJK UNIFIED IDEOGRAPH
+0xEC6F 0x975C #CJK UNIFIED IDEOGRAPH
+0xEC70 0x975D #CJK UNIFIED IDEOGRAPH
+0xEC71 0x975F #CJK UNIFIED IDEOGRAPH
+0xEC72 0x9763 #CJK UNIFIED IDEOGRAPH
+0xEC73 0x9764 #CJK UNIFIED IDEOGRAPH
+0xEC74 0x9766 #CJK UNIFIED IDEOGRAPH
+0xEC75 0x9767 #CJK UNIFIED IDEOGRAPH
+0xEC76 0x9768 #CJK UNIFIED IDEOGRAPH
+0xEC77 0x976A #CJK UNIFIED IDEOGRAPH
+0xEC78 0x976B #CJK UNIFIED IDEOGRAPH
+0xEC79 0x976C #CJK UNIFIED IDEOGRAPH
+0xEC7A 0x976D #CJK UNIFIED IDEOGRAPH
+0xEC7B 0x976E #CJK UNIFIED IDEOGRAPH
+0xEC7C 0x976F #CJK UNIFIED IDEOGRAPH
+0xEC7D 0x9770 #CJK UNIFIED IDEOGRAPH
+0xEC7E 0x9771 #CJK UNIFIED IDEOGRAPH
+0xEC80 0x9772 #CJK UNIFIED IDEOGRAPH
+0xEC81 0x9775 #CJK UNIFIED IDEOGRAPH
+0xEC82 0x9777 #CJK UNIFIED IDEOGRAPH
+0xEC83 0x9778 #CJK UNIFIED IDEOGRAPH
+0xEC84 0x9779 #CJK UNIFIED IDEOGRAPH
+0xEC85 0x977A #CJK UNIFIED IDEOGRAPH
+0xEC86 0x977B #CJK UNIFIED IDEOGRAPH
+0xEC87 0x977D #CJK UNIFIED IDEOGRAPH
+0xEC88 0x977E #CJK UNIFIED IDEOGRAPH
+0xEC89 0x977F #CJK UNIFIED IDEOGRAPH
+0xEC8A 0x9780 #CJK UNIFIED IDEOGRAPH
+0xEC8B 0x9781 #CJK UNIFIED IDEOGRAPH
+0xEC8C 0x9782 #CJK UNIFIED IDEOGRAPH
+0xEC8D 0x9783 #CJK UNIFIED IDEOGRAPH
+0xEC8E 0x9784 #CJK UNIFIED IDEOGRAPH
+0xEC8F 0x9786 #CJK UNIFIED IDEOGRAPH
+0xEC90 0x9787 #CJK UNIFIED IDEOGRAPH
+0xEC91 0x9788 #CJK UNIFIED IDEOGRAPH
+0xEC92 0x9789 #CJK UNIFIED IDEOGRAPH
+0xEC93 0x978A #CJK UNIFIED IDEOGRAPH
+0xEC94 0x978C #CJK UNIFIED IDEOGRAPH
+0xEC95 0x978E #CJK UNIFIED IDEOGRAPH
+0xEC96 0x978F #CJK UNIFIED IDEOGRAPH
+0xEC97 0x9790 #CJK UNIFIED IDEOGRAPH
+0xEC98 0x9793 #CJK UNIFIED IDEOGRAPH
+0xEC99 0x9795 #CJK UNIFIED IDEOGRAPH
+0xEC9A 0x9796 #CJK UNIFIED IDEOGRAPH
+0xEC9B 0x9797 #CJK UNIFIED IDEOGRAPH
+0xEC9C 0x9799 #CJK UNIFIED IDEOGRAPH
+0xEC9D 0x979A #CJK UNIFIED IDEOGRAPH
+0xEC9E 0x979B #CJK UNIFIED IDEOGRAPH
+0xEC9F 0x979C #CJK UNIFIED IDEOGRAPH
+0xECA0 0x979D #CJK UNIFIED IDEOGRAPH
+0xECA1 0x81C1 #CJK UNIFIED IDEOGRAPH
+0xECA2 0x81A6 #CJK UNIFIED IDEOGRAPH
+0xECA3 0x6B24 #CJK UNIFIED IDEOGRAPH
+0xECA4 0x6B37 #CJK UNIFIED IDEOGRAPH
+0xECA5 0x6B39 #CJK UNIFIED IDEOGRAPH
+0xECA6 0x6B43 #CJK UNIFIED IDEOGRAPH
+0xECA7 0x6B46 #CJK UNIFIED IDEOGRAPH
+0xECA8 0x6B59 #CJK UNIFIED IDEOGRAPH
+0xECA9 0x98D1 #CJK UNIFIED IDEOGRAPH
+0xECAA 0x98D2 #CJK UNIFIED IDEOGRAPH
+0xECAB 0x98D3 #CJK UNIFIED IDEOGRAPH
+0xECAC 0x98D5 #CJK UNIFIED IDEOGRAPH
+0xECAD 0x98D9 #CJK UNIFIED IDEOGRAPH
+0xECAE 0x98DA #CJK UNIFIED IDEOGRAPH
+0xECAF 0x6BB3 #CJK UNIFIED IDEOGRAPH
+0xECB0 0x5F40 #CJK UNIFIED IDEOGRAPH
+0xECB1 0x6BC2 #CJK UNIFIED IDEOGRAPH
+0xECB2 0x89F3 #CJK UNIFIED IDEOGRAPH
+0xECB3 0x6590 #CJK UNIFIED IDEOGRAPH
+0xECB4 0x9F51 #CJK UNIFIED IDEOGRAPH
+0xECB5 0x6593 #CJK UNIFIED IDEOGRAPH
+0xECB6 0x65BC #CJK UNIFIED IDEOGRAPH
+0xECB7 0x65C6 #CJK UNIFIED IDEOGRAPH
+0xECB8 0x65C4 #CJK UNIFIED IDEOGRAPH
+0xECB9 0x65C3 #CJK UNIFIED IDEOGRAPH
+0xECBA 0x65CC #CJK UNIFIED IDEOGRAPH
+0xECBB 0x65CE #CJK UNIFIED IDEOGRAPH
+0xECBC 0x65D2 #CJK UNIFIED IDEOGRAPH
+0xECBD 0x65D6 #CJK UNIFIED IDEOGRAPH
+0xECBE 0x7080 #CJK UNIFIED IDEOGRAPH
+0xECBF 0x709C #CJK UNIFIED IDEOGRAPH
+0xECC0 0x7096 #CJK UNIFIED IDEOGRAPH
+0xECC1 0x709D #CJK UNIFIED IDEOGRAPH
+0xECC2 0x70BB #CJK UNIFIED IDEOGRAPH
+0xECC3 0x70C0 #CJK UNIFIED IDEOGRAPH
+0xECC4 0x70B7 #CJK UNIFIED IDEOGRAPH
+0xECC5 0x70AB #CJK UNIFIED IDEOGRAPH
+0xECC6 0x70B1 #CJK UNIFIED IDEOGRAPH
+0xECC7 0x70E8 #CJK UNIFIED IDEOGRAPH
+0xECC8 0x70CA #CJK UNIFIED IDEOGRAPH
+0xECC9 0x7110 #CJK UNIFIED IDEOGRAPH
+0xECCA 0x7113 #CJK UNIFIED IDEOGRAPH
+0xECCB 0x7116 #CJK UNIFIED IDEOGRAPH
+0xECCC 0x712F #CJK UNIFIED IDEOGRAPH
+0xECCD 0x7131 #CJK UNIFIED IDEOGRAPH
+0xECCE 0x7173 #CJK UNIFIED IDEOGRAPH
+0xECCF 0x715C #CJK UNIFIED IDEOGRAPH
+0xECD0 0x7168 #CJK UNIFIED IDEOGRAPH
+0xECD1 0x7145 #CJK UNIFIED IDEOGRAPH
+0xECD2 0x7172 #CJK UNIFIED IDEOGRAPH
+0xECD3 0x714A #CJK UNIFIED IDEOGRAPH
+0xECD4 0x7178 #CJK UNIFIED IDEOGRAPH
+0xECD5 0x717A #CJK UNIFIED IDEOGRAPH
+0xECD6 0x7198 #CJK UNIFIED IDEOGRAPH
+0xECD7 0x71B3 #CJK UNIFIED IDEOGRAPH
+0xECD8 0x71B5 #CJK UNIFIED IDEOGRAPH
+0xECD9 0x71A8 #CJK UNIFIED IDEOGRAPH
+0xECDA 0x71A0 #CJK UNIFIED IDEOGRAPH
+0xECDB 0x71E0 #CJK UNIFIED IDEOGRAPH
+0xECDC 0x71D4 #CJK UNIFIED IDEOGRAPH
+0xECDD 0x71E7 #CJK UNIFIED IDEOGRAPH
+0xECDE 0x71F9 #CJK UNIFIED IDEOGRAPH
+0xECDF 0x721D #CJK UNIFIED IDEOGRAPH
+0xECE0 0x7228 #CJK UNIFIED IDEOGRAPH
+0xECE1 0x706C #CJK UNIFIED IDEOGRAPH
+0xECE2 0x7118 #CJK UNIFIED IDEOGRAPH
+0xECE3 0x7166 #CJK UNIFIED IDEOGRAPH
+0xECE4 0x71B9 #CJK UNIFIED IDEOGRAPH
+0xECE5 0x623E #CJK UNIFIED IDEOGRAPH
+0xECE6 0x623D #CJK UNIFIED IDEOGRAPH
+0xECE7 0x6243 #CJK UNIFIED IDEOGRAPH
+0xECE8 0x6248 #CJK UNIFIED IDEOGRAPH
+0xECE9 0x6249 #CJK UNIFIED IDEOGRAPH
+0xECEA 0x793B #CJK UNIFIED IDEOGRAPH
+0xECEB 0x7940 #CJK UNIFIED IDEOGRAPH
+0xECEC 0x7946 #CJK UNIFIED IDEOGRAPH
+0xECED 0x7949 #CJK UNIFIED IDEOGRAPH
+0xECEE 0x795B #CJK UNIFIED IDEOGRAPH
+0xECEF 0x795C #CJK UNIFIED IDEOGRAPH
+0xECF0 0x7953 #CJK UNIFIED IDEOGRAPH
+0xECF1 0x795A #CJK UNIFIED IDEOGRAPH
+0xECF2 0x7962 #CJK UNIFIED IDEOGRAPH
+0xECF3 0x7957 #CJK UNIFIED IDEOGRAPH
+0xECF4 0x7960 #CJK UNIFIED IDEOGRAPH
+0xECF5 0x796F #CJK UNIFIED IDEOGRAPH
+0xECF6 0x7967 #CJK UNIFIED IDEOGRAPH
+0xECF7 0x797A #CJK UNIFIED IDEOGRAPH
+0xECF8 0x7985 #CJK UNIFIED IDEOGRAPH
+0xECF9 0x798A #CJK UNIFIED IDEOGRAPH
+0xECFA 0x799A #CJK UNIFIED IDEOGRAPH
+0xECFB 0x79A7 #CJK UNIFIED IDEOGRAPH
+0xECFC 0x79B3 #CJK UNIFIED IDEOGRAPH
+0xECFD 0x5FD1 #CJK UNIFIED IDEOGRAPH
+0xECFE 0x5FD0 #CJK UNIFIED IDEOGRAPH
+0xED40 0x979E #CJK UNIFIED IDEOGRAPH
+0xED41 0x979F #CJK UNIFIED IDEOGRAPH
+0xED42 0x97A1 #CJK UNIFIED IDEOGRAPH
+0xED43 0x97A2 #CJK UNIFIED IDEOGRAPH
+0xED44 0x97A4 #CJK UNIFIED IDEOGRAPH
+0xED45 0x97A5 #CJK UNIFIED IDEOGRAPH
+0xED46 0x97A6 #CJK UNIFIED IDEOGRAPH
+0xED47 0x97A7 #CJK UNIFIED IDEOGRAPH
+0xED48 0x97A8 #CJK UNIFIED IDEOGRAPH
+0xED49 0x97A9 #CJK UNIFIED IDEOGRAPH
+0xED4A 0x97AA #CJK UNIFIED IDEOGRAPH
+0xED4B 0x97AC #CJK UNIFIED IDEOGRAPH
+0xED4C 0x97AE #CJK UNIFIED IDEOGRAPH
+0xED4D 0x97B0 #CJK UNIFIED IDEOGRAPH
+0xED4E 0x97B1 #CJK UNIFIED IDEOGRAPH
+0xED4F 0x97B3 #CJK UNIFIED IDEOGRAPH
+0xED50 0x97B5 #CJK UNIFIED IDEOGRAPH
+0xED51 0x97B6 #CJK UNIFIED IDEOGRAPH
+0xED52 0x97B7 #CJK UNIFIED IDEOGRAPH
+0xED53 0x97B8 #CJK UNIFIED IDEOGRAPH
+0xED54 0x97B9 #CJK UNIFIED IDEOGRAPH
+0xED55 0x97BA #CJK UNIFIED IDEOGRAPH
+0xED56 0x97BB #CJK UNIFIED IDEOGRAPH
+0xED57 0x97BC #CJK UNIFIED IDEOGRAPH
+0xED58 0x97BD #CJK UNIFIED IDEOGRAPH
+0xED59 0x97BE #CJK UNIFIED IDEOGRAPH
+0xED5A 0x97BF #CJK UNIFIED IDEOGRAPH
+0xED5B 0x97C0 #CJK UNIFIED IDEOGRAPH
+0xED5C 0x97C1 #CJK UNIFIED IDEOGRAPH
+0xED5D 0x97C2 #CJK UNIFIED IDEOGRAPH
+0xED5E 0x97C3 #CJK UNIFIED IDEOGRAPH
+0xED5F 0x97C4 #CJK UNIFIED IDEOGRAPH
+0xED60 0x97C5 #CJK UNIFIED IDEOGRAPH
+0xED61 0x97C6 #CJK UNIFIED IDEOGRAPH
+0xED62 0x97C7 #CJK UNIFIED IDEOGRAPH
+0xED63 0x97C8 #CJK UNIFIED IDEOGRAPH
+0xED64 0x97C9 #CJK UNIFIED IDEOGRAPH
+0xED65 0x97CA #CJK UNIFIED IDEOGRAPH
+0xED66 0x97CB #CJK UNIFIED IDEOGRAPH
+0xED67 0x97CC #CJK UNIFIED IDEOGRAPH
+0xED68 0x97CD #CJK UNIFIED IDEOGRAPH
+0xED69 0x97CE #CJK UNIFIED IDEOGRAPH
+0xED6A 0x97CF #CJK UNIFIED IDEOGRAPH
+0xED6B 0x97D0 #CJK UNIFIED IDEOGRAPH
+0xED6C 0x97D1 #CJK UNIFIED IDEOGRAPH
+0xED6D 0x97D2 #CJK UNIFIED IDEOGRAPH
+0xED6E 0x97D3 #CJK UNIFIED IDEOGRAPH
+0xED6F 0x97D4 #CJK UNIFIED IDEOGRAPH
+0xED70 0x97D5 #CJK UNIFIED IDEOGRAPH
+0xED71 0x97D6 #CJK UNIFIED IDEOGRAPH
+0xED72 0x97D7 #CJK UNIFIED IDEOGRAPH
+0xED73 0x97D8 #CJK UNIFIED IDEOGRAPH
+0xED74 0x97D9 #CJK UNIFIED IDEOGRAPH
+0xED75 0x97DA #CJK UNIFIED IDEOGRAPH
+0xED76 0x97DB #CJK UNIFIED IDEOGRAPH
+0xED77 0x97DC #CJK UNIFIED IDEOGRAPH
+0xED78 0x97DD #CJK UNIFIED IDEOGRAPH
+0xED79 0x97DE #CJK UNIFIED IDEOGRAPH
+0xED7A 0x97DF #CJK UNIFIED IDEOGRAPH
+0xED7B 0x97E0 #CJK UNIFIED IDEOGRAPH
+0xED7C 0x97E1 #CJK UNIFIED IDEOGRAPH
+0xED7D 0x97E2 #CJK UNIFIED IDEOGRAPH
+0xED7E 0x97E3 #CJK UNIFIED IDEOGRAPH
+0xED80 0x97E4 #CJK UNIFIED IDEOGRAPH
+0xED81 0x97E5 #CJK UNIFIED IDEOGRAPH
+0xED82 0x97E8 #CJK UNIFIED IDEOGRAPH
+0xED83 0x97EE #CJK UNIFIED IDEOGRAPH
+0xED84 0x97EF #CJK UNIFIED IDEOGRAPH
+0xED85 0x97F0 #CJK UNIFIED IDEOGRAPH
+0xED86 0x97F1 #CJK UNIFIED IDEOGRAPH
+0xED87 0x97F2 #CJK UNIFIED IDEOGRAPH
+0xED88 0x97F4 #CJK UNIFIED IDEOGRAPH
+0xED89 0x97F7 #CJK UNIFIED IDEOGRAPH
+0xED8A 0x97F8 #CJK UNIFIED IDEOGRAPH
+0xED8B 0x97F9 #CJK UNIFIED IDEOGRAPH
+0xED8C 0x97FA #CJK UNIFIED IDEOGRAPH
+0xED8D 0x97FB #CJK UNIFIED IDEOGRAPH
+0xED8E 0x97FC #CJK UNIFIED IDEOGRAPH
+0xED8F 0x97FD #CJK UNIFIED IDEOGRAPH
+0xED90 0x97FE #CJK UNIFIED IDEOGRAPH
+0xED91 0x97FF #CJK UNIFIED IDEOGRAPH
+0xED92 0x9800 #CJK UNIFIED IDEOGRAPH
+0xED93 0x9801 #CJK UNIFIED IDEOGRAPH
+0xED94 0x9802 #CJK UNIFIED IDEOGRAPH
+0xED95 0x9803 #CJK UNIFIED IDEOGRAPH
+0xED96 0x9804 #CJK UNIFIED IDEOGRAPH
+0xED97 0x9805 #CJK UNIFIED IDEOGRAPH
+0xED98 0x9806 #CJK UNIFIED IDEOGRAPH
+0xED99 0x9807 #CJK UNIFIED IDEOGRAPH
+0xED9A 0x9808 #CJK UNIFIED IDEOGRAPH
+0xED9B 0x9809 #CJK UNIFIED IDEOGRAPH
+0xED9C 0x980A #CJK UNIFIED IDEOGRAPH
+0xED9D 0x980B #CJK UNIFIED IDEOGRAPH
+0xED9E 0x980C #CJK UNIFIED IDEOGRAPH
+0xED9F 0x980D #CJK UNIFIED IDEOGRAPH
+0xEDA0 0x980E #CJK UNIFIED IDEOGRAPH
+0xEDA1 0x603C #CJK UNIFIED IDEOGRAPH
+0xEDA2 0x605D #CJK UNIFIED IDEOGRAPH
+0xEDA3 0x605A #CJK UNIFIED IDEOGRAPH
+0xEDA4 0x6067 #CJK UNIFIED IDEOGRAPH
+0xEDA5 0x6041 #CJK UNIFIED IDEOGRAPH
+0xEDA6 0x6059 #CJK UNIFIED IDEOGRAPH
+0xEDA7 0x6063 #CJK UNIFIED IDEOGRAPH
+0xEDA8 0x60AB #CJK UNIFIED IDEOGRAPH
+0xEDA9 0x6106 #CJK UNIFIED IDEOGRAPH
+0xEDAA 0x610D #CJK UNIFIED IDEOGRAPH
+0xEDAB 0x615D #CJK UNIFIED IDEOGRAPH
+0xEDAC 0x61A9 #CJK UNIFIED IDEOGRAPH
+0xEDAD 0x619D #CJK UNIFIED IDEOGRAPH
+0xEDAE 0x61CB #CJK UNIFIED IDEOGRAPH
+0xEDAF 0x61D1 #CJK UNIFIED IDEOGRAPH
+0xEDB0 0x6206 #CJK UNIFIED IDEOGRAPH
+0xEDB1 0x8080 #CJK UNIFIED IDEOGRAPH
+0xEDB2 0x807F #CJK UNIFIED IDEOGRAPH
+0xEDB3 0x6C93 #CJK UNIFIED IDEOGRAPH
+0xEDB4 0x6CF6 #CJK UNIFIED IDEOGRAPH
+0xEDB5 0x6DFC #CJK UNIFIED IDEOGRAPH
+0xEDB6 0x77F6 #CJK UNIFIED IDEOGRAPH
+0xEDB7 0x77F8 #CJK UNIFIED IDEOGRAPH
+0xEDB8 0x7800 #CJK UNIFIED IDEOGRAPH
+0xEDB9 0x7809 #CJK UNIFIED IDEOGRAPH
+0xEDBA 0x7817 #CJK UNIFIED IDEOGRAPH
+0xEDBB 0x7818 #CJK UNIFIED IDEOGRAPH
+0xEDBC 0x7811 #CJK UNIFIED IDEOGRAPH
+0xEDBD 0x65AB #CJK UNIFIED IDEOGRAPH
+0xEDBE 0x782D #CJK UNIFIED IDEOGRAPH
+0xEDBF 0x781C #CJK UNIFIED IDEOGRAPH
+0xEDC0 0x781D #CJK UNIFIED IDEOGRAPH
+0xEDC1 0x7839 #CJK UNIFIED IDEOGRAPH
+0xEDC2 0x783A #CJK UNIFIED IDEOGRAPH
+0xEDC3 0x783B #CJK UNIFIED IDEOGRAPH
+0xEDC4 0x781F #CJK UNIFIED IDEOGRAPH
+0xEDC5 0x783C #CJK UNIFIED IDEOGRAPH
+0xEDC6 0x7825 #CJK UNIFIED IDEOGRAPH
+0xEDC7 0x782C #CJK UNIFIED IDEOGRAPH
+0xEDC8 0x7823 #CJK UNIFIED IDEOGRAPH
+0xEDC9 0x7829 #CJK UNIFIED IDEOGRAPH
+0xEDCA 0x784E #CJK UNIFIED IDEOGRAPH
+0xEDCB 0x786D #CJK UNIFIED IDEOGRAPH
+0xEDCC 0x7856 #CJK UNIFIED IDEOGRAPH
+0xEDCD 0x7857 #CJK UNIFIED IDEOGRAPH
+0xEDCE 0x7826 #CJK UNIFIED IDEOGRAPH
+0xEDCF 0x7850 #CJK UNIFIED IDEOGRAPH
+0xEDD0 0x7847 #CJK UNIFIED IDEOGRAPH
+0xEDD1 0x784C #CJK UNIFIED IDEOGRAPH
+0xEDD2 0x786A #CJK UNIFIED IDEOGRAPH
+0xEDD3 0x789B #CJK UNIFIED IDEOGRAPH
+0xEDD4 0x7893 #CJK UNIFIED IDEOGRAPH
+0xEDD5 0x789A #CJK UNIFIED IDEOGRAPH
+0xEDD6 0x7887 #CJK UNIFIED IDEOGRAPH
+0xEDD7 0x789C #CJK UNIFIED IDEOGRAPH
+0xEDD8 0x78A1 #CJK UNIFIED IDEOGRAPH
+0xEDD9 0x78A3 #CJK UNIFIED IDEOGRAPH
+0xEDDA 0x78B2 #CJK UNIFIED IDEOGRAPH
+0xEDDB 0x78B9 #CJK UNIFIED IDEOGRAPH
+0xEDDC 0x78A5 #CJK UNIFIED IDEOGRAPH
+0xEDDD 0x78D4 #CJK UNIFIED IDEOGRAPH
+0xEDDE 0x78D9 #CJK UNIFIED IDEOGRAPH
+0xEDDF 0x78C9 #CJK UNIFIED IDEOGRAPH
+0xEDE0 0x78EC #CJK UNIFIED IDEOGRAPH
+0xEDE1 0x78F2 #CJK UNIFIED IDEOGRAPH
+0xEDE2 0x7905 #CJK UNIFIED IDEOGRAPH
+0xEDE3 0x78F4 #CJK UNIFIED IDEOGRAPH
+0xEDE4 0x7913 #CJK UNIFIED IDEOGRAPH
+0xEDE5 0x7924 #CJK UNIFIED IDEOGRAPH
+0xEDE6 0x791E #CJK UNIFIED IDEOGRAPH
+0xEDE7 0x7934 #CJK UNIFIED IDEOGRAPH
+0xEDE8 0x9F9B #CJK UNIFIED IDEOGRAPH
+0xEDE9 0x9EF9 #CJK UNIFIED IDEOGRAPH
+0xEDEA 0x9EFB #CJK UNIFIED IDEOGRAPH
+0xEDEB 0x9EFC #CJK UNIFIED IDEOGRAPH
+0xEDEC 0x76F1 #CJK UNIFIED IDEOGRAPH
+0xEDED 0x7704 #CJK UNIFIED IDEOGRAPH
+0xEDEE 0x770D #CJK UNIFIED IDEOGRAPH
+0xEDEF 0x76F9 #CJK UNIFIED IDEOGRAPH
+0xEDF0 0x7707 #CJK UNIFIED IDEOGRAPH
+0xEDF1 0x7708 #CJK UNIFIED IDEOGRAPH
+0xEDF2 0x771A #CJK UNIFIED IDEOGRAPH
+0xEDF3 0x7722 #CJK UNIFIED IDEOGRAPH
+0xEDF4 0x7719 #CJK UNIFIED IDEOGRAPH
+0xEDF5 0x772D #CJK UNIFIED IDEOGRAPH
+0xEDF6 0x7726 #CJK UNIFIED IDEOGRAPH
+0xEDF7 0x7735 #CJK UNIFIED IDEOGRAPH
+0xEDF8 0x7738 #CJK UNIFIED IDEOGRAPH
+0xEDF9 0x7750 #CJK UNIFIED IDEOGRAPH
+0xEDFA 0x7751 #CJK UNIFIED IDEOGRAPH
+0xEDFB 0x7747 #CJK UNIFIED IDEOGRAPH
+0xEDFC 0x7743 #CJK UNIFIED IDEOGRAPH
+0xEDFD 0x775A #CJK UNIFIED IDEOGRAPH
+0xEDFE 0x7768 #CJK UNIFIED IDEOGRAPH
+0xEE40 0x980F #CJK UNIFIED IDEOGRAPH
+0xEE41 0x9810 #CJK UNIFIED IDEOGRAPH
+0xEE42 0x9811 #CJK UNIFIED IDEOGRAPH
+0xEE43 0x9812 #CJK UNIFIED IDEOGRAPH
+0xEE44 0x9813 #CJK UNIFIED IDEOGRAPH
+0xEE45 0x9814 #CJK UNIFIED IDEOGRAPH
+0xEE46 0x9815 #CJK UNIFIED IDEOGRAPH
+0xEE47 0x9816 #CJK UNIFIED IDEOGRAPH
+0xEE48 0x9817 #CJK UNIFIED IDEOGRAPH
+0xEE49 0x9818 #CJK UNIFIED IDEOGRAPH
+0xEE4A 0x9819 #CJK UNIFIED IDEOGRAPH
+0xEE4B 0x981A #CJK UNIFIED IDEOGRAPH
+0xEE4C 0x981B #CJK UNIFIED IDEOGRAPH
+0xEE4D 0x981C #CJK UNIFIED IDEOGRAPH
+0xEE4E 0x981D #CJK UNIFIED IDEOGRAPH
+0xEE4F 0x981E #CJK UNIFIED IDEOGRAPH
+0xEE50 0x981F #CJK UNIFIED IDEOGRAPH
+0xEE51 0x9820 #CJK UNIFIED IDEOGRAPH
+0xEE52 0x9821 #CJK UNIFIED IDEOGRAPH
+0xEE53 0x9822 #CJK UNIFIED IDEOGRAPH
+0xEE54 0x9823 #CJK UNIFIED IDEOGRAPH
+0xEE55 0x9824 #CJK UNIFIED IDEOGRAPH
+0xEE56 0x9825 #CJK UNIFIED IDEOGRAPH
+0xEE57 0x9826 #CJK UNIFIED IDEOGRAPH
+0xEE58 0x9827 #CJK UNIFIED IDEOGRAPH
+0xEE59 0x9828 #CJK UNIFIED IDEOGRAPH
+0xEE5A 0x9829 #CJK UNIFIED IDEOGRAPH
+0xEE5B 0x982A #CJK UNIFIED IDEOGRAPH
+0xEE5C 0x982B #CJK UNIFIED IDEOGRAPH
+0xEE5D 0x982C #CJK UNIFIED IDEOGRAPH
+0xEE5E 0x982D #CJK UNIFIED IDEOGRAPH
+0xEE5F 0x982E #CJK UNIFIED IDEOGRAPH
+0xEE60 0x982F #CJK UNIFIED IDEOGRAPH
+0xEE61 0x9830 #CJK UNIFIED IDEOGRAPH
+0xEE62 0x9831 #CJK UNIFIED IDEOGRAPH
+0xEE63 0x9832 #CJK UNIFIED IDEOGRAPH
+0xEE64 0x9833 #CJK UNIFIED IDEOGRAPH
+0xEE65 0x9834 #CJK UNIFIED IDEOGRAPH
+0xEE66 0x9835 #CJK UNIFIED IDEOGRAPH
+0xEE67 0x9836 #CJK UNIFIED IDEOGRAPH
+0xEE68 0x9837 #CJK UNIFIED IDEOGRAPH
+0xEE69 0x9838 #CJK UNIFIED IDEOGRAPH
+0xEE6A 0x9839 #CJK UNIFIED IDEOGRAPH
+0xEE6B 0x983A #CJK UNIFIED IDEOGRAPH
+0xEE6C 0x983B #CJK UNIFIED IDEOGRAPH
+0xEE6D 0x983C #CJK UNIFIED IDEOGRAPH
+0xEE6E 0x983D #CJK UNIFIED IDEOGRAPH
+0xEE6F 0x983E #CJK UNIFIED IDEOGRAPH
+0xEE70 0x983F #CJK UNIFIED IDEOGRAPH
+0xEE71 0x9840 #CJK UNIFIED IDEOGRAPH
+0xEE72 0x9841 #CJK UNIFIED IDEOGRAPH
+0xEE73 0x9842 #CJK UNIFIED IDEOGRAPH
+0xEE74 0x9843 #CJK UNIFIED IDEOGRAPH
+0xEE75 0x9844 #CJK UNIFIED IDEOGRAPH
+0xEE76 0x9845 #CJK UNIFIED IDEOGRAPH
+0xEE77 0x9846 #CJK UNIFIED IDEOGRAPH
+0xEE78 0x9847 #CJK UNIFIED IDEOGRAPH
+0xEE79 0x9848 #CJK UNIFIED IDEOGRAPH
+0xEE7A 0x9849 #CJK UNIFIED IDEOGRAPH
+0xEE7B 0x984A #CJK UNIFIED IDEOGRAPH
+0xEE7C 0x984B #CJK UNIFIED IDEOGRAPH
+0xEE7D 0x984C #CJK UNIFIED IDEOGRAPH
+0xEE7E 0x984D #CJK UNIFIED IDEOGRAPH
+0xEE80 0x984E #CJK UNIFIED IDEOGRAPH
+0xEE81 0x984F #CJK UNIFIED IDEOGRAPH
+0xEE82 0x9850 #CJK UNIFIED IDEOGRAPH
+0xEE83 0x9851 #CJK UNIFIED IDEOGRAPH
+0xEE84 0x9852 #CJK UNIFIED IDEOGRAPH
+0xEE85 0x9853 #CJK UNIFIED IDEOGRAPH
+0xEE86 0x9854 #CJK UNIFIED IDEOGRAPH
+0xEE87 0x9855 #CJK UNIFIED IDEOGRAPH
+0xEE88 0x9856 #CJK UNIFIED IDEOGRAPH
+0xEE89 0x9857 #CJK UNIFIED IDEOGRAPH
+0xEE8A 0x9858 #CJK UNIFIED IDEOGRAPH
+0xEE8B 0x9859 #CJK UNIFIED IDEOGRAPH
+0xEE8C 0x985A #CJK UNIFIED IDEOGRAPH
+0xEE8D 0x985B #CJK UNIFIED IDEOGRAPH
+0xEE8E 0x985C #CJK UNIFIED IDEOGRAPH
+0xEE8F 0x985D #CJK UNIFIED IDEOGRAPH
+0xEE90 0x985E #CJK UNIFIED IDEOGRAPH
+0xEE91 0x985F #CJK UNIFIED IDEOGRAPH
+0xEE92 0x9860 #CJK UNIFIED IDEOGRAPH
+0xEE93 0x9861 #CJK UNIFIED IDEOGRAPH
+0xEE94 0x9862 #CJK UNIFIED IDEOGRAPH
+0xEE95 0x9863 #CJK UNIFIED IDEOGRAPH
+0xEE96 0x9864 #CJK UNIFIED IDEOGRAPH
+0xEE97 0x9865 #CJK UNIFIED IDEOGRAPH
+0xEE98 0x9866 #CJK UNIFIED IDEOGRAPH
+0xEE99 0x9867 #CJK UNIFIED IDEOGRAPH
+0xEE9A 0x9868 #CJK UNIFIED IDEOGRAPH
+0xEE9B 0x9869 #CJK UNIFIED IDEOGRAPH
+0xEE9C 0x986A #CJK UNIFIED IDEOGRAPH
+0xEE9D 0x986B #CJK UNIFIED IDEOGRAPH
+0xEE9E 0x986C #CJK UNIFIED IDEOGRAPH
+0xEE9F 0x986D #CJK UNIFIED IDEOGRAPH
+0xEEA0 0x986E #CJK UNIFIED IDEOGRAPH
+0xEEA1 0x7762 #CJK UNIFIED IDEOGRAPH
+0xEEA2 0x7765 #CJK UNIFIED IDEOGRAPH
+0xEEA3 0x777F #CJK UNIFIED IDEOGRAPH
+0xEEA4 0x778D #CJK UNIFIED IDEOGRAPH
+0xEEA5 0x777D #CJK UNIFIED IDEOGRAPH
+0xEEA6 0x7780 #CJK UNIFIED IDEOGRAPH
+0xEEA7 0x778C #CJK UNIFIED IDEOGRAPH
+0xEEA8 0x7791 #CJK UNIFIED IDEOGRAPH
+0xEEA9 0x779F #CJK UNIFIED IDEOGRAPH
+0xEEAA 0x77A0 #CJK UNIFIED IDEOGRAPH
+0xEEAB 0x77B0 #CJK UNIFIED IDEOGRAPH
+0xEEAC 0x77B5 #CJK UNIFIED IDEOGRAPH
+0xEEAD 0x77BD #CJK UNIFIED IDEOGRAPH
+0xEEAE 0x753A #CJK UNIFIED IDEOGRAPH
+0xEEAF 0x7540 #CJK UNIFIED IDEOGRAPH
+0xEEB0 0x754E #CJK UNIFIED IDEOGRAPH
+0xEEB1 0x754B #CJK UNIFIED IDEOGRAPH
+0xEEB2 0x7548 #CJK UNIFIED IDEOGRAPH
+0xEEB3 0x755B #CJK UNIFIED IDEOGRAPH
+0xEEB4 0x7572 #CJK UNIFIED IDEOGRAPH
+0xEEB5 0x7579 #CJK UNIFIED IDEOGRAPH
+0xEEB6 0x7583 #CJK UNIFIED IDEOGRAPH
+0xEEB7 0x7F58 #CJK UNIFIED IDEOGRAPH
+0xEEB8 0x7F61 #CJK UNIFIED IDEOGRAPH
+0xEEB9 0x7F5F #CJK UNIFIED IDEOGRAPH
+0xEEBA 0x8A48 #CJK UNIFIED IDEOGRAPH
+0xEEBB 0x7F68 #CJK UNIFIED IDEOGRAPH
+0xEEBC 0x7F74 #CJK UNIFIED IDEOGRAPH
+0xEEBD 0x7F71 #CJK UNIFIED IDEOGRAPH
+0xEEBE 0x7F79 #CJK UNIFIED IDEOGRAPH
+0xEEBF 0x7F81 #CJK UNIFIED IDEOGRAPH
+0xEEC0 0x7F7E #CJK UNIFIED IDEOGRAPH
+0xEEC1 0x76CD #CJK UNIFIED IDEOGRAPH
+0xEEC2 0x76E5 #CJK UNIFIED IDEOGRAPH
+0xEEC3 0x8832 #CJK UNIFIED IDEOGRAPH
+0xEEC4 0x9485 #CJK UNIFIED IDEOGRAPH
+0xEEC5 0x9486 #CJK UNIFIED IDEOGRAPH
+0xEEC6 0x9487 #CJK UNIFIED IDEOGRAPH
+0xEEC7 0x948B #CJK UNIFIED IDEOGRAPH
+0xEEC8 0x948A #CJK UNIFIED IDEOGRAPH
+0xEEC9 0x948C #CJK UNIFIED IDEOGRAPH
+0xEECA 0x948D #CJK UNIFIED IDEOGRAPH
+0xEECB 0x948F #CJK UNIFIED IDEOGRAPH
+0xEECC 0x9490 #CJK UNIFIED IDEOGRAPH
+0xEECD 0x9494 #CJK UNIFIED IDEOGRAPH
+0xEECE 0x9497 #CJK UNIFIED IDEOGRAPH
+0xEECF 0x9495 #CJK UNIFIED IDEOGRAPH
+0xEED0 0x949A #CJK UNIFIED IDEOGRAPH
+0xEED1 0x949B #CJK UNIFIED IDEOGRAPH
+0xEED2 0x949C #CJK UNIFIED IDEOGRAPH
+0xEED3 0x94A3 #CJK UNIFIED IDEOGRAPH
+0xEED4 0x94A4 #CJK UNIFIED IDEOGRAPH
+0xEED5 0x94AB #CJK UNIFIED IDEOGRAPH
+0xEED6 0x94AA #CJK UNIFIED IDEOGRAPH
+0xEED7 0x94AD #CJK UNIFIED IDEOGRAPH
+0xEED8 0x94AC #CJK UNIFIED IDEOGRAPH
+0xEED9 0x94AF #CJK UNIFIED IDEOGRAPH
+0xEEDA 0x94B0 #CJK UNIFIED IDEOGRAPH
+0xEEDB 0x94B2 #CJK UNIFIED IDEOGRAPH
+0xEEDC 0x94B4 #CJK UNIFIED IDEOGRAPH
+0xEEDD 0x94B6 #CJK UNIFIED IDEOGRAPH
+0xEEDE 0x94B7 #CJK UNIFIED IDEOGRAPH
+0xEEDF 0x94B8 #CJK UNIFIED IDEOGRAPH
+0xEEE0 0x94B9 #CJK UNIFIED IDEOGRAPH
+0xEEE1 0x94BA #CJK UNIFIED IDEOGRAPH
+0xEEE2 0x94BC #CJK UNIFIED IDEOGRAPH
+0xEEE3 0x94BD #CJK UNIFIED IDEOGRAPH
+0xEEE4 0x94BF #CJK UNIFIED IDEOGRAPH
+0xEEE5 0x94C4 #CJK UNIFIED IDEOGRAPH
+0xEEE6 0x94C8 #CJK UNIFIED IDEOGRAPH
+0xEEE7 0x94C9 #CJK UNIFIED IDEOGRAPH
+0xEEE8 0x94CA #CJK UNIFIED IDEOGRAPH
+0xEEE9 0x94CB #CJK UNIFIED IDEOGRAPH
+0xEEEA 0x94CC #CJK UNIFIED IDEOGRAPH
+0xEEEB 0x94CD #CJK UNIFIED IDEOGRAPH
+0xEEEC 0x94CE #CJK UNIFIED IDEOGRAPH
+0xEEED 0x94D0 #CJK UNIFIED IDEOGRAPH
+0xEEEE 0x94D1 #CJK UNIFIED IDEOGRAPH
+0xEEEF 0x94D2 #CJK UNIFIED IDEOGRAPH
+0xEEF0 0x94D5 #CJK UNIFIED IDEOGRAPH
+0xEEF1 0x94D6 #CJK UNIFIED IDEOGRAPH
+0xEEF2 0x94D7 #CJK UNIFIED IDEOGRAPH
+0xEEF3 0x94D9 #CJK UNIFIED IDEOGRAPH
+0xEEF4 0x94D8 #CJK UNIFIED IDEOGRAPH
+0xEEF5 0x94DB #CJK UNIFIED IDEOGRAPH
+0xEEF6 0x94DE #CJK UNIFIED IDEOGRAPH
+0xEEF7 0x94DF #CJK UNIFIED IDEOGRAPH
+0xEEF8 0x94E0 #CJK UNIFIED IDEOGRAPH
+0xEEF9 0x94E2 #CJK UNIFIED IDEOGRAPH
+0xEEFA 0x94E4 #CJK UNIFIED IDEOGRAPH
+0xEEFB 0x94E5 #CJK UNIFIED IDEOGRAPH
+0xEEFC 0x94E7 #CJK UNIFIED IDEOGRAPH
+0xEEFD 0x94E8 #CJK UNIFIED IDEOGRAPH
+0xEEFE 0x94EA #CJK UNIFIED IDEOGRAPH
+0xEF40 0x986F #CJK UNIFIED IDEOGRAPH
+0xEF41 0x9870 #CJK UNIFIED IDEOGRAPH
+0xEF42 0x9871 #CJK UNIFIED IDEOGRAPH
+0xEF43 0x9872 #CJK UNIFIED IDEOGRAPH
+0xEF44 0x9873 #CJK UNIFIED IDEOGRAPH
+0xEF45 0x9874 #CJK UNIFIED IDEOGRAPH
+0xEF46 0x988B #CJK UNIFIED IDEOGRAPH
+0xEF47 0x988E #CJK UNIFIED IDEOGRAPH
+0xEF48 0x9892 #CJK UNIFIED IDEOGRAPH
+0xEF49 0x9895 #CJK UNIFIED IDEOGRAPH
+0xEF4A 0x9899 #CJK UNIFIED IDEOGRAPH
+0xEF4B 0x98A3 #CJK UNIFIED IDEOGRAPH
+0xEF4C 0x98A8 #CJK UNIFIED IDEOGRAPH
+0xEF4D 0x98A9 #CJK UNIFIED IDEOGRAPH
+0xEF4E 0x98AA #CJK UNIFIED IDEOGRAPH
+0xEF4F 0x98AB #CJK UNIFIED IDEOGRAPH
+0xEF50 0x98AC #CJK UNIFIED IDEOGRAPH
+0xEF51 0x98AD #CJK UNIFIED IDEOGRAPH
+0xEF52 0x98AE #CJK UNIFIED IDEOGRAPH
+0xEF53 0x98AF #CJK UNIFIED IDEOGRAPH
+0xEF54 0x98B0 #CJK UNIFIED IDEOGRAPH
+0xEF55 0x98B1 #CJK UNIFIED IDEOGRAPH
+0xEF56 0x98B2 #CJK UNIFIED IDEOGRAPH
+0xEF57 0x98B3 #CJK UNIFIED IDEOGRAPH
+0xEF58 0x98B4 #CJK UNIFIED IDEOGRAPH
+0xEF59 0x98B5 #CJK UNIFIED IDEOGRAPH
+0xEF5A 0x98B6 #CJK UNIFIED IDEOGRAPH
+0xEF5B 0x98B7 #CJK UNIFIED IDEOGRAPH
+0xEF5C 0x98B8 #CJK UNIFIED IDEOGRAPH
+0xEF5D 0x98B9 #CJK UNIFIED IDEOGRAPH
+0xEF5E 0x98BA #CJK UNIFIED IDEOGRAPH
+0xEF5F 0x98BB #CJK UNIFIED IDEOGRAPH
+0xEF60 0x98BC #CJK UNIFIED IDEOGRAPH
+0xEF61 0x98BD #CJK UNIFIED IDEOGRAPH
+0xEF62 0x98BE #CJK UNIFIED IDEOGRAPH
+0xEF63 0x98BF #CJK UNIFIED IDEOGRAPH
+0xEF64 0x98C0 #CJK UNIFIED IDEOGRAPH
+0xEF65 0x98C1 #CJK UNIFIED IDEOGRAPH
+0xEF66 0x98C2 #CJK UNIFIED IDEOGRAPH
+0xEF67 0x98C3 #CJK UNIFIED IDEOGRAPH
+0xEF68 0x98C4 #CJK UNIFIED IDEOGRAPH
+0xEF69 0x98C5 #CJK UNIFIED IDEOGRAPH
+0xEF6A 0x98C6 #CJK UNIFIED IDEOGRAPH
+0xEF6B 0x98C7 #CJK UNIFIED IDEOGRAPH
+0xEF6C 0x98C8 #CJK UNIFIED IDEOGRAPH
+0xEF6D 0x98C9 #CJK UNIFIED IDEOGRAPH
+0xEF6E 0x98CA #CJK UNIFIED IDEOGRAPH
+0xEF6F 0x98CB #CJK UNIFIED IDEOGRAPH
+0xEF70 0x98CC #CJK UNIFIED IDEOGRAPH
+0xEF71 0x98CD #CJK UNIFIED IDEOGRAPH
+0xEF72 0x98CF #CJK UNIFIED IDEOGRAPH
+0xEF73 0x98D0 #CJK UNIFIED IDEOGRAPH
+0xEF74 0x98D4 #CJK UNIFIED IDEOGRAPH
+0xEF75 0x98D6 #CJK UNIFIED IDEOGRAPH
+0xEF76 0x98D7 #CJK UNIFIED IDEOGRAPH
+0xEF77 0x98DB #CJK UNIFIED IDEOGRAPH
+0xEF78 0x98DC #CJK UNIFIED IDEOGRAPH
+0xEF79 0x98DD #CJK UNIFIED IDEOGRAPH
+0xEF7A 0x98E0 #CJK UNIFIED IDEOGRAPH
+0xEF7B 0x98E1 #CJK UNIFIED IDEOGRAPH
+0xEF7C 0x98E2 #CJK UNIFIED IDEOGRAPH
+0xEF7D 0x98E3 #CJK UNIFIED IDEOGRAPH
+0xEF7E 0x98E4 #CJK UNIFIED IDEOGRAPH
+0xEF80 0x98E5 #CJK UNIFIED IDEOGRAPH
+0xEF81 0x98E6 #CJK UNIFIED IDEOGRAPH
+0xEF82 0x98E9 #CJK UNIFIED IDEOGRAPH
+0xEF83 0x98EA #CJK UNIFIED IDEOGRAPH
+0xEF84 0x98EB #CJK UNIFIED IDEOGRAPH
+0xEF85 0x98EC #CJK UNIFIED IDEOGRAPH
+0xEF86 0x98ED #CJK UNIFIED IDEOGRAPH
+0xEF87 0x98EE #CJK UNIFIED IDEOGRAPH
+0xEF88 0x98EF #CJK UNIFIED IDEOGRAPH
+0xEF89 0x98F0 #CJK UNIFIED IDEOGRAPH
+0xEF8A 0x98F1 #CJK UNIFIED IDEOGRAPH
+0xEF8B 0x98F2 #CJK UNIFIED IDEOGRAPH
+0xEF8C 0x98F3 #CJK UNIFIED IDEOGRAPH
+0xEF8D 0x98F4 #CJK UNIFIED IDEOGRAPH
+0xEF8E 0x98F5 #CJK UNIFIED IDEOGRAPH
+0xEF8F 0x98F6 #CJK UNIFIED IDEOGRAPH
+0xEF90 0x98F7 #CJK UNIFIED IDEOGRAPH
+0xEF91 0x98F8 #CJK UNIFIED IDEOGRAPH
+0xEF92 0x98F9 #CJK UNIFIED IDEOGRAPH
+0xEF93 0x98FA #CJK UNIFIED IDEOGRAPH
+0xEF94 0x98FB #CJK UNIFIED IDEOGRAPH
+0xEF95 0x98FC #CJK UNIFIED IDEOGRAPH
+0xEF96 0x98FD #CJK UNIFIED IDEOGRAPH
+0xEF97 0x98FE #CJK UNIFIED IDEOGRAPH
+0xEF98 0x98FF #CJK UNIFIED IDEOGRAPH
+0xEF99 0x9900 #CJK UNIFIED IDEOGRAPH
+0xEF9A 0x9901 #CJK UNIFIED IDEOGRAPH
+0xEF9B 0x9902 #CJK UNIFIED IDEOGRAPH
+0xEF9C 0x9903 #CJK UNIFIED IDEOGRAPH
+0xEF9D 0x9904 #CJK UNIFIED IDEOGRAPH
+0xEF9E 0x9905 #CJK UNIFIED IDEOGRAPH
+0xEF9F 0x9906 #CJK UNIFIED IDEOGRAPH
+0xEFA0 0x9907 #CJK UNIFIED IDEOGRAPH
+0xEFA1 0x94E9 #CJK UNIFIED IDEOGRAPH
+0xEFA2 0x94EB #CJK UNIFIED IDEOGRAPH
+0xEFA3 0x94EE #CJK UNIFIED IDEOGRAPH
+0xEFA4 0x94EF #CJK UNIFIED IDEOGRAPH
+0xEFA5 0x94F3 #CJK UNIFIED IDEOGRAPH
+0xEFA6 0x94F4 #CJK UNIFIED IDEOGRAPH
+0xEFA7 0x94F5 #CJK UNIFIED IDEOGRAPH
+0xEFA8 0x94F7 #CJK UNIFIED IDEOGRAPH
+0xEFA9 0x94F9 #CJK UNIFIED IDEOGRAPH
+0xEFAA 0x94FC #CJK UNIFIED IDEOGRAPH
+0xEFAB 0x94FD #CJK UNIFIED IDEOGRAPH
+0xEFAC 0x94FF #CJK UNIFIED IDEOGRAPH
+0xEFAD 0x9503 #CJK UNIFIED IDEOGRAPH
+0xEFAE 0x9502 #CJK UNIFIED IDEOGRAPH
+0xEFAF 0x9506 #CJK UNIFIED IDEOGRAPH
+0xEFB0 0x9507 #CJK UNIFIED IDEOGRAPH
+0xEFB1 0x9509 #CJK UNIFIED IDEOGRAPH
+0xEFB2 0x950A #CJK UNIFIED IDEOGRAPH
+0xEFB3 0x950D #CJK UNIFIED IDEOGRAPH
+0xEFB4 0x950E #CJK UNIFIED IDEOGRAPH
+0xEFB5 0x950F #CJK UNIFIED IDEOGRAPH
+0xEFB6 0x9512 #CJK UNIFIED IDEOGRAPH
+0xEFB7 0x9513 #CJK UNIFIED IDEOGRAPH
+0xEFB8 0x9514 #CJK UNIFIED IDEOGRAPH
+0xEFB9 0x9515 #CJK UNIFIED IDEOGRAPH
+0xEFBA 0x9516 #CJK UNIFIED IDEOGRAPH
+0xEFBB 0x9518 #CJK UNIFIED IDEOGRAPH
+0xEFBC 0x951B #CJK UNIFIED IDEOGRAPH
+0xEFBD 0x951D #CJK UNIFIED IDEOGRAPH
+0xEFBE 0x951E #CJK UNIFIED IDEOGRAPH
+0xEFBF 0x951F #CJK UNIFIED IDEOGRAPH
+0xEFC0 0x9522 #CJK UNIFIED IDEOGRAPH
+0xEFC1 0x952A #CJK UNIFIED IDEOGRAPH
+0xEFC2 0x952B #CJK UNIFIED IDEOGRAPH
+0xEFC3 0x9529 #CJK UNIFIED IDEOGRAPH
+0xEFC4 0x952C #CJK UNIFIED IDEOGRAPH
+0xEFC5 0x9531 #CJK UNIFIED IDEOGRAPH
+0xEFC6 0x9532 #CJK UNIFIED IDEOGRAPH
+0xEFC7 0x9534 #CJK UNIFIED IDEOGRAPH
+0xEFC8 0x9536 #CJK UNIFIED IDEOGRAPH
+0xEFC9 0x9537 #CJK UNIFIED IDEOGRAPH
+0xEFCA 0x9538 #CJK UNIFIED IDEOGRAPH
+0xEFCB 0x953C #CJK UNIFIED IDEOGRAPH
+0xEFCC 0x953E #CJK UNIFIED IDEOGRAPH
+0xEFCD 0x953F #CJK UNIFIED IDEOGRAPH
+0xEFCE 0x9542 #CJK UNIFIED IDEOGRAPH
+0xEFCF 0x9535 #CJK UNIFIED IDEOGRAPH
+0xEFD0 0x9544 #CJK UNIFIED IDEOGRAPH
+0xEFD1 0x9545 #CJK UNIFIED IDEOGRAPH
+0xEFD2 0x9546 #CJK UNIFIED IDEOGRAPH
+0xEFD3 0x9549 #CJK UNIFIED IDEOGRAPH
+0xEFD4 0x954C #CJK UNIFIED IDEOGRAPH
+0xEFD5 0x954E #CJK UNIFIED IDEOGRAPH
+0xEFD6 0x954F #CJK UNIFIED IDEOGRAPH
+0xEFD7 0x9552 #CJK UNIFIED IDEOGRAPH
+0xEFD8 0x9553 #CJK UNIFIED IDEOGRAPH
+0xEFD9 0x9554 #CJK UNIFIED IDEOGRAPH
+0xEFDA 0x9556 #CJK UNIFIED IDEOGRAPH
+0xEFDB 0x9557 #CJK UNIFIED IDEOGRAPH
+0xEFDC 0x9558 #CJK UNIFIED IDEOGRAPH
+0xEFDD 0x9559 #CJK UNIFIED IDEOGRAPH
+0xEFDE 0x955B #CJK UNIFIED IDEOGRAPH
+0xEFDF 0x955E #CJK UNIFIED IDEOGRAPH
+0xEFE0 0x955F #CJK UNIFIED IDEOGRAPH
+0xEFE1 0x955D #CJK UNIFIED IDEOGRAPH
+0xEFE2 0x9561 #CJK UNIFIED IDEOGRAPH
+0xEFE3 0x9562 #CJK UNIFIED IDEOGRAPH
+0xEFE4 0x9564 #CJK UNIFIED IDEOGRAPH
+0xEFE5 0x9565 #CJK UNIFIED IDEOGRAPH
+0xEFE6 0x9566 #CJK UNIFIED IDEOGRAPH
+0xEFE7 0x9567 #CJK UNIFIED IDEOGRAPH
+0xEFE8 0x9568 #CJK UNIFIED IDEOGRAPH
+0xEFE9 0x9569 #CJK UNIFIED IDEOGRAPH
+0xEFEA 0x956A #CJK UNIFIED IDEOGRAPH
+0xEFEB 0x956B #CJK UNIFIED IDEOGRAPH
+0xEFEC 0x956C #CJK UNIFIED IDEOGRAPH
+0xEFED 0x956F #CJK UNIFIED IDEOGRAPH
+0xEFEE 0x9571 #CJK UNIFIED IDEOGRAPH
+0xEFEF 0x9572 #CJK UNIFIED IDEOGRAPH
+0xEFF0 0x9573 #CJK UNIFIED IDEOGRAPH
+0xEFF1 0x953A #CJK UNIFIED IDEOGRAPH
+0xEFF2 0x77E7 #CJK UNIFIED IDEOGRAPH
+0xEFF3 0x77EC #CJK UNIFIED IDEOGRAPH
+0xEFF4 0x96C9 #CJK UNIFIED IDEOGRAPH
+0xEFF5 0x79D5 #CJK UNIFIED IDEOGRAPH
+0xEFF6 0x79ED #CJK UNIFIED IDEOGRAPH
+0xEFF7 0x79E3 #CJK UNIFIED IDEOGRAPH
+0xEFF8 0x79EB #CJK UNIFIED IDEOGRAPH
+0xEFF9 0x7A06 #CJK UNIFIED IDEOGRAPH
+0xEFFA 0x5D47 #CJK UNIFIED IDEOGRAPH
+0xEFFB 0x7A03 #CJK UNIFIED IDEOGRAPH
+0xEFFC 0x7A02 #CJK UNIFIED IDEOGRAPH
+0xEFFD 0x7A1E #CJK UNIFIED IDEOGRAPH
+0xEFFE 0x7A14 #CJK UNIFIED IDEOGRAPH
+0xF040 0x9908 #CJK UNIFIED IDEOGRAPH
+0xF041 0x9909 #CJK UNIFIED IDEOGRAPH
+0xF042 0x990A #CJK UNIFIED IDEOGRAPH
+0xF043 0x990B #CJK UNIFIED IDEOGRAPH
+0xF044 0x990C #CJK UNIFIED IDEOGRAPH
+0xF045 0x990E #CJK UNIFIED IDEOGRAPH
+0xF046 0x990F #CJK UNIFIED IDEOGRAPH
+0xF047 0x9911 #CJK UNIFIED IDEOGRAPH
+0xF048 0x9912 #CJK UNIFIED IDEOGRAPH
+0xF049 0x9913 #CJK UNIFIED IDEOGRAPH
+0xF04A 0x9914 #CJK UNIFIED IDEOGRAPH
+0xF04B 0x9915 #CJK UNIFIED IDEOGRAPH
+0xF04C 0x9916 #CJK UNIFIED IDEOGRAPH
+0xF04D 0x9917 #CJK UNIFIED IDEOGRAPH
+0xF04E 0x9918 #CJK UNIFIED IDEOGRAPH
+0xF04F 0x9919 #CJK UNIFIED IDEOGRAPH
+0xF050 0x991A #CJK UNIFIED IDEOGRAPH
+0xF051 0x991B #CJK UNIFIED IDEOGRAPH
+0xF052 0x991C #CJK UNIFIED IDEOGRAPH
+0xF053 0x991D #CJK UNIFIED IDEOGRAPH
+0xF054 0x991E #CJK UNIFIED IDEOGRAPH
+0xF055 0x991F #CJK UNIFIED IDEOGRAPH
+0xF056 0x9920 #CJK UNIFIED IDEOGRAPH
+0xF057 0x9921 #CJK UNIFIED IDEOGRAPH
+0xF058 0x9922 #CJK UNIFIED IDEOGRAPH
+0xF059 0x9923 #CJK UNIFIED IDEOGRAPH
+0xF05A 0x9924 #CJK UNIFIED IDEOGRAPH
+0xF05B 0x9925 #CJK UNIFIED IDEOGRAPH
+0xF05C 0x9926 #CJK UNIFIED IDEOGRAPH
+0xF05D 0x9927 #CJK UNIFIED IDEOGRAPH
+0xF05E 0x9928 #CJK UNIFIED IDEOGRAPH
+0xF05F 0x9929 #CJK UNIFIED IDEOGRAPH
+0xF060 0x992A #CJK UNIFIED IDEOGRAPH
+0xF061 0x992B #CJK UNIFIED IDEOGRAPH
+0xF062 0x992C #CJK UNIFIED IDEOGRAPH
+0xF063 0x992D #CJK UNIFIED IDEOGRAPH
+0xF064 0x992F #CJK UNIFIED IDEOGRAPH
+0xF065 0x9930 #CJK UNIFIED IDEOGRAPH
+0xF066 0x9931 #CJK UNIFIED IDEOGRAPH
+0xF067 0x9932 #CJK UNIFIED IDEOGRAPH
+0xF068 0x9933 #CJK UNIFIED IDEOGRAPH
+0xF069 0x9934 #CJK UNIFIED IDEOGRAPH
+0xF06A 0x9935 #CJK UNIFIED IDEOGRAPH
+0xF06B 0x9936 #CJK UNIFIED IDEOGRAPH
+0xF06C 0x9937 #CJK UNIFIED IDEOGRAPH
+0xF06D 0x9938 #CJK UNIFIED IDEOGRAPH
+0xF06E 0x9939 #CJK UNIFIED IDEOGRAPH
+0xF06F 0x993A #CJK UNIFIED IDEOGRAPH
+0xF070 0x993B #CJK UNIFIED IDEOGRAPH
+0xF071 0x993C #CJK UNIFIED IDEOGRAPH
+0xF072 0x993D #CJK UNIFIED IDEOGRAPH
+0xF073 0x993E #CJK UNIFIED IDEOGRAPH
+0xF074 0x993F #CJK UNIFIED IDEOGRAPH
+0xF075 0x9940 #CJK UNIFIED IDEOGRAPH
+0xF076 0x9941 #CJK UNIFIED IDEOGRAPH
+0xF077 0x9942 #CJK UNIFIED IDEOGRAPH
+0xF078 0x9943 #CJK UNIFIED IDEOGRAPH
+0xF079 0x9944 #CJK UNIFIED IDEOGRAPH
+0xF07A 0x9945 #CJK UNIFIED IDEOGRAPH
+0xF07B 0x9946 #CJK UNIFIED IDEOGRAPH
+0xF07C 0x9947 #CJK UNIFIED IDEOGRAPH
+0xF07D 0x9948 #CJK UNIFIED IDEOGRAPH
+0xF07E 0x9949 #CJK UNIFIED IDEOGRAPH
+0xF080 0x994A #CJK UNIFIED IDEOGRAPH
+0xF081 0x994B #CJK UNIFIED IDEOGRAPH
+0xF082 0x994C #CJK UNIFIED IDEOGRAPH
+0xF083 0x994D #CJK UNIFIED IDEOGRAPH
+0xF084 0x994E #CJK UNIFIED IDEOGRAPH
+0xF085 0x994F #CJK UNIFIED IDEOGRAPH
+0xF086 0x9950 #CJK UNIFIED IDEOGRAPH
+0xF087 0x9951 #CJK UNIFIED IDEOGRAPH
+0xF088 0x9952 #CJK UNIFIED IDEOGRAPH
+0xF089 0x9953 #CJK UNIFIED IDEOGRAPH
+0xF08A 0x9956 #CJK UNIFIED IDEOGRAPH
+0xF08B 0x9957 #CJK UNIFIED IDEOGRAPH
+0xF08C 0x9958 #CJK UNIFIED IDEOGRAPH
+0xF08D 0x9959 #CJK UNIFIED IDEOGRAPH
+0xF08E 0x995A #CJK UNIFIED IDEOGRAPH
+0xF08F 0x995B #CJK UNIFIED IDEOGRAPH
+0xF090 0x995C #CJK UNIFIED IDEOGRAPH
+0xF091 0x995D #CJK UNIFIED IDEOGRAPH
+0xF092 0x995E #CJK UNIFIED IDEOGRAPH
+0xF093 0x995F #CJK UNIFIED IDEOGRAPH
+0xF094 0x9960 #CJK UNIFIED IDEOGRAPH
+0xF095 0x9961 #CJK UNIFIED IDEOGRAPH
+0xF096 0x9962 #CJK UNIFIED IDEOGRAPH
+0xF097 0x9964 #CJK UNIFIED IDEOGRAPH
+0xF098 0x9966 #CJK UNIFIED IDEOGRAPH
+0xF099 0x9973 #CJK UNIFIED IDEOGRAPH
+0xF09A 0x9978 #CJK UNIFIED IDEOGRAPH
+0xF09B 0x9979 #CJK UNIFIED IDEOGRAPH
+0xF09C 0x997B #CJK UNIFIED IDEOGRAPH
+0xF09D 0x997E #CJK UNIFIED IDEOGRAPH
+0xF09E 0x9982 #CJK UNIFIED IDEOGRAPH
+0xF09F 0x9983 #CJK UNIFIED IDEOGRAPH
+0xF0A0 0x9989 #CJK UNIFIED IDEOGRAPH
+0xF0A1 0x7A39 #CJK UNIFIED IDEOGRAPH
+0xF0A2 0x7A37 #CJK UNIFIED IDEOGRAPH
+0xF0A3 0x7A51 #CJK UNIFIED IDEOGRAPH
+0xF0A4 0x9ECF #CJK UNIFIED IDEOGRAPH
+0xF0A5 0x99A5 #CJK UNIFIED IDEOGRAPH
+0xF0A6 0x7A70 #CJK UNIFIED IDEOGRAPH
+0xF0A7 0x7688 #CJK UNIFIED IDEOGRAPH
+0xF0A8 0x768E #CJK UNIFIED IDEOGRAPH
+0xF0A9 0x7693 #CJK UNIFIED IDEOGRAPH
+0xF0AA 0x7699 #CJK UNIFIED IDEOGRAPH
+0xF0AB 0x76A4 #CJK UNIFIED IDEOGRAPH
+0xF0AC 0x74DE #CJK UNIFIED IDEOGRAPH
+0xF0AD 0x74E0 #CJK UNIFIED IDEOGRAPH
+0xF0AE 0x752C #CJK UNIFIED IDEOGRAPH
+0xF0AF 0x9E20 #CJK UNIFIED IDEOGRAPH
+0xF0B0 0x9E22 #CJK UNIFIED IDEOGRAPH
+0xF0B1 0x9E28 #CJK UNIFIED IDEOGRAPH
+0xF0B2 0x9E29 #CJK UNIFIED IDEOGRAPH
+0xF0B3 0x9E2A #CJK UNIFIED IDEOGRAPH
+0xF0B4 0x9E2B #CJK UNIFIED IDEOGRAPH
+0xF0B5 0x9E2C #CJK UNIFIED IDEOGRAPH
+0xF0B6 0x9E32 #CJK UNIFIED IDEOGRAPH
+0xF0B7 0x9E31 #CJK UNIFIED IDEOGRAPH
+0xF0B8 0x9E36 #CJK UNIFIED IDEOGRAPH
+0xF0B9 0x9E38 #CJK UNIFIED IDEOGRAPH
+0xF0BA 0x9E37 #CJK UNIFIED IDEOGRAPH
+0xF0BB 0x9E39 #CJK UNIFIED IDEOGRAPH
+0xF0BC 0x9E3A #CJK UNIFIED IDEOGRAPH
+0xF0BD 0x9E3E #CJK UNIFIED IDEOGRAPH
+0xF0BE 0x9E41 #CJK UNIFIED IDEOGRAPH
+0xF0BF 0x9E42 #CJK UNIFIED IDEOGRAPH
+0xF0C0 0x9E44 #CJK UNIFIED IDEOGRAPH
+0xF0C1 0x9E46 #CJK UNIFIED IDEOGRAPH
+0xF0C2 0x9E47 #CJK UNIFIED IDEOGRAPH
+0xF0C3 0x9E48 #CJK UNIFIED IDEOGRAPH
+0xF0C4 0x9E49 #CJK UNIFIED IDEOGRAPH
+0xF0C5 0x9E4B #CJK UNIFIED IDEOGRAPH
+0xF0C6 0x9E4C #CJK UNIFIED IDEOGRAPH
+0xF0C7 0x9E4E #CJK UNIFIED IDEOGRAPH
+0xF0C8 0x9E51 #CJK UNIFIED IDEOGRAPH
+0xF0C9 0x9E55 #CJK UNIFIED IDEOGRAPH
+0xF0CA 0x9E57 #CJK UNIFIED IDEOGRAPH
+0xF0CB 0x9E5A #CJK UNIFIED IDEOGRAPH
+0xF0CC 0x9E5B #CJK UNIFIED IDEOGRAPH
+0xF0CD 0x9E5C #CJK UNIFIED IDEOGRAPH
+0xF0CE 0x9E5E #CJK UNIFIED IDEOGRAPH
+0xF0CF 0x9E63 #CJK UNIFIED IDEOGRAPH
+0xF0D0 0x9E66 #CJK UNIFIED IDEOGRAPH
+0xF0D1 0x9E67 #CJK UNIFIED IDEOGRAPH
+0xF0D2 0x9E68 #CJK UNIFIED IDEOGRAPH
+0xF0D3 0x9E69 #CJK UNIFIED IDEOGRAPH
+0xF0D4 0x9E6A #CJK UNIFIED IDEOGRAPH
+0xF0D5 0x9E6B #CJK UNIFIED IDEOGRAPH
+0xF0D6 0x9E6C #CJK UNIFIED IDEOGRAPH
+0xF0D7 0x9E71 #CJK UNIFIED IDEOGRAPH
+0xF0D8 0x9E6D #CJK UNIFIED IDEOGRAPH
+0xF0D9 0x9E73 #CJK UNIFIED IDEOGRAPH
+0xF0DA 0x7592 #CJK UNIFIED IDEOGRAPH
+0xF0DB 0x7594 #CJK UNIFIED IDEOGRAPH
+0xF0DC 0x7596 #CJK UNIFIED IDEOGRAPH
+0xF0DD 0x75A0 #CJK UNIFIED IDEOGRAPH
+0xF0DE 0x759D #CJK UNIFIED IDEOGRAPH
+0xF0DF 0x75AC #CJK UNIFIED IDEOGRAPH
+0xF0E0 0x75A3 #CJK UNIFIED IDEOGRAPH
+0xF0E1 0x75B3 #CJK UNIFIED IDEOGRAPH
+0xF0E2 0x75B4 #CJK UNIFIED IDEOGRAPH
+0xF0E3 0x75B8 #CJK UNIFIED IDEOGRAPH
+0xF0E4 0x75C4 #CJK UNIFIED IDEOGRAPH
+0xF0E5 0x75B1 #CJK UNIFIED IDEOGRAPH
+0xF0E6 0x75B0 #CJK UNIFIED IDEOGRAPH
+0xF0E7 0x75C3 #CJK UNIFIED IDEOGRAPH
+0xF0E8 0x75C2 #CJK UNIFIED IDEOGRAPH
+0xF0E9 0x75D6 #CJK UNIFIED IDEOGRAPH
+0xF0EA 0x75CD #CJK UNIFIED IDEOGRAPH
+0xF0EB 0x75E3 #CJK UNIFIED IDEOGRAPH
+0xF0EC 0x75E8 #CJK UNIFIED IDEOGRAPH
+0xF0ED 0x75E6 #CJK UNIFIED IDEOGRAPH
+0xF0EE 0x75E4 #CJK UNIFIED IDEOGRAPH
+0xF0EF 0x75EB #CJK UNIFIED IDEOGRAPH
+0xF0F0 0x75E7 #CJK UNIFIED IDEOGRAPH
+0xF0F1 0x7603 #CJK UNIFIED IDEOGRAPH
+0xF0F2 0x75F1 #CJK UNIFIED IDEOGRAPH
+0xF0F3 0x75FC #CJK UNIFIED IDEOGRAPH
+0xF0F4 0x75FF #CJK UNIFIED IDEOGRAPH
+0xF0F5 0x7610 #CJK UNIFIED IDEOGRAPH
+0xF0F6 0x7600 #CJK UNIFIED IDEOGRAPH
+0xF0F7 0x7605 #CJK UNIFIED IDEOGRAPH
+0xF0F8 0x760C #CJK UNIFIED IDEOGRAPH
+0xF0F9 0x7617 #CJK UNIFIED IDEOGRAPH
+0xF0FA 0x760A #CJK UNIFIED IDEOGRAPH
+0xF0FB 0x7625 #CJK UNIFIED IDEOGRAPH
+0xF0FC 0x7618 #CJK UNIFIED IDEOGRAPH
+0xF0FD 0x7615 #CJK UNIFIED IDEOGRAPH
+0xF0FE 0x7619 #CJK UNIFIED IDEOGRAPH
+0xF140 0x998C #CJK UNIFIED IDEOGRAPH
+0xF141 0x998E #CJK UNIFIED IDEOGRAPH
+0xF142 0x999A #CJK UNIFIED IDEOGRAPH
+0xF143 0x999B #CJK UNIFIED IDEOGRAPH
+0xF144 0x999C #CJK UNIFIED IDEOGRAPH
+0xF145 0x999D #CJK UNIFIED IDEOGRAPH
+0xF146 0x999E #CJK UNIFIED IDEOGRAPH
+0xF147 0x999F #CJK UNIFIED IDEOGRAPH
+0xF148 0x99A0 #CJK UNIFIED IDEOGRAPH
+0xF149 0x99A1 #CJK UNIFIED IDEOGRAPH
+0xF14A 0x99A2 #CJK UNIFIED IDEOGRAPH
+0xF14B 0x99A3 #CJK UNIFIED IDEOGRAPH
+0xF14C 0x99A4 #CJK UNIFIED IDEOGRAPH
+0xF14D 0x99A6 #CJK UNIFIED IDEOGRAPH
+0xF14E 0x99A7 #CJK UNIFIED IDEOGRAPH
+0xF14F 0x99A9 #CJK UNIFIED IDEOGRAPH
+0xF150 0x99AA #CJK UNIFIED IDEOGRAPH
+0xF151 0x99AB #CJK UNIFIED IDEOGRAPH
+0xF152 0x99AC #CJK UNIFIED IDEOGRAPH
+0xF153 0x99AD #CJK UNIFIED IDEOGRAPH
+0xF154 0x99AE #CJK UNIFIED IDEOGRAPH
+0xF155 0x99AF #CJK UNIFIED IDEOGRAPH
+0xF156 0x99B0 #CJK UNIFIED IDEOGRAPH
+0xF157 0x99B1 #CJK UNIFIED IDEOGRAPH
+0xF158 0x99B2 #CJK UNIFIED IDEOGRAPH
+0xF159 0x99B3 #CJK UNIFIED IDEOGRAPH
+0xF15A 0x99B4 #CJK UNIFIED IDEOGRAPH
+0xF15B 0x99B5 #CJK UNIFIED IDEOGRAPH
+0xF15C 0x99B6 #CJK UNIFIED IDEOGRAPH
+0xF15D 0x99B7 #CJK UNIFIED IDEOGRAPH
+0xF15E 0x99B8 #CJK UNIFIED IDEOGRAPH
+0xF15F 0x99B9 #CJK UNIFIED IDEOGRAPH
+0xF160 0x99BA #CJK UNIFIED IDEOGRAPH
+0xF161 0x99BB #CJK UNIFIED IDEOGRAPH
+0xF162 0x99BC #CJK UNIFIED IDEOGRAPH
+0xF163 0x99BD #CJK UNIFIED IDEOGRAPH
+0xF164 0x99BE #CJK UNIFIED IDEOGRAPH
+0xF165 0x99BF #CJK UNIFIED IDEOGRAPH
+0xF166 0x99C0 #CJK UNIFIED IDEOGRAPH
+0xF167 0x99C1 #CJK UNIFIED IDEOGRAPH
+0xF168 0x99C2 #CJK UNIFIED IDEOGRAPH
+0xF169 0x99C3 #CJK UNIFIED IDEOGRAPH
+0xF16A 0x99C4 #CJK UNIFIED IDEOGRAPH
+0xF16B 0x99C5 #CJK UNIFIED IDEOGRAPH
+0xF16C 0x99C6 #CJK UNIFIED IDEOGRAPH
+0xF16D 0x99C7 #CJK UNIFIED IDEOGRAPH
+0xF16E 0x99C8 #CJK UNIFIED IDEOGRAPH
+0xF16F 0x99C9 #CJK UNIFIED IDEOGRAPH
+0xF170 0x99CA #CJK UNIFIED IDEOGRAPH
+0xF171 0x99CB #CJK UNIFIED IDEOGRAPH
+0xF172 0x99CC #CJK UNIFIED IDEOGRAPH
+0xF173 0x99CD #CJK UNIFIED IDEOGRAPH
+0xF174 0x99CE #CJK UNIFIED IDEOGRAPH
+0xF175 0x99CF #CJK UNIFIED IDEOGRAPH
+0xF176 0x99D0 #CJK UNIFIED IDEOGRAPH
+0xF177 0x99D1 #CJK UNIFIED IDEOGRAPH
+0xF178 0x99D2 #CJK UNIFIED IDEOGRAPH
+0xF179 0x99D3 #CJK UNIFIED IDEOGRAPH
+0xF17A 0x99D4 #CJK UNIFIED IDEOGRAPH
+0xF17B 0x99D5 #CJK UNIFIED IDEOGRAPH
+0xF17C 0x99D6 #CJK UNIFIED IDEOGRAPH
+0xF17D 0x99D7 #CJK UNIFIED IDEOGRAPH
+0xF17E 0x99D8 #CJK UNIFIED IDEOGRAPH
+0xF180 0x99D9 #CJK UNIFIED IDEOGRAPH
+0xF181 0x99DA #CJK UNIFIED IDEOGRAPH
+0xF182 0x99DB #CJK UNIFIED IDEOGRAPH
+0xF183 0x99DC #CJK UNIFIED IDEOGRAPH
+0xF184 0x99DD #CJK UNIFIED IDEOGRAPH
+0xF185 0x99DE #CJK UNIFIED IDEOGRAPH
+0xF186 0x99DF #CJK UNIFIED IDEOGRAPH
+0xF187 0x99E0 #CJK UNIFIED IDEOGRAPH
+0xF188 0x99E1 #CJK UNIFIED IDEOGRAPH
+0xF189 0x99E2 #CJK UNIFIED IDEOGRAPH
+0xF18A 0x99E3 #CJK UNIFIED IDEOGRAPH
+0xF18B 0x99E4 #CJK UNIFIED IDEOGRAPH
+0xF18C 0x99E5 #CJK UNIFIED IDEOGRAPH
+0xF18D 0x99E6 #CJK UNIFIED IDEOGRAPH
+0xF18E 0x99E7 #CJK UNIFIED IDEOGRAPH
+0xF18F 0x99E8 #CJK UNIFIED IDEOGRAPH
+0xF190 0x99E9 #CJK UNIFIED IDEOGRAPH
+0xF191 0x99EA #CJK UNIFIED IDEOGRAPH
+0xF192 0x99EB #CJK UNIFIED IDEOGRAPH
+0xF193 0x99EC #CJK UNIFIED IDEOGRAPH
+0xF194 0x99ED #CJK UNIFIED IDEOGRAPH
+0xF195 0x99EE #CJK UNIFIED IDEOGRAPH
+0xF196 0x99EF #CJK UNIFIED IDEOGRAPH
+0xF197 0x99F0 #CJK UNIFIED IDEOGRAPH
+0xF198 0x99F1 #CJK UNIFIED IDEOGRAPH
+0xF199 0x99F2 #CJK UNIFIED IDEOGRAPH
+0xF19A 0x99F3 #CJK UNIFIED IDEOGRAPH
+0xF19B 0x99F4 #CJK UNIFIED IDEOGRAPH
+0xF19C 0x99F5 #CJK UNIFIED IDEOGRAPH
+0xF19D 0x99F6 #CJK UNIFIED IDEOGRAPH
+0xF19E 0x99F7 #CJK UNIFIED IDEOGRAPH
+0xF19F 0x99F8 #CJK UNIFIED IDEOGRAPH
+0xF1A0 0x99F9 #CJK UNIFIED IDEOGRAPH
+0xF1A1 0x761B #CJK UNIFIED IDEOGRAPH
+0xF1A2 0x763C #CJK UNIFIED IDEOGRAPH
+0xF1A3 0x7622 #CJK UNIFIED IDEOGRAPH
+0xF1A4 0x7620 #CJK UNIFIED IDEOGRAPH
+0xF1A5 0x7640 #CJK UNIFIED IDEOGRAPH
+0xF1A6 0x762D #CJK UNIFIED IDEOGRAPH
+0xF1A7 0x7630 #CJK UNIFIED IDEOGRAPH
+0xF1A8 0x763F #CJK UNIFIED IDEOGRAPH
+0xF1A9 0x7635 #CJK UNIFIED IDEOGRAPH
+0xF1AA 0x7643 #CJK UNIFIED IDEOGRAPH
+0xF1AB 0x763E #CJK UNIFIED IDEOGRAPH
+0xF1AC 0x7633 #CJK UNIFIED IDEOGRAPH
+0xF1AD 0x764D #CJK UNIFIED IDEOGRAPH
+0xF1AE 0x765E #CJK UNIFIED IDEOGRAPH
+0xF1AF 0x7654 #CJK UNIFIED IDEOGRAPH
+0xF1B0 0x765C #CJK UNIFIED IDEOGRAPH
+0xF1B1 0x7656 #CJK UNIFIED IDEOGRAPH
+0xF1B2 0x766B #CJK UNIFIED IDEOGRAPH
+0xF1B3 0x766F #CJK UNIFIED IDEOGRAPH
+0xF1B4 0x7FCA #CJK UNIFIED IDEOGRAPH
+0xF1B5 0x7AE6 #CJK UNIFIED IDEOGRAPH
+0xF1B6 0x7A78 #CJK UNIFIED IDEOGRAPH
+0xF1B7 0x7A79 #CJK UNIFIED IDEOGRAPH
+0xF1B8 0x7A80 #CJK UNIFIED IDEOGRAPH
+0xF1B9 0x7A86 #CJK UNIFIED IDEOGRAPH
+0xF1BA 0x7A88 #CJK UNIFIED IDEOGRAPH
+0xF1BB 0x7A95 #CJK UNIFIED IDEOGRAPH
+0xF1BC 0x7AA6 #CJK UNIFIED IDEOGRAPH
+0xF1BD 0x7AA0 #CJK UNIFIED IDEOGRAPH
+0xF1BE 0x7AAC #CJK UNIFIED IDEOGRAPH
+0xF1BF 0x7AA8 #CJK UNIFIED IDEOGRAPH
+0xF1C0 0x7AAD #CJK UNIFIED IDEOGRAPH
+0xF1C1 0x7AB3 #CJK UNIFIED IDEOGRAPH
+0xF1C2 0x8864 #CJK UNIFIED IDEOGRAPH
+0xF1C3 0x8869 #CJK UNIFIED IDEOGRAPH
+0xF1C4 0x8872 #CJK UNIFIED IDEOGRAPH
+0xF1C5 0x887D #CJK UNIFIED IDEOGRAPH
+0xF1C6 0x887F #CJK UNIFIED IDEOGRAPH
+0xF1C7 0x8882 #CJK UNIFIED IDEOGRAPH
+0xF1C8 0x88A2 #CJK UNIFIED IDEOGRAPH
+0xF1C9 0x88C6 #CJK UNIFIED IDEOGRAPH
+0xF1CA 0x88B7 #CJK UNIFIED IDEOGRAPH
+0xF1CB 0x88BC #CJK UNIFIED IDEOGRAPH
+0xF1CC 0x88C9 #CJK UNIFIED IDEOGRAPH
+0xF1CD 0x88E2 #CJK UNIFIED IDEOGRAPH
+0xF1CE 0x88CE #CJK UNIFIED IDEOGRAPH
+0xF1CF 0x88E3 #CJK UNIFIED IDEOGRAPH
+0xF1D0 0x88E5 #CJK UNIFIED IDEOGRAPH
+0xF1D1 0x88F1 #CJK UNIFIED IDEOGRAPH
+0xF1D2 0x891A #CJK UNIFIED IDEOGRAPH
+0xF1D3 0x88FC #CJK UNIFIED IDEOGRAPH
+0xF1D4 0x88E8 #CJK UNIFIED IDEOGRAPH
+0xF1D5 0x88FE #CJK UNIFIED IDEOGRAPH
+0xF1D6 0x88F0 #CJK UNIFIED IDEOGRAPH
+0xF1D7 0x8921 #CJK UNIFIED IDEOGRAPH
+0xF1D8 0x8919 #CJK UNIFIED IDEOGRAPH
+0xF1D9 0x8913 #CJK UNIFIED IDEOGRAPH
+0xF1DA 0x891B #CJK UNIFIED IDEOGRAPH
+0xF1DB 0x890A #CJK UNIFIED IDEOGRAPH
+0xF1DC 0x8934 #CJK UNIFIED IDEOGRAPH
+0xF1DD 0x892B #CJK UNIFIED IDEOGRAPH
+0xF1DE 0x8936 #CJK UNIFIED IDEOGRAPH
+0xF1DF 0x8941 #CJK UNIFIED IDEOGRAPH
+0xF1E0 0x8966 #CJK UNIFIED IDEOGRAPH
+0xF1E1 0x897B #CJK UNIFIED IDEOGRAPH
+0xF1E2 0x758B #CJK UNIFIED IDEOGRAPH
+0xF1E3 0x80E5 #CJK UNIFIED IDEOGRAPH
+0xF1E4 0x76B2 #CJK UNIFIED IDEOGRAPH
+0xF1E5 0x76B4 #CJK UNIFIED IDEOGRAPH
+0xF1E6 0x77DC #CJK UNIFIED IDEOGRAPH
+0xF1E7 0x8012 #CJK UNIFIED IDEOGRAPH
+0xF1E8 0x8014 #CJK UNIFIED IDEOGRAPH
+0xF1E9 0x8016 #CJK UNIFIED IDEOGRAPH
+0xF1EA 0x801C #CJK UNIFIED IDEOGRAPH
+0xF1EB 0x8020 #CJK UNIFIED IDEOGRAPH
+0xF1EC 0x8022 #CJK UNIFIED IDEOGRAPH
+0xF1ED 0x8025 #CJK UNIFIED IDEOGRAPH
+0xF1EE 0x8026 #CJK UNIFIED IDEOGRAPH
+0xF1EF 0x8027 #CJK UNIFIED IDEOGRAPH
+0xF1F0 0x8029 #CJK UNIFIED IDEOGRAPH
+0xF1F1 0x8028 #CJK UNIFIED IDEOGRAPH
+0xF1F2 0x8031 #CJK UNIFIED IDEOGRAPH
+0xF1F3 0x800B #CJK UNIFIED IDEOGRAPH
+0xF1F4 0x8035 #CJK UNIFIED IDEOGRAPH
+0xF1F5 0x8043 #CJK UNIFIED IDEOGRAPH
+0xF1F6 0x8046 #CJK UNIFIED IDEOGRAPH
+0xF1F7 0x804D #CJK UNIFIED IDEOGRAPH
+0xF1F8 0x8052 #CJK UNIFIED IDEOGRAPH
+0xF1F9 0x8069 #CJK UNIFIED IDEOGRAPH
+0xF1FA 0x8071 #CJK UNIFIED IDEOGRAPH
+0xF1FB 0x8983 #CJK UNIFIED IDEOGRAPH
+0xF1FC 0x9878 #CJK UNIFIED IDEOGRAPH
+0xF1FD 0x9880 #CJK UNIFIED IDEOGRAPH
+0xF1FE 0x9883 #CJK UNIFIED IDEOGRAPH
+0xF240 0x99FA #CJK UNIFIED IDEOGRAPH
+0xF241 0x99FB #CJK UNIFIED IDEOGRAPH
+0xF242 0x99FC #CJK UNIFIED IDEOGRAPH
+0xF243 0x99FD #CJK UNIFIED IDEOGRAPH
+0xF244 0x99FE #CJK UNIFIED IDEOGRAPH
+0xF245 0x99FF #CJK UNIFIED IDEOGRAPH
+0xF246 0x9A00 #CJK UNIFIED IDEOGRAPH
+0xF247 0x9A01 #CJK UNIFIED IDEOGRAPH
+0xF248 0x9A02 #CJK UNIFIED IDEOGRAPH
+0xF249 0x9A03 #CJK UNIFIED IDEOGRAPH
+0xF24A 0x9A04 #CJK UNIFIED IDEOGRAPH
+0xF24B 0x9A05 #CJK UNIFIED IDEOGRAPH
+0xF24C 0x9A06 #CJK UNIFIED IDEOGRAPH
+0xF24D 0x9A07 #CJK UNIFIED IDEOGRAPH
+0xF24E 0x9A08 #CJK UNIFIED IDEOGRAPH
+0xF24F 0x9A09 #CJK UNIFIED IDEOGRAPH
+0xF250 0x9A0A #CJK UNIFIED IDEOGRAPH
+0xF251 0x9A0B #CJK UNIFIED IDEOGRAPH
+0xF252 0x9A0C #CJK UNIFIED IDEOGRAPH
+0xF253 0x9A0D #CJK UNIFIED IDEOGRAPH
+0xF254 0x9A0E #CJK UNIFIED IDEOGRAPH
+0xF255 0x9A0F #CJK UNIFIED IDEOGRAPH
+0xF256 0x9A10 #CJK UNIFIED IDEOGRAPH
+0xF257 0x9A11 #CJK UNIFIED IDEOGRAPH
+0xF258 0x9A12 #CJK UNIFIED IDEOGRAPH
+0xF259 0x9A13 #CJK UNIFIED IDEOGRAPH
+0xF25A 0x9A14 #CJK UNIFIED IDEOGRAPH
+0xF25B 0x9A15 #CJK UNIFIED IDEOGRAPH
+0xF25C 0x9A16 #CJK UNIFIED IDEOGRAPH
+0xF25D 0x9A17 #CJK UNIFIED IDEOGRAPH
+0xF25E 0x9A18 #CJK UNIFIED IDEOGRAPH
+0xF25F 0x9A19 #CJK UNIFIED IDEOGRAPH
+0xF260 0x9A1A #CJK UNIFIED IDEOGRAPH
+0xF261 0x9A1B #CJK UNIFIED IDEOGRAPH
+0xF262 0x9A1C #CJK UNIFIED IDEOGRAPH
+0xF263 0x9A1D #CJK UNIFIED IDEOGRAPH
+0xF264 0x9A1E #CJK UNIFIED IDEOGRAPH
+0xF265 0x9A1F #CJK UNIFIED IDEOGRAPH
+0xF266 0x9A20 #CJK UNIFIED IDEOGRAPH
+0xF267 0x9A21 #CJK UNIFIED IDEOGRAPH
+0xF268 0x9A22 #CJK UNIFIED IDEOGRAPH
+0xF269 0x9A23 #CJK UNIFIED IDEOGRAPH
+0xF26A 0x9A24 #CJK UNIFIED IDEOGRAPH
+0xF26B 0x9A25 #CJK UNIFIED IDEOGRAPH
+0xF26C 0x9A26 #CJK UNIFIED IDEOGRAPH
+0xF26D 0x9A27 #CJK UNIFIED IDEOGRAPH
+0xF26E 0x9A28 #CJK UNIFIED IDEOGRAPH
+0xF26F 0x9A29 #CJK UNIFIED IDEOGRAPH
+0xF270 0x9A2A #CJK UNIFIED IDEOGRAPH
+0xF271 0x9A2B #CJK UNIFIED IDEOGRAPH
+0xF272 0x9A2C #CJK UNIFIED IDEOGRAPH
+0xF273 0x9A2D #CJK UNIFIED IDEOGRAPH
+0xF274 0x9A2E #CJK UNIFIED IDEOGRAPH
+0xF275 0x9A2F #CJK UNIFIED IDEOGRAPH
+0xF276 0x9A30 #CJK UNIFIED IDEOGRAPH
+0xF277 0x9A31 #CJK UNIFIED IDEOGRAPH
+0xF278 0x9A32 #CJK UNIFIED IDEOGRAPH
+0xF279 0x9A33 #CJK UNIFIED IDEOGRAPH
+0xF27A 0x9A34 #CJK UNIFIED IDEOGRAPH
+0xF27B 0x9A35 #CJK UNIFIED IDEOGRAPH
+0xF27C 0x9A36 #CJK UNIFIED IDEOGRAPH
+0xF27D 0x9A37 #CJK UNIFIED IDEOGRAPH
+0xF27E 0x9A38 #CJK UNIFIED IDEOGRAPH
+0xF280 0x9A39 #CJK UNIFIED IDEOGRAPH
+0xF281 0x9A3A #CJK UNIFIED IDEOGRAPH
+0xF282 0x9A3B #CJK UNIFIED IDEOGRAPH
+0xF283 0x9A3C #CJK UNIFIED IDEOGRAPH
+0xF284 0x9A3D #CJK UNIFIED IDEOGRAPH
+0xF285 0x9A3E #CJK UNIFIED IDEOGRAPH
+0xF286 0x9A3F #CJK UNIFIED IDEOGRAPH
+0xF287 0x9A40 #CJK UNIFIED IDEOGRAPH
+0xF288 0x9A41 #CJK UNIFIED IDEOGRAPH
+0xF289 0x9A42 #CJK UNIFIED IDEOGRAPH
+0xF28A 0x9A43 #CJK UNIFIED IDEOGRAPH
+0xF28B 0x9A44 #CJK UNIFIED IDEOGRAPH
+0xF28C 0x9A45 #CJK UNIFIED IDEOGRAPH
+0xF28D 0x9A46 #CJK UNIFIED IDEOGRAPH
+0xF28E 0x9A47 #CJK UNIFIED IDEOGRAPH
+0xF28F 0x9A48 #CJK UNIFIED IDEOGRAPH
+0xF290 0x9A49 #CJK UNIFIED IDEOGRAPH
+0xF291 0x9A4A #CJK UNIFIED IDEOGRAPH
+0xF292 0x9A4B #CJK UNIFIED IDEOGRAPH
+0xF293 0x9A4C #CJK UNIFIED IDEOGRAPH
+0xF294 0x9A4D #CJK UNIFIED IDEOGRAPH
+0xF295 0x9A4E #CJK UNIFIED IDEOGRAPH
+0xF296 0x9A4F #CJK UNIFIED IDEOGRAPH
+0xF297 0x9A50 #CJK UNIFIED IDEOGRAPH
+0xF298 0x9A51 #CJK UNIFIED IDEOGRAPH
+0xF299 0x9A52 #CJK UNIFIED IDEOGRAPH
+0xF29A 0x9A53 #CJK UNIFIED IDEOGRAPH
+0xF29B 0x9A54 #CJK UNIFIED IDEOGRAPH
+0xF29C 0x9A55 #CJK UNIFIED IDEOGRAPH
+0xF29D 0x9A56 #CJK UNIFIED IDEOGRAPH
+0xF29E 0x9A57 #CJK UNIFIED IDEOGRAPH
+0xF29F 0x9A58 #CJK UNIFIED IDEOGRAPH
+0xF2A0 0x9A59 #CJK UNIFIED IDEOGRAPH
+0xF2A1 0x9889 #CJK UNIFIED IDEOGRAPH
+0xF2A2 0x988C #CJK UNIFIED IDEOGRAPH
+0xF2A3 0x988D #CJK UNIFIED IDEOGRAPH
+0xF2A4 0x988F #CJK UNIFIED IDEOGRAPH
+0xF2A5 0x9894 #CJK UNIFIED IDEOGRAPH
+0xF2A6 0x989A #CJK UNIFIED IDEOGRAPH
+0xF2A7 0x989B #CJK UNIFIED IDEOGRAPH
+0xF2A8 0x989E #CJK UNIFIED IDEOGRAPH
+0xF2A9 0x989F #CJK UNIFIED IDEOGRAPH
+0xF2AA 0x98A1 #CJK UNIFIED IDEOGRAPH
+0xF2AB 0x98A2 #CJK UNIFIED IDEOGRAPH
+0xF2AC 0x98A5 #CJK UNIFIED IDEOGRAPH
+0xF2AD 0x98A6 #CJK UNIFIED IDEOGRAPH
+0xF2AE 0x864D #CJK UNIFIED IDEOGRAPH
+0xF2AF 0x8654 #CJK UNIFIED IDEOGRAPH
+0xF2B0 0x866C #CJK UNIFIED IDEOGRAPH
+0xF2B1 0x866E #CJK UNIFIED IDEOGRAPH
+0xF2B2 0x867F #CJK UNIFIED IDEOGRAPH
+0xF2B3 0x867A #CJK UNIFIED IDEOGRAPH
+0xF2B4 0x867C #CJK UNIFIED IDEOGRAPH
+0xF2B5 0x867B #CJK UNIFIED IDEOGRAPH
+0xF2B6 0x86A8 #CJK UNIFIED IDEOGRAPH
+0xF2B7 0x868D #CJK UNIFIED IDEOGRAPH
+0xF2B8 0x868B #CJK UNIFIED IDEOGRAPH
+0xF2B9 0x86AC #CJK UNIFIED IDEOGRAPH
+0xF2BA 0x869D #CJK UNIFIED IDEOGRAPH
+0xF2BB 0x86A7 #CJK UNIFIED IDEOGRAPH
+0xF2BC 0x86A3 #CJK UNIFIED IDEOGRAPH
+0xF2BD 0x86AA #CJK UNIFIED IDEOGRAPH
+0xF2BE 0x8693 #CJK UNIFIED IDEOGRAPH
+0xF2BF 0x86A9 #CJK UNIFIED IDEOGRAPH
+0xF2C0 0x86B6 #CJK UNIFIED IDEOGRAPH
+0xF2C1 0x86C4 #CJK UNIFIED IDEOGRAPH
+0xF2C2 0x86B5 #CJK UNIFIED IDEOGRAPH
+0xF2C3 0x86CE #CJK UNIFIED IDEOGRAPH
+0xF2C4 0x86B0 #CJK UNIFIED IDEOGRAPH
+0xF2C5 0x86BA #CJK UNIFIED IDEOGRAPH
+0xF2C6 0x86B1 #CJK UNIFIED IDEOGRAPH
+0xF2C7 0x86AF #CJK UNIFIED IDEOGRAPH
+0xF2C8 0x86C9 #CJK UNIFIED IDEOGRAPH
+0xF2C9 0x86CF #CJK UNIFIED IDEOGRAPH
+0xF2CA 0x86B4 #CJK UNIFIED IDEOGRAPH
+0xF2CB 0x86E9 #CJK UNIFIED IDEOGRAPH
+0xF2CC 0x86F1 #CJK UNIFIED IDEOGRAPH
+0xF2CD 0x86F2 #CJK UNIFIED IDEOGRAPH
+0xF2CE 0x86ED #CJK UNIFIED IDEOGRAPH
+0xF2CF 0x86F3 #CJK UNIFIED IDEOGRAPH
+0xF2D0 0x86D0 #CJK UNIFIED IDEOGRAPH
+0xF2D1 0x8713 #CJK UNIFIED IDEOGRAPH
+0xF2D2 0x86DE #CJK UNIFIED IDEOGRAPH
+0xF2D3 0x86F4 #CJK UNIFIED IDEOGRAPH
+0xF2D4 0x86DF #CJK UNIFIED IDEOGRAPH
+0xF2D5 0x86D8 #CJK UNIFIED IDEOGRAPH
+0xF2D6 0x86D1 #CJK UNIFIED IDEOGRAPH
+0xF2D7 0x8703 #CJK UNIFIED IDEOGRAPH
+0xF2D8 0x8707 #CJK UNIFIED IDEOGRAPH
+0xF2D9 0x86F8 #CJK UNIFIED IDEOGRAPH
+0xF2DA 0x8708 #CJK UNIFIED IDEOGRAPH
+0xF2DB 0x870A #CJK UNIFIED IDEOGRAPH
+0xF2DC 0x870D #CJK UNIFIED IDEOGRAPH
+0xF2DD 0x8709 #CJK UNIFIED IDEOGRAPH
+0xF2DE 0x8723 #CJK UNIFIED IDEOGRAPH
+0xF2DF 0x873B #CJK UNIFIED IDEOGRAPH
+0xF2E0 0x871E #CJK UNIFIED IDEOGRAPH
+0xF2E1 0x8725 #CJK UNIFIED IDEOGRAPH
+0xF2E2 0x872E #CJK UNIFIED IDEOGRAPH
+0xF2E3 0x871A #CJK UNIFIED IDEOGRAPH
+0xF2E4 0x873E #CJK UNIFIED IDEOGRAPH
+0xF2E5 0x8748 #CJK UNIFIED IDEOGRAPH
+0xF2E6 0x8734 #CJK UNIFIED IDEOGRAPH
+0xF2E7 0x8731 #CJK UNIFIED IDEOGRAPH
+0xF2E8 0x8729 #CJK UNIFIED IDEOGRAPH
+0xF2E9 0x8737 #CJK UNIFIED IDEOGRAPH
+0xF2EA 0x873F #CJK UNIFIED IDEOGRAPH
+0xF2EB 0x8782 #CJK UNIFIED IDEOGRAPH
+0xF2EC 0x8722 #CJK UNIFIED IDEOGRAPH
+0xF2ED 0x877D #CJK UNIFIED IDEOGRAPH
+0xF2EE 0x877E #CJK UNIFIED IDEOGRAPH
+0xF2EF 0x877B #CJK UNIFIED IDEOGRAPH
+0xF2F0 0x8760 #CJK UNIFIED IDEOGRAPH
+0xF2F1 0x8770 #CJK UNIFIED IDEOGRAPH
+0xF2F2 0x874C #CJK UNIFIED IDEOGRAPH
+0xF2F3 0x876E #CJK UNIFIED IDEOGRAPH
+0xF2F4 0x878B #CJK UNIFIED IDEOGRAPH
+0xF2F5 0x8753 #CJK UNIFIED IDEOGRAPH
+0xF2F6 0x8763 #CJK UNIFIED IDEOGRAPH
+0xF2F7 0x877C #CJK UNIFIED IDEOGRAPH
+0xF2F8 0x8764 #CJK UNIFIED IDEOGRAPH
+0xF2F9 0x8759 #CJK UNIFIED IDEOGRAPH
+0xF2FA 0x8765 #CJK UNIFIED IDEOGRAPH
+0xF2FB 0x8793 #CJK UNIFIED IDEOGRAPH
+0xF2FC 0x87AF #CJK UNIFIED IDEOGRAPH
+0xF2FD 0x87A8 #CJK UNIFIED IDEOGRAPH
+0xF2FE 0x87D2 #CJK UNIFIED IDEOGRAPH
+0xF340 0x9A5A #CJK UNIFIED IDEOGRAPH
+0xF341 0x9A5B #CJK UNIFIED IDEOGRAPH
+0xF342 0x9A5C #CJK UNIFIED IDEOGRAPH
+0xF343 0x9A5D #CJK UNIFIED IDEOGRAPH
+0xF344 0x9A5E #CJK UNIFIED IDEOGRAPH
+0xF345 0x9A5F #CJK UNIFIED IDEOGRAPH
+0xF346 0x9A60 #CJK UNIFIED IDEOGRAPH
+0xF347 0x9A61 #CJK UNIFIED IDEOGRAPH
+0xF348 0x9A62 #CJK UNIFIED IDEOGRAPH
+0xF349 0x9A63 #CJK UNIFIED IDEOGRAPH
+0xF34A 0x9A64 #CJK UNIFIED IDEOGRAPH
+0xF34B 0x9A65 #CJK UNIFIED IDEOGRAPH
+0xF34C 0x9A66 #CJK UNIFIED IDEOGRAPH
+0xF34D 0x9A67 #CJK UNIFIED IDEOGRAPH
+0xF34E 0x9A68 #CJK UNIFIED IDEOGRAPH
+0xF34F 0x9A69 #CJK UNIFIED IDEOGRAPH
+0xF350 0x9A6A #CJK UNIFIED IDEOGRAPH
+0xF351 0x9A6B #CJK UNIFIED IDEOGRAPH
+0xF352 0x9A72 #CJK UNIFIED IDEOGRAPH
+0xF353 0x9A83 #CJK UNIFIED IDEOGRAPH
+0xF354 0x9A89 #CJK UNIFIED IDEOGRAPH
+0xF355 0x9A8D #CJK UNIFIED IDEOGRAPH
+0xF356 0x9A8E #CJK UNIFIED IDEOGRAPH
+0xF357 0x9A94 #CJK UNIFIED IDEOGRAPH
+0xF358 0x9A95 #CJK UNIFIED IDEOGRAPH
+0xF359 0x9A99 #CJK UNIFIED IDEOGRAPH
+0xF35A 0x9AA6 #CJK UNIFIED IDEOGRAPH
+0xF35B 0x9AA9 #CJK UNIFIED IDEOGRAPH
+0xF35C 0x9AAA #CJK UNIFIED IDEOGRAPH
+0xF35D 0x9AAB #CJK UNIFIED IDEOGRAPH
+0xF35E 0x9AAC #CJK UNIFIED IDEOGRAPH
+0xF35F 0x9AAD #CJK UNIFIED IDEOGRAPH
+0xF360 0x9AAE #CJK UNIFIED IDEOGRAPH
+0xF361 0x9AAF #CJK UNIFIED IDEOGRAPH
+0xF362 0x9AB2 #CJK UNIFIED IDEOGRAPH
+0xF363 0x9AB3 #CJK UNIFIED IDEOGRAPH
+0xF364 0x9AB4 #CJK UNIFIED IDEOGRAPH
+0xF365 0x9AB5 #CJK UNIFIED IDEOGRAPH
+0xF366 0x9AB9 #CJK UNIFIED IDEOGRAPH
+0xF367 0x9ABB #CJK UNIFIED IDEOGRAPH
+0xF368 0x9ABD #CJK UNIFIED IDEOGRAPH
+0xF369 0x9ABE #CJK UNIFIED IDEOGRAPH
+0xF36A 0x9ABF #CJK UNIFIED IDEOGRAPH
+0xF36B 0x9AC3 #CJK UNIFIED IDEOGRAPH
+0xF36C 0x9AC4 #CJK UNIFIED IDEOGRAPH
+0xF36D 0x9AC6 #CJK UNIFIED IDEOGRAPH
+0xF36E 0x9AC7 #CJK UNIFIED IDEOGRAPH
+0xF36F 0x9AC8 #CJK UNIFIED IDEOGRAPH
+0xF370 0x9AC9 #CJK UNIFIED IDEOGRAPH
+0xF371 0x9ACA #CJK UNIFIED IDEOGRAPH
+0xF372 0x9ACD #CJK UNIFIED IDEOGRAPH
+0xF373 0x9ACE #CJK UNIFIED IDEOGRAPH
+0xF374 0x9ACF #CJK UNIFIED IDEOGRAPH
+0xF375 0x9AD0 #CJK UNIFIED IDEOGRAPH
+0xF376 0x9AD2 #CJK UNIFIED IDEOGRAPH
+0xF377 0x9AD4 #CJK UNIFIED IDEOGRAPH
+0xF378 0x9AD5 #CJK UNIFIED IDEOGRAPH
+0xF379 0x9AD6 #CJK UNIFIED IDEOGRAPH
+0xF37A 0x9AD7 #CJK UNIFIED IDEOGRAPH
+0xF37B 0x9AD9 #CJK UNIFIED IDEOGRAPH
+0xF37C 0x9ADA #CJK UNIFIED IDEOGRAPH
+0xF37D 0x9ADB #CJK UNIFIED IDEOGRAPH
+0xF37E 0x9ADC #CJK UNIFIED IDEOGRAPH
+0xF380 0x9ADD #CJK UNIFIED IDEOGRAPH
+0xF381 0x9ADE #CJK UNIFIED IDEOGRAPH
+0xF382 0x9AE0 #CJK UNIFIED IDEOGRAPH
+0xF383 0x9AE2 #CJK UNIFIED IDEOGRAPH
+0xF384 0x9AE3 #CJK UNIFIED IDEOGRAPH
+0xF385 0x9AE4 #CJK UNIFIED IDEOGRAPH
+0xF386 0x9AE5 #CJK UNIFIED IDEOGRAPH
+0xF387 0x9AE7 #CJK UNIFIED IDEOGRAPH
+0xF388 0x9AE8 #CJK UNIFIED IDEOGRAPH
+0xF389 0x9AE9 #CJK UNIFIED IDEOGRAPH
+0xF38A 0x9AEA #CJK UNIFIED IDEOGRAPH
+0xF38B 0x9AEC #CJK UNIFIED IDEOGRAPH
+0xF38C 0x9AEE #CJK UNIFIED IDEOGRAPH
+0xF38D 0x9AF0 #CJK UNIFIED IDEOGRAPH
+0xF38E 0x9AF1 #CJK UNIFIED IDEOGRAPH
+0xF38F 0x9AF2 #CJK UNIFIED IDEOGRAPH
+0xF390 0x9AF3 #CJK UNIFIED IDEOGRAPH
+0xF391 0x9AF4 #CJK UNIFIED IDEOGRAPH
+0xF392 0x9AF5 #CJK UNIFIED IDEOGRAPH
+0xF393 0x9AF6 #CJK UNIFIED IDEOGRAPH
+0xF394 0x9AF7 #CJK UNIFIED IDEOGRAPH
+0xF395 0x9AF8 #CJK UNIFIED IDEOGRAPH
+0xF396 0x9AFA #CJK UNIFIED IDEOGRAPH
+0xF397 0x9AFC #CJK UNIFIED IDEOGRAPH
+0xF398 0x9AFD #CJK UNIFIED IDEOGRAPH
+0xF399 0x9AFE #CJK UNIFIED IDEOGRAPH
+0xF39A 0x9AFF #CJK UNIFIED IDEOGRAPH
+0xF39B 0x9B00 #CJK UNIFIED IDEOGRAPH
+0xF39C 0x9B01 #CJK UNIFIED IDEOGRAPH
+0xF39D 0x9B02 #CJK UNIFIED IDEOGRAPH
+0xF39E 0x9B04 #CJK UNIFIED IDEOGRAPH
+0xF39F 0x9B05 #CJK UNIFIED IDEOGRAPH
+0xF3A0 0x9B06 #CJK UNIFIED IDEOGRAPH
+0xF3A1 0x87C6 #CJK UNIFIED IDEOGRAPH
+0xF3A2 0x8788 #CJK UNIFIED IDEOGRAPH
+0xF3A3 0x8785 #CJK UNIFIED IDEOGRAPH
+0xF3A4 0x87AD #CJK UNIFIED IDEOGRAPH
+0xF3A5 0x8797 #CJK UNIFIED IDEOGRAPH
+0xF3A6 0x8783 #CJK UNIFIED IDEOGRAPH
+0xF3A7 0x87AB #CJK UNIFIED IDEOGRAPH
+0xF3A8 0x87E5 #CJK UNIFIED IDEOGRAPH
+0xF3A9 0x87AC #CJK UNIFIED IDEOGRAPH
+0xF3AA 0x87B5 #CJK UNIFIED IDEOGRAPH
+0xF3AB 0x87B3 #CJK UNIFIED IDEOGRAPH
+0xF3AC 0x87CB #CJK UNIFIED IDEOGRAPH
+0xF3AD 0x87D3 #CJK UNIFIED IDEOGRAPH
+0xF3AE 0x87BD #CJK UNIFIED IDEOGRAPH
+0xF3AF 0x87D1 #CJK UNIFIED IDEOGRAPH
+0xF3B0 0x87C0 #CJK UNIFIED IDEOGRAPH
+0xF3B1 0x87CA #CJK UNIFIED IDEOGRAPH
+0xF3B2 0x87DB #CJK UNIFIED IDEOGRAPH
+0xF3B3 0x87EA #CJK UNIFIED IDEOGRAPH
+0xF3B4 0x87E0 #CJK UNIFIED IDEOGRAPH
+0xF3B5 0x87EE #CJK UNIFIED IDEOGRAPH
+0xF3B6 0x8816 #CJK UNIFIED IDEOGRAPH
+0xF3B7 0x8813 #CJK UNIFIED IDEOGRAPH
+0xF3B8 0x87FE #CJK UNIFIED IDEOGRAPH
+0xF3B9 0x880A #CJK UNIFIED IDEOGRAPH
+0xF3BA 0x881B #CJK UNIFIED IDEOGRAPH
+0xF3BB 0x8821 #CJK UNIFIED IDEOGRAPH
+0xF3BC 0x8839 #CJK UNIFIED IDEOGRAPH
+0xF3BD 0x883C #CJK UNIFIED IDEOGRAPH
+0xF3BE 0x7F36 #CJK UNIFIED IDEOGRAPH
+0xF3BF 0x7F42 #CJK UNIFIED IDEOGRAPH
+0xF3C0 0x7F44 #CJK UNIFIED IDEOGRAPH
+0xF3C1 0x7F45 #CJK UNIFIED IDEOGRAPH
+0xF3C2 0x8210 #CJK UNIFIED IDEOGRAPH
+0xF3C3 0x7AFA #CJK UNIFIED IDEOGRAPH
+0xF3C4 0x7AFD #CJK UNIFIED IDEOGRAPH
+0xF3C5 0x7B08 #CJK UNIFIED IDEOGRAPH
+0xF3C6 0x7B03 #CJK UNIFIED IDEOGRAPH
+0xF3C7 0x7B04 #CJK UNIFIED IDEOGRAPH
+0xF3C8 0x7B15 #CJK UNIFIED IDEOGRAPH
+0xF3C9 0x7B0A #CJK UNIFIED IDEOGRAPH
+0xF3CA 0x7B2B #CJK UNIFIED IDEOGRAPH
+0xF3CB 0x7B0F #CJK UNIFIED IDEOGRAPH
+0xF3CC 0x7B47 #CJK UNIFIED IDEOGRAPH
+0xF3CD 0x7B38 #CJK UNIFIED IDEOGRAPH
+0xF3CE 0x7B2A #CJK UNIFIED IDEOGRAPH
+0xF3CF 0x7B19 #CJK UNIFIED IDEOGRAPH
+0xF3D0 0x7B2E #CJK UNIFIED IDEOGRAPH
+0xF3D1 0x7B31 #CJK UNIFIED IDEOGRAPH
+0xF3D2 0x7B20 #CJK UNIFIED IDEOGRAPH
+0xF3D3 0x7B25 #CJK UNIFIED IDEOGRAPH
+0xF3D4 0x7B24 #CJK UNIFIED IDEOGRAPH
+0xF3D5 0x7B33 #CJK UNIFIED IDEOGRAPH
+0xF3D6 0x7B3E #CJK UNIFIED IDEOGRAPH
+0xF3D7 0x7B1E #CJK UNIFIED IDEOGRAPH
+0xF3D8 0x7B58 #CJK UNIFIED IDEOGRAPH
+0xF3D9 0x7B5A #CJK UNIFIED IDEOGRAPH
+0xF3DA 0x7B45 #CJK UNIFIED IDEOGRAPH
+0xF3DB 0x7B75 #CJK UNIFIED IDEOGRAPH
+0xF3DC 0x7B4C #CJK UNIFIED IDEOGRAPH
+0xF3DD 0x7B5D #CJK UNIFIED IDEOGRAPH
+0xF3DE 0x7B60 #CJK UNIFIED IDEOGRAPH
+0xF3DF 0x7B6E #CJK UNIFIED IDEOGRAPH
+0xF3E0 0x7B7B #CJK UNIFIED IDEOGRAPH
+0xF3E1 0x7B62 #CJK UNIFIED IDEOGRAPH
+0xF3E2 0x7B72 #CJK UNIFIED IDEOGRAPH
+0xF3E3 0x7B71 #CJK UNIFIED IDEOGRAPH
+0xF3E4 0x7B90 #CJK UNIFIED IDEOGRAPH
+0xF3E5 0x7BA6 #CJK UNIFIED IDEOGRAPH
+0xF3E6 0x7BA7 #CJK UNIFIED IDEOGRAPH
+0xF3E7 0x7BB8 #CJK UNIFIED IDEOGRAPH
+0xF3E8 0x7BAC #CJK UNIFIED IDEOGRAPH
+0xF3E9 0x7B9D #CJK UNIFIED IDEOGRAPH
+0xF3EA 0x7BA8 #CJK UNIFIED IDEOGRAPH
+0xF3EB 0x7B85 #CJK UNIFIED IDEOGRAPH
+0xF3EC 0x7BAA #CJK UNIFIED IDEOGRAPH
+0xF3ED 0x7B9C #CJK UNIFIED IDEOGRAPH
+0xF3EE 0x7BA2 #CJK UNIFIED IDEOGRAPH
+0xF3EF 0x7BAB #CJK UNIFIED IDEOGRAPH
+0xF3F0 0x7BB4 #CJK UNIFIED IDEOGRAPH
+0xF3F1 0x7BD1 #CJK UNIFIED IDEOGRAPH
+0xF3F2 0x7BC1 #CJK UNIFIED IDEOGRAPH
+0xF3F3 0x7BCC #CJK UNIFIED IDEOGRAPH
+0xF3F4 0x7BDD #CJK UNIFIED IDEOGRAPH
+0xF3F5 0x7BDA #CJK UNIFIED IDEOGRAPH
+0xF3F6 0x7BE5 #CJK UNIFIED IDEOGRAPH
+0xF3F7 0x7BE6 #CJK UNIFIED IDEOGRAPH
+0xF3F8 0x7BEA #CJK UNIFIED IDEOGRAPH
+0xF3F9 0x7C0C #CJK UNIFIED IDEOGRAPH
+0xF3FA 0x7BFE #CJK UNIFIED IDEOGRAPH
+0xF3FB 0x7BFC #CJK UNIFIED IDEOGRAPH
+0xF3FC 0x7C0F #CJK UNIFIED IDEOGRAPH
+0xF3FD 0x7C16 #CJK UNIFIED IDEOGRAPH
+0xF3FE 0x7C0B #CJK UNIFIED IDEOGRAPH
+0xF440 0x9B07 #CJK UNIFIED IDEOGRAPH
+0xF441 0x9B09 #CJK UNIFIED IDEOGRAPH
+0xF442 0x9B0A #CJK UNIFIED IDEOGRAPH
+0xF443 0x9B0B #CJK UNIFIED IDEOGRAPH
+0xF444 0x9B0C #CJK UNIFIED IDEOGRAPH
+0xF445 0x9B0D #CJK UNIFIED IDEOGRAPH
+0xF446 0x9B0E #CJK UNIFIED IDEOGRAPH
+0xF447 0x9B10 #CJK UNIFIED IDEOGRAPH
+0xF448 0x9B11 #CJK UNIFIED IDEOGRAPH
+0xF449 0x9B12 #CJK UNIFIED IDEOGRAPH
+0xF44A 0x9B14 #CJK UNIFIED IDEOGRAPH
+0xF44B 0x9B15 #CJK UNIFIED IDEOGRAPH
+0xF44C 0x9B16 #CJK UNIFIED IDEOGRAPH
+0xF44D 0x9B17 #CJK UNIFIED IDEOGRAPH
+0xF44E 0x9B18 #CJK UNIFIED IDEOGRAPH
+0xF44F 0x9B19 #CJK UNIFIED IDEOGRAPH
+0xF450 0x9B1A #CJK UNIFIED IDEOGRAPH
+0xF451 0x9B1B #CJK UNIFIED IDEOGRAPH
+0xF452 0x9B1C #CJK UNIFIED IDEOGRAPH
+0xF453 0x9B1D #CJK UNIFIED IDEOGRAPH
+0xF454 0x9B1E #CJK UNIFIED IDEOGRAPH
+0xF455 0x9B20 #CJK UNIFIED IDEOGRAPH
+0xF456 0x9B21 #CJK UNIFIED IDEOGRAPH
+0xF457 0x9B22 #CJK UNIFIED IDEOGRAPH
+0xF458 0x9B24 #CJK UNIFIED IDEOGRAPH
+0xF459 0x9B25 #CJK UNIFIED IDEOGRAPH
+0xF45A 0x9B26 #CJK UNIFIED IDEOGRAPH
+0xF45B 0x9B27 #CJK UNIFIED IDEOGRAPH
+0xF45C 0x9B28 #CJK UNIFIED IDEOGRAPH
+0xF45D 0x9B29 #CJK UNIFIED IDEOGRAPH
+0xF45E 0x9B2A #CJK UNIFIED IDEOGRAPH
+0xF45F 0x9B2B #CJK UNIFIED IDEOGRAPH
+0xF460 0x9B2C #CJK UNIFIED IDEOGRAPH
+0xF461 0x9B2D #CJK UNIFIED IDEOGRAPH
+0xF462 0x9B2E #CJK UNIFIED IDEOGRAPH
+0xF463 0x9B30 #CJK UNIFIED IDEOGRAPH
+0xF464 0x9B31 #CJK UNIFIED IDEOGRAPH
+0xF465 0x9B33 #CJK UNIFIED IDEOGRAPH
+0xF466 0x9B34 #CJK UNIFIED IDEOGRAPH
+0xF467 0x9B35 #CJK UNIFIED IDEOGRAPH
+0xF468 0x9B36 #CJK UNIFIED IDEOGRAPH
+0xF469 0x9B37 #CJK UNIFIED IDEOGRAPH
+0xF46A 0x9B38 #CJK UNIFIED IDEOGRAPH
+0xF46B 0x9B39 #CJK UNIFIED IDEOGRAPH
+0xF46C 0x9B3A #CJK UNIFIED IDEOGRAPH
+0xF46D 0x9B3D #CJK UNIFIED IDEOGRAPH
+0xF46E 0x9B3E #CJK UNIFIED IDEOGRAPH
+0xF46F 0x9B3F #CJK UNIFIED IDEOGRAPH
+0xF470 0x9B40 #CJK UNIFIED IDEOGRAPH
+0xF471 0x9B46 #CJK UNIFIED IDEOGRAPH
+0xF472 0x9B4A #CJK UNIFIED IDEOGRAPH
+0xF473 0x9B4B #CJK UNIFIED IDEOGRAPH
+0xF474 0x9B4C #CJK UNIFIED IDEOGRAPH
+0xF475 0x9B4E #CJK UNIFIED IDEOGRAPH
+0xF476 0x9B50 #CJK UNIFIED IDEOGRAPH
+0xF477 0x9B52 #CJK UNIFIED IDEOGRAPH
+0xF478 0x9B53 #CJK UNIFIED IDEOGRAPH
+0xF479 0x9B55 #CJK UNIFIED IDEOGRAPH
+0xF47A 0x9B56 #CJK UNIFIED IDEOGRAPH
+0xF47B 0x9B57 #CJK UNIFIED IDEOGRAPH
+0xF47C 0x9B58 #CJK UNIFIED IDEOGRAPH
+0xF47D 0x9B59 #CJK UNIFIED IDEOGRAPH
+0xF47E 0x9B5A #CJK UNIFIED IDEOGRAPH
+0xF480 0x9B5B #CJK UNIFIED IDEOGRAPH
+0xF481 0x9B5C #CJK UNIFIED IDEOGRAPH
+0xF482 0x9B5D #CJK UNIFIED IDEOGRAPH
+0xF483 0x9B5E #CJK UNIFIED IDEOGRAPH
+0xF484 0x9B5F #CJK UNIFIED IDEOGRAPH
+0xF485 0x9B60 #CJK UNIFIED IDEOGRAPH
+0xF486 0x9B61 #CJK UNIFIED IDEOGRAPH
+0xF487 0x9B62 #CJK UNIFIED IDEOGRAPH
+0xF488 0x9B63 #CJK UNIFIED IDEOGRAPH
+0xF489 0x9B64 #CJK UNIFIED IDEOGRAPH
+0xF48A 0x9B65 #CJK UNIFIED IDEOGRAPH
+0xF48B 0x9B66 #CJK UNIFIED IDEOGRAPH
+0xF48C 0x9B67 #CJK UNIFIED IDEOGRAPH
+0xF48D 0x9B68 #CJK UNIFIED IDEOGRAPH
+0xF48E 0x9B69 #CJK UNIFIED IDEOGRAPH
+0xF48F 0x9B6A #CJK UNIFIED IDEOGRAPH
+0xF490 0x9B6B #CJK UNIFIED IDEOGRAPH
+0xF491 0x9B6C #CJK UNIFIED IDEOGRAPH
+0xF492 0x9B6D #CJK UNIFIED IDEOGRAPH
+0xF493 0x9B6E #CJK UNIFIED IDEOGRAPH
+0xF494 0x9B6F #CJK UNIFIED IDEOGRAPH
+0xF495 0x9B70 #CJK UNIFIED IDEOGRAPH
+0xF496 0x9B71 #CJK UNIFIED IDEOGRAPH
+0xF497 0x9B72 #CJK UNIFIED IDEOGRAPH
+0xF498 0x9B73 #CJK UNIFIED IDEOGRAPH
+0xF499 0x9B74 #CJK UNIFIED IDEOGRAPH
+0xF49A 0x9B75 #CJK UNIFIED IDEOGRAPH
+0xF49B 0x9B76 #CJK UNIFIED IDEOGRAPH
+0xF49C 0x9B77 #CJK UNIFIED IDEOGRAPH
+0xF49D 0x9B78 #CJK UNIFIED IDEOGRAPH
+0xF49E 0x9B79 #CJK UNIFIED IDEOGRAPH
+0xF49F 0x9B7A #CJK UNIFIED IDEOGRAPH
+0xF4A0 0x9B7B #CJK UNIFIED IDEOGRAPH
+0xF4A1 0x7C1F #CJK UNIFIED IDEOGRAPH
+0xF4A2 0x7C2A #CJK UNIFIED IDEOGRAPH
+0xF4A3 0x7C26 #CJK UNIFIED IDEOGRAPH
+0xF4A4 0x7C38 #CJK UNIFIED IDEOGRAPH
+0xF4A5 0x7C41 #CJK UNIFIED IDEOGRAPH
+0xF4A6 0x7C40 #CJK UNIFIED IDEOGRAPH
+0xF4A7 0x81FE #CJK UNIFIED IDEOGRAPH
+0xF4A8 0x8201 #CJK UNIFIED IDEOGRAPH
+0xF4A9 0x8202 #CJK UNIFIED IDEOGRAPH
+0xF4AA 0x8204 #CJK UNIFIED IDEOGRAPH
+0xF4AB 0x81EC #CJK UNIFIED IDEOGRAPH
+0xF4AC 0x8844 #CJK UNIFIED IDEOGRAPH
+0xF4AD 0x8221 #CJK UNIFIED IDEOGRAPH
+0xF4AE 0x8222 #CJK UNIFIED IDEOGRAPH
+0xF4AF 0x8223 #CJK UNIFIED IDEOGRAPH
+0xF4B0 0x822D #CJK UNIFIED IDEOGRAPH
+0xF4B1 0x822F #CJK UNIFIED IDEOGRAPH
+0xF4B2 0x8228 #CJK UNIFIED IDEOGRAPH
+0xF4B3 0x822B #CJK UNIFIED IDEOGRAPH
+0xF4B4 0x8238 #CJK UNIFIED IDEOGRAPH
+0xF4B5 0x823B #CJK UNIFIED IDEOGRAPH
+0xF4B6 0x8233 #CJK UNIFIED IDEOGRAPH
+0xF4B7 0x8234 #CJK UNIFIED IDEOGRAPH
+0xF4B8 0x823E #CJK UNIFIED IDEOGRAPH
+0xF4B9 0x8244 #CJK UNIFIED IDEOGRAPH
+0xF4BA 0x8249 #CJK UNIFIED IDEOGRAPH
+0xF4BB 0x824B #CJK UNIFIED IDEOGRAPH
+0xF4BC 0x824F #CJK UNIFIED IDEOGRAPH
+0xF4BD 0x825A #CJK UNIFIED IDEOGRAPH
+0xF4BE 0x825F #CJK UNIFIED IDEOGRAPH
+0xF4BF 0x8268 #CJK UNIFIED IDEOGRAPH
+0xF4C0 0x887E #CJK UNIFIED IDEOGRAPH
+0xF4C1 0x8885 #CJK UNIFIED IDEOGRAPH
+0xF4C2 0x8888 #CJK UNIFIED IDEOGRAPH
+0xF4C3 0x88D8 #CJK UNIFIED IDEOGRAPH
+0xF4C4 0x88DF #CJK UNIFIED IDEOGRAPH
+0xF4C5 0x895E #CJK UNIFIED IDEOGRAPH
+0xF4C6 0x7F9D #CJK UNIFIED IDEOGRAPH
+0xF4C7 0x7F9F #CJK UNIFIED IDEOGRAPH
+0xF4C8 0x7FA7 #CJK UNIFIED IDEOGRAPH
+0xF4C9 0x7FAF #CJK UNIFIED IDEOGRAPH
+0xF4CA 0x7FB0 #CJK UNIFIED IDEOGRAPH
+0xF4CB 0x7FB2 #CJK UNIFIED IDEOGRAPH
+0xF4CC 0x7C7C #CJK UNIFIED IDEOGRAPH
+0xF4CD 0x6549 #CJK UNIFIED IDEOGRAPH
+0xF4CE 0x7C91 #CJK UNIFIED IDEOGRAPH
+0xF4CF 0x7C9D #CJK UNIFIED IDEOGRAPH
+0xF4D0 0x7C9C #CJK UNIFIED IDEOGRAPH
+0xF4D1 0x7C9E #CJK UNIFIED IDEOGRAPH
+0xF4D2 0x7CA2 #CJK UNIFIED IDEOGRAPH
+0xF4D3 0x7CB2 #CJK UNIFIED IDEOGRAPH
+0xF4D4 0x7CBC #CJK UNIFIED IDEOGRAPH
+0xF4D5 0x7CBD #CJK UNIFIED IDEOGRAPH
+0xF4D6 0x7CC1 #CJK UNIFIED IDEOGRAPH
+0xF4D7 0x7CC7 #CJK UNIFIED IDEOGRAPH
+0xF4D8 0x7CCC #CJK UNIFIED IDEOGRAPH
+0xF4D9 0x7CCD #CJK UNIFIED IDEOGRAPH
+0xF4DA 0x7CC8 #CJK UNIFIED IDEOGRAPH
+0xF4DB 0x7CC5 #CJK UNIFIED IDEOGRAPH
+0xF4DC 0x7CD7 #CJK UNIFIED IDEOGRAPH
+0xF4DD 0x7CE8 #CJK UNIFIED IDEOGRAPH
+0xF4DE 0x826E #CJK UNIFIED IDEOGRAPH
+0xF4DF 0x66A8 #CJK UNIFIED IDEOGRAPH
+0xF4E0 0x7FBF #CJK UNIFIED IDEOGRAPH
+0xF4E1 0x7FCE #CJK UNIFIED IDEOGRAPH
+0xF4E2 0x7FD5 #CJK UNIFIED IDEOGRAPH
+0xF4E3 0x7FE5 #CJK UNIFIED IDEOGRAPH
+0xF4E4 0x7FE1 #CJK UNIFIED IDEOGRAPH
+0xF4E5 0x7FE6 #CJK UNIFIED IDEOGRAPH
+0xF4E6 0x7FE9 #CJK UNIFIED IDEOGRAPH
+0xF4E7 0x7FEE #CJK UNIFIED IDEOGRAPH
+0xF4E8 0x7FF3 #CJK UNIFIED IDEOGRAPH
+0xF4E9 0x7CF8 #CJK UNIFIED IDEOGRAPH
+0xF4EA 0x7D77 #CJK UNIFIED IDEOGRAPH
+0xF4EB 0x7DA6 #CJK UNIFIED IDEOGRAPH
+0xF4EC 0x7DAE #CJK UNIFIED IDEOGRAPH
+0xF4ED 0x7E47 #CJK UNIFIED IDEOGRAPH
+0xF4EE 0x7E9B #CJK UNIFIED IDEOGRAPH
+0xF4EF 0x9EB8 #CJK UNIFIED IDEOGRAPH
+0xF4F0 0x9EB4 #CJK UNIFIED IDEOGRAPH
+0xF4F1 0x8D73 #CJK UNIFIED IDEOGRAPH
+0xF4F2 0x8D84 #CJK UNIFIED IDEOGRAPH
+0xF4F3 0x8D94 #CJK UNIFIED IDEOGRAPH
+0xF4F4 0x8D91 #CJK UNIFIED IDEOGRAPH
+0xF4F5 0x8DB1 #CJK UNIFIED IDEOGRAPH
+0xF4F6 0x8D67 #CJK UNIFIED IDEOGRAPH
+0xF4F7 0x8D6D #CJK UNIFIED IDEOGRAPH
+0xF4F8 0x8C47 #CJK UNIFIED IDEOGRAPH
+0xF4F9 0x8C49 #CJK UNIFIED IDEOGRAPH
+0xF4FA 0x914A #CJK UNIFIED IDEOGRAPH
+0xF4FB 0x9150 #CJK UNIFIED IDEOGRAPH
+0xF4FC 0x914E #CJK UNIFIED IDEOGRAPH
+0xF4FD 0x914F #CJK UNIFIED IDEOGRAPH
+0xF4FE 0x9164 #CJK UNIFIED IDEOGRAPH
+0xF540 0x9B7C #CJK UNIFIED IDEOGRAPH
+0xF541 0x9B7D #CJK UNIFIED IDEOGRAPH
+0xF542 0x9B7E #CJK UNIFIED IDEOGRAPH
+0xF543 0x9B7F #CJK UNIFIED IDEOGRAPH
+0xF544 0x9B80 #CJK UNIFIED IDEOGRAPH
+0xF545 0x9B81 #CJK UNIFIED IDEOGRAPH
+0xF546 0x9B82 #CJK UNIFIED IDEOGRAPH
+0xF547 0x9B83 #CJK UNIFIED IDEOGRAPH
+0xF548 0x9B84 #CJK UNIFIED IDEOGRAPH
+0xF549 0x9B85 #CJK UNIFIED IDEOGRAPH
+0xF54A 0x9B86 #CJK UNIFIED IDEOGRAPH
+0xF54B 0x9B87 #CJK UNIFIED IDEOGRAPH
+0xF54C 0x9B88 #CJK UNIFIED IDEOGRAPH
+0xF54D 0x9B89 #CJK UNIFIED IDEOGRAPH
+0xF54E 0x9B8A #CJK UNIFIED IDEOGRAPH
+0xF54F 0x9B8B #CJK UNIFIED IDEOGRAPH
+0xF550 0x9B8C #CJK UNIFIED IDEOGRAPH
+0xF551 0x9B8D #CJK UNIFIED IDEOGRAPH
+0xF552 0x9B8E #CJK UNIFIED IDEOGRAPH
+0xF553 0x9B8F #CJK UNIFIED IDEOGRAPH
+0xF554 0x9B90 #CJK UNIFIED IDEOGRAPH
+0xF555 0x9B91 #CJK UNIFIED IDEOGRAPH
+0xF556 0x9B92 #CJK UNIFIED IDEOGRAPH
+0xF557 0x9B93 #CJK UNIFIED IDEOGRAPH
+0xF558 0x9B94 #CJK UNIFIED IDEOGRAPH
+0xF559 0x9B95 #CJK UNIFIED IDEOGRAPH
+0xF55A 0x9B96 #CJK UNIFIED IDEOGRAPH
+0xF55B 0x9B97 #CJK UNIFIED IDEOGRAPH
+0xF55C 0x9B98 #CJK UNIFIED IDEOGRAPH
+0xF55D 0x9B99 #CJK UNIFIED IDEOGRAPH
+0xF55E 0x9B9A #CJK UNIFIED IDEOGRAPH
+0xF55F 0x9B9B #CJK UNIFIED IDEOGRAPH
+0xF560 0x9B9C #CJK UNIFIED IDEOGRAPH
+0xF561 0x9B9D #CJK UNIFIED IDEOGRAPH
+0xF562 0x9B9E #CJK UNIFIED IDEOGRAPH
+0xF563 0x9B9F #CJK UNIFIED IDEOGRAPH
+0xF564 0x9BA0 #CJK UNIFIED IDEOGRAPH
+0xF565 0x9BA1 #CJK UNIFIED IDEOGRAPH
+0xF566 0x9BA2 #CJK UNIFIED IDEOGRAPH
+0xF567 0x9BA3 #CJK UNIFIED IDEOGRAPH
+0xF568 0x9BA4 #CJK UNIFIED IDEOGRAPH
+0xF569 0x9BA5 #CJK UNIFIED IDEOGRAPH
+0xF56A 0x9BA6 #CJK UNIFIED IDEOGRAPH
+0xF56B 0x9BA7 #CJK UNIFIED IDEOGRAPH
+0xF56C 0x9BA8 #CJK UNIFIED IDEOGRAPH
+0xF56D 0x9BA9 #CJK UNIFIED IDEOGRAPH
+0xF56E 0x9BAA #CJK UNIFIED IDEOGRAPH
+0xF56F 0x9BAB #CJK UNIFIED IDEOGRAPH
+0xF570 0x9BAC #CJK UNIFIED IDEOGRAPH
+0xF571 0x9BAD #CJK UNIFIED IDEOGRAPH
+0xF572 0x9BAE #CJK UNIFIED IDEOGRAPH
+0xF573 0x9BAF #CJK UNIFIED IDEOGRAPH
+0xF574 0x9BB0 #CJK UNIFIED IDEOGRAPH
+0xF575 0x9BB1 #CJK UNIFIED IDEOGRAPH
+0xF576 0x9BB2 #CJK UNIFIED IDEOGRAPH
+0xF577 0x9BB3 #CJK UNIFIED IDEOGRAPH
+0xF578 0x9BB4 #CJK UNIFIED IDEOGRAPH
+0xF579 0x9BB5 #CJK UNIFIED IDEOGRAPH
+0xF57A 0x9BB6 #CJK UNIFIED IDEOGRAPH
+0xF57B 0x9BB7 #CJK UNIFIED IDEOGRAPH
+0xF57C 0x9BB8 #CJK UNIFIED IDEOGRAPH
+0xF57D 0x9BB9 #CJK UNIFIED IDEOGRAPH
+0xF57E 0x9BBA #CJK UNIFIED IDEOGRAPH
+0xF580 0x9BBB #CJK UNIFIED IDEOGRAPH
+0xF581 0x9BBC #CJK UNIFIED IDEOGRAPH
+0xF582 0x9BBD #CJK UNIFIED IDEOGRAPH
+0xF583 0x9BBE #CJK UNIFIED IDEOGRAPH
+0xF584 0x9BBF #CJK UNIFIED IDEOGRAPH
+0xF585 0x9BC0 #CJK UNIFIED IDEOGRAPH
+0xF586 0x9BC1 #CJK UNIFIED IDEOGRAPH
+0xF587 0x9BC2 #CJK UNIFIED IDEOGRAPH
+0xF588 0x9BC3 #CJK UNIFIED IDEOGRAPH
+0xF589 0x9BC4 #CJK UNIFIED IDEOGRAPH
+0xF58A 0x9BC5 #CJK UNIFIED IDEOGRAPH
+0xF58B 0x9BC6 #CJK UNIFIED IDEOGRAPH
+0xF58C 0x9BC7 #CJK UNIFIED IDEOGRAPH
+0xF58D 0x9BC8 #CJK UNIFIED IDEOGRAPH
+0xF58E 0x9BC9 #CJK UNIFIED IDEOGRAPH
+0xF58F 0x9BCA #CJK UNIFIED IDEOGRAPH
+0xF590 0x9BCB #CJK UNIFIED IDEOGRAPH
+0xF591 0x9BCC #CJK UNIFIED IDEOGRAPH
+0xF592 0x9BCD #CJK UNIFIED IDEOGRAPH
+0xF593 0x9BCE #CJK UNIFIED IDEOGRAPH
+0xF594 0x9BCF #CJK UNIFIED IDEOGRAPH
+0xF595 0x9BD0 #CJK UNIFIED IDEOGRAPH
+0xF596 0x9BD1 #CJK UNIFIED IDEOGRAPH
+0xF597 0x9BD2 #CJK UNIFIED IDEOGRAPH
+0xF598 0x9BD3 #CJK UNIFIED IDEOGRAPH
+0xF599 0x9BD4 #CJK UNIFIED IDEOGRAPH
+0xF59A 0x9BD5 #CJK UNIFIED IDEOGRAPH
+0xF59B 0x9BD6 #CJK UNIFIED IDEOGRAPH
+0xF59C 0x9BD7 #CJK UNIFIED IDEOGRAPH
+0xF59D 0x9BD8 #CJK UNIFIED IDEOGRAPH
+0xF59E 0x9BD9 #CJK UNIFIED IDEOGRAPH
+0xF59F 0x9BDA #CJK UNIFIED IDEOGRAPH
+0xF5A0 0x9BDB #CJK UNIFIED IDEOGRAPH
+0xF5A1 0x9162 #CJK UNIFIED IDEOGRAPH
+0xF5A2 0x9161 #CJK UNIFIED IDEOGRAPH
+0xF5A3 0x9170 #CJK UNIFIED IDEOGRAPH
+0xF5A4 0x9169 #CJK UNIFIED IDEOGRAPH
+0xF5A5 0x916F #CJK UNIFIED IDEOGRAPH
+0xF5A6 0x917D #CJK UNIFIED IDEOGRAPH
+0xF5A7 0x917E #CJK UNIFIED IDEOGRAPH
+0xF5A8 0x9172 #CJK UNIFIED IDEOGRAPH
+0xF5A9 0x9174 #CJK UNIFIED IDEOGRAPH
+0xF5AA 0x9179 #CJK UNIFIED IDEOGRAPH
+0xF5AB 0x918C #CJK UNIFIED IDEOGRAPH
+0xF5AC 0x9185 #CJK UNIFIED IDEOGRAPH
+0xF5AD 0x9190 #CJK UNIFIED IDEOGRAPH
+0xF5AE 0x918D #CJK UNIFIED IDEOGRAPH
+0xF5AF 0x9191 #CJK UNIFIED IDEOGRAPH
+0xF5B0 0x91A2 #CJK UNIFIED IDEOGRAPH
+0xF5B1 0x91A3 #CJK UNIFIED IDEOGRAPH
+0xF5B2 0x91AA #CJK UNIFIED IDEOGRAPH
+0xF5B3 0x91AD #CJK UNIFIED IDEOGRAPH
+0xF5B4 0x91AE #CJK UNIFIED IDEOGRAPH
+0xF5B5 0x91AF #CJK UNIFIED IDEOGRAPH
+0xF5B6 0x91B5 #CJK UNIFIED IDEOGRAPH
+0xF5B7 0x91B4 #CJK UNIFIED IDEOGRAPH
+0xF5B8 0x91BA #CJK UNIFIED IDEOGRAPH
+0xF5B9 0x8C55 #CJK UNIFIED IDEOGRAPH
+0xF5BA 0x9E7E #CJK UNIFIED IDEOGRAPH
+0xF5BB 0x8DB8 #CJK UNIFIED IDEOGRAPH
+0xF5BC 0x8DEB #CJK UNIFIED IDEOGRAPH
+0xF5BD 0x8E05 #CJK UNIFIED IDEOGRAPH
+0xF5BE 0x8E59 #CJK UNIFIED IDEOGRAPH
+0xF5BF 0x8E69 #CJK UNIFIED IDEOGRAPH
+0xF5C0 0x8DB5 #CJK UNIFIED IDEOGRAPH
+0xF5C1 0x8DBF #CJK UNIFIED IDEOGRAPH
+0xF5C2 0x8DBC #CJK UNIFIED IDEOGRAPH
+0xF5C3 0x8DBA #CJK UNIFIED IDEOGRAPH
+0xF5C4 0x8DC4 #CJK UNIFIED IDEOGRAPH
+0xF5C5 0x8DD6 #CJK UNIFIED IDEOGRAPH
+0xF5C6 0x8DD7 #CJK UNIFIED IDEOGRAPH
+0xF5C7 0x8DDA #CJK UNIFIED IDEOGRAPH
+0xF5C8 0x8DDE #CJK UNIFIED IDEOGRAPH
+0xF5C9 0x8DCE #CJK UNIFIED IDEOGRAPH
+0xF5CA 0x8DCF #CJK UNIFIED IDEOGRAPH
+0xF5CB 0x8DDB #CJK UNIFIED IDEOGRAPH
+0xF5CC 0x8DC6 #CJK UNIFIED IDEOGRAPH
+0xF5CD 0x8DEC #CJK UNIFIED IDEOGRAPH
+0xF5CE 0x8DF7 #CJK UNIFIED IDEOGRAPH
+0xF5CF 0x8DF8 #CJK UNIFIED IDEOGRAPH
+0xF5D0 0x8DE3 #CJK UNIFIED IDEOGRAPH
+0xF5D1 0x8DF9 #CJK UNIFIED IDEOGRAPH
+0xF5D2 0x8DFB #CJK UNIFIED IDEOGRAPH
+0xF5D3 0x8DE4 #CJK UNIFIED IDEOGRAPH
+0xF5D4 0x8E09 #CJK UNIFIED IDEOGRAPH
+0xF5D5 0x8DFD #CJK UNIFIED IDEOGRAPH
+0xF5D6 0x8E14 #CJK UNIFIED IDEOGRAPH
+0xF5D7 0x8E1D #CJK UNIFIED IDEOGRAPH
+0xF5D8 0x8E1F #CJK UNIFIED IDEOGRAPH
+0xF5D9 0x8E2C #CJK UNIFIED IDEOGRAPH
+0xF5DA 0x8E2E #CJK UNIFIED IDEOGRAPH
+0xF5DB 0x8E23 #CJK UNIFIED IDEOGRAPH
+0xF5DC 0x8E2F #CJK UNIFIED IDEOGRAPH
+0xF5DD 0x8E3A #CJK UNIFIED IDEOGRAPH
+0xF5DE 0x8E40 #CJK UNIFIED IDEOGRAPH
+0xF5DF 0x8E39 #CJK UNIFIED IDEOGRAPH
+0xF5E0 0x8E35 #CJK UNIFIED IDEOGRAPH
+0xF5E1 0x8E3D #CJK UNIFIED IDEOGRAPH
+0xF5E2 0x8E31 #CJK UNIFIED IDEOGRAPH
+0xF5E3 0x8E49 #CJK UNIFIED IDEOGRAPH
+0xF5E4 0x8E41 #CJK UNIFIED IDEOGRAPH
+0xF5E5 0x8E42 #CJK UNIFIED IDEOGRAPH
+0xF5E6 0x8E51 #CJK UNIFIED IDEOGRAPH
+0xF5E7 0x8E52 #CJK UNIFIED IDEOGRAPH
+0xF5E8 0x8E4A #CJK UNIFIED IDEOGRAPH
+0xF5E9 0x8E70 #CJK UNIFIED IDEOGRAPH
+0xF5EA 0x8E76 #CJK UNIFIED IDEOGRAPH
+0xF5EB 0x8E7C #CJK UNIFIED IDEOGRAPH
+0xF5EC 0x8E6F #CJK UNIFIED IDEOGRAPH
+0xF5ED 0x8E74 #CJK UNIFIED IDEOGRAPH
+0xF5EE 0x8E85 #CJK UNIFIED IDEOGRAPH
+0xF5EF 0x8E8F #CJK UNIFIED IDEOGRAPH
+0xF5F0 0x8E94 #CJK UNIFIED IDEOGRAPH
+0xF5F1 0x8E90 #CJK UNIFIED IDEOGRAPH
+0xF5F2 0x8E9C #CJK UNIFIED IDEOGRAPH
+0xF5F3 0x8E9E #CJK UNIFIED IDEOGRAPH
+0xF5F4 0x8C78 #CJK UNIFIED IDEOGRAPH
+0xF5F5 0x8C82 #CJK UNIFIED IDEOGRAPH
+0xF5F6 0x8C8A #CJK UNIFIED IDEOGRAPH
+0xF5F7 0x8C85 #CJK UNIFIED IDEOGRAPH
+0xF5F8 0x8C98 #CJK UNIFIED IDEOGRAPH
+0xF5F9 0x8C94 #CJK UNIFIED IDEOGRAPH
+0xF5FA 0x659B #CJK UNIFIED IDEOGRAPH
+0xF5FB 0x89D6 #CJK UNIFIED IDEOGRAPH
+0xF5FC 0x89DE #CJK UNIFIED IDEOGRAPH
+0xF5FD 0x89DA #CJK UNIFIED IDEOGRAPH
+0xF5FE 0x89DC #CJK UNIFIED IDEOGRAPH
+0xF640 0x9BDC #CJK UNIFIED IDEOGRAPH
+0xF641 0x9BDD #CJK UNIFIED IDEOGRAPH
+0xF642 0x9BDE #CJK UNIFIED IDEOGRAPH
+0xF643 0x9BDF #CJK UNIFIED IDEOGRAPH
+0xF644 0x9BE0 #CJK UNIFIED IDEOGRAPH
+0xF645 0x9BE1 #CJK UNIFIED IDEOGRAPH
+0xF646 0x9BE2 #CJK UNIFIED IDEOGRAPH
+0xF647 0x9BE3 #CJK UNIFIED IDEOGRAPH
+0xF648 0x9BE4 #CJK UNIFIED IDEOGRAPH
+0xF649 0x9BE5 #CJK UNIFIED IDEOGRAPH
+0xF64A 0x9BE6 #CJK UNIFIED IDEOGRAPH
+0xF64B 0x9BE7 #CJK UNIFIED IDEOGRAPH
+0xF64C 0x9BE8 #CJK UNIFIED IDEOGRAPH
+0xF64D 0x9BE9 #CJK UNIFIED IDEOGRAPH
+0xF64E 0x9BEA #CJK UNIFIED IDEOGRAPH
+0xF64F 0x9BEB #CJK UNIFIED IDEOGRAPH
+0xF650 0x9BEC #CJK UNIFIED IDEOGRAPH
+0xF651 0x9BED #CJK UNIFIED IDEOGRAPH
+0xF652 0x9BEE #CJK UNIFIED IDEOGRAPH
+0xF653 0x9BEF #CJK UNIFIED IDEOGRAPH
+0xF654 0x9BF0 #CJK UNIFIED IDEOGRAPH
+0xF655 0x9BF1 #CJK UNIFIED IDEOGRAPH
+0xF656 0x9BF2 #CJK UNIFIED IDEOGRAPH
+0xF657 0x9BF3 #CJK UNIFIED IDEOGRAPH
+0xF658 0x9BF4 #CJK UNIFIED IDEOGRAPH
+0xF659 0x9BF5 #CJK UNIFIED IDEOGRAPH
+0xF65A 0x9BF6 #CJK UNIFIED IDEOGRAPH
+0xF65B 0x9BF7 #CJK UNIFIED IDEOGRAPH
+0xF65C 0x9BF8 #CJK UNIFIED IDEOGRAPH
+0xF65D 0x9BF9 #CJK UNIFIED IDEOGRAPH
+0xF65E 0x9BFA #CJK UNIFIED IDEOGRAPH
+0xF65F 0x9BFB #CJK UNIFIED IDEOGRAPH
+0xF660 0x9BFC #CJK UNIFIED IDEOGRAPH
+0xF661 0x9BFD #CJK UNIFIED IDEOGRAPH
+0xF662 0x9BFE #CJK UNIFIED IDEOGRAPH
+0xF663 0x9BFF #CJK UNIFIED IDEOGRAPH
+0xF664 0x9C00 #CJK UNIFIED IDEOGRAPH
+0xF665 0x9C01 #CJK UNIFIED IDEOGRAPH
+0xF666 0x9C02 #CJK UNIFIED IDEOGRAPH
+0xF667 0x9C03 #CJK UNIFIED IDEOGRAPH
+0xF668 0x9C04 #CJK UNIFIED IDEOGRAPH
+0xF669 0x9C05 #CJK UNIFIED IDEOGRAPH
+0xF66A 0x9C06 #CJK UNIFIED IDEOGRAPH
+0xF66B 0x9C07 #CJK UNIFIED IDEOGRAPH
+0xF66C 0x9C08 #CJK UNIFIED IDEOGRAPH
+0xF66D 0x9C09 #CJK UNIFIED IDEOGRAPH
+0xF66E 0x9C0A #CJK UNIFIED IDEOGRAPH
+0xF66F 0x9C0B #CJK UNIFIED IDEOGRAPH
+0xF670 0x9C0C #CJK UNIFIED IDEOGRAPH
+0xF671 0x9C0D #CJK UNIFIED IDEOGRAPH
+0xF672 0x9C0E #CJK UNIFIED IDEOGRAPH
+0xF673 0x9C0F #CJK UNIFIED IDEOGRAPH
+0xF674 0x9C10 #CJK UNIFIED IDEOGRAPH
+0xF675 0x9C11 #CJK UNIFIED IDEOGRAPH
+0xF676 0x9C12 #CJK UNIFIED IDEOGRAPH
+0xF677 0x9C13 #CJK UNIFIED IDEOGRAPH
+0xF678 0x9C14 #CJK UNIFIED IDEOGRAPH
+0xF679 0x9C15 #CJK UNIFIED IDEOGRAPH
+0xF67A 0x9C16 #CJK UNIFIED IDEOGRAPH
+0xF67B 0x9C17 #CJK UNIFIED IDEOGRAPH
+0xF67C 0x9C18 #CJK UNIFIED IDEOGRAPH
+0xF67D 0x9C19 #CJK UNIFIED IDEOGRAPH
+0xF67E 0x9C1A #CJK UNIFIED IDEOGRAPH
+0xF680 0x9C1B #CJK UNIFIED IDEOGRAPH
+0xF681 0x9C1C #CJK UNIFIED IDEOGRAPH
+0xF682 0x9C1D #CJK UNIFIED IDEOGRAPH
+0xF683 0x9C1E #CJK UNIFIED IDEOGRAPH
+0xF684 0x9C1F #CJK UNIFIED IDEOGRAPH
+0xF685 0x9C20 #CJK UNIFIED IDEOGRAPH
+0xF686 0x9C21 #CJK UNIFIED IDEOGRAPH
+0xF687 0x9C22 #CJK UNIFIED IDEOGRAPH
+0xF688 0x9C23 #CJK UNIFIED IDEOGRAPH
+0xF689 0x9C24 #CJK UNIFIED IDEOGRAPH
+0xF68A 0x9C25 #CJK UNIFIED IDEOGRAPH
+0xF68B 0x9C26 #CJK UNIFIED IDEOGRAPH
+0xF68C 0x9C27 #CJK UNIFIED IDEOGRAPH
+0xF68D 0x9C28 #CJK UNIFIED IDEOGRAPH
+0xF68E 0x9C29 #CJK UNIFIED IDEOGRAPH
+0xF68F 0x9C2A #CJK UNIFIED IDEOGRAPH
+0xF690 0x9C2B #CJK UNIFIED IDEOGRAPH
+0xF691 0x9C2C #CJK UNIFIED IDEOGRAPH
+0xF692 0x9C2D #CJK UNIFIED IDEOGRAPH
+0xF693 0x9C2E #CJK UNIFIED IDEOGRAPH
+0xF694 0x9C2F #CJK UNIFIED IDEOGRAPH
+0xF695 0x9C30 #CJK UNIFIED IDEOGRAPH
+0xF696 0x9C31 #CJK UNIFIED IDEOGRAPH
+0xF697 0x9C32 #CJK UNIFIED IDEOGRAPH
+0xF698 0x9C33 #CJK UNIFIED IDEOGRAPH
+0xF699 0x9C34 #CJK UNIFIED IDEOGRAPH
+0xF69A 0x9C35 #CJK UNIFIED IDEOGRAPH
+0xF69B 0x9C36 #CJK UNIFIED IDEOGRAPH
+0xF69C 0x9C37 #CJK UNIFIED IDEOGRAPH
+0xF69D 0x9C38 #CJK UNIFIED IDEOGRAPH
+0xF69E 0x9C39 #CJK UNIFIED IDEOGRAPH
+0xF69F 0x9C3A #CJK UNIFIED IDEOGRAPH
+0xF6A0 0x9C3B #CJK UNIFIED IDEOGRAPH
+0xF6A1 0x89E5 #CJK UNIFIED IDEOGRAPH
+0xF6A2 0x89EB #CJK UNIFIED IDEOGRAPH
+0xF6A3 0x89EF #CJK UNIFIED IDEOGRAPH
+0xF6A4 0x8A3E #CJK UNIFIED IDEOGRAPH
+0xF6A5 0x8B26 #CJK UNIFIED IDEOGRAPH
+0xF6A6 0x9753 #CJK UNIFIED IDEOGRAPH
+0xF6A7 0x96E9 #CJK UNIFIED IDEOGRAPH
+0xF6A8 0x96F3 #CJK UNIFIED IDEOGRAPH
+0xF6A9 0x96EF #CJK UNIFIED IDEOGRAPH
+0xF6AA 0x9706 #CJK UNIFIED IDEOGRAPH
+0xF6AB 0x9701 #CJK UNIFIED IDEOGRAPH
+0xF6AC 0x9708 #CJK UNIFIED IDEOGRAPH
+0xF6AD 0x970F #CJK UNIFIED IDEOGRAPH
+0xF6AE 0x970E #CJK UNIFIED IDEOGRAPH
+0xF6AF 0x972A #CJK UNIFIED IDEOGRAPH
+0xF6B0 0x972D #CJK UNIFIED IDEOGRAPH
+0xF6B1 0x9730 #CJK UNIFIED IDEOGRAPH
+0xF6B2 0x973E #CJK UNIFIED IDEOGRAPH
+0xF6B3 0x9F80 #CJK UNIFIED IDEOGRAPH
+0xF6B4 0x9F83 #CJK UNIFIED IDEOGRAPH
+0xF6B5 0x9F85 #CJK UNIFIED IDEOGRAPH
+0xF6B6 0x9F86 #CJK UNIFIED IDEOGRAPH
+0xF6B7 0x9F87 #CJK UNIFIED IDEOGRAPH
+0xF6B8 0x9F88 #CJK UNIFIED IDEOGRAPH
+0xF6B9 0x9F89 #CJK UNIFIED IDEOGRAPH
+0xF6BA 0x9F8A #CJK UNIFIED IDEOGRAPH
+0xF6BB 0x9F8C #CJK UNIFIED IDEOGRAPH
+0xF6BC 0x9EFE #CJK UNIFIED IDEOGRAPH
+0xF6BD 0x9F0B #CJK UNIFIED IDEOGRAPH
+0xF6BE 0x9F0D #CJK UNIFIED IDEOGRAPH
+0xF6BF 0x96B9 #CJK UNIFIED IDEOGRAPH
+0xF6C0 0x96BC #CJK UNIFIED IDEOGRAPH
+0xF6C1 0x96BD #CJK UNIFIED IDEOGRAPH
+0xF6C2 0x96CE #CJK UNIFIED IDEOGRAPH
+0xF6C3 0x96D2 #CJK UNIFIED IDEOGRAPH
+0xF6C4 0x77BF #CJK UNIFIED IDEOGRAPH
+0xF6C5 0x96E0 #CJK UNIFIED IDEOGRAPH
+0xF6C6 0x928E #CJK UNIFIED IDEOGRAPH
+0xF6C7 0x92AE #CJK UNIFIED IDEOGRAPH
+0xF6C8 0x92C8 #CJK UNIFIED IDEOGRAPH
+0xF6C9 0x933E #CJK UNIFIED IDEOGRAPH
+0xF6CA 0x936A #CJK UNIFIED IDEOGRAPH
+0xF6CB 0x93CA #CJK UNIFIED IDEOGRAPH
+0xF6CC 0x938F #CJK UNIFIED IDEOGRAPH
+0xF6CD 0x943E #CJK UNIFIED IDEOGRAPH
+0xF6CE 0x946B #CJK UNIFIED IDEOGRAPH
+0xF6CF 0x9C7F #CJK UNIFIED IDEOGRAPH
+0xF6D0 0x9C82 #CJK UNIFIED IDEOGRAPH
+0xF6D1 0x9C85 #CJK UNIFIED IDEOGRAPH
+0xF6D2 0x9C86 #CJK UNIFIED IDEOGRAPH
+0xF6D3 0x9C87 #CJK UNIFIED IDEOGRAPH
+0xF6D4 0x9C88 #CJK UNIFIED IDEOGRAPH
+0xF6D5 0x7A23 #CJK UNIFIED IDEOGRAPH
+0xF6D6 0x9C8B #CJK UNIFIED IDEOGRAPH
+0xF6D7 0x9C8E #CJK UNIFIED IDEOGRAPH
+0xF6D8 0x9C90 #CJK UNIFIED IDEOGRAPH
+0xF6D9 0x9C91 #CJK UNIFIED IDEOGRAPH
+0xF6DA 0x9C92 #CJK UNIFIED IDEOGRAPH
+0xF6DB 0x9C94 #CJK UNIFIED IDEOGRAPH
+0xF6DC 0x9C95 #CJK UNIFIED IDEOGRAPH
+0xF6DD 0x9C9A #CJK UNIFIED IDEOGRAPH
+0xF6DE 0x9C9B #CJK UNIFIED IDEOGRAPH
+0xF6DF 0x9C9E #CJK UNIFIED IDEOGRAPH
+0xF6E0 0x9C9F #CJK UNIFIED IDEOGRAPH
+0xF6E1 0x9CA0 #CJK UNIFIED IDEOGRAPH
+0xF6E2 0x9CA1 #CJK UNIFIED IDEOGRAPH
+0xF6E3 0x9CA2 #CJK UNIFIED IDEOGRAPH
+0xF6E4 0x9CA3 #CJK UNIFIED IDEOGRAPH
+0xF6E5 0x9CA5 #CJK UNIFIED IDEOGRAPH
+0xF6E6 0x9CA6 #CJK UNIFIED IDEOGRAPH
+0xF6E7 0x9CA7 #CJK UNIFIED IDEOGRAPH
+0xF6E8 0x9CA8 #CJK UNIFIED IDEOGRAPH
+0xF6E9 0x9CA9 #CJK UNIFIED IDEOGRAPH
+0xF6EA 0x9CAB #CJK UNIFIED IDEOGRAPH
+0xF6EB 0x9CAD #CJK UNIFIED IDEOGRAPH
+0xF6EC 0x9CAE #CJK UNIFIED IDEOGRAPH
+0xF6ED 0x9CB0 #CJK UNIFIED IDEOGRAPH
+0xF6EE 0x9CB1 #CJK UNIFIED IDEOGRAPH
+0xF6EF 0x9CB2 #CJK UNIFIED IDEOGRAPH
+0xF6F0 0x9CB3 #CJK UNIFIED IDEOGRAPH
+0xF6F1 0x9CB4 #CJK UNIFIED IDEOGRAPH
+0xF6F2 0x9CB5 #CJK UNIFIED IDEOGRAPH
+0xF6F3 0x9CB6 #CJK UNIFIED IDEOGRAPH
+0xF6F4 0x9CB7 #CJK UNIFIED IDEOGRAPH
+0xF6F5 0x9CBA #CJK UNIFIED IDEOGRAPH
+0xF6F6 0x9CBB #CJK UNIFIED IDEOGRAPH
+0xF6F7 0x9CBC #CJK UNIFIED IDEOGRAPH
+0xF6F8 0x9CBD #CJK UNIFIED IDEOGRAPH
+0xF6F9 0x9CC4 #CJK UNIFIED IDEOGRAPH
+0xF6FA 0x9CC5 #CJK UNIFIED IDEOGRAPH
+0xF6FB 0x9CC6 #CJK UNIFIED IDEOGRAPH
+0xF6FC 0x9CC7 #CJK UNIFIED IDEOGRAPH
+0xF6FD 0x9CCA #CJK UNIFIED IDEOGRAPH
+0xF6FE 0x9CCB #CJK UNIFIED IDEOGRAPH
+0xF740 0x9C3C #CJK UNIFIED IDEOGRAPH
+0xF741 0x9C3D #CJK UNIFIED IDEOGRAPH
+0xF742 0x9C3E #CJK UNIFIED IDEOGRAPH
+0xF743 0x9C3F #CJK UNIFIED IDEOGRAPH
+0xF744 0x9C40 #CJK UNIFIED IDEOGRAPH
+0xF745 0x9C41 #CJK UNIFIED IDEOGRAPH
+0xF746 0x9C42 #CJK UNIFIED IDEOGRAPH
+0xF747 0x9C43 #CJK UNIFIED IDEOGRAPH
+0xF748 0x9C44 #CJK UNIFIED IDEOGRAPH
+0xF749 0x9C45 #CJK UNIFIED IDEOGRAPH
+0xF74A 0x9C46 #CJK UNIFIED IDEOGRAPH
+0xF74B 0x9C47 #CJK UNIFIED IDEOGRAPH
+0xF74C 0x9C48 #CJK UNIFIED IDEOGRAPH
+0xF74D 0x9C49 #CJK UNIFIED IDEOGRAPH
+0xF74E 0x9C4A #CJK UNIFIED IDEOGRAPH
+0xF74F 0x9C4B #CJK UNIFIED IDEOGRAPH
+0xF750 0x9C4C #CJK UNIFIED IDEOGRAPH
+0xF751 0x9C4D #CJK UNIFIED IDEOGRAPH
+0xF752 0x9C4E #CJK UNIFIED IDEOGRAPH
+0xF753 0x9C4F #CJK UNIFIED IDEOGRAPH
+0xF754 0x9C50 #CJK UNIFIED IDEOGRAPH
+0xF755 0x9C51 #CJK UNIFIED IDEOGRAPH
+0xF756 0x9C52 #CJK UNIFIED IDEOGRAPH
+0xF757 0x9C53 #CJK UNIFIED IDEOGRAPH
+0xF758 0x9C54 #CJK UNIFIED IDEOGRAPH
+0xF759 0x9C55 #CJK UNIFIED IDEOGRAPH
+0xF75A 0x9C56 #CJK UNIFIED IDEOGRAPH
+0xF75B 0x9C57 #CJK UNIFIED IDEOGRAPH
+0xF75C 0x9C58 #CJK UNIFIED IDEOGRAPH
+0xF75D 0x9C59 #CJK UNIFIED IDEOGRAPH
+0xF75E 0x9C5A #CJK UNIFIED IDEOGRAPH
+0xF75F 0x9C5B #CJK UNIFIED IDEOGRAPH
+0xF760 0x9C5C #CJK UNIFIED IDEOGRAPH
+0xF761 0x9C5D #CJK UNIFIED IDEOGRAPH
+0xF762 0x9C5E #CJK UNIFIED IDEOGRAPH
+0xF763 0x9C5F #CJK UNIFIED IDEOGRAPH
+0xF764 0x9C60 #CJK UNIFIED IDEOGRAPH
+0xF765 0x9C61 #CJK UNIFIED IDEOGRAPH
+0xF766 0x9C62 #CJK UNIFIED IDEOGRAPH
+0xF767 0x9C63 #CJK UNIFIED IDEOGRAPH
+0xF768 0x9C64 #CJK UNIFIED IDEOGRAPH
+0xF769 0x9C65 #CJK UNIFIED IDEOGRAPH
+0xF76A 0x9C66 #CJK UNIFIED IDEOGRAPH
+0xF76B 0x9C67 #CJK UNIFIED IDEOGRAPH
+0xF76C 0x9C68 #CJK UNIFIED IDEOGRAPH
+0xF76D 0x9C69 #CJK UNIFIED IDEOGRAPH
+0xF76E 0x9C6A #CJK UNIFIED IDEOGRAPH
+0xF76F 0x9C6B #CJK UNIFIED IDEOGRAPH
+0xF770 0x9C6C #CJK UNIFIED IDEOGRAPH
+0xF771 0x9C6D #CJK UNIFIED IDEOGRAPH
+0xF772 0x9C6E #CJK UNIFIED IDEOGRAPH
+0xF773 0x9C6F #CJK UNIFIED IDEOGRAPH
+0xF774 0x9C70 #CJK UNIFIED IDEOGRAPH
+0xF775 0x9C71 #CJK UNIFIED IDEOGRAPH
+0xF776 0x9C72 #CJK UNIFIED IDEOGRAPH
+0xF777 0x9C73 #CJK UNIFIED IDEOGRAPH
+0xF778 0x9C74 #CJK UNIFIED IDEOGRAPH
+0xF779 0x9C75 #CJK UNIFIED IDEOGRAPH
+0xF77A 0x9C76 #CJK UNIFIED IDEOGRAPH
+0xF77B 0x9C77 #CJK UNIFIED IDEOGRAPH
+0xF77C 0x9C78 #CJK UNIFIED IDEOGRAPH
+0xF77D 0x9C79 #CJK UNIFIED IDEOGRAPH
+0xF77E 0x9C7A #CJK UNIFIED IDEOGRAPH
+0xF780 0x9C7B #CJK UNIFIED IDEOGRAPH
+0xF781 0x9C7D #CJK UNIFIED IDEOGRAPH
+0xF782 0x9C7E #CJK UNIFIED IDEOGRAPH
+0xF783 0x9C80 #CJK UNIFIED IDEOGRAPH
+0xF784 0x9C83 #CJK UNIFIED IDEOGRAPH
+0xF785 0x9C84 #CJK UNIFIED IDEOGRAPH
+0xF786 0x9C89 #CJK UNIFIED IDEOGRAPH
+0xF787 0x9C8A #CJK UNIFIED IDEOGRAPH
+0xF788 0x9C8C #CJK UNIFIED IDEOGRAPH
+0xF789 0x9C8F #CJK UNIFIED IDEOGRAPH
+0xF78A 0x9C93 #CJK UNIFIED IDEOGRAPH
+0xF78B 0x9C96 #CJK UNIFIED IDEOGRAPH
+0xF78C 0x9C97 #CJK UNIFIED IDEOGRAPH
+0xF78D 0x9C98 #CJK UNIFIED IDEOGRAPH
+0xF78E 0x9C99 #CJK UNIFIED IDEOGRAPH
+0xF78F 0x9C9D #CJK UNIFIED IDEOGRAPH
+0xF790 0x9CAA #CJK UNIFIED IDEOGRAPH
+0xF791 0x9CAC #CJK UNIFIED IDEOGRAPH
+0xF792 0x9CAF #CJK UNIFIED IDEOGRAPH
+0xF793 0x9CB9 #CJK UNIFIED IDEOGRAPH
+0xF794 0x9CBE #CJK UNIFIED IDEOGRAPH
+0xF795 0x9CBF #CJK UNIFIED IDEOGRAPH
+0xF796 0x9CC0 #CJK UNIFIED IDEOGRAPH
+0xF797 0x9CC1 #CJK UNIFIED IDEOGRAPH
+0xF798 0x9CC2 #CJK UNIFIED IDEOGRAPH
+0xF799 0x9CC8 #CJK UNIFIED IDEOGRAPH
+0xF79A 0x9CC9 #CJK UNIFIED IDEOGRAPH
+0xF79B 0x9CD1 #CJK UNIFIED IDEOGRAPH
+0xF79C 0x9CD2 #CJK UNIFIED IDEOGRAPH
+0xF79D 0x9CDA #CJK UNIFIED IDEOGRAPH
+0xF79E 0x9CDB #CJK UNIFIED IDEOGRAPH
+0xF79F 0x9CE0 #CJK UNIFIED IDEOGRAPH
+0xF7A0 0x9CE1 #CJK UNIFIED IDEOGRAPH
+0xF7A1 0x9CCC #CJK UNIFIED IDEOGRAPH
+0xF7A2 0x9CCD #CJK UNIFIED IDEOGRAPH
+0xF7A3 0x9CCE #CJK UNIFIED IDEOGRAPH
+0xF7A4 0x9CCF #CJK UNIFIED IDEOGRAPH
+0xF7A5 0x9CD0 #CJK UNIFIED IDEOGRAPH
+0xF7A6 0x9CD3 #CJK UNIFIED IDEOGRAPH
+0xF7A7 0x9CD4 #CJK UNIFIED IDEOGRAPH
+0xF7A8 0x9CD5 #CJK UNIFIED IDEOGRAPH
+0xF7A9 0x9CD7 #CJK UNIFIED IDEOGRAPH
+0xF7AA 0x9CD8 #CJK UNIFIED IDEOGRAPH
+0xF7AB 0x9CD9 #CJK UNIFIED IDEOGRAPH
+0xF7AC 0x9CDC #CJK UNIFIED IDEOGRAPH
+0xF7AD 0x9CDD #CJK UNIFIED IDEOGRAPH
+0xF7AE 0x9CDF #CJK UNIFIED IDEOGRAPH
+0xF7AF 0x9CE2 #CJK UNIFIED IDEOGRAPH
+0xF7B0 0x977C #CJK UNIFIED IDEOGRAPH
+0xF7B1 0x9785 #CJK UNIFIED IDEOGRAPH
+0xF7B2 0x9791 #CJK UNIFIED IDEOGRAPH
+0xF7B3 0x9792 #CJK UNIFIED IDEOGRAPH
+0xF7B4 0x9794 #CJK UNIFIED IDEOGRAPH
+0xF7B5 0x97AF #CJK UNIFIED IDEOGRAPH
+0xF7B6 0x97AB #CJK UNIFIED IDEOGRAPH
+0xF7B7 0x97A3 #CJK UNIFIED IDEOGRAPH
+0xF7B8 0x97B2 #CJK UNIFIED IDEOGRAPH
+0xF7B9 0x97B4 #CJK UNIFIED IDEOGRAPH
+0xF7BA 0x9AB1 #CJK UNIFIED IDEOGRAPH
+0xF7BB 0x9AB0 #CJK UNIFIED IDEOGRAPH
+0xF7BC 0x9AB7 #CJK UNIFIED IDEOGRAPH
+0xF7BD 0x9E58 #CJK UNIFIED IDEOGRAPH
+0xF7BE 0x9AB6 #CJK UNIFIED IDEOGRAPH
+0xF7BF 0x9ABA #CJK UNIFIED IDEOGRAPH
+0xF7C0 0x9ABC #CJK UNIFIED IDEOGRAPH
+0xF7C1 0x9AC1 #CJK UNIFIED IDEOGRAPH
+0xF7C2 0x9AC0 #CJK UNIFIED IDEOGRAPH
+0xF7C3 0x9AC5 #CJK UNIFIED IDEOGRAPH
+0xF7C4 0x9AC2 #CJK UNIFIED IDEOGRAPH
+0xF7C5 0x9ACB #CJK UNIFIED IDEOGRAPH
+0xF7C6 0x9ACC #CJK UNIFIED IDEOGRAPH
+0xF7C7 0x9AD1 #CJK UNIFIED IDEOGRAPH
+0xF7C8 0x9B45 #CJK UNIFIED IDEOGRAPH
+0xF7C9 0x9B43 #CJK UNIFIED IDEOGRAPH
+0xF7CA 0x9B47 #CJK UNIFIED IDEOGRAPH
+0xF7CB 0x9B49 #CJK UNIFIED IDEOGRAPH
+0xF7CC 0x9B48 #CJK UNIFIED IDEOGRAPH
+0xF7CD 0x9B4D #CJK UNIFIED IDEOGRAPH
+0xF7CE 0x9B51 #CJK UNIFIED IDEOGRAPH
+0xF7CF 0x98E8 #CJK UNIFIED IDEOGRAPH
+0xF7D0 0x990D #CJK UNIFIED IDEOGRAPH
+0xF7D1 0x992E #CJK UNIFIED IDEOGRAPH
+0xF7D2 0x9955 #CJK UNIFIED IDEOGRAPH
+0xF7D3 0x9954 #CJK UNIFIED IDEOGRAPH
+0xF7D4 0x9ADF #CJK UNIFIED IDEOGRAPH
+0xF7D5 0x9AE1 #CJK UNIFIED IDEOGRAPH
+0xF7D6 0x9AE6 #CJK UNIFIED IDEOGRAPH
+0xF7D7 0x9AEF #CJK UNIFIED IDEOGRAPH
+0xF7D8 0x9AEB #CJK UNIFIED IDEOGRAPH
+0xF7D9 0x9AFB #CJK UNIFIED IDEOGRAPH
+0xF7DA 0x9AED #CJK UNIFIED IDEOGRAPH
+0xF7DB 0x9AF9 #CJK UNIFIED IDEOGRAPH
+0xF7DC 0x9B08 #CJK UNIFIED IDEOGRAPH
+0xF7DD 0x9B0F #CJK UNIFIED IDEOGRAPH
+0xF7DE 0x9B13 #CJK UNIFIED IDEOGRAPH
+0xF7DF 0x9B1F #CJK UNIFIED IDEOGRAPH
+0xF7E0 0x9B23 #CJK UNIFIED IDEOGRAPH
+0xF7E1 0x9EBD #CJK UNIFIED IDEOGRAPH
+0xF7E2 0x9EBE #CJK UNIFIED IDEOGRAPH
+0xF7E3 0x7E3B #CJK UNIFIED IDEOGRAPH
+0xF7E4 0x9E82 #CJK UNIFIED IDEOGRAPH
+0xF7E5 0x9E87 #CJK UNIFIED IDEOGRAPH
+0xF7E6 0x9E88 #CJK UNIFIED IDEOGRAPH
+0xF7E7 0x9E8B #CJK UNIFIED IDEOGRAPH
+0xF7E8 0x9E92 #CJK UNIFIED IDEOGRAPH
+0xF7E9 0x93D6 #CJK UNIFIED IDEOGRAPH
+0xF7EA 0x9E9D #CJK UNIFIED IDEOGRAPH
+0xF7EB 0x9E9F #CJK UNIFIED IDEOGRAPH
+0xF7EC 0x9EDB #CJK UNIFIED IDEOGRAPH
+0xF7ED 0x9EDC #CJK UNIFIED IDEOGRAPH
+0xF7EE 0x9EDD #CJK UNIFIED IDEOGRAPH
+0xF7EF 0x9EE0 #CJK UNIFIED IDEOGRAPH
+0xF7F0 0x9EDF #CJK UNIFIED IDEOGRAPH
+0xF7F1 0x9EE2 #CJK UNIFIED IDEOGRAPH
+0xF7F2 0x9EE9 #CJK UNIFIED IDEOGRAPH
+0xF7F3 0x9EE7 #CJK UNIFIED IDEOGRAPH
+0xF7F4 0x9EE5 #CJK UNIFIED IDEOGRAPH
+0xF7F5 0x9EEA #CJK UNIFIED IDEOGRAPH
+0xF7F6 0x9EEF #CJK UNIFIED IDEOGRAPH
+0xF7F7 0x9F22 #CJK UNIFIED IDEOGRAPH
+0xF7F8 0x9F2C #CJK UNIFIED IDEOGRAPH
+0xF7F9 0x9F2F #CJK UNIFIED IDEOGRAPH
+0xF7FA 0x9F39 #CJK UNIFIED IDEOGRAPH
+0xF7FB 0x9F37 #CJK UNIFIED IDEOGRAPH
+0xF7FC 0x9F3D #CJK UNIFIED IDEOGRAPH
+0xF7FD 0x9F3E #CJK UNIFIED IDEOGRAPH
+0xF7FE 0x9F44 #CJK UNIFIED IDEOGRAPH
+0xF840 0x9CE3 #CJK UNIFIED IDEOGRAPH
+0xF841 0x9CE4 #CJK UNIFIED IDEOGRAPH
+0xF842 0x9CE5 #CJK UNIFIED IDEOGRAPH
+0xF843 0x9CE6 #CJK UNIFIED IDEOGRAPH
+0xF844 0x9CE7 #CJK UNIFIED IDEOGRAPH
+0xF845 0x9CE8 #CJK UNIFIED IDEOGRAPH
+0xF846 0x9CE9 #CJK UNIFIED IDEOGRAPH
+0xF847 0x9CEA #CJK UNIFIED IDEOGRAPH
+0xF848 0x9CEB #CJK UNIFIED IDEOGRAPH
+0xF849 0x9CEC #CJK UNIFIED IDEOGRAPH
+0xF84A 0x9CED #CJK UNIFIED IDEOGRAPH
+0xF84B 0x9CEE #CJK UNIFIED IDEOGRAPH
+0xF84C 0x9CEF #CJK UNIFIED IDEOGRAPH
+0xF84D 0x9CF0 #CJK UNIFIED IDEOGRAPH
+0xF84E 0x9CF1 #CJK UNIFIED IDEOGRAPH
+0xF84F 0x9CF2 #CJK UNIFIED IDEOGRAPH
+0xF850 0x9CF3 #CJK UNIFIED IDEOGRAPH
+0xF851 0x9CF4 #CJK UNIFIED IDEOGRAPH
+0xF852 0x9CF5 #CJK UNIFIED IDEOGRAPH
+0xF853 0x9CF6 #CJK UNIFIED IDEOGRAPH
+0xF854 0x9CF7 #CJK UNIFIED IDEOGRAPH
+0xF855 0x9CF8 #CJK UNIFIED IDEOGRAPH
+0xF856 0x9CF9 #CJK UNIFIED IDEOGRAPH
+0xF857 0x9CFA #CJK UNIFIED IDEOGRAPH
+0xF858 0x9CFB #CJK UNIFIED IDEOGRAPH
+0xF859 0x9CFC #CJK UNIFIED IDEOGRAPH
+0xF85A 0x9CFD #CJK UNIFIED IDEOGRAPH
+0xF85B 0x9CFE #CJK UNIFIED IDEOGRAPH
+0xF85C 0x9CFF #CJK UNIFIED IDEOGRAPH
+0xF85D 0x9D00 #CJK UNIFIED IDEOGRAPH
+0xF85E 0x9D01 #CJK UNIFIED IDEOGRAPH
+0xF85F 0x9D02 #CJK UNIFIED IDEOGRAPH
+0xF860 0x9D03 #CJK UNIFIED IDEOGRAPH
+0xF861 0x9D04 #CJK UNIFIED IDEOGRAPH
+0xF862 0x9D05 #CJK UNIFIED IDEOGRAPH
+0xF863 0x9D06 #CJK UNIFIED IDEOGRAPH
+0xF864 0x9D07 #CJK UNIFIED IDEOGRAPH
+0xF865 0x9D08 #CJK UNIFIED IDEOGRAPH
+0xF866 0x9D09 #CJK UNIFIED IDEOGRAPH
+0xF867 0x9D0A #CJK UNIFIED IDEOGRAPH
+0xF868 0x9D0B #CJK UNIFIED IDEOGRAPH
+0xF869 0x9D0C #CJK UNIFIED IDEOGRAPH
+0xF86A 0x9D0D #CJK UNIFIED IDEOGRAPH
+0xF86B 0x9D0E #CJK UNIFIED IDEOGRAPH
+0xF86C 0x9D0F #CJK UNIFIED IDEOGRAPH
+0xF86D 0x9D10 #CJK UNIFIED IDEOGRAPH
+0xF86E 0x9D11 #CJK UNIFIED IDEOGRAPH
+0xF86F 0x9D12 #CJK UNIFIED IDEOGRAPH
+0xF870 0x9D13 #CJK UNIFIED IDEOGRAPH
+0xF871 0x9D14 #CJK UNIFIED IDEOGRAPH
+0xF872 0x9D15 #CJK UNIFIED IDEOGRAPH
+0xF873 0x9D16 #CJK UNIFIED IDEOGRAPH
+0xF874 0x9D17 #CJK UNIFIED IDEOGRAPH
+0xF875 0x9D18 #CJK UNIFIED IDEOGRAPH
+0xF876 0x9D19 #CJK UNIFIED IDEOGRAPH
+0xF877 0x9D1A #CJK UNIFIED IDEOGRAPH
+0xF878 0x9D1B #CJK UNIFIED IDEOGRAPH
+0xF879 0x9D1C #CJK UNIFIED IDEOGRAPH
+0xF87A 0x9D1D #CJK UNIFIED IDEOGRAPH
+0xF87B 0x9D1E #CJK UNIFIED IDEOGRAPH
+0xF87C 0x9D1F #CJK UNIFIED IDEOGRAPH
+0xF87D 0x9D20 #CJK UNIFIED IDEOGRAPH
+0xF87E 0x9D21 #CJK UNIFIED IDEOGRAPH
+0xF880 0x9D22 #CJK UNIFIED IDEOGRAPH
+0xF881 0x9D23 #CJK UNIFIED IDEOGRAPH
+0xF882 0x9D24 #CJK UNIFIED IDEOGRAPH
+0xF883 0x9D25 #CJK UNIFIED IDEOGRAPH
+0xF884 0x9D26 #CJK UNIFIED IDEOGRAPH
+0xF885 0x9D27 #CJK UNIFIED IDEOGRAPH
+0xF886 0x9D28 #CJK UNIFIED IDEOGRAPH
+0xF887 0x9D29 #CJK UNIFIED IDEOGRAPH
+0xF888 0x9D2A #CJK UNIFIED IDEOGRAPH
+0xF889 0x9D2B #CJK UNIFIED IDEOGRAPH
+0xF88A 0x9D2C #CJK UNIFIED IDEOGRAPH
+0xF88B 0x9D2D #CJK UNIFIED IDEOGRAPH
+0xF88C 0x9D2E #CJK UNIFIED IDEOGRAPH
+0xF88D 0x9D2F #CJK UNIFIED IDEOGRAPH
+0xF88E 0x9D30 #CJK UNIFIED IDEOGRAPH
+0xF88F 0x9D31 #CJK UNIFIED IDEOGRAPH
+0xF890 0x9D32 #CJK UNIFIED IDEOGRAPH
+0xF891 0x9D33 #CJK UNIFIED IDEOGRAPH
+0xF892 0x9D34 #CJK UNIFIED IDEOGRAPH
+0xF893 0x9D35 #CJK UNIFIED IDEOGRAPH
+0xF894 0x9D36 #CJK UNIFIED IDEOGRAPH
+0xF895 0x9D37 #CJK UNIFIED IDEOGRAPH
+0xF896 0x9D38 #CJK UNIFIED IDEOGRAPH
+0xF897 0x9D39 #CJK UNIFIED IDEOGRAPH
+0xF898 0x9D3A #CJK UNIFIED IDEOGRAPH
+0xF899 0x9D3B #CJK UNIFIED IDEOGRAPH
+0xF89A 0x9D3C #CJK UNIFIED IDEOGRAPH
+0xF89B 0x9D3D #CJK UNIFIED IDEOGRAPH
+0xF89C 0x9D3E #CJK UNIFIED IDEOGRAPH
+0xF89D 0x9D3F #CJK UNIFIED IDEOGRAPH
+0xF89E 0x9D40 #CJK UNIFIED IDEOGRAPH
+0xF89F 0x9D41 #CJK UNIFIED IDEOGRAPH
+0xF8A0 0x9D42 #CJK UNIFIED IDEOGRAPH
+0xF940 0x9D43 #CJK UNIFIED IDEOGRAPH
+0xF941 0x9D44 #CJK UNIFIED IDEOGRAPH
+0xF942 0x9D45 #CJK UNIFIED IDEOGRAPH
+0xF943 0x9D46 #CJK UNIFIED IDEOGRAPH
+0xF944 0x9D47 #CJK UNIFIED IDEOGRAPH
+0xF945 0x9D48 #CJK UNIFIED IDEOGRAPH
+0xF946 0x9D49 #CJK UNIFIED IDEOGRAPH
+0xF947 0x9D4A #CJK UNIFIED IDEOGRAPH
+0xF948 0x9D4B #CJK UNIFIED IDEOGRAPH
+0xF949 0x9D4C #CJK UNIFIED IDEOGRAPH
+0xF94A 0x9D4D #CJK UNIFIED IDEOGRAPH
+0xF94B 0x9D4E #CJK UNIFIED IDEOGRAPH
+0xF94C 0x9D4F #CJK UNIFIED IDEOGRAPH
+0xF94D 0x9D50 #CJK UNIFIED IDEOGRAPH
+0xF94E 0x9D51 #CJK UNIFIED IDEOGRAPH
+0xF94F 0x9D52 #CJK UNIFIED IDEOGRAPH
+0xF950 0x9D53 #CJK UNIFIED IDEOGRAPH
+0xF951 0x9D54 #CJK UNIFIED IDEOGRAPH
+0xF952 0x9D55 #CJK UNIFIED IDEOGRAPH
+0xF953 0x9D56 #CJK UNIFIED IDEOGRAPH
+0xF954 0x9D57 #CJK UNIFIED IDEOGRAPH
+0xF955 0x9D58 #CJK UNIFIED IDEOGRAPH
+0xF956 0x9D59 #CJK UNIFIED IDEOGRAPH
+0xF957 0x9D5A #CJK UNIFIED IDEOGRAPH
+0xF958 0x9D5B #CJK UNIFIED IDEOGRAPH
+0xF959 0x9D5C #CJK UNIFIED IDEOGRAPH
+0xF95A 0x9D5D #CJK UNIFIED IDEOGRAPH
+0xF95B 0x9D5E #CJK UNIFIED IDEOGRAPH
+0xF95C 0x9D5F #CJK UNIFIED IDEOGRAPH
+0xF95D 0x9D60 #CJK UNIFIED IDEOGRAPH
+0xF95E 0x9D61 #CJK UNIFIED IDEOGRAPH
+0xF95F 0x9D62 #CJK UNIFIED IDEOGRAPH
+0xF960 0x9D63 #CJK UNIFIED IDEOGRAPH
+0xF961 0x9D64 #CJK UNIFIED IDEOGRAPH
+0xF962 0x9D65 #CJK UNIFIED IDEOGRAPH
+0xF963 0x9D66 #CJK UNIFIED IDEOGRAPH
+0xF964 0x9D67 #CJK UNIFIED IDEOGRAPH
+0xF965 0x9D68 #CJK UNIFIED IDEOGRAPH
+0xF966 0x9D69 #CJK UNIFIED IDEOGRAPH
+0xF967 0x9D6A #CJK UNIFIED IDEOGRAPH
+0xF968 0x9D6B #CJK UNIFIED IDEOGRAPH
+0xF969 0x9D6C #CJK UNIFIED IDEOGRAPH
+0xF96A 0x9D6D #CJK UNIFIED IDEOGRAPH
+0xF96B 0x9D6E #CJK UNIFIED IDEOGRAPH
+0xF96C 0x9D6F #CJK UNIFIED IDEOGRAPH
+0xF96D 0x9D70 #CJK UNIFIED IDEOGRAPH
+0xF96E 0x9D71 #CJK UNIFIED IDEOGRAPH
+0xF96F 0x9D72 #CJK UNIFIED IDEOGRAPH
+0xF970 0x9D73 #CJK UNIFIED IDEOGRAPH
+0xF971 0x9D74 #CJK UNIFIED IDEOGRAPH
+0xF972 0x9D75 #CJK UNIFIED IDEOGRAPH
+0xF973 0x9D76 #CJK UNIFIED IDEOGRAPH
+0xF974 0x9D77 #CJK UNIFIED IDEOGRAPH
+0xF975 0x9D78 #CJK UNIFIED IDEOGRAPH
+0xF976 0x9D79 #CJK UNIFIED IDEOGRAPH
+0xF977 0x9D7A #CJK UNIFIED IDEOGRAPH
+0xF978 0x9D7B #CJK UNIFIED IDEOGRAPH
+0xF979 0x9D7C #CJK UNIFIED IDEOGRAPH
+0xF97A 0x9D7D #CJK UNIFIED IDEOGRAPH
+0xF97B 0x9D7E #CJK UNIFIED IDEOGRAPH
+0xF97C 0x9D7F #CJK UNIFIED IDEOGRAPH
+0xF97D 0x9D80 #CJK UNIFIED IDEOGRAPH
+0xF97E 0x9D81 #CJK UNIFIED IDEOGRAPH
+0xF980 0x9D82 #CJK UNIFIED IDEOGRAPH
+0xF981 0x9D83 #CJK UNIFIED IDEOGRAPH
+0xF982 0x9D84 #CJK UNIFIED IDEOGRAPH
+0xF983 0x9D85 #CJK UNIFIED IDEOGRAPH
+0xF984 0x9D86 #CJK UNIFIED IDEOGRAPH
+0xF985 0x9D87 #CJK UNIFIED IDEOGRAPH
+0xF986 0x9D88 #CJK UNIFIED IDEOGRAPH
+0xF987 0x9D89 #CJK UNIFIED IDEOGRAPH
+0xF988 0x9D8A #CJK UNIFIED IDEOGRAPH
+0xF989 0x9D8B #CJK UNIFIED IDEOGRAPH
+0xF98A 0x9D8C #CJK UNIFIED IDEOGRAPH
+0xF98B 0x9D8D #CJK UNIFIED IDEOGRAPH
+0xF98C 0x9D8E #CJK UNIFIED IDEOGRAPH
+0xF98D 0x9D8F #CJK UNIFIED IDEOGRAPH
+0xF98E 0x9D90 #CJK UNIFIED IDEOGRAPH
+0xF98F 0x9D91 #CJK UNIFIED IDEOGRAPH
+0xF990 0x9D92 #CJK UNIFIED IDEOGRAPH
+0xF991 0x9D93 #CJK UNIFIED IDEOGRAPH
+0xF992 0x9D94 #CJK UNIFIED IDEOGRAPH
+0xF993 0x9D95 #CJK UNIFIED IDEOGRAPH
+0xF994 0x9D96 #CJK UNIFIED IDEOGRAPH
+0xF995 0x9D97 #CJK UNIFIED IDEOGRAPH
+0xF996 0x9D98 #CJK UNIFIED IDEOGRAPH
+0xF997 0x9D99 #CJK UNIFIED IDEOGRAPH
+0xF998 0x9D9A #CJK UNIFIED IDEOGRAPH
+0xF999 0x9D9B #CJK UNIFIED IDEOGRAPH
+0xF99A 0x9D9C #CJK UNIFIED IDEOGRAPH
+0xF99B 0x9D9D #CJK UNIFIED IDEOGRAPH
+0xF99C 0x9D9E #CJK UNIFIED IDEOGRAPH
+0xF99D 0x9D9F #CJK UNIFIED IDEOGRAPH
+0xF99E 0x9DA0 #CJK UNIFIED IDEOGRAPH
+0xF99F 0x9DA1 #CJK UNIFIED IDEOGRAPH
+0xF9A0 0x9DA2 #CJK UNIFIED IDEOGRAPH
+0xFA40 0x9DA3 #CJK UNIFIED IDEOGRAPH
+0xFA41 0x9DA4 #CJK UNIFIED IDEOGRAPH
+0xFA42 0x9DA5 #CJK UNIFIED IDEOGRAPH
+0xFA43 0x9DA6 #CJK UNIFIED IDEOGRAPH
+0xFA44 0x9DA7 #CJK UNIFIED IDEOGRAPH
+0xFA45 0x9DA8 #CJK UNIFIED IDEOGRAPH
+0xFA46 0x9DA9 #CJK UNIFIED IDEOGRAPH
+0xFA47 0x9DAA #CJK UNIFIED IDEOGRAPH
+0xFA48 0x9DAB #CJK UNIFIED IDEOGRAPH
+0xFA49 0x9DAC #CJK UNIFIED IDEOGRAPH
+0xFA4A 0x9DAD #CJK UNIFIED IDEOGRAPH
+0xFA4B 0x9DAE #CJK UNIFIED IDEOGRAPH
+0xFA4C 0x9DAF #CJK UNIFIED IDEOGRAPH
+0xFA4D 0x9DB0 #CJK UNIFIED IDEOGRAPH
+0xFA4E 0x9DB1 #CJK UNIFIED IDEOGRAPH
+0xFA4F 0x9DB2 #CJK UNIFIED IDEOGRAPH
+0xFA50 0x9DB3 #CJK UNIFIED IDEOGRAPH
+0xFA51 0x9DB4 #CJK UNIFIED IDEOGRAPH
+0xFA52 0x9DB5 #CJK UNIFIED IDEOGRAPH
+0xFA53 0x9DB6 #CJK UNIFIED IDEOGRAPH
+0xFA54 0x9DB7 #CJK UNIFIED IDEOGRAPH
+0xFA55 0x9DB8 #CJK UNIFIED IDEOGRAPH
+0xFA56 0x9DB9 #CJK UNIFIED IDEOGRAPH
+0xFA57 0x9DBA #CJK UNIFIED IDEOGRAPH
+0xFA58 0x9DBB #CJK UNIFIED IDEOGRAPH
+0xFA59 0x9DBC #CJK UNIFIED IDEOGRAPH
+0xFA5A 0x9DBD #CJK UNIFIED IDEOGRAPH
+0xFA5B 0x9DBE #CJK UNIFIED IDEOGRAPH
+0xFA5C 0x9DBF #CJK UNIFIED IDEOGRAPH
+0xFA5D 0x9DC0 #CJK UNIFIED IDEOGRAPH
+0xFA5E 0x9DC1 #CJK UNIFIED IDEOGRAPH
+0xFA5F 0x9DC2 #CJK UNIFIED IDEOGRAPH
+0xFA60 0x9DC3 #CJK UNIFIED IDEOGRAPH
+0xFA61 0x9DC4 #CJK UNIFIED IDEOGRAPH
+0xFA62 0x9DC5 #CJK UNIFIED IDEOGRAPH
+0xFA63 0x9DC6 #CJK UNIFIED IDEOGRAPH
+0xFA64 0x9DC7 #CJK UNIFIED IDEOGRAPH
+0xFA65 0x9DC8 #CJK UNIFIED IDEOGRAPH
+0xFA66 0x9DC9 #CJK UNIFIED IDEOGRAPH
+0xFA67 0x9DCA #CJK UNIFIED IDEOGRAPH
+0xFA68 0x9DCB #CJK UNIFIED IDEOGRAPH
+0xFA69 0x9DCC #CJK UNIFIED IDEOGRAPH
+0xFA6A 0x9DCD #CJK UNIFIED IDEOGRAPH
+0xFA6B 0x9DCE #CJK UNIFIED IDEOGRAPH
+0xFA6C 0x9DCF #CJK UNIFIED IDEOGRAPH
+0xFA6D 0x9DD0 #CJK UNIFIED IDEOGRAPH
+0xFA6E 0x9DD1 #CJK UNIFIED IDEOGRAPH
+0xFA6F 0x9DD2 #CJK UNIFIED IDEOGRAPH
+0xFA70 0x9DD3 #CJK UNIFIED IDEOGRAPH
+0xFA71 0x9DD4 #CJK UNIFIED IDEOGRAPH
+0xFA72 0x9DD5 #CJK UNIFIED IDEOGRAPH
+0xFA73 0x9DD6 #CJK UNIFIED IDEOGRAPH
+0xFA74 0x9DD7 #CJK UNIFIED IDEOGRAPH
+0xFA75 0x9DD8 #CJK UNIFIED IDEOGRAPH
+0xFA76 0x9DD9 #CJK UNIFIED IDEOGRAPH
+0xFA77 0x9DDA #CJK UNIFIED IDEOGRAPH
+0xFA78 0x9DDB #CJK UNIFIED IDEOGRAPH
+0xFA79 0x9DDC #CJK UNIFIED IDEOGRAPH
+0xFA7A 0x9DDD #CJK UNIFIED IDEOGRAPH
+0xFA7B 0x9DDE #CJK UNIFIED IDEOGRAPH
+0xFA7C 0x9DDF #CJK UNIFIED IDEOGRAPH
+0xFA7D 0x9DE0 #CJK UNIFIED IDEOGRAPH
+0xFA7E 0x9DE1 #CJK UNIFIED IDEOGRAPH
+0xFA80 0x9DE2 #CJK UNIFIED IDEOGRAPH
+0xFA81 0x9DE3 #CJK UNIFIED IDEOGRAPH
+0xFA82 0x9DE4 #CJK UNIFIED IDEOGRAPH
+0xFA83 0x9DE5 #CJK UNIFIED IDEOGRAPH
+0xFA84 0x9DE6 #CJK UNIFIED IDEOGRAPH
+0xFA85 0x9DE7 #CJK UNIFIED IDEOGRAPH
+0xFA86 0x9DE8 #CJK UNIFIED IDEOGRAPH
+0xFA87 0x9DE9 #CJK UNIFIED IDEOGRAPH
+0xFA88 0x9DEA #CJK UNIFIED IDEOGRAPH
+0xFA89 0x9DEB #CJK UNIFIED IDEOGRAPH
+0xFA8A 0x9DEC #CJK UNIFIED IDEOGRAPH
+0xFA8B 0x9DED #CJK UNIFIED IDEOGRAPH
+0xFA8C 0x9DEE #CJK UNIFIED IDEOGRAPH
+0xFA8D 0x9DEF #CJK UNIFIED IDEOGRAPH
+0xFA8E 0x9DF0 #CJK UNIFIED IDEOGRAPH
+0xFA8F 0x9DF1 #CJK UNIFIED IDEOGRAPH
+0xFA90 0x9DF2 #CJK UNIFIED IDEOGRAPH
+0xFA91 0x9DF3 #CJK UNIFIED IDEOGRAPH
+0xFA92 0x9DF4 #CJK UNIFIED IDEOGRAPH
+0xFA93 0x9DF5 #CJK UNIFIED IDEOGRAPH
+0xFA94 0x9DF6 #CJK UNIFIED IDEOGRAPH
+0xFA95 0x9DF7 #CJK UNIFIED IDEOGRAPH
+0xFA96 0x9DF8 #CJK UNIFIED IDEOGRAPH
+0xFA97 0x9DF9 #CJK UNIFIED IDEOGRAPH
+0xFA98 0x9DFA #CJK UNIFIED IDEOGRAPH
+0xFA99 0x9DFB #CJK UNIFIED IDEOGRAPH
+0xFA9A 0x9DFC #CJK UNIFIED IDEOGRAPH
+0xFA9B 0x9DFD #CJK UNIFIED IDEOGRAPH
+0xFA9C 0x9DFE #CJK UNIFIED IDEOGRAPH
+0xFA9D 0x9DFF #CJK UNIFIED IDEOGRAPH
+0xFA9E 0x9E00 #CJK UNIFIED IDEOGRAPH
+0xFA9F 0x9E01 #CJK UNIFIED IDEOGRAPH
+0xFAA0 0x9E02 #CJK UNIFIED IDEOGRAPH
+0xFB40 0x9E03 #CJK UNIFIED IDEOGRAPH
+0xFB41 0x9E04 #CJK UNIFIED IDEOGRAPH
+0xFB42 0x9E05 #CJK UNIFIED IDEOGRAPH
+0xFB43 0x9E06 #CJK UNIFIED IDEOGRAPH
+0xFB44 0x9E07 #CJK UNIFIED IDEOGRAPH
+0xFB45 0x9E08 #CJK UNIFIED IDEOGRAPH
+0xFB46 0x9E09 #CJK UNIFIED IDEOGRAPH
+0xFB47 0x9E0A #CJK UNIFIED IDEOGRAPH
+0xFB48 0x9E0B #CJK UNIFIED IDEOGRAPH
+0xFB49 0x9E0C #CJK UNIFIED IDEOGRAPH
+0xFB4A 0x9E0D #CJK UNIFIED IDEOGRAPH
+0xFB4B 0x9E0E #CJK UNIFIED IDEOGRAPH
+0xFB4C 0x9E0F #CJK UNIFIED IDEOGRAPH
+0xFB4D 0x9E10 #CJK UNIFIED IDEOGRAPH
+0xFB4E 0x9E11 #CJK UNIFIED IDEOGRAPH
+0xFB4F 0x9E12 #CJK UNIFIED IDEOGRAPH
+0xFB50 0x9E13 #CJK UNIFIED IDEOGRAPH
+0xFB51 0x9E14 #CJK UNIFIED IDEOGRAPH
+0xFB52 0x9E15 #CJK UNIFIED IDEOGRAPH
+0xFB53 0x9E16 #CJK UNIFIED IDEOGRAPH
+0xFB54 0x9E17 #CJK UNIFIED IDEOGRAPH
+0xFB55 0x9E18 #CJK UNIFIED IDEOGRAPH
+0xFB56 0x9E19 #CJK UNIFIED IDEOGRAPH
+0xFB57 0x9E1A #CJK UNIFIED IDEOGRAPH
+0xFB58 0x9E1B #CJK UNIFIED IDEOGRAPH
+0xFB59 0x9E1C #CJK UNIFIED IDEOGRAPH
+0xFB5A 0x9E1D #CJK UNIFIED IDEOGRAPH
+0xFB5B 0x9E1E #CJK UNIFIED IDEOGRAPH
+0xFB5C 0x9E24 #CJK UNIFIED IDEOGRAPH
+0xFB5D 0x9E27 #CJK UNIFIED IDEOGRAPH
+0xFB5E 0x9E2E #CJK UNIFIED IDEOGRAPH
+0xFB5F 0x9E30 #CJK UNIFIED IDEOGRAPH
+0xFB60 0x9E34 #CJK UNIFIED IDEOGRAPH
+0xFB61 0x9E3B #CJK UNIFIED IDEOGRAPH
+0xFB62 0x9E3C #CJK UNIFIED IDEOGRAPH
+0xFB63 0x9E40 #CJK UNIFIED IDEOGRAPH
+0xFB64 0x9E4D #CJK UNIFIED IDEOGRAPH
+0xFB65 0x9E50 #CJK UNIFIED IDEOGRAPH
+0xFB66 0x9E52 #CJK UNIFIED IDEOGRAPH
+0xFB67 0x9E53 #CJK UNIFIED IDEOGRAPH
+0xFB68 0x9E54 #CJK UNIFIED IDEOGRAPH
+0xFB69 0x9E56 #CJK UNIFIED IDEOGRAPH
+0xFB6A 0x9E59 #CJK UNIFIED IDEOGRAPH
+0xFB6B 0x9E5D #CJK UNIFIED IDEOGRAPH
+0xFB6C 0x9E5F #CJK UNIFIED IDEOGRAPH
+0xFB6D 0x9E60 #CJK UNIFIED IDEOGRAPH
+0xFB6E 0x9E61 #CJK UNIFIED IDEOGRAPH
+0xFB6F 0x9E62 #CJK UNIFIED IDEOGRAPH
+0xFB70 0x9E65 #CJK UNIFIED IDEOGRAPH
+0xFB71 0x9E6E #CJK UNIFIED IDEOGRAPH
+0xFB72 0x9E6F #CJK UNIFIED IDEOGRAPH
+0xFB73 0x9E72 #CJK UNIFIED IDEOGRAPH
+0xFB74 0x9E74 #CJK UNIFIED IDEOGRAPH
+0xFB75 0x9E75 #CJK UNIFIED IDEOGRAPH
+0xFB76 0x9E76 #CJK UNIFIED IDEOGRAPH
+0xFB77 0x9E77 #CJK UNIFIED IDEOGRAPH
+0xFB78 0x9E78 #CJK UNIFIED IDEOGRAPH
+0xFB79 0x9E79 #CJK UNIFIED IDEOGRAPH
+0xFB7A 0x9E7A #CJK UNIFIED IDEOGRAPH
+0xFB7B 0x9E7B #CJK UNIFIED IDEOGRAPH
+0xFB7C 0x9E7C #CJK UNIFIED IDEOGRAPH
+0xFB7D 0x9E7D #CJK UNIFIED IDEOGRAPH
+0xFB7E 0x9E80 #CJK UNIFIED IDEOGRAPH
+0xFB80 0x9E81 #CJK UNIFIED IDEOGRAPH
+0xFB81 0x9E83 #CJK UNIFIED IDEOGRAPH
+0xFB82 0x9E84 #CJK UNIFIED IDEOGRAPH
+0xFB83 0x9E85 #CJK UNIFIED IDEOGRAPH
+0xFB84 0x9E86 #CJK UNIFIED IDEOGRAPH
+0xFB85 0x9E89 #CJK UNIFIED IDEOGRAPH
+0xFB86 0x9E8A #CJK UNIFIED IDEOGRAPH
+0xFB87 0x9E8C #CJK UNIFIED IDEOGRAPH
+0xFB88 0x9E8D #CJK UNIFIED IDEOGRAPH
+0xFB89 0x9E8E #CJK UNIFIED IDEOGRAPH
+0xFB8A 0x9E8F #CJK UNIFIED IDEOGRAPH
+0xFB8B 0x9E90 #CJK UNIFIED IDEOGRAPH
+0xFB8C 0x9E91 #CJK UNIFIED IDEOGRAPH
+0xFB8D 0x9E94 #CJK UNIFIED IDEOGRAPH
+0xFB8E 0x9E95 #CJK UNIFIED IDEOGRAPH
+0xFB8F 0x9E96 #CJK UNIFIED IDEOGRAPH
+0xFB90 0x9E97 #CJK UNIFIED IDEOGRAPH
+0xFB91 0x9E98 #CJK UNIFIED IDEOGRAPH
+0xFB92 0x9E99 #CJK UNIFIED IDEOGRAPH
+0xFB93 0x9E9A #CJK UNIFIED IDEOGRAPH
+0xFB94 0x9E9B #CJK UNIFIED IDEOGRAPH
+0xFB95 0x9E9C #CJK UNIFIED IDEOGRAPH
+0xFB96 0x9E9E #CJK UNIFIED IDEOGRAPH
+0xFB97 0x9EA0 #CJK UNIFIED IDEOGRAPH
+0xFB98 0x9EA1 #CJK UNIFIED IDEOGRAPH
+0xFB99 0x9EA2 #CJK UNIFIED IDEOGRAPH
+0xFB9A 0x9EA3 #CJK UNIFIED IDEOGRAPH
+0xFB9B 0x9EA4 #CJK UNIFIED IDEOGRAPH
+0xFB9C 0x9EA5 #CJK UNIFIED IDEOGRAPH
+0xFB9D 0x9EA7 #CJK UNIFIED IDEOGRAPH
+0xFB9E 0x9EA8 #CJK UNIFIED IDEOGRAPH
+0xFB9F 0x9EA9 #CJK UNIFIED IDEOGRAPH
+0xFBA0 0x9EAA #CJK UNIFIED IDEOGRAPH
+0xFC40 0x9EAB #CJK UNIFIED IDEOGRAPH
+0xFC41 0x9EAC #CJK UNIFIED IDEOGRAPH
+0xFC42 0x9EAD #CJK UNIFIED IDEOGRAPH
+0xFC43 0x9EAE #CJK UNIFIED IDEOGRAPH
+0xFC44 0x9EAF #CJK UNIFIED IDEOGRAPH
+0xFC45 0x9EB0 #CJK UNIFIED IDEOGRAPH
+0xFC46 0x9EB1 #CJK UNIFIED IDEOGRAPH
+0xFC47 0x9EB2 #CJK UNIFIED IDEOGRAPH
+0xFC48 0x9EB3 #CJK UNIFIED IDEOGRAPH
+0xFC49 0x9EB5 #CJK UNIFIED IDEOGRAPH
+0xFC4A 0x9EB6 #CJK UNIFIED IDEOGRAPH
+0xFC4B 0x9EB7 #CJK UNIFIED IDEOGRAPH
+0xFC4C 0x9EB9 #CJK UNIFIED IDEOGRAPH
+0xFC4D 0x9EBA #CJK UNIFIED IDEOGRAPH
+0xFC4E 0x9EBC #CJK UNIFIED IDEOGRAPH
+0xFC4F 0x9EBF #CJK UNIFIED IDEOGRAPH
+0xFC50 0x9EC0 #CJK UNIFIED IDEOGRAPH
+0xFC51 0x9EC1 #CJK UNIFIED IDEOGRAPH
+0xFC52 0x9EC2 #CJK UNIFIED IDEOGRAPH
+0xFC53 0x9EC3 #CJK UNIFIED IDEOGRAPH
+0xFC54 0x9EC5 #CJK UNIFIED IDEOGRAPH
+0xFC55 0x9EC6 #CJK UNIFIED IDEOGRAPH
+0xFC56 0x9EC7 #CJK UNIFIED IDEOGRAPH
+0xFC57 0x9EC8 #CJK UNIFIED IDEOGRAPH
+0xFC58 0x9ECA #CJK UNIFIED IDEOGRAPH
+0xFC59 0x9ECB #CJK UNIFIED IDEOGRAPH
+0xFC5A 0x9ECC #CJK UNIFIED IDEOGRAPH
+0xFC5B 0x9ED0 #CJK UNIFIED IDEOGRAPH
+0xFC5C 0x9ED2 #CJK UNIFIED IDEOGRAPH
+0xFC5D 0x9ED3 #CJK UNIFIED IDEOGRAPH
+0xFC5E 0x9ED5 #CJK UNIFIED IDEOGRAPH
+0xFC5F 0x9ED6 #CJK UNIFIED IDEOGRAPH
+0xFC60 0x9ED7 #CJK UNIFIED IDEOGRAPH
+0xFC61 0x9ED9 #CJK UNIFIED IDEOGRAPH
+0xFC62 0x9EDA #CJK UNIFIED IDEOGRAPH
+0xFC63 0x9EDE #CJK UNIFIED IDEOGRAPH
+0xFC64 0x9EE1 #CJK UNIFIED IDEOGRAPH
+0xFC65 0x9EE3 #CJK UNIFIED IDEOGRAPH
+0xFC66 0x9EE4 #CJK UNIFIED IDEOGRAPH
+0xFC67 0x9EE6 #CJK UNIFIED IDEOGRAPH
+0xFC68 0x9EE8 #CJK UNIFIED IDEOGRAPH
+0xFC69 0x9EEB #CJK UNIFIED IDEOGRAPH
+0xFC6A 0x9EEC #CJK UNIFIED IDEOGRAPH
+0xFC6B 0x9EED #CJK UNIFIED IDEOGRAPH
+0xFC6C 0x9EEE #CJK UNIFIED IDEOGRAPH
+0xFC6D 0x9EF0 #CJK UNIFIED IDEOGRAPH
+0xFC6E 0x9EF1 #CJK UNIFIED IDEOGRAPH
+0xFC6F 0x9EF2 #CJK UNIFIED IDEOGRAPH
+0xFC70 0x9EF3 #CJK UNIFIED IDEOGRAPH
+0xFC71 0x9EF4 #CJK UNIFIED IDEOGRAPH
+0xFC72 0x9EF5 #CJK UNIFIED IDEOGRAPH
+0xFC73 0x9EF6 #CJK UNIFIED IDEOGRAPH
+0xFC74 0x9EF7 #CJK UNIFIED IDEOGRAPH
+0xFC75 0x9EF8 #CJK UNIFIED IDEOGRAPH
+0xFC76 0x9EFA #CJK UNIFIED IDEOGRAPH
+0xFC77 0x9EFD #CJK UNIFIED IDEOGRAPH
+0xFC78 0x9EFF #CJK UNIFIED IDEOGRAPH
+0xFC79 0x9F00 #CJK UNIFIED IDEOGRAPH
+0xFC7A 0x9F01 #CJK UNIFIED IDEOGRAPH
+0xFC7B 0x9F02 #CJK UNIFIED IDEOGRAPH
+0xFC7C 0x9F03 #CJK UNIFIED IDEOGRAPH
+0xFC7D 0x9F04 #CJK UNIFIED IDEOGRAPH
+0xFC7E 0x9F05 #CJK UNIFIED IDEOGRAPH
+0xFC80 0x9F06 #CJK UNIFIED IDEOGRAPH
+0xFC81 0x9F07 #CJK UNIFIED IDEOGRAPH
+0xFC82 0x9F08 #CJK UNIFIED IDEOGRAPH
+0xFC83 0x9F09 #CJK UNIFIED IDEOGRAPH
+0xFC84 0x9F0A #CJK UNIFIED IDEOGRAPH
+0xFC85 0x9F0C #CJK UNIFIED IDEOGRAPH
+0xFC86 0x9F0F #CJK UNIFIED IDEOGRAPH
+0xFC87 0x9F11 #CJK UNIFIED IDEOGRAPH
+0xFC88 0x9F12 #CJK UNIFIED IDEOGRAPH
+0xFC89 0x9F14 #CJK UNIFIED IDEOGRAPH
+0xFC8A 0x9F15 #CJK UNIFIED IDEOGRAPH
+0xFC8B 0x9F16 #CJK UNIFIED IDEOGRAPH
+0xFC8C 0x9F18 #CJK UNIFIED IDEOGRAPH
+0xFC8D 0x9F1A #CJK UNIFIED IDEOGRAPH
+0xFC8E 0x9F1B #CJK UNIFIED IDEOGRAPH
+0xFC8F 0x9F1C #CJK UNIFIED IDEOGRAPH
+0xFC90 0x9F1D #CJK UNIFIED IDEOGRAPH
+0xFC91 0x9F1E #CJK UNIFIED IDEOGRAPH
+0xFC92 0x9F1F #CJK UNIFIED IDEOGRAPH
+0xFC93 0x9F21 #CJK UNIFIED IDEOGRAPH
+0xFC94 0x9F23 #CJK UNIFIED IDEOGRAPH
+0xFC95 0x9F24 #CJK UNIFIED IDEOGRAPH
+0xFC96 0x9F25 #CJK UNIFIED IDEOGRAPH
+0xFC97 0x9F26 #CJK UNIFIED IDEOGRAPH
+0xFC98 0x9F27 #CJK UNIFIED IDEOGRAPH
+0xFC99 0x9F28 #CJK UNIFIED IDEOGRAPH
+0xFC9A 0x9F29 #CJK UNIFIED IDEOGRAPH
+0xFC9B 0x9F2A #CJK UNIFIED IDEOGRAPH
+0xFC9C 0x9F2B #CJK UNIFIED IDEOGRAPH
+0xFC9D 0x9F2D #CJK UNIFIED IDEOGRAPH
+0xFC9E 0x9F2E #CJK UNIFIED IDEOGRAPH
+0xFC9F 0x9F30 #CJK UNIFIED IDEOGRAPH
+0xFCA0 0x9F31 #CJK UNIFIED IDEOGRAPH
+0xFD40 0x9F32 #CJK UNIFIED IDEOGRAPH
+0xFD41 0x9F33 #CJK UNIFIED IDEOGRAPH
+0xFD42 0x9F34 #CJK UNIFIED IDEOGRAPH
+0xFD43 0x9F35 #CJK UNIFIED IDEOGRAPH
+0xFD44 0x9F36 #CJK UNIFIED IDEOGRAPH
+0xFD45 0x9F38 #CJK UNIFIED IDEOGRAPH
+0xFD46 0x9F3A #CJK UNIFIED IDEOGRAPH
+0xFD47 0x9F3C #CJK UNIFIED IDEOGRAPH
+0xFD48 0x9F3F #CJK UNIFIED IDEOGRAPH
+0xFD49 0x9F40 #CJK UNIFIED IDEOGRAPH
+0xFD4A 0x9F41 #CJK UNIFIED IDEOGRAPH
+0xFD4B 0x9F42 #CJK UNIFIED IDEOGRAPH
+0xFD4C 0x9F43 #CJK UNIFIED IDEOGRAPH
+0xFD4D 0x9F45 #CJK UNIFIED IDEOGRAPH
+0xFD4E 0x9F46 #CJK UNIFIED IDEOGRAPH
+0xFD4F 0x9F47 #CJK UNIFIED IDEOGRAPH
+0xFD50 0x9F48 #CJK UNIFIED IDEOGRAPH
+0xFD51 0x9F49 #CJK UNIFIED IDEOGRAPH
+0xFD52 0x9F4A #CJK UNIFIED IDEOGRAPH
+0xFD53 0x9F4B #CJK UNIFIED IDEOGRAPH
+0xFD54 0x9F4C #CJK UNIFIED IDEOGRAPH
+0xFD55 0x9F4D #CJK UNIFIED IDEOGRAPH
+0xFD56 0x9F4E #CJK UNIFIED IDEOGRAPH
+0xFD57 0x9F4F #CJK UNIFIED IDEOGRAPH
+0xFD58 0x9F52 #CJK UNIFIED IDEOGRAPH
+0xFD59 0x9F53 #CJK UNIFIED IDEOGRAPH
+0xFD5A 0x9F54 #CJK UNIFIED IDEOGRAPH
+0xFD5B 0x9F55 #CJK UNIFIED IDEOGRAPH
+0xFD5C 0x9F56 #CJK UNIFIED IDEOGRAPH
+0xFD5D 0x9F57 #CJK UNIFIED IDEOGRAPH
+0xFD5E 0x9F58 #CJK UNIFIED IDEOGRAPH
+0xFD5F 0x9F59 #CJK UNIFIED IDEOGRAPH
+0xFD60 0x9F5A #CJK UNIFIED IDEOGRAPH
+0xFD61 0x9F5B #CJK UNIFIED IDEOGRAPH
+0xFD62 0x9F5C #CJK UNIFIED IDEOGRAPH
+0xFD63 0x9F5D #CJK UNIFIED IDEOGRAPH
+0xFD64 0x9F5E #CJK UNIFIED IDEOGRAPH
+0xFD65 0x9F5F #CJK UNIFIED IDEOGRAPH
+0xFD66 0x9F60 #CJK UNIFIED IDEOGRAPH
+0xFD67 0x9F61 #CJK UNIFIED IDEOGRAPH
+0xFD68 0x9F62 #CJK UNIFIED IDEOGRAPH
+0xFD69 0x9F63 #CJK UNIFIED IDEOGRAPH
+0xFD6A 0x9F64 #CJK UNIFIED IDEOGRAPH
+0xFD6B 0x9F65 #CJK UNIFIED IDEOGRAPH
+0xFD6C 0x9F66 #CJK UNIFIED IDEOGRAPH
+0xFD6D 0x9F67 #CJK UNIFIED IDEOGRAPH
+0xFD6E 0x9F68 #CJK UNIFIED IDEOGRAPH
+0xFD6F 0x9F69 #CJK UNIFIED IDEOGRAPH
+0xFD70 0x9F6A #CJK UNIFIED IDEOGRAPH
+0xFD71 0x9F6B #CJK UNIFIED IDEOGRAPH
+0xFD72 0x9F6C #CJK UNIFIED IDEOGRAPH
+0xFD73 0x9F6D #CJK UNIFIED IDEOGRAPH
+0xFD74 0x9F6E #CJK UNIFIED IDEOGRAPH
+0xFD75 0x9F6F #CJK UNIFIED IDEOGRAPH
+0xFD76 0x9F70 #CJK UNIFIED IDEOGRAPH
+0xFD77 0x9F71 #CJK UNIFIED IDEOGRAPH
+0xFD78 0x9F72 #CJK UNIFIED IDEOGRAPH
+0xFD79 0x9F73 #CJK UNIFIED IDEOGRAPH
+0xFD7A 0x9F74 #CJK UNIFIED IDEOGRAPH
+0xFD7B 0x9F75 #CJK UNIFIED IDEOGRAPH
+0xFD7C 0x9F76 #CJK UNIFIED IDEOGRAPH
+0xFD7D 0x9F77 #CJK UNIFIED IDEOGRAPH
+0xFD7E 0x9F78 #CJK UNIFIED IDEOGRAPH
+0xFD80 0x9F79 #CJK UNIFIED IDEOGRAPH
+0xFD81 0x9F7A #CJK UNIFIED IDEOGRAPH
+0xFD82 0x9F7B #CJK UNIFIED IDEOGRAPH
+0xFD83 0x9F7C #CJK UNIFIED IDEOGRAPH
+0xFD84 0x9F7D #CJK UNIFIED IDEOGRAPH
+0xFD85 0x9F7E #CJK UNIFIED IDEOGRAPH
+0xFD86 0x9F81 #CJK UNIFIED IDEOGRAPH
+0xFD87 0x9F82 #CJK UNIFIED IDEOGRAPH
+0xFD88 0x9F8D #CJK UNIFIED IDEOGRAPH
+0xFD89 0x9F8E #CJK UNIFIED IDEOGRAPH
+0xFD8A 0x9F8F #CJK UNIFIED IDEOGRAPH
+0xFD8B 0x9F90 #CJK UNIFIED IDEOGRAPH
+0xFD8C 0x9F91 #CJK UNIFIED IDEOGRAPH
+0xFD8D 0x9F92 #CJK UNIFIED IDEOGRAPH
+0xFD8E 0x9F93 #CJK UNIFIED IDEOGRAPH
+0xFD8F 0x9F94 #CJK UNIFIED IDEOGRAPH
+0xFD90 0x9F95 #CJK UNIFIED IDEOGRAPH
+0xFD91 0x9F96 #CJK UNIFIED IDEOGRAPH
+0xFD92 0x9F97 #CJK UNIFIED IDEOGRAPH
+0xFD93 0x9F98 #CJK UNIFIED IDEOGRAPH
+0xFD94 0x9F9C #CJK UNIFIED IDEOGRAPH
+0xFD95 0x9F9D #CJK UNIFIED IDEOGRAPH
+0xFD96 0x9F9E #CJK UNIFIED IDEOGRAPH
+0xFD97 0x9FA1 #CJK UNIFIED IDEOGRAPH
+0xFD98 0x9FA2 #CJK UNIFIED IDEOGRAPH
+0xFD99 0x9FA3 #CJK UNIFIED IDEOGRAPH
+0xFD9A 0x9FA4 #CJK UNIFIED IDEOGRAPH
+0xFD9B 0x9FA5 #CJK UNIFIED IDEOGRAPH
+0xFD9C 0xF92C #CJK COMPATIBILITY IDEOGRAPH
+0xFD9D 0xF979 #CJK COMPATIBILITY IDEOGRAPH
+0xFD9E 0xF995 #CJK COMPATIBILITY IDEOGRAPH
+0xFD9F 0xF9E7 #CJK COMPATIBILITY IDEOGRAPH
+0xFDA0 0xF9F1 #CJK COMPATIBILITY IDEOGRAPH
+0xFE40 0xFA0C #CJK COMPATIBILITY IDEOGRAPH
+0xFE41 0xFA0D #CJK COMPATIBILITY IDEOGRAPH
+0xFE42 0xFA0E #CJK COMPATIBILITY IDEOGRAPH
+0xFE43 0xFA0F #CJK COMPATIBILITY IDEOGRAPH
+0xFE44 0xFA11 #CJK COMPATIBILITY IDEOGRAPH
+0xFE45 0xFA13 #CJK COMPATIBILITY IDEOGRAPH
+0xFE46 0xFA14 #CJK COMPATIBILITY IDEOGRAPH
+0xFE47 0xFA18 #CJK COMPATIBILITY IDEOGRAPH
+0xFE48 0xFA1F #CJK COMPATIBILITY IDEOGRAPH
+0xFE49 0xFA20 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4A 0xFA21 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4B 0xFA23 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4C 0xFA24 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4D 0xFA27 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4E 0xFA28 #CJK COMPATIBILITY IDEOGRAPH
+0xFE4F 0xFA29 #CJK COMPATIBILITY IDEOGRAPH
diff --git a/source/codepages/CP949.TXT b/source/codepages/CP949.TXT
new file mode 100755
index 00000000000..d9a7ad3ed59
--- /dev/null
+++ b/source/codepages/CP949.TXT
@@ -0,0 +1,17320 @@
+#
+# Name: cp949 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.01
+# Table format: Format A
+# Date: 04/15/98
+#
+# Contact: cpxlate@microsoft.com
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp949 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp949 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0A 0x000A #LINE FEED
+0x0B 0x000B #VERTICAL TABULATION
+0x0C 0x000C #FORM FEED
+0x0D 0x000D #CARRIAGE RETURN
+0x0E 0x000E #SHIFT OUT
+0x0F 0x000F #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1A 0x001A #SUBSTITUTE
+0x1B 0x001B #ESCAPE
+0x1C 0x001C #FILE SEPARATOR
+0x1D 0x001D #GROUP SEPARATOR
+0x1E 0x001E #RECORD SEPARATOR
+0x1F 0x001F #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2A 0x002A #ASTERISK
+0x2B 0x002B #PLUS SIGN
+0x2C 0x002C #COMMA
+0x2D 0x002D #HYPHEN-MINUS
+0x2E 0x002E #FULL STOP
+0x2F 0x002F #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3A 0x003A #COLON
+0x3B 0x003B #SEMICOLON
+0x3C 0x003C #LESS-THAN SIGN
+0x3D 0x003D #EQUALS SIGN
+0x3E 0x003E #GREATER-THAN SIGN
+0x3F 0x003F #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4A 0x004A #LATIN CAPITAL LETTER J
+0x4B 0x004B #LATIN CAPITAL LETTER K
+0x4C 0x004C #LATIN CAPITAL LETTER L
+0x4D 0x004D #LATIN CAPITAL LETTER M
+0x4E 0x004E #LATIN CAPITAL LETTER N
+0x4F 0x004F #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5A 0x005A #LATIN CAPITAL LETTER Z
+0x5B 0x005B #LEFT SQUARE BRACKET
+0x5C 0x005C #REVERSE SOLIDUS
+0x5D 0x005D #RIGHT SQUARE BRACKET
+0x5E 0x005E #CIRCUMFLEX ACCENT
+0x5F 0x005F #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6A 0x006A #LATIN SMALL LETTER J
+0x6B 0x006B #LATIN SMALL LETTER K
+0x6C 0x006C #LATIN SMALL LETTER L
+0x6D 0x006D #LATIN SMALL LETTER M
+0x6E 0x006E #LATIN SMALL LETTER N
+0x6F 0x006F #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7A 0x007A #LATIN SMALL LETTER Z
+0x7B 0x007B #LEFT CURLY BRACKET
+0x7C 0x007C #VERTICAL LINE
+0x7D 0x007D #RIGHT CURLY BRACKET
+0x7E 0x007E #TILDE
+0x7F 0x007F #DELETE
+0x80 #UNDEFINED
+0x81 #DBCS LEAD BYTE
+0x82 #DBCS LEAD BYTE
+0x83 #DBCS LEAD BYTE
+0x84 #DBCS LEAD BYTE
+0x85 #DBCS LEAD BYTE
+0x86 #DBCS LEAD BYTE
+0x87 #DBCS LEAD BYTE
+0x88 #DBCS LEAD BYTE
+0x89 #DBCS LEAD BYTE
+0x8A #DBCS LEAD BYTE
+0x8B #DBCS LEAD BYTE
+0x8C #DBCS LEAD BYTE
+0x8D #DBCS LEAD BYTE
+0x8E #DBCS LEAD BYTE
+0x8F #DBCS LEAD BYTE
+0x90 #DBCS LEAD BYTE
+0x91 #DBCS LEAD BYTE
+0x92 #DBCS LEAD BYTE
+0x93 #DBCS LEAD BYTE
+0x94 #DBCS LEAD BYTE
+0x95 #DBCS LEAD BYTE
+0x96 #DBCS LEAD BYTE
+0x97 #DBCS LEAD BYTE
+0x98 #DBCS LEAD BYTE
+0x99 #DBCS LEAD BYTE
+0x9A #DBCS LEAD BYTE
+0x9B #DBCS LEAD BYTE
+0x9C #DBCS LEAD BYTE
+0x9D #DBCS LEAD BYTE
+0x9E #DBCS LEAD BYTE
+0x9F #DBCS LEAD BYTE
+0xA0 #DBCS LEAD BYTE
+0xA1 #DBCS LEAD BYTE
+0xA2 #DBCS LEAD BYTE
+0xA3 #DBCS LEAD BYTE
+0xA4 #DBCS LEAD BYTE
+0xA5 #DBCS LEAD BYTE
+0xA6 #DBCS LEAD BYTE
+0xA7 #DBCS LEAD BYTE
+0xA8 #DBCS LEAD BYTE
+0xA9 #DBCS LEAD BYTE
+0xAA #DBCS LEAD BYTE
+0xAB #DBCS LEAD BYTE
+0xAC #DBCS LEAD BYTE
+0xAD #DBCS LEAD BYTE
+0xAE #DBCS LEAD BYTE
+0xAF #DBCS LEAD BYTE
+0xB0 #DBCS LEAD BYTE
+0xB1 #DBCS LEAD BYTE
+0xB2 #DBCS LEAD BYTE
+0xB3 #DBCS LEAD BYTE
+0xB4 #DBCS LEAD BYTE
+0xB5 #DBCS LEAD BYTE
+0xB6 #DBCS LEAD BYTE
+0xB7 #DBCS LEAD BYTE
+0xB8 #DBCS LEAD BYTE
+0xB9 #DBCS LEAD BYTE
+0xBA #DBCS LEAD BYTE
+0xBB #DBCS LEAD BYTE
+0xBC #DBCS LEAD BYTE
+0xBD #DBCS LEAD BYTE
+0xBE #DBCS LEAD BYTE
+0xBF #DBCS LEAD BYTE
+0xC0 #DBCS LEAD BYTE
+0xC1 #DBCS LEAD BYTE
+0xC2 #DBCS LEAD BYTE
+0xC3 #DBCS LEAD BYTE
+0xC4 #DBCS LEAD BYTE
+0xC5 #DBCS LEAD BYTE
+0xC6 #DBCS LEAD BYTE
+0xC7 #DBCS LEAD BYTE
+0xC8 #DBCS LEAD BYTE
+0xC9 #DBCS LEAD BYTE
+0xCA #DBCS LEAD BYTE
+0xCB #DBCS LEAD BYTE
+0xCC #DBCS LEAD BYTE
+0xCD #DBCS LEAD BYTE
+0xCE #DBCS LEAD BYTE
+0xCF #DBCS LEAD BYTE
+0xD0 #DBCS LEAD BYTE
+0xD1 #DBCS LEAD BYTE
+0xD2 #DBCS LEAD BYTE
+0xD3 #DBCS LEAD BYTE
+0xD4 #DBCS LEAD BYTE
+0xD5 #DBCS LEAD BYTE
+0xD6 #DBCS LEAD BYTE
+0xD7 #DBCS LEAD BYTE
+0xD8 #DBCS LEAD BYTE
+0xD9 #DBCS LEAD BYTE
+0xDA #DBCS LEAD BYTE
+0xDB #DBCS LEAD BYTE
+0xDC #DBCS LEAD BYTE
+0xDD #DBCS LEAD BYTE
+0xDE #DBCS LEAD BYTE
+0xDF #DBCS LEAD BYTE
+0xE0 #DBCS LEAD BYTE
+0xE1 #DBCS LEAD BYTE
+0xE2 #DBCS LEAD BYTE
+0xE3 #DBCS LEAD BYTE
+0xE4 #DBCS LEAD BYTE
+0xE5 #DBCS LEAD BYTE
+0xE6 #DBCS LEAD BYTE
+0xE7 #DBCS LEAD BYTE
+0xE8 #DBCS LEAD BYTE
+0xE9 #DBCS LEAD BYTE
+0xEA #DBCS LEAD BYTE
+0xEB #DBCS LEAD BYTE
+0xEC #DBCS LEAD BYTE
+0xED #DBCS LEAD BYTE
+0xEE #DBCS LEAD BYTE
+0xEF #DBCS LEAD BYTE
+0xF0 #DBCS LEAD BYTE
+0xF1 #DBCS LEAD BYTE
+0xF2 #DBCS LEAD BYTE
+0xF3 #DBCS LEAD BYTE
+0xF4 #DBCS LEAD BYTE
+0xF5 #DBCS LEAD BYTE
+0xF6 #DBCS LEAD BYTE
+0xF7 #DBCS LEAD BYTE
+0xF8 #DBCS LEAD BYTE
+0xF9 #DBCS LEAD BYTE
+0xFA #DBCS LEAD BYTE
+0xFB #DBCS LEAD BYTE
+0xFC #DBCS LEAD BYTE
+0xFD #DBCS LEAD BYTE
+0xFE #DBCS LEAD BYTE
+0xFF #UNDEFINED
+0x8141 0xAC02 #HANGUL SYLLABLE KIYEOK A SSANGKIYEOK
+0x8142 0xAC03 #HANGUL SYLLABLE KIYEOK A KIYEOKSIOS
+0x8143 0xAC05 #HANGUL SYLLABLE KIYEOK A NIEUNCIEUC
+0x8144 0xAC06 #HANGUL SYLLABLE KIYEOK A NIEUNHIEUH
+0x8145 0xAC0B #HANGUL SYLLABLE KIYEOK A RIEULPIEUP
+0x8146 0xAC0C #HANGUL SYLLABLE KIYEOK A RIEULSIOS
+0x8147 0xAC0D #HANGUL SYLLABLE KIYEOK A RIEULTHIEUTH
+0x8148 0xAC0E #HANGUL SYLLABLE KIYEOK A RIEULPHIEUPH
+0x8149 0xAC0F #HANGUL SYLLABLE KIYEOK A RIEULHIEUH
+0x814A 0xAC18 #HANGUL SYLLABLE KIYEOK A KHIEUKH
+0x814B 0xAC1E #HANGUL SYLLABLE KIYEOK AE SSANGKIYEOK
+0x814C 0xAC1F #HANGUL SYLLABLE KIYEOK AE KIYEOKSIOS
+0x814D 0xAC21 #HANGUL SYLLABLE KIYEOK AE NIEUNCIEUC
+0x814E 0xAC22 #HANGUL SYLLABLE KIYEOK AE NIEUNHIEUH
+0x814F 0xAC23 #HANGUL SYLLABLE KIYEOK AE TIKEUT
+0x8150 0xAC25 #HANGUL SYLLABLE KIYEOK AE RIEULKIYEOK
+0x8151 0xAC26 #HANGUL SYLLABLE KIYEOK AE RIEULMIEUM
+0x8152 0xAC27 #HANGUL SYLLABLE KIYEOK AE RIEULPIEUP
+0x8153 0xAC28 #HANGUL SYLLABLE KIYEOK AE RIEULSIOS
+0x8154 0xAC29 #HANGUL SYLLABLE KIYEOK AE RIEULTHIEUTH
+0x8155 0xAC2A #HANGUL SYLLABLE KIYEOK AE RIEULPHIEUPH
+0x8156 0xAC2B #HANGUL SYLLABLE KIYEOK AE RIEULHIEUH
+0x8157 0xAC2E #HANGUL SYLLABLE KIYEOK AE PIEUPSIOS
+0x8158 0xAC32 #HANGUL SYLLABLE KIYEOK AE CIEUC
+0x8159 0xAC33 #HANGUL SYLLABLE KIYEOK AE CHIEUCH
+0x815A 0xAC34 #HANGUL SYLLABLE KIYEOK AE KHIEUKH
+0x8161 0xAC35 #HANGUL SYLLABLE KIYEOK AE THIEUTH
+0x8162 0xAC36 #HANGUL SYLLABLE KIYEOK AE PHIEUPH
+0x8163 0xAC37 #HANGUL SYLLABLE KIYEOK AE HIEUH
+0x8164 0xAC3A #HANGUL SYLLABLE KIYEOK YA SSANGKIYEOK
+0x8165 0xAC3B #HANGUL SYLLABLE KIYEOK YA KIYEOKSIOS
+0x8166 0xAC3D #HANGUL SYLLABLE KIYEOK YA NIEUNCIEUC
+0x8167 0xAC3E #HANGUL SYLLABLE KIYEOK YA NIEUNHIEUH
+0x8168 0xAC3F #HANGUL SYLLABLE KIYEOK YA TIKEUT
+0x8169 0xAC41 #HANGUL SYLLABLE KIYEOK YA RIEULKIYEOK
+0x816A 0xAC42 #HANGUL SYLLABLE KIYEOK YA RIEULMIEUM
+0x816B 0xAC43 #HANGUL SYLLABLE KIYEOK YA RIEULPIEUP
+0x816C 0xAC44 #HANGUL SYLLABLE KIYEOK YA RIEULSIOS
+0x816D 0xAC45 #HANGUL SYLLABLE KIYEOK YA RIEULTHIEUTH
+0x816E 0xAC46 #HANGUL SYLLABLE KIYEOK YA RIEULPHIEUPH
+0x816F 0xAC47 #HANGUL SYLLABLE KIYEOK YA RIEULHIEUH
+0x8170 0xAC48 #HANGUL SYLLABLE KIYEOK YA MIEUM
+0x8171 0xAC49 #HANGUL SYLLABLE KIYEOK YA PIEUP
+0x8172 0xAC4A #HANGUL SYLLABLE KIYEOK YA PIEUPSIOS
+0x8173 0xAC4C #HANGUL SYLLABLE KIYEOK YA SSANGSIOS
+0x8174 0xAC4E #HANGUL SYLLABLE KIYEOK YA CIEUC
+0x8175 0xAC4F #HANGUL SYLLABLE KIYEOK YA CHIEUCH
+0x8176 0xAC50 #HANGUL SYLLABLE KIYEOK YA KHIEUKH
+0x8177 0xAC51 #HANGUL SYLLABLE KIYEOK YA THIEUTH
+0x8178 0xAC52 #HANGUL SYLLABLE KIYEOK YA PHIEUPH
+0x8179 0xAC53 #HANGUL SYLLABLE KIYEOK YA HIEUH
+0x817A 0xAC55 #HANGUL SYLLABLE KIYEOK YAE KIYEOK
+0x8181 0xAC56 #HANGUL SYLLABLE KIYEOK YAE SSANGKIYEOK
+0x8182 0xAC57 #HANGUL SYLLABLE KIYEOK YAE KIYEOKSIOS
+0x8183 0xAC59 #HANGUL SYLLABLE KIYEOK YAE NIEUNCIEUC
+0x8184 0xAC5A #HANGUL SYLLABLE KIYEOK YAE NIEUNHIEUH
+0x8185 0xAC5B #HANGUL SYLLABLE KIYEOK YAE TIKEUT
+0x8186 0xAC5D #HANGUL SYLLABLE KIYEOK YAE RIEULKIYEOK
+0x8187 0xAC5E #HANGUL SYLLABLE KIYEOK YAE RIEULMIEUM
+0x8188 0xAC5F #HANGUL SYLLABLE KIYEOK YAE RIEULPIEUP
+0x8189 0xAC60 #HANGUL SYLLABLE KIYEOK YAE RIEULSIOS
+0x818A 0xAC61 #HANGUL SYLLABLE KIYEOK YAE RIEULTHIEUTH
+0x818B 0xAC62 #HANGUL SYLLABLE KIYEOK YAE RIEULPHIEUPH
+0x818C 0xAC63 #HANGUL SYLLABLE KIYEOK YAE RIEULHIEUH
+0x818D 0xAC64 #HANGUL SYLLABLE KIYEOK YAE MIEUM
+0x818E 0xAC65 #HANGUL SYLLABLE KIYEOK YAE PIEUP
+0x818F 0xAC66 #HANGUL SYLLABLE KIYEOK YAE PIEUPSIOS
+0x8190 0xAC67 #HANGUL SYLLABLE KIYEOK YAE SIOS
+0x8191 0xAC68 #HANGUL SYLLABLE KIYEOK YAE SSANGSIOS
+0x8192 0xAC69 #HANGUL SYLLABLE KIYEOK YAE IEUNG
+0x8193 0xAC6A #HANGUL SYLLABLE KIYEOK YAE CIEUC
+0x8194 0xAC6B #HANGUL SYLLABLE KIYEOK YAE CHIEUCH
+0x8195 0xAC6C #HANGUL SYLLABLE KIYEOK YAE KHIEUKH
+0x8196 0xAC6D #HANGUL SYLLABLE KIYEOK YAE THIEUTH
+0x8197 0xAC6E #HANGUL SYLLABLE KIYEOK YAE PHIEUPH
+0x8198 0xAC6F #HANGUL SYLLABLE KIYEOK YAE HIEUH
+0x8199 0xAC72 #HANGUL SYLLABLE KIYEOK EO SSANGKIYEOK
+0x819A 0xAC73 #HANGUL SYLLABLE KIYEOK EO KIYEOKSIOS
+0x819B 0xAC75 #HANGUL SYLLABLE KIYEOK EO NIEUNCIEUC
+0x819C 0xAC76 #HANGUL SYLLABLE KIYEOK EO NIEUNHIEUH
+0x819D 0xAC79 #HANGUL SYLLABLE KIYEOK EO RIEULKIYEOK
+0x819E 0xAC7B #HANGUL SYLLABLE KIYEOK EO RIEULPIEUP
+0x819F 0xAC7C #HANGUL SYLLABLE KIYEOK EO RIEULSIOS
+0x81A0 0xAC7D #HANGUL SYLLABLE KIYEOK EO RIEULTHIEUTH
+0x81A1 0xAC7E #HANGUL SYLLABLE KIYEOK EO RIEULPHIEUPH
+0x81A2 0xAC7F #HANGUL SYLLABLE KIYEOK EO RIEULHIEUH
+0x81A3 0xAC82 #HANGUL SYLLABLE KIYEOK EO PIEUPSIOS
+0x81A4 0xAC87 #HANGUL SYLLABLE KIYEOK EO CHIEUCH
+0x81A5 0xAC88 #HANGUL SYLLABLE KIYEOK EO KHIEUKH
+0x81A6 0xAC8D #HANGUL SYLLABLE KIYEOK E KIYEOK
+0x81A7 0xAC8E #HANGUL SYLLABLE KIYEOK E SSANGKIYEOK
+0x81A8 0xAC8F #HANGUL SYLLABLE KIYEOK E KIYEOKSIOS
+0x81A9 0xAC91 #HANGUL SYLLABLE KIYEOK E NIEUNCIEUC
+0x81AA 0xAC92 #HANGUL SYLLABLE KIYEOK E NIEUNHIEUH
+0x81AB 0xAC93 #HANGUL SYLLABLE KIYEOK E TIKEUT
+0x81AC 0xAC95 #HANGUL SYLLABLE KIYEOK E RIEULKIYEOK
+0x81AD 0xAC96 #HANGUL SYLLABLE KIYEOK E RIEULMIEUM
+0x81AE 0xAC97 #HANGUL SYLLABLE KIYEOK E RIEULPIEUP
+0x81AF 0xAC98 #HANGUL SYLLABLE KIYEOK E RIEULSIOS
+0x81B0 0xAC99 #HANGUL SYLLABLE KIYEOK E RIEULTHIEUTH
+0x81B1 0xAC9A #HANGUL SYLLABLE KIYEOK E RIEULPHIEUPH
+0x81B2 0xAC9B #HANGUL SYLLABLE KIYEOK E RIEULHIEUH
+0x81B3 0xAC9E #HANGUL SYLLABLE KIYEOK E PIEUPSIOS
+0x81B4 0xACA2 #HANGUL SYLLABLE KIYEOK E CIEUC
+0x81B5 0xACA3 #HANGUL SYLLABLE KIYEOK E CHIEUCH
+0x81B6 0xACA4 #HANGUL SYLLABLE KIYEOK E KHIEUKH
+0x81B7 0xACA5 #HANGUL SYLLABLE KIYEOK E THIEUTH
+0x81B8 0xACA6 #HANGUL SYLLABLE KIYEOK E PHIEUPH
+0x81B9 0xACA7 #HANGUL SYLLABLE KIYEOK E HIEUH
+0x81BA 0xACAB #HANGUL SYLLABLE KIYEOK YEO KIYEOKSIOS
+0x81BB 0xACAD #HANGUL SYLLABLE KIYEOK YEO NIEUNCIEUC
+0x81BC 0xACAE #HANGUL SYLLABLE KIYEOK YEO NIEUNHIEUH
+0x81BD 0xACB1 #HANGUL SYLLABLE KIYEOK YEO RIEULKIYEOK
+0x81BE 0xACB2 #HANGUL SYLLABLE KIYEOK YEO RIEULMIEUM
+0x81BF 0xACB3 #HANGUL SYLLABLE KIYEOK YEO RIEULPIEUP
+0x81C0 0xACB4 #HANGUL SYLLABLE KIYEOK YEO RIEULSIOS
+0x81C1 0xACB5 #HANGUL SYLLABLE KIYEOK YEO RIEULTHIEUTH
+0x81C2 0xACB6 #HANGUL SYLLABLE KIYEOK YEO RIEULPHIEUPH
+0x81C3 0xACB7 #HANGUL SYLLABLE KIYEOK YEO RIEULHIEUH
+0x81C4 0xACBA #HANGUL SYLLABLE KIYEOK YEO PIEUPSIOS
+0x81C5 0xACBE #HANGUL SYLLABLE KIYEOK YEO CIEUC
+0x81C6 0xACBF #HANGUL SYLLABLE KIYEOK YEO CHIEUCH
+0x81C7 0xACC0 #HANGUL SYLLABLE KIYEOK YEO KHIEUKH
+0x81C8 0xACC2 #HANGUL SYLLABLE KIYEOK YEO PHIEUPH
+0x81C9 0xACC3 #HANGUL SYLLABLE KIYEOK YEO HIEUH
+0x81CA 0xACC5 #HANGUL SYLLABLE KIYEOK YE KIYEOK
+0x81CB 0xACC6 #HANGUL SYLLABLE KIYEOK YE SSANGKIYEOK
+0x81CC 0xACC7 #HANGUL SYLLABLE KIYEOK YE KIYEOKSIOS
+0x81CD 0xACC9 #HANGUL SYLLABLE KIYEOK YE NIEUNCIEUC
+0x81CE 0xACCA #HANGUL SYLLABLE KIYEOK YE NIEUNHIEUH
+0x81CF 0xACCB #HANGUL SYLLABLE KIYEOK YE TIKEUT
+0x81D0 0xACCD #HANGUL SYLLABLE KIYEOK YE RIEULKIYEOK
+0x81D1 0xACCE #HANGUL SYLLABLE KIYEOK YE RIEULMIEUM
+0x81D2 0xACCF #HANGUL SYLLABLE KIYEOK YE RIEULPIEUP
+0x81D3 0xACD0 #HANGUL SYLLABLE KIYEOK YE RIEULSIOS
+0x81D4 0xACD1 #HANGUL SYLLABLE KIYEOK YE RIEULTHIEUTH
+0x81D5 0xACD2 #HANGUL SYLLABLE KIYEOK YE RIEULPHIEUPH
+0x81D6 0xACD3 #HANGUL SYLLABLE KIYEOK YE RIEULHIEUH
+0x81D7 0xACD4 #HANGUL SYLLABLE KIYEOK YE MIEUM
+0x81D8 0xACD6 #HANGUL SYLLABLE KIYEOK YE PIEUPSIOS
+0x81D9 0xACD8 #HANGUL SYLLABLE KIYEOK YE SSANGSIOS
+0x81DA 0xACD9 #HANGUL SYLLABLE KIYEOK YE IEUNG
+0x81DB 0xACDA #HANGUL SYLLABLE KIYEOK YE CIEUC
+0x81DC 0xACDB #HANGUL SYLLABLE KIYEOK YE CHIEUCH
+0x81DD 0xACDC #HANGUL SYLLABLE KIYEOK YE KHIEUKH
+0x81DE 0xACDD #HANGUL SYLLABLE KIYEOK YE THIEUTH
+0x81DF 0xACDE #HANGUL SYLLABLE KIYEOK YE PHIEUPH
+0x81E0 0xACDF #HANGUL SYLLABLE KIYEOK YE HIEUH
+0x81E1 0xACE2 #HANGUL SYLLABLE KIYEOK O SSANGKIYEOK
+0x81E2 0xACE3 #HANGUL SYLLABLE KIYEOK O KIYEOKSIOS
+0x81E3 0xACE5 #HANGUL SYLLABLE KIYEOK O NIEUNCIEUC
+0x81E4 0xACE6 #HANGUL SYLLABLE KIYEOK O NIEUNHIEUH
+0x81E5 0xACE9 #HANGUL SYLLABLE KIYEOK O RIEULKIYEOK
+0x81E6 0xACEB #HANGUL SYLLABLE KIYEOK O RIEULPIEUP
+0x81E7 0xACED #HANGUL SYLLABLE KIYEOK O RIEULTHIEUTH
+0x81E8 0xACEE #HANGUL SYLLABLE KIYEOK O RIEULPHIEUPH
+0x81E9 0xACF2 #HANGUL SYLLABLE KIYEOK O PIEUPSIOS
+0x81EA 0xACF4 #HANGUL SYLLABLE KIYEOK O SSANGSIOS
+0x81EB 0xACF7 #HANGUL SYLLABLE KIYEOK O CHIEUCH
+0x81EC 0xACF8 #HANGUL SYLLABLE KIYEOK O KHIEUKH
+0x81ED 0xACF9 #HANGUL SYLLABLE KIYEOK O THIEUTH
+0x81EE 0xACFA #HANGUL SYLLABLE KIYEOK O PHIEUPH
+0x81EF 0xACFB #HANGUL SYLLABLE KIYEOK O HIEUH
+0x81F0 0xACFE #HANGUL SYLLABLE KIYEOK WA SSANGKIYEOK
+0x81F1 0xACFF #HANGUL SYLLABLE KIYEOK WA KIYEOKSIOS
+0x81F2 0xAD01 #HANGUL SYLLABLE KIYEOK WA NIEUNCIEUC
+0x81F3 0xAD02 #HANGUL SYLLABLE KIYEOK WA NIEUNHIEUH
+0x81F4 0xAD03 #HANGUL SYLLABLE KIYEOK WA TIKEUT
+0x81F5 0xAD05 #HANGUL SYLLABLE KIYEOK WA RIEULKIYEOK
+0x81F6 0xAD07 #HANGUL SYLLABLE KIYEOK WA RIEULPIEUP
+0x81F7 0xAD08 #HANGUL SYLLABLE KIYEOK WA RIEULSIOS
+0x81F8 0xAD09 #HANGUL SYLLABLE KIYEOK WA RIEULTHIEUTH
+0x81F9 0xAD0A #HANGUL SYLLABLE KIYEOK WA RIEULPHIEUPH
+0x81FA 0xAD0B #HANGUL SYLLABLE KIYEOK WA RIEULHIEUH
+0x81FB 0xAD0E #HANGUL SYLLABLE KIYEOK WA PIEUPSIOS
+0x81FC 0xAD10 #HANGUL SYLLABLE KIYEOK WA SSANGSIOS
+0x81FD 0xAD12 #HANGUL SYLLABLE KIYEOK WA CIEUC
+0x81FE 0xAD13 #HANGUL SYLLABLE KIYEOK WA CHIEUCH
+0x8241 0xAD14 #HANGUL SYLLABLE KIYEOK WA KHIEUKH
+0x8242 0xAD15 #HANGUL SYLLABLE KIYEOK WA THIEUTH
+0x8243 0xAD16 #HANGUL SYLLABLE KIYEOK WA PHIEUPH
+0x8244 0xAD17 #HANGUL SYLLABLE KIYEOK WA HIEUH
+0x8245 0xAD19 #HANGUL SYLLABLE KIYEOK WAE KIYEOK
+0x8246 0xAD1A #HANGUL SYLLABLE KIYEOK WAE SSANGKIYEOK
+0x8247 0xAD1B #HANGUL SYLLABLE KIYEOK WAE KIYEOKSIOS
+0x8248 0xAD1D #HANGUL SYLLABLE KIYEOK WAE NIEUNCIEUC
+0x8249 0xAD1E #HANGUL SYLLABLE KIYEOK WAE NIEUNHIEUH
+0x824A 0xAD1F #HANGUL SYLLABLE KIYEOK WAE TIKEUT
+0x824B 0xAD21 #HANGUL SYLLABLE KIYEOK WAE RIEULKIYEOK
+0x824C 0xAD22 #HANGUL SYLLABLE KIYEOK WAE RIEULMIEUM
+0x824D 0xAD23 #HANGUL SYLLABLE KIYEOK WAE RIEULPIEUP
+0x824E 0xAD24 #HANGUL SYLLABLE KIYEOK WAE RIEULSIOS
+0x824F 0xAD25 #HANGUL SYLLABLE KIYEOK WAE RIEULTHIEUTH
+0x8250 0xAD26 #HANGUL SYLLABLE KIYEOK WAE RIEULPHIEUPH
+0x8251 0xAD27 #HANGUL SYLLABLE KIYEOK WAE RIEULHIEUH
+0x8252 0xAD28 #HANGUL SYLLABLE KIYEOK WAE MIEUM
+0x8253 0xAD2A #HANGUL SYLLABLE KIYEOK WAE PIEUPSIOS
+0x8254 0xAD2B #HANGUL SYLLABLE KIYEOK WAE SIOS
+0x8255 0xAD2E #HANGUL SYLLABLE KIYEOK WAE CIEUC
+0x8256 0xAD2F #HANGUL SYLLABLE KIYEOK WAE CHIEUCH
+0x8257 0xAD30 #HANGUL SYLLABLE KIYEOK WAE KHIEUKH
+0x8258 0xAD31 #HANGUL SYLLABLE KIYEOK WAE THIEUTH
+0x8259 0xAD32 #HANGUL SYLLABLE KIYEOK WAE PHIEUPH
+0x825A 0xAD33 #HANGUL SYLLABLE KIYEOK WAE HIEUH
+0x8261 0xAD36 #HANGUL SYLLABLE KIYEOK OE SSANGKIYEOK
+0x8262 0xAD37 #HANGUL SYLLABLE KIYEOK OE KIYEOKSIOS
+0x8263 0xAD39 #HANGUL SYLLABLE KIYEOK OE NIEUNCIEUC
+0x8264 0xAD3A #HANGUL SYLLABLE KIYEOK OE NIEUNHIEUH
+0x8265 0xAD3B #HANGUL SYLLABLE KIYEOK OE TIKEUT
+0x8266 0xAD3D #HANGUL SYLLABLE KIYEOK OE RIEULKIYEOK
+0x8267 0xAD3E #HANGUL SYLLABLE KIYEOK OE RIEULMIEUM
+0x8268 0xAD3F #HANGUL SYLLABLE KIYEOK OE RIEULPIEUP
+0x8269 0xAD40 #HANGUL SYLLABLE KIYEOK OE RIEULSIOS
+0x826A 0xAD41 #HANGUL SYLLABLE KIYEOK OE RIEULTHIEUTH
+0x826B 0xAD42 #HANGUL SYLLABLE KIYEOK OE RIEULPHIEUPH
+0x826C 0xAD43 #HANGUL SYLLABLE KIYEOK OE RIEULHIEUH
+0x826D 0xAD46 #HANGUL SYLLABLE KIYEOK OE PIEUPSIOS
+0x826E 0xAD48 #HANGUL SYLLABLE KIYEOK OE SSANGSIOS
+0x826F 0xAD4A #HANGUL SYLLABLE KIYEOK OE CIEUC
+0x8270 0xAD4B #HANGUL SYLLABLE KIYEOK OE CHIEUCH
+0x8271 0xAD4C #HANGUL SYLLABLE KIYEOK OE KHIEUKH
+0x8272 0xAD4D #HANGUL SYLLABLE KIYEOK OE THIEUTH
+0x8273 0xAD4E #HANGUL SYLLABLE KIYEOK OE PHIEUPH
+0x8274 0xAD4F #HANGUL SYLLABLE KIYEOK OE HIEUH
+0x8275 0xAD51 #HANGUL SYLLABLE KIYEOK YO KIYEOK
+0x8276 0xAD52 #HANGUL SYLLABLE KIYEOK YO SSANGKIYEOK
+0x8277 0xAD53 #HANGUL SYLLABLE KIYEOK YO KIYEOKSIOS
+0x8278 0xAD55 #HANGUL SYLLABLE KIYEOK YO NIEUNCIEUC
+0x8279 0xAD56 #HANGUL SYLLABLE KIYEOK YO NIEUNHIEUH
+0x827A 0xAD57 #HANGUL SYLLABLE KIYEOK YO TIKEUT
+0x8281 0xAD59 #HANGUL SYLLABLE KIYEOK YO RIEULKIYEOK
+0x8282 0xAD5A #HANGUL SYLLABLE KIYEOK YO RIEULMIEUM
+0x8283 0xAD5B #HANGUL SYLLABLE KIYEOK YO RIEULPIEUP
+0x8284 0xAD5C #HANGUL SYLLABLE KIYEOK YO RIEULSIOS
+0x8285 0xAD5D #HANGUL SYLLABLE KIYEOK YO RIEULTHIEUTH
+0x8286 0xAD5E #HANGUL SYLLABLE KIYEOK YO RIEULPHIEUPH
+0x8287 0xAD5F #HANGUL SYLLABLE KIYEOK YO RIEULHIEUH
+0x8288 0xAD60 #HANGUL SYLLABLE KIYEOK YO MIEUM
+0x8289 0xAD62 #HANGUL SYLLABLE KIYEOK YO PIEUPSIOS
+0x828A 0xAD64 #HANGUL SYLLABLE KIYEOK YO SSANGSIOS
+0x828B 0xAD65 #HANGUL SYLLABLE KIYEOK YO IEUNG
+0x828C 0xAD66 #HANGUL SYLLABLE KIYEOK YO CIEUC
+0x828D 0xAD67 #HANGUL SYLLABLE KIYEOK YO CHIEUCH
+0x828E 0xAD68 #HANGUL SYLLABLE KIYEOK YO KHIEUKH
+0x828F 0xAD69 #HANGUL SYLLABLE KIYEOK YO THIEUTH
+0x8290 0xAD6A #HANGUL SYLLABLE KIYEOK YO PHIEUPH
+0x8291 0xAD6B #HANGUL SYLLABLE KIYEOK YO HIEUH
+0x8292 0xAD6E #HANGUL SYLLABLE KIYEOK U SSANGKIYEOK
+0x8293 0xAD6F #HANGUL SYLLABLE KIYEOK U KIYEOKSIOS
+0x8294 0xAD71 #HANGUL SYLLABLE KIYEOK U NIEUNCIEUC
+0x8295 0xAD72 #HANGUL SYLLABLE KIYEOK U NIEUNHIEUH
+0x8296 0xAD77 #HANGUL SYLLABLE KIYEOK U RIEULPIEUP
+0x8297 0xAD78 #HANGUL SYLLABLE KIYEOK U RIEULSIOS
+0x8298 0xAD79 #HANGUL SYLLABLE KIYEOK U RIEULTHIEUTH
+0x8299 0xAD7A #HANGUL SYLLABLE KIYEOK U RIEULPHIEUPH
+0x829A 0xAD7E #HANGUL SYLLABLE KIYEOK U PIEUPSIOS
+0x829B 0xAD80 #HANGUL SYLLABLE KIYEOK U SSANGSIOS
+0x829C 0xAD83 #HANGUL SYLLABLE KIYEOK U CHIEUCH
+0x829D 0xAD84 #HANGUL SYLLABLE KIYEOK U KHIEUKH
+0x829E 0xAD85 #HANGUL SYLLABLE KIYEOK U THIEUTH
+0x829F 0xAD86 #HANGUL SYLLABLE KIYEOK U PHIEUPH
+0x82A0 0xAD87 #HANGUL SYLLABLE KIYEOK U HIEUH
+0x82A1 0xAD8A #HANGUL SYLLABLE KIYEOK WEO SSANGKIYEOK
+0x82A2 0xAD8B #HANGUL SYLLABLE KIYEOK WEO KIYEOKSIOS
+0x82A3 0xAD8D #HANGUL SYLLABLE KIYEOK WEO NIEUNCIEUC
+0x82A4 0xAD8E #HANGUL SYLLABLE KIYEOK WEO NIEUNHIEUH
+0x82A5 0xAD8F #HANGUL SYLLABLE KIYEOK WEO TIKEUT
+0x82A6 0xAD91 #HANGUL SYLLABLE KIYEOK WEO RIEULKIYEOK
+0x82A7 0xAD92 #HANGUL SYLLABLE KIYEOK WEO RIEULMIEUM
+0x82A8 0xAD93 #HANGUL SYLLABLE KIYEOK WEO RIEULPIEUP
+0x82A9 0xAD94 #HANGUL SYLLABLE KIYEOK WEO RIEULSIOS
+0x82AA 0xAD95 #HANGUL SYLLABLE KIYEOK WEO RIEULTHIEUTH
+0x82AB 0xAD96 #HANGUL SYLLABLE KIYEOK WEO RIEULPHIEUPH
+0x82AC 0xAD97 #HANGUL SYLLABLE KIYEOK WEO RIEULHIEUH
+0x82AD 0xAD98 #HANGUL SYLLABLE KIYEOK WEO MIEUM
+0x82AE 0xAD99 #HANGUL SYLLABLE KIYEOK WEO PIEUP
+0x82AF 0xAD9A #HANGUL SYLLABLE KIYEOK WEO PIEUPSIOS
+0x82B0 0xAD9B #HANGUL SYLLABLE KIYEOK WEO SIOS
+0x82B1 0xAD9E #HANGUL SYLLABLE KIYEOK WEO CIEUC
+0x82B2 0xAD9F #HANGUL SYLLABLE KIYEOK WEO CHIEUCH
+0x82B3 0xADA0 #HANGUL SYLLABLE KIYEOK WEO KHIEUKH
+0x82B4 0xADA1 #HANGUL SYLLABLE KIYEOK WEO THIEUTH
+0x82B5 0xADA2 #HANGUL SYLLABLE KIYEOK WEO PHIEUPH
+0x82B6 0xADA3 #HANGUL SYLLABLE KIYEOK WEO HIEUH
+0x82B7 0xADA5 #HANGUL SYLLABLE KIYEOK WE KIYEOK
+0x82B8 0xADA6 #HANGUL SYLLABLE KIYEOK WE SSANGKIYEOK
+0x82B9 0xADA7 #HANGUL SYLLABLE KIYEOK WE KIYEOKSIOS
+0x82BA 0xADA8 #HANGUL SYLLABLE KIYEOK WE NIEUN
+0x82BB 0xADA9 #HANGUL SYLLABLE KIYEOK WE NIEUNCIEUC
+0x82BC 0xADAA #HANGUL SYLLABLE KIYEOK WE NIEUNHIEUH
+0x82BD 0xADAB #HANGUL SYLLABLE KIYEOK WE TIKEUT
+0x82BE 0xADAC #HANGUL SYLLABLE KIYEOK WE RIEUL
+0x82BF 0xADAD #HANGUL SYLLABLE KIYEOK WE RIEULKIYEOK
+0x82C0 0xADAE #HANGUL SYLLABLE KIYEOK WE RIEULMIEUM
+0x82C1 0xADAF #HANGUL SYLLABLE KIYEOK WE RIEULPIEUP
+0x82C2 0xADB0 #HANGUL SYLLABLE KIYEOK WE RIEULSIOS
+0x82C3 0xADB1 #HANGUL SYLLABLE KIYEOK WE RIEULTHIEUTH
+0x82C4 0xADB2 #HANGUL SYLLABLE KIYEOK WE RIEULPHIEUPH
+0x82C5 0xADB3 #HANGUL SYLLABLE KIYEOK WE RIEULHIEUH
+0x82C6 0xADB4 #HANGUL SYLLABLE KIYEOK WE MIEUM
+0x82C7 0xADB5 #HANGUL SYLLABLE KIYEOK WE PIEUP
+0x82C8 0xADB6 #HANGUL SYLLABLE KIYEOK WE PIEUPSIOS
+0x82C9 0xADB8 #HANGUL SYLLABLE KIYEOK WE SSANGSIOS
+0x82CA 0xADB9 #HANGUL SYLLABLE KIYEOK WE IEUNG
+0x82CB 0xADBA #HANGUL SYLLABLE KIYEOK WE CIEUC
+0x82CC 0xADBB #HANGUL SYLLABLE KIYEOK WE CHIEUCH
+0x82CD 0xADBC #HANGUL SYLLABLE KIYEOK WE KHIEUKH
+0x82CE 0xADBD #HANGUL SYLLABLE KIYEOK WE THIEUTH
+0x82CF 0xADBE #HANGUL SYLLABLE KIYEOK WE PHIEUPH
+0x82D0 0xADBF #HANGUL SYLLABLE KIYEOK WE HIEUH
+0x82D1 0xADC2 #HANGUL SYLLABLE KIYEOK WI SSANGKIYEOK
+0x82D2 0xADC3 #HANGUL SYLLABLE KIYEOK WI KIYEOKSIOS
+0x82D3 0xADC5 #HANGUL SYLLABLE KIYEOK WI NIEUNCIEUC
+0x82D4 0xADC6 #HANGUL SYLLABLE KIYEOK WI NIEUNHIEUH
+0x82D5 0xADC7 #HANGUL SYLLABLE KIYEOK WI TIKEUT
+0x82D6 0xADC9 #HANGUL SYLLABLE KIYEOK WI RIEULKIYEOK
+0x82D7 0xADCA #HANGUL SYLLABLE KIYEOK WI RIEULMIEUM
+0x82D8 0xADCB #HANGUL SYLLABLE KIYEOK WI RIEULPIEUP
+0x82D9 0xADCC #HANGUL SYLLABLE KIYEOK WI RIEULSIOS
+0x82DA 0xADCD #HANGUL SYLLABLE KIYEOK WI RIEULTHIEUTH
+0x82DB 0xADCE #HANGUL SYLLABLE KIYEOK WI RIEULPHIEUPH
+0x82DC 0xADCF #HANGUL SYLLABLE KIYEOK WI RIEULHIEUH
+0x82DD 0xADD2 #HANGUL SYLLABLE KIYEOK WI PIEUPSIOS
+0x82DE 0xADD4 #HANGUL SYLLABLE KIYEOK WI SSANGSIOS
+0x82DF 0xADD5 #HANGUL SYLLABLE KIYEOK WI IEUNG
+0x82E0 0xADD6 #HANGUL SYLLABLE KIYEOK WI CIEUC
+0x82E1 0xADD7 #HANGUL SYLLABLE KIYEOK WI CHIEUCH
+0x82E2 0xADD8 #HANGUL SYLLABLE KIYEOK WI KHIEUKH
+0x82E3 0xADD9 #HANGUL SYLLABLE KIYEOK WI THIEUTH
+0x82E4 0xADDA #HANGUL SYLLABLE KIYEOK WI PHIEUPH
+0x82E5 0xADDB #HANGUL SYLLABLE KIYEOK WI HIEUH
+0x82E6 0xADDD #HANGUL SYLLABLE KIYEOK YU KIYEOK
+0x82E7 0xADDE #HANGUL SYLLABLE KIYEOK YU SSANGKIYEOK
+0x82E8 0xADDF #HANGUL SYLLABLE KIYEOK YU KIYEOKSIOS
+0x82E9 0xADE1 #HANGUL SYLLABLE KIYEOK YU NIEUNCIEUC
+0x82EA 0xADE2 #HANGUL SYLLABLE KIYEOK YU NIEUNHIEUH
+0x82EB 0xADE3 #HANGUL SYLLABLE KIYEOK YU TIKEUT
+0x82EC 0xADE5 #HANGUL SYLLABLE KIYEOK YU RIEULKIYEOK
+0x82ED 0xADE6 #HANGUL SYLLABLE KIYEOK YU RIEULMIEUM
+0x82EE 0xADE7 #HANGUL SYLLABLE KIYEOK YU RIEULPIEUP
+0x82EF 0xADE8 #HANGUL SYLLABLE KIYEOK YU RIEULSIOS
+0x82F0 0xADE9 #HANGUL SYLLABLE KIYEOK YU RIEULTHIEUTH
+0x82F1 0xADEA #HANGUL SYLLABLE KIYEOK YU RIEULPHIEUPH
+0x82F2 0xADEB #HANGUL SYLLABLE KIYEOK YU RIEULHIEUH
+0x82F3 0xADEC #HANGUL SYLLABLE KIYEOK YU MIEUM
+0x82F4 0xADED #HANGUL SYLLABLE KIYEOK YU PIEUP
+0x82F5 0xADEE #HANGUL SYLLABLE KIYEOK YU PIEUPSIOS
+0x82F6 0xADEF #HANGUL SYLLABLE KIYEOK YU SIOS
+0x82F7 0xADF0 #HANGUL SYLLABLE KIYEOK YU SSANGSIOS
+0x82F8 0xADF1 #HANGUL SYLLABLE KIYEOK YU IEUNG
+0x82F9 0xADF2 #HANGUL SYLLABLE KIYEOK YU CIEUC
+0x82FA 0xADF3 #HANGUL SYLLABLE KIYEOK YU CHIEUCH
+0x82FB 0xADF4 #HANGUL SYLLABLE KIYEOK YU KHIEUKH
+0x82FC 0xADF5 #HANGUL SYLLABLE KIYEOK YU THIEUTH
+0x82FD 0xADF6 #HANGUL SYLLABLE KIYEOK YU PHIEUPH
+0x82FE 0xADF7 #HANGUL SYLLABLE KIYEOK YU HIEUH
+0x8341 0xADFA #HANGUL SYLLABLE KIYEOK EU SSANGKIYEOK
+0x8342 0xADFB #HANGUL SYLLABLE KIYEOK EU KIYEOKSIOS
+0x8343 0xADFD #HANGUL SYLLABLE KIYEOK EU NIEUNCIEUC
+0x8344 0xADFE #HANGUL SYLLABLE KIYEOK EU NIEUNHIEUH
+0x8345 0xAE02 #HANGUL SYLLABLE KIYEOK EU RIEULMIEUM
+0x8346 0xAE03 #HANGUL SYLLABLE KIYEOK EU RIEULPIEUP
+0x8347 0xAE04 #HANGUL SYLLABLE KIYEOK EU RIEULSIOS
+0x8348 0xAE05 #HANGUL SYLLABLE KIYEOK EU RIEULTHIEUTH
+0x8349 0xAE06 #HANGUL SYLLABLE KIYEOK EU RIEULPHIEUPH
+0x834A 0xAE07 #HANGUL SYLLABLE KIYEOK EU RIEULHIEUH
+0x834B 0xAE0A #HANGUL SYLLABLE KIYEOK EU PIEUPSIOS
+0x834C 0xAE0C #HANGUL SYLLABLE KIYEOK EU SSANGSIOS
+0x834D 0xAE0E #HANGUL SYLLABLE KIYEOK EU CIEUC
+0x834E 0xAE0F #HANGUL SYLLABLE KIYEOK EU CHIEUCH
+0x834F 0xAE10 #HANGUL SYLLABLE KIYEOK EU KHIEUKH
+0x8350 0xAE11 #HANGUL SYLLABLE KIYEOK EU THIEUTH
+0x8351 0xAE12 #HANGUL SYLLABLE KIYEOK EU PHIEUPH
+0x8352 0xAE13 #HANGUL SYLLABLE KIYEOK EU HIEUH
+0x8353 0xAE15 #HANGUL SYLLABLE KIYEOK YI KIYEOK
+0x8354 0xAE16 #HANGUL SYLLABLE KIYEOK YI SSANGKIYEOK
+0x8355 0xAE17 #HANGUL SYLLABLE KIYEOK YI KIYEOKSIOS
+0x8356 0xAE18 #HANGUL SYLLABLE KIYEOK YI NIEUN
+0x8357 0xAE19 #HANGUL SYLLABLE KIYEOK YI NIEUNCIEUC
+0x8358 0xAE1A #HANGUL SYLLABLE KIYEOK YI NIEUNHIEUH
+0x8359 0xAE1B #HANGUL SYLLABLE KIYEOK YI TIKEUT
+0x835A 0xAE1C #HANGUL SYLLABLE KIYEOK YI RIEUL
+0x8361 0xAE1D #HANGUL SYLLABLE KIYEOK YI RIEULKIYEOK
+0x8362 0xAE1E #HANGUL SYLLABLE KIYEOK YI RIEULMIEUM
+0x8363 0xAE1F #HANGUL SYLLABLE KIYEOK YI RIEULPIEUP
+0x8364 0xAE20 #HANGUL SYLLABLE KIYEOK YI RIEULSIOS
+0x8365 0xAE21 #HANGUL SYLLABLE KIYEOK YI RIEULTHIEUTH
+0x8366 0xAE22 #HANGUL SYLLABLE KIYEOK YI RIEULPHIEUPH
+0x8367 0xAE23 #HANGUL SYLLABLE KIYEOK YI RIEULHIEUH
+0x8368 0xAE24 #HANGUL SYLLABLE KIYEOK YI MIEUM
+0x8369 0xAE25 #HANGUL SYLLABLE KIYEOK YI PIEUP
+0x836A 0xAE26 #HANGUL SYLLABLE KIYEOK YI PIEUPSIOS
+0x836B 0xAE27 #HANGUL SYLLABLE KIYEOK YI SIOS
+0x836C 0xAE28 #HANGUL SYLLABLE KIYEOK YI SSANGSIOS
+0x836D 0xAE29 #HANGUL SYLLABLE KIYEOK YI IEUNG
+0x836E 0xAE2A #HANGUL SYLLABLE KIYEOK YI CIEUC
+0x836F 0xAE2B #HANGUL SYLLABLE KIYEOK YI CHIEUCH
+0x8370 0xAE2C #HANGUL SYLLABLE KIYEOK YI KHIEUKH
+0x8371 0xAE2D #HANGUL SYLLABLE KIYEOK YI THIEUTH
+0x8372 0xAE2E #HANGUL SYLLABLE KIYEOK YI PHIEUPH
+0x8373 0xAE2F #HANGUL SYLLABLE KIYEOK YI HIEUH
+0x8374 0xAE32 #HANGUL SYLLABLE KIYEOK I SSANGKIYEOK
+0x8375 0xAE33 #HANGUL SYLLABLE KIYEOK I KIYEOKSIOS
+0x8376 0xAE35 #HANGUL SYLLABLE KIYEOK I NIEUNCIEUC
+0x8377 0xAE36 #HANGUL SYLLABLE KIYEOK I NIEUNHIEUH
+0x8378 0xAE39 #HANGUL SYLLABLE KIYEOK I RIEULKIYEOK
+0x8379 0xAE3B #HANGUL SYLLABLE KIYEOK I RIEULPIEUP
+0x837A 0xAE3C #HANGUL SYLLABLE KIYEOK I RIEULSIOS
+0x8381 0xAE3D #HANGUL SYLLABLE KIYEOK I RIEULTHIEUTH
+0x8382 0xAE3E #HANGUL SYLLABLE KIYEOK I RIEULPHIEUPH
+0x8383 0xAE3F #HANGUL SYLLABLE KIYEOK I RIEULHIEUH
+0x8384 0xAE42 #HANGUL SYLLABLE KIYEOK I PIEUPSIOS
+0x8385 0xAE44 #HANGUL SYLLABLE KIYEOK I SSANGSIOS
+0x8386 0xAE47 #HANGUL SYLLABLE KIYEOK I CHIEUCH
+0x8387 0xAE48 #HANGUL SYLLABLE KIYEOK I KHIEUKH
+0x8388 0xAE49 #HANGUL SYLLABLE KIYEOK I THIEUTH
+0x8389 0xAE4B #HANGUL SYLLABLE KIYEOK I HIEUH
+0x838A 0xAE4F #HANGUL SYLLABLE SSANGKIYEOK A KIYEOKSIOS
+0x838B 0xAE51 #HANGUL SYLLABLE SSANGKIYEOK A NIEUNCIEUC
+0x838C 0xAE52 #HANGUL SYLLABLE SSANGKIYEOK A NIEUNHIEUH
+0x838D 0xAE53 #HANGUL SYLLABLE SSANGKIYEOK A TIKEUT
+0x838E 0xAE55 #HANGUL SYLLABLE SSANGKIYEOK A RIEULKIYEOK
+0x838F 0xAE57 #HANGUL SYLLABLE SSANGKIYEOK A RIEULPIEUP
+0x8390 0xAE58 #HANGUL SYLLABLE SSANGKIYEOK A RIEULSIOS
+0x8391 0xAE59 #HANGUL SYLLABLE SSANGKIYEOK A RIEULTHIEUTH
+0x8392 0xAE5A #HANGUL SYLLABLE SSANGKIYEOK A RIEULPHIEUPH
+0x8393 0xAE5B #HANGUL SYLLABLE SSANGKIYEOK A RIEULHIEUH
+0x8394 0xAE5E #HANGUL SYLLABLE SSANGKIYEOK A PIEUPSIOS
+0x8395 0xAE62 #HANGUL SYLLABLE SSANGKIYEOK A CIEUC
+0x8396 0xAE63 #HANGUL SYLLABLE SSANGKIYEOK A CHIEUCH
+0x8397 0xAE64 #HANGUL SYLLABLE SSANGKIYEOK A KHIEUKH
+0x8398 0xAE66 #HANGUL SYLLABLE SSANGKIYEOK A PHIEUPH
+0x8399 0xAE67 #HANGUL SYLLABLE SSANGKIYEOK A HIEUH
+0x839A 0xAE6A #HANGUL SYLLABLE SSANGKIYEOK AE SSANGKIYEOK
+0x839B 0xAE6B #HANGUL SYLLABLE SSANGKIYEOK AE KIYEOKSIOS
+0x839C 0xAE6D #HANGUL SYLLABLE SSANGKIYEOK AE NIEUNCIEUC
+0x839D 0xAE6E #HANGUL SYLLABLE SSANGKIYEOK AE NIEUNHIEUH
+0x839E 0xAE6F #HANGUL SYLLABLE SSANGKIYEOK AE TIKEUT
+0x839F 0xAE71 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULKIYEOK
+0x83A0 0xAE72 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULMIEUM
+0x83A1 0xAE73 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULPIEUP
+0x83A2 0xAE74 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULSIOS
+0x83A3 0xAE75 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULTHIEUTH
+0x83A4 0xAE76 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULPHIEUPH
+0x83A5 0xAE77 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULHIEUH
+0x83A6 0xAE7A #HANGUL SYLLABLE SSANGKIYEOK AE PIEUPSIOS
+0x83A7 0xAE7E #HANGUL SYLLABLE SSANGKIYEOK AE CIEUC
+0x83A8 0xAE7F #HANGUL SYLLABLE SSANGKIYEOK AE CHIEUCH
+0x83A9 0xAE80 #HANGUL SYLLABLE SSANGKIYEOK AE KHIEUKH
+0x83AA 0xAE81 #HANGUL SYLLABLE SSANGKIYEOK AE THIEUTH
+0x83AB 0xAE82 #HANGUL SYLLABLE SSANGKIYEOK AE PHIEUPH
+0x83AC 0xAE83 #HANGUL SYLLABLE SSANGKIYEOK AE HIEUH
+0x83AD 0xAE86 #HANGUL SYLLABLE SSANGKIYEOK YA SSANGKIYEOK
+0x83AE 0xAE87 #HANGUL SYLLABLE SSANGKIYEOK YA KIYEOKSIOS
+0x83AF 0xAE88 #HANGUL SYLLABLE SSANGKIYEOK YA NIEUN
+0x83B0 0xAE89 #HANGUL SYLLABLE SSANGKIYEOK YA NIEUNCIEUC
+0x83B1 0xAE8A #HANGUL SYLLABLE SSANGKIYEOK YA NIEUNHIEUH
+0x83B2 0xAE8B #HANGUL SYLLABLE SSANGKIYEOK YA TIKEUT
+0x83B3 0xAE8D #HANGUL SYLLABLE SSANGKIYEOK YA RIEULKIYEOK
+0x83B4 0xAE8E #HANGUL SYLLABLE SSANGKIYEOK YA RIEULMIEUM
+0x83B5 0xAE8F #HANGUL SYLLABLE SSANGKIYEOK YA RIEULPIEUP
+0x83B6 0xAE90 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULSIOS
+0x83B7 0xAE91 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULTHIEUTH
+0x83B8 0xAE92 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULPHIEUPH
+0x83B9 0xAE93 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULHIEUH
+0x83BA 0xAE94 #HANGUL SYLLABLE SSANGKIYEOK YA MIEUM
+0x83BB 0xAE95 #HANGUL SYLLABLE SSANGKIYEOK YA PIEUP
+0x83BC 0xAE96 #HANGUL SYLLABLE SSANGKIYEOK YA PIEUPSIOS
+0x83BD 0xAE97 #HANGUL SYLLABLE SSANGKIYEOK YA SIOS
+0x83BE 0xAE98 #HANGUL SYLLABLE SSANGKIYEOK YA SSANGSIOS
+0x83BF 0xAE99 #HANGUL SYLLABLE SSANGKIYEOK YA IEUNG
+0x83C0 0xAE9A #HANGUL SYLLABLE SSANGKIYEOK YA CIEUC
+0x83C1 0xAE9B #HANGUL SYLLABLE SSANGKIYEOK YA CHIEUCH
+0x83C2 0xAE9C #HANGUL SYLLABLE SSANGKIYEOK YA KHIEUKH
+0x83C3 0xAE9D #HANGUL SYLLABLE SSANGKIYEOK YA THIEUTH
+0x83C4 0xAE9E #HANGUL SYLLABLE SSANGKIYEOK YA PHIEUPH
+0x83C5 0xAE9F #HANGUL SYLLABLE SSANGKIYEOK YA HIEUH
+0x83C6 0xAEA0 #HANGUL SYLLABLE SSANGKIYEOK YAE
+0x83C7 0xAEA1 #HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOK
+0x83C8 0xAEA2 #HANGUL SYLLABLE SSANGKIYEOK YAE SSANGKIYEOK
+0x83C9 0xAEA3 #HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOKSIOS
+0x83CA 0xAEA4 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUN
+0x83CB 0xAEA5 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNCIEUC
+0x83CC 0xAEA6 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNHIEUH
+0x83CD 0xAEA7 #HANGUL SYLLABLE SSANGKIYEOK YAE TIKEUT
+0x83CE 0xAEA8 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEUL
+0x83CF 0xAEA9 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULKIYEOK
+0x83D0 0xAEAA #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULMIEUM
+0x83D1 0xAEAB #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPIEUP
+0x83D2 0xAEAC #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULSIOS
+0x83D3 0xAEAD #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULTHIEUTH
+0x83D4 0xAEAE #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPHIEUPH
+0x83D5 0xAEAF #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULHIEUH
+0x83D6 0xAEB0 #HANGUL SYLLABLE SSANGKIYEOK YAE MIEUM
+0x83D7 0xAEB1 #HANGUL SYLLABLE SSANGKIYEOK YAE PIEUP
+0x83D8 0xAEB2 #HANGUL SYLLABLE SSANGKIYEOK YAE PIEUPSIOS
+0x83D9 0xAEB3 #HANGUL SYLLABLE SSANGKIYEOK YAE SIOS
+0x83DA 0xAEB4 #HANGUL SYLLABLE SSANGKIYEOK YAE SSANGSIOS
+0x83DB 0xAEB5 #HANGUL SYLLABLE SSANGKIYEOK YAE IEUNG
+0x83DC 0xAEB6 #HANGUL SYLLABLE SSANGKIYEOK YAE CIEUC
+0x83DD 0xAEB7 #HANGUL SYLLABLE SSANGKIYEOK YAE CHIEUCH
+0x83DE 0xAEB8 #HANGUL SYLLABLE SSANGKIYEOK YAE KHIEUKH
+0x83DF 0xAEB9 #HANGUL SYLLABLE SSANGKIYEOK YAE THIEUTH
+0x83E0 0xAEBA #HANGUL SYLLABLE SSANGKIYEOK YAE PHIEUPH
+0x83E1 0xAEBB #HANGUL SYLLABLE SSANGKIYEOK YAE HIEUH
+0x83E2 0xAEBF #HANGUL SYLLABLE SSANGKIYEOK EO KIYEOKSIOS
+0x83E3 0xAEC1 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUNCIEUC
+0x83E4 0xAEC2 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUNHIEUH
+0x83E5 0xAEC3 #HANGUL SYLLABLE SSANGKIYEOK EO TIKEUT
+0x83E6 0xAEC5 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULKIYEOK
+0x83E7 0xAEC6 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULMIEUM
+0x83E8 0xAEC7 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULPIEUP
+0x83E9 0xAEC8 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULSIOS
+0x83EA 0xAEC9 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULTHIEUTH
+0x83EB 0xAECA #HANGUL SYLLABLE SSANGKIYEOK EO RIEULPHIEUPH
+0x83EC 0xAECB #HANGUL SYLLABLE SSANGKIYEOK EO RIEULHIEUH
+0x83ED 0xAECE #HANGUL SYLLABLE SSANGKIYEOK EO PIEUPSIOS
+0x83EE 0xAED2 #HANGUL SYLLABLE SSANGKIYEOK EO CIEUC
+0x83EF 0xAED3 #HANGUL SYLLABLE SSANGKIYEOK EO CHIEUCH
+0x83F0 0xAED4 #HANGUL SYLLABLE SSANGKIYEOK EO KHIEUKH
+0x83F1 0xAED5 #HANGUL SYLLABLE SSANGKIYEOK EO THIEUTH
+0x83F2 0xAED6 #HANGUL SYLLABLE SSANGKIYEOK EO PHIEUPH
+0x83F3 0xAED7 #HANGUL SYLLABLE SSANGKIYEOK EO HIEUH
+0x83F4 0xAEDA #HANGUL SYLLABLE SSANGKIYEOK E SSANGKIYEOK
+0x83F5 0xAEDB #HANGUL SYLLABLE SSANGKIYEOK E KIYEOKSIOS
+0x83F6 0xAEDD #HANGUL SYLLABLE SSANGKIYEOK E NIEUNCIEUC
+0x83F7 0xAEDE #HANGUL SYLLABLE SSANGKIYEOK E NIEUNHIEUH
+0x83F8 0xAEDF #HANGUL SYLLABLE SSANGKIYEOK E TIKEUT
+0x83F9 0xAEE0 #HANGUL SYLLABLE SSANGKIYEOK E RIEUL
+0x83FA 0xAEE1 #HANGUL SYLLABLE SSANGKIYEOK E RIEULKIYEOK
+0x83FB 0xAEE2 #HANGUL SYLLABLE SSANGKIYEOK E RIEULMIEUM
+0x83FC 0xAEE3 #HANGUL SYLLABLE SSANGKIYEOK E RIEULPIEUP
+0x83FD 0xAEE4 #HANGUL SYLLABLE SSANGKIYEOK E RIEULSIOS
+0x83FE 0xAEE5 #HANGUL SYLLABLE SSANGKIYEOK E RIEULTHIEUTH
+0x8441 0xAEE6 #HANGUL SYLLABLE SSANGKIYEOK E RIEULPHIEUPH
+0x8442 0xAEE7 #HANGUL SYLLABLE SSANGKIYEOK E RIEULHIEUH
+0x8443 0xAEE9 #HANGUL SYLLABLE SSANGKIYEOK E PIEUP
+0x8444 0xAEEA #HANGUL SYLLABLE SSANGKIYEOK E PIEUPSIOS
+0x8445 0xAEEC #HANGUL SYLLABLE SSANGKIYEOK E SSANGSIOS
+0x8446 0xAEEE #HANGUL SYLLABLE SSANGKIYEOK E CIEUC
+0x8447 0xAEEF #HANGUL SYLLABLE SSANGKIYEOK E CHIEUCH
+0x8448 0xAEF0 #HANGUL SYLLABLE SSANGKIYEOK E KHIEUKH
+0x8449 0xAEF1 #HANGUL SYLLABLE SSANGKIYEOK E THIEUTH
+0x844A 0xAEF2 #HANGUL SYLLABLE SSANGKIYEOK E PHIEUPH
+0x844B 0xAEF3 #HANGUL SYLLABLE SSANGKIYEOK E HIEUH
+0x844C 0xAEF5 #HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOK
+0x844D 0xAEF6 #HANGUL SYLLABLE SSANGKIYEOK YEO SSANGKIYEOK
+0x844E 0xAEF7 #HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOKSIOS
+0x844F 0xAEF9 #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNCIEUC
+0x8450 0xAEFA #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNHIEUH
+0x8451 0xAEFB #HANGUL SYLLABLE SSANGKIYEOK YEO TIKEUT
+0x8452 0xAEFD #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULKIYEOK
+0x8453 0xAEFE #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULMIEUM
+0x8454 0xAEFF #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPIEUP
+0x8455 0xAF00 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULSIOS
+0x8456 0xAF01 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULTHIEUTH
+0x8457 0xAF02 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPHIEUPH
+0x8458 0xAF03 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULHIEUH
+0x8459 0xAF04 #HANGUL SYLLABLE SSANGKIYEOK YEO MIEUM
+0x845A 0xAF05 #HANGUL SYLLABLE SSANGKIYEOK YEO PIEUP
+0x8461 0xAF06 #HANGUL SYLLABLE SSANGKIYEOK YEO PIEUPSIOS
+0x8462 0xAF09 #HANGUL SYLLABLE SSANGKIYEOK YEO IEUNG
+0x8463 0xAF0A #HANGUL SYLLABLE SSANGKIYEOK YEO CIEUC
+0x8464 0xAF0B #HANGUL SYLLABLE SSANGKIYEOK YEO CHIEUCH
+0x8465 0xAF0C #HANGUL SYLLABLE SSANGKIYEOK YEO KHIEUKH
+0x8466 0xAF0E #HANGUL SYLLABLE SSANGKIYEOK YEO PHIEUPH
+0x8467 0xAF0F #HANGUL SYLLABLE SSANGKIYEOK YEO HIEUH
+0x8468 0xAF11 #HANGUL SYLLABLE SSANGKIYEOK YE KIYEOK
+0x8469 0xAF12 #HANGUL SYLLABLE SSANGKIYEOK YE SSANGKIYEOK
+0x846A 0xAF13 #HANGUL SYLLABLE SSANGKIYEOK YE KIYEOKSIOS
+0x846B 0xAF14 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUN
+0x846C 0xAF15 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUNCIEUC
+0x846D 0xAF16 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUNHIEUH
+0x846E 0xAF17 #HANGUL SYLLABLE SSANGKIYEOK YE TIKEUT
+0x846F 0xAF18 #HANGUL SYLLABLE SSANGKIYEOK YE RIEUL
+0x8470 0xAF19 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULKIYEOK
+0x8471 0xAF1A #HANGUL SYLLABLE SSANGKIYEOK YE RIEULMIEUM
+0x8472 0xAF1B #HANGUL SYLLABLE SSANGKIYEOK YE RIEULPIEUP
+0x8473 0xAF1C #HANGUL SYLLABLE SSANGKIYEOK YE RIEULSIOS
+0x8474 0xAF1D #HANGUL SYLLABLE SSANGKIYEOK YE RIEULTHIEUTH
+0x8475 0xAF1E #HANGUL SYLLABLE SSANGKIYEOK YE RIEULPHIEUPH
+0x8476 0xAF1F #HANGUL SYLLABLE SSANGKIYEOK YE RIEULHIEUH
+0x8477 0xAF20 #HANGUL SYLLABLE SSANGKIYEOK YE MIEUM
+0x8478 0xAF21 #HANGUL SYLLABLE SSANGKIYEOK YE PIEUP
+0x8479 0xAF22 #HANGUL SYLLABLE SSANGKIYEOK YE PIEUPSIOS
+0x847A 0xAF23 #HANGUL SYLLABLE SSANGKIYEOK YE SIOS
+0x8481 0xAF24 #HANGUL SYLLABLE SSANGKIYEOK YE SSANGSIOS
+0x8482 0xAF25 #HANGUL SYLLABLE SSANGKIYEOK YE IEUNG
+0x8483 0xAF26 #HANGUL SYLLABLE SSANGKIYEOK YE CIEUC
+0x8484 0xAF27 #HANGUL SYLLABLE SSANGKIYEOK YE CHIEUCH
+0x8485 0xAF28 #HANGUL SYLLABLE SSANGKIYEOK YE KHIEUKH
+0x8486 0xAF29 #HANGUL SYLLABLE SSANGKIYEOK YE THIEUTH
+0x8487 0xAF2A #HANGUL SYLLABLE SSANGKIYEOK YE PHIEUPH
+0x8488 0xAF2B #HANGUL SYLLABLE SSANGKIYEOK YE HIEUH
+0x8489 0xAF2E #HANGUL SYLLABLE SSANGKIYEOK O SSANGKIYEOK
+0x848A 0xAF2F #HANGUL SYLLABLE SSANGKIYEOK O KIYEOKSIOS
+0x848B 0xAF31 #HANGUL SYLLABLE SSANGKIYEOK O NIEUNCIEUC
+0x848C 0xAF33 #HANGUL SYLLABLE SSANGKIYEOK O TIKEUT
+0x848D 0xAF35 #HANGUL SYLLABLE SSANGKIYEOK O RIEULKIYEOK
+0x848E 0xAF36 #HANGUL SYLLABLE SSANGKIYEOK O RIEULMIEUM
+0x848F 0xAF37 #HANGUL SYLLABLE SSANGKIYEOK O RIEULPIEUP
+0x8490 0xAF38 #HANGUL SYLLABLE SSANGKIYEOK O RIEULSIOS
+0x8491 0xAF39 #HANGUL SYLLABLE SSANGKIYEOK O RIEULTHIEUTH
+0x8492 0xAF3A #HANGUL SYLLABLE SSANGKIYEOK O RIEULPHIEUPH
+0x8493 0xAF3B #HANGUL SYLLABLE SSANGKIYEOK O RIEULHIEUH
+0x8494 0xAF3E #HANGUL SYLLABLE SSANGKIYEOK O PIEUPSIOS
+0x8495 0xAF40 #HANGUL SYLLABLE SSANGKIYEOK O SSANGSIOS
+0x8496 0xAF44 #HANGUL SYLLABLE SSANGKIYEOK O KHIEUKH
+0x8497 0xAF45 #HANGUL SYLLABLE SSANGKIYEOK O THIEUTH
+0x8498 0xAF46 #HANGUL SYLLABLE SSANGKIYEOK O PHIEUPH
+0x8499 0xAF47 #HANGUL SYLLABLE SSANGKIYEOK O HIEUH
+0x849A 0xAF4A #HANGUL SYLLABLE SSANGKIYEOK WA SSANGKIYEOK
+0x849B 0xAF4B #HANGUL SYLLABLE SSANGKIYEOK WA KIYEOKSIOS
+0x849C 0xAF4C #HANGUL SYLLABLE SSANGKIYEOK WA NIEUN
+0x849D 0xAF4D #HANGUL SYLLABLE SSANGKIYEOK WA NIEUNCIEUC
+0x849E 0xAF4E #HANGUL SYLLABLE SSANGKIYEOK WA NIEUNHIEUH
+0x849F 0xAF4F #HANGUL SYLLABLE SSANGKIYEOK WA TIKEUT
+0x84A0 0xAF51 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULKIYEOK
+0x84A1 0xAF52 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULMIEUM
+0x84A2 0xAF53 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULPIEUP
+0x84A3 0xAF54 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULSIOS
+0x84A4 0xAF55 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULTHIEUTH
+0x84A5 0xAF56 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULPHIEUPH
+0x84A6 0xAF57 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULHIEUH
+0x84A7 0xAF58 #HANGUL SYLLABLE SSANGKIYEOK WA MIEUM
+0x84A8 0xAF59 #HANGUL SYLLABLE SSANGKIYEOK WA PIEUP
+0x84A9 0xAF5A #HANGUL SYLLABLE SSANGKIYEOK WA PIEUPSIOS
+0x84AA 0xAF5B #HANGUL SYLLABLE SSANGKIYEOK WA SIOS
+0x84AB 0xAF5E #HANGUL SYLLABLE SSANGKIYEOK WA CIEUC
+0x84AC 0xAF5F #HANGUL SYLLABLE SSANGKIYEOK WA CHIEUCH
+0x84AD 0xAF60 #HANGUL SYLLABLE SSANGKIYEOK WA KHIEUKH
+0x84AE 0xAF61 #HANGUL SYLLABLE SSANGKIYEOK WA THIEUTH
+0x84AF 0xAF62 #HANGUL SYLLABLE SSANGKIYEOK WA PHIEUPH
+0x84B0 0xAF63 #HANGUL SYLLABLE SSANGKIYEOK WA HIEUH
+0x84B1 0xAF66 #HANGUL SYLLABLE SSANGKIYEOK WAE SSANGKIYEOK
+0x84B2 0xAF67 #HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOKSIOS
+0x84B3 0xAF68 #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUN
+0x84B4 0xAF69 #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNCIEUC
+0x84B5 0xAF6A #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNHIEUH
+0x84B6 0xAF6B #HANGUL SYLLABLE SSANGKIYEOK WAE TIKEUT
+0x84B7 0xAF6C #HANGUL SYLLABLE SSANGKIYEOK WAE RIEUL
+0x84B8 0xAF6D #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULKIYEOK
+0x84B9 0xAF6E #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULMIEUM
+0x84BA 0xAF6F #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPIEUP
+0x84BB 0xAF70 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULSIOS
+0x84BC 0xAF71 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULTHIEUTH
+0x84BD 0xAF72 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPHIEUPH
+0x84BE 0xAF73 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULHIEUH
+0x84BF 0xAF74 #HANGUL SYLLABLE SSANGKIYEOK WAE MIEUM
+0x84C0 0xAF75 #HANGUL SYLLABLE SSANGKIYEOK WAE PIEUP
+0x84C1 0xAF76 #HANGUL SYLLABLE SSANGKIYEOK WAE PIEUPSIOS
+0x84C2 0xAF77 #HANGUL SYLLABLE SSANGKIYEOK WAE SIOS
+0x84C3 0xAF78 #HANGUL SYLLABLE SSANGKIYEOK WAE SSANGSIOS
+0x84C4 0xAF7A #HANGUL SYLLABLE SSANGKIYEOK WAE CIEUC
+0x84C5 0xAF7B #HANGUL SYLLABLE SSANGKIYEOK WAE CHIEUCH
+0x84C6 0xAF7C #HANGUL SYLLABLE SSANGKIYEOK WAE KHIEUKH
+0x84C7 0xAF7D #HANGUL SYLLABLE SSANGKIYEOK WAE THIEUTH
+0x84C8 0xAF7E #HANGUL SYLLABLE SSANGKIYEOK WAE PHIEUPH
+0x84C9 0xAF7F #HANGUL SYLLABLE SSANGKIYEOK WAE HIEUH
+0x84CA 0xAF81 #HANGUL SYLLABLE SSANGKIYEOK OE KIYEOK
+0x84CB 0xAF82 #HANGUL SYLLABLE SSANGKIYEOK OE SSANGKIYEOK
+0x84CC 0xAF83 #HANGUL SYLLABLE SSANGKIYEOK OE KIYEOKSIOS
+0x84CD 0xAF85 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUNCIEUC
+0x84CE 0xAF86 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUNHIEUH
+0x84CF 0xAF87 #HANGUL SYLLABLE SSANGKIYEOK OE TIKEUT
+0x84D0 0xAF89 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULKIYEOK
+0x84D1 0xAF8A #HANGUL SYLLABLE SSANGKIYEOK OE RIEULMIEUM
+0x84D2 0xAF8B #HANGUL SYLLABLE SSANGKIYEOK OE RIEULPIEUP
+0x84D3 0xAF8C #HANGUL SYLLABLE SSANGKIYEOK OE RIEULSIOS
+0x84D4 0xAF8D #HANGUL SYLLABLE SSANGKIYEOK OE RIEULTHIEUTH
+0x84D5 0xAF8E #HANGUL SYLLABLE SSANGKIYEOK OE RIEULPHIEUPH
+0x84D6 0xAF8F #HANGUL SYLLABLE SSANGKIYEOK OE RIEULHIEUH
+0x84D7 0xAF92 #HANGUL SYLLABLE SSANGKIYEOK OE PIEUPSIOS
+0x84D8 0xAF93 #HANGUL SYLLABLE SSANGKIYEOK OE SIOS
+0x84D9 0xAF94 #HANGUL SYLLABLE SSANGKIYEOK OE SSANGSIOS
+0x84DA 0xAF96 #HANGUL SYLLABLE SSANGKIYEOK OE CIEUC
+0x84DB 0xAF97 #HANGUL SYLLABLE SSANGKIYEOK OE CHIEUCH
+0x84DC 0xAF98 #HANGUL SYLLABLE SSANGKIYEOK OE KHIEUKH
+0x84DD 0xAF99 #HANGUL SYLLABLE SSANGKIYEOK OE THIEUTH
+0x84DE 0xAF9A #HANGUL SYLLABLE SSANGKIYEOK OE PHIEUPH
+0x84DF 0xAF9B #HANGUL SYLLABLE SSANGKIYEOK OE HIEUH
+0x84E0 0xAF9D #HANGUL SYLLABLE SSANGKIYEOK YO KIYEOK
+0x84E1 0xAF9E #HANGUL SYLLABLE SSANGKIYEOK YO SSANGKIYEOK
+0x84E2 0xAF9F #HANGUL SYLLABLE SSANGKIYEOK YO KIYEOKSIOS
+0x84E3 0xAFA0 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUN
+0x84E4 0xAFA1 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUNCIEUC
+0x84E5 0xAFA2 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUNHIEUH
+0x84E6 0xAFA3 #HANGUL SYLLABLE SSANGKIYEOK YO TIKEUT
+0x84E7 0xAFA4 #HANGUL SYLLABLE SSANGKIYEOK YO RIEUL
+0x84E8 0xAFA5 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULKIYEOK
+0x84E9 0xAFA6 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULMIEUM
+0x84EA 0xAFA7 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULPIEUP
+0x84EB 0xAFA8 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULSIOS
+0x84EC 0xAFA9 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULTHIEUTH
+0x84ED 0xAFAA #HANGUL SYLLABLE SSANGKIYEOK YO RIEULPHIEUPH
+0x84EE 0xAFAB #HANGUL SYLLABLE SSANGKIYEOK YO RIEULHIEUH
+0x84EF 0xAFAC #HANGUL SYLLABLE SSANGKIYEOK YO MIEUM
+0x84F0 0xAFAD #HANGUL SYLLABLE SSANGKIYEOK YO PIEUP
+0x84F1 0xAFAE #HANGUL SYLLABLE SSANGKIYEOK YO PIEUPSIOS
+0x84F2 0xAFAF #HANGUL SYLLABLE SSANGKIYEOK YO SIOS
+0x84F3 0xAFB0 #HANGUL SYLLABLE SSANGKIYEOK YO SSANGSIOS
+0x84F4 0xAFB1 #HANGUL SYLLABLE SSANGKIYEOK YO IEUNG
+0x84F5 0xAFB2 #HANGUL SYLLABLE SSANGKIYEOK YO CIEUC
+0x84F6 0xAFB3 #HANGUL SYLLABLE SSANGKIYEOK YO CHIEUCH
+0x84F7 0xAFB4 #HANGUL SYLLABLE SSANGKIYEOK YO KHIEUKH
+0x84F8 0xAFB5 #HANGUL SYLLABLE SSANGKIYEOK YO THIEUTH
+0x84F9 0xAFB6 #HANGUL SYLLABLE SSANGKIYEOK YO PHIEUPH
+0x84FA 0xAFB7 #HANGUL SYLLABLE SSANGKIYEOK YO HIEUH
+0x84FB 0xAFBA #HANGUL SYLLABLE SSANGKIYEOK U SSANGKIYEOK
+0x84FC 0xAFBB #HANGUL SYLLABLE SSANGKIYEOK U KIYEOKSIOS
+0x84FD 0xAFBD #HANGUL SYLLABLE SSANGKIYEOK U NIEUNCIEUC
+0x84FE 0xAFBE #HANGUL SYLLABLE SSANGKIYEOK U NIEUNHIEUH
+0x8541 0xAFBF #HANGUL SYLLABLE SSANGKIYEOK U TIKEUT
+0x8542 0xAFC1 #HANGUL SYLLABLE SSANGKIYEOK U RIEULKIYEOK
+0x8543 0xAFC2 #HANGUL SYLLABLE SSANGKIYEOK U RIEULMIEUM
+0x8544 0xAFC3 #HANGUL SYLLABLE SSANGKIYEOK U RIEULPIEUP
+0x8545 0xAFC4 #HANGUL SYLLABLE SSANGKIYEOK U RIEULSIOS
+0x8546 0xAFC5 #HANGUL SYLLABLE SSANGKIYEOK U RIEULTHIEUTH
+0x8547 0xAFC6 #HANGUL SYLLABLE SSANGKIYEOK U RIEULPHIEUPH
+0x8548 0xAFCA #HANGUL SYLLABLE SSANGKIYEOK U PIEUPSIOS
+0x8549 0xAFCC #HANGUL SYLLABLE SSANGKIYEOK U SSANGSIOS
+0x854A 0xAFCF #HANGUL SYLLABLE SSANGKIYEOK U CHIEUCH
+0x854B 0xAFD0 #HANGUL SYLLABLE SSANGKIYEOK U KHIEUKH
+0x854C 0xAFD1 #HANGUL SYLLABLE SSANGKIYEOK U THIEUTH
+0x854D 0xAFD2 #HANGUL SYLLABLE SSANGKIYEOK U PHIEUPH
+0x854E 0xAFD3 #HANGUL SYLLABLE SSANGKIYEOK U HIEUH
+0x854F 0xAFD5 #HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOK
+0x8550 0xAFD6 #HANGUL SYLLABLE SSANGKIYEOK WEO SSANGKIYEOK
+0x8551 0xAFD7 #HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOKSIOS
+0x8552 0xAFD8 #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUN
+0x8553 0xAFD9 #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNCIEUC
+0x8554 0xAFDA #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNHIEUH
+0x8555 0xAFDB #HANGUL SYLLABLE SSANGKIYEOK WEO TIKEUT
+0x8556 0xAFDD #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULKIYEOK
+0x8557 0xAFDE #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULMIEUM
+0x8558 0xAFDF #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPIEUP
+0x8559 0xAFE0 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULSIOS
+0x855A 0xAFE1 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULTHIEUTH
+0x8561 0xAFE2 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPHIEUPH
+0x8562 0xAFE3 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULHIEUH
+0x8563 0xAFE4 #HANGUL SYLLABLE SSANGKIYEOK WEO MIEUM
+0x8564 0xAFE5 #HANGUL SYLLABLE SSANGKIYEOK WEO PIEUP
+0x8565 0xAFE6 #HANGUL SYLLABLE SSANGKIYEOK WEO PIEUPSIOS
+0x8566 0xAFE7 #HANGUL SYLLABLE SSANGKIYEOK WEO SIOS
+0x8567 0xAFEA #HANGUL SYLLABLE SSANGKIYEOK WEO CIEUC
+0x8568 0xAFEB #HANGUL SYLLABLE SSANGKIYEOK WEO CHIEUCH
+0x8569 0xAFEC #HANGUL SYLLABLE SSANGKIYEOK WEO KHIEUKH
+0x856A 0xAFED #HANGUL SYLLABLE SSANGKIYEOK WEO THIEUTH
+0x856B 0xAFEE #HANGUL SYLLABLE SSANGKIYEOK WEO PHIEUPH
+0x856C 0xAFEF #HANGUL SYLLABLE SSANGKIYEOK WEO HIEUH
+0x856D 0xAFF2 #HANGUL SYLLABLE SSANGKIYEOK WE SSANGKIYEOK
+0x856E 0xAFF3 #HANGUL SYLLABLE SSANGKIYEOK WE KIYEOKSIOS
+0x856F 0xAFF5 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUNCIEUC
+0x8570 0xAFF6 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUNHIEUH
+0x8571 0xAFF7 #HANGUL SYLLABLE SSANGKIYEOK WE TIKEUT
+0x8572 0xAFF9 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULKIYEOK
+0x8573 0xAFFA #HANGUL SYLLABLE SSANGKIYEOK WE RIEULMIEUM
+0x8574 0xAFFB #HANGUL SYLLABLE SSANGKIYEOK WE RIEULPIEUP
+0x8575 0xAFFC #HANGUL SYLLABLE SSANGKIYEOK WE RIEULSIOS
+0x8576 0xAFFD #HANGUL SYLLABLE SSANGKIYEOK WE RIEULTHIEUTH
+0x8577 0xAFFE #HANGUL SYLLABLE SSANGKIYEOK WE RIEULPHIEUPH
+0x8578 0xAFFF #HANGUL SYLLABLE SSANGKIYEOK WE RIEULHIEUH
+0x8579 0xB002 #HANGUL SYLLABLE SSANGKIYEOK WE PIEUPSIOS
+0x857A 0xB003 #HANGUL SYLLABLE SSANGKIYEOK WE SIOS
+0x8581 0xB005 #HANGUL SYLLABLE SSANGKIYEOK WE IEUNG
+0x8582 0xB006 #HANGUL SYLLABLE SSANGKIYEOK WE CIEUC
+0x8583 0xB007 #HANGUL SYLLABLE SSANGKIYEOK WE CHIEUCH
+0x8584 0xB008 #HANGUL SYLLABLE SSANGKIYEOK WE KHIEUKH
+0x8585 0xB009 #HANGUL SYLLABLE SSANGKIYEOK WE THIEUTH
+0x8586 0xB00A #HANGUL SYLLABLE SSANGKIYEOK WE PHIEUPH
+0x8587 0xB00B #HANGUL SYLLABLE SSANGKIYEOK WE HIEUH
+0x8588 0xB00D #HANGUL SYLLABLE SSANGKIYEOK WI KIYEOK
+0x8589 0xB00E #HANGUL SYLLABLE SSANGKIYEOK WI SSANGKIYEOK
+0x858A 0xB00F #HANGUL SYLLABLE SSANGKIYEOK WI KIYEOKSIOS
+0x858B 0xB011 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUNCIEUC
+0x858C 0xB012 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUNHIEUH
+0x858D 0xB013 #HANGUL SYLLABLE SSANGKIYEOK WI TIKEUT
+0x858E 0xB015 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULKIYEOK
+0x858F 0xB016 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULMIEUM
+0x8590 0xB017 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULPIEUP
+0x8591 0xB018 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULSIOS
+0x8592 0xB019 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULTHIEUTH
+0x8593 0xB01A #HANGUL SYLLABLE SSANGKIYEOK WI RIEULPHIEUPH
+0x8594 0xB01B #HANGUL SYLLABLE SSANGKIYEOK WI RIEULHIEUH
+0x8595 0xB01E #HANGUL SYLLABLE SSANGKIYEOK WI PIEUPSIOS
+0x8596 0xB01F #HANGUL SYLLABLE SSANGKIYEOK WI SIOS
+0x8597 0xB020 #HANGUL SYLLABLE SSANGKIYEOK WI SSANGSIOS
+0x8598 0xB021 #HANGUL SYLLABLE SSANGKIYEOK WI IEUNG
+0x8599 0xB022 #HANGUL SYLLABLE SSANGKIYEOK WI CIEUC
+0x859A 0xB023 #HANGUL SYLLABLE SSANGKIYEOK WI CHIEUCH
+0x859B 0xB024 #HANGUL SYLLABLE SSANGKIYEOK WI KHIEUKH
+0x859C 0xB025 #HANGUL SYLLABLE SSANGKIYEOK WI THIEUTH
+0x859D 0xB026 #HANGUL SYLLABLE SSANGKIYEOK WI PHIEUPH
+0x859E 0xB027 #HANGUL SYLLABLE SSANGKIYEOK WI HIEUH
+0x859F 0xB029 #HANGUL SYLLABLE SSANGKIYEOK YU KIYEOK
+0x85A0 0xB02A #HANGUL SYLLABLE SSANGKIYEOK YU SSANGKIYEOK
+0x85A1 0xB02B #HANGUL SYLLABLE SSANGKIYEOK YU KIYEOKSIOS
+0x85A2 0xB02C #HANGUL SYLLABLE SSANGKIYEOK YU NIEUN
+0x85A3 0xB02D #HANGUL SYLLABLE SSANGKIYEOK YU NIEUNCIEUC
+0x85A4 0xB02E #HANGUL SYLLABLE SSANGKIYEOK YU NIEUNHIEUH
+0x85A5 0xB02F #HANGUL SYLLABLE SSANGKIYEOK YU TIKEUT
+0x85A6 0xB030 #HANGUL SYLLABLE SSANGKIYEOK YU RIEUL
+0x85A7 0xB031 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULKIYEOK
+0x85A8 0xB032 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULMIEUM
+0x85A9 0xB033 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULPIEUP
+0x85AA 0xB034 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULSIOS
+0x85AB 0xB035 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULTHIEUTH
+0x85AC 0xB036 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULPHIEUPH
+0x85AD 0xB037 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULHIEUH
+0x85AE 0xB038 #HANGUL SYLLABLE SSANGKIYEOK YU MIEUM
+0x85AF 0xB039 #HANGUL SYLLABLE SSANGKIYEOK YU PIEUP
+0x85B0 0xB03A #HANGUL SYLLABLE SSANGKIYEOK YU PIEUPSIOS
+0x85B1 0xB03B #HANGUL SYLLABLE SSANGKIYEOK YU SIOS
+0x85B2 0xB03C #HANGUL SYLLABLE SSANGKIYEOK YU SSANGSIOS
+0x85B3 0xB03D #HANGUL SYLLABLE SSANGKIYEOK YU IEUNG
+0x85B4 0xB03E #HANGUL SYLLABLE SSANGKIYEOK YU CIEUC
+0x85B5 0xB03F #HANGUL SYLLABLE SSANGKIYEOK YU CHIEUCH
+0x85B6 0xB040 #HANGUL SYLLABLE SSANGKIYEOK YU KHIEUKH
+0x85B7 0xB041 #HANGUL SYLLABLE SSANGKIYEOK YU THIEUTH
+0x85B8 0xB042 #HANGUL SYLLABLE SSANGKIYEOK YU PHIEUPH
+0x85B9 0xB043 #HANGUL SYLLABLE SSANGKIYEOK YU HIEUH
+0x85BA 0xB046 #HANGUL SYLLABLE SSANGKIYEOK EU SSANGKIYEOK
+0x85BB 0xB047 #HANGUL SYLLABLE SSANGKIYEOK EU KIYEOKSIOS
+0x85BC 0xB049 #HANGUL SYLLABLE SSANGKIYEOK EU NIEUNCIEUC
+0x85BD 0xB04B #HANGUL SYLLABLE SSANGKIYEOK EU TIKEUT
+0x85BE 0xB04D #HANGUL SYLLABLE SSANGKIYEOK EU RIEULKIYEOK
+0x85BF 0xB04F #HANGUL SYLLABLE SSANGKIYEOK EU RIEULPIEUP
+0x85C0 0xB050 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULSIOS
+0x85C1 0xB051 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULTHIEUTH
+0x85C2 0xB052 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULPHIEUPH
+0x85C3 0xB056 #HANGUL SYLLABLE SSANGKIYEOK EU PIEUPSIOS
+0x85C4 0xB058 #HANGUL SYLLABLE SSANGKIYEOK EU SSANGSIOS
+0x85C5 0xB05A #HANGUL SYLLABLE SSANGKIYEOK EU CIEUC
+0x85C6 0xB05B #HANGUL SYLLABLE SSANGKIYEOK EU CHIEUCH
+0x85C7 0xB05C #HANGUL SYLLABLE SSANGKIYEOK EU KHIEUKH
+0x85C8 0xB05E #HANGUL SYLLABLE SSANGKIYEOK EU PHIEUPH
+0x85C9 0xB05F #HANGUL SYLLABLE SSANGKIYEOK EU HIEUH
+0x85CA 0xB060 #HANGUL SYLLABLE SSANGKIYEOK YI
+0x85CB 0xB061 #HANGUL SYLLABLE SSANGKIYEOK YI KIYEOK
+0x85CC 0xB062 #HANGUL SYLLABLE SSANGKIYEOK YI SSANGKIYEOK
+0x85CD 0xB063 #HANGUL SYLLABLE SSANGKIYEOK YI KIYEOKSIOS
+0x85CE 0xB064 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUN
+0x85CF 0xB065 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUNCIEUC
+0x85D0 0xB066 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUNHIEUH
+0x85D1 0xB067 #HANGUL SYLLABLE SSANGKIYEOK YI TIKEUT
+0x85D2 0xB068 #HANGUL SYLLABLE SSANGKIYEOK YI RIEUL
+0x85D3 0xB069 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULKIYEOK
+0x85D4 0xB06A #HANGUL SYLLABLE SSANGKIYEOK YI RIEULMIEUM
+0x85D5 0xB06B #HANGUL SYLLABLE SSANGKIYEOK YI RIEULPIEUP
+0x85D6 0xB06C #HANGUL SYLLABLE SSANGKIYEOK YI RIEULSIOS
+0x85D7 0xB06D #HANGUL SYLLABLE SSANGKIYEOK YI RIEULTHIEUTH
+0x85D8 0xB06E #HANGUL SYLLABLE SSANGKIYEOK YI RIEULPHIEUPH
+0x85D9 0xB06F #HANGUL SYLLABLE SSANGKIYEOK YI RIEULHIEUH
+0x85DA 0xB070 #HANGUL SYLLABLE SSANGKIYEOK YI MIEUM
+0x85DB 0xB071 #HANGUL SYLLABLE SSANGKIYEOK YI PIEUP
+0x85DC 0xB072 #HANGUL SYLLABLE SSANGKIYEOK YI PIEUPSIOS
+0x85DD 0xB073 #HANGUL SYLLABLE SSANGKIYEOK YI SIOS
+0x85DE 0xB074 #HANGUL SYLLABLE SSANGKIYEOK YI SSANGSIOS
+0x85DF 0xB075 #HANGUL SYLLABLE SSANGKIYEOK YI IEUNG
+0x85E0 0xB076 #HANGUL SYLLABLE SSANGKIYEOK YI CIEUC
+0x85E1 0xB077 #HANGUL SYLLABLE SSANGKIYEOK YI CHIEUCH
+0x85E2 0xB078 #HANGUL SYLLABLE SSANGKIYEOK YI KHIEUKH
+0x85E3 0xB079 #HANGUL SYLLABLE SSANGKIYEOK YI THIEUTH
+0x85E4 0xB07A #HANGUL SYLLABLE SSANGKIYEOK YI PHIEUPH
+0x85E5 0xB07B #HANGUL SYLLABLE SSANGKIYEOK YI HIEUH
+0x85E6 0xB07E #HANGUL SYLLABLE SSANGKIYEOK I SSANGKIYEOK
+0x85E7 0xB07F #HANGUL SYLLABLE SSANGKIYEOK I KIYEOKSIOS
+0x85E8 0xB081 #HANGUL SYLLABLE SSANGKIYEOK I NIEUNCIEUC
+0x85E9 0xB082 #HANGUL SYLLABLE SSANGKIYEOK I NIEUNHIEUH
+0x85EA 0xB083 #HANGUL SYLLABLE SSANGKIYEOK I TIKEUT
+0x85EB 0xB085 #HANGUL SYLLABLE SSANGKIYEOK I RIEULKIYEOK
+0x85EC 0xB086 #HANGUL SYLLABLE SSANGKIYEOK I RIEULMIEUM
+0x85ED 0xB087 #HANGUL SYLLABLE SSANGKIYEOK I RIEULPIEUP
+0x85EE 0xB088 #HANGUL SYLLABLE SSANGKIYEOK I RIEULSIOS
+0x85EF 0xB089 #HANGUL SYLLABLE SSANGKIYEOK I RIEULTHIEUTH
+0x85F0 0xB08A #HANGUL SYLLABLE SSANGKIYEOK I RIEULPHIEUPH
+0x85F1 0xB08B #HANGUL SYLLABLE SSANGKIYEOK I RIEULHIEUH
+0x85F2 0xB08E #HANGUL SYLLABLE SSANGKIYEOK I PIEUPSIOS
+0x85F3 0xB090 #HANGUL SYLLABLE SSANGKIYEOK I SSANGSIOS
+0x85F4 0xB092 #HANGUL SYLLABLE SSANGKIYEOK I CIEUC
+0x85F5 0xB093 #HANGUL SYLLABLE SSANGKIYEOK I CHIEUCH
+0x85F6 0xB094 #HANGUL SYLLABLE SSANGKIYEOK I KHIEUKH
+0x85F7 0xB095 #HANGUL SYLLABLE SSANGKIYEOK I THIEUTH
+0x85F8 0xB096 #HANGUL SYLLABLE SSANGKIYEOK I PHIEUPH
+0x85F9 0xB097 #HANGUL SYLLABLE SSANGKIYEOK I HIEUH
+0x85FA 0xB09B #HANGUL SYLLABLE NIEUN A KIYEOKSIOS
+0x85FB 0xB09D #HANGUL SYLLABLE NIEUN A NIEUNCIEUC
+0x85FC 0xB09E #HANGUL SYLLABLE NIEUN A NIEUNHIEUH
+0x85FD 0xB0A3 #HANGUL SYLLABLE NIEUN A RIEULPIEUP
+0x85FE 0xB0A4 #HANGUL SYLLABLE NIEUN A RIEULSIOS
+0x8641 0xB0A5 #HANGUL SYLLABLE NIEUN A RIEULTHIEUTH
+0x8642 0xB0A6 #HANGUL SYLLABLE NIEUN A RIEULPHIEUPH
+0x8643 0xB0A7 #HANGUL SYLLABLE NIEUN A RIEULHIEUH
+0x8644 0xB0AA #HANGUL SYLLABLE NIEUN A PIEUPSIOS
+0x8645 0xB0B0 #HANGUL SYLLABLE NIEUN A KHIEUKH
+0x8646 0xB0B2 #HANGUL SYLLABLE NIEUN A PHIEUPH
+0x8647 0xB0B6 #HANGUL SYLLABLE NIEUN AE SSANGKIYEOK
+0x8648 0xB0B7 #HANGUL SYLLABLE NIEUN AE KIYEOKSIOS
+0x8649 0xB0B9 #HANGUL SYLLABLE NIEUN AE NIEUNCIEUC
+0x864A 0xB0BA #HANGUL SYLLABLE NIEUN AE NIEUNHIEUH
+0x864B 0xB0BB #HANGUL SYLLABLE NIEUN AE TIKEUT
+0x864C 0xB0BD #HANGUL SYLLABLE NIEUN AE RIEULKIYEOK
+0x864D 0xB0BE #HANGUL SYLLABLE NIEUN AE RIEULMIEUM
+0x864E 0xB0BF #HANGUL SYLLABLE NIEUN AE RIEULPIEUP
+0x864F 0xB0C0 #HANGUL SYLLABLE NIEUN AE RIEULSIOS
+0x8650 0xB0C1 #HANGUL SYLLABLE NIEUN AE RIEULTHIEUTH
+0x8651 0xB0C2 #HANGUL SYLLABLE NIEUN AE RIEULPHIEUPH
+0x8652 0xB0C3 #HANGUL SYLLABLE NIEUN AE RIEULHIEUH
+0x8653 0xB0C6 #HANGUL SYLLABLE NIEUN AE PIEUPSIOS
+0x8654 0xB0CA #HANGUL SYLLABLE NIEUN AE CIEUC
+0x8655 0xB0CB #HANGUL SYLLABLE NIEUN AE CHIEUCH
+0x8656 0xB0CC #HANGUL SYLLABLE NIEUN AE KHIEUKH
+0x8657 0xB0CD #HANGUL SYLLABLE NIEUN AE THIEUTH
+0x8658 0xB0CE #HANGUL SYLLABLE NIEUN AE PHIEUPH
+0x8659 0xB0CF #HANGUL SYLLABLE NIEUN AE HIEUH
+0x865A 0xB0D2 #HANGUL SYLLABLE NIEUN YA SSANGKIYEOK
+0x8661 0xB0D3 #HANGUL SYLLABLE NIEUN YA KIYEOKSIOS
+0x8662 0xB0D5 #HANGUL SYLLABLE NIEUN YA NIEUNCIEUC
+0x8663 0xB0D6 #HANGUL SYLLABLE NIEUN YA NIEUNHIEUH
+0x8664 0xB0D7 #HANGUL SYLLABLE NIEUN YA TIKEUT
+0x8665 0xB0D9 #HANGUL SYLLABLE NIEUN YA RIEULKIYEOK
+0x8666 0xB0DA #HANGUL SYLLABLE NIEUN YA RIEULMIEUM
+0x8667 0xB0DB #HANGUL SYLLABLE NIEUN YA RIEULPIEUP
+0x8668 0xB0DC #HANGUL SYLLABLE NIEUN YA RIEULSIOS
+0x8669 0xB0DD #HANGUL SYLLABLE NIEUN YA RIEULTHIEUTH
+0x866A 0xB0DE #HANGUL SYLLABLE NIEUN YA RIEULPHIEUPH
+0x866B 0xB0DF #HANGUL SYLLABLE NIEUN YA RIEULHIEUH
+0x866C 0xB0E1 #HANGUL SYLLABLE NIEUN YA PIEUP
+0x866D 0xB0E2 #HANGUL SYLLABLE NIEUN YA PIEUPSIOS
+0x866E 0xB0E3 #HANGUL SYLLABLE NIEUN YA SIOS
+0x866F 0xB0E4 #HANGUL SYLLABLE NIEUN YA SSANGSIOS
+0x8670 0xB0E6 #HANGUL SYLLABLE NIEUN YA CIEUC
+0x8671 0xB0E7 #HANGUL SYLLABLE NIEUN YA CHIEUCH
+0x8672 0xB0E8 #HANGUL SYLLABLE NIEUN YA KHIEUKH
+0x8673 0xB0E9 #HANGUL SYLLABLE NIEUN YA THIEUTH
+0x8674 0xB0EA #HANGUL SYLLABLE NIEUN YA PHIEUPH
+0x8675 0xB0EB #HANGUL SYLLABLE NIEUN YA HIEUH
+0x8676 0xB0EC #HANGUL SYLLABLE NIEUN YAE
+0x8677 0xB0ED #HANGUL SYLLABLE NIEUN YAE KIYEOK
+0x8678 0xB0EE #HANGUL SYLLABLE NIEUN YAE SSANGKIYEOK
+0x8679 0xB0EF #HANGUL SYLLABLE NIEUN YAE KIYEOKSIOS
+0x867A 0xB0F0 #HANGUL SYLLABLE NIEUN YAE NIEUN
+0x8681 0xB0F1 #HANGUL SYLLABLE NIEUN YAE NIEUNCIEUC
+0x8682 0xB0F2 #HANGUL SYLLABLE NIEUN YAE NIEUNHIEUH
+0x8683 0xB0F3 #HANGUL SYLLABLE NIEUN YAE TIKEUT
+0x8684 0xB0F4 #HANGUL SYLLABLE NIEUN YAE RIEUL
+0x8685 0xB0F5 #HANGUL SYLLABLE NIEUN YAE RIEULKIYEOK
+0x8686 0xB0F6 #HANGUL SYLLABLE NIEUN YAE RIEULMIEUM
+0x8687 0xB0F7 #HANGUL SYLLABLE NIEUN YAE RIEULPIEUP
+0x8688 0xB0F8 #HANGUL SYLLABLE NIEUN YAE RIEULSIOS
+0x8689 0xB0F9 #HANGUL SYLLABLE NIEUN YAE RIEULTHIEUTH
+0x868A 0xB0FA #HANGUL SYLLABLE NIEUN YAE RIEULPHIEUPH
+0x868B 0xB0FB #HANGUL SYLLABLE NIEUN YAE RIEULHIEUH
+0x868C 0xB0FC #HANGUL SYLLABLE NIEUN YAE MIEUM
+0x868D 0xB0FD #HANGUL SYLLABLE NIEUN YAE PIEUP
+0x868E 0xB0FE #HANGUL SYLLABLE NIEUN YAE PIEUPSIOS
+0x868F 0xB0FF #HANGUL SYLLABLE NIEUN YAE SIOS
+0x8690 0xB100 #HANGUL SYLLABLE NIEUN YAE SSANGSIOS
+0x8691 0xB101 #HANGUL SYLLABLE NIEUN YAE IEUNG
+0x8692 0xB102 #HANGUL SYLLABLE NIEUN YAE CIEUC
+0x8693 0xB103 #HANGUL SYLLABLE NIEUN YAE CHIEUCH
+0x8694 0xB104 #HANGUL SYLLABLE NIEUN YAE KHIEUKH
+0x8695 0xB105 #HANGUL SYLLABLE NIEUN YAE THIEUTH
+0x8696 0xB106 #HANGUL SYLLABLE NIEUN YAE PHIEUPH
+0x8697 0xB107 #HANGUL SYLLABLE NIEUN YAE HIEUH
+0x8698 0xB10A #HANGUL SYLLABLE NIEUN EO SSANGKIYEOK
+0x8699 0xB10D #HANGUL SYLLABLE NIEUN EO NIEUNCIEUC
+0x869A 0xB10E #HANGUL SYLLABLE NIEUN EO NIEUNHIEUH
+0x869B 0xB10F #HANGUL SYLLABLE NIEUN EO TIKEUT
+0x869C 0xB111 #HANGUL SYLLABLE NIEUN EO RIEULKIYEOK
+0x869D 0xB114 #HANGUL SYLLABLE NIEUN EO RIEULSIOS
+0x869E 0xB115 #HANGUL SYLLABLE NIEUN EO RIEULTHIEUTH
+0x869F 0xB116 #HANGUL SYLLABLE NIEUN EO RIEULPHIEUPH
+0x86A0 0xB117 #HANGUL SYLLABLE NIEUN EO RIEULHIEUH
+0x86A1 0xB11A #HANGUL SYLLABLE NIEUN EO PIEUPSIOS
+0x86A2 0xB11E #HANGUL SYLLABLE NIEUN EO CIEUC
+0x86A3 0xB11F #HANGUL SYLLABLE NIEUN EO CHIEUCH
+0x86A4 0xB120 #HANGUL SYLLABLE NIEUN EO KHIEUKH
+0x86A5 0xB121 #HANGUL SYLLABLE NIEUN EO THIEUTH
+0x86A6 0xB122 #HANGUL SYLLABLE NIEUN EO PHIEUPH
+0x86A7 0xB126 #HANGUL SYLLABLE NIEUN E SSANGKIYEOK
+0x86A8 0xB127 #HANGUL SYLLABLE NIEUN E KIYEOKSIOS
+0x86A9 0xB129 #HANGUL SYLLABLE NIEUN E NIEUNCIEUC
+0x86AA 0xB12A #HANGUL SYLLABLE NIEUN E NIEUNHIEUH
+0x86AB 0xB12B #HANGUL SYLLABLE NIEUN E TIKEUT
+0x86AC 0xB12D #HANGUL SYLLABLE NIEUN E RIEULKIYEOK
+0x86AD 0xB12E #HANGUL SYLLABLE NIEUN E RIEULMIEUM
+0x86AE 0xB12F #HANGUL SYLLABLE NIEUN E RIEULPIEUP
+0x86AF 0xB130 #HANGUL SYLLABLE NIEUN E RIEULSIOS
+0x86B0 0xB131 #HANGUL SYLLABLE NIEUN E RIEULTHIEUTH
+0x86B1 0xB132 #HANGUL SYLLABLE NIEUN E RIEULPHIEUPH
+0x86B2 0xB133 #HANGUL SYLLABLE NIEUN E RIEULHIEUH
+0x86B3 0xB136 #HANGUL SYLLABLE NIEUN E PIEUPSIOS
+0x86B4 0xB13A #HANGUL SYLLABLE NIEUN E CIEUC
+0x86B5 0xB13B #HANGUL SYLLABLE NIEUN E CHIEUCH
+0x86B6 0xB13C #HANGUL SYLLABLE NIEUN E KHIEUKH
+0x86B7 0xB13D #HANGUL SYLLABLE NIEUN E THIEUTH
+0x86B8 0xB13E #HANGUL SYLLABLE NIEUN E PHIEUPH
+0x86B9 0xB13F #HANGUL SYLLABLE NIEUN E HIEUH
+0x86BA 0xB142 #HANGUL SYLLABLE NIEUN YEO SSANGKIYEOK
+0x86BB 0xB143 #HANGUL SYLLABLE NIEUN YEO KIYEOKSIOS
+0x86BC 0xB145 #HANGUL SYLLABLE NIEUN YEO NIEUNCIEUC
+0x86BD 0xB146 #HANGUL SYLLABLE NIEUN YEO NIEUNHIEUH
+0x86BE 0xB147 #HANGUL SYLLABLE NIEUN YEO TIKEUT
+0x86BF 0xB149 #HANGUL SYLLABLE NIEUN YEO RIEULKIYEOK
+0x86C0 0xB14A #HANGUL SYLLABLE NIEUN YEO RIEULMIEUM
+0x86C1 0xB14B #HANGUL SYLLABLE NIEUN YEO RIEULPIEUP
+0x86C2 0xB14C #HANGUL SYLLABLE NIEUN YEO RIEULSIOS
+0x86C3 0xB14D #HANGUL SYLLABLE NIEUN YEO RIEULTHIEUTH
+0x86C4 0xB14E #HANGUL SYLLABLE NIEUN YEO RIEULPHIEUPH
+0x86C5 0xB14F #HANGUL SYLLABLE NIEUN YEO RIEULHIEUH
+0x86C6 0xB152 #HANGUL SYLLABLE NIEUN YEO PIEUPSIOS
+0x86C7 0xB153 #HANGUL SYLLABLE NIEUN YEO SIOS
+0x86C8 0xB156 #HANGUL SYLLABLE NIEUN YEO CIEUC
+0x86C9 0xB157 #HANGUL SYLLABLE NIEUN YEO CHIEUCH
+0x86CA 0xB159 #HANGUL SYLLABLE NIEUN YEO THIEUTH
+0x86CB 0xB15A #HANGUL SYLLABLE NIEUN YEO PHIEUPH
+0x86CC 0xB15B #HANGUL SYLLABLE NIEUN YEO HIEUH
+0x86CD 0xB15D #HANGUL SYLLABLE NIEUN YE KIYEOK
+0x86CE 0xB15E #HANGUL SYLLABLE NIEUN YE SSANGKIYEOK
+0x86CF 0xB15F #HANGUL SYLLABLE NIEUN YE KIYEOKSIOS
+0x86D0 0xB161 #HANGUL SYLLABLE NIEUN YE NIEUNCIEUC
+0x86D1 0xB162 #HANGUL SYLLABLE NIEUN YE NIEUNHIEUH
+0x86D2 0xB163 #HANGUL SYLLABLE NIEUN YE TIKEUT
+0x86D3 0xB164 #HANGUL SYLLABLE NIEUN YE RIEUL
+0x86D4 0xB165 #HANGUL SYLLABLE NIEUN YE RIEULKIYEOK
+0x86D5 0xB166 #HANGUL SYLLABLE NIEUN YE RIEULMIEUM
+0x86D6 0xB167 #HANGUL SYLLABLE NIEUN YE RIEULPIEUP
+0x86D7 0xB168 #HANGUL SYLLABLE NIEUN YE RIEULSIOS
+0x86D8 0xB169 #HANGUL SYLLABLE NIEUN YE RIEULTHIEUTH
+0x86D9 0xB16A #HANGUL SYLLABLE NIEUN YE RIEULPHIEUPH
+0x86DA 0xB16B #HANGUL SYLLABLE NIEUN YE RIEULHIEUH
+0x86DB 0xB16C #HANGUL SYLLABLE NIEUN YE MIEUM
+0x86DC 0xB16D #HANGUL SYLLABLE NIEUN YE PIEUP
+0x86DD 0xB16E #HANGUL SYLLABLE NIEUN YE PIEUPSIOS
+0x86DE 0xB16F #HANGUL SYLLABLE NIEUN YE SIOS
+0x86DF 0xB170 #HANGUL SYLLABLE NIEUN YE SSANGSIOS
+0x86E0 0xB171 #HANGUL SYLLABLE NIEUN YE IEUNG
+0x86E1 0xB172 #HANGUL SYLLABLE NIEUN YE CIEUC
+0x86E2 0xB173 #HANGUL SYLLABLE NIEUN YE CHIEUCH
+0x86E3 0xB174 #HANGUL SYLLABLE NIEUN YE KHIEUKH
+0x86E4 0xB175 #HANGUL SYLLABLE NIEUN YE THIEUTH
+0x86E5 0xB176 #HANGUL SYLLABLE NIEUN YE PHIEUPH
+0x86E6 0xB177 #HANGUL SYLLABLE NIEUN YE HIEUH
+0x86E7 0xB17A #HANGUL SYLLABLE NIEUN O SSANGKIYEOK
+0x86E8 0xB17B #HANGUL SYLLABLE NIEUN O KIYEOKSIOS
+0x86E9 0xB17D #HANGUL SYLLABLE NIEUN O NIEUNCIEUC
+0x86EA 0xB17E #HANGUL SYLLABLE NIEUN O NIEUNHIEUH
+0x86EB 0xB17F #HANGUL SYLLABLE NIEUN O TIKEUT
+0x86EC 0xB181 #HANGUL SYLLABLE NIEUN O RIEULKIYEOK
+0x86ED 0xB183 #HANGUL SYLLABLE NIEUN O RIEULPIEUP
+0x86EE 0xB184 #HANGUL SYLLABLE NIEUN O RIEULSIOS
+0x86EF 0xB185 #HANGUL SYLLABLE NIEUN O RIEULTHIEUTH
+0x86F0 0xB186 #HANGUL SYLLABLE NIEUN O RIEULPHIEUPH
+0x86F1 0xB187 #HANGUL SYLLABLE NIEUN O RIEULHIEUH
+0x86F2 0xB18A #HANGUL SYLLABLE NIEUN O PIEUPSIOS
+0x86F3 0xB18C #HANGUL SYLLABLE NIEUN O SSANGSIOS
+0x86F4 0xB18E #HANGUL SYLLABLE NIEUN O CIEUC
+0x86F5 0xB18F #HANGUL SYLLABLE NIEUN O CHIEUCH
+0x86F6 0xB190 #HANGUL SYLLABLE NIEUN O KHIEUKH
+0x86F7 0xB191 #HANGUL SYLLABLE NIEUN O THIEUTH
+0x86F8 0xB195 #HANGUL SYLLABLE NIEUN WA KIYEOK
+0x86F9 0xB196 #HANGUL SYLLABLE NIEUN WA SSANGKIYEOK
+0x86FA 0xB197 #HANGUL SYLLABLE NIEUN WA KIYEOKSIOS
+0x86FB 0xB199 #HANGUL SYLLABLE NIEUN WA NIEUNCIEUC
+0x86FC 0xB19A #HANGUL SYLLABLE NIEUN WA NIEUNHIEUH
+0x86FD 0xB19B #HANGUL SYLLABLE NIEUN WA TIKEUT
+0x86FE 0xB19D #HANGUL SYLLABLE NIEUN WA RIEULKIYEOK
+0x8741 0xB19E #HANGUL SYLLABLE NIEUN WA RIEULMIEUM
+0x8742 0xB19F #HANGUL SYLLABLE NIEUN WA RIEULPIEUP
+0x8743 0xB1A0 #HANGUL SYLLABLE NIEUN WA RIEULSIOS
+0x8744 0xB1A1 #HANGUL SYLLABLE NIEUN WA RIEULTHIEUTH
+0x8745 0xB1A2 #HANGUL SYLLABLE NIEUN WA RIEULPHIEUPH
+0x8746 0xB1A3 #HANGUL SYLLABLE NIEUN WA RIEULHIEUH
+0x8747 0xB1A4 #HANGUL SYLLABLE NIEUN WA MIEUM
+0x8748 0xB1A5 #HANGUL SYLLABLE NIEUN WA PIEUP
+0x8749 0xB1A6 #HANGUL SYLLABLE NIEUN WA PIEUPSIOS
+0x874A 0xB1A7 #HANGUL SYLLABLE NIEUN WA SIOS
+0x874B 0xB1A9 #HANGUL SYLLABLE NIEUN WA IEUNG
+0x874C 0xB1AA #HANGUL SYLLABLE NIEUN WA CIEUC
+0x874D 0xB1AB #HANGUL SYLLABLE NIEUN WA CHIEUCH
+0x874E 0xB1AC #HANGUL SYLLABLE NIEUN WA KHIEUKH
+0x874F 0xB1AD #HANGUL SYLLABLE NIEUN WA THIEUTH
+0x8750 0xB1AE #HANGUL SYLLABLE NIEUN WA PHIEUPH
+0x8751 0xB1AF #HANGUL SYLLABLE NIEUN WA HIEUH
+0x8752 0xB1B0 #HANGUL SYLLABLE NIEUN WAE
+0x8753 0xB1B1 #HANGUL SYLLABLE NIEUN WAE KIYEOK
+0x8754 0xB1B2 #HANGUL SYLLABLE NIEUN WAE SSANGKIYEOK
+0x8755 0xB1B3 #HANGUL SYLLABLE NIEUN WAE KIYEOKSIOS
+0x8756 0xB1B4 #HANGUL SYLLABLE NIEUN WAE NIEUN
+0x8757 0xB1B5 #HANGUL SYLLABLE NIEUN WAE NIEUNCIEUC
+0x8758 0xB1B6 #HANGUL SYLLABLE NIEUN WAE NIEUNHIEUH
+0x8759 0xB1B7 #HANGUL SYLLABLE NIEUN WAE TIKEUT
+0x875A 0xB1B8 #HANGUL SYLLABLE NIEUN WAE RIEUL
+0x8761 0xB1B9 #HANGUL SYLLABLE NIEUN WAE RIEULKIYEOK
+0x8762 0xB1BA #HANGUL SYLLABLE NIEUN WAE RIEULMIEUM
+0x8763 0xB1BB #HANGUL SYLLABLE NIEUN WAE RIEULPIEUP
+0x8764 0xB1BC #HANGUL SYLLABLE NIEUN WAE RIEULSIOS
+0x8765 0xB1BD #HANGUL SYLLABLE NIEUN WAE RIEULTHIEUTH
+0x8766 0xB1BE #HANGUL SYLLABLE NIEUN WAE RIEULPHIEUPH
+0x8767 0xB1BF #HANGUL SYLLABLE NIEUN WAE RIEULHIEUH
+0x8768 0xB1C0 #HANGUL SYLLABLE NIEUN WAE MIEUM
+0x8769 0xB1C1 #HANGUL SYLLABLE NIEUN WAE PIEUP
+0x876A 0xB1C2 #HANGUL SYLLABLE NIEUN WAE PIEUPSIOS
+0x876B 0xB1C3 #HANGUL SYLLABLE NIEUN WAE SIOS
+0x876C 0xB1C4 #HANGUL SYLLABLE NIEUN WAE SSANGSIOS
+0x876D 0xB1C5 #HANGUL SYLLABLE NIEUN WAE IEUNG
+0x876E 0xB1C6 #HANGUL SYLLABLE NIEUN WAE CIEUC
+0x876F 0xB1C7 #HANGUL SYLLABLE NIEUN WAE CHIEUCH
+0x8770 0xB1C8 #HANGUL SYLLABLE NIEUN WAE KHIEUKH
+0x8771 0xB1C9 #HANGUL SYLLABLE NIEUN WAE THIEUTH
+0x8772 0xB1CA #HANGUL SYLLABLE NIEUN WAE PHIEUPH
+0x8773 0xB1CB #HANGUL SYLLABLE NIEUN WAE HIEUH
+0x8774 0xB1CD #HANGUL SYLLABLE NIEUN OE KIYEOK
+0x8775 0xB1CE #HANGUL SYLLABLE NIEUN OE SSANGKIYEOK
+0x8776 0xB1CF #HANGUL SYLLABLE NIEUN OE KIYEOKSIOS
+0x8777 0xB1D1 #HANGUL SYLLABLE NIEUN OE NIEUNCIEUC
+0x8778 0xB1D2 #HANGUL SYLLABLE NIEUN OE NIEUNHIEUH
+0x8779 0xB1D3 #HANGUL SYLLABLE NIEUN OE TIKEUT
+0x877A 0xB1D5 #HANGUL SYLLABLE NIEUN OE RIEULKIYEOK
+0x8781 0xB1D6 #HANGUL SYLLABLE NIEUN OE RIEULMIEUM
+0x8782 0xB1D7 #HANGUL SYLLABLE NIEUN OE RIEULPIEUP
+0x8783 0xB1D8 #HANGUL SYLLABLE NIEUN OE RIEULSIOS
+0x8784 0xB1D9 #HANGUL SYLLABLE NIEUN OE RIEULTHIEUTH
+0x8785 0xB1DA #HANGUL SYLLABLE NIEUN OE RIEULPHIEUPH
+0x8786 0xB1DB #HANGUL SYLLABLE NIEUN OE RIEULHIEUH
+0x8787 0xB1DE #HANGUL SYLLABLE NIEUN OE PIEUPSIOS
+0x8788 0xB1E0 #HANGUL SYLLABLE NIEUN OE SSANGSIOS
+0x8789 0xB1E1 #HANGUL SYLLABLE NIEUN OE IEUNG
+0x878A 0xB1E2 #HANGUL SYLLABLE NIEUN OE CIEUC
+0x878B 0xB1E3 #HANGUL SYLLABLE NIEUN OE CHIEUCH
+0x878C 0xB1E4 #HANGUL SYLLABLE NIEUN OE KHIEUKH
+0x878D 0xB1E5 #HANGUL SYLLABLE NIEUN OE THIEUTH
+0x878E 0xB1E6 #HANGUL SYLLABLE NIEUN OE PHIEUPH
+0x878F 0xB1E7 #HANGUL SYLLABLE NIEUN OE HIEUH
+0x8790 0xB1EA #HANGUL SYLLABLE NIEUN YO SSANGKIYEOK
+0x8791 0xB1EB #HANGUL SYLLABLE NIEUN YO KIYEOKSIOS
+0x8792 0xB1ED #HANGUL SYLLABLE NIEUN YO NIEUNCIEUC
+0x8793 0xB1EE #HANGUL SYLLABLE NIEUN YO NIEUNHIEUH
+0x8794 0xB1EF #HANGUL SYLLABLE NIEUN YO TIKEUT
+0x8795 0xB1F1 #HANGUL SYLLABLE NIEUN YO RIEULKIYEOK
+0x8796 0xB1F2 #HANGUL SYLLABLE NIEUN YO RIEULMIEUM
+0x8797 0xB1F3 #HANGUL SYLLABLE NIEUN YO RIEULPIEUP
+0x8798 0xB1F4 #HANGUL SYLLABLE NIEUN YO RIEULSIOS
+0x8799 0xB1F5 #HANGUL SYLLABLE NIEUN YO RIEULTHIEUTH
+0x879A 0xB1F6 #HANGUL SYLLABLE NIEUN YO RIEULPHIEUPH
+0x879B 0xB1F7 #HANGUL SYLLABLE NIEUN YO RIEULHIEUH
+0x879C 0xB1F8 #HANGUL SYLLABLE NIEUN YO MIEUM
+0x879D 0xB1FA #HANGUL SYLLABLE NIEUN YO PIEUPSIOS
+0x879E 0xB1FC #HANGUL SYLLABLE NIEUN YO SSANGSIOS
+0x879F 0xB1FE #HANGUL SYLLABLE NIEUN YO CIEUC
+0x87A0 0xB1FF #HANGUL SYLLABLE NIEUN YO CHIEUCH
+0x87A1 0xB200 #HANGUL SYLLABLE NIEUN YO KHIEUKH
+0x87A2 0xB201 #HANGUL SYLLABLE NIEUN YO THIEUTH
+0x87A3 0xB202 #HANGUL SYLLABLE NIEUN YO PHIEUPH
+0x87A4 0xB203 #HANGUL SYLLABLE NIEUN YO HIEUH
+0x87A5 0xB206 #HANGUL SYLLABLE NIEUN U SSANGKIYEOK
+0x87A6 0xB207 #HANGUL SYLLABLE NIEUN U KIYEOKSIOS
+0x87A7 0xB209 #HANGUL SYLLABLE NIEUN U NIEUNCIEUC
+0x87A8 0xB20A #HANGUL SYLLABLE NIEUN U NIEUNHIEUH
+0x87A9 0xB20D #HANGUL SYLLABLE NIEUN U RIEULKIYEOK
+0x87AA 0xB20E #HANGUL SYLLABLE NIEUN U RIEULMIEUM
+0x87AB 0xB20F #HANGUL SYLLABLE NIEUN U RIEULPIEUP
+0x87AC 0xB210 #HANGUL SYLLABLE NIEUN U RIEULSIOS
+0x87AD 0xB211 #HANGUL SYLLABLE NIEUN U RIEULTHIEUTH
+0x87AE 0xB212 #HANGUL SYLLABLE NIEUN U RIEULPHIEUPH
+0x87AF 0xB213 #HANGUL SYLLABLE NIEUN U RIEULHIEUH
+0x87B0 0xB216 #HANGUL SYLLABLE NIEUN U PIEUPSIOS
+0x87B1 0xB218 #HANGUL SYLLABLE NIEUN U SSANGSIOS
+0x87B2 0xB21A #HANGUL SYLLABLE NIEUN U CIEUC
+0x87B3 0xB21B #HANGUL SYLLABLE NIEUN U CHIEUCH
+0x87B4 0xB21C #HANGUL SYLLABLE NIEUN U KHIEUKH
+0x87B5 0xB21D #HANGUL SYLLABLE NIEUN U THIEUTH
+0x87B6 0xB21E #HANGUL SYLLABLE NIEUN U PHIEUPH
+0x87B7 0xB21F #HANGUL SYLLABLE NIEUN U HIEUH
+0x87B8 0xB221 #HANGUL SYLLABLE NIEUN WEO KIYEOK
+0x87B9 0xB222 #HANGUL SYLLABLE NIEUN WEO SSANGKIYEOK
+0x87BA 0xB223 #HANGUL SYLLABLE NIEUN WEO KIYEOKSIOS
+0x87BB 0xB224 #HANGUL SYLLABLE NIEUN WEO NIEUN
+0x87BC 0xB225 #HANGUL SYLLABLE NIEUN WEO NIEUNCIEUC
+0x87BD 0xB226 #HANGUL SYLLABLE NIEUN WEO NIEUNHIEUH
+0x87BE 0xB227 #HANGUL SYLLABLE NIEUN WEO TIKEUT
+0x87BF 0xB228 #HANGUL SYLLABLE NIEUN WEO RIEUL
+0x87C0 0xB229 #HANGUL SYLLABLE NIEUN WEO RIEULKIYEOK
+0x87C1 0xB22A #HANGUL SYLLABLE NIEUN WEO RIEULMIEUM
+0x87C2 0xB22B #HANGUL SYLLABLE NIEUN WEO RIEULPIEUP
+0x87C3 0xB22C #HANGUL SYLLABLE NIEUN WEO RIEULSIOS
+0x87C4 0xB22D #HANGUL SYLLABLE NIEUN WEO RIEULTHIEUTH
+0x87C5 0xB22E #HANGUL SYLLABLE NIEUN WEO RIEULPHIEUPH
+0x87C6 0xB22F #HANGUL SYLLABLE NIEUN WEO RIEULHIEUH
+0x87C7 0xB230 #HANGUL SYLLABLE NIEUN WEO MIEUM
+0x87C8 0xB231 #HANGUL SYLLABLE NIEUN WEO PIEUP
+0x87C9 0xB232 #HANGUL SYLLABLE NIEUN WEO PIEUPSIOS
+0x87CA 0xB233 #HANGUL SYLLABLE NIEUN WEO SIOS
+0x87CB 0xB235 #HANGUL SYLLABLE NIEUN WEO IEUNG
+0x87CC 0xB236 #HANGUL SYLLABLE NIEUN WEO CIEUC
+0x87CD 0xB237 #HANGUL SYLLABLE NIEUN WEO CHIEUCH
+0x87CE 0xB238 #HANGUL SYLLABLE NIEUN WEO KHIEUKH
+0x87CF 0xB239 #HANGUL SYLLABLE NIEUN WEO THIEUTH
+0x87D0 0xB23A #HANGUL SYLLABLE NIEUN WEO PHIEUPH
+0x87D1 0xB23B #HANGUL SYLLABLE NIEUN WEO HIEUH
+0x87D2 0xB23D #HANGUL SYLLABLE NIEUN WE KIYEOK
+0x87D3 0xB23E #HANGUL SYLLABLE NIEUN WE SSANGKIYEOK
+0x87D4 0xB23F #HANGUL SYLLABLE NIEUN WE KIYEOKSIOS
+0x87D5 0xB240 #HANGUL SYLLABLE NIEUN WE NIEUN
+0x87D6 0xB241 #HANGUL SYLLABLE NIEUN WE NIEUNCIEUC
+0x87D7 0xB242 #HANGUL SYLLABLE NIEUN WE NIEUNHIEUH
+0x87D8 0xB243 #HANGUL SYLLABLE NIEUN WE TIKEUT
+0x87D9 0xB244 #HANGUL SYLLABLE NIEUN WE RIEUL
+0x87DA 0xB245 #HANGUL SYLLABLE NIEUN WE RIEULKIYEOK
+0x87DB 0xB246 #HANGUL SYLLABLE NIEUN WE RIEULMIEUM
+0x87DC 0xB247 #HANGUL SYLLABLE NIEUN WE RIEULPIEUP
+0x87DD 0xB248 #HANGUL SYLLABLE NIEUN WE RIEULSIOS
+0x87DE 0xB249 #HANGUL SYLLABLE NIEUN WE RIEULTHIEUTH
+0x87DF 0xB24A #HANGUL SYLLABLE NIEUN WE RIEULPHIEUPH
+0x87E0 0xB24B #HANGUL SYLLABLE NIEUN WE RIEULHIEUH
+0x87E1 0xB24C #HANGUL SYLLABLE NIEUN WE MIEUM
+0x87E2 0xB24D #HANGUL SYLLABLE NIEUN WE PIEUP
+0x87E3 0xB24E #HANGUL SYLLABLE NIEUN WE PIEUPSIOS
+0x87E4 0xB24F #HANGUL SYLLABLE NIEUN WE SIOS
+0x87E5 0xB250 #HANGUL SYLLABLE NIEUN WE SSANGSIOS
+0x87E6 0xB251 #HANGUL SYLLABLE NIEUN WE IEUNG
+0x87E7 0xB252 #HANGUL SYLLABLE NIEUN WE CIEUC
+0x87E8 0xB253 #HANGUL SYLLABLE NIEUN WE CHIEUCH
+0x87E9 0xB254 #HANGUL SYLLABLE NIEUN WE KHIEUKH
+0x87EA 0xB255 #HANGUL SYLLABLE NIEUN WE THIEUTH
+0x87EB 0xB256 #HANGUL SYLLABLE NIEUN WE PHIEUPH
+0x87EC 0xB257 #HANGUL SYLLABLE NIEUN WE HIEUH
+0x87ED 0xB259 #HANGUL SYLLABLE NIEUN WI KIYEOK
+0x87EE 0xB25A #HANGUL SYLLABLE NIEUN WI SSANGKIYEOK
+0x87EF 0xB25B #HANGUL SYLLABLE NIEUN WI KIYEOKSIOS
+0x87F0 0xB25D #HANGUL SYLLABLE NIEUN WI NIEUNCIEUC
+0x87F1 0xB25E #HANGUL SYLLABLE NIEUN WI NIEUNHIEUH
+0x87F2 0xB25F #HANGUL SYLLABLE NIEUN WI TIKEUT
+0x87F3 0xB261 #HANGUL SYLLABLE NIEUN WI RIEULKIYEOK
+0x87F4 0xB262 #HANGUL SYLLABLE NIEUN WI RIEULMIEUM
+0x87F5 0xB263 #HANGUL SYLLABLE NIEUN WI RIEULPIEUP
+0x87F6 0xB264 #HANGUL SYLLABLE NIEUN WI RIEULSIOS
+0x87F7 0xB265 #HANGUL SYLLABLE NIEUN WI RIEULTHIEUTH
+0x87F8 0xB266 #HANGUL SYLLABLE NIEUN WI RIEULPHIEUPH
+0x87F9 0xB267 #HANGUL SYLLABLE NIEUN WI RIEULHIEUH
+0x87FA 0xB26A #HANGUL SYLLABLE NIEUN WI PIEUPSIOS
+0x87FB 0xB26B #HANGUL SYLLABLE NIEUN WI SIOS
+0x87FC 0xB26C #HANGUL SYLLABLE NIEUN WI SSANGSIOS
+0x87FD 0xB26D #HANGUL SYLLABLE NIEUN WI IEUNG
+0x87FE 0xB26E #HANGUL SYLLABLE NIEUN WI CIEUC
+0x8841 0xB26F #HANGUL SYLLABLE NIEUN WI CHIEUCH
+0x8842 0xB270 #HANGUL SYLLABLE NIEUN WI KHIEUKH
+0x8843 0xB271 #HANGUL SYLLABLE NIEUN WI THIEUTH
+0x8844 0xB272 #HANGUL SYLLABLE NIEUN WI PHIEUPH
+0x8845 0xB273 #HANGUL SYLLABLE NIEUN WI HIEUH
+0x8846 0xB276 #HANGUL SYLLABLE NIEUN YU SSANGKIYEOK
+0x8847 0xB277 #HANGUL SYLLABLE NIEUN YU KIYEOKSIOS
+0x8848 0xB278 #HANGUL SYLLABLE NIEUN YU NIEUN
+0x8849 0xB279 #HANGUL SYLLABLE NIEUN YU NIEUNCIEUC
+0x884A 0xB27A #HANGUL SYLLABLE NIEUN YU NIEUNHIEUH
+0x884B 0xB27B #HANGUL SYLLABLE NIEUN YU TIKEUT
+0x884C 0xB27D #HANGUL SYLLABLE NIEUN YU RIEULKIYEOK
+0x884D 0xB27E #HANGUL SYLLABLE NIEUN YU RIEULMIEUM
+0x884E 0xB27F #HANGUL SYLLABLE NIEUN YU RIEULPIEUP
+0x884F 0xB280 #HANGUL SYLLABLE NIEUN YU RIEULSIOS
+0x8850 0xB281 #HANGUL SYLLABLE NIEUN YU RIEULTHIEUTH
+0x8851 0xB282 #HANGUL SYLLABLE NIEUN YU RIEULPHIEUPH
+0x8852 0xB283 #HANGUL SYLLABLE NIEUN YU RIEULHIEUH
+0x8853 0xB286 #HANGUL SYLLABLE NIEUN YU PIEUPSIOS
+0x8854 0xB287 #HANGUL SYLLABLE NIEUN YU SIOS
+0x8855 0xB288 #HANGUL SYLLABLE NIEUN YU SSANGSIOS
+0x8856 0xB28A #HANGUL SYLLABLE NIEUN YU CIEUC
+0x8857 0xB28B #HANGUL SYLLABLE NIEUN YU CHIEUCH
+0x8858 0xB28C #HANGUL SYLLABLE NIEUN YU KHIEUKH
+0x8859 0xB28D #HANGUL SYLLABLE NIEUN YU THIEUTH
+0x885A 0xB28E #HANGUL SYLLABLE NIEUN YU PHIEUPH
+0x8861 0xB28F #HANGUL SYLLABLE NIEUN YU HIEUH
+0x8862 0xB292 #HANGUL SYLLABLE NIEUN EU SSANGKIYEOK
+0x8863 0xB293 #HANGUL SYLLABLE NIEUN EU KIYEOKSIOS
+0x8864 0xB295 #HANGUL SYLLABLE NIEUN EU NIEUNCIEUC
+0x8865 0xB296 #HANGUL SYLLABLE NIEUN EU NIEUNHIEUH
+0x8866 0xB297 #HANGUL SYLLABLE NIEUN EU TIKEUT
+0x8867 0xB29B #HANGUL SYLLABLE NIEUN EU RIEULPIEUP
+0x8868 0xB29C #HANGUL SYLLABLE NIEUN EU RIEULSIOS
+0x8869 0xB29D #HANGUL SYLLABLE NIEUN EU RIEULTHIEUTH
+0x886A 0xB29E #HANGUL SYLLABLE NIEUN EU RIEULPHIEUPH
+0x886B 0xB29F #HANGUL SYLLABLE NIEUN EU RIEULHIEUH
+0x886C 0xB2A2 #HANGUL SYLLABLE NIEUN EU PIEUPSIOS
+0x886D 0xB2A4 #HANGUL SYLLABLE NIEUN EU SSANGSIOS
+0x886E 0xB2A7 #HANGUL SYLLABLE NIEUN EU CHIEUCH
+0x886F 0xB2A8 #HANGUL SYLLABLE NIEUN EU KHIEUKH
+0x8870 0xB2A9 #HANGUL SYLLABLE NIEUN EU THIEUTH
+0x8871 0xB2AB #HANGUL SYLLABLE NIEUN EU HIEUH
+0x8872 0xB2AD #HANGUL SYLLABLE NIEUN YI KIYEOK
+0x8873 0xB2AE #HANGUL SYLLABLE NIEUN YI SSANGKIYEOK
+0x8874 0xB2AF #HANGUL SYLLABLE NIEUN YI KIYEOKSIOS
+0x8875 0xB2B1 #HANGUL SYLLABLE NIEUN YI NIEUNCIEUC
+0x8876 0xB2B2 #HANGUL SYLLABLE NIEUN YI NIEUNHIEUH
+0x8877 0xB2B3 #HANGUL SYLLABLE NIEUN YI TIKEUT
+0x8878 0xB2B5 #HANGUL SYLLABLE NIEUN YI RIEULKIYEOK
+0x8879 0xB2B6 #HANGUL SYLLABLE NIEUN YI RIEULMIEUM
+0x887A 0xB2B7 #HANGUL SYLLABLE NIEUN YI RIEULPIEUP
+0x8881 0xB2B8 #HANGUL SYLLABLE NIEUN YI RIEULSIOS
+0x8882 0xB2B9 #HANGUL SYLLABLE NIEUN YI RIEULTHIEUTH
+0x8883 0xB2BA #HANGUL SYLLABLE NIEUN YI RIEULPHIEUPH
+0x8884 0xB2BB #HANGUL SYLLABLE NIEUN YI RIEULHIEUH
+0x8885 0xB2BC #HANGUL SYLLABLE NIEUN YI MIEUM
+0x8886 0xB2BD #HANGUL SYLLABLE NIEUN YI PIEUP
+0x8887 0xB2BE #HANGUL SYLLABLE NIEUN YI PIEUPSIOS
+0x8888 0xB2BF #HANGUL SYLLABLE NIEUN YI SIOS
+0x8889 0xB2C0 #HANGUL SYLLABLE NIEUN YI SSANGSIOS
+0x888A 0xB2C1 #HANGUL SYLLABLE NIEUN YI IEUNG
+0x888B 0xB2C2 #HANGUL SYLLABLE NIEUN YI CIEUC
+0x888C 0xB2C3 #HANGUL SYLLABLE NIEUN YI CHIEUCH
+0x888D 0xB2C4 #HANGUL SYLLABLE NIEUN YI KHIEUKH
+0x888E 0xB2C5 #HANGUL SYLLABLE NIEUN YI THIEUTH
+0x888F 0xB2C6 #HANGUL SYLLABLE NIEUN YI PHIEUPH
+0x8890 0xB2C7 #HANGUL SYLLABLE NIEUN YI HIEUH
+0x8891 0xB2CA #HANGUL SYLLABLE NIEUN I SSANGKIYEOK
+0x8892 0xB2CB #HANGUL SYLLABLE NIEUN I KIYEOKSIOS
+0x8893 0xB2CD #HANGUL SYLLABLE NIEUN I NIEUNCIEUC
+0x8894 0xB2CE #HANGUL SYLLABLE NIEUN I NIEUNHIEUH
+0x8895 0xB2CF #HANGUL SYLLABLE NIEUN I TIKEUT
+0x8896 0xB2D1 #HANGUL SYLLABLE NIEUN I RIEULKIYEOK
+0x8897 0xB2D3 #HANGUL SYLLABLE NIEUN I RIEULPIEUP
+0x8898 0xB2D4 #HANGUL SYLLABLE NIEUN I RIEULSIOS
+0x8899 0xB2D5 #HANGUL SYLLABLE NIEUN I RIEULTHIEUTH
+0x889A 0xB2D6 #HANGUL SYLLABLE NIEUN I RIEULPHIEUPH
+0x889B 0xB2D7 #HANGUL SYLLABLE NIEUN I RIEULHIEUH
+0x889C 0xB2DA #HANGUL SYLLABLE NIEUN I PIEUPSIOS
+0x889D 0xB2DC #HANGUL SYLLABLE NIEUN I SSANGSIOS
+0x889E 0xB2DE #HANGUL SYLLABLE NIEUN I CIEUC
+0x889F 0xB2DF #HANGUL SYLLABLE NIEUN I CHIEUCH
+0x88A0 0xB2E0 #HANGUL SYLLABLE NIEUN I KHIEUKH
+0x88A1 0xB2E1 #HANGUL SYLLABLE NIEUN I THIEUTH
+0x88A2 0xB2E3 #HANGUL SYLLABLE NIEUN I HIEUH
+0x88A3 0xB2E7 #HANGUL SYLLABLE TIKEUT A KIYEOKSIOS
+0x88A4 0xB2E9 #HANGUL SYLLABLE TIKEUT A NIEUNCIEUC
+0x88A5 0xB2EA #HANGUL SYLLABLE TIKEUT A NIEUNHIEUH
+0x88A6 0xB2F0 #HANGUL SYLLABLE TIKEUT A RIEULSIOS
+0x88A7 0xB2F1 #HANGUL SYLLABLE TIKEUT A RIEULTHIEUTH
+0x88A8 0xB2F2 #HANGUL SYLLABLE TIKEUT A RIEULPHIEUPH
+0x88A9 0xB2F6 #HANGUL SYLLABLE TIKEUT A PIEUPSIOS
+0x88AA 0xB2FC #HANGUL SYLLABLE TIKEUT A KHIEUKH
+0x88AB 0xB2FD #HANGUL SYLLABLE TIKEUT A THIEUTH
+0x88AC 0xB2FE #HANGUL SYLLABLE TIKEUT A PHIEUPH
+0x88AD 0xB302 #HANGUL SYLLABLE TIKEUT AE SSANGKIYEOK
+0x88AE 0xB303 #HANGUL SYLLABLE TIKEUT AE KIYEOKSIOS
+0x88AF 0xB305 #HANGUL SYLLABLE TIKEUT AE NIEUNCIEUC
+0x88B0 0xB306 #HANGUL SYLLABLE TIKEUT AE NIEUNHIEUH
+0x88B1 0xB307 #HANGUL SYLLABLE TIKEUT AE TIKEUT
+0x88B2 0xB309 #HANGUL SYLLABLE TIKEUT AE RIEULKIYEOK
+0x88B3 0xB30A #HANGUL SYLLABLE TIKEUT AE RIEULMIEUM
+0x88B4 0xB30B #HANGUL SYLLABLE TIKEUT AE RIEULPIEUP
+0x88B5 0xB30C #HANGUL SYLLABLE TIKEUT AE RIEULSIOS
+0x88B6 0xB30D #HANGUL SYLLABLE TIKEUT AE RIEULTHIEUTH
+0x88B7 0xB30E #HANGUL SYLLABLE TIKEUT AE RIEULPHIEUPH
+0x88B8 0xB30F #HANGUL SYLLABLE TIKEUT AE RIEULHIEUH
+0x88B9 0xB312 #HANGUL SYLLABLE TIKEUT AE PIEUPSIOS
+0x88BA 0xB316 #HANGUL SYLLABLE TIKEUT AE CIEUC
+0x88BB 0xB317 #HANGUL SYLLABLE TIKEUT AE CHIEUCH
+0x88BC 0xB318 #HANGUL SYLLABLE TIKEUT AE KHIEUKH
+0x88BD 0xB319 #HANGUL SYLLABLE TIKEUT AE THIEUTH
+0x88BE 0xB31A #HANGUL SYLLABLE TIKEUT AE PHIEUPH
+0x88BF 0xB31B #HANGUL SYLLABLE TIKEUT AE HIEUH
+0x88C0 0xB31D #HANGUL SYLLABLE TIKEUT YA KIYEOK
+0x88C1 0xB31E #HANGUL SYLLABLE TIKEUT YA SSANGKIYEOK
+0x88C2 0xB31F #HANGUL SYLLABLE TIKEUT YA KIYEOKSIOS
+0x88C3 0xB320 #HANGUL SYLLABLE TIKEUT YA NIEUN
+0x88C4 0xB321 #HANGUL SYLLABLE TIKEUT YA NIEUNCIEUC
+0x88C5 0xB322 #HANGUL SYLLABLE TIKEUT YA NIEUNHIEUH
+0x88C6 0xB323 #HANGUL SYLLABLE TIKEUT YA TIKEUT
+0x88C7 0xB324 #HANGUL SYLLABLE TIKEUT YA RIEUL
+0x88C8 0xB325 #HANGUL SYLLABLE TIKEUT YA RIEULKIYEOK
+0x88C9 0xB326 #HANGUL SYLLABLE TIKEUT YA RIEULMIEUM
+0x88CA 0xB327 #HANGUL SYLLABLE TIKEUT YA RIEULPIEUP
+0x88CB 0xB328 #HANGUL SYLLABLE TIKEUT YA RIEULSIOS
+0x88CC 0xB329 #HANGUL SYLLABLE TIKEUT YA RIEULTHIEUTH
+0x88CD 0xB32A #HANGUL SYLLABLE TIKEUT YA RIEULPHIEUPH
+0x88CE 0xB32B #HANGUL SYLLABLE TIKEUT YA RIEULHIEUH
+0x88CF 0xB32C #HANGUL SYLLABLE TIKEUT YA MIEUM
+0x88D0 0xB32D #HANGUL SYLLABLE TIKEUT YA PIEUP
+0x88D1 0xB32E #HANGUL SYLLABLE TIKEUT YA PIEUPSIOS
+0x88D2 0xB32F #HANGUL SYLLABLE TIKEUT YA SIOS
+0x88D3 0xB330 #HANGUL SYLLABLE TIKEUT YA SSANGSIOS
+0x88D4 0xB331 #HANGUL SYLLABLE TIKEUT YA IEUNG
+0x88D5 0xB332 #HANGUL SYLLABLE TIKEUT YA CIEUC
+0x88D6 0xB333 #HANGUL SYLLABLE TIKEUT YA CHIEUCH
+0x88D7 0xB334 #HANGUL SYLLABLE TIKEUT YA KHIEUKH
+0x88D8 0xB335 #HANGUL SYLLABLE TIKEUT YA THIEUTH
+0x88D9 0xB336 #HANGUL SYLLABLE TIKEUT YA PHIEUPH
+0x88DA 0xB337 #HANGUL SYLLABLE TIKEUT YA HIEUH
+0x88DB 0xB338 #HANGUL SYLLABLE TIKEUT YAE
+0x88DC 0xB339 #HANGUL SYLLABLE TIKEUT YAE KIYEOK
+0x88DD 0xB33A #HANGUL SYLLABLE TIKEUT YAE SSANGKIYEOK
+0x88DE 0xB33B #HANGUL SYLLABLE TIKEUT YAE KIYEOKSIOS
+0x88DF 0xB33C #HANGUL SYLLABLE TIKEUT YAE NIEUN
+0x88E0 0xB33D #HANGUL SYLLABLE TIKEUT YAE NIEUNCIEUC
+0x88E1 0xB33E #HANGUL SYLLABLE TIKEUT YAE NIEUNHIEUH
+0x88E2 0xB33F #HANGUL SYLLABLE TIKEUT YAE TIKEUT
+0x88E3 0xB340 #HANGUL SYLLABLE TIKEUT YAE RIEUL
+0x88E4 0xB341 #HANGUL SYLLABLE TIKEUT YAE RIEULKIYEOK
+0x88E5 0xB342 #HANGUL SYLLABLE TIKEUT YAE RIEULMIEUM
+0x88E6 0xB343 #HANGUL SYLLABLE TIKEUT YAE RIEULPIEUP
+0x88E7 0xB344 #HANGUL SYLLABLE TIKEUT YAE RIEULSIOS
+0x88E8 0xB345 #HANGUL SYLLABLE TIKEUT YAE RIEULTHIEUTH
+0x88E9 0xB346 #HANGUL SYLLABLE TIKEUT YAE RIEULPHIEUPH
+0x88EA 0xB347 #HANGUL SYLLABLE TIKEUT YAE RIEULHIEUH
+0x88EB 0xB348 #HANGUL SYLLABLE TIKEUT YAE MIEUM
+0x88EC 0xB349 #HANGUL SYLLABLE TIKEUT YAE PIEUP
+0x88ED 0xB34A #HANGUL SYLLABLE TIKEUT YAE PIEUPSIOS
+0x88EE 0xB34B #HANGUL SYLLABLE TIKEUT YAE SIOS
+0x88EF 0xB34C #HANGUL SYLLABLE TIKEUT YAE SSANGSIOS
+0x88F0 0xB34D #HANGUL SYLLABLE TIKEUT YAE IEUNG
+0x88F1 0xB34E #HANGUL SYLLABLE TIKEUT YAE CIEUC
+0x88F2 0xB34F #HANGUL SYLLABLE TIKEUT YAE CHIEUCH
+0x88F3 0xB350 #HANGUL SYLLABLE TIKEUT YAE KHIEUKH
+0x88F4 0xB351 #HANGUL SYLLABLE TIKEUT YAE THIEUTH
+0x88F5 0xB352 #HANGUL SYLLABLE TIKEUT YAE PHIEUPH
+0x88F6 0xB353 #HANGUL SYLLABLE TIKEUT YAE HIEUH
+0x88F7 0xB357 #HANGUL SYLLABLE TIKEUT EO KIYEOKSIOS
+0x88F8 0xB359 #HANGUL SYLLABLE TIKEUT EO NIEUNCIEUC
+0x88F9 0xB35A #HANGUL SYLLABLE TIKEUT EO NIEUNHIEUH
+0x88FA 0xB35D #HANGUL SYLLABLE TIKEUT EO RIEULKIYEOK
+0x88FB 0xB360 #HANGUL SYLLABLE TIKEUT EO RIEULSIOS
+0x88FC 0xB361 #HANGUL SYLLABLE TIKEUT EO RIEULTHIEUTH
+0x88FD 0xB362 #HANGUL SYLLABLE TIKEUT EO RIEULPHIEUPH
+0x88FE 0xB363 #HANGUL SYLLABLE TIKEUT EO RIEULHIEUH
+0x8941 0xB366 #HANGUL SYLLABLE TIKEUT EO PIEUPSIOS
+0x8942 0xB368 #HANGUL SYLLABLE TIKEUT EO SSANGSIOS
+0x8943 0xB36A #HANGUL SYLLABLE TIKEUT EO CIEUC
+0x8944 0xB36C #HANGUL SYLLABLE TIKEUT EO KHIEUKH
+0x8945 0xB36D #HANGUL SYLLABLE TIKEUT EO THIEUTH
+0x8946 0xB36F #HANGUL SYLLABLE TIKEUT EO HIEUH
+0x8947 0xB372 #HANGUL SYLLABLE TIKEUT E SSANGKIYEOK
+0x8948 0xB373 #HANGUL SYLLABLE TIKEUT E KIYEOKSIOS
+0x8949 0xB375 #HANGUL SYLLABLE TIKEUT E NIEUNCIEUC
+0x894A 0xB376 #HANGUL SYLLABLE TIKEUT E NIEUNHIEUH
+0x894B 0xB377 #HANGUL SYLLABLE TIKEUT E TIKEUT
+0x894C 0xB379 #HANGUL SYLLABLE TIKEUT E RIEULKIYEOK
+0x894D 0xB37A #HANGUL SYLLABLE TIKEUT E RIEULMIEUM
+0x894E 0xB37B #HANGUL SYLLABLE TIKEUT E RIEULPIEUP
+0x894F 0xB37C #HANGUL SYLLABLE TIKEUT E RIEULSIOS
+0x8950 0xB37D #HANGUL SYLLABLE TIKEUT E RIEULTHIEUTH
+0x8951 0xB37E #HANGUL SYLLABLE TIKEUT E RIEULPHIEUPH
+0x8952 0xB37F #HANGUL SYLLABLE TIKEUT E RIEULHIEUH
+0x8953 0xB382 #HANGUL SYLLABLE TIKEUT E PIEUPSIOS
+0x8954 0xB386 #HANGUL SYLLABLE TIKEUT E CIEUC
+0x8955 0xB387 #HANGUL SYLLABLE TIKEUT E CHIEUCH
+0x8956 0xB388 #HANGUL SYLLABLE TIKEUT E KHIEUKH
+0x8957 0xB389 #HANGUL SYLLABLE TIKEUT E THIEUTH
+0x8958 0xB38A #HANGUL SYLLABLE TIKEUT E PHIEUPH
+0x8959 0xB38B #HANGUL SYLLABLE TIKEUT E HIEUH
+0x895A 0xB38D #HANGUL SYLLABLE TIKEUT YEO KIYEOK
+0x8961 0xB38E #HANGUL SYLLABLE TIKEUT YEO SSANGKIYEOK
+0x8962 0xB38F #HANGUL SYLLABLE TIKEUT YEO KIYEOKSIOS
+0x8963 0xB391 #HANGUL SYLLABLE TIKEUT YEO NIEUNCIEUC
+0x8964 0xB392 #HANGUL SYLLABLE TIKEUT YEO NIEUNHIEUH
+0x8965 0xB393 #HANGUL SYLLABLE TIKEUT YEO TIKEUT
+0x8966 0xB395 #HANGUL SYLLABLE TIKEUT YEO RIEULKIYEOK
+0x8967 0xB396 #HANGUL SYLLABLE TIKEUT YEO RIEULMIEUM
+0x8968 0xB397 #HANGUL SYLLABLE TIKEUT YEO RIEULPIEUP
+0x8969 0xB398 #HANGUL SYLLABLE TIKEUT YEO RIEULSIOS
+0x896A 0xB399 #HANGUL SYLLABLE TIKEUT YEO RIEULTHIEUTH
+0x896B 0xB39A #HANGUL SYLLABLE TIKEUT YEO RIEULPHIEUPH
+0x896C 0xB39B #HANGUL SYLLABLE TIKEUT YEO RIEULHIEUH
+0x896D 0xB39C #HANGUL SYLLABLE TIKEUT YEO MIEUM
+0x896E 0xB39D #HANGUL SYLLABLE TIKEUT YEO PIEUP
+0x896F 0xB39E #HANGUL SYLLABLE TIKEUT YEO PIEUPSIOS
+0x8970 0xB39F #HANGUL SYLLABLE TIKEUT YEO SIOS
+0x8971 0xB3A2 #HANGUL SYLLABLE TIKEUT YEO CIEUC
+0x8972 0xB3A3 #HANGUL SYLLABLE TIKEUT YEO CHIEUCH
+0x8973 0xB3A4 #HANGUL SYLLABLE TIKEUT YEO KHIEUKH
+0x8974 0xB3A5 #HANGUL SYLLABLE TIKEUT YEO THIEUTH
+0x8975 0xB3A6 #HANGUL SYLLABLE TIKEUT YEO PHIEUPH
+0x8976 0xB3A7 #HANGUL SYLLABLE TIKEUT YEO HIEUH
+0x8977 0xB3A9 #HANGUL SYLLABLE TIKEUT YE KIYEOK
+0x8978 0xB3AA #HANGUL SYLLABLE TIKEUT YE SSANGKIYEOK
+0x8979 0xB3AB #HANGUL SYLLABLE TIKEUT YE KIYEOKSIOS
+0x897A 0xB3AD #HANGUL SYLLABLE TIKEUT YE NIEUNCIEUC
+0x8981 0xB3AE #HANGUL SYLLABLE TIKEUT YE NIEUNHIEUH
+0x8982 0xB3AF #HANGUL SYLLABLE TIKEUT YE TIKEUT
+0x8983 0xB3B0 #HANGUL SYLLABLE TIKEUT YE RIEUL
+0x8984 0xB3B1 #HANGUL SYLLABLE TIKEUT YE RIEULKIYEOK
+0x8985 0xB3B2 #HANGUL SYLLABLE TIKEUT YE RIEULMIEUM
+0x8986 0xB3B3 #HANGUL SYLLABLE TIKEUT YE RIEULPIEUP
+0x8987 0xB3B4 #HANGUL SYLLABLE TIKEUT YE RIEULSIOS
+0x8988 0xB3B5 #HANGUL SYLLABLE TIKEUT YE RIEULTHIEUTH
+0x8989 0xB3B6 #HANGUL SYLLABLE TIKEUT YE RIEULPHIEUPH
+0x898A 0xB3B7 #HANGUL SYLLABLE TIKEUT YE RIEULHIEUH
+0x898B 0xB3B8 #HANGUL SYLLABLE TIKEUT YE MIEUM
+0x898C 0xB3B9 #HANGUL SYLLABLE TIKEUT YE PIEUP
+0x898D 0xB3BA #HANGUL SYLLABLE TIKEUT YE PIEUPSIOS
+0x898E 0xB3BB #HANGUL SYLLABLE TIKEUT YE SIOS
+0x898F 0xB3BC #HANGUL SYLLABLE TIKEUT YE SSANGSIOS
+0x8990 0xB3BD #HANGUL SYLLABLE TIKEUT YE IEUNG
+0x8991 0xB3BE #HANGUL SYLLABLE TIKEUT YE CIEUC
+0x8992 0xB3BF #HANGUL SYLLABLE TIKEUT YE CHIEUCH
+0x8993 0xB3C0 #HANGUL SYLLABLE TIKEUT YE KHIEUKH
+0x8994 0xB3C1 #HANGUL SYLLABLE TIKEUT YE THIEUTH
+0x8995 0xB3C2 #HANGUL SYLLABLE TIKEUT YE PHIEUPH
+0x8996 0xB3C3 #HANGUL SYLLABLE TIKEUT YE HIEUH
+0x8997 0xB3C6 #HANGUL SYLLABLE TIKEUT O SSANGKIYEOK
+0x8998 0xB3C7 #HANGUL SYLLABLE TIKEUT O KIYEOKSIOS
+0x8999 0xB3C9 #HANGUL SYLLABLE TIKEUT O NIEUNCIEUC
+0x899A 0xB3CA #HANGUL SYLLABLE TIKEUT O NIEUNHIEUH
+0x899B 0xB3CD #HANGUL SYLLABLE TIKEUT O RIEULKIYEOK
+0x899C 0xB3CF #HANGUL SYLLABLE TIKEUT O RIEULPIEUP
+0x899D 0xB3D1 #HANGUL SYLLABLE TIKEUT O RIEULTHIEUTH
+0x899E 0xB3D2 #HANGUL SYLLABLE TIKEUT O RIEULPHIEUPH
+0x899F 0xB3D3 #HANGUL SYLLABLE TIKEUT O RIEULHIEUH
+0x89A0 0xB3D6 #HANGUL SYLLABLE TIKEUT O PIEUPSIOS
+0x89A1 0xB3D8 #HANGUL SYLLABLE TIKEUT O SSANGSIOS
+0x89A2 0xB3DA #HANGUL SYLLABLE TIKEUT O CIEUC
+0x89A3 0xB3DC #HANGUL SYLLABLE TIKEUT O KHIEUKH
+0x89A4 0xB3DE #HANGUL SYLLABLE TIKEUT O PHIEUPH
+0x89A5 0xB3DF #HANGUL SYLLABLE TIKEUT O HIEUH
+0x89A6 0xB3E1 #HANGUL SYLLABLE TIKEUT WA KIYEOK
+0x89A7 0xB3E2 #HANGUL SYLLABLE TIKEUT WA SSANGKIYEOK
+0x89A8 0xB3E3 #HANGUL SYLLABLE TIKEUT WA KIYEOKSIOS
+0x89A9 0xB3E5 #HANGUL SYLLABLE TIKEUT WA NIEUNCIEUC
+0x89AA 0xB3E6 #HANGUL SYLLABLE TIKEUT WA NIEUNHIEUH
+0x89AB 0xB3E7 #HANGUL SYLLABLE TIKEUT WA TIKEUT
+0x89AC 0xB3E9 #HANGUL SYLLABLE TIKEUT WA RIEULKIYEOK
+0x89AD 0xB3EA #HANGUL SYLLABLE TIKEUT WA RIEULMIEUM
+0x89AE 0xB3EB #HANGUL SYLLABLE TIKEUT WA RIEULPIEUP
+0x89AF 0xB3EC #HANGUL SYLLABLE TIKEUT WA RIEULSIOS
+0x89B0 0xB3ED #HANGUL SYLLABLE TIKEUT WA RIEULTHIEUTH
+0x89B1 0xB3EE #HANGUL SYLLABLE TIKEUT WA RIEULPHIEUPH
+0x89B2 0xB3EF #HANGUL SYLLABLE TIKEUT WA RIEULHIEUH
+0x89B3 0xB3F0 #HANGUL SYLLABLE TIKEUT WA MIEUM
+0x89B4 0xB3F1 #HANGUL SYLLABLE TIKEUT WA PIEUP
+0x89B5 0xB3F2 #HANGUL SYLLABLE TIKEUT WA PIEUPSIOS
+0x89B6 0xB3F3 #HANGUL SYLLABLE TIKEUT WA SIOS
+0x89B7 0xB3F4 #HANGUL SYLLABLE TIKEUT WA SSANGSIOS
+0x89B8 0xB3F5 #HANGUL SYLLABLE TIKEUT WA IEUNG
+0x89B9 0xB3F6 #HANGUL SYLLABLE TIKEUT WA CIEUC
+0x89BA 0xB3F7 #HANGUL SYLLABLE TIKEUT WA CHIEUCH
+0x89BB 0xB3F8 #HANGUL SYLLABLE TIKEUT WA KHIEUKH
+0x89BC 0xB3F9 #HANGUL SYLLABLE TIKEUT WA THIEUTH
+0x89BD 0xB3FA #HANGUL SYLLABLE TIKEUT WA PHIEUPH
+0x89BE 0xB3FB #HANGUL SYLLABLE TIKEUT WA HIEUH
+0x89BF 0xB3FD #HANGUL SYLLABLE TIKEUT WAE KIYEOK
+0x89C0 0xB3FE #HANGUL SYLLABLE TIKEUT WAE SSANGKIYEOK
+0x89C1 0xB3FF #HANGUL SYLLABLE TIKEUT WAE KIYEOKSIOS
+0x89C2 0xB400 #HANGUL SYLLABLE TIKEUT WAE NIEUN
+0x89C3 0xB401 #HANGUL SYLLABLE TIKEUT WAE NIEUNCIEUC
+0x89C4 0xB402 #HANGUL SYLLABLE TIKEUT WAE NIEUNHIEUH
+0x89C5 0xB403 #HANGUL SYLLABLE TIKEUT WAE TIKEUT
+0x89C6 0xB404 #HANGUL SYLLABLE TIKEUT WAE RIEUL
+0x89C7 0xB405 #HANGUL SYLLABLE TIKEUT WAE RIEULKIYEOK
+0x89C8 0xB406 #HANGUL SYLLABLE TIKEUT WAE RIEULMIEUM
+0x89C9 0xB407 #HANGUL SYLLABLE TIKEUT WAE RIEULPIEUP
+0x89CA 0xB408 #HANGUL SYLLABLE TIKEUT WAE RIEULSIOS
+0x89CB 0xB409 #HANGUL SYLLABLE TIKEUT WAE RIEULTHIEUTH
+0x89CC 0xB40A #HANGUL SYLLABLE TIKEUT WAE RIEULPHIEUPH
+0x89CD 0xB40B #HANGUL SYLLABLE TIKEUT WAE RIEULHIEUH
+0x89CE 0xB40C #HANGUL SYLLABLE TIKEUT WAE MIEUM
+0x89CF 0xB40D #HANGUL SYLLABLE TIKEUT WAE PIEUP
+0x89D0 0xB40E #HANGUL SYLLABLE TIKEUT WAE PIEUPSIOS
+0x89D1 0xB40F #HANGUL SYLLABLE TIKEUT WAE SIOS
+0x89D2 0xB411 #HANGUL SYLLABLE TIKEUT WAE IEUNG
+0x89D3 0xB412 #HANGUL SYLLABLE TIKEUT WAE CIEUC
+0x89D4 0xB413 #HANGUL SYLLABLE TIKEUT WAE CHIEUCH
+0x89D5 0xB414 #HANGUL SYLLABLE TIKEUT WAE KHIEUKH
+0x89D6 0xB415 #HANGUL SYLLABLE TIKEUT WAE THIEUTH
+0x89D7 0xB416 #HANGUL SYLLABLE TIKEUT WAE PHIEUPH
+0x89D8 0xB417 #HANGUL SYLLABLE TIKEUT WAE HIEUH
+0x89D9 0xB419 #HANGUL SYLLABLE TIKEUT OE KIYEOK
+0x89DA 0xB41A #HANGUL SYLLABLE TIKEUT OE SSANGKIYEOK
+0x89DB 0xB41B #HANGUL SYLLABLE TIKEUT OE KIYEOKSIOS
+0x89DC 0xB41D #HANGUL SYLLABLE TIKEUT OE NIEUNCIEUC
+0x89DD 0xB41E #HANGUL SYLLABLE TIKEUT OE NIEUNHIEUH
+0x89DE 0xB41F #HANGUL SYLLABLE TIKEUT OE TIKEUT
+0x89DF 0xB421 #HANGUL SYLLABLE TIKEUT OE RIEULKIYEOK
+0x89E0 0xB422 #HANGUL SYLLABLE TIKEUT OE RIEULMIEUM
+0x89E1 0xB423 #HANGUL SYLLABLE TIKEUT OE RIEULPIEUP
+0x89E2 0xB424 #HANGUL SYLLABLE TIKEUT OE RIEULSIOS
+0x89E3 0xB425 #HANGUL SYLLABLE TIKEUT OE RIEULTHIEUTH
+0x89E4 0xB426 #HANGUL SYLLABLE TIKEUT OE RIEULPHIEUPH
+0x89E5 0xB427 #HANGUL SYLLABLE TIKEUT OE RIEULHIEUH
+0x89E6 0xB42A #HANGUL SYLLABLE TIKEUT OE PIEUPSIOS
+0x89E7 0xB42C #HANGUL SYLLABLE TIKEUT OE SSANGSIOS
+0x89E8 0xB42D #HANGUL SYLLABLE TIKEUT OE IEUNG
+0x89E9 0xB42E #HANGUL SYLLABLE TIKEUT OE CIEUC
+0x89EA 0xB42F #HANGUL SYLLABLE TIKEUT OE CHIEUCH
+0x89EB 0xB430 #HANGUL SYLLABLE TIKEUT OE KHIEUKH
+0x89EC 0xB431 #HANGUL SYLLABLE TIKEUT OE THIEUTH
+0x89ED 0xB432 #HANGUL SYLLABLE TIKEUT OE PHIEUPH
+0x89EE 0xB433 #HANGUL SYLLABLE TIKEUT OE HIEUH
+0x89EF 0xB435 #HANGUL SYLLABLE TIKEUT YO KIYEOK
+0x89F0 0xB436 #HANGUL SYLLABLE TIKEUT YO SSANGKIYEOK
+0x89F1 0xB437 #HANGUL SYLLABLE TIKEUT YO KIYEOKSIOS
+0x89F2 0xB438 #HANGUL SYLLABLE TIKEUT YO NIEUN
+0x89F3 0xB439 #HANGUL SYLLABLE TIKEUT YO NIEUNCIEUC
+0x89F4 0xB43A #HANGUL SYLLABLE TIKEUT YO NIEUNHIEUH
+0x89F5 0xB43B #HANGUL SYLLABLE TIKEUT YO TIKEUT
+0x89F6 0xB43C #HANGUL SYLLABLE TIKEUT YO RIEUL
+0x89F7 0xB43D #HANGUL SYLLABLE TIKEUT YO RIEULKIYEOK
+0x89F8 0xB43E #HANGUL SYLLABLE TIKEUT YO RIEULMIEUM
+0x89F9 0xB43F #HANGUL SYLLABLE TIKEUT YO RIEULPIEUP
+0x89FA 0xB440 #HANGUL SYLLABLE TIKEUT YO RIEULSIOS
+0x89FB 0xB441 #HANGUL SYLLABLE TIKEUT YO RIEULTHIEUTH
+0x89FC 0xB442 #HANGUL SYLLABLE TIKEUT YO RIEULPHIEUPH
+0x89FD 0xB443 #HANGUL SYLLABLE TIKEUT YO RIEULHIEUH
+0x89FE 0xB444 #HANGUL SYLLABLE TIKEUT YO MIEUM
+0x8A41 0xB445 #HANGUL SYLLABLE TIKEUT YO PIEUP
+0x8A42 0xB446 #HANGUL SYLLABLE TIKEUT YO PIEUPSIOS
+0x8A43 0xB447 #HANGUL SYLLABLE TIKEUT YO SIOS
+0x8A44 0xB448 #HANGUL SYLLABLE TIKEUT YO SSANGSIOS
+0x8A45 0xB449 #HANGUL SYLLABLE TIKEUT YO IEUNG
+0x8A46 0xB44A #HANGUL SYLLABLE TIKEUT YO CIEUC
+0x8A47 0xB44B #HANGUL SYLLABLE TIKEUT YO CHIEUCH
+0x8A48 0xB44C #HANGUL SYLLABLE TIKEUT YO KHIEUKH
+0x8A49 0xB44D #HANGUL SYLLABLE TIKEUT YO THIEUTH
+0x8A4A 0xB44E #HANGUL SYLLABLE TIKEUT YO PHIEUPH
+0x8A4B 0xB44F #HANGUL SYLLABLE TIKEUT YO HIEUH
+0x8A4C 0xB452 #HANGUL SYLLABLE TIKEUT U SSANGKIYEOK
+0x8A4D 0xB453 #HANGUL SYLLABLE TIKEUT U KIYEOKSIOS
+0x8A4E 0xB455 #HANGUL SYLLABLE TIKEUT U NIEUNCIEUC
+0x8A4F 0xB456 #HANGUL SYLLABLE TIKEUT U NIEUNHIEUH
+0x8A50 0xB457 #HANGUL SYLLABLE TIKEUT U TIKEUT
+0x8A51 0xB459 #HANGUL SYLLABLE TIKEUT U RIEULKIYEOK
+0x8A52 0xB45A #HANGUL SYLLABLE TIKEUT U RIEULMIEUM
+0x8A53 0xB45B #HANGUL SYLLABLE TIKEUT U RIEULPIEUP
+0x8A54 0xB45C #HANGUL SYLLABLE TIKEUT U RIEULSIOS
+0x8A55 0xB45D #HANGUL SYLLABLE TIKEUT U RIEULTHIEUTH
+0x8A56 0xB45E #HANGUL SYLLABLE TIKEUT U RIEULPHIEUPH
+0x8A57 0xB45F #HANGUL SYLLABLE TIKEUT U RIEULHIEUH
+0x8A58 0xB462 #HANGUL SYLLABLE TIKEUT U PIEUPSIOS
+0x8A59 0xB464 #HANGUL SYLLABLE TIKEUT U SSANGSIOS
+0x8A5A 0xB466 #HANGUL SYLLABLE TIKEUT U CIEUC
+0x8A61 0xB467 #HANGUL SYLLABLE TIKEUT U CHIEUCH
+0x8A62 0xB468 #HANGUL SYLLABLE TIKEUT U KHIEUKH
+0x8A63 0xB469 #HANGUL SYLLABLE TIKEUT U THIEUTH
+0x8A64 0xB46A #HANGUL SYLLABLE TIKEUT U PHIEUPH
+0x8A65 0xB46B #HANGUL SYLLABLE TIKEUT U HIEUH
+0x8A66 0xB46D #HANGUL SYLLABLE TIKEUT WEO KIYEOK
+0x8A67 0xB46E #HANGUL SYLLABLE TIKEUT WEO SSANGKIYEOK
+0x8A68 0xB46F #HANGUL SYLLABLE TIKEUT WEO KIYEOKSIOS
+0x8A69 0xB470 #HANGUL SYLLABLE TIKEUT WEO NIEUN
+0x8A6A 0xB471 #HANGUL SYLLABLE TIKEUT WEO NIEUNCIEUC
+0x8A6B 0xB472 #HANGUL SYLLABLE TIKEUT WEO NIEUNHIEUH
+0x8A6C 0xB473 #HANGUL SYLLABLE TIKEUT WEO TIKEUT
+0x8A6D 0xB474 #HANGUL SYLLABLE TIKEUT WEO RIEUL
+0x8A6E 0xB475 #HANGUL SYLLABLE TIKEUT WEO RIEULKIYEOK
+0x8A6F 0xB476 #HANGUL SYLLABLE TIKEUT WEO RIEULMIEUM
+0x8A70 0xB477 #HANGUL SYLLABLE TIKEUT WEO RIEULPIEUP
+0x8A71 0xB478 #HANGUL SYLLABLE TIKEUT WEO RIEULSIOS
+0x8A72 0xB479 #HANGUL SYLLABLE TIKEUT WEO RIEULTHIEUTH
+0x8A73 0xB47A #HANGUL SYLLABLE TIKEUT WEO RIEULPHIEUPH
+0x8A74 0xB47B #HANGUL SYLLABLE TIKEUT WEO RIEULHIEUH
+0x8A75 0xB47C #HANGUL SYLLABLE TIKEUT WEO MIEUM
+0x8A76 0xB47D #HANGUL SYLLABLE TIKEUT WEO PIEUP
+0x8A77 0xB47E #HANGUL SYLLABLE TIKEUT WEO PIEUPSIOS
+0x8A78 0xB47F #HANGUL SYLLABLE TIKEUT WEO SIOS
+0x8A79 0xB481 #HANGUL SYLLABLE TIKEUT WEO IEUNG
+0x8A7A 0xB482 #HANGUL SYLLABLE TIKEUT WEO CIEUC
+0x8A81 0xB483 #HANGUL SYLLABLE TIKEUT WEO CHIEUCH
+0x8A82 0xB484 #HANGUL SYLLABLE TIKEUT WEO KHIEUKH
+0x8A83 0xB485 #HANGUL SYLLABLE TIKEUT WEO THIEUTH
+0x8A84 0xB486 #HANGUL SYLLABLE TIKEUT WEO PHIEUPH
+0x8A85 0xB487 #HANGUL SYLLABLE TIKEUT WEO HIEUH
+0x8A86 0xB489 #HANGUL SYLLABLE TIKEUT WE KIYEOK
+0x8A87 0xB48A #HANGUL SYLLABLE TIKEUT WE SSANGKIYEOK
+0x8A88 0xB48B #HANGUL SYLLABLE TIKEUT WE KIYEOKSIOS
+0x8A89 0xB48C #HANGUL SYLLABLE TIKEUT WE NIEUN
+0x8A8A 0xB48D #HANGUL SYLLABLE TIKEUT WE NIEUNCIEUC
+0x8A8B 0xB48E #HANGUL SYLLABLE TIKEUT WE NIEUNHIEUH
+0x8A8C 0xB48F #HANGUL SYLLABLE TIKEUT WE TIKEUT
+0x8A8D 0xB490 #HANGUL SYLLABLE TIKEUT WE RIEUL
+0x8A8E 0xB491 #HANGUL SYLLABLE TIKEUT WE RIEULKIYEOK
+0x8A8F 0xB492 #HANGUL SYLLABLE TIKEUT WE RIEULMIEUM
+0x8A90 0xB493 #HANGUL SYLLABLE TIKEUT WE RIEULPIEUP
+0x8A91 0xB494 #HANGUL SYLLABLE TIKEUT WE RIEULSIOS
+0x8A92 0xB495 #HANGUL SYLLABLE TIKEUT WE RIEULTHIEUTH
+0x8A93 0xB496 #HANGUL SYLLABLE TIKEUT WE RIEULPHIEUPH
+0x8A94 0xB497 #HANGUL SYLLABLE TIKEUT WE RIEULHIEUH
+0x8A95 0xB498 #HANGUL SYLLABLE TIKEUT WE MIEUM
+0x8A96 0xB499 #HANGUL SYLLABLE TIKEUT WE PIEUP
+0x8A97 0xB49A #HANGUL SYLLABLE TIKEUT WE PIEUPSIOS
+0x8A98 0xB49B #HANGUL SYLLABLE TIKEUT WE SIOS
+0x8A99 0xB49C #HANGUL SYLLABLE TIKEUT WE SSANGSIOS
+0x8A9A 0xB49E #HANGUL SYLLABLE TIKEUT WE CIEUC
+0x8A9B 0xB49F #HANGUL SYLLABLE TIKEUT WE CHIEUCH
+0x8A9C 0xB4A0 #HANGUL SYLLABLE TIKEUT WE KHIEUKH
+0x8A9D 0xB4A1 #HANGUL SYLLABLE TIKEUT WE THIEUTH
+0x8A9E 0xB4A2 #HANGUL SYLLABLE TIKEUT WE PHIEUPH
+0x8A9F 0xB4A3 #HANGUL SYLLABLE TIKEUT WE HIEUH
+0x8AA0 0xB4A5 #HANGUL SYLLABLE TIKEUT WI KIYEOK
+0x8AA1 0xB4A6 #HANGUL SYLLABLE TIKEUT WI SSANGKIYEOK
+0x8AA2 0xB4A7 #HANGUL SYLLABLE TIKEUT WI KIYEOKSIOS
+0x8AA3 0xB4A9 #HANGUL SYLLABLE TIKEUT WI NIEUNCIEUC
+0x8AA4 0xB4AA #HANGUL SYLLABLE TIKEUT WI NIEUNHIEUH
+0x8AA5 0xB4AB #HANGUL SYLLABLE TIKEUT WI TIKEUT
+0x8AA6 0xB4AD #HANGUL SYLLABLE TIKEUT WI RIEULKIYEOK
+0x8AA7 0xB4AE #HANGUL SYLLABLE TIKEUT WI RIEULMIEUM
+0x8AA8 0xB4AF #HANGUL SYLLABLE TIKEUT WI RIEULPIEUP
+0x8AA9 0xB4B0 #HANGUL SYLLABLE TIKEUT WI RIEULSIOS
+0x8AAA 0xB4B1 #HANGUL SYLLABLE TIKEUT WI RIEULTHIEUTH
+0x8AAB 0xB4B2 #HANGUL SYLLABLE TIKEUT WI RIEULPHIEUPH
+0x8AAC 0xB4B3 #HANGUL SYLLABLE TIKEUT WI RIEULHIEUH
+0x8AAD 0xB4B4 #HANGUL SYLLABLE TIKEUT WI MIEUM
+0x8AAE 0xB4B6 #HANGUL SYLLABLE TIKEUT WI PIEUPSIOS
+0x8AAF 0xB4B8 #HANGUL SYLLABLE TIKEUT WI SSANGSIOS
+0x8AB0 0xB4BA #HANGUL SYLLABLE TIKEUT WI CIEUC
+0x8AB1 0xB4BB #HANGUL SYLLABLE TIKEUT WI CHIEUCH
+0x8AB2 0xB4BC #HANGUL SYLLABLE TIKEUT WI KHIEUKH
+0x8AB3 0xB4BD #HANGUL SYLLABLE TIKEUT WI THIEUTH
+0x8AB4 0xB4BE #HANGUL SYLLABLE TIKEUT WI PHIEUPH
+0x8AB5 0xB4BF #HANGUL SYLLABLE TIKEUT WI HIEUH
+0x8AB6 0xB4C1 #HANGUL SYLLABLE TIKEUT YU KIYEOK
+0x8AB7 0xB4C2 #HANGUL SYLLABLE TIKEUT YU SSANGKIYEOK
+0x8AB8 0xB4C3 #HANGUL SYLLABLE TIKEUT YU KIYEOKSIOS
+0x8AB9 0xB4C5 #HANGUL SYLLABLE TIKEUT YU NIEUNCIEUC
+0x8ABA 0xB4C6 #HANGUL SYLLABLE TIKEUT YU NIEUNHIEUH
+0x8ABB 0xB4C7 #HANGUL SYLLABLE TIKEUT YU TIKEUT
+0x8ABC 0xB4C9 #HANGUL SYLLABLE TIKEUT YU RIEULKIYEOK
+0x8ABD 0xB4CA #HANGUL SYLLABLE TIKEUT YU RIEULMIEUM
+0x8ABE 0xB4CB #HANGUL SYLLABLE TIKEUT YU RIEULPIEUP
+0x8ABF 0xB4CC #HANGUL SYLLABLE TIKEUT YU RIEULSIOS
+0x8AC0 0xB4CD #HANGUL SYLLABLE TIKEUT YU RIEULTHIEUTH
+0x8AC1 0xB4CE #HANGUL SYLLABLE TIKEUT YU RIEULPHIEUPH
+0x8AC2 0xB4CF #HANGUL SYLLABLE TIKEUT YU RIEULHIEUH
+0x8AC3 0xB4D1 #HANGUL SYLLABLE TIKEUT YU PIEUP
+0x8AC4 0xB4D2 #HANGUL SYLLABLE TIKEUT YU PIEUPSIOS
+0x8AC5 0xB4D3 #HANGUL SYLLABLE TIKEUT YU SIOS
+0x8AC6 0xB4D4 #HANGUL SYLLABLE TIKEUT YU SSANGSIOS
+0x8AC7 0xB4D6 #HANGUL SYLLABLE TIKEUT YU CIEUC
+0x8AC8 0xB4D7 #HANGUL SYLLABLE TIKEUT YU CHIEUCH
+0x8AC9 0xB4D8 #HANGUL SYLLABLE TIKEUT YU KHIEUKH
+0x8ACA 0xB4D9 #HANGUL SYLLABLE TIKEUT YU THIEUTH
+0x8ACB 0xB4DA #HANGUL SYLLABLE TIKEUT YU PHIEUPH
+0x8ACC 0xB4DB #HANGUL SYLLABLE TIKEUT YU HIEUH
+0x8ACD 0xB4DE #HANGUL SYLLABLE TIKEUT EU SSANGKIYEOK
+0x8ACE 0xB4DF #HANGUL SYLLABLE TIKEUT EU KIYEOKSIOS
+0x8ACF 0xB4E1 #HANGUL SYLLABLE TIKEUT EU NIEUNCIEUC
+0x8AD0 0xB4E2 #HANGUL SYLLABLE TIKEUT EU NIEUNHIEUH
+0x8AD1 0xB4E5 #HANGUL SYLLABLE TIKEUT EU RIEULKIYEOK
+0x8AD2 0xB4E7 #HANGUL SYLLABLE TIKEUT EU RIEULPIEUP
+0x8AD3 0xB4E8 #HANGUL SYLLABLE TIKEUT EU RIEULSIOS
+0x8AD4 0xB4E9 #HANGUL SYLLABLE TIKEUT EU RIEULTHIEUTH
+0x8AD5 0xB4EA #HANGUL SYLLABLE TIKEUT EU RIEULPHIEUPH
+0x8AD6 0xB4EB #HANGUL SYLLABLE TIKEUT EU RIEULHIEUH
+0x8AD7 0xB4EE #HANGUL SYLLABLE TIKEUT EU PIEUPSIOS
+0x8AD8 0xB4F0 #HANGUL SYLLABLE TIKEUT EU SSANGSIOS
+0x8AD9 0xB4F2 #HANGUL SYLLABLE TIKEUT EU CIEUC
+0x8ADA 0xB4F3 #HANGUL SYLLABLE TIKEUT EU CHIEUCH
+0x8ADB 0xB4F4 #HANGUL SYLLABLE TIKEUT EU KHIEUKH
+0x8ADC 0xB4F5 #HANGUL SYLLABLE TIKEUT EU THIEUTH
+0x8ADD 0xB4F6 #HANGUL SYLLABLE TIKEUT EU PHIEUPH
+0x8ADE 0xB4F7 #HANGUL SYLLABLE TIKEUT EU HIEUH
+0x8ADF 0xB4F9 #HANGUL SYLLABLE TIKEUT YI KIYEOK
+0x8AE0 0xB4FA #HANGUL SYLLABLE TIKEUT YI SSANGKIYEOK
+0x8AE1 0xB4FB #HANGUL SYLLABLE TIKEUT YI KIYEOKSIOS
+0x8AE2 0xB4FC #HANGUL SYLLABLE TIKEUT YI NIEUN
+0x8AE3 0xB4FD #HANGUL SYLLABLE TIKEUT YI NIEUNCIEUC
+0x8AE4 0xB4FE #HANGUL SYLLABLE TIKEUT YI NIEUNHIEUH
+0x8AE5 0xB4FF #HANGUL SYLLABLE TIKEUT YI TIKEUT
+0x8AE6 0xB500 #HANGUL SYLLABLE TIKEUT YI RIEUL
+0x8AE7 0xB501 #HANGUL SYLLABLE TIKEUT YI RIEULKIYEOK
+0x8AE8 0xB502 #HANGUL SYLLABLE TIKEUT YI RIEULMIEUM
+0x8AE9 0xB503 #HANGUL SYLLABLE TIKEUT YI RIEULPIEUP
+0x8AEA 0xB504 #HANGUL SYLLABLE TIKEUT YI RIEULSIOS
+0x8AEB 0xB505 #HANGUL SYLLABLE TIKEUT YI RIEULTHIEUTH
+0x8AEC 0xB506 #HANGUL SYLLABLE TIKEUT YI RIEULPHIEUPH
+0x8AED 0xB507 #HANGUL SYLLABLE TIKEUT YI RIEULHIEUH
+0x8AEE 0xB508 #HANGUL SYLLABLE TIKEUT YI MIEUM
+0x8AEF 0xB509 #HANGUL SYLLABLE TIKEUT YI PIEUP
+0x8AF0 0xB50A #HANGUL SYLLABLE TIKEUT YI PIEUPSIOS
+0x8AF1 0xB50B #HANGUL SYLLABLE TIKEUT YI SIOS
+0x8AF2 0xB50C #HANGUL SYLLABLE TIKEUT YI SSANGSIOS
+0x8AF3 0xB50D #HANGUL SYLLABLE TIKEUT YI IEUNG
+0x8AF4 0xB50E #HANGUL SYLLABLE TIKEUT YI CIEUC
+0x8AF5 0xB50F #HANGUL SYLLABLE TIKEUT YI CHIEUCH
+0x8AF6 0xB510 #HANGUL SYLLABLE TIKEUT YI KHIEUKH
+0x8AF7 0xB511 #HANGUL SYLLABLE TIKEUT YI THIEUTH
+0x8AF8 0xB512 #HANGUL SYLLABLE TIKEUT YI PHIEUPH
+0x8AF9 0xB513 #HANGUL SYLLABLE TIKEUT YI HIEUH
+0x8AFA 0xB516 #HANGUL SYLLABLE TIKEUT I SSANGKIYEOK
+0x8AFB 0xB517 #HANGUL SYLLABLE TIKEUT I KIYEOKSIOS
+0x8AFC 0xB519 #HANGUL SYLLABLE TIKEUT I NIEUNCIEUC
+0x8AFD 0xB51A #HANGUL SYLLABLE TIKEUT I NIEUNHIEUH
+0x8AFE 0xB51D #HANGUL SYLLABLE TIKEUT I RIEULKIYEOK
+0x8B41 0xB51E #HANGUL SYLLABLE TIKEUT I RIEULMIEUM
+0x8B42 0xB51F #HANGUL SYLLABLE TIKEUT I RIEULPIEUP
+0x8B43 0xB520 #HANGUL SYLLABLE TIKEUT I RIEULSIOS
+0x8B44 0xB521 #HANGUL SYLLABLE TIKEUT I RIEULTHIEUTH
+0x8B45 0xB522 #HANGUL SYLLABLE TIKEUT I RIEULPHIEUPH
+0x8B46 0xB523 #HANGUL SYLLABLE TIKEUT I RIEULHIEUH
+0x8B47 0xB526 #HANGUL SYLLABLE TIKEUT I PIEUPSIOS
+0x8B48 0xB52B #HANGUL SYLLABLE TIKEUT I CHIEUCH
+0x8B49 0xB52C #HANGUL SYLLABLE TIKEUT I KHIEUKH
+0x8B4A 0xB52D #HANGUL SYLLABLE TIKEUT I THIEUTH
+0x8B4B 0xB52E #HANGUL SYLLABLE TIKEUT I PHIEUPH
+0x8B4C 0xB52F #HANGUL SYLLABLE TIKEUT I HIEUH
+0x8B4D 0xB532 #HANGUL SYLLABLE SSANGTIKEUT A SSANGKIYEOK
+0x8B4E 0xB533 #HANGUL SYLLABLE SSANGTIKEUT A KIYEOKSIOS
+0x8B4F 0xB535 #HANGUL SYLLABLE SSANGTIKEUT A NIEUNCIEUC
+0x8B50 0xB536 #HANGUL SYLLABLE SSANGTIKEUT A NIEUNHIEUH
+0x8B51 0xB537 #HANGUL SYLLABLE SSANGTIKEUT A TIKEUT
+0x8B52 0xB539 #HANGUL SYLLABLE SSANGTIKEUT A RIEULKIYEOK
+0x8B53 0xB53A #HANGUL SYLLABLE SSANGTIKEUT A RIEULMIEUM
+0x8B54 0xB53B #HANGUL SYLLABLE SSANGTIKEUT A RIEULPIEUP
+0x8B55 0xB53C #HANGUL SYLLABLE SSANGTIKEUT A RIEULSIOS
+0x8B56 0xB53D #HANGUL SYLLABLE SSANGTIKEUT A RIEULTHIEUTH
+0x8B57 0xB53E #HANGUL SYLLABLE SSANGTIKEUT A RIEULPHIEUPH
+0x8B58 0xB53F #HANGUL SYLLABLE SSANGTIKEUT A RIEULHIEUH
+0x8B59 0xB542 #HANGUL SYLLABLE SSANGTIKEUT A PIEUPSIOS
+0x8B5A 0xB546 #HANGUL SYLLABLE SSANGTIKEUT A CIEUC
+0x8B61 0xB547 #HANGUL SYLLABLE SSANGTIKEUT A CHIEUCH
+0x8B62 0xB548 #HANGUL SYLLABLE SSANGTIKEUT A KHIEUKH
+0x8B63 0xB549 #HANGUL SYLLABLE SSANGTIKEUT A THIEUTH
+0x8B64 0xB54A #HANGUL SYLLABLE SSANGTIKEUT A PHIEUPH
+0x8B65 0xB54E #HANGUL SYLLABLE SSANGTIKEUT AE SSANGKIYEOK
+0x8B66 0xB54F #HANGUL SYLLABLE SSANGTIKEUT AE KIYEOKSIOS
+0x8B67 0xB551 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUNCIEUC
+0x8B68 0xB552 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUNHIEUH
+0x8B69 0xB553 #HANGUL SYLLABLE SSANGTIKEUT AE TIKEUT
+0x8B6A 0xB555 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULKIYEOK
+0x8B6B 0xB556 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULMIEUM
+0x8B6C 0xB557 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULPIEUP
+0x8B6D 0xB558 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULSIOS
+0x8B6E 0xB559 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULTHIEUTH
+0x8B6F 0xB55A #HANGUL SYLLABLE SSANGTIKEUT AE RIEULPHIEUPH
+0x8B70 0xB55B #HANGUL SYLLABLE SSANGTIKEUT AE RIEULHIEUH
+0x8B71 0xB55E #HANGUL SYLLABLE SSANGTIKEUT AE PIEUPSIOS
+0x8B72 0xB562 #HANGUL SYLLABLE SSANGTIKEUT AE CIEUC
+0x8B73 0xB563 #HANGUL SYLLABLE SSANGTIKEUT AE CHIEUCH
+0x8B74 0xB564 #HANGUL SYLLABLE SSANGTIKEUT AE KHIEUKH
+0x8B75 0xB565 #HANGUL SYLLABLE SSANGTIKEUT AE THIEUTH
+0x8B76 0xB566 #HANGUL SYLLABLE SSANGTIKEUT AE PHIEUPH
+0x8B77 0xB567 #HANGUL SYLLABLE SSANGTIKEUT AE HIEUH
+0x8B78 0xB568 #HANGUL SYLLABLE SSANGTIKEUT YA
+0x8B79 0xB569 #HANGUL SYLLABLE SSANGTIKEUT YA KIYEOK
+0x8B7A 0xB56A #HANGUL SYLLABLE SSANGTIKEUT YA SSANGKIYEOK
+0x8B81 0xB56B #HANGUL SYLLABLE SSANGTIKEUT YA KIYEOKSIOS
+0x8B82 0xB56C #HANGUL SYLLABLE SSANGTIKEUT YA NIEUN
+0x8B83 0xB56D #HANGUL SYLLABLE SSANGTIKEUT YA NIEUNCIEUC
+0x8B84 0xB56E #HANGUL SYLLABLE SSANGTIKEUT YA NIEUNHIEUH
+0x8B85 0xB56F #HANGUL SYLLABLE SSANGTIKEUT YA TIKEUT
+0x8B86 0xB570 #HANGUL SYLLABLE SSANGTIKEUT YA RIEUL
+0x8B87 0xB571 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULKIYEOK
+0x8B88 0xB572 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULMIEUM
+0x8B89 0xB573 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULPIEUP
+0x8B8A 0xB574 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULSIOS
+0x8B8B 0xB575 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULTHIEUTH
+0x8B8C 0xB576 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULPHIEUPH
+0x8B8D 0xB577 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULHIEUH
+0x8B8E 0xB578 #HANGUL SYLLABLE SSANGTIKEUT YA MIEUM
+0x8B8F 0xB579 #HANGUL SYLLABLE SSANGTIKEUT YA PIEUP
+0x8B90 0xB57A #HANGUL SYLLABLE SSANGTIKEUT YA PIEUPSIOS
+0x8B91 0xB57B #HANGUL SYLLABLE SSANGTIKEUT YA SIOS
+0x8B92 0xB57C #HANGUL SYLLABLE SSANGTIKEUT YA SSANGSIOS
+0x8B93 0xB57D #HANGUL SYLLABLE SSANGTIKEUT YA IEUNG
+0x8B94 0xB57E #HANGUL SYLLABLE SSANGTIKEUT YA CIEUC
+0x8B95 0xB57F #HANGUL SYLLABLE SSANGTIKEUT YA CHIEUCH
+0x8B96 0xB580 #HANGUL SYLLABLE SSANGTIKEUT YA KHIEUKH
+0x8B97 0xB581 #HANGUL SYLLABLE SSANGTIKEUT YA THIEUTH
+0x8B98 0xB582 #HANGUL SYLLABLE SSANGTIKEUT YA PHIEUPH
+0x8B99 0xB583 #HANGUL SYLLABLE SSANGTIKEUT YA HIEUH
+0x8B9A 0xB584 #HANGUL SYLLABLE SSANGTIKEUT YAE
+0x8B9B 0xB585 #HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOK
+0x8B9C 0xB586 #HANGUL SYLLABLE SSANGTIKEUT YAE SSANGKIYEOK
+0x8B9D 0xB587 #HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOKSIOS
+0x8B9E 0xB588 #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUN
+0x8B9F 0xB589 #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNCIEUC
+0x8BA0 0xB58A #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNHIEUH
+0x8BA1 0xB58B #HANGUL SYLLABLE SSANGTIKEUT YAE TIKEUT
+0x8BA2 0xB58C #HANGUL SYLLABLE SSANGTIKEUT YAE RIEUL
+0x8BA3 0xB58D #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULKIYEOK
+0x8BA4 0xB58E #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULMIEUM
+0x8BA5 0xB58F #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPIEUP
+0x8BA6 0xB590 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULSIOS
+0x8BA7 0xB591 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULTHIEUTH
+0x8BA8 0xB592 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPHIEUPH
+0x8BA9 0xB593 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULHIEUH
+0x8BAA 0xB594 #HANGUL SYLLABLE SSANGTIKEUT YAE MIEUM
+0x8BAB 0xB595 #HANGUL SYLLABLE SSANGTIKEUT YAE PIEUP
+0x8BAC 0xB596 #HANGUL SYLLABLE SSANGTIKEUT YAE PIEUPSIOS
+0x8BAD 0xB597 #HANGUL SYLLABLE SSANGTIKEUT YAE SIOS
+0x8BAE 0xB598 #HANGUL SYLLABLE SSANGTIKEUT YAE SSANGSIOS
+0x8BAF 0xB599 #HANGUL SYLLABLE SSANGTIKEUT YAE IEUNG
+0x8BB0 0xB59A #HANGUL SYLLABLE SSANGTIKEUT YAE CIEUC
+0x8BB1 0xB59B #HANGUL SYLLABLE SSANGTIKEUT YAE CHIEUCH
+0x8BB2 0xB59C #HANGUL SYLLABLE SSANGTIKEUT YAE KHIEUKH
+0x8BB3 0xB59D #HANGUL SYLLABLE SSANGTIKEUT YAE THIEUTH
+0x8BB4 0xB59E #HANGUL SYLLABLE SSANGTIKEUT YAE PHIEUPH
+0x8BB5 0xB59F #HANGUL SYLLABLE SSANGTIKEUT YAE HIEUH
+0x8BB6 0xB5A2 #HANGUL SYLLABLE SSANGTIKEUT EO SSANGKIYEOK
+0x8BB7 0xB5A3 #HANGUL SYLLABLE SSANGTIKEUT EO KIYEOKSIOS
+0x8BB8 0xB5A5 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUNCIEUC
+0x8BB9 0xB5A6 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUNHIEUH
+0x8BBA 0xB5A7 #HANGUL SYLLABLE SSANGTIKEUT EO TIKEUT
+0x8BBB 0xB5A9 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULKIYEOK
+0x8BBC 0xB5AC #HANGUL SYLLABLE SSANGTIKEUT EO RIEULSIOS
+0x8BBD 0xB5AD #HANGUL SYLLABLE SSANGTIKEUT EO RIEULTHIEUTH
+0x8BBE 0xB5AE #HANGUL SYLLABLE SSANGTIKEUT EO RIEULPHIEUPH
+0x8BBF 0xB5AF #HANGUL SYLLABLE SSANGTIKEUT EO RIEULHIEUH
+0x8BC0 0xB5B2 #HANGUL SYLLABLE SSANGTIKEUT EO PIEUPSIOS
+0x8BC1 0xB5B6 #HANGUL SYLLABLE SSANGTIKEUT EO CIEUC
+0x8BC2 0xB5B7 #HANGUL SYLLABLE SSANGTIKEUT EO CHIEUCH
+0x8BC3 0xB5B8 #HANGUL SYLLABLE SSANGTIKEUT EO KHIEUKH
+0x8BC4 0xB5B9 #HANGUL SYLLABLE SSANGTIKEUT EO THIEUTH
+0x8BC5 0xB5BA #HANGUL SYLLABLE SSANGTIKEUT EO PHIEUPH
+0x8BC6 0xB5BE #HANGUL SYLLABLE SSANGTIKEUT E SSANGKIYEOK
+0x8BC7 0xB5BF #HANGUL SYLLABLE SSANGTIKEUT E KIYEOKSIOS
+0x8BC8 0xB5C1 #HANGUL SYLLABLE SSANGTIKEUT E NIEUNCIEUC
+0x8BC9 0xB5C2 #HANGUL SYLLABLE SSANGTIKEUT E NIEUNHIEUH
+0x8BCA 0xB5C3 #HANGUL SYLLABLE SSANGTIKEUT E TIKEUT
+0x8BCB 0xB5C5 #HANGUL SYLLABLE SSANGTIKEUT E RIEULKIYEOK
+0x8BCC 0xB5C6 #HANGUL SYLLABLE SSANGTIKEUT E RIEULMIEUM
+0x8BCD 0xB5C7 #HANGUL SYLLABLE SSANGTIKEUT E RIEULPIEUP
+0x8BCE 0xB5C8 #HANGUL SYLLABLE SSANGTIKEUT E RIEULSIOS
+0x8BCF 0xB5C9 #HANGUL SYLLABLE SSANGTIKEUT E RIEULTHIEUTH
+0x8BD0 0xB5CA #HANGUL SYLLABLE SSANGTIKEUT E RIEULPHIEUPH
+0x8BD1 0xB5CB #HANGUL SYLLABLE SSANGTIKEUT E RIEULHIEUH
+0x8BD2 0xB5CE #HANGUL SYLLABLE SSANGTIKEUT E PIEUPSIOS
+0x8BD3 0xB5D2 #HANGUL SYLLABLE SSANGTIKEUT E CIEUC
+0x8BD4 0xB5D3 #HANGUL SYLLABLE SSANGTIKEUT E CHIEUCH
+0x8BD5 0xB5D4 #HANGUL SYLLABLE SSANGTIKEUT E KHIEUKH
+0x8BD6 0xB5D5 #HANGUL SYLLABLE SSANGTIKEUT E THIEUTH
+0x8BD7 0xB5D6 #HANGUL SYLLABLE SSANGTIKEUT E PHIEUPH
+0x8BD8 0xB5D7 #HANGUL SYLLABLE SSANGTIKEUT E HIEUH
+0x8BD9 0xB5D9 #HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOK
+0x8BDA 0xB5DA #HANGUL SYLLABLE SSANGTIKEUT YEO SSANGKIYEOK
+0x8BDB 0xB5DB #HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOKSIOS
+0x8BDC 0xB5DC #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUN
+0x8BDD 0xB5DD #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNCIEUC
+0x8BDE 0xB5DE #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNHIEUH
+0x8BDF 0xB5DF #HANGUL SYLLABLE SSANGTIKEUT YEO TIKEUT
+0x8BE0 0xB5E0 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEUL
+0x8BE1 0xB5E1 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULKIYEOK
+0x8BE2 0xB5E2 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULMIEUM
+0x8BE3 0xB5E3 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPIEUP
+0x8BE4 0xB5E4 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULSIOS
+0x8BE5 0xB5E5 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULTHIEUTH
+0x8BE6 0xB5E6 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPHIEUPH
+0x8BE7 0xB5E7 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULHIEUH
+0x8BE8 0xB5E8 #HANGUL SYLLABLE SSANGTIKEUT YEO MIEUM
+0x8BE9 0xB5E9 #HANGUL SYLLABLE SSANGTIKEUT YEO PIEUP
+0x8BEA 0xB5EA #HANGUL SYLLABLE SSANGTIKEUT YEO PIEUPSIOS
+0x8BEB 0xB5EB #HANGUL SYLLABLE SSANGTIKEUT YEO SIOS
+0x8BEC 0xB5ED #HANGUL SYLLABLE SSANGTIKEUT YEO IEUNG
+0x8BED 0xB5EE #HANGUL SYLLABLE SSANGTIKEUT YEO CIEUC
+0x8BEE 0xB5EF #HANGUL SYLLABLE SSANGTIKEUT YEO CHIEUCH
+0x8BEF 0xB5F0 #HANGUL SYLLABLE SSANGTIKEUT YEO KHIEUKH
+0x8BF0 0xB5F1 #HANGUL SYLLABLE SSANGTIKEUT YEO THIEUTH
+0x8BF1 0xB5F2 #HANGUL SYLLABLE SSANGTIKEUT YEO PHIEUPH
+0x8BF2 0xB5F3 #HANGUL SYLLABLE SSANGTIKEUT YEO HIEUH
+0x8BF3 0xB5F4 #HANGUL SYLLABLE SSANGTIKEUT YE
+0x8BF4 0xB5F5 #HANGUL SYLLABLE SSANGTIKEUT YE KIYEOK
+0x8BF5 0xB5F6 #HANGUL SYLLABLE SSANGTIKEUT YE SSANGKIYEOK
+0x8BF6 0xB5F7 #HANGUL SYLLABLE SSANGTIKEUT YE KIYEOKSIOS
+0x8BF7 0xB5F8 #HANGUL SYLLABLE SSANGTIKEUT YE NIEUN
+0x8BF8 0xB5F9 #HANGUL SYLLABLE SSANGTIKEUT YE NIEUNCIEUC
+0x8BF9 0xB5FA #HANGUL SYLLABLE SSANGTIKEUT YE NIEUNHIEUH
+0x8BFA 0xB5FB #HANGUL SYLLABLE SSANGTIKEUT YE TIKEUT
+0x8BFB 0xB5FC #HANGUL SYLLABLE SSANGTIKEUT YE RIEUL
+0x8BFC 0xB5FD #HANGUL SYLLABLE SSANGTIKEUT YE RIEULKIYEOK
+0x8BFD 0xB5FE #HANGUL SYLLABLE SSANGTIKEUT YE RIEULMIEUM
+0x8BFE 0xB5FF #HANGUL SYLLABLE SSANGTIKEUT YE RIEULPIEUP
+0x8C41 0xB600 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULSIOS
+0x8C42 0xB601 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULTHIEUTH
+0x8C43 0xB602 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULPHIEUPH
+0x8C44 0xB603 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULHIEUH
+0x8C45 0xB604 #HANGUL SYLLABLE SSANGTIKEUT YE MIEUM
+0x8C46 0xB605 #HANGUL SYLLABLE SSANGTIKEUT YE PIEUP
+0x8C47 0xB606 #HANGUL SYLLABLE SSANGTIKEUT YE PIEUPSIOS
+0x8C48 0xB607 #HANGUL SYLLABLE SSANGTIKEUT YE SIOS
+0x8C49 0xB608 #HANGUL SYLLABLE SSANGTIKEUT YE SSANGSIOS
+0x8C4A 0xB609 #HANGUL SYLLABLE SSANGTIKEUT YE IEUNG
+0x8C4B 0xB60A #HANGUL SYLLABLE SSANGTIKEUT YE CIEUC
+0x8C4C 0xB60B #HANGUL SYLLABLE SSANGTIKEUT YE CHIEUCH
+0x8C4D 0xB60C #HANGUL SYLLABLE SSANGTIKEUT YE KHIEUKH
+0x8C4E 0xB60D #HANGUL SYLLABLE SSANGTIKEUT YE THIEUTH
+0x8C4F 0xB60E #HANGUL SYLLABLE SSANGTIKEUT YE PHIEUPH
+0x8C50 0xB60F #HANGUL SYLLABLE SSANGTIKEUT YE HIEUH
+0x8C51 0xB612 #HANGUL SYLLABLE SSANGTIKEUT O SSANGKIYEOK
+0x8C52 0xB613 #HANGUL SYLLABLE SSANGTIKEUT O KIYEOKSIOS
+0x8C53 0xB615 #HANGUL SYLLABLE SSANGTIKEUT O NIEUNCIEUC
+0x8C54 0xB616 #HANGUL SYLLABLE SSANGTIKEUT O NIEUNHIEUH
+0x8C55 0xB617 #HANGUL SYLLABLE SSANGTIKEUT O TIKEUT
+0x8C56 0xB619 #HANGUL SYLLABLE SSANGTIKEUT O RIEULKIYEOK
+0x8C57 0xB61A #HANGUL SYLLABLE SSANGTIKEUT O RIEULMIEUM
+0x8C58 0xB61B #HANGUL SYLLABLE SSANGTIKEUT O RIEULPIEUP
+0x8C59 0xB61C #HANGUL SYLLABLE SSANGTIKEUT O RIEULSIOS
+0x8C5A 0xB61D #HANGUL SYLLABLE SSANGTIKEUT O RIEULTHIEUTH
+0x8C61 0xB61E #HANGUL SYLLABLE SSANGTIKEUT O RIEULPHIEUPH
+0x8C62 0xB61F #HANGUL SYLLABLE SSANGTIKEUT O RIEULHIEUH
+0x8C63 0xB620 #HANGUL SYLLABLE SSANGTIKEUT O MIEUM
+0x8C64 0xB621 #HANGUL SYLLABLE SSANGTIKEUT O PIEUP
+0x8C65 0xB622 #HANGUL SYLLABLE SSANGTIKEUT O PIEUPSIOS
+0x8C66 0xB623 #HANGUL SYLLABLE SSANGTIKEUT O SIOS
+0x8C67 0xB624 #HANGUL SYLLABLE SSANGTIKEUT O SSANGSIOS
+0x8C68 0xB626 #HANGUL SYLLABLE SSANGTIKEUT O CIEUC
+0x8C69 0xB627 #HANGUL SYLLABLE SSANGTIKEUT O CHIEUCH
+0x8C6A 0xB628 #HANGUL SYLLABLE SSANGTIKEUT O KHIEUKH
+0x8C6B 0xB629 #HANGUL SYLLABLE SSANGTIKEUT O THIEUTH
+0x8C6C 0xB62A #HANGUL SYLLABLE SSANGTIKEUT O PHIEUPH
+0x8C6D 0xB62B #HANGUL SYLLABLE SSANGTIKEUT O HIEUH
+0x8C6E 0xB62D #HANGUL SYLLABLE SSANGTIKEUT WA KIYEOK
+0x8C6F 0xB62E #HANGUL SYLLABLE SSANGTIKEUT WA SSANGKIYEOK
+0x8C70 0xB62F #HANGUL SYLLABLE SSANGTIKEUT WA KIYEOKSIOS
+0x8C71 0xB630 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUN
+0x8C72 0xB631 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUNCIEUC
+0x8C73 0xB632 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUNHIEUH
+0x8C74 0xB633 #HANGUL SYLLABLE SSANGTIKEUT WA TIKEUT
+0x8C75 0xB635 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULKIYEOK
+0x8C76 0xB636 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULMIEUM
+0x8C77 0xB637 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULPIEUP
+0x8C78 0xB638 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULSIOS
+0x8C79 0xB639 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULTHIEUTH
+0x8C7A 0xB63A #HANGUL SYLLABLE SSANGTIKEUT WA RIEULPHIEUPH
+0x8C81 0xB63B #HANGUL SYLLABLE SSANGTIKEUT WA RIEULHIEUH
+0x8C82 0xB63C #HANGUL SYLLABLE SSANGTIKEUT WA MIEUM
+0x8C83 0xB63D #HANGUL SYLLABLE SSANGTIKEUT WA PIEUP
+0x8C84 0xB63E #HANGUL SYLLABLE SSANGTIKEUT WA PIEUPSIOS
+0x8C85 0xB63F #HANGUL SYLLABLE SSANGTIKEUT WA SIOS
+0x8C86 0xB640 #HANGUL SYLLABLE SSANGTIKEUT WA SSANGSIOS
+0x8C87 0xB641 #HANGUL SYLLABLE SSANGTIKEUT WA IEUNG
+0x8C88 0xB642 #HANGUL SYLLABLE SSANGTIKEUT WA CIEUC
+0x8C89 0xB643 #HANGUL SYLLABLE SSANGTIKEUT WA CHIEUCH
+0x8C8A 0xB644 #HANGUL SYLLABLE SSANGTIKEUT WA KHIEUKH
+0x8C8B 0xB645 #HANGUL SYLLABLE SSANGTIKEUT WA THIEUTH
+0x8C8C 0xB646 #HANGUL SYLLABLE SSANGTIKEUT WA PHIEUPH
+0x8C8D 0xB647 #HANGUL SYLLABLE SSANGTIKEUT WA HIEUH
+0x8C8E 0xB649 #HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOK
+0x8C8F 0xB64A #HANGUL SYLLABLE SSANGTIKEUT WAE SSANGKIYEOK
+0x8C90 0xB64B #HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOKSIOS
+0x8C91 0xB64C #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUN
+0x8C92 0xB64D #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNCIEUC
+0x8C93 0xB64E #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNHIEUH
+0x8C94 0xB64F #HANGUL SYLLABLE SSANGTIKEUT WAE TIKEUT
+0x8C95 0xB650 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEUL
+0x8C96 0xB651 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULKIYEOK
+0x8C97 0xB652 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULMIEUM
+0x8C98 0xB653 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPIEUP
+0x8C99 0xB654 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULSIOS
+0x8C9A 0xB655 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULTHIEUTH
+0x8C9B 0xB656 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPHIEUPH
+0x8C9C 0xB657 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULHIEUH
+0x8C9D 0xB658 #HANGUL SYLLABLE SSANGTIKEUT WAE MIEUM
+0x8C9E 0xB659 #HANGUL SYLLABLE SSANGTIKEUT WAE PIEUP
+0x8C9F 0xB65A #HANGUL SYLLABLE SSANGTIKEUT WAE PIEUPSIOS
+0x8CA0 0xB65B #HANGUL SYLLABLE SSANGTIKEUT WAE SIOS
+0x8CA1 0xB65C #HANGUL SYLLABLE SSANGTIKEUT WAE SSANGSIOS
+0x8CA2 0xB65D #HANGUL SYLLABLE SSANGTIKEUT WAE IEUNG
+0x8CA3 0xB65E #HANGUL SYLLABLE SSANGTIKEUT WAE CIEUC
+0x8CA4 0xB65F #HANGUL SYLLABLE SSANGTIKEUT WAE CHIEUCH
+0x8CA5 0xB660 #HANGUL SYLLABLE SSANGTIKEUT WAE KHIEUKH
+0x8CA6 0xB661 #HANGUL SYLLABLE SSANGTIKEUT WAE THIEUTH
+0x8CA7 0xB662 #HANGUL SYLLABLE SSANGTIKEUT WAE PHIEUPH
+0x8CA8 0xB663 #HANGUL SYLLABLE SSANGTIKEUT WAE HIEUH
+0x8CA9 0xB665 #HANGUL SYLLABLE SSANGTIKEUT OE KIYEOK
+0x8CAA 0xB666 #HANGUL SYLLABLE SSANGTIKEUT OE SSANGKIYEOK
+0x8CAB 0xB667 #HANGUL SYLLABLE SSANGTIKEUT OE KIYEOKSIOS
+0x8CAC 0xB669 #HANGUL SYLLABLE SSANGTIKEUT OE NIEUNCIEUC
+0x8CAD 0xB66A #HANGUL SYLLABLE SSANGTIKEUT OE NIEUNHIEUH
+0x8CAE 0xB66B #HANGUL SYLLABLE SSANGTIKEUT OE TIKEUT
+0x8CAF 0xB66C #HANGUL SYLLABLE SSANGTIKEUT OE RIEUL
+0x8CB0 0xB66D #HANGUL SYLLABLE SSANGTIKEUT OE RIEULKIYEOK
+0x8CB1 0xB66E #HANGUL SYLLABLE SSANGTIKEUT OE RIEULMIEUM
+0x8CB2 0xB66F #HANGUL SYLLABLE SSANGTIKEUT OE RIEULPIEUP
+0x8CB3 0xB670 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULSIOS
+0x8CB4 0xB671 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULTHIEUTH
+0x8CB5 0xB672 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULPHIEUPH
+0x8CB6 0xB673 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULHIEUH
+0x8CB7 0xB674 #HANGUL SYLLABLE SSANGTIKEUT OE MIEUM
+0x8CB8 0xB675 #HANGUL SYLLABLE SSANGTIKEUT OE PIEUP
+0x8CB9 0xB676 #HANGUL SYLLABLE SSANGTIKEUT OE PIEUPSIOS
+0x8CBA 0xB677 #HANGUL SYLLABLE SSANGTIKEUT OE SIOS
+0x8CBB 0xB678 #HANGUL SYLLABLE SSANGTIKEUT OE SSANGSIOS
+0x8CBC 0xB679 #HANGUL SYLLABLE SSANGTIKEUT OE IEUNG
+0x8CBD 0xB67A #HANGUL SYLLABLE SSANGTIKEUT OE CIEUC
+0x8CBE 0xB67B #HANGUL SYLLABLE SSANGTIKEUT OE CHIEUCH
+0x8CBF 0xB67C #HANGUL SYLLABLE SSANGTIKEUT OE KHIEUKH
+0x8CC0 0xB67D #HANGUL SYLLABLE SSANGTIKEUT OE THIEUTH
+0x8CC1 0xB67E #HANGUL SYLLABLE SSANGTIKEUT OE PHIEUPH
+0x8CC2 0xB67F #HANGUL SYLLABLE SSANGTIKEUT OE HIEUH
+0x8CC3 0xB680 #HANGUL SYLLABLE SSANGTIKEUT YO
+0x8CC4 0xB681 #HANGUL SYLLABLE SSANGTIKEUT YO KIYEOK
+0x8CC5 0xB682 #HANGUL SYLLABLE SSANGTIKEUT YO SSANGKIYEOK
+0x8CC6 0xB683 #HANGUL SYLLABLE SSANGTIKEUT YO KIYEOKSIOS
+0x8CC7 0xB684 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUN
+0x8CC8 0xB685 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUNCIEUC
+0x8CC9 0xB686 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUNHIEUH
+0x8CCA 0xB687 #HANGUL SYLLABLE SSANGTIKEUT YO TIKEUT
+0x8CCB 0xB688 #HANGUL SYLLABLE SSANGTIKEUT YO RIEUL
+0x8CCC 0xB689 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULKIYEOK
+0x8CCD 0xB68A #HANGUL SYLLABLE SSANGTIKEUT YO RIEULMIEUM
+0x8CCE 0xB68B #HANGUL SYLLABLE SSANGTIKEUT YO RIEULPIEUP
+0x8CCF 0xB68C #HANGUL SYLLABLE SSANGTIKEUT YO RIEULSIOS
+0x8CD0 0xB68D #HANGUL SYLLABLE SSANGTIKEUT YO RIEULTHIEUTH
+0x8CD1 0xB68E #HANGUL SYLLABLE SSANGTIKEUT YO RIEULPHIEUPH
+0x8CD2 0xB68F #HANGUL SYLLABLE SSANGTIKEUT YO RIEULHIEUH
+0x8CD3 0xB690 #HANGUL SYLLABLE SSANGTIKEUT YO MIEUM
+0x8CD4 0xB691 #HANGUL SYLLABLE SSANGTIKEUT YO PIEUP
+0x8CD5 0xB692 #HANGUL SYLLABLE SSANGTIKEUT YO PIEUPSIOS
+0x8CD6 0xB693 #HANGUL SYLLABLE SSANGTIKEUT YO SIOS
+0x8CD7 0xB694 #HANGUL SYLLABLE SSANGTIKEUT YO SSANGSIOS
+0x8CD8 0xB695 #HANGUL SYLLABLE SSANGTIKEUT YO IEUNG
+0x8CD9 0xB696 #HANGUL SYLLABLE SSANGTIKEUT YO CIEUC
+0x8CDA 0xB697 #HANGUL SYLLABLE SSANGTIKEUT YO CHIEUCH
+0x8CDB 0xB698 #HANGUL SYLLABLE SSANGTIKEUT YO KHIEUKH
+0x8CDC 0xB699 #HANGUL SYLLABLE SSANGTIKEUT YO THIEUTH
+0x8CDD 0xB69A #HANGUL SYLLABLE SSANGTIKEUT YO PHIEUPH
+0x8CDE 0xB69B #HANGUL SYLLABLE SSANGTIKEUT YO HIEUH
+0x8CDF 0xB69E #HANGUL SYLLABLE SSANGTIKEUT U SSANGKIYEOK
+0x8CE0 0xB69F #HANGUL SYLLABLE SSANGTIKEUT U KIYEOKSIOS
+0x8CE1 0xB6A1 #HANGUL SYLLABLE SSANGTIKEUT U NIEUNCIEUC
+0x8CE2 0xB6A2 #HANGUL SYLLABLE SSANGTIKEUT U NIEUNHIEUH
+0x8CE3 0xB6A3 #HANGUL SYLLABLE SSANGTIKEUT U TIKEUT
+0x8CE4 0xB6A5 #HANGUL SYLLABLE SSANGTIKEUT U RIEULKIYEOK
+0x8CE5 0xB6A6 #HANGUL SYLLABLE SSANGTIKEUT U RIEULMIEUM
+0x8CE6 0xB6A7 #HANGUL SYLLABLE SSANGTIKEUT U RIEULPIEUP
+0x8CE7 0xB6A8 #HANGUL SYLLABLE SSANGTIKEUT U RIEULSIOS
+0x8CE8 0xB6A9 #HANGUL SYLLABLE SSANGTIKEUT U RIEULTHIEUTH
+0x8CE9 0xB6AA #HANGUL SYLLABLE SSANGTIKEUT U RIEULPHIEUPH
+0x8CEA 0xB6AD #HANGUL SYLLABLE SSANGTIKEUT U PIEUP
+0x8CEB 0xB6AE #HANGUL SYLLABLE SSANGTIKEUT U PIEUPSIOS
+0x8CEC 0xB6AF #HANGUL SYLLABLE SSANGTIKEUT U SIOS
+0x8CED 0xB6B0 #HANGUL SYLLABLE SSANGTIKEUT U SSANGSIOS
+0x8CEE 0xB6B2 #HANGUL SYLLABLE SSANGTIKEUT U CIEUC
+0x8CEF 0xB6B3 #HANGUL SYLLABLE SSANGTIKEUT U CHIEUCH
+0x8CF0 0xB6B4 #HANGUL SYLLABLE SSANGTIKEUT U KHIEUKH
+0x8CF1 0xB6B5 #HANGUL SYLLABLE SSANGTIKEUT U THIEUTH
+0x8CF2 0xB6B6 #HANGUL SYLLABLE SSANGTIKEUT U PHIEUPH
+0x8CF3 0xB6B7 #HANGUL SYLLABLE SSANGTIKEUT U HIEUH
+0x8CF4 0xB6B8 #HANGUL SYLLABLE SSANGTIKEUT WEO
+0x8CF5 0xB6B9 #HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOK
+0x8CF6 0xB6BA #HANGUL SYLLABLE SSANGTIKEUT WEO SSANGKIYEOK
+0x8CF7 0xB6BB #HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOKSIOS
+0x8CF8 0xB6BC #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUN
+0x8CF9 0xB6BD #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNCIEUC
+0x8CFA 0xB6BE #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNHIEUH
+0x8CFB 0xB6BF #HANGUL SYLLABLE SSANGTIKEUT WEO TIKEUT
+0x8CFC 0xB6C0 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEUL
+0x8CFD 0xB6C1 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULKIYEOK
+0x8CFE 0xB6C2 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULMIEUM
+0x8D41 0xB6C3 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPIEUP
+0x8D42 0xB6C4 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULSIOS
+0x8D43 0xB6C5 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULTHIEUTH
+0x8D44 0xB6C6 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPHIEUPH
+0x8D45 0xB6C7 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULHIEUH
+0x8D46 0xB6C8 #HANGUL SYLLABLE SSANGTIKEUT WEO MIEUM
+0x8D47 0xB6C9 #HANGUL SYLLABLE SSANGTIKEUT WEO PIEUP
+0x8D48 0xB6CA #HANGUL SYLLABLE SSANGTIKEUT WEO PIEUPSIOS
+0x8D49 0xB6CB #HANGUL SYLLABLE SSANGTIKEUT WEO SIOS
+0x8D4A 0xB6CC #HANGUL SYLLABLE SSANGTIKEUT WEO SSANGSIOS
+0x8D4B 0xB6CD #HANGUL SYLLABLE SSANGTIKEUT WEO IEUNG
+0x8D4C 0xB6CE #HANGUL SYLLABLE SSANGTIKEUT WEO CIEUC
+0x8D4D 0xB6CF #HANGUL SYLLABLE SSANGTIKEUT WEO CHIEUCH
+0x8D4E 0xB6D0 #HANGUL SYLLABLE SSANGTIKEUT WEO KHIEUKH
+0x8D4F 0xB6D1 #HANGUL SYLLABLE SSANGTIKEUT WEO THIEUTH
+0x8D50 0xB6D2 #HANGUL SYLLABLE SSANGTIKEUT WEO PHIEUPH
+0x8D51 0xB6D3 #HANGUL SYLLABLE SSANGTIKEUT WEO HIEUH
+0x8D52 0xB6D5 #HANGUL SYLLABLE SSANGTIKEUT WE KIYEOK
+0x8D53 0xB6D6 #HANGUL SYLLABLE SSANGTIKEUT WE SSANGKIYEOK
+0x8D54 0xB6D7 #HANGUL SYLLABLE SSANGTIKEUT WE KIYEOKSIOS
+0x8D55 0xB6D8 #HANGUL SYLLABLE SSANGTIKEUT WE NIEUN
+0x8D56 0xB6D9 #HANGUL SYLLABLE SSANGTIKEUT WE NIEUNCIEUC
+0x8D57 0xB6DA #HANGUL SYLLABLE SSANGTIKEUT WE NIEUNHIEUH
+0x8D58 0xB6DB #HANGUL SYLLABLE SSANGTIKEUT WE TIKEUT
+0x8D59 0xB6DC #HANGUL SYLLABLE SSANGTIKEUT WE RIEUL
+0x8D5A 0xB6DD #HANGUL SYLLABLE SSANGTIKEUT WE RIEULKIYEOK
+0x8D61 0xB6DE #HANGUL SYLLABLE SSANGTIKEUT WE RIEULMIEUM
+0x8D62 0xB6DF #HANGUL SYLLABLE SSANGTIKEUT WE RIEULPIEUP
+0x8D63 0xB6E0 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULSIOS
+0x8D64 0xB6E1 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULTHIEUTH
+0x8D65 0xB6E2 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULPHIEUPH
+0x8D66 0xB6E3 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULHIEUH
+0x8D67 0xB6E4 #HANGUL SYLLABLE SSANGTIKEUT WE MIEUM
+0x8D68 0xB6E5 #HANGUL SYLLABLE SSANGTIKEUT WE PIEUP
+0x8D69 0xB6E6 #HANGUL SYLLABLE SSANGTIKEUT WE PIEUPSIOS
+0x8D6A 0xB6E7 #HANGUL SYLLABLE SSANGTIKEUT WE SIOS
+0x8D6B 0xB6E8 #HANGUL SYLLABLE SSANGTIKEUT WE SSANGSIOS
+0x8D6C 0xB6E9 #HANGUL SYLLABLE SSANGTIKEUT WE IEUNG
+0x8D6D 0xB6EA #HANGUL SYLLABLE SSANGTIKEUT WE CIEUC
+0x8D6E 0xB6EB #HANGUL SYLLABLE SSANGTIKEUT WE CHIEUCH
+0x8D6F 0xB6EC #HANGUL SYLLABLE SSANGTIKEUT WE KHIEUKH
+0x8D70 0xB6ED #HANGUL SYLLABLE SSANGTIKEUT WE THIEUTH
+0x8D71 0xB6EE #HANGUL SYLLABLE SSANGTIKEUT WE PHIEUPH
+0x8D72 0xB6EF #HANGUL SYLLABLE SSANGTIKEUT WE HIEUH
+0x8D73 0xB6F1 #HANGUL SYLLABLE SSANGTIKEUT WI KIYEOK
+0x8D74 0xB6F2 #HANGUL SYLLABLE SSANGTIKEUT WI SSANGKIYEOK
+0x8D75 0xB6F3 #HANGUL SYLLABLE SSANGTIKEUT WI KIYEOKSIOS
+0x8D76 0xB6F5 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUNCIEUC
+0x8D77 0xB6F6 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUNHIEUH
+0x8D78 0xB6F7 #HANGUL SYLLABLE SSANGTIKEUT WI TIKEUT
+0x8D79 0xB6F9 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULKIYEOK
+0x8D7A 0xB6FA #HANGUL SYLLABLE SSANGTIKEUT WI RIEULMIEUM
+0x8D81 0xB6FB #HANGUL SYLLABLE SSANGTIKEUT WI RIEULPIEUP
+0x8D82 0xB6FC #HANGUL SYLLABLE SSANGTIKEUT WI RIEULSIOS
+0x8D83 0xB6FD #HANGUL SYLLABLE SSANGTIKEUT WI RIEULTHIEUTH
+0x8D84 0xB6FE #HANGUL SYLLABLE SSANGTIKEUT WI RIEULPHIEUPH
+0x8D85 0xB6FF #HANGUL SYLLABLE SSANGTIKEUT WI RIEULHIEUH
+0x8D86 0xB702 #HANGUL SYLLABLE SSANGTIKEUT WI PIEUPSIOS
+0x8D87 0xB703 #HANGUL SYLLABLE SSANGTIKEUT WI SIOS
+0x8D88 0xB704 #HANGUL SYLLABLE SSANGTIKEUT WI SSANGSIOS
+0x8D89 0xB706 #HANGUL SYLLABLE SSANGTIKEUT WI CIEUC
+0x8D8A 0xB707 #HANGUL SYLLABLE SSANGTIKEUT WI CHIEUCH
+0x8D8B 0xB708 #HANGUL SYLLABLE SSANGTIKEUT WI KHIEUKH
+0x8D8C 0xB709 #HANGUL SYLLABLE SSANGTIKEUT WI THIEUTH
+0x8D8D 0xB70A #HANGUL SYLLABLE SSANGTIKEUT WI PHIEUPH
+0x8D8E 0xB70B #HANGUL SYLLABLE SSANGTIKEUT WI HIEUH
+0x8D8F 0xB70C #HANGUL SYLLABLE SSANGTIKEUT YU
+0x8D90 0xB70D #HANGUL SYLLABLE SSANGTIKEUT YU KIYEOK
+0x8D91 0xB70E #HANGUL SYLLABLE SSANGTIKEUT YU SSANGKIYEOK
+0x8D92 0xB70F #HANGUL SYLLABLE SSANGTIKEUT YU KIYEOKSIOS
+0x8D93 0xB710 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUN
+0x8D94 0xB711 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUNCIEUC
+0x8D95 0xB712 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUNHIEUH
+0x8D96 0xB713 #HANGUL SYLLABLE SSANGTIKEUT YU TIKEUT
+0x8D97 0xB714 #HANGUL SYLLABLE SSANGTIKEUT YU RIEUL
+0x8D98 0xB715 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULKIYEOK
+0x8D99 0xB716 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULMIEUM
+0x8D9A 0xB717 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULPIEUP
+0x8D9B 0xB718 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULSIOS
+0x8D9C 0xB719 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULTHIEUTH
+0x8D9D 0xB71A #HANGUL SYLLABLE SSANGTIKEUT YU RIEULPHIEUPH
+0x8D9E 0xB71B #HANGUL SYLLABLE SSANGTIKEUT YU RIEULHIEUH
+0x8D9F 0xB71C #HANGUL SYLLABLE SSANGTIKEUT YU MIEUM
+0x8DA0 0xB71D #HANGUL SYLLABLE SSANGTIKEUT YU PIEUP
+0x8DA1 0xB71E #HANGUL SYLLABLE SSANGTIKEUT YU PIEUPSIOS
+0x8DA2 0xB71F #HANGUL SYLLABLE SSANGTIKEUT YU SIOS
+0x8DA3 0xB720 #HANGUL SYLLABLE SSANGTIKEUT YU SSANGSIOS
+0x8DA4 0xB721 #HANGUL SYLLABLE SSANGTIKEUT YU IEUNG
+0x8DA5 0xB722 #HANGUL SYLLABLE SSANGTIKEUT YU CIEUC
+0x8DA6 0xB723 #HANGUL SYLLABLE SSANGTIKEUT YU CHIEUCH
+0x8DA7 0xB724 #HANGUL SYLLABLE SSANGTIKEUT YU KHIEUKH
+0x8DA8 0xB725 #HANGUL SYLLABLE SSANGTIKEUT YU THIEUTH
+0x8DA9 0xB726 #HANGUL SYLLABLE SSANGTIKEUT YU PHIEUPH
+0x8DAA 0xB727 #HANGUL SYLLABLE SSANGTIKEUT YU HIEUH
+0x8DAB 0xB72A #HANGUL SYLLABLE SSANGTIKEUT EU SSANGKIYEOK
+0x8DAC 0xB72B #HANGUL SYLLABLE SSANGTIKEUT EU KIYEOKSIOS
+0x8DAD 0xB72D #HANGUL SYLLABLE SSANGTIKEUT EU NIEUNCIEUC
+0x8DAE 0xB72E #HANGUL SYLLABLE SSANGTIKEUT EU NIEUNHIEUH
+0x8DAF 0xB731 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULKIYEOK
+0x8DB0 0xB732 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULMIEUM
+0x8DB1 0xB733 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULPIEUP
+0x8DB2 0xB734 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULSIOS
+0x8DB3 0xB735 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULTHIEUTH
+0x8DB4 0xB736 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULPHIEUPH
+0x8DB5 0xB737 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULHIEUH
+0x8DB6 0xB73A #HANGUL SYLLABLE SSANGTIKEUT EU PIEUPSIOS
+0x8DB7 0xB73C #HANGUL SYLLABLE SSANGTIKEUT EU SSANGSIOS
+0x8DB8 0xB73D #HANGUL SYLLABLE SSANGTIKEUT EU IEUNG
+0x8DB9 0xB73E #HANGUL SYLLABLE SSANGTIKEUT EU CIEUC
+0x8DBA 0xB73F #HANGUL SYLLABLE SSANGTIKEUT EU CHIEUCH
+0x8DBB 0xB740 #HANGUL SYLLABLE SSANGTIKEUT EU KHIEUKH
+0x8DBC 0xB741 #HANGUL SYLLABLE SSANGTIKEUT EU THIEUTH
+0x8DBD 0xB742 #HANGUL SYLLABLE SSANGTIKEUT EU PHIEUPH
+0x8DBE 0xB743 #HANGUL SYLLABLE SSANGTIKEUT EU HIEUH
+0x8DBF 0xB745 #HANGUL SYLLABLE SSANGTIKEUT YI KIYEOK
+0x8DC0 0xB746 #HANGUL SYLLABLE SSANGTIKEUT YI SSANGKIYEOK
+0x8DC1 0xB747 #HANGUL SYLLABLE SSANGTIKEUT YI KIYEOKSIOS
+0x8DC2 0xB749 #HANGUL SYLLABLE SSANGTIKEUT YI NIEUNCIEUC
+0x8DC3 0xB74A #HANGUL SYLLABLE SSANGTIKEUT YI NIEUNHIEUH
+0x8DC4 0xB74B #HANGUL SYLLABLE SSANGTIKEUT YI TIKEUT
+0x8DC5 0xB74D #HANGUL SYLLABLE SSANGTIKEUT YI RIEULKIYEOK
+0x8DC6 0xB74E #HANGUL SYLLABLE SSANGTIKEUT YI RIEULMIEUM
+0x8DC7 0xB74F #HANGUL SYLLABLE SSANGTIKEUT YI RIEULPIEUP
+0x8DC8 0xB750 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULSIOS
+0x8DC9 0xB751 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULTHIEUTH
+0x8DCA 0xB752 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULPHIEUPH
+0x8DCB 0xB753 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULHIEUH
+0x8DCC 0xB756 #HANGUL SYLLABLE SSANGTIKEUT YI PIEUPSIOS
+0x8DCD 0xB757 #HANGUL SYLLABLE SSANGTIKEUT YI SIOS
+0x8DCE 0xB758 #HANGUL SYLLABLE SSANGTIKEUT YI SSANGSIOS
+0x8DCF 0xB759 #HANGUL SYLLABLE SSANGTIKEUT YI IEUNG
+0x8DD0 0xB75A #HANGUL SYLLABLE SSANGTIKEUT YI CIEUC
+0x8DD1 0xB75B #HANGUL SYLLABLE SSANGTIKEUT YI CHIEUCH
+0x8DD2 0xB75C #HANGUL SYLLABLE SSANGTIKEUT YI KHIEUKH
+0x8DD3 0xB75D #HANGUL SYLLABLE SSANGTIKEUT YI THIEUTH
+0x8DD4 0xB75E #HANGUL SYLLABLE SSANGTIKEUT YI PHIEUPH
+0x8DD5 0xB75F #HANGUL SYLLABLE SSANGTIKEUT YI HIEUH
+0x8DD6 0xB761 #HANGUL SYLLABLE SSANGTIKEUT I KIYEOK
+0x8DD7 0xB762 #HANGUL SYLLABLE SSANGTIKEUT I SSANGKIYEOK
+0x8DD8 0xB763 #HANGUL SYLLABLE SSANGTIKEUT I KIYEOKSIOS
+0x8DD9 0xB765 #HANGUL SYLLABLE SSANGTIKEUT I NIEUNCIEUC
+0x8DDA 0xB766 #HANGUL SYLLABLE SSANGTIKEUT I NIEUNHIEUH
+0x8DDB 0xB767 #HANGUL SYLLABLE SSANGTIKEUT I TIKEUT
+0x8DDC 0xB769 #HANGUL SYLLABLE SSANGTIKEUT I RIEULKIYEOK
+0x8DDD 0xB76A #HANGUL SYLLABLE SSANGTIKEUT I RIEULMIEUM
+0x8DDE 0xB76B #HANGUL SYLLABLE SSANGTIKEUT I RIEULPIEUP
+0x8DDF 0xB76C #HANGUL SYLLABLE SSANGTIKEUT I RIEULSIOS
+0x8DE0 0xB76D #HANGUL SYLLABLE SSANGTIKEUT I RIEULTHIEUTH
+0x8DE1 0xB76E #HANGUL SYLLABLE SSANGTIKEUT I RIEULPHIEUPH
+0x8DE2 0xB76F #HANGUL SYLLABLE SSANGTIKEUT I RIEULHIEUH
+0x8DE3 0xB772 #HANGUL SYLLABLE SSANGTIKEUT I PIEUPSIOS
+0x8DE4 0xB774 #HANGUL SYLLABLE SSANGTIKEUT I SSANGSIOS
+0x8DE5 0xB776 #HANGUL SYLLABLE SSANGTIKEUT I CIEUC
+0x8DE6 0xB777 #HANGUL SYLLABLE SSANGTIKEUT I CHIEUCH
+0x8DE7 0xB778 #HANGUL SYLLABLE SSANGTIKEUT I KHIEUKH
+0x8DE8 0xB779 #HANGUL SYLLABLE SSANGTIKEUT I THIEUTH
+0x8DE9 0xB77A #HANGUL SYLLABLE SSANGTIKEUT I PHIEUPH
+0x8DEA 0xB77B #HANGUL SYLLABLE SSANGTIKEUT I HIEUH
+0x8DEB 0xB77E #HANGUL SYLLABLE RIEUL A SSANGKIYEOK
+0x8DEC 0xB77F #HANGUL SYLLABLE RIEUL A KIYEOKSIOS
+0x8DED 0xB781 #HANGUL SYLLABLE RIEUL A NIEUNCIEUC
+0x8DEE 0xB782 #HANGUL SYLLABLE RIEUL A NIEUNHIEUH
+0x8DEF 0xB783 #HANGUL SYLLABLE RIEUL A TIKEUT
+0x8DF0 0xB785 #HANGUL SYLLABLE RIEUL A RIEULKIYEOK
+0x8DF1 0xB786 #HANGUL SYLLABLE RIEUL A RIEULMIEUM
+0x8DF2 0xB787 #HANGUL SYLLABLE RIEUL A RIEULPIEUP
+0x8DF3 0xB788 #HANGUL SYLLABLE RIEUL A RIEULSIOS
+0x8DF4 0xB789 #HANGUL SYLLABLE RIEUL A RIEULTHIEUTH
+0x8DF5 0xB78A #HANGUL SYLLABLE RIEUL A RIEULPHIEUPH
+0x8DF6 0xB78B #HANGUL SYLLABLE RIEUL A RIEULHIEUH
+0x8DF7 0xB78E #HANGUL SYLLABLE RIEUL A PIEUPSIOS
+0x8DF8 0xB793 #HANGUL SYLLABLE RIEUL A CHIEUCH
+0x8DF9 0xB794 #HANGUL SYLLABLE RIEUL A KHIEUKH
+0x8DFA 0xB795 #HANGUL SYLLABLE RIEUL A THIEUTH
+0x8DFB 0xB79A #HANGUL SYLLABLE RIEUL AE SSANGKIYEOK
+0x8DFC 0xB79B #HANGUL SYLLABLE RIEUL AE KIYEOKSIOS
+0x8DFD 0xB79D #HANGUL SYLLABLE RIEUL AE NIEUNCIEUC
+0x8DFE 0xB79E #HANGUL SYLLABLE RIEUL AE NIEUNHIEUH
+0x8E41 0xB79F #HANGUL SYLLABLE RIEUL AE TIKEUT
+0x8E42 0xB7A1 #HANGUL SYLLABLE RIEUL AE RIEULKIYEOK
+0x8E43 0xB7A2 #HANGUL SYLLABLE RIEUL AE RIEULMIEUM
+0x8E44 0xB7A3 #HANGUL SYLLABLE RIEUL AE RIEULPIEUP
+0x8E45 0xB7A4 #HANGUL SYLLABLE RIEUL AE RIEULSIOS
+0x8E46 0xB7A5 #HANGUL SYLLABLE RIEUL AE RIEULTHIEUTH
+0x8E47 0xB7A6 #HANGUL SYLLABLE RIEUL AE RIEULPHIEUPH
+0x8E48 0xB7A7 #HANGUL SYLLABLE RIEUL AE RIEULHIEUH
+0x8E49 0xB7AA #HANGUL SYLLABLE RIEUL AE PIEUPSIOS
+0x8E4A 0xB7AE #HANGUL SYLLABLE RIEUL AE CIEUC
+0x8E4B 0xB7AF #HANGUL SYLLABLE RIEUL AE CHIEUCH
+0x8E4C 0xB7B0 #HANGUL SYLLABLE RIEUL AE KHIEUKH
+0x8E4D 0xB7B1 #HANGUL SYLLABLE RIEUL AE THIEUTH
+0x8E4E 0xB7B2 #HANGUL SYLLABLE RIEUL AE PHIEUPH
+0x8E4F 0xB7B3 #HANGUL SYLLABLE RIEUL AE HIEUH
+0x8E50 0xB7B6 #HANGUL SYLLABLE RIEUL YA SSANGKIYEOK
+0x8E51 0xB7B7 #HANGUL SYLLABLE RIEUL YA KIYEOKSIOS
+0x8E52 0xB7B9 #HANGUL SYLLABLE RIEUL YA NIEUNCIEUC
+0x8E53 0xB7BA #HANGUL SYLLABLE RIEUL YA NIEUNHIEUH
+0x8E54 0xB7BB #HANGUL SYLLABLE RIEUL YA TIKEUT
+0x8E55 0xB7BC #HANGUL SYLLABLE RIEUL YA RIEUL
+0x8E56 0xB7BD #HANGUL SYLLABLE RIEUL YA RIEULKIYEOK
+0x8E57 0xB7BE #HANGUL SYLLABLE RIEUL YA RIEULMIEUM
+0x8E58 0xB7BF #HANGUL SYLLABLE RIEUL YA RIEULPIEUP
+0x8E59 0xB7C0 #HANGUL SYLLABLE RIEUL YA RIEULSIOS
+0x8E5A 0xB7C1 #HANGUL SYLLABLE RIEUL YA RIEULTHIEUTH
+0x8E61 0xB7C2 #HANGUL SYLLABLE RIEUL YA RIEULPHIEUPH
+0x8E62 0xB7C3 #HANGUL SYLLABLE RIEUL YA RIEULHIEUH
+0x8E63 0xB7C4 #HANGUL SYLLABLE RIEUL YA MIEUM
+0x8E64 0xB7C5 #HANGUL SYLLABLE RIEUL YA PIEUP
+0x8E65 0xB7C6 #HANGUL SYLLABLE RIEUL YA PIEUPSIOS
+0x8E66 0xB7C8 #HANGUL SYLLABLE RIEUL YA SSANGSIOS
+0x8E67 0xB7CA #HANGUL SYLLABLE RIEUL YA CIEUC
+0x8E68 0xB7CB #HANGUL SYLLABLE RIEUL YA CHIEUCH
+0x8E69 0xB7CC #HANGUL SYLLABLE RIEUL YA KHIEUKH
+0x8E6A 0xB7CD #HANGUL SYLLABLE RIEUL YA THIEUTH
+0x8E6B 0xB7CE #HANGUL SYLLABLE RIEUL YA PHIEUPH
+0x8E6C 0xB7CF #HANGUL SYLLABLE RIEUL YA HIEUH
+0x8E6D 0xB7D0 #HANGUL SYLLABLE RIEUL YAE
+0x8E6E 0xB7D1 #HANGUL SYLLABLE RIEUL YAE KIYEOK
+0x8E6F 0xB7D2 #HANGUL SYLLABLE RIEUL YAE SSANGKIYEOK
+0x8E70 0xB7D3 #HANGUL SYLLABLE RIEUL YAE KIYEOKSIOS
+0x8E71 0xB7D4 #HANGUL SYLLABLE RIEUL YAE NIEUN
+0x8E72 0xB7D5 #HANGUL SYLLABLE RIEUL YAE NIEUNCIEUC
+0x8E73 0xB7D6 #HANGUL SYLLABLE RIEUL YAE NIEUNHIEUH
+0x8E74 0xB7D7 #HANGUL SYLLABLE RIEUL YAE TIKEUT
+0x8E75 0xB7D8 #HANGUL SYLLABLE RIEUL YAE RIEUL
+0x8E76 0xB7D9 #HANGUL SYLLABLE RIEUL YAE RIEULKIYEOK
+0x8E77 0xB7DA #HANGUL SYLLABLE RIEUL YAE RIEULMIEUM
+0x8E78 0xB7DB #HANGUL SYLLABLE RIEUL YAE RIEULPIEUP
+0x8E79 0xB7DC #HANGUL SYLLABLE RIEUL YAE RIEULSIOS
+0x8E7A 0xB7DD #HANGUL SYLLABLE RIEUL YAE RIEULTHIEUTH
+0x8E81 0xB7DE #HANGUL SYLLABLE RIEUL YAE RIEULPHIEUPH
+0x8E82 0xB7DF #HANGUL SYLLABLE RIEUL YAE RIEULHIEUH
+0x8E83 0xB7E0 #HANGUL SYLLABLE RIEUL YAE MIEUM
+0x8E84 0xB7E1 #HANGUL SYLLABLE RIEUL YAE PIEUP
+0x8E85 0xB7E2 #HANGUL SYLLABLE RIEUL YAE PIEUPSIOS
+0x8E86 0xB7E3 #HANGUL SYLLABLE RIEUL YAE SIOS
+0x8E87 0xB7E4 #HANGUL SYLLABLE RIEUL YAE SSANGSIOS
+0x8E88 0xB7E5 #HANGUL SYLLABLE RIEUL YAE IEUNG
+0x8E89 0xB7E6 #HANGUL SYLLABLE RIEUL YAE CIEUC
+0x8E8A 0xB7E7 #HANGUL SYLLABLE RIEUL YAE CHIEUCH
+0x8E8B 0xB7E8 #HANGUL SYLLABLE RIEUL YAE KHIEUKH
+0x8E8C 0xB7E9 #HANGUL SYLLABLE RIEUL YAE THIEUTH
+0x8E8D 0xB7EA #HANGUL SYLLABLE RIEUL YAE PHIEUPH
+0x8E8E 0xB7EB #HANGUL SYLLABLE RIEUL YAE HIEUH
+0x8E8F 0xB7EE #HANGUL SYLLABLE RIEUL EO SSANGKIYEOK
+0x8E90 0xB7EF #HANGUL SYLLABLE RIEUL EO KIYEOKSIOS
+0x8E91 0xB7F1 #HANGUL SYLLABLE RIEUL EO NIEUNCIEUC
+0x8E92 0xB7F2 #HANGUL SYLLABLE RIEUL EO NIEUNHIEUH
+0x8E93 0xB7F3 #HANGUL SYLLABLE RIEUL EO TIKEUT
+0x8E94 0xB7F5 #HANGUL SYLLABLE RIEUL EO RIEULKIYEOK
+0x8E95 0xB7F6 #HANGUL SYLLABLE RIEUL EO RIEULMIEUM
+0x8E96 0xB7F7 #HANGUL SYLLABLE RIEUL EO RIEULPIEUP
+0x8E97 0xB7F8 #HANGUL SYLLABLE RIEUL EO RIEULSIOS
+0x8E98 0xB7F9 #HANGUL SYLLABLE RIEUL EO RIEULTHIEUTH
+0x8E99 0xB7FA #HANGUL SYLLABLE RIEUL EO RIEULPHIEUPH
+0x8E9A 0xB7FB #HANGUL SYLLABLE RIEUL EO RIEULHIEUH
+0x8E9B 0xB7FE #HANGUL SYLLABLE RIEUL EO PIEUPSIOS
+0x8E9C 0xB802 #HANGUL SYLLABLE RIEUL EO CIEUC
+0x8E9D 0xB803 #HANGUL SYLLABLE RIEUL EO CHIEUCH
+0x8E9E 0xB804 #HANGUL SYLLABLE RIEUL EO KHIEUKH
+0x8E9F 0xB805 #HANGUL SYLLABLE RIEUL EO THIEUTH
+0x8EA0 0xB806 #HANGUL SYLLABLE RIEUL EO PHIEUPH
+0x8EA1 0xB80A #HANGUL SYLLABLE RIEUL E SSANGKIYEOK
+0x8EA2 0xB80B #HANGUL SYLLABLE RIEUL E KIYEOKSIOS
+0x8EA3 0xB80D #HANGUL SYLLABLE RIEUL E NIEUNCIEUC
+0x8EA4 0xB80E #HANGUL SYLLABLE RIEUL E NIEUNHIEUH
+0x8EA5 0xB80F #HANGUL SYLLABLE RIEUL E TIKEUT
+0x8EA6 0xB811 #HANGUL SYLLABLE RIEUL E RIEULKIYEOK
+0x8EA7 0xB812 #HANGUL SYLLABLE RIEUL E RIEULMIEUM
+0x8EA8 0xB813 #HANGUL SYLLABLE RIEUL E RIEULPIEUP
+0x8EA9 0xB814 #HANGUL SYLLABLE RIEUL E RIEULSIOS
+0x8EAA 0xB815 #HANGUL SYLLABLE RIEUL E RIEULTHIEUTH
+0x8EAB 0xB816 #HANGUL SYLLABLE RIEUL E RIEULPHIEUPH
+0x8EAC 0xB817 #HANGUL SYLLABLE RIEUL E RIEULHIEUH
+0x8EAD 0xB81A #HANGUL SYLLABLE RIEUL E PIEUPSIOS
+0x8EAE 0xB81C #HANGUL SYLLABLE RIEUL E SSANGSIOS
+0x8EAF 0xB81E #HANGUL SYLLABLE RIEUL E CIEUC
+0x8EB0 0xB81F #HANGUL SYLLABLE RIEUL E CHIEUCH
+0x8EB1 0xB820 #HANGUL SYLLABLE RIEUL E KHIEUKH
+0x8EB2 0xB821 #HANGUL SYLLABLE RIEUL E THIEUTH
+0x8EB3 0xB822 #HANGUL SYLLABLE RIEUL E PHIEUPH
+0x8EB4 0xB823 #HANGUL SYLLABLE RIEUL E HIEUH
+0x8EB5 0xB826 #HANGUL SYLLABLE RIEUL YEO SSANGKIYEOK
+0x8EB6 0xB827 #HANGUL SYLLABLE RIEUL YEO KIYEOKSIOS
+0x8EB7 0xB829 #HANGUL SYLLABLE RIEUL YEO NIEUNCIEUC
+0x8EB8 0xB82A #HANGUL SYLLABLE RIEUL YEO NIEUNHIEUH
+0x8EB9 0xB82B #HANGUL SYLLABLE RIEUL YEO TIKEUT
+0x8EBA 0xB82D #HANGUL SYLLABLE RIEUL YEO RIEULKIYEOK
+0x8EBB 0xB82E #HANGUL SYLLABLE RIEUL YEO RIEULMIEUM
+0x8EBC 0xB82F #HANGUL SYLLABLE RIEUL YEO RIEULPIEUP
+0x8EBD 0xB830 #HANGUL SYLLABLE RIEUL YEO RIEULSIOS
+0x8EBE 0xB831 #HANGUL SYLLABLE RIEUL YEO RIEULTHIEUTH
+0x8EBF 0xB832 #HANGUL SYLLABLE RIEUL YEO RIEULPHIEUPH
+0x8EC0 0xB833 #HANGUL SYLLABLE RIEUL YEO RIEULHIEUH
+0x8EC1 0xB836 #HANGUL SYLLABLE RIEUL YEO PIEUPSIOS
+0x8EC2 0xB83A #HANGUL SYLLABLE RIEUL YEO CIEUC
+0x8EC3 0xB83B #HANGUL SYLLABLE RIEUL YEO CHIEUCH
+0x8EC4 0xB83C #HANGUL SYLLABLE RIEUL YEO KHIEUKH
+0x8EC5 0xB83D #HANGUL SYLLABLE RIEUL YEO THIEUTH
+0x8EC6 0xB83E #HANGUL SYLLABLE RIEUL YEO PHIEUPH
+0x8EC7 0xB83F #HANGUL SYLLABLE RIEUL YEO HIEUH
+0x8EC8 0xB841 #HANGUL SYLLABLE RIEUL YE KIYEOK
+0x8EC9 0xB842 #HANGUL SYLLABLE RIEUL YE SSANGKIYEOK
+0x8ECA 0xB843 #HANGUL SYLLABLE RIEUL YE KIYEOKSIOS
+0x8ECB 0xB845 #HANGUL SYLLABLE RIEUL YE NIEUNCIEUC
+0x8ECC 0xB846 #HANGUL SYLLABLE RIEUL YE NIEUNHIEUH
+0x8ECD 0xB847 #HANGUL SYLLABLE RIEUL YE TIKEUT
+0x8ECE 0xB848 #HANGUL SYLLABLE RIEUL YE RIEUL
+0x8ECF 0xB849 #HANGUL SYLLABLE RIEUL YE RIEULKIYEOK
+0x8ED0 0xB84A #HANGUL SYLLABLE RIEUL YE RIEULMIEUM
+0x8ED1 0xB84B #HANGUL SYLLABLE RIEUL YE RIEULPIEUP
+0x8ED2 0xB84C #HANGUL SYLLABLE RIEUL YE RIEULSIOS
+0x8ED3 0xB84D #HANGUL SYLLABLE RIEUL YE RIEULTHIEUTH
+0x8ED4 0xB84E #HANGUL SYLLABLE RIEUL YE RIEULPHIEUPH
+0x8ED5 0xB84F #HANGUL SYLLABLE RIEUL YE RIEULHIEUH
+0x8ED6 0xB850 #HANGUL SYLLABLE RIEUL YE MIEUM
+0x8ED7 0xB852 #HANGUL SYLLABLE RIEUL YE PIEUPSIOS
+0x8ED8 0xB854 #HANGUL SYLLABLE RIEUL YE SSANGSIOS
+0x8ED9 0xB855 #HANGUL SYLLABLE RIEUL YE IEUNG
+0x8EDA 0xB856 #HANGUL SYLLABLE RIEUL YE CIEUC
+0x8EDB 0xB857 #HANGUL SYLLABLE RIEUL YE CHIEUCH
+0x8EDC 0xB858 #HANGUL SYLLABLE RIEUL YE KHIEUKH
+0x8EDD 0xB859 #HANGUL SYLLABLE RIEUL YE THIEUTH
+0x8EDE 0xB85A #HANGUL SYLLABLE RIEUL YE PHIEUPH
+0x8EDF 0xB85B #HANGUL SYLLABLE RIEUL YE HIEUH
+0x8EE0 0xB85E #HANGUL SYLLABLE RIEUL O SSANGKIYEOK
+0x8EE1 0xB85F #HANGUL SYLLABLE RIEUL O KIYEOKSIOS
+0x8EE2 0xB861 #HANGUL SYLLABLE RIEUL O NIEUNCIEUC
+0x8EE3 0xB862 #HANGUL SYLLABLE RIEUL O NIEUNHIEUH
+0x8EE4 0xB863 #HANGUL SYLLABLE RIEUL O TIKEUT
+0x8EE5 0xB865 #HANGUL SYLLABLE RIEUL O RIEULKIYEOK
+0x8EE6 0xB866 #HANGUL SYLLABLE RIEUL O RIEULMIEUM
+0x8EE7 0xB867 #HANGUL SYLLABLE RIEUL O RIEULPIEUP
+0x8EE8 0xB868 #HANGUL SYLLABLE RIEUL O RIEULSIOS
+0x8EE9 0xB869 #HANGUL SYLLABLE RIEUL O RIEULTHIEUTH
+0x8EEA 0xB86A #HANGUL SYLLABLE RIEUL O RIEULPHIEUPH
+0x8EEB 0xB86B #HANGUL SYLLABLE RIEUL O RIEULHIEUH
+0x8EEC 0xB86E #HANGUL SYLLABLE RIEUL O PIEUPSIOS
+0x8EED 0xB870 #HANGUL SYLLABLE RIEUL O SSANGSIOS
+0x8EEE 0xB872 #HANGUL SYLLABLE RIEUL O CIEUC
+0x8EEF 0xB873 #HANGUL SYLLABLE RIEUL O CHIEUCH
+0x8EF0 0xB874 #HANGUL SYLLABLE RIEUL O KHIEUKH
+0x8EF1 0xB875 #HANGUL SYLLABLE RIEUL O THIEUTH
+0x8EF2 0xB876 #HANGUL SYLLABLE RIEUL O PHIEUPH
+0x8EF3 0xB877 #HANGUL SYLLABLE RIEUL O HIEUH
+0x8EF4 0xB879 #HANGUL SYLLABLE RIEUL WA KIYEOK
+0x8EF5 0xB87A #HANGUL SYLLABLE RIEUL WA SSANGKIYEOK
+0x8EF6 0xB87B #HANGUL SYLLABLE RIEUL WA KIYEOKSIOS
+0x8EF7 0xB87D #HANGUL SYLLABLE RIEUL WA NIEUNCIEUC
+0x8EF8 0xB87E #HANGUL SYLLABLE RIEUL WA NIEUNHIEUH
+0x8EF9 0xB87F #HANGUL SYLLABLE RIEUL WA TIKEUT
+0x8EFA 0xB880 #HANGUL SYLLABLE RIEUL WA RIEUL
+0x8EFB 0xB881 #HANGUL SYLLABLE RIEUL WA RIEULKIYEOK
+0x8EFC 0xB882 #HANGUL SYLLABLE RIEUL WA RIEULMIEUM
+0x8EFD 0xB883 #HANGUL SYLLABLE RIEUL WA RIEULPIEUP
+0x8EFE 0xB884 #HANGUL SYLLABLE RIEUL WA RIEULSIOS
+0x8F41 0xB885 #HANGUL SYLLABLE RIEUL WA RIEULTHIEUTH
+0x8F42 0xB886 #HANGUL SYLLABLE RIEUL WA RIEULPHIEUPH
+0x8F43 0xB887 #HANGUL SYLLABLE RIEUL WA RIEULHIEUH
+0x8F44 0xB888 #HANGUL SYLLABLE RIEUL WA MIEUM
+0x8F45 0xB889 #HANGUL SYLLABLE RIEUL WA PIEUP
+0x8F46 0xB88A #HANGUL SYLLABLE RIEUL WA PIEUPSIOS
+0x8F47 0xB88B #HANGUL SYLLABLE RIEUL WA SIOS
+0x8F48 0xB88C #HANGUL SYLLABLE RIEUL WA SSANGSIOS
+0x8F49 0xB88E #HANGUL SYLLABLE RIEUL WA CIEUC
+0x8F4A 0xB88F #HANGUL SYLLABLE RIEUL WA CHIEUCH
+0x8F4B 0xB890 #HANGUL SYLLABLE RIEUL WA KHIEUKH
+0x8F4C 0xB891 #HANGUL SYLLABLE RIEUL WA THIEUTH
+0x8F4D 0xB892 #HANGUL SYLLABLE RIEUL WA PHIEUPH
+0x8F4E 0xB893 #HANGUL SYLLABLE RIEUL WA HIEUH
+0x8F4F 0xB894 #HANGUL SYLLABLE RIEUL WAE
+0x8F50 0xB895 #HANGUL SYLLABLE RIEUL WAE KIYEOK
+0x8F51 0xB896 #HANGUL SYLLABLE RIEUL WAE SSANGKIYEOK
+0x8F52 0xB897 #HANGUL SYLLABLE RIEUL WAE KIYEOKSIOS
+0x8F53 0xB898 #HANGUL SYLLABLE RIEUL WAE NIEUN
+0x8F54 0xB899 #HANGUL SYLLABLE RIEUL WAE NIEUNCIEUC
+0x8F55 0xB89A #HANGUL SYLLABLE RIEUL WAE NIEUNHIEUH
+0x8F56 0xB89B #HANGUL SYLLABLE RIEUL WAE TIKEUT
+0x8F57 0xB89C #HANGUL SYLLABLE RIEUL WAE RIEUL
+0x8F58 0xB89D #HANGUL SYLLABLE RIEUL WAE RIEULKIYEOK
+0x8F59 0xB89E #HANGUL SYLLABLE RIEUL WAE RIEULMIEUM
+0x8F5A 0xB89F #HANGUL SYLLABLE RIEUL WAE RIEULPIEUP
+0x8F61 0xB8A0 #HANGUL SYLLABLE RIEUL WAE RIEULSIOS
+0x8F62 0xB8A1 #HANGUL SYLLABLE RIEUL WAE RIEULTHIEUTH
+0x8F63 0xB8A2 #HANGUL SYLLABLE RIEUL WAE RIEULPHIEUPH
+0x8F64 0xB8A3 #HANGUL SYLLABLE RIEUL WAE RIEULHIEUH
+0x8F65 0xB8A4 #HANGUL SYLLABLE RIEUL WAE MIEUM
+0x8F66 0xB8A5 #HANGUL SYLLABLE RIEUL WAE PIEUP
+0x8F67 0xB8A6 #HANGUL SYLLABLE RIEUL WAE PIEUPSIOS
+0x8F68 0xB8A7 #HANGUL SYLLABLE RIEUL WAE SIOS
+0x8F69 0xB8A9 #HANGUL SYLLABLE RIEUL WAE IEUNG
+0x8F6A 0xB8AA #HANGUL SYLLABLE RIEUL WAE CIEUC
+0x8F6B 0xB8AB #HANGUL SYLLABLE RIEUL WAE CHIEUCH
+0x8F6C 0xB8AC #HANGUL SYLLABLE RIEUL WAE KHIEUKH
+0x8F6D 0xB8AD #HANGUL SYLLABLE RIEUL WAE THIEUTH
+0x8F6E 0xB8AE #HANGUL SYLLABLE RIEUL WAE PHIEUPH
+0x8F6F 0xB8AF #HANGUL SYLLABLE RIEUL WAE HIEUH
+0x8F70 0xB8B1 #HANGUL SYLLABLE RIEUL OE KIYEOK
+0x8F71 0xB8B2 #HANGUL SYLLABLE RIEUL OE SSANGKIYEOK
+0x8F72 0xB8B3 #HANGUL SYLLABLE RIEUL OE KIYEOKSIOS
+0x8F73 0xB8B5 #HANGUL SYLLABLE RIEUL OE NIEUNCIEUC
+0x8F74 0xB8B6 #HANGUL SYLLABLE RIEUL OE NIEUNHIEUH
+0x8F75 0xB8B7 #HANGUL SYLLABLE RIEUL OE TIKEUT
+0x8F76 0xB8B9 #HANGUL SYLLABLE RIEUL OE RIEULKIYEOK
+0x8F77 0xB8BA #HANGUL SYLLABLE RIEUL OE RIEULMIEUM
+0x8F78 0xB8BB #HANGUL SYLLABLE RIEUL OE RIEULPIEUP
+0x8F79 0xB8BC #HANGUL SYLLABLE RIEUL OE RIEULSIOS
+0x8F7A 0xB8BD #HANGUL SYLLABLE RIEUL OE RIEULTHIEUTH
+0x8F81 0xB8BE #HANGUL SYLLABLE RIEUL OE RIEULPHIEUPH
+0x8F82 0xB8BF #HANGUL SYLLABLE RIEUL OE RIEULHIEUH
+0x8F83 0xB8C2 #HANGUL SYLLABLE RIEUL OE PIEUPSIOS
+0x8F84 0xB8C4 #HANGUL SYLLABLE RIEUL OE SSANGSIOS
+0x8F85 0xB8C6 #HANGUL SYLLABLE RIEUL OE CIEUC
+0x8F86 0xB8C7 #HANGUL SYLLABLE RIEUL OE CHIEUCH
+0x8F87 0xB8C8 #HANGUL SYLLABLE RIEUL OE KHIEUKH
+0x8F88 0xB8C9 #HANGUL SYLLABLE RIEUL OE THIEUTH
+0x8F89 0xB8CA #HANGUL SYLLABLE RIEUL OE PHIEUPH
+0x8F8A 0xB8CB #HANGUL SYLLABLE RIEUL OE HIEUH
+0x8F8B 0xB8CD #HANGUL SYLLABLE RIEUL YO KIYEOK
+0x8F8C 0xB8CE #HANGUL SYLLABLE RIEUL YO SSANGKIYEOK
+0x8F8D 0xB8CF #HANGUL SYLLABLE RIEUL YO KIYEOKSIOS
+0x8F8E 0xB8D1 #HANGUL SYLLABLE RIEUL YO NIEUNCIEUC
+0x8F8F 0xB8D2 #HANGUL SYLLABLE RIEUL YO NIEUNHIEUH
+0x8F90 0xB8D3 #HANGUL SYLLABLE RIEUL YO TIKEUT
+0x8F91 0xB8D5 #HANGUL SYLLABLE RIEUL YO RIEULKIYEOK
+0x8F92 0xB8D6 #HANGUL SYLLABLE RIEUL YO RIEULMIEUM
+0x8F93 0xB8D7 #HANGUL SYLLABLE RIEUL YO RIEULPIEUP
+0x8F94 0xB8D8 #HANGUL SYLLABLE RIEUL YO RIEULSIOS
+0x8F95 0xB8D9 #HANGUL SYLLABLE RIEUL YO RIEULTHIEUTH
+0x8F96 0xB8DA #HANGUL SYLLABLE RIEUL YO RIEULPHIEUPH
+0x8F97 0xB8DB #HANGUL SYLLABLE RIEUL YO RIEULHIEUH
+0x8F98 0xB8DC #HANGUL SYLLABLE RIEUL YO MIEUM
+0x8F99 0xB8DE #HANGUL SYLLABLE RIEUL YO PIEUPSIOS
+0x8F9A 0xB8E0 #HANGUL SYLLABLE RIEUL YO SSANGSIOS
+0x8F9B 0xB8E2 #HANGUL SYLLABLE RIEUL YO CIEUC
+0x8F9C 0xB8E3 #HANGUL SYLLABLE RIEUL YO CHIEUCH
+0x8F9D 0xB8E4 #HANGUL SYLLABLE RIEUL YO KHIEUKH
+0x8F9E 0xB8E5 #HANGUL SYLLABLE RIEUL YO THIEUTH
+0x8F9F 0xB8E6 #HANGUL SYLLABLE RIEUL YO PHIEUPH
+0x8FA0 0xB8E7 #HANGUL SYLLABLE RIEUL YO HIEUH
+0x8FA1 0xB8EA #HANGUL SYLLABLE RIEUL U SSANGKIYEOK
+0x8FA2 0xB8EB #HANGUL SYLLABLE RIEUL U KIYEOKSIOS
+0x8FA3 0xB8ED #HANGUL SYLLABLE RIEUL U NIEUNCIEUC
+0x8FA4 0xB8EE #HANGUL SYLLABLE RIEUL U NIEUNHIEUH
+0x8FA5 0xB8EF #HANGUL SYLLABLE RIEUL U TIKEUT
+0x8FA6 0xB8F1 #HANGUL SYLLABLE RIEUL U RIEULKIYEOK
+0x8FA7 0xB8F2 #HANGUL SYLLABLE RIEUL U RIEULMIEUM
+0x8FA8 0xB8F3 #HANGUL SYLLABLE RIEUL U RIEULPIEUP
+0x8FA9 0xB8F4 #HANGUL SYLLABLE RIEUL U RIEULSIOS
+0x8FAA 0xB8F5 #HANGUL SYLLABLE RIEUL U RIEULTHIEUTH
+0x8FAB 0xB8F6 #HANGUL SYLLABLE RIEUL U RIEULPHIEUPH
+0x8FAC 0xB8F7 #HANGUL SYLLABLE RIEUL U RIEULHIEUH
+0x8FAD 0xB8FA #HANGUL SYLLABLE RIEUL U PIEUPSIOS
+0x8FAE 0xB8FC #HANGUL SYLLABLE RIEUL U SSANGSIOS
+0x8FAF 0xB8FE #HANGUL SYLLABLE RIEUL U CIEUC
+0x8FB0 0xB8FF #HANGUL SYLLABLE RIEUL U CHIEUCH
+0x8FB1 0xB900 #HANGUL SYLLABLE RIEUL U KHIEUKH
+0x8FB2 0xB901 #HANGUL SYLLABLE RIEUL U THIEUTH
+0x8FB3 0xB902 #HANGUL SYLLABLE RIEUL U PHIEUPH
+0x8FB4 0xB903 #HANGUL SYLLABLE RIEUL U HIEUH
+0x8FB5 0xB905 #HANGUL SYLLABLE RIEUL WEO KIYEOK
+0x8FB6 0xB906 #HANGUL SYLLABLE RIEUL WEO SSANGKIYEOK
+0x8FB7 0xB907 #HANGUL SYLLABLE RIEUL WEO KIYEOKSIOS
+0x8FB8 0xB908 #HANGUL SYLLABLE RIEUL WEO NIEUN
+0x8FB9 0xB909 #HANGUL SYLLABLE RIEUL WEO NIEUNCIEUC
+0x8FBA 0xB90A #HANGUL SYLLABLE RIEUL WEO NIEUNHIEUH
+0x8FBB 0xB90B #HANGUL SYLLABLE RIEUL WEO TIKEUT
+0x8FBC 0xB90C #HANGUL SYLLABLE RIEUL WEO RIEUL
+0x8FBD 0xB90D #HANGUL SYLLABLE RIEUL WEO RIEULKIYEOK
+0x8FBE 0xB90E #HANGUL SYLLABLE RIEUL WEO RIEULMIEUM
+0x8FBF 0xB90F #HANGUL SYLLABLE RIEUL WEO RIEULPIEUP
+0x8FC0 0xB910 #HANGUL SYLLABLE RIEUL WEO RIEULSIOS
+0x8FC1 0xB911 #HANGUL SYLLABLE RIEUL WEO RIEULTHIEUTH
+0x8FC2 0xB912 #HANGUL SYLLABLE RIEUL WEO RIEULPHIEUPH
+0x8FC3 0xB913 #HANGUL SYLLABLE RIEUL WEO RIEULHIEUH
+0x8FC4 0xB914 #HANGUL SYLLABLE RIEUL WEO MIEUM
+0x8FC5 0xB915 #HANGUL SYLLABLE RIEUL WEO PIEUP
+0x8FC6 0xB916 #HANGUL SYLLABLE RIEUL WEO PIEUPSIOS
+0x8FC7 0xB917 #HANGUL SYLLABLE RIEUL WEO SIOS
+0x8FC8 0xB919 #HANGUL SYLLABLE RIEUL WEO IEUNG
+0x8FC9 0xB91A #HANGUL SYLLABLE RIEUL WEO CIEUC
+0x8FCA 0xB91B #HANGUL SYLLABLE RIEUL WEO CHIEUCH
+0x8FCB 0xB91C #HANGUL SYLLABLE RIEUL WEO KHIEUKH
+0x8FCC 0xB91D #HANGUL SYLLABLE RIEUL WEO THIEUTH
+0x8FCD 0xB91E #HANGUL SYLLABLE RIEUL WEO PHIEUPH
+0x8FCE 0xB91F #HANGUL SYLLABLE RIEUL WEO HIEUH
+0x8FCF 0xB921 #HANGUL SYLLABLE RIEUL WE KIYEOK
+0x8FD0 0xB922 #HANGUL SYLLABLE RIEUL WE SSANGKIYEOK
+0x8FD1 0xB923 #HANGUL SYLLABLE RIEUL WE KIYEOKSIOS
+0x8FD2 0xB924 #HANGUL SYLLABLE RIEUL WE NIEUN
+0x8FD3 0xB925 #HANGUL SYLLABLE RIEUL WE NIEUNCIEUC
+0x8FD4 0xB926 #HANGUL SYLLABLE RIEUL WE NIEUNHIEUH
+0x8FD5 0xB927 #HANGUL SYLLABLE RIEUL WE TIKEUT
+0x8FD6 0xB928 #HANGUL SYLLABLE RIEUL WE RIEUL
+0x8FD7 0xB929 #HANGUL SYLLABLE RIEUL WE RIEULKIYEOK
+0x8FD8 0xB92A #HANGUL SYLLABLE RIEUL WE RIEULMIEUM
+0x8FD9 0xB92B #HANGUL SYLLABLE RIEUL WE RIEULPIEUP
+0x8FDA 0xB92C #HANGUL SYLLABLE RIEUL WE RIEULSIOS
+0x8FDB 0xB92D #HANGUL SYLLABLE RIEUL WE RIEULTHIEUTH
+0x8FDC 0xB92E #HANGUL SYLLABLE RIEUL WE RIEULPHIEUPH
+0x8FDD 0xB92F #HANGUL SYLLABLE RIEUL WE RIEULHIEUH
+0x8FDE 0xB930 #HANGUL SYLLABLE RIEUL WE MIEUM
+0x8FDF 0xB931 #HANGUL SYLLABLE RIEUL WE PIEUP
+0x8FE0 0xB932 #HANGUL SYLLABLE RIEUL WE PIEUPSIOS
+0x8FE1 0xB933 #HANGUL SYLLABLE RIEUL WE SIOS
+0x8FE2 0xB934 #HANGUL SYLLABLE RIEUL WE SSANGSIOS
+0x8FE3 0xB935 #HANGUL SYLLABLE RIEUL WE IEUNG
+0x8FE4 0xB936 #HANGUL SYLLABLE RIEUL WE CIEUC
+0x8FE5 0xB937 #HANGUL SYLLABLE RIEUL WE CHIEUCH
+0x8FE6 0xB938 #HANGUL SYLLABLE RIEUL WE KHIEUKH
+0x8FE7 0xB939 #HANGUL SYLLABLE RIEUL WE THIEUTH
+0x8FE8 0xB93A #HANGUL SYLLABLE RIEUL WE PHIEUPH
+0x8FE9 0xB93B #HANGUL SYLLABLE RIEUL WE HIEUH
+0x8FEA 0xB93E #HANGUL SYLLABLE RIEUL WI SSANGKIYEOK
+0x8FEB 0xB93F #HANGUL SYLLABLE RIEUL WI KIYEOKSIOS
+0x8FEC 0xB941 #HANGUL SYLLABLE RIEUL WI NIEUNCIEUC
+0x8FED 0xB942 #HANGUL SYLLABLE RIEUL WI NIEUNHIEUH
+0x8FEE 0xB943 #HANGUL SYLLABLE RIEUL WI TIKEUT
+0x8FEF 0xB945 #HANGUL SYLLABLE RIEUL WI RIEULKIYEOK
+0x8FF0 0xB946 #HANGUL SYLLABLE RIEUL WI RIEULMIEUM
+0x8FF1 0xB947 #HANGUL SYLLABLE RIEUL WI RIEULPIEUP
+0x8FF2 0xB948 #HANGUL SYLLABLE RIEUL WI RIEULSIOS
+0x8FF3 0xB949 #HANGUL SYLLABLE RIEUL WI RIEULTHIEUTH
+0x8FF4 0xB94A #HANGUL SYLLABLE RIEUL WI RIEULPHIEUPH
+0x8FF5 0xB94B #HANGUL SYLLABLE RIEUL WI RIEULHIEUH
+0x8FF6 0xB94D #HANGUL SYLLABLE RIEUL WI PIEUP
+0x8FF7 0xB94E #HANGUL SYLLABLE RIEUL WI PIEUPSIOS
+0x8FF8 0xB950 #HANGUL SYLLABLE RIEUL WI SSANGSIOS
+0x8FF9 0xB952 #HANGUL SYLLABLE RIEUL WI CIEUC
+0x8FFA 0xB953 #HANGUL SYLLABLE RIEUL WI CHIEUCH
+0x8FFB 0xB954 #HANGUL SYLLABLE RIEUL WI KHIEUKH
+0x8FFC 0xB955 #HANGUL SYLLABLE RIEUL WI THIEUTH
+0x8FFD 0xB956 #HANGUL SYLLABLE RIEUL WI PHIEUPH
+0x8FFE 0xB957 #HANGUL SYLLABLE RIEUL WI HIEUH
+0x9041 0xB95A #HANGUL SYLLABLE RIEUL YU SSANGKIYEOK
+0x9042 0xB95B #HANGUL SYLLABLE RIEUL YU KIYEOKSIOS
+0x9043 0xB95D #HANGUL SYLLABLE RIEUL YU NIEUNCIEUC
+0x9044 0xB95E #HANGUL SYLLABLE RIEUL YU NIEUNHIEUH
+0x9045 0xB95F #HANGUL SYLLABLE RIEUL YU TIKEUT
+0x9046 0xB961 #HANGUL SYLLABLE RIEUL YU RIEULKIYEOK
+0x9047 0xB962 #HANGUL SYLLABLE RIEUL YU RIEULMIEUM
+0x9048 0xB963 #HANGUL SYLLABLE RIEUL YU RIEULPIEUP
+0x9049 0xB964 #HANGUL SYLLABLE RIEUL YU RIEULSIOS
+0x904A 0xB965 #HANGUL SYLLABLE RIEUL YU RIEULTHIEUTH
+0x904B 0xB966 #HANGUL SYLLABLE RIEUL YU RIEULPHIEUPH
+0x904C 0xB967 #HANGUL SYLLABLE RIEUL YU RIEULHIEUH
+0x904D 0xB96A #HANGUL SYLLABLE RIEUL YU PIEUPSIOS
+0x904E 0xB96C #HANGUL SYLLABLE RIEUL YU SSANGSIOS
+0x904F 0xB96E #HANGUL SYLLABLE RIEUL YU CIEUC
+0x9050 0xB96F #HANGUL SYLLABLE RIEUL YU CHIEUCH
+0x9051 0xB970 #HANGUL SYLLABLE RIEUL YU KHIEUKH
+0x9052 0xB971 #HANGUL SYLLABLE RIEUL YU THIEUTH
+0x9053 0xB972 #HANGUL SYLLABLE RIEUL YU PHIEUPH
+0x9054 0xB973 #HANGUL SYLLABLE RIEUL YU HIEUH
+0x9055 0xB976 #HANGUL SYLLABLE RIEUL EU SSANGKIYEOK
+0x9056 0xB977 #HANGUL SYLLABLE RIEUL EU KIYEOKSIOS
+0x9057 0xB979 #HANGUL SYLLABLE RIEUL EU NIEUNCIEUC
+0x9058 0xB97A #HANGUL SYLLABLE RIEUL EU NIEUNHIEUH
+0x9059 0xB97B #HANGUL SYLLABLE RIEUL EU TIKEUT
+0x905A 0xB97D #HANGUL SYLLABLE RIEUL EU RIEULKIYEOK
+0x9061 0xB97E #HANGUL SYLLABLE RIEUL EU RIEULMIEUM
+0x9062 0xB97F #HANGUL SYLLABLE RIEUL EU RIEULPIEUP
+0x9063 0xB980 #HANGUL SYLLABLE RIEUL EU RIEULSIOS
+0x9064 0xB981 #HANGUL SYLLABLE RIEUL EU RIEULTHIEUTH
+0x9065 0xB982 #HANGUL SYLLABLE RIEUL EU RIEULPHIEUPH
+0x9066 0xB983 #HANGUL SYLLABLE RIEUL EU RIEULHIEUH
+0x9067 0xB986 #HANGUL SYLLABLE RIEUL EU PIEUPSIOS
+0x9068 0xB988 #HANGUL SYLLABLE RIEUL EU SSANGSIOS
+0x9069 0xB98B #HANGUL SYLLABLE RIEUL EU CHIEUCH
+0x906A 0xB98C #HANGUL SYLLABLE RIEUL EU KHIEUKH
+0x906B 0xB98F #HANGUL SYLLABLE RIEUL EU HIEUH
+0x906C 0xB990 #HANGUL SYLLABLE RIEUL YI
+0x906D 0xB991 #HANGUL SYLLABLE RIEUL YI KIYEOK
+0x906E 0xB992 #HANGUL SYLLABLE RIEUL YI SSANGKIYEOK
+0x906F 0xB993 #HANGUL SYLLABLE RIEUL YI KIYEOKSIOS
+0x9070 0xB994 #HANGUL SYLLABLE RIEUL YI NIEUN
+0x9071 0xB995 #HANGUL SYLLABLE RIEUL YI NIEUNCIEUC
+0x9072 0xB996 #HANGUL SYLLABLE RIEUL YI NIEUNHIEUH
+0x9073 0xB997 #HANGUL SYLLABLE RIEUL YI TIKEUT
+0x9074 0xB998 #HANGUL SYLLABLE RIEUL YI RIEUL
+0x9075 0xB999 #HANGUL SYLLABLE RIEUL YI RIEULKIYEOK
+0x9076 0xB99A #HANGUL SYLLABLE RIEUL YI RIEULMIEUM
+0x9077 0xB99B #HANGUL SYLLABLE RIEUL YI RIEULPIEUP
+0x9078 0xB99C #HANGUL SYLLABLE RIEUL YI RIEULSIOS
+0x9079 0xB99D #HANGUL SYLLABLE RIEUL YI RIEULTHIEUTH
+0x907A 0xB99E #HANGUL SYLLABLE RIEUL YI RIEULPHIEUPH
+0x9081 0xB99F #HANGUL SYLLABLE RIEUL YI RIEULHIEUH
+0x9082 0xB9A0 #HANGUL SYLLABLE RIEUL YI MIEUM
+0x9083 0xB9A1 #HANGUL SYLLABLE RIEUL YI PIEUP
+0x9084 0xB9A2 #HANGUL SYLLABLE RIEUL YI PIEUPSIOS
+0x9085 0xB9A3 #HANGUL SYLLABLE RIEUL YI SIOS
+0x9086 0xB9A4 #HANGUL SYLLABLE RIEUL YI SSANGSIOS
+0x9087 0xB9A5 #HANGUL SYLLABLE RIEUL YI IEUNG
+0x9088 0xB9A6 #HANGUL SYLLABLE RIEUL YI CIEUC
+0x9089 0xB9A7 #HANGUL SYLLABLE RIEUL YI CHIEUCH
+0x908A 0xB9A8 #HANGUL SYLLABLE RIEUL YI KHIEUKH
+0x908B 0xB9A9 #HANGUL SYLLABLE RIEUL YI THIEUTH
+0x908C 0xB9AA #HANGUL SYLLABLE RIEUL YI PHIEUPH
+0x908D 0xB9AB #HANGUL SYLLABLE RIEUL YI HIEUH
+0x908E 0xB9AE #HANGUL SYLLABLE RIEUL I SSANGKIYEOK
+0x908F 0xB9AF #HANGUL SYLLABLE RIEUL I KIYEOKSIOS
+0x9090 0xB9B1 #HANGUL SYLLABLE RIEUL I NIEUNCIEUC
+0x9091 0xB9B2 #HANGUL SYLLABLE RIEUL I NIEUNHIEUH
+0x9092 0xB9B3 #HANGUL SYLLABLE RIEUL I TIKEUT
+0x9093 0xB9B5 #HANGUL SYLLABLE RIEUL I RIEULKIYEOK
+0x9094 0xB9B6 #HANGUL SYLLABLE RIEUL I RIEULMIEUM
+0x9095 0xB9B7 #HANGUL SYLLABLE RIEUL I RIEULPIEUP
+0x9096 0xB9B8 #HANGUL SYLLABLE RIEUL I RIEULSIOS
+0x9097 0xB9B9 #HANGUL SYLLABLE RIEUL I RIEULTHIEUTH
+0x9098 0xB9BA #HANGUL SYLLABLE RIEUL I RIEULPHIEUPH
+0x9099 0xB9BB #HANGUL SYLLABLE RIEUL I RIEULHIEUH
+0x909A 0xB9BE #HANGUL SYLLABLE RIEUL I PIEUPSIOS
+0x909B 0xB9C0 #HANGUL SYLLABLE RIEUL I SSANGSIOS
+0x909C 0xB9C2 #HANGUL SYLLABLE RIEUL I CIEUC
+0x909D 0xB9C3 #HANGUL SYLLABLE RIEUL I CHIEUCH
+0x909E 0xB9C4 #HANGUL SYLLABLE RIEUL I KHIEUKH
+0x909F 0xB9C5 #HANGUL SYLLABLE RIEUL I THIEUTH
+0x90A0 0xB9C6 #HANGUL SYLLABLE RIEUL I PHIEUPH
+0x90A1 0xB9C7 #HANGUL SYLLABLE RIEUL I HIEUH
+0x90A2 0xB9CA #HANGUL SYLLABLE MIEUM A SSANGKIYEOK
+0x90A3 0xB9CB #HANGUL SYLLABLE MIEUM A KIYEOKSIOS
+0x90A4 0xB9CD #HANGUL SYLLABLE MIEUM A NIEUNCIEUC
+0x90A5 0xB9D3 #HANGUL SYLLABLE MIEUM A RIEULPIEUP
+0x90A6 0xB9D4 #HANGUL SYLLABLE MIEUM A RIEULSIOS
+0x90A7 0xB9D5 #HANGUL SYLLABLE MIEUM A RIEULTHIEUTH
+0x90A8 0xB9D6 #HANGUL SYLLABLE MIEUM A RIEULPHIEUPH
+0x90A9 0xB9D7 #HANGUL SYLLABLE MIEUM A RIEULHIEUH
+0x90AA 0xB9DA #HANGUL SYLLABLE MIEUM A PIEUPSIOS
+0x90AB 0xB9DC #HANGUL SYLLABLE MIEUM A SSANGSIOS
+0x90AC 0xB9DF #HANGUL SYLLABLE MIEUM A CHIEUCH
+0x90AD 0xB9E0 #HANGUL SYLLABLE MIEUM A KHIEUKH
+0x90AE 0xB9E2 #HANGUL SYLLABLE MIEUM A PHIEUPH
+0x90AF 0xB9E6 #HANGUL SYLLABLE MIEUM AE SSANGKIYEOK
+0x90B0 0xB9E7 #HANGUL SYLLABLE MIEUM AE KIYEOKSIOS
+0x90B1 0xB9E9 #HANGUL SYLLABLE MIEUM AE NIEUNCIEUC
+0x90B2 0xB9EA #HANGUL SYLLABLE MIEUM AE NIEUNHIEUH
+0x90B3 0xB9EB #HANGUL SYLLABLE MIEUM AE TIKEUT
+0x90B4 0xB9ED #HANGUL SYLLABLE MIEUM AE RIEULKIYEOK
+0x90B5 0xB9EE #HANGUL SYLLABLE MIEUM AE RIEULMIEUM
+0x90B6 0xB9EF #HANGUL SYLLABLE MIEUM AE RIEULPIEUP
+0x90B7 0xB9F0 #HANGUL SYLLABLE MIEUM AE RIEULSIOS
+0x90B8 0xB9F1 #HANGUL SYLLABLE MIEUM AE RIEULTHIEUTH
+0x90B9 0xB9F2 #HANGUL SYLLABLE MIEUM AE RIEULPHIEUPH
+0x90BA 0xB9F3 #HANGUL SYLLABLE MIEUM AE RIEULHIEUH
+0x90BB 0xB9F6 #HANGUL SYLLABLE MIEUM AE PIEUPSIOS
+0x90BC 0xB9FB #HANGUL SYLLABLE MIEUM AE CHIEUCH
+0x90BD 0xB9FC #HANGUL SYLLABLE MIEUM AE KHIEUKH
+0x90BE 0xB9FD #HANGUL SYLLABLE MIEUM AE THIEUTH
+0x90BF 0xB9FE #HANGUL SYLLABLE MIEUM AE PHIEUPH
+0x90C0 0xB9FF #HANGUL SYLLABLE MIEUM AE HIEUH
+0x90C1 0xBA02 #HANGUL SYLLABLE MIEUM YA SSANGKIYEOK
+0x90C2 0xBA03 #HANGUL SYLLABLE MIEUM YA KIYEOKSIOS
+0x90C3 0xBA04 #HANGUL SYLLABLE MIEUM YA NIEUN
+0x90C4 0xBA05 #HANGUL SYLLABLE MIEUM YA NIEUNCIEUC
+0x90C5 0xBA06 #HANGUL SYLLABLE MIEUM YA NIEUNHIEUH
+0x90C6 0xBA07 #HANGUL SYLLABLE MIEUM YA TIKEUT
+0x90C7 0xBA09 #HANGUL SYLLABLE MIEUM YA RIEULKIYEOK
+0x90C8 0xBA0A #HANGUL SYLLABLE MIEUM YA RIEULMIEUM
+0x90C9 0xBA0B #HANGUL SYLLABLE MIEUM YA RIEULPIEUP
+0x90CA 0xBA0C #HANGUL SYLLABLE MIEUM YA RIEULSIOS
+0x90CB 0xBA0D #HANGUL SYLLABLE MIEUM YA RIEULTHIEUTH
+0x90CC 0xBA0E #HANGUL SYLLABLE MIEUM YA RIEULPHIEUPH
+0x90CD 0xBA0F #HANGUL SYLLABLE MIEUM YA RIEULHIEUH
+0x90CE 0xBA10 #HANGUL SYLLABLE MIEUM YA MIEUM
+0x90CF 0xBA11 #HANGUL SYLLABLE MIEUM YA PIEUP
+0x90D0 0xBA12 #HANGUL SYLLABLE MIEUM YA PIEUPSIOS
+0x90D1 0xBA13 #HANGUL SYLLABLE MIEUM YA SIOS
+0x90D2 0xBA14 #HANGUL SYLLABLE MIEUM YA SSANGSIOS
+0x90D3 0xBA16 #HANGUL SYLLABLE MIEUM YA CIEUC
+0x90D4 0xBA17 #HANGUL SYLLABLE MIEUM YA CHIEUCH
+0x90D5 0xBA18 #HANGUL SYLLABLE MIEUM YA KHIEUKH
+0x90D6 0xBA19 #HANGUL SYLLABLE MIEUM YA THIEUTH
+0x90D7 0xBA1A #HANGUL SYLLABLE MIEUM YA PHIEUPH
+0x90D8 0xBA1B #HANGUL SYLLABLE MIEUM YA HIEUH
+0x90D9 0xBA1C #HANGUL SYLLABLE MIEUM YAE
+0x90DA 0xBA1D #HANGUL SYLLABLE MIEUM YAE KIYEOK
+0x90DB 0xBA1E #HANGUL SYLLABLE MIEUM YAE SSANGKIYEOK
+0x90DC 0xBA1F #HANGUL SYLLABLE MIEUM YAE KIYEOKSIOS
+0x90DD 0xBA20 #HANGUL SYLLABLE MIEUM YAE NIEUN
+0x90DE 0xBA21 #HANGUL SYLLABLE MIEUM YAE NIEUNCIEUC
+0x90DF 0xBA22 #HANGUL SYLLABLE MIEUM YAE NIEUNHIEUH
+0x90E0 0xBA23 #HANGUL SYLLABLE MIEUM YAE TIKEUT
+0x90E1 0xBA24 #HANGUL SYLLABLE MIEUM YAE RIEUL
+0x90E2 0xBA25 #HANGUL SYLLABLE MIEUM YAE RIEULKIYEOK
+0x90E3 0xBA26 #HANGUL SYLLABLE MIEUM YAE RIEULMIEUM
+0x90E4 0xBA27 #HANGUL SYLLABLE MIEUM YAE RIEULPIEUP
+0x90E5 0xBA28 #HANGUL SYLLABLE MIEUM YAE RIEULSIOS
+0x90E6 0xBA29 #HANGUL SYLLABLE MIEUM YAE RIEULTHIEUTH
+0x90E7 0xBA2A #HANGUL SYLLABLE MIEUM YAE RIEULPHIEUPH
+0x90E8 0xBA2B #HANGUL SYLLABLE MIEUM YAE RIEULHIEUH
+0x90E9 0xBA2C #HANGUL SYLLABLE MIEUM YAE MIEUM
+0x90EA 0xBA2D #HANGUL SYLLABLE MIEUM YAE PIEUP
+0x90EB 0xBA2E #HANGUL SYLLABLE MIEUM YAE PIEUPSIOS
+0x90EC 0xBA2F #HANGUL SYLLABLE MIEUM YAE SIOS
+0x90ED 0xBA30 #HANGUL SYLLABLE MIEUM YAE SSANGSIOS
+0x90EE 0xBA31 #HANGUL SYLLABLE MIEUM YAE IEUNG
+0x90EF 0xBA32 #HANGUL SYLLABLE MIEUM YAE CIEUC
+0x90F0 0xBA33 #HANGUL SYLLABLE MIEUM YAE CHIEUCH
+0x90F1 0xBA34 #HANGUL SYLLABLE MIEUM YAE KHIEUKH
+0x90F2 0xBA35 #HANGUL SYLLABLE MIEUM YAE THIEUTH
+0x90F3 0xBA36 #HANGUL SYLLABLE MIEUM YAE PHIEUPH
+0x90F4 0xBA37 #HANGUL SYLLABLE MIEUM YAE HIEUH
+0x90F5 0xBA3A #HANGUL SYLLABLE MIEUM EO SSANGKIYEOK
+0x90F6 0xBA3B #HANGUL SYLLABLE MIEUM EO KIYEOKSIOS
+0x90F7 0xBA3D #HANGUL SYLLABLE MIEUM EO NIEUNCIEUC
+0x90F8 0xBA3E #HANGUL SYLLABLE MIEUM EO NIEUNHIEUH
+0x90F9 0xBA3F #HANGUL SYLLABLE MIEUM EO TIKEUT
+0x90FA 0xBA41 #HANGUL SYLLABLE MIEUM EO RIEULKIYEOK
+0x90FB 0xBA43 #HANGUL SYLLABLE MIEUM EO RIEULPIEUP
+0x90FC 0xBA44 #HANGUL SYLLABLE MIEUM EO RIEULSIOS
+0x90FD 0xBA45 #HANGUL SYLLABLE MIEUM EO RIEULTHIEUTH
+0x90FE 0xBA46 #HANGUL SYLLABLE MIEUM EO RIEULPHIEUPH
+0x9141 0xBA47 #HANGUL SYLLABLE MIEUM EO RIEULHIEUH
+0x9142 0xBA4A #HANGUL SYLLABLE MIEUM EO PIEUPSIOS
+0x9143 0xBA4C #HANGUL SYLLABLE MIEUM EO SSANGSIOS
+0x9144 0xBA4F #HANGUL SYLLABLE MIEUM EO CHIEUCH
+0x9145 0xBA50 #HANGUL SYLLABLE MIEUM EO KHIEUKH
+0x9146 0xBA51 #HANGUL SYLLABLE MIEUM EO THIEUTH
+0x9147 0xBA52 #HANGUL SYLLABLE MIEUM EO PHIEUPH
+0x9148 0xBA56 #HANGUL SYLLABLE MIEUM E SSANGKIYEOK
+0x9149 0xBA57 #HANGUL SYLLABLE MIEUM E KIYEOKSIOS
+0x914A 0xBA59 #HANGUL SYLLABLE MIEUM E NIEUNCIEUC
+0x914B 0xBA5A #HANGUL SYLLABLE MIEUM E NIEUNHIEUH
+0x914C 0xBA5B #HANGUL SYLLABLE MIEUM E TIKEUT
+0x914D 0xBA5D #HANGUL SYLLABLE MIEUM E RIEULKIYEOK
+0x914E 0xBA5E #HANGUL SYLLABLE MIEUM E RIEULMIEUM
+0x914F 0xBA5F #HANGUL SYLLABLE MIEUM E RIEULPIEUP
+0x9150 0xBA60 #HANGUL SYLLABLE MIEUM E RIEULSIOS
+0x9151 0xBA61 #HANGUL SYLLABLE MIEUM E RIEULTHIEUTH
+0x9152 0xBA62 #HANGUL SYLLABLE MIEUM E RIEULPHIEUPH
+0x9153 0xBA63 #HANGUL SYLLABLE MIEUM E RIEULHIEUH
+0x9154 0xBA66 #HANGUL SYLLABLE MIEUM E PIEUPSIOS
+0x9155 0xBA6A #HANGUL SYLLABLE MIEUM E CIEUC
+0x9156 0xBA6B #HANGUL SYLLABLE MIEUM E CHIEUCH
+0x9157 0xBA6C #HANGUL SYLLABLE MIEUM E KHIEUKH
+0x9158 0xBA6D #HANGUL SYLLABLE MIEUM E THIEUTH
+0x9159 0xBA6E #HANGUL SYLLABLE MIEUM E PHIEUPH
+0x915A 0xBA6F #HANGUL SYLLABLE MIEUM E HIEUH
+0x9161 0xBA72 #HANGUL SYLLABLE MIEUM YEO SSANGKIYEOK
+0x9162 0xBA73 #HANGUL SYLLABLE MIEUM YEO KIYEOKSIOS
+0x9163 0xBA75 #HANGUL SYLLABLE MIEUM YEO NIEUNCIEUC
+0x9164 0xBA76 #HANGUL SYLLABLE MIEUM YEO NIEUNHIEUH
+0x9165 0xBA77 #HANGUL SYLLABLE MIEUM YEO TIKEUT
+0x9166 0xBA79 #HANGUL SYLLABLE MIEUM YEO RIEULKIYEOK
+0x9167 0xBA7A #HANGUL SYLLABLE MIEUM YEO RIEULMIEUM
+0x9168 0xBA7B #HANGUL SYLLABLE MIEUM YEO RIEULPIEUP
+0x9169 0xBA7C #HANGUL SYLLABLE MIEUM YEO RIEULSIOS
+0x916A 0xBA7D #HANGUL SYLLABLE MIEUM YEO RIEULTHIEUTH
+0x916B 0xBA7E #HANGUL SYLLABLE MIEUM YEO RIEULPHIEUPH
+0x916C 0xBA7F #HANGUL SYLLABLE MIEUM YEO RIEULHIEUH
+0x916D 0xBA80 #HANGUL SYLLABLE MIEUM YEO MIEUM
+0x916E 0xBA81 #HANGUL SYLLABLE MIEUM YEO PIEUP
+0x916F 0xBA82 #HANGUL SYLLABLE MIEUM YEO PIEUPSIOS
+0x9170 0xBA86 #HANGUL SYLLABLE MIEUM YEO CIEUC
+0x9171 0xBA88 #HANGUL SYLLABLE MIEUM YEO KHIEUKH
+0x9172 0xBA89 #HANGUL SYLLABLE MIEUM YEO THIEUTH
+0x9173 0xBA8A #HANGUL SYLLABLE MIEUM YEO PHIEUPH
+0x9174 0xBA8B #HANGUL SYLLABLE MIEUM YEO HIEUH
+0x9175 0xBA8D #HANGUL SYLLABLE MIEUM YE KIYEOK
+0x9176 0xBA8E #HANGUL SYLLABLE MIEUM YE SSANGKIYEOK
+0x9177 0xBA8F #HANGUL SYLLABLE MIEUM YE KIYEOKSIOS
+0x9178 0xBA90 #HANGUL SYLLABLE MIEUM YE NIEUN
+0x9179 0xBA91 #HANGUL SYLLABLE MIEUM YE NIEUNCIEUC
+0x917A 0xBA92 #HANGUL SYLLABLE MIEUM YE NIEUNHIEUH
+0x9181 0xBA93 #HANGUL SYLLABLE MIEUM YE TIKEUT
+0x9182 0xBA94 #HANGUL SYLLABLE MIEUM YE RIEUL
+0x9183 0xBA95 #HANGUL SYLLABLE MIEUM YE RIEULKIYEOK
+0x9184 0xBA96 #HANGUL SYLLABLE MIEUM YE RIEULMIEUM
+0x9185 0xBA97 #HANGUL SYLLABLE MIEUM YE RIEULPIEUP
+0x9186 0xBA98 #HANGUL SYLLABLE MIEUM YE RIEULSIOS
+0x9187 0xBA99 #HANGUL SYLLABLE MIEUM YE RIEULTHIEUTH
+0x9188 0xBA9A #HANGUL SYLLABLE MIEUM YE RIEULPHIEUPH
+0x9189 0xBA9B #HANGUL SYLLABLE MIEUM YE RIEULHIEUH
+0x918A 0xBA9C #HANGUL SYLLABLE MIEUM YE MIEUM
+0x918B 0xBA9D #HANGUL SYLLABLE MIEUM YE PIEUP
+0x918C 0xBA9E #HANGUL SYLLABLE MIEUM YE PIEUPSIOS
+0x918D 0xBA9F #HANGUL SYLLABLE MIEUM YE SIOS
+0x918E 0xBAA0 #HANGUL SYLLABLE MIEUM YE SSANGSIOS
+0x918F 0xBAA1 #HANGUL SYLLABLE MIEUM YE IEUNG
+0x9190 0xBAA2 #HANGUL SYLLABLE MIEUM YE CIEUC
+0x9191 0xBAA3 #HANGUL SYLLABLE MIEUM YE CHIEUCH
+0x9192 0xBAA4 #HANGUL SYLLABLE MIEUM YE KHIEUKH
+0x9193 0xBAA5 #HANGUL SYLLABLE MIEUM YE THIEUTH
+0x9194 0xBAA6 #HANGUL SYLLABLE MIEUM YE PHIEUPH
+0x9195 0xBAA7 #HANGUL SYLLABLE MIEUM YE HIEUH
+0x9196 0xBAAA #HANGUL SYLLABLE MIEUM O SSANGKIYEOK
+0x9197 0xBAAD #HANGUL SYLLABLE MIEUM O NIEUNCIEUC
+0x9198 0xBAAE #HANGUL SYLLABLE MIEUM O NIEUNHIEUH
+0x9199 0xBAAF #HANGUL SYLLABLE MIEUM O TIKEUT
+0x919A 0xBAB1 #HANGUL SYLLABLE MIEUM O RIEULKIYEOK
+0x919B 0xBAB3 #HANGUL SYLLABLE MIEUM O RIEULPIEUP
+0x919C 0xBAB4 #HANGUL SYLLABLE MIEUM O RIEULSIOS
+0x919D 0xBAB5 #HANGUL SYLLABLE MIEUM O RIEULTHIEUTH
+0x919E 0xBAB6 #HANGUL SYLLABLE MIEUM O RIEULPHIEUPH
+0x919F 0xBAB7 #HANGUL SYLLABLE MIEUM O RIEULHIEUH
+0x91A0 0xBABA #HANGUL SYLLABLE MIEUM O PIEUPSIOS
+0x91A1 0xBABC #HANGUL SYLLABLE MIEUM O SSANGSIOS
+0x91A2 0xBABE #HANGUL SYLLABLE MIEUM O CIEUC
+0x91A3 0xBABF #HANGUL SYLLABLE MIEUM O CHIEUCH
+0x91A4 0xBAC0 #HANGUL SYLLABLE MIEUM O KHIEUKH
+0x91A5 0xBAC1 #HANGUL SYLLABLE MIEUM O THIEUTH
+0x91A6 0xBAC2 #HANGUL SYLLABLE MIEUM O PHIEUPH
+0x91A7 0xBAC3 #HANGUL SYLLABLE MIEUM O HIEUH
+0x91A8 0xBAC5 #HANGUL SYLLABLE MIEUM WA KIYEOK
+0x91A9 0xBAC6 #HANGUL SYLLABLE MIEUM WA SSANGKIYEOK
+0x91AA 0xBAC7 #HANGUL SYLLABLE MIEUM WA KIYEOKSIOS
+0x91AB 0xBAC9 #HANGUL SYLLABLE MIEUM WA NIEUNCIEUC
+0x91AC 0xBACA #HANGUL SYLLABLE MIEUM WA NIEUNHIEUH
+0x91AD 0xBACB #HANGUL SYLLABLE MIEUM WA TIKEUT
+0x91AE 0xBACC #HANGUL SYLLABLE MIEUM WA RIEUL
+0x91AF 0xBACD #HANGUL SYLLABLE MIEUM WA RIEULKIYEOK
+0x91B0 0xBACE #HANGUL SYLLABLE MIEUM WA RIEULMIEUM
+0x91B1 0xBACF #HANGUL SYLLABLE MIEUM WA RIEULPIEUP
+0x91B2 0xBAD0 #HANGUL SYLLABLE MIEUM WA RIEULSIOS
+0x91B3 0xBAD1 #HANGUL SYLLABLE MIEUM WA RIEULTHIEUTH
+0x91B4 0xBAD2 #HANGUL SYLLABLE MIEUM WA RIEULPHIEUPH
+0x91B5 0xBAD3 #HANGUL SYLLABLE MIEUM WA RIEULHIEUH
+0x91B6 0xBAD4 #HANGUL SYLLABLE MIEUM WA MIEUM
+0x91B7 0xBAD5 #HANGUL SYLLABLE MIEUM WA PIEUP
+0x91B8 0xBAD6 #HANGUL SYLLABLE MIEUM WA PIEUPSIOS
+0x91B9 0xBAD7 #HANGUL SYLLABLE MIEUM WA SIOS
+0x91BA 0xBADA #HANGUL SYLLABLE MIEUM WA CIEUC
+0x91BB 0xBADB #HANGUL SYLLABLE MIEUM WA CHIEUCH
+0x91BC 0xBADC #HANGUL SYLLABLE MIEUM WA KHIEUKH
+0x91BD 0xBADD #HANGUL SYLLABLE MIEUM WA THIEUTH
+0x91BE 0xBADE #HANGUL SYLLABLE MIEUM WA PHIEUPH
+0x91BF 0xBADF #HANGUL SYLLABLE MIEUM WA HIEUH
+0x91C0 0xBAE0 #HANGUL SYLLABLE MIEUM WAE
+0x91C1 0xBAE1 #HANGUL SYLLABLE MIEUM WAE KIYEOK
+0x91C2 0xBAE2 #HANGUL SYLLABLE MIEUM WAE SSANGKIYEOK
+0x91C3 0xBAE3 #HANGUL SYLLABLE MIEUM WAE KIYEOKSIOS
+0x91C4 0xBAE4 #HANGUL SYLLABLE MIEUM WAE NIEUN
+0x91C5 0xBAE5 #HANGUL SYLLABLE MIEUM WAE NIEUNCIEUC
+0x91C6 0xBAE6 #HANGUL SYLLABLE MIEUM WAE NIEUNHIEUH
+0x91C7 0xBAE7 #HANGUL SYLLABLE MIEUM WAE TIKEUT
+0x91C8 0xBAE8 #HANGUL SYLLABLE MIEUM WAE RIEUL
+0x91C9 0xBAE9 #HANGUL SYLLABLE MIEUM WAE RIEULKIYEOK
+0x91CA 0xBAEA #HANGUL SYLLABLE MIEUM WAE RIEULMIEUM
+0x91CB 0xBAEB #HANGUL SYLLABLE MIEUM WAE RIEULPIEUP
+0x91CC 0xBAEC #HANGUL SYLLABLE MIEUM WAE RIEULSIOS
+0x91CD 0xBAED #HANGUL SYLLABLE MIEUM WAE RIEULTHIEUTH
+0x91CE 0xBAEE #HANGUL SYLLABLE MIEUM WAE RIEULPHIEUPH
+0x91CF 0xBAEF #HANGUL SYLLABLE MIEUM WAE RIEULHIEUH
+0x91D0 0xBAF0 #HANGUL SYLLABLE MIEUM WAE MIEUM
+0x91D1 0xBAF1 #HANGUL SYLLABLE MIEUM WAE PIEUP
+0x91D2 0xBAF2 #HANGUL SYLLABLE MIEUM WAE PIEUPSIOS
+0x91D3 0xBAF3 #HANGUL SYLLABLE MIEUM WAE SIOS
+0x91D4 0xBAF4 #HANGUL SYLLABLE MIEUM WAE SSANGSIOS
+0x91D5 0xBAF5 #HANGUL SYLLABLE MIEUM WAE IEUNG
+0x91D6 0xBAF6 #HANGUL SYLLABLE MIEUM WAE CIEUC
+0x91D7 0xBAF7 #HANGUL SYLLABLE MIEUM WAE CHIEUCH
+0x91D8 0xBAF8 #HANGUL SYLLABLE MIEUM WAE KHIEUKH
+0x91D9 0xBAF9 #HANGUL SYLLABLE MIEUM WAE THIEUTH
+0x91DA 0xBAFA #HANGUL SYLLABLE MIEUM WAE PHIEUPH
+0x91DB 0xBAFB #HANGUL SYLLABLE MIEUM WAE HIEUH
+0x91DC 0xBAFD #HANGUL SYLLABLE MIEUM OE KIYEOK
+0x91DD 0xBAFE #HANGUL SYLLABLE MIEUM OE SSANGKIYEOK
+0x91DE 0xBAFF #HANGUL SYLLABLE MIEUM OE KIYEOKSIOS
+0x91DF 0xBB01 #HANGUL SYLLABLE MIEUM OE NIEUNCIEUC
+0x91E0 0xBB02 #HANGUL SYLLABLE MIEUM OE NIEUNHIEUH
+0x91E1 0xBB03 #HANGUL SYLLABLE MIEUM OE TIKEUT
+0x91E2 0xBB05 #HANGUL SYLLABLE MIEUM OE RIEULKIYEOK
+0x91E3 0xBB06 #HANGUL SYLLABLE MIEUM OE RIEULMIEUM
+0x91E4 0xBB07 #HANGUL SYLLABLE MIEUM OE RIEULPIEUP
+0x91E5 0xBB08 #HANGUL SYLLABLE MIEUM OE RIEULSIOS
+0x91E6 0xBB09 #HANGUL SYLLABLE MIEUM OE RIEULTHIEUTH
+0x91E7 0xBB0A #HANGUL SYLLABLE MIEUM OE RIEULPHIEUPH
+0x91E8 0xBB0B #HANGUL SYLLABLE MIEUM OE RIEULHIEUH
+0x91E9 0xBB0C #HANGUL SYLLABLE MIEUM OE MIEUM
+0x91EA 0xBB0E #HANGUL SYLLABLE MIEUM OE PIEUPSIOS
+0x91EB 0xBB10 #HANGUL SYLLABLE MIEUM OE SSANGSIOS
+0x91EC 0xBB12 #HANGUL SYLLABLE MIEUM OE CIEUC
+0x91ED 0xBB13 #HANGUL SYLLABLE MIEUM OE CHIEUCH
+0x91EE 0xBB14 #HANGUL SYLLABLE MIEUM OE KHIEUKH
+0x91EF 0xBB15 #HANGUL SYLLABLE MIEUM OE THIEUTH
+0x91F0 0xBB16 #HANGUL SYLLABLE MIEUM OE PHIEUPH
+0x91F1 0xBB17 #HANGUL SYLLABLE MIEUM OE HIEUH
+0x91F2 0xBB19 #HANGUL SYLLABLE MIEUM YO KIYEOK
+0x91F3 0xBB1A #HANGUL SYLLABLE MIEUM YO SSANGKIYEOK
+0x91F4 0xBB1B #HANGUL SYLLABLE MIEUM YO KIYEOKSIOS
+0x91F5 0xBB1D #HANGUL SYLLABLE MIEUM YO NIEUNCIEUC
+0x91F6 0xBB1E #HANGUL SYLLABLE MIEUM YO NIEUNHIEUH
+0x91F7 0xBB1F #HANGUL SYLLABLE MIEUM YO TIKEUT
+0x91F8 0xBB21 #HANGUL SYLLABLE MIEUM YO RIEULKIYEOK
+0x91F9 0xBB22 #HANGUL SYLLABLE MIEUM YO RIEULMIEUM
+0x91FA 0xBB23 #HANGUL SYLLABLE MIEUM YO RIEULPIEUP
+0x91FB 0xBB24 #HANGUL SYLLABLE MIEUM YO RIEULSIOS
+0x91FC 0xBB25 #HANGUL SYLLABLE MIEUM YO RIEULTHIEUTH
+0x91FD 0xBB26 #HANGUL SYLLABLE MIEUM YO RIEULPHIEUPH
+0x91FE 0xBB27 #HANGUL SYLLABLE MIEUM YO RIEULHIEUH
+0x9241 0xBB28 #HANGUL SYLLABLE MIEUM YO MIEUM
+0x9242 0xBB2A #HANGUL SYLLABLE MIEUM YO PIEUPSIOS
+0x9243 0xBB2C #HANGUL SYLLABLE MIEUM YO SSANGSIOS
+0x9244 0xBB2D #HANGUL SYLLABLE MIEUM YO IEUNG
+0x9245 0xBB2E #HANGUL SYLLABLE MIEUM YO CIEUC
+0x9246 0xBB2F #HANGUL SYLLABLE MIEUM YO CHIEUCH
+0x9247 0xBB30 #HANGUL SYLLABLE MIEUM YO KHIEUKH
+0x9248 0xBB31 #HANGUL SYLLABLE MIEUM YO THIEUTH
+0x9249 0xBB32 #HANGUL SYLLABLE MIEUM YO PHIEUPH
+0x924A 0xBB33 #HANGUL SYLLABLE MIEUM YO HIEUH
+0x924B 0xBB37 #HANGUL SYLLABLE MIEUM U KIYEOKSIOS
+0x924C 0xBB39 #HANGUL SYLLABLE MIEUM U NIEUNCIEUC
+0x924D 0xBB3A #HANGUL SYLLABLE MIEUM U NIEUNHIEUH
+0x924E 0xBB3F #HANGUL SYLLABLE MIEUM U RIEULPIEUP
+0x924F 0xBB40 #HANGUL SYLLABLE MIEUM U RIEULSIOS
+0x9250 0xBB41 #HANGUL SYLLABLE MIEUM U RIEULTHIEUTH
+0x9251 0xBB42 #HANGUL SYLLABLE MIEUM U RIEULPHIEUPH
+0x9252 0xBB43 #HANGUL SYLLABLE MIEUM U RIEULHIEUH
+0x9253 0xBB46 #HANGUL SYLLABLE MIEUM U PIEUPSIOS
+0x9254 0xBB48 #HANGUL SYLLABLE MIEUM U SSANGSIOS
+0x9255 0xBB4A #HANGUL SYLLABLE MIEUM U CIEUC
+0x9256 0xBB4B #HANGUL SYLLABLE MIEUM U CHIEUCH
+0x9257 0xBB4C #HANGUL SYLLABLE MIEUM U KHIEUKH
+0x9258 0xBB4E #HANGUL SYLLABLE MIEUM U PHIEUPH
+0x9259 0xBB51 #HANGUL SYLLABLE MIEUM WEO KIYEOK
+0x925A 0xBB52 #HANGUL SYLLABLE MIEUM WEO SSANGKIYEOK
+0x9261 0xBB53 #HANGUL SYLLABLE MIEUM WEO KIYEOKSIOS
+0x9262 0xBB55 #HANGUL SYLLABLE MIEUM WEO NIEUNCIEUC
+0x9263 0xBB56 #HANGUL SYLLABLE MIEUM WEO NIEUNHIEUH
+0x9264 0xBB57 #HANGUL SYLLABLE MIEUM WEO TIKEUT
+0x9265 0xBB59 #HANGUL SYLLABLE MIEUM WEO RIEULKIYEOK
+0x9266 0xBB5A #HANGUL SYLLABLE MIEUM WEO RIEULMIEUM
+0x9267 0xBB5B #HANGUL SYLLABLE MIEUM WEO RIEULPIEUP
+0x9268 0xBB5C #HANGUL SYLLABLE MIEUM WEO RIEULSIOS
+0x9269 0xBB5D #HANGUL SYLLABLE MIEUM WEO RIEULTHIEUTH
+0x926A 0xBB5E #HANGUL SYLLABLE MIEUM WEO RIEULPHIEUPH
+0x926B 0xBB5F #HANGUL SYLLABLE MIEUM WEO RIEULHIEUH
+0x926C 0xBB60 #HANGUL SYLLABLE MIEUM WEO MIEUM
+0x926D 0xBB62 #HANGUL SYLLABLE MIEUM WEO PIEUPSIOS
+0x926E 0xBB64 #HANGUL SYLLABLE MIEUM WEO SSANGSIOS
+0x926F 0xBB65 #HANGUL SYLLABLE MIEUM WEO IEUNG
+0x9270 0xBB66 #HANGUL SYLLABLE MIEUM WEO CIEUC
+0x9271 0xBB67 #HANGUL SYLLABLE MIEUM WEO CHIEUCH
+0x9272 0xBB68 #HANGUL SYLLABLE MIEUM WEO KHIEUKH
+0x9273 0xBB69 #HANGUL SYLLABLE MIEUM WEO THIEUTH
+0x9274 0xBB6A #HANGUL SYLLABLE MIEUM WEO PHIEUPH
+0x9275 0xBB6B #HANGUL SYLLABLE MIEUM WEO HIEUH
+0x9276 0xBB6D #HANGUL SYLLABLE MIEUM WE KIYEOK
+0x9277 0xBB6E #HANGUL SYLLABLE MIEUM WE SSANGKIYEOK
+0x9278 0xBB6F #HANGUL SYLLABLE MIEUM WE KIYEOKSIOS
+0x9279 0xBB70 #HANGUL SYLLABLE MIEUM WE NIEUN
+0x927A 0xBB71 #HANGUL SYLLABLE MIEUM WE NIEUNCIEUC
+0x9281 0xBB72 #HANGUL SYLLABLE MIEUM WE NIEUNHIEUH
+0x9282 0xBB73 #HANGUL SYLLABLE MIEUM WE TIKEUT
+0x9283 0xBB74 #HANGUL SYLLABLE MIEUM WE RIEUL
+0x9284 0xBB75 #HANGUL SYLLABLE MIEUM WE RIEULKIYEOK
+0x9285 0xBB76 #HANGUL SYLLABLE MIEUM WE RIEULMIEUM
+0x9286 0xBB77 #HANGUL SYLLABLE MIEUM WE RIEULPIEUP
+0x9287 0xBB78 #HANGUL SYLLABLE MIEUM WE RIEULSIOS
+0x9288 0xBB79 #HANGUL SYLLABLE MIEUM WE RIEULTHIEUTH
+0x9289 0xBB7A #HANGUL SYLLABLE MIEUM WE RIEULPHIEUPH
+0x928A 0xBB7B #HANGUL SYLLABLE MIEUM WE RIEULHIEUH
+0x928B 0xBB7C #HANGUL SYLLABLE MIEUM WE MIEUM
+0x928C 0xBB7D #HANGUL SYLLABLE MIEUM WE PIEUP
+0x928D 0xBB7E #HANGUL SYLLABLE MIEUM WE PIEUPSIOS
+0x928E 0xBB7F #HANGUL SYLLABLE MIEUM WE SIOS
+0x928F 0xBB80 #HANGUL SYLLABLE MIEUM WE SSANGSIOS
+0x9290 0xBB81 #HANGUL SYLLABLE MIEUM WE IEUNG
+0x9291 0xBB82 #HANGUL SYLLABLE MIEUM WE CIEUC
+0x9292 0xBB83 #HANGUL SYLLABLE MIEUM WE CHIEUCH
+0x9293 0xBB84 #HANGUL SYLLABLE MIEUM WE KHIEUKH
+0x9294 0xBB85 #HANGUL SYLLABLE MIEUM WE THIEUTH
+0x9295 0xBB86 #HANGUL SYLLABLE MIEUM WE PHIEUPH
+0x9296 0xBB87 #HANGUL SYLLABLE MIEUM WE HIEUH
+0x9297 0xBB89 #HANGUL SYLLABLE MIEUM WI KIYEOK
+0x9298 0xBB8A #HANGUL SYLLABLE MIEUM WI SSANGKIYEOK
+0x9299 0xBB8B #HANGUL SYLLABLE MIEUM WI KIYEOKSIOS
+0x929A 0xBB8D #HANGUL SYLLABLE MIEUM WI NIEUNCIEUC
+0x929B 0xBB8E #HANGUL SYLLABLE MIEUM WI NIEUNHIEUH
+0x929C 0xBB8F #HANGUL SYLLABLE MIEUM WI TIKEUT
+0x929D 0xBB91 #HANGUL SYLLABLE MIEUM WI RIEULKIYEOK
+0x929E 0xBB92 #HANGUL SYLLABLE MIEUM WI RIEULMIEUM
+0x929F 0xBB93 #HANGUL SYLLABLE MIEUM WI RIEULPIEUP
+0x92A0 0xBB94 #HANGUL SYLLABLE MIEUM WI RIEULSIOS
+0x92A1 0xBB95 #HANGUL SYLLABLE MIEUM WI RIEULTHIEUTH
+0x92A2 0xBB96 #HANGUL SYLLABLE MIEUM WI RIEULPHIEUPH
+0x92A3 0xBB97 #HANGUL SYLLABLE MIEUM WI RIEULHIEUH
+0x92A4 0xBB98 #HANGUL SYLLABLE MIEUM WI MIEUM
+0x92A5 0xBB99 #HANGUL SYLLABLE MIEUM WI PIEUP
+0x92A6 0xBB9A #HANGUL SYLLABLE MIEUM WI PIEUPSIOS
+0x92A7 0xBB9B #HANGUL SYLLABLE MIEUM WI SIOS
+0x92A8 0xBB9C #HANGUL SYLLABLE MIEUM WI SSANGSIOS
+0x92A9 0xBB9D #HANGUL SYLLABLE MIEUM WI IEUNG
+0x92AA 0xBB9E #HANGUL SYLLABLE MIEUM WI CIEUC
+0x92AB 0xBB9F #HANGUL SYLLABLE MIEUM WI CHIEUCH
+0x92AC 0xBBA0 #HANGUL SYLLABLE MIEUM WI KHIEUKH
+0x92AD 0xBBA1 #HANGUL SYLLABLE MIEUM WI THIEUTH
+0x92AE 0xBBA2 #HANGUL SYLLABLE MIEUM WI PHIEUPH
+0x92AF 0xBBA3 #HANGUL SYLLABLE MIEUM WI HIEUH
+0x92B0 0xBBA5 #HANGUL SYLLABLE MIEUM YU KIYEOK
+0x92B1 0xBBA6 #HANGUL SYLLABLE MIEUM YU SSANGKIYEOK
+0x92B2 0xBBA7 #HANGUL SYLLABLE MIEUM YU KIYEOKSIOS
+0x92B3 0xBBA9 #HANGUL SYLLABLE MIEUM YU NIEUNCIEUC
+0x92B4 0xBBAA #HANGUL SYLLABLE MIEUM YU NIEUNHIEUH
+0x92B5 0xBBAB #HANGUL SYLLABLE MIEUM YU TIKEUT
+0x92B6 0xBBAD #HANGUL SYLLABLE MIEUM YU RIEULKIYEOK
+0x92B7 0xBBAE #HANGUL SYLLABLE MIEUM YU RIEULMIEUM
+0x92B8 0xBBAF #HANGUL SYLLABLE MIEUM YU RIEULPIEUP
+0x92B9 0xBBB0 #HANGUL SYLLABLE MIEUM YU RIEULSIOS
+0x92BA 0xBBB1 #HANGUL SYLLABLE MIEUM YU RIEULTHIEUTH
+0x92BB 0xBBB2 #HANGUL SYLLABLE MIEUM YU RIEULPHIEUPH
+0x92BC 0xBBB3 #HANGUL SYLLABLE MIEUM YU RIEULHIEUH
+0x92BD 0xBBB5 #HANGUL SYLLABLE MIEUM YU PIEUP
+0x92BE 0xBBB6 #HANGUL SYLLABLE MIEUM YU PIEUPSIOS
+0x92BF 0xBBB8 #HANGUL SYLLABLE MIEUM YU SSANGSIOS
+0x92C0 0xBBB9 #HANGUL SYLLABLE MIEUM YU IEUNG
+0x92C1 0xBBBA #HANGUL SYLLABLE MIEUM YU CIEUC
+0x92C2 0xBBBB #HANGUL SYLLABLE MIEUM YU CHIEUCH
+0x92C3 0xBBBC #HANGUL SYLLABLE MIEUM YU KHIEUKH
+0x92C4 0xBBBD #HANGUL SYLLABLE MIEUM YU THIEUTH
+0x92C5 0xBBBE #HANGUL SYLLABLE MIEUM YU PHIEUPH
+0x92C6 0xBBBF #HANGUL SYLLABLE MIEUM YU HIEUH
+0x92C7 0xBBC1 #HANGUL SYLLABLE MIEUM EU KIYEOK
+0x92C8 0xBBC2 #HANGUL SYLLABLE MIEUM EU SSANGKIYEOK
+0x92C9 0xBBC3 #HANGUL SYLLABLE MIEUM EU KIYEOKSIOS
+0x92CA 0xBBC5 #HANGUL SYLLABLE MIEUM EU NIEUNCIEUC
+0x92CB 0xBBC6 #HANGUL SYLLABLE MIEUM EU NIEUNHIEUH
+0x92CC 0xBBC7 #HANGUL SYLLABLE MIEUM EU TIKEUT
+0x92CD 0xBBC9 #HANGUL SYLLABLE MIEUM EU RIEULKIYEOK
+0x92CE 0xBBCA #HANGUL SYLLABLE MIEUM EU RIEULMIEUM
+0x92CF 0xBBCB #HANGUL SYLLABLE MIEUM EU RIEULPIEUP
+0x92D0 0xBBCC #HANGUL SYLLABLE MIEUM EU RIEULSIOS
+0x92D1 0xBBCD #HANGUL SYLLABLE MIEUM EU RIEULTHIEUTH
+0x92D2 0xBBCE #HANGUL SYLLABLE MIEUM EU RIEULPHIEUPH
+0x92D3 0xBBCF #HANGUL SYLLABLE MIEUM EU RIEULHIEUH
+0x92D4 0xBBD1 #HANGUL SYLLABLE MIEUM EU PIEUP
+0x92D5 0xBBD2 #HANGUL SYLLABLE MIEUM EU PIEUPSIOS
+0x92D6 0xBBD4 #HANGUL SYLLABLE MIEUM EU SSANGSIOS
+0x92D7 0xBBD5 #HANGUL SYLLABLE MIEUM EU IEUNG
+0x92D8 0xBBD6 #HANGUL SYLLABLE MIEUM EU CIEUC
+0x92D9 0xBBD7 #HANGUL SYLLABLE MIEUM EU CHIEUCH
+0x92DA 0xBBD8 #HANGUL SYLLABLE MIEUM EU KHIEUKH
+0x92DB 0xBBD9 #HANGUL SYLLABLE MIEUM EU THIEUTH
+0x92DC 0xBBDA #HANGUL SYLLABLE MIEUM EU PHIEUPH
+0x92DD 0xBBDB #HANGUL SYLLABLE MIEUM EU HIEUH
+0x92DE 0xBBDC #HANGUL SYLLABLE MIEUM YI
+0x92DF 0xBBDD #HANGUL SYLLABLE MIEUM YI KIYEOK
+0x92E0 0xBBDE #HANGUL SYLLABLE MIEUM YI SSANGKIYEOK
+0x92E1 0xBBDF #HANGUL SYLLABLE MIEUM YI KIYEOKSIOS
+0x92E2 0xBBE0 #HANGUL SYLLABLE MIEUM YI NIEUN
+0x92E3 0xBBE1 #HANGUL SYLLABLE MIEUM YI NIEUNCIEUC
+0x92E4 0xBBE2 #HANGUL SYLLABLE MIEUM YI NIEUNHIEUH
+0x92E5 0xBBE3 #HANGUL SYLLABLE MIEUM YI TIKEUT
+0x92E6 0xBBE4 #HANGUL SYLLABLE MIEUM YI RIEUL
+0x92E7 0xBBE5 #HANGUL SYLLABLE MIEUM YI RIEULKIYEOK
+0x92E8 0xBBE6 #HANGUL SYLLABLE MIEUM YI RIEULMIEUM
+0x92E9 0xBBE7 #HANGUL SYLLABLE MIEUM YI RIEULPIEUP
+0x92EA 0xBBE8 #HANGUL SYLLABLE MIEUM YI RIEULSIOS
+0x92EB 0xBBE9 #HANGUL SYLLABLE MIEUM YI RIEULTHIEUTH
+0x92EC 0xBBEA #HANGUL SYLLABLE MIEUM YI RIEULPHIEUPH
+0x92ED 0xBBEB #HANGUL SYLLABLE MIEUM YI RIEULHIEUH
+0x92EE 0xBBEC #HANGUL SYLLABLE MIEUM YI MIEUM
+0x92EF 0xBBED #HANGUL SYLLABLE MIEUM YI PIEUP
+0x92F0 0xBBEE #HANGUL SYLLABLE MIEUM YI PIEUPSIOS
+0x92F1 0xBBEF #HANGUL SYLLABLE MIEUM YI SIOS
+0x92F2 0xBBF0 #HANGUL SYLLABLE MIEUM YI SSANGSIOS
+0x92F3 0xBBF1 #HANGUL SYLLABLE MIEUM YI IEUNG
+0x92F4 0xBBF2 #HANGUL SYLLABLE MIEUM YI CIEUC
+0x92F5 0xBBF3 #HANGUL SYLLABLE MIEUM YI CHIEUCH
+0x92F6 0xBBF4 #HANGUL SYLLABLE MIEUM YI KHIEUKH
+0x92F7 0xBBF5 #HANGUL SYLLABLE MIEUM YI THIEUTH
+0x92F8 0xBBF6 #HANGUL SYLLABLE MIEUM YI PHIEUPH
+0x92F9 0xBBF7 #HANGUL SYLLABLE MIEUM YI HIEUH
+0x92FA 0xBBFA #HANGUL SYLLABLE MIEUM I SSANGKIYEOK
+0x92FB 0xBBFB #HANGUL SYLLABLE MIEUM I KIYEOKSIOS
+0x92FC 0xBBFD #HANGUL SYLLABLE MIEUM I NIEUNCIEUC
+0x92FD 0xBBFE #HANGUL SYLLABLE MIEUM I NIEUNHIEUH
+0x92FE 0xBC01 #HANGUL SYLLABLE MIEUM I RIEULKIYEOK
+0x9341 0xBC03 #HANGUL SYLLABLE MIEUM I RIEULPIEUP
+0x9342 0xBC04 #HANGUL SYLLABLE MIEUM I RIEULSIOS
+0x9343 0xBC05 #HANGUL SYLLABLE MIEUM I RIEULTHIEUTH
+0x9344 0xBC06 #HANGUL SYLLABLE MIEUM I RIEULPHIEUPH
+0x9345 0xBC07 #HANGUL SYLLABLE MIEUM I RIEULHIEUH
+0x9346 0xBC0A #HANGUL SYLLABLE MIEUM I PIEUPSIOS
+0x9347 0xBC0E #HANGUL SYLLABLE MIEUM I CIEUC
+0x9348 0xBC10 #HANGUL SYLLABLE MIEUM I KHIEUKH
+0x9349 0xBC12 #HANGUL SYLLABLE MIEUM I PHIEUPH
+0x934A 0xBC13 #HANGUL SYLLABLE MIEUM I HIEUH
+0x934B 0xBC19 #HANGUL SYLLABLE PIEUP A NIEUNCIEUC
+0x934C 0xBC1A #HANGUL SYLLABLE PIEUP A NIEUNHIEUH
+0x934D 0xBC20 #HANGUL SYLLABLE PIEUP A RIEULSIOS
+0x934E 0xBC21 #HANGUL SYLLABLE PIEUP A RIEULTHIEUTH
+0x934F 0xBC22 #HANGUL SYLLABLE PIEUP A RIEULPHIEUPH
+0x9350 0xBC23 #HANGUL SYLLABLE PIEUP A RIEULHIEUH
+0x9351 0xBC26 #HANGUL SYLLABLE PIEUP A PIEUPSIOS
+0x9352 0xBC28 #HANGUL SYLLABLE PIEUP A SSANGSIOS
+0x9353 0xBC2A #HANGUL SYLLABLE PIEUP A CIEUC
+0x9354 0xBC2B #HANGUL SYLLABLE PIEUP A CHIEUCH
+0x9355 0xBC2C #HANGUL SYLLABLE PIEUP A KHIEUKH
+0x9356 0xBC2E #HANGUL SYLLABLE PIEUP A PHIEUPH
+0x9357 0xBC2F #HANGUL SYLLABLE PIEUP A HIEUH
+0x9358 0xBC32 #HANGUL SYLLABLE PIEUP AE SSANGKIYEOK
+0x9359 0xBC33 #HANGUL SYLLABLE PIEUP AE KIYEOKSIOS
+0x935A 0xBC35 #HANGUL SYLLABLE PIEUP AE NIEUNCIEUC
+0x9361 0xBC36 #HANGUL SYLLABLE PIEUP AE NIEUNHIEUH
+0x9362 0xBC37 #HANGUL SYLLABLE PIEUP AE TIKEUT
+0x9363 0xBC39 #HANGUL SYLLABLE PIEUP AE RIEULKIYEOK
+0x9364 0xBC3A #HANGUL SYLLABLE PIEUP AE RIEULMIEUM
+0x9365 0xBC3B #HANGUL SYLLABLE PIEUP AE RIEULPIEUP
+0x9366 0xBC3C #HANGUL SYLLABLE PIEUP AE RIEULSIOS
+0x9367 0xBC3D #HANGUL SYLLABLE PIEUP AE RIEULTHIEUTH
+0x9368 0xBC3E #HANGUL SYLLABLE PIEUP AE RIEULPHIEUPH
+0x9369 0xBC3F #HANGUL SYLLABLE PIEUP AE RIEULHIEUH
+0x936A 0xBC42 #HANGUL SYLLABLE PIEUP AE PIEUPSIOS
+0x936B 0xBC46 #HANGUL SYLLABLE PIEUP AE CIEUC
+0x936C 0xBC47 #HANGUL SYLLABLE PIEUP AE CHIEUCH
+0x936D 0xBC48 #HANGUL SYLLABLE PIEUP AE KHIEUKH
+0x936E 0xBC4A #HANGUL SYLLABLE PIEUP AE PHIEUPH
+0x936F 0xBC4B #HANGUL SYLLABLE PIEUP AE HIEUH
+0x9370 0xBC4E #HANGUL SYLLABLE PIEUP YA SSANGKIYEOK
+0x9371 0xBC4F #HANGUL SYLLABLE PIEUP YA KIYEOKSIOS
+0x9372 0xBC51 #HANGUL SYLLABLE PIEUP YA NIEUNCIEUC
+0x9373 0xBC52 #HANGUL SYLLABLE PIEUP YA NIEUNHIEUH
+0x9374 0xBC53 #HANGUL SYLLABLE PIEUP YA TIKEUT
+0x9375 0xBC54 #HANGUL SYLLABLE PIEUP YA RIEUL
+0x9376 0xBC55 #HANGUL SYLLABLE PIEUP YA RIEULKIYEOK
+0x9377 0xBC56 #HANGUL SYLLABLE PIEUP YA RIEULMIEUM
+0x9378 0xBC57 #HANGUL SYLLABLE PIEUP YA RIEULPIEUP
+0x9379 0xBC58 #HANGUL SYLLABLE PIEUP YA RIEULSIOS
+0x937A 0xBC59 #HANGUL SYLLABLE PIEUP YA RIEULTHIEUTH
+0x9381 0xBC5A #HANGUL SYLLABLE PIEUP YA RIEULPHIEUPH
+0x9382 0xBC5B #HANGUL SYLLABLE PIEUP YA RIEULHIEUH
+0x9383 0xBC5C #HANGUL SYLLABLE PIEUP YA MIEUM
+0x9384 0xBC5E #HANGUL SYLLABLE PIEUP YA PIEUPSIOS
+0x9385 0xBC5F #HANGUL SYLLABLE PIEUP YA SIOS
+0x9386 0xBC60 #HANGUL SYLLABLE PIEUP YA SSANGSIOS
+0x9387 0xBC61 #HANGUL SYLLABLE PIEUP YA IEUNG
+0x9388 0xBC62 #HANGUL SYLLABLE PIEUP YA CIEUC
+0x9389 0xBC63 #HANGUL SYLLABLE PIEUP YA CHIEUCH
+0x938A 0xBC64 #HANGUL SYLLABLE PIEUP YA KHIEUKH
+0x938B 0xBC65 #HANGUL SYLLABLE PIEUP YA THIEUTH
+0x938C 0xBC66 #HANGUL SYLLABLE PIEUP YA PHIEUPH
+0x938D 0xBC67 #HANGUL SYLLABLE PIEUP YA HIEUH
+0x938E 0xBC68 #HANGUL SYLLABLE PIEUP YAE
+0x938F 0xBC69 #HANGUL SYLLABLE PIEUP YAE KIYEOK
+0x9390 0xBC6A #HANGUL SYLLABLE PIEUP YAE SSANGKIYEOK
+0x9391 0xBC6B #HANGUL SYLLABLE PIEUP YAE KIYEOKSIOS
+0x9392 0xBC6C #HANGUL SYLLABLE PIEUP YAE NIEUN
+0x9393 0xBC6D #HANGUL SYLLABLE PIEUP YAE NIEUNCIEUC
+0x9394 0xBC6E #HANGUL SYLLABLE PIEUP YAE NIEUNHIEUH
+0x9395 0xBC6F #HANGUL SYLLABLE PIEUP YAE TIKEUT
+0x9396 0xBC70 #HANGUL SYLLABLE PIEUP YAE RIEUL
+0x9397 0xBC71 #HANGUL SYLLABLE PIEUP YAE RIEULKIYEOK
+0x9398 0xBC72 #HANGUL SYLLABLE PIEUP YAE RIEULMIEUM
+0x9399 0xBC73 #HANGUL SYLLABLE PIEUP YAE RIEULPIEUP
+0x939A 0xBC74 #HANGUL SYLLABLE PIEUP YAE RIEULSIOS
+0x939B 0xBC75 #HANGUL SYLLABLE PIEUP YAE RIEULTHIEUTH
+0x939C 0xBC76 #HANGUL SYLLABLE PIEUP YAE RIEULPHIEUPH
+0x939D 0xBC77 #HANGUL SYLLABLE PIEUP YAE RIEULHIEUH
+0x939E 0xBC78 #HANGUL SYLLABLE PIEUP YAE MIEUM
+0x939F 0xBC79 #HANGUL SYLLABLE PIEUP YAE PIEUP
+0x93A0 0xBC7A #HANGUL SYLLABLE PIEUP YAE PIEUPSIOS
+0x93A1 0xBC7B #HANGUL SYLLABLE PIEUP YAE SIOS
+0x93A2 0xBC7C #HANGUL SYLLABLE PIEUP YAE SSANGSIOS
+0x93A3 0xBC7D #HANGUL SYLLABLE PIEUP YAE IEUNG
+0x93A4 0xBC7E #HANGUL SYLLABLE PIEUP YAE CIEUC
+0x93A5 0xBC7F #HANGUL SYLLABLE PIEUP YAE CHIEUCH
+0x93A6 0xBC80 #HANGUL SYLLABLE PIEUP YAE KHIEUKH
+0x93A7 0xBC81 #HANGUL SYLLABLE PIEUP YAE THIEUTH
+0x93A8 0xBC82 #HANGUL SYLLABLE PIEUP YAE PHIEUPH
+0x93A9 0xBC83 #HANGUL SYLLABLE PIEUP YAE HIEUH
+0x93AA 0xBC86 #HANGUL SYLLABLE PIEUP EO SSANGKIYEOK
+0x93AB 0xBC87 #HANGUL SYLLABLE PIEUP EO KIYEOKSIOS
+0x93AC 0xBC89 #HANGUL SYLLABLE PIEUP EO NIEUNCIEUC
+0x93AD 0xBC8A #HANGUL SYLLABLE PIEUP EO NIEUNHIEUH
+0x93AE 0xBC8D #HANGUL SYLLABLE PIEUP EO RIEULKIYEOK
+0x93AF 0xBC8F #HANGUL SYLLABLE PIEUP EO RIEULPIEUP
+0x93B0 0xBC90 #HANGUL SYLLABLE PIEUP EO RIEULSIOS
+0x93B1 0xBC91 #HANGUL SYLLABLE PIEUP EO RIEULTHIEUTH
+0x93B2 0xBC92 #HANGUL SYLLABLE PIEUP EO RIEULPHIEUPH
+0x93B3 0xBC93 #HANGUL SYLLABLE PIEUP EO RIEULHIEUH
+0x93B4 0xBC96 #HANGUL SYLLABLE PIEUP EO PIEUPSIOS
+0x93B5 0xBC98 #HANGUL SYLLABLE PIEUP EO SSANGSIOS
+0x93B6 0xBC9B #HANGUL SYLLABLE PIEUP EO CHIEUCH
+0x93B7 0xBC9C #HANGUL SYLLABLE PIEUP EO KHIEUKH
+0x93B8 0xBC9D #HANGUL SYLLABLE PIEUP EO THIEUTH
+0x93B9 0xBC9E #HANGUL SYLLABLE PIEUP EO PHIEUPH
+0x93BA 0xBC9F #HANGUL SYLLABLE PIEUP EO HIEUH
+0x93BB 0xBCA2 #HANGUL SYLLABLE PIEUP E SSANGKIYEOK
+0x93BC 0xBCA3 #HANGUL SYLLABLE PIEUP E KIYEOKSIOS
+0x93BD 0xBCA5 #HANGUL SYLLABLE PIEUP E NIEUNCIEUC
+0x93BE 0xBCA6 #HANGUL SYLLABLE PIEUP E NIEUNHIEUH
+0x93BF 0xBCA9 #HANGUL SYLLABLE PIEUP E RIEULKIYEOK
+0x93C0 0xBCAA #HANGUL SYLLABLE PIEUP E RIEULMIEUM
+0x93C1 0xBCAB #HANGUL SYLLABLE PIEUP E RIEULPIEUP
+0x93C2 0xBCAC #HANGUL SYLLABLE PIEUP E RIEULSIOS
+0x93C3 0xBCAD #HANGUL SYLLABLE PIEUP E RIEULTHIEUTH
+0x93C4 0xBCAE #HANGUL SYLLABLE PIEUP E RIEULPHIEUPH
+0x93C5 0xBCAF #HANGUL SYLLABLE PIEUP E RIEULHIEUH
+0x93C6 0xBCB2 #HANGUL SYLLABLE PIEUP E PIEUPSIOS
+0x93C7 0xBCB6 #HANGUL SYLLABLE PIEUP E CIEUC
+0x93C8 0xBCB7 #HANGUL SYLLABLE PIEUP E CHIEUCH
+0x93C9 0xBCB8 #HANGUL SYLLABLE PIEUP E KHIEUKH
+0x93CA 0xBCB9 #HANGUL SYLLABLE PIEUP E THIEUTH
+0x93CB 0xBCBA #HANGUL SYLLABLE PIEUP E PHIEUPH
+0x93CC 0xBCBB #HANGUL SYLLABLE PIEUP E HIEUH
+0x93CD 0xBCBE #HANGUL SYLLABLE PIEUP YEO SSANGKIYEOK
+0x93CE 0xBCBF #HANGUL SYLLABLE PIEUP YEO KIYEOKSIOS
+0x93CF 0xBCC1 #HANGUL SYLLABLE PIEUP YEO NIEUNCIEUC
+0x93D0 0xBCC2 #HANGUL SYLLABLE PIEUP YEO NIEUNHIEUH
+0x93D1 0xBCC3 #HANGUL SYLLABLE PIEUP YEO TIKEUT
+0x93D2 0xBCC5 #HANGUL SYLLABLE PIEUP YEO RIEULKIYEOK
+0x93D3 0xBCC6 #HANGUL SYLLABLE PIEUP YEO RIEULMIEUM
+0x93D4 0xBCC7 #HANGUL SYLLABLE PIEUP YEO RIEULPIEUP
+0x93D5 0xBCC8 #HANGUL SYLLABLE PIEUP YEO RIEULSIOS
+0x93D6 0xBCC9 #HANGUL SYLLABLE PIEUP YEO RIEULTHIEUTH
+0x93D7 0xBCCA #HANGUL SYLLABLE PIEUP YEO RIEULPHIEUPH
+0x93D8 0xBCCB #HANGUL SYLLABLE PIEUP YEO RIEULHIEUH
+0x93D9 0xBCCC #HANGUL SYLLABLE PIEUP YEO MIEUM
+0x93DA 0xBCCE #HANGUL SYLLABLE PIEUP YEO PIEUPSIOS
+0x93DB 0xBCD2 #HANGUL SYLLABLE PIEUP YEO CIEUC
+0x93DC 0xBCD3 #HANGUL SYLLABLE PIEUP YEO CHIEUCH
+0x93DD 0xBCD4 #HANGUL SYLLABLE PIEUP YEO KHIEUKH
+0x93DE 0xBCD6 #HANGUL SYLLABLE PIEUP YEO PHIEUPH
+0x93DF 0xBCD7 #HANGUL SYLLABLE PIEUP YEO HIEUH
+0x93E0 0xBCD9 #HANGUL SYLLABLE PIEUP YE KIYEOK
+0x93E1 0xBCDA #HANGUL SYLLABLE PIEUP YE SSANGKIYEOK
+0x93E2 0xBCDB #HANGUL SYLLABLE PIEUP YE KIYEOKSIOS
+0x93E3 0xBCDD #HANGUL SYLLABLE PIEUP YE NIEUNCIEUC
+0x93E4 0xBCDE #HANGUL SYLLABLE PIEUP YE NIEUNHIEUH
+0x93E5 0xBCDF #HANGUL SYLLABLE PIEUP YE TIKEUT
+0x93E6 0xBCE0 #HANGUL SYLLABLE PIEUP YE RIEUL
+0x93E7 0xBCE1 #HANGUL SYLLABLE PIEUP YE RIEULKIYEOK
+0x93E8 0xBCE2 #HANGUL SYLLABLE PIEUP YE RIEULMIEUM
+0x93E9 0xBCE3 #HANGUL SYLLABLE PIEUP YE RIEULPIEUP
+0x93EA 0xBCE4 #HANGUL SYLLABLE PIEUP YE RIEULSIOS
+0x93EB 0xBCE5 #HANGUL SYLLABLE PIEUP YE RIEULTHIEUTH
+0x93EC 0xBCE6 #HANGUL SYLLABLE PIEUP YE RIEULPHIEUPH
+0x93ED 0xBCE7 #HANGUL SYLLABLE PIEUP YE RIEULHIEUH
+0x93EE 0xBCE8 #HANGUL SYLLABLE PIEUP YE MIEUM
+0x93EF 0xBCE9 #HANGUL SYLLABLE PIEUP YE PIEUP
+0x93F0 0xBCEA #HANGUL SYLLABLE PIEUP YE PIEUPSIOS
+0x93F1 0xBCEB #HANGUL SYLLABLE PIEUP YE SIOS
+0x93F2 0xBCEC #HANGUL SYLLABLE PIEUP YE SSANGSIOS
+0x93F3 0xBCED #HANGUL SYLLABLE PIEUP YE IEUNG
+0x93F4 0xBCEE #HANGUL SYLLABLE PIEUP YE CIEUC
+0x93F5 0xBCEF #HANGUL SYLLABLE PIEUP YE CHIEUCH
+0x93F6 0xBCF0 #HANGUL SYLLABLE PIEUP YE KHIEUKH
+0x93F7 0xBCF1 #HANGUL SYLLABLE PIEUP YE THIEUTH
+0x93F8 0xBCF2 #HANGUL SYLLABLE PIEUP YE PHIEUPH
+0x93F9 0xBCF3 #HANGUL SYLLABLE PIEUP YE HIEUH
+0x93FA 0xBCF7 #HANGUL SYLLABLE PIEUP O KIYEOKSIOS
+0x93FB 0xBCF9 #HANGUL SYLLABLE PIEUP O NIEUNCIEUC
+0x93FC 0xBCFA #HANGUL SYLLABLE PIEUP O NIEUNHIEUH
+0x93FD 0xBCFB #HANGUL SYLLABLE PIEUP O TIKEUT
+0x93FE 0xBCFD #HANGUL SYLLABLE PIEUP O RIEULKIYEOK
+0x9441 0xBCFE #HANGUL SYLLABLE PIEUP O RIEULMIEUM
+0x9442 0xBCFF #HANGUL SYLLABLE PIEUP O RIEULPIEUP
+0x9443 0xBD00 #HANGUL SYLLABLE PIEUP O RIEULSIOS
+0x9444 0xBD01 #HANGUL SYLLABLE PIEUP O RIEULTHIEUTH
+0x9445 0xBD02 #HANGUL SYLLABLE PIEUP O RIEULPHIEUPH
+0x9446 0xBD03 #HANGUL SYLLABLE PIEUP O RIEULHIEUH
+0x9447 0xBD06 #HANGUL SYLLABLE PIEUP O PIEUPSIOS
+0x9448 0xBD08 #HANGUL SYLLABLE PIEUP O SSANGSIOS
+0x9449 0xBD0A #HANGUL SYLLABLE PIEUP O CIEUC
+0x944A 0xBD0B #HANGUL SYLLABLE PIEUP O CHIEUCH
+0x944B 0xBD0C #HANGUL SYLLABLE PIEUP O KHIEUKH
+0x944C 0xBD0D #HANGUL SYLLABLE PIEUP O THIEUTH
+0x944D 0xBD0E #HANGUL SYLLABLE PIEUP O PHIEUPH
+0x944E 0xBD0F #HANGUL SYLLABLE PIEUP O HIEUH
+0x944F 0xBD11 #HANGUL SYLLABLE PIEUP WA KIYEOK
+0x9450 0xBD12 #HANGUL SYLLABLE PIEUP WA SSANGKIYEOK
+0x9451 0xBD13 #HANGUL SYLLABLE PIEUP WA KIYEOKSIOS
+0x9452 0xBD15 #HANGUL SYLLABLE PIEUP WA NIEUNCIEUC
+0x9453 0xBD16 #HANGUL SYLLABLE PIEUP WA NIEUNHIEUH
+0x9454 0xBD17 #HANGUL SYLLABLE PIEUP WA TIKEUT
+0x9455 0xBD18 #HANGUL SYLLABLE PIEUP WA RIEUL
+0x9456 0xBD19 #HANGUL SYLLABLE PIEUP WA RIEULKIYEOK
+0x9457 0xBD1A #HANGUL SYLLABLE PIEUP WA RIEULMIEUM
+0x9458 0xBD1B #HANGUL SYLLABLE PIEUP WA RIEULPIEUP
+0x9459 0xBD1C #HANGUL SYLLABLE PIEUP WA RIEULSIOS
+0x945A 0xBD1D #HANGUL SYLLABLE PIEUP WA RIEULTHIEUTH
+0x9461 0xBD1E #HANGUL SYLLABLE PIEUP WA RIEULPHIEUPH
+0x9462 0xBD1F #HANGUL SYLLABLE PIEUP WA RIEULHIEUH
+0x9463 0xBD20 #HANGUL SYLLABLE PIEUP WA MIEUM
+0x9464 0xBD21 #HANGUL SYLLABLE PIEUP WA PIEUP
+0x9465 0xBD22 #HANGUL SYLLABLE PIEUP WA PIEUPSIOS
+0x9466 0xBD23 #HANGUL SYLLABLE PIEUP WA SIOS
+0x9467 0xBD25 #HANGUL SYLLABLE PIEUP WA IEUNG
+0x9468 0xBD26 #HANGUL SYLLABLE PIEUP WA CIEUC
+0x9469 0xBD27 #HANGUL SYLLABLE PIEUP WA CHIEUCH
+0x946A 0xBD28 #HANGUL SYLLABLE PIEUP WA KHIEUKH
+0x946B 0xBD29 #HANGUL SYLLABLE PIEUP WA THIEUTH
+0x946C 0xBD2A #HANGUL SYLLABLE PIEUP WA PHIEUPH
+0x946D 0xBD2B #HANGUL SYLLABLE PIEUP WA HIEUH
+0x946E 0xBD2D #HANGUL SYLLABLE PIEUP WAE KIYEOK
+0x946F 0xBD2E #HANGUL SYLLABLE PIEUP WAE SSANGKIYEOK
+0x9470 0xBD2F #HANGUL SYLLABLE PIEUP WAE KIYEOKSIOS
+0x9471 0xBD30 #HANGUL SYLLABLE PIEUP WAE NIEUN
+0x9472 0xBD31 #HANGUL SYLLABLE PIEUP WAE NIEUNCIEUC
+0x9473 0xBD32 #HANGUL SYLLABLE PIEUP WAE NIEUNHIEUH
+0x9474 0xBD33 #HANGUL SYLLABLE PIEUP WAE TIKEUT
+0x9475 0xBD34 #HANGUL SYLLABLE PIEUP WAE RIEUL
+0x9476 0xBD35 #HANGUL SYLLABLE PIEUP WAE RIEULKIYEOK
+0x9477 0xBD36 #HANGUL SYLLABLE PIEUP WAE RIEULMIEUM
+0x9478 0xBD37 #HANGUL SYLLABLE PIEUP WAE RIEULPIEUP
+0x9479 0xBD38 #HANGUL SYLLABLE PIEUP WAE RIEULSIOS
+0x947A 0xBD39 #HANGUL SYLLABLE PIEUP WAE RIEULTHIEUTH
+0x9481 0xBD3A #HANGUL SYLLABLE PIEUP WAE RIEULPHIEUPH
+0x9482 0xBD3B #HANGUL SYLLABLE PIEUP WAE RIEULHIEUH
+0x9483 0xBD3C #HANGUL SYLLABLE PIEUP WAE MIEUM
+0x9484 0xBD3D #HANGUL SYLLABLE PIEUP WAE PIEUP
+0x9485 0xBD3E #HANGUL SYLLABLE PIEUP WAE PIEUPSIOS
+0x9486 0xBD3F #HANGUL SYLLABLE PIEUP WAE SIOS
+0x9487 0xBD41 #HANGUL SYLLABLE PIEUP WAE IEUNG
+0x9488 0xBD42 #HANGUL SYLLABLE PIEUP WAE CIEUC
+0x9489 0xBD43 #HANGUL SYLLABLE PIEUP WAE CHIEUCH
+0x948A 0xBD44 #HANGUL SYLLABLE PIEUP WAE KHIEUKH
+0x948B 0xBD45 #HANGUL SYLLABLE PIEUP WAE THIEUTH
+0x948C 0xBD46 #HANGUL SYLLABLE PIEUP WAE PHIEUPH
+0x948D 0xBD47 #HANGUL SYLLABLE PIEUP WAE HIEUH
+0x948E 0xBD4A #HANGUL SYLLABLE PIEUP OE SSANGKIYEOK
+0x948F 0xBD4B #HANGUL SYLLABLE PIEUP OE KIYEOKSIOS
+0x9490 0xBD4D #HANGUL SYLLABLE PIEUP OE NIEUNCIEUC
+0x9491 0xBD4E #HANGUL SYLLABLE PIEUP OE NIEUNHIEUH
+0x9492 0xBD4F #HANGUL SYLLABLE PIEUP OE TIKEUT
+0x9493 0xBD51 #HANGUL SYLLABLE PIEUP OE RIEULKIYEOK
+0x9494 0xBD52 #HANGUL SYLLABLE PIEUP OE RIEULMIEUM
+0x9495 0xBD53 #HANGUL SYLLABLE PIEUP OE RIEULPIEUP
+0x9496 0xBD54 #HANGUL SYLLABLE PIEUP OE RIEULSIOS
+0x9497 0xBD55 #HANGUL SYLLABLE PIEUP OE RIEULTHIEUTH
+0x9498 0xBD56 #HANGUL SYLLABLE PIEUP OE RIEULPHIEUPH
+0x9499 0xBD57 #HANGUL SYLLABLE PIEUP OE RIEULHIEUH
+0x949A 0xBD5A #HANGUL SYLLABLE PIEUP OE PIEUPSIOS
+0x949B 0xBD5B #HANGUL SYLLABLE PIEUP OE SIOS
+0x949C 0xBD5C #HANGUL SYLLABLE PIEUP OE SSANGSIOS
+0x949D 0xBD5D #HANGUL SYLLABLE PIEUP OE IEUNG
+0x949E 0xBD5E #HANGUL SYLLABLE PIEUP OE CIEUC
+0x949F 0xBD5F #HANGUL SYLLABLE PIEUP OE CHIEUCH
+0x94A0 0xBD60 #HANGUL SYLLABLE PIEUP OE KHIEUKH
+0x94A1 0xBD61 #HANGUL SYLLABLE PIEUP OE THIEUTH
+0x94A2 0xBD62 #HANGUL SYLLABLE PIEUP OE PHIEUPH
+0x94A3 0xBD63 #HANGUL SYLLABLE PIEUP OE HIEUH
+0x94A4 0xBD65 #HANGUL SYLLABLE PIEUP YO KIYEOK
+0x94A5 0xBD66 #HANGUL SYLLABLE PIEUP YO SSANGKIYEOK
+0x94A6 0xBD67 #HANGUL SYLLABLE PIEUP YO KIYEOKSIOS
+0x94A7 0xBD69 #HANGUL SYLLABLE PIEUP YO NIEUNCIEUC
+0x94A8 0xBD6A #HANGUL SYLLABLE PIEUP YO NIEUNHIEUH
+0x94A9 0xBD6B #HANGUL SYLLABLE PIEUP YO TIKEUT
+0x94AA 0xBD6C #HANGUL SYLLABLE PIEUP YO RIEUL
+0x94AB 0xBD6D #HANGUL SYLLABLE PIEUP YO RIEULKIYEOK
+0x94AC 0xBD6E #HANGUL SYLLABLE PIEUP YO RIEULMIEUM
+0x94AD 0xBD6F #HANGUL SYLLABLE PIEUP YO RIEULPIEUP
+0x94AE 0xBD70 #HANGUL SYLLABLE PIEUP YO RIEULSIOS
+0x94AF 0xBD71 #HANGUL SYLLABLE PIEUP YO RIEULTHIEUTH
+0x94B0 0xBD72 #HANGUL SYLLABLE PIEUP YO RIEULPHIEUPH
+0x94B1 0xBD73 #HANGUL SYLLABLE PIEUP YO RIEULHIEUH
+0x94B2 0xBD74 #HANGUL SYLLABLE PIEUP YO MIEUM
+0x94B3 0xBD75 #HANGUL SYLLABLE PIEUP YO PIEUP
+0x94B4 0xBD76 #HANGUL SYLLABLE PIEUP YO PIEUPSIOS
+0x94B5 0xBD77 #HANGUL SYLLABLE PIEUP YO SIOS
+0x94B6 0xBD78 #HANGUL SYLLABLE PIEUP YO SSANGSIOS
+0x94B7 0xBD79 #HANGUL SYLLABLE PIEUP YO IEUNG
+0x94B8 0xBD7A #HANGUL SYLLABLE PIEUP YO CIEUC
+0x94B9 0xBD7B #HANGUL SYLLABLE PIEUP YO CHIEUCH
+0x94BA 0xBD7C #HANGUL SYLLABLE PIEUP YO KHIEUKH
+0x94BB 0xBD7D #HANGUL SYLLABLE PIEUP YO THIEUTH
+0x94BC 0xBD7E #HANGUL SYLLABLE PIEUP YO PHIEUPH
+0x94BD 0xBD7F #HANGUL SYLLABLE PIEUP YO HIEUH
+0x94BE 0xBD82 #HANGUL SYLLABLE PIEUP U SSANGKIYEOK
+0x94BF 0xBD83 #HANGUL SYLLABLE PIEUP U KIYEOKSIOS
+0x94C0 0xBD85 #HANGUL SYLLABLE PIEUP U NIEUNCIEUC
+0x94C1 0xBD86 #HANGUL SYLLABLE PIEUP U NIEUNHIEUH
+0x94C2 0xBD8B #HANGUL SYLLABLE PIEUP U RIEULPIEUP
+0x94C3 0xBD8C #HANGUL SYLLABLE PIEUP U RIEULSIOS
+0x94C4 0xBD8D #HANGUL SYLLABLE PIEUP U RIEULTHIEUTH
+0x94C5 0xBD8E #HANGUL SYLLABLE PIEUP U RIEULPHIEUPH
+0x94C6 0xBD8F #HANGUL SYLLABLE PIEUP U RIEULHIEUH
+0x94C7 0xBD92 #HANGUL SYLLABLE PIEUP U PIEUPSIOS
+0x94C8 0xBD94 #HANGUL SYLLABLE PIEUP U SSANGSIOS
+0x94C9 0xBD96 #HANGUL SYLLABLE PIEUP U CIEUC
+0x94CA 0xBD97 #HANGUL SYLLABLE PIEUP U CHIEUCH
+0x94CB 0xBD98 #HANGUL SYLLABLE PIEUP U KHIEUKH
+0x94CC 0xBD9B #HANGUL SYLLABLE PIEUP U HIEUH
+0x94CD 0xBD9D #HANGUL SYLLABLE PIEUP WEO KIYEOK
+0x94CE 0xBD9E #HANGUL SYLLABLE PIEUP WEO SSANGKIYEOK
+0x94CF 0xBD9F #HANGUL SYLLABLE PIEUP WEO KIYEOKSIOS
+0x94D0 0xBDA0 #HANGUL SYLLABLE PIEUP WEO NIEUN
+0x94D1 0xBDA1 #HANGUL SYLLABLE PIEUP WEO NIEUNCIEUC
+0x94D2 0xBDA2 #HANGUL SYLLABLE PIEUP WEO NIEUNHIEUH
+0x94D3 0xBDA3 #HANGUL SYLLABLE PIEUP WEO TIKEUT
+0x94D4 0xBDA5 #HANGUL SYLLABLE PIEUP WEO RIEULKIYEOK
+0x94D5 0xBDA6 #HANGUL SYLLABLE PIEUP WEO RIEULMIEUM
+0x94D6 0xBDA7 #HANGUL SYLLABLE PIEUP WEO RIEULPIEUP
+0x94D7 0xBDA8 #HANGUL SYLLABLE PIEUP WEO RIEULSIOS
+0x94D8 0xBDA9 #HANGUL SYLLABLE PIEUP WEO RIEULTHIEUTH
+0x94D9 0xBDAA #HANGUL SYLLABLE PIEUP WEO RIEULPHIEUPH
+0x94DA 0xBDAB #HANGUL SYLLABLE PIEUP WEO RIEULHIEUH
+0x94DB 0xBDAC #HANGUL SYLLABLE PIEUP WEO MIEUM
+0x94DC 0xBDAD #HANGUL SYLLABLE PIEUP WEO PIEUP
+0x94DD 0xBDAE #HANGUL SYLLABLE PIEUP WEO PIEUPSIOS
+0x94DE 0xBDAF #HANGUL SYLLABLE PIEUP WEO SIOS
+0x94DF 0xBDB1 #HANGUL SYLLABLE PIEUP WEO IEUNG
+0x94E0 0xBDB2 #HANGUL SYLLABLE PIEUP WEO CIEUC
+0x94E1 0xBDB3 #HANGUL SYLLABLE PIEUP WEO CHIEUCH
+0x94E2 0xBDB4 #HANGUL SYLLABLE PIEUP WEO KHIEUKH
+0x94E3 0xBDB5 #HANGUL SYLLABLE PIEUP WEO THIEUTH
+0x94E4 0xBDB6 #HANGUL SYLLABLE PIEUP WEO PHIEUPH
+0x94E5 0xBDB7 #HANGUL SYLLABLE PIEUP WEO HIEUH
+0x94E6 0xBDB9 #HANGUL SYLLABLE PIEUP WE KIYEOK
+0x94E7 0xBDBA #HANGUL SYLLABLE PIEUP WE SSANGKIYEOK
+0x94E8 0xBDBB #HANGUL SYLLABLE PIEUP WE KIYEOKSIOS
+0x94E9 0xBDBC #HANGUL SYLLABLE PIEUP WE NIEUN
+0x94EA 0xBDBD #HANGUL SYLLABLE PIEUP WE NIEUNCIEUC
+0x94EB 0xBDBE #HANGUL SYLLABLE PIEUP WE NIEUNHIEUH
+0x94EC 0xBDBF #HANGUL SYLLABLE PIEUP WE TIKEUT
+0x94ED 0xBDC0 #HANGUL SYLLABLE PIEUP WE RIEUL
+0x94EE 0xBDC1 #HANGUL SYLLABLE PIEUP WE RIEULKIYEOK
+0x94EF 0xBDC2 #HANGUL SYLLABLE PIEUP WE RIEULMIEUM
+0x94F0 0xBDC3 #HANGUL SYLLABLE PIEUP WE RIEULPIEUP
+0x94F1 0xBDC4 #HANGUL SYLLABLE PIEUP WE RIEULSIOS
+0x94F2 0xBDC5 #HANGUL SYLLABLE PIEUP WE RIEULTHIEUTH
+0x94F3 0xBDC6 #HANGUL SYLLABLE PIEUP WE RIEULPHIEUPH
+0x94F4 0xBDC7 #HANGUL SYLLABLE PIEUP WE RIEULHIEUH
+0x94F5 0xBDC8 #HANGUL SYLLABLE PIEUP WE MIEUM
+0x94F6 0xBDC9 #HANGUL SYLLABLE PIEUP WE PIEUP
+0x94F7 0xBDCA #HANGUL SYLLABLE PIEUP WE PIEUPSIOS
+0x94F8 0xBDCB #HANGUL SYLLABLE PIEUP WE SIOS
+0x94F9 0xBDCC #HANGUL SYLLABLE PIEUP WE SSANGSIOS
+0x94FA 0xBDCD #HANGUL SYLLABLE PIEUP WE IEUNG
+0x94FB 0xBDCE #HANGUL SYLLABLE PIEUP WE CIEUC
+0x94FC 0xBDCF #HANGUL SYLLABLE PIEUP WE CHIEUCH
+0x94FD 0xBDD0 #HANGUL SYLLABLE PIEUP WE KHIEUKH
+0x94FE 0xBDD1 #HANGUL SYLLABLE PIEUP WE THIEUTH
+0x9541 0xBDD2 #HANGUL SYLLABLE PIEUP WE PHIEUPH
+0x9542 0xBDD3 #HANGUL SYLLABLE PIEUP WE HIEUH
+0x9543 0xBDD6 #HANGUL SYLLABLE PIEUP WI SSANGKIYEOK
+0x9544 0xBDD7 #HANGUL SYLLABLE PIEUP WI KIYEOKSIOS
+0x9545 0xBDD9 #HANGUL SYLLABLE PIEUP WI NIEUNCIEUC
+0x9546 0xBDDA #HANGUL SYLLABLE PIEUP WI NIEUNHIEUH
+0x9547 0xBDDB #HANGUL SYLLABLE PIEUP WI TIKEUT
+0x9548 0xBDDD #HANGUL SYLLABLE PIEUP WI RIEULKIYEOK
+0x9549 0xBDDE #HANGUL SYLLABLE PIEUP WI RIEULMIEUM
+0x954A 0xBDDF #HANGUL SYLLABLE PIEUP WI RIEULPIEUP
+0x954B 0xBDE0 #HANGUL SYLLABLE PIEUP WI RIEULSIOS
+0x954C 0xBDE1 #HANGUL SYLLABLE PIEUP WI RIEULTHIEUTH
+0x954D 0xBDE2 #HANGUL SYLLABLE PIEUP WI RIEULPHIEUPH
+0x954E 0xBDE3 #HANGUL SYLLABLE PIEUP WI RIEULHIEUH
+0x954F 0xBDE4 #HANGUL SYLLABLE PIEUP WI MIEUM
+0x9550 0xBDE5 #HANGUL SYLLABLE PIEUP WI PIEUP
+0x9551 0xBDE6 #HANGUL SYLLABLE PIEUP WI PIEUPSIOS
+0x9552 0xBDE7 #HANGUL SYLLABLE PIEUP WI SIOS
+0x9553 0xBDE8 #HANGUL SYLLABLE PIEUP WI SSANGSIOS
+0x9554 0xBDEA #HANGUL SYLLABLE PIEUP WI CIEUC
+0x9555 0xBDEB #HANGUL SYLLABLE PIEUP WI CHIEUCH
+0x9556 0xBDEC #HANGUL SYLLABLE PIEUP WI KHIEUKH
+0x9557 0xBDED #HANGUL SYLLABLE PIEUP WI THIEUTH
+0x9558 0xBDEE #HANGUL SYLLABLE PIEUP WI PHIEUPH
+0x9559 0xBDEF #HANGUL SYLLABLE PIEUP WI HIEUH
+0x955A 0xBDF1 #HANGUL SYLLABLE PIEUP YU KIYEOK
+0x9561 0xBDF2 #HANGUL SYLLABLE PIEUP YU SSANGKIYEOK
+0x9562 0xBDF3 #HANGUL SYLLABLE PIEUP YU KIYEOKSIOS
+0x9563 0xBDF5 #HANGUL SYLLABLE PIEUP YU NIEUNCIEUC
+0x9564 0xBDF6 #HANGUL SYLLABLE PIEUP YU NIEUNHIEUH
+0x9565 0xBDF7 #HANGUL SYLLABLE PIEUP YU TIKEUT
+0x9566 0xBDF9 #HANGUL SYLLABLE PIEUP YU RIEULKIYEOK
+0x9567 0xBDFA #HANGUL SYLLABLE PIEUP YU RIEULMIEUM
+0x9568 0xBDFB #HANGUL SYLLABLE PIEUP YU RIEULPIEUP
+0x9569 0xBDFC #HANGUL SYLLABLE PIEUP YU RIEULSIOS
+0x956A 0xBDFD #HANGUL SYLLABLE PIEUP YU RIEULTHIEUTH
+0x956B 0xBDFE #HANGUL SYLLABLE PIEUP YU RIEULPHIEUPH
+0x956C 0xBDFF #HANGUL SYLLABLE PIEUP YU RIEULHIEUH
+0x956D 0xBE01 #HANGUL SYLLABLE PIEUP YU PIEUP
+0x956E 0xBE02 #HANGUL SYLLABLE PIEUP YU PIEUPSIOS
+0x956F 0xBE04 #HANGUL SYLLABLE PIEUP YU SSANGSIOS
+0x9570 0xBE06 #HANGUL SYLLABLE PIEUP YU CIEUC
+0x9571 0xBE07 #HANGUL SYLLABLE PIEUP YU CHIEUCH
+0x9572 0xBE08 #HANGUL SYLLABLE PIEUP YU KHIEUKH
+0x9573 0xBE09 #HANGUL SYLLABLE PIEUP YU THIEUTH
+0x9574 0xBE0A #HANGUL SYLLABLE PIEUP YU PHIEUPH
+0x9575 0xBE0B #HANGUL SYLLABLE PIEUP YU HIEUH
+0x9576 0xBE0E #HANGUL SYLLABLE PIEUP EU SSANGKIYEOK
+0x9577 0xBE0F #HANGUL SYLLABLE PIEUP EU KIYEOKSIOS
+0x9578 0xBE11 #HANGUL SYLLABLE PIEUP EU NIEUNCIEUC
+0x9579 0xBE12 #HANGUL SYLLABLE PIEUP EU NIEUNHIEUH
+0x957A 0xBE13 #HANGUL SYLLABLE PIEUP EU TIKEUT
+0x9581 0xBE15 #HANGUL SYLLABLE PIEUP EU RIEULKIYEOK
+0x9582 0xBE16 #HANGUL SYLLABLE PIEUP EU RIEULMIEUM
+0x9583 0xBE17 #HANGUL SYLLABLE PIEUP EU RIEULPIEUP
+0x9584 0xBE18 #HANGUL SYLLABLE PIEUP EU RIEULSIOS
+0x9585 0xBE19 #HANGUL SYLLABLE PIEUP EU RIEULTHIEUTH
+0x9586 0xBE1A #HANGUL SYLLABLE PIEUP EU RIEULPHIEUPH
+0x9587 0xBE1B #HANGUL SYLLABLE PIEUP EU RIEULHIEUH
+0x9588 0xBE1E #HANGUL SYLLABLE PIEUP EU PIEUPSIOS
+0x9589 0xBE20 #HANGUL SYLLABLE PIEUP EU SSANGSIOS
+0x958A 0xBE21 #HANGUL SYLLABLE PIEUP EU IEUNG
+0x958B 0xBE22 #HANGUL SYLLABLE PIEUP EU CIEUC
+0x958C 0xBE23 #HANGUL SYLLABLE PIEUP EU CHIEUCH
+0x958D 0xBE24 #HANGUL SYLLABLE PIEUP EU KHIEUKH
+0x958E 0xBE25 #HANGUL SYLLABLE PIEUP EU THIEUTH
+0x958F 0xBE26 #HANGUL SYLLABLE PIEUP EU PHIEUPH
+0x9590 0xBE27 #HANGUL SYLLABLE PIEUP EU HIEUH
+0x9591 0xBE28 #HANGUL SYLLABLE PIEUP YI
+0x9592 0xBE29 #HANGUL SYLLABLE PIEUP YI KIYEOK
+0x9593 0xBE2A #HANGUL SYLLABLE PIEUP YI SSANGKIYEOK
+0x9594 0xBE2B #HANGUL SYLLABLE PIEUP YI KIYEOKSIOS
+0x9595 0xBE2C #HANGUL SYLLABLE PIEUP YI NIEUN
+0x9596 0xBE2D #HANGUL SYLLABLE PIEUP YI NIEUNCIEUC
+0x9597 0xBE2E #HANGUL SYLLABLE PIEUP YI NIEUNHIEUH
+0x9598 0xBE2F #HANGUL SYLLABLE PIEUP YI TIKEUT
+0x9599 0xBE30 #HANGUL SYLLABLE PIEUP YI RIEUL
+0x959A 0xBE31 #HANGUL SYLLABLE PIEUP YI RIEULKIYEOK
+0x959B 0xBE32 #HANGUL SYLLABLE PIEUP YI RIEULMIEUM
+0x959C 0xBE33 #HANGUL SYLLABLE PIEUP YI RIEULPIEUP
+0x959D 0xBE34 #HANGUL SYLLABLE PIEUP YI RIEULSIOS
+0x959E 0xBE35 #HANGUL SYLLABLE PIEUP YI RIEULTHIEUTH
+0x959F 0xBE36 #HANGUL SYLLABLE PIEUP YI RIEULPHIEUPH
+0x95A0 0xBE37 #HANGUL SYLLABLE PIEUP YI RIEULHIEUH
+0x95A1 0xBE38 #HANGUL SYLLABLE PIEUP YI MIEUM
+0x95A2 0xBE39 #HANGUL SYLLABLE PIEUP YI PIEUP
+0x95A3 0xBE3A #HANGUL SYLLABLE PIEUP YI PIEUPSIOS
+0x95A4 0xBE3B #HANGUL SYLLABLE PIEUP YI SIOS
+0x95A5 0xBE3C #HANGUL SYLLABLE PIEUP YI SSANGSIOS
+0x95A6 0xBE3D #HANGUL SYLLABLE PIEUP YI IEUNG
+0x95A7 0xBE3E #HANGUL SYLLABLE PIEUP YI CIEUC
+0x95A8 0xBE3F #HANGUL SYLLABLE PIEUP YI CHIEUCH
+0x95A9 0xBE40 #HANGUL SYLLABLE PIEUP YI KHIEUKH
+0x95AA 0xBE41 #HANGUL SYLLABLE PIEUP YI THIEUTH
+0x95AB 0xBE42 #HANGUL SYLLABLE PIEUP YI PHIEUPH
+0x95AC 0xBE43 #HANGUL SYLLABLE PIEUP YI HIEUH
+0x95AD 0xBE46 #HANGUL SYLLABLE PIEUP I SSANGKIYEOK
+0x95AE 0xBE47 #HANGUL SYLLABLE PIEUP I KIYEOKSIOS
+0x95AF 0xBE49 #HANGUL SYLLABLE PIEUP I NIEUNCIEUC
+0x95B0 0xBE4A #HANGUL SYLLABLE PIEUP I NIEUNHIEUH
+0x95B1 0xBE4B #HANGUL SYLLABLE PIEUP I TIKEUT
+0x95B2 0xBE4D #HANGUL SYLLABLE PIEUP I RIEULKIYEOK
+0x95B3 0xBE4F #HANGUL SYLLABLE PIEUP I RIEULPIEUP
+0x95B4 0xBE50 #HANGUL SYLLABLE PIEUP I RIEULSIOS
+0x95B5 0xBE51 #HANGUL SYLLABLE PIEUP I RIEULTHIEUTH
+0x95B6 0xBE52 #HANGUL SYLLABLE PIEUP I RIEULPHIEUPH
+0x95B7 0xBE53 #HANGUL SYLLABLE PIEUP I RIEULHIEUH
+0x95B8 0xBE56 #HANGUL SYLLABLE PIEUP I PIEUPSIOS
+0x95B9 0xBE58 #HANGUL SYLLABLE PIEUP I SSANGSIOS
+0x95BA 0xBE5C #HANGUL SYLLABLE PIEUP I KHIEUKH
+0x95BB 0xBE5D #HANGUL SYLLABLE PIEUP I THIEUTH
+0x95BC 0xBE5E #HANGUL SYLLABLE PIEUP I PHIEUPH
+0x95BD 0xBE5F #HANGUL SYLLABLE PIEUP I HIEUH
+0x95BE 0xBE62 #HANGUL SYLLABLE SSANGPIEUP A SSANGKIYEOK
+0x95BF 0xBE63 #HANGUL SYLLABLE SSANGPIEUP A KIYEOKSIOS
+0x95C0 0xBE65 #HANGUL SYLLABLE SSANGPIEUP A NIEUNCIEUC
+0x95C1 0xBE66 #HANGUL SYLLABLE SSANGPIEUP A NIEUNHIEUH
+0x95C2 0xBE67 #HANGUL SYLLABLE SSANGPIEUP A TIKEUT
+0x95C3 0xBE69 #HANGUL SYLLABLE SSANGPIEUP A RIEULKIYEOK
+0x95C4 0xBE6B #HANGUL SYLLABLE SSANGPIEUP A RIEULPIEUP
+0x95C5 0xBE6C #HANGUL SYLLABLE SSANGPIEUP A RIEULSIOS
+0x95C6 0xBE6D #HANGUL SYLLABLE SSANGPIEUP A RIEULTHIEUTH
+0x95C7 0xBE6E #HANGUL SYLLABLE SSANGPIEUP A RIEULPHIEUPH
+0x95C8 0xBE6F #HANGUL SYLLABLE SSANGPIEUP A RIEULHIEUH
+0x95C9 0xBE72 #HANGUL SYLLABLE SSANGPIEUP A PIEUPSIOS
+0x95CA 0xBE76 #HANGUL SYLLABLE SSANGPIEUP A CIEUC
+0x95CB 0xBE77 #HANGUL SYLLABLE SSANGPIEUP A CHIEUCH
+0x95CC 0xBE78 #HANGUL SYLLABLE SSANGPIEUP A KHIEUKH
+0x95CD 0xBE79 #HANGUL SYLLABLE SSANGPIEUP A THIEUTH
+0x95CE 0xBE7A #HANGUL SYLLABLE SSANGPIEUP A PHIEUPH
+0x95CF 0xBE7E #HANGUL SYLLABLE SSANGPIEUP AE SSANGKIYEOK
+0x95D0 0xBE7F #HANGUL SYLLABLE SSANGPIEUP AE KIYEOKSIOS
+0x95D1 0xBE81 #HANGUL SYLLABLE SSANGPIEUP AE NIEUNCIEUC
+0x95D2 0xBE82 #HANGUL SYLLABLE SSANGPIEUP AE NIEUNHIEUH
+0x95D3 0xBE83 #HANGUL SYLLABLE SSANGPIEUP AE TIKEUT
+0x95D4 0xBE85 #HANGUL SYLLABLE SSANGPIEUP AE RIEULKIYEOK
+0x95D5 0xBE86 #HANGUL SYLLABLE SSANGPIEUP AE RIEULMIEUM
+0x95D6 0xBE87 #HANGUL SYLLABLE SSANGPIEUP AE RIEULPIEUP
+0x95D7 0xBE88 #HANGUL SYLLABLE SSANGPIEUP AE RIEULSIOS
+0x95D8 0xBE89 #HANGUL SYLLABLE SSANGPIEUP AE RIEULTHIEUTH
+0x95D9 0xBE8A #HANGUL SYLLABLE SSANGPIEUP AE RIEULPHIEUPH
+0x95DA 0xBE8B #HANGUL SYLLABLE SSANGPIEUP AE RIEULHIEUH
+0x95DB 0xBE8E #HANGUL SYLLABLE SSANGPIEUP AE PIEUPSIOS
+0x95DC 0xBE92 #HANGUL SYLLABLE SSANGPIEUP AE CIEUC
+0x95DD 0xBE93 #HANGUL SYLLABLE SSANGPIEUP AE CHIEUCH
+0x95DE 0xBE94 #HANGUL SYLLABLE SSANGPIEUP AE KHIEUKH
+0x95DF 0xBE95 #HANGUL SYLLABLE SSANGPIEUP AE THIEUTH
+0x95E0 0xBE96 #HANGUL SYLLABLE SSANGPIEUP AE PHIEUPH
+0x95E1 0xBE97 #HANGUL SYLLABLE SSANGPIEUP AE HIEUH
+0x95E2 0xBE9A #HANGUL SYLLABLE SSANGPIEUP YA SSANGKIYEOK
+0x95E3 0xBE9B #HANGUL SYLLABLE SSANGPIEUP YA KIYEOKSIOS
+0x95E4 0xBE9C #HANGUL SYLLABLE SSANGPIEUP YA NIEUN
+0x95E5 0xBE9D #HANGUL SYLLABLE SSANGPIEUP YA NIEUNCIEUC
+0x95E6 0xBE9E #HANGUL SYLLABLE SSANGPIEUP YA NIEUNHIEUH
+0x95E7 0xBE9F #HANGUL SYLLABLE SSANGPIEUP YA TIKEUT
+0x95E8 0xBEA0 #HANGUL SYLLABLE SSANGPIEUP YA RIEUL
+0x95E9 0xBEA1 #HANGUL SYLLABLE SSANGPIEUP YA RIEULKIYEOK
+0x95EA 0xBEA2 #HANGUL SYLLABLE SSANGPIEUP YA RIEULMIEUM
+0x95EB 0xBEA3 #HANGUL SYLLABLE SSANGPIEUP YA RIEULPIEUP
+0x95EC 0xBEA4 #HANGUL SYLLABLE SSANGPIEUP YA RIEULSIOS
+0x95ED 0xBEA5 #HANGUL SYLLABLE SSANGPIEUP YA RIEULTHIEUTH
+0x95EE 0xBEA6 #HANGUL SYLLABLE SSANGPIEUP YA RIEULPHIEUPH
+0x95EF 0xBEA7 #HANGUL SYLLABLE SSANGPIEUP YA RIEULHIEUH
+0x95F0 0xBEA9 #HANGUL SYLLABLE SSANGPIEUP YA PIEUP
+0x95F1 0xBEAA #HANGUL SYLLABLE SSANGPIEUP YA PIEUPSIOS
+0x95F2 0xBEAB #HANGUL SYLLABLE SSANGPIEUP YA SIOS
+0x95F3 0xBEAC #HANGUL SYLLABLE SSANGPIEUP YA SSANGSIOS
+0x95F4 0xBEAD #HANGUL SYLLABLE SSANGPIEUP YA IEUNG
+0x95F5 0xBEAE #HANGUL SYLLABLE SSANGPIEUP YA CIEUC
+0x95F6 0xBEAF #HANGUL SYLLABLE SSANGPIEUP YA CHIEUCH
+0x95F7 0xBEB0 #HANGUL SYLLABLE SSANGPIEUP YA KHIEUKH
+0x95F8 0xBEB1 #HANGUL SYLLABLE SSANGPIEUP YA THIEUTH
+0x95F9 0xBEB2 #HANGUL SYLLABLE SSANGPIEUP YA PHIEUPH
+0x95FA 0xBEB3 #HANGUL SYLLABLE SSANGPIEUP YA HIEUH
+0x95FB 0xBEB4 #HANGUL SYLLABLE SSANGPIEUP YAE
+0x95FC 0xBEB5 #HANGUL SYLLABLE SSANGPIEUP YAE KIYEOK
+0x95FD 0xBEB6 #HANGUL SYLLABLE SSANGPIEUP YAE SSANGKIYEOK
+0x95FE 0xBEB7 #HANGUL SYLLABLE SSANGPIEUP YAE KIYEOKSIOS
+0x9641 0xBEB8 #HANGUL SYLLABLE SSANGPIEUP YAE NIEUN
+0x9642 0xBEB9 #HANGUL SYLLABLE SSANGPIEUP YAE NIEUNCIEUC
+0x9643 0xBEBA #HANGUL SYLLABLE SSANGPIEUP YAE NIEUNHIEUH
+0x9644 0xBEBB #HANGUL SYLLABLE SSANGPIEUP YAE TIKEUT
+0x9645 0xBEBC #HANGUL SYLLABLE SSANGPIEUP YAE RIEUL
+0x9646 0xBEBD #HANGUL SYLLABLE SSANGPIEUP YAE RIEULKIYEOK
+0x9647 0xBEBE #HANGUL SYLLABLE SSANGPIEUP YAE RIEULMIEUM
+0x9648 0xBEBF #HANGUL SYLLABLE SSANGPIEUP YAE RIEULPIEUP
+0x9649 0xBEC0 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULSIOS
+0x964A 0xBEC1 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULTHIEUTH
+0x964B 0xBEC2 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULPHIEUPH
+0x964C 0xBEC3 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULHIEUH
+0x964D 0xBEC4 #HANGUL SYLLABLE SSANGPIEUP YAE MIEUM
+0x964E 0xBEC5 #HANGUL SYLLABLE SSANGPIEUP YAE PIEUP
+0x964F 0xBEC6 #HANGUL SYLLABLE SSANGPIEUP YAE PIEUPSIOS
+0x9650 0xBEC7 #HANGUL SYLLABLE SSANGPIEUP YAE SIOS
+0x9651 0xBEC8 #HANGUL SYLLABLE SSANGPIEUP YAE SSANGSIOS
+0x9652 0xBEC9 #HANGUL SYLLABLE SSANGPIEUP YAE IEUNG
+0x9653 0xBECA #HANGUL SYLLABLE SSANGPIEUP YAE CIEUC
+0x9654 0xBECB #HANGUL SYLLABLE SSANGPIEUP YAE CHIEUCH
+0x9655 0xBECC #HANGUL SYLLABLE SSANGPIEUP YAE KHIEUKH
+0x9656 0xBECD #HANGUL SYLLABLE SSANGPIEUP YAE THIEUTH
+0x9657 0xBECE #HANGUL SYLLABLE SSANGPIEUP YAE PHIEUPH
+0x9658 0xBECF #HANGUL SYLLABLE SSANGPIEUP YAE HIEUH
+0x9659 0xBED2 #HANGUL SYLLABLE SSANGPIEUP EO SSANGKIYEOK
+0x965A 0xBED3 #HANGUL SYLLABLE SSANGPIEUP EO KIYEOKSIOS
+0x9661 0xBED5 #HANGUL SYLLABLE SSANGPIEUP EO NIEUNCIEUC
+0x9662 0xBED6 #HANGUL SYLLABLE SSANGPIEUP EO NIEUNHIEUH
+0x9663 0xBED9 #HANGUL SYLLABLE SSANGPIEUP EO RIEULKIYEOK
+0x9664 0xBEDA #HANGUL SYLLABLE SSANGPIEUP EO RIEULMIEUM
+0x9665 0xBEDB #HANGUL SYLLABLE SSANGPIEUP EO RIEULPIEUP
+0x9666 0xBEDC #HANGUL SYLLABLE SSANGPIEUP EO RIEULSIOS
+0x9667 0xBEDD #HANGUL SYLLABLE SSANGPIEUP EO RIEULTHIEUTH
+0x9668 0xBEDE #HANGUL SYLLABLE SSANGPIEUP EO RIEULPHIEUPH
+0x9669 0xBEDF #HANGUL SYLLABLE SSANGPIEUP EO RIEULHIEUH
+0x966A 0xBEE1 #HANGUL SYLLABLE SSANGPIEUP EO PIEUP
+0x966B 0xBEE2 #HANGUL SYLLABLE SSANGPIEUP EO PIEUPSIOS
+0x966C 0xBEE6 #HANGUL SYLLABLE SSANGPIEUP EO CIEUC
+0x966D 0xBEE7 #HANGUL SYLLABLE SSANGPIEUP EO CHIEUCH
+0x966E 0xBEE8 #HANGUL SYLLABLE SSANGPIEUP EO KHIEUKH
+0x966F 0xBEE9 #HANGUL SYLLABLE SSANGPIEUP EO THIEUTH
+0x9670 0xBEEA #HANGUL SYLLABLE SSANGPIEUP EO PHIEUPH
+0x9671 0xBEEB #HANGUL SYLLABLE SSANGPIEUP EO HIEUH
+0x9672 0xBEED #HANGUL SYLLABLE SSANGPIEUP E KIYEOK
+0x9673 0xBEEE #HANGUL SYLLABLE SSANGPIEUP E SSANGKIYEOK
+0x9674 0xBEEF #HANGUL SYLLABLE SSANGPIEUP E KIYEOKSIOS
+0x9675 0xBEF0 #HANGUL SYLLABLE SSANGPIEUP E NIEUN
+0x9676 0xBEF1 #HANGUL SYLLABLE SSANGPIEUP E NIEUNCIEUC
+0x9677 0xBEF2 #HANGUL SYLLABLE SSANGPIEUP E NIEUNHIEUH
+0x9678 0xBEF3 #HANGUL SYLLABLE SSANGPIEUP E TIKEUT
+0x9679 0xBEF4 #HANGUL SYLLABLE SSANGPIEUP E RIEUL
+0x967A 0xBEF5 #HANGUL SYLLABLE SSANGPIEUP E RIEULKIYEOK
+0x9681 0xBEF6 #HANGUL SYLLABLE SSANGPIEUP E RIEULMIEUM
+0x9682 0xBEF7 #HANGUL SYLLABLE SSANGPIEUP E RIEULPIEUP
+0x9683 0xBEF8 #HANGUL SYLLABLE SSANGPIEUP E RIEULSIOS
+0x9684 0xBEF9 #HANGUL SYLLABLE SSANGPIEUP E RIEULTHIEUTH
+0x9685 0xBEFA #HANGUL SYLLABLE SSANGPIEUP E RIEULPHIEUPH
+0x9686 0xBEFB #HANGUL SYLLABLE SSANGPIEUP E RIEULHIEUH
+0x9687 0xBEFC #HANGUL SYLLABLE SSANGPIEUP E MIEUM
+0x9688 0xBEFD #HANGUL SYLLABLE SSANGPIEUP E PIEUP
+0x9689 0xBEFE #HANGUL SYLLABLE SSANGPIEUP E PIEUPSIOS
+0x968A 0xBEFF #HANGUL SYLLABLE SSANGPIEUP E SIOS
+0x968B 0xBF00 #HANGUL SYLLABLE SSANGPIEUP E SSANGSIOS
+0x968C 0xBF02 #HANGUL SYLLABLE SSANGPIEUP E CIEUC
+0x968D 0xBF03 #HANGUL SYLLABLE SSANGPIEUP E CHIEUCH
+0x968E 0xBF04 #HANGUL SYLLABLE SSANGPIEUP E KHIEUKH
+0x968F 0xBF05 #HANGUL SYLLABLE SSANGPIEUP E THIEUTH
+0x9690 0xBF06 #HANGUL SYLLABLE SSANGPIEUP E PHIEUPH
+0x9691 0xBF07 #HANGUL SYLLABLE SSANGPIEUP E HIEUH
+0x9692 0xBF0A #HANGUL SYLLABLE SSANGPIEUP YEO SSANGKIYEOK
+0x9693 0xBF0B #HANGUL SYLLABLE SSANGPIEUP YEO KIYEOKSIOS
+0x9694 0xBF0C #HANGUL SYLLABLE SSANGPIEUP YEO NIEUN
+0x9695 0xBF0D #HANGUL SYLLABLE SSANGPIEUP YEO NIEUNCIEUC
+0x9696 0xBF0E #HANGUL SYLLABLE SSANGPIEUP YEO NIEUNHIEUH
+0x9697 0xBF0F #HANGUL SYLLABLE SSANGPIEUP YEO TIKEUT
+0x9698 0xBF10 #HANGUL SYLLABLE SSANGPIEUP YEO RIEUL
+0x9699 0xBF11 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULKIYEOK
+0x969A 0xBF12 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULMIEUM
+0x969B 0xBF13 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULPIEUP
+0x969C 0xBF14 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULSIOS
+0x969D 0xBF15 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULTHIEUTH
+0x969E 0xBF16 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULPHIEUPH
+0x969F 0xBF17 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULHIEUH
+0x96A0 0xBF1A #HANGUL SYLLABLE SSANGPIEUP YEO PIEUPSIOS
+0x96A1 0xBF1E #HANGUL SYLLABLE SSANGPIEUP YEO CIEUC
+0x96A2 0xBF1F #HANGUL SYLLABLE SSANGPIEUP YEO CHIEUCH
+0x96A3 0xBF20 #HANGUL SYLLABLE SSANGPIEUP YEO KHIEUKH
+0x96A4 0xBF21 #HANGUL SYLLABLE SSANGPIEUP YEO THIEUTH
+0x96A5 0xBF22 #HANGUL SYLLABLE SSANGPIEUP YEO PHIEUPH
+0x96A6 0xBF23 #HANGUL SYLLABLE SSANGPIEUP YEO HIEUH
+0x96A7 0xBF24 #HANGUL SYLLABLE SSANGPIEUP YE
+0x96A8 0xBF25 #HANGUL SYLLABLE SSANGPIEUP YE KIYEOK
+0x96A9 0xBF26 #HANGUL SYLLABLE SSANGPIEUP YE SSANGKIYEOK
+0x96AA 0xBF27 #HANGUL SYLLABLE SSANGPIEUP YE KIYEOKSIOS
+0x96AB 0xBF28 #HANGUL SYLLABLE SSANGPIEUP YE NIEUN
+0x96AC 0xBF29 #HANGUL SYLLABLE SSANGPIEUP YE NIEUNCIEUC
+0x96AD 0xBF2A #HANGUL SYLLABLE SSANGPIEUP YE NIEUNHIEUH
+0x96AE 0xBF2B #HANGUL SYLLABLE SSANGPIEUP YE TIKEUT
+0x96AF 0xBF2C #HANGUL SYLLABLE SSANGPIEUP YE RIEUL
+0x96B0 0xBF2D #HANGUL SYLLABLE SSANGPIEUP YE RIEULKIYEOK
+0x96B1 0xBF2E #HANGUL SYLLABLE SSANGPIEUP YE RIEULMIEUM
+0x96B2 0xBF2F #HANGUL SYLLABLE SSANGPIEUP YE RIEULPIEUP
+0x96B3 0xBF30 #HANGUL SYLLABLE SSANGPIEUP YE RIEULSIOS
+0x96B4 0xBF31 #HANGUL SYLLABLE SSANGPIEUP YE RIEULTHIEUTH
+0x96B5 0xBF32 #HANGUL SYLLABLE SSANGPIEUP YE RIEULPHIEUPH
+0x96B6 0xBF33 #HANGUL SYLLABLE SSANGPIEUP YE RIEULHIEUH
+0x96B7 0xBF34 #HANGUL SYLLABLE SSANGPIEUP YE MIEUM
+0x96B8 0xBF35 #HANGUL SYLLABLE SSANGPIEUP YE PIEUP
+0x96B9 0xBF36 #HANGUL SYLLABLE SSANGPIEUP YE PIEUPSIOS
+0x96BA 0xBF37 #HANGUL SYLLABLE SSANGPIEUP YE SIOS
+0x96BB 0xBF38 #HANGUL SYLLABLE SSANGPIEUP YE SSANGSIOS
+0x96BC 0xBF39 #HANGUL SYLLABLE SSANGPIEUP YE IEUNG
+0x96BD 0xBF3A #HANGUL SYLLABLE SSANGPIEUP YE CIEUC
+0x96BE 0xBF3B #HANGUL SYLLABLE SSANGPIEUP YE CHIEUCH
+0x96BF 0xBF3C #HANGUL SYLLABLE SSANGPIEUP YE KHIEUKH
+0x96C0 0xBF3D #HANGUL SYLLABLE SSANGPIEUP YE THIEUTH
+0x96C1 0xBF3E #HANGUL SYLLABLE SSANGPIEUP YE PHIEUPH
+0x96C2 0xBF3F #HANGUL SYLLABLE SSANGPIEUP YE HIEUH
+0x96C3 0xBF42 #HANGUL SYLLABLE SSANGPIEUP O SSANGKIYEOK
+0x96C4 0xBF43 #HANGUL SYLLABLE SSANGPIEUP O KIYEOKSIOS
+0x96C5 0xBF45 #HANGUL SYLLABLE SSANGPIEUP O NIEUNCIEUC
+0x96C6 0xBF46 #HANGUL SYLLABLE SSANGPIEUP O NIEUNHIEUH
+0x96C7 0xBF47 #HANGUL SYLLABLE SSANGPIEUP O TIKEUT
+0x96C8 0xBF49 #HANGUL SYLLABLE SSANGPIEUP O RIEULKIYEOK
+0x96C9 0xBF4A #HANGUL SYLLABLE SSANGPIEUP O RIEULMIEUM
+0x96CA 0xBF4B #HANGUL SYLLABLE SSANGPIEUP O RIEULPIEUP
+0x96CB 0xBF4C #HANGUL SYLLABLE SSANGPIEUP O RIEULSIOS
+0x96CC 0xBF4D #HANGUL SYLLABLE SSANGPIEUP O RIEULTHIEUTH
+0x96CD 0xBF4E #HANGUL SYLLABLE SSANGPIEUP O RIEULPHIEUPH
+0x96CE 0xBF4F #HANGUL SYLLABLE SSANGPIEUP O RIEULHIEUH
+0x96CF 0xBF52 #HANGUL SYLLABLE SSANGPIEUP O PIEUPSIOS
+0x96D0 0xBF53 #HANGUL SYLLABLE SSANGPIEUP O SIOS
+0x96D1 0xBF54 #HANGUL SYLLABLE SSANGPIEUP O SSANGSIOS
+0x96D2 0xBF56 #HANGUL SYLLABLE SSANGPIEUP O CIEUC
+0x96D3 0xBF57 #HANGUL SYLLABLE SSANGPIEUP O CHIEUCH
+0x96D4 0xBF58 #HANGUL SYLLABLE SSANGPIEUP O KHIEUKH
+0x96D5 0xBF59 #HANGUL SYLLABLE SSANGPIEUP O THIEUTH
+0x96D6 0xBF5A #HANGUL SYLLABLE SSANGPIEUP O PHIEUPH
+0x96D7 0xBF5B #HANGUL SYLLABLE SSANGPIEUP O HIEUH
+0x96D8 0xBF5C #HANGUL SYLLABLE SSANGPIEUP WA
+0x96D9 0xBF5D #HANGUL SYLLABLE SSANGPIEUP WA KIYEOK
+0x96DA 0xBF5E #HANGUL SYLLABLE SSANGPIEUP WA SSANGKIYEOK
+0x96DB 0xBF5F #HANGUL SYLLABLE SSANGPIEUP WA KIYEOKSIOS
+0x96DC 0xBF60 #HANGUL SYLLABLE SSANGPIEUP WA NIEUN
+0x96DD 0xBF61 #HANGUL SYLLABLE SSANGPIEUP WA NIEUNCIEUC
+0x96DE 0xBF62 #HANGUL SYLLABLE SSANGPIEUP WA NIEUNHIEUH
+0x96DF 0xBF63 #HANGUL SYLLABLE SSANGPIEUP WA TIKEUT
+0x96E0 0xBF64 #HANGUL SYLLABLE SSANGPIEUP WA RIEUL
+0x96E1 0xBF65 #HANGUL SYLLABLE SSANGPIEUP WA RIEULKIYEOK
+0x96E2 0xBF66 #HANGUL SYLLABLE SSANGPIEUP WA RIEULMIEUM
+0x96E3 0xBF67 #HANGUL SYLLABLE SSANGPIEUP WA RIEULPIEUP
+0x96E4 0xBF68 #HANGUL SYLLABLE SSANGPIEUP WA RIEULSIOS
+0x96E5 0xBF69 #HANGUL SYLLABLE SSANGPIEUP WA RIEULTHIEUTH
+0x96E6 0xBF6A #HANGUL SYLLABLE SSANGPIEUP WA RIEULPHIEUPH
+0x96E7 0xBF6B #HANGUL SYLLABLE SSANGPIEUP WA RIEULHIEUH
+0x96E8 0xBF6C #HANGUL SYLLABLE SSANGPIEUP WA MIEUM
+0x96E9 0xBF6D #HANGUL SYLLABLE SSANGPIEUP WA PIEUP
+0x96EA 0xBF6E #HANGUL SYLLABLE SSANGPIEUP WA PIEUPSIOS
+0x96EB 0xBF6F #HANGUL SYLLABLE SSANGPIEUP WA SIOS
+0x96EC 0xBF70 #HANGUL SYLLABLE SSANGPIEUP WA SSANGSIOS
+0x96ED 0xBF71 #HANGUL SYLLABLE SSANGPIEUP WA IEUNG
+0x96EE 0xBF72 #HANGUL SYLLABLE SSANGPIEUP WA CIEUC
+0x96EF 0xBF73 #HANGUL SYLLABLE SSANGPIEUP WA CHIEUCH
+0x96F0 0xBF74 #HANGUL SYLLABLE SSANGPIEUP WA KHIEUKH
+0x96F1 0xBF75 #HANGUL SYLLABLE SSANGPIEUP WA THIEUTH
+0x96F2 0xBF76 #HANGUL SYLLABLE SSANGPIEUP WA PHIEUPH
+0x96F3 0xBF77 #HANGUL SYLLABLE SSANGPIEUP WA HIEUH
+0x96F4 0xBF78 #HANGUL SYLLABLE SSANGPIEUP WAE
+0x96F5 0xBF79 #HANGUL SYLLABLE SSANGPIEUP WAE KIYEOK
+0x96F6 0xBF7A #HANGUL SYLLABLE SSANGPIEUP WAE SSANGKIYEOK
+0x96F7 0xBF7B #HANGUL SYLLABLE SSANGPIEUP WAE KIYEOKSIOS
+0x96F8 0xBF7C #HANGUL SYLLABLE SSANGPIEUP WAE NIEUN
+0x96F9 0xBF7D #HANGUL SYLLABLE SSANGPIEUP WAE NIEUNCIEUC
+0x96FA 0xBF7E #HANGUL SYLLABLE SSANGPIEUP WAE NIEUNHIEUH
+0x96FB 0xBF7F #HANGUL SYLLABLE SSANGPIEUP WAE TIKEUT
+0x96FC 0xBF80 #HANGUL SYLLABLE SSANGPIEUP WAE RIEUL
+0x96FD 0xBF81 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULKIYEOK
+0x96FE 0xBF82 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULMIEUM
+0x9741 0xBF83 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULPIEUP
+0x9742 0xBF84 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULSIOS
+0x9743 0xBF85 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULTHIEUTH
+0x9744 0xBF86 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULPHIEUPH
+0x9745 0xBF87 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULHIEUH
+0x9746 0xBF88 #HANGUL SYLLABLE SSANGPIEUP WAE MIEUM
+0x9747 0xBF89 #HANGUL SYLLABLE SSANGPIEUP WAE PIEUP
+0x9748 0xBF8A #HANGUL SYLLABLE SSANGPIEUP WAE PIEUPSIOS
+0x9749 0xBF8B #HANGUL SYLLABLE SSANGPIEUP WAE SIOS
+0x974A 0xBF8C #HANGUL SYLLABLE SSANGPIEUP WAE SSANGSIOS
+0x974B 0xBF8D #HANGUL SYLLABLE SSANGPIEUP WAE IEUNG
+0x974C 0xBF8E #HANGUL SYLLABLE SSANGPIEUP WAE CIEUC
+0x974D 0xBF8F #HANGUL SYLLABLE SSANGPIEUP WAE CHIEUCH
+0x974E 0xBF90 #HANGUL SYLLABLE SSANGPIEUP WAE KHIEUKH
+0x974F 0xBF91 #HANGUL SYLLABLE SSANGPIEUP WAE THIEUTH
+0x9750 0xBF92 #HANGUL SYLLABLE SSANGPIEUP WAE PHIEUPH
+0x9751 0xBF93 #HANGUL SYLLABLE SSANGPIEUP WAE HIEUH
+0x9752 0xBF95 #HANGUL SYLLABLE SSANGPIEUP OE KIYEOK
+0x9753 0xBF96 #HANGUL SYLLABLE SSANGPIEUP OE SSANGKIYEOK
+0x9754 0xBF97 #HANGUL SYLLABLE SSANGPIEUP OE KIYEOKSIOS
+0x9755 0xBF98 #HANGUL SYLLABLE SSANGPIEUP OE NIEUN
+0x9756 0xBF99 #HANGUL SYLLABLE SSANGPIEUP OE NIEUNCIEUC
+0x9757 0xBF9A #HANGUL SYLLABLE SSANGPIEUP OE NIEUNHIEUH
+0x9758 0xBF9B #HANGUL SYLLABLE SSANGPIEUP OE TIKEUT
+0x9759 0xBF9C #HANGUL SYLLABLE SSANGPIEUP OE RIEUL
+0x975A 0xBF9D #HANGUL SYLLABLE SSANGPIEUP OE RIEULKIYEOK
+0x9761 0xBF9E #HANGUL SYLLABLE SSANGPIEUP OE RIEULMIEUM
+0x9762 0xBF9F #HANGUL SYLLABLE SSANGPIEUP OE RIEULPIEUP
+0x9763 0xBFA0 #HANGUL SYLLABLE SSANGPIEUP OE RIEULSIOS
+0x9764 0xBFA1 #HANGUL SYLLABLE SSANGPIEUP OE RIEULTHIEUTH
+0x9765 0xBFA2 #HANGUL SYLLABLE SSANGPIEUP OE RIEULPHIEUPH
+0x9766 0xBFA3 #HANGUL SYLLABLE SSANGPIEUP OE RIEULHIEUH
+0x9767 0xBFA4 #HANGUL SYLLABLE SSANGPIEUP OE MIEUM
+0x9768 0xBFA5 #HANGUL SYLLABLE SSANGPIEUP OE PIEUP
+0x9769 0xBFA6 #HANGUL SYLLABLE SSANGPIEUP OE PIEUPSIOS
+0x976A 0xBFA7 #HANGUL SYLLABLE SSANGPIEUP OE SIOS
+0x976B 0xBFA8 #HANGUL SYLLABLE SSANGPIEUP OE SSANGSIOS
+0x976C 0xBFA9 #HANGUL SYLLABLE SSANGPIEUP OE IEUNG
+0x976D 0xBFAA #HANGUL SYLLABLE SSANGPIEUP OE CIEUC
+0x976E 0xBFAB #HANGUL SYLLABLE SSANGPIEUP OE CHIEUCH
+0x976F 0xBFAC #HANGUL SYLLABLE SSANGPIEUP OE KHIEUKH
+0x9770 0xBFAD #HANGUL SYLLABLE SSANGPIEUP OE THIEUTH
+0x9771 0xBFAE #HANGUL SYLLABLE SSANGPIEUP OE PHIEUPH
+0x9772 0xBFAF #HANGUL SYLLABLE SSANGPIEUP OE HIEUH
+0x9773 0xBFB1 #HANGUL SYLLABLE SSANGPIEUP YO KIYEOK
+0x9774 0xBFB2 #HANGUL SYLLABLE SSANGPIEUP YO SSANGKIYEOK
+0x9775 0xBFB3 #HANGUL SYLLABLE SSANGPIEUP YO KIYEOKSIOS
+0x9776 0xBFB4 #HANGUL SYLLABLE SSANGPIEUP YO NIEUN
+0x9777 0xBFB5 #HANGUL SYLLABLE SSANGPIEUP YO NIEUNCIEUC
+0x9778 0xBFB6 #HANGUL SYLLABLE SSANGPIEUP YO NIEUNHIEUH
+0x9779 0xBFB7 #HANGUL SYLLABLE SSANGPIEUP YO TIKEUT
+0x977A 0xBFB8 #HANGUL SYLLABLE SSANGPIEUP YO RIEUL
+0x9781 0xBFB9 #HANGUL SYLLABLE SSANGPIEUP YO RIEULKIYEOK
+0x9782 0xBFBA #HANGUL SYLLABLE SSANGPIEUP YO RIEULMIEUM
+0x9783 0xBFBB #HANGUL SYLLABLE SSANGPIEUP YO RIEULPIEUP
+0x9784 0xBFBC #HANGUL SYLLABLE SSANGPIEUP YO RIEULSIOS
+0x9785 0xBFBD #HANGUL SYLLABLE SSANGPIEUP YO RIEULTHIEUTH
+0x9786 0xBFBE #HANGUL SYLLABLE SSANGPIEUP YO RIEULPHIEUPH
+0x9787 0xBFBF #HANGUL SYLLABLE SSANGPIEUP YO RIEULHIEUH
+0x9788 0xBFC0 #HANGUL SYLLABLE SSANGPIEUP YO MIEUM
+0x9789 0xBFC1 #HANGUL SYLLABLE SSANGPIEUP YO PIEUP
+0x978A 0xBFC2 #HANGUL SYLLABLE SSANGPIEUP YO PIEUPSIOS
+0x978B 0xBFC3 #HANGUL SYLLABLE SSANGPIEUP YO SIOS
+0x978C 0xBFC4 #HANGUL SYLLABLE SSANGPIEUP YO SSANGSIOS
+0x978D 0xBFC6 #HANGUL SYLLABLE SSANGPIEUP YO CIEUC
+0x978E 0xBFC7 #HANGUL SYLLABLE SSANGPIEUP YO CHIEUCH
+0x978F 0xBFC8 #HANGUL SYLLABLE SSANGPIEUP YO KHIEUKH
+0x9790 0xBFC9 #HANGUL SYLLABLE SSANGPIEUP YO THIEUTH
+0x9791 0xBFCA #HANGUL SYLLABLE SSANGPIEUP YO PHIEUPH
+0x9792 0xBFCB #HANGUL SYLLABLE SSANGPIEUP YO HIEUH
+0x9793 0xBFCE #HANGUL SYLLABLE SSANGPIEUP U SSANGKIYEOK
+0x9794 0xBFCF #HANGUL SYLLABLE SSANGPIEUP U KIYEOKSIOS
+0x9795 0xBFD1 #HANGUL SYLLABLE SSANGPIEUP U NIEUNCIEUC
+0x9796 0xBFD2 #HANGUL SYLLABLE SSANGPIEUP U NIEUNHIEUH
+0x9797 0xBFD3 #HANGUL SYLLABLE SSANGPIEUP U TIKEUT
+0x9798 0xBFD5 #HANGUL SYLLABLE SSANGPIEUP U RIEULKIYEOK
+0x9799 0xBFD6 #HANGUL SYLLABLE SSANGPIEUP U RIEULMIEUM
+0x979A 0xBFD7 #HANGUL SYLLABLE SSANGPIEUP U RIEULPIEUP
+0x979B 0xBFD8 #HANGUL SYLLABLE SSANGPIEUP U RIEULSIOS
+0x979C 0xBFD9 #HANGUL SYLLABLE SSANGPIEUP U RIEULTHIEUTH
+0x979D 0xBFDA #HANGUL SYLLABLE SSANGPIEUP U RIEULPHIEUPH
+0x979E 0xBFDB #HANGUL SYLLABLE SSANGPIEUP U RIEULHIEUH
+0x979F 0xBFDD #HANGUL SYLLABLE SSANGPIEUP U PIEUP
+0x97A0 0xBFDE #HANGUL SYLLABLE SSANGPIEUP U PIEUPSIOS
+0x97A1 0xBFE0 #HANGUL SYLLABLE SSANGPIEUP U SSANGSIOS
+0x97A2 0xBFE2 #HANGUL SYLLABLE SSANGPIEUP U CIEUC
+0x97A3 0xBFE3 #HANGUL SYLLABLE SSANGPIEUP U CHIEUCH
+0x97A4 0xBFE4 #HANGUL SYLLABLE SSANGPIEUP U KHIEUKH
+0x97A5 0xBFE5 #HANGUL SYLLABLE SSANGPIEUP U THIEUTH
+0x97A6 0xBFE6 #HANGUL SYLLABLE SSANGPIEUP U PHIEUPH
+0x97A7 0xBFE7 #HANGUL SYLLABLE SSANGPIEUP U HIEUH
+0x97A8 0xBFE8 #HANGUL SYLLABLE SSANGPIEUP WEO
+0x97A9 0xBFE9 #HANGUL SYLLABLE SSANGPIEUP WEO KIYEOK
+0x97AA 0xBFEA #HANGUL SYLLABLE SSANGPIEUP WEO SSANGKIYEOK
+0x97AB 0xBFEB #HANGUL SYLLABLE SSANGPIEUP WEO KIYEOKSIOS
+0x97AC 0xBFEC #HANGUL SYLLABLE SSANGPIEUP WEO NIEUN
+0x97AD 0xBFED #HANGUL SYLLABLE SSANGPIEUP WEO NIEUNCIEUC
+0x97AE 0xBFEE #HANGUL SYLLABLE SSANGPIEUP WEO NIEUNHIEUH
+0x97AF 0xBFEF #HANGUL SYLLABLE SSANGPIEUP WEO TIKEUT
+0x97B0 0xBFF0 #HANGUL SYLLABLE SSANGPIEUP WEO RIEUL
+0x97B1 0xBFF1 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULKIYEOK
+0x97B2 0xBFF2 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULMIEUM
+0x97B3 0xBFF3 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULPIEUP
+0x97B4 0xBFF4 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULSIOS
+0x97B5 0xBFF5 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULTHIEUTH
+0x97B6 0xBFF6 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULPHIEUPH
+0x97B7 0xBFF7 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULHIEUH
+0x97B8 0xBFF8 #HANGUL SYLLABLE SSANGPIEUP WEO MIEUM
+0x97B9 0xBFF9 #HANGUL SYLLABLE SSANGPIEUP WEO PIEUP
+0x97BA 0xBFFA #HANGUL SYLLABLE SSANGPIEUP WEO PIEUPSIOS
+0x97BB 0xBFFB #HANGUL SYLLABLE SSANGPIEUP WEO SIOS
+0x97BC 0xBFFC #HANGUL SYLLABLE SSANGPIEUP WEO SSANGSIOS
+0x97BD 0xBFFD #HANGUL SYLLABLE SSANGPIEUP WEO IEUNG
+0x97BE 0xBFFE #HANGUL SYLLABLE SSANGPIEUP WEO CIEUC
+0x97BF 0xBFFF #HANGUL SYLLABLE SSANGPIEUP WEO CHIEUCH
+0x97C0 0xC000 #HANGUL SYLLABLE SSANGPIEUP WEO KHIEUKH
+0x97C1 0xC001 #HANGUL SYLLABLE SSANGPIEUP WEO THIEUTH
+0x97C2 0xC002 #HANGUL SYLLABLE SSANGPIEUP WEO PHIEUPH
+0x97C3 0xC003 #HANGUL SYLLABLE SSANGPIEUP WEO HIEUH
+0x97C4 0xC004 #HANGUL SYLLABLE SSANGPIEUP WE
+0x97C5 0xC005 #HANGUL SYLLABLE SSANGPIEUP WE KIYEOK
+0x97C6 0xC006 #HANGUL SYLLABLE SSANGPIEUP WE SSANGKIYEOK
+0x97C7 0xC007 #HANGUL SYLLABLE SSANGPIEUP WE KIYEOKSIOS
+0x97C8 0xC008 #HANGUL SYLLABLE SSANGPIEUP WE NIEUN
+0x97C9 0xC009 #HANGUL SYLLABLE SSANGPIEUP WE NIEUNCIEUC
+0x97CA 0xC00A #HANGUL SYLLABLE SSANGPIEUP WE NIEUNHIEUH
+0x97CB 0xC00B #HANGUL SYLLABLE SSANGPIEUP WE TIKEUT
+0x97CC 0xC00C #HANGUL SYLLABLE SSANGPIEUP WE RIEUL
+0x97CD 0xC00D #HANGUL SYLLABLE SSANGPIEUP WE RIEULKIYEOK
+0x97CE 0xC00E #HANGUL SYLLABLE SSANGPIEUP WE RIEULMIEUM
+0x97CF 0xC00F #HANGUL SYLLABLE SSANGPIEUP WE RIEULPIEUP
+0x97D0 0xC010 #HANGUL SYLLABLE SSANGPIEUP WE RIEULSIOS
+0x97D1 0xC011 #HANGUL SYLLABLE SSANGPIEUP WE RIEULTHIEUTH
+0x97D2 0xC012 #HANGUL SYLLABLE SSANGPIEUP WE RIEULPHIEUPH
+0x97D3 0xC013 #HANGUL SYLLABLE SSANGPIEUP WE RIEULHIEUH
+0x97D4 0xC014 #HANGUL SYLLABLE SSANGPIEUP WE MIEUM
+0x97D5 0xC015 #HANGUL SYLLABLE SSANGPIEUP WE PIEUP
+0x97D6 0xC016 #HANGUL SYLLABLE SSANGPIEUP WE PIEUPSIOS
+0x97D7 0xC017 #HANGUL SYLLABLE SSANGPIEUP WE SIOS
+0x97D8 0xC018 #HANGUL SYLLABLE SSANGPIEUP WE SSANGSIOS
+0x97D9 0xC019 #HANGUL SYLLABLE SSANGPIEUP WE IEUNG
+0x97DA 0xC01A #HANGUL SYLLABLE SSANGPIEUP WE CIEUC
+0x97DB 0xC01B #HANGUL SYLLABLE SSANGPIEUP WE CHIEUCH
+0x97DC 0xC01C #HANGUL SYLLABLE SSANGPIEUP WE KHIEUKH
+0x97DD 0xC01D #HANGUL SYLLABLE SSANGPIEUP WE THIEUTH
+0x97DE 0xC01E #HANGUL SYLLABLE SSANGPIEUP WE PHIEUPH
+0x97DF 0xC01F #HANGUL SYLLABLE SSANGPIEUP WE HIEUH
+0x97E0 0xC020 #HANGUL SYLLABLE SSANGPIEUP WI
+0x97E1 0xC021 #HANGUL SYLLABLE SSANGPIEUP WI KIYEOK
+0x97E2 0xC022 #HANGUL SYLLABLE SSANGPIEUP WI SSANGKIYEOK
+0x97E3 0xC023 #HANGUL SYLLABLE SSANGPIEUP WI KIYEOKSIOS
+0x97E4 0xC024 #HANGUL SYLLABLE SSANGPIEUP WI NIEUN
+0x97E5 0xC025 #HANGUL SYLLABLE SSANGPIEUP WI NIEUNCIEUC
+0x97E6 0xC026 #HANGUL SYLLABLE SSANGPIEUP WI NIEUNHIEUH
+0x97E7 0xC027 #HANGUL SYLLABLE SSANGPIEUP WI TIKEUT
+0x97E8 0xC028 #HANGUL SYLLABLE SSANGPIEUP WI RIEUL
+0x97E9 0xC029 #HANGUL SYLLABLE SSANGPIEUP WI RIEULKIYEOK
+0x97EA 0xC02A #HANGUL SYLLABLE SSANGPIEUP WI RIEULMIEUM
+0x97EB 0xC02B #HANGUL SYLLABLE SSANGPIEUP WI RIEULPIEUP
+0x97EC 0xC02C #HANGUL SYLLABLE SSANGPIEUP WI RIEULSIOS
+0x97ED 0xC02D #HANGUL SYLLABLE SSANGPIEUP WI RIEULTHIEUTH
+0x97EE 0xC02E #HANGUL SYLLABLE SSANGPIEUP WI RIEULPHIEUPH
+0x97EF 0xC02F #HANGUL SYLLABLE SSANGPIEUP WI RIEULHIEUH
+0x97F0 0xC030 #HANGUL SYLLABLE SSANGPIEUP WI MIEUM
+0x97F1 0xC031 #HANGUL SYLLABLE SSANGPIEUP WI PIEUP
+0x97F2 0xC032 #HANGUL SYLLABLE SSANGPIEUP WI PIEUPSIOS
+0x97F3 0xC033 #HANGUL SYLLABLE SSANGPIEUP WI SIOS
+0x97F4 0xC034 #HANGUL SYLLABLE SSANGPIEUP WI SSANGSIOS
+0x97F5 0xC035 #HANGUL SYLLABLE SSANGPIEUP WI IEUNG
+0x97F6 0xC036 #HANGUL SYLLABLE SSANGPIEUP WI CIEUC
+0x97F7 0xC037 #HANGUL SYLLABLE SSANGPIEUP WI CHIEUCH
+0x97F8 0xC038 #HANGUL SYLLABLE SSANGPIEUP WI KHIEUKH
+0x97F9 0xC039 #HANGUL SYLLABLE SSANGPIEUP WI THIEUTH
+0x97FA 0xC03A #HANGUL SYLLABLE SSANGPIEUP WI PHIEUPH
+0x97FB 0xC03B #HANGUL SYLLABLE SSANGPIEUP WI HIEUH
+0x97FC 0xC03D #HANGUL SYLLABLE SSANGPIEUP YU KIYEOK
+0x97FD 0xC03E #HANGUL SYLLABLE SSANGPIEUP YU SSANGKIYEOK
+0x97FE 0xC03F #HANGUL SYLLABLE SSANGPIEUP YU KIYEOKSIOS
+0x9841 0xC040 #HANGUL SYLLABLE SSANGPIEUP YU NIEUN
+0x9842 0xC041 #HANGUL SYLLABLE SSANGPIEUP YU NIEUNCIEUC
+0x9843 0xC042 #HANGUL SYLLABLE SSANGPIEUP YU NIEUNHIEUH
+0x9844 0xC043 #HANGUL SYLLABLE SSANGPIEUP YU TIKEUT
+0x9845 0xC044 #HANGUL SYLLABLE SSANGPIEUP YU RIEUL
+0x9846 0xC045 #HANGUL SYLLABLE SSANGPIEUP YU RIEULKIYEOK
+0x9847 0xC046 #HANGUL SYLLABLE SSANGPIEUP YU RIEULMIEUM
+0x9848 0xC047 #HANGUL SYLLABLE SSANGPIEUP YU RIEULPIEUP
+0x9849 0xC048 #HANGUL SYLLABLE SSANGPIEUP YU RIEULSIOS
+0x984A 0xC049 #HANGUL SYLLABLE SSANGPIEUP YU RIEULTHIEUTH
+0x984B 0xC04A #HANGUL SYLLABLE SSANGPIEUP YU RIEULPHIEUPH
+0x984C 0xC04B #HANGUL SYLLABLE SSANGPIEUP YU RIEULHIEUH
+0x984D 0xC04C #HANGUL SYLLABLE SSANGPIEUP YU MIEUM
+0x984E 0xC04D #HANGUL SYLLABLE SSANGPIEUP YU PIEUP
+0x984F 0xC04E #HANGUL SYLLABLE SSANGPIEUP YU PIEUPSIOS
+0x9850 0xC04F #HANGUL SYLLABLE SSANGPIEUP YU SIOS
+0x9851 0xC050 #HANGUL SYLLABLE SSANGPIEUP YU SSANGSIOS
+0x9852 0xC052 #HANGUL SYLLABLE SSANGPIEUP YU CIEUC
+0x9853 0xC053 #HANGUL SYLLABLE SSANGPIEUP YU CHIEUCH
+0x9854 0xC054 #HANGUL SYLLABLE SSANGPIEUP YU KHIEUKH
+0x9855 0xC055 #HANGUL SYLLABLE SSANGPIEUP YU THIEUTH
+0x9856 0xC056 #HANGUL SYLLABLE SSANGPIEUP YU PHIEUPH
+0x9857 0xC057 #HANGUL SYLLABLE SSANGPIEUP YU HIEUH
+0x9858 0xC059 #HANGUL SYLLABLE SSANGPIEUP EU KIYEOK
+0x9859 0xC05A #HANGUL SYLLABLE SSANGPIEUP EU SSANGKIYEOK
+0x985A 0xC05B #HANGUL SYLLABLE SSANGPIEUP EU KIYEOKSIOS
+0x9861 0xC05D #HANGUL SYLLABLE SSANGPIEUP EU NIEUNCIEUC
+0x9862 0xC05E #HANGUL SYLLABLE SSANGPIEUP EU NIEUNHIEUH
+0x9863 0xC05F #HANGUL SYLLABLE SSANGPIEUP EU TIKEUT
+0x9864 0xC061 #HANGUL SYLLABLE SSANGPIEUP EU RIEULKIYEOK
+0x9865 0xC062 #HANGUL SYLLABLE SSANGPIEUP EU RIEULMIEUM
+0x9866 0xC063 #HANGUL SYLLABLE SSANGPIEUP EU RIEULPIEUP
+0x9867 0xC064 #HANGUL SYLLABLE SSANGPIEUP EU RIEULSIOS
+0x9868 0xC065 #HANGUL SYLLABLE SSANGPIEUP EU RIEULTHIEUTH
+0x9869 0xC066 #HANGUL SYLLABLE SSANGPIEUP EU RIEULPHIEUPH
+0x986A 0xC067 #HANGUL SYLLABLE SSANGPIEUP EU RIEULHIEUH
+0x986B 0xC06A #HANGUL SYLLABLE SSANGPIEUP EU PIEUPSIOS
+0x986C 0xC06B #HANGUL SYLLABLE SSANGPIEUP EU SIOS
+0x986D 0xC06C #HANGUL SYLLABLE SSANGPIEUP EU SSANGSIOS
+0x986E 0xC06D #HANGUL SYLLABLE SSANGPIEUP EU IEUNG
+0x986F 0xC06E #HANGUL SYLLABLE SSANGPIEUP EU CIEUC
+0x9870 0xC06F #HANGUL SYLLABLE SSANGPIEUP EU CHIEUCH
+0x9871 0xC070 #HANGUL SYLLABLE SSANGPIEUP EU KHIEUKH
+0x9872 0xC071 #HANGUL SYLLABLE SSANGPIEUP EU THIEUTH
+0x9873 0xC072 #HANGUL SYLLABLE SSANGPIEUP EU PHIEUPH
+0x9874 0xC073 #HANGUL SYLLABLE SSANGPIEUP EU HIEUH
+0x9875 0xC074 #HANGUL SYLLABLE SSANGPIEUP YI
+0x9876 0xC075 #HANGUL SYLLABLE SSANGPIEUP YI KIYEOK
+0x9877 0xC076 #HANGUL SYLLABLE SSANGPIEUP YI SSANGKIYEOK
+0x9878 0xC077 #HANGUL SYLLABLE SSANGPIEUP YI KIYEOKSIOS
+0x9879 0xC078 #HANGUL SYLLABLE SSANGPIEUP YI NIEUN
+0x987A 0xC079 #HANGUL SYLLABLE SSANGPIEUP YI NIEUNCIEUC
+0x9881 0xC07A #HANGUL SYLLABLE SSANGPIEUP YI NIEUNHIEUH
+0x9882 0xC07B #HANGUL SYLLABLE SSANGPIEUP YI TIKEUT
+0x9883 0xC07C #HANGUL SYLLABLE SSANGPIEUP YI RIEUL
+0x9884 0xC07D #HANGUL SYLLABLE SSANGPIEUP YI RIEULKIYEOK
+0x9885 0xC07E #HANGUL SYLLABLE SSANGPIEUP YI RIEULMIEUM
+0x9886 0xC07F #HANGUL SYLLABLE SSANGPIEUP YI RIEULPIEUP
+0x9887 0xC080 #HANGUL SYLLABLE SSANGPIEUP YI RIEULSIOS
+0x9888 0xC081 #HANGUL SYLLABLE SSANGPIEUP YI RIEULTHIEUTH
+0x9889 0xC082 #HANGUL SYLLABLE SSANGPIEUP YI RIEULPHIEUPH
+0x988A 0xC083 #HANGUL SYLLABLE SSANGPIEUP YI RIEULHIEUH
+0x988B 0xC084 #HANGUL SYLLABLE SSANGPIEUP YI MIEUM
+0x988C 0xC085 #HANGUL SYLLABLE SSANGPIEUP YI PIEUP
+0x988D 0xC086 #HANGUL SYLLABLE SSANGPIEUP YI PIEUPSIOS
+0x988E 0xC087 #HANGUL SYLLABLE SSANGPIEUP YI SIOS
+0x988F 0xC088 #HANGUL SYLLABLE SSANGPIEUP YI SSANGSIOS
+0x9890 0xC089 #HANGUL SYLLABLE SSANGPIEUP YI IEUNG
+0x9891 0xC08A #HANGUL SYLLABLE SSANGPIEUP YI CIEUC
+0x9892 0xC08B #HANGUL SYLLABLE SSANGPIEUP YI CHIEUCH
+0x9893 0xC08C #HANGUL SYLLABLE SSANGPIEUP YI KHIEUKH
+0x9894 0xC08D #HANGUL SYLLABLE SSANGPIEUP YI THIEUTH
+0x9895 0xC08E #HANGUL SYLLABLE SSANGPIEUP YI PHIEUPH
+0x9896 0xC08F #HANGUL SYLLABLE SSANGPIEUP YI HIEUH
+0x9897 0xC092 #HANGUL SYLLABLE SSANGPIEUP I SSANGKIYEOK
+0x9898 0xC093 #HANGUL SYLLABLE SSANGPIEUP I KIYEOKSIOS
+0x9899 0xC095 #HANGUL SYLLABLE SSANGPIEUP I NIEUNCIEUC
+0x989A 0xC096 #HANGUL SYLLABLE SSANGPIEUP I NIEUNHIEUH
+0x989B 0xC097 #HANGUL SYLLABLE SSANGPIEUP I TIKEUT
+0x989C 0xC099 #HANGUL SYLLABLE SSANGPIEUP I RIEULKIYEOK
+0x989D 0xC09A #HANGUL SYLLABLE SSANGPIEUP I RIEULMIEUM
+0x989E 0xC09B #HANGUL SYLLABLE SSANGPIEUP I RIEULPIEUP
+0x989F 0xC09C #HANGUL SYLLABLE SSANGPIEUP I RIEULSIOS
+0x98A0 0xC09D #HANGUL SYLLABLE SSANGPIEUP I RIEULTHIEUTH
+0x98A1 0xC09E #HANGUL SYLLABLE SSANGPIEUP I RIEULPHIEUPH
+0x98A2 0xC09F #HANGUL SYLLABLE SSANGPIEUP I RIEULHIEUH
+0x98A3 0xC0A2 #HANGUL SYLLABLE SSANGPIEUP I PIEUPSIOS
+0x98A4 0xC0A4 #HANGUL SYLLABLE SSANGPIEUP I SSANGSIOS
+0x98A5 0xC0A6 #HANGUL SYLLABLE SSANGPIEUP I CIEUC
+0x98A6 0xC0A7 #HANGUL SYLLABLE SSANGPIEUP I CHIEUCH
+0x98A7 0xC0A8 #HANGUL SYLLABLE SSANGPIEUP I KHIEUKH
+0x98A8 0xC0A9 #HANGUL SYLLABLE SSANGPIEUP I THIEUTH
+0x98A9 0xC0AA #HANGUL SYLLABLE SSANGPIEUP I PHIEUPH
+0x98AA 0xC0AB #HANGUL SYLLABLE SSANGPIEUP I HIEUH
+0x98AB 0xC0AE #HANGUL SYLLABLE SIOS A SSANGKIYEOK
+0x98AC 0xC0B1 #HANGUL SYLLABLE SIOS A NIEUNCIEUC
+0x98AD 0xC0B2 #HANGUL SYLLABLE SIOS A NIEUNHIEUH
+0x98AE 0xC0B7 #HANGUL SYLLABLE SIOS A RIEULPIEUP
+0x98AF 0xC0B8 #HANGUL SYLLABLE SIOS A RIEULSIOS
+0x98B0 0xC0B9 #HANGUL SYLLABLE SIOS A RIEULTHIEUTH
+0x98B1 0xC0BA #HANGUL SYLLABLE SIOS A RIEULPHIEUPH
+0x98B2 0xC0BB #HANGUL SYLLABLE SIOS A RIEULHIEUH
+0x98B3 0xC0BE #HANGUL SYLLABLE SIOS A PIEUPSIOS
+0x98B4 0xC0C2 #HANGUL SYLLABLE SIOS A CIEUC
+0x98B5 0xC0C3 #HANGUL SYLLABLE SIOS A CHIEUCH
+0x98B6 0xC0C4 #HANGUL SYLLABLE SIOS A KHIEUKH
+0x98B7 0xC0C6 #HANGUL SYLLABLE SIOS A PHIEUPH
+0x98B8 0xC0C7 #HANGUL SYLLABLE SIOS A HIEUH
+0x98B9 0xC0CA #HANGUL SYLLABLE SIOS AE SSANGKIYEOK
+0x98BA 0xC0CB #HANGUL SYLLABLE SIOS AE KIYEOKSIOS
+0x98BB 0xC0CD #HANGUL SYLLABLE SIOS AE NIEUNCIEUC
+0x98BC 0xC0CE #HANGUL SYLLABLE SIOS AE NIEUNHIEUH
+0x98BD 0xC0CF #HANGUL SYLLABLE SIOS AE TIKEUT
+0x98BE 0xC0D1 #HANGUL SYLLABLE SIOS AE RIEULKIYEOK
+0x98BF 0xC0D2 #HANGUL SYLLABLE SIOS AE RIEULMIEUM
+0x98C0 0xC0D3 #HANGUL SYLLABLE SIOS AE RIEULPIEUP
+0x98C1 0xC0D4 #HANGUL SYLLABLE SIOS AE RIEULSIOS
+0x98C2 0xC0D5 #HANGUL SYLLABLE SIOS AE RIEULTHIEUTH
+0x98C3 0xC0D6 #HANGUL SYLLABLE SIOS AE RIEULPHIEUPH
+0x98C4 0xC0D7 #HANGUL SYLLABLE SIOS AE RIEULHIEUH
+0x98C5 0xC0DA #HANGUL SYLLABLE SIOS AE PIEUPSIOS
+0x98C6 0xC0DE #HANGUL SYLLABLE SIOS AE CIEUC
+0x98C7 0xC0DF #HANGUL SYLLABLE SIOS AE CHIEUCH
+0x98C8 0xC0E0 #HANGUL SYLLABLE SIOS AE KHIEUKH
+0x98C9 0xC0E1 #HANGUL SYLLABLE SIOS AE THIEUTH
+0x98CA 0xC0E2 #HANGUL SYLLABLE SIOS AE PHIEUPH
+0x98CB 0xC0E3 #HANGUL SYLLABLE SIOS AE HIEUH
+0x98CC 0xC0E6 #HANGUL SYLLABLE SIOS YA SSANGKIYEOK
+0x98CD 0xC0E7 #HANGUL SYLLABLE SIOS YA KIYEOKSIOS
+0x98CE 0xC0E9 #HANGUL SYLLABLE SIOS YA NIEUNCIEUC
+0x98CF 0xC0EA #HANGUL SYLLABLE SIOS YA NIEUNHIEUH
+0x98D0 0xC0EB #HANGUL SYLLABLE SIOS YA TIKEUT
+0x98D1 0xC0ED #HANGUL SYLLABLE SIOS YA RIEULKIYEOK
+0x98D2 0xC0EE #HANGUL SYLLABLE SIOS YA RIEULMIEUM
+0x98D3 0xC0EF #HANGUL SYLLABLE SIOS YA RIEULPIEUP
+0x98D4 0xC0F0 #HANGUL SYLLABLE SIOS YA RIEULSIOS
+0x98D5 0xC0F1 #HANGUL SYLLABLE SIOS YA RIEULTHIEUTH
+0x98D6 0xC0F2 #HANGUL SYLLABLE SIOS YA RIEULPHIEUPH
+0x98D7 0xC0F3 #HANGUL SYLLABLE SIOS YA RIEULHIEUH
+0x98D8 0xC0F6 #HANGUL SYLLABLE SIOS YA PIEUPSIOS
+0x98D9 0xC0F8 #HANGUL SYLLABLE SIOS YA SSANGSIOS
+0x98DA 0xC0FA #HANGUL SYLLABLE SIOS YA CIEUC
+0x98DB 0xC0FB #HANGUL SYLLABLE SIOS YA CHIEUCH
+0x98DC 0xC0FC #HANGUL SYLLABLE SIOS YA KHIEUKH
+0x98DD 0xC0FD #HANGUL SYLLABLE SIOS YA THIEUTH
+0x98DE 0xC0FE #HANGUL SYLLABLE SIOS YA PHIEUPH
+0x98DF 0xC0FF #HANGUL SYLLABLE SIOS YA HIEUH
+0x98E0 0xC101 #HANGUL SYLLABLE SIOS YAE KIYEOK
+0x98E1 0xC102 #HANGUL SYLLABLE SIOS YAE SSANGKIYEOK
+0x98E2 0xC103 #HANGUL SYLLABLE SIOS YAE KIYEOKSIOS
+0x98E3 0xC105 #HANGUL SYLLABLE SIOS YAE NIEUNCIEUC
+0x98E4 0xC106 #HANGUL SYLLABLE SIOS YAE NIEUNHIEUH
+0x98E5 0xC107 #HANGUL SYLLABLE SIOS YAE TIKEUT
+0x98E6 0xC109 #HANGUL SYLLABLE SIOS YAE RIEULKIYEOK
+0x98E7 0xC10A #HANGUL SYLLABLE SIOS YAE RIEULMIEUM
+0x98E8 0xC10B #HANGUL SYLLABLE SIOS YAE RIEULPIEUP
+0x98E9 0xC10C #HANGUL SYLLABLE SIOS YAE RIEULSIOS
+0x98EA 0xC10D #HANGUL SYLLABLE SIOS YAE RIEULTHIEUTH
+0x98EB 0xC10E #HANGUL SYLLABLE SIOS YAE RIEULPHIEUPH
+0x98EC 0xC10F #HANGUL SYLLABLE SIOS YAE RIEULHIEUH
+0x98ED 0xC111 #HANGUL SYLLABLE SIOS YAE PIEUP
+0x98EE 0xC112 #HANGUL SYLLABLE SIOS YAE PIEUPSIOS
+0x98EF 0xC113 #HANGUL SYLLABLE SIOS YAE SIOS
+0x98F0 0xC114 #HANGUL SYLLABLE SIOS YAE SSANGSIOS
+0x98F1 0xC116 #HANGUL SYLLABLE SIOS YAE CIEUC
+0x98F2 0xC117 #HANGUL SYLLABLE SIOS YAE CHIEUCH
+0x98F3 0xC118 #HANGUL SYLLABLE SIOS YAE KHIEUKH
+0x98F4 0xC119 #HANGUL SYLLABLE SIOS YAE THIEUTH
+0x98F5 0xC11A #HANGUL SYLLABLE SIOS YAE PHIEUPH
+0x98F6 0xC11B #HANGUL SYLLABLE SIOS YAE HIEUH
+0x98F7 0xC121 #HANGUL SYLLABLE SIOS EO NIEUNCIEUC
+0x98F8 0xC122 #HANGUL SYLLABLE SIOS EO NIEUNHIEUH
+0x98F9 0xC125 #HANGUL SYLLABLE SIOS EO RIEULKIYEOK
+0x98FA 0xC128 #HANGUL SYLLABLE SIOS EO RIEULSIOS
+0x98FB 0xC129 #HANGUL SYLLABLE SIOS EO RIEULTHIEUTH
+0x98FC 0xC12A #HANGUL SYLLABLE SIOS EO RIEULPHIEUPH
+0x98FD 0xC12B #HANGUL SYLLABLE SIOS EO RIEULHIEUH
+0x98FE 0xC12E #HANGUL SYLLABLE SIOS EO PIEUPSIOS
+0x9941 0xC132 #HANGUL SYLLABLE SIOS EO CIEUC
+0x9942 0xC133 #HANGUL SYLLABLE SIOS EO CHIEUCH
+0x9943 0xC134 #HANGUL SYLLABLE SIOS EO KHIEUKH
+0x9944 0xC135 #HANGUL SYLLABLE SIOS EO THIEUTH
+0x9945 0xC137 #HANGUL SYLLABLE SIOS EO HIEUH
+0x9946 0xC13A #HANGUL SYLLABLE SIOS E SSANGKIYEOK
+0x9947 0xC13B #HANGUL SYLLABLE SIOS E KIYEOKSIOS
+0x9948 0xC13D #HANGUL SYLLABLE SIOS E NIEUNCIEUC
+0x9949 0xC13E #HANGUL SYLLABLE SIOS E NIEUNHIEUH
+0x994A 0xC13F #HANGUL SYLLABLE SIOS E TIKEUT
+0x994B 0xC141 #HANGUL SYLLABLE SIOS E RIEULKIYEOK
+0x994C 0xC142 #HANGUL SYLLABLE SIOS E RIEULMIEUM
+0x994D 0xC143 #HANGUL SYLLABLE SIOS E RIEULPIEUP
+0x994E 0xC144 #HANGUL SYLLABLE SIOS E RIEULSIOS
+0x994F 0xC145 #HANGUL SYLLABLE SIOS E RIEULTHIEUTH
+0x9950 0xC146 #HANGUL SYLLABLE SIOS E RIEULPHIEUPH
+0x9951 0xC147 #HANGUL SYLLABLE SIOS E RIEULHIEUH
+0x9952 0xC14A #HANGUL SYLLABLE SIOS E PIEUPSIOS
+0x9953 0xC14E #HANGUL SYLLABLE SIOS E CIEUC
+0x9954 0xC14F #HANGUL SYLLABLE SIOS E CHIEUCH
+0x9955 0xC150 #HANGUL SYLLABLE SIOS E KHIEUKH
+0x9956 0xC151 #HANGUL SYLLABLE SIOS E THIEUTH
+0x9957 0xC152 #HANGUL SYLLABLE SIOS E PHIEUPH
+0x9958 0xC153 #HANGUL SYLLABLE SIOS E HIEUH
+0x9959 0xC156 #HANGUL SYLLABLE SIOS YEO SSANGKIYEOK
+0x995A 0xC157 #HANGUL SYLLABLE SIOS YEO KIYEOKSIOS
+0x9961 0xC159 #HANGUL SYLLABLE SIOS YEO NIEUNCIEUC
+0x9962 0xC15A #HANGUL SYLLABLE SIOS YEO NIEUNHIEUH
+0x9963 0xC15B #HANGUL SYLLABLE SIOS YEO TIKEUT
+0x9964 0xC15D #HANGUL SYLLABLE SIOS YEO RIEULKIYEOK
+0x9965 0xC15E #HANGUL SYLLABLE SIOS YEO RIEULMIEUM
+0x9966 0xC15F #HANGUL SYLLABLE SIOS YEO RIEULPIEUP
+0x9967 0xC160 #HANGUL SYLLABLE SIOS YEO RIEULSIOS
+0x9968 0xC161 #HANGUL SYLLABLE SIOS YEO RIEULTHIEUTH
+0x9969 0xC162 #HANGUL SYLLABLE SIOS YEO RIEULPHIEUPH
+0x996A 0xC163 #HANGUL SYLLABLE SIOS YEO RIEULHIEUH
+0x996B 0xC166 #HANGUL SYLLABLE SIOS YEO PIEUPSIOS
+0x996C 0xC16A #HANGUL SYLLABLE SIOS YEO CIEUC
+0x996D 0xC16B #HANGUL SYLLABLE SIOS YEO CHIEUCH
+0x996E 0xC16C #HANGUL SYLLABLE SIOS YEO KHIEUKH
+0x996F 0xC16D #HANGUL SYLLABLE SIOS YEO THIEUTH
+0x9970 0xC16E #HANGUL SYLLABLE SIOS YEO PHIEUPH
+0x9971 0xC16F #HANGUL SYLLABLE SIOS YEO HIEUH
+0x9972 0xC171 #HANGUL SYLLABLE SIOS YE KIYEOK
+0x9973 0xC172 #HANGUL SYLLABLE SIOS YE SSANGKIYEOK
+0x9974 0xC173 #HANGUL SYLLABLE SIOS YE KIYEOKSIOS
+0x9975 0xC175 #HANGUL SYLLABLE SIOS YE NIEUNCIEUC
+0x9976 0xC176 #HANGUL SYLLABLE SIOS YE NIEUNHIEUH
+0x9977 0xC177 #HANGUL SYLLABLE SIOS YE TIKEUT
+0x9978 0xC179 #HANGUL SYLLABLE SIOS YE RIEULKIYEOK
+0x9979 0xC17A #HANGUL SYLLABLE SIOS YE RIEULMIEUM
+0x997A 0xC17B #HANGUL SYLLABLE SIOS YE RIEULPIEUP
+0x9981 0xC17C #HANGUL SYLLABLE SIOS YE RIEULSIOS
+0x9982 0xC17D #HANGUL SYLLABLE SIOS YE RIEULTHIEUTH
+0x9983 0xC17E #HANGUL SYLLABLE SIOS YE RIEULPHIEUPH
+0x9984 0xC17F #HANGUL SYLLABLE SIOS YE RIEULHIEUH
+0x9985 0xC180 #HANGUL SYLLABLE SIOS YE MIEUM
+0x9986 0xC181 #HANGUL SYLLABLE SIOS YE PIEUP
+0x9987 0xC182 #HANGUL SYLLABLE SIOS YE PIEUPSIOS
+0x9988 0xC183 #HANGUL SYLLABLE SIOS YE SIOS
+0x9989 0xC184 #HANGUL SYLLABLE SIOS YE SSANGSIOS
+0x998A 0xC186 #HANGUL SYLLABLE SIOS YE CIEUC
+0x998B 0xC187 #HANGUL SYLLABLE SIOS YE CHIEUCH
+0x998C 0xC188 #HANGUL SYLLABLE SIOS YE KHIEUKH
+0x998D 0xC189 #HANGUL SYLLABLE SIOS YE THIEUTH
+0x998E 0xC18A #HANGUL SYLLABLE SIOS YE PHIEUPH
+0x998F 0xC18B #HANGUL SYLLABLE SIOS YE HIEUH
+0x9990 0xC18F #HANGUL SYLLABLE SIOS O KIYEOKSIOS
+0x9991 0xC191 #HANGUL SYLLABLE SIOS O NIEUNCIEUC
+0x9992 0xC192 #HANGUL SYLLABLE SIOS O NIEUNHIEUH
+0x9993 0xC193 #HANGUL SYLLABLE SIOS O TIKEUT
+0x9994 0xC195 #HANGUL SYLLABLE SIOS O RIEULKIYEOK
+0x9995 0xC197 #HANGUL SYLLABLE SIOS O RIEULPIEUP
+0x9996 0xC198 #HANGUL SYLLABLE SIOS O RIEULSIOS
+0x9997 0xC199 #HANGUL SYLLABLE SIOS O RIEULTHIEUTH
+0x9998 0xC19A #HANGUL SYLLABLE SIOS O RIEULPHIEUPH
+0x9999 0xC19B #HANGUL SYLLABLE SIOS O RIEULHIEUH
+0x999A 0xC19E #HANGUL SYLLABLE SIOS O PIEUPSIOS
+0x999B 0xC1A0 #HANGUL SYLLABLE SIOS O SSANGSIOS
+0x999C 0xC1A2 #HANGUL SYLLABLE SIOS O CIEUC
+0x999D 0xC1A3 #HANGUL SYLLABLE SIOS O CHIEUCH
+0x999E 0xC1A4 #HANGUL SYLLABLE SIOS O KHIEUKH
+0x999F 0xC1A6 #HANGUL SYLLABLE SIOS O PHIEUPH
+0x99A0 0xC1A7 #HANGUL SYLLABLE SIOS O HIEUH
+0x99A1 0xC1AA #HANGUL SYLLABLE SIOS WA SSANGKIYEOK
+0x99A2 0xC1AB #HANGUL SYLLABLE SIOS WA KIYEOKSIOS
+0x99A3 0xC1AD #HANGUL SYLLABLE SIOS WA NIEUNCIEUC
+0x99A4 0xC1AE #HANGUL SYLLABLE SIOS WA NIEUNHIEUH
+0x99A5 0xC1AF #HANGUL SYLLABLE SIOS WA TIKEUT
+0x99A6 0xC1B1 #HANGUL SYLLABLE SIOS WA RIEULKIYEOK
+0x99A7 0xC1B2 #HANGUL SYLLABLE SIOS WA RIEULMIEUM
+0x99A8 0xC1B3 #HANGUL SYLLABLE SIOS WA RIEULPIEUP
+0x99A9 0xC1B4 #HANGUL SYLLABLE SIOS WA RIEULSIOS
+0x99AA 0xC1B5 #HANGUL SYLLABLE SIOS WA RIEULTHIEUTH
+0x99AB 0xC1B6 #HANGUL SYLLABLE SIOS WA RIEULPHIEUPH
+0x99AC 0xC1B7 #HANGUL SYLLABLE SIOS WA RIEULHIEUH
+0x99AD 0xC1B8 #HANGUL SYLLABLE SIOS WA MIEUM
+0x99AE 0xC1B9 #HANGUL SYLLABLE SIOS WA PIEUP
+0x99AF 0xC1BA #HANGUL SYLLABLE SIOS WA PIEUPSIOS
+0x99B0 0xC1BB #HANGUL SYLLABLE SIOS WA SIOS
+0x99B1 0xC1BC #HANGUL SYLLABLE SIOS WA SSANGSIOS
+0x99B2 0xC1BE #HANGUL SYLLABLE SIOS WA CIEUC
+0x99B3 0xC1BF #HANGUL SYLLABLE SIOS WA CHIEUCH
+0x99B4 0xC1C0 #HANGUL SYLLABLE SIOS WA KHIEUKH
+0x99B5 0xC1C1 #HANGUL SYLLABLE SIOS WA THIEUTH
+0x99B6 0xC1C2 #HANGUL SYLLABLE SIOS WA PHIEUPH
+0x99B7 0xC1C3 #HANGUL SYLLABLE SIOS WA HIEUH
+0x99B8 0xC1C5 #HANGUL SYLLABLE SIOS WAE KIYEOK
+0x99B9 0xC1C6 #HANGUL SYLLABLE SIOS WAE SSANGKIYEOK
+0x99BA 0xC1C7 #HANGUL SYLLABLE SIOS WAE KIYEOKSIOS
+0x99BB 0xC1C9 #HANGUL SYLLABLE SIOS WAE NIEUNCIEUC
+0x99BC 0xC1CA #HANGUL SYLLABLE SIOS WAE NIEUNHIEUH
+0x99BD 0xC1CB #HANGUL SYLLABLE SIOS WAE TIKEUT
+0x99BE 0xC1CD #HANGUL SYLLABLE SIOS WAE RIEULKIYEOK
+0x99BF 0xC1CE #HANGUL SYLLABLE SIOS WAE RIEULMIEUM
+0x99C0 0xC1CF #HANGUL SYLLABLE SIOS WAE RIEULPIEUP
+0x99C1 0xC1D0 #HANGUL SYLLABLE SIOS WAE RIEULSIOS
+0x99C2 0xC1D1 #HANGUL SYLLABLE SIOS WAE RIEULTHIEUTH
+0x99C3 0xC1D2 #HANGUL SYLLABLE SIOS WAE RIEULPHIEUPH
+0x99C4 0xC1D3 #HANGUL SYLLABLE SIOS WAE RIEULHIEUH
+0x99C5 0xC1D5 #HANGUL SYLLABLE SIOS WAE PIEUP
+0x99C6 0xC1D6 #HANGUL SYLLABLE SIOS WAE PIEUPSIOS
+0x99C7 0xC1D9 #HANGUL SYLLABLE SIOS WAE IEUNG
+0x99C8 0xC1DA #HANGUL SYLLABLE SIOS WAE CIEUC
+0x99C9 0xC1DB #HANGUL SYLLABLE SIOS WAE CHIEUCH
+0x99CA 0xC1DC #HANGUL SYLLABLE SIOS WAE KHIEUKH
+0x99CB 0xC1DD #HANGUL SYLLABLE SIOS WAE THIEUTH
+0x99CC 0xC1DE #HANGUL SYLLABLE SIOS WAE PHIEUPH
+0x99CD 0xC1DF #HANGUL SYLLABLE SIOS WAE HIEUH
+0x99CE 0xC1E1 #HANGUL SYLLABLE SIOS OE KIYEOK
+0x99CF 0xC1E2 #HANGUL SYLLABLE SIOS OE SSANGKIYEOK
+0x99D0 0xC1E3 #HANGUL SYLLABLE SIOS OE KIYEOKSIOS
+0x99D1 0xC1E5 #HANGUL SYLLABLE SIOS OE NIEUNCIEUC
+0x99D2 0xC1E6 #HANGUL SYLLABLE SIOS OE NIEUNHIEUH
+0x99D3 0xC1E7 #HANGUL SYLLABLE SIOS OE TIKEUT
+0x99D4 0xC1E9 #HANGUL SYLLABLE SIOS OE RIEULKIYEOK
+0x99D5 0xC1EA #HANGUL SYLLABLE SIOS OE RIEULMIEUM
+0x99D6 0xC1EB #HANGUL SYLLABLE SIOS OE RIEULPIEUP
+0x99D7 0xC1EC #HANGUL SYLLABLE SIOS OE RIEULSIOS
+0x99D8 0xC1ED #HANGUL SYLLABLE SIOS OE RIEULTHIEUTH
+0x99D9 0xC1EE #HANGUL SYLLABLE SIOS OE RIEULPHIEUPH
+0x99DA 0xC1EF #HANGUL SYLLABLE SIOS OE RIEULHIEUH
+0x99DB 0xC1F2 #HANGUL SYLLABLE SIOS OE PIEUPSIOS
+0x99DC 0xC1F4 #HANGUL SYLLABLE SIOS OE SSANGSIOS
+0x99DD 0xC1F5 #HANGUL SYLLABLE SIOS OE IEUNG
+0x99DE 0xC1F6 #HANGUL SYLLABLE SIOS OE CIEUC
+0x99DF 0xC1F7 #HANGUL SYLLABLE SIOS OE CHIEUCH
+0x99E0 0xC1F8 #HANGUL SYLLABLE SIOS OE KHIEUKH
+0x99E1 0xC1F9 #HANGUL SYLLABLE SIOS OE THIEUTH
+0x99E2 0xC1FA #HANGUL SYLLABLE SIOS OE PHIEUPH
+0x99E3 0xC1FB #HANGUL SYLLABLE SIOS OE HIEUH
+0x99E4 0xC1FE #HANGUL SYLLABLE SIOS YO SSANGKIYEOK
+0x99E5 0xC1FF #HANGUL SYLLABLE SIOS YO KIYEOKSIOS
+0x99E6 0xC201 #HANGUL SYLLABLE SIOS YO NIEUNCIEUC
+0x99E7 0xC202 #HANGUL SYLLABLE SIOS YO NIEUNHIEUH
+0x99E8 0xC203 #HANGUL SYLLABLE SIOS YO TIKEUT
+0x99E9 0xC205 #HANGUL SYLLABLE SIOS YO RIEULKIYEOK
+0x99EA 0xC206 #HANGUL SYLLABLE SIOS YO RIEULMIEUM
+0x99EB 0xC207 #HANGUL SYLLABLE SIOS YO RIEULPIEUP
+0x99EC 0xC208 #HANGUL SYLLABLE SIOS YO RIEULSIOS
+0x99ED 0xC209 #HANGUL SYLLABLE SIOS YO RIEULTHIEUTH
+0x99EE 0xC20A #HANGUL SYLLABLE SIOS YO RIEULPHIEUPH
+0x99EF 0xC20B #HANGUL SYLLABLE SIOS YO RIEULHIEUH
+0x99F0 0xC20E #HANGUL SYLLABLE SIOS YO PIEUPSIOS
+0x99F1 0xC210 #HANGUL SYLLABLE SIOS YO SSANGSIOS
+0x99F2 0xC212 #HANGUL SYLLABLE SIOS YO CIEUC
+0x99F3 0xC213 #HANGUL SYLLABLE SIOS YO CHIEUCH
+0x99F4 0xC214 #HANGUL SYLLABLE SIOS YO KHIEUKH
+0x99F5 0xC215 #HANGUL SYLLABLE SIOS YO THIEUTH
+0x99F6 0xC216 #HANGUL SYLLABLE SIOS YO PHIEUPH
+0x99F7 0xC217 #HANGUL SYLLABLE SIOS YO HIEUH
+0x99F8 0xC21A #HANGUL SYLLABLE SIOS U SSANGKIYEOK
+0x99F9 0xC21B #HANGUL SYLLABLE SIOS U KIYEOKSIOS
+0x99FA 0xC21D #HANGUL SYLLABLE SIOS U NIEUNCIEUC
+0x99FB 0xC21E #HANGUL SYLLABLE SIOS U NIEUNHIEUH
+0x99FC 0xC221 #HANGUL SYLLABLE SIOS U RIEULKIYEOK
+0x99FD 0xC222 #HANGUL SYLLABLE SIOS U RIEULMIEUM
+0x99FE 0xC223 #HANGUL SYLLABLE SIOS U RIEULPIEUP
+0x9A41 0xC224 #HANGUL SYLLABLE SIOS U RIEULSIOS
+0x9A42 0xC225 #HANGUL SYLLABLE SIOS U RIEULTHIEUTH
+0x9A43 0xC226 #HANGUL SYLLABLE SIOS U RIEULPHIEUPH
+0x9A44 0xC227 #HANGUL SYLLABLE SIOS U RIEULHIEUH
+0x9A45 0xC22A #HANGUL SYLLABLE SIOS U PIEUPSIOS
+0x9A46 0xC22C #HANGUL SYLLABLE SIOS U SSANGSIOS
+0x9A47 0xC22E #HANGUL SYLLABLE SIOS U CIEUC
+0x9A48 0xC230 #HANGUL SYLLABLE SIOS U KHIEUKH
+0x9A49 0xC233 #HANGUL SYLLABLE SIOS U HIEUH
+0x9A4A 0xC235 #HANGUL SYLLABLE SIOS WEO KIYEOK
+0x9A4B 0xC236 #HANGUL SYLLABLE SIOS WEO SSANGKIYEOK
+0x9A4C 0xC237 #HANGUL SYLLABLE SIOS WEO KIYEOKSIOS
+0x9A4D 0xC238 #HANGUL SYLLABLE SIOS WEO NIEUN
+0x9A4E 0xC239 #HANGUL SYLLABLE SIOS WEO NIEUNCIEUC
+0x9A4F 0xC23A #HANGUL SYLLABLE SIOS WEO NIEUNHIEUH
+0x9A50 0xC23B #HANGUL SYLLABLE SIOS WEO TIKEUT
+0x9A51 0xC23C #HANGUL SYLLABLE SIOS WEO RIEUL
+0x9A52 0xC23D #HANGUL SYLLABLE SIOS WEO RIEULKIYEOK
+0x9A53 0xC23E #HANGUL SYLLABLE SIOS WEO RIEULMIEUM
+0x9A54 0xC23F #HANGUL SYLLABLE SIOS WEO RIEULPIEUP
+0x9A55 0xC240 #HANGUL SYLLABLE SIOS WEO RIEULSIOS
+0x9A56 0xC241 #HANGUL SYLLABLE SIOS WEO RIEULTHIEUTH
+0x9A57 0xC242 #HANGUL SYLLABLE SIOS WEO RIEULPHIEUPH
+0x9A58 0xC243 #HANGUL SYLLABLE SIOS WEO RIEULHIEUH
+0x9A59 0xC244 #HANGUL SYLLABLE SIOS WEO MIEUM
+0x9A5A 0xC245 #HANGUL SYLLABLE SIOS WEO PIEUP
+0x9A61 0xC246 #HANGUL SYLLABLE SIOS WEO PIEUPSIOS
+0x9A62 0xC247 #HANGUL SYLLABLE SIOS WEO SIOS
+0x9A63 0xC249 #HANGUL SYLLABLE SIOS WEO IEUNG
+0x9A64 0xC24A #HANGUL SYLLABLE SIOS WEO CIEUC
+0x9A65 0xC24B #HANGUL SYLLABLE SIOS WEO CHIEUCH
+0x9A66 0xC24C #HANGUL SYLLABLE SIOS WEO KHIEUKH
+0x9A67 0xC24D #HANGUL SYLLABLE SIOS WEO THIEUTH
+0x9A68 0xC24E #HANGUL SYLLABLE SIOS WEO PHIEUPH
+0x9A69 0xC24F #HANGUL SYLLABLE SIOS WEO HIEUH
+0x9A6A 0xC252 #HANGUL SYLLABLE SIOS WE SSANGKIYEOK
+0x9A6B 0xC253 #HANGUL SYLLABLE SIOS WE KIYEOKSIOS
+0x9A6C 0xC255 #HANGUL SYLLABLE SIOS WE NIEUNCIEUC
+0x9A6D 0xC256 #HANGUL SYLLABLE SIOS WE NIEUNHIEUH
+0x9A6E 0xC257 #HANGUL SYLLABLE SIOS WE TIKEUT
+0x9A6F 0xC259 #HANGUL SYLLABLE SIOS WE RIEULKIYEOK
+0x9A70 0xC25A #HANGUL SYLLABLE SIOS WE RIEULMIEUM
+0x9A71 0xC25B #HANGUL SYLLABLE SIOS WE RIEULPIEUP
+0x9A72 0xC25C #HANGUL SYLLABLE SIOS WE RIEULSIOS
+0x9A73 0xC25D #HANGUL SYLLABLE SIOS WE RIEULTHIEUTH
+0x9A74 0xC25E #HANGUL SYLLABLE SIOS WE RIEULPHIEUPH
+0x9A75 0xC25F #HANGUL SYLLABLE SIOS WE RIEULHIEUH
+0x9A76 0xC261 #HANGUL SYLLABLE SIOS WE PIEUP
+0x9A77 0xC262 #HANGUL SYLLABLE SIOS WE PIEUPSIOS
+0x9A78 0xC263 #HANGUL SYLLABLE SIOS WE SIOS
+0x9A79 0xC264 #HANGUL SYLLABLE SIOS WE SSANGSIOS
+0x9A7A 0xC266 #HANGUL SYLLABLE SIOS WE CIEUC
+0x9A81 0xC267 #HANGUL SYLLABLE SIOS WE CHIEUCH
+0x9A82 0xC268 #HANGUL SYLLABLE SIOS WE KHIEUKH
+0x9A83 0xC269 #HANGUL SYLLABLE SIOS WE THIEUTH
+0x9A84 0xC26A #HANGUL SYLLABLE SIOS WE PHIEUPH
+0x9A85 0xC26B #HANGUL SYLLABLE SIOS WE HIEUH
+0x9A86 0xC26E #HANGUL SYLLABLE SIOS WI SSANGKIYEOK
+0x9A87 0xC26F #HANGUL SYLLABLE SIOS WI KIYEOKSIOS
+0x9A88 0xC271 #HANGUL SYLLABLE SIOS WI NIEUNCIEUC
+0x9A89 0xC272 #HANGUL SYLLABLE SIOS WI NIEUNHIEUH
+0x9A8A 0xC273 #HANGUL SYLLABLE SIOS WI TIKEUT
+0x9A8B 0xC275 #HANGUL SYLLABLE SIOS WI RIEULKIYEOK
+0x9A8C 0xC276 #HANGUL SYLLABLE SIOS WI RIEULMIEUM
+0x9A8D 0xC277 #HANGUL SYLLABLE SIOS WI RIEULPIEUP
+0x9A8E 0xC278 #HANGUL SYLLABLE SIOS WI RIEULSIOS
+0x9A8F 0xC279 #HANGUL SYLLABLE SIOS WI RIEULTHIEUTH
+0x9A90 0xC27A #HANGUL SYLLABLE SIOS WI RIEULPHIEUPH
+0x9A91 0xC27B #HANGUL SYLLABLE SIOS WI RIEULHIEUH
+0x9A92 0xC27E #HANGUL SYLLABLE SIOS WI PIEUPSIOS
+0x9A93 0xC280 #HANGUL SYLLABLE SIOS WI SSANGSIOS
+0x9A94 0xC282 #HANGUL SYLLABLE SIOS WI CIEUC
+0x9A95 0xC283 #HANGUL SYLLABLE SIOS WI CHIEUCH
+0x9A96 0xC284 #HANGUL SYLLABLE SIOS WI KHIEUKH
+0x9A97 0xC285 #HANGUL SYLLABLE SIOS WI THIEUTH
+0x9A98 0xC286 #HANGUL SYLLABLE SIOS WI PHIEUPH
+0x9A99 0xC287 #HANGUL SYLLABLE SIOS WI HIEUH
+0x9A9A 0xC28A #HANGUL SYLLABLE SIOS YU SSANGKIYEOK
+0x9A9B 0xC28B #HANGUL SYLLABLE SIOS YU KIYEOKSIOS
+0x9A9C 0xC28C #HANGUL SYLLABLE SIOS YU NIEUN
+0x9A9D 0xC28D #HANGUL SYLLABLE SIOS YU NIEUNCIEUC
+0x9A9E 0xC28E #HANGUL SYLLABLE SIOS YU NIEUNHIEUH
+0x9A9F 0xC28F #HANGUL SYLLABLE SIOS YU TIKEUT
+0x9AA0 0xC291 #HANGUL SYLLABLE SIOS YU RIEULKIYEOK
+0x9AA1 0xC292 #HANGUL SYLLABLE SIOS YU RIEULMIEUM
+0x9AA2 0xC293 #HANGUL SYLLABLE SIOS YU RIEULPIEUP
+0x9AA3 0xC294 #HANGUL SYLLABLE SIOS YU RIEULSIOS
+0x9AA4 0xC295 #HANGUL SYLLABLE SIOS YU RIEULTHIEUTH
+0x9AA5 0xC296 #HANGUL SYLLABLE SIOS YU RIEULPHIEUPH
+0x9AA6 0xC297 #HANGUL SYLLABLE SIOS YU RIEULHIEUH
+0x9AA7 0xC299 #HANGUL SYLLABLE SIOS YU PIEUP
+0x9AA8 0xC29A #HANGUL SYLLABLE SIOS YU PIEUPSIOS
+0x9AA9 0xC29C #HANGUL SYLLABLE SIOS YU SSANGSIOS
+0x9AAA 0xC29E #HANGUL SYLLABLE SIOS YU CIEUC
+0x9AAB 0xC29F #HANGUL SYLLABLE SIOS YU CHIEUCH
+0x9AAC 0xC2A0 #HANGUL SYLLABLE SIOS YU KHIEUKH
+0x9AAD 0xC2A1 #HANGUL SYLLABLE SIOS YU THIEUTH
+0x9AAE 0xC2A2 #HANGUL SYLLABLE SIOS YU PHIEUPH
+0x9AAF 0xC2A3 #HANGUL SYLLABLE SIOS YU HIEUH
+0x9AB0 0xC2A6 #HANGUL SYLLABLE SIOS EU SSANGKIYEOK
+0x9AB1 0xC2A7 #HANGUL SYLLABLE SIOS EU KIYEOKSIOS
+0x9AB2 0xC2A9 #HANGUL SYLLABLE SIOS EU NIEUNCIEUC
+0x9AB3 0xC2AA #HANGUL SYLLABLE SIOS EU NIEUNHIEUH
+0x9AB4 0xC2AB #HANGUL SYLLABLE SIOS EU TIKEUT
+0x9AB5 0xC2AE #HANGUL SYLLABLE SIOS EU RIEULMIEUM
+0x9AB6 0xC2AF #HANGUL SYLLABLE SIOS EU RIEULPIEUP
+0x9AB7 0xC2B0 #HANGUL SYLLABLE SIOS EU RIEULSIOS
+0x9AB8 0xC2B1 #HANGUL SYLLABLE SIOS EU RIEULTHIEUTH
+0x9AB9 0xC2B2 #HANGUL SYLLABLE SIOS EU RIEULPHIEUPH
+0x9ABA 0xC2B3 #HANGUL SYLLABLE SIOS EU RIEULHIEUH
+0x9ABB 0xC2B6 #HANGUL SYLLABLE SIOS EU PIEUPSIOS
+0x9ABC 0xC2B8 #HANGUL SYLLABLE SIOS EU SSANGSIOS
+0x9ABD 0xC2BA #HANGUL SYLLABLE SIOS EU CIEUC
+0x9ABE 0xC2BB #HANGUL SYLLABLE SIOS EU CHIEUCH
+0x9ABF 0xC2BC #HANGUL SYLLABLE SIOS EU KHIEUKH
+0x9AC0 0xC2BD #HANGUL SYLLABLE SIOS EU THIEUTH
+0x9AC1 0xC2BE #HANGUL SYLLABLE SIOS EU PHIEUPH
+0x9AC2 0xC2BF #HANGUL SYLLABLE SIOS EU HIEUH
+0x9AC3 0xC2C0 #HANGUL SYLLABLE SIOS YI
+0x9AC4 0xC2C1 #HANGUL SYLLABLE SIOS YI KIYEOK
+0x9AC5 0xC2C2 #HANGUL SYLLABLE SIOS YI SSANGKIYEOK
+0x9AC6 0xC2C3 #HANGUL SYLLABLE SIOS YI KIYEOKSIOS
+0x9AC7 0xC2C4 #HANGUL SYLLABLE SIOS YI NIEUN
+0x9AC8 0xC2C5 #HANGUL SYLLABLE SIOS YI NIEUNCIEUC
+0x9AC9 0xC2C6 #HANGUL SYLLABLE SIOS YI NIEUNHIEUH
+0x9ACA 0xC2C7 #HANGUL SYLLABLE SIOS YI TIKEUT
+0x9ACB 0xC2C8 #HANGUL SYLLABLE SIOS YI RIEUL
+0x9ACC 0xC2C9 #HANGUL SYLLABLE SIOS YI RIEULKIYEOK
+0x9ACD 0xC2CA #HANGUL SYLLABLE SIOS YI RIEULMIEUM
+0x9ACE 0xC2CB #HANGUL SYLLABLE SIOS YI RIEULPIEUP
+0x9ACF 0xC2CC #HANGUL SYLLABLE SIOS YI RIEULSIOS
+0x9AD0 0xC2CD #HANGUL SYLLABLE SIOS YI RIEULTHIEUTH
+0x9AD1 0xC2CE #HANGUL SYLLABLE SIOS YI RIEULPHIEUPH
+0x9AD2 0xC2CF #HANGUL SYLLABLE SIOS YI RIEULHIEUH
+0x9AD3 0xC2D0 #HANGUL SYLLABLE SIOS YI MIEUM
+0x9AD4 0xC2D1 #HANGUL SYLLABLE SIOS YI PIEUP
+0x9AD5 0xC2D2 #HANGUL SYLLABLE SIOS YI PIEUPSIOS
+0x9AD6 0xC2D3 #HANGUL SYLLABLE SIOS YI SIOS
+0x9AD7 0xC2D4 #HANGUL SYLLABLE SIOS YI SSANGSIOS
+0x9AD8 0xC2D5 #HANGUL SYLLABLE SIOS YI IEUNG
+0x9AD9 0xC2D6 #HANGUL SYLLABLE SIOS YI CIEUC
+0x9ADA 0xC2D7 #HANGUL SYLLABLE SIOS YI CHIEUCH
+0x9ADB 0xC2D8 #HANGUL SYLLABLE SIOS YI KHIEUKH
+0x9ADC 0xC2D9 #HANGUL SYLLABLE SIOS YI THIEUTH
+0x9ADD 0xC2DA #HANGUL SYLLABLE SIOS YI PHIEUPH
+0x9ADE 0xC2DB #HANGUL SYLLABLE SIOS YI HIEUH
+0x9ADF 0xC2DE #HANGUL SYLLABLE SIOS I SSANGKIYEOK
+0x9AE0 0xC2DF #HANGUL SYLLABLE SIOS I KIYEOKSIOS
+0x9AE1 0xC2E1 #HANGUL SYLLABLE SIOS I NIEUNCIEUC
+0x9AE2 0xC2E2 #HANGUL SYLLABLE SIOS I NIEUNHIEUH
+0x9AE3 0xC2E5 #HANGUL SYLLABLE SIOS I RIEULKIYEOK
+0x9AE4 0xC2E6 #HANGUL SYLLABLE SIOS I RIEULMIEUM
+0x9AE5 0xC2E7 #HANGUL SYLLABLE SIOS I RIEULPIEUP
+0x9AE6 0xC2E8 #HANGUL SYLLABLE SIOS I RIEULSIOS
+0x9AE7 0xC2E9 #HANGUL SYLLABLE SIOS I RIEULTHIEUTH
+0x9AE8 0xC2EA #HANGUL SYLLABLE SIOS I RIEULPHIEUPH
+0x9AE9 0xC2EE #HANGUL SYLLABLE SIOS I PIEUPSIOS
+0x9AEA 0xC2F0 #HANGUL SYLLABLE SIOS I SSANGSIOS
+0x9AEB 0xC2F2 #HANGUL SYLLABLE SIOS I CIEUC
+0x9AEC 0xC2F3 #HANGUL SYLLABLE SIOS I CHIEUCH
+0x9AED 0xC2F4 #HANGUL SYLLABLE SIOS I KHIEUKH
+0x9AEE 0xC2F5 #HANGUL SYLLABLE SIOS I THIEUTH
+0x9AEF 0xC2F7 #HANGUL SYLLABLE SIOS I HIEUH
+0x9AF0 0xC2FA #HANGUL SYLLABLE SSANGSIOS A SSANGKIYEOK
+0x9AF1 0xC2FD #HANGUL SYLLABLE SSANGSIOS A NIEUNCIEUC
+0x9AF2 0xC2FE #HANGUL SYLLABLE SSANGSIOS A NIEUNHIEUH
+0x9AF3 0xC2FF #HANGUL SYLLABLE SSANGSIOS A TIKEUT
+0x9AF4 0xC301 #HANGUL SYLLABLE SSANGSIOS A RIEULKIYEOK
+0x9AF5 0xC302 #HANGUL SYLLABLE SSANGSIOS A RIEULMIEUM
+0x9AF6 0xC303 #HANGUL SYLLABLE SSANGSIOS A RIEULPIEUP
+0x9AF7 0xC304 #HANGUL SYLLABLE SSANGSIOS A RIEULSIOS
+0x9AF8 0xC305 #HANGUL SYLLABLE SSANGSIOS A RIEULTHIEUTH
+0x9AF9 0xC306 #HANGUL SYLLABLE SSANGSIOS A RIEULPHIEUPH
+0x9AFA 0xC307 #HANGUL SYLLABLE SSANGSIOS A RIEULHIEUH
+0x9AFB 0xC30A #HANGUL SYLLABLE SSANGSIOS A PIEUPSIOS
+0x9AFC 0xC30B #HANGUL SYLLABLE SSANGSIOS A SIOS
+0x9AFD 0xC30E #HANGUL SYLLABLE SSANGSIOS A CIEUC
+0x9AFE 0xC30F #HANGUL SYLLABLE SSANGSIOS A CHIEUCH
+0x9B41 0xC310 #HANGUL SYLLABLE SSANGSIOS A KHIEUKH
+0x9B42 0xC311 #HANGUL SYLLABLE SSANGSIOS A THIEUTH
+0x9B43 0xC312 #HANGUL SYLLABLE SSANGSIOS A PHIEUPH
+0x9B44 0xC316 #HANGUL SYLLABLE SSANGSIOS AE SSANGKIYEOK
+0x9B45 0xC317 #HANGUL SYLLABLE SSANGSIOS AE KIYEOKSIOS
+0x9B46 0xC319 #HANGUL SYLLABLE SSANGSIOS AE NIEUNCIEUC
+0x9B47 0xC31A #HANGUL SYLLABLE SSANGSIOS AE NIEUNHIEUH
+0x9B48 0xC31B #HANGUL SYLLABLE SSANGSIOS AE TIKEUT
+0x9B49 0xC31D #HANGUL SYLLABLE SSANGSIOS AE RIEULKIYEOK
+0x9B4A 0xC31E #HANGUL SYLLABLE SSANGSIOS AE RIEULMIEUM
+0x9B4B 0xC31F #HANGUL SYLLABLE SSANGSIOS AE RIEULPIEUP
+0x9B4C 0xC320 #HANGUL SYLLABLE SSANGSIOS AE RIEULSIOS
+0x9B4D 0xC321 #HANGUL SYLLABLE SSANGSIOS AE RIEULTHIEUTH
+0x9B4E 0xC322 #HANGUL SYLLABLE SSANGSIOS AE RIEULPHIEUPH
+0x9B4F 0xC323 #HANGUL SYLLABLE SSANGSIOS AE RIEULHIEUH
+0x9B50 0xC326 #HANGUL SYLLABLE SSANGSIOS AE PIEUPSIOS
+0x9B51 0xC327 #HANGUL SYLLABLE SSANGSIOS AE SIOS
+0x9B52 0xC32A #HANGUL SYLLABLE SSANGSIOS AE CIEUC
+0x9B53 0xC32B #HANGUL SYLLABLE SSANGSIOS AE CHIEUCH
+0x9B54 0xC32C #HANGUL SYLLABLE SSANGSIOS AE KHIEUKH
+0x9B55 0xC32D #HANGUL SYLLABLE SSANGSIOS AE THIEUTH
+0x9B56 0xC32E #HANGUL SYLLABLE SSANGSIOS AE PHIEUPH
+0x9B57 0xC32F #HANGUL SYLLABLE SSANGSIOS AE HIEUH
+0x9B58 0xC330 #HANGUL SYLLABLE SSANGSIOS YA
+0x9B59 0xC331 #HANGUL SYLLABLE SSANGSIOS YA KIYEOK
+0x9B5A 0xC332 #HANGUL SYLLABLE SSANGSIOS YA SSANGKIYEOK
+0x9B61 0xC333 #HANGUL SYLLABLE SSANGSIOS YA KIYEOKSIOS
+0x9B62 0xC334 #HANGUL SYLLABLE SSANGSIOS YA NIEUN
+0x9B63 0xC335 #HANGUL SYLLABLE SSANGSIOS YA NIEUNCIEUC
+0x9B64 0xC336 #HANGUL SYLLABLE SSANGSIOS YA NIEUNHIEUH
+0x9B65 0xC337 #HANGUL SYLLABLE SSANGSIOS YA TIKEUT
+0x9B66 0xC338 #HANGUL SYLLABLE SSANGSIOS YA RIEUL
+0x9B67 0xC339 #HANGUL SYLLABLE SSANGSIOS YA RIEULKIYEOK
+0x9B68 0xC33A #HANGUL SYLLABLE SSANGSIOS YA RIEULMIEUM
+0x9B69 0xC33B #HANGUL SYLLABLE SSANGSIOS YA RIEULPIEUP
+0x9B6A 0xC33C #HANGUL SYLLABLE SSANGSIOS YA RIEULSIOS
+0x9B6B 0xC33D #HANGUL SYLLABLE SSANGSIOS YA RIEULTHIEUTH
+0x9B6C 0xC33E #HANGUL SYLLABLE SSANGSIOS YA RIEULPHIEUPH
+0x9B6D 0xC33F #HANGUL SYLLABLE SSANGSIOS YA RIEULHIEUH
+0x9B6E 0xC340 #HANGUL SYLLABLE SSANGSIOS YA MIEUM
+0x9B6F 0xC341 #HANGUL SYLLABLE SSANGSIOS YA PIEUP
+0x9B70 0xC342 #HANGUL SYLLABLE SSANGSIOS YA PIEUPSIOS
+0x9B71 0xC343 #HANGUL SYLLABLE SSANGSIOS YA SIOS
+0x9B72 0xC344 #HANGUL SYLLABLE SSANGSIOS YA SSANGSIOS
+0x9B73 0xC346 #HANGUL SYLLABLE SSANGSIOS YA CIEUC
+0x9B74 0xC347 #HANGUL SYLLABLE SSANGSIOS YA CHIEUCH
+0x9B75 0xC348 #HANGUL SYLLABLE SSANGSIOS YA KHIEUKH
+0x9B76 0xC349 #HANGUL SYLLABLE SSANGSIOS YA THIEUTH
+0x9B77 0xC34A #HANGUL SYLLABLE SSANGSIOS YA PHIEUPH
+0x9B78 0xC34B #HANGUL SYLLABLE SSANGSIOS YA HIEUH
+0x9B79 0xC34C #HANGUL SYLLABLE SSANGSIOS YAE
+0x9B7A 0xC34D #HANGUL SYLLABLE SSANGSIOS YAE KIYEOK
+0x9B81 0xC34E #HANGUL SYLLABLE SSANGSIOS YAE SSANGKIYEOK
+0x9B82 0xC34F #HANGUL SYLLABLE SSANGSIOS YAE KIYEOKSIOS
+0x9B83 0xC350 #HANGUL SYLLABLE SSANGSIOS YAE NIEUN
+0x9B84 0xC351 #HANGUL SYLLABLE SSANGSIOS YAE NIEUNCIEUC
+0x9B85 0xC352 #HANGUL SYLLABLE SSANGSIOS YAE NIEUNHIEUH
+0x9B86 0xC353 #HANGUL SYLLABLE SSANGSIOS YAE TIKEUT
+0x9B87 0xC354 #HANGUL SYLLABLE SSANGSIOS YAE RIEUL
+0x9B88 0xC355 #HANGUL SYLLABLE SSANGSIOS YAE RIEULKIYEOK
+0x9B89 0xC356 #HANGUL SYLLABLE SSANGSIOS YAE RIEULMIEUM
+0x9B8A 0xC357 #HANGUL SYLLABLE SSANGSIOS YAE RIEULPIEUP
+0x9B8B 0xC358 #HANGUL SYLLABLE SSANGSIOS YAE RIEULSIOS
+0x9B8C 0xC359 #HANGUL SYLLABLE SSANGSIOS YAE RIEULTHIEUTH
+0x9B8D 0xC35A #HANGUL SYLLABLE SSANGSIOS YAE RIEULPHIEUPH
+0x9B8E 0xC35B #HANGUL SYLLABLE SSANGSIOS YAE RIEULHIEUH
+0x9B8F 0xC35C #HANGUL SYLLABLE SSANGSIOS YAE MIEUM
+0x9B90 0xC35D #HANGUL SYLLABLE SSANGSIOS YAE PIEUP
+0x9B91 0xC35E #HANGUL SYLLABLE SSANGSIOS YAE PIEUPSIOS
+0x9B92 0xC35F #HANGUL SYLLABLE SSANGSIOS YAE SIOS
+0x9B93 0xC360 #HANGUL SYLLABLE SSANGSIOS YAE SSANGSIOS
+0x9B94 0xC361 #HANGUL SYLLABLE SSANGSIOS YAE IEUNG
+0x9B95 0xC362 #HANGUL SYLLABLE SSANGSIOS YAE CIEUC
+0x9B96 0xC363 #HANGUL SYLLABLE SSANGSIOS YAE CHIEUCH
+0x9B97 0xC364 #HANGUL SYLLABLE SSANGSIOS YAE KHIEUKH
+0x9B98 0xC365 #HANGUL SYLLABLE SSANGSIOS YAE THIEUTH
+0x9B99 0xC366 #HANGUL SYLLABLE SSANGSIOS YAE PHIEUPH
+0x9B9A 0xC367 #HANGUL SYLLABLE SSANGSIOS YAE HIEUH
+0x9B9B 0xC36A #HANGUL SYLLABLE SSANGSIOS EO SSANGKIYEOK
+0x9B9C 0xC36B #HANGUL SYLLABLE SSANGSIOS EO KIYEOKSIOS
+0x9B9D 0xC36D #HANGUL SYLLABLE SSANGSIOS EO NIEUNCIEUC
+0x9B9E 0xC36E #HANGUL SYLLABLE SSANGSIOS EO NIEUNHIEUH
+0x9B9F 0xC36F #HANGUL SYLLABLE SSANGSIOS EO TIKEUT
+0x9BA0 0xC371 #HANGUL SYLLABLE SSANGSIOS EO RIEULKIYEOK
+0x9BA1 0xC373 #HANGUL SYLLABLE SSANGSIOS EO RIEULPIEUP
+0x9BA2 0xC374 #HANGUL SYLLABLE SSANGSIOS EO RIEULSIOS
+0x9BA3 0xC375 #HANGUL SYLLABLE SSANGSIOS EO RIEULTHIEUTH
+0x9BA4 0xC376 #HANGUL SYLLABLE SSANGSIOS EO RIEULPHIEUPH
+0x9BA5 0xC377 #HANGUL SYLLABLE SSANGSIOS EO RIEULHIEUH
+0x9BA6 0xC37A #HANGUL SYLLABLE SSANGSIOS EO PIEUPSIOS
+0x9BA7 0xC37B #HANGUL SYLLABLE SSANGSIOS EO SIOS
+0x9BA8 0xC37E #HANGUL SYLLABLE SSANGSIOS EO CIEUC
+0x9BA9 0xC37F #HANGUL SYLLABLE SSANGSIOS EO CHIEUCH
+0x9BAA 0xC380 #HANGUL SYLLABLE SSANGSIOS EO KHIEUKH
+0x9BAB 0xC381 #HANGUL SYLLABLE SSANGSIOS EO THIEUTH
+0x9BAC 0xC382 #HANGUL SYLLABLE SSANGSIOS EO PHIEUPH
+0x9BAD 0xC383 #HANGUL SYLLABLE SSANGSIOS EO HIEUH
+0x9BAE 0xC385 #HANGUL SYLLABLE SSANGSIOS E KIYEOK
+0x9BAF 0xC386 #HANGUL SYLLABLE SSANGSIOS E SSANGKIYEOK
+0x9BB0 0xC387 #HANGUL SYLLABLE SSANGSIOS E KIYEOKSIOS
+0x9BB1 0xC389 #HANGUL SYLLABLE SSANGSIOS E NIEUNCIEUC
+0x9BB2 0xC38A #HANGUL SYLLABLE SSANGSIOS E NIEUNHIEUH
+0x9BB3 0xC38B #HANGUL SYLLABLE SSANGSIOS E TIKEUT
+0x9BB4 0xC38D #HANGUL SYLLABLE SSANGSIOS E RIEULKIYEOK
+0x9BB5 0xC38E #HANGUL SYLLABLE SSANGSIOS E RIEULMIEUM
+0x9BB6 0xC38F #HANGUL SYLLABLE SSANGSIOS E RIEULPIEUP
+0x9BB7 0xC390 #HANGUL SYLLABLE SSANGSIOS E RIEULSIOS
+0x9BB8 0xC391 #HANGUL SYLLABLE SSANGSIOS E RIEULTHIEUTH
+0x9BB9 0xC392 #HANGUL SYLLABLE SSANGSIOS E RIEULPHIEUPH
+0x9BBA 0xC393 #HANGUL SYLLABLE SSANGSIOS E RIEULHIEUH
+0x9BBB 0xC394 #HANGUL SYLLABLE SSANGSIOS E MIEUM
+0x9BBC 0xC395 #HANGUL SYLLABLE SSANGSIOS E PIEUP
+0x9BBD 0xC396 #HANGUL SYLLABLE SSANGSIOS E PIEUPSIOS
+0x9BBE 0xC397 #HANGUL SYLLABLE SSANGSIOS E SIOS
+0x9BBF 0xC398 #HANGUL SYLLABLE SSANGSIOS E SSANGSIOS
+0x9BC0 0xC399 #HANGUL SYLLABLE SSANGSIOS E IEUNG
+0x9BC1 0xC39A #HANGUL SYLLABLE SSANGSIOS E CIEUC
+0x9BC2 0xC39B #HANGUL SYLLABLE SSANGSIOS E CHIEUCH
+0x9BC3 0xC39C #HANGUL SYLLABLE SSANGSIOS E KHIEUKH
+0x9BC4 0xC39D #HANGUL SYLLABLE SSANGSIOS E THIEUTH
+0x9BC5 0xC39E #HANGUL SYLLABLE SSANGSIOS E PHIEUPH
+0x9BC6 0xC39F #HANGUL SYLLABLE SSANGSIOS E HIEUH
+0x9BC7 0xC3A0 #HANGUL SYLLABLE SSANGSIOS YEO
+0x9BC8 0xC3A1 #HANGUL SYLLABLE SSANGSIOS YEO KIYEOK
+0x9BC9 0xC3A2 #HANGUL SYLLABLE SSANGSIOS YEO SSANGKIYEOK
+0x9BCA 0xC3A3 #HANGUL SYLLABLE SSANGSIOS YEO KIYEOKSIOS
+0x9BCB 0xC3A4 #HANGUL SYLLABLE SSANGSIOS YEO NIEUN
+0x9BCC 0xC3A5 #HANGUL SYLLABLE SSANGSIOS YEO NIEUNCIEUC
+0x9BCD 0xC3A6 #HANGUL SYLLABLE SSANGSIOS YEO NIEUNHIEUH
+0x9BCE 0xC3A7 #HANGUL SYLLABLE SSANGSIOS YEO TIKEUT
+0x9BCF 0xC3A8 #HANGUL SYLLABLE SSANGSIOS YEO RIEUL
+0x9BD0 0xC3A9 #HANGUL SYLLABLE SSANGSIOS YEO RIEULKIYEOK
+0x9BD1 0xC3AA #HANGUL SYLLABLE SSANGSIOS YEO RIEULMIEUM
+0x9BD2 0xC3AB #HANGUL SYLLABLE SSANGSIOS YEO RIEULPIEUP
+0x9BD3 0xC3AC #HANGUL SYLLABLE SSANGSIOS YEO RIEULSIOS
+0x9BD4 0xC3AD #HANGUL SYLLABLE SSANGSIOS YEO RIEULTHIEUTH
+0x9BD5 0xC3AE #HANGUL SYLLABLE SSANGSIOS YEO RIEULPHIEUPH
+0x9BD6 0xC3AF #HANGUL SYLLABLE SSANGSIOS YEO RIEULHIEUH
+0x9BD7 0xC3B0 #HANGUL SYLLABLE SSANGSIOS YEO MIEUM
+0x9BD8 0xC3B1 #HANGUL SYLLABLE SSANGSIOS YEO PIEUP
+0x9BD9 0xC3B2 #HANGUL SYLLABLE SSANGSIOS YEO PIEUPSIOS
+0x9BDA 0xC3B3 #HANGUL SYLLABLE SSANGSIOS YEO SIOS
+0x9BDB 0xC3B4 #HANGUL SYLLABLE SSANGSIOS YEO SSANGSIOS
+0x9BDC 0xC3B5 #HANGUL SYLLABLE SSANGSIOS YEO IEUNG
+0x9BDD 0xC3B6 #HANGUL SYLLABLE SSANGSIOS YEO CIEUC
+0x9BDE 0xC3B7 #HANGUL SYLLABLE SSANGSIOS YEO CHIEUCH
+0x9BDF 0xC3B8 #HANGUL SYLLABLE SSANGSIOS YEO KHIEUKH
+0x9BE0 0xC3B9 #HANGUL SYLLABLE SSANGSIOS YEO THIEUTH
+0x9BE1 0xC3BA #HANGUL SYLLABLE SSANGSIOS YEO PHIEUPH
+0x9BE2 0xC3BB #HANGUL SYLLABLE SSANGSIOS YEO HIEUH
+0x9BE3 0xC3BC #HANGUL SYLLABLE SSANGSIOS YE
+0x9BE4 0xC3BD #HANGUL SYLLABLE SSANGSIOS YE KIYEOK
+0x9BE5 0xC3BE #HANGUL SYLLABLE SSANGSIOS YE SSANGKIYEOK
+0x9BE6 0xC3BF #HANGUL SYLLABLE SSANGSIOS YE KIYEOKSIOS
+0x9BE7 0xC3C1 #HANGUL SYLLABLE SSANGSIOS YE NIEUNCIEUC
+0x9BE8 0xC3C2 #HANGUL SYLLABLE SSANGSIOS YE NIEUNHIEUH
+0x9BE9 0xC3C3 #HANGUL SYLLABLE SSANGSIOS YE TIKEUT
+0x9BEA 0xC3C4 #HANGUL SYLLABLE SSANGSIOS YE RIEUL
+0x9BEB 0xC3C5 #HANGUL SYLLABLE SSANGSIOS YE RIEULKIYEOK
+0x9BEC 0xC3C6 #HANGUL SYLLABLE SSANGSIOS YE RIEULMIEUM
+0x9BED 0xC3C7 #HANGUL SYLLABLE SSANGSIOS YE RIEULPIEUP
+0x9BEE 0xC3C8 #HANGUL SYLLABLE SSANGSIOS YE RIEULSIOS
+0x9BEF 0xC3C9 #HANGUL SYLLABLE SSANGSIOS YE RIEULTHIEUTH
+0x9BF0 0xC3CA #HANGUL SYLLABLE SSANGSIOS YE RIEULPHIEUPH
+0x9BF1 0xC3CB #HANGUL SYLLABLE SSANGSIOS YE RIEULHIEUH
+0x9BF2 0xC3CC #HANGUL SYLLABLE SSANGSIOS YE MIEUM
+0x9BF3 0xC3CD #HANGUL SYLLABLE SSANGSIOS YE PIEUP
+0x9BF4 0xC3CE #HANGUL SYLLABLE SSANGSIOS YE PIEUPSIOS
+0x9BF5 0xC3CF #HANGUL SYLLABLE SSANGSIOS YE SIOS
+0x9BF6 0xC3D0 #HANGUL SYLLABLE SSANGSIOS YE SSANGSIOS
+0x9BF7 0xC3D1 #HANGUL SYLLABLE SSANGSIOS YE IEUNG
+0x9BF8 0xC3D2 #HANGUL SYLLABLE SSANGSIOS YE CIEUC
+0x9BF9 0xC3D3 #HANGUL SYLLABLE SSANGSIOS YE CHIEUCH
+0x9BFA 0xC3D4 #HANGUL SYLLABLE SSANGSIOS YE KHIEUKH
+0x9BFB 0xC3D5 #HANGUL SYLLABLE SSANGSIOS YE THIEUTH
+0x9BFC 0xC3D6 #HANGUL SYLLABLE SSANGSIOS YE PHIEUPH
+0x9BFD 0xC3D7 #HANGUL SYLLABLE SSANGSIOS YE HIEUH
+0x9BFE 0xC3DA #HANGUL SYLLABLE SSANGSIOS O SSANGKIYEOK
+0x9C41 0xC3DB #HANGUL SYLLABLE SSANGSIOS O KIYEOKSIOS
+0x9C42 0xC3DD #HANGUL SYLLABLE SSANGSIOS O NIEUNCIEUC
+0x9C43 0xC3DE #HANGUL SYLLABLE SSANGSIOS O NIEUNHIEUH
+0x9C44 0xC3E1 #HANGUL SYLLABLE SSANGSIOS O RIEULKIYEOK
+0x9C45 0xC3E3 #HANGUL SYLLABLE SSANGSIOS O RIEULPIEUP
+0x9C46 0xC3E4 #HANGUL SYLLABLE SSANGSIOS O RIEULSIOS
+0x9C47 0xC3E5 #HANGUL SYLLABLE SSANGSIOS O RIEULTHIEUTH
+0x9C48 0xC3E6 #HANGUL SYLLABLE SSANGSIOS O RIEULPHIEUPH
+0x9C49 0xC3E7 #HANGUL SYLLABLE SSANGSIOS O RIEULHIEUH
+0x9C4A 0xC3EA #HANGUL SYLLABLE SSANGSIOS O PIEUPSIOS
+0x9C4B 0xC3EB #HANGUL SYLLABLE SSANGSIOS O SIOS
+0x9C4C 0xC3EC #HANGUL SYLLABLE SSANGSIOS O SSANGSIOS
+0x9C4D 0xC3EE #HANGUL SYLLABLE SSANGSIOS O CIEUC
+0x9C4E 0xC3EF #HANGUL SYLLABLE SSANGSIOS O CHIEUCH
+0x9C4F 0xC3F0 #HANGUL SYLLABLE SSANGSIOS O KHIEUKH
+0x9C50 0xC3F1 #HANGUL SYLLABLE SSANGSIOS O THIEUTH
+0x9C51 0xC3F2 #HANGUL SYLLABLE SSANGSIOS O PHIEUPH
+0x9C52 0xC3F3 #HANGUL SYLLABLE SSANGSIOS O HIEUH
+0x9C53 0xC3F6 #HANGUL SYLLABLE SSANGSIOS WA SSANGKIYEOK
+0x9C54 0xC3F7 #HANGUL SYLLABLE SSANGSIOS WA KIYEOKSIOS
+0x9C55 0xC3F9 #HANGUL SYLLABLE SSANGSIOS WA NIEUNCIEUC
+0x9C56 0xC3FA #HANGUL SYLLABLE SSANGSIOS WA NIEUNHIEUH
+0x9C57 0xC3FB #HANGUL SYLLABLE SSANGSIOS WA TIKEUT
+0x9C58 0xC3FC #HANGUL SYLLABLE SSANGSIOS WA RIEUL
+0x9C59 0xC3FD #HANGUL SYLLABLE SSANGSIOS WA RIEULKIYEOK
+0x9C5A 0xC3FE #HANGUL SYLLABLE SSANGSIOS WA RIEULMIEUM
+0x9C61 0xC3FF #HANGUL SYLLABLE SSANGSIOS WA RIEULPIEUP
+0x9C62 0xC400 #HANGUL SYLLABLE SSANGSIOS WA RIEULSIOS
+0x9C63 0xC401 #HANGUL SYLLABLE SSANGSIOS WA RIEULTHIEUTH
+0x9C64 0xC402 #HANGUL SYLLABLE SSANGSIOS WA RIEULPHIEUPH
+0x9C65 0xC403 #HANGUL SYLLABLE SSANGSIOS WA RIEULHIEUH
+0x9C66 0xC404 #HANGUL SYLLABLE SSANGSIOS WA MIEUM
+0x9C67 0xC405 #HANGUL SYLLABLE SSANGSIOS WA PIEUP
+0x9C68 0xC406 #HANGUL SYLLABLE SSANGSIOS WA PIEUPSIOS
+0x9C69 0xC407 #HANGUL SYLLABLE SSANGSIOS WA SIOS
+0x9C6A 0xC409 #HANGUL SYLLABLE SSANGSIOS WA IEUNG
+0x9C6B 0xC40A #HANGUL SYLLABLE SSANGSIOS WA CIEUC
+0x9C6C 0xC40B #HANGUL SYLLABLE SSANGSIOS WA CHIEUCH
+0x9C6D 0xC40C #HANGUL SYLLABLE SSANGSIOS WA KHIEUKH
+0x9C6E 0xC40D #HANGUL SYLLABLE SSANGSIOS WA THIEUTH
+0x9C6F 0xC40E #HANGUL SYLLABLE SSANGSIOS WA PHIEUPH
+0x9C70 0xC40F #HANGUL SYLLABLE SSANGSIOS WA HIEUH
+0x9C71 0xC411 #HANGUL SYLLABLE SSANGSIOS WAE KIYEOK
+0x9C72 0xC412 #HANGUL SYLLABLE SSANGSIOS WAE SSANGKIYEOK
+0x9C73 0xC413 #HANGUL SYLLABLE SSANGSIOS WAE KIYEOKSIOS
+0x9C74 0xC414 #HANGUL SYLLABLE SSANGSIOS WAE NIEUN
+0x9C75 0xC415 #HANGUL SYLLABLE SSANGSIOS WAE NIEUNCIEUC
+0x9C76 0xC416 #HANGUL SYLLABLE SSANGSIOS WAE NIEUNHIEUH
+0x9C77 0xC417 #HANGUL SYLLABLE SSANGSIOS WAE TIKEUT
+0x9C78 0xC418 #HANGUL SYLLABLE SSANGSIOS WAE RIEUL
+0x9C79 0xC419 #HANGUL SYLLABLE SSANGSIOS WAE RIEULKIYEOK
+0x9C7A 0xC41A #HANGUL SYLLABLE SSANGSIOS WAE RIEULMIEUM
+0x9C81 0xC41B #HANGUL SYLLABLE SSANGSIOS WAE RIEULPIEUP
+0x9C82 0xC41C #HANGUL SYLLABLE SSANGSIOS WAE RIEULSIOS
+0x9C83 0xC41D #HANGUL SYLLABLE SSANGSIOS WAE RIEULTHIEUTH
+0x9C84 0xC41E #HANGUL SYLLABLE SSANGSIOS WAE RIEULPHIEUPH
+0x9C85 0xC41F #HANGUL SYLLABLE SSANGSIOS WAE RIEULHIEUH
+0x9C86 0xC420 #HANGUL SYLLABLE SSANGSIOS WAE MIEUM
+0x9C87 0xC421 #HANGUL SYLLABLE SSANGSIOS WAE PIEUP
+0x9C88 0xC422 #HANGUL SYLLABLE SSANGSIOS WAE PIEUPSIOS
+0x9C89 0xC423 #HANGUL SYLLABLE SSANGSIOS WAE SIOS
+0x9C8A 0xC425 #HANGUL SYLLABLE SSANGSIOS WAE IEUNG
+0x9C8B 0xC426 #HANGUL SYLLABLE SSANGSIOS WAE CIEUC
+0x9C8C 0xC427 #HANGUL SYLLABLE SSANGSIOS WAE CHIEUCH
+0x9C8D 0xC428 #HANGUL SYLLABLE SSANGSIOS WAE KHIEUKH
+0x9C8E 0xC429 #HANGUL SYLLABLE SSANGSIOS WAE THIEUTH
+0x9C8F 0xC42A #HANGUL SYLLABLE SSANGSIOS WAE PHIEUPH
+0x9C90 0xC42B #HANGUL SYLLABLE SSANGSIOS WAE HIEUH
+0x9C91 0xC42D #HANGUL SYLLABLE SSANGSIOS OE KIYEOK
+0x9C92 0xC42E #HANGUL SYLLABLE SSANGSIOS OE SSANGKIYEOK
+0x9C93 0xC42F #HANGUL SYLLABLE SSANGSIOS OE KIYEOKSIOS
+0x9C94 0xC431 #HANGUL SYLLABLE SSANGSIOS OE NIEUNCIEUC
+0x9C95 0xC432 #HANGUL SYLLABLE SSANGSIOS OE NIEUNHIEUH
+0x9C96 0xC433 #HANGUL SYLLABLE SSANGSIOS OE TIKEUT
+0x9C97 0xC435 #HANGUL SYLLABLE SSANGSIOS OE RIEULKIYEOK
+0x9C98 0xC436 #HANGUL SYLLABLE SSANGSIOS OE RIEULMIEUM
+0x9C99 0xC437 #HANGUL SYLLABLE SSANGSIOS OE RIEULPIEUP
+0x9C9A 0xC438 #HANGUL SYLLABLE SSANGSIOS OE RIEULSIOS
+0x9C9B 0xC439 #HANGUL SYLLABLE SSANGSIOS OE RIEULTHIEUTH
+0x9C9C 0xC43A #HANGUL SYLLABLE SSANGSIOS OE RIEULPHIEUPH
+0x9C9D 0xC43B #HANGUL SYLLABLE SSANGSIOS OE RIEULHIEUH
+0x9C9E 0xC43E #HANGUL SYLLABLE SSANGSIOS OE PIEUPSIOS
+0x9C9F 0xC43F #HANGUL SYLLABLE SSANGSIOS OE SIOS
+0x9CA0 0xC440 #HANGUL SYLLABLE SSANGSIOS OE SSANGSIOS
+0x9CA1 0xC441 #HANGUL SYLLABLE SSANGSIOS OE IEUNG
+0x9CA2 0xC442 #HANGUL SYLLABLE SSANGSIOS OE CIEUC
+0x9CA3 0xC443 #HANGUL SYLLABLE SSANGSIOS OE CHIEUCH
+0x9CA4 0xC444 #HANGUL SYLLABLE SSANGSIOS OE KHIEUKH
+0x9CA5 0xC445 #HANGUL SYLLABLE SSANGSIOS OE THIEUTH
+0x9CA6 0xC446 #HANGUL SYLLABLE SSANGSIOS OE PHIEUPH
+0x9CA7 0xC447 #HANGUL SYLLABLE SSANGSIOS OE HIEUH
+0x9CA8 0xC449 #HANGUL SYLLABLE SSANGSIOS YO KIYEOK
+0x9CA9 0xC44A #HANGUL SYLLABLE SSANGSIOS YO SSANGKIYEOK
+0x9CAA 0xC44B #HANGUL SYLLABLE SSANGSIOS YO KIYEOKSIOS
+0x9CAB 0xC44C #HANGUL SYLLABLE SSANGSIOS YO NIEUN
+0x9CAC 0xC44D #HANGUL SYLLABLE SSANGSIOS YO NIEUNCIEUC
+0x9CAD 0xC44E #HANGUL SYLLABLE SSANGSIOS YO NIEUNHIEUH
+0x9CAE 0xC44F #HANGUL SYLLABLE SSANGSIOS YO TIKEUT
+0x9CAF 0xC450 #HANGUL SYLLABLE SSANGSIOS YO RIEUL
+0x9CB0 0xC451 #HANGUL SYLLABLE SSANGSIOS YO RIEULKIYEOK
+0x9CB1 0xC452 #HANGUL SYLLABLE SSANGSIOS YO RIEULMIEUM
+0x9CB2 0xC453 #HANGUL SYLLABLE SSANGSIOS YO RIEULPIEUP
+0x9CB3 0xC454 #HANGUL SYLLABLE SSANGSIOS YO RIEULSIOS
+0x9CB4 0xC455 #HANGUL SYLLABLE SSANGSIOS YO RIEULTHIEUTH
+0x9CB5 0xC456 #HANGUL SYLLABLE SSANGSIOS YO RIEULPHIEUPH
+0x9CB6 0xC457 #HANGUL SYLLABLE SSANGSIOS YO RIEULHIEUH
+0x9CB7 0xC458 #HANGUL SYLLABLE SSANGSIOS YO MIEUM
+0x9CB8 0xC459 #HANGUL SYLLABLE SSANGSIOS YO PIEUP
+0x9CB9 0xC45A #HANGUL SYLLABLE SSANGSIOS YO PIEUPSIOS
+0x9CBA 0xC45B #HANGUL SYLLABLE SSANGSIOS YO SIOS
+0x9CBB 0xC45C #HANGUL SYLLABLE SSANGSIOS YO SSANGSIOS
+0x9CBC 0xC45D #HANGUL SYLLABLE SSANGSIOS YO IEUNG
+0x9CBD 0xC45E #HANGUL SYLLABLE SSANGSIOS YO CIEUC
+0x9CBE 0xC45F #HANGUL SYLLABLE SSANGSIOS YO CHIEUCH
+0x9CBF 0xC460 #HANGUL SYLLABLE SSANGSIOS YO KHIEUKH
+0x9CC0 0xC461 #HANGUL SYLLABLE SSANGSIOS YO THIEUTH
+0x9CC1 0xC462 #HANGUL SYLLABLE SSANGSIOS YO PHIEUPH
+0x9CC2 0xC463 #HANGUL SYLLABLE SSANGSIOS YO HIEUH
+0x9CC3 0xC466 #HANGUL SYLLABLE SSANGSIOS U SSANGKIYEOK
+0x9CC4 0xC467 #HANGUL SYLLABLE SSANGSIOS U KIYEOKSIOS
+0x9CC5 0xC469 #HANGUL SYLLABLE SSANGSIOS U NIEUNCIEUC
+0x9CC6 0xC46A #HANGUL SYLLABLE SSANGSIOS U NIEUNHIEUH
+0x9CC7 0xC46B #HANGUL SYLLABLE SSANGSIOS U TIKEUT
+0x9CC8 0xC46D #HANGUL SYLLABLE SSANGSIOS U RIEULKIYEOK
+0x9CC9 0xC46E #HANGUL SYLLABLE SSANGSIOS U RIEULMIEUM
+0x9CCA 0xC46F #HANGUL SYLLABLE SSANGSIOS U RIEULPIEUP
+0x9CCB 0xC470 #HANGUL SYLLABLE SSANGSIOS U RIEULSIOS
+0x9CCC 0xC471 #HANGUL SYLLABLE SSANGSIOS U RIEULTHIEUTH
+0x9CCD 0xC472 #HANGUL SYLLABLE SSANGSIOS U RIEULPHIEUPH
+0x9CCE 0xC473 #HANGUL SYLLABLE SSANGSIOS U RIEULHIEUH
+0x9CCF 0xC476 #HANGUL SYLLABLE SSANGSIOS U PIEUPSIOS
+0x9CD0 0xC477 #HANGUL SYLLABLE SSANGSIOS U SIOS
+0x9CD1 0xC478 #HANGUL SYLLABLE SSANGSIOS U SSANGSIOS
+0x9CD2 0xC47A #HANGUL SYLLABLE SSANGSIOS U CIEUC
+0x9CD3 0xC47B #HANGUL SYLLABLE SSANGSIOS U CHIEUCH
+0x9CD4 0xC47C #HANGUL SYLLABLE SSANGSIOS U KHIEUKH
+0x9CD5 0xC47D #HANGUL SYLLABLE SSANGSIOS U THIEUTH
+0x9CD6 0xC47E #HANGUL SYLLABLE SSANGSIOS U PHIEUPH
+0x9CD7 0xC47F #HANGUL SYLLABLE SSANGSIOS U HIEUH
+0x9CD8 0xC481 #HANGUL SYLLABLE SSANGSIOS WEO KIYEOK
+0x9CD9 0xC482 #HANGUL SYLLABLE SSANGSIOS WEO SSANGKIYEOK
+0x9CDA 0xC483 #HANGUL SYLLABLE SSANGSIOS WEO KIYEOKSIOS
+0x9CDB 0xC484 #HANGUL SYLLABLE SSANGSIOS WEO NIEUN
+0x9CDC 0xC485 #HANGUL SYLLABLE SSANGSIOS WEO NIEUNCIEUC
+0x9CDD 0xC486 #HANGUL SYLLABLE SSANGSIOS WEO NIEUNHIEUH
+0x9CDE 0xC487 #HANGUL SYLLABLE SSANGSIOS WEO TIKEUT
+0x9CDF 0xC488 #HANGUL SYLLABLE SSANGSIOS WEO RIEUL
+0x9CE0 0xC489 #HANGUL SYLLABLE SSANGSIOS WEO RIEULKIYEOK
+0x9CE1 0xC48A #HANGUL SYLLABLE SSANGSIOS WEO RIEULMIEUM
+0x9CE2 0xC48B #HANGUL SYLLABLE SSANGSIOS WEO RIEULPIEUP
+0x9CE3 0xC48C #HANGUL SYLLABLE SSANGSIOS WEO RIEULSIOS
+0x9CE4 0xC48D #HANGUL SYLLABLE SSANGSIOS WEO RIEULTHIEUTH
+0x9CE5 0xC48E #HANGUL SYLLABLE SSANGSIOS WEO RIEULPHIEUPH
+0x9CE6 0xC48F #HANGUL SYLLABLE SSANGSIOS WEO RIEULHIEUH
+0x9CE7 0xC490 #HANGUL SYLLABLE SSANGSIOS WEO MIEUM
+0x9CE8 0xC491 #HANGUL SYLLABLE SSANGSIOS WEO PIEUP
+0x9CE9 0xC492 #HANGUL SYLLABLE SSANGSIOS WEO PIEUPSIOS
+0x9CEA 0xC493 #HANGUL SYLLABLE SSANGSIOS WEO SIOS
+0x9CEB 0xC495 #HANGUL SYLLABLE SSANGSIOS WEO IEUNG
+0x9CEC 0xC496 #HANGUL SYLLABLE SSANGSIOS WEO CIEUC
+0x9CED 0xC497 #HANGUL SYLLABLE SSANGSIOS WEO CHIEUCH
+0x9CEE 0xC498 #HANGUL SYLLABLE SSANGSIOS WEO KHIEUKH
+0x9CEF 0xC499 #HANGUL SYLLABLE SSANGSIOS WEO THIEUTH
+0x9CF0 0xC49A #HANGUL SYLLABLE SSANGSIOS WEO PHIEUPH
+0x9CF1 0xC49B #HANGUL SYLLABLE SSANGSIOS WEO HIEUH
+0x9CF2 0xC49D #HANGUL SYLLABLE SSANGSIOS WE KIYEOK
+0x9CF3 0xC49E #HANGUL SYLLABLE SSANGSIOS WE SSANGKIYEOK
+0x9CF4 0xC49F #HANGUL SYLLABLE SSANGSIOS WE KIYEOKSIOS
+0x9CF5 0xC4A0 #HANGUL SYLLABLE SSANGSIOS WE NIEUN
+0x9CF6 0xC4A1 #HANGUL SYLLABLE SSANGSIOS WE NIEUNCIEUC
+0x9CF7 0xC4A2 #HANGUL SYLLABLE SSANGSIOS WE NIEUNHIEUH
+0x9CF8 0xC4A3 #HANGUL SYLLABLE SSANGSIOS WE TIKEUT
+0x9CF9 0xC4A4 #HANGUL SYLLABLE SSANGSIOS WE RIEUL
+0x9CFA 0xC4A5 #HANGUL SYLLABLE SSANGSIOS WE RIEULKIYEOK
+0x9CFB 0xC4A6 #HANGUL SYLLABLE SSANGSIOS WE RIEULMIEUM
+0x9CFC 0xC4A7 #HANGUL SYLLABLE SSANGSIOS WE RIEULPIEUP
+0x9CFD 0xC4A8 #HANGUL SYLLABLE SSANGSIOS WE RIEULSIOS
+0x9CFE 0xC4A9 #HANGUL SYLLABLE SSANGSIOS WE RIEULTHIEUTH
+0x9D41 0xC4AA #HANGUL SYLLABLE SSANGSIOS WE RIEULPHIEUPH
+0x9D42 0xC4AB #HANGUL SYLLABLE SSANGSIOS WE RIEULHIEUH
+0x9D43 0xC4AC #HANGUL SYLLABLE SSANGSIOS WE MIEUM
+0x9D44 0xC4AD #HANGUL SYLLABLE SSANGSIOS WE PIEUP
+0x9D45 0xC4AE #HANGUL SYLLABLE SSANGSIOS WE PIEUPSIOS
+0x9D46 0xC4AF #HANGUL SYLLABLE SSANGSIOS WE SIOS
+0x9D47 0xC4B0 #HANGUL SYLLABLE SSANGSIOS WE SSANGSIOS
+0x9D48 0xC4B1 #HANGUL SYLLABLE SSANGSIOS WE IEUNG
+0x9D49 0xC4B2 #HANGUL SYLLABLE SSANGSIOS WE CIEUC
+0x9D4A 0xC4B3 #HANGUL SYLLABLE SSANGSIOS WE CHIEUCH
+0x9D4B 0xC4B4 #HANGUL SYLLABLE SSANGSIOS WE KHIEUKH
+0x9D4C 0xC4B5 #HANGUL SYLLABLE SSANGSIOS WE THIEUTH
+0x9D4D 0xC4B6 #HANGUL SYLLABLE SSANGSIOS WE PHIEUPH
+0x9D4E 0xC4B7 #HANGUL SYLLABLE SSANGSIOS WE HIEUH
+0x9D4F 0xC4B9 #HANGUL SYLLABLE SSANGSIOS WI KIYEOK
+0x9D50 0xC4BA #HANGUL SYLLABLE SSANGSIOS WI SSANGKIYEOK
+0x9D51 0xC4BB #HANGUL SYLLABLE SSANGSIOS WI KIYEOKSIOS
+0x9D52 0xC4BD #HANGUL SYLLABLE SSANGSIOS WI NIEUNCIEUC
+0x9D53 0xC4BE #HANGUL SYLLABLE SSANGSIOS WI NIEUNHIEUH
+0x9D54 0xC4BF #HANGUL SYLLABLE SSANGSIOS WI TIKEUT
+0x9D55 0xC4C0 #HANGUL SYLLABLE SSANGSIOS WI RIEUL
+0x9D56 0xC4C1 #HANGUL SYLLABLE SSANGSIOS WI RIEULKIYEOK
+0x9D57 0xC4C2 #HANGUL SYLLABLE SSANGSIOS WI RIEULMIEUM
+0x9D58 0xC4C3 #HANGUL SYLLABLE SSANGSIOS WI RIEULPIEUP
+0x9D59 0xC4C4 #HANGUL SYLLABLE SSANGSIOS WI RIEULSIOS
+0x9D5A 0xC4C5 #HANGUL SYLLABLE SSANGSIOS WI RIEULTHIEUTH
+0x9D61 0xC4C6 #HANGUL SYLLABLE SSANGSIOS WI RIEULPHIEUPH
+0x9D62 0xC4C7 #HANGUL SYLLABLE SSANGSIOS WI RIEULHIEUH
+0x9D63 0xC4C8 #HANGUL SYLLABLE SSANGSIOS WI MIEUM
+0x9D64 0xC4C9 #HANGUL SYLLABLE SSANGSIOS WI PIEUP
+0x9D65 0xC4CA #HANGUL SYLLABLE SSANGSIOS WI PIEUPSIOS
+0x9D66 0xC4CB #HANGUL SYLLABLE SSANGSIOS WI SIOS
+0x9D67 0xC4CC #HANGUL SYLLABLE SSANGSIOS WI SSANGSIOS
+0x9D68 0xC4CD #HANGUL SYLLABLE SSANGSIOS WI IEUNG
+0x9D69 0xC4CE #HANGUL SYLLABLE SSANGSIOS WI CIEUC
+0x9D6A 0xC4CF #HANGUL SYLLABLE SSANGSIOS WI CHIEUCH
+0x9D6B 0xC4D0 #HANGUL SYLLABLE SSANGSIOS WI KHIEUKH
+0x9D6C 0xC4D1 #HANGUL SYLLABLE SSANGSIOS WI THIEUTH
+0x9D6D 0xC4D2 #HANGUL SYLLABLE SSANGSIOS WI PHIEUPH
+0x9D6E 0xC4D3 #HANGUL SYLLABLE SSANGSIOS WI HIEUH
+0x9D6F 0xC4D4 #HANGUL SYLLABLE SSANGSIOS YU
+0x9D70 0xC4D5 #HANGUL SYLLABLE SSANGSIOS YU KIYEOK
+0x9D71 0xC4D6 #HANGUL SYLLABLE SSANGSIOS YU SSANGKIYEOK
+0x9D72 0xC4D7 #HANGUL SYLLABLE SSANGSIOS YU KIYEOKSIOS
+0x9D73 0xC4D8 #HANGUL SYLLABLE SSANGSIOS YU NIEUN
+0x9D74 0xC4D9 #HANGUL SYLLABLE SSANGSIOS YU NIEUNCIEUC
+0x9D75 0xC4DA #HANGUL SYLLABLE SSANGSIOS YU NIEUNHIEUH
+0x9D76 0xC4DB #HANGUL SYLLABLE SSANGSIOS YU TIKEUT
+0x9D77 0xC4DC #HANGUL SYLLABLE SSANGSIOS YU RIEUL
+0x9D78 0xC4DD #HANGUL SYLLABLE SSANGSIOS YU RIEULKIYEOK
+0x9D79 0xC4DE #HANGUL SYLLABLE SSANGSIOS YU RIEULMIEUM
+0x9D7A 0xC4DF #HANGUL SYLLABLE SSANGSIOS YU RIEULPIEUP
+0x9D81 0xC4E0 #HANGUL SYLLABLE SSANGSIOS YU RIEULSIOS
+0x9D82 0xC4E1 #HANGUL SYLLABLE SSANGSIOS YU RIEULTHIEUTH
+0x9D83 0xC4E2 #HANGUL SYLLABLE SSANGSIOS YU RIEULPHIEUPH
+0x9D84 0xC4E3 #HANGUL SYLLABLE SSANGSIOS YU RIEULHIEUH
+0x9D85 0xC4E4 #HANGUL SYLLABLE SSANGSIOS YU MIEUM
+0x9D86 0xC4E5 #HANGUL SYLLABLE SSANGSIOS YU PIEUP
+0x9D87 0xC4E6 #HANGUL SYLLABLE SSANGSIOS YU PIEUPSIOS
+0x9D88 0xC4E7 #HANGUL SYLLABLE SSANGSIOS YU SIOS
+0x9D89 0xC4E8 #HANGUL SYLLABLE SSANGSIOS YU SSANGSIOS
+0x9D8A 0xC4EA #HANGUL SYLLABLE SSANGSIOS YU CIEUC
+0x9D8B 0xC4EB #HANGUL SYLLABLE SSANGSIOS YU CHIEUCH
+0x9D8C 0xC4EC #HANGUL SYLLABLE SSANGSIOS YU KHIEUKH
+0x9D8D 0xC4ED #HANGUL SYLLABLE SSANGSIOS YU THIEUTH
+0x9D8E 0xC4EE #HANGUL SYLLABLE SSANGSIOS YU PHIEUPH
+0x9D8F 0xC4EF #HANGUL SYLLABLE SSANGSIOS YU HIEUH
+0x9D90 0xC4F2 #HANGUL SYLLABLE SSANGSIOS EU SSANGKIYEOK
+0x9D91 0xC4F3 #HANGUL SYLLABLE SSANGSIOS EU KIYEOKSIOS
+0x9D92 0xC4F5 #HANGUL SYLLABLE SSANGSIOS EU NIEUNCIEUC
+0x9D93 0xC4F6 #HANGUL SYLLABLE SSANGSIOS EU NIEUNHIEUH
+0x9D94 0xC4F7 #HANGUL SYLLABLE SSANGSIOS EU TIKEUT
+0x9D95 0xC4F9 #HANGUL SYLLABLE SSANGSIOS EU RIEULKIYEOK
+0x9D96 0xC4FB #HANGUL SYLLABLE SSANGSIOS EU RIEULPIEUP
+0x9D97 0xC4FC #HANGUL SYLLABLE SSANGSIOS EU RIEULSIOS
+0x9D98 0xC4FD #HANGUL SYLLABLE SSANGSIOS EU RIEULTHIEUTH
+0x9D99 0xC4FE #HANGUL SYLLABLE SSANGSIOS EU RIEULPHIEUPH
+0x9D9A 0xC502 #HANGUL SYLLABLE SSANGSIOS EU PIEUPSIOS
+0x9D9B 0xC503 #HANGUL SYLLABLE SSANGSIOS EU SIOS
+0x9D9C 0xC504 #HANGUL SYLLABLE SSANGSIOS EU SSANGSIOS
+0x9D9D 0xC505 #HANGUL SYLLABLE SSANGSIOS EU IEUNG
+0x9D9E 0xC506 #HANGUL SYLLABLE SSANGSIOS EU CIEUC
+0x9D9F 0xC507 #HANGUL SYLLABLE SSANGSIOS EU CHIEUCH
+0x9DA0 0xC508 #HANGUL SYLLABLE SSANGSIOS EU KHIEUKH
+0x9DA1 0xC509 #HANGUL SYLLABLE SSANGSIOS EU THIEUTH
+0x9DA2 0xC50A #HANGUL SYLLABLE SSANGSIOS EU PHIEUPH
+0x9DA3 0xC50B #HANGUL SYLLABLE SSANGSIOS EU HIEUH
+0x9DA4 0xC50D #HANGUL SYLLABLE SSANGSIOS YI KIYEOK
+0x9DA5 0xC50E #HANGUL SYLLABLE SSANGSIOS YI SSANGKIYEOK
+0x9DA6 0xC50F #HANGUL SYLLABLE SSANGSIOS YI KIYEOKSIOS
+0x9DA7 0xC511 #HANGUL SYLLABLE SSANGSIOS YI NIEUNCIEUC
+0x9DA8 0xC512 #HANGUL SYLLABLE SSANGSIOS YI NIEUNHIEUH
+0x9DA9 0xC513 #HANGUL SYLLABLE SSANGSIOS YI TIKEUT
+0x9DAA 0xC515 #HANGUL SYLLABLE SSANGSIOS YI RIEULKIYEOK
+0x9DAB 0xC516 #HANGUL SYLLABLE SSANGSIOS YI RIEULMIEUM
+0x9DAC 0xC517 #HANGUL SYLLABLE SSANGSIOS YI RIEULPIEUP
+0x9DAD 0xC518 #HANGUL SYLLABLE SSANGSIOS YI RIEULSIOS
+0x9DAE 0xC519 #HANGUL SYLLABLE SSANGSIOS YI RIEULTHIEUTH
+0x9DAF 0xC51A #HANGUL SYLLABLE SSANGSIOS YI RIEULPHIEUPH
+0x9DB0 0xC51B #HANGUL SYLLABLE SSANGSIOS YI RIEULHIEUH
+0x9DB1 0xC51D #HANGUL SYLLABLE SSANGSIOS YI PIEUP
+0x9DB2 0xC51E #HANGUL SYLLABLE SSANGSIOS YI PIEUPSIOS
+0x9DB3 0xC51F #HANGUL SYLLABLE SSANGSIOS YI SIOS
+0x9DB4 0xC520 #HANGUL SYLLABLE SSANGSIOS YI SSANGSIOS
+0x9DB5 0xC521 #HANGUL SYLLABLE SSANGSIOS YI IEUNG
+0x9DB6 0xC522 #HANGUL SYLLABLE SSANGSIOS YI CIEUC
+0x9DB7 0xC523 #HANGUL SYLLABLE SSANGSIOS YI CHIEUCH
+0x9DB8 0xC524 #HANGUL SYLLABLE SSANGSIOS YI KHIEUKH
+0x9DB9 0xC525 #HANGUL SYLLABLE SSANGSIOS YI THIEUTH
+0x9DBA 0xC526 #HANGUL SYLLABLE SSANGSIOS YI PHIEUPH
+0x9DBB 0xC527 #HANGUL SYLLABLE SSANGSIOS YI HIEUH
+0x9DBC 0xC52A #HANGUL SYLLABLE SSANGSIOS I SSANGKIYEOK
+0x9DBD 0xC52B #HANGUL SYLLABLE SSANGSIOS I KIYEOKSIOS
+0x9DBE 0xC52D #HANGUL SYLLABLE SSANGSIOS I NIEUNCIEUC
+0x9DBF 0xC52E #HANGUL SYLLABLE SSANGSIOS I NIEUNHIEUH
+0x9DC0 0xC52F #HANGUL SYLLABLE SSANGSIOS I TIKEUT
+0x9DC1 0xC531 #HANGUL SYLLABLE SSANGSIOS I RIEULKIYEOK
+0x9DC2 0xC532 #HANGUL SYLLABLE SSANGSIOS I RIEULMIEUM
+0x9DC3 0xC533 #HANGUL SYLLABLE SSANGSIOS I RIEULPIEUP
+0x9DC4 0xC534 #HANGUL SYLLABLE SSANGSIOS I RIEULSIOS
+0x9DC5 0xC535 #HANGUL SYLLABLE SSANGSIOS I RIEULTHIEUTH
+0x9DC6 0xC536 #HANGUL SYLLABLE SSANGSIOS I RIEULPHIEUPH
+0x9DC7 0xC537 #HANGUL SYLLABLE SSANGSIOS I RIEULHIEUH
+0x9DC8 0xC53A #HANGUL SYLLABLE SSANGSIOS I PIEUPSIOS
+0x9DC9 0xC53C #HANGUL SYLLABLE SSANGSIOS I SSANGSIOS
+0x9DCA 0xC53E #HANGUL SYLLABLE SSANGSIOS I CIEUC
+0x9DCB 0xC53F #HANGUL SYLLABLE SSANGSIOS I CHIEUCH
+0x9DCC 0xC540 #HANGUL SYLLABLE SSANGSIOS I KHIEUKH
+0x9DCD 0xC541 #HANGUL SYLLABLE SSANGSIOS I THIEUTH
+0x9DCE 0xC542 #HANGUL SYLLABLE SSANGSIOS I PHIEUPH
+0x9DCF 0xC543 #HANGUL SYLLABLE SSANGSIOS I HIEUH
+0x9DD0 0xC546 #HANGUL SYLLABLE IEUNG A SSANGKIYEOK
+0x9DD1 0xC547 #HANGUL SYLLABLE IEUNG A KIYEOKSIOS
+0x9DD2 0xC54B #HANGUL SYLLABLE IEUNG A TIKEUT
+0x9DD3 0xC54F #HANGUL SYLLABLE IEUNG A RIEULPIEUP
+0x9DD4 0xC550 #HANGUL SYLLABLE IEUNG A RIEULSIOS
+0x9DD5 0xC551 #HANGUL SYLLABLE IEUNG A RIEULTHIEUTH
+0x9DD6 0xC552 #HANGUL SYLLABLE IEUNG A RIEULPHIEUPH
+0x9DD7 0xC556 #HANGUL SYLLABLE IEUNG A PIEUPSIOS
+0x9DD8 0xC55A #HANGUL SYLLABLE IEUNG A CIEUC
+0x9DD9 0xC55B #HANGUL SYLLABLE IEUNG A CHIEUCH
+0x9DDA 0xC55C #HANGUL SYLLABLE IEUNG A KHIEUKH
+0x9DDB 0xC55F #HANGUL SYLLABLE IEUNG A HIEUH
+0x9DDC 0xC562 #HANGUL SYLLABLE IEUNG AE SSANGKIYEOK
+0x9DDD 0xC563 #HANGUL SYLLABLE IEUNG AE KIYEOKSIOS
+0x9DDE 0xC565 #HANGUL SYLLABLE IEUNG AE NIEUNCIEUC
+0x9DDF 0xC566 #HANGUL SYLLABLE IEUNG AE NIEUNHIEUH
+0x9DE0 0xC567 #HANGUL SYLLABLE IEUNG AE TIKEUT
+0x9DE1 0xC569 #HANGUL SYLLABLE IEUNG AE RIEULKIYEOK
+0x9DE2 0xC56A #HANGUL SYLLABLE IEUNG AE RIEULMIEUM
+0x9DE3 0xC56B #HANGUL SYLLABLE IEUNG AE RIEULPIEUP
+0x9DE4 0xC56C #HANGUL SYLLABLE IEUNG AE RIEULSIOS
+0x9DE5 0xC56D #HANGUL SYLLABLE IEUNG AE RIEULTHIEUTH
+0x9DE6 0xC56E #HANGUL SYLLABLE IEUNG AE RIEULPHIEUPH
+0x9DE7 0xC56F #HANGUL SYLLABLE IEUNG AE RIEULHIEUH
+0x9DE8 0xC572 #HANGUL SYLLABLE IEUNG AE PIEUPSIOS
+0x9DE9 0xC576 #HANGUL SYLLABLE IEUNG AE CIEUC
+0x9DEA 0xC577 #HANGUL SYLLABLE IEUNG AE CHIEUCH
+0x9DEB 0xC578 #HANGUL SYLLABLE IEUNG AE KHIEUKH
+0x9DEC 0xC579 #HANGUL SYLLABLE IEUNG AE THIEUTH
+0x9DED 0xC57A #HANGUL SYLLABLE IEUNG AE PHIEUPH
+0x9DEE 0xC57B #HANGUL SYLLABLE IEUNG AE HIEUH
+0x9DEF 0xC57E #HANGUL SYLLABLE IEUNG YA SSANGKIYEOK
+0x9DF0 0xC57F #HANGUL SYLLABLE IEUNG YA KIYEOKSIOS
+0x9DF1 0xC581 #HANGUL SYLLABLE IEUNG YA NIEUNCIEUC
+0x9DF2 0xC582 #HANGUL SYLLABLE IEUNG YA NIEUNHIEUH
+0x9DF3 0xC583 #HANGUL SYLLABLE IEUNG YA TIKEUT
+0x9DF4 0xC585 #HANGUL SYLLABLE IEUNG YA RIEULKIYEOK
+0x9DF5 0xC586 #HANGUL SYLLABLE IEUNG YA RIEULMIEUM
+0x9DF6 0xC588 #HANGUL SYLLABLE IEUNG YA RIEULSIOS
+0x9DF7 0xC589 #HANGUL SYLLABLE IEUNG YA RIEULTHIEUTH
+0x9DF8 0xC58A #HANGUL SYLLABLE IEUNG YA RIEULPHIEUPH
+0x9DF9 0xC58B #HANGUL SYLLABLE IEUNG YA RIEULHIEUH
+0x9DFA 0xC58E #HANGUL SYLLABLE IEUNG YA PIEUPSIOS
+0x9DFB 0xC590 #HANGUL SYLLABLE IEUNG YA SSANGSIOS
+0x9DFC 0xC592 #HANGUL SYLLABLE IEUNG YA CIEUC
+0x9DFD 0xC593 #HANGUL SYLLABLE IEUNG YA CHIEUCH
+0x9DFE 0xC594 #HANGUL SYLLABLE IEUNG YA KHIEUKH
+0x9E41 0xC596 #HANGUL SYLLABLE IEUNG YA PHIEUPH
+0x9E42 0xC599 #HANGUL SYLLABLE IEUNG YAE KIYEOK
+0x9E43 0xC59A #HANGUL SYLLABLE IEUNG YAE SSANGKIYEOK
+0x9E44 0xC59B #HANGUL SYLLABLE IEUNG YAE KIYEOKSIOS
+0x9E45 0xC59D #HANGUL SYLLABLE IEUNG YAE NIEUNCIEUC
+0x9E46 0xC59E #HANGUL SYLLABLE IEUNG YAE NIEUNHIEUH
+0x9E47 0xC59F #HANGUL SYLLABLE IEUNG YAE TIKEUT
+0x9E48 0xC5A1 #HANGUL SYLLABLE IEUNG YAE RIEULKIYEOK
+0x9E49 0xC5A2 #HANGUL SYLLABLE IEUNG YAE RIEULMIEUM
+0x9E4A 0xC5A3 #HANGUL SYLLABLE IEUNG YAE RIEULPIEUP
+0x9E4B 0xC5A4 #HANGUL SYLLABLE IEUNG YAE RIEULSIOS
+0x9E4C 0xC5A5 #HANGUL SYLLABLE IEUNG YAE RIEULTHIEUTH
+0x9E4D 0xC5A6 #HANGUL SYLLABLE IEUNG YAE RIEULPHIEUPH
+0x9E4E 0xC5A7 #HANGUL SYLLABLE IEUNG YAE RIEULHIEUH
+0x9E4F 0xC5A8 #HANGUL SYLLABLE IEUNG YAE MIEUM
+0x9E50 0xC5AA #HANGUL SYLLABLE IEUNG YAE PIEUPSIOS
+0x9E51 0xC5AB #HANGUL SYLLABLE IEUNG YAE SIOS
+0x9E52 0xC5AC #HANGUL SYLLABLE IEUNG YAE SSANGSIOS
+0x9E53 0xC5AD #HANGUL SYLLABLE IEUNG YAE IEUNG
+0x9E54 0xC5AE #HANGUL SYLLABLE IEUNG YAE CIEUC
+0x9E55 0xC5AF #HANGUL SYLLABLE IEUNG YAE CHIEUCH
+0x9E56 0xC5B0 #HANGUL SYLLABLE IEUNG YAE KHIEUKH
+0x9E57 0xC5B1 #HANGUL SYLLABLE IEUNG YAE THIEUTH
+0x9E58 0xC5B2 #HANGUL SYLLABLE IEUNG YAE PHIEUPH
+0x9E59 0xC5B3 #HANGUL SYLLABLE IEUNG YAE HIEUH
+0x9E5A 0xC5B6 #HANGUL SYLLABLE IEUNG EO SSANGKIYEOK
+0x9E61 0xC5B7 #HANGUL SYLLABLE IEUNG EO KIYEOKSIOS
+0x9E62 0xC5BA #HANGUL SYLLABLE IEUNG EO NIEUNHIEUH
+0x9E63 0xC5BF #HANGUL SYLLABLE IEUNG EO RIEULPIEUP
+0x9E64 0xC5C0 #HANGUL SYLLABLE IEUNG EO RIEULSIOS
+0x9E65 0xC5C1 #HANGUL SYLLABLE IEUNG EO RIEULTHIEUTH
+0x9E66 0xC5C2 #HANGUL SYLLABLE IEUNG EO RIEULPHIEUPH
+0x9E67 0xC5C3 #HANGUL SYLLABLE IEUNG EO RIEULHIEUH
+0x9E68 0xC5CB #HANGUL SYLLABLE IEUNG EO CHIEUCH
+0x9E69 0xC5CD #HANGUL SYLLABLE IEUNG EO THIEUTH
+0x9E6A 0xC5CF #HANGUL SYLLABLE IEUNG EO HIEUH
+0x9E6B 0xC5D2 #HANGUL SYLLABLE IEUNG E SSANGKIYEOK
+0x9E6C 0xC5D3 #HANGUL SYLLABLE IEUNG E KIYEOKSIOS
+0x9E6D 0xC5D5 #HANGUL SYLLABLE IEUNG E NIEUNCIEUC
+0x9E6E 0xC5D6 #HANGUL SYLLABLE IEUNG E NIEUNHIEUH
+0x9E6F 0xC5D7 #HANGUL SYLLABLE IEUNG E TIKEUT
+0x9E70 0xC5D9 #HANGUL SYLLABLE IEUNG E RIEULKIYEOK
+0x9E71 0xC5DA #HANGUL SYLLABLE IEUNG E RIEULMIEUM
+0x9E72 0xC5DB #HANGUL SYLLABLE IEUNG E RIEULPIEUP
+0x9E73 0xC5DC #HANGUL SYLLABLE IEUNG E RIEULSIOS
+0x9E74 0xC5DD #HANGUL SYLLABLE IEUNG E RIEULTHIEUTH
+0x9E75 0xC5DE #HANGUL SYLLABLE IEUNG E RIEULPHIEUPH
+0x9E76 0xC5DF #HANGUL SYLLABLE IEUNG E RIEULHIEUH
+0x9E77 0xC5E2 #HANGUL SYLLABLE IEUNG E PIEUPSIOS
+0x9E78 0xC5E4 #HANGUL SYLLABLE IEUNG E SSANGSIOS
+0x9E79 0xC5E6 #HANGUL SYLLABLE IEUNG E CIEUC
+0x9E7A 0xC5E7 #HANGUL SYLLABLE IEUNG E CHIEUCH
+0x9E81 0xC5E8 #HANGUL SYLLABLE IEUNG E KHIEUKH
+0x9E82 0xC5E9 #HANGUL SYLLABLE IEUNG E THIEUTH
+0x9E83 0xC5EA #HANGUL SYLLABLE IEUNG E PHIEUPH
+0x9E84 0xC5EB #HANGUL SYLLABLE IEUNG E HIEUH
+0x9E85 0xC5EF #HANGUL SYLLABLE IEUNG YEO KIYEOKSIOS
+0x9E86 0xC5F1 #HANGUL SYLLABLE IEUNG YEO NIEUNCIEUC
+0x9E87 0xC5F2 #HANGUL SYLLABLE IEUNG YEO NIEUNHIEUH
+0x9E88 0xC5F3 #HANGUL SYLLABLE IEUNG YEO TIKEUT
+0x9E89 0xC5F5 #HANGUL SYLLABLE IEUNG YEO RIEULKIYEOK
+0x9E8A 0xC5F8 #HANGUL SYLLABLE IEUNG YEO RIEULSIOS
+0x9E8B 0xC5F9 #HANGUL SYLLABLE IEUNG YEO RIEULTHIEUTH
+0x9E8C 0xC5FA #HANGUL SYLLABLE IEUNG YEO RIEULPHIEUPH
+0x9E8D 0xC5FB #HANGUL SYLLABLE IEUNG YEO RIEULHIEUH
+0x9E8E 0xC602 #HANGUL SYLLABLE IEUNG YEO CIEUC
+0x9E8F 0xC603 #HANGUL SYLLABLE IEUNG YEO CHIEUCH
+0x9E90 0xC604 #HANGUL SYLLABLE IEUNG YEO KHIEUKH
+0x9E91 0xC609 #HANGUL SYLLABLE IEUNG YE KIYEOK
+0x9E92 0xC60A #HANGUL SYLLABLE IEUNG YE SSANGKIYEOK
+0x9E93 0xC60B #HANGUL SYLLABLE IEUNG YE KIYEOKSIOS
+0x9E94 0xC60D #HANGUL SYLLABLE IEUNG YE NIEUNCIEUC
+0x9E95 0xC60E #HANGUL SYLLABLE IEUNG YE NIEUNHIEUH
+0x9E96 0xC60F #HANGUL SYLLABLE IEUNG YE TIKEUT
+0x9E97 0xC611 #HANGUL SYLLABLE IEUNG YE RIEULKIYEOK
+0x9E98 0xC612 #HANGUL SYLLABLE IEUNG YE RIEULMIEUM
+0x9E99 0xC613 #HANGUL SYLLABLE IEUNG YE RIEULPIEUP
+0x9E9A 0xC614 #HANGUL SYLLABLE IEUNG YE RIEULSIOS
+0x9E9B 0xC615 #HANGUL SYLLABLE IEUNG YE RIEULTHIEUTH
+0x9E9C 0xC616 #HANGUL SYLLABLE IEUNG YE RIEULPHIEUPH
+0x9E9D 0xC617 #HANGUL SYLLABLE IEUNG YE RIEULHIEUH
+0x9E9E 0xC61A #HANGUL SYLLABLE IEUNG YE PIEUPSIOS
+0x9E9F 0xC61D #HANGUL SYLLABLE IEUNG YE IEUNG
+0x9EA0 0xC61E #HANGUL SYLLABLE IEUNG YE CIEUC
+0x9EA1 0xC61F #HANGUL SYLLABLE IEUNG YE CHIEUCH
+0x9EA2 0xC620 #HANGUL SYLLABLE IEUNG YE KHIEUKH
+0x9EA3 0xC621 #HANGUL SYLLABLE IEUNG YE THIEUTH
+0x9EA4 0xC622 #HANGUL SYLLABLE IEUNG YE PHIEUPH
+0x9EA5 0xC623 #HANGUL SYLLABLE IEUNG YE HIEUH
+0x9EA6 0xC626 #HANGUL SYLLABLE IEUNG O SSANGKIYEOK
+0x9EA7 0xC627 #HANGUL SYLLABLE IEUNG O KIYEOKSIOS
+0x9EA8 0xC629 #HANGUL SYLLABLE IEUNG O NIEUNCIEUC
+0x9EA9 0xC62A #HANGUL SYLLABLE IEUNG O NIEUNHIEUH
+0x9EAA 0xC62B #HANGUL SYLLABLE IEUNG O TIKEUT
+0x9EAB 0xC62F #HANGUL SYLLABLE IEUNG O RIEULPIEUP
+0x9EAC 0xC631 #HANGUL SYLLABLE IEUNG O RIEULTHIEUTH
+0x9EAD 0xC632 #HANGUL SYLLABLE IEUNG O RIEULPHIEUPH
+0x9EAE 0xC636 #HANGUL SYLLABLE IEUNG O PIEUPSIOS
+0x9EAF 0xC638 #HANGUL SYLLABLE IEUNG O SSANGSIOS
+0x9EB0 0xC63A #HANGUL SYLLABLE IEUNG O CIEUC
+0x9EB1 0xC63C #HANGUL SYLLABLE IEUNG O KHIEUKH
+0x9EB2 0xC63D #HANGUL SYLLABLE IEUNG O THIEUTH
+0x9EB3 0xC63E #HANGUL SYLLABLE IEUNG O PHIEUPH
+0x9EB4 0xC63F #HANGUL SYLLABLE IEUNG O HIEUH
+0x9EB5 0xC642 #HANGUL SYLLABLE IEUNG WA SSANGKIYEOK
+0x9EB6 0xC643 #HANGUL SYLLABLE IEUNG WA KIYEOKSIOS
+0x9EB7 0xC645 #HANGUL SYLLABLE IEUNG WA NIEUNCIEUC
+0x9EB8 0xC646 #HANGUL SYLLABLE IEUNG WA NIEUNHIEUH
+0x9EB9 0xC647 #HANGUL SYLLABLE IEUNG WA TIKEUT
+0x9EBA 0xC649 #HANGUL SYLLABLE IEUNG WA RIEULKIYEOK
+0x9EBB 0xC64A #HANGUL SYLLABLE IEUNG WA RIEULMIEUM
+0x9EBC 0xC64B #HANGUL SYLLABLE IEUNG WA RIEULPIEUP
+0x9EBD 0xC64C #HANGUL SYLLABLE IEUNG WA RIEULSIOS
+0x9EBE 0xC64D #HANGUL SYLLABLE IEUNG WA RIEULTHIEUTH
+0x9EBF 0xC64E #HANGUL SYLLABLE IEUNG WA RIEULPHIEUPH
+0x9EC0 0xC64F #HANGUL SYLLABLE IEUNG WA RIEULHIEUH
+0x9EC1 0xC652 #HANGUL SYLLABLE IEUNG WA PIEUPSIOS
+0x9EC2 0xC656 #HANGUL SYLLABLE IEUNG WA CIEUC
+0x9EC3 0xC657 #HANGUL SYLLABLE IEUNG WA CHIEUCH
+0x9EC4 0xC658 #HANGUL SYLLABLE IEUNG WA KHIEUKH
+0x9EC5 0xC659 #HANGUL SYLLABLE IEUNG WA THIEUTH
+0x9EC6 0xC65A #HANGUL SYLLABLE IEUNG WA PHIEUPH
+0x9EC7 0xC65B #HANGUL SYLLABLE IEUNG WA HIEUH
+0x9EC8 0xC65E #HANGUL SYLLABLE IEUNG WAE SSANGKIYEOK
+0x9EC9 0xC65F #HANGUL SYLLABLE IEUNG WAE KIYEOKSIOS
+0x9ECA 0xC661 #HANGUL SYLLABLE IEUNG WAE NIEUNCIEUC
+0x9ECB 0xC662 #HANGUL SYLLABLE IEUNG WAE NIEUNHIEUH
+0x9ECC 0xC663 #HANGUL SYLLABLE IEUNG WAE TIKEUT
+0x9ECD 0xC664 #HANGUL SYLLABLE IEUNG WAE RIEUL
+0x9ECE 0xC665 #HANGUL SYLLABLE IEUNG WAE RIEULKIYEOK
+0x9ECF 0xC666 #HANGUL SYLLABLE IEUNG WAE RIEULMIEUM
+0x9ED0 0xC667 #HANGUL SYLLABLE IEUNG WAE RIEULPIEUP
+0x9ED1 0xC668 #HANGUL SYLLABLE IEUNG WAE RIEULSIOS
+0x9ED2 0xC669 #HANGUL SYLLABLE IEUNG WAE RIEULTHIEUTH
+0x9ED3 0xC66A #HANGUL SYLLABLE IEUNG WAE RIEULPHIEUPH
+0x9ED4 0xC66B #HANGUL SYLLABLE IEUNG WAE RIEULHIEUH
+0x9ED5 0xC66D #HANGUL SYLLABLE IEUNG WAE PIEUP
+0x9ED6 0xC66E #HANGUL SYLLABLE IEUNG WAE PIEUPSIOS
+0x9ED7 0xC670 #HANGUL SYLLABLE IEUNG WAE SSANGSIOS
+0x9ED8 0xC672 #HANGUL SYLLABLE IEUNG WAE CIEUC
+0x9ED9 0xC673 #HANGUL SYLLABLE IEUNG WAE CHIEUCH
+0x9EDA 0xC674 #HANGUL SYLLABLE IEUNG WAE KHIEUKH
+0x9EDB 0xC675 #HANGUL SYLLABLE IEUNG WAE THIEUTH
+0x9EDC 0xC676 #HANGUL SYLLABLE IEUNG WAE PHIEUPH
+0x9EDD 0xC677 #HANGUL SYLLABLE IEUNG WAE HIEUH
+0x9EDE 0xC67A #HANGUL SYLLABLE IEUNG OE SSANGKIYEOK
+0x9EDF 0xC67B #HANGUL SYLLABLE IEUNG OE KIYEOKSIOS
+0x9EE0 0xC67D #HANGUL SYLLABLE IEUNG OE NIEUNCIEUC
+0x9EE1 0xC67E #HANGUL SYLLABLE IEUNG OE NIEUNHIEUH
+0x9EE2 0xC67F #HANGUL SYLLABLE IEUNG OE TIKEUT
+0x9EE3 0xC681 #HANGUL SYLLABLE IEUNG OE RIEULKIYEOK
+0x9EE4 0xC682 #HANGUL SYLLABLE IEUNG OE RIEULMIEUM
+0x9EE5 0xC683 #HANGUL SYLLABLE IEUNG OE RIEULPIEUP
+0x9EE6 0xC684 #HANGUL SYLLABLE IEUNG OE RIEULSIOS
+0x9EE7 0xC685 #HANGUL SYLLABLE IEUNG OE RIEULTHIEUTH
+0x9EE8 0xC686 #HANGUL SYLLABLE IEUNG OE RIEULPHIEUPH
+0x9EE9 0xC687 #HANGUL SYLLABLE IEUNG OE RIEULHIEUH
+0x9EEA 0xC68A #HANGUL SYLLABLE IEUNG OE PIEUPSIOS
+0x9EEB 0xC68C #HANGUL SYLLABLE IEUNG OE SSANGSIOS
+0x9EEC 0xC68E #HANGUL SYLLABLE IEUNG OE CIEUC
+0x9EED 0xC68F #HANGUL SYLLABLE IEUNG OE CHIEUCH
+0x9EEE 0xC690 #HANGUL SYLLABLE IEUNG OE KHIEUKH
+0x9EEF 0xC691 #HANGUL SYLLABLE IEUNG OE THIEUTH
+0x9EF0 0xC692 #HANGUL SYLLABLE IEUNG OE PHIEUPH
+0x9EF1 0xC693 #HANGUL SYLLABLE IEUNG OE HIEUH
+0x9EF2 0xC696 #HANGUL SYLLABLE IEUNG YO SSANGKIYEOK
+0x9EF3 0xC697 #HANGUL SYLLABLE IEUNG YO KIYEOKSIOS
+0x9EF4 0xC699 #HANGUL SYLLABLE IEUNG YO NIEUNCIEUC
+0x9EF5 0xC69A #HANGUL SYLLABLE IEUNG YO NIEUNHIEUH
+0x9EF6 0xC69B #HANGUL SYLLABLE IEUNG YO TIKEUT
+0x9EF7 0xC69D #HANGUL SYLLABLE IEUNG YO RIEULKIYEOK
+0x9EF8 0xC69E #HANGUL SYLLABLE IEUNG YO RIEULMIEUM
+0x9EF9 0xC69F #HANGUL SYLLABLE IEUNG YO RIEULPIEUP
+0x9EFA 0xC6A0 #HANGUL SYLLABLE IEUNG YO RIEULSIOS
+0x9EFB 0xC6A1 #HANGUL SYLLABLE IEUNG YO RIEULTHIEUTH
+0x9EFC 0xC6A2 #HANGUL SYLLABLE IEUNG YO RIEULPHIEUPH
+0x9EFD 0xC6A3 #HANGUL SYLLABLE IEUNG YO RIEULHIEUH
+0x9EFE 0xC6A6 #HANGUL SYLLABLE IEUNG YO PIEUPSIOS
+0x9F41 0xC6A8 #HANGUL SYLLABLE IEUNG YO SSANGSIOS
+0x9F42 0xC6AA #HANGUL SYLLABLE IEUNG YO CIEUC
+0x9F43 0xC6AB #HANGUL SYLLABLE IEUNG YO CHIEUCH
+0x9F44 0xC6AC #HANGUL SYLLABLE IEUNG YO KHIEUKH
+0x9F45 0xC6AD #HANGUL SYLLABLE IEUNG YO THIEUTH
+0x9F46 0xC6AE #HANGUL SYLLABLE IEUNG YO PHIEUPH
+0x9F47 0xC6AF #HANGUL SYLLABLE IEUNG YO HIEUH
+0x9F48 0xC6B2 #HANGUL SYLLABLE IEUNG U SSANGKIYEOK
+0x9F49 0xC6B3 #HANGUL SYLLABLE IEUNG U KIYEOKSIOS
+0x9F4A 0xC6B5 #HANGUL SYLLABLE IEUNG U NIEUNCIEUC
+0x9F4B 0xC6B6 #HANGUL SYLLABLE IEUNG U NIEUNHIEUH
+0x9F4C 0xC6B7 #HANGUL SYLLABLE IEUNG U TIKEUT
+0x9F4D 0xC6BB #HANGUL SYLLABLE IEUNG U RIEULPIEUP
+0x9F4E 0xC6BC #HANGUL SYLLABLE IEUNG U RIEULSIOS
+0x9F4F 0xC6BD #HANGUL SYLLABLE IEUNG U RIEULTHIEUTH
+0x9F50 0xC6BE #HANGUL SYLLABLE IEUNG U RIEULPHIEUPH
+0x9F51 0xC6BF #HANGUL SYLLABLE IEUNG U RIEULHIEUH
+0x9F52 0xC6C2 #HANGUL SYLLABLE IEUNG U PIEUPSIOS
+0x9F53 0xC6C4 #HANGUL SYLLABLE IEUNG U SSANGSIOS
+0x9F54 0xC6C6 #HANGUL SYLLABLE IEUNG U CIEUC
+0x9F55 0xC6C7 #HANGUL SYLLABLE IEUNG U CHIEUCH
+0x9F56 0xC6C8 #HANGUL SYLLABLE IEUNG U KHIEUKH
+0x9F57 0xC6C9 #HANGUL SYLLABLE IEUNG U THIEUTH
+0x9F58 0xC6CA #HANGUL SYLLABLE IEUNG U PHIEUPH
+0x9F59 0xC6CB #HANGUL SYLLABLE IEUNG U HIEUH
+0x9F5A 0xC6CE #HANGUL SYLLABLE IEUNG WEO SSANGKIYEOK
+0x9F61 0xC6CF #HANGUL SYLLABLE IEUNG WEO KIYEOKSIOS
+0x9F62 0xC6D1 #HANGUL SYLLABLE IEUNG WEO NIEUNCIEUC
+0x9F63 0xC6D2 #HANGUL SYLLABLE IEUNG WEO NIEUNHIEUH
+0x9F64 0xC6D3 #HANGUL SYLLABLE IEUNG WEO TIKEUT
+0x9F65 0xC6D5 #HANGUL SYLLABLE IEUNG WEO RIEULKIYEOK
+0x9F66 0xC6D6 #HANGUL SYLLABLE IEUNG WEO RIEULMIEUM
+0x9F67 0xC6D7 #HANGUL SYLLABLE IEUNG WEO RIEULPIEUP
+0x9F68 0xC6D8 #HANGUL SYLLABLE IEUNG WEO RIEULSIOS
+0x9F69 0xC6D9 #HANGUL SYLLABLE IEUNG WEO RIEULTHIEUTH
+0x9F6A 0xC6DA #HANGUL SYLLABLE IEUNG WEO RIEULPHIEUPH
+0x9F6B 0xC6DB #HANGUL SYLLABLE IEUNG WEO RIEULHIEUH
+0x9F6C 0xC6DE #HANGUL SYLLABLE IEUNG WEO PIEUPSIOS
+0x9F6D 0xC6DF #HANGUL SYLLABLE IEUNG WEO SIOS
+0x9F6E 0xC6E2 #HANGUL SYLLABLE IEUNG WEO CIEUC
+0x9F6F 0xC6E3 #HANGUL SYLLABLE IEUNG WEO CHIEUCH
+0x9F70 0xC6E4 #HANGUL SYLLABLE IEUNG WEO KHIEUKH
+0x9F71 0xC6E5 #HANGUL SYLLABLE IEUNG WEO THIEUTH
+0x9F72 0xC6E6 #HANGUL SYLLABLE IEUNG WEO PHIEUPH
+0x9F73 0xC6E7 #HANGUL SYLLABLE IEUNG WEO HIEUH
+0x9F74 0xC6EA #HANGUL SYLLABLE IEUNG WE SSANGKIYEOK
+0x9F75 0xC6EB #HANGUL SYLLABLE IEUNG WE KIYEOKSIOS
+0x9F76 0xC6ED #HANGUL SYLLABLE IEUNG WE NIEUNCIEUC
+0x9F77 0xC6EE #HANGUL SYLLABLE IEUNG WE NIEUNHIEUH
+0x9F78 0xC6EF #HANGUL SYLLABLE IEUNG WE TIKEUT
+0x9F79 0xC6F1 #HANGUL SYLLABLE IEUNG WE RIEULKIYEOK
+0x9F7A 0xC6F2 #HANGUL SYLLABLE IEUNG WE RIEULMIEUM
+0x9F81 0xC6F3 #HANGUL SYLLABLE IEUNG WE RIEULPIEUP
+0x9F82 0xC6F4 #HANGUL SYLLABLE IEUNG WE RIEULSIOS
+0x9F83 0xC6F5 #HANGUL SYLLABLE IEUNG WE RIEULTHIEUTH
+0x9F84 0xC6F6 #HANGUL SYLLABLE IEUNG WE RIEULPHIEUPH
+0x9F85 0xC6F7 #HANGUL SYLLABLE IEUNG WE RIEULHIEUH
+0x9F86 0xC6FA #HANGUL SYLLABLE IEUNG WE PIEUPSIOS
+0x9F87 0xC6FB #HANGUL SYLLABLE IEUNG WE SIOS
+0x9F88 0xC6FC #HANGUL SYLLABLE IEUNG WE SSANGSIOS
+0x9F89 0xC6FE #HANGUL SYLLABLE IEUNG WE CIEUC
+0x9F8A 0xC6FF #HANGUL SYLLABLE IEUNG WE CHIEUCH
+0x9F8B 0xC700 #HANGUL SYLLABLE IEUNG WE KHIEUKH
+0x9F8C 0xC701 #HANGUL SYLLABLE IEUNG WE THIEUTH
+0x9F8D 0xC702 #HANGUL SYLLABLE IEUNG WE PHIEUPH
+0x9F8E 0xC703 #HANGUL SYLLABLE IEUNG WE HIEUH
+0x9F8F 0xC706 #HANGUL SYLLABLE IEUNG WI SSANGKIYEOK
+0x9F90 0xC707 #HANGUL SYLLABLE IEUNG WI KIYEOKSIOS
+0x9F91 0xC709 #HANGUL SYLLABLE IEUNG WI NIEUNCIEUC
+0x9F92 0xC70A #HANGUL SYLLABLE IEUNG WI NIEUNHIEUH
+0x9F93 0xC70B #HANGUL SYLLABLE IEUNG WI TIKEUT
+0x9F94 0xC70D #HANGUL SYLLABLE IEUNG WI RIEULKIYEOK
+0x9F95 0xC70E #HANGUL SYLLABLE IEUNG WI RIEULMIEUM
+0x9F96 0xC70F #HANGUL SYLLABLE IEUNG WI RIEULPIEUP
+0x9F97 0xC710 #HANGUL SYLLABLE IEUNG WI RIEULSIOS
+0x9F98 0xC711 #HANGUL SYLLABLE IEUNG WI RIEULTHIEUTH
+0x9F99 0xC712 #HANGUL SYLLABLE IEUNG WI RIEULPHIEUPH
+0x9F9A 0xC713 #HANGUL SYLLABLE IEUNG WI RIEULHIEUH
+0x9F9B 0xC716 #HANGUL SYLLABLE IEUNG WI PIEUPSIOS
+0x9F9C 0xC718 #HANGUL SYLLABLE IEUNG WI SSANGSIOS
+0x9F9D 0xC71A #HANGUL SYLLABLE IEUNG WI CIEUC
+0x9F9E 0xC71B #HANGUL SYLLABLE IEUNG WI CHIEUCH
+0x9F9F 0xC71C #HANGUL SYLLABLE IEUNG WI KHIEUKH
+0x9FA0 0xC71D #HANGUL SYLLABLE IEUNG WI THIEUTH
+0x9FA1 0xC71E #HANGUL SYLLABLE IEUNG WI PHIEUPH
+0x9FA2 0xC71F #HANGUL SYLLABLE IEUNG WI HIEUH
+0x9FA3 0xC722 #HANGUL SYLLABLE IEUNG YU SSANGKIYEOK
+0x9FA4 0xC723 #HANGUL SYLLABLE IEUNG YU KIYEOKSIOS
+0x9FA5 0xC725 #HANGUL SYLLABLE IEUNG YU NIEUNCIEUC
+0x9FA6 0xC726 #HANGUL SYLLABLE IEUNG YU NIEUNHIEUH
+0x9FA7 0xC727 #HANGUL SYLLABLE IEUNG YU TIKEUT
+0x9FA8 0xC729 #HANGUL SYLLABLE IEUNG YU RIEULKIYEOK
+0x9FA9 0xC72A #HANGUL SYLLABLE IEUNG YU RIEULMIEUM
+0x9FAA 0xC72B #HANGUL SYLLABLE IEUNG YU RIEULPIEUP
+0x9FAB 0xC72C #HANGUL SYLLABLE IEUNG YU RIEULSIOS
+0x9FAC 0xC72D #HANGUL SYLLABLE IEUNG YU RIEULTHIEUTH
+0x9FAD 0xC72E #HANGUL SYLLABLE IEUNG YU RIEULPHIEUPH
+0x9FAE 0xC72F #HANGUL SYLLABLE IEUNG YU RIEULHIEUH
+0x9FAF 0xC732 #HANGUL SYLLABLE IEUNG YU PIEUPSIOS
+0x9FB0 0xC734 #HANGUL SYLLABLE IEUNG YU SSANGSIOS
+0x9FB1 0xC736 #HANGUL SYLLABLE IEUNG YU CIEUC
+0x9FB2 0xC738 #HANGUL SYLLABLE IEUNG YU KHIEUKH
+0x9FB3 0xC739 #HANGUL SYLLABLE IEUNG YU THIEUTH
+0x9FB4 0xC73A #HANGUL SYLLABLE IEUNG YU PHIEUPH
+0x9FB5 0xC73B #HANGUL SYLLABLE IEUNG YU HIEUH
+0x9FB6 0xC73E #HANGUL SYLLABLE IEUNG EU SSANGKIYEOK
+0x9FB7 0xC73F #HANGUL SYLLABLE IEUNG EU KIYEOKSIOS
+0x9FB8 0xC741 #HANGUL SYLLABLE IEUNG EU NIEUNCIEUC
+0x9FB9 0xC742 #HANGUL SYLLABLE IEUNG EU NIEUNHIEUH
+0x9FBA 0xC743 #HANGUL SYLLABLE IEUNG EU TIKEUT
+0x9FBB 0xC745 #HANGUL SYLLABLE IEUNG EU RIEULKIYEOK
+0x9FBC 0xC746 #HANGUL SYLLABLE IEUNG EU RIEULMIEUM
+0x9FBD 0xC747 #HANGUL SYLLABLE IEUNG EU RIEULPIEUP
+0x9FBE 0xC748 #HANGUL SYLLABLE IEUNG EU RIEULSIOS
+0x9FBF 0xC749 #HANGUL SYLLABLE IEUNG EU RIEULTHIEUTH
+0x9FC0 0xC74B #HANGUL SYLLABLE IEUNG EU RIEULHIEUH
+0x9FC1 0xC74E #HANGUL SYLLABLE IEUNG EU PIEUPSIOS
+0x9FC2 0xC750 #HANGUL SYLLABLE IEUNG EU SSANGSIOS
+0x9FC3 0xC759 #HANGUL SYLLABLE IEUNG YI KIYEOK
+0x9FC4 0xC75A #HANGUL SYLLABLE IEUNG YI SSANGKIYEOK
+0x9FC5 0xC75B #HANGUL SYLLABLE IEUNG YI KIYEOKSIOS
+0x9FC6 0xC75D #HANGUL SYLLABLE IEUNG YI NIEUNCIEUC
+0x9FC7 0xC75E #HANGUL SYLLABLE IEUNG YI NIEUNHIEUH
+0x9FC8 0xC75F #HANGUL SYLLABLE IEUNG YI TIKEUT
+0x9FC9 0xC761 #HANGUL SYLLABLE IEUNG YI RIEULKIYEOK
+0x9FCA 0xC762 #HANGUL SYLLABLE IEUNG YI RIEULMIEUM
+0x9FCB 0xC763 #HANGUL SYLLABLE IEUNG YI RIEULPIEUP
+0x9FCC 0xC764 #HANGUL SYLLABLE IEUNG YI RIEULSIOS
+0x9FCD 0xC765 #HANGUL SYLLABLE IEUNG YI RIEULTHIEUTH
+0x9FCE 0xC766 #HANGUL SYLLABLE IEUNG YI RIEULPHIEUPH
+0x9FCF 0xC767 #HANGUL SYLLABLE IEUNG YI RIEULHIEUH
+0x9FD0 0xC769 #HANGUL SYLLABLE IEUNG YI PIEUP
+0x9FD1 0xC76A #HANGUL SYLLABLE IEUNG YI PIEUPSIOS
+0x9FD2 0xC76C #HANGUL SYLLABLE IEUNG YI SSANGSIOS
+0x9FD3 0xC76D #HANGUL SYLLABLE IEUNG YI IEUNG
+0x9FD4 0xC76E #HANGUL SYLLABLE IEUNG YI CIEUC
+0x9FD5 0xC76F #HANGUL SYLLABLE IEUNG YI CHIEUCH
+0x9FD6 0xC770 #HANGUL SYLLABLE IEUNG YI KHIEUKH
+0x9FD7 0xC771 #HANGUL SYLLABLE IEUNG YI THIEUTH
+0x9FD8 0xC772 #HANGUL SYLLABLE IEUNG YI PHIEUPH
+0x9FD9 0xC773 #HANGUL SYLLABLE IEUNG YI HIEUH
+0x9FDA 0xC776 #HANGUL SYLLABLE IEUNG I SSANGKIYEOK
+0x9FDB 0xC777 #HANGUL SYLLABLE IEUNG I KIYEOKSIOS
+0x9FDC 0xC779 #HANGUL SYLLABLE IEUNG I NIEUNCIEUC
+0x9FDD 0xC77A #HANGUL SYLLABLE IEUNG I NIEUNHIEUH
+0x9FDE 0xC77B #HANGUL SYLLABLE IEUNG I TIKEUT
+0x9FDF 0xC77F #HANGUL SYLLABLE IEUNG I RIEULPIEUP
+0x9FE0 0xC780 #HANGUL SYLLABLE IEUNG I RIEULSIOS
+0x9FE1 0xC781 #HANGUL SYLLABLE IEUNG I RIEULTHIEUTH
+0x9FE2 0xC782 #HANGUL SYLLABLE IEUNG I RIEULPHIEUPH
+0x9FE3 0xC786 #HANGUL SYLLABLE IEUNG I PIEUPSIOS
+0x9FE4 0xC78B #HANGUL SYLLABLE IEUNG I CHIEUCH
+0x9FE5 0xC78C #HANGUL SYLLABLE IEUNG I KHIEUKH
+0x9FE6 0xC78D #HANGUL SYLLABLE IEUNG I THIEUTH
+0x9FE7 0xC78F #HANGUL SYLLABLE IEUNG I HIEUH
+0x9FE8 0xC792 #HANGUL SYLLABLE CIEUC A SSANGKIYEOK
+0x9FE9 0xC793 #HANGUL SYLLABLE CIEUC A KIYEOKSIOS
+0x9FEA 0xC795 #HANGUL SYLLABLE CIEUC A NIEUNCIEUC
+0x9FEB 0xC799 #HANGUL SYLLABLE CIEUC A RIEULKIYEOK
+0x9FEC 0xC79B #HANGUL SYLLABLE CIEUC A RIEULPIEUP
+0x9FED 0xC79C #HANGUL SYLLABLE CIEUC A RIEULSIOS
+0x9FEE 0xC79D #HANGUL SYLLABLE CIEUC A RIEULTHIEUTH
+0x9FEF 0xC79E #HANGUL SYLLABLE CIEUC A RIEULPHIEUPH
+0x9FF0 0xC79F #HANGUL SYLLABLE CIEUC A RIEULHIEUH
+0x9FF1 0xC7A2 #HANGUL SYLLABLE CIEUC A PIEUPSIOS
+0x9FF2 0xC7A7 #HANGUL SYLLABLE CIEUC A CHIEUCH
+0x9FF3 0xC7A8 #HANGUL SYLLABLE CIEUC A KHIEUKH
+0x9FF4 0xC7A9 #HANGUL SYLLABLE CIEUC A THIEUTH
+0x9FF5 0xC7AA #HANGUL SYLLABLE CIEUC A PHIEUPH
+0x9FF6 0xC7AB #HANGUL SYLLABLE CIEUC A HIEUH
+0x9FF7 0xC7AE #HANGUL SYLLABLE CIEUC AE SSANGKIYEOK
+0x9FF8 0xC7AF #HANGUL SYLLABLE CIEUC AE KIYEOKSIOS
+0x9FF9 0xC7B1 #HANGUL SYLLABLE CIEUC AE NIEUNCIEUC
+0x9FFA 0xC7B2 #HANGUL SYLLABLE CIEUC AE NIEUNHIEUH
+0x9FFB 0xC7B3 #HANGUL SYLLABLE CIEUC AE TIKEUT
+0x9FFC 0xC7B5 #HANGUL SYLLABLE CIEUC AE RIEULKIYEOK
+0x9FFD 0xC7B6 #HANGUL SYLLABLE CIEUC AE RIEULMIEUM
+0x9FFE 0xC7B7 #HANGUL SYLLABLE CIEUC AE RIEULPIEUP
+0xA041 0xC7B8 #HANGUL SYLLABLE CIEUC AE RIEULSIOS
+0xA042 0xC7B9 #HANGUL SYLLABLE CIEUC AE RIEULTHIEUTH
+0xA043 0xC7BA #HANGUL SYLLABLE CIEUC AE RIEULPHIEUPH
+0xA044 0xC7BB #HANGUL SYLLABLE CIEUC AE RIEULHIEUH
+0xA045 0xC7BE #HANGUL SYLLABLE CIEUC AE PIEUPSIOS
+0xA046 0xC7C2 #HANGUL SYLLABLE CIEUC AE CIEUC
+0xA047 0xC7C3 #HANGUL SYLLABLE CIEUC AE CHIEUCH
+0xA048 0xC7C4 #HANGUL SYLLABLE CIEUC AE KHIEUKH
+0xA049 0xC7C5 #HANGUL SYLLABLE CIEUC AE THIEUTH
+0xA04A 0xC7C6 #HANGUL SYLLABLE CIEUC AE PHIEUPH
+0xA04B 0xC7C7 #HANGUL SYLLABLE CIEUC AE HIEUH
+0xA04C 0xC7CA #HANGUL SYLLABLE CIEUC YA SSANGKIYEOK
+0xA04D 0xC7CB #HANGUL SYLLABLE CIEUC YA KIYEOKSIOS
+0xA04E 0xC7CD #HANGUL SYLLABLE CIEUC YA NIEUNCIEUC
+0xA04F 0xC7CF #HANGUL SYLLABLE CIEUC YA TIKEUT
+0xA050 0xC7D1 #HANGUL SYLLABLE CIEUC YA RIEULKIYEOK
+0xA051 0xC7D2 #HANGUL SYLLABLE CIEUC YA RIEULMIEUM
+0xA052 0xC7D3 #HANGUL SYLLABLE CIEUC YA RIEULPIEUP
+0xA053 0xC7D4 #HANGUL SYLLABLE CIEUC YA RIEULSIOS
+0xA054 0xC7D5 #HANGUL SYLLABLE CIEUC YA RIEULTHIEUTH
+0xA055 0xC7D6 #HANGUL SYLLABLE CIEUC YA RIEULPHIEUPH
+0xA056 0xC7D7 #HANGUL SYLLABLE CIEUC YA RIEULHIEUH
+0xA057 0xC7D9 #HANGUL SYLLABLE CIEUC YA PIEUP
+0xA058 0xC7DA #HANGUL SYLLABLE CIEUC YA PIEUPSIOS
+0xA059 0xC7DB #HANGUL SYLLABLE CIEUC YA SIOS
+0xA05A 0xC7DC #HANGUL SYLLABLE CIEUC YA SSANGSIOS
+0xA061 0xC7DE #HANGUL SYLLABLE CIEUC YA CIEUC
+0xA062 0xC7DF #HANGUL SYLLABLE CIEUC YA CHIEUCH
+0xA063 0xC7E0 #HANGUL SYLLABLE CIEUC YA KHIEUKH
+0xA064 0xC7E1 #HANGUL SYLLABLE CIEUC YA THIEUTH
+0xA065 0xC7E2 #HANGUL SYLLABLE CIEUC YA PHIEUPH
+0xA066 0xC7E3 #HANGUL SYLLABLE CIEUC YA HIEUH
+0xA067 0xC7E5 #HANGUL SYLLABLE CIEUC YAE KIYEOK
+0xA068 0xC7E6 #HANGUL SYLLABLE CIEUC YAE SSANGKIYEOK
+0xA069 0xC7E7 #HANGUL SYLLABLE CIEUC YAE KIYEOKSIOS
+0xA06A 0xC7E9 #HANGUL SYLLABLE CIEUC YAE NIEUNCIEUC
+0xA06B 0xC7EA #HANGUL SYLLABLE CIEUC YAE NIEUNHIEUH
+0xA06C 0xC7EB #HANGUL SYLLABLE CIEUC YAE TIKEUT
+0xA06D 0xC7ED #HANGUL SYLLABLE CIEUC YAE RIEULKIYEOK
+0xA06E 0xC7EE #HANGUL SYLLABLE CIEUC YAE RIEULMIEUM
+0xA06F 0xC7EF #HANGUL SYLLABLE CIEUC YAE RIEULPIEUP
+0xA070 0xC7F0 #HANGUL SYLLABLE CIEUC YAE RIEULSIOS
+0xA071 0xC7F1 #HANGUL SYLLABLE CIEUC YAE RIEULTHIEUTH
+0xA072 0xC7F2 #HANGUL SYLLABLE CIEUC YAE RIEULPHIEUPH
+0xA073 0xC7F3 #HANGUL SYLLABLE CIEUC YAE RIEULHIEUH
+0xA074 0xC7F4 #HANGUL SYLLABLE CIEUC YAE MIEUM
+0xA075 0xC7F5 #HANGUL SYLLABLE CIEUC YAE PIEUP
+0xA076 0xC7F6 #HANGUL SYLLABLE CIEUC YAE PIEUPSIOS
+0xA077 0xC7F7 #HANGUL SYLLABLE CIEUC YAE SIOS
+0xA078 0xC7F8 #HANGUL SYLLABLE CIEUC YAE SSANGSIOS
+0xA079 0xC7F9 #HANGUL SYLLABLE CIEUC YAE IEUNG
+0xA07A 0xC7FA #HANGUL SYLLABLE CIEUC YAE CIEUC
+0xA081 0xC7FB #HANGUL SYLLABLE CIEUC YAE CHIEUCH
+0xA082 0xC7FC #HANGUL SYLLABLE CIEUC YAE KHIEUKH
+0xA083 0xC7FD #HANGUL SYLLABLE CIEUC YAE THIEUTH
+0xA084 0xC7FE #HANGUL SYLLABLE CIEUC YAE PHIEUPH
+0xA085 0xC7FF #HANGUL SYLLABLE CIEUC YAE HIEUH
+0xA086 0xC802 #HANGUL SYLLABLE CIEUC EO SSANGKIYEOK
+0xA087 0xC803 #HANGUL SYLLABLE CIEUC EO KIYEOKSIOS
+0xA088 0xC805 #HANGUL SYLLABLE CIEUC EO NIEUNCIEUC
+0xA089 0xC806 #HANGUL SYLLABLE CIEUC EO NIEUNHIEUH
+0xA08A 0xC807 #HANGUL SYLLABLE CIEUC EO TIKEUT
+0xA08B 0xC809 #HANGUL SYLLABLE CIEUC EO RIEULKIYEOK
+0xA08C 0xC80B #HANGUL SYLLABLE CIEUC EO RIEULPIEUP
+0xA08D 0xC80C #HANGUL SYLLABLE CIEUC EO RIEULSIOS
+0xA08E 0xC80D #HANGUL SYLLABLE CIEUC EO RIEULTHIEUTH
+0xA08F 0xC80E #HANGUL SYLLABLE CIEUC EO RIEULPHIEUPH
+0xA090 0xC80F #HANGUL SYLLABLE CIEUC EO RIEULHIEUH
+0xA091 0xC812 #HANGUL SYLLABLE CIEUC EO PIEUPSIOS
+0xA092 0xC814 #HANGUL SYLLABLE CIEUC EO SSANGSIOS
+0xA093 0xC817 #HANGUL SYLLABLE CIEUC EO CHIEUCH
+0xA094 0xC818 #HANGUL SYLLABLE CIEUC EO KHIEUKH
+0xA095 0xC819 #HANGUL SYLLABLE CIEUC EO THIEUTH
+0xA096 0xC81A #HANGUL SYLLABLE CIEUC EO PHIEUPH
+0xA097 0xC81B #HANGUL SYLLABLE CIEUC EO HIEUH
+0xA098 0xC81E #HANGUL SYLLABLE CIEUC E SSANGKIYEOK
+0xA099 0xC81F #HANGUL SYLLABLE CIEUC E KIYEOKSIOS
+0xA09A 0xC821 #HANGUL SYLLABLE CIEUC E NIEUNCIEUC
+0xA09B 0xC822 #HANGUL SYLLABLE CIEUC E NIEUNHIEUH
+0xA09C 0xC823 #HANGUL SYLLABLE CIEUC E TIKEUT
+0xA09D 0xC825 #HANGUL SYLLABLE CIEUC E RIEULKIYEOK
+0xA09E 0xC826 #HANGUL SYLLABLE CIEUC E RIEULMIEUM
+0xA09F 0xC827 #HANGUL SYLLABLE CIEUC E RIEULPIEUP
+0xA0A0 0xC828 #HANGUL SYLLABLE CIEUC E RIEULSIOS
+0xA0A1 0xC829 #HANGUL SYLLABLE CIEUC E RIEULTHIEUTH
+0xA0A2 0xC82A #HANGUL SYLLABLE CIEUC E RIEULPHIEUPH
+0xA0A3 0xC82B #HANGUL SYLLABLE CIEUC E RIEULHIEUH
+0xA0A4 0xC82E #HANGUL SYLLABLE CIEUC E PIEUPSIOS
+0xA0A5 0xC830 #HANGUL SYLLABLE CIEUC E SSANGSIOS
+0xA0A6 0xC832 #HANGUL SYLLABLE CIEUC E CIEUC
+0xA0A7 0xC833 #HANGUL SYLLABLE CIEUC E CHIEUCH
+0xA0A8 0xC834 #HANGUL SYLLABLE CIEUC E KHIEUKH
+0xA0A9 0xC835 #HANGUL SYLLABLE CIEUC E THIEUTH
+0xA0AA 0xC836 #HANGUL SYLLABLE CIEUC E PHIEUPH
+0xA0AB 0xC837 #HANGUL SYLLABLE CIEUC E HIEUH
+0xA0AC 0xC839 #HANGUL SYLLABLE CIEUC YEO KIYEOK
+0xA0AD 0xC83A #HANGUL SYLLABLE CIEUC YEO SSANGKIYEOK
+0xA0AE 0xC83B #HANGUL SYLLABLE CIEUC YEO KIYEOKSIOS
+0xA0AF 0xC83D #HANGUL SYLLABLE CIEUC YEO NIEUNCIEUC
+0xA0B0 0xC83E #HANGUL SYLLABLE CIEUC YEO NIEUNHIEUH
+0xA0B1 0xC83F #HANGUL SYLLABLE CIEUC YEO TIKEUT
+0xA0B2 0xC841 #HANGUL SYLLABLE CIEUC YEO RIEULKIYEOK
+0xA0B3 0xC842 #HANGUL SYLLABLE CIEUC YEO RIEULMIEUM
+0xA0B4 0xC843 #HANGUL SYLLABLE CIEUC YEO RIEULPIEUP
+0xA0B5 0xC844 #HANGUL SYLLABLE CIEUC YEO RIEULSIOS
+0xA0B6 0xC845 #HANGUL SYLLABLE CIEUC YEO RIEULTHIEUTH
+0xA0B7 0xC846 #HANGUL SYLLABLE CIEUC YEO RIEULPHIEUPH
+0xA0B8 0xC847 #HANGUL SYLLABLE CIEUC YEO RIEULHIEUH
+0xA0B9 0xC84A #HANGUL SYLLABLE CIEUC YEO PIEUPSIOS
+0xA0BA 0xC84B #HANGUL SYLLABLE CIEUC YEO SIOS
+0xA0BB 0xC84E #HANGUL SYLLABLE CIEUC YEO CIEUC
+0xA0BC 0xC84F #HANGUL SYLLABLE CIEUC YEO CHIEUCH
+0xA0BD 0xC850 #HANGUL SYLLABLE CIEUC YEO KHIEUKH
+0xA0BE 0xC851 #HANGUL SYLLABLE CIEUC YEO THIEUTH
+0xA0BF 0xC852 #HANGUL SYLLABLE CIEUC YEO PHIEUPH
+0xA0C0 0xC853 #HANGUL SYLLABLE CIEUC YEO HIEUH
+0xA0C1 0xC855 #HANGUL SYLLABLE CIEUC YE KIYEOK
+0xA0C2 0xC856 #HANGUL SYLLABLE CIEUC YE SSANGKIYEOK
+0xA0C3 0xC857 #HANGUL SYLLABLE CIEUC YE KIYEOKSIOS
+0xA0C4 0xC858 #HANGUL SYLLABLE CIEUC YE NIEUN
+0xA0C5 0xC859 #HANGUL SYLLABLE CIEUC YE NIEUNCIEUC
+0xA0C6 0xC85A #HANGUL SYLLABLE CIEUC YE NIEUNHIEUH
+0xA0C7 0xC85B #HANGUL SYLLABLE CIEUC YE TIKEUT
+0xA0C8 0xC85C #HANGUL SYLLABLE CIEUC YE RIEUL
+0xA0C9 0xC85D #HANGUL SYLLABLE CIEUC YE RIEULKIYEOK
+0xA0CA 0xC85E #HANGUL SYLLABLE CIEUC YE RIEULMIEUM
+0xA0CB 0xC85F #HANGUL SYLLABLE CIEUC YE RIEULPIEUP
+0xA0CC 0xC860 #HANGUL SYLLABLE CIEUC YE RIEULSIOS
+0xA0CD 0xC861 #HANGUL SYLLABLE CIEUC YE RIEULTHIEUTH
+0xA0CE 0xC862 #HANGUL SYLLABLE CIEUC YE RIEULPHIEUPH
+0xA0CF 0xC863 #HANGUL SYLLABLE CIEUC YE RIEULHIEUH
+0xA0D0 0xC864 #HANGUL SYLLABLE CIEUC YE MIEUM
+0xA0D1 0xC865 #HANGUL SYLLABLE CIEUC YE PIEUP
+0xA0D2 0xC866 #HANGUL SYLLABLE CIEUC YE PIEUPSIOS
+0xA0D3 0xC867 #HANGUL SYLLABLE CIEUC YE SIOS
+0xA0D4 0xC868 #HANGUL SYLLABLE CIEUC YE SSANGSIOS
+0xA0D5 0xC869 #HANGUL SYLLABLE CIEUC YE IEUNG
+0xA0D6 0xC86A #HANGUL SYLLABLE CIEUC YE CIEUC
+0xA0D7 0xC86B #HANGUL SYLLABLE CIEUC YE CHIEUCH
+0xA0D8 0xC86C #HANGUL SYLLABLE CIEUC YE KHIEUKH
+0xA0D9 0xC86D #HANGUL SYLLABLE CIEUC YE THIEUTH
+0xA0DA 0xC86E #HANGUL SYLLABLE CIEUC YE PHIEUPH
+0xA0DB 0xC86F #HANGUL SYLLABLE CIEUC YE HIEUH
+0xA0DC 0xC872 #HANGUL SYLLABLE CIEUC O SSANGKIYEOK
+0xA0DD 0xC873 #HANGUL SYLLABLE CIEUC O KIYEOKSIOS
+0xA0DE 0xC875 #HANGUL SYLLABLE CIEUC O NIEUNCIEUC
+0xA0DF 0xC876 #HANGUL SYLLABLE CIEUC O NIEUNHIEUH
+0xA0E0 0xC877 #HANGUL SYLLABLE CIEUC O TIKEUT
+0xA0E1 0xC879 #HANGUL SYLLABLE CIEUC O RIEULKIYEOK
+0xA0E2 0xC87B #HANGUL SYLLABLE CIEUC O RIEULPIEUP
+0xA0E3 0xC87C #HANGUL SYLLABLE CIEUC O RIEULSIOS
+0xA0E4 0xC87D #HANGUL SYLLABLE CIEUC O RIEULTHIEUTH
+0xA0E5 0xC87E #HANGUL SYLLABLE CIEUC O RIEULPHIEUPH
+0xA0E6 0xC87F #HANGUL SYLLABLE CIEUC O RIEULHIEUH
+0xA0E7 0xC882 #HANGUL SYLLABLE CIEUC O PIEUPSIOS
+0xA0E8 0xC884 #HANGUL SYLLABLE CIEUC O SSANGSIOS
+0xA0E9 0xC888 #HANGUL SYLLABLE CIEUC O KHIEUKH
+0xA0EA 0xC889 #HANGUL SYLLABLE CIEUC O THIEUTH
+0xA0EB 0xC88A #HANGUL SYLLABLE CIEUC O PHIEUPH
+0xA0EC 0xC88E #HANGUL SYLLABLE CIEUC WA SSANGKIYEOK
+0xA0ED 0xC88F #HANGUL SYLLABLE CIEUC WA KIYEOKSIOS
+0xA0EE 0xC890 #HANGUL SYLLABLE CIEUC WA NIEUN
+0xA0EF 0xC891 #HANGUL SYLLABLE CIEUC WA NIEUNCIEUC
+0xA0F0 0xC892 #HANGUL SYLLABLE CIEUC WA NIEUNHIEUH
+0xA0F1 0xC893 #HANGUL SYLLABLE CIEUC WA TIKEUT
+0xA0F2 0xC895 #HANGUL SYLLABLE CIEUC WA RIEULKIYEOK
+0xA0F3 0xC896 #HANGUL SYLLABLE CIEUC WA RIEULMIEUM
+0xA0F4 0xC897 #HANGUL SYLLABLE CIEUC WA RIEULPIEUP
+0xA0F5 0xC898 #HANGUL SYLLABLE CIEUC WA RIEULSIOS
+0xA0F6 0xC899 #HANGUL SYLLABLE CIEUC WA RIEULTHIEUTH
+0xA0F7 0xC89A #HANGUL SYLLABLE CIEUC WA RIEULPHIEUPH
+0xA0F8 0xC89B #HANGUL SYLLABLE CIEUC WA RIEULHIEUH
+0xA0F9 0xC89C #HANGUL SYLLABLE CIEUC WA MIEUM
+0xA0FA 0xC89E #HANGUL SYLLABLE CIEUC WA PIEUPSIOS
+0xA0FB 0xC8A0 #HANGUL SYLLABLE CIEUC WA SSANGSIOS
+0xA0FC 0xC8A2 #HANGUL SYLLABLE CIEUC WA CIEUC
+0xA0FD 0xC8A3 #HANGUL SYLLABLE CIEUC WA CHIEUCH
+0xA0FE 0xC8A4 #HANGUL SYLLABLE CIEUC WA KHIEUKH
+0xA141 0xC8A5 #HANGUL SYLLABLE CIEUC WA THIEUTH
+0xA142 0xC8A6 #HANGUL SYLLABLE CIEUC WA PHIEUPH
+0xA143 0xC8A7 #HANGUL SYLLABLE CIEUC WA HIEUH
+0xA144 0xC8A9 #HANGUL SYLLABLE CIEUC WAE KIYEOK
+0xA145 0xC8AA #HANGUL SYLLABLE CIEUC WAE SSANGKIYEOK
+0xA146 0xC8AB #HANGUL SYLLABLE CIEUC WAE KIYEOKSIOS
+0xA147 0xC8AC #HANGUL SYLLABLE CIEUC WAE NIEUN
+0xA148 0xC8AD #HANGUL SYLLABLE CIEUC WAE NIEUNCIEUC
+0xA149 0xC8AE #HANGUL SYLLABLE CIEUC WAE NIEUNHIEUH
+0xA14A 0xC8AF #HANGUL SYLLABLE CIEUC WAE TIKEUT
+0xA14B 0xC8B0 #HANGUL SYLLABLE CIEUC WAE RIEUL
+0xA14C 0xC8B1 #HANGUL SYLLABLE CIEUC WAE RIEULKIYEOK
+0xA14D 0xC8B2 #HANGUL SYLLABLE CIEUC WAE RIEULMIEUM
+0xA14E 0xC8B3 #HANGUL SYLLABLE CIEUC WAE RIEULPIEUP
+0xA14F 0xC8B4 #HANGUL SYLLABLE CIEUC WAE RIEULSIOS
+0xA150 0xC8B5 #HANGUL SYLLABLE CIEUC WAE RIEULTHIEUTH
+0xA151 0xC8B6 #HANGUL SYLLABLE CIEUC WAE RIEULPHIEUPH
+0xA152 0xC8B7 #HANGUL SYLLABLE CIEUC WAE RIEULHIEUH
+0xA153 0xC8B8 #HANGUL SYLLABLE CIEUC WAE MIEUM
+0xA154 0xC8B9 #HANGUL SYLLABLE CIEUC WAE PIEUP
+0xA155 0xC8BA #HANGUL SYLLABLE CIEUC WAE PIEUPSIOS
+0xA156 0xC8BB #HANGUL SYLLABLE CIEUC WAE SIOS
+0xA157 0xC8BE #HANGUL SYLLABLE CIEUC WAE CIEUC
+0xA158 0xC8BF #HANGUL SYLLABLE CIEUC WAE CHIEUCH
+0xA159 0xC8C0 #HANGUL SYLLABLE CIEUC WAE KHIEUKH
+0xA15A 0xC8C1 #HANGUL SYLLABLE CIEUC WAE THIEUTH
+0xA161 0xC8C2 #HANGUL SYLLABLE CIEUC WAE PHIEUPH
+0xA162 0xC8C3 #HANGUL SYLLABLE CIEUC WAE HIEUH
+0xA163 0xC8C5 #HANGUL SYLLABLE CIEUC OE KIYEOK
+0xA164 0xC8C6 #HANGUL SYLLABLE CIEUC OE SSANGKIYEOK
+0xA165 0xC8C7 #HANGUL SYLLABLE CIEUC OE KIYEOKSIOS
+0xA166 0xC8C9 #HANGUL SYLLABLE CIEUC OE NIEUNCIEUC
+0xA167 0xC8CA #HANGUL SYLLABLE CIEUC OE NIEUNHIEUH
+0xA168 0xC8CB #HANGUL SYLLABLE CIEUC OE TIKEUT
+0xA169 0xC8CD #HANGUL SYLLABLE CIEUC OE RIEULKIYEOK
+0xA16A 0xC8CE #HANGUL SYLLABLE CIEUC OE RIEULMIEUM
+0xA16B 0xC8CF #HANGUL SYLLABLE CIEUC OE RIEULPIEUP
+0xA16C 0xC8D0 #HANGUL SYLLABLE CIEUC OE RIEULSIOS
+0xA16D 0xC8D1 #HANGUL SYLLABLE CIEUC OE RIEULTHIEUTH
+0xA16E 0xC8D2 #HANGUL SYLLABLE CIEUC OE RIEULPHIEUPH
+0xA16F 0xC8D3 #HANGUL SYLLABLE CIEUC OE RIEULHIEUH
+0xA170 0xC8D6 #HANGUL SYLLABLE CIEUC OE PIEUPSIOS
+0xA171 0xC8D8 #HANGUL SYLLABLE CIEUC OE SSANGSIOS
+0xA172 0xC8DA #HANGUL SYLLABLE CIEUC OE CIEUC
+0xA173 0xC8DB #HANGUL SYLLABLE CIEUC OE CHIEUCH
+0xA174 0xC8DC #HANGUL SYLLABLE CIEUC OE KHIEUKH
+0xA175 0xC8DD #HANGUL SYLLABLE CIEUC OE THIEUTH
+0xA176 0xC8DE #HANGUL SYLLABLE CIEUC OE PHIEUPH
+0xA177 0xC8DF #HANGUL SYLLABLE CIEUC OE HIEUH
+0xA178 0xC8E2 #HANGUL SYLLABLE CIEUC YO SSANGKIYEOK
+0xA179 0xC8E3 #HANGUL SYLLABLE CIEUC YO KIYEOKSIOS
+0xA17A 0xC8E5 #HANGUL SYLLABLE CIEUC YO NIEUNCIEUC
+0xA181 0xC8E6 #HANGUL SYLLABLE CIEUC YO NIEUNHIEUH
+0xA182 0xC8E7 #HANGUL SYLLABLE CIEUC YO TIKEUT
+0xA183 0xC8E8 #HANGUL SYLLABLE CIEUC YO RIEUL
+0xA184 0xC8E9 #HANGUL SYLLABLE CIEUC YO RIEULKIYEOK
+0xA185 0xC8EA #HANGUL SYLLABLE CIEUC YO RIEULMIEUM
+0xA186 0xC8EB #HANGUL SYLLABLE CIEUC YO RIEULPIEUP
+0xA187 0xC8EC #HANGUL SYLLABLE CIEUC YO RIEULSIOS
+0xA188 0xC8ED #HANGUL SYLLABLE CIEUC YO RIEULTHIEUTH
+0xA189 0xC8EE #HANGUL SYLLABLE CIEUC YO RIEULPHIEUPH
+0xA18A 0xC8EF #HANGUL SYLLABLE CIEUC YO RIEULHIEUH
+0xA18B 0xC8F0 #HANGUL SYLLABLE CIEUC YO MIEUM
+0xA18C 0xC8F1 #HANGUL SYLLABLE CIEUC YO PIEUP
+0xA18D 0xC8F2 #HANGUL SYLLABLE CIEUC YO PIEUPSIOS
+0xA18E 0xC8F3 #HANGUL SYLLABLE CIEUC YO SIOS
+0xA18F 0xC8F4 #HANGUL SYLLABLE CIEUC YO SSANGSIOS
+0xA190 0xC8F6 #HANGUL SYLLABLE CIEUC YO CIEUC
+0xA191 0xC8F7 #HANGUL SYLLABLE CIEUC YO CHIEUCH
+0xA192 0xC8F8 #HANGUL SYLLABLE CIEUC YO KHIEUKH
+0xA193 0xC8F9 #HANGUL SYLLABLE CIEUC YO THIEUTH
+0xA194 0xC8FA #HANGUL SYLLABLE CIEUC YO PHIEUPH
+0xA195 0xC8FB #HANGUL SYLLABLE CIEUC YO HIEUH
+0xA196 0xC8FE #HANGUL SYLLABLE CIEUC U SSANGKIYEOK
+0xA197 0xC8FF #HANGUL SYLLABLE CIEUC U KIYEOKSIOS
+0xA198 0xC901 #HANGUL SYLLABLE CIEUC U NIEUNCIEUC
+0xA199 0xC902 #HANGUL SYLLABLE CIEUC U NIEUNHIEUH
+0xA19A 0xC903 #HANGUL SYLLABLE CIEUC U TIKEUT
+0xA19B 0xC907 #HANGUL SYLLABLE CIEUC U RIEULPIEUP
+0xA19C 0xC908 #HANGUL SYLLABLE CIEUC U RIEULSIOS
+0xA19D 0xC909 #HANGUL SYLLABLE CIEUC U RIEULTHIEUTH
+0xA19E 0xC90A #HANGUL SYLLABLE CIEUC U RIEULPHIEUPH
+0xA19F 0xC90B #HANGUL SYLLABLE CIEUC U RIEULHIEUH
+0xA1A0 0xC90E #HANGUL SYLLABLE CIEUC U PIEUPSIOS
+0xA1A1 0x3000 #IDEOGRAPHIC SPACE
+0xA1A2 0x3001 #IDEOGRAPHIC COMMA
+0xA1A3 0x3002 #IDEOGRAPHIC FULL STOP
+0xA1A4 0x00B7 #MIDDLE DOT
+0xA1A5 0x2025 #TWO DOT LEADER
+0xA1A6 0x2026 #HORIZONTAL ELLIPSIS
+0xA1A7 0x00A8 #DIAERESIS
+0xA1A8 0x3003 #DITTO MARK
+0xA1A9 0x00AD #SOFT HYPHEN
+0xA1AA 0x2015 #HORIZONTAL BAR
+0xA1AB 0x2225 #PARALLEL TO
+0xA1AC 0xFF3C #FULLWIDTH REVERSE SOLIDUS
+0xA1AD 0x223C #TILDE OPERATOR
+0xA1AE 0x2018 #LEFT SINGLE QUOTATION MARK
+0xA1AF 0x2019 #RIGHT SINGLE QUOTATION MARK
+0xA1B0 0x201C #LEFT DOUBLE QUOTATION MARK
+0xA1B1 0x201D #RIGHT DOUBLE QUOTATION MARK
+0xA1B2 0x3014 #LEFT TORTOISE SHELL BRACKET
+0xA1B3 0x3015 #RIGHT TORTOISE SHELL BRACKET
+0xA1B4 0x3008 #LEFT ANGLE BRACKET
+0xA1B5 0x3009 #RIGHT ANGLE BRACKET
+0xA1B6 0x300A #LEFT DOUBLE ANGLE BRACKET
+0xA1B7 0x300B #RIGHT DOUBLE ANGLE BRACKET
+0xA1B8 0x300C #LEFT CORNER BRACKET
+0xA1B9 0x300D #RIGHT CORNER BRACKET
+0xA1BA 0x300E #LEFT WHITE CORNER BRACKET
+0xA1BB 0x300F #RIGHT WHITE CORNER BRACKET
+0xA1BC 0x3010 #LEFT BLACK LENTICULAR BRACKET
+0xA1BD 0x3011 #RIGHT BLACK LENTICULAR BRACKET
+0xA1BE 0x00B1 #PLUS-MINUS SIGN
+0xA1BF 0x00D7 #MULTIPLICATION SIGN
+0xA1C0 0x00F7 #DIVISION SIGN
+0xA1C1 0x2260 #NOT EQUAL TO
+0xA1C2 0x2264 #LESS-THAN OR EQUAL TO
+0xA1C3 0x2265 #GREATER-THAN OR EQUAL TO
+0xA1C4 0x221E #INFINITY
+0xA1C5 0x2234 #THEREFORE
+0xA1C6 0x00B0 #DEGREE SIGN
+0xA1C7 0x2032 #PRIME
+0xA1C8 0x2033 #DOUBLE PRIME
+0xA1C9 0x2103 #DEGREE CELSIUS
+0xA1CA 0x212B #ANGSTROM SIGN
+0xA1CB 0xFFE0 #FULLWIDTH CENT SIGN
+0xA1CC 0xFFE1 #FULLWIDTH POUND SIGN
+0xA1CD 0xFFE5 #FULLWIDTH YEN SIGN
+0xA1CE 0x2642 #MALE SIGN
+0xA1CF 0x2640 #FEMALE SIGN
+0xA1D0 0x2220 #ANGLE
+0xA1D1 0x22A5 #UP TACK
+0xA1D2 0x2312 #ARC
+0xA1D3 0x2202 #PARTIAL DIFFERENTIAL
+0xA1D4 0x2207 #NABLA
+0xA1D5 0x2261 #IDENTICAL TO
+0xA1D6 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA1D7 0x00A7 #SECTION SIGN
+0xA1D8 0x203B #REFERENCE MARK
+0xA1D9 0x2606 #WHITE STAR
+0xA1DA 0x2605 #BLACK STAR
+0xA1DB 0x25CB #WHITE CIRCLE
+0xA1DC 0x25CF #BLACK CIRCLE
+0xA1DD 0x25CE #BULLSEYE
+0xA1DE 0x25C7 #WHITE DIAMOND
+0xA1DF 0x25C6 #BLACK DIAMOND
+0xA1E0 0x25A1 #WHITE SQUARE
+0xA1E1 0x25A0 #BLACK SQUARE
+0xA1E2 0x25B3 #WHITE UP-POINTING TRIANGLE
+0xA1E3 0x25B2 #BLACK UP-POINTING TRIANGLE
+0xA1E4 0x25BD #WHITE DOWN-POINTING TRIANGLE
+0xA1E5 0x25BC #BLACK DOWN-POINTING TRIANGLE
+0xA1E6 0x2192 #RIGHTWARDS ARROW
+0xA1E7 0x2190 #LEFTWARDS ARROW
+0xA1E8 0x2191 #UPWARDS ARROW
+0xA1E9 0x2193 #DOWNWARDS ARROW
+0xA1EA 0x2194 #LEFT RIGHT ARROW
+0xA1EB 0x3013 #GETA MARK
+0xA1EC 0x226A #MUCH LESS-THAN
+0xA1ED 0x226B #MUCH GREATER-THAN
+0xA1EE 0x221A #SQUARE ROOT
+0xA1EF 0x223D #REVERSED TILDE
+0xA1F0 0x221D #PROPORTIONAL TO
+0xA1F1 0x2235 #BECAUSE
+0xA1F2 0x222B #INTEGRAL
+0xA1F3 0x222C #DOUBLE INTEGRAL
+0xA1F4 0x2208 #ELEMENT OF
+0xA1F5 0x220B #CONTAINS AS MEMBER
+0xA1F6 0x2286 #SUBSET OF OR EQUAL TO
+0xA1F7 0x2287 #SUPERSET OF OR EQUAL TO
+0xA1F8 0x2282 #SUBSET OF
+0xA1F9 0x2283 #SUPERSET OF
+0xA1FA 0x222A #UNION
+0xA1FB 0x2229 #INTERSECTION
+0xA1FC 0x2227 #LOGICAL AND
+0xA1FD 0x2228 #LOGICAL OR
+0xA1FE 0xFFE2 #FULLWIDTH NOT SIGN
+0xA241 0xC910 #HANGUL SYLLABLE CIEUC U SSANGSIOS
+0xA242 0xC912 #HANGUL SYLLABLE CIEUC U CIEUC
+0xA243 0xC913 #HANGUL SYLLABLE CIEUC U CHIEUCH
+0xA244 0xC914 #HANGUL SYLLABLE CIEUC U KHIEUKH
+0xA245 0xC915 #HANGUL SYLLABLE CIEUC U THIEUTH
+0xA246 0xC916 #HANGUL SYLLABLE CIEUC U PHIEUPH
+0xA247 0xC917 #HANGUL SYLLABLE CIEUC U HIEUH
+0xA248 0xC919 #HANGUL SYLLABLE CIEUC WEO KIYEOK
+0xA249 0xC91A #HANGUL SYLLABLE CIEUC WEO SSANGKIYEOK
+0xA24A 0xC91B #HANGUL SYLLABLE CIEUC WEO KIYEOKSIOS
+0xA24B 0xC91C #HANGUL SYLLABLE CIEUC WEO NIEUN
+0xA24C 0xC91D #HANGUL SYLLABLE CIEUC WEO NIEUNCIEUC
+0xA24D 0xC91E #HANGUL SYLLABLE CIEUC WEO NIEUNHIEUH
+0xA24E 0xC91F #HANGUL SYLLABLE CIEUC WEO TIKEUT
+0xA24F 0xC920 #HANGUL SYLLABLE CIEUC WEO RIEUL
+0xA250 0xC921 #HANGUL SYLLABLE CIEUC WEO RIEULKIYEOK
+0xA251 0xC922 #HANGUL SYLLABLE CIEUC WEO RIEULMIEUM
+0xA252 0xC923 #HANGUL SYLLABLE CIEUC WEO RIEULPIEUP
+0xA253 0xC924 #HANGUL SYLLABLE CIEUC WEO RIEULSIOS
+0xA254 0xC925 #HANGUL SYLLABLE CIEUC WEO RIEULTHIEUTH
+0xA255 0xC926 #HANGUL SYLLABLE CIEUC WEO RIEULPHIEUPH
+0xA256 0xC927 #HANGUL SYLLABLE CIEUC WEO RIEULHIEUH
+0xA257 0xC928 #HANGUL SYLLABLE CIEUC WEO MIEUM
+0xA258 0xC929 #HANGUL SYLLABLE CIEUC WEO PIEUP
+0xA259 0xC92A #HANGUL SYLLABLE CIEUC WEO PIEUPSIOS
+0xA25A 0xC92B #HANGUL SYLLABLE CIEUC WEO SIOS
+0xA261 0xC92D #HANGUL SYLLABLE CIEUC WEO IEUNG
+0xA262 0xC92E #HANGUL SYLLABLE CIEUC WEO CIEUC
+0xA263 0xC92F #HANGUL SYLLABLE CIEUC WEO CHIEUCH
+0xA264 0xC930 #HANGUL SYLLABLE CIEUC WEO KHIEUKH
+0xA265 0xC931 #HANGUL SYLLABLE CIEUC WEO THIEUTH
+0xA266 0xC932 #HANGUL SYLLABLE CIEUC WEO PHIEUPH
+0xA267 0xC933 #HANGUL SYLLABLE CIEUC WEO HIEUH
+0xA268 0xC935 #HANGUL SYLLABLE CIEUC WE KIYEOK
+0xA269 0xC936 #HANGUL SYLLABLE CIEUC WE SSANGKIYEOK
+0xA26A 0xC937 #HANGUL SYLLABLE CIEUC WE KIYEOKSIOS
+0xA26B 0xC938 #HANGUL SYLLABLE CIEUC WE NIEUN
+0xA26C 0xC939 #HANGUL SYLLABLE CIEUC WE NIEUNCIEUC
+0xA26D 0xC93A #HANGUL SYLLABLE CIEUC WE NIEUNHIEUH
+0xA26E 0xC93B #HANGUL SYLLABLE CIEUC WE TIKEUT
+0xA26F 0xC93C #HANGUL SYLLABLE CIEUC WE RIEUL
+0xA270 0xC93D #HANGUL SYLLABLE CIEUC WE RIEULKIYEOK
+0xA271 0xC93E #HANGUL SYLLABLE CIEUC WE RIEULMIEUM
+0xA272 0xC93F #HANGUL SYLLABLE CIEUC WE RIEULPIEUP
+0xA273 0xC940 #HANGUL SYLLABLE CIEUC WE RIEULSIOS
+0xA274 0xC941 #HANGUL SYLLABLE CIEUC WE RIEULTHIEUTH
+0xA275 0xC942 #HANGUL SYLLABLE CIEUC WE RIEULPHIEUPH
+0xA276 0xC943 #HANGUL SYLLABLE CIEUC WE RIEULHIEUH
+0xA277 0xC944 #HANGUL SYLLABLE CIEUC WE MIEUM
+0xA278 0xC945 #HANGUL SYLLABLE CIEUC WE PIEUP
+0xA279 0xC946 #HANGUL SYLLABLE CIEUC WE PIEUPSIOS
+0xA27A 0xC947 #HANGUL SYLLABLE CIEUC WE SIOS
+0xA281 0xC948 #HANGUL SYLLABLE CIEUC WE SSANGSIOS
+0xA282 0xC949 #HANGUL SYLLABLE CIEUC WE IEUNG
+0xA283 0xC94A #HANGUL SYLLABLE CIEUC WE CIEUC
+0xA284 0xC94B #HANGUL SYLLABLE CIEUC WE CHIEUCH
+0xA285 0xC94C #HANGUL SYLLABLE CIEUC WE KHIEUKH
+0xA286 0xC94D #HANGUL SYLLABLE CIEUC WE THIEUTH
+0xA287 0xC94E #HANGUL SYLLABLE CIEUC WE PHIEUPH
+0xA288 0xC94F #HANGUL SYLLABLE CIEUC WE HIEUH
+0xA289 0xC952 #HANGUL SYLLABLE CIEUC WI SSANGKIYEOK
+0xA28A 0xC953 #HANGUL SYLLABLE CIEUC WI KIYEOKSIOS
+0xA28B 0xC955 #HANGUL SYLLABLE CIEUC WI NIEUNCIEUC
+0xA28C 0xC956 #HANGUL SYLLABLE CIEUC WI NIEUNHIEUH
+0xA28D 0xC957 #HANGUL SYLLABLE CIEUC WI TIKEUT
+0xA28E 0xC959 #HANGUL SYLLABLE CIEUC WI RIEULKIYEOK
+0xA28F 0xC95A #HANGUL SYLLABLE CIEUC WI RIEULMIEUM
+0xA290 0xC95B #HANGUL SYLLABLE CIEUC WI RIEULPIEUP
+0xA291 0xC95C #HANGUL SYLLABLE CIEUC WI RIEULSIOS
+0xA292 0xC95D #HANGUL SYLLABLE CIEUC WI RIEULTHIEUTH
+0xA293 0xC95E #HANGUL SYLLABLE CIEUC WI RIEULPHIEUPH
+0xA294 0xC95F #HANGUL SYLLABLE CIEUC WI RIEULHIEUH
+0xA295 0xC962 #HANGUL SYLLABLE CIEUC WI PIEUPSIOS
+0xA296 0xC964 #HANGUL SYLLABLE CIEUC WI SSANGSIOS
+0xA297 0xC965 #HANGUL SYLLABLE CIEUC WI IEUNG
+0xA298 0xC966 #HANGUL SYLLABLE CIEUC WI CIEUC
+0xA299 0xC967 #HANGUL SYLLABLE CIEUC WI CHIEUCH
+0xA29A 0xC968 #HANGUL SYLLABLE CIEUC WI KHIEUKH
+0xA29B 0xC969 #HANGUL SYLLABLE CIEUC WI THIEUTH
+0xA29C 0xC96A #HANGUL SYLLABLE CIEUC WI PHIEUPH
+0xA29D 0xC96B #HANGUL SYLLABLE CIEUC WI HIEUH
+0xA29E 0xC96D #HANGUL SYLLABLE CIEUC YU KIYEOK
+0xA29F 0xC96E #HANGUL SYLLABLE CIEUC YU SSANGKIYEOK
+0xA2A0 0xC96F #HANGUL SYLLABLE CIEUC YU KIYEOKSIOS
+0xA2A1 0x21D2 #RIGHTWARDS DOUBLE ARROW
+0xA2A2 0x21D4 #LEFT RIGHT DOUBLE ARROW
+0xA2A3 0x2200 #FOR ALL
+0xA2A4 0x2203 #THERE EXISTS
+0xA2A5 0x00B4 #ACUTE ACCENT
+0xA2A6 0xFF5E #FULLWIDTH TILDE
+0xA2A7 0x02C7 #CARON
+0xA2A8 0x02D8 #BREVE
+0xA2A9 0x02DD #DOUBLE ACUTE ACCENT
+0xA2AA 0x02DA #RING ABOVE
+0xA2AB 0x02D9 #DOT ABOVE
+0xA2AC 0x00B8 #CEDILLA
+0xA2AD 0x02DB #OGONEK
+0xA2AE 0x00A1 #INVERTED EXCLAMATION MARK
+0xA2AF 0x00BF #INVERTED QUESTION MARK
+0xA2B0 0x02D0 #MODIFIER LETTER TRIANGULAR COLON
+0xA2B1 0x222E #CONTOUR INTEGRAL
+0xA2B2 0x2211 #N-ARY SUMMATION
+0xA2B3 0x220F #N-ARY PRODUCT
+0xA2B4 0x00A4 #CURRENCY SIGN
+0xA2B5 0x2109 #DEGREE FAHRENHEIT
+0xA2B6 0x2030 #PER MILLE SIGN
+0xA2B7 0x25C1 #WHITE LEFT-POINTING TRIANGLE
+0xA2B8 0x25C0 #BLACK LEFT-POINTING TRIANGLE
+0xA2B9 0x25B7 #WHITE RIGHT-POINTING TRIANGLE
+0xA2BA 0x25B6 #BLACK RIGHT-POINTING TRIANGLE
+0xA2BB 0x2664 #WHITE SPADE SUIT
+0xA2BC 0x2660 #BLACK SPADE SUIT
+0xA2BD 0x2661 #WHITE HEART SUIT
+0xA2BE 0x2665 #BLACK HEART SUIT
+0xA2BF 0x2667 #WHITE CLUB SUIT
+0xA2C0 0x2663 #BLACK CLUB SUIT
+0xA2C1 0x2299 #CIRCLED DOT OPERATOR
+0xA2C2 0x25C8 #WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+0xA2C3 0x25A3 #WHITE SQUARE CONTAINING BLACK SMALL SQUARE
+0xA2C4 0x25D0 #CIRCLE WITH LEFT HALF BLACK
+0xA2C5 0x25D1 #CIRCLE WITH RIGHT HALF BLACK
+0xA2C6 0x2592 #MEDIUM SHADE
+0xA2C7 0x25A4 #SQUARE WITH HORIZONTAL FILL
+0xA2C8 0x25A5 #SQUARE WITH VERTICAL FILL
+0xA2C9 0x25A8 #SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL
+0xA2CA 0x25A7 #SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL
+0xA2CB 0x25A6 #SQUARE WITH ORTHOGONAL CROSSHATCH FILL
+0xA2CC 0x25A9 #SQUARE WITH DIAGONAL CROSSHATCH FILL
+0xA2CD 0x2668 #HOT SPRINGS
+0xA2CE 0x260F #WHITE TELEPHONE
+0xA2CF 0x260E #BLACK TELEPHONE
+0xA2D0 0x261C #WHITE LEFT POINTING INDEX
+0xA2D1 0x261E #WHITE RIGHT POINTING INDEX
+0xA2D2 0x00B6 #PILCROW SIGN
+0xA2D3 0x2020 #DAGGER
+0xA2D4 0x2021 #DOUBLE DAGGER
+0xA2D5 0x2195 #UP DOWN ARROW
+0xA2D6 0x2197 #NORTH EAST ARROW
+0xA2D7 0x2199 #SOUTH WEST ARROW
+0xA2D8 0x2196 #NORTH WEST ARROW
+0xA2D9 0x2198 #SOUTH EAST ARROW
+0xA2DA 0x266D #MUSIC FLAT SIGN
+0xA2DB 0x2669 #QUARTER NOTE
+0xA2DC 0x266A #EIGHTH NOTE
+0xA2DD 0x266C #BEAMED SIXTEENTH NOTES
+0xA2DE 0x327F #KOREAN STANDARD SYMBOL
+0xA2DF 0x321C #PARENTHESIZED HANGUL CIEUC U
+0xA2E0 0x2116 #NUMERO SIGN
+0xA2E1 0x33C7 #SQUARE CO
+0xA2E2 0x2122 #TRADE MARK SIGN
+0xA2E3 0x33C2 #SQUARE AM
+0xA2E4 0x33D8 #SQUARE PM
+0xA2E5 0x2121 #TELEPHONE SIGN
+0xA341 0xC971 #HANGUL SYLLABLE CIEUC YU NIEUNCIEUC
+0xA342 0xC972 #HANGUL SYLLABLE CIEUC YU NIEUNHIEUH
+0xA343 0xC973 #HANGUL SYLLABLE CIEUC YU TIKEUT
+0xA344 0xC975 #HANGUL SYLLABLE CIEUC YU RIEULKIYEOK
+0xA345 0xC976 #HANGUL SYLLABLE CIEUC YU RIEULMIEUM
+0xA346 0xC977 #HANGUL SYLLABLE CIEUC YU RIEULPIEUP
+0xA347 0xC978 #HANGUL SYLLABLE CIEUC YU RIEULSIOS
+0xA348 0xC979 #HANGUL SYLLABLE CIEUC YU RIEULTHIEUTH
+0xA349 0xC97A #HANGUL SYLLABLE CIEUC YU RIEULPHIEUPH
+0xA34A 0xC97B #HANGUL SYLLABLE CIEUC YU RIEULHIEUH
+0xA34B 0xC97D #HANGUL SYLLABLE CIEUC YU PIEUP
+0xA34C 0xC97E #HANGUL SYLLABLE CIEUC YU PIEUPSIOS
+0xA34D 0xC97F #HANGUL SYLLABLE CIEUC YU SIOS
+0xA34E 0xC980 #HANGUL SYLLABLE CIEUC YU SSANGSIOS
+0xA34F 0xC981 #HANGUL SYLLABLE CIEUC YU IEUNG
+0xA350 0xC982 #HANGUL SYLLABLE CIEUC YU CIEUC
+0xA351 0xC983 #HANGUL SYLLABLE CIEUC YU CHIEUCH
+0xA352 0xC984 #HANGUL SYLLABLE CIEUC YU KHIEUKH
+0xA353 0xC985 #HANGUL SYLLABLE CIEUC YU THIEUTH
+0xA354 0xC986 #HANGUL SYLLABLE CIEUC YU PHIEUPH
+0xA355 0xC987 #HANGUL SYLLABLE CIEUC YU HIEUH
+0xA356 0xC98A #HANGUL SYLLABLE CIEUC EU SSANGKIYEOK
+0xA357 0xC98B #HANGUL SYLLABLE CIEUC EU KIYEOKSIOS
+0xA358 0xC98D #HANGUL SYLLABLE CIEUC EU NIEUNCIEUC
+0xA359 0xC98E #HANGUL SYLLABLE CIEUC EU NIEUNHIEUH
+0xA35A 0xC98F #HANGUL SYLLABLE CIEUC EU TIKEUT
+0xA361 0xC991 #HANGUL SYLLABLE CIEUC EU RIEULKIYEOK
+0xA362 0xC992 #HANGUL SYLLABLE CIEUC EU RIEULMIEUM
+0xA363 0xC993 #HANGUL SYLLABLE CIEUC EU RIEULPIEUP
+0xA364 0xC994 #HANGUL SYLLABLE CIEUC EU RIEULSIOS
+0xA365 0xC995 #HANGUL SYLLABLE CIEUC EU RIEULTHIEUTH
+0xA366 0xC996 #HANGUL SYLLABLE CIEUC EU RIEULPHIEUPH
+0xA367 0xC997 #HANGUL SYLLABLE CIEUC EU RIEULHIEUH
+0xA368 0xC99A #HANGUL SYLLABLE CIEUC EU PIEUPSIOS
+0xA369 0xC99C #HANGUL SYLLABLE CIEUC EU SSANGSIOS
+0xA36A 0xC99E #HANGUL SYLLABLE CIEUC EU CIEUC
+0xA36B 0xC99F #HANGUL SYLLABLE CIEUC EU CHIEUCH
+0xA36C 0xC9A0 #HANGUL SYLLABLE CIEUC EU KHIEUKH
+0xA36D 0xC9A1 #HANGUL SYLLABLE CIEUC EU THIEUTH
+0xA36E 0xC9A2 #HANGUL SYLLABLE CIEUC EU PHIEUPH
+0xA36F 0xC9A3 #HANGUL SYLLABLE CIEUC EU HIEUH
+0xA370 0xC9A4 #HANGUL SYLLABLE CIEUC YI
+0xA371 0xC9A5 #HANGUL SYLLABLE CIEUC YI KIYEOK
+0xA372 0xC9A6 #HANGUL SYLLABLE CIEUC YI SSANGKIYEOK
+0xA373 0xC9A7 #HANGUL SYLLABLE CIEUC YI KIYEOKSIOS
+0xA374 0xC9A8 #HANGUL SYLLABLE CIEUC YI NIEUN
+0xA375 0xC9A9 #HANGUL SYLLABLE CIEUC YI NIEUNCIEUC
+0xA376 0xC9AA #HANGUL SYLLABLE CIEUC YI NIEUNHIEUH
+0xA377 0xC9AB #HANGUL SYLLABLE CIEUC YI TIKEUT
+0xA378 0xC9AC #HANGUL SYLLABLE CIEUC YI RIEUL
+0xA379 0xC9AD #HANGUL SYLLABLE CIEUC YI RIEULKIYEOK
+0xA37A 0xC9AE #HANGUL SYLLABLE CIEUC YI RIEULMIEUM
+0xA381 0xC9AF #HANGUL SYLLABLE CIEUC YI RIEULPIEUP
+0xA382 0xC9B0 #HANGUL SYLLABLE CIEUC YI RIEULSIOS
+0xA383 0xC9B1 #HANGUL SYLLABLE CIEUC YI RIEULTHIEUTH
+0xA384 0xC9B2 #HANGUL SYLLABLE CIEUC YI RIEULPHIEUPH
+0xA385 0xC9B3 #HANGUL SYLLABLE CIEUC YI RIEULHIEUH
+0xA386 0xC9B4 #HANGUL SYLLABLE CIEUC YI MIEUM
+0xA387 0xC9B5 #HANGUL SYLLABLE CIEUC YI PIEUP
+0xA388 0xC9B6 #HANGUL SYLLABLE CIEUC YI PIEUPSIOS
+0xA389 0xC9B7 #HANGUL SYLLABLE CIEUC YI SIOS
+0xA38A 0xC9B8 #HANGUL SYLLABLE CIEUC YI SSANGSIOS
+0xA38B 0xC9B9 #HANGUL SYLLABLE CIEUC YI IEUNG
+0xA38C 0xC9BA #HANGUL SYLLABLE CIEUC YI CIEUC
+0xA38D 0xC9BB #HANGUL SYLLABLE CIEUC YI CHIEUCH
+0xA38E 0xC9BC #HANGUL SYLLABLE CIEUC YI KHIEUKH
+0xA38F 0xC9BD #HANGUL SYLLABLE CIEUC YI THIEUTH
+0xA390 0xC9BE #HANGUL SYLLABLE CIEUC YI PHIEUPH
+0xA391 0xC9BF #HANGUL SYLLABLE CIEUC YI HIEUH
+0xA392 0xC9C2 #HANGUL SYLLABLE CIEUC I SSANGKIYEOK
+0xA393 0xC9C3 #HANGUL SYLLABLE CIEUC I KIYEOKSIOS
+0xA394 0xC9C5 #HANGUL SYLLABLE CIEUC I NIEUNCIEUC
+0xA395 0xC9C6 #HANGUL SYLLABLE CIEUC I NIEUNHIEUH
+0xA396 0xC9C9 #HANGUL SYLLABLE CIEUC I RIEULKIYEOK
+0xA397 0xC9CB #HANGUL SYLLABLE CIEUC I RIEULPIEUP
+0xA398 0xC9CC #HANGUL SYLLABLE CIEUC I RIEULSIOS
+0xA399 0xC9CD #HANGUL SYLLABLE CIEUC I RIEULTHIEUTH
+0xA39A 0xC9CE #HANGUL SYLLABLE CIEUC I RIEULPHIEUPH
+0xA39B 0xC9CF #HANGUL SYLLABLE CIEUC I RIEULHIEUH
+0xA39C 0xC9D2 #HANGUL SYLLABLE CIEUC I PIEUPSIOS
+0xA39D 0xC9D4 #HANGUL SYLLABLE CIEUC I SSANGSIOS
+0xA39E 0xC9D7 #HANGUL SYLLABLE CIEUC I CHIEUCH
+0xA39F 0xC9D8 #HANGUL SYLLABLE CIEUC I KHIEUKH
+0xA3A0 0xC9DB #HANGUL SYLLABLE CIEUC I HIEUH
+0xA3A1 0xFF01 #FULLWIDTH EXCLAMATION MARK
+0xA3A2 0xFF02 #FULLWIDTH QUOTATION MARK
+0xA3A3 0xFF03 #FULLWIDTH NUMBER SIGN
+0xA3A4 0xFF04 #FULLWIDTH DOLLAR SIGN
+0xA3A5 0xFF05 #FULLWIDTH PERCENT SIGN
+0xA3A6 0xFF06 #FULLWIDTH AMPERSAND
+0xA3A7 0xFF07 #FULLWIDTH APOSTROPHE
+0xA3A8 0xFF08 #FULLWIDTH LEFT PARENTHESIS
+0xA3A9 0xFF09 #FULLWIDTH RIGHT PARENTHESIS
+0xA3AA 0xFF0A #FULLWIDTH ASTERISK
+0xA3AB 0xFF0B #FULLWIDTH PLUS SIGN
+0xA3AC 0xFF0C #FULLWIDTH COMMA
+0xA3AD 0xFF0D #FULLWIDTH HYPHEN-MINUS
+0xA3AE 0xFF0E #FULLWIDTH FULL STOP
+0xA3AF 0xFF0F #FULLWIDTH SOLIDUS
+0xA3B0 0xFF10 #FULLWIDTH DIGIT ZERO
+0xA3B1 0xFF11 #FULLWIDTH DIGIT ONE
+0xA3B2 0xFF12 #FULLWIDTH DIGIT TWO
+0xA3B3 0xFF13 #FULLWIDTH DIGIT THREE
+0xA3B4 0xFF14 #FULLWIDTH DIGIT FOUR
+0xA3B5 0xFF15 #FULLWIDTH DIGIT FIVE
+0xA3B6 0xFF16 #FULLWIDTH DIGIT SIX
+0xA3B7 0xFF17 #FULLWIDTH DIGIT SEVEN
+0xA3B8 0xFF18 #FULLWIDTH DIGIT EIGHT
+0xA3B9 0xFF19 #FULLWIDTH DIGIT NINE
+0xA3BA 0xFF1A #FULLWIDTH COLON
+0xA3BB 0xFF1B #FULLWIDTH SEMICOLON
+0xA3BC 0xFF1C #FULLWIDTH LESS-THAN SIGN
+0xA3BD 0xFF1D #FULLWIDTH EQUALS SIGN
+0xA3BE 0xFF1E #FULLWIDTH GREATER-THAN SIGN
+0xA3BF 0xFF1F #FULLWIDTH QUESTION MARK
+0xA3C0 0xFF20 #FULLWIDTH COMMERCIAL AT
+0xA3C1 0xFF21 #FULLWIDTH LATIN CAPITAL LETTER A
+0xA3C2 0xFF22 #FULLWIDTH LATIN CAPITAL LETTER B
+0xA3C3 0xFF23 #FULLWIDTH LATIN CAPITAL LETTER C
+0xA3C4 0xFF24 #FULLWIDTH LATIN CAPITAL LETTER D
+0xA3C5 0xFF25 #FULLWIDTH LATIN CAPITAL LETTER E
+0xA3C6 0xFF26 #FULLWIDTH LATIN CAPITAL LETTER F
+0xA3C7 0xFF27 #FULLWIDTH LATIN CAPITAL LETTER G
+0xA3C8 0xFF28 #FULLWIDTH LATIN CAPITAL LETTER H
+0xA3C9 0xFF29 #FULLWIDTH LATIN CAPITAL LETTER I
+0xA3CA 0xFF2A #FULLWIDTH LATIN CAPITAL LETTER J
+0xA3CB 0xFF2B #FULLWIDTH LATIN CAPITAL LETTER K
+0xA3CC 0xFF2C #FULLWIDTH LATIN CAPITAL LETTER L
+0xA3CD 0xFF2D #FULLWIDTH LATIN CAPITAL LETTER M
+0xA3CE 0xFF2E #FULLWIDTH LATIN CAPITAL LETTER N
+0xA3CF 0xFF2F #FULLWIDTH LATIN CAPITAL LETTER O
+0xA3D0 0xFF30 #FULLWIDTH LATIN CAPITAL LETTER P
+0xA3D1 0xFF31 #FULLWIDTH LATIN CAPITAL LETTER Q
+0xA3D2 0xFF32 #FULLWIDTH LATIN CAPITAL LETTER R
+0xA3D3 0xFF33 #FULLWIDTH LATIN CAPITAL LETTER S
+0xA3D4 0xFF34 #FULLWIDTH LATIN CAPITAL LETTER T
+0xA3D5 0xFF35 #FULLWIDTH LATIN CAPITAL LETTER U
+0xA3D6 0xFF36 #FULLWIDTH LATIN CAPITAL LETTER V
+0xA3D7 0xFF37 #FULLWIDTH LATIN CAPITAL LETTER W
+0xA3D8 0xFF38 #FULLWIDTH LATIN CAPITAL LETTER X
+0xA3D9 0xFF39 #FULLWIDTH LATIN CAPITAL LETTER Y
+0xA3DA 0xFF3A #FULLWIDTH LATIN CAPITAL LETTER Z
+0xA3DB 0xFF3B #FULLWIDTH LEFT SQUARE BRACKET
+0xA3DC 0xFFE6 #FULLWIDTH WON SIGN
+0xA3DD 0xFF3D #FULLWIDTH RIGHT SQUARE BRACKET
+0xA3DE 0xFF3E #FULLWIDTH CIRCUMFLEX ACCENT
+0xA3DF 0xFF3F #FULLWIDTH LOW LINE
+0xA3E0 0xFF40 #FULLWIDTH GRAVE ACCENT
+0xA3E1 0xFF41 #FULLWIDTH LATIN SMALL LETTER A
+0xA3E2 0xFF42 #FULLWIDTH LATIN SMALL LETTER B
+0xA3E3 0xFF43 #FULLWIDTH LATIN SMALL LETTER C
+0xA3E4 0xFF44 #FULLWIDTH LATIN SMALL LETTER D
+0xA3E5 0xFF45 #FULLWIDTH LATIN SMALL LETTER E
+0xA3E6 0xFF46 #FULLWIDTH LATIN SMALL LETTER F
+0xA3E7 0xFF47 #FULLWIDTH LATIN SMALL LETTER G
+0xA3E8 0xFF48 #FULLWIDTH LATIN SMALL LETTER H
+0xA3E9 0xFF49 #FULLWIDTH LATIN SMALL LETTER I
+0xA3EA 0xFF4A #FULLWIDTH LATIN SMALL LETTER J
+0xA3EB 0xFF4B #FULLWIDTH LATIN SMALL LETTER K
+0xA3EC 0xFF4C #FULLWIDTH LATIN SMALL LETTER L
+0xA3ED 0xFF4D #FULLWIDTH LATIN SMALL LETTER M
+0xA3EE 0xFF4E #FULLWIDTH LATIN SMALL LETTER N
+0xA3EF 0xFF4F #FULLWIDTH LATIN SMALL LETTER O
+0xA3F0 0xFF50 #FULLWIDTH LATIN SMALL LETTER P
+0xA3F1 0xFF51 #FULLWIDTH LATIN SMALL LETTER Q
+0xA3F2 0xFF52 #FULLWIDTH LATIN SMALL LETTER R
+0xA3F3 0xFF53 #FULLWIDTH LATIN SMALL LETTER S
+0xA3F4 0xFF54 #FULLWIDTH LATIN SMALL LETTER T
+0xA3F5 0xFF55 #FULLWIDTH LATIN SMALL LETTER U
+0xA3F6 0xFF56 #FULLWIDTH LATIN SMALL LETTER V
+0xA3F7 0xFF57 #FULLWIDTH LATIN SMALL LETTER W
+0xA3F8 0xFF58 #FULLWIDTH LATIN SMALL LETTER X
+0xA3F9 0xFF59 #FULLWIDTH LATIN SMALL LETTER Y
+0xA3FA 0xFF5A #FULLWIDTH LATIN SMALL LETTER Z
+0xA3FB 0xFF5B #FULLWIDTH LEFT CURLY BRACKET
+0xA3FC 0xFF5C #FULLWIDTH VERTICAL LINE
+0xA3FD 0xFF5D #FULLWIDTH RIGHT CURLY BRACKET
+0xA3FE 0xFFE3 #FULLWIDTH MACRON
+0xA441 0xC9DE #HANGUL SYLLABLE SSANGCIEUC A SSANGKIYEOK
+0xA442 0xC9DF #HANGUL SYLLABLE SSANGCIEUC A KIYEOKSIOS
+0xA443 0xC9E1 #HANGUL SYLLABLE SSANGCIEUC A NIEUNCIEUC
+0xA444 0xC9E3 #HANGUL SYLLABLE SSANGCIEUC A TIKEUT
+0xA445 0xC9E5 #HANGUL SYLLABLE SSANGCIEUC A RIEULKIYEOK
+0xA446 0xC9E6 #HANGUL SYLLABLE SSANGCIEUC A RIEULMIEUM
+0xA447 0xC9E8 #HANGUL SYLLABLE SSANGCIEUC A RIEULSIOS
+0xA448 0xC9E9 #HANGUL SYLLABLE SSANGCIEUC A RIEULTHIEUTH
+0xA449 0xC9EA #HANGUL SYLLABLE SSANGCIEUC A RIEULPHIEUPH
+0xA44A 0xC9EB #HANGUL SYLLABLE SSANGCIEUC A RIEULHIEUH
+0xA44B 0xC9EE #HANGUL SYLLABLE SSANGCIEUC A PIEUPSIOS
+0xA44C 0xC9F2 #HANGUL SYLLABLE SSANGCIEUC A CIEUC
+0xA44D 0xC9F3 #HANGUL SYLLABLE SSANGCIEUC A CHIEUCH
+0xA44E 0xC9F4 #HANGUL SYLLABLE SSANGCIEUC A KHIEUKH
+0xA44F 0xC9F5 #HANGUL SYLLABLE SSANGCIEUC A THIEUTH
+0xA450 0xC9F6 #HANGUL SYLLABLE SSANGCIEUC A PHIEUPH
+0xA451 0xC9F7 #HANGUL SYLLABLE SSANGCIEUC A HIEUH
+0xA452 0xC9FA #HANGUL SYLLABLE SSANGCIEUC AE SSANGKIYEOK
+0xA453 0xC9FB #HANGUL SYLLABLE SSANGCIEUC AE KIYEOKSIOS
+0xA454 0xC9FD #HANGUL SYLLABLE SSANGCIEUC AE NIEUNCIEUC
+0xA455 0xC9FE #HANGUL SYLLABLE SSANGCIEUC AE NIEUNHIEUH
+0xA456 0xC9FF #HANGUL SYLLABLE SSANGCIEUC AE TIKEUT
+0xA457 0xCA01 #HANGUL SYLLABLE SSANGCIEUC AE RIEULKIYEOK
+0xA458 0xCA02 #HANGUL SYLLABLE SSANGCIEUC AE RIEULMIEUM
+0xA459 0xCA03 #HANGUL SYLLABLE SSANGCIEUC AE RIEULPIEUP
+0xA45A 0xCA04 #HANGUL SYLLABLE SSANGCIEUC AE RIEULSIOS
+0xA461 0xCA05 #HANGUL SYLLABLE SSANGCIEUC AE RIEULTHIEUTH
+0xA462 0xCA06 #HANGUL SYLLABLE SSANGCIEUC AE RIEULPHIEUPH
+0xA463 0xCA07 #HANGUL SYLLABLE SSANGCIEUC AE RIEULHIEUH
+0xA464 0xCA0A #HANGUL SYLLABLE SSANGCIEUC AE PIEUPSIOS
+0xA465 0xCA0E #HANGUL SYLLABLE SSANGCIEUC AE CIEUC
+0xA466 0xCA0F #HANGUL SYLLABLE SSANGCIEUC AE CHIEUCH
+0xA467 0xCA10 #HANGUL SYLLABLE SSANGCIEUC AE KHIEUKH
+0xA468 0xCA11 #HANGUL SYLLABLE SSANGCIEUC AE THIEUTH
+0xA469 0xCA12 #HANGUL SYLLABLE SSANGCIEUC AE PHIEUPH
+0xA46A 0xCA13 #HANGUL SYLLABLE SSANGCIEUC AE HIEUH
+0xA46B 0xCA15 #HANGUL SYLLABLE SSANGCIEUC YA KIYEOK
+0xA46C 0xCA16 #HANGUL SYLLABLE SSANGCIEUC YA SSANGKIYEOK
+0xA46D 0xCA17 #HANGUL SYLLABLE SSANGCIEUC YA KIYEOKSIOS
+0xA46E 0xCA19 #HANGUL SYLLABLE SSANGCIEUC YA NIEUNCIEUC
+0xA46F 0xCA1A #HANGUL SYLLABLE SSANGCIEUC YA NIEUNHIEUH
+0xA470 0xCA1B #HANGUL SYLLABLE SSANGCIEUC YA TIKEUT
+0xA471 0xCA1C #HANGUL SYLLABLE SSANGCIEUC YA RIEUL
+0xA472 0xCA1D #HANGUL SYLLABLE SSANGCIEUC YA RIEULKIYEOK
+0xA473 0xCA1E #HANGUL SYLLABLE SSANGCIEUC YA RIEULMIEUM
+0xA474 0xCA1F #HANGUL SYLLABLE SSANGCIEUC YA RIEULPIEUP
+0xA475 0xCA20 #HANGUL SYLLABLE SSANGCIEUC YA RIEULSIOS
+0xA476 0xCA21 #HANGUL SYLLABLE SSANGCIEUC YA RIEULTHIEUTH
+0xA477 0xCA22 #HANGUL SYLLABLE SSANGCIEUC YA RIEULPHIEUPH
+0xA478 0xCA23 #HANGUL SYLLABLE SSANGCIEUC YA RIEULHIEUH
+0xA479 0xCA24 #HANGUL SYLLABLE SSANGCIEUC YA MIEUM
+0xA47A 0xCA25 #HANGUL SYLLABLE SSANGCIEUC YA PIEUP
+0xA481 0xCA26 #HANGUL SYLLABLE SSANGCIEUC YA PIEUPSIOS
+0xA482 0xCA27 #HANGUL SYLLABLE SSANGCIEUC YA SIOS
+0xA483 0xCA28 #HANGUL SYLLABLE SSANGCIEUC YA SSANGSIOS
+0xA484 0xCA2A #HANGUL SYLLABLE SSANGCIEUC YA CIEUC
+0xA485 0xCA2B #HANGUL SYLLABLE SSANGCIEUC YA CHIEUCH
+0xA486 0xCA2C #HANGUL SYLLABLE SSANGCIEUC YA KHIEUKH
+0xA487 0xCA2D #HANGUL SYLLABLE SSANGCIEUC YA THIEUTH
+0xA488 0xCA2E #HANGUL SYLLABLE SSANGCIEUC YA PHIEUPH
+0xA489 0xCA2F #HANGUL SYLLABLE SSANGCIEUC YA HIEUH
+0xA48A 0xCA30 #HANGUL SYLLABLE SSANGCIEUC YAE
+0xA48B 0xCA31 #HANGUL SYLLABLE SSANGCIEUC YAE KIYEOK
+0xA48C 0xCA32 #HANGUL SYLLABLE SSANGCIEUC YAE SSANGKIYEOK
+0xA48D 0xCA33 #HANGUL SYLLABLE SSANGCIEUC YAE KIYEOKSIOS
+0xA48E 0xCA34 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUN
+0xA48F 0xCA35 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUNCIEUC
+0xA490 0xCA36 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUNHIEUH
+0xA491 0xCA37 #HANGUL SYLLABLE SSANGCIEUC YAE TIKEUT
+0xA492 0xCA38 #HANGUL SYLLABLE SSANGCIEUC YAE RIEUL
+0xA493 0xCA39 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULKIYEOK
+0xA494 0xCA3A #HANGUL SYLLABLE SSANGCIEUC YAE RIEULMIEUM
+0xA495 0xCA3B #HANGUL SYLLABLE SSANGCIEUC YAE RIEULPIEUP
+0xA496 0xCA3C #HANGUL SYLLABLE SSANGCIEUC YAE RIEULSIOS
+0xA497 0xCA3D #HANGUL SYLLABLE SSANGCIEUC YAE RIEULTHIEUTH
+0xA498 0xCA3E #HANGUL SYLLABLE SSANGCIEUC YAE RIEULPHIEUPH
+0xA499 0xCA3F #HANGUL SYLLABLE SSANGCIEUC YAE RIEULHIEUH
+0xA49A 0xCA40 #HANGUL SYLLABLE SSANGCIEUC YAE MIEUM
+0xA49B 0xCA41 #HANGUL SYLLABLE SSANGCIEUC YAE PIEUP
+0xA49C 0xCA42 #HANGUL SYLLABLE SSANGCIEUC YAE PIEUPSIOS
+0xA49D 0xCA43 #HANGUL SYLLABLE SSANGCIEUC YAE SIOS
+0xA49E 0xCA44 #HANGUL SYLLABLE SSANGCIEUC YAE SSANGSIOS
+0xA49F 0xCA45 #HANGUL SYLLABLE SSANGCIEUC YAE IEUNG
+0xA4A0 0xCA46 #HANGUL SYLLABLE SSANGCIEUC YAE CIEUC
+0xA4A1 0x3131 #HANGUL LETTER KIYEOK
+0xA4A2 0x3132 #HANGUL LETTER SSANGKIYEOK
+0xA4A3 0x3133 #HANGUL LETTER KIYEOK-SIOS
+0xA4A4 0x3134 #HANGUL LETTER NIEUN
+0xA4A5 0x3135 #HANGUL LETTER NIEUN-CIEUC
+0xA4A6 0x3136 #HANGUL LETTER NIEUN-HIEUH
+0xA4A7 0x3137 #HANGUL LETTER TIKEUT
+0xA4A8 0x3138 #HANGUL LETTER SSANGTIKEUT
+0xA4A9 0x3139 #HANGUL LETTER RIEUL
+0xA4AA 0x313A #HANGUL LETTER RIEUL-KIYEOK
+0xA4AB 0x313B #HANGUL LETTER RIEUL-MIEUM
+0xA4AC 0x313C #HANGUL LETTER RIEUL-PIEUP
+0xA4AD 0x313D #HANGUL LETTER RIEUL-SIOS
+0xA4AE 0x313E #HANGUL LETTER RIEUL-THIEUTH
+0xA4AF 0x313F #HANGUL LETTER RIEUL-PHIEUPH
+0xA4B0 0x3140 #HANGUL LETTER RIEUL-HIEUH
+0xA4B1 0x3141 #HANGUL LETTER MIEUM
+0xA4B2 0x3142 #HANGUL LETTER PIEUP
+0xA4B3 0x3143 #HANGUL LETTER SSANGPIEUP
+0xA4B4 0x3144 #HANGUL LETTER PIEUP-SIOS
+0xA4B5 0x3145 #HANGUL LETTER SIOS
+0xA4B6 0x3146 #HANGUL LETTER SSANGSIOS
+0xA4B7 0x3147 #HANGUL LETTER IEUNG
+0xA4B8 0x3148 #HANGUL LETTER CIEUC
+0xA4B9 0x3149 #HANGUL LETTER SSANGCIEUC
+0xA4BA 0x314A #HANGUL LETTER CHIEUCH
+0xA4BB 0x314B #HANGUL LETTER KHIEUKH
+0xA4BC 0x314C #HANGUL LETTER THIEUTH
+0xA4BD 0x314D #HANGUL LETTER PHIEUPH
+0xA4BE 0x314E #HANGUL LETTER HIEUH
+0xA4BF 0x314F #HANGUL LETTER A
+0xA4C0 0x3150 #HANGUL LETTER AE
+0xA4C1 0x3151 #HANGUL LETTER YA
+0xA4C2 0x3152 #HANGUL LETTER YAE
+0xA4C3 0x3153 #HANGUL LETTER EO
+0xA4C4 0x3154 #HANGUL LETTER E
+0xA4C5 0x3155 #HANGUL LETTER YEO
+0xA4C6 0x3156 #HANGUL LETTER YE
+0xA4C7 0x3157 #HANGUL LETTER O
+0xA4C8 0x3158 #HANGUL LETTER WA
+0xA4C9 0x3159 #HANGUL LETTER WAE
+0xA4CA 0x315A #HANGUL LETTER OE
+0xA4CB 0x315B #HANGUL LETTER YO
+0xA4CC 0x315C #HANGUL LETTER U
+0xA4CD 0x315D #HANGUL LETTER WEO
+0xA4CE 0x315E #HANGUL LETTER WE
+0xA4CF 0x315F #HANGUL LETTER WI
+0xA4D0 0x3160 #HANGUL LETTER YU
+0xA4D1 0x3161 #HANGUL LETTER EU
+0xA4D2 0x3162 #HANGUL LETTER YI
+0xA4D3 0x3163 #HANGUL LETTER I
+0xA4D4 0x3164 #HANGUL FILLER
+0xA4D5 0x3165 #HANGUL LETTER SSANGNIEUN
+0xA4D6 0x3166 #HANGUL LETTER NIEUN-TIKEUT
+0xA4D7 0x3167 #HANGUL LETTER NIEUN-SIOS
+0xA4D8 0x3168 #HANGUL LETTER NIEUN-PANSIOS
+0xA4D9 0x3169 #HANGUL LETTER RIEUL-KIYEOK-SIOS
+0xA4DA 0x316A #HANGUL LETTER RIEUL-TIKEUT
+0xA4DB 0x316B #HANGUL LETTER RIEUL-PIEUP-SIOS
+0xA4DC 0x316C #HANGUL LETTER RIEUL-PANSIOS
+0xA4DD 0x316D #HANGUL LETTER RIEUL-YEORINHIEUH
+0xA4DE 0x316E #HANGUL LETTER MIEUM-PIEUP
+0xA4DF 0x316F #HANGUL LETTER MIEUM-SIOS
+0xA4E0 0x3170 #HANGUL LETTER MIEUM-PANSIOS
+0xA4E1 0x3171 #HANGUL LETTER KAPYEOUNMIEUM
+0xA4E2 0x3172 #HANGUL LETTER PIEUP-KIYEOK
+0xA4E3 0x3173 #HANGUL LETTER PIEUP-TIKEUT
+0xA4E4 0x3174 #HANGUL LETTER PIEUP-SIOS-KIYEOK
+0xA4E5 0x3175 #HANGUL LETTER PIEUP-SIOS-TIKEUT
+0xA4E6 0x3176 #HANGUL LETTER PIEUP-CIEUC
+0xA4E7 0x3177 #HANGUL LETTER PIEUP-THIEUTH
+0xA4E8 0x3178 #HANGUL LETTER KAPYEOUNPIEUP
+0xA4E9 0x3179 #HANGUL LETTER KAPYEOUNSSANGPIEUP
+0xA4EA 0x317A #HANGUL LETTER SIOS-KIYEOK
+0xA4EB 0x317B #HANGUL LETTER SIOS-NIEUN
+0xA4EC 0x317C #HANGUL LETTER SIOS-TIKEUT
+0xA4ED 0x317D #HANGUL LETTER SIOS-PIEUP
+0xA4EE 0x317E #HANGUL LETTER SIOS-CIEUC
+0xA4EF 0x317F #HANGUL LETTER PANSIOS
+0xA4F0 0x3180 #HANGUL LETTER SSANGIEUNG
+0xA4F1 0x3181 #HANGUL LETTER YESIEUNG
+0xA4F2 0x3182 #HANGUL LETTER YESIEUNG-SIOS
+0xA4F3 0x3183 #HANGUL LETTER YESIEUNG-PANSIOS
+0xA4F4 0x3184 #HANGUL LETTER KAPYEOUNPHIEUPH
+0xA4F5 0x3185 #HANGUL LETTER SSANGHIEUH
+0xA4F6 0x3186 #HANGUL LETTER YEORINHIEUH
+0xA4F7 0x3187 #HANGUL LETTER YO-YA
+0xA4F8 0x3188 #HANGUL LETTER YO-YAE
+0xA4F9 0x3189 #HANGUL LETTER YO-I
+0xA4FA 0x318A #HANGUL LETTER YU-YEO
+0xA4FB 0x318B #HANGUL LETTER YU-YE
+0xA4FC 0x318C #HANGUL LETTER YU-I
+0xA4FD 0x318D #HANGUL LETTER ARAEA
+0xA4FE 0x318E #HANGUL LETTER ARAEAE
+0xA541 0xCA47 #HANGUL SYLLABLE SSANGCIEUC YAE CHIEUCH
+0xA542 0xCA48 #HANGUL SYLLABLE SSANGCIEUC YAE KHIEUKH
+0xA543 0xCA49 #HANGUL SYLLABLE SSANGCIEUC YAE THIEUTH
+0xA544 0xCA4A #HANGUL SYLLABLE SSANGCIEUC YAE PHIEUPH
+0xA545 0xCA4B #HANGUL SYLLABLE SSANGCIEUC YAE HIEUH
+0xA546 0xCA4E #HANGUL SYLLABLE SSANGCIEUC EO SSANGKIYEOK
+0xA547 0xCA4F #HANGUL SYLLABLE SSANGCIEUC EO KIYEOKSIOS
+0xA548 0xCA51 #HANGUL SYLLABLE SSANGCIEUC EO NIEUNCIEUC
+0xA549 0xCA52 #HANGUL SYLLABLE SSANGCIEUC EO NIEUNHIEUH
+0xA54A 0xCA53 #HANGUL SYLLABLE SSANGCIEUC EO TIKEUT
+0xA54B 0xCA55 #HANGUL SYLLABLE SSANGCIEUC EO RIEULKIYEOK
+0xA54C 0xCA56 #HANGUL SYLLABLE SSANGCIEUC EO RIEULMIEUM
+0xA54D 0xCA57 #HANGUL SYLLABLE SSANGCIEUC EO RIEULPIEUP
+0xA54E 0xCA58 #HANGUL SYLLABLE SSANGCIEUC EO RIEULSIOS
+0xA54F 0xCA59 #HANGUL SYLLABLE SSANGCIEUC EO RIEULTHIEUTH
+0xA550 0xCA5A #HANGUL SYLLABLE SSANGCIEUC EO RIEULPHIEUPH
+0xA551 0xCA5B #HANGUL SYLLABLE SSANGCIEUC EO RIEULHIEUH
+0xA552 0xCA5E #HANGUL SYLLABLE SSANGCIEUC EO PIEUPSIOS
+0xA553 0xCA62 #HANGUL SYLLABLE SSANGCIEUC EO CIEUC
+0xA554 0xCA63 #HANGUL SYLLABLE SSANGCIEUC EO CHIEUCH
+0xA555 0xCA64 #HANGUL SYLLABLE SSANGCIEUC EO KHIEUKH
+0xA556 0xCA65 #HANGUL SYLLABLE SSANGCIEUC EO THIEUTH
+0xA557 0xCA66 #HANGUL SYLLABLE SSANGCIEUC EO PHIEUPH
+0xA558 0xCA67 #HANGUL SYLLABLE SSANGCIEUC EO HIEUH
+0xA559 0xCA69 #HANGUL SYLLABLE SSANGCIEUC E KIYEOK
+0xA55A 0xCA6A #HANGUL SYLLABLE SSANGCIEUC E SSANGKIYEOK
+0xA561 0xCA6B #HANGUL SYLLABLE SSANGCIEUC E KIYEOKSIOS
+0xA562 0xCA6C #HANGUL SYLLABLE SSANGCIEUC E NIEUN
+0xA563 0xCA6D #HANGUL SYLLABLE SSANGCIEUC E NIEUNCIEUC
+0xA564 0xCA6E #HANGUL SYLLABLE SSANGCIEUC E NIEUNHIEUH
+0xA565 0xCA6F #HANGUL SYLLABLE SSANGCIEUC E TIKEUT
+0xA566 0xCA70 #HANGUL SYLLABLE SSANGCIEUC E RIEUL
+0xA567 0xCA71 #HANGUL SYLLABLE SSANGCIEUC E RIEULKIYEOK
+0xA568 0xCA72 #HANGUL SYLLABLE SSANGCIEUC E RIEULMIEUM
+0xA569 0xCA73 #HANGUL SYLLABLE SSANGCIEUC E RIEULPIEUP
+0xA56A 0xCA74 #HANGUL SYLLABLE SSANGCIEUC E RIEULSIOS
+0xA56B 0xCA75 #HANGUL SYLLABLE SSANGCIEUC E RIEULTHIEUTH
+0xA56C 0xCA76 #HANGUL SYLLABLE SSANGCIEUC E RIEULPHIEUPH
+0xA56D 0xCA77 #HANGUL SYLLABLE SSANGCIEUC E RIEULHIEUH
+0xA56E 0xCA78 #HANGUL SYLLABLE SSANGCIEUC E MIEUM
+0xA56F 0xCA79 #HANGUL SYLLABLE SSANGCIEUC E PIEUP
+0xA570 0xCA7A #HANGUL SYLLABLE SSANGCIEUC E PIEUPSIOS
+0xA571 0xCA7B #HANGUL SYLLABLE SSANGCIEUC E SIOS
+0xA572 0xCA7C #HANGUL SYLLABLE SSANGCIEUC E SSANGSIOS
+0xA573 0xCA7E #HANGUL SYLLABLE SSANGCIEUC E CIEUC
+0xA574 0xCA7F #HANGUL SYLLABLE SSANGCIEUC E CHIEUCH
+0xA575 0xCA80 #HANGUL SYLLABLE SSANGCIEUC E KHIEUKH
+0xA576 0xCA81 #HANGUL SYLLABLE SSANGCIEUC E THIEUTH
+0xA577 0xCA82 #HANGUL SYLLABLE SSANGCIEUC E PHIEUPH
+0xA578 0xCA83 #HANGUL SYLLABLE SSANGCIEUC E HIEUH
+0xA579 0xCA85 #HANGUL SYLLABLE SSANGCIEUC YEO KIYEOK
+0xA57A 0xCA86 #HANGUL SYLLABLE SSANGCIEUC YEO SSANGKIYEOK
+0xA581 0xCA87 #HANGUL SYLLABLE SSANGCIEUC YEO KIYEOKSIOS
+0xA582 0xCA88 #HANGUL SYLLABLE SSANGCIEUC YEO NIEUN
+0xA583 0xCA89 #HANGUL SYLLABLE SSANGCIEUC YEO NIEUNCIEUC
+0xA584 0xCA8A #HANGUL SYLLABLE SSANGCIEUC YEO NIEUNHIEUH
+0xA585 0xCA8B #HANGUL SYLLABLE SSANGCIEUC YEO TIKEUT
+0xA586 0xCA8C #HANGUL SYLLABLE SSANGCIEUC YEO RIEUL
+0xA587 0xCA8D #HANGUL SYLLABLE SSANGCIEUC YEO RIEULKIYEOK
+0xA588 0xCA8E #HANGUL SYLLABLE SSANGCIEUC YEO RIEULMIEUM
+0xA589 0xCA8F #HANGUL SYLLABLE SSANGCIEUC YEO RIEULPIEUP
+0xA58A 0xCA90 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULSIOS
+0xA58B 0xCA91 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULTHIEUTH
+0xA58C 0xCA92 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULPHIEUPH
+0xA58D 0xCA93 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULHIEUH
+0xA58E 0xCA94 #HANGUL SYLLABLE SSANGCIEUC YEO MIEUM
+0xA58F 0xCA95 #HANGUL SYLLABLE SSANGCIEUC YEO PIEUP
+0xA590 0xCA96 #HANGUL SYLLABLE SSANGCIEUC YEO PIEUPSIOS
+0xA591 0xCA97 #HANGUL SYLLABLE SSANGCIEUC YEO SIOS
+0xA592 0xCA99 #HANGUL SYLLABLE SSANGCIEUC YEO IEUNG
+0xA593 0xCA9A #HANGUL SYLLABLE SSANGCIEUC YEO CIEUC
+0xA594 0xCA9B #HANGUL SYLLABLE SSANGCIEUC YEO CHIEUCH
+0xA595 0xCA9C #HANGUL SYLLABLE SSANGCIEUC YEO KHIEUKH
+0xA596 0xCA9D #HANGUL SYLLABLE SSANGCIEUC YEO THIEUTH
+0xA597 0xCA9E #HANGUL SYLLABLE SSANGCIEUC YEO PHIEUPH
+0xA598 0xCA9F #HANGUL SYLLABLE SSANGCIEUC YEO HIEUH
+0xA599 0xCAA0 #HANGUL SYLLABLE SSANGCIEUC YE
+0xA59A 0xCAA1 #HANGUL SYLLABLE SSANGCIEUC YE KIYEOK
+0xA59B 0xCAA2 #HANGUL SYLLABLE SSANGCIEUC YE SSANGKIYEOK
+0xA59C 0xCAA3 #HANGUL SYLLABLE SSANGCIEUC YE KIYEOKSIOS
+0xA59D 0xCAA4 #HANGUL SYLLABLE SSANGCIEUC YE NIEUN
+0xA59E 0xCAA5 #HANGUL SYLLABLE SSANGCIEUC YE NIEUNCIEUC
+0xA59F 0xCAA6 #HANGUL SYLLABLE SSANGCIEUC YE NIEUNHIEUH
+0xA5A0 0xCAA7 #HANGUL SYLLABLE SSANGCIEUC YE TIKEUT
+0xA5A1 0x2170 #SMALL ROMAN NUMERAL ONE
+0xA5A2 0x2171 #SMALL ROMAN NUMERAL TWO
+0xA5A3 0x2172 #SMALL ROMAN NUMERAL THREE
+0xA5A4 0x2173 #SMALL ROMAN NUMERAL FOUR
+0xA5A5 0x2174 #SMALL ROMAN NUMERAL FIVE
+0xA5A6 0x2175 #SMALL ROMAN NUMERAL SIX
+0xA5A7 0x2176 #SMALL ROMAN NUMERAL SEVEN
+0xA5A8 0x2177 #SMALL ROMAN NUMERAL EIGHT
+0xA5A9 0x2178 #SMALL ROMAN NUMERAL NINE
+0xA5AA 0x2179 #SMALL ROMAN NUMERAL TEN
+0xA5B0 0x2160 #ROMAN NUMERAL ONE
+0xA5B1 0x2161 #ROMAN NUMERAL TWO
+0xA5B2 0x2162 #ROMAN NUMERAL THREE
+0xA5B3 0x2163 #ROMAN NUMERAL FOUR
+0xA5B4 0x2164 #ROMAN NUMERAL FIVE
+0xA5B5 0x2165 #ROMAN NUMERAL SIX
+0xA5B6 0x2166 #ROMAN NUMERAL SEVEN
+0xA5B7 0x2167 #ROMAN NUMERAL EIGHT
+0xA5B8 0x2168 #ROMAN NUMERAL NINE
+0xA5B9 0x2169 #ROMAN NUMERAL TEN
+0xA5C1 0x0391 #GREEK CAPITAL LETTER ALPHA
+0xA5C2 0x0392 #GREEK CAPITAL LETTER BETA
+0xA5C3 0x0393 #GREEK CAPITAL LETTER GAMMA
+0xA5C4 0x0394 #GREEK CAPITAL LETTER DELTA
+0xA5C5 0x0395 #GREEK CAPITAL LETTER EPSILON
+0xA5C6 0x0396 #GREEK CAPITAL LETTER ZETA
+0xA5C7 0x0397 #GREEK CAPITAL LETTER ETA
+0xA5C8 0x0398 #GREEK CAPITAL LETTER THETA
+0xA5C9 0x0399 #GREEK CAPITAL LETTER IOTA
+0xA5CA 0x039A #GREEK CAPITAL LETTER KAPPA
+0xA5CB 0x039B #GREEK CAPITAL LETTER LAMDA
+0xA5CC 0x039C #GREEK CAPITAL LETTER MU
+0xA5CD 0x039D #GREEK CAPITAL LETTER NU
+0xA5CE 0x039E #GREEK CAPITAL LETTER XI
+0xA5CF 0x039F #GREEK CAPITAL LETTER OMICRON
+0xA5D0 0x03A0 #GREEK CAPITAL LETTER PI
+0xA5D1 0x03A1 #GREEK CAPITAL LETTER RHO
+0xA5D2 0x03A3 #GREEK CAPITAL LETTER SIGMA
+0xA5D3 0x03A4 #GREEK CAPITAL LETTER TAU
+0xA5D4 0x03A5 #GREEK CAPITAL LETTER UPSILON
+0xA5D5 0x03A6 #GREEK CAPITAL LETTER PHI
+0xA5D6 0x03A7 #GREEK CAPITAL LETTER CHI
+0xA5D7 0x03A8 #GREEK CAPITAL LETTER PSI
+0xA5D8 0x03A9 #GREEK CAPITAL LETTER OMEGA
+0xA5E1 0x03B1 #GREEK SMALL LETTER ALPHA
+0xA5E2 0x03B2 #GREEK SMALL LETTER BETA
+0xA5E3 0x03B3 #GREEK SMALL LETTER GAMMA
+0xA5E4 0x03B4 #GREEK SMALL LETTER DELTA
+0xA5E5 0x03B5 #GREEK SMALL LETTER EPSILON
+0xA5E6 0x03B6 #GREEK SMALL LETTER ZETA
+0xA5E7 0x03B7 #GREEK SMALL LETTER ETA
+0xA5E8 0x03B8 #GREEK SMALL LETTER THETA
+0xA5E9 0x03B9 #GREEK SMALL LETTER IOTA
+0xA5EA 0x03BA #GREEK SMALL LETTER KAPPA
+0xA5EB 0x03BB #GREEK SMALL LETTER LAMDA
+0xA5EC 0x03BC #GREEK SMALL LETTER MU
+0xA5ED 0x03BD #GREEK SMALL LETTER NU
+0xA5EE 0x03BE #GREEK SMALL LETTER XI
+0xA5EF 0x03BF #GREEK SMALL LETTER OMICRON
+0xA5F0 0x03C0 #GREEK SMALL LETTER PI
+0xA5F1 0x03C1 #GREEK SMALL LETTER RHO
+0xA5F2 0x03C3 #GREEK SMALL LETTER SIGMA
+0xA5F3 0x03C4 #GREEK SMALL LETTER TAU
+0xA5F4 0x03C5 #GREEK SMALL LETTER UPSILON
+0xA5F5 0x03C6 #GREEK SMALL LETTER PHI
+0xA5F6 0x03C7 #GREEK SMALL LETTER CHI
+0xA5F7 0x03C8 #GREEK SMALL LETTER PSI
+0xA5F8 0x03C9 #GREEK SMALL LETTER OMEGA
+0xA641 0xCAA8 #HANGUL SYLLABLE SSANGCIEUC YE RIEUL
+0xA642 0xCAA9 #HANGUL SYLLABLE SSANGCIEUC YE RIEULKIYEOK
+0xA643 0xCAAA #HANGUL SYLLABLE SSANGCIEUC YE RIEULMIEUM
+0xA644 0xCAAB #HANGUL SYLLABLE SSANGCIEUC YE RIEULPIEUP
+0xA645 0xCAAC #HANGUL SYLLABLE SSANGCIEUC YE RIEULSIOS
+0xA646 0xCAAD #HANGUL SYLLABLE SSANGCIEUC YE RIEULTHIEUTH
+0xA647 0xCAAE #HANGUL SYLLABLE SSANGCIEUC YE RIEULPHIEUPH
+0xA648 0xCAAF #HANGUL SYLLABLE SSANGCIEUC YE RIEULHIEUH
+0xA649 0xCAB0 #HANGUL SYLLABLE SSANGCIEUC YE MIEUM
+0xA64A 0xCAB1 #HANGUL SYLLABLE SSANGCIEUC YE PIEUP
+0xA64B 0xCAB2 #HANGUL SYLLABLE SSANGCIEUC YE PIEUPSIOS
+0xA64C 0xCAB3 #HANGUL SYLLABLE SSANGCIEUC YE SIOS
+0xA64D 0xCAB4 #HANGUL SYLLABLE SSANGCIEUC YE SSANGSIOS
+0xA64E 0xCAB5 #HANGUL SYLLABLE SSANGCIEUC YE IEUNG
+0xA64F 0xCAB6 #HANGUL SYLLABLE SSANGCIEUC YE CIEUC
+0xA650 0xCAB7 #HANGUL SYLLABLE SSANGCIEUC YE CHIEUCH
+0xA651 0xCAB8 #HANGUL SYLLABLE SSANGCIEUC YE KHIEUKH
+0xA652 0xCAB9 #HANGUL SYLLABLE SSANGCIEUC YE THIEUTH
+0xA653 0xCABA #HANGUL SYLLABLE SSANGCIEUC YE PHIEUPH
+0xA654 0xCABB #HANGUL SYLLABLE SSANGCIEUC YE HIEUH
+0xA655 0xCABE #HANGUL SYLLABLE SSANGCIEUC O SSANGKIYEOK
+0xA656 0xCABF #HANGUL SYLLABLE SSANGCIEUC O KIYEOKSIOS
+0xA657 0xCAC1 #HANGUL SYLLABLE SSANGCIEUC O NIEUNCIEUC
+0xA658 0xCAC2 #HANGUL SYLLABLE SSANGCIEUC O NIEUNHIEUH
+0xA659 0xCAC3 #HANGUL SYLLABLE SSANGCIEUC O TIKEUT
+0xA65A 0xCAC5 #HANGUL SYLLABLE SSANGCIEUC O RIEULKIYEOK
+0xA661 0xCAC6 #HANGUL SYLLABLE SSANGCIEUC O RIEULMIEUM
+0xA662 0xCAC7 #HANGUL SYLLABLE SSANGCIEUC O RIEULPIEUP
+0xA663 0xCAC8 #HANGUL SYLLABLE SSANGCIEUC O RIEULSIOS
+0xA664 0xCAC9 #HANGUL SYLLABLE SSANGCIEUC O RIEULTHIEUTH
+0xA665 0xCACA #HANGUL SYLLABLE SSANGCIEUC O RIEULPHIEUPH
+0xA666 0xCACB #HANGUL SYLLABLE SSANGCIEUC O RIEULHIEUH
+0xA667 0xCACE #HANGUL SYLLABLE SSANGCIEUC O PIEUPSIOS
+0xA668 0xCAD0 #HANGUL SYLLABLE SSANGCIEUC O SSANGSIOS
+0xA669 0xCAD2 #HANGUL SYLLABLE SSANGCIEUC O CIEUC
+0xA66A 0xCAD4 #HANGUL SYLLABLE SSANGCIEUC O KHIEUKH
+0xA66B 0xCAD5 #HANGUL SYLLABLE SSANGCIEUC O THIEUTH
+0xA66C 0xCAD6 #HANGUL SYLLABLE SSANGCIEUC O PHIEUPH
+0xA66D 0xCAD7 #HANGUL SYLLABLE SSANGCIEUC O HIEUH
+0xA66E 0xCADA #HANGUL SYLLABLE SSANGCIEUC WA SSANGKIYEOK
+0xA66F 0xCADB #HANGUL SYLLABLE SSANGCIEUC WA KIYEOKSIOS
+0xA670 0xCADC #HANGUL SYLLABLE SSANGCIEUC WA NIEUN
+0xA671 0xCADD #HANGUL SYLLABLE SSANGCIEUC WA NIEUNCIEUC
+0xA672 0xCADE #HANGUL SYLLABLE SSANGCIEUC WA NIEUNHIEUH
+0xA673 0xCADF #HANGUL SYLLABLE SSANGCIEUC WA TIKEUT
+0xA674 0xCAE1 #HANGUL SYLLABLE SSANGCIEUC WA RIEULKIYEOK
+0xA675 0xCAE2 #HANGUL SYLLABLE SSANGCIEUC WA RIEULMIEUM
+0xA676 0xCAE3 #HANGUL SYLLABLE SSANGCIEUC WA RIEULPIEUP
+0xA677 0xCAE4 #HANGUL SYLLABLE SSANGCIEUC WA RIEULSIOS
+0xA678 0xCAE5 #HANGUL SYLLABLE SSANGCIEUC WA RIEULTHIEUTH
+0xA679 0xCAE6 #HANGUL SYLLABLE SSANGCIEUC WA RIEULPHIEUPH
+0xA67A 0xCAE7 #HANGUL SYLLABLE SSANGCIEUC WA RIEULHIEUH
+0xA681 0xCAE8 #HANGUL SYLLABLE SSANGCIEUC WA MIEUM
+0xA682 0xCAE9 #HANGUL SYLLABLE SSANGCIEUC WA PIEUP
+0xA683 0xCAEA #HANGUL SYLLABLE SSANGCIEUC WA PIEUPSIOS
+0xA684 0xCAEB #HANGUL SYLLABLE SSANGCIEUC WA SIOS
+0xA685 0xCAED #HANGUL SYLLABLE SSANGCIEUC WA IEUNG
+0xA686 0xCAEE #HANGUL SYLLABLE SSANGCIEUC WA CIEUC
+0xA687 0xCAEF #HANGUL SYLLABLE SSANGCIEUC WA CHIEUCH
+0xA688 0xCAF0 #HANGUL SYLLABLE SSANGCIEUC WA KHIEUKH
+0xA689 0xCAF1 #HANGUL SYLLABLE SSANGCIEUC WA THIEUTH
+0xA68A 0xCAF2 #HANGUL SYLLABLE SSANGCIEUC WA PHIEUPH
+0xA68B 0xCAF3 #HANGUL SYLLABLE SSANGCIEUC WA HIEUH
+0xA68C 0xCAF5 #HANGUL SYLLABLE SSANGCIEUC WAE KIYEOK
+0xA68D 0xCAF6 #HANGUL SYLLABLE SSANGCIEUC WAE SSANGKIYEOK
+0xA68E 0xCAF7 #HANGUL SYLLABLE SSANGCIEUC WAE KIYEOKSIOS
+0xA68F 0xCAF8 #HANGUL SYLLABLE SSANGCIEUC WAE NIEUN
+0xA690 0xCAF9 #HANGUL SYLLABLE SSANGCIEUC WAE NIEUNCIEUC
+0xA691 0xCAFA #HANGUL SYLLABLE SSANGCIEUC WAE NIEUNHIEUH
+0xA692 0xCAFB #HANGUL SYLLABLE SSANGCIEUC WAE TIKEUT
+0xA693 0xCAFC #HANGUL SYLLABLE SSANGCIEUC WAE RIEUL
+0xA694 0xCAFD #HANGUL SYLLABLE SSANGCIEUC WAE RIEULKIYEOK
+0xA695 0xCAFE #HANGUL SYLLABLE SSANGCIEUC WAE RIEULMIEUM
+0xA696 0xCAFF #HANGUL SYLLABLE SSANGCIEUC WAE RIEULPIEUP
+0xA697 0xCB00 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULSIOS
+0xA698 0xCB01 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULTHIEUTH
+0xA699 0xCB02 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULPHIEUPH
+0xA69A 0xCB03 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULHIEUH
+0xA69B 0xCB04 #HANGUL SYLLABLE SSANGCIEUC WAE MIEUM
+0xA69C 0xCB05 #HANGUL SYLLABLE SSANGCIEUC WAE PIEUP
+0xA69D 0xCB06 #HANGUL SYLLABLE SSANGCIEUC WAE PIEUPSIOS
+0xA69E 0xCB07 #HANGUL SYLLABLE SSANGCIEUC WAE SIOS
+0xA69F 0xCB09 #HANGUL SYLLABLE SSANGCIEUC WAE IEUNG
+0xA6A0 0xCB0A #HANGUL SYLLABLE SSANGCIEUC WAE CIEUC
+0xA6A1 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xA6A2 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xA6A3 0x250C #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA6A4 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA6A5 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xA6A6 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xA6A7 0x251C #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA6A8 0x252C #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA6A9 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA6AA 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA6AB 0x253C #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA6AC 0x2501 #BOX DRAWINGS HEAVY HORIZONTAL
+0xA6AD 0x2503 #BOX DRAWINGS HEAVY VERTICAL
+0xA6AE 0x250F #BOX DRAWINGS HEAVY DOWN AND RIGHT
+0xA6AF 0x2513 #BOX DRAWINGS HEAVY DOWN AND LEFT
+0xA6B0 0x251B #BOX DRAWINGS HEAVY UP AND LEFT
+0xA6B1 0x2517 #BOX DRAWINGS HEAVY UP AND RIGHT
+0xA6B2 0x2523 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0xA6B3 0x2533 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0xA6B4 0x252B #BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0xA6B5 0x253B #BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0xA6B6 0x254B #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0xA6B7 0x2520 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0xA6B8 0x252F #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0xA6B9 0x2528 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0xA6BA 0x2537 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0xA6BB 0x253F #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0xA6BC 0x251D #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0xA6BD 0x2530 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0xA6BE 0x2525 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0xA6BF 0x2538 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0xA6C0 0x2542 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0xA6C1 0x2512 #BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0xA6C2 0x2511 #BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0xA6C3 0x251A #BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0xA6C4 0x2519 #BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0xA6C5 0x2516 #BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0xA6C6 0x2515 #BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0xA6C7 0x250E #BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0xA6C8 0x250D #BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0xA6C9 0x251E #BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0xA6CA 0x251F #BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0xA6CB 0x2521 #BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0xA6CC 0x2522 #BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0xA6CD 0x2526 #BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0xA6CE 0x2527 #BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0xA6CF 0x2529 #BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0xA6D0 0x252A #BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0xA6D1 0x252D #BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0xA6D2 0x252E #BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0xA6D3 0x2531 #BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0xA6D4 0x2532 #BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0xA6D5 0x2535 #BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0xA6D6 0x2536 #BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0xA6D7 0x2539 #BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0xA6D8 0x253A #BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0xA6D9 0x253D #BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0xA6DA 0x253E #BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0xA6DB 0x2540 #BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0xA6DC 0x2541 #BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0xA6DD 0x2543 #BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0xA6DE 0x2544 #BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0xA6DF 0x2545 #BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0xA6E0 0x2546 #BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0xA6E1 0x2547 #BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0xA6E2 0x2548 #BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0xA6E3 0x2549 #BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0xA6E4 0x254A #BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0xA741 0xCB0B #HANGUL SYLLABLE SSANGCIEUC WAE CHIEUCH
+0xA742 0xCB0C #HANGUL SYLLABLE SSANGCIEUC WAE KHIEUKH
+0xA743 0xCB0D #HANGUL SYLLABLE SSANGCIEUC WAE THIEUTH
+0xA744 0xCB0E #HANGUL SYLLABLE SSANGCIEUC WAE PHIEUPH
+0xA745 0xCB0F #HANGUL SYLLABLE SSANGCIEUC WAE HIEUH
+0xA746 0xCB11 #HANGUL SYLLABLE SSANGCIEUC OE KIYEOK
+0xA747 0xCB12 #HANGUL SYLLABLE SSANGCIEUC OE SSANGKIYEOK
+0xA748 0xCB13 #HANGUL SYLLABLE SSANGCIEUC OE KIYEOKSIOS
+0xA749 0xCB15 #HANGUL SYLLABLE SSANGCIEUC OE NIEUNCIEUC
+0xA74A 0xCB16 #HANGUL SYLLABLE SSANGCIEUC OE NIEUNHIEUH
+0xA74B 0xCB17 #HANGUL SYLLABLE SSANGCIEUC OE TIKEUT
+0xA74C 0xCB19 #HANGUL SYLLABLE SSANGCIEUC OE RIEULKIYEOK
+0xA74D 0xCB1A #HANGUL SYLLABLE SSANGCIEUC OE RIEULMIEUM
+0xA74E 0xCB1B #HANGUL SYLLABLE SSANGCIEUC OE RIEULPIEUP
+0xA74F 0xCB1C #HANGUL SYLLABLE SSANGCIEUC OE RIEULSIOS
+0xA750 0xCB1D #HANGUL SYLLABLE SSANGCIEUC OE RIEULTHIEUTH
+0xA751 0xCB1E #HANGUL SYLLABLE SSANGCIEUC OE RIEULPHIEUPH
+0xA752 0xCB1F #HANGUL SYLLABLE SSANGCIEUC OE RIEULHIEUH
+0xA753 0xCB22 #HANGUL SYLLABLE SSANGCIEUC OE PIEUPSIOS
+0xA754 0xCB23 #HANGUL SYLLABLE SSANGCIEUC OE SIOS
+0xA755 0xCB24 #HANGUL SYLLABLE SSANGCIEUC OE SSANGSIOS
+0xA756 0xCB25 #HANGUL SYLLABLE SSANGCIEUC OE IEUNG
+0xA757 0xCB26 #HANGUL SYLLABLE SSANGCIEUC OE CIEUC
+0xA758 0xCB27 #HANGUL SYLLABLE SSANGCIEUC OE CHIEUCH
+0xA759 0xCB28 #HANGUL SYLLABLE SSANGCIEUC OE KHIEUKH
+0xA75A 0xCB29 #HANGUL SYLLABLE SSANGCIEUC OE THIEUTH
+0xA761 0xCB2A #HANGUL SYLLABLE SSANGCIEUC OE PHIEUPH
+0xA762 0xCB2B #HANGUL SYLLABLE SSANGCIEUC OE HIEUH
+0xA763 0xCB2C #HANGUL SYLLABLE SSANGCIEUC YO
+0xA764 0xCB2D #HANGUL SYLLABLE SSANGCIEUC YO KIYEOK
+0xA765 0xCB2E #HANGUL SYLLABLE SSANGCIEUC YO SSANGKIYEOK
+0xA766 0xCB2F #HANGUL SYLLABLE SSANGCIEUC YO KIYEOKSIOS
+0xA767 0xCB30 #HANGUL SYLLABLE SSANGCIEUC YO NIEUN
+0xA768 0xCB31 #HANGUL SYLLABLE SSANGCIEUC YO NIEUNCIEUC
+0xA769 0xCB32 #HANGUL SYLLABLE SSANGCIEUC YO NIEUNHIEUH
+0xA76A 0xCB33 #HANGUL SYLLABLE SSANGCIEUC YO TIKEUT
+0xA76B 0xCB34 #HANGUL SYLLABLE SSANGCIEUC YO RIEUL
+0xA76C 0xCB35 #HANGUL SYLLABLE SSANGCIEUC YO RIEULKIYEOK
+0xA76D 0xCB36 #HANGUL SYLLABLE SSANGCIEUC YO RIEULMIEUM
+0xA76E 0xCB37 #HANGUL SYLLABLE SSANGCIEUC YO RIEULPIEUP
+0xA76F 0xCB38 #HANGUL SYLLABLE SSANGCIEUC YO RIEULSIOS
+0xA770 0xCB39 #HANGUL SYLLABLE SSANGCIEUC YO RIEULTHIEUTH
+0xA771 0xCB3A #HANGUL SYLLABLE SSANGCIEUC YO RIEULPHIEUPH
+0xA772 0xCB3B #HANGUL SYLLABLE SSANGCIEUC YO RIEULHIEUH
+0xA773 0xCB3C #HANGUL SYLLABLE SSANGCIEUC YO MIEUM
+0xA774 0xCB3D #HANGUL SYLLABLE SSANGCIEUC YO PIEUP
+0xA775 0xCB3E #HANGUL SYLLABLE SSANGCIEUC YO PIEUPSIOS
+0xA776 0xCB3F #HANGUL SYLLABLE SSANGCIEUC YO SIOS
+0xA777 0xCB40 #HANGUL SYLLABLE SSANGCIEUC YO SSANGSIOS
+0xA778 0xCB42 #HANGUL SYLLABLE SSANGCIEUC YO CIEUC
+0xA779 0xCB43 #HANGUL SYLLABLE SSANGCIEUC YO CHIEUCH
+0xA77A 0xCB44 #HANGUL SYLLABLE SSANGCIEUC YO KHIEUKH
+0xA781 0xCB45 #HANGUL SYLLABLE SSANGCIEUC YO THIEUTH
+0xA782 0xCB46 #HANGUL SYLLABLE SSANGCIEUC YO PHIEUPH
+0xA783 0xCB47 #HANGUL SYLLABLE SSANGCIEUC YO HIEUH
+0xA784 0xCB4A #HANGUL SYLLABLE SSANGCIEUC U SSANGKIYEOK
+0xA785 0xCB4B #HANGUL SYLLABLE SSANGCIEUC U KIYEOKSIOS
+0xA786 0xCB4D #HANGUL SYLLABLE SSANGCIEUC U NIEUNCIEUC
+0xA787 0xCB4E #HANGUL SYLLABLE SSANGCIEUC U NIEUNHIEUH
+0xA788 0xCB4F #HANGUL SYLLABLE SSANGCIEUC U TIKEUT
+0xA789 0xCB51 #HANGUL SYLLABLE SSANGCIEUC U RIEULKIYEOK
+0xA78A 0xCB52 #HANGUL SYLLABLE SSANGCIEUC U RIEULMIEUM
+0xA78B 0xCB53 #HANGUL SYLLABLE SSANGCIEUC U RIEULPIEUP
+0xA78C 0xCB54 #HANGUL SYLLABLE SSANGCIEUC U RIEULSIOS
+0xA78D 0xCB55 #HANGUL SYLLABLE SSANGCIEUC U RIEULTHIEUTH
+0xA78E 0xCB56 #HANGUL SYLLABLE SSANGCIEUC U RIEULPHIEUPH
+0xA78F 0xCB57 #HANGUL SYLLABLE SSANGCIEUC U RIEULHIEUH
+0xA790 0xCB5A #HANGUL SYLLABLE SSANGCIEUC U PIEUPSIOS
+0xA791 0xCB5B #HANGUL SYLLABLE SSANGCIEUC U SIOS
+0xA792 0xCB5C #HANGUL SYLLABLE SSANGCIEUC U SSANGSIOS
+0xA793 0xCB5E #HANGUL SYLLABLE SSANGCIEUC U CIEUC
+0xA794 0xCB5F #HANGUL SYLLABLE SSANGCIEUC U CHIEUCH
+0xA795 0xCB60 #HANGUL SYLLABLE SSANGCIEUC U KHIEUKH
+0xA796 0xCB61 #HANGUL SYLLABLE SSANGCIEUC U THIEUTH
+0xA797 0xCB62 #HANGUL SYLLABLE SSANGCIEUC U PHIEUPH
+0xA798 0xCB63 #HANGUL SYLLABLE SSANGCIEUC U HIEUH
+0xA799 0xCB65 #HANGUL SYLLABLE SSANGCIEUC WEO KIYEOK
+0xA79A 0xCB66 #HANGUL SYLLABLE SSANGCIEUC WEO SSANGKIYEOK
+0xA79B 0xCB67 #HANGUL SYLLABLE SSANGCIEUC WEO KIYEOKSIOS
+0xA79C 0xCB68 #HANGUL SYLLABLE SSANGCIEUC WEO NIEUN
+0xA79D 0xCB69 #HANGUL SYLLABLE SSANGCIEUC WEO NIEUNCIEUC
+0xA79E 0xCB6A #HANGUL SYLLABLE SSANGCIEUC WEO NIEUNHIEUH
+0xA79F 0xCB6B #HANGUL SYLLABLE SSANGCIEUC WEO TIKEUT
+0xA7A0 0xCB6C #HANGUL SYLLABLE SSANGCIEUC WEO RIEUL
+0xA7A1 0x3395 #SQUARE MU L
+0xA7A2 0x3396 #SQUARE ML
+0xA7A3 0x3397 #SQUARE DL
+0xA7A4 0x2113 #SCRIPT SMALL L
+0xA7A5 0x3398 #SQUARE KL
+0xA7A6 0x33C4 #SQUARE CC
+0xA7A7 0x33A3 #SQUARE MM CUBED
+0xA7A8 0x33A4 #SQUARE CM CUBED
+0xA7A9 0x33A5 #SQUARE M CUBED
+0xA7AA 0x33A6 #SQUARE KM CUBED
+0xA7AB 0x3399 #SQUARE FM
+0xA7AC 0x339A #SQUARE NM
+0xA7AD 0x339B #SQUARE MU M
+0xA7AE 0x339C #SQUARE MM
+0xA7AF 0x339D #SQUARE CM
+0xA7B0 0x339E #SQUARE KM
+0xA7B1 0x339F #SQUARE MM SQUARED
+0xA7B2 0x33A0 #SQUARE CM SQUARED
+0xA7B3 0x33A1 #SQUARE M SQUARED
+0xA7B4 0x33A2 #SQUARE KM SQUARED
+0xA7B5 0x33CA #SQUARE HA
+0xA7B6 0x338D #SQUARE MU G
+0xA7B7 0x338E #SQUARE MG
+0xA7B8 0x338F #SQUARE KG
+0xA7B9 0x33CF #SQUARE KT
+0xA7BA 0x3388 #SQUARE CAL
+0xA7BB 0x3389 #SQUARE KCAL
+0xA7BC 0x33C8 #SQUARE DB
+0xA7BD 0x33A7 #SQUARE M OVER S
+0xA7BE 0x33A8 #SQUARE M OVER S SQUARED
+0xA7BF 0x33B0 #SQUARE PS
+0xA7C0 0x33B1 #SQUARE NS
+0xA7C1 0x33B2 #SQUARE MU S
+0xA7C2 0x33B3 #SQUARE MS
+0xA7C3 0x33B4 #SQUARE PV
+0xA7C4 0x33B5 #SQUARE NV
+0xA7C5 0x33B6 #SQUARE MU V
+0xA7C6 0x33B7 #SQUARE MV
+0xA7C7 0x33B8 #SQUARE KV
+0xA7C8 0x33B9 #SQUARE MV MEGA
+0xA7C9 0x3380 #SQUARE PA AMPS
+0xA7CA 0x3381 #SQUARE NA
+0xA7CB 0x3382 #SQUARE MU A
+0xA7CC 0x3383 #SQUARE MA
+0xA7CD 0x3384 #SQUARE KA
+0xA7CE 0x33BA #SQUARE PW
+0xA7CF 0x33BB #SQUARE NW
+0xA7D0 0x33BC #SQUARE MU W
+0xA7D1 0x33BD #SQUARE MW
+0xA7D2 0x33BE #SQUARE KW
+0xA7D3 0x33BF #SQUARE MW MEGA
+0xA7D4 0x3390 #SQUARE HZ
+0xA7D5 0x3391 #SQUARE KHZ
+0xA7D6 0x3392 #SQUARE MHZ
+0xA7D7 0x3393 #SQUARE GHZ
+0xA7D8 0x3394 #SQUARE THZ
+0xA7D9 0x2126 #OHM SIGN
+0xA7DA 0x33C0 #SQUARE K OHM
+0xA7DB 0x33C1 #SQUARE M OHM
+0xA7DC 0x338A #SQUARE PF
+0xA7DD 0x338B #SQUARE NF
+0xA7DE 0x338C #SQUARE MU F
+0xA7DF 0x33D6 #SQUARE MOL
+0xA7E0 0x33C5 #SQUARE CD
+0xA7E1 0x33AD #SQUARE RAD
+0xA7E2 0x33AE #SQUARE RAD OVER S
+0xA7E3 0x33AF #SQUARE RAD OVER S SQUARED
+0xA7E4 0x33DB #SQUARE SR
+0xA7E5 0x33A9 #SQUARE PA
+0xA7E6 0x33AA #SQUARE KPA
+0xA7E7 0x33AB #SQUARE MPA
+0xA7E8 0x33AC #SQUARE GPA
+0xA7E9 0x33DD #SQUARE WB
+0xA7EA 0x33D0 #SQUARE LM
+0xA7EB 0x33D3 #SQUARE LX
+0xA7EC 0x33C3 #SQUARE BQ
+0xA7ED 0x33C9 #SQUARE GY
+0xA7EE 0x33DC #SQUARE SV
+0xA7EF 0x33C6 #SQUARE C OVER KG
+0xA841 0xCB6D #HANGUL SYLLABLE SSANGCIEUC WEO RIEULKIYEOK
+0xA842 0xCB6E #HANGUL SYLLABLE SSANGCIEUC WEO RIEULMIEUM
+0xA843 0xCB6F #HANGUL SYLLABLE SSANGCIEUC WEO RIEULPIEUP
+0xA844 0xCB70 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULSIOS
+0xA845 0xCB71 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULTHIEUTH
+0xA846 0xCB72 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULPHIEUPH
+0xA847 0xCB73 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULHIEUH
+0xA848 0xCB74 #HANGUL SYLLABLE SSANGCIEUC WEO MIEUM
+0xA849 0xCB75 #HANGUL SYLLABLE SSANGCIEUC WEO PIEUP
+0xA84A 0xCB76 #HANGUL SYLLABLE SSANGCIEUC WEO PIEUPSIOS
+0xA84B 0xCB77 #HANGUL SYLLABLE SSANGCIEUC WEO SIOS
+0xA84C 0xCB7A #HANGUL SYLLABLE SSANGCIEUC WEO CIEUC
+0xA84D 0xCB7B #HANGUL SYLLABLE SSANGCIEUC WEO CHIEUCH
+0xA84E 0xCB7C #HANGUL SYLLABLE SSANGCIEUC WEO KHIEUKH
+0xA84F 0xCB7D #HANGUL SYLLABLE SSANGCIEUC WEO THIEUTH
+0xA850 0xCB7E #HANGUL SYLLABLE SSANGCIEUC WEO PHIEUPH
+0xA851 0xCB7F #HANGUL SYLLABLE SSANGCIEUC WEO HIEUH
+0xA852 0xCB80 #HANGUL SYLLABLE SSANGCIEUC WE
+0xA853 0xCB81 #HANGUL SYLLABLE SSANGCIEUC WE KIYEOK
+0xA854 0xCB82 #HANGUL SYLLABLE SSANGCIEUC WE SSANGKIYEOK
+0xA855 0xCB83 #HANGUL SYLLABLE SSANGCIEUC WE KIYEOKSIOS
+0xA856 0xCB84 #HANGUL SYLLABLE SSANGCIEUC WE NIEUN
+0xA857 0xCB85 #HANGUL SYLLABLE SSANGCIEUC WE NIEUNCIEUC
+0xA858 0xCB86 #HANGUL SYLLABLE SSANGCIEUC WE NIEUNHIEUH
+0xA859 0xCB87 #HANGUL SYLLABLE SSANGCIEUC WE TIKEUT
+0xA85A 0xCB88 #HANGUL SYLLABLE SSANGCIEUC WE RIEUL
+0xA861 0xCB89 #HANGUL SYLLABLE SSANGCIEUC WE RIEULKIYEOK
+0xA862 0xCB8A #HANGUL SYLLABLE SSANGCIEUC WE RIEULMIEUM
+0xA863 0xCB8B #HANGUL SYLLABLE SSANGCIEUC WE RIEULPIEUP
+0xA864 0xCB8C #HANGUL SYLLABLE SSANGCIEUC WE RIEULSIOS
+0xA865 0xCB8D #HANGUL SYLLABLE SSANGCIEUC WE RIEULTHIEUTH
+0xA866 0xCB8E #HANGUL SYLLABLE SSANGCIEUC WE RIEULPHIEUPH
+0xA867 0xCB8F #HANGUL SYLLABLE SSANGCIEUC WE RIEULHIEUH
+0xA868 0xCB90 #HANGUL SYLLABLE SSANGCIEUC WE MIEUM
+0xA869 0xCB91 #HANGUL SYLLABLE SSANGCIEUC WE PIEUP
+0xA86A 0xCB92 #HANGUL SYLLABLE SSANGCIEUC WE PIEUPSIOS
+0xA86B 0xCB93 #HANGUL SYLLABLE SSANGCIEUC WE SIOS
+0xA86C 0xCB94 #HANGUL SYLLABLE SSANGCIEUC WE SSANGSIOS
+0xA86D 0xCB95 #HANGUL SYLLABLE SSANGCIEUC WE IEUNG
+0xA86E 0xCB96 #HANGUL SYLLABLE SSANGCIEUC WE CIEUC
+0xA86F 0xCB97 #HANGUL SYLLABLE SSANGCIEUC WE CHIEUCH
+0xA870 0xCB98 #HANGUL SYLLABLE SSANGCIEUC WE KHIEUKH
+0xA871 0xCB99 #HANGUL SYLLABLE SSANGCIEUC WE THIEUTH
+0xA872 0xCB9A #HANGUL SYLLABLE SSANGCIEUC WE PHIEUPH
+0xA873 0xCB9B #HANGUL SYLLABLE SSANGCIEUC WE HIEUH
+0xA874 0xCB9D #HANGUL SYLLABLE SSANGCIEUC WI KIYEOK
+0xA875 0xCB9E #HANGUL SYLLABLE SSANGCIEUC WI SSANGKIYEOK
+0xA876 0xCB9F #HANGUL SYLLABLE SSANGCIEUC WI KIYEOKSIOS
+0xA877 0xCBA0 #HANGUL SYLLABLE SSANGCIEUC WI NIEUN
+0xA878 0xCBA1 #HANGUL SYLLABLE SSANGCIEUC WI NIEUNCIEUC
+0xA879 0xCBA2 #HANGUL SYLLABLE SSANGCIEUC WI NIEUNHIEUH
+0xA87A 0xCBA3 #HANGUL SYLLABLE SSANGCIEUC WI TIKEUT
+0xA881 0xCBA4 #HANGUL SYLLABLE SSANGCIEUC WI RIEUL
+0xA882 0xCBA5 #HANGUL SYLLABLE SSANGCIEUC WI RIEULKIYEOK
+0xA883 0xCBA6 #HANGUL SYLLABLE SSANGCIEUC WI RIEULMIEUM
+0xA884 0xCBA7 #HANGUL SYLLABLE SSANGCIEUC WI RIEULPIEUP
+0xA885 0xCBA8 #HANGUL SYLLABLE SSANGCIEUC WI RIEULSIOS
+0xA886 0xCBA9 #HANGUL SYLLABLE SSANGCIEUC WI RIEULTHIEUTH
+0xA887 0xCBAA #HANGUL SYLLABLE SSANGCIEUC WI RIEULPHIEUPH
+0xA888 0xCBAB #HANGUL SYLLABLE SSANGCIEUC WI RIEULHIEUH
+0xA889 0xCBAC #HANGUL SYLLABLE SSANGCIEUC WI MIEUM
+0xA88A 0xCBAD #HANGUL SYLLABLE SSANGCIEUC WI PIEUP
+0xA88B 0xCBAE #HANGUL SYLLABLE SSANGCIEUC WI PIEUPSIOS
+0xA88C 0xCBAF #HANGUL SYLLABLE SSANGCIEUC WI SIOS
+0xA88D 0xCBB0 #HANGUL SYLLABLE SSANGCIEUC WI SSANGSIOS
+0xA88E 0xCBB1 #HANGUL SYLLABLE SSANGCIEUC WI IEUNG
+0xA88F 0xCBB2 #HANGUL SYLLABLE SSANGCIEUC WI CIEUC
+0xA890 0xCBB3 #HANGUL SYLLABLE SSANGCIEUC WI CHIEUCH
+0xA891 0xCBB4 #HANGUL SYLLABLE SSANGCIEUC WI KHIEUKH
+0xA892 0xCBB5 #HANGUL SYLLABLE SSANGCIEUC WI THIEUTH
+0xA893 0xCBB6 #HANGUL SYLLABLE SSANGCIEUC WI PHIEUPH
+0xA894 0xCBB7 #HANGUL SYLLABLE SSANGCIEUC WI HIEUH
+0xA895 0xCBB9 #HANGUL SYLLABLE SSANGCIEUC YU KIYEOK
+0xA896 0xCBBA #HANGUL SYLLABLE SSANGCIEUC YU SSANGKIYEOK
+0xA897 0xCBBB #HANGUL SYLLABLE SSANGCIEUC YU KIYEOKSIOS
+0xA898 0xCBBC #HANGUL SYLLABLE SSANGCIEUC YU NIEUN
+0xA899 0xCBBD #HANGUL SYLLABLE SSANGCIEUC YU NIEUNCIEUC
+0xA89A 0xCBBE #HANGUL SYLLABLE SSANGCIEUC YU NIEUNHIEUH
+0xA89B 0xCBBF #HANGUL SYLLABLE SSANGCIEUC YU TIKEUT
+0xA89C 0xCBC0 #HANGUL SYLLABLE SSANGCIEUC YU RIEUL
+0xA89D 0xCBC1 #HANGUL SYLLABLE SSANGCIEUC YU RIEULKIYEOK
+0xA89E 0xCBC2 #HANGUL SYLLABLE SSANGCIEUC YU RIEULMIEUM
+0xA89F 0xCBC3 #HANGUL SYLLABLE SSANGCIEUC YU RIEULPIEUP
+0xA8A0 0xCBC4 #HANGUL SYLLABLE SSANGCIEUC YU RIEULSIOS
+0xA8A1 0x00C6 #LATIN CAPITAL LETTER AE
+0xA8A2 0x00D0 #LATIN CAPITAL LETTER ETH
+0xA8A3 0x00AA #FEMININE ORDINAL INDICATOR
+0xA8A4 0x0126 #LATIN CAPITAL LETTER H WITH STROKE
+0xA8A6 0x0132 #LATIN CAPITAL LIGATURE IJ
+0xA8A8 0x013F #LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0xA8A9 0x0141 #LATIN CAPITAL LETTER L WITH STROKE
+0xA8AA 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE
+0xA8AB 0x0152 #LATIN CAPITAL LIGATURE OE
+0xA8AC 0x00BA #MASCULINE ORDINAL INDICATOR
+0xA8AD 0x00DE #LATIN CAPITAL LETTER THORN
+0xA8AE 0x0166 #LATIN CAPITAL LETTER T WITH STROKE
+0xA8AF 0x014A #LATIN CAPITAL LETTER ENG
+0xA8B1 0x3260 #CIRCLED HANGUL KIYEOK
+0xA8B2 0x3261 #CIRCLED HANGUL NIEUN
+0xA8B3 0x3262 #CIRCLED HANGUL TIKEUT
+0xA8B4 0x3263 #CIRCLED HANGUL RIEUL
+0xA8B5 0x3264 #CIRCLED HANGUL MIEUM
+0xA8B6 0x3265 #CIRCLED HANGUL PIEUP
+0xA8B7 0x3266 #CIRCLED HANGUL SIOS
+0xA8B8 0x3267 #CIRCLED HANGUL IEUNG
+0xA8B9 0x3268 #CIRCLED HANGUL CIEUC
+0xA8BA 0x3269 #CIRCLED HANGUL CHIEUCH
+0xA8BB 0x326A #CIRCLED HANGUL KHIEUKH
+0xA8BC 0x326B #CIRCLED HANGUL THIEUTH
+0xA8BD 0x326C #CIRCLED HANGUL PHIEUPH
+0xA8BE 0x326D #CIRCLED HANGUL HIEUH
+0xA8BF 0x326E #CIRCLED HANGUL KIYEOK A
+0xA8C0 0x326F #CIRCLED HANGUL NIEUN A
+0xA8C1 0x3270 #CIRCLED HANGUL TIKEUT A
+0xA8C2 0x3271 #CIRCLED HANGUL RIEUL A
+0xA8C3 0x3272 #CIRCLED HANGUL MIEUM A
+0xA8C4 0x3273 #CIRCLED HANGUL PIEUP A
+0xA8C5 0x3274 #CIRCLED HANGUL SIOS A
+0xA8C6 0x3275 #CIRCLED HANGUL IEUNG A
+0xA8C7 0x3276 #CIRCLED HANGUL CIEUC A
+0xA8C8 0x3277 #CIRCLED HANGUL CHIEUCH A
+0xA8C9 0x3278 #CIRCLED HANGUL KHIEUKH A
+0xA8CA 0x3279 #CIRCLED HANGUL THIEUTH A
+0xA8CB 0x327A #CIRCLED HANGUL PHIEUPH A
+0xA8CC 0x327B #CIRCLED HANGUL HIEUH A
+0xA8CD 0x24D0 #CIRCLED LATIN SMALL LETTER A
+0xA8CE 0x24D1 #CIRCLED LATIN SMALL LETTER B
+0xA8CF 0x24D2 #CIRCLED LATIN SMALL LETTER C
+0xA8D0 0x24D3 #CIRCLED LATIN SMALL LETTER D
+0xA8D1 0x24D4 #CIRCLED LATIN SMALL LETTER E
+0xA8D2 0x24D5 #CIRCLED LATIN SMALL LETTER F
+0xA8D3 0x24D6 #CIRCLED LATIN SMALL LETTER G
+0xA8D4 0x24D7 #CIRCLED LATIN SMALL LETTER H
+0xA8D5 0x24D8 #CIRCLED LATIN SMALL LETTER I
+0xA8D6 0x24D9 #CIRCLED LATIN SMALL LETTER J
+0xA8D7 0x24DA #CIRCLED LATIN SMALL LETTER K
+0xA8D8 0x24DB #CIRCLED LATIN SMALL LETTER L
+0xA8D9 0x24DC #CIRCLED LATIN SMALL LETTER M
+0xA8DA 0x24DD #CIRCLED LATIN SMALL LETTER N
+0xA8DB 0x24DE #CIRCLED LATIN SMALL LETTER O
+0xA8DC 0x24DF #CIRCLED LATIN SMALL LETTER P
+0xA8DD 0x24E0 #CIRCLED LATIN SMALL LETTER Q
+0xA8DE 0x24E1 #CIRCLED LATIN SMALL LETTER R
+0xA8DF 0x24E2 #CIRCLED LATIN SMALL LETTER S
+0xA8E0 0x24E3 #CIRCLED LATIN SMALL LETTER T
+0xA8E1 0x24E4 #CIRCLED LATIN SMALL LETTER U
+0xA8E2 0x24E5 #CIRCLED LATIN SMALL LETTER V
+0xA8E3 0x24E6 #CIRCLED LATIN SMALL LETTER W
+0xA8E4 0x24E7 #CIRCLED LATIN SMALL LETTER X
+0xA8E5 0x24E8 #CIRCLED LATIN SMALL LETTER Y
+0xA8E6 0x24E9 #CIRCLED LATIN SMALL LETTER Z
+0xA8E7 0x2460 #CIRCLED DIGIT ONE
+0xA8E8 0x2461 #CIRCLED DIGIT TWO
+0xA8E9 0x2462 #CIRCLED DIGIT THREE
+0xA8EA 0x2463 #CIRCLED DIGIT FOUR
+0xA8EB 0x2464 #CIRCLED DIGIT FIVE
+0xA8EC 0x2465 #CIRCLED DIGIT SIX
+0xA8ED 0x2466 #CIRCLED DIGIT SEVEN
+0xA8EE 0x2467 #CIRCLED DIGIT EIGHT
+0xA8EF 0x2468 #CIRCLED DIGIT NINE
+0xA8F0 0x2469 #CIRCLED NUMBER TEN
+0xA8F1 0x246A #CIRCLED NUMBER ELEVEN
+0xA8F2 0x246B #CIRCLED NUMBER TWELVE
+0xA8F3 0x246C #CIRCLED NUMBER THIRTEEN
+0xA8F4 0x246D #CIRCLED NUMBER FOURTEEN
+0xA8F5 0x246E #CIRCLED NUMBER FIFTEEN
+0xA8F6 0x00BD #VULGAR FRACTION ONE HALF
+0xA8F7 0x2153 #VULGAR FRACTION ONE THIRD
+0xA8F8 0x2154 #VULGAR FRACTION TWO THIRDS
+0xA8F9 0x00BC #VULGAR FRACTION ONE QUARTER
+0xA8FA 0x00BE #VULGAR FRACTION THREE QUARTERS
+0xA8FB 0x215B #VULGAR FRACTION ONE EIGHTH
+0xA8FC 0x215C #VULGAR FRACTION THREE EIGHTHS
+0xA8FD 0x215D #VULGAR FRACTION FIVE EIGHTHS
+0xA8FE 0x215E #VULGAR FRACTION SEVEN EIGHTHS
+0xA941 0xCBC5 #HANGUL SYLLABLE SSANGCIEUC YU RIEULTHIEUTH
+0xA942 0xCBC6 #HANGUL SYLLABLE SSANGCIEUC YU RIEULPHIEUPH
+0xA943 0xCBC7 #HANGUL SYLLABLE SSANGCIEUC YU RIEULHIEUH
+0xA944 0xCBC8 #HANGUL SYLLABLE SSANGCIEUC YU MIEUM
+0xA945 0xCBC9 #HANGUL SYLLABLE SSANGCIEUC YU PIEUP
+0xA946 0xCBCA #HANGUL SYLLABLE SSANGCIEUC YU PIEUPSIOS
+0xA947 0xCBCB #HANGUL SYLLABLE SSANGCIEUC YU SIOS
+0xA948 0xCBCC #HANGUL SYLLABLE SSANGCIEUC YU SSANGSIOS
+0xA949 0xCBCD #HANGUL SYLLABLE SSANGCIEUC YU IEUNG
+0xA94A 0xCBCE #HANGUL SYLLABLE SSANGCIEUC YU CIEUC
+0xA94B 0xCBCF #HANGUL SYLLABLE SSANGCIEUC YU CHIEUCH
+0xA94C 0xCBD0 #HANGUL SYLLABLE SSANGCIEUC YU KHIEUKH
+0xA94D 0xCBD1 #HANGUL SYLLABLE SSANGCIEUC YU THIEUTH
+0xA94E 0xCBD2 #HANGUL SYLLABLE SSANGCIEUC YU PHIEUPH
+0xA94F 0xCBD3 #HANGUL SYLLABLE SSANGCIEUC YU HIEUH
+0xA950 0xCBD5 #HANGUL SYLLABLE SSANGCIEUC EU KIYEOK
+0xA951 0xCBD6 #HANGUL SYLLABLE SSANGCIEUC EU SSANGKIYEOK
+0xA952 0xCBD7 #HANGUL SYLLABLE SSANGCIEUC EU KIYEOKSIOS
+0xA953 0xCBD8 #HANGUL SYLLABLE SSANGCIEUC EU NIEUN
+0xA954 0xCBD9 #HANGUL SYLLABLE SSANGCIEUC EU NIEUNCIEUC
+0xA955 0xCBDA #HANGUL SYLLABLE SSANGCIEUC EU NIEUNHIEUH
+0xA956 0xCBDB #HANGUL SYLLABLE SSANGCIEUC EU TIKEUT
+0xA957 0xCBDC #HANGUL SYLLABLE SSANGCIEUC EU RIEUL
+0xA958 0xCBDD #HANGUL SYLLABLE SSANGCIEUC EU RIEULKIYEOK
+0xA959 0xCBDE #HANGUL SYLLABLE SSANGCIEUC EU RIEULMIEUM
+0xA95A 0xCBDF #HANGUL SYLLABLE SSANGCIEUC EU RIEULPIEUP
+0xA961 0xCBE0 #HANGUL SYLLABLE SSANGCIEUC EU RIEULSIOS
+0xA962 0xCBE1 #HANGUL SYLLABLE SSANGCIEUC EU RIEULTHIEUTH
+0xA963 0xCBE2 #HANGUL SYLLABLE SSANGCIEUC EU RIEULPHIEUPH
+0xA964 0xCBE3 #HANGUL SYLLABLE SSANGCIEUC EU RIEULHIEUH
+0xA965 0xCBE5 #HANGUL SYLLABLE SSANGCIEUC EU PIEUP
+0xA966 0xCBE6 #HANGUL SYLLABLE SSANGCIEUC EU PIEUPSIOS
+0xA967 0xCBE8 #HANGUL SYLLABLE SSANGCIEUC EU SSANGSIOS
+0xA968 0xCBEA #HANGUL SYLLABLE SSANGCIEUC EU CIEUC
+0xA969 0xCBEB #HANGUL SYLLABLE SSANGCIEUC EU CHIEUCH
+0xA96A 0xCBEC #HANGUL SYLLABLE SSANGCIEUC EU KHIEUKH
+0xA96B 0xCBED #HANGUL SYLLABLE SSANGCIEUC EU THIEUTH
+0xA96C 0xCBEE #HANGUL SYLLABLE SSANGCIEUC EU PHIEUPH
+0xA96D 0xCBEF #HANGUL SYLLABLE SSANGCIEUC EU HIEUH
+0xA96E 0xCBF0 #HANGUL SYLLABLE SSANGCIEUC YI
+0xA96F 0xCBF1 #HANGUL SYLLABLE SSANGCIEUC YI KIYEOK
+0xA970 0xCBF2 #HANGUL SYLLABLE SSANGCIEUC YI SSANGKIYEOK
+0xA971 0xCBF3 #HANGUL SYLLABLE SSANGCIEUC YI KIYEOKSIOS
+0xA972 0xCBF4 #HANGUL SYLLABLE SSANGCIEUC YI NIEUN
+0xA973 0xCBF5 #HANGUL SYLLABLE SSANGCIEUC YI NIEUNCIEUC
+0xA974 0xCBF6 #HANGUL SYLLABLE SSANGCIEUC YI NIEUNHIEUH
+0xA975 0xCBF7 #HANGUL SYLLABLE SSANGCIEUC YI TIKEUT
+0xA976 0xCBF8 #HANGUL SYLLABLE SSANGCIEUC YI RIEUL
+0xA977 0xCBF9 #HANGUL SYLLABLE SSANGCIEUC YI RIEULKIYEOK
+0xA978 0xCBFA #HANGUL SYLLABLE SSANGCIEUC YI RIEULMIEUM
+0xA979 0xCBFB #HANGUL SYLLABLE SSANGCIEUC YI RIEULPIEUP
+0xA97A 0xCBFC #HANGUL SYLLABLE SSANGCIEUC YI RIEULSIOS
+0xA981 0xCBFD #HANGUL SYLLABLE SSANGCIEUC YI RIEULTHIEUTH
+0xA982 0xCBFE #HANGUL SYLLABLE SSANGCIEUC YI RIEULPHIEUPH
+0xA983 0xCBFF #HANGUL SYLLABLE SSANGCIEUC YI RIEULHIEUH
+0xA984 0xCC00 #HANGUL SYLLABLE SSANGCIEUC YI MIEUM
+0xA985 0xCC01 #HANGUL SYLLABLE SSANGCIEUC YI PIEUP
+0xA986 0xCC02 #HANGUL SYLLABLE SSANGCIEUC YI PIEUPSIOS
+0xA987 0xCC03 #HANGUL SYLLABLE SSANGCIEUC YI SIOS
+0xA988 0xCC04 #HANGUL SYLLABLE SSANGCIEUC YI SSANGSIOS
+0xA989 0xCC05 #HANGUL SYLLABLE SSANGCIEUC YI IEUNG
+0xA98A 0xCC06 #HANGUL SYLLABLE SSANGCIEUC YI CIEUC
+0xA98B 0xCC07 #HANGUL SYLLABLE SSANGCIEUC YI CHIEUCH
+0xA98C 0xCC08 #HANGUL SYLLABLE SSANGCIEUC YI KHIEUKH
+0xA98D 0xCC09 #HANGUL SYLLABLE SSANGCIEUC YI THIEUTH
+0xA98E 0xCC0A #HANGUL SYLLABLE SSANGCIEUC YI PHIEUPH
+0xA98F 0xCC0B #HANGUL SYLLABLE SSANGCIEUC YI HIEUH
+0xA990 0xCC0E #HANGUL SYLLABLE SSANGCIEUC I SSANGKIYEOK
+0xA991 0xCC0F #HANGUL SYLLABLE SSANGCIEUC I KIYEOKSIOS
+0xA992 0xCC11 #HANGUL SYLLABLE SSANGCIEUC I NIEUNCIEUC
+0xA993 0xCC12 #HANGUL SYLLABLE SSANGCIEUC I NIEUNHIEUH
+0xA994 0xCC13 #HANGUL SYLLABLE SSANGCIEUC I TIKEUT
+0xA995 0xCC15 #HANGUL SYLLABLE SSANGCIEUC I RIEULKIYEOK
+0xA996 0xCC16 #HANGUL SYLLABLE SSANGCIEUC I RIEULMIEUM
+0xA997 0xCC17 #HANGUL SYLLABLE SSANGCIEUC I RIEULPIEUP
+0xA998 0xCC18 #HANGUL SYLLABLE SSANGCIEUC I RIEULSIOS
+0xA999 0xCC19 #HANGUL SYLLABLE SSANGCIEUC I RIEULTHIEUTH
+0xA99A 0xCC1A #HANGUL SYLLABLE SSANGCIEUC I RIEULPHIEUPH
+0xA99B 0xCC1B #HANGUL SYLLABLE SSANGCIEUC I RIEULHIEUH
+0xA99C 0xCC1E #HANGUL SYLLABLE SSANGCIEUC I PIEUPSIOS
+0xA99D 0xCC1F #HANGUL SYLLABLE SSANGCIEUC I SIOS
+0xA99E 0xCC20 #HANGUL SYLLABLE SSANGCIEUC I SSANGSIOS
+0xA99F 0xCC23 #HANGUL SYLLABLE SSANGCIEUC I CHIEUCH
+0xA9A0 0xCC24 #HANGUL SYLLABLE SSANGCIEUC I KHIEUKH
+0xA9A1 0x00E6 #LATIN SMALL LETTER AE
+0xA9A2 0x0111 #LATIN SMALL LETTER D WITH STROKE
+0xA9A3 0x00F0 #LATIN SMALL LETTER ETH
+0xA9A4 0x0127 #LATIN SMALL LETTER H WITH STROKE
+0xA9A5 0x0131 #LATIN SMALL LETTER DOTLESS I
+0xA9A6 0x0133 #LATIN SMALL LIGATURE IJ
+0xA9A7 0x0138 #LATIN SMALL LETTER KRA
+0xA9A8 0x0140 #LATIN SMALL LETTER L WITH MIDDLE DOT
+0xA9A9 0x0142 #LATIN SMALL LETTER L WITH STROKE
+0xA9AA 0x00F8 #LATIN SMALL LETTER O WITH STROKE
+0xA9AB 0x0153 #LATIN SMALL LIGATURE OE
+0xA9AC 0x00DF #LATIN SMALL LETTER SHARP S
+0xA9AD 0x00FE #LATIN SMALL LETTER THORN
+0xA9AE 0x0167 #LATIN SMALL LETTER T WITH STROKE
+0xA9AF 0x014B #LATIN SMALL LETTER ENG
+0xA9B0 0x0149 #LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0xA9B1 0x3200 #PARENTHESIZED HANGUL KIYEOK
+0xA9B2 0x3201 #PARENTHESIZED HANGUL NIEUN
+0xA9B3 0x3202 #PARENTHESIZED HANGUL TIKEUT
+0xA9B4 0x3203 #PARENTHESIZED HANGUL RIEUL
+0xA9B5 0x3204 #PARENTHESIZED HANGUL MIEUM
+0xA9B6 0x3205 #PARENTHESIZED HANGUL PIEUP
+0xA9B7 0x3206 #PARENTHESIZED HANGUL SIOS
+0xA9B8 0x3207 #PARENTHESIZED HANGUL IEUNG
+0xA9B9 0x3208 #PARENTHESIZED HANGUL CIEUC
+0xA9BA 0x3209 #PARENTHESIZED HANGUL CHIEUCH
+0xA9BB 0x320A #PARENTHESIZED HANGUL KHIEUKH
+0xA9BC 0x320B #PARENTHESIZED HANGUL THIEUTH
+0xA9BD 0x320C #PARENTHESIZED HANGUL PHIEUPH
+0xA9BE 0x320D #PARENTHESIZED HANGUL HIEUH
+0xA9BF 0x320E #PARENTHESIZED HANGUL KIYEOK A
+0xA9C0 0x320F #PARENTHESIZED HANGUL NIEUN A
+0xA9C1 0x3210 #PARENTHESIZED HANGUL TIKEUT A
+0xA9C2 0x3211 #PARENTHESIZED HANGUL RIEUL A
+0xA9C3 0x3212 #PARENTHESIZED HANGUL MIEUM A
+0xA9C4 0x3213 #PARENTHESIZED HANGUL PIEUP A
+0xA9C5 0x3214 #PARENTHESIZED HANGUL SIOS A
+0xA9C6 0x3215 #PARENTHESIZED HANGUL IEUNG A
+0xA9C7 0x3216 #PARENTHESIZED HANGUL CIEUC A
+0xA9C8 0x3217 #PARENTHESIZED HANGUL CHIEUCH A
+0xA9C9 0x3218 #PARENTHESIZED HANGUL KHIEUKH A
+0xA9CA 0x3219 #PARENTHESIZED HANGUL THIEUTH A
+0xA9CB 0x321A #PARENTHESIZED HANGUL PHIEUPH A
+0xA9CC 0x321B #PARENTHESIZED HANGUL HIEUH A
+0xA9CD 0x249C #PARENTHESIZED LATIN SMALL LETTER A
+0xA9CE 0x249D #PARENTHESIZED LATIN SMALL LETTER B
+0xA9CF 0x249E #PARENTHESIZED LATIN SMALL LETTER C
+0xA9D0 0x249F #PARENTHESIZED LATIN SMALL LETTER D
+0xA9D1 0x24A0 #PARENTHESIZED LATIN SMALL LETTER E
+0xA9D2 0x24A1 #PARENTHESIZED LATIN SMALL LETTER F
+0xA9D3 0x24A2 #PARENTHESIZED LATIN SMALL LETTER G
+0xA9D4 0x24A3 #PARENTHESIZED LATIN SMALL LETTER H
+0xA9D5 0x24A4 #PARENTHESIZED LATIN SMALL LETTER I
+0xA9D6 0x24A5 #PARENTHESIZED LATIN SMALL LETTER J
+0xA9D7 0x24A6 #PARENTHESIZED LATIN SMALL LETTER K
+0xA9D8 0x24A7 #PARENTHESIZED LATIN SMALL LETTER L
+0xA9D9 0x24A8 #PARENTHESIZED LATIN SMALL LETTER M
+0xA9DA 0x24A9 #PARENTHESIZED LATIN SMALL LETTER N
+0xA9DB 0x24AA #PARENTHESIZED LATIN SMALL LETTER O
+0xA9DC 0x24AB #PARENTHESIZED LATIN SMALL LETTER P
+0xA9DD 0x24AC #PARENTHESIZED LATIN SMALL LETTER Q
+0xA9DE 0x24AD #PARENTHESIZED LATIN SMALL LETTER R
+0xA9DF 0x24AE #PARENTHESIZED LATIN SMALL LETTER S
+0xA9E0 0x24AF #PARENTHESIZED LATIN SMALL LETTER T
+0xA9E1 0x24B0 #PARENTHESIZED LATIN SMALL LETTER U
+0xA9E2 0x24B1 #PARENTHESIZED LATIN SMALL LETTER V
+0xA9E3 0x24B2 #PARENTHESIZED LATIN SMALL LETTER W
+0xA9E4 0x24B3 #PARENTHESIZED LATIN SMALL LETTER X
+0xA9E5 0x24B4 #PARENTHESIZED LATIN SMALL LETTER Y
+0xA9E6 0x24B5 #PARENTHESIZED LATIN SMALL LETTER Z
+0xA9E7 0x2474 #PARENTHESIZED DIGIT ONE
+0xA9E8 0x2475 #PARENTHESIZED DIGIT TWO
+0xA9E9 0x2476 #PARENTHESIZED DIGIT THREE
+0xA9EA 0x2477 #PARENTHESIZED DIGIT FOUR
+0xA9EB 0x2478 #PARENTHESIZED DIGIT FIVE
+0xA9EC 0x2479 #PARENTHESIZED DIGIT SIX
+0xA9ED 0x247A #PARENTHESIZED DIGIT SEVEN
+0xA9EE 0x247B #PARENTHESIZED DIGIT EIGHT
+0xA9EF 0x247C #PARENTHESIZED DIGIT NINE
+0xA9F0 0x247D #PARENTHESIZED NUMBER TEN
+0xA9F1 0x247E #PARENTHESIZED NUMBER ELEVEN
+0xA9F2 0x247F #PARENTHESIZED NUMBER TWELVE
+0xA9F3 0x2480 #PARENTHESIZED NUMBER THIRTEEN
+0xA9F4 0x2481 #PARENTHESIZED NUMBER FOURTEEN
+0xA9F5 0x2482 #PARENTHESIZED NUMBER FIFTEEN
+0xA9F6 0x00B9 #SUPERSCRIPT ONE
+0xA9F7 0x00B2 #SUPERSCRIPT TWO
+0xA9F8 0x00B3 #SUPERSCRIPT THREE
+0xA9F9 0x2074 #SUPERSCRIPT FOUR
+0xA9FA 0x207F #SUPERSCRIPT LATIN SMALL LETTER N
+0xA9FB 0x2081 #SUBSCRIPT ONE
+0xA9FC 0x2082 #SUBSCRIPT TWO
+0xA9FD 0x2083 #SUBSCRIPT THREE
+0xA9FE 0x2084 #SUBSCRIPT FOUR
+0xAA41 0xCC25 #HANGUL SYLLABLE SSANGCIEUC I THIEUTH
+0xAA42 0xCC26 #HANGUL SYLLABLE SSANGCIEUC I PHIEUPH
+0xAA43 0xCC2A #HANGUL SYLLABLE CHIEUCH A SSANGKIYEOK
+0xAA44 0xCC2B #HANGUL SYLLABLE CHIEUCH A KIYEOKSIOS
+0xAA45 0xCC2D #HANGUL SYLLABLE CHIEUCH A NIEUNCIEUC
+0xAA46 0xCC2F #HANGUL SYLLABLE CHIEUCH A TIKEUT
+0xAA47 0xCC31 #HANGUL SYLLABLE CHIEUCH A RIEULKIYEOK
+0xAA48 0xCC32 #HANGUL SYLLABLE CHIEUCH A RIEULMIEUM
+0xAA49 0xCC33 #HANGUL SYLLABLE CHIEUCH A RIEULPIEUP
+0xAA4A 0xCC34 #HANGUL SYLLABLE CHIEUCH A RIEULSIOS
+0xAA4B 0xCC35 #HANGUL SYLLABLE CHIEUCH A RIEULTHIEUTH
+0xAA4C 0xCC36 #HANGUL SYLLABLE CHIEUCH A RIEULPHIEUPH
+0xAA4D 0xCC37 #HANGUL SYLLABLE CHIEUCH A RIEULHIEUH
+0xAA4E 0xCC3A #HANGUL SYLLABLE CHIEUCH A PIEUPSIOS
+0xAA4F 0xCC3F #HANGUL SYLLABLE CHIEUCH A CHIEUCH
+0xAA50 0xCC40 #HANGUL SYLLABLE CHIEUCH A KHIEUKH
+0xAA51 0xCC41 #HANGUL SYLLABLE CHIEUCH A THIEUTH
+0xAA52 0xCC42 #HANGUL SYLLABLE CHIEUCH A PHIEUPH
+0xAA53 0xCC43 #HANGUL SYLLABLE CHIEUCH A HIEUH
+0xAA54 0xCC46 #HANGUL SYLLABLE CHIEUCH AE SSANGKIYEOK
+0xAA55 0xCC47 #HANGUL SYLLABLE CHIEUCH AE KIYEOKSIOS
+0xAA56 0xCC49 #HANGUL SYLLABLE CHIEUCH AE NIEUNCIEUC
+0xAA57 0xCC4A #HANGUL SYLLABLE CHIEUCH AE NIEUNHIEUH
+0xAA58 0xCC4B #HANGUL SYLLABLE CHIEUCH AE TIKEUT
+0xAA59 0xCC4D #HANGUL SYLLABLE CHIEUCH AE RIEULKIYEOK
+0xAA5A 0xCC4E #HANGUL SYLLABLE CHIEUCH AE RIEULMIEUM
+0xAA61 0xCC4F #HANGUL SYLLABLE CHIEUCH AE RIEULPIEUP
+0xAA62 0xCC50 #HANGUL SYLLABLE CHIEUCH AE RIEULSIOS
+0xAA63 0xCC51 #HANGUL SYLLABLE CHIEUCH AE RIEULTHIEUTH
+0xAA64 0xCC52 #HANGUL SYLLABLE CHIEUCH AE RIEULPHIEUPH
+0xAA65 0xCC53 #HANGUL SYLLABLE CHIEUCH AE RIEULHIEUH
+0xAA66 0xCC56 #HANGUL SYLLABLE CHIEUCH AE PIEUPSIOS
+0xAA67 0xCC5A #HANGUL SYLLABLE CHIEUCH AE CIEUC
+0xAA68 0xCC5B #HANGUL SYLLABLE CHIEUCH AE CHIEUCH
+0xAA69 0xCC5C #HANGUL SYLLABLE CHIEUCH AE KHIEUKH
+0xAA6A 0xCC5D #HANGUL SYLLABLE CHIEUCH AE THIEUTH
+0xAA6B 0xCC5E #HANGUL SYLLABLE CHIEUCH AE PHIEUPH
+0xAA6C 0xCC5F #HANGUL SYLLABLE CHIEUCH AE HIEUH
+0xAA6D 0xCC61 #HANGUL SYLLABLE CHIEUCH YA KIYEOK
+0xAA6E 0xCC62 #HANGUL SYLLABLE CHIEUCH YA SSANGKIYEOK
+0xAA6F 0xCC63 #HANGUL SYLLABLE CHIEUCH YA KIYEOKSIOS
+0xAA70 0xCC65 #HANGUL SYLLABLE CHIEUCH YA NIEUNCIEUC
+0xAA71 0xCC67 #HANGUL SYLLABLE CHIEUCH YA TIKEUT
+0xAA72 0xCC69 #HANGUL SYLLABLE CHIEUCH YA RIEULKIYEOK
+0xAA73 0xCC6A #HANGUL SYLLABLE CHIEUCH YA RIEULMIEUM
+0xAA74 0xCC6B #HANGUL SYLLABLE CHIEUCH YA RIEULPIEUP
+0xAA75 0xCC6C #HANGUL SYLLABLE CHIEUCH YA RIEULSIOS
+0xAA76 0xCC6D #HANGUL SYLLABLE CHIEUCH YA RIEULTHIEUTH
+0xAA77 0xCC6E #HANGUL SYLLABLE CHIEUCH YA RIEULPHIEUPH
+0xAA78 0xCC6F #HANGUL SYLLABLE CHIEUCH YA RIEULHIEUH
+0xAA79 0xCC71 #HANGUL SYLLABLE CHIEUCH YA PIEUP
+0xAA7A 0xCC72 #HANGUL SYLLABLE CHIEUCH YA PIEUPSIOS
+0xAA81 0xCC73 #HANGUL SYLLABLE CHIEUCH YA SIOS
+0xAA82 0xCC74 #HANGUL SYLLABLE CHIEUCH YA SSANGSIOS
+0xAA83 0xCC76 #HANGUL SYLLABLE CHIEUCH YA CIEUC
+0xAA84 0xCC77 #HANGUL SYLLABLE CHIEUCH YA CHIEUCH
+0xAA85 0xCC78 #HANGUL SYLLABLE CHIEUCH YA KHIEUKH
+0xAA86 0xCC79 #HANGUL SYLLABLE CHIEUCH YA THIEUTH
+0xAA87 0xCC7A #HANGUL SYLLABLE CHIEUCH YA PHIEUPH
+0xAA88 0xCC7B #HANGUL SYLLABLE CHIEUCH YA HIEUH
+0xAA89 0xCC7C #HANGUL SYLLABLE CHIEUCH YAE
+0xAA8A 0xCC7D #HANGUL SYLLABLE CHIEUCH YAE KIYEOK
+0xAA8B 0xCC7E #HANGUL SYLLABLE CHIEUCH YAE SSANGKIYEOK
+0xAA8C 0xCC7F #HANGUL SYLLABLE CHIEUCH YAE KIYEOKSIOS
+0xAA8D 0xCC80 #HANGUL SYLLABLE CHIEUCH YAE NIEUN
+0xAA8E 0xCC81 #HANGUL SYLLABLE CHIEUCH YAE NIEUNCIEUC
+0xAA8F 0xCC82 #HANGUL SYLLABLE CHIEUCH YAE NIEUNHIEUH
+0xAA90 0xCC83 #HANGUL SYLLABLE CHIEUCH YAE TIKEUT
+0xAA91 0xCC84 #HANGUL SYLLABLE CHIEUCH YAE RIEUL
+0xAA92 0xCC85 #HANGUL SYLLABLE CHIEUCH YAE RIEULKIYEOK
+0xAA93 0xCC86 #HANGUL SYLLABLE CHIEUCH YAE RIEULMIEUM
+0xAA94 0xCC87 #HANGUL SYLLABLE CHIEUCH YAE RIEULPIEUP
+0xAA95 0xCC88 #HANGUL SYLLABLE CHIEUCH YAE RIEULSIOS
+0xAA96 0xCC89 #HANGUL SYLLABLE CHIEUCH YAE RIEULTHIEUTH
+0xAA97 0xCC8A #HANGUL SYLLABLE CHIEUCH YAE RIEULPHIEUPH
+0xAA98 0xCC8B #HANGUL SYLLABLE CHIEUCH YAE RIEULHIEUH
+0xAA99 0xCC8C #HANGUL SYLLABLE CHIEUCH YAE MIEUM
+0xAA9A 0xCC8D #HANGUL SYLLABLE CHIEUCH YAE PIEUP
+0xAA9B 0xCC8E #HANGUL SYLLABLE CHIEUCH YAE PIEUPSIOS
+0xAA9C 0xCC8F #HANGUL SYLLABLE CHIEUCH YAE SIOS
+0xAA9D 0xCC90 #HANGUL SYLLABLE CHIEUCH YAE SSANGSIOS
+0xAA9E 0xCC91 #HANGUL SYLLABLE CHIEUCH YAE IEUNG
+0xAA9F 0xCC92 #HANGUL SYLLABLE CHIEUCH YAE CIEUC
+0xAAA0 0xCC93 #HANGUL SYLLABLE CHIEUCH YAE CHIEUCH
+0xAAA1 0x3041 #HIRAGANA LETTER SMALL A
+0xAAA2 0x3042 #HIRAGANA LETTER A
+0xAAA3 0x3043 #HIRAGANA LETTER SMALL I
+0xAAA4 0x3044 #HIRAGANA LETTER I
+0xAAA5 0x3045 #HIRAGANA LETTER SMALL U
+0xAAA6 0x3046 #HIRAGANA LETTER U
+0xAAA7 0x3047 #HIRAGANA LETTER SMALL E
+0xAAA8 0x3048 #HIRAGANA LETTER E
+0xAAA9 0x3049 #HIRAGANA LETTER SMALL O
+0xAAAA 0x304A #HIRAGANA LETTER O
+0xAAAB 0x304B #HIRAGANA LETTER KA
+0xAAAC 0x304C #HIRAGANA LETTER GA
+0xAAAD 0x304D #HIRAGANA LETTER KI
+0xAAAE 0x304E #HIRAGANA LETTER GI
+0xAAAF 0x304F #HIRAGANA LETTER KU
+0xAAB0 0x3050 #HIRAGANA LETTER GU
+0xAAB1 0x3051 #HIRAGANA LETTER KE
+0xAAB2 0x3052 #HIRAGANA LETTER GE
+0xAAB3 0x3053 #HIRAGANA LETTER KO
+0xAAB4 0x3054 #HIRAGANA LETTER GO
+0xAAB5 0x3055 #HIRAGANA LETTER SA
+0xAAB6 0x3056 #HIRAGANA LETTER ZA
+0xAAB7 0x3057 #HIRAGANA LETTER SI
+0xAAB8 0x3058 #HIRAGANA LETTER ZI
+0xAAB9 0x3059 #HIRAGANA LETTER SU
+0xAABA 0x305A #HIRAGANA LETTER ZU
+0xAABB 0x305B #HIRAGANA LETTER SE
+0xAABC 0x305C #HIRAGANA LETTER ZE
+0xAABD 0x305D #HIRAGANA LETTER SO
+0xAABE 0x305E #HIRAGANA LETTER ZO
+0xAABF 0x305F #HIRAGANA LETTER TA
+0xAAC0 0x3060 #HIRAGANA LETTER DA
+0xAAC1 0x3061 #HIRAGANA LETTER TI
+0xAAC2 0x3062 #HIRAGANA LETTER DI
+0xAAC3 0x3063 #HIRAGANA LETTER SMALL TU
+0xAAC4 0x3064 #HIRAGANA LETTER TU
+0xAAC5 0x3065 #HIRAGANA LETTER DU
+0xAAC6 0x3066 #HIRAGANA LETTER TE
+0xAAC7 0x3067 #HIRAGANA LETTER DE
+0xAAC8 0x3068 #HIRAGANA LETTER TO
+0xAAC9 0x3069 #HIRAGANA LETTER DO
+0xAACA 0x306A #HIRAGANA LETTER NA
+0xAACB 0x306B #HIRAGANA LETTER NI
+0xAACC 0x306C #HIRAGANA LETTER NU
+0xAACD 0x306D #HIRAGANA LETTER NE
+0xAACE 0x306E #HIRAGANA LETTER NO
+0xAACF 0x306F #HIRAGANA LETTER HA
+0xAAD0 0x3070 #HIRAGANA LETTER BA
+0xAAD1 0x3071 #HIRAGANA LETTER PA
+0xAAD2 0x3072 #HIRAGANA LETTER HI
+0xAAD3 0x3073 #HIRAGANA LETTER BI
+0xAAD4 0x3074 #HIRAGANA LETTER PI
+0xAAD5 0x3075 #HIRAGANA LETTER HU
+0xAAD6 0x3076 #HIRAGANA LETTER BU
+0xAAD7 0x3077 #HIRAGANA LETTER PU
+0xAAD8 0x3078 #HIRAGANA LETTER HE
+0xAAD9 0x3079 #HIRAGANA LETTER BE
+0xAADA 0x307A #HIRAGANA LETTER PE
+0xAADB 0x307B #HIRAGANA LETTER HO
+0xAADC 0x307C #HIRAGANA LETTER BO
+0xAADD 0x307D #HIRAGANA LETTER PO
+0xAADE 0x307E #HIRAGANA LETTER MA
+0xAADF 0x307F #HIRAGANA LETTER MI
+0xAAE0 0x3080 #HIRAGANA LETTER MU
+0xAAE1 0x3081 #HIRAGANA LETTER ME
+0xAAE2 0x3082 #HIRAGANA LETTER MO
+0xAAE3 0x3083 #HIRAGANA LETTER SMALL YA
+0xAAE4 0x3084 #HIRAGANA LETTER YA
+0xAAE5 0x3085 #HIRAGANA LETTER SMALL YU
+0xAAE6 0x3086 #HIRAGANA LETTER YU
+0xAAE7 0x3087 #HIRAGANA LETTER SMALL YO
+0xAAE8 0x3088 #HIRAGANA LETTER YO
+0xAAE9 0x3089 #HIRAGANA LETTER RA
+0xAAEA 0x308A #HIRAGANA LETTER RI
+0xAAEB 0x308B #HIRAGANA LETTER RU
+0xAAEC 0x308C #HIRAGANA LETTER RE
+0xAAED 0x308D #HIRAGANA LETTER RO
+0xAAEE 0x308E #HIRAGANA LETTER SMALL WA
+0xAAEF 0x308F #HIRAGANA LETTER WA
+0xAAF0 0x3090 #HIRAGANA LETTER WI
+0xAAF1 0x3091 #HIRAGANA LETTER WE
+0xAAF2 0x3092 #HIRAGANA LETTER WO
+0xAAF3 0x3093 #HIRAGANA LETTER N
+0xAB41 0xCC94 #HANGUL SYLLABLE CHIEUCH YAE KHIEUKH
+0xAB42 0xCC95 #HANGUL SYLLABLE CHIEUCH YAE THIEUTH
+0xAB43 0xCC96 #HANGUL SYLLABLE CHIEUCH YAE PHIEUPH
+0xAB44 0xCC97 #HANGUL SYLLABLE CHIEUCH YAE HIEUH
+0xAB45 0xCC9A #HANGUL SYLLABLE CHIEUCH EO SSANGKIYEOK
+0xAB46 0xCC9B #HANGUL SYLLABLE CHIEUCH EO KIYEOKSIOS
+0xAB47 0xCC9D #HANGUL SYLLABLE CHIEUCH EO NIEUNCIEUC
+0xAB48 0xCC9E #HANGUL SYLLABLE CHIEUCH EO NIEUNHIEUH
+0xAB49 0xCC9F #HANGUL SYLLABLE CHIEUCH EO TIKEUT
+0xAB4A 0xCCA1 #HANGUL SYLLABLE CHIEUCH EO RIEULKIYEOK
+0xAB4B 0xCCA2 #HANGUL SYLLABLE CHIEUCH EO RIEULMIEUM
+0xAB4C 0xCCA3 #HANGUL SYLLABLE CHIEUCH EO RIEULPIEUP
+0xAB4D 0xCCA4 #HANGUL SYLLABLE CHIEUCH EO RIEULSIOS
+0xAB4E 0xCCA5 #HANGUL SYLLABLE CHIEUCH EO RIEULTHIEUTH
+0xAB4F 0xCCA6 #HANGUL SYLLABLE CHIEUCH EO RIEULPHIEUPH
+0xAB50 0xCCA7 #HANGUL SYLLABLE CHIEUCH EO RIEULHIEUH
+0xAB51 0xCCAA #HANGUL SYLLABLE CHIEUCH EO PIEUPSIOS
+0xAB52 0xCCAE #HANGUL SYLLABLE CHIEUCH EO CIEUC
+0xAB53 0xCCAF #HANGUL SYLLABLE CHIEUCH EO CHIEUCH
+0xAB54 0xCCB0 #HANGUL SYLLABLE CHIEUCH EO KHIEUKH
+0xAB55 0xCCB1 #HANGUL SYLLABLE CHIEUCH EO THIEUTH
+0xAB56 0xCCB2 #HANGUL SYLLABLE CHIEUCH EO PHIEUPH
+0xAB57 0xCCB3 #HANGUL SYLLABLE CHIEUCH EO HIEUH
+0xAB58 0xCCB6 #HANGUL SYLLABLE CHIEUCH E SSANGKIYEOK
+0xAB59 0xCCB7 #HANGUL SYLLABLE CHIEUCH E KIYEOKSIOS
+0xAB5A 0xCCB9 #HANGUL SYLLABLE CHIEUCH E NIEUNCIEUC
+0xAB61 0xCCBA #HANGUL SYLLABLE CHIEUCH E NIEUNHIEUH
+0xAB62 0xCCBB #HANGUL SYLLABLE CHIEUCH E TIKEUT
+0xAB63 0xCCBD #HANGUL SYLLABLE CHIEUCH E RIEULKIYEOK
+0xAB64 0xCCBE #HANGUL SYLLABLE CHIEUCH E RIEULMIEUM
+0xAB65 0xCCBF #HANGUL SYLLABLE CHIEUCH E RIEULPIEUP
+0xAB66 0xCCC0 #HANGUL SYLLABLE CHIEUCH E RIEULSIOS
+0xAB67 0xCCC1 #HANGUL SYLLABLE CHIEUCH E RIEULTHIEUTH
+0xAB68 0xCCC2 #HANGUL SYLLABLE CHIEUCH E RIEULPHIEUPH
+0xAB69 0xCCC3 #HANGUL SYLLABLE CHIEUCH E RIEULHIEUH
+0xAB6A 0xCCC6 #HANGUL SYLLABLE CHIEUCH E PIEUPSIOS
+0xAB6B 0xCCC8 #HANGUL SYLLABLE CHIEUCH E SSANGSIOS
+0xAB6C 0xCCCA #HANGUL SYLLABLE CHIEUCH E CIEUC
+0xAB6D 0xCCCB #HANGUL SYLLABLE CHIEUCH E CHIEUCH
+0xAB6E 0xCCCC #HANGUL SYLLABLE CHIEUCH E KHIEUKH
+0xAB6F 0xCCCD #HANGUL SYLLABLE CHIEUCH E THIEUTH
+0xAB70 0xCCCE #HANGUL SYLLABLE CHIEUCH E PHIEUPH
+0xAB71 0xCCCF #HANGUL SYLLABLE CHIEUCH E HIEUH
+0xAB72 0xCCD1 #HANGUL SYLLABLE CHIEUCH YEO KIYEOK
+0xAB73 0xCCD2 #HANGUL SYLLABLE CHIEUCH YEO SSANGKIYEOK
+0xAB74 0xCCD3 #HANGUL SYLLABLE CHIEUCH YEO KIYEOKSIOS
+0xAB75 0xCCD5 #HANGUL SYLLABLE CHIEUCH YEO NIEUNCIEUC
+0xAB76 0xCCD6 #HANGUL SYLLABLE CHIEUCH YEO NIEUNHIEUH
+0xAB77 0xCCD7 #HANGUL SYLLABLE CHIEUCH YEO TIKEUT
+0xAB78 0xCCD8 #HANGUL SYLLABLE CHIEUCH YEO RIEUL
+0xAB79 0xCCD9 #HANGUL SYLLABLE CHIEUCH YEO RIEULKIYEOK
+0xAB7A 0xCCDA #HANGUL SYLLABLE CHIEUCH YEO RIEULMIEUM
+0xAB81 0xCCDB #HANGUL SYLLABLE CHIEUCH YEO RIEULPIEUP
+0xAB82 0xCCDC #HANGUL SYLLABLE CHIEUCH YEO RIEULSIOS
+0xAB83 0xCCDD #HANGUL SYLLABLE CHIEUCH YEO RIEULTHIEUTH
+0xAB84 0xCCDE #HANGUL SYLLABLE CHIEUCH YEO RIEULPHIEUPH
+0xAB85 0xCCDF #HANGUL SYLLABLE CHIEUCH YEO RIEULHIEUH
+0xAB86 0xCCE0 #HANGUL SYLLABLE CHIEUCH YEO MIEUM
+0xAB87 0xCCE1 #HANGUL SYLLABLE CHIEUCH YEO PIEUP
+0xAB88 0xCCE2 #HANGUL SYLLABLE CHIEUCH YEO PIEUPSIOS
+0xAB89 0xCCE3 #HANGUL SYLLABLE CHIEUCH YEO SIOS
+0xAB8A 0xCCE5 #HANGUL SYLLABLE CHIEUCH YEO IEUNG
+0xAB8B 0xCCE6 #HANGUL SYLLABLE CHIEUCH YEO CIEUC
+0xAB8C 0xCCE7 #HANGUL SYLLABLE CHIEUCH YEO CHIEUCH
+0xAB8D 0xCCE8 #HANGUL SYLLABLE CHIEUCH YEO KHIEUKH
+0xAB8E 0xCCE9 #HANGUL SYLLABLE CHIEUCH YEO THIEUTH
+0xAB8F 0xCCEA #HANGUL SYLLABLE CHIEUCH YEO PHIEUPH
+0xAB90 0xCCEB #HANGUL SYLLABLE CHIEUCH YEO HIEUH
+0xAB91 0xCCED #HANGUL SYLLABLE CHIEUCH YE KIYEOK
+0xAB92 0xCCEE #HANGUL SYLLABLE CHIEUCH YE SSANGKIYEOK
+0xAB93 0xCCEF #HANGUL SYLLABLE CHIEUCH YE KIYEOKSIOS
+0xAB94 0xCCF1 #HANGUL SYLLABLE CHIEUCH YE NIEUNCIEUC
+0xAB95 0xCCF2 #HANGUL SYLLABLE CHIEUCH YE NIEUNHIEUH
+0xAB96 0xCCF3 #HANGUL SYLLABLE CHIEUCH YE TIKEUT
+0xAB97 0xCCF4 #HANGUL SYLLABLE CHIEUCH YE RIEUL
+0xAB98 0xCCF5 #HANGUL SYLLABLE CHIEUCH YE RIEULKIYEOK
+0xAB99 0xCCF6 #HANGUL SYLLABLE CHIEUCH YE RIEULMIEUM
+0xAB9A 0xCCF7 #HANGUL SYLLABLE CHIEUCH YE RIEULPIEUP
+0xAB9B 0xCCF8 #HANGUL SYLLABLE CHIEUCH YE RIEULSIOS
+0xAB9C 0xCCF9 #HANGUL SYLLABLE CHIEUCH YE RIEULTHIEUTH
+0xAB9D 0xCCFA #HANGUL SYLLABLE CHIEUCH YE RIEULPHIEUPH
+0xAB9E 0xCCFB #HANGUL SYLLABLE CHIEUCH YE RIEULHIEUH
+0xAB9F 0xCCFC #HANGUL SYLLABLE CHIEUCH YE MIEUM
+0xABA0 0xCCFD #HANGUL SYLLABLE CHIEUCH YE PIEUP
+0xABA1 0x30A1 #KATAKANA LETTER SMALL A
+0xABA2 0x30A2 #KATAKANA LETTER A
+0xABA3 0x30A3 #KATAKANA LETTER SMALL I
+0xABA4 0x30A4 #KATAKANA LETTER I
+0xABA5 0x30A5 #KATAKANA LETTER SMALL U
+0xABA6 0x30A6 #KATAKANA LETTER U
+0xABA7 0x30A7 #KATAKANA LETTER SMALL E
+0xABA8 0x30A8 #KATAKANA LETTER E
+0xABA9 0x30A9 #KATAKANA LETTER SMALL O
+0xABAA 0x30AA #KATAKANA LETTER O
+0xABAB 0x30AB #KATAKANA LETTER KA
+0xABAC 0x30AC #KATAKANA LETTER GA
+0xABAD 0x30AD #KATAKANA LETTER KI
+0xABAE 0x30AE #KATAKANA LETTER GI
+0xABAF 0x30AF #KATAKANA LETTER KU
+0xABB0 0x30B0 #KATAKANA LETTER GU
+0xABB1 0x30B1 #KATAKANA LETTER KE
+0xABB2 0x30B2 #KATAKANA LETTER GE
+0xABB3 0x30B3 #KATAKANA LETTER KO
+0xABB4 0x30B4 #KATAKANA LETTER GO
+0xABB5 0x30B5 #KATAKANA LETTER SA
+0xABB6 0x30B6 #KATAKANA LETTER ZA
+0xABB7 0x30B7 #KATAKANA LETTER SI
+0xABB8 0x30B8 #KATAKANA LETTER ZI
+0xABB9 0x30B9 #KATAKANA LETTER SU
+0xABBA 0x30BA #KATAKANA LETTER ZU
+0xABBB 0x30BB #KATAKANA LETTER SE
+0xABBC 0x30BC #KATAKANA LETTER ZE
+0xABBD 0x30BD #KATAKANA LETTER SO
+0xABBE 0x30BE #KATAKANA LETTER ZO
+0xABBF 0x30BF #KATAKANA LETTER TA
+0xABC0 0x30C0 #KATAKANA LETTER DA
+0xABC1 0x30C1 #KATAKANA LETTER TI
+0xABC2 0x30C2 #KATAKANA LETTER DI
+0xABC3 0x30C3 #KATAKANA LETTER SMALL TU
+0xABC4 0x30C4 #KATAKANA LETTER TU
+0xABC5 0x30C5 #KATAKANA LETTER DU
+0xABC6 0x30C6 #KATAKANA LETTER TE
+0xABC7 0x30C7 #KATAKANA LETTER DE
+0xABC8 0x30C8 #KATAKANA LETTER TO
+0xABC9 0x30C9 #KATAKANA LETTER DO
+0xABCA 0x30CA #KATAKANA LETTER NA
+0xABCB 0x30CB #KATAKANA LETTER NI
+0xABCC 0x30CC #KATAKANA LETTER NU
+0xABCD 0x30CD #KATAKANA LETTER NE
+0xABCE 0x30CE #KATAKANA LETTER NO
+0xABCF 0x30CF #KATAKANA LETTER HA
+0xABD0 0x30D0 #KATAKANA LETTER BA
+0xABD1 0x30D1 #KATAKANA LETTER PA
+0xABD2 0x30D2 #KATAKANA LETTER HI
+0xABD3 0x30D3 #KATAKANA LETTER BI
+0xABD4 0x30D4 #KATAKANA LETTER PI
+0xABD5 0x30D5 #KATAKANA LETTER HU
+0xABD6 0x30D6 #KATAKANA LETTER BU
+0xABD7 0x30D7 #KATAKANA LETTER PU
+0xABD8 0x30D8 #KATAKANA LETTER HE
+0xABD9 0x30D9 #KATAKANA LETTER BE
+0xABDA 0x30DA #KATAKANA LETTER PE
+0xABDB 0x30DB #KATAKANA LETTER HO
+0xABDC 0x30DC #KATAKANA LETTER BO
+0xABDD 0x30DD #KATAKANA LETTER PO
+0xABDE 0x30DE #KATAKANA LETTER MA
+0xABDF 0x30DF #KATAKANA LETTER MI
+0xABE0 0x30E0 #KATAKANA LETTER MU
+0xABE1 0x30E1 #KATAKANA LETTER ME
+0xABE2 0x30E2 #KATAKANA LETTER MO
+0xABE3 0x30E3 #KATAKANA LETTER SMALL YA
+0xABE4 0x30E4 #KATAKANA LETTER YA
+0xABE5 0x30E5 #KATAKANA LETTER SMALL YU
+0xABE6 0x30E6 #KATAKANA LETTER YU
+0xABE7 0x30E7 #KATAKANA LETTER SMALL YO
+0xABE8 0x30E8 #KATAKANA LETTER YO
+0xABE9 0x30E9 #KATAKANA LETTER RA
+0xABEA 0x30EA #KATAKANA LETTER RI
+0xABEB 0x30EB #KATAKANA LETTER RU
+0xABEC 0x30EC #KATAKANA LETTER RE
+0xABED 0x30ED #KATAKANA LETTER RO
+0xABEE 0x30EE #KATAKANA LETTER SMALL WA
+0xABEF 0x30EF #KATAKANA LETTER WA
+0xABF0 0x30F0 #KATAKANA LETTER WI
+0xABF1 0x30F1 #KATAKANA LETTER WE
+0xABF2 0x30F2 #KATAKANA LETTER WO
+0xABF3 0x30F3 #KATAKANA LETTER N
+0xABF4 0x30F4 #KATAKANA LETTER VU
+0xABF5 0x30F5 #KATAKANA LETTER SMALL KA
+0xABF6 0x30F6 #KATAKANA LETTER SMALL KE
+0xAC41 0xCCFE #HANGUL SYLLABLE CHIEUCH YE PIEUPSIOS
+0xAC42 0xCCFF #HANGUL SYLLABLE CHIEUCH YE SIOS
+0xAC43 0xCD00 #HANGUL SYLLABLE CHIEUCH YE SSANGSIOS
+0xAC44 0xCD02 #HANGUL SYLLABLE CHIEUCH YE CIEUC
+0xAC45 0xCD03 #HANGUL SYLLABLE CHIEUCH YE CHIEUCH
+0xAC46 0xCD04 #HANGUL SYLLABLE CHIEUCH YE KHIEUKH
+0xAC47 0xCD05 #HANGUL SYLLABLE CHIEUCH YE THIEUTH
+0xAC48 0xCD06 #HANGUL SYLLABLE CHIEUCH YE PHIEUPH
+0xAC49 0xCD07 #HANGUL SYLLABLE CHIEUCH YE HIEUH
+0xAC4A 0xCD0A #HANGUL SYLLABLE CHIEUCH O SSANGKIYEOK
+0xAC4B 0xCD0B #HANGUL SYLLABLE CHIEUCH O KIYEOKSIOS
+0xAC4C 0xCD0D #HANGUL SYLLABLE CHIEUCH O NIEUNCIEUC
+0xAC4D 0xCD0E #HANGUL SYLLABLE CHIEUCH O NIEUNHIEUH
+0xAC4E 0xCD0F #HANGUL SYLLABLE CHIEUCH O TIKEUT
+0xAC4F 0xCD11 #HANGUL SYLLABLE CHIEUCH O RIEULKIYEOK
+0xAC50 0xCD12 #HANGUL SYLLABLE CHIEUCH O RIEULMIEUM
+0xAC51 0xCD13 #HANGUL SYLLABLE CHIEUCH O RIEULPIEUP
+0xAC52 0xCD14 #HANGUL SYLLABLE CHIEUCH O RIEULSIOS
+0xAC53 0xCD15 #HANGUL SYLLABLE CHIEUCH O RIEULTHIEUTH
+0xAC54 0xCD16 #HANGUL SYLLABLE CHIEUCH O RIEULPHIEUPH
+0xAC55 0xCD17 #HANGUL SYLLABLE CHIEUCH O RIEULHIEUH
+0xAC56 0xCD1A #HANGUL SYLLABLE CHIEUCH O PIEUPSIOS
+0xAC57 0xCD1C #HANGUL SYLLABLE CHIEUCH O SSANGSIOS
+0xAC58 0xCD1E #HANGUL SYLLABLE CHIEUCH O CIEUC
+0xAC59 0xCD1F #HANGUL SYLLABLE CHIEUCH O CHIEUCH
+0xAC5A 0xCD20 #HANGUL SYLLABLE CHIEUCH O KHIEUKH
+0xAC61 0xCD21 #HANGUL SYLLABLE CHIEUCH O THIEUTH
+0xAC62 0xCD22 #HANGUL SYLLABLE CHIEUCH O PHIEUPH
+0xAC63 0xCD23 #HANGUL SYLLABLE CHIEUCH O HIEUH
+0xAC64 0xCD25 #HANGUL SYLLABLE CHIEUCH WA KIYEOK
+0xAC65 0xCD26 #HANGUL SYLLABLE CHIEUCH WA SSANGKIYEOK
+0xAC66 0xCD27 #HANGUL SYLLABLE CHIEUCH WA KIYEOKSIOS
+0xAC67 0xCD29 #HANGUL SYLLABLE CHIEUCH WA NIEUNCIEUC
+0xAC68 0xCD2A #HANGUL SYLLABLE CHIEUCH WA NIEUNHIEUH
+0xAC69 0xCD2B #HANGUL SYLLABLE CHIEUCH WA TIKEUT
+0xAC6A 0xCD2D #HANGUL SYLLABLE CHIEUCH WA RIEULKIYEOK
+0xAC6B 0xCD2E #HANGUL SYLLABLE CHIEUCH WA RIEULMIEUM
+0xAC6C 0xCD2F #HANGUL SYLLABLE CHIEUCH WA RIEULPIEUP
+0xAC6D 0xCD30 #HANGUL SYLLABLE CHIEUCH WA RIEULSIOS
+0xAC6E 0xCD31 #HANGUL SYLLABLE CHIEUCH WA RIEULTHIEUTH
+0xAC6F 0xCD32 #HANGUL SYLLABLE CHIEUCH WA RIEULPHIEUPH
+0xAC70 0xCD33 #HANGUL SYLLABLE CHIEUCH WA RIEULHIEUH
+0xAC71 0xCD34 #HANGUL SYLLABLE CHIEUCH WA MIEUM
+0xAC72 0xCD35 #HANGUL SYLLABLE CHIEUCH WA PIEUP
+0xAC73 0xCD36 #HANGUL SYLLABLE CHIEUCH WA PIEUPSIOS
+0xAC74 0xCD37 #HANGUL SYLLABLE CHIEUCH WA SIOS
+0xAC75 0xCD38 #HANGUL SYLLABLE CHIEUCH WA SSANGSIOS
+0xAC76 0xCD3A #HANGUL SYLLABLE CHIEUCH WA CIEUC
+0xAC77 0xCD3B #HANGUL SYLLABLE CHIEUCH WA CHIEUCH
+0xAC78 0xCD3C #HANGUL SYLLABLE CHIEUCH WA KHIEUKH
+0xAC79 0xCD3D #HANGUL SYLLABLE CHIEUCH WA THIEUTH
+0xAC7A 0xCD3E #HANGUL SYLLABLE CHIEUCH WA PHIEUPH
+0xAC81 0xCD3F #HANGUL SYLLABLE CHIEUCH WA HIEUH
+0xAC82 0xCD40 #HANGUL SYLLABLE CHIEUCH WAE
+0xAC83 0xCD41 #HANGUL SYLLABLE CHIEUCH WAE KIYEOK
+0xAC84 0xCD42 #HANGUL SYLLABLE CHIEUCH WAE SSANGKIYEOK
+0xAC85 0xCD43 #HANGUL SYLLABLE CHIEUCH WAE KIYEOKSIOS
+0xAC86 0xCD44 #HANGUL SYLLABLE CHIEUCH WAE NIEUN
+0xAC87 0xCD45 #HANGUL SYLLABLE CHIEUCH WAE NIEUNCIEUC
+0xAC88 0xCD46 #HANGUL SYLLABLE CHIEUCH WAE NIEUNHIEUH
+0xAC89 0xCD47 #HANGUL SYLLABLE CHIEUCH WAE TIKEUT
+0xAC8A 0xCD48 #HANGUL SYLLABLE CHIEUCH WAE RIEUL
+0xAC8B 0xCD49 #HANGUL SYLLABLE CHIEUCH WAE RIEULKIYEOK
+0xAC8C 0xCD4A #HANGUL SYLLABLE CHIEUCH WAE RIEULMIEUM
+0xAC8D 0xCD4B #HANGUL SYLLABLE CHIEUCH WAE RIEULPIEUP
+0xAC8E 0xCD4C #HANGUL SYLLABLE CHIEUCH WAE RIEULSIOS
+0xAC8F 0xCD4D #HANGUL SYLLABLE CHIEUCH WAE RIEULTHIEUTH
+0xAC90 0xCD4E #HANGUL SYLLABLE CHIEUCH WAE RIEULPHIEUPH
+0xAC91 0xCD4F #HANGUL SYLLABLE CHIEUCH WAE RIEULHIEUH
+0xAC92 0xCD50 #HANGUL SYLLABLE CHIEUCH WAE MIEUM
+0xAC93 0xCD51 #HANGUL SYLLABLE CHIEUCH WAE PIEUP
+0xAC94 0xCD52 #HANGUL SYLLABLE CHIEUCH WAE PIEUPSIOS
+0xAC95 0xCD53 #HANGUL SYLLABLE CHIEUCH WAE SIOS
+0xAC96 0xCD54 #HANGUL SYLLABLE CHIEUCH WAE SSANGSIOS
+0xAC97 0xCD55 #HANGUL SYLLABLE CHIEUCH WAE IEUNG
+0xAC98 0xCD56 #HANGUL SYLLABLE CHIEUCH WAE CIEUC
+0xAC99 0xCD57 #HANGUL SYLLABLE CHIEUCH WAE CHIEUCH
+0xAC9A 0xCD58 #HANGUL SYLLABLE CHIEUCH WAE KHIEUKH
+0xAC9B 0xCD59 #HANGUL SYLLABLE CHIEUCH WAE THIEUTH
+0xAC9C 0xCD5A #HANGUL SYLLABLE CHIEUCH WAE PHIEUPH
+0xAC9D 0xCD5B #HANGUL SYLLABLE CHIEUCH WAE HIEUH
+0xAC9E 0xCD5D #HANGUL SYLLABLE CHIEUCH OE KIYEOK
+0xAC9F 0xCD5E #HANGUL SYLLABLE CHIEUCH OE SSANGKIYEOK
+0xACA0 0xCD5F #HANGUL SYLLABLE CHIEUCH OE KIYEOKSIOS
+0xACA1 0x0410 #CYRILLIC CAPITAL LETTER A
+0xACA2 0x0411 #CYRILLIC CAPITAL LETTER BE
+0xACA3 0x0412 #CYRILLIC CAPITAL LETTER VE
+0xACA4 0x0413 #CYRILLIC CAPITAL LETTER GHE
+0xACA5 0x0414 #CYRILLIC CAPITAL LETTER DE
+0xACA6 0x0415 #CYRILLIC CAPITAL LETTER IE
+0xACA7 0x0401 #CYRILLIC CAPITAL LETTER IO
+0xACA8 0x0416 #CYRILLIC CAPITAL LETTER ZHE
+0xACA9 0x0417 #CYRILLIC CAPITAL LETTER ZE
+0xACAA 0x0418 #CYRILLIC CAPITAL LETTER I
+0xACAB 0x0419 #CYRILLIC CAPITAL LETTER SHORT I
+0xACAC 0x041A #CYRILLIC CAPITAL LETTER KA
+0xACAD 0x041B #CYRILLIC CAPITAL LETTER EL
+0xACAE 0x041C #CYRILLIC CAPITAL LETTER EM
+0xACAF 0x041D #CYRILLIC CAPITAL LETTER EN
+0xACB0 0x041E #CYRILLIC CAPITAL LETTER O
+0xACB1 0x041F #CYRILLIC CAPITAL LETTER PE
+0xACB2 0x0420 #CYRILLIC CAPITAL LETTER ER
+0xACB3 0x0421 #CYRILLIC CAPITAL LETTER ES
+0xACB4 0x0422 #CYRILLIC CAPITAL LETTER TE
+0xACB5 0x0423 #CYRILLIC CAPITAL LETTER U
+0xACB6 0x0424 #CYRILLIC CAPITAL LETTER EF
+0xACB7 0x0425 #CYRILLIC CAPITAL LETTER HA
+0xACB8 0x0426 #CYRILLIC CAPITAL LETTER TSE
+0xACB9 0x0427 #CYRILLIC CAPITAL LETTER CHE
+0xACBA 0x0428 #CYRILLIC CAPITAL LETTER SHA
+0xACBB 0x0429 #CYRILLIC CAPITAL LETTER SHCHA
+0xACBC 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN
+0xACBD 0x042B #CYRILLIC CAPITAL LETTER YERU
+0xACBE 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN
+0xACBF 0x042D #CYRILLIC CAPITAL LETTER E
+0xACC0 0x042E #CYRILLIC CAPITAL LETTER YU
+0xACC1 0x042F #CYRILLIC CAPITAL LETTER YA
+0xACD1 0x0430 #CYRILLIC SMALL LETTER A
+0xACD2 0x0431 #CYRILLIC SMALL LETTER BE
+0xACD3 0x0432 #CYRILLIC SMALL LETTER VE
+0xACD4 0x0433 #CYRILLIC SMALL LETTER GHE
+0xACD5 0x0434 #CYRILLIC SMALL LETTER DE
+0xACD6 0x0435 #CYRILLIC SMALL LETTER IE
+0xACD7 0x0451 #CYRILLIC SMALL LETTER IO
+0xACD8 0x0436 #CYRILLIC SMALL LETTER ZHE
+0xACD9 0x0437 #CYRILLIC SMALL LETTER ZE
+0xACDA 0x0438 #CYRILLIC SMALL LETTER I
+0xACDB 0x0439 #CYRILLIC SMALL LETTER SHORT I
+0xACDC 0x043A #CYRILLIC SMALL LETTER KA
+0xACDD 0x043B #CYRILLIC SMALL LETTER EL
+0xACDE 0x043C #CYRILLIC SMALL LETTER EM
+0xACDF 0x043D #CYRILLIC SMALL LETTER EN
+0xACE0 0x043E #CYRILLIC SMALL LETTER O
+0xACE1 0x043F #CYRILLIC SMALL LETTER PE
+0xACE2 0x0440 #CYRILLIC SMALL LETTER ER
+0xACE3 0x0441 #CYRILLIC SMALL LETTER ES
+0xACE4 0x0442 #CYRILLIC SMALL LETTER TE
+0xACE5 0x0443 #CYRILLIC SMALL LETTER U
+0xACE6 0x0444 #CYRILLIC SMALL LETTER EF
+0xACE7 0x0445 #CYRILLIC SMALL LETTER HA
+0xACE8 0x0446 #CYRILLIC SMALL LETTER TSE
+0xACE9 0x0447 #CYRILLIC SMALL LETTER CHE
+0xACEA 0x0448 #CYRILLIC SMALL LETTER SHA
+0xACEB 0x0449 #CYRILLIC SMALL LETTER SHCHA
+0xACEC 0x044A #CYRILLIC SMALL LETTER HARD SIGN
+0xACED 0x044B #CYRILLIC SMALL LETTER YERU
+0xACEE 0x044C #CYRILLIC SMALL LETTER SOFT SIGN
+0xACEF 0x044D #CYRILLIC SMALL LETTER E
+0xACF0 0x044E #CYRILLIC SMALL LETTER YU
+0xACF1 0x044F #CYRILLIC SMALL LETTER YA
+0xAD41 0xCD61 #HANGUL SYLLABLE CHIEUCH OE NIEUNCIEUC
+0xAD42 0xCD62 #HANGUL SYLLABLE CHIEUCH OE NIEUNHIEUH
+0xAD43 0xCD63 #HANGUL SYLLABLE CHIEUCH OE TIKEUT
+0xAD44 0xCD65 #HANGUL SYLLABLE CHIEUCH OE RIEULKIYEOK
+0xAD45 0xCD66 #HANGUL SYLLABLE CHIEUCH OE RIEULMIEUM
+0xAD46 0xCD67 #HANGUL SYLLABLE CHIEUCH OE RIEULPIEUP
+0xAD47 0xCD68 #HANGUL SYLLABLE CHIEUCH OE RIEULSIOS
+0xAD48 0xCD69 #HANGUL SYLLABLE CHIEUCH OE RIEULTHIEUTH
+0xAD49 0xCD6A #HANGUL SYLLABLE CHIEUCH OE RIEULPHIEUPH
+0xAD4A 0xCD6B #HANGUL SYLLABLE CHIEUCH OE RIEULHIEUH
+0xAD4B 0xCD6E #HANGUL SYLLABLE CHIEUCH OE PIEUPSIOS
+0xAD4C 0xCD70 #HANGUL SYLLABLE CHIEUCH OE SSANGSIOS
+0xAD4D 0xCD72 #HANGUL SYLLABLE CHIEUCH OE CIEUC
+0xAD4E 0xCD73 #HANGUL SYLLABLE CHIEUCH OE CHIEUCH
+0xAD4F 0xCD74 #HANGUL SYLLABLE CHIEUCH OE KHIEUKH
+0xAD50 0xCD75 #HANGUL SYLLABLE CHIEUCH OE THIEUTH
+0xAD51 0xCD76 #HANGUL SYLLABLE CHIEUCH OE PHIEUPH
+0xAD52 0xCD77 #HANGUL SYLLABLE CHIEUCH OE HIEUH
+0xAD53 0xCD79 #HANGUL SYLLABLE CHIEUCH YO KIYEOK
+0xAD54 0xCD7A #HANGUL SYLLABLE CHIEUCH YO SSANGKIYEOK
+0xAD55 0xCD7B #HANGUL SYLLABLE CHIEUCH YO KIYEOKSIOS
+0xAD56 0xCD7C #HANGUL SYLLABLE CHIEUCH YO NIEUN
+0xAD57 0xCD7D #HANGUL SYLLABLE CHIEUCH YO NIEUNCIEUC
+0xAD58 0xCD7E #HANGUL SYLLABLE CHIEUCH YO NIEUNHIEUH
+0xAD59 0xCD7F #HANGUL SYLLABLE CHIEUCH YO TIKEUT
+0xAD5A 0xCD80 #HANGUL SYLLABLE CHIEUCH YO RIEUL
+0xAD61 0xCD81 #HANGUL SYLLABLE CHIEUCH YO RIEULKIYEOK
+0xAD62 0xCD82 #HANGUL SYLLABLE CHIEUCH YO RIEULMIEUM
+0xAD63 0xCD83 #HANGUL SYLLABLE CHIEUCH YO RIEULPIEUP
+0xAD64 0xCD84 #HANGUL SYLLABLE CHIEUCH YO RIEULSIOS
+0xAD65 0xCD85 #HANGUL SYLLABLE CHIEUCH YO RIEULTHIEUTH
+0xAD66 0xCD86 #HANGUL SYLLABLE CHIEUCH YO RIEULPHIEUPH
+0xAD67 0xCD87 #HANGUL SYLLABLE CHIEUCH YO RIEULHIEUH
+0xAD68 0xCD89 #HANGUL SYLLABLE CHIEUCH YO PIEUP
+0xAD69 0xCD8A #HANGUL SYLLABLE CHIEUCH YO PIEUPSIOS
+0xAD6A 0xCD8B #HANGUL SYLLABLE CHIEUCH YO SIOS
+0xAD6B 0xCD8C #HANGUL SYLLABLE CHIEUCH YO SSANGSIOS
+0xAD6C 0xCD8D #HANGUL SYLLABLE CHIEUCH YO IEUNG
+0xAD6D 0xCD8E #HANGUL SYLLABLE CHIEUCH YO CIEUC
+0xAD6E 0xCD8F #HANGUL SYLLABLE CHIEUCH YO CHIEUCH
+0xAD6F 0xCD90 #HANGUL SYLLABLE CHIEUCH YO KHIEUKH
+0xAD70 0xCD91 #HANGUL SYLLABLE CHIEUCH YO THIEUTH
+0xAD71 0xCD92 #HANGUL SYLLABLE CHIEUCH YO PHIEUPH
+0xAD72 0xCD93 #HANGUL SYLLABLE CHIEUCH YO HIEUH
+0xAD73 0xCD96 #HANGUL SYLLABLE CHIEUCH U SSANGKIYEOK
+0xAD74 0xCD97 #HANGUL SYLLABLE CHIEUCH U KIYEOKSIOS
+0xAD75 0xCD99 #HANGUL SYLLABLE CHIEUCH U NIEUNCIEUC
+0xAD76 0xCD9A #HANGUL SYLLABLE CHIEUCH U NIEUNHIEUH
+0xAD77 0xCD9B #HANGUL SYLLABLE CHIEUCH U TIKEUT
+0xAD78 0xCD9D #HANGUL SYLLABLE CHIEUCH U RIEULKIYEOK
+0xAD79 0xCD9E #HANGUL SYLLABLE CHIEUCH U RIEULMIEUM
+0xAD7A 0xCD9F #HANGUL SYLLABLE CHIEUCH U RIEULPIEUP
+0xAD81 0xCDA0 #HANGUL SYLLABLE CHIEUCH U RIEULSIOS
+0xAD82 0xCDA1 #HANGUL SYLLABLE CHIEUCH U RIEULTHIEUTH
+0xAD83 0xCDA2 #HANGUL SYLLABLE CHIEUCH U RIEULPHIEUPH
+0xAD84 0xCDA3 #HANGUL SYLLABLE CHIEUCH U RIEULHIEUH
+0xAD85 0xCDA6 #HANGUL SYLLABLE CHIEUCH U PIEUPSIOS
+0xAD86 0xCDA8 #HANGUL SYLLABLE CHIEUCH U SSANGSIOS
+0xAD87 0xCDAA #HANGUL SYLLABLE CHIEUCH U CIEUC
+0xAD88 0xCDAB #HANGUL SYLLABLE CHIEUCH U CHIEUCH
+0xAD89 0xCDAC #HANGUL SYLLABLE CHIEUCH U KHIEUKH
+0xAD8A 0xCDAD #HANGUL SYLLABLE CHIEUCH U THIEUTH
+0xAD8B 0xCDAE #HANGUL SYLLABLE CHIEUCH U PHIEUPH
+0xAD8C 0xCDAF #HANGUL SYLLABLE CHIEUCH U HIEUH
+0xAD8D 0xCDB1 #HANGUL SYLLABLE CHIEUCH WEO KIYEOK
+0xAD8E 0xCDB2 #HANGUL SYLLABLE CHIEUCH WEO SSANGKIYEOK
+0xAD8F 0xCDB3 #HANGUL SYLLABLE CHIEUCH WEO KIYEOKSIOS
+0xAD90 0xCDB4 #HANGUL SYLLABLE CHIEUCH WEO NIEUN
+0xAD91 0xCDB5 #HANGUL SYLLABLE CHIEUCH WEO NIEUNCIEUC
+0xAD92 0xCDB6 #HANGUL SYLLABLE CHIEUCH WEO NIEUNHIEUH
+0xAD93 0xCDB7 #HANGUL SYLLABLE CHIEUCH WEO TIKEUT
+0xAD94 0xCDB8 #HANGUL SYLLABLE CHIEUCH WEO RIEUL
+0xAD95 0xCDB9 #HANGUL SYLLABLE CHIEUCH WEO RIEULKIYEOK
+0xAD96 0xCDBA #HANGUL SYLLABLE CHIEUCH WEO RIEULMIEUM
+0xAD97 0xCDBB #HANGUL SYLLABLE CHIEUCH WEO RIEULPIEUP
+0xAD98 0xCDBC #HANGUL SYLLABLE CHIEUCH WEO RIEULSIOS
+0xAD99 0xCDBD #HANGUL SYLLABLE CHIEUCH WEO RIEULTHIEUTH
+0xAD9A 0xCDBE #HANGUL SYLLABLE CHIEUCH WEO RIEULPHIEUPH
+0xAD9B 0xCDBF #HANGUL SYLLABLE CHIEUCH WEO RIEULHIEUH
+0xAD9C 0xCDC0 #HANGUL SYLLABLE CHIEUCH WEO MIEUM
+0xAD9D 0xCDC1 #HANGUL SYLLABLE CHIEUCH WEO PIEUP
+0xAD9E 0xCDC2 #HANGUL SYLLABLE CHIEUCH WEO PIEUPSIOS
+0xAD9F 0xCDC3 #HANGUL SYLLABLE CHIEUCH WEO SIOS
+0xADA0 0xCDC5 #HANGUL SYLLABLE CHIEUCH WEO IEUNG
+0xAE41 0xCDC6 #HANGUL SYLLABLE CHIEUCH WEO CIEUC
+0xAE42 0xCDC7 #HANGUL SYLLABLE CHIEUCH WEO CHIEUCH
+0xAE43 0xCDC8 #HANGUL SYLLABLE CHIEUCH WEO KHIEUKH
+0xAE44 0xCDC9 #HANGUL SYLLABLE CHIEUCH WEO THIEUTH
+0xAE45 0xCDCA #HANGUL SYLLABLE CHIEUCH WEO PHIEUPH
+0xAE46 0xCDCB #HANGUL SYLLABLE CHIEUCH WEO HIEUH
+0xAE47 0xCDCD #HANGUL SYLLABLE CHIEUCH WE KIYEOK
+0xAE48 0xCDCE #HANGUL SYLLABLE CHIEUCH WE SSANGKIYEOK
+0xAE49 0xCDCF #HANGUL SYLLABLE CHIEUCH WE KIYEOKSIOS
+0xAE4A 0xCDD1 #HANGUL SYLLABLE CHIEUCH WE NIEUNCIEUC
+0xAE4B 0xCDD2 #HANGUL SYLLABLE CHIEUCH WE NIEUNHIEUH
+0xAE4C 0xCDD3 #HANGUL SYLLABLE CHIEUCH WE TIKEUT
+0xAE4D 0xCDD4 #HANGUL SYLLABLE CHIEUCH WE RIEUL
+0xAE4E 0xCDD5 #HANGUL SYLLABLE CHIEUCH WE RIEULKIYEOK
+0xAE4F 0xCDD6 #HANGUL SYLLABLE CHIEUCH WE RIEULMIEUM
+0xAE50 0xCDD7 #HANGUL SYLLABLE CHIEUCH WE RIEULPIEUP
+0xAE51 0xCDD8 #HANGUL SYLLABLE CHIEUCH WE RIEULSIOS
+0xAE52 0xCDD9 #HANGUL SYLLABLE CHIEUCH WE RIEULTHIEUTH
+0xAE53 0xCDDA #HANGUL SYLLABLE CHIEUCH WE RIEULPHIEUPH
+0xAE54 0xCDDB #HANGUL SYLLABLE CHIEUCH WE RIEULHIEUH
+0xAE55 0xCDDC #HANGUL SYLLABLE CHIEUCH WE MIEUM
+0xAE56 0xCDDD #HANGUL SYLLABLE CHIEUCH WE PIEUP
+0xAE57 0xCDDE #HANGUL SYLLABLE CHIEUCH WE PIEUPSIOS
+0xAE58 0xCDDF #HANGUL SYLLABLE CHIEUCH WE SIOS
+0xAE59 0xCDE0 #HANGUL SYLLABLE CHIEUCH WE SSANGSIOS
+0xAE5A 0xCDE1 #HANGUL SYLLABLE CHIEUCH WE IEUNG
+0xAE61 0xCDE2 #HANGUL SYLLABLE CHIEUCH WE CIEUC
+0xAE62 0xCDE3 #HANGUL SYLLABLE CHIEUCH WE CHIEUCH
+0xAE63 0xCDE4 #HANGUL SYLLABLE CHIEUCH WE KHIEUKH
+0xAE64 0xCDE5 #HANGUL SYLLABLE CHIEUCH WE THIEUTH
+0xAE65 0xCDE6 #HANGUL SYLLABLE CHIEUCH WE PHIEUPH
+0xAE66 0xCDE7 #HANGUL SYLLABLE CHIEUCH WE HIEUH
+0xAE67 0xCDE9 #HANGUL SYLLABLE CHIEUCH WI KIYEOK
+0xAE68 0xCDEA #HANGUL SYLLABLE CHIEUCH WI SSANGKIYEOK
+0xAE69 0xCDEB #HANGUL SYLLABLE CHIEUCH WI KIYEOKSIOS
+0xAE6A 0xCDED #HANGUL SYLLABLE CHIEUCH WI NIEUNCIEUC
+0xAE6B 0xCDEE #HANGUL SYLLABLE CHIEUCH WI NIEUNHIEUH
+0xAE6C 0xCDEF #HANGUL SYLLABLE CHIEUCH WI TIKEUT
+0xAE6D 0xCDF1 #HANGUL SYLLABLE CHIEUCH WI RIEULKIYEOK
+0xAE6E 0xCDF2 #HANGUL SYLLABLE CHIEUCH WI RIEULMIEUM
+0xAE6F 0xCDF3 #HANGUL SYLLABLE CHIEUCH WI RIEULPIEUP
+0xAE70 0xCDF4 #HANGUL SYLLABLE CHIEUCH WI RIEULSIOS
+0xAE71 0xCDF5 #HANGUL SYLLABLE CHIEUCH WI RIEULTHIEUTH
+0xAE72 0xCDF6 #HANGUL SYLLABLE CHIEUCH WI RIEULPHIEUPH
+0xAE73 0xCDF7 #HANGUL SYLLABLE CHIEUCH WI RIEULHIEUH
+0xAE74 0xCDFA #HANGUL SYLLABLE CHIEUCH WI PIEUPSIOS
+0xAE75 0xCDFC #HANGUL SYLLABLE CHIEUCH WI SSANGSIOS
+0xAE76 0xCDFE #HANGUL SYLLABLE CHIEUCH WI CIEUC
+0xAE77 0xCDFF #HANGUL SYLLABLE CHIEUCH WI CHIEUCH
+0xAE78 0xCE00 #HANGUL SYLLABLE CHIEUCH WI KHIEUKH
+0xAE79 0xCE01 #HANGUL SYLLABLE CHIEUCH WI THIEUTH
+0xAE7A 0xCE02 #HANGUL SYLLABLE CHIEUCH WI PHIEUPH
+0xAE81 0xCE03 #HANGUL SYLLABLE CHIEUCH WI HIEUH
+0xAE82 0xCE05 #HANGUL SYLLABLE CHIEUCH YU KIYEOK
+0xAE83 0xCE06 #HANGUL SYLLABLE CHIEUCH YU SSANGKIYEOK
+0xAE84 0xCE07 #HANGUL SYLLABLE CHIEUCH YU KIYEOKSIOS
+0xAE85 0xCE09 #HANGUL SYLLABLE CHIEUCH YU NIEUNCIEUC
+0xAE86 0xCE0A #HANGUL SYLLABLE CHIEUCH YU NIEUNHIEUH
+0xAE87 0xCE0B #HANGUL SYLLABLE CHIEUCH YU TIKEUT
+0xAE88 0xCE0D #HANGUL SYLLABLE CHIEUCH YU RIEULKIYEOK
+0xAE89 0xCE0E #HANGUL SYLLABLE CHIEUCH YU RIEULMIEUM
+0xAE8A 0xCE0F #HANGUL SYLLABLE CHIEUCH YU RIEULPIEUP
+0xAE8B 0xCE10 #HANGUL SYLLABLE CHIEUCH YU RIEULSIOS
+0xAE8C 0xCE11 #HANGUL SYLLABLE CHIEUCH YU RIEULTHIEUTH
+0xAE8D 0xCE12 #HANGUL SYLLABLE CHIEUCH YU RIEULPHIEUPH
+0xAE8E 0xCE13 #HANGUL SYLLABLE CHIEUCH YU RIEULHIEUH
+0xAE8F 0xCE15 #HANGUL SYLLABLE CHIEUCH YU PIEUP
+0xAE90 0xCE16 #HANGUL SYLLABLE CHIEUCH YU PIEUPSIOS
+0xAE91 0xCE17 #HANGUL SYLLABLE CHIEUCH YU SIOS
+0xAE92 0xCE18 #HANGUL SYLLABLE CHIEUCH YU SSANGSIOS
+0xAE93 0xCE1A #HANGUL SYLLABLE CHIEUCH YU CIEUC
+0xAE94 0xCE1B #HANGUL SYLLABLE CHIEUCH YU CHIEUCH
+0xAE95 0xCE1C #HANGUL SYLLABLE CHIEUCH YU KHIEUKH
+0xAE96 0xCE1D #HANGUL SYLLABLE CHIEUCH YU THIEUTH
+0xAE97 0xCE1E #HANGUL SYLLABLE CHIEUCH YU PHIEUPH
+0xAE98 0xCE1F #HANGUL SYLLABLE CHIEUCH YU HIEUH
+0xAE99 0xCE22 #HANGUL SYLLABLE CHIEUCH EU SSANGKIYEOK
+0xAE9A 0xCE23 #HANGUL SYLLABLE CHIEUCH EU KIYEOKSIOS
+0xAE9B 0xCE25 #HANGUL SYLLABLE CHIEUCH EU NIEUNCIEUC
+0xAE9C 0xCE26 #HANGUL SYLLABLE CHIEUCH EU NIEUNHIEUH
+0xAE9D 0xCE27 #HANGUL SYLLABLE CHIEUCH EU TIKEUT
+0xAE9E 0xCE29 #HANGUL SYLLABLE CHIEUCH EU RIEULKIYEOK
+0xAE9F 0xCE2A #HANGUL SYLLABLE CHIEUCH EU RIEULMIEUM
+0xAEA0 0xCE2B #HANGUL SYLLABLE CHIEUCH EU RIEULPIEUP
+0xAF41 0xCE2C #HANGUL SYLLABLE CHIEUCH EU RIEULSIOS
+0xAF42 0xCE2D #HANGUL SYLLABLE CHIEUCH EU RIEULTHIEUTH
+0xAF43 0xCE2E #HANGUL SYLLABLE CHIEUCH EU RIEULPHIEUPH
+0xAF44 0xCE2F #HANGUL SYLLABLE CHIEUCH EU RIEULHIEUH
+0xAF45 0xCE32 #HANGUL SYLLABLE CHIEUCH EU PIEUPSIOS
+0xAF46 0xCE34 #HANGUL SYLLABLE CHIEUCH EU SSANGSIOS
+0xAF47 0xCE36 #HANGUL SYLLABLE CHIEUCH EU CIEUC
+0xAF48 0xCE37 #HANGUL SYLLABLE CHIEUCH EU CHIEUCH
+0xAF49 0xCE38 #HANGUL SYLLABLE CHIEUCH EU KHIEUKH
+0xAF4A 0xCE39 #HANGUL SYLLABLE CHIEUCH EU THIEUTH
+0xAF4B 0xCE3A #HANGUL SYLLABLE CHIEUCH EU PHIEUPH
+0xAF4C 0xCE3B #HANGUL SYLLABLE CHIEUCH EU HIEUH
+0xAF4D 0xCE3C #HANGUL SYLLABLE CHIEUCH YI
+0xAF4E 0xCE3D #HANGUL SYLLABLE CHIEUCH YI KIYEOK
+0xAF4F 0xCE3E #HANGUL SYLLABLE CHIEUCH YI SSANGKIYEOK
+0xAF50 0xCE3F #HANGUL SYLLABLE CHIEUCH YI KIYEOKSIOS
+0xAF51 0xCE40 #HANGUL SYLLABLE CHIEUCH YI NIEUN
+0xAF52 0xCE41 #HANGUL SYLLABLE CHIEUCH YI NIEUNCIEUC
+0xAF53 0xCE42 #HANGUL SYLLABLE CHIEUCH YI NIEUNHIEUH
+0xAF54 0xCE43 #HANGUL SYLLABLE CHIEUCH YI TIKEUT
+0xAF55 0xCE44 #HANGUL SYLLABLE CHIEUCH YI RIEUL
+0xAF56 0xCE45 #HANGUL SYLLABLE CHIEUCH YI RIEULKIYEOK
+0xAF57 0xCE46 #HANGUL SYLLABLE CHIEUCH YI RIEULMIEUM
+0xAF58 0xCE47 #HANGUL SYLLABLE CHIEUCH YI RIEULPIEUP
+0xAF59 0xCE48 #HANGUL SYLLABLE CHIEUCH YI RIEULSIOS
+0xAF5A 0xCE49 #HANGUL SYLLABLE CHIEUCH YI RIEULTHIEUTH
+0xAF61 0xCE4A #HANGUL SYLLABLE CHIEUCH YI RIEULPHIEUPH
+0xAF62 0xCE4B #HANGUL SYLLABLE CHIEUCH YI RIEULHIEUH
+0xAF63 0xCE4C #HANGUL SYLLABLE CHIEUCH YI MIEUM
+0xAF64 0xCE4D #HANGUL SYLLABLE CHIEUCH YI PIEUP
+0xAF65 0xCE4E #HANGUL SYLLABLE CHIEUCH YI PIEUPSIOS
+0xAF66 0xCE4F #HANGUL SYLLABLE CHIEUCH YI SIOS
+0xAF67 0xCE50 #HANGUL SYLLABLE CHIEUCH YI SSANGSIOS
+0xAF68 0xCE51 #HANGUL SYLLABLE CHIEUCH YI IEUNG
+0xAF69 0xCE52 #HANGUL SYLLABLE CHIEUCH YI CIEUC
+0xAF6A 0xCE53 #HANGUL SYLLABLE CHIEUCH YI CHIEUCH
+0xAF6B 0xCE54 #HANGUL SYLLABLE CHIEUCH YI KHIEUKH
+0xAF6C 0xCE55 #HANGUL SYLLABLE CHIEUCH YI THIEUTH
+0xAF6D 0xCE56 #HANGUL SYLLABLE CHIEUCH YI PHIEUPH
+0xAF6E 0xCE57 #HANGUL SYLLABLE CHIEUCH YI HIEUH
+0xAF6F 0xCE5A #HANGUL SYLLABLE CHIEUCH I SSANGKIYEOK
+0xAF70 0xCE5B #HANGUL SYLLABLE CHIEUCH I KIYEOKSIOS
+0xAF71 0xCE5D #HANGUL SYLLABLE CHIEUCH I NIEUNCIEUC
+0xAF72 0xCE5E #HANGUL SYLLABLE CHIEUCH I NIEUNHIEUH
+0xAF73 0xCE62 #HANGUL SYLLABLE CHIEUCH I RIEULMIEUM
+0xAF74 0xCE63 #HANGUL SYLLABLE CHIEUCH I RIEULPIEUP
+0xAF75 0xCE64 #HANGUL SYLLABLE CHIEUCH I RIEULSIOS
+0xAF76 0xCE65 #HANGUL SYLLABLE CHIEUCH I RIEULTHIEUTH
+0xAF77 0xCE66 #HANGUL SYLLABLE CHIEUCH I RIEULPHIEUPH
+0xAF78 0xCE67 #HANGUL SYLLABLE CHIEUCH I RIEULHIEUH
+0xAF79 0xCE6A #HANGUL SYLLABLE CHIEUCH I PIEUPSIOS
+0xAF7A 0xCE6C #HANGUL SYLLABLE CHIEUCH I SSANGSIOS
+0xAF81 0xCE6E #HANGUL SYLLABLE CHIEUCH I CIEUC
+0xAF82 0xCE6F #HANGUL SYLLABLE CHIEUCH I CHIEUCH
+0xAF83 0xCE70 #HANGUL SYLLABLE CHIEUCH I KHIEUKH
+0xAF84 0xCE71 #HANGUL SYLLABLE CHIEUCH I THIEUTH
+0xAF85 0xCE72 #HANGUL SYLLABLE CHIEUCH I PHIEUPH
+0xAF86 0xCE73 #HANGUL SYLLABLE CHIEUCH I HIEUH
+0xAF87 0xCE76 #HANGUL SYLLABLE KHIEUKH A SSANGKIYEOK
+0xAF88 0xCE77 #HANGUL SYLLABLE KHIEUKH A KIYEOKSIOS
+0xAF89 0xCE79 #HANGUL SYLLABLE KHIEUKH A NIEUNCIEUC
+0xAF8A 0xCE7A #HANGUL SYLLABLE KHIEUKH A NIEUNHIEUH
+0xAF8B 0xCE7B #HANGUL SYLLABLE KHIEUKH A TIKEUT
+0xAF8C 0xCE7D #HANGUL SYLLABLE KHIEUKH A RIEULKIYEOK
+0xAF8D 0xCE7E #HANGUL SYLLABLE KHIEUKH A RIEULMIEUM
+0xAF8E 0xCE7F #HANGUL SYLLABLE KHIEUKH A RIEULPIEUP
+0xAF8F 0xCE80 #HANGUL SYLLABLE KHIEUKH A RIEULSIOS
+0xAF90 0xCE81 #HANGUL SYLLABLE KHIEUKH A RIEULTHIEUTH
+0xAF91 0xCE82 #HANGUL SYLLABLE KHIEUKH A RIEULPHIEUPH
+0xAF92 0xCE83 #HANGUL SYLLABLE KHIEUKH A RIEULHIEUH
+0xAF93 0xCE86 #HANGUL SYLLABLE KHIEUKH A PIEUPSIOS
+0xAF94 0xCE88 #HANGUL SYLLABLE KHIEUKH A SSANGSIOS
+0xAF95 0xCE8A #HANGUL SYLLABLE KHIEUKH A CIEUC
+0xAF96 0xCE8B #HANGUL SYLLABLE KHIEUKH A CHIEUCH
+0xAF97 0xCE8C #HANGUL SYLLABLE KHIEUKH A KHIEUKH
+0xAF98 0xCE8D #HANGUL SYLLABLE KHIEUKH A THIEUTH
+0xAF99 0xCE8E #HANGUL SYLLABLE KHIEUKH A PHIEUPH
+0xAF9A 0xCE8F #HANGUL SYLLABLE KHIEUKH A HIEUH
+0xAF9B 0xCE92 #HANGUL SYLLABLE KHIEUKH AE SSANGKIYEOK
+0xAF9C 0xCE93 #HANGUL SYLLABLE KHIEUKH AE KIYEOKSIOS
+0xAF9D 0xCE95 #HANGUL SYLLABLE KHIEUKH AE NIEUNCIEUC
+0xAF9E 0xCE96 #HANGUL SYLLABLE KHIEUKH AE NIEUNHIEUH
+0xAF9F 0xCE97 #HANGUL SYLLABLE KHIEUKH AE TIKEUT
+0xAFA0 0xCE99 #HANGUL SYLLABLE KHIEUKH AE RIEULKIYEOK
+0xB041 0xCE9A #HANGUL SYLLABLE KHIEUKH AE RIEULMIEUM
+0xB042 0xCE9B #HANGUL SYLLABLE KHIEUKH AE RIEULPIEUP
+0xB043 0xCE9C #HANGUL SYLLABLE KHIEUKH AE RIEULSIOS
+0xB044 0xCE9D #HANGUL SYLLABLE KHIEUKH AE RIEULTHIEUTH
+0xB045 0xCE9E #HANGUL SYLLABLE KHIEUKH AE RIEULPHIEUPH
+0xB046 0xCE9F #HANGUL SYLLABLE KHIEUKH AE RIEULHIEUH
+0xB047 0xCEA2 #HANGUL SYLLABLE KHIEUKH AE PIEUPSIOS
+0xB048 0xCEA6 #HANGUL SYLLABLE KHIEUKH AE CIEUC
+0xB049 0xCEA7 #HANGUL SYLLABLE KHIEUKH AE CHIEUCH
+0xB04A 0xCEA8 #HANGUL SYLLABLE KHIEUKH AE KHIEUKH
+0xB04B 0xCEA9 #HANGUL SYLLABLE KHIEUKH AE THIEUTH
+0xB04C 0xCEAA #HANGUL SYLLABLE KHIEUKH AE PHIEUPH
+0xB04D 0xCEAB #HANGUL SYLLABLE KHIEUKH AE HIEUH
+0xB04E 0xCEAE #HANGUL SYLLABLE KHIEUKH YA SSANGKIYEOK
+0xB04F 0xCEAF #HANGUL SYLLABLE KHIEUKH YA KIYEOKSIOS
+0xB050 0xCEB0 #HANGUL SYLLABLE KHIEUKH YA NIEUN
+0xB051 0xCEB1 #HANGUL SYLLABLE KHIEUKH YA NIEUNCIEUC
+0xB052 0xCEB2 #HANGUL SYLLABLE KHIEUKH YA NIEUNHIEUH
+0xB053 0xCEB3 #HANGUL SYLLABLE KHIEUKH YA TIKEUT
+0xB054 0xCEB4 #HANGUL SYLLABLE KHIEUKH YA RIEUL
+0xB055 0xCEB5 #HANGUL SYLLABLE KHIEUKH YA RIEULKIYEOK
+0xB056 0xCEB6 #HANGUL SYLLABLE KHIEUKH YA RIEULMIEUM
+0xB057 0xCEB7 #HANGUL SYLLABLE KHIEUKH YA RIEULPIEUP
+0xB058 0xCEB8 #HANGUL SYLLABLE KHIEUKH YA RIEULSIOS
+0xB059 0xCEB9 #HANGUL SYLLABLE KHIEUKH YA RIEULTHIEUTH
+0xB05A 0xCEBA #HANGUL SYLLABLE KHIEUKH YA RIEULPHIEUPH
+0xB061 0xCEBB #HANGUL SYLLABLE KHIEUKH YA RIEULHIEUH
+0xB062 0xCEBC #HANGUL SYLLABLE KHIEUKH YA MIEUM
+0xB063 0xCEBD #HANGUL SYLLABLE KHIEUKH YA PIEUP
+0xB064 0xCEBE #HANGUL SYLLABLE KHIEUKH YA PIEUPSIOS
+0xB065 0xCEBF #HANGUL SYLLABLE KHIEUKH YA SIOS
+0xB066 0xCEC0 #HANGUL SYLLABLE KHIEUKH YA SSANGSIOS
+0xB067 0xCEC2 #HANGUL SYLLABLE KHIEUKH YA CIEUC
+0xB068 0xCEC3 #HANGUL SYLLABLE KHIEUKH YA CHIEUCH
+0xB069 0xCEC4 #HANGUL SYLLABLE KHIEUKH YA KHIEUKH
+0xB06A 0xCEC5 #HANGUL SYLLABLE KHIEUKH YA THIEUTH
+0xB06B 0xCEC6 #HANGUL SYLLABLE KHIEUKH YA PHIEUPH
+0xB06C 0xCEC7 #HANGUL SYLLABLE KHIEUKH YA HIEUH
+0xB06D 0xCEC8 #HANGUL SYLLABLE KHIEUKH YAE
+0xB06E 0xCEC9 #HANGUL SYLLABLE KHIEUKH YAE KIYEOK
+0xB06F 0xCECA #HANGUL SYLLABLE KHIEUKH YAE SSANGKIYEOK
+0xB070 0xCECB #HANGUL SYLLABLE KHIEUKH YAE KIYEOKSIOS
+0xB071 0xCECC #HANGUL SYLLABLE KHIEUKH YAE NIEUN
+0xB072 0xCECD #HANGUL SYLLABLE KHIEUKH YAE NIEUNCIEUC
+0xB073 0xCECE #HANGUL SYLLABLE KHIEUKH YAE NIEUNHIEUH
+0xB074 0xCECF #HANGUL SYLLABLE KHIEUKH YAE TIKEUT
+0xB075 0xCED0 #HANGUL SYLLABLE KHIEUKH YAE RIEUL
+0xB076 0xCED1 #HANGUL SYLLABLE KHIEUKH YAE RIEULKIYEOK
+0xB077 0xCED2 #HANGUL SYLLABLE KHIEUKH YAE RIEULMIEUM
+0xB078 0xCED3 #HANGUL SYLLABLE KHIEUKH YAE RIEULPIEUP
+0xB079 0xCED4 #HANGUL SYLLABLE KHIEUKH YAE RIEULSIOS
+0xB07A 0xCED5 #HANGUL SYLLABLE KHIEUKH YAE RIEULTHIEUTH
+0xB081 0xCED6 #HANGUL SYLLABLE KHIEUKH YAE RIEULPHIEUPH
+0xB082 0xCED7 #HANGUL SYLLABLE KHIEUKH YAE RIEULHIEUH
+0xB083 0xCED8 #HANGUL SYLLABLE KHIEUKH YAE MIEUM
+0xB084 0xCED9 #HANGUL SYLLABLE KHIEUKH YAE PIEUP
+0xB085 0xCEDA #HANGUL SYLLABLE KHIEUKH YAE PIEUPSIOS
+0xB086 0xCEDB #HANGUL SYLLABLE KHIEUKH YAE SIOS
+0xB087 0xCEDC #HANGUL SYLLABLE KHIEUKH YAE SSANGSIOS
+0xB088 0xCEDD #HANGUL SYLLABLE KHIEUKH YAE IEUNG
+0xB089 0xCEDE #HANGUL SYLLABLE KHIEUKH YAE CIEUC
+0xB08A 0xCEDF #HANGUL SYLLABLE KHIEUKH YAE CHIEUCH
+0xB08B 0xCEE0 #HANGUL SYLLABLE KHIEUKH YAE KHIEUKH
+0xB08C 0xCEE1 #HANGUL SYLLABLE KHIEUKH YAE THIEUTH
+0xB08D 0xCEE2 #HANGUL SYLLABLE KHIEUKH YAE PHIEUPH
+0xB08E 0xCEE3 #HANGUL SYLLABLE KHIEUKH YAE HIEUH
+0xB08F 0xCEE6 #HANGUL SYLLABLE KHIEUKH EO SSANGKIYEOK
+0xB090 0xCEE7 #HANGUL SYLLABLE KHIEUKH EO KIYEOKSIOS
+0xB091 0xCEE9 #HANGUL SYLLABLE KHIEUKH EO NIEUNCIEUC
+0xB092 0xCEEA #HANGUL SYLLABLE KHIEUKH EO NIEUNHIEUH
+0xB093 0xCEED #HANGUL SYLLABLE KHIEUKH EO RIEULKIYEOK
+0xB094 0xCEEE #HANGUL SYLLABLE KHIEUKH EO RIEULMIEUM
+0xB095 0xCEEF #HANGUL SYLLABLE KHIEUKH EO RIEULPIEUP
+0xB096 0xCEF0 #HANGUL SYLLABLE KHIEUKH EO RIEULSIOS
+0xB097 0xCEF1 #HANGUL SYLLABLE KHIEUKH EO RIEULTHIEUTH
+0xB098 0xCEF2 #HANGUL SYLLABLE KHIEUKH EO RIEULPHIEUPH
+0xB099 0xCEF3 #HANGUL SYLLABLE KHIEUKH EO RIEULHIEUH
+0xB09A 0xCEF6 #HANGUL SYLLABLE KHIEUKH EO PIEUPSIOS
+0xB09B 0xCEFA #HANGUL SYLLABLE KHIEUKH EO CIEUC
+0xB09C 0xCEFB #HANGUL SYLLABLE KHIEUKH EO CHIEUCH
+0xB09D 0xCEFC #HANGUL SYLLABLE KHIEUKH EO KHIEUKH
+0xB09E 0xCEFD #HANGUL SYLLABLE KHIEUKH EO THIEUTH
+0xB09F 0xCEFE #HANGUL SYLLABLE KHIEUKH EO PHIEUPH
+0xB0A0 0xCEFF #HANGUL SYLLABLE KHIEUKH EO HIEUH
+0xB0A1 0xAC00 #HANGUL SYLLABLE KIYEOK A
+0xB0A2 0xAC01 #HANGUL SYLLABLE KIYEOK A KIYEOK
+0xB0A3 0xAC04 #HANGUL SYLLABLE KIYEOK A NIEUN
+0xB0A4 0xAC07 #HANGUL SYLLABLE KIYEOK A TIKEUT
+0xB0A5 0xAC08 #HANGUL SYLLABLE KIYEOK A RIEUL
+0xB0A6 0xAC09 #HANGUL SYLLABLE KIYEOK A RIEULKIYEOK
+0xB0A7 0xAC0A #HANGUL SYLLABLE KIYEOK A RIEULMIEUM
+0xB0A8 0xAC10 #HANGUL SYLLABLE KIYEOK A MIEUM
+0xB0A9 0xAC11 #HANGUL SYLLABLE KIYEOK A PIEUP
+0xB0AA 0xAC12 #HANGUL SYLLABLE KIYEOK A PIEUPSIOS
+0xB0AB 0xAC13 #HANGUL SYLLABLE KIYEOK A SIOS
+0xB0AC 0xAC14 #HANGUL SYLLABLE KIYEOK A SSANGSIOS
+0xB0AD 0xAC15 #HANGUL SYLLABLE KIYEOK A IEUNG
+0xB0AE 0xAC16 #HANGUL SYLLABLE KIYEOK A CIEUC
+0xB0AF 0xAC17 #HANGUL SYLLABLE KIYEOK A CHIEUCH
+0xB0B0 0xAC19 #HANGUL SYLLABLE KIYEOK A THIEUTH
+0xB0B1 0xAC1A #HANGUL SYLLABLE KIYEOK A PHIEUPH
+0xB0B2 0xAC1B #HANGUL SYLLABLE KIYEOK A HIEUH
+0xB0B3 0xAC1C #HANGUL SYLLABLE KIYEOK AE
+0xB0B4 0xAC1D #HANGUL SYLLABLE KIYEOK AE KIYEOK
+0xB0B5 0xAC20 #HANGUL SYLLABLE KIYEOK AE NIEUN
+0xB0B6 0xAC24 #HANGUL SYLLABLE KIYEOK AE RIEUL
+0xB0B7 0xAC2C #HANGUL SYLLABLE KIYEOK AE MIEUM
+0xB0B8 0xAC2D #HANGUL SYLLABLE KIYEOK AE PIEUP
+0xB0B9 0xAC2F #HANGUL SYLLABLE KIYEOK AE SIOS
+0xB0BA 0xAC30 #HANGUL SYLLABLE KIYEOK AE SSANGSIOS
+0xB0BB 0xAC31 #HANGUL SYLLABLE KIYEOK AE IEUNG
+0xB0BC 0xAC38 #HANGUL SYLLABLE KIYEOK YA
+0xB0BD 0xAC39 #HANGUL SYLLABLE KIYEOK YA KIYEOK
+0xB0BE 0xAC3C #HANGUL SYLLABLE KIYEOK YA NIEUN
+0xB0BF 0xAC40 #HANGUL SYLLABLE KIYEOK YA RIEUL
+0xB0C0 0xAC4B #HANGUL SYLLABLE KIYEOK YA SIOS
+0xB0C1 0xAC4D #HANGUL SYLLABLE KIYEOK YA IEUNG
+0xB0C2 0xAC54 #HANGUL SYLLABLE KIYEOK YAE
+0xB0C3 0xAC58 #HANGUL SYLLABLE KIYEOK YAE NIEUN
+0xB0C4 0xAC5C #HANGUL SYLLABLE KIYEOK YAE RIEUL
+0xB0C5 0xAC70 #HANGUL SYLLABLE KIYEOK EO
+0xB0C6 0xAC71 #HANGUL SYLLABLE KIYEOK EO KIYEOK
+0xB0C7 0xAC74 #HANGUL SYLLABLE KIYEOK EO NIEUN
+0xB0C8 0xAC77 #HANGUL SYLLABLE KIYEOK EO TIKEUT
+0xB0C9 0xAC78 #HANGUL SYLLABLE KIYEOK EO RIEUL
+0xB0CA 0xAC7A #HANGUL SYLLABLE KIYEOK EO RIEULMIEUM
+0xB0CB 0xAC80 #HANGUL SYLLABLE KIYEOK EO MIEUM
+0xB0CC 0xAC81 #HANGUL SYLLABLE KIYEOK EO PIEUP
+0xB0CD 0xAC83 #HANGUL SYLLABLE KIYEOK EO SIOS
+0xB0CE 0xAC84 #HANGUL SYLLABLE KIYEOK EO SSANGSIOS
+0xB0CF 0xAC85 #HANGUL SYLLABLE KIYEOK EO IEUNG
+0xB0D0 0xAC86 #HANGUL SYLLABLE KIYEOK EO CIEUC
+0xB0D1 0xAC89 #HANGUL SYLLABLE KIYEOK EO THIEUTH
+0xB0D2 0xAC8A #HANGUL SYLLABLE KIYEOK EO PHIEUPH
+0xB0D3 0xAC8B #HANGUL SYLLABLE KIYEOK EO HIEUH
+0xB0D4 0xAC8C #HANGUL SYLLABLE KIYEOK E
+0xB0D5 0xAC90 #HANGUL SYLLABLE KIYEOK E NIEUN
+0xB0D6 0xAC94 #HANGUL SYLLABLE KIYEOK E RIEUL
+0xB0D7 0xAC9C #HANGUL SYLLABLE KIYEOK E MIEUM
+0xB0D8 0xAC9D #HANGUL SYLLABLE KIYEOK E PIEUP
+0xB0D9 0xAC9F #HANGUL SYLLABLE KIYEOK E SIOS
+0xB0DA 0xACA0 #HANGUL SYLLABLE KIYEOK E SSANGSIOS
+0xB0DB 0xACA1 #HANGUL SYLLABLE KIYEOK E IEUNG
+0xB0DC 0xACA8 #HANGUL SYLLABLE KIYEOK YEO
+0xB0DD 0xACA9 #HANGUL SYLLABLE KIYEOK YEO KIYEOK
+0xB0DE 0xACAA #HANGUL SYLLABLE KIYEOK YEO SSANGKIYEOK
+0xB0DF 0xACAC #HANGUL SYLLABLE KIYEOK YEO NIEUN
+0xB0E0 0xACAF #HANGUL SYLLABLE KIYEOK YEO TIKEUT
+0xB0E1 0xACB0 #HANGUL SYLLABLE KIYEOK YEO RIEUL
+0xB0E2 0xACB8 #HANGUL SYLLABLE KIYEOK YEO MIEUM
+0xB0E3 0xACB9 #HANGUL SYLLABLE KIYEOK YEO PIEUP
+0xB0E4 0xACBB #HANGUL SYLLABLE KIYEOK YEO SIOS
+0xB0E5 0xACBC #HANGUL SYLLABLE KIYEOK YEO SSANGSIOS
+0xB0E6 0xACBD #HANGUL SYLLABLE KIYEOK YEO IEUNG
+0xB0E7 0xACC1 #HANGUL SYLLABLE KIYEOK YEO THIEUTH
+0xB0E8 0xACC4 #HANGUL SYLLABLE KIYEOK YE
+0xB0E9 0xACC8 #HANGUL SYLLABLE KIYEOK YE NIEUN
+0xB0EA 0xACCC #HANGUL SYLLABLE KIYEOK YE RIEUL
+0xB0EB 0xACD5 #HANGUL SYLLABLE KIYEOK YE PIEUP
+0xB0EC 0xACD7 #HANGUL SYLLABLE KIYEOK YE SIOS
+0xB0ED 0xACE0 #HANGUL SYLLABLE KIYEOK O
+0xB0EE 0xACE1 #HANGUL SYLLABLE KIYEOK O KIYEOK
+0xB0EF 0xACE4 #HANGUL SYLLABLE KIYEOK O NIEUN
+0xB0F0 0xACE7 #HANGUL SYLLABLE KIYEOK O TIKEUT
+0xB0F1 0xACE8 #HANGUL SYLLABLE KIYEOK O RIEUL
+0xB0F2 0xACEA #HANGUL SYLLABLE KIYEOK O RIEULMIEUM
+0xB0F3 0xACEC #HANGUL SYLLABLE KIYEOK O RIEULSIOS
+0xB0F4 0xACEF #HANGUL SYLLABLE KIYEOK O RIEULHIEUH
+0xB0F5 0xACF0 #HANGUL SYLLABLE KIYEOK O MIEUM
+0xB0F6 0xACF1 #HANGUL SYLLABLE KIYEOK O PIEUP
+0xB0F7 0xACF3 #HANGUL SYLLABLE KIYEOK O SIOS
+0xB0F8 0xACF5 #HANGUL SYLLABLE KIYEOK O IEUNG
+0xB0F9 0xACF6 #HANGUL SYLLABLE KIYEOK O CIEUC
+0xB0FA 0xACFC #HANGUL SYLLABLE KIYEOK WA
+0xB0FB 0xACFD #HANGUL SYLLABLE KIYEOK WA KIYEOK
+0xB0FC 0xAD00 #HANGUL SYLLABLE KIYEOK WA NIEUN
+0xB0FD 0xAD04 #HANGUL SYLLABLE KIYEOK WA RIEUL
+0xB0FE 0xAD06 #HANGUL SYLLABLE KIYEOK WA RIEULMIEUM
+0xB141 0xCF02 #HANGUL SYLLABLE KHIEUKH E SSANGKIYEOK
+0xB142 0xCF03 #HANGUL SYLLABLE KHIEUKH E KIYEOKSIOS
+0xB143 0xCF05 #HANGUL SYLLABLE KHIEUKH E NIEUNCIEUC
+0xB144 0xCF06 #HANGUL SYLLABLE KHIEUKH E NIEUNHIEUH
+0xB145 0xCF07 #HANGUL SYLLABLE KHIEUKH E TIKEUT
+0xB146 0xCF09 #HANGUL SYLLABLE KHIEUKH E RIEULKIYEOK
+0xB147 0xCF0A #HANGUL SYLLABLE KHIEUKH E RIEULMIEUM
+0xB148 0xCF0B #HANGUL SYLLABLE KHIEUKH E RIEULPIEUP
+0xB149 0xCF0C #HANGUL SYLLABLE KHIEUKH E RIEULSIOS
+0xB14A 0xCF0D #HANGUL SYLLABLE KHIEUKH E RIEULTHIEUTH
+0xB14B 0xCF0E #HANGUL SYLLABLE KHIEUKH E RIEULPHIEUPH
+0xB14C 0xCF0F #HANGUL SYLLABLE KHIEUKH E RIEULHIEUH
+0xB14D 0xCF12 #HANGUL SYLLABLE KHIEUKH E PIEUPSIOS
+0xB14E 0xCF14 #HANGUL SYLLABLE KHIEUKH E SSANGSIOS
+0xB14F 0xCF16 #HANGUL SYLLABLE KHIEUKH E CIEUC
+0xB150 0xCF17 #HANGUL SYLLABLE KHIEUKH E CHIEUCH
+0xB151 0xCF18 #HANGUL SYLLABLE KHIEUKH E KHIEUKH
+0xB152 0xCF19 #HANGUL SYLLABLE KHIEUKH E THIEUTH
+0xB153 0xCF1A #HANGUL SYLLABLE KHIEUKH E PHIEUPH
+0xB154 0xCF1B #HANGUL SYLLABLE KHIEUKH E HIEUH
+0xB155 0xCF1D #HANGUL SYLLABLE KHIEUKH YEO KIYEOK
+0xB156 0xCF1E #HANGUL SYLLABLE KHIEUKH YEO SSANGKIYEOK
+0xB157 0xCF1F #HANGUL SYLLABLE KHIEUKH YEO KIYEOKSIOS
+0xB158 0xCF21 #HANGUL SYLLABLE KHIEUKH YEO NIEUNCIEUC
+0xB159 0xCF22 #HANGUL SYLLABLE KHIEUKH YEO NIEUNHIEUH
+0xB15A 0xCF23 #HANGUL SYLLABLE KHIEUKH YEO TIKEUT
+0xB161 0xCF25 #HANGUL SYLLABLE KHIEUKH YEO RIEULKIYEOK
+0xB162 0xCF26 #HANGUL SYLLABLE KHIEUKH YEO RIEULMIEUM
+0xB163 0xCF27 #HANGUL SYLLABLE KHIEUKH YEO RIEULPIEUP
+0xB164 0xCF28 #HANGUL SYLLABLE KHIEUKH YEO RIEULSIOS
+0xB165 0xCF29 #HANGUL SYLLABLE KHIEUKH YEO RIEULTHIEUTH
+0xB166 0xCF2A #HANGUL SYLLABLE KHIEUKH YEO RIEULPHIEUPH
+0xB167 0xCF2B #HANGUL SYLLABLE KHIEUKH YEO RIEULHIEUH
+0xB168 0xCF2E #HANGUL SYLLABLE KHIEUKH YEO PIEUPSIOS
+0xB169 0xCF32 #HANGUL SYLLABLE KHIEUKH YEO CIEUC
+0xB16A 0xCF33 #HANGUL SYLLABLE KHIEUKH YEO CHIEUCH
+0xB16B 0xCF34 #HANGUL SYLLABLE KHIEUKH YEO KHIEUKH
+0xB16C 0xCF35 #HANGUL SYLLABLE KHIEUKH YEO THIEUTH
+0xB16D 0xCF36 #HANGUL SYLLABLE KHIEUKH YEO PHIEUPH
+0xB16E 0xCF37 #HANGUL SYLLABLE KHIEUKH YEO HIEUH
+0xB16F 0xCF39 #HANGUL SYLLABLE KHIEUKH YE KIYEOK
+0xB170 0xCF3A #HANGUL SYLLABLE KHIEUKH YE SSANGKIYEOK
+0xB171 0xCF3B #HANGUL SYLLABLE KHIEUKH YE KIYEOKSIOS
+0xB172 0xCF3C #HANGUL SYLLABLE KHIEUKH YE NIEUN
+0xB173 0xCF3D #HANGUL SYLLABLE KHIEUKH YE NIEUNCIEUC
+0xB174 0xCF3E #HANGUL SYLLABLE KHIEUKH YE NIEUNHIEUH
+0xB175 0xCF3F #HANGUL SYLLABLE KHIEUKH YE TIKEUT
+0xB176 0xCF40 #HANGUL SYLLABLE KHIEUKH YE RIEUL
+0xB177 0xCF41 #HANGUL SYLLABLE KHIEUKH YE RIEULKIYEOK
+0xB178 0xCF42 #HANGUL SYLLABLE KHIEUKH YE RIEULMIEUM
+0xB179 0xCF43 #HANGUL SYLLABLE KHIEUKH YE RIEULPIEUP
+0xB17A 0xCF44 #HANGUL SYLLABLE KHIEUKH YE RIEULSIOS
+0xB181 0xCF45 #HANGUL SYLLABLE KHIEUKH YE RIEULTHIEUTH
+0xB182 0xCF46 #HANGUL SYLLABLE KHIEUKH YE RIEULPHIEUPH
+0xB183 0xCF47 #HANGUL SYLLABLE KHIEUKH YE RIEULHIEUH
+0xB184 0xCF48 #HANGUL SYLLABLE KHIEUKH YE MIEUM
+0xB185 0xCF49 #HANGUL SYLLABLE KHIEUKH YE PIEUP
+0xB186 0xCF4A #HANGUL SYLLABLE KHIEUKH YE PIEUPSIOS
+0xB187 0xCF4B #HANGUL SYLLABLE KHIEUKH YE SIOS
+0xB188 0xCF4C #HANGUL SYLLABLE KHIEUKH YE SSANGSIOS
+0xB189 0xCF4D #HANGUL SYLLABLE KHIEUKH YE IEUNG
+0xB18A 0xCF4E #HANGUL SYLLABLE KHIEUKH YE CIEUC
+0xB18B 0xCF4F #HANGUL SYLLABLE KHIEUKH YE CHIEUCH
+0xB18C 0xCF50 #HANGUL SYLLABLE KHIEUKH YE KHIEUKH
+0xB18D 0xCF51 #HANGUL SYLLABLE KHIEUKH YE THIEUTH
+0xB18E 0xCF52 #HANGUL SYLLABLE KHIEUKH YE PHIEUPH
+0xB18F 0xCF53 #HANGUL SYLLABLE KHIEUKH YE HIEUH
+0xB190 0xCF56 #HANGUL SYLLABLE KHIEUKH O SSANGKIYEOK
+0xB191 0xCF57 #HANGUL SYLLABLE KHIEUKH O KIYEOKSIOS
+0xB192 0xCF59 #HANGUL SYLLABLE KHIEUKH O NIEUNCIEUC
+0xB193 0xCF5A #HANGUL SYLLABLE KHIEUKH O NIEUNHIEUH
+0xB194 0xCF5B #HANGUL SYLLABLE KHIEUKH O TIKEUT
+0xB195 0xCF5D #HANGUL SYLLABLE KHIEUKH O RIEULKIYEOK
+0xB196 0xCF5E #HANGUL SYLLABLE KHIEUKH O RIEULMIEUM
+0xB197 0xCF5F #HANGUL SYLLABLE KHIEUKH O RIEULPIEUP
+0xB198 0xCF60 #HANGUL SYLLABLE KHIEUKH O RIEULSIOS
+0xB199 0xCF61 #HANGUL SYLLABLE KHIEUKH O RIEULTHIEUTH
+0xB19A 0xCF62 #HANGUL SYLLABLE KHIEUKH O RIEULPHIEUPH
+0xB19B 0xCF63 #HANGUL SYLLABLE KHIEUKH O RIEULHIEUH
+0xB19C 0xCF66 #HANGUL SYLLABLE KHIEUKH O PIEUPSIOS
+0xB19D 0xCF68 #HANGUL SYLLABLE KHIEUKH O SSANGSIOS
+0xB19E 0xCF6A #HANGUL SYLLABLE KHIEUKH O CIEUC
+0xB19F 0xCF6B #HANGUL SYLLABLE KHIEUKH O CHIEUCH
+0xB1A0 0xCF6C #HANGUL SYLLABLE KHIEUKH O KHIEUKH
+0xB1A1 0xAD0C #HANGUL SYLLABLE KIYEOK WA MIEUM
+0xB1A2 0xAD0D #HANGUL SYLLABLE KIYEOK WA PIEUP
+0xB1A3 0xAD0F #HANGUL SYLLABLE KIYEOK WA SIOS
+0xB1A4 0xAD11 #HANGUL SYLLABLE KIYEOK WA IEUNG
+0xB1A5 0xAD18 #HANGUL SYLLABLE KIYEOK WAE
+0xB1A6 0xAD1C #HANGUL SYLLABLE KIYEOK WAE NIEUN
+0xB1A7 0xAD20 #HANGUL SYLLABLE KIYEOK WAE RIEUL
+0xB1A8 0xAD29 #HANGUL SYLLABLE KIYEOK WAE PIEUP
+0xB1A9 0xAD2C #HANGUL SYLLABLE KIYEOK WAE SSANGSIOS
+0xB1AA 0xAD2D #HANGUL SYLLABLE KIYEOK WAE IEUNG
+0xB1AB 0xAD34 #HANGUL SYLLABLE KIYEOK OE
+0xB1AC 0xAD35 #HANGUL SYLLABLE KIYEOK OE KIYEOK
+0xB1AD 0xAD38 #HANGUL SYLLABLE KIYEOK OE NIEUN
+0xB1AE 0xAD3C #HANGUL SYLLABLE KIYEOK OE RIEUL
+0xB1AF 0xAD44 #HANGUL SYLLABLE KIYEOK OE MIEUM
+0xB1B0 0xAD45 #HANGUL SYLLABLE KIYEOK OE PIEUP
+0xB1B1 0xAD47 #HANGUL SYLLABLE KIYEOK OE SIOS
+0xB1B2 0xAD49 #HANGUL SYLLABLE KIYEOK OE IEUNG
+0xB1B3 0xAD50 #HANGUL SYLLABLE KIYEOK YO
+0xB1B4 0xAD54 #HANGUL SYLLABLE KIYEOK YO NIEUN
+0xB1B5 0xAD58 #HANGUL SYLLABLE KIYEOK YO RIEUL
+0xB1B6 0xAD61 #HANGUL SYLLABLE KIYEOK YO PIEUP
+0xB1B7 0xAD63 #HANGUL SYLLABLE KIYEOK YO SIOS
+0xB1B8 0xAD6C #HANGUL SYLLABLE KIYEOK U
+0xB1B9 0xAD6D #HANGUL SYLLABLE KIYEOK U KIYEOK
+0xB1BA 0xAD70 #HANGUL SYLLABLE KIYEOK U NIEUN
+0xB1BB 0xAD73 #HANGUL SYLLABLE KIYEOK U TIKEUT
+0xB1BC 0xAD74 #HANGUL SYLLABLE KIYEOK U RIEUL
+0xB1BD 0xAD75 #HANGUL SYLLABLE KIYEOK U RIEULKIYEOK
+0xB1BE 0xAD76 #HANGUL SYLLABLE KIYEOK U RIEULMIEUM
+0xB1BF 0xAD7B #HANGUL SYLLABLE KIYEOK U RIEULHIEUH
+0xB1C0 0xAD7C #HANGUL SYLLABLE KIYEOK U MIEUM
+0xB1C1 0xAD7D #HANGUL SYLLABLE KIYEOK U PIEUP
+0xB1C2 0xAD7F #HANGUL SYLLABLE KIYEOK U SIOS
+0xB1C3 0xAD81 #HANGUL SYLLABLE KIYEOK U IEUNG
+0xB1C4 0xAD82 #HANGUL SYLLABLE KIYEOK U CIEUC
+0xB1C5 0xAD88 #HANGUL SYLLABLE KIYEOK WEO
+0xB1C6 0xAD89 #HANGUL SYLLABLE KIYEOK WEO KIYEOK
+0xB1C7 0xAD8C #HANGUL SYLLABLE KIYEOK WEO NIEUN
+0xB1C8 0xAD90 #HANGUL SYLLABLE KIYEOK WEO RIEUL
+0xB1C9 0xAD9C #HANGUL SYLLABLE KIYEOK WEO SSANGSIOS
+0xB1CA 0xAD9D #HANGUL SYLLABLE KIYEOK WEO IEUNG
+0xB1CB 0xADA4 #HANGUL SYLLABLE KIYEOK WE
+0xB1CC 0xADB7 #HANGUL SYLLABLE KIYEOK WE SIOS
+0xB1CD 0xADC0 #HANGUL SYLLABLE KIYEOK WI
+0xB1CE 0xADC1 #HANGUL SYLLABLE KIYEOK WI KIYEOK
+0xB1CF 0xADC4 #HANGUL SYLLABLE KIYEOK WI NIEUN
+0xB1D0 0xADC8 #HANGUL SYLLABLE KIYEOK WI RIEUL
+0xB1D1 0xADD0 #HANGUL SYLLABLE KIYEOK WI MIEUM
+0xB1D2 0xADD1 #HANGUL SYLLABLE KIYEOK WI PIEUP
+0xB1D3 0xADD3 #HANGUL SYLLABLE KIYEOK WI SIOS
+0xB1D4 0xADDC #HANGUL SYLLABLE KIYEOK YU
+0xB1D5 0xADE0 #HANGUL SYLLABLE KIYEOK YU NIEUN
+0xB1D6 0xADE4 #HANGUL SYLLABLE KIYEOK YU RIEUL
+0xB1D7 0xADF8 #HANGUL SYLLABLE KIYEOK EU
+0xB1D8 0xADF9 #HANGUL SYLLABLE KIYEOK EU KIYEOK
+0xB1D9 0xADFC #HANGUL SYLLABLE KIYEOK EU NIEUN
+0xB1DA 0xADFF #HANGUL SYLLABLE KIYEOK EU TIKEUT
+0xB1DB 0xAE00 #HANGUL SYLLABLE KIYEOK EU RIEUL
+0xB1DC 0xAE01 #HANGUL SYLLABLE KIYEOK EU RIEULKIYEOK
+0xB1DD 0xAE08 #HANGUL SYLLABLE KIYEOK EU MIEUM
+0xB1DE 0xAE09 #HANGUL SYLLABLE KIYEOK EU PIEUP
+0xB1DF 0xAE0B #HANGUL SYLLABLE KIYEOK EU SIOS
+0xB1E0 0xAE0D #HANGUL SYLLABLE KIYEOK EU IEUNG
+0xB1E1 0xAE14 #HANGUL SYLLABLE KIYEOK YI
+0xB1E2 0xAE30 #HANGUL SYLLABLE KIYEOK I
+0xB1E3 0xAE31 #HANGUL SYLLABLE KIYEOK I KIYEOK
+0xB1E4 0xAE34 #HANGUL SYLLABLE KIYEOK I NIEUN
+0xB1E5 0xAE37 #HANGUL SYLLABLE KIYEOK I TIKEUT
+0xB1E6 0xAE38 #HANGUL SYLLABLE KIYEOK I RIEUL
+0xB1E7 0xAE3A #HANGUL SYLLABLE KIYEOK I RIEULMIEUM
+0xB1E8 0xAE40 #HANGUL SYLLABLE KIYEOK I MIEUM
+0xB1E9 0xAE41 #HANGUL SYLLABLE KIYEOK I PIEUP
+0xB1EA 0xAE43 #HANGUL SYLLABLE KIYEOK I SIOS
+0xB1EB 0xAE45 #HANGUL SYLLABLE KIYEOK I IEUNG
+0xB1EC 0xAE46 #HANGUL SYLLABLE KIYEOK I CIEUC
+0xB1ED 0xAE4A #HANGUL SYLLABLE KIYEOK I PHIEUPH
+0xB1EE 0xAE4C #HANGUL SYLLABLE SSANGKIYEOK A
+0xB1EF 0xAE4D #HANGUL SYLLABLE SSANGKIYEOK A KIYEOK
+0xB1F0 0xAE4E #HANGUL SYLLABLE SSANGKIYEOK A SSANGKIYEOK
+0xB1F1 0xAE50 #HANGUL SYLLABLE SSANGKIYEOK A NIEUN
+0xB1F2 0xAE54 #HANGUL SYLLABLE SSANGKIYEOK A RIEUL
+0xB1F3 0xAE56 #HANGUL SYLLABLE SSANGKIYEOK A RIEULMIEUM
+0xB1F4 0xAE5C #HANGUL SYLLABLE SSANGKIYEOK A MIEUM
+0xB1F5 0xAE5D #HANGUL SYLLABLE SSANGKIYEOK A PIEUP
+0xB1F6 0xAE5F #HANGUL SYLLABLE SSANGKIYEOK A SIOS
+0xB1F7 0xAE60 #HANGUL SYLLABLE SSANGKIYEOK A SSANGSIOS
+0xB1F8 0xAE61 #HANGUL SYLLABLE SSANGKIYEOK A IEUNG
+0xB1F9 0xAE65 #HANGUL SYLLABLE SSANGKIYEOK A THIEUTH
+0xB1FA 0xAE68 #HANGUL SYLLABLE SSANGKIYEOK AE
+0xB1FB 0xAE69 #HANGUL SYLLABLE SSANGKIYEOK AE KIYEOK
+0xB1FC 0xAE6C #HANGUL SYLLABLE SSANGKIYEOK AE NIEUN
+0xB1FD 0xAE70 #HANGUL SYLLABLE SSANGKIYEOK AE RIEUL
+0xB1FE 0xAE78 #HANGUL SYLLABLE SSANGKIYEOK AE MIEUM
+0xB241 0xCF6D #HANGUL SYLLABLE KHIEUKH O THIEUTH
+0xB242 0xCF6E #HANGUL SYLLABLE KHIEUKH O PHIEUPH
+0xB243 0xCF6F #HANGUL SYLLABLE KHIEUKH O HIEUH
+0xB244 0xCF72 #HANGUL SYLLABLE KHIEUKH WA SSANGKIYEOK
+0xB245 0xCF73 #HANGUL SYLLABLE KHIEUKH WA KIYEOKSIOS
+0xB246 0xCF75 #HANGUL SYLLABLE KHIEUKH WA NIEUNCIEUC
+0xB247 0xCF76 #HANGUL SYLLABLE KHIEUKH WA NIEUNHIEUH
+0xB248 0xCF77 #HANGUL SYLLABLE KHIEUKH WA TIKEUT
+0xB249 0xCF79 #HANGUL SYLLABLE KHIEUKH WA RIEULKIYEOK
+0xB24A 0xCF7A #HANGUL SYLLABLE KHIEUKH WA RIEULMIEUM
+0xB24B 0xCF7B #HANGUL SYLLABLE KHIEUKH WA RIEULPIEUP
+0xB24C 0xCF7C #HANGUL SYLLABLE KHIEUKH WA RIEULSIOS
+0xB24D 0xCF7D #HANGUL SYLLABLE KHIEUKH WA RIEULTHIEUTH
+0xB24E 0xCF7E #HANGUL SYLLABLE KHIEUKH WA RIEULPHIEUPH
+0xB24F 0xCF7F #HANGUL SYLLABLE KHIEUKH WA RIEULHIEUH
+0xB250 0xCF81 #HANGUL SYLLABLE KHIEUKH WA PIEUP
+0xB251 0xCF82 #HANGUL SYLLABLE KHIEUKH WA PIEUPSIOS
+0xB252 0xCF83 #HANGUL SYLLABLE KHIEUKH WA SIOS
+0xB253 0xCF84 #HANGUL SYLLABLE KHIEUKH WA SSANGSIOS
+0xB254 0xCF86 #HANGUL SYLLABLE KHIEUKH WA CIEUC
+0xB255 0xCF87 #HANGUL SYLLABLE KHIEUKH WA CHIEUCH
+0xB256 0xCF88 #HANGUL SYLLABLE KHIEUKH WA KHIEUKH
+0xB257 0xCF89 #HANGUL SYLLABLE KHIEUKH WA THIEUTH
+0xB258 0xCF8A #HANGUL SYLLABLE KHIEUKH WA PHIEUPH
+0xB259 0xCF8B #HANGUL SYLLABLE KHIEUKH WA HIEUH
+0xB25A 0xCF8D #HANGUL SYLLABLE KHIEUKH WAE KIYEOK
+0xB261 0xCF8E #HANGUL SYLLABLE KHIEUKH WAE SSANGKIYEOK
+0xB262 0xCF8F #HANGUL SYLLABLE KHIEUKH WAE KIYEOKSIOS
+0xB263 0xCF90 #HANGUL SYLLABLE KHIEUKH WAE NIEUN
+0xB264 0xCF91 #HANGUL SYLLABLE KHIEUKH WAE NIEUNCIEUC
+0xB265 0xCF92 #HANGUL SYLLABLE KHIEUKH WAE NIEUNHIEUH
+0xB266 0xCF93 #HANGUL SYLLABLE KHIEUKH WAE TIKEUT
+0xB267 0xCF94 #HANGUL SYLLABLE KHIEUKH WAE RIEUL
+0xB268 0xCF95 #HANGUL SYLLABLE KHIEUKH WAE RIEULKIYEOK
+0xB269 0xCF96 #HANGUL SYLLABLE KHIEUKH WAE RIEULMIEUM
+0xB26A 0xCF97 #HANGUL SYLLABLE KHIEUKH WAE RIEULPIEUP
+0xB26B 0xCF98 #HANGUL SYLLABLE KHIEUKH WAE RIEULSIOS
+0xB26C 0xCF99 #HANGUL SYLLABLE KHIEUKH WAE RIEULTHIEUTH
+0xB26D 0xCF9A #HANGUL SYLLABLE KHIEUKH WAE RIEULPHIEUPH
+0xB26E 0xCF9B #HANGUL SYLLABLE KHIEUKH WAE RIEULHIEUH
+0xB26F 0xCF9C #HANGUL SYLLABLE KHIEUKH WAE MIEUM
+0xB270 0xCF9D #HANGUL SYLLABLE KHIEUKH WAE PIEUP
+0xB271 0xCF9E #HANGUL SYLLABLE KHIEUKH WAE PIEUPSIOS
+0xB272 0xCF9F #HANGUL SYLLABLE KHIEUKH WAE SIOS
+0xB273 0xCFA0 #HANGUL SYLLABLE KHIEUKH WAE SSANGSIOS
+0xB274 0xCFA2 #HANGUL SYLLABLE KHIEUKH WAE CIEUC
+0xB275 0xCFA3 #HANGUL SYLLABLE KHIEUKH WAE CHIEUCH
+0xB276 0xCFA4 #HANGUL SYLLABLE KHIEUKH WAE KHIEUKH
+0xB277 0xCFA5 #HANGUL SYLLABLE KHIEUKH WAE THIEUTH
+0xB278 0xCFA6 #HANGUL SYLLABLE KHIEUKH WAE PHIEUPH
+0xB279 0xCFA7 #HANGUL SYLLABLE KHIEUKH WAE HIEUH
+0xB27A 0xCFA9 #HANGUL SYLLABLE KHIEUKH OE KIYEOK
+0xB281 0xCFAA #HANGUL SYLLABLE KHIEUKH OE SSANGKIYEOK
+0xB282 0xCFAB #HANGUL SYLLABLE KHIEUKH OE KIYEOKSIOS
+0xB283 0xCFAC #HANGUL SYLLABLE KHIEUKH OE NIEUN
+0xB284 0xCFAD #HANGUL SYLLABLE KHIEUKH OE NIEUNCIEUC
+0xB285 0xCFAE #HANGUL SYLLABLE KHIEUKH OE NIEUNHIEUH
+0xB286 0xCFAF #HANGUL SYLLABLE KHIEUKH OE TIKEUT
+0xB287 0xCFB1 #HANGUL SYLLABLE KHIEUKH OE RIEULKIYEOK
+0xB288 0xCFB2 #HANGUL SYLLABLE KHIEUKH OE RIEULMIEUM
+0xB289 0xCFB3 #HANGUL SYLLABLE KHIEUKH OE RIEULPIEUP
+0xB28A 0xCFB4 #HANGUL SYLLABLE KHIEUKH OE RIEULSIOS
+0xB28B 0xCFB5 #HANGUL SYLLABLE KHIEUKH OE RIEULTHIEUTH
+0xB28C 0xCFB6 #HANGUL SYLLABLE KHIEUKH OE RIEULPHIEUPH
+0xB28D 0xCFB7 #HANGUL SYLLABLE KHIEUKH OE RIEULHIEUH
+0xB28E 0xCFB8 #HANGUL SYLLABLE KHIEUKH OE MIEUM
+0xB28F 0xCFB9 #HANGUL SYLLABLE KHIEUKH OE PIEUP
+0xB290 0xCFBA #HANGUL SYLLABLE KHIEUKH OE PIEUPSIOS
+0xB291 0xCFBB #HANGUL SYLLABLE KHIEUKH OE SIOS
+0xB292 0xCFBC #HANGUL SYLLABLE KHIEUKH OE SSANGSIOS
+0xB293 0xCFBD #HANGUL SYLLABLE KHIEUKH OE IEUNG
+0xB294 0xCFBE #HANGUL SYLLABLE KHIEUKH OE CIEUC
+0xB295 0xCFBF #HANGUL SYLLABLE KHIEUKH OE CHIEUCH
+0xB296 0xCFC0 #HANGUL SYLLABLE KHIEUKH OE KHIEUKH
+0xB297 0xCFC1 #HANGUL SYLLABLE KHIEUKH OE THIEUTH
+0xB298 0xCFC2 #HANGUL SYLLABLE KHIEUKH OE PHIEUPH
+0xB299 0xCFC3 #HANGUL SYLLABLE KHIEUKH OE HIEUH
+0xB29A 0xCFC5 #HANGUL SYLLABLE KHIEUKH YO KIYEOK
+0xB29B 0xCFC6 #HANGUL SYLLABLE KHIEUKH YO SSANGKIYEOK
+0xB29C 0xCFC7 #HANGUL SYLLABLE KHIEUKH YO KIYEOKSIOS
+0xB29D 0xCFC8 #HANGUL SYLLABLE KHIEUKH YO NIEUN
+0xB29E 0xCFC9 #HANGUL SYLLABLE KHIEUKH YO NIEUNCIEUC
+0xB29F 0xCFCA #HANGUL SYLLABLE KHIEUKH YO NIEUNHIEUH
+0xB2A0 0xCFCB #HANGUL SYLLABLE KHIEUKH YO TIKEUT
+0xB2A1 0xAE79 #HANGUL SYLLABLE SSANGKIYEOK AE PIEUP
+0xB2A2 0xAE7B #HANGUL SYLLABLE SSANGKIYEOK AE SIOS
+0xB2A3 0xAE7C #HANGUL SYLLABLE SSANGKIYEOK AE SSANGSIOS
+0xB2A4 0xAE7D #HANGUL SYLLABLE SSANGKIYEOK AE IEUNG
+0xB2A5 0xAE84 #HANGUL SYLLABLE SSANGKIYEOK YA
+0xB2A6 0xAE85 #HANGUL SYLLABLE SSANGKIYEOK YA KIYEOK
+0xB2A7 0xAE8C #HANGUL SYLLABLE SSANGKIYEOK YA RIEUL
+0xB2A8 0xAEBC #HANGUL SYLLABLE SSANGKIYEOK EO
+0xB2A9 0xAEBD #HANGUL SYLLABLE SSANGKIYEOK EO KIYEOK
+0xB2AA 0xAEBE #HANGUL SYLLABLE SSANGKIYEOK EO SSANGKIYEOK
+0xB2AB 0xAEC0 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUN
+0xB2AC 0xAEC4 #HANGUL SYLLABLE SSANGKIYEOK EO RIEUL
+0xB2AD 0xAECC #HANGUL SYLLABLE SSANGKIYEOK EO MIEUM
+0xB2AE 0xAECD #HANGUL SYLLABLE SSANGKIYEOK EO PIEUP
+0xB2AF 0xAECF #HANGUL SYLLABLE SSANGKIYEOK EO SIOS
+0xB2B0 0xAED0 #HANGUL SYLLABLE SSANGKIYEOK EO SSANGSIOS
+0xB2B1 0xAED1 #HANGUL SYLLABLE SSANGKIYEOK EO IEUNG
+0xB2B2 0xAED8 #HANGUL SYLLABLE SSANGKIYEOK E
+0xB2B3 0xAED9 #HANGUL SYLLABLE SSANGKIYEOK E KIYEOK
+0xB2B4 0xAEDC #HANGUL SYLLABLE SSANGKIYEOK E NIEUN
+0xB2B5 0xAEE8 #HANGUL SYLLABLE SSANGKIYEOK E MIEUM
+0xB2B6 0xAEEB #HANGUL SYLLABLE SSANGKIYEOK E SIOS
+0xB2B7 0xAEED #HANGUL SYLLABLE SSANGKIYEOK E IEUNG
+0xB2B8 0xAEF4 #HANGUL SYLLABLE SSANGKIYEOK YEO
+0xB2B9 0xAEF8 #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUN
+0xB2BA 0xAEFC #HANGUL SYLLABLE SSANGKIYEOK YEO RIEUL
+0xB2BB 0xAF07 #HANGUL SYLLABLE SSANGKIYEOK YEO SIOS
+0xB2BC 0xAF08 #HANGUL SYLLABLE SSANGKIYEOK YEO SSANGSIOS
+0xB2BD 0xAF0D #HANGUL SYLLABLE SSANGKIYEOK YEO THIEUTH
+0xB2BE 0xAF10 #HANGUL SYLLABLE SSANGKIYEOK YE
+0xB2BF 0xAF2C #HANGUL SYLLABLE SSANGKIYEOK O
+0xB2C0 0xAF2D #HANGUL SYLLABLE SSANGKIYEOK O KIYEOK
+0xB2C1 0xAF30 #HANGUL SYLLABLE SSANGKIYEOK O NIEUN
+0xB2C2 0xAF32 #HANGUL SYLLABLE SSANGKIYEOK O NIEUNHIEUH
+0xB2C3 0xAF34 #HANGUL SYLLABLE SSANGKIYEOK O RIEUL
+0xB2C4 0xAF3C #HANGUL SYLLABLE SSANGKIYEOK O MIEUM
+0xB2C5 0xAF3D #HANGUL SYLLABLE SSANGKIYEOK O PIEUP
+0xB2C6 0xAF3F #HANGUL SYLLABLE SSANGKIYEOK O SIOS
+0xB2C7 0xAF41 #HANGUL SYLLABLE SSANGKIYEOK O IEUNG
+0xB2C8 0xAF42 #HANGUL SYLLABLE SSANGKIYEOK O CIEUC
+0xB2C9 0xAF43 #HANGUL SYLLABLE SSANGKIYEOK O CHIEUCH
+0xB2CA 0xAF48 #HANGUL SYLLABLE SSANGKIYEOK WA
+0xB2CB 0xAF49 #HANGUL SYLLABLE SSANGKIYEOK WA KIYEOK
+0xB2CC 0xAF50 #HANGUL SYLLABLE SSANGKIYEOK WA RIEUL
+0xB2CD 0xAF5C #HANGUL SYLLABLE SSANGKIYEOK WA SSANGSIOS
+0xB2CE 0xAF5D #HANGUL SYLLABLE SSANGKIYEOK WA IEUNG
+0xB2CF 0xAF64 #HANGUL SYLLABLE SSANGKIYEOK WAE
+0xB2D0 0xAF65 #HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOK
+0xB2D1 0xAF79 #HANGUL SYLLABLE SSANGKIYEOK WAE IEUNG
+0xB2D2 0xAF80 #HANGUL SYLLABLE SSANGKIYEOK OE
+0xB2D3 0xAF84 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUN
+0xB2D4 0xAF88 #HANGUL SYLLABLE SSANGKIYEOK OE RIEUL
+0xB2D5 0xAF90 #HANGUL SYLLABLE SSANGKIYEOK OE MIEUM
+0xB2D6 0xAF91 #HANGUL SYLLABLE SSANGKIYEOK OE PIEUP
+0xB2D7 0xAF95 #HANGUL SYLLABLE SSANGKIYEOK OE IEUNG
+0xB2D8 0xAF9C #HANGUL SYLLABLE SSANGKIYEOK YO
+0xB2D9 0xAFB8 #HANGUL SYLLABLE SSANGKIYEOK U
+0xB2DA 0xAFB9 #HANGUL SYLLABLE SSANGKIYEOK U KIYEOK
+0xB2DB 0xAFBC #HANGUL SYLLABLE SSANGKIYEOK U NIEUN
+0xB2DC 0xAFC0 #HANGUL SYLLABLE SSANGKIYEOK U RIEUL
+0xB2DD 0xAFC7 #HANGUL SYLLABLE SSANGKIYEOK U RIEULHIEUH
+0xB2DE 0xAFC8 #HANGUL SYLLABLE SSANGKIYEOK U MIEUM
+0xB2DF 0xAFC9 #HANGUL SYLLABLE SSANGKIYEOK U PIEUP
+0xB2E0 0xAFCB #HANGUL SYLLABLE SSANGKIYEOK U SIOS
+0xB2E1 0xAFCD #HANGUL SYLLABLE SSANGKIYEOK U IEUNG
+0xB2E2 0xAFCE #HANGUL SYLLABLE SSANGKIYEOK U CIEUC
+0xB2E3 0xAFD4 #HANGUL SYLLABLE SSANGKIYEOK WEO
+0xB2E4 0xAFDC #HANGUL SYLLABLE SSANGKIYEOK WEO RIEUL
+0xB2E5 0xAFE8 #HANGUL SYLLABLE SSANGKIYEOK WEO SSANGSIOS
+0xB2E6 0xAFE9 #HANGUL SYLLABLE SSANGKIYEOK WEO IEUNG
+0xB2E7 0xAFF0 #HANGUL SYLLABLE SSANGKIYEOK WE
+0xB2E8 0xAFF1 #HANGUL SYLLABLE SSANGKIYEOK WE KIYEOK
+0xB2E9 0xAFF4 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUN
+0xB2EA 0xAFF8 #HANGUL SYLLABLE SSANGKIYEOK WE RIEUL
+0xB2EB 0xB000 #HANGUL SYLLABLE SSANGKIYEOK WE MIEUM
+0xB2EC 0xB001 #HANGUL SYLLABLE SSANGKIYEOK WE PIEUP
+0xB2ED 0xB004 #HANGUL SYLLABLE SSANGKIYEOK WE SSANGSIOS
+0xB2EE 0xB00C #HANGUL SYLLABLE SSANGKIYEOK WI
+0xB2EF 0xB010 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUN
+0xB2F0 0xB014 #HANGUL SYLLABLE SSANGKIYEOK WI RIEUL
+0xB2F1 0xB01C #HANGUL SYLLABLE SSANGKIYEOK WI MIEUM
+0xB2F2 0xB01D #HANGUL SYLLABLE SSANGKIYEOK WI PIEUP
+0xB2F3 0xB028 #HANGUL SYLLABLE SSANGKIYEOK YU
+0xB2F4 0xB044 #HANGUL SYLLABLE SSANGKIYEOK EU
+0xB2F5 0xB045 #HANGUL SYLLABLE SSANGKIYEOK EU KIYEOK
+0xB2F6 0xB048 #HANGUL SYLLABLE SSANGKIYEOK EU NIEUN
+0xB2F7 0xB04A #HANGUL SYLLABLE SSANGKIYEOK EU NIEUNHIEUH
+0xB2F8 0xB04C #HANGUL SYLLABLE SSANGKIYEOK EU RIEUL
+0xB2F9 0xB04E #HANGUL SYLLABLE SSANGKIYEOK EU RIEULMIEUM
+0xB2FA 0xB053 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULHIEUH
+0xB2FB 0xB054 #HANGUL SYLLABLE SSANGKIYEOK EU MIEUM
+0xB2FC 0xB055 #HANGUL SYLLABLE SSANGKIYEOK EU PIEUP
+0xB2FD 0xB057 #HANGUL SYLLABLE SSANGKIYEOK EU SIOS
+0xB2FE 0xB059 #HANGUL SYLLABLE SSANGKIYEOK EU IEUNG
+0xB341 0xCFCC #HANGUL SYLLABLE KHIEUKH YO RIEUL
+0xB342 0xCFCD #HANGUL SYLLABLE KHIEUKH YO RIEULKIYEOK
+0xB343 0xCFCE #HANGUL SYLLABLE KHIEUKH YO RIEULMIEUM
+0xB344 0xCFCF #HANGUL SYLLABLE KHIEUKH YO RIEULPIEUP
+0xB345 0xCFD0 #HANGUL SYLLABLE KHIEUKH YO RIEULSIOS
+0xB346 0xCFD1 #HANGUL SYLLABLE KHIEUKH YO RIEULTHIEUTH
+0xB347 0xCFD2 #HANGUL SYLLABLE KHIEUKH YO RIEULPHIEUPH
+0xB348 0xCFD3 #HANGUL SYLLABLE KHIEUKH YO RIEULHIEUH
+0xB349 0xCFD4 #HANGUL SYLLABLE KHIEUKH YO MIEUM
+0xB34A 0xCFD5 #HANGUL SYLLABLE KHIEUKH YO PIEUP
+0xB34B 0xCFD6 #HANGUL SYLLABLE KHIEUKH YO PIEUPSIOS
+0xB34C 0xCFD7 #HANGUL SYLLABLE KHIEUKH YO SIOS
+0xB34D 0xCFD8 #HANGUL SYLLABLE KHIEUKH YO SSANGSIOS
+0xB34E 0xCFD9 #HANGUL SYLLABLE KHIEUKH YO IEUNG
+0xB34F 0xCFDA #HANGUL SYLLABLE KHIEUKH YO CIEUC
+0xB350 0xCFDB #HANGUL SYLLABLE KHIEUKH YO CHIEUCH
+0xB351 0xCFDC #HANGUL SYLLABLE KHIEUKH YO KHIEUKH
+0xB352 0xCFDD #HANGUL SYLLABLE KHIEUKH YO THIEUTH
+0xB353 0xCFDE #HANGUL SYLLABLE KHIEUKH YO PHIEUPH
+0xB354 0xCFDF #HANGUL SYLLABLE KHIEUKH YO HIEUH
+0xB355 0xCFE2 #HANGUL SYLLABLE KHIEUKH U SSANGKIYEOK
+0xB356 0xCFE3 #HANGUL SYLLABLE KHIEUKH U KIYEOKSIOS
+0xB357 0xCFE5 #HANGUL SYLLABLE KHIEUKH U NIEUNCIEUC
+0xB358 0xCFE6 #HANGUL SYLLABLE KHIEUKH U NIEUNHIEUH
+0xB359 0xCFE7 #HANGUL SYLLABLE KHIEUKH U TIKEUT
+0xB35A 0xCFE9 #HANGUL SYLLABLE KHIEUKH U RIEULKIYEOK
+0xB361 0xCFEA #HANGUL SYLLABLE KHIEUKH U RIEULMIEUM
+0xB362 0xCFEB #HANGUL SYLLABLE KHIEUKH U RIEULPIEUP
+0xB363 0xCFEC #HANGUL SYLLABLE KHIEUKH U RIEULSIOS
+0xB364 0xCFED #HANGUL SYLLABLE KHIEUKH U RIEULTHIEUTH
+0xB365 0xCFEE #HANGUL SYLLABLE KHIEUKH U RIEULPHIEUPH
+0xB366 0xCFEF #HANGUL SYLLABLE KHIEUKH U RIEULHIEUH
+0xB367 0xCFF2 #HANGUL SYLLABLE KHIEUKH U PIEUPSIOS
+0xB368 0xCFF4 #HANGUL SYLLABLE KHIEUKH U SSANGSIOS
+0xB369 0xCFF6 #HANGUL SYLLABLE KHIEUKH U CIEUC
+0xB36A 0xCFF7 #HANGUL SYLLABLE KHIEUKH U CHIEUCH
+0xB36B 0xCFF8 #HANGUL SYLLABLE KHIEUKH U KHIEUKH
+0xB36C 0xCFF9 #HANGUL SYLLABLE KHIEUKH U THIEUTH
+0xB36D 0xCFFA #HANGUL SYLLABLE KHIEUKH U PHIEUPH
+0xB36E 0xCFFB #HANGUL SYLLABLE KHIEUKH U HIEUH
+0xB36F 0xCFFD #HANGUL SYLLABLE KHIEUKH WEO KIYEOK
+0xB370 0xCFFE #HANGUL SYLLABLE KHIEUKH WEO SSANGKIYEOK
+0xB371 0xCFFF #HANGUL SYLLABLE KHIEUKH WEO KIYEOKSIOS
+0xB372 0xD001 #HANGUL SYLLABLE KHIEUKH WEO NIEUNCIEUC
+0xB373 0xD002 #HANGUL SYLLABLE KHIEUKH WEO NIEUNHIEUH
+0xB374 0xD003 #HANGUL SYLLABLE KHIEUKH WEO TIKEUT
+0xB375 0xD005 #HANGUL SYLLABLE KHIEUKH WEO RIEULKIYEOK
+0xB376 0xD006 #HANGUL SYLLABLE KHIEUKH WEO RIEULMIEUM
+0xB377 0xD007 #HANGUL SYLLABLE KHIEUKH WEO RIEULPIEUP
+0xB378 0xD008 #HANGUL SYLLABLE KHIEUKH WEO RIEULSIOS
+0xB379 0xD009 #HANGUL SYLLABLE KHIEUKH WEO RIEULTHIEUTH
+0xB37A 0xD00A #HANGUL SYLLABLE KHIEUKH WEO RIEULPHIEUPH
+0xB381 0xD00B #HANGUL SYLLABLE KHIEUKH WEO RIEULHIEUH
+0xB382 0xD00C #HANGUL SYLLABLE KHIEUKH WEO MIEUM
+0xB383 0xD00D #HANGUL SYLLABLE KHIEUKH WEO PIEUP
+0xB384 0xD00E #HANGUL SYLLABLE KHIEUKH WEO PIEUPSIOS
+0xB385 0xD00F #HANGUL SYLLABLE KHIEUKH WEO SIOS
+0xB386 0xD010 #HANGUL SYLLABLE KHIEUKH WEO SSANGSIOS
+0xB387 0xD012 #HANGUL SYLLABLE KHIEUKH WEO CIEUC
+0xB388 0xD013 #HANGUL SYLLABLE KHIEUKH WEO CHIEUCH
+0xB389 0xD014 #HANGUL SYLLABLE KHIEUKH WEO KHIEUKH
+0xB38A 0xD015 #HANGUL SYLLABLE KHIEUKH WEO THIEUTH
+0xB38B 0xD016 #HANGUL SYLLABLE KHIEUKH WEO PHIEUPH
+0xB38C 0xD017 #HANGUL SYLLABLE KHIEUKH WEO HIEUH
+0xB38D 0xD019 #HANGUL SYLLABLE KHIEUKH WE KIYEOK
+0xB38E 0xD01A #HANGUL SYLLABLE KHIEUKH WE SSANGKIYEOK
+0xB38F 0xD01B #HANGUL SYLLABLE KHIEUKH WE KIYEOKSIOS
+0xB390 0xD01C #HANGUL SYLLABLE KHIEUKH WE NIEUN
+0xB391 0xD01D #HANGUL SYLLABLE KHIEUKH WE NIEUNCIEUC
+0xB392 0xD01E #HANGUL SYLLABLE KHIEUKH WE NIEUNHIEUH
+0xB393 0xD01F #HANGUL SYLLABLE KHIEUKH WE TIKEUT
+0xB394 0xD020 #HANGUL SYLLABLE KHIEUKH WE RIEUL
+0xB395 0xD021 #HANGUL SYLLABLE KHIEUKH WE RIEULKIYEOK
+0xB396 0xD022 #HANGUL SYLLABLE KHIEUKH WE RIEULMIEUM
+0xB397 0xD023 #HANGUL SYLLABLE KHIEUKH WE RIEULPIEUP
+0xB398 0xD024 #HANGUL SYLLABLE KHIEUKH WE RIEULSIOS
+0xB399 0xD025 #HANGUL SYLLABLE KHIEUKH WE RIEULTHIEUTH
+0xB39A 0xD026 #HANGUL SYLLABLE KHIEUKH WE RIEULPHIEUPH
+0xB39B 0xD027 #HANGUL SYLLABLE KHIEUKH WE RIEULHIEUH
+0xB39C 0xD028 #HANGUL SYLLABLE KHIEUKH WE MIEUM
+0xB39D 0xD029 #HANGUL SYLLABLE KHIEUKH WE PIEUP
+0xB39E 0xD02A #HANGUL SYLLABLE KHIEUKH WE PIEUPSIOS
+0xB39F 0xD02B #HANGUL SYLLABLE KHIEUKH WE SIOS
+0xB3A0 0xD02C #HANGUL SYLLABLE KHIEUKH WE SSANGSIOS
+0xB3A1 0xB05D #HANGUL SYLLABLE SSANGKIYEOK EU THIEUTH
+0xB3A2 0xB07C #HANGUL SYLLABLE SSANGKIYEOK I
+0xB3A3 0xB07D #HANGUL SYLLABLE SSANGKIYEOK I KIYEOK
+0xB3A4 0xB080 #HANGUL SYLLABLE SSANGKIYEOK I NIEUN
+0xB3A5 0xB084 #HANGUL SYLLABLE SSANGKIYEOK I RIEUL
+0xB3A6 0xB08C #HANGUL SYLLABLE SSANGKIYEOK I MIEUM
+0xB3A7 0xB08D #HANGUL SYLLABLE SSANGKIYEOK I PIEUP
+0xB3A8 0xB08F #HANGUL SYLLABLE SSANGKIYEOK I SIOS
+0xB3A9 0xB091 #HANGUL SYLLABLE SSANGKIYEOK I IEUNG
+0xB3AA 0xB098 #HANGUL SYLLABLE NIEUN A
+0xB3AB 0xB099 #HANGUL SYLLABLE NIEUN A KIYEOK
+0xB3AC 0xB09A #HANGUL SYLLABLE NIEUN A SSANGKIYEOK
+0xB3AD 0xB09C #HANGUL SYLLABLE NIEUN A NIEUN
+0xB3AE 0xB09F #HANGUL SYLLABLE NIEUN A TIKEUT
+0xB3AF 0xB0A0 #HANGUL SYLLABLE NIEUN A RIEUL
+0xB3B0 0xB0A1 #HANGUL SYLLABLE NIEUN A RIEULKIYEOK
+0xB3B1 0xB0A2 #HANGUL SYLLABLE NIEUN A RIEULMIEUM
+0xB3B2 0xB0A8 #HANGUL SYLLABLE NIEUN A MIEUM
+0xB3B3 0xB0A9 #HANGUL SYLLABLE NIEUN A PIEUP
+0xB3B4 0xB0AB #HANGUL SYLLABLE NIEUN A SIOS
+0xB3B5 0xB0AC #HANGUL SYLLABLE NIEUN A SSANGSIOS
+0xB3B6 0xB0AD #HANGUL SYLLABLE NIEUN A IEUNG
+0xB3B7 0xB0AE #HANGUL SYLLABLE NIEUN A CIEUC
+0xB3B8 0xB0AF #HANGUL SYLLABLE NIEUN A CHIEUCH
+0xB3B9 0xB0B1 #HANGUL SYLLABLE NIEUN A THIEUTH
+0xB3BA 0xB0B3 #HANGUL SYLLABLE NIEUN A HIEUH
+0xB3BB 0xB0B4 #HANGUL SYLLABLE NIEUN AE
+0xB3BC 0xB0B5 #HANGUL SYLLABLE NIEUN AE KIYEOK
+0xB3BD 0xB0B8 #HANGUL SYLLABLE NIEUN AE NIEUN
+0xB3BE 0xB0BC #HANGUL SYLLABLE NIEUN AE RIEUL
+0xB3BF 0xB0C4 #HANGUL SYLLABLE NIEUN AE MIEUM
+0xB3C0 0xB0C5 #HANGUL SYLLABLE NIEUN AE PIEUP
+0xB3C1 0xB0C7 #HANGUL SYLLABLE NIEUN AE SIOS
+0xB3C2 0xB0C8 #HANGUL SYLLABLE NIEUN AE SSANGSIOS
+0xB3C3 0xB0C9 #HANGUL SYLLABLE NIEUN AE IEUNG
+0xB3C4 0xB0D0 #HANGUL SYLLABLE NIEUN YA
+0xB3C5 0xB0D1 #HANGUL SYLLABLE NIEUN YA KIYEOK
+0xB3C6 0xB0D4 #HANGUL SYLLABLE NIEUN YA NIEUN
+0xB3C7 0xB0D8 #HANGUL SYLLABLE NIEUN YA RIEUL
+0xB3C8 0xB0E0 #HANGUL SYLLABLE NIEUN YA MIEUM
+0xB3C9 0xB0E5 #HANGUL SYLLABLE NIEUN YA IEUNG
+0xB3CA 0xB108 #HANGUL SYLLABLE NIEUN EO
+0xB3CB 0xB109 #HANGUL SYLLABLE NIEUN EO KIYEOK
+0xB3CC 0xB10B #HANGUL SYLLABLE NIEUN EO KIYEOKSIOS
+0xB3CD 0xB10C #HANGUL SYLLABLE NIEUN EO NIEUN
+0xB3CE 0xB110 #HANGUL SYLLABLE NIEUN EO RIEUL
+0xB3CF 0xB112 #HANGUL SYLLABLE NIEUN EO RIEULMIEUM
+0xB3D0 0xB113 #HANGUL SYLLABLE NIEUN EO RIEULPIEUP
+0xB3D1 0xB118 #HANGUL SYLLABLE NIEUN EO MIEUM
+0xB3D2 0xB119 #HANGUL SYLLABLE NIEUN EO PIEUP
+0xB3D3 0xB11B #HANGUL SYLLABLE NIEUN EO SIOS
+0xB3D4 0xB11C #HANGUL SYLLABLE NIEUN EO SSANGSIOS
+0xB3D5 0xB11D #HANGUL SYLLABLE NIEUN EO IEUNG
+0xB3D6 0xB123 #HANGUL SYLLABLE NIEUN EO HIEUH
+0xB3D7 0xB124 #HANGUL SYLLABLE NIEUN E
+0xB3D8 0xB125 #HANGUL SYLLABLE NIEUN E KIYEOK
+0xB3D9 0xB128 #HANGUL SYLLABLE NIEUN E NIEUN
+0xB3DA 0xB12C #HANGUL SYLLABLE NIEUN E RIEUL
+0xB3DB 0xB134 #HANGUL SYLLABLE NIEUN E MIEUM
+0xB3DC 0xB135 #HANGUL SYLLABLE NIEUN E PIEUP
+0xB3DD 0xB137 #HANGUL SYLLABLE NIEUN E SIOS
+0xB3DE 0xB138 #HANGUL SYLLABLE NIEUN E SSANGSIOS
+0xB3DF 0xB139 #HANGUL SYLLABLE NIEUN E IEUNG
+0xB3E0 0xB140 #HANGUL SYLLABLE NIEUN YEO
+0xB3E1 0xB141 #HANGUL SYLLABLE NIEUN YEO KIYEOK
+0xB3E2 0xB144 #HANGUL SYLLABLE NIEUN YEO NIEUN
+0xB3E3 0xB148 #HANGUL SYLLABLE NIEUN YEO RIEUL
+0xB3E4 0xB150 #HANGUL SYLLABLE NIEUN YEO MIEUM
+0xB3E5 0xB151 #HANGUL SYLLABLE NIEUN YEO PIEUP
+0xB3E6 0xB154 #HANGUL SYLLABLE NIEUN YEO SSANGSIOS
+0xB3E7 0xB155 #HANGUL SYLLABLE NIEUN YEO IEUNG
+0xB3E8 0xB158 #HANGUL SYLLABLE NIEUN YEO KHIEUKH
+0xB3E9 0xB15C #HANGUL SYLLABLE NIEUN YE
+0xB3EA 0xB160 #HANGUL SYLLABLE NIEUN YE NIEUN
+0xB3EB 0xB178 #HANGUL SYLLABLE NIEUN O
+0xB3EC 0xB179 #HANGUL SYLLABLE NIEUN O KIYEOK
+0xB3ED 0xB17C #HANGUL SYLLABLE NIEUN O NIEUN
+0xB3EE 0xB180 #HANGUL SYLLABLE NIEUN O RIEUL
+0xB3EF 0xB182 #HANGUL SYLLABLE NIEUN O RIEULMIEUM
+0xB3F0 0xB188 #HANGUL SYLLABLE NIEUN O MIEUM
+0xB3F1 0xB189 #HANGUL SYLLABLE NIEUN O PIEUP
+0xB3F2 0xB18B #HANGUL SYLLABLE NIEUN O SIOS
+0xB3F3 0xB18D #HANGUL SYLLABLE NIEUN O IEUNG
+0xB3F4 0xB192 #HANGUL SYLLABLE NIEUN O PHIEUPH
+0xB3F5 0xB193 #HANGUL SYLLABLE NIEUN O HIEUH
+0xB3F6 0xB194 #HANGUL SYLLABLE NIEUN WA
+0xB3F7 0xB198 #HANGUL SYLLABLE NIEUN WA NIEUN
+0xB3F8 0xB19C #HANGUL SYLLABLE NIEUN WA RIEUL
+0xB3F9 0xB1A8 #HANGUL SYLLABLE NIEUN WA SSANGSIOS
+0xB3FA 0xB1CC #HANGUL SYLLABLE NIEUN OE
+0xB3FB 0xB1D0 #HANGUL SYLLABLE NIEUN OE NIEUN
+0xB3FC 0xB1D4 #HANGUL SYLLABLE NIEUN OE RIEUL
+0xB3FD 0xB1DC #HANGUL SYLLABLE NIEUN OE MIEUM
+0xB3FE 0xB1DD #HANGUL SYLLABLE NIEUN OE PIEUP
+0xB441 0xD02E #HANGUL SYLLABLE KHIEUKH WE CIEUC
+0xB442 0xD02F #HANGUL SYLLABLE KHIEUKH WE CHIEUCH
+0xB443 0xD030 #HANGUL SYLLABLE KHIEUKH WE KHIEUKH
+0xB444 0xD031 #HANGUL SYLLABLE KHIEUKH WE THIEUTH
+0xB445 0xD032 #HANGUL SYLLABLE KHIEUKH WE PHIEUPH
+0xB446 0xD033 #HANGUL SYLLABLE KHIEUKH WE HIEUH
+0xB447 0xD036 #HANGUL SYLLABLE KHIEUKH WI SSANGKIYEOK
+0xB448 0xD037 #HANGUL SYLLABLE KHIEUKH WI KIYEOKSIOS
+0xB449 0xD039 #HANGUL SYLLABLE KHIEUKH WI NIEUNCIEUC
+0xB44A 0xD03A #HANGUL SYLLABLE KHIEUKH WI NIEUNHIEUH
+0xB44B 0xD03B #HANGUL SYLLABLE KHIEUKH WI TIKEUT
+0xB44C 0xD03D #HANGUL SYLLABLE KHIEUKH WI RIEULKIYEOK
+0xB44D 0xD03E #HANGUL SYLLABLE KHIEUKH WI RIEULMIEUM
+0xB44E 0xD03F #HANGUL SYLLABLE KHIEUKH WI RIEULPIEUP
+0xB44F 0xD040 #HANGUL SYLLABLE KHIEUKH WI RIEULSIOS
+0xB450 0xD041 #HANGUL SYLLABLE KHIEUKH WI RIEULTHIEUTH
+0xB451 0xD042 #HANGUL SYLLABLE KHIEUKH WI RIEULPHIEUPH
+0xB452 0xD043 #HANGUL SYLLABLE KHIEUKH WI RIEULHIEUH
+0xB453 0xD046 #HANGUL SYLLABLE KHIEUKH WI PIEUPSIOS
+0xB454 0xD048 #HANGUL SYLLABLE KHIEUKH WI SSANGSIOS
+0xB455 0xD04A #HANGUL SYLLABLE KHIEUKH WI CIEUC
+0xB456 0xD04B #HANGUL SYLLABLE KHIEUKH WI CHIEUCH
+0xB457 0xD04C #HANGUL SYLLABLE KHIEUKH WI KHIEUKH
+0xB458 0xD04D #HANGUL SYLLABLE KHIEUKH WI THIEUTH
+0xB459 0xD04E #HANGUL SYLLABLE KHIEUKH WI PHIEUPH
+0xB45A 0xD04F #HANGUL SYLLABLE KHIEUKH WI HIEUH
+0xB461 0xD051 #HANGUL SYLLABLE KHIEUKH YU KIYEOK
+0xB462 0xD052 #HANGUL SYLLABLE KHIEUKH YU SSANGKIYEOK
+0xB463 0xD053 #HANGUL SYLLABLE KHIEUKH YU KIYEOKSIOS
+0xB464 0xD055 #HANGUL SYLLABLE KHIEUKH YU NIEUNCIEUC
+0xB465 0xD056 #HANGUL SYLLABLE KHIEUKH YU NIEUNHIEUH
+0xB466 0xD057 #HANGUL SYLLABLE KHIEUKH YU TIKEUT
+0xB467 0xD059 #HANGUL SYLLABLE KHIEUKH YU RIEULKIYEOK
+0xB468 0xD05A #HANGUL SYLLABLE KHIEUKH YU RIEULMIEUM
+0xB469 0xD05B #HANGUL SYLLABLE KHIEUKH YU RIEULPIEUP
+0xB46A 0xD05C #HANGUL SYLLABLE KHIEUKH YU RIEULSIOS
+0xB46B 0xD05D #HANGUL SYLLABLE KHIEUKH YU RIEULTHIEUTH
+0xB46C 0xD05E #HANGUL SYLLABLE KHIEUKH YU RIEULPHIEUPH
+0xB46D 0xD05F #HANGUL SYLLABLE KHIEUKH YU RIEULHIEUH
+0xB46E 0xD061 #HANGUL SYLLABLE KHIEUKH YU PIEUP
+0xB46F 0xD062 #HANGUL SYLLABLE KHIEUKH YU PIEUPSIOS
+0xB470 0xD063 #HANGUL SYLLABLE KHIEUKH YU SIOS
+0xB471 0xD064 #HANGUL SYLLABLE KHIEUKH YU SSANGSIOS
+0xB472 0xD065 #HANGUL SYLLABLE KHIEUKH YU IEUNG
+0xB473 0xD066 #HANGUL SYLLABLE KHIEUKH YU CIEUC
+0xB474 0xD067 #HANGUL SYLLABLE KHIEUKH YU CHIEUCH
+0xB475 0xD068 #HANGUL SYLLABLE KHIEUKH YU KHIEUKH
+0xB476 0xD069 #HANGUL SYLLABLE KHIEUKH YU THIEUTH
+0xB477 0xD06A #HANGUL SYLLABLE KHIEUKH YU PHIEUPH
+0xB478 0xD06B #HANGUL SYLLABLE KHIEUKH YU HIEUH
+0xB479 0xD06E #HANGUL SYLLABLE KHIEUKH EU SSANGKIYEOK
+0xB47A 0xD06F #HANGUL SYLLABLE KHIEUKH EU KIYEOKSIOS
+0xB481 0xD071 #HANGUL SYLLABLE KHIEUKH EU NIEUNCIEUC
+0xB482 0xD072 #HANGUL SYLLABLE KHIEUKH EU NIEUNHIEUH
+0xB483 0xD073 #HANGUL SYLLABLE KHIEUKH EU TIKEUT
+0xB484 0xD075 #HANGUL SYLLABLE KHIEUKH EU RIEULKIYEOK
+0xB485 0xD076 #HANGUL SYLLABLE KHIEUKH EU RIEULMIEUM
+0xB486 0xD077 #HANGUL SYLLABLE KHIEUKH EU RIEULPIEUP
+0xB487 0xD078 #HANGUL SYLLABLE KHIEUKH EU RIEULSIOS
+0xB488 0xD079 #HANGUL SYLLABLE KHIEUKH EU RIEULTHIEUTH
+0xB489 0xD07A #HANGUL SYLLABLE KHIEUKH EU RIEULPHIEUPH
+0xB48A 0xD07B #HANGUL SYLLABLE KHIEUKH EU RIEULHIEUH
+0xB48B 0xD07E #HANGUL SYLLABLE KHIEUKH EU PIEUPSIOS
+0xB48C 0xD07F #HANGUL SYLLABLE KHIEUKH EU SIOS
+0xB48D 0xD080 #HANGUL SYLLABLE KHIEUKH EU SSANGSIOS
+0xB48E 0xD082 #HANGUL SYLLABLE KHIEUKH EU CIEUC
+0xB48F 0xD083 #HANGUL SYLLABLE KHIEUKH EU CHIEUCH
+0xB490 0xD084 #HANGUL SYLLABLE KHIEUKH EU KHIEUKH
+0xB491 0xD085 #HANGUL SYLLABLE KHIEUKH EU THIEUTH
+0xB492 0xD086 #HANGUL SYLLABLE KHIEUKH EU PHIEUPH
+0xB493 0xD087 #HANGUL SYLLABLE KHIEUKH EU HIEUH
+0xB494 0xD088 #HANGUL SYLLABLE KHIEUKH YI
+0xB495 0xD089 #HANGUL SYLLABLE KHIEUKH YI KIYEOK
+0xB496 0xD08A #HANGUL SYLLABLE KHIEUKH YI SSANGKIYEOK
+0xB497 0xD08B #HANGUL SYLLABLE KHIEUKH YI KIYEOKSIOS
+0xB498 0xD08C #HANGUL SYLLABLE KHIEUKH YI NIEUN
+0xB499 0xD08D #HANGUL SYLLABLE KHIEUKH YI NIEUNCIEUC
+0xB49A 0xD08E #HANGUL SYLLABLE KHIEUKH YI NIEUNHIEUH
+0xB49B 0xD08F #HANGUL SYLLABLE KHIEUKH YI TIKEUT
+0xB49C 0xD090 #HANGUL SYLLABLE KHIEUKH YI RIEUL
+0xB49D 0xD091 #HANGUL SYLLABLE KHIEUKH YI RIEULKIYEOK
+0xB49E 0xD092 #HANGUL SYLLABLE KHIEUKH YI RIEULMIEUM
+0xB49F 0xD093 #HANGUL SYLLABLE KHIEUKH YI RIEULPIEUP
+0xB4A0 0xD094 #HANGUL SYLLABLE KHIEUKH YI RIEULSIOS
+0xB4A1 0xB1DF #HANGUL SYLLABLE NIEUN OE SIOS
+0xB4A2 0xB1E8 #HANGUL SYLLABLE NIEUN YO
+0xB4A3 0xB1E9 #HANGUL SYLLABLE NIEUN YO KIYEOK
+0xB4A4 0xB1EC #HANGUL SYLLABLE NIEUN YO NIEUN
+0xB4A5 0xB1F0 #HANGUL SYLLABLE NIEUN YO RIEUL
+0xB4A6 0xB1F9 #HANGUL SYLLABLE NIEUN YO PIEUP
+0xB4A7 0xB1FB #HANGUL SYLLABLE NIEUN YO SIOS
+0xB4A8 0xB1FD #HANGUL SYLLABLE NIEUN YO IEUNG
+0xB4A9 0xB204 #HANGUL SYLLABLE NIEUN U
+0xB4AA 0xB205 #HANGUL SYLLABLE NIEUN U KIYEOK
+0xB4AB 0xB208 #HANGUL SYLLABLE NIEUN U NIEUN
+0xB4AC 0xB20B #HANGUL SYLLABLE NIEUN U TIKEUT
+0xB4AD 0xB20C #HANGUL SYLLABLE NIEUN U RIEUL
+0xB4AE 0xB214 #HANGUL SYLLABLE NIEUN U MIEUM
+0xB4AF 0xB215 #HANGUL SYLLABLE NIEUN U PIEUP
+0xB4B0 0xB217 #HANGUL SYLLABLE NIEUN U SIOS
+0xB4B1 0xB219 #HANGUL SYLLABLE NIEUN U IEUNG
+0xB4B2 0xB220 #HANGUL SYLLABLE NIEUN WEO
+0xB4B3 0xB234 #HANGUL SYLLABLE NIEUN WEO SSANGSIOS
+0xB4B4 0xB23C #HANGUL SYLLABLE NIEUN WE
+0xB4B5 0xB258 #HANGUL SYLLABLE NIEUN WI
+0xB4B6 0xB25C #HANGUL SYLLABLE NIEUN WI NIEUN
+0xB4B7 0xB260 #HANGUL SYLLABLE NIEUN WI RIEUL
+0xB4B8 0xB268 #HANGUL SYLLABLE NIEUN WI MIEUM
+0xB4B9 0xB269 #HANGUL SYLLABLE NIEUN WI PIEUP
+0xB4BA 0xB274 #HANGUL SYLLABLE NIEUN YU
+0xB4BB 0xB275 #HANGUL SYLLABLE NIEUN YU KIYEOK
+0xB4BC 0xB27C #HANGUL SYLLABLE NIEUN YU RIEUL
+0xB4BD 0xB284 #HANGUL SYLLABLE NIEUN YU MIEUM
+0xB4BE 0xB285 #HANGUL SYLLABLE NIEUN YU PIEUP
+0xB4BF 0xB289 #HANGUL SYLLABLE NIEUN YU IEUNG
+0xB4C0 0xB290 #HANGUL SYLLABLE NIEUN EU
+0xB4C1 0xB291 #HANGUL SYLLABLE NIEUN EU KIYEOK
+0xB4C2 0xB294 #HANGUL SYLLABLE NIEUN EU NIEUN
+0xB4C3 0xB298 #HANGUL SYLLABLE NIEUN EU RIEUL
+0xB4C4 0xB299 #HANGUL SYLLABLE NIEUN EU RIEULKIYEOK
+0xB4C5 0xB29A #HANGUL SYLLABLE NIEUN EU RIEULMIEUM
+0xB4C6 0xB2A0 #HANGUL SYLLABLE NIEUN EU MIEUM
+0xB4C7 0xB2A1 #HANGUL SYLLABLE NIEUN EU PIEUP
+0xB4C8 0xB2A3 #HANGUL SYLLABLE NIEUN EU SIOS
+0xB4C9 0xB2A5 #HANGUL SYLLABLE NIEUN EU IEUNG
+0xB4CA 0xB2A6 #HANGUL SYLLABLE NIEUN EU CIEUC
+0xB4CB 0xB2AA #HANGUL SYLLABLE NIEUN EU PHIEUPH
+0xB4CC 0xB2AC #HANGUL SYLLABLE NIEUN YI
+0xB4CD 0xB2B0 #HANGUL SYLLABLE NIEUN YI NIEUN
+0xB4CE 0xB2B4 #HANGUL SYLLABLE NIEUN YI RIEUL
+0xB4CF 0xB2C8 #HANGUL SYLLABLE NIEUN I
+0xB4D0 0xB2C9 #HANGUL SYLLABLE NIEUN I KIYEOK
+0xB4D1 0xB2CC #HANGUL SYLLABLE NIEUN I NIEUN
+0xB4D2 0xB2D0 #HANGUL SYLLABLE NIEUN I RIEUL
+0xB4D3 0xB2D2 #HANGUL SYLLABLE NIEUN I RIEULMIEUM
+0xB4D4 0xB2D8 #HANGUL SYLLABLE NIEUN I MIEUM
+0xB4D5 0xB2D9 #HANGUL SYLLABLE NIEUN I PIEUP
+0xB4D6 0xB2DB #HANGUL SYLLABLE NIEUN I SIOS
+0xB4D7 0xB2DD #HANGUL SYLLABLE NIEUN I IEUNG
+0xB4D8 0xB2E2 #HANGUL SYLLABLE NIEUN I PHIEUPH
+0xB4D9 0xB2E4 #HANGUL SYLLABLE TIKEUT A
+0xB4DA 0xB2E5 #HANGUL SYLLABLE TIKEUT A KIYEOK
+0xB4DB 0xB2E6 #HANGUL SYLLABLE TIKEUT A SSANGKIYEOK
+0xB4DC 0xB2E8 #HANGUL SYLLABLE TIKEUT A NIEUN
+0xB4DD 0xB2EB #HANGUL SYLLABLE TIKEUT A TIKEUT
+0xB4DE 0xB2EC #HANGUL SYLLABLE TIKEUT A RIEUL
+0xB4DF 0xB2ED #HANGUL SYLLABLE TIKEUT A RIEULKIYEOK
+0xB4E0 0xB2EE #HANGUL SYLLABLE TIKEUT A RIEULMIEUM
+0xB4E1 0xB2EF #HANGUL SYLLABLE TIKEUT A RIEULPIEUP
+0xB4E2 0xB2F3 #HANGUL SYLLABLE TIKEUT A RIEULHIEUH
+0xB4E3 0xB2F4 #HANGUL SYLLABLE TIKEUT A MIEUM
+0xB4E4 0xB2F5 #HANGUL SYLLABLE TIKEUT A PIEUP
+0xB4E5 0xB2F7 #HANGUL SYLLABLE TIKEUT A SIOS
+0xB4E6 0xB2F8 #HANGUL SYLLABLE TIKEUT A SSANGSIOS
+0xB4E7 0xB2F9 #HANGUL SYLLABLE TIKEUT A IEUNG
+0xB4E8 0xB2FA #HANGUL SYLLABLE TIKEUT A CIEUC
+0xB4E9 0xB2FB #HANGUL SYLLABLE TIKEUT A CHIEUCH
+0xB4EA 0xB2FF #HANGUL SYLLABLE TIKEUT A HIEUH
+0xB4EB 0xB300 #HANGUL SYLLABLE TIKEUT AE
+0xB4EC 0xB301 #HANGUL SYLLABLE TIKEUT AE KIYEOK
+0xB4ED 0xB304 #HANGUL SYLLABLE TIKEUT AE NIEUN
+0xB4EE 0xB308 #HANGUL SYLLABLE TIKEUT AE RIEUL
+0xB4EF 0xB310 #HANGUL SYLLABLE TIKEUT AE MIEUM
+0xB4F0 0xB311 #HANGUL SYLLABLE TIKEUT AE PIEUP
+0xB4F1 0xB313 #HANGUL SYLLABLE TIKEUT AE SIOS
+0xB4F2 0xB314 #HANGUL SYLLABLE TIKEUT AE SSANGSIOS
+0xB4F3 0xB315 #HANGUL SYLLABLE TIKEUT AE IEUNG
+0xB4F4 0xB31C #HANGUL SYLLABLE TIKEUT YA
+0xB4F5 0xB354 #HANGUL SYLLABLE TIKEUT EO
+0xB4F6 0xB355 #HANGUL SYLLABLE TIKEUT EO KIYEOK
+0xB4F7 0xB356 #HANGUL SYLLABLE TIKEUT EO SSANGKIYEOK
+0xB4F8 0xB358 #HANGUL SYLLABLE TIKEUT EO NIEUN
+0xB4F9 0xB35B #HANGUL SYLLABLE TIKEUT EO TIKEUT
+0xB4FA 0xB35C #HANGUL SYLLABLE TIKEUT EO RIEUL
+0xB4FB 0xB35E #HANGUL SYLLABLE TIKEUT EO RIEULMIEUM
+0xB4FC 0xB35F #HANGUL SYLLABLE TIKEUT EO RIEULPIEUP
+0xB4FD 0xB364 #HANGUL SYLLABLE TIKEUT EO MIEUM
+0xB4FE 0xB365 #HANGUL SYLLABLE TIKEUT EO PIEUP
+0xB541 0xD095 #HANGUL SYLLABLE KHIEUKH YI RIEULTHIEUTH
+0xB542 0xD096 #HANGUL SYLLABLE KHIEUKH YI RIEULPHIEUPH
+0xB543 0xD097 #HANGUL SYLLABLE KHIEUKH YI RIEULHIEUH
+0xB544 0xD098 #HANGUL SYLLABLE KHIEUKH YI MIEUM
+0xB545 0xD099 #HANGUL SYLLABLE KHIEUKH YI PIEUP
+0xB546 0xD09A #HANGUL SYLLABLE KHIEUKH YI PIEUPSIOS
+0xB547 0xD09B #HANGUL SYLLABLE KHIEUKH YI SIOS
+0xB548 0xD09C #HANGUL SYLLABLE KHIEUKH YI SSANGSIOS
+0xB549 0xD09D #HANGUL SYLLABLE KHIEUKH YI IEUNG
+0xB54A 0xD09E #HANGUL SYLLABLE KHIEUKH YI CIEUC
+0xB54B 0xD09F #HANGUL SYLLABLE KHIEUKH YI CHIEUCH
+0xB54C 0xD0A0 #HANGUL SYLLABLE KHIEUKH YI KHIEUKH
+0xB54D 0xD0A1 #HANGUL SYLLABLE KHIEUKH YI THIEUTH
+0xB54E 0xD0A2 #HANGUL SYLLABLE KHIEUKH YI PHIEUPH
+0xB54F 0xD0A3 #HANGUL SYLLABLE KHIEUKH YI HIEUH
+0xB550 0xD0A6 #HANGUL SYLLABLE KHIEUKH I SSANGKIYEOK
+0xB551 0xD0A7 #HANGUL SYLLABLE KHIEUKH I KIYEOKSIOS
+0xB552 0xD0A9 #HANGUL SYLLABLE KHIEUKH I NIEUNCIEUC
+0xB553 0xD0AA #HANGUL SYLLABLE KHIEUKH I NIEUNHIEUH
+0xB554 0xD0AB #HANGUL SYLLABLE KHIEUKH I TIKEUT
+0xB555 0xD0AD #HANGUL SYLLABLE KHIEUKH I RIEULKIYEOK
+0xB556 0xD0AE #HANGUL SYLLABLE KHIEUKH I RIEULMIEUM
+0xB557 0xD0AF #HANGUL SYLLABLE KHIEUKH I RIEULPIEUP
+0xB558 0xD0B0 #HANGUL SYLLABLE KHIEUKH I RIEULSIOS
+0xB559 0xD0B1 #HANGUL SYLLABLE KHIEUKH I RIEULTHIEUTH
+0xB55A 0xD0B2 #HANGUL SYLLABLE KHIEUKH I RIEULPHIEUPH
+0xB561 0xD0B3 #HANGUL SYLLABLE KHIEUKH I RIEULHIEUH
+0xB562 0xD0B6 #HANGUL SYLLABLE KHIEUKH I PIEUPSIOS
+0xB563 0xD0B8 #HANGUL SYLLABLE KHIEUKH I SSANGSIOS
+0xB564 0xD0BA #HANGUL SYLLABLE KHIEUKH I CIEUC
+0xB565 0xD0BB #HANGUL SYLLABLE KHIEUKH I CHIEUCH
+0xB566 0xD0BC #HANGUL SYLLABLE KHIEUKH I KHIEUKH
+0xB567 0xD0BD #HANGUL SYLLABLE KHIEUKH I THIEUTH
+0xB568 0xD0BE #HANGUL SYLLABLE KHIEUKH I PHIEUPH
+0xB569 0xD0BF #HANGUL SYLLABLE KHIEUKH I HIEUH
+0xB56A 0xD0C2 #HANGUL SYLLABLE THIEUTH A SSANGKIYEOK
+0xB56B 0xD0C3 #HANGUL SYLLABLE THIEUTH A KIYEOKSIOS
+0xB56C 0xD0C5 #HANGUL SYLLABLE THIEUTH A NIEUNCIEUC
+0xB56D 0xD0C6 #HANGUL SYLLABLE THIEUTH A NIEUNHIEUH
+0xB56E 0xD0C7 #HANGUL SYLLABLE THIEUTH A TIKEUT
+0xB56F 0xD0CA #HANGUL SYLLABLE THIEUTH A RIEULMIEUM
+0xB570 0xD0CB #HANGUL SYLLABLE THIEUTH A RIEULPIEUP
+0xB571 0xD0CC #HANGUL SYLLABLE THIEUTH A RIEULSIOS
+0xB572 0xD0CD #HANGUL SYLLABLE THIEUTH A RIEULTHIEUTH
+0xB573 0xD0CE #HANGUL SYLLABLE THIEUTH A RIEULPHIEUPH
+0xB574 0xD0CF #HANGUL SYLLABLE THIEUTH A RIEULHIEUH
+0xB575 0xD0D2 #HANGUL SYLLABLE THIEUTH A PIEUPSIOS
+0xB576 0xD0D6 #HANGUL SYLLABLE THIEUTH A CIEUC
+0xB577 0xD0D7 #HANGUL SYLLABLE THIEUTH A CHIEUCH
+0xB578 0xD0D8 #HANGUL SYLLABLE THIEUTH A KHIEUKH
+0xB579 0xD0D9 #HANGUL SYLLABLE THIEUTH A THIEUTH
+0xB57A 0xD0DA #HANGUL SYLLABLE THIEUTH A PHIEUPH
+0xB581 0xD0DB #HANGUL SYLLABLE THIEUTH A HIEUH
+0xB582 0xD0DE #HANGUL SYLLABLE THIEUTH AE SSANGKIYEOK
+0xB583 0xD0DF #HANGUL SYLLABLE THIEUTH AE KIYEOKSIOS
+0xB584 0xD0E1 #HANGUL SYLLABLE THIEUTH AE NIEUNCIEUC
+0xB585 0xD0E2 #HANGUL SYLLABLE THIEUTH AE NIEUNHIEUH
+0xB586 0xD0E3 #HANGUL SYLLABLE THIEUTH AE TIKEUT
+0xB587 0xD0E5 #HANGUL SYLLABLE THIEUTH AE RIEULKIYEOK
+0xB588 0xD0E6 #HANGUL SYLLABLE THIEUTH AE RIEULMIEUM
+0xB589 0xD0E7 #HANGUL SYLLABLE THIEUTH AE RIEULPIEUP
+0xB58A 0xD0E8 #HANGUL SYLLABLE THIEUTH AE RIEULSIOS
+0xB58B 0xD0E9 #HANGUL SYLLABLE THIEUTH AE RIEULTHIEUTH
+0xB58C 0xD0EA #HANGUL SYLLABLE THIEUTH AE RIEULPHIEUPH
+0xB58D 0xD0EB #HANGUL SYLLABLE THIEUTH AE RIEULHIEUH
+0xB58E 0xD0EE #HANGUL SYLLABLE THIEUTH AE PIEUPSIOS
+0xB58F 0xD0F2 #HANGUL SYLLABLE THIEUTH AE CIEUC
+0xB590 0xD0F3 #HANGUL SYLLABLE THIEUTH AE CHIEUCH
+0xB591 0xD0F4 #HANGUL SYLLABLE THIEUTH AE KHIEUKH
+0xB592 0xD0F5 #HANGUL SYLLABLE THIEUTH AE THIEUTH
+0xB593 0xD0F6 #HANGUL SYLLABLE THIEUTH AE PHIEUPH
+0xB594 0xD0F7 #HANGUL SYLLABLE THIEUTH AE HIEUH
+0xB595 0xD0F9 #HANGUL SYLLABLE THIEUTH YA KIYEOK
+0xB596 0xD0FA #HANGUL SYLLABLE THIEUTH YA SSANGKIYEOK
+0xB597 0xD0FB #HANGUL SYLLABLE THIEUTH YA KIYEOKSIOS
+0xB598 0xD0FC #HANGUL SYLLABLE THIEUTH YA NIEUN
+0xB599 0xD0FD #HANGUL SYLLABLE THIEUTH YA NIEUNCIEUC
+0xB59A 0xD0FE #HANGUL SYLLABLE THIEUTH YA NIEUNHIEUH
+0xB59B 0xD0FF #HANGUL SYLLABLE THIEUTH YA TIKEUT
+0xB59C 0xD100 #HANGUL SYLLABLE THIEUTH YA RIEUL
+0xB59D 0xD101 #HANGUL SYLLABLE THIEUTH YA RIEULKIYEOK
+0xB59E 0xD102 #HANGUL SYLLABLE THIEUTH YA RIEULMIEUM
+0xB59F 0xD103 #HANGUL SYLLABLE THIEUTH YA RIEULPIEUP
+0xB5A0 0xD104 #HANGUL SYLLABLE THIEUTH YA RIEULSIOS
+0xB5A1 0xB367 #HANGUL SYLLABLE TIKEUT EO SIOS
+0xB5A2 0xB369 #HANGUL SYLLABLE TIKEUT EO IEUNG
+0xB5A3 0xB36B #HANGUL SYLLABLE TIKEUT EO CHIEUCH
+0xB5A4 0xB36E #HANGUL SYLLABLE TIKEUT EO PHIEUPH
+0xB5A5 0xB370 #HANGUL SYLLABLE TIKEUT E
+0xB5A6 0xB371 #HANGUL SYLLABLE TIKEUT E KIYEOK
+0xB5A7 0xB374 #HANGUL SYLLABLE TIKEUT E NIEUN
+0xB5A8 0xB378 #HANGUL SYLLABLE TIKEUT E RIEUL
+0xB5A9 0xB380 #HANGUL SYLLABLE TIKEUT E MIEUM
+0xB5AA 0xB381 #HANGUL SYLLABLE TIKEUT E PIEUP
+0xB5AB 0xB383 #HANGUL SYLLABLE TIKEUT E SIOS
+0xB5AC 0xB384 #HANGUL SYLLABLE TIKEUT E SSANGSIOS
+0xB5AD 0xB385 #HANGUL SYLLABLE TIKEUT E IEUNG
+0xB5AE 0xB38C #HANGUL SYLLABLE TIKEUT YEO
+0xB5AF 0xB390 #HANGUL SYLLABLE TIKEUT YEO NIEUN
+0xB5B0 0xB394 #HANGUL SYLLABLE TIKEUT YEO RIEUL
+0xB5B1 0xB3A0 #HANGUL SYLLABLE TIKEUT YEO SSANGSIOS
+0xB5B2 0xB3A1 #HANGUL SYLLABLE TIKEUT YEO IEUNG
+0xB5B3 0xB3A8 #HANGUL SYLLABLE TIKEUT YE
+0xB5B4 0xB3AC #HANGUL SYLLABLE TIKEUT YE NIEUN
+0xB5B5 0xB3C4 #HANGUL SYLLABLE TIKEUT O
+0xB5B6 0xB3C5 #HANGUL SYLLABLE TIKEUT O KIYEOK
+0xB5B7 0xB3C8 #HANGUL SYLLABLE TIKEUT O NIEUN
+0xB5B8 0xB3CB #HANGUL SYLLABLE TIKEUT O TIKEUT
+0xB5B9 0xB3CC #HANGUL SYLLABLE TIKEUT O RIEUL
+0xB5BA 0xB3CE #HANGUL SYLLABLE TIKEUT O RIEULMIEUM
+0xB5BB 0xB3D0 #HANGUL SYLLABLE TIKEUT O RIEULSIOS
+0xB5BC 0xB3D4 #HANGUL SYLLABLE TIKEUT O MIEUM
+0xB5BD 0xB3D5 #HANGUL SYLLABLE TIKEUT O PIEUP
+0xB5BE 0xB3D7 #HANGUL SYLLABLE TIKEUT O SIOS
+0xB5BF 0xB3D9 #HANGUL SYLLABLE TIKEUT O IEUNG
+0xB5C0 0xB3DB #HANGUL SYLLABLE TIKEUT O CHIEUCH
+0xB5C1 0xB3DD #HANGUL SYLLABLE TIKEUT O THIEUTH
+0xB5C2 0xB3E0 #HANGUL SYLLABLE TIKEUT WA
+0xB5C3 0xB3E4 #HANGUL SYLLABLE TIKEUT WA NIEUN
+0xB5C4 0xB3E8 #HANGUL SYLLABLE TIKEUT WA RIEUL
+0xB5C5 0xB3FC #HANGUL SYLLABLE TIKEUT WAE
+0xB5C6 0xB410 #HANGUL SYLLABLE TIKEUT WAE SSANGSIOS
+0xB5C7 0xB418 #HANGUL SYLLABLE TIKEUT OE
+0xB5C8 0xB41C #HANGUL SYLLABLE TIKEUT OE NIEUN
+0xB5C9 0xB420 #HANGUL SYLLABLE TIKEUT OE RIEUL
+0xB5CA 0xB428 #HANGUL SYLLABLE TIKEUT OE MIEUM
+0xB5CB 0xB429 #HANGUL SYLLABLE TIKEUT OE PIEUP
+0xB5CC 0xB42B #HANGUL SYLLABLE TIKEUT OE SIOS
+0xB5CD 0xB434 #HANGUL SYLLABLE TIKEUT YO
+0xB5CE 0xB450 #HANGUL SYLLABLE TIKEUT U
+0xB5CF 0xB451 #HANGUL SYLLABLE TIKEUT U KIYEOK
+0xB5D0 0xB454 #HANGUL SYLLABLE TIKEUT U NIEUN
+0xB5D1 0xB458 #HANGUL SYLLABLE TIKEUT U RIEUL
+0xB5D2 0xB460 #HANGUL SYLLABLE TIKEUT U MIEUM
+0xB5D3 0xB461 #HANGUL SYLLABLE TIKEUT U PIEUP
+0xB5D4 0xB463 #HANGUL SYLLABLE TIKEUT U SIOS
+0xB5D5 0xB465 #HANGUL SYLLABLE TIKEUT U IEUNG
+0xB5D6 0xB46C #HANGUL SYLLABLE TIKEUT WEO
+0xB5D7 0xB480 #HANGUL SYLLABLE TIKEUT WEO SSANGSIOS
+0xB5D8 0xB488 #HANGUL SYLLABLE TIKEUT WE
+0xB5D9 0xB49D #HANGUL SYLLABLE TIKEUT WE IEUNG
+0xB5DA 0xB4A4 #HANGUL SYLLABLE TIKEUT WI
+0xB5DB 0xB4A8 #HANGUL SYLLABLE TIKEUT WI NIEUN
+0xB5DC 0xB4AC #HANGUL SYLLABLE TIKEUT WI RIEUL
+0xB5DD 0xB4B5 #HANGUL SYLLABLE TIKEUT WI PIEUP
+0xB5DE 0xB4B7 #HANGUL SYLLABLE TIKEUT WI SIOS
+0xB5DF 0xB4B9 #HANGUL SYLLABLE TIKEUT WI IEUNG
+0xB5E0 0xB4C0 #HANGUL SYLLABLE TIKEUT YU
+0xB5E1 0xB4C4 #HANGUL SYLLABLE TIKEUT YU NIEUN
+0xB5E2 0xB4C8 #HANGUL SYLLABLE TIKEUT YU RIEUL
+0xB5E3 0xB4D0 #HANGUL SYLLABLE TIKEUT YU MIEUM
+0xB5E4 0xB4D5 #HANGUL SYLLABLE TIKEUT YU IEUNG
+0xB5E5 0xB4DC #HANGUL SYLLABLE TIKEUT EU
+0xB5E6 0xB4DD #HANGUL SYLLABLE TIKEUT EU KIYEOK
+0xB5E7 0xB4E0 #HANGUL SYLLABLE TIKEUT EU NIEUN
+0xB5E8 0xB4E3 #HANGUL SYLLABLE TIKEUT EU TIKEUT
+0xB5E9 0xB4E4 #HANGUL SYLLABLE TIKEUT EU RIEUL
+0xB5EA 0xB4E6 #HANGUL SYLLABLE TIKEUT EU RIEULMIEUM
+0xB5EB 0xB4EC #HANGUL SYLLABLE TIKEUT EU MIEUM
+0xB5EC 0xB4ED #HANGUL SYLLABLE TIKEUT EU PIEUP
+0xB5ED 0xB4EF #HANGUL SYLLABLE TIKEUT EU SIOS
+0xB5EE 0xB4F1 #HANGUL SYLLABLE TIKEUT EU IEUNG
+0xB5EF 0xB4F8 #HANGUL SYLLABLE TIKEUT YI
+0xB5F0 0xB514 #HANGUL SYLLABLE TIKEUT I
+0xB5F1 0xB515 #HANGUL SYLLABLE TIKEUT I KIYEOK
+0xB5F2 0xB518 #HANGUL SYLLABLE TIKEUT I NIEUN
+0xB5F3 0xB51B #HANGUL SYLLABLE TIKEUT I TIKEUT
+0xB5F4 0xB51C #HANGUL SYLLABLE TIKEUT I RIEUL
+0xB5F5 0xB524 #HANGUL SYLLABLE TIKEUT I MIEUM
+0xB5F6 0xB525 #HANGUL SYLLABLE TIKEUT I PIEUP
+0xB5F7 0xB527 #HANGUL SYLLABLE TIKEUT I SIOS
+0xB5F8 0xB528 #HANGUL SYLLABLE TIKEUT I SSANGSIOS
+0xB5F9 0xB529 #HANGUL SYLLABLE TIKEUT I IEUNG
+0xB5FA 0xB52A #HANGUL SYLLABLE TIKEUT I CIEUC
+0xB5FB 0xB530 #HANGUL SYLLABLE SSANGTIKEUT A
+0xB5FC 0xB531 #HANGUL SYLLABLE SSANGTIKEUT A KIYEOK
+0xB5FD 0xB534 #HANGUL SYLLABLE SSANGTIKEUT A NIEUN
+0xB5FE 0xB538 #HANGUL SYLLABLE SSANGTIKEUT A RIEUL
+0xB641 0xD105 #HANGUL SYLLABLE THIEUTH YA RIEULTHIEUTH
+0xB642 0xD106 #HANGUL SYLLABLE THIEUTH YA RIEULPHIEUPH
+0xB643 0xD107 #HANGUL SYLLABLE THIEUTH YA RIEULHIEUH
+0xB644 0xD108 #HANGUL SYLLABLE THIEUTH YA MIEUM
+0xB645 0xD109 #HANGUL SYLLABLE THIEUTH YA PIEUP
+0xB646 0xD10A #HANGUL SYLLABLE THIEUTH YA PIEUPSIOS
+0xB647 0xD10B #HANGUL SYLLABLE THIEUTH YA SIOS
+0xB648 0xD10C #HANGUL SYLLABLE THIEUTH YA SSANGSIOS
+0xB649 0xD10E #HANGUL SYLLABLE THIEUTH YA CIEUC
+0xB64A 0xD10F #HANGUL SYLLABLE THIEUTH YA CHIEUCH
+0xB64B 0xD110 #HANGUL SYLLABLE THIEUTH YA KHIEUKH
+0xB64C 0xD111 #HANGUL SYLLABLE THIEUTH YA THIEUTH
+0xB64D 0xD112 #HANGUL SYLLABLE THIEUTH YA PHIEUPH
+0xB64E 0xD113 #HANGUL SYLLABLE THIEUTH YA HIEUH
+0xB64F 0xD114 #HANGUL SYLLABLE THIEUTH YAE
+0xB650 0xD115 #HANGUL SYLLABLE THIEUTH YAE KIYEOK
+0xB651 0xD116 #HANGUL SYLLABLE THIEUTH YAE SSANGKIYEOK
+0xB652 0xD117 #HANGUL SYLLABLE THIEUTH YAE KIYEOKSIOS
+0xB653 0xD118 #HANGUL SYLLABLE THIEUTH YAE NIEUN
+0xB654 0xD119 #HANGUL SYLLABLE THIEUTH YAE NIEUNCIEUC
+0xB655 0xD11A #HANGUL SYLLABLE THIEUTH YAE NIEUNHIEUH
+0xB656 0xD11B #HANGUL SYLLABLE THIEUTH YAE TIKEUT
+0xB657 0xD11C #HANGUL SYLLABLE THIEUTH YAE RIEUL
+0xB658 0xD11D #HANGUL SYLLABLE THIEUTH YAE RIEULKIYEOK
+0xB659 0xD11E #HANGUL SYLLABLE THIEUTH YAE RIEULMIEUM
+0xB65A 0xD11F #HANGUL SYLLABLE THIEUTH YAE RIEULPIEUP
+0xB661 0xD120 #HANGUL SYLLABLE THIEUTH YAE RIEULSIOS
+0xB662 0xD121 #HANGUL SYLLABLE THIEUTH YAE RIEULTHIEUTH
+0xB663 0xD122 #HANGUL SYLLABLE THIEUTH YAE RIEULPHIEUPH
+0xB664 0xD123 #HANGUL SYLLABLE THIEUTH YAE RIEULHIEUH
+0xB665 0xD124 #HANGUL SYLLABLE THIEUTH YAE MIEUM
+0xB666 0xD125 #HANGUL SYLLABLE THIEUTH YAE PIEUP
+0xB667 0xD126 #HANGUL SYLLABLE THIEUTH YAE PIEUPSIOS
+0xB668 0xD127 #HANGUL SYLLABLE THIEUTH YAE SIOS
+0xB669 0xD128 #HANGUL SYLLABLE THIEUTH YAE SSANGSIOS
+0xB66A 0xD129 #HANGUL SYLLABLE THIEUTH YAE IEUNG
+0xB66B 0xD12A #HANGUL SYLLABLE THIEUTH YAE CIEUC
+0xB66C 0xD12B #HANGUL SYLLABLE THIEUTH YAE CHIEUCH
+0xB66D 0xD12C #HANGUL SYLLABLE THIEUTH YAE KHIEUKH
+0xB66E 0xD12D #HANGUL SYLLABLE THIEUTH YAE THIEUTH
+0xB66F 0xD12E #HANGUL SYLLABLE THIEUTH YAE PHIEUPH
+0xB670 0xD12F #HANGUL SYLLABLE THIEUTH YAE HIEUH
+0xB671 0xD132 #HANGUL SYLLABLE THIEUTH EO SSANGKIYEOK
+0xB672 0xD133 #HANGUL SYLLABLE THIEUTH EO KIYEOKSIOS
+0xB673 0xD135 #HANGUL SYLLABLE THIEUTH EO NIEUNCIEUC
+0xB674 0xD136 #HANGUL SYLLABLE THIEUTH EO NIEUNHIEUH
+0xB675 0xD137 #HANGUL SYLLABLE THIEUTH EO TIKEUT
+0xB676 0xD139 #HANGUL SYLLABLE THIEUTH EO RIEULKIYEOK
+0xB677 0xD13B #HANGUL SYLLABLE THIEUTH EO RIEULPIEUP
+0xB678 0xD13C #HANGUL SYLLABLE THIEUTH EO RIEULSIOS
+0xB679 0xD13D #HANGUL SYLLABLE THIEUTH EO RIEULTHIEUTH
+0xB67A 0xD13E #HANGUL SYLLABLE THIEUTH EO RIEULPHIEUPH
+0xB681 0xD13F #HANGUL SYLLABLE THIEUTH EO RIEULHIEUH
+0xB682 0xD142 #HANGUL SYLLABLE THIEUTH EO PIEUPSIOS
+0xB683 0xD146 #HANGUL SYLLABLE THIEUTH EO CIEUC
+0xB684 0xD147 #HANGUL SYLLABLE THIEUTH EO CHIEUCH
+0xB685 0xD148 #HANGUL SYLLABLE THIEUTH EO KHIEUKH
+0xB686 0xD149 #HANGUL SYLLABLE THIEUTH EO THIEUTH
+0xB687 0xD14A #HANGUL SYLLABLE THIEUTH EO PHIEUPH
+0xB688 0xD14B #HANGUL SYLLABLE THIEUTH EO HIEUH
+0xB689 0xD14E #HANGUL SYLLABLE THIEUTH E SSANGKIYEOK
+0xB68A 0xD14F #HANGUL SYLLABLE THIEUTH E KIYEOKSIOS
+0xB68B 0xD151 #HANGUL SYLLABLE THIEUTH E NIEUNCIEUC
+0xB68C 0xD152 #HANGUL SYLLABLE THIEUTH E NIEUNHIEUH
+0xB68D 0xD153 #HANGUL SYLLABLE THIEUTH E TIKEUT
+0xB68E 0xD155 #HANGUL SYLLABLE THIEUTH E RIEULKIYEOK
+0xB68F 0xD156 #HANGUL SYLLABLE THIEUTH E RIEULMIEUM
+0xB690 0xD157 #HANGUL SYLLABLE THIEUTH E RIEULPIEUP
+0xB691 0xD158 #HANGUL SYLLABLE THIEUTH E RIEULSIOS
+0xB692 0xD159 #HANGUL SYLLABLE THIEUTH E RIEULTHIEUTH
+0xB693 0xD15A #HANGUL SYLLABLE THIEUTH E RIEULPHIEUPH
+0xB694 0xD15B #HANGUL SYLLABLE THIEUTH E RIEULHIEUH
+0xB695 0xD15E #HANGUL SYLLABLE THIEUTH E PIEUPSIOS
+0xB696 0xD160 #HANGUL SYLLABLE THIEUTH E SSANGSIOS
+0xB697 0xD162 #HANGUL SYLLABLE THIEUTH E CIEUC
+0xB698 0xD163 #HANGUL SYLLABLE THIEUTH E CHIEUCH
+0xB699 0xD164 #HANGUL SYLLABLE THIEUTH E KHIEUKH
+0xB69A 0xD165 #HANGUL SYLLABLE THIEUTH E THIEUTH
+0xB69B 0xD166 #HANGUL SYLLABLE THIEUTH E PHIEUPH
+0xB69C 0xD167 #HANGUL SYLLABLE THIEUTH E HIEUH
+0xB69D 0xD169 #HANGUL SYLLABLE THIEUTH YEO KIYEOK
+0xB69E 0xD16A #HANGUL SYLLABLE THIEUTH YEO SSANGKIYEOK
+0xB69F 0xD16B #HANGUL SYLLABLE THIEUTH YEO KIYEOKSIOS
+0xB6A0 0xD16D #HANGUL SYLLABLE THIEUTH YEO NIEUNCIEUC
+0xB6A1 0xB540 #HANGUL SYLLABLE SSANGTIKEUT A MIEUM
+0xB6A2 0xB541 #HANGUL SYLLABLE SSANGTIKEUT A PIEUP
+0xB6A3 0xB543 #HANGUL SYLLABLE SSANGTIKEUT A SIOS
+0xB6A4 0xB544 #HANGUL SYLLABLE SSANGTIKEUT A SSANGSIOS
+0xB6A5 0xB545 #HANGUL SYLLABLE SSANGTIKEUT A IEUNG
+0xB6A6 0xB54B #HANGUL SYLLABLE SSANGTIKEUT A HIEUH
+0xB6A7 0xB54C #HANGUL SYLLABLE SSANGTIKEUT AE
+0xB6A8 0xB54D #HANGUL SYLLABLE SSANGTIKEUT AE KIYEOK
+0xB6A9 0xB550 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUN
+0xB6AA 0xB554 #HANGUL SYLLABLE SSANGTIKEUT AE RIEUL
+0xB6AB 0xB55C #HANGUL SYLLABLE SSANGTIKEUT AE MIEUM
+0xB6AC 0xB55D #HANGUL SYLLABLE SSANGTIKEUT AE PIEUP
+0xB6AD 0xB55F #HANGUL SYLLABLE SSANGTIKEUT AE SIOS
+0xB6AE 0xB560 #HANGUL SYLLABLE SSANGTIKEUT AE SSANGSIOS
+0xB6AF 0xB561 #HANGUL SYLLABLE SSANGTIKEUT AE IEUNG
+0xB6B0 0xB5A0 #HANGUL SYLLABLE SSANGTIKEUT EO
+0xB6B1 0xB5A1 #HANGUL SYLLABLE SSANGTIKEUT EO KIYEOK
+0xB6B2 0xB5A4 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUN
+0xB6B3 0xB5A8 #HANGUL SYLLABLE SSANGTIKEUT EO RIEUL
+0xB6B4 0xB5AA #HANGUL SYLLABLE SSANGTIKEUT EO RIEULMIEUM
+0xB6B5 0xB5AB #HANGUL SYLLABLE SSANGTIKEUT EO RIEULPIEUP
+0xB6B6 0xB5B0 #HANGUL SYLLABLE SSANGTIKEUT EO MIEUM
+0xB6B7 0xB5B1 #HANGUL SYLLABLE SSANGTIKEUT EO PIEUP
+0xB6B8 0xB5B3 #HANGUL SYLLABLE SSANGTIKEUT EO SIOS
+0xB6B9 0xB5B4 #HANGUL SYLLABLE SSANGTIKEUT EO SSANGSIOS
+0xB6BA 0xB5B5 #HANGUL SYLLABLE SSANGTIKEUT EO IEUNG
+0xB6BB 0xB5BB #HANGUL SYLLABLE SSANGTIKEUT EO HIEUH
+0xB6BC 0xB5BC #HANGUL SYLLABLE SSANGTIKEUT E
+0xB6BD 0xB5BD #HANGUL SYLLABLE SSANGTIKEUT E KIYEOK
+0xB6BE 0xB5C0 #HANGUL SYLLABLE SSANGTIKEUT E NIEUN
+0xB6BF 0xB5C4 #HANGUL SYLLABLE SSANGTIKEUT E RIEUL
+0xB6C0 0xB5CC #HANGUL SYLLABLE SSANGTIKEUT E MIEUM
+0xB6C1 0xB5CD #HANGUL SYLLABLE SSANGTIKEUT E PIEUP
+0xB6C2 0xB5CF #HANGUL SYLLABLE SSANGTIKEUT E SIOS
+0xB6C3 0xB5D0 #HANGUL SYLLABLE SSANGTIKEUT E SSANGSIOS
+0xB6C4 0xB5D1 #HANGUL SYLLABLE SSANGTIKEUT E IEUNG
+0xB6C5 0xB5D8 #HANGUL SYLLABLE SSANGTIKEUT YEO
+0xB6C6 0xB5EC #HANGUL SYLLABLE SSANGTIKEUT YEO SSANGSIOS
+0xB6C7 0xB610 #HANGUL SYLLABLE SSANGTIKEUT O
+0xB6C8 0xB611 #HANGUL SYLLABLE SSANGTIKEUT O KIYEOK
+0xB6C9 0xB614 #HANGUL SYLLABLE SSANGTIKEUT O NIEUN
+0xB6CA 0xB618 #HANGUL SYLLABLE SSANGTIKEUT O RIEUL
+0xB6CB 0xB625 #HANGUL SYLLABLE SSANGTIKEUT O IEUNG
+0xB6CC 0xB62C #HANGUL SYLLABLE SSANGTIKEUT WA
+0xB6CD 0xB634 #HANGUL SYLLABLE SSANGTIKEUT WA RIEUL
+0xB6CE 0xB648 #HANGUL SYLLABLE SSANGTIKEUT WAE
+0xB6CF 0xB664 #HANGUL SYLLABLE SSANGTIKEUT OE
+0xB6D0 0xB668 #HANGUL SYLLABLE SSANGTIKEUT OE NIEUN
+0xB6D1 0xB69C #HANGUL SYLLABLE SSANGTIKEUT U
+0xB6D2 0xB69D #HANGUL SYLLABLE SSANGTIKEUT U KIYEOK
+0xB6D3 0xB6A0 #HANGUL SYLLABLE SSANGTIKEUT U NIEUN
+0xB6D4 0xB6A4 #HANGUL SYLLABLE SSANGTIKEUT U RIEUL
+0xB6D5 0xB6AB #HANGUL SYLLABLE SSANGTIKEUT U RIEULHIEUH
+0xB6D6 0xB6AC #HANGUL SYLLABLE SSANGTIKEUT U MIEUM
+0xB6D7 0xB6B1 #HANGUL SYLLABLE SSANGTIKEUT U IEUNG
+0xB6D8 0xB6D4 #HANGUL SYLLABLE SSANGTIKEUT WE
+0xB6D9 0xB6F0 #HANGUL SYLLABLE SSANGTIKEUT WI
+0xB6DA 0xB6F4 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUN
+0xB6DB 0xB6F8 #HANGUL SYLLABLE SSANGTIKEUT WI RIEUL
+0xB6DC 0xB700 #HANGUL SYLLABLE SSANGTIKEUT WI MIEUM
+0xB6DD 0xB701 #HANGUL SYLLABLE SSANGTIKEUT WI PIEUP
+0xB6DE 0xB705 #HANGUL SYLLABLE SSANGTIKEUT WI IEUNG
+0xB6DF 0xB728 #HANGUL SYLLABLE SSANGTIKEUT EU
+0xB6E0 0xB729 #HANGUL SYLLABLE SSANGTIKEUT EU KIYEOK
+0xB6E1 0xB72C #HANGUL SYLLABLE SSANGTIKEUT EU NIEUN
+0xB6E2 0xB72F #HANGUL SYLLABLE SSANGTIKEUT EU TIKEUT
+0xB6E3 0xB730 #HANGUL SYLLABLE SSANGTIKEUT EU RIEUL
+0xB6E4 0xB738 #HANGUL SYLLABLE SSANGTIKEUT EU MIEUM
+0xB6E5 0xB739 #HANGUL SYLLABLE SSANGTIKEUT EU PIEUP
+0xB6E6 0xB73B #HANGUL SYLLABLE SSANGTIKEUT EU SIOS
+0xB6E7 0xB744 #HANGUL SYLLABLE SSANGTIKEUT YI
+0xB6E8 0xB748 #HANGUL SYLLABLE SSANGTIKEUT YI NIEUN
+0xB6E9 0xB74C #HANGUL SYLLABLE SSANGTIKEUT YI RIEUL
+0xB6EA 0xB754 #HANGUL SYLLABLE SSANGTIKEUT YI MIEUM
+0xB6EB 0xB755 #HANGUL SYLLABLE SSANGTIKEUT YI PIEUP
+0xB6EC 0xB760 #HANGUL SYLLABLE SSANGTIKEUT I
+0xB6ED 0xB764 #HANGUL SYLLABLE SSANGTIKEUT I NIEUN
+0xB6EE 0xB768 #HANGUL SYLLABLE SSANGTIKEUT I RIEUL
+0xB6EF 0xB770 #HANGUL SYLLABLE SSANGTIKEUT I MIEUM
+0xB6F0 0xB771 #HANGUL SYLLABLE SSANGTIKEUT I PIEUP
+0xB6F1 0xB773 #HANGUL SYLLABLE SSANGTIKEUT I SIOS
+0xB6F2 0xB775 #HANGUL SYLLABLE SSANGTIKEUT I IEUNG
+0xB6F3 0xB77C #HANGUL SYLLABLE RIEUL A
+0xB6F4 0xB77D #HANGUL SYLLABLE RIEUL A KIYEOK
+0xB6F5 0xB780 #HANGUL SYLLABLE RIEUL A NIEUN
+0xB6F6 0xB784 #HANGUL SYLLABLE RIEUL A RIEUL
+0xB6F7 0xB78C #HANGUL SYLLABLE RIEUL A MIEUM
+0xB6F8 0xB78D #HANGUL SYLLABLE RIEUL A PIEUP
+0xB6F9 0xB78F #HANGUL SYLLABLE RIEUL A SIOS
+0xB6FA 0xB790 #HANGUL SYLLABLE RIEUL A SSANGSIOS
+0xB6FB 0xB791 #HANGUL SYLLABLE RIEUL A IEUNG
+0xB6FC 0xB792 #HANGUL SYLLABLE RIEUL A CIEUC
+0xB6FD 0xB796 #HANGUL SYLLABLE RIEUL A PHIEUPH
+0xB6FE 0xB797 #HANGUL SYLLABLE RIEUL A HIEUH
+0xB741 0xD16E #HANGUL SYLLABLE THIEUTH YEO NIEUNHIEUH
+0xB742 0xD16F #HANGUL SYLLABLE THIEUTH YEO TIKEUT
+0xB743 0xD170 #HANGUL SYLLABLE THIEUTH YEO RIEUL
+0xB744 0xD171 #HANGUL SYLLABLE THIEUTH YEO RIEULKIYEOK
+0xB745 0xD172 #HANGUL SYLLABLE THIEUTH YEO RIEULMIEUM
+0xB746 0xD173 #HANGUL SYLLABLE THIEUTH YEO RIEULPIEUP
+0xB747 0xD174 #HANGUL SYLLABLE THIEUTH YEO RIEULSIOS
+0xB748 0xD175 #HANGUL SYLLABLE THIEUTH YEO RIEULTHIEUTH
+0xB749 0xD176 #HANGUL SYLLABLE THIEUTH YEO RIEULPHIEUPH
+0xB74A 0xD177 #HANGUL SYLLABLE THIEUTH YEO RIEULHIEUH
+0xB74B 0xD178 #HANGUL SYLLABLE THIEUTH YEO MIEUM
+0xB74C 0xD179 #HANGUL SYLLABLE THIEUTH YEO PIEUP
+0xB74D 0xD17A #HANGUL SYLLABLE THIEUTH YEO PIEUPSIOS
+0xB74E 0xD17B #HANGUL SYLLABLE THIEUTH YEO SIOS
+0xB74F 0xD17D #HANGUL SYLLABLE THIEUTH YEO IEUNG
+0xB750 0xD17E #HANGUL SYLLABLE THIEUTH YEO CIEUC
+0xB751 0xD17F #HANGUL SYLLABLE THIEUTH YEO CHIEUCH
+0xB752 0xD180 #HANGUL SYLLABLE THIEUTH YEO KHIEUKH
+0xB753 0xD181 #HANGUL SYLLABLE THIEUTH YEO THIEUTH
+0xB754 0xD182 #HANGUL SYLLABLE THIEUTH YEO PHIEUPH
+0xB755 0xD183 #HANGUL SYLLABLE THIEUTH YEO HIEUH
+0xB756 0xD185 #HANGUL SYLLABLE THIEUTH YE KIYEOK
+0xB757 0xD186 #HANGUL SYLLABLE THIEUTH YE SSANGKIYEOK
+0xB758 0xD187 #HANGUL SYLLABLE THIEUTH YE KIYEOKSIOS
+0xB759 0xD189 #HANGUL SYLLABLE THIEUTH YE NIEUNCIEUC
+0xB75A 0xD18A #HANGUL SYLLABLE THIEUTH YE NIEUNHIEUH
+0xB761 0xD18B #HANGUL SYLLABLE THIEUTH YE TIKEUT
+0xB762 0xD18C #HANGUL SYLLABLE THIEUTH YE RIEUL
+0xB763 0xD18D #HANGUL SYLLABLE THIEUTH YE RIEULKIYEOK
+0xB764 0xD18E #HANGUL SYLLABLE THIEUTH YE RIEULMIEUM
+0xB765 0xD18F #HANGUL SYLLABLE THIEUTH YE RIEULPIEUP
+0xB766 0xD190 #HANGUL SYLLABLE THIEUTH YE RIEULSIOS
+0xB767 0xD191 #HANGUL SYLLABLE THIEUTH YE RIEULTHIEUTH
+0xB768 0xD192 #HANGUL SYLLABLE THIEUTH YE RIEULPHIEUPH
+0xB769 0xD193 #HANGUL SYLLABLE THIEUTH YE RIEULHIEUH
+0xB76A 0xD194 #HANGUL SYLLABLE THIEUTH YE MIEUM
+0xB76B 0xD195 #HANGUL SYLLABLE THIEUTH YE PIEUP
+0xB76C 0xD196 #HANGUL SYLLABLE THIEUTH YE PIEUPSIOS
+0xB76D 0xD197 #HANGUL SYLLABLE THIEUTH YE SIOS
+0xB76E 0xD198 #HANGUL SYLLABLE THIEUTH YE SSANGSIOS
+0xB76F 0xD199 #HANGUL SYLLABLE THIEUTH YE IEUNG
+0xB770 0xD19A #HANGUL SYLLABLE THIEUTH YE CIEUC
+0xB771 0xD19B #HANGUL SYLLABLE THIEUTH YE CHIEUCH
+0xB772 0xD19C #HANGUL SYLLABLE THIEUTH YE KHIEUKH
+0xB773 0xD19D #HANGUL SYLLABLE THIEUTH YE THIEUTH
+0xB774 0xD19E #HANGUL SYLLABLE THIEUTH YE PHIEUPH
+0xB775 0xD19F #HANGUL SYLLABLE THIEUTH YE HIEUH
+0xB776 0xD1A2 #HANGUL SYLLABLE THIEUTH O SSANGKIYEOK
+0xB777 0xD1A3 #HANGUL SYLLABLE THIEUTH O KIYEOKSIOS
+0xB778 0xD1A5 #HANGUL SYLLABLE THIEUTH O NIEUNCIEUC
+0xB779 0xD1A6 #HANGUL SYLLABLE THIEUTH O NIEUNHIEUH
+0xB77A 0xD1A7 #HANGUL SYLLABLE THIEUTH O TIKEUT
+0xB781 0xD1A9 #HANGUL SYLLABLE THIEUTH O RIEULKIYEOK
+0xB782 0xD1AA #HANGUL SYLLABLE THIEUTH O RIEULMIEUM
+0xB783 0xD1AB #HANGUL SYLLABLE THIEUTH O RIEULPIEUP
+0xB784 0xD1AC #HANGUL SYLLABLE THIEUTH O RIEULSIOS
+0xB785 0xD1AD #HANGUL SYLLABLE THIEUTH O RIEULTHIEUTH
+0xB786 0xD1AE #HANGUL SYLLABLE THIEUTH O RIEULPHIEUPH
+0xB787 0xD1AF #HANGUL SYLLABLE THIEUTH O RIEULHIEUH
+0xB788 0xD1B2 #HANGUL SYLLABLE THIEUTH O PIEUPSIOS
+0xB789 0xD1B4 #HANGUL SYLLABLE THIEUTH O SSANGSIOS
+0xB78A 0xD1B6 #HANGUL SYLLABLE THIEUTH O CIEUC
+0xB78B 0xD1B7 #HANGUL SYLLABLE THIEUTH O CHIEUCH
+0xB78C 0xD1B8 #HANGUL SYLLABLE THIEUTH O KHIEUKH
+0xB78D 0xD1B9 #HANGUL SYLLABLE THIEUTH O THIEUTH
+0xB78E 0xD1BB #HANGUL SYLLABLE THIEUTH O HIEUH
+0xB78F 0xD1BD #HANGUL SYLLABLE THIEUTH WA KIYEOK
+0xB790 0xD1BE #HANGUL SYLLABLE THIEUTH WA SSANGKIYEOK
+0xB791 0xD1BF #HANGUL SYLLABLE THIEUTH WA KIYEOKSIOS
+0xB792 0xD1C1 #HANGUL SYLLABLE THIEUTH WA NIEUNCIEUC
+0xB793 0xD1C2 #HANGUL SYLLABLE THIEUTH WA NIEUNHIEUH
+0xB794 0xD1C3 #HANGUL SYLLABLE THIEUTH WA TIKEUT
+0xB795 0xD1C4 #HANGUL SYLLABLE THIEUTH WA RIEUL
+0xB796 0xD1C5 #HANGUL SYLLABLE THIEUTH WA RIEULKIYEOK
+0xB797 0xD1C6 #HANGUL SYLLABLE THIEUTH WA RIEULMIEUM
+0xB798 0xD1C7 #HANGUL SYLLABLE THIEUTH WA RIEULPIEUP
+0xB799 0xD1C8 #HANGUL SYLLABLE THIEUTH WA RIEULSIOS
+0xB79A 0xD1C9 #HANGUL SYLLABLE THIEUTH WA RIEULTHIEUTH
+0xB79B 0xD1CA #HANGUL SYLLABLE THIEUTH WA RIEULPHIEUPH
+0xB79C 0xD1CB #HANGUL SYLLABLE THIEUTH WA RIEULHIEUH
+0xB79D 0xD1CC #HANGUL SYLLABLE THIEUTH WA MIEUM
+0xB79E 0xD1CD #HANGUL SYLLABLE THIEUTH WA PIEUP
+0xB79F 0xD1CE #HANGUL SYLLABLE THIEUTH WA PIEUPSIOS
+0xB7A0 0xD1CF #HANGUL SYLLABLE THIEUTH WA SIOS
+0xB7A1 0xB798 #HANGUL SYLLABLE RIEUL AE
+0xB7A2 0xB799 #HANGUL SYLLABLE RIEUL AE KIYEOK
+0xB7A3 0xB79C #HANGUL SYLLABLE RIEUL AE NIEUN
+0xB7A4 0xB7A0 #HANGUL SYLLABLE RIEUL AE RIEUL
+0xB7A5 0xB7A8 #HANGUL SYLLABLE RIEUL AE MIEUM
+0xB7A6 0xB7A9 #HANGUL SYLLABLE RIEUL AE PIEUP
+0xB7A7 0xB7AB #HANGUL SYLLABLE RIEUL AE SIOS
+0xB7A8 0xB7AC #HANGUL SYLLABLE RIEUL AE SSANGSIOS
+0xB7A9 0xB7AD #HANGUL SYLLABLE RIEUL AE IEUNG
+0xB7AA 0xB7B4 #HANGUL SYLLABLE RIEUL YA
+0xB7AB 0xB7B5 #HANGUL SYLLABLE RIEUL YA KIYEOK
+0xB7AC 0xB7B8 #HANGUL SYLLABLE RIEUL YA NIEUN
+0xB7AD 0xB7C7 #HANGUL SYLLABLE RIEUL YA SIOS
+0xB7AE 0xB7C9 #HANGUL SYLLABLE RIEUL YA IEUNG
+0xB7AF 0xB7EC #HANGUL SYLLABLE RIEUL EO
+0xB7B0 0xB7ED #HANGUL SYLLABLE RIEUL EO KIYEOK
+0xB7B1 0xB7F0 #HANGUL SYLLABLE RIEUL EO NIEUN
+0xB7B2 0xB7F4 #HANGUL SYLLABLE RIEUL EO RIEUL
+0xB7B3 0xB7FC #HANGUL SYLLABLE RIEUL EO MIEUM
+0xB7B4 0xB7FD #HANGUL SYLLABLE RIEUL EO PIEUP
+0xB7B5 0xB7FF #HANGUL SYLLABLE RIEUL EO SIOS
+0xB7B6 0xB800 #HANGUL SYLLABLE RIEUL EO SSANGSIOS
+0xB7B7 0xB801 #HANGUL SYLLABLE RIEUL EO IEUNG
+0xB7B8 0xB807 #HANGUL SYLLABLE RIEUL EO HIEUH
+0xB7B9 0xB808 #HANGUL SYLLABLE RIEUL E
+0xB7BA 0xB809 #HANGUL SYLLABLE RIEUL E KIYEOK
+0xB7BB 0xB80C #HANGUL SYLLABLE RIEUL E NIEUN
+0xB7BC 0xB810 #HANGUL SYLLABLE RIEUL E RIEUL
+0xB7BD 0xB818 #HANGUL SYLLABLE RIEUL E MIEUM
+0xB7BE 0xB819 #HANGUL SYLLABLE RIEUL E PIEUP
+0xB7BF 0xB81B #HANGUL SYLLABLE RIEUL E SIOS
+0xB7C0 0xB81D #HANGUL SYLLABLE RIEUL E IEUNG
+0xB7C1 0xB824 #HANGUL SYLLABLE RIEUL YEO
+0xB7C2 0xB825 #HANGUL SYLLABLE RIEUL YEO KIYEOK
+0xB7C3 0xB828 #HANGUL SYLLABLE RIEUL YEO NIEUN
+0xB7C4 0xB82C #HANGUL SYLLABLE RIEUL YEO RIEUL
+0xB7C5 0xB834 #HANGUL SYLLABLE RIEUL YEO MIEUM
+0xB7C6 0xB835 #HANGUL SYLLABLE RIEUL YEO PIEUP
+0xB7C7 0xB837 #HANGUL SYLLABLE RIEUL YEO SIOS
+0xB7C8 0xB838 #HANGUL SYLLABLE RIEUL YEO SSANGSIOS
+0xB7C9 0xB839 #HANGUL SYLLABLE RIEUL YEO IEUNG
+0xB7CA 0xB840 #HANGUL SYLLABLE RIEUL YE
+0xB7CB 0xB844 #HANGUL SYLLABLE RIEUL YE NIEUN
+0xB7CC 0xB851 #HANGUL SYLLABLE RIEUL YE PIEUP
+0xB7CD 0xB853 #HANGUL SYLLABLE RIEUL YE SIOS
+0xB7CE 0xB85C #HANGUL SYLLABLE RIEUL O
+0xB7CF 0xB85D #HANGUL SYLLABLE RIEUL O KIYEOK
+0xB7D0 0xB860 #HANGUL SYLLABLE RIEUL O NIEUN
+0xB7D1 0xB864 #HANGUL SYLLABLE RIEUL O RIEUL
+0xB7D2 0xB86C #HANGUL SYLLABLE RIEUL O MIEUM
+0xB7D3 0xB86D #HANGUL SYLLABLE RIEUL O PIEUP
+0xB7D4 0xB86F #HANGUL SYLLABLE RIEUL O SIOS
+0xB7D5 0xB871 #HANGUL SYLLABLE RIEUL O IEUNG
+0xB7D6 0xB878 #HANGUL SYLLABLE RIEUL WA
+0xB7D7 0xB87C #HANGUL SYLLABLE RIEUL WA NIEUN
+0xB7D8 0xB88D #HANGUL SYLLABLE RIEUL WA IEUNG
+0xB7D9 0xB8A8 #HANGUL SYLLABLE RIEUL WAE SSANGSIOS
+0xB7DA 0xB8B0 #HANGUL SYLLABLE RIEUL OE
+0xB7DB 0xB8B4 #HANGUL SYLLABLE RIEUL OE NIEUN
+0xB7DC 0xB8B8 #HANGUL SYLLABLE RIEUL OE RIEUL
+0xB7DD 0xB8C0 #HANGUL SYLLABLE RIEUL OE MIEUM
+0xB7DE 0xB8C1 #HANGUL SYLLABLE RIEUL OE PIEUP
+0xB7DF 0xB8C3 #HANGUL SYLLABLE RIEUL OE SIOS
+0xB7E0 0xB8C5 #HANGUL SYLLABLE RIEUL OE IEUNG
+0xB7E1 0xB8CC #HANGUL SYLLABLE RIEUL YO
+0xB7E2 0xB8D0 #HANGUL SYLLABLE RIEUL YO NIEUN
+0xB7E3 0xB8D4 #HANGUL SYLLABLE RIEUL YO RIEUL
+0xB7E4 0xB8DD #HANGUL SYLLABLE RIEUL YO PIEUP
+0xB7E5 0xB8DF #HANGUL SYLLABLE RIEUL YO SIOS
+0xB7E6 0xB8E1 #HANGUL SYLLABLE RIEUL YO IEUNG
+0xB7E7 0xB8E8 #HANGUL SYLLABLE RIEUL U
+0xB7E8 0xB8E9 #HANGUL SYLLABLE RIEUL U KIYEOK
+0xB7E9 0xB8EC #HANGUL SYLLABLE RIEUL U NIEUN
+0xB7EA 0xB8F0 #HANGUL SYLLABLE RIEUL U RIEUL
+0xB7EB 0xB8F8 #HANGUL SYLLABLE RIEUL U MIEUM
+0xB7EC 0xB8F9 #HANGUL SYLLABLE RIEUL U PIEUP
+0xB7ED 0xB8FB #HANGUL SYLLABLE RIEUL U SIOS
+0xB7EE 0xB8FD #HANGUL SYLLABLE RIEUL U IEUNG
+0xB7EF 0xB904 #HANGUL SYLLABLE RIEUL WEO
+0xB7F0 0xB918 #HANGUL SYLLABLE RIEUL WEO SSANGSIOS
+0xB7F1 0xB920 #HANGUL SYLLABLE RIEUL WE
+0xB7F2 0xB93C #HANGUL SYLLABLE RIEUL WI
+0xB7F3 0xB93D #HANGUL SYLLABLE RIEUL WI KIYEOK
+0xB7F4 0xB940 #HANGUL SYLLABLE RIEUL WI NIEUN
+0xB7F5 0xB944 #HANGUL SYLLABLE RIEUL WI RIEUL
+0xB7F6 0xB94C #HANGUL SYLLABLE RIEUL WI MIEUM
+0xB7F7 0xB94F #HANGUL SYLLABLE RIEUL WI SIOS
+0xB7F8 0xB951 #HANGUL SYLLABLE RIEUL WI IEUNG
+0xB7F9 0xB958 #HANGUL SYLLABLE RIEUL YU
+0xB7FA 0xB959 #HANGUL SYLLABLE RIEUL YU KIYEOK
+0xB7FB 0xB95C #HANGUL SYLLABLE RIEUL YU NIEUN
+0xB7FC 0xB960 #HANGUL SYLLABLE RIEUL YU RIEUL
+0xB7FD 0xB968 #HANGUL SYLLABLE RIEUL YU MIEUM
+0xB7FE 0xB969 #HANGUL SYLLABLE RIEUL YU PIEUP
+0xB841 0xD1D0 #HANGUL SYLLABLE THIEUTH WA SSANGSIOS
+0xB842 0xD1D1 #HANGUL SYLLABLE THIEUTH WA IEUNG
+0xB843 0xD1D2 #HANGUL SYLLABLE THIEUTH WA CIEUC
+0xB844 0xD1D3 #HANGUL SYLLABLE THIEUTH WA CHIEUCH
+0xB845 0xD1D4 #HANGUL SYLLABLE THIEUTH WA KHIEUKH
+0xB846 0xD1D5 #HANGUL SYLLABLE THIEUTH WA THIEUTH
+0xB847 0xD1D6 #HANGUL SYLLABLE THIEUTH WA PHIEUPH
+0xB848 0xD1D7 #HANGUL SYLLABLE THIEUTH WA HIEUH
+0xB849 0xD1D9 #HANGUL SYLLABLE THIEUTH WAE KIYEOK
+0xB84A 0xD1DA #HANGUL SYLLABLE THIEUTH WAE SSANGKIYEOK
+0xB84B 0xD1DB #HANGUL SYLLABLE THIEUTH WAE KIYEOKSIOS
+0xB84C 0xD1DC #HANGUL SYLLABLE THIEUTH WAE NIEUN
+0xB84D 0xD1DD #HANGUL SYLLABLE THIEUTH WAE NIEUNCIEUC
+0xB84E 0xD1DE #HANGUL SYLLABLE THIEUTH WAE NIEUNHIEUH
+0xB84F 0xD1DF #HANGUL SYLLABLE THIEUTH WAE TIKEUT
+0xB850 0xD1E0 #HANGUL SYLLABLE THIEUTH WAE RIEUL
+0xB851 0xD1E1 #HANGUL SYLLABLE THIEUTH WAE RIEULKIYEOK
+0xB852 0xD1E2 #HANGUL SYLLABLE THIEUTH WAE RIEULMIEUM
+0xB853 0xD1E3 #HANGUL SYLLABLE THIEUTH WAE RIEULPIEUP
+0xB854 0xD1E4 #HANGUL SYLLABLE THIEUTH WAE RIEULSIOS
+0xB855 0xD1E5 #HANGUL SYLLABLE THIEUTH WAE RIEULTHIEUTH
+0xB856 0xD1E6 #HANGUL SYLLABLE THIEUTH WAE RIEULPHIEUPH
+0xB857 0xD1E7 #HANGUL SYLLABLE THIEUTH WAE RIEULHIEUH
+0xB858 0xD1E8 #HANGUL SYLLABLE THIEUTH WAE MIEUM
+0xB859 0xD1E9 #HANGUL SYLLABLE THIEUTH WAE PIEUP
+0xB85A 0xD1EA #HANGUL SYLLABLE THIEUTH WAE PIEUPSIOS
+0xB861 0xD1EB #HANGUL SYLLABLE THIEUTH WAE SIOS
+0xB862 0xD1EC #HANGUL SYLLABLE THIEUTH WAE SSANGSIOS
+0xB863 0xD1ED #HANGUL SYLLABLE THIEUTH WAE IEUNG
+0xB864 0xD1EE #HANGUL SYLLABLE THIEUTH WAE CIEUC
+0xB865 0xD1EF #HANGUL SYLLABLE THIEUTH WAE CHIEUCH
+0xB866 0xD1F0 #HANGUL SYLLABLE THIEUTH WAE KHIEUKH
+0xB867 0xD1F1 #HANGUL SYLLABLE THIEUTH WAE THIEUTH
+0xB868 0xD1F2 #HANGUL SYLLABLE THIEUTH WAE PHIEUPH
+0xB869 0xD1F3 #HANGUL SYLLABLE THIEUTH WAE HIEUH
+0xB86A 0xD1F5 #HANGUL SYLLABLE THIEUTH OE KIYEOK
+0xB86B 0xD1F6 #HANGUL SYLLABLE THIEUTH OE SSANGKIYEOK
+0xB86C 0xD1F7 #HANGUL SYLLABLE THIEUTH OE KIYEOKSIOS
+0xB86D 0xD1F9 #HANGUL SYLLABLE THIEUTH OE NIEUNCIEUC
+0xB86E 0xD1FA #HANGUL SYLLABLE THIEUTH OE NIEUNHIEUH
+0xB86F 0xD1FB #HANGUL SYLLABLE THIEUTH OE TIKEUT
+0xB870 0xD1FC #HANGUL SYLLABLE THIEUTH OE RIEUL
+0xB871 0xD1FD #HANGUL SYLLABLE THIEUTH OE RIEULKIYEOK
+0xB872 0xD1FE #HANGUL SYLLABLE THIEUTH OE RIEULMIEUM
+0xB873 0xD1FF #HANGUL SYLLABLE THIEUTH OE RIEULPIEUP
+0xB874 0xD200 #HANGUL SYLLABLE THIEUTH OE RIEULSIOS
+0xB875 0xD201 #HANGUL SYLLABLE THIEUTH OE RIEULTHIEUTH
+0xB876 0xD202 #HANGUL SYLLABLE THIEUTH OE RIEULPHIEUPH
+0xB877 0xD203 #HANGUL SYLLABLE THIEUTH OE RIEULHIEUH
+0xB878 0xD204 #HANGUL SYLLABLE THIEUTH OE MIEUM
+0xB879 0xD205 #HANGUL SYLLABLE THIEUTH OE PIEUP
+0xB87A 0xD206 #HANGUL SYLLABLE THIEUTH OE PIEUPSIOS
+0xB881 0xD208 #HANGUL SYLLABLE THIEUTH OE SSANGSIOS
+0xB882 0xD20A #HANGUL SYLLABLE THIEUTH OE CIEUC
+0xB883 0xD20B #HANGUL SYLLABLE THIEUTH OE CHIEUCH
+0xB884 0xD20C #HANGUL SYLLABLE THIEUTH OE KHIEUKH
+0xB885 0xD20D #HANGUL SYLLABLE THIEUTH OE THIEUTH
+0xB886 0xD20E #HANGUL SYLLABLE THIEUTH OE PHIEUPH
+0xB887 0xD20F #HANGUL SYLLABLE THIEUTH OE HIEUH
+0xB888 0xD211 #HANGUL SYLLABLE THIEUTH YO KIYEOK
+0xB889 0xD212 #HANGUL SYLLABLE THIEUTH YO SSANGKIYEOK
+0xB88A 0xD213 #HANGUL SYLLABLE THIEUTH YO KIYEOKSIOS
+0xB88B 0xD214 #HANGUL SYLLABLE THIEUTH YO NIEUN
+0xB88C 0xD215 #HANGUL SYLLABLE THIEUTH YO NIEUNCIEUC
+0xB88D 0xD216 #HANGUL SYLLABLE THIEUTH YO NIEUNHIEUH
+0xB88E 0xD217 #HANGUL SYLLABLE THIEUTH YO TIKEUT
+0xB88F 0xD218 #HANGUL SYLLABLE THIEUTH YO RIEUL
+0xB890 0xD219 #HANGUL SYLLABLE THIEUTH YO RIEULKIYEOK
+0xB891 0xD21A #HANGUL SYLLABLE THIEUTH YO RIEULMIEUM
+0xB892 0xD21B #HANGUL SYLLABLE THIEUTH YO RIEULPIEUP
+0xB893 0xD21C #HANGUL SYLLABLE THIEUTH YO RIEULSIOS
+0xB894 0xD21D #HANGUL SYLLABLE THIEUTH YO RIEULTHIEUTH
+0xB895 0xD21E #HANGUL SYLLABLE THIEUTH YO RIEULPHIEUPH
+0xB896 0xD21F #HANGUL SYLLABLE THIEUTH YO RIEULHIEUH
+0xB897 0xD220 #HANGUL SYLLABLE THIEUTH YO MIEUM
+0xB898 0xD221 #HANGUL SYLLABLE THIEUTH YO PIEUP
+0xB899 0xD222 #HANGUL SYLLABLE THIEUTH YO PIEUPSIOS
+0xB89A 0xD223 #HANGUL SYLLABLE THIEUTH YO SIOS
+0xB89B 0xD224 #HANGUL SYLLABLE THIEUTH YO SSANGSIOS
+0xB89C 0xD225 #HANGUL SYLLABLE THIEUTH YO IEUNG
+0xB89D 0xD226 #HANGUL SYLLABLE THIEUTH YO CIEUC
+0xB89E 0xD227 #HANGUL SYLLABLE THIEUTH YO CHIEUCH
+0xB89F 0xD228 #HANGUL SYLLABLE THIEUTH YO KHIEUKH
+0xB8A0 0xD229 #HANGUL SYLLABLE THIEUTH YO THIEUTH
+0xB8A1 0xB96B #HANGUL SYLLABLE RIEUL YU SIOS
+0xB8A2 0xB96D #HANGUL SYLLABLE RIEUL YU IEUNG
+0xB8A3 0xB974 #HANGUL SYLLABLE RIEUL EU
+0xB8A4 0xB975 #HANGUL SYLLABLE RIEUL EU KIYEOK
+0xB8A5 0xB978 #HANGUL SYLLABLE RIEUL EU NIEUN
+0xB8A6 0xB97C #HANGUL SYLLABLE RIEUL EU RIEUL
+0xB8A7 0xB984 #HANGUL SYLLABLE RIEUL EU MIEUM
+0xB8A8 0xB985 #HANGUL SYLLABLE RIEUL EU PIEUP
+0xB8A9 0xB987 #HANGUL SYLLABLE RIEUL EU SIOS
+0xB8AA 0xB989 #HANGUL SYLLABLE RIEUL EU IEUNG
+0xB8AB 0xB98A #HANGUL SYLLABLE RIEUL EU CIEUC
+0xB8AC 0xB98D #HANGUL SYLLABLE RIEUL EU THIEUTH
+0xB8AD 0xB98E #HANGUL SYLLABLE RIEUL EU PHIEUPH
+0xB8AE 0xB9AC #HANGUL SYLLABLE RIEUL I
+0xB8AF 0xB9AD #HANGUL SYLLABLE RIEUL I KIYEOK
+0xB8B0 0xB9B0 #HANGUL SYLLABLE RIEUL I NIEUN
+0xB8B1 0xB9B4 #HANGUL SYLLABLE RIEUL I RIEUL
+0xB8B2 0xB9BC #HANGUL SYLLABLE RIEUL I MIEUM
+0xB8B3 0xB9BD #HANGUL SYLLABLE RIEUL I PIEUP
+0xB8B4 0xB9BF #HANGUL SYLLABLE RIEUL I SIOS
+0xB8B5 0xB9C1 #HANGUL SYLLABLE RIEUL I IEUNG
+0xB8B6 0xB9C8 #HANGUL SYLLABLE MIEUM A
+0xB8B7 0xB9C9 #HANGUL SYLLABLE MIEUM A KIYEOK
+0xB8B8 0xB9CC #HANGUL SYLLABLE MIEUM A NIEUN
+0xB8B9 0xB9CE #HANGUL SYLLABLE MIEUM A NIEUNHIEUH
+0xB8BA 0xB9CF #HANGUL SYLLABLE MIEUM A TIKEUT
+0xB8BB 0xB9D0 #HANGUL SYLLABLE MIEUM A RIEUL
+0xB8BC 0xB9D1 #HANGUL SYLLABLE MIEUM A RIEULKIYEOK
+0xB8BD 0xB9D2 #HANGUL SYLLABLE MIEUM A RIEULMIEUM
+0xB8BE 0xB9D8 #HANGUL SYLLABLE MIEUM A MIEUM
+0xB8BF 0xB9D9 #HANGUL SYLLABLE MIEUM A PIEUP
+0xB8C0 0xB9DB #HANGUL SYLLABLE MIEUM A SIOS
+0xB8C1 0xB9DD #HANGUL SYLLABLE MIEUM A IEUNG
+0xB8C2 0xB9DE #HANGUL SYLLABLE MIEUM A CIEUC
+0xB8C3 0xB9E1 #HANGUL SYLLABLE MIEUM A THIEUTH
+0xB8C4 0xB9E3 #HANGUL SYLLABLE MIEUM A HIEUH
+0xB8C5 0xB9E4 #HANGUL SYLLABLE MIEUM AE
+0xB8C6 0xB9E5 #HANGUL SYLLABLE MIEUM AE KIYEOK
+0xB8C7 0xB9E8 #HANGUL SYLLABLE MIEUM AE NIEUN
+0xB8C8 0xB9EC #HANGUL SYLLABLE MIEUM AE RIEUL
+0xB8C9 0xB9F4 #HANGUL SYLLABLE MIEUM AE MIEUM
+0xB8CA 0xB9F5 #HANGUL SYLLABLE MIEUM AE PIEUP
+0xB8CB 0xB9F7 #HANGUL SYLLABLE MIEUM AE SIOS
+0xB8CC 0xB9F8 #HANGUL SYLLABLE MIEUM AE SSANGSIOS
+0xB8CD 0xB9F9 #HANGUL SYLLABLE MIEUM AE IEUNG
+0xB8CE 0xB9FA #HANGUL SYLLABLE MIEUM AE CIEUC
+0xB8CF 0xBA00 #HANGUL SYLLABLE MIEUM YA
+0xB8D0 0xBA01 #HANGUL SYLLABLE MIEUM YA KIYEOK
+0xB8D1 0xBA08 #HANGUL SYLLABLE MIEUM YA RIEUL
+0xB8D2 0xBA15 #HANGUL SYLLABLE MIEUM YA IEUNG
+0xB8D3 0xBA38 #HANGUL SYLLABLE MIEUM EO
+0xB8D4 0xBA39 #HANGUL SYLLABLE MIEUM EO KIYEOK
+0xB8D5 0xBA3C #HANGUL SYLLABLE MIEUM EO NIEUN
+0xB8D6 0xBA40 #HANGUL SYLLABLE MIEUM EO RIEUL
+0xB8D7 0xBA42 #HANGUL SYLLABLE MIEUM EO RIEULMIEUM
+0xB8D8 0xBA48 #HANGUL SYLLABLE MIEUM EO MIEUM
+0xB8D9 0xBA49 #HANGUL SYLLABLE MIEUM EO PIEUP
+0xB8DA 0xBA4B #HANGUL SYLLABLE MIEUM EO SIOS
+0xB8DB 0xBA4D #HANGUL SYLLABLE MIEUM EO IEUNG
+0xB8DC 0xBA4E #HANGUL SYLLABLE MIEUM EO CIEUC
+0xB8DD 0xBA53 #HANGUL SYLLABLE MIEUM EO HIEUH
+0xB8DE 0xBA54 #HANGUL SYLLABLE MIEUM E
+0xB8DF 0xBA55 #HANGUL SYLLABLE MIEUM E KIYEOK
+0xB8E0 0xBA58 #HANGUL SYLLABLE MIEUM E NIEUN
+0xB8E1 0xBA5C #HANGUL SYLLABLE MIEUM E RIEUL
+0xB8E2 0xBA64 #HANGUL SYLLABLE MIEUM E MIEUM
+0xB8E3 0xBA65 #HANGUL SYLLABLE MIEUM E PIEUP
+0xB8E4 0xBA67 #HANGUL SYLLABLE MIEUM E SIOS
+0xB8E5 0xBA68 #HANGUL SYLLABLE MIEUM E SSANGSIOS
+0xB8E6 0xBA69 #HANGUL SYLLABLE MIEUM E IEUNG
+0xB8E7 0xBA70 #HANGUL SYLLABLE MIEUM YEO
+0xB8E8 0xBA71 #HANGUL SYLLABLE MIEUM YEO KIYEOK
+0xB8E9 0xBA74 #HANGUL SYLLABLE MIEUM YEO NIEUN
+0xB8EA 0xBA78 #HANGUL SYLLABLE MIEUM YEO RIEUL
+0xB8EB 0xBA83 #HANGUL SYLLABLE MIEUM YEO SIOS
+0xB8EC 0xBA84 #HANGUL SYLLABLE MIEUM YEO SSANGSIOS
+0xB8ED 0xBA85 #HANGUL SYLLABLE MIEUM YEO IEUNG
+0xB8EE 0xBA87 #HANGUL SYLLABLE MIEUM YEO CHIEUCH
+0xB8EF 0xBA8C #HANGUL SYLLABLE MIEUM YE
+0xB8F0 0xBAA8 #HANGUL SYLLABLE MIEUM O
+0xB8F1 0xBAA9 #HANGUL SYLLABLE MIEUM O KIYEOK
+0xB8F2 0xBAAB #HANGUL SYLLABLE MIEUM O KIYEOKSIOS
+0xB8F3 0xBAAC #HANGUL SYLLABLE MIEUM O NIEUN
+0xB8F4 0xBAB0 #HANGUL SYLLABLE MIEUM O RIEUL
+0xB8F5 0xBAB2 #HANGUL SYLLABLE MIEUM O RIEULMIEUM
+0xB8F6 0xBAB8 #HANGUL SYLLABLE MIEUM O MIEUM
+0xB8F7 0xBAB9 #HANGUL SYLLABLE MIEUM O PIEUP
+0xB8F8 0xBABB #HANGUL SYLLABLE MIEUM O SIOS
+0xB8F9 0xBABD #HANGUL SYLLABLE MIEUM O IEUNG
+0xB8FA 0xBAC4 #HANGUL SYLLABLE MIEUM WA
+0xB8FB 0xBAC8 #HANGUL SYLLABLE MIEUM WA NIEUN
+0xB8FC 0xBAD8 #HANGUL SYLLABLE MIEUM WA SSANGSIOS
+0xB8FD 0xBAD9 #HANGUL SYLLABLE MIEUM WA IEUNG
+0xB8FE 0xBAFC #HANGUL SYLLABLE MIEUM OE
+0xB941 0xD22A #HANGUL SYLLABLE THIEUTH YO PHIEUPH
+0xB942 0xD22B #HANGUL SYLLABLE THIEUTH YO HIEUH
+0xB943 0xD22E #HANGUL SYLLABLE THIEUTH U SSANGKIYEOK
+0xB944 0xD22F #HANGUL SYLLABLE THIEUTH U KIYEOKSIOS
+0xB945 0xD231 #HANGUL SYLLABLE THIEUTH U NIEUNCIEUC
+0xB946 0xD232 #HANGUL SYLLABLE THIEUTH U NIEUNHIEUH
+0xB947 0xD233 #HANGUL SYLLABLE THIEUTH U TIKEUT
+0xB948 0xD235 #HANGUL SYLLABLE THIEUTH U RIEULKIYEOK
+0xB949 0xD236 #HANGUL SYLLABLE THIEUTH U RIEULMIEUM
+0xB94A 0xD237 #HANGUL SYLLABLE THIEUTH U RIEULPIEUP
+0xB94B 0xD238 #HANGUL SYLLABLE THIEUTH U RIEULSIOS
+0xB94C 0xD239 #HANGUL SYLLABLE THIEUTH U RIEULTHIEUTH
+0xB94D 0xD23A #HANGUL SYLLABLE THIEUTH U RIEULPHIEUPH
+0xB94E 0xD23B #HANGUL SYLLABLE THIEUTH U RIEULHIEUH
+0xB94F 0xD23E #HANGUL SYLLABLE THIEUTH U PIEUPSIOS
+0xB950 0xD240 #HANGUL SYLLABLE THIEUTH U SSANGSIOS
+0xB951 0xD242 #HANGUL SYLLABLE THIEUTH U CIEUC
+0xB952 0xD243 #HANGUL SYLLABLE THIEUTH U CHIEUCH
+0xB953 0xD244 #HANGUL SYLLABLE THIEUTH U KHIEUKH
+0xB954 0xD245 #HANGUL SYLLABLE THIEUTH U THIEUTH
+0xB955 0xD246 #HANGUL SYLLABLE THIEUTH U PHIEUPH
+0xB956 0xD247 #HANGUL SYLLABLE THIEUTH U HIEUH
+0xB957 0xD249 #HANGUL SYLLABLE THIEUTH WEO KIYEOK
+0xB958 0xD24A #HANGUL SYLLABLE THIEUTH WEO SSANGKIYEOK
+0xB959 0xD24B #HANGUL SYLLABLE THIEUTH WEO KIYEOKSIOS
+0xB95A 0xD24C #HANGUL SYLLABLE THIEUTH WEO NIEUN
+0xB961 0xD24D #HANGUL SYLLABLE THIEUTH WEO NIEUNCIEUC
+0xB962 0xD24E #HANGUL SYLLABLE THIEUTH WEO NIEUNHIEUH
+0xB963 0xD24F #HANGUL SYLLABLE THIEUTH WEO TIKEUT
+0xB964 0xD250 #HANGUL SYLLABLE THIEUTH WEO RIEUL
+0xB965 0xD251 #HANGUL SYLLABLE THIEUTH WEO RIEULKIYEOK
+0xB966 0xD252 #HANGUL SYLLABLE THIEUTH WEO RIEULMIEUM
+0xB967 0xD253 #HANGUL SYLLABLE THIEUTH WEO RIEULPIEUP
+0xB968 0xD254 #HANGUL SYLLABLE THIEUTH WEO RIEULSIOS
+0xB969 0xD255 #HANGUL SYLLABLE THIEUTH WEO RIEULTHIEUTH
+0xB96A 0xD256 #HANGUL SYLLABLE THIEUTH WEO RIEULPHIEUPH
+0xB96B 0xD257 #HANGUL SYLLABLE THIEUTH WEO RIEULHIEUH
+0xB96C 0xD258 #HANGUL SYLLABLE THIEUTH WEO MIEUM
+0xB96D 0xD259 #HANGUL SYLLABLE THIEUTH WEO PIEUP
+0xB96E 0xD25A #HANGUL SYLLABLE THIEUTH WEO PIEUPSIOS
+0xB96F 0xD25B #HANGUL SYLLABLE THIEUTH WEO SIOS
+0xB970 0xD25D #HANGUL SYLLABLE THIEUTH WEO IEUNG
+0xB971 0xD25E #HANGUL SYLLABLE THIEUTH WEO CIEUC
+0xB972 0xD25F #HANGUL SYLLABLE THIEUTH WEO CHIEUCH
+0xB973 0xD260 #HANGUL SYLLABLE THIEUTH WEO KHIEUKH
+0xB974 0xD261 #HANGUL SYLLABLE THIEUTH WEO THIEUTH
+0xB975 0xD262 #HANGUL SYLLABLE THIEUTH WEO PHIEUPH
+0xB976 0xD263 #HANGUL SYLLABLE THIEUTH WEO HIEUH
+0xB977 0xD265 #HANGUL SYLLABLE THIEUTH WE KIYEOK
+0xB978 0xD266 #HANGUL SYLLABLE THIEUTH WE SSANGKIYEOK
+0xB979 0xD267 #HANGUL SYLLABLE THIEUTH WE KIYEOKSIOS
+0xB97A 0xD268 #HANGUL SYLLABLE THIEUTH WE NIEUN
+0xB981 0xD269 #HANGUL SYLLABLE THIEUTH WE NIEUNCIEUC
+0xB982 0xD26A #HANGUL SYLLABLE THIEUTH WE NIEUNHIEUH
+0xB983 0xD26B #HANGUL SYLLABLE THIEUTH WE TIKEUT
+0xB984 0xD26C #HANGUL SYLLABLE THIEUTH WE RIEUL
+0xB985 0xD26D #HANGUL SYLLABLE THIEUTH WE RIEULKIYEOK
+0xB986 0xD26E #HANGUL SYLLABLE THIEUTH WE RIEULMIEUM
+0xB987 0xD26F #HANGUL SYLLABLE THIEUTH WE RIEULPIEUP
+0xB988 0xD270 #HANGUL SYLLABLE THIEUTH WE RIEULSIOS
+0xB989 0xD271 #HANGUL SYLLABLE THIEUTH WE RIEULTHIEUTH
+0xB98A 0xD272 #HANGUL SYLLABLE THIEUTH WE RIEULPHIEUPH
+0xB98B 0xD273 #HANGUL SYLLABLE THIEUTH WE RIEULHIEUH
+0xB98C 0xD274 #HANGUL SYLLABLE THIEUTH WE MIEUM
+0xB98D 0xD275 #HANGUL SYLLABLE THIEUTH WE PIEUP
+0xB98E 0xD276 #HANGUL SYLLABLE THIEUTH WE PIEUPSIOS
+0xB98F 0xD277 #HANGUL SYLLABLE THIEUTH WE SIOS
+0xB990 0xD278 #HANGUL SYLLABLE THIEUTH WE SSANGSIOS
+0xB991 0xD279 #HANGUL SYLLABLE THIEUTH WE IEUNG
+0xB992 0xD27A #HANGUL SYLLABLE THIEUTH WE CIEUC
+0xB993 0xD27B #HANGUL SYLLABLE THIEUTH WE CHIEUCH
+0xB994 0xD27C #HANGUL SYLLABLE THIEUTH WE KHIEUKH
+0xB995 0xD27D #HANGUL SYLLABLE THIEUTH WE THIEUTH
+0xB996 0xD27E #HANGUL SYLLABLE THIEUTH WE PHIEUPH
+0xB997 0xD27F #HANGUL SYLLABLE THIEUTH WE HIEUH
+0xB998 0xD282 #HANGUL SYLLABLE THIEUTH WI SSANGKIYEOK
+0xB999 0xD283 #HANGUL SYLLABLE THIEUTH WI KIYEOKSIOS
+0xB99A 0xD285 #HANGUL SYLLABLE THIEUTH WI NIEUNCIEUC
+0xB99B 0xD286 #HANGUL SYLLABLE THIEUTH WI NIEUNHIEUH
+0xB99C 0xD287 #HANGUL SYLLABLE THIEUTH WI TIKEUT
+0xB99D 0xD289 #HANGUL SYLLABLE THIEUTH WI RIEULKIYEOK
+0xB99E 0xD28A #HANGUL SYLLABLE THIEUTH WI RIEULMIEUM
+0xB99F 0xD28B #HANGUL SYLLABLE THIEUTH WI RIEULPIEUP
+0xB9A0 0xD28C #HANGUL SYLLABLE THIEUTH WI RIEULSIOS
+0xB9A1 0xBB00 #HANGUL SYLLABLE MIEUM OE NIEUN
+0xB9A2 0xBB04 #HANGUL SYLLABLE MIEUM OE RIEUL
+0xB9A3 0xBB0D #HANGUL SYLLABLE MIEUM OE PIEUP
+0xB9A4 0xBB0F #HANGUL SYLLABLE MIEUM OE SIOS
+0xB9A5 0xBB11 #HANGUL SYLLABLE MIEUM OE IEUNG
+0xB9A6 0xBB18 #HANGUL SYLLABLE MIEUM YO
+0xB9A7 0xBB1C #HANGUL SYLLABLE MIEUM YO NIEUN
+0xB9A8 0xBB20 #HANGUL SYLLABLE MIEUM YO RIEUL
+0xB9A9 0xBB29 #HANGUL SYLLABLE MIEUM YO PIEUP
+0xB9AA 0xBB2B #HANGUL SYLLABLE MIEUM YO SIOS
+0xB9AB 0xBB34 #HANGUL SYLLABLE MIEUM U
+0xB9AC 0xBB35 #HANGUL SYLLABLE MIEUM U KIYEOK
+0xB9AD 0xBB36 #HANGUL SYLLABLE MIEUM U SSANGKIYEOK
+0xB9AE 0xBB38 #HANGUL SYLLABLE MIEUM U NIEUN
+0xB9AF 0xBB3B #HANGUL SYLLABLE MIEUM U TIKEUT
+0xB9B0 0xBB3C #HANGUL SYLLABLE MIEUM U RIEUL
+0xB9B1 0xBB3D #HANGUL SYLLABLE MIEUM U RIEULKIYEOK
+0xB9B2 0xBB3E #HANGUL SYLLABLE MIEUM U RIEULMIEUM
+0xB9B3 0xBB44 #HANGUL SYLLABLE MIEUM U MIEUM
+0xB9B4 0xBB45 #HANGUL SYLLABLE MIEUM U PIEUP
+0xB9B5 0xBB47 #HANGUL SYLLABLE MIEUM U SIOS
+0xB9B6 0xBB49 #HANGUL SYLLABLE MIEUM U IEUNG
+0xB9B7 0xBB4D #HANGUL SYLLABLE MIEUM U THIEUTH
+0xB9B8 0xBB4F #HANGUL SYLLABLE MIEUM U HIEUH
+0xB9B9 0xBB50 #HANGUL SYLLABLE MIEUM WEO
+0xB9BA 0xBB54 #HANGUL SYLLABLE MIEUM WEO NIEUN
+0xB9BB 0xBB58 #HANGUL SYLLABLE MIEUM WEO RIEUL
+0xB9BC 0xBB61 #HANGUL SYLLABLE MIEUM WEO PIEUP
+0xB9BD 0xBB63 #HANGUL SYLLABLE MIEUM WEO SIOS
+0xB9BE 0xBB6C #HANGUL SYLLABLE MIEUM WE
+0xB9BF 0xBB88 #HANGUL SYLLABLE MIEUM WI
+0xB9C0 0xBB8C #HANGUL SYLLABLE MIEUM WI NIEUN
+0xB9C1 0xBB90 #HANGUL SYLLABLE MIEUM WI RIEUL
+0xB9C2 0xBBA4 #HANGUL SYLLABLE MIEUM YU
+0xB9C3 0xBBA8 #HANGUL SYLLABLE MIEUM YU NIEUN
+0xB9C4 0xBBAC #HANGUL SYLLABLE MIEUM YU RIEUL
+0xB9C5 0xBBB4 #HANGUL SYLLABLE MIEUM YU MIEUM
+0xB9C6 0xBBB7 #HANGUL SYLLABLE MIEUM YU SIOS
+0xB9C7 0xBBC0 #HANGUL SYLLABLE MIEUM EU
+0xB9C8 0xBBC4 #HANGUL SYLLABLE MIEUM EU NIEUN
+0xB9C9 0xBBC8 #HANGUL SYLLABLE MIEUM EU RIEUL
+0xB9CA 0xBBD0 #HANGUL SYLLABLE MIEUM EU MIEUM
+0xB9CB 0xBBD3 #HANGUL SYLLABLE MIEUM EU SIOS
+0xB9CC 0xBBF8 #HANGUL SYLLABLE MIEUM I
+0xB9CD 0xBBF9 #HANGUL SYLLABLE MIEUM I KIYEOK
+0xB9CE 0xBBFC #HANGUL SYLLABLE MIEUM I NIEUN
+0xB9CF 0xBBFF #HANGUL SYLLABLE MIEUM I TIKEUT
+0xB9D0 0xBC00 #HANGUL SYLLABLE MIEUM I RIEUL
+0xB9D1 0xBC02 #HANGUL SYLLABLE MIEUM I RIEULMIEUM
+0xB9D2 0xBC08 #HANGUL SYLLABLE MIEUM I MIEUM
+0xB9D3 0xBC09 #HANGUL SYLLABLE MIEUM I PIEUP
+0xB9D4 0xBC0B #HANGUL SYLLABLE MIEUM I SIOS
+0xB9D5 0xBC0C #HANGUL SYLLABLE MIEUM I SSANGSIOS
+0xB9D6 0xBC0D #HANGUL SYLLABLE MIEUM I IEUNG
+0xB9D7 0xBC0F #HANGUL SYLLABLE MIEUM I CHIEUCH
+0xB9D8 0xBC11 #HANGUL SYLLABLE MIEUM I THIEUTH
+0xB9D9 0xBC14 #HANGUL SYLLABLE PIEUP A
+0xB9DA 0xBC15 #HANGUL SYLLABLE PIEUP A KIYEOK
+0xB9DB 0xBC16 #HANGUL SYLLABLE PIEUP A SSANGKIYEOK
+0xB9DC 0xBC17 #HANGUL SYLLABLE PIEUP A KIYEOKSIOS
+0xB9DD 0xBC18 #HANGUL SYLLABLE PIEUP A NIEUN
+0xB9DE 0xBC1B #HANGUL SYLLABLE PIEUP A TIKEUT
+0xB9DF 0xBC1C #HANGUL SYLLABLE PIEUP A RIEUL
+0xB9E0 0xBC1D #HANGUL SYLLABLE PIEUP A RIEULKIYEOK
+0xB9E1 0xBC1E #HANGUL SYLLABLE PIEUP A RIEULMIEUM
+0xB9E2 0xBC1F #HANGUL SYLLABLE PIEUP A RIEULPIEUP
+0xB9E3 0xBC24 #HANGUL SYLLABLE PIEUP A MIEUM
+0xB9E4 0xBC25 #HANGUL SYLLABLE PIEUP A PIEUP
+0xB9E5 0xBC27 #HANGUL SYLLABLE PIEUP A SIOS
+0xB9E6 0xBC29 #HANGUL SYLLABLE PIEUP A IEUNG
+0xB9E7 0xBC2D #HANGUL SYLLABLE PIEUP A THIEUTH
+0xB9E8 0xBC30 #HANGUL SYLLABLE PIEUP AE
+0xB9E9 0xBC31 #HANGUL SYLLABLE PIEUP AE KIYEOK
+0xB9EA 0xBC34 #HANGUL SYLLABLE PIEUP AE NIEUN
+0xB9EB 0xBC38 #HANGUL SYLLABLE PIEUP AE RIEUL
+0xB9EC 0xBC40 #HANGUL SYLLABLE PIEUP AE MIEUM
+0xB9ED 0xBC41 #HANGUL SYLLABLE PIEUP AE PIEUP
+0xB9EE 0xBC43 #HANGUL SYLLABLE PIEUP AE SIOS
+0xB9EF 0xBC44 #HANGUL SYLLABLE PIEUP AE SSANGSIOS
+0xB9F0 0xBC45 #HANGUL SYLLABLE PIEUP AE IEUNG
+0xB9F1 0xBC49 #HANGUL SYLLABLE PIEUP AE THIEUTH
+0xB9F2 0xBC4C #HANGUL SYLLABLE PIEUP YA
+0xB9F3 0xBC4D #HANGUL SYLLABLE PIEUP YA KIYEOK
+0xB9F4 0xBC50 #HANGUL SYLLABLE PIEUP YA NIEUN
+0xB9F5 0xBC5D #HANGUL SYLLABLE PIEUP YA PIEUP
+0xB9F6 0xBC84 #HANGUL SYLLABLE PIEUP EO
+0xB9F7 0xBC85 #HANGUL SYLLABLE PIEUP EO KIYEOK
+0xB9F8 0xBC88 #HANGUL SYLLABLE PIEUP EO NIEUN
+0xB9F9 0xBC8B #HANGUL SYLLABLE PIEUP EO TIKEUT
+0xB9FA 0xBC8C #HANGUL SYLLABLE PIEUP EO RIEUL
+0xB9FB 0xBC8E #HANGUL SYLLABLE PIEUP EO RIEULMIEUM
+0xB9FC 0xBC94 #HANGUL SYLLABLE PIEUP EO MIEUM
+0xB9FD 0xBC95 #HANGUL SYLLABLE PIEUP EO PIEUP
+0xB9FE 0xBC97 #HANGUL SYLLABLE PIEUP EO SIOS
+0xBA41 0xD28D #HANGUL SYLLABLE THIEUTH WI RIEULTHIEUTH
+0xBA42 0xD28E #HANGUL SYLLABLE THIEUTH WI RIEULPHIEUPH
+0xBA43 0xD28F #HANGUL SYLLABLE THIEUTH WI RIEULHIEUH
+0xBA44 0xD292 #HANGUL SYLLABLE THIEUTH WI PIEUPSIOS
+0xBA45 0xD293 #HANGUL SYLLABLE THIEUTH WI SIOS
+0xBA46 0xD294 #HANGUL SYLLABLE THIEUTH WI SSANGSIOS
+0xBA47 0xD296 #HANGUL SYLLABLE THIEUTH WI CIEUC
+0xBA48 0xD297 #HANGUL SYLLABLE THIEUTH WI CHIEUCH
+0xBA49 0xD298 #HANGUL SYLLABLE THIEUTH WI KHIEUKH
+0xBA4A 0xD299 #HANGUL SYLLABLE THIEUTH WI THIEUTH
+0xBA4B 0xD29A #HANGUL SYLLABLE THIEUTH WI PHIEUPH
+0xBA4C 0xD29B #HANGUL SYLLABLE THIEUTH WI HIEUH
+0xBA4D 0xD29D #HANGUL SYLLABLE THIEUTH YU KIYEOK
+0xBA4E 0xD29E #HANGUL SYLLABLE THIEUTH YU SSANGKIYEOK
+0xBA4F 0xD29F #HANGUL SYLLABLE THIEUTH YU KIYEOKSIOS
+0xBA50 0xD2A1 #HANGUL SYLLABLE THIEUTH YU NIEUNCIEUC
+0xBA51 0xD2A2 #HANGUL SYLLABLE THIEUTH YU NIEUNHIEUH
+0xBA52 0xD2A3 #HANGUL SYLLABLE THIEUTH YU TIKEUT
+0xBA53 0xD2A5 #HANGUL SYLLABLE THIEUTH YU RIEULKIYEOK
+0xBA54 0xD2A6 #HANGUL SYLLABLE THIEUTH YU RIEULMIEUM
+0xBA55 0xD2A7 #HANGUL SYLLABLE THIEUTH YU RIEULPIEUP
+0xBA56 0xD2A8 #HANGUL SYLLABLE THIEUTH YU RIEULSIOS
+0xBA57 0xD2A9 #HANGUL SYLLABLE THIEUTH YU RIEULTHIEUTH
+0xBA58 0xD2AA #HANGUL SYLLABLE THIEUTH YU RIEULPHIEUPH
+0xBA59 0xD2AB #HANGUL SYLLABLE THIEUTH YU RIEULHIEUH
+0xBA5A 0xD2AD #HANGUL SYLLABLE THIEUTH YU PIEUP
+0xBA61 0xD2AE #HANGUL SYLLABLE THIEUTH YU PIEUPSIOS
+0xBA62 0xD2AF #HANGUL SYLLABLE THIEUTH YU SIOS
+0xBA63 0xD2B0 #HANGUL SYLLABLE THIEUTH YU SSANGSIOS
+0xBA64 0xD2B2 #HANGUL SYLLABLE THIEUTH YU CIEUC
+0xBA65 0xD2B3 #HANGUL SYLLABLE THIEUTH YU CHIEUCH
+0xBA66 0xD2B4 #HANGUL SYLLABLE THIEUTH YU KHIEUKH
+0xBA67 0xD2B5 #HANGUL SYLLABLE THIEUTH YU THIEUTH
+0xBA68 0xD2B6 #HANGUL SYLLABLE THIEUTH YU PHIEUPH
+0xBA69 0xD2B7 #HANGUL SYLLABLE THIEUTH YU HIEUH
+0xBA6A 0xD2BA #HANGUL SYLLABLE THIEUTH EU SSANGKIYEOK
+0xBA6B 0xD2BB #HANGUL SYLLABLE THIEUTH EU KIYEOKSIOS
+0xBA6C 0xD2BD #HANGUL SYLLABLE THIEUTH EU NIEUNCIEUC
+0xBA6D 0xD2BE #HANGUL SYLLABLE THIEUTH EU NIEUNHIEUH
+0xBA6E 0xD2C1 #HANGUL SYLLABLE THIEUTH EU RIEULKIYEOK
+0xBA6F 0xD2C3 #HANGUL SYLLABLE THIEUTH EU RIEULPIEUP
+0xBA70 0xD2C4 #HANGUL SYLLABLE THIEUTH EU RIEULSIOS
+0xBA71 0xD2C5 #HANGUL SYLLABLE THIEUTH EU RIEULTHIEUTH
+0xBA72 0xD2C6 #HANGUL SYLLABLE THIEUTH EU RIEULPHIEUPH
+0xBA73 0xD2C7 #HANGUL SYLLABLE THIEUTH EU RIEULHIEUH
+0xBA74 0xD2CA #HANGUL SYLLABLE THIEUTH EU PIEUPSIOS
+0xBA75 0xD2CC #HANGUL SYLLABLE THIEUTH EU SSANGSIOS
+0xBA76 0xD2CD #HANGUL SYLLABLE THIEUTH EU IEUNG
+0xBA77 0xD2CE #HANGUL SYLLABLE THIEUTH EU CIEUC
+0xBA78 0xD2CF #HANGUL SYLLABLE THIEUTH EU CHIEUCH
+0xBA79 0xD2D0 #HANGUL SYLLABLE THIEUTH EU KHIEUKH
+0xBA7A 0xD2D1 #HANGUL SYLLABLE THIEUTH EU THIEUTH
+0xBA81 0xD2D2 #HANGUL SYLLABLE THIEUTH EU PHIEUPH
+0xBA82 0xD2D3 #HANGUL SYLLABLE THIEUTH EU HIEUH
+0xBA83 0xD2D5 #HANGUL SYLLABLE THIEUTH YI KIYEOK
+0xBA84 0xD2D6 #HANGUL SYLLABLE THIEUTH YI SSANGKIYEOK
+0xBA85 0xD2D7 #HANGUL SYLLABLE THIEUTH YI KIYEOKSIOS
+0xBA86 0xD2D9 #HANGUL SYLLABLE THIEUTH YI NIEUNCIEUC
+0xBA87 0xD2DA #HANGUL SYLLABLE THIEUTH YI NIEUNHIEUH
+0xBA88 0xD2DB #HANGUL SYLLABLE THIEUTH YI TIKEUT
+0xBA89 0xD2DD #HANGUL SYLLABLE THIEUTH YI RIEULKIYEOK
+0xBA8A 0xD2DE #HANGUL SYLLABLE THIEUTH YI RIEULMIEUM
+0xBA8B 0xD2DF #HANGUL SYLLABLE THIEUTH YI RIEULPIEUP
+0xBA8C 0xD2E0 #HANGUL SYLLABLE THIEUTH YI RIEULSIOS
+0xBA8D 0xD2E1 #HANGUL SYLLABLE THIEUTH YI RIEULTHIEUTH
+0xBA8E 0xD2E2 #HANGUL SYLLABLE THIEUTH YI RIEULPHIEUPH
+0xBA8F 0xD2E3 #HANGUL SYLLABLE THIEUTH YI RIEULHIEUH
+0xBA90 0xD2E6 #HANGUL SYLLABLE THIEUTH YI PIEUPSIOS
+0xBA91 0xD2E7 #HANGUL SYLLABLE THIEUTH YI SIOS
+0xBA92 0xD2E8 #HANGUL SYLLABLE THIEUTH YI SSANGSIOS
+0xBA93 0xD2E9 #HANGUL SYLLABLE THIEUTH YI IEUNG
+0xBA94 0xD2EA #HANGUL SYLLABLE THIEUTH YI CIEUC
+0xBA95 0xD2EB #HANGUL SYLLABLE THIEUTH YI CHIEUCH
+0xBA96 0xD2EC #HANGUL SYLLABLE THIEUTH YI KHIEUKH
+0xBA97 0xD2ED #HANGUL SYLLABLE THIEUTH YI THIEUTH
+0xBA98 0xD2EE #HANGUL SYLLABLE THIEUTH YI PHIEUPH
+0xBA99 0xD2EF #HANGUL SYLLABLE THIEUTH YI HIEUH
+0xBA9A 0xD2F2 #HANGUL SYLLABLE THIEUTH I SSANGKIYEOK
+0xBA9B 0xD2F3 #HANGUL SYLLABLE THIEUTH I KIYEOKSIOS
+0xBA9C 0xD2F5 #HANGUL SYLLABLE THIEUTH I NIEUNCIEUC
+0xBA9D 0xD2F6 #HANGUL SYLLABLE THIEUTH I NIEUNHIEUH
+0xBA9E 0xD2F7 #HANGUL SYLLABLE THIEUTH I TIKEUT
+0xBA9F 0xD2F9 #HANGUL SYLLABLE THIEUTH I RIEULKIYEOK
+0xBAA0 0xD2FA #HANGUL SYLLABLE THIEUTH I RIEULMIEUM
+0xBAA1 0xBC99 #HANGUL SYLLABLE PIEUP EO IEUNG
+0xBAA2 0xBC9A #HANGUL SYLLABLE PIEUP EO CIEUC
+0xBAA3 0xBCA0 #HANGUL SYLLABLE PIEUP E
+0xBAA4 0xBCA1 #HANGUL SYLLABLE PIEUP E KIYEOK
+0xBAA5 0xBCA4 #HANGUL SYLLABLE PIEUP E NIEUN
+0xBAA6 0xBCA7 #HANGUL SYLLABLE PIEUP E TIKEUT
+0xBAA7 0xBCA8 #HANGUL SYLLABLE PIEUP E RIEUL
+0xBAA8 0xBCB0 #HANGUL SYLLABLE PIEUP E MIEUM
+0xBAA9 0xBCB1 #HANGUL SYLLABLE PIEUP E PIEUP
+0xBAAA 0xBCB3 #HANGUL SYLLABLE PIEUP E SIOS
+0xBAAB 0xBCB4 #HANGUL SYLLABLE PIEUP E SSANGSIOS
+0xBAAC 0xBCB5 #HANGUL SYLLABLE PIEUP E IEUNG
+0xBAAD 0xBCBC #HANGUL SYLLABLE PIEUP YEO
+0xBAAE 0xBCBD #HANGUL SYLLABLE PIEUP YEO KIYEOK
+0xBAAF 0xBCC0 #HANGUL SYLLABLE PIEUP YEO NIEUN
+0xBAB0 0xBCC4 #HANGUL SYLLABLE PIEUP YEO RIEUL
+0xBAB1 0xBCCD #HANGUL SYLLABLE PIEUP YEO PIEUP
+0xBAB2 0xBCCF #HANGUL SYLLABLE PIEUP YEO SIOS
+0xBAB3 0xBCD0 #HANGUL SYLLABLE PIEUP YEO SSANGSIOS
+0xBAB4 0xBCD1 #HANGUL SYLLABLE PIEUP YEO IEUNG
+0xBAB5 0xBCD5 #HANGUL SYLLABLE PIEUP YEO THIEUTH
+0xBAB6 0xBCD8 #HANGUL SYLLABLE PIEUP YE
+0xBAB7 0xBCDC #HANGUL SYLLABLE PIEUP YE NIEUN
+0xBAB8 0xBCF4 #HANGUL SYLLABLE PIEUP O
+0xBAB9 0xBCF5 #HANGUL SYLLABLE PIEUP O KIYEOK
+0xBABA 0xBCF6 #HANGUL SYLLABLE PIEUP O SSANGKIYEOK
+0xBABB 0xBCF8 #HANGUL SYLLABLE PIEUP O NIEUN
+0xBABC 0xBCFC #HANGUL SYLLABLE PIEUP O RIEUL
+0xBABD 0xBD04 #HANGUL SYLLABLE PIEUP O MIEUM
+0xBABE 0xBD05 #HANGUL SYLLABLE PIEUP O PIEUP
+0xBABF 0xBD07 #HANGUL SYLLABLE PIEUP O SIOS
+0xBAC0 0xBD09 #HANGUL SYLLABLE PIEUP O IEUNG
+0xBAC1 0xBD10 #HANGUL SYLLABLE PIEUP WA
+0xBAC2 0xBD14 #HANGUL SYLLABLE PIEUP WA NIEUN
+0xBAC3 0xBD24 #HANGUL SYLLABLE PIEUP WA SSANGSIOS
+0xBAC4 0xBD2C #HANGUL SYLLABLE PIEUP WAE
+0xBAC5 0xBD40 #HANGUL SYLLABLE PIEUP WAE SSANGSIOS
+0xBAC6 0xBD48 #HANGUL SYLLABLE PIEUP OE
+0xBAC7 0xBD49 #HANGUL SYLLABLE PIEUP OE KIYEOK
+0xBAC8 0xBD4C #HANGUL SYLLABLE PIEUP OE NIEUN
+0xBAC9 0xBD50 #HANGUL SYLLABLE PIEUP OE RIEUL
+0xBACA 0xBD58 #HANGUL SYLLABLE PIEUP OE MIEUM
+0xBACB 0xBD59 #HANGUL SYLLABLE PIEUP OE PIEUP
+0xBACC 0xBD64 #HANGUL SYLLABLE PIEUP YO
+0xBACD 0xBD68 #HANGUL SYLLABLE PIEUP YO NIEUN
+0xBACE 0xBD80 #HANGUL SYLLABLE PIEUP U
+0xBACF 0xBD81 #HANGUL SYLLABLE PIEUP U KIYEOK
+0xBAD0 0xBD84 #HANGUL SYLLABLE PIEUP U NIEUN
+0xBAD1 0xBD87 #HANGUL SYLLABLE PIEUP U TIKEUT
+0xBAD2 0xBD88 #HANGUL SYLLABLE PIEUP U RIEUL
+0xBAD3 0xBD89 #HANGUL SYLLABLE PIEUP U RIEULKIYEOK
+0xBAD4 0xBD8A #HANGUL SYLLABLE PIEUP U RIEULMIEUM
+0xBAD5 0xBD90 #HANGUL SYLLABLE PIEUP U MIEUM
+0xBAD6 0xBD91 #HANGUL SYLLABLE PIEUP U PIEUP
+0xBAD7 0xBD93 #HANGUL SYLLABLE PIEUP U SIOS
+0xBAD8 0xBD95 #HANGUL SYLLABLE PIEUP U IEUNG
+0xBAD9 0xBD99 #HANGUL SYLLABLE PIEUP U THIEUTH
+0xBADA 0xBD9A #HANGUL SYLLABLE PIEUP U PHIEUPH
+0xBADB 0xBD9C #HANGUL SYLLABLE PIEUP WEO
+0xBADC 0xBDA4 #HANGUL SYLLABLE PIEUP WEO RIEUL
+0xBADD 0xBDB0 #HANGUL SYLLABLE PIEUP WEO SSANGSIOS
+0xBADE 0xBDB8 #HANGUL SYLLABLE PIEUP WE
+0xBADF 0xBDD4 #HANGUL SYLLABLE PIEUP WI
+0xBAE0 0xBDD5 #HANGUL SYLLABLE PIEUP WI KIYEOK
+0xBAE1 0xBDD8 #HANGUL SYLLABLE PIEUP WI NIEUN
+0xBAE2 0xBDDC #HANGUL SYLLABLE PIEUP WI RIEUL
+0xBAE3 0xBDE9 #HANGUL SYLLABLE PIEUP WI IEUNG
+0xBAE4 0xBDF0 #HANGUL SYLLABLE PIEUP YU
+0xBAE5 0xBDF4 #HANGUL SYLLABLE PIEUP YU NIEUN
+0xBAE6 0xBDF8 #HANGUL SYLLABLE PIEUP YU RIEUL
+0xBAE7 0xBE00 #HANGUL SYLLABLE PIEUP YU MIEUM
+0xBAE8 0xBE03 #HANGUL SYLLABLE PIEUP YU SIOS
+0xBAE9 0xBE05 #HANGUL SYLLABLE PIEUP YU IEUNG
+0xBAEA 0xBE0C #HANGUL SYLLABLE PIEUP EU
+0xBAEB 0xBE0D #HANGUL SYLLABLE PIEUP EU KIYEOK
+0xBAEC 0xBE10 #HANGUL SYLLABLE PIEUP EU NIEUN
+0xBAED 0xBE14 #HANGUL SYLLABLE PIEUP EU RIEUL
+0xBAEE 0xBE1C #HANGUL SYLLABLE PIEUP EU MIEUM
+0xBAEF 0xBE1D #HANGUL SYLLABLE PIEUP EU PIEUP
+0xBAF0 0xBE1F #HANGUL SYLLABLE PIEUP EU SIOS
+0xBAF1 0xBE44 #HANGUL SYLLABLE PIEUP I
+0xBAF2 0xBE45 #HANGUL SYLLABLE PIEUP I KIYEOK
+0xBAF3 0xBE48 #HANGUL SYLLABLE PIEUP I NIEUN
+0xBAF4 0xBE4C #HANGUL SYLLABLE PIEUP I RIEUL
+0xBAF5 0xBE4E #HANGUL SYLLABLE PIEUP I RIEULMIEUM
+0xBAF6 0xBE54 #HANGUL SYLLABLE PIEUP I MIEUM
+0xBAF7 0xBE55 #HANGUL SYLLABLE PIEUP I PIEUP
+0xBAF8 0xBE57 #HANGUL SYLLABLE PIEUP I SIOS
+0xBAF9 0xBE59 #HANGUL SYLLABLE PIEUP I IEUNG
+0xBAFA 0xBE5A #HANGUL SYLLABLE PIEUP I CIEUC
+0xBAFB 0xBE5B #HANGUL SYLLABLE PIEUP I CHIEUCH
+0xBAFC 0xBE60 #HANGUL SYLLABLE SSANGPIEUP A
+0xBAFD 0xBE61 #HANGUL SYLLABLE SSANGPIEUP A KIYEOK
+0xBAFE 0xBE64 #HANGUL SYLLABLE SSANGPIEUP A NIEUN
+0xBB41 0xD2FB #HANGUL SYLLABLE THIEUTH I RIEULPIEUP
+0xBB42 0xD2FC #HANGUL SYLLABLE THIEUTH I RIEULSIOS
+0xBB43 0xD2FD #HANGUL SYLLABLE THIEUTH I RIEULTHIEUTH
+0xBB44 0xD2FE #HANGUL SYLLABLE THIEUTH I RIEULPHIEUPH
+0xBB45 0xD2FF #HANGUL SYLLABLE THIEUTH I RIEULHIEUH
+0xBB46 0xD302 #HANGUL SYLLABLE THIEUTH I PIEUPSIOS
+0xBB47 0xD304 #HANGUL SYLLABLE THIEUTH I SSANGSIOS
+0xBB48 0xD306 #HANGUL SYLLABLE THIEUTH I CIEUC
+0xBB49 0xD307 #HANGUL SYLLABLE THIEUTH I CHIEUCH
+0xBB4A 0xD308 #HANGUL SYLLABLE THIEUTH I KHIEUKH
+0xBB4B 0xD309 #HANGUL SYLLABLE THIEUTH I THIEUTH
+0xBB4C 0xD30A #HANGUL SYLLABLE THIEUTH I PHIEUPH
+0xBB4D 0xD30B #HANGUL SYLLABLE THIEUTH I HIEUH
+0xBB4E 0xD30F #HANGUL SYLLABLE PHIEUPH A KIYEOKSIOS
+0xBB4F 0xD311 #HANGUL SYLLABLE PHIEUPH A NIEUNCIEUC
+0xBB50 0xD312 #HANGUL SYLLABLE PHIEUPH A NIEUNHIEUH
+0xBB51 0xD313 #HANGUL SYLLABLE PHIEUPH A TIKEUT
+0xBB52 0xD315 #HANGUL SYLLABLE PHIEUPH A RIEULKIYEOK
+0xBB53 0xD317 #HANGUL SYLLABLE PHIEUPH A RIEULPIEUP
+0xBB54 0xD318 #HANGUL SYLLABLE PHIEUPH A RIEULSIOS
+0xBB55 0xD319 #HANGUL SYLLABLE PHIEUPH A RIEULTHIEUTH
+0xBB56 0xD31A #HANGUL SYLLABLE PHIEUPH A RIEULPHIEUPH
+0xBB57 0xD31B #HANGUL SYLLABLE PHIEUPH A RIEULHIEUH
+0xBB58 0xD31E #HANGUL SYLLABLE PHIEUPH A PIEUPSIOS
+0xBB59 0xD322 #HANGUL SYLLABLE PHIEUPH A CIEUC
+0xBB5A 0xD323 #HANGUL SYLLABLE PHIEUPH A CHIEUCH
+0xBB61 0xD324 #HANGUL SYLLABLE PHIEUPH A KHIEUKH
+0xBB62 0xD326 #HANGUL SYLLABLE PHIEUPH A PHIEUPH
+0xBB63 0xD327 #HANGUL SYLLABLE PHIEUPH A HIEUH
+0xBB64 0xD32A #HANGUL SYLLABLE PHIEUPH AE SSANGKIYEOK
+0xBB65 0xD32B #HANGUL SYLLABLE PHIEUPH AE KIYEOKSIOS
+0xBB66 0xD32D #HANGUL SYLLABLE PHIEUPH AE NIEUNCIEUC
+0xBB67 0xD32E #HANGUL SYLLABLE PHIEUPH AE NIEUNHIEUH
+0xBB68 0xD32F #HANGUL SYLLABLE PHIEUPH AE TIKEUT
+0xBB69 0xD331 #HANGUL SYLLABLE PHIEUPH AE RIEULKIYEOK
+0xBB6A 0xD332 #HANGUL SYLLABLE PHIEUPH AE RIEULMIEUM
+0xBB6B 0xD333 #HANGUL SYLLABLE PHIEUPH AE RIEULPIEUP
+0xBB6C 0xD334 #HANGUL SYLLABLE PHIEUPH AE RIEULSIOS
+0xBB6D 0xD335 #HANGUL SYLLABLE PHIEUPH AE RIEULTHIEUTH
+0xBB6E 0xD336 #HANGUL SYLLABLE PHIEUPH AE RIEULPHIEUPH
+0xBB6F 0xD337 #HANGUL SYLLABLE PHIEUPH AE RIEULHIEUH
+0xBB70 0xD33A #HANGUL SYLLABLE PHIEUPH AE PIEUPSIOS
+0xBB71 0xD33E #HANGUL SYLLABLE PHIEUPH AE CIEUC
+0xBB72 0xD33F #HANGUL SYLLABLE PHIEUPH AE CHIEUCH
+0xBB73 0xD340 #HANGUL SYLLABLE PHIEUPH AE KHIEUKH
+0xBB74 0xD341 #HANGUL SYLLABLE PHIEUPH AE THIEUTH
+0xBB75 0xD342 #HANGUL SYLLABLE PHIEUPH AE PHIEUPH
+0xBB76 0xD343 #HANGUL SYLLABLE PHIEUPH AE HIEUH
+0xBB77 0xD346 #HANGUL SYLLABLE PHIEUPH YA SSANGKIYEOK
+0xBB78 0xD347 #HANGUL SYLLABLE PHIEUPH YA KIYEOKSIOS
+0xBB79 0xD348 #HANGUL SYLLABLE PHIEUPH YA NIEUN
+0xBB7A 0xD349 #HANGUL SYLLABLE PHIEUPH YA NIEUNCIEUC
+0xBB81 0xD34A #HANGUL SYLLABLE PHIEUPH YA NIEUNHIEUH
+0xBB82 0xD34B #HANGUL SYLLABLE PHIEUPH YA TIKEUT
+0xBB83 0xD34C #HANGUL SYLLABLE PHIEUPH YA RIEUL
+0xBB84 0xD34D #HANGUL SYLLABLE PHIEUPH YA RIEULKIYEOK
+0xBB85 0xD34E #HANGUL SYLLABLE PHIEUPH YA RIEULMIEUM
+0xBB86 0xD34F #HANGUL SYLLABLE PHIEUPH YA RIEULPIEUP
+0xBB87 0xD350 #HANGUL SYLLABLE PHIEUPH YA RIEULSIOS
+0xBB88 0xD351 #HANGUL SYLLABLE PHIEUPH YA RIEULTHIEUTH
+0xBB89 0xD352 #HANGUL SYLLABLE PHIEUPH YA RIEULPHIEUPH
+0xBB8A 0xD353 #HANGUL SYLLABLE PHIEUPH YA RIEULHIEUH
+0xBB8B 0xD354 #HANGUL SYLLABLE PHIEUPH YA MIEUM
+0xBB8C 0xD355 #HANGUL SYLLABLE PHIEUPH YA PIEUP
+0xBB8D 0xD356 #HANGUL SYLLABLE PHIEUPH YA PIEUPSIOS
+0xBB8E 0xD357 #HANGUL SYLLABLE PHIEUPH YA SIOS
+0xBB8F 0xD358 #HANGUL SYLLABLE PHIEUPH YA SSANGSIOS
+0xBB90 0xD359 #HANGUL SYLLABLE PHIEUPH YA IEUNG
+0xBB91 0xD35A #HANGUL SYLLABLE PHIEUPH YA CIEUC
+0xBB92 0xD35B #HANGUL SYLLABLE PHIEUPH YA CHIEUCH
+0xBB93 0xD35C #HANGUL SYLLABLE PHIEUPH YA KHIEUKH
+0xBB94 0xD35D #HANGUL SYLLABLE PHIEUPH YA THIEUTH
+0xBB95 0xD35E #HANGUL SYLLABLE PHIEUPH YA PHIEUPH
+0xBB96 0xD35F #HANGUL SYLLABLE PHIEUPH YA HIEUH
+0xBB97 0xD360 #HANGUL SYLLABLE PHIEUPH YAE
+0xBB98 0xD361 #HANGUL SYLLABLE PHIEUPH YAE KIYEOK
+0xBB99 0xD362 #HANGUL SYLLABLE PHIEUPH YAE SSANGKIYEOK
+0xBB9A 0xD363 #HANGUL SYLLABLE PHIEUPH YAE KIYEOKSIOS
+0xBB9B 0xD364 #HANGUL SYLLABLE PHIEUPH YAE NIEUN
+0xBB9C 0xD365 #HANGUL SYLLABLE PHIEUPH YAE NIEUNCIEUC
+0xBB9D 0xD366 #HANGUL SYLLABLE PHIEUPH YAE NIEUNHIEUH
+0xBB9E 0xD367 #HANGUL SYLLABLE PHIEUPH YAE TIKEUT
+0xBB9F 0xD368 #HANGUL SYLLABLE PHIEUPH YAE RIEUL
+0xBBA0 0xD369 #HANGUL SYLLABLE PHIEUPH YAE RIEULKIYEOK
+0xBBA1 0xBE68 #HANGUL SYLLABLE SSANGPIEUP A RIEUL
+0xBBA2 0xBE6A #HANGUL SYLLABLE SSANGPIEUP A RIEULMIEUM
+0xBBA3 0xBE70 #HANGUL SYLLABLE SSANGPIEUP A MIEUM
+0xBBA4 0xBE71 #HANGUL SYLLABLE SSANGPIEUP A PIEUP
+0xBBA5 0xBE73 #HANGUL SYLLABLE SSANGPIEUP A SIOS
+0xBBA6 0xBE74 #HANGUL SYLLABLE SSANGPIEUP A SSANGSIOS
+0xBBA7 0xBE75 #HANGUL SYLLABLE SSANGPIEUP A IEUNG
+0xBBA8 0xBE7B #HANGUL SYLLABLE SSANGPIEUP A HIEUH
+0xBBA9 0xBE7C #HANGUL SYLLABLE SSANGPIEUP AE
+0xBBAA 0xBE7D #HANGUL SYLLABLE SSANGPIEUP AE KIYEOK
+0xBBAB 0xBE80 #HANGUL SYLLABLE SSANGPIEUP AE NIEUN
+0xBBAC 0xBE84 #HANGUL SYLLABLE SSANGPIEUP AE RIEUL
+0xBBAD 0xBE8C #HANGUL SYLLABLE SSANGPIEUP AE MIEUM
+0xBBAE 0xBE8D #HANGUL SYLLABLE SSANGPIEUP AE PIEUP
+0xBBAF 0xBE8F #HANGUL SYLLABLE SSANGPIEUP AE SIOS
+0xBBB0 0xBE90 #HANGUL SYLLABLE SSANGPIEUP AE SSANGSIOS
+0xBBB1 0xBE91 #HANGUL SYLLABLE SSANGPIEUP AE IEUNG
+0xBBB2 0xBE98 #HANGUL SYLLABLE SSANGPIEUP YA
+0xBBB3 0xBE99 #HANGUL SYLLABLE SSANGPIEUP YA KIYEOK
+0xBBB4 0xBEA8 #HANGUL SYLLABLE SSANGPIEUP YA MIEUM
+0xBBB5 0xBED0 #HANGUL SYLLABLE SSANGPIEUP EO
+0xBBB6 0xBED1 #HANGUL SYLLABLE SSANGPIEUP EO KIYEOK
+0xBBB7 0xBED4 #HANGUL SYLLABLE SSANGPIEUP EO NIEUN
+0xBBB8 0xBED7 #HANGUL SYLLABLE SSANGPIEUP EO TIKEUT
+0xBBB9 0xBED8 #HANGUL SYLLABLE SSANGPIEUP EO RIEUL
+0xBBBA 0xBEE0 #HANGUL SYLLABLE SSANGPIEUP EO MIEUM
+0xBBBB 0xBEE3 #HANGUL SYLLABLE SSANGPIEUP EO SIOS
+0xBBBC 0xBEE4 #HANGUL SYLLABLE SSANGPIEUP EO SSANGSIOS
+0xBBBD 0xBEE5 #HANGUL SYLLABLE SSANGPIEUP EO IEUNG
+0xBBBE 0xBEEC #HANGUL SYLLABLE SSANGPIEUP E
+0xBBBF 0xBF01 #HANGUL SYLLABLE SSANGPIEUP E IEUNG
+0xBBC0 0xBF08 #HANGUL SYLLABLE SSANGPIEUP YEO
+0xBBC1 0xBF09 #HANGUL SYLLABLE SSANGPIEUP YEO KIYEOK
+0xBBC2 0xBF18 #HANGUL SYLLABLE SSANGPIEUP YEO MIEUM
+0xBBC3 0xBF19 #HANGUL SYLLABLE SSANGPIEUP YEO PIEUP
+0xBBC4 0xBF1B #HANGUL SYLLABLE SSANGPIEUP YEO SIOS
+0xBBC5 0xBF1C #HANGUL SYLLABLE SSANGPIEUP YEO SSANGSIOS
+0xBBC6 0xBF1D #HANGUL SYLLABLE SSANGPIEUP YEO IEUNG
+0xBBC7 0xBF40 #HANGUL SYLLABLE SSANGPIEUP O
+0xBBC8 0xBF41 #HANGUL SYLLABLE SSANGPIEUP O KIYEOK
+0xBBC9 0xBF44 #HANGUL SYLLABLE SSANGPIEUP O NIEUN
+0xBBCA 0xBF48 #HANGUL SYLLABLE SSANGPIEUP O RIEUL
+0xBBCB 0xBF50 #HANGUL SYLLABLE SSANGPIEUP O MIEUM
+0xBBCC 0xBF51 #HANGUL SYLLABLE SSANGPIEUP O PIEUP
+0xBBCD 0xBF55 #HANGUL SYLLABLE SSANGPIEUP O IEUNG
+0xBBCE 0xBF94 #HANGUL SYLLABLE SSANGPIEUP OE
+0xBBCF 0xBFB0 #HANGUL SYLLABLE SSANGPIEUP YO
+0xBBD0 0xBFC5 #HANGUL SYLLABLE SSANGPIEUP YO IEUNG
+0xBBD1 0xBFCC #HANGUL SYLLABLE SSANGPIEUP U
+0xBBD2 0xBFCD #HANGUL SYLLABLE SSANGPIEUP U KIYEOK
+0xBBD3 0xBFD0 #HANGUL SYLLABLE SSANGPIEUP U NIEUN
+0xBBD4 0xBFD4 #HANGUL SYLLABLE SSANGPIEUP U RIEUL
+0xBBD5 0xBFDC #HANGUL SYLLABLE SSANGPIEUP U MIEUM
+0xBBD6 0xBFDF #HANGUL SYLLABLE SSANGPIEUP U SIOS
+0xBBD7 0xBFE1 #HANGUL SYLLABLE SSANGPIEUP U IEUNG
+0xBBD8 0xC03C #HANGUL SYLLABLE SSANGPIEUP YU
+0xBBD9 0xC051 #HANGUL SYLLABLE SSANGPIEUP YU IEUNG
+0xBBDA 0xC058 #HANGUL SYLLABLE SSANGPIEUP EU
+0xBBDB 0xC05C #HANGUL SYLLABLE SSANGPIEUP EU NIEUN
+0xBBDC 0xC060 #HANGUL SYLLABLE SSANGPIEUP EU RIEUL
+0xBBDD 0xC068 #HANGUL SYLLABLE SSANGPIEUP EU MIEUM
+0xBBDE 0xC069 #HANGUL SYLLABLE SSANGPIEUP EU PIEUP
+0xBBDF 0xC090 #HANGUL SYLLABLE SSANGPIEUP I
+0xBBE0 0xC091 #HANGUL SYLLABLE SSANGPIEUP I KIYEOK
+0xBBE1 0xC094 #HANGUL SYLLABLE SSANGPIEUP I NIEUN
+0xBBE2 0xC098 #HANGUL SYLLABLE SSANGPIEUP I RIEUL
+0xBBE3 0xC0A0 #HANGUL SYLLABLE SSANGPIEUP I MIEUM
+0xBBE4 0xC0A1 #HANGUL SYLLABLE SSANGPIEUP I PIEUP
+0xBBE5 0xC0A3 #HANGUL SYLLABLE SSANGPIEUP I SIOS
+0xBBE6 0xC0A5 #HANGUL SYLLABLE SSANGPIEUP I IEUNG
+0xBBE7 0xC0AC #HANGUL SYLLABLE SIOS A
+0xBBE8 0xC0AD #HANGUL SYLLABLE SIOS A KIYEOK
+0xBBE9 0xC0AF #HANGUL SYLLABLE SIOS A KIYEOKSIOS
+0xBBEA 0xC0B0 #HANGUL SYLLABLE SIOS A NIEUN
+0xBBEB 0xC0B3 #HANGUL SYLLABLE SIOS A TIKEUT
+0xBBEC 0xC0B4 #HANGUL SYLLABLE SIOS A RIEUL
+0xBBED 0xC0B5 #HANGUL SYLLABLE SIOS A RIEULKIYEOK
+0xBBEE 0xC0B6 #HANGUL SYLLABLE SIOS A RIEULMIEUM
+0xBBEF 0xC0BC #HANGUL SYLLABLE SIOS A MIEUM
+0xBBF0 0xC0BD #HANGUL SYLLABLE SIOS A PIEUP
+0xBBF1 0xC0BF #HANGUL SYLLABLE SIOS A SIOS
+0xBBF2 0xC0C0 #HANGUL SYLLABLE SIOS A SSANGSIOS
+0xBBF3 0xC0C1 #HANGUL SYLLABLE SIOS A IEUNG
+0xBBF4 0xC0C5 #HANGUL SYLLABLE SIOS A THIEUTH
+0xBBF5 0xC0C8 #HANGUL SYLLABLE SIOS AE
+0xBBF6 0xC0C9 #HANGUL SYLLABLE SIOS AE KIYEOK
+0xBBF7 0xC0CC #HANGUL SYLLABLE SIOS AE NIEUN
+0xBBF8 0xC0D0 #HANGUL SYLLABLE SIOS AE RIEUL
+0xBBF9 0xC0D8 #HANGUL SYLLABLE SIOS AE MIEUM
+0xBBFA 0xC0D9 #HANGUL SYLLABLE SIOS AE PIEUP
+0xBBFB 0xC0DB #HANGUL SYLLABLE SIOS AE SIOS
+0xBBFC 0xC0DC #HANGUL SYLLABLE SIOS AE SSANGSIOS
+0xBBFD 0xC0DD #HANGUL SYLLABLE SIOS AE IEUNG
+0xBBFE 0xC0E4 #HANGUL SYLLABLE SIOS YA
+0xBC41 0xD36A #HANGUL SYLLABLE PHIEUPH YAE RIEULMIEUM
+0xBC42 0xD36B #HANGUL SYLLABLE PHIEUPH YAE RIEULPIEUP
+0xBC43 0xD36C #HANGUL SYLLABLE PHIEUPH YAE RIEULSIOS
+0xBC44 0xD36D #HANGUL SYLLABLE PHIEUPH YAE RIEULTHIEUTH
+0xBC45 0xD36E #HANGUL SYLLABLE PHIEUPH YAE RIEULPHIEUPH
+0xBC46 0xD36F #HANGUL SYLLABLE PHIEUPH YAE RIEULHIEUH
+0xBC47 0xD370 #HANGUL SYLLABLE PHIEUPH YAE MIEUM
+0xBC48 0xD371 #HANGUL SYLLABLE PHIEUPH YAE PIEUP
+0xBC49 0xD372 #HANGUL SYLLABLE PHIEUPH YAE PIEUPSIOS
+0xBC4A 0xD373 #HANGUL SYLLABLE PHIEUPH YAE SIOS
+0xBC4B 0xD374 #HANGUL SYLLABLE PHIEUPH YAE SSANGSIOS
+0xBC4C 0xD375 #HANGUL SYLLABLE PHIEUPH YAE IEUNG
+0xBC4D 0xD376 #HANGUL SYLLABLE PHIEUPH YAE CIEUC
+0xBC4E 0xD377 #HANGUL SYLLABLE PHIEUPH YAE CHIEUCH
+0xBC4F 0xD378 #HANGUL SYLLABLE PHIEUPH YAE KHIEUKH
+0xBC50 0xD379 #HANGUL SYLLABLE PHIEUPH YAE THIEUTH
+0xBC51 0xD37A #HANGUL SYLLABLE PHIEUPH YAE PHIEUPH
+0xBC52 0xD37B #HANGUL SYLLABLE PHIEUPH YAE HIEUH
+0xBC53 0xD37E #HANGUL SYLLABLE PHIEUPH EO SSANGKIYEOK
+0xBC54 0xD37F #HANGUL SYLLABLE PHIEUPH EO KIYEOKSIOS
+0xBC55 0xD381 #HANGUL SYLLABLE PHIEUPH EO NIEUNCIEUC
+0xBC56 0xD382 #HANGUL SYLLABLE PHIEUPH EO NIEUNHIEUH
+0xBC57 0xD383 #HANGUL SYLLABLE PHIEUPH EO TIKEUT
+0xBC58 0xD385 #HANGUL SYLLABLE PHIEUPH EO RIEULKIYEOK
+0xBC59 0xD386 #HANGUL SYLLABLE PHIEUPH EO RIEULMIEUM
+0xBC5A 0xD387 #HANGUL SYLLABLE PHIEUPH EO RIEULPIEUP
+0xBC61 0xD388 #HANGUL SYLLABLE PHIEUPH EO RIEULSIOS
+0xBC62 0xD389 #HANGUL SYLLABLE PHIEUPH EO RIEULTHIEUTH
+0xBC63 0xD38A #HANGUL SYLLABLE PHIEUPH EO RIEULPHIEUPH
+0xBC64 0xD38B #HANGUL SYLLABLE PHIEUPH EO RIEULHIEUH
+0xBC65 0xD38E #HANGUL SYLLABLE PHIEUPH EO PIEUPSIOS
+0xBC66 0xD392 #HANGUL SYLLABLE PHIEUPH EO CIEUC
+0xBC67 0xD393 #HANGUL SYLLABLE PHIEUPH EO CHIEUCH
+0xBC68 0xD394 #HANGUL SYLLABLE PHIEUPH EO KHIEUKH
+0xBC69 0xD395 #HANGUL SYLLABLE PHIEUPH EO THIEUTH
+0xBC6A 0xD396 #HANGUL SYLLABLE PHIEUPH EO PHIEUPH
+0xBC6B 0xD397 #HANGUL SYLLABLE PHIEUPH EO HIEUH
+0xBC6C 0xD39A #HANGUL SYLLABLE PHIEUPH E SSANGKIYEOK
+0xBC6D 0xD39B #HANGUL SYLLABLE PHIEUPH E KIYEOKSIOS
+0xBC6E 0xD39D #HANGUL SYLLABLE PHIEUPH E NIEUNCIEUC
+0xBC6F 0xD39E #HANGUL SYLLABLE PHIEUPH E NIEUNHIEUH
+0xBC70 0xD39F #HANGUL SYLLABLE PHIEUPH E TIKEUT
+0xBC71 0xD3A1 #HANGUL SYLLABLE PHIEUPH E RIEULKIYEOK
+0xBC72 0xD3A2 #HANGUL SYLLABLE PHIEUPH E RIEULMIEUM
+0xBC73 0xD3A3 #HANGUL SYLLABLE PHIEUPH E RIEULPIEUP
+0xBC74 0xD3A4 #HANGUL SYLLABLE PHIEUPH E RIEULSIOS
+0xBC75 0xD3A5 #HANGUL SYLLABLE PHIEUPH E RIEULTHIEUTH
+0xBC76 0xD3A6 #HANGUL SYLLABLE PHIEUPH E RIEULPHIEUPH
+0xBC77 0xD3A7 #HANGUL SYLLABLE PHIEUPH E RIEULHIEUH
+0xBC78 0xD3AA #HANGUL SYLLABLE PHIEUPH E PIEUPSIOS
+0xBC79 0xD3AC #HANGUL SYLLABLE PHIEUPH E SSANGSIOS
+0xBC7A 0xD3AE #HANGUL SYLLABLE PHIEUPH E CIEUC
+0xBC81 0xD3AF #HANGUL SYLLABLE PHIEUPH E CHIEUCH
+0xBC82 0xD3B0 #HANGUL SYLLABLE PHIEUPH E KHIEUKH
+0xBC83 0xD3B1 #HANGUL SYLLABLE PHIEUPH E THIEUTH
+0xBC84 0xD3B2 #HANGUL SYLLABLE PHIEUPH E PHIEUPH
+0xBC85 0xD3B3 #HANGUL SYLLABLE PHIEUPH E HIEUH
+0xBC86 0xD3B5 #HANGUL SYLLABLE PHIEUPH YEO KIYEOK
+0xBC87 0xD3B6 #HANGUL SYLLABLE PHIEUPH YEO SSANGKIYEOK
+0xBC88 0xD3B7 #HANGUL SYLLABLE PHIEUPH YEO KIYEOKSIOS
+0xBC89 0xD3B9 #HANGUL SYLLABLE PHIEUPH YEO NIEUNCIEUC
+0xBC8A 0xD3BA #HANGUL SYLLABLE PHIEUPH YEO NIEUNHIEUH
+0xBC8B 0xD3BB #HANGUL SYLLABLE PHIEUPH YEO TIKEUT
+0xBC8C 0xD3BD #HANGUL SYLLABLE PHIEUPH YEO RIEULKIYEOK
+0xBC8D 0xD3BE #HANGUL SYLLABLE PHIEUPH YEO RIEULMIEUM
+0xBC8E 0xD3BF #HANGUL SYLLABLE PHIEUPH YEO RIEULPIEUP
+0xBC8F 0xD3C0 #HANGUL SYLLABLE PHIEUPH YEO RIEULSIOS
+0xBC90 0xD3C1 #HANGUL SYLLABLE PHIEUPH YEO RIEULTHIEUTH
+0xBC91 0xD3C2 #HANGUL SYLLABLE PHIEUPH YEO RIEULPHIEUPH
+0xBC92 0xD3C3 #HANGUL SYLLABLE PHIEUPH YEO RIEULHIEUH
+0xBC93 0xD3C6 #HANGUL SYLLABLE PHIEUPH YEO PIEUPSIOS
+0xBC94 0xD3C7 #HANGUL SYLLABLE PHIEUPH YEO SIOS
+0xBC95 0xD3CA #HANGUL SYLLABLE PHIEUPH YEO CIEUC
+0xBC96 0xD3CB #HANGUL SYLLABLE PHIEUPH YEO CHIEUCH
+0xBC97 0xD3CC #HANGUL SYLLABLE PHIEUPH YEO KHIEUKH
+0xBC98 0xD3CD #HANGUL SYLLABLE PHIEUPH YEO THIEUTH
+0xBC99 0xD3CE #HANGUL SYLLABLE PHIEUPH YEO PHIEUPH
+0xBC9A 0xD3CF #HANGUL SYLLABLE PHIEUPH YEO HIEUH
+0xBC9B 0xD3D1 #HANGUL SYLLABLE PHIEUPH YE KIYEOK
+0xBC9C 0xD3D2 #HANGUL SYLLABLE PHIEUPH YE SSANGKIYEOK
+0xBC9D 0xD3D3 #HANGUL SYLLABLE PHIEUPH YE KIYEOKSIOS
+0xBC9E 0xD3D4 #HANGUL SYLLABLE PHIEUPH YE NIEUN
+0xBC9F 0xD3D5 #HANGUL SYLLABLE PHIEUPH YE NIEUNCIEUC
+0xBCA0 0xD3D6 #HANGUL SYLLABLE PHIEUPH YE NIEUNHIEUH
+0xBCA1 0xC0E5 #HANGUL SYLLABLE SIOS YA KIYEOK
+0xBCA2 0xC0E8 #HANGUL SYLLABLE SIOS YA NIEUN
+0xBCA3 0xC0EC #HANGUL SYLLABLE SIOS YA RIEUL
+0xBCA4 0xC0F4 #HANGUL SYLLABLE SIOS YA MIEUM
+0xBCA5 0xC0F5 #HANGUL SYLLABLE SIOS YA PIEUP
+0xBCA6 0xC0F7 #HANGUL SYLLABLE SIOS YA SIOS
+0xBCA7 0xC0F9 #HANGUL SYLLABLE SIOS YA IEUNG
+0xBCA8 0xC100 #HANGUL SYLLABLE SIOS YAE
+0xBCA9 0xC104 #HANGUL SYLLABLE SIOS YAE NIEUN
+0xBCAA 0xC108 #HANGUL SYLLABLE SIOS YAE RIEUL
+0xBCAB 0xC110 #HANGUL SYLLABLE SIOS YAE MIEUM
+0xBCAC 0xC115 #HANGUL SYLLABLE SIOS YAE IEUNG
+0xBCAD 0xC11C #HANGUL SYLLABLE SIOS EO
+0xBCAE 0xC11D #HANGUL SYLLABLE SIOS EO KIYEOK
+0xBCAF 0xC11E #HANGUL SYLLABLE SIOS EO SSANGKIYEOK
+0xBCB0 0xC11F #HANGUL SYLLABLE SIOS EO KIYEOKSIOS
+0xBCB1 0xC120 #HANGUL SYLLABLE SIOS EO NIEUN
+0xBCB2 0xC123 #HANGUL SYLLABLE SIOS EO TIKEUT
+0xBCB3 0xC124 #HANGUL SYLLABLE SIOS EO RIEUL
+0xBCB4 0xC126 #HANGUL SYLLABLE SIOS EO RIEULMIEUM
+0xBCB5 0xC127 #HANGUL SYLLABLE SIOS EO RIEULPIEUP
+0xBCB6 0xC12C #HANGUL SYLLABLE SIOS EO MIEUM
+0xBCB7 0xC12D #HANGUL SYLLABLE SIOS EO PIEUP
+0xBCB8 0xC12F #HANGUL SYLLABLE SIOS EO SIOS
+0xBCB9 0xC130 #HANGUL SYLLABLE SIOS EO SSANGSIOS
+0xBCBA 0xC131 #HANGUL SYLLABLE SIOS EO IEUNG
+0xBCBB 0xC136 #HANGUL SYLLABLE SIOS EO PHIEUPH
+0xBCBC 0xC138 #HANGUL SYLLABLE SIOS E
+0xBCBD 0xC139 #HANGUL SYLLABLE SIOS E KIYEOK
+0xBCBE 0xC13C #HANGUL SYLLABLE SIOS E NIEUN
+0xBCBF 0xC140 #HANGUL SYLLABLE SIOS E RIEUL
+0xBCC0 0xC148 #HANGUL SYLLABLE SIOS E MIEUM
+0xBCC1 0xC149 #HANGUL SYLLABLE SIOS E PIEUP
+0xBCC2 0xC14B #HANGUL SYLLABLE SIOS E SIOS
+0xBCC3 0xC14C #HANGUL SYLLABLE SIOS E SSANGSIOS
+0xBCC4 0xC14D #HANGUL SYLLABLE SIOS E IEUNG
+0xBCC5 0xC154 #HANGUL SYLLABLE SIOS YEO
+0xBCC6 0xC155 #HANGUL SYLLABLE SIOS YEO KIYEOK
+0xBCC7 0xC158 #HANGUL SYLLABLE SIOS YEO NIEUN
+0xBCC8 0xC15C #HANGUL SYLLABLE SIOS YEO RIEUL
+0xBCC9 0xC164 #HANGUL SYLLABLE SIOS YEO MIEUM
+0xBCCA 0xC165 #HANGUL SYLLABLE SIOS YEO PIEUP
+0xBCCB 0xC167 #HANGUL SYLLABLE SIOS YEO SIOS
+0xBCCC 0xC168 #HANGUL SYLLABLE SIOS YEO SSANGSIOS
+0xBCCD 0xC169 #HANGUL SYLLABLE SIOS YEO IEUNG
+0xBCCE 0xC170 #HANGUL SYLLABLE SIOS YE
+0xBCCF 0xC174 #HANGUL SYLLABLE SIOS YE NIEUN
+0xBCD0 0xC178 #HANGUL SYLLABLE SIOS YE RIEUL
+0xBCD1 0xC185 #HANGUL SYLLABLE SIOS YE IEUNG
+0xBCD2 0xC18C #HANGUL SYLLABLE SIOS O
+0xBCD3 0xC18D #HANGUL SYLLABLE SIOS O KIYEOK
+0xBCD4 0xC18E #HANGUL SYLLABLE SIOS O SSANGKIYEOK
+0xBCD5 0xC190 #HANGUL SYLLABLE SIOS O NIEUN
+0xBCD6 0xC194 #HANGUL SYLLABLE SIOS O RIEUL
+0xBCD7 0xC196 #HANGUL SYLLABLE SIOS O RIEULMIEUM
+0xBCD8 0xC19C #HANGUL SYLLABLE SIOS O MIEUM
+0xBCD9 0xC19D #HANGUL SYLLABLE SIOS O PIEUP
+0xBCDA 0xC19F #HANGUL SYLLABLE SIOS O SIOS
+0xBCDB 0xC1A1 #HANGUL SYLLABLE SIOS O IEUNG
+0xBCDC 0xC1A5 #HANGUL SYLLABLE SIOS O THIEUTH
+0xBCDD 0xC1A8 #HANGUL SYLLABLE SIOS WA
+0xBCDE 0xC1A9 #HANGUL SYLLABLE SIOS WA KIYEOK
+0xBCDF 0xC1AC #HANGUL SYLLABLE SIOS WA NIEUN
+0xBCE0 0xC1B0 #HANGUL SYLLABLE SIOS WA RIEUL
+0xBCE1 0xC1BD #HANGUL SYLLABLE SIOS WA IEUNG
+0xBCE2 0xC1C4 #HANGUL SYLLABLE SIOS WAE
+0xBCE3 0xC1C8 #HANGUL SYLLABLE SIOS WAE NIEUN
+0xBCE4 0xC1CC #HANGUL SYLLABLE SIOS WAE RIEUL
+0xBCE5 0xC1D4 #HANGUL SYLLABLE SIOS WAE MIEUM
+0xBCE6 0xC1D7 #HANGUL SYLLABLE SIOS WAE SIOS
+0xBCE7 0xC1D8 #HANGUL SYLLABLE SIOS WAE SSANGSIOS
+0xBCE8 0xC1E0 #HANGUL SYLLABLE SIOS OE
+0xBCE9 0xC1E4 #HANGUL SYLLABLE SIOS OE NIEUN
+0xBCEA 0xC1E8 #HANGUL SYLLABLE SIOS OE RIEUL
+0xBCEB 0xC1F0 #HANGUL SYLLABLE SIOS OE MIEUM
+0xBCEC 0xC1F1 #HANGUL SYLLABLE SIOS OE PIEUP
+0xBCED 0xC1F3 #HANGUL SYLLABLE SIOS OE SIOS
+0xBCEE 0xC1FC #HANGUL SYLLABLE SIOS YO
+0xBCEF 0xC1FD #HANGUL SYLLABLE SIOS YO KIYEOK
+0xBCF0 0xC200 #HANGUL SYLLABLE SIOS YO NIEUN
+0xBCF1 0xC204 #HANGUL SYLLABLE SIOS YO RIEUL
+0xBCF2 0xC20C #HANGUL SYLLABLE SIOS YO MIEUM
+0xBCF3 0xC20D #HANGUL SYLLABLE SIOS YO PIEUP
+0xBCF4 0xC20F #HANGUL SYLLABLE SIOS YO SIOS
+0xBCF5 0xC211 #HANGUL SYLLABLE SIOS YO IEUNG
+0xBCF6 0xC218 #HANGUL SYLLABLE SIOS U
+0xBCF7 0xC219 #HANGUL SYLLABLE SIOS U KIYEOK
+0xBCF8 0xC21C #HANGUL SYLLABLE SIOS U NIEUN
+0xBCF9 0xC21F #HANGUL SYLLABLE SIOS U TIKEUT
+0xBCFA 0xC220 #HANGUL SYLLABLE SIOS U RIEUL
+0xBCFB 0xC228 #HANGUL SYLLABLE SIOS U MIEUM
+0xBCFC 0xC229 #HANGUL SYLLABLE SIOS U PIEUP
+0xBCFD 0xC22B #HANGUL SYLLABLE SIOS U SIOS
+0xBCFE 0xC22D #HANGUL SYLLABLE SIOS U IEUNG
+0xBD41 0xD3D7 #HANGUL SYLLABLE PHIEUPH YE TIKEUT
+0xBD42 0xD3D9 #HANGUL SYLLABLE PHIEUPH YE RIEULKIYEOK
+0xBD43 0xD3DA #HANGUL SYLLABLE PHIEUPH YE RIEULMIEUM
+0xBD44 0xD3DB #HANGUL SYLLABLE PHIEUPH YE RIEULPIEUP
+0xBD45 0xD3DC #HANGUL SYLLABLE PHIEUPH YE RIEULSIOS
+0xBD46 0xD3DD #HANGUL SYLLABLE PHIEUPH YE RIEULTHIEUTH
+0xBD47 0xD3DE #HANGUL SYLLABLE PHIEUPH YE RIEULPHIEUPH
+0xBD48 0xD3DF #HANGUL SYLLABLE PHIEUPH YE RIEULHIEUH
+0xBD49 0xD3E0 #HANGUL SYLLABLE PHIEUPH YE MIEUM
+0xBD4A 0xD3E2 #HANGUL SYLLABLE PHIEUPH YE PIEUPSIOS
+0xBD4B 0xD3E4 #HANGUL SYLLABLE PHIEUPH YE SSANGSIOS
+0xBD4C 0xD3E5 #HANGUL SYLLABLE PHIEUPH YE IEUNG
+0xBD4D 0xD3E6 #HANGUL SYLLABLE PHIEUPH YE CIEUC
+0xBD4E 0xD3E7 #HANGUL SYLLABLE PHIEUPH YE CHIEUCH
+0xBD4F 0xD3E8 #HANGUL SYLLABLE PHIEUPH YE KHIEUKH
+0xBD50 0xD3E9 #HANGUL SYLLABLE PHIEUPH YE THIEUTH
+0xBD51 0xD3EA #HANGUL SYLLABLE PHIEUPH YE PHIEUPH
+0xBD52 0xD3EB #HANGUL SYLLABLE PHIEUPH YE HIEUH
+0xBD53 0xD3EE #HANGUL SYLLABLE PHIEUPH O SSANGKIYEOK
+0xBD54 0xD3EF #HANGUL SYLLABLE PHIEUPH O KIYEOKSIOS
+0xBD55 0xD3F1 #HANGUL SYLLABLE PHIEUPH O NIEUNCIEUC
+0xBD56 0xD3F2 #HANGUL SYLLABLE PHIEUPH O NIEUNHIEUH
+0xBD57 0xD3F3 #HANGUL SYLLABLE PHIEUPH O TIKEUT
+0xBD58 0xD3F5 #HANGUL SYLLABLE PHIEUPH O RIEULKIYEOK
+0xBD59 0xD3F6 #HANGUL SYLLABLE PHIEUPH O RIEULMIEUM
+0xBD5A 0xD3F7 #HANGUL SYLLABLE PHIEUPH O RIEULPIEUP
+0xBD61 0xD3F8 #HANGUL SYLLABLE PHIEUPH O RIEULSIOS
+0xBD62 0xD3F9 #HANGUL SYLLABLE PHIEUPH O RIEULTHIEUTH
+0xBD63 0xD3FA #HANGUL SYLLABLE PHIEUPH O RIEULPHIEUPH
+0xBD64 0xD3FB #HANGUL SYLLABLE PHIEUPH O RIEULHIEUH
+0xBD65 0xD3FE #HANGUL SYLLABLE PHIEUPH O PIEUPSIOS
+0xBD66 0xD400 #HANGUL SYLLABLE PHIEUPH O SSANGSIOS
+0xBD67 0xD402 #HANGUL SYLLABLE PHIEUPH O CIEUC
+0xBD68 0xD403 #HANGUL SYLLABLE PHIEUPH O CHIEUCH
+0xBD69 0xD404 #HANGUL SYLLABLE PHIEUPH O KHIEUKH
+0xBD6A 0xD405 #HANGUL SYLLABLE PHIEUPH O THIEUTH
+0xBD6B 0xD406 #HANGUL SYLLABLE PHIEUPH O PHIEUPH
+0xBD6C 0xD407 #HANGUL SYLLABLE PHIEUPH O HIEUH
+0xBD6D 0xD409 #HANGUL SYLLABLE PHIEUPH WA KIYEOK
+0xBD6E 0xD40A #HANGUL SYLLABLE PHIEUPH WA SSANGKIYEOK
+0xBD6F 0xD40B #HANGUL SYLLABLE PHIEUPH WA KIYEOKSIOS
+0xBD70 0xD40C #HANGUL SYLLABLE PHIEUPH WA NIEUN
+0xBD71 0xD40D #HANGUL SYLLABLE PHIEUPH WA NIEUNCIEUC
+0xBD72 0xD40E #HANGUL SYLLABLE PHIEUPH WA NIEUNHIEUH
+0xBD73 0xD40F #HANGUL SYLLABLE PHIEUPH WA TIKEUT
+0xBD74 0xD410 #HANGUL SYLLABLE PHIEUPH WA RIEUL
+0xBD75 0xD411 #HANGUL SYLLABLE PHIEUPH WA RIEULKIYEOK
+0xBD76 0xD412 #HANGUL SYLLABLE PHIEUPH WA RIEULMIEUM
+0xBD77 0xD413 #HANGUL SYLLABLE PHIEUPH WA RIEULPIEUP
+0xBD78 0xD414 #HANGUL SYLLABLE PHIEUPH WA RIEULSIOS
+0xBD79 0xD415 #HANGUL SYLLABLE PHIEUPH WA RIEULTHIEUTH
+0xBD7A 0xD416 #HANGUL SYLLABLE PHIEUPH WA RIEULPHIEUPH
+0xBD81 0xD417 #HANGUL SYLLABLE PHIEUPH WA RIEULHIEUH
+0xBD82 0xD418 #HANGUL SYLLABLE PHIEUPH WA MIEUM
+0xBD83 0xD419 #HANGUL SYLLABLE PHIEUPH WA PIEUP
+0xBD84 0xD41A #HANGUL SYLLABLE PHIEUPH WA PIEUPSIOS
+0xBD85 0xD41B #HANGUL SYLLABLE PHIEUPH WA SIOS
+0xBD86 0xD41C #HANGUL SYLLABLE PHIEUPH WA SSANGSIOS
+0xBD87 0xD41E #HANGUL SYLLABLE PHIEUPH WA CIEUC
+0xBD88 0xD41F #HANGUL SYLLABLE PHIEUPH WA CHIEUCH
+0xBD89 0xD420 #HANGUL SYLLABLE PHIEUPH WA KHIEUKH
+0xBD8A 0xD421 #HANGUL SYLLABLE PHIEUPH WA THIEUTH
+0xBD8B 0xD422 #HANGUL SYLLABLE PHIEUPH WA PHIEUPH
+0xBD8C 0xD423 #HANGUL SYLLABLE PHIEUPH WA HIEUH
+0xBD8D 0xD424 #HANGUL SYLLABLE PHIEUPH WAE
+0xBD8E 0xD425 #HANGUL SYLLABLE PHIEUPH WAE KIYEOK
+0xBD8F 0xD426 #HANGUL SYLLABLE PHIEUPH WAE SSANGKIYEOK
+0xBD90 0xD427 #HANGUL SYLLABLE PHIEUPH WAE KIYEOKSIOS
+0xBD91 0xD428 #HANGUL SYLLABLE PHIEUPH WAE NIEUN
+0xBD92 0xD429 #HANGUL SYLLABLE PHIEUPH WAE NIEUNCIEUC
+0xBD93 0xD42A #HANGUL SYLLABLE PHIEUPH WAE NIEUNHIEUH
+0xBD94 0xD42B #HANGUL SYLLABLE PHIEUPH WAE TIKEUT
+0xBD95 0xD42C #HANGUL SYLLABLE PHIEUPH WAE RIEUL
+0xBD96 0xD42D #HANGUL SYLLABLE PHIEUPH WAE RIEULKIYEOK
+0xBD97 0xD42E #HANGUL SYLLABLE PHIEUPH WAE RIEULMIEUM
+0xBD98 0xD42F #HANGUL SYLLABLE PHIEUPH WAE RIEULPIEUP
+0xBD99 0xD430 #HANGUL SYLLABLE PHIEUPH WAE RIEULSIOS
+0xBD9A 0xD431 #HANGUL SYLLABLE PHIEUPH WAE RIEULTHIEUTH
+0xBD9B 0xD432 #HANGUL SYLLABLE PHIEUPH WAE RIEULPHIEUPH
+0xBD9C 0xD433 #HANGUL SYLLABLE PHIEUPH WAE RIEULHIEUH
+0xBD9D 0xD434 #HANGUL SYLLABLE PHIEUPH WAE MIEUM
+0xBD9E 0xD435 #HANGUL SYLLABLE PHIEUPH WAE PIEUP
+0xBD9F 0xD436 #HANGUL SYLLABLE PHIEUPH WAE PIEUPSIOS
+0xBDA0 0xD437 #HANGUL SYLLABLE PHIEUPH WAE SIOS
+0xBDA1 0xC22F #HANGUL SYLLABLE SIOS U CHIEUCH
+0xBDA2 0xC231 #HANGUL SYLLABLE SIOS U THIEUTH
+0xBDA3 0xC232 #HANGUL SYLLABLE SIOS U PHIEUPH
+0xBDA4 0xC234 #HANGUL SYLLABLE SIOS WEO
+0xBDA5 0xC248 #HANGUL SYLLABLE SIOS WEO SSANGSIOS
+0xBDA6 0xC250 #HANGUL SYLLABLE SIOS WE
+0xBDA7 0xC251 #HANGUL SYLLABLE SIOS WE KIYEOK
+0xBDA8 0xC254 #HANGUL SYLLABLE SIOS WE NIEUN
+0xBDA9 0xC258 #HANGUL SYLLABLE SIOS WE RIEUL
+0xBDAA 0xC260 #HANGUL SYLLABLE SIOS WE MIEUM
+0xBDAB 0xC265 #HANGUL SYLLABLE SIOS WE IEUNG
+0xBDAC 0xC26C #HANGUL SYLLABLE SIOS WI
+0xBDAD 0xC26D #HANGUL SYLLABLE SIOS WI KIYEOK
+0xBDAE 0xC270 #HANGUL SYLLABLE SIOS WI NIEUN
+0xBDAF 0xC274 #HANGUL SYLLABLE SIOS WI RIEUL
+0xBDB0 0xC27C #HANGUL SYLLABLE SIOS WI MIEUM
+0xBDB1 0xC27D #HANGUL SYLLABLE SIOS WI PIEUP
+0xBDB2 0xC27F #HANGUL SYLLABLE SIOS WI SIOS
+0xBDB3 0xC281 #HANGUL SYLLABLE SIOS WI IEUNG
+0xBDB4 0xC288 #HANGUL SYLLABLE SIOS YU
+0xBDB5 0xC289 #HANGUL SYLLABLE SIOS YU KIYEOK
+0xBDB6 0xC290 #HANGUL SYLLABLE SIOS YU RIEUL
+0xBDB7 0xC298 #HANGUL SYLLABLE SIOS YU MIEUM
+0xBDB8 0xC29B #HANGUL SYLLABLE SIOS YU SIOS
+0xBDB9 0xC29D #HANGUL SYLLABLE SIOS YU IEUNG
+0xBDBA 0xC2A4 #HANGUL SYLLABLE SIOS EU
+0xBDBB 0xC2A5 #HANGUL SYLLABLE SIOS EU KIYEOK
+0xBDBC 0xC2A8 #HANGUL SYLLABLE SIOS EU NIEUN
+0xBDBD 0xC2AC #HANGUL SYLLABLE SIOS EU RIEUL
+0xBDBE 0xC2AD #HANGUL SYLLABLE SIOS EU RIEULKIYEOK
+0xBDBF 0xC2B4 #HANGUL SYLLABLE SIOS EU MIEUM
+0xBDC0 0xC2B5 #HANGUL SYLLABLE SIOS EU PIEUP
+0xBDC1 0xC2B7 #HANGUL SYLLABLE SIOS EU SIOS
+0xBDC2 0xC2B9 #HANGUL SYLLABLE SIOS EU IEUNG
+0xBDC3 0xC2DC #HANGUL SYLLABLE SIOS I
+0xBDC4 0xC2DD #HANGUL SYLLABLE SIOS I KIYEOK
+0xBDC5 0xC2E0 #HANGUL SYLLABLE SIOS I NIEUN
+0xBDC6 0xC2E3 #HANGUL SYLLABLE SIOS I TIKEUT
+0xBDC7 0xC2E4 #HANGUL SYLLABLE SIOS I RIEUL
+0xBDC8 0xC2EB #HANGUL SYLLABLE SIOS I RIEULHIEUH
+0xBDC9 0xC2EC #HANGUL SYLLABLE SIOS I MIEUM
+0xBDCA 0xC2ED #HANGUL SYLLABLE SIOS I PIEUP
+0xBDCB 0xC2EF #HANGUL SYLLABLE SIOS I SIOS
+0xBDCC 0xC2F1 #HANGUL SYLLABLE SIOS I IEUNG
+0xBDCD 0xC2F6 #HANGUL SYLLABLE SIOS I PHIEUPH
+0xBDCE 0xC2F8 #HANGUL SYLLABLE SSANGSIOS A
+0xBDCF 0xC2F9 #HANGUL SYLLABLE SSANGSIOS A KIYEOK
+0xBDD0 0xC2FB #HANGUL SYLLABLE SSANGSIOS A KIYEOKSIOS
+0xBDD1 0xC2FC #HANGUL SYLLABLE SSANGSIOS A NIEUN
+0xBDD2 0xC300 #HANGUL SYLLABLE SSANGSIOS A RIEUL
+0xBDD3 0xC308 #HANGUL SYLLABLE SSANGSIOS A MIEUM
+0xBDD4 0xC309 #HANGUL SYLLABLE SSANGSIOS A PIEUP
+0xBDD5 0xC30C #HANGUL SYLLABLE SSANGSIOS A SSANGSIOS
+0xBDD6 0xC30D #HANGUL SYLLABLE SSANGSIOS A IEUNG
+0xBDD7 0xC313 #HANGUL SYLLABLE SSANGSIOS A HIEUH
+0xBDD8 0xC314 #HANGUL SYLLABLE SSANGSIOS AE
+0xBDD9 0xC315 #HANGUL SYLLABLE SSANGSIOS AE KIYEOK
+0xBDDA 0xC318 #HANGUL SYLLABLE SSANGSIOS AE NIEUN
+0xBDDB 0xC31C #HANGUL SYLLABLE SSANGSIOS AE RIEUL
+0xBDDC 0xC324 #HANGUL SYLLABLE SSANGSIOS AE MIEUM
+0xBDDD 0xC325 #HANGUL SYLLABLE SSANGSIOS AE PIEUP
+0xBDDE 0xC328 #HANGUL SYLLABLE SSANGSIOS AE SSANGSIOS
+0xBDDF 0xC329 #HANGUL SYLLABLE SSANGSIOS AE IEUNG
+0xBDE0 0xC345 #HANGUL SYLLABLE SSANGSIOS YA IEUNG
+0xBDE1 0xC368 #HANGUL SYLLABLE SSANGSIOS EO
+0xBDE2 0xC369 #HANGUL SYLLABLE SSANGSIOS EO KIYEOK
+0xBDE3 0xC36C #HANGUL SYLLABLE SSANGSIOS EO NIEUN
+0xBDE4 0xC370 #HANGUL SYLLABLE SSANGSIOS EO RIEUL
+0xBDE5 0xC372 #HANGUL SYLLABLE SSANGSIOS EO RIEULMIEUM
+0xBDE6 0xC378 #HANGUL SYLLABLE SSANGSIOS EO MIEUM
+0xBDE7 0xC379 #HANGUL SYLLABLE SSANGSIOS EO PIEUP
+0xBDE8 0xC37C #HANGUL SYLLABLE SSANGSIOS EO SSANGSIOS
+0xBDE9 0xC37D #HANGUL SYLLABLE SSANGSIOS EO IEUNG
+0xBDEA 0xC384 #HANGUL SYLLABLE SSANGSIOS E
+0xBDEB 0xC388 #HANGUL SYLLABLE SSANGSIOS E NIEUN
+0xBDEC 0xC38C #HANGUL SYLLABLE SSANGSIOS E RIEUL
+0xBDED 0xC3C0 #HANGUL SYLLABLE SSANGSIOS YE NIEUN
+0xBDEE 0xC3D8 #HANGUL SYLLABLE SSANGSIOS O
+0xBDEF 0xC3D9 #HANGUL SYLLABLE SSANGSIOS O KIYEOK
+0xBDF0 0xC3DC #HANGUL SYLLABLE SSANGSIOS O NIEUN
+0xBDF1 0xC3DF #HANGUL SYLLABLE SSANGSIOS O TIKEUT
+0xBDF2 0xC3E0 #HANGUL SYLLABLE SSANGSIOS O RIEUL
+0xBDF3 0xC3E2 #HANGUL SYLLABLE SSANGSIOS O RIEULMIEUM
+0xBDF4 0xC3E8 #HANGUL SYLLABLE SSANGSIOS O MIEUM
+0xBDF5 0xC3E9 #HANGUL SYLLABLE SSANGSIOS O PIEUP
+0xBDF6 0xC3ED #HANGUL SYLLABLE SSANGSIOS O IEUNG
+0xBDF7 0xC3F4 #HANGUL SYLLABLE SSANGSIOS WA
+0xBDF8 0xC3F5 #HANGUL SYLLABLE SSANGSIOS WA KIYEOK
+0xBDF9 0xC3F8 #HANGUL SYLLABLE SSANGSIOS WA NIEUN
+0xBDFA 0xC408 #HANGUL SYLLABLE SSANGSIOS WA SSANGSIOS
+0xBDFB 0xC410 #HANGUL SYLLABLE SSANGSIOS WAE
+0xBDFC 0xC424 #HANGUL SYLLABLE SSANGSIOS WAE SSANGSIOS
+0xBDFD 0xC42C #HANGUL SYLLABLE SSANGSIOS OE
+0xBDFE 0xC430 #HANGUL SYLLABLE SSANGSIOS OE NIEUN
+0xBE41 0xD438 #HANGUL SYLLABLE PHIEUPH WAE SSANGSIOS
+0xBE42 0xD439 #HANGUL SYLLABLE PHIEUPH WAE IEUNG
+0xBE43 0xD43A #HANGUL SYLLABLE PHIEUPH WAE CIEUC
+0xBE44 0xD43B #HANGUL SYLLABLE PHIEUPH WAE CHIEUCH
+0xBE45 0xD43C #HANGUL SYLLABLE PHIEUPH WAE KHIEUKH
+0xBE46 0xD43D #HANGUL SYLLABLE PHIEUPH WAE THIEUTH
+0xBE47 0xD43E #HANGUL SYLLABLE PHIEUPH WAE PHIEUPH
+0xBE48 0xD43F #HANGUL SYLLABLE PHIEUPH WAE HIEUH
+0xBE49 0xD441 #HANGUL SYLLABLE PHIEUPH OE KIYEOK
+0xBE4A 0xD442 #HANGUL SYLLABLE PHIEUPH OE SSANGKIYEOK
+0xBE4B 0xD443 #HANGUL SYLLABLE PHIEUPH OE KIYEOKSIOS
+0xBE4C 0xD445 #HANGUL SYLLABLE PHIEUPH OE NIEUNCIEUC
+0xBE4D 0xD446 #HANGUL SYLLABLE PHIEUPH OE NIEUNHIEUH
+0xBE4E 0xD447 #HANGUL SYLLABLE PHIEUPH OE TIKEUT
+0xBE4F 0xD448 #HANGUL SYLLABLE PHIEUPH OE RIEUL
+0xBE50 0xD449 #HANGUL SYLLABLE PHIEUPH OE RIEULKIYEOK
+0xBE51 0xD44A #HANGUL SYLLABLE PHIEUPH OE RIEULMIEUM
+0xBE52 0xD44B #HANGUL SYLLABLE PHIEUPH OE RIEULPIEUP
+0xBE53 0xD44C #HANGUL SYLLABLE PHIEUPH OE RIEULSIOS
+0xBE54 0xD44D #HANGUL SYLLABLE PHIEUPH OE RIEULTHIEUTH
+0xBE55 0xD44E #HANGUL SYLLABLE PHIEUPH OE RIEULPHIEUPH
+0xBE56 0xD44F #HANGUL SYLLABLE PHIEUPH OE RIEULHIEUH
+0xBE57 0xD450 #HANGUL SYLLABLE PHIEUPH OE MIEUM
+0xBE58 0xD451 #HANGUL SYLLABLE PHIEUPH OE PIEUP
+0xBE59 0xD452 #HANGUL SYLLABLE PHIEUPH OE PIEUPSIOS
+0xBE5A 0xD453 #HANGUL SYLLABLE PHIEUPH OE SIOS
+0xBE61 0xD454 #HANGUL SYLLABLE PHIEUPH OE SSANGSIOS
+0xBE62 0xD455 #HANGUL SYLLABLE PHIEUPH OE IEUNG
+0xBE63 0xD456 #HANGUL SYLLABLE PHIEUPH OE CIEUC
+0xBE64 0xD457 #HANGUL SYLLABLE PHIEUPH OE CHIEUCH
+0xBE65 0xD458 #HANGUL SYLLABLE PHIEUPH OE KHIEUKH
+0xBE66 0xD459 #HANGUL SYLLABLE PHIEUPH OE THIEUTH
+0xBE67 0xD45A #HANGUL SYLLABLE PHIEUPH OE PHIEUPH
+0xBE68 0xD45B #HANGUL SYLLABLE PHIEUPH OE HIEUH
+0xBE69 0xD45D #HANGUL SYLLABLE PHIEUPH YO KIYEOK
+0xBE6A 0xD45E #HANGUL SYLLABLE PHIEUPH YO SSANGKIYEOK
+0xBE6B 0xD45F #HANGUL SYLLABLE PHIEUPH YO KIYEOKSIOS
+0xBE6C 0xD461 #HANGUL SYLLABLE PHIEUPH YO NIEUNCIEUC
+0xBE6D 0xD462 #HANGUL SYLLABLE PHIEUPH YO NIEUNHIEUH
+0xBE6E 0xD463 #HANGUL SYLLABLE PHIEUPH YO TIKEUT
+0xBE6F 0xD465 #HANGUL SYLLABLE PHIEUPH YO RIEULKIYEOK
+0xBE70 0xD466 #HANGUL SYLLABLE PHIEUPH YO RIEULMIEUM
+0xBE71 0xD467 #HANGUL SYLLABLE PHIEUPH YO RIEULPIEUP
+0xBE72 0xD468 #HANGUL SYLLABLE PHIEUPH YO RIEULSIOS
+0xBE73 0xD469 #HANGUL SYLLABLE PHIEUPH YO RIEULTHIEUTH
+0xBE74 0xD46A #HANGUL SYLLABLE PHIEUPH YO RIEULPHIEUPH
+0xBE75 0xD46B #HANGUL SYLLABLE PHIEUPH YO RIEULHIEUH
+0xBE76 0xD46C #HANGUL SYLLABLE PHIEUPH YO MIEUM
+0xBE77 0xD46E #HANGUL SYLLABLE PHIEUPH YO PIEUPSIOS
+0xBE78 0xD470 #HANGUL SYLLABLE PHIEUPH YO SSANGSIOS
+0xBE79 0xD471 #HANGUL SYLLABLE PHIEUPH YO IEUNG
+0xBE7A 0xD472 #HANGUL SYLLABLE PHIEUPH YO CIEUC
+0xBE81 0xD473 #HANGUL SYLLABLE PHIEUPH YO CHIEUCH
+0xBE82 0xD474 #HANGUL SYLLABLE PHIEUPH YO KHIEUKH
+0xBE83 0xD475 #HANGUL SYLLABLE PHIEUPH YO THIEUTH
+0xBE84 0xD476 #HANGUL SYLLABLE PHIEUPH YO PHIEUPH
+0xBE85 0xD477 #HANGUL SYLLABLE PHIEUPH YO HIEUH
+0xBE86 0xD47A #HANGUL SYLLABLE PHIEUPH U SSANGKIYEOK
+0xBE87 0xD47B #HANGUL SYLLABLE PHIEUPH U KIYEOKSIOS
+0xBE88 0xD47D #HANGUL SYLLABLE PHIEUPH U NIEUNCIEUC
+0xBE89 0xD47E #HANGUL SYLLABLE PHIEUPH U NIEUNHIEUH
+0xBE8A 0xD481 #HANGUL SYLLABLE PHIEUPH U RIEULKIYEOK
+0xBE8B 0xD483 #HANGUL SYLLABLE PHIEUPH U RIEULPIEUP
+0xBE8C 0xD484 #HANGUL SYLLABLE PHIEUPH U RIEULSIOS
+0xBE8D 0xD485 #HANGUL SYLLABLE PHIEUPH U RIEULTHIEUTH
+0xBE8E 0xD486 #HANGUL SYLLABLE PHIEUPH U RIEULPHIEUPH
+0xBE8F 0xD487 #HANGUL SYLLABLE PHIEUPH U RIEULHIEUH
+0xBE90 0xD48A #HANGUL SYLLABLE PHIEUPH U PIEUPSIOS
+0xBE91 0xD48C #HANGUL SYLLABLE PHIEUPH U SSANGSIOS
+0xBE92 0xD48E #HANGUL SYLLABLE PHIEUPH U CIEUC
+0xBE93 0xD48F #HANGUL SYLLABLE PHIEUPH U CHIEUCH
+0xBE94 0xD490 #HANGUL SYLLABLE PHIEUPH U KHIEUKH
+0xBE95 0xD491 #HANGUL SYLLABLE PHIEUPH U THIEUTH
+0xBE96 0xD492 #HANGUL SYLLABLE PHIEUPH U PHIEUPH
+0xBE97 0xD493 #HANGUL SYLLABLE PHIEUPH U HIEUH
+0xBE98 0xD495 #HANGUL SYLLABLE PHIEUPH WEO KIYEOK
+0xBE99 0xD496 #HANGUL SYLLABLE PHIEUPH WEO SSANGKIYEOK
+0xBE9A 0xD497 #HANGUL SYLLABLE PHIEUPH WEO KIYEOKSIOS
+0xBE9B 0xD498 #HANGUL SYLLABLE PHIEUPH WEO NIEUN
+0xBE9C 0xD499 #HANGUL SYLLABLE PHIEUPH WEO NIEUNCIEUC
+0xBE9D 0xD49A #HANGUL SYLLABLE PHIEUPH WEO NIEUNHIEUH
+0xBE9E 0xD49B #HANGUL SYLLABLE PHIEUPH WEO TIKEUT
+0xBE9F 0xD49C #HANGUL SYLLABLE PHIEUPH WEO RIEUL
+0xBEA0 0xD49D #HANGUL SYLLABLE PHIEUPH WEO RIEULKIYEOK
+0xBEA1 0xC434 #HANGUL SYLLABLE SSANGSIOS OE RIEUL
+0xBEA2 0xC43C #HANGUL SYLLABLE SSANGSIOS OE MIEUM
+0xBEA3 0xC43D #HANGUL SYLLABLE SSANGSIOS OE PIEUP
+0xBEA4 0xC448 #HANGUL SYLLABLE SSANGSIOS YO
+0xBEA5 0xC464 #HANGUL SYLLABLE SSANGSIOS U
+0xBEA6 0xC465 #HANGUL SYLLABLE SSANGSIOS U KIYEOK
+0xBEA7 0xC468 #HANGUL SYLLABLE SSANGSIOS U NIEUN
+0xBEA8 0xC46C #HANGUL SYLLABLE SSANGSIOS U RIEUL
+0xBEA9 0xC474 #HANGUL SYLLABLE SSANGSIOS U MIEUM
+0xBEAA 0xC475 #HANGUL SYLLABLE SSANGSIOS U PIEUP
+0xBEAB 0xC479 #HANGUL SYLLABLE SSANGSIOS U IEUNG
+0xBEAC 0xC480 #HANGUL SYLLABLE SSANGSIOS WEO
+0xBEAD 0xC494 #HANGUL SYLLABLE SSANGSIOS WEO SSANGSIOS
+0xBEAE 0xC49C #HANGUL SYLLABLE SSANGSIOS WE
+0xBEAF 0xC4B8 #HANGUL SYLLABLE SSANGSIOS WI
+0xBEB0 0xC4BC #HANGUL SYLLABLE SSANGSIOS WI NIEUN
+0xBEB1 0xC4E9 #HANGUL SYLLABLE SSANGSIOS YU IEUNG
+0xBEB2 0xC4F0 #HANGUL SYLLABLE SSANGSIOS EU
+0xBEB3 0xC4F1 #HANGUL SYLLABLE SSANGSIOS EU KIYEOK
+0xBEB4 0xC4F4 #HANGUL SYLLABLE SSANGSIOS EU NIEUN
+0xBEB5 0xC4F8 #HANGUL SYLLABLE SSANGSIOS EU RIEUL
+0xBEB6 0xC4FA #HANGUL SYLLABLE SSANGSIOS EU RIEULMIEUM
+0xBEB7 0xC4FF #HANGUL SYLLABLE SSANGSIOS EU RIEULHIEUH
+0xBEB8 0xC500 #HANGUL SYLLABLE SSANGSIOS EU MIEUM
+0xBEB9 0xC501 #HANGUL SYLLABLE SSANGSIOS EU PIEUP
+0xBEBA 0xC50C #HANGUL SYLLABLE SSANGSIOS YI
+0xBEBB 0xC510 #HANGUL SYLLABLE SSANGSIOS YI NIEUN
+0xBEBC 0xC514 #HANGUL SYLLABLE SSANGSIOS YI RIEUL
+0xBEBD 0xC51C #HANGUL SYLLABLE SSANGSIOS YI MIEUM
+0xBEBE 0xC528 #HANGUL SYLLABLE SSANGSIOS I
+0xBEBF 0xC529 #HANGUL SYLLABLE SSANGSIOS I KIYEOK
+0xBEC0 0xC52C #HANGUL SYLLABLE SSANGSIOS I NIEUN
+0xBEC1 0xC530 #HANGUL SYLLABLE SSANGSIOS I RIEUL
+0xBEC2 0xC538 #HANGUL SYLLABLE SSANGSIOS I MIEUM
+0xBEC3 0xC539 #HANGUL SYLLABLE SSANGSIOS I PIEUP
+0xBEC4 0xC53B #HANGUL SYLLABLE SSANGSIOS I SIOS
+0xBEC5 0xC53D #HANGUL SYLLABLE SSANGSIOS I IEUNG
+0xBEC6 0xC544 #HANGUL SYLLABLE IEUNG A
+0xBEC7 0xC545 #HANGUL SYLLABLE IEUNG A KIYEOK
+0xBEC8 0xC548 #HANGUL SYLLABLE IEUNG A NIEUN
+0xBEC9 0xC549 #HANGUL SYLLABLE IEUNG A NIEUNCIEUC
+0xBECA 0xC54A #HANGUL SYLLABLE IEUNG A NIEUNHIEUH
+0xBECB 0xC54C #HANGUL SYLLABLE IEUNG A RIEUL
+0xBECC 0xC54D #HANGUL SYLLABLE IEUNG A RIEULKIYEOK
+0xBECD 0xC54E #HANGUL SYLLABLE IEUNG A RIEULMIEUM
+0xBECE 0xC553 #HANGUL SYLLABLE IEUNG A RIEULHIEUH
+0xBECF 0xC554 #HANGUL SYLLABLE IEUNG A MIEUM
+0xBED0 0xC555 #HANGUL SYLLABLE IEUNG A PIEUP
+0xBED1 0xC557 #HANGUL SYLLABLE IEUNG A SIOS
+0xBED2 0xC558 #HANGUL SYLLABLE IEUNG A SSANGSIOS
+0xBED3 0xC559 #HANGUL SYLLABLE IEUNG A IEUNG
+0xBED4 0xC55D #HANGUL SYLLABLE IEUNG A THIEUTH
+0xBED5 0xC55E #HANGUL SYLLABLE IEUNG A PHIEUPH
+0xBED6 0xC560 #HANGUL SYLLABLE IEUNG AE
+0xBED7 0xC561 #HANGUL SYLLABLE IEUNG AE KIYEOK
+0xBED8 0xC564 #HANGUL SYLLABLE IEUNG AE NIEUN
+0xBED9 0xC568 #HANGUL SYLLABLE IEUNG AE RIEUL
+0xBEDA 0xC570 #HANGUL SYLLABLE IEUNG AE MIEUM
+0xBEDB 0xC571 #HANGUL SYLLABLE IEUNG AE PIEUP
+0xBEDC 0xC573 #HANGUL SYLLABLE IEUNG AE SIOS
+0xBEDD 0xC574 #HANGUL SYLLABLE IEUNG AE SSANGSIOS
+0xBEDE 0xC575 #HANGUL SYLLABLE IEUNG AE IEUNG
+0xBEDF 0xC57C #HANGUL SYLLABLE IEUNG YA
+0xBEE0 0xC57D #HANGUL SYLLABLE IEUNG YA KIYEOK
+0xBEE1 0xC580 #HANGUL SYLLABLE IEUNG YA NIEUN
+0xBEE2 0xC584 #HANGUL SYLLABLE IEUNG YA RIEUL
+0xBEE3 0xC587 #HANGUL SYLLABLE IEUNG YA RIEULPIEUP
+0xBEE4 0xC58C #HANGUL SYLLABLE IEUNG YA MIEUM
+0xBEE5 0xC58D #HANGUL SYLLABLE IEUNG YA PIEUP
+0xBEE6 0xC58F #HANGUL SYLLABLE IEUNG YA SIOS
+0xBEE7 0xC591 #HANGUL SYLLABLE IEUNG YA IEUNG
+0xBEE8 0xC595 #HANGUL SYLLABLE IEUNG YA THIEUTH
+0xBEE9 0xC597 #HANGUL SYLLABLE IEUNG YA HIEUH
+0xBEEA 0xC598 #HANGUL SYLLABLE IEUNG YAE
+0xBEEB 0xC59C #HANGUL SYLLABLE IEUNG YAE NIEUN
+0xBEEC 0xC5A0 #HANGUL SYLLABLE IEUNG YAE RIEUL
+0xBEED 0xC5A9 #HANGUL SYLLABLE IEUNG YAE PIEUP
+0xBEEE 0xC5B4 #HANGUL SYLLABLE IEUNG EO
+0xBEEF 0xC5B5 #HANGUL SYLLABLE IEUNG EO KIYEOK
+0xBEF0 0xC5B8 #HANGUL SYLLABLE IEUNG EO NIEUN
+0xBEF1 0xC5B9 #HANGUL SYLLABLE IEUNG EO NIEUNCIEUC
+0xBEF2 0xC5BB #HANGUL SYLLABLE IEUNG EO TIKEUT
+0xBEF3 0xC5BC #HANGUL SYLLABLE IEUNG EO RIEUL
+0xBEF4 0xC5BD #HANGUL SYLLABLE IEUNG EO RIEULKIYEOK
+0xBEF5 0xC5BE #HANGUL SYLLABLE IEUNG EO RIEULMIEUM
+0xBEF6 0xC5C4 #HANGUL SYLLABLE IEUNG EO MIEUM
+0xBEF7 0xC5C5 #HANGUL SYLLABLE IEUNG EO PIEUP
+0xBEF8 0xC5C6 #HANGUL SYLLABLE IEUNG EO PIEUPSIOS
+0xBEF9 0xC5C7 #HANGUL SYLLABLE IEUNG EO SIOS
+0xBEFA 0xC5C8 #HANGUL SYLLABLE IEUNG EO SSANGSIOS
+0xBEFB 0xC5C9 #HANGUL SYLLABLE IEUNG EO IEUNG
+0xBEFC 0xC5CA #HANGUL SYLLABLE IEUNG EO CIEUC
+0xBEFD 0xC5CC #HANGUL SYLLABLE IEUNG EO KHIEUKH
+0xBEFE 0xC5CE #HANGUL SYLLABLE IEUNG EO PHIEUPH
+0xBF41 0xD49E #HANGUL SYLLABLE PHIEUPH WEO RIEULMIEUM
+0xBF42 0xD49F #HANGUL SYLLABLE PHIEUPH WEO RIEULPIEUP
+0xBF43 0xD4A0 #HANGUL SYLLABLE PHIEUPH WEO RIEULSIOS
+0xBF44 0xD4A1 #HANGUL SYLLABLE PHIEUPH WEO RIEULTHIEUTH
+0xBF45 0xD4A2 #HANGUL SYLLABLE PHIEUPH WEO RIEULPHIEUPH
+0xBF46 0xD4A3 #HANGUL SYLLABLE PHIEUPH WEO RIEULHIEUH
+0xBF47 0xD4A4 #HANGUL SYLLABLE PHIEUPH WEO MIEUM
+0xBF48 0xD4A5 #HANGUL SYLLABLE PHIEUPH WEO PIEUP
+0xBF49 0xD4A6 #HANGUL SYLLABLE PHIEUPH WEO PIEUPSIOS
+0xBF4A 0xD4A7 #HANGUL SYLLABLE PHIEUPH WEO SIOS
+0xBF4B 0xD4A8 #HANGUL SYLLABLE PHIEUPH WEO SSANGSIOS
+0xBF4C 0xD4AA #HANGUL SYLLABLE PHIEUPH WEO CIEUC
+0xBF4D 0xD4AB #HANGUL SYLLABLE PHIEUPH WEO CHIEUCH
+0xBF4E 0xD4AC #HANGUL SYLLABLE PHIEUPH WEO KHIEUKH
+0xBF4F 0xD4AD #HANGUL SYLLABLE PHIEUPH WEO THIEUTH
+0xBF50 0xD4AE #HANGUL SYLLABLE PHIEUPH WEO PHIEUPH
+0xBF51 0xD4AF #HANGUL SYLLABLE PHIEUPH WEO HIEUH
+0xBF52 0xD4B0 #HANGUL SYLLABLE PHIEUPH WE
+0xBF53 0xD4B1 #HANGUL SYLLABLE PHIEUPH WE KIYEOK
+0xBF54 0xD4B2 #HANGUL SYLLABLE PHIEUPH WE SSANGKIYEOK
+0xBF55 0xD4B3 #HANGUL SYLLABLE PHIEUPH WE KIYEOKSIOS
+0xBF56 0xD4B4 #HANGUL SYLLABLE PHIEUPH WE NIEUN
+0xBF57 0xD4B5 #HANGUL SYLLABLE PHIEUPH WE NIEUNCIEUC
+0xBF58 0xD4B6 #HANGUL SYLLABLE PHIEUPH WE NIEUNHIEUH
+0xBF59 0xD4B7 #HANGUL SYLLABLE PHIEUPH WE TIKEUT
+0xBF5A 0xD4B8 #HANGUL SYLLABLE PHIEUPH WE RIEUL
+0xBF61 0xD4B9 #HANGUL SYLLABLE PHIEUPH WE RIEULKIYEOK
+0xBF62 0xD4BA #HANGUL SYLLABLE PHIEUPH WE RIEULMIEUM
+0xBF63 0xD4BB #HANGUL SYLLABLE PHIEUPH WE RIEULPIEUP
+0xBF64 0xD4BC #HANGUL SYLLABLE PHIEUPH WE RIEULSIOS
+0xBF65 0xD4BD #HANGUL SYLLABLE PHIEUPH WE RIEULTHIEUTH
+0xBF66 0xD4BE #HANGUL SYLLABLE PHIEUPH WE RIEULPHIEUPH
+0xBF67 0xD4BF #HANGUL SYLLABLE PHIEUPH WE RIEULHIEUH
+0xBF68 0xD4C0 #HANGUL SYLLABLE PHIEUPH WE MIEUM
+0xBF69 0xD4C1 #HANGUL SYLLABLE PHIEUPH WE PIEUP
+0xBF6A 0xD4C2 #HANGUL SYLLABLE PHIEUPH WE PIEUPSIOS
+0xBF6B 0xD4C3 #HANGUL SYLLABLE PHIEUPH WE SIOS
+0xBF6C 0xD4C4 #HANGUL SYLLABLE PHIEUPH WE SSANGSIOS
+0xBF6D 0xD4C5 #HANGUL SYLLABLE PHIEUPH WE IEUNG
+0xBF6E 0xD4C6 #HANGUL SYLLABLE PHIEUPH WE CIEUC
+0xBF6F 0xD4C7 #HANGUL SYLLABLE PHIEUPH WE CHIEUCH
+0xBF70 0xD4C8 #HANGUL SYLLABLE PHIEUPH WE KHIEUKH
+0xBF71 0xD4C9 #HANGUL SYLLABLE PHIEUPH WE THIEUTH
+0xBF72 0xD4CA #HANGUL SYLLABLE PHIEUPH WE PHIEUPH
+0xBF73 0xD4CB #HANGUL SYLLABLE PHIEUPH WE HIEUH
+0xBF74 0xD4CD #HANGUL SYLLABLE PHIEUPH WI KIYEOK
+0xBF75 0xD4CE #HANGUL SYLLABLE PHIEUPH WI SSANGKIYEOK
+0xBF76 0xD4CF #HANGUL SYLLABLE PHIEUPH WI KIYEOKSIOS
+0xBF77 0xD4D1 #HANGUL SYLLABLE PHIEUPH WI NIEUNCIEUC
+0xBF78 0xD4D2 #HANGUL SYLLABLE PHIEUPH WI NIEUNHIEUH
+0xBF79 0xD4D3 #HANGUL SYLLABLE PHIEUPH WI TIKEUT
+0xBF7A 0xD4D5 #HANGUL SYLLABLE PHIEUPH WI RIEULKIYEOK
+0xBF81 0xD4D6 #HANGUL SYLLABLE PHIEUPH WI RIEULMIEUM
+0xBF82 0xD4D7 #HANGUL SYLLABLE PHIEUPH WI RIEULPIEUP
+0xBF83 0xD4D8 #HANGUL SYLLABLE PHIEUPH WI RIEULSIOS
+0xBF84 0xD4D9 #HANGUL SYLLABLE PHIEUPH WI RIEULTHIEUTH
+0xBF85 0xD4DA #HANGUL SYLLABLE PHIEUPH WI RIEULPHIEUPH
+0xBF86 0xD4DB #HANGUL SYLLABLE PHIEUPH WI RIEULHIEUH
+0xBF87 0xD4DD #HANGUL SYLLABLE PHIEUPH WI PIEUP
+0xBF88 0xD4DE #HANGUL SYLLABLE PHIEUPH WI PIEUPSIOS
+0xBF89 0xD4E0 #HANGUL SYLLABLE PHIEUPH WI SSANGSIOS
+0xBF8A 0xD4E1 #HANGUL SYLLABLE PHIEUPH WI IEUNG
+0xBF8B 0xD4E2 #HANGUL SYLLABLE PHIEUPH WI CIEUC
+0xBF8C 0xD4E3 #HANGUL SYLLABLE PHIEUPH WI CHIEUCH
+0xBF8D 0xD4E4 #HANGUL SYLLABLE PHIEUPH WI KHIEUKH
+0xBF8E 0xD4E5 #HANGUL SYLLABLE PHIEUPH WI THIEUTH
+0xBF8F 0xD4E6 #HANGUL SYLLABLE PHIEUPH WI PHIEUPH
+0xBF90 0xD4E7 #HANGUL SYLLABLE PHIEUPH WI HIEUH
+0xBF91 0xD4E9 #HANGUL SYLLABLE PHIEUPH YU KIYEOK
+0xBF92 0xD4EA #HANGUL SYLLABLE PHIEUPH YU SSANGKIYEOK
+0xBF93 0xD4EB #HANGUL SYLLABLE PHIEUPH YU KIYEOKSIOS
+0xBF94 0xD4ED #HANGUL SYLLABLE PHIEUPH YU NIEUNCIEUC
+0xBF95 0xD4EE #HANGUL SYLLABLE PHIEUPH YU NIEUNHIEUH
+0xBF96 0xD4EF #HANGUL SYLLABLE PHIEUPH YU TIKEUT
+0xBF97 0xD4F1 #HANGUL SYLLABLE PHIEUPH YU RIEULKIYEOK
+0xBF98 0xD4F2 #HANGUL SYLLABLE PHIEUPH YU RIEULMIEUM
+0xBF99 0xD4F3 #HANGUL SYLLABLE PHIEUPH YU RIEULPIEUP
+0xBF9A 0xD4F4 #HANGUL SYLLABLE PHIEUPH YU RIEULSIOS
+0xBF9B 0xD4F5 #HANGUL SYLLABLE PHIEUPH YU RIEULTHIEUTH
+0xBF9C 0xD4F6 #HANGUL SYLLABLE PHIEUPH YU RIEULPHIEUPH
+0xBF9D 0xD4F7 #HANGUL SYLLABLE PHIEUPH YU RIEULHIEUH
+0xBF9E 0xD4F9 #HANGUL SYLLABLE PHIEUPH YU PIEUP
+0xBF9F 0xD4FA #HANGUL SYLLABLE PHIEUPH YU PIEUPSIOS
+0xBFA0 0xD4FC #HANGUL SYLLABLE PHIEUPH YU SSANGSIOS
+0xBFA1 0xC5D0 #HANGUL SYLLABLE IEUNG E
+0xBFA2 0xC5D1 #HANGUL SYLLABLE IEUNG E KIYEOK
+0xBFA3 0xC5D4 #HANGUL SYLLABLE IEUNG E NIEUN
+0xBFA4 0xC5D8 #HANGUL SYLLABLE IEUNG E RIEUL
+0xBFA5 0xC5E0 #HANGUL SYLLABLE IEUNG E MIEUM
+0xBFA6 0xC5E1 #HANGUL SYLLABLE IEUNG E PIEUP
+0xBFA7 0xC5E3 #HANGUL SYLLABLE IEUNG E SIOS
+0xBFA8 0xC5E5 #HANGUL SYLLABLE IEUNG E IEUNG
+0xBFA9 0xC5EC #HANGUL SYLLABLE IEUNG YEO
+0xBFAA 0xC5ED #HANGUL SYLLABLE IEUNG YEO KIYEOK
+0xBFAB 0xC5EE #HANGUL SYLLABLE IEUNG YEO SSANGKIYEOK
+0xBFAC 0xC5F0 #HANGUL SYLLABLE IEUNG YEO NIEUN
+0xBFAD 0xC5F4 #HANGUL SYLLABLE IEUNG YEO RIEUL
+0xBFAE 0xC5F6 #HANGUL SYLLABLE IEUNG YEO RIEULMIEUM
+0xBFAF 0xC5F7 #HANGUL SYLLABLE IEUNG YEO RIEULPIEUP
+0xBFB0 0xC5FC #HANGUL SYLLABLE IEUNG YEO MIEUM
+0xBFB1 0xC5FD #HANGUL SYLLABLE IEUNG YEO PIEUP
+0xBFB2 0xC5FE #HANGUL SYLLABLE IEUNG YEO PIEUPSIOS
+0xBFB3 0xC5FF #HANGUL SYLLABLE IEUNG YEO SIOS
+0xBFB4 0xC600 #HANGUL SYLLABLE IEUNG YEO SSANGSIOS
+0xBFB5 0xC601 #HANGUL SYLLABLE IEUNG YEO IEUNG
+0xBFB6 0xC605 #HANGUL SYLLABLE IEUNG YEO THIEUTH
+0xBFB7 0xC606 #HANGUL SYLLABLE IEUNG YEO PHIEUPH
+0xBFB8 0xC607 #HANGUL SYLLABLE IEUNG YEO HIEUH
+0xBFB9 0xC608 #HANGUL SYLLABLE IEUNG YE
+0xBFBA 0xC60C #HANGUL SYLLABLE IEUNG YE NIEUN
+0xBFBB 0xC610 #HANGUL SYLLABLE IEUNG YE RIEUL
+0xBFBC 0xC618 #HANGUL SYLLABLE IEUNG YE MIEUM
+0xBFBD 0xC619 #HANGUL SYLLABLE IEUNG YE PIEUP
+0xBFBE 0xC61B #HANGUL SYLLABLE IEUNG YE SIOS
+0xBFBF 0xC61C #HANGUL SYLLABLE IEUNG YE SSANGSIOS
+0xBFC0 0xC624 #HANGUL SYLLABLE IEUNG O
+0xBFC1 0xC625 #HANGUL SYLLABLE IEUNG O KIYEOK
+0xBFC2 0xC628 #HANGUL SYLLABLE IEUNG O NIEUN
+0xBFC3 0xC62C #HANGUL SYLLABLE IEUNG O RIEUL
+0xBFC4 0xC62D #HANGUL SYLLABLE IEUNG O RIEULKIYEOK
+0xBFC5 0xC62E #HANGUL SYLLABLE IEUNG O RIEULMIEUM
+0xBFC6 0xC630 #HANGUL SYLLABLE IEUNG O RIEULSIOS
+0xBFC7 0xC633 #HANGUL SYLLABLE IEUNG O RIEULHIEUH
+0xBFC8 0xC634 #HANGUL SYLLABLE IEUNG O MIEUM
+0xBFC9 0xC635 #HANGUL SYLLABLE IEUNG O PIEUP
+0xBFCA 0xC637 #HANGUL SYLLABLE IEUNG O SIOS
+0xBFCB 0xC639 #HANGUL SYLLABLE IEUNG O IEUNG
+0xBFCC 0xC63B #HANGUL SYLLABLE IEUNG O CHIEUCH
+0xBFCD 0xC640 #HANGUL SYLLABLE IEUNG WA
+0xBFCE 0xC641 #HANGUL SYLLABLE IEUNG WA KIYEOK
+0xBFCF 0xC644 #HANGUL SYLLABLE IEUNG WA NIEUN
+0xBFD0 0xC648 #HANGUL SYLLABLE IEUNG WA RIEUL
+0xBFD1 0xC650 #HANGUL SYLLABLE IEUNG WA MIEUM
+0xBFD2 0xC651 #HANGUL SYLLABLE IEUNG WA PIEUP
+0xBFD3 0xC653 #HANGUL SYLLABLE IEUNG WA SIOS
+0xBFD4 0xC654 #HANGUL SYLLABLE IEUNG WA SSANGSIOS
+0xBFD5 0xC655 #HANGUL SYLLABLE IEUNG WA IEUNG
+0xBFD6 0xC65C #HANGUL SYLLABLE IEUNG WAE
+0xBFD7 0xC65D #HANGUL SYLLABLE IEUNG WAE KIYEOK
+0xBFD8 0xC660 #HANGUL SYLLABLE IEUNG WAE NIEUN
+0xBFD9 0xC66C #HANGUL SYLLABLE IEUNG WAE MIEUM
+0xBFDA 0xC66F #HANGUL SYLLABLE IEUNG WAE SIOS
+0xBFDB 0xC671 #HANGUL SYLLABLE IEUNG WAE IEUNG
+0xBFDC 0xC678 #HANGUL SYLLABLE IEUNG OE
+0xBFDD 0xC679 #HANGUL SYLLABLE IEUNG OE KIYEOK
+0xBFDE 0xC67C #HANGUL SYLLABLE IEUNG OE NIEUN
+0xBFDF 0xC680 #HANGUL SYLLABLE IEUNG OE RIEUL
+0xBFE0 0xC688 #HANGUL SYLLABLE IEUNG OE MIEUM
+0xBFE1 0xC689 #HANGUL SYLLABLE IEUNG OE PIEUP
+0xBFE2 0xC68B #HANGUL SYLLABLE IEUNG OE SIOS
+0xBFE3 0xC68D #HANGUL SYLLABLE IEUNG OE IEUNG
+0xBFE4 0xC694 #HANGUL SYLLABLE IEUNG YO
+0xBFE5 0xC695 #HANGUL SYLLABLE IEUNG YO KIYEOK
+0xBFE6 0xC698 #HANGUL SYLLABLE IEUNG YO NIEUN
+0xBFE7 0xC69C #HANGUL SYLLABLE IEUNG YO RIEUL
+0xBFE8 0xC6A4 #HANGUL SYLLABLE IEUNG YO MIEUM
+0xBFE9 0xC6A5 #HANGUL SYLLABLE IEUNG YO PIEUP
+0xBFEA 0xC6A7 #HANGUL SYLLABLE IEUNG YO SIOS
+0xBFEB 0xC6A9 #HANGUL SYLLABLE IEUNG YO IEUNG
+0xBFEC 0xC6B0 #HANGUL SYLLABLE IEUNG U
+0xBFED 0xC6B1 #HANGUL SYLLABLE IEUNG U KIYEOK
+0xBFEE 0xC6B4 #HANGUL SYLLABLE IEUNG U NIEUN
+0xBFEF 0xC6B8 #HANGUL SYLLABLE IEUNG U RIEUL
+0xBFF0 0xC6B9 #HANGUL SYLLABLE IEUNG U RIEULKIYEOK
+0xBFF1 0xC6BA #HANGUL SYLLABLE IEUNG U RIEULMIEUM
+0xBFF2 0xC6C0 #HANGUL SYLLABLE IEUNG U MIEUM
+0xBFF3 0xC6C1 #HANGUL SYLLABLE IEUNG U PIEUP
+0xBFF4 0xC6C3 #HANGUL SYLLABLE IEUNG U SIOS
+0xBFF5 0xC6C5 #HANGUL SYLLABLE IEUNG U IEUNG
+0xBFF6 0xC6CC #HANGUL SYLLABLE IEUNG WEO
+0xBFF7 0xC6CD #HANGUL SYLLABLE IEUNG WEO KIYEOK
+0xBFF8 0xC6D0 #HANGUL SYLLABLE IEUNG WEO NIEUN
+0xBFF9 0xC6D4 #HANGUL SYLLABLE IEUNG WEO RIEUL
+0xBFFA 0xC6DC #HANGUL SYLLABLE IEUNG WEO MIEUM
+0xBFFB 0xC6DD #HANGUL SYLLABLE IEUNG WEO PIEUP
+0xBFFC 0xC6E0 #HANGUL SYLLABLE IEUNG WEO SSANGSIOS
+0xBFFD 0xC6E1 #HANGUL SYLLABLE IEUNG WEO IEUNG
+0xBFFE 0xC6E8 #HANGUL SYLLABLE IEUNG WE
+0xC041 0xD4FE #HANGUL SYLLABLE PHIEUPH YU CIEUC
+0xC042 0xD4FF #HANGUL SYLLABLE PHIEUPH YU CHIEUCH
+0xC043 0xD500 #HANGUL SYLLABLE PHIEUPH YU KHIEUKH
+0xC044 0xD501 #HANGUL SYLLABLE PHIEUPH YU THIEUTH
+0xC045 0xD502 #HANGUL SYLLABLE PHIEUPH YU PHIEUPH
+0xC046 0xD503 #HANGUL SYLLABLE PHIEUPH YU HIEUH
+0xC047 0xD505 #HANGUL SYLLABLE PHIEUPH EU KIYEOK
+0xC048 0xD506 #HANGUL SYLLABLE PHIEUPH EU SSANGKIYEOK
+0xC049 0xD507 #HANGUL SYLLABLE PHIEUPH EU KIYEOKSIOS
+0xC04A 0xD509 #HANGUL SYLLABLE PHIEUPH EU NIEUNCIEUC
+0xC04B 0xD50A #HANGUL SYLLABLE PHIEUPH EU NIEUNHIEUH
+0xC04C 0xD50B #HANGUL SYLLABLE PHIEUPH EU TIKEUT
+0xC04D 0xD50D #HANGUL SYLLABLE PHIEUPH EU RIEULKIYEOK
+0xC04E 0xD50E #HANGUL SYLLABLE PHIEUPH EU RIEULMIEUM
+0xC04F 0xD50F #HANGUL SYLLABLE PHIEUPH EU RIEULPIEUP
+0xC050 0xD510 #HANGUL SYLLABLE PHIEUPH EU RIEULSIOS
+0xC051 0xD511 #HANGUL SYLLABLE PHIEUPH EU RIEULTHIEUTH
+0xC052 0xD512 #HANGUL SYLLABLE PHIEUPH EU RIEULPHIEUPH
+0xC053 0xD513 #HANGUL SYLLABLE PHIEUPH EU RIEULHIEUH
+0xC054 0xD516 #HANGUL SYLLABLE PHIEUPH EU PIEUPSIOS
+0xC055 0xD518 #HANGUL SYLLABLE PHIEUPH EU SSANGSIOS
+0xC056 0xD519 #HANGUL SYLLABLE PHIEUPH EU IEUNG
+0xC057 0xD51A #HANGUL SYLLABLE PHIEUPH EU CIEUC
+0xC058 0xD51B #HANGUL SYLLABLE PHIEUPH EU CHIEUCH
+0xC059 0xD51C #HANGUL SYLLABLE PHIEUPH EU KHIEUKH
+0xC05A 0xD51D #HANGUL SYLLABLE PHIEUPH EU THIEUTH
+0xC061 0xD51E #HANGUL SYLLABLE PHIEUPH EU PHIEUPH
+0xC062 0xD51F #HANGUL SYLLABLE PHIEUPH EU HIEUH
+0xC063 0xD520 #HANGUL SYLLABLE PHIEUPH YI
+0xC064 0xD521 #HANGUL SYLLABLE PHIEUPH YI KIYEOK
+0xC065 0xD522 #HANGUL SYLLABLE PHIEUPH YI SSANGKIYEOK
+0xC066 0xD523 #HANGUL SYLLABLE PHIEUPH YI KIYEOKSIOS
+0xC067 0xD524 #HANGUL SYLLABLE PHIEUPH YI NIEUN
+0xC068 0xD525 #HANGUL SYLLABLE PHIEUPH YI NIEUNCIEUC
+0xC069 0xD526 #HANGUL SYLLABLE PHIEUPH YI NIEUNHIEUH
+0xC06A 0xD527 #HANGUL SYLLABLE PHIEUPH YI TIKEUT
+0xC06B 0xD528 #HANGUL SYLLABLE PHIEUPH YI RIEUL
+0xC06C 0xD529 #HANGUL SYLLABLE PHIEUPH YI RIEULKIYEOK
+0xC06D 0xD52A #HANGUL SYLLABLE PHIEUPH YI RIEULMIEUM
+0xC06E 0xD52B #HANGUL SYLLABLE PHIEUPH YI RIEULPIEUP
+0xC06F 0xD52C #HANGUL SYLLABLE PHIEUPH YI RIEULSIOS
+0xC070 0xD52D #HANGUL SYLLABLE PHIEUPH YI RIEULTHIEUTH
+0xC071 0xD52E #HANGUL SYLLABLE PHIEUPH YI RIEULPHIEUPH
+0xC072 0xD52F #HANGUL SYLLABLE PHIEUPH YI RIEULHIEUH
+0xC073 0xD530 #HANGUL SYLLABLE PHIEUPH YI MIEUM
+0xC074 0xD531 #HANGUL SYLLABLE PHIEUPH YI PIEUP
+0xC075 0xD532 #HANGUL SYLLABLE PHIEUPH YI PIEUPSIOS
+0xC076 0xD533 #HANGUL SYLLABLE PHIEUPH YI SIOS
+0xC077 0xD534 #HANGUL SYLLABLE PHIEUPH YI SSANGSIOS
+0xC078 0xD535 #HANGUL SYLLABLE PHIEUPH YI IEUNG
+0xC079 0xD536 #HANGUL SYLLABLE PHIEUPH YI CIEUC
+0xC07A 0xD537 #HANGUL SYLLABLE PHIEUPH YI CHIEUCH
+0xC081 0xD538 #HANGUL SYLLABLE PHIEUPH YI KHIEUKH
+0xC082 0xD539 #HANGUL SYLLABLE PHIEUPH YI THIEUTH
+0xC083 0xD53A #HANGUL SYLLABLE PHIEUPH YI PHIEUPH
+0xC084 0xD53B #HANGUL SYLLABLE PHIEUPH YI HIEUH
+0xC085 0xD53E #HANGUL SYLLABLE PHIEUPH I SSANGKIYEOK
+0xC086 0xD53F #HANGUL SYLLABLE PHIEUPH I KIYEOKSIOS
+0xC087 0xD541 #HANGUL SYLLABLE PHIEUPH I NIEUNCIEUC
+0xC088 0xD542 #HANGUL SYLLABLE PHIEUPH I NIEUNHIEUH
+0xC089 0xD543 #HANGUL SYLLABLE PHIEUPH I TIKEUT
+0xC08A 0xD545 #HANGUL SYLLABLE PHIEUPH I RIEULKIYEOK
+0xC08B 0xD546 #HANGUL SYLLABLE PHIEUPH I RIEULMIEUM
+0xC08C 0xD547 #HANGUL SYLLABLE PHIEUPH I RIEULPIEUP
+0xC08D 0xD548 #HANGUL SYLLABLE PHIEUPH I RIEULSIOS
+0xC08E 0xD549 #HANGUL SYLLABLE PHIEUPH I RIEULTHIEUTH
+0xC08F 0xD54A #HANGUL SYLLABLE PHIEUPH I RIEULPHIEUPH
+0xC090 0xD54B #HANGUL SYLLABLE PHIEUPH I RIEULHIEUH
+0xC091 0xD54E #HANGUL SYLLABLE PHIEUPH I PIEUPSIOS
+0xC092 0xD550 #HANGUL SYLLABLE PHIEUPH I SSANGSIOS
+0xC093 0xD552 #HANGUL SYLLABLE PHIEUPH I CIEUC
+0xC094 0xD553 #HANGUL SYLLABLE PHIEUPH I CHIEUCH
+0xC095 0xD554 #HANGUL SYLLABLE PHIEUPH I KHIEUKH
+0xC096 0xD555 #HANGUL SYLLABLE PHIEUPH I THIEUTH
+0xC097 0xD556 #HANGUL SYLLABLE PHIEUPH I PHIEUPH
+0xC098 0xD557 #HANGUL SYLLABLE PHIEUPH I HIEUH
+0xC099 0xD55A #HANGUL SYLLABLE HIEUH A SSANGKIYEOK
+0xC09A 0xD55B #HANGUL SYLLABLE HIEUH A KIYEOKSIOS
+0xC09B 0xD55D #HANGUL SYLLABLE HIEUH A NIEUNCIEUC
+0xC09C 0xD55E #HANGUL SYLLABLE HIEUH A NIEUNHIEUH
+0xC09D 0xD55F #HANGUL SYLLABLE HIEUH A TIKEUT
+0xC09E 0xD561 #HANGUL SYLLABLE HIEUH A RIEULKIYEOK
+0xC09F 0xD562 #HANGUL SYLLABLE HIEUH A RIEULMIEUM
+0xC0A0 0xD563 #HANGUL SYLLABLE HIEUH A RIEULPIEUP
+0xC0A1 0xC6E9 #HANGUL SYLLABLE IEUNG WE KIYEOK
+0xC0A2 0xC6EC #HANGUL SYLLABLE IEUNG WE NIEUN
+0xC0A3 0xC6F0 #HANGUL SYLLABLE IEUNG WE RIEUL
+0xC0A4 0xC6F8 #HANGUL SYLLABLE IEUNG WE MIEUM
+0xC0A5 0xC6F9 #HANGUL SYLLABLE IEUNG WE PIEUP
+0xC0A6 0xC6FD #HANGUL SYLLABLE IEUNG WE IEUNG
+0xC0A7 0xC704 #HANGUL SYLLABLE IEUNG WI
+0xC0A8 0xC705 #HANGUL SYLLABLE IEUNG WI KIYEOK
+0xC0A9 0xC708 #HANGUL SYLLABLE IEUNG WI NIEUN
+0xC0AA 0xC70C #HANGUL SYLLABLE IEUNG WI RIEUL
+0xC0AB 0xC714 #HANGUL SYLLABLE IEUNG WI MIEUM
+0xC0AC 0xC715 #HANGUL SYLLABLE IEUNG WI PIEUP
+0xC0AD 0xC717 #HANGUL SYLLABLE IEUNG WI SIOS
+0xC0AE 0xC719 #HANGUL SYLLABLE IEUNG WI IEUNG
+0xC0AF 0xC720 #HANGUL SYLLABLE IEUNG YU
+0xC0B0 0xC721 #HANGUL SYLLABLE IEUNG YU KIYEOK
+0xC0B1 0xC724 #HANGUL SYLLABLE IEUNG YU NIEUN
+0xC0B2 0xC728 #HANGUL SYLLABLE IEUNG YU RIEUL
+0xC0B3 0xC730 #HANGUL SYLLABLE IEUNG YU MIEUM
+0xC0B4 0xC731 #HANGUL SYLLABLE IEUNG YU PIEUP
+0xC0B5 0xC733 #HANGUL SYLLABLE IEUNG YU SIOS
+0xC0B6 0xC735 #HANGUL SYLLABLE IEUNG YU IEUNG
+0xC0B7 0xC737 #HANGUL SYLLABLE IEUNG YU CHIEUCH
+0xC0B8 0xC73C #HANGUL SYLLABLE IEUNG EU
+0xC0B9 0xC73D #HANGUL SYLLABLE IEUNG EU KIYEOK
+0xC0BA 0xC740 #HANGUL SYLLABLE IEUNG EU NIEUN
+0xC0BB 0xC744 #HANGUL SYLLABLE IEUNG EU RIEUL
+0xC0BC 0xC74A #HANGUL SYLLABLE IEUNG EU RIEULPHIEUPH
+0xC0BD 0xC74C #HANGUL SYLLABLE IEUNG EU MIEUM
+0xC0BE 0xC74D #HANGUL SYLLABLE IEUNG EU PIEUP
+0xC0BF 0xC74F #HANGUL SYLLABLE IEUNG EU SIOS
+0xC0C0 0xC751 #HANGUL SYLLABLE IEUNG EU IEUNG
+0xC0C1 0xC752 #HANGUL SYLLABLE IEUNG EU CIEUC
+0xC0C2 0xC753 #HANGUL SYLLABLE IEUNG EU CHIEUCH
+0xC0C3 0xC754 #HANGUL SYLLABLE IEUNG EU KHIEUKH
+0xC0C4 0xC755 #HANGUL SYLLABLE IEUNG EU THIEUTH
+0xC0C5 0xC756 #HANGUL SYLLABLE IEUNG EU PHIEUPH
+0xC0C6 0xC757 #HANGUL SYLLABLE IEUNG EU HIEUH
+0xC0C7 0xC758 #HANGUL SYLLABLE IEUNG YI
+0xC0C8 0xC75C #HANGUL SYLLABLE IEUNG YI NIEUN
+0xC0C9 0xC760 #HANGUL SYLLABLE IEUNG YI RIEUL
+0xC0CA 0xC768 #HANGUL SYLLABLE IEUNG YI MIEUM
+0xC0CB 0xC76B #HANGUL SYLLABLE IEUNG YI SIOS
+0xC0CC 0xC774 #HANGUL SYLLABLE IEUNG I
+0xC0CD 0xC775 #HANGUL SYLLABLE IEUNG I KIYEOK
+0xC0CE 0xC778 #HANGUL SYLLABLE IEUNG I NIEUN
+0xC0CF 0xC77C #HANGUL SYLLABLE IEUNG I RIEUL
+0xC0D0 0xC77D #HANGUL SYLLABLE IEUNG I RIEULKIYEOK
+0xC0D1 0xC77E #HANGUL SYLLABLE IEUNG I RIEULMIEUM
+0xC0D2 0xC783 #HANGUL SYLLABLE IEUNG I RIEULHIEUH
+0xC0D3 0xC784 #HANGUL SYLLABLE IEUNG I MIEUM
+0xC0D4 0xC785 #HANGUL SYLLABLE IEUNG I PIEUP
+0xC0D5 0xC787 #HANGUL SYLLABLE IEUNG I SIOS
+0xC0D6 0xC788 #HANGUL SYLLABLE IEUNG I SSANGSIOS
+0xC0D7 0xC789 #HANGUL SYLLABLE IEUNG I IEUNG
+0xC0D8 0xC78A #HANGUL SYLLABLE IEUNG I CIEUC
+0xC0D9 0xC78E #HANGUL SYLLABLE IEUNG I PHIEUPH
+0xC0DA 0xC790 #HANGUL SYLLABLE CIEUC A
+0xC0DB 0xC791 #HANGUL SYLLABLE CIEUC A KIYEOK
+0xC0DC 0xC794 #HANGUL SYLLABLE CIEUC A NIEUN
+0xC0DD 0xC796 #HANGUL SYLLABLE CIEUC A NIEUNHIEUH
+0xC0DE 0xC797 #HANGUL SYLLABLE CIEUC A TIKEUT
+0xC0DF 0xC798 #HANGUL SYLLABLE CIEUC A RIEUL
+0xC0E0 0xC79A #HANGUL SYLLABLE CIEUC A RIEULMIEUM
+0xC0E1 0xC7A0 #HANGUL SYLLABLE CIEUC A MIEUM
+0xC0E2 0xC7A1 #HANGUL SYLLABLE CIEUC A PIEUP
+0xC0E3 0xC7A3 #HANGUL SYLLABLE CIEUC A SIOS
+0xC0E4 0xC7A4 #HANGUL SYLLABLE CIEUC A SSANGSIOS
+0xC0E5 0xC7A5 #HANGUL SYLLABLE CIEUC A IEUNG
+0xC0E6 0xC7A6 #HANGUL SYLLABLE CIEUC A CIEUC
+0xC0E7 0xC7AC #HANGUL SYLLABLE CIEUC AE
+0xC0E8 0xC7AD #HANGUL SYLLABLE CIEUC AE KIYEOK
+0xC0E9 0xC7B0 #HANGUL SYLLABLE CIEUC AE NIEUN
+0xC0EA 0xC7B4 #HANGUL SYLLABLE CIEUC AE RIEUL
+0xC0EB 0xC7BC #HANGUL SYLLABLE CIEUC AE MIEUM
+0xC0EC 0xC7BD #HANGUL SYLLABLE CIEUC AE PIEUP
+0xC0ED 0xC7BF #HANGUL SYLLABLE CIEUC AE SIOS
+0xC0EE 0xC7C0 #HANGUL SYLLABLE CIEUC AE SSANGSIOS
+0xC0EF 0xC7C1 #HANGUL SYLLABLE CIEUC AE IEUNG
+0xC0F0 0xC7C8 #HANGUL SYLLABLE CIEUC YA
+0xC0F1 0xC7C9 #HANGUL SYLLABLE CIEUC YA KIYEOK
+0xC0F2 0xC7CC #HANGUL SYLLABLE CIEUC YA NIEUN
+0xC0F3 0xC7CE #HANGUL SYLLABLE CIEUC YA NIEUNHIEUH
+0xC0F4 0xC7D0 #HANGUL SYLLABLE CIEUC YA RIEUL
+0xC0F5 0xC7D8 #HANGUL SYLLABLE CIEUC YA MIEUM
+0xC0F6 0xC7DD #HANGUL SYLLABLE CIEUC YA IEUNG
+0xC0F7 0xC7E4 #HANGUL SYLLABLE CIEUC YAE
+0xC0F8 0xC7E8 #HANGUL SYLLABLE CIEUC YAE NIEUN
+0xC0F9 0xC7EC #HANGUL SYLLABLE CIEUC YAE RIEUL
+0xC0FA 0xC800 #HANGUL SYLLABLE CIEUC EO
+0xC0FB 0xC801 #HANGUL SYLLABLE CIEUC EO KIYEOK
+0xC0FC 0xC804 #HANGUL SYLLABLE CIEUC EO NIEUN
+0xC0FD 0xC808 #HANGUL SYLLABLE CIEUC EO RIEUL
+0xC0FE 0xC80A #HANGUL SYLLABLE CIEUC EO RIEULMIEUM
+0xC141 0xD564 #HANGUL SYLLABLE HIEUH A RIEULSIOS
+0xC142 0xD566 #HANGUL SYLLABLE HIEUH A RIEULPHIEUPH
+0xC143 0xD567 #HANGUL SYLLABLE HIEUH A RIEULHIEUH
+0xC144 0xD56A #HANGUL SYLLABLE HIEUH A PIEUPSIOS
+0xC145 0xD56C #HANGUL SYLLABLE HIEUH A SSANGSIOS
+0xC146 0xD56E #HANGUL SYLLABLE HIEUH A CIEUC
+0xC147 0xD56F #HANGUL SYLLABLE HIEUH A CHIEUCH
+0xC148 0xD570 #HANGUL SYLLABLE HIEUH A KHIEUKH
+0xC149 0xD571 #HANGUL SYLLABLE HIEUH A THIEUTH
+0xC14A 0xD572 #HANGUL SYLLABLE HIEUH A PHIEUPH
+0xC14B 0xD573 #HANGUL SYLLABLE HIEUH A HIEUH
+0xC14C 0xD576 #HANGUL SYLLABLE HIEUH AE SSANGKIYEOK
+0xC14D 0xD577 #HANGUL SYLLABLE HIEUH AE KIYEOKSIOS
+0xC14E 0xD579 #HANGUL SYLLABLE HIEUH AE NIEUNCIEUC
+0xC14F 0xD57A #HANGUL SYLLABLE HIEUH AE NIEUNHIEUH
+0xC150 0xD57B #HANGUL SYLLABLE HIEUH AE TIKEUT
+0xC151 0xD57D #HANGUL SYLLABLE HIEUH AE RIEULKIYEOK
+0xC152 0xD57E #HANGUL SYLLABLE HIEUH AE RIEULMIEUM
+0xC153 0xD57F #HANGUL SYLLABLE HIEUH AE RIEULPIEUP
+0xC154 0xD580 #HANGUL SYLLABLE HIEUH AE RIEULSIOS
+0xC155 0xD581 #HANGUL SYLLABLE HIEUH AE RIEULTHIEUTH
+0xC156 0xD582 #HANGUL SYLLABLE HIEUH AE RIEULPHIEUPH
+0xC157 0xD583 #HANGUL SYLLABLE HIEUH AE RIEULHIEUH
+0xC158 0xD586 #HANGUL SYLLABLE HIEUH AE PIEUPSIOS
+0xC159 0xD58A #HANGUL SYLLABLE HIEUH AE CIEUC
+0xC15A 0xD58B #HANGUL SYLLABLE HIEUH AE CHIEUCH
+0xC161 0xD58C #HANGUL SYLLABLE HIEUH AE KHIEUKH
+0xC162 0xD58D #HANGUL SYLLABLE HIEUH AE THIEUTH
+0xC163 0xD58E #HANGUL SYLLABLE HIEUH AE PHIEUPH
+0xC164 0xD58F #HANGUL SYLLABLE HIEUH AE HIEUH
+0xC165 0xD591 #HANGUL SYLLABLE HIEUH YA KIYEOK
+0xC166 0xD592 #HANGUL SYLLABLE HIEUH YA SSANGKIYEOK
+0xC167 0xD593 #HANGUL SYLLABLE HIEUH YA KIYEOKSIOS
+0xC168 0xD594 #HANGUL SYLLABLE HIEUH YA NIEUN
+0xC169 0xD595 #HANGUL SYLLABLE HIEUH YA NIEUNCIEUC
+0xC16A 0xD596 #HANGUL SYLLABLE HIEUH YA NIEUNHIEUH
+0xC16B 0xD597 #HANGUL SYLLABLE HIEUH YA TIKEUT
+0xC16C 0xD598 #HANGUL SYLLABLE HIEUH YA RIEUL
+0xC16D 0xD599 #HANGUL SYLLABLE HIEUH YA RIEULKIYEOK
+0xC16E 0xD59A #HANGUL SYLLABLE HIEUH YA RIEULMIEUM
+0xC16F 0xD59B #HANGUL SYLLABLE HIEUH YA RIEULPIEUP
+0xC170 0xD59C #HANGUL SYLLABLE HIEUH YA RIEULSIOS
+0xC171 0xD59D #HANGUL SYLLABLE HIEUH YA RIEULTHIEUTH
+0xC172 0xD59E #HANGUL SYLLABLE HIEUH YA RIEULPHIEUPH
+0xC173 0xD59F #HANGUL SYLLABLE HIEUH YA RIEULHIEUH
+0xC174 0xD5A0 #HANGUL SYLLABLE HIEUH YA MIEUM
+0xC175 0xD5A1 #HANGUL SYLLABLE HIEUH YA PIEUP
+0xC176 0xD5A2 #HANGUL SYLLABLE HIEUH YA PIEUPSIOS
+0xC177 0xD5A3 #HANGUL SYLLABLE HIEUH YA SIOS
+0xC178 0xD5A4 #HANGUL SYLLABLE HIEUH YA SSANGSIOS
+0xC179 0xD5A6 #HANGUL SYLLABLE HIEUH YA CIEUC
+0xC17A 0xD5A7 #HANGUL SYLLABLE HIEUH YA CHIEUCH
+0xC181 0xD5A8 #HANGUL SYLLABLE HIEUH YA KHIEUKH
+0xC182 0xD5A9 #HANGUL SYLLABLE HIEUH YA THIEUTH
+0xC183 0xD5AA #HANGUL SYLLABLE HIEUH YA PHIEUPH
+0xC184 0xD5AB #HANGUL SYLLABLE HIEUH YA HIEUH
+0xC185 0xD5AC #HANGUL SYLLABLE HIEUH YAE
+0xC186 0xD5AD #HANGUL SYLLABLE HIEUH YAE KIYEOK
+0xC187 0xD5AE #HANGUL SYLLABLE HIEUH YAE SSANGKIYEOK
+0xC188 0xD5AF #HANGUL SYLLABLE HIEUH YAE KIYEOKSIOS
+0xC189 0xD5B0 #HANGUL SYLLABLE HIEUH YAE NIEUN
+0xC18A 0xD5B1 #HANGUL SYLLABLE HIEUH YAE NIEUNCIEUC
+0xC18B 0xD5B2 #HANGUL SYLLABLE HIEUH YAE NIEUNHIEUH
+0xC18C 0xD5B3 #HANGUL SYLLABLE HIEUH YAE TIKEUT
+0xC18D 0xD5B4 #HANGUL SYLLABLE HIEUH YAE RIEUL
+0xC18E 0xD5B5 #HANGUL SYLLABLE HIEUH YAE RIEULKIYEOK
+0xC18F 0xD5B6 #HANGUL SYLLABLE HIEUH YAE RIEULMIEUM
+0xC190 0xD5B7 #HANGUL SYLLABLE HIEUH YAE RIEULPIEUP
+0xC191 0xD5B8 #HANGUL SYLLABLE HIEUH YAE RIEULSIOS
+0xC192 0xD5B9 #HANGUL SYLLABLE HIEUH YAE RIEULTHIEUTH
+0xC193 0xD5BA #HANGUL SYLLABLE HIEUH YAE RIEULPHIEUPH
+0xC194 0xD5BB #HANGUL SYLLABLE HIEUH YAE RIEULHIEUH
+0xC195 0xD5BC #HANGUL SYLLABLE HIEUH YAE MIEUM
+0xC196 0xD5BD #HANGUL SYLLABLE HIEUH YAE PIEUP
+0xC197 0xD5BE #HANGUL SYLLABLE HIEUH YAE PIEUPSIOS
+0xC198 0xD5BF #HANGUL SYLLABLE HIEUH YAE SIOS
+0xC199 0xD5C0 #HANGUL SYLLABLE HIEUH YAE SSANGSIOS
+0xC19A 0xD5C1 #HANGUL SYLLABLE HIEUH YAE IEUNG
+0xC19B 0xD5C2 #HANGUL SYLLABLE HIEUH YAE CIEUC
+0xC19C 0xD5C3 #HANGUL SYLLABLE HIEUH YAE CHIEUCH
+0xC19D 0xD5C4 #HANGUL SYLLABLE HIEUH YAE KHIEUKH
+0xC19E 0xD5C5 #HANGUL SYLLABLE HIEUH YAE THIEUTH
+0xC19F 0xD5C6 #HANGUL SYLLABLE HIEUH YAE PHIEUPH
+0xC1A0 0xD5C7 #HANGUL SYLLABLE HIEUH YAE HIEUH
+0xC1A1 0xC810 #HANGUL SYLLABLE CIEUC EO MIEUM
+0xC1A2 0xC811 #HANGUL SYLLABLE CIEUC EO PIEUP
+0xC1A3 0xC813 #HANGUL SYLLABLE CIEUC EO SIOS
+0xC1A4 0xC815 #HANGUL SYLLABLE CIEUC EO IEUNG
+0xC1A5 0xC816 #HANGUL SYLLABLE CIEUC EO CIEUC
+0xC1A6 0xC81C #HANGUL SYLLABLE CIEUC E
+0xC1A7 0xC81D #HANGUL SYLLABLE CIEUC E KIYEOK
+0xC1A8 0xC820 #HANGUL SYLLABLE CIEUC E NIEUN
+0xC1A9 0xC824 #HANGUL SYLLABLE CIEUC E RIEUL
+0xC1AA 0xC82C #HANGUL SYLLABLE CIEUC E MIEUM
+0xC1AB 0xC82D #HANGUL SYLLABLE CIEUC E PIEUP
+0xC1AC 0xC82F #HANGUL SYLLABLE CIEUC E SIOS
+0xC1AD 0xC831 #HANGUL SYLLABLE CIEUC E IEUNG
+0xC1AE 0xC838 #HANGUL SYLLABLE CIEUC YEO
+0xC1AF 0xC83C #HANGUL SYLLABLE CIEUC YEO NIEUN
+0xC1B0 0xC840 #HANGUL SYLLABLE CIEUC YEO RIEUL
+0xC1B1 0xC848 #HANGUL SYLLABLE CIEUC YEO MIEUM
+0xC1B2 0xC849 #HANGUL SYLLABLE CIEUC YEO PIEUP
+0xC1B3 0xC84C #HANGUL SYLLABLE CIEUC YEO SSANGSIOS
+0xC1B4 0xC84D #HANGUL SYLLABLE CIEUC YEO IEUNG
+0xC1B5 0xC854 #HANGUL SYLLABLE CIEUC YE
+0xC1B6 0xC870 #HANGUL SYLLABLE CIEUC O
+0xC1B7 0xC871 #HANGUL SYLLABLE CIEUC O KIYEOK
+0xC1B8 0xC874 #HANGUL SYLLABLE CIEUC O NIEUN
+0xC1B9 0xC878 #HANGUL SYLLABLE CIEUC O RIEUL
+0xC1BA 0xC87A #HANGUL SYLLABLE CIEUC O RIEULMIEUM
+0xC1BB 0xC880 #HANGUL SYLLABLE CIEUC O MIEUM
+0xC1BC 0xC881 #HANGUL SYLLABLE CIEUC O PIEUP
+0xC1BD 0xC883 #HANGUL SYLLABLE CIEUC O SIOS
+0xC1BE 0xC885 #HANGUL SYLLABLE CIEUC O IEUNG
+0xC1BF 0xC886 #HANGUL SYLLABLE CIEUC O CIEUC
+0xC1C0 0xC887 #HANGUL SYLLABLE CIEUC O CHIEUCH
+0xC1C1 0xC88B #HANGUL SYLLABLE CIEUC O HIEUH
+0xC1C2 0xC88C #HANGUL SYLLABLE CIEUC WA
+0xC1C3 0xC88D #HANGUL SYLLABLE CIEUC WA KIYEOK
+0xC1C4 0xC894 #HANGUL SYLLABLE CIEUC WA RIEUL
+0xC1C5 0xC89D #HANGUL SYLLABLE CIEUC WA PIEUP
+0xC1C6 0xC89F #HANGUL SYLLABLE CIEUC WA SIOS
+0xC1C7 0xC8A1 #HANGUL SYLLABLE CIEUC WA IEUNG
+0xC1C8 0xC8A8 #HANGUL SYLLABLE CIEUC WAE
+0xC1C9 0xC8BC #HANGUL SYLLABLE CIEUC WAE SSANGSIOS
+0xC1CA 0xC8BD #HANGUL SYLLABLE CIEUC WAE IEUNG
+0xC1CB 0xC8C4 #HANGUL SYLLABLE CIEUC OE
+0xC1CC 0xC8C8 #HANGUL SYLLABLE CIEUC OE NIEUN
+0xC1CD 0xC8CC #HANGUL SYLLABLE CIEUC OE RIEUL
+0xC1CE 0xC8D4 #HANGUL SYLLABLE CIEUC OE MIEUM
+0xC1CF 0xC8D5 #HANGUL SYLLABLE CIEUC OE PIEUP
+0xC1D0 0xC8D7 #HANGUL SYLLABLE CIEUC OE SIOS
+0xC1D1 0xC8D9 #HANGUL SYLLABLE CIEUC OE IEUNG
+0xC1D2 0xC8E0 #HANGUL SYLLABLE CIEUC YO
+0xC1D3 0xC8E1 #HANGUL SYLLABLE CIEUC YO KIYEOK
+0xC1D4 0xC8E4 #HANGUL SYLLABLE CIEUC YO NIEUN
+0xC1D5 0xC8F5 #HANGUL SYLLABLE CIEUC YO IEUNG
+0xC1D6 0xC8FC #HANGUL SYLLABLE CIEUC U
+0xC1D7 0xC8FD #HANGUL SYLLABLE CIEUC U KIYEOK
+0xC1D8 0xC900 #HANGUL SYLLABLE CIEUC U NIEUN
+0xC1D9 0xC904 #HANGUL SYLLABLE CIEUC U RIEUL
+0xC1DA 0xC905 #HANGUL SYLLABLE CIEUC U RIEULKIYEOK
+0xC1DB 0xC906 #HANGUL SYLLABLE CIEUC U RIEULMIEUM
+0xC1DC 0xC90C #HANGUL SYLLABLE CIEUC U MIEUM
+0xC1DD 0xC90D #HANGUL SYLLABLE CIEUC U PIEUP
+0xC1DE 0xC90F #HANGUL SYLLABLE CIEUC U SIOS
+0xC1DF 0xC911 #HANGUL SYLLABLE CIEUC U IEUNG
+0xC1E0 0xC918 #HANGUL SYLLABLE CIEUC WEO
+0xC1E1 0xC92C #HANGUL SYLLABLE CIEUC WEO SSANGSIOS
+0xC1E2 0xC934 #HANGUL SYLLABLE CIEUC WE
+0xC1E3 0xC950 #HANGUL SYLLABLE CIEUC WI
+0xC1E4 0xC951 #HANGUL SYLLABLE CIEUC WI KIYEOK
+0xC1E5 0xC954 #HANGUL SYLLABLE CIEUC WI NIEUN
+0xC1E6 0xC958 #HANGUL SYLLABLE CIEUC WI RIEUL
+0xC1E7 0xC960 #HANGUL SYLLABLE CIEUC WI MIEUM
+0xC1E8 0xC961 #HANGUL SYLLABLE CIEUC WI PIEUP
+0xC1E9 0xC963 #HANGUL SYLLABLE CIEUC WI SIOS
+0xC1EA 0xC96C #HANGUL SYLLABLE CIEUC YU
+0xC1EB 0xC970 #HANGUL SYLLABLE CIEUC YU NIEUN
+0xC1EC 0xC974 #HANGUL SYLLABLE CIEUC YU RIEUL
+0xC1ED 0xC97C #HANGUL SYLLABLE CIEUC YU MIEUM
+0xC1EE 0xC988 #HANGUL SYLLABLE CIEUC EU
+0xC1EF 0xC989 #HANGUL SYLLABLE CIEUC EU KIYEOK
+0xC1F0 0xC98C #HANGUL SYLLABLE CIEUC EU NIEUN
+0xC1F1 0xC990 #HANGUL SYLLABLE CIEUC EU RIEUL
+0xC1F2 0xC998 #HANGUL SYLLABLE CIEUC EU MIEUM
+0xC1F3 0xC999 #HANGUL SYLLABLE CIEUC EU PIEUP
+0xC1F4 0xC99B #HANGUL SYLLABLE CIEUC EU SIOS
+0xC1F5 0xC99D #HANGUL SYLLABLE CIEUC EU IEUNG
+0xC1F6 0xC9C0 #HANGUL SYLLABLE CIEUC I
+0xC1F7 0xC9C1 #HANGUL SYLLABLE CIEUC I KIYEOK
+0xC1F8 0xC9C4 #HANGUL SYLLABLE CIEUC I NIEUN
+0xC1F9 0xC9C7 #HANGUL SYLLABLE CIEUC I TIKEUT
+0xC1FA 0xC9C8 #HANGUL SYLLABLE CIEUC I RIEUL
+0xC1FB 0xC9CA #HANGUL SYLLABLE CIEUC I RIEULMIEUM
+0xC1FC 0xC9D0 #HANGUL SYLLABLE CIEUC I MIEUM
+0xC1FD 0xC9D1 #HANGUL SYLLABLE CIEUC I PIEUP
+0xC1FE 0xC9D3 #HANGUL SYLLABLE CIEUC I SIOS
+0xC241 0xD5CA #HANGUL SYLLABLE HIEUH EO SSANGKIYEOK
+0xC242 0xD5CB #HANGUL SYLLABLE HIEUH EO KIYEOKSIOS
+0xC243 0xD5CD #HANGUL SYLLABLE HIEUH EO NIEUNCIEUC
+0xC244 0xD5CE #HANGUL SYLLABLE HIEUH EO NIEUNHIEUH
+0xC245 0xD5CF #HANGUL SYLLABLE HIEUH EO TIKEUT
+0xC246 0xD5D1 #HANGUL SYLLABLE HIEUH EO RIEULKIYEOK
+0xC247 0xD5D3 #HANGUL SYLLABLE HIEUH EO RIEULPIEUP
+0xC248 0xD5D4 #HANGUL SYLLABLE HIEUH EO RIEULSIOS
+0xC249 0xD5D5 #HANGUL SYLLABLE HIEUH EO RIEULTHIEUTH
+0xC24A 0xD5D6 #HANGUL SYLLABLE HIEUH EO RIEULPHIEUPH
+0xC24B 0xD5D7 #HANGUL SYLLABLE HIEUH EO RIEULHIEUH
+0xC24C 0xD5DA #HANGUL SYLLABLE HIEUH EO PIEUPSIOS
+0xC24D 0xD5DC #HANGUL SYLLABLE HIEUH EO SSANGSIOS
+0xC24E 0xD5DE #HANGUL SYLLABLE HIEUH EO CIEUC
+0xC24F 0xD5DF #HANGUL SYLLABLE HIEUH EO CHIEUCH
+0xC250 0xD5E0 #HANGUL SYLLABLE HIEUH EO KHIEUKH
+0xC251 0xD5E1 #HANGUL SYLLABLE HIEUH EO THIEUTH
+0xC252 0xD5E2 #HANGUL SYLLABLE HIEUH EO PHIEUPH
+0xC253 0xD5E3 #HANGUL SYLLABLE HIEUH EO HIEUH
+0xC254 0xD5E6 #HANGUL SYLLABLE HIEUH E SSANGKIYEOK
+0xC255 0xD5E7 #HANGUL SYLLABLE HIEUH E KIYEOKSIOS
+0xC256 0xD5E9 #HANGUL SYLLABLE HIEUH E NIEUNCIEUC
+0xC257 0xD5EA #HANGUL SYLLABLE HIEUH E NIEUNHIEUH
+0xC258 0xD5EB #HANGUL SYLLABLE HIEUH E TIKEUT
+0xC259 0xD5ED #HANGUL SYLLABLE HIEUH E RIEULKIYEOK
+0xC25A 0xD5EE #HANGUL SYLLABLE HIEUH E RIEULMIEUM
+0xC261 0xD5EF #HANGUL SYLLABLE HIEUH E RIEULPIEUP
+0xC262 0xD5F0 #HANGUL SYLLABLE HIEUH E RIEULSIOS
+0xC263 0xD5F1 #HANGUL SYLLABLE HIEUH E RIEULTHIEUTH
+0xC264 0xD5F2 #HANGUL SYLLABLE HIEUH E RIEULPHIEUPH
+0xC265 0xD5F3 #HANGUL SYLLABLE HIEUH E RIEULHIEUH
+0xC266 0xD5F6 #HANGUL SYLLABLE HIEUH E PIEUPSIOS
+0xC267 0xD5F8 #HANGUL SYLLABLE HIEUH E SSANGSIOS
+0xC268 0xD5FA #HANGUL SYLLABLE HIEUH E CIEUC
+0xC269 0xD5FB #HANGUL SYLLABLE HIEUH E CHIEUCH
+0xC26A 0xD5FC #HANGUL SYLLABLE HIEUH E KHIEUKH
+0xC26B 0xD5FD #HANGUL SYLLABLE HIEUH E THIEUTH
+0xC26C 0xD5FE #HANGUL SYLLABLE HIEUH E PHIEUPH
+0xC26D 0xD5FF #HANGUL SYLLABLE HIEUH E HIEUH
+0xC26E 0xD602 #HANGUL SYLLABLE HIEUH YEO SSANGKIYEOK
+0xC26F 0xD603 #HANGUL SYLLABLE HIEUH YEO KIYEOKSIOS
+0xC270 0xD605 #HANGUL SYLLABLE HIEUH YEO NIEUNCIEUC
+0xC271 0xD606 #HANGUL SYLLABLE HIEUH YEO NIEUNHIEUH
+0xC272 0xD607 #HANGUL SYLLABLE HIEUH YEO TIKEUT
+0xC273 0xD609 #HANGUL SYLLABLE HIEUH YEO RIEULKIYEOK
+0xC274 0xD60A #HANGUL SYLLABLE HIEUH YEO RIEULMIEUM
+0xC275 0xD60B #HANGUL SYLLABLE HIEUH YEO RIEULPIEUP
+0xC276 0xD60C #HANGUL SYLLABLE HIEUH YEO RIEULSIOS
+0xC277 0xD60D #HANGUL SYLLABLE HIEUH YEO RIEULTHIEUTH
+0xC278 0xD60E #HANGUL SYLLABLE HIEUH YEO RIEULPHIEUPH
+0xC279 0xD60F #HANGUL SYLLABLE HIEUH YEO RIEULHIEUH
+0xC27A 0xD612 #HANGUL SYLLABLE HIEUH YEO PIEUPSIOS
+0xC281 0xD616 #HANGUL SYLLABLE HIEUH YEO CIEUC
+0xC282 0xD617 #HANGUL SYLLABLE HIEUH YEO CHIEUCH
+0xC283 0xD618 #HANGUL SYLLABLE HIEUH YEO KHIEUKH
+0xC284 0xD619 #HANGUL SYLLABLE HIEUH YEO THIEUTH
+0xC285 0xD61A #HANGUL SYLLABLE HIEUH YEO PHIEUPH
+0xC286 0xD61B #HANGUL SYLLABLE HIEUH YEO HIEUH
+0xC287 0xD61D #HANGUL SYLLABLE HIEUH YE KIYEOK
+0xC288 0xD61E #HANGUL SYLLABLE HIEUH YE SSANGKIYEOK
+0xC289 0xD61F #HANGUL SYLLABLE HIEUH YE KIYEOKSIOS
+0xC28A 0xD621 #HANGUL SYLLABLE HIEUH YE NIEUNCIEUC
+0xC28B 0xD622 #HANGUL SYLLABLE HIEUH YE NIEUNHIEUH
+0xC28C 0xD623 #HANGUL SYLLABLE HIEUH YE TIKEUT
+0xC28D 0xD625 #HANGUL SYLLABLE HIEUH YE RIEULKIYEOK
+0xC28E 0xD626 #HANGUL SYLLABLE HIEUH YE RIEULMIEUM
+0xC28F 0xD627 #HANGUL SYLLABLE HIEUH YE RIEULPIEUP
+0xC290 0xD628 #HANGUL SYLLABLE HIEUH YE RIEULSIOS
+0xC291 0xD629 #HANGUL SYLLABLE HIEUH YE RIEULTHIEUTH
+0xC292 0xD62A #HANGUL SYLLABLE HIEUH YE RIEULPHIEUPH
+0xC293 0xD62B #HANGUL SYLLABLE HIEUH YE RIEULHIEUH
+0xC294 0xD62C #HANGUL SYLLABLE HIEUH YE MIEUM
+0xC295 0xD62E #HANGUL SYLLABLE HIEUH YE PIEUPSIOS
+0xC296 0xD62F #HANGUL SYLLABLE HIEUH YE SIOS
+0xC297 0xD630 #HANGUL SYLLABLE HIEUH YE SSANGSIOS
+0xC298 0xD631 #HANGUL SYLLABLE HIEUH YE IEUNG
+0xC299 0xD632 #HANGUL SYLLABLE HIEUH YE CIEUC
+0xC29A 0xD633 #HANGUL SYLLABLE HIEUH YE CHIEUCH
+0xC29B 0xD634 #HANGUL SYLLABLE HIEUH YE KHIEUKH
+0xC29C 0xD635 #HANGUL SYLLABLE HIEUH YE THIEUTH
+0xC29D 0xD636 #HANGUL SYLLABLE HIEUH YE PHIEUPH
+0xC29E 0xD637 #HANGUL SYLLABLE HIEUH YE HIEUH
+0xC29F 0xD63A #HANGUL SYLLABLE HIEUH O SSANGKIYEOK
+0xC2A0 0xD63B #HANGUL SYLLABLE HIEUH O KIYEOKSIOS
+0xC2A1 0xC9D5 #HANGUL SYLLABLE CIEUC I IEUNG
+0xC2A2 0xC9D6 #HANGUL SYLLABLE CIEUC I CIEUC
+0xC2A3 0xC9D9 #HANGUL SYLLABLE CIEUC I THIEUTH
+0xC2A4 0xC9DA #HANGUL SYLLABLE CIEUC I PHIEUPH
+0xC2A5 0xC9DC #HANGUL SYLLABLE SSANGCIEUC A
+0xC2A6 0xC9DD #HANGUL SYLLABLE SSANGCIEUC A KIYEOK
+0xC2A7 0xC9E0 #HANGUL SYLLABLE SSANGCIEUC A NIEUN
+0xC2A8 0xC9E2 #HANGUL SYLLABLE SSANGCIEUC A NIEUNHIEUH
+0xC2A9 0xC9E4 #HANGUL SYLLABLE SSANGCIEUC A RIEUL
+0xC2AA 0xC9E7 #HANGUL SYLLABLE SSANGCIEUC A RIEULPIEUP
+0xC2AB 0xC9EC #HANGUL SYLLABLE SSANGCIEUC A MIEUM
+0xC2AC 0xC9ED #HANGUL SYLLABLE SSANGCIEUC A PIEUP
+0xC2AD 0xC9EF #HANGUL SYLLABLE SSANGCIEUC A SIOS
+0xC2AE 0xC9F0 #HANGUL SYLLABLE SSANGCIEUC A SSANGSIOS
+0xC2AF 0xC9F1 #HANGUL SYLLABLE SSANGCIEUC A IEUNG
+0xC2B0 0xC9F8 #HANGUL SYLLABLE SSANGCIEUC AE
+0xC2B1 0xC9F9 #HANGUL SYLLABLE SSANGCIEUC AE KIYEOK
+0xC2B2 0xC9FC #HANGUL SYLLABLE SSANGCIEUC AE NIEUN
+0xC2B3 0xCA00 #HANGUL SYLLABLE SSANGCIEUC AE RIEUL
+0xC2B4 0xCA08 #HANGUL SYLLABLE SSANGCIEUC AE MIEUM
+0xC2B5 0xCA09 #HANGUL SYLLABLE SSANGCIEUC AE PIEUP
+0xC2B6 0xCA0B #HANGUL SYLLABLE SSANGCIEUC AE SIOS
+0xC2B7 0xCA0C #HANGUL SYLLABLE SSANGCIEUC AE SSANGSIOS
+0xC2B8 0xCA0D #HANGUL SYLLABLE SSANGCIEUC AE IEUNG
+0xC2B9 0xCA14 #HANGUL SYLLABLE SSANGCIEUC YA
+0xC2BA 0xCA18 #HANGUL SYLLABLE SSANGCIEUC YA NIEUN
+0xC2BB 0xCA29 #HANGUL SYLLABLE SSANGCIEUC YA IEUNG
+0xC2BC 0xCA4C #HANGUL SYLLABLE SSANGCIEUC EO
+0xC2BD 0xCA4D #HANGUL SYLLABLE SSANGCIEUC EO KIYEOK
+0xC2BE 0xCA50 #HANGUL SYLLABLE SSANGCIEUC EO NIEUN
+0xC2BF 0xCA54 #HANGUL SYLLABLE SSANGCIEUC EO RIEUL
+0xC2C0 0xCA5C #HANGUL SYLLABLE SSANGCIEUC EO MIEUM
+0xC2C1 0xCA5D #HANGUL SYLLABLE SSANGCIEUC EO PIEUP
+0xC2C2 0xCA5F #HANGUL SYLLABLE SSANGCIEUC EO SIOS
+0xC2C3 0xCA60 #HANGUL SYLLABLE SSANGCIEUC EO SSANGSIOS
+0xC2C4 0xCA61 #HANGUL SYLLABLE SSANGCIEUC EO IEUNG
+0xC2C5 0xCA68 #HANGUL SYLLABLE SSANGCIEUC E
+0xC2C6 0xCA7D #HANGUL SYLLABLE SSANGCIEUC E IEUNG
+0xC2C7 0xCA84 #HANGUL SYLLABLE SSANGCIEUC YEO
+0xC2C8 0xCA98 #HANGUL SYLLABLE SSANGCIEUC YEO SSANGSIOS
+0xC2C9 0xCABC #HANGUL SYLLABLE SSANGCIEUC O
+0xC2CA 0xCABD #HANGUL SYLLABLE SSANGCIEUC O KIYEOK
+0xC2CB 0xCAC0 #HANGUL SYLLABLE SSANGCIEUC O NIEUN
+0xC2CC 0xCAC4 #HANGUL SYLLABLE SSANGCIEUC O RIEUL
+0xC2CD 0xCACC #HANGUL SYLLABLE SSANGCIEUC O MIEUM
+0xC2CE 0xCACD #HANGUL SYLLABLE SSANGCIEUC O PIEUP
+0xC2CF 0xCACF #HANGUL SYLLABLE SSANGCIEUC O SIOS
+0xC2D0 0xCAD1 #HANGUL SYLLABLE SSANGCIEUC O IEUNG
+0xC2D1 0xCAD3 #HANGUL SYLLABLE SSANGCIEUC O CHIEUCH
+0xC2D2 0xCAD8 #HANGUL SYLLABLE SSANGCIEUC WA
+0xC2D3 0xCAD9 #HANGUL SYLLABLE SSANGCIEUC WA KIYEOK
+0xC2D4 0xCAE0 #HANGUL SYLLABLE SSANGCIEUC WA RIEUL
+0xC2D5 0xCAEC #HANGUL SYLLABLE SSANGCIEUC WA SSANGSIOS
+0xC2D6 0xCAF4 #HANGUL SYLLABLE SSANGCIEUC WAE
+0xC2D7 0xCB08 #HANGUL SYLLABLE SSANGCIEUC WAE SSANGSIOS
+0xC2D8 0xCB10 #HANGUL SYLLABLE SSANGCIEUC OE
+0xC2D9 0xCB14 #HANGUL SYLLABLE SSANGCIEUC OE NIEUN
+0xC2DA 0xCB18 #HANGUL SYLLABLE SSANGCIEUC OE RIEUL
+0xC2DB 0xCB20 #HANGUL SYLLABLE SSANGCIEUC OE MIEUM
+0xC2DC 0xCB21 #HANGUL SYLLABLE SSANGCIEUC OE PIEUP
+0xC2DD 0xCB41 #HANGUL SYLLABLE SSANGCIEUC YO IEUNG
+0xC2DE 0xCB48 #HANGUL SYLLABLE SSANGCIEUC U
+0xC2DF 0xCB49 #HANGUL SYLLABLE SSANGCIEUC U KIYEOK
+0xC2E0 0xCB4C #HANGUL SYLLABLE SSANGCIEUC U NIEUN
+0xC2E1 0xCB50 #HANGUL SYLLABLE SSANGCIEUC U RIEUL
+0xC2E2 0xCB58 #HANGUL SYLLABLE SSANGCIEUC U MIEUM
+0xC2E3 0xCB59 #HANGUL SYLLABLE SSANGCIEUC U PIEUP
+0xC2E4 0xCB5D #HANGUL SYLLABLE SSANGCIEUC U IEUNG
+0xC2E5 0xCB64 #HANGUL SYLLABLE SSANGCIEUC WEO
+0xC2E6 0xCB78 #HANGUL SYLLABLE SSANGCIEUC WEO SSANGSIOS
+0xC2E7 0xCB79 #HANGUL SYLLABLE SSANGCIEUC WEO IEUNG
+0xC2E8 0xCB9C #HANGUL SYLLABLE SSANGCIEUC WI
+0xC2E9 0xCBB8 #HANGUL SYLLABLE SSANGCIEUC YU
+0xC2EA 0xCBD4 #HANGUL SYLLABLE SSANGCIEUC EU
+0xC2EB 0xCBE4 #HANGUL SYLLABLE SSANGCIEUC EU MIEUM
+0xC2EC 0xCBE7 #HANGUL SYLLABLE SSANGCIEUC EU SIOS
+0xC2ED 0xCBE9 #HANGUL SYLLABLE SSANGCIEUC EU IEUNG
+0xC2EE 0xCC0C #HANGUL SYLLABLE SSANGCIEUC I
+0xC2EF 0xCC0D #HANGUL SYLLABLE SSANGCIEUC I KIYEOK
+0xC2F0 0xCC10 #HANGUL SYLLABLE SSANGCIEUC I NIEUN
+0xC2F1 0xCC14 #HANGUL SYLLABLE SSANGCIEUC I RIEUL
+0xC2F2 0xCC1C #HANGUL SYLLABLE SSANGCIEUC I MIEUM
+0xC2F3 0xCC1D #HANGUL SYLLABLE SSANGCIEUC I PIEUP
+0xC2F4 0xCC21 #HANGUL SYLLABLE SSANGCIEUC I IEUNG
+0xC2F5 0xCC22 #HANGUL SYLLABLE SSANGCIEUC I CIEUC
+0xC2F6 0xCC27 #HANGUL SYLLABLE SSANGCIEUC I HIEUH
+0xC2F7 0xCC28 #HANGUL SYLLABLE CHIEUCH A
+0xC2F8 0xCC29 #HANGUL SYLLABLE CHIEUCH A KIYEOK
+0xC2F9 0xCC2C #HANGUL SYLLABLE CHIEUCH A NIEUN
+0xC2FA 0xCC2E #HANGUL SYLLABLE CHIEUCH A NIEUNHIEUH
+0xC2FB 0xCC30 #HANGUL SYLLABLE CHIEUCH A RIEUL
+0xC2FC 0xCC38 #HANGUL SYLLABLE CHIEUCH A MIEUM
+0xC2FD 0xCC39 #HANGUL SYLLABLE CHIEUCH A PIEUP
+0xC2FE 0xCC3B #HANGUL SYLLABLE CHIEUCH A SIOS
+0xC341 0xD63D #HANGUL SYLLABLE HIEUH O NIEUNCIEUC
+0xC342 0xD63E #HANGUL SYLLABLE HIEUH O NIEUNHIEUH
+0xC343 0xD63F #HANGUL SYLLABLE HIEUH O TIKEUT
+0xC344 0xD641 #HANGUL SYLLABLE HIEUH O RIEULKIYEOK
+0xC345 0xD642 #HANGUL SYLLABLE HIEUH O RIEULMIEUM
+0xC346 0xD643 #HANGUL SYLLABLE HIEUH O RIEULPIEUP
+0xC347 0xD644 #HANGUL SYLLABLE HIEUH O RIEULSIOS
+0xC348 0xD646 #HANGUL SYLLABLE HIEUH O RIEULPHIEUPH
+0xC349 0xD647 #HANGUL SYLLABLE HIEUH O RIEULHIEUH
+0xC34A 0xD64A #HANGUL SYLLABLE HIEUH O PIEUPSIOS
+0xC34B 0xD64C #HANGUL SYLLABLE HIEUH O SSANGSIOS
+0xC34C 0xD64E #HANGUL SYLLABLE HIEUH O CIEUC
+0xC34D 0xD64F #HANGUL SYLLABLE HIEUH O CHIEUCH
+0xC34E 0xD650 #HANGUL SYLLABLE HIEUH O KHIEUKH
+0xC34F 0xD652 #HANGUL SYLLABLE HIEUH O PHIEUPH
+0xC350 0xD653 #HANGUL SYLLABLE HIEUH O HIEUH
+0xC351 0xD656 #HANGUL SYLLABLE HIEUH WA SSANGKIYEOK
+0xC352 0xD657 #HANGUL SYLLABLE HIEUH WA KIYEOKSIOS
+0xC353 0xD659 #HANGUL SYLLABLE HIEUH WA NIEUNCIEUC
+0xC354 0xD65A #HANGUL SYLLABLE HIEUH WA NIEUNHIEUH
+0xC355 0xD65B #HANGUL SYLLABLE HIEUH WA TIKEUT
+0xC356 0xD65D #HANGUL SYLLABLE HIEUH WA RIEULKIYEOK
+0xC357 0xD65E #HANGUL SYLLABLE HIEUH WA RIEULMIEUM
+0xC358 0xD65F #HANGUL SYLLABLE HIEUH WA RIEULPIEUP
+0xC359 0xD660 #HANGUL SYLLABLE HIEUH WA RIEULSIOS
+0xC35A 0xD661 #HANGUL SYLLABLE HIEUH WA RIEULTHIEUTH
+0xC361 0xD662 #HANGUL SYLLABLE HIEUH WA RIEULPHIEUPH
+0xC362 0xD663 #HANGUL SYLLABLE HIEUH WA RIEULHIEUH
+0xC363 0xD664 #HANGUL SYLLABLE HIEUH WA MIEUM
+0xC364 0xD665 #HANGUL SYLLABLE HIEUH WA PIEUP
+0xC365 0xD666 #HANGUL SYLLABLE HIEUH WA PIEUPSIOS
+0xC366 0xD668 #HANGUL SYLLABLE HIEUH WA SSANGSIOS
+0xC367 0xD66A #HANGUL SYLLABLE HIEUH WA CIEUC
+0xC368 0xD66B #HANGUL SYLLABLE HIEUH WA CHIEUCH
+0xC369 0xD66C #HANGUL SYLLABLE HIEUH WA KHIEUKH
+0xC36A 0xD66D #HANGUL SYLLABLE HIEUH WA THIEUTH
+0xC36B 0xD66E #HANGUL SYLLABLE HIEUH WA PHIEUPH
+0xC36C 0xD66F #HANGUL SYLLABLE HIEUH WA HIEUH
+0xC36D 0xD672 #HANGUL SYLLABLE HIEUH WAE SSANGKIYEOK
+0xC36E 0xD673 #HANGUL SYLLABLE HIEUH WAE KIYEOKSIOS
+0xC36F 0xD675 #HANGUL SYLLABLE HIEUH WAE NIEUNCIEUC
+0xC370 0xD676 #HANGUL SYLLABLE HIEUH WAE NIEUNHIEUH
+0xC371 0xD677 #HANGUL SYLLABLE HIEUH WAE TIKEUT
+0xC372 0xD678 #HANGUL SYLLABLE HIEUH WAE RIEUL
+0xC373 0xD679 #HANGUL SYLLABLE HIEUH WAE RIEULKIYEOK
+0xC374 0xD67A #HANGUL SYLLABLE HIEUH WAE RIEULMIEUM
+0xC375 0xD67B #HANGUL SYLLABLE HIEUH WAE RIEULPIEUP
+0xC376 0xD67C #HANGUL SYLLABLE HIEUH WAE RIEULSIOS
+0xC377 0xD67D #HANGUL SYLLABLE HIEUH WAE RIEULTHIEUTH
+0xC378 0xD67E #HANGUL SYLLABLE HIEUH WAE RIEULPHIEUPH
+0xC379 0xD67F #HANGUL SYLLABLE HIEUH WAE RIEULHIEUH
+0xC37A 0xD680 #HANGUL SYLLABLE HIEUH WAE MIEUM
+0xC381 0xD681 #HANGUL SYLLABLE HIEUH WAE PIEUP
+0xC382 0xD682 #HANGUL SYLLABLE HIEUH WAE PIEUPSIOS
+0xC383 0xD684 #HANGUL SYLLABLE HIEUH WAE SSANGSIOS
+0xC384 0xD686 #HANGUL SYLLABLE HIEUH WAE CIEUC
+0xC385 0xD687 #HANGUL SYLLABLE HIEUH WAE CHIEUCH
+0xC386 0xD688 #HANGUL SYLLABLE HIEUH WAE KHIEUKH
+0xC387 0xD689 #HANGUL SYLLABLE HIEUH WAE THIEUTH
+0xC388 0xD68A #HANGUL SYLLABLE HIEUH WAE PHIEUPH
+0xC389 0xD68B #HANGUL SYLLABLE HIEUH WAE HIEUH
+0xC38A 0xD68E #HANGUL SYLLABLE HIEUH OE SSANGKIYEOK
+0xC38B 0xD68F #HANGUL SYLLABLE HIEUH OE KIYEOKSIOS
+0xC38C 0xD691 #HANGUL SYLLABLE HIEUH OE NIEUNCIEUC
+0xC38D 0xD692 #HANGUL SYLLABLE HIEUH OE NIEUNHIEUH
+0xC38E 0xD693 #HANGUL SYLLABLE HIEUH OE TIKEUT
+0xC38F 0xD695 #HANGUL SYLLABLE HIEUH OE RIEULKIYEOK
+0xC390 0xD696 #HANGUL SYLLABLE HIEUH OE RIEULMIEUM
+0xC391 0xD697 #HANGUL SYLLABLE HIEUH OE RIEULPIEUP
+0xC392 0xD698 #HANGUL SYLLABLE HIEUH OE RIEULSIOS
+0xC393 0xD699 #HANGUL SYLLABLE HIEUH OE RIEULTHIEUTH
+0xC394 0xD69A #HANGUL SYLLABLE HIEUH OE RIEULPHIEUPH
+0xC395 0xD69B #HANGUL SYLLABLE HIEUH OE RIEULHIEUH
+0xC396 0xD69C #HANGUL SYLLABLE HIEUH OE MIEUM
+0xC397 0xD69E #HANGUL SYLLABLE HIEUH OE PIEUPSIOS
+0xC398 0xD6A0 #HANGUL SYLLABLE HIEUH OE SSANGSIOS
+0xC399 0xD6A2 #HANGUL SYLLABLE HIEUH OE CIEUC
+0xC39A 0xD6A3 #HANGUL SYLLABLE HIEUH OE CHIEUCH
+0xC39B 0xD6A4 #HANGUL SYLLABLE HIEUH OE KHIEUKH
+0xC39C 0xD6A5 #HANGUL SYLLABLE HIEUH OE THIEUTH
+0xC39D 0xD6A6 #HANGUL SYLLABLE HIEUH OE PHIEUPH
+0xC39E 0xD6A7 #HANGUL SYLLABLE HIEUH OE HIEUH
+0xC39F 0xD6A9 #HANGUL SYLLABLE HIEUH YO KIYEOK
+0xC3A0 0xD6AA #HANGUL SYLLABLE HIEUH YO SSANGKIYEOK
+0xC3A1 0xCC3C #HANGUL SYLLABLE CHIEUCH A SSANGSIOS
+0xC3A2 0xCC3D #HANGUL SYLLABLE CHIEUCH A IEUNG
+0xC3A3 0xCC3E #HANGUL SYLLABLE CHIEUCH A CIEUC
+0xC3A4 0xCC44 #HANGUL SYLLABLE CHIEUCH AE
+0xC3A5 0xCC45 #HANGUL SYLLABLE CHIEUCH AE KIYEOK
+0xC3A6 0xCC48 #HANGUL SYLLABLE CHIEUCH AE NIEUN
+0xC3A7 0xCC4C #HANGUL SYLLABLE CHIEUCH AE RIEUL
+0xC3A8 0xCC54 #HANGUL SYLLABLE CHIEUCH AE MIEUM
+0xC3A9 0xCC55 #HANGUL SYLLABLE CHIEUCH AE PIEUP
+0xC3AA 0xCC57 #HANGUL SYLLABLE CHIEUCH AE SIOS
+0xC3AB 0xCC58 #HANGUL SYLLABLE CHIEUCH AE SSANGSIOS
+0xC3AC 0xCC59 #HANGUL SYLLABLE CHIEUCH AE IEUNG
+0xC3AD 0xCC60 #HANGUL SYLLABLE CHIEUCH YA
+0xC3AE 0xCC64 #HANGUL SYLLABLE CHIEUCH YA NIEUN
+0xC3AF 0xCC66 #HANGUL SYLLABLE CHIEUCH YA NIEUNHIEUH
+0xC3B0 0xCC68 #HANGUL SYLLABLE CHIEUCH YA RIEUL
+0xC3B1 0xCC70 #HANGUL SYLLABLE CHIEUCH YA MIEUM
+0xC3B2 0xCC75 #HANGUL SYLLABLE CHIEUCH YA IEUNG
+0xC3B3 0xCC98 #HANGUL SYLLABLE CHIEUCH EO
+0xC3B4 0xCC99 #HANGUL SYLLABLE CHIEUCH EO KIYEOK
+0xC3B5 0xCC9C #HANGUL SYLLABLE CHIEUCH EO NIEUN
+0xC3B6 0xCCA0 #HANGUL SYLLABLE CHIEUCH EO RIEUL
+0xC3B7 0xCCA8 #HANGUL SYLLABLE CHIEUCH EO MIEUM
+0xC3B8 0xCCA9 #HANGUL SYLLABLE CHIEUCH EO PIEUP
+0xC3B9 0xCCAB #HANGUL SYLLABLE CHIEUCH EO SIOS
+0xC3BA 0xCCAC #HANGUL SYLLABLE CHIEUCH EO SSANGSIOS
+0xC3BB 0xCCAD #HANGUL SYLLABLE CHIEUCH EO IEUNG
+0xC3BC 0xCCB4 #HANGUL SYLLABLE CHIEUCH E
+0xC3BD 0xCCB5 #HANGUL SYLLABLE CHIEUCH E KIYEOK
+0xC3BE 0xCCB8 #HANGUL SYLLABLE CHIEUCH E NIEUN
+0xC3BF 0xCCBC #HANGUL SYLLABLE CHIEUCH E RIEUL
+0xC3C0 0xCCC4 #HANGUL SYLLABLE CHIEUCH E MIEUM
+0xC3C1 0xCCC5 #HANGUL SYLLABLE CHIEUCH E PIEUP
+0xC3C2 0xCCC7 #HANGUL SYLLABLE CHIEUCH E SIOS
+0xC3C3 0xCCC9 #HANGUL SYLLABLE CHIEUCH E IEUNG
+0xC3C4 0xCCD0 #HANGUL SYLLABLE CHIEUCH YEO
+0xC3C5 0xCCD4 #HANGUL SYLLABLE CHIEUCH YEO NIEUN
+0xC3C6 0xCCE4 #HANGUL SYLLABLE CHIEUCH YEO SSANGSIOS
+0xC3C7 0xCCEC #HANGUL SYLLABLE CHIEUCH YE
+0xC3C8 0xCCF0 #HANGUL SYLLABLE CHIEUCH YE NIEUN
+0xC3C9 0xCD01 #HANGUL SYLLABLE CHIEUCH YE IEUNG
+0xC3CA 0xCD08 #HANGUL SYLLABLE CHIEUCH O
+0xC3CB 0xCD09 #HANGUL SYLLABLE CHIEUCH O KIYEOK
+0xC3CC 0xCD0C #HANGUL SYLLABLE CHIEUCH O NIEUN
+0xC3CD 0xCD10 #HANGUL SYLLABLE CHIEUCH O RIEUL
+0xC3CE 0xCD18 #HANGUL SYLLABLE CHIEUCH O MIEUM
+0xC3CF 0xCD19 #HANGUL SYLLABLE CHIEUCH O PIEUP
+0xC3D0 0xCD1B #HANGUL SYLLABLE CHIEUCH O SIOS
+0xC3D1 0xCD1D #HANGUL SYLLABLE CHIEUCH O IEUNG
+0xC3D2 0xCD24 #HANGUL SYLLABLE CHIEUCH WA
+0xC3D3 0xCD28 #HANGUL SYLLABLE CHIEUCH WA NIEUN
+0xC3D4 0xCD2C #HANGUL SYLLABLE CHIEUCH WA RIEUL
+0xC3D5 0xCD39 #HANGUL SYLLABLE CHIEUCH WA IEUNG
+0xC3D6 0xCD5C #HANGUL SYLLABLE CHIEUCH OE
+0xC3D7 0xCD60 #HANGUL SYLLABLE CHIEUCH OE NIEUN
+0xC3D8 0xCD64 #HANGUL SYLLABLE CHIEUCH OE RIEUL
+0xC3D9 0xCD6C #HANGUL SYLLABLE CHIEUCH OE MIEUM
+0xC3DA 0xCD6D #HANGUL SYLLABLE CHIEUCH OE PIEUP
+0xC3DB 0xCD6F #HANGUL SYLLABLE CHIEUCH OE SIOS
+0xC3DC 0xCD71 #HANGUL SYLLABLE CHIEUCH OE IEUNG
+0xC3DD 0xCD78 #HANGUL SYLLABLE CHIEUCH YO
+0xC3DE 0xCD88 #HANGUL SYLLABLE CHIEUCH YO MIEUM
+0xC3DF 0xCD94 #HANGUL SYLLABLE CHIEUCH U
+0xC3E0 0xCD95 #HANGUL SYLLABLE CHIEUCH U KIYEOK
+0xC3E1 0xCD98 #HANGUL SYLLABLE CHIEUCH U NIEUN
+0xC3E2 0xCD9C #HANGUL SYLLABLE CHIEUCH U RIEUL
+0xC3E3 0xCDA4 #HANGUL SYLLABLE CHIEUCH U MIEUM
+0xC3E4 0xCDA5 #HANGUL SYLLABLE CHIEUCH U PIEUP
+0xC3E5 0xCDA7 #HANGUL SYLLABLE CHIEUCH U SIOS
+0xC3E6 0xCDA9 #HANGUL SYLLABLE CHIEUCH U IEUNG
+0xC3E7 0xCDB0 #HANGUL SYLLABLE CHIEUCH WEO
+0xC3E8 0xCDC4 #HANGUL SYLLABLE CHIEUCH WEO SSANGSIOS
+0xC3E9 0xCDCC #HANGUL SYLLABLE CHIEUCH WE
+0xC3EA 0xCDD0 #HANGUL SYLLABLE CHIEUCH WE NIEUN
+0xC3EB 0xCDE8 #HANGUL SYLLABLE CHIEUCH WI
+0xC3EC 0xCDEC #HANGUL SYLLABLE CHIEUCH WI NIEUN
+0xC3ED 0xCDF0 #HANGUL SYLLABLE CHIEUCH WI RIEUL
+0xC3EE 0xCDF8 #HANGUL SYLLABLE CHIEUCH WI MIEUM
+0xC3EF 0xCDF9 #HANGUL SYLLABLE CHIEUCH WI PIEUP
+0xC3F0 0xCDFB #HANGUL SYLLABLE CHIEUCH WI SIOS
+0xC3F1 0xCDFD #HANGUL SYLLABLE CHIEUCH WI IEUNG
+0xC3F2 0xCE04 #HANGUL SYLLABLE CHIEUCH YU
+0xC3F3 0xCE08 #HANGUL SYLLABLE CHIEUCH YU NIEUN
+0xC3F4 0xCE0C #HANGUL SYLLABLE CHIEUCH YU RIEUL
+0xC3F5 0xCE14 #HANGUL SYLLABLE CHIEUCH YU MIEUM
+0xC3F6 0xCE19 #HANGUL SYLLABLE CHIEUCH YU IEUNG
+0xC3F7 0xCE20 #HANGUL SYLLABLE CHIEUCH EU
+0xC3F8 0xCE21 #HANGUL SYLLABLE CHIEUCH EU KIYEOK
+0xC3F9 0xCE24 #HANGUL SYLLABLE CHIEUCH EU NIEUN
+0xC3FA 0xCE28 #HANGUL SYLLABLE CHIEUCH EU RIEUL
+0xC3FB 0xCE30 #HANGUL SYLLABLE CHIEUCH EU MIEUM
+0xC3FC 0xCE31 #HANGUL SYLLABLE CHIEUCH EU PIEUP
+0xC3FD 0xCE33 #HANGUL SYLLABLE CHIEUCH EU SIOS
+0xC3FE 0xCE35 #HANGUL SYLLABLE CHIEUCH EU IEUNG
+0xC441 0xD6AB #HANGUL SYLLABLE HIEUH YO KIYEOKSIOS
+0xC442 0xD6AD #HANGUL SYLLABLE HIEUH YO NIEUNCIEUC
+0xC443 0xD6AE #HANGUL SYLLABLE HIEUH YO NIEUNHIEUH
+0xC444 0xD6AF #HANGUL SYLLABLE HIEUH YO TIKEUT
+0xC445 0xD6B1 #HANGUL SYLLABLE HIEUH YO RIEULKIYEOK
+0xC446 0xD6B2 #HANGUL SYLLABLE HIEUH YO RIEULMIEUM
+0xC447 0xD6B3 #HANGUL SYLLABLE HIEUH YO RIEULPIEUP
+0xC448 0xD6B4 #HANGUL SYLLABLE HIEUH YO RIEULSIOS
+0xC449 0xD6B5 #HANGUL SYLLABLE HIEUH YO RIEULTHIEUTH
+0xC44A 0xD6B6 #HANGUL SYLLABLE HIEUH YO RIEULPHIEUPH
+0xC44B 0xD6B7 #HANGUL SYLLABLE HIEUH YO RIEULHIEUH
+0xC44C 0xD6B8 #HANGUL SYLLABLE HIEUH YO MIEUM
+0xC44D 0xD6BA #HANGUL SYLLABLE HIEUH YO PIEUPSIOS
+0xC44E 0xD6BC #HANGUL SYLLABLE HIEUH YO SSANGSIOS
+0xC44F 0xD6BD #HANGUL SYLLABLE HIEUH YO IEUNG
+0xC450 0xD6BE #HANGUL SYLLABLE HIEUH YO CIEUC
+0xC451 0xD6BF #HANGUL SYLLABLE HIEUH YO CHIEUCH
+0xC452 0xD6C0 #HANGUL SYLLABLE HIEUH YO KHIEUKH
+0xC453 0xD6C1 #HANGUL SYLLABLE HIEUH YO THIEUTH
+0xC454 0xD6C2 #HANGUL SYLLABLE HIEUH YO PHIEUPH
+0xC455 0xD6C3 #HANGUL SYLLABLE HIEUH YO HIEUH
+0xC456 0xD6C6 #HANGUL SYLLABLE HIEUH U SSANGKIYEOK
+0xC457 0xD6C7 #HANGUL SYLLABLE HIEUH U KIYEOKSIOS
+0xC458 0xD6C9 #HANGUL SYLLABLE HIEUH U NIEUNCIEUC
+0xC459 0xD6CA #HANGUL SYLLABLE HIEUH U NIEUNHIEUH
+0xC45A 0xD6CB #HANGUL SYLLABLE HIEUH U TIKEUT
+0xC461 0xD6CD #HANGUL SYLLABLE HIEUH U RIEULKIYEOK
+0xC462 0xD6CE #HANGUL SYLLABLE HIEUH U RIEULMIEUM
+0xC463 0xD6CF #HANGUL SYLLABLE HIEUH U RIEULPIEUP
+0xC464 0xD6D0 #HANGUL SYLLABLE HIEUH U RIEULSIOS
+0xC465 0xD6D2 #HANGUL SYLLABLE HIEUH U RIEULPHIEUPH
+0xC466 0xD6D3 #HANGUL SYLLABLE HIEUH U RIEULHIEUH
+0xC467 0xD6D5 #HANGUL SYLLABLE HIEUH U PIEUP
+0xC468 0xD6D6 #HANGUL SYLLABLE HIEUH U PIEUPSIOS
+0xC469 0xD6D8 #HANGUL SYLLABLE HIEUH U SSANGSIOS
+0xC46A 0xD6DA #HANGUL SYLLABLE HIEUH U CIEUC
+0xC46B 0xD6DB #HANGUL SYLLABLE HIEUH U CHIEUCH
+0xC46C 0xD6DC #HANGUL SYLLABLE HIEUH U KHIEUKH
+0xC46D 0xD6DD #HANGUL SYLLABLE HIEUH U THIEUTH
+0xC46E 0xD6DE #HANGUL SYLLABLE HIEUH U PHIEUPH
+0xC46F 0xD6DF #HANGUL SYLLABLE HIEUH U HIEUH
+0xC470 0xD6E1 #HANGUL SYLLABLE HIEUH WEO KIYEOK
+0xC471 0xD6E2 #HANGUL SYLLABLE HIEUH WEO SSANGKIYEOK
+0xC472 0xD6E3 #HANGUL SYLLABLE HIEUH WEO KIYEOKSIOS
+0xC473 0xD6E5 #HANGUL SYLLABLE HIEUH WEO NIEUNCIEUC
+0xC474 0xD6E6 #HANGUL SYLLABLE HIEUH WEO NIEUNHIEUH
+0xC475 0xD6E7 #HANGUL SYLLABLE HIEUH WEO TIKEUT
+0xC476 0xD6E9 #HANGUL SYLLABLE HIEUH WEO RIEULKIYEOK
+0xC477 0xD6EA #HANGUL SYLLABLE HIEUH WEO RIEULMIEUM
+0xC478 0xD6EB #HANGUL SYLLABLE HIEUH WEO RIEULPIEUP
+0xC479 0xD6EC #HANGUL SYLLABLE HIEUH WEO RIEULSIOS
+0xC47A 0xD6ED #HANGUL SYLLABLE HIEUH WEO RIEULTHIEUTH
+0xC481 0xD6EE #HANGUL SYLLABLE HIEUH WEO RIEULPHIEUPH
+0xC482 0xD6EF #HANGUL SYLLABLE HIEUH WEO RIEULHIEUH
+0xC483 0xD6F1 #HANGUL SYLLABLE HIEUH WEO PIEUP
+0xC484 0xD6F2 #HANGUL SYLLABLE HIEUH WEO PIEUPSIOS
+0xC485 0xD6F3 #HANGUL SYLLABLE HIEUH WEO SIOS
+0xC486 0xD6F4 #HANGUL SYLLABLE HIEUH WEO SSANGSIOS
+0xC487 0xD6F6 #HANGUL SYLLABLE HIEUH WEO CIEUC
+0xC488 0xD6F7 #HANGUL SYLLABLE HIEUH WEO CHIEUCH
+0xC489 0xD6F8 #HANGUL SYLLABLE HIEUH WEO KHIEUKH
+0xC48A 0xD6F9 #HANGUL SYLLABLE HIEUH WEO THIEUTH
+0xC48B 0xD6FA #HANGUL SYLLABLE HIEUH WEO PHIEUPH
+0xC48C 0xD6FB #HANGUL SYLLABLE HIEUH WEO HIEUH
+0xC48D 0xD6FE #HANGUL SYLLABLE HIEUH WE SSANGKIYEOK
+0xC48E 0xD6FF #HANGUL SYLLABLE HIEUH WE KIYEOKSIOS
+0xC48F 0xD701 #HANGUL SYLLABLE HIEUH WE NIEUNCIEUC
+0xC490 0xD702 #HANGUL SYLLABLE HIEUH WE NIEUNHIEUH
+0xC491 0xD703 #HANGUL SYLLABLE HIEUH WE TIKEUT
+0xC492 0xD705 #HANGUL SYLLABLE HIEUH WE RIEULKIYEOK
+0xC493 0xD706 #HANGUL SYLLABLE HIEUH WE RIEULMIEUM
+0xC494 0xD707 #HANGUL SYLLABLE HIEUH WE RIEULPIEUP
+0xC495 0xD708 #HANGUL SYLLABLE HIEUH WE RIEULSIOS
+0xC496 0xD709 #HANGUL SYLLABLE HIEUH WE RIEULTHIEUTH
+0xC497 0xD70A #HANGUL SYLLABLE HIEUH WE RIEULPHIEUPH
+0xC498 0xD70B #HANGUL SYLLABLE HIEUH WE RIEULHIEUH
+0xC499 0xD70C #HANGUL SYLLABLE HIEUH WE MIEUM
+0xC49A 0xD70D #HANGUL SYLLABLE HIEUH WE PIEUP
+0xC49B 0xD70E #HANGUL SYLLABLE HIEUH WE PIEUPSIOS
+0xC49C 0xD70F #HANGUL SYLLABLE HIEUH WE SIOS
+0xC49D 0xD710 #HANGUL SYLLABLE HIEUH WE SSANGSIOS
+0xC49E 0xD712 #HANGUL SYLLABLE HIEUH WE CIEUC
+0xC49F 0xD713 #HANGUL SYLLABLE HIEUH WE CHIEUCH
+0xC4A0 0xD714 #HANGUL SYLLABLE HIEUH WE KHIEUKH
+0xC4A1 0xCE58 #HANGUL SYLLABLE CHIEUCH I
+0xC4A2 0xCE59 #HANGUL SYLLABLE CHIEUCH I KIYEOK
+0xC4A3 0xCE5C #HANGUL SYLLABLE CHIEUCH I NIEUN
+0xC4A4 0xCE5F #HANGUL SYLLABLE CHIEUCH I TIKEUT
+0xC4A5 0xCE60 #HANGUL SYLLABLE CHIEUCH I RIEUL
+0xC4A6 0xCE61 #HANGUL SYLLABLE CHIEUCH I RIEULKIYEOK
+0xC4A7 0xCE68 #HANGUL SYLLABLE CHIEUCH I MIEUM
+0xC4A8 0xCE69 #HANGUL SYLLABLE CHIEUCH I PIEUP
+0xC4A9 0xCE6B #HANGUL SYLLABLE CHIEUCH I SIOS
+0xC4AA 0xCE6D #HANGUL SYLLABLE CHIEUCH I IEUNG
+0xC4AB 0xCE74 #HANGUL SYLLABLE KHIEUKH A
+0xC4AC 0xCE75 #HANGUL SYLLABLE KHIEUKH A KIYEOK
+0xC4AD 0xCE78 #HANGUL SYLLABLE KHIEUKH A NIEUN
+0xC4AE 0xCE7C #HANGUL SYLLABLE KHIEUKH A RIEUL
+0xC4AF 0xCE84 #HANGUL SYLLABLE KHIEUKH A MIEUM
+0xC4B0 0xCE85 #HANGUL SYLLABLE KHIEUKH A PIEUP
+0xC4B1 0xCE87 #HANGUL SYLLABLE KHIEUKH A SIOS
+0xC4B2 0xCE89 #HANGUL SYLLABLE KHIEUKH A IEUNG
+0xC4B3 0xCE90 #HANGUL SYLLABLE KHIEUKH AE
+0xC4B4 0xCE91 #HANGUL SYLLABLE KHIEUKH AE KIYEOK
+0xC4B5 0xCE94 #HANGUL SYLLABLE KHIEUKH AE NIEUN
+0xC4B6 0xCE98 #HANGUL SYLLABLE KHIEUKH AE RIEUL
+0xC4B7 0xCEA0 #HANGUL SYLLABLE KHIEUKH AE MIEUM
+0xC4B8 0xCEA1 #HANGUL SYLLABLE KHIEUKH AE PIEUP
+0xC4B9 0xCEA3 #HANGUL SYLLABLE KHIEUKH AE SIOS
+0xC4BA 0xCEA4 #HANGUL SYLLABLE KHIEUKH AE SSANGSIOS
+0xC4BB 0xCEA5 #HANGUL SYLLABLE KHIEUKH AE IEUNG
+0xC4BC 0xCEAC #HANGUL SYLLABLE KHIEUKH YA
+0xC4BD 0xCEAD #HANGUL SYLLABLE KHIEUKH YA KIYEOK
+0xC4BE 0xCEC1 #HANGUL SYLLABLE KHIEUKH YA IEUNG
+0xC4BF 0xCEE4 #HANGUL SYLLABLE KHIEUKH EO
+0xC4C0 0xCEE5 #HANGUL SYLLABLE KHIEUKH EO KIYEOK
+0xC4C1 0xCEE8 #HANGUL SYLLABLE KHIEUKH EO NIEUN
+0xC4C2 0xCEEB #HANGUL SYLLABLE KHIEUKH EO TIKEUT
+0xC4C3 0xCEEC #HANGUL SYLLABLE KHIEUKH EO RIEUL
+0xC4C4 0xCEF4 #HANGUL SYLLABLE KHIEUKH EO MIEUM
+0xC4C5 0xCEF5 #HANGUL SYLLABLE KHIEUKH EO PIEUP
+0xC4C6 0xCEF7 #HANGUL SYLLABLE KHIEUKH EO SIOS
+0xC4C7 0xCEF8 #HANGUL SYLLABLE KHIEUKH EO SSANGSIOS
+0xC4C8 0xCEF9 #HANGUL SYLLABLE KHIEUKH EO IEUNG
+0xC4C9 0xCF00 #HANGUL SYLLABLE KHIEUKH E
+0xC4CA 0xCF01 #HANGUL SYLLABLE KHIEUKH E KIYEOK
+0xC4CB 0xCF04 #HANGUL SYLLABLE KHIEUKH E NIEUN
+0xC4CC 0xCF08 #HANGUL SYLLABLE KHIEUKH E RIEUL
+0xC4CD 0xCF10 #HANGUL SYLLABLE KHIEUKH E MIEUM
+0xC4CE 0xCF11 #HANGUL SYLLABLE KHIEUKH E PIEUP
+0xC4CF 0xCF13 #HANGUL SYLLABLE KHIEUKH E SIOS
+0xC4D0 0xCF15 #HANGUL SYLLABLE KHIEUKH E IEUNG
+0xC4D1 0xCF1C #HANGUL SYLLABLE KHIEUKH YEO
+0xC4D2 0xCF20 #HANGUL SYLLABLE KHIEUKH YEO NIEUN
+0xC4D3 0xCF24 #HANGUL SYLLABLE KHIEUKH YEO RIEUL
+0xC4D4 0xCF2C #HANGUL SYLLABLE KHIEUKH YEO MIEUM
+0xC4D5 0xCF2D #HANGUL SYLLABLE KHIEUKH YEO PIEUP
+0xC4D6 0xCF2F #HANGUL SYLLABLE KHIEUKH YEO SIOS
+0xC4D7 0xCF30 #HANGUL SYLLABLE KHIEUKH YEO SSANGSIOS
+0xC4D8 0xCF31 #HANGUL SYLLABLE KHIEUKH YEO IEUNG
+0xC4D9 0xCF38 #HANGUL SYLLABLE KHIEUKH YE
+0xC4DA 0xCF54 #HANGUL SYLLABLE KHIEUKH O
+0xC4DB 0xCF55 #HANGUL SYLLABLE KHIEUKH O KIYEOK
+0xC4DC 0xCF58 #HANGUL SYLLABLE KHIEUKH O NIEUN
+0xC4DD 0xCF5C #HANGUL SYLLABLE KHIEUKH O RIEUL
+0xC4DE 0xCF64 #HANGUL SYLLABLE KHIEUKH O MIEUM
+0xC4DF 0xCF65 #HANGUL SYLLABLE KHIEUKH O PIEUP
+0xC4E0 0xCF67 #HANGUL SYLLABLE KHIEUKH O SIOS
+0xC4E1 0xCF69 #HANGUL SYLLABLE KHIEUKH O IEUNG
+0xC4E2 0xCF70 #HANGUL SYLLABLE KHIEUKH WA
+0xC4E3 0xCF71 #HANGUL SYLLABLE KHIEUKH WA KIYEOK
+0xC4E4 0xCF74 #HANGUL SYLLABLE KHIEUKH WA NIEUN
+0xC4E5 0xCF78 #HANGUL SYLLABLE KHIEUKH WA RIEUL
+0xC4E6 0xCF80 #HANGUL SYLLABLE KHIEUKH WA MIEUM
+0xC4E7 0xCF85 #HANGUL SYLLABLE KHIEUKH WA IEUNG
+0xC4E8 0xCF8C #HANGUL SYLLABLE KHIEUKH WAE
+0xC4E9 0xCFA1 #HANGUL SYLLABLE KHIEUKH WAE IEUNG
+0xC4EA 0xCFA8 #HANGUL SYLLABLE KHIEUKH OE
+0xC4EB 0xCFB0 #HANGUL SYLLABLE KHIEUKH OE RIEUL
+0xC4EC 0xCFC4 #HANGUL SYLLABLE KHIEUKH YO
+0xC4ED 0xCFE0 #HANGUL SYLLABLE KHIEUKH U
+0xC4EE 0xCFE1 #HANGUL SYLLABLE KHIEUKH U KIYEOK
+0xC4EF 0xCFE4 #HANGUL SYLLABLE KHIEUKH U NIEUN
+0xC4F0 0xCFE8 #HANGUL SYLLABLE KHIEUKH U RIEUL
+0xC4F1 0xCFF0 #HANGUL SYLLABLE KHIEUKH U MIEUM
+0xC4F2 0xCFF1 #HANGUL SYLLABLE KHIEUKH U PIEUP
+0xC4F3 0xCFF3 #HANGUL SYLLABLE KHIEUKH U SIOS
+0xC4F4 0xCFF5 #HANGUL SYLLABLE KHIEUKH U IEUNG
+0xC4F5 0xCFFC #HANGUL SYLLABLE KHIEUKH WEO
+0xC4F6 0xD000 #HANGUL SYLLABLE KHIEUKH WEO NIEUN
+0xC4F7 0xD004 #HANGUL SYLLABLE KHIEUKH WEO RIEUL
+0xC4F8 0xD011 #HANGUL SYLLABLE KHIEUKH WEO IEUNG
+0xC4F9 0xD018 #HANGUL SYLLABLE KHIEUKH WE
+0xC4FA 0xD02D #HANGUL SYLLABLE KHIEUKH WE IEUNG
+0xC4FB 0xD034 #HANGUL SYLLABLE KHIEUKH WI
+0xC4FC 0xD035 #HANGUL SYLLABLE KHIEUKH WI KIYEOK
+0xC4FD 0xD038 #HANGUL SYLLABLE KHIEUKH WI NIEUN
+0xC4FE 0xD03C #HANGUL SYLLABLE KHIEUKH WI RIEUL
+0xC541 0xD715 #HANGUL SYLLABLE HIEUH WE THIEUTH
+0xC542 0xD716 #HANGUL SYLLABLE HIEUH WE PHIEUPH
+0xC543 0xD717 #HANGUL SYLLABLE HIEUH WE HIEUH
+0xC544 0xD71A #HANGUL SYLLABLE HIEUH WI SSANGKIYEOK
+0xC545 0xD71B #HANGUL SYLLABLE HIEUH WI KIYEOKSIOS
+0xC546 0xD71D #HANGUL SYLLABLE HIEUH WI NIEUNCIEUC
+0xC547 0xD71E #HANGUL SYLLABLE HIEUH WI NIEUNHIEUH
+0xC548 0xD71F #HANGUL SYLLABLE HIEUH WI TIKEUT
+0xC549 0xD721 #HANGUL SYLLABLE HIEUH WI RIEULKIYEOK
+0xC54A 0xD722 #HANGUL SYLLABLE HIEUH WI RIEULMIEUM
+0xC54B 0xD723 #HANGUL SYLLABLE HIEUH WI RIEULPIEUP
+0xC54C 0xD724 #HANGUL SYLLABLE HIEUH WI RIEULSIOS
+0xC54D 0xD725 #HANGUL SYLLABLE HIEUH WI RIEULTHIEUTH
+0xC54E 0xD726 #HANGUL SYLLABLE HIEUH WI RIEULPHIEUPH
+0xC54F 0xD727 #HANGUL SYLLABLE HIEUH WI RIEULHIEUH
+0xC550 0xD72A #HANGUL SYLLABLE HIEUH WI PIEUPSIOS
+0xC551 0xD72C #HANGUL SYLLABLE HIEUH WI SSANGSIOS
+0xC552 0xD72E #HANGUL SYLLABLE HIEUH WI CIEUC
+0xC553 0xD72F #HANGUL SYLLABLE HIEUH WI CHIEUCH
+0xC554 0xD730 #HANGUL SYLLABLE HIEUH WI KHIEUKH
+0xC555 0xD731 #HANGUL SYLLABLE HIEUH WI THIEUTH
+0xC556 0xD732 #HANGUL SYLLABLE HIEUH WI PHIEUPH
+0xC557 0xD733 #HANGUL SYLLABLE HIEUH WI HIEUH
+0xC558 0xD736 #HANGUL SYLLABLE HIEUH YU SSANGKIYEOK
+0xC559 0xD737 #HANGUL SYLLABLE HIEUH YU KIYEOKSIOS
+0xC55A 0xD739 #HANGUL SYLLABLE HIEUH YU NIEUNCIEUC
+0xC561 0xD73A #HANGUL SYLLABLE HIEUH YU NIEUNHIEUH
+0xC562 0xD73B #HANGUL SYLLABLE HIEUH YU TIKEUT
+0xC563 0xD73D #HANGUL SYLLABLE HIEUH YU RIEULKIYEOK
+0xC564 0xD73E #HANGUL SYLLABLE HIEUH YU RIEULMIEUM
+0xC565 0xD73F #HANGUL SYLLABLE HIEUH YU RIEULPIEUP
+0xC566 0xD740 #HANGUL SYLLABLE HIEUH YU RIEULSIOS
+0xC567 0xD741 #HANGUL SYLLABLE HIEUH YU RIEULTHIEUTH
+0xC568 0xD742 #HANGUL SYLLABLE HIEUH YU RIEULPHIEUPH
+0xC569 0xD743 #HANGUL SYLLABLE HIEUH YU RIEULHIEUH
+0xC56A 0xD745 #HANGUL SYLLABLE HIEUH YU PIEUP
+0xC56B 0xD746 #HANGUL SYLLABLE HIEUH YU PIEUPSIOS
+0xC56C 0xD748 #HANGUL SYLLABLE HIEUH YU SSANGSIOS
+0xC56D 0xD74A #HANGUL SYLLABLE HIEUH YU CIEUC
+0xC56E 0xD74B #HANGUL SYLLABLE HIEUH YU CHIEUCH
+0xC56F 0xD74C #HANGUL SYLLABLE HIEUH YU KHIEUKH
+0xC570 0xD74D #HANGUL SYLLABLE HIEUH YU THIEUTH
+0xC571 0xD74E #HANGUL SYLLABLE HIEUH YU PHIEUPH
+0xC572 0xD74F #HANGUL SYLLABLE HIEUH YU HIEUH
+0xC573 0xD752 #HANGUL SYLLABLE HIEUH EU SSANGKIYEOK
+0xC574 0xD753 #HANGUL SYLLABLE HIEUH EU KIYEOKSIOS
+0xC575 0xD755 #HANGUL SYLLABLE HIEUH EU NIEUNCIEUC
+0xC576 0xD75A #HANGUL SYLLABLE HIEUH EU RIEULMIEUM
+0xC577 0xD75B #HANGUL SYLLABLE HIEUH EU RIEULPIEUP
+0xC578 0xD75C #HANGUL SYLLABLE HIEUH EU RIEULSIOS
+0xC579 0xD75D #HANGUL SYLLABLE HIEUH EU RIEULTHIEUTH
+0xC57A 0xD75E #HANGUL SYLLABLE HIEUH EU RIEULPHIEUPH
+0xC581 0xD75F #HANGUL SYLLABLE HIEUH EU RIEULHIEUH
+0xC582 0xD762 #HANGUL SYLLABLE HIEUH EU PIEUPSIOS
+0xC583 0xD764 #HANGUL SYLLABLE HIEUH EU SSANGSIOS
+0xC584 0xD766 #HANGUL SYLLABLE HIEUH EU CIEUC
+0xC585 0xD767 #HANGUL SYLLABLE HIEUH EU CHIEUCH
+0xC586 0xD768 #HANGUL SYLLABLE HIEUH EU KHIEUKH
+0xC587 0xD76A #HANGUL SYLLABLE HIEUH EU PHIEUPH
+0xC588 0xD76B #HANGUL SYLLABLE HIEUH EU HIEUH
+0xC589 0xD76D #HANGUL SYLLABLE HIEUH YI KIYEOK
+0xC58A 0xD76E #HANGUL SYLLABLE HIEUH YI SSANGKIYEOK
+0xC58B 0xD76F #HANGUL SYLLABLE HIEUH YI KIYEOKSIOS
+0xC58C 0xD771 #HANGUL SYLLABLE HIEUH YI NIEUNCIEUC
+0xC58D 0xD772 #HANGUL SYLLABLE HIEUH YI NIEUNHIEUH
+0xC58E 0xD773 #HANGUL SYLLABLE HIEUH YI TIKEUT
+0xC58F 0xD775 #HANGUL SYLLABLE HIEUH YI RIEULKIYEOK
+0xC590 0xD776 #HANGUL SYLLABLE HIEUH YI RIEULMIEUM
+0xC591 0xD777 #HANGUL SYLLABLE HIEUH YI RIEULPIEUP
+0xC592 0xD778 #HANGUL SYLLABLE HIEUH YI RIEULSIOS
+0xC593 0xD779 #HANGUL SYLLABLE HIEUH YI RIEULTHIEUTH
+0xC594 0xD77A #HANGUL SYLLABLE HIEUH YI RIEULPHIEUPH
+0xC595 0xD77B #HANGUL SYLLABLE HIEUH YI RIEULHIEUH
+0xC596 0xD77E #HANGUL SYLLABLE HIEUH YI PIEUPSIOS
+0xC597 0xD77F #HANGUL SYLLABLE HIEUH YI SIOS
+0xC598 0xD780 #HANGUL SYLLABLE HIEUH YI SSANGSIOS
+0xC599 0xD782 #HANGUL SYLLABLE HIEUH YI CIEUC
+0xC59A 0xD783 #HANGUL SYLLABLE HIEUH YI CHIEUCH
+0xC59B 0xD784 #HANGUL SYLLABLE HIEUH YI KHIEUKH
+0xC59C 0xD785 #HANGUL SYLLABLE HIEUH YI THIEUTH
+0xC59D 0xD786 #HANGUL SYLLABLE HIEUH YI PHIEUPH
+0xC59E 0xD787 #HANGUL SYLLABLE HIEUH YI HIEUH
+0xC59F 0xD78A #HANGUL SYLLABLE HIEUH I SSANGKIYEOK
+0xC5A0 0xD78B #HANGUL SYLLABLE HIEUH I KIYEOKSIOS
+0xC5A1 0xD044 #HANGUL SYLLABLE KHIEUKH WI MIEUM
+0xC5A2 0xD045 #HANGUL SYLLABLE KHIEUKH WI PIEUP
+0xC5A3 0xD047 #HANGUL SYLLABLE KHIEUKH WI SIOS
+0xC5A4 0xD049 #HANGUL SYLLABLE KHIEUKH WI IEUNG
+0xC5A5 0xD050 #HANGUL SYLLABLE KHIEUKH YU
+0xC5A6 0xD054 #HANGUL SYLLABLE KHIEUKH YU NIEUN
+0xC5A7 0xD058 #HANGUL SYLLABLE KHIEUKH YU RIEUL
+0xC5A8 0xD060 #HANGUL SYLLABLE KHIEUKH YU MIEUM
+0xC5A9 0xD06C #HANGUL SYLLABLE KHIEUKH EU
+0xC5AA 0xD06D #HANGUL SYLLABLE KHIEUKH EU KIYEOK
+0xC5AB 0xD070 #HANGUL SYLLABLE KHIEUKH EU NIEUN
+0xC5AC 0xD074 #HANGUL SYLLABLE KHIEUKH EU RIEUL
+0xC5AD 0xD07C #HANGUL SYLLABLE KHIEUKH EU MIEUM
+0xC5AE 0xD07D #HANGUL SYLLABLE KHIEUKH EU PIEUP
+0xC5AF 0xD081 #HANGUL SYLLABLE KHIEUKH EU IEUNG
+0xC5B0 0xD0A4 #HANGUL SYLLABLE KHIEUKH I
+0xC5B1 0xD0A5 #HANGUL SYLLABLE KHIEUKH I KIYEOK
+0xC5B2 0xD0A8 #HANGUL SYLLABLE KHIEUKH I NIEUN
+0xC5B3 0xD0AC #HANGUL SYLLABLE KHIEUKH I RIEUL
+0xC5B4 0xD0B4 #HANGUL SYLLABLE KHIEUKH I MIEUM
+0xC5B5 0xD0B5 #HANGUL SYLLABLE KHIEUKH I PIEUP
+0xC5B6 0xD0B7 #HANGUL SYLLABLE KHIEUKH I SIOS
+0xC5B7 0xD0B9 #HANGUL SYLLABLE KHIEUKH I IEUNG
+0xC5B8 0xD0C0 #HANGUL SYLLABLE THIEUTH A
+0xC5B9 0xD0C1 #HANGUL SYLLABLE THIEUTH A KIYEOK
+0xC5BA 0xD0C4 #HANGUL SYLLABLE THIEUTH A NIEUN
+0xC5BB 0xD0C8 #HANGUL SYLLABLE THIEUTH A RIEUL
+0xC5BC 0xD0C9 #HANGUL SYLLABLE THIEUTH A RIEULKIYEOK
+0xC5BD 0xD0D0 #HANGUL SYLLABLE THIEUTH A MIEUM
+0xC5BE 0xD0D1 #HANGUL SYLLABLE THIEUTH A PIEUP
+0xC5BF 0xD0D3 #HANGUL SYLLABLE THIEUTH A SIOS
+0xC5C0 0xD0D4 #HANGUL SYLLABLE THIEUTH A SSANGSIOS
+0xC5C1 0xD0D5 #HANGUL SYLLABLE THIEUTH A IEUNG
+0xC5C2 0xD0DC #HANGUL SYLLABLE THIEUTH AE
+0xC5C3 0xD0DD #HANGUL SYLLABLE THIEUTH AE KIYEOK
+0xC5C4 0xD0E0 #HANGUL SYLLABLE THIEUTH AE NIEUN
+0xC5C5 0xD0E4 #HANGUL SYLLABLE THIEUTH AE RIEUL
+0xC5C6 0xD0EC #HANGUL SYLLABLE THIEUTH AE MIEUM
+0xC5C7 0xD0ED #HANGUL SYLLABLE THIEUTH AE PIEUP
+0xC5C8 0xD0EF #HANGUL SYLLABLE THIEUTH AE SIOS
+0xC5C9 0xD0F0 #HANGUL SYLLABLE THIEUTH AE SSANGSIOS
+0xC5CA 0xD0F1 #HANGUL SYLLABLE THIEUTH AE IEUNG
+0xC5CB 0xD0F8 #HANGUL SYLLABLE THIEUTH YA
+0xC5CC 0xD10D #HANGUL SYLLABLE THIEUTH YA IEUNG
+0xC5CD 0xD130 #HANGUL SYLLABLE THIEUTH EO
+0xC5CE 0xD131 #HANGUL SYLLABLE THIEUTH EO KIYEOK
+0xC5CF 0xD134 #HANGUL SYLLABLE THIEUTH EO NIEUN
+0xC5D0 0xD138 #HANGUL SYLLABLE THIEUTH EO RIEUL
+0xC5D1 0xD13A #HANGUL SYLLABLE THIEUTH EO RIEULMIEUM
+0xC5D2 0xD140 #HANGUL SYLLABLE THIEUTH EO MIEUM
+0xC5D3 0xD141 #HANGUL SYLLABLE THIEUTH EO PIEUP
+0xC5D4 0xD143 #HANGUL SYLLABLE THIEUTH EO SIOS
+0xC5D5 0xD144 #HANGUL SYLLABLE THIEUTH EO SSANGSIOS
+0xC5D6 0xD145 #HANGUL SYLLABLE THIEUTH EO IEUNG
+0xC5D7 0xD14C #HANGUL SYLLABLE THIEUTH E
+0xC5D8 0xD14D #HANGUL SYLLABLE THIEUTH E KIYEOK
+0xC5D9 0xD150 #HANGUL SYLLABLE THIEUTH E NIEUN
+0xC5DA 0xD154 #HANGUL SYLLABLE THIEUTH E RIEUL
+0xC5DB 0xD15C #HANGUL SYLLABLE THIEUTH E MIEUM
+0xC5DC 0xD15D #HANGUL SYLLABLE THIEUTH E PIEUP
+0xC5DD 0xD15F #HANGUL SYLLABLE THIEUTH E SIOS
+0xC5DE 0xD161 #HANGUL SYLLABLE THIEUTH E IEUNG
+0xC5DF 0xD168 #HANGUL SYLLABLE THIEUTH YEO
+0xC5E0 0xD16C #HANGUL SYLLABLE THIEUTH YEO NIEUN
+0xC5E1 0xD17C #HANGUL SYLLABLE THIEUTH YEO SSANGSIOS
+0xC5E2 0xD184 #HANGUL SYLLABLE THIEUTH YE
+0xC5E3 0xD188 #HANGUL SYLLABLE THIEUTH YE NIEUN
+0xC5E4 0xD1A0 #HANGUL SYLLABLE THIEUTH O
+0xC5E5 0xD1A1 #HANGUL SYLLABLE THIEUTH O KIYEOK
+0xC5E6 0xD1A4 #HANGUL SYLLABLE THIEUTH O NIEUN
+0xC5E7 0xD1A8 #HANGUL SYLLABLE THIEUTH O RIEUL
+0xC5E8 0xD1B0 #HANGUL SYLLABLE THIEUTH O MIEUM
+0xC5E9 0xD1B1 #HANGUL SYLLABLE THIEUTH O PIEUP
+0xC5EA 0xD1B3 #HANGUL SYLLABLE THIEUTH O SIOS
+0xC5EB 0xD1B5 #HANGUL SYLLABLE THIEUTH O IEUNG
+0xC5EC 0xD1BA #HANGUL SYLLABLE THIEUTH O PHIEUPH
+0xC5ED 0xD1BC #HANGUL SYLLABLE THIEUTH WA
+0xC5EE 0xD1C0 #HANGUL SYLLABLE THIEUTH WA NIEUN
+0xC5EF 0xD1D8 #HANGUL SYLLABLE THIEUTH WAE
+0xC5F0 0xD1F4 #HANGUL SYLLABLE THIEUTH OE
+0xC5F1 0xD1F8 #HANGUL SYLLABLE THIEUTH OE NIEUN
+0xC5F2 0xD207 #HANGUL SYLLABLE THIEUTH OE SIOS
+0xC5F3 0xD209 #HANGUL SYLLABLE THIEUTH OE IEUNG
+0xC5F4 0xD210 #HANGUL SYLLABLE THIEUTH YO
+0xC5F5 0xD22C #HANGUL SYLLABLE THIEUTH U
+0xC5F6 0xD22D #HANGUL SYLLABLE THIEUTH U KIYEOK
+0xC5F7 0xD230 #HANGUL SYLLABLE THIEUTH U NIEUN
+0xC5F8 0xD234 #HANGUL SYLLABLE THIEUTH U RIEUL
+0xC5F9 0xD23C #HANGUL SYLLABLE THIEUTH U MIEUM
+0xC5FA 0xD23D #HANGUL SYLLABLE THIEUTH U PIEUP
+0xC5FB 0xD23F #HANGUL SYLLABLE THIEUTH U SIOS
+0xC5FC 0xD241 #HANGUL SYLLABLE THIEUTH U IEUNG
+0xC5FD 0xD248 #HANGUL SYLLABLE THIEUTH WEO
+0xC5FE 0xD25C #HANGUL SYLLABLE THIEUTH WEO SSANGSIOS
+0xC641 0xD78D #HANGUL SYLLABLE HIEUH I NIEUNCIEUC
+0xC642 0xD78E #HANGUL SYLLABLE HIEUH I NIEUNHIEUH
+0xC643 0xD78F #HANGUL SYLLABLE HIEUH I TIKEUT
+0xC644 0xD791 #HANGUL SYLLABLE HIEUH I RIEULKIYEOK
+0xC645 0xD792 #HANGUL SYLLABLE HIEUH I RIEULMIEUM
+0xC646 0xD793 #HANGUL SYLLABLE HIEUH I RIEULPIEUP
+0xC647 0xD794 #HANGUL SYLLABLE HIEUH I RIEULSIOS
+0xC648 0xD795 #HANGUL SYLLABLE HIEUH I RIEULTHIEUTH
+0xC649 0xD796 #HANGUL SYLLABLE HIEUH I RIEULPHIEUPH
+0xC64A 0xD797 #HANGUL SYLLABLE HIEUH I RIEULHIEUH
+0xC64B 0xD79A #HANGUL SYLLABLE HIEUH I PIEUPSIOS
+0xC64C 0xD79C #HANGUL SYLLABLE HIEUH I SSANGSIOS
+0xC64D 0xD79E #HANGUL SYLLABLE HIEUH I CIEUC
+0xC64E 0xD79F #HANGUL SYLLABLE HIEUH I CHIEUCH
+0xC64F 0xD7A0 #HANGUL SYLLABLE HIEUH I KHIEUKH
+0xC650 0xD7A1 #HANGUL SYLLABLE HIEUH I THIEUTH
+0xC651 0xD7A2 #HANGUL SYLLABLE HIEUH I PHIEUPH
+0xC652 0xD7A3 #HANGUL SYLLABLE HIEUH I HIEUH
+0xC6A1 0xD264 #HANGUL SYLLABLE THIEUTH WE
+0xC6A2 0xD280 #HANGUL SYLLABLE THIEUTH WI
+0xC6A3 0xD281 #HANGUL SYLLABLE THIEUTH WI KIYEOK
+0xC6A4 0xD284 #HANGUL SYLLABLE THIEUTH WI NIEUN
+0xC6A5 0xD288 #HANGUL SYLLABLE THIEUTH WI RIEUL
+0xC6A6 0xD290 #HANGUL SYLLABLE THIEUTH WI MIEUM
+0xC6A7 0xD291 #HANGUL SYLLABLE THIEUTH WI PIEUP
+0xC6A8 0xD295 #HANGUL SYLLABLE THIEUTH WI IEUNG
+0xC6A9 0xD29C #HANGUL SYLLABLE THIEUTH YU
+0xC6AA 0xD2A0 #HANGUL SYLLABLE THIEUTH YU NIEUN
+0xC6AB 0xD2A4 #HANGUL SYLLABLE THIEUTH YU RIEUL
+0xC6AC 0xD2AC #HANGUL SYLLABLE THIEUTH YU MIEUM
+0xC6AD 0xD2B1 #HANGUL SYLLABLE THIEUTH YU IEUNG
+0xC6AE 0xD2B8 #HANGUL SYLLABLE THIEUTH EU
+0xC6AF 0xD2B9 #HANGUL SYLLABLE THIEUTH EU KIYEOK
+0xC6B0 0xD2BC #HANGUL SYLLABLE THIEUTH EU NIEUN
+0xC6B1 0xD2BF #HANGUL SYLLABLE THIEUTH EU TIKEUT
+0xC6B2 0xD2C0 #HANGUL SYLLABLE THIEUTH EU RIEUL
+0xC6B3 0xD2C2 #HANGUL SYLLABLE THIEUTH EU RIEULMIEUM
+0xC6B4 0xD2C8 #HANGUL SYLLABLE THIEUTH EU MIEUM
+0xC6B5 0xD2C9 #HANGUL SYLLABLE THIEUTH EU PIEUP
+0xC6B6 0xD2CB #HANGUL SYLLABLE THIEUTH EU SIOS
+0xC6B7 0xD2D4 #HANGUL SYLLABLE THIEUTH YI
+0xC6B8 0xD2D8 #HANGUL SYLLABLE THIEUTH YI NIEUN
+0xC6B9 0xD2DC #HANGUL SYLLABLE THIEUTH YI RIEUL
+0xC6BA 0xD2E4 #HANGUL SYLLABLE THIEUTH YI MIEUM
+0xC6BB 0xD2E5 #HANGUL SYLLABLE THIEUTH YI PIEUP
+0xC6BC 0xD2F0 #HANGUL SYLLABLE THIEUTH I
+0xC6BD 0xD2F1 #HANGUL SYLLABLE THIEUTH I KIYEOK
+0xC6BE 0xD2F4 #HANGUL SYLLABLE THIEUTH I NIEUN
+0xC6BF 0xD2F8 #HANGUL SYLLABLE THIEUTH I RIEUL
+0xC6C0 0xD300 #HANGUL SYLLABLE THIEUTH I MIEUM
+0xC6C1 0xD301 #HANGUL SYLLABLE THIEUTH I PIEUP
+0xC6C2 0xD303 #HANGUL SYLLABLE THIEUTH I SIOS
+0xC6C3 0xD305 #HANGUL SYLLABLE THIEUTH I IEUNG
+0xC6C4 0xD30C #HANGUL SYLLABLE PHIEUPH A
+0xC6C5 0xD30D #HANGUL SYLLABLE PHIEUPH A KIYEOK
+0xC6C6 0xD30E #HANGUL SYLLABLE PHIEUPH A SSANGKIYEOK
+0xC6C7 0xD310 #HANGUL SYLLABLE PHIEUPH A NIEUN
+0xC6C8 0xD314 #HANGUL SYLLABLE PHIEUPH A RIEUL
+0xC6C9 0xD316 #HANGUL SYLLABLE PHIEUPH A RIEULMIEUM
+0xC6CA 0xD31C #HANGUL SYLLABLE PHIEUPH A MIEUM
+0xC6CB 0xD31D #HANGUL SYLLABLE PHIEUPH A PIEUP
+0xC6CC 0xD31F #HANGUL SYLLABLE PHIEUPH A SIOS
+0xC6CD 0xD320 #HANGUL SYLLABLE PHIEUPH A SSANGSIOS
+0xC6CE 0xD321 #HANGUL SYLLABLE PHIEUPH A IEUNG
+0xC6CF 0xD325 #HANGUL SYLLABLE PHIEUPH A THIEUTH
+0xC6D0 0xD328 #HANGUL SYLLABLE PHIEUPH AE
+0xC6D1 0xD329 #HANGUL SYLLABLE PHIEUPH AE KIYEOK
+0xC6D2 0xD32C #HANGUL SYLLABLE PHIEUPH AE NIEUN
+0xC6D3 0xD330 #HANGUL SYLLABLE PHIEUPH AE RIEUL
+0xC6D4 0xD338 #HANGUL SYLLABLE PHIEUPH AE MIEUM
+0xC6D5 0xD339 #HANGUL SYLLABLE PHIEUPH AE PIEUP
+0xC6D6 0xD33B #HANGUL SYLLABLE PHIEUPH AE SIOS
+0xC6D7 0xD33C #HANGUL SYLLABLE PHIEUPH AE SSANGSIOS
+0xC6D8 0xD33D #HANGUL SYLLABLE PHIEUPH AE IEUNG
+0xC6D9 0xD344 #HANGUL SYLLABLE PHIEUPH YA
+0xC6DA 0xD345 #HANGUL SYLLABLE PHIEUPH YA KIYEOK
+0xC6DB 0xD37C #HANGUL SYLLABLE PHIEUPH EO
+0xC6DC 0xD37D #HANGUL SYLLABLE PHIEUPH EO KIYEOK
+0xC6DD 0xD380 #HANGUL SYLLABLE PHIEUPH EO NIEUN
+0xC6DE 0xD384 #HANGUL SYLLABLE PHIEUPH EO RIEUL
+0xC6DF 0xD38C #HANGUL SYLLABLE PHIEUPH EO MIEUM
+0xC6E0 0xD38D #HANGUL SYLLABLE PHIEUPH EO PIEUP
+0xC6E1 0xD38F #HANGUL SYLLABLE PHIEUPH EO SIOS
+0xC6E2 0xD390 #HANGUL SYLLABLE PHIEUPH EO SSANGSIOS
+0xC6E3 0xD391 #HANGUL SYLLABLE PHIEUPH EO IEUNG
+0xC6E4 0xD398 #HANGUL SYLLABLE PHIEUPH E
+0xC6E5 0xD399 #HANGUL SYLLABLE PHIEUPH E KIYEOK
+0xC6E6 0xD39C #HANGUL SYLLABLE PHIEUPH E NIEUN
+0xC6E7 0xD3A0 #HANGUL SYLLABLE PHIEUPH E RIEUL
+0xC6E8 0xD3A8 #HANGUL SYLLABLE PHIEUPH E MIEUM
+0xC6E9 0xD3A9 #HANGUL SYLLABLE PHIEUPH E PIEUP
+0xC6EA 0xD3AB #HANGUL SYLLABLE PHIEUPH E SIOS
+0xC6EB 0xD3AD #HANGUL SYLLABLE PHIEUPH E IEUNG
+0xC6EC 0xD3B4 #HANGUL SYLLABLE PHIEUPH YEO
+0xC6ED 0xD3B8 #HANGUL SYLLABLE PHIEUPH YEO NIEUN
+0xC6EE 0xD3BC #HANGUL SYLLABLE PHIEUPH YEO RIEUL
+0xC6EF 0xD3C4 #HANGUL SYLLABLE PHIEUPH YEO MIEUM
+0xC6F0 0xD3C5 #HANGUL SYLLABLE PHIEUPH YEO PIEUP
+0xC6F1 0xD3C8 #HANGUL SYLLABLE PHIEUPH YEO SSANGSIOS
+0xC6F2 0xD3C9 #HANGUL SYLLABLE PHIEUPH YEO IEUNG
+0xC6F3 0xD3D0 #HANGUL SYLLABLE PHIEUPH YE
+0xC6F4 0xD3D8 #HANGUL SYLLABLE PHIEUPH YE RIEUL
+0xC6F5 0xD3E1 #HANGUL SYLLABLE PHIEUPH YE PIEUP
+0xC6F6 0xD3E3 #HANGUL SYLLABLE PHIEUPH YE SIOS
+0xC6F7 0xD3EC #HANGUL SYLLABLE PHIEUPH O
+0xC6F8 0xD3ED #HANGUL SYLLABLE PHIEUPH O KIYEOK
+0xC6F9 0xD3F0 #HANGUL SYLLABLE PHIEUPH O NIEUN
+0xC6FA 0xD3F4 #HANGUL SYLLABLE PHIEUPH O RIEUL
+0xC6FB 0xD3FC #HANGUL SYLLABLE PHIEUPH O MIEUM
+0xC6FC 0xD3FD #HANGUL SYLLABLE PHIEUPH O PIEUP
+0xC6FD 0xD3FF #HANGUL SYLLABLE PHIEUPH O SIOS
+0xC6FE 0xD401 #HANGUL SYLLABLE PHIEUPH O IEUNG
+0xC7A1 0xD408 #HANGUL SYLLABLE PHIEUPH WA
+0xC7A2 0xD41D #HANGUL SYLLABLE PHIEUPH WA IEUNG
+0xC7A3 0xD440 #HANGUL SYLLABLE PHIEUPH OE
+0xC7A4 0xD444 #HANGUL SYLLABLE PHIEUPH OE NIEUN
+0xC7A5 0xD45C #HANGUL SYLLABLE PHIEUPH YO
+0xC7A6 0xD460 #HANGUL SYLLABLE PHIEUPH YO NIEUN
+0xC7A7 0xD464 #HANGUL SYLLABLE PHIEUPH YO RIEUL
+0xC7A8 0xD46D #HANGUL SYLLABLE PHIEUPH YO PIEUP
+0xC7A9 0xD46F #HANGUL SYLLABLE PHIEUPH YO SIOS
+0xC7AA 0xD478 #HANGUL SYLLABLE PHIEUPH U
+0xC7AB 0xD479 #HANGUL SYLLABLE PHIEUPH U KIYEOK
+0xC7AC 0xD47C #HANGUL SYLLABLE PHIEUPH U NIEUN
+0xC7AD 0xD47F #HANGUL SYLLABLE PHIEUPH U TIKEUT
+0xC7AE 0xD480 #HANGUL SYLLABLE PHIEUPH U RIEUL
+0xC7AF 0xD482 #HANGUL SYLLABLE PHIEUPH U RIEULMIEUM
+0xC7B0 0xD488 #HANGUL SYLLABLE PHIEUPH U MIEUM
+0xC7B1 0xD489 #HANGUL SYLLABLE PHIEUPH U PIEUP
+0xC7B2 0xD48B #HANGUL SYLLABLE PHIEUPH U SIOS
+0xC7B3 0xD48D #HANGUL SYLLABLE PHIEUPH U IEUNG
+0xC7B4 0xD494 #HANGUL SYLLABLE PHIEUPH WEO
+0xC7B5 0xD4A9 #HANGUL SYLLABLE PHIEUPH WEO IEUNG
+0xC7B6 0xD4CC #HANGUL SYLLABLE PHIEUPH WI
+0xC7B7 0xD4D0 #HANGUL SYLLABLE PHIEUPH WI NIEUN
+0xC7B8 0xD4D4 #HANGUL SYLLABLE PHIEUPH WI RIEUL
+0xC7B9 0xD4DC #HANGUL SYLLABLE PHIEUPH WI MIEUM
+0xC7BA 0xD4DF #HANGUL SYLLABLE PHIEUPH WI SIOS
+0xC7BB 0xD4E8 #HANGUL SYLLABLE PHIEUPH YU
+0xC7BC 0xD4EC #HANGUL SYLLABLE PHIEUPH YU NIEUN
+0xC7BD 0xD4F0 #HANGUL SYLLABLE PHIEUPH YU RIEUL
+0xC7BE 0xD4F8 #HANGUL SYLLABLE PHIEUPH YU MIEUM
+0xC7BF 0xD4FB #HANGUL SYLLABLE PHIEUPH YU SIOS
+0xC7C0 0xD4FD #HANGUL SYLLABLE PHIEUPH YU IEUNG
+0xC7C1 0xD504 #HANGUL SYLLABLE PHIEUPH EU
+0xC7C2 0xD508 #HANGUL SYLLABLE PHIEUPH EU NIEUN
+0xC7C3 0xD50C #HANGUL SYLLABLE PHIEUPH EU RIEUL
+0xC7C4 0xD514 #HANGUL SYLLABLE PHIEUPH EU MIEUM
+0xC7C5 0xD515 #HANGUL SYLLABLE PHIEUPH EU PIEUP
+0xC7C6 0xD517 #HANGUL SYLLABLE PHIEUPH EU SIOS
+0xC7C7 0xD53C #HANGUL SYLLABLE PHIEUPH I
+0xC7C8 0xD53D #HANGUL SYLLABLE PHIEUPH I KIYEOK
+0xC7C9 0xD540 #HANGUL SYLLABLE PHIEUPH I NIEUN
+0xC7CA 0xD544 #HANGUL SYLLABLE PHIEUPH I RIEUL
+0xC7CB 0xD54C #HANGUL SYLLABLE PHIEUPH I MIEUM
+0xC7CC 0xD54D #HANGUL SYLLABLE PHIEUPH I PIEUP
+0xC7CD 0xD54F #HANGUL SYLLABLE PHIEUPH I SIOS
+0xC7CE 0xD551 #HANGUL SYLLABLE PHIEUPH I IEUNG
+0xC7CF 0xD558 #HANGUL SYLLABLE HIEUH A
+0xC7D0 0xD559 #HANGUL SYLLABLE HIEUH A KIYEOK
+0xC7D1 0xD55C #HANGUL SYLLABLE HIEUH A NIEUN
+0xC7D2 0xD560 #HANGUL SYLLABLE HIEUH A RIEUL
+0xC7D3 0xD565 #HANGUL SYLLABLE HIEUH A RIEULTHIEUTH
+0xC7D4 0xD568 #HANGUL SYLLABLE HIEUH A MIEUM
+0xC7D5 0xD569 #HANGUL SYLLABLE HIEUH A PIEUP
+0xC7D6 0xD56B #HANGUL SYLLABLE HIEUH A SIOS
+0xC7D7 0xD56D #HANGUL SYLLABLE HIEUH A IEUNG
+0xC7D8 0xD574 #HANGUL SYLLABLE HIEUH AE
+0xC7D9 0xD575 #HANGUL SYLLABLE HIEUH AE KIYEOK
+0xC7DA 0xD578 #HANGUL SYLLABLE HIEUH AE NIEUN
+0xC7DB 0xD57C #HANGUL SYLLABLE HIEUH AE RIEUL
+0xC7DC 0xD584 #HANGUL SYLLABLE HIEUH AE MIEUM
+0xC7DD 0xD585 #HANGUL SYLLABLE HIEUH AE PIEUP
+0xC7DE 0xD587 #HANGUL SYLLABLE HIEUH AE SIOS
+0xC7DF 0xD588 #HANGUL SYLLABLE HIEUH AE SSANGSIOS
+0xC7E0 0xD589 #HANGUL SYLLABLE HIEUH AE IEUNG
+0xC7E1 0xD590 #HANGUL SYLLABLE HIEUH YA
+0xC7E2 0xD5A5 #HANGUL SYLLABLE HIEUH YA IEUNG
+0xC7E3 0xD5C8 #HANGUL SYLLABLE HIEUH EO
+0xC7E4 0xD5C9 #HANGUL SYLLABLE HIEUH EO KIYEOK
+0xC7E5 0xD5CC #HANGUL SYLLABLE HIEUH EO NIEUN
+0xC7E6 0xD5D0 #HANGUL SYLLABLE HIEUH EO RIEUL
+0xC7E7 0xD5D2 #HANGUL SYLLABLE HIEUH EO RIEULMIEUM
+0xC7E8 0xD5D8 #HANGUL SYLLABLE HIEUH EO MIEUM
+0xC7E9 0xD5D9 #HANGUL SYLLABLE HIEUH EO PIEUP
+0xC7EA 0xD5DB #HANGUL SYLLABLE HIEUH EO SIOS
+0xC7EB 0xD5DD #HANGUL SYLLABLE HIEUH EO IEUNG
+0xC7EC 0xD5E4 #HANGUL SYLLABLE HIEUH E
+0xC7ED 0xD5E5 #HANGUL SYLLABLE HIEUH E KIYEOK
+0xC7EE 0xD5E8 #HANGUL SYLLABLE HIEUH E NIEUN
+0xC7EF 0xD5EC #HANGUL SYLLABLE HIEUH E RIEUL
+0xC7F0 0xD5F4 #HANGUL SYLLABLE HIEUH E MIEUM
+0xC7F1 0xD5F5 #HANGUL SYLLABLE HIEUH E PIEUP
+0xC7F2 0xD5F7 #HANGUL SYLLABLE HIEUH E SIOS
+0xC7F3 0xD5F9 #HANGUL SYLLABLE HIEUH E IEUNG
+0xC7F4 0xD600 #HANGUL SYLLABLE HIEUH YEO
+0xC7F5 0xD601 #HANGUL SYLLABLE HIEUH YEO KIYEOK
+0xC7F6 0xD604 #HANGUL SYLLABLE HIEUH YEO NIEUN
+0xC7F7 0xD608 #HANGUL SYLLABLE HIEUH YEO RIEUL
+0xC7F8 0xD610 #HANGUL SYLLABLE HIEUH YEO MIEUM
+0xC7F9 0xD611 #HANGUL SYLLABLE HIEUH YEO PIEUP
+0xC7FA 0xD613 #HANGUL SYLLABLE HIEUH YEO SIOS
+0xC7FB 0xD614 #HANGUL SYLLABLE HIEUH YEO SSANGSIOS
+0xC7FC 0xD615 #HANGUL SYLLABLE HIEUH YEO IEUNG
+0xC7FD 0xD61C #HANGUL SYLLABLE HIEUH YE
+0xC7FE 0xD620 #HANGUL SYLLABLE HIEUH YE NIEUN
+0xC8A1 0xD624 #HANGUL SYLLABLE HIEUH YE RIEUL
+0xC8A2 0xD62D #HANGUL SYLLABLE HIEUH YE PIEUP
+0xC8A3 0xD638 #HANGUL SYLLABLE HIEUH O
+0xC8A4 0xD639 #HANGUL SYLLABLE HIEUH O KIYEOK
+0xC8A5 0xD63C #HANGUL SYLLABLE HIEUH O NIEUN
+0xC8A6 0xD640 #HANGUL SYLLABLE HIEUH O RIEUL
+0xC8A7 0xD645 #HANGUL SYLLABLE HIEUH O RIEULTHIEUTH
+0xC8A8 0xD648 #HANGUL SYLLABLE HIEUH O MIEUM
+0xC8A9 0xD649 #HANGUL SYLLABLE HIEUH O PIEUP
+0xC8AA 0xD64B #HANGUL SYLLABLE HIEUH O SIOS
+0xC8AB 0xD64D #HANGUL SYLLABLE HIEUH O IEUNG
+0xC8AC 0xD651 #HANGUL SYLLABLE HIEUH O THIEUTH
+0xC8AD 0xD654 #HANGUL SYLLABLE HIEUH WA
+0xC8AE 0xD655 #HANGUL SYLLABLE HIEUH WA KIYEOK
+0xC8AF 0xD658 #HANGUL SYLLABLE HIEUH WA NIEUN
+0xC8B0 0xD65C #HANGUL SYLLABLE HIEUH WA RIEUL
+0xC8B1 0xD667 #HANGUL SYLLABLE HIEUH WA SIOS
+0xC8B2 0xD669 #HANGUL SYLLABLE HIEUH WA IEUNG
+0xC8B3 0xD670 #HANGUL SYLLABLE HIEUH WAE
+0xC8B4 0xD671 #HANGUL SYLLABLE HIEUH WAE KIYEOK
+0xC8B5 0xD674 #HANGUL SYLLABLE HIEUH WAE NIEUN
+0xC8B6 0xD683 #HANGUL SYLLABLE HIEUH WAE SIOS
+0xC8B7 0xD685 #HANGUL SYLLABLE HIEUH WAE IEUNG
+0xC8B8 0xD68C #HANGUL SYLLABLE HIEUH OE
+0xC8B9 0xD68D #HANGUL SYLLABLE HIEUH OE KIYEOK
+0xC8BA 0xD690 #HANGUL SYLLABLE HIEUH OE NIEUN
+0xC8BB 0xD694 #HANGUL SYLLABLE HIEUH OE RIEUL
+0xC8BC 0xD69D #HANGUL SYLLABLE HIEUH OE PIEUP
+0xC8BD 0xD69F #HANGUL SYLLABLE HIEUH OE SIOS
+0xC8BE 0xD6A1 #HANGUL SYLLABLE HIEUH OE IEUNG
+0xC8BF 0xD6A8 #HANGUL SYLLABLE HIEUH YO
+0xC8C0 0xD6AC #HANGUL SYLLABLE HIEUH YO NIEUN
+0xC8C1 0xD6B0 #HANGUL SYLLABLE HIEUH YO RIEUL
+0xC8C2 0xD6B9 #HANGUL SYLLABLE HIEUH YO PIEUP
+0xC8C3 0xD6BB #HANGUL SYLLABLE HIEUH YO SIOS
+0xC8C4 0xD6C4 #HANGUL SYLLABLE HIEUH U
+0xC8C5 0xD6C5 #HANGUL SYLLABLE HIEUH U KIYEOK
+0xC8C6 0xD6C8 #HANGUL SYLLABLE HIEUH U NIEUN
+0xC8C7 0xD6CC #HANGUL SYLLABLE HIEUH U RIEUL
+0xC8C8 0xD6D1 #HANGUL SYLLABLE HIEUH U RIEULTHIEUTH
+0xC8C9 0xD6D4 #HANGUL SYLLABLE HIEUH U MIEUM
+0xC8CA 0xD6D7 #HANGUL SYLLABLE HIEUH U SIOS
+0xC8CB 0xD6D9 #HANGUL SYLLABLE HIEUH U IEUNG
+0xC8CC 0xD6E0 #HANGUL SYLLABLE HIEUH WEO
+0xC8CD 0xD6E4 #HANGUL SYLLABLE HIEUH WEO NIEUN
+0xC8CE 0xD6E8 #HANGUL SYLLABLE HIEUH WEO RIEUL
+0xC8CF 0xD6F0 #HANGUL SYLLABLE HIEUH WEO MIEUM
+0xC8D0 0xD6F5 #HANGUL SYLLABLE HIEUH WEO IEUNG
+0xC8D1 0xD6FC #HANGUL SYLLABLE HIEUH WE
+0xC8D2 0xD6FD #HANGUL SYLLABLE HIEUH WE KIYEOK
+0xC8D3 0xD700 #HANGUL SYLLABLE HIEUH WE NIEUN
+0xC8D4 0xD704 #HANGUL SYLLABLE HIEUH WE RIEUL
+0xC8D5 0xD711 #HANGUL SYLLABLE HIEUH WE IEUNG
+0xC8D6 0xD718 #HANGUL SYLLABLE HIEUH WI
+0xC8D7 0xD719 #HANGUL SYLLABLE HIEUH WI KIYEOK
+0xC8D8 0xD71C #HANGUL SYLLABLE HIEUH WI NIEUN
+0xC8D9 0xD720 #HANGUL SYLLABLE HIEUH WI RIEUL
+0xC8DA 0xD728 #HANGUL SYLLABLE HIEUH WI MIEUM
+0xC8DB 0xD729 #HANGUL SYLLABLE HIEUH WI PIEUP
+0xC8DC 0xD72B #HANGUL SYLLABLE HIEUH WI SIOS
+0xC8DD 0xD72D #HANGUL SYLLABLE HIEUH WI IEUNG
+0xC8DE 0xD734 #HANGUL SYLLABLE HIEUH YU
+0xC8DF 0xD735 #HANGUL SYLLABLE HIEUH YU KIYEOK
+0xC8E0 0xD738 #HANGUL SYLLABLE HIEUH YU NIEUN
+0xC8E1 0xD73C #HANGUL SYLLABLE HIEUH YU RIEUL
+0xC8E2 0xD744 #HANGUL SYLLABLE HIEUH YU MIEUM
+0xC8E3 0xD747 #HANGUL SYLLABLE HIEUH YU SIOS
+0xC8E4 0xD749 #HANGUL SYLLABLE HIEUH YU IEUNG
+0xC8E5 0xD750 #HANGUL SYLLABLE HIEUH EU
+0xC8E6 0xD751 #HANGUL SYLLABLE HIEUH EU KIYEOK
+0xC8E7 0xD754 #HANGUL SYLLABLE HIEUH EU NIEUN
+0xC8E8 0xD756 #HANGUL SYLLABLE HIEUH EU NIEUNHIEUH
+0xC8E9 0xD757 #HANGUL SYLLABLE HIEUH EU TIKEUT
+0xC8EA 0xD758 #HANGUL SYLLABLE HIEUH EU RIEUL
+0xC8EB 0xD759 #HANGUL SYLLABLE HIEUH EU RIEULKIYEOK
+0xC8EC 0xD760 #HANGUL SYLLABLE HIEUH EU MIEUM
+0xC8ED 0xD761 #HANGUL SYLLABLE HIEUH EU PIEUP
+0xC8EE 0xD763 #HANGUL SYLLABLE HIEUH EU SIOS
+0xC8EF 0xD765 #HANGUL SYLLABLE HIEUH EU IEUNG
+0xC8F0 0xD769 #HANGUL SYLLABLE HIEUH EU THIEUTH
+0xC8F1 0xD76C #HANGUL SYLLABLE HIEUH YI
+0xC8F2 0xD770 #HANGUL SYLLABLE HIEUH YI NIEUN
+0xC8F3 0xD774 #HANGUL SYLLABLE HIEUH YI RIEUL
+0xC8F4 0xD77C #HANGUL SYLLABLE HIEUH YI MIEUM
+0xC8F5 0xD77D #HANGUL SYLLABLE HIEUH YI PIEUP
+0xC8F6 0xD781 #HANGUL SYLLABLE HIEUH YI IEUNG
+0xC8F7 0xD788 #HANGUL SYLLABLE HIEUH I
+0xC8F8 0xD789 #HANGUL SYLLABLE HIEUH I KIYEOK
+0xC8F9 0xD78C #HANGUL SYLLABLE HIEUH I NIEUN
+0xC8FA 0xD790 #HANGUL SYLLABLE HIEUH I RIEUL
+0xC8FB 0xD798 #HANGUL SYLLABLE HIEUH I MIEUM
+0xC8FC 0xD799 #HANGUL SYLLABLE HIEUH I PIEUP
+0xC8FD 0xD79B #HANGUL SYLLABLE HIEUH I SIOS
+0xC8FE 0xD79D #HANGUL SYLLABLE HIEUH I IEUNG
+0xCAA1 0x4F3D #CJK UNIFIED IDEOGRAPH
+0xCAA2 0x4F73 #CJK UNIFIED IDEOGRAPH
+0xCAA3 0x5047 #CJK UNIFIED IDEOGRAPH
+0xCAA4 0x50F9 #CJK UNIFIED IDEOGRAPH
+0xCAA5 0x52A0 #CJK UNIFIED IDEOGRAPH
+0xCAA6 0x53EF #CJK UNIFIED IDEOGRAPH
+0xCAA7 0x5475 #CJK UNIFIED IDEOGRAPH
+0xCAA8 0x54E5 #CJK UNIFIED IDEOGRAPH
+0xCAA9 0x5609 #CJK UNIFIED IDEOGRAPH
+0xCAAA 0x5AC1 #CJK UNIFIED IDEOGRAPH
+0xCAAB 0x5BB6 #CJK UNIFIED IDEOGRAPH
+0xCAAC 0x6687 #CJK UNIFIED IDEOGRAPH
+0xCAAD 0x67B6 #CJK UNIFIED IDEOGRAPH
+0xCAAE 0x67B7 #CJK UNIFIED IDEOGRAPH
+0xCAAF 0x67EF #CJK UNIFIED IDEOGRAPH
+0xCAB0 0x6B4C #CJK UNIFIED IDEOGRAPH
+0xCAB1 0x73C2 #CJK UNIFIED IDEOGRAPH
+0xCAB2 0x75C2 #CJK UNIFIED IDEOGRAPH
+0xCAB3 0x7A3C #CJK UNIFIED IDEOGRAPH
+0xCAB4 0x82DB #CJK UNIFIED IDEOGRAPH
+0xCAB5 0x8304 #CJK UNIFIED IDEOGRAPH
+0xCAB6 0x8857 #CJK UNIFIED IDEOGRAPH
+0xCAB7 0x8888 #CJK UNIFIED IDEOGRAPH
+0xCAB8 0x8A36 #CJK UNIFIED IDEOGRAPH
+0xCAB9 0x8CC8 #CJK UNIFIED IDEOGRAPH
+0xCABA 0x8DCF #CJK UNIFIED IDEOGRAPH
+0xCABB 0x8EFB #CJK UNIFIED IDEOGRAPH
+0xCABC 0x8FE6 #CJK UNIFIED IDEOGRAPH
+0xCABD 0x99D5 #CJK UNIFIED IDEOGRAPH
+0xCABE 0x523B #CJK UNIFIED IDEOGRAPH
+0xCABF 0x5374 #CJK UNIFIED IDEOGRAPH
+0xCAC0 0x5404 #CJK UNIFIED IDEOGRAPH
+0xCAC1 0x606A #CJK UNIFIED IDEOGRAPH
+0xCAC2 0x6164 #CJK UNIFIED IDEOGRAPH
+0xCAC3 0x6BBC #CJK UNIFIED IDEOGRAPH
+0xCAC4 0x73CF #CJK UNIFIED IDEOGRAPH
+0xCAC5 0x811A #CJK UNIFIED IDEOGRAPH
+0xCAC6 0x89BA #CJK UNIFIED IDEOGRAPH
+0xCAC7 0x89D2 #CJK UNIFIED IDEOGRAPH
+0xCAC8 0x95A3 #CJK UNIFIED IDEOGRAPH
+0xCAC9 0x4F83 #CJK UNIFIED IDEOGRAPH
+0xCACA 0x520A #CJK UNIFIED IDEOGRAPH
+0xCACB 0x58BE #CJK UNIFIED IDEOGRAPH
+0xCACC 0x5978 #CJK UNIFIED IDEOGRAPH
+0xCACD 0x59E6 #CJK UNIFIED IDEOGRAPH
+0xCACE 0x5E72 #CJK UNIFIED IDEOGRAPH
+0xCACF 0x5E79 #CJK UNIFIED IDEOGRAPH
+0xCAD0 0x61C7 #CJK UNIFIED IDEOGRAPH
+0xCAD1 0x63C0 #CJK UNIFIED IDEOGRAPH
+0xCAD2 0x6746 #CJK UNIFIED IDEOGRAPH
+0xCAD3 0x67EC #CJK UNIFIED IDEOGRAPH
+0xCAD4 0x687F #CJK UNIFIED IDEOGRAPH
+0xCAD5 0x6F97 #CJK UNIFIED IDEOGRAPH
+0xCAD6 0x764E #CJK UNIFIED IDEOGRAPH
+0xCAD7 0x770B #CJK UNIFIED IDEOGRAPH
+0xCAD8 0x78F5 #CJK UNIFIED IDEOGRAPH
+0xCAD9 0x7A08 #CJK UNIFIED IDEOGRAPH
+0xCADA 0x7AFF #CJK UNIFIED IDEOGRAPH
+0xCADB 0x7C21 #CJK UNIFIED IDEOGRAPH
+0xCADC 0x809D #CJK UNIFIED IDEOGRAPH
+0xCADD 0x826E #CJK UNIFIED IDEOGRAPH
+0xCADE 0x8271 #CJK UNIFIED IDEOGRAPH
+0xCADF 0x8AEB #CJK UNIFIED IDEOGRAPH
+0xCAE0 0x9593 #CJK UNIFIED IDEOGRAPH
+0xCAE1 0x4E6B #CJK UNIFIED IDEOGRAPH
+0xCAE2 0x559D #CJK UNIFIED IDEOGRAPH
+0xCAE3 0x66F7 #CJK UNIFIED IDEOGRAPH
+0xCAE4 0x6E34 #CJK UNIFIED IDEOGRAPH
+0xCAE5 0x78A3 #CJK UNIFIED IDEOGRAPH
+0xCAE6 0x7AED #CJK UNIFIED IDEOGRAPH
+0xCAE7 0x845B #CJK UNIFIED IDEOGRAPH
+0xCAE8 0x8910 #CJK UNIFIED IDEOGRAPH
+0xCAE9 0x874E #CJK UNIFIED IDEOGRAPH
+0xCAEA 0x97A8 #CJK UNIFIED IDEOGRAPH
+0xCAEB 0x52D8 #CJK UNIFIED IDEOGRAPH
+0xCAEC 0x574E #CJK UNIFIED IDEOGRAPH
+0xCAED 0x582A #CJK UNIFIED IDEOGRAPH
+0xCAEE 0x5D4C #CJK UNIFIED IDEOGRAPH
+0xCAEF 0x611F #CJK UNIFIED IDEOGRAPH
+0xCAF0 0x61BE #CJK UNIFIED IDEOGRAPH
+0xCAF1 0x6221 #CJK UNIFIED IDEOGRAPH
+0xCAF2 0x6562 #CJK UNIFIED IDEOGRAPH
+0xCAF3 0x67D1 #CJK UNIFIED IDEOGRAPH
+0xCAF4 0x6A44 #CJK UNIFIED IDEOGRAPH
+0xCAF5 0x6E1B #CJK UNIFIED IDEOGRAPH
+0xCAF6 0x7518 #CJK UNIFIED IDEOGRAPH
+0xCAF7 0x75B3 #CJK UNIFIED IDEOGRAPH
+0xCAF8 0x76E3 #CJK UNIFIED IDEOGRAPH
+0xCAF9 0x77B0 #CJK UNIFIED IDEOGRAPH
+0xCAFA 0x7D3A #CJK UNIFIED IDEOGRAPH
+0xCAFB 0x90AF #CJK UNIFIED IDEOGRAPH
+0xCAFC 0x9451 #CJK UNIFIED IDEOGRAPH
+0xCAFD 0x9452 #CJK UNIFIED IDEOGRAPH
+0xCAFE 0x9F95 #CJK UNIFIED IDEOGRAPH
+0xCBA1 0x5323 #CJK UNIFIED IDEOGRAPH
+0xCBA2 0x5CAC #CJK UNIFIED IDEOGRAPH
+0xCBA3 0x7532 #CJK UNIFIED IDEOGRAPH
+0xCBA4 0x80DB #CJK UNIFIED IDEOGRAPH
+0xCBA5 0x9240 #CJK UNIFIED IDEOGRAPH
+0xCBA6 0x9598 #CJK UNIFIED IDEOGRAPH
+0xCBA7 0x525B #CJK UNIFIED IDEOGRAPH
+0xCBA8 0x5808 #CJK UNIFIED IDEOGRAPH
+0xCBA9 0x59DC #CJK UNIFIED IDEOGRAPH
+0xCBAA 0x5CA1 #CJK UNIFIED IDEOGRAPH
+0xCBAB 0x5D17 #CJK UNIFIED IDEOGRAPH
+0xCBAC 0x5EB7 #CJK UNIFIED IDEOGRAPH
+0xCBAD 0x5F3A #CJK UNIFIED IDEOGRAPH
+0xCBAE 0x5F4A #CJK UNIFIED IDEOGRAPH
+0xCBAF 0x6177 #CJK UNIFIED IDEOGRAPH
+0xCBB0 0x6C5F #CJK UNIFIED IDEOGRAPH
+0xCBB1 0x757A #CJK UNIFIED IDEOGRAPH
+0xCBB2 0x7586 #CJK UNIFIED IDEOGRAPH
+0xCBB3 0x7CE0 #CJK UNIFIED IDEOGRAPH
+0xCBB4 0x7D73 #CJK UNIFIED IDEOGRAPH
+0xCBB5 0x7DB1 #CJK UNIFIED IDEOGRAPH
+0xCBB6 0x7F8C #CJK UNIFIED IDEOGRAPH
+0xCBB7 0x8154 #CJK UNIFIED IDEOGRAPH
+0xCBB8 0x8221 #CJK UNIFIED IDEOGRAPH
+0xCBB9 0x8591 #CJK UNIFIED IDEOGRAPH
+0xCBBA 0x8941 #CJK UNIFIED IDEOGRAPH
+0xCBBB 0x8B1B #CJK UNIFIED IDEOGRAPH
+0xCBBC 0x92FC #CJK UNIFIED IDEOGRAPH
+0xCBBD 0x964D #CJK UNIFIED IDEOGRAPH
+0xCBBE 0x9C47 #CJK UNIFIED IDEOGRAPH
+0xCBBF 0x4ECB #CJK UNIFIED IDEOGRAPH
+0xCBC0 0x4EF7 #CJK UNIFIED IDEOGRAPH
+0xCBC1 0x500B #CJK UNIFIED IDEOGRAPH
+0xCBC2 0x51F1 #CJK UNIFIED IDEOGRAPH
+0xCBC3 0x584F #CJK UNIFIED IDEOGRAPH
+0xCBC4 0x6137 #CJK UNIFIED IDEOGRAPH
+0xCBC5 0x613E #CJK UNIFIED IDEOGRAPH
+0xCBC6 0x6168 #CJK UNIFIED IDEOGRAPH
+0xCBC7 0x6539 #CJK UNIFIED IDEOGRAPH
+0xCBC8 0x69EA #CJK UNIFIED IDEOGRAPH
+0xCBC9 0x6F11 #CJK UNIFIED IDEOGRAPH
+0xCBCA 0x75A5 #CJK UNIFIED IDEOGRAPH
+0xCBCB 0x7686 #CJK UNIFIED IDEOGRAPH
+0xCBCC 0x76D6 #CJK UNIFIED IDEOGRAPH
+0xCBCD 0x7B87 #CJK UNIFIED IDEOGRAPH
+0xCBCE 0x82A5 #CJK UNIFIED IDEOGRAPH
+0xCBCF 0x84CB #CJK UNIFIED IDEOGRAPH
+0xCBD0 0xF900 #CJK COMPATIBILITY IDEOGRAPH
+0xCBD1 0x93A7 #CJK UNIFIED IDEOGRAPH
+0xCBD2 0x958B #CJK UNIFIED IDEOGRAPH
+0xCBD3 0x5580 #CJK UNIFIED IDEOGRAPH
+0xCBD4 0x5BA2 #CJK UNIFIED IDEOGRAPH
+0xCBD5 0x5751 #CJK UNIFIED IDEOGRAPH
+0xCBD6 0xF901 #CJK COMPATIBILITY IDEOGRAPH
+0xCBD7 0x7CB3 #CJK UNIFIED IDEOGRAPH
+0xCBD8 0x7FB9 #CJK UNIFIED IDEOGRAPH
+0xCBD9 0x91B5 #CJK UNIFIED IDEOGRAPH
+0xCBDA 0x5028 #CJK UNIFIED IDEOGRAPH
+0xCBDB 0x53BB #CJK UNIFIED IDEOGRAPH
+0xCBDC 0x5C45 #CJK UNIFIED IDEOGRAPH
+0xCBDD 0x5DE8 #CJK UNIFIED IDEOGRAPH
+0xCBDE 0x62D2 #CJK UNIFIED IDEOGRAPH
+0xCBDF 0x636E #CJK UNIFIED IDEOGRAPH
+0xCBE0 0x64DA #CJK UNIFIED IDEOGRAPH
+0xCBE1 0x64E7 #CJK UNIFIED IDEOGRAPH
+0xCBE2 0x6E20 #CJK UNIFIED IDEOGRAPH
+0xCBE3 0x70AC #CJK UNIFIED IDEOGRAPH
+0xCBE4 0x795B #CJK UNIFIED IDEOGRAPH
+0xCBE5 0x8DDD #CJK UNIFIED IDEOGRAPH
+0xCBE6 0x8E1E #CJK UNIFIED IDEOGRAPH
+0xCBE7 0xF902 #CJK COMPATIBILITY IDEOGRAPH
+0xCBE8 0x907D #CJK UNIFIED IDEOGRAPH
+0xCBE9 0x9245 #CJK UNIFIED IDEOGRAPH
+0xCBEA 0x92F8 #CJK UNIFIED IDEOGRAPH
+0xCBEB 0x4E7E #CJK UNIFIED IDEOGRAPH
+0xCBEC 0x4EF6 #CJK UNIFIED IDEOGRAPH
+0xCBED 0x5065 #CJK UNIFIED IDEOGRAPH
+0xCBEE 0x5DFE #CJK UNIFIED IDEOGRAPH
+0xCBEF 0x5EFA #CJK UNIFIED IDEOGRAPH
+0xCBF0 0x6106 #CJK UNIFIED IDEOGRAPH
+0xCBF1 0x6957 #CJK UNIFIED IDEOGRAPH
+0xCBF2 0x8171 #CJK UNIFIED IDEOGRAPH
+0xCBF3 0x8654 #CJK UNIFIED IDEOGRAPH
+0xCBF4 0x8E47 #CJK UNIFIED IDEOGRAPH
+0xCBF5 0x9375 #CJK UNIFIED IDEOGRAPH
+0xCBF6 0x9A2B #CJK UNIFIED IDEOGRAPH
+0xCBF7 0x4E5E #CJK UNIFIED IDEOGRAPH
+0xCBF8 0x5091 #CJK UNIFIED IDEOGRAPH
+0xCBF9 0x6770 #CJK UNIFIED IDEOGRAPH
+0xCBFA 0x6840 #CJK UNIFIED IDEOGRAPH
+0xCBFB 0x5109 #CJK UNIFIED IDEOGRAPH
+0xCBFC 0x528D #CJK UNIFIED IDEOGRAPH
+0xCBFD 0x5292 #CJK UNIFIED IDEOGRAPH
+0xCBFE 0x6AA2 #CJK UNIFIED IDEOGRAPH
+0xCCA1 0x77BC #CJK UNIFIED IDEOGRAPH
+0xCCA2 0x9210 #CJK UNIFIED IDEOGRAPH
+0xCCA3 0x9ED4 #CJK UNIFIED IDEOGRAPH
+0xCCA4 0x52AB #CJK UNIFIED IDEOGRAPH
+0xCCA5 0x602F #CJK UNIFIED IDEOGRAPH
+0xCCA6 0x8FF2 #CJK UNIFIED IDEOGRAPH
+0xCCA7 0x5048 #CJK UNIFIED IDEOGRAPH
+0xCCA8 0x61A9 #CJK UNIFIED IDEOGRAPH
+0xCCA9 0x63ED #CJK UNIFIED IDEOGRAPH
+0xCCAA 0x64CA #CJK UNIFIED IDEOGRAPH
+0xCCAB 0x683C #CJK UNIFIED IDEOGRAPH
+0xCCAC 0x6A84 #CJK UNIFIED IDEOGRAPH
+0xCCAD 0x6FC0 #CJK UNIFIED IDEOGRAPH
+0xCCAE 0x8188 #CJK UNIFIED IDEOGRAPH
+0xCCAF 0x89A1 #CJK UNIFIED IDEOGRAPH
+0xCCB0 0x9694 #CJK UNIFIED IDEOGRAPH
+0xCCB1 0x5805 #CJK UNIFIED IDEOGRAPH
+0xCCB2 0x727D #CJK UNIFIED IDEOGRAPH
+0xCCB3 0x72AC #CJK UNIFIED IDEOGRAPH
+0xCCB4 0x7504 #CJK UNIFIED IDEOGRAPH
+0xCCB5 0x7D79 #CJK UNIFIED IDEOGRAPH
+0xCCB6 0x7E6D #CJK UNIFIED IDEOGRAPH
+0xCCB7 0x80A9 #CJK UNIFIED IDEOGRAPH
+0xCCB8 0x898B #CJK UNIFIED IDEOGRAPH
+0xCCB9 0x8B74 #CJK UNIFIED IDEOGRAPH
+0xCCBA 0x9063 #CJK UNIFIED IDEOGRAPH
+0xCCBB 0x9D51 #CJK UNIFIED IDEOGRAPH
+0xCCBC 0x6289 #CJK UNIFIED IDEOGRAPH
+0xCCBD 0x6C7A #CJK UNIFIED IDEOGRAPH
+0xCCBE 0x6F54 #CJK UNIFIED IDEOGRAPH
+0xCCBF 0x7D50 #CJK UNIFIED IDEOGRAPH
+0xCCC0 0x7F3A #CJK UNIFIED IDEOGRAPH
+0xCCC1 0x8A23 #CJK UNIFIED IDEOGRAPH
+0xCCC2 0x517C #CJK UNIFIED IDEOGRAPH
+0xCCC3 0x614A #CJK UNIFIED IDEOGRAPH
+0xCCC4 0x7B9D #CJK UNIFIED IDEOGRAPH
+0xCCC5 0x8B19 #CJK UNIFIED IDEOGRAPH
+0xCCC6 0x9257 #CJK UNIFIED IDEOGRAPH
+0xCCC7 0x938C #CJK UNIFIED IDEOGRAPH
+0xCCC8 0x4EAC #CJK UNIFIED IDEOGRAPH
+0xCCC9 0x4FD3 #CJK UNIFIED IDEOGRAPH
+0xCCCA 0x501E #CJK UNIFIED IDEOGRAPH
+0xCCCB 0x50BE #CJK UNIFIED IDEOGRAPH
+0xCCCC 0x5106 #CJK UNIFIED IDEOGRAPH
+0xCCCD 0x52C1 #CJK UNIFIED IDEOGRAPH
+0xCCCE 0x52CD #CJK UNIFIED IDEOGRAPH
+0xCCCF 0x537F #CJK UNIFIED IDEOGRAPH
+0xCCD0 0x5770 #CJK UNIFIED IDEOGRAPH
+0xCCD1 0x5883 #CJK UNIFIED IDEOGRAPH
+0xCCD2 0x5E9A #CJK UNIFIED IDEOGRAPH
+0xCCD3 0x5F91 #CJK UNIFIED IDEOGRAPH
+0xCCD4 0x6176 #CJK UNIFIED IDEOGRAPH
+0xCCD5 0x61AC #CJK UNIFIED IDEOGRAPH
+0xCCD6 0x64CE #CJK UNIFIED IDEOGRAPH
+0xCCD7 0x656C #CJK UNIFIED IDEOGRAPH
+0xCCD8 0x666F #CJK UNIFIED IDEOGRAPH
+0xCCD9 0x66BB #CJK UNIFIED IDEOGRAPH
+0xCCDA 0x66F4 #CJK UNIFIED IDEOGRAPH
+0xCCDB 0x6897 #CJK UNIFIED IDEOGRAPH
+0xCCDC 0x6D87 #CJK UNIFIED IDEOGRAPH
+0xCCDD 0x7085 #CJK UNIFIED IDEOGRAPH
+0xCCDE 0x70F1 #CJK UNIFIED IDEOGRAPH
+0xCCDF 0x749F #CJK UNIFIED IDEOGRAPH
+0xCCE0 0x74A5 #CJK UNIFIED IDEOGRAPH
+0xCCE1 0x74CA #CJK UNIFIED IDEOGRAPH
+0xCCE2 0x75D9 #CJK UNIFIED IDEOGRAPH
+0xCCE3 0x786C #CJK UNIFIED IDEOGRAPH
+0xCCE4 0x78EC #CJK UNIFIED IDEOGRAPH
+0xCCE5 0x7ADF #CJK UNIFIED IDEOGRAPH
+0xCCE6 0x7AF6 #CJK UNIFIED IDEOGRAPH
+0xCCE7 0x7D45 #CJK UNIFIED IDEOGRAPH
+0xCCE8 0x7D93 #CJK UNIFIED IDEOGRAPH
+0xCCE9 0x8015 #CJK UNIFIED IDEOGRAPH
+0xCCEA 0x803F #CJK UNIFIED IDEOGRAPH
+0xCCEB 0x811B #CJK UNIFIED IDEOGRAPH
+0xCCEC 0x8396 #CJK UNIFIED IDEOGRAPH
+0xCCED 0x8B66 #CJK UNIFIED IDEOGRAPH
+0xCCEE 0x8F15 #CJK UNIFIED IDEOGRAPH
+0xCCEF 0x9015 #CJK UNIFIED IDEOGRAPH
+0xCCF0 0x93E1 #CJK UNIFIED IDEOGRAPH
+0xCCF1 0x9803 #CJK UNIFIED IDEOGRAPH
+0xCCF2 0x9838 #CJK UNIFIED IDEOGRAPH
+0xCCF3 0x9A5A #CJK UNIFIED IDEOGRAPH
+0xCCF4 0x9BE8 #CJK UNIFIED IDEOGRAPH
+0xCCF5 0x4FC2 #CJK UNIFIED IDEOGRAPH
+0xCCF6 0x5553 #CJK UNIFIED IDEOGRAPH
+0xCCF7 0x583A #CJK UNIFIED IDEOGRAPH
+0xCCF8 0x5951 #CJK UNIFIED IDEOGRAPH
+0xCCF9 0x5B63 #CJK UNIFIED IDEOGRAPH
+0xCCFA 0x5C46 #CJK UNIFIED IDEOGRAPH
+0xCCFB 0x60B8 #CJK UNIFIED IDEOGRAPH
+0xCCFC 0x6212 #CJK UNIFIED IDEOGRAPH
+0xCCFD 0x6842 #CJK UNIFIED IDEOGRAPH
+0xCCFE 0x68B0 #CJK UNIFIED IDEOGRAPH
+0xCDA1 0x68E8 #CJK UNIFIED IDEOGRAPH
+0xCDA2 0x6EAA #CJK UNIFIED IDEOGRAPH
+0xCDA3 0x754C #CJK UNIFIED IDEOGRAPH
+0xCDA4 0x7678 #CJK UNIFIED IDEOGRAPH
+0xCDA5 0x78CE #CJK UNIFIED IDEOGRAPH
+0xCDA6 0x7A3D #CJK UNIFIED IDEOGRAPH
+0xCDA7 0x7CFB #CJK UNIFIED IDEOGRAPH
+0xCDA8 0x7E6B #CJK UNIFIED IDEOGRAPH
+0xCDA9 0x7E7C #CJK UNIFIED IDEOGRAPH
+0xCDAA 0x8A08 #CJK UNIFIED IDEOGRAPH
+0xCDAB 0x8AA1 #CJK UNIFIED IDEOGRAPH
+0xCDAC 0x8C3F #CJK UNIFIED IDEOGRAPH
+0xCDAD 0x968E #CJK UNIFIED IDEOGRAPH
+0xCDAE 0x9DC4 #CJK UNIFIED IDEOGRAPH
+0xCDAF 0x53E4 #CJK UNIFIED IDEOGRAPH
+0xCDB0 0x53E9 #CJK UNIFIED IDEOGRAPH
+0xCDB1 0x544A #CJK UNIFIED IDEOGRAPH
+0xCDB2 0x5471 #CJK UNIFIED IDEOGRAPH
+0xCDB3 0x56FA #CJK UNIFIED IDEOGRAPH
+0xCDB4 0x59D1 #CJK UNIFIED IDEOGRAPH
+0xCDB5 0x5B64 #CJK UNIFIED IDEOGRAPH
+0xCDB6 0x5C3B #CJK UNIFIED IDEOGRAPH
+0xCDB7 0x5EAB #CJK UNIFIED IDEOGRAPH
+0xCDB8 0x62F7 #CJK UNIFIED IDEOGRAPH
+0xCDB9 0x6537 #CJK UNIFIED IDEOGRAPH
+0xCDBA 0x6545 #CJK UNIFIED IDEOGRAPH
+0xCDBB 0x6572 #CJK UNIFIED IDEOGRAPH
+0xCDBC 0x66A0 #CJK UNIFIED IDEOGRAPH
+0xCDBD 0x67AF #CJK UNIFIED IDEOGRAPH
+0xCDBE 0x69C1 #CJK UNIFIED IDEOGRAPH
+0xCDBF 0x6CBD #CJK UNIFIED IDEOGRAPH
+0xCDC0 0x75FC #CJK UNIFIED IDEOGRAPH
+0xCDC1 0x7690 #CJK UNIFIED IDEOGRAPH
+0xCDC2 0x777E #CJK UNIFIED IDEOGRAPH
+0xCDC3 0x7A3F #CJK UNIFIED IDEOGRAPH
+0xCDC4 0x7F94 #CJK UNIFIED IDEOGRAPH
+0xCDC5 0x8003 #CJK UNIFIED IDEOGRAPH
+0xCDC6 0x80A1 #CJK UNIFIED IDEOGRAPH
+0xCDC7 0x818F #CJK UNIFIED IDEOGRAPH
+0xCDC8 0x82E6 #CJK UNIFIED IDEOGRAPH
+0xCDC9 0x82FD #CJK UNIFIED IDEOGRAPH
+0xCDCA 0x83F0 #CJK UNIFIED IDEOGRAPH
+0xCDCB 0x85C1 #CJK UNIFIED IDEOGRAPH
+0xCDCC 0x8831 #CJK UNIFIED IDEOGRAPH
+0xCDCD 0x88B4 #CJK UNIFIED IDEOGRAPH
+0xCDCE 0x8AA5 #CJK UNIFIED IDEOGRAPH
+0xCDCF 0xF903 #CJK COMPATIBILITY IDEOGRAPH
+0xCDD0 0x8F9C #CJK UNIFIED IDEOGRAPH
+0xCDD1 0x932E #CJK UNIFIED IDEOGRAPH
+0xCDD2 0x96C7 #CJK UNIFIED IDEOGRAPH
+0xCDD3 0x9867 #CJK UNIFIED IDEOGRAPH
+0xCDD4 0x9AD8 #CJK UNIFIED IDEOGRAPH
+0xCDD5 0x9F13 #CJK UNIFIED IDEOGRAPH
+0xCDD6 0x54ED #CJK UNIFIED IDEOGRAPH
+0xCDD7 0x659B #CJK UNIFIED IDEOGRAPH
+0xCDD8 0x66F2 #CJK UNIFIED IDEOGRAPH
+0xCDD9 0x688F #CJK UNIFIED IDEOGRAPH
+0xCDDA 0x7A40 #CJK UNIFIED IDEOGRAPH
+0xCDDB 0x8C37 #CJK UNIFIED IDEOGRAPH
+0xCDDC 0x9D60 #CJK UNIFIED IDEOGRAPH
+0xCDDD 0x56F0 #CJK UNIFIED IDEOGRAPH
+0xCDDE 0x5764 #CJK UNIFIED IDEOGRAPH
+0xCDDF 0x5D11 #CJK UNIFIED IDEOGRAPH
+0xCDE0 0x6606 #CJK UNIFIED IDEOGRAPH
+0xCDE1 0x68B1 #CJK UNIFIED IDEOGRAPH
+0xCDE2 0x68CD #CJK UNIFIED IDEOGRAPH
+0xCDE3 0x6EFE #CJK UNIFIED IDEOGRAPH
+0xCDE4 0x7428 #CJK UNIFIED IDEOGRAPH
+0xCDE5 0x889E #CJK UNIFIED IDEOGRAPH
+0xCDE6 0x9BE4 #CJK UNIFIED IDEOGRAPH
+0xCDE7 0x6C68 #CJK UNIFIED IDEOGRAPH
+0xCDE8 0xF904 #CJK COMPATIBILITY IDEOGRAPH
+0xCDE9 0x9AA8 #CJK UNIFIED IDEOGRAPH
+0xCDEA 0x4F9B #CJK UNIFIED IDEOGRAPH
+0xCDEB 0x516C #CJK UNIFIED IDEOGRAPH
+0xCDEC 0x5171 #CJK UNIFIED IDEOGRAPH
+0xCDED 0x529F #CJK UNIFIED IDEOGRAPH
+0xCDEE 0x5B54 #CJK UNIFIED IDEOGRAPH
+0xCDEF 0x5DE5 #CJK UNIFIED IDEOGRAPH
+0xCDF0 0x6050 #CJK UNIFIED IDEOGRAPH
+0xCDF1 0x606D #CJK UNIFIED IDEOGRAPH
+0xCDF2 0x62F1 #CJK UNIFIED IDEOGRAPH
+0xCDF3 0x63A7 #CJK UNIFIED IDEOGRAPH
+0xCDF4 0x653B #CJK UNIFIED IDEOGRAPH
+0xCDF5 0x73D9 #CJK UNIFIED IDEOGRAPH
+0xCDF6 0x7A7A #CJK UNIFIED IDEOGRAPH
+0xCDF7 0x86A3 #CJK UNIFIED IDEOGRAPH
+0xCDF8 0x8CA2 #CJK UNIFIED IDEOGRAPH
+0xCDF9 0x978F #CJK UNIFIED IDEOGRAPH
+0xCDFA 0x4E32 #CJK UNIFIED IDEOGRAPH
+0xCDFB 0x5BE1 #CJK UNIFIED IDEOGRAPH
+0xCDFC 0x6208 #CJK UNIFIED IDEOGRAPH
+0xCDFD 0x679C #CJK UNIFIED IDEOGRAPH
+0xCDFE 0x74DC #CJK UNIFIED IDEOGRAPH
+0xCEA1 0x79D1 #CJK UNIFIED IDEOGRAPH
+0xCEA2 0x83D3 #CJK UNIFIED IDEOGRAPH
+0xCEA3 0x8A87 #CJK UNIFIED IDEOGRAPH
+0xCEA4 0x8AB2 #CJK UNIFIED IDEOGRAPH
+0xCEA5 0x8DE8 #CJK UNIFIED IDEOGRAPH
+0xCEA6 0x904E #CJK UNIFIED IDEOGRAPH
+0xCEA7 0x934B #CJK UNIFIED IDEOGRAPH
+0xCEA8 0x9846 #CJK UNIFIED IDEOGRAPH
+0xCEA9 0x5ED3 #CJK UNIFIED IDEOGRAPH
+0xCEAA 0x69E8 #CJK UNIFIED IDEOGRAPH
+0xCEAB 0x85FF #CJK UNIFIED IDEOGRAPH
+0xCEAC 0x90ED #CJK UNIFIED IDEOGRAPH
+0xCEAD 0xF905 #CJK COMPATIBILITY IDEOGRAPH
+0xCEAE 0x51A0 #CJK UNIFIED IDEOGRAPH
+0xCEAF 0x5B98 #CJK UNIFIED IDEOGRAPH
+0xCEB0 0x5BEC #CJK UNIFIED IDEOGRAPH
+0xCEB1 0x6163 #CJK UNIFIED IDEOGRAPH
+0xCEB2 0x68FA #CJK UNIFIED IDEOGRAPH
+0xCEB3 0x6B3E #CJK UNIFIED IDEOGRAPH
+0xCEB4 0x704C #CJK UNIFIED IDEOGRAPH
+0xCEB5 0x742F #CJK UNIFIED IDEOGRAPH
+0xCEB6 0x74D8 #CJK UNIFIED IDEOGRAPH
+0xCEB7 0x7BA1 #CJK UNIFIED IDEOGRAPH
+0xCEB8 0x7F50 #CJK UNIFIED IDEOGRAPH
+0xCEB9 0x83C5 #CJK UNIFIED IDEOGRAPH
+0xCEBA 0x89C0 #CJK UNIFIED IDEOGRAPH
+0xCEBB 0x8CAB #CJK UNIFIED IDEOGRAPH
+0xCEBC 0x95DC #CJK UNIFIED IDEOGRAPH
+0xCEBD 0x9928 #CJK UNIFIED IDEOGRAPH
+0xCEBE 0x522E #CJK UNIFIED IDEOGRAPH
+0xCEBF 0x605D #CJK UNIFIED IDEOGRAPH
+0xCEC0 0x62EC #CJK UNIFIED IDEOGRAPH
+0xCEC1 0x9002 #CJK UNIFIED IDEOGRAPH
+0xCEC2 0x4F8A #CJK UNIFIED IDEOGRAPH
+0xCEC3 0x5149 #CJK UNIFIED IDEOGRAPH
+0xCEC4 0x5321 #CJK UNIFIED IDEOGRAPH
+0xCEC5 0x58D9 #CJK UNIFIED IDEOGRAPH
+0xCEC6 0x5EE3 #CJK UNIFIED IDEOGRAPH
+0xCEC7 0x66E0 #CJK UNIFIED IDEOGRAPH
+0xCEC8 0x6D38 #CJK UNIFIED IDEOGRAPH
+0xCEC9 0x709A #CJK UNIFIED IDEOGRAPH
+0xCECA 0x72C2 #CJK UNIFIED IDEOGRAPH
+0xCECB 0x73D6 #CJK UNIFIED IDEOGRAPH
+0xCECC 0x7B50 #CJK UNIFIED IDEOGRAPH
+0xCECD 0x80F1 #CJK UNIFIED IDEOGRAPH
+0xCECE 0x945B #CJK UNIFIED IDEOGRAPH
+0xCECF 0x5366 #CJK UNIFIED IDEOGRAPH
+0xCED0 0x639B #CJK UNIFIED IDEOGRAPH
+0xCED1 0x7F6B #CJK UNIFIED IDEOGRAPH
+0xCED2 0x4E56 #CJK UNIFIED IDEOGRAPH
+0xCED3 0x5080 #CJK UNIFIED IDEOGRAPH
+0xCED4 0x584A #CJK UNIFIED IDEOGRAPH
+0xCED5 0x58DE #CJK UNIFIED IDEOGRAPH
+0xCED6 0x602A #CJK UNIFIED IDEOGRAPH
+0xCED7 0x6127 #CJK UNIFIED IDEOGRAPH
+0xCED8 0x62D0 #CJK UNIFIED IDEOGRAPH
+0xCED9 0x69D0 #CJK UNIFIED IDEOGRAPH
+0xCEDA 0x9B41 #CJK UNIFIED IDEOGRAPH
+0xCEDB 0x5B8F #CJK UNIFIED IDEOGRAPH
+0xCEDC 0x7D18 #CJK UNIFIED IDEOGRAPH
+0xCEDD 0x80B1 #CJK UNIFIED IDEOGRAPH
+0xCEDE 0x8F5F #CJK UNIFIED IDEOGRAPH
+0xCEDF 0x4EA4 #CJK UNIFIED IDEOGRAPH
+0xCEE0 0x50D1 #CJK UNIFIED IDEOGRAPH
+0xCEE1 0x54AC #CJK UNIFIED IDEOGRAPH
+0xCEE2 0x55AC #CJK UNIFIED IDEOGRAPH
+0xCEE3 0x5B0C #CJK UNIFIED IDEOGRAPH
+0xCEE4 0x5DA0 #CJK UNIFIED IDEOGRAPH
+0xCEE5 0x5DE7 #CJK UNIFIED IDEOGRAPH
+0xCEE6 0x652A #CJK UNIFIED IDEOGRAPH
+0xCEE7 0x654E #CJK UNIFIED IDEOGRAPH
+0xCEE8 0x6821 #CJK UNIFIED IDEOGRAPH
+0xCEE9 0x6A4B #CJK UNIFIED IDEOGRAPH
+0xCEEA 0x72E1 #CJK UNIFIED IDEOGRAPH
+0xCEEB 0x768E #CJK UNIFIED IDEOGRAPH
+0xCEEC 0x77EF #CJK UNIFIED IDEOGRAPH
+0xCEED 0x7D5E #CJK UNIFIED IDEOGRAPH
+0xCEEE 0x7FF9 #CJK UNIFIED IDEOGRAPH
+0xCEEF 0x81A0 #CJK UNIFIED IDEOGRAPH
+0xCEF0 0x854E #CJK UNIFIED IDEOGRAPH
+0xCEF1 0x86DF #CJK UNIFIED IDEOGRAPH
+0xCEF2 0x8F03 #CJK UNIFIED IDEOGRAPH
+0xCEF3 0x8F4E #CJK UNIFIED IDEOGRAPH
+0xCEF4 0x90CA #CJK UNIFIED IDEOGRAPH
+0xCEF5 0x9903 #CJK UNIFIED IDEOGRAPH
+0xCEF6 0x9A55 #CJK UNIFIED IDEOGRAPH
+0xCEF7 0x9BAB #CJK UNIFIED IDEOGRAPH
+0xCEF8 0x4E18 #CJK UNIFIED IDEOGRAPH
+0xCEF9 0x4E45 #CJK UNIFIED IDEOGRAPH
+0xCEFA 0x4E5D #CJK UNIFIED IDEOGRAPH
+0xCEFB 0x4EC7 #CJK UNIFIED IDEOGRAPH
+0xCEFC 0x4FF1 #CJK UNIFIED IDEOGRAPH
+0xCEFD 0x5177 #CJK UNIFIED IDEOGRAPH
+0xCEFE 0x52FE #CJK UNIFIED IDEOGRAPH
+0xCFA1 0x5340 #CJK UNIFIED IDEOGRAPH
+0xCFA2 0x53E3 #CJK UNIFIED IDEOGRAPH
+0xCFA3 0x53E5 #CJK UNIFIED IDEOGRAPH
+0xCFA4 0x548E #CJK UNIFIED IDEOGRAPH
+0xCFA5 0x5614 #CJK UNIFIED IDEOGRAPH
+0xCFA6 0x5775 #CJK UNIFIED IDEOGRAPH
+0xCFA7 0x57A2 #CJK UNIFIED IDEOGRAPH
+0xCFA8 0x5BC7 #CJK UNIFIED IDEOGRAPH
+0xCFA9 0x5D87 #CJK UNIFIED IDEOGRAPH
+0xCFAA 0x5ED0 #CJK UNIFIED IDEOGRAPH
+0xCFAB 0x61FC #CJK UNIFIED IDEOGRAPH
+0xCFAC 0x62D8 #CJK UNIFIED IDEOGRAPH
+0xCFAD 0x6551 #CJK UNIFIED IDEOGRAPH
+0xCFAE 0x67B8 #CJK UNIFIED IDEOGRAPH
+0xCFAF 0x67E9 #CJK UNIFIED IDEOGRAPH
+0xCFB0 0x69CB #CJK UNIFIED IDEOGRAPH
+0xCFB1 0x6B50 #CJK UNIFIED IDEOGRAPH
+0xCFB2 0x6BC6 #CJK UNIFIED IDEOGRAPH
+0xCFB3 0x6BEC #CJK UNIFIED IDEOGRAPH
+0xCFB4 0x6C42 #CJK UNIFIED IDEOGRAPH
+0xCFB5 0x6E9D #CJK UNIFIED IDEOGRAPH
+0xCFB6 0x7078 #CJK UNIFIED IDEOGRAPH
+0xCFB7 0x72D7 #CJK UNIFIED IDEOGRAPH
+0xCFB8 0x7396 #CJK UNIFIED IDEOGRAPH
+0xCFB9 0x7403 #CJK UNIFIED IDEOGRAPH
+0xCFBA 0x77BF #CJK UNIFIED IDEOGRAPH
+0xCFBB 0x77E9 #CJK UNIFIED IDEOGRAPH
+0xCFBC 0x7A76 #CJK UNIFIED IDEOGRAPH
+0xCFBD 0x7D7F #CJK UNIFIED IDEOGRAPH
+0xCFBE 0x8009 #CJK UNIFIED IDEOGRAPH
+0xCFBF 0x81FC #CJK UNIFIED IDEOGRAPH
+0xCFC0 0x8205 #CJK UNIFIED IDEOGRAPH
+0xCFC1 0x820A #CJK UNIFIED IDEOGRAPH
+0xCFC2 0x82DF #CJK UNIFIED IDEOGRAPH
+0xCFC3 0x8862 #CJK UNIFIED IDEOGRAPH
+0xCFC4 0x8B33 #CJK UNIFIED IDEOGRAPH
+0xCFC5 0x8CFC #CJK UNIFIED IDEOGRAPH
+0xCFC6 0x8EC0 #CJK UNIFIED IDEOGRAPH
+0xCFC7 0x9011 #CJK UNIFIED IDEOGRAPH
+0xCFC8 0x90B1 #CJK UNIFIED IDEOGRAPH
+0xCFC9 0x9264 #CJK UNIFIED IDEOGRAPH
+0xCFCA 0x92B6 #CJK UNIFIED IDEOGRAPH
+0xCFCB 0x99D2 #CJK UNIFIED IDEOGRAPH
+0xCFCC 0x9A45 #CJK UNIFIED IDEOGRAPH
+0xCFCD 0x9CE9 #CJK UNIFIED IDEOGRAPH
+0xCFCE 0x9DD7 #CJK UNIFIED IDEOGRAPH
+0xCFCF 0x9F9C #CJK UNIFIED IDEOGRAPH
+0xCFD0 0x570B #CJK UNIFIED IDEOGRAPH
+0xCFD1 0x5C40 #CJK UNIFIED IDEOGRAPH
+0xCFD2 0x83CA #CJK UNIFIED IDEOGRAPH
+0xCFD3 0x97A0 #CJK UNIFIED IDEOGRAPH
+0xCFD4 0x97AB #CJK UNIFIED IDEOGRAPH
+0xCFD5 0x9EB4 #CJK UNIFIED IDEOGRAPH
+0xCFD6 0x541B #CJK UNIFIED IDEOGRAPH
+0xCFD7 0x7A98 #CJK UNIFIED IDEOGRAPH
+0xCFD8 0x7FA4 #CJK UNIFIED IDEOGRAPH
+0xCFD9 0x88D9 #CJK UNIFIED IDEOGRAPH
+0xCFDA 0x8ECD #CJK UNIFIED IDEOGRAPH
+0xCFDB 0x90E1 #CJK UNIFIED IDEOGRAPH
+0xCFDC 0x5800 #CJK UNIFIED IDEOGRAPH
+0xCFDD 0x5C48 #CJK UNIFIED IDEOGRAPH
+0xCFDE 0x6398 #CJK UNIFIED IDEOGRAPH
+0xCFDF 0x7A9F #CJK UNIFIED IDEOGRAPH
+0xCFE0 0x5BAE #CJK UNIFIED IDEOGRAPH
+0xCFE1 0x5F13 #CJK UNIFIED IDEOGRAPH
+0xCFE2 0x7A79 #CJK UNIFIED IDEOGRAPH
+0xCFE3 0x7AAE #CJK UNIFIED IDEOGRAPH
+0xCFE4 0x828E #CJK UNIFIED IDEOGRAPH
+0xCFE5 0x8EAC #CJK UNIFIED IDEOGRAPH
+0xCFE6 0x5026 #CJK UNIFIED IDEOGRAPH
+0xCFE7 0x5238 #CJK UNIFIED IDEOGRAPH
+0xCFE8 0x52F8 #CJK UNIFIED IDEOGRAPH
+0xCFE9 0x5377 #CJK UNIFIED IDEOGRAPH
+0xCFEA 0x5708 #CJK UNIFIED IDEOGRAPH
+0xCFEB 0x62F3 #CJK UNIFIED IDEOGRAPH
+0xCFEC 0x6372 #CJK UNIFIED IDEOGRAPH
+0xCFED 0x6B0A #CJK UNIFIED IDEOGRAPH
+0xCFEE 0x6DC3 #CJK UNIFIED IDEOGRAPH
+0xCFEF 0x7737 #CJK UNIFIED IDEOGRAPH
+0xCFF0 0x53A5 #CJK UNIFIED IDEOGRAPH
+0xCFF1 0x7357 #CJK UNIFIED IDEOGRAPH
+0xCFF2 0x8568 #CJK UNIFIED IDEOGRAPH
+0xCFF3 0x8E76 #CJK UNIFIED IDEOGRAPH
+0xCFF4 0x95D5 #CJK UNIFIED IDEOGRAPH
+0xCFF5 0x673A #CJK UNIFIED IDEOGRAPH
+0xCFF6 0x6AC3 #CJK UNIFIED IDEOGRAPH
+0xCFF7 0x6F70 #CJK UNIFIED IDEOGRAPH
+0xCFF8 0x8A6D #CJK UNIFIED IDEOGRAPH
+0xCFF9 0x8ECC #CJK UNIFIED IDEOGRAPH
+0xCFFA 0x994B #CJK UNIFIED IDEOGRAPH
+0xCFFB 0xF906 #CJK COMPATIBILITY IDEOGRAPH
+0xCFFC 0x6677 #CJK UNIFIED IDEOGRAPH
+0xCFFD 0x6B78 #CJK UNIFIED IDEOGRAPH
+0xCFFE 0x8CB4 #CJK UNIFIED IDEOGRAPH
+0xD0A1 0x9B3C #CJK UNIFIED IDEOGRAPH
+0xD0A2 0xF907 #CJK COMPATIBILITY IDEOGRAPH
+0xD0A3 0x53EB #CJK UNIFIED IDEOGRAPH
+0xD0A4 0x572D #CJK UNIFIED IDEOGRAPH
+0xD0A5 0x594E #CJK UNIFIED IDEOGRAPH
+0xD0A6 0x63C6 #CJK UNIFIED IDEOGRAPH
+0xD0A7 0x69FB #CJK UNIFIED IDEOGRAPH
+0xD0A8 0x73EA #CJK UNIFIED IDEOGRAPH
+0xD0A9 0x7845 #CJK UNIFIED IDEOGRAPH
+0xD0AA 0x7ABA #CJK UNIFIED IDEOGRAPH
+0xD0AB 0x7AC5 #CJK UNIFIED IDEOGRAPH
+0xD0AC 0x7CFE #CJK UNIFIED IDEOGRAPH
+0xD0AD 0x8475 #CJK UNIFIED IDEOGRAPH
+0xD0AE 0x898F #CJK UNIFIED IDEOGRAPH
+0xD0AF 0x8D73 #CJK UNIFIED IDEOGRAPH
+0xD0B0 0x9035 #CJK UNIFIED IDEOGRAPH
+0xD0B1 0x95A8 #CJK UNIFIED IDEOGRAPH
+0xD0B2 0x52FB #CJK UNIFIED IDEOGRAPH
+0xD0B3 0x5747 #CJK UNIFIED IDEOGRAPH
+0xD0B4 0x7547 #CJK UNIFIED IDEOGRAPH
+0xD0B5 0x7B60 #CJK UNIFIED IDEOGRAPH
+0xD0B6 0x83CC #CJK UNIFIED IDEOGRAPH
+0xD0B7 0x921E #CJK UNIFIED IDEOGRAPH
+0xD0B8 0xF908 #CJK COMPATIBILITY IDEOGRAPH
+0xD0B9 0x6A58 #CJK UNIFIED IDEOGRAPH
+0xD0BA 0x514B #CJK UNIFIED IDEOGRAPH
+0xD0BB 0x524B #CJK UNIFIED IDEOGRAPH
+0xD0BC 0x5287 #CJK UNIFIED IDEOGRAPH
+0xD0BD 0x621F #CJK UNIFIED IDEOGRAPH
+0xD0BE 0x68D8 #CJK UNIFIED IDEOGRAPH
+0xD0BF 0x6975 #CJK UNIFIED IDEOGRAPH
+0xD0C0 0x9699 #CJK UNIFIED IDEOGRAPH
+0xD0C1 0x50C5 #CJK UNIFIED IDEOGRAPH
+0xD0C2 0x52A4 #CJK UNIFIED IDEOGRAPH
+0xD0C3 0x52E4 #CJK UNIFIED IDEOGRAPH
+0xD0C4 0x61C3 #CJK UNIFIED IDEOGRAPH
+0xD0C5 0x65A4 #CJK UNIFIED IDEOGRAPH
+0xD0C6 0x6839 #CJK UNIFIED IDEOGRAPH
+0xD0C7 0x69FF #CJK UNIFIED IDEOGRAPH
+0xD0C8 0x747E #CJK UNIFIED IDEOGRAPH
+0xD0C9 0x7B4B #CJK UNIFIED IDEOGRAPH
+0xD0CA 0x82B9 #CJK UNIFIED IDEOGRAPH
+0xD0CB 0x83EB #CJK UNIFIED IDEOGRAPH
+0xD0CC 0x89B2 #CJK UNIFIED IDEOGRAPH
+0xD0CD 0x8B39 #CJK UNIFIED IDEOGRAPH
+0xD0CE 0x8FD1 #CJK UNIFIED IDEOGRAPH
+0xD0CF 0x9949 #CJK UNIFIED IDEOGRAPH
+0xD0D0 0xF909 #CJK COMPATIBILITY IDEOGRAPH
+0xD0D1 0x4ECA #CJK UNIFIED IDEOGRAPH
+0xD0D2 0x5997 #CJK UNIFIED IDEOGRAPH
+0xD0D3 0x64D2 #CJK UNIFIED IDEOGRAPH
+0xD0D4 0x6611 #CJK UNIFIED IDEOGRAPH
+0xD0D5 0x6A8E #CJK UNIFIED IDEOGRAPH
+0xD0D6 0x7434 #CJK UNIFIED IDEOGRAPH
+0xD0D7 0x7981 #CJK UNIFIED IDEOGRAPH
+0xD0D8 0x79BD #CJK UNIFIED IDEOGRAPH
+0xD0D9 0x82A9 #CJK UNIFIED IDEOGRAPH
+0xD0DA 0x887E #CJK UNIFIED IDEOGRAPH
+0xD0DB 0x887F #CJK UNIFIED IDEOGRAPH
+0xD0DC 0x895F #CJK UNIFIED IDEOGRAPH
+0xD0DD 0xF90A #CJK COMPATIBILITY IDEOGRAPH
+0xD0DE 0x9326 #CJK UNIFIED IDEOGRAPH
+0xD0DF 0x4F0B #CJK UNIFIED IDEOGRAPH
+0xD0E0 0x53CA #CJK UNIFIED IDEOGRAPH
+0xD0E1 0x6025 #CJK UNIFIED IDEOGRAPH
+0xD0E2 0x6271 #CJK UNIFIED IDEOGRAPH
+0xD0E3 0x6C72 #CJK UNIFIED IDEOGRAPH
+0xD0E4 0x7D1A #CJK UNIFIED IDEOGRAPH
+0xD0E5 0x7D66 #CJK UNIFIED IDEOGRAPH
+0xD0E6 0x4E98 #CJK UNIFIED IDEOGRAPH
+0xD0E7 0x5162 #CJK UNIFIED IDEOGRAPH
+0xD0E8 0x77DC #CJK UNIFIED IDEOGRAPH
+0xD0E9 0x80AF #CJK UNIFIED IDEOGRAPH
+0xD0EA 0x4F01 #CJK UNIFIED IDEOGRAPH
+0xD0EB 0x4F0E #CJK UNIFIED IDEOGRAPH
+0xD0EC 0x5176 #CJK UNIFIED IDEOGRAPH
+0xD0ED 0x5180 #CJK UNIFIED IDEOGRAPH
+0xD0EE 0x55DC #CJK UNIFIED IDEOGRAPH
+0xD0EF 0x5668 #CJK UNIFIED IDEOGRAPH
+0xD0F0 0x573B #CJK UNIFIED IDEOGRAPH
+0xD0F1 0x57FA #CJK UNIFIED IDEOGRAPH
+0xD0F2 0x57FC #CJK UNIFIED IDEOGRAPH
+0xD0F3 0x5914 #CJK UNIFIED IDEOGRAPH
+0xD0F4 0x5947 #CJK UNIFIED IDEOGRAPH
+0xD0F5 0x5993 #CJK UNIFIED IDEOGRAPH
+0xD0F6 0x5BC4 #CJK UNIFIED IDEOGRAPH
+0xD0F7 0x5C90 #CJK UNIFIED IDEOGRAPH
+0xD0F8 0x5D0E #CJK UNIFIED IDEOGRAPH
+0xD0F9 0x5DF1 #CJK UNIFIED IDEOGRAPH
+0xD0FA 0x5E7E #CJK UNIFIED IDEOGRAPH
+0xD0FB 0x5FCC #CJK UNIFIED IDEOGRAPH
+0xD0FC 0x6280 #CJK UNIFIED IDEOGRAPH
+0xD0FD 0x65D7 #CJK UNIFIED IDEOGRAPH
+0xD0FE 0x65E3 #CJK UNIFIED IDEOGRAPH
+0xD1A1 0x671E #CJK UNIFIED IDEOGRAPH
+0xD1A2 0x671F #CJK UNIFIED IDEOGRAPH
+0xD1A3 0x675E #CJK UNIFIED IDEOGRAPH
+0xD1A4 0x68CB #CJK UNIFIED IDEOGRAPH
+0xD1A5 0x68C4 #CJK UNIFIED IDEOGRAPH
+0xD1A6 0x6A5F #CJK UNIFIED IDEOGRAPH
+0xD1A7 0x6B3A #CJK UNIFIED IDEOGRAPH
+0xD1A8 0x6C23 #CJK UNIFIED IDEOGRAPH
+0xD1A9 0x6C7D #CJK UNIFIED IDEOGRAPH
+0xD1AA 0x6C82 #CJK UNIFIED IDEOGRAPH
+0xD1AB 0x6DC7 #CJK UNIFIED IDEOGRAPH
+0xD1AC 0x7398 #CJK UNIFIED IDEOGRAPH
+0xD1AD 0x7426 #CJK UNIFIED IDEOGRAPH
+0xD1AE 0x742A #CJK UNIFIED IDEOGRAPH
+0xD1AF 0x7482 #CJK UNIFIED IDEOGRAPH
+0xD1B0 0x74A3 #CJK UNIFIED IDEOGRAPH
+0xD1B1 0x7578 #CJK UNIFIED IDEOGRAPH
+0xD1B2 0x757F #CJK UNIFIED IDEOGRAPH
+0xD1B3 0x7881 #CJK UNIFIED IDEOGRAPH
+0xD1B4 0x78EF #CJK UNIFIED IDEOGRAPH
+0xD1B5 0x7941 #CJK UNIFIED IDEOGRAPH
+0xD1B6 0x7947 #CJK UNIFIED IDEOGRAPH
+0xD1B7 0x7948 #CJK UNIFIED IDEOGRAPH
+0xD1B8 0x797A #CJK UNIFIED IDEOGRAPH
+0xD1B9 0x7B95 #CJK UNIFIED IDEOGRAPH
+0xD1BA 0x7D00 #CJK UNIFIED IDEOGRAPH
+0xD1BB 0x7DBA #CJK UNIFIED IDEOGRAPH
+0xD1BC 0x7F88 #CJK UNIFIED IDEOGRAPH
+0xD1BD 0x8006 #CJK UNIFIED IDEOGRAPH
+0xD1BE 0x802D #CJK UNIFIED IDEOGRAPH
+0xD1BF 0x808C #CJK UNIFIED IDEOGRAPH
+0xD1C0 0x8A18 #CJK UNIFIED IDEOGRAPH
+0xD1C1 0x8B4F #CJK UNIFIED IDEOGRAPH
+0xD1C2 0x8C48 #CJK UNIFIED IDEOGRAPH
+0xD1C3 0x8D77 #CJK UNIFIED IDEOGRAPH
+0xD1C4 0x9321 #CJK UNIFIED IDEOGRAPH
+0xD1C5 0x9324 #CJK UNIFIED IDEOGRAPH
+0xD1C6 0x98E2 #CJK UNIFIED IDEOGRAPH
+0xD1C7 0x9951 #CJK UNIFIED IDEOGRAPH
+0xD1C8 0x9A0E #CJK UNIFIED IDEOGRAPH
+0xD1C9 0x9A0F #CJK UNIFIED IDEOGRAPH
+0xD1CA 0x9A65 #CJK UNIFIED IDEOGRAPH
+0xD1CB 0x9E92 #CJK UNIFIED IDEOGRAPH
+0xD1CC 0x7DCA #CJK UNIFIED IDEOGRAPH
+0xD1CD 0x4F76 #CJK UNIFIED IDEOGRAPH
+0xD1CE 0x5409 #CJK UNIFIED IDEOGRAPH
+0xD1CF 0x62EE #CJK UNIFIED IDEOGRAPH
+0xD1D0 0x6854 #CJK UNIFIED IDEOGRAPH
+0xD1D1 0x91D1 #CJK UNIFIED IDEOGRAPH
+0xD1D2 0x55AB #CJK UNIFIED IDEOGRAPH
+0xD1D3 0x513A #CJK UNIFIED IDEOGRAPH
+0xD1D4 0xF90B #CJK COMPATIBILITY IDEOGRAPH
+0xD1D5 0xF90C #CJK COMPATIBILITY IDEOGRAPH
+0xD1D6 0x5A1C #CJK UNIFIED IDEOGRAPH
+0xD1D7 0x61E6 #CJK UNIFIED IDEOGRAPH
+0xD1D8 0xF90D #CJK COMPATIBILITY IDEOGRAPH
+0xD1D9 0x62CF #CJK UNIFIED IDEOGRAPH
+0xD1DA 0x62FF #CJK UNIFIED IDEOGRAPH
+0xD1DB 0xF90E #CJK COMPATIBILITY IDEOGRAPH
+0xD1DC 0xF90F #CJK COMPATIBILITY IDEOGRAPH
+0xD1DD 0xF910 #CJK COMPATIBILITY IDEOGRAPH
+0xD1DE 0xF911 #CJK COMPATIBILITY IDEOGRAPH
+0xD1DF 0xF912 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E0 0xF913 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E1 0x90A3 #CJK UNIFIED IDEOGRAPH
+0xD1E2 0xF914 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E3 0xF915 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E4 0xF916 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E5 0xF917 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E6 0xF918 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E7 0x8AFE #CJK UNIFIED IDEOGRAPH
+0xD1E8 0xF919 #CJK COMPATIBILITY IDEOGRAPH
+0xD1E9 0xF91A #CJK COMPATIBILITY IDEOGRAPH
+0xD1EA 0xF91B #CJK COMPATIBILITY IDEOGRAPH
+0xD1EB 0xF91C #CJK COMPATIBILITY IDEOGRAPH
+0xD1EC 0x6696 #CJK UNIFIED IDEOGRAPH
+0xD1ED 0xF91D #CJK COMPATIBILITY IDEOGRAPH
+0xD1EE 0x7156 #CJK UNIFIED IDEOGRAPH
+0xD1EF 0xF91E #CJK COMPATIBILITY IDEOGRAPH
+0xD1F0 0xF91F #CJK COMPATIBILITY IDEOGRAPH
+0xD1F1 0x96E3 #CJK UNIFIED IDEOGRAPH
+0xD1F2 0xF920 #CJK COMPATIBILITY IDEOGRAPH
+0xD1F3 0x634F #CJK UNIFIED IDEOGRAPH
+0xD1F4 0x637A #CJK UNIFIED IDEOGRAPH
+0xD1F5 0x5357 #CJK UNIFIED IDEOGRAPH
+0xD1F6 0xF921 #CJK COMPATIBILITY IDEOGRAPH
+0xD1F7 0x678F #CJK UNIFIED IDEOGRAPH
+0xD1F8 0x6960 #CJK UNIFIED IDEOGRAPH
+0xD1F9 0x6E73 #CJK UNIFIED IDEOGRAPH
+0xD1FA 0xF922 #CJK COMPATIBILITY IDEOGRAPH
+0xD1FB 0x7537 #CJK UNIFIED IDEOGRAPH
+0xD1FC 0xF923 #CJK COMPATIBILITY IDEOGRAPH
+0xD1FD 0xF924 #CJK COMPATIBILITY IDEOGRAPH
+0xD1FE 0xF925 #CJK COMPATIBILITY IDEOGRAPH
+0xD2A1 0x7D0D #CJK UNIFIED IDEOGRAPH
+0xD2A2 0xF926 #CJK COMPATIBILITY IDEOGRAPH
+0xD2A3 0xF927 #CJK COMPATIBILITY IDEOGRAPH
+0xD2A4 0x8872 #CJK UNIFIED IDEOGRAPH
+0xD2A5 0x56CA #CJK UNIFIED IDEOGRAPH
+0xD2A6 0x5A18 #CJK UNIFIED IDEOGRAPH
+0xD2A7 0xF928 #CJK COMPATIBILITY IDEOGRAPH
+0xD2A8 0xF929 #CJK COMPATIBILITY IDEOGRAPH
+0xD2A9 0xF92A #CJK COMPATIBILITY IDEOGRAPH
+0xD2AA 0xF92B #CJK COMPATIBILITY IDEOGRAPH
+0xD2AB 0xF92C #CJK COMPATIBILITY IDEOGRAPH
+0xD2AC 0x4E43 #CJK UNIFIED IDEOGRAPH
+0xD2AD 0xF92D #CJK COMPATIBILITY IDEOGRAPH
+0xD2AE 0x5167 #CJK UNIFIED IDEOGRAPH
+0xD2AF 0x5948 #CJK UNIFIED IDEOGRAPH
+0xD2B0 0x67F0 #CJK UNIFIED IDEOGRAPH
+0xD2B1 0x8010 #CJK UNIFIED IDEOGRAPH
+0xD2B2 0xF92E #CJK COMPATIBILITY IDEOGRAPH
+0xD2B3 0x5973 #CJK UNIFIED IDEOGRAPH
+0xD2B4 0x5E74 #CJK UNIFIED IDEOGRAPH
+0xD2B5 0x649A #CJK UNIFIED IDEOGRAPH
+0xD2B6 0x79CA #CJK UNIFIED IDEOGRAPH
+0xD2B7 0x5FF5 #CJK UNIFIED IDEOGRAPH
+0xD2B8 0x606C #CJK UNIFIED IDEOGRAPH
+0xD2B9 0x62C8 #CJK UNIFIED IDEOGRAPH
+0xD2BA 0x637B #CJK UNIFIED IDEOGRAPH
+0xD2BB 0x5BE7 #CJK UNIFIED IDEOGRAPH
+0xD2BC 0x5BD7 #CJK UNIFIED IDEOGRAPH
+0xD2BD 0x52AA #CJK UNIFIED IDEOGRAPH
+0xD2BE 0xF92F #CJK COMPATIBILITY IDEOGRAPH
+0xD2BF 0x5974 #CJK UNIFIED IDEOGRAPH
+0xD2C0 0x5F29 #CJK UNIFIED IDEOGRAPH
+0xD2C1 0x6012 #CJK UNIFIED IDEOGRAPH
+0xD2C2 0xF930 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C3 0xF931 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C4 0xF932 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C5 0x7459 #CJK UNIFIED IDEOGRAPH
+0xD2C6 0xF933 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C7 0xF934 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C8 0xF935 #CJK COMPATIBILITY IDEOGRAPH
+0xD2C9 0xF936 #CJK COMPATIBILITY IDEOGRAPH
+0xD2CA 0xF937 #CJK COMPATIBILITY IDEOGRAPH
+0xD2CB 0xF938 #CJK COMPATIBILITY IDEOGRAPH
+0xD2CC 0x99D1 #CJK UNIFIED IDEOGRAPH
+0xD2CD 0xF939 #CJK COMPATIBILITY IDEOGRAPH
+0xD2CE 0xF93A #CJK COMPATIBILITY IDEOGRAPH
+0xD2CF 0xF93B #CJK COMPATIBILITY IDEOGRAPH
+0xD2D0 0xF93C #CJK COMPATIBILITY IDEOGRAPH
+0xD2D1 0xF93D #CJK COMPATIBILITY IDEOGRAPH
+0xD2D2 0xF93E #CJK COMPATIBILITY IDEOGRAPH
+0xD2D3 0xF93F #CJK COMPATIBILITY IDEOGRAPH
+0xD2D4 0xF940 #CJK COMPATIBILITY IDEOGRAPH
+0xD2D5 0xF941 #CJK COMPATIBILITY IDEOGRAPH
+0xD2D6 0xF942 #CJK COMPATIBILITY IDEOGRAPH
+0xD2D7 0xF943 #CJK COMPATIBILITY IDEOGRAPH
+0xD2D8 0x6FC3 #CJK UNIFIED IDEOGRAPH
+0xD2D9 0xF944 #CJK COMPATIBILITY IDEOGRAPH
+0xD2DA 0xF945 #CJK COMPATIBILITY IDEOGRAPH
+0xD2DB 0x81BF #CJK UNIFIED IDEOGRAPH
+0xD2DC 0x8FB2 #CJK UNIFIED IDEOGRAPH
+0xD2DD 0x60F1 #CJK UNIFIED IDEOGRAPH
+0xD2DE 0xF946 #CJK COMPATIBILITY IDEOGRAPH
+0xD2DF 0xF947 #CJK COMPATIBILITY IDEOGRAPH
+0xD2E0 0x8166 #CJK UNIFIED IDEOGRAPH
+0xD2E1 0xF948 #CJK COMPATIBILITY IDEOGRAPH
+0xD2E2 0xF949 #CJK COMPATIBILITY IDEOGRAPH
+0xD2E3 0x5C3F #CJK UNIFIED IDEOGRAPH
+0xD2E4 0xF94A #CJK COMPATIBILITY IDEOGRAPH
+0xD2E5 0xF94B #CJK COMPATIBILITY IDEOGRAPH
+0xD2E6 0xF94C #CJK COMPATIBILITY IDEOGRAPH
+0xD2E7 0xF94D #CJK COMPATIBILITY IDEOGRAPH
+0xD2E8 0xF94E #CJK COMPATIBILITY IDEOGRAPH
+0xD2E9 0xF94F #CJK COMPATIBILITY IDEOGRAPH
+0xD2EA 0xF950 #CJK COMPATIBILITY IDEOGRAPH
+0xD2EB 0xF951 #CJK COMPATIBILITY IDEOGRAPH
+0xD2EC 0x5AE9 #CJK UNIFIED IDEOGRAPH
+0xD2ED 0x8A25 #CJK UNIFIED IDEOGRAPH
+0xD2EE 0x677B #CJK UNIFIED IDEOGRAPH
+0xD2EF 0x7D10 #CJK UNIFIED IDEOGRAPH
+0xD2F0 0xF952 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F1 0xF953 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F2 0xF954 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F3 0xF955 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F4 0xF956 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F5 0xF957 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F6 0x80FD #CJK UNIFIED IDEOGRAPH
+0xD2F7 0xF958 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F8 0xF959 #CJK COMPATIBILITY IDEOGRAPH
+0xD2F9 0x5C3C #CJK UNIFIED IDEOGRAPH
+0xD2FA 0x6CE5 #CJK UNIFIED IDEOGRAPH
+0xD2FB 0x533F #CJK UNIFIED IDEOGRAPH
+0xD2FC 0x6EBA #CJK UNIFIED IDEOGRAPH
+0xD2FD 0x591A #CJK UNIFIED IDEOGRAPH
+0xD2FE 0x8336 #CJK UNIFIED IDEOGRAPH
+0xD3A1 0x4E39 #CJK UNIFIED IDEOGRAPH
+0xD3A2 0x4EB6 #CJK UNIFIED IDEOGRAPH
+0xD3A3 0x4F46 #CJK UNIFIED IDEOGRAPH
+0xD3A4 0x55AE #CJK UNIFIED IDEOGRAPH
+0xD3A5 0x5718 #CJK UNIFIED IDEOGRAPH
+0xD3A6 0x58C7 #CJK UNIFIED IDEOGRAPH
+0xD3A7 0x5F56 #CJK UNIFIED IDEOGRAPH
+0xD3A8 0x65B7 #CJK UNIFIED IDEOGRAPH
+0xD3A9 0x65E6 #CJK UNIFIED IDEOGRAPH
+0xD3AA 0x6A80 #CJK UNIFIED IDEOGRAPH
+0xD3AB 0x6BB5 #CJK UNIFIED IDEOGRAPH
+0xD3AC 0x6E4D #CJK UNIFIED IDEOGRAPH
+0xD3AD 0x77ED #CJK UNIFIED IDEOGRAPH
+0xD3AE 0x7AEF #CJK UNIFIED IDEOGRAPH
+0xD3AF 0x7C1E #CJK UNIFIED IDEOGRAPH
+0xD3B0 0x7DDE #CJK UNIFIED IDEOGRAPH
+0xD3B1 0x86CB #CJK UNIFIED IDEOGRAPH
+0xD3B2 0x8892 #CJK UNIFIED IDEOGRAPH
+0xD3B3 0x9132 #CJK UNIFIED IDEOGRAPH
+0xD3B4 0x935B #CJK UNIFIED IDEOGRAPH
+0xD3B5 0x64BB #CJK UNIFIED IDEOGRAPH
+0xD3B6 0x6FBE #CJK UNIFIED IDEOGRAPH
+0xD3B7 0x737A #CJK UNIFIED IDEOGRAPH
+0xD3B8 0x75B8 #CJK UNIFIED IDEOGRAPH
+0xD3B9 0x9054 #CJK UNIFIED IDEOGRAPH
+0xD3BA 0x5556 #CJK UNIFIED IDEOGRAPH
+0xD3BB 0x574D #CJK UNIFIED IDEOGRAPH
+0xD3BC 0x61BA #CJK UNIFIED IDEOGRAPH
+0xD3BD 0x64D4 #CJK UNIFIED IDEOGRAPH
+0xD3BE 0x66C7 #CJK UNIFIED IDEOGRAPH
+0xD3BF 0x6DE1 #CJK UNIFIED IDEOGRAPH
+0xD3C0 0x6E5B #CJK UNIFIED IDEOGRAPH
+0xD3C1 0x6F6D #CJK UNIFIED IDEOGRAPH
+0xD3C2 0x6FB9 #CJK UNIFIED IDEOGRAPH
+0xD3C3 0x75F0 #CJK UNIFIED IDEOGRAPH
+0xD3C4 0x8043 #CJK UNIFIED IDEOGRAPH
+0xD3C5 0x81BD #CJK UNIFIED IDEOGRAPH
+0xD3C6 0x8541 #CJK UNIFIED IDEOGRAPH
+0xD3C7 0x8983 #CJK UNIFIED IDEOGRAPH
+0xD3C8 0x8AC7 #CJK UNIFIED IDEOGRAPH
+0xD3C9 0x8B5A #CJK UNIFIED IDEOGRAPH
+0xD3CA 0x931F #CJK UNIFIED IDEOGRAPH
+0xD3CB 0x6C93 #CJK UNIFIED IDEOGRAPH
+0xD3CC 0x7553 #CJK UNIFIED IDEOGRAPH
+0xD3CD 0x7B54 #CJK UNIFIED IDEOGRAPH
+0xD3CE 0x8E0F #CJK UNIFIED IDEOGRAPH
+0xD3CF 0x905D #CJK UNIFIED IDEOGRAPH
+0xD3D0 0x5510 #CJK UNIFIED IDEOGRAPH
+0xD3D1 0x5802 #CJK UNIFIED IDEOGRAPH
+0xD3D2 0x5858 #CJK UNIFIED IDEOGRAPH
+0xD3D3 0x5E62 #CJK UNIFIED IDEOGRAPH
+0xD3D4 0x6207 #CJK UNIFIED IDEOGRAPH
+0xD3D5 0x649E #CJK UNIFIED IDEOGRAPH
+0xD3D6 0x68E0 #CJK UNIFIED IDEOGRAPH
+0xD3D7 0x7576 #CJK UNIFIED IDEOGRAPH
+0xD3D8 0x7CD6 #CJK UNIFIED IDEOGRAPH
+0xD3D9 0x87B3 #CJK UNIFIED IDEOGRAPH
+0xD3DA 0x9EE8 #CJK UNIFIED IDEOGRAPH
+0xD3DB 0x4EE3 #CJK UNIFIED IDEOGRAPH
+0xD3DC 0x5788 #CJK UNIFIED IDEOGRAPH
+0xD3DD 0x576E #CJK UNIFIED IDEOGRAPH
+0xD3DE 0x5927 #CJK UNIFIED IDEOGRAPH
+0xD3DF 0x5C0D #CJK UNIFIED IDEOGRAPH
+0xD3E0 0x5CB1 #CJK UNIFIED IDEOGRAPH
+0xD3E1 0x5E36 #CJK UNIFIED IDEOGRAPH
+0xD3E2 0x5F85 #CJK UNIFIED IDEOGRAPH
+0xD3E3 0x6234 #CJK UNIFIED IDEOGRAPH
+0xD3E4 0x64E1 #CJK UNIFIED IDEOGRAPH
+0xD3E5 0x73B3 #CJK UNIFIED IDEOGRAPH
+0xD3E6 0x81FA #CJK UNIFIED IDEOGRAPH
+0xD3E7 0x888B #CJK UNIFIED IDEOGRAPH
+0xD3E8 0x8CB8 #CJK UNIFIED IDEOGRAPH
+0xD3E9 0x968A #CJK UNIFIED IDEOGRAPH
+0xD3EA 0x9EDB #CJK UNIFIED IDEOGRAPH
+0xD3EB 0x5B85 #CJK UNIFIED IDEOGRAPH
+0xD3EC 0x5FB7 #CJK UNIFIED IDEOGRAPH
+0xD3ED 0x60B3 #CJK UNIFIED IDEOGRAPH
+0xD3EE 0x5012 #CJK UNIFIED IDEOGRAPH
+0xD3EF 0x5200 #CJK UNIFIED IDEOGRAPH
+0xD3F0 0x5230 #CJK UNIFIED IDEOGRAPH
+0xD3F1 0x5716 #CJK UNIFIED IDEOGRAPH
+0xD3F2 0x5835 #CJK UNIFIED IDEOGRAPH
+0xD3F3 0x5857 #CJK UNIFIED IDEOGRAPH
+0xD3F4 0x5C0E #CJK UNIFIED IDEOGRAPH
+0xD3F5 0x5C60 #CJK UNIFIED IDEOGRAPH
+0xD3F6 0x5CF6 #CJK UNIFIED IDEOGRAPH
+0xD3F7 0x5D8B #CJK UNIFIED IDEOGRAPH
+0xD3F8 0x5EA6 #CJK UNIFIED IDEOGRAPH
+0xD3F9 0x5F92 #CJK UNIFIED IDEOGRAPH
+0xD3FA 0x60BC #CJK UNIFIED IDEOGRAPH
+0xD3FB 0x6311 #CJK UNIFIED IDEOGRAPH
+0xD3FC 0x6389 #CJK UNIFIED IDEOGRAPH
+0xD3FD 0x6417 #CJK UNIFIED IDEOGRAPH
+0xD3FE 0x6843 #CJK UNIFIED IDEOGRAPH
+0xD4A1 0x68F9 #CJK UNIFIED IDEOGRAPH
+0xD4A2 0x6AC2 #CJK UNIFIED IDEOGRAPH
+0xD4A3 0x6DD8 #CJK UNIFIED IDEOGRAPH
+0xD4A4 0x6E21 #CJK UNIFIED IDEOGRAPH
+0xD4A5 0x6ED4 #CJK UNIFIED IDEOGRAPH
+0xD4A6 0x6FE4 #CJK UNIFIED IDEOGRAPH
+0xD4A7 0x71FE #CJK UNIFIED IDEOGRAPH
+0xD4A8 0x76DC #CJK UNIFIED IDEOGRAPH
+0xD4A9 0x7779 #CJK UNIFIED IDEOGRAPH
+0xD4AA 0x79B1 #CJK UNIFIED IDEOGRAPH
+0xD4AB 0x7A3B #CJK UNIFIED IDEOGRAPH
+0xD4AC 0x8404 #CJK UNIFIED IDEOGRAPH
+0xD4AD 0x89A9 #CJK UNIFIED IDEOGRAPH
+0xD4AE 0x8CED #CJK UNIFIED IDEOGRAPH
+0xD4AF 0x8DF3 #CJK UNIFIED IDEOGRAPH
+0xD4B0 0x8E48 #CJK UNIFIED IDEOGRAPH
+0xD4B1 0x9003 #CJK UNIFIED IDEOGRAPH
+0xD4B2 0x9014 #CJK UNIFIED IDEOGRAPH
+0xD4B3 0x9053 #CJK UNIFIED IDEOGRAPH
+0xD4B4 0x90FD #CJK UNIFIED IDEOGRAPH
+0xD4B5 0x934D #CJK UNIFIED IDEOGRAPH
+0xD4B6 0x9676 #CJK UNIFIED IDEOGRAPH
+0xD4B7 0x97DC #CJK UNIFIED IDEOGRAPH
+0xD4B8 0x6BD2 #CJK UNIFIED IDEOGRAPH
+0xD4B9 0x7006 #CJK UNIFIED IDEOGRAPH
+0xD4BA 0x7258 #CJK UNIFIED IDEOGRAPH
+0xD4BB 0x72A2 #CJK UNIFIED IDEOGRAPH
+0xD4BC 0x7368 #CJK UNIFIED IDEOGRAPH
+0xD4BD 0x7763 #CJK UNIFIED IDEOGRAPH
+0xD4BE 0x79BF #CJK UNIFIED IDEOGRAPH
+0xD4BF 0x7BE4 #CJK UNIFIED IDEOGRAPH
+0xD4C0 0x7E9B #CJK UNIFIED IDEOGRAPH
+0xD4C1 0x8B80 #CJK UNIFIED IDEOGRAPH
+0xD4C2 0x58A9 #CJK UNIFIED IDEOGRAPH
+0xD4C3 0x60C7 #CJK UNIFIED IDEOGRAPH
+0xD4C4 0x6566 #CJK UNIFIED IDEOGRAPH
+0xD4C5 0x65FD #CJK UNIFIED IDEOGRAPH
+0xD4C6 0x66BE #CJK UNIFIED IDEOGRAPH
+0xD4C7 0x6C8C #CJK UNIFIED IDEOGRAPH
+0xD4C8 0x711E #CJK UNIFIED IDEOGRAPH
+0xD4C9 0x71C9 #CJK UNIFIED IDEOGRAPH
+0xD4CA 0x8C5A #CJK UNIFIED IDEOGRAPH
+0xD4CB 0x9813 #CJK UNIFIED IDEOGRAPH
+0xD4CC 0x4E6D #CJK UNIFIED IDEOGRAPH
+0xD4CD 0x7A81 #CJK UNIFIED IDEOGRAPH
+0xD4CE 0x4EDD #CJK UNIFIED IDEOGRAPH
+0xD4CF 0x51AC #CJK UNIFIED IDEOGRAPH
+0xD4D0 0x51CD #CJK UNIFIED IDEOGRAPH
+0xD4D1 0x52D5 #CJK UNIFIED IDEOGRAPH
+0xD4D2 0x540C #CJK UNIFIED IDEOGRAPH
+0xD4D3 0x61A7 #CJK UNIFIED IDEOGRAPH
+0xD4D4 0x6771 #CJK UNIFIED IDEOGRAPH
+0xD4D5 0x6850 #CJK UNIFIED IDEOGRAPH
+0xD4D6 0x68DF #CJK UNIFIED IDEOGRAPH
+0xD4D7 0x6D1E #CJK UNIFIED IDEOGRAPH
+0xD4D8 0x6F7C #CJK UNIFIED IDEOGRAPH
+0xD4D9 0x75BC #CJK UNIFIED IDEOGRAPH
+0xD4DA 0x77B3 #CJK UNIFIED IDEOGRAPH
+0xD4DB 0x7AE5 #CJK UNIFIED IDEOGRAPH
+0xD4DC 0x80F4 #CJK UNIFIED IDEOGRAPH
+0xD4DD 0x8463 #CJK UNIFIED IDEOGRAPH
+0xD4DE 0x9285 #CJK UNIFIED IDEOGRAPH
+0xD4DF 0x515C #CJK UNIFIED IDEOGRAPH
+0xD4E0 0x6597 #CJK UNIFIED IDEOGRAPH
+0xD4E1 0x675C #CJK UNIFIED IDEOGRAPH
+0xD4E2 0x6793 #CJK UNIFIED IDEOGRAPH
+0xD4E3 0x75D8 #CJK UNIFIED IDEOGRAPH
+0xD4E4 0x7AC7 #CJK UNIFIED IDEOGRAPH
+0xD4E5 0x8373 #CJK UNIFIED IDEOGRAPH
+0xD4E6 0xF95A #CJK COMPATIBILITY IDEOGRAPH
+0xD4E7 0x8C46 #CJK UNIFIED IDEOGRAPH
+0xD4E8 0x9017 #CJK UNIFIED IDEOGRAPH
+0xD4E9 0x982D #CJK UNIFIED IDEOGRAPH
+0xD4EA 0x5C6F #CJK UNIFIED IDEOGRAPH
+0xD4EB 0x81C0 #CJK UNIFIED IDEOGRAPH
+0xD4EC 0x829A #CJK UNIFIED IDEOGRAPH
+0xD4ED 0x9041 #CJK UNIFIED IDEOGRAPH
+0xD4EE 0x906F #CJK UNIFIED IDEOGRAPH
+0xD4EF 0x920D #CJK UNIFIED IDEOGRAPH
+0xD4F0 0x5F97 #CJK UNIFIED IDEOGRAPH
+0xD4F1 0x5D9D #CJK UNIFIED IDEOGRAPH
+0xD4F2 0x6A59 #CJK UNIFIED IDEOGRAPH
+0xD4F3 0x71C8 #CJK UNIFIED IDEOGRAPH
+0xD4F4 0x767B #CJK UNIFIED IDEOGRAPH
+0xD4F5 0x7B49 #CJK UNIFIED IDEOGRAPH
+0xD4F6 0x85E4 #CJK UNIFIED IDEOGRAPH
+0xD4F7 0x8B04 #CJK UNIFIED IDEOGRAPH
+0xD4F8 0x9127 #CJK UNIFIED IDEOGRAPH
+0xD4F9 0x9A30 #CJK UNIFIED IDEOGRAPH
+0xD4FA 0x5587 #CJK UNIFIED IDEOGRAPH
+0xD4FB 0x61F6 #CJK UNIFIED IDEOGRAPH
+0xD4FC 0xF95B #CJK COMPATIBILITY IDEOGRAPH
+0xD4FD 0x7669 #CJK UNIFIED IDEOGRAPH
+0xD4FE 0x7F85 #CJK UNIFIED IDEOGRAPH
+0xD5A1 0x863F #CJK UNIFIED IDEOGRAPH
+0xD5A2 0x87BA #CJK UNIFIED IDEOGRAPH
+0xD5A3 0x88F8 #CJK UNIFIED IDEOGRAPH
+0xD5A4 0x908F #CJK UNIFIED IDEOGRAPH
+0xD5A5 0xF95C #CJK COMPATIBILITY IDEOGRAPH
+0xD5A6 0x6D1B #CJK UNIFIED IDEOGRAPH
+0xD5A7 0x70D9 #CJK UNIFIED IDEOGRAPH
+0xD5A8 0x73DE #CJK UNIFIED IDEOGRAPH
+0xD5A9 0x7D61 #CJK UNIFIED IDEOGRAPH
+0xD5AA 0x843D #CJK UNIFIED IDEOGRAPH
+0xD5AB 0xF95D #CJK COMPATIBILITY IDEOGRAPH
+0xD5AC 0x916A #CJK UNIFIED IDEOGRAPH
+0xD5AD 0x99F1 #CJK UNIFIED IDEOGRAPH
+0xD5AE 0xF95E #CJK COMPATIBILITY IDEOGRAPH
+0xD5AF 0x4E82 #CJK UNIFIED IDEOGRAPH
+0xD5B0 0x5375 #CJK UNIFIED IDEOGRAPH
+0xD5B1 0x6B04 #CJK UNIFIED IDEOGRAPH
+0xD5B2 0x6B12 #CJK UNIFIED IDEOGRAPH
+0xD5B3 0x703E #CJK UNIFIED IDEOGRAPH
+0xD5B4 0x721B #CJK UNIFIED IDEOGRAPH
+0xD5B5 0x862D #CJK UNIFIED IDEOGRAPH
+0xD5B6 0x9E1E #CJK UNIFIED IDEOGRAPH
+0xD5B7 0x524C #CJK UNIFIED IDEOGRAPH
+0xD5B8 0x8FA3 #CJK UNIFIED IDEOGRAPH
+0xD5B9 0x5D50 #CJK UNIFIED IDEOGRAPH
+0xD5BA 0x64E5 #CJK UNIFIED IDEOGRAPH
+0xD5BB 0x652C #CJK UNIFIED IDEOGRAPH
+0xD5BC 0x6B16 #CJK UNIFIED IDEOGRAPH
+0xD5BD 0x6FEB #CJK UNIFIED IDEOGRAPH
+0xD5BE 0x7C43 #CJK UNIFIED IDEOGRAPH
+0xD5BF 0x7E9C #CJK UNIFIED IDEOGRAPH
+0xD5C0 0x85CD #CJK UNIFIED IDEOGRAPH
+0xD5C1 0x8964 #CJK UNIFIED IDEOGRAPH
+0xD5C2 0x89BD #CJK UNIFIED IDEOGRAPH
+0xD5C3 0x62C9 #CJK UNIFIED IDEOGRAPH
+0xD5C4 0x81D8 #CJK UNIFIED IDEOGRAPH
+0xD5C5 0x881F #CJK UNIFIED IDEOGRAPH
+0xD5C6 0x5ECA #CJK UNIFIED IDEOGRAPH
+0xD5C7 0x6717 #CJK UNIFIED IDEOGRAPH
+0xD5C8 0x6D6A #CJK UNIFIED IDEOGRAPH
+0xD5C9 0x72FC #CJK UNIFIED IDEOGRAPH
+0xD5CA 0x7405 #CJK UNIFIED IDEOGRAPH
+0xD5CB 0x746F #CJK UNIFIED IDEOGRAPH
+0xD5CC 0x8782 #CJK UNIFIED IDEOGRAPH
+0xD5CD 0x90DE #CJK UNIFIED IDEOGRAPH
+0xD5CE 0x4F86 #CJK UNIFIED IDEOGRAPH
+0xD5CF 0x5D0D #CJK UNIFIED IDEOGRAPH
+0xD5D0 0x5FA0 #CJK UNIFIED IDEOGRAPH
+0xD5D1 0x840A #CJK UNIFIED IDEOGRAPH
+0xD5D2 0x51B7 #CJK UNIFIED IDEOGRAPH
+0xD5D3 0x63A0 #CJK UNIFIED IDEOGRAPH
+0xD5D4 0x7565 #CJK UNIFIED IDEOGRAPH
+0xD5D5 0x4EAE #CJK UNIFIED IDEOGRAPH
+0xD5D6 0x5006 #CJK UNIFIED IDEOGRAPH
+0xD5D7 0x5169 #CJK UNIFIED IDEOGRAPH
+0xD5D8 0x51C9 #CJK UNIFIED IDEOGRAPH
+0xD5D9 0x6881 #CJK UNIFIED IDEOGRAPH
+0xD5DA 0x6A11 #CJK UNIFIED IDEOGRAPH
+0xD5DB 0x7CAE #CJK UNIFIED IDEOGRAPH
+0xD5DC 0x7CB1 #CJK UNIFIED IDEOGRAPH
+0xD5DD 0x7CE7 #CJK UNIFIED IDEOGRAPH
+0xD5DE 0x826F #CJK UNIFIED IDEOGRAPH
+0xD5DF 0x8AD2 #CJK UNIFIED IDEOGRAPH
+0xD5E0 0x8F1B #CJK UNIFIED IDEOGRAPH
+0xD5E1 0x91CF #CJK UNIFIED IDEOGRAPH
+0xD5E2 0x4FB6 #CJK UNIFIED IDEOGRAPH
+0xD5E3 0x5137 #CJK UNIFIED IDEOGRAPH
+0xD5E4 0x52F5 #CJK UNIFIED IDEOGRAPH
+0xD5E5 0x5442 #CJK UNIFIED IDEOGRAPH
+0xD5E6 0x5EEC #CJK UNIFIED IDEOGRAPH
+0xD5E7 0x616E #CJK UNIFIED IDEOGRAPH
+0xD5E8 0x623E #CJK UNIFIED IDEOGRAPH
+0xD5E9 0x65C5 #CJK UNIFIED IDEOGRAPH
+0xD5EA 0x6ADA #CJK UNIFIED IDEOGRAPH
+0xD5EB 0x6FFE #CJK UNIFIED IDEOGRAPH
+0xD5EC 0x792A #CJK UNIFIED IDEOGRAPH
+0xD5ED 0x85DC #CJK UNIFIED IDEOGRAPH
+0xD5EE 0x8823 #CJK UNIFIED IDEOGRAPH
+0xD5EF 0x95AD #CJK UNIFIED IDEOGRAPH
+0xD5F0 0x9A62 #CJK UNIFIED IDEOGRAPH
+0xD5F1 0x9A6A #CJK UNIFIED IDEOGRAPH
+0xD5F2 0x9E97 #CJK UNIFIED IDEOGRAPH
+0xD5F3 0x9ECE #CJK UNIFIED IDEOGRAPH
+0xD5F4 0x529B #CJK UNIFIED IDEOGRAPH
+0xD5F5 0x66C6 #CJK UNIFIED IDEOGRAPH
+0xD5F6 0x6B77 #CJK UNIFIED IDEOGRAPH
+0xD5F7 0x701D #CJK UNIFIED IDEOGRAPH
+0xD5F8 0x792B #CJK UNIFIED IDEOGRAPH
+0xD5F9 0x8F62 #CJK UNIFIED IDEOGRAPH
+0xD5FA 0x9742 #CJK UNIFIED IDEOGRAPH
+0xD5FB 0x6190 #CJK UNIFIED IDEOGRAPH
+0xD5FC 0x6200 #CJK UNIFIED IDEOGRAPH
+0xD5FD 0x6523 #CJK UNIFIED IDEOGRAPH
+0xD5FE 0x6F23 #CJK UNIFIED IDEOGRAPH
+0xD6A1 0x7149 #CJK UNIFIED IDEOGRAPH
+0xD6A2 0x7489 #CJK UNIFIED IDEOGRAPH
+0xD6A3 0x7DF4 #CJK UNIFIED IDEOGRAPH
+0xD6A4 0x806F #CJK UNIFIED IDEOGRAPH
+0xD6A5 0x84EE #CJK UNIFIED IDEOGRAPH
+0xD6A6 0x8F26 #CJK UNIFIED IDEOGRAPH
+0xD6A7 0x9023 #CJK UNIFIED IDEOGRAPH
+0xD6A8 0x934A #CJK UNIFIED IDEOGRAPH
+0xD6A9 0x51BD #CJK UNIFIED IDEOGRAPH
+0xD6AA 0x5217 #CJK UNIFIED IDEOGRAPH
+0xD6AB 0x52A3 #CJK UNIFIED IDEOGRAPH
+0xD6AC 0x6D0C #CJK UNIFIED IDEOGRAPH
+0xD6AD 0x70C8 #CJK UNIFIED IDEOGRAPH
+0xD6AE 0x88C2 #CJK UNIFIED IDEOGRAPH
+0xD6AF 0x5EC9 #CJK UNIFIED IDEOGRAPH
+0xD6B0 0x6582 #CJK UNIFIED IDEOGRAPH
+0xD6B1 0x6BAE #CJK UNIFIED IDEOGRAPH
+0xD6B2 0x6FC2 #CJK UNIFIED IDEOGRAPH
+0xD6B3 0x7C3E #CJK UNIFIED IDEOGRAPH
+0xD6B4 0x7375 #CJK UNIFIED IDEOGRAPH
+0xD6B5 0x4EE4 #CJK UNIFIED IDEOGRAPH
+0xD6B6 0x4F36 #CJK UNIFIED IDEOGRAPH
+0xD6B7 0x56F9 #CJK UNIFIED IDEOGRAPH
+0xD6B8 0xF95F #CJK COMPATIBILITY IDEOGRAPH
+0xD6B9 0x5CBA #CJK UNIFIED IDEOGRAPH
+0xD6BA 0x5DBA #CJK UNIFIED IDEOGRAPH
+0xD6BB 0x601C #CJK UNIFIED IDEOGRAPH
+0xD6BC 0x73B2 #CJK UNIFIED IDEOGRAPH
+0xD6BD 0x7B2D #CJK UNIFIED IDEOGRAPH
+0xD6BE 0x7F9A #CJK UNIFIED IDEOGRAPH
+0xD6BF 0x7FCE #CJK UNIFIED IDEOGRAPH
+0xD6C0 0x8046 #CJK UNIFIED IDEOGRAPH
+0xD6C1 0x901E #CJK UNIFIED IDEOGRAPH
+0xD6C2 0x9234 #CJK UNIFIED IDEOGRAPH
+0xD6C3 0x96F6 #CJK UNIFIED IDEOGRAPH
+0xD6C4 0x9748 #CJK UNIFIED IDEOGRAPH
+0xD6C5 0x9818 #CJK UNIFIED IDEOGRAPH
+0xD6C6 0x9F61 #CJK UNIFIED IDEOGRAPH
+0xD6C7 0x4F8B #CJK UNIFIED IDEOGRAPH
+0xD6C8 0x6FA7 #CJK UNIFIED IDEOGRAPH
+0xD6C9 0x79AE #CJK UNIFIED IDEOGRAPH
+0xD6CA 0x91B4 #CJK UNIFIED IDEOGRAPH
+0xD6CB 0x96B7 #CJK UNIFIED IDEOGRAPH
+0xD6CC 0x52DE #CJK UNIFIED IDEOGRAPH
+0xD6CD 0xF960 #CJK COMPATIBILITY IDEOGRAPH
+0xD6CE 0x6488 #CJK UNIFIED IDEOGRAPH
+0xD6CF 0x64C4 #CJK UNIFIED IDEOGRAPH
+0xD6D0 0x6AD3 #CJK UNIFIED IDEOGRAPH
+0xD6D1 0x6F5E #CJK UNIFIED IDEOGRAPH
+0xD6D2 0x7018 #CJK UNIFIED IDEOGRAPH
+0xD6D3 0x7210 #CJK UNIFIED IDEOGRAPH
+0xD6D4 0x76E7 #CJK UNIFIED IDEOGRAPH
+0xD6D5 0x8001 #CJK UNIFIED IDEOGRAPH
+0xD6D6 0x8606 #CJK UNIFIED IDEOGRAPH
+0xD6D7 0x865C #CJK UNIFIED IDEOGRAPH
+0xD6D8 0x8DEF #CJK UNIFIED IDEOGRAPH
+0xD6D9 0x8F05 #CJK UNIFIED IDEOGRAPH
+0xD6DA 0x9732 #CJK UNIFIED IDEOGRAPH
+0xD6DB 0x9B6F #CJK UNIFIED IDEOGRAPH
+0xD6DC 0x9DFA #CJK UNIFIED IDEOGRAPH
+0xD6DD 0x9E75 #CJK UNIFIED IDEOGRAPH
+0xD6DE 0x788C #CJK UNIFIED IDEOGRAPH
+0xD6DF 0x797F #CJK UNIFIED IDEOGRAPH
+0xD6E0 0x7DA0 #CJK UNIFIED IDEOGRAPH
+0xD6E1 0x83C9 #CJK UNIFIED IDEOGRAPH
+0xD6E2 0x9304 #CJK UNIFIED IDEOGRAPH
+0xD6E3 0x9E7F #CJK UNIFIED IDEOGRAPH
+0xD6E4 0x9E93 #CJK UNIFIED IDEOGRAPH
+0xD6E5 0x8AD6 #CJK UNIFIED IDEOGRAPH
+0xD6E6 0x58DF #CJK UNIFIED IDEOGRAPH
+0xD6E7 0x5F04 #CJK UNIFIED IDEOGRAPH
+0xD6E8 0x6727 #CJK UNIFIED IDEOGRAPH
+0xD6E9 0x7027 #CJK UNIFIED IDEOGRAPH
+0xD6EA 0x74CF #CJK UNIFIED IDEOGRAPH
+0xD6EB 0x7C60 #CJK UNIFIED IDEOGRAPH
+0xD6EC 0x807E #CJK UNIFIED IDEOGRAPH
+0xD6ED 0x5121 #CJK UNIFIED IDEOGRAPH
+0xD6EE 0x7028 #CJK UNIFIED IDEOGRAPH
+0xD6EF 0x7262 #CJK UNIFIED IDEOGRAPH
+0xD6F0 0x78CA #CJK UNIFIED IDEOGRAPH
+0xD6F1 0x8CC2 #CJK UNIFIED IDEOGRAPH
+0xD6F2 0x8CDA #CJK UNIFIED IDEOGRAPH
+0xD6F3 0x8CF4 #CJK UNIFIED IDEOGRAPH
+0xD6F4 0x96F7 #CJK UNIFIED IDEOGRAPH
+0xD6F5 0x4E86 #CJK UNIFIED IDEOGRAPH
+0xD6F6 0x50DA #CJK UNIFIED IDEOGRAPH
+0xD6F7 0x5BEE #CJK UNIFIED IDEOGRAPH
+0xD6F8 0x5ED6 #CJK UNIFIED IDEOGRAPH
+0xD6F9 0x6599 #CJK UNIFIED IDEOGRAPH
+0xD6FA 0x71CE #CJK UNIFIED IDEOGRAPH
+0xD6FB 0x7642 #CJK UNIFIED IDEOGRAPH
+0xD6FC 0x77AD #CJK UNIFIED IDEOGRAPH
+0xD6FD 0x804A #CJK UNIFIED IDEOGRAPH
+0xD6FE 0x84FC #CJK UNIFIED IDEOGRAPH
+0xD7A1 0x907C #CJK UNIFIED IDEOGRAPH
+0xD7A2 0x9B27 #CJK UNIFIED IDEOGRAPH
+0xD7A3 0x9F8D #CJK UNIFIED IDEOGRAPH
+0xD7A4 0x58D8 #CJK UNIFIED IDEOGRAPH
+0xD7A5 0x5A41 #CJK UNIFIED IDEOGRAPH
+0xD7A6 0x5C62 #CJK UNIFIED IDEOGRAPH
+0xD7A7 0x6A13 #CJK UNIFIED IDEOGRAPH
+0xD7A8 0x6DDA #CJK UNIFIED IDEOGRAPH
+0xD7A9 0x6F0F #CJK UNIFIED IDEOGRAPH
+0xD7AA 0x763B #CJK UNIFIED IDEOGRAPH
+0xD7AB 0x7D2F #CJK UNIFIED IDEOGRAPH
+0xD7AC 0x7E37 #CJK UNIFIED IDEOGRAPH
+0xD7AD 0x851E #CJK UNIFIED IDEOGRAPH
+0xD7AE 0x8938 #CJK UNIFIED IDEOGRAPH
+0xD7AF 0x93E4 #CJK UNIFIED IDEOGRAPH
+0xD7B0 0x964B #CJK UNIFIED IDEOGRAPH
+0xD7B1 0x5289 #CJK UNIFIED IDEOGRAPH
+0xD7B2 0x65D2 #CJK UNIFIED IDEOGRAPH
+0xD7B3 0x67F3 #CJK UNIFIED IDEOGRAPH
+0xD7B4 0x69B4 #CJK UNIFIED IDEOGRAPH
+0xD7B5 0x6D41 #CJK UNIFIED IDEOGRAPH
+0xD7B6 0x6E9C #CJK UNIFIED IDEOGRAPH
+0xD7B7 0x700F #CJK UNIFIED IDEOGRAPH
+0xD7B8 0x7409 #CJK UNIFIED IDEOGRAPH
+0xD7B9 0x7460 #CJK UNIFIED IDEOGRAPH
+0xD7BA 0x7559 #CJK UNIFIED IDEOGRAPH
+0xD7BB 0x7624 #CJK UNIFIED IDEOGRAPH
+0xD7BC 0x786B #CJK UNIFIED IDEOGRAPH
+0xD7BD 0x8B2C #CJK UNIFIED IDEOGRAPH
+0xD7BE 0x985E #CJK UNIFIED IDEOGRAPH
+0xD7BF 0x516D #CJK UNIFIED IDEOGRAPH
+0xD7C0 0x622E #CJK UNIFIED IDEOGRAPH
+0xD7C1 0x9678 #CJK UNIFIED IDEOGRAPH
+0xD7C2 0x4F96 #CJK UNIFIED IDEOGRAPH
+0xD7C3 0x502B #CJK UNIFIED IDEOGRAPH
+0xD7C4 0x5D19 #CJK UNIFIED IDEOGRAPH
+0xD7C5 0x6DEA #CJK UNIFIED IDEOGRAPH
+0xD7C6 0x7DB8 #CJK UNIFIED IDEOGRAPH
+0xD7C7 0x8F2A #CJK UNIFIED IDEOGRAPH
+0xD7C8 0x5F8B #CJK UNIFIED IDEOGRAPH
+0xD7C9 0x6144 #CJK UNIFIED IDEOGRAPH
+0xD7CA 0x6817 #CJK UNIFIED IDEOGRAPH
+0xD7CB 0xF961 #CJK COMPATIBILITY IDEOGRAPH
+0xD7CC 0x9686 #CJK UNIFIED IDEOGRAPH
+0xD7CD 0x52D2 #CJK UNIFIED IDEOGRAPH
+0xD7CE 0x808B #CJK UNIFIED IDEOGRAPH
+0xD7CF 0x51DC #CJK UNIFIED IDEOGRAPH
+0xD7D0 0x51CC #CJK UNIFIED IDEOGRAPH
+0xD7D1 0x695E #CJK UNIFIED IDEOGRAPH
+0xD7D2 0x7A1C #CJK UNIFIED IDEOGRAPH
+0xD7D3 0x7DBE #CJK UNIFIED IDEOGRAPH
+0xD7D4 0x83F1 #CJK UNIFIED IDEOGRAPH
+0xD7D5 0x9675 #CJK UNIFIED IDEOGRAPH
+0xD7D6 0x4FDA #CJK UNIFIED IDEOGRAPH
+0xD7D7 0x5229 #CJK UNIFIED IDEOGRAPH
+0xD7D8 0x5398 #CJK UNIFIED IDEOGRAPH
+0xD7D9 0x540F #CJK UNIFIED IDEOGRAPH
+0xD7DA 0x550E #CJK UNIFIED IDEOGRAPH
+0xD7DB 0x5C65 #CJK UNIFIED IDEOGRAPH
+0xD7DC 0x60A7 #CJK UNIFIED IDEOGRAPH
+0xD7DD 0x674E #CJK UNIFIED IDEOGRAPH
+0xD7DE 0x68A8 #CJK UNIFIED IDEOGRAPH
+0xD7DF 0x6D6C #CJK UNIFIED IDEOGRAPH
+0xD7E0 0x7281 #CJK UNIFIED IDEOGRAPH
+0xD7E1 0x72F8 #CJK UNIFIED IDEOGRAPH
+0xD7E2 0x7406 #CJK UNIFIED IDEOGRAPH
+0xD7E3 0x7483 #CJK UNIFIED IDEOGRAPH
+0xD7E4 0xF962 #CJK COMPATIBILITY IDEOGRAPH
+0xD7E5 0x75E2 #CJK UNIFIED IDEOGRAPH
+0xD7E6 0x7C6C #CJK UNIFIED IDEOGRAPH
+0xD7E7 0x7F79 #CJK UNIFIED IDEOGRAPH
+0xD7E8 0x7FB8 #CJK UNIFIED IDEOGRAPH
+0xD7E9 0x8389 #CJK UNIFIED IDEOGRAPH
+0xD7EA 0x88CF #CJK UNIFIED IDEOGRAPH
+0xD7EB 0x88E1 #CJK UNIFIED IDEOGRAPH
+0xD7EC 0x91CC #CJK UNIFIED IDEOGRAPH
+0xD7ED 0x91D0 #CJK UNIFIED IDEOGRAPH
+0xD7EE 0x96E2 #CJK UNIFIED IDEOGRAPH
+0xD7EF 0x9BC9 #CJK UNIFIED IDEOGRAPH
+0xD7F0 0x541D #CJK UNIFIED IDEOGRAPH
+0xD7F1 0x6F7E #CJK UNIFIED IDEOGRAPH
+0xD7F2 0x71D0 #CJK UNIFIED IDEOGRAPH
+0xD7F3 0x7498 #CJK UNIFIED IDEOGRAPH
+0xD7F4 0x85FA #CJK UNIFIED IDEOGRAPH
+0xD7F5 0x8EAA #CJK UNIFIED IDEOGRAPH
+0xD7F6 0x96A3 #CJK UNIFIED IDEOGRAPH
+0xD7F7 0x9C57 #CJK UNIFIED IDEOGRAPH
+0xD7F8 0x9E9F #CJK UNIFIED IDEOGRAPH
+0xD7F9 0x6797 #CJK UNIFIED IDEOGRAPH
+0xD7FA 0x6DCB #CJK UNIFIED IDEOGRAPH
+0xD7FB 0x7433 #CJK UNIFIED IDEOGRAPH
+0xD7FC 0x81E8 #CJK UNIFIED IDEOGRAPH
+0xD7FD 0x9716 #CJK UNIFIED IDEOGRAPH
+0xD7FE 0x782C #CJK UNIFIED IDEOGRAPH
+0xD8A1 0x7ACB #CJK UNIFIED IDEOGRAPH
+0xD8A2 0x7B20 #CJK UNIFIED IDEOGRAPH
+0xD8A3 0x7C92 #CJK UNIFIED IDEOGRAPH
+0xD8A4 0x6469 #CJK UNIFIED IDEOGRAPH
+0xD8A5 0x746A #CJK UNIFIED IDEOGRAPH
+0xD8A6 0x75F2 #CJK UNIFIED IDEOGRAPH
+0xD8A7 0x78BC #CJK UNIFIED IDEOGRAPH
+0xD8A8 0x78E8 #CJK UNIFIED IDEOGRAPH
+0xD8A9 0x99AC #CJK UNIFIED IDEOGRAPH
+0xD8AA 0x9B54 #CJK UNIFIED IDEOGRAPH
+0xD8AB 0x9EBB #CJK UNIFIED IDEOGRAPH
+0xD8AC 0x5BDE #CJK UNIFIED IDEOGRAPH
+0xD8AD 0x5E55 #CJK UNIFIED IDEOGRAPH
+0xD8AE 0x6F20 #CJK UNIFIED IDEOGRAPH
+0xD8AF 0x819C #CJK UNIFIED IDEOGRAPH
+0xD8B0 0x83AB #CJK UNIFIED IDEOGRAPH
+0xD8B1 0x9088 #CJK UNIFIED IDEOGRAPH
+0xD8B2 0x4E07 #CJK UNIFIED IDEOGRAPH
+0xD8B3 0x534D #CJK UNIFIED IDEOGRAPH
+0xD8B4 0x5A29 #CJK UNIFIED IDEOGRAPH
+0xD8B5 0x5DD2 #CJK UNIFIED IDEOGRAPH
+0xD8B6 0x5F4E #CJK UNIFIED IDEOGRAPH
+0xD8B7 0x6162 #CJK UNIFIED IDEOGRAPH
+0xD8B8 0x633D #CJK UNIFIED IDEOGRAPH
+0xD8B9 0x6669 #CJK UNIFIED IDEOGRAPH
+0xD8BA 0x66FC #CJK UNIFIED IDEOGRAPH
+0xD8BB 0x6EFF #CJK UNIFIED IDEOGRAPH
+0xD8BC 0x6F2B #CJK UNIFIED IDEOGRAPH
+0xD8BD 0x7063 #CJK UNIFIED IDEOGRAPH
+0xD8BE 0x779E #CJK UNIFIED IDEOGRAPH
+0xD8BF 0x842C #CJK UNIFIED IDEOGRAPH
+0xD8C0 0x8513 #CJK UNIFIED IDEOGRAPH
+0xD8C1 0x883B #CJK UNIFIED IDEOGRAPH
+0xD8C2 0x8F13 #CJK UNIFIED IDEOGRAPH
+0xD8C3 0x9945 #CJK UNIFIED IDEOGRAPH
+0xD8C4 0x9C3B #CJK UNIFIED IDEOGRAPH
+0xD8C5 0x551C #CJK UNIFIED IDEOGRAPH
+0xD8C6 0x62B9 #CJK UNIFIED IDEOGRAPH
+0xD8C7 0x672B #CJK UNIFIED IDEOGRAPH
+0xD8C8 0x6CAB #CJK UNIFIED IDEOGRAPH
+0xD8C9 0x8309 #CJK UNIFIED IDEOGRAPH
+0xD8CA 0x896A #CJK UNIFIED IDEOGRAPH
+0xD8CB 0x977A #CJK UNIFIED IDEOGRAPH
+0xD8CC 0x4EA1 #CJK UNIFIED IDEOGRAPH
+0xD8CD 0x5984 #CJK UNIFIED IDEOGRAPH
+0xD8CE 0x5FD8 #CJK UNIFIED IDEOGRAPH
+0xD8CF 0x5FD9 #CJK UNIFIED IDEOGRAPH
+0xD8D0 0x671B #CJK UNIFIED IDEOGRAPH
+0xD8D1 0x7DB2 #CJK UNIFIED IDEOGRAPH
+0xD8D2 0x7F54 #CJK UNIFIED IDEOGRAPH
+0xD8D3 0x8292 #CJK UNIFIED IDEOGRAPH
+0xD8D4 0x832B #CJK UNIFIED IDEOGRAPH
+0xD8D5 0x83BD #CJK UNIFIED IDEOGRAPH
+0xD8D6 0x8F1E #CJK UNIFIED IDEOGRAPH
+0xD8D7 0x9099 #CJK UNIFIED IDEOGRAPH
+0xD8D8 0x57CB #CJK UNIFIED IDEOGRAPH
+0xD8D9 0x59B9 #CJK UNIFIED IDEOGRAPH
+0xD8DA 0x5A92 #CJK UNIFIED IDEOGRAPH
+0xD8DB 0x5BD0 #CJK UNIFIED IDEOGRAPH
+0xD8DC 0x6627 #CJK UNIFIED IDEOGRAPH
+0xD8DD 0x679A #CJK UNIFIED IDEOGRAPH
+0xD8DE 0x6885 #CJK UNIFIED IDEOGRAPH
+0xD8DF 0x6BCF #CJK UNIFIED IDEOGRAPH
+0xD8E0 0x7164 #CJK UNIFIED IDEOGRAPH
+0xD8E1 0x7F75 #CJK UNIFIED IDEOGRAPH
+0xD8E2 0x8CB7 #CJK UNIFIED IDEOGRAPH
+0xD8E3 0x8CE3 #CJK UNIFIED IDEOGRAPH
+0xD8E4 0x9081 #CJK UNIFIED IDEOGRAPH
+0xD8E5 0x9B45 #CJK UNIFIED IDEOGRAPH
+0xD8E6 0x8108 #CJK UNIFIED IDEOGRAPH
+0xD8E7 0x8C8A #CJK UNIFIED IDEOGRAPH
+0xD8E8 0x964C #CJK UNIFIED IDEOGRAPH
+0xD8E9 0x9A40 #CJK UNIFIED IDEOGRAPH
+0xD8EA 0x9EA5 #CJK UNIFIED IDEOGRAPH
+0xD8EB 0x5B5F #CJK UNIFIED IDEOGRAPH
+0xD8EC 0x6C13 #CJK UNIFIED IDEOGRAPH
+0xD8ED 0x731B #CJK UNIFIED IDEOGRAPH
+0xD8EE 0x76F2 #CJK UNIFIED IDEOGRAPH
+0xD8EF 0x76DF #CJK UNIFIED IDEOGRAPH
+0xD8F0 0x840C #CJK UNIFIED IDEOGRAPH
+0xD8F1 0x51AA #CJK UNIFIED IDEOGRAPH
+0xD8F2 0x8993 #CJK UNIFIED IDEOGRAPH
+0xD8F3 0x514D #CJK UNIFIED IDEOGRAPH
+0xD8F4 0x5195 #CJK UNIFIED IDEOGRAPH
+0xD8F5 0x52C9 #CJK UNIFIED IDEOGRAPH
+0xD8F6 0x68C9 #CJK UNIFIED IDEOGRAPH
+0xD8F7 0x6C94 #CJK UNIFIED IDEOGRAPH
+0xD8F8 0x7704 #CJK UNIFIED IDEOGRAPH
+0xD8F9 0x7720 #CJK UNIFIED IDEOGRAPH
+0xD8FA 0x7DBF #CJK UNIFIED IDEOGRAPH
+0xD8FB 0x7DEC #CJK UNIFIED IDEOGRAPH
+0xD8FC 0x9762 #CJK UNIFIED IDEOGRAPH
+0xD8FD 0x9EB5 #CJK UNIFIED IDEOGRAPH
+0xD8FE 0x6EC5 #CJK UNIFIED IDEOGRAPH
+0xD9A1 0x8511 #CJK UNIFIED IDEOGRAPH
+0xD9A2 0x51A5 #CJK UNIFIED IDEOGRAPH
+0xD9A3 0x540D #CJK UNIFIED IDEOGRAPH
+0xD9A4 0x547D #CJK UNIFIED IDEOGRAPH
+0xD9A5 0x660E #CJK UNIFIED IDEOGRAPH
+0xD9A6 0x669D #CJK UNIFIED IDEOGRAPH
+0xD9A7 0x6927 #CJK UNIFIED IDEOGRAPH
+0xD9A8 0x6E9F #CJK UNIFIED IDEOGRAPH
+0xD9A9 0x76BF #CJK UNIFIED IDEOGRAPH
+0xD9AA 0x7791 #CJK UNIFIED IDEOGRAPH
+0xD9AB 0x8317 #CJK UNIFIED IDEOGRAPH
+0xD9AC 0x84C2 #CJK UNIFIED IDEOGRAPH
+0xD9AD 0x879F #CJK UNIFIED IDEOGRAPH
+0xD9AE 0x9169 #CJK UNIFIED IDEOGRAPH
+0xD9AF 0x9298 #CJK UNIFIED IDEOGRAPH
+0xD9B0 0x9CF4 #CJK UNIFIED IDEOGRAPH
+0xD9B1 0x8882 #CJK UNIFIED IDEOGRAPH
+0xD9B2 0x4FAE #CJK UNIFIED IDEOGRAPH
+0xD9B3 0x5192 #CJK UNIFIED IDEOGRAPH
+0xD9B4 0x52DF #CJK UNIFIED IDEOGRAPH
+0xD9B5 0x59C6 #CJK UNIFIED IDEOGRAPH
+0xD9B6 0x5E3D #CJK UNIFIED IDEOGRAPH
+0xD9B7 0x6155 #CJK UNIFIED IDEOGRAPH
+0xD9B8 0x6478 #CJK UNIFIED IDEOGRAPH
+0xD9B9 0x6479 #CJK UNIFIED IDEOGRAPH
+0xD9BA 0x66AE #CJK UNIFIED IDEOGRAPH
+0xD9BB 0x67D0 #CJK UNIFIED IDEOGRAPH
+0xD9BC 0x6A21 #CJK UNIFIED IDEOGRAPH
+0xD9BD 0x6BCD #CJK UNIFIED IDEOGRAPH
+0xD9BE 0x6BDB #CJK UNIFIED IDEOGRAPH
+0xD9BF 0x725F #CJK UNIFIED IDEOGRAPH
+0xD9C0 0x7261 #CJK UNIFIED IDEOGRAPH
+0xD9C1 0x7441 #CJK UNIFIED IDEOGRAPH
+0xD9C2 0x7738 #CJK UNIFIED IDEOGRAPH
+0xD9C3 0x77DB #CJK UNIFIED IDEOGRAPH
+0xD9C4 0x8017 #CJK UNIFIED IDEOGRAPH
+0xD9C5 0x82BC #CJK UNIFIED IDEOGRAPH
+0xD9C6 0x8305 #CJK UNIFIED IDEOGRAPH
+0xD9C7 0x8B00 #CJK UNIFIED IDEOGRAPH
+0xD9C8 0x8B28 #CJK UNIFIED IDEOGRAPH
+0xD9C9 0x8C8C #CJK UNIFIED IDEOGRAPH
+0xD9CA 0x6728 #CJK UNIFIED IDEOGRAPH
+0xD9CB 0x6C90 #CJK UNIFIED IDEOGRAPH
+0xD9CC 0x7267 #CJK UNIFIED IDEOGRAPH
+0xD9CD 0x76EE #CJK UNIFIED IDEOGRAPH
+0xD9CE 0x7766 #CJK UNIFIED IDEOGRAPH
+0xD9CF 0x7A46 #CJK UNIFIED IDEOGRAPH
+0xD9D0 0x9DA9 #CJK UNIFIED IDEOGRAPH
+0xD9D1 0x6B7F #CJK UNIFIED IDEOGRAPH
+0xD9D2 0x6C92 #CJK UNIFIED IDEOGRAPH
+0xD9D3 0x5922 #CJK UNIFIED IDEOGRAPH
+0xD9D4 0x6726 #CJK UNIFIED IDEOGRAPH
+0xD9D5 0x8499 #CJK UNIFIED IDEOGRAPH
+0xD9D6 0x536F #CJK UNIFIED IDEOGRAPH
+0xD9D7 0x5893 #CJK UNIFIED IDEOGRAPH
+0xD9D8 0x5999 #CJK UNIFIED IDEOGRAPH
+0xD9D9 0x5EDF #CJK UNIFIED IDEOGRAPH
+0xD9DA 0x63CF #CJK UNIFIED IDEOGRAPH
+0xD9DB 0x6634 #CJK UNIFIED IDEOGRAPH
+0xD9DC 0x6773 #CJK UNIFIED IDEOGRAPH
+0xD9DD 0x6E3A #CJK UNIFIED IDEOGRAPH
+0xD9DE 0x732B #CJK UNIFIED IDEOGRAPH
+0xD9DF 0x7AD7 #CJK UNIFIED IDEOGRAPH
+0xD9E0 0x82D7 #CJK UNIFIED IDEOGRAPH
+0xD9E1 0x9328 #CJK UNIFIED IDEOGRAPH
+0xD9E2 0x52D9 #CJK UNIFIED IDEOGRAPH
+0xD9E3 0x5DEB #CJK UNIFIED IDEOGRAPH
+0xD9E4 0x61AE #CJK UNIFIED IDEOGRAPH
+0xD9E5 0x61CB #CJK UNIFIED IDEOGRAPH
+0xD9E6 0x620A #CJK UNIFIED IDEOGRAPH
+0xD9E7 0x62C7 #CJK UNIFIED IDEOGRAPH
+0xD9E8 0x64AB #CJK UNIFIED IDEOGRAPH
+0xD9E9 0x65E0 #CJK UNIFIED IDEOGRAPH
+0xD9EA 0x6959 #CJK UNIFIED IDEOGRAPH
+0xD9EB 0x6B66 #CJK UNIFIED IDEOGRAPH
+0xD9EC 0x6BCB #CJK UNIFIED IDEOGRAPH
+0xD9ED 0x7121 #CJK UNIFIED IDEOGRAPH
+0xD9EE 0x73F7 #CJK UNIFIED IDEOGRAPH
+0xD9EF 0x755D #CJK UNIFIED IDEOGRAPH
+0xD9F0 0x7E46 #CJK UNIFIED IDEOGRAPH
+0xD9F1 0x821E #CJK UNIFIED IDEOGRAPH
+0xD9F2 0x8302 #CJK UNIFIED IDEOGRAPH
+0xD9F3 0x856A #CJK UNIFIED IDEOGRAPH
+0xD9F4 0x8AA3 #CJK UNIFIED IDEOGRAPH
+0xD9F5 0x8CBF #CJK UNIFIED IDEOGRAPH
+0xD9F6 0x9727 #CJK UNIFIED IDEOGRAPH
+0xD9F7 0x9D61 #CJK UNIFIED IDEOGRAPH
+0xD9F8 0x58A8 #CJK UNIFIED IDEOGRAPH
+0xD9F9 0x9ED8 #CJK UNIFIED IDEOGRAPH
+0xD9FA 0x5011 #CJK UNIFIED IDEOGRAPH
+0xD9FB 0x520E #CJK UNIFIED IDEOGRAPH
+0xD9FC 0x543B #CJK UNIFIED IDEOGRAPH
+0xD9FD 0x554F #CJK UNIFIED IDEOGRAPH
+0xD9FE 0x6587 #CJK UNIFIED IDEOGRAPH
+0xDAA1 0x6C76 #CJK UNIFIED IDEOGRAPH
+0xDAA2 0x7D0A #CJK UNIFIED IDEOGRAPH
+0xDAA3 0x7D0B #CJK UNIFIED IDEOGRAPH
+0xDAA4 0x805E #CJK UNIFIED IDEOGRAPH
+0xDAA5 0x868A #CJK UNIFIED IDEOGRAPH
+0xDAA6 0x9580 #CJK UNIFIED IDEOGRAPH
+0xDAA7 0x96EF #CJK UNIFIED IDEOGRAPH
+0xDAA8 0x52FF #CJK UNIFIED IDEOGRAPH
+0xDAA9 0x6C95 #CJK UNIFIED IDEOGRAPH
+0xDAAA 0x7269 #CJK UNIFIED IDEOGRAPH
+0xDAAB 0x5473 #CJK UNIFIED IDEOGRAPH
+0xDAAC 0x5A9A #CJK UNIFIED IDEOGRAPH
+0xDAAD 0x5C3E #CJK UNIFIED IDEOGRAPH
+0xDAAE 0x5D4B #CJK UNIFIED IDEOGRAPH
+0xDAAF 0x5F4C #CJK UNIFIED IDEOGRAPH
+0xDAB0 0x5FAE #CJK UNIFIED IDEOGRAPH
+0xDAB1 0x672A #CJK UNIFIED IDEOGRAPH
+0xDAB2 0x68B6 #CJK UNIFIED IDEOGRAPH
+0xDAB3 0x6963 #CJK UNIFIED IDEOGRAPH
+0xDAB4 0x6E3C #CJK UNIFIED IDEOGRAPH
+0xDAB5 0x6E44 #CJK UNIFIED IDEOGRAPH
+0xDAB6 0x7709 #CJK UNIFIED IDEOGRAPH
+0xDAB7 0x7C73 #CJK UNIFIED IDEOGRAPH
+0xDAB8 0x7F8E #CJK UNIFIED IDEOGRAPH
+0xDAB9 0x8587 #CJK UNIFIED IDEOGRAPH
+0xDABA 0x8B0E #CJK UNIFIED IDEOGRAPH
+0xDABB 0x8FF7 #CJK UNIFIED IDEOGRAPH
+0xDABC 0x9761 #CJK UNIFIED IDEOGRAPH
+0xDABD 0x9EF4 #CJK UNIFIED IDEOGRAPH
+0xDABE 0x5CB7 #CJK UNIFIED IDEOGRAPH
+0xDABF 0x60B6 #CJK UNIFIED IDEOGRAPH
+0xDAC0 0x610D #CJK UNIFIED IDEOGRAPH
+0xDAC1 0x61AB #CJK UNIFIED IDEOGRAPH
+0xDAC2 0x654F #CJK UNIFIED IDEOGRAPH
+0xDAC3 0x65FB #CJK UNIFIED IDEOGRAPH
+0xDAC4 0x65FC #CJK UNIFIED IDEOGRAPH
+0xDAC5 0x6C11 #CJK UNIFIED IDEOGRAPH
+0xDAC6 0x6CEF #CJK UNIFIED IDEOGRAPH
+0xDAC7 0x739F #CJK UNIFIED IDEOGRAPH
+0xDAC8 0x73C9 #CJK UNIFIED IDEOGRAPH
+0xDAC9 0x7DE1 #CJK UNIFIED IDEOGRAPH
+0xDACA 0x9594 #CJK UNIFIED IDEOGRAPH
+0xDACB 0x5BC6 #CJK UNIFIED IDEOGRAPH
+0xDACC 0x871C #CJK UNIFIED IDEOGRAPH
+0xDACD 0x8B10 #CJK UNIFIED IDEOGRAPH
+0xDACE 0x525D #CJK UNIFIED IDEOGRAPH
+0xDACF 0x535A #CJK UNIFIED IDEOGRAPH
+0xDAD0 0x62CD #CJK UNIFIED IDEOGRAPH
+0xDAD1 0x640F #CJK UNIFIED IDEOGRAPH
+0xDAD2 0x64B2 #CJK UNIFIED IDEOGRAPH
+0xDAD3 0x6734 #CJK UNIFIED IDEOGRAPH
+0xDAD4 0x6A38 #CJK UNIFIED IDEOGRAPH
+0xDAD5 0x6CCA #CJK UNIFIED IDEOGRAPH
+0xDAD6 0x73C0 #CJK UNIFIED IDEOGRAPH
+0xDAD7 0x749E #CJK UNIFIED IDEOGRAPH
+0xDAD8 0x7B94 #CJK UNIFIED IDEOGRAPH
+0xDAD9 0x7C95 #CJK UNIFIED IDEOGRAPH
+0xDADA 0x7E1B #CJK UNIFIED IDEOGRAPH
+0xDADB 0x818A #CJK UNIFIED IDEOGRAPH
+0xDADC 0x8236 #CJK UNIFIED IDEOGRAPH
+0xDADD 0x8584 #CJK UNIFIED IDEOGRAPH
+0xDADE 0x8FEB #CJK UNIFIED IDEOGRAPH
+0xDADF 0x96F9 #CJK UNIFIED IDEOGRAPH
+0xDAE0 0x99C1 #CJK UNIFIED IDEOGRAPH
+0xDAE1 0x4F34 #CJK UNIFIED IDEOGRAPH
+0xDAE2 0x534A #CJK UNIFIED IDEOGRAPH
+0xDAE3 0x53CD #CJK UNIFIED IDEOGRAPH
+0xDAE4 0x53DB #CJK UNIFIED IDEOGRAPH
+0xDAE5 0x62CC #CJK UNIFIED IDEOGRAPH
+0xDAE6 0x642C #CJK UNIFIED IDEOGRAPH
+0xDAE7 0x6500 #CJK UNIFIED IDEOGRAPH
+0xDAE8 0x6591 #CJK UNIFIED IDEOGRAPH
+0xDAE9 0x69C3 #CJK UNIFIED IDEOGRAPH
+0xDAEA 0x6CEE #CJK UNIFIED IDEOGRAPH
+0xDAEB 0x6F58 #CJK UNIFIED IDEOGRAPH
+0xDAEC 0x73ED #CJK UNIFIED IDEOGRAPH
+0xDAED 0x7554 #CJK UNIFIED IDEOGRAPH
+0xDAEE 0x7622 #CJK UNIFIED IDEOGRAPH
+0xDAEF 0x76E4 #CJK UNIFIED IDEOGRAPH
+0xDAF0 0x76FC #CJK UNIFIED IDEOGRAPH
+0xDAF1 0x78D0 #CJK UNIFIED IDEOGRAPH
+0xDAF2 0x78FB #CJK UNIFIED IDEOGRAPH
+0xDAF3 0x792C #CJK UNIFIED IDEOGRAPH
+0xDAF4 0x7D46 #CJK UNIFIED IDEOGRAPH
+0xDAF5 0x822C #CJK UNIFIED IDEOGRAPH
+0xDAF6 0x87E0 #CJK UNIFIED IDEOGRAPH
+0xDAF7 0x8FD4 #CJK UNIFIED IDEOGRAPH
+0xDAF8 0x9812 #CJK UNIFIED IDEOGRAPH
+0xDAF9 0x98EF #CJK UNIFIED IDEOGRAPH
+0xDAFA 0x52C3 #CJK UNIFIED IDEOGRAPH
+0xDAFB 0x62D4 #CJK UNIFIED IDEOGRAPH
+0xDAFC 0x64A5 #CJK UNIFIED IDEOGRAPH
+0xDAFD 0x6E24 #CJK UNIFIED IDEOGRAPH
+0xDAFE 0x6F51 #CJK UNIFIED IDEOGRAPH
+0xDBA1 0x767C #CJK UNIFIED IDEOGRAPH
+0xDBA2 0x8DCB #CJK UNIFIED IDEOGRAPH
+0xDBA3 0x91B1 #CJK UNIFIED IDEOGRAPH
+0xDBA4 0x9262 #CJK UNIFIED IDEOGRAPH
+0xDBA5 0x9AEE #CJK UNIFIED IDEOGRAPH
+0xDBA6 0x9B43 #CJK UNIFIED IDEOGRAPH
+0xDBA7 0x5023 #CJK UNIFIED IDEOGRAPH
+0xDBA8 0x508D #CJK UNIFIED IDEOGRAPH
+0xDBA9 0x574A #CJK UNIFIED IDEOGRAPH
+0xDBAA 0x59A8 #CJK UNIFIED IDEOGRAPH
+0xDBAB 0x5C28 #CJK UNIFIED IDEOGRAPH
+0xDBAC 0x5E47 #CJK UNIFIED IDEOGRAPH
+0xDBAD 0x5F77 #CJK UNIFIED IDEOGRAPH
+0xDBAE 0x623F #CJK UNIFIED IDEOGRAPH
+0xDBAF 0x653E #CJK UNIFIED IDEOGRAPH
+0xDBB0 0x65B9 #CJK UNIFIED IDEOGRAPH
+0xDBB1 0x65C1 #CJK UNIFIED IDEOGRAPH
+0xDBB2 0x6609 #CJK UNIFIED IDEOGRAPH
+0xDBB3 0x678B #CJK UNIFIED IDEOGRAPH
+0xDBB4 0x699C #CJK UNIFIED IDEOGRAPH
+0xDBB5 0x6EC2 #CJK UNIFIED IDEOGRAPH
+0xDBB6 0x78C5 #CJK UNIFIED IDEOGRAPH
+0xDBB7 0x7D21 #CJK UNIFIED IDEOGRAPH
+0xDBB8 0x80AA #CJK UNIFIED IDEOGRAPH
+0xDBB9 0x8180 #CJK UNIFIED IDEOGRAPH
+0xDBBA 0x822B #CJK UNIFIED IDEOGRAPH
+0xDBBB 0x82B3 #CJK UNIFIED IDEOGRAPH
+0xDBBC 0x84A1 #CJK UNIFIED IDEOGRAPH
+0xDBBD 0x868C #CJK UNIFIED IDEOGRAPH
+0xDBBE 0x8A2A #CJK UNIFIED IDEOGRAPH
+0xDBBF 0x8B17 #CJK UNIFIED IDEOGRAPH
+0xDBC0 0x90A6 #CJK UNIFIED IDEOGRAPH
+0xDBC1 0x9632 #CJK UNIFIED IDEOGRAPH
+0xDBC2 0x9F90 #CJK UNIFIED IDEOGRAPH
+0xDBC3 0x500D #CJK UNIFIED IDEOGRAPH
+0xDBC4 0x4FF3 #CJK UNIFIED IDEOGRAPH
+0xDBC5 0xF963 #CJK COMPATIBILITY IDEOGRAPH
+0xDBC6 0x57F9 #CJK UNIFIED IDEOGRAPH
+0xDBC7 0x5F98 #CJK UNIFIED IDEOGRAPH
+0xDBC8 0x62DC #CJK UNIFIED IDEOGRAPH
+0xDBC9 0x6392 #CJK UNIFIED IDEOGRAPH
+0xDBCA 0x676F #CJK UNIFIED IDEOGRAPH
+0xDBCB 0x6E43 #CJK UNIFIED IDEOGRAPH
+0xDBCC 0x7119 #CJK UNIFIED IDEOGRAPH
+0xDBCD 0x76C3 #CJK UNIFIED IDEOGRAPH
+0xDBCE 0x80CC #CJK UNIFIED IDEOGRAPH
+0xDBCF 0x80DA #CJK UNIFIED IDEOGRAPH
+0xDBD0 0x88F4 #CJK UNIFIED IDEOGRAPH
+0xDBD1 0x88F5 #CJK UNIFIED IDEOGRAPH
+0xDBD2 0x8919 #CJK UNIFIED IDEOGRAPH
+0xDBD3 0x8CE0 #CJK UNIFIED IDEOGRAPH
+0xDBD4 0x8F29 #CJK UNIFIED IDEOGRAPH
+0xDBD5 0x914D #CJK UNIFIED IDEOGRAPH
+0xDBD6 0x966A #CJK UNIFIED IDEOGRAPH
+0xDBD7 0x4F2F #CJK UNIFIED IDEOGRAPH
+0xDBD8 0x4F70 #CJK UNIFIED IDEOGRAPH
+0xDBD9 0x5E1B #CJK UNIFIED IDEOGRAPH
+0xDBDA 0x67CF #CJK UNIFIED IDEOGRAPH
+0xDBDB 0x6822 #CJK UNIFIED IDEOGRAPH
+0xDBDC 0x767D #CJK UNIFIED IDEOGRAPH
+0xDBDD 0x767E #CJK UNIFIED IDEOGRAPH
+0xDBDE 0x9B44 #CJK UNIFIED IDEOGRAPH
+0xDBDF 0x5E61 #CJK UNIFIED IDEOGRAPH
+0xDBE0 0x6A0A #CJK UNIFIED IDEOGRAPH
+0xDBE1 0x7169 #CJK UNIFIED IDEOGRAPH
+0xDBE2 0x71D4 #CJK UNIFIED IDEOGRAPH
+0xDBE3 0x756A #CJK UNIFIED IDEOGRAPH
+0xDBE4 0xF964 #CJK COMPATIBILITY IDEOGRAPH
+0xDBE5 0x7E41 #CJK UNIFIED IDEOGRAPH
+0xDBE6 0x8543 #CJK UNIFIED IDEOGRAPH
+0xDBE7 0x85E9 #CJK UNIFIED IDEOGRAPH
+0xDBE8 0x98DC #CJK UNIFIED IDEOGRAPH
+0xDBE9 0x4F10 #CJK UNIFIED IDEOGRAPH
+0xDBEA 0x7B4F #CJK UNIFIED IDEOGRAPH
+0xDBEB 0x7F70 #CJK UNIFIED IDEOGRAPH
+0xDBEC 0x95A5 #CJK UNIFIED IDEOGRAPH
+0xDBED 0x51E1 #CJK UNIFIED IDEOGRAPH
+0xDBEE 0x5E06 #CJK UNIFIED IDEOGRAPH
+0xDBEF 0x68B5 #CJK UNIFIED IDEOGRAPH
+0xDBF0 0x6C3E #CJK UNIFIED IDEOGRAPH
+0xDBF1 0x6C4E #CJK UNIFIED IDEOGRAPH
+0xDBF2 0x6CDB #CJK UNIFIED IDEOGRAPH
+0xDBF3 0x72AF #CJK UNIFIED IDEOGRAPH
+0xDBF4 0x7BC4 #CJK UNIFIED IDEOGRAPH
+0xDBF5 0x8303 #CJK UNIFIED IDEOGRAPH
+0xDBF6 0x6CD5 #CJK UNIFIED IDEOGRAPH
+0xDBF7 0x743A #CJK UNIFIED IDEOGRAPH
+0xDBF8 0x50FB #CJK UNIFIED IDEOGRAPH
+0xDBF9 0x5288 #CJK UNIFIED IDEOGRAPH
+0xDBFA 0x58C1 #CJK UNIFIED IDEOGRAPH
+0xDBFB 0x64D8 #CJK UNIFIED IDEOGRAPH
+0xDBFC 0x6A97 #CJK UNIFIED IDEOGRAPH
+0xDBFD 0x74A7 #CJK UNIFIED IDEOGRAPH
+0xDBFE 0x7656 #CJK UNIFIED IDEOGRAPH
+0xDCA1 0x78A7 #CJK UNIFIED IDEOGRAPH
+0xDCA2 0x8617 #CJK UNIFIED IDEOGRAPH
+0xDCA3 0x95E2 #CJK UNIFIED IDEOGRAPH
+0xDCA4 0x9739 #CJK UNIFIED IDEOGRAPH
+0xDCA5 0xF965 #CJK COMPATIBILITY IDEOGRAPH
+0xDCA6 0x535E #CJK UNIFIED IDEOGRAPH
+0xDCA7 0x5F01 #CJK UNIFIED IDEOGRAPH
+0xDCA8 0x8B8A #CJK UNIFIED IDEOGRAPH
+0xDCA9 0x8FA8 #CJK UNIFIED IDEOGRAPH
+0xDCAA 0x8FAF #CJK UNIFIED IDEOGRAPH
+0xDCAB 0x908A #CJK UNIFIED IDEOGRAPH
+0xDCAC 0x5225 #CJK UNIFIED IDEOGRAPH
+0xDCAD 0x77A5 #CJK UNIFIED IDEOGRAPH
+0xDCAE 0x9C49 #CJK UNIFIED IDEOGRAPH
+0xDCAF 0x9F08 #CJK UNIFIED IDEOGRAPH
+0xDCB0 0x4E19 #CJK UNIFIED IDEOGRAPH
+0xDCB1 0x5002 #CJK UNIFIED IDEOGRAPH
+0xDCB2 0x5175 #CJK UNIFIED IDEOGRAPH
+0xDCB3 0x5C5B #CJK UNIFIED IDEOGRAPH
+0xDCB4 0x5E77 #CJK UNIFIED IDEOGRAPH
+0xDCB5 0x661E #CJK UNIFIED IDEOGRAPH
+0xDCB6 0x663A #CJK UNIFIED IDEOGRAPH
+0xDCB7 0x67C4 #CJK UNIFIED IDEOGRAPH
+0xDCB8 0x68C5 #CJK UNIFIED IDEOGRAPH
+0xDCB9 0x70B3 #CJK UNIFIED IDEOGRAPH
+0xDCBA 0x7501 #CJK UNIFIED IDEOGRAPH
+0xDCBB 0x75C5 #CJK UNIFIED IDEOGRAPH
+0xDCBC 0x79C9 #CJK UNIFIED IDEOGRAPH
+0xDCBD 0x7ADD #CJK UNIFIED IDEOGRAPH
+0xDCBE 0x8F27 #CJK UNIFIED IDEOGRAPH
+0xDCBF 0x9920 #CJK UNIFIED IDEOGRAPH
+0xDCC0 0x9A08 #CJK UNIFIED IDEOGRAPH
+0xDCC1 0x4FDD #CJK UNIFIED IDEOGRAPH
+0xDCC2 0x5821 #CJK UNIFIED IDEOGRAPH
+0xDCC3 0x5831 #CJK UNIFIED IDEOGRAPH
+0xDCC4 0x5BF6 #CJK UNIFIED IDEOGRAPH
+0xDCC5 0x666E #CJK UNIFIED IDEOGRAPH
+0xDCC6 0x6B65 #CJK UNIFIED IDEOGRAPH
+0xDCC7 0x6D11 #CJK UNIFIED IDEOGRAPH
+0xDCC8 0x6E7A #CJK UNIFIED IDEOGRAPH
+0xDCC9 0x6F7D #CJK UNIFIED IDEOGRAPH
+0xDCCA 0x73E4 #CJK UNIFIED IDEOGRAPH
+0xDCCB 0x752B #CJK UNIFIED IDEOGRAPH
+0xDCCC 0x83E9 #CJK UNIFIED IDEOGRAPH
+0xDCCD 0x88DC #CJK UNIFIED IDEOGRAPH
+0xDCCE 0x8913 #CJK UNIFIED IDEOGRAPH
+0xDCCF 0x8B5C #CJK UNIFIED IDEOGRAPH
+0xDCD0 0x8F14 #CJK UNIFIED IDEOGRAPH
+0xDCD1 0x4F0F #CJK UNIFIED IDEOGRAPH
+0xDCD2 0x50D5 #CJK UNIFIED IDEOGRAPH
+0xDCD3 0x5310 #CJK UNIFIED IDEOGRAPH
+0xDCD4 0x535C #CJK UNIFIED IDEOGRAPH
+0xDCD5 0x5B93 #CJK UNIFIED IDEOGRAPH
+0xDCD6 0x5FA9 #CJK UNIFIED IDEOGRAPH
+0xDCD7 0x670D #CJK UNIFIED IDEOGRAPH
+0xDCD8 0x798F #CJK UNIFIED IDEOGRAPH
+0xDCD9 0x8179 #CJK UNIFIED IDEOGRAPH
+0xDCDA 0x832F #CJK UNIFIED IDEOGRAPH
+0xDCDB 0x8514 #CJK UNIFIED IDEOGRAPH
+0xDCDC 0x8907 #CJK UNIFIED IDEOGRAPH
+0xDCDD 0x8986 #CJK UNIFIED IDEOGRAPH
+0xDCDE 0x8F39 #CJK UNIFIED IDEOGRAPH
+0xDCDF 0x8F3B #CJK UNIFIED IDEOGRAPH
+0xDCE0 0x99A5 #CJK UNIFIED IDEOGRAPH
+0xDCE1 0x9C12 #CJK UNIFIED IDEOGRAPH
+0xDCE2 0x672C #CJK UNIFIED IDEOGRAPH
+0xDCE3 0x4E76 #CJK UNIFIED IDEOGRAPH
+0xDCE4 0x4FF8 #CJK UNIFIED IDEOGRAPH
+0xDCE5 0x5949 #CJK UNIFIED IDEOGRAPH
+0xDCE6 0x5C01 #CJK UNIFIED IDEOGRAPH
+0xDCE7 0x5CEF #CJK UNIFIED IDEOGRAPH
+0xDCE8 0x5CF0 #CJK UNIFIED IDEOGRAPH
+0xDCE9 0x6367 #CJK UNIFIED IDEOGRAPH
+0xDCEA 0x68D2 #CJK UNIFIED IDEOGRAPH
+0xDCEB 0x70FD #CJK UNIFIED IDEOGRAPH
+0xDCEC 0x71A2 #CJK UNIFIED IDEOGRAPH
+0xDCED 0x742B #CJK UNIFIED IDEOGRAPH
+0xDCEE 0x7E2B #CJK UNIFIED IDEOGRAPH
+0xDCEF 0x84EC #CJK UNIFIED IDEOGRAPH
+0xDCF0 0x8702 #CJK UNIFIED IDEOGRAPH
+0xDCF1 0x9022 #CJK UNIFIED IDEOGRAPH
+0xDCF2 0x92D2 #CJK UNIFIED IDEOGRAPH
+0xDCF3 0x9CF3 #CJK UNIFIED IDEOGRAPH
+0xDCF4 0x4E0D #CJK UNIFIED IDEOGRAPH
+0xDCF5 0x4ED8 #CJK UNIFIED IDEOGRAPH
+0xDCF6 0x4FEF #CJK UNIFIED IDEOGRAPH
+0xDCF7 0x5085 #CJK UNIFIED IDEOGRAPH
+0xDCF8 0x5256 #CJK UNIFIED IDEOGRAPH
+0xDCF9 0x526F #CJK UNIFIED IDEOGRAPH
+0xDCFA 0x5426 #CJK UNIFIED IDEOGRAPH
+0xDCFB 0x5490 #CJK UNIFIED IDEOGRAPH
+0xDCFC 0x57E0 #CJK UNIFIED IDEOGRAPH
+0xDCFD 0x592B #CJK UNIFIED IDEOGRAPH
+0xDCFE 0x5A66 #CJK UNIFIED IDEOGRAPH
+0xDDA1 0x5B5A #CJK UNIFIED IDEOGRAPH
+0xDDA2 0x5B75 #CJK UNIFIED IDEOGRAPH
+0xDDA3 0x5BCC #CJK UNIFIED IDEOGRAPH
+0xDDA4 0x5E9C #CJK UNIFIED IDEOGRAPH
+0xDDA5 0xF966 #CJK COMPATIBILITY IDEOGRAPH
+0xDDA6 0x6276 #CJK UNIFIED IDEOGRAPH
+0xDDA7 0x6577 #CJK UNIFIED IDEOGRAPH
+0xDDA8 0x65A7 #CJK UNIFIED IDEOGRAPH
+0xDDA9 0x6D6E #CJK UNIFIED IDEOGRAPH
+0xDDAA 0x6EA5 #CJK UNIFIED IDEOGRAPH
+0xDDAB 0x7236 #CJK UNIFIED IDEOGRAPH
+0xDDAC 0x7B26 #CJK UNIFIED IDEOGRAPH
+0xDDAD 0x7C3F #CJK UNIFIED IDEOGRAPH
+0xDDAE 0x7F36 #CJK UNIFIED IDEOGRAPH
+0xDDAF 0x8150 #CJK UNIFIED IDEOGRAPH
+0xDDB0 0x8151 #CJK UNIFIED IDEOGRAPH
+0xDDB1 0x819A #CJK UNIFIED IDEOGRAPH
+0xDDB2 0x8240 #CJK UNIFIED IDEOGRAPH
+0xDDB3 0x8299 #CJK UNIFIED IDEOGRAPH
+0xDDB4 0x83A9 #CJK UNIFIED IDEOGRAPH
+0xDDB5 0x8A03 #CJK UNIFIED IDEOGRAPH
+0xDDB6 0x8CA0 #CJK UNIFIED IDEOGRAPH
+0xDDB7 0x8CE6 #CJK UNIFIED IDEOGRAPH
+0xDDB8 0x8CFB #CJK UNIFIED IDEOGRAPH
+0xDDB9 0x8D74 #CJK UNIFIED IDEOGRAPH
+0xDDBA 0x8DBA #CJK UNIFIED IDEOGRAPH
+0xDDBB 0x90E8 #CJK UNIFIED IDEOGRAPH
+0xDDBC 0x91DC #CJK UNIFIED IDEOGRAPH
+0xDDBD 0x961C #CJK UNIFIED IDEOGRAPH
+0xDDBE 0x9644 #CJK UNIFIED IDEOGRAPH
+0xDDBF 0x99D9 #CJK UNIFIED IDEOGRAPH
+0xDDC0 0x9CE7 #CJK UNIFIED IDEOGRAPH
+0xDDC1 0x5317 #CJK UNIFIED IDEOGRAPH
+0xDDC2 0x5206 #CJK UNIFIED IDEOGRAPH
+0xDDC3 0x5429 #CJK UNIFIED IDEOGRAPH
+0xDDC4 0x5674 #CJK UNIFIED IDEOGRAPH
+0xDDC5 0x58B3 #CJK UNIFIED IDEOGRAPH
+0xDDC6 0x5954 #CJK UNIFIED IDEOGRAPH
+0xDDC7 0x596E #CJK UNIFIED IDEOGRAPH
+0xDDC8 0x5FFF #CJK UNIFIED IDEOGRAPH
+0xDDC9 0x61A4 #CJK UNIFIED IDEOGRAPH
+0xDDCA 0x626E #CJK UNIFIED IDEOGRAPH
+0xDDCB 0x6610 #CJK UNIFIED IDEOGRAPH
+0xDDCC 0x6C7E #CJK UNIFIED IDEOGRAPH
+0xDDCD 0x711A #CJK UNIFIED IDEOGRAPH
+0xDDCE 0x76C6 #CJK UNIFIED IDEOGRAPH
+0xDDCF 0x7C89 #CJK UNIFIED IDEOGRAPH
+0xDDD0 0x7CDE #CJK UNIFIED IDEOGRAPH
+0xDDD1 0x7D1B #CJK UNIFIED IDEOGRAPH
+0xDDD2 0x82AC #CJK UNIFIED IDEOGRAPH
+0xDDD3 0x8CC1 #CJK UNIFIED IDEOGRAPH
+0xDDD4 0x96F0 #CJK UNIFIED IDEOGRAPH
+0xDDD5 0xF967 #CJK COMPATIBILITY IDEOGRAPH
+0xDDD6 0x4F5B #CJK UNIFIED IDEOGRAPH
+0xDDD7 0x5F17 #CJK UNIFIED IDEOGRAPH
+0xDDD8 0x5F7F #CJK UNIFIED IDEOGRAPH
+0xDDD9 0x62C2 #CJK UNIFIED IDEOGRAPH
+0xDDDA 0x5D29 #CJK UNIFIED IDEOGRAPH
+0xDDDB 0x670B #CJK UNIFIED IDEOGRAPH
+0xDDDC 0x68DA #CJK UNIFIED IDEOGRAPH
+0xDDDD 0x787C #CJK UNIFIED IDEOGRAPH
+0xDDDE 0x7E43 #CJK UNIFIED IDEOGRAPH
+0xDDDF 0x9D6C #CJK UNIFIED IDEOGRAPH
+0xDDE0 0x4E15 #CJK UNIFIED IDEOGRAPH
+0xDDE1 0x5099 #CJK UNIFIED IDEOGRAPH
+0xDDE2 0x5315 #CJK UNIFIED IDEOGRAPH
+0xDDE3 0x532A #CJK UNIFIED IDEOGRAPH
+0xDDE4 0x5351 #CJK UNIFIED IDEOGRAPH
+0xDDE5 0x5983 #CJK UNIFIED IDEOGRAPH
+0xDDE6 0x5A62 #CJK UNIFIED IDEOGRAPH
+0xDDE7 0x5E87 #CJK UNIFIED IDEOGRAPH
+0xDDE8 0x60B2 #CJK UNIFIED IDEOGRAPH
+0xDDE9 0x618A #CJK UNIFIED IDEOGRAPH
+0xDDEA 0x6249 #CJK UNIFIED IDEOGRAPH
+0xDDEB 0x6279 #CJK UNIFIED IDEOGRAPH
+0xDDEC 0x6590 #CJK UNIFIED IDEOGRAPH
+0xDDED 0x6787 #CJK UNIFIED IDEOGRAPH
+0xDDEE 0x69A7 #CJK UNIFIED IDEOGRAPH
+0xDDEF 0x6BD4 #CJK UNIFIED IDEOGRAPH
+0xDDF0 0x6BD6 #CJK UNIFIED IDEOGRAPH
+0xDDF1 0x6BD7 #CJK UNIFIED IDEOGRAPH
+0xDDF2 0x6BD8 #CJK UNIFIED IDEOGRAPH
+0xDDF3 0x6CB8 #CJK UNIFIED IDEOGRAPH
+0xDDF4 0xF968 #CJK COMPATIBILITY IDEOGRAPH
+0xDDF5 0x7435 #CJK UNIFIED IDEOGRAPH
+0xDDF6 0x75FA #CJK UNIFIED IDEOGRAPH
+0xDDF7 0x7812 #CJK UNIFIED IDEOGRAPH
+0xDDF8 0x7891 #CJK UNIFIED IDEOGRAPH
+0xDDF9 0x79D5 #CJK UNIFIED IDEOGRAPH
+0xDDFA 0x79D8 #CJK UNIFIED IDEOGRAPH
+0xDDFB 0x7C83 #CJK UNIFIED IDEOGRAPH
+0xDDFC 0x7DCB #CJK UNIFIED IDEOGRAPH
+0xDDFD 0x7FE1 #CJK UNIFIED IDEOGRAPH
+0xDDFE 0x80A5 #CJK UNIFIED IDEOGRAPH
+0xDEA1 0x813E #CJK UNIFIED IDEOGRAPH
+0xDEA2 0x81C2 #CJK UNIFIED IDEOGRAPH
+0xDEA3 0x83F2 #CJK UNIFIED IDEOGRAPH
+0xDEA4 0x871A #CJK UNIFIED IDEOGRAPH
+0xDEA5 0x88E8 #CJK UNIFIED IDEOGRAPH
+0xDEA6 0x8AB9 #CJK UNIFIED IDEOGRAPH
+0xDEA7 0x8B6C #CJK UNIFIED IDEOGRAPH
+0xDEA8 0x8CBB #CJK UNIFIED IDEOGRAPH
+0xDEA9 0x9119 #CJK UNIFIED IDEOGRAPH
+0xDEAA 0x975E #CJK UNIFIED IDEOGRAPH
+0xDEAB 0x98DB #CJK UNIFIED IDEOGRAPH
+0xDEAC 0x9F3B #CJK UNIFIED IDEOGRAPH
+0xDEAD 0x56AC #CJK UNIFIED IDEOGRAPH
+0xDEAE 0x5B2A #CJK UNIFIED IDEOGRAPH
+0xDEAF 0x5F6C #CJK UNIFIED IDEOGRAPH
+0xDEB0 0x658C #CJK UNIFIED IDEOGRAPH
+0xDEB1 0x6AB3 #CJK UNIFIED IDEOGRAPH
+0xDEB2 0x6BAF #CJK UNIFIED IDEOGRAPH
+0xDEB3 0x6D5C #CJK UNIFIED IDEOGRAPH
+0xDEB4 0x6FF1 #CJK UNIFIED IDEOGRAPH
+0xDEB5 0x7015 #CJK UNIFIED IDEOGRAPH
+0xDEB6 0x725D #CJK UNIFIED IDEOGRAPH
+0xDEB7 0x73AD #CJK UNIFIED IDEOGRAPH
+0xDEB8 0x8CA7 #CJK UNIFIED IDEOGRAPH
+0xDEB9 0x8CD3 #CJK UNIFIED IDEOGRAPH
+0xDEBA 0x983B #CJK UNIFIED IDEOGRAPH
+0xDEBB 0x6191 #CJK UNIFIED IDEOGRAPH
+0xDEBC 0x6C37 #CJK UNIFIED IDEOGRAPH
+0xDEBD 0x8058 #CJK UNIFIED IDEOGRAPH
+0xDEBE 0x9A01 #CJK UNIFIED IDEOGRAPH
+0xDEBF 0x4E4D #CJK UNIFIED IDEOGRAPH
+0xDEC0 0x4E8B #CJK UNIFIED IDEOGRAPH
+0xDEC1 0x4E9B #CJK UNIFIED IDEOGRAPH
+0xDEC2 0x4ED5 #CJK UNIFIED IDEOGRAPH
+0xDEC3 0x4F3A #CJK UNIFIED IDEOGRAPH
+0xDEC4 0x4F3C #CJK UNIFIED IDEOGRAPH
+0xDEC5 0x4F7F #CJK UNIFIED IDEOGRAPH
+0xDEC6 0x4FDF #CJK UNIFIED IDEOGRAPH
+0xDEC7 0x50FF #CJK UNIFIED IDEOGRAPH
+0xDEC8 0x53F2 #CJK UNIFIED IDEOGRAPH
+0xDEC9 0x53F8 #CJK UNIFIED IDEOGRAPH
+0xDECA 0x5506 #CJK UNIFIED IDEOGRAPH
+0xDECB 0x55E3 #CJK UNIFIED IDEOGRAPH
+0xDECC 0x56DB #CJK UNIFIED IDEOGRAPH
+0xDECD 0x58EB #CJK UNIFIED IDEOGRAPH
+0xDECE 0x5962 #CJK UNIFIED IDEOGRAPH
+0xDECF 0x5A11 #CJK UNIFIED IDEOGRAPH
+0xDED0 0x5BEB #CJK UNIFIED IDEOGRAPH
+0xDED1 0x5BFA #CJK UNIFIED IDEOGRAPH
+0xDED2 0x5C04 #CJK UNIFIED IDEOGRAPH
+0xDED3 0x5DF3 #CJK UNIFIED IDEOGRAPH
+0xDED4 0x5E2B #CJK UNIFIED IDEOGRAPH
+0xDED5 0x5F99 #CJK UNIFIED IDEOGRAPH
+0xDED6 0x601D #CJK UNIFIED IDEOGRAPH
+0xDED7 0x6368 #CJK UNIFIED IDEOGRAPH
+0xDED8 0x659C #CJK UNIFIED IDEOGRAPH
+0xDED9 0x65AF #CJK UNIFIED IDEOGRAPH
+0xDEDA 0x67F6 #CJK UNIFIED IDEOGRAPH
+0xDEDB 0x67FB #CJK UNIFIED IDEOGRAPH
+0xDEDC 0x68AD #CJK UNIFIED IDEOGRAPH
+0xDEDD 0x6B7B #CJK UNIFIED IDEOGRAPH
+0xDEDE 0x6C99 #CJK UNIFIED IDEOGRAPH
+0xDEDF 0x6CD7 #CJK UNIFIED IDEOGRAPH
+0xDEE0 0x6E23 #CJK UNIFIED IDEOGRAPH
+0xDEE1 0x7009 #CJK UNIFIED IDEOGRAPH
+0xDEE2 0x7345 #CJK UNIFIED IDEOGRAPH
+0xDEE3 0x7802 #CJK UNIFIED IDEOGRAPH
+0xDEE4 0x793E #CJK UNIFIED IDEOGRAPH
+0xDEE5 0x7940 #CJK UNIFIED IDEOGRAPH
+0xDEE6 0x7960 #CJK UNIFIED IDEOGRAPH
+0xDEE7 0x79C1 #CJK UNIFIED IDEOGRAPH
+0xDEE8 0x7BE9 #CJK UNIFIED IDEOGRAPH
+0xDEE9 0x7D17 #CJK UNIFIED IDEOGRAPH
+0xDEEA 0x7D72 #CJK UNIFIED IDEOGRAPH
+0xDEEB 0x8086 #CJK UNIFIED IDEOGRAPH
+0xDEEC 0x820D #CJK UNIFIED IDEOGRAPH
+0xDEED 0x838E #CJK UNIFIED IDEOGRAPH
+0xDEEE 0x84D1 #CJK UNIFIED IDEOGRAPH
+0xDEEF 0x86C7 #CJK UNIFIED IDEOGRAPH
+0xDEF0 0x88DF #CJK UNIFIED IDEOGRAPH
+0xDEF1 0x8A50 #CJK UNIFIED IDEOGRAPH
+0xDEF2 0x8A5E #CJK UNIFIED IDEOGRAPH
+0xDEF3 0x8B1D #CJK UNIFIED IDEOGRAPH
+0xDEF4 0x8CDC #CJK UNIFIED IDEOGRAPH
+0xDEF5 0x8D66 #CJK UNIFIED IDEOGRAPH
+0xDEF6 0x8FAD #CJK UNIFIED IDEOGRAPH
+0xDEF7 0x90AA #CJK UNIFIED IDEOGRAPH
+0xDEF8 0x98FC #CJK UNIFIED IDEOGRAPH
+0xDEF9 0x99DF #CJK UNIFIED IDEOGRAPH
+0xDEFA 0x9E9D #CJK UNIFIED IDEOGRAPH
+0xDEFB 0x524A #CJK UNIFIED IDEOGRAPH
+0xDEFC 0xF969 #CJK COMPATIBILITY IDEOGRAPH
+0xDEFD 0x6714 #CJK UNIFIED IDEOGRAPH
+0xDEFE 0xF96A #CJK COMPATIBILITY IDEOGRAPH
+0xDFA1 0x5098 #CJK UNIFIED IDEOGRAPH
+0xDFA2 0x522A #CJK UNIFIED IDEOGRAPH
+0xDFA3 0x5C71 #CJK UNIFIED IDEOGRAPH
+0xDFA4 0x6563 #CJK UNIFIED IDEOGRAPH
+0xDFA5 0x6C55 #CJK UNIFIED IDEOGRAPH
+0xDFA6 0x73CA #CJK UNIFIED IDEOGRAPH
+0xDFA7 0x7523 #CJK UNIFIED IDEOGRAPH
+0xDFA8 0x759D #CJK UNIFIED IDEOGRAPH
+0xDFA9 0x7B97 #CJK UNIFIED IDEOGRAPH
+0xDFAA 0x849C #CJK UNIFIED IDEOGRAPH
+0xDFAB 0x9178 #CJK UNIFIED IDEOGRAPH
+0xDFAC 0x9730 #CJK UNIFIED IDEOGRAPH
+0xDFAD 0x4E77 #CJK UNIFIED IDEOGRAPH
+0xDFAE 0x6492 #CJK UNIFIED IDEOGRAPH
+0xDFAF 0x6BBA #CJK UNIFIED IDEOGRAPH
+0xDFB0 0x715E #CJK UNIFIED IDEOGRAPH
+0xDFB1 0x85A9 #CJK UNIFIED IDEOGRAPH
+0xDFB2 0x4E09 #CJK UNIFIED IDEOGRAPH
+0xDFB3 0xF96B #CJK COMPATIBILITY IDEOGRAPH
+0xDFB4 0x6749 #CJK UNIFIED IDEOGRAPH
+0xDFB5 0x68EE #CJK UNIFIED IDEOGRAPH
+0xDFB6 0x6E17 #CJK UNIFIED IDEOGRAPH
+0xDFB7 0x829F #CJK UNIFIED IDEOGRAPH
+0xDFB8 0x8518 #CJK UNIFIED IDEOGRAPH
+0xDFB9 0x886B #CJK UNIFIED IDEOGRAPH
+0xDFBA 0x63F7 #CJK UNIFIED IDEOGRAPH
+0xDFBB 0x6F81 #CJK UNIFIED IDEOGRAPH
+0xDFBC 0x9212 #CJK UNIFIED IDEOGRAPH
+0xDFBD 0x98AF #CJK UNIFIED IDEOGRAPH
+0xDFBE 0x4E0A #CJK UNIFIED IDEOGRAPH
+0xDFBF 0x50B7 #CJK UNIFIED IDEOGRAPH
+0xDFC0 0x50CF #CJK UNIFIED IDEOGRAPH
+0xDFC1 0x511F #CJK UNIFIED IDEOGRAPH
+0xDFC2 0x5546 #CJK UNIFIED IDEOGRAPH
+0xDFC3 0x55AA #CJK UNIFIED IDEOGRAPH
+0xDFC4 0x5617 #CJK UNIFIED IDEOGRAPH
+0xDFC5 0x5B40 #CJK UNIFIED IDEOGRAPH
+0xDFC6 0x5C19 #CJK UNIFIED IDEOGRAPH
+0xDFC7 0x5CE0 #CJK UNIFIED IDEOGRAPH
+0xDFC8 0x5E38 #CJK UNIFIED IDEOGRAPH
+0xDFC9 0x5E8A #CJK UNIFIED IDEOGRAPH
+0xDFCA 0x5EA0 #CJK UNIFIED IDEOGRAPH
+0xDFCB 0x5EC2 #CJK UNIFIED IDEOGRAPH
+0xDFCC 0x60F3 #CJK UNIFIED IDEOGRAPH
+0xDFCD 0x6851 #CJK UNIFIED IDEOGRAPH
+0xDFCE 0x6A61 #CJK UNIFIED IDEOGRAPH
+0xDFCF 0x6E58 #CJK UNIFIED IDEOGRAPH
+0xDFD0 0x723D #CJK UNIFIED IDEOGRAPH
+0xDFD1 0x7240 #CJK UNIFIED IDEOGRAPH
+0xDFD2 0x72C0 #CJK UNIFIED IDEOGRAPH
+0xDFD3 0x76F8 #CJK UNIFIED IDEOGRAPH
+0xDFD4 0x7965 #CJK UNIFIED IDEOGRAPH
+0xDFD5 0x7BB1 #CJK UNIFIED IDEOGRAPH
+0xDFD6 0x7FD4 #CJK UNIFIED IDEOGRAPH
+0xDFD7 0x88F3 #CJK UNIFIED IDEOGRAPH
+0xDFD8 0x89F4 #CJK UNIFIED IDEOGRAPH
+0xDFD9 0x8A73 #CJK UNIFIED IDEOGRAPH
+0xDFDA 0x8C61 #CJK UNIFIED IDEOGRAPH
+0xDFDB 0x8CDE #CJK UNIFIED IDEOGRAPH
+0xDFDC 0x971C #CJK UNIFIED IDEOGRAPH
+0xDFDD 0x585E #CJK UNIFIED IDEOGRAPH
+0xDFDE 0x74BD #CJK UNIFIED IDEOGRAPH
+0xDFDF 0x8CFD #CJK UNIFIED IDEOGRAPH
+0xDFE0 0x55C7 #CJK UNIFIED IDEOGRAPH
+0xDFE1 0xF96C #CJK COMPATIBILITY IDEOGRAPH
+0xDFE2 0x7A61 #CJK UNIFIED IDEOGRAPH
+0xDFE3 0x7D22 #CJK UNIFIED IDEOGRAPH
+0xDFE4 0x8272 #CJK UNIFIED IDEOGRAPH
+0xDFE5 0x7272 #CJK UNIFIED IDEOGRAPH
+0xDFE6 0x751F #CJK UNIFIED IDEOGRAPH
+0xDFE7 0x7525 #CJK UNIFIED IDEOGRAPH
+0xDFE8 0xF96D #CJK COMPATIBILITY IDEOGRAPH
+0xDFE9 0x7B19 #CJK UNIFIED IDEOGRAPH
+0xDFEA 0x5885 #CJK UNIFIED IDEOGRAPH
+0xDFEB 0x58FB #CJK UNIFIED IDEOGRAPH
+0xDFEC 0x5DBC #CJK UNIFIED IDEOGRAPH
+0xDFED 0x5E8F #CJK UNIFIED IDEOGRAPH
+0xDFEE 0x5EB6 #CJK UNIFIED IDEOGRAPH
+0xDFEF 0x5F90 #CJK UNIFIED IDEOGRAPH
+0xDFF0 0x6055 #CJK UNIFIED IDEOGRAPH
+0xDFF1 0x6292 #CJK UNIFIED IDEOGRAPH
+0xDFF2 0x637F #CJK UNIFIED IDEOGRAPH
+0xDFF3 0x654D #CJK UNIFIED IDEOGRAPH
+0xDFF4 0x6691 #CJK UNIFIED IDEOGRAPH
+0xDFF5 0x66D9 #CJK UNIFIED IDEOGRAPH
+0xDFF6 0x66F8 #CJK UNIFIED IDEOGRAPH
+0xDFF7 0x6816 #CJK UNIFIED IDEOGRAPH
+0xDFF8 0x68F2 #CJK UNIFIED IDEOGRAPH
+0xDFF9 0x7280 #CJK UNIFIED IDEOGRAPH
+0xDFFA 0x745E #CJK UNIFIED IDEOGRAPH
+0xDFFB 0x7B6E #CJK UNIFIED IDEOGRAPH
+0xDFFC 0x7D6E #CJK UNIFIED IDEOGRAPH
+0xDFFD 0x7DD6 #CJK UNIFIED IDEOGRAPH
+0xDFFE 0x7F72 #CJK UNIFIED IDEOGRAPH
+0xE0A1 0x80E5 #CJK UNIFIED IDEOGRAPH
+0xE0A2 0x8212 #CJK UNIFIED IDEOGRAPH
+0xE0A3 0x85AF #CJK UNIFIED IDEOGRAPH
+0xE0A4 0x897F #CJK UNIFIED IDEOGRAPH
+0xE0A5 0x8A93 #CJK UNIFIED IDEOGRAPH
+0xE0A6 0x901D #CJK UNIFIED IDEOGRAPH
+0xE0A7 0x92E4 #CJK UNIFIED IDEOGRAPH
+0xE0A8 0x9ECD #CJK UNIFIED IDEOGRAPH
+0xE0A9 0x9F20 #CJK UNIFIED IDEOGRAPH
+0xE0AA 0x5915 #CJK UNIFIED IDEOGRAPH
+0xE0AB 0x596D #CJK UNIFIED IDEOGRAPH
+0xE0AC 0x5E2D #CJK UNIFIED IDEOGRAPH
+0xE0AD 0x60DC #CJK UNIFIED IDEOGRAPH
+0xE0AE 0x6614 #CJK UNIFIED IDEOGRAPH
+0xE0AF 0x6673 #CJK UNIFIED IDEOGRAPH
+0xE0B0 0x6790 #CJK UNIFIED IDEOGRAPH
+0xE0B1 0x6C50 #CJK UNIFIED IDEOGRAPH
+0xE0B2 0x6DC5 #CJK UNIFIED IDEOGRAPH
+0xE0B3 0x6F5F #CJK UNIFIED IDEOGRAPH
+0xE0B4 0x77F3 #CJK UNIFIED IDEOGRAPH
+0xE0B5 0x78A9 #CJK UNIFIED IDEOGRAPH
+0xE0B6 0x84C6 #CJK UNIFIED IDEOGRAPH
+0xE0B7 0x91CB #CJK UNIFIED IDEOGRAPH
+0xE0B8 0x932B #CJK UNIFIED IDEOGRAPH
+0xE0B9 0x4ED9 #CJK UNIFIED IDEOGRAPH
+0xE0BA 0x50CA #CJK UNIFIED IDEOGRAPH
+0xE0BB 0x5148 #CJK UNIFIED IDEOGRAPH
+0xE0BC 0x5584 #CJK UNIFIED IDEOGRAPH
+0xE0BD 0x5B0B #CJK UNIFIED IDEOGRAPH
+0xE0BE 0x5BA3 #CJK UNIFIED IDEOGRAPH
+0xE0BF 0x6247 #CJK UNIFIED IDEOGRAPH
+0xE0C0 0x657E #CJK UNIFIED IDEOGRAPH
+0xE0C1 0x65CB #CJK UNIFIED IDEOGRAPH
+0xE0C2 0x6E32 #CJK UNIFIED IDEOGRAPH
+0xE0C3 0x717D #CJK UNIFIED IDEOGRAPH
+0xE0C4 0x7401 #CJK UNIFIED IDEOGRAPH
+0xE0C5 0x7444 #CJK UNIFIED IDEOGRAPH
+0xE0C6 0x7487 #CJK UNIFIED IDEOGRAPH
+0xE0C7 0x74BF #CJK UNIFIED IDEOGRAPH
+0xE0C8 0x766C #CJK UNIFIED IDEOGRAPH
+0xE0C9 0x79AA #CJK UNIFIED IDEOGRAPH
+0xE0CA 0x7DDA #CJK UNIFIED IDEOGRAPH
+0xE0CB 0x7E55 #CJK UNIFIED IDEOGRAPH
+0xE0CC 0x7FA8 #CJK UNIFIED IDEOGRAPH
+0xE0CD 0x817A #CJK UNIFIED IDEOGRAPH
+0xE0CE 0x81B3 #CJK UNIFIED IDEOGRAPH
+0xE0CF 0x8239 #CJK UNIFIED IDEOGRAPH
+0xE0D0 0x861A #CJK UNIFIED IDEOGRAPH
+0xE0D1 0x87EC #CJK UNIFIED IDEOGRAPH
+0xE0D2 0x8A75 #CJK UNIFIED IDEOGRAPH
+0xE0D3 0x8DE3 #CJK UNIFIED IDEOGRAPH
+0xE0D4 0x9078 #CJK UNIFIED IDEOGRAPH
+0xE0D5 0x9291 #CJK UNIFIED IDEOGRAPH
+0xE0D6 0x9425 #CJK UNIFIED IDEOGRAPH
+0xE0D7 0x994D #CJK UNIFIED IDEOGRAPH
+0xE0D8 0x9BAE #CJK UNIFIED IDEOGRAPH
+0xE0D9 0x5368 #CJK UNIFIED IDEOGRAPH
+0xE0DA 0x5C51 #CJK UNIFIED IDEOGRAPH
+0xE0DB 0x6954 #CJK UNIFIED IDEOGRAPH
+0xE0DC 0x6CC4 #CJK UNIFIED IDEOGRAPH
+0xE0DD 0x6D29 #CJK UNIFIED IDEOGRAPH
+0xE0DE 0x6E2B #CJK UNIFIED IDEOGRAPH
+0xE0DF 0x820C #CJK UNIFIED IDEOGRAPH
+0xE0E0 0x859B #CJK UNIFIED IDEOGRAPH
+0xE0E1 0x893B #CJK UNIFIED IDEOGRAPH
+0xE0E2 0x8A2D #CJK UNIFIED IDEOGRAPH
+0xE0E3 0x8AAA #CJK UNIFIED IDEOGRAPH
+0xE0E4 0x96EA #CJK UNIFIED IDEOGRAPH
+0xE0E5 0x9F67 #CJK UNIFIED IDEOGRAPH
+0xE0E6 0x5261 #CJK UNIFIED IDEOGRAPH
+0xE0E7 0x66B9 #CJK UNIFIED IDEOGRAPH
+0xE0E8 0x6BB2 #CJK UNIFIED IDEOGRAPH
+0xE0E9 0x7E96 #CJK UNIFIED IDEOGRAPH
+0xE0EA 0x87FE #CJK UNIFIED IDEOGRAPH
+0xE0EB 0x8D0D #CJK UNIFIED IDEOGRAPH
+0xE0EC 0x9583 #CJK UNIFIED IDEOGRAPH
+0xE0ED 0x965D #CJK UNIFIED IDEOGRAPH
+0xE0EE 0x651D #CJK UNIFIED IDEOGRAPH
+0xE0EF 0x6D89 #CJK UNIFIED IDEOGRAPH
+0xE0F0 0x71EE #CJK UNIFIED IDEOGRAPH
+0xE0F1 0xF96E #CJK COMPATIBILITY IDEOGRAPH
+0xE0F2 0x57CE #CJK UNIFIED IDEOGRAPH
+0xE0F3 0x59D3 #CJK UNIFIED IDEOGRAPH
+0xE0F4 0x5BAC #CJK UNIFIED IDEOGRAPH
+0xE0F5 0x6027 #CJK UNIFIED IDEOGRAPH
+0xE0F6 0x60FA #CJK UNIFIED IDEOGRAPH
+0xE0F7 0x6210 #CJK UNIFIED IDEOGRAPH
+0xE0F8 0x661F #CJK UNIFIED IDEOGRAPH
+0xE0F9 0x665F #CJK UNIFIED IDEOGRAPH
+0xE0FA 0x7329 #CJK UNIFIED IDEOGRAPH
+0xE0FB 0x73F9 #CJK UNIFIED IDEOGRAPH
+0xE0FC 0x76DB #CJK UNIFIED IDEOGRAPH
+0xE0FD 0x7701 #CJK UNIFIED IDEOGRAPH
+0xE0FE 0x7B6C #CJK UNIFIED IDEOGRAPH
+0xE1A1 0x8056 #CJK UNIFIED IDEOGRAPH
+0xE1A2 0x8072 #CJK UNIFIED IDEOGRAPH
+0xE1A3 0x8165 #CJK UNIFIED IDEOGRAPH
+0xE1A4 0x8AA0 #CJK UNIFIED IDEOGRAPH
+0xE1A5 0x9192 #CJK UNIFIED IDEOGRAPH
+0xE1A6 0x4E16 #CJK UNIFIED IDEOGRAPH
+0xE1A7 0x52E2 #CJK UNIFIED IDEOGRAPH
+0xE1A8 0x6B72 #CJK UNIFIED IDEOGRAPH
+0xE1A9 0x6D17 #CJK UNIFIED IDEOGRAPH
+0xE1AA 0x7A05 #CJK UNIFIED IDEOGRAPH
+0xE1AB 0x7B39 #CJK UNIFIED IDEOGRAPH
+0xE1AC 0x7D30 #CJK UNIFIED IDEOGRAPH
+0xE1AD 0xF96F #CJK COMPATIBILITY IDEOGRAPH
+0xE1AE 0x8CB0 #CJK UNIFIED IDEOGRAPH
+0xE1AF 0x53EC #CJK UNIFIED IDEOGRAPH
+0xE1B0 0x562F #CJK UNIFIED IDEOGRAPH
+0xE1B1 0x5851 #CJK UNIFIED IDEOGRAPH
+0xE1B2 0x5BB5 #CJK UNIFIED IDEOGRAPH
+0xE1B3 0x5C0F #CJK UNIFIED IDEOGRAPH
+0xE1B4 0x5C11 #CJK UNIFIED IDEOGRAPH
+0xE1B5 0x5DE2 #CJK UNIFIED IDEOGRAPH
+0xE1B6 0x6240 #CJK UNIFIED IDEOGRAPH
+0xE1B7 0x6383 #CJK UNIFIED IDEOGRAPH
+0xE1B8 0x6414 #CJK UNIFIED IDEOGRAPH
+0xE1B9 0x662D #CJK UNIFIED IDEOGRAPH
+0xE1BA 0x68B3 #CJK UNIFIED IDEOGRAPH
+0xE1BB 0x6CBC #CJK UNIFIED IDEOGRAPH
+0xE1BC 0x6D88 #CJK UNIFIED IDEOGRAPH
+0xE1BD 0x6EAF #CJK UNIFIED IDEOGRAPH
+0xE1BE 0x701F #CJK UNIFIED IDEOGRAPH
+0xE1BF 0x70A4 #CJK UNIFIED IDEOGRAPH
+0xE1C0 0x71D2 #CJK UNIFIED IDEOGRAPH
+0xE1C1 0x7526 #CJK UNIFIED IDEOGRAPH
+0xE1C2 0x758F #CJK UNIFIED IDEOGRAPH
+0xE1C3 0x758E #CJK UNIFIED IDEOGRAPH
+0xE1C4 0x7619 #CJK UNIFIED IDEOGRAPH
+0xE1C5 0x7B11 #CJK UNIFIED IDEOGRAPH
+0xE1C6 0x7BE0 #CJK UNIFIED IDEOGRAPH
+0xE1C7 0x7C2B #CJK UNIFIED IDEOGRAPH
+0xE1C8 0x7D20 #CJK UNIFIED IDEOGRAPH
+0xE1C9 0x7D39 #CJK UNIFIED IDEOGRAPH
+0xE1CA 0x852C #CJK UNIFIED IDEOGRAPH
+0xE1CB 0x856D #CJK UNIFIED IDEOGRAPH
+0xE1CC 0x8607 #CJK UNIFIED IDEOGRAPH
+0xE1CD 0x8A34 #CJK UNIFIED IDEOGRAPH
+0xE1CE 0x900D #CJK UNIFIED IDEOGRAPH
+0xE1CF 0x9061 #CJK UNIFIED IDEOGRAPH
+0xE1D0 0x90B5 #CJK UNIFIED IDEOGRAPH
+0xE1D1 0x92B7 #CJK UNIFIED IDEOGRAPH
+0xE1D2 0x97F6 #CJK UNIFIED IDEOGRAPH
+0xE1D3 0x9A37 #CJK UNIFIED IDEOGRAPH
+0xE1D4 0x4FD7 #CJK UNIFIED IDEOGRAPH
+0xE1D5 0x5C6C #CJK UNIFIED IDEOGRAPH
+0xE1D6 0x675F #CJK UNIFIED IDEOGRAPH
+0xE1D7 0x6D91 #CJK UNIFIED IDEOGRAPH
+0xE1D8 0x7C9F #CJK UNIFIED IDEOGRAPH
+0xE1D9 0x7E8C #CJK UNIFIED IDEOGRAPH
+0xE1DA 0x8B16 #CJK UNIFIED IDEOGRAPH
+0xE1DB 0x8D16 #CJK UNIFIED IDEOGRAPH
+0xE1DC 0x901F #CJK UNIFIED IDEOGRAPH
+0xE1DD 0x5B6B #CJK UNIFIED IDEOGRAPH
+0xE1DE 0x5DFD #CJK UNIFIED IDEOGRAPH
+0xE1DF 0x640D #CJK UNIFIED IDEOGRAPH
+0xE1E0 0x84C0 #CJK UNIFIED IDEOGRAPH
+0xE1E1 0x905C #CJK UNIFIED IDEOGRAPH
+0xE1E2 0x98E1 #CJK UNIFIED IDEOGRAPH
+0xE1E3 0x7387 #CJK UNIFIED IDEOGRAPH
+0xE1E4 0x5B8B #CJK UNIFIED IDEOGRAPH
+0xE1E5 0x609A #CJK UNIFIED IDEOGRAPH
+0xE1E6 0x677E #CJK UNIFIED IDEOGRAPH
+0xE1E7 0x6DDE #CJK UNIFIED IDEOGRAPH
+0xE1E8 0x8A1F #CJK UNIFIED IDEOGRAPH
+0xE1E9 0x8AA6 #CJK UNIFIED IDEOGRAPH
+0xE1EA 0x9001 #CJK UNIFIED IDEOGRAPH
+0xE1EB 0x980C #CJK UNIFIED IDEOGRAPH
+0xE1EC 0x5237 #CJK UNIFIED IDEOGRAPH
+0xE1ED 0xF970 #CJK COMPATIBILITY IDEOGRAPH
+0xE1EE 0x7051 #CJK UNIFIED IDEOGRAPH
+0xE1EF 0x788E #CJK UNIFIED IDEOGRAPH
+0xE1F0 0x9396 #CJK UNIFIED IDEOGRAPH
+0xE1F1 0x8870 #CJK UNIFIED IDEOGRAPH
+0xE1F2 0x91D7 #CJK UNIFIED IDEOGRAPH
+0xE1F3 0x4FEE #CJK UNIFIED IDEOGRAPH
+0xE1F4 0x53D7 #CJK UNIFIED IDEOGRAPH
+0xE1F5 0x55FD #CJK UNIFIED IDEOGRAPH
+0xE1F6 0x56DA #CJK UNIFIED IDEOGRAPH
+0xE1F7 0x5782 #CJK UNIFIED IDEOGRAPH
+0xE1F8 0x58FD #CJK UNIFIED IDEOGRAPH
+0xE1F9 0x5AC2 #CJK UNIFIED IDEOGRAPH
+0xE1FA 0x5B88 #CJK UNIFIED IDEOGRAPH
+0xE1FB 0x5CAB #CJK UNIFIED IDEOGRAPH
+0xE1FC 0x5CC0 #CJK UNIFIED IDEOGRAPH
+0xE1FD 0x5E25 #CJK UNIFIED IDEOGRAPH
+0xE1FE 0x6101 #CJK UNIFIED IDEOGRAPH
+0xE2A1 0x620D #CJK UNIFIED IDEOGRAPH
+0xE2A2 0x624B #CJK UNIFIED IDEOGRAPH
+0xE2A3 0x6388 #CJK UNIFIED IDEOGRAPH
+0xE2A4 0x641C #CJK UNIFIED IDEOGRAPH
+0xE2A5 0x6536 #CJK UNIFIED IDEOGRAPH
+0xE2A6 0x6578 #CJK UNIFIED IDEOGRAPH
+0xE2A7 0x6A39 #CJK UNIFIED IDEOGRAPH
+0xE2A8 0x6B8A #CJK UNIFIED IDEOGRAPH
+0xE2A9 0x6C34 #CJK UNIFIED IDEOGRAPH
+0xE2AA 0x6D19 #CJK UNIFIED IDEOGRAPH
+0xE2AB 0x6F31 #CJK UNIFIED IDEOGRAPH
+0xE2AC 0x71E7 #CJK UNIFIED IDEOGRAPH
+0xE2AD 0x72E9 #CJK UNIFIED IDEOGRAPH
+0xE2AE 0x7378 #CJK UNIFIED IDEOGRAPH
+0xE2AF 0x7407 #CJK UNIFIED IDEOGRAPH
+0xE2B0 0x74B2 #CJK UNIFIED IDEOGRAPH
+0xE2B1 0x7626 #CJK UNIFIED IDEOGRAPH
+0xE2B2 0x7761 #CJK UNIFIED IDEOGRAPH
+0xE2B3 0x79C0 #CJK UNIFIED IDEOGRAPH
+0xE2B4 0x7A57 #CJK UNIFIED IDEOGRAPH
+0xE2B5 0x7AEA #CJK UNIFIED IDEOGRAPH
+0xE2B6 0x7CB9 #CJK UNIFIED IDEOGRAPH
+0xE2B7 0x7D8F #CJK UNIFIED IDEOGRAPH
+0xE2B8 0x7DAC #CJK UNIFIED IDEOGRAPH
+0xE2B9 0x7E61 #CJK UNIFIED IDEOGRAPH
+0xE2BA 0x7F9E #CJK UNIFIED IDEOGRAPH
+0xE2BB 0x8129 #CJK UNIFIED IDEOGRAPH
+0xE2BC 0x8331 #CJK UNIFIED IDEOGRAPH
+0xE2BD 0x8490 #CJK UNIFIED IDEOGRAPH
+0xE2BE 0x84DA #CJK UNIFIED IDEOGRAPH
+0xE2BF 0x85EA #CJK UNIFIED IDEOGRAPH
+0xE2C0 0x8896 #CJK UNIFIED IDEOGRAPH
+0xE2C1 0x8AB0 #CJK UNIFIED IDEOGRAPH
+0xE2C2 0x8B90 #CJK UNIFIED IDEOGRAPH
+0xE2C3 0x8F38 #CJK UNIFIED IDEOGRAPH
+0xE2C4 0x9042 #CJK UNIFIED IDEOGRAPH
+0xE2C5 0x9083 #CJK UNIFIED IDEOGRAPH
+0xE2C6 0x916C #CJK UNIFIED IDEOGRAPH
+0xE2C7 0x9296 #CJK UNIFIED IDEOGRAPH
+0xE2C8 0x92B9 #CJK UNIFIED IDEOGRAPH
+0xE2C9 0x968B #CJK UNIFIED IDEOGRAPH
+0xE2CA 0x96A7 #CJK UNIFIED IDEOGRAPH
+0xE2CB 0x96A8 #CJK UNIFIED IDEOGRAPH
+0xE2CC 0x96D6 #CJK UNIFIED IDEOGRAPH
+0xE2CD 0x9700 #CJK UNIFIED IDEOGRAPH
+0xE2CE 0x9808 #CJK UNIFIED IDEOGRAPH
+0xE2CF 0x9996 #CJK UNIFIED IDEOGRAPH
+0xE2D0 0x9AD3 #CJK UNIFIED IDEOGRAPH
+0xE2D1 0x9B1A #CJK UNIFIED IDEOGRAPH
+0xE2D2 0x53D4 #CJK UNIFIED IDEOGRAPH
+0xE2D3 0x587E #CJK UNIFIED IDEOGRAPH
+0xE2D4 0x5919 #CJK UNIFIED IDEOGRAPH
+0xE2D5 0x5B70 #CJK UNIFIED IDEOGRAPH
+0xE2D6 0x5BBF #CJK UNIFIED IDEOGRAPH
+0xE2D7 0x6DD1 #CJK UNIFIED IDEOGRAPH
+0xE2D8 0x6F5A #CJK UNIFIED IDEOGRAPH
+0xE2D9 0x719F #CJK UNIFIED IDEOGRAPH
+0xE2DA 0x7421 #CJK UNIFIED IDEOGRAPH
+0xE2DB 0x74B9 #CJK UNIFIED IDEOGRAPH
+0xE2DC 0x8085 #CJK UNIFIED IDEOGRAPH
+0xE2DD 0x83FD #CJK UNIFIED IDEOGRAPH
+0xE2DE 0x5DE1 #CJK UNIFIED IDEOGRAPH
+0xE2DF 0x5F87 #CJK UNIFIED IDEOGRAPH
+0xE2E0 0x5FAA #CJK UNIFIED IDEOGRAPH
+0xE2E1 0x6042 #CJK UNIFIED IDEOGRAPH
+0xE2E2 0x65EC #CJK UNIFIED IDEOGRAPH
+0xE2E3 0x6812 #CJK UNIFIED IDEOGRAPH
+0xE2E4 0x696F #CJK UNIFIED IDEOGRAPH
+0xE2E5 0x6A53 #CJK UNIFIED IDEOGRAPH
+0xE2E6 0x6B89 #CJK UNIFIED IDEOGRAPH
+0xE2E7 0x6D35 #CJK UNIFIED IDEOGRAPH
+0xE2E8 0x6DF3 #CJK UNIFIED IDEOGRAPH
+0xE2E9 0x73E3 #CJK UNIFIED IDEOGRAPH
+0xE2EA 0x76FE #CJK UNIFIED IDEOGRAPH
+0xE2EB 0x77AC #CJK UNIFIED IDEOGRAPH
+0xE2EC 0x7B4D #CJK UNIFIED IDEOGRAPH
+0xE2ED 0x7D14 #CJK UNIFIED IDEOGRAPH
+0xE2EE 0x8123 #CJK UNIFIED IDEOGRAPH
+0xE2EF 0x821C #CJK UNIFIED IDEOGRAPH
+0xE2F0 0x8340 #CJK UNIFIED IDEOGRAPH
+0xE2F1 0x84F4 #CJK UNIFIED IDEOGRAPH
+0xE2F2 0x8563 #CJK UNIFIED IDEOGRAPH
+0xE2F3 0x8A62 #CJK UNIFIED IDEOGRAPH
+0xE2F4 0x8AC4 #CJK UNIFIED IDEOGRAPH
+0xE2F5 0x9187 #CJK UNIFIED IDEOGRAPH
+0xE2F6 0x931E #CJK UNIFIED IDEOGRAPH
+0xE2F7 0x9806 #CJK UNIFIED IDEOGRAPH
+0xE2F8 0x99B4 #CJK UNIFIED IDEOGRAPH
+0xE2F9 0x620C #CJK UNIFIED IDEOGRAPH
+0xE2FA 0x8853 #CJK UNIFIED IDEOGRAPH
+0xE2FB 0x8FF0 #CJK UNIFIED IDEOGRAPH
+0xE2FC 0x9265 #CJK UNIFIED IDEOGRAPH
+0xE2FD 0x5D07 #CJK UNIFIED IDEOGRAPH
+0xE2FE 0x5D27 #CJK UNIFIED IDEOGRAPH
+0xE3A1 0x5D69 #CJK UNIFIED IDEOGRAPH
+0xE3A2 0x745F #CJK UNIFIED IDEOGRAPH
+0xE3A3 0x819D #CJK UNIFIED IDEOGRAPH
+0xE3A4 0x8768 #CJK UNIFIED IDEOGRAPH
+0xE3A5 0x6FD5 #CJK UNIFIED IDEOGRAPH
+0xE3A6 0x62FE #CJK UNIFIED IDEOGRAPH
+0xE3A7 0x7FD2 #CJK UNIFIED IDEOGRAPH
+0xE3A8 0x8936 #CJK UNIFIED IDEOGRAPH
+0xE3A9 0x8972 #CJK UNIFIED IDEOGRAPH
+0xE3AA 0x4E1E #CJK UNIFIED IDEOGRAPH
+0xE3AB 0x4E58 #CJK UNIFIED IDEOGRAPH
+0xE3AC 0x50E7 #CJK UNIFIED IDEOGRAPH
+0xE3AD 0x52DD #CJK UNIFIED IDEOGRAPH
+0xE3AE 0x5347 #CJK UNIFIED IDEOGRAPH
+0xE3AF 0x627F #CJK UNIFIED IDEOGRAPH
+0xE3B0 0x6607 #CJK UNIFIED IDEOGRAPH
+0xE3B1 0x7E69 #CJK UNIFIED IDEOGRAPH
+0xE3B2 0x8805 #CJK UNIFIED IDEOGRAPH
+0xE3B3 0x965E #CJK UNIFIED IDEOGRAPH
+0xE3B4 0x4F8D #CJK UNIFIED IDEOGRAPH
+0xE3B5 0x5319 #CJK UNIFIED IDEOGRAPH
+0xE3B6 0x5636 #CJK UNIFIED IDEOGRAPH
+0xE3B7 0x59CB #CJK UNIFIED IDEOGRAPH
+0xE3B8 0x5AA4 #CJK UNIFIED IDEOGRAPH
+0xE3B9 0x5C38 #CJK UNIFIED IDEOGRAPH
+0xE3BA 0x5C4E #CJK UNIFIED IDEOGRAPH
+0xE3BB 0x5C4D #CJK UNIFIED IDEOGRAPH
+0xE3BC 0x5E02 #CJK UNIFIED IDEOGRAPH
+0xE3BD 0x5F11 #CJK UNIFIED IDEOGRAPH
+0xE3BE 0x6043 #CJK UNIFIED IDEOGRAPH
+0xE3BF 0x65BD #CJK UNIFIED IDEOGRAPH
+0xE3C0 0x662F #CJK UNIFIED IDEOGRAPH
+0xE3C1 0x6642 #CJK UNIFIED IDEOGRAPH
+0xE3C2 0x67BE #CJK UNIFIED IDEOGRAPH
+0xE3C3 0x67F4 #CJK UNIFIED IDEOGRAPH
+0xE3C4 0x731C #CJK UNIFIED IDEOGRAPH
+0xE3C5 0x77E2 #CJK UNIFIED IDEOGRAPH
+0xE3C6 0x793A #CJK UNIFIED IDEOGRAPH
+0xE3C7 0x7FC5 #CJK UNIFIED IDEOGRAPH
+0xE3C8 0x8494 #CJK UNIFIED IDEOGRAPH
+0xE3C9 0x84CD #CJK UNIFIED IDEOGRAPH
+0xE3CA 0x8996 #CJK UNIFIED IDEOGRAPH
+0xE3CB 0x8A66 #CJK UNIFIED IDEOGRAPH
+0xE3CC 0x8A69 #CJK UNIFIED IDEOGRAPH
+0xE3CD 0x8AE1 #CJK UNIFIED IDEOGRAPH
+0xE3CE 0x8C55 #CJK UNIFIED IDEOGRAPH
+0xE3CF 0x8C7A #CJK UNIFIED IDEOGRAPH
+0xE3D0 0x57F4 #CJK UNIFIED IDEOGRAPH
+0xE3D1 0x5BD4 #CJK UNIFIED IDEOGRAPH
+0xE3D2 0x5F0F #CJK UNIFIED IDEOGRAPH
+0xE3D3 0x606F #CJK UNIFIED IDEOGRAPH
+0xE3D4 0x62ED #CJK UNIFIED IDEOGRAPH
+0xE3D5 0x690D #CJK UNIFIED IDEOGRAPH
+0xE3D6 0x6B96 #CJK UNIFIED IDEOGRAPH
+0xE3D7 0x6E5C #CJK UNIFIED IDEOGRAPH
+0xE3D8 0x7184 #CJK UNIFIED IDEOGRAPH
+0xE3D9 0x7BD2 #CJK UNIFIED IDEOGRAPH
+0xE3DA 0x8755 #CJK UNIFIED IDEOGRAPH
+0xE3DB 0x8B58 #CJK UNIFIED IDEOGRAPH
+0xE3DC 0x8EFE #CJK UNIFIED IDEOGRAPH
+0xE3DD 0x98DF #CJK UNIFIED IDEOGRAPH
+0xE3DE 0x98FE #CJK UNIFIED IDEOGRAPH
+0xE3DF 0x4F38 #CJK UNIFIED IDEOGRAPH
+0xE3E0 0x4F81 #CJK UNIFIED IDEOGRAPH
+0xE3E1 0x4FE1 #CJK UNIFIED IDEOGRAPH
+0xE3E2 0x547B #CJK UNIFIED IDEOGRAPH
+0xE3E3 0x5A20 #CJK UNIFIED IDEOGRAPH
+0xE3E4 0x5BB8 #CJK UNIFIED IDEOGRAPH
+0xE3E5 0x613C #CJK UNIFIED IDEOGRAPH
+0xE3E6 0x65B0 #CJK UNIFIED IDEOGRAPH
+0xE3E7 0x6668 #CJK UNIFIED IDEOGRAPH
+0xE3E8 0x71FC #CJK UNIFIED IDEOGRAPH
+0xE3E9 0x7533 #CJK UNIFIED IDEOGRAPH
+0xE3EA 0x795E #CJK UNIFIED IDEOGRAPH
+0xE3EB 0x7D33 #CJK UNIFIED IDEOGRAPH
+0xE3EC 0x814E #CJK UNIFIED IDEOGRAPH
+0xE3ED 0x81E3 #CJK UNIFIED IDEOGRAPH
+0xE3EE 0x8398 #CJK UNIFIED IDEOGRAPH
+0xE3EF 0x85AA #CJK UNIFIED IDEOGRAPH
+0xE3F0 0x85CE #CJK UNIFIED IDEOGRAPH
+0xE3F1 0x8703 #CJK UNIFIED IDEOGRAPH
+0xE3F2 0x8A0A #CJK UNIFIED IDEOGRAPH
+0xE3F3 0x8EAB #CJK UNIFIED IDEOGRAPH
+0xE3F4 0x8F9B #CJK UNIFIED IDEOGRAPH
+0xE3F5 0xF971 #CJK COMPATIBILITY IDEOGRAPH
+0xE3F6 0x8FC5 #CJK UNIFIED IDEOGRAPH
+0xE3F7 0x5931 #CJK UNIFIED IDEOGRAPH
+0xE3F8 0x5BA4 #CJK UNIFIED IDEOGRAPH
+0xE3F9 0x5BE6 #CJK UNIFIED IDEOGRAPH
+0xE3FA 0x6089 #CJK UNIFIED IDEOGRAPH
+0xE3FB 0x5BE9 #CJK UNIFIED IDEOGRAPH
+0xE3FC 0x5C0B #CJK UNIFIED IDEOGRAPH
+0xE3FD 0x5FC3 #CJK UNIFIED IDEOGRAPH
+0xE3FE 0x6C81 #CJK UNIFIED IDEOGRAPH
+0xE4A1 0xF972 #CJK COMPATIBILITY IDEOGRAPH
+0xE4A2 0x6DF1 #CJK UNIFIED IDEOGRAPH
+0xE4A3 0x700B #CJK UNIFIED IDEOGRAPH
+0xE4A4 0x751A #CJK UNIFIED IDEOGRAPH
+0xE4A5 0x82AF #CJK UNIFIED IDEOGRAPH
+0xE4A6 0x8AF6 #CJK UNIFIED IDEOGRAPH
+0xE4A7 0x4EC0 #CJK UNIFIED IDEOGRAPH
+0xE4A8 0x5341 #CJK UNIFIED IDEOGRAPH
+0xE4A9 0xF973 #CJK COMPATIBILITY IDEOGRAPH
+0xE4AA 0x96D9 #CJK UNIFIED IDEOGRAPH
+0xE4AB 0x6C0F #CJK UNIFIED IDEOGRAPH
+0xE4AC 0x4E9E #CJK UNIFIED IDEOGRAPH
+0xE4AD 0x4FC4 #CJK UNIFIED IDEOGRAPH
+0xE4AE 0x5152 #CJK UNIFIED IDEOGRAPH
+0xE4AF 0x555E #CJK UNIFIED IDEOGRAPH
+0xE4B0 0x5A25 #CJK UNIFIED IDEOGRAPH
+0xE4B1 0x5CE8 #CJK UNIFIED IDEOGRAPH
+0xE4B2 0x6211 #CJK UNIFIED IDEOGRAPH
+0xE4B3 0x7259 #CJK UNIFIED IDEOGRAPH
+0xE4B4 0x82BD #CJK UNIFIED IDEOGRAPH
+0xE4B5 0x83AA #CJK UNIFIED IDEOGRAPH
+0xE4B6 0x86FE #CJK UNIFIED IDEOGRAPH
+0xE4B7 0x8859 #CJK UNIFIED IDEOGRAPH
+0xE4B8 0x8A1D #CJK UNIFIED IDEOGRAPH
+0xE4B9 0x963F #CJK UNIFIED IDEOGRAPH
+0xE4BA 0x96C5 #CJK UNIFIED IDEOGRAPH
+0xE4BB 0x9913 #CJK UNIFIED IDEOGRAPH
+0xE4BC 0x9D09 #CJK UNIFIED IDEOGRAPH
+0xE4BD 0x9D5D #CJK UNIFIED IDEOGRAPH
+0xE4BE 0x580A #CJK UNIFIED IDEOGRAPH
+0xE4BF 0x5CB3 #CJK UNIFIED IDEOGRAPH
+0xE4C0 0x5DBD #CJK UNIFIED IDEOGRAPH
+0xE4C1 0x5E44 #CJK UNIFIED IDEOGRAPH
+0xE4C2 0x60E1 #CJK UNIFIED IDEOGRAPH
+0xE4C3 0x6115 #CJK UNIFIED IDEOGRAPH
+0xE4C4 0x63E1 #CJK UNIFIED IDEOGRAPH
+0xE4C5 0x6A02 #CJK UNIFIED IDEOGRAPH
+0xE4C6 0x6E25 #CJK UNIFIED IDEOGRAPH
+0xE4C7 0x9102 #CJK UNIFIED IDEOGRAPH
+0xE4C8 0x9354 #CJK UNIFIED IDEOGRAPH
+0xE4C9 0x984E #CJK UNIFIED IDEOGRAPH
+0xE4CA 0x9C10 #CJK UNIFIED IDEOGRAPH
+0xE4CB 0x9F77 #CJK UNIFIED IDEOGRAPH
+0xE4CC 0x5B89 #CJK UNIFIED IDEOGRAPH
+0xE4CD 0x5CB8 #CJK UNIFIED IDEOGRAPH
+0xE4CE 0x6309 #CJK UNIFIED IDEOGRAPH
+0xE4CF 0x664F #CJK UNIFIED IDEOGRAPH
+0xE4D0 0x6848 #CJK UNIFIED IDEOGRAPH
+0xE4D1 0x773C #CJK UNIFIED IDEOGRAPH
+0xE4D2 0x96C1 #CJK UNIFIED IDEOGRAPH
+0xE4D3 0x978D #CJK UNIFIED IDEOGRAPH
+0xE4D4 0x9854 #CJK UNIFIED IDEOGRAPH
+0xE4D5 0x9B9F #CJK UNIFIED IDEOGRAPH
+0xE4D6 0x65A1 #CJK UNIFIED IDEOGRAPH
+0xE4D7 0x8B01 #CJK UNIFIED IDEOGRAPH
+0xE4D8 0x8ECB #CJK UNIFIED IDEOGRAPH
+0xE4D9 0x95BC #CJK UNIFIED IDEOGRAPH
+0xE4DA 0x5535 #CJK UNIFIED IDEOGRAPH
+0xE4DB 0x5CA9 #CJK UNIFIED IDEOGRAPH
+0xE4DC 0x5DD6 #CJK UNIFIED IDEOGRAPH
+0xE4DD 0x5EB5 #CJK UNIFIED IDEOGRAPH
+0xE4DE 0x6697 #CJK UNIFIED IDEOGRAPH
+0xE4DF 0x764C #CJK UNIFIED IDEOGRAPH
+0xE4E0 0x83F4 #CJK UNIFIED IDEOGRAPH
+0xE4E1 0x95C7 #CJK UNIFIED IDEOGRAPH
+0xE4E2 0x58D3 #CJK UNIFIED IDEOGRAPH
+0xE4E3 0x62BC #CJK UNIFIED IDEOGRAPH
+0xE4E4 0x72CE #CJK UNIFIED IDEOGRAPH
+0xE4E5 0x9D28 #CJK UNIFIED IDEOGRAPH
+0xE4E6 0x4EF0 #CJK UNIFIED IDEOGRAPH
+0xE4E7 0x592E #CJK UNIFIED IDEOGRAPH
+0xE4E8 0x600F #CJK UNIFIED IDEOGRAPH
+0xE4E9 0x663B #CJK UNIFIED IDEOGRAPH
+0xE4EA 0x6B83 #CJK UNIFIED IDEOGRAPH
+0xE4EB 0x79E7 #CJK UNIFIED IDEOGRAPH
+0xE4EC 0x9D26 #CJK UNIFIED IDEOGRAPH
+0xE4ED 0x5393 #CJK UNIFIED IDEOGRAPH
+0xE4EE 0x54C0 #CJK UNIFIED IDEOGRAPH
+0xE4EF 0x57C3 #CJK UNIFIED IDEOGRAPH
+0xE4F0 0x5D16 #CJK UNIFIED IDEOGRAPH
+0xE4F1 0x611B #CJK UNIFIED IDEOGRAPH
+0xE4F2 0x66D6 #CJK UNIFIED IDEOGRAPH
+0xE4F3 0x6DAF #CJK UNIFIED IDEOGRAPH
+0xE4F4 0x788D #CJK UNIFIED IDEOGRAPH
+0xE4F5 0x827E #CJK UNIFIED IDEOGRAPH
+0xE4F6 0x9698 #CJK UNIFIED IDEOGRAPH
+0xE4F7 0x9744 #CJK UNIFIED IDEOGRAPH
+0xE4F8 0x5384 #CJK UNIFIED IDEOGRAPH
+0xE4F9 0x627C #CJK UNIFIED IDEOGRAPH
+0xE4FA 0x6396 #CJK UNIFIED IDEOGRAPH
+0xE4FB 0x6DB2 #CJK UNIFIED IDEOGRAPH
+0xE4FC 0x7E0A #CJK UNIFIED IDEOGRAPH
+0xE4FD 0x814B #CJK UNIFIED IDEOGRAPH
+0xE4FE 0x984D #CJK UNIFIED IDEOGRAPH
+0xE5A1 0x6AFB #CJK UNIFIED IDEOGRAPH
+0xE5A2 0x7F4C #CJK UNIFIED IDEOGRAPH
+0xE5A3 0x9DAF #CJK UNIFIED IDEOGRAPH
+0xE5A4 0x9E1A #CJK UNIFIED IDEOGRAPH
+0xE5A5 0x4E5F #CJK UNIFIED IDEOGRAPH
+0xE5A6 0x503B #CJK UNIFIED IDEOGRAPH
+0xE5A7 0x51B6 #CJK UNIFIED IDEOGRAPH
+0xE5A8 0x591C #CJK UNIFIED IDEOGRAPH
+0xE5A9 0x60F9 #CJK UNIFIED IDEOGRAPH
+0xE5AA 0x63F6 #CJK UNIFIED IDEOGRAPH
+0xE5AB 0x6930 #CJK UNIFIED IDEOGRAPH
+0xE5AC 0x723A #CJK UNIFIED IDEOGRAPH
+0xE5AD 0x8036 #CJK UNIFIED IDEOGRAPH
+0xE5AE 0xF974 #CJK COMPATIBILITY IDEOGRAPH
+0xE5AF 0x91CE #CJK UNIFIED IDEOGRAPH
+0xE5B0 0x5F31 #CJK UNIFIED IDEOGRAPH
+0xE5B1 0xF975 #CJK COMPATIBILITY IDEOGRAPH
+0xE5B2 0xF976 #CJK COMPATIBILITY IDEOGRAPH
+0xE5B3 0x7D04 #CJK UNIFIED IDEOGRAPH
+0xE5B4 0x82E5 #CJK UNIFIED IDEOGRAPH
+0xE5B5 0x846F #CJK UNIFIED IDEOGRAPH
+0xE5B6 0x84BB #CJK UNIFIED IDEOGRAPH
+0xE5B7 0x85E5 #CJK UNIFIED IDEOGRAPH
+0xE5B8 0x8E8D #CJK UNIFIED IDEOGRAPH
+0xE5B9 0xF977 #CJK COMPATIBILITY IDEOGRAPH
+0xE5BA 0x4F6F #CJK UNIFIED IDEOGRAPH
+0xE5BB 0xF978 #CJK COMPATIBILITY IDEOGRAPH
+0xE5BC 0xF979 #CJK COMPATIBILITY IDEOGRAPH
+0xE5BD 0x58E4 #CJK UNIFIED IDEOGRAPH
+0xE5BE 0x5B43 #CJK UNIFIED IDEOGRAPH
+0xE5BF 0x6059 #CJK UNIFIED IDEOGRAPH
+0xE5C0 0x63DA #CJK UNIFIED IDEOGRAPH
+0xE5C1 0x6518 #CJK UNIFIED IDEOGRAPH
+0xE5C2 0x656D #CJK UNIFIED IDEOGRAPH
+0xE5C3 0x6698 #CJK UNIFIED IDEOGRAPH
+0xE5C4 0xF97A #CJK COMPATIBILITY IDEOGRAPH
+0xE5C5 0x694A #CJK UNIFIED IDEOGRAPH
+0xE5C6 0x6A23 #CJK UNIFIED IDEOGRAPH
+0xE5C7 0x6D0B #CJK UNIFIED IDEOGRAPH
+0xE5C8 0x7001 #CJK UNIFIED IDEOGRAPH
+0xE5C9 0x716C #CJK UNIFIED IDEOGRAPH
+0xE5CA 0x75D2 #CJK UNIFIED IDEOGRAPH
+0xE5CB 0x760D #CJK UNIFIED IDEOGRAPH
+0xE5CC 0x79B3 #CJK UNIFIED IDEOGRAPH
+0xE5CD 0x7A70 #CJK UNIFIED IDEOGRAPH
+0xE5CE 0xF97B #CJK COMPATIBILITY IDEOGRAPH
+0xE5CF 0x7F8A #CJK UNIFIED IDEOGRAPH
+0xE5D0 0xF97C #CJK COMPATIBILITY IDEOGRAPH
+0xE5D1 0x8944 #CJK UNIFIED IDEOGRAPH
+0xE5D2 0xF97D #CJK COMPATIBILITY IDEOGRAPH
+0xE5D3 0x8B93 #CJK UNIFIED IDEOGRAPH
+0xE5D4 0x91C0 #CJK UNIFIED IDEOGRAPH
+0xE5D5 0x967D #CJK UNIFIED IDEOGRAPH
+0xE5D6 0xF97E #CJK COMPATIBILITY IDEOGRAPH
+0xE5D7 0x990A #CJK UNIFIED IDEOGRAPH
+0xE5D8 0x5704 #CJK UNIFIED IDEOGRAPH
+0xE5D9 0x5FA1 #CJK UNIFIED IDEOGRAPH
+0xE5DA 0x65BC #CJK UNIFIED IDEOGRAPH
+0xE5DB 0x6F01 #CJK UNIFIED IDEOGRAPH
+0xE5DC 0x7600 #CJK UNIFIED IDEOGRAPH
+0xE5DD 0x79A6 #CJK UNIFIED IDEOGRAPH
+0xE5DE 0x8A9E #CJK UNIFIED IDEOGRAPH
+0xE5DF 0x99AD #CJK UNIFIED IDEOGRAPH
+0xE5E0 0x9B5A #CJK UNIFIED IDEOGRAPH
+0xE5E1 0x9F6C #CJK UNIFIED IDEOGRAPH
+0xE5E2 0x5104 #CJK UNIFIED IDEOGRAPH
+0xE5E3 0x61B6 #CJK UNIFIED IDEOGRAPH
+0xE5E4 0x6291 #CJK UNIFIED IDEOGRAPH
+0xE5E5 0x6A8D #CJK UNIFIED IDEOGRAPH
+0xE5E6 0x81C6 #CJK UNIFIED IDEOGRAPH
+0xE5E7 0x5043 #CJK UNIFIED IDEOGRAPH
+0xE5E8 0x5830 #CJK UNIFIED IDEOGRAPH
+0xE5E9 0x5F66 #CJK UNIFIED IDEOGRAPH
+0xE5EA 0x7109 #CJK UNIFIED IDEOGRAPH
+0xE5EB 0x8A00 #CJK UNIFIED IDEOGRAPH
+0xE5EC 0x8AFA #CJK UNIFIED IDEOGRAPH
+0xE5ED 0x5B7C #CJK UNIFIED IDEOGRAPH
+0xE5EE 0x8616 #CJK UNIFIED IDEOGRAPH
+0xE5EF 0x4FFA #CJK UNIFIED IDEOGRAPH
+0xE5F0 0x513C #CJK UNIFIED IDEOGRAPH
+0xE5F1 0x56B4 #CJK UNIFIED IDEOGRAPH
+0xE5F2 0x5944 #CJK UNIFIED IDEOGRAPH
+0xE5F3 0x63A9 #CJK UNIFIED IDEOGRAPH
+0xE5F4 0x6DF9 #CJK UNIFIED IDEOGRAPH
+0xE5F5 0x5DAA #CJK UNIFIED IDEOGRAPH
+0xE5F6 0x696D #CJK UNIFIED IDEOGRAPH
+0xE5F7 0x5186 #CJK UNIFIED IDEOGRAPH
+0xE5F8 0x4E88 #CJK UNIFIED IDEOGRAPH
+0xE5F9 0x4F59 #CJK UNIFIED IDEOGRAPH
+0xE5FA 0xF97F #CJK COMPATIBILITY IDEOGRAPH
+0xE5FB 0xF980 #CJK COMPATIBILITY IDEOGRAPH
+0xE5FC 0xF981 #CJK COMPATIBILITY IDEOGRAPH
+0xE5FD 0x5982 #CJK UNIFIED IDEOGRAPH
+0xE5FE 0xF982 #CJK COMPATIBILITY IDEOGRAPH
+0xE6A1 0xF983 #CJK COMPATIBILITY IDEOGRAPH
+0xE6A2 0x6B5F #CJK UNIFIED IDEOGRAPH
+0xE6A3 0x6C5D #CJK UNIFIED IDEOGRAPH
+0xE6A4 0xF984 #CJK COMPATIBILITY IDEOGRAPH
+0xE6A5 0x74B5 #CJK UNIFIED IDEOGRAPH
+0xE6A6 0x7916 #CJK UNIFIED IDEOGRAPH
+0xE6A7 0xF985 #CJK COMPATIBILITY IDEOGRAPH
+0xE6A8 0x8207 #CJK UNIFIED IDEOGRAPH
+0xE6A9 0x8245 #CJK UNIFIED IDEOGRAPH
+0xE6AA 0x8339 #CJK UNIFIED IDEOGRAPH
+0xE6AB 0x8F3F #CJK UNIFIED IDEOGRAPH
+0xE6AC 0x8F5D #CJK UNIFIED IDEOGRAPH
+0xE6AD 0xF986 #CJK COMPATIBILITY IDEOGRAPH
+0xE6AE 0x9918 #CJK UNIFIED IDEOGRAPH
+0xE6AF 0xF987 #CJK COMPATIBILITY IDEOGRAPH
+0xE6B0 0xF988 #CJK COMPATIBILITY IDEOGRAPH
+0xE6B1 0xF989 #CJK COMPATIBILITY IDEOGRAPH
+0xE6B2 0x4EA6 #CJK UNIFIED IDEOGRAPH
+0xE6B3 0xF98A #CJK COMPATIBILITY IDEOGRAPH
+0xE6B4 0x57DF #CJK UNIFIED IDEOGRAPH
+0xE6B5 0x5F79 #CJK UNIFIED IDEOGRAPH
+0xE6B6 0x6613 #CJK UNIFIED IDEOGRAPH
+0xE6B7 0xF98B #CJK COMPATIBILITY IDEOGRAPH
+0xE6B8 0xF98C #CJK COMPATIBILITY IDEOGRAPH
+0xE6B9 0x75AB #CJK UNIFIED IDEOGRAPH
+0xE6BA 0x7E79 #CJK UNIFIED IDEOGRAPH
+0xE6BB 0x8B6F #CJK UNIFIED IDEOGRAPH
+0xE6BC 0xF98D #CJK COMPATIBILITY IDEOGRAPH
+0xE6BD 0x9006 #CJK UNIFIED IDEOGRAPH
+0xE6BE 0x9A5B #CJK UNIFIED IDEOGRAPH
+0xE6BF 0x56A5 #CJK UNIFIED IDEOGRAPH
+0xE6C0 0x5827 #CJK UNIFIED IDEOGRAPH
+0xE6C1 0x59F8 #CJK UNIFIED IDEOGRAPH
+0xE6C2 0x5A1F #CJK UNIFIED IDEOGRAPH
+0xE6C3 0x5BB4 #CJK UNIFIED IDEOGRAPH
+0xE6C4 0xF98E #CJK COMPATIBILITY IDEOGRAPH
+0xE6C5 0x5EF6 #CJK UNIFIED IDEOGRAPH
+0xE6C6 0xF98F #CJK COMPATIBILITY IDEOGRAPH
+0xE6C7 0xF990 #CJK COMPATIBILITY IDEOGRAPH
+0xE6C8 0x6350 #CJK UNIFIED IDEOGRAPH
+0xE6C9 0x633B #CJK UNIFIED IDEOGRAPH
+0xE6CA 0xF991 #CJK COMPATIBILITY IDEOGRAPH
+0xE6CB 0x693D #CJK UNIFIED IDEOGRAPH
+0xE6CC 0x6C87 #CJK UNIFIED IDEOGRAPH
+0xE6CD 0x6CBF #CJK UNIFIED IDEOGRAPH
+0xE6CE 0x6D8E #CJK UNIFIED IDEOGRAPH
+0xE6CF 0x6D93 #CJK UNIFIED IDEOGRAPH
+0xE6D0 0x6DF5 #CJK UNIFIED IDEOGRAPH
+0xE6D1 0x6F14 #CJK UNIFIED IDEOGRAPH
+0xE6D2 0xF992 #CJK COMPATIBILITY IDEOGRAPH
+0xE6D3 0x70DF #CJK UNIFIED IDEOGRAPH
+0xE6D4 0x7136 #CJK UNIFIED IDEOGRAPH
+0xE6D5 0x7159 #CJK UNIFIED IDEOGRAPH
+0xE6D6 0xF993 #CJK COMPATIBILITY IDEOGRAPH
+0xE6D7 0x71C3 #CJK UNIFIED IDEOGRAPH
+0xE6D8 0x71D5 #CJK UNIFIED IDEOGRAPH
+0xE6D9 0xF994 #CJK COMPATIBILITY IDEOGRAPH
+0xE6DA 0x784F #CJK UNIFIED IDEOGRAPH
+0xE6DB 0x786F #CJK UNIFIED IDEOGRAPH
+0xE6DC 0xF995 #CJK COMPATIBILITY IDEOGRAPH
+0xE6DD 0x7B75 #CJK UNIFIED IDEOGRAPH
+0xE6DE 0x7DE3 #CJK UNIFIED IDEOGRAPH
+0xE6DF 0xF996 #CJK COMPATIBILITY IDEOGRAPH
+0xE6E0 0x7E2F #CJK UNIFIED IDEOGRAPH
+0xE6E1 0xF997 #CJK COMPATIBILITY IDEOGRAPH
+0xE6E2 0x884D #CJK UNIFIED IDEOGRAPH
+0xE6E3 0x8EDF #CJK UNIFIED IDEOGRAPH
+0xE6E4 0xF998 #CJK COMPATIBILITY IDEOGRAPH
+0xE6E5 0xF999 #CJK COMPATIBILITY IDEOGRAPH
+0xE6E6 0xF99A #CJK COMPATIBILITY IDEOGRAPH
+0xE6E7 0x925B #CJK UNIFIED IDEOGRAPH
+0xE6E8 0xF99B #CJK COMPATIBILITY IDEOGRAPH
+0xE6E9 0x9CF6 #CJK UNIFIED IDEOGRAPH
+0xE6EA 0xF99C #CJK COMPATIBILITY IDEOGRAPH
+0xE6EB 0xF99D #CJK COMPATIBILITY IDEOGRAPH
+0xE6EC 0xF99E #CJK COMPATIBILITY IDEOGRAPH
+0xE6ED 0x6085 #CJK UNIFIED IDEOGRAPH
+0xE6EE 0x6D85 #CJK UNIFIED IDEOGRAPH
+0xE6EF 0xF99F #CJK COMPATIBILITY IDEOGRAPH
+0xE6F0 0x71B1 #CJK UNIFIED IDEOGRAPH
+0xE6F1 0xF9A0 #CJK COMPATIBILITY IDEOGRAPH
+0xE6F2 0xF9A1 #CJK COMPATIBILITY IDEOGRAPH
+0xE6F3 0x95B1 #CJK UNIFIED IDEOGRAPH
+0xE6F4 0x53AD #CJK UNIFIED IDEOGRAPH
+0xE6F5 0xF9A2 #CJK COMPATIBILITY IDEOGRAPH
+0xE6F6 0xF9A3 #CJK COMPATIBILITY IDEOGRAPH
+0xE6F7 0xF9A4 #CJK COMPATIBILITY IDEOGRAPH
+0xE6F8 0x67D3 #CJK UNIFIED IDEOGRAPH
+0xE6F9 0xF9A5 #CJK COMPATIBILITY IDEOGRAPH
+0xE6FA 0x708E #CJK UNIFIED IDEOGRAPH
+0xE6FB 0x7130 #CJK UNIFIED IDEOGRAPH
+0xE6FC 0x7430 #CJK UNIFIED IDEOGRAPH
+0xE6FD 0x8276 #CJK UNIFIED IDEOGRAPH
+0xE6FE 0x82D2 #CJK UNIFIED IDEOGRAPH
+0xE7A1 0xF9A6 #CJK COMPATIBILITY IDEOGRAPH
+0xE7A2 0x95BB #CJK UNIFIED IDEOGRAPH
+0xE7A3 0x9AE5 #CJK UNIFIED IDEOGRAPH
+0xE7A4 0x9E7D #CJK UNIFIED IDEOGRAPH
+0xE7A5 0x66C4 #CJK UNIFIED IDEOGRAPH
+0xE7A6 0xF9A7 #CJK COMPATIBILITY IDEOGRAPH
+0xE7A7 0x71C1 #CJK UNIFIED IDEOGRAPH
+0xE7A8 0x8449 #CJK UNIFIED IDEOGRAPH
+0xE7A9 0xF9A8 #CJK COMPATIBILITY IDEOGRAPH
+0xE7AA 0xF9A9 #CJK COMPATIBILITY IDEOGRAPH
+0xE7AB 0x584B #CJK UNIFIED IDEOGRAPH
+0xE7AC 0xF9AA #CJK COMPATIBILITY IDEOGRAPH
+0xE7AD 0xF9AB #CJK COMPATIBILITY IDEOGRAPH
+0xE7AE 0x5DB8 #CJK UNIFIED IDEOGRAPH
+0xE7AF 0x5F71 #CJK UNIFIED IDEOGRAPH
+0xE7B0 0xF9AC #CJK COMPATIBILITY IDEOGRAPH
+0xE7B1 0x6620 #CJK UNIFIED IDEOGRAPH
+0xE7B2 0x668E #CJK UNIFIED IDEOGRAPH
+0xE7B3 0x6979 #CJK UNIFIED IDEOGRAPH
+0xE7B4 0x69AE #CJK UNIFIED IDEOGRAPH
+0xE7B5 0x6C38 #CJK UNIFIED IDEOGRAPH
+0xE7B6 0x6CF3 #CJK UNIFIED IDEOGRAPH
+0xE7B7 0x6E36 #CJK UNIFIED IDEOGRAPH
+0xE7B8 0x6F41 #CJK UNIFIED IDEOGRAPH
+0xE7B9 0x6FDA #CJK UNIFIED IDEOGRAPH
+0xE7BA 0x701B #CJK UNIFIED IDEOGRAPH
+0xE7BB 0x702F #CJK UNIFIED IDEOGRAPH
+0xE7BC 0x7150 #CJK UNIFIED IDEOGRAPH
+0xE7BD 0x71DF #CJK UNIFIED IDEOGRAPH
+0xE7BE 0x7370 #CJK UNIFIED IDEOGRAPH
+0xE7BF 0xF9AD #CJK COMPATIBILITY IDEOGRAPH
+0xE7C0 0x745B #CJK UNIFIED IDEOGRAPH
+0xE7C1 0xF9AE #CJK COMPATIBILITY IDEOGRAPH
+0xE7C2 0x74D4 #CJK UNIFIED IDEOGRAPH
+0xE7C3 0x76C8 #CJK UNIFIED IDEOGRAPH
+0xE7C4 0x7A4E #CJK UNIFIED IDEOGRAPH
+0xE7C5 0x7E93 #CJK UNIFIED IDEOGRAPH
+0xE7C6 0xF9AF #CJK COMPATIBILITY IDEOGRAPH
+0xE7C7 0xF9B0 #CJK COMPATIBILITY IDEOGRAPH
+0xE7C8 0x82F1 #CJK UNIFIED IDEOGRAPH
+0xE7C9 0x8A60 #CJK UNIFIED IDEOGRAPH
+0xE7CA 0x8FCE #CJK UNIFIED IDEOGRAPH
+0xE7CB 0xF9B1 #CJK COMPATIBILITY IDEOGRAPH
+0xE7CC 0x9348 #CJK UNIFIED IDEOGRAPH
+0xE7CD 0xF9B2 #CJK COMPATIBILITY IDEOGRAPH
+0xE7CE 0x9719 #CJK UNIFIED IDEOGRAPH
+0xE7CF 0xF9B3 #CJK COMPATIBILITY IDEOGRAPH
+0xE7D0 0xF9B4 #CJK COMPATIBILITY IDEOGRAPH
+0xE7D1 0x4E42 #CJK UNIFIED IDEOGRAPH
+0xE7D2 0x502A #CJK UNIFIED IDEOGRAPH
+0xE7D3 0xF9B5 #CJK COMPATIBILITY IDEOGRAPH
+0xE7D4 0x5208 #CJK UNIFIED IDEOGRAPH
+0xE7D5 0x53E1 #CJK UNIFIED IDEOGRAPH
+0xE7D6 0x66F3 #CJK UNIFIED IDEOGRAPH
+0xE7D7 0x6C6D #CJK UNIFIED IDEOGRAPH
+0xE7D8 0x6FCA #CJK UNIFIED IDEOGRAPH
+0xE7D9 0x730A #CJK UNIFIED IDEOGRAPH
+0xE7DA 0x777F #CJK UNIFIED IDEOGRAPH
+0xE7DB 0x7A62 #CJK UNIFIED IDEOGRAPH
+0xE7DC 0x82AE #CJK UNIFIED IDEOGRAPH
+0xE7DD 0x85DD #CJK UNIFIED IDEOGRAPH
+0xE7DE 0x8602 #CJK UNIFIED IDEOGRAPH
+0xE7DF 0xF9B6 #CJK COMPATIBILITY IDEOGRAPH
+0xE7E0 0x88D4 #CJK UNIFIED IDEOGRAPH
+0xE7E1 0x8A63 #CJK UNIFIED IDEOGRAPH
+0xE7E2 0x8B7D #CJK UNIFIED IDEOGRAPH
+0xE7E3 0x8C6B #CJK UNIFIED IDEOGRAPH
+0xE7E4 0xF9B7 #CJK COMPATIBILITY IDEOGRAPH
+0xE7E5 0x92B3 #CJK UNIFIED IDEOGRAPH
+0xE7E6 0xF9B8 #CJK COMPATIBILITY IDEOGRAPH
+0xE7E7 0x9713 #CJK UNIFIED IDEOGRAPH
+0xE7E8 0x9810 #CJK UNIFIED IDEOGRAPH
+0xE7E9 0x4E94 #CJK UNIFIED IDEOGRAPH
+0xE7EA 0x4F0D #CJK UNIFIED IDEOGRAPH
+0xE7EB 0x4FC9 #CJK UNIFIED IDEOGRAPH
+0xE7EC 0x50B2 #CJK UNIFIED IDEOGRAPH
+0xE7ED 0x5348 #CJK UNIFIED IDEOGRAPH
+0xE7EE 0x543E #CJK UNIFIED IDEOGRAPH
+0xE7EF 0x5433 #CJK UNIFIED IDEOGRAPH
+0xE7F0 0x55DA #CJK UNIFIED IDEOGRAPH
+0xE7F1 0x5862 #CJK UNIFIED IDEOGRAPH
+0xE7F2 0x58BA #CJK UNIFIED IDEOGRAPH
+0xE7F3 0x5967 #CJK UNIFIED IDEOGRAPH
+0xE7F4 0x5A1B #CJK UNIFIED IDEOGRAPH
+0xE7F5 0x5BE4 #CJK UNIFIED IDEOGRAPH
+0xE7F6 0x609F #CJK UNIFIED IDEOGRAPH
+0xE7F7 0xF9B9 #CJK COMPATIBILITY IDEOGRAPH
+0xE7F8 0x61CA #CJK UNIFIED IDEOGRAPH
+0xE7F9 0x6556 #CJK UNIFIED IDEOGRAPH
+0xE7FA 0x65FF #CJK UNIFIED IDEOGRAPH
+0xE7FB 0x6664 #CJK UNIFIED IDEOGRAPH
+0xE7FC 0x68A7 #CJK UNIFIED IDEOGRAPH
+0xE7FD 0x6C5A #CJK UNIFIED IDEOGRAPH
+0xE7FE 0x6FB3 #CJK UNIFIED IDEOGRAPH
+0xE8A1 0x70CF #CJK UNIFIED IDEOGRAPH
+0xE8A2 0x71AC #CJK UNIFIED IDEOGRAPH
+0xE8A3 0x7352 #CJK UNIFIED IDEOGRAPH
+0xE8A4 0x7B7D #CJK UNIFIED IDEOGRAPH
+0xE8A5 0x8708 #CJK UNIFIED IDEOGRAPH
+0xE8A6 0x8AA4 #CJK UNIFIED IDEOGRAPH
+0xE8A7 0x9C32 #CJK UNIFIED IDEOGRAPH
+0xE8A8 0x9F07 #CJK UNIFIED IDEOGRAPH
+0xE8A9 0x5C4B #CJK UNIFIED IDEOGRAPH
+0xE8AA 0x6C83 #CJK UNIFIED IDEOGRAPH
+0xE8AB 0x7344 #CJK UNIFIED IDEOGRAPH
+0xE8AC 0x7389 #CJK UNIFIED IDEOGRAPH
+0xE8AD 0x923A #CJK UNIFIED IDEOGRAPH
+0xE8AE 0x6EAB #CJK UNIFIED IDEOGRAPH
+0xE8AF 0x7465 #CJK UNIFIED IDEOGRAPH
+0xE8B0 0x761F #CJK UNIFIED IDEOGRAPH
+0xE8B1 0x7A69 #CJK UNIFIED IDEOGRAPH
+0xE8B2 0x7E15 #CJK UNIFIED IDEOGRAPH
+0xE8B3 0x860A #CJK UNIFIED IDEOGRAPH
+0xE8B4 0x5140 #CJK UNIFIED IDEOGRAPH
+0xE8B5 0x58C5 #CJK UNIFIED IDEOGRAPH
+0xE8B6 0x64C1 #CJK UNIFIED IDEOGRAPH
+0xE8B7 0x74EE #CJK UNIFIED IDEOGRAPH
+0xE8B8 0x7515 #CJK UNIFIED IDEOGRAPH
+0xE8B9 0x7670 #CJK UNIFIED IDEOGRAPH
+0xE8BA 0x7FC1 #CJK UNIFIED IDEOGRAPH
+0xE8BB 0x9095 #CJK UNIFIED IDEOGRAPH
+0xE8BC 0x96CD #CJK UNIFIED IDEOGRAPH
+0xE8BD 0x9954 #CJK UNIFIED IDEOGRAPH
+0xE8BE 0x6E26 #CJK UNIFIED IDEOGRAPH
+0xE8BF 0x74E6 #CJK UNIFIED IDEOGRAPH
+0xE8C0 0x7AA9 #CJK UNIFIED IDEOGRAPH
+0xE8C1 0x7AAA #CJK UNIFIED IDEOGRAPH
+0xE8C2 0x81E5 #CJK UNIFIED IDEOGRAPH
+0xE8C3 0x86D9 #CJK UNIFIED IDEOGRAPH
+0xE8C4 0x8778 #CJK UNIFIED IDEOGRAPH
+0xE8C5 0x8A1B #CJK UNIFIED IDEOGRAPH
+0xE8C6 0x5A49 #CJK UNIFIED IDEOGRAPH
+0xE8C7 0x5B8C #CJK UNIFIED IDEOGRAPH
+0xE8C8 0x5B9B #CJK UNIFIED IDEOGRAPH
+0xE8C9 0x68A1 #CJK UNIFIED IDEOGRAPH
+0xE8CA 0x6900 #CJK UNIFIED IDEOGRAPH
+0xE8CB 0x6D63 #CJK UNIFIED IDEOGRAPH
+0xE8CC 0x73A9 #CJK UNIFIED IDEOGRAPH
+0xE8CD 0x7413 #CJK UNIFIED IDEOGRAPH
+0xE8CE 0x742C #CJK UNIFIED IDEOGRAPH
+0xE8CF 0x7897 #CJK UNIFIED IDEOGRAPH
+0xE8D0 0x7DE9 #CJK UNIFIED IDEOGRAPH
+0xE8D1 0x7FEB #CJK UNIFIED IDEOGRAPH
+0xE8D2 0x8118 #CJK UNIFIED IDEOGRAPH
+0xE8D3 0x8155 #CJK UNIFIED IDEOGRAPH
+0xE8D4 0x839E #CJK UNIFIED IDEOGRAPH
+0xE8D5 0x8C4C #CJK UNIFIED IDEOGRAPH
+0xE8D6 0x962E #CJK UNIFIED IDEOGRAPH
+0xE8D7 0x9811 #CJK UNIFIED IDEOGRAPH
+0xE8D8 0x66F0 #CJK UNIFIED IDEOGRAPH
+0xE8D9 0x5F80 #CJK UNIFIED IDEOGRAPH
+0xE8DA 0x65FA #CJK UNIFIED IDEOGRAPH
+0xE8DB 0x6789 #CJK UNIFIED IDEOGRAPH
+0xE8DC 0x6C6A #CJK UNIFIED IDEOGRAPH
+0xE8DD 0x738B #CJK UNIFIED IDEOGRAPH
+0xE8DE 0x502D #CJK UNIFIED IDEOGRAPH
+0xE8DF 0x5A03 #CJK UNIFIED IDEOGRAPH
+0xE8E0 0x6B6A #CJK UNIFIED IDEOGRAPH
+0xE8E1 0x77EE #CJK UNIFIED IDEOGRAPH
+0xE8E2 0x5916 #CJK UNIFIED IDEOGRAPH
+0xE8E3 0x5D6C #CJK UNIFIED IDEOGRAPH
+0xE8E4 0x5DCD #CJK UNIFIED IDEOGRAPH
+0xE8E5 0x7325 #CJK UNIFIED IDEOGRAPH
+0xE8E6 0x754F #CJK UNIFIED IDEOGRAPH
+0xE8E7 0xF9BA #CJK COMPATIBILITY IDEOGRAPH
+0xE8E8 0xF9BB #CJK COMPATIBILITY IDEOGRAPH
+0xE8E9 0x50E5 #CJK UNIFIED IDEOGRAPH
+0xE8EA 0x51F9 #CJK UNIFIED IDEOGRAPH
+0xE8EB 0x582F #CJK UNIFIED IDEOGRAPH
+0xE8EC 0x592D #CJK UNIFIED IDEOGRAPH
+0xE8ED 0x5996 #CJK UNIFIED IDEOGRAPH
+0xE8EE 0x59DA #CJK UNIFIED IDEOGRAPH
+0xE8EF 0x5BE5 #CJK UNIFIED IDEOGRAPH
+0xE8F0 0xF9BC #CJK COMPATIBILITY IDEOGRAPH
+0xE8F1 0xF9BD #CJK COMPATIBILITY IDEOGRAPH
+0xE8F2 0x5DA2 #CJK UNIFIED IDEOGRAPH
+0xE8F3 0x62D7 #CJK UNIFIED IDEOGRAPH
+0xE8F4 0x6416 #CJK UNIFIED IDEOGRAPH
+0xE8F5 0x6493 #CJK UNIFIED IDEOGRAPH
+0xE8F6 0x64FE #CJK UNIFIED IDEOGRAPH
+0xE8F7 0xF9BE #CJK COMPATIBILITY IDEOGRAPH
+0xE8F8 0x66DC #CJK UNIFIED IDEOGRAPH
+0xE8F9 0xF9BF #CJK COMPATIBILITY IDEOGRAPH
+0xE8FA 0x6A48 #CJK UNIFIED IDEOGRAPH
+0xE8FB 0xF9C0 #CJK COMPATIBILITY IDEOGRAPH
+0xE8FC 0x71FF #CJK UNIFIED IDEOGRAPH
+0xE8FD 0x7464 #CJK UNIFIED IDEOGRAPH
+0xE8FE 0xF9C1 #CJK COMPATIBILITY IDEOGRAPH
+0xE9A1 0x7A88 #CJK UNIFIED IDEOGRAPH
+0xE9A2 0x7AAF #CJK UNIFIED IDEOGRAPH
+0xE9A3 0x7E47 #CJK UNIFIED IDEOGRAPH
+0xE9A4 0x7E5E #CJK UNIFIED IDEOGRAPH
+0xE9A5 0x8000 #CJK UNIFIED IDEOGRAPH
+0xE9A6 0x8170 #CJK UNIFIED IDEOGRAPH
+0xE9A7 0xF9C2 #CJK COMPATIBILITY IDEOGRAPH
+0xE9A8 0x87EF #CJK UNIFIED IDEOGRAPH
+0xE9A9 0x8981 #CJK UNIFIED IDEOGRAPH
+0xE9AA 0x8B20 #CJK UNIFIED IDEOGRAPH
+0xE9AB 0x9059 #CJK UNIFIED IDEOGRAPH
+0xE9AC 0xF9C3 #CJK COMPATIBILITY IDEOGRAPH
+0xE9AD 0x9080 #CJK UNIFIED IDEOGRAPH
+0xE9AE 0x9952 #CJK UNIFIED IDEOGRAPH
+0xE9AF 0x617E #CJK UNIFIED IDEOGRAPH
+0xE9B0 0x6B32 #CJK UNIFIED IDEOGRAPH
+0xE9B1 0x6D74 #CJK UNIFIED IDEOGRAPH
+0xE9B2 0x7E1F #CJK UNIFIED IDEOGRAPH
+0xE9B3 0x8925 #CJK UNIFIED IDEOGRAPH
+0xE9B4 0x8FB1 #CJK UNIFIED IDEOGRAPH
+0xE9B5 0x4FD1 #CJK UNIFIED IDEOGRAPH
+0xE9B6 0x50AD #CJK UNIFIED IDEOGRAPH
+0xE9B7 0x5197 #CJK UNIFIED IDEOGRAPH
+0xE9B8 0x52C7 #CJK UNIFIED IDEOGRAPH
+0xE9B9 0x57C7 #CJK UNIFIED IDEOGRAPH
+0xE9BA 0x5889 #CJK UNIFIED IDEOGRAPH
+0xE9BB 0x5BB9 #CJK UNIFIED IDEOGRAPH
+0xE9BC 0x5EB8 #CJK UNIFIED IDEOGRAPH
+0xE9BD 0x6142 #CJK UNIFIED IDEOGRAPH
+0xE9BE 0x6995 #CJK UNIFIED IDEOGRAPH
+0xE9BF 0x6D8C #CJK UNIFIED IDEOGRAPH
+0xE9C0 0x6E67 #CJK UNIFIED IDEOGRAPH
+0xE9C1 0x6EB6 #CJK UNIFIED IDEOGRAPH
+0xE9C2 0x7194 #CJK UNIFIED IDEOGRAPH
+0xE9C3 0x7462 #CJK UNIFIED IDEOGRAPH
+0xE9C4 0x7528 #CJK UNIFIED IDEOGRAPH
+0xE9C5 0x752C #CJK UNIFIED IDEOGRAPH
+0xE9C6 0x8073 #CJK UNIFIED IDEOGRAPH
+0xE9C7 0x8338 #CJK UNIFIED IDEOGRAPH
+0xE9C8 0x84C9 #CJK UNIFIED IDEOGRAPH
+0xE9C9 0x8E0A #CJK UNIFIED IDEOGRAPH
+0xE9CA 0x9394 #CJK UNIFIED IDEOGRAPH
+0xE9CB 0x93DE #CJK UNIFIED IDEOGRAPH
+0xE9CC 0xF9C4 #CJK COMPATIBILITY IDEOGRAPH
+0xE9CD 0x4E8E #CJK UNIFIED IDEOGRAPH
+0xE9CE 0x4F51 #CJK UNIFIED IDEOGRAPH
+0xE9CF 0x5076 #CJK UNIFIED IDEOGRAPH
+0xE9D0 0x512A #CJK UNIFIED IDEOGRAPH
+0xE9D1 0x53C8 #CJK UNIFIED IDEOGRAPH
+0xE9D2 0x53CB #CJK UNIFIED IDEOGRAPH
+0xE9D3 0x53F3 #CJK UNIFIED IDEOGRAPH
+0xE9D4 0x5B87 #CJK UNIFIED IDEOGRAPH
+0xE9D5 0x5BD3 #CJK UNIFIED IDEOGRAPH
+0xE9D6 0x5C24 #CJK UNIFIED IDEOGRAPH
+0xE9D7 0x611A #CJK UNIFIED IDEOGRAPH
+0xE9D8 0x6182 #CJK UNIFIED IDEOGRAPH
+0xE9D9 0x65F4 #CJK UNIFIED IDEOGRAPH
+0xE9DA 0x725B #CJK UNIFIED IDEOGRAPH
+0xE9DB 0x7397 #CJK UNIFIED IDEOGRAPH
+0xE9DC 0x7440 #CJK UNIFIED IDEOGRAPH
+0xE9DD 0x76C2 #CJK UNIFIED IDEOGRAPH
+0xE9DE 0x7950 #CJK UNIFIED IDEOGRAPH
+0xE9DF 0x7991 #CJK UNIFIED IDEOGRAPH
+0xE9E0 0x79B9 #CJK UNIFIED IDEOGRAPH
+0xE9E1 0x7D06 #CJK UNIFIED IDEOGRAPH
+0xE9E2 0x7FBD #CJK UNIFIED IDEOGRAPH
+0xE9E3 0x828B #CJK UNIFIED IDEOGRAPH
+0xE9E4 0x85D5 #CJK UNIFIED IDEOGRAPH
+0xE9E5 0x865E #CJK UNIFIED IDEOGRAPH
+0xE9E6 0x8FC2 #CJK UNIFIED IDEOGRAPH
+0xE9E7 0x9047 #CJK UNIFIED IDEOGRAPH
+0xE9E8 0x90F5 #CJK UNIFIED IDEOGRAPH
+0xE9E9 0x91EA #CJK UNIFIED IDEOGRAPH
+0xE9EA 0x9685 #CJK UNIFIED IDEOGRAPH
+0xE9EB 0x96E8 #CJK UNIFIED IDEOGRAPH
+0xE9EC 0x96E9 #CJK UNIFIED IDEOGRAPH
+0xE9ED 0x52D6 #CJK UNIFIED IDEOGRAPH
+0xE9EE 0x5F67 #CJK UNIFIED IDEOGRAPH
+0xE9EF 0x65ED #CJK UNIFIED IDEOGRAPH
+0xE9F0 0x6631 #CJK UNIFIED IDEOGRAPH
+0xE9F1 0x682F #CJK UNIFIED IDEOGRAPH
+0xE9F2 0x715C #CJK UNIFIED IDEOGRAPH
+0xE9F3 0x7A36 #CJK UNIFIED IDEOGRAPH
+0xE9F4 0x90C1 #CJK UNIFIED IDEOGRAPH
+0xE9F5 0x980A #CJK UNIFIED IDEOGRAPH
+0xE9F6 0x4E91 #CJK UNIFIED IDEOGRAPH
+0xE9F7 0xF9C5 #CJK COMPATIBILITY IDEOGRAPH
+0xE9F8 0x6A52 #CJK UNIFIED IDEOGRAPH
+0xE9F9 0x6B9E #CJK UNIFIED IDEOGRAPH
+0xE9FA 0x6F90 #CJK UNIFIED IDEOGRAPH
+0xE9FB 0x7189 #CJK UNIFIED IDEOGRAPH
+0xE9FC 0x8018 #CJK UNIFIED IDEOGRAPH
+0xE9FD 0x82B8 #CJK UNIFIED IDEOGRAPH
+0xE9FE 0x8553 #CJK UNIFIED IDEOGRAPH
+0xEAA1 0x904B #CJK UNIFIED IDEOGRAPH
+0xEAA2 0x9695 #CJK UNIFIED IDEOGRAPH
+0xEAA3 0x96F2 #CJK UNIFIED IDEOGRAPH
+0xEAA4 0x97FB #CJK UNIFIED IDEOGRAPH
+0xEAA5 0x851A #CJK UNIFIED IDEOGRAPH
+0xEAA6 0x9B31 #CJK UNIFIED IDEOGRAPH
+0xEAA7 0x4E90 #CJK UNIFIED IDEOGRAPH
+0xEAA8 0x718A #CJK UNIFIED IDEOGRAPH
+0xEAA9 0x96C4 #CJK UNIFIED IDEOGRAPH
+0xEAAA 0x5143 #CJK UNIFIED IDEOGRAPH
+0xEAAB 0x539F #CJK UNIFIED IDEOGRAPH
+0xEAAC 0x54E1 #CJK UNIFIED IDEOGRAPH
+0xEAAD 0x5713 #CJK UNIFIED IDEOGRAPH
+0xEAAE 0x5712 #CJK UNIFIED IDEOGRAPH
+0xEAAF 0x57A3 #CJK UNIFIED IDEOGRAPH
+0xEAB0 0x5A9B #CJK UNIFIED IDEOGRAPH
+0xEAB1 0x5AC4 #CJK UNIFIED IDEOGRAPH
+0xEAB2 0x5BC3 #CJK UNIFIED IDEOGRAPH
+0xEAB3 0x6028 #CJK UNIFIED IDEOGRAPH
+0xEAB4 0x613F #CJK UNIFIED IDEOGRAPH
+0xEAB5 0x63F4 #CJK UNIFIED IDEOGRAPH
+0xEAB6 0x6C85 #CJK UNIFIED IDEOGRAPH
+0xEAB7 0x6D39 #CJK UNIFIED IDEOGRAPH
+0xEAB8 0x6E72 #CJK UNIFIED IDEOGRAPH
+0xEAB9 0x6E90 #CJK UNIFIED IDEOGRAPH
+0xEABA 0x7230 #CJK UNIFIED IDEOGRAPH
+0xEABB 0x733F #CJK UNIFIED IDEOGRAPH
+0xEABC 0x7457 #CJK UNIFIED IDEOGRAPH
+0xEABD 0x82D1 #CJK UNIFIED IDEOGRAPH
+0xEABE 0x8881 #CJK UNIFIED IDEOGRAPH
+0xEABF 0x8F45 #CJK UNIFIED IDEOGRAPH
+0xEAC0 0x9060 #CJK UNIFIED IDEOGRAPH
+0xEAC1 0xF9C6 #CJK COMPATIBILITY IDEOGRAPH
+0xEAC2 0x9662 #CJK UNIFIED IDEOGRAPH
+0xEAC3 0x9858 #CJK UNIFIED IDEOGRAPH
+0xEAC4 0x9D1B #CJK UNIFIED IDEOGRAPH
+0xEAC5 0x6708 #CJK UNIFIED IDEOGRAPH
+0xEAC6 0x8D8A #CJK UNIFIED IDEOGRAPH
+0xEAC7 0x925E #CJK UNIFIED IDEOGRAPH
+0xEAC8 0x4F4D #CJK UNIFIED IDEOGRAPH
+0xEAC9 0x5049 #CJK UNIFIED IDEOGRAPH
+0xEACA 0x50DE #CJK UNIFIED IDEOGRAPH
+0xEACB 0x5371 #CJK UNIFIED IDEOGRAPH
+0xEACC 0x570D #CJK UNIFIED IDEOGRAPH
+0xEACD 0x59D4 #CJK UNIFIED IDEOGRAPH
+0xEACE 0x5A01 #CJK UNIFIED IDEOGRAPH
+0xEACF 0x5C09 #CJK UNIFIED IDEOGRAPH
+0xEAD0 0x6170 #CJK UNIFIED IDEOGRAPH
+0xEAD1 0x6690 #CJK UNIFIED IDEOGRAPH
+0xEAD2 0x6E2D #CJK UNIFIED IDEOGRAPH
+0xEAD3 0x7232 #CJK UNIFIED IDEOGRAPH
+0xEAD4 0x744B #CJK UNIFIED IDEOGRAPH
+0xEAD5 0x7DEF #CJK UNIFIED IDEOGRAPH
+0xEAD6 0x80C3 #CJK UNIFIED IDEOGRAPH
+0xEAD7 0x840E #CJK UNIFIED IDEOGRAPH
+0xEAD8 0x8466 #CJK UNIFIED IDEOGRAPH
+0xEAD9 0x853F #CJK UNIFIED IDEOGRAPH
+0xEADA 0x875F #CJK UNIFIED IDEOGRAPH
+0xEADB 0x885B #CJK UNIFIED IDEOGRAPH
+0xEADC 0x8918 #CJK UNIFIED IDEOGRAPH
+0xEADD 0x8B02 #CJK UNIFIED IDEOGRAPH
+0xEADE 0x9055 #CJK UNIFIED IDEOGRAPH
+0xEADF 0x97CB #CJK UNIFIED IDEOGRAPH
+0xEAE0 0x9B4F #CJK UNIFIED IDEOGRAPH
+0xEAE1 0x4E73 #CJK UNIFIED IDEOGRAPH
+0xEAE2 0x4F91 #CJK UNIFIED IDEOGRAPH
+0xEAE3 0x5112 #CJK UNIFIED IDEOGRAPH
+0xEAE4 0x516A #CJK UNIFIED IDEOGRAPH
+0xEAE5 0xF9C7 #CJK COMPATIBILITY IDEOGRAPH
+0xEAE6 0x552F #CJK UNIFIED IDEOGRAPH
+0xEAE7 0x55A9 #CJK UNIFIED IDEOGRAPH
+0xEAE8 0x5B7A #CJK UNIFIED IDEOGRAPH
+0xEAE9 0x5BA5 #CJK UNIFIED IDEOGRAPH
+0xEAEA 0x5E7C #CJK UNIFIED IDEOGRAPH
+0xEAEB 0x5E7D #CJK UNIFIED IDEOGRAPH
+0xEAEC 0x5EBE #CJK UNIFIED IDEOGRAPH
+0xEAED 0x60A0 #CJK UNIFIED IDEOGRAPH
+0xEAEE 0x60DF #CJK UNIFIED IDEOGRAPH
+0xEAEF 0x6108 #CJK UNIFIED IDEOGRAPH
+0xEAF0 0x6109 #CJK UNIFIED IDEOGRAPH
+0xEAF1 0x63C4 #CJK UNIFIED IDEOGRAPH
+0xEAF2 0x6538 #CJK UNIFIED IDEOGRAPH
+0xEAF3 0x6709 #CJK UNIFIED IDEOGRAPH
+0xEAF4 0xF9C8 #CJK COMPATIBILITY IDEOGRAPH
+0xEAF5 0x67D4 #CJK UNIFIED IDEOGRAPH
+0xEAF6 0x67DA #CJK UNIFIED IDEOGRAPH
+0xEAF7 0xF9C9 #CJK COMPATIBILITY IDEOGRAPH
+0xEAF8 0x6961 #CJK UNIFIED IDEOGRAPH
+0xEAF9 0x6962 #CJK UNIFIED IDEOGRAPH
+0xEAFA 0x6CB9 #CJK UNIFIED IDEOGRAPH
+0xEAFB 0x6D27 #CJK UNIFIED IDEOGRAPH
+0xEAFC 0xF9CA #CJK COMPATIBILITY IDEOGRAPH
+0xEAFD 0x6E38 #CJK UNIFIED IDEOGRAPH
+0xEAFE 0xF9CB #CJK COMPATIBILITY IDEOGRAPH
+0xEBA1 0x6FE1 #CJK UNIFIED IDEOGRAPH
+0xEBA2 0x7336 #CJK UNIFIED IDEOGRAPH
+0xEBA3 0x7337 #CJK UNIFIED IDEOGRAPH
+0xEBA4 0xF9CC #CJK COMPATIBILITY IDEOGRAPH
+0xEBA5 0x745C #CJK UNIFIED IDEOGRAPH
+0xEBA6 0x7531 #CJK UNIFIED IDEOGRAPH
+0xEBA7 0xF9CD #CJK COMPATIBILITY IDEOGRAPH
+0xEBA8 0x7652 #CJK UNIFIED IDEOGRAPH
+0xEBA9 0xF9CE #CJK COMPATIBILITY IDEOGRAPH
+0xEBAA 0xF9CF #CJK COMPATIBILITY IDEOGRAPH
+0xEBAB 0x7DAD #CJK UNIFIED IDEOGRAPH
+0xEBAC 0x81FE #CJK UNIFIED IDEOGRAPH
+0xEBAD 0x8438 #CJK UNIFIED IDEOGRAPH
+0xEBAE 0x88D5 #CJK UNIFIED IDEOGRAPH
+0xEBAF 0x8A98 #CJK UNIFIED IDEOGRAPH
+0xEBB0 0x8ADB #CJK UNIFIED IDEOGRAPH
+0xEBB1 0x8AED #CJK UNIFIED IDEOGRAPH
+0xEBB2 0x8E30 #CJK UNIFIED IDEOGRAPH
+0xEBB3 0x8E42 #CJK UNIFIED IDEOGRAPH
+0xEBB4 0x904A #CJK UNIFIED IDEOGRAPH
+0xEBB5 0x903E #CJK UNIFIED IDEOGRAPH
+0xEBB6 0x907A #CJK UNIFIED IDEOGRAPH
+0xEBB7 0x9149 #CJK UNIFIED IDEOGRAPH
+0xEBB8 0x91C9 #CJK UNIFIED IDEOGRAPH
+0xEBB9 0x936E #CJK UNIFIED IDEOGRAPH
+0xEBBA 0xF9D0 #CJK COMPATIBILITY IDEOGRAPH
+0xEBBB 0xF9D1 #CJK COMPATIBILITY IDEOGRAPH
+0xEBBC 0x5809 #CJK UNIFIED IDEOGRAPH
+0xEBBD 0xF9D2 #CJK COMPATIBILITY IDEOGRAPH
+0xEBBE 0x6BD3 #CJK UNIFIED IDEOGRAPH
+0xEBBF 0x8089 #CJK UNIFIED IDEOGRAPH
+0xEBC0 0x80B2 #CJK UNIFIED IDEOGRAPH
+0xEBC1 0xF9D3 #CJK COMPATIBILITY IDEOGRAPH
+0xEBC2 0xF9D4 #CJK COMPATIBILITY IDEOGRAPH
+0xEBC3 0x5141 #CJK UNIFIED IDEOGRAPH
+0xEBC4 0x596B #CJK UNIFIED IDEOGRAPH
+0xEBC5 0x5C39 #CJK UNIFIED IDEOGRAPH
+0xEBC6 0xF9D5 #CJK COMPATIBILITY IDEOGRAPH
+0xEBC7 0xF9D6 #CJK COMPATIBILITY IDEOGRAPH
+0xEBC8 0x6F64 #CJK UNIFIED IDEOGRAPH
+0xEBC9 0x73A7 #CJK UNIFIED IDEOGRAPH
+0xEBCA 0x80E4 #CJK UNIFIED IDEOGRAPH
+0xEBCB 0x8D07 #CJK UNIFIED IDEOGRAPH
+0xEBCC 0xF9D7 #CJK COMPATIBILITY IDEOGRAPH
+0xEBCD 0x9217 #CJK UNIFIED IDEOGRAPH
+0xEBCE 0x958F #CJK UNIFIED IDEOGRAPH
+0xEBCF 0xF9D8 #CJK COMPATIBILITY IDEOGRAPH
+0xEBD0 0xF9D9 #CJK COMPATIBILITY IDEOGRAPH
+0xEBD1 0xF9DA #CJK COMPATIBILITY IDEOGRAPH
+0xEBD2 0xF9DB #CJK COMPATIBILITY IDEOGRAPH
+0xEBD3 0x807F #CJK UNIFIED IDEOGRAPH
+0xEBD4 0x620E #CJK UNIFIED IDEOGRAPH
+0xEBD5 0x701C #CJK UNIFIED IDEOGRAPH
+0xEBD6 0x7D68 #CJK UNIFIED IDEOGRAPH
+0xEBD7 0x878D #CJK UNIFIED IDEOGRAPH
+0xEBD8 0xF9DC #CJK COMPATIBILITY IDEOGRAPH
+0xEBD9 0x57A0 #CJK UNIFIED IDEOGRAPH
+0xEBDA 0x6069 #CJK UNIFIED IDEOGRAPH
+0xEBDB 0x6147 #CJK UNIFIED IDEOGRAPH
+0xEBDC 0x6BB7 #CJK UNIFIED IDEOGRAPH
+0xEBDD 0x8ABE #CJK UNIFIED IDEOGRAPH
+0xEBDE 0x9280 #CJK UNIFIED IDEOGRAPH
+0xEBDF 0x96B1 #CJK UNIFIED IDEOGRAPH
+0xEBE0 0x4E59 #CJK UNIFIED IDEOGRAPH
+0xEBE1 0x541F #CJK UNIFIED IDEOGRAPH
+0xEBE2 0x6DEB #CJK UNIFIED IDEOGRAPH
+0xEBE3 0x852D #CJK UNIFIED IDEOGRAPH
+0xEBE4 0x9670 #CJK UNIFIED IDEOGRAPH
+0xEBE5 0x97F3 #CJK UNIFIED IDEOGRAPH
+0xEBE6 0x98EE #CJK UNIFIED IDEOGRAPH
+0xEBE7 0x63D6 #CJK UNIFIED IDEOGRAPH
+0xEBE8 0x6CE3 #CJK UNIFIED IDEOGRAPH
+0xEBE9 0x9091 #CJK UNIFIED IDEOGRAPH
+0xEBEA 0x51DD #CJK UNIFIED IDEOGRAPH
+0xEBEB 0x61C9 #CJK UNIFIED IDEOGRAPH
+0xEBEC 0x81BA #CJK UNIFIED IDEOGRAPH
+0xEBED 0x9DF9 #CJK UNIFIED IDEOGRAPH
+0xEBEE 0x4F9D #CJK UNIFIED IDEOGRAPH
+0xEBEF 0x501A #CJK UNIFIED IDEOGRAPH
+0xEBF0 0x5100 #CJK UNIFIED IDEOGRAPH
+0xEBF1 0x5B9C #CJK UNIFIED IDEOGRAPH
+0xEBF2 0x610F #CJK UNIFIED IDEOGRAPH
+0xEBF3 0x61FF #CJK UNIFIED IDEOGRAPH
+0xEBF4 0x64EC #CJK UNIFIED IDEOGRAPH
+0xEBF5 0x6905 #CJK UNIFIED IDEOGRAPH
+0xEBF6 0x6BC5 #CJK UNIFIED IDEOGRAPH
+0xEBF7 0x7591 #CJK UNIFIED IDEOGRAPH
+0xEBF8 0x77E3 #CJK UNIFIED IDEOGRAPH
+0xEBF9 0x7FA9 #CJK UNIFIED IDEOGRAPH
+0xEBFA 0x8264 #CJK UNIFIED IDEOGRAPH
+0xEBFB 0x858F #CJK UNIFIED IDEOGRAPH
+0xEBFC 0x87FB #CJK UNIFIED IDEOGRAPH
+0xEBFD 0x8863 #CJK UNIFIED IDEOGRAPH
+0xEBFE 0x8ABC #CJK UNIFIED IDEOGRAPH
+0xECA1 0x8B70 #CJK UNIFIED IDEOGRAPH
+0xECA2 0x91AB #CJK UNIFIED IDEOGRAPH
+0xECA3 0x4E8C #CJK UNIFIED IDEOGRAPH
+0xECA4 0x4EE5 #CJK UNIFIED IDEOGRAPH
+0xECA5 0x4F0A #CJK UNIFIED IDEOGRAPH
+0xECA6 0xF9DD #CJK COMPATIBILITY IDEOGRAPH
+0xECA7 0xF9DE #CJK COMPATIBILITY IDEOGRAPH
+0xECA8 0x5937 #CJK UNIFIED IDEOGRAPH
+0xECA9 0x59E8 #CJK UNIFIED IDEOGRAPH
+0xECAA 0xF9DF #CJK COMPATIBILITY IDEOGRAPH
+0xECAB 0x5DF2 #CJK UNIFIED IDEOGRAPH
+0xECAC 0x5F1B #CJK UNIFIED IDEOGRAPH
+0xECAD 0x5F5B #CJK UNIFIED IDEOGRAPH
+0xECAE 0x6021 #CJK UNIFIED IDEOGRAPH
+0xECAF 0xF9E0 #CJK COMPATIBILITY IDEOGRAPH
+0xECB0 0xF9E1 #CJK COMPATIBILITY IDEOGRAPH
+0xECB1 0xF9E2 #CJK COMPATIBILITY IDEOGRAPH
+0xECB2 0xF9E3 #CJK COMPATIBILITY IDEOGRAPH
+0xECB3 0x723E #CJK UNIFIED IDEOGRAPH
+0xECB4 0x73E5 #CJK UNIFIED IDEOGRAPH
+0xECB5 0xF9E4 #CJK COMPATIBILITY IDEOGRAPH
+0xECB6 0x7570 #CJK UNIFIED IDEOGRAPH
+0xECB7 0x75CD #CJK UNIFIED IDEOGRAPH
+0xECB8 0xF9E5 #CJK COMPATIBILITY IDEOGRAPH
+0xECB9 0x79FB #CJK UNIFIED IDEOGRAPH
+0xECBA 0xF9E6 #CJK COMPATIBILITY IDEOGRAPH
+0xECBB 0x800C #CJK UNIFIED IDEOGRAPH
+0xECBC 0x8033 #CJK UNIFIED IDEOGRAPH
+0xECBD 0x8084 #CJK UNIFIED IDEOGRAPH
+0xECBE 0x82E1 #CJK UNIFIED IDEOGRAPH
+0xECBF 0x8351 #CJK UNIFIED IDEOGRAPH
+0xECC0 0xF9E7 #CJK COMPATIBILITY IDEOGRAPH
+0xECC1 0xF9E8 #CJK COMPATIBILITY IDEOGRAPH
+0xECC2 0x8CBD #CJK UNIFIED IDEOGRAPH
+0xECC3 0x8CB3 #CJK UNIFIED IDEOGRAPH
+0xECC4 0x9087 #CJK UNIFIED IDEOGRAPH
+0xECC5 0xF9E9 #CJK COMPATIBILITY IDEOGRAPH
+0xECC6 0xF9EA #CJK COMPATIBILITY IDEOGRAPH
+0xECC7 0x98F4 #CJK UNIFIED IDEOGRAPH
+0xECC8 0x990C #CJK UNIFIED IDEOGRAPH
+0xECC9 0xF9EB #CJK COMPATIBILITY IDEOGRAPH
+0xECCA 0xF9EC #CJK COMPATIBILITY IDEOGRAPH
+0xECCB 0x7037 #CJK UNIFIED IDEOGRAPH
+0xECCC 0x76CA #CJK UNIFIED IDEOGRAPH
+0xECCD 0x7FCA #CJK UNIFIED IDEOGRAPH
+0xECCE 0x7FCC #CJK UNIFIED IDEOGRAPH
+0xECCF 0x7FFC #CJK UNIFIED IDEOGRAPH
+0xECD0 0x8B1A #CJK UNIFIED IDEOGRAPH
+0xECD1 0x4EBA #CJK UNIFIED IDEOGRAPH
+0xECD2 0x4EC1 #CJK UNIFIED IDEOGRAPH
+0xECD3 0x5203 #CJK UNIFIED IDEOGRAPH
+0xECD4 0x5370 #CJK UNIFIED IDEOGRAPH
+0xECD5 0xF9ED #CJK COMPATIBILITY IDEOGRAPH
+0xECD6 0x54BD #CJK UNIFIED IDEOGRAPH
+0xECD7 0x56E0 #CJK UNIFIED IDEOGRAPH
+0xECD8 0x59FB #CJK UNIFIED IDEOGRAPH
+0xECD9 0x5BC5 #CJK UNIFIED IDEOGRAPH
+0xECDA 0x5F15 #CJK UNIFIED IDEOGRAPH
+0xECDB 0x5FCD #CJK UNIFIED IDEOGRAPH
+0xECDC 0x6E6E #CJK UNIFIED IDEOGRAPH
+0xECDD 0xF9EE #CJK COMPATIBILITY IDEOGRAPH
+0xECDE 0xF9EF #CJK COMPATIBILITY IDEOGRAPH
+0xECDF 0x7D6A #CJK UNIFIED IDEOGRAPH
+0xECE0 0x8335 #CJK UNIFIED IDEOGRAPH
+0xECE1 0xF9F0 #CJK COMPATIBILITY IDEOGRAPH
+0xECE2 0x8693 #CJK UNIFIED IDEOGRAPH
+0xECE3 0x8A8D #CJK UNIFIED IDEOGRAPH
+0xECE4 0xF9F1 #CJK COMPATIBILITY IDEOGRAPH
+0xECE5 0x976D #CJK UNIFIED IDEOGRAPH
+0xECE6 0x9777 #CJK UNIFIED IDEOGRAPH
+0xECE7 0xF9F2 #CJK COMPATIBILITY IDEOGRAPH
+0xECE8 0xF9F3 #CJK COMPATIBILITY IDEOGRAPH
+0xECE9 0x4E00 #CJK UNIFIED IDEOGRAPH
+0xECEA 0x4F5A #CJK UNIFIED IDEOGRAPH
+0xECEB 0x4F7E #CJK UNIFIED IDEOGRAPH
+0xECEC 0x58F9 #CJK UNIFIED IDEOGRAPH
+0xECED 0x65E5 #CJK UNIFIED IDEOGRAPH
+0xECEE 0x6EA2 #CJK UNIFIED IDEOGRAPH
+0xECEF 0x9038 #CJK UNIFIED IDEOGRAPH
+0xECF0 0x93B0 #CJK UNIFIED IDEOGRAPH
+0xECF1 0x99B9 #CJK UNIFIED IDEOGRAPH
+0xECF2 0x4EFB #CJK UNIFIED IDEOGRAPH
+0xECF3 0x58EC #CJK UNIFIED IDEOGRAPH
+0xECF4 0x598A #CJK UNIFIED IDEOGRAPH
+0xECF5 0x59D9 #CJK UNIFIED IDEOGRAPH
+0xECF6 0x6041 #CJK UNIFIED IDEOGRAPH
+0xECF7 0xF9F4 #CJK COMPATIBILITY IDEOGRAPH
+0xECF8 0xF9F5 #CJK COMPATIBILITY IDEOGRAPH
+0xECF9 0x7A14 #CJK UNIFIED IDEOGRAPH
+0xECFA 0xF9F6 #CJK COMPATIBILITY IDEOGRAPH
+0xECFB 0x834F #CJK UNIFIED IDEOGRAPH
+0xECFC 0x8CC3 #CJK UNIFIED IDEOGRAPH
+0xECFD 0x5165 #CJK UNIFIED IDEOGRAPH
+0xECFE 0x5344 #CJK UNIFIED IDEOGRAPH
+0xEDA1 0xF9F7 #CJK COMPATIBILITY IDEOGRAPH
+0xEDA2 0xF9F8 #CJK COMPATIBILITY IDEOGRAPH
+0xEDA3 0xF9F9 #CJK COMPATIBILITY IDEOGRAPH
+0xEDA4 0x4ECD #CJK UNIFIED IDEOGRAPH
+0xEDA5 0x5269 #CJK UNIFIED IDEOGRAPH
+0xEDA6 0x5B55 #CJK UNIFIED IDEOGRAPH
+0xEDA7 0x82BF #CJK UNIFIED IDEOGRAPH
+0xEDA8 0x4ED4 #CJK UNIFIED IDEOGRAPH
+0xEDA9 0x523A #CJK UNIFIED IDEOGRAPH
+0xEDAA 0x54A8 #CJK UNIFIED IDEOGRAPH
+0xEDAB 0x59C9 #CJK UNIFIED IDEOGRAPH
+0xEDAC 0x59FF #CJK UNIFIED IDEOGRAPH
+0xEDAD 0x5B50 #CJK UNIFIED IDEOGRAPH
+0xEDAE 0x5B57 #CJK UNIFIED IDEOGRAPH
+0xEDAF 0x5B5C #CJK UNIFIED IDEOGRAPH
+0xEDB0 0x6063 #CJK UNIFIED IDEOGRAPH
+0xEDB1 0x6148 #CJK UNIFIED IDEOGRAPH
+0xEDB2 0x6ECB #CJK UNIFIED IDEOGRAPH
+0xEDB3 0x7099 #CJK UNIFIED IDEOGRAPH
+0xEDB4 0x716E #CJK UNIFIED IDEOGRAPH
+0xEDB5 0x7386 #CJK UNIFIED IDEOGRAPH
+0xEDB6 0x74F7 #CJK UNIFIED IDEOGRAPH
+0xEDB7 0x75B5 #CJK UNIFIED IDEOGRAPH
+0xEDB8 0x78C1 #CJK UNIFIED IDEOGRAPH
+0xEDB9 0x7D2B #CJK UNIFIED IDEOGRAPH
+0xEDBA 0x8005 #CJK UNIFIED IDEOGRAPH
+0xEDBB 0x81EA #CJK UNIFIED IDEOGRAPH
+0xEDBC 0x8328 #CJK UNIFIED IDEOGRAPH
+0xEDBD 0x8517 #CJK UNIFIED IDEOGRAPH
+0xEDBE 0x85C9 #CJK UNIFIED IDEOGRAPH
+0xEDBF 0x8AEE #CJK UNIFIED IDEOGRAPH
+0xEDC0 0x8CC7 #CJK UNIFIED IDEOGRAPH
+0xEDC1 0x96CC #CJK UNIFIED IDEOGRAPH
+0xEDC2 0x4F5C #CJK UNIFIED IDEOGRAPH
+0xEDC3 0x52FA #CJK UNIFIED IDEOGRAPH
+0xEDC4 0x56BC #CJK UNIFIED IDEOGRAPH
+0xEDC5 0x65AB #CJK UNIFIED IDEOGRAPH
+0xEDC6 0x6628 #CJK UNIFIED IDEOGRAPH
+0xEDC7 0x707C #CJK UNIFIED IDEOGRAPH
+0xEDC8 0x70B8 #CJK UNIFIED IDEOGRAPH
+0xEDC9 0x7235 #CJK UNIFIED IDEOGRAPH
+0xEDCA 0x7DBD #CJK UNIFIED IDEOGRAPH
+0xEDCB 0x828D #CJK UNIFIED IDEOGRAPH
+0xEDCC 0x914C #CJK UNIFIED IDEOGRAPH
+0xEDCD 0x96C0 #CJK UNIFIED IDEOGRAPH
+0xEDCE 0x9D72 #CJK UNIFIED IDEOGRAPH
+0xEDCF 0x5B71 #CJK UNIFIED IDEOGRAPH
+0xEDD0 0x68E7 #CJK UNIFIED IDEOGRAPH
+0xEDD1 0x6B98 #CJK UNIFIED IDEOGRAPH
+0xEDD2 0x6F7A #CJK UNIFIED IDEOGRAPH
+0xEDD3 0x76DE #CJK UNIFIED IDEOGRAPH
+0xEDD4 0x5C91 #CJK UNIFIED IDEOGRAPH
+0xEDD5 0x66AB #CJK UNIFIED IDEOGRAPH
+0xEDD6 0x6F5B #CJK UNIFIED IDEOGRAPH
+0xEDD7 0x7BB4 #CJK UNIFIED IDEOGRAPH
+0xEDD8 0x7C2A #CJK UNIFIED IDEOGRAPH
+0xEDD9 0x8836 #CJK UNIFIED IDEOGRAPH
+0xEDDA 0x96DC #CJK UNIFIED IDEOGRAPH
+0xEDDB 0x4E08 #CJK UNIFIED IDEOGRAPH
+0xEDDC 0x4ED7 #CJK UNIFIED IDEOGRAPH
+0xEDDD 0x5320 #CJK UNIFIED IDEOGRAPH
+0xEDDE 0x5834 #CJK UNIFIED IDEOGRAPH
+0xEDDF 0x58BB #CJK UNIFIED IDEOGRAPH
+0xEDE0 0x58EF #CJK UNIFIED IDEOGRAPH
+0xEDE1 0x596C #CJK UNIFIED IDEOGRAPH
+0xEDE2 0x5C07 #CJK UNIFIED IDEOGRAPH
+0xEDE3 0x5E33 #CJK UNIFIED IDEOGRAPH
+0xEDE4 0x5E84 #CJK UNIFIED IDEOGRAPH
+0xEDE5 0x5F35 #CJK UNIFIED IDEOGRAPH
+0xEDE6 0x638C #CJK UNIFIED IDEOGRAPH
+0xEDE7 0x66B2 #CJK UNIFIED IDEOGRAPH
+0xEDE8 0x6756 #CJK UNIFIED IDEOGRAPH
+0xEDE9 0x6A1F #CJK UNIFIED IDEOGRAPH
+0xEDEA 0x6AA3 #CJK UNIFIED IDEOGRAPH
+0xEDEB 0x6B0C #CJK UNIFIED IDEOGRAPH
+0xEDEC 0x6F3F #CJK UNIFIED IDEOGRAPH
+0xEDED 0x7246 #CJK UNIFIED IDEOGRAPH
+0xEDEE 0xF9FA #CJK COMPATIBILITY IDEOGRAPH
+0xEDEF 0x7350 #CJK UNIFIED IDEOGRAPH
+0xEDF0 0x748B #CJK UNIFIED IDEOGRAPH
+0xEDF1 0x7AE0 #CJK UNIFIED IDEOGRAPH
+0xEDF2 0x7CA7 #CJK UNIFIED IDEOGRAPH
+0xEDF3 0x8178 #CJK UNIFIED IDEOGRAPH
+0xEDF4 0x81DF #CJK UNIFIED IDEOGRAPH
+0xEDF5 0x81E7 #CJK UNIFIED IDEOGRAPH
+0xEDF6 0x838A #CJK UNIFIED IDEOGRAPH
+0xEDF7 0x846C #CJK UNIFIED IDEOGRAPH
+0xEDF8 0x8523 #CJK UNIFIED IDEOGRAPH
+0xEDF9 0x8594 #CJK UNIFIED IDEOGRAPH
+0xEDFA 0x85CF #CJK UNIFIED IDEOGRAPH
+0xEDFB 0x88DD #CJK UNIFIED IDEOGRAPH
+0xEDFC 0x8D13 #CJK UNIFIED IDEOGRAPH
+0xEDFD 0x91AC #CJK UNIFIED IDEOGRAPH
+0xEDFE 0x9577 #CJK UNIFIED IDEOGRAPH
+0xEEA1 0x969C #CJK UNIFIED IDEOGRAPH
+0xEEA2 0x518D #CJK UNIFIED IDEOGRAPH
+0xEEA3 0x54C9 #CJK UNIFIED IDEOGRAPH
+0xEEA4 0x5728 #CJK UNIFIED IDEOGRAPH
+0xEEA5 0x5BB0 #CJK UNIFIED IDEOGRAPH
+0xEEA6 0x624D #CJK UNIFIED IDEOGRAPH
+0xEEA7 0x6750 #CJK UNIFIED IDEOGRAPH
+0xEEA8 0x683D #CJK UNIFIED IDEOGRAPH
+0xEEA9 0x6893 #CJK UNIFIED IDEOGRAPH
+0xEEAA 0x6E3D #CJK UNIFIED IDEOGRAPH
+0xEEAB 0x6ED3 #CJK UNIFIED IDEOGRAPH
+0xEEAC 0x707D #CJK UNIFIED IDEOGRAPH
+0xEEAD 0x7E21 #CJK UNIFIED IDEOGRAPH
+0xEEAE 0x88C1 #CJK UNIFIED IDEOGRAPH
+0xEEAF 0x8CA1 #CJK UNIFIED IDEOGRAPH
+0xEEB0 0x8F09 #CJK UNIFIED IDEOGRAPH
+0xEEB1 0x9F4B #CJK UNIFIED IDEOGRAPH
+0xEEB2 0x9F4E #CJK UNIFIED IDEOGRAPH
+0xEEB3 0x722D #CJK UNIFIED IDEOGRAPH
+0xEEB4 0x7B8F #CJK UNIFIED IDEOGRAPH
+0xEEB5 0x8ACD #CJK UNIFIED IDEOGRAPH
+0xEEB6 0x931A #CJK UNIFIED IDEOGRAPH
+0xEEB7 0x4F47 #CJK UNIFIED IDEOGRAPH
+0xEEB8 0x4F4E #CJK UNIFIED IDEOGRAPH
+0xEEB9 0x5132 #CJK UNIFIED IDEOGRAPH
+0xEEBA 0x5480 #CJK UNIFIED IDEOGRAPH
+0xEEBB 0x59D0 #CJK UNIFIED IDEOGRAPH
+0xEEBC 0x5E95 #CJK UNIFIED IDEOGRAPH
+0xEEBD 0x62B5 #CJK UNIFIED IDEOGRAPH
+0xEEBE 0x6775 #CJK UNIFIED IDEOGRAPH
+0xEEBF 0x696E #CJK UNIFIED IDEOGRAPH
+0xEEC0 0x6A17 #CJK UNIFIED IDEOGRAPH
+0xEEC1 0x6CAE #CJK UNIFIED IDEOGRAPH
+0xEEC2 0x6E1A #CJK UNIFIED IDEOGRAPH
+0xEEC3 0x72D9 #CJK UNIFIED IDEOGRAPH
+0xEEC4 0x732A #CJK UNIFIED IDEOGRAPH
+0xEEC5 0x75BD #CJK UNIFIED IDEOGRAPH
+0xEEC6 0x7BB8 #CJK UNIFIED IDEOGRAPH
+0xEEC7 0x7D35 #CJK UNIFIED IDEOGRAPH
+0xEEC8 0x82E7 #CJK UNIFIED IDEOGRAPH
+0xEEC9 0x83F9 #CJK UNIFIED IDEOGRAPH
+0xEECA 0x8457 #CJK UNIFIED IDEOGRAPH
+0xEECB 0x85F7 #CJK UNIFIED IDEOGRAPH
+0xEECC 0x8A5B #CJK UNIFIED IDEOGRAPH
+0xEECD 0x8CAF #CJK UNIFIED IDEOGRAPH
+0xEECE 0x8E87 #CJK UNIFIED IDEOGRAPH
+0xEECF 0x9019 #CJK UNIFIED IDEOGRAPH
+0xEED0 0x90B8 #CJK UNIFIED IDEOGRAPH
+0xEED1 0x96CE #CJK UNIFIED IDEOGRAPH
+0xEED2 0x9F5F #CJK UNIFIED IDEOGRAPH
+0xEED3 0x52E3 #CJK UNIFIED IDEOGRAPH
+0xEED4 0x540A #CJK UNIFIED IDEOGRAPH
+0xEED5 0x5AE1 #CJK UNIFIED IDEOGRAPH
+0xEED6 0x5BC2 #CJK UNIFIED IDEOGRAPH
+0xEED7 0x6458 #CJK UNIFIED IDEOGRAPH
+0xEED8 0x6575 #CJK UNIFIED IDEOGRAPH
+0xEED9 0x6EF4 #CJK UNIFIED IDEOGRAPH
+0xEEDA 0x72C4 #CJK UNIFIED IDEOGRAPH
+0xEEDB 0xF9FB #CJK COMPATIBILITY IDEOGRAPH
+0xEEDC 0x7684 #CJK UNIFIED IDEOGRAPH
+0xEEDD 0x7A4D #CJK UNIFIED IDEOGRAPH
+0xEEDE 0x7B1B #CJK UNIFIED IDEOGRAPH
+0xEEDF 0x7C4D #CJK UNIFIED IDEOGRAPH
+0xEEE0 0x7E3E #CJK UNIFIED IDEOGRAPH
+0xEEE1 0x7FDF #CJK UNIFIED IDEOGRAPH
+0xEEE2 0x837B #CJK UNIFIED IDEOGRAPH
+0xEEE3 0x8B2B #CJK UNIFIED IDEOGRAPH
+0xEEE4 0x8CCA #CJK UNIFIED IDEOGRAPH
+0xEEE5 0x8D64 #CJK UNIFIED IDEOGRAPH
+0xEEE6 0x8DE1 #CJK UNIFIED IDEOGRAPH
+0xEEE7 0x8E5F #CJK UNIFIED IDEOGRAPH
+0xEEE8 0x8FEA #CJK UNIFIED IDEOGRAPH
+0xEEE9 0x8FF9 #CJK UNIFIED IDEOGRAPH
+0xEEEA 0x9069 #CJK UNIFIED IDEOGRAPH
+0xEEEB 0x93D1 #CJK UNIFIED IDEOGRAPH
+0xEEEC 0x4F43 #CJK UNIFIED IDEOGRAPH
+0xEEED 0x4F7A #CJK UNIFIED IDEOGRAPH
+0xEEEE 0x50B3 #CJK UNIFIED IDEOGRAPH
+0xEEEF 0x5168 #CJK UNIFIED IDEOGRAPH
+0xEEF0 0x5178 #CJK UNIFIED IDEOGRAPH
+0xEEF1 0x524D #CJK UNIFIED IDEOGRAPH
+0xEEF2 0x526A #CJK UNIFIED IDEOGRAPH
+0xEEF3 0x5861 #CJK UNIFIED IDEOGRAPH
+0xEEF4 0x587C #CJK UNIFIED IDEOGRAPH
+0xEEF5 0x5960 #CJK UNIFIED IDEOGRAPH
+0xEEF6 0x5C08 #CJK UNIFIED IDEOGRAPH
+0xEEF7 0x5C55 #CJK UNIFIED IDEOGRAPH
+0xEEF8 0x5EDB #CJK UNIFIED IDEOGRAPH
+0xEEF9 0x609B #CJK UNIFIED IDEOGRAPH
+0xEEFA 0x6230 #CJK UNIFIED IDEOGRAPH
+0xEEFB 0x6813 #CJK UNIFIED IDEOGRAPH
+0xEEFC 0x6BBF #CJK UNIFIED IDEOGRAPH
+0xEEFD 0x6C08 #CJK UNIFIED IDEOGRAPH
+0xEEFE 0x6FB1 #CJK UNIFIED IDEOGRAPH
+0xEFA1 0x714E #CJK UNIFIED IDEOGRAPH
+0xEFA2 0x7420 #CJK UNIFIED IDEOGRAPH
+0xEFA3 0x7530 #CJK UNIFIED IDEOGRAPH
+0xEFA4 0x7538 #CJK UNIFIED IDEOGRAPH
+0xEFA5 0x7551 #CJK UNIFIED IDEOGRAPH
+0xEFA6 0x7672 #CJK UNIFIED IDEOGRAPH
+0xEFA7 0x7B4C #CJK UNIFIED IDEOGRAPH
+0xEFA8 0x7B8B #CJK UNIFIED IDEOGRAPH
+0xEFA9 0x7BAD #CJK UNIFIED IDEOGRAPH
+0xEFAA 0x7BC6 #CJK UNIFIED IDEOGRAPH
+0xEFAB 0x7E8F #CJK UNIFIED IDEOGRAPH
+0xEFAC 0x8A6E #CJK UNIFIED IDEOGRAPH
+0xEFAD 0x8F3E #CJK UNIFIED IDEOGRAPH
+0xEFAE 0x8F49 #CJK UNIFIED IDEOGRAPH
+0xEFAF 0x923F #CJK UNIFIED IDEOGRAPH
+0xEFB0 0x9293 #CJK UNIFIED IDEOGRAPH
+0xEFB1 0x9322 #CJK UNIFIED IDEOGRAPH
+0xEFB2 0x942B #CJK UNIFIED IDEOGRAPH
+0xEFB3 0x96FB #CJK UNIFIED IDEOGRAPH
+0xEFB4 0x985A #CJK UNIFIED IDEOGRAPH
+0xEFB5 0x986B #CJK UNIFIED IDEOGRAPH
+0xEFB6 0x991E #CJK UNIFIED IDEOGRAPH
+0xEFB7 0x5207 #CJK UNIFIED IDEOGRAPH
+0xEFB8 0x622A #CJK UNIFIED IDEOGRAPH
+0xEFB9 0x6298 #CJK UNIFIED IDEOGRAPH
+0xEFBA 0x6D59 #CJK UNIFIED IDEOGRAPH
+0xEFBB 0x7664 #CJK UNIFIED IDEOGRAPH
+0xEFBC 0x7ACA #CJK UNIFIED IDEOGRAPH
+0xEFBD 0x7BC0 #CJK UNIFIED IDEOGRAPH
+0xEFBE 0x7D76 #CJK UNIFIED IDEOGRAPH
+0xEFBF 0x5360 #CJK UNIFIED IDEOGRAPH
+0xEFC0 0x5CBE #CJK UNIFIED IDEOGRAPH
+0xEFC1 0x5E97 #CJK UNIFIED IDEOGRAPH
+0xEFC2 0x6F38 #CJK UNIFIED IDEOGRAPH
+0xEFC3 0x70B9 #CJK UNIFIED IDEOGRAPH
+0xEFC4 0x7C98 #CJK UNIFIED IDEOGRAPH
+0xEFC5 0x9711 #CJK UNIFIED IDEOGRAPH
+0xEFC6 0x9B8E #CJK UNIFIED IDEOGRAPH
+0xEFC7 0x9EDE #CJK UNIFIED IDEOGRAPH
+0xEFC8 0x63A5 #CJK UNIFIED IDEOGRAPH
+0xEFC9 0x647A #CJK UNIFIED IDEOGRAPH
+0xEFCA 0x8776 #CJK UNIFIED IDEOGRAPH
+0xEFCB 0x4E01 #CJK UNIFIED IDEOGRAPH
+0xEFCC 0x4E95 #CJK UNIFIED IDEOGRAPH
+0xEFCD 0x4EAD #CJK UNIFIED IDEOGRAPH
+0xEFCE 0x505C #CJK UNIFIED IDEOGRAPH
+0xEFCF 0x5075 #CJK UNIFIED IDEOGRAPH
+0xEFD0 0x5448 #CJK UNIFIED IDEOGRAPH
+0xEFD1 0x59C3 #CJK UNIFIED IDEOGRAPH
+0xEFD2 0x5B9A #CJK UNIFIED IDEOGRAPH
+0xEFD3 0x5E40 #CJK UNIFIED IDEOGRAPH
+0xEFD4 0x5EAD #CJK UNIFIED IDEOGRAPH
+0xEFD5 0x5EF7 #CJK UNIFIED IDEOGRAPH
+0xEFD6 0x5F81 #CJK UNIFIED IDEOGRAPH
+0xEFD7 0x60C5 #CJK UNIFIED IDEOGRAPH
+0xEFD8 0x633A #CJK UNIFIED IDEOGRAPH
+0xEFD9 0x653F #CJK UNIFIED IDEOGRAPH
+0xEFDA 0x6574 #CJK UNIFIED IDEOGRAPH
+0xEFDB 0x65CC #CJK UNIFIED IDEOGRAPH
+0xEFDC 0x6676 #CJK UNIFIED IDEOGRAPH
+0xEFDD 0x6678 #CJK UNIFIED IDEOGRAPH
+0xEFDE 0x67FE #CJK UNIFIED IDEOGRAPH
+0xEFDF 0x6968 #CJK UNIFIED IDEOGRAPH
+0xEFE0 0x6A89 #CJK UNIFIED IDEOGRAPH
+0xEFE1 0x6B63 #CJK UNIFIED IDEOGRAPH
+0xEFE2 0x6C40 #CJK UNIFIED IDEOGRAPH
+0xEFE3 0x6DC0 #CJK UNIFIED IDEOGRAPH
+0xEFE4 0x6DE8 #CJK UNIFIED IDEOGRAPH
+0xEFE5 0x6E1F #CJK UNIFIED IDEOGRAPH
+0xEFE6 0x6E5E #CJK UNIFIED IDEOGRAPH
+0xEFE7 0x701E #CJK UNIFIED IDEOGRAPH
+0xEFE8 0x70A1 #CJK UNIFIED IDEOGRAPH
+0xEFE9 0x738E #CJK UNIFIED IDEOGRAPH
+0xEFEA 0x73FD #CJK UNIFIED IDEOGRAPH
+0xEFEB 0x753A #CJK UNIFIED IDEOGRAPH
+0xEFEC 0x775B #CJK UNIFIED IDEOGRAPH
+0xEFED 0x7887 #CJK UNIFIED IDEOGRAPH
+0xEFEE 0x798E #CJK UNIFIED IDEOGRAPH
+0xEFEF 0x7A0B #CJK UNIFIED IDEOGRAPH
+0xEFF0 0x7A7D #CJK UNIFIED IDEOGRAPH
+0xEFF1 0x7CBE #CJK UNIFIED IDEOGRAPH
+0xEFF2 0x7D8E #CJK UNIFIED IDEOGRAPH
+0xEFF3 0x8247 #CJK UNIFIED IDEOGRAPH
+0xEFF4 0x8A02 #CJK UNIFIED IDEOGRAPH
+0xEFF5 0x8AEA #CJK UNIFIED IDEOGRAPH
+0xEFF6 0x8C9E #CJK UNIFIED IDEOGRAPH
+0xEFF7 0x912D #CJK UNIFIED IDEOGRAPH
+0xEFF8 0x914A #CJK UNIFIED IDEOGRAPH
+0xEFF9 0x91D8 #CJK UNIFIED IDEOGRAPH
+0xEFFA 0x9266 #CJK UNIFIED IDEOGRAPH
+0xEFFB 0x92CC #CJK UNIFIED IDEOGRAPH
+0xEFFC 0x9320 #CJK UNIFIED IDEOGRAPH
+0xEFFD 0x9706 #CJK UNIFIED IDEOGRAPH
+0xEFFE 0x9756 #CJK UNIFIED IDEOGRAPH
+0xF0A1 0x975C #CJK UNIFIED IDEOGRAPH
+0xF0A2 0x9802 #CJK UNIFIED IDEOGRAPH
+0xF0A3 0x9F0E #CJK UNIFIED IDEOGRAPH
+0xF0A4 0x5236 #CJK UNIFIED IDEOGRAPH
+0xF0A5 0x5291 #CJK UNIFIED IDEOGRAPH
+0xF0A6 0x557C #CJK UNIFIED IDEOGRAPH
+0xF0A7 0x5824 #CJK UNIFIED IDEOGRAPH
+0xF0A8 0x5E1D #CJK UNIFIED IDEOGRAPH
+0xF0A9 0x5F1F #CJK UNIFIED IDEOGRAPH
+0xF0AA 0x608C #CJK UNIFIED IDEOGRAPH
+0xF0AB 0x63D0 #CJK UNIFIED IDEOGRAPH
+0xF0AC 0x68AF #CJK UNIFIED IDEOGRAPH
+0xF0AD 0x6FDF #CJK UNIFIED IDEOGRAPH
+0xF0AE 0x796D #CJK UNIFIED IDEOGRAPH
+0xF0AF 0x7B2C #CJK UNIFIED IDEOGRAPH
+0xF0B0 0x81CD #CJK UNIFIED IDEOGRAPH
+0xF0B1 0x85BA #CJK UNIFIED IDEOGRAPH
+0xF0B2 0x88FD #CJK UNIFIED IDEOGRAPH
+0xF0B3 0x8AF8 #CJK UNIFIED IDEOGRAPH
+0xF0B4 0x8E44 #CJK UNIFIED IDEOGRAPH
+0xF0B5 0x918D #CJK UNIFIED IDEOGRAPH
+0xF0B6 0x9664 #CJK UNIFIED IDEOGRAPH
+0xF0B7 0x969B #CJK UNIFIED IDEOGRAPH
+0xF0B8 0x973D #CJK UNIFIED IDEOGRAPH
+0xF0B9 0x984C #CJK UNIFIED IDEOGRAPH
+0xF0BA 0x9F4A #CJK UNIFIED IDEOGRAPH
+0xF0BB 0x4FCE #CJK UNIFIED IDEOGRAPH
+0xF0BC 0x5146 #CJK UNIFIED IDEOGRAPH
+0xF0BD 0x51CB #CJK UNIFIED IDEOGRAPH
+0xF0BE 0x52A9 #CJK UNIFIED IDEOGRAPH
+0xF0BF 0x5632 #CJK UNIFIED IDEOGRAPH
+0xF0C0 0x5F14 #CJK UNIFIED IDEOGRAPH
+0xF0C1 0x5F6B #CJK UNIFIED IDEOGRAPH
+0xF0C2 0x63AA #CJK UNIFIED IDEOGRAPH
+0xF0C3 0x64CD #CJK UNIFIED IDEOGRAPH
+0xF0C4 0x65E9 #CJK UNIFIED IDEOGRAPH
+0xF0C5 0x6641 #CJK UNIFIED IDEOGRAPH
+0xF0C6 0x66FA #CJK UNIFIED IDEOGRAPH
+0xF0C7 0x66F9 #CJK UNIFIED IDEOGRAPH
+0xF0C8 0x671D #CJK UNIFIED IDEOGRAPH
+0xF0C9 0x689D #CJK UNIFIED IDEOGRAPH
+0xF0CA 0x68D7 #CJK UNIFIED IDEOGRAPH
+0xF0CB 0x69FD #CJK UNIFIED IDEOGRAPH
+0xF0CC 0x6F15 #CJK UNIFIED IDEOGRAPH
+0xF0CD 0x6F6E #CJK UNIFIED IDEOGRAPH
+0xF0CE 0x7167 #CJK UNIFIED IDEOGRAPH
+0xF0CF 0x71E5 #CJK UNIFIED IDEOGRAPH
+0xF0D0 0x722A #CJK UNIFIED IDEOGRAPH
+0xF0D1 0x74AA #CJK UNIFIED IDEOGRAPH
+0xF0D2 0x773A #CJK UNIFIED IDEOGRAPH
+0xF0D3 0x7956 #CJK UNIFIED IDEOGRAPH
+0xF0D4 0x795A #CJK UNIFIED IDEOGRAPH
+0xF0D5 0x79DF #CJK UNIFIED IDEOGRAPH
+0xF0D6 0x7A20 #CJK UNIFIED IDEOGRAPH
+0xF0D7 0x7A95 #CJK UNIFIED IDEOGRAPH
+0xF0D8 0x7C97 #CJK UNIFIED IDEOGRAPH
+0xF0D9 0x7CDF #CJK UNIFIED IDEOGRAPH
+0xF0DA 0x7D44 #CJK UNIFIED IDEOGRAPH
+0xF0DB 0x7E70 #CJK UNIFIED IDEOGRAPH
+0xF0DC 0x8087 #CJK UNIFIED IDEOGRAPH
+0xF0DD 0x85FB #CJK UNIFIED IDEOGRAPH
+0xF0DE 0x86A4 #CJK UNIFIED IDEOGRAPH
+0xF0DF 0x8A54 #CJK UNIFIED IDEOGRAPH
+0xF0E0 0x8ABF #CJK UNIFIED IDEOGRAPH
+0xF0E1 0x8D99 #CJK UNIFIED IDEOGRAPH
+0xF0E2 0x8E81 #CJK UNIFIED IDEOGRAPH
+0xF0E3 0x9020 #CJK UNIFIED IDEOGRAPH
+0xF0E4 0x906D #CJK UNIFIED IDEOGRAPH
+0xF0E5 0x91E3 #CJK UNIFIED IDEOGRAPH
+0xF0E6 0x963B #CJK UNIFIED IDEOGRAPH
+0xF0E7 0x96D5 #CJK UNIFIED IDEOGRAPH
+0xF0E8 0x9CE5 #CJK UNIFIED IDEOGRAPH
+0xF0E9 0x65CF #CJK UNIFIED IDEOGRAPH
+0xF0EA 0x7C07 #CJK UNIFIED IDEOGRAPH
+0xF0EB 0x8DB3 #CJK UNIFIED IDEOGRAPH
+0xF0EC 0x93C3 #CJK UNIFIED IDEOGRAPH
+0xF0ED 0x5B58 #CJK UNIFIED IDEOGRAPH
+0xF0EE 0x5C0A #CJK UNIFIED IDEOGRAPH
+0xF0EF 0x5352 #CJK UNIFIED IDEOGRAPH
+0xF0F0 0x62D9 #CJK UNIFIED IDEOGRAPH
+0xF0F1 0x731D #CJK UNIFIED IDEOGRAPH
+0xF0F2 0x5027 #CJK UNIFIED IDEOGRAPH
+0xF0F3 0x5B97 #CJK UNIFIED IDEOGRAPH
+0xF0F4 0x5F9E #CJK UNIFIED IDEOGRAPH
+0xF0F5 0x60B0 #CJK UNIFIED IDEOGRAPH
+0xF0F6 0x616B #CJK UNIFIED IDEOGRAPH
+0xF0F7 0x68D5 #CJK UNIFIED IDEOGRAPH
+0xF0F8 0x6DD9 #CJK UNIFIED IDEOGRAPH
+0xF0F9 0x742E #CJK UNIFIED IDEOGRAPH
+0xF0FA 0x7A2E #CJK UNIFIED IDEOGRAPH
+0xF0FB 0x7D42 #CJK UNIFIED IDEOGRAPH
+0xF0FC 0x7D9C #CJK UNIFIED IDEOGRAPH
+0xF0FD 0x7E31 #CJK UNIFIED IDEOGRAPH
+0xF0FE 0x816B #CJK UNIFIED IDEOGRAPH
+0xF1A1 0x8E2A #CJK UNIFIED IDEOGRAPH
+0xF1A2 0x8E35 #CJK UNIFIED IDEOGRAPH
+0xF1A3 0x937E #CJK UNIFIED IDEOGRAPH
+0xF1A4 0x9418 #CJK UNIFIED IDEOGRAPH
+0xF1A5 0x4F50 #CJK UNIFIED IDEOGRAPH
+0xF1A6 0x5750 #CJK UNIFIED IDEOGRAPH
+0xF1A7 0x5DE6 #CJK UNIFIED IDEOGRAPH
+0xF1A8 0x5EA7 #CJK UNIFIED IDEOGRAPH
+0xF1A9 0x632B #CJK UNIFIED IDEOGRAPH
+0xF1AA 0x7F6A #CJK UNIFIED IDEOGRAPH
+0xF1AB 0x4E3B #CJK UNIFIED IDEOGRAPH
+0xF1AC 0x4F4F #CJK UNIFIED IDEOGRAPH
+0xF1AD 0x4F8F #CJK UNIFIED IDEOGRAPH
+0xF1AE 0x505A #CJK UNIFIED IDEOGRAPH
+0xF1AF 0x59DD #CJK UNIFIED IDEOGRAPH
+0xF1B0 0x80C4 #CJK UNIFIED IDEOGRAPH
+0xF1B1 0x546A #CJK UNIFIED IDEOGRAPH
+0xF1B2 0x5468 #CJK UNIFIED IDEOGRAPH
+0xF1B3 0x55FE #CJK UNIFIED IDEOGRAPH
+0xF1B4 0x594F #CJK UNIFIED IDEOGRAPH
+0xF1B5 0x5B99 #CJK UNIFIED IDEOGRAPH
+0xF1B6 0x5DDE #CJK UNIFIED IDEOGRAPH
+0xF1B7 0x5EDA #CJK UNIFIED IDEOGRAPH
+0xF1B8 0x665D #CJK UNIFIED IDEOGRAPH
+0xF1B9 0x6731 #CJK UNIFIED IDEOGRAPH
+0xF1BA 0x67F1 #CJK UNIFIED IDEOGRAPH
+0xF1BB 0x682A #CJK UNIFIED IDEOGRAPH
+0xF1BC 0x6CE8 #CJK UNIFIED IDEOGRAPH
+0xF1BD 0x6D32 #CJK UNIFIED IDEOGRAPH
+0xF1BE 0x6E4A #CJK UNIFIED IDEOGRAPH
+0xF1BF 0x6F8D #CJK UNIFIED IDEOGRAPH
+0xF1C0 0x70B7 #CJK UNIFIED IDEOGRAPH
+0xF1C1 0x73E0 #CJK UNIFIED IDEOGRAPH
+0xF1C2 0x7587 #CJK UNIFIED IDEOGRAPH
+0xF1C3 0x7C4C #CJK UNIFIED IDEOGRAPH
+0xF1C4 0x7D02 #CJK UNIFIED IDEOGRAPH
+0xF1C5 0x7D2C #CJK UNIFIED IDEOGRAPH
+0xF1C6 0x7DA2 #CJK UNIFIED IDEOGRAPH
+0xF1C7 0x821F #CJK UNIFIED IDEOGRAPH
+0xF1C8 0x86DB #CJK UNIFIED IDEOGRAPH
+0xF1C9 0x8A3B #CJK UNIFIED IDEOGRAPH
+0xF1CA 0x8A85 #CJK UNIFIED IDEOGRAPH
+0xF1CB 0x8D70 #CJK UNIFIED IDEOGRAPH
+0xF1CC 0x8E8A #CJK UNIFIED IDEOGRAPH
+0xF1CD 0x8F33 #CJK UNIFIED IDEOGRAPH
+0xF1CE 0x9031 #CJK UNIFIED IDEOGRAPH
+0xF1CF 0x914E #CJK UNIFIED IDEOGRAPH
+0xF1D0 0x9152 #CJK UNIFIED IDEOGRAPH
+0xF1D1 0x9444 #CJK UNIFIED IDEOGRAPH
+0xF1D2 0x99D0 #CJK UNIFIED IDEOGRAPH
+0xF1D3 0x7AF9 #CJK UNIFIED IDEOGRAPH
+0xF1D4 0x7CA5 #CJK UNIFIED IDEOGRAPH
+0xF1D5 0x4FCA #CJK UNIFIED IDEOGRAPH
+0xF1D6 0x5101 #CJK UNIFIED IDEOGRAPH
+0xF1D7 0x51C6 #CJK UNIFIED IDEOGRAPH
+0xF1D8 0x57C8 #CJK UNIFIED IDEOGRAPH
+0xF1D9 0x5BEF #CJK UNIFIED IDEOGRAPH
+0xF1DA 0x5CFB #CJK UNIFIED IDEOGRAPH
+0xF1DB 0x6659 #CJK UNIFIED IDEOGRAPH
+0xF1DC 0x6A3D #CJK UNIFIED IDEOGRAPH
+0xF1DD 0x6D5A #CJK UNIFIED IDEOGRAPH
+0xF1DE 0x6E96 #CJK UNIFIED IDEOGRAPH
+0xF1DF 0x6FEC #CJK UNIFIED IDEOGRAPH
+0xF1E0 0x710C #CJK UNIFIED IDEOGRAPH
+0xF1E1 0x756F #CJK UNIFIED IDEOGRAPH
+0xF1E2 0x7AE3 #CJK UNIFIED IDEOGRAPH
+0xF1E3 0x8822 #CJK UNIFIED IDEOGRAPH
+0xF1E4 0x9021 #CJK UNIFIED IDEOGRAPH
+0xF1E5 0x9075 #CJK UNIFIED IDEOGRAPH
+0xF1E6 0x96CB #CJK UNIFIED IDEOGRAPH
+0xF1E7 0x99FF #CJK UNIFIED IDEOGRAPH
+0xF1E8 0x8301 #CJK UNIFIED IDEOGRAPH
+0xF1E9 0x4E2D #CJK UNIFIED IDEOGRAPH
+0xF1EA 0x4EF2 #CJK UNIFIED IDEOGRAPH
+0xF1EB 0x8846 #CJK UNIFIED IDEOGRAPH
+0xF1EC 0x91CD #CJK UNIFIED IDEOGRAPH
+0xF1ED 0x537D #CJK UNIFIED IDEOGRAPH
+0xF1EE 0x6ADB #CJK UNIFIED IDEOGRAPH
+0xF1EF 0x696B #CJK UNIFIED IDEOGRAPH
+0xF1F0 0x6C41 #CJK UNIFIED IDEOGRAPH
+0xF1F1 0x847A #CJK UNIFIED IDEOGRAPH
+0xF1F2 0x589E #CJK UNIFIED IDEOGRAPH
+0xF1F3 0x618E #CJK UNIFIED IDEOGRAPH
+0xF1F4 0x66FE #CJK UNIFIED IDEOGRAPH
+0xF1F5 0x62EF #CJK UNIFIED IDEOGRAPH
+0xF1F6 0x70DD #CJK UNIFIED IDEOGRAPH
+0xF1F7 0x7511 #CJK UNIFIED IDEOGRAPH
+0xF1F8 0x75C7 #CJK UNIFIED IDEOGRAPH
+0xF1F9 0x7E52 #CJK UNIFIED IDEOGRAPH
+0xF1FA 0x84B8 #CJK UNIFIED IDEOGRAPH
+0xF1FB 0x8B49 #CJK UNIFIED IDEOGRAPH
+0xF1FC 0x8D08 #CJK UNIFIED IDEOGRAPH
+0xF1FD 0x4E4B #CJK UNIFIED IDEOGRAPH
+0xF1FE 0x53EA #CJK UNIFIED IDEOGRAPH
+0xF2A1 0x54AB #CJK UNIFIED IDEOGRAPH
+0xF2A2 0x5730 #CJK UNIFIED IDEOGRAPH
+0xF2A3 0x5740 #CJK UNIFIED IDEOGRAPH
+0xF2A4 0x5FD7 #CJK UNIFIED IDEOGRAPH
+0xF2A5 0x6301 #CJK UNIFIED IDEOGRAPH
+0xF2A6 0x6307 #CJK UNIFIED IDEOGRAPH
+0xF2A7 0x646F #CJK UNIFIED IDEOGRAPH
+0xF2A8 0x652F #CJK UNIFIED IDEOGRAPH
+0xF2A9 0x65E8 #CJK UNIFIED IDEOGRAPH
+0xF2AA 0x667A #CJK UNIFIED IDEOGRAPH
+0xF2AB 0x679D #CJK UNIFIED IDEOGRAPH
+0xF2AC 0x67B3 #CJK UNIFIED IDEOGRAPH
+0xF2AD 0x6B62 #CJK UNIFIED IDEOGRAPH
+0xF2AE 0x6C60 #CJK UNIFIED IDEOGRAPH
+0xF2AF 0x6C9A #CJK UNIFIED IDEOGRAPH
+0xF2B0 0x6F2C #CJK UNIFIED IDEOGRAPH
+0xF2B1 0x77E5 #CJK UNIFIED IDEOGRAPH
+0xF2B2 0x7825 #CJK UNIFIED IDEOGRAPH
+0xF2B3 0x7949 #CJK UNIFIED IDEOGRAPH
+0xF2B4 0x7957 #CJK UNIFIED IDEOGRAPH
+0xF2B5 0x7D19 #CJK UNIFIED IDEOGRAPH
+0xF2B6 0x80A2 #CJK UNIFIED IDEOGRAPH
+0xF2B7 0x8102 #CJK UNIFIED IDEOGRAPH
+0xF2B8 0x81F3 #CJK UNIFIED IDEOGRAPH
+0xF2B9 0x829D #CJK UNIFIED IDEOGRAPH
+0xF2BA 0x82B7 #CJK UNIFIED IDEOGRAPH
+0xF2BB 0x8718 #CJK UNIFIED IDEOGRAPH
+0xF2BC 0x8A8C #CJK UNIFIED IDEOGRAPH
+0xF2BD 0xF9FC #CJK COMPATIBILITY IDEOGRAPH
+0xF2BE 0x8D04 #CJK UNIFIED IDEOGRAPH
+0xF2BF 0x8DBE #CJK UNIFIED IDEOGRAPH
+0xF2C0 0x9072 #CJK UNIFIED IDEOGRAPH
+0xF2C1 0x76F4 #CJK UNIFIED IDEOGRAPH
+0xF2C2 0x7A19 #CJK UNIFIED IDEOGRAPH
+0xF2C3 0x7A37 #CJK UNIFIED IDEOGRAPH
+0xF2C4 0x7E54 #CJK UNIFIED IDEOGRAPH
+0xF2C5 0x8077 #CJK UNIFIED IDEOGRAPH
+0xF2C6 0x5507 #CJK UNIFIED IDEOGRAPH
+0xF2C7 0x55D4 #CJK UNIFIED IDEOGRAPH
+0xF2C8 0x5875 #CJK UNIFIED IDEOGRAPH
+0xF2C9 0x632F #CJK UNIFIED IDEOGRAPH
+0xF2CA 0x6422 #CJK UNIFIED IDEOGRAPH
+0xF2CB 0x6649 #CJK UNIFIED IDEOGRAPH
+0xF2CC 0x664B #CJK UNIFIED IDEOGRAPH
+0xF2CD 0x686D #CJK UNIFIED IDEOGRAPH
+0xF2CE 0x699B #CJK UNIFIED IDEOGRAPH
+0xF2CF 0x6B84 #CJK UNIFIED IDEOGRAPH
+0xF2D0 0x6D25 #CJK UNIFIED IDEOGRAPH
+0xF2D1 0x6EB1 #CJK UNIFIED IDEOGRAPH
+0xF2D2 0x73CD #CJK UNIFIED IDEOGRAPH
+0xF2D3 0x7468 #CJK UNIFIED IDEOGRAPH
+0xF2D4 0x74A1 #CJK UNIFIED IDEOGRAPH
+0xF2D5 0x755B #CJK UNIFIED IDEOGRAPH
+0xF2D6 0x75B9 #CJK UNIFIED IDEOGRAPH
+0xF2D7 0x76E1 #CJK UNIFIED IDEOGRAPH
+0xF2D8 0x771E #CJK UNIFIED IDEOGRAPH
+0xF2D9 0x778B #CJK UNIFIED IDEOGRAPH
+0xF2DA 0x79E6 #CJK UNIFIED IDEOGRAPH
+0xF2DB 0x7E09 #CJK UNIFIED IDEOGRAPH
+0xF2DC 0x7E1D #CJK UNIFIED IDEOGRAPH
+0xF2DD 0x81FB #CJK UNIFIED IDEOGRAPH
+0xF2DE 0x852F #CJK UNIFIED IDEOGRAPH
+0xF2DF 0x8897 #CJK UNIFIED IDEOGRAPH
+0xF2E0 0x8A3A #CJK UNIFIED IDEOGRAPH
+0xF2E1 0x8CD1 #CJK UNIFIED IDEOGRAPH
+0xF2E2 0x8EEB #CJK UNIFIED IDEOGRAPH
+0xF2E3 0x8FB0 #CJK UNIFIED IDEOGRAPH
+0xF2E4 0x9032 #CJK UNIFIED IDEOGRAPH
+0xF2E5 0x93AD #CJK UNIFIED IDEOGRAPH
+0xF2E6 0x9663 #CJK UNIFIED IDEOGRAPH
+0xF2E7 0x9673 #CJK UNIFIED IDEOGRAPH
+0xF2E8 0x9707 #CJK UNIFIED IDEOGRAPH
+0xF2E9 0x4F84 #CJK UNIFIED IDEOGRAPH
+0xF2EA 0x53F1 #CJK UNIFIED IDEOGRAPH
+0xF2EB 0x59EA #CJK UNIFIED IDEOGRAPH
+0xF2EC 0x5AC9 #CJK UNIFIED IDEOGRAPH
+0xF2ED 0x5E19 #CJK UNIFIED IDEOGRAPH
+0xF2EE 0x684E #CJK UNIFIED IDEOGRAPH
+0xF2EF 0x74C6 #CJK UNIFIED IDEOGRAPH
+0xF2F0 0x75BE #CJK UNIFIED IDEOGRAPH
+0xF2F1 0x79E9 #CJK UNIFIED IDEOGRAPH
+0xF2F2 0x7A92 #CJK UNIFIED IDEOGRAPH
+0xF2F3 0x81A3 #CJK UNIFIED IDEOGRAPH
+0xF2F4 0x86ED #CJK UNIFIED IDEOGRAPH
+0xF2F5 0x8CEA #CJK UNIFIED IDEOGRAPH
+0xF2F6 0x8DCC #CJK UNIFIED IDEOGRAPH
+0xF2F7 0x8FED #CJK UNIFIED IDEOGRAPH
+0xF2F8 0x659F #CJK UNIFIED IDEOGRAPH
+0xF2F9 0x6715 #CJK UNIFIED IDEOGRAPH
+0xF2FA 0xF9FD #CJK COMPATIBILITY IDEOGRAPH
+0xF2FB 0x57F7 #CJK UNIFIED IDEOGRAPH
+0xF2FC 0x6F57 #CJK UNIFIED IDEOGRAPH
+0xF2FD 0x7DDD #CJK UNIFIED IDEOGRAPH
+0xF2FE 0x8F2F #CJK UNIFIED IDEOGRAPH
+0xF3A1 0x93F6 #CJK UNIFIED IDEOGRAPH
+0xF3A2 0x96C6 #CJK UNIFIED IDEOGRAPH
+0xF3A3 0x5FB5 #CJK UNIFIED IDEOGRAPH
+0xF3A4 0x61F2 #CJK UNIFIED IDEOGRAPH
+0xF3A5 0x6F84 #CJK UNIFIED IDEOGRAPH
+0xF3A6 0x4E14 #CJK UNIFIED IDEOGRAPH
+0xF3A7 0x4F98 #CJK UNIFIED IDEOGRAPH
+0xF3A8 0x501F #CJK UNIFIED IDEOGRAPH
+0xF3A9 0x53C9 #CJK UNIFIED IDEOGRAPH
+0xF3AA 0x55DF #CJK UNIFIED IDEOGRAPH
+0xF3AB 0x5D6F #CJK UNIFIED IDEOGRAPH
+0xF3AC 0x5DEE #CJK UNIFIED IDEOGRAPH
+0xF3AD 0x6B21 #CJK UNIFIED IDEOGRAPH
+0xF3AE 0x6B64 #CJK UNIFIED IDEOGRAPH
+0xF3AF 0x78CB #CJK UNIFIED IDEOGRAPH
+0xF3B0 0x7B9A #CJK UNIFIED IDEOGRAPH
+0xF3B1 0xF9FE #CJK COMPATIBILITY IDEOGRAPH
+0xF3B2 0x8E49 #CJK UNIFIED IDEOGRAPH
+0xF3B3 0x8ECA #CJK UNIFIED IDEOGRAPH
+0xF3B4 0x906E #CJK UNIFIED IDEOGRAPH
+0xF3B5 0x6349 #CJK UNIFIED IDEOGRAPH
+0xF3B6 0x643E #CJK UNIFIED IDEOGRAPH
+0xF3B7 0x7740 #CJK UNIFIED IDEOGRAPH
+0xF3B8 0x7A84 #CJK UNIFIED IDEOGRAPH
+0xF3B9 0x932F #CJK UNIFIED IDEOGRAPH
+0xF3BA 0x947F #CJK UNIFIED IDEOGRAPH
+0xF3BB 0x9F6A #CJK UNIFIED IDEOGRAPH
+0xF3BC 0x64B0 #CJK UNIFIED IDEOGRAPH
+0xF3BD 0x6FAF #CJK UNIFIED IDEOGRAPH
+0xF3BE 0x71E6 #CJK UNIFIED IDEOGRAPH
+0xF3BF 0x74A8 #CJK UNIFIED IDEOGRAPH
+0xF3C0 0x74DA #CJK UNIFIED IDEOGRAPH
+0xF3C1 0x7AC4 #CJK UNIFIED IDEOGRAPH
+0xF3C2 0x7C12 #CJK UNIFIED IDEOGRAPH
+0xF3C3 0x7E82 #CJK UNIFIED IDEOGRAPH
+0xF3C4 0x7CB2 #CJK UNIFIED IDEOGRAPH
+0xF3C5 0x7E98 #CJK UNIFIED IDEOGRAPH
+0xF3C6 0x8B9A #CJK UNIFIED IDEOGRAPH
+0xF3C7 0x8D0A #CJK UNIFIED IDEOGRAPH
+0xF3C8 0x947D #CJK UNIFIED IDEOGRAPH
+0xF3C9 0x9910 #CJK UNIFIED IDEOGRAPH
+0xF3CA 0x994C #CJK UNIFIED IDEOGRAPH
+0xF3CB 0x5239 #CJK UNIFIED IDEOGRAPH
+0xF3CC 0x5BDF #CJK UNIFIED IDEOGRAPH
+0xF3CD 0x64E6 #CJK UNIFIED IDEOGRAPH
+0xF3CE 0x672D #CJK UNIFIED IDEOGRAPH
+0xF3CF 0x7D2E #CJK UNIFIED IDEOGRAPH
+0xF3D0 0x50ED #CJK UNIFIED IDEOGRAPH
+0xF3D1 0x53C3 #CJK UNIFIED IDEOGRAPH
+0xF3D2 0x5879 #CJK UNIFIED IDEOGRAPH
+0xF3D3 0x6158 #CJK UNIFIED IDEOGRAPH
+0xF3D4 0x6159 #CJK UNIFIED IDEOGRAPH
+0xF3D5 0x61FA #CJK UNIFIED IDEOGRAPH
+0xF3D6 0x65AC #CJK UNIFIED IDEOGRAPH
+0xF3D7 0x7AD9 #CJK UNIFIED IDEOGRAPH
+0xF3D8 0x8B92 #CJK UNIFIED IDEOGRAPH
+0xF3D9 0x8B96 #CJK UNIFIED IDEOGRAPH
+0xF3DA 0x5009 #CJK UNIFIED IDEOGRAPH
+0xF3DB 0x5021 #CJK UNIFIED IDEOGRAPH
+0xF3DC 0x5275 #CJK UNIFIED IDEOGRAPH
+0xF3DD 0x5531 #CJK UNIFIED IDEOGRAPH
+0xF3DE 0x5A3C #CJK UNIFIED IDEOGRAPH
+0xF3DF 0x5EE0 #CJK UNIFIED IDEOGRAPH
+0xF3E0 0x5F70 #CJK UNIFIED IDEOGRAPH
+0xF3E1 0x6134 #CJK UNIFIED IDEOGRAPH
+0xF3E2 0x655E #CJK UNIFIED IDEOGRAPH
+0xF3E3 0x660C #CJK UNIFIED IDEOGRAPH
+0xF3E4 0x6636 #CJK UNIFIED IDEOGRAPH
+0xF3E5 0x66A2 #CJK UNIFIED IDEOGRAPH
+0xF3E6 0x69CD #CJK UNIFIED IDEOGRAPH
+0xF3E7 0x6EC4 #CJK UNIFIED IDEOGRAPH
+0xF3E8 0x6F32 #CJK UNIFIED IDEOGRAPH
+0xF3E9 0x7316 #CJK UNIFIED IDEOGRAPH
+0xF3EA 0x7621 #CJK UNIFIED IDEOGRAPH
+0xF3EB 0x7A93 #CJK UNIFIED IDEOGRAPH
+0xF3EC 0x8139 #CJK UNIFIED IDEOGRAPH
+0xF3ED 0x8259 #CJK UNIFIED IDEOGRAPH
+0xF3EE 0x83D6 #CJK UNIFIED IDEOGRAPH
+0xF3EF 0x84BC #CJK UNIFIED IDEOGRAPH
+0xF3F0 0x50B5 #CJK UNIFIED IDEOGRAPH
+0xF3F1 0x57F0 #CJK UNIFIED IDEOGRAPH
+0xF3F2 0x5BC0 #CJK UNIFIED IDEOGRAPH
+0xF3F3 0x5BE8 #CJK UNIFIED IDEOGRAPH
+0xF3F4 0x5F69 #CJK UNIFIED IDEOGRAPH
+0xF3F5 0x63A1 #CJK UNIFIED IDEOGRAPH
+0xF3F6 0x7826 #CJK UNIFIED IDEOGRAPH
+0xF3F7 0x7DB5 #CJK UNIFIED IDEOGRAPH
+0xF3F8 0x83DC #CJK UNIFIED IDEOGRAPH
+0xF3F9 0x8521 #CJK UNIFIED IDEOGRAPH
+0xF3FA 0x91C7 #CJK UNIFIED IDEOGRAPH
+0xF3FB 0x91F5 #CJK UNIFIED IDEOGRAPH
+0xF3FC 0x518A #CJK UNIFIED IDEOGRAPH
+0xF3FD 0x67F5 #CJK UNIFIED IDEOGRAPH
+0xF3FE 0x7B56 #CJK UNIFIED IDEOGRAPH
+0xF4A1 0x8CAC #CJK UNIFIED IDEOGRAPH
+0xF4A2 0x51C4 #CJK UNIFIED IDEOGRAPH
+0xF4A3 0x59BB #CJK UNIFIED IDEOGRAPH
+0xF4A4 0x60BD #CJK UNIFIED IDEOGRAPH
+0xF4A5 0x8655 #CJK UNIFIED IDEOGRAPH
+0xF4A6 0x501C #CJK UNIFIED IDEOGRAPH
+0xF4A7 0xF9FF #CJK COMPATIBILITY IDEOGRAPH
+0xF4A8 0x5254 #CJK UNIFIED IDEOGRAPH
+0xF4A9 0x5C3A #CJK UNIFIED IDEOGRAPH
+0xF4AA 0x617D #CJK UNIFIED IDEOGRAPH
+0xF4AB 0x621A #CJK UNIFIED IDEOGRAPH
+0xF4AC 0x62D3 #CJK UNIFIED IDEOGRAPH
+0xF4AD 0x64F2 #CJK UNIFIED IDEOGRAPH
+0xF4AE 0x65A5 #CJK UNIFIED IDEOGRAPH
+0xF4AF 0x6ECC #CJK UNIFIED IDEOGRAPH
+0xF4B0 0x7620 #CJK UNIFIED IDEOGRAPH
+0xF4B1 0x810A #CJK UNIFIED IDEOGRAPH
+0xF4B2 0x8E60 #CJK UNIFIED IDEOGRAPH
+0xF4B3 0x965F #CJK UNIFIED IDEOGRAPH
+0xF4B4 0x96BB #CJK UNIFIED IDEOGRAPH
+0xF4B5 0x4EDF #CJK UNIFIED IDEOGRAPH
+0xF4B6 0x5343 #CJK UNIFIED IDEOGRAPH
+0xF4B7 0x5598 #CJK UNIFIED IDEOGRAPH
+0xF4B8 0x5929 #CJK UNIFIED IDEOGRAPH
+0xF4B9 0x5DDD #CJK UNIFIED IDEOGRAPH
+0xF4BA 0x64C5 #CJK UNIFIED IDEOGRAPH
+0xF4BB 0x6CC9 #CJK UNIFIED IDEOGRAPH
+0xF4BC 0x6DFA #CJK UNIFIED IDEOGRAPH
+0xF4BD 0x7394 #CJK UNIFIED IDEOGRAPH
+0xF4BE 0x7A7F #CJK UNIFIED IDEOGRAPH
+0xF4BF 0x821B #CJK UNIFIED IDEOGRAPH
+0xF4C0 0x85A6 #CJK UNIFIED IDEOGRAPH
+0xF4C1 0x8CE4 #CJK UNIFIED IDEOGRAPH
+0xF4C2 0x8E10 #CJK UNIFIED IDEOGRAPH
+0xF4C3 0x9077 #CJK UNIFIED IDEOGRAPH
+0xF4C4 0x91E7 #CJK UNIFIED IDEOGRAPH
+0xF4C5 0x95E1 #CJK UNIFIED IDEOGRAPH
+0xF4C6 0x9621 #CJK UNIFIED IDEOGRAPH
+0xF4C7 0x97C6 #CJK UNIFIED IDEOGRAPH
+0xF4C8 0x51F8 #CJK UNIFIED IDEOGRAPH
+0xF4C9 0x54F2 #CJK UNIFIED IDEOGRAPH
+0xF4CA 0x5586 #CJK UNIFIED IDEOGRAPH
+0xF4CB 0x5FB9 #CJK UNIFIED IDEOGRAPH
+0xF4CC 0x64A4 #CJK UNIFIED IDEOGRAPH
+0xF4CD 0x6F88 #CJK UNIFIED IDEOGRAPH
+0xF4CE 0x7DB4 #CJK UNIFIED IDEOGRAPH
+0xF4CF 0x8F1F #CJK UNIFIED IDEOGRAPH
+0xF4D0 0x8F4D #CJK UNIFIED IDEOGRAPH
+0xF4D1 0x9435 #CJK UNIFIED IDEOGRAPH
+0xF4D2 0x50C9 #CJK UNIFIED IDEOGRAPH
+0xF4D3 0x5C16 #CJK UNIFIED IDEOGRAPH
+0xF4D4 0x6CBE #CJK UNIFIED IDEOGRAPH
+0xF4D5 0x6DFB #CJK UNIFIED IDEOGRAPH
+0xF4D6 0x751B #CJK UNIFIED IDEOGRAPH
+0xF4D7 0x77BB #CJK UNIFIED IDEOGRAPH
+0xF4D8 0x7C3D #CJK UNIFIED IDEOGRAPH
+0xF4D9 0x7C64 #CJK UNIFIED IDEOGRAPH
+0xF4DA 0x8A79 #CJK UNIFIED IDEOGRAPH
+0xF4DB 0x8AC2 #CJK UNIFIED IDEOGRAPH
+0xF4DC 0x581E #CJK UNIFIED IDEOGRAPH
+0xF4DD 0x59BE #CJK UNIFIED IDEOGRAPH
+0xF4DE 0x5E16 #CJK UNIFIED IDEOGRAPH
+0xF4DF 0x6377 #CJK UNIFIED IDEOGRAPH
+0xF4E0 0x7252 #CJK UNIFIED IDEOGRAPH
+0xF4E1 0x758A #CJK UNIFIED IDEOGRAPH
+0xF4E2 0x776B #CJK UNIFIED IDEOGRAPH
+0xF4E3 0x8ADC #CJK UNIFIED IDEOGRAPH
+0xF4E4 0x8CBC #CJK UNIFIED IDEOGRAPH
+0xF4E5 0x8F12 #CJK UNIFIED IDEOGRAPH
+0xF4E6 0x5EF3 #CJK UNIFIED IDEOGRAPH
+0xF4E7 0x6674 #CJK UNIFIED IDEOGRAPH
+0xF4E8 0x6DF8 #CJK UNIFIED IDEOGRAPH
+0xF4E9 0x807D #CJK UNIFIED IDEOGRAPH
+0xF4EA 0x83C1 #CJK UNIFIED IDEOGRAPH
+0xF4EB 0x8ACB #CJK UNIFIED IDEOGRAPH
+0xF4EC 0x9751 #CJK UNIFIED IDEOGRAPH
+0xF4ED 0x9BD6 #CJK UNIFIED IDEOGRAPH
+0xF4EE 0xFA00 #CJK COMPATIBILITY IDEOGRAPH
+0xF4EF 0x5243 #CJK UNIFIED IDEOGRAPH
+0xF4F0 0x66FF #CJK UNIFIED IDEOGRAPH
+0xF4F1 0x6D95 #CJK UNIFIED IDEOGRAPH
+0xF4F2 0x6EEF #CJK UNIFIED IDEOGRAPH
+0xF4F3 0x7DE0 #CJK UNIFIED IDEOGRAPH
+0xF4F4 0x8AE6 #CJK UNIFIED IDEOGRAPH
+0xF4F5 0x902E #CJK UNIFIED IDEOGRAPH
+0xF4F6 0x905E #CJK UNIFIED IDEOGRAPH
+0xF4F7 0x9AD4 #CJK UNIFIED IDEOGRAPH
+0xF4F8 0x521D #CJK UNIFIED IDEOGRAPH
+0xF4F9 0x527F #CJK UNIFIED IDEOGRAPH
+0xF4FA 0x54E8 #CJK UNIFIED IDEOGRAPH
+0xF4FB 0x6194 #CJK UNIFIED IDEOGRAPH
+0xF4FC 0x6284 #CJK UNIFIED IDEOGRAPH
+0xF4FD 0x62DB #CJK UNIFIED IDEOGRAPH
+0xF4FE 0x68A2 #CJK UNIFIED IDEOGRAPH
+0xF5A1 0x6912 #CJK UNIFIED IDEOGRAPH
+0xF5A2 0x695A #CJK UNIFIED IDEOGRAPH
+0xF5A3 0x6A35 #CJK UNIFIED IDEOGRAPH
+0xF5A4 0x7092 #CJK UNIFIED IDEOGRAPH
+0xF5A5 0x7126 #CJK UNIFIED IDEOGRAPH
+0xF5A6 0x785D #CJK UNIFIED IDEOGRAPH
+0xF5A7 0x7901 #CJK UNIFIED IDEOGRAPH
+0xF5A8 0x790E #CJK UNIFIED IDEOGRAPH
+0xF5A9 0x79D2 #CJK UNIFIED IDEOGRAPH
+0xF5AA 0x7A0D #CJK UNIFIED IDEOGRAPH
+0xF5AB 0x8096 #CJK UNIFIED IDEOGRAPH
+0xF5AC 0x8278 #CJK UNIFIED IDEOGRAPH
+0xF5AD 0x82D5 #CJK UNIFIED IDEOGRAPH
+0xF5AE 0x8349 #CJK UNIFIED IDEOGRAPH
+0xF5AF 0x8549 #CJK UNIFIED IDEOGRAPH
+0xF5B0 0x8C82 #CJK UNIFIED IDEOGRAPH
+0xF5B1 0x8D85 #CJK UNIFIED IDEOGRAPH
+0xF5B2 0x9162 #CJK UNIFIED IDEOGRAPH
+0xF5B3 0x918B #CJK UNIFIED IDEOGRAPH
+0xF5B4 0x91AE #CJK UNIFIED IDEOGRAPH
+0xF5B5 0x4FC3 #CJK UNIFIED IDEOGRAPH
+0xF5B6 0x56D1 #CJK UNIFIED IDEOGRAPH
+0xF5B7 0x71ED #CJK UNIFIED IDEOGRAPH
+0xF5B8 0x77D7 #CJK UNIFIED IDEOGRAPH
+0xF5B9 0x8700 #CJK UNIFIED IDEOGRAPH
+0xF5BA 0x89F8 #CJK UNIFIED IDEOGRAPH
+0xF5BB 0x5BF8 #CJK UNIFIED IDEOGRAPH
+0xF5BC 0x5FD6 #CJK UNIFIED IDEOGRAPH
+0xF5BD 0x6751 #CJK UNIFIED IDEOGRAPH
+0xF5BE 0x90A8 #CJK UNIFIED IDEOGRAPH
+0xF5BF 0x53E2 #CJK UNIFIED IDEOGRAPH
+0xF5C0 0x585A #CJK UNIFIED IDEOGRAPH
+0xF5C1 0x5BF5 #CJK UNIFIED IDEOGRAPH
+0xF5C2 0x60A4 #CJK UNIFIED IDEOGRAPH
+0xF5C3 0x6181 #CJK UNIFIED IDEOGRAPH
+0xF5C4 0x6460 #CJK UNIFIED IDEOGRAPH
+0xF5C5 0x7E3D #CJK UNIFIED IDEOGRAPH
+0xF5C6 0x8070 #CJK UNIFIED IDEOGRAPH
+0xF5C7 0x8525 #CJK UNIFIED IDEOGRAPH
+0xF5C8 0x9283 #CJK UNIFIED IDEOGRAPH
+0xF5C9 0x64AE #CJK UNIFIED IDEOGRAPH
+0xF5CA 0x50AC #CJK UNIFIED IDEOGRAPH
+0xF5CB 0x5D14 #CJK UNIFIED IDEOGRAPH
+0xF5CC 0x6700 #CJK UNIFIED IDEOGRAPH
+0xF5CD 0x589C #CJK UNIFIED IDEOGRAPH
+0xF5CE 0x62BD #CJK UNIFIED IDEOGRAPH
+0xF5CF 0x63A8 #CJK UNIFIED IDEOGRAPH
+0xF5D0 0x690E #CJK UNIFIED IDEOGRAPH
+0xF5D1 0x6978 #CJK UNIFIED IDEOGRAPH
+0xF5D2 0x6A1E #CJK UNIFIED IDEOGRAPH
+0xF5D3 0x6E6B #CJK UNIFIED IDEOGRAPH
+0xF5D4 0x76BA #CJK UNIFIED IDEOGRAPH
+0xF5D5 0x79CB #CJK UNIFIED IDEOGRAPH
+0xF5D6 0x82BB #CJK UNIFIED IDEOGRAPH
+0xF5D7 0x8429 #CJK UNIFIED IDEOGRAPH
+0xF5D8 0x8ACF #CJK UNIFIED IDEOGRAPH
+0xF5D9 0x8DA8 #CJK UNIFIED IDEOGRAPH
+0xF5DA 0x8FFD #CJK UNIFIED IDEOGRAPH
+0xF5DB 0x9112 #CJK UNIFIED IDEOGRAPH
+0xF5DC 0x914B #CJK UNIFIED IDEOGRAPH
+0xF5DD 0x919C #CJK UNIFIED IDEOGRAPH
+0xF5DE 0x9310 #CJK UNIFIED IDEOGRAPH
+0xF5DF 0x9318 #CJK UNIFIED IDEOGRAPH
+0xF5E0 0x939A #CJK UNIFIED IDEOGRAPH
+0xF5E1 0x96DB #CJK UNIFIED IDEOGRAPH
+0xF5E2 0x9A36 #CJK UNIFIED IDEOGRAPH
+0xF5E3 0x9C0D #CJK UNIFIED IDEOGRAPH
+0xF5E4 0x4E11 #CJK UNIFIED IDEOGRAPH
+0xF5E5 0x755C #CJK UNIFIED IDEOGRAPH
+0xF5E6 0x795D #CJK UNIFIED IDEOGRAPH
+0xF5E7 0x7AFA #CJK UNIFIED IDEOGRAPH
+0xF5E8 0x7B51 #CJK UNIFIED IDEOGRAPH
+0xF5E9 0x7BC9 #CJK UNIFIED IDEOGRAPH
+0xF5EA 0x7E2E #CJK UNIFIED IDEOGRAPH
+0xF5EB 0x84C4 #CJK UNIFIED IDEOGRAPH
+0xF5EC 0x8E59 #CJK UNIFIED IDEOGRAPH
+0xF5ED 0x8E74 #CJK UNIFIED IDEOGRAPH
+0xF5EE 0x8EF8 #CJK UNIFIED IDEOGRAPH
+0xF5EF 0x9010 #CJK UNIFIED IDEOGRAPH
+0xF5F0 0x6625 #CJK UNIFIED IDEOGRAPH
+0xF5F1 0x693F #CJK UNIFIED IDEOGRAPH
+0xF5F2 0x7443 #CJK UNIFIED IDEOGRAPH
+0xF5F3 0x51FA #CJK UNIFIED IDEOGRAPH
+0xF5F4 0x672E #CJK UNIFIED IDEOGRAPH
+0xF5F5 0x9EDC #CJK UNIFIED IDEOGRAPH
+0xF5F6 0x5145 #CJK UNIFIED IDEOGRAPH
+0xF5F7 0x5FE0 #CJK UNIFIED IDEOGRAPH
+0xF5F8 0x6C96 #CJK UNIFIED IDEOGRAPH
+0xF5F9 0x87F2 #CJK UNIFIED IDEOGRAPH
+0xF5FA 0x885D #CJK UNIFIED IDEOGRAPH
+0xF5FB 0x8877 #CJK UNIFIED IDEOGRAPH
+0xF5FC 0x60B4 #CJK UNIFIED IDEOGRAPH
+0xF5FD 0x81B5 #CJK UNIFIED IDEOGRAPH
+0xF5FE 0x8403 #CJK UNIFIED IDEOGRAPH
+0xF6A1 0x8D05 #CJK UNIFIED IDEOGRAPH
+0xF6A2 0x53D6 #CJK UNIFIED IDEOGRAPH
+0xF6A3 0x5439 #CJK UNIFIED IDEOGRAPH
+0xF6A4 0x5634 #CJK UNIFIED IDEOGRAPH
+0xF6A5 0x5A36 #CJK UNIFIED IDEOGRAPH
+0xF6A6 0x5C31 #CJK UNIFIED IDEOGRAPH
+0xF6A7 0x708A #CJK UNIFIED IDEOGRAPH
+0xF6A8 0x7FE0 #CJK UNIFIED IDEOGRAPH
+0xF6A9 0x805A #CJK UNIFIED IDEOGRAPH
+0xF6AA 0x8106 #CJK UNIFIED IDEOGRAPH
+0xF6AB 0x81ED #CJK UNIFIED IDEOGRAPH
+0xF6AC 0x8DA3 #CJK UNIFIED IDEOGRAPH
+0xF6AD 0x9189 #CJK UNIFIED IDEOGRAPH
+0xF6AE 0x9A5F #CJK UNIFIED IDEOGRAPH
+0xF6AF 0x9DF2 #CJK UNIFIED IDEOGRAPH
+0xF6B0 0x5074 #CJK UNIFIED IDEOGRAPH
+0xF6B1 0x4EC4 #CJK UNIFIED IDEOGRAPH
+0xF6B2 0x53A0 #CJK UNIFIED IDEOGRAPH
+0xF6B3 0x60FB #CJK UNIFIED IDEOGRAPH
+0xF6B4 0x6E2C #CJK UNIFIED IDEOGRAPH
+0xF6B5 0x5C64 #CJK UNIFIED IDEOGRAPH
+0xF6B6 0x4F88 #CJK UNIFIED IDEOGRAPH
+0xF6B7 0x5024 #CJK UNIFIED IDEOGRAPH
+0xF6B8 0x55E4 #CJK UNIFIED IDEOGRAPH
+0xF6B9 0x5CD9 #CJK UNIFIED IDEOGRAPH
+0xF6BA 0x5E5F #CJK UNIFIED IDEOGRAPH
+0xF6BB 0x6065 #CJK UNIFIED IDEOGRAPH
+0xF6BC 0x6894 #CJK UNIFIED IDEOGRAPH
+0xF6BD 0x6CBB #CJK UNIFIED IDEOGRAPH
+0xF6BE 0x6DC4 #CJK UNIFIED IDEOGRAPH
+0xF6BF 0x71BE #CJK UNIFIED IDEOGRAPH
+0xF6C0 0x75D4 #CJK UNIFIED IDEOGRAPH
+0xF6C1 0x75F4 #CJK UNIFIED IDEOGRAPH
+0xF6C2 0x7661 #CJK UNIFIED IDEOGRAPH
+0xF6C3 0x7A1A #CJK UNIFIED IDEOGRAPH
+0xF6C4 0x7A49 #CJK UNIFIED IDEOGRAPH
+0xF6C5 0x7DC7 #CJK UNIFIED IDEOGRAPH
+0xF6C6 0x7DFB #CJK UNIFIED IDEOGRAPH
+0xF6C7 0x7F6E #CJK UNIFIED IDEOGRAPH
+0xF6C8 0x81F4 #CJK UNIFIED IDEOGRAPH
+0xF6C9 0x86A9 #CJK UNIFIED IDEOGRAPH
+0xF6CA 0x8F1C #CJK UNIFIED IDEOGRAPH
+0xF6CB 0x96C9 #CJK UNIFIED IDEOGRAPH
+0xF6CC 0x99B3 #CJK UNIFIED IDEOGRAPH
+0xF6CD 0x9F52 #CJK UNIFIED IDEOGRAPH
+0xF6CE 0x5247 #CJK UNIFIED IDEOGRAPH
+0xF6CF 0x52C5 #CJK UNIFIED IDEOGRAPH
+0xF6D0 0x98ED #CJK UNIFIED IDEOGRAPH
+0xF6D1 0x89AA #CJK UNIFIED IDEOGRAPH
+0xF6D2 0x4E03 #CJK UNIFIED IDEOGRAPH
+0xF6D3 0x67D2 #CJK UNIFIED IDEOGRAPH
+0xF6D4 0x6F06 #CJK UNIFIED IDEOGRAPH
+0xF6D5 0x4FB5 #CJK UNIFIED IDEOGRAPH
+0xF6D6 0x5BE2 #CJK UNIFIED IDEOGRAPH
+0xF6D7 0x6795 #CJK UNIFIED IDEOGRAPH
+0xF6D8 0x6C88 #CJK UNIFIED IDEOGRAPH
+0xF6D9 0x6D78 #CJK UNIFIED IDEOGRAPH
+0xF6DA 0x741B #CJK UNIFIED IDEOGRAPH
+0xF6DB 0x7827 #CJK UNIFIED IDEOGRAPH
+0xF6DC 0x91DD #CJK UNIFIED IDEOGRAPH
+0xF6DD 0x937C #CJK UNIFIED IDEOGRAPH
+0xF6DE 0x87C4 #CJK UNIFIED IDEOGRAPH
+0xF6DF 0x79E4 #CJK UNIFIED IDEOGRAPH
+0xF6E0 0x7A31 #CJK UNIFIED IDEOGRAPH
+0xF6E1 0x5FEB #CJK UNIFIED IDEOGRAPH
+0xF6E2 0x4ED6 #CJK UNIFIED IDEOGRAPH
+0xF6E3 0x54A4 #CJK UNIFIED IDEOGRAPH
+0xF6E4 0x553E #CJK UNIFIED IDEOGRAPH
+0xF6E5 0x58AE #CJK UNIFIED IDEOGRAPH
+0xF6E6 0x59A5 #CJK UNIFIED IDEOGRAPH
+0xF6E7 0x60F0 #CJK UNIFIED IDEOGRAPH
+0xF6E8 0x6253 #CJK UNIFIED IDEOGRAPH
+0xF6E9 0x62D6 #CJK UNIFIED IDEOGRAPH
+0xF6EA 0x6736 #CJK UNIFIED IDEOGRAPH
+0xF6EB 0x6955 #CJK UNIFIED IDEOGRAPH
+0xF6EC 0x8235 #CJK UNIFIED IDEOGRAPH
+0xF6ED 0x9640 #CJK UNIFIED IDEOGRAPH
+0xF6EE 0x99B1 #CJK UNIFIED IDEOGRAPH
+0xF6EF 0x99DD #CJK UNIFIED IDEOGRAPH
+0xF6F0 0x502C #CJK UNIFIED IDEOGRAPH
+0xF6F1 0x5353 #CJK UNIFIED IDEOGRAPH
+0xF6F2 0x5544 #CJK UNIFIED IDEOGRAPH
+0xF6F3 0x577C #CJK UNIFIED IDEOGRAPH
+0xF6F4 0xFA01 #CJK COMPATIBILITY IDEOGRAPH
+0xF6F5 0x6258 #CJK UNIFIED IDEOGRAPH
+0xF6F6 0xFA02 #CJK COMPATIBILITY IDEOGRAPH
+0xF6F7 0x64E2 #CJK UNIFIED IDEOGRAPH
+0xF6F8 0x666B #CJK UNIFIED IDEOGRAPH
+0xF6F9 0x67DD #CJK UNIFIED IDEOGRAPH
+0xF6FA 0x6FC1 #CJK UNIFIED IDEOGRAPH
+0xF6FB 0x6FEF #CJK UNIFIED IDEOGRAPH
+0xF6FC 0x7422 #CJK UNIFIED IDEOGRAPH
+0xF6FD 0x7438 #CJK UNIFIED IDEOGRAPH
+0xF6FE 0x8A17 #CJK UNIFIED IDEOGRAPH
+0xF7A1 0x9438 #CJK UNIFIED IDEOGRAPH
+0xF7A2 0x5451 #CJK UNIFIED IDEOGRAPH
+0xF7A3 0x5606 #CJK UNIFIED IDEOGRAPH
+0xF7A4 0x5766 #CJK UNIFIED IDEOGRAPH
+0xF7A5 0x5F48 #CJK UNIFIED IDEOGRAPH
+0xF7A6 0x619A #CJK UNIFIED IDEOGRAPH
+0xF7A7 0x6B4E #CJK UNIFIED IDEOGRAPH
+0xF7A8 0x7058 #CJK UNIFIED IDEOGRAPH
+0xF7A9 0x70AD #CJK UNIFIED IDEOGRAPH
+0xF7AA 0x7DBB #CJK UNIFIED IDEOGRAPH
+0xF7AB 0x8A95 #CJK UNIFIED IDEOGRAPH
+0xF7AC 0x596A #CJK UNIFIED IDEOGRAPH
+0xF7AD 0x812B #CJK UNIFIED IDEOGRAPH
+0xF7AE 0x63A2 #CJK UNIFIED IDEOGRAPH
+0xF7AF 0x7708 #CJK UNIFIED IDEOGRAPH
+0xF7B0 0x803D #CJK UNIFIED IDEOGRAPH
+0xF7B1 0x8CAA #CJK UNIFIED IDEOGRAPH
+0xF7B2 0x5854 #CJK UNIFIED IDEOGRAPH
+0xF7B3 0x642D #CJK UNIFIED IDEOGRAPH
+0xF7B4 0x69BB #CJK UNIFIED IDEOGRAPH
+0xF7B5 0x5B95 #CJK UNIFIED IDEOGRAPH
+0xF7B6 0x5E11 #CJK UNIFIED IDEOGRAPH
+0xF7B7 0x6E6F #CJK UNIFIED IDEOGRAPH
+0xF7B8 0xFA03 #CJK COMPATIBILITY IDEOGRAPH
+0xF7B9 0x8569 #CJK UNIFIED IDEOGRAPH
+0xF7BA 0x514C #CJK UNIFIED IDEOGRAPH
+0xF7BB 0x53F0 #CJK UNIFIED IDEOGRAPH
+0xF7BC 0x592A #CJK UNIFIED IDEOGRAPH
+0xF7BD 0x6020 #CJK UNIFIED IDEOGRAPH
+0xF7BE 0x614B #CJK UNIFIED IDEOGRAPH
+0xF7BF 0x6B86 #CJK UNIFIED IDEOGRAPH
+0xF7C0 0x6C70 #CJK UNIFIED IDEOGRAPH
+0xF7C1 0x6CF0 #CJK UNIFIED IDEOGRAPH
+0xF7C2 0x7B1E #CJK UNIFIED IDEOGRAPH
+0xF7C3 0x80CE #CJK UNIFIED IDEOGRAPH
+0xF7C4 0x82D4 #CJK UNIFIED IDEOGRAPH
+0xF7C5 0x8DC6 #CJK UNIFIED IDEOGRAPH
+0xF7C6 0x90B0 #CJK UNIFIED IDEOGRAPH
+0xF7C7 0x98B1 #CJK UNIFIED IDEOGRAPH
+0xF7C8 0xFA04 #CJK COMPATIBILITY IDEOGRAPH
+0xF7C9 0x64C7 #CJK UNIFIED IDEOGRAPH
+0xF7CA 0x6FA4 #CJK UNIFIED IDEOGRAPH
+0xF7CB 0x6491 #CJK UNIFIED IDEOGRAPH
+0xF7CC 0x6504 #CJK UNIFIED IDEOGRAPH
+0xF7CD 0x514E #CJK UNIFIED IDEOGRAPH
+0xF7CE 0x5410 #CJK UNIFIED IDEOGRAPH
+0xF7CF 0x571F #CJK UNIFIED IDEOGRAPH
+0xF7D0 0x8A0E #CJK UNIFIED IDEOGRAPH
+0xF7D1 0x615F #CJK UNIFIED IDEOGRAPH
+0xF7D2 0x6876 #CJK UNIFIED IDEOGRAPH
+0xF7D3 0xFA05 #CJK COMPATIBILITY IDEOGRAPH
+0xF7D4 0x75DB #CJK UNIFIED IDEOGRAPH
+0xF7D5 0x7B52 #CJK UNIFIED IDEOGRAPH
+0xF7D6 0x7D71 #CJK UNIFIED IDEOGRAPH
+0xF7D7 0x901A #CJK UNIFIED IDEOGRAPH
+0xF7D8 0x5806 #CJK UNIFIED IDEOGRAPH
+0xF7D9 0x69CC #CJK UNIFIED IDEOGRAPH
+0xF7DA 0x817F #CJK UNIFIED IDEOGRAPH
+0xF7DB 0x892A #CJK UNIFIED IDEOGRAPH
+0xF7DC 0x9000 #CJK UNIFIED IDEOGRAPH
+0xF7DD 0x9839 #CJK UNIFIED IDEOGRAPH
+0xF7DE 0x5078 #CJK UNIFIED IDEOGRAPH
+0xF7DF 0x5957 #CJK UNIFIED IDEOGRAPH
+0xF7E0 0x59AC #CJK UNIFIED IDEOGRAPH
+0xF7E1 0x6295 #CJK UNIFIED IDEOGRAPH
+0xF7E2 0x900F #CJK UNIFIED IDEOGRAPH
+0xF7E3 0x9B2A #CJK UNIFIED IDEOGRAPH
+0xF7E4 0x615D #CJK UNIFIED IDEOGRAPH
+0xF7E5 0x7279 #CJK UNIFIED IDEOGRAPH
+0xF7E6 0x95D6 #CJK UNIFIED IDEOGRAPH
+0xF7E7 0x5761 #CJK UNIFIED IDEOGRAPH
+0xF7E8 0x5A46 #CJK UNIFIED IDEOGRAPH
+0xF7E9 0x5DF4 #CJK UNIFIED IDEOGRAPH
+0xF7EA 0x628A #CJK UNIFIED IDEOGRAPH
+0xF7EB 0x64AD #CJK UNIFIED IDEOGRAPH
+0xF7EC 0x64FA #CJK UNIFIED IDEOGRAPH
+0xF7ED 0x6777 #CJK UNIFIED IDEOGRAPH
+0xF7EE 0x6CE2 #CJK UNIFIED IDEOGRAPH
+0xF7EF 0x6D3E #CJK UNIFIED IDEOGRAPH
+0xF7F0 0x722C #CJK UNIFIED IDEOGRAPH
+0xF7F1 0x7436 #CJK UNIFIED IDEOGRAPH
+0xF7F2 0x7834 #CJK UNIFIED IDEOGRAPH
+0xF7F3 0x7F77 #CJK UNIFIED IDEOGRAPH
+0xF7F4 0x82AD #CJK UNIFIED IDEOGRAPH
+0xF7F5 0x8DDB #CJK UNIFIED IDEOGRAPH
+0xF7F6 0x9817 #CJK UNIFIED IDEOGRAPH
+0xF7F7 0x5224 #CJK UNIFIED IDEOGRAPH
+0xF7F8 0x5742 #CJK UNIFIED IDEOGRAPH
+0xF7F9 0x677F #CJK UNIFIED IDEOGRAPH
+0xF7FA 0x7248 #CJK UNIFIED IDEOGRAPH
+0xF7FB 0x74E3 #CJK UNIFIED IDEOGRAPH
+0xF7FC 0x8CA9 #CJK UNIFIED IDEOGRAPH
+0xF7FD 0x8FA6 #CJK UNIFIED IDEOGRAPH
+0xF7FE 0x9211 #CJK UNIFIED IDEOGRAPH
+0xF8A1 0x962A #CJK UNIFIED IDEOGRAPH
+0xF8A2 0x516B #CJK UNIFIED IDEOGRAPH
+0xF8A3 0x53ED #CJK UNIFIED IDEOGRAPH
+0xF8A4 0x634C #CJK UNIFIED IDEOGRAPH
+0xF8A5 0x4F69 #CJK UNIFIED IDEOGRAPH
+0xF8A6 0x5504 #CJK UNIFIED IDEOGRAPH
+0xF8A7 0x6096 #CJK UNIFIED IDEOGRAPH
+0xF8A8 0x6557 #CJK UNIFIED IDEOGRAPH
+0xF8A9 0x6C9B #CJK UNIFIED IDEOGRAPH
+0xF8AA 0x6D7F #CJK UNIFIED IDEOGRAPH
+0xF8AB 0x724C #CJK UNIFIED IDEOGRAPH
+0xF8AC 0x72FD #CJK UNIFIED IDEOGRAPH
+0xF8AD 0x7A17 #CJK UNIFIED IDEOGRAPH
+0xF8AE 0x8987 #CJK UNIFIED IDEOGRAPH
+0xF8AF 0x8C9D #CJK UNIFIED IDEOGRAPH
+0xF8B0 0x5F6D #CJK UNIFIED IDEOGRAPH
+0xF8B1 0x6F8E #CJK UNIFIED IDEOGRAPH
+0xF8B2 0x70F9 #CJK UNIFIED IDEOGRAPH
+0xF8B3 0x81A8 #CJK UNIFIED IDEOGRAPH
+0xF8B4 0x610E #CJK UNIFIED IDEOGRAPH
+0xF8B5 0x4FBF #CJK UNIFIED IDEOGRAPH
+0xF8B6 0x504F #CJK UNIFIED IDEOGRAPH
+0xF8B7 0x6241 #CJK UNIFIED IDEOGRAPH
+0xF8B8 0x7247 #CJK UNIFIED IDEOGRAPH
+0xF8B9 0x7BC7 #CJK UNIFIED IDEOGRAPH
+0xF8BA 0x7DE8 #CJK UNIFIED IDEOGRAPH
+0xF8BB 0x7FE9 #CJK UNIFIED IDEOGRAPH
+0xF8BC 0x904D #CJK UNIFIED IDEOGRAPH
+0xF8BD 0x97AD #CJK UNIFIED IDEOGRAPH
+0xF8BE 0x9A19 #CJK UNIFIED IDEOGRAPH
+0xF8BF 0x8CB6 #CJK UNIFIED IDEOGRAPH
+0xF8C0 0x576A #CJK UNIFIED IDEOGRAPH
+0xF8C1 0x5E73 #CJK UNIFIED IDEOGRAPH
+0xF8C2 0x67B0 #CJK UNIFIED IDEOGRAPH
+0xF8C3 0x840D #CJK UNIFIED IDEOGRAPH
+0xF8C4 0x8A55 #CJK UNIFIED IDEOGRAPH
+0xF8C5 0x5420 #CJK UNIFIED IDEOGRAPH
+0xF8C6 0x5B16 #CJK UNIFIED IDEOGRAPH
+0xF8C7 0x5E63 #CJK UNIFIED IDEOGRAPH
+0xF8C8 0x5EE2 #CJK UNIFIED IDEOGRAPH
+0xF8C9 0x5F0A #CJK UNIFIED IDEOGRAPH
+0xF8CA 0x6583 #CJK UNIFIED IDEOGRAPH
+0xF8CB 0x80BA #CJK UNIFIED IDEOGRAPH
+0xF8CC 0x853D #CJK UNIFIED IDEOGRAPH
+0xF8CD 0x9589 #CJK UNIFIED IDEOGRAPH
+0xF8CE 0x965B #CJK UNIFIED IDEOGRAPH
+0xF8CF 0x4F48 #CJK UNIFIED IDEOGRAPH
+0xF8D0 0x5305 #CJK UNIFIED IDEOGRAPH
+0xF8D1 0x530D #CJK UNIFIED IDEOGRAPH
+0xF8D2 0x530F #CJK UNIFIED IDEOGRAPH
+0xF8D3 0x5486 #CJK UNIFIED IDEOGRAPH
+0xF8D4 0x54FA #CJK UNIFIED IDEOGRAPH
+0xF8D5 0x5703 #CJK UNIFIED IDEOGRAPH
+0xF8D6 0x5E03 #CJK UNIFIED IDEOGRAPH
+0xF8D7 0x6016 #CJK UNIFIED IDEOGRAPH
+0xF8D8 0x629B #CJK UNIFIED IDEOGRAPH
+0xF8D9 0x62B1 #CJK UNIFIED IDEOGRAPH
+0xF8DA 0x6355 #CJK UNIFIED IDEOGRAPH
+0xF8DB 0xFA06 #CJK COMPATIBILITY IDEOGRAPH
+0xF8DC 0x6CE1 #CJK UNIFIED IDEOGRAPH
+0xF8DD 0x6D66 #CJK UNIFIED IDEOGRAPH
+0xF8DE 0x75B1 #CJK UNIFIED IDEOGRAPH
+0xF8DF 0x7832 #CJK UNIFIED IDEOGRAPH
+0xF8E0 0x80DE #CJK UNIFIED IDEOGRAPH
+0xF8E1 0x812F #CJK UNIFIED IDEOGRAPH
+0xF8E2 0x82DE #CJK UNIFIED IDEOGRAPH
+0xF8E3 0x8461 #CJK UNIFIED IDEOGRAPH
+0xF8E4 0x84B2 #CJK UNIFIED IDEOGRAPH
+0xF8E5 0x888D #CJK UNIFIED IDEOGRAPH
+0xF8E6 0x8912 #CJK UNIFIED IDEOGRAPH
+0xF8E7 0x900B #CJK UNIFIED IDEOGRAPH
+0xF8E8 0x92EA #CJK UNIFIED IDEOGRAPH
+0xF8E9 0x98FD #CJK UNIFIED IDEOGRAPH
+0xF8EA 0x9B91 #CJK UNIFIED IDEOGRAPH
+0xF8EB 0x5E45 #CJK UNIFIED IDEOGRAPH
+0xF8EC 0x66B4 #CJK UNIFIED IDEOGRAPH
+0xF8ED 0x66DD #CJK UNIFIED IDEOGRAPH
+0xF8EE 0x7011 #CJK UNIFIED IDEOGRAPH
+0xF8EF 0x7206 #CJK UNIFIED IDEOGRAPH
+0xF8F0 0xFA07 #CJK COMPATIBILITY IDEOGRAPH
+0xF8F1 0x4FF5 #CJK UNIFIED IDEOGRAPH
+0xF8F2 0x527D #CJK UNIFIED IDEOGRAPH
+0xF8F3 0x5F6A #CJK UNIFIED IDEOGRAPH
+0xF8F4 0x6153 #CJK UNIFIED IDEOGRAPH
+0xF8F5 0x6753 #CJK UNIFIED IDEOGRAPH
+0xF8F6 0x6A19 #CJK UNIFIED IDEOGRAPH
+0xF8F7 0x6F02 #CJK UNIFIED IDEOGRAPH
+0xF8F8 0x74E2 #CJK UNIFIED IDEOGRAPH
+0xF8F9 0x7968 #CJK UNIFIED IDEOGRAPH
+0xF8FA 0x8868 #CJK UNIFIED IDEOGRAPH
+0xF8FB 0x8C79 #CJK UNIFIED IDEOGRAPH
+0xF8FC 0x98C7 #CJK UNIFIED IDEOGRAPH
+0xF8FD 0x98C4 #CJK UNIFIED IDEOGRAPH
+0xF8FE 0x9A43 #CJK UNIFIED IDEOGRAPH
+0xF9A1 0x54C1 #CJK UNIFIED IDEOGRAPH
+0xF9A2 0x7A1F #CJK UNIFIED IDEOGRAPH
+0xF9A3 0x6953 #CJK UNIFIED IDEOGRAPH
+0xF9A4 0x8AF7 #CJK UNIFIED IDEOGRAPH
+0xF9A5 0x8C4A #CJK UNIFIED IDEOGRAPH
+0xF9A6 0x98A8 #CJK UNIFIED IDEOGRAPH
+0xF9A7 0x99AE #CJK UNIFIED IDEOGRAPH
+0xF9A8 0x5F7C #CJK UNIFIED IDEOGRAPH
+0xF9A9 0x62AB #CJK UNIFIED IDEOGRAPH
+0xF9AA 0x75B2 #CJK UNIFIED IDEOGRAPH
+0xF9AB 0x76AE #CJK UNIFIED IDEOGRAPH
+0xF9AC 0x88AB #CJK UNIFIED IDEOGRAPH
+0xF9AD 0x907F #CJK UNIFIED IDEOGRAPH
+0xF9AE 0x9642 #CJK UNIFIED IDEOGRAPH
+0xF9AF 0x5339 #CJK UNIFIED IDEOGRAPH
+0xF9B0 0x5F3C #CJK UNIFIED IDEOGRAPH
+0xF9B1 0x5FC5 #CJK UNIFIED IDEOGRAPH
+0xF9B2 0x6CCC #CJK UNIFIED IDEOGRAPH
+0xF9B3 0x73CC #CJK UNIFIED IDEOGRAPH
+0xF9B4 0x7562 #CJK UNIFIED IDEOGRAPH
+0xF9B5 0x758B #CJK UNIFIED IDEOGRAPH
+0xF9B6 0x7B46 #CJK UNIFIED IDEOGRAPH
+0xF9B7 0x82FE #CJK UNIFIED IDEOGRAPH
+0xF9B8 0x999D #CJK UNIFIED IDEOGRAPH
+0xF9B9 0x4E4F #CJK UNIFIED IDEOGRAPH
+0xF9BA 0x903C #CJK UNIFIED IDEOGRAPH
+0xF9BB 0x4E0B #CJK UNIFIED IDEOGRAPH
+0xF9BC 0x4F55 #CJK UNIFIED IDEOGRAPH
+0xF9BD 0x53A6 #CJK UNIFIED IDEOGRAPH
+0xF9BE 0x590F #CJK UNIFIED IDEOGRAPH
+0xF9BF 0x5EC8 #CJK UNIFIED IDEOGRAPH
+0xF9C0 0x6630 #CJK UNIFIED IDEOGRAPH
+0xF9C1 0x6CB3 #CJK UNIFIED IDEOGRAPH
+0xF9C2 0x7455 #CJK UNIFIED IDEOGRAPH
+0xF9C3 0x8377 #CJK UNIFIED IDEOGRAPH
+0xF9C4 0x8766 #CJK UNIFIED IDEOGRAPH
+0xF9C5 0x8CC0 #CJK UNIFIED IDEOGRAPH
+0xF9C6 0x9050 #CJK UNIFIED IDEOGRAPH
+0xF9C7 0x971E #CJK UNIFIED IDEOGRAPH
+0xF9C8 0x9C15 #CJK UNIFIED IDEOGRAPH
+0xF9C9 0x58D1 #CJK UNIFIED IDEOGRAPH
+0xF9CA 0x5B78 #CJK UNIFIED IDEOGRAPH
+0xF9CB 0x8650 #CJK UNIFIED IDEOGRAPH
+0xF9CC 0x8B14 #CJK UNIFIED IDEOGRAPH
+0xF9CD 0x9DB4 #CJK UNIFIED IDEOGRAPH
+0xF9CE 0x5BD2 #CJK UNIFIED IDEOGRAPH
+0xF9CF 0x6068 #CJK UNIFIED IDEOGRAPH
+0xF9D0 0x608D #CJK UNIFIED IDEOGRAPH
+0xF9D1 0x65F1 #CJK UNIFIED IDEOGRAPH
+0xF9D2 0x6C57 #CJK UNIFIED IDEOGRAPH
+0xF9D3 0x6F22 #CJK UNIFIED IDEOGRAPH
+0xF9D4 0x6FA3 #CJK UNIFIED IDEOGRAPH
+0xF9D5 0x701A #CJK UNIFIED IDEOGRAPH
+0xF9D6 0x7F55 #CJK UNIFIED IDEOGRAPH
+0xF9D7 0x7FF0 #CJK UNIFIED IDEOGRAPH
+0xF9D8 0x9591 #CJK UNIFIED IDEOGRAPH
+0xF9D9 0x9592 #CJK UNIFIED IDEOGRAPH
+0xF9DA 0x9650 #CJK UNIFIED IDEOGRAPH
+0xF9DB 0x97D3 #CJK UNIFIED IDEOGRAPH
+0xF9DC 0x5272 #CJK UNIFIED IDEOGRAPH
+0xF9DD 0x8F44 #CJK UNIFIED IDEOGRAPH
+0xF9DE 0x51FD #CJK UNIFIED IDEOGRAPH
+0xF9DF 0x542B #CJK UNIFIED IDEOGRAPH
+0xF9E0 0x54B8 #CJK UNIFIED IDEOGRAPH
+0xF9E1 0x5563 #CJK UNIFIED IDEOGRAPH
+0xF9E2 0x558A #CJK UNIFIED IDEOGRAPH
+0xF9E3 0x6ABB #CJK UNIFIED IDEOGRAPH
+0xF9E4 0x6DB5 #CJK UNIFIED IDEOGRAPH
+0xF9E5 0x7DD8 #CJK UNIFIED IDEOGRAPH
+0xF9E6 0x8266 #CJK UNIFIED IDEOGRAPH
+0xF9E7 0x929C #CJK UNIFIED IDEOGRAPH
+0xF9E8 0x9677 #CJK UNIFIED IDEOGRAPH
+0xF9E9 0x9E79 #CJK UNIFIED IDEOGRAPH
+0xF9EA 0x5408 #CJK UNIFIED IDEOGRAPH
+0xF9EB 0x54C8 #CJK UNIFIED IDEOGRAPH
+0xF9EC 0x76D2 #CJK UNIFIED IDEOGRAPH
+0xF9ED 0x86E4 #CJK UNIFIED IDEOGRAPH
+0xF9EE 0x95A4 #CJK UNIFIED IDEOGRAPH
+0xF9EF 0x95D4 #CJK UNIFIED IDEOGRAPH
+0xF9F0 0x965C #CJK UNIFIED IDEOGRAPH
+0xF9F1 0x4EA2 #CJK UNIFIED IDEOGRAPH
+0xF9F2 0x4F09 #CJK UNIFIED IDEOGRAPH
+0xF9F3 0x59EE #CJK UNIFIED IDEOGRAPH
+0xF9F4 0x5AE6 #CJK UNIFIED IDEOGRAPH
+0xF9F5 0x5DF7 #CJK UNIFIED IDEOGRAPH
+0xF9F6 0x6052 #CJK UNIFIED IDEOGRAPH
+0xF9F7 0x6297 #CJK UNIFIED IDEOGRAPH
+0xF9F8 0x676D #CJK UNIFIED IDEOGRAPH
+0xF9F9 0x6841 #CJK UNIFIED IDEOGRAPH
+0xF9FA 0x6C86 #CJK UNIFIED IDEOGRAPH
+0xF9FB 0x6E2F #CJK UNIFIED IDEOGRAPH
+0xF9FC 0x7F38 #CJK UNIFIED IDEOGRAPH
+0xF9FD 0x809B #CJK UNIFIED IDEOGRAPH
+0xF9FE 0x822A #CJK UNIFIED IDEOGRAPH
+0xFAA1 0xFA08 #CJK COMPATIBILITY IDEOGRAPH
+0xFAA2 0xFA09 #CJK COMPATIBILITY IDEOGRAPH
+0xFAA3 0x9805 #CJK UNIFIED IDEOGRAPH
+0xFAA4 0x4EA5 #CJK UNIFIED IDEOGRAPH
+0xFAA5 0x5055 #CJK UNIFIED IDEOGRAPH
+0xFAA6 0x54B3 #CJK UNIFIED IDEOGRAPH
+0xFAA7 0x5793 #CJK UNIFIED IDEOGRAPH
+0xFAA8 0x595A #CJK UNIFIED IDEOGRAPH
+0xFAA9 0x5B69 #CJK UNIFIED IDEOGRAPH
+0xFAAA 0x5BB3 #CJK UNIFIED IDEOGRAPH
+0xFAAB 0x61C8 #CJK UNIFIED IDEOGRAPH
+0xFAAC 0x6977 #CJK UNIFIED IDEOGRAPH
+0xFAAD 0x6D77 #CJK UNIFIED IDEOGRAPH
+0xFAAE 0x7023 #CJK UNIFIED IDEOGRAPH
+0xFAAF 0x87F9 #CJK UNIFIED IDEOGRAPH
+0xFAB0 0x89E3 #CJK UNIFIED IDEOGRAPH
+0xFAB1 0x8A72 #CJK UNIFIED IDEOGRAPH
+0xFAB2 0x8AE7 #CJK UNIFIED IDEOGRAPH
+0xFAB3 0x9082 #CJK UNIFIED IDEOGRAPH
+0xFAB4 0x99ED #CJK UNIFIED IDEOGRAPH
+0xFAB5 0x9AB8 #CJK UNIFIED IDEOGRAPH
+0xFAB6 0x52BE #CJK UNIFIED IDEOGRAPH
+0xFAB7 0x6838 #CJK UNIFIED IDEOGRAPH
+0xFAB8 0x5016 #CJK UNIFIED IDEOGRAPH
+0xFAB9 0x5E78 #CJK UNIFIED IDEOGRAPH
+0xFABA 0x674F #CJK UNIFIED IDEOGRAPH
+0xFABB 0x8347 #CJK UNIFIED IDEOGRAPH
+0xFABC 0x884C #CJK UNIFIED IDEOGRAPH
+0xFABD 0x4EAB #CJK UNIFIED IDEOGRAPH
+0xFABE 0x5411 #CJK UNIFIED IDEOGRAPH
+0xFABF 0x56AE #CJK UNIFIED IDEOGRAPH
+0xFAC0 0x73E6 #CJK UNIFIED IDEOGRAPH
+0xFAC1 0x9115 #CJK UNIFIED IDEOGRAPH
+0xFAC2 0x97FF #CJK UNIFIED IDEOGRAPH
+0xFAC3 0x9909 #CJK UNIFIED IDEOGRAPH
+0xFAC4 0x9957 #CJK UNIFIED IDEOGRAPH
+0xFAC5 0x9999 #CJK UNIFIED IDEOGRAPH
+0xFAC6 0x5653 #CJK UNIFIED IDEOGRAPH
+0xFAC7 0x589F #CJK UNIFIED IDEOGRAPH
+0xFAC8 0x865B #CJK UNIFIED IDEOGRAPH
+0xFAC9 0x8A31 #CJK UNIFIED IDEOGRAPH
+0xFACA 0x61B2 #CJK UNIFIED IDEOGRAPH
+0xFACB 0x6AF6 #CJK UNIFIED IDEOGRAPH
+0xFACC 0x737B #CJK UNIFIED IDEOGRAPH
+0xFACD 0x8ED2 #CJK UNIFIED IDEOGRAPH
+0xFACE 0x6B47 #CJK UNIFIED IDEOGRAPH
+0xFACF 0x96AA #CJK UNIFIED IDEOGRAPH
+0xFAD0 0x9A57 #CJK UNIFIED IDEOGRAPH
+0xFAD1 0x5955 #CJK UNIFIED IDEOGRAPH
+0xFAD2 0x7200 #CJK UNIFIED IDEOGRAPH
+0xFAD3 0x8D6B #CJK UNIFIED IDEOGRAPH
+0xFAD4 0x9769 #CJK UNIFIED IDEOGRAPH
+0xFAD5 0x4FD4 #CJK UNIFIED IDEOGRAPH
+0xFAD6 0x5CF4 #CJK UNIFIED IDEOGRAPH
+0xFAD7 0x5F26 #CJK UNIFIED IDEOGRAPH
+0xFAD8 0x61F8 #CJK UNIFIED IDEOGRAPH
+0xFAD9 0x665B #CJK UNIFIED IDEOGRAPH
+0xFADA 0x6CEB #CJK UNIFIED IDEOGRAPH
+0xFADB 0x70AB #CJK UNIFIED IDEOGRAPH
+0xFADC 0x7384 #CJK UNIFIED IDEOGRAPH
+0xFADD 0x73B9 #CJK UNIFIED IDEOGRAPH
+0xFADE 0x73FE #CJK UNIFIED IDEOGRAPH
+0xFADF 0x7729 #CJK UNIFIED IDEOGRAPH
+0xFAE0 0x774D #CJK UNIFIED IDEOGRAPH
+0xFAE1 0x7D43 #CJK UNIFIED IDEOGRAPH
+0xFAE2 0x7D62 #CJK UNIFIED IDEOGRAPH
+0xFAE3 0x7E23 #CJK UNIFIED IDEOGRAPH
+0xFAE4 0x8237 #CJK UNIFIED IDEOGRAPH
+0xFAE5 0x8852 #CJK UNIFIED IDEOGRAPH
+0xFAE6 0xFA0A #CJK COMPATIBILITY IDEOGRAPH
+0xFAE7 0x8CE2 #CJK UNIFIED IDEOGRAPH
+0xFAE8 0x9249 #CJK UNIFIED IDEOGRAPH
+0xFAE9 0x986F #CJK UNIFIED IDEOGRAPH
+0xFAEA 0x5B51 #CJK UNIFIED IDEOGRAPH
+0xFAEB 0x7A74 #CJK UNIFIED IDEOGRAPH
+0xFAEC 0x8840 #CJK UNIFIED IDEOGRAPH
+0xFAED 0x9801 #CJK UNIFIED IDEOGRAPH
+0xFAEE 0x5ACC #CJK UNIFIED IDEOGRAPH
+0xFAEF 0x4FE0 #CJK UNIFIED IDEOGRAPH
+0xFAF0 0x5354 #CJK UNIFIED IDEOGRAPH
+0xFAF1 0x593E #CJK UNIFIED IDEOGRAPH
+0xFAF2 0x5CFD #CJK UNIFIED IDEOGRAPH
+0xFAF3 0x633E #CJK UNIFIED IDEOGRAPH
+0xFAF4 0x6D79 #CJK UNIFIED IDEOGRAPH
+0xFAF5 0x72F9 #CJK UNIFIED IDEOGRAPH
+0xFAF6 0x8105 #CJK UNIFIED IDEOGRAPH
+0xFAF7 0x8107 #CJK UNIFIED IDEOGRAPH
+0xFAF8 0x83A2 #CJK UNIFIED IDEOGRAPH
+0xFAF9 0x92CF #CJK UNIFIED IDEOGRAPH
+0xFAFA 0x9830 #CJK UNIFIED IDEOGRAPH
+0xFAFB 0x4EA8 #CJK UNIFIED IDEOGRAPH
+0xFAFC 0x5144 #CJK UNIFIED IDEOGRAPH
+0xFAFD 0x5211 #CJK UNIFIED IDEOGRAPH
+0xFAFE 0x578B #CJK UNIFIED IDEOGRAPH
+0xFBA1 0x5F62 #CJK UNIFIED IDEOGRAPH
+0xFBA2 0x6CC2 #CJK UNIFIED IDEOGRAPH
+0xFBA3 0x6ECE #CJK UNIFIED IDEOGRAPH
+0xFBA4 0x7005 #CJK UNIFIED IDEOGRAPH
+0xFBA5 0x7050 #CJK UNIFIED IDEOGRAPH
+0xFBA6 0x70AF #CJK UNIFIED IDEOGRAPH
+0xFBA7 0x7192 #CJK UNIFIED IDEOGRAPH
+0xFBA8 0x73E9 #CJK UNIFIED IDEOGRAPH
+0xFBA9 0x7469 #CJK UNIFIED IDEOGRAPH
+0xFBAA 0x834A #CJK UNIFIED IDEOGRAPH
+0xFBAB 0x87A2 #CJK UNIFIED IDEOGRAPH
+0xFBAC 0x8861 #CJK UNIFIED IDEOGRAPH
+0xFBAD 0x9008 #CJK UNIFIED IDEOGRAPH
+0xFBAE 0x90A2 #CJK UNIFIED IDEOGRAPH
+0xFBAF 0x93A3 #CJK UNIFIED IDEOGRAPH
+0xFBB0 0x99A8 #CJK UNIFIED IDEOGRAPH
+0xFBB1 0x516E #CJK UNIFIED IDEOGRAPH
+0xFBB2 0x5F57 #CJK UNIFIED IDEOGRAPH
+0xFBB3 0x60E0 #CJK UNIFIED IDEOGRAPH
+0xFBB4 0x6167 #CJK UNIFIED IDEOGRAPH
+0xFBB5 0x66B3 #CJK UNIFIED IDEOGRAPH
+0xFBB6 0x8559 #CJK UNIFIED IDEOGRAPH
+0xFBB7 0x8E4A #CJK UNIFIED IDEOGRAPH
+0xFBB8 0x91AF #CJK UNIFIED IDEOGRAPH
+0xFBB9 0x978B #CJK UNIFIED IDEOGRAPH
+0xFBBA 0x4E4E #CJK UNIFIED IDEOGRAPH
+0xFBBB 0x4E92 #CJK UNIFIED IDEOGRAPH
+0xFBBC 0x547C #CJK UNIFIED IDEOGRAPH
+0xFBBD 0x58D5 #CJK UNIFIED IDEOGRAPH
+0xFBBE 0x58FA #CJK UNIFIED IDEOGRAPH
+0xFBBF 0x597D #CJK UNIFIED IDEOGRAPH
+0xFBC0 0x5CB5 #CJK UNIFIED IDEOGRAPH
+0xFBC1 0x5F27 #CJK UNIFIED IDEOGRAPH
+0xFBC2 0x6236 #CJK UNIFIED IDEOGRAPH
+0xFBC3 0x6248 #CJK UNIFIED IDEOGRAPH
+0xFBC4 0x660A #CJK UNIFIED IDEOGRAPH
+0xFBC5 0x6667 #CJK UNIFIED IDEOGRAPH
+0xFBC6 0x6BEB #CJK UNIFIED IDEOGRAPH
+0xFBC7 0x6D69 #CJK UNIFIED IDEOGRAPH
+0xFBC8 0x6DCF #CJK UNIFIED IDEOGRAPH
+0xFBC9 0x6E56 #CJK UNIFIED IDEOGRAPH
+0xFBCA 0x6EF8 #CJK UNIFIED IDEOGRAPH
+0xFBCB 0x6F94 #CJK UNIFIED IDEOGRAPH
+0xFBCC 0x6FE0 #CJK UNIFIED IDEOGRAPH
+0xFBCD 0x6FE9 #CJK UNIFIED IDEOGRAPH
+0xFBCE 0x705D #CJK UNIFIED IDEOGRAPH
+0xFBCF 0x72D0 #CJK UNIFIED IDEOGRAPH
+0xFBD0 0x7425 #CJK UNIFIED IDEOGRAPH
+0xFBD1 0x745A #CJK UNIFIED IDEOGRAPH
+0xFBD2 0x74E0 #CJK UNIFIED IDEOGRAPH
+0xFBD3 0x7693 #CJK UNIFIED IDEOGRAPH
+0xFBD4 0x795C #CJK UNIFIED IDEOGRAPH
+0xFBD5 0x7CCA #CJK UNIFIED IDEOGRAPH
+0xFBD6 0x7E1E #CJK UNIFIED IDEOGRAPH
+0xFBD7 0x80E1 #CJK UNIFIED IDEOGRAPH
+0xFBD8 0x82A6 #CJK UNIFIED IDEOGRAPH
+0xFBD9 0x846B #CJK UNIFIED IDEOGRAPH
+0xFBDA 0x84BF #CJK UNIFIED IDEOGRAPH
+0xFBDB 0x864E #CJK UNIFIED IDEOGRAPH
+0xFBDC 0x865F #CJK UNIFIED IDEOGRAPH
+0xFBDD 0x8774 #CJK UNIFIED IDEOGRAPH
+0xFBDE 0x8B77 #CJK UNIFIED IDEOGRAPH
+0xFBDF 0x8C6A #CJK UNIFIED IDEOGRAPH
+0xFBE0 0x93AC #CJK UNIFIED IDEOGRAPH
+0xFBE1 0x9800 #CJK UNIFIED IDEOGRAPH
+0xFBE2 0x9865 #CJK UNIFIED IDEOGRAPH
+0xFBE3 0x60D1 #CJK UNIFIED IDEOGRAPH
+0xFBE4 0x6216 #CJK UNIFIED IDEOGRAPH
+0xFBE5 0x9177 #CJK UNIFIED IDEOGRAPH
+0xFBE6 0x5A5A #CJK UNIFIED IDEOGRAPH
+0xFBE7 0x660F #CJK UNIFIED IDEOGRAPH
+0xFBE8 0x6DF7 #CJK UNIFIED IDEOGRAPH
+0xFBE9 0x6E3E #CJK UNIFIED IDEOGRAPH
+0xFBEA 0x743F #CJK UNIFIED IDEOGRAPH
+0xFBEB 0x9B42 #CJK UNIFIED IDEOGRAPH
+0xFBEC 0x5FFD #CJK UNIFIED IDEOGRAPH
+0xFBED 0x60DA #CJK UNIFIED IDEOGRAPH
+0xFBEE 0x7B0F #CJK UNIFIED IDEOGRAPH
+0xFBEF 0x54C4 #CJK UNIFIED IDEOGRAPH
+0xFBF0 0x5F18 #CJK UNIFIED IDEOGRAPH
+0xFBF1 0x6C5E #CJK UNIFIED IDEOGRAPH
+0xFBF2 0x6CD3 #CJK UNIFIED IDEOGRAPH
+0xFBF3 0x6D2A #CJK UNIFIED IDEOGRAPH
+0xFBF4 0x70D8 #CJK UNIFIED IDEOGRAPH
+0xFBF5 0x7D05 #CJK UNIFIED IDEOGRAPH
+0xFBF6 0x8679 #CJK UNIFIED IDEOGRAPH
+0xFBF7 0x8A0C #CJK UNIFIED IDEOGRAPH
+0xFBF8 0x9D3B #CJK UNIFIED IDEOGRAPH
+0xFBF9 0x5316 #CJK UNIFIED IDEOGRAPH
+0xFBFA 0x548C #CJK UNIFIED IDEOGRAPH
+0xFBFB 0x5B05 #CJK UNIFIED IDEOGRAPH
+0xFBFC 0x6A3A #CJK UNIFIED IDEOGRAPH
+0xFBFD 0x706B #CJK UNIFIED IDEOGRAPH
+0xFBFE 0x7575 #CJK UNIFIED IDEOGRAPH
+0xFCA1 0x798D #CJK UNIFIED IDEOGRAPH
+0xFCA2 0x79BE #CJK UNIFIED IDEOGRAPH
+0xFCA3 0x82B1 #CJK UNIFIED IDEOGRAPH
+0xFCA4 0x83EF #CJK UNIFIED IDEOGRAPH
+0xFCA5 0x8A71 #CJK UNIFIED IDEOGRAPH
+0xFCA6 0x8B41 #CJK UNIFIED IDEOGRAPH
+0xFCA7 0x8CA8 #CJK UNIFIED IDEOGRAPH
+0xFCA8 0x9774 #CJK UNIFIED IDEOGRAPH
+0xFCA9 0xFA0B #CJK COMPATIBILITY IDEOGRAPH
+0xFCAA 0x64F4 #CJK UNIFIED IDEOGRAPH
+0xFCAB 0x652B #CJK UNIFIED IDEOGRAPH
+0xFCAC 0x78BA #CJK UNIFIED IDEOGRAPH
+0xFCAD 0x78BB #CJK UNIFIED IDEOGRAPH
+0xFCAE 0x7A6B #CJK UNIFIED IDEOGRAPH
+0xFCAF 0x4E38 #CJK UNIFIED IDEOGRAPH
+0xFCB0 0x559A #CJK UNIFIED IDEOGRAPH
+0xFCB1 0x5950 #CJK UNIFIED IDEOGRAPH
+0xFCB2 0x5BA6 #CJK UNIFIED IDEOGRAPH
+0xFCB3 0x5E7B #CJK UNIFIED IDEOGRAPH
+0xFCB4 0x60A3 #CJK UNIFIED IDEOGRAPH
+0xFCB5 0x63DB #CJK UNIFIED IDEOGRAPH
+0xFCB6 0x6B61 #CJK UNIFIED IDEOGRAPH
+0xFCB7 0x6665 #CJK UNIFIED IDEOGRAPH
+0xFCB8 0x6853 #CJK UNIFIED IDEOGRAPH
+0xFCB9 0x6E19 #CJK UNIFIED IDEOGRAPH
+0xFCBA 0x7165 #CJK UNIFIED IDEOGRAPH
+0xFCBB 0x74B0 #CJK UNIFIED IDEOGRAPH
+0xFCBC 0x7D08 #CJK UNIFIED IDEOGRAPH
+0xFCBD 0x9084 #CJK UNIFIED IDEOGRAPH
+0xFCBE 0x9A69 #CJK UNIFIED IDEOGRAPH
+0xFCBF 0x9C25 #CJK UNIFIED IDEOGRAPH
+0xFCC0 0x6D3B #CJK UNIFIED IDEOGRAPH
+0xFCC1 0x6ED1 #CJK UNIFIED IDEOGRAPH
+0xFCC2 0x733E #CJK UNIFIED IDEOGRAPH
+0xFCC3 0x8C41 #CJK UNIFIED IDEOGRAPH
+0xFCC4 0x95CA #CJK UNIFIED IDEOGRAPH
+0xFCC5 0x51F0 #CJK UNIFIED IDEOGRAPH
+0xFCC6 0x5E4C #CJK UNIFIED IDEOGRAPH
+0xFCC7 0x5FA8 #CJK UNIFIED IDEOGRAPH
+0xFCC8 0x604D #CJK UNIFIED IDEOGRAPH
+0xFCC9 0x60F6 #CJK UNIFIED IDEOGRAPH
+0xFCCA 0x6130 #CJK UNIFIED IDEOGRAPH
+0xFCCB 0x614C #CJK UNIFIED IDEOGRAPH
+0xFCCC 0x6643 #CJK UNIFIED IDEOGRAPH
+0xFCCD 0x6644 #CJK UNIFIED IDEOGRAPH
+0xFCCE 0x69A5 #CJK UNIFIED IDEOGRAPH
+0xFCCF 0x6CC1 #CJK UNIFIED IDEOGRAPH
+0xFCD0 0x6E5F #CJK UNIFIED IDEOGRAPH
+0xFCD1 0x6EC9 #CJK UNIFIED IDEOGRAPH
+0xFCD2 0x6F62 #CJK UNIFIED IDEOGRAPH
+0xFCD3 0x714C #CJK UNIFIED IDEOGRAPH
+0xFCD4 0x749C #CJK UNIFIED IDEOGRAPH
+0xFCD5 0x7687 #CJK UNIFIED IDEOGRAPH
+0xFCD6 0x7BC1 #CJK UNIFIED IDEOGRAPH
+0xFCD7 0x7C27 #CJK UNIFIED IDEOGRAPH
+0xFCD8 0x8352 #CJK UNIFIED IDEOGRAPH
+0xFCD9 0x8757 #CJK UNIFIED IDEOGRAPH
+0xFCDA 0x9051 #CJK UNIFIED IDEOGRAPH
+0xFCDB 0x968D #CJK UNIFIED IDEOGRAPH
+0xFCDC 0x9EC3 #CJK UNIFIED IDEOGRAPH
+0xFCDD 0x532F #CJK UNIFIED IDEOGRAPH
+0xFCDE 0x56DE #CJK UNIFIED IDEOGRAPH
+0xFCDF 0x5EFB #CJK UNIFIED IDEOGRAPH
+0xFCE0 0x5F8A #CJK UNIFIED IDEOGRAPH
+0xFCE1 0x6062 #CJK UNIFIED IDEOGRAPH
+0xFCE2 0x6094 #CJK UNIFIED IDEOGRAPH
+0xFCE3 0x61F7 #CJK UNIFIED IDEOGRAPH
+0xFCE4 0x6666 #CJK UNIFIED IDEOGRAPH
+0xFCE5 0x6703 #CJK UNIFIED IDEOGRAPH
+0xFCE6 0x6A9C #CJK UNIFIED IDEOGRAPH
+0xFCE7 0x6DEE #CJK UNIFIED IDEOGRAPH
+0xFCE8 0x6FAE #CJK UNIFIED IDEOGRAPH
+0xFCE9 0x7070 #CJK UNIFIED IDEOGRAPH
+0xFCEA 0x736A #CJK UNIFIED IDEOGRAPH
+0xFCEB 0x7E6A #CJK UNIFIED IDEOGRAPH
+0xFCEC 0x81BE #CJK UNIFIED IDEOGRAPH
+0xFCED 0x8334 #CJK UNIFIED IDEOGRAPH
+0xFCEE 0x86D4 #CJK UNIFIED IDEOGRAPH
+0xFCEF 0x8AA8 #CJK UNIFIED IDEOGRAPH
+0xFCF0 0x8CC4 #CJK UNIFIED IDEOGRAPH
+0xFCF1 0x5283 #CJK UNIFIED IDEOGRAPH
+0xFCF2 0x7372 #CJK UNIFIED IDEOGRAPH
+0xFCF3 0x5B96 #CJK UNIFIED IDEOGRAPH
+0xFCF4 0x6A6B #CJK UNIFIED IDEOGRAPH
+0xFCF5 0x9404 #CJK UNIFIED IDEOGRAPH
+0xFCF6 0x54EE #CJK UNIFIED IDEOGRAPH
+0xFCF7 0x5686 #CJK UNIFIED IDEOGRAPH
+0xFCF8 0x5B5D #CJK UNIFIED IDEOGRAPH
+0xFCF9 0x6548 #CJK UNIFIED IDEOGRAPH
+0xFCFA 0x6585 #CJK UNIFIED IDEOGRAPH
+0xFCFB 0x66C9 #CJK UNIFIED IDEOGRAPH
+0xFCFC 0x689F #CJK UNIFIED IDEOGRAPH
+0xFCFD 0x6D8D #CJK UNIFIED IDEOGRAPH
+0xFCFE 0x6DC6 #CJK UNIFIED IDEOGRAPH
+0xFDA1 0x723B #CJK UNIFIED IDEOGRAPH
+0xFDA2 0x80B4 #CJK UNIFIED IDEOGRAPH
+0xFDA3 0x9175 #CJK UNIFIED IDEOGRAPH
+0xFDA4 0x9A4D #CJK UNIFIED IDEOGRAPH
+0xFDA5 0x4FAF #CJK UNIFIED IDEOGRAPH
+0xFDA6 0x5019 #CJK UNIFIED IDEOGRAPH
+0xFDA7 0x539A #CJK UNIFIED IDEOGRAPH
+0xFDA8 0x540E #CJK UNIFIED IDEOGRAPH
+0xFDA9 0x543C #CJK UNIFIED IDEOGRAPH
+0xFDAA 0x5589 #CJK UNIFIED IDEOGRAPH
+0xFDAB 0x55C5 #CJK UNIFIED IDEOGRAPH
+0xFDAC 0x5E3F #CJK UNIFIED IDEOGRAPH
+0xFDAD 0x5F8C #CJK UNIFIED IDEOGRAPH
+0xFDAE 0x673D #CJK UNIFIED IDEOGRAPH
+0xFDAF 0x7166 #CJK UNIFIED IDEOGRAPH
+0xFDB0 0x73DD #CJK UNIFIED IDEOGRAPH
+0xFDB1 0x9005 #CJK UNIFIED IDEOGRAPH
+0xFDB2 0x52DB #CJK UNIFIED IDEOGRAPH
+0xFDB3 0x52F3 #CJK UNIFIED IDEOGRAPH
+0xFDB4 0x5864 #CJK UNIFIED IDEOGRAPH
+0xFDB5 0x58CE #CJK UNIFIED IDEOGRAPH
+0xFDB6 0x7104 #CJK UNIFIED IDEOGRAPH
+0xFDB7 0x718F #CJK UNIFIED IDEOGRAPH
+0xFDB8 0x71FB #CJK UNIFIED IDEOGRAPH
+0xFDB9 0x85B0 #CJK UNIFIED IDEOGRAPH
+0xFDBA 0x8A13 #CJK UNIFIED IDEOGRAPH
+0xFDBB 0x6688 #CJK UNIFIED IDEOGRAPH
+0xFDBC 0x85A8 #CJK UNIFIED IDEOGRAPH
+0xFDBD 0x55A7 #CJK UNIFIED IDEOGRAPH
+0xFDBE 0x6684 #CJK UNIFIED IDEOGRAPH
+0xFDBF 0x714A #CJK UNIFIED IDEOGRAPH
+0xFDC0 0x8431 #CJK UNIFIED IDEOGRAPH
+0xFDC1 0x5349 #CJK UNIFIED IDEOGRAPH
+0xFDC2 0x5599 #CJK UNIFIED IDEOGRAPH
+0xFDC3 0x6BC1 #CJK UNIFIED IDEOGRAPH
+0xFDC4 0x5F59 #CJK UNIFIED IDEOGRAPH
+0xFDC5 0x5FBD #CJK UNIFIED IDEOGRAPH
+0xFDC6 0x63EE #CJK UNIFIED IDEOGRAPH
+0xFDC7 0x6689 #CJK UNIFIED IDEOGRAPH
+0xFDC8 0x7147 #CJK UNIFIED IDEOGRAPH
+0xFDC9 0x8AF1 #CJK UNIFIED IDEOGRAPH
+0xFDCA 0x8F1D #CJK UNIFIED IDEOGRAPH
+0xFDCB 0x9EBE #CJK UNIFIED IDEOGRAPH
+0xFDCC 0x4F11 #CJK UNIFIED IDEOGRAPH
+0xFDCD 0x643A #CJK UNIFIED IDEOGRAPH
+0xFDCE 0x70CB #CJK UNIFIED IDEOGRAPH
+0xFDCF 0x7566 #CJK UNIFIED IDEOGRAPH
+0xFDD0 0x8667 #CJK UNIFIED IDEOGRAPH
+0xFDD1 0x6064 #CJK UNIFIED IDEOGRAPH
+0xFDD2 0x8B4E #CJK UNIFIED IDEOGRAPH
+0xFDD3 0x9DF8 #CJK UNIFIED IDEOGRAPH
+0xFDD4 0x5147 #CJK UNIFIED IDEOGRAPH
+0xFDD5 0x51F6 #CJK UNIFIED IDEOGRAPH
+0xFDD6 0x5308 #CJK UNIFIED IDEOGRAPH
+0xFDD7 0x6D36 #CJK UNIFIED IDEOGRAPH
+0xFDD8 0x80F8 #CJK UNIFIED IDEOGRAPH
+0xFDD9 0x9ED1 #CJK UNIFIED IDEOGRAPH
+0xFDDA 0x6615 #CJK UNIFIED IDEOGRAPH
+0xFDDB 0x6B23 #CJK UNIFIED IDEOGRAPH
+0xFDDC 0x7098 #CJK UNIFIED IDEOGRAPH
+0xFDDD 0x75D5 #CJK UNIFIED IDEOGRAPH
+0xFDDE 0x5403 #CJK UNIFIED IDEOGRAPH
+0xFDDF 0x5C79 #CJK UNIFIED IDEOGRAPH
+0xFDE0 0x7D07 #CJK UNIFIED IDEOGRAPH
+0xFDE1 0x8A16 #CJK UNIFIED IDEOGRAPH
+0xFDE2 0x6B20 #CJK UNIFIED IDEOGRAPH
+0xFDE3 0x6B3D #CJK UNIFIED IDEOGRAPH
+0xFDE4 0x6B46 #CJK UNIFIED IDEOGRAPH
+0xFDE5 0x5438 #CJK UNIFIED IDEOGRAPH
+0xFDE6 0x6070 #CJK UNIFIED IDEOGRAPH
+0xFDE7 0x6D3D #CJK UNIFIED IDEOGRAPH
+0xFDE8 0x7FD5 #CJK UNIFIED IDEOGRAPH
+0xFDE9 0x8208 #CJK UNIFIED IDEOGRAPH
+0xFDEA 0x50D6 #CJK UNIFIED IDEOGRAPH
+0xFDEB 0x51DE #CJK UNIFIED IDEOGRAPH
+0xFDEC 0x559C #CJK UNIFIED IDEOGRAPH
+0xFDED 0x566B #CJK UNIFIED IDEOGRAPH
+0xFDEE 0x56CD #CJK UNIFIED IDEOGRAPH
+0xFDEF 0x59EC #CJK UNIFIED IDEOGRAPH
+0xFDF0 0x5B09 #CJK UNIFIED IDEOGRAPH
+0xFDF1 0x5E0C #CJK UNIFIED IDEOGRAPH
+0xFDF2 0x6199 #CJK UNIFIED IDEOGRAPH
+0xFDF3 0x6198 #CJK UNIFIED IDEOGRAPH
+0xFDF4 0x6231 #CJK UNIFIED IDEOGRAPH
+0xFDF5 0x665E #CJK UNIFIED IDEOGRAPH
+0xFDF6 0x66E6 #CJK UNIFIED IDEOGRAPH
+0xFDF7 0x7199 #CJK UNIFIED IDEOGRAPH
+0xFDF8 0x71B9 #CJK UNIFIED IDEOGRAPH
+0xFDF9 0x71BA #CJK UNIFIED IDEOGRAPH
+0xFDFA 0x72A7 #CJK UNIFIED IDEOGRAPH
+0xFDFB 0x79A7 #CJK UNIFIED IDEOGRAPH
+0xFDFC 0x7A00 #CJK UNIFIED IDEOGRAPH
+0xFDFD 0x7FB2 #CJK UNIFIED IDEOGRAPH
+0xFDFE 0x8A70 #CJK UNIFIED IDEOGRAPH
diff --git a/source/codepages/CP950.TXT b/source/codepages/CP950.TXT
new file mode 100755
index 00000000000..d01901039c5
--- /dev/null
+++ b/source/codepages/CP950.TXT
@@ -0,0 +1,13776 @@
+#
+# Name: cp950 to Unicode table
+# Unicode version: 2.0
+# Table version: 2.01
+# Table format: Format A
+# Date: 04/15/98
+#
+# Contact: cpxlate@microsoft.com
+#
+# General notes: none
+#
+# Format: Three tab-separated columns
+# Column #1 is the cp950 code (in hex)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 is the Unicode name (follows a comment sign, '#')
+#
+# The entries are in cp950 order
+#
+0x00 0x0000 #NULL
+0x01 0x0001 #START OF HEADING
+0x02 0x0002 #START OF TEXT
+0x03 0x0003 #END OF TEXT
+0x04 0x0004 #END OF TRANSMISSION
+0x05 0x0005 #ENQUIRY
+0x06 0x0006 #ACKNOWLEDGE
+0x07 0x0007 #BELL
+0x08 0x0008 #BACKSPACE
+0x09 0x0009 #HORIZONTAL TABULATION
+0x0A 0x000A #LINE FEED
+0x0B 0x000B #VERTICAL TABULATION
+0x0C 0x000C #FORM FEED
+0x0D 0x000D #CARRIAGE RETURN
+0x0E 0x000E #SHIFT OUT
+0x0F 0x000F #SHIFT IN
+0x10 0x0010 #DATA LINK ESCAPE
+0x11 0x0011 #DEVICE CONTROL ONE
+0x12 0x0012 #DEVICE CONTROL TWO
+0x13 0x0013 #DEVICE CONTROL THREE
+0x14 0x0014 #DEVICE CONTROL FOUR
+0x15 0x0015 #NEGATIVE ACKNOWLEDGE
+0x16 0x0016 #SYNCHRONOUS IDLE
+0x17 0x0017 #END OF TRANSMISSION BLOCK
+0x18 0x0018 #CANCEL
+0x19 0x0019 #END OF MEDIUM
+0x1A 0x001A #SUBSTITUTE
+0x1B 0x001B #ESCAPE
+0x1C 0x001C #FILE SEPARATOR
+0x1D 0x001D #GROUP SEPARATOR
+0x1E 0x001E #RECORD SEPARATOR
+0x1F 0x001F #UNIT SEPARATOR
+0x20 0x0020 #SPACE
+0x21 0x0021 #EXCLAMATION MARK
+0x22 0x0022 #QUOTATION MARK
+0x23 0x0023 #NUMBER SIGN
+0x24 0x0024 #DOLLAR SIGN
+0x25 0x0025 #PERCENT SIGN
+0x26 0x0026 #AMPERSAND
+0x27 0x0027 #APOSTROPHE
+0x28 0x0028 #LEFT PARENTHESIS
+0x29 0x0029 #RIGHT PARENTHESIS
+0x2A 0x002A #ASTERISK
+0x2B 0x002B #PLUS SIGN
+0x2C 0x002C #COMMA
+0x2D 0x002D #HYPHEN-MINUS
+0x2E 0x002E #FULL STOP
+0x2F 0x002F #SOLIDUS
+0x30 0x0030 #DIGIT ZERO
+0x31 0x0031 #DIGIT ONE
+0x32 0x0032 #DIGIT TWO
+0x33 0x0033 #DIGIT THREE
+0x34 0x0034 #DIGIT FOUR
+0x35 0x0035 #DIGIT FIVE
+0x36 0x0036 #DIGIT SIX
+0x37 0x0037 #DIGIT SEVEN
+0x38 0x0038 #DIGIT EIGHT
+0x39 0x0039 #DIGIT NINE
+0x3A 0x003A #COLON
+0x3B 0x003B #SEMICOLON
+0x3C 0x003C #LESS-THAN SIGN
+0x3D 0x003D #EQUALS SIGN
+0x3E 0x003E #GREATER-THAN SIGN
+0x3F 0x003F #QUESTION MARK
+0x40 0x0040 #COMMERCIAL AT
+0x41 0x0041 #LATIN CAPITAL LETTER A
+0x42 0x0042 #LATIN CAPITAL LETTER B
+0x43 0x0043 #LATIN CAPITAL LETTER C
+0x44 0x0044 #LATIN CAPITAL LETTER D
+0x45 0x0045 #LATIN CAPITAL LETTER E
+0x46 0x0046 #LATIN CAPITAL LETTER F
+0x47 0x0047 #LATIN CAPITAL LETTER G
+0x48 0x0048 #LATIN CAPITAL LETTER H
+0x49 0x0049 #LATIN CAPITAL LETTER I
+0x4A 0x004A #LATIN CAPITAL LETTER J
+0x4B 0x004B #LATIN CAPITAL LETTER K
+0x4C 0x004C #LATIN CAPITAL LETTER L
+0x4D 0x004D #LATIN CAPITAL LETTER M
+0x4E 0x004E #LATIN CAPITAL LETTER N
+0x4F 0x004F #LATIN CAPITAL LETTER O
+0x50 0x0050 #LATIN CAPITAL LETTER P
+0x51 0x0051 #LATIN CAPITAL LETTER Q
+0x52 0x0052 #LATIN CAPITAL LETTER R
+0x53 0x0053 #LATIN CAPITAL LETTER S
+0x54 0x0054 #LATIN CAPITAL LETTER T
+0x55 0x0055 #LATIN CAPITAL LETTER U
+0x56 0x0056 #LATIN CAPITAL LETTER V
+0x57 0x0057 #LATIN CAPITAL LETTER W
+0x58 0x0058 #LATIN CAPITAL LETTER X
+0x59 0x0059 #LATIN CAPITAL LETTER Y
+0x5A 0x005A #LATIN CAPITAL LETTER Z
+0x5B 0x005B #LEFT SQUARE BRACKET
+0x5C 0x005C #REVERSE SOLIDUS
+0x5D 0x005D #RIGHT SQUARE BRACKET
+0x5E 0x005E #CIRCUMFLEX ACCENT
+0x5F 0x005F #LOW LINE
+0x60 0x0060 #GRAVE ACCENT
+0x61 0x0061 #LATIN SMALL LETTER A
+0x62 0x0062 #LATIN SMALL LETTER B
+0x63 0x0063 #LATIN SMALL LETTER C
+0x64 0x0064 #LATIN SMALL LETTER D
+0x65 0x0065 #LATIN SMALL LETTER E
+0x66 0x0066 #LATIN SMALL LETTER F
+0x67 0x0067 #LATIN SMALL LETTER G
+0x68 0x0068 #LATIN SMALL LETTER H
+0x69 0x0069 #LATIN SMALL LETTER I
+0x6A 0x006A #LATIN SMALL LETTER J
+0x6B 0x006B #LATIN SMALL LETTER K
+0x6C 0x006C #LATIN SMALL LETTER L
+0x6D 0x006D #LATIN SMALL LETTER M
+0x6E 0x006E #LATIN SMALL LETTER N
+0x6F 0x006F #LATIN SMALL LETTER O
+0x70 0x0070 #LATIN SMALL LETTER P
+0x71 0x0071 #LATIN SMALL LETTER Q
+0x72 0x0072 #LATIN SMALL LETTER R
+0x73 0x0073 #LATIN SMALL LETTER S
+0x74 0x0074 #LATIN SMALL LETTER T
+0x75 0x0075 #LATIN SMALL LETTER U
+0x76 0x0076 #LATIN SMALL LETTER V
+0x77 0x0077 #LATIN SMALL LETTER W
+0x78 0x0078 #LATIN SMALL LETTER X
+0x79 0x0079 #LATIN SMALL LETTER Y
+0x7A 0x007A #LATIN SMALL LETTER Z
+0x7B 0x007B #LEFT CURLY BRACKET
+0x7C 0x007C #VERTICAL LINE
+0x7D 0x007D #RIGHT CURLY BRACKET
+0x7E 0x007E #TILDE
+0x7F 0x007F #DELETE
+0x80 #UNDEFINED
+0x81 #DBCS LEAD BYTE
+0x82 #DBCS LEAD BYTE
+0x83 #DBCS LEAD BYTE
+0x84 #DBCS LEAD BYTE
+0x85 #DBCS LEAD BYTE
+0x86 #DBCS LEAD BYTE
+0x87 #DBCS LEAD BYTE
+0x88 #DBCS LEAD BYTE
+0x89 #DBCS LEAD BYTE
+0x8A #DBCS LEAD BYTE
+0x8B #DBCS LEAD BYTE
+0x8C #DBCS LEAD BYTE
+0x8D #DBCS LEAD BYTE
+0x8E #DBCS LEAD BYTE
+0x8F #DBCS LEAD BYTE
+0x90 #DBCS LEAD BYTE
+0x91 #DBCS LEAD BYTE
+0x92 #DBCS LEAD BYTE
+0x93 #DBCS LEAD BYTE
+0x94 #DBCS LEAD BYTE
+0x95 #DBCS LEAD BYTE
+0x96 #DBCS LEAD BYTE
+0x97 #DBCS LEAD BYTE
+0x98 #DBCS LEAD BYTE
+0x99 #DBCS LEAD BYTE
+0x9A #DBCS LEAD BYTE
+0x9B #DBCS LEAD BYTE
+0x9C #DBCS LEAD BYTE
+0x9D #DBCS LEAD BYTE
+0x9E #DBCS LEAD BYTE
+0x9F #DBCS LEAD BYTE
+0xA0 #DBCS LEAD BYTE
+0xA1 #DBCS LEAD BYTE
+0xA2 #DBCS LEAD BYTE
+0xA3 #DBCS LEAD BYTE
+0xA4 #DBCS LEAD BYTE
+0xA5 #DBCS LEAD BYTE
+0xA6 #DBCS LEAD BYTE
+0xA7 #DBCS LEAD BYTE
+0xA8 #DBCS LEAD BYTE
+0xA9 #DBCS LEAD BYTE
+0xAA #DBCS LEAD BYTE
+0xAB #DBCS LEAD BYTE
+0xAC #DBCS LEAD BYTE
+0xAD #DBCS LEAD BYTE
+0xAE #DBCS LEAD BYTE
+0xAF #DBCS LEAD BYTE
+0xB0 #DBCS LEAD BYTE
+0xB1 #DBCS LEAD BYTE
+0xB2 #DBCS LEAD BYTE
+0xB3 #DBCS LEAD BYTE
+0xB4 #DBCS LEAD BYTE
+0xB5 #DBCS LEAD BYTE
+0xB6 #DBCS LEAD BYTE
+0xB7 #DBCS LEAD BYTE
+0xB8 #DBCS LEAD BYTE
+0xB9 #DBCS LEAD BYTE
+0xBA #DBCS LEAD BYTE
+0xBB #DBCS LEAD BYTE
+0xBC #DBCS LEAD BYTE
+0xBD #DBCS LEAD BYTE
+0xBE #DBCS LEAD BYTE
+0xBF #DBCS LEAD BYTE
+0xC0 #DBCS LEAD BYTE
+0xC1 #DBCS LEAD BYTE
+0xC2 #DBCS LEAD BYTE
+0xC3 #DBCS LEAD BYTE
+0xC4 #DBCS LEAD BYTE
+0xC5 #DBCS LEAD BYTE
+0xC6 #DBCS LEAD BYTE
+0xC7 #DBCS LEAD BYTE
+0xC8 #DBCS LEAD BYTE
+0xC9 #DBCS LEAD BYTE
+0xCA #DBCS LEAD BYTE
+0xCB #DBCS LEAD BYTE
+0xCC #DBCS LEAD BYTE
+0xCD #DBCS LEAD BYTE
+0xCE #DBCS LEAD BYTE
+0xCF #DBCS LEAD BYTE
+0xD0 #DBCS LEAD BYTE
+0xD1 #DBCS LEAD BYTE
+0xD2 #DBCS LEAD BYTE
+0xD3 #DBCS LEAD BYTE
+0xD4 #DBCS LEAD BYTE
+0xD5 #DBCS LEAD BYTE
+0xD6 #DBCS LEAD BYTE
+0xD7 #DBCS LEAD BYTE
+0xD8 #DBCS LEAD BYTE
+0xD9 #DBCS LEAD BYTE
+0xDA #DBCS LEAD BYTE
+0xDB #DBCS LEAD BYTE
+0xDC #DBCS LEAD BYTE
+0xDD #DBCS LEAD BYTE
+0xDE #DBCS LEAD BYTE
+0xDF #DBCS LEAD BYTE
+0xE0 #DBCS LEAD BYTE
+0xE1 #DBCS LEAD BYTE
+0xE2 #DBCS LEAD BYTE
+0xE3 #DBCS LEAD BYTE
+0xE4 #DBCS LEAD BYTE
+0xE5 #DBCS LEAD BYTE
+0xE6 #DBCS LEAD BYTE
+0xE7 #DBCS LEAD BYTE
+0xE8 #DBCS LEAD BYTE
+0xE9 #DBCS LEAD BYTE
+0xEA #DBCS LEAD BYTE
+0xEB #DBCS LEAD BYTE
+0xEC #DBCS LEAD BYTE
+0xED #DBCS LEAD BYTE
+0xEE #DBCS LEAD BYTE
+0xEF #DBCS LEAD BYTE
+0xF0 #DBCS LEAD BYTE
+0xF1 #DBCS LEAD BYTE
+0xF2 #DBCS LEAD BYTE
+0xF3 #DBCS LEAD BYTE
+0xF4 #DBCS LEAD BYTE
+0xF5 #DBCS LEAD BYTE
+0xF6 #DBCS LEAD BYTE
+0xF7 #DBCS LEAD BYTE
+0xF8 #DBCS LEAD BYTE
+0xF9 #DBCS LEAD BYTE
+0xFA #DBCS LEAD BYTE
+0xFB #DBCS LEAD BYTE
+0xFC #DBCS LEAD BYTE
+0xFD #DBCS LEAD BYTE
+0xFE #DBCS LEAD BYTE
+0xFF #UNDEFINED
+0xA140 0x3000 #IDEOGRAPHIC SPACE
+0xA141 0xFF0C #FULLWIDTH COMMA
+0xA142 0x3001 #IDEOGRAPHIC COMMA
+0xA143 0x3002 #IDEOGRAPHIC FULL STOP
+0xA144 0xFF0E #FULLWIDTH FULL STOP
+0xA145 0x2027 #HYPHENATION POINT
+0xA146 0xFF1B #FULLWIDTH SEMICOLON
+0xA147 0xFF1A #FULLWIDTH COLON
+0xA148 0xFF1F #FULLWIDTH QUESTION MARK
+0xA149 0xFF01 #FULLWIDTH EXCLAMATION MARK
+0xA14A 0xFE30 #PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+0xA14B 0x2026 #HORIZONTAL ELLIPSIS
+0xA14C 0x2025 #TWO DOT LEADER
+0xA14D 0xFE50 #SMALL COMMA
+0xA14E 0xFE51 #SMALL IDEOGRAPHIC COMMA
+0xA14F 0xFE52 #SMALL FULL STOP
+0xA150 0x00B7 #MIDDLE DOT
+0xA151 0xFE54 #SMALL SEMICOLON
+0xA152 0xFE55 #SMALL COLON
+0xA153 0xFE56 #SMALL QUESTION MARK
+0xA154 0xFE57 #SMALL EXCLAMATION MARK
+0xA155 0xFF5C #FULLWIDTH VERTICAL LINE
+0xA156 0x2013 #EN DASH
+0xA157 0xFE31 #PRESENTATION FORM FOR VERTICAL EM DASH
+0xA158 0x2014 #EM DASH
+0xA159 0xFE33 #PRESENTATION FORM FOR VERTICAL LOW LINE
+0xA15A 0x2574 #BOX DRAWINGS LIGHT LEFT
+0xA15B 0xFE34 #PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+0xA15C 0xFE4F #WAVY LOW LINE
+0xA15D 0xFF08 #FULLWIDTH LEFT PARENTHESIS
+0xA15E 0xFF09 #FULLWIDTH RIGHT PARENTHESIS
+0xA15F 0xFE35 #PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+0xA160 0xFE36 #PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+0xA161 0xFF5B #FULLWIDTH LEFT CURLY BRACKET
+0xA162 0xFF5D #FULLWIDTH RIGHT CURLY BRACKET
+0xA163 0xFE37 #PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+0xA164 0xFE38 #PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+0xA165 0x3014 #LEFT TORTOISE SHELL BRACKET
+0xA166 0x3015 #RIGHT TORTOISE SHELL BRACKET
+0xA167 0xFE39 #PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+0xA168 0xFE3A #PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+0xA169 0x3010 #LEFT BLACK LENTICULAR BRACKET
+0xA16A 0x3011 #RIGHT BLACK LENTICULAR BRACKET
+0xA16B 0xFE3B #PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+0xA16C 0xFE3C #PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+0xA16D 0x300A #LEFT DOUBLE ANGLE BRACKET
+0xA16E 0x300B #RIGHT DOUBLE ANGLE BRACKET
+0xA16F 0xFE3D #PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+0xA170 0xFE3E #PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+0xA171 0x3008 #LEFT ANGLE BRACKET
+0xA172 0x3009 #RIGHT ANGLE BRACKET
+0xA173 0xFE3F #PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+0xA174 0xFE40 #PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+0xA175 0x300C #LEFT CORNER BRACKET
+0xA176 0x300D #RIGHT CORNER BRACKET
+0xA177 0xFE41 #PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+0xA178 0xFE42 #PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+0xA179 0x300E #LEFT WHITE CORNER BRACKET
+0xA17A 0x300F #RIGHT WHITE CORNER BRACKET
+0xA17B 0xFE43 #PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+0xA17C 0xFE44 #PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+0xA17D 0xFE59 #SMALL LEFT PARENTHESIS
+0xA17E 0xFE5A #SMALL RIGHT PARENTHESIS
+0xA1A1 0xFE5B #SMALL LEFT CURLY BRACKET
+0xA1A2 0xFE5C #SMALL RIGHT CURLY BRACKET
+0xA1A3 0xFE5D #SMALL LEFT TORTOISE SHELL BRACKET
+0xA1A4 0xFE5E #SMALL RIGHT TORTOISE SHELL BRACKET
+0xA1A5 0x2018 #LEFT SINGLE QUOTATION MARK
+0xA1A6 0x2019 #RIGHT SINGLE QUOTATION MARK
+0xA1A7 0x201C #LEFT DOUBLE QUOTATION MARK
+0xA1A8 0x201D #RIGHT DOUBLE QUOTATION MARK
+0xA1A9 0x301D #REVERSED DOUBLE PRIME QUOTATION MARK
+0xA1AA 0x301E #DOUBLE PRIME QUOTATION MARK
+0xA1AB 0x2035 #REVERSED PRIME
+0xA1AC 0x2032 #PRIME
+0xA1AD 0xFF03 #FULLWIDTH NUMBER SIGN
+0xA1AE 0xFF06 #FULLWIDTH AMPERSAND
+0xA1AF 0xFF0A #FULLWIDTH ASTERISK
+0xA1B0 0x203B #REFERENCE MARK
+0xA1B1 0x00A7 #SECTION SIGN
+0xA1B2 0x3003 #DITTO MARK
+0xA1B3 0x25CB #WHITE CIRCLE
+0xA1B4 0x25CF #BLACK CIRCLE
+0xA1B5 0x25B3 #WHITE UP-POINTING TRIANGLE
+0xA1B6 0x25B2 #BLACK UP-POINTING TRIANGLE
+0xA1B7 0x25CE #BULLSEYE
+0xA1B8 0x2606 #WHITE STAR
+0xA1B9 0x2605 #BLACK STAR
+0xA1BA 0x25C7 #WHITE DIAMOND
+0xA1BB 0x25C6 #BLACK DIAMOND
+0xA1BC 0x25A1 #WHITE SQUARE
+0xA1BD 0x25A0 #BLACK SQUARE
+0xA1BE 0x25BD #WHITE DOWN-POINTING TRIANGLE
+0xA1BF 0x25BC #BLACK DOWN-POINTING TRIANGLE
+0xA1C0 0x32A3 #CIRCLED IDEOGRAPH CORRECT
+0xA1C1 0x2105 #CARE OF
+0xA1C2 0x00AF #MACRON
+0xA1C3 0xFFE3 #FULLWIDTH MACRON
+0xA1C4 0xFF3F #FULLWIDTH LOW LINE
+0xA1C5 0x02CD #MODIFIER LETTER LOW MACRON
+0xA1C6 0xFE49 #DASHED OVERLINE
+0xA1C7 0xFE4A #CENTRELINE OVERLINE
+0xA1C8 0xFE4D #DASHED LOW LINE
+0xA1C9 0xFE4E #CENTRELINE LOW LINE
+0xA1CA 0xFE4B #WAVY OVERLINE
+0xA1CB 0xFE4C #DOUBLE WAVY OVERLINE
+0xA1CC 0xFE5F #SMALL NUMBER SIGN
+0xA1CD 0xFE60 #SMALL AMPERSAND
+0xA1CE 0xFE61 #SMALL ASTERISK
+0xA1CF 0xFF0B #FULLWIDTH PLUS SIGN
+0xA1D0 0xFF0D #FULLWIDTH HYPHEN-MINUS
+0xA1D1 0x00D7 #MULTIPLICATION SIGN
+0xA1D2 0x00F7 #DIVISION SIGN
+0xA1D3 0x00B1 #PLUS-MINUS SIGN
+0xA1D4 0x221A #SQUARE ROOT
+0xA1D5 0xFF1C #FULLWIDTH LESS-THAN SIGN
+0xA1D6 0xFF1E #FULLWIDTH GREATER-THAN SIGN
+0xA1D7 0xFF1D #FULLWIDTH EQUALS SIGN
+0xA1D8 0x2266 #LESS-THAN OVER EQUAL TO
+0xA1D9 0x2267 #GREATER-THAN OVER EQUAL TO
+0xA1DA 0x2260 #NOT EQUAL TO
+0xA1DB 0x221E #INFINITY
+0xA1DC 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA1DD 0x2261 #IDENTICAL TO
+0xA1DE 0xFE62 #SMALL PLUS SIGN
+0xA1DF 0xFE63 #SMALL HYPHEN-MINUS
+0xA1E0 0xFE64 #SMALL LESS-THAN SIGN
+0xA1E1 0xFE65 #SMALL GREATER-THAN SIGN
+0xA1E2 0xFE66 #SMALL EQUALS SIGN
+0xA1E3 0xFF5E #FULLWIDTH TILDE
+0xA1E4 0x2229 #INTERSECTION
+0xA1E5 0x222A #UNION
+0xA1E6 0x22A5 #UP TACK
+0xA1E7 0x2220 #ANGLE
+0xA1E8 0x221F #RIGHT ANGLE
+0xA1E9 0x22BF #RIGHT TRIANGLE
+0xA1EA 0x33D2 #SQUARE LOG
+0xA1EB 0x33D1 #SQUARE LN
+0xA1EC 0x222B #INTEGRAL
+0xA1ED 0x222E #CONTOUR INTEGRAL
+0xA1EE 0x2235 #BECAUSE
+0xA1EF 0x2234 #THEREFORE
+0xA1F0 0x2640 #FEMALE SIGN
+0xA1F1 0x2642 #MALE SIGN
+0xA1F2 0x2295 #CIRCLED PLUS
+0xA1F3 0x2299 #CIRCLED DOT OPERATOR
+0xA1F4 0x2191 #UPWARDS ARROW
+0xA1F5 0x2193 #DOWNWARDS ARROW
+0xA1F6 0x2190 #LEFTWARDS ARROW
+0xA1F7 0x2192 #RIGHTWARDS ARROW
+0xA1F8 0x2196 #NORTH WEST ARROW
+0xA1F9 0x2197 #NORTH EAST ARROW
+0xA1FA 0x2199 #SOUTH WEST ARROW
+0xA1FB 0x2198 #SOUTH EAST ARROW
+0xA1FC 0x2225 #PARALLEL TO
+0xA1FD 0x2223 #DIVIDES
+0xA1FE 0xFF0F #FULLWIDTH SOLIDUS
+0xA240 0xFF3C #FULLWIDTH REVERSE SOLIDUS
+0xA241 0x2215 #DIVISION SLASH
+0xA242 0xFE68 #SMALL REVERSE SOLIDUS
+0xA243 0xFF04 #FULLWIDTH DOLLAR SIGN
+0xA244 0xFFE5 #FULLWIDTH YEN SIGN
+0xA245 0x3012 #POSTAL MARK
+0xA246 0xFFE0 #FULLWIDTH CENT SIGN
+0xA247 0xFFE1 #FULLWIDTH POUND SIGN
+0xA248 0xFF05 #FULLWIDTH PERCENT SIGN
+0xA249 0xFF20 #FULLWIDTH COMMERCIAL AT
+0xA24A 0x2103 #DEGREE CELSIUS
+0xA24B 0x2109 #DEGREE FAHRENHEIT
+0xA24C 0xFE69 #SMALL DOLLAR SIGN
+0xA24D 0xFE6A #SMALL PERCENT SIGN
+0xA24E 0xFE6B #SMALL COMMERCIAL AT
+0xA24F 0x33D5 #SQUARE MIL
+0xA250 0x339C #SQUARE MM
+0xA251 0x339D #SQUARE CM
+0xA252 0x339E #SQUARE KM
+0xA253 0x33CE #SQUARE KM CAPITAL
+0xA254 0x33A1 #SQUARE M SQUARED
+0xA255 0x338E #SQUARE MG
+0xA256 0x338F #SQUARE KG
+0xA257 0x33C4 #SQUARE CC
+0xA258 0x00B0 #DEGREE SIGN
+0xA259 0x5159 #CJK UNIFIED IDEOGRAPH
+0xA25A 0x515B #CJK UNIFIED IDEOGRAPH
+0xA25B 0x515E #CJK UNIFIED IDEOGRAPH
+0xA25C 0x515D #CJK UNIFIED IDEOGRAPH
+0xA25D 0x5161 #CJK UNIFIED IDEOGRAPH
+0xA25E 0x5163 #CJK UNIFIED IDEOGRAPH
+0xA25F 0x55E7 #CJK UNIFIED IDEOGRAPH
+0xA260 0x74E9 #CJK UNIFIED IDEOGRAPH
+0xA261 0x7CCE #CJK UNIFIED IDEOGRAPH
+0xA262 0x2581 #LOWER ONE EIGHTH BLOCK
+0xA263 0x2582 #LOWER ONE QUARTER BLOCK
+0xA264 0x2583 #LOWER THREE EIGHTHS BLOCK
+0xA265 0x2584 #LOWER HALF BLOCK
+0xA266 0x2585 #LOWER FIVE EIGHTHS BLOCK
+0xA267 0x2586 #LOWER THREE QUARTERS BLOCK
+0xA268 0x2587 #LOWER SEVEN EIGHTHS BLOCK
+0xA269 0x2588 #FULL BLOCK
+0xA26A 0x258F #LEFT ONE EIGHTH BLOCK
+0xA26B 0x258E #LEFT ONE QUARTER BLOCK
+0xA26C 0x258D #LEFT THREE EIGHTHS BLOCK
+0xA26D 0x258C #LEFT HALF BLOCK
+0xA26E 0x258B #LEFT FIVE EIGHTHS BLOCK
+0xA26F 0x258A #LEFT THREE QUARTERS BLOCK
+0xA270 0x2589 #LEFT SEVEN EIGHTHS BLOCK
+0xA271 0x253C #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA272 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA273 0x252C #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA274 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA275 0x251C #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA276 0x2594 #UPPER ONE EIGHTH BLOCK
+0xA277 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL
+0xA278 0x2502 #BOX DRAWINGS LIGHT VERTICAL
+0xA279 0x2595 #RIGHT ONE EIGHTH BLOCK
+0xA27A 0x250C #BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA27B 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA27C 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT
+0xA27D 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT
+0xA27E 0x256D #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xA2A1 0x256E #BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xA2A2 0x2570 #BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xA2A3 0x256F #BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xA2A4 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xA2A5 0x255E #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xA2A6 0x256A #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xA2A7 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xA2A8 0x25E2 #BLACK LOWER RIGHT TRIANGLE
+0xA2A9 0x25E3 #BLACK LOWER LEFT TRIANGLE
+0xA2AA 0x25E5 #BLACK UPPER RIGHT TRIANGLE
+0xA2AB 0x25E4 #BLACK UPPER LEFT TRIANGLE
+0xA2AC 0x2571 #BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+0xA2AD 0x2572 #BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+0xA2AE 0x2573 #BOX DRAWINGS LIGHT DIAGONAL CROSS
+0xA2AF 0xFF10 #FULLWIDTH DIGIT ZERO
+0xA2B0 0xFF11 #FULLWIDTH DIGIT ONE
+0xA2B1 0xFF12 #FULLWIDTH DIGIT TWO
+0xA2B2 0xFF13 #FULLWIDTH DIGIT THREE
+0xA2B3 0xFF14 #FULLWIDTH DIGIT FOUR
+0xA2B4 0xFF15 #FULLWIDTH DIGIT FIVE
+0xA2B5 0xFF16 #FULLWIDTH DIGIT SIX
+0xA2B6 0xFF17 #FULLWIDTH DIGIT SEVEN
+0xA2B7 0xFF18 #FULLWIDTH DIGIT EIGHT
+0xA2B8 0xFF19 #FULLWIDTH DIGIT NINE
+0xA2B9 0x2160 #ROMAN NUMERAL ONE
+0xA2BA 0x2161 #ROMAN NUMERAL TWO
+0xA2BB 0x2162 #ROMAN NUMERAL THREE
+0xA2BC 0x2163 #ROMAN NUMERAL FOUR
+0xA2BD 0x2164 #ROMAN NUMERAL FIVE
+0xA2BE 0x2165 #ROMAN NUMERAL SIX
+0xA2BF 0x2166 #ROMAN NUMERAL SEVEN
+0xA2C0 0x2167 #ROMAN NUMERAL EIGHT
+0xA2C1 0x2168 #ROMAN NUMERAL NINE
+0xA2C2 0x2169 #ROMAN NUMERAL TEN
+0xA2C3 0x3021 #HANGZHOU NUMERAL ONE
+0xA2C4 0x3022 #HANGZHOU NUMERAL TWO
+0xA2C5 0x3023 #HANGZHOU NUMERAL THREE
+0xA2C6 0x3024 #HANGZHOU NUMERAL FOUR
+0xA2C7 0x3025 #HANGZHOU NUMERAL FIVE
+0xA2C8 0x3026 #HANGZHOU NUMERAL SIX
+0xA2C9 0x3027 #HANGZHOU NUMERAL SEVEN
+0xA2CA 0x3028 #HANGZHOU NUMERAL EIGHT
+0xA2CB 0x3029 #HANGZHOU NUMERAL NINE
+0xA2CC 0x5341 #CJK UNIFIED IDEOGRAPH
+0xA2CD 0x5344 #CJK UNIFIED IDEOGRAPH
+0xA2CE 0x5345 #CJK UNIFIED IDEOGRAPH
+0xA2CF 0xFF21 #FULLWIDTH LATIN CAPITAL LETTER A
+0xA2D0 0xFF22 #FULLWIDTH LATIN CAPITAL LETTER B
+0xA2D1 0xFF23 #FULLWIDTH LATIN CAPITAL LETTER C
+0xA2D2 0xFF24 #FULLWIDTH LATIN CAPITAL LETTER D
+0xA2D3 0xFF25 #FULLWIDTH LATIN CAPITAL LETTER E
+0xA2D4 0xFF26 #FULLWIDTH LATIN CAPITAL LETTER F
+0xA2D5 0xFF27 #FULLWIDTH LATIN CAPITAL LETTER G
+0xA2D6 0xFF28 #FULLWIDTH LATIN CAPITAL LETTER H
+0xA2D7 0xFF29 #FULLWIDTH LATIN CAPITAL LETTER I
+0xA2D8 0xFF2A #FULLWIDTH LATIN CAPITAL LETTER J
+0xA2D9 0xFF2B #FULLWIDTH LATIN CAPITAL LETTER K
+0xA2DA 0xFF2C #FULLWIDTH LATIN CAPITAL LETTER L
+0xA2DB 0xFF2D #FULLWIDTH LATIN CAPITAL LETTER M
+0xA2DC 0xFF2E #FULLWIDTH LATIN CAPITAL LETTER N
+0xA2DD 0xFF2F #FULLWIDTH LATIN CAPITAL LETTER O
+0xA2DE 0xFF30 #FULLWIDTH LATIN CAPITAL LETTER P
+0xA2DF 0xFF31 #FULLWIDTH LATIN CAPITAL LETTER Q
+0xA2E0 0xFF32 #FULLWIDTH LATIN CAPITAL LETTER R
+0xA2E1 0xFF33 #FULLWIDTH LATIN CAPITAL LETTER S
+0xA2E2 0xFF34 #FULLWIDTH LATIN CAPITAL LETTER T
+0xA2E3 0xFF35 #FULLWIDTH LATIN CAPITAL LETTER U
+0xA2E4 0xFF36 #FULLWIDTH LATIN CAPITAL LETTER V
+0xA2E5 0xFF37 #FULLWIDTH LATIN CAPITAL LETTER W
+0xA2E6 0xFF38 #FULLWIDTH LATIN CAPITAL LETTER X
+0xA2E7 0xFF39 #FULLWIDTH LATIN CAPITAL LETTER Y
+0xA2E8 0xFF3A #FULLWIDTH LATIN CAPITAL LETTER Z
+0xA2E9 0xFF41 #FULLWIDTH LATIN SMALL LETTER A
+0xA2EA 0xFF42 #FULLWIDTH LATIN SMALL LETTER B
+0xA2EB 0xFF43 #FULLWIDTH LATIN SMALL LETTER C
+0xA2EC 0xFF44 #FULLWIDTH LATIN SMALL LETTER D
+0xA2ED 0xFF45 #FULLWIDTH LATIN SMALL LETTER E
+0xA2EE 0xFF46 #FULLWIDTH LATIN SMALL LETTER F
+0xA2EF 0xFF47 #FULLWIDTH LATIN SMALL LETTER G
+0xA2F0 0xFF48 #FULLWIDTH LATIN SMALL LETTER H
+0xA2F1 0xFF49 #FULLWIDTH LATIN SMALL LETTER I
+0xA2F2 0xFF4A #FULLWIDTH LATIN SMALL LETTER J
+0xA2F3 0xFF4B #FULLWIDTH LATIN SMALL LETTER K
+0xA2F4 0xFF4C #FULLWIDTH LATIN SMALL LETTER L
+0xA2F5 0xFF4D #FULLWIDTH LATIN SMALL LETTER M
+0xA2F6 0xFF4E #FULLWIDTH LATIN SMALL LETTER N
+0xA2F7 0xFF4F #FULLWIDTH LATIN SMALL LETTER O
+0xA2F8 0xFF50 #FULLWIDTH LATIN SMALL LETTER P
+0xA2F9 0xFF51 #FULLWIDTH LATIN SMALL LETTER Q
+0xA2FA 0xFF52 #FULLWIDTH LATIN SMALL LETTER R
+0xA2FB 0xFF53 #FULLWIDTH LATIN SMALL LETTER S
+0xA2FC 0xFF54 #FULLWIDTH LATIN SMALL LETTER T
+0xA2FD 0xFF55 #FULLWIDTH LATIN SMALL LETTER U
+0xA2FE 0xFF56 #FULLWIDTH LATIN SMALL LETTER V
+0xA340 0xFF57 #FULLWIDTH LATIN SMALL LETTER W
+0xA341 0xFF58 #FULLWIDTH LATIN SMALL LETTER X
+0xA342 0xFF59 #FULLWIDTH LATIN SMALL LETTER Y
+0xA343 0xFF5A #FULLWIDTH LATIN SMALL LETTER Z
+0xA344 0x0391 #GREEK CAPITAL LETTER ALPHA
+0xA345 0x0392 #GREEK CAPITAL LETTER BETA
+0xA346 0x0393 #GREEK CAPITAL LETTER GAMMA
+0xA347 0x0394 #GREEK CAPITAL LETTER DELTA
+0xA348 0x0395 #GREEK CAPITAL LETTER EPSILON
+0xA349 0x0396 #GREEK CAPITAL LETTER ZETA
+0xA34A 0x0397 #GREEK CAPITAL LETTER ETA
+0xA34B 0x0398 #GREEK CAPITAL LETTER THETA
+0xA34C 0x0399 #GREEK CAPITAL LETTER IOTA
+0xA34D 0x039A #GREEK CAPITAL LETTER KAPPA
+0xA34E 0x039B #GREEK CAPITAL LETTER LAMDA
+0xA34F 0x039C #GREEK CAPITAL LETTER MU
+0xA350 0x039D #GREEK CAPITAL LETTER NU
+0xA351 0x039E #GREEK CAPITAL LETTER XI
+0xA352 0x039F #GREEK CAPITAL LETTER OMICRON
+0xA353 0x03A0 #GREEK CAPITAL LETTER PI
+0xA354 0x03A1 #GREEK CAPITAL LETTER RHO
+0xA355 0x03A3 #GREEK CAPITAL LETTER SIGMA
+0xA356 0x03A4 #GREEK CAPITAL LETTER TAU
+0xA357 0x03A5 #GREEK CAPITAL LETTER UPSILON
+0xA358 0x03A6 #GREEK CAPITAL LETTER PHI
+0xA359 0x03A7 #GREEK CAPITAL LETTER CHI
+0xA35A 0x03A8 #GREEK CAPITAL LETTER PSI
+0xA35B 0x03A9 #GREEK CAPITAL LETTER OMEGA
+0xA35C 0x03B1 #GREEK SMALL LETTER ALPHA
+0xA35D 0x03B2 #GREEK SMALL LETTER BETA
+0xA35E 0x03B3 #GREEK SMALL LETTER GAMMA
+0xA35F 0x03B4 #GREEK SMALL LETTER DELTA
+0xA360 0x03B5 #GREEK SMALL LETTER EPSILON
+0xA361 0x03B6 #GREEK SMALL LETTER ZETA
+0xA362 0x03B7 #GREEK SMALL LETTER ETA
+0xA363 0x03B8 #GREEK SMALL LETTER THETA
+0xA364 0x03B9 #GREEK SMALL LETTER IOTA
+0xA365 0x03BA #GREEK SMALL LETTER KAPPA
+0xA366 0x03BB #GREEK SMALL LETTER LAMDA
+0xA367 0x03BC #GREEK SMALL LETTER MU
+0xA368 0x03BD #GREEK SMALL LETTER NU
+0xA369 0x03BE #GREEK SMALL LETTER XI
+0xA36A 0x03BF #GREEK SMALL LETTER OMICRON
+0xA36B 0x03C0 #GREEK SMALL LETTER PI
+0xA36C 0x03C1 #GREEK SMALL LETTER RHO
+0xA36D 0x03C3 #GREEK SMALL LETTER SIGMA
+0xA36E 0x03C4 #GREEK SMALL LETTER TAU
+0xA36F 0x03C5 #GREEK SMALL LETTER UPSILON
+0xA370 0x03C6 #GREEK SMALL LETTER PHI
+0xA371 0x03C7 #GREEK SMALL LETTER CHI
+0xA372 0x03C8 #GREEK SMALL LETTER PSI
+0xA373 0x03C9 #GREEK SMALL LETTER OMEGA
+0xA374 0x3105 #BOPOMOFO LETTER B
+0xA375 0x3106 #BOPOMOFO LETTER P
+0xA376 0x3107 #BOPOMOFO LETTER M
+0xA377 0x3108 #BOPOMOFO LETTER F
+0xA378 0x3109 #BOPOMOFO LETTER D
+0xA379 0x310A #BOPOMOFO LETTER T
+0xA37A 0x310B #BOPOMOFO LETTER N
+0xA37B 0x310C #BOPOMOFO LETTER L
+0xA37C 0x310D #BOPOMOFO LETTER G
+0xA37D 0x310E #BOPOMOFO LETTER K
+0xA37E 0x310F #BOPOMOFO LETTER H
+0xA3A1 0x3110 #BOPOMOFO LETTER J
+0xA3A2 0x3111 #BOPOMOFO LETTER Q
+0xA3A3 0x3112 #BOPOMOFO LETTER X
+0xA3A4 0x3113 #BOPOMOFO LETTER ZH
+0xA3A5 0x3114 #BOPOMOFO LETTER CH
+0xA3A6 0x3115 #BOPOMOFO LETTER SH
+0xA3A7 0x3116 #BOPOMOFO LETTER R
+0xA3A8 0x3117 #BOPOMOFO LETTER Z
+0xA3A9 0x3118 #BOPOMOFO LETTER C
+0xA3AA 0x3119 #BOPOMOFO LETTER S
+0xA3AB 0x311A #BOPOMOFO LETTER A
+0xA3AC 0x311B #BOPOMOFO LETTER O
+0xA3AD 0x311C #BOPOMOFO LETTER E
+0xA3AE 0x311D #BOPOMOFO LETTER EH
+0xA3AF 0x311E #BOPOMOFO LETTER AI
+0xA3B0 0x311F #BOPOMOFO LETTER EI
+0xA3B1 0x3120 #BOPOMOFO LETTER AU
+0xA3B2 0x3121 #BOPOMOFO LETTER OU
+0xA3B3 0x3122 #BOPOMOFO LETTER AN
+0xA3B4 0x3123 #BOPOMOFO LETTER EN
+0xA3B5 0x3124 #BOPOMOFO LETTER ANG
+0xA3B6 0x3125 #BOPOMOFO LETTER ENG
+0xA3B7 0x3126 #BOPOMOFO LETTER ER
+0xA3B8 0x3127 #BOPOMOFO LETTER I
+0xA3B9 0x3128 #BOPOMOFO LETTER U
+0xA3BA 0x3129 #BOPOMOFO LETTER IU
+0xA3BB 0x02D9 #DOT ABOVE
+0xA3BC 0x02C9 #MODIFIER LETTER MACRON
+0xA3BD 0x02CA #MODIFIER LETTER ACUTE ACCENT
+0xA3BE 0x02C7 #CARON
+0xA3BF 0x02CB #MODIFIER LETTER GRAVE ACCENT
+0xA440 0x4E00 #CJK UNIFIED IDEOGRAPH
+0xA441 0x4E59 #CJK UNIFIED IDEOGRAPH
+0xA442 0x4E01 #CJK UNIFIED IDEOGRAPH
+0xA443 0x4E03 #CJK UNIFIED IDEOGRAPH
+0xA444 0x4E43 #CJK UNIFIED IDEOGRAPH
+0xA445 0x4E5D #CJK UNIFIED IDEOGRAPH
+0xA446 0x4E86 #CJK UNIFIED IDEOGRAPH
+0xA447 0x4E8C #CJK UNIFIED IDEOGRAPH
+0xA448 0x4EBA #CJK UNIFIED IDEOGRAPH
+0xA449 0x513F #CJK UNIFIED IDEOGRAPH
+0xA44A 0x5165 #CJK UNIFIED IDEOGRAPH
+0xA44B 0x516B #CJK UNIFIED IDEOGRAPH
+0xA44C 0x51E0 #CJK UNIFIED IDEOGRAPH
+0xA44D 0x5200 #CJK UNIFIED IDEOGRAPH
+0xA44E 0x5201 #CJK UNIFIED IDEOGRAPH
+0xA44F 0x529B #CJK UNIFIED IDEOGRAPH
+0xA450 0x5315 #CJK UNIFIED IDEOGRAPH
+0xA451 0x5341 #CJK UNIFIED IDEOGRAPH
+0xA452 0x535C #CJK UNIFIED IDEOGRAPH
+0xA453 0x53C8 #CJK UNIFIED IDEOGRAPH
+0xA454 0x4E09 #CJK UNIFIED IDEOGRAPH
+0xA455 0x4E0B #CJK UNIFIED IDEOGRAPH
+0xA456 0x4E08 #CJK UNIFIED IDEOGRAPH
+0xA457 0x4E0A #CJK UNIFIED IDEOGRAPH
+0xA458 0x4E2B #CJK UNIFIED IDEOGRAPH
+0xA459 0x4E38 #CJK UNIFIED IDEOGRAPH
+0xA45A 0x51E1 #CJK UNIFIED IDEOGRAPH
+0xA45B 0x4E45 #CJK UNIFIED IDEOGRAPH
+0xA45C 0x4E48 #CJK UNIFIED IDEOGRAPH
+0xA45D 0x4E5F #CJK UNIFIED IDEOGRAPH
+0xA45E 0x4E5E #CJK UNIFIED IDEOGRAPH
+0xA45F 0x4E8E #CJK UNIFIED IDEOGRAPH
+0xA460 0x4EA1 #CJK UNIFIED IDEOGRAPH
+0xA461 0x5140 #CJK UNIFIED IDEOGRAPH
+0xA462 0x5203 #CJK UNIFIED IDEOGRAPH
+0xA463 0x52FA #CJK UNIFIED IDEOGRAPH
+0xA464 0x5343 #CJK UNIFIED IDEOGRAPH
+0xA465 0x53C9 #CJK UNIFIED IDEOGRAPH
+0xA466 0x53E3 #CJK UNIFIED IDEOGRAPH
+0xA467 0x571F #CJK UNIFIED IDEOGRAPH
+0xA468 0x58EB #CJK UNIFIED IDEOGRAPH
+0xA469 0x5915 #CJK UNIFIED IDEOGRAPH
+0xA46A 0x5927 #CJK UNIFIED IDEOGRAPH
+0xA46B 0x5973 #CJK UNIFIED IDEOGRAPH
+0xA46C 0x5B50 #CJK UNIFIED IDEOGRAPH
+0xA46D 0x5B51 #CJK UNIFIED IDEOGRAPH
+0xA46E 0x5B53 #CJK UNIFIED IDEOGRAPH
+0xA46F 0x5BF8 #CJK UNIFIED IDEOGRAPH
+0xA470 0x5C0F #CJK UNIFIED IDEOGRAPH
+0xA471 0x5C22 #CJK UNIFIED IDEOGRAPH
+0xA472 0x5C38 #CJK UNIFIED IDEOGRAPH
+0xA473 0x5C71 #CJK UNIFIED IDEOGRAPH
+0xA474 0x5DDD #CJK UNIFIED IDEOGRAPH
+0xA475 0x5DE5 #CJK UNIFIED IDEOGRAPH
+0xA476 0x5DF1 #CJK UNIFIED IDEOGRAPH
+0xA477 0x5DF2 #CJK UNIFIED IDEOGRAPH
+0xA478 0x5DF3 #CJK UNIFIED IDEOGRAPH
+0xA479 0x5DFE #CJK UNIFIED IDEOGRAPH
+0xA47A 0x5E72 #CJK UNIFIED IDEOGRAPH
+0xA47B 0x5EFE #CJK UNIFIED IDEOGRAPH
+0xA47C 0x5F0B #CJK UNIFIED IDEOGRAPH
+0xA47D 0x5F13 #CJK UNIFIED IDEOGRAPH
+0xA47E 0x624D #CJK UNIFIED IDEOGRAPH
+0xA4A1 0x4E11 #CJK UNIFIED IDEOGRAPH
+0xA4A2 0x4E10 #CJK UNIFIED IDEOGRAPH
+0xA4A3 0x4E0D #CJK UNIFIED IDEOGRAPH
+0xA4A4 0x4E2D #CJK UNIFIED IDEOGRAPH
+0xA4A5 0x4E30 #CJK UNIFIED IDEOGRAPH
+0xA4A6 0x4E39 #CJK UNIFIED IDEOGRAPH
+0xA4A7 0x4E4B #CJK UNIFIED IDEOGRAPH
+0xA4A8 0x5C39 #CJK UNIFIED IDEOGRAPH
+0xA4A9 0x4E88 #CJK UNIFIED IDEOGRAPH
+0xA4AA 0x4E91 #CJK UNIFIED IDEOGRAPH
+0xA4AB 0x4E95 #CJK UNIFIED IDEOGRAPH
+0xA4AC 0x4E92 #CJK UNIFIED IDEOGRAPH
+0xA4AD 0x4E94 #CJK UNIFIED IDEOGRAPH
+0xA4AE 0x4EA2 #CJK UNIFIED IDEOGRAPH
+0xA4AF 0x4EC1 #CJK UNIFIED IDEOGRAPH
+0xA4B0 0x4EC0 #CJK UNIFIED IDEOGRAPH
+0xA4B1 0x4EC3 #CJK UNIFIED IDEOGRAPH
+0xA4B2 0x4EC6 #CJK UNIFIED IDEOGRAPH
+0xA4B3 0x4EC7 #CJK UNIFIED IDEOGRAPH
+0xA4B4 0x4ECD #CJK UNIFIED IDEOGRAPH
+0xA4B5 0x4ECA #CJK UNIFIED IDEOGRAPH
+0xA4B6 0x4ECB #CJK UNIFIED IDEOGRAPH
+0xA4B7 0x4EC4 #CJK UNIFIED IDEOGRAPH
+0xA4B8 0x5143 #CJK UNIFIED IDEOGRAPH
+0xA4B9 0x5141 #CJK UNIFIED IDEOGRAPH
+0xA4BA 0x5167 #CJK UNIFIED IDEOGRAPH
+0xA4BB 0x516D #CJK UNIFIED IDEOGRAPH
+0xA4BC 0x516E #CJK UNIFIED IDEOGRAPH
+0xA4BD 0x516C #CJK UNIFIED IDEOGRAPH
+0xA4BE 0x5197 #CJK UNIFIED IDEOGRAPH
+0xA4BF 0x51F6 #CJK UNIFIED IDEOGRAPH
+0xA4C0 0x5206 #CJK UNIFIED IDEOGRAPH
+0xA4C1 0x5207 #CJK UNIFIED IDEOGRAPH
+0xA4C2 0x5208 #CJK UNIFIED IDEOGRAPH
+0xA4C3 0x52FB #CJK UNIFIED IDEOGRAPH
+0xA4C4 0x52FE #CJK UNIFIED IDEOGRAPH
+0xA4C5 0x52FF #CJK UNIFIED IDEOGRAPH
+0xA4C6 0x5316 #CJK UNIFIED IDEOGRAPH
+0xA4C7 0x5339 #CJK UNIFIED IDEOGRAPH
+0xA4C8 0x5348 #CJK UNIFIED IDEOGRAPH
+0xA4C9 0x5347 #CJK UNIFIED IDEOGRAPH
+0xA4CA 0x5345 #CJK UNIFIED IDEOGRAPH
+0xA4CB 0x535E #CJK UNIFIED IDEOGRAPH
+0xA4CC 0x5384 #CJK UNIFIED IDEOGRAPH
+0xA4CD 0x53CB #CJK UNIFIED IDEOGRAPH
+0xA4CE 0x53CA #CJK UNIFIED IDEOGRAPH
+0xA4CF 0x53CD #CJK UNIFIED IDEOGRAPH
+0xA4D0 0x58EC #CJK UNIFIED IDEOGRAPH
+0xA4D1 0x5929 #CJK UNIFIED IDEOGRAPH
+0xA4D2 0x592B #CJK UNIFIED IDEOGRAPH
+0xA4D3 0x592A #CJK UNIFIED IDEOGRAPH
+0xA4D4 0x592D #CJK UNIFIED IDEOGRAPH
+0xA4D5 0x5B54 #CJK UNIFIED IDEOGRAPH
+0xA4D6 0x5C11 #CJK UNIFIED IDEOGRAPH
+0xA4D7 0x5C24 #CJK UNIFIED IDEOGRAPH
+0xA4D8 0x5C3A #CJK UNIFIED IDEOGRAPH
+0xA4D9 0x5C6F #CJK UNIFIED IDEOGRAPH
+0xA4DA 0x5DF4 #CJK UNIFIED IDEOGRAPH
+0xA4DB 0x5E7B #CJK UNIFIED IDEOGRAPH
+0xA4DC 0x5EFF #CJK UNIFIED IDEOGRAPH
+0xA4DD 0x5F14 #CJK UNIFIED IDEOGRAPH
+0xA4DE 0x5F15 #CJK UNIFIED IDEOGRAPH
+0xA4DF 0x5FC3 #CJK UNIFIED IDEOGRAPH
+0xA4E0 0x6208 #CJK UNIFIED IDEOGRAPH
+0xA4E1 0x6236 #CJK UNIFIED IDEOGRAPH
+0xA4E2 0x624B #CJK UNIFIED IDEOGRAPH
+0xA4E3 0x624E #CJK UNIFIED IDEOGRAPH
+0xA4E4 0x652F #CJK UNIFIED IDEOGRAPH
+0xA4E5 0x6587 #CJK UNIFIED IDEOGRAPH
+0xA4E6 0x6597 #CJK UNIFIED IDEOGRAPH
+0xA4E7 0x65A4 #CJK UNIFIED IDEOGRAPH
+0xA4E8 0x65B9 #CJK UNIFIED IDEOGRAPH
+0xA4E9 0x65E5 #CJK UNIFIED IDEOGRAPH
+0xA4EA 0x66F0 #CJK UNIFIED IDEOGRAPH
+0xA4EB 0x6708 #CJK UNIFIED IDEOGRAPH
+0xA4EC 0x6728 #CJK UNIFIED IDEOGRAPH
+0xA4ED 0x6B20 #CJK UNIFIED IDEOGRAPH
+0xA4EE 0x6B62 #CJK UNIFIED IDEOGRAPH
+0xA4EF 0x6B79 #CJK UNIFIED IDEOGRAPH
+0xA4F0 0x6BCB #CJK UNIFIED IDEOGRAPH
+0xA4F1 0x6BD4 #CJK UNIFIED IDEOGRAPH
+0xA4F2 0x6BDB #CJK UNIFIED IDEOGRAPH
+0xA4F3 0x6C0F #CJK UNIFIED IDEOGRAPH
+0xA4F4 0x6C34 #CJK UNIFIED IDEOGRAPH
+0xA4F5 0x706B #CJK UNIFIED IDEOGRAPH
+0xA4F6 0x722A #CJK UNIFIED IDEOGRAPH
+0xA4F7 0x7236 #CJK UNIFIED IDEOGRAPH
+0xA4F8 0x723B #CJK UNIFIED IDEOGRAPH
+0xA4F9 0x7247 #CJK UNIFIED IDEOGRAPH
+0xA4FA 0x7259 #CJK UNIFIED IDEOGRAPH
+0xA4FB 0x725B #CJK UNIFIED IDEOGRAPH
+0xA4FC 0x72AC #CJK UNIFIED IDEOGRAPH
+0xA4FD 0x738B #CJK UNIFIED IDEOGRAPH
+0xA4FE 0x4E19 #CJK UNIFIED IDEOGRAPH
+0xA540 0x4E16 #CJK UNIFIED IDEOGRAPH
+0xA541 0x4E15 #CJK UNIFIED IDEOGRAPH
+0xA542 0x4E14 #CJK UNIFIED IDEOGRAPH
+0xA543 0x4E18 #CJK UNIFIED IDEOGRAPH
+0xA544 0x4E3B #CJK UNIFIED IDEOGRAPH
+0xA545 0x4E4D #CJK UNIFIED IDEOGRAPH
+0xA546 0x4E4F #CJK UNIFIED IDEOGRAPH
+0xA547 0x4E4E #CJK UNIFIED IDEOGRAPH
+0xA548 0x4EE5 #CJK UNIFIED IDEOGRAPH
+0xA549 0x4ED8 #CJK UNIFIED IDEOGRAPH
+0xA54A 0x4ED4 #CJK UNIFIED IDEOGRAPH
+0xA54B 0x4ED5 #CJK UNIFIED IDEOGRAPH
+0xA54C 0x4ED6 #CJK UNIFIED IDEOGRAPH
+0xA54D 0x4ED7 #CJK UNIFIED IDEOGRAPH
+0xA54E 0x4EE3 #CJK UNIFIED IDEOGRAPH
+0xA54F 0x4EE4 #CJK UNIFIED IDEOGRAPH
+0xA550 0x4ED9 #CJK UNIFIED IDEOGRAPH
+0xA551 0x4EDE #CJK UNIFIED IDEOGRAPH
+0xA552 0x5145 #CJK UNIFIED IDEOGRAPH
+0xA553 0x5144 #CJK UNIFIED IDEOGRAPH
+0xA554 0x5189 #CJK UNIFIED IDEOGRAPH
+0xA555 0x518A #CJK UNIFIED IDEOGRAPH
+0xA556 0x51AC #CJK UNIFIED IDEOGRAPH
+0xA557 0x51F9 #CJK UNIFIED IDEOGRAPH
+0xA558 0x51FA #CJK UNIFIED IDEOGRAPH
+0xA559 0x51F8 #CJK UNIFIED IDEOGRAPH
+0xA55A 0x520A #CJK UNIFIED IDEOGRAPH
+0xA55B 0x52A0 #CJK UNIFIED IDEOGRAPH
+0xA55C 0x529F #CJK UNIFIED IDEOGRAPH
+0xA55D 0x5305 #CJK UNIFIED IDEOGRAPH
+0xA55E 0x5306 #CJK UNIFIED IDEOGRAPH
+0xA55F 0x5317 #CJK UNIFIED IDEOGRAPH
+0xA560 0x531D #CJK UNIFIED IDEOGRAPH
+0xA561 0x4EDF #CJK UNIFIED IDEOGRAPH
+0xA562 0x534A #CJK UNIFIED IDEOGRAPH
+0xA563 0x5349 #CJK UNIFIED IDEOGRAPH
+0xA564 0x5361 #CJK UNIFIED IDEOGRAPH
+0xA565 0x5360 #CJK UNIFIED IDEOGRAPH
+0xA566 0x536F #CJK UNIFIED IDEOGRAPH
+0xA567 0x536E #CJK UNIFIED IDEOGRAPH
+0xA568 0x53BB #CJK UNIFIED IDEOGRAPH
+0xA569 0x53EF #CJK UNIFIED IDEOGRAPH
+0xA56A 0x53E4 #CJK UNIFIED IDEOGRAPH
+0xA56B 0x53F3 #CJK UNIFIED IDEOGRAPH
+0xA56C 0x53EC #CJK UNIFIED IDEOGRAPH
+0xA56D 0x53EE #CJK UNIFIED IDEOGRAPH
+0xA56E 0x53E9 #CJK UNIFIED IDEOGRAPH
+0xA56F 0x53E8 #CJK UNIFIED IDEOGRAPH
+0xA570 0x53FC #CJK UNIFIED IDEOGRAPH
+0xA571 0x53F8 #CJK UNIFIED IDEOGRAPH
+0xA572 0x53F5 #CJK UNIFIED IDEOGRAPH
+0xA573 0x53EB #CJK UNIFIED IDEOGRAPH
+0xA574 0x53E6 #CJK UNIFIED IDEOGRAPH
+0xA575 0x53EA #CJK UNIFIED IDEOGRAPH
+0xA576 0x53F2 #CJK UNIFIED IDEOGRAPH
+0xA577 0x53F1 #CJK UNIFIED IDEOGRAPH
+0xA578 0x53F0 #CJK UNIFIED IDEOGRAPH
+0xA579 0x53E5 #CJK UNIFIED IDEOGRAPH
+0xA57A 0x53ED #CJK UNIFIED IDEOGRAPH
+0xA57B 0x53FB #CJK UNIFIED IDEOGRAPH
+0xA57C 0x56DB #CJK UNIFIED IDEOGRAPH
+0xA57D 0x56DA #CJK UNIFIED IDEOGRAPH
+0xA57E 0x5916 #CJK UNIFIED IDEOGRAPH
+0xA5A1 0x592E #CJK UNIFIED IDEOGRAPH
+0xA5A2 0x5931 #CJK UNIFIED IDEOGRAPH
+0xA5A3 0x5974 #CJK UNIFIED IDEOGRAPH
+0xA5A4 0x5976 #CJK UNIFIED IDEOGRAPH
+0xA5A5 0x5B55 #CJK UNIFIED IDEOGRAPH
+0xA5A6 0x5B83 #CJK UNIFIED IDEOGRAPH
+0xA5A7 0x5C3C #CJK UNIFIED IDEOGRAPH
+0xA5A8 0x5DE8 #CJK UNIFIED IDEOGRAPH
+0xA5A9 0x5DE7 #CJK UNIFIED IDEOGRAPH
+0xA5AA 0x5DE6 #CJK UNIFIED IDEOGRAPH
+0xA5AB 0x5E02 #CJK UNIFIED IDEOGRAPH
+0xA5AC 0x5E03 #CJK UNIFIED IDEOGRAPH
+0xA5AD 0x5E73 #CJK UNIFIED IDEOGRAPH
+0xA5AE 0x5E7C #CJK UNIFIED IDEOGRAPH
+0xA5AF 0x5F01 #CJK UNIFIED IDEOGRAPH
+0xA5B0 0x5F18 #CJK UNIFIED IDEOGRAPH
+0xA5B1 0x5F17 #CJK UNIFIED IDEOGRAPH
+0xA5B2 0x5FC5 #CJK UNIFIED IDEOGRAPH
+0xA5B3 0x620A #CJK UNIFIED IDEOGRAPH
+0xA5B4 0x6253 #CJK UNIFIED IDEOGRAPH
+0xA5B5 0x6254 #CJK UNIFIED IDEOGRAPH
+0xA5B6 0x6252 #CJK UNIFIED IDEOGRAPH
+0xA5B7 0x6251 #CJK UNIFIED IDEOGRAPH
+0xA5B8 0x65A5 #CJK UNIFIED IDEOGRAPH
+0xA5B9 0x65E6 #CJK UNIFIED IDEOGRAPH
+0xA5BA 0x672E #CJK UNIFIED IDEOGRAPH
+0xA5BB 0x672C #CJK UNIFIED IDEOGRAPH
+0xA5BC 0x672A #CJK UNIFIED IDEOGRAPH
+0xA5BD 0x672B #CJK UNIFIED IDEOGRAPH
+0xA5BE 0x672D #CJK UNIFIED IDEOGRAPH
+0xA5BF 0x6B63 #CJK UNIFIED IDEOGRAPH
+0xA5C0 0x6BCD #CJK UNIFIED IDEOGRAPH
+0xA5C1 0x6C11 #CJK UNIFIED IDEOGRAPH
+0xA5C2 0x6C10 #CJK UNIFIED IDEOGRAPH
+0xA5C3 0x6C38 #CJK UNIFIED IDEOGRAPH
+0xA5C4 0x6C41 #CJK UNIFIED IDEOGRAPH
+0xA5C5 0x6C40 #CJK UNIFIED IDEOGRAPH
+0xA5C6 0x6C3E #CJK UNIFIED IDEOGRAPH
+0xA5C7 0x72AF #CJK UNIFIED IDEOGRAPH
+0xA5C8 0x7384 #CJK UNIFIED IDEOGRAPH
+0xA5C9 0x7389 #CJK UNIFIED IDEOGRAPH
+0xA5CA 0x74DC #CJK UNIFIED IDEOGRAPH
+0xA5CB 0x74E6 #CJK UNIFIED IDEOGRAPH
+0xA5CC 0x7518 #CJK UNIFIED IDEOGRAPH
+0xA5CD 0x751F #CJK UNIFIED IDEOGRAPH
+0xA5CE 0x7528 #CJK UNIFIED IDEOGRAPH
+0xA5CF 0x7529 #CJK UNIFIED IDEOGRAPH
+0xA5D0 0x7530 #CJK UNIFIED IDEOGRAPH
+0xA5D1 0x7531 #CJK UNIFIED IDEOGRAPH
+0xA5D2 0x7532 #CJK UNIFIED IDEOGRAPH
+0xA5D3 0x7533 #CJK UNIFIED IDEOGRAPH
+0xA5D4 0x758B #CJK UNIFIED IDEOGRAPH
+0xA5D5 0x767D #CJK UNIFIED IDEOGRAPH
+0xA5D6 0x76AE #CJK UNIFIED IDEOGRAPH
+0xA5D7 0x76BF #CJK UNIFIED IDEOGRAPH
+0xA5D8 0x76EE #CJK UNIFIED IDEOGRAPH
+0xA5D9 0x77DB #CJK UNIFIED IDEOGRAPH
+0xA5DA 0x77E2 #CJK UNIFIED IDEOGRAPH
+0xA5DB 0x77F3 #CJK UNIFIED IDEOGRAPH
+0xA5DC 0x793A #CJK UNIFIED IDEOGRAPH
+0xA5DD 0x79BE #CJK UNIFIED IDEOGRAPH
+0xA5DE 0x7A74 #CJK UNIFIED IDEOGRAPH
+0xA5DF 0x7ACB #CJK UNIFIED IDEOGRAPH
+0xA5E0 0x4E1E #CJK UNIFIED IDEOGRAPH
+0xA5E1 0x4E1F #CJK UNIFIED IDEOGRAPH
+0xA5E2 0x4E52 #CJK UNIFIED IDEOGRAPH
+0xA5E3 0x4E53 #CJK UNIFIED IDEOGRAPH
+0xA5E4 0x4E69 #CJK UNIFIED IDEOGRAPH
+0xA5E5 0x4E99 #CJK UNIFIED IDEOGRAPH
+0xA5E6 0x4EA4 #CJK UNIFIED IDEOGRAPH
+0xA5E7 0x4EA6 #CJK UNIFIED IDEOGRAPH
+0xA5E8 0x4EA5 #CJK UNIFIED IDEOGRAPH
+0xA5E9 0x4EFF #CJK UNIFIED IDEOGRAPH
+0xA5EA 0x4F09 #CJK UNIFIED IDEOGRAPH
+0xA5EB 0x4F19 #CJK UNIFIED IDEOGRAPH
+0xA5EC 0x4F0A #CJK UNIFIED IDEOGRAPH
+0xA5ED 0x4F15 #CJK UNIFIED IDEOGRAPH
+0xA5EE 0x4F0D #CJK UNIFIED IDEOGRAPH
+0xA5EF 0x4F10 #CJK UNIFIED IDEOGRAPH
+0xA5F0 0x4F11 #CJK UNIFIED IDEOGRAPH
+0xA5F1 0x4F0F #CJK UNIFIED IDEOGRAPH
+0xA5F2 0x4EF2 #CJK UNIFIED IDEOGRAPH
+0xA5F3 0x4EF6 #CJK UNIFIED IDEOGRAPH
+0xA5F4 0x4EFB #CJK UNIFIED IDEOGRAPH
+0xA5F5 0x4EF0 #CJK UNIFIED IDEOGRAPH
+0xA5F6 0x4EF3 #CJK UNIFIED IDEOGRAPH
+0xA5F7 0x4EFD #CJK UNIFIED IDEOGRAPH
+0xA5F8 0x4F01 #CJK UNIFIED IDEOGRAPH
+0xA5F9 0x4F0B #CJK UNIFIED IDEOGRAPH
+0xA5FA 0x5149 #CJK UNIFIED IDEOGRAPH
+0xA5FB 0x5147 #CJK UNIFIED IDEOGRAPH
+0xA5FC 0x5146 #CJK UNIFIED IDEOGRAPH
+0xA5FD 0x5148 #CJK UNIFIED IDEOGRAPH
+0xA5FE 0x5168 #CJK UNIFIED IDEOGRAPH
+0xA640 0x5171 #CJK UNIFIED IDEOGRAPH
+0xA641 0x518D #CJK UNIFIED IDEOGRAPH
+0xA642 0x51B0 #CJK UNIFIED IDEOGRAPH
+0xA643 0x5217 #CJK UNIFIED IDEOGRAPH
+0xA644 0x5211 #CJK UNIFIED IDEOGRAPH
+0xA645 0x5212 #CJK UNIFIED IDEOGRAPH
+0xA646 0x520E #CJK UNIFIED IDEOGRAPH
+0xA647 0x5216 #CJK UNIFIED IDEOGRAPH
+0xA648 0x52A3 #CJK UNIFIED IDEOGRAPH
+0xA649 0x5308 #CJK UNIFIED IDEOGRAPH
+0xA64A 0x5321 #CJK UNIFIED IDEOGRAPH
+0xA64B 0x5320 #CJK UNIFIED IDEOGRAPH
+0xA64C 0x5370 #CJK UNIFIED IDEOGRAPH
+0xA64D 0x5371 #CJK UNIFIED IDEOGRAPH
+0xA64E 0x5409 #CJK UNIFIED IDEOGRAPH
+0xA64F 0x540F #CJK UNIFIED IDEOGRAPH
+0xA650 0x540C #CJK UNIFIED IDEOGRAPH
+0xA651 0x540A #CJK UNIFIED IDEOGRAPH
+0xA652 0x5410 #CJK UNIFIED IDEOGRAPH
+0xA653 0x5401 #CJK UNIFIED IDEOGRAPH
+0xA654 0x540B #CJK UNIFIED IDEOGRAPH
+0xA655 0x5404 #CJK UNIFIED IDEOGRAPH
+0xA656 0x5411 #CJK UNIFIED IDEOGRAPH
+0xA657 0x540D #CJK UNIFIED IDEOGRAPH
+0xA658 0x5408 #CJK UNIFIED IDEOGRAPH
+0xA659 0x5403 #CJK UNIFIED IDEOGRAPH
+0xA65A 0x540E #CJK UNIFIED IDEOGRAPH
+0xA65B 0x5406 #CJK UNIFIED IDEOGRAPH
+0xA65C 0x5412 #CJK UNIFIED IDEOGRAPH
+0xA65D 0x56E0 #CJK UNIFIED IDEOGRAPH
+0xA65E 0x56DE #CJK UNIFIED IDEOGRAPH
+0xA65F 0x56DD #CJK UNIFIED IDEOGRAPH
+0xA660 0x5733 #CJK UNIFIED IDEOGRAPH
+0xA661 0x5730 #CJK UNIFIED IDEOGRAPH
+0xA662 0x5728 #CJK UNIFIED IDEOGRAPH
+0xA663 0x572D #CJK UNIFIED IDEOGRAPH
+0xA664 0x572C #CJK UNIFIED IDEOGRAPH
+0xA665 0x572F #CJK UNIFIED IDEOGRAPH
+0xA666 0x5729 #CJK UNIFIED IDEOGRAPH
+0xA667 0x5919 #CJK UNIFIED IDEOGRAPH
+0xA668 0x591A #CJK UNIFIED IDEOGRAPH
+0xA669 0x5937 #CJK UNIFIED IDEOGRAPH
+0xA66A 0x5938 #CJK UNIFIED IDEOGRAPH
+0xA66B 0x5984 #CJK UNIFIED IDEOGRAPH
+0xA66C 0x5978 #CJK UNIFIED IDEOGRAPH
+0xA66D 0x5983 #CJK UNIFIED IDEOGRAPH
+0xA66E 0x597D #CJK UNIFIED IDEOGRAPH
+0xA66F 0x5979 #CJK UNIFIED IDEOGRAPH
+0xA670 0x5982 #CJK UNIFIED IDEOGRAPH
+0xA671 0x5981 #CJK UNIFIED IDEOGRAPH
+0xA672 0x5B57 #CJK UNIFIED IDEOGRAPH
+0xA673 0x5B58 #CJK UNIFIED IDEOGRAPH
+0xA674 0x5B87 #CJK UNIFIED IDEOGRAPH
+0xA675 0x5B88 #CJK UNIFIED IDEOGRAPH
+0xA676 0x5B85 #CJK UNIFIED IDEOGRAPH
+0xA677 0x5B89 #CJK UNIFIED IDEOGRAPH
+0xA678 0x5BFA #CJK UNIFIED IDEOGRAPH
+0xA679 0x5C16 #CJK UNIFIED IDEOGRAPH
+0xA67A 0x5C79 #CJK UNIFIED IDEOGRAPH
+0xA67B 0x5DDE #CJK UNIFIED IDEOGRAPH
+0xA67C 0x5E06 #CJK UNIFIED IDEOGRAPH
+0xA67D 0x5E76 #CJK UNIFIED IDEOGRAPH
+0xA67E 0x5E74 #CJK UNIFIED IDEOGRAPH
+0xA6A1 0x5F0F #CJK UNIFIED IDEOGRAPH
+0xA6A2 0x5F1B #CJK UNIFIED IDEOGRAPH
+0xA6A3 0x5FD9 #CJK UNIFIED IDEOGRAPH
+0xA6A4 0x5FD6 #CJK UNIFIED IDEOGRAPH
+0xA6A5 0x620E #CJK UNIFIED IDEOGRAPH
+0xA6A6 0x620C #CJK UNIFIED IDEOGRAPH
+0xA6A7 0x620D #CJK UNIFIED IDEOGRAPH
+0xA6A8 0x6210 #CJK UNIFIED IDEOGRAPH
+0xA6A9 0x6263 #CJK UNIFIED IDEOGRAPH
+0xA6AA 0x625B #CJK UNIFIED IDEOGRAPH
+0xA6AB 0x6258 #CJK UNIFIED IDEOGRAPH
+0xA6AC 0x6536 #CJK UNIFIED IDEOGRAPH
+0xA6AD 0x65E9 #CJK UNIFIED IDEOGRAPH
+0xA6AE 0x65E8 #CJK UNIFIED IDEOGRAPH
+0xA6AF 0x65EC #CJK UNIFIED IDEOGRAPH
+0xA6B0 0x65ED #CJK UNIFIED IDEOGRAPH
+0xA6B1 0x66F2 #CJK UNIFIED IDEOGRAPH
+0xA6B2 0x66F3 #CJK UNIFIED IDEOGRAPH
+0xA6B3 0x6709 #CJK UNIFIED IDEOGRAPH
+0xA6B4 0x673D #CJK UNIFIED IDEOGRAPH
+0xA6B5 0x6734 #CJK UNIFIED IDEOGRAPH
+0xA6B6 0x6731 #CJK UNIFIED IDEOGRAPH
+0xA6B7 0x6735 #CJK UNIFIED IDEOGRAPH
+0xA6B8 0x6B21 #CJK UNIFIED IDEOGRAPH
+0xA6B9 0x6B64 #CJK UNIFIED IDEOGRAPH
+0xA6BA 0x6B7B #CJK UNIFIED IDEOGRAPH
+0xA6BB 0x6C16 #CJK UNIFIED IDEOGRAPH
+0xA6BC 0x6C5D #CJK UNIFIED IDEOGRAPH
+0xA6BD 0x6C57 #CJK UNIFIED IDEOGRAPH
+0xA6BE 0x6C59 #CJK UNIFIED IDEOGRAPH
+0xA6BF 0x6C5F #CJK UNIFIED IDEOGRAPH
+0xA6C0 0x6C60 #CJK UNIFIED IDEOGRAPH
+0xA6C1 0x6C50 #CJK UNIFIED IDEOGRAPH
+0xA6C2 0x6C55 #CJK UNIFIED IDEOGRAPH
+0xA6C3 0x6C61 #CJK UNIFIED IDEOGRAPH
+0xA6C4 0x6C5B #CJK UNIFIED IDEOGRAPH
+0xA6C5 0x6C4D #CJK UNIFIED IDEOGRAPH
+0xA6C6 0x6C4E #CJK UNIFIED IDEOGRAPH
+0xA6C7 0x7070 #CJK UNIFIED IDEOGRAPH
+0xA6C8 0x725F #CJK UNIFIED IDEOGRAPH
+0xA6C9 0x725D #CJK UNIFIED IDEOGRAPH
+0xA6CA 0x767E #CJK UNIFIED IDEOGRAPH
+0xA6CB 0x7AF9 #CJK UNIFIED IDEOGRAPH
+0xA6CC 0x7C73 #CJK UNIFIED IDEOGRAPH
+0xA6CD 0x7CF8 #CJK UNIFIED IDEOGRAPH
+0xA6CE 0x7F36 #CJK UNIFIED IDEOGRAPH
+0xA6CF 0x7F8A #CJK UNIFIED IDEOGRAPH
+0xA6D0 0x7FBD #CJK UNIFIED IDEOGRAPH
+0xA6D1 0x8001 #CJK UNIFIED IDEOGRAPH
+0xA6D2 0x8003 #CJK UNIFIED IDEOGRAPH
+0xA6D3 0x800C #CJK UNIFIED IDEOGRAPH
+0xA6D4 0x8012 #CJK UNIFIED IDEOGRAPH
+0xA6D5 0x8033 #CJK UNIFIED IDEOGRAPH
+0xA6D6 0x807F #CJK UNIFIED IDEOGRAPH
+0xA6D7 0x8089 #CJK UNIFIED IDEOGRAPH
+0xA6D8 0x808B #CJK UNIFIED IDEOGRAPH
+0xA6D9 0x808C #CJK UNIFIED IDEOGRAPH
+0xA6DA 0x81E3 #CJK UNIFIED IDEOGRAPH
+0xA6DB 0x81EA #CJK UNIFIED IDEOGRAPH
+0xA6DC 0x81F3 #CJK UNIFIED IDEOGRAPH
+0xA6DD 0x81FC #CJK UNIFIED IDEOGRAPH
+0xA6DE 0x820C #CJK UNIFIED IDEOGRAPH
+0xA6DF 0x821B #CJK UNIFIED IDEOGRAPH
+0xA6E0 0x821F #CJK UNIFIED IDEOGRAPH
+0xA6E1 0x826E #CJK UNIFIED IDEOGRAPH
+0xA6E2 0x8272 #CJK UNIFIED IDEOGRAPH
+0xA6E3 0x827E #CJK UNIFIED IDEOGRAPH
+0xA6E4 0x866B #CJK UNIFIED IDEOGRAPH
+0xA6E5 0x8840 #CJK UNIFIED IDEOGRAPH
+0xA6E6 0x884C #CJK UNIFIED IDEOGRAPH
+0xA6E7 0x8863 #CJK UNIFIED IDEOGRAPH
+0xA6E8 0x897F #CJK UNIFIED IDEOGRAPH
+0xA6E9 0x9621 #CJK UNIFIED IDEOGRAPH
+0xA6EA 0x4E32 #CJK UNIFIED IDEOGRAPH
+0xA6EB 0x4EA8 #CJK UNIFIED IDEOGRAPH
+0xA6EC 0x4F4D #CJK UNIFIED IDEOGRAPH
+0xA6ED 0x4F4F #CJK UNIFIED IDEOGRAPH
+0xA6EE 0x4F47 #CJK UNIFIED IDEOGRAPH
+0xA6EF 0x4F57 #CJK UNIFIED IDEOGRAPH
+0xA6F0 0x4F5E #CJK UNIFIED IDEOGRAPH
+0xA6F1 0x4F34 #CJK UNIFIED IDEOGRAPH
+0xA6F2 0x4F5B #CJK UNIFIED IDEOGRAPH
+0xA6F3 0x4F55 #CJK UNIFIED IDEOGRAPH
+0xA6F4 0x4F30 #CJK UNIFIED IDEOGRAPH
+0xA6F5 0x4F50 #CJK UNIFIED IDEOGRAPH
+0xA6F6 0x4F51 #CJK UNIFIED IDEOGRAPH
+0xA6F7 0x4F3D #CJK UNIFIED IDEOGRAPH
+0xA6F8 0x4F3A #CJK UNIFIED IDEOGRAPH
+0xA6F9 0x4F38 #CJK UNIFIED IDEOGRAPH
+0xA6FA 0x4F43 #CJK UNIFIED IDEOGRAPH
+0xA6FB 0x4F54 #CJK UNIFIED IDEOGRAPH
+0xA6FC 0x4F3C #CJK UNIFIED IDEOGRAPH
+0xA6FD 0x4F46 #CJK UNIFIED IDEOGRAPH
+0xA6FE 0x4F63 #CJK UNIFIED IDEOGRAPH
+0xA740 0x4F5C #CJK UNIFIED IDEOGRAPH
+0xA741 0x4F60 #CJK UNIFIED IDEOGRAPH
+0xA742 0x4F2F #CJK UNIFIED IDEOGRAPH
+0xA743 0x4F4E #CJK UNIFIED IDEOGRAPH
+0xA744 0x4F36 #CJK UNIFIED IDEOGRAPH
+0xA745 0x4F59 #CJK UNIFIED IDEOGRAPH
+0xA746 0x4F5D #CJK UNIFIED IDEOGRAPH
+0xA747 0x4F48 #CJK UNIFIED IDEOGRAPH
+0xA748 0x4F5A #CJK UNIFIED IDEOGRAPH
+0xA749 0x514C #CJK UNIFIED IDEOGRAPH
+0xA74A 0x514B #CJK UNIFIED IDEOGRAPH
+0xA74B 0x514D #CJK UNIFIED IDEOGRAPH
+0xA74C 0x5175 #CJK UNIFIED IDEOGRAPH
+0xA74D 0x51B6 #CJK UNIFIED IDEOGRAPH
+0xA74E 0x51B7 #CJK UNIFIED IDEOGRAPH
+0xA74F 0x5225 #CJK UNIFIED IDEOGRAPH
+0xA750 0x5224 #CJK UNIFIED IDEOGRAPH
+0xA751 0x5229 #CJK UNIFIED IDEOGRAPH
+0xA752 0x522A #CJK UNIFIED IDEOGRAPH
+0xA753 0x5228 #CJK UNIFIED IDEOGRAPH
+0xA754 0x52AB #CJK UNIFIED IDEOGRAPH
+0xA755 0x52A9 #CJK UNIFIED IDEOGRAPH
+0xA756 0x52AA #CJK UNIFIED IDEOGRAPH
+0xA757 0x52AC #CJK UNIFIED IDEOGRAPH
+0xA758 0x5323 #CJK UNIFIED IDEOGRAPH
+0xA759 0x5373 #CJK UNIFIED IDEOGRAPH
+0xA75A 0x5375 #CJK UNIFIED IDEOGRAPH
+0xA75B 0x541D #CJK UNIFIED IDEOGRAPH
+0xA75C 0x542D #CJK UNIFIED IDEOGRAPH
+0xA75D 0x541E #CJK UNIFIED IDEOGRAPH
+0xA75E 0x543E #CJK UNIFIED IDEOGRAPH
+0xA75F 0x5426 #CJK UNIFIED IDEOGRAPH
+0xA760 0x544E #CJK UNIFIED IDEOGRAPH
+0xA761 0x5427 #CJK UNIFIED IDEOGRAPH
+0xA762 0x5446 #CJK UNIFIED IDEOGRAPH
+0xA763 0x5443 #CJK UNIFIED IDEOGRAPH
+0xA764 0x5433 #CJK UNIFIED IDEOGRAPH
+0xA765 0x5448 #CJK UNIFIED IDEOGRAPH
+0xA766 0x5442 #CJK UNIFIED IDEOGRAPH
+0xA767 0x541B #CJK UNIFIED IDEOGRAPH
+0xA768 0x5429 #CJK UNIFIED IDEOGRAPH
+0xA769 0x544A #CJK UNIFIED IDEOGRAPH
+0xA76A 0x5439 #CJK UNIFIED IDEOGRAPH
+0xA76B 0x543B #CJK UNIFIED IDEOGRAPH
+0xA76C 0x5438 #CJK UNIFIED IDEOGRAPH
+0xA76D 0x542E #CJK UNIFIED IDEOGRAPH
+0xA76E 0x5435 #CJK UNIFIED IDEOGRAPH
+0xA76F 0x5436 #CJK UNIFIED IDEOGRAPH
+0xA770 0x5420 #CJK UNIFIED IDEOGRAPH
+0xA771 0x543C #CJK UNIFIED IDEOGRAPH
+0xA772 0x5440 #CJK UNIFIED IDEOGRAPH
+0xA773 0x5431 #CJK UNIFIED IDEOGRAPH
+0xA774 0x542B #CJK UNIFIED IDEOGRAPH
+0xA775 0x541F #CJK UNIFIED IDEOGRAPH
+0xA776 0x542C #CJK UNIFIED IDEOGRAPH
+0xA777 0x56EA #CJK UNIFIED IDEOGRAPH
+0xA778 0x56F0 #CJK UNIFIED IDEOGRAPH
+0xA779 0x56E4 #CJK UNIFIED IDEOGRAPH
+0xA77A 0x56EB #CJK UNIFIED IDEOGRAPH
+0xA77B 0x574A #CJK UNIFIED IDEOGRAPH
+0xA77C 0x5751 #CJK UNIFIED IDEOGRAPH
+0xA77D 0x5740 #CJK UNIFIED IDEOGRAPH
+0xA77E 0x574D #CJK UNIFIED IDEOGRAPH
+0xA7A1 0x5747 #CJK UNIFIED IDEOGRAPH
+0xA7A2 0x574E #CJK UNIFIED IDEOGRAPH
+0xA7A3 0x573E #CJK UNIFIED IDEOGRAPH
+0xA7A4 0x5750 #CJK UNIFIED IDEOGRAPH
+0xA7A5 0x574F #CJK UNIFIED IDEOGRAPH
+0xA7A6 0x573B #CJK UNIFIED IDEOGRAPH
+0xA7A7 0x58EF #CJK UNIFIED IDEOGRAPH
+0xA7A8 0x593E #CJK UNIFIED IDEOGRAPH
+0xA7A9 0x599D #CJK UNIFIED IDEOGRAPH
+0xA7AA 0x5992 #CJK UNIFIED IDEOGRAPH
+0xA7AB 0x59A8 #CJK UNIFIED IDEOGRAPH
+0xA7AC 0x599E #CJK UNIFIED IDEOGRAPH
+0xA7AD 0x59A3 #CJK UNIFIED IDEOGRAPH
+0xA7AE 0x5999 #CJK UNIFIED IDEOGRAPH
+0xA7AF 0x5996 #CJK UNIFIED IDEOGRAPH
+0xA7B0 0x598D #CJK UNIFIED IDEOGRAPH
+0xA7B1 0x59A4 #CJK UNIFIED IDEOGRAPH
+0xA7B2 0x5993 #CJK UNIFIED IDEOGRAPH
+0xA7B3 0x598A #CJK UNIFIED IDEOGRAPH
+0xA7B4 0x59A5 #CJK UNIFIED IDEOGRAPH
+0xA7B5 0x5B5D #CJK UNIFIED IDEOGRAPH
+0xA7B6 0x5B5C #CJK UNIFIED IDEOGRAPH
+0xA7B7 0x5B5A #CJK UNIFIED IDEOGRAPH
+0xA7B8 0x5B5B #CJK UNIFIED IDEOGRAPH
+0xA7B9 0x5B8C #CJK UNIFIED IDEOGRAPH
+0xA7BA 0x5B8B #CJK UNIFIED IDEOGRAPH
+0xA7BB 0x5B8F #CJK UNIFIED IDEOGRAPH
+0xA7BC 0x5C2C #CJK UNIFIED IDEOGRAPH
+0xA7BD 0x5C40 #CJK UNIFIED IDEOGRAPH
+0xA7BE 0x5C41 #CJK UNIFIED IDEOGRAPH
+0xA7BF 0x5C3F #CJK UNIFIED IDEOGRAPH
+0xA7C0 0x5C3E #CJK UNIFIED IDEOGRAPH
+0xA7C1 0x5C90 #CJK UNIFIED IDEOGRAPH
+0xA7C2 0x5C91 #CJK UNIFIED IDEOGRAPH
+0xA7C3 0x5C94 #CJK UNIFIED IDEOGRAPH
+0xA7C4 0x5C8C #CJK UNIFIED IDEOGRAPH
+0xA7C5 0x5DEB #CJK UNIFIED IDEOGRAPH
+0xA7C6 0x5E0C #CJK UNIFIED IDEOGRAPH
+0xA7C7 0x5E8F #CJK UNIFIED IDEOGRAPH
+0xA7C8 0x5E87 #CJK UNIFIED IDEOGRAPH
+0xA7C9 0x5E8A #CJK UNIFIED IDEOGRAPH
+0xA7CA 0x5EF7 #CJK UNIFIED IDEOGRAPH
+0xA7CB 0x5F04 #CJK UNIFIED IDEOGRAPH
+0xA7CC 0x5F1F #CJK UNIFIED IDEOGRAPH
+0xA7CD 0x5F64 #CJK UNIFIED IDEOGRAPH
+0xA7CE 0x5F62 #CJK UNIFIED IDEOGRAPH
+0xA7CF 0x5F77 #CJK UNIFIED IDEOGRAPH
+0xA7D0 0x5F79 #CJK UNIFIED IDEOGRAPH
+0xA7D1 0x5FD8 #CJK UNIFIED IDEOGRAPH
+0xA7D2 0x5FCC #CJK UNIFIED IDEOGRAPH
+0xA7D3 0x5FD7 #CJK UNIFIED IDEOGRAPH
+0xA7D4 0x5FCD #CJK UNIFIED IDEOGRAPH
+0xA7D5 0x5FF1 #CJK UNIFIED IDEOGRAPH
+0xA7D6 0x5FEB #CJK UNIFIED IDEOGRAPH
+0xA7D7 0x5FF8 #CJK UNIFIED IDEOGRAPH
+0xA7D8 0x5FEA #CJK UNIFIED IDEOGRAPH
+0xA7D9 0x6212 #CJK UNIFIED IDEOGRAPH
+0xA7DA 0x6211 #CJK UNIFIED IDEOGRAPH
+0xA7DB 0x6284 #CJK UNIFIED IDEOGRAPH
+0xA7DC 0x6297 #CJK UNIFIED IDEOGRAPH
+0xA7DD 0x6296 #CJK UNIFIED IDEOGRAPH
+0xA7DE 0x6280 #CJK UNIFIED IDEOGRAPH
+0xA7DF 0x6276 #CJK UNIFIED IDEOGRAPH
+0xA7E0 0x6289 #CJK UNIFIED IDEOGRAPH
+0xA7E1 0x626D #CJK UNIFIED IDEOGRAPH
+0xA7E2 0x628A #CJK UNIFIED IDEOGRAPH
+0xA7E3 0x627C #CJK UNIFIED IDEOGRAPH
+0xA7E4 0x627E #CJK UNIFIED IDEOGRAPH
+0xA7E5 0x6279 #CJK UNIFIED IDEOGRAPH
+0xA7E6 0x6273 #CJK UNIFIED IDEOGRAPH
+0xA7E7 0x6292 #CJK UNIFIED IDEOGRAPH
+0xA7E8 0x626F #CJK UNIFIED IDEOGRAPH
+0xA7E9 0x6298 #CJK UNIFIED IDEOGRAPH
+0xA7EA 0x626E #CJK UNIFIED IDEOGRAPH
+0xA7EB 0x6295 #CJK UNIFIED IDEOGRAPH
+0xA7EC 0x6293 #CJK UNIFIED IDEOGRAPH
+0xA7ED 0x6291 #CJK UNIFIED IDEOGRAPH
+0xA7EE 0x6286 #CJK UNIFIED IDEOGRAPH
+0xA7EF 0x6539 #CJK UNIFIED IDEOGRAPH
+0xA7F0 0x653B #CJK UNIFIED IDEOGRAPH
+0xA7F1 0x6538 #CJK UNIFIED IDEOGRAPH
+0xA7F2 0x65F1 #CJK UNIFIED IDEOGRAPH
+0xA7F3 0x66F4 #CJK UNIFIED IDEOGRAPH
+0xA7F4 0x675F #CJK UNIFIED IDEOGRAPH
+0xA7F5 0x674E #CJK UNIFIED IDEOGRAPH
+0xA7F6 0x674F #CJK UNIFIED IDEOGRAPH
+0xA7F7 0x6750 #CJK UNIFIED IDEOGRAPH
+0xA7F8 0x6751 #CJK UNIFIED IDEOGRAPH
+0xA7F9 0x675C #CJK UNIFIED IDEOGRAPH
+0xA7FA 0x6756 #CJK UNIFIED IDEOGRAPH
+0xA7FB 0x675E #CJK UNIFIED IDEOGRAPH
+0xA7FC 0x6749 #CJK UNIFIED IDEOGRAPH
+0xA7FD 0x6746 #CJK UNIFIED IDEOGRAPH
+0xA7FE 0x6760 #CJK UNIFIED IDEOGRAPH
+0xA840 0x6753 #CJK UNIFIED IDEOGRAPH
+0xA841 0x6757 #CJK UNIFIED IDEOGRAPH
+0xA842 0x6B65 #CJK UNIFIED IDEOGRAPH
+0xA843 0x6BCF #CJK UNIFIED IDEOGRAPH
+0xA844 0x6C42 #CJK UNIFIED IDEOGRAPH
+0xA845 0x6C5E #CJK UNIFIED IDEOGRAPH
+0xA846 0x6C99 #CJK UNIFIED IDEOGRAPH
+0xA847 0x6C81 #CJK UNIFIED IDEOGRAPH
+0xA848 0x6C88 #CJK UNIFIED IDEOGRAPH
+0xA849 0x6C89 #CJK UNIFIED IDEOGRAPH
+0xA84A 0x6C85 #CJK UNIFIED IDEOGRAPH
+0xA84B 0x6C9B #CJK UNIFIED IDEOGRAPH
+0xA84C 0x6C6A #CJK UNIFIED IDEOGRAPH
+0xA84D 0x6C7A #CJK UNIFIED IDEOGRAPH
+0xA84E 0x6C90 #CJK UNIFIED IDEOGRAPH
+0xA84F 0x6C70 #CJK UNIFIED IDEOGRAPH
+0xA850 0x6C8C #CJK UNIFIED IDEOGRAPH
+0xA851 0x6C68 #CJK UNIFIED IDEOGRAPH
+0xA852 0x6C96 #CJK UNIFIED IDEOGRAPH
+0xA853 0x6C92 #CJK UNIFIED IDEOGRAPH
+0xA854 0x6C7D #CJK UNIFIED IDEOGRAPH
+0xA855 0x6C83 #CJK UNIFIED IDEOGRAPH
+0xA856 0x6C72 #CJK UNIFIED IDEOGRAPH
+0xA857 0x6C7E #CJK UNIFIED IDEOGRAPH
+0xA858 0x6C74 #CJK UNIFIED IDEOGRAPH
+0xA859 0x6C86 #CJK UNIFIED IDEOGRAPH
+0xA85A 0x6C76 #CJK UNIFIED IDEOGRAPH
+0xA85B 0x6C8D #CJK UNIFIED IDEOGRAPH
+0xA85C 0x6C94 #CJK UNIFIED IDEOGRAPH
+0xA85D 0x6C98 #CJK UNIFIED IDEOGRAPH
+0xA85E 0x6C82 #CJK UNIFIED IDEOGRAPH
+0xA85F 0x7076 #CJK UNIFIED IDEOGRAPH
+0xA860 0x707C #CJK UNIFIED IDEOGRAPH
+0xA861 0x707D #CJK UNIFIED IDEOGRAPH
+0xA862 0x7078 #CJK UNIFIED IDEOGRAPH
+0xA863 0x7262 #CJK UNIFIED IDEOGRAPH
+0xA864 0x7261 #CJK UNIFIED IDEOGRAPH
+0xA865 0x7260 #CJK UNIFIED IDEOGRAPH
+0xA866 0x72C4 #CJK UNIFIED IDEOGRAPH
+0xA867 0x72C2 #CJK UNIFIED IDEOGRAPH
+0xA868 0x7396 #CJK UNIFIED IDEOGRAPH
+0xA869 0x752C #CJK UNIFIED IDEOGRAPH
+0xA86A 0x752B #CJK UNIFIED IDEOGRAPH
+0xA86B 0x7537 #CJK UNIFIED IDEOGRAPH
+0xA86C 0x7538 #CJK UNIFIED IDEOGRAPH
+0xA86D 0x7682 #CJK UNIFIED IDEOGRAPH
+0xA86E 0x76EF #CJK UNIFIED IDEOGRAPH
+0xA86F 0x77E3 #CJK UNIFIED IDEOGRAPH
+0xA870 0x79C1 #CJK UNIFIED IDEOGRAPH
+0xA871 0x79C0 #CJK UNIFIED IDEOGRAPH
+0xA872 0x79BF #CJK UNIFIED IDEOGRAPH
+0xA873 0x7A76 #CJK UNIFIED IDEOGRAPH
+0xA874 0x7CFB #CJK UNIFIED IDEOGRAPH
+0xA875 0x7F55 #CJK UNIFIED IDEOGRAPH
+0xA876 0x8096 #CJK UNIFIED IDEOGRAPH
+0xA877 0x8093 #CJK UNIFIED IDEOGRAPH
+0xA878 0x809D #CJK UNIFIED IDEOGRAPH
+0xA879 0x8098 #CJK UNIFIED IDEOGRAPH
+0xA87A 0x809B #CJK UNIFIED IDEOGRAPH
+0xA87B 0x809A #CJK UNIFIED IDEOGRAPH
+0xA87C 0x80B2 #CJK UNIFIED IDEOGRAPH
+0xA87D 0x826F #CJK UNIFIED IDEOGRAPH
+0xA87E 0x8292 #CJK UNIFIED IDEOGRAPH
+0xA8A1 0x828B #CJK UNIFIED IDEOGRAPH
+0xA8A2 0x828D #CJK UNIFIED IDEOGRAPH
+0xA8A3 0x898B #CJK UNIFIED IDEOGRAPH
+0xA8A4 0x89D2 #CJK UNIFIED IDEOGRAPH
+0xA8A5 0x8A00 #CJK UNIFIED IDEOGRAPH
+0xA8A6 0x8C37 #CJK UNIFIED IDEOGRAPH
+0xA8A7 0x8C46 #CJK UNIFIED IDEOGRAPH
+0xA8A8 0x8C55 #CJK UNIFIED IDEOGRAPH
+0xA8A9 0x8C9D #CJK UNIFIED IDEOGRAPH
+0xA8AA 0x8D64 #CJK UNIFIED IDEOGRAPH
+0xA8AB 0x8D70 #CJK UNIFIED IDEOGRAPH
+0xA8AC 0x8DB3 #CJK UNIFIED IDEOGRAPH
+0xA8AD 0x8EAB #CJK UNIFIED IDEOGRAPH
+0xA8AE 0x8ECA #CJK UNIFIED IDEOGRAPH
+0xA8AF 0x8F9B #CJK UNIFIED IDEOGRAPH
+0xA8B0 0x8FB0 #CJK UNIFIED IDEOGRAPH
+0xA8B1 0x8FC2 #CJK UNIFIED IDEOGRAPH
+0xA8B2 0x8FC6 #CJK UNIFIED IDEOGRAPH
+0xA8B3 0x8FC5 #CJK UNIFIED IDEOGRAPH
+0xA8B4 0x8FC4 #CJK UNIFIED IDEOGRAPH
+0xA8B5 0x5DE1 #CJK UNIFIED IDEOGRAPH
+0xA8B6 0x9091 #CJK UNIFIED IDEOGRAPH
+0xA8B7 0x90A2 #CJK UNIFIED IDEOGRAPH
+0xA8B8 0x90AA #CJK UNIFIED IDEOGRAPH
+0xA8B9 0x90A6 #CJK UNIFIED IDEOGRAPH
+0xA8BA 0x90A3 #CJK UNIFIED IDEOGRAPH
+0xA8BB 0x9149 #CJK UNIFIED IDEOGRAPH
+0xA8BC 0x91C6 #CJK UNIFIED IDEOGRAPH
+0xA8BD 0x91CC #CJK UNIFIED IDEOGRAPH
+0xA8BE 0x9632 #CJK UNIFIED IDEOGRAPH
+0xA8BF 0x962E #CJK UNIFIED IDEOGRAPH
+0xA8C0 0x9631 #CJK UNIFIED IDEOGRAPH
+0xA8C1 0x962A #CJK UNIFIED IDEOGRAPH
+0xA8C2 0x962C #CJK UNIFIED IDEOGRAPH
+0xA8C3 0x4E26 #CJK UNIFIED IDEOGRAPH
+0xA8C4 0x4E56 #CJK UNIFIED IDEOGRAPH
+0xA8C5 0x4E73 #CJK UNIFIED IDEOGRAPH
+0xA8C6 0x4E8B #CJK UNIFIED IDEOGRAPH
+0xA8C7 0x4E9B #CJK UNIFIED IDEOGRAPH
+0xA8C8 0x4E9E #CJK UNIFIED IDEOGRAPH
+0xA8C9 0x4EAB #CJK UNIFIED IDEOGRAPH
+0xA8CA 0x4EAC #CJK UNIFIED IDEOGRAPH
+0xA8CB 0x4F6F #CJK UNIFIED IDEOGRAPH
+0xA8CC 0x4F9D #CJK UNIFIED IDEOGRAPH
+0xA8CD 0x4F8D #CJK UNIFIED IDEOGRAPH
+0xA8CE 0x4F73 #CJK UNIFIED IDEOGRAPH
+0xA8CF 0x4F7F #CJK UNIFIED IDEOGRAPH
+0xA8D0 0x4F6C #CJK UNIFIED IDEOGRAPH
+0xA8D1 0x4F9B #CJK UNIFIED IDEOGRAPH
+0xA8D2 0x4F8B #CJK UNIFIED IDEOGRAPH
+0xA8D3 0x4F86 #CJK UNIFIED IDEOGRAPH
+0xA8D4 0x4F83 #CJK UNIFIED IDEOGRAPH
+0xA8D5 0x4F70 #CJK UNIFIED IDEOGRAPH
+0xA8D6 0x4F75 #CJK UNIFIED IDEOGRAPH
+0xA8D7 0x4F88 #CJK UNIFIED IDEOGRAPH
+0xA8D8 0x4F69 #CJK UNIFIED IDEOGRAPH
+0xA8D9 0x4F7B #CJK UNIFIED IDEOGRAPH
+0xA8DA 0x4F96 #CJK UNIFIED IDEOGRAPH
+0xA8DB 0x4F7E #CJK UNIFIED IDEOGRAPH
+0xA8DC 0x4F8F #CJK UNIFIED IDEOGRAPH
+0xA8DD 0x4F91 #CJK UNIFIED IDEOGRAPH
+0xA8DE 0x4F7A #CJK UNIFIED IDEOGRAPH
+0xA8DF 0x5154 #CJK UNIFIED IDEOGRAPH
+0xA8E0 0x5152 #CJK UNIFIED IDEOGRAPH
+0xA8E1 0x5155 #CJK UNIFIED IDEOGRAPH
+0xA8E2 0x5169 #CJK UNIFIED IDEOGRAPH
+0xA8E3 0x5177 #CJK UNIFIED IDEOGRAPH
+0xA8E4 0x5176 #CJK UNIFIED IDEOGRAPH
+0xA8E5 0x5178 #CJK UNIFIED IDEOGRAPH
+0xA8E6 0x51BD #CJK UNIFIED IDEOGRAPH
+0xA8E7 0x51FD #CJK UNIFIED IDEOGRAPH
+0xA8E8 0x523B #CJK UNIFIED IDEOGRAPH
+0xA8E9 0x5238 #CJK UNIFIED IDEOGRAPH
+0xA8EA 0x5237 #CJK UNIFIED IDEOGRAPH
+0xA8EB 0x523A #CJK UNIFIED IDEOGRAPH
+0xA8EC 0x5230 #CJK UNIFIED IDEOGRAPH
+0xA8ED 0x522E #CJK UNIFIED IDEOGRAPH
+0xA8EE 0x5236 #CJK UNIFIED IDEOGRAPH
+0xA8EF 0x5241 #CJK UNIFIED IDEOGRAPH
+0xA8F0 0x52BE #CJK UNIFIED IDEOGRAPH
+0xA8F1 0x52BB #CJK UNIFIED IDEOGRAPH
+0xA8F2 0x5352 #CJK UNIFIED IDEOGRAPH
+0xA8F3 0x5354 #CJK UNIFIED IDEOGRAPH
+0xA8F4 0x5353 #CJK UNIFIED IDEOGRAPH
+0xA8F5 0x5351 #CJK UNIFIED IDEOGRAPH
+0xA8F6 0x5366 #CJK UNIFIED IDEOGRAPH
+0xA8F7 0x5377 #CJK UNIFIED IDEOGRAPH
+0xA8F8 0x5378 #CJK UNIFIED IDEOGRAPH
+0xA8F9 0x5379 #CJK UNIFIED IDEOGRAPH
+0xA8FA 0x53D6 #CJK UNIFIED IDEOGRAPH
+0xA8FB 0x53D4 #CJK UNIFIED IDEOGRAPH
+0xA8FC 0x53D7 #CJK UNIFIED IDEOGRAPH
+0xA8FD 0x5473 #CJK UNIFIED IDEOGRAPH
+0xA8FE 0x5475 #CJK UNIFIED IDEOGRAPH
+0xA940 0x5496 #CJK UNIFIED IDEOGRAPH
+0xA941 0x5478 #CJK UNIFIED IDEOGRAPH
+0xA942 0x5495 #CJK UNIFIED IDEOGRAPH
+0xA943 0x5480 #CJK UNIFIED IDEOGRAPH
+0xA944 0x547B #CJK UNIFIED IDEOGRAPH
+0xA945 0x5477 #CJK UNIFIED IDEOGRAPH
+0xA946 0x5484 #CJK UNIFIED IDEOGRAPH
+0xA947 0x5492 #CJK UNIFIED IDEOGRAPH
+0xA948 0x5486 #CJK UNIFIED IDEOGRAPH
+0xA949 0x547C #CJK UNIFIED IDEOGRAPH
+0xA94A 0x5490 #CJK UNIFIED IDEOGRAPH
+0xA94B 0x5471 #CJK UNIFIED IDEOGRAPH
+0xA94C 0x5476 #CJK UNIFIED IDEOGRAPH
+0xA94D 0x548C #CJK UNIFIED IDEOGRAPH
+0xA94E 0x549A #CJK UNIFIED IDEOGRAPH
+0xA94F 0x5462 #CJK UNIFIED IDEOGRAPH
+0xA950 0x5468 #CJK UNIFIED IDEOGRAPH
+0xA951 0x548B #CJK UNIFIED IDEOGRAPH
+0xA952 0x547D #CJK UNIFIED IDEOGRAPH
+0xA953 0x548E #CJK UNIFIED IDEOGRAPH
+0xA954 0x56FA #CJK UNIFIED IDEOGRAPH
+0xA955 0x5783 #CJK UNIFIED IDEOGRAPH
+0xA956 0x5777 #CJK UNIFIED IDEOGRAPH
+0xA957 0x576A #CJK UNIFIED IDEOGRAPH
+0xA958 0x5769 #CJK UNIFIED IDEOGRAPH
+0xA959 0x5761 #CJK UNIFIED IDEOGRAPH
+0xA95A 0x5766 #CJK UNIFIED IDEOGRAPH
+0xA95B 0x5764 #CJK UNIFIED IDEOGRAPH
+0xA95C 0x577C #CJK UNIFIED IDEOGRAPH
+0xA95D 0x591C #CJK UNIFIED IDEOGRAPH
+0xA95E 0x5949 #CJK UNIFIED IDEOGRAPH
+0xA95F 0x5947 #CJK UNIFIED IDEOGRAPH
+0xA960 0x5948 #CJK UNIFIED IDEOGRAPH
+0xA961 0x5944 #CJK UNIFIED IDEOGRAPH
+0xA962 0x5954 #CJK UNIFIED IDEOGRAPH
+0xA963 0x59BE #CJK UNIFIED IDEOGRAPH
+0xA964 0x59BB #CJK UNIFIED IDEOGRAPH
+0xA965 0x59D4 #CJK UNIFIED IDEOGRAPH
+0xA966 0x59B9 #CJK UNIFIED IDEOGRAPH
+0xA967 0x59AE #CJK UNIFIED IDEOGRAPH
+0xA968 0x59D1 #CJK UNIFIED IDEOGRAPH
+0xA969 0x59C6 #CJK UNIFIED IDEOGRAPH
+0xA96A 0x59D0 #CJK UNIFIED IDEOGRAPH
+0xA96B 0x59CD #CJK UNIFIED IDEOGRAPH
+0xA96C 0x59CB #CJK UNIFIED IDEOGRAPH
+0xA96D 0x59D3 #CJK UNIFIED IDEOGRAPH
+0xA96E 0x59CA #CJK UNIFIED IDEOGRAPH
+0xA96F 0x59AF #CJK UNIFIED IDEOGRAPH
+0xA970 0x59B3 #CJK UNIFIED IDEOGRAPH
+0xA971 0x59D2 #CJK UNIFIED IDEOGRAPH
+0xA972 0x59C5 #CJK UNIFIED IDEOGRAPH
+0xA973 0x5B5F #CJK UNIFIED IDEOGRAPH
+0xA974 0x5B64 #CJK UNIFIED IDEOGRAPH
+0xA975 0x5B63 #CJK UNIFIED IDEOGRAPH
+0xA976 0x5B97 #CJK UNIFIED IDEOGRAPH
+0xA977 0x5B9A #CJK UNIFIED IDEOGRAPH
+0xA978 0x5B98 #CJK UNIFIED IDEOGRAPH
+0xA979 0x5B9C #CJK UNIFIED IDEOGRAPH
+0xA97A 0x5B99 #CJK UNIFIED IDEOGRAPH
+0xA97B 0x5B9B #CJK UNIFIED IDEOGRAPH
+0xA97C 0x5C1A #CJK UNIFIED IDEOGRAPH
+0xA97D 0x5C48 #CJK UNIFIED IDEOGRAPH
+0xA97E 0x5C45 #CJK UNIFIED IDEOGRAPH
+0xA9A1 0x5C46 #CJK UNIFIED IDEOGRAPH
+0xA9A2 0x5CB7 #CJK UNIFIED IDEOGRAPH
+0xA9A3 0x5CA1 #CJK UNIFIED IDEOGRAPH
+0xA9A4 0x5CB8 #CJK UNIFIED IDEOGRAPH
+0xA9A5 0x5CA9 #CJK UNIFIED IDEOGRAPH
+0xA9A6 0x5CAB #CJK UNIFIED IDEOGRAPH
+0xA9A7 0x5CB1 #CJK UNIFIED IDEOGRAPH
+0xA9A8 0x5CB3 #CJK UNIFIED IDEOGRAPH
+0xA9A9 0x5E18 #CJK UNIFIED IDEOGRAPH
+0xA9AA 0x5E1A #CJK UNIFIED IDEOGRAPH
+0xA9AB 0x5E16 #CJK UNIFIED IDEOGRAPH
+0xA9AC 0x5E15 #CJK UNIFIED IDEOGRAPH
+0xA9AD 0x5E1B #CJK UNIFIED IDEOGRAPH
+0xA9AE 0x5E11 #CJK UNIFIED IDEOGRAPH
+0xA9AF 0x5E78 #CJK UNIFIED IDEOGRAPH
+0xA9B0 0x5E9A #CJK UNIFIED IDEOGRAPH
+0xA9B1 0x5E97 #CJK UNIFIED IDEOGRAPH
+0xA9B2 0x5E9C #CJK UNIFIED IDEOGRAPH
+0xA9B3 0x5E95 #CJK UNIFIED IDEOGRAPH
+0xA9B4 0x5E96 #CJK UNIFIED IDEOGRAPH
+0xA9B5 0x5EF6 #CJK UNIFIED IDEOGRAPH
+0xA9B6 0x5F26 #CJK UNIFIED IDEOGRAPH
+0xA9B7 0x5F27 #CJK UNIFIED IDEOGRAPH
+0xA9B8 0x5F29 #CJK UNIFIED IDEOGRAPH
+0xA9B9 0x5F80 #CJK UNIFIED IDEOGRAPH
+0xA9BA 0x5F81 #CJK UNIFIED IDEOGRAPH
+0xA9BB 0x5F7F #CJK UNIFIED IDEOGRAPH
+0xA9BC 0x5F7C #CJK UNIFIED IDEOGRAPH
+0xA9BD 0x5FDD #CJK UNIFIED IDEOGRAPH
+0xA9BE 0x5FE0 #CJK UNIFIED IDEOGRAPH
+0xA9BF 0x5FFD #CJK UNIFIED IDEOGRAPH
+0xA9C0 0x5FF5 #CJK UNIFIED IDEOGRAPH
+0xA9C1 0x5FFF #CJK UNIFIED IDEOGRAPH
+0xA9C2 0x600F #CJK UNIFIED IDEOGRAPH
+0xA9C3 0x6014 #CJK UNIFIED IDEOGRAPH
+0xA9C4 0x602F #CJK UNIFIED IDEOGRAPH
+0xA9C5 0x6035 #CJK UNIFIED IDEOGRAPH
+0xA9C6 0x6016 #CJK UNIFIED IDEOGRAPH
+0xA9C7 0x602A #CJK UNIFIED IDEOGRAPH
+0xA9C8 0x6015 #CJK UNIFIED IDEOGRAPH
+0xA9C9 0x6021 #CJK UNIFIED IDEOGRAPH
+0xA9CA 0x6027 #CJK UNIFIED IDEOGRAPH
+0xA9CB 0x6029 #CJK UNIFIED IDEOGRAPH
+0xA9CC 0x602B #CJK UNIFIED IDEOGRAPH
+0xA9CD 0x601B #CJK UNIFIED IDEOGRAPH
+0xA9CE 0x6216 #CJK UNIFIED IDEOGRAPH
+0xA9CF 0x6215 #CJK UNIFIED IDEOGRAPH
+0xA9D0 0x623F #CJK UNIFIED IDEOGRAPH
+0xA9D1 0x623E #CJK UNIFIED IDEOGRAPH
+0xA9D2 0x6240 #CJK UNIFIED IDEOGRAPH
+0xA9D3 0x627F #CJK UNIFIED IDEOGRAPH
+0xA9D4 0x62C9 #CJK UNIFIED IDEOGRAPH
+0xA9D5 0x62CC #CJK UNIFIED IDEOGRAPH
+0xA9D6 0x62C4 #CJK UNIFIED IDEOGRAPH
+0xA9D7 0x62BF #CJK UNIFIED IDEOGRAPH
+0xA9D8 0x62C2 #CJK UNIFIED IDEOGRAPH
+0xA9D9 0x62B9 #CJK UNIFIED IDEOGRAPH
+0xA9DA 0x62D2 #CJK UNIFIED IDEOGRAPH
+0xA9DB 0x62DB #CJK UNIFIED IDEOGRAPH
+0xA9DC 0x62AB #CJK UNIFIED IDEOGRAPH
+0xA9DD 0x62D3 #CJK UNIFIED IDEOGRAPH
+0xA9DE 0x62D4 #CJK UNIFIED IDEOGRAPH
+0xA9DF 0x62CB #CJK UNIFIED IDEOGRAPH
+0xA9E0 0x62C8 #CJK UNIFIED IDEOGRAPH
+0xA9E1 0x62A8 #CJK UNIFIED IDEOGRAPH
+0xA9E2 0x62BD #CJK UNIFIED IDEOGRAPH
+0xA9E3 0x62BC #CJK UNIFIED IDEOGRAPH
+0xA9E4 0x62D0 #CJK UNIFIED IDEOGRAPH
+0xA9E5 0x62D9 #CJK UNIFIED IDEOGRAPH
+0xA9E6 0x62C7 #CJK UNIFIED IDEOGRAPH
+0xA9E7 0x62CD #CJK UNIFIED IDEOGRAPH
+0xA9E8 0x62B5 #CJK UNIFIED IDEOGRAPH
+0xA9E9 0x62DA #CJK UNIFIED IDEOGRAPH
+0xA9EA 0x62B1 #CJK UNIFIED IDEOGRAPH
+0xA9EB 0x62D8 #CJK UNIFIED IDEOGRAPH
+0xA9EC 0x62D6 #CJK UNIFIED IDEOGRAPH
+0xA9ED 0x62D7 #CJK UNIFIED IDEOGRAPH
+0xA9EE 0x62C6 #CJK UNIFIED IDEOGRAPH
+0xA9EF 0x62AC #CJK UNIFIED IDEOGRAPH
+0xA9F0 0x62CE #CJK UNIFIED IDEOGRAPH
+0xA9F1 0x653E #CJK UNIFIED IDEOGRAPH
+0xA9F2 0x65A7 #CJK UNIFIED IDEOGRAPH
+0xA9F3 0x65BC #CJK UNIFIED IDEOGRAPH
+0xA9F4 0x65FA #CJK UNIFIED IDEOGRAPH
+0xA9F5 0x6614 #CJK UNIFIED IDEOGRAPH
+0xA9F6 0x6613 #CJK UNIFIED IDEOGRAPH
+0xA9F7 0x660C #CJK UNIFIED IDEOGRAPH
+0xA9F8 0x6606 #CJK UNIFIED IDEOGRAPH
+0xA9F9 0x6602 #CJK UNIFIED IDEOGRAPH
+0xA9FA 0x660E #CJK UNIFIED IDEOGRAPH
+0xA9FB 0x6600 #CJK UNIFIED IDEOGRAPH
+0xA9FC 0x660F #CJK UNIFIED IDEOGRAPH
+0xA9FD 0x6615 #CJK UNIFIED IDEOGRAPH
+0xA9FE 0x660A #CJK UNIFIED IDEOGRAPH
+0xAA40 0x6607 #CJK UNIFIED IDEOGRAPH
+0xAA41 0x670D #CJK UNIFIED IDEOGRAPH
+0xAA42 0x670B #CJK UNIFIED IDEOGRAPH
+0xAA43 0x676D #CJK UNIFIED IDEOGRAPH
+0xAA44 0x678B #CJK UNIFIED IDEOGRAPH
+0xAA45 0x6795 #CJK UNIFIED IDEOGRAPH
+0xAA46 0x6771 #CJK UNIFIED IDEOGRAPH
+0xAA47 0x679C #CJK UNIFIED IDEOGRAPH
+0xAA48 0x6773 #CJK UNIFIED IDEOGRAPH
+0xAA49 0x6777 #CJK UNIFIED IDEOGRAPH
+0xAA4A 0x6787 #CJK UNIFIED IDEOGRAPH
+0xAA4B 0x679D #CJK UNIFIED IDEOGRAPH
+0xAA4C 0x6797 #CJK UNIFIED IDEOGRAPH
+0xAA4D 0x676F #CJK UNIFIED IDEOGRAPH
+0xAA4E 0x6770 #CJK UNIFIED IDEOGRAPH
+0xAA4F 0x677F #CJK UNIFIED IDEOGRAPH
+0xAA50 0x6789 #CJK UNIFIED IDEOGRAPH
+0xAA51 0x677E #CJK UNIFIED IDEOGRAPH
+0xAA52 0x6790 #CJK UNIFIED IDEOGRAPH
+0xAA53 0x6775 #CJK UNIFIED IDEOGRAPH
+0xAA54 0x679A #CJK UNIFIED IDEOGRAPH
+0xAA55 0x6793 #CJK UNIFIED IDEOGRAPH
+0xAA56 0x677C #CJK UNIFIED IDEOGRAPH
+0xAA57 0x676A #CJK UNIFIED IDEOGRAPH
+0xAA58 0x6772 #CJK UNIFIED IDEOGRAPH
+0xAA59 0x6B23 #CJK UNIFIED IDEOGRAPH
+0xAA5A 0x6B66 #CJK UNIFIED IDEOGRAPH
+0xAA5B 0x6B67 #CJK UNIFIED IDEOGRAPH
+0xAA5C 0x6B7F #CJK UNIFIED IDEOGRAPH
+0xAA5D 0x6C13 #CJK UNIFIED IDEOGRAPH
+0xAA5E 0x6C1B #CJK UNIFIED IDEOGRAPH
+0xAA5F 0x6CE3 #CJK UNIFIED IDEOGRAPH
+0xAA60 0x6CE8 #CJK UNIFIED IDEOGRAPH
+0xAA61 0x6CF3 #CJK UNIFIED IDEOGRAPH
+0xAA62 0x6CB1 #CJK UNIFIED IDEOGRAPH
+0xAA63 0x6CCC #CJK UNIFIED IDEOGRAPH
+0xAA64 0x6CE5 #CJK UNIFIED IDEOGRAPH
+0xAA65 0x6CB3 #CJK UNIFIED IDEOGRAPH
+0xAA66 0x6CBD #CJK UNIFIED IDEOGRAPH
+0xAA67 0x6CBE #CJK UNIFIED IDEOGRAPH
+0xAA68 0x6CBC #CJK UNIFIED IDEOGRAPH
+0xAA69 0x6CE2 #CJK UNIFIED IDEOGRAPH
+0xAA6A 0x6CAB #CJK UNIFIED IDEOGRAPH
+0xAA6B 0x6CD5 #CJK UNIFIED IDEOGRAPH
+0xAA6C 0x6CD3 #CJK UNIFIED IDEOGRAPH
+0xAA6D 0x6CB8 #CJK UNIFIED IDEOGRAPH
+0xAA6E 0x6CC4 #CJK UNIFIED IDEOGRAPH
+0xAA6F 0x6CB9 #CJK UNIFIED IDEOGRAPH
+0xAA70 0x6CC1 #CJK UNIFIED IDEOGRAPH
+0xAA71 0x6CAE #CJK UNIFIED IDEOGRAPH
+0xAA72 0x6CD7 #CJK UNIFIED IDEOGRAPH
+0xAA73 0x6CC5 #CJK UNIFIED IDEOGRAPH
+0xAA74 0x6CF1 #CJK UNIFIED IDEOGRAPH
+0xAA75 0x6CBF #CJK UNIFIED IDEOGRAPH
+0xAA76 0x6CBB #CJK UNIFIED IDEOGRAPH
+0xAA77 0x6CE1 #CJK UNIFIED IDEOGRAPH
+0xAA78 0x6CDB #CJK UNIFIED IDEOGRAPH
+0xAA79 0x6CCA #CJK UNIFIED IDEOGRAPH
+0xAA7A 0x6CAC #CJK UNIFIED IDEOGRAPH
+0xAA7B 0x6CEF #CJK UNIFIED IDEOGRAPH
+0xAA7C 0x6CDC #CJK UNIFIED IDEOGRAPH
+0xAA7D 0x6CD6 #CJK UNIFIED IDEOGRAPH
+0xAA7E 0x6CE0 #CJK UNIFIED IDEOGRAPH
+0xAAA1 0x7095 #CJK UNIFIED IDEOGRAPH
+0xAAA2 0x708E #CJK UNIFIED IDEOGRAPH
+0xAAA3 0x7092 #CJK UNIFIED IDEOGRAPH
+0xAAA4 0x708A #CJK UNIFIED IDEOGRAPH
+0xAAA5 0x7099 #CJK UNIFIED IDEOGRAPH
+0xAAA6 0x722C #CJK UNIFIED IDEOGRAPH
+0xAAA7 0x722D #CJK UNIFIED IDEOGRAPH
+0xAAA8 0x7238 #CJK UNIFIED IDEOGRAPH
+0xAAA9 0x7248 #CJK UNIFIED IDEOGRAPH
+0xAAAA 0x7267 #CJK UNIFIED IDEOGRAPH
+0xAAAB 0x7269 #CJK UNIFIED IDEOGRAPH
+0xAAAC 0x72C0 #CJK UNIFIED IDEOGRAPH
+0xAAAD 0x72CE #CJK UNIFIED IDEOGRAPH
+0xAAAE 0x72D9 #CJK UNIFIED IDEOGRAPH
+0xAAAF 0x72D7 #CJK UNIFIED IDEOGRAPH
+0xAAB0 0x72D0 #CJK UNIFIED IDEOGRAPH
+0xAAB1 0x73A9 #CJK UNIFIED IDEOGRAPH
+0xAAB2 0x73A8 #CJK UNIFIED IDEOGRAPH
+0xAAB3 0x739F #CJK UNIFIED IDEOGRAPH
+0xAAB4 0x73AB #CJK UNIFIED IDEOGRAPH
+0xAAB5 0x73A5 #CJK UNIFIED IDEOGRAPH
+0xAAB6 0x753D #CJK UNIFIED IDEOGRAPH
+0xAAB7 0x759D #CJK UNIFIED IDEOGRAPH
+0xAAB8 0x7599 #CJK UNIFIED IDEOGRAPH
+0xAAB9 0x759A #CJK UNIFIED IDEOGRAPH
+0xAABA 0x7684 #CJK UNIFIED IDEOGRAPH
+0xAABB 0x76C2 #CJK UNIFIED IDEOGRAPH
+0xAABC 0x76F2 #CJK UNIFIED IDEOGRAPH
+0xAABD 0x76F4 #CJK UNIFIED IDEOGRAPH
+0xAABE 0x77E5 #CJK UNIFIED IDEOGRAPH
+0xAABF 0x77FD #CJK UNIFIED IDEOGRAPH
+0xAAC0 0x793E #CJK UNIFIED IDEOGRAPH
+0xAAC1 0x7940 #CJK UNIFIED IDEOGRAPH
+0xAAC2 0x7941 #CJK UNIFIED IDEOGRAPH
+0xAAC3 0x79C9 #CJK UNIFIED IDEOGRAPH
+0xAAC4 0x79C8 #CJK UNIFIED IDEOGRAPH
+0xAAC5 0x7A7A #CJK UNIFIED IDEOGRAPH
+0xAAC6 0x7A79 #CJK UNIFIED IDEOGRAPH
+0xAAC7 0x7AFA #CJK UNIFIED IDEOGRAPH
+0xAAC8 0x7CFE #CJK UNIFIED IDEOGRAPH
+0xAAC9 0x7F54 #CJK UNIFIED IDEOGRAPH
+0xAACA 0x7F8C #CJK UNIFIED IDEOGRAPH
+0xAACB 0x7F8B #CJK UNIFIED IDEOGRAPH
+0xAACC 0x8005 #CJK UNIFIED IDEOGRAPH
+0xAACD 0x80BA #CJK UNIFIED IDEOGRAPH
+0xAACE 0x80A5 #CJK UNIFIED IDEOGRAPH
+0xAACF 0x80A2 #CJK UNIFIED IDEOGRAPH
+0xAAD0 0x80B1 #CJK UNIFIED IDEOGRAPH
+0xAAD1 0x80A1 #CJK UNIFIED IDEOGRAPH
+0xAAD2 0x80AB #CJK UNIFIED IDEOGRAPH
+0xAAD3 0x80A9 #CJK UNIFIED IDEOGRAPH
+0xAAD4 0x80B4 #CJK UNIFIED IDEOGRAPH
+0xAAD5 0x80AA #CJK UNIFIED IDEOGRAPH
+0xAAD6 0x80AF #CJK UNIFIED IDEOGRAPH
+0xAAD7 0x81E5 #CJK UNIFIED IDEOGRAPH
+0xAAD8 0x81FE #CJK UNIFIED IDEOGRAPH
+0xAAD9 0x820D #CJK UNIFIED IDEOGRAPH
+0xAADA 0x82B3 #CJK UNIFIED IDEOGRAPH
+0xAADB 0x829D #CJK UNIFIED IDEOGRAPH
+0xAADC 0x8299 #CJK UNIFIED IDEOGRAPH
+0xAADD 0x82AD #CJK UNIFIED IDEOGRAPH
+0xAADE 0x82BD #CJK UNIFIED IDEOGRAPH
+0xAADF 0x829F #CJK UNIFIED IDEOGRAPH
+0xAAE0 0x82B9 #CJK UNIFIED IDEOGRAPH
+0xAAE1 0x82B1 #CJK UNIFIED IDEOGRAPH
+0xAAE2 0x82AC #CJK UNIFIED IDEOGRAPH
+0xAAE3 0x82A5 #CJK UNIFIED IDEOGRAPH
+0xAAE4 0x82AF #CJK UNIFIED IDEOGRAPH
+0xAAE5 0x82B8 #CJK UNIFIED IDEOGRAPH
+0xAAE6 0x82A3 #CJK UNIFIED IDEOGRAPH
+0xAAE7 0x82B0 #CJK UNIFIED IDEOGRAPH
+0xAAE8 0x82BE #CJK UNIFIED IDEOGRAPH
+0xAAE9 0x82B7 #CJK UNIFIED IDEOGRAPH
+0xAAEA 0x864E #CJK UNIFIED IDEOGRAPH
+0xAAEB 0x8671 #CJK UNIFIED IDEOGRAPH
+0xAAEC 0x521D #CJK UNIFIED IDEOGRAPH
+0xAAED 0x8868 #CJK UNIFIED IDEOGRAPH
+0xAAEE 0x8ECB #CJK UNIFIED IDEOGRAPH
+0xAAEF 0x8FCE #CJK UNIFIED IDEOGRAPH
+0xAAF0 0x8FD4 #CJK UNIFIED IDEOGRAPH
+0xAAF1 0x8FD1 #CJK UNIFIED IDEOGRAPH
+0xAAF2 0x90B5 #CJK UNIFIED IDEOGRAPH
+0xAAF3 0x90B8 #CJK UNIFIED IDEOGRAPH
+0xAAF4 0x90B1 #CJK UNIFIED IDEOGRAPH
+0xAAF5 0x90B6 #CJK UNIFIED IDEOGRAPH
+0xAAF6 0x91C7 #CJK UNIFIED IDEOGRAPH
+0xAAF7 0x91D1 #CJK UNIFIED IDEOGRAPH
+0xAAF8 0x9577 #CJK UNIFIED IDEOGRAPH
+0xAAF9 0x9580 #CJK UNIFIED IDEOGRAPH
+0xAAFA 0x961C #CJK UNIFIED IDEOGRAPH
+0xAAFB 0x9640 #CJK UNIFIED IDEOGRAPH
+0xAAFC 0x963F #CJK UNIFIED IDEOGRAPH
+0xAAFD 0x963B #CJK UNIFIED IDEOGRAPH
+0xAAFE 0x9644 #CJK UNIFIED IDEOGRAPH
+0xAB40 0x9642 #CJK UNIFIED IDEOGRAPH
+0xAB41 0x96B9 #CJK UNIFIED IDEOGRAPH
+0xAB42 0x96E8 #CJK UNIFIED IDEOGRAPH
+0xAB43 0x9752 #CJK UNIFIED IDEOGRAPH
+0xAB44 0x975E #CJK UNIFIED IDEOGRAPH
+0xAB45 0x4E9F #CJK UNIFIED IDEOGRAPH
+0xAB46 0x4EAD #CJK UNIFIED IDEOGRAPH
+0xAB47 0x4EAE #CJK UNIFIED IDEOGRAPH
+0xAB48 0x4FE1 #CJK UNIFIED IDEOGRAPH
+0xAB49 0x4FB5 #CJK UNIFIED IDEOGRAPH
+0xAB4A 0x4FAF #CJK UNIFIED IDEOGRAPH
+0xAB4B 0x4FBF #CJK UNIFIED IDEOGRAPH
+0xAB4C 0x4FE0 #CJK UNIFIED IDEOGRAPH
+0xAB4D 0x4FD1 #CJK UNIFIED IDEOGRAPH
+0xAB4E 0x4FCF #CJK UNIFIED IDEOGRAPH
+0xAB4F 0x4FDD #CJK UNIFIED IDEOGRAPH
+0xAB50 0x4FC3 #CJK UNIFIED IDEOGRAPH
+0xAB51 0x4FB6 #CJK UNIFIED IDEOGRAPH
+0xAB52 0x4FD8 #CJK UNIFIED IDEOGRAPH
+0xAB53 0x4FDF #CJK UNIFIED IDEOGRAPH
+0xAB54 0x4FCA #CJK UNIFIED IDEOGRAPH
+0xAB55 0x4FD7 #CJK UNIFIED IDEOGRAPH
+0xAB56 0x4FAE #CJK UNIFIED IDEOGRAPH
+0xAB57 0x4FD0 #CJK UNIFIED IDEOGRAPH
+0xAB58 0x4FC4 #CJK UNIFIED IDEOGRAPH
+0xAB59 0x4FC2 #CJK UNIFIED IDEOGRAPH
+0xAB5A 0x4FDA #CJK UNIFIED IDEOGRAPH
+0xAB5B 0x4FCE #CJK UNIFIED IDEOGRAPH
+0xAB5C 0x4FDE #CJK UNIFIED IDEOGRAPH
+0xAB5D 0x4FB7 #CJK UNIFIED IDEOGRAPH
+0xAB5E 0x5157 #CJK UNIFIED IDEOGRAPH
+0xAB5F 0x5192 #CJK UNIFIED IDEOGRAPH
+0xAB60 0x5191 #CJK UNIFIED IDEOGRAPH
+0xAB61 0x51A0 #CJK UNIFIED IDEOGRAPH
+0xAB62 0x524E #CJK UNIFIED IDEOGRAPH
+0xAB63 0x5243 #CJK UNIFIED IDEOGRAPH
+0xAB64 0x524A #CJK UNIFIED IDEOGRAPH
+0xAB65 0x524D #CJK UNIFIED IDEOGRAPH
+0xAB66 0x524C #CJK UNIFIED IDEOGRAPH
+0xAB67 0x524B #CJK UNIFIED IDEOGRAPH
+0xAB68 0x5247 #CJK UNIFIED IDEOGRAPH
+0xAB69 0x52C7 #CJK UNIFIED IDEOGRAPH
+0xAB6A 0x52C9 #CJK UNIFIED IDEOGRAPH
+0xAB6B 0x52C3 #CJK UNIFIED IDEOGRAPH
+0xAB6C 0x52C1 #CJK UNIFIED IDEOGRAPH
+0xAB6D 0x530D #CJK UNIFIED IDEOGRAPH
+0xAB6E 0x5357 #CJK UNIFIED IDEOGRAPH
+0xAB6F 0x537B #CJK UNIFIED IDEOGRAPH
+0xAB70 0x539A #CJK UNIFIED IDEOGRAPH
+0xAB71 0x53DB #CJK UNIFIED IDEOGRAPH
+0xAB72 0x54AC #CJK UNIFIED IDEOGRAPH
+0xAB73 0x54C0 #CJK UNIFIED IDEOGRAPH
+0xAB74 0x54A8 #CJK UNIFIED IDEOGRAPH
+0xAB75 0x54CE #CJK UNIFIED IDEOGRAPH
+0xAB76 0x54C9 #CJK UNIFIED IDEOGRAPH
+0xAB77 0x54B8 #CJK UNIFIED IDEOGRAPH
+0xAB78 0x54A6 #CJK UNIFIED IDEOGRAPH
+0xAB79 0x54B3 #CJK UNIFIED IDEOGRAPH
+0xAB7A 0x54C7 #CJK UNIFIED IDEOGRAPH
+0xAB7B 0x54C2 #CJK UNIFIED IDEOGRAPH
+0xAB7C 0x54BD #CJK UNIFIED IDEOGRAPH
+0xAB7D 0x54AA #CJK UNIFIED IDEOGRAPH
+0xAB7E 0x54C1 #CJK UNIFIED IDEOGRAPH
+0xABA1 0x54C4 #CJK UNIFIED IDEOGRAPH
+0xABA2 0x54C8 #CJK UNIFIED IDEOGRAPH
+0xABA3 0x54AF #CJK UNIFIED IDEOGRAPH
+0xABA4 0x54AB #CJK UNIFIED IDEOGRAPH
+0xABA5 0x54B1 #CJK UNIFIED IDEOGRAPH
+0xABA6 0x54BB #CJK UNIFIED IDEOGRAPH
+0xABA7 0x54A9 #CJK UNIFIED IDEOGRAPH
+0xABA8 0x54A7 #CJK UNIFIED IDEOGRAPH
+0xABA9 0x54BF #CJK UNIFIED IDEOGRAPH
+0xABAA 0x56FF #CJK UNIFIED IDEOGRAPH
+0xABAB 0x5782 #CJK UNIFIED IDEOGRAPH
+0xABAC 0x578B #CJK UNIFIED IDEOGRAPH
+0xABAD 0x57A0 #CJK UNIFIED IDEOGRAPH
+0xABAE 0x57A3 #CJK UNIFIED IDEOGRAPH
+0xABAF 0x57A2 #CJK UNIFIED IDEOGRAPH
+0xABB0 0x57CE #CJK UNIFIED IDEOGRAPH
+0xABB1 0x57AE #CJK UNIFIED IDEOGRAPH
+0xABB2 0x5793 #CJK UNIFIED IDEOGRAPH
+0xABB3 0x5955 #CJK UNIFIED IDEOGRAPH
+0xABB4 0x5951 #CJK UNIFIED IDEOGRAPH
+0xABB5 0x594F #CJK UNIFIED IDEOGRAPH
+0xABB6 0x594E #CJK UNIFIED IDEOGRAPH
+0xABB7 0x5950 #CJK UNIFIED IDEOGRAPH
+0xABB8 0x59DC #CJK UNIFIED IDEOGRAPH
+0xABB9 0x59D8 #CJK UNIFIED IDEOGRAPH
+0xABBA 0x59FF #CJK UNIFIED IDEOGRAPH
+0xABBB 0x59E3 #CJK UNIFIED IDEOGRAPH
+0xABBC 0x59E8 #CJK UNIFIED IDEOGRAPH
+0xABBD 0x5A03 #CJK UNIFIED IDEOGRAPH
+0xABBE 0x59E5 #CJK UNIFIED IDEOGRAPH
+0xABBF 0x59EA #CJK UNIFIED IDEOGRAPH
+0xABC0 0x59DA #CJK UNIFIED IDEOGRAPH
+0xABC1 0x59E6 #CJK UNIFIED IDEOGRAPH
+0xABC2 0x5A01 #CJK UNIFIED IDEOGRAPH
+0xABC3 0x59FB #CJK UNIFIED IDEOGRAPH
+0xABC4 0x5B69 #CJK UNIFIED IDEOGRAPH
+0xABC5 0x5BA3 #CJK UNIFIED IDEOGRAPH
+0xABC6 0x5BA6 #CJK UNIFIED IDEOGRAPH
+0xABC7 0x5BA4 #CJK UNIFIED IDEOGRAPH
+0xABC8 0x5BA2 #CJK UNIFIED IDEOGRAPH
+0xABC9 0x5BA5 #CJK UNIFIED IDEOGRAPH
+0xABCA 0x5C01 #CJK UNIFIED IDEOGRAPH
+0xABCB 0x5C4E #CJK UNIFIED IDEOGRAPH
+0xABCC 0x5C4F #CJK UNIFIED IDEOGRAPH
+0xABCD 0x5C4D #CJK UNIFIED IDEOGRAPH
+0xABCE 0x5C4B #CJK UNIFIED IDEOGRAPH
+0xABCF 0x5CD9 #CJK UNIFIED IDEOGRAPH
+0xABD0 0x5CD2 #CJK UNIFIED IDEOGRAPH
+0xABD1 0x5DF7 #CJK UNIFIED IDEOGRAPH
+0xABD2 0x5E1D #CJK UNIFIED IDEOGRAPH
+0xABD3 0x5E25 #CJK UNIFIED IDEOGRAPH
+0xABD4 0x5E1F #CJK UNIFIED IDEOGRAPH
+0xABD5 0x5E7D #CJK UNIFIED IDEOGRAPH
+0xABD6 0x5EA0 #CJK UNIFIED IDEOGRAPH
+0xABD7 0x5EA6 #CJK UNIFIED IDEOGRAPH
+0xABD8 0x5EFA #CJK UNIFIED IDEOGRAPH
+0xABD9 0x5F08 #CJK UNIFIED IDEOGRAPH
+0xABDA 0x5F2D #CJK UNIFIED IDEOGRAPH
+0xABDB 0x5F65 #CJK UNIFIED IDEOGRAPH
+0xABDC 0x5F88 #CJK UNIFIED IDEOGRAPH
+0xABDD 0x5F85 #CJK UNIFIED IDEOGRAPH
+0xABDE 0x5F8A #CJK UNIFIED IDEOGRAPH
+0xABDF 0x5F8B #CJK UNIFIED IDEOGRAPH
+0xABE0 0x5F87 #CJK UNIFIED IDEOGRAPH
+0xABE1 0x5F8C #CJK UNIFIED IDEOGRAPH
+0xABE2 0x5F89 #CJK UNIFIED IDEOGRAPH
+0xABE3 0x6012 #CJK UNIFIED IDEOGRAPH
+0xABE4 0x601D #CJK UNIFIED IDEOGRAPH
+0xABE5 0x6020 #CJK UNIFIED IDEOGRAPH
+0xABE6 0x6025 #CJK UNIFIED IDEOGRAPH
+0xABE7 0x600E #CJK UNIFIED IDEOGRAPH
+0xABE8 0x6028 #CJK UNIFIED IDEOGRAPH
+0xABE9 0x604D #CJK UNIFIED IDEOGRAPH
+0xABEA 0x6070 #CJK UNIFIED IDEOGRAPH
+0xABEB 0x6068 #CJK UNIFIED IDEOGRAPH
+0xABEC 0x6062 #CJK UNIFIED IDEOGRAPH
+0xABED 0x6046 #CJK UNIFIED IDEOGRAPH
+0xABEE 0x6043 #CJK UNIFIED IDEOGRAPH
+0xABEF 0x606C #CJK UNIFIED IDEOGRAPH
+0xABF0 0x606B #CJK UNIFIED IDEOGRAPH
+0xABF1 0x606A #CJK UNIFIED IDEOGRAPH
+0xABF2 0x6064 #CJK UNIFIED IDEOGRAPH
+0xABF3 0x6241 #CJK UNIFIED IDEOGRAPH
+0xABF4 0x62DC #CJK UNIFIED IDEOGRAPH
+0xABF5 0x6316 #CJK UNIFIED IDEOGRAPH
+0xABF6 0x6309 #CJK UNIFIED IDEOGRAPH
+0xABF7 0x62FC #CJK UNIFIED IDEOGRAPH
+0xABF8 0x62ED #CJK UNIFIED IDEOGRAPH
+0xABF9 0x6301 #CJK UNIFIED IDEOGRAPH
+0xABFA 0x62EE #CJK UNIFIED IDEOGRAPH
+0xABFB 0x62FD #CJK UNIFIED IDEOGRAPH
+0xABFC 0x6307 #CJK UNIFIED IDEOGRAPH
+0xABFD 0x62F1 #CJK UNIFIED IDEOGRAPH
+0xABFE 0x62F7 #CJK UNIFIED IDEOGRAPH
+0xAC40 0x62EF #CJK UNIFIED IDEOGRAPH
+0xAC41 0x62EC #CJK UNIFIED IDEOGRAPH
+0xAC42 0x62FE #CJK UNIFIED IDEOGRAPH
+0xAC43 0x62F4 #CJK UNIFIED IDEOGRAPH
+0xAC44 0x6311 #CJK UNIFIED IDEOGRAPH
+0xAC45 0x6302 #CJK UNIFIED IDEOGRAPH
+0xAC46 0x653F #CJK UNIFIED IDEOGRAPH
+0xAC47 0x6545 #CJK UNIFIED IDEOGRAPH
+0xAC48 0x65AB #CJK UNIFIED IDEOGRAPH
+0xAC49 0x65BD #CJK UNIFIED IDEOGRAPH
+0xAC4A 0x65E2 #CJK UNIFIED IDEOGRAPH
+0xAC4B 0x6625 #CJK UNIFIED IDEOGRAPH
+0xAC4C 0x662D #CJK UNIFIED IDEOGRAPH
+0xAC4D 0x6620 #CJK UNIFIED IDEOGRAPH
+0xAC4E 0x6627 #CJK UNIFIED IDEOGRAPH
+0xAC4F 0x662F #CJK UNIFIED IDEOGRAPH
+0xAC50 0x661F #CJK UNIFIED IDEOGRAPH
+0xAC51 0x6628 #CJK UNIFIED IDEOGRAPH
+0xAC52 0x6631 #CJK UNIFIED IDEOGRAPH
+0xAC53 0x6624 #CJK UNIFIED IDEOGRAPH
+0xAC54 0x66F7 #CJK UNIFIED IDEOGRAPH
+0xAC55 0x67FF #CJK UNIFIED IDEOGRAPH
+0xAC56 0x67D3 #CJK UNIFIED IDEOGRAPH
+0xAC57 0x67F1 #CJK UNIFIED IDEOGRAPH
+0xAC58 0x67D4 #CJK UNIFIED IDEOGRAPH
+0xAC59 0x67D0 #CJK UNIFIED IDEOGRAPH
+0xAC5A 0x67EC #CJK UNIFIED IDEOGRAPH
+0xAC5B 0x67B6 #CJK UNIFIED IDEOGRAPH
+0xAC5C 0x67AF #CJK UNIFIED IDEOGRAPH
+0xAC5D 0x67F5 #CJK UNIFIED IDEOGRAPH
+0xAC5E 0x67E9 #CJK UNIFIED IDEOGRAPH
+0xAC5F 0x67EF #CJK UNIFIED IDEOGRAPH
+0xAC60 0x67C4 #CJK UNIFIED IDEOGRAPH
+0xAC61 0x67D1 #CJK UNIFIED IDEOGRAPH
+0xAC62 0x67B4 #CJK UNIFIED IDEOGRAPH
+0xAC63 0x67DA #CJK UNIFIED IDEOGRAPH
+0xAC64 0x67E5 #CJK UNIFIED IDEOGRAPH
+0xAC65 0x67B8 #CJK UNIFIED IDEOGRAPH
+0xAC66 0x67CF #CJK UNIFIED IDEOGRAPH
+0xAC67 0x67DE #CJK UNIFIED IDEOGRAPH
+0xAC68 0x67F3 #CJK UNIFIED IDEOGRAPH
+0xAC69 0x67B0 #CJK UNIFIED IDEOGRAPH
+0xAC6A 0x67D9 #CJK UNIFIED IDEOGRAPH
+0xAC6B 0x67E2 #CJK UNIFIED IDEOGRAPH
+0xAC6C 0x67DD #CJK UNIFIED IDEOGRAPH
+0xAC6D 0x67D2 #CJK UNIFIED IDEOGRAPH
+0xAC6E 0x6B6A #CJK UNIFIED IDEOGRAPH
+0xAC6F 0x6B83 #CJK UNIFIED IDEOGRAPH
+0xAC70 0x6B86 #CJK UNIFIED IDEOGRAPH
+0xAC71 0x6BB5 #CJK UNIFIED IDEOGRAPH
+0xAC72 0x6BD2 #CJK UNIFIED IDEOGRAPH
+0xAC73 0x6BD7 #CJK UNIFIED IDEOGRAPH
+0xAC74 0x6C1F #CJK UNIFIED IDEOGRAPH
+0xAC75 0x6CC9 #CJK UNIFIED IDEOGRAPH
+0xAC76 0x6D0B #CJK UNIFIED IDEOGRAPH
+0xAC77 0x6D32 #CJK UNIFIED IDEOGRAPH
+0xAC78 0x6D2A #CJK UNIFIED IDEOGRAPH
+0xAC79 0x6D41 #CJK UNIFIED IDEOGRAPH
+0xAC7A 0x6D25 #CJK UNIFIED IDEOGRAPH
+0xAC7B 0x6D0C #CJK UNIFIED IDEOGRAPH
+0xAC7C 0x6D31 #CJK UNIFIED IDEOGRAPH
+0xAC7D 0x6D1E #CJK UNIFIED IDEOGRAPH
+0xAC7E 0x6D17 #CJK UNIFIED IDEOGRAPH
+0xACA1 0x6D3B #CJK UNIFIED IDEOGRAPH
+0xACA2 0x6D3D #CJK UNIFIED IDEOGRAPH
+0xACA3 0x6D3E #CJK UNIFIED IDEOGRAPH
+0xACA4 0x6D36 #CJK UNIFIED IDEOGRAPH
+0xACA5 0x6D1B #CJK UNIFIED IDEOGRAPH
+0xACA6 0x6CF5 #CJK UNIFIED IDEOGRAPH
+0xACA7 0x6D39 #CJK UNIFIED IDEOGRAPH
+0xACA8 0x6D27 #CJK UNIFIED IDEOGRAPH
+0xACA9 0x6D38 #CJK UNIFIED IDEOGRAPH
+0xACAA 0x6D29 #CJK UNIFIED IDEOGRAPH
+0xACAB 0x6D2E #CJK UNIFIED IDEOGRAPH
+0xACAC 0x6D35 #CJK UNIFIED IDEOGRAPH
+0xACAD 0x6D0E #CJK UNIFIED IDEOGRAPH
+0xACAE 0x6D2B #CJK UNIFIED IDEOGRAPH
+0xACAF 0x70AB #CJK UNIFIED IDEOGRAPH
+0xACB0 0x70BA #CJK UNIFIED IDEOGRAPH
+0xACB1 0x70B3 #CJK UNIFIED IDEOGRAPH
+0xACB2 0x70AC #CJK UNIFIED IDEOGRAPH
+0xACB3 0x70AF #CJK UNIFIED IDEOGRAPH
+0xACB4 0x70AD #CJK UNIFIED IDEOGRAPH
+0xACB5 0x70B8 #CJK UNIFIED IDEOGRAPH
+0xACB6 0x70AE #CJK UNIFIED IDEOGRAPH
+0xACB7 0x70A4 #CJK UNIFIED IDEOGRAPH
+0xACB8 0x7230 #CJK UNIFIED IDEOGRAPH
+0xACB9 0x7272 #CJK UNIFIED IDEOGRAPH
+0xACBA 0x726F #CJK UNIFIED IDEOGRAPH
+0xACBB 0x7274 #CJK UNIFIED IDEOGRAPH
+0xACBC 0x72E9 #CJK UNIFIED IDEOGRAPH
+0xACBD 0x72E0 #CJK UNIFIED IDEOGRAPH
+0xACBE 0x72E1 #CJK UNIFIED IDEOGRAPH
+0xACBF 0x73B7 #CJK UNIFIED IDEOGRAPH
+0xACC0 0x73CA #CJK UNIFIED IDEOGRAPH
+0xACC1 0x73BB #CJK UNIFIED IDEOGRAPH
+0xACC2 0x73B2 #CJK UNIFIED IDEOGRAPH
+0xACC3 0x73CD #CJK UNIFIED IDEOGRAPH
+0xACC4 0x73C0 #CJK UNIFIED IDEOGRAPH
+0xACC5 0x73B3 #CJK UNIFIED IDEOGRAPH
+0xACC6 0x751A #CJK UNIFIED IDEOGRAPH
+0xACC7 0x752D #CJK UNIFIED IDEOGRAPH
+0xACC8 0x754F #CJK UNIFIED IDEOGRAPH
+0xACC9 0x754C #CJK UNIFIED IDEOGRAPH
+0xACCA 0x754E #CJK UNIFIED IDEOGRAPH
+0xACCB 0x754B #CJK UNIFIED IDEOGRAPH
+0xACCC 0x75AB #CJK UNIFIED IDEOGRAPH
+0xACCD 0x75A4 #CJK UNIFIED IDEOGRAPH
+0xACCE 0x75A5 #CJK UNIFIED IDEOGRAPH
+0xACCF 0x75A2 #CJK UNIFIED IDEOGRAPH
+0xACD0 0x75A3 #CJK UNIFIED IDEOGRAPH
+0xACD1 0x7678 #CJK UNIFIED IDEOGRAPH
+0xACD2 0x7686 #CJK UNIFIED IDEOGRAPH
+0xACD3 0x7687 #CJK UNIFIED IDEOGRAPH
+0xACD4 0x7688 #CJK UNIFIED IDEOGRAPH
+0xACD5 0x76C8 #CJK UNIFIED IDEOGRAPH
+0xACD6 0x76C6 #CJK UNIFIED IDEOGRAPH
+0xACD7 0x76C3 #CJK UNIFIED IDEOGRAPH
+0xACD8 0x76C5 #CJK UNIFIED IDEOGRAPH
+0xACD9 0x7701 #CJK UNIFIED IDEOGRAPH
+0xACDA 0x76F9 #CJK UNIFIED IDEOGRAPH
+0xACDB 0x76F8 #CJK UNIFIED IDEOGRAPH
+0xACDC 0x7709 #CJK UNIFIED IDEOGRAPH
+0xACDD 0x770B #CJK UNIFIED IDEOGRAPH
+0xACDE 0x76FE #CJK UNIFIED IDEOGRAPH
+0xACDF 0x76FC #CJK UNIFIED IDEOGRAPH
+0xACE0 0x7707 #CJK UNIFIED IDEOGRAPH
+0xACE1 0x77DC #CJK UNIFIED IDEOGRAPH
+0xACE2 0x7802 #CJK UNIFIED IDEOGRAPH
+0xACE3 0x7814 #CJK UNIFIED IDEOGRAPH
+0xACE4 0x780C #CJK UNIFIED IDEOGRAPH
+0xACE5 0x780D #CJK UNIFIED IDEOGRAPH
+0xACE6 0x7946 #CJK UNIFIED IDEOGRAPH
+0xACE7 0x7949 #CJK UNIFIED IDEOGRAPH
+0xACE8 0x7948 #CJK UNIFIED IDEOGRAPH
+0xACE9 0x7947 #CJK UNIFIED IDEOGRAPH
+0xACEA 0x79B9 #CJK UNIFIED IDEOGRAPH
+0xACEB 0x79BA #CJK UNIFIED IDEOGRAPH
+0xACEC 0x79D1 #CJK UNIFIED IDEOGRAPH
+0xACED 0x79D2 #CJK UNIFIED IDEOGRAPH
+0xACEE 0x79CB #CJK UNIFIED IDEOGRAPH
+0xACEF 0x7A7F #CJK UNIFIED IDEOGRAPH
+0xACF0 0x7A81 #CJK UNIFIED IDEOGRAPH
+0xACF1 0x7AFF #CJK UNIFIED IDEOGRAPH
+0xACF2 0x7AFD #CJK UNIFIED IDEOGRAPH
+0xACF3 0x7C7D #CJK UNIFIED IDEOGRAPH
+0xACF4 0x7D02 #CJK UNIFIED IDEOGRAPH
+0xACF5 0x7D05 #CJK UNIFIED IDEOGRAPH
+0xACF6 0x7D00 #CJK UNIFIED IDEOGRAPH
+0xACF7 0x7D09 #CJK UNIFIED IDEOGRAPH
+0xACF8 0x7D07 #CJK UNIFIED IDEOGRAPH
+0xACF9 0x7D04 #CJK UNIFIED IDEOGRAPH
+0xACFA 0x7D06 #CJK UNIFIED IDEOGRAPH
+0xACFB 0x7F38 #CJK UNIFIED IDEOGRAPH
+0xACFC 0x7F8E #CJK UNIFIED IDEOGRAPH
+0xACFD 0x7FBF #CJK UNIFIED IDEOGRAPH
+0xACFE 0x8004 #CJK UNIFIED IDEOGRAPH
+0xAD40 0x8010 #CJK UNIFIED IDEOGRAPH
+0xAD41 0x800D #CJK UNIFIED IDEOGRAPH
+0xAD42 0x8011 #CJK UNIFIED IDEOGRAPH
+0xAD43 0x8036 #CJK UNIFIED IDEOGRAPH
+0xAD44 0x80D6 #CJK UNIFIED IDEOGRAPH
+0xAD45 0x80E5 #CJK UNIFIED IDEOGRAPH
+0xAD46 0x80DA #CJK UNIFIED IDEOGRAPH
+0xAD47 0x80C3 #CJK UNIFIED IDEOGRAPH
+0xAD48 0x80C4 #CJK UNIFIED IDEOGRAPH
+0xAD49 0x80CC #CJK UNIFIED IDEOGRAPH
+0xAD4A 0x80E1 #CJK UNIFIED IDEOGRAPH
+0xAD4B 0x80DB #CJK UNIFIED IDEOGRAPH
+0xAD4C 0x80CE #CJK UNIFIED IDEOGRAPH
+0xAD4D 0x80DE #CJK UNIFIED IDEOGRAPH
+0xAD4E 0x80E4 #CJK UNIFIED IDEOGRAPH
+0xAD4F 0x80DD #CJK UNIFIED IDEOGRAPH
+0xAD50 0x81F4 #CJK UNIFIED IDEOGRAPH
+0xAD51 0x8222 #CJK UNIFIED IDEOGRAPH
+0xAD52 0x82E7 #CJK UNIFIED IDEOGRAPH
+0xAD53 0x8303 #CJK UNIFIED IDEOGRAPH
+0xAD54 0x8305 #CJK UNIFIED IDEOGRAPH
+0xAD55 0x82E3 #CJK UNIFIED IDEOGRAPH
+0xAD56 0x82DB #CJK UNIFIED IDEOGRAPH
+0xAD57 0x82E6 #CJK UNIFIED IDEOGRAPH
+0xAD58 0x8304 #CJK UNIFIED IDEOGRAPH
+0xAD59 0x82E5 #CJK UNIFIED IDEOGRAPH
+0xAD5A 0x8302 #CJK UNIFIED IDEOGRAPH
+0xAD5B 0x8309 #CJK UNIFIED IDEOGRAPH
+0xAD5C 0x82D2 #CJK UNIFIED IDEOGRAPH
+0xAD5D 0x82D7 #CJK UNIFIED IDEOGRAPH
+0xAD5E 0x82F1 #CJK UNIFIED IDEOGRAPH
+0xAD5F 0x8301 #CJK UNIFIED IDEOGRAPH
+0xAD60 0x82DC #CJK UNIFIED IDEOGRAPH
+0xAD61 0x82D4 #CJK UNIFIED IDEOGRAPH
+0xAD62 0x82D1 #CJK UNIFIED IDEOGRAPH
+0xAD63 0x82DE #CJK UNIFIED IDEOGRAPH
+0xAD64 0x82D3 #CJK UNIFIED IDEOGRAPH
+0xAD65 0x82DF #CJK UNIFIED IDEOGRAPH
+0xAD66 0x82EF #CJK UNIFIED IDEOGRAPH
+0xAD67 0x8306 #CJK UNIFIED IDEOGRAPH
+0xAD68 0x8650 #CJK UNIFIED IDEOGRAPH
+0xAD69 0x8679 #CJK UNIFIED IDEOGRAPH
+0xAD6A 0x867B #CJK UNIFIED IDEOGRAPH
+0xAD6B 0x867A #CJK UNIFIED IDEOGRAPH
+0xAD6C 0x884D #CJK UNIFIED IDEOGRAPH
+0xAD6D 0x886B #CJK UNIFIED IDEOGRAPH
+0xAD6E 0x8981 #CJK UNIFIED IDEOGRAPH
+0xAD6F 0x89D4 #CJK UNIFIED IDEOGRAPH
+0xAD70 0x8A08 #CJK UNIFIED IDEOGRAPH
+0xAD71 0x8A02 #CJK UNIFIED IDEOGRAPH
+0xAD72 0x8A03 #CJK UNIFIED IDEOGRAPH
+0xAD73 0x8C9E #CJK UNIFIED IDEOGRAPH
+0xAD74 0x8CA0 #CJK UNIFIED IDEOGRAPH
+0xAD75 0x8D74 #CJK UNIFIED IDEOGRAPH
+0xAD76 0x8D73 #CJK UNIFIED IDEOGRAPH
+0xAD77 0x8DB4 #CJK UNIFIED IDEOGRAPH
+0xAD78 0x8ECD #CJK UNIFIED IDEOGRAPH
+0xAD79 0x8ECC #CJK UNIFIED IDEOGRAPH
+0xAD7A 0x8FF0 #CJK UNIFIED IDEOGRAPH
+0xAD7B 0x8FE6 #CJK UNIFIED IDEOGRAPH
+0xAD7C 0x8FE2 #CJK UNIFIED IDEOGRAPH
+0xAD7D 0x8FEA #CJK UNIFIED IDEOGRAPH
+0xAD7E 0x8FE5 #CJK UNIFIED IDEOGRAPH
+0xADA1 0x8FED #CJK UNIFIED IDEOGRAPH
+0xADA2 0x8FEB #CJK UNIFIED IDEOGRAPH
+0xADA3 0x8FE4 #CJK UNIFIED IDEOGRAPH
+0xADA4 0x8FE8 #CJK UNIFIED IDEOGRAPH
+0xADA5 0x90CA #CJK UNIFIED IDEOGRAPH
+0xADA6 0x90CE #CJK UNIFIED IDEOGRAPH
+0xADA7 0x90C1 #CJK UNIFIED IDEOGRAPH
+0xADA8 0x90C3 #CJK UNIFIED IDEOGRAPH
+0xADA9 0x914B #CJK UNIFIED IDEOGRAPH
+0xADAA 0x914A #CJK UNIFIED IDEOGRAPH
+0xADAB 0x91CD #CJK UNIFIED IDEOGRAPH
+0xADAC 0x9582 #CJK UNIFIED IDEOGRAPH
+0xADAD 0x9650 #CJK UNIFIED IDEOGRAPH
+0xADAE 0x964B #CJK UNIFIED IDEOGRAPH
+0xADAF 0x964C #CJK UNIFIED IDEOGRAPH
+0xADB0 0x964D #CJK UNIFIED IDEOGRAPH
+0xADB1 0x9762 #CJK UNIFIED IDEOGRAPH
+0xADB2 0x9769 #CJK UNIFIED IDEOGRAPH
+0xADB3 0x97CB #CJK UNIFIED IDEOGRAPH
+0xADB4 0x97ED #CJK UNIFIED IDEOGRAPH
+0xADB5 0x97F3 #CJK UNIFIED IDEOGRAPH
+0xADB6 0x9801 #CJK UNIFIED IDEOGRAPH
+0xADB7 0x98A8 #CJK UNIFIED IDEOGRAPH
+0xADB8 0x98DB #CJK UNIFIED IDEOGRAPH
+0xADB9 0x98DF #CJK UNIFIED IDEOGRAPH
+0xADBA 0x9996 #CJK UNIFIED IDEOGRAPH
+0xADBB 0x9999 #CJK UNIFIED IDEOGRAPH
+0xADBC 0x4E58 #CJK UNIFIED IDEOGRAPH
+0xADBD 0x4EB3 #CJK UNIFIED IDEOGRAPH
+0xADBE 0x500C #CJK UNIFIED IDEOGRAPH
+0xADBF 0x500D #CJK UNIFIED IDEOGRAPH
+0xADC0 0x5023 #CJK UNIFIED IDEOGRAPH
+0xADC1 0x4FEF #CJK UNIFIED IDEOGRAPH
+0xADC2 0x5026 #CJK UNIFIED IDEOGRAPH
+0xADC3 0x5025 #CJK UNIFIED IDEOGRAPH
+0xADC4 0x4FF8 #CJK UNIFIED IDEOGRAPH
+0xADC5 0x5029 #CJK UNIFIED IDEOGRAPH
+0xADC6 0x5016 #CJK UNIFIED IDEOGRAPH
+0xADC7 0x5006 #CJK UNIFIED IDEOGRAPH
+0xADC8 0x503C #CJK UNIFIED IDEOGRAPH
+0xADC9 0x501F #CJK UNIFIED IDEOGRAPH
+0xADCA 0x501A #CJK UNIFIED IDEOGRAPH
+0xADCB 0x5012 #CJK UNIFIED IDEOGRAPH
+0xADCC 0x5011 #CJK UNIFIED IDEOGRAPH
+0xADCD 0x4FFA #CJK UNIFIED IDEOGRAPH
+0xADCE 0x5000 #CJK UNIFIED IDEOGRAPH
+0xADCF 0x5014 #CJK UNIFIED IDEOGRAPH
+0xADD0 0x5028 #CJK UNIFIED IDEOGRAPH
+0xADD1 0x4FF1 #CJK UNIFIED IDEOGRAPH
+0xADD2 0x5021 #CJK UNIFIED IDEOGRAPH
+0xADD3 0x500B #CJK UNIFIED IDEOGRAPH
+0xADD4 0x5019 #CJK UNIFIED IDEOGRAPH
+0xADD5 0x5018 #CJK UNIFIED IDEOGRAPH
+0xADD6 0x4FF3 #CJK UNIFIED IDEOGRAPH
+0xADD7 0x4FEE #CJK UNIFIED IDEOGRAPH
+0xADD8 0x502D #CJK UNIFIED IDEOGRAPH
+0xADD9 0x502A #CJK UNIFIED IDEOGRAPH
+0xADDA 0x4FFE #CJK UNIFIED IDEOGRAPH
+0xADDB 0x502B #CJK UNIFIED IDEOGRAPH
+0xADDC 0x5009 #CJK UNIFIED IDEOGRAPH
+0xADDD 0x517C #CJK UNIFIED IDEOGRAPH
+0xADDE 0x51A4 #CJK UNIFIED IDEOGRAPH
+0xADDF 0x51A5 #CJK UNIFIED IDEOGRAPH
+0xADE0 0x51A2 #CJK UNIFIED IDEOGRAPH
+0xADE1 0x51CD #CJK UNIFIED IDEOGRAPH
+0xADE2 0x51CC #CJK UNIFIED IDEOGRAPH
+0xADE3 0x51C6 #CJK UNIFIED IDEOGRAPH
+0xADE4 0x51CB #CJK UNIFIED IDEOGRAPH
+0xADE5 0x5256 #CJK UNIFIED IDEOGRAPH
+0xADE6 0x525C #CJK UNIFIED IDEOGRAPH
+0xADE7 0x5254 #CJK UNIFIED IDEOGRAPH
+0xADE8 0x525B #CJK UNIFIED IDEOGRAPH
+0xADE9 0x525D #CJK UNIFIED IDEOGRAPH
+0xADEA 0x532A #CJK UNIFIED IDEOGRAPH
+0xADEB 0x537F #CJK UNIFIED IDEOGRAPH
+0xADEC 0x539F #CJK UNIFIED IDEOGRAPH
+0xADED 0x539D #CJK UNIFIED IDEOGRAPH
+0xADEE 0x53DF #CJK UNIFIED IDEOGRAPH
+0xADEF 0x54E8 #CJK UNIFIED IDEOGRAPH
+0xADF0 0x5510 #CJK UNIFIED IDEOGRAPH
+0xADF1 0x5501 #CJK UNIFIED IDEOGRAPH
+0xADF2 0x5537 #CJK UNIFIED IDEOGRAPH
+0xADF3 0x54FC #CJK UNIFIED IDEOGRAPH
+0xADF4 0x54E5 #CJK UNIFIED IDEOGRAPH
+0xADF5 0x54F2 #CJK UNIFIED IDEOGRAPH
+0xADF6 0x5506 #CJK UNIFIED IDEOGRAPH
+0xADF7 0x54FA #CJK UNIFIED IDEOGRAPH
+0xADF8 0x5514 #CJK UNIFIED IDEOGRAPH
+0xADF9 0x54E9 #CJK UNIFIED IDEOGRAPH
+0xADFA 0x54ED #CJK UNIFIED IDEOGRAPH
+0xADFB 0x54E1 #CJK UNIFIED IDEOGRAPH
+0xADFC 0x5509 #CJK UNIFIED IDEOGRAPH
+0xADFD 0x54EE #CJK UNIFIED IDEOGRAPH
+0xADFE 0x54EA #CJK UNIFIED IDEOGRAPH
+0xAE40 0x54E6 #CJK UNIFIED IDEOGRAPH
+0xAE41 0x5527 #CJK UNIFIED IDEOGRAPH
+0xAE42 0x5507 #CJK UNIFIED IDEOGRAPH
+0xAE43 0x54FD #CJK UNIFIED IDEOGRAPH
+0xAE44 0x550F #CJK UNIFIED IDEOGRAPH
+0xAE45 0x5703 #CJK UNIFIED IDEOGRAPH
+0xAE46 0x5704 #CJK UNIFIED IDEOGRAPH
+0xAE47 0x57C2 #CJK UNIFIED IDEOGRAPH
+0xAE48 0x57D4 #CJK UNIFIED IDEOGRAPH
+0xAE49 0x57CB #CJK UNIFIED IDEOGRAPH
+0xAE4A 0x57C3 #CJK UNIFIED IDEOGRAPH
+0xAE4B 0x5809 #CJK UNIFIED IDEOGRAPH
+0xAE4C 0x590F #CJK UNIFIED IDEOGRAPH
+0xAE4D 0x5957 #CJK UNIFIED IDEOGRAPH
+0xAE4E 0x5958 #CJK UNIFIED IDEOGRAPH
+0xAE4F 0x595A #CJK UNIFIED IDEOGRAPH
+0xAE50 0x5A11 #CJK UNIFIED IDEOGRAPH
+0xAE51 0x5A18 #CJK UNIFIED IDEOGRAPH
+0xAE52 0x5A1C #CJK UNIFIED IDEOGRAPH
+0xAE53 0x5A1F #CJK UNIFIED IDEOGRAPH
+0xAE54 0x5A1B #CJK UNIFIED IDEOGRAPH
+0xAE55 0x5A13 #CJK UNIFIED IDEOGRAPH
+0xAE56 0x59EC #CJK UNIFIED IDEOGRAPH
+0xAE57 0x5A20 #CJK UNIFIED IDEOGRAPH
+0xAE58 0x5A23 #CJK UNIFIED IDEOGRAPH
+0xAE59 0x5A29 #CJK UNIFIED IDEOGRAPH
+0xAE5A 0x5A25 #CJK UNIFIED IDEOGRAPH
+0xAE5B 0x5A0C #CJK UNIFIED IDEOGRAPH
+0xAE5C 0x5A09 #CJK UNIFIED IDEOGRAPH
+0xAE5D 0x5B6B #CJK UNIFIED IDEOGRAPH
+0xAE5E 0x5C58 #CJK UNIFIED IDEOGRAPH
+0xAE5F 0x5BB0 #CJK UNIFIED IDEOGRAPH
+0xAE60 0x5BB3 #CJK UNIFIED IDEOGRAPH
+0xAE61 0x5BB6 #CJK UNIFIED IDEOGRAPH
+0xAE62 0x5BB4 #CJK UNIFIED IDEOGRAPH
+0xAE63 0x5BAE #CJK UNIFIED IDEOGRAPH
+0xAE64 0x5BB5 #CJK UNIFIED IDEOGRAPH
+0xAE65 0x5BB9 #CJK UNIFIED IDEOGRAPH
+0xAE66 0x5BB8 #CJK UNIFIED IDEOGRAPH
+0xAE67 0x5C04 #CJK UNIFIED IDEOGRAPH
+0xAE68 0x5C51 #CJK UNIFIED IDEOGRAPH
+0xAE69 0x5C55 #CJK UNIFIED IDEOGRAPH
+0xAE6A 0x5C50 #CJK UNIFIED IDEOGRAPH
+0xAE6B 0x5CED #CJK UNIFIED IDEOGRAPH
+0xAE6C 0x5CFD #CJK UNIFIED IDEOGRAPH
+0xAE6D 0x5CFB #CJK UNIFIED IDEOGRAPH
+0xAE6E 0x5CEA #CJK UNIFIED IDEOGRAPH
+0xAE6F 0x5CE8 #CJK UNIFIED IDEOGRAPH
+0xAE70 0x5CF0 #CJK UNIFIED IDEOGRAPH
+0xAE71 0x5CF6 #CJK UNIFIED IDEOGRAPH
+0xAE72 0x5D01 #CJK UNIFIED IDEOGRAPH
+0xAE73 0x5CF4 #CJK UNIFIED IDEOGRAPH
+0xAE74 0x5DEE #CJK UNIFIED IDEOGRAPH
+0xAE75 0x5E2D #CJK UNIFIED IDEOGRAPH
+0xAE76 0x5E2B #CJK UNIFIED IDEOGRAPH
+0xAE77 0x5EAB #CJK UNIFIED IDEOGRAPH
+0xAE78 0x5EAD #CJK UNIFIED IDEOGRAPH
+0xAE79 0x5EA7 #CJK UNIFIED IDEOGRAPH
+0xAE7A 0x5F31 #CJK UNIFIED IDEOGRAPH
+0xAE7B 0x5F92 #CJK UNIFIED IDEOGRAPH
+0xAE7C 0x5F91 #CJK UNIFIED IDEOGRAPH
+0xAE7D 0x5F90 #CJK UNIFIED IDEOGRAPH
+0xAE7E 0x6059 #CJK UNIFIED IDEOGRAPH
+0xAEA1 0x6063 #CJK UNIFIED IDEOGRAPH
+0xAEA2 0x6065 #CJK UNIFIED IDEOGRAPH
+0xAEA3 0x6050 #CJK UNIFIED IDEOGRAPH
+0xAEA4 0x6055 #CJK UNIFIED IDEOGRAPH
+0xAEA5 0x606D #CJK UNIFIED IDEOGRAPH
+0xAEA6 0x6069 #CJK UNIFIED IDEOGRAPH
+0xAEA7 0x606F #CJK UNIFIED IDEOGRAPH
+0xAEA8 0x6084 #CJK UNIFIED IDEOGRAPH
+0xAEA9 0x609F #CJK UNIFIED IDEOGRAPH
+0xAEAA 0x609A #CJK UNIFIED IDEOGRAPH
+0xAEAB 0x608D #CJK UNIFIED IDEOGRAPH
+0xAEAC 0x6094 #CJK UNIFIED IDEOGRAPH
+0xAEAD 0x608C #CJK UNIFIED IDEOGRAPH
+0xAEAE 0x6085 #CJK UNIFIED IDEOGRAPH
+0xAEAF 0x6096 #CJK UNIFIED IDEOGRAPH
+0xAEB0 0x6247 #CJK UNIFIED IDEOGRAPH
+0xAEB1 0x62F3 #CJK UNIFIED IDEOGRAPH
+0xAEB2 0x6308 #CJK UNIFIED IDEOGRAPH
+0xAEB3 0x62FF #CJK UNIFIED IDEOGRAPH
+0xAEB4 0x634E #CJK UNIFIED IDEOGRAPH
+0xAEB5 0x633E #CJK UNIFIED IDEOGRAPH
+0xAEB6 0x632F #CJK UNIFIED IDEOGRAPH
+0xAEB7 0x6355 #CJK UNIFIED IDEOGRAPH
+0xAEB8 0x6342 #CJK UNIFIED IDEOGRAPH
+0xAEB9 0x6346 #CJK UNIFIED IDEOGRAPH
+0xAEBA 0x634F #CJK UNIFIED IDEOGRAPH
+0xAEBB 0x6349 #CJK UNIFIED IDEOGRAPH
+0xAEBC 0x633A #CJK UNIFIED IDEOGRAPH
+0xAEBD 0x6350 #CJK UNIFIED IDEOGRAPH
+0xAEBE 0x633D #CJK UNIFIED IDEOGRAPH
+0xAEBF 0x632A #CJK UNIFIED IDEOGRAPH
+0xAEC0 0x632B #CJK UNIFIED IDEOGRAPH
+0xAEC1 0x6328 #CJK UNIFIED IDEOGRAPH
+0xAEC2 0x634D #CJK UNIFIED IDEOGRAPH
+0xAEC3 0x634C #CJK UNIFIED IDEOGRAPH
+0xAEC4 0x6548 #CJK UNIFIED IDEOGRAPH
+0xAEC5 0x6549 #CJK UNIFIED IDEOGRAPH
+0xAEC6 0x6599 #CJK UNIFIED IDEOGRAPH
+0xAEC7 0x65C1 #CJK UNIFIED IDEOGRAPH
+0xAEC8 0x65C5 #CJK UNIFIED IDEOGRAPH
+0xAEC9 0x6642 #CJK UNIFIED IDEOGRAPH
+0xAECA 0x6649 #CJK UNIFIED IDEOGRAPH
+0xAECB 0x664F #CJK UNIFIED IDEOGRAPH
+0xAECC 0x6643 #CJK UNIFIED IDEOGRAPH
+0xAECD 0x6652 #CJK UNIFIED IDEOGRAPH
+0xAECE 0x664C #CJK UNIFIED IDEOGRAPH
+0xAECF 0x6645 #CJK UNIFIED IDEOGRAPH
+0xAED0 0x6641 #CJK UNIFIED IDEOGRAPH
+0xAED1 0x66F8 #CJK UNIFIED IDEOGRAPH
+0xAED2 0x6714 #CJK UNIFIED IDEOGRAPH
+0xAED3 0x6715 #CJK UNIFIED IDEOGRAPH
+0xAED4 0x6717 #CJK UNIFIED IDEOGRAPH
+0xAED5 0x6821 #CJK UNIFIED IDEOGRAPH
+0xAED6 0x6838 #CJK UNIFIED IDEOGRAPH
+0xAED7 0x6848 #CJK UNIFIED IDEOGRAPH
+0xAED8 0x6846 #CJK UNIFIED IDEOGRAPH
+0xAED9 0x6853 #CJK UNIFIED IDEOGRAPH
+0xAEDA 0x6839 #CJK UNIFIED IDEOGRAPH
+0xAEDB 0x6842 #CJK UNIFIED IDEOGRAPH
+0xAEDC 0x6854 #CJK UNIFIED IDEOGRAPH
+0xAEDD 0x6829 #CJK UNIFIED IDEOGRAPH
+0xAEDE 0x68B3 #CJK UNIFIED IDEOGRAPH
+0xAEDF 0x6817 #CJK UNIFIED IDEOGRAPH
+0xAEE0 0x684C #CJK UNIFIED IDEOGRAPH
+0xAEE1 0x6851 #CJK UNIFIED IDEOGRAPH
+0xAEE2 0x683D #CJK UNIFIED IDEOGRAPH
+0xAEE3 0x67F4 #CJK UNIFIED IDEOGRAPH
+0xAEE4 0x6850 #CJK UNIFIED IDEOGRAPH
+0xAEE5 0x6840 #CJK UNIFIED IDEOGRAPH
+0xAEE6 0x683C #CJK UNIFIED IDEOGRAPH
+0xAEE7 0x6843 #CJK UNIFIED IDEOGRAPH
+0xAEE8 0x682A #CJK UNIFIED IDEOGRAPH
+0xAEE9 0x6845 #CJK UNIFIED IDEOGRAPH
+0xAEEA 0x6813 #CJK UNIFIED IDEOGRAPH
+0xAEEB 0x6818 #CJK UNIFIED IDEOGRAPH
+0xAEEC 0x6841 #CJK UNIFIED IDEOGRAPH
+0xAEED 0x6B8A #CJK UNIFIED IDEOGRAPH
+0xAEEE 0x6B89 #CJK UNIFIED IDEOGRAPH
+0xAEEF 0x6BB7 #CJK UNIFIED IDEOGRAPH
+0xAEF0 0x6C23 #CJK UNIFIED IDEOGRAPH
+0xAEF1 0x6C27 #CJK UNIFIED IDEOGRAPH
+0xAEF2 0x6C28 #CJK UNIFIED IDEOGRAPH
+0xAEF3 0x6C26 #CJK UNIFIED IDEOGRAPH
+0xAEF4 0x6C24 #CJK UNIFIED IDEOGRAPH
+0xAEF5 0x6CF0 #CJK UNIFIED IDEOGRAPH
+0xAEF6 0x6D6A #CJK UNIFIED IDEOGRAPH
+0xAEF7 0x6D95 #CJK UNIFIED IDEOGRAPH
+0xAEF8 0x6D88 #CJK UNIFIED IDEOGRAPH
+0xAEF9 0x6D87 #CJK UNIFIED IDEOGRAPH
+0xAEFA 0x6D66 #CJK UNIFIED IDEOGRAPH
+0xAEFB 0x6D78 #CJK UNIFIED IDEOGRAPH
+0xAEFC 0x6D77 #CJK UNIFIED IDEOGRAPH
+0xAEFD 0x6D59 #CJK UNIFIED IDEOGRAPH
+0xAEFE 0x6D93 #CJK UNIFIED IDEOGRAPH
+0xAF40 0x6D6C #CJK UNIFIED IDEOGRAPH
+0xAF41 0x6D89 #CJK UNIFIED IDEOGRAPH
+0xAF42 0x6D6E #CJK UNIFIED IDEOGRAPH
+0xAF43 0x6D5A #CJK UNIFIED IDEOGRAPH
+0xAF44 0x6D74 #CJK UNIFIED IDEOGRAPH
+0xAF45 0x6D69 #CJK UNIFIED IDEOGRAPH
+0xAF46 0x6D8C #CJK UNIFIED IDEOGRAPH
+0xAF47 0x6D8A #CJK UNIFIED IDEOGRAPH
+0xAF48 0x6D79 #CJK UNIFIED IDEOGRAPH
+0xAF49 0x6D85 #CJK UNIFIED IDEOGRAPH
+0xAF4A 0x6D65 #CJK UNIFIED IDEOGRAPH
+0xAF4B 0x6D94 #CJK UNIFIED IDEOGRAPH
+0xAF4C 0x70CA #CJK UNIFIED IDEOGRAPH
+0xAF4D 0x70D8 #CJK UNIFIED IDEOGRAPH
+0xAF4E 0x70E4 #CJK UNIFIED IDEOGRAPH
+0xAF4F 0x70D9 #CJK UNIFIED IDEOGRAPH
+0xAF50 0x70C8 #CJK UNIFIED IDEOGRAPH
+0xAF51 0x70CF #CJK UNIFIED IDEOGRAPH
+0xAF52 0x7239 #CJK UNIFIED IDEOGRAPH
+0xAF53 0x7279 #CJK UNIFIED IDEOGRAPH
+0xAF54 0x72FC #CJK UNIFIED IDEOGRAPH
+0xAF55 0x72F9 #CJK UNIFIED IDEOGRAPH
+0xAF56 0x72FD #CJK UNIFIED IDEOGRAPH
+0xAF57 0x72F8 #CJK UNIFIED IDEOGRAPH
+0xAF58 0x72F7 #CJK UNIFIED IDEOGRAPH
+0xAF59 0x7386 #CJK UNIFIED IDEOGRAPH
+0xAF5A 0x73ED #CJK UNIFIED IDEOGRAPH
+0xAF5B 0x7409 #CJK UNIFIED IDEOGRAPH
+0xAF5C 0x73EE #CJK UNIFIED IDEOGRAPH
+0xAF5D 0x73E0 #CJK UNIFIED IDEOGRAPH
+0xAF5E 0x73EA #CJK UNIFIED IDEOGRAPH
+0xAF5F 0x73DE #CJK UNIFIED IDEOGRAPH
+0xAF60 0x7554 #CJK UNIFIED IDEOGRAPH
+0xAF61 0x755D #CJK UNIFIED IDEOGRAPH
+0xAF62 0x755C #CJK UNIFIED IDEOGRAPH
+0xAF63 0x755A #CJK UNIFIED IDEOGRAPH
+0xAF64 0x7559 #CJK UNIFIED IDEOGRAPH
+0xAF65 0x75BE #CJK UNIFIED IDEOGRAPH
+0xAF66 0x75C5 #CJK UNIFIED IDEOGRAPH
+0xAF67 0x75C7 #CJK UNIFIED IDEOGRAPH
+0xAF68 0x75B2 #CJK UNIFIED IDEOGRAPH
+0xAF69 0x75B3 #CJK UNIFIED IDEOGRAPH
+0xAF6A 0x75BD #CJK UNIFIED IDEOGRAPH
+0xAF6B 0x75BC #CJK UNIFIED IDEOGRAPH
+0xAF6C 0x75B9 #CJK UNIFIED IDEOGRAPH
+0xAF6D 0x75C2 #CJK UNIFIED IDEOGRAPH
+0xAF6E 0x75B8 #CJK UNIFIED IDEOGRAPH
+0xAF6F 0x768B #CJK UNIFIED IDEOGRAPH
+0xAF70 0x76B0 #CJK UNIFIED IDEOGRAPH
+0xAF71 0x76CA #CJK UNIFIED IDEOGRAPH
+0xAF72 0x76CD #CJK UNIFIED IDEOGRAPH
+0xAF73 0x76CE #CJK UNIFIED IDEOGRAPH
+0xAF74 0x7729 #CJK UNIFIED IDEOGRAPH
+0xAF75 0x771F #CJK UNIFIED IDEOGRAPH
+0xAF76 0x7720 #CJK UNIFIED IDEOGRAPH
+0xAF77 0x7728 #CJK UNIFIED IDEOGRAPH
+0xAF78 0x77E9 #CJK UNIFIED IDEOGRAPH
+0xAF79 0x7830 #CJK UNIFIED IDEOGRAPH
+0xAF7A 0x7827 #CJK UNIFIED IDEOGRAPH
+0xAF7B 0x7838 #CJK UNIFIED IDEOGRAPH
+0xAF7C 0x781D #CJK UNIFIED IDEOGRAPH
+0xAF7D 0x7834 #CJK UNIFIED IDEOGRAPH
+0xAF7E 0x7837 #CJK UNIFIED IDEOGRAPH
+0xAFA1 0x7825 #CJK UNIFIED IDEOGRAPH
+0xAFA2 0x782D #CJK UNIFIED IDEOGRAPH
+0xAFA3 0x7820 #CJK UNIFIED IDEOGRAPH
+0xAFA4 0x781F #CJK UNIFIED IDEOGRAPH
+0xAFA5 0x7832 #CJK UNIFIED IDEOGRAPH
+0xAFA6 0x7955 #CJK UNIFIED IDEOGRAPH
+0xAFA7 0x7950 #CJK UNIFIED IDEOGRAPH
+0xAFA8 0x7960 #CJK UNIFIED IDEOGRAPH
+0xAFA9 0x795F #CJK UNIFIED IDEOGRAPH
+0xAFAA 0x7956 #CJK UNIFIED IDEOGRAPH
+0xAFAB 0x795E #CJK UNIFIED IDEOGRAPH
+0xAFAC 0x795D #CJK UNIFIED IDEOGRAPH
+0xAFAD 0x7957 #CJK UNIFIED IDEOGRAPH
+0xAFAE 0x795A #CJK UNIFIED IDEOGRAPH
+0xAFAF 0x79E4 #CJK UNIFIED IDEOGRAPH
+0xAFB0 0x79E3 #CJK UNIFIED IDEOGRAPH
+0xAFB1 0x79E7 #CJK UNIFIED IDEOGRAPH
+0xAFB2 0x79DF #CJK UNIFIED IDEOGRAPH
+0xAFB3 0x79E6 #CJK UNIFIED IDEOGRAPH
+0xAFB4 0x79E9 #CJK UNIFIED IDEOGRAPH
+0xAFB5 0x79D8 #CJK UNIFIED IDEOGRAPH
+0xAFB6 0x7A84 #CJK UNIFIED IDEOGRAPH
+0xAFB7 0x7A88 #CJK UNIFIED IDEOGRAPH
+0xAFB8 0x7AD9 #CJK UNIFIED IDEOGRAPH
+0xAFB9 0x7B06 #CJK UNIFIED IDEOGRAPH
+0xAFBA 0x7B11 #CJK UNIFIED IDEOGRAPH
+0xAFBB 0x7C89 #CJK UNIFIED IDEOGRAPH
+0xAFBC 0x7D21 #CJK UNIFIED IDEOGRAPH
+0xAFBD 0x7D17 #CJK UNIFIED IDEOGRAPH
+0xAFBE 0x7D0B #CJK UNIFIED IDEOGRAPH
+0xAFBF 0x7D0A #CJK UNIFIED IDEOGRAPH
+0xAFC0 0x7D20 #CJK UNIFIED IDEOGRAPH
+0xAFC1 0x7D22 #CJK UNIFIED IDEOGRAPH
+0xAFC2 0x7D14 #CJK UNIFIED IDEOGRAPH
+0xAFC3 0x7D10 #CJK UNIFIED IDEOGRAPH
+0xAFC4 0x7D15 #CJK UNIFIED IDEOGRAPH
+0xAFC5 0x7D1A #CJK UNIFIED IDEOGRAPH
+0xAFC6 0x7D1C #CJK UNIFIED IDEOGRAPH
+0xAFC7 0x7D0D #CJK UNIFIED IDEOGRAPH
+0xAFC8 0x7D19 #CJK UNIFIED IDEOGRAPH
+0xAFC9 0x7D1B #CJK UNIFIED IDEOGRAPH
+0xAFCA 0x7F3A #CJK UNIFIED IDEOGRAPH
+0xAFCB 0x7F5F #CJK UNIFIED IDEOGRAPH
+0xAFCC 0x7F94 #CJK UNIFIED IDEOGRAPH
+0xAFCD 0x7FC5 #CJK UNIFIED IDEOGRAPH
+0xAFCE 0x7FC1 #CJK UNIFIED IDEOGRAPH
+0xAFCF 0x8006 #CJK UNIFIED IDEOGRAPH
+0xAFD0 0x8018 #CJK UNIFIED IDEOGRAPH
+0xAFD1 0x8015 #CJK UNIFIED IDEOGRAPH
+0xAFD2 0x8019 #CJK UNIFIED IDEOGRAPH
+0xAFD3 0x8017 #CJK UNIFIED IDEOGRAPH
+0xAFD4 0x803D #CJK UNIFIED IDEOGRAPH
+0xAFD5 0x803F #CJK UNIFIED IDEOGRAPH
+0xAFD6 0x80F1 #CJK UNIFIED IDEOGRAPH
+0xAFD7 0x8102 #CJK UNIFIED IDEOGRAPH
+0xAFD8 0x80F0 #CJK UNIFIED IDEOGRAPH
+0xAFD9 0x8105 #CJK UNIFIED IDEOGRAPH
+0xAFDA 0x80ED #CJK UNIFIED IDEOGRAPH
+0xAFDB 0x80F4 #CJK UNIFIED IDEOGRAPH
+0xAFDC 0x8106 #CJK UNIFIED IDEOGRAPH
+0xAFDD 0x80F8 #CJK UNIFIED IDEOGRAPH
+0xAFDE 0x80F3 #CJK UNIFIED IDEOGRAPH
+0xAFDF 0x8108 #CJK UNIFIED IDEOGRAPH
+0xAFE0 0x80FD #CJK UNIFIED IDEOGRAPH
+0xAFE1 0x810A #CJK UNIFIED IDEOGRAPH
+0xAFE2 0x80FC #CJK UNIFIED IDEOGRAPH
+0xAFE3 0x80EF #CJK UNIFIED IDEOGRAPH
+0xAFE4 0x81ED #CJK UNIFIED IDEOGRAPH
+0xAFE5 0x81EC #CJK UNIFIED IDEOGRAPH
+0xAFE6 0x8200 #CJK UNIFIED IDEOGRAPH
+0xAFE7 0x8210 #CJK UNIFIED IDEOGRAPH
+0xAFE8 0x822A #CJK UNIFIED IDEOGRAPH
+0xAFE9 0x822B #CJK UNIFIED IDEOGRAPH
+0xAFEA 0x8228 #CJK UNIFIED IDEOGRAPH
+0xAFEB 0x822C #CJK UNIFIED IDEOGRAPH
+0xAFEC 0x82BB #CJK UNIFIED IDEOGRAPH
+0xAFED 0x832B #CJK UNIFIED IDEOGRAPH
+0xAFEE 0x8352 #CJK UNIFIED IDEOGRAPH
+0xAFEF 0x8354 #CJK UNIFIED IDEOGRAPH
+0xAFF0 0x834A #CJK UNIFIED IDEOGRAPH
+0xAFF1 0x8338 #CJK UNIFIED IDEOGRAPH
+0xAFF2 0x8350 #CJK UNIFIED IDEOGRAPH
+0xAFF3 0x8349 #CJK UNIFIED IDEOGRAPH
+0xAFF4 0x8335 #CJK UNIFIED IDEOGRAPH
+0xAFF5 0x8334 #CJK UNIFIED IDEOGRAPH
+0xAFF6 0x834F #CJK UNIFIED IDEOGRAPH
+0xAFF7 0x8332 #CJK UNIFIED IDEOGRAPH
+0xAFF8 0x8339 #CJK UNIFIED IDEOGRAPH
+0xAFF9 0x8336 #CJK UNIFIED IDEOGRAPH
+0xAFFA 0x8317 #CJK UNIFIED IDEOGRAPH
+0xAFFB 0x8340 #CJK UNIFIED IDEOGRAPH
+0xAFFC 0x8331 #CJK UNIFIED IDEOGRAPH
+0xAFFD 0x8328 #CJK UNIFIED IDEOGRAPH
+0xAFFE 0x8343 #CJK UNIFIED IDEOGRAPH
+0xB040 0x8654 #CJK UNIFIED IDEOGRAPH
+0xB041 0x868A #CJK UNIFIED IDEOGRAPH
+0xB042 0x86AA #CJK UNIFIED IDEOGRAPH
+0xB043 0x8693 #CJK UNIFIED IDEOGRAPH
+0xB044 0x86A4 #CJK UNIFIED IDEOGRAPH
+0xB045 0x86A9 #CJK UNIFIED IDEOGRAPH
+0xB046 0x868C #CJK UNIFIED IDEOGRAPH
+0xB047 0x86A3 #CJK UNIFIED IDEOGRAPH
+0xB048 0x869C #CJK UNIFIED IDEOGRAPH
+0xB049 0x8870 #CJK UNIFIED IDEOGRAPH
+0xB04A 0x8877 #CJK UNIFIED IDEOGRAPH
+0xB04B 0x8881 #CJK UNIFIED IDEOGRAPH
+0xB04C 0x8882 #CJK UNIFIED IDEOGRAPH
+0xB04D 0x887D #CJK UNIFIED IDEOGRAPH
+0xB04E 0x8879 #CJK UNIFIED IDEOGRAPH
+0xB04F 0x8A18 #CJK UNIFIED IDEOGRAPH
+0xB050 0x8A10 #CJK UNIFIED IDEOGRAPH
+0xB051 0x8A0E #CJK UNIFIED IDEOGRAPH
+0xB052 0x8A0C #CJK UNIFIED IDEOGRAPH
+0xB053 0x8A15 #CJK UNIFIED IDEOGRAPH
+0xB054 0x8A0A #CJK UNIFIED IDEOGRAPH
+0xB055 0x8A17 #CJK UNIFIED IDEOGRAPH
+0xB056 0x8A13 #CJK UNIFIED IDEOGRAPH
+0xB057 0x8A16 #CJK UNIFIED IDEOGRAPH
+0xB058 0x8A0F #CJK UNIFIED IDEOGRAPH
+0xB059 0x8A11 #CJK UNIFIED IDEOGRAPH
+0xB05A 0x8C48 #CJK UNIFIED IDEOGRAPH
+0xB05B 0x8C7A #CJK UNIFIED IDEOGRAPH
+0xB05C 0x8C79 #CJK UNIFIED IDEOGRAPH
+0xB05D 0x8CA1 #CJK UNIFIED IDEOGRAPH
+0xB05E 0x8CA2 #CJK UNIFIED IDEOGRAPH
+0xB05F 0x8D77 #CJK UNIFIED IDEOGRAPH
+0xB060 0x8EAC #CJK UNIFIED IDEOGRAPH
+0xB061 0x8ED2 #CJK UNIFIED IDEOGRAPH
+0xB062 0x8ED4 #CJK UNIFIED IDEOGRAPH
+0xB063 0x8ECF #CJK UNIFIED IDEOGRAPH
+0xB064 0x8FB1 #CJK UNIFIED IDEOGRAPH
+0xB065 0x9001 #CJK UNIFIED IDEOGRAPH
+0xB066 0x9006 #CJK UNIFIED IDEOGRAPH
+0xB067 0x8FF7 #CJK UNIFIED IDEOGRAPH
+0xB068 0x9000 #CJK UNIFIED IDEOGRAPH
+0xB069 0x8FFA #CJK UNIFIED IDEOGRAPH
+0xB06A 0x8FF4 #CJK UNIFIED IDEOGRAPH
+0xB06B 0x9003 #CJK UNIFIED IDEOGRAPH
+0xB06C 0x8FFD #CJK UNIFIED IDEOGRAPH
+0xB06D 0x9005 #CJK UNIFIED IDEOGRAPH
+0xB06E 0x8FF8 #CJK UNIFIED IDEOGRAPH
+0xB06F 0x9095 #CJK UNIFIED IDEOGRAPH
+0xB070 0x90E1 #CJK UNIFIED IDEOGRAPH
+0xB071 0x90DD #CJK UNIFIED IDEOGRAPH
+0xB072 0x90E2 #CJK UNIFIED IDEOGRAPH
+0xB073 0x9152 #CJK UNIFIED IDEOGRAPH
+0xB074 0x914D #CJK UNIFIED IDEOGRAPH
+0xB075 0x914C #CJK UNIFIED IDEOGRAPH
+0xB076 0x91D8 #CJK UNIFIED IDEOGRAPH
+0xB077 0x91DD #CJK UNIFIED IDEOGRAPH
+0xB078 0x91D7 #CJK UNIFIED IDEOGRAPH
+0xB079 0x91DC #CJK UNIFIED IDEOGRAPH
+0xB07A 0x91D9 #CJK UNIFIED IDEOGRAPH
+0xB07B 0x9583 #CJK UNIFIED IDEOGRAPH
+0xB07C 0x9662 #CJK UNIFIED IDEOGRAPH
+0xB07D 0x9663 #CJK UNIFIED IDEOGRAPH
+0xB07E 0x9661 #CJK UNIFIED IDEOGRAPH
+0xB0A1 0x965B #CJK UNIFIED IDEOGRAPH
+0xB0A2 0x965D #CJK UNIFIED IDEOGRAPH
+0xB0A3 0x9664 #CJK UNIFIED IDEOGRAPH
+0xB0A4 0x9658 #CJK UNIFIED IDEOGRAPH
+0xB0A5 0x965E #CJK UNIFIED IDEOGRAPH
+0xB0A6 0x96BB #CJK UNIFIED IDEOGRAPH
+0xB0A7 0x98E2 #CJK UNIFIED IDEOGRAPH
+0xB0A8 0x99AC #CJK UNIFIED IDEOGRAPH
+0xB0A9 0x9AA8 #CJK UNIFIED IDEOGRAPH
+0xB0AA 0x9AD8 #CJK UNIFIED IDEOGRAPH
+0xB0AB 0x9B25 #CJK UNIFIED IDEOGRAPH
+0xB0AC 0x9B32 #CJK UNIFIED IDEOGRAPH
+0xB0AD 0x9B3C #CJK UNIFIED IDEOGRAPH
+0xB0AE 0x4E7E #CJK UNIFIED IDEOGRAPH
+0xB0AF 0x507A #CJK UNIFIED IDEOGRAPH
+0xB0B0 0x507D #CJK UNIFIED IDEOGRAPH
+0xB0B1 0x505C #CJK UNIFIED IDEOGRAPH
+0xB0B2 0x5047 #CJK UNIFIED IDEOGRAPH
+0xB0B3 0x5043 #CJK UNIFIED IDEOGRAPH
+0xB0B4 0x504C #CJK UNIFIED IDEOGRAPH
+0xB0B5 0x505A #CJK UNIFIED IDEOGRAPH
+0xB0B6 0x5049 #CJK UNIFIED IDEOGRAPH
+0xB0B7 0x5065 #CJK UNIFIED IDEOGRAPH
+0xB0B8 0x5076 #CJK UNIFIED IDEOGRAPH
+0xB0B9 0x504E #CJK UNIFIED IDEOGRAPH
+0xB0BA 0x5055 #CJK UNIFIED IDEOGRAPH
+0xB0BB 0x5075 #CJK UNIFIED IDEOGRAPH
+0xB0BC 0x5074 #CJK UNIFIED IDEOGRAPH
+0xB0BD 0x5077 #CJK UNIFIED IDEOGRAPH
+0xB0BE 0x504F #CJK UNIFIED IDEOGRAPH
+0xB0BF 0x500F #CJK UNIFIED IDEOGRAPH
+0xB0C0 0x506F #CJK UNIFIED IDEOGRAPH
+0xB0C1 0x506D #CJK UNIFIED IDEOGRAPH
+0xB0C2 0x515C #CJK UNIFIED IDEOGRAPH
+0xB0C3 0x5195 #CJK UNIFIED IDEOGRAPH
+0xB0C4 0x51F0 #CJK UNIFIED IDEOGRAPH
+0xB0C5 0x526A #CJK UNIFIED IDEOGRAPH
+0xB0C6 0x526F #CJK UNIFIED IDEOGRAPH
+0xB0C7 0x52D2 #CJK UNIFIED IDEOGRAPH
+0xB0C8 0x52D9 #CJK UNIFIED IDEOGRAPH
+0xB0C9 0x52D8 #CJK UNIFIED IDEOGRAPH
+0xB0CA 0x52D5 #CJK UNIFIED IDEOGRAPH
+0xB0CB 0x5310 #CJK UNIFIED IDEOGRAPH
+0xB0CC 0x530F #CJK UNIFIED IDEOGRAPH
+0xB0CD 0x5319 #CJK UNIFIED IDEOGRAPH
+0xB0CE 0x533F #CJK UNIFIED IDEOGRAPH
+0xB0CF 0x5340 #CJK UNIFIED IDEOGRAPH
+0xB0D0 0x533E #CJK UNIFIED IDEOGRAPH
+0xB0D1 0x53C3 #CJK UNIFIED IDEOGRAPH
+0xB0D2 0x66FC #CJK UNIFIED IDEOGRAPH
+0xB0D3 0x5546 #CJK UNIFIED IDEOGRAPH
+0xB0D4 0x556A #CJK UNIFIED IDEOGRAPH
+0xB0D5 0x5566 #CJK UNIFIED IDEOGRAPH
+0xB0D6 0x5544 #CJK UNIFIED IDEOGRAPH
+0xB0D7 0x555E #CJK UNIFIED IDEOGRAPH
+0xB0D8 0x5561 #CJK UNIFIED IDEOGRAPH
+0xB0D9 0x5543 #CJK UNIFIED IDEOGRAPH
+0xB0DA 0x554A #CJK UNIFIED IDEOGRAPH
+0xB0DB 0x5531 #CJK UNIFIED IDEOGRAPH
+0xB0DC 0x5556 #CJK UNIFIED IDEOGRAPH
+0xB0DD 0x554F #CJK UNIFIED IDEOGRAPH
+0xB0DE 0x5555 #CJK UNIFIED IDEOGRAPH
+0xB0DF 0x552F #CJK UNIFIED IDEOGRAPH
+0xB0E0 0x5564 #CJK UNIFIED IDEOGRAPH
+0xB0E1 0x5538 #CJK UNIFIED IDEOGRAPH
+0xB0E2 0x552E #CJK UNIFIED IDEOGRAPH
+0xB0E3 0x555C #CJK UNIFIED IDEOGRAPH
+0xB0E4 0x552C #CJK UNIFIED IDEOGRAPH
+0xB0E5 0x5563 #CJK UNIFIED IDEOGRAPH
+0xB0E6 0x5533 #CJK UNIFIED IDEOGRAPH
+0xB0E7 0x5541 #CJK UNIFIED IDEOGRAPH
+0xB0E8 0x5557 #CJK UNIFIED IDEOGRAPH
+0xB0E9 0x5708 #CJK UNIFIED IDEOGRAPH
+0xB0EA 0x570B #CJK UNIFIED IDEOGRAPH
+0xB0EB 0x5709 #CJK UNIFIED IDEOGRAPH
+0xB0EC 0x57DF #CJK UNIFIED IDEOGRAPH
+0xB0ED 0x5805 #CJK UNIFIED IDEOGRAPH
+0xB0EE 0x580A #CJK UNIFIED IDEOGRAPH
+0xB0EF 0x5806 #CJK UNIFIED IDEOGRAPH
+0xB0F0 0x57E0 #CJK UNIFIED IDEOGRAPH
+0xB0F1 0x57E4 #CJK UNIFIED IDEOGRAPH
+0xB0F2 0x57FA #CJK UNIFIED IDEOGRAPH
+0xB0F3 0x5802 #CJK UNIFIED IDEOGRAPH
+0xB0F4 0x5835 #CJK UNIFIED IDEOGRAPH
+0xB0F5 0x57F7 #CJK UNIFIED IDEOGRAPH
+0xB0F6 0x57F9 #CJK UNIFIED IDEOGRAPH
+0xB0F7 0x5920 #CJK UNIFIED IDEOGRAPH
+0xB0F8 0x5962 #CJK UNIFIED IDEOGRAPH
+0xB0F9 0x5A36 #CJK UNIFIED IDEOGRAPH
+0xB0FA 0x5A41 #CJK UNIFIED IDEOGRAPH
+0xB0FB 0x5A49 #CJK UNIFIED IDEOGRAPH
+0xB0FC 0x5A66 #CJK UNIFIED IDEOGRAPH
+0xB0FD 0x5A6A #CJK UNIFIED IDEOGRAPH
+0xB0FE 0x5A40 #CJK UNIFIED IDEOGRAPH
+0xB140 0x5A3C #CJK UNIFIED IDEOGRAPH
+0xB141 0x5A62 #CJK UNIFIED IDEOGRAPH
+0xB142 0x5A5A #CJK UNIFIED IDEOGRAPH
+0xB143 0x5A46 #CJK UNIFIED IDEOGRAPH
+0xB144 0x5A4A #CJK UNIFIED IDEOGRAPH
+0xB145 0x5B70 #CJK UNIFIED IDEOGRAPH
+0xB146 0x5BC7 #CJK UNIFIED IDEOGRAPH
+0xB147 0x5BC5 #CJK UNIFIED IDEOGRAPH
+0xB148 0x5BC4 #CJK UNIFIED IDEOGRAPH
+0xB149 0x5BC2 #CJK UNIFIED IDEOGRAPH
+0xB14A 0x5BBF #CJK UNIFIED IDEOGRAPH
+0xB14B 0x5BC6 #CJK UNIFIED IDEOGRAPH
+0xB14C 0x5C09 #CJK UNIFIED IDEOGRAPH
+0xB14D 0x5C08 #CJK UNIFIED IDEOGRAPH
+0xB14E 0x5C07 #CJK UNIFIED IDEOGRAPH
+0xB14F 0x5C60 #CJK UNIFIED IDEOGRAPH
+0xB150 0x5C5C #CJK UNIFIED IDEOGRAPH
+0xB151 0x5C5D #CJK UNIFIED IDEOGRAPH
+0xB152 0x5D07 #CJK UNIFIED IDEOGRAPH
+0xB153 0x5D06 #CJK UNIFIED IDEOGRAPH
+0xB154 0x5D0E #CJK UNIFIED IDEOGRAPH
+0xB155 0x5D1B #CJK UNIFIED IDEOGRAPH
+0xB156 0x5D16 #CJK UNIFIED IDEOGRAPH
+0xB157 0x5D22 #CJK UNIFIED IDEOGRAPH
+0xB158 0x5D11 #CJK UNIFIED IDEOGRAPH
+0xB159 0x5D29 #CJK UNIFIED IDEOGRAPH
+0xB15A 0x5D14 #CJK UNIFIED IDEOGRAPH
+0xB15B 0x5D19 #CJK UNIFIED IDEOGRAPH
+0xB15C 0x5D24 #CJK UNIFIED IDEOGRAPH
+0xB15D 0x5D27 #CJK UNIFIED IDEOGRAPH
+0xB15E 0x5D17 #CJK UNIFIED IDEOGRAPH
+0xB15F 0x5DE2 #CJK UNIFIED IDEOGRAPH
+0xB160 0x5E38 #CJK UNIFIED IDEOGRAPH
+0xB161 0x5E36 #CJK UNIFIED IDEOGRAPH
+0xB162 0x5E33 #CJK UNIFIED IDEOGRAPH
+0xB163 0x5E37 #CJK UNIFIED IDEOGRAPH
+0xB164 0x5EB7 #CJK UNIFIED IDEOGRAPH
+0xB165 0x5EB8 #CJK UNIFIED IDEOGRAPH
+0xB166 0x5EB6 #CJK UNIFIED IDEOGRAPH
+0xB167 0x5EB5 #CJK UNIFIED IDEOGRAPH
+0xB168 0x5EBE #CJK UNIFIED IDEOGRAPH
+0xB169 0x5F35 #CJK UNIFIED IDEOGRAPH
+0xB16A 0x5F37 #CJK UNIFIED IDEOGRAPH
+0xB16B 0x5F57 #CJK UNIFIED IDEOGRAPH
+0xB16C 0x5F6C #CJK UNIFIED IDEOGRAPH
+0xB16D 0x5F69 #CJK UNIFIED IDEOGRAPH
+0xB16E 0x5F6B #CJK UNIFIED IDEOGRAPH
+0xB16F 0x5F97 #CJK UNIFIED IDEOGRAPH
+0xB170 0x5F99 #CJK UNIFIED IDEOGRAPH
+0xB171 0x5F9E #CJK UNIFIED IDEOGRAPH
+0xB172 0x5F98 #CJK UNIFIED IDEOGRAPH
+0xB173 0x5FA1 #CJK UNIFIED IDEOGRAPH
+0xB174 0x5FA0 #CJK UNIFIED IDEOGRAPH
+0xB175 0x5F9C #CJK UNIFIED IDEOGRAPH
+0xB176 0x607F #CJK UNIFIED IDEOGRAPH
+0xB177 0x60A3 #CJK UNIFIED IDEOGRAPH
+0xB178 0x6089 #CJK UNIFIED IDEOGRAPH
+0xB179 0x60A0 #CJK UNIFIED IDEOGRAPH
+0xB17A 0x60A8 #CJK UNIFIED IDEOGRAPH
+0xB17B 0x60CB #CJK UNIFIED IDEOGRAPH
+0xB17C 0x60B4 #CJK UNIFIED IDEOGRAPH
+0xB17D 0x60E6 #CJK UNIFIED IDEOGRAPH
+0xB17E 0x60BD #CJK UNIFIED IDEOGRAPH
+0xB1A1 0x60C5 #CJK UNIFIED IDEOGRAPH
+0xB1A2 0x60BB #CJK UNIFIED IDEOGRAPH
+0xB1A3 0x60B5 #CJK UNIFIED IDEOGRAPH
+0xB1A4 0x60DC #CJK UNIFIED IDEOGRAPH
+0xB1A5 0x60BC #CJK UNIFIED IDEOGRAPH
+0xB1A6 0x60D8 #CJK UNIFIED IDEOGRAPH
+0xB1A7 0x60D5 #CJK UNIFIED IDEOGRAPH
+0xB1A8 0x60C6 #CJK UNIFIED IDEOGRAPH
+0xB1A9 0x60DF #CJK UNIFIED IDEOGRAPH
+0xB1AA 0x60B8 #CJK UNIFIED IDEOGRAPH
+0xB1AB 0x60DA #CJK UNIFIED IDEOGRAPH
+0xB1AC 0x60C7 #CJK UNIFIED IDEOGRAPH
+0xB1AD 0x621A #CJK UNIFIED IDEOGRAPH
+0xB1AE 0x621B #CJK UNIFIED IDEOGRAPH
+0xB1AF 0x6248 #CJK UNIFIED IDEOGRAPH
+0xB1B0 0x63A0 #CJK UNIFIED IDEOGRAPH
+0xB1B1 0x63A7 #CJK UNIFIED IDEOGRAPH
+0xB1B2 0x6372 #CJK UNIFIED IDEOGRAPH
+0xB1B3 0x6396 #CJK UNIFIED IDEOGRAPH
+0xB1B4 0x63A2 #CJK UNIFIED IDEOGRAPH
+0xB1B5 0x63A5 #CJK UNIFIED IDEOGRAPH
+0xB1B6 0x6377 #CJK UNIFIED IDEOGRAPH
+0xB1B7 0x6367 #CJK UNIFIED IDEOGRAPH
+0xB1B8 0x6398 #CJK UNIFIED IDEOGRAPH
+0xB1B9 0x63AA #CJK UNIFIED IDEOGRAPH
+0xB1BA 0x6371 #CJK UNIFIED IDEOGRAPH
+0xB1BB 0x63A9 #CJK UNIFIED IDEOGRAPH
+0xB1BC 0x6389 #CJK UNIFIED IDEOGRAPH
+0xB1BD 0x6383 #CJK UNIFIED IDEOGRAPH
+0xB1BE 0x639B #CJK UNIFIED IDEOGRAPH
+0xB1BF 0x636B #CJK UNIFIED IDEOGRAPH
+0xB1C0 0x63A8 #CJK UNIFIED IDEOGRAPH
+0xB1C1 0x6384 #CJK UNIFIED IDEOGRAPH
+0xB1C2 0x6388 #CJK UNIFIED IDEOGRAPH
+0xB1C3 0x6399 #CJK UNIFIED IDEOGRAPH
+0xB1C4 0x63A1 #CJK UNIFIED IDEOGRAPH
+0xB1C5 0x63AC #CJK UNIFIED IDEOGRAPH
+0xB1C6 0x6392 #CJK UNIFIED IDEOGRAPH
+0xB1C7 0x638F #CJK UNIFIED IDEOGRAPH
+0xB1C8 0x6380 #CJK UNIFIED IDEOGRAPH
+0xB1C9 0x637B #CJK UNIFIED IDEOGRAPH
+0xB1CA 0x6369 #CJK UNIFIED IDEOGRAPH
+0xB1CB 0x6368 #CJK UNIFIED IDEOGRAPH
+0xB1CC 0x637A #CJK UNIFIED IDEOGRAPH
+0xB1CD 0x655D #CJK UNIFIED IDEOGRAPH
+0xB1CE 0x6556 #CJK UNIFIED IDEOGRAPH
+0xB1CF 0x6551 #CJK UNIFIED IDEOGRAPH
+0xB1D0 0x6559 #CJK UNIFIED IDEOGRAPH
+0xB1D1 0x6557 #CJK UNIFIED IDEOGRAPH
+0xB1D2 0x555F #CJK UNIFIED IDEOGRAPH
+0xB1D3 0x654F #CJK UNIFIED IDEOGRAPH
+0xB1D4 0x6558 #CJK UNIFIED IDEOGRAPH
+0xB1D5 0x6555 #CJK UNIFIED IDEOGRAPH
+0xB1D6 0x6554 #CJK UNIFIED IDEOGRAPH
+0xB1D7 0x659C #CJK UNIFIED IDEOGRAPH
+0xB1D8 0x659B #CJK UNIFIED IDEOGRAPH
+0xB1D9 0x65AC #CJK UNIFIED IDEOGRAPH
+0xB1DA 0x65CF #CJK UNIFIED IDEOGRAPH
+0xB1DB 0x65CB #CJK UNIFIED IDEOGRAPH
+0xB1DC 0x65CC #CJK UNIFIED IDEOGRAPH
+0xB1DD 0x65CE #CJK UNIFIED IDEOGRAPH
+0xB1DE 0x665D #CJK UNIFIED IDEOGRAPH
+0xB1DF 0x665A #CJK UNIFIED IDEOGRAPH
+0xB1E0 0x6664 #CJK UNIFIED IDEOGRAPH
+0xB1E1 0x6668 #CJK UNIFIED IDEOGRAPH
+0xB1E2 0x6666 #CJK UNIFIED IDEOGRAPH
+0xB1E3 0x665E #CJK UNIFIED IDEOGRAPH
+0xB1E4 0x66F9 #CJK UNIFIED IDEOGRAPH
+0xB1E5 0x52D7 #CJK UNIFIED IDEOGRAPH
+0xB1E6 0x671B #CJK UNIFIED IDEOGRAPH
+0xB1E7 0x6881 #CJK UNIFIED IDEOGRAPH
+0xB1E8 0x68AF #CJK UNIFIED IDEOGRAPH
+0xB1E9 0x68A2 #CJK UNIFIED IDEOGRAPH
+0xB1EA 0x6893 #CJK UNIFIED IDEOGRAPH
+0xB1EB 0x68B5 #CJK UNIFIED IDEOGRAPH
+0xB1EC 0x687F #CJK UNIFIED IDEOGRAPH
+0xB1ED 0x6876 #CJK UNIFIED IDEOGRAPH
+0xB1EE 0x68B1 #CJK UNIFIED IDEOGRAPH
+0xB1EF 0x68A7 #CJK UNIFIED IDEOGRAPH
+0xB1F0 0x6897 #CJK UNIFIED IDEOGRAPH
+0xB1F1 0x68B0 #CJK UNIFIED IDEOGRAPH
+0xB1F2 0x6883 #CJK UNIFIED IDEOGRAPH
+0xB1F3 0x68C4 #CJK UNIFIED IDEOGRAPH
+0xB1F4 0x68AD #CJK UNIFIED IDEOGRAPH
+0xB1F5 0x6886 #CJK UNIFIED IDEOGRAPH
+0xB1F6 0x6885 #CJK UNIFIED IDEOGRAPH
+0xB1F7 0x6894 #CJK UNIFIED IDEOGRAPH
+0xB1F8 0x689D #CJK UNIFIED IDEOGRAPH
+0xB1F9 0x68A8 #CJK UNIFIED IDEOGRAPH
+0xB1FA 0x689F #CJK UNIFIED IDEOGRAPH
+0xB1FB 0x68A1 #CJK UNIFIED IDEOGRAPH
+0xB1FC 0x6882 #CJK UNIFIED IDEOGRAPH
+0xB1FD 0x6B32 #CJK UNIFIED IDEOGRAPH
+0xB1FE 0x6BBA #CJK UNIFIED IDEOGRAPH
+0xB240 0x6BEB #CJK UNIFIED IDEOGRAPH
+0xB241 0x6BEC #CJK UNIFIED IDEOGRAPH
+0xB242 0x6C2B #CJK UNIFIED IDEOGRAPH
+0xB243 0x6D8E #CJK UNIFIED IDEOGRAPH
+0xB244 0x6DBC #CJK UNIFIED IDEOGRAPH
+0xB245 0x6DF3 #CJK UNIFIED IDEOGRAPH
+0xB246 0x6DD9 #CJK UNIFIED IDEOGRAPH
+0xB247 0x6DB2 #CJK UNIFIED IDEOGRAPH
+0xB248 0x6DE1 #CJK UNIFIED IDEOGRAPH
+0xB249 0x6DCC #CJK UNIFIED IDEOGRAPH
+0xB24A 0x6DE4 #CJK UNIFIED IDEOGRAPH
+0xB24B 0x6DFB #CJK UNIFIED IDEOGRAPH
+0xB24C 0x6DFA #CJK UNIFIED IDEOGRAPH
+0xB24D 0x6E05 #CJK UNIFIED IDEOGRAPH
+0xB24E 0x6DC7 #CJK UNIFIED IDEOGRAPH
+0xB24F 0x6DCB #CJK UNIFIED IDEOGRAPH
+0xB250 0x6DAF #CJK UNIFIED IDEOGRAPH
+0xB251 0x6DD1 #CJK UNIFIED IDEOGRAPH
+0xB252 0x6DAE #CJK UNIFIED IDEOGRAPH
+0xB253 0x6DDE #CJK UNIFIED IDEOGRAPH
+0xB254 0x6DF9 #CJK UNIFIED IDEOGRAPH
+0xB255 0x6DB8 #CJK UNIFIED IDEOGRAPH
+0xB256 0x6DF7 #CJK UNIFIED IDEOGRAPH
+0xB257 0x6DF5 #CJK UNIFIED IDEOGRAPH
+0xB258 0x6DC5 #CJK UNIFIED IDEOGRAPH
+0xB259 0x6DD2 #CJK UNIFIED IDEOGRAPH
+0xB25A 0x6E1A #CJK UNIFIED IDEOGRAPH
+0xB25B 0x6DB5 #CJK UNIFIED IDEOGRAPH
+0xB25C 0x6DDA #CJK UNIFIED IDEOGRAPH
+0xB25D 0x6DEB #CJK UNIFIED IDEOGRAPH
+0xB25E 0x6DD8 #CJK UNIFIED IDEOGRAPH
+0xB25F 0x6DEA #CJK UNIFIED IDEOGRAPH
+0xB260 0x6DF1 #CJK UNIFIED IDEOGRAPH
+0xB261 0x6DEE #CJK UNIFIED IDEOGRAPH
+0xB262 0x6DE8 #CJK UNIFIED IDEOGRAPH
+0xB263 0x6DC6 #CJK UNIFIED IDEOGRAPH
+0xB264 0x6DC4 #CJK UNIFIED IDEOGRAPH
+0xB265 0x6DAA #CJK UNIFIED IDEOGRAPH
+0xB266 0x6DEC #CJK UNIFIED IDEOGRAPH
+0xB267 0x6DBF #CJK UNIFIED IDEOGRAPH
+0xB268 0x6DE6 #CJK UNIFIED IDEOGRAPH
+0xB269 0x70F9 #CJK UNIFIED IDEOGRAPH
+0xB26A 0x7109 #CJK UNIFIED IDEOGRAPH
+0xB26B 0x710A #CJK UNIFIED IDEOGRAPH
+0xB26C 0x70FD #CJK UNIFIED IDEOGRAPH
+0xB26D 0x70EF #CJK UNIFIED IDEOGRAPH
+0xB26E 0x723D #CJK UNIFIED IDEOGRAPH
+0xB26F 0x727D #CJK UNIFIED IDEOGRAPH
+0xB270 0x7281 #CJK UNIFIED IDEOGRAPH
+0xB271 0x731C #CJK UNIFIED IDEOGRAPH
+0xB272 0x731B #CJK UNIFIED IDEOGRAPH
+0xB273 0x7316 #CJK UNIFIED IDEOGRAPH
+0xB274 0x7313 #CJK UNIFIED IDEOGRAPH
+0xB275 0x7319 #CJK UNIFIED IDEOGRAPH
+0xB276 0x7387 #CJK UNIFIED IDEOGRAPH
+0xB277 0x7405 #CJK UNIFIED IDEOGRAPH
+0xB278 0x740A #CJK UNIFIED IDEOGRAPH
+0xB279 0x7403 #CJK UNIFIED IDEOGRAPH
+0xB27A 0x7406 #CJK UNIFIED IDEOGRAPH
+0xB27B 0x73FE #CJK UNIFIED IDEOGRAPH
+0xB27C 0x740D #CJK UNIFIED IDEOGRAPH
+0xB27D 0x74E0 #CJK UNIFIED IDEOGRAPH
+0xB27E 0x74F6 #CJK UNIFIED IDEOGRAPH
+0xB2A1 0x74F7 #CJK UNIFIED IDEOGRAPH
+0xB2A2 0x751C #CJK UNIFIED IDEOGRAPH
+0xB2A3 0x7522 #CJK UNIFIED IDEOGRAPH
+0xB2A4 0x7565 #CJK UNIFIED IDEOGRAPH
+0xB2A5 0x7566 #CJK UNIFIED IDEOGRAPH
+0xB2A6 0x7562 #CJK UNIFIED IDEOGRAPH
+0xB2A7 0x7570 #CJK UNIFIED IDEOGRAPH
+0xB2A8 0x758F #CJK UNIFIED IDEOGRAPH
+0xB2A9 0x75D4 #CJK UNIFIED IDEOGRAPH
+0xB2AA 0x75D5 #CJK UNIFIED IDEOGRAPH
+0xB2AB 0x75B5 #CJK UNIFIED IDEOGRAPH
+0xB2AC 0x75CA #CJK UNIFIED IDEOGRAPH
+0xB2AD 0x75CD #CJK UNIFIED IDEOGRAPH
+0xB2AE 0x768E #CJK UNIFIED IDEOGRAPH
+0xB2AF 0x76D4 #CJK UNIFIED IDEOGRAPH
+0xB2B0 0x76D2 #CJK UNIFIED IDEOGRAPH
+0xB2B1 0x76DB #CJK UNIFIED IDEOGRAPH
+0xB2B2 0x7737 #CJK UNIFIED IDEOGRAPH
+0xB2B3 0x773E #CJK UNIFIED IDEOGRAPH
+0xB2B4 0x773C #CJK UNIFIED IDEOGRAPH
+0xB2B5 0x7736 #CJK UNIFIED IDEOGRAPH
+0xB2B6 0x7738 #CJK UNIFIED IDEOGRAPH
+0xB2B7 0x773A #CJK UNIFIED IDEOGRAPH
+0xB2B8 0x786B #CJK UNIFIED IDEOGRAPH
+0xB2B9 0x7843 #CJK UNIFIED IDEOGRAPH
+0xB2BA 0x784E #CJK UNIFIED IDEOGRAPH
+0xB2BB 0x7965 #CJK UNIFIED IDEOGRAPH
+0xB2BC 0x7968 #CJK UNIFIED IDEOGRAPH
+0xB2BD 0x796D #CJK UNIFIED IDEOGRAPH
+0xB2BE 0x79FB #CJK UNIFIED IDEOGRAPH
+0xB2BF 0x7A92 #CJK UNIFIED IDEOGRAPH
+0xB2C0 0x7A95 #CJK UNIFIED IDEOGRAPH
+0xB2C1 0x7B20 #CJK UNIFIED IDEOGRAPH
+0xB2C2 0x7B28 #CJK UNIFIED IDEOGRAPH
+0xB2C3 0x7B1B #CJK UNIFIED IDEOGRAPH
+0xB2C4 0x7B2C #CJK UNIFIED IDEOGRAPH
+0xB2C5 0x7B26 #CJK UNIFIED IDEOGRAPH
+0xB2C6 0x7B19 #CJK UNIFIED IDEOGRAPH
+0xB2C7 0x7B1E #CJK UNIFIED IDEOGRAPH
+0xB2C8 0x7B2E #CJK UNIFIED IDEOGRAPH
+0xB2C9 0x7C92 #CJK UNIFIED IDEOGRAPH
+0xB2CA 0x7C97 #CJK UNIFIED IDEOGRAPH
+0xB2CB 0x7C95 #CJK UNIFIED IDEOGRAPH
+0xB2CC 0x7D46 #CJK UNIFIED IDEOGRAPH
+0xB2CD 0x7D43 #CJK UNIFIED IDEOGRAPH
+0xB2CE 0x7D71 #CJK UNIFIED IDEOGRAPH
+0xB2CF 0x7D2E #CJK UNIFIED IDEOGRAPH
+0xB2D0 0x7D39 #CJK UNIFIED IDEOGRAPH
+0xB2D1 0x7D3C #CJK UNIFIED IDEOGRAPH
+0xB2D2 0x7D40 #CJK UNIFIED IDEOGRAPH
+0xB2D3 0x7D30 #CJK UNIFIED IDEOGRAPH
+0xB2D4 0x7D33 #CJK UNIFIED IDEOGRAPH
+0xB2D5 0x7D44 #CJK UNIFIED IDEOGRAPH
+0xB2D6 0x7D2F #CJK UNIFIED IDEOGRAPH
+0xB2D7 0x7D42 #CJK UNIFIED IDEOGRAPH
+0xB2D8 0x7D32 #CJK UNIFIED IDEOGRAPH
+0xB2D9 0x7D31 #CJK UNIFIED IDEOGRAPH
+0xB2DA 0x7F3D #CJK UNIFIED IDEOGRAPH
+0xB2DB 0x7F9E #CJK UNIFIED IDEOGRAPH
+0xB2DC 0x7F9A #CJK UNIFIED IDEOGRAPH
+0xB2DD 0x7FCC #CJK UNIFIED IDEOGRAPH
+0xB2DE 0x7FCE #CJK UNIFIED IDEOGRAPH
+0xB2DF 0x7FD2 #CJK UNIFIED IDEOGRAPH
+0xB2E0 0x801C #CJK UNIFIED IDEOGRAPH
+0xB2E1 0x804A #CJK UNIFIED IDEOGRAPH
+0xB2E2 0x8046 #CJK UNIFIED IDEOGRAPH
+0xB2E3 0x812F #CJK UNIFIED IDEOGRAPH
+0xB2E4 0x8116 #CJK UNIFIED IDEOGRAPH
+0xB2E5 0x8123 #CJK UNIFIED IDEOGRAPH
+0xB2E6 0x812B #CJK UNIFIED IDEOGRAPH
+0xB2E7 0x8129 #CJK UNIFIED IDEOGRAPH
+0xB2E8 0x8130 #CJK UNIFIED IDEOGRAPH
+0xB2E9 0x8124 #CJK UNIFIED IDEOGRAPH
+0xB2EA 0x8202 #CJK UNIFIED IDEOGRAPH
+0xB2EB 0x8235 #CJK UNIFIED IDEOGRAPH
+0xB2EC 0x8237 #CJK UNIFIED IDEOGRAPH
+0xB2ED 0x8236 #CJK UNIFIED IDEOGRAPH
+0xB2EE 0x8239 #CJK UNIFIED IDEOGRAPH
+0xB2EF 0x838E #CJK UNIFIED IDEOGRAPH
+0xB2F0 0x839E #CJK UNIFIED IDEOGRAPH
+0xB2F1 0x8398 #CJK UNIFIED IDEOGRAPH
+0xB2F2 0x8378 #CJK UNIFIED IDEOGRAPH
+0xB2F3 0x83A2 #CJK UNIFIED IDEOGRAPH
+0xB2F4 0x8396 #CJK UNIFIED IDEOGRAPH
+0xB2F5 0x83BD #CJK UNIFIED IDEOGRAPH
+0xB2F6 0x83AB #CJK UNIFIED IDEOGRAPH
+0xB2F7 0x8392 #CJK UNIFIED IDEOGRAPH
+0xB2F8 0x838A #CJK UNIFIED IDEOGRAPH
+0xB2F9 0x8393 #CJK UNIFIED IDEOGRAPH
+0xB2FA 0x8389 #CJK UNIFIED IDEOGRAPH
+0xB2FB 0x83A0 #CJK UNIFIED IDEOGRAPH
+0xB2FC 0x8377 #CJK UNIFIED IDEOGRAPH
+0xB2FD 0x837B #CJK UNIFIED IDEOGRAPH
+0xB2FE 0x837C #CJK UNIFIED IDEOGRAPH
+0xB340 0x8386 #CJK UNIFIED IDEOGRAPH
+0xB341 0x83A7 #CJK UNIFIED IDEOGRAPH
+0xB342 0x8655 #CJK UNIFIED IDEOGRAPH
+0xB343 0x5F6A #CJK UNIFIED IDEOGRAPH
+0xB344 0x86C7 #CJK UNIFIED IDEOGRAPH
+0xB345 0x86C0 #CJK UNIFIED IDEOGRAPH
+0xB346 0x86B6 #CJK UNIFIED IDEOGRAPH
+0xB347 0x86C4 #CJK UNIFIED IDEOGRAPH
+0xB348 0x86B5 #CJK UNIFIED IDEOGRAPH
+0xB349 0x86C6 #CJK UNIFIED IDEOGRAPH
+0xB34A 0x86CB #CJK UNIFIED IDEOGRAPH
+0xB34B 0x86B1 #CJK UNIFIED IDEOGRAPH
+0xB34C 0x86AF #CJK UNIFIED IDEOGRAPH
+0xB34D 0x86C9 #CJK UNIFIED IDEOGRAPH
+0xB34E 0x8853 #CJK UNIFIED IDEOGRAPH
+0xB34F 0x889E #CJK UNIFIED IDEOGRAPH
+0xB350 0x8888 #CJK UNIFIED IDEOGRAPH
+0xB351 0x88AB #CJK UNIFIED IDEOGRAPH
+0xB352 0x8892 #CJK UNIFIED IDEOGRAPH
+0xB353 0x8896 #CJK UNIFIED IDEOGRAPH
+0xB354 0x888D #CJK UNIFIED IDEOGRAPH
+0xB355 0x888B #CJK UNIFIED IDEOGRAPH
+0xB356 0x8993 #CJK UNIFIED IDEOGRAPH
+0xB357 0x898F #CJK UNIFIED IDEOGRAPH
+0xB358 0x8A2A #CJK UNIFIED IDEOGRAPH
+0xB359 0x8A1D #CJK UNIFIED IDEOGRAPH
+0xB35A 0x8A23 #CJK UNIFIED IDEOGRAPH
+0xB35B 0x8A25 #CJK UNIFIED IDEOGRAPH
+0xB35C 0x8A31 #CJK UNIFIED IDEOGRAPH
+0xB35D 0x8A2D #CJK UNIFIED IDEOGRAPH
+0xB35E 0x8A1F #CJK UNIFIED IDEOGRAPH
+0xB35F 0x8A1B #CJK UNIFIED IDEOGRAPH
+0xB360 0x8A22 #CJK UNIFIED IDEOGRAPH
+0xB361 0x8C49 #CJK UNIFIED IDEOGRAPH
+0xB362 0x8C5A #CJK UNIFIED IDEOGRAPH
+0xB363 0x8CA9 #CJK UNIFIED IDEOGRAPH
+0xB364 0x8CAC #CJK UNIFIED IDEOGRAPH
+0xB365 0x8CAB #CJK UNIFIED IDEOGRAPH
+0xB366 0x8CA8 #CJK UNIFIED IDEOGRAPH
+0xB367 0x8CAA #CJK UNIFIED IDEOGRAPH
+0xB368 0x8CA7 #CJK UNIFIED IDEOGRAPH
+0xB369 0x8D67 #CJK UNIFIED IDEOGRAPH
+0xB36A 0x8D66 #CJK UNIFIED IDEOGRAPH
+0xB36B 0x8DBE #CJK UNIFIED IDEOGRAPH
+0xB36C 0x8DBA #CJK UNIFIED IDEOGRAPH
+0xB36D 0x8EDB #CJK UNIFIED IDEOGRAPH
+0xB36E 0x8EDF #CJK UNIFIED IDEOGRAPH
+0xB36F 0x9019 #CJK UNIFIED IDEOGRAPH
+0xB370 0x900D #CJK UNIFIED IDEOGRAPH
+0xB371 0x901A #CJK UNIFIED IDEOGRAPH
+0xB372 0x9017 #CJK UNIFIED IDEOGRAPH
+0xB373 0x9023 #CJK UNIFIED IDEOGRAPH
+0xB374 0x901F #CJK UNIFIED IDEOGRAPH
+0xB375 0x901D #CJK UNIFIED IDEOGRAPH
+0xB376 0x9010 #CJK UNIFIED IDEOGRAPH
+0xB377 0x9015 #CJK UNIFIED IDEOGRAPH
+0xB378 0x901E #CJK UNIFIED IDEOGRAPH
+0xB379 0x9020 #CJK UNIFIED IDEOGRAPH
+0xB37A 0x900F #CJK UNIFIED IDEOGRAPH
+0xB37B 0x9022 #CJK UNIFIED IDEOGRAPH
+0xB37C 0x9016 #CJK UNIFIED IDEOGRAPH
+0xB37D 0x901B #CJK UNIFIED IDEOGRAPH
+0xB37E 0x9014 #CJK UNIFIED IDEOGRAPH
+0xB3A1 0x90E8 #CJK UNIFIED IDEOGRAPH
+0xB3A2 0x90ED #CJK UNIFIED IDEOGRAPH
+0xB3A3 0x90FD #CJK UNIFIED IDEOGRAPH
+0xB3A4 0x9157 #CJK UNIFIED IDEOGRAPH
+0xB3A5 0x91CE #CJK UNIFIED IDEOGRAPH
+0xB3A6 0x91F5 #CJK UNIFIED IDEOGRAPH
+0xB3A7 0x91E6 #CJK UNIFIED IDEOGRAPH
+0xB3A8 0x91E3 #CJK UNIFIED IDEOGRAPH
+0xB3A9 0x91E7 #CJK UNIFIED IDEOGRAPH
+0xB3AA 0x91ED #CJK UNIFIED IDEOGRAPH
+0xB3AB 0x91E9 #CJK UNIFIED IDEOGRAPH
+0xB3AC 0x9589 #CJK UNIFIED IDEOGRAPH
+0xB3AD 0x966A #CJK UNIFIED IDEOGRAPH
+0xB3AE 0x9675 #CJK UNIFIED IDEOGRAPH
+0xB3AF 0x9673 #CJK UNIFIED IDEOGRAPH
+0xB3B0 0x9678 #CJK UNIFIED IDEOGRAPH
+0xB3B1 0x9670 #CJK UNIFIED IDEOGRAPH
+0xB3B2 0x9674 #CJK UNIFIED IDEOGRAPH
+0xB3B3 0x9676 #CJK UNIFIED IDEOGRAPH
+0xB3B4 0x9677 #CJK UNIFIED IDEOGRAPH
+0xB3B5 0x966C #CJK UNIFIED IDEOGRAPH
+0xB3B6 0x96C0 #CJK UNIFIED IDEOGRAPH
+0xB3B7 0x96EA #CJK UNIFIED IDEOGRAPH
+0xB3B8 0x96E9 #CJK UNIFIED IDEOGRAPH
+0xB3B9 0x7AE0 #CJK UNIFIED IDEOGRAPH
+0xB3BA 0x7ADF #CJK UNIFIED IDEOGRAPH
+0xB3BB 0x9802 #CJK UNIFIED IDEOGRAPH
+0xB3BC 0x9803 #CJK UNIFIED IDEOGRAPH
+0xB3BD 0x9B5A #CJK UNIFIED IDEOGRAPH
+0xB3BE 0x9CE5 #CJK UNIFIED IDEOGRAPH
+0xB3BF 0x9E75 #CJK UNIFIED IDEOGRAPH
+0xB3C0 0x9E7F #CJK UNIFIED IDEOGRAPH
+0xB3C1 0x9EA5 #CJK UNIFIED IDEOGRAPH
+0xB3C2 0x9EBB #CJK UNIFIED IDEOGRAPH
+0xB3C3 0x50A2 #CJK UNIFIED IDEOGRAPH
+0xB3C4 0x508D #CJK UNIFIED IDEOGRAPH
+0xB3C5 0x5085 #CJK UNIFIED IDEOGRAPH
+0xB3C6 0x5099 #CJK UNIFIED IDEOGRAPH
+0xB3C7 0x5091 #CJK UNIFIED IDEOGRAPH
+0xB3C8 0x5080 #CJK UNIFIED IDEOGRAPH
+0xB3C9 0x5096 #CJK UNIFIED IDEOGRAPH
+0xB3CA 0x5098 #CJK UNIFIED IDEOGRAPH
+0xB3CB 0x509A #CJK UNIFIED IDEOGRAPH
+0xB3CC 0x6700 #CJK UNIFIED IDEOGRAPH
+0xB3CD 0x51F1 #CJK UNIFIED IDEOGRAPH
+0xB3CE 0x5272 #CJK UNIFIED IDEOGRAPH
+0xB3CF 0x5274 #CJK UNIFIED IDEOGRAPH
+0xB3D0 0x5275 #CJK UNIFIED IDEOGRAPH
+0xB3D1 0x5269 #CJK UNIFIED IDEOGRAPH
+0xB3D2 0x52DE #CJK UNIFIED IDEOGRAPH
+0xB3D3 0x52DD #CJK UNIFIED IDEOGRAPH
+0xB3D4 0x52DB #CJK UNIFIED IDEOGRAPH
+0xB3D5 0x535A #CJK UNIFIED IDEOGRAPH
+0xB3D6 0x53A5 #CJK UNIFIED IDEOGRAPH
+0xB3D7 0x557B #CJK UNIFIED IDEOGRAPH
+0xB3D8 0x5580 #CJK UNIFIED IDEOGRAPH
+0xB3D9 0x55A7 #CJK UNIFIED IDEOGRAPH
+0xB3DA 0x557C #CJK UNIFIED IDEOGRAPH
+0xB3DB 0x558A #CJK UNIFIED IDEOGRAPH
+0xB3DC 0x559D #CJK UNIFIED IDEOGRAPH
+0xB3DD 0x5598 #CJK UNIFIED IDEOGRAPH
+0xB3DE 0x5582 #CJK UNIFIED IDEOGRAPH
+0xB3DF 0x559C #CJK UNIFIED IDEOGRAPH
+0xB3E0 0x55AA #CJK UNIFIED IDEOGRAPH
+0xB3E1 0x5594 #CJK UNIFIED IDEOGRAPH
+0xB3E2 0x5587 #CJK UNIFIED IDEOGRAPH
+0xB3E3 0x558B #CJK UNIFIED IDEOGRAPH
+0xB3E4 0x5583 #CJK UNIFIED IDEOGRAPH
+0xB3E5 0x55B3 #CJK UNIFIED IDEOGRAPH
+0xB3E6 0x55AE #CJK UNIFIED IDEOGRAPH
+0xB3E7 0x559F #CJK UNIFIED IDEOGRAPH
+0xB3E8 0x553E #CJK UNIFIED IDEOGRAPH
+0xB3E9 0x55B2 #CJK UNIFIED IDEOGRAPH
+0xB3EA 0x559A #CJK UNIFIED IDEOGRAPH
+0xB3EB 0x55BB #CJK UNIFIED IDEOGRAPH
+0xB3EC 0x55AC #CJK UNIFIED IDEOGRAPH
+0xB3ED 0x55B1 #CJK UNIFIED IDEOGRAPH
+0xB3EE 0x557E #CJK UNIFIED IDEOGRAPH
+0xB3EF 0x5589 #CJK UNIFIED IDEOGRAPH
+0xB3F0 0x55AB #CJK UNIFIED IDEOGRAPH
+0xB3F1 0x5599 #CJK UNIFIED IDEOGRAPH
+0xB3F2 0x570D #CJK UNIFIED IDEOGRAPH
+0xB3F3 0x582F #CJK UNIFIED IDEOGRAPH
+0xB3F4 0x582A #CJK UNIFIED IDEOGRAPH
+0xB3F5 0x5834 #CJK UNIFIED IDEOGRAPH
+0xB3F6 0x5824 #CJK UNIFIED IDEOGRAPH
+0xB3F7 0x5830 #CJK UNIFIED IDEOGRAPH
+0xB3F8 0x5831 #CJK UNIFIED IDEOGRAPH
+0xB3F9 0x5821 #CJK UNIFIED IDEOGRAPH
+0xB3FA 0x581D #CJK UNIFIED IDEOGRAPH
+0xB3FB 0x5820 #CJK UNIFIED IDEOGRAPH
+0xB3FC 0x58F9 #CJK UNIFIED IDEOGRAPH
+0xB3FD 0x58FA #CJK UNIFIED IDEOGRAPH
+0xB3FE 0x5960 #CJK UNIFIED IDEOGRAPH
+0xB440 0x5A77 #CJK UNIFIED IDEOGRAPH
+0xB441 0x5A9A #CJK UNIFIED IDEOGRAPH
+0xB442 0x5A7F #CJK UNIFIED IDEOGRAPH
+0xB443 0x5A92 #CJK UNIFIED IDEOGRAPH
+0xB444 0x5A9B #CJK UNIFIED IDEOGRAPH
+0xB445 0x5AA7 #CJK UNIFIED IDEOGRAPH
+0xB446 0x5B73 #CJK UNIFIED IDEOGRAPH
+0xB447 0x5B71 #CJK UNIFIED IDEOGRAPH
+0xB448 0x5BD2 #CJK UNIFIED IDEOGRAPH
+0xB449 0x5BCC #CJK UNIFIED IDEOGRAPH
+0xB44A 0x5BD3 #CJK UNIFIED IDEOGRAPH
+0xB44B 0x5BD0 #CJK UNIFIED IDEOGRAPH
+0xB44C 0x5C0A #CJK UNIFIED IDEOGRAPH
+0xB44D 0x5C0B #CJK UNIFIED IDEOGRAPH
+0xB44E 0x5C31 #CJK UNIFIED IDEOGRAPH
+0xB44F 0x5D4C #CJK UNIFIED IDEOGRAPH
+0xB450 0x5D50 #CJK UNIFIED IDEOGRAPH
+0xB451 0x5D34 #CJK UNIFIED IDEOGRAPH
+0xB452 0x5D47 #CJK UNIFIED IDEOGRAPH
+0xB453 0x5DFD #CJK UNIFIED IDEOGRAPH
+0xB454 0x5E45 #CJK UNIFIED IDEOGRAPH
+0xB455 0x5E3D #CJK UNIFIED IDEOGRAPH
+0xB456 0x5E40 #CJK UNIFIED IDEOGRAPH
+0xB457 0x5E43 #CJK UNIFIED IDEOGRAPH
+0xB458 0x5E7E #CJK UNIFIED IDEOGRAPH
+0xB459 0x5ECA #CJK UNIFIED IDEOGRAPH
+0xB45A 0x5EC1 #CJK UNIFIED IDEOGRAPH
+0xB45B 0x5EC2 #CJK UNIFIED IDEOGRAPH
+0xB45C 0x5EC4 #CJK UNIFIED IDEOGRAPH
+0xB45D 0x5F3C #CJK UNIFIED IDEOGRAPH
+0xB45E 0x5F6D #CJK UNIFIED IDEOGRAPH
+0xB45F 0x5FA9 #CJK UNIFIED IDEOGRAPH
+0xB460 0x5FAA #CJK UNIFIED IDEOGRAPH
+0xB461 0x5FA8 #CJK UNIFIED IDEOGRAPH
+0xB462 0x60D1 #CJK UNIFIED IDEOGRAPH
+0xB463 0x60E1 #CJK UNIFIED IDEOGRAPH
+0xB464 0x60B2 #CJK UNIFIED IDEOGRAPH
+0xB465 0x60B6 #CJK UNIFIED IDEOGRAPH
+0xB466 0x60E0 #CJK UNIFIED IDEOGRAPH
+0xB467 0x611C #CJK UNIFIED IDEOGRAPH
+0xB468 0x6123 #CJK UNIFIED IDEOGRAPH
+0xB469 0x60FA #CJK UNIFIED IDEOGRAPH
+0xB46A 0x6115 #CJK UNIFIED IDEOGRAPH
+0xB46B 0x60F0 #CJK UNIFIED IDEOGRAPH
+0xB46C 0x60FB #CJK UNIFIED IDEOGRAPH
+0xB46D 0x60F4 #CJK UNIFIED IDEOGRAPH
+0xB46E 0x6168 #CJK UNIFIED IDEOGRAPH
+0xB46F 0x60F1 #CJK UNIFIED IDEOGRAPH
+0xB470 0x610E #CJK UNIFIED IDEOGRAPH
+0xB471 0x60F6 #CJK UNIFIED IDEOGRAPH
+0xB472 0x6109 #CJK UNIFIED IDEOGRAPH
+0xB473 0x6100 #CJK UNIFIED IDEOGRAPH
+0xB474 0x6112 #CJK UNIFIED IDEOGRAPH
+0xB475 0x621F #CJK UNIFIED IDEOGRAPH
+0xB476 0x6249 #CJK UNIFIED IDEOGRAPH
+0xB477 0x63A3 #CJK UNIFIED IDEOGRAPH
+0xB478 0x638C #CJK UNIFIED IDEOGRAPH
+0xB479 0x63CF #CJK UNIFIED IDEOGRAPH
+0xB47A 0x63C0 #CJK UNIFIED IDEOGRAPH
+0xB47B 0x63E9 #CJK UNIFIED IDEOGRAPH
+0xB47C 0x63C9 #CJK UNIFIED IDEOGRAPH
+0xB47D 0x63C6 #CJK UNIFIED IDEOGRAPH
+0xB47E 0x63CD #CJK UNIFIED IDEOGRAPH
+0xB4A1 0x63D2 #CJK UNIFIED IDEOGRAPH
+0xB4A2 0x63E3 #CJK UNIFIED IDEOGRAPH
+0xB4A3 0x63D0 #CJK UNIFIED IDEOGRAPH
+0xB4A4 0x63E1 #CJK UNIFIED IDEOGRAPH
+0xB4A5 0x63D6 #CJK UNIFIED IDEOGRAPH
+0xB4A6 0x63ED #CJK UNIFIED IDEOGRAPH
+0xB4A7 0x63EE #CJK UNIFIED IDEOGRAPH
+0xB4A8 0x6376 #CJK UNIFIED IDEOGRAPH
+0xB4A9 0x63F4 #CJK UNIFIED IDEOGRAPH
+0xB4AA 0x63EA #CJK UNIFIED IDEOGRAPH
+0xB4AB 0x63DB #CJK UNIFIED IDEOGRAPH
+0xB4AC 0x6452 #CJK UNIFIED IDEOGRAPH
+0xB4AD 0x63DA #CJK UNIFIED IDEOGRAPH
+0xB4AE 0x63F9 #CJK UNIFIED IDEOGRAPH
+0xB4AF 0x655E #CJK UNIFIED IDEOGRAPH
+0xB4B0 0x6566 #CJK UNIFIED IDEOGRAPH
+0xB4B1 0x6562 #CJK UNIFIED IDEOGRAPH
+0xB4B2 0x6563 #CJK UNIFIED IDEOGRAPH
+0xB4B3 0x6591 #CJK UNIFIED IDEOGRAPH
+0xB4B4 0x6590 #CJK UNIFIED IDEOGRAPH
+0xB4B5 0x65AF #CJK UNIFIED IDEOGRAPH
+0xB4B6 0x666E #CJK UNIFIED IDEOGRAPH
+0xB4B7 0x6670 #CJK UNIFIED IDEOGRAPH
+0xB4B8 0x6674 #CJK UNIFIED IDEOGRAPH
+0xB4B9 0x6676 #CJK UNIFIED IDEOGRAPH
+0xB4BA 0x666F #CJK UNIFIED IDEOGRAPH
+0xB4BB 0x6691 #CJK UNIFIED IDEOGRAPH
+0xB4BC 0x667A #CJK UNIFIED IDEOGRAPH
+0xB4BD 0x667E #CJK UNIFIED IDEOGRAPH
+0xB4BE 0x6677 #CJK UNIFIED IDEOGRAPH
+0xB4BF 0x66FE #CJK UNIFIED IDEOGRAPH
+0xB4C0 0x66FF #CJK UNIFIED IDEOGRAPH
+0xB4C1 0x671F #CJK UNIFIED IDEOGRAPH
+0xB4C2 0x671D #CJK UNIFIED IDEOGRAPH
+0xB4C3 0x68FA #CJK UNIFIED IDEOGRAPH
+0xB4C4 0x68D5 #CJK UNIFIED IDEOGRAPH
+0xB4C5 0x68E0 #CJK UNIFIED IDEOGRAPH
+0xB4C6 0x68D8 #CJK UNIFIED IDEOGRAPH
+0xB4C7 0x68D7 #CJK UNIFIED IDEOGRAPH
+0xB4C8 0x6905 #CJK UNIFIED IDEOGRAPH
+0xB4C9 0x68DF #CJK UNIFIED IDEOGRAPH
+0xB4CA 0x68F5 #CJK UNIFIED IDEOGRAPH
+0xB4CB 0x68EE #CJK UNIFIED IDEOGRAPH
+0xB4CC 0x68E7 #CJK UNIFIED IDEOGRAPH
+0xB4CD 0x68F9 #CJK UNIFIED IDEOGRAPH
+0xB4CE 0x68D2 #CJK UNIFIED IDEOGRAPH
+0xB4CF 0x68F2 #CJK UNIFIED IDEOGRAPH
+0xB4D0 0x68E3 #CJK UNIFIED IDEOGRAPH
+0xB4D1 0x68CB #CJK UNIFIED IDEOGRAPH
+0xB4D2 0x68CD #CJK UNIFIED IDEOGRAPH
+0xB4D3 0x690D #CJK UNIFIED IDEOGRAPH
+0xB4D4 0x6912 #CJK UNIFIED IDEOGRAPH
+0xB4D5 0x690E #CJK UNIFIED IDEOGRAPH
+0xB4D6 0x68C9 #CJK UNIFIED IDEOGRAPH
+0xB4D7 0x68DA #CJK UNIFIED IDEOGRAPH
+0xB4D8 0x696E #CJK UNIFIED IDEOGRAPH
+0xB4D9 0x68FB #CJK UNIFIED IDEOGRAPH
+0xB4DA 0x6B3E #CJK UNIFIED IDEOGRAPH
+0xB4DB 0x6B3A #CJK UNIFIED IDEOGRAPH
+0xB4DC 0x6B3D #CJK UNIFIED IDEOGRAPH
+0xB4DD 0x6B98 #CJK UNIFIED IDEOGRAPH
+0xB4DE 0x6B96 #CJK UNIFIED IDEOGRAPH
+0xB4DF 0x6BBC #CJK UNIFIED IDEOGRAPH
+0xB4E0 0x6BEF #CJK UNIFIED IDEOGRAPH
+0xB4E1 0x6C2E #CJK UNIFIED IDEOGRAPH
+0xB4E2 0x6C2F #CJK UNIFIED IDEOGRAPH
+0xB4E3 0x6C2C #CJK UNIFIED IDEOGRAPH
+0xB4E4 0x6E2F #CJK UNIFIED IDEOGRAPH
+0xB4E5 0x6E38 #CJK UNIFIED IDEOGRAPH
+0xB4E6 0x6E54 #CJK UNIFIED IDEOGRAPH
+0xB4E7 0x6E21 #CJK UNIFIED IDEOGRAPH
+0xB4E8 0x6E32 #CJK UNIFIED IDEOGRAPH
+0xB4E9 0x6E67 #CJK UNIFIED IDEOGRAPH
+0xB4EA 0x6E4A #CJK UNIFIED IDEOGRAPH
+0xB4EB 0x6E20 #CJK UNIFIED IDEOGRAPH
+0xB4EC 0x6E25 #CJK UNIFIED IDEOGRAPH
+0xB4ED 0x6E23 #CJK UNIFIED IDEOGRAPH
+0xB4EE 0x6E1B #CJK UNIFIED IDEOGRAPH
+0xB4EF 0x6E5B #CJK UNIFIED IDEOGRAPH
+0xB4F0 0x6E58 #CJK UNIFIED IDEOGRAPH
+0xB4F1 0x6E24 #CJK UNIFIED IDEOGRAPH
+0xB4F2 0x6E56 #CJK UNIFIED IDEOGRAPH
+0xB4F3 0x6E6E #CJK UNIFIED IDEOGRAPH
+0xB4F4 0x6E2D #CJK UNIFIED IDEOGRAPH
+0xB4F5 0x6E26 #CJK UNIFIED IDEOGRAPH
+0xB4F6 0x6E6F #CJK UNIFIED IDEOGRAPH
+0xB4F7 0x6E34 #CJK UNIFIED IDEOGRAPH
+0xB4F8 0x6E4D #CJK UNIFIED IDEOGRAPH
+0xB4F9 0x6E3A #CJK UNIFIED IDEOGRAPH
+0xB4FA 0x6E2C #CJK UNIFIED IDEOGRAPH
+0xB4FB 0x6E43 #CJK UNIFIED IDEOGRAPH
+0xB4FC 0x6E1D #CJK UNIFIED IDEOGRAPH
+0xB4FD 0x6E3E #CJK UNIFIED IDEOGRAPH
+0xB4FE 0x6ECB #CJK UNIFIED IDEOGRAPH
+0xB540 0x6E89 #CJK UNIFIED IDEOGRAPH
+0xB541 0x6E19 #CJK UNIFIED IDEOGRAPH
+0xB542 0x6E4E #CJK UNIFIED IDEOGRAPH
+0xB543 0x6E63 #CJK UNIFIED IDEOGRAPH
+0xB544 0x6E44 #CJK UNIFIED IDEOGRAPH
+0xB545 0x6E72 #CJK UNIFIED IDEOGRAPH
+0xB546 0x6E69 #CJK UNIFIED IDEOGRAPH
+0xB547 0x6E5F #CJK UNIFIED IDEOGRAPH
+0xB548 0x7119 #CJK UNIFIED IDEOGRAPH
+0xB549 0x711A #CJK UNIFIED IDEOGRAPH
+0xB54A 0x7126 #CJK UNIFIED IDEOGRAPH
+0xB54B 0x7130 #CJK UNIFIED IDEOGRAPH
+0xB54C 0x7121 #CJK UNIFIED IDEOGRAPH
+0xB54D 0x7136 #CJK UNIFIED IDEOGRAPH
+0xB54E 0x716E #CJK UNIFIED IDEOGRAPH
+0xB54F 0x711C #CJK UNIFIED IDEOGRAPH
+0xB550 0x724C #CJK UNIFIED IDEOGRAPH
+0xB551 0x7284 #CJK UNIFIED IDEOGRAPH
+0xB552 0x7280 #CJK UNIFIED IDEOGRAPH
+0xB553 0x7336 #CJK UNIFIED IDEOGRAPH
+0xB554 0x7325 #CJK UNIFIED IDEOGRAPH
+0xB555 0x7334 #CJK UNIFIED IDEOGRAPH
+0xB556 0x7329 #CJK UNIFIED IDEOGRAPH
+0xB557 0x743A #CJK UNIFIED IDEOGRAPH
+0xB558 0x742A #CJK UNIFIED IDEOGRAPH
+0xB559 0x7433 #CJK UNIFIED IDEOGRAPH
+0xB55A 0x7422 #CJK UNIFIED IDEOGRAPH
+0xB55B 0x7425 #CJK UNIFIED IDEOGRAPH
+0xB55C 0x7435 #CJK UNIFIED IDEOGRAPH
+0xB55D 0x7436 #CJK UNIFIED IDEOGRAPH
+0xB55E 0x7434 #CJK UNIFIED IDEOGRAPH
+0xB55F 0x742F #CJK UNIFIED IDEOGRAPH
+0xB560 0x741B #CJK UNIFIED IDEOGRAPH
+0xB561 0x7426 #CJK UNIFIED IDEOGRAPH
+0xB562 0x7428 #CJK UNIFIED IDEOGRAPH
+0xB563 0x7525 #CJK UNIFIED IDEOGRAPH
+0xB564 0x7526 #CJK UNIFIED IDEOGRAPH
+0xB565 0x756B #CJK UNIFIED IDEOGRAPH
+0xB566 0x756A #CJK UNIFIED IDEOGRAPH
+0xB567 0x75E2 #CJK UNIFIED IDEOGRAPH
+0xB568 0x75DB #CJK UNIFIED IDEOGRAPH
+0xB569 0x75E3 #CJK UNIFIED IDEOGRAPH
+0xB56A 0x75D9 #CJK UNIFIED IDEOGRAPH
+0xB56B 0x75D8 #CJK UNIFIED IDEOGRAPH
+0xB56C 0x75DE #CJK UNIFIED IDEOGRAPH
+0xB56D 0x75E0 #CJK UNIFIED IDEOGRAPH
+0xB56E 0x767B #CJK UNIFIED IDEOGRAPH
+0xB56F 0x767C #CJK UNIFIED IDEOGRAPH
+0xB570 0x7696 #CJK UNIFIED IDEOGRAPH
+0xB571 0x7693 #CJK UNIFIED IDEOGRAPH
+0xB572 0x76B4 #CJK UNIFIED IDEOGRAPH
+0xB573 0x76DC #CJK UNIFIED IDEOGRAPH
+0xB574 0x774F #CJK UNIFIED IDEOGRAPH
+0xB575 0x77ED #CJK UNIFIED IDEOGRAPH
+0xB576 0x785D #CJK UNIFIED IDEOGRAPH
+0xB577 0x786C #CJK UNIFIED IDEOGRAPH
+0xB578 0x786F #CJK UNIFIED IDEOGRAPH
+0xB579 0x7A0D #CJK UNIFIED IDEOGRAPH
+0xB57A 0x7A08 #CJK UNIFIED IDEOGRAPH
+0xB57B 0x7A0B #CJK UNIFIED IDEOGRAPH
+0xB57C 0x7A05 #CJK UNIFIED IDEOGRAPH
+0xB57D 0x7A00 #CJK UNIFIED IDEOGRAPH
+0xB57E 0x7A98 #CJK UNIFIED IDEOGRAPH
+0xB5A1 0x7A97 #CJK UNIFIED IDEOGRAPH
+0xB5A2 0x7A96 #CJK UNIFIED IDEOGRAPH
+0xB5A3 0x7AE5 #CJK UNIFIED IDEOGRAPH
+0xB5A4 0x7AE3 #CJK UNIFIED IDEOGRAPH
+0xB5A5 0x7B49 #CJK UNIFIED IDEOGRAPH
+0xB5A6 0x7B56 #CJK UNIFIED IDEOGRAPH
+0xB5A7 0x7B46 #CJK UNIFIED IDEOGRAPH
+0xB5A8 0x7B50 #CJK UNIFIED IDEOGRAPH
+0xB5A9 0x7B52 #CJK UNIFIED IDEOGRAPH
+0xB5AA 0x7B54 #CJK UNIFIED IDEOGRAPH
+0xB5AB 0x7B4D #CJK UNIFIED IDEOGRAPH
+0xB5AC 0x7B4B #CJK UNIFIED IDEOGRAPH
+0xB5AD 0x7B4F #CJK UNIFIED IDEOGRAPH
+0xB5AE 0x7B51 #CJK UNIFIED IDEOGRAPH
+0xB5AF 0x7C9F #CJK UNIFIED IDEOGRAPH
+0xB5B0 0x7CA5 #CJK UNIFIED IDEOGRAPH
+0xB5B1 0x7D5E #CJK UNIFIED IDEOGRAPH
+0xB5B2 0x7D50 #CJK UNIFIED IDEOGRAPH
+0xB5B3 0x7D68 #CJK UNIFIED IDEOGRAPH
+0xB5B4 0x7D55 #CJK UNIFIED IDEOGRAPH
+0xB5B5 0x7D2B #CJK UNIFIED IDEOGRAPH
+0xB5B6 0x7D6E #CJK UNIFIED IDEOGRAPH
+0xB5B7 0x7D72 #CJK UNIFIED IDEOGRAPH
+0xB5B8 0x7D61 #CJK UNIFIED IDEOGRAPH
+0xB5B9 0x7D66 #CJK UNIFIED IDEOGRAPH
+0xB5BA 0x7D62 #CJK UNIFIED IDEOGRAPH
+0xB5BB 0x7D70 #CJK UNIFIED IDEOGRAPH
+0xB5BC 0x7D73 #CJK UNIFIED IDEOGRAPH
+0xB5BD 0x5584 #CJK UNIFIED IDEOGRAPH
+0xB5BE 0x7FD4 #CJK UNIFIED IDEOGRAPH
+0xB5BF 0x7FD5 #CJK UNIFIED IDEOGRAPH
+0xB5C0 0x800B #CJK UNIFIED IDEOGRAPH
+0xB5C1 0x8052 #CJK UNIFIED IDEOGRAPH
+0xB5C2 0x8085 #CJK UNIFIED IDEOGRAPH
+0xB5C3 0x8155 #CJK UNIFIED IDEOGRAPH
+0xB5C4 0x8154 #CJK UNIFIED IDEOGRAPH
+0xB5C5 0x814B #CJK UNIFIED IDEOGRAPH
+0xB5C6 0x8151 #CJK UNIFIED IDEOGRAPH
+0xB5C7 0x814E #CJK UNIFIED IDEOGRAPH
+0xB5C8 0x8139 #CJK UNIFIED IDEOGRAPH
+0xB5C9 0x8146 #CJK UNIFIED IDEOGRAPH
+0xB5CA 0x813E #CJK UNIFIED IDEOGRAPH
+0xB5CB 0x814C #CJK UNIFIED IDEOGRAPH
+0xB5CC 0x8153 #CJK UNIFIED IDEOGRAPH
+0xB5CD 0x8174 #CJK UNIFIED IDEOGRAPH
+0xB5CE 0x8212 #CJK UNIFIED IDEOGRAPH
+0xB5CF 0x821C #CJK UNIFIED IDEOGRAPH
+0xB5D0 0x83E9 #CJK UNIFIED IDEOGRAPH
+0xB5D1 0x8403 #CJK UNIFIED IDEOGRAPH
+0xB5D2 0x83F8 #CJK UNIFIED IDEOGRAPH
+0xB5D3 0x840D #CJK UNIFIED IDEOGRAPH
+0xB5D4 0x83E0 #CJK UNIFIED IDEOGRAPH
+0xB5D5 0x83C5 #CJK UNIFIED IDEOGRAPH
+0xB5D6 0x840B #CJK UNIFIED IDEOGRAPH
+0xB5D7 0x83C1 #CJK UNIFIED IDEOGRAPH
+0xB5D8 0x83EF #CJK UNIFIED IDEOGRAPH
+0xB5D9 0x83F1 #CJK UNIFIED IDEOGRAPH
+0xB5DA 0x83F4 #CJK UNIFIED IDEOGRAPH
+0xB5DB 0x8457 #CJK UNIFIED IDEOGRAPH
+0xB5DC 0x840A #CJK UNIFIED IDEOGRAPH
+0xB5DD 0x83F0 #CJK UNIFIED IDEOGRAPH
+0xB5DE 0x840C #CJK UNIFIED IDEOGRAPH
+0xB5DF 0x83CC #CJK UNIFIED IDEOGRAPH
+0xB5E0 0x83FD #CJK UNIFIED IDEOGRAPH
+0xB5E1 0x83F2 #CJK UNIFIED IDEOGRAPH
+0xB5E2 0x83CA #CJK UNIFIED IDEOGRAPH
+0xB5E3 0x8438 #CJK UNIFIED IDEOGRAPH
+0xB5E4 0x840E #CJK UNIFIED IDEOGRAPH
+0xB5E5 0x8404 #CJK UNIFIED IDEOGRAPH
+0xB5E6 0x83DC #CJK UNIFIED IDEOGRAPH
+0xB5E7 0x8407 #CJK UNIFIED IDEOGRAPH
+0xB5E8 0x83D4 #CJK UNIFIED IDEOGRAPH
+0xB5E9 0x83DF #CJK UNIFIED IDEOGRAPH
+0xB5EA 0x865B #CJK UNIFIED IDEOGRAPH
+0xB5EB 0x86DF #CJK UNIFIED IDEOGRAPH
+0xB5EC 0x86D9 #CJK UNIFIED IDEOGRAPH
+0xB5ED 0x86ED #CJK UNIFIED IDEOGRAPH
+0xB5EE 0x86D4 #CJK UNIFIED IDEOGRAPH
+0xB5EF 0x86DB #CJK UNIFIED IDEOGRAPH
+0xB5F0 0x86E4 #CJK UNIFIED IDEOGRAPH
+0xB5F1 0x86D0 #CJK UNIFIED IDEOGRAPH
+0xB5F2 0x86DE #CJK UNIFIED IDEOGRAPH
+0xB5F3 0x8857 #CJK UNIFIED IDEOGRAPH
+0xB5F4 0x88C1 #CJK UNIFIED IDEOGRAPH
+0xB5F5 0x88C2 #CJK UNIFIED IDEOGRAPH
+0xB5F6 0x88B1 #CJK UNIFIED IDEOGRAPH
+0xB5F7 0x8983 #CJK UNIFIED IDEOGRAPH
+0xB5F8 0x8996 #CJK UNIFIED IDEOGRAPH
+0xB5F9 0x8A3B #CJK UNIFIED IDEOGRAPH
+0xB5FA 0x8A60 #CJK UNIFIED IDEOGRAPH
+0xB5FB 0x8A55 #CJK UNIFIED IDEOGRAPH
+0xB5FC 0x8A5E #CJK UNIFIED IDEOGRAPH
+0xB5FD 0x8A3C #CJK UNIFIED IDEOGRAPH
+0xB5FE 0x8A41 #CJK UNIFIED IDEOGRAPH
+0xB640 0x8A54 #CJK UNIFIED IDEOGRAPH
+0xB641 0x8A5B #CJK UNIFIED IDEOGRAPH
+0xB642 0x8A50 #CJK UNIFIED IDEOGRAPH
+0xB643 0x8A46 #CJK UNIFIED IDEOGRAPH
+0xB644 0x8A34 #CJK UNIFIED IDEOGRAPH
+0xB645 0x8A3A #CJK UNIFIED IDEOGRAPH
+0xB646 0x8A36 #CJK UNIFIED IDEOGRAPH
+0xB647 0x8A56 #CJK UNIFIED IDEOGRAPH
+0xB648 0x8C61 #CJK UNIFIED IDEOGRAPH
+0xB649 0x8C82 #CJK UNIFIED IDEOGRAPH
+0xB64A 0x8CAF #CJK UNIFIED IDEOGRAPH
+0xB64B 0x8CBC #CJK UNIFIED IDEOGRAPH
+0xB64C 0x8CB3 #CJK UNIFIED IDEOGRAPH
+0xB64D 0x8CBD #CJK UNIFIED IDEOGRAPH
+0xB64E 0x8CC1 #CJK UNIFIED IDEOGRAPH
+0xB64F 0x8CBB #CJK UNIFIED IDEOGRAPH
+0xB650 0x8CC0 #CJK UNIFIED IDEOGRAPH
+0xB651 0x8CB4 #CJK UNIFIED IDEOGRAPH
+0xB652 0x8CB7 #CJK UNIFIED IDEOGRAPH
+0xB653 0x8CB6 #CJK UNIFIED IDEOGRAPH
+0xB654 0x8CBF #CJK UNIFIED IDEOGRAPH
+0xB655 0x8CB8 #CJK UNIFIED IDEOGRAPH
+0xB656 0x8D8A #CJK UNIFIED IDEOGRAPH
+0xB657 0x8D85 #CJK UNIFIED IDEOGRAPH
+0xB658 0x8D81 #CJK UNIFIED IDEOGRAPH
+0xB659 0x8DCE #CJK UNIFIED IDEOGRAPH
+0xB65A 0x8DDD #CJK UNIFIED IDEOGRAPH
+0xB65B 0x8DCB #CJK UNIFIED IDEOGRAPH
+0xB65C 0x8DDA #CJK UNIFIED IDEOGRAPH
+0xB65D 0x8DD1 #CJK UNIFIED IDEOGRAPH
+0xB65E 0x8DCC #CJK UNIFIED IDEOGRAPH
+0xB65F 0x8DDB #CJK UNIFIED IDEOGRAPH
+0xB660 0x8DC6 #CJK UNIFIED IDEOGRAPH
+0xB661 0x8EFB #CJK UNIFIED IDEOGRAPH
+0xB662 0x8EF8 #CJK UNIFIED IDEOGRAPH
+0xB663 0x8EFC #CJK UNIFIED IDEOGRAPH
+0xB664 0x8F9C #CJK UNIFIED IDEOGRAPH
+0xB665 0x902E #CJK UNIFIED IDEOGRAPH
+0xB666 0x9035 #CJK UNIFIED IDEOGRAPH
+0xB667 0x9031 #CJK UNIFIED IDEOGRAPH
+0xB668 0x9038 #CJK UNIFIED IDEOGRAPH
+0xB669 0x9032 #CJK UNIFIED IDEOGRAPH
+0xB66A 0x9036 #CJK UNIFIED IDEOGRAPH
+0xB66B 0x9102 #CJK UNIFIED IDEOGRAPH
+0xB66C 0x90F5 #CJK UNIFIED IDEOGRAPH
+0xB66D 0x9109 #CJK UNIFIED IDEOGRAPH
+0xB66E 0x90FE #CJK UNIFIED IDEOGRAPH
+0xB66F 0x9163 #CJK UNIFIED IDEOGRAPH
+0xB670 0x9165 #CJK UNIFIED IDEOGRAPH
+0xB671 0x91CF #CJK UNIFIED IDEOGRAPH
+0xB672 0x9214 #CJK UNIFIED IDEOGRAPH
+0xB673 0x9215 #CJK UNIFIED IDEOGRAPH
+0xB674 0x9223 #CJK UNIFIED IDEOGRAPH
+0xB675 0x9209 #CJK UNIFIED IDEOGRAPH
+0xB676 0x921E #CJK UNIFIED IDEOGRAPH
+0xB677 0x920D #CJK UNIFIED IDEOGRAPH
+0xB678 0x9210 #CJK UNIFIED IDEOGRAPH
+0xB679 0x9207 #CJK UNIFIED IDEOGRAPH
+0xB67A 0x9211 #CJK UNIFIED IDEOGRAPH
+0xB67B 0x9594 #CJK UNIFIED IDEOGRAPH
+0xB67C 0x958F #CJK UNIFIED IDEOGRAPH
+0xB67D 0x958B #CJK UNIFIED IDEOGRAPH
+0xB67E 0x9591 #CJK UNIFIED IDEOGRAPH
+0xB6A1 0x9593 #CJK UNIFIED IDEOGRAPH
+0xB6A2 0x9592 #CJK UNIFIED IDEOGRAPH
+0xB6A3 0x958E #CJK UNIFIED IDEOGRAPH
+0xB6A4 0x968A #CJK UNIFIED IDEOGRAPH
+0xB6A5 0x968E #CJK UNIFIED IDEOGRAPH
+0xB6A6 0x968B #CJK UNIFIED IDEOGRAPH
+0xB6A7 0x967D #CJK UNIFIED IDEOGRAPH
+0xB6A8 0x9685 #CJK UNIFIED IDEOGRAPH
+0xB6A9 0x9686 #CJK UNIFIED IDEOGRAPH
+0xB6AA 0x968D #CJK UNIFIED IDEOGRAPH
+0xB6AB 0x9672 #CJK UNIFIED IDEOGRAPH
+0xB6AC 0x9684 #CJK UNIFIED IDEOGRAPH
+0xB6AD 0x96C1 #CJK UNIFIED IDEOGRAPH
+0xB6AE 0x96C5 #CJK UNIFIED IDEOGRAPH
+0xB6AF 0x96C4 #CJK UNIFIED IDEOGRAPH
+0xB6B0 0x96C6 #CJK UNIFIED IDEOGRAPH
+0xB6B1 0x96C7 #CJK UNIFIED IDEOGRAPH
+0xB6B2 0x96EF #CJK UNIFIED IDEOGRAPH
+0xB6B3 0x96F2 #CJK UNIFIED IDEOGRAPH
+0xB6B4 0x97CC #CJK UNIFIED IDEOGRAPH
+0xB6B5 0x9805 #CJK UNIFIED IDEOGRAPH
+0xB6B6 0x9806 #CJK UNIFIED IDEOGRAPH
+0xB6B7 0x9808 #CJK UNIFIED IDEOGRAPH
+0xB6B8 0x98E7 #CJK UNIFIED IDEOGRAPH
+0xB6B9 0x98EA #CJK UNIFIED IDEOGRAPH
+0xB6BA 0x98EF #CJK UNIFIED IDEOGRAPH
+0xB6BB 0x98E9 #CJK UNIFIED IDEOGRAPH
+0xB6BC 0x98F2 #CJK UNIFIED IDEOGRAPH
+0xB6BD 0x98ED #CJK UNIFIED IDEOGRAPH
+0xB6BE 0x99AE #CJK UNIFIED IDEOGRAPH
+0xB6BF 0x99AD #CJK UNIFIED IDEOGRAPH
+0xB6C0 0x9EC3 #CJK UNIFIED IDEOGRAPH
+0xB6C1 0x9ECD #CJK UNIFIED IDEOGRAPH
+0xB6C2 0x9ED1 #CJK UNIFIED IDEOGRAPH
+0xB6C3 0x4E82 #CJK UNIFIED IDEOGRAPH
+0xB6C4 0x50AD #CJK UNIFIED IDEOGRAPH
+0xB6C5 0x50B5 #CJK UNIFIED IDEOGRAPH
+0xB6C6 0x50B2 #CJK UNIFIED IDEOGRAPH
+0xB6C7 0x50B3 #CJK UNIFIED IDEOGRAPH
+0xB6C8 0x50C5 #CJK UNIFIED IDEOGRAPH
+0xB6C9 0x50BE #CJK UNIFIED IDEOGRAPH
+0xB6CA 0x50AC #CJK UNIFIED IDEOGRAPH
+0xB6CB 0x50B7 #CJK UNIFIED IDEOGRAPH
+0xB6CC 0x50BB #CJK UNIFIED IDEOGRAPH
+0xB6CD 0x50AF #CJK UNIFIED IDEOGRAPH
+0xB6CE 0x50C7 #CJK UNIFIED IDEOGRAPH
+0xB6CF 0x527F #CJK UNIFIED IDEOGRAPH
+0xB6D0 0x5277 #CJK UNIFIED IDEOGRAPH
+0xB6D1 0x527D #CJK UNIFIED IDEOGRAPH
+0xB6D2 0x52DF #CJK UNIFIED IDEOGRAPH
+0xB6D3 0x52E6 #CJK UNIFIED IDEOGRAPH
+0xB6D4 0x52E4 #CJK UNIFIED IDEOGRAPH
+0xB6D5 0x52E2 #CJK UNIFIED IDEOGRAPH
+0xB6D6 0x52E3 #CJK UNIFIED IDEOGRAPH
+0xB6D7 0x532F #CJK UNIFIED IDEOGRAPH
+0xB6D8 0x55DF #CJK UNIFIED IDEOGRAPH
+0xB6D9 0x55E8 #CJK UNIFIED IDEOGRAPH
+0xB6DA 0x55D3 #CJK UNIFIED IDEOGRAPH
+0xB6DB 0x55E6 #CJK UNIFIED IDEOGRAPH
+0xB6DC 0x55CE #CJK UNIFIED IDEOGRAPH
+0xB6DD 0x55DC #CJK UNIFIED IDEOGRAPH
+0xB6DE 0x55C7 #CJK UNIFIED IDEOGRAPH
+0xB6DF 0x55D1 #CJK UNIFIED IDEOGRAPH
+0xB6E0 0x55E3 #CJK UNIFIED IDEOGRAPH
+0xB6E1 0x55E4 #CJK UNIFIED IDEOGRAPH
+0xB6E2 0x55EF #CJK UNIFIED IDEOGRAPH
+0xB6E3 0x55DA #CJK UNIFIED IDEOGRAPH
+0xB6E4 0x55E1 #CJK UNIFIED IDEOGRAPH
+0xB6E5 0x55C5 #CJK UNIFIED IDEOGRAPH
+0xB6E6 0x55C6 #CJK UNIFIED IDEOGRAPH
+0xB6E7 0x55E5 #CJK UNIFIED IDEOGRAPH
+0xB6E8 0x55C9 #CJK UNIFIED IDEOGRAPH
+0xB6E9 0x5712 #CJK UNIFIED IDEOGRAPH
+0xB6EA 0x5713 #CJK UNIFIED IDEOGRAPH
+0xB6EB 0x585E #CJK UNIFIED IDEOGRAPH
+0xB6EC 0x5851 #CJK UNIFIED IDEOGRAPH
+0xB6ED 0x5858 #CJK UNIFIED IDEOGRAPH
+0xB6EE 0x5857 #CJK UNIFIED IDEOGRAPH
+0xB6EF 0x585A #CJK UNIFIED IDEOGRAPH
+0xB6F0 0x5854 #CJK UNIFIED IDEOGRAPH
+0xB6F1 0x586B #CJK UNIFIED IDEOGRAPH
+0xB6F2 0x584C #CJK UNIFIED IDEOGRAPH
+0xB6F3 0x586D #CJK UNIFIED IDEOGRAPH
+0xB6F4 0x584A #CJK UNIFIED IDEOGRAPH
+0xB6F5 0x5862 #CJK UNIFIED IDEOGRAPH
+0xB6F6 0x5852 #CJK UNIFIED IDEOGRAPH
+0xB6F7 0x584B #CJK UNIFIED IDEOGRAPH
+0xB6F8 0x5967 #CJK UNIFIED IDEOGRAPH
+0xB6F9 0x5AC1 #CJK UNIFIED IDEOGRAPH
+0xB6FA 0x5AC9 #CJK UNIFIED IDEOGRAPH
+0xB6FB 0x5ACC #CJK UNIFIED IDEOGRAPH
+0xB6FC 0x5ABE #CJK UNIFIED IDEOGRAPH
+0xB6FD 0x5ABD #CJK UNIFIED IDEOGRAPH
+0xB6FE 0x5ABC #CJK UNIFIED IDEOGRAPH
+0xB740 0x5AB3 #CJK UNIFIED IDEOGRAPH
+0xB741 0x5AC2 #CJK UNIFIED IDEOGRAPH
+0xB742 0x5AB2 #CJK UNIFIED IDEOGRAPH
+0xB743 0x5D69 #CJK UNIFIED IDEOGRAPH
+0xB744 0x5D6F #CJK UNIFIED IDEOGRAPH
+0xB745 0x5E4C #CJK UNIFIED IDEOGRAPH
+0xB746 0x5E79 #CJK UNIFIED IDEOGRAPH
+0xB747 0x5EC9 #CJK UNIFIED IDEOGRAPH
+0xB748 0x5EC8 #CJK UNIFIED IDEOGRAPH
+0xB749 0x5F12 #CJK UNIFIED IDEOGRAPH
+0xB74A 0x5F59 #CJK UNIFIED IDEOGRAPH
+0xB74B 0x5FAC #CJK UNIFIED IDEOGRAPH
+0xB74C 0x5FAE #CJK UNIFIED IDEOGRAPH
+0xB74D 0x611A #CJK UNIFIED IDEOGRAPH
+0xB74E 0x610F #CJK UNIFIED IDEOGRAPH
+0xB74F 0x6148 #CJK UNIFIED IDEOGRAPH
+0xB750 0x611F #CJK UNIFIED IDEOGRAPH
+0xB751 0x60F3 #CJK UNIFIED IDEOGRAPH
+0xB752 0x611B #CJK UNIFIED IDEOGRAPH
+0xB753 0x60F9 #CJK UNIFIED IDEOGRAPH
+0xB754 0x6101 #CJK UNIFIED IDEOGRAPH
+0xB755 0x6108 #CJK UNIFIED IDEOGRAPH
+0xB756 0x614E #CJK UNIFIED IDEOGRAPH
+0xB757 0x614C #CJK UNIFIED IDEOGRAPH
+0xB758 0x6144 #CJK UNIFIED IDEOGRAPH
+0xB759 0x614D #CJK UNIFIED IDEOGRAPH
+0xB75A 0x613E #CJK UNIFIED IDEOGRAPH
+0xB75B 0x6134 #CJK UNIFIED IDEOGRAPH
+0xB75C 0x6127 #CJK UNIFIED IDEOGRAPH
+0xB75D 0x610D #CJK UNIFIED IDEOGRAPH
+0xB75E 0x6106 #CJK UNIFIED IDEOGRAPH
+0xB75F 0x6137 #CJK UNIFIED IDEOGRAPH
+0xB760 0x6221 #CJK UNIFIED IDEOGRAPH
+0xB761 0x6222 #CJK UNIFIED IDEOGRAPH
+0xB762 0x6413 #CJK UNIFIED IDEOGRAPH
+0xB763 0x643E #CJK UNIFIED IDEOGRAPH
+0xB764 0x641E #CJK UNIFIED IDEOGRAPH
+0xB765 0x642A #CJK UNIFIED IDEOGRAPH
+0xB766 0x642D #CJK UNIFIED IDEOGRAPH
+0xB767 0x643D #CJK UNIFIED IDEOGRAPH
+0xB768 0x642C #CJK UNIFIED IDEOGRAPH
+0xB769 0x640F #CJK UNIFIED IDEOGRAPH
+0xB76A 0x641C #CJK UNIFIED IDEOGRAPH
+0xB76B 0x6414 #CJK UNIFIED IDEOGRAPH
+0xB76C 0x640D #CJK UNIFIED IDEOGRAPH
+0xB76D 0x6436 #CJK UNIFIED IDEOGRAPH
+0xB76E 0x6416 #CJK UNIFIED IDEOGRAPH
+0xB76F 0x6417 #CJK UNIFIED IDEOGRAPH
+0xB770 0x6406 #CJK UNIFIED IDEOGRAPH
+0xB771 0x656C #CJK UNIFIED IDEOGRAPH
+0xB772 0x659F #CJK UNIFIED IDEOGRAPH
+0xB773 0x65B0 #CJK UNIFIED IDEOGRAPH
+0xB774 0x6697 #CJK UNIFIED IDEOGRAPH
+0xB775 0x6689 #CJK UNIFIED IDEOGRAPH
+0xB776 0x6687 #CJK UNIFIED IDEOGRAPH
+0xB777 0x6688 #CJK UNIFIED IDEOGRAPH
+0xB778 0x6696 #CJK UNIFIED IDEOGRAPH
+0xB779 0x6684 #CJK UNIFIED IDEOGRAPH
+0xB77A 0x6698 #CJK UNIFIED IDEOGRAPH
+0xB77B 0x668D #CJK UNIFIED IDEOGRAPH
+0xB77C 0x6703 #CJK UNIFIED IDEOGRAPH
+0xB77D 0x6994 #CJK UNIFIED IDEOGRAPH
+0xB77E 0x696D #CJK UNIFIED IDEOGRAPH
+0xB7A1 0x695A #CJK UNIFIED IDEOGRAPH
+0xB7A2 0x6977 #CJK UNIFIED IDEOGRAPH
+0xB7A3 0x6960 #CJK UNIFIED IDEOGRAPH
+0xB7A4 0x6954 #CJK UNIFIED IDEOGRAPH
+0xB7A5 0x6975 #CJK UNIFIED IDEOGRAPH
+0xB7A6 0x6930 #CJK UNIFIED IDEOGRAPH
+0xB7A7 0x6982 #CJK UNIFIED IDEOGRAPH
+0xB7A8 0x694A #CJK UNIFIED IDEOGRAPH
+0xB7A9 0x6968 #CJK UNIFIED IDEOGRAPH
+0xB7AA 0x696B #CJK UNIFIED IDEOGRAPH
+0xB7AB 0x695E #CJK UNIFIED IDEOGRAPH
+0xB7AC 0x6953 #CJK UNIFIED IDEOGRAPH
+0xB7AD 0x6979 #CJK UNIFIED IDEOGRAPH
+0xB7AE 0x6986 #CJK UNIFIED IDEOGRAPH
+0xB7AF 0x695D #CJK UNIFIED IDEOGRAPH
+0xB7B0 0x6963 #CJK UNIFIED IDEOGRAPH
+0xB7B1 0x695B #CJK UNIFIED IDEOGRAPH
+0xB7B2 0x6B47 #CJK UNIFIED IDEOGRAPH
+0xB7B3 0x6B72 #CJK UNIFIED IDEOGRAPH
+0xB7B4 0x6BC0 #CJK UNIFIED IDEOGRAPH
+0xB7B5 0x6BBF #CJK UNIFIED IDEOGRAPH
+0xB7B6 0x6BD3 #CJK UNIFIED IDEOGRAPH
+0xB7B7 0x6BFD #CJK UNIFIED IDEOGRAPH
+0xB7B8 0x6EA2 #CJK UNIFIED IDEOGRAPH
+0xB7B9 0x6EAF #CJK UNIFIED IDEOGRAPH
+0xB7BA 0x6ED3 #CJK UNIFIED IDEOGRAPH
+0xB7BB 0x6EB6 #CJK UNIFIED IDEOGRAPH
+0xB7BC 0x6EC2 #CJK UNIFIED IDEOGRAPH
+0xB7BD 0x6E90 #CJK UNIFIED IDEOGRAPH
+0xB7BE 0x6E9D #CJK UNIFIED IDEOGRAPH
+0xB7BF 0x6EC7 #CJK UNIFIED IDEOGRAPH
+0xB7C0 0x6EC5 #CJK UNIFIED IDEOGRAPH
+0xB7C1 0x6EA5 #CJK UNIFIED IDEOGRAPH
+0xB7C2 0x6E98 #CJK UNIFIED IDEOGRAPH
+0xB7C3 0x6EBC #CJK UNIFIED IDEOGRAPH
+0xB7C4 0x6EBA #CJK UNIFIED IDEOGRAPH
+0xB7C5 0x6EAB #CJK UNIFIED IDEOGRAPH
+0xB7C6 0x6ED1 #CJK UNIFIED IDEOGRAPH
+0xB7C7 0x6E96 #CJK UNIFIED IDEOGRAPH
+0xB7C8 0x6E9C #CJK UNIFIED IDEOGRAPH
+0xB7C9 0x6EC4 #CJK UNIFIED IDEOGRAPH
+0xB7CA 0x6ED4 #CJK UNIFIED IDEOGRAPH
+0xB7CB 0x6EAA #CJK UNIFIED IDEOGRAPH
+0xB7CC 0x6EA7 #CJK UNIFIED IDEOGRAPH
+0xB7CD 0x6EB4 #CJK UNIFIED IDEOGRAPH
+0xB7CE 0x714E #CJK UNIFIED IDEOGRAPH
+0xB7CF 0x7159 #CJK UNIFIED IDEOGRAPH
+0xB7D0 0x7169 #CJK UNIFIED IDEOGRAPH
+0xB7D1 0x7164 #CJK UNIFIED IDEOGRAPH
+0xB7D2 0x7149 #CJK UNIFIED IDEOGRAPH
+0xB7D3 0x7167 #CJK UNIFIED IDEOGRAPH
+0xB7D4 0x715C #CJK UNIFIED IDEOGRAPH
+0xB7D5 0x716C #CJK UNIFIED IDEOGRAPH
+0xB7D6 0x7166 #CJK UNIFIED IDEOGRAPH
+0xB7D7 0x714C #CJK UNIFIED IDEOGRAPH
+0xB7D8 0x7165 #CJK UNIFIED IDEOGRAPH
+0xB7D9 0x715E #CJK UNIFIED IDEOGRAPH
+0xB7DA 0x7146 #CJK UNIFIED IDEOGRAPH
+0xB7DB 0x7168 #CJK UNIFIED IDEOGRAPH
+0xB7DC 0x7156 #CJK UNIFIED IDEOGRAPH
+0xB7DD 0x723A #CJK UNIFIED IDEOGRAPH
+0xB7DE 0x7252 #CJK UNIFIED IDEOGRAPH
+0xB7DF 0x7337 #CJK UNIFIED IDEOGRAPH
+0xB7E0 0x7345 #CJK UNIFIED IDEOGRAPH
+0xB7E1 0x733F #CJK UNIFIED IDEOGRAPH
+0xB7E2 0x733E #CJK UNIFIED IDEOGRAPH
+0xB7E3 0x746F #CJK UNIFIED IDEOGRAPH
+0xB7E4 0x745A #CJK UNIFIED IDEOGRAPH
+0xB7E5 0x7455 #CJK UNIFIED IDEOGRAPH
+0xB7E6 0x745F #CJK UNIFIED IDEOGRAPH
+0xB7E7 0x745E #CJK UNIFIED IDEOGRAPH
+0xB7E8 0x7441 #CJK UNIFIED IDEOGRAPH
+0xB7E9 0x743F #CJK UNIFIED IDEOGRAPH
+0xB7EA 0x7459 #CJK UNIFIED IDEOGRAPH
+0xB7EB 0x745B #CJK UNIFIED IDEOGRAPH
+0xB7EC 0x745C #CJK UNIFIED IDEOGRAPH
+0xB7ED 0x7576 #CJK UNIFIED IDEOGRAPH
+0xB7EE 0x7578 #CJK UNIFIED IDEOGRAPH
+0xB7EF 0x7600 #CJK UNIFIED IDEOGRAPH
+0xB7F0 0x75F0 #CJK UNIFIED IDEOGRAPH
+0xB7F1 0x7601 #CJK UNIFIED IDEOGRAPH
+0xB7F2 0x75F2 #CJK UNIFIED IDEOGRAPH
+0xB7F3 0x75F1 #CJK UNIFIED IDEOGRAPH
+0xB7F4 0x75FA #CJK UNIFIED IDEOGRAPH
+0xB7F5 0x75FF #CJK UNIFIED IDEOGRAPH
+0xB7F6 0x75F4 #CJK UNIFIED IDEOGRAPH
+0xB7F7 0x75F3 #CJK UNIFIED IDEOGRAPH
+0xB7F8 0x76DE #CJK UNIFIED IDEOGRAPH
+0xB7F9 0x76DF #CJK UNIFIED IDEOGRAPH
+0xB7FA 0x775B #CJK UNIFIED IDEOGRAPH
+0xB7FB 0x776B #CJK UNIFIED IDEOGRAPH
+0xB7FC 0x7766 #CJK UNIFIED IDEOGRAPH
+0xB7FD 0x775E #CJK UNIFIED IDEOGRAPH
+0xB7FE 0x7763 #CJK UNIFIED IDEOGRAPH
+0xB840 0x7779 #CJK UNIFIED IDEOGRAPH
+0xB841 0x776A #CJK UNIFIED IDEOGRAPH
+0xB842 0x776C #CJK UNIFIED IDEOGRAPH
+0xB843 0x775C #CJK UNIFIED IDEOGRAPH
+0xB844 0x7765 #CJK UNIFIED IDEOGRAPH
+0xB845 0x7768 #CJK UNIFIED IDEOGRAPH
+0xB846 0x7762 #CJK UNIFIED IDEOGRAPH
+0xB847 0x77EE #CJK UNIFIED IDEOGRAPH
+0xB848 0x788E #CJK UNIFIED IDEOGRAPH
+0xB849 0x78B0 #CJK UNIFIED IDEOGRAPH
+0xB84A 0x7897 #CJK UNIFIED IDEOGRAPH
+0xB84B 0x7898 #CJK UNIFIED IDEOGRAPH
+0xB84C 0x788C #CJK UNIFIED IDEOGRAPH
+0xB84D 0x7889 #CJK UNIFIED IDEOGRAPH
+0xB84E 0x787C #CJK UNIFIED IDEOGRAPH
+0xB84F 0x7891 #CJK UNIFIED IDEOGRAPH
+0xB850 0x7893 #CJK UNIFIED IDEOGRAPH
+0xB851 0x787F #CJK UNIFIED IDEOGRAPH
+0xB852 0x797A #CJK UNIFIED IDEOGRAPH
+0xB853 0x797F #CJK UNIFIED IDEOGRAPH
+0xB854 0x7981 #CJK UNIFIED IDEOGRAPH
+0xB855 0x842C #CJK UNIFIED IDEOGRAPH
+0xB856 0x79BD #CJK UNIFIED IDEOGRAPH
+0xB857 0x7A1C #CJK UNIFIED IDEOGRAPH
+0xB858 0x7A1A #CJK UNIFIED IDEOGRAPH
+0xB859 0x7A20 #CJK UNIFIED IDEOGRAPH
+0xB85A 0x7A14 #CJK UNIFIED IDEOGRAPH
+0xB85B 0x7A1F #CJK UNIFIED IDEOGRAPH
+0xB85C 0x7A1E #CJK UNIFIED IDEOGRAPH
+0xB85D 0x7A9F #CJK UNIFIED IDEOGRAPH
+0xB85E 0x7AA0 #CJK UNIFIED IDEOGRAPH
+0xB85F 0x7B77 #CJK UNIFIED IDEOGRAPH
+0xB860 0x7BC0 #CJK UNIFIED IDEOGRAPH
+0xB861 0x7B60 #CJK UNIFIED IDEOGRAPH
+0xB862 0x7B6E #CJK UNIFIED IDEOGRAPH
+0xB863 0x7B67 #CJK UNIFIED IDEOGRAPH
+0xB864 0x7CB1 #CJK UNIFIED IDEOGRAPH
+0xB865 0x7CB3 #CJK UNIFIED IDEOGRAPH
+0xB866 0x7CB5 #CJK UNIFIED IDEOGRAPH
+0xB867 0x7D93 #CJK UNIFIED IDEOGRAPH
+0xB868 0x7D79 #CJK UNIFIED IDEOGRAPH
+0xB869 0x7D91 #CJK UNIFIED IDEOGRAPH
+0xB86A 0x7D81 #CJK UNIFIED IDEOGRAPH
+0xB86B 0x7D8F #CJK UNIFIED IDEOGRAPH
+0xB86C 0x7D5B #CJK UNIFIED IDEOGRAPH
+0xB86D 0x7F6E #CJK UNIFIED IDEOGRAPH
+0xB86E 0x7F69 #CJK UNIFIED IDEOGRAPH
+0xB86F 0x7F6A #CJK UNIFIED IDEOGRAPH
+0xB870 0x7F72 #CJK UNIFIED IDEOGRAPH
+0xB871 0x7FA9 #CJK UNIFIED IDEOGRAPH
+0xB872 0x7FA8 #CJK UNIFIED IDEOGRAPH
+0xB873 0x7FA4 #CJK UNIFIED IDEOGRAPH
+0xB874 0x8056 #CJK UNIFIED IDEOGRAPH
+0xB875 0x8058 #CJK UNIFIED IDEOGRAPH
+0xB876 0x8086 #CJK UNIFIED IDEOGRAPH
+0xB877 0x8084 #CJK UNIFIED IDEOGRAPH
+0xB878 0x8171 #CJK UNIFIED IDEOGRAPH
+0xB879 0x8170 #CJK UNIFIED IDEOGRAPH
+0xB87A 0x8178 #CJK UNIFIED IDEOGRAPH
+0xB87B 0x8165 #CJK UNIFIED IDEOGRAPH
+0xB87C 0x816E #CJK UNIFIED IDEOGRAPH
+0xB87D 0x8173 #CJK UNIFIED IDEOGRAPH
+0xB87E 0x816B #CJK UNIFIED IDEOGRAPH
+0xB8A1 0x8179 #CJK UNIFIED IDEOGRAPH
+0xB8A2 0x817A #CJK UNIFIED IDEOGRAPH
+0xB8A3 0x8166 #CJK UNIFIED IDEOGRAPH
+0xB8A4 0x8205 #CJK UNIFIED IDEOGRAPH
+0xB8A5 0x8247 #CJK UNIFIED IDEOGRAPH
+0xB8A6 0x8482 #CJK UNIFIED IDEOGRAPH
+0xB8A7 0x8477 #CJK UNIFIED IDEOGRAPH
+0xB8A8 0x843D #CJK UNIFIED IDEOGRAPH
+0xB8A9 0x8431 #CJK UNIFIED IDEOGRAPH
+0xB8AA 0x8475 #CJK UNIFIED IDEOGRAPH
+0xB8AB 0x8466 #CJK UNIFIED IDEOGRAPH
+0xB8AC 0x846B #CJK UNIFIED IDEOGRAPH
+0xB8AD 0x8449 #CJK UNIFIED IDEOGRAPH
+0xB8AE 0x846C #CJK UNIFIED IDEOGRAPH
+0xB8AF 0x845B #CJK UNIFIED IDEOGRAPH
+0xB8B0 0x843C #CJK UNIFIED IDEOGRAPH
+0xB8B1 0x8435 #CJK UNIFIED IDEOGRAPH
+0xB8B2 0x8461 #CJK UNIFIED IDEOGRAPH
+0xB8B3 0x8463 #CJK UNIFIED IDEOGRAPH
+0xB8B4 0x8469 #CJK UNIFIED IDEOGRAPH
+0xB8B5 0x846D #CJK UNIFIED IDEOGRAPH
+0xB8B6 0x8446 #CJK UNIFIED IDEOGRAPH
+0xB8B7 0x865E #CJK UNIFIED IDEOGRAPH
+0xB8B8 0x865C #CJK UNIFIED IDEOGRAPH
+0xB8B9 0x865F #CJK UNIFIED IDEOGRAPH
+0xB8BA 0x86F9 #CJK UNIFIED IDEOGRAPH
+0xB8BB 0x8713 #CJK UNIFIED IDEOGRAPH
+0xB8BC 0x8708 #CJK UNIFIED IDEOGRAPH
+0xB8BD 0x8707 #CJK UNIFIED IDEOGRAPH
+0xB8BE 0x8700 #CJK UNIFIED IDEOGRAPH
+0xB8BF 0x86FE #CJK UNIFIED IDEOGRAPH
+0xB8C0 0x86FB #CJK UNIFIED IDEOGRAPH
+0xB8C1 0x8702 #CJK UNIFIED IDEOGRAPH
+0xB8C2 0x8703 #CJK UNIFIED IDEOGRAPH
+0xB8C3 0x8706 #CJK UNIFIED IDEOGRAPH
+0xB8C4 0x870A #CJK UNIFIED IDEOGRAPH
+0xB8C5 0x8859 #CJK UNIFIED IDEOGRAPH
+0xB8C6 0x88DF #CJK UNIFIED IDEOGRAPH
+0xB8C7 0x88D4 #CJK UNIFIED IDEOGRAPH
+0xB8C8 0x88D9 #CJK UNIFIED IDEOGRAPH
+0xB8C9 0x88DC #CJK UNIFIED IDEOGRAPH
+0xB8CA 0x88D8 #CJK UNIFIED IDEOGRAPH
+0xB8CB 0x88DD #CJK UNIFIED IDEOGRAPH
+0xB8CC 0x88E1 #CJK UNIFIED IDEOGRAPH
+0xB8CD 0x88CA #CJK UNIFIED IDEOGRAPH
+0xB8CE 0x88D5 #CJK UNIFIED IDEOGRAPH
+0xB8CF 0x88D2 #CJK UNIFIED IDEOGRAPH
+0xB8D0 0x899C #CJK UNIFIED IDEOGRAPH
+0xB8D1 0x89E3 #CJK UNIFIED IDEOGRAPH
+0xB8D2 0x8A6B #CJK UNIFIED IDEOGRAPH
+0xB8D3 0x8A72 #CJK UNIFIED IDEOGRAPH
+0xB8D4 0x8A73 #CJK UNIFIED IDEOGRAPH
+0xB8D5 0x8A66 #CJK UNIFIED IDEOGRAPH
+0xB8D6 0x8A69 #CJK UNIFIED IDEOGRAPH
+0xB8D7 0x8A70 #CJK UNIFIED IDEOGRAPH
+0xB8D8 0x8A87 #CJK UNIFIED IDEOGRAPH
+0xB8D9 0x8A7C #CJK UNIFIED IDEOGRAPH
+0xB8DA 0x8A63 #CJK UNIFIED IDEOGRAPH
+0xB8DB 0x8AA0 #CJK UNIFIED IDEOGRAPH
+0xB8DC 0x8A71 #CJK UNIFIED IDEOGRAPH
+0xB8DD 0x8A85 #CJK UNIFIED IDEOGRAPH
+0xB8DE 0x8A6D #CJK UNIFIED IDEOGRAPH
+0xB8DF 0x8A62 #CJK UNIFIED IDEOGRAPH
+0xB8E0 0x8A6E #CJK UNIFIED IDEOGRAPH
+0xB8E1 0x8A6C #CJK UNIFIED IDEOGRAPH
+0xB8E2 0x8A79 #CJK UNIFIED IDEOGRAPH
+0xB8E3 0x8A7B #CJK UNIFIED IDEOGRAPH
+0xB8E4 0x8A3E #CJK UNIFIED IDEOGRAPH
+0xB8E5 0x8A68 #CJK UNIFIED IDEOGRAPH
+0xB8E6 0x8C62 #CJK UNIFIED IDEOGRAPH
+0xB8E7 0x8C8A #CJK UNIFIED IDEOGRAPH
+0xB8E8 0x8C89 #CJK UNIFIED IDEOGRAPH
+0xB8E9 0x8CCA #CJK UNIFIED IDEOGRAPH
+0xB8EA 0x8CC7 #CJK UNIFIED IDEOGRAPH
+0xB8EB 0x8CC8 #CJK UNIFIED IDEOGRAPH
+0xB8EC 0x8CC4 #CJK UNIFIED IDEOGRAPH
+0xB8ED 0x8CB2 #CJK UNIFIED IDEOGRAPH
+0xB8EE 0x8CC3 #CJK UNIFIED IDEOGRAPH
+0xB8EF 0x8CC2 #CJK UNIFIED IDEOGRAPH
+0xB8F0 0x8CC5 #CJK UNIFIED IDEOGRAPH
+0xB8F1 0x8DE1 #CJK UNIFIED IDEOGRAPH
+0xB8F2 0x8DDF #CJK UNIFIED IDEOGRAPH
+0xB8F3 0x8DE8 #CJK UNIFIED IDEOGRAPH
+0xB8F4 0x8DEF #CJK UNIFIED IDEOGRAPH
+0xB8F5 0x8DF3 #CJK UNIFIED IDEOGRAPH
+0xB8F6 0x8DFA #CJK UNIFIED IDEOGRAPH
+0xB8F7 0x8DEA #CJK UNIFIED IDEOGRAPH
+0xB8F8 0x8DE4 #CJK UNIFIED IDEOGRAPH
+0xB8F9 0x8DE6 #CJK UNIFIED IDEOGRAPH
+0xB8FA 0x8EB2 #CJK UNIFIED IDEOGRAPH
+0xB8FB 0x8F03 #CJK UNIFIED IDEOGRAPH
+0xB8FC 0x8F09 #CJK UNIFIED IDEOGRAPH
+0xB8FD 0x8EFE #CJK UNIFIED IDEOGRAPH
+0xB8FE 0x8F0A #CJK UNIFIED IDEOGRAPH
+0xB940 0x8F9F #CJK UNIFIED IDEOGRAPH
+0xB941 0x8FB2 #CJK UNIFIED IDEOGRAPH
+0xB942 0x904B #CJK UNIFIED IDEOGRAPH
+0xB943 0x904A #CJK UNIFIED IDEOGRAPH
+0xB944 0x9053 #CJK UNIFIED IDEOGRAPH
+0xB945 0x9042 #CJK UNIFIED IDEOGRAPH
+0xB946 0x9054 #CJK UNIFIED IDEOGRAPH
+0xB947 0x903C #CJK UNIFIED IDEOGRAPH
+0xB948 0x9055 #CJK UNIFIED IDEOGRAPH
+0xB949 0x9050 #CJK UNIFIED IDEOGRAPH
+0xB94A 0x9047 #CJK UNIFIED IDEOGRAPH
+0xB94B 0x904F #CJK UNIFIED IDEOGRAPH
+0xB94C 0x904E #CJK UNIFIED IDEOGRAPH
+0xB94D 0x904D #CJK UNIFIED IDEOGRAPH
+0xB94E 0x9051 #CJK UNIFIED IDEOGRAPH
+0xB94F 0x903E #CJK UNIFIED IDEOGRAPH
+0xB950 0x9041 #CJK UNIFIED IDEOGRAPH
+0xB951 0x9112 #CJK UNIFIED IDEOGRAPH
+0xB952 0x9117 #CJK UNIFIED IDEOGRAPH
+0xB953 0x916C #CJK UNIFIED IDEOGRAPH
+0xB954 0x916A #CJK UNIFIED IDEOGRAPH
+0xB955 0x9169 #CJK UNIFIED IDEOGRAPH
+0xB956 0x91C9 #CJK UNIFIED IDEOGRAPH
+0xB957 0x9237 #CJK UNIFIED IDEOGRAPH
+0xB958 0x9257 #CJK UNIFIED IDEOGRAPH
+0xB959 0x9238 #CJK UNIFIED IDEOGRAPH
+0xB95A 0x923D #CJK UNIFIED IDEOGRAPH
+0xB95B 0x9240 #CJK UNIFIED IDEOGRAPH
+0xB95C 0x923E #CJK UNIFIED IDEOGRAPH
+0xB95D 0x925B #CJK UNIFIED IDEOGRAPH
+0xB95E 0x924B #CJK UNIFIED IDEOGRAPH
+0xB95F 0x9264 #CJK UNIFIED IDEOGRAPH
+0xB960 0x9251 #CJK UNIFIED IDEOGRAPH
+0xB961 0x9234 #CJK UNIFIED IDEOGRAPH
+0xB962 0x9249 #CJK UNIFIED IDEOGRAPH
+0xB963 0x924D #CJK UNIFIED IDEOGRAPH
+0xB964 0x9245 #CJK UNIFIED IDEOGRAPH
+0xB965 0x9239 #CJK UNIFIED IDEOGRAPH
+0xB966 0x923F #CJK UNIFIED IDEOGRAPH
+0xB967 0x925A #CJK UNIFIED IDEOGRAPH
+0xB968 0x9598 #CJK UNIFIED IDEOGRAPH
+0xB969 0x9698 #CJK UNIFIED IDEOGRAPH
+0xB96A 0x9694 #CJK UNIFIED IDEOGRAPH
+0xB96B 0x9695 #CJK UNIFIED IDEOGRAPH
+0xB96C 0x96CD #CJK UNIFIED IDEOGRAPH
+0xB96D 0x96CB #CJK UNIFIED IDEOGRAPH
+0xB96E 0x96C9 #CJK UNIFIED IDEOGRAPH
+0xB96F 0x96CA #CJK UNIFIED IDEOGRAPH
+0xB970 0x96F7 #CJK UNIFIED IDEOGRAPH
+0xB971 0x96FB #CJK UNIFIED IDEOGRAPH
+0xB972 0x96F9 #CJK UNIFIED IDEOGRAPH
+0xB973 0x96F6 #CJK UNIFIED IDEOGRAPH
+0xB974 0x9756 #CJK UNIFIED IDEOGRAPH
+0xB975 0x9774 #CJK UNIFIED IDEOGRAPH
+0xB976 0x9776 #CJK UNIFIED IDEOGRAPH
+0xB977 0x9810 #CJK UNIFIED IDEOGRAPH
+0xB978 0x9811 #CJK UNIFIED IDEOGRAPH
+0xB979 0x9813 #CJK UNIFIED IDEOGRAPH
+0xB97A 0x980A #CJK UNIFIED IDEOGRAPH
+0xB97B 0x9812 #CJK UNIFIED IDEOGRAPH
+0xB97C 0x980C #CJK UNIFIED IDEOGRAPH
+0xB97D 0x98FC #CJK UNIFIED IDEOGRAPH
+0xB97E 0x98F4 #CJK UNIFIED IDEOGRAPH
+0xB9A1 0x98FD #CJK UNIFIED IDEOGRAPH
+0xB9A2 0x98FE #CJK UNIFIED IDEOGRAPH
+0xB9A3 0x99B3 #CJK UNIFIED IDEOGRAPH
+0xB9A4 0x99B1 #CJK UNIFIED IDEOGRAPH
+0xB9A5 0x99B4 #CJK UNIFIED IDEOGRAPH
+0xB9A6 0x9AE1 #CJK UNIFIED IDEOGRAPH
+0xB9A7 0x9CE9 #CJK UNIFIED IDEOGRAPH
+0xB9A8 0x9E82 #CJK UNIFIED IDEOGRAPH
+0xB9A9 0x9F0E #CJK UNIFIED IDEOGRAPH
+0xB9AA 0x9F13 #CJK UNIFIED IDEOGRAPH
+0xB9AB 0x9F20 #CJK UNIFIED IDEOGRAPH
+0xB9AC 0x50E7 #CJK UNIFIED IDEOGRAPH
+0xB9AD 0x50EE #CJK UNIFIED IDEOGRAPH
+0xB9AE 0x50E5 #CJK UNIFIED IDEOGRAPH
+0xB9AF 0x50D6 #CJK UNIFIED IDEOGRAPH
+0xB9B0 0x50ED #CJK UNIFIED IDEOGRAPH
+0xB9B1 0x50DA #CJK UNIFIED IDEOGRAPH
+0xB9B2 0x50D5 #CJK UNIFIED IDEOGRAPH
+0xB9B3 0x50CF #CJK UNIFIED IDEOGRAPH
+0xB9B4 0x50D1 #CJK UNIFIED IDEOGRAPH
+0xB9B5 0x50F1 #CJK UNIFIED IDEOGRAPH
+0xB9B6 0x50CE #CJK UNIFIED IDEOGRAPH
+0xB9B7 0x50E9 #CJK UNIFIED IDEOGRAPH
+0xB9B8 0x5162 #CJK UNIFIED IDEOGRAPH
+0xB9B9 0x51F3 #CJK UNIFIED IDEOGRAPH
+0xB9BA 0x5283 #CJK UNIFIED IDEOGRAPH
+0xB9BB 0x5282 #CJK UNIFIED IDEOGRAPH
+0xB9BC 0x5331 #CJK UNIFIED IDEOGRAPH
+0xB9BD 0x53AD #CJK UNIFIED IDEOGRAPH
+0xB9BE 0x55FE #CJK UNIFIED IDEOGRAPH
+0xB9BF 0x5600 #CJK UNIFIED IDEOGRAPH
+0xB9C0 0x561B #CJK UNIFIED IDEOGRAPH
+0xB9C1 0x5617 #CJK UNIFIED IDEOGRAPH
+0xB9C2 0x55FD #CJK UNIFIED IDEOGRAPH
+0xB9C3 0x5614 #CJK UNIFIED IDEOGRAPH
+0xB9C4 0x5606 #CJK UNIFIED IDEOGRAPH
+0xB9C5 0x5609 #CJK UNIFIED IDEOGRAPH
+0xB9C6 0x560D #CJK UNIFIED IDEOGRAPH
+0xB9C7 0x560E #CJK UNIFIED IDEOGRAPH
+0xB9C8 0x55F7 #CJK UNIFIED IDEOGRAPH
+0xB9C9 0x5616 #CJK UNIFIED IDEOGRAPH
+0xB9CA 0x561F #CJK UNIFIED IDEOGRAPH
+0xB9CB 0x5608 #CJK UNIFIED IDEOGRAPH
+0xB9CC 0x5610 #CJK UNIFIED IDEOGRAPH
+0xB9CD 0x55F6 #CJK UNIFIED IDEOGRAPH
+0xB9CE 0x5718 #CJK UNIFIED IDEOGRAPH
+0xB9CF 0x5716 #CJK UNIFIED IDEOGRAPH
+0xB9D0 0x5875 #CJK UNIFIED IDEOGRAPH
+0xB9D1 0x587E #CJK UNIFIED IDEOGRAPH
+0xB9D2 0x5883 #CJK UNIFIED IDEOGRAPH
+0xB9D3 0x5893 #CJK UNIFIED IDEOGRAPH
+0xB9D4 0x588A #CJK UNIFIED IDEOGRAPH
+0xB9D5 0x5879 #CJK UNIFIED IDEOGRAPH
+0xB9D6 0x5885 #CJK UNIFIED IDEOGRAPH
+0xB9D7 0x587D #CJK UNIFIED IDEOGRAPH
+0xB9D8 0x58FD #CJK UNIFIED IDEOGRAPH
+0xB9D9 0x5925 #CJK UNIFIED IDEOGRAPH
+0xB9DA 0x5922 #CJK UNIFIED IDEOGRAPH
+0xB9DB 0x5924 #CJK UNIFIED IDEOGRAPH
+0xB9DC 0x596A #CJK UNIFIED IDEOGRAPH
+0xB9DD 0x5969 #CJK UNIFIED IDEOGRAPH
+0xB9DE 0x5AE1 #CJK UNIFIED IDEOGRAPH
+0xB9DF 0x5AE6 #CJK UNIFIED IDEOGRAPH
+0xB9E0 0x5AE9 #CJK UNIFIED IDEOGRAPH
+0xB9E1 0x5AD7 #CJK UNIFIED IDEOGRAPH
+0xB9E2 0x5AD6 #CJK UNIFIED IDEOGRAPH
+0xB9E3 0x5AD8 #CJK UNIFIED IDEOGRAPH
+0xB9E4 0x5AE3 #CJK UNIFIED IDEOGRAPH
+0xB9E5 0x5B75 #CJK UNIFIED IDEOGRAPH
+0xB9E6 0x5BDE #CJK UNIFIED IDEOGRAPH
+0xB9E7 0x5BE7 #CJK UNIFIED IDEOGRAPH
+0xB9E8 0x5BE1 #CJK UNIFIED IDEOGRAPH
+0xB9E9 0x5BE5 #CJK UNIFIED IDEOGRAPH
+0xB9EA 0x5BE6 #CJK UNIFIED IDEOGRAPH
+0xB9EB 0x5BE8 #CJK UNIFIED IDEOGRAPH
+0xB9EC 0x5BE2 #CJK UNIFIED IDEOGRAPH
+0xB9ED 0x5BE4 #CJK UNIFIED IDEOGRAPH
+0xB9EE 0x5BDF #CJK UNIFIED IDEOGRAPH
+0xB9EF 0x5C0D #CJK UNIFIED IDEOGRAPH
+0xB9F0 0x5C62 #CJK UNIFIED IDEOGRAPH
+0xB9F1 0x5D84 #CJK UNIFIED IDEOGRAPH
+0xB9F2 0x5D87 #CJK UNIFIED IDEOGRAPH
+0xB9F3 0x5E5B #CJK UNIFIED IDEOGRAPH
+0xB9F4 0x5E63 #CJK UNIFIED IDEOGRAPH
+0xB9F5 0x5E55 #CJK UNIFIED IDEOGRAPH
+0xB9F6 0x5E57 #CJK UNIFIED IDEOGRAPH
+0xB9F7 0x5E54 #CJK UNIFIED IDEOGRAPH
+0xB9F8 0x5ED3 #CJK UNIFIED IDEOGRAPH
+0xB9F9 0x5ED6 #CJK UNIFIED IDEOGRAPH
+0xB9FA 0x5F0A #CJK UNIFIED IDEOGRAPH
+0xB9FB 0x5F46 #CJK UNIFIED IDEOGRAPH
+0xB9FC 0x5F70 #CJK UNIFIED IDEOGRAPH
+0xB9FD 0x5FB9 #CJK UNIFIED IDEOGRAPH
+0xB9FE 0x6147 #CJK UNIFIED IDEOGRAPH
+0xBA40 0x613F #CJK UNIFIED IDEOGRAPH
+0xBA41 0x614B #CJK UNIFIED IDEOGRAPH
+0xBA42 0x6177 #CJK UNIFIED IDEOGRAPH
+0xBA43 0x6162 #CJK UNIFIED IDEOGRAPH
+0xBA44 0x6163 #CJK UNIFIED IDEOGRAPH
+0xBA45 0x615F #CJK UNIFIED IDEOGRAPH
+0xBA46 0x615A #CJK UNIFIED IDEOGRAPH
+0xBA47 0x6158 #CJK UNIFIED IDEOGRAPH
+0xBA48 0x6175 #CJK UNIFIED IDEOGRAPH
+0xBA49 0x622A #CJK UNIFIED IDEOGRAPH
+0xBA4A 0x6487 #CJK UNIFIED IDEOGRAPH
+0xBA4B 0x6458 #CJK UNIFIED IDEOGRAPH
+0xBA4C 0x6454 #CJK UNIFIED IDEOGRAPH
+0xBA4D 0x64A4 #CJK UNIFIED IDEOGRAPH
+0xBA4E 0x6478 #CJK UNIFIED IDEOGRAPH
+0xBA4F 0x645F #CJK UNIFIED IDEOGRAPH
+0xBA50 0x647A #CJK UNIFIED IDEOGRAPH
+0xBA51 0x6451 #CJK UNIFIED IDEOGRAPH
+0xBA52 0x6467 #CJK UNIFIED IDEOGRAPH
+0xBA53 0x6434 #CJK UNIFIED IDEOGRAPH
+0xBA54 0x646D #CJK UNIFIED IDEOGRAPH
+0xBA55 0x647B #CJK UNIFIED IDEOGRAPH
+0xBA56 0x6572 #CJK UNIFIED IDEOGRAPH
+0xBA57 0x65A1 #CJK UNIFIED IDEOGRAPH
+0xBA58 0x65D7 #CJK UNIFIED IDEOGRAPH
+0xBA59 0x65D6 #CJK UNIFIED IDEOGRAPH
+0xBA5A 0x66A2 #CJK UNIFIED IDEOGRAPH
+0xBA5B 0x66A8 #CJK UNIFIED IDEOGRAPH
+0xBA5C 0x669D #CJK UNIFIED IDEOGRAPH
+0xBA5D 0x699C #CJK UNIFIED IDEOGRAPH
+0xBA5E 0x69A8 #CJK UNIFIED IDEOGRAPH
+0xBA5F 0x6995 #CJK UNIFIED IDEOGRAPH
+0xBA60 0x69C1 #CJK UNIFIED IDEOGRAPH
+0xBA61 0x69AE #CJK UNIFIED IDEOGRAPH
+0xBA62 0x69D3 #CJK UNIFIED IDEOGRAPH
+0xBA63 0x69CB #CJK UNIFIED IDEOGRAPH
+0xBA64 0x699B #CJK UNIFIED IDEOGRAPH
+0xBA65 0x69B7 #CJK UNIFIED IDEOGRAPH
+0xBA66 0x69BB #CJK UNIFIED IDEOGRAPH
+0xBA67 0x69AB #CJK UNIFIED IDEOGRAPH
+0xBA68 0x69B4 #CJK UNIFIED IDEOGRAPH
+0xBA69 0x69D0 #CJK UNIFIED IDEOGRAPH
+0xBA6A 0x69CD #CJK UNIFIED IDEOGRAPH
+0xBA6B 0x69AD #CJK UNIFIED IDEOGRAPH
+0xBA6C 0x69CC #CJK UNIFIED IDEOGRAPH
+0xBA6D 0x69A6 #CJK UNIFIED IDEOGRAPH
+0xBA6E 0x69C3 #CJK UNIFIED IDEOGRAPH
+0xBA6F 0x69A3 #CJK UNIFIED IDEOGRAPH
+0xBA70 0x6B49 #CJK UNIFIED IDEOGRAPH
+0xBA71 0x6B4C #CJK UNIFIED IDEOGRAPH
+0xBA72 0x6C33 #CJK UNIFIED IDEOGRAPH
+0xBA73 0x6F33 #CJK UNIFIED IDEOGRAPH
+0xBA74 0x6F14 #CJK UNIFIED IDEOGRAPH
+0xBA75 0x6EFE #CJK UNIFIED IDEOGRAPH
+0xBA76 0x6F13 #CJK UNIFIED IDEOGRAPH
+0xBA77 0x6EF4 #CJK UNIFIED IDEOGRAPH
+0xBA78 0x6F29 #CJK UNIFIED IDEOGRAPH
+0xBA79 0x6F3E #CJK UNIFIED IDEOGRAPH
+0xBA7A 0x6F20 #CJK UNIFIED IDEOGRAPH
+0xBA7B 0x6F2C #CJK UNIFIED IDEOGRAPH
+0xBA7C 0x6F0F #CJK UNIFIED IDEOGRAPH
+0xBA7D 0x6F02 #CJK UNIFIED IDEOGRAPH
+0xBA7E 0x6F22 #CJK UNIFIED IDEOGRAPH
+0xBAA1 0x6EFF #CJK UNIFIED IDEOGRAPH
+0xBAA2 0x6EEF #CJK UNIFIED IDEOGRAPH
+0xBAA3 0x6F06 #CJK UNIFIED IDEOGRAPH
+0xBAA4 0x6F31 #CJK UNIFIED IDEOGRAPH
+0xBAA5 0x6F38 #CJK UNIFIED IDEOGRAPH
+0xBAA6 0x6F32 #CJK UNIFIED IDEOGRAPH
+0xBAA7 0x6F23 #CJK UNIFIED IDEOGRAPH
+0xBAA8 0x6F15 #CJK UNIFIED IDEOGRAPH
+0xBAA9 0x6F2B #CJK UNIFIED IDEOGRAPH
+0xBAAA 0x6F2F #CJK UNIFIED IDEOGRAPH
+0xBAAB 0x6F88 #CJK UNIFIED IDEOGRAPH
+0xBAAC 0x6F2A #CJK UNIFIED IDEOGRAPH
+0xBAAD 0x6EEC #CJK UNIFIED IDEOGRAPH
+0xBAAE 0x6F01 #CJK UNIFIED IDEOGRAPH
+0xBAAF 0x6EF2 #CJK UNIFIED IDEOGRAPH
+0xBAB0 0x6ECC #CJK UNIFIED IDEOGRAPH
+0xBAB1 0x6EF7 #CJK UNIFIED IDEOGRAPH
+0xBAB2 0x7194 #CJK UNIFIED IDEOGRAPH
+0xBAB3 0x7199 #CJK UNIFIED IDEOGRAPH
+0xBAB4 0x717D #CJK UNIFIED IDEOGRAPH
+0xBAB5 0x718A #CJK UNIFIED IDEOGRAPH
+0xBAB6 0x7184 #CJK UNIFIED IDEOGRAPH
+0xBAB7 0x7192 #CJK UNIFIED IDEOGRAPH
+0xBAB8 0x723E #CJK UNIFIED IDEOGRAPH
+0xBAB9 0x7292 #CJK UNIFIED IDEOGRAPH
+0xBABA 0x7296 #CJK UNIFIED IDEOGRAPH
+0xBABB 0x7344 #CJK UNIFIED IDEOGRAPH
+0xBABC 0x7350 #CJK UNIFIED IDEOGRAPH
+0xBABD 0x7464 #CJK UNIFIED IDEOGRAPH
+0xBABE 0x7463 #CJK UNIFIED IDEOGRAPH
+0xBABF 0x746A #CJK UNIFIED IDEOGRAPH
+0xBAC0 0x7470 #CJK UNIFIED IDEOGRAPH
+0xBAC1 0x746D #CJK UNIFIED IDEOGRAPH
+0xBAC2 0x7504 #CJK UNIFIED IDEOGRAPH
+0xBAC3 0x7591 #CJK UNIFIED IDEOGRAPH
+0xBAC4 0x7627 #CJK UNIFIED IDEOGRAPH
+0xBAC5 0x760D #CJK UNIFIED IDEOGRAPH
+0xBAC6 0x760B #CJK UNIFIED IDEOGRAPH
+0xBAC7 0x7609 #CJK UNIFIED IDEOGRAPH
+0xBAC8 0x7613 #CJK UNIFIED IDEOGRAPH
+0xBAC9 0x76E1 #CJK UNIFIED IDEOGRAPH
+0xBACA 0x76E3 #CJK UNIFIED IDEOGRAPH
+0xBACB 0x7784 #CJK UNIFIED IDEOGRAPH
+0xBACC 0x777D #CJK UNIFIED IDEOGRAPH
+0xBACD 0x777F #CJK UNIFIED IDEOGRAPH
+0xBACE 0x7761 #CJK UNIFIED IDEOGRAPH
+0xBACF 0x78C1 #CJK UNIFIED IDEOGRAPH
+0xBAD0 0x789F #CJK UNIFIED IDEOGRAPH
+0xBAD1 0x78A7 #CJK UNIFIED IDEOGRAPH
+0xBAD2 0x78B3 #CJK UNIFIED IDEOGRAPH
+0xBAD3 0x78A9 #CJK UNIFIED IDEOGRAPH
+0xBAD4 0x78A3 #CJK UNIFIED IDEOGRAPH
+0xBAD5 0x798E #CJK UNIFIED IDEOGRAPH
+0xBAD6 0x798F #CJK UNIFIED IDEOGRAPH
+0xBAD7 0x798D #CJK UNIFIED IDEOGRAPH
+0xBAD8 0x7A2E #CJK UNIFIED IDEOGRAPH
+0xBAD9 0x7A31 #CJK UNIFIED IDEOGRAPH
+0xBADA 0x7AAA #CJK UNIFIED IDEOGRAPH
+0xBADB 0x7AA9 #CJK UNIFIED IDEOGRAPH
+0xBADC 0x7AED #CJK UNIFIED IDEOGRAPH
+0xBADD 0x7AEF #CJK UNIFIED IDEOGRAPH
+0xBADE 0x7BA1 #CJK UNIFIED IDEOGRAPH
+0xBADF 0x7B95 #CJK UNIFIED IDEOGRAPH
+0xBAE0 0x7B8B #CJK UNIFIED IDEOGRAPH
+0xBAE1 0x7B75 #CJK UNIFIED IDEOGRAPH
+0xBAE2 0x7B97 #CJK UNIFIED IDEOGRAPH
+0xBAE3 0x7B9D #CJK UNIFIED IDEOGRAPH
+0xBAE4 0x7B94 #CJK UNIFIED IDEOGRAPH
+0xBAE5 0x7B8F #CJK UNIFIED IDEOGRAPH
+0xBAE6 0x7BB8 #CJK UNIFIED IDEOGRAPH
+0xBAE7 0x7B87 #CJK UNIFIED IDEOGRAPH
+0xBAE8 0x7B84 #CJK UNIFIED IDEOGRAPH
+0xBAE9 0x7CB9 #CJK UNIFIED IDEOGRAPH
+0xBAEA 0x7CBD #CJK UNIFIED IDEOGRAPH
+0xBAEB 0x7CBE #CJK UNIFIED IDEOGRAPH
+0xBAEC 0x7DBB #CJK UNIFIED IDEOGRAPH
+0xBAED 0x7DB0 #CJK UNIFIED IDEOGRAPH
+0xBAEE 0x7D9C #CJK UNIFIED IDEOGRAPH
+0xBAEF 0x7DBD #CJK UNIFIED IDEOGRAPH
+0xBAF0 0x7DBE #CJK UNIFIED IDEOGRAPH
+0xBAF1 0x7DA0 #CJK UNIFIED IDEOGRAPH
+0xBAF2 0x7DCA #CJK UNIFIED IDEOGRAPH
+0xBAF3 0x7DB4 #CJK UNIFIED IDEOGRAPH
+0xBAF4 0x7DB2 #CJK UNIFIED IDEOGRAPH
+0xBAF5 0x7DB1 #CJK UNIFIED IDEOGRAPH
+0xBAF6 0x7DBA #CJK UNIFIED IDEOGRAPH
+0xBAF7 0x7DA2 #CJK UNIFIED IDEOGRAPH
+0xBAF8 0x7DBF #CJK UNIFIED IDEOGRAPH
+0xBAF9 0x7DB5 #CJK UNIFIED IDEOGRAPH
+0xBAFA 0x7DB8 #CJK UNIFIED IDEOGRAPH
+0xBAFB 0x7DAD #CJK UNIFIED IDEOGRAPH
+0xBAFC 0x7DD2 #CJK UNIFIED IDEOGRAPH
+0xBAFD 0x7DC7 #CJK UNIFIED IDEOGRAPH
+0xBAFE 0x7DAC #CJK UNIFIED IDEOGRAPH
+0xBB40 0x7F70 #CJK UNIFIED IDEOGRAPH
+0xBB41 0x7FE0 #CJK UNIFIED IDEOGRAPH
+0xBB42 0x7FE1 #CJK UNIFIED IDEOGRAPH
+0xBB43 0x7FDF #CJK UNIFIED IDEOGRAPH
+0xBB44 0x805E #CJK UNIFIED IDEOGRAPH
+0xBB45 0x805A #CJK UNIFIED IDEOGRAPH
+0xBB46 0x8087 #CJK UNIFIED IDEOGRAPH
+0xBB47 0x8150 #CJK UNIFIED IDEOGRAPH
+0xBB48 0x8180 #CJK UNIFIED IDEOGRAPH
+0xBB49 0x818F #CJK UNIFIED IDEOGRAPH
+0xBB4A 0x8188 #CJK UNIFIED IDEOGRAPH
+0xBB4B 0x818A #CJK UNIFIED IDEOGRAPH
+0xBB4C 0x817F #CJK UNIFIED IDEOGRAPH
+0xBB4D 0x8182 #CJK UNIFIED IDEOGRAPH
+0xBB4E 0x81E7 #CJK UNIFIED IDEOGRAPH
+0xBB4F 0x81FA #CJK UNIFIED IDEOGRAPH
+0xBB50 0x8207 #CJK UNIFIED IDEOGRAPH
+0xBB51 0x8214 #CJK UNIFIED IDEOGRAPH
+0xBB52 0x821E #CJK UNIFIED IDEOGRAPH
+0xBB53 0x824B #CJK UNIFIED IDEOGRAPH
+0xBB54 0x84C9 #CJK UNIFIED IDEOGRAPH
+0xBB55 0x84BF #CJK UNIFIED IDEOGRAPH
+0xBB56 0x84C6 #CJK UNIFIED IDEOGRAPH
+0xBB57 0x84C4 #CJK UNIFIED IDEOGRAPH
+0xBB58 0x8499 #CJK UNIFIED IDEOGRAPH
+0xBB59 0x849E #CJK UNIFIED IDEOGRAPH
+0xBB5A 0x84B2 #CJK UNIFIED IDEOGRAPH
+0xBB5B 0x849C #CJK UNIFIED IDEOGRAPH
+0xBB5C 0x84CB #CJK UNIFIED IDEOGRAPH
+0xBB5D 0x84B8 #CJK UNIFIED IDEOGRAPH
+0xBB5E 0x84C0 #CJK UNIFIED IDEOGRAPH
+0xBB5F 0x84D3 #CJK UNIFIED IDEOGRAPH
+0xBB60 0x8490 #CJK UNIFIED IDEOGRAPH
+0xBB61 0x84BC #CJK UNIFIED IDEOGRAPH
+0xBB62 0x84D1 #CJK UNIFIED IDEOGRAPH
+0xBB63 0x84CA #CJK UNIFIED IDEOGRAPH
+0xBB64 0x873F #CJK UNIFIED IDEOGRAPH
+0xBB65 0x871C #CJK UNIFIED IDEOGRAPH
+0xBB66 0x873B #CJK UNIFIED IDEOGRAPH
+0xBB67 0x8722 #CJK UNIFIED IDEOGRAPH
+0xBB68 0x8725 #CJK UNIFIED IDEOGRAPH
+0xBB69 0x8734 #CJK UNIFIED IDEOGRAPH
+0xBB6A 0x8718 #CJK UNIFIED IDEOGRAPH
+0xBB6B 0x8755 #CJK UNIFIED IDEOGRAPH
+0xBB6C 0x8737 #CJK UNIFIED IDEOGRAPH
+0xBB6D 0x8729 #CJK UNIFIED IDEOGRAPH
+0xBB6E 0x88F3 #CJK UNIFIED IDEOGRAPH
+0xBB6F 0x8902 #CJK UNIFIED IDEOGRAPH
+0xBB70 0x88F4 #CJK UNIFIED IDEOGRAPH
+0xBB71 0x88F9 #CJK UNIFIED IDEOGRAPH
+0xBB72 0x88F8 #CJK UNIFIED IDEOGRAPH
+0xBB73 0x88FD #CJK UNIFIED IDEOGRAPH
+0xBB74 0x88E8 #CJK UNIFIED IDEOGRAPH
+0xBB75 0x891A #CJK UNIFIED IDEOGRAPH
+0xBB76 0x88EF #CJK UNIFIED IDEOGRAPH
+0xBB77 0x8AA6 #CJK UNIFIED IDEOGRAPH
+0xBB78 0x8A8C #CJK UNIFIED IDEOGRAPH
+0xBB79 0x8A9E #CJK UNIFIED IDEOGRAPH
+0xBB7A 0x8AA3 #CJK UNIFIED IDEOGRAPH
+0xBB7B 0x8A8D #CJK UNIFIED IDEOGRAPH
+0xBB7C 0x8AA1 #CJK UNIFIED IDEOGRAPH
+0xBB7D 0x8A93 #CJK UNIFIED IDEOGRAPH
+0xBB7E 0x8AA4 #CJK UNIFIED IDEOGRAPH
+0xBBA1 0x8AAA #CJK UNIFIED IDEOGRAPH
+0xBBA2 0x8AA5 #CJK UNIFIED IDEOGRAPH
+0xBBA3 0x8AA8 #CJK UNIFIED IDEOGRAPH
+0xBBA4 0x8A98 #CJK UNIFIED IDEOGRAPH
+0xBBA5 0x8A91 #CJK UNIFIED IDEOGRAPH
+0xBBA6 0x8A9A #CJK UNIFIED IDEOGRAPH
+0xBBA7 0x8AA7 #CJK UNIFIED IDEOGRAPH
+0xBBA8 0x8C6A #CJK UNIFIED IDEOGRAPH
+0xBBA9 0x8C8D #CJK UNIFIED IDEOGRAPH
+0xBBAA 0x8C8C #CJK UNIFIED IDEOGRAPH
+0xBBAB 0x8CD3 #CJK UNIFIED IDEOGRAPH
+0xBBAC 0x8CD1 #CJK UNIFIED IDEOGRAPH
+0xBBAD 0x8CD2 #CJK UNIFIED IDEOGRAPH
+0xBBAE 0x8D6B #CJK UNIFIED IDEOGRAPH
+0xBBAF 0x8D99 #CJK UNIFIED IDEOGRAPH
+0xBBB0 0x8D95 #CJK UNIFIED IDEOGRAPH
+0xBBB1 0x8DFC #CJK UNIFIED IDEOGRAPH
+0xBBB2 0x8F14 #CJK UNIFIED IDEOGRAPH
+0xBBB3 0x8F12 #CJK UNIFIED IDEOGRAPH
+0xBBB4 0x8F15 #CJK UNIFIED IDEOGRAPH
+0xBBB5 0x8F13 #CJK UNIFIED IDEOGRAPH
+0xBBB6 0x8FA3 #CJK UNIFIED IDEOGRAPH
+0xBBB7 0x9060 #CJK UNIFIED IDEOGRAPH
+0xBBB8 0x9058 #CJK UNIFIED IDEOGRAPH
+0xBBB9 0x905C #CJK UNIFIED IDEOGRAPH
+0xBBBA 0x9063 #CJK UNIFIED IDEOGRAPH
+0xBBBB 0x9059 #CJK UNIFIED IDEOGRAPH
+0xBBBC 0x905E #CJK UNIFIED IDEOGRAPH
+0xBBBD 0x9062 #CJK UNIFIED IDEOGRAPH
+0xBBBE 0x905D #CJK UNIFIED IDEOGRAPH
+0xBBBF 0x905B #CJK UNIFIED IDEOGRAPH
+0xBBC0 0x9119 #CJK UNIFIED IDEOGRAPH
+0xBBC1 0x9118 #CJK UNIFIED IDEOGRAPH
+0xBBC2 0x911E #CJK UNIFIED IDEOGRAPH
+0xBBC3 0x9175 #CJK UNIFIED IDEOGRAPH
+0xBBC4 0x9178 #CJK UNIFIED IDEOGRAPH
+0xBBC5 0x9177 #CJK UNIFIED IDEOGRAPH
+0xBBC6 0x9174 #CJK UNIFIED IDEOGRAPH
+0xBBC7 0x9278 #CJK UNIFIED IDEOGRAPH
+0xBBC8 0x9280 #CJK UNIFIED IDEOGRAPH
+0xBBC9 0x9285 #CJK UNIFIED IDEOGRAPH
+0xBBCA 0x9298 #CJK UNIFIED IDEOGRAPH
+0xBBCB 0x9296 #CJK UNIFIED IDEOGRAPH
+0xBBCC 0x927B #CJK UNIFIED IDEOGRAPH
+0xBBCD 0x9293 #CJK UNIFIED IDEOGRAPH
+0xBBCE 0x929C #CJK UNIFIED IDEOGRAPH
+0xBBCF 0x92A8 #CJK UNIFIED IDEOGRAPH
+0xBBD0 0x927C #CJK UNIFIED IDEOGRAPH
+0xBBD1 0x9291 #CJK UNIFIED IDEOGRAPH
+0xBBD2 0x95A1 #CJK UNIFIED IDEOGRAPH
+0xBBD3 0x95A8 #CJK UNIFIED IDEOGRAPH
+0xBBD4 0x95A9 #CJK UNIFIED IDEOGRAPH
+0xBBD5 0x95A3 #CJK UNIFIED IDEOGRAPH
+0xBBD6 0x95A5 #CJK UNIFIED IDEOGRAPH
+0xBBD7 0x95A4 #CJK UNIFIED IDEOGRAPH
+0xBBD8 0x9699 #CJK UNIFIED IDEOGRAPH
+0xBBD9 0x969C #CJK UNIFIED IDEOGRAPH
+0xBBDA 0x969B #CJK UNIFIED IDEOGRAPH
+0xBBDB 0x96CC #CJK UNIFIED IDEOGRAPH
+0xBBDC 0x96D2 #CJK UNIFIED IDEOGRAPH
+0xBBDD 0x9700 #CJK UNIFIED IDEOGRAPH
+0xBBDE 0x977C #CJK UNIFIED IDEOGRAPH
+0xBBDF 0x9785 #CJK UNIFIED IDEOGRAPH
+0xBBE0 0x97F6 #CJK UNIFIED IDEOGRAPH
+0xBBE1 0x9817 #CJK UNIFIED IDEOGRAPH
+0xBBE2 0x9818 #CJK UNIFIED IDEOGRAPH
+0xBBE3 0x98AF #CJK UNIFIED IDEOGRAPH
+0xBBE4 0x98B1 #CJK UNIFIED IDEOGRAPH
+0xBBE5 0x9903 #CJK UNIFIED IDEOGRAPH
+0xBBE6 0x9905 #CJK UNIFIED IDEOGRAPH
+0xBBE7 0x990C #CJK UNIFIED IDEOGRAPH
+0xBBE8 0x9909 #CJK UNIFIED IDEOGRAPH
+0xBBE9 0x99C1 #CJK UNIFIED IDEOGRAPH
+0xBBEA 0x9AAF #CJK UNIFIED IDEOGRAPH
+0xBBEB 0x9AB0 #CJK UNIFIED IDEOGRAPH
+0xBBEC 0x9AE6 #CJK UNIFIED IDEOGRAPH
+0xBBED 0x9B41 #CJK UNIFIED IDEOGRAPH
+0xBBEE 0x9B42 #CJK UNIFIED IDEOGRAPH
+0xBBEF 0x9CF4 #CJK UNIFIED IDEOGRAPH
+0xBBF0 0x9CF6 #CJK UNIFIED IDEOGRAPH
+0xBBF1 0x9CF3 #CJK UNIFIED IDEOGRAPH
+0xBBF2 0x9EBC #CJK UNIFIED IDEOGRAPH
+0xBBF3 0x9F3B #CJK UNIFIED IDEOGRAPH
+0xBBF4 0x9F4A #CJK UNIFIED IDEOGRAPH
+0xBBF5 0x5104 #CJK UNIFIED IDEOGRAPH
+0xBBF6 0x5100 #CJK UNIFIED IDEOGRAPH
+0xBBF7 0x50FB #CJK UNIFIED IDEOGRAPH
+0xBBF8 0x50F5 #CJK UNIFIED IDEOGRAPH
+0xBBF9 0x50F9 #CJK UNIFIED IDEOGRAPH
+0xBBFA 0x5102 #CJK UNIFIED IDEOGRAPH
+0xBBFB 0x5108 #CJK UNIFIED IDEOGRAPH
+0xBBFC 0x5109 #CJK UNIFIED IDEOGRAPH
+0xBBFD 0x5105 #CJK UNIFIED IDEOGRAPH
+0xBBFE 0x51DC #CJK UNIFIED IDEOGRAPH
+0xBC40 0x5287 #CJK UNIFIED IDEOGRAPH
+0xBC41 0x5288 #CJK UNIFIED IDEOGRAPH
+0xBC42 0x5289 #CJK UNIFIED IDEOGRAPH
+0xBC43 0x528D #CJK UNIFIED IDEOGRAPH
+0xBC44 0x528A #CJK UNIFIED IDEOGRAPH
+0xBC45 0x52F0 #CJK UNIFIED IDEOGRAPH
+0xBC46 0x53B2 #CJK UNIFIED IDEOGRAPH
+0xBC47 0x562E #CJK UNIFIED IDEOGRAPH
+0xBC48 0x563B #CJK UNIFIED IDEOGRAPH
+0xBC49 0x5639 #CJK UNIFIED IDEOGRAPH
+0xBC4A 0x5632 #CJK UNIFIED IDEOGRAPH
+0xBC4B 0x563F #CJK UNIFIED IDEOGRAPH
+0xBC4C 0x5634 #CJK UNIFIED IDEOGRAPH
+0xBC4D 0x5629 #CJK UNIFIED IDEOGRAPH
+0xBC4E 0x5653 #CJK UNIFIED IDEOGRAPH
+0xBC4F 0x564E #CJK UNIFIED IDEOGRAPH
+0xBC50 0x5657 #CJK UNIFIED IDEOGRAPH
+0xBC51 0x5674 #CJK UNIFIED IDEOGRAPH
+0xBC52 0x5636 #CJK UNIFIED IDEOGRAPH
+0xBC53 0x562F #CJK UNIFIED IDEOGRAPH
+0xBC54 0x5630 #CJK UNIFIED IDEOGRAPH
+0xBC55 0x5880 #CJK UNIFIED IDEOGRAPH
+0xBC56 0x589F #CJK UNIFIED IDEOGRAPH
+0xBC57 0x589E #CJK UNIFIED IDEOGRAPH
+0xBC58 0x58B3 #CJK UNIFIED IDEOGRAPH
+0xBC59 0x589C #CJK UNIFIED IDEOGRAPH
+0xBC5A 0x58AE #CJK UNIFIED IDEOGRAPH
+0xBC5B 0x58A9 #CJK UNIFIED IDEOGRAPH
+0xBC5C 0x58A6 #CJK UNIFIED IDEOGRAPH
+0xBC5D 0x596D #CJK UNIFIED IDEOGRAPH
+0xBC5E 0x5B09 #CJK UNIFIED IDEOGRAPH
+0xBC5F 0x5AFB #CJK UNIFIED IDEOGRAPH
+0xBC60 0x5B0B #CJK UNIFIED IDEOGRAPH
+0xBC61 0x5AF5 #CJK UNIFIED IDEOGRAPH
+0xBC62 0x5B0C #CJK UNIFIED IDEOGRAPH
+0xBC63 0x5B08 #CJK UNIFIED IDEOGRAPH
+0xBC64 0x5BEE #CJK UNIFIED IDEOGRAPH
+0xBC65 0x5BEC #CJK UNIFIED IDEOGRAPH
+0xBC66 0x5BE9 #CJK UNIFIED IDEOGRAPH
+0xBC67 0x5BEB #CJK UNIFIED IDEOGRAPH
+0xBC68 0x5C64 #CJK UNIFIED IDEOGRAPH
+0xBC69 0x5C65 #CJK UNIFIED IDEOGRAPH
+0xBC6A 0x5D9D #CJK UNIFIED IDEOGRAPH
+0xBC6B 0x5D94 #CJK UNIFIED IDEOGRAPH
+0xBC6C 0x5E62 #CJK UNIFIED IDEOGRAPH
+0xBC6D 0x5E5F #CJK UNIFIED IDEOGRAPH
+0xBC6E 0x5E61 #CJK UNIFIED IDEOGRAPH
+0xBC6F 0x5EE2 #CJK UNIFIED IDEOGRAPH
+0xBC70 0x5EDA #CJK UNIFIED IDEOGRAPH
+0xBC71 0x5EDF #CJK UNIFIED IDEOGRAPH
+0xBC72 0x5EDD #CJK UNIFIED IDEOGRAPH
+0xBC73 0x5EE3 #CJK UNIFIED IDEOGRAPH
+0xBC74 0x5EE0 #CJK UNIFIED IDEOGRAPH
+0xBC75 0x5F48 #CJK UNIFIED IDEOGRAPH
+0xBC76 0x5F71 #CJK UNIFIED IDEOGRAPH
+0xBC77 0x5FB7 #CJK UNIFIED IDEOGRAPH
+0xBC78 0x5FB5 #CJK UNIFIED IDEOGRAPH
+0xBC79 0x6176 #CJK UNIFIED IDEOGRAPH
+0xBC7A 0x6167 #CJK UNIFIED IDEOGRAPH
+0xBC7B 0x616E #CJK UNIFIED IDEOGRAPH
+0xBC7C 0x615D #CJK UNIFIED IDEOGRAPH
+0xBC7D 0x6155 #CJK UNIFIED IDEOGRAPH
+0xBC7E 0x6182 #CJK UNIFIED IDEOGRAPH
+0xBCA1 0x617C #CJK UNIFIED IDEOGRAPH
+0xBCA2 0x6170 #CJK UNIFIED IDEOGRAPH
+0xBCA3 0x616B #CJK UNIFIED IDEOGRAPH
+0xBCA4 0x617E #CJK UNIFIED IDEOGRAPH
+0xBCA5 0x61A7 #CJK UNIFIED IDEOGRAPH
+0xBCA6 0x6190 #CJK UNIFIED IDEOGRAPH
+0xBCA7 0x61AB #CJK UNIFIED IDEOGRAPH
+0xBCA8 0x618E #CJK UNIFIED IDEOGRAPH
+0xBCA9 0x61AC #CJK UNIFIED IDEOGRAPH
+0xBCAA 0x619A #CJK UNIFIED IDEOGRAPH
+0xBCAB 0x61A4 #CJK UNIFIED IDEOGRAPH
+0xBCAC 0x6194 #CJK UNIFIED IDEOGRAPH
+0xBCAD 0x61AE #CJK UNIFIED IDEOGRAPH
+0xBCAE 0x622E #CJK UNIFIED IDEOGRAPH
+0xBCAF 0x6469 #CJK UNIFIED IDEOGRAPH
+0xBCB0 0x646F #CJK UNIFIED IDEOGRAPH
+0xBCB1 0x6479 #CJK UNIFIED IDEOGRAPH
+0xBCB2 0x649E #CJK UNIFIED IDEOGRAPH
+0xBCB3 0x64B2 #CJK UNIFIED IDEOGRAPH
+0xBCB4 0x6488 #CJK UNIFIED IDEOGRAPH
+0xBCB5 0x6490 #CJK UNIFIED IDEOGRAPH
+0xBCB6 0x64B0 #CJK UNIFIED IDEOGRAPH
+0xBCB7 0x64A5 #CJK UNIFIED IDEOGRAPH
+0xBCB8 0x6493 #CJK UNIFIED IDEOGRAPH
+0xBCB9 0x6495 #CJK UNIFIED IDEOGRAPH
+0xBCBA 0x64A9 #CJK UNIFIED IDEOGRAPH
+0xBCBB 0x6492 #CJK UNIFIED IDEOGRAPH
+0xBCBC 0x64AE #CJK UNIFIED IDEOGRAPH
+0xBCBD 0x64AD #CJK UNIFIED IDEOGRAPH
+0xBCBE 0x64AB #CJK UNIFIED IDEOGRAPH
+0xBCBF 0x649A #CJK UNIFIED IDEOGRAPH
+0xBCC0 0x64AC #CJK UNIFIED IDEOGRAPH
+0xBCC1 0x6499 #CJK UNIFIED IDEOGRAPH
+0xBCC2 0x64A2 #CJK UNIFIED IDEOGRAPH
+0xBCC3 0x64B3 #CJK UNIFIED IDEOGRAPH
+0xBCC4 0x6575 #CJK UNIFIED IDEOGRAPH
+0xBCC5 0x6577 #CJK UNIFIED IDEOGRAPH
+0xBCC6 0x6578 #CJK UNIFIED IDEOGRAPH
+0xBCC7 0x66AE #CJK UNIFIED IDEOGRAPH
+0xBCC8 0x66AB #CJK UNIFIED IDEOGRAPH
+0xBCC9 0x66B4 #CJK UNIFIED IDEOGRAPH
+0xBCCA 0x66B1 #CJK UNIFIED IDEOGRAPH
+0xBCCB 0x6A23 #CJK UNIFIED IDEOGRAPH
+0xBCCC 0x6A1F #CJK UNIFIED IDEOGRAPH
+0xBCCD 0x69E8 #CJK UNIFIED IDEOGRAPH
+0xBCCE 0x6A01 #CJK UNIFIED IDEOGRAPH
+0xBCCF 0x6A1E #CJK UNIFIED IDEOGRAPH
+0xBCD0 0x6A19 #CJK UNIFIED IDEOGRAPH
+0xBCD1 0x69FD #CJK UNIFIED IDEOGRAPH
+0xBCD2 0x6A21 #CJK UNIFIED IDEOGRAPH
+0xBCD3 0x6A13 #CJK UNIFIED IDEOGRAPH
+0xBCD4 0x6A0A #CJK UNIFIED IDEOGRAPH
+0xBCD5 0x69F3 #CJK UNIFIED IDEOGRAPH
+0xBCD6 0x6A02 #CJK UNIFIED IDEOGRAPH
+0xBCD7 0x6A05 #CJK UNIFIED IDEOGRAPH
+0xBCD8 0x69ED #CJK UNIFIED IDEOGRAPH
+0xBCD9 0x6A11 #CJK UNIFIED IDEOGRAPH
+0xBCDA 0x6B50 #CJK UNIFIED IDEOGRAPH
+0xBCDB 0x6B4E #CJK UNIFIED IDEOGRAPH
+0xBCDC 0x6BA4 #CJK UNIFIED IDEOGRAPH
+0xBCDD 0x6BC5 #CJK UNIFIED IDEOGRAPH
+0xBCDE 0x6BC6 #CJK UNIFIED IDEOGRAPH
+0xBCDF 0x6F3F #CJK UNIFIED IDEOGRAPH
+0xBCE0 0x6F7C #CJK UNIFIED IDEOGRAPH
+0xBCE1 0x6F84 #CJK UNIFIED IDEOGRAPH
+0xBCE2 0x6F51 #CJK UNIFIED IDEOGRAPH
+0xBCE3 0x6F66 #CJK UNIFIED IDEOGRAPH
+0xBCE4 0x6F54 #CJK UNIFIED IDEOGRAPH
+0xBCE5 0x6F86 #CJK UNIFIED IDEOGRAPH
+0xBCE6 0x6F6D #CJK UNIFIED IDEOGRAPH
+0xBCE7 0x6F5B #CJK UNIFIED IDEOGRAPH
+0xBCE8 0x6F78 #CJK UNIFIED IDEOGRAPH
+0xBCE9 0x6F6E #CJK UNIFIED IDEOGRAPH
+0xBCEA 0x6F8E #CJK UNIFIED IDEOGRAPH
+0xBCEB 0x6F7A #CJK UNIFIED IDEOGRAPH
+0xBCEC 0x6F70 #CJK UNIFIED IDEOGRAPH
+0xBCED 0x6F64 #CJK UNIFIED IDEOGRAPH
+0xBCEE 0x6F97 #CJK UNIFIED IDEOGRAPH
+0xBCEF 0x6F58 #CJK UNIFIED IDEOGRAPH
+0xBCF0 0x6ED5 #CJK UNIFIED IDEOGRAPH
+0xBCF1 0x6F6F #CJK UNIFIED IDEOGRAPH
+0xBCF2 0x6F60 #CJK UNIFIED IDEOGRAPH
+0xBCF3 0x6F5F #CJK UNIFIED IDEOGRAPH
+0xBCF4 0x719F #CJK UNIFIED IDEOGRAPH
+0xBCF5 0x71AC #CJK UNIFIED IDEOGRAPH
+0xBCF6 0x71B1 #CJK UNIFIED IDEOGRAPH
+0xBCF7 0x71A8 #CJK UNIFIED IDEOGRAPH
+0xBCF8 0x7256 #CJK UNIFIED IDEOGRAPH
+0xBCF9 0x729B #CJK UNIFIED IDEOGRAPH
+0xBCFA 0x734E #CJK UNIFIED IDEOGRAPH
+0xBCFB 0x7357 #CJK UNIFIED IDEOGRAPH
+0xBCFC 0x7469 #CJK UNIFIED IDEOGRAPH
+0xBCFD 0x748B #CJK UNIFIED IDEOGRAPH
+0xBCFE 0x7483 #CJK UNIFIED IDEOGRAPH
+0xBD40 0x747E #CJK UNIFIED IDEOGRAPH
+0xBD41 0x7480 #CJK UNIFIED IDEOGRAPH
+0xBD42 0x757F #CJK UNIFIED IDEOGRAPH
+0xBD43 0x7620 #CJK UNIFIED IDEOGRAPH
+0xBD44 0x7629 #CJK UNIFIED IDEOGRAPH
+0xBD45 0x761F #CJK UNIFIED IDEOGRAPH
+0xBD46 0x7624 #CJK UNIFIED IDEOGRAPH
+0xBD47 0x7626 #CJK UNIFIED IDEOGRAPH
+0xBD48 0x7621 #CJK UNIFIED IDEOGRAPH
+0xBD49 0x7622 #CJK UNIFIED IDEOGRAPH
+0xBD4A 0x769A #CJK UNIFIED IDEOGRAPH
+0xBD4B 0x76BA #CJK UNIFIED IDEOGRAPH
+0xBD4C 0x76E4 #CJK UNIFIED IDEOGRAPH
+0xBD4D 0x778E #CJK UNIFIED IDEOGRAPH
+0xBD4E 0x7787 #CJK UNIFIED IDEOGRAPH
+0xBD4F 0x778C #CJK UNIFIED IDEOGRAPH
+0xBD50 0x7791 #CJK UNIFIED IDEOGRAPH
+0xBD51 0x778B #CJK UNIFIED IDEOGRAPH
+0xBD52 0x78CB #CJK UNIFIED IDEOGRAPH
+0xBD53 0x78C5 #CJK UNIFIED IDEOGRAPH
+0xBD54 0x78BA #CJK UNIFIED IDEOGRAPH
+0xBD55 0x78CA #CJK UNIFIED IDEOGRAPH
+0xBD56 0x78BE #CJK UNIFIED IDEOGRAPH
+0xBD57 0x78D5 #CJK UNIFIED IDEOGRAPH
+0xBD58 0x78BC #CJK UNIFIED IDEOGRAPH
+0xBD59 0x78D0 #CJK UNIFIED IDEOGRAPH
+0xBD5A 0x7A3F #CJK UNIFIED IDEOGRAPH
+0xBD5B 0x7A3C #CJK UNIFIED IDEOGRAPH
+0xBD5C 0x7A40 #CJK UNIFIED IDEOGRAPH
+0xBD5D 0x7A3D #CJK UNIFIED IDEOGRAPH
+0xBD5E 0x7A37 #CJK UNIFIED IDEOGRAPH
+0xBD5F 0x7A3B #CJK UNIFIED IDEOGRAPH
+0xBD60 0x7AAF #CJK UNIFIED IDEOGRAPH
+0xBD61 0x7AAE #CJK UNIFIED IDEOGRAPH
+0xBD62 0x7BAD #CJK UNIFIED IDEOGRAPH
+0xBD63 0x7BB1 #CJK UNIFIED IDEOGRAPH
+0xBD64 0x7BC4 #CJK UNIFIED IDEOGRAPH
+0xBD65 0x7BB4 #CJK UNIFIED IDEOGRAPH
+0xBD66 0x7BC6 #CJK UNIFIED IDEOGRAPH
+0xBD67 0x7BC7 #CJK UNIFIED IDEOGRAPH
+0xBD68 0x7BC1 #CJK UNIFIED IDEOGRAPH
+0xBD69 0x7BA0 #CJK UNIFIED IDEOGRAPH
+0xBD6A 0x7BCC #CJK UNIFIED IDEOGRAPH
+0xBD6B 0x7CCA #CJK UNIFIED IDEOGRAPH
+0xBD6C 0x7DE0 #CJK UNIFIED IDEOGRAPH
+0xBD6D 0x7DF4 #CJK UNIFIED IDEOGRAPH
+0xBD6E 0x7DEF #CJK UNIFIED IDEOGRAPH
+0xBD6F 0x7DFB #CJK UNIFIED IDEOGRAPH
+0xBD70 0x7DD8 #CJK UNIFIED IDEOGRAPH
+0xBD71 0x7DEC #CJK UNIFIED IDEOGRAPH
+0xBD72 0x7DDD #CJK UNIFIED IDEOGRAPH
+0xBD73 0x7DE8 #CJK UNIFIED IDEOGRAPH
+0xBD74 0x7DE3 #CJK UNIFIED IDEOGRAPH
+0xBD75 0x7DDA #CJK UNIFIED IDEOGRAPH
+0xBD76 0x7DDE #CJK UNIFIED IDEOGRAPH
+0xBD77 0x7DE9 #CJK UNIFIED IDEOGRAPH
+0xBD78 0x7D9E #CJK UNIFIED IDEOGRAPH
+0xBD79 0x7DD9 #CJK UNIFIED IDEOGRAPH
+0xBD7A 0x7DF2 #CJK UNIFIED IDEOGRAPH
+0xBD7B 0x7DF9 #CJK UNIFIED IDEOGRAPH
+0xBD7C 0x7F75 #CJK UNIFIED IDEOGRAPH
+0xBD7D 0x7F77 #CJK UNIFIED IDEOGRAPH
+0xBD7E 0x7FAF #CJK UNIFIED IDEOGRAPH
+0xBDA1 0x7FE9 #CJK UNIFIED IDEOGRAPH
+0xBDA2 0x8026 #CJK UNIFIED IDEOGRAPH
+0xBDA3 0x819B #CJK UNIFIED IDEOGRAPH
+0xBDA4 0x819C #CJK UNIFIED IDEOGRAPH
+0xBDA5 0x819D #CJK UNIFIED IDEOGRAPH
+0xBDA6 0x81A0 #CJK UNIFIED IDEOGRAPH
+0xBDA7 0x819A #CJK UNIFIED IDEOGRAPH
+0xBDA8 0x8198 #CJK UNIFIED IDEOGRAPH
+0xBDA9 0x8517 #CJK UNIFIED IDEOGRAPH
+0xBDAA 0x853D #CJK UNIFIED IDEOGRAPH
+0xBDAB 0x851A #CJK UNIFIED IDEOGRAPH
+0xBDAC 0x84EE #CJK UNIFIED IDEOGRAPH
+0xBDAD 0x852C #CJK UNIFIED IDEOGRAPH
+0xBDAE 0x852D #CJK UNIFIED IDEOGRAPH
+0xBDAF 0x8513 #CJK UNIFIED IDEOGRAPH
+0xBDB0 0x8511 #CJK UNIFIED IDEOGRAPH
+0xBDB1 0x8523 #CJK UNIFIED IDEOGRAPH
+0xBDB2 0x8521 #CJK UNIFIED IDEOGRAPH
+0xBDB3 0x8514 #CJK UNIFIED IDEOGRAPH
+0xBDB4 0x84EC #CJK UNIFIED IDEOGRAPH
+0xBDB5 0x8525 #CJK UNIFIED IDEOGRAPH
+0xBDB6 0x84FF #CJK UNIFIED IDEOGRAPH
+0xBDB7 0x8506 #CJK UNIFIED IDEOGRAPH
+0xBDB8 0x8782 #CJK UNIFIED IDEOGRAPH
+0xBDB9 0x8774 #CJK UNIFIED IDEOGRAPH
+0xBDBA 0x8776 #CJK UNIFIED IDEOGRAPH
+0xBDBB 0x8760 #CJK UNIFIED IDEOGRAPH
+0xBDBC 0x8766 #CJK UNIFIED IDEOGRAPH
+0xBDBD 0x8778 #CJK UNIFIED IDEOGRAPH
+0xBDBE 0x8768 #CJK UNIFIED IDEOGRAPH
+0xBDBF 0x8759 #CJK UNIFIED IDEOGRAPH
+0xBDC0 0x8757 #CJK UNIFIED IDEOGRAPH
+0xBDC1 0x874C #CJK UNIFIED IDEOGRAPH
+0xBDC2 0x8753 #CJK UNIFIED IDEOGRAPH
+0xBDC3 0x885B #CJK UNIFIED IDEOGRAPH
+0xBDC4 0x885D #CJK UNIFIED IDEOGRAPH
+0xBDC5 0x8910 #CJK UNIFIED IDEOGRAPH
+0xBDC6 0x8907 #CJK UNIFIED IDEOGRAPH
+0xBDC7 0x8912 #CJK UNIFIED IDEOGRAPH
+0xBDC8 0x8913 #CJK UNIFIED IDEOGRAPH
+0xBDC9 0x8915 #CJK UNIFIED IDEOGRAPH
+0xBDCA 0x890A #CJK UNIFIED IDEOGRAPH
+0xBDCB 0x8ABC #CJK UNIFIED IDEOGRAPH
+0xBDCC 0x8AD2 #CJK UNIFIED IDEOGRAPH
+0xBDCD 0x8AC7 #CJK UNIFIED IDEOGRAPH
+0xBDCE 0x8AC4 #CJK UNIFIED IDEOGRAPH
+0xBDCF 0x8A95 #CJK UNIFIED IDEOGRAPH
+0xBDD0 0x8ACB #CJK UNIFIED IDEOGRAPH
+0xBDD1 0x8AF8 #CJK UNIFIED IDEOGRAPH
+0xBDD2 0x8AB2 #CJK UNIFIED IDEOGRAPH
+0xBDD3 0x8AC9 #CJK UNIFIED IDEOGRAPH
+0xBDD4 0x8AC2 #CJK UNIFIED IDEOGRAPH
+0xBDD5 0x8ABF #CJK UNIFIED IDEOGRAPH
+0xBDD6 0x8AB0 #CJK UNIFIED IDEOGRAPH
+0xBDD7 0x8AD6 #CJK UNIFIED IDEOGRAPH
+0xBDD8 0x8ACD #CJK UNIFIED IDEOGRAPH
+0xBDD9 0x8AB6 #CJK UNIFIED IDEOGRAPH
+0xBDDA 0x8AB9 #CJK UNIFIED IDEOGRAPH
+0xBDDB 0x8ADB #CJK UNIFIED IDEOGRAPH
+0xBDDC 0x8C4C #CJK UNIFIED IDEOGRAPH
+0xBDDD 0x8C4E #CJK UNIFIED IDEOGRAPH
+0xBDDE 0x8C6C #CJK UNIFIED IDEOGRAPH
+0xBDDF 0x8CE0 #CJK UNIFIED IDEOGRAPH
+0xBDE0 0x8CDE #CJK UNIFIED IDEOGRAPH
+0xBDE1 0x8CE6 #CJK UNIFIED IDEOGRAPH
+0xBDE2 0x8CE4 #CJK UNIFIED IDEOGRAPH
+0xBDE3 0x8CEC #CJK UNIFIED IDEOGRAPH
+0xBDE4 0x8CED #CJK UNIFIED IDEOGRAPH
+0xBDE5 0x8CE2 #CJK UNIFIED IDEOGRAPH
+0xBDE6 0x8CE3 #CJK UNIFIED IDEOGRAPH
+0xBDE7 0x8CDC #CJK UNIFIED IDEOGRAPH
+0xBDE8 0x8CEA #CJK UNIFIED IDEOGRAPH
+0xBDE9 0x8CE1 #CJK UNIFIED IDEOGRAPH
+0xBDEA 0x8D6D #CJK UNIFIED IDEOGRAPH
+0xBDEB 0x8D9F #CJK UNIFIED IDEOGRAPH
+0xBDEC 0x8DA3 #CJK UNIFIED IDEOGRAPH
+0xBDED 0x8E2B #CJK UNIFIED IDEOGRAPH
+0xBDEE 0x8E10 #CJK UNIFIED IDEOGRAPH
+0xBDEF 0x8E1D #CJK UNIFIED IDEOGRAPH
+0xBDF0 0x8E22 #CJK UNIFIED IDEOGRAPH
+0xBDF1 0x8E0F #CJK UNIFIED IDEOGRAPH
+0xBDF2 0x8E29 #CJK UNIFIED IDEOGRAPH
+0xBDF3 0x8E1F #CJK UNIFIED IDEOGRAPH
+0xBDF4 0x8E21 #CJK UNIFIED IDEOGRAPH
+0xBDF5 0x8E1E #CJK UNIFIED IDEOGRAPH
+0xBDF6 0x8EBA #CJK UNIFIED IDEOGRAPH
+0xBDF7 0x8F1D #CJK UNIFIED IDEOGRAPH
+0xBDF8 0x8F1B #CJK UNIFIED IDEOGRAPH
+0xBDF9 0x8F1F #CJK UNIFIED IDEOGRAPH
+0xBDFA 0x8F29 #CJK UNIFIED IDEOGRAPH
+0xBDFB 0x8F26 #CJK UNIFIED IDEOGRAPH
+0xBDFC 0x8F2A #CJK UNIFIED IDEOGRAPH
+0xBDFD 0x8F1C #CJK UNIFIED IDEOGRAPH
+0xBDFE 0x8F1E #CJK UNIFIED IDEOGRAPH
+0xBE40 0x8F25 #CJK UNIFIED IDEOGRAPH
+0xBE41 0x9069 #CJK UNIFIED IDEOGRAPH
+0xBE42 0x906E #CJK UNIFIED IDEOGRAPH
+0xBE43 0x9068 #CJK UNIFIED IDEOGRAPH
+0xBE44 0x906D #CJK UNIFIED IDEOGRAPH
+0xBE45 0x9077 #CJK UNIFIED IDEOGRAPH
+0xBE46 0x9130 #CJK UNIFIED IDEOGRAPH
+0xBE47 0x912D #CJK UNIFIED IDEOGRAPH
+0xBE48 0x9127 #CJK UNIFIED IDEOGRAPH
+0xBE49 0x9131 #CJK UNIFIED IDEOGRAPH
+0xBE4A 0x9187 #CJK UNIFIED IDEOGRAPH
+0xBE4B 0x9189 #CJK UNIFIED IDEOGRAPH
+0xBE4C 0x918B #CJK UNIFIED IDEOGRAPH
+0xBE4D 0x9183 #CJK UNIFIED IDEOGRAPH
+0xBE4E 0x92C5 #CJK UNIFIED IDEOGRAPH
+0xBE4F 0x92BB #CJK UNIFIED IDEOGRAPH
+0xBE50 0x92B7 #CJK UNIFIED IDEOGRAPH
+0xBE51 0x92EA #CJK UNIFIED IDEOGRAPH
+0xBE52 0x92AC #CJK UNIFIED IDEOGRAPH
+0xBE53 0x92E4 #CJK UNIFIED IDEOGRAPH
+0xBE54 0x92C1 #CJK UNIFIED IDEOGRAPH
+0xBE55 0x92B3 #CJK UNIFIED IDEOGRAPH
+0xBE56 0x92BC #CJK UNIFIED IDEOGRAPH
+0xBE57 0x92D2 #CJK UNIFIED IDEOGRAPH
+0xBE58 0x92C7 #CJK UNIFIED IDEOGRAPH
+0xBE59 0x92F0 #CJK UNIFIED IDEOGRAPH
+0xBE5A 0x92B2 #CJK UNIFIED IDEOGRAPH
+0xBE5B 0x95AD #CJK UNIFIED IDEOGRAPH
+0xBE5C 0x95B1 #CJK UNIFIED IDEOGRAPH
+0xBE5D 0x9704 #CJK UNIFIED IDEOGRAPH
+0xBE5E 0x9706 #CJK UNIFIED IDEOGRAPH
+0xBE5F 0x9707 #CJK UNIFIED IDEOGRAPH
+0xBE60 0x9709 #CJK UNIFIED IDEOGRAPH
+0xBE61 0x9760 #CJK UNIFIED IDEOGRAPH
+0xBE62 0x978D #CJK UNIFIED IDEOGRAPH
+0xBE63 0x978B #CJK UNIFIED IDEOGRAPH
+0xBE64 0x978F #CJK UNIFIED IDEOGRAPH
+0xBE65 0x9821 #CJK UNIFIED IDEOGRAPH
+0xBE66 0x982B #CJK UNIFIED IDEOGRAPH
+0xBE67 0x981C #CJK UNIFIED IDEOGRAPH
+0xBE68 0x98B3 #CJK UNIFIED IDEOGRAPH
+0xBE69 0x990A #CJK UNIFIED IDEOGRAPH
+0xBE6A 0x9913 #CJK UNIFIED IDEOGRAPH
+0xBE6B 0x9912 #CJK UNIFIED IDEOGRAPH
+0xBE6C 0x9918 #CJK UNIFIED IDEOGRAPH
+0xBE6D 0x99DD #CJK UNIFIED IDEOGRAPH
+0xBE6E 0x99D0 #CJK UNIFIED IDEOGRAPH
+0xBE6F 0x99DF #CJK UNIFIED IDEOGRAPH
+0xBE70 0x99DB #CJK UNIFIED IDEOGRAPH
+0xBE71 0x99D1 #CJK UNIFIED IDEOGRAPH
+0xBE72 0x99D5 #CJK UNIFIED IDEOGRAPH
+0xBE73 0x99D2 #CJK UNIFIED IDEOGRAPH
+0xBE74 0x99D9 #CJK UNIFIED IDEOGRAPH
+0xBE75 0x9AB7 #CJK UNIFIED IDEOGRAPH
+0xBE76 0x9AEE #CJK UNIFIED IDEOGRAPH
+0xBE77 0x9AEF #CJK UNIFIED IDEOGRAPH
+0xBE78 0x9B27 #CJK UNIFIED IDEOGRAPH
+0xBE79 0x9B45 #CJK UNIFIED IDEOGRAPH
+0xBE7A 0x9B44 #CJK UNIFIED IDEOGRAPH
+0xBE7B 0x9B77 #CJK UNIFIED IDEOGRAPH
+0xBE7C 0x9B6F #CJK UNIFIED IDEOGRAPH
+0xBE7D 0x9D06 #CJK UNIFIED IDEOGRAPH
+0xBE7E 0x9D09 #CJK UNIFIED IDEOGRAPH
+0xBEA1 0x9D03 #CJK UNIFIED IDEOGRAPH
+0xBEA2 0x9EA9 #CJK UNIFIED IDEOGRAPH
+0xBEA3 0x9EBE #CJK UNIFIED IDEOGRAPH
+0xBEA4 0x9ECE #CJK UNIFIED IDEOGRAPH
+0xBEA5 0x58A8 #CJK UNIFIED IDEOGRAPH
+0xBEA6 0x9F52 #CJK UNIFIED IDEOGRAPH
+0xBEA7 0x5112 #CJK UNIFIED IDEOGRAPH
+0xBEA8 0x5118 #CJK UNIFIED IDEOGRAPH
+0xBEA9 0x5114 #CJK UNIFIED IDEOGRAPH
+0xBEAA 0x5110 #CJK UNIFIED IDEOGRAPH
+0xBEAB 0x5115 #CJK UNIFIED IDEOGRAPH
+0xBEAC 0x5180 #CJK UNIFIED IDEOGRAPH
+0xBEAD 0x51AA #CJK UNIFIED IDEOGRAPH
+0xBEAE 0x51DD #CJK UNIFIED IDEOGRAPH
+0xBEAF 0x5291 #CJK UNIFIED IDEOGRAPH
+0xBEB0 0x5293 #CJK UNIFIED IDEOGRAPH
+0xBEB1 0x52F3 #CJK UNIFIED IDEOGRAPH
+0xBEB2 0x5659 #CJK UNIFIED IDEOGRAPH
+0xBEB3 0x566B #CJK UNIFIED IDEOGRAPH
+0xBEB4 0x5679 #CJK UNIFIED IDEOGRAPH
+0xBEB5 0x5669 #CJK UNIFIED IDEOGRAPH
+0xBEB6 0x5664 #CJK UNIFIED IDEOGRAPH
+0xBEB7 0x5678 #CJK UNIFIED IDEOGRAPH
+0xBEB8 0x566A #CJK UNIFIED IDEOGRAPH
+0xBEB9 0x5668 #CJK UNIFIED IDEOGRAPH
+0xBEBA 0x5665 #CJK UNIFIED IDEOGRAPH
+0xBEBB 0x5671 #CJK UNIFIED IDEOGRAPH
+0xBEBC 0x566F #CJK UNIFIED IDEOGRAPH
+0xBEBD 0x566C #CJK UNIFIED IDEOGRAPH
+0xBEBE 0x5662 #CJK UNIFIED IDEOGRAPH
+0xBEBF 0x5676 #CJK UNIFIED IDEOGRAPH
+0xBEC0 0x58C1 #CJK UNIFIED IDEOGRAPH
+0xBEC1 0x58BE #CJK UNIFIED IDEOGRAPH
+0xBEC2 0x58C7 #CJK UNIFIED IDEOGRAPH
+0xBEC3 0x58C5 #CJK UNIFIED IDEOGRAPH
+0xBEC4 0x596E #CJK UNIFIED IDEOGRAPH
+0xBEC5 0x5B1D #CJK UNIFIED IDEOGRAPH
+0xBEC6 0x5B34 #CJK UNIFIED IDEOGRAPH
+0xBEC7 0x5B78 #CJK UNIFIED IDEOGRAPH
+0xBEC8 0x5BF0 #CJK UNIFIED IDEOGRAPH
+0xBEC9 0x5C0E #CJK UNIFIED IDEOGRAPH
+0xBECA 0x5F4A #CJK UNIFIED IDEOGRAPH
+0xBECB 0x61B2 #CJK UNIFIED IDEOGRAPH
+0xBECC 0x6191 #CJK UNIFIED IDEOGRAPH
+0xBECD 0x61A9 #CJK UNIFIED IDEOGRAPH
+0xBECE 0x618A #CJK UNIFIED IDEOGRAPH
+0xBECF 0x61CD #CJK UNIFIED IDEOGRAPH
+0xBED0 0x61B6 #CJK UNIFIED IDEOGRAPH
+0xBED1 0x61BE #CJK UNIFIED IDEOGRAPH
+0xBED2 0x61CA #CJK UNIFIED IDEOGRAPH
+0xBED3 0x61C8 #CJK UNIFIED IDEOGRAPH
+0xBED4 0x6230 #CJK UNIFIED IDEOGRAPH
+0xBED5 0x64C5 #CJK UNIFIED IDEOGRAPH
+0xBED6 0x64C1 #CJK UNIFIED IDEOGRAPH
+0xBED7 0x64CB #CJK UNIFIED IDEOGRAPH
+0xBED8 0x64BB #CJK UNIFIED IDEOGRAPH
+0xBED9 0x64BC #CJK UNIFIED IDEOGRAPH
+0xBEDA 0x64DA #CJK UNIFIED IDEOGRAPH
+0xBEDB 0x64C4 #CJK UNIFIED IDEOGRAPH
+0xBEDC 0x64C7 #CJK UNIFIED IDEOGRAPH
+0xBEDD 0x64C2 #CJK UNIFIED IDEOGRAPH
+0xBEDE 0x64CD #CJK UNIFIED IDEOGRAPH
+0xBEDF 0x64BF #CJK UNIFIED IDEOGRAPH
+0xBEE0 0x64D2 #CJK UNIFIED IDEOGRAPH
+0xBEE1 0x64D4 #CJK UNIFIED IDEOGRAPH
+0xBEE2 0x64BE #CJK UNIFIED IDEOGRAPH
+0xBEE3 0x6574 #CJK UNIFIED IDEOGRAPH
+0xBEE4 0x66C6 #CJK UNIFIED IDEOGRAPH
+0xBEE5 0x66C9 #CJK UNIFIED IDEOGRAPH
+0xBEE6 0x66B9 #CJK UNIFIED IDEOGRAPH
+0xBEE7 0x66C4 #CJK UNIFIED IDEOGRAPH
+0xBEE8 0x66C7 #CJK UNIFIED IDEOGRAPH
+0xBEE9 0x66B8 #CJK UNIFIED IDEOGRAPH
+0xBEEA 0x6A3D #CJK UNIFIED IDEOGRAPH
+0xBEEB 0x6A38 #CJK UNIFIED IDEOGRAPH
+0xBEEC 0x6A3A #CJK UNIFIED IDEOGRAPH
+0xBEED 0x6A59 #CJK UNIFIED IDEOGRAPH
+0xBEEE 0x6A6B #CJK UNIFIED IDEOGRAPH
+0xBEEF 0x6A58 #CJK UNIFIED IDEOGRAPH
+0xBEF0 0x6A39 #CJK UNIFIED IDEOGRAPH
+0xBEF1 0x6A44 #CJK UNIFIED IDEOGRAPH
+0xBEF2 0x6A62 #CJK UNIFIED IDEOGRAPH
+0xBEF3 0x6A61 #CJK UNIFIED IDEOGRAPH
+0xBEF4 0x6A4B #CJK UNIFIED IDEOGRAPH
+0xBEF5 0x6A47 #CJK UNIFIED IDEOGRAPH
+0xBEF6 0x6A35 #CJK UNIFIED IDEOGRAPH
+0xBEF7 0x6A5F #CJK UNIFIED IDEOGRAPH
+0xBEF8 0x6A48 #CJK UNIFIED IDEOGRAPH
+0xBEF9 0x6B59 #CJK UNIFIED IDEOGRAPH
+0xBEFA 0x6B77 #CJK UNIFIED IDEOGRAPH
+0xBEFB 0x6C05 #CJK UNIFIED IDEOGRAPH
+0xBEFC 0x6FC2 #CJK UNIFIED IDEOGRAPH
+0xBEFD 0x6FB1 #CJK UNIFIED IDEOGRAPH
+0xBEFE 0x6FA1 #CJK UNIFIED IDEOGRAPH
+0xBF40 0x6FC3 #CJK UNIFIED IDEOGRAPH
+0xBF41 0x6FA4 #CJK UNIFIED IDEOGRAPH
+0xBF42 0x6FC1 #CJK UNIFIED IDEOGRAPH
+0xBF43 0x6FA7 #CJK UNIFIED IDEOGRAPH
+0xBF44 0x6FB3 #CJK UNIFIED IDEOGRAPH
+0xBF45 0x6FC0 #CJK UNIFIED IDEOGRAPH
+0xBF46 0x6FB9 #CJK UNIFIED IDEOGRAPH
+0xBF47 0x6FB6 #CJK UNIFIED IDEOGRAPH
+0xBF48 0x6FA6 #CJK UNIFIED IDEOGRAPH
+0xBF49 0x6FA0 #CJK UNIFIED IDEOGRAPH
+0xBF4A 0x6FB4 #CJK UNIFIED IDEOGRAPH
+0xBF4B 0x71BE #CJK UNIFIED IDEOGRAPH
+0xBF4C 0x71C9 #CJK UNIFIED IDEOGRAPH
+0xBF4D 0x71D0 #CJK UNIFIED IDEOGRAPH
+0xBF4E 0x71D2 #CJK UNIFIED IDEOGRAPH
+0xBF4F 0x71C8 #CJK UNIFIED IDEOGRAPH
+0xBF50 0x71D5 #CJK UNIFIED IDEOGRAPH
+0xBF51 0x71B9 #CJK UNIFIED IDEOGRAPH
+0xBF52 0x71CE #CJK UNIFIED IDEOGRAPH
+0xBF53 0x71D9 #CJK UNIFIED IDEOGRAPH
+0xBF54 0x71DC #CJK UNIFIED IDEOGRAPH
+0xBF55 0x71C3 #CJK UNIFIED IDEOGRAPH
+0xBF56 0x71C4 #CJK UNIFIED IDEOGRAPH
+0xBF57 0x7368 #CJK UNIFIED IDEOGRAPH
+0xBF58 0x749C #CJK UNIFIED IDEOGRAPH
+0xBF59 0x74A3 #CJK UNIFIED IDEOGRAPH
+0xBF5A 0x7498 #CJK UNIFIED IDEOGRAPH
+0xBF5B 0x749F #CJK UNIFIED IDEOGRAPH
+0xBF5C 0x749E #CJK UNIFIED IDEOGRAPH
+0xBF5D 0x74E2 #CJK UNIFIED IDEOGRAPH
+0xBF5E 0x750C #CJK UNIFIED IDEOGRAPH
+0xBF5F 0x750D #CJK UNIFIED IDEOGRAPH
+0xBF60 0x7634 #CJK UNIFIED IDEOGRAPH
+0xBF61 0x7638 #CJK UNIFIED IDEOGRAPH
+0xBF62 0x763A #CJK UNIFIED IDEOGRAPH
+0xBF63 0x76E7 #CJK UNIFIED IDEOGRAPH
+0xBF64 0x76E5 #CJK UNIFIED IDEOGRAPH
+0xBF65 0x77A0 #CJK UNIFIED IDEOGRAPH
+0xBF66 0x779E #CJK UNIFIED IDEOGRAPH
+0xBF67 0x779F #CJK UNIFIED IDEOGRAPH
+0xBF68 0x77A5 #CJK UNIFIED IDEOGRAPH
+0xBF69 0x78E8 #CJK UNIFIED IDEOGRAPH
+0xBF6A 0x78DA #CJK UNIFIED IDEOGRAPH
+0xBF6B 0x78EC #CJK UNIFIED IDEOGRAPH
+0xBF6C 0x78E7 #CJK UNIFIED IDEOGRAPH
+0xBF6D 0x79A6 #CJK UNIFIED IDEOGRAPH
+0xBF6E 0x7A4D #CJK UNIFIED IDEOGRAPH
+0xBF6F 0x7A4E #CJK UNIFIED IDEOGRAPH
+0xBF70 0x7A46 #CJK UNIFIED IDEOGRAPH
+0xBF71 0x7A4C #CJK UNIFIED IDEOGRAPH
+0xBF72 0x7A4B #CJK UNIFIED IDEOGRAPH
+0xBF73 0x7ABA #CJK UNIFIED IDEOGRAPH
+0xBF74 0x7BD9 #CJK UNIFIED IDEOGRAPH
+0xBF75 0x7C11 #CJK UNIFIED IDEOGRAPH
+0xBF76 0x7BC9 #CJK UNIFIED IDEOGRAPH
+0xBF77 0x7BE4 #CJK UNIFIED IDEOGRAPH
+0xBF78 0x7BDB #CJK UNIFIED IDEOGRAPH
+0xBF79 0x7BE1 #CJK UNIFIED IDEOGRAPH
+0xBF7A 0x7BE9 #CJK UNIFIED IDEOGRAPH
+0xBF7B 0x7BE6 #CJK UNIFIED IDEOGRAPH
+0xBF7C 0x7CD5 #CJK UNIFIED IDEOGRAPH
+0xBF7D 0x7CD6 #CJK UNIFIED IDEOGRAPH
+0xBF7E 0x7E0A #CJK UNIFIED IDEOGRAPH
+0xBFA1 0x7E11 #CJK UNIFIED IDEOGRAPH
+0xBFA2 0x7E08 #CJK UNIFIED IDEOGRAPH
+0xBFA3 0x7E1B #CJK UNIFIED IDEOGRAPH
+0xBFA4 0x7E23 #CJK UNIFIED IDEOGRAPH
+0xBFA5 0x7E1E #CJK UNIFIED IDEOGRAPH
+0xBFA6 0x7E1D #CJK UNIFIED IDEOGRAPH
+0xBFA7 0x7E09 #CJK UNIFIED IDEOGRAPH
+0xBFA8 0x7E10 #CJK UNIFIED IDEOGRAPH
+0xBFA9 0x7F79 #CJK UNIFIED IDEOGRAPH
+0xBFAA 0x7FB2 #CJK UNIFIED IDEOGRAPH
+0xBFAB 0x7FF0 #CJK UNIFIED IDEOGRAPH
+0xBFAC 0x7FF1 #CJK UNIFIED IDEOGRAPH
+0xBFAD 0x7FEE #CJK UNIFIED IDEOGRAPH
+0xBFAE 0x8028 #CJK UNIFIED IDEOGRAPH
+0xBFAF 0x81B3 #CJK UNIFIED IDEOGRAPH
+0xBFB0 0x81A9 #CJK UNIFIED IDEOGRAPH
+0xBFB1 0x81A8 #CJK UNIFIED IDEOGRAPH
+0xBFB2 0x81FB #CJK UNIFIED IDEOGRAPH
+0xBFB3 0x8208 #CJK UNIFIED IDEOGRAPH
+0xBFB4 0x8258 #CJK UNIFIED IDEOGRAPH
+0xBFB5 0x8259 #CJK UNIFIED IDEOGRAPH
+0xBFB6 0x854A #CJK UNIFIED IDEOGRAPH
+0xBFB7 0x8559 #CJK UNIFIED IDEOGRAPH
+0xBFB8 0x8548 #CJK UNIFIED IDEOGRAPH
+0xBFB9 0x8568 #CJK UNIFIED IDEOGRAPH
+0xBFBA 0x8569 #CJK UNIFIED IDEOGRAPH
+0xBFBB 0x8543 #CJK UNIFIED IDEOGRAPH
+0xBFBC 0x8549 #CJK UNIFIED IDEOGRAPH
+0xBFBD 0x856D #CJK UNIFIED IDEOGRAPH
+0xBFBE 0x856A #CJK UNIFIED IDEOGRAPH
+0xBFBF 0x855E #CJK UNIFIED IDEOGRAPH
+0xBFC0 0x8783 #CJK UNIFIED IDEOGRAPH
+0xBFC1 0x879F #CJK UNIFIED IDEOGRAPH
+0xBFC2 0x879E #CJK UNIFIED IDEOGRAPH
+0xBFC3 0x87A2 #CJK UNIFIED IDEOGRAPH
+0xBFC4 0x878D #CJK UNIFIED IDEOGRAPH
+0xBFC5 0x8861 #CJK UNIFIED IDEOGRAPH
+0xBFC6 0x892A #CJK UNIFIED IDEOGRAPH
+0xBFC7 0x8932 #CJK UNIFIED IDEOGRAPH
+0xBFC8 0x8925 #CJK UNIFIED IDEOGRAPH
+0xBFC9 0x892B #CJK UNIFIED IDEOGRAPH
+0xBFCA 0x8921 #CJK UNIFIED IDEOGRAPH
+0xBFCB 0x89AA #CJK UNIFIED IDEOGRAPH
+0xBFCC 0x89A6 #CJK UNIFIED IDEOGRAPH
+0xBFCD 0x8AE6 #CJK UNIFIED IDEOGRAPH
+0xBFCE 0x8AFA #CJK UNIFIED IDEOGRAPH
+0xBFCF 0x8AEB #CJK UNIFIED IDEOGRAPH
+0xBFD0 0x8AF1 #CJK UNIFIED IDEOGRAPH
+0xBFD1 0x8B00 #CJK UNIFIED IDEOGRAPH
+0xBFD2 0x8ADC #CJK UNIFIED IDEOGRAPH
+0xBFD3 0x8AE7 #CJK UNIFIED IDEOGRAPH
+0xBFD4 0x8AEE #CJK UNIFIED IDEOGRAPH
+0xBFD5 0x8AFE #CJK UNIFIED IDEOGRAPH
+0xBFD6 0x8B01 #CJK UNIFIED IDEOGRAPH
+0xBFD7 0x8B02 #CJK UNIFIED IDEOGRAPH
+0xBFD8 0x8AF7 #CJK UNIFIED IDEOGRAPH
+0xBFD9 0x8AED #CJK UNIFIED IDEOGRAPH
+0xBFDA 0x8AF3 #CJK UNIFIED IDEOGRAPH
+0xBFDB 0x8AF6 #CJK UNIFIED IDEOGRAPH
+0xBFDC 0x8AFC #CJK UNIFIED IDEOGRAPH
+0xBFDD 0x8C6B #CJK UNIFIED IDEOGRAPH
+0xBFDE 0x8C6D #CJK UNIFIED IDEOGRAPH
+0xBFDF 0x8C93 #CJK UNIFIED IDEOGRAPH
+0xBFE0 0x8CF4 #CJK UNIFIED IDEOGRAPH
+0xBFE1 0x8E44 #CJK UNIFIED IDEOGRAPH
+0xBFE2 0x8E31 #CJK UNIFIED IDEOGRAPH
+0xBFE3 0x8E34 #CJK UNIFIED IDEOGRAPH
+0xBFE4 0x8E42 #CJK UNIFIED IDEOGRAPH
+0xBFE5 0x8E39 #CJK UNIFIED IDEOGRAPH
+0xBFE6 0x8E35 #CJK UNIFIED IDEOGRAPH
+0xBFE7 0x8F3B #CJK UNIFIED IDEOGRAPH
+0xBFE8 0x8F2F #CJK UNIFIED IDEOGRAPH
+0xBFE9 0x8F38 #CJK UNIFIED IDEOGRAPH
+0xBFEA 0x8F33 #CJK UNIFIED IDEOGRAPH
+0xBFEB 0x8FA8 #CJK UNIFIED IDEOGRAPH
+0xBFEC 0x8FA6 #CJK UNIFIED IDEOGRAPH
+0xBFED 0x9075 #CJK UNIFIED IDEOGRAPH
+0xBFEE 0x9074 #CJK UNIFIED IDEOGRAPH
+0xBFEF 0x9078 #CJK UNIFIED IDEOGRAPH
+0xBFF0 0x9072 #CJK UNIFIED IDEOGRAPH
+0xBFF1 0x907C #CJK UNIFIED IDEOGRAPH
+0xBFF2 0x907A #CJK UNIFIED IDEOGRAPH
+0xBFF3 0x9134 #CJK UNIFIED IDEOGRAPH
+0xBFF4 0x9192 #CJK UNIFIED IDEOGRAPH
+0xBFF5 0x9320 #CJK UNIFIED IDEOGRAPH
+0xBFF6 0x9336 #CJK UNIFIED IDEOGRAPH
+0xBFF7 0x92F8 #CJK UNIFIED IDEOGRAPH
+0xBFF8 0x9333 #CJK UNIFIED IDEOGRAPH
+0xBFF9 0x932F #CJK UNIFIED IDEOGRAPH
+0xBFFA 0x9322 #CJK UNIFIED IDEOGRAPH
+0xBFFB 0x92FC #CJK UNIFIED IDEOGRAPH
+0xBFFC 0x932B #CJK UNIFIED IDEOGRAPH
+0xBFFD 0x9304 #CJK UNIFIED IDEOGRAPH
+0xBFFE 0x931A #CJK UNIFIED IDEOGRAPH
+0xC040 0x9310 #CJK UNIFIED IDEOGRAPH
+0xC041 0x9326 #CJK UNIFIED IDEOGRAPH
+0xC042 0x9321 #CJK UNIFIED IDEOGRAPH
+0xC043 0x9315 #CJK UNIFIED IDEOGRAPH
+0xC044 0x932E #CJK UNIFIED IDEOGRAPH
+0xC045 0x9319 #CJK UNIFIED IDEOGRAPH
+0xC046 0x95BB #CJK UNIFIED IDEOGRAPH
+0xC047 0x96A7 #CJK UNIFIED IDEOGRAPH
+0xC048 0x96A8 #CJK UNIFIED IDEOGRAPH
+0xC049 0x96AA #CJK UNIFIED IDEOGRAPH
+0xC04A 0x96D5 #CJK UNIFIED IDEOGRAPH
+0xC04B 0x970E #CJK UNIFIED IDEOGRAPH
+0xC04C 0x9711 #CJK UNIFIED IDEOGRAPH
+0xC04D 0x9716 #CJK UNIFIED IDEOGRAPH
+0xC04E 0x970D #CJK UNIFIED IDEOGRAPH
+0xC04F 0x9713 #CJK UNIFIED IDEOGRAPH
+0xC050 0x970F #CJK UNIFIED IDEOGRAPH
+0xC051 0x975B #CJK UNIFIED IDEOGRAPH
+0xC052 0x975C #CJK UNIFIED IDEOGRAPH
+0xC053 0x9766 #CJK UNIFIED IDEOGRAPH
+0xC054 0x9798 #CJK UNIFIED IDEOGRAPH
+0xC055 0x9830 #CJK UNIFIED IDEOGRAPH
+0xC056 0x9838 #CJK UNIFIED IDEOGRAPH
+0xC057 0x983B #CJK UNIFIED IDEOGRAPH
+0xC058 0x9837 #CJK UNIFIED IDEOGRAPH
+0xC059 0x982D #CJK UNIFIED IDEOGRAPH
+0xC05A 0x9839 #CJK UNIFIED IDEOGRAPH
+0xC05B 0x9824 #CJK UNIFIED IDEOGRAPH
+0xC05C 0x9910 #CJK UNIFIED IDEOGRAPH
+0xC05D 0x9928 #CJK UNIFIED IDEOGRAPH
+0xC05E 0x991E #CJK UNIFIED IDEOGRAPH
+0xC05F 0x991B #CJK UNIFIED IDEOGRAPH
+0xC060 0x9921 #CJK UNIFIED IDEOGRAPH
+0xC061 0x991A #CJK UNIFIED IDEOGRAPH
+0xC062 0x99ED #CJK UNIFIED IDEOGRAPH
+0xC063 0x99E2 #CJK UNIFIED IDEOGRAPH
+0xC064 0x99F1 #CJK UNIFIED IDEOGRAPH
+0xC065 0x9AB8 #CJK UNIFIED IDEOGRAPH
+0xC066 0x9ABC #CJK UNIFIED IDEOGRAPH
+0xC067 0x9AFB #CJK UNIFIED IDEOGRAPH
+0xC068 0x9AED #CJK UNIFIED IDEOGRAPH
+0xC069 0x9B28 #CJK UNIFIED IDEOGRAPH
+0xC06A 0x9B91 #CJK UNIFIED IDEOGRAPH
+0xC06B 0x9D15 #CJK UNIFIED IDEOGRAPH
+0xC06C 0x9D23 #CJK UNIFIED IDEOGRAPH
+0xC06D 0x9D26 #CJK UNIFIED IDEOGRAPH
+0xC06E 0x9D28 #CJK UNIFIED IDEOGRAPH
+0xC06F 0x9D12 #CJK UNIFIED IDEOGRAPH
+0xC070 0x9D1B #CJK UNIFIED IDEOGRAPH
+0xC071 0x9ED8 #CJK UNIFIED IDEOGRAPH
+0xC072 0x9ED4 #CJK UNIFIED IDEOGRAPH
+0xC073 0x9F8D #CJK UNIFIED IDEOGRAPH
+0xC074 0x9F9C #CJK UNIFIED IDEOGRAPH
+0xC075 0x512A #CJK UNIFIED IDEOGRAPH
+0xC076 0x511F #CJK UNIFIED IDEOGRAPH
+0xC077 0x5121 #CJK UNIFIED IDEOGRAPH
+0xC078 0x5132 #CJK UNIFIED IDEOGRAPH
+0xC079 0x52F5 #CJK UNIFIED IDEOGRAPH
+0xC07A 0x568E #CJK UNIFIED IDEOGRAPH
+0xC07B 0x5680 #CJK UNIFIED IDEOGRAPH
+0xC07C 0x5690 #CJK UNIFIED IDEOGRAPH
+0xC07D 0x5685 #CJK UNIFIED IDEOGRAPH
+0xC07E 0x5687 #CJK UNIFIED IDEOGRAPH
+0xC0A1 0x568F #CJK UNIFIED IDEOGRAPH
+0xC0A2 0x58D5 #CJK UNIFIED IDEOGRAPH
+0xC0A3 0x58D3 #CJK UNIFIED IDEOGRAPH
+0xC0A4 0x58D1 #CJK UNIFIED IDEOGRAPH
+0xC0A5 0x58CE #CJK UNIFIED IDEOGRAPH
+0xC0A6 0x5B30 #CJK UNIFIED IDEOGRAPH
+0xC0A7 0x5B2A #CJK UNIFIED IDEOGRAPH
+0xC0A8 0x5B24 #CJK UNIFIED IDEOGRAPH
+0xC0A9 0x5B7A #CJK UNIFIED IDEOGRAPH
+0xC0AA 0x5C37 #CJK UNIFIED IDEOGRAPH
+0xC0AB 0x5C68 #CJK UNIFIED IDEOGRAPH
+0xC0AC 0x5DBC #CJK UNIFIED IDEOGRAPH
+0xC0AD 0x5DBA #CJK UNIFIED IDEOGRAPH
+0xC0AE 0x5DBD #CJK UNIFIED IDEOGRAPH
+0xC0AF 0x5DB8 #CJK UNIFIED IDEOGRAPH
+0xC0B0 0x5E6B #CJK UNIFIED IDEOGRAPH
+0xC0B1 0x5F4C #CJK UNIFIED IDEOGRAPH
+0xC0B2 0x5FBD #CJK UNIFIED IDEOGRAPH
+0xC0B3 0x61C9 #CJK UNIFIED IDEOGRAPH
+0xC0B4 0x61C2 #CJK UNIFIED IDEOGRAPH
+0xC0B5 0x61C7 #CJK UNIFIED IDEOGRAPH
+0xC0B6 0x61E6 #CJK UNIFIED IDEOGRAPH
+0xC0B7 0x61CB #CJK UNIFIED IDEOGRAPH
+0xC0B8 0x6232 #CJK UNIFIED IDEOGRAPH
+0xC0B9 0x6234 #CJK UNIFIED IDEOGRAPH
+0xC0BA 0x64CE #CJK UNIFIED IDEOGRAPH
+0xC0BB 0x64CA #CJK UNIFIED IDEOGRAPH
+0xC0BC 0x64D8 #CJK UNIFIED IDEOGRAPH
+0xC0BD 0x64E0 #CJK UNIFIED IDEOGRAPH
+0xC0BE 0x64F0 #CJK UNIFIED IDEOGRAPH
+0xC0BF 0x64E6 #CJK UNIFIED IDEOGRAPH
+0xC0C0 0x64EC #CJK UNIFIED IDEOGRAPH
+0xC0C1 0x64F1 #CJK UNIFIED IDEOGRAPH
+0xC0C2 0x64E2 #CJK UNIFIED IDEOGRAPH
+0xC0C3 0x64ED #CJK UNIFIED IDEOGRAPH
+0xC0C4 0x6582 #CJK UNIFIED IDEOGRAPH
+0xC0C5 0x6583 #CJK UNIFIED IDEOGRAPH
+0xC0C6 0x66D9 #CJK UNIFIED IDEOGRAPH
+0xC0C7 0x66D6 #CJK UNIFIED IDEOGRAPH
+0xC0C8 0x6A80 #CJK UNIFIED IDEOGRAPH
+0xC0C9 0x6A94 #CJK UNIFIED IDEOGRAPH
+0xC0CA 0x6A84 #CJK UNIFIED IDEOGRAPH
+0xC0CB 0x6AA2 #CJK UNIFIED IDEOGRAPH
+0xC0CC 0x6A9C #CJK UNIFIED IDEOGRAPH
+0xC0CD 0x6ADB #CJK UNIFIED IDEOGRAPH
+0xC0CE 0x6AA3 #CJK UNIFIED IDEOGRAPH
+0xC0CF 0x6A7E #CJK UNIFIED IDEOGRAPH
+0xC0D0 0x6A97 #CJK UNIFIED IDEOGRAPH
+0xC0D1 0x6A90 #CJK UNIFIED IDEOGRAPH
+0xC0D2 0x6AA0 #CJK UNIFIED IDEOGRAPH
+0xC0D3 0x6B5C #CJK UNIFIED IDEOGRAPH
+0xC0D4 0x6BAE #CJK UNIFIED IDEOGRAPH
+0xC0D5 0x6BDA #CJK UNIFIED IDEOGRAPH
+0xC0D6 0x6C08 #CJK UNIFIED IDEOGRAPH
+0xC0D7 0x6FD8 #CJK UNIFIED IDEOGRAPH
+0xC0D8 0x6FF1 #CJK UNIFIED IDEOGRAPH
+0xC0D9 0x6FDF #CJK UNIFIED IDEOGRAPH
+0xC0DA 0x6FE0 #CJK UNIFIED IDEOGRAPH
+0xC0DB 0x6FDB #CJK UNIFIED IDEOGRAPH
+0xC0DC 0x6FE4 #CJK UNIFIED IDEOGRAPH
+0xC0DD 0x6FEB #CJK UNIFIED IDEOGRAPH
+0xC0DE 0x6FEF #CJK UNIFIED IDEOGRAPH
+0xC0DF 0x6F80 #CJK UNIFIED IDEOGRAPH
+0xC0E0 0x6FEC #CJK UNIFIED IDEOGRAPH
+0xC0E1 0x6FE1 #CJK UNIFIED IDEOGRAPH
+0xC0E2 0x6FE9 #CJK UNIFIED IDEOGRAPH
+0xC0E3 0x6FD5 #CJK UNIFIED IDEOGRAPH
+0xC0E4 0x6FEE #CJK UNIFIED IDEOGRAPH
+0xC0E5 0x6FF0 #CJK UNIFIED IDEOGRAPH
+0xC0E6 0x71E7 #CJK UNIFIED IDEOGRAPH
+0xC0E7 0x71DF #CJK UNIFIED IDEOGRAPH
+0xC0E8 0x71EE #CJK UNIFIED IDEOGRAPH
+0xC0E9 0x71E6 #CJK UNIFIED IDEOGRAPH
+0xC0EA 0x71E5 #CJK UNIFIED IDEOGRAPH
+0xC0EB 0x71ED #CJK UNIFIED IDEOGRAPH
+0xC0EC 0x71EC #CJK UNIFIED IDEOGRAPH
+0xC0ED 0x71F4 #CJK UNIFIED IDEOGRAPH
+0xC0EE 0x71E0 #CJK UNIFIED IDEOGRAPH
+0xC0EF 0x7235 #CJK UNIFIED IDEOGRAPH
+0xC0F0 0x7246 #CJK UNIFIED IDEOGRAPH
+0xC0F1 0x7370 #CJK UNIFIED IDEOGRAPH
+0xC0F2 0x7372 #CJK UNIFIED IDEOGRAPH
+0xC0F3 0x74A9 #CJK UNIFIED IDEOGRAPH
+0xC0F4 0x74B0 #CJK UNIFIED IDEOGRAPH
+0xC0F5 0x74A6 #CJK UNIFIED IDEOGRAPH
+0xC0F6 0x74A8 #CJK UNIFIED IDEOGRAPH
+0xC0F7 0x7646 #CJK UNIFIED IDEOGRAPH
+0xC0F8 0x7642 #CJK UNIFIED IDEOGRAPH
+0xC0F9 0x764C #CJK UNIFIED IDEOGRAPH
+0xC0FA 0x76EA #CJK UNIFIED IDEOGRAPH
+0xC0FB 0x77B3 #CJK UNIFIED IDEOGRAPH
+0xC0FC 0x77AA #CJK UNIFIED IDEOGRAPH
+0xC0FD 0x77B0 #CJK UNIFIED IDEOGRAPH
+0xC0FE 0x77AC #CJK UNIFIED IDEOGRAPH
+0xC140 0x77A7 #CJK UNIFIED IDEOGRAPH
+0xC141 0x77AD #CJK UNIFIED IDEOGRAPH
+0xC142 0x77EF #CJK UNIFIED IDEOGRAPH
+0xC143 0x78F7 #CJK UNIFIED IDEOGRAPH
+0xC144 0x78FA #CJK UNIFIED IDEOGRAPH
+0xC145 0x78F4 #CJK UNIFIED IDEOGRAPH
+0xC146 0x78EF #CJK UNIFIED IDEOGRAPH
+0xC147 0x7901 #CJK UNIFIED IDEOGRAPH
+0xC148 0x79A7 #CJK UNIFIED IDEOGRAPH
+0xC149 0x79AA #CJK UNIFIED IDEOGRAPH
+0xC14A 0x7A57 #CJK UNIFIED IDEOGRAPH
+0xC14B 0x7ABF #CJK UNIFIED IDEOGRAPH
+0xC14C 0x7C07 #CJK UNIFIED IDEOGRAPH
+0xC14D 0x7C0D #CJK UNIFIED IDEOGRAPH
+0xC14E 0x7BFE #CJK UNIFIED IDEOGRAPH
+0xC14F 0x7BF7 #CJK UNIFIED IDEOGRAPH
+0xC150 0x7C0C #CJK UNIFIED IDEOGRAPH
+0xC151 0x7BE0 #CJK UNIFIED IDEOGRAPH
+0xC152 0x7CE0 #CJK UNIFIED IDEOGRAPH
+0xC153 0x7CDC #CJK UNIFIED IDEOGRAPH
+0xC154 0x7CDE #CJK UNIFIED IDEOGRAPH
+0xC155 0x7CE2 #CJK UNIFIED IDEOGRAPH
+0xC156 0x7CDF #CJK UNIFIED IDEOGRAPH
+0xC157 0x7CD9 #CJK UNIFIED IDEOGRAPH
+0xC158 0x7CDD #CJK UNIFIED IDEOGRAPH
+0xC159 0x7E2E #CJK UNIFIED IDEOGRAPH
+0xC15A 0x7E3E #CJK UNIFIED IDEOGRAPH
+0xC15B 0x7E46 #CJK UNIFIED IDEOGRAPH
+0xC15C 0x7E37 #CJK UNIFIED IDEOGRAPH
+0xC15D 0x7E32 #CJK UNIFIED IDEOGRAPH
+0xC15E 0x7E43 #CJK UNIFIED IDEOGRAPH
+0xC15F 0x7E2B #CJK UNIFIED IDEOGRAPH
+0xC160 0x7E3D #CJK UNIFIED IDEOGRAPH
+0xC161 0x7E31 #CJK UNIFIED IDEOGRAPH
+0xC162 0x7E45 #CJK UNIFIED IDEOGRAPH
+0xC163 0x7E41 #CJK UNIFIED IDEOGRAPH
+0xC164 0x7E34 #CJK UNIFIED IDEOGRAPH
+0xC165 0x7E39 #CJK UNIFIED IDEOGRAPH
+0xC166 0x7E48 #CJK UNIFIED IDEOGRAPH
+0xC167 0x7E35 #CJK UNIFIED IDEOGRAPH
+0xC168 0x7E3F #CJK UNIFIED IDEOGRAPH
+0xC169 0x7E2F #CJK UNIFIED IDEOGRAPH
+0xC16A 0x7F44 #CJK UNIFIED IDEOGRAPH
+0xC16B 0x7FF3 #CJK UNIFIED IDEOGRAPH
+0xC16C 0x7FFC #CJK UNIFIED IDEOGRAPH
+0xC16D 0x8071 #CJK UNIFIED IDEOGRAPH
+0xC16E 0x8072 #CJK UNIFIED IDEOGRAPH
+0xC16F 0x8070 #CJK UNIFIED IDEOGRAPH
+0xC170 0x806F #CJK UNIFIED IDEOGRAPH
+0xC171 0x8073 #CJK UNIFIED IDEOGRAPH
+0xC172 0x81C6 #CJK UNIFIED IDEOGRAPH
+0xC173 0x81C3 #CJK UNIFIED IDEOGRAPH
+0xC174 0x81BA #CJK UNIFIED IDEOGRAPH
+0xC175 0x81C2 #CJK UNIFIED IDEOGRAPH
+0xC176 0x81C0 #CJK UNIFIED IDEOGRAPH
+0xC177 0x81BF #CJK UNIFIED IDEOGRAPH
+0xC178 0x81BD #CJK UNIFIED IDEOGRAPH
+0xC179 0x81C9 #CJK UNIFIED IDEOGRAPH
+0xC17A 0x81BE #CJK UNIFIED IDEOGRAPH
+0xC17B 0x81E8 #CJK UNIFIED IDEOGRAPH
+0xC17C 0x8209 #CJK UNIFIED IDEOGRAPH
+0xC17D 0x8271 #CJK UNIFIED IDEOGRAPH
+0xC17E 0x85AA #CJK UNIFIED IDEOGRAPH
+0xC1A1 0x8584 #CJK UNIFIED IDEOGRAPH
+0xC1A2 0x857E #CJK UNIFIED IDEOGRAPH
+0xC1A3 0x859C #CJK UNIFIED IDEOGRAPH
+0xC1A4 0x8591 #CJK UNIFIED IDEOGRAPH
+0xC1A5 0x8594 #CJK UNIFIED IDEOGRAPH
+0xC1A6 0x85AF #CJK UNIFIED IDEOGRAPH
+0xC1A7 0x859B #CJK UNIFIED IDEOGRAPH
+0xC1A8 0x8587 #CJK UNIFIED IDEOGRAPH
+0xC1A9 0x85A8 #CJK UNIFIED IDEOGRAPH
+0xC1AA 0x858A #CJK UNIFIED IDEOGRAPH
+0xC1AB 0x8667 #CJK UNIFIED IDEOGRAPH
+0xC1AC 0x87C0 #CJK UNIFIED IDEOGRAPH
+0xC1AD 0x87D1 #CJK UNIFIED IDEOGRAPH
+0xC1AE 0x87B3 #CJK UNIFIED IDEOGRAPH
+0xC1AF 0x87D2 #CJK UNIFIED IDEOGRAPH
+0xC1B0 0x87C6 #CJK UNIFIED IDEOGRAPH
+0xC1B1 0x87AB #CJK UNIFIED IDEOGRAPH
+0xC1B2 0x87BB #CJK UNIFIED IDEOGRAPH
+0xC1B3 0x87BA #CJK UNIFIED IDEOGRAPH
+0xC1B4 0x87C8 #CJK UNIFIED IDEOGRAPH
+0xC1B5 0x87CB #CJK UNIFIED IDEOGRAPH
+0xC1B6 0x893B #CJK UNIFIED IDEOGRAPH
+0xC1B7 0x8936 #CJK UNIFIED IDEOGRAPH
+0xC1B8 0x8944 #CJK UNIFIED IDEOGRAPH
+0xC1B9 0x8938 #CJK UNIFIED IDEOGRAPH
+0xC1BA 0x893D #CJK UNIFIED IDEOGRAPH
+0xC1BB 0x89AC #CJK UNIFIED IDEOGRAPH
+0xC1BC 0x8B0E #CJK UNIFIED IDEOGRAPH
+0xC1BD 0x8B17 #CJK UNIFIED IDEOGRAPH
+0xC1BE 0x8B19 #CJK UNIFIED IDEOGRAPH
+0xC1BF 0x8B1B #CJK UNIFIED IDEOGRAPH
+0xC1C0 0x8B0A #CJK UNIFIED IDEOGRAPH
+0xC1C1 0x8B20 #CJK UNIFIED IDEOGRAPH
+0xC1C2 0x8B1D #CJK UNIFIED IDEOGRAPH
+0xC1C3 0x8B04 #CJK UNIFIED IDEOGRAPH
+0xC1C4 0x8B10 #CJK UNIFIED IDEOGRAPH
+0xC1C5 0x8C41 #CJK UNIFIED IDEOGRAPH
+0xC1C6 0x8C3F #CJK UNIFIED IDEOGRAPH
+0xC1C7 0x8C73 #CJK UNIFIED IDEOGRAPH
+0xC1C8 0x8CFA #CJK UNIFIED IDEOGRAPH
+0xC1C9 0x8CFD #CJK UNIFIED IDEOGRAPH
+0xC1CA 0x8CFC #CJK UNIFIED IDEOGRAPH
+0xC1CB 0x8CF8 #CJK UNIFIED IDEOGRAPH
+0xC1CC 0x8CFB #CJK UNIFIED IDEOGRAPH
+0xC1CD 0x8DA8 #CJK UNIFIED IDEOGRAPH
+0xC1CE 0x8E49 #CJK UNIFIED IDEOGRAPH
+0xC1CF 0x8E4B #CJK UNIFIED IDEOGRAPH
+0xC1D0 0x8E48 #CJK UNIFIED IDEOGRAPH
+0xC1D1 0x8E4A #CJK UNIFIED IDEOGRAPH
+0xC1D2 0x8F44 #CJK UNIFIED IDEOGRAPH
+0xC1D3 0x8F3E #CJK UNIFIED IDEOGRAPH
+0xC1D4 0x8F42 #CJK UNIFIED IDEOGRAPH
+0xC1D5 0x8F45 #CJK UNIFIED IDEOGRAPH
+0xC1D6 0x8F3F #CJK UNIFIED IDEOGRAPH
+0xC1D7 0x907F #CJK UNIFIED IDEOGRAPH
+0xC1D8 0x907D #CJK UNIFIED IDEOGRAPH
+0xC1D9 0x9084 #CJK UNIFIED IDEOGRAPH
+0xC1DA 0x9081 #CJK UNIFIED IDEOGRAPH
+0xC1DB 0x9082 #CJK UNIFIED IDEOGRAPH
+0xC1DC 0x9080 #CJK UNIFIED IDEOGRAPH
+0xC1DD 0x9139 #CJK UNIFIED IDEOGRAPH
+0xC1DE 0x91A3 #CJK UNIFIED IDEOGRAPH
+0xC1DF 0x919E #CJK UNIFIED IDEOGRAPH
+0xC1E0 0x919C #CJK UNIFIED IDEOGRAPH
+0xC1E1 0x934D #CJK UNIFIED IDEOGRAPH
+0xC1E2 0x9382 #CJK UNIFIED IDEOGRAPH
+0xC1E3 0x9328 #CJK UNIFIED IDEOGRAPH
+0xC1E4 0x9375 #CJK UNIFIED IDEOGRAPH
+0xC1E5 0x934A #CJK UNIFIED IDEOGRAPH
+0xC1E6 0x9365 #CJK UNIFIED IDEOGRAPH
+0xC1E7 0x934B #CJK UNIFIED IDEOGRAPH
+0xC1E8 0x9318 #CJK UNIFIED IDEOGRAPH
+0xC1E9 0x937E #CJK UNIFIED IDEOGRAPH
+0xC1EA 0x936C #CJK UNIFIED IDEOGRAPH
+0xC1EB 0x935B #CJK UNIFIED IDEOGRAPH
+0xC1EC 0x9370 #CJK UNIFIED IDEOGRAPH
+0xC1ED 0x935A #CJK UNIFIED IDEOGRAPH
+0xC1EE 0x9354 #CJK UNIFIED IDEOGRAPH
+0xC1EF 0x95CA #CJK UNIFIED IDEOGRAPH
+0xC1F0 0x95CB #CJK UNIFIED IDEOGRAPH
+0xC1F1 0x95CC #CJK UNIFIED IDEOGRAPH
+0xC1F2 0x95C8 #CJK UNIFIED IDEOGRAPH
+0xC1F3 0x95C6 #CJK UNIFIED IDEOGRAPH
+0xC1F4 0x96B1 #CJK UNIFIED IDEOGRAPH
+0xC1F5 0x96B8 #CJK UNIFIED IDEOGRAPH
+0xC1F6 0x96D6 #CJK UNIFIED IDEOGRAPH
+0xC1F7 0x971C #CJK UNIFIED IDEOGRAPH
+0xC1F8 0x971E #CJK UNIFIED IDEOGRAPH
+0xC1F9 0x97A0 #CJK UNIFIED IDEOGRAPH
+0xC1FA 0x97D3 #CJK UNIFIED IDEOGRAPH
+0xC1FB 0x9846 #CJK UNIFIED IDEOGRAPH
+0xC1FC 0x98B6 #CJK UNIFIED IDEOGRAPH
+0xC1FD 0x9935 #CJK UNIFIED IDEOGRAPH
+0xC1FE 0x9A01 #CJK UNIFIED IDEOGRAPH
+0xC240 0x99FF #CJK UNIFIED IDEOGRAPH
+0xC241 0x9BAE #CJK UNIFIED IDEOGRAPH
+0xC242 0x9BAB #CJK UNIFIED IDEOGRAPH
+0xC243 0x9BAA #CJK UNIFIED IDEOGRAPH
+0xC244 0x9BAD #CJK UNIFIED IDEOGRAPH
+0xC245 0x9D3B #CJK UNIFIED IDEOGRAPH
+0xC246 0x9D3F #CJK UNIFIED IDEOGRAPH
+0xC247 0x9E8B #CJK UNIFIED IDEOGRAPH
+0xC248 0x9ECF #CJK UNIFIED IDEOGRAPH
+0xC249 0x9EDE #CJK UNIFIED IDEOGRAPH
+0xC24A 0x9EDC #CJK UNIFIED IDEOGRAPH
+0xC24B 0x9EDD #CJK UNIFIED IDEOGRAPH
+0xC24C 0x9EDB #CJK UNIFIED IDEOGRAPH
+0xC24D 0x9F3E #CJK UNIFIED IDEOGRAPH
+0xC24E 0x9F4B #CJK UNIFIED IDEOGRAPH
+0xC24F 0x53E2 #CJK UNIFIED IDEOGRAPH
+0xC250 0x5695 #CJK UNIFIED IDEOGRAPH
+0xC251 0x56AE #CJK UNIFIED IDEOGRAPH
+0xC252 0x58D9 #CJK UNIFIED IDEOGRAPH
+0xC253 0x58D8 #CJK UNIFIED IDEOGRAPH
+0xC254 0x5B38 #CJK UNIFIED IDEOGRAPH
+0xC255 0x5F5D #CJK UNIFIED IDEOGRAPH
+0xC256 0x61E3 #CJK UNIFIED IDEOGRAPH
+0xC257 0x6233 #CJK UNIFIED IDEOGRAPH
+0xC258 0x64F4 #CJK UNIFIED IDEOGRAPH
+0xC259 0x64F2 #CJK UNIFIED IDEOGRAPH
+0xC25A 0x64FE #CJK UNIFIED IDEOGRAPH
+0xC25B 0x6506 #CJK UNIFIED IDEOGRAPH
+0xC25C 0x64FA #CJK UNIFIED IDEOGRAPH
+0xC25D 0x64FB #CJK UNIFIED IDEOGRAPH
+0xC25E 0x64F7 #CJK UNIFIED IDEOGRAPH
+0xC25F 0x65B7 #CJK UNIFIED IDEOGRAPH
+0xC260 0x66DC #CJK UNIFIED IDEOGRAPH
+0xC261 0x6726 #CJK UNIFIED IDEOGRAPH
+0xC262 0x6AB3 #CJK UNIFIED IDEOGRAPH
+0xC263 0x6AAC #CJK UNIFIED IDEOGRAPH
+0xC264 0x6AC3 #CJK UNIFIED IDEOGRAPH
+0xC265 0x6ABB #CJK UNIFIED IDEOGRAPH
+0xC266 0x6AB8 #CJK UNIFIED IDEOGRAPH
+0xC267 0x6AC2 #CJK UNIFIED IDEOGRAPH
+0xC268 0x6AAE #CJK UNIFIED IDEOGRAPH
+0xC269 0x6AAF #CJK UNIFIED IDEOGRAPH
+0xC26A 0x6B5F #CJK UNIFIED IDEOGRAPH
+0xC26B 0x6B78 #CJK UNIFIED IDEOGRAPH
+0xC26C 0x6BAF #CJK UNIFIED IDEOGRAPH
+0xC26D 0x7009 #CJK UNIFIED IDEOGRAPH
+0xC26E 0x700B #CJK UNIFIED IDEOGRAPH
+0xC26F 0x6FFE #CJK UNIFIED IDEOGRAPH
+0xC270 0x7006 #CJK UNIFIED IDEOGRAPH
+0xC271 0x6FFA #CJK UNIFIED IDEOGRAPH
+0xC272 0x7011 #CJK UNIFIED IDEOGRAPH
+0xC273 0x700F #CJK UNIFIED IDEOGRAPH
+0xC274 0x71FB #CJK UNIFIED IDEOGRAPH
+0xC275 0x71FC #CJK UNIFIED IDEOGRAPH
+0xC276 0x71FE #CJK UNIFIED IDEOGRAPH
+0xC277 0x71F8 #CJK UNIFIED IDEOGRAPH
+0xC278 0x7377 #CJK UNIFIED IDEOGRAPH
+0xC279 0x7375 #CJK UNIFIED IDEOGRAPH
+0xC27A 0x74A7 #CJK UNIFIED IDEOGRAPH
+0xC27B 0x74BF #CJK UNIFIED IDEOGRAPH
+0xC27C 0x7515 #CJK UNIFIED IDEOGRAPH
+0xC27D 0x7656 #CJK UNIFIED IDEOGRAPH
+0xC27E 0x7658 #CJK UNIFIED IDEOGRAPH
+0xC2A1 0x7652 #CJK UNIFIED IDEOGRAPH
+0xC2A2 0x77BD #CJK UNIFIED IDEOGRAPH
+0xC2A3 0x77BF #CJK UNIFIED IDEOGRAPH
+0xC2A4 0x77BB #CJK UNIFIED IDEOGRAPH
+0xC2A5 0x77BC #CJK UNIFIED IDEOGRAPH
+0xC2A6 0x790E #CJK UNIFIED IDEOGRAPH
+0xC2A7 0x79AE #CJK UNIFIED IDEOGRAPH
+0xC2A8 0x7A61 #CJK UNIFIED IDEOGRAPH
+0xC2A9 0x7A62 #CJK UNIFIED IDEOGRAPH
+0xC2AA 0x7A60 #CJK UNIFIED IDEOGRAPH
+0xC2AB 0x7AC4 #CJK UNIFIED IDEOGRAPH
+0xC2AC 0x7AC5 #CJK UNIFIED IDEOGRAPH
+0xC2AD 0x7C2B #CJK UNIFIED IDEOGRAPH
+0xC2AE 0x7C27 #CJK UNIFIED IDEOGRAPH
+0xC2AF 0x7C2A #CJK UNIFIED IDEOGRAPH
+0xC2B0 0x7C1E #CJK UNIFIED IDEOGRAPH
+0xC2B1 0x7C23 #CJK UNIFIED IDEOGRAPH
+0xC2B2 0x7C21 #CJK UNIFIED IDEOGRAPH
+0xC2B3 0x7CE7 #CJK UNIFIED IDEOGRAPH
+0xC2B4 0x7E54 #CJK UNIFIED IDEOGRAPH
+0xC2B5 0x7E55 #CJK UNIFIED IDEOGRAPH
+0xC2B6 0x7E5E #CJK UNIFIED IDEOGRAPH
+0xC2B7 0x7E5A #CJK UNIFIED IDEOGRAPH
+0xC2B8 0x7E61 #CJK UNIFIED IDEOGRAPH
+0xC2B9 0x7E52 #CJK UNIFIED IDEOGRAPH
+0xC2BA 0x7E59 #CJK UNIFIED IDEOGRAPH
+0xC2BB 0x7F48 #CJK UNIFIED IDEOGRAPH
+0xC2BC 0x7FF9 #CJK UNIFIED IDEOGRAPH
+0xC2BD 0x7FFB #CJK UNIFIED IDEOGRAPH
+0xC2BE 0x8077 #CJK UNIFIED IDEOGRAPH
+0xC2BF 0x8076 #CJK UNIFIED IDEOGRAPH
+0xC2C0 0x81CD #CJK UNIFIED IDEOGRAPH
+0xC2C1 0x81CF #CJK UNIFIED IDEOGRAPH
+0xC2C2 0x820A #CJK UNIFIED IDEOGRAPH
+0xC2C3 0x85CF #CJK UNIFIED IDEOGRAPH
+0xC2C4 0x85A9 #CJK UNIFIED IDEOGRAPH
+0xC2C5 0x85CD #CJK UNIFIED IDEOGRAPH
+0xC2C6 0x85D0 #CJK UNIFIED IDEOGRAPH
+0xC2C7 0x85C9 #CJK UNIFIED IDEOGRAPH
+0xC2C8 0x85B0 #CJK UNIFIED IDEOGRAPH
+0xC2C9 0x85BA #CJK UNIFIED IDEOGRAPH
+0xC2CA 0x85B9 #CJK UNIFIED IDEOGRAPH
+0xC2CB 0x85A6 #CJK UNIFIED IDEOGRAPH
+0xC2CC 0x87EF #CJK UNIFIED IDEOGRAPH
+0xC2CD 0x87EC #CJK UNIFIED IDEOGRAPH
+0xC2CE 0x87F2 #CJK UNIFIED IDEOGRAPH
+0xC2CF 0x87E0 #CJK UNIFIED IDEOGRAPH
+0xC2D0 0x8986 #CJK UNIFIED IDEOGRAPH
+0xC2D1 0x89B2 #CJK UNIFIED IDEOGRAPH
+0xC2D2 0x89F4 #CJK UNIFIED IDEOGRAPH
+0xC2D3 0x8B28 #CJK UNIFIED IDEOGRAPH
+0xC2D4 0x8B39 #CJK UNIFIED IDEOGRAPH
+0xC2D5 0x8B2C #CJK UNIFIED IDEOGRAPH
+0xC2D6 0x8B2B #CJK UNIFIED IDEOGRAPH
+0xC2D7 0x8C50 #CJK UNIFIED IDEOGRAPH
+0xC2D8 0x8D05 #CJK UNIFIED IDEOGRAPH
+0xC2D9 0x8E59 #CJK UNIFIED IDEOGRAPH
+0xC2DA 0x8E63 #CJK UNIFIED IDEOGRAPH
+0xC2DB 0x8E66 #CJK UNIFIED IDEOGRAPH
+0xC2DC 0x8E64 #CJK UNIFIED IDEOGRAPH
+0xC2DD 0x8E5F #CJK UNIFIED IDEOGRAPH
+0xC2DE 0x8E55 #CJK UNIFIED IDEOGRAPH
+0xC2DF 0x8EC0 #CJK UNIFIED IDEOGRAPH
+0xC2E0 0x8F49 #CJK UNIFIED IDEOGRAPH
+0xC2E1 0x8F4D #CJK UNIFIED IDEOGRAPH
+0xC2E2 0x9087 #CJK UNIFIED IDEOGRAPH
+0xC2E3 0x9083 #CJK UNIFIED IDEOGRAPH
+0xC2E4 0x9088 #CJK UNIFIED IDEOGRAPH
+0xC2E5 0x91AB #CJK UNIFIED IDEOGRAPH
+0xC2E6 0x91AC #CJK UNIFIED IDEOGRAPH
+0xC2E7 0x91D0 #CJK UNIFIED IDEOGRAPH
+0xC2E8 0x9394 #CJK UNIFIED IDEOGRAPH
+0xC2E9 0x938A #CJK UNIFIED IDEOGRAPH
+0xC2EA 0x9396 #CJK UNIFIED IDEOGRAPH
+0xC2EB 0x93A2 #CJK UNIFIED IDEOGRAPH
+0xC2EC 0x93B3 #CJK UNIFIED IDEOGRAPH
+0xC2ED 0x93AE #CJK UNIFIED IDEOGRAPH
+0xC2EE 0x93AC #CJK UNIFIED IDEOGRAPH
+0xC2EF 0x93B0 #CJK UNIFIED IDEOGRAPH
+0xC2F0 0x9398 #CJK UNIFIED IDEOGRAPH
+0xC2F1 0x939A #CJK UNIFIED IDEOGRAPH
+0xC2F2 0x9397 #CJK UNIFIED IDEOGRAPH
+0xC2F3 0x95D4 #CJK UNIFIED IDEOGRAPH
+0xC2F4 0x95D6 #CJK UNIFIED IDEOGRAPH
+0xC2F5 0x95D0 #CJK UNIFIED IDEOGRAPH
+0xC2F6 0x95D5 #CJK UNIFIED IDEOGRAPH
+0xC2F7 0x96E2 #CJK UNIFIED IDEOGRAPH
+0xC2F8 0x96DC #CJK UNIFIED IDEOGRAPH
+0xC2F9 0x96D9 #CJK UNIFIED IDEOGRAPH
+0xC2FA 0x96DB #CJK UNIFIED IDEOGRAPH
+0xC2FB 0x96DE #CJK UNIFIED IDEOGRAPH
+0xC2FC 0x9724 #CJK UNIFIED IDEOGRAPH
+0xC2FD 0x97A3 #CJK UNIFIED IDEOGRAPH
+0xC2FE 0x97A6 #CJK UNIFIED IDEOGRAPH
+0xC340 0x97AD #CJK UNIFIED IDEOGRAPH
+0xC341 0x97F9 #CJK UNIFIED IDEOGRAPH
+0xC342 0x984D #CJK UNIFIED IDEOGRAPH
+0xC343 0x984F #CJK UNIFIED IDEOGRAPH
+0xC344 0x984C #CJK UNIFIED IDEOGRAPH
+0xC345 0x984E #CJK UNIFIED IDEOGRAPH
+0xC346 0x9853 #CJK UNIFIED IDEOGRAPH
+0xC347 0x98BA #CJK UNIFIED IDEOGRAPH
+0xC348 0x993E #CJK UNIFIED IDEOGRAPH
+0xC349 0x993F #CJK UNIFIED IDEOGRAPH
+0xC34A 0x993D #CJK UNIFIED IDEOGRAPH
+0xC34B 0x992E #CJK UNIFIED IDEOGRAPH
+0xC34C 0x99A5 #CJK UNIFIED IDEOGRAPH
+0xC34D 0x9A0E #CJK UNIFIED IDEOGRAPH
+0xC34E 0x9AC1 #CJK UNIFIED IDEOGRAPH
+0xC34F 0x9B03 #CJK UNIFIED IDEOGRAPH
+0xC350 0x9B06 #CJK UNIFIED IDEOGRAPH
+0xC351 0x9B4F #CJK UNIFIED IDEOGRAPH
+0xC352 0x9B4E #CJK UNIFIED IDEOGRAPH
+0xC353 0x9B4D #CJK UNIFIED IDEOGRAPH
+0xC354 0x9BCA #CJK UNIFIED IDEOGRAPH
+0xC355 0x9BC9 #CJK UNIFIED IDEOGRAPH
+0xC356 0x9BFD #CJK UNIFIED IDEOGRAPH
+0xC357 0x9BC8 #CJK UNIFIED IDEOGRAPH
+0xC358 0x9BC0 #CJK UNIFIED IDEOGRAPH
+0xC359 0x9D51 #CJK UNIFIED IDEOGRAPH
+0xC35A 0x9D5D #CJK UNIFIED IDEOGRAPH
+0xC35B 0x9D60 #CJK UNIFIED IDEOGRAPH
+0xC35C 0x9EE0 #CJK UNIFIED IDEOGRAPH
+0xC35D 0x9F15 #CJK UNIFIED IDEOGRAPH
+0xC35E 0x9F2C #CJK UNIFIED IDEOGRAPH
+0xC35F 0x5133 #CJK UNIFIED IDEOGRAPH
+0xC360 0x56A5 #CJK UNIFIED IDEOGRAPH
+0xC361 0x58DE #CJK UNIFIED IDEOGRAPH
+0xC362 0x58DF #CJK UNIFIED IDEOGRAPH
+0xC363 0x58E2 #CJK UNIFIED IDEOGRAPH
+0xC364 0x5BF5 #CJK UNIFIED IDEOGRAPH
+0xC365 0x9F90 #CJK UNIFIED IDEOGRAPH
+0xC366 0x5EEC #CJK UNIFIED IDEOGRAPH
+0xC367 0x61F2 #CJK UNIFIED IDEOGRAPH
+0xC368 0x61F7 #CJK UNIFIED IDEOGRAPH
+0xC369 0x61F6 #CJK UNIFIED IDEOGRAPH
+0xC36A 0x61F5 #CJK UNIFIED IDEOGRAPH
+0xC36B 0x6500 #CJK UNIFIED IDEOGRAPH
+0xC36C 0x650F #CJK UNIFIED IDEOGRAPH
+0xC36D 0x66E0 #CJK UNIFIED IDEOGRAPH
+0xC36E 0x66DD #CJK UNIFIED IDEOGRAPH
+0xC36F 0x6AE5 #CJK UNIFIED IDEOGRAPH
+0xC370 0x6ADD #CJK UNIFIED IDEOGRAPH
+0xC371 0x6ADA #CJK UNIFIED IDEOGRAPH
+0xC372 0x6AD3 #CJK UNIFIED IDEOGRAPH
+0xC373 0x701B #CJK UNIFIED IDEOGRAPH
+0xC374 0x701F #CJK UNIFIED IDEOGRAPH
+0xC375 0x7028 #CJK UNIFIED IDEOGRAPH
+0xC376 0x701A #CJK UNIFIED IDEOGRAPH
+0xC377 0x701D #CJK UNIFIED IDEOGRAPH
+0xC378 0x7015 #CJK UNIFIED IDEOGRAPH
+0xC379 0x7018 #CJK UNIFIED IDEOGRAPH
+0xC37A 0x7206 #CJK UNIFIED IDEOGRAPH
+0xC37B 0x720D #CJK UNIFIED IDEOGRAPH
+0xC37C 0x7258 #CJK UNIFIED IDEOGRAPH
+0xC37D 0x72A2 #CJK UNIFIED IDEOGRAPH
+0xC37E 0x7378 #CJK UNIFIED IDEOGRAPH
+0xC3A1 0x737A #CJK UNIFIED IDEOGRAPH
+0xC3A2 0x74BD #CJK UNIFIED IDEOGRAPH
+0xC3A3 0x74CA #CJK UNIFIED IDEOGRAPH
+0xC3A4 0x74E3 #CJK UNIFIED IDEOGRAPH
+0xC3A5 0x7587 #CJK UNIFIED IDEOGRAPH
+0xC3A6 0x7586 #CJK UNIFIED IDEOGRAPH
+0xC3A7 0x765F #CJK UNIFIED IDEOGRAPH
+0xC3A8 0x7661 #CJK UNIFIED IDEOGRAPH
+0xC3A9 0x77C7 #CJK UNIFIED IDEOGRAPH
+0xC3AA 0x7919 #CJK UNIFIED IDEOGRAPH
+0xC3AB 0x79B1 #CJK UNIFIED IDEOGRAPH
+0xC3AC 0x7A6B #CJK UNIFIED IDEOGRAPH
+0xC3AD 0x7A69 #CJK UNIFIED IDEOGRAPH
+0xC3AE 0x7C3E #CJK UNIFIED IDEOGRAPH
+0xC3AF 0x7C3F #CJK UNIFIED IDEOGRAPH
+0xC3B0 0x7C38 #CJK UNIFIED IDEOGRAPH
+0xC3B1 0x7C3D #CJK UNIFIED IDEOGRAPH
+0xC3B2 0x7C37 #CJK UNIFIED IDEOGRAPH
+0xC3B3 0x7C40 #CJK UNIFIED IDEOGRAPH
+0xC3B4 0x7E6B #CJK UNIFIED IDEOGRAPH
+0xC3B5 0x7E6D #CJK UNIFIED IDEOGRAPH
+0xC3B6 0x7E79 #CJK UNIFIED IDEOGRAPH
+0xC3B7 0x7E69 #CJK UNIFIED IDEOGRAPH
+0xC3B8 0x7E6A #CJK UNIFIED IDEOGRAPH
+0xC3B9 0x7F85 #CJK UNIFIED IDEOGRAPH
+0xC3BA 0x7E73 #CJK UNIFIED IDEOGRAPH
+0xC3BB 0x7FB6 #CJK UNIFIED IDEOGRAPH
+0xC3BC 0x7FB9 #CJK UNIFIED IDEOGRAPH
+0xC3BD 0x7FB8 #CJK UNIFIED IDEOGRAPH
+0xC3BE 0x81D8 #CJK UNIFIED IDEOGRAPH
+0xC3BF 0x85E9 #CJK UNIFIED IDEOGRAPH
+0xC3C0 0x85DD #CJK UNIFIED IDEOGRAPH
+0xC3C1 0x85EA #CJK UNIFIED IDEOGRAPH
+0xC3C2 0x85D5 #CJK UNIFIED IDEOGRAPH
+0xC3C3 0x85E4 #CJK UNIFIED IDEOGRAPH
+0xC3C4 0x85E5 #CJK UNIFIED IDEOGRAPH
+0xC3C5 0x85F7 #CJK UNIFIED IDEOGRAPH
+0xC3C6 0x87FB #CJK UNIFIED IDEOGRAPH
+0xC3C7 0x8805 #CJK UNIFIED IDEOGRAPH
+0xC3C8 0x880D #CJK UNIFIED IDEOGRAPH
+0xC3C9 0x87F9 #CJK UNIFIED IDEOGRAPH
+0xC3CA 0x87FE #CJK UNIFIED IDEOGRAPH
+0xC3CB 0x8960 #CJK UNIFIED IDEOGRAPH
+0xC3CC 0x895F #CJK UNIFIED IDEOGRAPH
+0xC3CD 0x8956 #CJK UNIFIED IDEOGRAPH
+0xC3CE 0x895E #CJK UNIFIED IDEOGRAPH
+0xC3CF 0x8B41 #CJK UNIFIED IDEOGRAPH
+0xC3D0 0x8B5C #CJK UNIFIED IDEOGRAPH
+0xC3D1 0x8B58 #CJK UNIFIED IDEOGRAPH
+0xC3D2 0x8B49 #CJK UNIFIED IDEOGRAPH
+0xC3D3 0x8B5A #CJK UNIFIED IDEOGRAPH
+0xC3D4 0x8B4E #CJK UNIFIED IDEOGRAPH
+0xC3D5 0x8B4F #CJK UNIFIED IDEOGRAPH
+0xC3D6 0x8B46 #CJK UNIFIED IDEOGRAPH
+0xC3D7 0x8B59 #CJK UNIFIED IDEOGRAPH
+0xC3D8 0x8D08 #CJK UNIFIED IDEOGRAPH
+0xC3D9 0x8D0A #CJK UNIFIED IDEOGRAPH
+0xC3DA 0x8E7C #CJK UNIFIED IDEOGRAPH
+0xC3DB 0x8E72 #CJK UNIFIED IDEOGRAPH
+0xC3DC 0x8E87 #CJK UNIFIED IDEOGRAPH
+0xC3DD 0x8E76 #CJK UNIFIED IDEOGRAPH
+0xC3DE 0x8E6C #CJK UNIFIED IDEOGRAPH
+0xC3DF 0x8E7A #CJK UNIFIED IDEOGRAPH
+0xC3E0 0x8E74 #CJK UNIFIED IDEOGRAPH
+0xC3E1 0x8F54 #CJK UNIFIED IDEOGRAPH
+0xC3E2 0x8F4E #CJK UNIFIED IDEOGRAPH
+0xC3E3 0x8FAD #CJK UNIFIED IDEOGRAPH
+0xC3E4 0x908A #CJK UNIFIED IDEOGRAPH
+0xC3E5 0x908B #CJK UNIFIED IDEOGRAPH
+0xC3E6 0x91B1 #CJK UNIFIED IDEOGRAPH
+0xC3E7 0x91AE #CJK UNIFIED IDEOGRAPH
+0xC3E8 0x93E1 #CJK UNIFIED IDEOGRAPH
+0xC3E9 0x93D1 #CJK UNIFIED IDEOGRAPH
+0xC3EA 0x93DF #CJK UNIFIED IDEOGRAPH
+0xC3EB 0x93C3 #CJK UNIFIED IDEOGRAPH
+0xC3EC 0x93C8 #CJK UNIFIED IDEOGRAPH
+0xC3ED 0x93DC #CJK UNIFIED IDEOGRAPH
+0xC3EE 0x93DD #CJK UNIFIED IDEOGRAPH
+0xC3EF 0x93D6 #CJK UNIFIED IDEOGRAPH
+0xC3F0 0x93E2 #CJK UNIFIED IDEOGRAPH
+0xC3F1 0x93CD #CJK UNIFIED IDEOGRAPH
+0xC3F2 0x93D8 #CJK UNIFIED IDEOGRAPH
+0xC3F3 0x93E4 #CJK UNIFIED IDEOGRAPH
+0xC3F4 0x93D7 #CJK UNIFIED IDEOGRAPH
+0xC3F5 0x93E8 #CJK UNIFIED IDEOGRAPH
+0xC3F6 0x95DC #CJK UNIFIED IDEOGRAPH
+0xC3F7 0x96B4 #CJK UNIFIED IDEOGRAPH
+0xC3F8 0x96E3 #CJK UNIFIED IDEOGRAPH
+0xC3F9 0x972A #CJK UNIFIED IDEOGRAPH
+0xC3FA 0x9727 #CJK UNIFIED IDEOGRAPH
+0xC3FB 0x9761 #CJK UNIFIED IDEOGRAPH
+0xC3FC 0x97DC #CJK UNIFIED IDEOGRAPH
+0xC3FD 0x97FB #CJK UNIFIED IDEOGRAPH
+0xC3FE 0x985E #CJK UNIFIED IDEOGRAPH
+0xC440 0x9858 #CJK UNIFIED IDEOGRAPH
+0xC441 0x985B #CJK UNIFIED IDEOGRAPH
+0xC442 0x98BC #CJK UNIFIED IDEOGRAPH
+0xC443 0x9945 #CJK UNIFIED IDEOGRAPH
+0xC444 0x9949 #CJK UNIFIED IDEOGRAPH
+0xC445 0x9A16 #CJK UNIFIED IDEOGRAPH
+0xC446 0x9A19 #CJK UNIFIED IDEOGRAPH
+0xC447 0x9B0D #CJK UNIFIED IDEOGRAPH
+0xC448 0x9BE8 #CJK UNIFIED IDEOGRAPH
+0xC449 0x9BE7 #CJK UNIFIED IDEOGRAPH
+0xC44A 0x9BD6 #CJK UNIFIED IDEOGRAPH
+0xC44B 0x9BDB #CJK UNIFIED IDEOGRAPH
+0xC44C 0x9D89 #CJK UNIFIED IDEOGRAPH
+0xC44D 0x9D61 #CJK UNIFIED IDEOGRAPH
+0xC44E 0x9D72 #CJK UNIFIED IDEOGRAPH
+0xC44F 0x9D6A #CJK UNIFIED IDEOGRAPH
+0xC450 0x9D6C #CJK UNIFIED IDEOGRAPH
+0xC451 0x9E92 #CJK UNIFIED IDEOGRAPH
+0xC452 0x9E97 #CJK UNIFIED IDEOGRAPH
+0xC453 0x9E93 #CJK UNIFIED IDEOGRAPH
+0xC454 0x9EB4 #CJK UNIFIED IDEOGRAPH
+0xC455 0x52F8 #CJK UNIFIED IDEOGRAPH
+0xC456 0x56A8 #CJK UNIFIED IDEOGRAPH
+0xC457 0x56B7 #CJK UNIFIED IDEOGRAPH
+0xC458 0x56B6 #CJK UNIFIED IDEOGRAPH
+0xC459 0x56B4 #CJK UNIFIED IDEOGRAPH
+0xC45A 0x56BC #CJK UNIFIED IDEOGRAPH
+0xC45B 0x58E4 #CJK UNIFIED IDEOGRAPH
+0xC45C 0x5B40 #CJK UNIFIED IDEOGRAPH
+0xC45D 0x5B43 #CJK UNIFIED IDEOGRAPH
+0xC45E 0x5B7D #CJK UNIFIED IDEOGRAPH
+0xC45F 0x5BF6 #CJK UNIFIED IDEOGRAPH
+0xC460 0x5DC9 #CJK UNIFIED IDEOGRAPH
+0xC461 0x61F8 #CJK UNIFIED IDEOGRAPH
+0xC462 0x61FA #CJK UNIFIED IDEOGRAPH
+0xC463 0x6518 #CJK UNIFIED IDEOGRAPH
+0xC464 0x6514 #CJK UNIFIED IDEOGRAPH
+0xC465 0x6519 #CJK UNIFIED IDEOGRAPH
+0xC466 0x66E6 #CJK UNIFIED IDEOGRAPH
+0xC467 0x6727 #CJK UNIFIED IDEOGRAPH
+0xC468 0x6AEC #CJK UNIFIED IDEOGRAPH
+0xC469 0x703E #CJK UNIFIED IDEOGRAPH
+0xC46A 0x7030 #CJK UNIFIED IDEOGRAPH
+0xC46B 0x7032 #CJK UNIFIED IDEOGRAPH
+0xC46C 0x7210 #CJK UNIFIED IDEOGRAPH
+0xC46D 0x737B #CJK UNIFIED IDEOGRAPH
+0xC46E 0x74CF #CJK UNIFIED IDEOGRAPH
+0xC46F 0x7662 #CJK UNIFIED IDEOGRAPH
+0xC470 0x7665 #CJK UNIFIED IDEOGRAPH
+0xC471 0x7926 #CJK UNIFIED IDEOGRAPH
+0xC472 0x792A #CJK UNIFIED IDEOGRAPH
+0xC473 0x792C #CJK UNIFIED IDEOGRAPH
+0xC474 0x792B #CJK UNIFIED IDEOGRAPH
+0xC475 0x7AC7 #CJK UNIFIED IDEOGRAPH
+0xC476 0x7AF6 #CJK UNIFIED IDEOGRAPH
+0xC477 0x7C4C #CJK UNIFIED IDEOGRAPH
+0xC478 0x7C43 #CJK UNIFIED IDEOGRAPH
+0xC479 0x7C4D #CJK UNIFIED IDEOGRAPH
+0xC47A 0x7CEF #CJK UNIFIED IDEOGRAPH
+0xC47B 0x7CF0 #CJK UNIFIED IDEOGRAPH
+0xC47C 0x8FAE #CJK UNIFIED IDEOGRAPH
+0xC47D 0x7E7D #CJK UNIFIED IDEOGRAPH
+0xC47E 0x7E7C #CJK UNIFIED IDEOGRAPH
+0xC4A1 0x7E82 #CJK UNIFIED IDEOGRAPH
+0xC4A2 0x7F4C #CJK UNIFIED IDEOGRAPH
+0xC4A3 0x8000 #CJK UNIFIED IDEOGRAPH
+0xC4A4 0x81DA #CJK UNIFIED IDEOGRAPH
+0xC4A5 0x8266 #CJK UNIFIED IDEOGRAPH
+0xC4A6 0x85FB #CJK UNIFIED IDEOGRAPH
+0xC4A7 0x85F9 #CJK UNIFIED IDEOGRAPH
+0xC4A8 0x8611 #CJK UNIFIED IDEOGRAPH
+0xC4A9 0x85FA #CJK UNIFIED IDEOGRAPH
+0xC4AA 0x8606 #CJK UNIFIED IDEOGRAPH
+0xC4AB 0x860B #CJK UNIFIED IDEOGRAPH
+0xC4AC 0x8607 #CJK UNIFIED IDEOGRAPH
+0xC4AD 0x860A #CJK UNIFIED IDEOGRAPH
+0xC4AE 0x8814 #CJK UNIFIED IDEOGRAPH
+0xC4AF 0x8815 #CJK UNIFIED IDEOGRAPH
+0xC4B0 0x8964 #CJK UNIFIED IDEOGRAPH
+0xC4B1 0x89BA #CJK UNIFIED IDEOGRAPH
+0xC4B2 0x89F8 #CJK UNIFIED IDEOGRAPH
+0xC4B3 0x8B70 #CJK UNIFIED IDEOGRAPH
+0xC4B4 0x8B6C #CJK UNIFIED IDEOGRAPH
+0xC4B5 0x8B66 #CJK UNIFIED IDEOGRAPH
+0xC4B6 0x8B6F #CJK UNIFIED IDEOGRAPH
+0xC4B7 0x8B5F #CJK UNIFIED IDEOGRAPH
+0xC4B8 0x8B6B #CJK UNIFIED IDEOGRAPH
+0xC4B9 0x8D0F #CJK UNIFIED IDEOGRAPH
+0xC4BA 0x8D0D #CJK UNIFIED IDEOGRAPH
+0xC4BB 0x8E89 #CJK UNIFIED IDEOGRAPH
+0xC4BC 0x8E81 #CJK UNIFIED IDEOGRAPH
+0xC4BD 0x8E85 #CJK UNIFIED IDEOGRAPH
+0xC4BE 0x8E82 #CJK UNIFIED IDEOGRAPH
+0xC4BF 0x91B4 #CJK UNIFIED IDEOGRAPH
+0xC4C0 0x91CB #CJK UNIFIED IDEOGRAPH
+0xC4C1 0x9418 #CJK UNIFIED IDEOGRAPH
+0xC4C2 0x9403 #CJK UNIFIED IDEOGRAPH
+0xC4C3 0x93FD #CJK UNIFIED IDEOGRAPH
+0xC4C4 0x95E1 #CJK UNIFIED IDEOGRAPH
+0xC4C5 0x9730 #CJK UNIFIED IDEOGRAPH
+0xC4C6 0x98C4 #CJK UNIFIED IDEOGRAPH
+0xC4C7 0x9952 #CJK UNIFIED IDEOGRAPH
+0xC4C8 0x9951 #CJK UNIFIED IDEOGRAPH
+0xC4C9 0x99A8 #CJK UNIFIED IDEOGRAPH
+0xC4CA 0x9A2B #CJK UNIFIED IDEOGRAPH
+0xC4CB 0x9A30 #CJK UNIFIED IDEOGRAPH
+0xC4CC 0x9A37 #CJK UNIFIED IDEOGRAPH
+0xC4CD 0x9A35 #CJK UNIFIED IDEOGRAPH
+0xC4CE 0x9C13 #CJK UNIFIED IDEOGRAPH
+0xC4CF 0x9C0D #CJK UNIFIED IDEOGRAPH
+0xC4D0 0x9E79 #CJK UNIFIED IDEOGRAPH
+0xC4D1 0x9EB5 #CJK UNIFIED IDEOGRAPH
+0xC4D2 0x9EE8 #CJK UNIFIED IDEOGRAPH
+0xC4D3 0x9F2F #CJK UNIFIED IDEOGRAPH
+0xC4D4 0x9F5F #CJK UNIFIED IDEOGRAPH
+0xC4D5 0x9F63 #CJK UNIFIED IDEOGRAPH
+0xC4D6 0x9F61 #CJK UNIFIED IDEOGRAPH
+0xC4D7 0x5137 #CJK UNIFIED IDEOGRAPH
+0xC4D8 0x5138 #CJK UNIFIED IDEOGRAPH
+0xC4D9 0x56C1 #CJK UNIFIED IDEOGRAPH
+0xC4DA 0x56C0 #CJK UNIFIED IDEOGRAPH
+0xC4DB 0x56C2 #CJK UNIFIED IDEOGRAPH
+0xC4DC 0x5914 #CJK UNIFIED IDEOGRAPH
+0xC4DD 0x5C6C #CJK UNIFIED IDEOGRAPH
+0xC4DE 0x5DCD #CJK UNIFIED IDEOGRAPH
+0xC4DF 0x61FC #CJK UNIFIED IDEOGRAPH
+0xC4E0 0x61FE #CJK UNIFIED IDEOGRAPH
+0xC4E1 0x651D #CJK UNIFIED IDEOGRAPH
+0xC4E2 0x651C #CJK UNIFIED IDEOGRAPH
+0xC4E3 0x6595 #CJK UNIFIED IDEOGRAPH
+0xC4E4 0x66E9 #CJK UNIFIED IDEOGRAPH
+0xC4E5 0x6AFB #CJK UNIFIED IDEOGRAPH
+0xC4E6 0x6B04 #CJK UNIFIED IDEOGRAPH
+0xC4E7 0x6AFA #CJK UNIFIED IDEOGRAPH
+0xC4E8 0x6BB2 #CJK UNIFIED IDEOGRAPH
+0xC4E9 0x704C #CJK UNIFIED IDEOGRAPH
+0xC4EA 0x721B #CJK UNIFIED IDEOGRAPH
+0xC4EB 0x72A7 #CJK UNIFIED IDEOGRAPH
+0xC4EC 0x74D6 #CJK UNIFIED IDEOGRAPH
+0xC4ED 0x74D4 #CJK UNIFIED IDEOGRAPH
+0xC4EE 0x7669 #CJK UNIFIED IDEOGRAPH
+0xC4EF 0x77D3 #CJK UNIFIED IDEOGRAPH
+0xC4F0 0x7C50 #CJK UNIFIED IDEOGRAPH
+0xC4F1 0x7E8F #CJK UNIFIED IDEOGRAPH
+0xC4F2 0x7E8C #CJK UNIFIED IDEOGRAPH
+0xC4F3 0x7FBC #CJK UNIFIED IDEOGRAPH
+0xC4F4 0x8617 #CJK UNIFIED IDEOGRAPH
+0xC4F5 0x862D #CJK UNIFIED IDEOGRAPH
+0xC4F6 0x861A #CJK UNIFIED IDEOGRAPH
+0xC4F7 0x8823 #CJK UNIFIED IDEOGRAPH
+0xC4F8 0x8822 #CJK UNIFIED IDEOGRAPH
+0xC4F9 0x8821 #CJK UNIFIED IDEOGRAPH
+0xC4FA 0x881F #CJK UNIFIED IDEOGRAPH
+0xC4FB 0x896A #CJK UNIFIED IDEOGRAPH
+0xC4FC 0x896C #CJK UNIFIED IDEOGRAPH
+0xC4FD 0x89BD #CJK UNIFIED IDEOGRAPH
+0xC4FE 0x8B74 #CJK UNIFIED IDEOGRAPH
+0xC540 0x8B77 #CJK UNIFIED IDEOGRAPH
+0xC541 0x8B7D #CJK UNIFIED IDEOGRAPH
+0xC542 0x8D13 #CJK UNIFIED IDEOGRAPH
+0xC543 0x8E8A #CJK UNIFIED IDEOGRAPH
+0xC544 0x8E8D #CJK UNIFIED IDEOGRAPH
+0xC545 0x8E8B #CJK UNIFIED IDEOGRAPH
+0xC546 0x8F5F #CJK UNIFIED IDEOGRAPH
+0xC547 0x8FAF #CJK UNIFIED IDEOGRAPH
+0xC548 0x91BA #CJK UNIFIED IDEOGRAPH
+0xC549 0x942E #CJK UNIFIED IDEOGRAPH
+0xC54A 0x9433 #CJK UNIFIED IDEOGRAPH
+0xC54B 0x9435 #CJK UNIFIED IDEOGRAPH
+0xC54C 0x943A #CJK UNIFIED IDEOGRAPH
+0xC54D 0x9438 #CJK UNIFIED IDEOGRAPH
+0xC54E 0x9432 #CJK UNIFIED IDEOGRAPH
+0xC54F 0x942B #CJK UNIFIED IDEOGRAPH
+0xC550 0x95E2 #CJK UNIFIED IDEOGRAPH
+0xC551 0x9738 #CJK UNIFIED IDEOGRAPH
+0xC552 0x9739 #CJK UNIFIED IDEOGRAPH
+0xC553 0x9732 #CJK UNIFIED IDEOGRAPH
+0xC554 0x97FF #CJK UNIFIED IDEOGRAPH
+0xC555 0x9867 #CJK UNIFIED IDEOGRAPH
+0xC556 0x9865 #CJK UNIFIED IDEOGRAPH
+0xC557 0x9957 #CJK UNIFIED IDEOGRAPH
+0xC558 0x9A45 #CJK UNIFIED IDEOGRAPH
+0xC559 0x9A43 #CJK UNIFIED IDEOGRAPH
+0xC55A 0x9A40 #CJK UNIFIED IDEOGRAPH
+0xC55B 0x9A3E #CJK UNIFIED IDEOGRAPH
+0xC55C 0x9ACF #CJK UNIFIED IDEOGRAPH
+0xC55D 0x9B54 #CJK UNIFIED IDEOGRAPH
+0xC55E 0x9B51 #CJK UNIFIED IDEOGRAPH
+0xC55F 0x9C2D #CJK UNIFIED IDEOGRAPH
+0xC560 0x9C25 #CJK UNIFIED IDEOGRAPH
+0xC561 0x9DAF #CJK UNIFIED IDEOGRAPH
+0xC562 0x9DB4 #CJK UNIFIED IDEOGRAPH
+0xC563 0x9DC2 #CJK UNIFIED IDEOGRAPH
+0xC564 0x9DB8 #CJK UNIFIED IDEOGRAPH
+0xC565 0x9E9D #CJK UNIFIED IDEOGRAPH
+0xC566 0x9EEF #CJK UNIFIED IDEOGRAPH
+0xC567 0x9F19 #CJK UNIFIED IDEOGRAPH
+0xC568 0x9F5C #CJK UNIFIED IDEOGRAPH
+0xC569 0x9F66 #CJK UNIFIED IDEOGRAPH
+0xC56A 0x9F67 #CJK UNIFIED IDEOGRAPH
+0xC56B 0x513C #CJK UNIFIED IDEOGRAPH
+0xC56C 0x513B #CJK UNIFIED IDEOGRAPH
+0xC56D 0x56C8 #CJK UNIFIED IDEOGRAPH
+0xC56E 0x56CA #CJK UNIFIED IDEOGRAPH
+0xC56F 0x56C9 #CJK UNIFIED IDEOGRAPH
+0xC570 0x5B7F #CJK UNIFIED IDEOGRAPH
+0xC571 0x5DD4 #CJK UNIFIED IDEOGRAPH
+0xC572 0x5DD2 #CJK UNIFIED IDEOGRAPH
+0xC573 0x5F4E #CJK UNIFIED IDEOGRAPH
+0xC574 0x61FF #CJK UNIFIED IDEOGRAPH
+0xC575 0x6524 #CJK UNIFIED IDEOGRAPH
+0xC576 0x6B0A #CJK UNIFIED IDEOGRAPH
+0xC577 0x6B61 #CJK UNIFIED IDEOGRAPH
+0xC578 0x7051 #CJK UNIFIED IDEOGRAPH
+0xC579 0x7058 #CJK UNIFIED IDEOGRAPH
+0xC57A 0x7380 #CJK UNIFIED IDEOGRAPH
+0xC57B 0x74E4 #CJK UNIFIED IDEOGRAPH
+0xC57C 0x758A #CJK UNIFIED IDEOGRAPH
+0xC57D 0x766E #CJK UNIFIED IDEOGRAPH
+0xC57E 0x766C #CJK UNIFIED IDEOGRAPH
+0xC5A1 0x79B3 #CJK UNIFIED IDEOGRAPH
+0xC5A2 0x7C60 #CJK UNIFIED IDEOGRAPH
+0xC5A3 0x7C5F #CJK UNIFIED IDEOGRAPH
+0xC5A4 0x807E #CJK UNIFIED IDEOGRAPH
+0xC5A5 0x807D #CJK UNIFIED IDEOGRAPH
+0xC5A6 0x81DF #CJK UNIFIED IDEOGRAPH
+0xC5A7 0x8972 #CJK UNIFIED IDEOGRAPH
+0xC5A8 0x896F #CJK UNIFIED IDEOGRAPH
+0xC5A9 0x89FC #CJK UNIFIED IDEOGRAPH
+0xC5AA 0x8B80 #CJK UNIFIED IDEOGRAPH
+0xC5AB 0x8D16 #CJK UNIFIED IDEOGRAPH
+0xC5AC 0x8D17 #CJK UNIFIED IDEOGRAPH
+0xC5AD 0x8E91 #CJK UNIFIED IDEOGRAPH
+0xC5AE 0x8E93 #CJK UNIFIED IDEOGRAPH
+0xC5AF 0x8F61 #CJK UNIFIED IDEOGRAPH
+0xC5B0 0x9148 #CJK UNIFIED IDEOGRAPH
+0xC5B1 0x9444 #CJK UNIFIED IDEOGRAPH
+0xC5B2 0x9451 #CJK UNIFIED IDEOGRAPH
+0xC5B3 0x9452 #CJK UNIFIED IDEOGRAPH
+0xC5B4 0x973D #CJK UNIFIED IDEOGRAPH
+0xC5B5 0x973E #CJK UNIFIED IDEOGRAPH
+0xC5B6 0x97C3 #CJK UNIFIED IDEOGRAPH
+0xC5B7 0x97C1 #CJK UNIFIED IDEOGRAPH
+0xC5B8 0x986B #CJK UNIFIED IDEOGRAPH
+0xC5B9 0x9955 #CJK UNIFIED IDEOGRAPH
+0xC5BA 0x9A55 #CJK UNIFIED IDEOGRAPH
+0xC5BB 0x9A4D #CJK UNIFIED IDEOGRAPH
+0xC5BC 0x9AD2 #CJK UNIFIED IDEOGRAPH
+0xC5BD 0x9B1A #CJK UNIFIED IDEOGRAPH
+0xC5BE 0x9C49 #CJK UNIFIED IDEOGRAPH
+0xC5BF 0x9C31 #CJK UNIFIED IDEOGRAPH
+0xC5C0 0x9C3E #CJK UNIFIED IDEOGRAPH
+0xC5C1 0x9C3B #CJK UNIFIED IDEOGRAPH
+0xC5C2 0x9DD3 #CJK UNIFIED IDEOGRAPH
+0xC5C3 0x9DD7 #CJK UNIFIED IDEOGRAPH
+0xC5C4 0x9F34 #CJK UNIFIED IDEOGRAPH
+0xC5C5 0x9F6C #CJK UNIFIED IDEOGRAPH
+0xC5C6 0x9F6A #CJK UNIFIED IDEOGRAPH
+0xC5C7 0x9F94 #CJK UNIFIED IDEOGRAPH
+0xC5C8 0x56CC #CJK UNIFIED IDEOGRAPH
+0xC5C9 0x5DD6 #CJK UNIFIED IDEOGRAPH
+0xC5CA 0x6200 #CJK UNIFIED IDEOGRAPH
+0xC5CB 0x6523 #CJK UNIFIED IDEOGRAPH
+0xC5CC 0x652B #CJK UNIFIED IDEOGRAPH
+0xC5CD 0x652A #CJK UNIFIED IDEOGRAPH
+0xC5CE 0x66EC #CJK UNIFIED IDEOGRAPH
+0xC5CF 0x6B10 #CJK UNIFIED IDEOGRAPH
+0xC5D0 0x74DA #CJK UNIFIED IDEOGRAPH
+0xC5D1 0x7ACA #CJK UNIFIED IDEOGRAPH
+0xC5D2 0x7C64 #CJK UNIFIED IDEOGRAPH
+0xC5D3 0x7C63 #CJK UNIFIED IDEOGRAPH
+0xC5D4 0x7C65 #CJK UNIFIED IDEOGRAPH
+0xC5D5 0x7E93 #CJK UNIFIED IDEOGRAPH
+0xC5D6 0x7E96 #CJK UNIFIED IDEOGRAPH
+0xC5D7 0x7E94 #CJK UNIFIED IDEOGRAPH
+0xC5D8 0x81E2 #CJK UNIFIED IDEOGRAPH
+0xC5D9 0x8638 #CJK UNIFIED IDEOGRAPH
+0xC5DA 0x863F #CJK UNIFIED IDEOGRAPH
+0xC5DB 0x8831 #CJK UNIFIED IDEOGRAPH
+0xC5DC 0x8B8A #CJK UNIFIED IDEOGRAPH
+0xC5DD 0x9090 #CJK UNIFIED IDEOGRAPH
+0xC5DE 0x908F #CJK UNIFIED IDEOGRAPH
+0xC5DF 0x9463 #CJK UNIFIED IDEOGRAPH
+0xC5E0 0x9460 #CJK UNIFIED IDEOGRAPH
+0xC5E1 0x9464 #CJK UNIFIED IDEOGRAPH
+0xC5E2 0x9768 #CJK UNIFIED IDEOGRAPH
+0xC5E3 0x986F #CJK UNIFIED IDEOGRAPH
+0xC5E4 0x995C #CJK UNIFIED IDEOGRAPH
+0xC5E5 0x9A5A #CJK UNIFIED IDEOGRAPH
+0xC5E6 0x9A5B #CJK UNIFIED IDEOGRAPH
+0xC5E7 0x9A57 #CJK UNIFIED IDEOGRAPH
+0xC5E8 0x9AD3 #CJK UNIFIED IDEOGRAPH
+0xC5E9 0x9AD4 #CJK UNIFIED IDEOGRAPH
+0xC5EA 0x9AD1 #CJK UNIFIED IDEOGRAPH
+0xC5EB 0x9C54 #CJK UNIFIED IDEOGRAPH
+0xC5EC 0x9C57 #CJK UNIFIED IDEOGRAPH
+0xC5ED 0x9C56 #CJK UNIFIED IDEOGRAPH
+0xC5EE 0x9DE5 #CJK UNIFIED IDEOGRAPH
+0xC5EF 0x9E9F #CJK UNIFIED IDEOGRAPH
+0xC5F0 0x9EF4 #CJK UNIFIED IDEOGRAPH
+0xC5F1 0x56D1 #CJK UNIFIED IDEOGRAPH
+0xC5F2 0x58E9 #CJK UNIFIED IDEOGRAPH
+0xC5F3 0x652C #CJK UNIFIED IDEOGRAPH
+0xC5F4 0x705E #CJK UNIFIED IDEOGRAPH
+0xC5F5 0x7671 #CJK UNIFIED IDEOGRAPH
+0xC5F6 0x7672 #CJK UNIFIED IDEOGRAPH
+0xC5F7 0x77D7 #CJK UNIFIED IDEOGRAPH
+0xC5F8 0x7F50 #CJK UNIFIED IDEOGRAPH
+0xC5F9 0x7F88 #CJK UNIFIED IDEOGRAPH
+0xC5FA 0x8836 #CJK UNIFIED IDEOGRAPH
+0xC5FB 0x8839 #CJK UNIFIED IDEOGRAPH
+0xC5FC 0x8862 #CJK UNIFIED IDEOGRAPH
+0xC5FD 0x8B93 #CJK UNIFIED IDEOGRAPH
+0xC5FE 0x8B92 #CJK UNIFIED IDEOGRAPH
+0xC640 0x8B96 #CJK UNIFIED IDEOGRAPH
+0xC641 0x8277 #CJK UNIFIED IDEOGRAPH
+0xC642 0x8D1B #CJK UNIFIED IDEOGRAPH
+0xC643 0x91C0 #CJK UNIFIED IDEOGRAPH
+0xC644 0x946A #CJK UNIFIED IDEOGRAPH
+0xC645 0x9742 #CJK UNIFIED IDEOGRAPH
+0xC646 0x9748 #CJK UNIFIED IDEOGRAPH
+0xC647 0x9744 #CJK UNIFIED IDEOGRAPH
+0xC648 0x97C6 #CJK UNIFIED IDEOGRAPH
+0xC649 0x9870 #CJK UNIFIED IDEOGRAPH
+0xC64A 0x9A5F #CJK UNIFIED IDEOGRAPH
+0xC64B 0x9B22 #CJK UNIFIED IDEOGRAPH
+0xC64C 0x9B58 #CJK UNIFIED IDEOGRAPH
+0xC64D 0x9C5F #CJK UNIFIED IDEOGRAPH
+0xC64E 0x9DF9 #CJK UNIFIED IDEOGRAPH
+0xC64F 0x9DFA #CJK UNIFIED IDEOGRAPH
+0xC650 0x9E7C #CJK UNIFIED IDEOGRAPH
+0xC651 0x9E7D #CJK UNIFIED IDEOGRAPH
+0xC652 0x9F07 #CJK UNIFIED IDEOGRAPH
+0xC653 0x9F77 #CJK UNIFIED IDEOGRAPH
+0xC654 0x9F72 #CJK UNIFIED IDEOGRAPH
+0xC655 0x5EF3 #CJK UNIFIED IDEOGRAPH
+0xC656 0x6B16 #CJK UNIFIED IDEOGRAPH
+0xC657 0x7063 #CJK UNIFIED IDEOGRAPH
+0xC658 0x7C6C #CJK UNIFIED IDEOGRAPH
+0xC659 0x7C6E #CJK UNIFIED IDEOGRAPH
+0xC65A 0x883B #CJK UNIFIED IDEOGRAPH
+0xC65B 0x89C0 #CJK UNIFIED IDEOGRAPH
+0xC65C 0x8EA1 #CJK UNIFIED IDEOGRAPH
+0xC65D 0x91C1 #CJK UNIFIED IDEOGRAPH
+0xC65E 0x9472 #CJK UNIFIED IDEOGRAPH
+0xC65F 0x9470 #CJK UNIFIED IDEOGRAPH
+0xC660 0x9871 #CJK UNIFIED IDEOGRAPH
+0xC661 0x995E #CJK UNIFIED IDEOGRAPH
+0xC662 0x9AD6 #CJK UNIFIED IDEOGRAPH
+0xC663 0x9B23 #CJK UNIFIED IDEOGRAPH
+0xC664 0x9ECC #CJK UNIFIED IDEOGRAPH
+0xC665 0x7064 #CJK UNIFIED IDEOGRAPH
+0xC666 0x77DA #CJK UNIFIED IDEOGRAPH
+0xC667 0x8B9A #CJK UNIFIED IDEOGRAPH
+0xC668 0x9477 #CJK UNIFIED IDEOGRAPH
+0xC669 0x97C9 #CJK UNIFIED IDEOGRAPH
+0xC66A 0x9A62 #CJK UNIFIED IDEOGRAPH
+0xC66B 0x9A65 #CJK UNIFIED IDEOGRAPH
+0xC66C 0x7E9C #CJK UNIFIED IDEOGRAPH
+0xC66D 0x8B9C #CJK UNIFIED IDEOGRAPH
+0xC66E 0x8EAA #CJK UNIFIED IDEOGRAPH
+0xC66F 0x91C5 #CJK UNIFIED IDEOGRAPH
+0xC670 0x947D #CJK UNIFIED IDEOGRAPH
+0xC671 0x947E #CJK UNIFIED IDEOGRAPH
+0xC672 0x947C #CJK UNIFIED IDEOGRAPH
+0xC673 0x9C77 #CJK UNIFIED IDEOGRAPH
+0xC674 0x9C78 #CJK UNIFIED IDEOGRAPH
+0xC675 0x9EF7 #CJK UNIFIED IDEOGRAPH
+0xC676 0x8C54 #CJK UNIFIED IDEOGRAPH
+0xC677 0x947F #CJK UNIFIED IDEOGRAPH
+0xC678 0x9E1A #CJK UNIFIED IDEOGRAPH
+0xC679 0x7228 #CJK UNIFIED IDEOGRAPH
+0xC67A 0x9A6A #CJK UNIFIED IDEOGRAPH
+0xC67B 0x9B31 #CJK UNIFIED IDEOGRAPH
+0xC67C 0x9E1B #CJK UNIFIED IDEOGRAPH
+0xC67D 0x9E1E #CJK UNIFIED IDEOGRAPH
+0xC67E 0x7C72 #CJK UNIFIED IDEOGRAPH
+0xC940 0x4E42 #CJK UNIFIED IDEOGRAPH
+0xC941 0x4E5C #CJK UNIFIED IDEOGRAPH
+0xC942 0x51F5 #CJK UNIFIED IDEOGRAPH
+0xC943 0x531A #CJK UNIFIED IDEOGRAPH
+0xC944 0x5382 #CJK UNIFIED IDEOGRAPH
+0xC945 0x4E07 #CJK UNIFIED IDEOGRAPH
+0xC946 0x4E0C #CJK UNIFIED IDEOGRAPH
+0xC947 0x4E47 #CJK UNIFIED IDEOGRAPH
+0xC948 0x4E8D #CJK UNIFIED IDEOGRAPH
+0xC949 0x56D7 #CJK UNIFIED IDEOGRAPH
+0xC94A 0xFA0C #CJK COMPATIBILITY IDEOGRAPH
+0xC94B 0x5C6E #CJK UNIFIED IDEOGRAPH
+0xC94C 0x5F73 #CJK UNIFIED IDEOGRAPH
+0xC94D 0x4E0F #CJK UNIFIED IDEOGRAPH
+0xC94E 0x5187 #CJK UNIFIED IDEOGRAPH
+0xC94F 0x4E0E #CJK UNIFIED IDEOGRAPH
+0xC950 0x4E2E #CJK UNIFIED IDEOGRAPH
+0xC951 0x4E93 #CJK UNIFIED IDEOGRAPH
+0xC952 0x4EC2 #CJK UNIFIED IDEOGRAPH
+0xC953 0x4EC9 #CJK UNIFIED IDEOGRAPH
+0xC954 0x4EC8 #CJK UNIFIED IDEOGRAPH
+0xC955 0x5198 #CJK UNIFIED IDEOGRAPH
+0xC956 0x52FC #CJK UNIFIED IDEOGRAPH
+0xC957 0x536C #CJK UNIFIED IDEOGRAPH
+0xC958 0x53B9 #CJK UNIFIED IDEOGRAPH
+0xC959 0x5720 #CJK UNIFIED IDEOGRAPH
+0xC95A 0x5903 #CJK UNIFIED IDEOGRAPH
+0xC95B 0x592C #CJK UNIFIED IDEOGRAPH
+0xC95C 0x5C10 #CJK UNIFIED IDEOGRAPH
+0xC95D 0x5DFF #CJK UNIFIED IDEOGRAPH
+0xC95E 0x65E1 #CJK UNIFIED IDEOGRAPH
+0xC95F 0x6BB3 #CJK UNIFIED IDEOGRAPH
+0xC960 0x6BCC #CJK UNIFIED IDEOGRAPH
+0xC961 0x6C14 #CJK UNIFIED IDEOGRAPH
+0xC962 0x723F #CJK UNIFIED IDEOGRAPH
+0xC963 0x4E31 #CJK UNIFIED IDEOGRAPH
+0xC964 0x4E3C #CJK UNIFIED IDEOGRAPH
+0xC965 0x4EE8 #CJK UNIFIED IDEOGRAPH
+0xC966 0x4EDC #CJK UNIFIED IDEOGRAPH
+0xC967 0x4EE9 #CJK UNIFIED IDEOGRAPH
+0xC968 0x4EE1 #CJK UNIFIED IDEOGRAPH
+0xC969 0x4EDD #CJK UNIFIED IDEOGRAPH
+0xC96A 0x4EDA #CJK UNIFIED IDEOGRAPH
+0xC96B 0x520C #CJK UNIFIED IDEOGRAPH
+0xC96C 0x531C #CJK UNIFIED IDEOGRAPH
+0xC96D 0x534C #CJK UNIFIED IDEOGRAPH
+0xC96E 0x5722 #CJK UNIFIED IDEOGRAPH
+0xC96F 0x5723 #CJK UNIFIED IDEOGRAPH
+0xC970 0x5917 #CJK UNIFIED IDEOGRAPH
+0xC971 0x592F #CJK UNIFIED IDEOGRAPH
+0xC972 0x5B81 #CJK UNIFIED IDEOGRAPH
+0xC973 0x5B84 #CJK UNIFIED IDEOGRAPH
+0xC974 0x5C12 #CJK UNIFIED IDEOGRAPH
+0xC975 0x5C3B #CJK UNIFIED IDEOGRAPH
+0xC976 0x5C74 #CJK UNIFIED IDEOGRAPH
+0xC977 0x5C73 #CJK UNIFIED IDEOGRAPH
+0xC978 0x5E04 #CJK UNIFIED IDEOGRAPH
+0xC979 0x5E80 #CJK UNIFIED IDEOGRAPH
+0xC97A 0x5E82 #CJK UNIFIED IDEOGRAPH
+0xC97B 0x5FC9 #CJK UNIFIED IDEOGRAPH
+0xC97C 0x6209 #CJK UNIFIED IDEOGRAPH
+0xC97D 0x6250 #CJK UNIFIED IDEOGRAPH
+0xC97E 0x6C15 #CJK UNIFIED IDEOGRAPH
+0xC9A1 0x6C36 #CJK UNIFIED IDEOGRAPH
+0xC9A2 0x6C43 #CJK UNIFIED IDEOGRAPH
+0xC9A3 0x6C3F #CJK UNIFIED IDEOGRAPH
+0xC9A4 0x6C3B #CJK UNIFIED IDEOGRAPH
+0xC9A5 0x72AE #CJK UNIFIED IDEOGRAPH
+0xC9A6 0x72B0 #CJK UNIFIED IDEOGRAPH
+0xC9A7 0x738A #CJK UNIFIED IDEOGRAPH
+0xC9A8 0x79B8 #CJK UNIFIED IDEOGRAPH
+0xC9A9 0x808A #CJK UNIFIED IDEOGRAPH
+0xC9AA 0x961E #CJK UNIFIED IDEOGRAPH
+0xC9AB 0x4F0E #CJK UNIFIED IDEOGRAPH
+0xC9AC 0x4F18 #CJK UNIFIED IDEOGRAPH
+0xC9AD 0x4F2C #CJK UNIFIED IDEOGRAPH
+0xC9AE 0x4EF5 #CJK UNIFIED IDEOGRAPH
+0xC9AF 0x4F14 #CJK UNIFIED IDEOGRAPH
+0xC9B0 0x4EF1 #CJK UNIFIED IDEOGRAPH
+0xC9B1 0x4F00 #CJK UNIFIED IDEOGRAPH
+0xC9B2 0x4EF7 #CJK UNIFIED IDEOGRAPH
+0xC9B3 0x4F08 #CJK UNIFIED IDEOGRAPH
+0xC9B4 0x4F1D #CJK UNIFIED IDEOGRAPH
+0xC9B5 0x4F02 #CJK UNIFIED IDEOGRAPH
+0xC9B6 0x4F05 #CJK UNIFIED IDEOGRAPH
+0xC9B7 0x4F22 #CJK UNIFIED IDEOGRAPH
+0xC9B8 0x4F13 #CJK UNIFIED IDEOGRAPH
+0xC9B9 0x4F04 #CJK UNIFIED IDEOGRAPH
+0xC9BA 0x4EF4 #CJK UNIFIED IDEOGRAPH
+0xC9BB 0x4F12 #CJK UNIFIED IDEOGRAPH
+0xC9BC 0x51B1 #CJK UNIFIED IDEOGRAPH
+0xC9BD 0x5213 #CJK UNIFIED IDEOGRAPH
+0xC9BE 0x5209 #CJK UNIFIED IDEOGRAPH
+0xC9BF 0x5210 #CJK UNIFIED IDEOGRAPH
+0xC9C0 0x52A6 #CJK UNIFIED IDEOGRAPH
+0xC9C1 0x5322 #CJK UNIFIED IDEOGRAPH
+0xC9C2 0x531F #CJK UNIFIED IDEOGRAPH
+0xC9C3 0x534D #CJK UNIFIED IDEOGRAPH
+0xC9C4 0x538A #CJK UNIFIED IDEOGRAPH
+0xC9C5 0x5407 #CJK UNIFIED IDEOGRAPH
+0xC9C6 0x56E1 #CJK UNIFIED IDEOGRAPH
+0xC9C7 0x56DF #CJK UNIFIED IDEOGRAPH
+0xC9C8 0x572E #CJK UNIFIED IDEOGRAPH
+0xC9C9 0x572A #CJK UNIFIED IDEOGRAPH
+0xC9CA 0x5734 #CJK UNIFIED IDEOGRAPH
+0xC9CB 0x593C #CJK UNIFIED IDEOGRAPH
+0xC9CC 0x5980 #CJK UNIFIED IDEOGRAPH
+0xC9CD 0x597C #CJK UNIFIED IDEOGRAPH
+0xC9CE 0x5985 #CJK UNIFIED IDEOGRAPH
+0xC9CF 0x597B #CJK UNIFIED IDEOGRAPH
+0xC9D0 0x597E #CJK UNIFIED IDEOGRAPH
+0xC9D1 0x5977 #CJK UNIFIED IDEOGRAPH
+0xC9D2 0x597F #CJK UNIFIED IDEOGRAPH
+0xC9D3 0x5B56 #CJK UNIFIED IDEOGRAPH
+0xC9D4 0x5C15 #CJK UNIFIED IDEOGRAPH
+0xC9D5 0x5C25 #CJK UNIFIED IDEOGRAPH
+0xC9D6 0x5C7C #CJK UNIFIED IDEOGRAPH
+0xC9D7 0x5C7A #CJK UNIFIED IDEOGRAPH
+0xC9D8 0x5C7B #CJK UNIFIED IDEOGRAPH
+0xC9D9 0x5C7E #CJK UNIFIED IDEOGRAPH
+0xC9DA 0x5DDF #CJK UNIFIED IDEOGRAPH
+0xC9DB 0x5E75 #CJK UNIFIED IDEOGRAPH
+0xC9DC 0x5E84 #CJK UNIFIED IDEOGRAPH
+0xC9DD 0x5F02 #CJK UNIFIED IDEOGRAPH
+0xC9DE 0x5F1A #CJK UNIFIED IDEOGRAPH
+0xC9DF 0x5F74 #CJK UNIFIED IDEOGRAPH
+0xC9E0 0x5FD5 #CJK UNIFIED IDEOGRAPH
+0xC9E1 0x5FD4 #CJK UNIFIED IDEOGRAPH
+0xC9E2 0x5FCF #CJK UNIFIED IDEOGRAPH
+0xC9E3 0x625C #CJK UNIFIED IDEOGRAPH
+0xC9E4 0x625E #CJK UNIFIED IDEOGRAPH
+0xC9E5 0x6264 #CJK UNIFIED IDEOGRAPH
+0xC9E6 0x6261 #CJK UNIFIED IDEOGRAPH
+0xC9E7 0x6266 #CJK UNIFIED IDEOGRAPH
+0xC9E8 0x6262 #CJK UNIFIED IDEOGRAPH
+0xC9E9 0x6259 #CJK UNIFIED IDEOGRAPH
+0xC9EA 0x6260 #CJK UNIFIED IDEOGRAPH
+0xC9EB 0x625A #CJK UNIFIED IDEOGRAPH
+0xC9EC 0x6265 #CJK UNIFIED IDEOGRAPH
+0xC9ED 0x65EF #CJK UNIFIED IDEOGRAPH
+0xC9EE 0x65EE #CJK UNIFIED IDEOGRAPH
+0xC9EF 0x673E #CJK UNIFIED IDEOGRAPH
+0xC9F0 0x6739 #CJK UNIFIED IDEOGRAPH
+0xC9F1 0x6738 #CJK UNIFIED IDEOGRAPH
+0xC9F2 0x673B #CJK UNIFIED IDEOGRAPH
+0xC9F3 0x673A #CJK UNIFIED IDEOGRAPH
+0xC9F4 0x673F #CJK UNIFIED IDEOGRAPH
+0xC9F5 0x673C #CJK UNIFIED IDEOGRAPH
+0xC9F6 0x6733 #CJK UNIFIED IDEOGRAPH
+0xC9F7 0x6C18 #CJK UNIFIED IDEOGRAPH
+0xC9F8 0x6C46 #CJK UNIFIED IDEOGRAPH
+0xC9F9 0x6C52 #CJK UNIFIED IDEOGRAPH
+0xC9FA 0x6C5C #CJK UNIFIED IDEOGRAPH
+0xC9FB 0x6C4F #CJK UNIFIED IDEOGRAPH
+0xC9FC 0x6C4A #CJK UNIFIED IDEOGRAPH
+0xC9FD 0x6C54 #CJK UNIFIED IDEOGRAPH
+0xC9FE 0x6C4B #CJK UNIFIED IDEOGRAPH
+0xCA40 0x6C4C #CJK UNIFIED IDEOGRAPH
+0xCA41 0x7071 #CJK UNIFIED IDEOGRAPH
+0xCA42 0x725E #CJK UNIFIED IDEOGRAPH
+0xCA43 0x72B4 #CJK UNIFIED IDEOGRAPH
+0xCA44 0x72B5 #CJK UNIFIED IDEOGRAPH
+0xCA45 0x738E #CJK UNIFIED IDEOGRAPH
+0xCA46 0x752A #CJK UNIFIED IDEOGRAPH
+0xCA47 0x767F #CJK UNIFIED IDEOGRAPH
+0xCA48 0x7A75 #CJK UNIFIED IDEOGRAPH
+0xCA49 0x7F51 #CJK UNIFIED IDEOGRAPH
+0xCA4A 0x8278 #CJK UNIFIED IDEOGRAPH
+0xCA4B 0x827C #CJK UNIFIED IDEOGRAPH
+0xCA4C 0x8280 #CJK UNIFIED IDEOGRAPH
+0xCA4D 0x827D #CJK UNIFIED IDEOGRAPH
+0xCA4E 0x827F #CJK UNIFIED IDEOGRAPH
+0xCA4F 0x864D #CJK UNIFIED IDEOGRAPH
+0xCA50 0x897E #CJK UNIFIED IDEOGRAPH
+0xCA51 0x9099 #CJK UNIFIED IDEOGRAPH
+0xCA52 0x9097 #CJK UNIFIED IDEOGRAPH
+0xCA53 0x9098 #CJK UNIFIED IDEOGRAPH
+0xCA54 0x909B #CJK UNIFIED IDEOGRAPH
+0xCA55 0x9094 #CJK UNIFIED IDEOGRAPH
+0xCA56 0x9622 #CJK UNIFIED IDEOGRAPH
+0xCA57 0x9624 #CJK UNIFIED IDEOGRAPH
+0xCA58 0x9620 #CJK UNIFIED IDEOGRAPH
+0xCA59 0x9623 #CJK UNIFIED IDEOGRAPH
+0xCA5A 0x4F56 #CJK UNIFIED IDEOGRAPH
+0xCA5B 0x4F3B #CJK UNIFIED IDEOGRAPH
+0xCA5C 0x4F62 #CJK UNIFIED IDEOGRAPH
+0xCA5D 0x4F49 #CJK UNIFIED IDEOGRAPH
+0xCA5E 0x4F53 #CJK UNIFIED IDEOGRAPH
+0xCA5F 0x4F64 #CJK UNIFIED IDEOGRAPH
+0xCA60 0x4F3E #CJK UNIFIED IDEOGRAPH
+0xCA61 0x4F67 #CJK UNIFIED IDEOGRAPH
+0xCA62 0x4F52 #CJK UNIFIED IDEOGRAPH
+0xCA63 0x4F5F #CJK UNIFIED IDEOGRAPH
+0xCA64 0x4F41 #CJK UNIFIED IDEOGRAPH
+0xCA65 0x4F58 #CJK UNIFIED IDEOGRAPH
+0xCA66 0x4F2D #CJK UNIFIED IDEOGRAPH
+0xCA67 0x4F33 #CJK UNIFIED IDEOGRAPH
+0xCA68 0x4F3F #CJK UNIFIED IDEOGRAPH
+0xCA69 0x4F61 #CJK UNIFIED IDEOGRAPH
+0xCA6A 0x518F #CJK UNIFIED IDEOGRAPH
+0xCA6B 0x51B9 #CJK UNIFIED IDEOGRAPH
+0xCA6C 0x521C #CJK UNIFIED IDEOGRAPH
+0xCA6D 0x521E #CJK UNIFIED IDEOGRAPH
+0xCA6E 0x5221 #CJK UNIFIED IDEOGRAPH
+0xCA6F 0x52AD #CJK UNIFIED IDEOGRAPH
+0xCA70 0x52AE #CJK UNIFIED IDEOGRAPH
+0xCA71 0x5309 #CJK UNIFIED IDEOGRAPH
+0xCA72 0x5363 #CJK UNIFIED IDEOGRAPH
+0xCA73 0x5372 #CJK UNIFIED IDEOGRAPH
+0xCA74 0x538E #CJK UNIFIED IDEOGRAPH
+0xCA75 0x538F #CJK UNIFIED IDEOGRAPH
+0xCA76 0x5430 #CJK UNIFIED IDEOGRAPH
+0xCA77 0x5437 #CJK UNIFIED IDEOGRAPH
+0xCA78 0x542A #CJK UNIFIED IDEOGRAPH
+0xCA79 0x5454 #CJK UNIFIED IDEOGRAPH
+0xCA7A 0x5445 #CJK UNIFIED IDEOGRAPH
+0xCA7B 0x5419 #CJK UNIFIED IDEOGRAPH
+0xCA7C 0x541C #CJK UNIFIED IDEOGRAPH
+0xCA7D 0x5425 #CJK UNIFIED IDEOGRAPH
+0xCA7E 0x5418 #CJK UNIFIED IDEOGRAPH
+0xCAA1 0x543D #CJK UNIFIED IDEOGRAPH
+0xCAA2 0x544F #CJK UNIFIED IDEOGRAPH
+0xCAA3 0x5441 #CJK UNIFIED IDEOGRAPH
+0xCAA4 0x5428 #CJK UNIFIED IDEOGRAPH
+0xCAA5 0x5424 #CJK UNIFIED IDEOGRAPH
+0xCAA6 0x5447 #CJK UNIFIED IDEOGRAPH
+0xCAA7 0x56EE #CJK UNIFIED IDEOGRAPH
+0xCAA8 0x56E7 #CJK UNIFIED IDEOGRAPH
+0xCAA9 0x56E5 #CJK UNIFIED IDEOGRAPH
+0xCAAA 0x5741 #CJK UNIFIED IDEOGRAPH
+0xCAAB 0x5745 #CJK UNIFIED IDEOGRAPH
+0xCAAC 0x574C #CJK UNIFIED IDEOGRAPH
+0xCAAD 0x5749 #CJK UNIFIED IDEOGRAPH
+0xCAAE 0x574B #CJK UNIFIED IDEOGRAPH
+0xCAAF 0x5752 #CJK UNIFIED IDEOGRAPH
+0xCAB0 0x5906 #CJK UNIFIED IDEOGRAPH
+0xCAB1 0x5940 #CJK UNIFIED IDEOGRAPH
+0xCAB2 0x59A6 #CJK UNIFIED IDEOGRAPH
+0xCAB3 0x5998 #CJK UNIFIED IDEOGRAPH
+0xCAB4 0x59A0 #CJK UNIFIED IDEOGRAPH
+0xCAB5 0x5997 #CJK UNIFIED IDEOGRAPH
+0xCAB6 0x598E #CJK UNIFIED IDEOGRAPH
+0xCAB7 0x59A2 #CJK UNIFIED IDEOGRAPH
+0xCAB8 0x5990 #CJK UNIFIED IDEOGRAPH
+0xCAB9 0x598F #CJK UNIFIED IDEOGRAPH
+0xCABA 0x59A7 #CJK UNIFIED IDEOGRAPH
+0xCABB 0x59A1 #CJK UNIFIED IDEOGRAPH
+0xCABC 0x5B8E #CJK UNIFIED IDEOGRAPH
+0xCABD 0x5B92 #CJK UNIFIED IDEOGRAPH
+0xCABE 0x5C28 #CJK UNIFIED IDEOGRAPH
+0xCABF 0x5C2A #CJK UNIFIED IDEOGRAPH
+0xCAC0 0x5C8D #CJK UNIFIED IDEOGRAPH
+0xCAC1 0x5C8F #CJK UNIFIED IDEOGRAPH
+0xCAC2 0x5C88 #CJK UNIFIED IDEOGRAPH
+0xCAC3 0x5C8B #CJK UNIFIED IDEOGRAPH
+0xCAC4 0x5C89 #CJK UNIFIED IDEOGRAPH
+0xCAC5 0x5C92 #CJK UNIFIED IDEOGRAPH
+0xCAC6 0x5C8A #CJK UNIFIED IDEOGRAPH
+0xCAC7 0x5C86 #CJK UNIFIED IDEOGRAPH
+0xCAC8 0x5C93 #CJK UNIFIED IDEOGRAPH
+0xCAC9 0x5C95 #CJK UNIFIED IDEOGRAPH
+0xCACA 0x5DE0 #CJK UNIFIED IDEOGRAPH
+0xCACB 0x5E0A #CJK UNIFIED IDEOGRAPH
+0xCACC 0x5E0E #CJK UNIFIED IDEOGRAPH
+0xCACD 0x5E8B #CJK UNIFIED IDEOGRAPH
+0xCACE 0x5E89 #CJK UNIFIED IDEOGRAPH
+0xCACF 0x5E8C #CJK UNIFIED IDEOGRAPH
+0xCAD0 0x5E88 #CJK UNIFIED IDEOGRAPH
+0xCAD1 0x5E8D #CJK UNIFIED IDEOGRAPH
+0xCAD2 0x5F05 #CJK UNIFIED IDEOGRAPH
+0xCAD3 0x5F1D #CJK UNIFIED IDEOGRAPH
+0xCAD4 0x5F78 #CJK UNIFIED IDEOGRAPH
+0xCAD5 0x5F76 #CJK UNIFIED IDEOGRAPH
+0xCAD6 0x5FD2 #CJK UNIFIED IDEOGRAPH
+0xCAD7 0x5FD1 #CJK UNIFIED IDEOGRAPH
+0xCAD8 0x5FD0 #CJK UNIFIED IDEOGRAPH
+0xCAD9 0x5FED #CJK UNIFIED IDEOGRAPH
+0xCADA 0x5FE8 #CJK UNIFIED IDEOGRAPH
+0xCADB 0x5FEE #CJK UNIFIED IDEOGRAPH
+0xCADC 0x5FF3 #CJK UNIFIED IDEOGRAPH
+0xCADD 0x5FE1 #CJK UNIFIED IDEOGRAPH
+0xCADE 0x5FE4 #CJK UNIFIED IDEOGRAPH
+0xCADF 0x5FE3 #CJK UNIFIED IDEOGRAPH
+0xCAE0 0x5FFA #CJK UNIFIED IDEOGRAPH
+0xCAE1 0x5FEF #CJK UNIFIED IDEOGRAPH
+0xCAE2 0x5FF7 #CJK UNIFIED IDEOGRAPH
+0xCAE3 0x5FFB #CJK UNIFIED IDEOGRAPH
+0xCAE4 0x6000 #CJK UNIFIED IDEOGRAPH
+0xCAE5 0x5FF4 #CJK UNIFIED IDEOGRAPH
+0xCAE6 0x623A #CJK UNIFIED IDEOGRAPH
+0xCAE7 0x6283 #CJK UNIFIED IDEOGRAPH
+0xCAE8 0x628C #CJK UNIFIED IDEOGRAPH
+0xCAE9 0x628E #CJK UNIFIED IDEOGRAPH
+0xCAEA 0x628F #CJK UNIFIED IDEOGRAPH
+0xCAEB 0x6294 #CJK UNIFIED IDEOGRAPH
+0xCAEC 0x6287 #CJK UNIFIED IDEOGRAPH
+0xCAED 0x6271 #CJK UNIFIED IDEOGRAPH
+0xCAEE 0x627B #CJK UNIFIED IDEOGRAPH
+0xCAEF 0x627A #CJK UNIFIED IDEOGRAPH
+0xCAF0 0x6270 #CJK UNIFIED IDEOGRAPH
+0xCAF1 0x6281 #CJK UNIFIED IDEOGRAPH
+0xCAF2 0x6288 #CJK UNIFIED IDEOGRAPH
+0xCAF3 0x6277 #CJK UNIFIED IDEOGRAPH
+0xCAF4 0x627D #CJK UNIFIED IDEOGRAPH
+0xCAF5 0x6272 #CJK UNIFIED IDEOGRAPH
+0xCAF6 0x6274 #CJK UNIFIED IDEOGRAPH
+0xCAF7 0x6537 #CJK UNIFIED IDEOGRAPH
+0xCAF8 0x65F0 #CJK UNIFIED IDEOGRAPH
+0xCAF9 0x65F4 #CJK UNIFIED IDEOGRAPH
+0xCAFA 0x65F3 #CJK UNIFIED IDEOGRAPH
+0xCAFB 0x65F2 #CJK UNIFIED IDEOGRAPH
+0xCAFC 0x65F5 #CJK UNIFIED IDEOGRAPH
+0xCAFD 0x6745 #CJK UNIFIED IDEOGRAPH
+0xCAFE 0x6747 #CJK UNIFIED IDEOGRAPH
+0xCB40 0x6759 #CJK UNIFIED IDEOGRAPH
+0xCB41 0x6755 #CJK UNIFIED IDEOGRAPH
+0xCB42 0x674C #CJK UNIFIED IDEOGRAPH
+0xCB43 0x6748 #CJK UNIFIED IDEOGRAPH
+0xCB44 0x675D #CJK UNIFIED IDEOGRAPH
+0xCB45 0x674D #CJK UNIFIED IDEOGRAPH
+0xCB46 0x675A #CJK UNIFIED IDEOGRAPH
+0xCB47 0x674B #CJK UNIFIED IDEOGRAPH
+0xCB48 0x6BD0 #CJK UNIFIED IDEOGRAPH
+0xCB49 0x6C19 #CJK UNIFIED IDEOGRAPH
+0xCB4A 0x6C1A #CJK UNIFIED IDEOGRAPH
+0xCB4B 0x6C78 #CJK UNIFIED IDEOGRAPH
+0xCB4C 0x6C67 #CJK UNIFIED IDEOGRAPH
+0xCB4D 0x6C6B #CJK UNIFIED IDEOGRAPH
+0xCB4E 0x6C84 #CJK UNIFIED IDEOGRAPH
+0xCB4F 0x6C8B #CJK UNIFIED IDEOGRAPH
+0xCB50 0x6C8F #CJK UNIFIED IDEOGRAPH
+0xCB51 0x6C71 #CJK UNIFIED IDEOGRAPH
+0xCB52 0x6C6F #CJK UNIFIED IDEOGRAPH
+0xCB53 0x6C69 #CJK UNIFIED IDEOGRAPH
+0xCB54 0x6C9A #CJK UNIFIED IDEOGRAPH
+0xCB55 0x6C6D #CJK UNIFIED IDEOGRAPH
+0xCB56 0x6C87 #CJK UNIFIED IDEOGRAPH
+0xCB57 0x6C95 #CJK UNIFIED IDEOGRAPH
+0xCB58 0x6C9C #CJK UNIFIED IDEOGRAPH
+0xCB59 0x6C66 #CJK UNIFIED IDEOGRAPH
+0xCB5A 0x6C73 #CJK UNIFIED IDEOGRAPH
+0xCB5B 0x6C65 #CJK UNIFIED IDEOGRAPH
+0xCB5C 0x6C7B #CJK UNIFIED IDEOGRAPH
+0xCB5D 0x6C8E #CJK UNIFIED IDEOGRAPH
+0xCB5E 0x7074 #CJK UNIFIED IDEOGRAPH
+0xCB5F 0x707A #CJK UNIFIED IDEOGRAPH
+0xCB60 0x7263 #CJK UNIFIED IDEOGRAPH
+0xCB61 0x72BF #CJK UNIFIED IDEOGRAPH
+0xCB62 0x72BD #CJK UNIFIED IDEOGRAPH
+0xCB63 0x72C3 #CJK UNIFIED IDEOGRAPH
+0xCB64 0x72C6 #CJK UNIFIED IDEOGRAPH
+0xCB65 0x72C1 #CJK UNIFIED IDEOGRAPH
+0xCB66 0x72BA #CJK UNIFIED IDEOGRAPH
+0xCB67 0x72C5 #CJK UNIFIED IDEOGRAPH
+0xCB68 0x7395 #CJK UNIFIED IDEOGRAPH
+0xCB69 0x7397 #CJK UNIFIED IDEOGRAPH
+0xCB6A 0x7393 #CJK UNIFIED IDEOGRAPH
+0xCB6B 0x7394 #CJK UNIFIED IDEOGRAPH
+0xCB6C 0x7392 #CJK UNIFIED IDEOGRAPH
+0xCB6D 0x753A #CJK UNIFIED IDEOGRAPH
+0xCB6E 0x7539 #CJK UNIFIED IDEOGRAPH
+0xCB6F 0x7594 #CJK UNIFIED IDEOGRAPH
+0xCB70 0x7595 #CJK UNIFIED IDEOGRAPH
+0xCB71 0x7681 #CJK UNIFIED IDEOGRAPH
+0xCB72 0x793D #CJK UNIFIED IDEOGRAPH
+0xCB73 0x8034 #CJK UNIFIED IDEOGRAPH
+0xCB74 0x8095 #CJK UNIFIED IDEOGRAPH
+0xCB75 0x8099 #CJK UNIFIED IDEOGRAPH
+0xCB76 0x8090 #CJK UNIFIED IDEOGRAPH
+0xCB77 0x8092 #CJK UNIFIED IDEOGRAPH
+0xCB78 0x809C #CJK UNIFIED IDEOGRAPH
+0xCB79 0x8290 #CJK UNIFIED IDEOGRAPH
+0xCB7A 0x828F #CJK UNIFIED IDEOGRAPH
+0xCB7B 0x8285 #CJK UNIFIED IDEOGRAPH
+0xCB7C 0x828E #CJK UNIFIED IDEOGRAPH
+0xCB7D 0x8291 #CJK UNIFIED IDEOGRAPH
+0xCB7E 0x8293 #CJK UNIFIED IDEOGRAPH
+0xCBA1 0x828A #CJK UNIFIED IDEOGRAPH
+0xCBA2 0x8283 #CJK UNIFIED IDEOGRAPH
+0xCBA3 0x8284 #CJK UNIFIED IDEOGRAPH
+0xCBA4 0x8C78 #CJK UNIFIED IDEOGRAPH
+0xCBA5 0x8FC9 #CJK UNIFIED IDEOGRAPH
+0xCBA6 0x8FBF #CJK UNIFIED IDEOGRAPH
+0xCBA7 0x909F #CJK UNIFIED IDEOGRAPH
+0xCBA8 0x90A1 #CJK UNIFIED IDEOGRAPH
+0xCBA9 0x90A5 #CJK UNIFIED IDEOGRAPH
+0xCBAA 0x909E #CJK UNIFIED IDEOGRAPH
+0xCBAB 0x90A7 #CJK UNIFIED IDEOGRAPH
+0xCBAC 0x90A0 #CJK UNIFIED IDEOGRAPH
+0xCBAD 0x9630 #CJK UNIFIED IDEOGRAPH
+0xCBAE 0x9628 #CJK UNIFIED IDEOGRAPH
+0xCBAF 0x962F #CJK UNIFIED IDEOGRAPH
+0xCBB0 0x962D #CJK UNIFIED IDEOGRAPH
+0xCBB1 0x4E33 #CJK UNIFIED IDEOGRAPH
+0xCBB2 0x4F98 #CJK UNIFIED IDEOGRAPH
+0xCBB3 0x4F7C #CJK UNIFIED IDEOGRAPH
+0xCBB4 0x4F85 #CJK UNIFIED IDEOGRAPH
+0xCBB5 0x4F7D #CJK UNIFIED IDEOGRAPH
+0xCBB6 0x4F80 #CJK UNIFIED IDEOGRAPH
+0xCBB7 0x4F87 #CJK UNIFIED IDEOGRAPH
+0xCBB8 0x4F76 #CJK UNIFIED IDEOGRAPH
+0xCBB9 0x4F74 #CJK UNIFIED IDEOGRAPH
+0xCBBA 0x4F89 #CJK UNIFIED IDEOGRAPH
+0xCBBB 0x4F84 #CJK UNIFIED IDEOGRAPH
+0xCBBC 0x4F77 #CJK UNIFIED IDEOGRAPH
+0xCBBD 0x4F4C #CJK UNIFIED IDEOGRAPH
+0xCBBE 0x4F97 #CJK UNIFIED IDEOGRAPH
+0xCBBF 0x4F6A #CJK UNIFIED IDEOGRAPH
+0xCBC0 0x4F9A #CJK UNIFIED IDEOGRAPH
+0xCBC1 0x4F79 #CJK UNIFIED IDEOGRAPH
+0xCBC2 0x4F81 #CJK UNIFIED IDEOGRAPH
+0xCBC3 0x4F78 #CJK UNIFIED IDEOGRAPH
+0xCBC4 0x4F90 #CJK UNIFIED IDEOGRAPH
+0xCBC5 0x4F9C #CJK UNIFIED IDEOGRAPH
+0xCBC6 0x4F94 #CJK UNIFIED IDEOGRAPH
+0xCBC7 0x4F9E #CJK UNIFIED IDEOGRAPH
+0xCBC8 0x4F92 #CJK UNIFIED IDEOGRAPH
+0xCBC9 0x4F82 #CJK UNIFIED IDEOGRAPH
+0xCBCA 0x4F95 #CJK UNIFIED IDEOGRAPH
+0xCBCB 0x4F6B #CJK UNIFIED IDEOGRAPH
+0xCBCC 0x4F6E #CJK UNIFIED IDEOGRAPH
+0xCBCD 0x519E #CJK UNIFIED IDEOGRAPH
+0xCBCE 0x51BC #CJK UNIFIED IDEOGRAPH
+0xCBCF 0x51BE #CJK UNIFIED IDEOGRAPH
+0xCBD0 0x5235 #CJK UNIFIED IDEOGRAPH
+0xCBD1 0x5232 #CJK UNIFIED IDEOGRAPH
+0xCBD2 0x5233 #CJK UNIFIED IDEOGRAPH
+0xCBD3 0x5246 #CJK UNIFIED IDEOGRAPH
+0xCBD4 0x5231 #CJK UNIFIED IDEOGRAPH
+0xCBD5 0x52BC #CJK UNIFIED IDEOGRAPH
+0xCBD6 0x530A #CJK UNIFIED IDEOGRAPH
+0xCBD7 0x530B #CJK UNIFIED IDEOGRAPH
+0xCBD8 0x533C #CJK UNIFIED IDEOGRAPH
+0xCBD9 0x5392 #CJK UNIFIED IDEOGRAPH
+0xCBDA 0x5394 #CJK UNIFIED IDEOGRAPH
+0xCBDB 0x5487 #CJK UNIFIED IDEOGRAPH
+0xCBDC 0x547F #CJK UNIFIED IDEOGRAPH
+0xCBDD 0x5481 #CJK UNIFIED IDEOGRAPH
+0xCBDE 0x5491 #CJK UNIFIED IDEOGRAPH
+0xCBDF 0x5482 #CJK UNIFIED IDEOGRAPH
+0xCBE0 0x5488 #CJK UNIFIED IDEOGRAPH
+0xCBE1 0x546B #CJK UNIFIED IDEOGRAPH
+0xCBE2 0x547A #CJK UNIFIED IDEOGRAPH
+0xCBE3 0x547E #CJK UNIFIED IDEOGRAPH
+0xCBE4 0x5465 #CJK UNIFIED IDEOGRAPH
+0xCBE5 0x546C #CJK UNIFIED IDEOGRAPH
+0xCBE6 0x5474 #CJK UNIFIED IDEOGRAPH
+0xCBE7 0x5466 #CJK UNIFIED IDEOGRAPH
+0xCBE8 0x548D #CJK UNIFIED IDEOGRAPH
+0xCBE9 0x546F #CJK UNIFIED IDEOGRAPH
+0xCBEA 0x5461 #CJK UNIFIED IDEOGRAPH
+0xCBEB 0x5460 #CJK UNIFIED IDEOGRAPH
+0xCBEC 0x5498 #CJK UNIFIED IDEOGRAPH
+0xCBED 0x5463 #CJK UNIFIED IDEOGRAPH
+0xCBEE 0x5467 #CJK UNIFIED IDEOGRAPH
+0xCBEF 0x5464 #CJK UNIFIED IDEOGRAPH
+0xCBF0 0x56F7 #CJK UNIFIED IDEOGRAPH
+0xCBF1 0x56F9 #CJK UNIFIED IDEOGRAPH
+0xCBF2 0x576F #CJK UNIFIED IDEOGRAPH
+0xCBF3 0x5772 #CJK UNIFIED IDEOGRAPH
+0xCBF4 0x576D #CJK UNIFIED IDEOGRAPH
+0xCBF5 0x576B #CJK UNIFIED IDEOGRAPH
+0xCBF6 0x5771 #CJK UNIFIED IDEOGRAPH
+0xCBF7 0x5770 #CJK UNIFIED IDEOGRAPH
+0xCBF8 0x5776 #CJK UNIFIED IDEOGRAPH
+0xCBF9 0x5780 #CJK UNIFIED IDEOGRAPH
+0xCBFA 0x5775 #CJK UNIFIED IDEOGRAPH
+0xCBFB 0x577B #CJK UNIFIED IDEOGRAPH
+0xCBFC 0x5773 #CJK UNIFIED IDEOGRAPH
+0xCBFD 0x5774 #CJK UNIFIED IDEOGRAPH
+0xCBFE 0x5762 #CJK UNIFIED IDEOGRAPH
+0xCC40 0x5768 #CJK UNIFIED IDEOGRAPH
+0xCC41 0x577D #CJK UNIFIED IDEOGRAPH
+0xCC42 0x590C #CJK UNIFIED IDEOGRAPH
+0xCC43 0x5945 #CJK UNIFIED IDEOGRAPH
+0xCC44 0x59B5 #CJK UNIFIED IDEOGRAPH
+0xCC45 0x59BA #CJK UNIFIED IDEOGRAPH
+0xCC46 0x59CF #CJK UNIFIED IDEOGRAPH
+0xCC47 0x59CE #CJK UNIFIED IDEOGRAPH
+0xCC48 0x59B2 #CJK UNIFIED IDEOGRAPH
+0xCC49 0x59CC #CJK UNIFIED IDEOGRAPH
+0xCC4A 0x59C1 #CJK UNIFIED IDEOGRAPH
+0xCC4B 0x59B6 #CJK UNIFIED IDEOGRAPH
+0xCC4C 0x59BC #CJK UNIFIED IDEOGRAPH
+0xCC4D 0x59C3 #CJK UNIFIED IDEOGRAPH
+0xCC4E 0x59D6 #CJK UNIFIED IDEOGRAPH
+0xCC4F 0x59B1 #CJK UNIFIED IDEOGRAPH
+0xCC50 0x59BD #CJK UNIFIED IDEOGRAPH
+0xCC51 0x59C0 #CJK UNIFIED IDEOGRAPH
+0xCC52 0x59C8 #CJK UNIFIED IDEOGRAPH
+0xCC53 0x59B4 #CJK UNIFIED IDEOGRAPH
+0xCC54 0x59C7 #CJK UNIFIED IDEOGRAPH
+0xCC55 0x5B62 #CJK UNIFIED IDEOGRAPH
+0xCC56 0x5B65 #CJK UNIFIED IDEOGRAPH
+0xCC57 0x5B93 #CJK UNIFIED IDEOGRAPH
+0xCC58 0x5B95 #CJK UNIFIED IDEOGRAPH
+0xCC59 0x5C44 #CJK UNIFIED IDEOGRAPH
+0xCC5A 0x5C47 #CJK UNIFIED IDEOGRAPH
+0xCC5B 0x5CAE #CJK UNIFIED IDEOGRAPH
+0xCC5C 0x5CA4 #CJK UNIFIED IDEOGRAPH
+0xCC5D 0x5CA0 #CJK UNIFIED IDEOGRAPH
+0xCC5E 0x5CB5 #CJK UNIFIED IDEOGRAPH
+0xCC5F 0x5CAF #CJK UNIFIED IDEOGRAPH
+0xCC60 0x5CA8 #CJK UNIFIED IDEOGRAPH
+0xCC61 0x5CAC #CJK UNIFIED IDEOGRAPH
+0xCC62 0x5C9F #CJK UNIFIED IDEOGRAPH
+0xCC63 0x5CA3 #CJK UNIFIED IDEOGRAPH
+0xCC64 0x5CAD #CJK UNIFIED IDEOGRAPH
+0xCC65 0x5CA2 #CJK UNIFIED IDEOGRAPH
+0xCC66 0x5CAA #CJK UNIFIED IDEOGRAPH
+0xCC67 0x5CA7 #CJK UNIFIED IDEOGRAPH
+0xCC68 0x5C9D #CJK UNIFIED IDEOGRAPH
+0xCC69 0x5CA5 #CJK UNIFIED IDEOGRAPH
+0xCC6A 0x5CB6 #CJK UNIFIED IDEOGRAPH
+0xCC6B 0x5CB0 #CJK UNIFIED IDEOGRAPH
+0xCC6C 0x5CA6 #CJK UNIFIED IDEOGRAPH
+0xCC6D 0x5E17 #CJK UNIFIED IDEOGRAPH
+0xCC6E 0x5E14 #CJK UNIFIED IDEOGRAPH
+0xCC6F 0x5E19 #CJK UNIFIED IDEOGRAPH
+0xCC70 0x5F28 #CJK UNIFIED IDEOGRAPH
+0xCC71 0x5F22 #CJK UNIFIED IDEOGRAPH
+0xCC72 0x5F23 #CJK UNIFIED IDEOGRAPH
+0xCC73 0x5F24 #CJK UNIFIED IDEOGRAPH
+0xCC74 0x5F54 #CJK UNIFIED IDEOGRAPH
+0xCC75 0x5F82 #CJK UNIFIED IDEOGRAPH
+0xCC76 0x5F7E #CJK UNIFIED IDEOGRAPH
+0xCC77 0x5F7D #CJK UNIFIED IDEOGRAPH
+0xCC78 0x5FDE #CJK UNIFIED IDEOGRAPH
+0xCC79 0x5FE5 #CJK UNIFIED IDEOGRAPH
+0xCC7A 0x602D #CJK UNIFIED IDEOGRAPH
+0xCC7B 0x6026 #CJK UNIFIED IDEOGRAPH
+0xCC7C 0x6019 #CJK UNIFIED IDEOGRAPH
+0xCC7D 0x6032 #CJK UNIFIED IDEOGRAPH
+0xCC7E 0x600B #CJK UNIFIED IDEOGRAPH
+0xCCA1 0x6034 #CJK UNIFIED IDEOGRAPH
+0xCCA2 0x600A #CJK UNIFIED IDEOGRAPH
+0xCCA3 0x6017 #CJK UNIFIED IDEOGRAPH
+0xCCA4 0x6033 #CJK UNIFIED IDEOGRAPH
+0xCCA5 0x601A #CJK UNIFIED IDEOGRAPH
+0xCCA6 0x601E #CJK UNIFIED IDEOGRAPH
+0xCCA7 0x602C #CJK UNIFIED IDEOGRAPH
+0xCCA8 0x6022 #CJK UNIFIED IDEOGRAPH
+0xCCA9 0x600D #CJK UNIFIED IDEOGRAPH
+0xCCAA 0x6010 #CJK UNIFIED IDEOGRAPH
+0xCCAB 0x602E #CJK UNIFIED IDEOGRAPH
+0xCCAC 0x6013 #CJK UNIFIED IDEOGRAPH
+0xCCAD 0x6011 #CJK UNIFIED IDEOGRAPH
+0xCCAE 0x600C #CJK UNIFIED IDEOGRAPH
+0xCCAF 0x6009 #CJK UNIFIED IDEOGRAPH
+0xCCB0 0x601C #CJK UNIFIED IDEOGRAPH
+0xCCB1 0x6214 #CJK UNIFIED IDEOGRAPH
+0xCCB2 0x623D #CJK UNIFIED IDEOGRAPH
+0xCCB3 0x62AD #CJK UNIFIED IDEOGRAPH
+0xCCB4 0x62B4 #CJK UNIFIED IDEOGRAPH
+0xCCB5 0x62D1 #CJK UNIFIED IDEOGRAPH
+0xCCB6 0x62BE #CJK UNIFIED IDEOGRAPH
+0xCCB7 0x62AA #CJK UNIFIED IDEOGRAPH
+0xCCB8 0x62B6 #CJK UNIFIED IDEOGRAPH
+0xCCB9 0x62CA #CJK UNIFIED IDEOGRAPH
+0xCCBA 0x62AE #CJK UNIFIED IDEOGRAPH
+0xCCBB 0x62B3 #CJK UNIFIED IDEOGRAPH
+0xCCBC 0x62AF #CJK UNIFIED IDEOGRAPH
+0xCCBD 0x62BB #CJK UNIFIED IDEOGRAPH
+0xCCBE 0x62A9 #CJK UNIFIED IDEOGRAPH
+0xCCBF 0x62B0 #CJK UNIFIED IDEOGRAPH
+0xCCC0 0x62B8 #CJK UNIFIED IDEOGRAPH
+0xCCC1 0x653D #CJK UNIFIED IDEOGRAPH
+0xCCC2 0x65A8 #CJK UNIFIED IDEOGRAPH
+0xCCC3 0x65BB #CJK UNIFIED IDEOGRAPH
+0xCCC4 0x6609 #CJK UNIFIED IDEOGRAPH
+0xCCC5 0x65FC #CJK UNIFIED IDEOGRAPH
+0xCCC6 0x6604 #CJK UNIFIED IDEOGRAPH
+0xCCC7 0x6612 #CJK UNIFIED IDEOGRAPH
+0xCCC8 0x6608 #CJK UNIFIED IDEOGRAPH
+0xCCC9 0x65FB #CJK UNIFIED IDEOGRAPH
+0xCCCA 0x6603 #CJK UNIFIED IDEOGRAPH
+0xCCCB 0x660B #CJK UNIFIED IDEOGRAPH
+0xCCCC 0x660D #CJK UNIFIED IDEOGRAPH
+0xCCCD 0x6605 #CJK UNIFIED IDEOGRAPH
+0xCCCE 0x65FD #CJK UNIFIED IDEOGRAPH
+0xCCCF 0x6611 #CJK UNIFIED IDEOGRAPH
+0xCCD0 0x6610 #CJK UNIFIED IDEOGRAPH
+0xCCD1 0x66F6 #CJK UNIFIED IDEOGRAPH
+0xCCD2 0x670A #CJK UNIFIED IDEOGRAPH
+0xCCD3 0x6785 #CJK UNIFIED IDEOGRAPH
+0xCCD4 0x676C #CJK UNIFIED IDEOGRAPH
+0xCCD5 0x678E #CJK UNIFIED IDEOGRAPH
+0xCCD6 0x6792 #CJK UNIFIED IDEOGRAPH
+0xCCD7 0x6776 #CJK UNIFIED IDEOGRAPH
+0xCCD8 0x677B #CJK UNIFIED IDEOGRAPH
+0xCCD9 0x6798 #CJK UNIFIED IDEOGRAPH
+0xCCDA 0x6786 #CJK UNIFIED IDEOGRAPH
+0xCCDB 0x6784 #CJK UNIFIED IDEOGRAPH
+0xCCDC 0x6774 #CJK UNIFIED IDEOGRAPH
+0xCCDD 0x678D #CJK UNIFIED IDEOGRAPH
+0xCCDE 0x678C #CJK UNIFIED IDEOGRAPH
+0xCCDF 0x677A #CJK UNIFIED IDEOGRAPH
+0xCCE0 0x679F #CJK UNIFIED IDEOGRAPH
+0xCCE1 0x6791 #CJK UNIFIED IDEOGRAPH
+0xCCE2 0x6799 #CJK UNIFIED IDEOGRAPH
+0xCCE3 0x6783 #CJK UNIFIED IDEOGRAPH
+0xCCE4 0x677D #CJK UNIFIED IDEOGRAPH
+0xCCE5 0x6781 #CJK UNIFIED IDEOGRAPH
+0xCCE6 0x6778 #CJK UNIFIED IDEOGRAPH
+0xCCE7 0x6779 #CJK UNIFIED IDEOGRAPH
+0xCCE8 0x6794 #CJK UNIFIED IDEOGRAPH
+0xCCE9 0x6B25 #CJK UNIFIED IDEOGRAPH
+0xCCEA 0x6B80 #CJK UNIFIED IDEOGRAPH
+0xCCEB 0x6B7E #CJK UNIFIED IDEOGRAPH
+0xCCEC 0x6BDE #CJK UNIFIED IDEOGRAPH
+0xCCED 0x6C1D #CJK UNIFIED IDEOGRAPH
+0xCCEE 0x6C93 #CJK UNIFIED IDEOGRAPH
+0xCCEF 0x6CEC #CJK UNIFIED IDEOGRAPH
+0xCCF0 0x6CEB #CJK UNIFIED IDEOGRAPH
+0xCCF1 0x6CEE #CJK UNIFIED IDEOGRAPH
+0xCCF2 0x6CD9 #CJK UNIFIED IDEOGRAPH
+0xCCF3 0x6CB6 #CJK UNIFIED IDEOGRAPH
+0xCCF4 0x6CD4 #CJK UNIFIED IDEOGRAPH
+0xCCF5 0x6CAD #CJK UNIFIED IDEOGRAPH
+0xCCF6 0x6CE7 #CJK UNIFIED IDEOGRAPH
+0xCCF7 0x6CB7 #CJK UNIFIED IDEOGRAPH
+0xCCF8 0x6CD0 #CJK UNIFIED IDEOGRAPH
+0xCCF9 0x6CC2 #CJK UNIFIED IDEOGRAPH
+0xCCFA 0x6CBA #CJK UNIFIED IDEOGRAPH
+0xCCFB 0x6CC3 #CJK UNIFIED IDEOGRAPH
+0xCCFC 0x6CC6 #CJK UNIFIED IDEOGRAPH
+0xCCFD 0x6CED #CJK UNIFIED IDEOGRAPH
+0xCCFE 0x6CF2 #CJK UNIFIED IDEOGRAPH
+0xCD40 0x6CD2 #CJK UNIFIED IDEOGRAPH
+0xCD41 0x6CDD #CJK UNIFIED IDEOGRAPH
+0xCD42 0x6CB4 #CJK UNIFIED IDEOGRAPH
+0xCD43 0x6C8A #CJK UNIFIED IDEOGRAPH
+0xCD44 0x6C9D #CJK UNIFIED IDEOGRAPH
+0xCD45 0x6C80 #CJK UNIFIED IDEOGRAPH
+0xCD46 0x6CDE #CJK UNIFIED IDEOGRAPH
+0xCD47 0x6CC0 #CJK UNIFIED IDEOGRAPH
+0xCD48 0x6D30 #CJK UNIFIED IDEOGRAPH
+0xCD49 0x6CCD #CJK UNIFIED IDEOGRAPH
+0xCD4A 0x6CC7 #CJK UNIFIED IDEOGRAPH
+0xCD4B 0x6CB0 #CJK UNIFIED IDEOGRAPH
+0xCD4C 0x6CF9 #CJK UNIFIED IDEOGRAPH
+0xCD4D 0x6CCF #CJK UNIFIED IDEOGRAPH
+0xCD4E 0x6CE9 #CJK UNIFIED IDEOGRAPH
+0xCD4F 0x6CD1 #CJK UNIFIED IDEOGRAPH
+0xCD50 0x7094 #CJK UNIFIED IDEOGRAPH
+0xCD51 0x7098 #CJK UNIFIED IDEOGRAPH
+0xCD52 0x7085 #CJK UNIFIED IDEOGRAPH
+0xCD53 0x7093 #CJK UNIFIED IDEOGRAPH
+0xCD54 0x7086 #CJK UNIFIED IDEOGRAPH
+0xCD55 0x7084 #CJK UNIFIED IDEOGRAPH
+0xCD56 0x7091 #CJK UNIFIED IDEOGRAPH
+0xCD57 0x7096 #CJK UNIFIED IDEOGRAPH
+0xCD58 0x7082 #CJK UNIFIED IDEOGRAPH
+0xCD59 0x709A #CJK UNIFIED IDEOGRAPH
+0xCD5A 0x7083 #CJK UNIFIED IDEOGRAPH
+0xCD5B 0x726A #CJK UNIFIED IDEOGRAPH
+0xCD5C 0x72D6 #CJK UNIFIED IDEOGRAPH
+0xCD5D 0x72CB #CJK UNIFIED IDEOGRAPH
+0xCD5E 0x72D8 #CJK UNIFIED IDEOGRAPH
+0xCD5F 0x72C9 #CJK UNIFIED IDEOGRAPH
+0xCD60 0x72DC #CJK UNIFIED IDEOGRAPH
+0xCD61 0x72D2 #CJK UNIFIED IDEOGRAPH
+0xCD62 0x72D4 #CJK UNIFIED IDEOGRAPH
+0xCD63 0x72DA #CJK UNIFIED IDEOGRAPH
+0xCD64 0x72CC #CJK UNIFIED IDEOGRAPH
+0xCD65 0x72D1 #CJK UNIFIED IDEOGRAPH
+0xCD66 0x73A4 #CJK UNIFIED IDEOGRAPH
+0xCD67 0x73A1 #CJK UNIFIED IDEOGRAPH
+0xCD68 0x73AD #CJK UNIFIED IDEOGRAPH
+0xCD69 0x73A6 #CJK UNIFIED IDEOGRAPH
+0xCD6A 0x73A2 #CJK UNIFIED IDEOGRAPH
+0xCD6B 0x73A0 #CJK UNIFIED IDEOGRAPH
+0xCD6C 0x73AC #CJK UNIFIED IDEOGRAPH
+0xCD6D 0x739D #CJK UNIFIED IDEOGRAPH
+0xCD6E 0x74DD #CJK UNIFIED IDEOGRAPH
+0xCD6F 0x74E8 #CJK UNIFIED IDEOGRAPH
+0xCD70 0x753F #CJK UNIFIED IDEOGRAPH
+0xCD71 0x7540 #CJK UNIFIED IDEOGRAPH
+0xCD72 0x753E #CJK UNIFIED IDEOGRAPH
+0xCD73 0x758C #CJK UNIFIED IDEOGRAPH
+0xCD74 0x7598 #CJK UNIFIED IDEOGRAPH
+0xCD75 0x76AF #CJK UNIFIED IDEOGRAPH
+0xCD76 0x76F3 #CJK UNIFIED IDEOGRAPH
+0xCD77 0x76F1 #CJK UNIFIED IDEOGRAPH
+0xCD78 0x76F0 #CJK UNIFIED IDEOGRAPH
+0xCD79 0x76F5 #CJK UNIFIED IDEOGRAPH
+0xCD7A 0x77F8 #CJK UNIFIED IDEOGRAPH
+0xCD7B 0x77FC #CJK UNIFIED IDEOGRAPH
+0xCD7C 0x77F9 #CJK UNIFIED IDEOGRAPH
+0xCD7D 0x77FB #CJK UNIFIED IDEOGRAPH
+0xCD7E 0x77FA #CJK UNIFIED IDEOGRAPH
+0xCDA1 0x77F7 #CJK UNIFIED IDEOGRAPH
+0xCDA2 0x7942 #CJK UNIFIED IDEOGRAPH
+0xCDA3 0x793F #CJK UNIFIED IDEOGRAPH
+0xCDA4 0x79C5 #CJK UNIFIED IDEOGRAPH
+0xCDA5 0x7A78 #CJK UNIFIED IDEOGRAPH
+0xCDA6 0x7A7B #CJK UNIFIED IDEOGRAPH
+0xCDA7 0x7AFB #CJK UNIFIED IDEOGRAPH
+0xCDA8 0x7C75 #CJK UNIFIED IDEOGRAPH
+0xCDA9 0x7CFD #CJK UNIFIED IDEOGRAPH
+0xCDAA 0x8035 #CJK UNIFIED IDEOGRAPH
+0xCDAB 0x808F #CJK UNIFIED IDEOGRAPH
+0xCDAC 0x80AE #CJK UNIFIED IDEOGRAPH
+0xCDAD 0x80A3 #CJK UNIFIED IDEOGRAPH
+0xCDAE 0x80B8 #CJK UNIFIED IDEOGRAPH
+0xCDAF 0x80B5 #CJK UNIFIED IDEOGRAPH
+0xCDB0 0x80AD #CJK UNIFIED IDEOGRAPH
+0xCDB1 0x8220 #CJK UNIFIED IDEOGRAPH
+0xCDB2 0x82A0 #CJK UNIFIED IDEOGRAPH
+0xCDB3 0x82C0 #CJK UNIFIED IDEOGRAPH
+0xCDB4 0x82AB #CJK UNIFIED IDEOGRAPH
+0xCDB5 0x829A #CJK UNIFIED IDEOGRAPH
+0xCDB6 0x8298 #CJK UNIFIED IDEOGRAPH
+0xCDB7 0x829B #CJK UNIFIED IDEOGRAPH
+0xCDB8 0x82B5 #CJK UNIFIED IDEOGRAPH
+0xCDB9 0x82A7 #CJK UNIFIED IDEOGRAPH
+0xCDBA 0x82AE #CJK UNIFIED IDEOGRAPH
+0xCDBB 0x82BC #CJK UNIFIED IDEOGRAPH
+0xCDBC 0x829E #CJK UNIFIED IDEOGRAPH
+0xCDBD 0x82BA #CJK UNIFIED IDEOGRAPH
+0xCDBE 0x82B4 #CJK UNIFIED IDEOGRAPH
+0xCDBF 0x82A8 #CJK UNIFIED IDEOGRAPH
+0xCDC0 0x82A1 #CJK UNIFIED IDEOGRAPH
+0xCDC1 0x82A9 #CJK UNIFIED IDEOGRAPH
+0xCDC2 0x82C2 #CJK UNIFIED IDEOGRAPH
+0xCDC3 0x82A4 #CJK UNIFIED IDEOGRAPH
+0xCDC4 0x82C3 #CJK UNIFIED IDEOGRAPH
+0xCDC5 0x82B6 #CJK UNIFIED IDEOGRAPH
+0xCDC6 0x82A2 #CJK UNIFIED IDEOGRAPH
+0xCDC7 0x8670 #CJK UNIFIED IDEOGRAPH
+0xCDC8 0x866F #CJK UNIFIED IDEOGRAPH
+0xCDC9 0x866D #CJK UNIFIED IDEOGRAPH
+0xCDCA 0x866E #CJK UNIFIED IDEOGRAPH
+0xCDCB 0x8C56 #CJK UNIFIED IDEOGRAPH
+0xCDCC 0x8FD2 #CJK UNIFIED IDEOGRAPH
+0xCDCD 0x8FCB #CJK UNIFIED IDEOGRAPH
+0xCDCE 0x8FD3 #CJK UNIFIED IDEOGRAPH
+0xCDCF 0x8FCD #CJK UNIFIED IDEOGRAPH
+0xCDD0 0x8FD6 #CJK UNIFIED IDEOGRAPH
+0xCDD1 0x8FD5 #CJK UNIFIED IDEOGRAPH
+0xCDD2 0x8FD7 #CJK UNIFIED IDEOGRAPH
+0xCDD3 0x90B2 #CJK UNIFIED IDEOGRAPH
+0xCDD4 0x90B4 #CJK UNIFIED IDEOGRAPH
+0xCDD5 0x90AF #CJK UNIFIED IDEOGRAPH
+0xCDD6 0x90B3 #CJK UNIFIED IDEOGRAPH
+0xCDD7 0x90B0 #CJK UNIFIED IDEOGRAPH
+0xCDD8 0x9639 #CJK UNIFIED IDEOGRAPH
+0xCDD9 0x963D #CJK UNIFIED IDEOGRAPH
+0xCDDA 0x963C #CJK UNIFIED IDEOGRAPH
+0xCDDB 0x963A #CJK UNIFIED IDEOGRAPH
+0xCDDC 0x9643 #CJK UNIFIED IDEOGRAPH
+0xCDDD 0x4FCD #CJK UNIFIED IDEOGRAPH
+0xCDDE 0x4FC5 #CJK UNIFIED IDEOGRAPH
+0xCDDF 0x4FD3 #CJK UNIFIED IDEOGRAPH
+0xCDE0 0x4FB2 #CJK UNIFIED IDEOGRAPH
+0xCDE1 0x4FC9 #CJK UNIFIED IDEOGRAPH
+0xCDE2 0x4FCB #CJK UNIFIED IDEOGRAPH
+0xCDE3 0x4FC1 #CJK UNIFIED IDEOGRAPH
+0xCDE4 0x4FD4 #CJK UNIFIED IDEOGRAPH
+0xCDE5 0x4FDC #CJK UNIFIED IDEOGRAPH
+0xCDE6 0x4FD9 #CJK UNIFIED IDEOGRAPH
+0xCDE7 0x4FBB #CJK UNIFIED IDEOGRAPH
+0xCDE8 0x4FB3 #CJK UNIFIED IDEOGRAPH
+0xCDE9 0x4FDB #CJK UNIFIED IDEOGRAPH
+0xCDEA 0x4FC7 #CJK UNIFIED IDEOGRAPH
+0xCDEB 0x4FD6 #CJK UNIFIED IDEOGRAPH
+0xCDEC 0x4FBA #CJK UNIFIED IDEOGRAPH
+0xCDED 0x4FC0 #CJK UNIFIED IDEOGRAPH
+0xCDEE 0x4FB9 #CJK UNIFIED IDEOGRAPH
+0xCDEF 0x4FEC #CJK UNIFIED IDEOGRAPH
+0xCDF0 0x5244 #CJK UNIFIED IDEOGRAPH
+0xCDF1 0x5249 #CJK UNIFIED IDEOGRAPH
+0xCDF2 0x52C0 #CJK UNIFIED IDEOGRAPH
+0xCDF3 0x52C2 #CJK UNIFIED IDEOGRAPH
+0xCDF4 0x533D #CJK UNIFIED IDEOGRAPH
+0xCDF5 0x537C #CJK UNIFIED IDEOGRAPH
+0xCDF6 0x5397 #CJK UNIFIED IDEOGRAPH
+0xCDF7 0x5396 #CJK UNIFIED IDEOGRAPH
+0xCDF8 0x5399 #CJK UNIFIED IDEOGRAPH
+0xCDF9 0x5398 #CJK UNIFIED IDEOGRAPH
+0xCDFA 0x54BA #CJK UNIFIED IDEOGRAPH
+0xCDFB 0x54A1 #CJK UNIFIED IDEOGRAPH
+0xCDFC 0x54AD #CJK UNIFIED IDEOGRAPH
+0xCDFD 0x54A5 #CJK UNIFIED IDEOGRAPH
+0xCDFE 0x54CF #CJK UNIFIED IDEOGRAPH
+0xCE40 0x54C3 #CJK UNIFIED IDEOGRAPH
+0xCE41 0x830D #CJK UNIFIED IDEOGRAPH
+0xCE42 0x54B7 #CJK UNIFIED IDEOGRAPH
+0xCE43 0x54AE #CJK UNIFIED IDEOGRAPH
+0xCE44 0x54D6 #CJK UNIFIED IDEOGRAPH
+0xCE45 0x54B6 #CJK UNIFIED IDEOGRAPH
+0xCE46 0x54C5 #CJK UNIFIED IDEOGRAPH
+0xCE47 0x54C6 #CJK UNIFIED IDEOGRAPH
+0xCE48 0x54A0 #CJK UNIFIED IDEOGRAPH
+0xCE49 0x5470 #CJK UNIFIED IDEOGRAPH
+0xCE4A 0x54BC #CJK UNIFIED IDEOGRAPH
+0xCE4B 0x54A2 #CJK UNIFIED IDEOGRAPH
+0xCE4C 0x54BE #CJK UNIFIED IDEOGRAPH
+0xCE4D 0x5472 #CJK UNIFIED IDEOGRAPH
+0xCE4E 0x54DE #CJK UNIFIED IDEOGRAPH
+0xCE4F 0x54B0 #CJK UNIFIED IDEOGRAPH
+0xCE50 0x57B5 #CJK UNIFIED IDEOGRAPH
+0xCE51 0x579E #CJK UNIFIED IDEOGRAPH
+0xCE52 0x579F #CJK UNIFIED IDEOGRAPH
+0xCE53 0x57A4 #CJK UNIFIED IDEOGRAPH
+0xCE54 0x578C #CJK UNIFIED IDEOGRAPH
+0xCE55 0x5797 #CJK UNIFIED IDEOGRAPH
+0xCE56 0x579D #CJK UNIFIED IDEOGRAPH
+0xCE57 0x579B #CJK UNIFIED IDEOGRAPH
+0xCE58 0x5794 #CJK UNIFIED IDEOGRAPH
+0xCE59 0x5798 #CJK UNIFIED IDEOGRAPH
+0xCE5A 0x578F #CJK UNIFIED IDEOGRAPH
+0xCE5B 0x5799 #CJK UNIFIED IDEOGRAPH
+0xCE5C 0x57A5 #CJK UNIFIED IDEOGRAPH
+0xCE5D 0x579A #CJK UNIFIED IDEOGRAPH
+0xCE5E 0x5795 #CJK UNIFIED IDEOGRAPH
+0xCE5F 0x58F4 #CJK UNIFIED IDEOGRAPH
+0xCE60 0x590D #CJK UNIFIED IDEOGRAPH
+0xCE61 0x5953 #CJK UNIFIED IDEOGRAPH
+0xCE62 0x59E1 #CJK UNIFIED IDEOGRAPH
+0xCE63 0x59DE #CJK UNIFIED IDEOGRAPH
+0xCE64 0x59EE #CJK UNIFIED IDEOGRAPH
+0xCE65 0x5A00 #CJK UNIFIED IDEOGRAPH
+0xCE66 0x59F1 #CJK UNIFIED IDEOGRAPH
+0xCE67 0x59DD #CJK UNIFIED IDEOGRAPH
+0xCE68 0x59FA #CJK UNIFIED IDEOGRAPH
+0xCE69 0x59FD #CJK UNIFIED IDEOGRAPH
+0xCE6A 0x59FC #CJK UNIFIED IDEOGRAPH
+0xCE6B 0x59F6 #CJK UNIFIED IDEOGRAPH
+0xCE6C 0x59E4 #CJK UNIFIED IDEOGRAPH
+0xCE6D 0x59F2 #CJK UNIFIED IDEOGRAPH
+0xCE6E 0x59F7 #CJK UNIFIED IDEOGRAPH
+0xCE6F 0x59DB #CJK UNIFIED IDEOGRAPH
+0xCE70 0x59E9 #CJK UNIFIED IDEOGRAPH
+0xCE71 0x59F3 #CJK UNIFIED IDEOGRAPH
+0xCE72 0x59F5 #CJK UNIFIED IDEOGRAPH
+0xCE73 0x59E0 #CJK UNIFIED IDEOGRAPH
+0xCE74 0x59FE #CJK UNIFIED IDEOGRAPH
+0xCE75 0x59F4 #CJK UNIFIED IDEOGRAPH
+0xCE76 0x59ED #CJK UNIFIED IDEOGRAPH
+0xCE77 0x5BA8 #CJK UNIFIED IDEOGRAPH
+0xCE78 0x5C4C #CJK UNIFIED IDEOGRAPH
+0xCE79 0x5CD0 #CJK UNIFIED IDEOGRAPH
+0xCE7A 0x5CD8 #CJK UNIFIED IDEOGRAPH
+0xCE7B 0x5CCC #CJK UNIFIED IDEOGRAPH
+0xCE7C 0x5CD7 #CJK UNIFIED IDEOGRAPH
+0xCE7D 0x5CCB #CJK UNIFIED IDEOGRAPH
+0xCE7E 0x5CDB #CJK UNIFIED IDEOGRAPH
+0xCEA1 0x5CDE #CJK UNIFIED IDEOGRAPH
+0xCEA2 0x5CDA #CJK UNIFIED IDEOGRAPH
+0xCEA3 0x5CC9 #CJK UNIFIED IDEOGRAPH
+0xCEA4 0x5CC7 #CJK UNIFIED IDEOGRAPH
+0xCEA5 0x5CCA #CJK UNIFIED IDEOGRAPH
+0xCEA6 0x5CD6 #CJK UNIFIED IDEOGRAPH
+0xCEA7 0x5CD3 #CJK UNIFIED IDEOGRAPH
+0xCEA8 0x5CD4 #CJK UNIFIED IDEOGRAPH
+0xCEA9 0x5CCF #CJK UNIFIED IDEOGRAPH
+0xCEAA 0x5CC8 #CJK UNIFIED IDEOGRAPH
+0xCEAB 0x5CC6 #CJK UNIFIED IDEOGRAPH
+0xCEAC 0x5CCE #CJK UNIFIED IDEOGRAPH
+0xCEAD 0x5CDF #CJK UNIFIED IDEOGRAPH
+0xCEAE 0x5CF8 #CJK UNIFIED IDEOGRAPH
+0xCEAF 0x5DF9 #CJK UNIFIED IDEOGRAPH
+0xCEB0 0x5E21 #CJK UNIFIED IDEOGRAPH
+0xCEB1 0x5E22 #CJK UNIFIED IDEOGRAPH
+0xCEB2 0x5E23 #CJK UNIFIED IDEOGRAPH
+0xCEB3 0x5E20 #CJK UNIFIED IDEOGRAPH
+0xCEB4 0x5E24 #CJK UNIFIED IDEOGRAPH
+0xCEB5 0x5EB0 #CJK UNIFIED IDEOGRAPH
+0xCEB6 0x5EA4 #CJK UNIFIED IDEOGRAPH
+0xCEB7 0x5EA2 #CJK UNIFIED IDEOGRAPH
+0xCEB8 0x5E9B #CJK UNIFIED IDEOGRAPH
+0xCEB9 0x5EA3 #CJK UNIFIED IDEOGRAPH
+0xCEBA 0x5EA5 #CJK UNIFIED IDEOGRAPH
+0xCEBB 0x5F07 #CJK UNIFIED IDEOGRAPH
+0xCEBC 0x5F2E #CJK UNIFIED IDEOGRAPH
+0xCEBD 0x5F56 #CJK UNIFIED IDEOGRAPH
+0xCEBE 0x5F86 #CJK UNIFIED IDEOGRAPH
+0xCEBF 0x6037 #CJK UNIFIED IDEOGRAPH
+0xCEC0 0x6039 #CJK UNIFIED IDEOGRAPH
+0xCEC1 0x6054 #CJK UNIFIED IDEOGRAPH
+0xCEC2 0x6072 #CJK UNIFIED IDEOGRAPH
+0xCEC3 0x605E #CJK UNIFIED IDEOGRAPH
+0xCEC4 0x6045 #CJK UNIFIED IDEOGRAPH
+0xCEC5 0x6053 #CJK UNIFIED IDEOGRAPH
+0xCEC6 0x6047 #CJK UNIFIED IDEOGRAPH
+0xCEC7 0x6049 #CJK UNIFIED IDEOGRAPH
+0xCEC8 0x605B #CJK UNIFIED IDEOGRAPH
+0xCEC9 0x604C #CJK UNIFIED IDEOGRAPH
+0xCECA 0x6040 #CJK UNIFIED IDEOGRAPH
+0xCECB 0x6042 #CJK UNIFIED IDEOGRAPH
+0xCECC 0x605F #CJK UNIFIED IDEOGRAPH
+0xCECD 0x6024 #CJK UNIFIED IDEOGRAPH
+0xCECE 0x6044 #CJK UNIFIED IDEOGRAPH
+0xCECF 0x6058 #CJK UNIFIED IDEOGRAPH
+0xCED0 0x6066 #CJK UNIFIED IDEOGRAPH
+0xCED1 0x606E #CJK UNIFIED IDEOGRAPH
+0xCED2 0x6242 #CJK UNIFIED IDEOGRAPH
+0xCED3 0x6243 #CJK UNIFIED IDEOGRAPH
+0xCED4 0x62CF #CJK UNIFIED IDEOGRAPH
+0xCED5 0x630D #CJK UNIFIED IDEOGRAPH
+0xCED6 0x630B #CJK UNIFIED IDEOGRAPH
+0xCED7 0x62F5 #CJK UNIFIED IDEOGRAPH
+0xCED8 0x630E #CJK UNIFIED IDEOGRAPH
+0xCED9 0x6303 #CJK UNIFIED IDEOGRAPH
+0xCEDA 0x62EB #CJK UNIFIED IDEOGRAPH
+0xCEDB 0x62F9 #CJK UNIFIED IDEOGRAPH
+0xCEDC 0x630F #CJK UNIFIED IDEOGRAPH
+0xCEDD 0x630C #CJK UNIFIED IDEOGRAPH
+0xCEDE 0x62F8 #CJK UNIFIED IDEOGRAPH
+0xCEDF 0x62F6 #CJK UNIFIED IDEOGRAPH
+0xCEE0 0x6300 #CJK UNIFIED IDEOGRAPH
+0xCEE1 0x6313 #CJK UNIFIED IDEOGRAPH
+0xCEE2 0x6314 #CJK UNIFIED IDEOGRAPH
+0xCEE3 0x62FA #CJK UNIFIED IDEOGRAPH
+0xCEE4 0x6315 #CJK UNIFIED IDEOGRAPH
+0xCEE5 0x62FB #CJK UNIFIED IDEOGRAPH
+0xCEE6 0x62F0 #CJK UNIFIED IDEOGRAPH
+0xCEE7 0x6541 #CJK UNIFIED IDEOGRAPH
+0xCEE8 0x6543 #CJK UNIFIED IDEOGRAPH
+0xCEE9 0x65AA #CJK UNIFIED IDEOGRAPH
+0xCEEA 0x65BF #CJK UNIFIED IDEOGRAPH
+0xCEEB 0x6636 #CJK UNIFIED IDEOGRAPH
+0xCEEC 0x6621 #CJK UNIFIED IDEOGRAPH
+0xCEED 0x6632 #CJK UNIFIED IDEOGRAPH
+0xCEEE 0x6635 #CJK UNIFIED IDEOGRAPH
+0xCEEF 0x661C #CJK UNIFIED IDEOGRAPH
+0xCEF0 0x6626 #CJK UNIFIED IDEOGRAPH
+0xCEF1 0x6622 #CJK UNIFIED IDEOGRAPH
+0xCEF2 0x6633 #CJK UNIFIED IDEOGRAPH
+0xCEF3 0x662B #CJK UNIFIED IDEOGRAPH
+0xCEF4 0x663A #CJK UNIFIED IDEOGRAPH
+0xCEF5 0x661D #CJK UNIFIED IDEOGRAPH
+0xCEF6 0x6634 #CJK UNIFIED IDEOGRAPH
+0xCEF7 0x6639 #CJK UNIFIED IDEOGRAPH
+0xCEF8 0x662E #CJK UNIFIED IDEOGRAPH
+0xCEF9 0x670F #CJK UNIFIED IDEOGRAPH
+0xCEFA 0x6710 #CJK UNIFIED IDEOGRAPH
+0xCEFB 0x67C1 #CJK UNIFIED IDEOGRAPH
+0xCEFC 0x67F2 #CJK UNIFIED IDEOGRAPH
+0xCEFD 0x67C8 #CJK UNIFIED IDEOGRAPH
+0xCEFE 0x67BA #CJK UNIFIED IDEOGRAPH
+0xCF40 0x67DC #CJK UNIFIED IDEOGRAPH
+0xCF41 0x67BB #CJK UNIFIED IDEOGRAPH
+0xCF42 0x67F8 #CJK UNIFIED IDEOGRAPH
+0xCF43 0x67D8 #CJK UNIFIED IDEOGRAPH
+0xCF44 0x67C0 #CJK UNIFIED IDEOGRAPH
+0xCF45 0x67B7 #CJK UNIFIED IDEOGRAPH
+0xCF46 0x67C5 #CJK UNIFIED IDEOGRAPH
+0xCF47 0x67EB #CJK UNIFIED IDEOGRAPH
+0xCF48 0x67E4 #CJK UNIFIED IDEOGRAPH
+0xCF49 0x67DF #CJK UNIFIED IDEOGRAPH
+0xCF4A 0x67B5 #CJK UNIFIED IDEOGRAPH
+0xCF4B 0x67CD #CJK UNIFIED IDEOGRAPH
+0xCF4C 0x67B3 #CJK UNIFIED IDEOGRAPH
+0xCF4D 0x67F7 #CJK UNIFIED IDEOGRAPH
+0xCF4E 0x67F6 #CJK UNIFIED IDEOGRAPH
+0xCF4F 0x67EE #CJK UNIFIED IDEOGRAPH
+0xCF50 0x67E3 #CJK UNIFIED IDEOGRAPH
+0xCF51 0x67C2 #CJK UNIFIED IDEOGRAPH
+0xCF52 0x67B9 #CJK UNIFIED IDEOGRAPH
+0xCF53 0x67CE #CJK UNIFIED IDEOGRAPH
+0xCF54 0x67E7 #CJK UNIFIED IDEOGRAPH
+0xCF55 0x67F0 #CJK UNIFIED IDEOGRAPH
+0xCF56 0x67B2 #CJK UNIFIED IDEOGRAPH
+0xCF57 0x67FC #CJK UNIFIED IDEOGRAPH
+0xCF58 0x67C6 #CJK UNIFIED IDEOGRAPH
+0xCF59 0x67ED #CJK UNIFIED IDEOGRAPH
+0xCF5A 0x67CC #CJK UNIFIED IDEOGRAPH
+0xCF5B 0x67AE #CJK UNIFIED IDEOGRAPH
+0xCF5C 0x67E6 #CJK UNIFIED IDEOGRAPH
+0xCF5D 0x67DB #CJK UNIFIED IDEOGRAPH
+0xCF5E 0x67FA #CJK UNIFIED IDEOGRAPH
+0xCF5F 0x67C9 #CJK UNIFIED IDEOGRAPH
+0xCF60 0x67CA #CJK UNIFIED IDEOGRAPH
+0xCF61 0x67C3 #CJK UNIFIED IDEOGRAPH
+0xCF62 0x67EA #CJK UNIFIED IDEOGRAPH
+0xCF63 0x67CB #CJK UNIFIED IDEOGRAPH
+0xCF64 0x6B28 #CJK UNIFIED IDEOGRAPH
+0xCF65 0x6B82 #CJK UNIFIED IDEOGRAPH
+0xCF66 0x6B84 #CJK UNIFIED IDEOGRAPH
+0xCF67 0x6BB6 #CJK UNIFIED IDEOGRAPH
+0xCF68 0x6BD6 #CJK UNIFIED IDEOGRAPH
+0xCF69 0x6BD8 #CJK UNIFIED IDEOGRAPH
+0xCF6A 0x6BE0 #CJK UNIFIED IDEOGRAPH
+0xCF6B 0x6C20 #CJK UNIFIED IDEOGRAPH
+0xCF6C 0x6C21 #CJK UNIFIED IDEOGRAPH
+0xCF6D 0x6D28 #CJK UNIFIED IDEOGRAPH
+0xCF6E 0x6D34 #CJK UNIFIED IDEOGRAPH
+0xCF6F 0x6D2D #CJK UNIFIED IDEOGRAPH
+0xCF70 0x6D1F #CJK UNIFIED IDEOGRAPH
+0xCF71 0x6D3C #CJK UNIFIED IDEOGRAPH
+0xCF72 0x6D3F #CJK UNIFIED IDEOGRAPH
+0xCF73 0x6D12 #CJK UNIFIED IDEOGRAPH
+0xCF74 0x6D0A #CJK UNIFIED IDEOGRAPH
+0xCF75 0x6CDA #CJK UNIFIED IDEOGRAPH
+0xCF76 0x6D33 #CJK UNIFIED IDEOGRAPH
+0xCF77 0x6D04 #CJK UNIFIED IDEOGRAPH
+0xCF78 0x6D19 #CJK UNIFIED IDEOGRAPH
+0xCF79 0x6D3A #CJK UNIFIED IDEOGRAPH
+0xCF7A 0x6D1A #CJK UNIFIED IDEOGRAPH
+0xCF7B 0x6D11 #CJK UNIFIED IDEOGRAPH
+0xCF7C 0x6D00 #CJK UNIFIED IDEOGRAPH
+0xCF7D 0x6D1D #CJK UNIFIED IDEOGRAPH
+0xCF7E 0x6D42 #CJK UNIFIED IDEOGRAPH
+0xCFA1 0x6D01 #CJK UNIFIED IDEOGRAPH
+0xCFA2 0x6D18 #CJK UNIFIED IDEOGRAPH
+0xCFA3 0x6D37 #CJK UNIFIED IDEOGRAPH
+0xCFA4 0x6D03 #CJK UNIFIED IDEOGRAPH
+0xCFA5 0x6D0F #CJK UNIFIED IDEOGRAPH
+0xCFA6 0x6D40 #CJK UNIFIED IDEOGRAPH
+0xCFA7 0x6D07 #CJK UNIFIED IDEOGRAPH
+0xCFA8 0x6D20 #CJK UNIFIED IDEOGRAPH
+0xCFA9 0x6D2C #CJK UNIFIED IDEOGRAPH
+0xCFAA 0x6D08 #CJK UNIFIED IDEOGRAPH
+0xCFAB 0x6D22 #CJK UNIFIED IDEOGRAPH
+0xCFAC 0x6D09 #CJK UNIFIED IDEOGRAPH
+0xCFAD 0x6D10 #CJK UNIFIED IDEOGRAPH
+0xCFAE 0x70B7 #CJK UNIFIED IDEOGRAPH
+0xCFAF 0x709F #CJK UNIFIED IDEOGRAPH
+0xCFB0 0x70BE #CJK UNIFIED IDEOGRAPH
+0xCFB1 0x70B1 #CJK UNIFIED IDEOGRAPH
+0xCFB2 0x70B0 #CJK UNIFIED IDEOGRAPH
+0xCFB3 0x70A1 #CJK UNIFIED IDEOGRAPH
+0xCFB4 0x70B4 #CJK UNIFIED IDEOGRAPH
+0xCFB5 0x70B5 #CJK UNIFIED IDEOGRAPH
+0xCFB6 0x70A9 #CJK UNIFIED IDEOGRAPH
+0xCFB7 0x7241 #CJK UNIFIED IDEOGRAPH
+0xCFB8 0x7249 #CJK UNIFIED IDEOGRAPH
+0xCFB9 0x724A #CJK UNIFIED IDEOGRAPH
+0xCFBA 0x726C #CJK UNIFIED IDEOGRAPH
+0xCFBB 0x7270 #CJK UNIFIED IDEOGRAPH
+0xCFBC 0x7273 #CJK UNIFIED IDEOGRAPH
+0xCFBD 0x726E #CJK UNIFIED IDEOGRAPH
+0xCFBE 0x72CA #CJK UNIFIED IDEOGRAPH
+0xCFBF 0x72E4 #CJK UNIFIED IDEOGRAPH
+0xCFC0 0x72E8 #CJK UNIFIED IDEOGRAPH
+0xCFC1 0x72EB #CJK UNIFIED IDEOGRAPH
+0xCFC2 0x72DF #CJK UNIFIED IDEOGRAPH
+0xCFC3 0x72EA #CJK UNIFIED IDEOGRAPH
+0xCFC4 0x72E6 #CJK UNIFIED IDEOGRAPH
+0xCFC5 0x72E3 #CJK UNIFIED IDEOGRAPH
+0xCFC6 0x7385 #CJK UNIFIED IDEOGRAPH
+0xCFC7 0x73CC #CJK UNIFIED IDEOGRAPH
+0xCFC8 0x73C2 #CJK UNIFIED IDEOGRAPH
+0xCFC9 0x73C8 #CJK UNIFIED IDEOGRAPH
+0xCFCA 0x73C5 #CJK UNIFIED IDEOGRAPH
+0xCFCB 0x73B9 #CJK UNIFIED IDEOGRAPH
+0xCFCC 0x73B6 #CJK UNIFIED IDEOGRAPH
+0xCFCD 0x73B5 #CJK UNIFIED IDEOGRAPH
+0xCFCE 0x73B4 #CJK UNIFIED IDEOGRAPH
+0xCFCF 0x73EB #CJK UNIFIED IDEOGRAPH
+0xCFD0 0x73BF #CJK UNIFIED IDEOGRAPH
+0xCFD1 0x73C7 #CJK UNIFIED IDEOGRAPH
+0xCFD2 0x73BE #CJK UNIFIED IDEOGRAPH
+0xCFD3 0x73C3 #CJK UNIFIED IDEOGRAPH
+0xCFD4 0x73C6 #CJK UNIFIED IDEOGRAPH
+0xCFD5 0x73B8 #CJK UNIFIED IDEOGRAPH
+0xCFD6 0x73CB #CJK UNIFIED IDEOGRAPH
+0xCFD7 0x74EC #CJK UNIFIED IDEOGRAPH
+0xCFD8 0x74EE #CJK UNIFIED IDEOGRAPH
+0xCFD9 0x752E #CJK UNIFIED IDEOGRAPH
+0xCFDA 0x7547 #CJK UNIFIED IDEOGRAPH
+0xCFDB 0x7548 #CJK UNIFIED IDEOGRAPH
+0xCFDC 0x75A7 #CJK UNIFIED IDEOGRAPH
+0xCFDD 0x75AA #CJK UNIFIED IDEOGRAPH
+0xCFDE 0x7679 #CJK UNIFIED IDEOGRAPH
+0xCFDF 0x76C4 #CJK UNIFIED IDEOGRAPH
+0xCFE0 0x7708 #CJK UNIFIED IDEOGRAPH
+0xCFE1 0x7703 #CJK UNIFIED IDEOGRAPH
+0xCFE2 0x7704 #CJK UNIFIED IDEOGRAPH
+0xCFE3 0x7705 #CJK UNIFIED IDEOGRAPH
+0xCFE4 0x770A #CJK UNIFIED IDEOGRAPH
+0xCFE5 0x76F7 #CJK UNIFIED IDEOGRAPH
+0xCFE6 0x76FB #CJK UNIFIED IDEOGRAPH
+0xCFE7 0x76FA #CJK UNIFIED IDEOGRAPH
+0xCFE8 0x77E7 #CJK UNIFIED IDEOGRAPH
+0xCFE9 0x77E8 #CJK UNIFIED IDEOGRAPH
+0xCFEA 0x7806 #CJK UNIFIED IDEOGRAPH
+0xCFEB 0x7811 #CJK UNIFIED IDEOGRAPH
+0xCFEC 0x7812 #CJK UNIFIED IDEOGRAPH
+0xCFED 0x7805 #CJK UNIFIED IDEOGRAPH
+0xCFEE 0x7810 #CJK UNIFIED IDEOGRAPH
+0xCFEF 0x780F #CJK UNIFIED IDEOGRAPH
+0xCFF0 0x780E #CJK UNIFIED IDEOGRAPH
+0xCFF1 0x7809 #CJK UNIFIED IDEOGRAPH
+0xCFF2 0x7803 #CJK UNIFIED IDEOGRAPH
+0xCFF3 0x7813 #CJK UNIFIED IDEOGRAPH
+0xCFF4 0x794A #CJK UNIFIED IDEOGRAPH
+0xCFF5 0x794C #CJK UNIFIED IDEOGRAPH
+0xCFF6 0x794B #CJK UNIFIED IDEOGRAPH
+0xCFF7 0x7945 #CJK UNIFIED IDEOGRAPH
+0xCFF8 0x7944 #CJK UNIFIED IDEOGRAPH
+0xCFF9 0x79D5 #CJK UNIFIED IDEOGRAPH
+0xCFFA 0x79CD #CJK UNIFIED IDEOGRAPH
+0xCFFB 0x79CF #CJK UNIFIED IDEOGRAPH
+0xCFFC 0x79D6 #CJK UNIFIED IDEOGRAPH
+0xCFFD 0x79CE #CJK UNIFIED IDEOGRAPH
+0xCFFE 0x7A80 #CJK UNIFIED IDEOGRAPH
+0xD040 0x7A7E #CJK UNIFIED IDEOGRAPH
+0xD041 0x7AD1 #CJK UNIFIED IDEOGRAPH
+0xD042 0x7B00 #CJK UNIFIED IDEOGRAPH
+0xD043 0x7B01 #CJK UNIFIED IDEOGRAPH
+0xD044 0x7C7A #CJK UNIFIED IDEOGRAPH
+0xD045 0x7C78 #CJK UNIFIED IDEOGRAPH
+0xD046 0x7C79 #CJK UNIFIED IDEOGRAPH
+0xD047 0x7C7F #CJK UNIFIED IDEOGRAPH
+0xD048 0x7C80 #CJK UNIFIED IDEOGRAPH
+0xD049 0x7C81 #CJK UNIFIED IDEOGRAPH
+0xD04A 0x7D03 #CJK UNIFIED IDEOGRAPH
+0xD04B 0x7D08 #CJK UNIFIED IDEOGRAPH
+0xD04C 0x7D01 #CJK UNIFIED IDEOGRAPH
+0xD04D 0x7F58 #CJK UNIFIED IDEOGRAPH
+0xD04E 0x7F91 #CJK UNIFIED IDEOGRAPH
+0xD04F 0x7F8D #CJK UNIFIED IDEOGRAPH
+0xD050 0x7FBE #CJK UNIFIED IDEOGRAPH
+0xD051 0x8007 #CJK UNIFIED IDEOGRAPH
+0xD052 0x800E #CJK UNIFIED IDEOGRAPH
+0xD053 0x800F #CJK UNIFIED IDEOGRAPH
+0xD054 0x8014 #CJK UNIFIED IDEOGRAPH
+0xD055 0x8037 #CJK UNIFIED IDEOGRAPH
+0xD056 0x80D8 #CJK UNIFIED IDEOGRAPH
+0xD057 0x80C7 #CJK UNIFIED IDEOGRAPH
+0xD058 0x80E0 #CJK UNIFIED IDEOGRAPH
+0xD059 0x80D1 #CJK UNIFIED IDEOGRAPH
+0xD05A 0x80C8 #CJK UNIFIED IDEOGRAPH
+0xD05B 0x80C2 #CJK UNIFIED IDEOGRAPH
+0xD05C 0x80D0 #CJK UNIFIED IDEOGRAPH
+0xD05D 0x80C5 #CJK UNIFIED IDEOGRAPH
+0xD05E 0x80E3 #CJK UNIFIED IDEOGRAPH
+0xD05F 0x80D9 #CJK UNIFIED IDEOGRAPH
+0xD060 0x80DC #CJK UNIFIED IDEOGRAPH
+0xD061 0x80CA #CJK UNIFIED IDEOGRAPH
+0xD062 0x80D5 #CJK UNIFIED IDEOGRAPH
+0xD063 0x80C9 #CJK UNIFIED IDEOGRAPH
+0xD064 0x80CF #CJK UNIFIED IDEOGRAPH
+0xD065 0x80D7 #CJK UNIFIED IDEOGRAPH
+0xD066 0x80E6 #CJK UNIFIED IDEOGRAPH
+0xD067 0x80CD #CJK UNIFIED IDEOGRAPH
+0xD068 0x81FF #CJK UNIFIED IDEOGRAPH
+0xD069 0x8221 #CJK UNIFIED IDEOGRAPH
+0xD06A 0x8294 #CJK UNIFIED IDEOGRAPH
+0xD06B 0x82D9 #CJK UNIFIED IDEOGRAPH
+0xD06C 0x82FE #CJK UNIFIED IDEOGRAPH
+0xD06D 0x82F9 #CJK UNIFIED IDEOGRAPH
+0xD06E 0x8307 #CJK UNIFIED IDEOGRAPH
+0xD06F 0x82E8 #CJK UNIFIED IDEOGRAPH
+0xD070 0x8300 #CJK UNIFIED IDEOGRAPH
+0xD071 0x82D5 #CJK UNIFIED IDEOGRAPH
+0xD072 0x833A #CJK UNIFIED IDEOGRAPH
+0xD073 0x82EB #CJK UNIFIED IDEOGRAPH
+0xD074 0x82D6 #CJK UNIFIED IDEOGRAPH
+0xD075 0x82F4 #CJK UNIFIED IDEOGRAPH
+0xD076 0x82EC #CJK UNIFIED IDEOGRAPH
+0xD077 0x82E1 #CJK UNIFIED IDEOGRAPH
+0xD078 0x82F2 #CJK UNIFIED IDEOGRAPH
+0xD079 0x82F5 #CJK UNIFIED IDEOGRAPH
+0xD07A 0x830C #CJK UNIFIED IDEOGRAPH
+0xD07B 0x82FB #CJK UNIFIED IDEOGRAPH
+0xD07C 0x82F6 #CJK UNIFIED IDEOGRAPH
+0xD07D 0x82F0 #CJK UNIFIED IDEOGRAPH
+0xD07E 0x82EA #CJK UNIFIED IDEOGRAPH
+0xD0A1 0x82E4 #CJK UNIFIED IDEOGRAPH
+0xD0A2 0x82E0 #CJK UNIFIED IDEOGRAPH
+0xD0A3 0x82FA #CJK UNIFIED IDEOGRAPH
+0xD0A4 0x82F3 #CJK UNIFIED IDEOGRAPH
+0xD0A5 0x82ED #CJK UNIFIED IDEOGRAPH
+0xD0A6 0x8677 #CJK UNIFIED IDEOGRAPH
+0xD0A7 0x8674 #CJK UNIFIED IDEOGRAPH
+0xD0A8 0x867C #CJK UNIFIED IDEOGRAPH
+0xD0A9 0x8673 #CJK UNIFIED IDEOGRAPH
+0xD0AA 0x8841 #CJK UNIFIED IDEOGRAPH
+0xD0AB 0x884E #CJK UNIFIED IDEOGRAPH
+0xD0AC 0x8867 #CJK UNIFIED IDEOGRAPH
+0xD0AD 0x886A #CJK UNIFIED IDEOGRAPH
+0xD0AE 0x8869 #CJK UNIFIED IDEOGRAPH
+0xD0AF 0x89D3 #CJK UNIFIED IDEOGRAPH
+0xD0B0 0x8A04 #CJK UNIFIED IDEOGRAPH
+0xD0B1 0x8A07 #CJK UNIFIED IDEOGRAPH
+0xD0B2 0x8D72 #CJK UNIFIED IDEOGRAPH
+0xD0B3 0x8FE3 #CJK UNIFIED IDEOGRAPH
+0xD0B4 0x8FE1 #CJK UNIFIED IDEOGRAPH
+0xD0B5 0x8FEE #CJK UNIFIED IDEOGRAPH
+0xD0B6 0x8FE0 #CJK UNIFIED IDEOGRAPH
+0xD0B7 0x90F1 #CJK UNIFIED IDEOGRAPH
+0xD0B8 0x90BD #CJK UNIFIED IDEOGRAPH
+0xD0B9 0x90BF #CJK UNIFIED IDEOGRAPH
+0xD0BA 0x90D5 #CJK UNIFIED IDEOGRAPH
+0xD0BB 0x90C5 #CJK UNIFIED IDEOGRAPH
+0xD0BC 0x90BE #CJK UNIFIED IDEOGRAPH
+0xD0BD 0x90C7 #CJK UNIFIED IDEOGRAPH
+0xD0BE 0x90CB #CJK UNIFIED IDEOGRAPH
+0xD0BF 0x90C8 #CJK UNIFIED IDEOGRAPH
+0xD0C0 0x91D4 #CJK UNIFIED IDEOGRAPH
+0xD0C1 0x91D3 #CJK UNIFIED IDEOGRAPH
+0xD0C2 0x9654 #CJK UNIFIED IDEOGRAPH
+0xD0C3 0x964F #CJK UNIFIED IDEOGRAPH
+0xD0C4 0x9651 #CJK UNIFIED IDEOGRAPH
+0xD0C5 0x9653 #CJK UNIFIED IDEOGRAPH
+0xD0C6 0x964A #CJK UNIFIED IDEOGRAPH
+0xD0C7 0x964E #CJK UNIFIED IDEOGRAPH
+0xD0C8 0x501E #CJK UNIFIED IDEOGRAPH
+0xD0C9 0x5005 #CJK UNIFIED IDEOGRAPH
+0xD0CA 0x5007 #CJK UNIFIED IDEOGRAPH
+0xD0CB 0x5013 #CJK UNIFIED IDEOGRAPH
+0xD0CC 0x5022 #CJK UNIFIED IDEOGRAPH
+0xD0CD 0x5030 #CJK UNIFIED IDEOGRAPH
+0xD0CE 0x501B #CJK UNIFIED IDEOGRAPH
+0xD0CF 0x4FF5 #CJK UNIFIED IDEOGRAPH
+0xD0D0 0x4FF4 #CJK UNIFIED IDEOGRAPH
+0xD0D1 0x5033 #CJK UNIFIED IDEOGRAPH
+0xD0D2 0x5037 #CJK UNIFIED IDEOGRAPH
+0xD0D3 0x502C #CJK UNIFIED IDEOGRAPH
+0xD0D4 0x4FF6 #CJK UNIFIED IDEOGRAPH
+0xD0D5 0x4FF7 #CJK UNIFIED IDEOGRAPH
+0xD0D6 0x5017 #CJK UNIFIED IDEOGRAPH
+0xD0D7 0x501C #CJK UNIFIED IDEOGRAPH
+0xD0D8 0x5020 #CJK UNIFIED IDEOGRAPH
+0xD0D9 0x5027 #CJK UNIFIED IDEOGRAPH
+0xD0DA 0x5035 #CJK UNIFIED IDEOGRAPH
+0xD0DB 0x502F #CJK UNIFIED IDEOGRAPH
+0xD0DC 0x5031 #CJK UNIFIED IDEOGRAPH
+0xD0DD 0x500E #CJK UNIFIED IDEOGRAPH
+0xD0DE 0x515A #CJK UNIFIED IDEOGRAPH
+0xD0DF 0x5194 #CJK UNIFIED IDEOGRAPH
+0xD0E0 0x5193 #CJK UNIFIED IDEOGRAPH
+0xD0E1 0x51CA #CJK UNIFIED IDEOGRAPH
+0xD0E2 0x51C4 #CJK UNIFIED IDEOGRAPH
+0xD0E3 0x51C5 #CJK UNIFIED IDEOGRAPH
+0xD0E4 0x51C8 #CJK UNIFIED IDEOGRAPH
+0xD0E5 0x51CE #CJK UNIFIED IDEOGRAPH
+0xD0E6 0x5261 #CJK UNIFIED IDEOGRAPH
+0xD0E7 0x525A #CJK UNIFIED IDEOGRAPH
+0xD0E8 0x5252 #CJK UNIFIED IDEOGRAPH
+0xD0E9 0x525E #CJK UNIFIED IDEOGRAPH
+0xD0EA 0x525F #CJK UNIFIED IDEOGRAPH
+0xD0EB 0x5255 #CJK UNIFIED IDEOGRAPH
+0xD0EC 0x5262 #CJK UNIFIED IDEOGRAPH
+0xD0ED 0x52CD #CJK UNIFIED IDEOGRAPH
+0xD0EE 0x530E #CJK UNIFIED IDEOGRAPH
+0xD0EF 0x539E #CJK UNIFIED IDEOGRAPH
+0xD0F0 0x5526 #CJK UNIFIED IDEOGRAPH
+0xD0F1 0x54E2 #CJK UNIFIED IDEOGRAPH
+0xD0F2 0x5517 #CJK UNIFIED IDEOGRAPH
+0xD0F3 0x5512 #CJK UNIFIED IDEOGRAPH
+0xD0F4 0x54E7 #CJK UNIFIED IDEOGRAPH
+0xD0F5 0x54F3 #CJK UNIFIED IDEOGRAPH
+0xD0F6 0x54E4 #CJK UNIFIED IDEOGRAPH
+0xD0F7 0x551A #CJK UNIFIED IDEOGRAPH
+0xD0F8 0x54FF #CJK UNIFIED IDEOGRAPH
+0xD0F9 0x5504 #CJK UNIFIED IDEOGRAPH
+0xD0FA 0x5508 #CJK UNIFIED IDEOGRAPH
+0xD0FB 0x54EB #CJK UNIFIED IDEOGRAPH
+0xD0FC 0x5511 #CJK UNIFIED IDEOGRAPH
+0xD0FD 0x5505 #CJK UNIFIED IDEOGRAPH
+0xD0FE 0x54F1 #CJK UNIFIED IDEOGRAPH
+0xD140 0x550A #CJK UNIFIED IDEOGRAPH
+0xD141 0x54FB #CJK UNIFIED IDEOGRAPH
+0xD142 0x54F7 #CJK UNIFIED IDEOGRAPH
+0xD143 0x54F8 #CJK UNIFIED IDEOGRAPH
+0xD144 0x54E0 #CJK UNIFIED IDEOGRAPH
+0xD145 0x550E #CJK UNIFIED IDEOGRAPH
+0xD146 0x5503 #CJK UNIFIED IDEOGRAPH
+0xD147 0x550B #CJK UNIFIED IDEOGRAPH
+0xD148 0x5701 #CJK UNIFIED IDEOGRAPH
+0xD149 0x5702 #CJK UNIFIED IDEOGRAPH
+0xD14A 0x57CC #CJK UNIFIED IDEOGRAPH
+0xD14B 0x5832 #CJK UNIFIED IDEOGRAPH
+0xD14C 0x57D5 #CJK UNIFIED IDEOGRAPH
+0xD14D 0x57D2 #CJK UNIFIED IDEOGRAPH
+0xD14E 0x57BA #CJK UNIFIED IDEOGRAPH
+0xD14F 0x57C6 #CJK UNIFIED IDEOGRAPH
+0xD150 0x57BD #CJK UNIFIED IDEOGRAPH
+0xD151 0x57BC #CJK UNIFIED IDEOGRAPH
+0xD152 0x57B8 #CJK UNIFIED IDEOGRAPH
+0xD153 0x57B6 #CJK UNIFIED IDEOGRAPH
+0xD154 0x57BF #CJK UNIFIED IDEOGRAPH
+0xD155 0x57C7 #CJK UNIFIED IDEOGRAPH
+0xD156 0x57D0 #CJK UNIFIED IDEOGRAPH
+0xD157 0x57B9 #CJK UNIFIED IDEOGRAPH
+0xD158 0x57C1 #CJK UNIFIED IDEOGRAPH
+0xD159 0x590E #CJK UNIFIED IDEOGRAPH
+0xD15A 0x594A #CJK UNIFIED IDEOGRAPH
+0xD15B 0x5A19 #CJK UNIFIED IDEOGRAPH
+0xD15C 0x5A16 #CJK UNIFIED IDEOGRAPH
+0xD15D 0x5A2D #CJK UNIFIED IDEOGRAPH
+0xD15E 0x5A2E #CJK UNIFIED IDEOGRAPH
+0xD15F 0x5A15 #CJK UNIFIED IDEOGRAPH
+0xD160 0x5A0F #CJK UNIFIED IDEOGRAPH
+0xD161 0x5A17 #CJK UNIFIED IDEOGRAPH
+0xD162 0x5A0A #CJK UNIFIED IDEOGRAPH
+0xD163 0x5A1E #CJK UNIFIED IDEOGRAPH
+0xD164 0x5A33 #CJK UNIFIED IDEOGRAPH
+0xD165 0x5B6C #CJK UNIFIED IDEOGRAPH
+0xD166 0x5BA7 #CJK UNIFIED IDEOGRAPH
+0xD167 0x5BAD #CJK UNIFIED IDEOGRAPH
+0xD168 0x5BAC #CJK UNIFIED IDEOGRAPH
+0xD169 0x5C03 #CJK UNIFIED IDEOGRAPH
+0xD16A 0x5C56 #CJK UNIFIED IDEOGRAPH
+0xD16B 0x5C54 #CJK UNIFIED IDEOGRAPH
+0xD16C 0x5CEC #CJK UNIFIED IDEOGRAPH
+0xD16D 0x5CFF #CJK UNIFIED IDEOGRAPH
+0xD16E 0x5CEE #CJK UNIFIED IDEOGRAPH
+0xD16F 0x5CF1 #CJK UNIFIED IDEOGRAPH
+0xD170 0x5CF7 #CJK UNIFIED IDEOGRAPH
+0xD171 0x5D00 #CJK UNIFIED IDEOGRAPH
+0xD172 0x5CF9 #CJK UNIFIED IDEOGRAPH
+0xD173 0x5E29 #CJK UNIFIED IDEOGRAPH
+0xD174 0x5E28 #CJK UNIFIED IDEOGRAPH
+0xD175 0x5EA8 #CJK UNIFIED IDEOGRAPH
+0xD176 0x5EAE #CJK UNIFIED IDEOGRAPH
+0xD177 0x5EAA #CJK UNIFIED IDEOGRAPH
+0xD178 0x5EAC #CJK UNIFIED IDEOGRAPH
+0xD179 0x5F33 #CJK UNIFIED IDEOGRAPH
+0xD17A 0x5F30 #CJK UNIFIED IDEOGRAPH
+0xD17B 0x5F67 #CJK UNIFIED IDEOGRAPH
+0xD17C 0x605D #CJK UNIFIED IDEOGRAPH
+0xD17D 0x605A #CJK UNIFIED IDEOGRAPH
+0xD17E 0x6067 #CJK UNIFIED IDEOGRAPH
+0xD1A1 0x6041 #CJK UNIFIED IDEOGRAPH
+0xD1A2 0x60A2 #CJK UNIFIED IDEOGRAPH
+0xD1A3 0x6088 #CJK UNIFIED IDEOGRAPH
+0xD1A4 0x6080 #CJK UNIFIED IDEOGRAPH
+0xD1A5 0x6092 #CJK UNIFIED IDEOGRAPH
+0xD1A6 0x6081 #CJK UNIFIED IDEOGRAPH
+0xD1A7 0x609D #CJK UNIFIED IDEOGRAPH
+0xD1A8 0x6083 #CJK UNIFIED IDEOGRAPH
+0xD1A9 0x6095 #CJK UNIFIED IDEOGRAPH
+0xD1AA 0x609B #CJK UNIFIED IDEOGRAPH
+0xD1AB 0x6097 #CJK UNIFIED IDEOGRAPH
+0xD1AC 0x6087 #CJK UNIFIED IDEOGRAPH
+0xD1AD 0x609C #CJK UNIFIED IDEOGRAPH
+0xD1AE 0x608E #CJK UNIFIED IDEOGRAPH
+0xD1AF 0x6219 #CJK UNIFIED IDEOGRAPH
+0xD1B0 0x6246 #CJK UNIFIED IDEOGRAPH
+0xD1B1 0x62F2 #CJK UNIFIED IDEOGRAPH
+0xD1B2 0x6310 #CJK UNIFIED IDEOGRAPH
+0xD1B3 0x6356 #CJK UNIFIED IDEOGRAPH
+0xD1B4 0x632C #CJK UNIFIED IDEOGRAPH
+0xD1B5 0x6344 #CJK UNIFIED IDEOGRAPH
+0xD1B6 0x6345 #CJK UNIFIED IDEOGRAPH
+0xD1B7 0x6336 #CJK UNIFIED IDEOGRAPH
+0xD1B8 0x6343 #CJK UNIFIED IDEOGRAPH
+0xD1B9 0x63E4 #CJK UNIFIED IDEOGRAPH
+0xD1BA 0x6339 #CJK UNIFIED IDEOGRAPH
+0xD1BB 0x634B #CJK UNIFIED IDEOGRAPH
+0xD1BC 0x634A #CJK UNIFIED IDEOGRAPH
+0xD1BD 0x633C #CJK UNIFIED IDEOGRAPH
+0xD1BE 0x6329 #CJK UNIFIED IDEOGRAPH
+0xD1BF 0x6341 #CJK UNIFIED IDEOGRAPH
+0xD1C0 0x6334 #CJK UNIFIED IDEOGRAPH
+0xD1C1 0x6358 #CJK UNIFIED IDEOGRAPH
+0xD1C2 0x6354 #CJK UNIFIED IDEOGRAPH
+0xD1C3 0x6359 #CJK UNIFIED IDEOGRAPH
+0xD1C4 0x632D #CJK UNIFIED IDEOGRAPH
+0xD1C5 0x6347 #CJK UNIFIED IDEOGRAPH
+0xD1C6 0x6333 #CJK UNIFIED IDEOGRAPH
+0xD1C7 0x635A #CJK UNIFIED IDEOGRAPH
+0xD1C8 0x6351 #CJK UNIFIED IDEOGRAPH
+0xD1C9 0x6338 #CJK UNIFIED IDEOGRAPH
+0xD1CA 0x6357 #CJK UNIFIED IDEOGRAPH
+0xD1CB 0x6340 #CJK UNIFIED IDEOGRAPH
+0xD1CC 0x6348 #CJK UNIFIED IDEOGRAPH
+0xD1CD 0x654A #CJK UNIFIED IDEOGRAPH
+0xD1CE 0x6546 #CJK UNIFIED IDEOGRAPH
+0xD1CF 0x65C6 #CJK UNIFIED IDEOGRAPH
+0xD1D0 0x65C3 #CJK UNIFIED IDEOGRAPH
+0xD1D1 0x65C4 #CJK UNIFIED IDEOGRAPH
+0xD1D2 0x65C2 #CJK UNIFIED IDEOGRAPH
+0xD1D3 0x664A #CJK UNIFIED IDEOGRAPH
+0xD1D4 0x665F #CJK UNIFIED IDEOGRAPH
+0xD1D5 0x6647 #CJK UNIFIED IDEOGRAPH
+0xD1D6 0x6651 #CJK UNIFIED IDEOGRAPH
+0xD1D7 0x6712 #CJK UNIFIED IDEOGRAPH
+0xD1D8 0x6713 #CJK UNIFIED IDEOGRAPH
+0xD1D9 0x681F #CJK UNIFIED IDEOGRAPH
+0xD1DA 0x681A #CJK UNIFIED IDEOGRAPH
+0xD1DB 0x6849 #CJK UNIFIED IDEOGRAPH
+0xD1DC 0x6832 #CJK UNIFIED IDEOGRAPH
+0xD1DD 0x6833 #CJK UNIFIED IDEOGRAPH
+0xD1DE 0x683B #CJK UNIFIED IDEOGRAPH
+0xD1DF 0x684B #CJK UNIFIED IDEOGRAPH
+0xD1E0 0x684F #CJK UNIFIED IDEOGRAPH
+0xD1E1 0x6816 #CJK UNIFIED IDEOGRAPH
+0xD1E2 0x6831 #CJK UNIFIED IDEOGRAPH
+0xD1E3 0x681C #CJK UNIFIED IDEOGRAPH
+0xD1E4 0x6835 #CJK UNIFIED IDEOGRAPH
+0xD1E5 0x682B #CJK UNIFIED IDEOGRAPH
+0xD1E6 0x682D #CJK UNIFIED IDEOGRAPH
+0xD1E7 0x682F #CJK UNIFIED IDEOGRAPH
+0xD1E8 0x684E #CJK UNIFIED IDEOGRAPH
+0xD1E9 0x6844 #CJK UNIFIED IDEOGRAPH
+0xD1EA 0x6834 #CJK UNIFIED IDEOGRAPH
+0xD1EB 0x681D #CJK UNIFIED IDEOGRAPH
+0xD1EC 0x6812 #CJK UNIFIED IDEOGRAPH
+0xD1ED 0x6814 #CJK UNIFIED IDEOGRAPH
+0xD1EE 0x6826 #CJK UNIFIED IDEOGRAPH
+0xD1EF 0x6828 #CJK UNIFIED IDEOGRAPH
+0xD1F0 0x682E #CJK UNIFIED IDEOGRAPH
+0xD1F1 0x684D #CJK UNIFIED IDEOGRAPH
+0xD1F2 0x683A #CJK UNIFIED IDEOGRAPH
+0xD1F3 0x6825 #CJK UNIFIED IDEOGRAPH
+0xD1F4 0x6820 #CJK UNIFIED IDEOGRAPH
+0xD1F5 0x6B2C #CJK UNIFIED IDEOGRAPH
+0xD1F6 0x6B2F #CJK UNIFIED IDEOGRAPH
+0xD1F7 0x6B2D #CJK UNIFIED IDEOGRAPH
+0xD1F8 0x6B31 #CJK UNIFIED IDEOGRAPH
+0xD1F9 0x6B34 #CJK UNIFIED IDEOGRAPH
+0xD1FA 0x6B6D #CJK UNIFIED IDEOGRAPH
+0xD1FB 0x8082 #CJK UNIFIED IDEOGRAPH
+0xD1FC 0x6B88 #CJK UNIFIED IDEOGRAPH
+0xD1FD 0x6BE6 #CJK UNIFIED IDEOGRAPH
+0xD1FE 0x6BE4 #CJK UNIFIED IDEOGRAPH
+0xD240 0x6BE8 #CJK UNIFIED IDEOGRAPH
+0xD241 0x6BE3 #CJK UNIFIED IDEOGRAPH
+0xD242 0x6BE2 #CJK UNIFIED IDEOGRAPH
+0xD243 0x6BE7 #CJK UNIFIED IDEOGRAPH
+0xD244 0x6C25 #CJK UNIFIED IDEOGRAPH
+0xD245 0x6D7A #CJK UNIFIED IDEOGRAPH
+0xD246 0x6D63 #CJK UNIFIED IDEOGRAPH
+0xD247 0x6D64 #CJK UNIFIED IDEOGRAPH
+0xD248 0x6D76 #CJK UNIFIED IDEOGRAPH
+0xD249 0x6D0D #CJK UNIFIED IDEOGRAPH
+0xD24A 0x6D61 #CJK UNIFIED IDEOGRAPH
+0xD24B 0x6D92 #CJK UNIFIED IDEOGRAPH
+0xD24C 0x6D58 #CJK UNIFIED IDEOGRAPH
+0xD24D 0x6D62 #CJK UNIFIED IDEOGRAPH
+0xD24E 0x6D6D #CJK UNIFIED IDEOGRAPH
+0xD24F 0x6D6F #CJK UNIFIED IDEOGRAPH
+0xD250 0x6D91 #CJK UNIFIED IDEOGRAPH
+0xD251 0x6D8D #CJK UNIFIED IDEOGRAPH
+0xD252 0x6DEF #CJK UNIFIED IDEOGRAPH
+0xD253 0x6D7F #CJK UNIFIED IDEOGRAPH
+0xD254 0x6D86 #CJK UNIFIED IDEOGRAPH
+0xD255 0x6D5E #CJK UNIFIED IDEOGRAPH
+0xD256 0x6D67 #CJK UNIFIED IDEOGRAPH
+0xD257 0x6D60 #CJK UNIFIED IDEOGRAPH
+0xD258 0x6D97 #CJK UNIFIED IDEOGRAPH
+0xD259 0x6D70 #CJK UNIFIED IDEOGRAPH
+0xD25A 0x6D7C #CJK UNIFIED IDEOGRAPH
+0xD25B 0x6D5F #CJK UNIFIED IDEOGRAPH
+0xD25C 0x6D82 #CJK UNIFIED IDEOGRAPH
+0xD25D 0x6D98 #CJK UNIFIED IDEOGRAPH
+0xD25E 0x6D2F #CJK UNIFIED IDEOGRAPH
+0xD25F 0x6D68 #CJK UNIFIED IDEOGRAPH
+0xD260 0x6D8B #CJK UNIFIED IDEOGRAPH
+0xD261 0x6D7E #CJK UNIFIED IDEOGRAPH
+0xD262 0x6D80 #CJK UNIFIED IDEOGRAPH
+0xD263 0x6D84 #CJK UNIFIED IDEOGRAPH
+0xD264 0x6D16 #CJK UNIFIED IDEOGRAPH
+0xD265 0x6D83 #CJK UNIFIED IDEOGRAPH
+0xD266 0x6D7B #CJK UNIFIED IDEOGRAPH
+0xD267 0x6D7D #CJK UNIFIED IDEOGRAPH
+0xD268 0x6D75 #CJK UNIFIED IDEOGRAPH
+0xD269 0x6D90 #CJK UNIFIED IDEOGRAPH
+0xD26A 0x70DC #CJK UNIFIED IDEOGRAPH
+0xD26B 0x70D3 #CJK UNIFIED IDEOGRAPH
+0xD26C 0x70D1 #CJK UNIFIED IDEOGRAPH
+0xD26D 0x70DD #CJK UNIFIED IDEOGRAPH
+0xD26E 0x70CB #CJK UNIFIED IDEOGRAPH
+0xD26F 0x7F39 #CJK UNIFIED IDEOGRAPH
+0xD270 0x70E2 #CJK UNIFIED IDEOGRAPH
+0xD271 0x70D7 #CJK UNIFIED IDEOGRAPH
+0xD272 0x70D2 #CJK UNIFIED IDEOGRAPH
+0xD273 0x70DE #CJK UNIFIED IDEOGRAPH
+0xD274 0x70E0 #CJK UNIFIED IDEOGRAPH
+0xD275 0x70D4 #CJK UNIFIED IDEOGRAPH
+0xD276 0x70CD #CJK UNIFIED IDEOGRAPH
+0xD277 0x70C5 #CJK UNIFIED IDEOGRAPH
+0xD278 0x70C6 #CJK UNIFIED IDEOGRAPH
+0xD279 0x70C7 #CJK UNIFIED IDEOGRAPH
+0xD27A 0x70DA #CJK UNIFIED IDEOGRAPH
+0xD27B 0x70CE #CJK UNIFIED IDEOGRAPH
+0xD27C 0x70E1 #CJK UNIFIED IDEOGRAPH
+0xD27D 0x7242 #CJK UNIFIED IDEOGRAPH
+0xD27E 0x7278 #CJK UNIFIED IDEOGRAPH
+0xD2A1 0x7277 #CJK UNIFIED IDEOGRAPH
+0xD2A2 0x7276 #CJK UNIFIED IDEOGRAPH
+0xD2A3 0x7300 #CJK UNIFIED IDEOGRAPH
+0xD2A4 0x72FA #CJK UNIFIED IDEOGRAPH
+0xD2A5 0x72F4 #CJK UNIFIED IDEOGRAPH
+0xD2A6 0x72FE #CJK UNIFIED IDEOGRAPH
+0xD2A7 0x72F6 #CJK UNIFIED IDEOGRAPH
+0xD2A8 0x72F3 #CJK UNIFIED IDEOGRAPH
+0xD2A9 0x72FB #CJK UNIFIED IDEOGRAPH
+0xD2AA 0x7301 #CJK UNIFIED IDEOGRAPH
+0xD2AB 0x73D3 #CJK UNIFIED IDEOGRAPH
+0xD2AC 0x73D9 #CJK UNIFIED IDEOGRAPH
+0xD2AD 0x73E5 #CJK UNIFIED IDEOGRAPH
+0xD2AE 0x73D6 #CJK UNIFIED IDEOGRAPH
+0xD2AF 0x73BC #CJK UNIFIED IDEOGRAPH
+0xD2B0 0x73E7 #CJK UNIFIED IDEOGRAPH
+0xD2B1 0x73E3 #CJK UNIFIED IDEOGRAPH
+0xD2B2 0x73E9 #CJK UNIFIED IDEOGRAPH
+0xD2B3 0x73DC #CJK UNIFIED IDEOGRAPH
+0xD2B4 0x73D2 #CJK UNIFIED IDEOGRAPH
+0xD2B5 0x73DB #CJK UNIFIED IDEOGRAPH
+0xD2B6 0x73D4 #CJK UNIFIED IDEOGRAPH
+0xD2B7 0x73DD #CJK UNIFIED IDEOGRAPH
+0xD2B8 0x73DA #CJK UNIFIED IDEOGRAPH
+0xD2B9 0x73D7 #CJK UNIFIED IDEOGRAPH
+0xD2BA 0x73D8 #CJK UNIFIED IDEOGRAPH
+0xD2BB 0x73E8 #CJK UNIFIED IDEOGRAPH
+0xD2BC 0x74DE #CJK UNIFIED IDEOGRAPH
+0xD2BD 0x74DF #CJK UNIFIED IDEOGRAPH
+0xD2BE 0x74F4 #CJK UNIFIED IDEOGRAPH
+0xD2BF 0x74F5 #CJK UNIFIED IDEOGRAPH
+0xD2C0 0x7521 #CJK UNIFIED IDEOGRAPH
+0xD2C1 0x755B #CJK UNIFIED IDEOGRAPH
+0xD2C2 0x755F #CJK UNIFIED IDEOGRAPH
+0xD2C3 0x75B0 #CJK UNIFIED IDEOGRAPH
+0xD2C4 0x75C1 #CJK UNIFIED IDEOGRAPH
+0xD2C5 0x75BB #CJK UNIFIED IDEOGRAPH
+0xD2C6 0x75C4 #CJK UNIFIED IDEOGRAPH
+0xD2C7 0x75C0 #CJK UNIFIED IDEOGRAPH
+0xD2C8 0x75BF #CJK UNIFIED IDEOGRAPH
+0xD2C9 0x75B6 #CJK UNIFIED IDEOGRAPH
+0xD2CA 0x75BA #CJK UNIFIED IDEOGRAPH
+0xD2CB 0x768A #CJK UNIFIED IDEOGRAPH
+0xD2CC 0x76C9 #CJK UNIFIED IDEOGRAPH
+0xD2CD 0x771D #CJK UNIFIED IDEOGRAPH
+0xD2CE 0x771B #CJK UNIFIED IDEOGRAPH
+0xD2CF 0x7710 #CJK UNIFIED IDEOGRAPH
+0xD2D0 0x7713 #CJK UNIFIED IDEOGRAPH
+0xD2D1 0x7712 #CJK UNIFIED IDEOGRAPH
+0xD2D2 0x7723 #CJK UNIFIED IDEOGRAPH
+0xD2D3 0x7711 #CJK UNIFIED IDEOGRAPH
+0xD2D4 0x7715 #CJK UNIFIED IDEOGRAPH
+0xD2D5 0x7719 #CJK UNIFIED IDEOGRAPH
+0xD2D6 0x771A #CJK UNIFIED IDEOGRAPH
+0xD2D7 0x7722 #CJK UNIFIED IDEOGRAPH
+0xD2D8 0x7727 #CJK UNIFIED IDEOGRAPH
+0xD2D9 0x7823 #CJK UNIFIED IDEOGRAPH
+0xD2DA 0x782C #CJK UNIFIED IDEOGRAPH
+0xD2DB 0x7822 #CJK UNIFIED IDEOGRAPH
+0xD2DC 0x7835 #CJK UNIFIED IDEOGRAPH
+0xD2DD 0x782F #CJK UNIFIED IDEOGRAPH
+0xD2DE 0x7828 #CJK UNIFIED IDEOGRAPH
+0xD2DF 0x782E #CJK UNIFIED IDEOGRAPH
+0xD2E0 0x782B #CJK UNIFIED IDEOGRAPH
+0xD2E1 0x7821 #CJK UNIFIED IDEOGRAPH
+0xD2E2 0x7829 #CJK UNIFIED IDEOGRAPH
+0xD2E3 0x7833 #CJK UNIFIED IDEOGRAPH
+0xD2E4 0x782A #CJK UNIFIED IDEOGRAPH
+0xD2E5 0x7831 #CJK UNIFIED IDEOGRAPH
+0xD2E6 0x7954 #CJK UNIFIED IDEOGRAPH
+0xD2E7 0x795B #CJK UNIFIED IDEOGRAPH
+0xD2E8 0x794F #CJK UNIFIED IDEOGRAPH
+0xD2E9 0x795C #CJK UNIFIED IDEOGRAPH
+0xD2EA 0x7953 #CJK UNIFIED IDEOGRAPH
+0xD2EB 0x7952 #CJK UNIFIED IDEOGRAPH
+0xD2EC 0x7951 #CJK UNIFIED IDEOGRAPH
+0xD2ED 0x79EB #CJK UNIFIED IDEOGRAPH
+0xD2EE 0x79EC #CJK UNIFIED IDEOGRAPH
+0xD2EF 0x79E0 #CJK UNIFIED IDEOGRAPH
+0xD2F0 0x79EE #CJK UNIFIED IDEOGRAPH
+0xD2F1 0x79ED #CJK UNIFIED IDEOGRAPH
+0xD2F2 0x79EA #CJK UNIFIED IDEOGRAPH
+0xD2F3 0x79DC #CJK UNIFIED IDEOGRAPH
+0xD2F4 0x79DE #CJK UNIFIED IDEOGRAPH
+0xD2F5 0x79DD #CJK UNIFIED IDEOGRAPH
+0xD2F6 0x7A86 #CJK UNIFIED IDEOGRAPH
+0xD2F7 0x7A89 #CJK UNIFIED IDEOGRAPH
+0xD2F8 0x7A85 #CJK UNIFIED IDEOGRAPH
+0xD2F9 0x7A8B #CJK UNIFIED IDEOGRAPH
+0xD2FA 0x7A8C #CJK UNIFIED IDEOGRAPH
+0xD2FB 0x7A8A #CJK UNIFIED IDEOGRAPH
+0xD2FC 0x7A87 #CJK UNIFIED IDEOGRAPH
+0xD2FD 0x7AD8 #CJK UNIFIED IDEOGRAPH
+0xD2FE 0x7B10 #CJK UNIFIED IDEOGRAPH
+0xD340 0x7B04 #CJK UNIFIED IDEOGRAPH
+0xD341 0x7B13 #CJK UNIFIED IDEOGRAPH
+0xD342 0x7B05 #CJK UNIFIED IDEOGRAPH
+0xD343 0x7B0F #CJK UNIFIED IDEOGRAPH
+0xD344 0x7B08 #CJK UNIFIED IDEOGRAPH
+0xD345 0x7B0A #CJK UNIFIED IDEOGRAPH
+0xD346 0x7B0E #CJK UNIFIED IDEOGRAPH
+0xD347 0x7B09 #CJK UNIFIED IDEOGRAPH
+0xD348 0x7B12 #CJK UNIFIED IDEOGRAPH
+0xD349 0x7C84 #CJK UNIFIED IDEOGRAPH
+0xD34A 0x7C91 #CJK UNIFIED IDEOGRAPH
+0xD34B 0x7C8A #CJK UNIFIED IDEOGRAPH
+0xD34C 0x7C8C #CJK UNIFIED IDEOGRAPH
+0xD34D 0x7C88 #CJK UNIFIED IDEOGRAPH
+0xD34E 0x7C8D #CJK UNIFIED IDEOGRAPH
+0xD34F 0x7C85 #CJK UNIFIED IDEOGRAPH
+0xD350 0x7D1E #CJK UNIFIED IDEOGRAPH
+0xD351 0x7D1D #CJK UNIFIED IDEOGRAPH
+0xD352 0x7D11 #CJK UNIFIED IDEOGRAPH
+0xD353 0x7D0E #CJK UNIFIED IDEOGRAPH
+0xD354 0x7D18 #CJK UNIFIED IDEOGRAPH
+0xD355 0x7D16 #CJK UNIFIED IDEOGRAPH
+0xD356 0x7D13 #CJK UNIFIED IDEOGRAPH
+0xD357 0x7D1F #CJK UNIFIED IDEOGRAPH
+0xD358 0x7D12 #CJK UNIFIED IDEOGRAPH
+0xD359 0x7D0F #CJK UNIFIED IDEOGRAPH
+0xD35A 0x7D0C #CJK UNIFIED IDEOGRAPH
+0xD35B 0x7F5C #CJK UNIFIED IDEOGRAPH
+0xD35C 0x7F61 #CJK UNIFIED IDEOGRAPH
+0xD35D 0x7F5E #CJK UNIFIED IDEOGRAPH
+0xD35E 0x7F60 #CJK UNIFIED IDEOGRAPH
+0xD35F 0x7F5D #CJK UNIFIED IDEOGRAPH
+0xD360 0x7F5B #CJK UNIFIED IDEOGRAPH
+0xD361 0x7F96 #CJK UNIFIED IDEOGRAPH
+0xD362 0x7F92 #CJK UNIFIED IDEOGRAPH
+0xD363 0x7FC3 #CJK UNIFIED IDEOGRAPH
+0xD364 0x7FC2 #CJK UNIFIED IDEOGRAPH
+0xD365 0x7FC0 #CJK UNIFIED IDEOGRAPH
+0xD366 0x8016 #CJK UNIFIED IDEOGRAPH
+0xD367 0x803E #CJK UNIFIED IDEOGRAPH
+0xD368 0x8039 #CJK UNIFIED IDEOGRAPH
+0xD369 0x80FA #CJK UNIFIED IDEOGRAPH
+0xD36A 0x80F2 #CJK UNIFIED IDEOGRAPH
+0xD36B 0x80F9 #CJK UNIFIED IDEOGRAPH
+0xD36C 0x80F5 #CJK UNIFIED IDEOGRAPH
+0xD36D 0x8101 #CJK UNIFIED IDEOGRAPH
+0xD36E 0x80FB #CJK UNIFIED IDEOGRAPH
+0xD36F 0x8100 #CJK UNIFIED IDEOGRAPH
+0xD370 0x8201 #CJK UNIFIED IDEOGRAPH
+0xD371 0x822F #CJK UNIFIED IDEOGRAPH
+0xD372 0x8225 #CJK UNIFIED IDEOGRAPH
+0xD373 0x8333 #CJK UNIFIED IDEOGRAPH
+0xD374 0x832D #CJK UNIFIED IDEOGRAPH
+0xD375 0x8344 #CJK UNIFIED IDEOGRAPH
+0xD376 0x8319 #CJK UNIFIED IDEOGRAPH
+0xD377 0x8351 #CJK UNIFIED IDEOGRAPH
+0xD378 0x8325 #CJK UNIFIED IDEOGRAPH
+0xD379 0x8356 #CJK UNIFIED IDEOGRAPH
+0xD37A 0x833F #CJK UNIFIED IDEOGRAPH
+0xD37B 0x8341 #CJK UNIFIED IDEOGRAPH
+0xD37C 0x8326 #CJK UNIFIED IDEOGRAPH
+0xD37D 0x831C #CJK UNIFIED IDEOGRAPH
+0xD37E 0x8322 #CJK UNIFIED IDEOGRAPH
+0xD3A1 0x8342 #CJK UNIFIED IDEOGRAPH
+0xD3A2 0x834E #CJK UNIFIED IDEOGRAPH
+0xD3A3 0x831B #CJK UNIFIED IDEOGRAPH
+0xD3A4 0x832A #CJK UNIFIED IDEOGRAPH
+0xD3A5 0x8308 #CJK UNIFIED IDEOGRAPH
+0xD3A6 0x833C #CJK UNIFIED IDEOGRAPH
+0xD3A7 0x834D #CJK UNIFIED IDEOGRAPH
+0xD3A8 0x8316 #CJK UNIFIED IDEOGRAPH
+0xD3A9 0x8324 #CJK UNIFIED IDEOGRAPH
+0xD3AA 0x8320 #CJK UNIFIED IDEOGRAPH
+0xD3AB 0x8337 #CJK UNIFIED IDEOGRAPH
+0xD3AC 0x832F #CJK UNIFIED IDEOGRAPH
+0xD3AD 0x8329 #CJK UNIFIED IDEOGRAPH
+0xD3AE 0x8347 #CJK UNIFIED IDEOGRAPH
+0xD3AF 0x8345 #CJK UNIFIED IDEOGRAPH
+0xD3B0 0x834C #CJK UNIFIED IDEOGRAPH
+0xD3B1 0x8353 #CJK UNIFIED IDEOGRAPH
+0xD3B2 0x831E #CJK UNIFIED IDEOGRAPH
+0xD3B3 0x832C #CJK UNIFIED IDEOGRAPH
+0xD3B4 0x834B #CJK UNIFIED IDEOGRAPH
+0xD3B5 0x8327 #CJK UNIFIED IDEOGRAPH
+0xD3B6 0x8348 #CJK UNIFIED IDEOGRAPH
+0xD3B7 0x8653 #CJK UNIFIED IDEOGRAPH
+0xD3B8 0x8652 #CJK UNIFIED IDEOGRAPH
+0xD3B9 0x86A2 #CJK UNIFIED IDEOGRAPH
+0xD3BA 0x86A8 #CJK UNIFIED IDEOGRAPH
+0xD3BB 0x8696 #CJK UNIFIED IDEOGRAPH
+0xD3BC 0x868D #CJK UNIFIED IDEOGRAPH
+0xD3BD 0x8691 #CJK UNIFIED IDEOGRAPH
+0xD3BE 0x869E #CJK UNIFIED IDEOGRAPH
+0xD3BF 0x8687 #CJK UNIFIED IDEOGRAPH
+0xD3C0 0x8697 #CJK UNIFIED IDEOGRAPH
+0xD3C1 0x8686 #CJK UNIFIED IDEOGRAPH
+0xD3C2 0x868B #CJK UNIFIED IDEOGRAPH
+0xD3C3 0x869A #CJK UNIFIED IDEOGRAPH
+0xD3C4 0x8685 #CJK UNIFIED IDEOGRAPH
+0xD3C5 0x86A5 #CJK UNIFIED IDEOGRAPH
+0xD3C6 0x8699 #CJK UNIFIED IDEOGRAPH
+0xD3C7 0x86A1 #CJK UNIFIED IDEOGRAPH
+0xD3C8 0x86A7 #CJK UNIFIED IDEOGRAPH
+0xD3C9 0x8695 #CJK UNIFIED IDEOGRAPH
+0xD3CA 0x8698 #CJK UNIFIED IDEOGRAPH
+0xD3CB 0x868E #CJK UNIFIED IDEOGRAPH
+0xD3CC 0x869D #CJK UNIFIED IDEOGRAPH
+0xD3CD 0x8690 #CJK UNIFIED IDEOGRAPH
+0xD3CE 0x8694 #CJK UNIFIED IDEOGRAPH
+0xD3CF 0x8843 #CJK UNIFIED IDEOGRAPH
+0xD3D0 0x8844 #CJK UNIFIED IDEOGRAPH
+0xD3D1 0x886D #CJK UNIFIED IDEOGRAPH
+0xD3D2 0x8875 #CJK UNIFIED IDEOGRAPH
+0xD3D3 0x8876 #CJK UNIFIED IDEOGRAPH
+0xD3D4 0x8872 #CJK UNIFIED IDEOGRAPH
+0xD3D5 0x8880 #CJK UNIFIED IDEOGRAPH
+0xD3D6 0x8871 #CJK UNIFIED IDEOGRAPH
+0xD3D7 0x887F #CJK UNIFIED IDEOGRAPH
+0xD3D8 0x886F #CJK UNIFIED IDEOGRAPH
+0xD3D9 0x8883 #CJK UNIFIED IDEOGRAPH
+0xD3DA 0x887E #CJK UNIFIED IDEOGRAPH
+0xD3DB 0x8874 #CJK UNIFIED IDEOGRAPH
+0xD3DC 0x887C #CJK UNIFIED IDEOGRAPH
+0xD3DD 0x8A12 #CJK UNIFIED IDEOGRAPH
+0xD3DE 0x8C47 #CJK UNIFIED IDEOGRAPH
+0xD3DF 0x8C57 #CJK UNIFIED IDEOGRAPH
+0xD3E0 0x8C7B #CJK UNIFIED IDEOGRAPH
+0xD3E1 0x8CA4 #CJK UNIFIED IDEOGRAPH
+0xD3E2 0x8CA3 #CJK UNIFIED IDEOGRAPH
+0xD3E3 0x8D76 #CJK UNIFIED IDEOGRAPH
+0xD3E4 0x8D78 #CJK UNIFIED IDEOGRAPH
+0xD3E5 0x8DB5 #CJK UNIFIED IDEOGRAPH
+0xD3E6 0x8DB7 #CJK UNIFIED IDEOGRAPH
+0xD3E7 0x8DB6 #CJK UNIFIED IDEOGRAPH
+0xD3E8 0x8ED1 #CJK UNIFIED IDEOGRAPH
+0xD3E9 0x8ED3 #CJK UNIFIED IDEOGRAPH
+0xD3EA 0x8FFE #CJK UNIFIED IDEOGRAPH
+0xD3EB 0x8FF5 #CJK UNIFIED IDEOGRAPH
+0xD3EC 0x9002 #CJK UNIFIED IDEOGRAPH
+0xD3ED 0x8FFF #CJK UNIFIED IDEOGRAPH
+0xD3EE 0x8FFB #CJK UNIFIED IDEOGRAPH
+0xD3EF 0x9004 #CJK UNIFIED IDEOGRAPH
+0xD3F0 0x8FFC #CJK UNIFIED IDEOGRAPH
+0xD3F1 0x8FF6 #CJK UNIFIED IDEOGRAPH
+0xD3F2 0x90D6 #CJK UNIFIED IDEOGRAPH
+0xD3F3 0x90E0 #CJK UNIFIED IDEOGRAPH
+0xD3F4 0x90D9 #CJK UNIFIED IDEOGRAPH
+0xD3F5 0x90DA #CJK UNIFIED IDEOGRAPH
+0xD3F6 0x90E3 #CJK UNIFIED IDEOGRAPH
+0xD3F7 0x90DF #CJK UNIFIED IDEOGRAPH
+0xD3F8 0x90E5 #CJK UNIFIED IDEOGRAPH
+0xD3F9 0x90D8 #CJK UNIFIED IDEOGRAPH
+0xD3FA 0x90DB #CJK UNIFIED IDEOGRAPH
+0xD3FB 0x90D7 #CJK UNIFIED IDEOGRAPH
+0xD3FC 0x90DC #CJK UNIFIED IDEOGRAPH
+0xD3FD 0x90E4 #CJK UNIFIED IDEOGRAPH
+0xD3FE 0x9150 #CJK UNIFIED IDEOGRAPH
+0xD440 0x914E #CJK UNIFIED IDEOGRAPH
+0xD441 0x914F #CJK UNIFIED IDEOGRAPH
+0xD442 0x91D5 #CJK UNIFIED IDEOGRAPH
+0xD443 0x91E2 #CJK UNIFIED IDEOGRAPH
+0xD444 0x91DA #CJK UNIFIED IDEOGRAPH
+0xD445 0x965C #CJK UNIFIED IDEOGRAPH
+0xD446 0x965F #CJK UNIFIED IDEOGRAPH
+0xD447 0x96BC #CJK UNIFIED IDEOGRAPH
+0xD448 0x98E3 #CJK UNIFIED IDEOGRAPH
+0xD449 0x9ADF #CJK UNIFIED IDEOGRAPH
+0xD44A 0x9B2F #CJK UNIFIED IDEOGRAPH
+0xD44B 0x4E7F #CJK UNIFIED IDEOGRAPH
+0xD44C 0x5070 #CJK UNIFIED IDEOGRAPH
+0xD44D 0x506A #CJK UNIFIED IDEOGRAPH
+0xD44E 0x5061 #CJK UNIFIED IDEOGRAPH
+0xD44F 0x505E #CJK UNIFIED IDEOGRAPH
+0xD450 0x5060 #CJK UNIFIED IDEOGRAPH
+0xD451 0x5053 #CJK UNIFIED IDEOGRAPH
+0xD452 0x504B #CJK UNIFIED IDEOGRAPH
+0xD453 0x505D #CJK UNIFIED IDEOGRAPH
+0xD454 0x5072 #CJK UNIFIED IDEOGRAPH
+0xD455 0x5048 #CJK UNIFIED IDEOGRAPH
+0xD456 0x504D #CJK UNIFIED IDEOGRAPH
+0xD457 0x5041 #CJK UNIFIED IDEOGRAPH
+0xD458 0x505B #CJK UNIFIED IDEOGRAPH
+0xD459 0x504A #CJK UNIFIED IDEOGRAPH
+0xD45A 0x5062 #CJK UNIFIED IDEOGRAPH
+0xD45B 0x5015 #CJK UNIFIED IDEOGRAPH
+0xD45C 0x5045 #CJK UNIFIED IDEOGRAPH
+0xD45D 0x505F #CJK UNIFIED IDEOGRAPH
+0xD45E 0x5069 #CJK UNIFIED IDEOGRAPH
+0xD45F 0x506B #CJK UNIFIED IDEOGRAPH
+0xD460 0x5063 #CJK UNIFIED IDEOGRAPH
+0xD461 0x5064 #CJK UNIFIED IDEOGRAPH
+0xD462 0x5046 #CJK UNIFIED IDEOGRAPH
+0xD463 0x5040 #CJK UNIFIED IDEOGRAPH
+0xD464 0x506E #CJK UNIFIED IDEOGRAPH
+0xD465 0x5073 #CJK UNIFIED IDEOGRAPH
+0xD466 0x5057 #CJK UNIFIED IDEOGRAPH
+0xD467 0x5051 #CJK UNIFIED IDEOGRAPH
+0xD468 0x51D0 #CJK UNIFIED IDEOGRAPH
+0xD469 0x526B #CJK UNIFIED IDEOGRAPH
+0xD46A 0x526D #CJK UNIFIED IDEOGRAPH
+0xD46B 0x526C #CJK UNIFIED IDEOGRAPH
+0xD46C 0x526E #CJK UNIFIED IDEOGRAPH
+0xD46D 0x52D6 #CJK UNIFIED IDEOGRAPH
+0xD46E 0x52D3 #CJK UNIFIED IDEOGRAPH
+0xD46F 0x532D #CJK UNIFIED IDEOGRAPH
+0xD470 0x539C #CJK UNIFIED IDEOGRAPH
+0xD471 0x5575 #CJK UNIFIED IDEOGRAPH
+0xD472 0x5576 #CJK UNIFIED IDEOGRAPH
+0xD473 0x553C #CJK UNIFIED IDEOGRAPH
+0xD474 0x554D #CJK UNIFIED IDEOGRAPH
+0xD475 0x5550 #CJK UNIFIED IDEOGRAPH
+0xD476 0x5534 #CJK UNIFIED IDEOGRAPH
+0xD477 0x552A #CJK UNIFIED IDEOGRAPH
+0xD478 0x5551 #CJK UNIFIED IDEOGRAPH
+0xD479 0x5562 #CJK UNIFIED IDEOGRAPH
+0xD47A 0x5536 #CJK UNIFIED IDEOGRAPH
+0xD47B 0x5535 #CJK UNIFIED IDEOGRAPH
+0xD47C 0x5530 #CJK UNIFIED IDEOGRAPH
+0xD47D 0x5552 #CJK UNIFIED IDEOGRAPH
+0xD47E 0x5545 #CJK UNIFIED IDEOGRAPH
+0xD4A1 0x550C #CJK UNIFIED IDEOGRAPH
+0xD4A2 0x5532 #CJK UNIFIED IDEOGRAPH
+0xD4A3 0x5565 #CJK UNIFIED IDEOGRAPH
+0xD4A4 0x554E #CJK UNIFIED IDEOGRAPH
+0xD4A5 0x5539 #CJK UNIFIED IDEOGRAPH
+0xD4A6 0x5548 #CJK UNIFIED IDEOGRAPH
+0xD4A7 0x552D #CJK UNIFIED IDEOGRAPH
+0xD4A8 0x553B #CJK UNIFIED IDEOGRAPH
+0xD4A9 0x5540 #CJK UNIFIED IDEOGRAPH
+0xD4AA 0x554B #CJK UNIFIED IDEOGRAPH
+0xD4AB 0x570A #CJK UNIFIED IDEOGRAPH
+0xD4AC 0x5707 #CJK UNIFIED IDEOGRAPH
+0xD4AD 0x57FB #CJK UNIFIED IDEOGRAPH
+0xD4AE 0x5814 #CJK UNIFIED IDEOGRAPH
+0xD4AF 0x57E2 #CJK UNIFIED IDEOGRAPH
+0xD4B0 0x57F6 #CJK UNIFIED IDEOGRAPH
+0xD4B1 0x57DC #CJK UNIFIED IDEOGRAPH
+0xD4B2 0x57F4 #CJK UNIFIED IDEOGRAPH
+0xD4B3 0x5800 #CJK UNIFIED IDEOGRAPH
+0xD4B4 0x57ED #CJK UNIFIED IDEOGRAPH
+0xD4B5 0x57FD #CJK UNIFIED IDEOGRAPH
+0xD4B6 0x5808 #CJK UNIFIED IDEOGRAPH
+0xD4B7 0x57F8 #CJK UNIFIED IDEOGRAPH
+0xD4B8 0x580B #CJK UNIFIED IDEOGRAPH
+0xD4B9 0x57F3 #CJK UNIFIED IDEOGRAPH
+0xD4BA 0x57CF #CJK UNIFIED IDEOGRAPH
+0xD4BB 0x5807 #CJK UNIFIED IDEOGRAPH
+0xD4BC 0x57EE #CJK UNIFIED IDEOGRAPH
+0xD4BD 0x57E3 #CJK UNIFIED IDEOGRAPH
+0xD4BE 0x57F2 #CJK UNIFIED IDEOGRAPH
+0xD4BF 0x57E5 #CJK UNIFIED IDEOGRAPH
+0xD4C0 0x57EC #CJK UNIFIED IDEOGRAPH
+0xD4C1 0x57E1 #CJK UNIFIED IDEOGRAPH
+0xD4C2 0x580E #CJK UNIFIED IDEOGRAPH
+0xD4C3 0x57FC #CJK UNIFIED IDEOGRAPH
+0xD4C4 0x5810 #CJK UNIFIED IDEOGRAPH
+0xD4C5 0x57E7 #CJK UNIFIED IDEOGRAPH
+0xD4C6 0x5801 #CJK UNIFIED IDEOGRAPH
+0xD4C7 0x580C #CJK UNIFIED IDEOGRAPH
+0xD4C8 0x57F1 #CJK UNIFIED IDEOGRAPH
+0xD4C9 0x57E9 #CJK UNIFIED IDEOGRAPH
+0xD4CA 0x57F0 #CJK UNIFIED IDEOGRAPH
+0xD4CB 0x580D #CJK UNIFIED IDEOGRAPH
+0xD4CC 0x5804 #CJK UNIFIED IDEOGRAPH
+0xD4CD 0x595C #CJK UNIFIED IDEOGRAPH
+0xD4CE 0x5A60 #CJK UNIFIED IDEOGRAPH
+0xD4CF 0x5A58 #CJK UNIFIED IDEOGRAPH
+0xD4D0 0x5A55 #CJK UNIFIED IDEOGRAPH
+0xD4D1 0x5A67 #CJK UNIFIED IDEOGRAPH
+0xD4D2 0x5A5E #CJK UNIFIED IDEOGRAPH
+0xD4D3 0x5A38 #CJK UNIFIED IDEOGRAPH
+0xD4D4 0x5A35 #CJK UNIFIED IDEOGRAPH
+0xD4D5 0x5A6D #CJK UNIFIED IDEOGRAPH
+0xD4D6 0x5A50 #CJK UNIFIED IDEOGRAPH
+0xD4D7 0x5A5F #CJK UNIFIED IDEOGRAPH
+0xD4D8 0x5A65 #CJK UNIFIED IDEOGRAPH
+0xD4D9 0x5A6C #CJK UNIFIED IDEOGRAPH
+0xD4DA 0x5A53 #CJK UNIFIED IDEOGRAPH
+0xD4DB 0x5A64 #CJK UNIFIED IDEOGRAPH
+0xD4DC 0x5A57 #CJK UNIFIED IDEOGRAPH
+0xD4DD 0x5A43 #CJK UNIFIED IDEOGRAPH
+0xD4DE 0x5A5D #CJK UNIFIED IDEOGRAPH
+0xD4DF 0x5A52 #CJK UNIFIED IDEOGRAPH
+0xD4E0 0x5A44 #CJK UNIFIED IDEOGRAPH
+0xD4E1 0x5A5B #CJK UNIFIED IDEOGRAPH
+0xD4E2 0x5A48 #CJK UNIFIED IDEOGRAPH
+0xD4E3 0x5A8E #CJK UNIFIED IDEOGRAPH
+0xD4E4 0x5A3E #CJK UNIFIED IDEOGRAPH
+0xD4E5 0x5A4D #CJK UNIFIED IDEOGRAPH
+0xD4E6 0x5A39 #CJK UNIFIED IDEOGRAPH
+0xD4E7 0x5A4C #CJK UNIFIED IDEOGRAPH
+0xD4E8 0x5A70 #CJK UNIFIED IDEOGRAPH
+0xD4E9 0x5A69 #CJK UNIFIED IDEOGRAPH
+0xD4EA 0x5A47 #CJK UNIFIED IDEOGRAPH
+0xD4EB 0x5A51 #CJK UNIFIED IDEOGRAPH
+0xD4EC 0x5A56 #CJK UNIFIED IDEOGRAPH
+0xD4ED 0x5A42 #CJK UNIFIED IDEOGRAPH
+0xD4EE 0x5A5C #CJK UNIFIED IDEOGRAPH
+0xD4EF 0x5B72 #CJK UNIFIED IDEOGRAPH
+0xD4F0 0x5B6E #CJK UNIFIED IDEOGRAPH
+0xD4F1 0x5BC1 #CJK UNIFIED IDEOGRAPH
+0xD4F2 0x5BC0 #CJK UNIFIED IDEOGRAPH
+0xD4F3 0x5C59 #CJK UNIFIED IDEOGRAPH
+0xD4F4 0x5D1E #CJK UNIFIED IDEOGRAPH
+0xD4F5 0x5D0B #CJK UNIFIED IDEOGRAPH
+0xD4F6 0x5D1D #CJK UNIFIED IDEOGRAPH
+0xD4F7 0x5D1A #CJK UNIFIED IDEOGRAPH
+0xD4F8 0x5D20 #CJK UNIFIED IDEOGRAPH
+0xD4F9 0x5D0C #CJK UNIFIED IDEOGRAPH
+0xD4FA 0x5D28 #CJK UNIFIED IDEOGRAPH
+0xD4FB 0x5D0D #CJK UNIFIED IDEOGRAPH
+0xD4FC 0x5D26 #CJK UNIFIED IDEOGRAPH
+0xD4FD 0x5D25 #CJK UNIFIED IDEOGRAPH
+0xD4FE 0x5D0F #CJK UNIFIED IDEOGRAPH
+0xD540 0x5D30 #CJK UNIFIED IDEOGRAPH
+0xD541 0x5D12 #CJK UNIFIED IDEOGRAPH
+0xD542 0x5D23 #CJK UNIFIED IDEOGRAPH
+0xD543 0x5D1F #CJK UNIFIED IDEOGRAPH
+0xD544 0x5D2E #CJK UNIFIED IDEOGRAPH
+0xD545 0x5E3E #CJK UNIFIED IDEOGRAPH
+0xD546 0x5E34 #CJK UNIFIED IDEOGRAPH
+0xD547 0x5EB1 #CJK UNIFIED IDEOGRAPH
+0xD548 0x5EB4 #CJK UNIFIED IDEOGRAPH
+0xD549 0x5EB9 #CJK UNIFIED IDEOGRAPH
+0xD54A 0x5EB2 #CJK UNIFIED IDEOGRAPH
+0xD54B 0x5EB3 #CJK UNIFIED IDEOGRAPH
+0xD54C 0x5F36 #CJK UNIFIED IDEOGRAPH
+0xD54D 0x5F38 #CJK UNIFIED IDEOGRAPH
+0xD54E 0x5F9B #CJK UNIFIED IDEOGRAPH
+0xD54F 0x5F96 #CJK UNIFIED IDEOGRAPH
+0xD550 0x5F9F #CJK UNIFIED IDEOGRAPH
+0xD551 0x608A #CJK UNIFIED IDEOGRAPH
+0xD552 0x6090 #CJK UNIFIED IDEOGRAPH
+0xD553 0x6086 #CJK UNIFIED IDEOGRAPH
+0xD554 0x60BE #CJK UNIFIED IDEOGRAPH
+0xD555 0x60B0 #CJK UNIFIED IDEOGRAPH
+0xD556 0x60BA #CJK UNIFIED IDEOGRAPH
+0xD557 0x60D3 #CJK UNIFIED IDEOGRAPH
+0xD558 0x60D4 #CJK UNIFIED IDEOGRAPH
+0xD559 0x60CF #CJK UNIFIED IDEOGRAPH
+0xD55A 0x60E4 #CJK UNIFIED IDEOGRAPH
+0xD55B 0x60D9 #CJK UNIFIED IDEOGRAPH
+0xD55C 0x60DD #CJK UNIFIED IDEOGRAPH
+0xD55D 0x60C8 #CJK UNIFIED IDEOGRAPH
+0xD55E 0x60B1 #CJK UNIFIED IDEOGRAPH
+0xD55F 0x60DB #CJK UNIFIED IDEOGRAPH
+0xD560 0x60B7 #CJK UNIFIED IDEOGRAPH
+0xD561 0x60CA #CJK UNIFIED IDEOGRAPH
+0xD562 0x60BF #CJK UNIFIED IDEOGRAPH
+0xD563 0x60C3 #CJK UNIFIED IDEOGRAPH
+0xD564 0x60CD #CJK UNIFIED IDEOGRAPH
+0xD565 0x60C0 #CJK UNIFIED IDEOGRAPH
+0xD566 0x6332 #CJK UNIFIED IDEOGRAPH
+0xD567 0x6365 #CJK UNIFIED IDEOGRAPH
+0xD568 0x638A #CJK UNIFIED IDEOGRAPH
+0xD569 0x6382 #CJK UNIFIED IDEOGRAPH
+0xD56A 0x637D #CJK UNIFIED IDEOGRAPH
+0xD56B 0x63BD #CJK UNIFIED IDEOGRAPH
+0xD56C 0x639E #CJK UNIFIED IDEOGRAPH
+0xD56D 0x63AD #CJK UNIFIED IDEOGRAPH
+0xD56E 0x639D #CJK UNIFIED IDEOGRAPH
+0xD56F 0x6397 #CJK UNIFIED IDEOGRAPH
+0xD570 0x63AB #CJK UNIFIED IDEOGRAPH
+0xD571 0x638E #CJK UNIFIED IDEOGRAPH
+0xD572 0x636F #CJK UNIFIED IDEOGRAPH
+0xD573 0x6387 #CJK UNIFIED IDEOGRAPH
+0xD574 0x6390 #CJK UNIFIED IDEOGRAPH
+0xD575 0x636E #CJK UNIFIED IDEOGRAPH
+0xD576 0x63AF #CJK UNIFIED IDEOGRAPH
+0xD577 0x6375 #CJK UNIFIED IDEOGRAPH
+0xD578 0x639C #CJK UNIFIED IDEOGRAPH
+0xD579 0x636D #CJK UNIFIED IDEOGRAPH
+0xD57A 0x63AE #CJK UNIFIED IDEOGRAPH
+0xD57B 0x637C #CJK UNIFIED IDEOGRAPH
+0xD57C 0x63A4 #CJK UNIFIED IDEOGRAPH
+0xD57D 0x633B #CJK UNIFIED IDEOGRAPH
+0xD57E 0x639F #CJK UNIFIED IDEOGRAPH
+0xD5A1 0x6378 #CJK UNIFIED IDEOGRAPH
+0xD5A2 0x6385 #CJK UNIFIED IDEOGRAPH
+0xD5A3 0x6381 #CJK UNIFIED IDEOGRAPH
+0xD5A4 0x6391 #CJK UNIFIED IDEOGRAPH
+0xD5A5 0x638D #CJK UNIFIED IDEOGRAPH
+0xD5A6 0x6370 #CJK UNIFIED IDEOGRAPH
+0xD5A7 0x6553 #CJK UNIFIED IDEOGRAPH
+0xD5A8 0x65CD #CJK UNIFIED IDEOGRAPH
+0xD5A9 0x6665 #CJK UNIFIED IDEOGRAPH
+0xD5AA 0x6661 #CJK UNIFIED IDEOGRAPH
+0xD5AB 0x665B #CJK UNIFIED IDEOGRAPH
+0xD5AC 0x6659 #CJK UNIFIED IDEOGRAPH
+0xD5AD 0x665C #CJK UNIFIED IDEOGRAPH
+0xD5AE 0x6662 #CJK UNIFIED IDEOGRAPH
+0xD5AF 0x6718 #CJK UNIFIED IDEOGRAPH
+0xD5B0 0x6879 #CJK UNIFIED IDEOGRAPH
+0xD5B1 0x6887 #CJK UNIFIED IDEOGRAPH
+0xD5B2 0x6890 #CJK UNIFIED IDEOGRAPH
+0xD5B3 0x689C #CJK UNIFIED IDEOGRAPH
+0xD5B4 0x686D #CJK UNIFIED IDEOGRAPH
+0xD5B5 0x686E #CJK UNIFIED IDEOGRAPH
+0xD5B6 0x68AE #CJK UNIFIED IDEOGRAPH
+0xD5B7 0x68AB #CJK UNIFIED IDEOGRAPH
+0xD5B8 0x6956 #CJK UNIFIED IDEOGRAPH
+0xD5B9 0x686F #CJK UNIFIED IDEOGRAPH
+0xD5BA 0x68A3 #CJK UNIFIED IDEOGRAPH
+0xD5BB 0x68AC #CJK UNIFIED IDEOGRAPH
+0xD5BC 0x68A9 #CJK UNIFIED IDEOGRAPH
+0xD5BD 0x6875 #CJK UNIFIED IDEOGRAPH
+0xD5BE 0x6874 #CJK UNIFIED IDEOGRAPH
+0xD5BF 0x68B2 #CJK UNIFIED IDEOGRAPH
+0xD5C0 0x688F #CJK UNIFIED IDEOGRAPH
+0xD5C1 0x6877 #CJK UNIFIED IDEOGRAPH
+0xD5C2 0x6892 #CJK UNIFIED IDEOGRAPH
+0xD5C3 0x687C #CJK UNIFIED IDEOGRAPH
+0xD5C4 0x686B #CJK UNIFIED IDEOGRAPH
+0xD5C5 0x6872 #CJK UNIFIED IDEOGRAPH
+0xD5C6 0x68AA #CJK UNIFIED IDEOGRAPH
+0xD5C7 0x6880 #CJK UNIFIED IDEOGRAPH
+0xD5C8 0x6871 #CJK UNIFIED IDEOGRAPH
+0xD5C9 0x687E #CJK UNIFIED IDEOGRAPH
+0xD5CA 0x689B #CJK UNIFIED IDEOGRAPH
+0xD5CB 0x6896 #CJK UNIFIED IDEOGRAPH
+0xD5CC 0x688B #CJK UNIFIED IDEOGRAPH
+0xD5CD 0x68A0 #CJK UNIFIED IDEOGRAPH
+0xD5CE 0x6889 #CJK UNIFIED IDEOGRAPH
+0xD5CF 0x68A4 #CJK UNIFIED IDEOGRAPH
+0xD5D0 0x6878 #CJK UNIFIED IDEOGRAPH
+0xD5D1 0x687B #CJK UNIFIED IDEOGRAPH
+0xD5D2 0x6891 #CJK UNIFIED IDEOGRAPH
+0xD5D3 0x688C #CJK UNIFIED IDEOGRAPH
+0xD5D4 0x688A #CJK UNIFIED IDEOGRAPH
+0xD5D5 0x687D #CJK UNIFIED IDEOGRAPH
+0xD5D6 0x6B36 #CJK UNIFIED IDEOGRAPH
+0xD5D7 0x6B33 #CJK UNIFIED IDEOGRAPH
+0xD5D8 0x6B37 #CJK UNIFIED IDEOGRAPH
+0xD5D9 0x6B38 #CJK UNIFIED IDEOGRAPH
+0xD5DA 0x6B91 #CJK UNIFIED IDEOGRAPH
+0xD5DB 0x6B8F #CJK UNIFIED IDEOGRAPH
+0xD5DC 0x6B8D #CJK UNIFIED IDEOGRAPH
+0xD5DD 0x6B8E #CJK UNIFIED IDEOGRAPH
+0xD5DE 0x6B8C #CJK UNIFIED IDEOGRAPH
+0xD5DF 0x6C2A #CJK UNIFIED IDEOGRAPH
+0xD5E0 0x6DC0 #CJK UNIFIED IDEOGRAPH
+0xD5E1 0x6DAB #CJK UNIFIED IDEOGRAPH
+0xD5E2 0x6DB4 #CJK UNIFIED IDEOGRAPH
+0xD5E3 0x6DB3 #CJK UNIFIED IDEOGRAPH
+0xD5E4 0x6E74 #CJK UNIFIED IDEOGRAPH
+0xD5E5 0x6DAC #CJK UNIFIED IDEOGRAPH
+0xD5E6 0x6DE9 #CJK UNIFIED IDEOGRAPH
+0xD5E7 0x6DE2 #CJK UNIFIED IDEOGRAPH
+0xD5E8 0x6DB7 #CJK UNIFIED IDEOGRAPH
+0xD5E9 0x6DF6 #CJK UNIFIED IDEOGRAPH
+0xD5EA 0x6DD4 #CJK UNIFIED IDEOGRAPH
+0xD5EB 0x6E00 #CJK UNIFIED IDEOGRAPH
+0xD5EC 0x6DC8 #CJK UNIFIED IDEOGRAPH
+0xD5ED 0x6DE0 #CJK UNIFIED IDEOGRAPH
+0xD5EE 0x6DDF #CJK UNIFIED IDEOGRAPH
+0xD5EF 0x6DD6 #CJK UNIFIED IDEOGRAPH
+0xD5F0 0x6DBE #CJK UNIFIED IDEOGRAPH
+0xD5F1 0x6DE5 #CJK UNIFIED IDEOGRAPH
+0xD5F2 0x6DDC #CJK UNIFIED IDEOGRAPH
+0xD5F3 0x6DDD #CJK UNIFIED IDEOGRAPH
+0xD5F4 0x6DDB #CJK UNIFIED IDEOGRAPH
+0xD5F5 0x6DF4 #CJK UNIFIED IDEOGRAPH
+0xD5F6 0x6DCA #CJK UNIFIED IDEOGRAPH
+0xD5F7 0x6DBD #CJK UNIFIED IDEOGRAPH
+0xD5F8 0x6DED #CJK UNIFIED IDEOGRAPH
+0xD5F9 0x6DF0 #CJK UNIFIED IDEOGRAPH
+0xD5FA 0x6DBA #CJK UNIFIED IDEOGRAPH
+0xD5FB 0x6DD5 #CJK UNIFIED IDEOGRAPH
+0xD5FC 0x6DC2 #CJK UNIFIED IDEOGRAPH
+0xD5FD 0x6DCF #CJK UNIFIED IDEOGRAPH
+0xD5FE 0x6DC9 #CJK UNIFIED IDEOGRAPH
+0xD640 0x6DD0 #CJK UNIFIED IDEOGRAPH
+0xD641 0x6DF2 #CJK UNIFIED IDEOGRAPH
+0xD642 0x6DD3 #CJK UNIFIED IDEOGRAPH
+0xD643 0x6DFD #CJK UNIFIED IDEOGRAPH
+0xD644 0x6DD7 #CJK UNIFIED IDEOGRAPH
+0xD645 0x6DCD #CJK UNIFIED IDEOGRAPH
+0xD646 0x6DE3 #CJK UNIFIED IDEOGRAPH
+0xD647 0x6DBB #CJK UNIFIED IDEOGRAPH
+0xD648 0x70FA #CJK UNIFIED IDEOGRAPH
+0xD649 0x710D #CJK UNIFIED IDEOGRAPH
+0xD64A 0x70F7 #CJK UNIFIED IDEOGRAPH
+0xD64B 0x7117 #CJK UNIFIED IDEOGRAPH
+0xD64C 0x70F4 #CJK UNIFIED IDEOGRAPH
+0xD64D 0x710C #CJK UNIFIED IDEOGRAPH
+0xD64E 0x70F0 #CJK UNIFIED IDEOGRAPH
+0xD64F 0x7104 #CJK UNIFIED IDEOGRAPH
+0xD650 0x70F3 #CJK UNIFIED IDEOGRAPH
+0xD651 0x7110 #CJK UNIFIED IDEOGRAPH
+0xD652 0x70FC #CJK UNIFIED IDEOGRAPH
+0xD653 0x70FF #CJK UNIFIED IDEOGRAPH
+0xD654 0x7106 #CJK UNIFIED IDEOGRAPH
+0xD655 0x7113 #CJK UNIFIED IDEOGRAPH
+0xD656 0x7100 #CJK UNIFIED IDEOGRAPH
+0xD657 0x70F8 #CJK UNIFIED IDEOGRAPH
+0xD658 0x70F6 #CJK UNIFIED IDEOGRAPH
+0xD659 0x710B #CJK UNIFIED IDEOGRAPH
+0xD65A 0x7102 #CJK UNIFIED IDEOGRAPH
+0xD65B 0x710E #CJK UNIFIED IDEOGRAPH
+0xD65C 0x727E #CJK UNIFIED IDEOGRAPH
+0xD65D 0x727B #CJK UNIFIED IDEOGRAPH
+0xD65E 0x727C #CJK UNIFIED IDEOGRAPH
+0xD65F 0x727F #CJK UNIFIED IDEOGRAPH
+0xD660 0x731D #CJK UNIFIED IDEOGRAPH
+0xD661 0x7317 #CJK UNIFIED IDEOGRAPH
+0xD662 0x7307 #CJK UNIFIED IDEOGRAPH
+0xD663 0x7311 #CJK UNIFIED IDEOGRAPH
+0xD664 0x7318 #CJK UNIFIED IDEOGRAPH
+0xD665 0x730A #CJK UNIFIED IDEOGRAPH
+0xD666 0x7308 #CJK UNIFIED IDEOGRAPH
+0xD667 0x72FF #CJK UNIFIED IDEOGRAPH
+0xD668 0x730F #CJK UNIFIED IDEOGRAPH
+0xD669 0x731E #CJK UNIFIED IDEOGRAPH
+0xD66A 0x7388 #CJK UNIFIED IDEOGRAPH
+0xD66B 0x73F6 #CJK UNIFIED IDEOGRAPH
+0xD66C 0x73F8 #CJK UNIFIED IDEOGRAPH
+0xD66D 0x73F5 #CJK UNIFIED IDEOGRAPH
+0xD66E 0x7404 #CJK UNIFIED IDEOGRAPH
+0xD66F 0x7401 #CJK UNIFIED IDEOGRAPH
+0xD670 0x73FD #CJK UNIFIED IDEOGRAPH
+0xD671 0x7407 #CJK UNIFIED IDEOGRAPH
+0xD672 0x7400 #CJK UNIFIED IDEOGRAPH
+0xD673 0x73FA #CJK UNIFIED IDEOGRAPH
+0xD674 0x73FC #CJK UNIFIED IDEOGRAPH
+0xD675 0x73FF #CJK UNIFIED IDEOGRAPH
+0xD676 0x740C #CJK UNIFIED IDEOGRAPH
+0xD677 0x740B #CJK UNIFIED IDEOGRAPH
+0xD678 0x73F4 #CJK UNIFIED IDEOGRAPH
+0xD679 0x7408 #CJK UNIFIED IDEOGRAPH
+0xD67A 0x7564 #CJK UNIFIED IDEOGRAPH
+0xD67B 0x7563 #CJK UNIFIED IDEOGRAPH
+0xD67C 0x75CE #CJK UNIFIED IDEOGRAPH
+0xD67D 0x75D2 #CJK UNIFIED IDEOGRAPH
+0xD67E 0x75CF #CJK UNIFIED IDEOGRAPH
+0xD6A1 0x75CB #CJK UNIFIED IDEOGRAPH
+0xD6A2 0x75CC #CJK UNIFIED IDEOGRAPH
+0xD6A3 0x75D1 #CJK UNIFIED IDEOGRAPH
+0xD6A4 0x75D0 #CJK UNIFIED IDEOGRAPH
+0xD6A5 0x768F #CJK UNIFIED IDEOGRAPH
+0xD6A6 0x7689 #CJK UNIFIED IDEOGRAPH
+0xD6A7 0x76D3 #CJK UNIFIED IDEOGRAPH
+0xD6A8 0x7739 #CJK UNIFIED IDEOGRAPH
+0xD6A9 0x772F #CJK UNIFIED IDEOGRAPH
+0xD6AA 0x772D #CJK UNIFIED IDEOGRAPH
+0xD6AB 0x7731 #CJK UNIFIED IDEOGRAPH
+0xD6AC 0x7732 #CJK UNIFIED IDEOGRAPH
+0xD6AD 0x7734 #CJK UNIFIED IDEOGRAPH
+0xD6AE 0x7733 #CJK UNIFIED IDEOGRAPH
+0xD6AF 0x773D #CJK UNIFIED IDEOGRAPH
+0xD6B0 0x7725 #CJK UNIFIED IDEOGRAPH
+0xD6B1 0x773B #CJK UNIFIED IDEOGRAPH
+0xD6B2 0x7735 #CJK UNIFIED IDEOGRAPH
+0xD6B3 0x7848 #CJK UNIFIED IDEOGRAPH
+0xD6B4 0x7852 #CJK UNIFIED IDEOGRAPH
+0xD6B5 0x7849 #CJK UNIFIED IDEOGRAPH
+0xD6B6 0x784D #CJK UNIFIED IDEOGRAPH
+0xD6B7 0x784A #CJK UNIFIED IDEOGRAPH
+0xD6B8 0x784C #CJK UNIFIED IDEOGRAPH
+0xD6B9 0x7826 #CJK UNIFIED IDEOGRAPH
+0xD6BA 0x7845 #CJK UNIFIED IDEOGRAPH
+0xD6BB 0x7850 #CJK UNIFIED IDEOGRAPH
+0xD6BC 0x7964 #CJK UNIFIED IDEOGRAPH
+0xD6BD 0x7967 #CJK UNIFIED IDEOGRAPH
+0xD6BE 0x7969 #CJK UNIFIED IDEOGRAPH
+0xD6BF 0x796A #CJK UNIFIED IDEOGRAPH
+0xD6C0 0x7963 #CJK UNIFIED IDEOGRAPH
+0xD6C1 0x796B #CJK UNIFIED IDEOGRAPH
+0xD6C2 0x7961 #CJK UNIFIED IDEOGRAPH
+0xD6C3 0x79BB #CJK UNIFIED IDEOGRAPH
+0xD6C4 0x79FA #CJK UNIFIED IDEOGRAPH
+0xD6C5 0x79F8 #CJK UNIFIED IDEOGRAPH
+0xD6C6 0x79F6 #CJK UNIFIED IDEOGRAPH
+0xD6C7 0x79F7 #CJK UNIFIED IDEOGRAPH
+0xD6C8 0x7A8F #CJK UNIFIED IDEOGRAPH
+0xD6C9 0x7A94 #CJK UNIFIED IDEOGRAPH
+0xD6CA 0x7A90 #CJK UNIFIED IDEOGRAPH
+0xD6CB 0x7B35 #CJK UNIFIED IDEOGRAPH
+0xD6CC 0x7B47 #CJK UNIFIED IDEOGRAPH
+0xD6CD 0x7B34 #CJK UNIFIED IDEOGRAPH
+0xD6CE 0x7B25 #CJK UNIFIED IDEOGRAPH
+0xD6CF 0x7B30 #CJK UNIFIED IDEOGRAPH
+0xD6D0 0x7B22 #CJK UNIFIED IDEOGRAPH
+0xD6D1 0x7B24 #CJK UNIFIED IDEOGRAPH
+0xD6D2 0x7B33 #CJK UNIFIED IDEOGRAPH
+0xD6D3 0x7B18 #CJK UNIFIED IDEOGRAPH
+0xD6D4 0x7B2A #CJK UNIFIED IDEOGRAPH
+0xD6D5 0x7B1D #CJK UNIFIED IDEOGRAPH
+0xD6D6 0x7B31 #CJK UNIFIED IDEOGRAPH
+0xD6D7 0x7B2B #CJK UNIFIED IDEOGRAPH
+0xD6D8 0x7B2D #CJK UNIFIED IDEOGRAPH
+0xD6D9 0x7B2F #CJK UNIFIED IDEOGRAPH
+0xD6DA 0x7B32 #CJK UNIFIED IDEOGRAPH
+0xD6DB 0x7B38 #CJK UNIFIED IDEOGRAPH
+0xD6DC 0x7B1A #CJK UNIFIED IDEOGRAPH
+0xD6DD 0x7B23 #CJK UNIFIED IDEOGRAPH
+0xD6DE 0x7C94 #CJK UNIFIED IDEOGRAPH
+0xD6DF 0x7C98 #CJK UNIFIED IDEOGRAPH
+0xD6E0 0x7C96 #CJK UNIFIED IDEOGRAPH
+0xD6E1 0x7CA3 #CJK UNIFIED IDEOGRAPH
+0xD6E2 0x7D35 #CJK UNIFIED IDEOGRAPH
+0xD6E3 0x7D3D #CJK UNIFIED IDEOGRAPH
+0xD6E4 0x7D38 #CJK UNIFIED IDEOGRAPH
+0xD6E5 0x7D36 #CJK UNIFIED IDEOGRAPH
+0xD6E6 0x7D3A #CJK UNIFIED IDEOGRAPH
+0xD6E7 0x7D45 #CJK UNIFIED IDEOGRAPH
+0xD6E8 0x7D2C #CJK UNIFIED IDEOGRAPH
+0xD6E9 0x7D29 #CJK UNIFIED IDEOGRAPH
+0xD6EA 0x7D41 #CJK UNIFIED IDEOGRAPH
+0xD6EB 0x7D47 #CJK UNIFIED IDEOGRAPH
+0xD6EC 0x7D3E #CJK UNIFIED IDEOGRAPH
+0xD6ED 0x7D3F #CJK UNIFIED IDEOGRAPH
+0xD6EE 0x7D4A #CJK UNIFIED IDEOGRAPH
+0xD6EF 0x7D3B #CJK UNIFIED IDEOGRAPH
+0xD6F0 0x7D28 #CJK UNIFIED IDEOGRAPH
+0xD6F1 0x7F63 #CJK UNIFIED IDEOGRAPH
+0xD6F2 0x7F95 #CJK UNIFIED IDEOGRAPH
+0xD6F3 0x7F9C #CJK UNIFIED IDEOGRAPH
+0xD6F4 0x7F9D #CJK UNIFIED IDEOGRAPH
+0xD6F5 0x7F9B #CJK UNIFIED IDEOGRAPH
+0xD6F6 0x7FCA #CJK UNIFIED IDEOGRAPH
+0xD6F7 0x7FCB #CJK UNIFIED IDEOGRAPH
+0xD6F8 0x7FCD #CJK UNIFIED IDEOGRAPH
+0xD6F9 0x7FD0 #CJK UNIFIED IDEOGRAPH
+0xD6FA 0x7FD1 #CJK UNIFIED IDEOGRAPH
+0xD6FB 0x7FC7 #CJK UNIFIED IDEOGRAPH
+0xD6FC 0x7FCF #CJK UNIFIED IDEOGRAPH
+0xD6FD 0x7FC9 #CJK UNIFIED IDEOGRAPH
+0xD6FE 0x801F #CJK UNIFIED IDEOGRAPH
+0xD740 0x801E #CJK UNIFIED IDEOGRAPH
+0xD741 0x801B #CJK UNIFIED IDEOGRAPH
+0xD742 0x8047 #CJK UNIFIED IDEOGRAPH
+0xD743 0x8043 #CJK UNIFIED IDEOGRAPH
+0xD744 0x8048 #CJK UNIFIED IDEOGRAPH
+0xD745 0x8118 #CJK UNIFIED IDEOGRAPH
+0xD746 0x8125 #CJK UNIFIED IDEOGRAPH
+0xD747 0x8119 #CJK UNIFIED IDEOGRAPH
+0xD748 0x811B #CJK UNIFIED IDEOGRAPH
+0xD749 0x812D #CJK UNIFIED IDEOGRAPH
+0xD74A 0x811F #CJK UNIFIED IDEOGRAPH
+0xD74B 0x812C #CJK UNIFIED IDEOGRAPH
+0xD74C 0x811E #CJK UNIFIED IDEOGRAPH
+0xD74D 0x8121 #CJK UNIFIED IDEOGRAPH
+0xD74E 0x8115 #CJK UNIFIED IDEOGRAPH
+0xD74F 0x8127 #CJK UNIFIED IDEOGRAPH
+0xD750 0x811D #CJK UNIFIED IDEOGRAPH
+0xD751 0x8122 #CJK UNIFIED IDEOGRAPH
+0xD752 0x8211 #CJK UNIFIED IDEOGRAPH
+0xD753 0x8238 #CJK UNIFIED IDEOGRAPH
+0xD754 0x8233 #CJK UNIFIED IDEOGRAPH
+0xD755 0x823A #CJK UNIFIED IDEOGRAPH
+0xD756 0x8234 #CJK UNIFIED IDEOGRAPH
+0xD757 0x8232 #CJK UNIFIED IDEOGRAPH
+0xD758 0x8274 #CJK UNIFIED IDEOGRAPH
+0xD759 0x8390 #CJK UNIFIED IDEOGRAPH
+0xD75A 0x83A3 #CJK UNIFIED IDEOGRAPH
+0xD75B 0x83A8 #CJK UNIFIED IDEOGRAPH
+0xD75C 0x838D #CJK UNIFIED IDEOGRAPH
+0xD75D 0x837A #CJK UNIFIED IDEOGRAPH
+0xD75E 0x8373 #CJK UNIFIED IDEOGRAPH
+0xD75F 0x83A4 #CJK UNIFIED IDEOGRAPH
+0xD760 0x8374 #CJK UNIFIED IDEOGRAPH
+0xD761 0x838F #CJK UNIFIED IDEOGRAPH
+0xD762 0x8381 #CJK UNIFIED IDEOGRAPH
+0xD763 0x8395 #CJK UNIFIED IDEOGRAPH
+0xD764 0x8399 #CJK UNIFIED IDEOGRAPH
+0xD765 0x8375 #CJK UNIFIED IDEOGRAPH
+0xD766 0x8394 #CJK UNIFIED IDEOGRAPH
+0xD767 0x83A9 #CJK UNIFIED IDEOGRAPH
+0xD768 0x837D #CJK UNIFIED IDEOGRAPH
+0xD769 0x8383 #CJK UNIFIED IDEOGRAPH
+0xD76A 0x838C #CJK UNIFIED IDEOGRAPH
+0xD76B 0x839D #CJK UNIFIED IDEOGRAPH
+0xD76C 0x839B #CJK UNIFIED IDEOGRAPH
+0xD76D 0x83AA #CJK UNIFIED IDEOGRAPH
+0xD76E 0x838B #CJK UNIFIED IDEOGRAPH
+0xD76F 0x837E #CJK UNIFIED IDEOGRAPH
+0xD770 0x83A5 #CJK UNIFIED IDEOGRAPH
+0xD771 0x83AF #CJK UNIFIED IDEOGRAPH
+0xD772 0x8388 #CJK UNIFIED IDEOGRAPH
+0xD773 0x8397 #CJK UNIFIED IDEOGRAPH
+0xD774 0x83B0 #CJK UNIFIED IDEOGRAPH
+0xD775 0x837F #CJK UNIFIED IDEOGRAPH
+0xD776 0x83A6 #CJK UNIFIED IDEOGRAPH
+0xD777 0x8387 #CJK UNIFIED IDEOGRAPH
+0xD778 0x83AE #CJK UNIFIED IDEOGRAPH
+0xD779 0x8376 #CJK UNIFIED IDEOGRAPH
+0xD77A 0x839A #CJK UNIFIED IDEOGRAPH
+0xD77B 0x8659 #CJK UNIFIED IDEOGRAPH
+0xD77C 0x8656 #CJK UNIFIED IDEOGRAPH
+0xD77D 0x86BF #CJK UNIFIED IDEOGRAPH
+0xD77E 0x86B7 #CJK UNIFIED IDEOGRAPH
+0xD7A1 0x86C2 #CJK UNIFIED IDEOGRAPH
+0xD7A2 0x86C1 #CJK UNIFIED IDEOGRAPH
+0xD7A3 0x86C5 #CJK UNIFIED IDEOGRAPH
+0xD7A4 0x86BA #CJK UNIFIED IDEOGRAPH
+0xD7A5 0x86B0 #CJK UNIFIED IDEOGRAPH
+0xD7A6 0x86C8 #CJK UNIFIED IDEOGRAPH
+0xD7A7 0x86B9 #CJK UNIFIED IDEOGRAPH
+0xD7A8 0x86B3 #CJK UNIFIED IDEOGRAPH
+0xD7A9 0x86B8 #CJK UNIFIED IDEOGRAPH
+0xD7AA 0x86CC #CJK UNIFIED IDEOGRAPH
+0xD7AB 0x86B4 #CJK UNIFIED IDEOGRAPH
+0xD7AC 0x86BB #CJK UNIFIED IDEOGRAPH
+0xD7AD 0x86BC #CJK UNIFIED IDEOGRAPH
+0xD7AE 0x86C3 #CJK UNIFIED IDEOGRAPH
+0xD7AF 0x86BD #CJK UNIFIED IDEOGRAPH
+0xD7B0 0x86BE #CJK UNIFIED IDEOGRAPH
+0xD7B1 0x8852 #CJK UNIFIED IDEOGRAPH
+0xD7B2 0x8889 #CJK UNIFIED IDEOGRAPH
+0xD7B3 0x8895 #CJK UNIFIED IDEOGRAPH
+0xD7B4 0x88A8 #CJK UNIFIED IDEOGRAPH
+0xD7B5 0x88A2 #CJK UNIFIED IDEOGRAPH
+0xD7B6 0x88AA #CJK UNIFIED IDEOGRAPH
+0xD7B7 0x889A #CJK UNIFIED IDEOGRAPH
+0xD7B8 0x8891 #CJK UNIFIED IDEOGRAPH
+0xD7B9 0x88A1 #CJK UNIFIED IDEOGRAPH
+0xD7BA 0x889F #CJK UNIFIED IDEOGRAPH
+0xD7BB 0x8898 #CJK UNIFIED IDEOGRAPH
+0xD7BC 0x88A7 #CJK UNIFIED IDEOGRAPH
+0xD7BD 0x8899 #CJK UNIFIED IDEOGRAPH
+0xD7BE 0x889B #CJK UNIFIED IDEOGRAPH
+0xD7BF 0x8897 #CJK UNIFIED IDEOGRAPH
+0xD7C0 0x88A4 #CJK UNIFIED IDEOGRAPH
+0xD7C1 0x88AC #CJK UNIFIED IDEOGRAPH
+0xD7C2 0x888C #CJK UNIFIED IDEOGRAPH
+0xD7C3 0x8893 #CJK UNIFIED IDEOGRAPH
+0xD7C4 0x888E #CJK UNIFIED IDEOGRAPH
+0xD7C5 0x8982 #CJK UNIFIED IDEOGRAPH
+0xD7C6 0x89D6 #CJK UNIFIED IDEOGRAPH
+0xD7C7 0x89D9 #CJK UNIFIED IDEOGRAPH
+0xD7C8 0x89D5 #CJK UNIFIED IDEOGRAPH
+0xD7C9 0x8A30 #CJK UNIFIED IDEOGRAPH
+0xD7CA 0x8A27 #CJK UNIFIED IDEOGRAPH
+0xD7CB 0x8A2C #CJK UNIFIED IDEOGRAPH
+0xD7CC 0x8A1E #CJK UNIFIED IDEOGRAPH
+0xD7CD 0x8C39 #CJK UNIFIED IDEOGRAPH
+0xD7CE 0x8C3B #CJK UNIFIED IDEOGRAPH
+0xD7CF 0x8C5C #CJK UNIFIED IDEOGRAPH
+0xD7D0 0x8C5D #CJK UNIFIED IDEOGRAPH
+0xD7D1 0x8C7D #CJK UNIFIED IDEOGRAPH
+0xD7D2 0x8CA5 #CJK UNIFIED IDEOGRAPH
+0xD7D3 0x8D7D #CJK UNIFIED IDEOGRAPH
+0xD7D4 0x8D7B #CJK UNIFIED IDEOGRAPH
+0xD7D5 0x8D79 #CJK UNIFIED IDEOGRAPH
+0xD7D6 0x8DBC #CJK UNIFIED IDEOGRAPH
+0xD7D7 0x8DC2 #CJK UNIFIED IDEOGRAPH
+0xD7D8 0x8DB9 #CJK UNIFIED IDEOGRAPH
+0xD7D9 0x8DBF #CJK UNIFIED IDEOGRAPH
+0xD7DA 0x8DC1 #CJK UNIFIED IDEOGRAPH
+0xD7DB 0x8ED8 #CJK UNIFIED IDEOGRAPH
+0xD7DC 0x8EDE #CJK UNIFIED IDEOGRAPH
+0xD7DD 0x8EDD #CJK UNIFIED IDEOGRAPH
+0xD7DE 0x8EDC #CJK UNIFIED IDEOGRAPH
+0xD7DF 0x8ED7 #CJK UNIFIED IDEOGRAPH
+0xD7E0 0x8EE0 #CJK UNIFIED IDEOGRAPH
+0xD7E1 0x8EE1 #CJK UNIFIED IDEOGRAPH
+0xD7E2 0x9024 #CJK UNIFIED IDEOGRAPH
+0xD7E3 0x900B #CJK UNIFIED IDEOGRAPH
+0xD7E4 0x9011 #CJK UNIFIED IDEOGRAPH
+0xD7E5 0x901C #CJK UNIFIED IDEOGRAPH
+0xD7E6 0x900C #CJK UNIFIED IDEOGRAPH
+0xD7E7 0x9021 #CJK UNIFIED IDEOGRAPH
+0xD7E8 0x90EF #CJK UNIFIED IDEOGRAPH
+0xD7E9 0x90EA #CJK UNIFIED IDEOGRAPH
+0xD7EA 0x90F0 #CJK UNIFIED IDEOGRAPH
+0xD7EB 0x90F4 #CJK UNIFIED IDEOGRAPH
+0xD7EC 0x90F2 #CJK UNIFIED IDEOGRAPH
+0xD7ED 0x90F3 #CJK UNIFIED IDEOGRAPH
+0xD7EE 0x90D4 #CJK UNIFIED IDEOGRAPH
+0xD7EF 0x90EB #CJK UNIFIED IDEOGRAPH
+0xD7F0 0x90EC #CJK UNIFIED IDEOGRAPH
+0xD7F1 0x90E9 #CJK UNIFIED IDEOGRAPH
+0xD7F2 0x9156 #CJK UNIFIED IDEOGRAPH
+0xD7F3 0x9158 #CJK UNIFIED IDEOGRAPH
+0xD7F4 0x915A #CJK UNIFIED IDEOGRAPH
+0xD7F5 0x9153 #CJK UNIFIED IDEOGRAPH
+0xD7F6 0x9155 #CJK UNIFIED IDEOGRAPH
+0xD7F7 0x91EC #CJK UNIFIED IDEOGRAPH
+0xD7F8 0x91F4 #CJK UNIFIED IDEOGRAPH
+0xD7F9 0x91F1 #CJK UNIFIED IDEOGRAPH
+0xD7FA 0x91F3 #CJK UNIFIED IDEOGRAPH
+0xD7FB 0x91F8 #CJK UNIFIED IDEOGRAPH
+0xD7FC 0x91E4 #CJK UNIFIED IDEOGRAPH
+0xD7FD 0x91F9 #CJK UNIFIED IDEOGRAPH
+0xD7FE 0x91EA #CJK UNIFIED IDEOGRAPH
+0xD840 0x91EB #CJK UNIFIED IDEOGRAPH
+0xD841 0x91F7 #CJK UNIFIED IDEOGRAPH
+0xD842 0x91E8 #CJK UNIFIED IDEOGRAPH
+0xD843 0x91EE #CJK UNIFIED IDEOGRAPH
+0xD844 0x957A #CJK UNIFIED IDEOGRAPH
+0xD845 0x9586 #CJK UNIFIED IDEOGRAPH
+0xD846 0x9588 #CJK UNIFIED IDEOGRAPH
+0xD847 0x967C #CJK UNIFIED IDEOGRAPH
+0xD848 0x966D #CJK UNIFIED IDEOGRAPH
+0xD849 0x966B #CJK UNIFIED IDEOGRAPH
+0xD84A 0x9671 #CJK UNIFIED IDEOGRAPH
+0xD84B 0x966F #CJK UNIFIED IDEOGRAPH
+0xD84C 0x96BF #CJK UNIFIED IDEOGRAPH
+0xD84D 0x976A #CJK UNIFIED IDEOGRAPH
+0xD84E 0x9804 #CJK UNIFIED IDEOGRAPH
+0xD84F 0x98E5 #CJK UNIFIED IDEOGRAPH
+0xD850 0x9997 #CJK UNIFIED IDEOGRAPH
+0xD851 0x509B #CJK UNIFIED IDEOGRAPH
+0xD852 0x5095 #CJK UNIFIED IDEOGRAPH
+0xD853 0x5094 #CJK UNIFIED IDEOGRAPH
+0xD854 0x509E #CJK UNIFIED IDEOGRAPH
+0xD855 0x508B #CJK UNIFIED IDEOGRAPH
+0xD856 0x50A3 #CJK UNIFIED IDEOGRAPH
+0xD857 0x5083 #CJK UNIFIED IDEOGRAPH
+0xD858 0x508C #CJK UNIFIED IDEOGRAPH
+0xD859 0x508E #CJK UNIFIED IDEOGRAPH
+0xD85A 0x509D #CJK UNIFIED IDEOGRAPH
+0xD85B 0x5068 #CJK UNIFIED IDEOGRAPH
+0xD85C 0x509C #CJK UNIFIED IDEOGRAPH
+0xD85D 0x5092 #CJK UNIFIED IDEOGRAPH
+0xD85E 0x5082 #CJK UNIFIED IDEOGRAPH
+0xD85F 0x5087 #CJK UNIFIED IDEOGRAPH
+0xD860 0x515F #CJK UNIFIED IDEOGRAPH
+0xD861 0x51D4 #CJK UNIFIED IDEOGRAPH
+0xD862 0x5312 #CJK UNIFIED IDEOGRAPH
+0xD863 0x5311 #CJK UNIFIED IDEOGRAPH
+0xD864 0x53A4 #CJK UNIFIED IDEOGRAPH
+0xD865 0x53A7 #CJK UNIFIED IDEOGRAPH
+0xD866 0x5591 #CJK UNIFIED IDEOGRAPH
+0xD867 0x55A8 #CJK UNIFIED IDEOGRAPH
+0xD868 0x55A5 #CJK UNIFIED IDEOGRAPH
+0xD869 0x55AD #CJK UNIFIED IDEOGRAPH
+0xD86A 0x5577 #CJK UNIFIED IDEOGRAPH
+0xD86B 0x5645 #CJK UNIFIED IDEOGRAPH
+0xD86C 0x55A2 #CJK UNIFIED IDEOGRAPH
+0xD86D 0x5593 #CJK UNIFIED IDEOGRAPH
+0xD86E 0x5588 #CJK UNIFIED IDEOGRAPH
+0xD86F 0x558F #CJK UNIFIED IDEOGRAPH
+0xD870 0x55B5 #CJK UNIFIED IDEOGRAPH
+0xD871 0x5581 #CJK UNIFIED IDEOGRAPH
+0xD872 0x55A3 #CJK UNIFIED IDEOGRAPH
+0xD873 0x5592 #CJK UNIFIED IDEOGRAPH
+0xD874 0x55A4 #CJK UNIFIED IDEOGRAPH
+0xD875 0x557D #CJK UNIFIED IDEOGRAPH
+0xD876 0x558C #CJK UNIFIED IDEOGRAPH
+0xD877 0x55A6 #CJK UNIFIED IDEOGRAPH
+0xD878 0x557F #CJK UNIFIED IDEOGRAPH
+0xD879 0x5595 #CJK UNIFIED IDEOGRAPH
+0xD87A 0x55A1 #CJK UNIFIED IDEOGRAPH
+0xD87B 0x558E #CJK UNIFIED IDEOGRAPH
+0xD87C 0x570C #CJK UNIFIED IDEOGRAPH
+0xD87D 0x5829 #CJK UNIFIED IDEOGRAPH
+0xD87E 0x5837 #CJK UNIFIED IDEOGRAPH
+0xD8A1 0x5819 #CJK UNIFIED IDEOGRAPH
+0xD8A2 0x581E #CJK UNIFIED IDEOGRAPH
+0xD8A3 0x5827 #CJK UNIFIED IDEOGRAPH
+0xD8A4 0x5823 #CJK UNIFIED IDEOGRAPH
+0xD8A5 0x5828 #CJK UNIFIED IDEOGRAPH
+0xD8A6 0x57F5 #CJK UNIFIED IDEOGRAPH
+0xD8A7 0x5848 #CJK UNIFIED IDEOGRAPH
+0xD8A8 0x5825 #CJK UNIFIED IDEOGRAPH
+0xD8A9 0x581C #CJK UNIFIED IDEOGRAPH
+0xD8AA 0x581B #CJK UNIFIED IDEOGRAPH
+0xD8AB 0x5833 #CJK UNIFIED IDEOGRAPH
+0xD8AC 0x583F #CJK UNIFIED IDEOGRAPH
+0xD8AD 0x5836 #CJK UNIFIED IDEOGRAPH
+0xD8AE 0x582E #CJK UNIFIED IDEOGRAPH
+0xD8AF 0x5839 #CJK UNIFIED IDEOGRAPH
+0xD8B0 0x5838 #CJK UNIFIED IDEOGRAPH
+0xD8B1 0x582D #CJK UNIFIED IDEOGRAPH
+0xD8B2 0x582C #CJK UNIFIED IDEOGRAPH
+0xD8B3 0x583B #CJK UNIFIED IDEOGRAPH
+0xD8B4 0x5961 #CJK UNIFIED IDEOGRAPH
+0xD8B5 0x5AAF #CJK UNIFIED IDEOGRAPH
+0xD8B6 0x5A94 #CJK UNIFIED IDEOGRAPH
+0xD8B7 0x5A9F #CJK UNIFIED IDEOGRAPH
+0xD8B8 0x5A7A #CJK UNIFIED IDEOGRAPH
+0xD8B9 0x5AA2 #CJK UNIFIED IDEOGRAPH
+0xD8BA 0x5A9E #CJK UNIFIED IDEOGRAPH
+0xD8BB 0x5A78 #CJK UNIFIED IDEOGRAPH
+0xD8BC 0x5AA6 #CJK UNIFIED IDEOGRAPH
+0xD8BD 0x5A7C #CJK UNIFIED IDEOGRAPH
+0xD8BE 0x5AA5 #CJK UNIFIED IDEOGRAPH
+0xD8BF 0x5AAC #CJK UNIFIED IDEOGRAPH
+0xD8C0 0x5A95 #CJK UNIFIED IDEOGRAPH
+0xD8C1 0x5AAE #CJK UNIFIED IDEOGRAPH
+0xD8C2 0x5A37 #CJK UNIFIED IDEOGRAPH
+0xD8C3 0x5A84 #CJK UNIFIED IDEOGRAPH
+0xD8C4 0x5A8A #CJK UNIFIED IDEOGRAPH
+0xD8C5 0x5A97 #CJK UNIFIED IDEOGRAPH
+0xD8C6 0x5A83 #CJK UNIFIED IDEOGRAPH
+0xD8C7 0x5A8B #CJK UNIFIED IDEOGRAPH
+0xD8C8 0x5AA9 #CJK UNIFIED IDEOGRAPH
+0xD8C9 0x5A7B #CJK UNIFIED IDEOGRAPH
+0xD8CA 0x5A7D #CJK UNIFIED IDEOGRAPH
+0xD8CB 0x5A8C #CJK UNIFIED IDEOGRAPH
+0xD8CC 0x5A9C #CJK UNIFIED IDEOGRAPH
+0xD8CD 0x5A8F #CJK UNIFIED IDEOGRAPH
+0xD8CE 0x5A93 #CJK UNIFIED IDEOGRAPH
+0xD8CF 0x5A9D #CJK UNIFIED IDEOGRAPH
+0xD8D0 0x5BEA #CJK UNIFIED IDEOGRAPH
+0xD8D1 0x5BCD #CJK UNIFIED IDEOGRAPH
+0xD8D2 0x5BCB #CJK UNIFIED IDEOGRAPH
+0xD8D3 0x5BD4 #CJK UNIFIED IDEOGRAPH
+0xD8D4 0x5BD1 #CJK UNIFIED IDEOGRAPH
+0xD8D5 0x5BCA #CJK UNIFIED IDEOGRAPH
+0xD8D6 0x5BCE #CJK UNIFIED IDEOGRAPH
+0xD8D7 0x5C0C #CJK UNIFIED IDEOGRAPH
+0xD8D8 0x5C30 #CJK UNIFIED IDEOGRAPH
+0xD8D9 0x5D37 #CJK UNIFIED IDEOGRAPH
+0xD8DA 0x5D43 #CJK UNIFIED IDEOGRAPH
+0xD8DB 0x5D6B #CJK UNIFIED IDEOGRAPH
+0xD8DC 0x5D41 #CJK UNIFIED IDEOGRAPH
+0xD8DD 0x5D4B #CJK UNIFIED IDEOGRAPH
+0xD8DE 0x5D3F #CJK UNIFIED IDEOGRAPH
+0xD8DF 0x5D35 #CJK UNIFIED IDEOGRAPH
+0xD8E0 0x5D51 #CJK UNIFIED IDEOGRAPH
+0xD8E1 0x5D4E #CJK UNIFIED IDEOGRAPH
+0xD8E2 0x5D55 #CJK UNIFIED IDEOGRAPH
+0xD8E3 0x5D33 #CJK UNIFIED IDEOGRAPH
+0xD8E4 0x5D3A #CJK UNIFIED IDEOGRAPH
+0xD8E5 0x5D52 #CJK UNIFIED IDEOGRAPH
+0xD8E6 0x5D3D #CJK UNIFIED IDEOGRAPH
+0xD8E7 0x5D31 #CJK UNIFIED IDEOGRAPH
+0xD8E8 0x5D59 #CJK UNIFIED IDEOGRAPH
+0xD8E9 0x5D42 #CJK UNIFIED IDEOGRAPH
+0xD8EA 0x5D39 #CJK UNIFIED IDEOGRAPH
+0xD8EB 0x5D49 #CJK UNIFIED IDEOGRAPH
+0xD8EC 0x5D38 #CJK UNIFIED IDEOGRAPH
+0xD8ED 0x5D3C #CJK UNIFIED IDEOGRAPH
+0xD8EE 0x5D32 #CJK UNIFIED IDEOGRAPH
+0xD8EF 0x5D36 #CJK UNIFIED IDEOGRAPH
+0xD8F0 0x5D40 #CJK UNIFIED IDEOGRAPH
+0xD8F1 0x5D45 #CJK UNIFIED IDEOGRAPH
+0xD8F2 0x5E44 #CJK UNIFIED IDEOGRAPH
+0xD8F3 0x5E41 #CJK UNIFIED IDEOGRAPH
+0xD8F4 0x5F58 #CJK UNIFIED IDEOGRAPH
+0xD8F5 0x5FA6 #CJK UNIFIED IDEOGRAPH
+0xD8F6 0x5FA5 #CJK UNIFIED IDEOGRAPH
+0xD8F7 0x5FAB #CJK UNIFIED IDEOGRAPH
+0xD8F8 0x60C9 #CJK UNIFIED IDEOGRAPH
+0xD8F9 0x60B9 #CJK UNIFIED IDEOGRAPH
+0xD8FA 0x60CC #CJK UNIFIED IDEOGRAPH
+0xD8FB 0x60E2 #CJK UNIFIED IDEOGRAPH
+0xD8FC 0x60CE #CJK UNIFIED IDEOGRAPH
+0xD8FD 0x60C4 #CJK UNIFIED IDEOGRAPH
+0xD8FE 0x6114 #CJK UNIFIED IDEOGRAPH
+0xD940 0x60F2 #CJK UNIFIED IDEOGRAPH
+0xD941 0x610A #CJK UNIFIED IDEOGRAPH
+0xD942 0x6116 #CJK UNIFIED IDEOGRAPH
+0xD943 0x6105 #CJK UNIFIED IDEOGRAPH
+0xD944 0x60F5 #CJK UNIFIED IDEOGRAPH
+0xD945 0x6113 #CJK UNIFIED IDEOGRAPH
+0xD946 0x60F8 #CJK UNIFIED IDEOGRAPH
+0xD947 0x60FC #CJK UNIFIED IDEOGRAPH
+0xD948 0x60FE #CJK UNIFIED IDEOGRAPH
+0xD949 0x60C1 #CJK UNIFIED IDEOGRAPH
+0xD94A 0x6103 #CJK UNIFIED IDEOGRAPH
+0xD94B 0x6118 #CJK UNIFIED IDEOGRAPH
+0xD94C 0x611D #CJK UNIFIED IDEOGRAPH
+0xD94D 0x6110 #CJK UNIFIED IDEOGRAPH
+0xD94E 0x60FF #CJK UNIFIED IDEOGRAPH
+0xD94F 0x6104 #CJK UNIFIED IDEOGRAPH
+0xD950 0x610B #CJK UNIFIED IDEOGRAPH
+0xD951 0x624A #CJK UNIFIED IDEOGRAPH
+0xD952 0x6394 #CJK UNIFIED IDEOGRAPH
+0xD953 0x63B1 #CJK UNIFIED IDEOGRAPH
+0xD954 0x63B0 #CJK UNIFIED IDEOGRAPH
+0xD955 0x63CE #CJK UNIFIED IDEOGRAPH
+0xD956 0x63E5 #CJK UNIFIED IDEOGRAPH
+0xD957 0x63E8 #CJK UNIFIED IDEOGRAPH
+0xD958 0x63EF #CJK UNIFIED IDEOGRAPH
+0xD959 0x63C3 #CJK UNIFIED IDEOGRAPH
+0xD95A 0x649D #CJK UNIFIED IDEOGRAPH
+0xD95B 0x63F3 #CJK UNIFIED IDEOGRAPH
+0xD95C 0x63CA #CJK UNIFIED IDEOGRAPH
+0xD95D 0x63E0 #CJK UNIFIED IDEOGRAPH
+0xD95E 0x63F6 #CJK UNIFIED IDEOGRAPH
+0xD95F 0x63D5 #CJK UNIFIED IDEOGRAPH
+0xD960 0x63F2 #CJK UNIFIED IDEOGRAPH
+0xD961 0x63F5 #CJK UNIFIED IDEOGRAPH
+0xD962 0x6461 #CJK UNIFIED IDEOGRAPH
+0xD963 0x63DF #CJK UNIFIED IDEOGRAPH
+0xD964 0x63BE #CJK UNIFIED IDEOGRAPH
+0xD965 0x63DD #CJK UNIFIED IDEOGRAPH
+0xD966 0x63DC #CJK UNIFIED IDEOGRAPH
+0xD967 0x63C4 #CJK UNIFIED IDEOGRAPH
+0xD968 0x63D8 #CJK UNIFIED IDEOGRAPH
+0xD969 0x63D3 #CJK UNIFIED IDEOGRAPH
+0xD96A 0x63C2 #CJK UNIFIED IDEOGRAPH
+0xD96B 0x63C7 #CJK UNIFIED IDEOGRAPH
+0xD96C 0x63CC #CJK UNIFIED IDEOGRAPH
+0xD96D 0x63CB #CJK UNIFIED IDEOGRAPH
+0xD96E 0x63C8 #CJK UNIFIED IDEOGRAPH
+0xD96F 0x63F0 #CJK UNIFIED IDEOGRAPH
+0xD970 0x63D7 #CJK UNIFIED IDEOGRAPH
+0xD971 0x63D9 #CJK UNIFIED IDEOGRAPH
+0xD972 0x6532 #CJK UNIFIED IDEOGRAPH
+0xD973 0x6567 #CJK UNIFIED IDEOGRAPH
+0xD974 0x656A #CJK UNIFIED IDEOGRAPH
+0xD975 0x6564 #CJK UNIFIED IDEOGRAPH
+0xD976 0x655C #CJK UNIFIED IDEOGRAPH
+0xD977 0x6568 #CJK UNIFIED IDEOGRAPH
+0xD978 0x6565 #CJK UNIFIED IDEOGRAPH
+0xD979 0x658C #CJK UNIFIED IDEOGRAPH
+0xD97A 0x659D #CJK UNIFIED IDEOGRAPH
+0xD97B 0x659E #CJK UNIFIED IDEOGRAPH
+0xD97C 0x65AE #CJK UNIFIED IDEOGRAPH
+0xD97D 0x65D0 #CJK UNIFIED IDEOGRAPH
+0xD97E 0x65D2 #CJK UNIFIED IDEOGRAPH
+0xD9A1 0x667C #CJK UNIFIED IDEOGRAPH
+0xD9A2 0x666C #CJK UNIFIED IDEOGRAPH
+0xD9A3 0x667B #CJK UNIFIED IDEOGRAPH
+0xD9A4 0x6680 #CJK UNIFIED IDEOGRAPH
+0xD9A5 0x6671 #CJK UNIFIED IDEOGRAPH
+0xD9A6 0x6679 #CJK UNIFIED IDEOGRAPH
+0xD9A7 0x666A #CJK UNIFIED IDEOGRAPH
+0xD9A8 0x6672 #CJK UNIFIED IDEOGRAPH
+0xD9A9 0x6701 #CJK UNIFIED IDEOGRAPH
+0xD9AA 0x690C #CJK UNIFIED IDEOGRAPH
+0xD9AB 0x68D3 #CJK UNIFIED IDEOGRAPH
+0xD9AC 0x6904 #CJK UNIFIED IDEOGRAPH
+0xD9AD 0x68DC #CJK UNIFIED IDEOGRAPH
+0xD9AE 0x692A #CJK UNIFIED IDEOGRAPH
+0xD9AF 0x68EC #CJK UNIFIED IDEOGRAPH
+0xD9B0 0x68EA #CJK UNIFIED IDEOGRAPH
+0xD9B1 0x68F1 #CJK UNIFIED IDEOGRAPH
+0xD9B2 0x690F #CJK UNIFIED IDEOGRAPH
+0xD9B3 0x68D6 #CJK UNIFIED IDEOGRAPH
+0xD9B4 0x68F7 #CJK UNIFIED IDEOGRAPH
+0xD9B5 0x68EB #CJK UNIFIED IDEOGRAPH
+0xD9B6 0x68E4 #CJK UNIFIED IDEOGRAPH
+0xD9B7 0x68F6 #CJK UNIFIED IDEOGRAPH
+0xD9B8 0x6913 #CJK UNIFIED IDEOGRAPH
+0xD9B9 0x6910 #CJK UNIFIED IDEOGRAPH
+0xD9BA 0x68F3 #CJK UNIFIED IDEOGRAPH
+0xD9BB 0x68E1 #CJK UNIFIED IDEOGRAPH
+0xD9BC 0x6907 #CJK UNIFIED IDEOGRAPH
+0xD9BD 0x68CC #CJK UNIFIED IDEOGRAPH
+0xD9BE 0x6908 #CJK UNIFIED IDEOGRAPH
+0xD9BF 0x6970 #CJK UNIFIED IDEOGRAPH
+0xD9C0 0x68B4 #CJK UNIFIED IDEOGRAPH
+0xD9C1 0x6911 #CJK UNIFIED IDEOGRAPH
+0xD9C2 0x68EF #CJK UNIFIED IDEOGRAPH
+0xD9C3 0x68C6 #CJK UNIFIED IDEOGRAPH
+0xD9C4 0x6914 #CJK UNIFIED IDEOGRAPH
+0xD9C5 0x68F8 #CJK UNIFIED IDEOGRAPH
+0xD9C6 0x68D0 #CJK UNIFIED IDEOGRAPH
+0xD9C7 0x68FD #CJK UNIFIED IDEOGRAPH
+0xD9C8 0x68FC #CJK UNIFIED IDEOGRAPH
+0xD9C9 0x68E8 #CJK UNIFIED IDEOGRAPH
+0xD9CA 0x690B #CJK UNIFIED IDEOGRAPH
+0xD9CB 0x690A #CJK UNIFIED IDEOGRAPH
+0xD9CC 0x6917 #CJK UNIFIED IDEOGRAPH
+0xD9CD 0x68CE #CJK UNIFIED IDEOGRAPH
+0xD9CE 0x68C8 #CJK UNIFIED IDEOGRAPH
+0xD9CF 0x68DD #CJK UNIFIED IDEOGRAPH
+0xD9D0 0x68DE #CJK UNIFIED IDEOGRAPH
+0xD9D1 0x68E6 #CJK UNIFIED IDEOGRAPH
+0xD9D2 0x68F4 #CJK UNIFIED IDEOGRAPH
+0xD9D3 0x68D1 #CJK UNIFIED IDEOGRAPH
+0xD9D4 0x6906 #CJK UNIFIED IDEOGRAPH
+0xD9D5 0x68D4 #CJK UNIFIED IDEOGRAPH
+0xD9D6 0x68E9 #CJK UNIFIED IDEOGRAPH
+0xD9D7 0x6915 #CJK UNIFIED IDEOGRAPH
+0xD9D8 0x6925 #CJK UNIFIED IDEOGRAPH
+0xD9D9 0x68C7 #CJK UNIFIED IDEOGRAPH
+0xD9DA 0x6B39 #CJK UNIFIED IDEOGRAPH
+0xD9DB 0x6B3B #CJK UNIFIED IDEOGRAPH
+0xD9DC 0x6B3F #CJK UNIFIED IDEOGRAPH
+0xD9DD 0x6B3C #CJK UNIFIED IDEOGRAPH
+0xD9DE 0x6B94 #CJK UNIFIED IDEOGRAPH
+0xD9DF 0x6B97 #CJK UNIFIED IDEOGRAPH
+0xD9E0 0x6B99 #CJK UNIFIED IDEOGRAPH
+0xD9E1 0x6B95 #CJK UNIFIED IDEOGRAPH
+0xD9E2 0x6BBD #CJK UNIFIED IDEOGRAPH
+0xD9E3 0x6BF0 #CJK UNIFIED IDEOGRAPH
+0xD9E4 0x6BF2 #CJK UNIFIED IDEOGRAPH
+0xD9E5 0x6BF3 #CJK UNIFIED IDEOGRAPH
+0xD9E6 0x6C30 #CJK UNIFIED IDEOGRAPH
+0xD9E7 0x6DFC #CJK UNIFIED IDEOGRAPH
+0xD9E8 0x6E46 #CJK UNIFIED IDEOGRAPH
+0xD9E9 0x6E47 #CJK UNIFIED IDEOGRAPH
+0xD9EA 0x6E1F #CJK UNIFIED IDEOGRAPH
+0xD9EB 0x6E49 #CJK UNIFIED IDEOGRAPH
+0xD9EC 0x6E88 #CJK UNIFIED IDEOGRAPH
+0xD9ED 0x6E3C #CJK UNIFIED IDEOGRAPH
+0xD9EE 0x6E3D #CJK UNIFIED IDEOGRAPH
+0xD9EF 0x6E45 #CJK UNIFIED IDEOGRAPH
+0xD9F0 0x6E62 #CJK UNIFIED IDEOGRAPH
+0xD9F1 0x6E2B #CJK UNIFIED IDEOGRAPH
+0xD9F2 0x6E3F #CJK UNIFIED IDEOGRAPH
+0xD9F3 0x6E41 #CJK UNIFIED IDEOGRAPH
+0xD9F4 0x6E5D #CJK UNIFIED IDEOGRAPH
+0xD9F5 0x6E73 #CJK UNIFIED IDEOGRAPH
+0xD9F6 0x6E1C #CJK UNIFIED IDEOGRAPH
+0xD9F7 0x6E33 #CJK UNIFIED IDEOGRAPH
+0xD9F8 0x6E4B #CJK UNIFIED IDEOGRAPH
+0xD9F9 0x6E40 #CJK UNIFIED IDEOGRAPH
+0xD9FA 0x6E51 #CJK UNIFIED IDEOGRAPH
+0xD9FB 0x6E3B #CJK UNIFIED IDEOGRAPH
+0xD9FC 0x6E03 #CJK UNIFIED IDEOGRAPH
+0xD9FD 0x6E2E #CJK UNIFIED IDEOGRAPH
+0xD9FE 0x6E5E #CJK UNIFIED IDEOGRAPH
+0xDA40 0x6E68 #CJK UNIFIED IDEOGRAPH
+0xDA41 0x6E5C #CJK UNIFIED IDEOGRAPH
+0xDA42 0x6E61 #CJK UNIFIED IDEOGRAPH
+0xDA43 0x6E31 #CJK UNIFIED IDEOGRAPH
+0xDA44 0x6E28 #CJK UNIFIED IDEOGRAPH
+0xDA45 0x6E60 #CJK UNIFIED IDEOGRAPH
+0xDA46 0x6E71 #CJK UNIFIED IDEOGRAPH
+0xDA47 0x6E6B #CJK UNIFIED IDEOGRAPH
+0xDA48 0x6E39 #CJK UNIFIED IDEOGRAPH
+0xDA49 0x6E22 #CJK UNIFIED IDEOGRAPH
+0xDA4A 0x6E30 #CJK UNIFIED IDEOGRAPH
+0xDA4B 0x6E53 #CJK UNIFIED IDEOGRAPH
+0xDA4C 0x6E65 #CJK UNIFIED IDEOGRAPH
+0xDA4D 0x6E27 #CJK UNIFIED IDEOGRAPH
+0xDA4E 0x6E78 #CJK UNIFIED IDEOGRAPH
+0xDA4F 0x6E64 #CJK UNIFIED IDEOGRAPH
+0xDA50 0x6E77 #CJK UNIFIED IDEOGRAPH
+0xDA51 0x6E55 #CJK UNIFIED IDEOGRAPH
+0xDA52 0x6E79 #CJK UNIFIED IDEOGRAPH
+0xDA53 0x6E52 #CJK UNIFIED IDEOGRAPH
+0xDA54 0x6E66 #CJK UNIFIED IDEOGRAPH
+0xDA55 0x6E35 #CJK UNIFIED IDEOGRAPH
+0xDA56 0x6E36 #CJK UNIFIED IDEOGRAPH
+0xDA57 0x6E5A #CJK UNIFIED IDEOGRAPH
+0xDA58 0x7120 #CJK UNIFIED IDEOGRAPH
+0xDA59 0x711E #CJK UNIFIED IDEOGRAPH
+0xDA5A 0x712F #CJK UNIFIED IDEOGRAPH
+0xDA5B 0x70FB #CJK UNIFIED IDEOGRAPH
+0xDA5C 0x712E #CJK UNIFIED IDEOGRAPH
+0xDA5D 0x7131 #CJK UNIFIED IDEOGRAPH
+0xDA5E 0x7123 #CJK UNIFIED IDEOGRAPH
+0xDA5F 0x7125 #CJK UNIFIED IDEOGRAPH
+0xDA60 0x7122 #CJK UNIFIED IDEOGRAPH
+0xDA61 0x7132 #CJK UNIFIED IDEOGRAPH
+0xDA62 0x711F #CJK UNIFIED IDEOGRAPH
+0xDA63 0x7128 #CJK UNIFIED IDEOGRAPH
+0xDA64 0x713A #CJK UNIFIED IDEOGRAPH
+0xDA65 0x711B #CJK UNIFIED IDEOGRAPH
+0xDA66 0x724B #CJK UNIFIED IDEOGRAPH
+0xDA67 0x725A #CJK UNIFIED IDEOGRAPH
+0xDA68 0x7288 #CJK UNIFIED IDEOGRAPH
+0xDA69 0x7289 #CJK UNIFIED IDEOGRAPH
+0xDA6A 0x7286 #CJK UNIFIED IDEOGRAPH
+0xDA6B 0x7285 #CJK UNIFIED IDEOGRAPH
+0xDA6C 0x728B #CJK UNIFIED IDEOGRAPH
+0xDA6D 0x7312 #CJK UNIFIED IDEOGRAPH
+0xDA6E 0x730B #CJK UNIFIED IDEOGRAPH
+0xDA6F 0x7330 #CJK UNIFIED IDEOGRAPH
+0xDA70 0x7322 #CJK UNIFIED IDEOGRAPH
+0xDA71 0x7331 #CJK UNIFIED IDEOGRAPH
+0xDA72 0x7333 #CJK UNIFIED IDEOGRAPH
+0xDA73 0x7327 #CJK UNIFIED IDEOGRAPH
+0xDA74 0x7332 #CJK UNIFIED IDEOGRAPH
+0xDA75 0x732D #CJK UNIFIED IDEOGRAPH
+0xDA76 0x7326 #CJK UNIFIED IDEOGRAPH
+0xDA77 0x7323 #CJK UNIFIED IDEOGRAPH
+0xDA78 0x7335 #CJK UNIFIED IDEOGRAPH
+0xDA79 0x730C #CJK UNIFIED IDEOGRAPH
+0xDA7A 0x742E #CJK UNIFIED IDEOGRAPH
+0xDA7B 0x742C #CJK UNIFIED IDEOGRAPH
+0xDA7C 0x7430 #CJK UNIFIED IDEOGRAPH
+0xDA7D 0x742B #CJK UNIFIED IDEOGRAPH
+0xDA7E 0x7416 #CJK UNIFIED IDEOGRAPH
+0xDAA1 0x741A #CJK UNIFIED IDEOGRAPH
+0xDAA2 0x7421 #CJK UNIFIED IDEOGRAPH
+0xDAA3 0x742D #CJK UNIFIED IDEOGRAPH
+0xDAA4 0x7431 #CJK UNIFIED IDEOGRAPH
+0xDAA5 0x7424 #CJK UNIFIED IDEOGRAPH
+0xDAA6 0x7423 #CJK UNIFIED IDEOGRAPH
+0xDAA7 0x741D #CJK UNIFIED IDEOGRAPH
+0xDAA8 0x7429 #CJK UNIFIED IDEOGRAPH
+0xDAA9 0x7420 #CJK UNIFIED IDEOGRAPH
+0xDAAA 0x7432 #CJK UNIFIED IDEOGRAPH
+0xDAAB 0x74FB #CJK UNIFIED IDEOGRAPH
+0xDAAC 0x752F #CJK UNIFIED IDEOGRAPH
+0xDAAD 0x756F #CJK UNIFIED IDEOGRAPH
+0xDAAE 0x756C #CJK UNIFIED IDEOGRAPH
+0xDAAF 0x75E7 #CJK UNIFIED IDEOGRAPH
+0xDAB0 0x75DA #CJK UNIFIED IDEOGRAPH
+0xDAB1 0x75E1 #CJK UNIFIED IDEOGRAPH
+0xDAB2 0x75E6 #CJK UNIFIED IDEOGRAPH
+0xDAB3 0x75DD #CJK UNIFIED IDEOGRAPH
+0xDAB4 0x75DF #CJK UNIFIED IDEOGRAPH
+0xDAB5 0x75E4 #CJK UNIFIED IDEOGRAPH
+0xDAB6 0x75D7 #CJK UNIFIED IDEOGRAPH
+0xDAB7 0x7695 #CJK UNIFIED IDEOGRAPH
+0xDAB8 0x7692 #CJK UNIFIED IDEOGRAPH
+0xDAB9 0x76DA #CJK UNIFIED IDEOGRAPH
+0xDABA 0x7746 #CJK UNIFIED IDEOGRAPH
+0xDABB 0x7747 #CJK UNIFIED IDEOGRAPH
+0xDABC 0x7744 #CJK UNIFIED IDEOGRAPH
+0xDABD 0x774D #CJK UNIFIED IDEOGRAPH
+0xDABE 0x7745 #CJK UNIFIED IDEOGRAPH
+0xDABF 0x774A #CJK UNIFIED IDEOGRAPH
+0xDAC0 0x774E #CJK UNIFIED IDEOGRAPH
+0xDAC1 0x774B #CJK UNIFIED IDEOGRAPH
+0xDAC2 0x774C #CJK UNIFIED IDEOGRAPH
+0xDAC3 0x77DE #CJK UNIFIED IDEOGRAPH
+0xDAC4 0x77EC #CJK UNIFIED IDEOGRAPH
+0xDAC5 0x7860 #CJK UNIFIED IDEOGRAPH
+0xDAC6 0x7864 #CJK UNIFIED IDEOGRAPH
+0xDAC7 0x7865 #CJK UNIFIED IDEOGRAPH
+0xDAC8 0x785C #CJK UNIFIED IDEOGRAPH
+0xDAC9 0x786D #CJK UNIFIED IDEOGRAPH
+0xDACA 0x7871 #CJK UNIFIED IDEOGRAPH
+0xDACB 0x786A #CJK UNIFIED IDEOGRAPH
+0xDACC 0x786E #CJK UNIFIED IDEOGRAPH
+0xDACD 0x7870 #CJK UNIFIED IDEOGRAPH
+0xDACE 0x7869 #CJK UNIFIED IDEOGRAPH
+0xDACF 0x7868 #CJK UNIFIED IDEOGRAPH
+0xDAD0 0x785E #CJK UNIFIED IDEOGRAPH
+0xDAD1 0x7862 #CJK UNIFIED IDEOGRAPH
+0xDAD2 0x7974 #CJK UNIFIED IDEOGRAPH
+0xDAD3 0x7973 #CJK UNIFIED IDEOGRAPH
+0xDAD4 0x7972 #CJK UNIFIED IDEOGRAPH
+0xDAD5 0x7970 #CJK UNIFIED IDEOGRAPH
+0xDAD6 0x7A02 #CJK UNIFIED IDEOGRAPH
+0xDAD7 0x7A0A #CJK UNIFIED IDEOGRAPH
+0xDAD8 0x7A03 #CJK UNIFIED IDEOGRAPH
+0xDAD9 0x7A0C #CJK UNIFIED IDEOGRAPH
+0xDADA 0x7A04 #CJK UNIFIED IDEOGRAPH
+0xDADB 0x7A99 #CJK UNIFIED IDEOGRAPH
+0xDADC 0x7AE6 #CJK UNIFIED IDEOGRAPH
+0xDADD 0x7AE4 #CJK UNIFIED IDEOGRAPH
+0xDADE 0x7B4A #CJK UNIFIED IDEOGRAPH
+0xDADF 0x7B3B #CJK UNIFIED IDEOGRAPH
+0xDAE0 0x7B44 #CJK UNIFIED IDEOGRAPH
+0xDAE1 0x7B48 #CJK UNIFIED IDEOGRAPH
+0xDAE2 0x7B4C #CJK UNIFIED IDEOGRAPH
+0xDAE3 0x7B4E #CJK UNIFIED IDEOGRAPH
+0xDAE4 0x7B40 #CJK UNIFIED IDEOGRAPH
+0xDAE5 0x7B58 #CJK UNIFIED IDEOGRAPH
+0xDAE6 0x7B45 #CJK UNIFIED IDEOGRAPH
+0xDAE7 0x7CA2 #CJK UNIFIED IDEOGRAPH
+0xDAE8 0x7C9E #CJK UNIFIED IDEOGRAPH
+0xDAE9 0x7CA8 #CJK UNIFIED IDEOGRAPH
+0xDAEA 0x7CA1 #CJK UNIFIED IDEOGRAPH
+0xDAEB 0x7D58 #CJK UNIFIED IDEOGRAPH
+0xDAEC 0x7D6F #CJK UNIFIED IDEOGRAPH
+0xDAED 0x7D63 #CJK UNIFIED IDEOGRAPH
+0xDAEE 0x7D53 #CJK UNIFIED IDEOGRAPH
+0xDAEF 0x7D56 #CJK UNIFIED IDEOGRAPH
+0xDAF0 0x7D67 #CJK UNIFIED IDEOGRAPH
+0xDAF1 0x7D6A #CJK UNIFIED IDEOGRAPH
+0xDAF2 0x7D4F #CJK UNIFIED IDEOGRAPH
+0xDAF3 0x7D6D #CJK UNIFIED IDEOGRAPH
+0xDAF4 0x7D5C #CJK UNIFIED IDEOGRAPH
+0xDAF5 0x7D6B #CJK UNIFIED IDEOGRAPH
+0xDAF6 0x7D52 #CJK UNIFIED IDEOGRAPH
+0xDAF7 0x7D54 #CJK UNIFIED IDEOGRAPH
+0xDAF8 0x7D69 #CJK UNIFIED IDEOGRAPH
+0xDAF9 0x7D51 #CJK UNIFIED IDEOGRAPH
+0xDAFA 0x7D5F #CJK UNIFIED IDEOGRAPH
+0xDAFB 0x7D4E #CJK UNIFIED IDEOGRAPH
+0xDAFC 0x7F3E #CJK UNIFIED IDEOGRAPH
+0xDAFD 0x7F3F #CJK UNIFIED IDEOGRAPH
+0xDAFE 0x7F65 #CJK UNIFIED IDEOGRAPH
+0xDB40 0x7F66 #CJK UNIFIED IDEOGRAPH
+0xDB41 0x7FA2 #CJK UNIFIED IDEOGRAPH
+0xDB42 0x7FA0 #CJK UNIFIED IDEOGRAPH
+0xDB43 0x7FA1 #CJK UNIFIED IDEOGRAPH
+0xDB44 0x7FD7 #CJK UNIFIED IDEOGRAPH
+0xDB45 0x8051 #CJK UNIFIED IDEOGRAPH
+0xDB46 0x804F #CJK UNIFIED IDEOGRAPH
+0xDB47 0x8050 #CJK UNIFIED IDEOGRAPH
+0xDB48 0x80FE #CJK UNIFIED IDEOGRAPH
+0xDB49 0x80D4 #CJK UNIFIED IDEOGRAPH
+0xDB4A 0x8143 #CJK UNIFIED IDEOGRAPH
+0xDB4B 0x814A #CJK UNIFIED IDEOGRAPH
+0xDB4C 0x8152 #CJK UNIFIED IDEOGRAPH
+0xDB4D 0x814F #CJK UNIFIED IDEOGRAPH
+0xDB4E 0x8147 #CJK UNIFIED IDEOGRAPH
+0xDB4F 0x813D #CJK UNIFIED IDEOGRAPH
+0xDB50 0x814D #CJK UNIFIED IDEOGRAPH
+0xDB51 0x813A #CJK UNIFIED IDEOGRAPH
+0xDB52 0x81E6 #CJK UNIFIED IDEOGRAPH
+0xDB53 0x81EE #CJK UNIFIED IDEOGRAPH
+0xDB54 0x81F7 #CJK UNIFIED IDEOGRAPH
+0xDB55 0x81F8 #CJK UNIFIED IDEOGRAPH
+0xDB56 0x81F9 #CJK UNIFIED IDEOGRAPH
+0xDB57 0x8204 #CJK UNIFIED IDEOGRAPH
+0xDB58 0x823C #CJK UNIFIED IDEOGRAPH
+0xDB59 0x823D #CJK UNIFIED IDEOGRAPH
+0xDB5A 0x823F #CJK UNIFIED IDEOGRAPH
+0xDB5B 0x8275 #CJK UNIFIED IDEOGRAPH
+0xDB5C 0x833B #CJK UNIFIED IDEOGRAPH
+0xDB5D 0x83CF #CJK UNIFIED IDEOGRAPH
+0xDB5E 0x83F9 #CJK UNIFIED IDEOGRAPH
+0xDB5F 0x8423 #CJK UNIFIED IDEOGRAPH
+0xDB60 0x83C0 #CJK UNIFIED IDEOGRAPH
+0xDB61 0x83E8 #CJK UNIFIED IDEOGRAPH
+0xDB62 0x8412 #CJK UNIFIED IDEOGRAPH
+0xDB63 0x83E7 #CJK UNIFIED IDEOGRAPH
+0xDB64 0x83E4 #CJK UNIFIED IDEOGRAPH
+0xDB65 0x83FC #CJK UNIFIED IDEOGRAPH
+0xDB66 0x83F6 #CJK UNIFIED IDEOGRAPH
+0xDB67 0x8410 #CJK UNIFIED IDEOGRAPH
+0xDB68 0x83C6 #CJK UNIFIED IDEOGRAPH
+0xDB69 0x83C8 #CJK UNIFIED IDEOGRAPH
+0xDB6A 0x83EB #CJK UNIFIED IDEOGRAPH
+0xDB6B 0x83E3 #CJK UNIFIED IDEOGRAPH
+0xDB6C 0x83BF #CJK UNIFIED IDEOGRAPH
+0xDB6D 0x8401 #CJK UNIFIED IDEOGRAPH
+0xDB6E 0x83DD #CJK UNIFIED IDEOGRAPH
+0xDB6F 0x83E5 #CJK UNIFIED IDEOGRAPH
+0xDB70 0x83D8 #CJK UNIFIED IDEOGRAPH
+0xDB71 0x83FF #CJK UNIFIED IDEOGRAPH
+0xDB72 0x83E1 #CJK UNIFIED IDEOGRAPH
+0xDB73 0x83CB #CJK UNIFIED IDEOGRAPH
+0xDB74 0x83CE #CJK UNIFIED IDEOGRAPH
+0xDB75 0x83D6 #CJK UNIFIED IDEOGRAPH
+0xDB76 0x83F5 #CJK UNIFIED IDEOGRAPH
+0xDB77 0x83C9 #CJK UNIFIED IDEOGRAPH
+0xDB78 0x8409 #CJK UNIFIED IDEOGRAPH
+0xDB79 0x840F #CJK UNIFIED IDEOGRAPH
+0xDB7A 0x83DE #CJK UNIFIED IDEOGRAPH
+0xDB7B 0x8411 #CJK UNIFIED IDEOGRAPH
+0xDB7C 0x8406 #CJK UNIFIED IDEOGRAPH
+0xDB7D 0x83C2 #CJK UNIFIED IDEOGRAPH
+0xDB7E 0x83F3 #CJK UNIFIED IDEOGRAPH
+0xDBA1 0x83D5 #CJK UNIFIED IDEOGRAPH
+0xDBA2 0x83FA #CJK UNIFIED IDEOGRAPH
+0xDBA3 0x83C7 #CJK UNIFIED IDEOGRAPH
+0xDBA4 0x83D1 #CJK UNIFIED IDEOGRAPH
+0xDBA5 0x83EA #CJK UNIFIED IDEOGRAPH
+0xDBA6 0x8413 #CJK UNIFIED IDEOGRAPH
+0xDBA7 0x83C3 #CJK UNIFIED IDEOGRAPH
+0xDBA8 0x83EC #CJK UNIFIED IDEOGRAPH
+0xDBA9 0x83EE #CJK UNIFIED IDEOGRAPH
+0xDBAA 0x83C4 #CJK UNIFIED IDEOGRAPH
+0xDBAB 0x83FB #CJK UNIFIED IDEOGRAPH
+0xDBAC 0x83D7 #CJK UNIFIED IDEOGRAPH
+0xDBAD 0x83E2 #CJK UNIFIED IDEOGRAPH
+0xDBAE 0x841B #CJK UNIFIED IDEOGRAPH
+0xDBAF 0x83DB #CJK UNIFIED IDEOGRAPH
+0xDBB0 0x83FE #CJK UNIFIED IDEOGRAPH
+0xDBB1 0x86D8 #CJK UNIFIED IDEOGRAPH
+0xDBB2 0x86E2 #CJK UNIFIED IDEOGRAPH
+0xDBB3 0x86E6 #CJK UNIFIED IDEOGRAPH
+0xDBB4 0x86D3 #CJK UNIFIED IDEOGRAPH
+0xDBB5 0x86E3 #CJK UNIFIED IDEOGRAPH
+0xDBB6 0x86DA #CJK UNIFIED IDEOGRAPH
+0xDBB7 0x86EA #CJK UNIFIED IDEOGRAPH
+0xDBB8 0x86DD #CJK UNIFIED IDEOGRAPH
+0xDBB9 0x86EB #CJK UNIFIED IDEOGRAPH
+0xDBBA 0x86DC #CJK UNIFIED IDEOGRAPH
+0xDBBB 0x86EC #CJK UNIFIED IDEOGRAPH
+0xDBBC 0x86E9 #CJK UNIFIED IDEOGRAPH
+0xDBBD 0x86D7 #CJK UNIFIED IDEOGRAPH
+0xDBBE 0x86E8 #CJK UNIFIED IDEOGRAPH
+0xDBBF 0x86D1 #CJK UNIFIED IDEOGRAPH
+0xDBC0 0x8848 #CJK UNIFIED IDEOGRAPH
+0xDBC1 0x8856 #CJK UNIFIED IDEOGRAPH
+0xDBC2 0x8855 #CJK UNIFIED IDEOGRAPH
+0xDBC3 0x88BA #CJK UNIFIED IDEOGRAPH
+0xDBC4 0x88D7 #CJK UNIFIED IDEOGRAPH
+0xDBC5 0x88B9 #CJK UNIFIED IDEOGRAPH
+0xDBC6 0x88B8 #CJK UNIFIED IDEOGRAPH
+0xDBC7 0x88C0 #CJK UNIFIED IDEOGRAPH
+0xDBC8 0x88BE #CJK UNIFIED IDEOGRAPH
+0xDBC9 0x88B6 #CJK UNIFIED IDEOGRAPH
+0xDBCA 0x88BC #CJK UNIFIED IDEOGRAPH
+0xDBCB 0x88B7 #CJK UNIFIED IDEOGRAPH
+0xDBCC 0x88BD #CJK UNIFIED IDEOGRAPH
+0xDBCD 0x88B2 #CJK UNIFIED IDEOGRAPH
+0xDBCE 0x8901 #CJK UNIFIED IDEOGRAPH
+0xDBCF 0x88C9 #CJK UNIFIED IDEOGRAPH
+0xDBD0 0x8995 #CJK UNIFIED IDEOGRAPH
+0xDBD1 0x8998 #CJK UNIFIED IDEOGRAPH
+0xDBD2 0x8997 #CJK UNIFIED IDEOGRAPH
+0xDBD3 0x89DD #CJK UNIFIED IDEOGRAPH
+0xDBD4 0x89DA #CJK UNIFIED IDEOGRAPH
+0xDBD5 0x89DB #CJK UNIFIED IDEOGRAPH
+0xDBD6 0x8A4E #CJK UNIFIED IDEOGRAPH
+0xDBD7 0x8A4D #CJK UNIFIED IDEOGRAPH
+0xDBD8 0x8A39 #CJK UNIFIED IDEOGRAPH
+0xDBD9 0x8A59 #CJK UNIFIED IDEOGRAPH
+0xDBDA 0x8A40 #CJK UNIFIED IDEOGRAPH
+0xDBDB 0x8A57 #CJK UNIFIED IDEOGRAPH
+0xDBDC 0x8A58 #CJK UNIFIED IDEOGRAPH
+0xDBDD 0x8A44 #CJK UNIFIED IDEOGRAPH
+0xDBDE 0x8A45 #CJK UNIFIED IDEOGRAPH
+0xDBDF 0x8A52 #CJK UNIFIED IDEOGRAPH
+0xDBE0 0x8A48 #CJK UNIFIED IDEOGRAPH
+0xDBE1 0x8A51 #CJK UNIFIED IDEOGRAPH
+0xDBE2 0x8A4A #CJK UNIFIED IDEOGRAPH
+0xDBE3 0x8A4C #CJK UNIFIED IDEOGRAPH
+0xDBE4 0x8A4F #CJK UNIFIED IDEOGRAPH
+0xDBE5 0x8C5F #CJK UNIFIED IDEOGRAPH
+0xDBE6 0x8C81 #CJK UNIFIED IDEOGRAPH
+0xDBE7 0x8C80 #CJK UNIFIED IDEOGRAPH
+0xDBE8 0x8CBA #CJK UNIFIED IDEOGRAPH
+0xDBE9 0x8CBE #CJK UNIFIED IDEOGRAPH
+0xDBEA 0x8CB0 #CJK UNIFIED IDEOGRAPH
+0xDBEB 0x8CB9 #CJK UNIFIED IDEOGRAPH
+0xDBEC 0x8CB5 #CJK UNIFIED IDEOGRAPH
+0xDBED 0x8D84 #CJK UNIFIED IDEOGRAPH
+0xDBEE 0x8D80 #CJK UNIFIED IDEOGRAPH
+0xDBEF 0x8D89 #CJK UNIFIED IDEOGRAPH
+0xDBF0 0x8DD8 #CJK UNIFIED IDEOGRAPH
+0xDBF1 0x8DD3 #CJK UNIFIED IDEOGRAPH
+0xDBF2 0x8DCD #CJK UNIFIED IDEOGRAPH
+0xDBF3 0x8DC7 #CJK UNIFIED IDEOGRAPH
+0xDBF4 0x8DD6 #CJK UNIFIED IDEOGRAPH
+0xDBF5 0x8DDC #CJK UNIFIED IDEOGRAPH
+0xDBF6 0x8DCF #CJK UNIFIED IDEOGRAPH
+0xDBF7 0x8DD5 #CJK UNIFIED IDEOGRAPH
+0xDBF8 0x8DD9 #CJK UNIFIED IDEOGRAPH
+0xDBF9 0x8DC8 #CJK UNIFIED IDEOGRAPH
+0xDBFA 0x8DD7 #CJK UNIFIED IDEOGRAPH
+0xDBFB 0x8DC5 #CJK UNIFIED IDEOGRAPH
+0xDBFC 0x8EEF #CJK UNIFIED IDEOGRAPH
+0xDBFD 0x8EF7 #CJK UNIFIED IDEOGRAPH
+0xDBFE 0x8EFA #CJK UNIFIED IDEOGRAPH
+0xDC40 0x8EF9 #CJK UNIFIED IDEOGRAPH
+0xDC41 0x8EE6 #CJK UNIFIED IDEOGRAPH
+0xDC42 0x8EEE #CJK UNIFIED IDEOGRAPH
+0xDC43 0x8EE5 #CJK UNIFIED IDEOGRAPH
+0xDC44 0x8EF5 #CJK UNIFIED IDEOGRAPH
+0xDC45 0x8EE7 #CJK UNIFIED IDEOGRAPH
+0xDC46 0x8EE8 #CJK UNIFIED IDEOGRAPH
+0xDC47 0x8EF6 #CJK UNIFIED IDEOGRAPH
+0xDC48 0x8EEB #CJK UNIFIED IDEOGRAPH
+0xDC49 0x8EF1 #CJK UNIFIED IDEOGRAPH
+0xDC4A 0x8EEC #CJK UNIFIED IDEOGRAPH
+0xDC4B 0x8EF4 #CJK UNIFIED IDEOGRAPH
+0xDC4C 0x8EE9 #CJK UNIFIED IDEOGRAPH
+0xDC4D 0x902D #CJK UNIFIED IDEOGRAPH
+0xDC4E 0x9034 #CJK UNIFIED IDEOGRAPH
+0xDC4F 0x902F #CJK UNIFIED IDEOGRAPH
+0xDC50 0x9106 #CJK UNIFIED IDEOGRAPH
+0xDC51 0x912C #CJK UNIFIED IDEOGRAPH
+0xDC52 0x9104 #CJK UNIFIED IDEOGRAPH
+0xDC53 0x90FF #CJK UNIFIED IDEOGRAPH
+0xDC54 0x90FC #CJK UNIFIED IDEOGRAPH
+0xDC55 0x9108 #CJK UNIFIED IDEOGRAPH
+0xDC56 0x90F9 #CJK UNIFIED IDEOGRAPH
+0xDC57 0x90FB #CJK UNIFIED IDEOGRAPH
+0xDC58 0x9101 #CJK UNIFIED IDEOGRAPH
+0xDC59 0x9100 #CJK UNIFIED IDEOGRAPH
+0xDC5A 0x9107 #CJK UNIFIED IDEOGRAPH
+0xDC5B 0x9105 #CJK UNIFIED IDEOGRAPH
+0xDC5C 0x9103 #CJK UNIFIED IDEOGRAPH
+0xDC5D 0x9161 #CJK UNIFIED IDEOGRAPH
+0xDC5E 0x9164 #CJK UNIFIED IDEOGRAPH
+0xDC5F 0x915F #CJK UNIFIED IDEOGRAPH
+0xDC60 0x9162 #CJK UNIFIED IDEOGRAPH
+0xDC61 0x9160 #CJK UNIFIED IDEOGRAPH
+0xDC62 0x9201 #CJK UNIFIED IDEOGRAPH
+0xDC63 0x920A #CJK UNIFIED IDEOGRAPH
+0xDC64 0x9225 #CJK UNIFIED IDEOGRAPH
+0xDC65 0x9203 #CJK UNIFIED IDEOGRAPH
+0xDC66 0x921A #CJK UNIFIED IDEOGRAPH
+0xDC67 0x9226 #CJK UNIFIED IDEOGRAPH
+0xDC68 0x920F #CJK UNIFIED IDEOGRAPH
+0xDC69 0x920C #CJK UNIFIED IDEOGRAPH
+0xDC6A 0x9200 #CJK UNIFIED IDEOGRAPH
+0xDC6B 0x9212 #CJK UNIFIED IDEOGRAPH
+0xDC6C 0x91FF #CJK UNIFIED IDEOGRAPH
+0xDC6D 0x91FD #CJK UNIFIED IDEOGRAPH
+0xDC6E 0x9206 #CJK UNIFIED IDEOGRAPH
+0xDC6F 0x9204 #CJK UNIFIED IDEOGRAPH
+0xDC70 0x9227 #CJK UNIFIED IDEOGRAPH
+0xDC71 0x9202 #CJK UNIFIED IDEOGRAPH
+0xDC72 0x921C #CJK UNIFIED IDEOGRAPH
+0xDC73 0x9224 #CJK UNIFIED IDEOGRAPH
+0xDC74 0x9219 #CJK UNIFIED IDEOGRAPH
+0xDC75 0x9217 #CJK UNIFIED IDEOGRAPH
+0xDC76 0x9205 #CJK UNIFIED IDEOGRAPH
+0xDC77 0x9216 #CJK UNIFIED IDEOGRAPH
+0xDC78 0x957B #CJK UNIFIED IDEOGRAPH
+0xDC79 0x958D #CJK UNIFIED IDEOGRAPH
+0xDC7A 0x958C #CJK UNIFIED IDEOGRAPH
+0xDC7B 0x9590 #CJK UNIFIED IDEOGRAPH
+0xDC7C 0x9687 #CJK UNIFIED IDEOGRAPH
+0xDC7D 0x967E #CJK UNIFIED IDEOGRAPH
+0xDC7E 0x9688 #CJK UNIFIED IDEOGRAPH
+0xDCA1 0x9689 #CJK UNIFIED IDEOGRAPH
+0xDCA2 0x9683 #CJK UNIFIED IDEOGRAPH
+0xDCA3 0x9680 #CJK UNIFIED IDEOGRAPH
+0xDCA4 0x96C2 #CJK UNIFIED IDEOGRAPH
+0xDCA5 0x96C8 #CJK UNIFIED IDEOGRAPH
+0xDCA6 0x96C3 #CJK UNIFIED IDEOGRAPH
+0xDCA7 0x96F1 #CJK UNIFIED IDEOGRAPH
+0xDCA8 0x96F0 #CJK UNIFIED IDEOGRAPH
+0xDCA9 0x976C #CJK UNIFIED IDEOGRAPH
+0xDCAA 0x9770 #CJK UNIFIED IDEOGRAPH
+0xDCAB 0x976E #CJK UNIFIED IDEOGRAPH
+0xDCAC 0x9807 #CJK UNIFIED IDEOGRAPH
+0xDCAD 0x98A9 #CJK UNIFIED IDEOGRAPH
+0xDCAE 0x98EB #CJK UNIFIED IDEOGRAPH
+0xDCAF 0x9CE6 #CJK UNIFIED IDEOGRAPH
+0xDCB0 0x9EF9 #CJK UNIFIED IDEOGRAPH
+0xDCB1 0x4E83 #CJK UNIFIED IDEOGRAPH
+0xDCB2 0x4E84 #CJK UNIFIED IDEOGRAPH
+0xDCB3 0x4EB6 #CJK UNIFIED IDEOGRAPH
+0xDCB4 0x50BD #CJK UNIFIED IDEOGRAPH
+0xDCB5 0x50BF #CJK UNIFIED IDEOGRAPH
+0xDCB6 0x50C6 #CJK UNIFIED IDEOGRAPH
+0xDCB7 0x50AE #CJK UNIFIED IDEOGRAPH
+0xDCB8 0x50C4 #CJK UNIFIED IDEOGRAPH
+0xDCB9 0x50CA #CJK UNIFIED IDEOGRAPH
+0xDCBA 0x50B4 #CJK UNIFIED IDEOGRAPH
+0xDCBB 0x50C8 #CJK UNIFIED IDEOGRAPH
+0xDCBC 0x50C2 #CJK UNIFIED IDEOGRAPH
+0xDCBD 0x50B0 #CJK UNIFIED IDEOGRAPH
+0xDCBE 0x50C1 #CJK UNIFIED IDEOGRAPH
+0xDCBF 0x50BA #CJK UNIFIED IDEOGRAPH
+0xDCC0 0x50B1 #CJK UNIFIED IDEOGRAPH
+0xDCC1 0x50CB #CJK UNIFIED IDEOGRAPH
+0xDCC2 0x50C9 #CJK UNIFIED IDEOGRAPH
+0xDCC3 0x50B6 #CJK UNIFIED IDEOGRAPH
+0xDCC4 0x50B8 #CJK UNIFIED IDEOGRAPH
+0xDCC5 0x51D7 #CJK UNIFIED IDEOGRAPH
+0xDCC6 0x527A #CJK UNIFIED IDEOGRAPH
+0xDCC7 0x5278 #CJK UNIFIED IDEOGRAPH
+0xDCC8 0x527B #CJK UNIFIED IDEOGRAPH
+0xDCC9 0x527C #CJK UNIFIED IDEOGRAPH
+0xDCCA 0x55C3 #CJK UNIFIED IDEOGRAPH
+0xDCCB 0x55DB #CJK UNIFIED IDEOGRAPH
+0xDCCC 0x55CC #CJK UNIFIED IDEOGRAPH
+0xDCCD 0x55D0 #CJK UNIFIED IDEOGRAPH
+0xDCCE 0x55CB #CJK UNIFIED IDEOGRAPH
+0xDCCF 0x55CA #CJK UNIFIED IDEOGRAPH
+0xDCD0 0x55DD #CJK UNIFIED IDEOGRAPH
+0xDCD1 0x55C0 #CJK UNIFIED IDEOGRAPH
+0xDCD2 0x55D4 #CJK UNIFIED IDEOGRAPH
+0xDCD3 0x55C4 #CJK UNIFIED IDEOGRAPH
+0xDCD4 0x55E9 #CJK UNIFIED IDEOGRAPH
+0xDCD5 0x55BF #CJK UNIFIED IDEOGRAPH
+0xDCD6 0x55D2 #CJK UNIFIED IDEOGRAPH
+0xDCD7 0x558D #CJK UNIFIED IDEOGRAPH
+0xDCD8 0x55CF #CJK UNIFIED IDEOGRAPH
+0xDCD9 0x55D5 #CJK UNIFIED IDEOGRAPH
+0xDCDA 0x55E2 #CJK UNIFIED IDEOGRAPH
+0xDCDB 0x55D6 #CJK UNIFIED IDEOGRAPH
+0xDCDC 0x55C8 #CJK UNIFIED IDEOGRAPH
+0xDCDD 0x55F2 #CJK UNIFIED IDEOGRAPH
+0xDCDE 0x55CD #CJK UNIFIED IDEOGRAPH
+0xDCDF 0x55D9 #CJK UNIFIED IDEOGRAPH
+0xDCE0 0x55C2 #CJK UNIFIED IDEOGRAPH
+0xDCE1 0x5714 #CJK UNIFIED IDEOGRAPH
+0xDCE2 0x5853 #CJK UNIFIED IDEOGRAPH
+0xDCE3 0x5868 #CJK UNIFIED IDEOGRAPH
+0xDCE4 0x5864 #CJK UNIFIED IDEOGRAPH
+0xDCE5 0x584F #CJK UNIFIED IDEOGRAPH
+0xDCE6 0x584D #CJK UNIFIED IDEOGRAPH
+0xDCE7 0x5849 #CJK UNIFIED IDEOGRAPH
+0xDCE8 0x586F #CJK UNIFIED IDEOGRAPH
+0xDCE9 0x5855 #CJK UNIFIED IDEOGRAPH
+0xDCEA 0x584E #CJK UNIFIED IDEOGRAPH
+0xDCEB 0x585D #CJK UNIFIED IDEOGRAPH
+0xDCEC 0x5859 #CJK UNIFIED IDEOGRAPH
+0xDCED 0x5865 #CJK UNIFIED IDEOGRAPH
+0xDCEE 0x585B #CJK UNIFIED IDEOGRAPH
+0xDCEF 0x583D #CJK UNIFIED IDEOGRAPH
+0xDCF0 0x5863 #CJK UNIFIED IDEOGRAPH
+0xDCF1 0x5871 #CJK UNIFIED IDEOGRAPH
+0xDCF2 0x58FC #CJK UNIFIED IDEOGRAPH
+0xDCF3 0x5AC7 #CJK UNIFIED IDEOGRAPH
+0xDCF4 0x5AC4 #CJK UNIFIED IDEOGRAPH
+0xDCF5 0x5ACB #CJK UNIFIED IDEOGRAPH
+0xDCF6 0x5ABA #CJK UNIFIED IDEOGRAPH
+0xDCF7 0x5AB8 #CJK UNIFIED IDEOGRAPH
+0xDCF8 0x5AB1 #CJK UNIFIED IDEOGRAPH
+0xDCF9 0x5AB5 #CJK UNIFIED IDEOGRAPH
+0xDCFA 0x5AB0 #CJK UNIFIED IDEOGRAPH
+0xDCFB 0x5ABF #CJK UNIFIED IDEOGRAPH
+0xDCFC 0x5AC8 #CJK UNIFIED IDEOGRAPH
+0xDCFD 0x5ABB #CJK UNIFIED IDEOGRAPH
+0xDCFE 0x5AC6 #CJK UNIFIED IDEOGRAPH
+0xDD40 0x5AB7 #CJK UNIFIED IDEOGRAPH
+0xDD41 0x5AC0 #CJK UNIFIED IDEOGRAPH
+0xDD42 0x5ACA #CJK UNIFIED IDEOGRAPH
+0xDD43 0x5AB4 #CJK UNIFIED IDEOGRAPH
+0xDD44 0x5AB6 #CJK UNIFIED IDEOGRAPH
+0xDD45 0x5ACD #CJK UNIFIED IDEOGRAPH
+0xDD46 0x5AB9 #CJK UNIFIED IDEOGRAPH
+0xDD47 0x5A90 #CJK UNIFIED IDEOGRAPH
+0xDD48 0x5BD6 #CJK UNIFIED IDEOGRAPH
+0xDD49 0x5BD8 #CJK UNIFIED IDEOGRAPH
+0xDD4A 0x5BD9 #CJK UNIFIED IDEOGRAPH
+0xDD4B 0x5C1F #CJK UNIFIED IDEOGRAPH
+0xDD4C 0x5C33 #CJK UNIFIED IDEOGRAPH
+0xDD4D 0x5D71 #CJK UNIFIED IDEOGRAPH
+0xDD4E 0x5D63 #CJK UNIFIED IDEOGRAPH
+0xDD4F 0x5D4A #CJK UNIFIED IDEOGRAPH
+0xDD50 0x5D65 #CJK UNIFIED IDEOGRAPH
+0xDD51 0x5D72 #CJK UNIFIED IDEOGRAPH
+0xDD52 0x5D6C #CJK UNIFIED IDEOGRAPH
+0xDD53 0x5D5E #CJK UNIFIED IDEOGRAPH
+0xDD54 0x5D68 #CJK UNIFIED IDEOGRAPH
+0xDD55 0x5D67 #CJK UNIFIED IDEOGRAPH
+0xDD56 0x5D62 #CJK UNIFIED IDEOGRAPH
+0xDD57 0x5DF0 #CJK UNIFIED IDEOGRAPH
+0xDD58 0x5E4F #CJK UNIFIED IDEOGRAPH
+0xDD59 0x5E4E #CJK UNIFIED IDEOGRAPH
+0xDD5A 0x5E4A #CJK UNIFIED IDEOGRAPH
+0xDD5B 0x5E4D #CJK UNIFIED IDEOGRAPH
+0xDD5C 0x5E4B #CJK UNIFIED IDEOGRAPH
+0xDD5D 0x5EC5 #CJK UNIFIED IDEOGRAPH
+0xDD5E 0x5ECC #CJK UNIFIED IDEOGRAPH
+0xDD5F 0x5EC6 #CJK UNIFIED IDEOGRAPH
+0xDD60 0x5ECB #CJK UNIFIED IDEOGRAPH
+0xDD61 0x5EC7 #CJK UNIFIED IDEOGRAPH
+0xDD62 0x5F40 #CJK UNIFIED IDEOGRAPH
+0xDD63 0x5FAF #CJK UNIFIED IDEOGRAPH
+0xDD64 0x5FAD #CJK UNIFIED IDEOGRAPH
+0xDD65 0x60F7 #CJK UNIFIED IDEOGRAPH
+0xDD66 0x6149 #CJK UNIFIED IDEOGRAPH
+0xDD67 0x614A #CJK UNIFIED IDEOGRAPH
+0xDD68 0x612B #CJK UNIFIED IDEOGRAPH
+0xDD69 0x6145 #CJK UNIFIED IDEOGRAPH
+0xDD6A 0x6136 #CJK UNIFIED IDEOGRAPH
+0xDD6B 0x6132 #CJK UNIFIED IDEOGRAPH
+0xDD6C 0x612E #CJK UNIFIED IDEOGRAPH
+0xDD6D 0x6146 #CJK UNIFIED IDEOGRAPH
+0xDD6E 0x612F #CJK UNIFIED IDEOGRAPH
+0xDD6F 0x614F #CJK UNIFIED IDEOGRAPH
+0xDD70 0x6129 #CJK UNIFIED IDEOGRAPH
+0xDD71 0x6140 #CJK UNIFIED IDEOGRAPH
+0xDD72 0x6220 #CJK UNIFIED IDEOGRAPH
+0xDD73 0x9168 #CJK UNIFIED IDEOGRAPH
+0xDD74 0x6223 #CJK UNIFIED IDEOGRAPH
+0xDD75 0x6225 #CJK UNIFIED IDEOGRAPH
+0xDD76 0x6224 #CJK UNIFIED IDEOGRAPH
+0xDD77 0x63C5 #CJK UNIFIED IDEOGRAPH
+0xDD78 0x63F1 #CJK UNIFIED IDEOGRAPH
+0xDD79 0x63EB #CJK UNIFIED IDEOGRAPH
+0xDD7A 0x6410 #CJK UNIFIED IDEOGRAPH
+0xDD7B 0x6412 #CJK UNIFIED IDEOGRAPH
+0xDD7C 0x6409 #CJK UNIFIED IDEOGRAPH
+0xDD7D 0x6420 #CJK UNIFIED IDEOGRAPH
+0xDD7E 0x6424 #CJK UNIFIED IDEOGRAPH
+0xDDA1 0x6433 #CJK UNIFIED IDEOGRAPH
+0xDDA2 0x6443 #CJK UNIFIED IDEOGRAPH
+0xDDA3 0x641F #CJK UNIFIED IDEOGRAPH
+0xDDA4 0x6415 #CJK UNIFIED IDEOGRAPH
+0xDDA5 0x6418 #CJK UNIFIED IDEOGRAPH
+0xDDA6 0x6439 #CJK UNIFIED IDEOGRAPH
+0xDDA7 0x6437 #CJK UNIFIED IDEOGRAPH
+0xDDA8 0x6422 #CJK UNIFIED IDEOGRAPH
+0xDDA9 0x6423 #CJK UNIFIED IDEOGRAPH
+0xDDAA 0x640C #CJK UNIFIED IDEOGRAPH
+0xDDAB 0x6426 #CJK UNIFIED IDEOGRAPH
+0xDDAC 0x6430 #CJK UNIFIED IDEOGRAPH
+0xDDAD 0x6428 #CJK UNIFIED IDEOGRAPH
+0xDDAE 0x6441 #CJK UNIFIED IDEOGRAPH
+0xDDAF 0x6435 #CJK UNIFIED IDEOGRAPH
+0xDDB0 0x642F #CJK UNIFIED IDEOGRAPH
+0xDDB1 0x640A #CJK UNIFIED IDEOGRAPH
+0xDDB2 0x641A #CJK UNIFIED IDEOGRAPH
+0xDDB3 0x6440 #CJK UNIFIED IDEOGRAPH
+0xDDB4 0x6425 #CJK UNIFIED IDEOGRAPH
+0xDDB5 0x6427 #CJK UNIFIED IDEOGRAPH
+0xDDB6 0x640B #CJK UNIFIED IDEOGRAPH
+0xDDB7 0x63E7 #CJK UNIFIED IDEOGRAPH
+0xDDB8 0x641B #CJK UNIFIED IDEOGRAPH
+0xDDB9 0x642E #CJK UNIFIED IDEOGRAPH
+0xDDBA 0x6421 #CJK UNIFIED IDEOGRAPH
+0xDDBB 0x640E #CJK UNIFIED IDEOGRAPH
+0xDDBC 0x656F #CJK UNIFIED IDEOGRAPH
+0xDDBD 0x6592 #CJK UNIFIED IDEOGRAPH
+0xDDBE 0x65D3 #CJK UNIFIED IDEOGRAPH
+0xDDBF 0x6686 #CJK UNIFIED IDEOGRAPH
+0xDDC0 0x668C #CJK UNIFIED IDEOGRAPH
+0xDDC1 0x6695 #CJK UNIFIED IDEOGRAPH
+0xDDC2 0x6690 #CJK UNIFIED IDEOGRAPH
+0xDDC3 0x668B #CJK UNIFIED IDEOGRAPH
+0xDDC4 0x668A #CJK UNIFIED IDEOGRAPH
+0xDDC5 0x6699 #CJK UNIFIED IDEOGRAPH
+0xDDC6 0x6694 #CJK UNIFIED IDEOGRAPH
+0xDDC7 0x6678 #CJK UNIFIED IDEOGRAPH
+0xDDC8 0x6720 #CJK UNIFIED IDEOGRAPH
+0xDDC9 0x6966 #CJK UNIFIED IDEOGRAPH
+0xDDCA 0x695F #CJK UNIFIED IDEOGRAPH
+0xDDCB 0x6938 #CJK UNIFIED IDEOGRAPH
+0xDDCC 0x694E #CJK UNIFIED IDEOGRAPH
+0xDDCD 0x6962 #CJK UNIFIED IDEOGRAPH
+0xDDCE 0x6971 #CJK UNIFIED IDEOGRAPH
+0xDDCF 0x693F #CJK UNIFIED IDEOGRAPH
+0xDDD0 0x6945 #CJK UNIFIED IDEOGRAPH
+0xDDD1 0x696A #CJK UNIFIED IDEOGRAPH
+0xDDD2 0x6939 #CJK UNIFIED IDEOGRAPH
+0xDDD3 0x6942 #CJK UNIFIED IDEOGRAPH
+0xDDD4 0x6957 #CJK UNIFIED IDEOGRAPH
+0xDDD5 0x6959 #CJK UNIFIED IDEOGRAPH
+0xDDD6 0x697A #CJK UNIFIED IDEOGRAPH
+0xDDD7 0x6948 #CJK UNIFIED IDEOGRAPH
+0xDDD8 0x6949 #CJK UNIFIED IDEOGRAPH
+0xDDD9 0x6935 #CJK UNIFIED IDEOGRAPH
+0xDDDA 0x696C #CJK UNIFIED IDEOGRAPH
+0xDDDB 0x6933 #CJK UNIFIED IDEOGRAPH
+0xDDDC 0x693D #CJK UNIFIED IDEOGRAPH
+0xDDDD 0x6965 #CJK UNIFIED IDEOGRAPH
+0xDDDE 0x68F0 #CJK UNIFIED IDEOGRAPH
+0xDDDF 0x6978 #CJK UNIFIED IDEOGRAPH
+0xDDE0 0x6934 #CJK UNIFIED IDEOGRAPH
+0xDDE1 0x6969 #CJK UNIFIED IDEOGRAPH
+0xDDE2 0x6940 #CJK UNIFIED IDEOGRAPH
+0xDDE3 0x696F #CJK UNIFIED IDEOGRAPH
+0xDDE4 0x6944 #CJK UNIFIED IDEOGRAPH
+0xDDE5 0x6976 #CJK UNIFIED IDEOGRAPH
+0xDDE6 0x6958 #CJK UNIFIED IDEOGRAPH
+0xDDE7 0x6941 #CJK UNIFIED IDEOGRAPH
+0xDDE8 0x6974 #CJK UNIFIED IDEOGRAPH
+0xDDE9 0x694C #CJK UNIFIED IDEOGRAPH
+0xDDEA 0x693B #CJK UNIFIED IDEOGRAPH
+0xDDEB 0x694B #CJK UNIFIED IDEOGRAPH
+0xDDEC 0x6937 #CJK UNIFIED IDEOGRAPH
+0xDDED 0x695C #CJK UNIFIED IDEOGRAPH
+0xDDEE 0x694F #CJK UNIFIED IDEOGRAPH
+0xDDEF 0x6951 #CJK UNIFIED IDEOGRAPH
+0xDDF0 0x6932 #CJK UNIFIED IDEOGRAPH
+0xDDF1 0x6952 #CJK UNIFIED IDEOGRAPH
+0xDDF2 0x692F #CJK UNIFIED IDEOGRAPH
+0xDDF3 0x697B #CJK UNIFIED IDEOGRAPH
+0xDDF4 0x693C #CJK UNIFIED IDEOGRAPH
+0xDDF5 0x6B46 #CJK UNIFIED IDEOGRAPH
+0xDDF6 0x6B45 #CJK UNIFIED IDEOGRAPH
+0xDDF7 0x6B43 #CJK UNIFIED IDEOGRAPH
+0xDDF8 0x6B42 #CJK UNIFIED IDEOGRAPH
+0xDDF9 0x6B48 #CJK UNIFIED IDEOGRAPH
+0xDDFA 0x6B41 #CJK UNIFIED IDEOGRAPH
+0xDDFB 0x6B9B #CJK UNIFIED IDEOGRAPH
+0xDDFC 0xFA0D #CJK COMPATIBILITY IDEOGRAPH
+0xDDFD 0x6BFB #CJK UNIFIED IDEOGRAPH
+0xDDFE 0x6BFC #CJK UNIFIED IDEOGRAPH
+0xDE40 0x6BF9 #CJK UNIFIED IDEOGRAPH
+0xDE41 0x6BF7 #CJK UNIFIED IDEOGRAPH
+0xDE42 0x6BF8 #CJK UNIFIED IDEOGRAPH
+0xDE43 0x6E9B #CJK UNIFIED IDEOGRAPH
+0xDE44 0x6ED6 #CJK UNIFIED IDEOGRAPH
+0xDE45 0x6EC8 #CJK UNIFIED IDEOGRAPH
+0xDE46 0x6E8F #CJK UNIFIED IDEOGRAPH
+0xDE47 0x6EC0 #CJK UNIFIED IDEOGRAPH
+0xDE48 0x6E9F #CJK UNIFIED IDEOGRAPH
+0xDE49 0x6E93 #CJK UNIFIED IDEOGRAPH
+0xDE4A 0x6E94 #CJK UNIFIED IDEOGRAPH
+0xDE4B 0x6EA0 #CJK UNIFIED IDEOGRAPH
+0xDE4C 0x6EB1 #CJK UNIFIED IDEOGRAPH
+0xDE4D 0x6EB9 #CJK UNIFIED IDEOGRAPH
+0xDE4E 0x6EC6 #CJK UNIFIED IDEOGRAPH
+0xDE4F 0x6ED2 #CJK UNIFIED IDEOGRAPH
+0xDE50 0x6EBD #CJK UNIFIED IDEOGRAPH
+0xDE51 0x6EC1 #CJK UNIFIED IDEOGRAPH
+0xDE52 0x6E9E #CJK UNIFIED IDEOGRAPH
+0xDE53 0x6EC9 #CJK UNIFIED IDEOGRAPH
+0xDE54 0x6EB7 #CJK UNIFIED IDEOGRAPH
+0xDE55 0x6EB0 #CJK UNIFIED IDEOGRAPH
+0xDE56 0x6ECD #CJK UNIFIED IDEOGRAPH
+0xDE57 0x6EA6 #CJK UNIFIED IDEOGRAPH
+0xDE58 0x6ECF #CJK UNIFIED IDEOGRAPH
+0xDE59 0x6EB2 #CJK UNIFIED IDEOGRAPH
+0xDE5A 0x6EBE #CJK UNIFIED IDEOGRAPH
+0xDE5B 0x6EC3 #CJK UNIFIED IDEOGRAPH
+0xDE5C 0x6EDC #CJK UNIFIED IDEOGRAPH
+0xDE5D 0x6ED8 #CJK UNIFIED IDEOGRAPH
+0xDE5E 0x6E99 #CJK UNIFIED IDEOGRAPH
+0xDE5F 0x6E92 #CJK UNIFIED IDEOGRAPH
+0xDE60 0x6E8E #CJK UNIFIED IDEOGRAPH
+0xDE61 0x6E8D #CJK UNIFIED IDEOGRAPH
+0xDE62 0x6EA4 #CJK UNIFIED IDEOGRAPH
+0xDE63 0x6EA1 #CJK UNIFIED IDEOGRAPH
+0xDE64 0x6EBF #CJK UNIFIED IDEOGRAPH
+0xDE65 0x6EB3 #CJK UNIFIED IDEOGRAPH
+0xDE66 0x6ED0 #CJK UNIFIED IDEOGRAPH
+0xDE67 0x6ECA #CJK UNIFIED IDEOGRAPH
+0xDE68 0x6E97 #CJK UNIFIED IDEOGRAPH
+0xDE69 0x6EAE #CJK UNIFIED IDEOGRAPH
+0xDE6A 0x6EA3 #CJK UNIFIED IDEOGRAPH
+0xDE6B 0x7147 #CJK UNIFIED IDEOGRAPH
+0xDE6C 0x7154 #CJK UNIFIED IDEOGRAPH
+0xDE6D 0x7152 #CJK UNIFIED IDEOGRAPH
+0xDE6E 0x7163 #CJK UNIFIED IDEOGRAPH
+0xDE6F 0x7160 #CJK UNIFIED IDEOGRAPH
+0xDE70 0x7141 #CJK UNIFIED IDEOGRAPH
+0xDE71 0x715D #CJK UNIFIED IDEOGRAPH
+0xDE72 0x7162 #CJK UNIFIED IDEOGRAPH
+0xDE73 0x7172 #CJK UNIFIED IDEOGRAPH
+0xDE74 0x7178 #CJK UNIFIED IDEOGRAPH
+0xDE75 0x716A #CJK UNIFIED IDEOGRAPH
+0xDE76 0x7161 #CJK UNIFIED IDEOGRAPH
+0xDE77 0x7142 #CJK UNIFIED IDEOGRAPH
+0xDE78 0x7158 #CJK UNIFIED IDEOGRAPH
+0xDE79 0x7143 #CJK UNIFIED IDEOGRAPH
+0xDE7A 0x714B #CJK UNIFIED IDEOGRAPH
+0xDE7B 0x7170 #CJK UNIFIED IDEOGRAPH
+0xDE7C 0x715F #CJK UNIFIED IDEOGRAPH
+0xDE7D 0x7150 #CJK UNIFIED IDEOGRAPH
+0xDE7E 0x7153 #CJK UNIFIED IDEOGRAPH
+0xDEA1 0x7144 #CJK UNIFIED IDEOGRAPH
+0xDEA2 0x714D #CJK UNIFIED IDEOGRAPH
+0xDEA3 0x715A #CJK UNIFIED IDEOGRAPH
+0xDEA4 0x724F #CJK UNIFIED IDEOGRAPH
+0xDEA5 0x728D #CJK UNIFIED IDEOGRAPH
+0xDEA6 0x728C #CJK UNIFIED IDEOGRAPH
+0xDEA7 0x7291 #CJK UNIFIED IDEOGRAPH
+0xDEA8 0x7290 #CJK UNIFIED IDEOGRAPH
+0xDEA9 0x728E #CJK UNIFIED IDEOGRAPH
+0xDEAA 0x733C #CJK UNIFIED IDEOGRAPH
+0xDEAB 0x7342 #CJK UNIFIED IDEOGRAPH
+0xDEAC 0x733B #CJK UNIFIED IDEOGRAPH
+0xDEAD 0x733A #CJK UNIFIED IDEOGRAPH
+0xDEAE 0x7340 #CJK UNIFIED IDEOGRAPH
+0xDEAF 0x734A #CJK UNIFIED IDEOGRAPH
+0xDEB0 0x7349 #CJK UNIFIED IDEOGRAPH
+0xDEB1 0x7444 #CJK UNIFIED IDEOGRAPH
+0xDEB2 0x744A #CJK UNIFIED IDEOGRAPH
+0xDEB3 0x744B #CJK UNIFIED IDEOGRAPH
+0xDEB4 0x7452 #CJK UNIFIED IDEOGRAPH
+0xDEB5 0x7451 #CJK UNIFIED IDEOGRAPH
+0xDEB6 0x7457 #CJK UNIFIED IDEOGRAPH
+0xDEB7 0x7440 #CJK UNIFIED IDEOGRAPH
+0xDEB8 0x744F #CJK UNIFIED IDEOGRAPH
+0xDEB9 0x7450 #CJK UNIFIED IDEOGRAPH
+0xDEBA 0x744E #CJK UNIFIED IDEOGRAPH
+0xDEBB 0x7442 #CJK UNIFIED IDEOGRAPH
+0xDEBC 0x7446 #CJK UNIFIED IDEOGRAPH
+0xDEBD 0x744D #CJK UNIFIED IDEOGRAPH
+0xDEBE 0x7454 #CJK UNIFIED IDEOGRAPH
+0xDEBF 0x74E1 #CJK UNIFIED IDEOGRAPH
+0xDEC0 0x74FF #CJK UNIFIED IDEOGRAPH
+0xDEC1 0x74FE #CJK UNIFIED IDEOGRAPH
+0xDEC2 0x74FD #CJK UNIFIED IDEOGRAPH
+0xDEC3 0x751D #CJK UNIFIED IDEOGRAPH
+0xDEC4 0x7579 #CJK UNIFIED IDEOGRAPH
+0xDEC5 0x7577 #CJK UNIFIED IDEOGRAPH
+0xDEC6 0x6983 #CJK UNIFIED IDEOGRAPH
+0xDEC7 0x75EF #CJK UNIFIED IDEOGRAPH
+0xDEC8 0x760F #CJK UNIFIED IDEOGRAPH
+0xDEC9 0x7603 #CJK UNIFIED IDEOGRAPH
+0xDECA 0x75F7 #CJK UNIFIED IDEOGRAPH
+0xDECB 0x75FE #CJK UNIFIED IDEOGRAPH
+0xDECC 0x75FC #CJK UNIFIED IDEOGRAPH
+0xDECD 0x75F9 #CJK UNIFIED IDEOGRAPH
+0xDECE 0x75F8 #CJK UNIFIED IDEOGRAPH
+0xDECF 0x7610 #CJK UNIFIED IDEOGRAPH
+0xDED0 0x75FB #CJK UNIFIED IDEOGRAPH
+0xDED1 0x75F6 #CJK UNIFIED IDEOGRAPH
+0xDED2 0x75ED #CJK UNIFIED IDEOGRAPH
+0xDED3 0x75F5 #CJK UNIFIED IDEOGRAPH
+0xDED4 0x75FD #CJK UNIFIED IDEOGRAPH
+0xDED5 0x7699 #CJK UNIFIED IDEOGRAPH
+0xDED6 0x76B5 #CJK UNIFIED IDEOGRAPH
+0xDED7 0x76DD #CJK UNIFIED IDEOGRAPH
+0xDED8 0x7755 #CJK UNIFIED IDEOGRAPH
+0xDED9 0x775F #CJK UNIFIED IDEOGRAPH
+0xDEDA 0x7760 #CJK UNIFIED IDEOGRAPH
+0xDEDB 0x7752 #CJK UNIFIED IDEOGRAPH
+0xDEDC 0x7756 #CJK UNIFIED IDEOGRAPH
+0xDEDD 0x775A #CJK UNIFIED IDEOGRAPH
+0xDEDE 0x7769 #CJK UNIFIED IDEOGRAPH
+0xDEDF 0x7767 #CJK UNIFIED IDEOGRAPH
+0xDEE0 0x7754 #CJK UNIFIED IDEOGRAPH
+0xDEE1 0x7759 #CJK UNIFIED IDEOGRAPH
+0xDEE2 0x776D #CJK UNIFIED IDEOGRAPH
+0xDEE3 0x77E0 #CJK UNIFIED IDEOGRAPH
+0xDEE4 0x7887 #CJK UNIFIED IDEOGRAPH
+0xDEE5 0x789A #CJK UNIFIED IDEOGRAPH
+0xDEE6 0x7894 #CJK UNIFIED IDEOGRAPH
+0xDEE7 0x788F #CJK UNIFIED IDEOGRAPH
+0xDEE8 0x7884 #CJK UNIFIED IDEOGRAPH
+0xDEE9 0x7895 #CJK UNIFIED IDEOGRAPH
+0xDEEA 0x7885 #CJK UNIFIED IDEOGRAPH
+0xDEEB 0x7886 #CJK UNIFIED IDEOGRAPH
+0xDEEC 0x78A1 #CJK UNIFIED IDEOGRAPH
+0xDEED 0x7883 #CJK UNIFIED IDEOGRAPH
+0xDEEE 0x7879 #CJK UNIFIED IDEOGRAPH
+0xDEEF 0x7899 #CJK UNIFIED IDEOGRAPH
+0xDEF0 0x7880 #CJK UNIFIED IDEOGRAPH
+0xDEF1 0x7896 #CJK UNIFIED IDEOGRAPH
+0xDEF2 0x787B #CJK UNIFIED IDEOGRAPH
+0xDEF3 0x797C #CJK UNIFIED IDEOGRAPH
+0xDEF4 0x7982 #CJK UNIFIED IDEOGRAPH
+0xDEF5 0x797D #CJK UNIFIED IDEOGRAPH
+0xDEF6 0x7979 #CJK UNIFIED IDEOGRAPH
+0xDEF7 0x7A11 #CJK UNIFIED IDEOGRAPH
+0xDEF8 0x7A18 #CJK UNIFIED IDEOGRAPH
+0xDEF9 0x7A19 #CJK UNIFIED IDEOGRAPH
+0xDEFA 0x7A12 #CJK UNIFIED IDEOGRAPH
+0xDEFB 0x7A17 #CJK UNIFIED IDEOGRAPH
+0xDEFC 0x7A15 #CJK UNIFIED IDEOGRAPH
+0xDEFD 0x7A22 #CJK UNIFIED IDEOGRAPH
+0xDEFE 0x7A13 #CJK UNIFIED IDEOGRAPH
+0xDF40 0x7A1B #CJK UNIFIED IDEOGRAPH
+0xDF41 0x7A10 #CJK UNIFIED IDEOGRAPH
+0xDF42 0x7AA3 #CJK UNIFIED IDEOGRAPH
+0xDF43 0x7AA2 #CJK UNIFIED IDEOGRAPH
+0xDF44 0x7A9E #CJK UNIFIED IDEOGRAPH
+0xDF45 0x7AEB #CJK UNIFIED IDEOGRAPH
+0xDF46 0x7B66 #CJK UNIFIED IDEOGRAPH
+0xDF47 0x7B64 #CJK UNIFIED IDEOGRAPH
+0xDF48 0x7B6D #CJK UNIFIED IDEOGRAPH
+0xDF49 0x7B74 #CJK UNIFIED IDEOGRAPH
+0xDF4A 0x7B69 #CJK UNIFIED IDEOGRAPH
+0xDF4B 0x7B72 #CJK UNIFIED IDEOGRAPH
+0xDF4C 0x7B65 #CJK UNIFIED IDEOGRAPH
+0xDF4D 0x7B73 #CJK UNIFIED IDEOGRAPH
+0xDF4E 0x7B71 #CJK UNIFIED IDEOGRAPH
+0xDF4F 0x7B70 #CJK UNIFIED IDEOGRAPH
+0xDF50 0x7B61 #CJK UNIFIED IDEOGRAPH
+0xDF51 0x7B78 #CJK UNIFIED IDEOGRAPH
+0xDF52 0x7B76 #CJK UNIFIED IDEOGRAPH
+0xDF53 0x7B63 #CJK UNIFIED IDEOGRAPH
+0xDF54 0x7CB2 #CJK UNIFIED IDEOGRAPH
+0xDF55 0x7CB4 #CJK UNIFIED IDEOGRAPH
+0xDF56 0x7CAF #CJK UNIFIED IDEOGRAPH
+0xDF57 0x7D88 #CJK UNIFIED IDEOGRAPH
+0xDF58 0x7D86 #CJK UNIFIED IDEOGRAPH
+0xDF59 0x7D80 #CJK UNIFIED IDEOGRAPH
+0xDF5A 0x7D8D #CJK UNIFIED IDEOGRAPH
+0xDF5B 0x7D7F #CJK UNIFIED IDEOGRAPH
+0xDF5C 0x7D85 #CJK UNIFIED IDEOGRAPH
+0xDF5D 0x7D7A #CJK UNIFIED IDEOGRAPH
+0xDF5E 0x7D8E #CJK UNIFIED IDEOGRAPH
+0xDF5F 0x7D7B #CJK UNIFIED IDEOGRAPH
+0xDF60 0x7D83 #CJK UNIFIED IDEOGRAPH
+0xDF61 0x7D7C #CJK UNIFIED IDEOGRAPH
+0xDF62 0x7D8C #CJK UNIFIED IDEOGRAPH
+0xDF63 0x7D94 #CJK UNIFIED IDEOGRAPH
+0xDF64 0x7D84 #CJK UNIFIED IDEOGRAPH
+0xDF65 0x7D7D #CJK UNIFIED IDEOGRAPH
+0xDF66 0x7D92 #CJK UNIFIED IDEOGRAPH
+0xDF67 0x7F6D #CJK UNIFIED IDEOGRAPH
+0xDF68 0x7F6B #CJK UNIFIED IDEOGRAPH
+0xDF69 0x7F67 #CJK UNIFIED IDEOGRAPH
+0xDF6A 0x7F68 #CJK UNIFIED IDEOGRAPH
+0xDF6B 0x7F6C #CJK UNIFIED IDEOGRAPH
+0xDF6C 0x7FA6 #CJK UNIFIED IDEOGRAPH
+0xDF6D 0x7FA5 #CJK UNIFIED IDEOGRAPH
+0xDF6E 0x7FA7 #CJK UNIFIED IDEOGRAPH
+0xDF6F 0x7FDB #CJK UNIFIED IDEOGRAPH
+0xDF70 0x7FDC #CJK UNIFIED IDEOGRAPH
+0xDF71 0x8021 #CJK UNIFIED IDEOGRAPH
+0xDF72 0x8164 #CJK UNIFIED IDEOGRAPH
+0xDF73 0x8160 #CJK UNIFIED IDEOGRAPH
+0xDF74 0x8177 #CJK UNIFIED IDEOGRAPH
+0xDF75 0x815C #CJK UNIFIED IDEOGRAPH
+0xDF76 0x8169 #CJK UNIFIED IDEOGRAPH
+0xDF77 0x815B #CJK UNIFIED IDEOGRAPH
+0xDF78 0x8162 #CJK UNIFIED IDEOGRAPH
+0xDF79 0x8172 #CJK UNIFIED IDEOGRAPH
+0xDF7A 0x6721 #CJK UNIFIED IDEOGRAPH
+0xDF7B 0x815E #CJK UNIFIED IDEOGRAPH
+0xDF7C 0x8176 #CJK UNIFIED IDEOGRAPH
+0xDF7D 0x8167 #CJK UNIFIED IDEOGRAPH
+0xDF7E 0x816F #CJK UNIFIED IDEOGRAPH
+0xDFA1 0x8144 #CJK UNIFIED IDEOGRAPH
+0xDFA2 0x8161 #CJK UNIFIED IDEOGRAPH
+0xDFA3 0x821D #CJK UNIFIED IDEOGRAPH
+0xDFA4 0x8249 #CJK UNIFIED IDEOGRAPH
+0xDFA5 0x8244 #CJK UNIFIED IDEOGRAPH
+0xDFA6 0x8240 #CJK UNIFIED IDEOGRAPH
+0xDFA7 0x8242 #CJK UNIFIED IDEOGRAPH
+0xDFA8 0x8245 #CJK UNIFIED IDEOGRAPH
+0xDFA9 0x84F1 #CJK UNIFIED IDEOGRAPH
+0xDFAA 0x843F #CJK UNIFIED IDEOGRAPH
+0xDFAB 0x8456 #CJK UNIFIED IDEOGRAPH
+0xDFAC 0x8476 #CJK UNIFIED IDEOGRAPH
+0xDFAD 0x8479 #CJK UNIFIED IDEOGRAPH
+0xDFAE 0x848F #CJK UNIFIED IDEOGRAPH
+0xDFAF 0x848D #CJK UNIFIED IDEOGRAPH
+0xDFB0 0x8465 #CJK UNIFIED IDEOGRAPH
+0xDFB1 0x8451 #CJK UNIFIED IDEOGRAPH
+0xDFB2 0x8440 #CJK UNIFIED IDEOGRAPH
+0xDFB3 0x8486 #CJK UNIFIED IDEOGRAPH
+0xDFB4 0x8467 #CJK UNIFIED IDEOGRAPH
+0xDFB5 0x8430 #CJK UNIFIED IDEOGRAPH
+0xDFB6 0x844D #CJK UNIFIED IDEOGRAPH
+0xDFB7 0x847D #CJK UNIFIED IDEOGRAPH
+0xDFB8 0x845A #CJK UNIFIED IDEOGRAPH
+0xDFB9 0x8459 #CJK UNIFIED IDEOGRAPH
+0xDFBA 0x8474 #CJK UNIFIED IDEOGRAPH
+0xDFBB 0x8473 #CJK UNIFIED IDEOGRAPH
+0xDFBC 0x845D #CJK UNIFIED IDEOGRAPH
+0xDFBD 0x8507 #CJK UNIFIED IDEOGRAPH
+0xDFBE 0x845E #CJK UNIFIED IDEOGRAPH
+0xDFBF 0x8437 #CJK UNIFIED IDEOGRAPH
+0xDFC0 0x843A #CJK UNIFIED IDEOGRAPH
+0xDFC1 0x8434 #CJK UNIFIED IDEOGRAPH
+0xDFC2 0x847A #CJK UNIFIED IDEOGRAPH
+0xDFC3 0x8443 #CJK UNIFIED IDEOGRAPH
+0xDFC4 0x8478 #CJK UNIFIED IDEOGRAPH
+0xDFC5 0x8432 #CJK UNIFIED IDEOGRAPH
+0xDFC6 0x8445 #CJK UNIFIED IDEOGRAPH
+0xDFC7 0x8429 #CJK UNIFIED IDEOGRAPH
+0xDFC8 0x83D9 #CJK UNIFIED IDEOGRAPH
+0xDFC9 0x844B #CJK UNIFIED IDEOGRAPH
+0xDFCA 0x842F #CJK UNIFIED IDEOGRAPH
+0xDFCB 0x8442 #CJK UNIFIED IDEOGRAPH
+0xDFCC 0x842D #CJK UNIFIED IDEOGRAPH
+0xDFCD 0x845F #CJK UNIFIED IDEOGRAPH
+0xDFCE 0x8470 #CJK UNIFIED IDEOGRAPH
+0xDFCF 0x8439 #CJK UNIFIED IDEOGRAPH
+0xDFD0 0x844E #CJK UNIFIED IDEOGRAPH
+0xDFD1 0x844C #CJK UNIFIED IDEOGRAPH
+0xDFD2 0x8452 #CJK UNIFIED IDEOGRAPH
+0xDFD3 0x846F #CJK UNIFIED IDEOGRAPH
+0xDFD4 0x84C5 #CJK UNIFIED IDEOGRAPH
+0xDFD5 0x848E #CJK UNIFIED IDEOGRAPH
+0xDFD6 0x843B #CJK UNIFIED IDEOGRAPH
+0xDFD7 0x8447 #CJK UNIFIED IDEOGRAPH
+0xDFD8 0x8436 #CJK UNIFIED IDEOGRAPH
+0xDFD9 0x8433 #CJK UNIFIED IDEOGRAPH
+0xDFDA 0x8468 #CJK UNIFIED IDEOGRAPH
+0xDFDB 0x847E #CJK UNIFIED IDEOGRAPH
+0xDFDC 0x8444 #CJK UNIFIED IDEOGRAPH
+0xDFDD 0x842B #CJK UNIFIED IDEOGRAPH
+0xDFDE 0x8460 #CJK UNIFIED IDEOGRAPH
+0xDFDF 0x8454 #CJK UNIFIED IDEOGRAPH
+0xDFE0 0x846E #CJK UNIFIED IDEOGRAPH
+0xDFE1 0x8450 #CJK UNIFIED IDEOGRAPH
+0xDFE2 0x870B #CJK UNIFIED IDEOGRAPH
+0xDFE3 0x8704 #CJK UNIFIED IDEOGRAPH
+0xDFE4 0x86F7 #CJK UNIFIED IDEOGRAPH
+0xDFE5 0x870C #CJK UNIFIED IDEOGRAPH
+0xDFE6 0x86FA #CJK UNIFIED IDEOGRAPH
+0xDFE7 0x86D6 #CJK UNIFIED IDEOGRAPH
+0xDFE8 0x86F5 #CJK UNIFIED IDEOGRAPH
+0xDFE9 0x874D #CJK UNIFIED IDEOGRAPH
+0xDFEA 0x86F8 #CJK UNIFIED IDEOGRAPH
+0xDFEB 0x870E #CJK UNIFIED IDEOGRAPH
+0xDFEC 0x8709 #CJK UNIFIED IDEOGRAPH
+0xDFED 0x8701 #CJK UNIFIED IDEOGRAPH
+0xDFEE 0x86F6 #CJK UNIFIED IDEOGRAPH
+0xDFEF 0x870D #CJK UNIFIED IDEOGRAPH
+0xDFF0 0x8705 #CJK UNIFIED IDEOGRAPH
+0xDFF1 0x88D6 #CJK UNIFIED IDEOGRAPH
+0xDFF2 0x88CB #CJK UNIFIED IDEOGRAPH
+0xDFF3 0x88CD #CJK UNIFIED IDEOGRAPH
+0xDFF4 0x88CE #CJK UNIFIED IDEOGRAPH
+0xDFF5 0x88DE #CJK UNIFIED IDEOGRAPH
+0xDFF6 0x88DB #CJK UNIFIED IDEOGRAPH
+0xDFF7 0x88DA #CJK UNIFIED IDEOGRAPH
+0xDFF8 0x88CC #CJK UNIFIED IDEOGRAPH
+0xDFF9 0x88D0 #CJK UNIFIED IDEOGRAPH
+0xDFFA 0x8985 #CJK UNIFIED IDEOGRAPH
+0xDFFB 0x899B #CJK UNIFIED IDEOGRAPH
+0xDFFC 0x89DF #CJK UNIFIED IDEOGRAPH
+0xDFFD 0x89E5 #CJK UNIFIED IDEOGRAPH
+0xDFFE 0x89E4 #CJK UNIFIED IDEOGRAPH
+0xE040 0x89E1 #CJK UNIFIED IDEOGRAPH
+0xE041 0x89E0 #CJK UNIFIED IDEOGRAPH
+0xE042 0x89E2 #CJK UNIFIED IDEOGRAPH
+0xE043 0x89DC #CJK UNIFIED IDEOGRAPH
+0xE044 0x89E6 #CJK UNIFIED IDEOGRAPH
+0xE045 0x8A76 #CJK UNIFIED IDEOGRAPH
+0xE046 0x8A86 #CJK UNIFIED IDEOGRAPH
+0xE047 0x8A7F #CJK UNIFIED IDEOGRAPH
+0xE048 0x8A61 #CJK UNIFIED IDEOGRAPH
+0xE049 0x8A3F #CJK UNIFIED IDEOGRAPH
+0xE04A 0x8A77 #CJK UNIFIED IDEOGRAPH
+0xE04B 0x8A82 #CJK UNIFIED IDEOGRAPH
+0xE04C 0x8A84 #CJK UNIFIED IDEOGRAPH
+0xE04D 0x8A75 #CJK UNIFIED IDEOGRAPH
+0xE04E 0x8A83 #CJK UNIFIED IDEOGRAPH
+0xE04F 0x8A81 #CJK UNIFIED IDEOGRAPH
+0xE050 0x8A74 #CJK UNIFIED IDEOGRAPH
+0xE051 0x8A7A #CJK UNIFIED IDEOGRAPH
+0xE052 0x8C3C #CJK UNIFIED IDEOGRAPH
+0xE053 0x8C4B #CJK UNIFIED IDEOGRAPH
+0xE054 0x8C4A #CJK UNIFIED IDEOGRAPH
+0xE055 0x8C65 #CJK UNIFIED IDEOGRAPH
+0xE056 0x8C64 #CJK UNIFIED IDEOGRAPH
+0xE057 0x8C66 #CJK UNIFIED IDEOGRAPH
+0xE058 0x8C86 #CJK UNIFIED IDEOGRAPH
+0xE059 0x8C84 #CJK UNIFIED IDEOGRAPH
+0xE05A 0x8C85 #CJK UNIFIED IDEOGRAPH
+0xE05B 0x8CCC #CJK UNIFIED IDEOGRAPH
+0xE05C 0x8D68 #CJK UNIFIED IDEOGRAPH
+0xE05D 0x8D69 #CJK UNIFIED IDEOGRAPH
+0xE05E 0x8D91 #CJK UNIFIED IDEOGRAPH
+0xE05F 0x8D8C #CJK UNIFIED IDEOGRAPH
+0xE060 0x8D8E #CJK UNIFIED IDEOGRAPH
+0xE061 0x8D8F #CJK UNIFIED IDEOGRAPH
+0xE062 0x8D8D #CJK UNIFIED IDEOGRAPH
+0xE063 0x8D93 #CJK UNIFIED IDEOGRAPH
+0xE064 0x8D94 #CJK UNIFIED IDEOGRAPH
+0xE065 0x8D90 #CJK UNIFIED IDEOGRAPH
+0xE066 0x8D92 #CJK UNIFIED IDEOGRAPH
+0xE067 0x8DF0 #CJK UNIFIED IDEOGRAPH
+0xE068 0x8DE0 #CJK UNIFIED IDEOGRAPH
+0xE069 0x8DEC #CJK UNIFIED IDEOGRAPH
+0xE06A 0x8DF1 #CJK UNIFIED IDEOGRAPH
+0xE06B 0x8DEE #CJK UNIFIED IDEOGRAPH
+0xE06C 0x8DD0 #CJK UNIFIED IDEOGRAPH
+0xE06D 0x8DE9 #CJK UNIFIED IDEOGRAPH
+0xE06E 0x8DE3 #CJK UNIFIED IDEOGRAPH
+0xE06F 0x8DE2 #CJK UNIFIED IDEOGRAPH
+0xE070 0x8DE7 #CJK UNIFIED IDEOGRAPH
+0xE071 0x8DF2 #CJK UNIFIED IDEOGRAPH
+0xE072 0x8DEB #CJK UNIFIED IDEOGRAPH
+0xE073 0x8DF4 #CJK UNIFIED IDEOGRAPH
+0xE074 0x8F06 #CJK UNIFIED IDEOGRAPH
+0xE075 0x8EFF #CJK UNIFIED IDEOGRAPH
+0xE076 0x8F01 #CJK UNIFIED IDEOGRAPH
+0xE077 0x8F00 #CJK UNIFIED IDEOGRAPH
+0xE078 0x8F05 #CJK UNIFIED IDEOGRAPH
+0xE079 0x8F07 #CJK UNIFIED IDEOGRAPH
+0xE07A 0x8F08 #CJK UNIFIED IDEOGRAPH
+0xE07B 0x8F02 #CJK UNIFIED IDEOGRAPH
+0xE07C 0x8F0B #CJK UNIFIED IDEOGRAPH
+0xE07D 0x9052 #CJK UNIFIED IDEOGRAPH
+0xE07E 0x903F #CJK UNIFIED IDEOGRAPH
+0xE0A1 0x9044 #CJK UNIFIED IDEOGRAPH
+0xE0A2 0x9049 #CJK UNIFIED IDEOGRAPH
+0xE0A3 0x903D #CJK UNIFIED IDEOGRAPH
+0xE0A4 0x9110 #CJK UNIFIED IDEOGRAPH
+0xE0A5 0x910D #CJK UNIFIED IDEOGRAPH
+0xE0A6 0x910F #CJK UNIFIED IDEOGRAPH
+0xE0A7 0x9111 #CJK UNIFIED IDEOGRAPH
+0xE0A8 0x9116 #CJK UNIFIED IDEOGRAPH
+0xE0A9 0x9114 #CJK UNIFIED IDEOGRAPH
+0xE0AA 0x910B #CJK UNIFIED IDEOGRAPH
+0xE0AB 0x910E #CJK UNIFIED IDEOGRAPH
+0xE0AC 0x916E #CJK UNIFIED IDEOGRAPH
+0xE0AD 0x916F #CJK UNIFIED IDEOGRAPH
+0xE0AE 0x9248 #CJK UNIFIED IDEOGRAPH
+0xE0AF 0x9252 #CJK UNIFIED IDEOGRAPH
+0xE0B0 0x9230 #CJK UNIFIED IDEOGRAPH
+0xE0B1 0x923A #CJK UNIFIED IDEOGRAPH
+0xE0B2 0x9266 #CJK UNIFIED IDEOGRAPH
+0xE0B3 0x9233 #CJK UNIFIED IDEOGRAPH
+0xE0B4 0x9265 #CJK UNIFIED IDEOGRAPH
+0xE0B5 0x925E #CJK UNIFIED IDEOGRAPH
+0xE0B6 0x9283 #CJK UNIFIED IDEOGRAPH
+0xE0B7 0x922E #CJK UNIFIED IDEOGRAPH
+0xE0B8 0x924A #CJK UNIFIED IDEOGRAPH
+0xE0B9 0x9246 #CJK UNIFIED IDEOGRAPH
+0xE0BA 0x926D #CJK UNIFIED IDEOGRAPH
+0xE0BB 0x926C #CJK UNIFIED IDEOGRAPH
+0xE0BC 0x924F #CJK UNIFIED IDEOGRAPH
+0xE0BD 0x9260 #CJK UNIFIED IDEOGRAPH
+0xE0BE 0x9267 #CJK UNIFIED IDEOGRAPH
+0xE0BF 0x926F #CJK UNIFIED IDEOGRAPH
+0xE0C0 0x9236 #CJK UNIFIED IDEOGRAPH
+0xE0C1 0x9261 #CJK UNIFIED IDEOGRAPH
+0xE0C2 0x9270 #CJK UNIFIED IDEOGRAPH
+0xE0C3 0x9231 #CJK UNIFIED IDEOGRAPH
+0xE0C4 0x9254 #CJK UNIFIED IDEOGRAPH
+0xE0C5 0x9263 #CJK UNIFIED IDEOGRAPH
+0xE0C6 0x9250 #CJK UNIFIED IDEOGRAPH
+0xE0C7 0x9272 #CJK UNIFIED IDEOGRAPH
+0xE0C8 0x924E #CJK UNIFIED IDEOGRAPH
+0xE0C9 0x9253 #CJK UNIFIED IDEOGRAPH
+0xE0CA 0x924C #CJK UNIFIED IDEOGRAPH
+0xE0CB 0x9256 #CJK UNIFIED IDEOGRAPH
+0xE0CC 0x9232 #CJK UNIFIED IDEOGRAPH
+0xE0CD 0x959F #CJK UNIFIED IDEOGRAPH
+0xE0CE 0x959C #CJK UNIFIED IDEOGRAPH
+0xE0CF 0x959E #CJK UNIFIED IDEOGRAPH
+0xE0D0 0x959B #CJK UNIFIED IDEOGRAPH
+0xE0D1 0x9692 #CJK UNIFIED IDEOGRAPH
+0xE0D2 0x9693 #CJK UNIFIED IDEOGRAPH
+0xE0D3 0x9691 #CJK UNIFIED IDEOGRAPH
+0xE0D4 0x9697 #CJK UNIFIED IDEOGRAPH
+0xE0D5 0x96CE #CJK UNIFIED IDEOGRAPH
+0xE0D6 0x96FA #CJK UNIFIED IDEOGRAPH
+0xE0D7 0x96FD #CJK UNIFIED IDEOGRAPH
+0xE0D8 0x96F8 #CJK UNIFIED IDEOGRAPH
+0xE0D9 0x96F5 #CJK UNIFIED IDEOGRAPH
+0xE0DA 0x9773 #CJK UNIFIED IDEOGRAPH
+0xE0DB 0x9777 #CJK UNIFIED IDEOGRAPH
+0xE0DC 0x9778 #CJK UNIFIED IDEOGRAPH
+0xE0DD 0x9772 #CJK UNIFIED IDEOGRAPH
+0xE0DE 0x980F #CJK UNIFIED IDEOGRAPH
+0xE0DF 0x980D #CJK UNIFIED IDEOGRAPH
+0xE0E0 0x980E #CJK UNIFIED IDEOGRAPH
+0xE0E1 0x98AC #CJK UNIFIED IDEOGRAPH
+0xE0E2 0x98F6 #CJK UNIFIED IDEOGRAPH
+0xE0E3 0x98F9 #CJK UNIFIED IDEOGRAPH
+0xE0E4 0x99AF #CJK UNIFIED IDEOGRAPH
+0xE0E5 0x99B2 #CJK UNIFIED IDEOGRAPH
+0xE0E6 0x99B0 #CJK UNIFIED IDEOGRAPH
+0xE0E7 0x99B5 #CJK UNIFIED IDEOGRAPH
+0xE0E8 0x9AAD #CJK UNIFIED IDEOGRAPH
+0xE0E9 0x9AAB #CJK UNIFIED IDEOGRAPH
+0xE0EA 0x9B5B #CJK UNIFIED IDEOGRAPH
+0xE0EB 0x9CEA #CJK UNIFIED IDEOGRAPH
+0xE0EC 0x9CED #CJK UNIFIED IDEOGRAPH
+0xE0ED 0x9CE7 #CJK UNIFIED IDEOGRAPH
+0xE0EE 0x9E80 #CJK UNIFIED IDEOGRAPH
+0xE0EF 0x9EFD #CJK UNIFIED IDEOGRAPH
+0xE0F0 0x50E6 #CJK UNIFIED IDEOGRAPH
+0xE0F1 0x50D4 #CJK UNIFIED IDEOGRAPH
+0xE0F2 0x50D7 #CJK UNIFIED IDEOGRAPH
+0xE0F3 0x50E8 #CJK UNIFIED IDEOGRAPH
+0xE0F4 0x50F3 #CJK UNIFIED IDEOGRAPH
+0xE0F5 0x50DB #CJK UNIFIED IDEOGRAPH
+0xE0F6 0x50EA #CJK UNIFIED IDEOGRAPH
+0xE0F7 0x50DD #CJK UNIFIED IDEOGRAPH
+0xE0F8 0x50E4 #CJK UNIFIED IDEOGRAPH
+0xE0F9 0x50D3 #CJK UNIFIED IDEOGRAPH
+0xE0FA 0x50EC #CJK UNIFIED IDEOGRAPH
+0xE0FB 0x50F0 #CJK UNIFIED IDEOGRAPH
+0xE0FC 0x50EF #CJK UNIFIED IDEOGRAPH
+0xE0FD 0x50E3 #CJK UNIFIED IDEOGRAPH
+0xE0FE 0x50E0 #CJK UNIFIED IDEOGRAPH
+0xE140 0x51D8 #CJK UNIFIED IDEOGRAPH
+0xE141 0x5280 #CJK UNIFIED IDEOGRAPH
+0xE142 0x5281 #CJK UNIFIED IDEOGRAPH
+0xE143 0x52E9 #CJK UNIFIED IDEOGRAPH
+0xE144 0x52EB #CJK UNIFIED IDEOGRAPH
+0xE145 0x5330 #CJK UNIFIED IDEOGRAPH
+0xE146 0x53AC #CJK UNIFIED IDEOGRAPH
+0xE147 0x5627 #CJK UNIFIED IDEOGRAPH
+0xE148 0x5615 #CJK UNIFIED IDEOGRAPH
+0xE149 0x560C #CJK UNIFIED IDEOGRAPH
+0xE14A 0x5612 #CJK UNIFIED IDEOGRAPH
+0xE14B 0x55FC #CJK UNIFIED IDEOGRAPH
+0xE14C 0x560F #CJK UNIFIED IDEOGRAPH
+0xE14D 0x561C #CJK UNIFIED IDEOGRAPH
+0xE14E 0x5601 #CJK UNIFIED IDEOGRAPH
+0xE14F 0x5613 #CJK UNIFIED IDEOGRAPH
+0xE150 0x5602 #CJK UNIFIED IDEOGRAPH
+0xE151 0x55FA #CJK UNIFIED IDEOGRAPH
+0xE152 0x561D #CJK UNIFIED IDEOGRAPH
+0xE153 0x5604 #CJK UNIFIED IDEOGRAPH
+0xE154 0x55FF #CJK UNIFIED IDEOGRAPH
+0xE155 0x55F9 #CJK UNIFIED IDEOGRAPH
+0xE156 0x5889 #CJK UNIFIED IDEOGRAPH
+0xE157 0x587C #CJK UNIFIED IDEOGRAPH
+0xE158 0x5890 #CJK UNIFIED IDEOGRAPH
+0xE159 0x5898 #CJK UNIFIED IDEOGRAPH
+0xE15A 0x5886 #CJK UNIFIED IDEOGRAPH
+0xE15B 0x5881 #CJK UNIFIED IDEOGRAPH
+0xE15C 0x587F #CJK UNIFIED IDEOGRAPH
+0xE15D 0x5874 #CJK UNIFIED IDEOGRAPH
+0xE15E 0x588B #CJK UNIFIED IDEOGRAPH
+0xE15F 0x587A #CJK UNIFIED IDEOGRAPH
+0xE160 0x5887 #CJK UNIFIED IDEOGRAPH
+0xE161 0x5891 #CJK UNIFIED IDEOGRAPH
+0xE162 0x588E #CJK UNIFIED IDEOGRAPH
+0xE163 0x5876 #CJK UNIFIED IDEOGRAPH
+0xE164 0x5882 #CJK UNIFIED IDEOGRAPH
+0xE165 0x5888 #CJK UNIFIED IDEOGRAPH
+0xE166 0x587B #CJK UNIFIED IDEOGRAPH
+0xE167 0x5894 #CJK UNIFIED IDEOGRAPH
+0xE168 0x588F #CJK UNIFIED IDEOGRAPH
+0xE169 0x58FE #CJK UNIFIED IDEOGRAPH
+0xE16A 0x596B #CJK UNIFIED IDEOGRAPH
+0xE16B 0x5ADC #CJK UNIFIED IDEOGRAPH
+0xE16C 0x5AEE #CJK UNIFIED IDEOGRAPH
+0xE16D 0x5AE5 #CJK UNIFIED IDEOGRAPH
+0xE16E 0x5AD5 #CJK UNIFIED IDEOGRAPH
+0xE16F 0x5AEA #CJK UNIFIED IDEOGRAPH
+0xE170 0x5ADA #CJK UNIFIED IDEOGRAPH
+0xE171 0x5AED #CJK UNIFIED IDEOGRAPH
+0xE172 0x5AEB #CJK UNIFIED IDEOGRAPH
+0xE173 0x5AF3 #CJK UNIFIED IDEOGRAPH
+0xE174 0x5AE2 #CJK UNIFIED IDEOGRAPH
+0xE175 0x5AE0 #CJK UNIFIED IDEOGRAPH
+0xE176 0x5ADB #CJK UNIFIED IDEOGRAPH
+0xE177 0x5AEC #CJK UNIFIED IDEOGRAPH
+0xE178 0x5ADE #CJK UNIFIED IDEOGRAPH
+0xE179 0x5ADD #CJK UNIFIED IDEOGRAPH
+0xE17A 0x5AD9 #CJK UNIFIED IDEOGRAPH
+0xE17B 0x5AE8 #CJK UNIFIED IDEOGRAPH
+0xE17C 0x5ADF #CJK UNIFIED IDEOGRAPH
+0xE17D 0x5B77 #CJK UNIFIED IDEOGRAPH
+0xE17E 0x5BE0 #CJK UNIFIED IDEOGRAPH
+0xE1A1 0x5BE3 #CJK UNIFIED IDEOGRAPH
+0xE1A2 0x5C63 #CJK UNIFIED IDEOGRAPH
+0xE1A3 0x5D82 #CJK UNIFIED IDEOGRAPH
+0xE1A4 0x5D80 #CJK UNIFIED IDEOGRAPH
+0xE1A5 0x5D7D #CJK UNIFIED IDEOGRAPH
+0xE1A6 0x5D86 #CJK UNIFIED IDEOGRAPH
+0xE1A7 0x5D7A #CJK UNIFIED IDEOGRAPH
+0xE1A8 0x5D81 #CJK UNIFIED IDEOGRAPH
+0xE1A9 0x5D77 #CJK UNIFIED IDEOGRAPH
+0xE1AA 0x5D8A #CJK UNIFIED IDEOGRAPH
+0xE1AB 0x5D89 #CJK UNIFIED IDEOGRAPH
+0xE1AC 0x5D88 #CJK UNIFIED IDEOGRAPH
+0xE1AD 0x5D7E #CJK UNIFIED IDEOGRAPH
+0xE1AE 0x5D7C #CJK UNIFIED IDEOGRAPH
+0xE1AF 0x5D8D #CJK UNIFIED IDEOGRAPH
+0xE1B0 0x5D79 #CJK UNIFIED IDEOGRAPH
+0xE1B1 0x5D7F #CJK UNIFIED IDEOGRAPH
+0xE1B2 0x5E58 #CJK UNIFIED IDEOGRAPH
+0xE1B3 0x5E59 #CJK UNIFIED IDEOGRAPH
+0xE1B4 0x5E53 #CJK UNIFIED IDEOGRAPH
+0xE1B5 0x5ED8 #CJK UNIFIED IDEOGRAPH
+0xE1B6 0x5ED1 #CJK UNIFIED IDEOGRAPH
+0xE1B7 0x5ED7 #CJK UNIFIED IDEOGRAPH
+0xE1B8 0x5ECE #CJK UNIFIED IDEOGRAPH
+0xE1B9 0x5EDC #CJK UNIFIED IDEOGRAPH
+0xE1BA 0x5ED5 #CJK UNIFIED IDEOGRAPH
+0xE1BB 0x5ED9 #CJK UNIFIED IDEOGRAPH
+0xE1BC 0x5ED2 #CJK UNIFIED IDEOGRAPH
+0xE1BD 0x5ED4 #CJK UNIFIED IDEOGRAPH
+0xE1BE 0x5F44 #CJK UNIFIED IDEOGRAPH
+0xE1BF 0x5F43 #CJK UNIFIED IDEOGRAPH
+0xE1C0 0x5F6F #CJK UNIFIED IDEOGRAPH
+0xE1C1 0x5FB6 #CJK UNIFIED IDEOGRAPH
+0xE1C2 0x612C #CJK UNIFIED IDEOGRAPH
+0xE1C3 0x6128 #CJK UNIFIED IDEOGRAPH
+0xE1C4 0x6141 #CJK UNIFIED IDEOGRAPH
+0xE1C5 0x615E #CJK UNIFIED IDEOGRAPH
+0xE1C6 0x6171 #CJK UNIFIED IDEOGRAPH
+0xE1C7 0x6173 #CJK UNIFIED IDEOGRAPH
+0xE1C8 0x6152 #CJK UNIFIED IDEOGRAPH
+0xE1C9 0x6153 #CJK UNIFIED IDEOGRAPH
+0xE1CA 0x6172 #CJK UNIFIED IDEOGRAPH
+0xE1CB 0x616C #CJK UNIFIED IDEOGRAPH
+0xE1CC 0x6180 #CJK UNIFIED IDEOGRAPH
+0xE1CD 0x6174 #CJK UNIFIED IDEOGRAPH
+0xE1CE 0x6154 #CJK UNIFIED IDEOGRAPH
+0xE1CF 0x617A #CJK UNIFIED IDEOGRAPH
+0xE1D0 0x615B #CJK UNIFIED IDEOGRAPH
+0xE1D1 0x6165 #CJK UNIFIED IDEOGRAPH
+0xE1D2 0x613B #CJK UNIFIED IDEOGRAPH
+0xE1D3 0x616A #CJK UNIFIED IDEOGRAPH
+0xE1D4 0x6161 #CJK UNIFIED IDEOGRAPH
+0xE1D5 0x6156 #CJK UNIFIED IDEOGRAPH
+0xE1D6 0x6229 #CJK UNIFIED IDEOGRAPH
+0xE1D7 0x6227 #CJK UNIFIED IDEOGRAPH
+0xE1D8 0x622B #CJK UNIFIED IDEOGRAPH
+0xE1D9 0x642B #CJK UNIFIED IDEOGRAPH
+0xE1DA 0x644D #CJK UNIFIED IDEOGRAPH
+0xE1DB 0x645B #CJK UNIFIED IDEOGRAPH
+0xE1DC 0x645D #CJK UNIFIED IDEOGRAPH
+0xE1DD 0x6474 #CJK UNIFIED IDEOGRAPH
+0xE1DE 0x6476 #CJK UNIFIED IDEOGRAPH
+0xE1DF 0x6472 #CJK UNIFIED IDEOGRAPH
+0xE1E0 0x6473 #CJK UNIFIED IDEOGRAPH
+0xE1E1 0x647D #CJK UNIFIED IDEOGRAPH
+0xE1E2 0x6475 #CJK UNIFIED IDEOGRAPH
+0xE1E3 0x6466 #CJK UNIFIED IDEOGRAPH
+0xE1E4 0x64A6 #CJK UNIFIED IDEOGRAPH
+0xE1E5 0x644E #CJK UNIFIED IDEOGRAPH
+0xE1E6 0x6482 #CJK UNIFIED IDEOGRAPH
+0xE1E7 0x645E #CJK UNIFIED IDEOGRAPH
+0xE1E8 0x645C #CJK UNIFIED IDEOGRAPH
+0xE1E9 0x644B #CJK UNIFIED IDEOGRAPH
+0xE1EA 0x6453 #CJK UNIFIED IDEOGRAPH
+0xE1EB 0x6460 #CJK UNIFIED IDEOGRAPH
+0xE1EC 0x6450 #CJK UNIFIED IDEOGRAPH
+0xE1ED 0x647F #CJK UNIFIED IDEOGRAPH
+0xE1EE 0x643F #CJK UNIFIED IDEOGRAPH
+0xE1EF 0x646C #CJK UNIFIED IDEOGRAPH
+0xE1F0 0x646B #CJK UNIFIED IDEOGRAPH
+0xE1F1 0x6459 #CJK UNIFIED IDEOGRAPH
+0xE1F2 0x6465 #CJK UNIFIED IDEOGRAPH
+0xE1F3 0x6477 #CJK UNIFIED IDEOGRAPH
+0xE1F4 0x6573 #CJK UNIFIED IDEOGRAPH
+0xE1F5 0x65A0 #CJK UNIFIED IDEOGRAPH
+0xE1F6 0x66A1 #CJK UNIFIED IDEOGRAPH
+0xE1F7 0x66A0 #CJK UNIFIED IDEOGRAPH
+0xE1F8 0x669F #CJK UNIFIED IDEOGRAPH
+0xE1F9 0x6705 #CJK UNIFIED IDEOGRAPH
+0xE1FA 0x6704 #CJK UNIFIED IDEOGRAPH
+0xE1FB 0x6722 #CJK UNIFIED IDEOGRAPH
+0xE1FC 0x69B1 #CJK UNIFIED IDEOGRAPH
+0xE1FD 0x69B6 #CJK UNIFIED IDEOGRAPH
+0xE1FE 0x69C9 #CJK UNIFIED IDEOGRAPH
+0xE240 0x69A0 #CJK UNIFIED IDEOGRAPH
+0xE241 0x69CE #CJK UNIFIED IDEOGRAPH
+0xE242 0x6996 #CJK UNIFIED IDEOGRAPH
+0xE243 0x69B0 #CJK UNIFIED IDEOGRAPH
+0xE244 0x69AC #CJK UNIFIED IDEOGRAPH
+0xE245 0x69BC #CJK UNIFIED IDEOGRAPH
+0xE246 0x6991 #CJK UNIFIED IDEOGRAPH
+0xE247 0x6999 #CJK UNIFIED IDEOGRAPH
+0xE248 0x698E #CJK UNIFIED IDEOGRAPH
+0xE249 0x69A7 #CJK UNIFIED IDEOGRAPH
+0xE24A 0x698D #CJK UNIFIED IDEOGRAPH
+0xE24B 0x69A9 #CJK UNIFIED IDEOGRAPH
+0xE24C 0x69BE #CJK UNIFIED IDEOGRAPH
+0xE24D 0x69AF #CJK UNIFIED IDEOGRAPH
+0xE24E 0x69BF #CJK UNIFIED IDEOGRAPH
+0xE24F 0x69C4 #CJK UNIFIED IDEOGRAPH
+0xE250 0x69BD #CJK UNIFIED IDEOGRAPH
+0xE251 0x69A4 #CJK UNIFIED IDEOGRAPH
+0xE252 0x69D4 #CJK UNIFIED IDEOGRAPH
+0xE253 0x69B9 #CJK UNIFIED IDEOGRAPH
+0xE254 0x69CA #CJK UNIFIED IDEOGRAPH
+0xE255 0x699A #CJK UNIFIED IDEOGRAPH
+0xE256 0x69CF #CJK UNIFIED IDEOGRAPH
+0xE257 0x69B3 #CJK UNIFIED IDEOGRAPH
+0xE258 0x6993 #CJK UNIFIED IDEOGRAPH
+0xE259 0x69AA #CJK UNIFIED IDEOGRAPH
+0xE25A 0x69A1 #CJK UNIFIED IDEOGRAPH
+0xE25B 0x699E #CJK UNIFIED IDEOGRAPH
+0xE25C 0x69D9 #CJK UNIFIED IDEOGRAPH
+0xE25D 0x6997 #CJK UNIFIED IDEOGRAPH
+0xE25E 0x6990 #CJK UNIFIED IDEOGRAPH
+0xE25F 0x69C2 #CJK UNIFIED IDEOGRAPH
+0xE260 0x69B5 #CJK UNIFIED IDEOGRAPH
+0xE261 0x69A5 #CJK UNIFIED IDEOGRAPH
+0xE262 0x69C6 #CJK UNIFIED IDEOGRAPH
+0xE263 0x6B4A #CJK UNIFIED IDEOGRAPH
+0xE264 0x6B4D #CJK UNIFIED IDEOGRAPH
+0xE265 0x6B4B #CJK UNIFIED IDEOGRAPH
+0xE266 0x6B9E #CJK UNIFIED IDEOGRAPH
+0xE267 0x6B9F #CJK UNIFIED IDEOGRAPH
+0xE268 0x6BA0 #CJK UNIFIED IDEOGRAPH
+0xE269 0x6BC3 #CJK UNIFIED IDEOGRAPH
+0xE26A 0x6BC4 #CJK UNIFIED IDEOGRAPH
+0xE26B 0x6BFE #CJK UNIFIED IDEOGRAPH
+0xE26C 0x6ECE #CJK UNIFIED IDEOGRAPH
+0xE26D 0x6EF5 #CJK UNIFIED IDEOGRAPH
+0xE26E 0x6EF1 #CJK UNIFIED IDEOGRAPH
+0xE26F 0x6F03 #CJK UNIFIED IDEOGRAPH
+0xE270 0x6F25 #CJK UNIFIED IDEOGRAPH
+0xE271 0x6EF8 #CJK UNIFIED IDEOGRAPH
+0xE272 0x6F37 #CJK UNIFIED IDEOGRAPH
+0xE273 0x6EFB #CJK UNIFIED IDEOGRAPH
+0xE274 0x6F2E #CJK UNIFIED IDEOGRAPH
+0xE275 0x6F09 #CJK UNIFIED IDEOGRAPH
+0xE276 0x6F4E #CJK UNIFIED IDEOGRAPH
+0xE277 0x6F19 #CJK UNIFIED IDEOGRAPH
+0xE278 0x6F1A #CJK UNIFIED IDEOGRAPH
+0xE279 0x6F27 #CJK UNIFIED IDEOGRAPH
+0xE27A 0x6F18 #CJK UNIFIED IDEOGRAPH
+0xE27B 0x6F3B #CJK UNIFIED IDEOGRAPH
+0xE27C 0x6F12 #CJK UNIFIED IDEOGRAPH
+0xE27D 0x6EED #CJK UNIFIED IDEOGRAPH
+0xE27E 0x6F0A #CJK UNIFIED IDEOGRAPH
+0xE2A1 0x6F36 #CJK UNIFIED IDEOGRAPH
+0xE2A2 0x6F73 #CJK UNIFIED IDEOGRAPH
+0xE2A3 0x6EF9 #CJK UNIFIED IDEOGRAPH
+0xE2A4 0x6EEE #CJK UNIFIED IDEOGRAPH
+0xE2A5 0x6F2D #CJK UNIFIED IDEOGRAPH
+0xE2A6 0x6F40 #CJK UNIFIED IDEOGRAPH
+0xE2A7 0x6F30 #CJK UNIFIED IDEOGRAPH
+0xE2A8 0x6F3C #CJK UNIFIED IDEOGRAPH
+0xE2A9 0x6F35 #CJK UNIFIED IDEOGRAPH
+0xE2AA 0x6EEB #CJK UNIFIED IDEOGRAPH
+0xE2AB 0x6F07 #CJK UNIFIED IDEOGRAPH
+0xE2AC 0x6F0E #CJK UNIFIED IDEOGRAPH
+0xE2AD 0x6F43 #CJK UNIFIED IDEOGRAPH
+0xE2AE 0x6F05 #CJK UNIFIED IDEOGRAPH
+0xE2AF 0x6EFD #CJK UNIFIED IDEOGRAPH
+0xE2B0 0x6EF6 #CJK UNIFIED IDEOGRAPH
+0xE2B1 0x6F39 #CJK UNIFIED IDEOGRAPH
+0xE2B2 0x6F1C #CJK UNIFIED IDEOGRAPH
+0xE2B3 0x6EFC #CJK UNIFIED IDEOGRAPH
+0xE2B4 0x6F3A #CJK UNIFIED IDEOGRAPH
+0xE2B5 0x6F1F #CJK UNIFIED IDEOGRAPH
+0xE2B6 0x6F0D #CJK UNIFIED IDEOGRAPH
+0xE2B7 0x6F1E #CJK UNIFIED IDEOGRAPH
+0xE2B8 0x6F08 #CJK UNIFIED IDEOGRAPH
+0xE2B9 0x6F21 #CJK UNIFIED IDEOGRAPH
+0xE2BA 0x7187 #CJK UNIFIED IDEOGRAPH
+0xE2BB 0x7190 #CJK UNIFIED IDEOGRAPH
+0xE2BC 0x7189 #CJK UNIFIED IDEOGRAPH
+0xE2BD 0x7180 #CJK UNIFIED IDEOGRAPH
+0xE2BE 0x7185 #CJK UNIFIED IDEOGRAPH
+0xE2BF 0x7182 #CJK UNIFIED IDEOGRAPH
+0xE2C0 0x718F #CJK UNIFIED IDEOGRAPH
+0xE2C1 0x717B #CJK UNIFIED IDEOGRAPH
+0xE2C2 0x7186 #CJK UNIFIED IDEOGRAPH
+0xE2C3 0x7181 #CJK UNIFIED IDEOGRAPH
+0xE2C4 0x7197 #CJK UNIFIED IDEOGRAPH
+0xE2C5 0x7244 #CJK UNIFIED IDEOGRAPH
+0xE2C6 0x7253 #CJK UNIFIED IDEOGRAPH
+0xE2C7 0x7297 #CJK UNIFIED IDEOGRAPH
+0xE2C8 0x7295 #CJK UNIFIED IDEOGRAPH
+0xE2C9 0x7293 #CJK UNIFIED IDEOGRAPH
+0xE2CA 0x7343 #CJK UNIFIED IDEOGRAPH
+0xE2CB 0x734D #CJK UNIFIED IDEOGRAPH
+0xE2CC 0x7351 #CJK UNIFIED IDEOGRAPH
+0xE2CD 0x734C #CJK UNIFIED IDEOGRAPH
+0xE2CE 0x7462 #CJK UNIFIED IDEOGRAPH
+0xE2CF 0x7473 #CJK UNIFIED IDEOGRAPH
+0xE2D0 0x7471 #CJK UNIFIED IDEOGRAPH
+0xE2D1 0x7475 #CJK UNIFIED IDEOGRAPH
+0xE2D2 0x7472 #CJK UNIFIED IDEOGRAPH
+0xE2D3 0x7467 #CJK UNIFIED IDEOGRAPH
+0xE2D4 0x746E #CJK UNIFIED IDEOGRAPH
+0xE2D5 0x7500 #CJK UNIFIED IDEOGRAPH
+0xE2D6 0x7502 #CJK UNIFIED IDEOGRAPH
+0xE2D7 0x7503 #CJK UNIFIED IDEOGRAPH
+0xE2D8 0x757D #CJK UNIFIED IDEOGRAPH
+0xE2D9 0x7590 #CJK UNIFIED IDEOGRAPH
+0xE2DA 0x7616 #CJK UNIFIED IDEOGRAPH
+0xE2DB 0x7608 #CJK UNIFIED IDEOGRAPH
+0xE2DC 0x760C #CJK UNIFIED IDEOGRAPH
+0xE2DD 0x7615 #CJK UNIFIED IDEOGRAPH
+0xE2DE 0x7611 #CJK UNIFIED IDEOGRAPH
+0xE2DF 0x760A #CJK UNIFIED IDEOGRAPH
+0xE2E0 0x7614 #CJK UNIFIED IDEOGRAPH
+0xE2E1 0x76B8 #CJK UNIFIED IDEOGRAPH
+0xE2E2 0x7781 #CJK UNIFIED IDEOGRAPH
+0xE2E3 0x777C #CJK UNIFIED IDEOGRAPH
+0xE2E4 0x7785 #CJK UNIFIED IDEOGRAPH
+0xE2E5 0x7782 #CJK UNIFIED IDEOGRAPH
+0xE2E6 0x776E #CJK UNIFIED IDEOGRAPH
+0xE2E7 0x7780 #CJK UNIFIED IDEOGRAPH
+0xE2E8 0x776F #CJK UNIFIED IDEOGRAPH
+0xE2E9 0x777E #CJK UNIFIED IDEOGRAPH
+0xE2EA 0x7783 #CJK UNIFIED IDEOGRAPH
+0xE2EB 0x78B2 #CJK UNIFIED IDEOGRAPH
+0xE2EC 0x78AA #CJK UNIFIED IDEOGRAPH
+0xE2ED 0x78B4 #CJK UNIFIED IDEOGRAPH
+0xE2EE 0x78AD #CJK UNIFIED IDEOGRAPH
+0xE2EF 0x78A8 #CJK UNIFIED IDEOGRAPH
+0xE2F0 0x787E #CJK UNIFIED IDEOGRAPH
+0xE2F1 0x78AB #CJK UNIFIED IDEOGRAPH
+0xE2F2 0x789E #CJK UNIFIED IDEOGRAPH
+0xE2F3 0x78A5 #CJK UNIFIED IDEOGRAPH
+0xE2F4 0x78A0 #CJK UNIFIED IDEOGRAPH
+0xE2F5 0x78AC #CJK UNIFIED IDEOGRAPH
+0xE2F6 0x78A2 #CJK UNIFIED IDEOGRAPH
+0xE2F7 0x78A4 #CJK UNIFIED IDEOGRAPH
+0xE2F8 0x7998 #CJK UNIFIED IDEOGRAPH
+0xE2F9 0x798A #CJK UNIFIED IDEOGRAPH
+0xE2FA 0x798B #CJK UNIFIED IDEOGRAPH
+0xE2FB 0x7996 #CJK UNIFIED IDEOGRAPH
+0xE2FC 0x7995 #CJK UNIFIED IDEOGRAPH
+0xE2FD 0x7994 #CJK UNIFIED IDEOGRAPH
+0xE2FE 0x7993 #CJK UNIFIED IDEOGRAPH
+0xE340 0x7997 #CJK UNIFIED IDEOGRAPH
+0xE341 0x7988 #CJK UNIFIED IDEOGRAPH
+0xE342 0x7992 #CJK UNIFIED IDEOGRAPH
+0xE343 0x7990 #CJK UNIFIED IDEOGRAPH
+0xE344 0x7A2B #CJK UNIFIED IDEOGRAPH
+0xE345 0x7A4A #CJK UNIFIED IDEOGRAPH
+0xE346 0x7A30 #CJK UNIFIED IDEOGRAPH
+0xE347 0x7A2F #CJK UNIFIED IDEOGRAPH
+0xE348 0x7A28 #CJK UNIFIED IDEOGRAPH
+0xE349 0x7A26 #CJK UNIFIED IDEOGRAPH
+0xE34A 0x7AA8 #CJK UNIFIED IDEOGRAPH
+0xE34B 0x7AAB #CJK UNIFIED IDEOGRAPH
+0xE34C 0x7AAC #CJK UNIFIED IDEOGRAPH
+0xE34D 0x7AEE #CJK UNIFIED IDEOGRAPH
+0xE34E 0x7B88 #CJK UNIFIED IDEOGRAPH
+0xE34F 0x7B9C #CJK UNIFIED IDEOGRAPH
+0xE350 0x7B8A #CJK UNIFIED IDEOGRAPH
+0xE351 0x7B91 #CJK UNIFIED IDEOGRAPH
+0xE352 0x7B90 #CJK UNIFIED IDEOGRAPH
+0xE353 0x7B96 #CJK UNIFIED IDEOGRAPH
+0xE354 0x7B8D #CJK UNIFIED IDEOGRAPH
+0xE355 0x7B8C #CJK UNIFIED IDEOGRAPH
+0xE356 0x7B9B #CJK UNIFIED IDEOGRAPH
+0xE357 0x7B8E #CJK UNIFIED IDEOGRAPH
+0xE358 0x7B85 #CJK UNIFIED IDEOGRAPH
+0xE359 0x7B98 #CJK UNIFIED IDEOGRAPH
+0xE35A 0x5284 #CJK UNIFIED IDEOGRAPH
+0xE35B 0x7B99 #CJK UNIFIED IDEOGRAPH
+0xE35C 0x7BA4 #CJK UNIFIED IDEOGRAPH
+0xE35D 0x7B82 #CJK UNIFIED IDEOGRAPH
+0xE35E 0x7CBB #CJK UNIFIED IDEOGRAPH
+0xE35F 0x7CBF #CJK UNIFIED IDEOGRAPH
+0xE360 0x7CBC #CJK UNIFIED IDEOGRAPH
+0xE361 0x7CBA #CJK UNIFIED IDEOGRAPH
+0xE362 0x7DA7 #CJK UNIFIED IDEOGRAPH
+0xE363 0x7DB7 #CJK UNIFIED IDEOGRAPH
+0xE364 0x7DC2 #CJK UNIFIED IDEOGRAPH
+0xE365 0x7DA3 #CJK UNIFIED IDEOGRAPH
+0xE366 0x7DAA #CJK UNIFIED IDEOGRAPH
+0xE367 0x7DC1 #CJK UNIFIED IDEOGRAPH
+0xE368 0x7DC0 #CJK UNIFIED IDEOGRAPH
+0xE369 0x7DC5 #CJK UNIFIED IDEOGRAPH
+0xE36A 0x7D9D #CJK UNIFIED IDEOGRAPH
+0xE36B 0x7DCE #CJK UNIFIED IDEOGRAPH
+0xE36C 0x7DC4 #CJK UNIFIED IDEOGRAPH
+0xE36D 0x7DC6 #CJK UNIFIED IDEOGRAPH
+0xE36E 0x7DCB #CJK UNIFIED IDEOGRAPH
+0xE36F 0x7DCC #CJK UNIFIED IDEOGRAPH
+0xE370 0x7DAF #CJK UNIFIED IDEOGRAPH
+0xE371 0x7DB9 #CJK UNIFIED IDEOGRAPH
+0xE372 0x7D96 #CJK UNIFIED IDEOGRAPH
+0xE373 0x7DBC #CJK UNIFIED IDEOGRAPH
+0xE374 0x7D9F #CJK UNIFIED IDEOGRAPH
+0xE375 0x7DA6 #CJK UNIFIED IDEOGRAPH
+0xE376 0x7DAE #CJK UNIFIED IDEOGRAPH
+0xE377 0x7DA9 #CJK UNIFIED IDEOGRAPH
+0xE378 0x7DA1 #CJK UNIFIED IDEOGRAPH
+0xE379 0x7DC9 #CJK UNIFIED IDEOGRAPH
+0xE37A 0x7F73 #CJK UNIFIED IDEOGRAPH
+0xE37B 0x7FE2 #CJK UNIFIED IDEOGRAPH
+0xE37C 0x7FE3 #CJK UNIFIED IDEOGRAPH
+0xE37D 0x7FE5 #CJK UNIFIED IDEOGRAPH
+0xE37E 0x7FDE #CJK UNIFIED IDEOGRAPH
+0xE3A1 0x8024 #CJK UNIFIED IDEOGRAPH
+0xE3A2 0x805D #CJK UNIFIED IDEOGRAPH
+0xE3A3 0x805C #CJK UNIFIED IDEOGRAPH
+0xE3A4 0x8189 #CJK UNIFIED IDEOGRAPH
+0xE3A5 0x8186 #CJK UNIFIED IDEOGRAPH
+0xE3A6 0x8183 #CJK UNIFIED IDEOGRAPH
+0xE3A7 0x8187 #CJK UNIFIED IDEOGRAPH
+0xE3A8 0x818D #CJK UNIFIED IDEOGRAPH
+0xE3A9 0x818C #CJK UNIFIED IDEOGRAPH
+0xE3AA 0x818B #CJK UNIFIED IDEOGRAPH
+0xE3AB 0x8215 #CJK UNIFIED IDEOGRAPH
+0xE3AC 0x8497 #CJK UNIFIED IDEOGRAPH
+0xE3AD 0x84A4 #CJK UNIFIED IDEOGRAPH
+0xE3AE 0x84A1 #CJK UNIFIED IDEOGRAPH
+0xE3AF 0x849F #CJK UNIFIED IDEOGRAPH
+0xE3B0 0x84BA #CJK UNIFIED IDEOGRAPH
+0xE3B1 0x84CE #CJK UNIFIED IDEOGRAPH
+0xE3B2 0x84C2 #CJK UNIFIED IDEOGRAPH
+0xE3B3 0x84AC #CJK UNIFIED IDEOGRAPH
+0xE3B4 0x84AE #CJK UNIFIED IDEOGRAPH
+0xE3B5 0x84AB #CJK UNIFIED IDEOGRAPH
+0xE3B6 0x84B9 #CJK UNIFIED IDEOGRAPH
+0xE3B7 0x84B4 #CJK UNIFIED IDEOGRAPH
+0xE3B8 0x84C1 #CJK UNIFIED IDEOGRAPH
+0xE3B9 0x84CD #CJK UNIFIED IDEOGRAPH
+0xE3BA 0x84AA #CJK UNIFIED IDEOGRAPH
+0xE3BB 0x849A #CJK UNIFIED IDEOGRAPH
+0xE3BC 0x84B1 #CJK UNIFIED IDEOGRAPH
+0xE3BD 0x84D0 #CJK UNIFIED IDEOGRAPH
+0xE3BE 0x849D #CJK UNIFIED IDEOGRAPH
+0xE3BF 0x84A7 #CJK UNIFIED IDEOGRAPH
+0xE3C0 0x84BB #CJK UNIFIED IDEOGRAPH
+0xE3C1 0x84A2 #CJK UNIFIED IDEOGRAPH
+0xE3C2 0x8494 #CJK UNIFIED IDEOGRAPH
+0xE3C3 0x84C7 #CJK UNIFIED IDEOGRAPH
+0xE3C4 0x84CC #CJK UNIFIED IDEOGRAPH
+0xE3C5 0x849B #CJK UNIFIED IDEOGRAPH
+0xE3C6 0x84A9 #CJK UNIFIED IDEOGRAPH
+0xE3C7 0x84AF #CJK UNIFIED IDEOGRAPH
+0xE3C8 0x84A8 #CJK UNIFIED IDEOGRAPH
+0xE3C9 0x84D6 #CJK UNIFIED IDEOGRAPH
+0xE3CA 0x8498 #CJK UNIFIED IDEOGRAPH
+0xE3CB 0x84B6 #CJK UNIFIED IDEOGRAPH
+0xE3CC 0x84CF #CJK UNIFIED IDEOGRAPH
+0xE3CD 0x84A0 #CJK UNIFIED IDEOGRAPH
+0xE3CE 0x84D7 #CJK UNIFIED IDEOGRAPH
+0xE3CF 0x84D4 #CJK UNIFIED IDEOGRAPH
+0xE3D0 0x84D2 #CJK UNIFIED IDEOGRAPH
+0xE3D1 0x84DB #CJK UNIFIED IDEOGRAPH
+0xE3D2 0x84B0 #CJK UNIFIED IDEOGRAPH
+0xE3D3 0x8491 #CJK UNIFIED IDEOGRAPH
+0xE3D4 0x8661 #CJK UNIFIED IDEOGRAPH
+0xE3D5 0x8733 #CJK UNIFIED IDEOGRAPH
+0xE3D6 0x8723 #CJK UNIFIED IDEOGRAPH
+0xE3D7 0x8728 #CJK UNIFIED IDEOGRAPH
+0xE3D8 0x876B #CJK UNIFIED IDEOGRAPH
+0xE3D9 0x8740 #CJK UNIFIED IDEOGRAPH
+0xE3DA 0x872E #CJK UNIFIED IDEOGRAPH
+0xE3DB 0x871E #CJK UNIFIED IDEOGRAPH
+0xE3DC 0x8721 #CJK UNIFIED IDEOGRAPH
+0xE3DD 0x8719 #CJK UNIFIED IDEOGRAPH
+0xE3DE 0x871B #CJK UNIFIED IDEOGRAPH
+0xE3DF 0x8743 #CJK UNIFIED IDEOGRAPH
+0xE3E0 0x872C #CJK UNIFIED IDEOGRAPH
+0xE3E1 0x8741 #CJK UNIFIED IDEOGRAPH
+0xE3E2 0x873E #CJK UNIFIED IDEOGRAPH
+0xE3E3 0x8746 #CJK UNIFIED IDEOGRAPH
+0xE3E4 0x8720 #CJK UNIFIED IDEOGRAPH
+0xE3E5 0x8732 #CJK UNIFIED IDEOGRAPH
+0xE3E6 0x872A #CJK UNIFIED IDEOGRAPH
+0xE3E7 0x872D #CJK UNIFIED IDEOGRAPH
+0xE3E8 0x873C #CJK UNIFIED IDEOGRAPH
+0xE3E9 0x8712 #CJK UNIFIED IDEOGRAPH
+0xE3EA 0x873A #CJK UNIFIED IDEOGRAPH
+0xE3EB 0x8731 #CJK UNIFIED IDEOGRAPH
+0xE3EC 0x8735 #CJK UNIFIED IDEOGRAPH
+0xE3ED 0x8742 #CJK UNIFIED IDEOGRAPH
+0xE3EE 0x8726 #CJK UNIFIED IDEOGRAPH
+0xE3EF 0x8727 #CJK UNIFIED IDEOGRAPH
+0xE3F0 0x8738 #CJK UNIFIED IDEOGRAPH
+0xE3F1 0x8724 #CJK UNIFIED IDEOGRAPH
+0xE3F2 0x871A #CJK UNIFIED IDEOGRAPH
+0xE3F3 0x8730 #CJK UNIFIED IDEOGRAPH
+0xE3F4 0x8711 #CJK UNIFIED IDEOGRAPH
+0xE3F5 0x88F7 #CJK UNIFIED IDEOGRAPH
+0xE3F6 0x88E7 #CJK UNIFIED IDEOGRAPH
+0xE3F7 0x88F1 #CJK UNIFIED IDEOGRAPH
+0xE3F8 0x88F2 #CJK UNIFIED IDEOGRAPH
+0xE3F9 0x88FA #CJK UNIFIED IDEOGRAPH
+0xE3FA 0x88FE #CJK UNIFIED IDEOGRAPH
+0xE3FB 0x88EE #CJK UNIFIED IDEOGRAPH
+0xE3FC 0x88FC #CJK UNIFIED IDEOGRAPH
+0xE3FD 0x88F6 #CJK UNIFIED IDEOGRAPH
+0xE3FE 0x88FB #CJK UNIFIED IDEOGRAPH
+0xE440 0x88F0 #CJK UNIFIED IDEOGRAPH
+0xE441 0x88EC #CJK UNIFIED IDEOGRAPH
+0xE442 0x88EB #CJK UNIFIED IDEOGRAPH
+0xE443 0x899D #CJK UNIFIED IDEOGRAPH
+0xE444 0x89A1 #CJK UNIFIED IDEOGRAPH
+0xE445 0x899F #CJK UNIFIED IDEOGRAPH
+0xE446 0x899E #CJK UNIFIED IDEOGRAPH
+0xE447 0x89E9 #CJK UNIFIED IDEOGRAPH
+0xE448 0x89EB #CJK UNIFIED IDEOGRAPH
+0xE449 0x89E8 #CJK UNIFIED IDEOGRAPH
+0xE44A 0x8AAB #CJK UNIFIED IDEOGRAPH
+0xE44B 0x8A99 #CJK UNIFIED IDEOGRAPH
+0xE44C 0x8A8B #CJK UNIFIED IDEOGRAPH
+0xE44D 0x8A92 #CJK UNIFIED IDEOGRAPH
+0xE44E 0x8A8F #CJK UNIFIED IDEOGRAPH
+0xE44F 0x8A96 #CJK UNIFIED IDEOGRAPH
+0xE450 0x8C3D #CJK UNIFIED IDEOGRAPH
+0xE451 0x8C68 #CJK UNIFIED IDEOGRAPH
+0xE452 0x8C69 #CJK UNIFIED IDEOGRAPH
+0xE453 0x8CD5 #CJK UNIFIED IDEOGRAPH
+0xE454 0x8CCF #CJK UNIFIED IDEOGRAPH
+0xE455 0x8CD7 #CJK UNIFIED IDEOGRAPH
+0xE456 0x8D96 #CJK UNIFIED IDEOGRAPH
+0xE457 0x8E09 #CJK UNIFIED IDEOGRAPH
+0xE458 0x8E02 #CJK UNIFIED IDEOGRAPH
+0xE459 0x8DFF #CJK UNIFIED IDEOGRAPH
+0xE45A 0x8E0D #CJK UNIFIED IDEOGRAPH
+0xE45B 0x8DFD #CJK UNIFIED IDEOGRAPH
+0xE45C 0x8E0A #CJK UNIFIED IDEOGRAPH
+0xE45D 0x8E03 #CJK UNIFIED IDEOGRAPH
+0xE45E 0x8E07 #CJK UNIFIED IDEOGRAPH
+0xE45F 0x8E06 #CJK UNIFIED IDEOGRAPH
+0xE460 0x8E05 #CJK UNIFIED IDEOGRAPH
+0xE461 0x8DFE #CJK UNIFIED IDEOGRAPH
+0xE462 0x8E00 #CJK UNIFIED IDEOGRAPH
+0xE463 0x8E04 #CJK UNIFIED IDEOGRAPH
+0xE464 0x8F10 #CJK UNIFIED IDEOGRAPH
+0xE465 0x8F11 #CJK UNIFIED IDEOGRAPH
+0xE466 0x8F0E #CJK UNIFIED IDEOGRAPH
+0xE467 0x8F0D #CJK UNIFIED IDEOGRAPH
+0xE468 0x9123 #CJK UNIFIED IDEOGRAPH
+0xE469 0x911C #CJK UNIFIED IDEOGRAPH
+0xE46A 0x9120 #CJK UNIFIED IDEOGRAPH
+0xE46B 0x9122 #CJK UNIFIED IDEOGRAPH
+0xE46C 0x911F #CJK UNIFIED IDEOGRAPH
+0xE46D 0x911D #CJK UNIFIED IDEOGRAPH
+0xE46E 0x911A #CJK UNIFIED IDEOGRAPH
+0xE46F 0x9124 #CJK UNIFIED IDEOGRAPH
+0xE470 0x9121 #CJK UNIFIED IDEOGRAPH
+0xE471 0x911B #CJK UNIFIED IDEOGRAPH
+0xE472 0x917A #CJK UNIFIED IDEOGRAPH
+0xE473 0x9172 #CJK UNIFIED IDEOGRAPH
+0xE474 0x9179 #CJK UNIFIED IDEOGRAPH
+0xE475 0x9173 #CJK UNIFIED IDEOGRAPH
+0xE476 0x92A5 #CJK UNIFIED IDEOGRAPH
+0xE477 0x92A4 #CJK UNIFIED IDEOGRAPH
+0xE478 0x9276 #CJK UNIFIED IDEOGRAPH
+0xE479 0x929B #CJK UNIFIED IDEOGRAPH
+0xE47A 0x927A #CJK UNIFIED IDEOGRAPH
+0xE47B 0x92A0 #CJK UNIFIED IDEOGRAPH
+0xE47C 0x9294 #CJK UNIFIED IDEOGRAPH
+0xE47D 0x92AA #CJK UNIFIED IDEOGRAPH
+0xE47E 0x928D #CJK UNIFIED IDEOGRAPH
+0xE4A1 0x92A6 #CJK UNIFIED IDEOGRAPH
+0xE4A2 0x929A #CJK UNIFIED IDEOGRAPH
+0xE4A3 0x92AB #CJK UNIFIED IDEOGRAPH
+0xE4A4 0x9279 #CJK UNIFIED IDEOGRAPH
+0xE4A5 0x9297 #CJK UNIFIED IDEOGRAPH
+0xE4A6 0x927F #CJK UNIFIED IDEOGRAPH
+0xE4A7 0x92A3 #CJK UNIFIED IDEOGRAPH
+0xE4A8 0x92EE #CJK UNIFIED IDEOGRAPH
+0xE4A9 0x928E #CJK UNIFIED IDEOGRAPH
+0xE4AA 0x9282 #CJK UNIFIED IDEOGRAPH
+0xE4AB 0x9295 #CJK UNIFIED IDEOGRAPH
+0xE4AC 0x92A2 #CJK UNIFIED IDEOGRAPH
+0xE4AD 0x927D #CJK UNIFIED IDEOGRAPH
+0xE4AE 0x9288 #CJK UNIFIED IDEOGRAPH
+0xE4AF 0x92A1 #CJK UNIFIED IDEOGRAPH
+0xE4B0 0x928A #CJK UNIFIED IDEOGRAPH
+0xE4B1 0x9286 #CJK UNIFIED IDEOGRAPH
+0xE4B2 0x928C #CJK UNIFIED IDEOGRAPH
+0xE4B3 0x9299 #CJK UNIFIED IDEOGRAPH
+0xE4B4 0x92A7 #CJK UNIFIED IDEOGRAPH
+0xE4B5 0x927E #CJK UNIFIED IDEOGRAPH
+0xE4B6 0x9287 #CJK UNIFIED IDEOGRAPH
+0xE4B7 0x92A9 #CJK UNIFIED IDEOGRAPH
+0xE4B8 0x929D #CJK UNIFIED IDEOGRAPH
+0xE4B9 0x928B #CJK UNIFIED IDEOGRAPH
+0xE4BA 0x922D #CJK UNIFIED IDEOGRAPH
+0xE4BB 0x969E #CJK UNIFIED IDEOGRAPH
+0xE4BC 0x96A1 #CJK UNIFIED IDEOGRAPH
+0xE4BD 0x96FF #CJK UNIFIED IDEOGRAPH
+0xE4BE 0x9758 #CJK UNIFIED IDEOGRAPH
+0xE4BF 0x977D #CJK UNIFIED IDEOGRAPH
+0xE4C0 0x977A #CJK UNIFIED IDEOGRAPH
+0xE4C1 0x977E #CJK UNIFIED IDEOGRAPH
+0xE4C2 0x9783 #CJK UNIFIED IDEOGRAPH
+0xE4C3 0x9780 #CJK UNIFIED IDEOGRAPH
+0xE4C4 0x9782 #CJK UNIFIED IDEOGRAPH
+0xE4C5 0x977B #CJK UNIFIED IDEOGRAPH
+0xE4C6 0x9784 #CJK UNIFIED IDEOGRAPH
+0xE4C7 0x9781 #CJK UNIFIED IDEOGRAPH
+0xE4C8 0x977F #CJK UNIFIED IDEOGRAPH
+0xE4C9 0x97CE #CJK UNIFIED IDEOGRAPH
+0xE4CA 0x97CD #CJK UNIFIED IDEOGRAPH
+0xE4CB 0x9816 #CJK UNIFIED IDEOGRAPH
+0xE4CC 0x98AD #CJK UNIFIED IDEOGRAPH
+0xE4CD 0x98AE #CJK UNIFIED IDEOGRAPH
+0xE4CE 0x9902 #CJK UNIFIED IDEOGRAPH
+0xE4CF 0x9900 #CJK UNIFIED IDEOGRAPH
+0xE4D0 0x9907 #CJK UNIFIED IDEOGRAPH
+0xE4D1 0x999D #CJK UNIFIED IDEOGRAPH
+0xE4D2 0x999C #CJK UNIFIED IDEOGRAPH
+0xE4D3 0x99C3 #CJK UNIFIED IDEOGRAPH
+0xE4D4 0x99B9 #CJK UNIFIED IDEOGRAPH
+0xE4D5 0x99BB #CJK UNIFIED IDEOGRAPH
+0xE4D6 0x99BA #CJK UNIFIED IDEOGRAPH
+0xE4D7 0x99C2 #CJK UNIFIED IDEOGRAPH
+0xE4D8 0x99BD #CJK UNIFIED IDEOGRAPH
+0xE4D9 0x99C7 #CJK UNIFIED IDEOGRAPH
+0xE4DA 0x9AB1 #CJK UNIFIED IDEOGRAPH
+0xE4DB 0x9AE3 #CJK UNIFIED IDEOGRAPH
+0xE4DC 0x9AE7 #CJK UNIFIED IDEOGRAPH
+0xE4DD 0x9B3E #CJK UNIFIED IDEOGRAPH
+0xE4DE 0x9B3F #CJK UNIFIED IDEOGRAPH
+0xE4DF 0x9B60 #CJK UNIFIED IDEOGRAPH
+0xE4E0 0x9B61 #CJK UNIFIED IDEOGRAPH
+0xE4E1 0x9B5F #CJK UNIFIED IDEOGRAPH
+0xE4E2 0x9CF1 #CJK UNIFIED IDEOGRAPH
+0xE4E3 0x9CF2 #CJK UNIFIED IDEOGRAPH
+0xE4E4 0x9CF5 #CJK UNIFIED IDEOGRAPH
+0xE4E5 0x9EA7 #CJK UNIFIED IDEOGRAPH
+0xE4E6 0x50FF #CJK UNIFIED IDEOGRAPH
+0xE4E7 0x5103 #CJK UNIFIED IDEOGRAPH
+0xE4E8 0x5130 #CJK UNIFIED IDEOGRAPH
+0xE4E9 0x50F8 #CJK UNIFIED IDEOGRAPH
+0xE4EA 0x5106 #CJK UNIFIED IDEOGRAPH
+0xE4EB 0x5107 #CJK UNIFIED IDEOGRAPH
+0xE4EC 0x50F6 #CJK UNIFIED IDEOGRAPH
+0xE4ED 0x50FE #CJK UNIFIED IDEOGRAPH
+0xE4EE 0x510B #CJK UNIFIED IDEOGRAPH
+0xE4EF 0x510C #CJK UNIFIED IDEOGRAPH
+0xE4F0 0x50FD #CJK UNIFIED IDEOGRAPH
+0xE4F1 0x510A #CJK UNIFIED IDEOGRAPH
+0xE4F2 0x528B #CJK UNIFIED IDEOGRAPH
+0xE4F3 0x528C #CJK UNIFIED IDEOGRAPH
+0xE4F4 0x52F1 #CJK UNIFIED IDEOGRAPH
+0xE4F5 0x52EF #CJK UNIFIED IDEOGRAPH
+0xE4F6 0x5648 #CJK UNIFIED IDEOGRAPH
+0xE4F7 0x5642 #CJK UNIFIED IDEOGRAPH
+0xE4F8 0x564C #CJK UNIFIED IDEOGRAPH
+0xE4F9 0x5635 #CJK UNIFIED IDEOGRAPH
+0xE4FA 0x5641 #CJK UNIFIED IDEOGRAPH
+0xE4FB 0x564A #CJK UNIFIED IDEOGRAPH
+0xE4FC 0x5649 #CJK UNIFIED IDEOGRAPH
+0xE4FD 0x5646 #CJK UNIFIED IDEOGRAPH
+0xE4FE 0x5658 #CJK UNIFIED IDEOGRAPH
+0xE540 0x565A #CJK UNIFIED IDEOGRAPH
+0xE541 0x5640 #CJK UNIFIED IDEOGRAPH
+0xE542 0x5633 #CJK UNIFIED IDEOGRAPH
+0xE543 0x563D #CJK UNIFIED IDEOGRAPH
+0xE544 0x562C #CJK UNIFIED IDEOGRAPH
+0xE545 0x563E #CJK UNIFIED IDEOGRAPH
+0xE546 0x5638 #CJK UNIFIED IDEOGRAPH
+0xE547 0x562A #CJK UNIFIED IDEOGRAPH
+0xE548 0x563A #CJK UNIFIED IDEOGRAPH
+0xE549 0x571A #CJK UNIFIED IDEOGRAPH
+0xE54A 0x58AB #CJK UNIFIED IDEOGRAPH
+0xE54B 0x589D #CJK UNIFIED IDEOGRAPH
+0xE54C 0x58B1 #CJK UNIFIED IDEOGRAPH
+0xE54D 0x58A0 #CJK UNIFIED IDEOGRAPH
+0xE54E 0x58A3 #CJK UNIFIED IDEOGRAPH
+0xE54F 0x58AF #CJK UNIFIED IDEOGRAPH
+0xE550 0x58AC #CJK UNIFIED IDEOGRAPH
+0xE551 0x58A5 #CJK UNIFIED IDEOGRAPH
+0xE552 0x58A1 #CJK UNIFIED IDEOGRAPH
+0xE553 0x58FF #CJK UNIFIED IDEOGRAPH
+0xE554 0x5AFF #CJK UNIFIED IDEOGRAPH
+0xE555 0x5AF4 #CJK UNIFIED IDEOGRAPH
+0xE556 0x5AFD #CJK UNIFIED IDEOGRAPH
+0xE557 0x5AF7 #CJK UNIFIED IDEOGRAPH
+0xE558 0x5AF6 #CJK UNIFIED IDEOGRAPH
+0xE559 0x5B03 #CJK UNIFIED IDEOGRAPH
+0xE55A 0x5AF8 #CJK UNIFIED IDEOGRAPH
+0xE55B 0x5B02 #CJK UNIFIED IDEOGRAPH
+0xE55C 0x5AF9 #CJK UNIFIED IDEOGRAPH
+0xE55D 0x5B01 #CJK UNIFIED IDEOGRAPH
+0xE55E 0x5B07 #CJK UNIFIED IDEOGRAPH
+0xE55F 0x5B05 #CJK UNIFIED IDEOGRAPH
+0xE560 0x5B0F #CJK UNIFIED IDEOGRAPH
+0xE561 0x5C67 #CJK UNIFIED IDEOGRAPH
+0xE562 0x5D99 #CJK UNIFIED IDEOGRAPH
+0xE563 0x5D97 #CJK UNIFIED IDEOGRAPH
+0xE564 0x5D9F #CJK UNIFIED IDEOGRAPH
+0xE565 0x5D92 #CJK UNIFIED IDEOGRAPH
+0xE566 0x5DA2 #CJK UNIFIED IDEOGRAPH
+0xE567 0x5D93 #CJK UNIFIED IDEOGRAPH
+0xE568 0x5D95 #CJK UNIFIED IDEOGRAPH
+0xE569 0x5DA0 #CJK UNIFIED IDEOGRAPH
+0xE56A 0x5D9C #CJK UNIFIED IDEOGRAPH
+0xE56B 0x5DA1 #CJK UNIFIED IDEOGRAPH
+0xE56C 0x5D9A #CJK UNIFIED IDEOGRAPH
+0xE56D 0x5D9E #CJK UNIFIED IDEOGRAPH
+0xE56E 0x5E69 #CJK UNIFIED IDEOGRAPH
+0xE56F 0x5E5D #CJK UNIFIED IDEOGRAPH
+0xE570 0x5E60 #CJK UNIFIED IDEOGRAPH
+0xE571 0x5E5C #CJK UNIFIED IDEOGRAPH
+0xE572 0x7DF3 #CJK UNIFIED IDEOGRAPH
+0xE573 0x5EDB #CJK UNIFIED IDEOGRAPH
+0xE574 0x5EDE #CJK UNIFIED IDEOGRAPH
+0xE575 0x5EE1 #CJK UNIFIED IDEOGRAPH
+0xE576 0x5F49 #CJK UNIFIED IDEOGRAPH
+0xE577 0x5FB2 #CJK UNIFIED IDEOGRAPH
+0xE578 0x618B #CJK UNIFIED IDEOGRAPH
+0xE579 0x6183 #CJK UNIFIED IDEOGRAPH
+0xE57A 0x6179 #CJK UNIFIED IDEOGRAPH
+0xE57B 0x61B1 #CJK UNIFIED IDEOGRAPH
+0xE57C 0x61B0 #CJK UNIFIED IDEOGRAPH
+0xE57D 0x61A2 #CJK UNIFIED IDEOGRAPH
+0xE57E 0x6189 #CJK UNIFIED IDEOGRAPH
+0xE5A1 0x619B #CJK UNIFIED IDEOGRAPH
+0xE5A2 0x6193 #CJK UNIFIED IDEOGRAPH
+0xE5A3 0x61AF #CJK UNIFIED IDEOGRAPH
+0xE5A4 0x61AD #CJK UNIFIED IDEOGRAPH
+0xE5A5 0x619F #CJK UNIFIED IDEOGRAPH
+0xE5A6 0x6192 #CJK UNIFIED IDEOGRAPH
+0xE5A7 0x61AA #CJK UNIFIED IDEOGRAPH
+0xE5A8 0x61A1 #CJK UNIFIED IDEOGRAPH
+0xE5A9 0x618D #CJK UNIFIED IDEOGRAPH
+0xE5AA 0x6166 #CJK UNIFIED IDEOGRAPH
+0xE5AB 0x61B3 #CJK UNIFIED IDEOGRAPH
+0xE5AC 0x622D #CJK UNIFIED IDEOGRAPH
+0xE5AD 0x646E #CJK UNIFIED IDEOGRAPH
+0xE5AE 0x6470 #CJK UNIFIED IDEOGRAPH
+0xE5AF 0x6496 #CJK UNIFIED IDEOGRAPH
+0xE5B0 0x64A0 #CJK UNIFIED IDEOGRAPH
+0xE5B1 0x6485 #CJK UNIFIED IDEOGRAPH
+0xE5B2 0x6497 #CJK UNIFIED IDEOGRAPH
+0xE5B3 0x649C #CJK UNIFIED IDEOGRAPH
+0xE5B4 0x648F #CJK UNIFIED IDEOGRAPH
+0xE5B5 0x648B #CJK UNIFIED IDEOGRAPH
+0xE5B6 0x648A #CJK UNIFIED IDEOGRAPH
+0xE5B7 0x648C #CJK UNIFIED IDEOGRAPH
+0xE5B8 0x64A3 #CJK UNIFIED IDEOGRAPH
+0xE5B9 0x649F #CJK UNIFIED IDEOGRAPH
+0xE5BA 0x6468 #CJK UNIFIED IDEOGRAPH
+0xE5BB 0x64B1 #CJK UNIFIED IDEOGRAPH
+0xE5BC 0x6498 #CJK UNIFIED IDEOGRAPH
+0xE5BD 0x6576 #CJK UNIFIED IDEOGRAPH
+0xE5BE 0x657A #CJK UNIFIED IDEOGRAPH
+0xE5BF 0x6579 #CJK UNIFIED IDEOGRAPH
+0xE5C0 0x657B #CJK UNIFIED IDEOGRAPH
+0xE5C1 0x65B2 #CJK UNIFIED IDEOGRAPH
+0xE5C2 0x65B3 #CJK UNIFIED IDEOGRAPH
+0xE5C3 0x66B5 #CJK UNIFIED IDEOGRAPH
+0xE5C4 0x66B0 #CJK UNIFIED IDEOGRAPH
+0xE5C5 0x66A9 #CJK UNIFIED IDEOGRAPH
+0xE5C6 0x66B2 #CJK UNIFIED IDEOGRAPH
+0xE5C7 0x66B7 #CJK UNIFIED IDEOGRAPH
+0xE5C8 0x66AA #CJK UNIFIED IDEOGRAPH
+0xE5C9 0x66AF #CJK UNIFIED IDEOGRAPH
+0xE5CA 0x6A00 #CJK UNIFIED IDEOGRAPH
+0xE5CB 0x6A06 #CJK UNIFIED IDEOGRAPH
+0xE5CC 0x6A17 #CJK UNIFIED IDEOGRAPH
+0xE5CD 0x69E5 #CJK UNIFIED IDEOGRAPH
+0xE5CE 0x69F8 #CJK UNIFIED IDEOGRAPH
+0xE5CF 0x6A15 #CJK UNIFIED IDEOGRAPH
+0xE5D0 0x69F1 #CJK UNIFIED IDEOGRAPH
+0xE5D1 0x69E4 #CJK UNIFIED IDEOGRAPH
+0xE5D2 0x6A20 #CJK UNIFIED IDEOGRAPH
+0xE5D3 0x69FF #CJK UNIFIED IDEOGRAPH
+0xE5D4 0x69EC #CJK UNIFIED IDEOGRAPH
+0xE5D5 0x69E2 #CJK UNIFIED IDEOGRAPH
+0xE5D6 0x6A1B #CJK UNIFIED IDEOGRAPH
+0xE5D7 0x6A1D #CJK UNIFIED IDEOGRAPH
+0xE5D8 0x69FE #CJK UNIFIED IDEOGRAPH
+0xE5D9 0x6A27 #CJK UNIFIED IDEOGRAPH
+0xE5DA 0x69F2 #CJK UNIFIED IDEOGRAPH
+0xE5DB 0x69EE #CJK UNIFIED IDEOGRAPH
+0xE5DC 0x6A14 #CJK UNIFIED IDEOGRAPH
+0xE5DD 0x69F7 #CJK UNIFIED IDEOGRAPH
+0xE5DE 0x69E7 #CJK UNIFIED IDEOGRAPH
+0xE5DF 0x6A40 #CJK UNIFIED IDEOGRAPH
+0xE5E0 0x6A08 #CJK UNIFIED IDEOGRAPH
+0xE5E1 0x69E6 #CJK UNIFIED IDEOGRAPH
+0xE5E2 0x69FB #CJK UNIFIED IDEOGRAPH
+0xE5E3 0x6A0D #CJK UNIFIED IDEOGRAPH
+0xE5E4 0x69FC #CJK UNIFIED IDEOGRAPH
+0xE5E5 0x69EB #CJK UNIFIED IDEOGRAPH
+0xE5E6 0x6A09 #CJK UNIFIED IDEOGRAPH
+0xE5E7 0x6A04 #CJK UNIFIED IDEOGRAPH
+0xE5E8 0x6A18 #CJK UNIFIED IDEOGRAPH
+0xE5E9 0x6A25 #CJK UNIFIED IDEOGRAPH
+0xE5EA 0x6A0F #CJK UNIFIED IDEOGRAPH
+0xE5EB 0x69F6 #CJK UNIFIED IDEOGRAPH
+0xE5EC 0x6A26 #CJK UNIFIED IDEOGRAPH
+0xE5ED 0x6A07 #CJK UNIFIED IDEOGRAPH
+0xE5EE 0x69F4 #CJK UNIFIED IDEOGRAPH
+0xE5EF 0x6A16 #CJK UNIFIED IDEOGRAPH
+0xE5F0 0x6B51 #CJK UNIFIED IDEOGRAPH
+0xE5F1 0x6BA5 #CJK UNIFIED IDEOGRAPH
+0xE5F2 0x6BA3 #CJK UNIFIED IDEOGRAPH
+0xE5F3 0x6BA2 #CJK UNIFIED IDEOGRAPH
+0xE5F4 0x6BA6 #CJK UNIFIED IDEOGRAPH
+0xE5F5 0x6C01 #CJK UNIFIED IDEOGRAPH
+0xE5F6 0x6C00 #CJK UNIFIED IDEOGRAPH
+0xE5F7 0x6BFF #CJK UNIFIED IDEOGRAPH
+0xE5F8 0x6C02 #CJK UNIFIED IDEOGRAPH
+0xE5F9 0x6F41 #CJK UNIFIED IDEOGRAPH
+0xE5FA 0x6F26 #CJK UNIFIED IDEOGRAPH
+0xE5FB 0x6F7E #CJK UNIFIED IDEOGRAPH
+0xE5FC 0x6F87 #CJK UNIFIED IDEOGRAPH
+0xE5FD 0x6FC6 #CJK UNIFIED IDEOGRAPH
+0xE5FE 0x6F92 #CJK UNIFIED IDEOGRAPH
+0xE640 0x6F8D #CJK UNIFIED IDEOGRAPH
+0xE641 0x6F89 #CJK UNIFIED IDEOGRAPH
+0xE642 0x6F8C #CJK UNIFIED IDEOGRAPH
+0xE643 0x6F62 #CJK UNIFIED IDEOGRAPH
+0xE644 0x6F4F #CJK UNIFIED IDEOGRAPH
+0xE645 0x6F85 #CJK UNIFIED IDEOGRAPH
+0xE646 0x6F5A #CJK UNIFIED IDEOGRAPH
+0xE647 0x6F96 #CJK UNIFIED IDEOGRAPH
+0xE648 0x6F76 #CJK UNIFIED IDEOGRAPH
+0xE649 0x6F6C #CJK UNIFIED IDEOGRAPH
+0xE64A 0x6F82 #CJK UNIFIED IDEOGRAPH
+0xE64B 0x6F55 #CJK UNIFIED IDEOGRAPH
+0xE64C 0x6F72 #CJK UNIFIED IDEOGRAPH
+0xE64D 0x6F52 #CJK UNIFIED IDEOGRAPH
+0xE64E 0x6F50 #CJK UNIFIED IDEOGRAPH
+0xE64F 0x6F57 #CJK UNIFIED IDEOGRAPH
+0xE650 0x6F94 #CJK UNIFIED IDEOGRAPH
+0xE651 0x6F93 #CJK UNIFIED IDEOGRAPH
+0xE652 0x6F5D #CJK UNIFIED IDEOGRAPH
+0xE653 0x6F00 #CJK UNIFIED IDEOGRAPH
+0xE654 0x6F61 #CJK UNIFIED IDEOGRAPH
+0xE655 0x6F6B #CJK UNIFIED IDEOGRAPH
+0xE656 0x6F7D #CJK UNIFIED IDEOGRAPH
+0xE657 0x6F67 #CJK UNIFIED IDEOGRAPH
+0xE658 0x6F90 #CJK UNIFIED IDEOGRAPH
+0xE659 0x6F53 #CJK UNIFIED IDEOGRAPH
+0xE65A 0x6F8B #CJK UNIFIED IDEOGRAPH
+0xE65B 0x6F69 #CJK UNIFIED IDEOGRAPH
+0xE65C 0x6F7F #CJK UNIFIED IDEOGRAPH
+0xE65D 0x6F95 #CJK UNIFIED IDEOGRAPH
+0xE65E 0x6F63 #CJK UNIFIED IDEOGRAPH
+0xE65F 0x6F77 #CJK UNIFIED IDEOGRAPH
+0xE660 0x6F6A #CJK UNIFIED IDEOGRAPH
+0xE661 0x6F7B #CJK UNIFIED IDEOGRAPH
+0xE662 0x71B2 #CJK UNIFIED IDEOGRAPH
+0xE663 0x71AF #CJK UNIFIED IDEOGRAPH
+0xE664 0x719B #CJK UNIFIED IDEOGRAPH
+0xE665 0x71B0 #CJK UNIFIED IDEOGRAPH
+0xE666 0x71A0 #CJK UNIFIED IDEOGRAPH
+0xE667 0x719A #CJK UNIFIED IDEOGRAPH
+0xE668 0x71A9 #CJK UNIFIED IDEOGRAPH
+0xE669 0x71B5 #CJK UNIFIED IDEOGRAPH
+0xE66A 0x719D #CJK UNIFIED IDEOGRAPH
+0xE66B 0x71A5 #CJK UNIFIED IDEOGRAPH
+0xE66C 0x719E #CJK UNIFIED IDEOGRAPH
+0xE66D 0x71A4 #CJK UNIFIED IDEOGRAPH
+0xE66E 0x71A1 #CJK UNIFIED IDEOGRAPH
+0xE66F 0x71AA #CJK UNIFIED IDEOGRAPH
+0xE670 0x719C #CJK UNIFIED IDEOGRAPH
+0xE671 0x71A7 #CJK UNIFIED IDEOGRAPH
+0xE672 0x71B3 #CJK UNIFIED IDEOGRAPH
+0xE673 0x7298 #CJK UNIFIED IDEOGRAPH
+0xE674 0x729A #CJK UNIFIED IDEOGRAPH
+0xE675 0x7358 #CJK UNIFIED IDEOGRAPH
+0xE676 0x7352 #CJK UNIFIED IDEOGRAPH
+0xE677 0x735E #CJK UNIFIED IDEOGRAPH
+0xE678 0x735F #CJK UNIFIED IDEOGRAPH
+0xE679 0x7360 #CJK UNIFIED IDEOGRAPH
+0xE67A 0x735D #CJK UNIFIED IDEOGRAPH
+0xE67B 0x735B #CJK UNIFIED IDEOGRAPH
+0xE67C 0x7361 #CJK UNIFIED IDEOGRAPH
+0xE67D 0x735A #CJK UNIFIED IDEOGRAPH
+0xE67E 0x7359 #CJK UNIFIED IDEOGRAPH
+0xE6A1 0x7362 #CJK UNIFIED IDEOGRAPH
+0xE6A2 0x7487 #CJK UNIFIED IDEOGRAPH
+0xE6A3 0x7489 #CJK UNIFIED IDEOGRAPH
+0xE6A4 0x748A #CJK UNIFIED IDEOGRAPH
+0xE6A5 0x7486 #CJK UNIFIED IDEOGRAPH
+0xE6A6 0x7481 #CJK UNIFIED IDEOGRAPH
+0xE6A7 0x747D #CJK UNIFIED IDEOGRAPH
+0xE6A8 0x7485 #CJK UNIFIED IDEOGRAPH
+0xE6A9 0x7488 #CJK UNIFIED IDEOGRAPH
+0xE6AA 0x747C #CJK UNIFIED IDEOGRAPH
+0xE6AB 0x7479 #CJK UNIFIED IDEOGRAPH
+0xE6AC 0x7508 #CJK UNIFIED IDEOGRAPH
+0xE6AD 0x7507 #CJK UNIFIED IDEOGRAPH
+0xE6AE 0x757E #CJK UNIFIED IDEOGRAPH
+0xE6AF 0x7625 #CJK UNIFIED IDEOGRAPH
+0xE6B0 0x761E #CJK UNIFIED IDEOGRAPH
+0xE6B1 0x7619 #CJK UNIFIED IDEOGRAPH
+0xE6B2 0x761D #CJK UNIFIED IDEOGRAPH
+0xE6B3 0x761C #CJK UNIFIED IDEOGRAPH
+0xE6B4 0x7623 #CJK UNIFIED IDEOGRAPH
+0xE6B5 0x761A #CJK UNIFIED IDEOGRAPH
+0xE6B6 0x7628 #CJK UNIFIED IDEOGRAPH
+0xE6B7 0x761B #CJK UNIFIED IDEOGRAPH
+0xE6B8 0x769C #CJK UNIFIED IDEOGRAPH
+0xE6B9 0x769D #CJK UNIFIED IDEOGRAPH
+0xE6BA 0x769E #CJK UNIFIED IDEOGRAPH
+0xE6BB 0x769B #CJK UNIFIED IDEOGRAPH
+0xE6BC 0x778D #CJK UNIFIED IDEOGRAPH
+0xE6BD 0x778F #CJK UNIFIED IDEOGRAPH
+0xE6BE 0x7789 #CJK UNIFIED IDEOGRAPH
+0xE6BF 0x7788 #CJK UNIFIED IDEOGRAPH
+0xE6C0 0x78CD #CJK UNIFIED IDEOGRAPH
+0xE6C1 0x78BB #CJK UNIFIED IDEOGRAPH
+0xE6C2 0x78CF #CJK UNIFIED IDEOGRAPH
+0xE6C3 0x78CC #CJK UNIFIED IDEOGRAPH
+0xE6C4 0x78D1 #CJK UNIFIED IDEOGRAPH
+0xE6C5 0x78CE #CJK UNIFIED IDEOGRAPH
+0xE6C6 0x78D4 #CJK UNIFIED IDEOGRAPH
+0xE6C7 0x78C8 #CJK UNIFIED IDEOGRAPH
+0xE6C8 0x78C3 #CJK UNIFIED IDEOGRAPH
+0xE6C9 0x78C4 #CJK UNIFIED IDEOGRAPH
+0xE6CA 0x78C9 #CJK UNIFIED IDEOGRAPH
+0xE6CB 0x799A #CJK UNIFIED IDEOGRAPH
+0xE6CC 0x79A1 #CJK UNIFIED IDEOGRAPH
+0xE6CD 0x79A0 #CJK UNIFIED IDEOGRAPH
+0xE6CE 0x799C #CJK UNIFIED IDEOGRAPH
+0xE6CF 0x79A2 #CJK UNIFIED IDEOGRAPH
+0xE6D0 0x799B #CJK UNIFIED IDEOGRAPH
+0xE6D1 0x6B76 #CJK UNIFIED IDEOGRAPH
+0xE6D2 0x7A39 #CJK UNIFIED IDEOGRAPH
+0xE6D3 0x7AB2 #CJK UNIFIED IDEOGRAPH
+0xE6D4 0x7AB4 #CJK UNIFIED IDEOGRAPH
+0xE6D5 0x7AB3 #CJK UNIFIED IDEOGRAPH
+0xE6D6 0x7BB7 #CJK UNIFIED IDEOGRAPH
+0xE6D7 0x7BCB #CJK UNIFIED IDEOGRAPH
+0xE6D8 0x7BBE #CJK UNIFIED IDEOGRAPH
+0xE6D9 0x7BAC #CJK UNIFIED IDEOGRAPH
+0xE6DA 0x7BCE #CJK UNIFIED IDEOGRAPH
+0xE6DB 0x7BAF #CJK UNIFIED IDEOGRAPH
+0xE6DC 0x7BB9 #CJK UNIFIED IDEOGRAPH
+0xE6DD 0x7BCA #CJK UNIFIED IDEOGRAPH
+0xE6DE 0x7BB5 #CJK UNIFIED IDEOGRAPH
+0xE6DF 0x7CC5 #CJK UNIFIED IDEOGRAPH
+0xE6E0 0x7CC8 #CJK UNIFIED IDEOGRAPH
+0xE6E1 0x7CCC #CJK UNIFIED IDEOGRAPH
+0xE6E2 0x7CCB #CJK UNIFIED IDEOGRAPH
+0xE6E3 0x7DF7 #CJK UNIFIED IDEOGRAPH
+0xE6E4 0x7DDB #CJK UNIFIED IDEOGRAPH
+0xE6E5 0x7DEA #CJK UNIFIED IDEOGRAPH
+0xE6E6 0x7DE7 #CJK UNIFIED IDEOGRAPH
+0xE6E7 0x7DD7 #CJK UNIFIED IDEOGRAPH
+0xE6E8 0x7DE1 #CJK UNIFIED IDEOGRAPH
+0xE6E9 0x7E03 #CJK UNIFIED IDEOGRAPH
+0xE6EA 0x7DFA #CJK UNIFIED IDEOGRAPH
+0xE6EB 0x7DE6 #CJK UNIFIED IDEOGRAPH
+0xE6EC 0x7DF6 #CJK UNIFIED IDEOGRAPH
+0xE6ED 0x7DF1 #CJK UNIFIED IDEOGRAPH
+0xE6EE 0x7DF0 #CJK UNIFIED IDEOGRAPH
+0xE6EF 0x7DEE #CJK UNIFIED IDEOGRAPH
+0xE6F0 0x7DDF #CJK UNIFIED IDEOGRAPH
+0xE6F1 0x7F76 #CJK UNIFIED IDEOGRAPH
+0xE6F2 0x7FAC #CJK UNIFIED IDEOGRAPH
+0xE6F3 0x7FB0 #CJK UNIFIED IDEOGRAPH
+0xE6F4 0x7FAD #CJK UNIFIED IDEOGRAPH
+0xE6F5 0x7FED #CJK UNIFIED IDEOGRAPH
+0xE6F6 0x7FEB #CJK UNIFIED IDEOGRAPH
+0xE6F7 0x7FEA #CJK UNIFIED IDEOGRAPH
+0xE6F8 0x7FEC #CJK UNIFIED IDEOGRAPH
+0xE6F9 0x7FE6 #CJK UNIFIED IDEOGRAPH
+0xE6FA 0x7FE8 #CJK UNIFIED IDEOGRAPH
+0xE6FB 0x8064 #CJK UNIFIED IDEOGRAPH
+0xE6FC 0x8067 #CJK UNIFIED IDEOGRAPH
+0xE6FD 0x81A3 #CJK UNIFIED IDEOGRAPH
+0xE6FE 0x819F #CJK UNIFIED IDEOGRAPH
+0xE740 0x819E #CJK UNIFIED IDEOGRAPH
+0xE741 0x8195 #CJK UNIFIED IDEOGRAPH
+0xE742 0x81A2 #CJK UNIFIED IDEOGRAPH
+0xE743 0x8199 #CJK UNIFIED IDEOGRAPH
+0xE744 0x8197 #CJK UNIFIED IDEOGRAPH
+0xE745 0x8216 #CJK UNIFIED IDEOGRAPH
+0xE746 0x824F #CJK UNIFIED IDEOGRAPH
+0xE747 0x8253 #CJK UNIFIED IDEOGRAPH
+0xE748 0x8252 #CJK UNIFIED IDEOGRAPH
+0xE749 0x8250 #CJK UNIFIED IDEOGRAPH
+0xE74A 0x824E #CJK UNIFIED IDEOGRAPH
+0xE74B 0x8251 #CJK UNIFIED IDEOGRAPH
+0xE74C 0x8524 #CJK UNIFIED IDEOGRAPH
+0xE74D 0x853B #CJK UNIFIED IDEOGRAPH
+0xE74E 0x850F #CJK UNIFIED IDEOGRAPH
+0xE74F 0x8500 #CJK UNIFIED IDEOGRAPH
+0xE750 0x8529 #CJK UNIFIED IDEOGRAPH
+0xE751 0x850E #CJK UNIFIED IDEOGRAPH
+0xE752 0x8509 #CJK UNIFIED IDEOGRAPH
+0xE753 0x850D #CJK UNIFIED IDEOGRAPH
+0xE754 0x851F #CJK UNIFIED IDEOGRAPH
+0xE755 0x850A #CJK UNIFIED IDEOGRAPH
+0xE756 0x8527 #CJK UNIFIED IDEOGRAPH
+0xE757 0x851C #CJK UNIFIED IDEOGRAPH
+0xE758 0x84FB #CJK UNIFIED IDEOGRAPH
+0xE759 0x852B #CJK UNIFIED IDEOGRAPH
+0xE75A 0x84FA #CJK UNIFIED IDEOGRAPH
+0xE75B 0x8508 #CJK UNIFIED IDEOGRAPH
+0xE75C 0x850C #CJK UNIFIED IDEOGRAPH
+0xE75D 0x84F4 #CJK UNIFIED IDEOGRAPH
+0xE75E 0x852A #CJK UNIFIED IDEOGRAPH
+0xE75F 0x84F2 #CJK UNIFIED IDEOGRAPH
+0xE760 0x8515 #CJK UNIFIED IDEOGRAPH
+0xE761 0x84F7 #CJK UNIFIED IDEOGRAPH
+0xE762 0x84EB #CJK UNIFIED IDEOGRAPH
+0xE763 0x84F3 #CJK UNIFIED IDEOGRAPH
+0xE764 0x84FC #CJK UNIFIED IDEOGRAPH
+0xE765 0x8512 #CJK UNIFIED IDEOGRAPH
+0xE766 0x84EA #CJK UNIFIED IDEOGRAPH
+0xE767 0x84E9 #CJK UNIFIED IDEOGRAPH
+0xE768 0x8516 #CJK UNIFIED IDEOGRAPH
+0xE769 0x84FE #CJK UNIFIED IDEOGRAPH
+0xE76A 0x8528 #CJK UNIFIED IDEOGRAPH
+0xE76B 0x851D #CJK UNIFIED IDEOGRAPH
+0xE76C 0x852E #CJK UNIFIED IDEOGRAPH
+0xE76D 0x8502 #CJK UNIFIED IDEOGRAPH
+0xE76E 0x84FD #CJK UNIFIED IDEOGRAPH
+0xE76F 0x851E #CJK UNIFIED IDEOGRAPH
+0xE770 0x84F6 #CJK UNIFIED IDEOGRAPH
+0xE771 0x8531 #CJK UNIFIED IDEOGRAPH
+0xE772 0x8526 #CJK UNIFIED IDEOGRAPH
+0xE773 0x84E7 #CJK UNIFIED IDEOGRAPH
+0xE774 0x84E8 #CJK UNIFIED IDEOGRAPH
+0xE775 0x84F0 #CJK UNIFIED IDEOGRAPH
+0xE776 0x84EF #CJK UNIFIED IDEOGRAPH
+0xE777 0x84F9 #CJK UNIFIED IDEOGRAPH
+0xE778 0x8518 #CJK UNIFIED IDEOGRAPH
+0xE779 0x8520 #CJK UNIFIED IDEOGRAPH
+0xE77A 0x8530 #CJK UNIFIED IDEOGRAPH
+0xE77B 0x850B #CJK UNIFIED IDEOGRAPH
+0xE77C 0x8519 #CJK UNIFIED IDEOGRAPH
+0xE77D 0x852F #CJK UNIFIED IDEOGRAPH
+0xE77E 0x8662 #CJK UNIFIED IDEOGRAPH
+0xE7A1 0x8756 #CJK UNIFIED IDEOGRAPH
+0xE7A2 0x8763 #CJK UNIFIED IDEOGRAPH
+0xE7A3 0x8764 #CJK UNIFIED IDEOGRAPH
+0xE7A4 0x8777 #CJK UNIFIED IDEOGRAPH
+0xE7A5 0x87E1 #CJK UNIFIED IDEOGRAPH
+0xE7A6 0x8773 #CJK UNIFIED IDEOGRAPH
+0xE7A7 0x8758 #CJK UNIFIED IDEOGRAPH
+0xE7A8 0x8754 #CJK UNIFIED IDEOGRAPH
+0xE7A9 0x875B #CJK UNIFIED IDEOGRAPH
+0xE7AA 0x8752 #CJK UNIFIED IDEOGRAPH
+0xE7AB 0x8761 #CJK UNIFIED IDEOGRAPH
+0xE7AC 0x875A #CJK UNIFIED IDEOGRAPH
+0xE7AD 0x8751 #CJK UNIFIED IDEOGRAPH
+0xE7AE 0x875E #CJK UNIFIED IDEOGRAPH
+0xE7AF 0x876D #CJK UNIFIED IDEOGRAPH
+0xE7B0 0x876A #CJK UNIFIED IDEOGRAPH
+0xE7B1 0x8750 #CJK UNIFIED IDEOGRAPH
+0xE7B2 0x874E #CJK UNIFIED IDEOGRAPH
+0xE7B3 0x875F #CJK UNIFIED IDEOGRAPH
+0xE7B4 0x875D #CJK UNIFIED IDEOGRAPH
+0xE7B5 0x876F #CJK UNIFIED IDEOGRAPH
+0xE7B6 0x876C #CJK UNIFIED IDEOGRAPH
+0xE7B7 0x877A #CJK UNIFIED IDEOGRAPH
+0xE7B8 0x876E #CJK UNIFIED IDEOGRAPH
+0xE7B9 0x875C #CJK UNIFIED IDEOGRAPH
+0xE7BA 0x8765 #CJK UNIFIED IDEOGRAPH
+0xE7BB 0x874F #CJK UNIFIED IDEOGRAPH
+0xE7BC 0x877B #CJK UNIFIED IDEOGRAPH
+0xE7BD 0x8775 #CJK UNIFIED IDEOGRAPH
+0xE7BE 0x8762 #CJK UNIFIED IDEOGRAPH
+0xE7BF 0x8767 #CJK UNIFIED IDEOGRAPH
+0xE7C0 0x8769 #CJK UNIFIED IDEOGRAPH
+0xE7C1 0x885A #CJK UNIFIED IDEOGRAPH
+0xE7C2 0x8905 #CJK UNIFIED IDEOGRAPH
+0xE7C3 0x890C #CJK UNIFIED IDEOGRAPH
+0xE7C4 0x8914 #CJK UNIFIED IDEOGRAPH
+0xE7C5 0x890B #CJK UNIFIED IDEOGRAPH
+0xE7C6 0x8917 #CJK UNIFIED IDEOGRAPH
+0xE7C7 0x8918 #CJK UNIFIED IDEOGRAPH
+0xE7C8 0x8919 #CJK UNIFIED IDEOGRAPH
+0xE7C9 0x8906 #CJK UNIFIED IDEOGRAPH
+0xE7CA 0x8916 #CJK UNIFIED IDEOGRAPH
+0xE7CB 0x8911 #CJK UNIFIED IDEOGRAPH
+0xE7CC 0x890E #CJK UNIFIED IDEOGRAPH
+0xE7CD 0x8909 #CJK UNIFIED IDEOGRAPH
+0xE7CE 0x89A2 #CJK UNIFIED IDEOGRAPH
+0xE7CF 0x89A4 #CJK UNIFIED IDEOGRAPH
+0xE7D0 0x89A3 #CJK UNIFIED IDEOGRAPH
+0xE7D1 0x89ED #CJK UNIFIED IDEOGRAPH
+0xE7D2 0x89F0 #CJK UNIFIED IDEOGRAPH
+0xE7D3 0x89EC #CJK UNIFIED IDEOGRAPH
+0xE7D4 0x8ACF #CJK UNIFIED IDEOGRAPH
+0xE7D5 0x8AC6 #CJK UNIFIED IDEOGRAPH
+0xE7D6 0x8AB8 #CJK UNIFIED IDEOGRAPH
+0xE7D7 0x8AD3 #CJK UNIFIED IDEOGRAPH
+0xE7D8 0x8AD1 #CJK UNIFIED IDEOGRAPH
+0xE7D9 0x8AD4 #CJK UNIFIED IDEOGRAPH
+0xE7DA 0x8AD5 #CJK UNIFIED IDEOGRAPH
+0xE7DB 0x8ABB #CJK UNIFIED IDEOGRAPH
+0xE7DC 0x8AD7 #CJK UNIFIED IDEOGRAPH
+0xE7DD 0x8ABE #CJK UNIFIED IDEOGRAPH
+0xE7DE 0x8AC0 #CJK UNIFIED IDEOGRAPH
+0xE7DF 0x8AC5 #CJK UNIFIED IDEOGRAPH
+0xE7E0 0x8AD8 #CJK UNIFIED IDEOGRAPH
+0xE7E1 0x8AC3 #CJK UNIFIED IDEOGRAPH
+0xE7E2 0x8ABA #CJK UNIFIED IDEOGRAPH
+0xE7E3 0x8ABD #CJK UNIFIED IDEOGRAPH
+0xE7E4 0x8AD9 #CJK UNIFIED IDEOGRAPH
+0xE7E5 0x8C3E #CJK UNIFIED IDEOGRAPH
+0xE7E6 0x8C4D #CJK UNIFIED IDEOGRAPH
+0xE7E7 0x8C8F #CJK UNIFIED IDEOGRAPH
+0xE7E8 0x8CE5 #CJK UNIFIED IDEOGRAPH
+0xE7E9 0x8CDF #CJK UNIFIED IDEOGRAPH
+0xE7EA 0x8CD9 #CJK UNIFIED IDEOGRAPH
+0xE7EB 0x8CE8 #CJK UNIFIED IDEOGRAPH
+0xE7EC 0x8CDA #CJK UNIFIED IDEOGRAPH
+0xE7ED 0x8CDD #CJK UNIFIED IDEOGRAPH
+0xE7EE 0x8CE7 #CJK UNIFIED IDEOGRAPH
+0xE7EF 0x8DA0 #CJK UNIFIED IDEOGRAPH
+0xE7F0 0x8D9C #CJK UNIFIED IDEOGRAPH
+0xE7F1 0x8DA1 #CJK UNIFIED IDEOGRAPH
+0xE7F2 0x8D9B #CJK UNIFIED IDEOGRAPH
+0xE7F3 0x8E20 #CJK UNIFIED IDEOGRAPH
+0xE7F4 0x8E23 #CJK UNIFIED IDEOGRAPH
+0xE7F5 0x8E25 #CJK UNIFIED IDEOGRAPH
+0xE7F6 0x8E24 #CJK UNIFIED IDEOGRAPH
+0xE7F7 0x8E2E #CJK UNIFIED IDEOGRAPH
+0xE7F8 0x8E15 #CJK UNIFIED IDEOGRAPH
+0xE7F9 0x8E1B #CJK UNIFIED IDEOGRAPH
+0xE7FA 0x8E16 #CJK UNIFIED IDEOGRAPH
+0xE7FB 0x8E11 #CJK UNIFIED IDEOGRAPH
+0xE7FC 0x8E19 #CJK UNIFIED IDEOGRAPH
+0xE7FD 0x8E26 #CJK UNIFIED IDEOGRAPH
+0xE7FE 0x8E27 #CJK UNIFIED IDEOGRAPH
+0xE840 0x8E14 #CJK UNIFIED IDEOGRAPH
+0xE841 0x8E12 #CJK UNIFIED IDEOGRAPH
+0xE842 0x8E18 #CJK UNIFIED IDEOGRAPH
+0xE843 0x8E13 #CJK UNIFIED IDEOGRAPH
+0xE844 0x8E1C #CJK UNIFIED IDEOGRAPH
+0xE845 0x8E17 #CJK UNIFIED IDEOGRAPH
+0xE846 0x8E1A #CJK UNIFIED IDEOGRAPH
+0xE847 0x8F2C #CJK UNIFIED IDEOGRAPH
+0xE848 0x8F24 #CJK UNIFIED IDEOGRAPH
+0xE849 0x8F18 #CJK UNIFIED IDEOGRAPH
+0xE84A 0x8F1A #CJK UNIFIED IDEOGRAPH
+0xE84B 0x8F20 #CJK UNIFIED IDEOGRAPH
+0xE84C 0x8F23 #CJK UNIFIED IDEOGRAPH
+0xE84D 0x8F16 #CJK UNIFIED IDEOGRAPH
+0xE84E 0x8F17 #CJK UNIFIED IDEOGRAPH
+0xE84F 0x9073 #CJK UNIFIED IDEOGRAPH
+0xE850 0x9070 #CJK UNIFIED IDEOGRAPH
+0xE851 0x906F #CJK UNIFIED IDEOGRAPH
+0xE852 0x9067 #CJK UNIFIED IDEOGRAPH
+0xE853 0x906B #CJK UNIFIED IDEOGRAPH
+0xE854 0x912F #CJK UNIFIED IDEOGRAPH
+0xE855 0x912B #CJK UNIFIED IDEOGRAPH
+0xE856 0x9129 #CJK UNIFIED IDEOGRAPH
+0xE857 0x912A #CJK UNIFIED IDEOGRAPH
+0xE858 0x9132 #CJK UNIFIED IDEOGRAPH
+0xE859 0x9126 #CJK UNIFIED IDEOGRAPH
+0xE85A 0x912E #CJK UNIFIED IDEOGRAPH
+0xE85B 0x9185 #CJK UNIFIED IDEOGRAPH
+0xE85C 0x9186 #CJK UNIFIED IDEOGRAPH
+0xE85D 0x918A #CJK UNIFIED IDEOGRAPH
+0xE85E 0x9181 #CJK UNIFIED IDEOGRAPH
+0xE85F 0x9182 #CJK UNIFIED IDEOGRAPH
+0xE860 0x9184 #CJK UNIFIED IDEOGRAPH
+0xE861 0x9180 #CJK UNIFIED IDEOGRAPH
+0xE862 0x92D0 #CJK UNIFIED IDEOGRAPH
+0xE863 0x92C3 #CJK UNIFIED IDEOGRAPH
+0xE864 0x92C4 #CJK UNIFIED IDEOGRAPH
+0xE865 0x92C0 #CJK UNIFIED IDEOGRAPH
+0xE866 0x92D9 #CJK UNIFIED IDEOGRAPH
+0xE867 0x92B6 #CJK UNIFIED IDEOGRAPH
+0xE868 0x92CF #CJK UNIFIED IDEOGRAPH
+0xE869 0x92F1 #CJK UNIFIED IDEOGRAPH
+0xE86A 0x92DF #CJK UNIFIED IDEOGRAPH
+0xE86B 0x92D8 #CJK UNIFIED IDEOGRAPH
+0xE86C 0x92E9 #CJK UNIFIED IDEOGRAPH
+0xE86D 0x92D7 #CJK UNIFIED IDEOGRAPH
+0xE86E 0x92DD #CJK UNIFIED IDEOGRAPH
+0xE86F 0x92CC #CJK UNIFIED IDEOGRAPH
+0xE870 0x92EF #CJK UNIFIED IDEOGRAPH
+0xE871 0x92C2 #CJK UNIFIED IDEOGRAPH
+0xE872 0x92E8 #CJK UNIFIED IDEOGRAPH
+0xE873 0x92CA #CJK UNIFIED IDEOGRAPH
+0xE874 0x92C8 #CJK UNIFIED IDEOGRAPH
+0xE875 0x92CE #CJK UNIFIED IDEOGRAPH
+0xE876 0x92E6 #CJK UNIFIED IDEOGRAPH
+0xE877 0x92CD #CJK UNIFIED IDEOGRAPH
+0xE878 0x92D5 #CJK UNIFIED IDEOGRAPH
+0xE879 0x92C9 #CJK UNIFIED IDEOGRAPH
+0xE87A 0x92E0 #CJK UNIFIED IDEOGRAPH
+0xE87B 0x92DE #CJK UNIFIED IDEOGRAPH
+0xE87C 0x92E7 #CJK UNIFIED IDEOGRAPH
+0xE87D 0x92D1 #CJK UNIFIED IDEOGRAPH
+0xE87E 0x92D3 #CJK UNIFIED IDEOGRAPH
+0xE8A1 0x92B5 #CJK UNIFIED IDEOGRAPH
+0xE8A2 0x92E1 #CJK UNIFIED IDEOGRAPH
+0xE8A3 0x92C6 #CJK UNIFIED IDEOGRAPH
+0xE8A4 0x92B4 #CJK UNIFIED IDEOGRAPH
+0xE8A5 0x957C #CJK UNIFIED IDEOGRAPH
+0xE8A6 0x95AC #CJK UNIFIED IDEOGRAPH
+0xE8A7 0x95AB #CJK UNIFIED IDEOGRAPH
+0xE8A8 0x95AE #CJK UNIFIED IDEOGRAPH
+0xE8A9 0x95B0 #CJK UNIFIED IDEOGRAPH
+0xE8AA 0x96A4 #CJK UNIFIED IDEOGRAPH
+0xE8AB 0x96A2 #CJK UNIFIED IDEOGRAPH
+0xE8AC 0x96D3 #CJK UNIFIED IDEOGRAPH
+0xE8AD 0x9705 #CJK UNIFIED IDEOGRAPH
+0xE8AE 0x9708 #CJK UNIFIED IDEOGRAPH
+0xE8AF 0x9702 #CJK UNIFIED IDEOGRAPH
+0xE8B0 0x975A #CJK UNIFIED IDEOGRAPH
+0xE8B1 0x978A #CJK UNIFIED IDEOGRAPH
+0xE8B2 0x978E #CJK UNIFIED IDEOGRAPH
+0xE8B3 0x9788 #CJK UNIFIED IDEOGRAPH
+0xE8B4 0x97D0 #CJK UNIFIED IDEOGRAPH
+0xE8B5 0x97CF #CJK UNIFIED IDEOGRAPH
+0xE8B6 0x981E #CJK UNIFIED IDEOGRAPH
+0xE8B7 0x981D #CJK UNIFIED IDEOGRAPH
+0xE8B8 0x9826 #CJK UNIFIED IDEOGRAPH
+0xE8B9 0x9829 #CJK UNIFIED IDEOGRAPH
+0xE8BA 0x9828 #CJK UNIFIED IDEOGRAPH
+0xE8BB 0x9820 #CJK UNIFIED IDEOGRAPH
+0xE8BC 0x981B #CJK UNIFIED IDEOGRAPH
+0xE8BD 0x9827 #CJK UNIFIED IDEOGRAPH
+0xE8BE 0x98B2 #CJK UNIFIED IDEOGRAPH
+0xE8BF 0x9908 #CJK UNIFIED IDEOGRAPH
+0xE8C0 0x98FA #CJK UNIFIED IDEOGRAPH
+0xE8C1 0x9911 #CJK UNIFIED IDEOGRAPH
+0xE8C2 0x9914 #CJK UNIFIED IDEOGRAPH
+0xE8C3 0x9916 #CJK UNIFIED IDEOGRAPH
+0xE8C4 0x9917 #CJK UNIFIED IDEOGRAPH
+0xE8C5 0x9915 #CJK UNIFIED IDEOGRAPH
+0xE8C6 0x99DC #CJK UNIFIED IDEOGRAPH
+0xE8C7 0x99CD #CJK UNIFIED IDEOGRAPH
+0xE8C8 0x99CF #CJK UNIFIED IDEOGRAPH
+0xE8C9 0x99D3 #CJK UNIFIED IDEOGRAPH
+0xE8CA 0x99D4 #CJK UNIFIED IDEOGRAPH
+0xE8CB 0x99CE #CJK UNIFIED IDEOGRAPH
+0xE8CC 0x99C9 #CJK UNIFIED IDEOGRAPH
+0xE8CD 0x99D6 #CJK UNIFIED IDEOGRAPH
+0xE8CE 0x99D8 #CJK UNIFIED IDEOGRAPH
+0xE8CF 0x99CB #CJK UNIFIED IDEOGRAPH
+0xE8D0 0x99D7 #CJK UNIFIED IDEOGRAPH
+0xE8D1 0x99CC #CJK UNIFIED IDEOGRAPH
+0xE8D2 0x9AB3 #CJK UNIFIED IDEOGRAPH
+0xE8D3 0x9AEC #CJK UNIFIED IDEOGRAPH
+0xE8D4 0x9AEB #CJK UNIFIED IDEOGRAPH
+0xE8D5 0x9AF3 #CJK UNIFIED IDEOGRAPH
+0xE8D6 0x9AF2 #CJK UNIFIED IDEOGRAPH
+0xE8D7 0x9AF1 #CJK UNIFIED IDEOGRAPH
+0xE8D8 0x9B46 #CJK UNIFIED IDEOGRAPH
+0xE8D9 0x9B43 #CJK UNIFIED IDEOGRAPH
+0xE8DA 0x9B67 #CJK UNIFIED IDEOGRAPH
+0xE8DB 0x9B74 #CJK UNIFIED IDEOGRAPH
+0xE8DC 0x9B71 #CJK UNIFIED IDEOGRAPH
+0xE8DD 0x9B66 #CJK UNIFIED IDEOGRAPH
+0xE8DE 0x9B76 #CJK UNIFIED IDEOGRAPH
+0xE8DF 0x9B75 #CJK UNIFIED IDEOGRAPH
+0xE8E0 0x9B70 #CJK UNIFIED IDEOGRAPH
+0xE8E1 0x9B68 #CJK UNIFIED IDEOGRAPH
+0xE8E2 0x9B64 #CJK UNIFIED IDEOGRAPH
+0xE8E3 0x9B6C #CJK UNIFIED IDEOGRAPH
+0xE8E4 0x9CFC #CJK UNIFIED IDEOGRAPH
+0xE8E5 0x9CFA #CJK UNIFIED IDEOGRAPH
+0xE8E6 0x9CFD #CJK UNIFIED IDEOGRAPH
+0xE8E7 0x9CFF #CJK UNIFIED IDEOGRAPH
+0xE8E8 0x9CF7 #CJK UNIFIED IDEOGRAPH
+0xE8E9 0x9D07 #CJK UNIFIED IDEOGRAPH
+0xE8EA 0x9D00 #CJK UNIFIED IDEOGRAPH
+0xE8EB 0x9CF9 #CJK UNIFIED IDEOGRAPH
+0xE8EC 0x9CFB #CJK UNIFIED IDEOGRAPH
+0xE8ED 0x9D08 #CJK UNIFIED IDEOGRAPH
+0xE8EE 0x9D05 #CJK UNIFIED IDEOGRAPH
+0xE8EF 0x9D04 #CJK UNIFIED IDEOGRAPH
+0xE8F0 0x9E83 #CJK UNIFIED IDEOGRAPH
+0xE8F1 0x9ED3 #CJK UNIFIED IDEOGRAPH
+0xE8F2 0x9F0F #CJK UNIFIED IDEOGRAPH
+0xE8F3 0x9F10 #CJK UNIFIED IDEOGRAPH
+0xE8F4 0x511C #CJK UNIFIED IDEOGRAPH
+0xE8F5 0x5113 #CJK UNIFIED IDEOGRAPH
+0xE8F6 0x5117 #CJK UNIFIED IDEOGRAPH
+0xE8F7 0x511A #CJK UNIFIED IDEOGRAPH
+0xE8F8 0x5111 #CJK UNIFIED IDEOGRAPH
+0xE8F9 0x51DE #CJK UNIFIED IDEOGRAPH
+0xE8FA 0x5334 #CJK UNIFIED IDEOGRAPH
+0xE8FB 0x53E1 #CJK UNIFIED IDEOGRAPH
+0xE8FC 0x5670 #CJK UNIFIED IDEOGRAPH
+0xE8FD 0x5660 #CJK UNIFIED IDEOGRAPH
+0xE8FE 0x566E #CJK UNIFIED IDEOGRAPH
+0xE940 0x5673 #CJK UNIFIED IDEOGRAPH
+0xE941 0x5666 #CJK UNIFIED IDEOGRAPH
+0xE942 0x5663 #CJK UNIFIED IDEOGRAPH
+0xE943 0x566D #CJK UNIFIED IDEOGRAPH
+0xE944 0x5672 #CJK UNIFIED IDEOGRAPH
+0xE945 0x565E #CJK UNIFIED IDEOGRAPH
+0xE946 0x5677 #CJK UNIFIED IDEOGRAPH
+0xE947 0x571C #CJK UNIFIED IDEOGRAPH
+0xE948 0x571B #CJK UNIFIED IDEOGRAPH
+0xE949 0x58C8 #CJK UNIFIED IDEOGRAPH
+0xE94A 0x58BD #CJK UNIFIED IDEOGRAPH
+0xE94B 0x58C9 #CJK UNIFIED IDEOGRAPH
+0xE94C 0x58BF #CJK UNIFIED IDEOGRAPH
+0xE94D 0x58BA #CJK UNIFIED IDEOGRAPH
+0xE94E 0x58C2 #CJK UNIFIED IDEOGRAPH
+0xE94F 0x58BC #CJK UNIFIED IDEOGRAPH
+0xE950 0x58C6 #CJK UNIFIED IDEOGRAPH
+0xE951 0x5B17 #CJK UNIFIED IDEOGRAPH
+0xE952 0x5B19 #CJK UNIFIED IDEOGRAPH
+0xE953 0x5B1B #CJK UNIFIED IDEOGRAPH
+0xE954 0x5B21 #CJK UNIFIED IDEOGRAPH
+0xE955 0x5B14 #CJK UNIFIED IDEOGRAPH
+0xE956 0x5B13 #CJK UNIFIED IDEOGRAPH
+0xE957 0x5B10 #CJK UNIFIED IDEOGRAPH
+0xE958 0x5B16 #CJK UNIFIED IDEOGRAPH
+0xE959 0x5B28 #CJK UNIFIED IDEOGRAPH
+0xE95A 0x5B1A #CJK UNIFIED IDEOGRAPH
+0xE95B 0x5B20 #CJK UNIFIED IDEOGRAPH
+0xE95C 0x5B1E #CJK UNIFIED IDEOGRAPH
+0xE95D 0x5BEF #CJK UNIFIED IDEOGRAPH
+0xE95E 0x5DAC #CJK UNIFIED IDEOGRAPH
+0xE95F 0x5DB1 #CJK UNIFIED IDEOGRAPH
+0xE960 0x5DA9 #CJK UNIFIED IDEOGRAPH
+0xE961 0x5DA7 #CJK UNIFIED IDEOGRAPH
+0xE962 0x5DB5 #CJK UNIFIED IDEOGRAPH
+0xE963 0x5DB0 #CJK UNIFIED IDEOGRAPH
+0xE964 0x5DAE #CJK UNIFIED IDEOGRAPH
+0xE965 0x5DAA #CJK UNIFIED IDEOGRAPH
+0xE966 0x5DA8 #CJK UNIFIED IDEOGRAPH
+0xE967 0x5DB2 #CJK UNIFIED IDEOGRAPH
+0xE968 0x5DAD #CJK UNIFIED IDEOGRAPH
+0xE969 0x5DAF #CJK UNIFIED IDEOGRAPH
+0xE96A 0x5DB4 #CJK UNIFIED IDEOGRAPH
+0xE96B 0x5E67 #CJK UNIFIED IDEOGRAPH
+0xE96C 0x5E68 #CJK UNIFIED IDEOGRAPH
+0xE96D 0x5E66 #CJK UNIFIED IDEOGRAPH
+0xE96E 0x5E6F #CJK UNIFIED IDEOGRAPH
+0xE96F 0x5EE9 #CJK UNIFIED IDEOGRAPH
+0xE970 0x5EE7 #CJK UNIFIED IDEOGRAPH
+0xE971 0x5EE6 #CJK UNIFIED IDEOGRAPH
+0xE972 0x5EE8 #CJK UNIFIED IDEOGRAPH
+0xE973 0x5EE5 #CJK UNIFIED IDEOGRAPH
+0xE974 0x5F4B #CJK UNIFIED IDEOGRAPH
+0xE975 0x5FBC #CJK UNIFIED IDEOGRAPH
+0xE976 0x619D #CJK UNIFIED IDEOGRAPH
+0xE977 0x61A8 #CJK UNIFIED IDEOGRAPH
+0xE978 0x6196 #CJK UNIFIED IDEOGRAPH
+0xE979 0x61C5 #CJK UNIFIED IDEOGRAPH
+0xE97A 0x61B4 #CJK UNIFIED IDEOGRAPH
+0xE97B 0x61C6 #CJK UNIFIED IDEOGRAPH
+0xE97C 0x61C1 #CJK UNIFIED IDEOGRAPH
+0xE97D 0x61CC #CJK UNIFIED IDEOGRAPH
+0xE97E 0x61BA #CJK UNIFIED IDEOGRAPH
+0xE9A1 0x61BF #CJK UNIFIED IDEOGRAPH
+0xE9A2 0x61B8 #CJK UNIFIED IDEOGRAPH
+0xE9A3 0x618C #CJK UNIFIED IDEOGRAPH
+0xE9A4 0x64D7 #CJK UNIFIED IDEOGRAPH
+0xE9A5 0x64D6 #CJK UNIFIED IDEOGRAPH
+0xE9A6 0x64D0 #CJK UNIFIED IDEOGRAPH
+0xE9A7 0x64CF #CJK UNIFIED IDEOGRAPH
+0xE9A8 0x64C9 #CJK UNIFIED IDEOGRAPH
+0xE9A9 0x64BD #CJK UNIFIED IDEOGRAPH
+0xE9AA 0x6489 #CJK UNIFIED IDEOGRAPH
+0xE9AB 0x64C3 #CJK UNIFIED IDEOGRAPH
+0xE9AC 0x64DB #CJK UNIFIED IDEOGRAPH
+0xE9AD 0x64F3 #CJK UNIFIED IDEOGRAPH
+0xE9AE 0x64D9 #CJK UNIFIED IDEOGRAPH
+0xE9AF 0x6533 #CJK UNIFIED IDEOGRAPH
+0xE9B0 0x657F #CJK UNIFIED IDEOGRAPH
+0xE9B1 0x657C #CJK UNIFIED IDEOGRAPH
+0xE9B2 0x65A2 #CJK UNIFIED IDEOGRAPH
+0xE9B3 0x66C8 #CJK UNIFIED IDEOGRAPH
+0xE9B4 0x66BE #CJK UNIFIED IDEOGRAPH
+0xE9B5 0x66C0 #CJK UNIFIED IDEOGRAPH
+0xE9B6 0x66CA #CJK UNIFIED IDEOGRAPH
+0xE9B7 0x66CB #CJK UNIFIED IDEOGRAPH
+0xE9B8 0x66CF #CJK UNIFIED IDEOGRAPH
+0xE9B9 0x66BD #CJK UNIFIED IDEOGRAPH
+0xE9BA 0x66BB #CJK UNIFIED IDEOGRAPH
+0xE9BB 0x66BA #CJK UNIFIED IDEOGRAPH
+0xE9BC 0x66CC #CJK UNIFIED IDEOGRAPH
+0xE9BD 0x6723 #CJK UNIFIED IDEOGRAPH
+0xE9BE 0x6A34 #CJK UNIFIED IDEOGRAPH
+0xE9BF 0x6A66 #CJK UNIFIED IDEOGRAPH
+0xE9C0 0x6A49 #CJK UNIFIED IDEOGRAPH
+0xE9C1 0x6A67 #CJK UNIFIED IDEOGRAPH
+0xE9C2 0x6A32 #CJK UNIFIED IDEOGRAPH
+0xE9C3 0x6A68 #CJK UNIFIED IDEOGRAPH
+0xE9C4 0x6A3E #CJK UNIFIED IDEOGRAPH
+0xE9C5 0x6A5D #CJK UNIFIED IDEOGRAPH
+0xE9C6 0x6A6D #CJK UNIFIED IDEOGRAPH
+0xE9C7 0x6A76 #CJK UNIFIED IDEOGRAPH
+0xE9C8 0x6A5B #CJK UNIFIED IDEOGRAPH
+0xE9C9 0x6A51 #CJK UNIFIED IDEOGRAPH
+0xE9CA 0x6A28 #CJK UNIFIED IDEOGRAPH
+0xE9CB 0x6A5A #CJK UNIFIED IDEOGRAPH
+0xE9CC 0x6A3B #CJK UNIFIED IDEOGRAPH
+0xE9CD 0x6A3F #CJK UNIFIED IDEOGRAPH
+0xE9CE 0x6A41 #CJK UNIFIED IDEOGRAPH
+0xE9CF 0x6A6A #CJK UNIFIED IDEOGRAPH
+0xE9D0 0x6A64 #CJK UNIFIED IDEOGRAPH
+0xE9D1 0x6A50 #CJK UNIFIED IDEOGRAPH
+0xE9D2 0x6A4F #CJK UNIFIED IDEOGRAPH
+0xE9D3 0x6A54 #CJK UNIFIED IDEOGRAPH
+0xE9D4 0x6A6F #CJK UNIFIED IDEOGRAPH
+0xE9D5 0x6A69 #CJK UNIFIED IDEOGRAPH
+0xE9D6 0x6A60 #CJK UNIFIED IDEOGRAPH
+0xE9D7 0x6A3C #CJK UNIFIED IDEOGRAPH
+0xE9D8 0x6A5E #CJK UNIFIED IDEOGRAPH
+0xE9D9 0x6A56 #CJK UNIFIED IDEOGRAPH
+0xE9DA 0x6A55 #CJK UNIFIED IDEOGRAPH
+0xE9DB 0x6A4D #CJK UNIFIED IDEOGRAPH
+0xE9DC 0x6A4E #CJK UNIFIED IDEOGRAPH
+0xE9DD 0x6A46 #CJK UNIFIED IDEOGRAPH
+0xE9DE 0x6B55 #CJK UNIFIED IDEOGRAPH
+0xE9DF 0x6B54 #CJK UNIFIED IDEOGRAPH
+0xE9E0 0x6B56 #CJK UNIFIED IDEOGRAPH
+0xE9E1 0x6BA7 #CJK UNIFIED IDEOGRAPH
+0xE9E2 0x6BAA #CJK UNIFIED IDEOGRAPH
+0xE9E3 0x6BAB #CJK UNIFIED IDEOGRAPH
+0xE9E4 0x6BC8 #CJK UNIFIED IDEOGRAPH
+0xE9E5 0x6BC7 #CJK UNIFIED IDEOGRAPH
+0xE9E6 0x6C04 #CJK UNIFIED IDEOGRAPH
+0xE9E7 0x6C03 #CJK UNIFIED IDEOGRAPH
+0xE9E8 0x6C06 #CJK UNIFIED IDEOGRAPH
+0xE9E9 0x6FAD #CJK UNIFIED IDEOGRAPH
+0xE9EA 0x6FCB #CJK UNIFIED IDEOGRAPH
+0xE9EB 0x6FA3 #CJK UNIFIED IDEOGRAPH
+0xE9EC 0x6FC7 #CJK UNIFIED IDEOGRAPH
+0xE9ED 0x6FBC #CJK UNIFIED IDEOGRAPH
+0xE9EE 0x6FCE #CJK UNIFIED IDEOGRAPH
+0xE9EF 0x6FC8 #CJK UNIFIED IDEOGRAPH
+0xE9F0 0x6F5E #CJK UNIFIED IDEOGRAPH
+0xE9F1 0x6FC4 #CJK UNIFIED IDEOGRAPH
+0xE9F2 0x6FBD #CJK UNIFIED IDEOGRAPH
+0xE9F3 0x6F9E #CJK UNIFIED IDEOGRAPH
+0xE9F4 0x6FCA #CJK UNIFIED IDEOGRAPH
+0xE9F5 0x6FA8 #CJK UNIFIED IDEOGRAPH
+0xE9F6 0x7004 #CJK UNIFIED IDEOGRAPH
+0xE9F7 0x6FA5 #CJK UNIFIED IDEOGRAPH
+0xE9F8 0x6FAE #CJK UNIFIED IDEOGRAPH
+0xE9F9 0x6FBA #CJK UNIFIED IDEOGRAPH
+0xE9FA 0x6FAC #CJK UNIFIED IDEOGRAPH
+0xE9FB 0x6FAA #CJK UNIFIED IDEOGRAPH
+0xE9FC 0x6FCF #CJK UNIFIED IDEOGRAPH
+0xE9FD 0x6FBF #CJK UNIFIED IDEOGRAPH
+0xE9FE 0x6FB8 #CJK UNIFIED IDEOGRAPH
+0xEA40 0x6FA2 #CJK UNIFIED IDEOGRAPH
+0xEA41 0x6FC9 #CJK UNIFIED IDEOGRAPH
+0xEA42 0x6FAB #CJK UNIFIED IDEOGRAPH
+0xEA43 0x6FCD #CJK UNIFIED IDEOGRAPH
+0xEA44 0x6FAF #CJK UNIFIED IDEOGRAPH
+0xEA45 0x6FB2 #CJK UNIFIED IDEOGRAPH
+0xEA46 0x6FB0 #CJK UNIFIED IDEOGRAPH
+0xEA47 0x71C5 #CJK UNIFIED IDEOGRAPH
+0xEA48 0x71C2 #CJK UNIFIED IDEOGRAPH
+0xEA49 0x71BF #CJK UNIFIED IDEOGRAPH
+0xEA4A 0x71B8 #CJK UNIFIED IDEOGRAPH
+0xEA4B 0x71D6 #CJK UNIFIED IDEOGRAPH
+0xEA4C 0x71C0 #CJK UNIFIED IDEOGRAPH
+0xEA4D 0x71C1 #CJK UNIFIED IDEOGRAPH
+0xEA4E 0x71CB #CJK UNIFIED IDEOGRAPH
+0xEA4F 0x71D4 #CJK UNIFIED IDEOGRAPH
+0xEA50 0x71CA #CJK UNIFIED IDEOGRAPH
+0xEA51 0x71C7 #CJK UNIFIED IDEOGRAPH
+0xEA52 0x71CF #CJK UNIFIED IDEOGRAPH
+0xEA53 0x71BD #CJK UNIFIED IDEOGRAPH
+0xEA54 0x71D8 #CJK UNIFIED IDEOGRAPH
+0xEA55 0x71BC #CJK UNIFIED IDEOGRAPH
+0xEA56 0x71C6 #CJK UNIFIED IDEOGRAPH
+0xEA57 0x71DA #CJK UNIFIED IDEOGRAPH
+0xEA58 0x71DB #CJK UNIFIED IDEOGRAPH
+0xEA59 0x729D #CJK UNIFIED IDEOGRAPH
+0xEA5A 0x729E #CJK UNIFIED IDEOGRAPH
+0xEA5B 0x7369 #CJK UNIFIED IDEOGRAPH
+0xEA5C 0x7366 #CJK UNIFIED IDEOGRAPH
+0xEA5D 0x7367 #CJK UNIFIED IDEOGRAPH
+0xEA5E 0x736C #CJK UNIFIED IDEOGRAPH
+0xEA5F 0x7365 #CJK UNIFIED IDEOGRAPH
+0xEA60 0x736B #CJK UNIFIED IDEOGRAPH
+0xEA61 0x736A #CJK UNIFIED IDEOGRAPH
+0xEA62 0x747F #CJK UNIFIED IDEOGRAPH
+0xEA63 0x749A #CJK UNIFIED IDEOGRAPH
+0xEA64 0x74A0 #CJK UNIFIED IDEOGRAPH
+0xEA65 0x7494 #CJK UNIFIED IDEOGRAPH
+0xEA66 0x7492 #CJK UNIFIED IDEOGRAPH
+0xEA67 0x7495 #CJK UNIFIED IDEOGRAPH
+0xEA68 0x74A1 #CJK UNIFIED IDEOGRAPH
+0xEA69 0x750B #CJK UNIFIED IDEOGRAPH
+0xEA6A 0x7580 #CJK UNIFIED IDEOGRAPH
+0xEA6B 0x762F #CJK UNIFIED IDEOGRAPH
+0xEA6C 0x762D #CJK UNIFIED IDEOGRAPH
+0xEA6D 0x7631 #CJK UNIFIED IDEOGRAPH
+0xEA6E 0x763D #CJK UNIFIED IDEOGRAPH
+0xEA6F 0x7633 #CJK UNIFIED IDEOGRAPH
+0xEA70 0x763C #CJK UNIFIED IDEOGRAPH
+0xEA71 0x7635 #CJK UNIFIED IDEOGRAPH
+0xEA72 0x7632 #CJK UNIFIED IDEOGRAPH
+0xEA73 0x7630 #CJK UNIFIED IDEOGRAPH
+0xEA74 0x76BB #CJK UNIFIED IDEOGRAPH
+0xEA75 0x76E6 #CJK UNIFIED IDEOGRAPH
+0xEA76 0x779A #CJK UNIFIED IDEOGRAPH
+0xEA77 0x779D #CJK UNIFIED IDEOGRAPH
+0xEA78 0x77A1 #CJK UNIFIED IDEOGRAPH
+0xEA79 0x779C #CJK UNIFIED IDEOGRAPH
+0xEA7A 0x779B #CJK UNIFIED IDEOGRAPH
+0xEA7B 0x77A2 #CJK UNIFIED IDEOGRAPH
+0xEA7C 0x77A3 #CJK UNIFIED IDEOGRAPH
+0xEA7D 0x7795 #CJK UNIFIED IDEOGRAPH
+0xEA7E 0x7799 #CJK UNIFIED IDEOGRAPH
+0xEAA1 0x7797 #CJK UNIFIED IDEOGRAPH
+0xEAA2 0x78DD #CJK UNIFIED IDEOGRAPH
+0xEAA3 0x78E9 #CJK UNIFIED IDEOGRAPH
+0xEAA4 0x78E5 #CJK UNIFIED IDEOGRAPH
+0xEAA5 0x78EA #CJK UNIFIED IDEOGRAPH
+0xEAA6 0x78DE #CJK UNIFIED IDEOGRAPH
+0xEAA7 0x78E3 #CJK UNIFIED IDEOGRAPH
+0xEAA8 0x78DB #CJK UNIFIED IDEOGRAPH
+0xEAA9 0x78E1 #CJK UNIFIED IDEOGRAPH
+0xEAAA 0x78E2 #CJK UNIFIED IDEOGRAPH
+0xEAAB 0x78ED #CJK UNIFIED IDEOGRAPH
+0xEAAC 0x78DF #CJK UNIFIED IDEOGRAPH
+0xEAAD 0x78E0 #CJK UNIFIED IDEOGRAPH
+0xEAAE 0x79A4 #CJK UNIFIED IDEOGRAPH
+0xEAAF 0x7A44 #CJK UNIFIED IDEOGRAPH
+0xEAB0 0x7A48 #CJK UNIFIED IDEOGRAPH
+0xEAB1 0x7A47 #CJK UNIFIED IDEOGRAPH
+0xEAB2 0x7AB6 #CJK UNIFIED IDEOGRAPH
+0xEAB3 0x7AB8 #CJK UNIFIED IDEOGRAPH
+0xEAB4 0x7AB5 #CJK UNIFIED IDEOGRAPH
+0xEAB5 0x7AB1 #CJK UNIFIED IDEOGRAPH
+0xEAB6 0x7AB7 #CJK UNIFIED IDEOGRAPH
+0xEAB7 0x7BDE #CJK UNIFIED IDEOGRAPH
+0xEAB8 0x7BE3 #CJK UNIFIED IDEOGRAPH
+0xEAB9 0x7BE7 #CJK UNIFIED IDEOGRAPH
+0xEABA 0x7BDD #CJK UNIFIED IDEOGRAPH
+0xEABB 0x7BD5 #CJK UNIFIED IDEOGRAPH
+0xEABC 0x7BE5 #CJK UNIFIED IDEOGRAPH
+0xEABD 0x7BDA #CJK UNIFIED IDEOGRAPH
+0xEABE 0x7BE8 #CJK UNIFIED IDEOGRAPH
+0xEABF 0x7BF9 #CJK UNIFIED IDEOGRAPH
+0xEAC0 0x7BD4 #CJK UNIFIED IDEOGRAPH
+0xEAC1 0x7BEA #CJK UNIFIED IDEOGRAPH
+0xEAC2 0x7BE2 #CJK UNIFIED IDEOGRAPH
+0xEAC3 0x7BDC #CJK UNIFIED IDEOGRAPH
+0xEAC4 0x7BEB #CJK UNIFIED IDEOGRAPH
+0xEAC5 0x7BD8 #CJK UNIFIED IDEOGRAPH
+0xEAC6 0x7BDF #CJK UNIFIED IDEOGRAPH
+0xEAC7 0x7CD2 #CJK UNIFIED IDEOGRAPH
+0xEAC8 0x7CD4 #CJK UNIFIED IDEOGRAPH
+0xEAC9 0x7CD7 #CJK UNIFIED IDEOGRAPH
+0xEACA 0x7CD0 #CJK UNIFIED IDEOGRAPH
+0xEACB 0x7CD1 #CJK UNIFIED IDEOGRAPH
+0xEACC 0x7E12 #CJK UNIFIED IDEOGRAPH
+0xEACD 0x7E21 #CJK UNIFIED IDEOGRAPH
+0xEACE 0x7E17 #CJK UNIFIED IDEOGRAPH
+0xEACF 0x7E0C #CJK UNIFIED IDEOGRAPH
+0xEAD0 0x7E1F #CJK UNIFIED IDEOGRAPH
+0xEAD1 0x7E20 #CJK UNIFIED IDEOGRAPH
+0xEAD2 0x7E13 #CJK UNIFIED IDEOGRAPH
+0xEAD3 0x7E0E #CJK UNIFIED IDEOGRAPH
+0xEAD4 0x7E1C #CJK UNIFIED IDEOGRAPH
+0xEAD5 0x7E15 #CJK UNIFIED IDEOGRAPH
+0xEAD6 0x7E1A #CJK UNIFIED IDEOGRAPH
+0xEAD7 0x7E22 #CJK UNIFIED IDEOGRAPH
+0xEAD8 0x7E0B #CJK UNIFIED IDEOGRAPH
+0xEAD9 0x7E0F #CJK UNIFIED IDEOGRAPH
+0xEADA 0x7E16 #CJK UNIFIED IDEOGRAPH
+0xEADB 0x7E0D #CJK UNIFIED IDEOGRAPH
+0xEADC 0x7E14 #CJK UNIFIED IDEOGRAPH
+0xEADD 0x7E25 #CJK UNIFIED IDEOGRAPH
+0xEADE 0x7E24 #CJK UNIFIED IDEOGRAPH
+0xEADF 0x7F43 #CJK UNIFIED IDEOGRAPH
+0xEAE0 0x7F7B #CJK UNIFIED IDEOGRAPH
+0xEAE1 0x7F7C #CJK UNIFIED IDEOGRAPH
+0xEAE2 0x7F7A #CJK UNIFIED IDEOGRAPH
+0xEAE3 0x7FB1 #CJK UNIFIED IDEOGRAPH
+0xEAE4 0x7FEF #CJK UNIFIED IDEOGRAPH
+0xEAE5 0x802A #CJK UNIFIED IDEOGRAPH
+0xEAE6 0x8029 #CJK UNIFIED IDEOGRAPH
+0xEAE7 0x806C #CJK UNIFIED IDEOGRAPH
+0xEAE8 0x81B1 #CJK UNIFIED IDEOGRAPH
+0xEAE9 0x81A6 #CJK UNIFIED IDEOGRAPH
+0xEAEA 0x81AE #CJK UNIFIED IDEOGRAPH
+0xEAEB 0x81B9 #CJK UNIFIED IDEOGRAPH
+0xEAEC 0x81B5 #CJK UNIFIED IDEOGRAPH
+0xEAED 0x81AB #CJK UNIFIED IDEOGRAPH
+0xEAEE 0x81B0 #CJK UNIFIED IDEOGRAPH
+0xEAEF 0x81AC #CJK UNIFIED IDEOGRAPH
+0xEAF0 0x81B4 #CJK UNIFIED IDEOGRAPH
+0xEAF1 0x81B2 #CJK UNIFIED IDEOGRAPH
+0xEAF2 0x81B7 #CJK UNIFIED IDEOGRAPH
+0xEAF3 0x81A7 #CJK UNIFIED IDEOGRAPH
+0xEAF4 0x81F2 #CJK UNIFIED IDEOGRAPH
+0xEAF5 0x8255 #CJK UNIFIED IDEOGRAPH
+0xEAF6 0x8256 #CJK UNIFIED IDEOGRAPH
+0xEAF7 0x8257 #CJK UNIFIED IDEOGRAPH
+0xEAF8 0x8556 #CJK UNIFIED IDEOGRAPH
+0xEAF9 0x8545 #CJK UNIFIED IDEOGRAPH
+0xEAFA 0x856B #CJK UNIFIED IDEOGRAPH
+0xEAFB 0x854D #CJK UNIFIED IDEOGRAPH
+0xEAFC 0x8553 #CJK UNIFIED IDEOGRAPH
+0xEAFD 0x8561 #CJK UNIFIED IDEOGRAPH
+0xEAFE 0x8558 #CJK UNIFIED IDEOGRAPH
+0xEB40 0x8540 #CJK UNIFIED IDEOGRAPH
+0xEB41 0x8546 #CJK UNIFIED IDEOGRAPH
+0xEB42 0x8564 #CJK UNIFIED IDEOGRAPH
+0xEB43 0x8541 #CJK UNIFIED IDEOGRAPH
+0xEB44 0x8562 #CJK UNIFIED IDEOGRAPH
+0xEB45 0x8544 #CJK UNIFIED IDEOGRAPH
+0xEB46 0x8551 #CJK UNIFIED IDEOGRAPH
+0xEB47 0x8547 #CJK UNIFIED IDEOGRAPH
+0xEB48 0x8563 #CJK UNIFIED IDEOGRAPH
+0xEB49 0x853E #CJK UNIFIED IDEOGRAPH
+0xEB4A 0x855B #CJK UNIFIED IDEOGRAPH
+0xEB4B 0x8571 #CJK UNIFIED IDEOGRAPH
+0xEB4C 0x854E #CJK UNIFIED IDEOGRAPH
+0xEB4D 0x856E #CJK UNIFIED IDEOGRAPH
+0xEB4E 0x8575 #CJK UNIFIED IDEOGRAPH
+0xEB4F 0x8555 #CJK UNIFIED IDEOGRAPH
+0xEB50 0x8567 #CJK UNIFIED IDEOGRAPH
+0xEB51 0x8560 #CJK UNIFIED IDEOGRAPH
+0xEB52 0x858C #CJK UNIFIED IDEOGRAPH
+0xEB53 0x8566 #CJK UNIFIED IDEOGRAPH
+0xEB54 0x855D #CJK UNIFIED IDEOGRAPH
+0xEB55 0x8554 #CJK UNIFIED IDEOGRAPH
+0xEB56 0x8565 #CJK UNIFIED IDEOGRAPH
+0xEB57 0x856C #CJK UNIFIED IDEOGRAPH
+0xEB58 0x8663 #CJK UNIFIED IDEOGRAPH
+0xEB59 0x8665 #CJK UNIFIED IDEOGRAPH
+0xEB5A 0x8664 #CJK UNIFIED IDEOGRAPH
+0xEB5B 0x879B #CJK UNIFIED IDEOGRAPH
+0xEB5C 0x878F #CJK UNIFIED IDEOGRAPH
+0xEB5D 0x8797 #CJK UNIFIED IDEOGRAPH
+0xEB5E 0x8793 #CJK UNIFIED IDEOGRAPH
+0xEB5F 0x8792 #CJK UNIFIED IDEOGRAPH
+0xEB60 0x8788 #CJK UNIFIED IDEOGRAPH
+0xEB61 0x8781 #CJK UNIFIED IDEOGRAPH
+0xEB62 0x8796 #CJK UNIFIED IDEOGRAPH
+0xEB63 0x8798 #CJK UNIFIED IDEOGRAPH
+0xEB64 0x8779 #CJK UNIFIED IDEOGRAPH
+0xEB65 0x8787 #CJK UNIFIED IDEOGRAPH
+0xEB66 0x87A3 #CJK UNIFIED IDEOGRAPH
+0xEB67 0x8785 #CJK UNIFIED IDEOGRAPH
+0xEB68 0x8790 #CJK UNIFIED IDEOGRAPH
+0xEB69 0x8791 #CJK UNIFIED IDEOGRAPH
+0xEB6A 0x879D #CJK UNIFIED IDEOGRAPH
+0xEB6B 0x8784 #CJK UNIFIED IDEOGRAPH
+0xEB6C 0x8794 #CJK UNIFIED IDEOGRAPH
+0xEB6D 0x879C #CJK UNIFIED IDEOGRAPH
+0xEB6E 0x879A #CJK UNIFIED IDEOGRAPH
+0xEB6F 0x8789 #CJK UNIFIED IDEOGRAPH
+0xEB70 0x891E #CJK UNIFIED IDEOGRAPH
+0xEB71 0x8926 #CJK UNIFIED IDEOGRAPH
+0xEB72 0x8930 #CJK UNIFIED IDEOGRAPH
+0xEB73 0x892D #CJK UNIFIED IDEOGRAPH
+0xEB74 0x892E #CJK UNIFIED IDEOGRAPH
+0xEB75 0x8927 #CJK UNIFIED IDEOGRAPH
+0xEB76 0x8931 #CJK UNIFIED IDEOGRAPH
+0xEB77 0x8922 #CJK UNIFIED IDEOGRAPH
+0xEB78 0x8929 #CJK UNIFIED IDEOGRAPH
+0xEB79 0x8923 #CJK UNIFIED IDEOGRAPH
+0xEB7A 0x892F #CJK UNIFIED IDEOGRAPH
+0xEB7B 0x892C #CJK UNIFIED IDEOGRAPH
+0xEB7C 0x891F #CJK UNIFIED IDEOGRAPH
+0xEB7D 0x89F1 #CJK UNIFIED IDEOGRAPH
+0xEB7E 0x8AE0 #CJK UNIFIED IDEOGRAPH
+0xEBA1 0x8AE2 #CJK UNIFIED IDEOGRAPH
+0xEBA2 0x8AF2 #CJK UNIFIED IDEOGRAPH
+0xEBA3 0x8AF4 #CJK UNIFIED IDEOGRAPH
+0xEBA4 0x8AF5 #CJK UNIFIED IDEOGRAPH
+0xEBA5 0x8ADD #CJK UNIFIED IDEOGRAPH
+0xEBA6 0x8B14 #CJK UNIFIED IDEOGRAPH
+0xEBA7 0x8AE4 #CJK UNIFIED IDEOGRAPH
+0xEBA8 0x8ADF #CJK UNIFIED IDEOGRAPH
+0xEBA9 0x8AF0 #CJK UNIFIED IDEOGRAPH
+0xEBAA 0x8AC8 #CJK UNIFIED IDEOGRAPH
+0xEBAB 0x8ADE #CJK UNIFIED IDEOGRAPH
+0xEBAC 0x8AE1 #CJK UNIFIED IDEOGRAPH
+0xEBAD 0x8AE8 #CJK UNIFIED IDEOGRAPH
+0xEBAE 0x8AFF #CJK UNIFIED IDEOGRAPH
+0xEBAF 0x8AEF #CJK UNIFIED IDEOGRAPH
+0xEBB0 0x8AFB #CJK UNIFIED IDEOGRAPH
+0xEBB1 0x8C91 #CJK UNIFIED IDEOGRAPH
+0xEBB2 0x8C92 #CJK UNIFIED IDEOGRAPH
+0xEBB3 0x8C90 #CJK UNIFIED IDEOGRAPH
+0xEBB4 0x8CF5 #CJK UNIFIED IDEOGRAPH
+0xEBB5 0x8CEE #CJK UNIFIED IDEOGRAPH
+0xEBB6 0x8CF1 #CJK UNIFIED IDEOGRAPH
+0xEBB7 0x8CF0 #CJK UNIFIED IDEOGRAPH
+0xEBB8 0x8CF3 #CJK UNIFIED IDEOGRAPH
+0xEBB9 0x8D6C #CJK UNIFIED IDEOGRAPH
+0xEBBA 0x8D6E #CJK UNIFIED IDEOGRAPH
+0xEBBB 0x8DA5 #CJK UNIFIED IDEOGRAPH
+0xEBBC 0x8DA7 #CJK UNIFIED IDEOGRAPH
+0xEBBD 0x8E33 #CJK UNIFIED IDEOGRAPH
+0xEBBE 0x8E3E #CJK UNIFIED IDEOGRAPH
+0xEBBF 0x8E38 #CJK UNIFIED IDEOGRAPH
+0xEBC0 0x8E40 #CJK UNIFIED IDEOGRAPH
+0xEBC1 0x8E45 #CJK UNIFIED IDEOGRAPH
+0xEBC2 0x8E36 #CJK UNIFIED IDEOGRAPH
+0xEBC3 0x8E3C #CJK UNIFIED IDEOGRAPH
+0xEBC4 0x8E3D #CJK UNIFIED IDEOGRAPH
+0xEBC5 0x8E41 #CJK UNIFIED IDEOGRAPH
+0xEBC6 0x8E30 #CJK UNIFIED IDEOGRAPH
+0xEBC7 0x8E3F #CJK UNIFIED IDEOGRAPH
+0xEBC8 0x8EBD #CJK UNIFIED IDEOGRAPH
+0xEBC9 0x8F36 #CJK UNIFIED IDEOGRAPH
+0xEBCA 0x8F2E #CJK UNIFIED IDEOGRAPH
+0xEBCB 0x8F35 #CJK UNIFIED IDEOGRAPH
+0xEBCC 0x8F32 #CJK UNIFIED IDEOGRAPH
+0xEBCD 0x8F39 #CJK UNIFIED IDEOGRAPH
+0xEBCE 0x8F37 #CJK UNIFIED IDEOGRAPH
+0xEBCF 0x8F34 #CJK UNIFIED IDEOGRAPH
+0xEBD0 0x9076 #CJK UNIFIED IDEOGRAPH
+0xEBD1 0x9079 #CJK UNIFIED IDEOGRAPH
+0xEBD2 0x907B #CJK UNIFIED IDEOGRAPH
+0xEBD3 0x9086 #CJK UNIFIED IDEOGRAPH
+0xEBD4 0x90FA #CJK UNIFIED IDEOGRAPH
+0xEBD5 0x9133 #CJK UNIFIED IDEOGRAPH
+0xEBD6 0x9135 #CJK UNIFIED IDEOGRAPH
+0xEBD7 0x9136 #CJK UNIFIED IDEOGRAPH
+0xEBD8 0x9193 #CJK UNIFIED IDEOGRAPH
+0xEBD9 0x9190 #CJK UNIFIED IDEOGRAPH
+0xEBDA 0x9191 #CJK UNIFIED IDEOGRAPH
+0xEBDB 0x918D #CJK UNIFIED IDEOGRAPH
+0xEBDC 0x918F #CJK UNIFIED IDEOGRAPH
+0xEBDD 0x9327 #CJK UNIFIED IDEOGRAPH
+0xEBDE 0x931E #CJK UNIFIED IDEOGRAPH
+0xEBDF 0x9308 #CJK UNIFIED IDEOGRAPH
+0xEBE0 0x931F #CJK UNIFIED IDEOGRAPH
+0xEBE1 0x9306 #CJK UNIFIED IDEOGRAPH
+0xEBE2 0x930F #CJK UNIFIED IDEOGRAPH
+0xEBE3 0x937A #CJK UNIFIED IDEOGRAPH
+0xEBE4 0x9338 #CJK UNIFIED IDEOGRAPH
+0xEBE5 0x933C #CJK UNIFIED IDEOGRAPH
+0xEBE6 0x931B #CJK UNIFIED IDEOGRAPH
+0xEBE7 0x9323 #CJK UNIFIED IDEOGRAPH
+0xEBE8 0x9312 #CJK UNIFIED IDEOGRAPH
+0xEBE9 0x9301 #CJK UNIFIED IDEOGRAPH
+0xEBEA 0x9346 #CJK UNIFIED IDEOGRAPH
+0xEBEB 0x932D #CJK UNIFIED IDEOGRAPH
+0xEBEC 0x930E #CJK UNIFIED IDEOGRAPH
+0xEBED 0x930D #CJK UNIFIED IDEOGRAPH
+0xEBEE 0x92CB #CJK UNIFIED IDEOGRAPH
+0xEBEF 0x931D #CJK UNIFIED IDEOGRAPH
+0xEBF0 0x92FA #CJK UNIFIED IDEOGRAPH
+0xEBF1 0x9325 #CJK UNIFIED IDEOGRAPH
+0xEBF2 0x9313 #CJK UNIFIED IDEOGRAPH
+0xEBF3 0x92F9 #CJK UNIFIED IDEOGRAPH
+0xEBF4 0x92F7 #CJK UNIFIED IDEOGRAPH
+0xEBF5 0x9334 #CJK UNIFIED IDEOGRAPH
+0xEBF6 0x9302 #CJK UNIFIED IDEOGRAPH
+0xEBF7 0x9324 #CJK UNIFIED IDEOGRAPH
+0xEBF8 0x92FF #CJK UNIFIED IDEOGRAPH
+0xEBF9 0x9329 #CJK UNIFIED IDEOGRAPH
+0xEBFA 0x9339 #CJK UNIFIED IDEOGRAPH
+0xEBFB 0x9335 #CJK UNIFIED IDEOGRAPH
+0xEBFC 0x932A #CJK UNIFIED IDEOGRAPH
+0xEBFD 0x9314 #CJK UNIFIED IDEOGRAPH
+0xEBFE 0x930C #CJK UNIFIED IDEOGRAPH
+0xEC40 0x930B #CJK UNIFIED IDEOGRAPH
+0xEC41 0x92FE #CJK UNIFIED IDEOGRAPH
+0xEC42 0x9309 #CJK UNIFIED IDEOGRAPH
+0xEC43 0x9300 #CJK UNIFIED IDEOGRAPH
+0xEC44 0x92FB #CJK UNIFIED IDEOGRAPH
+0xEC45 0x9316 #CJK UNIFIED IDEOGRAPH
+0xEC46 0x95BC #CJK UNIFIED IDEOGRAPH
+0xEC47 0x95CD #CJK UNIFIED IDEOGRAPH
+0xEC48 0x95BE #CJK UNIFIED IDEOGRAPH
+0xEC49 0x95B9 #CJK UNIFIED IDEOGRAPH
+0xEC4A 0x95BA #CJK UNIFIED IDEOGRAPH
+0xEC4B 0x95B6 #CJK UNIFIED IDEOGRAPH
+0xEC4C 0x95BF #CJK UNIFIED IDEOGRAPH
+0xEC4D 0x95B5 #CJK UNIFIED IDEOGRAPH
+0xEC4E 0x95BD #CJK UNIFIED IDEOGRAPH
+0xEC4F 0x96A9 #CJK UNIFIED IDEOGRAPH
+0xEC50 0x96D4 #CJK UNIFIED IDEOGRAPH
+0xEC51 0x970B #CJK UNIFIED IDEOGRAPH
+0xEC52 0x9712 #CJK UNIFIED IDEOGRAPH
+0xEC53 0x9710 #CJK UNIFIED IDEOGRAPH
+0xEC54 0x9799 #CJK UNIFIED IDEOGRAPH
+0xEC55 0x9797 #CJK UNIFIED IDEOGRAPH
+0xEC56 0x9794 #CJK UNIFIED IDEOGRAPH
+0xEC57 0x97F0 #CJK UNIFIED IDEOGRAPH
+0xEC58 0x97F8 #CJK UNIFIED IDEOGRAPH
+0xEC59 0x9835 #CJK UNIFIED IDEOGRAPH
+0xEC5A 0x982F #CJK UNIFIED IDEOGRAPH
+0xEC5B 0x9832 #CJK UNIFIED IDEOGRAPH
+0xEC5C 0x9924 #CJK UNIFIED IDEOGRAPH
+0xEC5D 0x991F #CJK UNIFIED IDEOGRAPH
+0xEC5E 0x9927 #CJK UNIFIED IDEOGRAPH
+0xEC5F 0x9929 #CJK UNIFIED IDEOGRAPH
+0xEC60 0x999E #CJK UNIFIED IDEOGRAPH
+0xEC61 0x99EE #CJK UNIFIED IDEOGRAPH
+0xEC62 0x99EC #CJK UNIFIED IDEOGRAPH
+0xEC63 0x99E5 #CJK UNIFIED IDEOGRAPH
+0xEC64 0x99E4 #CJK UNIFIED IDEOGRAPH
+0xEC65 0x99F0 #CJK UNIFIED IDEOGRAPH
+0xEC66 0x99E3 #CJK UNIFIED IDEOGRAPH
+0xEC67 0x99EA #CJK UNIFIED IDEOGRAPH
+0xEC68 0x99E9 #CJK UNIFIED IDEOGRAPH
+0xEC69 0x99E7 #CJK UNIFIED IDEOGRAPH
+0xEC6A 0x9AB9 #CJK UNIFIED IDEOGRAPH
+0xEC6B 0x9ABF #CJK UNIFIED IDEOGRAPH
+0xEC6C 0x9AB4 #CJK UNIFIED IDEOGRAPH
+0xEC6D 0x9ABB #CJK UNIFIED IDEOGRAPH
+0xEC6E 0x9AF6 #CJK UNIFIED IDEOGRAPH
+0xEC6F 0x9AFA #CJK UNIFIED IDEOGRAPH
+0xEC70 0x9AF9 #CJK UNIFIED IDEOGRAPH
+0xEC71 0x9AF7 #CJK UNIFIED IDEOGRAPH
+0xEC72 0x9B33 #CJK UNIFIED IDEOGRAPH
+0xEC73 0x9B80 #CJK UNIFIED IDEOGRAPH
+0xEC74 0x9B85 #CJK UNIFIED IDEOGRAPH
+0xEC75 0x9B87 #CJK UNIFIED IDEOGRAPH
+0xEC76 0x9B7C #CJK UNIFIED IDEOGRAPH
+0xEC77 0x9B7E #CJK UNIFIED IDEOGRAPH
+0xEC78 0x9B7B #CJK UNIFIED IDEOGRAPH
+0xEC79 0x9B82 #CJK UNIFIED IDEOGRAPH
+0xEC7A 0x9B93 #CJK UNIFIED IDEOGRAPH
+0xEC7B 0x9B92 #CJK UNIFIED IDEOGRAPH
+0xEC7C 0x9B90 #CJK UNIFIED IDEOGRAPH
+0xEC7D 0x9B7A #CJK UNIFIED IDEOGRAPH
+0xEC7E 0x9B95 #CJK UNIFIED IDEOGRAPH
+0xECA1 0x9B7D #CJK UNIFIED IDEOGRAPH
+0xECA2 0x9B88 #CJK UNIFIED IDEOGRAPH
+0xECA3 0x9D25 #CJK UNIFIED IDEOGRAPH
+0xECA4 0x9D17 #CJK UNIFIED IDEOGRAPH
+0xECA5 0x9D20 #CJK UNIFIED IDEOGRAPH
+0xECA6 0x9D1E #CJK UNIFIED IDEOGRAPH
+0xECA7 0x9D14 #CJK UNIFIED IDEOGRAPH
+0xECA8 0x9D29 #CJK UNIFIED IDEOGRAPH
+0xECA9 0x9D1D #CJK UNIFIED IDEOGRAPH
+0xECAA 0x9D18 #CJK UNIFIED IDEOGRAPH
+0xECAB 0x9D22 #CJK UNIFIED IDEOGRAPH
+0xECAC 0x9D10 #CJK UNIFIED IDEOGRAPH
+0xECAD 0x9D19 #CJK UNIFIED IDEOGRAPH
+0xECAE 0x9D1F #CJK UNIFIED IDEOGRAPH
+0xECAF 0x9E88 #CJK UNIFIED IDEOGRAPH
+0xECB0 0x9E86 #CJK UNIFIED IDEOGRAPH
+0xECB1 0x9E87 #CJK UNIFIED IDEOGRAPH
+0xECB2 0x9EAE #CJK UNIFIED IDEOGRAPH
+0xECB3 0x9EAD #CJK UNIFIED IDEOGRAPH
+0xECB4 0x9ED5 #CJK UNIFIED IDEOGRAPH
+0xECB5 0x9ED6 #CJK UNIFIED IDEOGRAPH
+0xECB6 0x9EFA #CJK UNIFIED IDEOGRAPH
+0xECB7 0x9F12 #CJK UNIFIED IDEOGRAPH
+0xECB8 0x9F3D #CJK UNIFIED IDEOGRAPH
+0xECB9 0x5126 #CJK UNIFIED IDEOGRAPH
+0xECBA 0x5125 #CJK UNIFIED IDEOGRAPH
+0xECBB 0x5122 #CJK UNIFIED IDEOGRAPH
+0xECBC 0x5124 #CJK UNIFIED IDEOGRAPH
+0xECBD 0x5120 #CJK UNIFIED IDEOGRAPH
+0xECBE 0x5129 #CJK UNIFIED IDEOGRAPH
+0xECBF 0x52F4 #CJK UNIFIED IDEOGRAPH
+0xECC0 0x5693 #CJK UNIFIED IDEOGRAPH
+0xECC1 0x568C #CJK UNIFIED IDEOGRAPH
+0xECC2 0x568D #CJK UNIFIED IDEOGRAPH
+0xECC3 0x5686 #CJK UNIFIED IDEOGRAPH
+0xECC4 0x5684 #CJK UNIFIED IDEOGRAPH
+0xECC5 0x5683 #CJK UNIFIED IDEOGRAPH
+0xECC6 0x567E #CJK UNIFIED IDEOGRAPH
+0xECC7 0x5682 #CJK UNIFIED IDEOGRAPH
+0xECC8 0x567F #CJK UNIFIED IDEOGRAPH
+0xECC9 0x5681 #CJK UNIFIED IDEOGRAPH
+0xECCA 0x58D6 #CJK UNIFIED IDEOGRAPH
+0xECCB 0x58D4 #CJK UNIFIED IDEOGRAPH
+0xECCC 0x58CF #CJK UNIFIED IDEOGRAPH
+0xECCD 0x58D2 #CJK UNIFIED IDEOGRAPH
+0xECCE 0x5B2D #CJK UNIFIED IDEOGRAPH
+0xECCF 0x5B25 #CJK UNIFIED IDEOGRAPH
+0xECD0 0x5B32 #CJK UNIFIED IDEOGRAPH
+0xECD1 0x5B23 #CJK UNIFIED IDEOGRAPH
+0xECD2 0x5B2C #CJK UNIFIED IDEOGRAPH
+0xECD3 0x5B27 #CJK UNIFIED IDEOGRAPH
+0xECD4 0x5B26 #CJK UNIFIED IDEOGRAPH
+0xECD5 0x5B2F #CJK UNIFIED IDEOGRAPH
+0xECD6 0x5B2E #CJK UNIFIED IDEOGRAPH
+0xECD7 0x5B7B #CJK UNIFIED IDEOGRAPH
+0xECD8 0x5BF1 #CJK UNIFIED IDEOGRAPH
+0xECD9 0x5BF2 #CJK UNIFIED IDEOGRAPH
+0xECDA 0x5DB7 #CJK UNIFIED IDEOGRAPH
+0xECDB 0x5E6C #CJK UNIFIED IDEOGRAPH
+0xECDC 0x5E6A #CJK UNIFIED IDEOGRAPH
+0xECDD 0x5FBE #CJK UNIFIED IDEOGRAPH
+0xECDE 0x5FBB #CJK UNIFIED IDEOGRAPH
+0xECDF 0x61C3 #CJK UNIFIED IDEOGRAPH
+0xECE0 0x61B5 #CJK UNIFIED IDEOGRAPH
+0xECE1 0x61BC #CJK UNIFIED IDEOGRAPH
+0xECE2 0x61E7 #CJK UNIFIED IDEOGRAPH
+0xECE3 0x61E0 #CJK UNIFIED IDEOGRAPH
+0xECE4 0x61E5 #CJK UNIFIED IDEOGRAPH
+0xECE5 0x61E4 #CJK UNIFIED IDEOGRAPH
+0xECE6 0x61E8 #CJK UNIFIED IDEOGRAPH
+0xECE7 0x61DE #CJK UNIFIED IDEOGRAPH
+0xECE8 0x64EF #CJK UNIFIED IDEOGRAPH
+0xECE9 0x64E9 #CJK UNIFIED IDEOGRAPH
+0xECEA 0x64E3 #CJK UNIFIED IDEOGRAPH
+0xECEB 0x64EB #CJK UNIFIED IDEOGRAPH
+0xECEC 0x64E4 #CJK UNIFIED IDEOGRAPH
+0xECED 0x64E8 #CJK UNIFIED IDEOGRAPH
+0xECEE 0x6581 #CJK UNIFIED IDEOGRAPH
+0xECEF 0x6580 #CJK UNIFIED IDEOGRAPH
+0xECF0 0x65B6 #CJK UNIFIED IDEOGRAPH
+0xECF1 0x65DA #CJK UNIFIED IDEOGRAPH
+0xECF2 0x66D2 #CJK UNIFIED IDEOGRAPH
+0xECF3 0x6A8D #CJK UNIFIED IDEOGRAPH
+0xECF4 0x6A96 #CJK UNIFIED IDEOGRAPH
+0xECF5 0x6A81 #CJK UNIFIED IDEOGRAPH
+0xECF6 0x6AA5 #CJK UNIFIED IDEOGRAPH
+0xECF7 0x6A89 #CJK UNIFIED IDEOGRAPH
+0xECF8 0x6A9F #CJK UNIFIED IDEOGRAPH
+0xECF9 0x6A9B #CJK UNIFIED IDEOGRAPH
+0xECFA 0x6AA1 #CJK UNIFIED IDEOGRAPH
+0xECFB 0x6A9E #CJK UNIFIED IDEOGRAPH
+0xECFC 0x6A87 #CJK UNIFIED IDEOGRAPH
+0xECFD 0x6A93 #CJK UNIFIED IDEOGRAPH
+0xECFE 0x6A8E #CJK UNIFIED IDEOGRAPH
+0xED40 0x6A95 #CJK UNIFIED IDEOGRAPH
+0xED41 0x6A83 #CJK UNIFIED IDEOGRAPH
+0xED42 0x6AA8 #CJK UNIFIED IDEOGRAPH
+0xED43 0x6AA4 #CJK UNIFIED IDEOGRAPH
+0xED44 0x6A91 #CJK UNIFIED IDEOGRAPH
+0xED45 0x6A7F #CJK UNIFIED IDEOGRAPH
+0xED46 0x6AA6 #CJK UNIFIED IDEOGRAPH
+0xED47 0x6A9A #CJK UNIFIED IDEOGRAPH
+0xED48 0x6A85 #CJK UNIFIED IDEOGRAPH
+0xED49 0x6A8C #CJK UNIFIED IDEOGRAPH
+0xED4A 0x6A92 #CJK UNIFIED IDEOGRAPH
+0xED4B 0x6B5B #CJK UNIFIED IDEOGRAPH
+0xED4C 0x6BAD #CJK UNIFIED IDEOGRAPH
+0xED4D 0x6C09 #CJK UNIFIED IDEOGRAPH
+0xED4E 0x6FCC #CJK UNIFIED IDEOGRAPH
+0xED4F 0x6FA9 #CJK UNIFIED IDEOGRAPH
+0xED50 0x6FF4 #CJK UNIFIED IDEOGRAPH
+0xED51 0x6FD4 #CJK UNIFIED IDEOGRAPH
+0xED52 0x6FE3 #CJK UNIFIED IDEOGRAPH
+0xED53 0x6FDC #CJK UNIFIED IDEOGRAPH
+0xED54 0x6FED #CJK UNIFIED IDEOGRAPH
+0xED55 0x6FE7 #CJK UNIFIED IDEOGRAPH
+0xED56 0x6FE6 #CJK UNIFIED IDEOGRAPH
+0xED57 0x6FDE #CJK UNIFIED IDEOGRAPH
+0xED58 0x6FF2 #CJK UNIFIED IDEOGRAPH
+0xED59 0x6FDD #CJK UNIFIED IDEOGRAPH
+0xED5A 0x6FE2 #CJK UNIFIED IDEOGRAPH
+0xED5B 0x6FE8 #CJK UNIFIED IDEOGRAPH
+0xED5C 0x71E1 #CJK UNIFIED IDEOGRAPH
+0xED5D 0x71F1 #CJK UNIFIED IDEOGRAPH
+0xED5E 0x71E8 #CJK UNIFIED IDEOGRAPH
+0xED5F 0x71F2 #CJK UNIFIED IDEOGRAPH
+0xED60 0x71E4 #CJK UNIFIED IDEOGRAPH
+0xED61 0x71F0 #CJK UNIFIED IDEOGRAPH
+0xED62 0x71E2 #CJK UNIFIED IDEOGRAPH
+0xED63 0x7373 #CJK UNIFIED IDEOGRAPH
+0xED64 0x736E #CJK UNIFIED IDEOGRAPH
+0xED65 0x736F #CJK UNIFIED IDEOGRAPH
+0xED66 0x7497 #CJK UNIFIED IDEOGRAPH
+0xED67 0x74B2 #CJK UNIFIED IDEOGRAPH
+0xED68 0x74AB #CJK UNIFIED IDEOGRAPH
+0xED69 0x7490 #CJK UNIFIED IDEOGRAPH
+0xED6A 0x74AA #CJK UNIFIED IDEOGRAPH
+0xED6B 0x74AD #CJK UNIFIED IDEOGRAPH
+0xED6C 0x74B1 #CJK UNIFIED IDEOGRAPH
+0xED6D 0x74A5 #CJK UNIFIED IDEOGRAPH
+0xED6E 0x74AF #CJK UNIFIED IDEOGRAPH
+0xED6F 0x7510 #CJK UNIFIED IDEOGRAPH
+0xED70 0x7511 #CJK UNIFIED IDEOGRAPH
+0xED71 0x7512 #CJK UNIFIED IDEOGRAPH
+0xED72 0x750F #CJK UNIFIED IDEOGRAPH
+0xED73 0x7584 #CJK UNIFIED IDEOGRAPH
+0xED74 0x7643 #CJK UNIFIED IDEOGRAPH
+0xED75 0x7648 #CJK UNIFIED IDEOGRAPH
+0xED76 0x7649 #CJK UNIFIED IDEOGRAPH
+0xED77 0x7647 #CJK UNIFIED IDEOGRAPH
+0xED78 0x76A4 #CJK UNIFIED IDEOGRAPH
+0xED79 0x76E9 #CJK UNIFIED IDEOGRAPH
+0xED7A 0x77B5 #CJK UNIFIED IDEOGRAPH
+0xED7B 0x77AB #CJK UNIFIED IDEOGRAPH
+0xED7C 0x77B2 #CJK UNIFIED IDEOGRAPH
+0xED7D 0x77B7 #CJK UNIFIED IDEOGRAPH
+0xED7E 0x77B6 #CJK UNIFIED IDEOGRAPH
+0xEDA1 0x77B4 #CJK UNIFIED IDEOGRAPH
+0xEDA2 0x77B1 #CJK UNIFIED IDEOGRAPH
+0xEDA3 0x77A8 #CJK UNIFIED IDEOGRAPH
+0xEDA4 0x77F0 #CJK UNIFIED IDEOGRAPH
+0xEDA5 0x78F3 #CJK UNIFIED IDEOGRAPH
+0xEDA6 0x78FD #CJK UNIFIED IDEOGRAPH
+0xEDA7 0x7902 #CJK UNIFIED IDEOGRAPH
+0xEDA8 0x78FB #CJK UNIFIED IDEOGRAPH
+0xEDA9 0x78FC #CJK UNIFIED IDEOGRAPH
+0xEDAA 0x78F2 #CJK UNIFIED IDEOGRAPH
+0xEDAB 0x7905 #CJK UNIFIED IDEOGRAPH
+0xEDAC 0x78F9 #CJK UNIFIED IDEOGRAPH
+0xEDAD 0x78FE #CJK UNIFIED IDEOGRAPH
+0xEDAE 0x7904 #CJK UNIFIED IDEOGRAPH
+0xEDAF 0x79AB #CJK UNIFIED IDEOGRAPH
+0xEDB0 0x79A8 #CJK UNIFIED IDEOGRAPH
+0xEDB1 0x7A5C #CJK UNIFIED IDEOGRAPH
+0xEDB2 0x7A5B #CJK UNIFIED IDEOGRAPH
+0xEDB3 0x7A56 #CJK UNIFIED IDEOGRAPH
+0xEDB4 0x7A58 #CJK UNIFIED IDEOGRAPH
+0xEDB5 0x7A54 #CJK UNIFIED IDEOGRAPH
+0xEDB6 0x7A5A #CJK UNIFIED IDEOGRAPH
+0xEDB7 0x7ABE #CJK UNIFIED IDEOGRAPH
+0xEDB8 0x7AC0 #CJK UNIFIED IDEOGRAPH
+0xEDB9 0x7AC1 #CJK UNIFIED IDEOGRAPH
+0xEDBA 0x7C05 #CJK UNIFIED IDEOGRAPH
+0xEDBB 0x7C0F #CJK UNIFIED IDEOGRAPH
+0xEDBC 0x7BF2 #CJK UNIFIED IDEOGRAPH
+0xEDBD 0x7C00 #CJK UNIFIED IDEOGRAPH
+0xEDBE 0x7BFF #CJK UNIFIED IDEOGRAPH
+0xEDBF 0x7BFB #CJK UNIFIED IDEOGRAPH
+0xEDC0 0x7C0E #CJK UNIFIED IDEOGRAPH
+0xEDC1 0x7BF4 #CJK UNIFIED IDEOGRAPH
+0xEDC2 0x7C0B #CJK UNIFIED IDEOGRAPH
+0xEDC3 0x7BF3 #CJK UNIFIED IDEOGRAPH
+0xEDC4 0x7C02 #CJK UNIFIED IDEOGRAPH
+0xEDC5 0x7C09 #CJK UNIFIED IDEOGRAPH
+0xEDC6 0x7C03 #CJK UNIFIED IDEOGRAPH
+0xEDC7 0x7C01 #CJK UNIFIED IDEOGRAPH
+0xEDC8 0x7BF8 #CJK UNIFIED IDEOGRAPH
+0xEDC9 0x7BFD #CJK UNIFIED IDEOGRAPH
+0xEDCA 0x7C06 #CJK UNIFIED IDEOGRAPH
+0xEDCB 0x7BF0 #CJK UNIFIED IDEOGRAPH
+0xEDCC 0x7BF1 #CJK UNIFIED IDEOGRAPH
+0xEDCD 0x7C10 #CJK UNIFIED IDEOGRAPH
+0xEDCE 0x7C0A #CJK UNIFIED IDEOGRAPH
+0xEDCF 0x7CE8 #CJK UNIFIED IDEOGRAPH
+0xEDD0 0x7E2D #CJK UNIFIED IDEOGRAPH
+0xEDD1 0x7E3C #CJK UNIFIED IDEOGRAPH
+0xEDD2 0x7E42 #CJK UNIFIED IDEOGRAPH
+0xEDD3 0x7E33 #CJK UNIFIED IDEOGRAPH
+0xEDD4 0x9848 #CJK UNIFIED IDEOGRAPH
+0xEDD5 0x7E38 #CJK UNIFIED IDEOGRAPH
+0xEDD6 0x7E2A #CJK UNIFIED IDEOGRAPH
+0xEDD7 0x7E49 #CJK UNIFIED IDEOGRAPH
+0xEDD8 0x7E40 #CJK UNIFIED IDEOGRAPH
+0xEDD9 0x7E47 #CJK UNIFIED IDEOGRAPH
+0xEDDA 0x7E29 #CJK UNIFIED IDEOGRAPH
+0xEDDB 0x7E4C #CJK UNIFIED IDEOGRAPH
+0xEDDC 0x7E30 #CJK UNIFIED IDEOGRAPH
+0xEDDD 0x7E3B #CJK UNIFIED IDEOGRAPH
+0xEDDE 0x7E36 #CJK UNIFIED IDEOGRAPH
+0xEDDF 0x7E44 #CJK UNIFIED IDEOGRAPH
+0xEDE0 0x7E3A #CJK UNIFIED IDEOGRAPH
+0xEDE1 0x7F45 #CJK UNIFIED IDEOGRAPH
+0xEDE2 0x7F7F #CJK UNIFIED IDEOGRAPH
+0xEDE3 0x7F7E #CJK UNIFIED IDEOGRAPH
+0xEDE4 0x7F7D #CJK UNIFIED IDEOGRAPH
+0xEDE5 0x7FF4 #CJK UNIFIED IDEOGRAPH
+0xEDE6 0x7FF2 #CJK UNIFIED IDEOGRAPH
+0xEDE7 0x802C #CJK UNIFIED IDEOGRAPH
+0xEDE8 0x81BB #CJK UNIFIED IDEOGRAPH
+0xEDE9 0x81C4 #CJK UNIFIED IDEOGRAPH
+0xEDEA 0x81CC #CJK UNIFIED IDEOGRAPH
+0xEDEB 0x81CA #CJK UNIFIED IDEOGRAPH
+0xEDEC 0x81C5 #CJK UNIFIED IDEOGRAPH
+0xEDED 0x81C7 #CJK UNIFIED IDEOGRAPH
+0xEDEE 0x81BC #CJK UNIFIED IDEOGRAPH
+0xEDEF 0x81E9 #CJK UNIFIED IDEOGRAPH
+0xEDF0 0x825B #CJK UNIFIED IDEOGRAPH
+0xEDF1 0x825A #CJK UNIFIED IDEOGRAPH
+0xEDF2 0x825C #CJK UNIFIED IDEOGRAPH
+0xEDF3 0x8583 #CJK UNIFIED IDEOGRAPH
+0xEDF4 0x8580 #CJK UNIFIED IDEOGRAPH
+0xEDF5 0x858F #CJK UNIFIED IDEOGRAPH
+0xEDF6 0x85A7 #CJK UNIFIED IDEOGRAPH
+0xEDF7 0x8595 #CJK UNIFIED IDEOGRAPH
+0xEDF8 0x85A0 #CJK UNIFIED IDEOGRAPH
+0xEDF9 0x858B #CJK UNIFIED IDEOGRAPH
+0xEDFA 0x85A3 #CJK UNIFIED IDEOGRAPH
+0xEDFB 0x857B #CJK UNIFIED IDEOGRAPH
+0xEDFC 0x85A4 #CJK UNIFIED IDEOGRAPH
+0xEDFD 0x859A #CJK UNIFIED IDEOGRAPH
+0xEDFE 0x859E #CJK UNIFIED IDEOGRAPH
+0xEE40 0x8577 #CJK UNIFIED IDEOGRAPH
+0xEE41 0x857C #CJK UNIFIED IDEOGRAPH
+0xEE42 0x8589 #CJK UNIFIED IDEOGRAPH
+0xEE43 0x85A1 #CJK UNIFIED IDEOGRAPH
+0xEE44 0x857A #CJK UNIFIED IDEOGRAPH
+0xEE45 0x8578 #CJK UNIFIED IDEOGRAPH
+0xEE46 0x8557 #CJK UNIFIED IDEOGRAPH
+0xEE47 0x858E #CJK UNIFIED IDEOGRAPH
+0xEE48 0x8596 #CJK UNIFIED IDEOGRAPH
+0xEE49 0x8586 #CJK UNIFIED IDEOGRAPH
+0xEE4A 0x858D #CJK UNIFIED IDEOGRAPH
+0xEE4B 0x8599 #CJK UNIFIED IDEOGRAPH
+0xEE4C 0x859D #CJK UNIFIED IDEOGRAPH
+0xEE4D 0x8581 #CJK UNIFIED IDEOGRAPH
+0xEE4E 0x85A2 #CJK UNIFIED IDEOGRAPH
+0xEE4F 0x8582 #CJK UNIFIED IDEOGRAPH
+0xEE50 0x8588 #CJK UNIFIED IDEOGRAPH
+0xEE51 0x8585 #CJK UNIFIED IDEOGRAPH
+0xEE52 0x8579 #CJK UNIFIED IDEOGRAPH
+0xEE53 0x8576 #CJK UNIFIED IDEOGRAPH
+0xEE54 0x8598 #CJK UNIFIED IDEOGRAPH
+0xEE55 0x8590 #CJK UNIFIED IDEOGRAPH
+0xEE56 0x859F #CJK UNIFIED IDEOGRAPH
+0xEE57 0x8668 #CJK UNIFIED IDEOGRAPH
+0xEE58 0x87BE #CJK UNIFIED IDEOGRAPH
+0xEE59 0x87AA #CJK UNIFIED IDEOGRAPH
+0xEE5A 0x87AD #CJK UNIFIED IDEOGRAPH
+0xEE5B 0x87C5 #CJK UNIFIED IDEOGRAPH
+0xEE5C 0x87B0 #CJK UNIFIED IDEOGRAPH
+0xEE5D 0x87AC #CJK UNIFIED IDEOGRAPH
+0xEE5E 0x87B9 #CJK UNIFIED IDEOGRAPH
+0xEE5F 0x87B5 #CJK UNIFIED IDEOGRAPH
+0xEE60 0x87BC #CJK UNIFIED IDEOGRAPH
+0xEE61 0x87AE #CJK UNIFIED IDEOGRAPH
+0xEE62 0x87C9 #CJK UNIFIED IDEOGRAPH
+0xEE63 0x87C3 #CJK UNIFIED IDEOGRAPH
+0xEE64 0x87C2 #CJK UNIFIED IDEOGRAPH
+0xEE65 0x87CC #CJK UNIFIED IDEOGRAPH
+0xEE66 0x87B7 #CJK UNIFIED IDEOGRAPH
+0xEE67 0x87AF #CJK UNIFIED IDEOGRAPH
+0xEE68 0x87C4 #CJK UNIFIED IDEOGRAPH
+0xEE69 0x87CA #CJK UNIFIED IDEOGRAPH
+0xEE6A 0x87B4 #CJK UNIFIED IDEOGRAPH
+0xEE6B 0x87B6 #CJK UNIFIED IDEOGRAPH
+0xEE6C 0x87BF #CJK UNIFIED IDEOGRAPH
+0xEE6D 0x87B8 #CJK UNIFIED IDEOGRAPH
+0xEE6E 0x87BD #CJK UNIFIED IDEOGRAPH
+0xEE6F 0x87DE #CJK UNIFIED IDEOGRAPH
+0xEE70 0x87B2 #CJK UNIFIED IDEOGRAPH
+0xEE71 0x8935 #CJK UNIFIED IDEOGRAPH
+0xEE72 0x8933 #CJK UNIFIED IDEOGRAPH
+0xEE73 0x893C #CJK UNIFIED IDEOGRAPH
+0xEE74 0x893E #CJK UNIFIED IDEOGRAPH
+0xEE75 0x8941 #CJK UNIFIED IDEOGRAPH
+0xEE76 0x8952 #CJK UNIFIED IDEOGRAPH
+0xEE77 0x8937 #CJK UNIFIED IDEOGRAPH
+0xEE78 0x8942 #CJK UNIFIED IDEOGRAPH
+0xEE79 0x89AD #CJK UNIFIED IDEOGRAPH
+0xEE7A 0x89AF #CJK UNIFIED IDEOGRAPH
+0xEE7B 0x89AE #CJK UNIFIED IDEOGRAPH
+0xEE7C 0x89F2 #CJK UNIFIED IDEOGRAPH
+0xEE7D 0x89F3 #CJK UNIFIED IDEOGRAPH
+0xEE7E 0x8B1E #CJK UNIFIED IDEOGRAPH
+0xEEA1 0x8B18 #CJK UNIFIED IDEOGRAPH
+0xEEA2 0x8B16 #CJK UNIFIED IDEOGRAPH
+0xEEA3 0x8B11 #CJK UNIFIED IDEOGRAPH
+0xEEA4 0x8B05 #CJK UNIFIED IDEOGRAPH
+0xEEA5 0x8B0B #CJK UNIFIED IDEOGRAPH
+0xEEA6 0x8B22 #CJK UNIFIED IDEOGRAPH
+0xEEA7 0x8B0F #CJK UNIFIED IDEOGRAPH
+0xEEA8 0x8B12 #CJK UNIFIED IDEOGRAPH
+0xEEA9 0x8B15 #CJK UNIFIED IDEOGRAPH
+0xEEAA 0x8B07 #CJK UNIFIED IDEOGRAPH
+0xEEAB 0x8B0D #CJK UNIFIED IDEOGRAPH
+0xEEAC 0x8B08 #CJK UNIFIED IDEOGRAPH
+0xEEAD 0x8B06 #CJK UNIFIED IDEOGRAPH
+0xEEAE 0x8B1C #CJK UNIFIED IDEOGRAPH
+0xEEAF 0x8B13 #CJK UNIFIED IDEOGRAPH
+0xEEB0 0x8B1A #CJK UNIFIED IDEOGRAPH
+0xEEB1 0x8C4F #CJK UNIFIED IDEOGRAPH
+0xEEB2 0x8C70 #CJK UNIFIED IDEOGRAPH
+0xEEB3 0x8C72 #CJK UNIFIED IDEOGRAPH
+0xEEB4 0x8C71 #CJK UNIFIED IDEOGRAPH
+0xEEB5 0x8C6F #CJK UNIFIED IDEOGRAPH
+0xEEB6 0x8C95 #CJK UNIFIED IDEOGRAPH
+0xEEB7 0x8C94 #CJK UNIFIED IDEOGRAPH
+0xEEB8 0x8CF9 #CJK UNIFIED IDEOGRAPH
+0xEEB9 0x8D6F #CJK UNIFIED IDEOGRAPH
+0xEEBA 0x8E4E #CJK UNIFIED IDEOGRAPH
+0xEEBB 0x8E4D #CJK UNIFIED IDEOGRAPH
+0xEEBC 0x8E53 #CJK UNIFIED IDEOGRAPH
+0xEEBD 0x8E50 #CJK UNIFIED IDEOGRAPH
+0xEEBE 0x8E4C #CJK UNIFIED IDEOGRAPH
+0xEEBF 0x8E47 #CJK UNIFIED IDEOGRAPH
+0xEEC0 0x8F43 #CJK UNIFIED IDEOGRAPH
+0xEEC1 0x8F40 #CJK UNIFIED IDEOGRAPH
+0xEEC2 0x9085 #CJK UNIFIED IDEOGRAPH
+0xEEC3 0x907E #CJK UNIFIED IDEOGRAPH
+0xEEC4 0x9138 #CJK UNIFIED IDEOGRAPH
+0xEEC5 0x919A #CJK UNIFIED IDEOGRAPH
+0xEEC6 0x91A2 #CJK UNIFIED IDEOGRAPH
+0xEEC7 0x919B #CJK UNIFIED IDEOGRAPH
+0xEEC8 0x9199 #CJK UNIFIED IDEOGRAPH
+0xEEC9 0x919F #CJK UNIFIED IDEOGRAPH
+0xEECA 0x91A1 #CJK UNIFIED IDEOGRAPH
+0xEECB 0x919D #CJK UNIFIED IDEOGRAPH
+0xEECC 0x91A0 #CJK UNIFIED IDEOGRAPH
+0xEECD 0x93A1 #CJK UNIFIED IDEOGRAPH
+0xEECE 0x9383 #CJK UNIFIED IDEOGRAPH
+0xEECF 0x93AF #CJK UNIFIED IDEOGRAPH
+0xEED0 0x9364 #CJK UNIFIED IDEOGRAPH
+0xEED1 0x9356 #CJK UNIFIED IDEOGRAPH
+0xEED2 0x9347 #CJK UNIFIED IDEOGRAPH
+0xEED3 0x937C #CJK UNIFIED IDEOGRAPH
+0xEED4 0x9358 #CJK UNIFIED IDEOGRAPH
+0xEED5 0x935C #CJK UNIFIED IDEOGRAPH
+0xEED6 0x9376 #CJK UNIFIED IDEOGRAPH
+0xEED7 0x9349 #CJK UNIFIED IDEOGRAPH
+0xEED8 0x9350 #CJK UNIFIED IDEOGRAPH
+0xEED9 0x9351 #CJK UNIFIED IDEOGRAPH
+0xEEDA 0x9360 #CJK UNIFIED IDEOGRAPH
+0xEEDB 0x936D #CJK UNIFIED IDEOGRAPH
+0xEEDC 0x938F #CJK UNIFIED IDEOGRAPH
+0xEEDD 0x934C #CJK UNIFIED IDEOGRAPH
+0xEEDE 0x936A #CJK UNIFIED IDEOGRAPH
+0xEEDF 0x9379 #CJK UNIFIED IDEOGRAPH
+0xEEE0 0x9357 #CJK UNIFIED IDEOGRAPH
+0xEEE1 0x9355 #CJK UNIFIED IDEOGRAPH
+0xEEE2 0x9352 #CJK UNIFIED IDEOGRAPH
+0xEEE3 0x934F #CJK UNIFIED IDEOGRAPH
+0xEEE4 0x9371 #CJK UNIFIED IDEOGRAPH
+0xEEE5 0x9377 #CJK UNIFIED IDEOGRAPH
+0xEEE6 0x937B #CJK UNIFIED IDEOGRAPH
+0xEEE7 0x9361 #CJK UNIFIED IDEOGRAPH
+0xEEE8 0x935E #CJK UNIFIED IDEOGRAPH
+0xEEE9 0x9363 #CJK UNIFIED IDEOGRAPH
+0xEEEA 0x9367 #CJK UNIFIED IDEOGRAPH
+0xEEEB 0x9380 #CJK UNIFIED IDEOGRAPH
+0xEEEC 0x934E #CJK UNIFIED IDEOGRAPH
+0xEEED 0x9359 #CJK UNIFIED IDEOGRAPH
+0xEEEE 0x95C7 #CJK UNIFIED IDEOGRAPH
+0xEEEF 0x95C0 #CJK UNIFIED IDEOGRAPH
+0xEEF0 0x95C9 #CJK UNIFIED IDEOGRAPH
+0xEEF1 0x95C3 #CJK UNIFIED IDEOGRAPH
+0xEEF2 0x95C5 #CJK UNIFIED IDEOGRAPH
+0xEEF3 0x95B7 #CJK UNIFIED IDEOGRAPH
+0xEEF4 0x96AE #CJK UNIFIED IDEOGRAPH
+0xEEF5 0x96B0 #CJK UNIFIED IDEOGRAPH
+0xEEF6 0x96AC #CJK UNIFIED IDEOGRAPH
+0xEEF7 0x9720 #CJK UNIFIED IDEOGRAPH
+0xEEF8 0x971F #CJK UNIFIED IDEOGRAPH
+0xEEF9 0x9718 #CJK UNIFIED IDEOGRAPH
+0xEEFA 0x971D #CJK UNIFIED IDEOGRAPH
+0xEEFB 0x9719 #CJK UNIFIED IDEOGRAPH
+0xEEFC 0x979A #CJK UNIFIED IDEOGRAPH
+0xEEFD 0x97A1 #CJK UNIFIED IDEOGRAPH
+0xEEFE 0x979C #CJK UNIFIED IDEOGRAPH
+0xEF40 0x979E #CJK UNIFIED IDEOGRAPH
+0xEF41 0x979D #CJK UNIFIED IDEOGRAPH
+0xEF42 0x97D5 #CJK UNIFIED IDEOGRAPH
+0xEF43 0x97D4 #CJK UNIFIED IDEOGRAPH
+0xEF44 0x97F1 #CJK UNIFIED IDEOGRAPH
+0xEF45 0x9841 #CJK UNIFIED IDEOGRAPH
+0xEF46 0x9844 #CJK UNIFIED IDEOGRAPH
+0xEF47 0x984A #CJK UNIFIED IDEOGRAPH
+0xEF48 0x9849 #CJK UNIFIED IDEOGRAPH
+0xEF49 0x9845 #CJK UNIFIED IDEOGRAPH
+0xEF4A 0x9843 #CJK UNIFIED IDEOGRAPH
+0xEF4B 0x9925 #CJK UNIFIED IDEOGRAPH
+0xEF4C 0x992B #CJK UNIFIED IDEOGRAPH
+0xEF4D 0x992C #CJK UNIFIED IDEOGRAPH
+0xEF4E 0x992A #CJK UNIFIED IDEOGRAPH
+0xEF4F 0x9933 #CJK UNIFIED IDEOGRAPH
+0xEF50 0x9932 #CJK UNIFIED IDEOGRAPH
+0xEF51 0x992F #CJK UNIFIED IDEOGRAPH
+0xEF52 0x992D #CJK UNIFIED IDEOGRAPH
+0xEF53 0x9931 #CJK UNIFIED IDEOGRAPH
+0xEF54 0x9930 #CJK UNIFIED IDEOGRAPH
+0xEF55 0x9998 #CJK UNIFIED IDEOGRAPH
+0xEF56 0x99A3 #CJK UNIFIED IDEOGRAPH
+0xEF57 0x99A1 #CJK UNIFIED IDEOGRAPH
+0xEF58 0x9A02 #CJK UNIFIED IDEOGRAPH
+0xEF59 0x99FA #CJK UNIFIED IDEOGRAPH
+0xEF5A 0x99F4 #CJK UNIFIED IDEOGRAPH
+0xEF5B 0x99F7 #CJK UNIFIED IDEOGRAPH
+0xEF5C 0x99F9 #CJK UNIFIED IDEOGRAPH
+0xEF5D 0x99F8 #CJK UNIFIED IDEOGRAPH
+0xEF5E 0x99F6 #CJK UNIFIED IDEOGRAPH
+0xEF5F 0x99FB #CJK UNIFIED IDEOGRAPH
+0xEF60 0x99FD #CJK UNIFIED IDEOGRAPH
+0xEF61 0x99FE #CJK UNIFIED IDEOGRAPH
+0xEF62 0x99FC #CJK UNIFIED IDEOGRAPH
+0xEF63 0x9A03 #CJK UNIFIED IDEOGRAPH
+0xEF64 0x9ABE #CJK UNIFIED IDEOGRAPH
+0xEF65 0x9AFE #CJK UNIFIED IDEOGRAPH
+0xEF66 0x9AFD #CJK UNIFIED IDEOGRAPH
+0xEF67 0x9B01 #CJK UNIFIED IDEOGRAPH
+0xEF68 0x9AFC #CJK UNIFIED IDEOGRAPH
+0xEF69 0x9B48 #CJK UNIFIED IDEOGRAPH
+0xEF6A 0x9B9A #CJK UNIFIED IDEOGRAPH
+0xEF6B 0x9BA8 #CJK UNIFIED IDEOGRAPH
+0xEF6C 0x9B9E #CJK UNIFIED IDEOGRAPH
+0xEF6D 0x9B9B #CJK UNIFIED IDEOGRAPH
+0xEF6E 0x9BA6 #CJK UNIFIED IDEOGRAPH
+0xEF6F 0x9BA1 #CJK UNIFIED IDEOGRAPH
+0xEF70 0x9BA5 #CJK UNIFIED IDEOGRAPH
+0xEF71 0x9BA4 #CJK UNIFIED IDEOGRAPH
+0xEF72 0x9B86 #CJK UNIFIED IDEOGRAPH
+0xEF73 0x9BA2 #CJK UNIFIED IDEOGRAPH
+0xEF74 0x9BA0 #CJK UNIFIED IDEOGRAPH
+0xEF75 0x9BAF #CJK UNIFIED IDEOGRAPH
+0xEF76 0x9D33 #CJK UNIFIED IDEOGRAPH
+0xEF77 0x9D41 #CJK UNIFIED IDEOGRAPH
+0xEF78 0x9D67 #CJK UNIFIED IDEOGRAPH
+0xEF79 0x9D36 #CJK UNIFIED IDEOGRAPH
+0xEF7A 0x9D2E #CJK UNIFIED IDEOGRAPH
+0xEF7B 0x9D2F #CJK UNIFIED IDEOGRAPH
+0xEF7C 0x9D31 #CJK UNIFIED IDEOGRAPH
+0xEF7D 0x9D38 #CJK UNIFIED IDEOGRAPH
+0xEF7E 0x9D30 #CJK UNIFIED IDEOGRAPH
+0xEFA1 0x9D45 #CJK UNIFIED IDEOGRAPH
+0xEFA2 0x9D42 #CJK UNIFIED IDEOGRAPH
+0xEFA3 0x9D43 #CJK UNIFIED IDEOGRAPH
+0xEFA4 0x9D3E #CJK UNIFIED IDEOGRAPH
+0xEFA5 0x9D37 #CJK UNIFIED IDEOGRAPH
+0xEFA6 0x9D40 #CJK UNIFIED IDEOGRAPH
+0xEFA7 0x9D3D #CJK UNIFIED IDEOGRAPH
+0xEFA8 0x7FF5 #CJK UNIFIED IDEOGRAPH
+0xEFA9 0x9D2D #CJK UNIFIED IDEOGRAPH
+0xEFAA 0x9E8A #CJK UNIFIED IDEOGRAPH
+0xEFAB 0x9E89 #CJK UNIFIED IDEOGRAPH
+0xEFAC 0x9E8D #CJK UNIFIED IDEOGRAPH
+0xEFAD 0x9EB0 #CJK UNIFIED IDEOGRAPH
+0xEFAE 0x9EC8 #CJK UNIFIED IDEOGRAPH
+0xEFAF 0x9EDA #CJK UNIFIED IDEOGRAPH
+0xEFB0 0x9EFB #CJK UNIFIED IDEOGRAPH
+0xEFB1 0x9EFF #CJK UNIFIED IDEOGRAPH
+0xEFB2 0x9F24 #CJK UNIFIED IDEOGRAPH
+0xEFB3 0x9F23 #CJK UNIFIED IDEOGRAPH
+0xEFB4 0x9F22 #CJK UNIFIED IDEOGRAPH
+0xEFB5 0x9F54 #CJK UNIFIED IDEOGRAPH
+0xEFB6 0x9FA0 #CJK UNIFIED IDEOGRAPH
+0xEFB7 0x5131 #CJK UNIFIED IDEOGRAPH
+0xEFB8 0x512D #CJK UNIFIED IDEOGRAPH
+0xEFB9 0x512E #CJK UNIFIED IDEOGRAPH
+0xEFBA 0x5698 #CJK UNIFIED IDEOGRAPH
+0xEFBB 0x569C #CJK UNIFIED IDEOGRAPH
+0xEFBC 0x5697 #CJK UNIFIED IDEOGRAPH
+0xEFBD 0x569A #CJK UNIFIED IDEOGRAPH
+0xEFBE 0x569D #CJK UNIFIED IDEOGRAPH
+0xEFBF 0x5699 #CJK UNIFIED IDEOGRAPH
+0xEFC0 0x5970 #CJK UNIFIED IDEOGRAPH
+0xEFC1 0x5B3C #CJK UNIFIED IDEOGRAPH
+0xEFC2 0x5C69 #CJK UNIFIED IDEOGRAPH
+0xEFC3 0x5C6A #CJK UNIFIED IDEOGRAPH
+0xEFC4 0x5DC0 #CJK UNIFIED IDEOGRAPH
+0xEFC5 0x5E6D #CJK UNIFIED IDEOGRAPH
+0xEFC6 0x5E6E #CJK UNIFIED IDEOGRAPH
+0xEFC7 0x61D8 #CJK UNIFIED IDEOGRAPH
+0xEFC8 0x61DF #CJK UNIFIED IDEOGRAPH
+0xEFC9 0x61ED #CJK UNIFIED IDEOGRAPH
+0xEFCA 0x61EE #CJK UNIFIED IDEOGRAPH
+0xEFCB 0x61F1 #CJK UNIFIED IDEOGRAPH
+0xEFCC 0x61EA #CJK UNIFIED IDEOGRAPH
+0xEFCD 0x61F0 #CJK UNIFIED IDEOGRAPH
+0xEFCE 0x61EB #CJK UNIFIED IDEOGRAPH
+0xEFCF 0x61D6 #CJK UNIFIED IDEOGRAPH
+0xEFD0 0x61E9 #CJK UNIFIED IDEOGRAPH
+0xEFD1 0x64FF #CJK UNIFIED IDEOGRAPH
+0xEFD2 0x6504 #CJK UNIFIED IDEOGRAPH
+0xEFD3 0x64FD #CJK UNIFIED IDEOGRAPH
+0xEFD4 0x64F8 #CJK UNIFIED IDEOGRAPH
+0xEFD5 0x6501 #CJK UNIFIED IDEOGRAPH
+0xEFD6 0x6503 #CJK UNIFIED IDEOGRAPH
+0xEFD7 0x64FC #CJK UNIFIED IDEOGRAPH
+0xEFD8 0x6594 #CJK UNIFIED IDEOGRAPH
+0xEFD9 0x65DB #CJK UNIFIED IDEOGRAPH
+0xEFDA 0x66DA #CJK UNIFIED IDEOGRAPH
+0xEFDB 0x66DB #CJK UNIFIED IDEOGRAPH
+0xEFDC 0x66D8 #CJK UNIFIED IDEOGRAPH
+0xEFDD 0x6AC5 #CJK UNIFIED IDEOGRAPH
+0xEFDE 0x6AB9 #CJK UNIFIED IDEOGRAPH
+0xEFDF 0x6ABD #CJK UNIFIED IDEOGRAPH
+0xEFE0 0x6AE1 #CJK UNIFIED IDEOGRAPH
+0xEFE1 0x6AC6 #CJK UNIFIED IDEOGRAPH
+0xEFE2 0x6ABA #CJK UNIFIED IDEOGRAPH
+0xEFE3 0x6AB6 #CJK UNIFIED IDEOGRAPH
+0xEFE4 0x6AB7 #CJK UNIFIED IDEOGRAPH
+0xEFE5 0x6AC7 #CJK UNIFIED IDEOGRAPH
+0xEFE6 0x6AB4 #CJK UNIFIED IDEOGRAPH
+0xEFE7 0x6AAD #CJK UNIFIED IDEOGRAPH
+0xEFE8 0x6B5E #CJK UNIFIED IDEOGRAPH
+0xEFE9 0x6BC9 #CJK UNIFIED IDEOGRAPH
+0xEFEA 0x6C0B #CJK UNIFIED IDEOGRAPH
+0xEFEB 0x7007 #CJK UNIFIED IDEOGRAPH
+0xEFEC 0x700C #CJK UNIFIED IDEOGRAPH
+0xEFED 0x700D #CJK UNIFIED IDEOGRAPH
+0xEFEE 0x7001 #CJK UNIFIED IDEOGRAPH
+0xEFEF 0x7005 #CJK UNIFIED IDEOGRAPH
+0xEFF0 0x7014 #CJK UNIFIED IDEOGRAPH
+0xEFF1 0x700E #CJK UNIFIED IDEOGRAPH
+0xEFF2 0x6FFF #CJK UNIFIED IDEOGRAPH
+0xEFF3 0x7000 #CJK UNIFIED IDEOGRAPH
+0xEFF4 0x6FFB #CJK UNIFIED IDEOGRAPH
+0xEFF5 0x7026 #CJK UNIFIED IDEOGRAPH
+0xEFF6 0x6FFC #CJK UNIFIED IDEOGRAPH
+0xEFF7 0x6FF7 #CJK UNIFIED IDEOGRAPH
+0xEFF8 0x700A #CJK UNIFIED IDEOGRAPH
+0xEFF9 0x7201 #CJK UNIFIED IDEOGRAPH
+0xEFFA 0x71FF #CJK UNIFIED IDEOGRAPH
+0xEFFB 0x71F9 #CJK UNIFIED IDEOGRAPH
+0xEFFC 0x7203 #CJK UNIFIED IDEOGRAPH
+0xEFFD 0x71FD #CJK UNIFIED IDEOGRAPH
+0xEFFE 0x7376 #CJK UNIFIED IDEOGRAPH
+0xF040 0x74B8 #CJK UNIFIED IDEOGRAPH
+0xF041 0x74C0 #CJK UNIFIED IDEOGRAPH
+0xF042 0x74B5 #CJK UNIFIED IDEOGRAPH
+0xF043 0x74C1 #CJK UNIFIED IDEOGRAPH
+0xF044 0x74BE #CJK UNIFIED IDEOGRAPH
+0xF045 0x74B6 #CJK UNIFIED IDEOGRAPH
+0xF046 0x74BB #CJK UNIFIED IDEOGRAPH
+0xF047 0x74C2 #CJK UNIFIED IDEOGRAPH
+0xF048 0x7514 #CJK UNIFIED IDEOGRAPH
+0xF049 0x7513 #CJK UNIFIED IDEOGRAPH
+0xF04A 0x765C #CJK UNIFIED IDEOGRAPH
+0xF04B 0x7664 #CJK UNIFIED IDEOGRAPH
+0xF04C 0x7659 #CJK UNIFIED IDEOGRAPH
+0xF04D 0x7650 #CJK UNIFIED IDEOGRAPH
+0xF04E 0x7653 #CJK UNIFIED IDEOGRAPH
+0xF04F 0x7657 #CJK UNIFIED IDEOGRAPH
+0xF050 0x765A #CJK UNIFIED IDEOGRAPH
+0xF051 0x76A6 #CJK UNIFIED IDEOGRAPH
+0xF052 0x76BD #CJK UNIFIED IDEOGRAPH
+0xF053 0x76EC #CJK UNIFIED IDEOGRAPH
+0xF054 0x77C2 #CJK UNIFIED IDEOGRAPH
+0xF055 0x77BA #CJK UNIFIED IDEOGRAPH
+0xF056 0x78FF #CJK UNIFIED IDEOGRAPH
+0xF057 0x790C #CJK UNIFIED IDEOGRAPH
+0xF058 0x7913 #CJK UNIFIED IDEOGRAPH
+0xF059 0x7914 #CJK UNIFIED IDEOGRAPH
+0xF05A 0x7909 #CJK UNIFIED IDEOGRAPH
+0xF05B 0x7910 #CJK UNIFIED IDEOGRAPH
+0xF05C 0x7912 #CJK UNIFIED IDEOGRAPH
+0xF05D 0x7911 #CJK UNIFIED IDEOGRAPH
+0xF05E 0x79AD #CJK UNIFIED IDEOGRAPH
+0xF05F 0x79AC #CJK UNIFIED IDEOGRAPH
+0xF060 0x7A5F #CJK UNIFIED IDEOGRAPH
+0xF061 0x7C1C #CJK UNIFIED IDEOGRAPH
+0xF062 0x7C29 #CJK UNIFIED IDEOGRAPH
+0xF063 0x7C19 #CJK UNIFIED IDEOGRAPH
+0xF064 0x7C20 #CJK UNIFIED IDEOGRAPH
+0xF065 0x7C1F #CJK UNIFIED IDEOGRAPH
+0xF066 0x7C2D #CJK UNIFIED IDEOGRAPH
+0xF067 0x7C1D #CJK UNIFIED IDEOGRAPH
+0xF068 0x7C26 #CJK UNIFIED IDEOGRAPH
+0xF069 0x7C28 #CJK UNIFIED IDEOGRAPH
+0xF06A 0x7C22 #CJK UNIFIED IDEOGRAPH
+0xF06B 0x7C25 #CJK UNIFIED IDEOGRAPH
+0xF06C 0x7C30 #CJK UNIFIED IDEOGRAPH
+0xF06D 0x7E5C #CJK UNIFIED IDEOGRAPH
+0xF06E 0x7E50 #CJK UNIFIED IDEOGRAPH
+0xF06F 0x7E56 #CJK UNIFIED IDEOGRAPH
+0xF070 0x7E63 #CJK UNIFIED IDEOGRAPH
+0xF071 0x7E58 #CJK UNIFIED IDEOGRAPH
+0xF072 0x7E62 #CJK UNIFIED IDEOGRAPH
+0xF073 0x7E5F #CJK UNIFIED IDEOGRAPH
+0xF074 0x7E51 #CJK UNIFIED IDEOGRAPH
+0xF075 0x7E60 #CJK UNIFIED IDEOGRAPH
+0xF076 0x7E57 #CJK UNIFIED IDEOGRAPH
+0xF077 0x7E53 #CJK UNIFIED IDEOGRAPH
+0xF078 0x7FB5 #CJK UNIFIED IDEOGRAPH
+0xF079 0x7FB3 #CJK UNIFIED IDEOGRAPH
+0xF07A 0x7FF7 #CJK UNIFIED IDEOGRAPH
+0xF07B 0x7FF8 #CJK UNIFIED IDEOGRAPH
+0xF07C 0x8075 #CJK UNIFIED IDEOGRAPH
+0xF07D 0x81D1 #CJK UNIFIED IDEOGRAPH
+0xF07E 0x81D2 #CJK UNIFIED IDEOGRAPH
+0xF0A1 0x81D0 #CJK UNIFIED IDEOGRAPH
+0xF0A2 0x825F #CJK UNIFIED IDEOGRAPH
+0xF0A3 0x825E #CJK UNIFIED IDEOGRAPH
+0xF0A4 0x85B4 #CJK UNIFIED IDEOGRAPH
+0xF0A5 0x85C6 #CJK UNIFIED IDEOGRAPH
+0xF0A6 0x85C0 #CJK UNIFIED IDEOGRAPH
+0xF0A7 0x85C3 #CJK UNIFIED IDEOGRAPH
+0xF0A8 0x85C2 #CJK UNIFIED IDEOGRAPH
+0xF0A9 0x85B3 #CJK UNIFIED IDEOGRAPH
+0xF0AA 0x85B5 #CJK UNIFIED IDEOGRAPH
+0xF0AB 0x85BD #CJK UNIFIED IDEOGRAPH
+0xF0AC 0x85C7 #CJK UNIFIED IDEOGRAPH
+0xF0AD 0x85C4 #CJK UNIFIED IDEOGRAPH
+0xF0AE 0x85BF #CJK UNIFIED IDEOGRAPH
+0xF0AF 0x85CB #CJK UNIFIED IDEOGRAPH
+0xF0B0 0x85CE #CJK UNIFIED IDEOGRAPH
+0xF0B1 0x85C8 #CJK UNIFIED IDEOGRAPH
+0xF0B2 0x85C5 #CJK UNIFIED IDEOGRAPH
+0xF0B3 0x85B1 #CJK UNIFIED IDEOGRAPH
+0xF0B4 0x85B6 #CJK UNIFIED IDEOGRAPH
+0xF0B5 0x85D2 #CJK UNIFIED IDEOGRAPH
+0xF0B6 0x8624 #CJK UNIFIED IDEOGRAPH
+0xF0B7 0x85B8 #CJK UNIFIED IDEOGRAPH
+0xF0B8 0x85B7 #CJK UNIFIED IDEOGRAPH
+0xF0B9 0x85BE #CJK UNIFIED IDEOGRAPH
+0xF0BA 0x8669 #CJK UNIFIED IDEOGRAPH
+0xF0BB 0x87E7 #CJK UNIFIED IDEOGRAPH
+0xF0BC 0x87E6 #CJK UNIFIED IDEOGRAPH
+0xF0BD 0x87E2 #CJK UNIFIED IDEOGRAPH
+0xF0BE 0x87DB #CJK UNIFIED IDEOGRAPH
+0xF0BF 0x87EB #CJK UNIFIED IDEOGRAPH
+0xF0C0 0x87EA #CJK UNIFIED IDEOGRAPH
+0xF0C1 0x87E5 #CJK UNIFIED IDEOGRAPH
+0xF0C2 0x87DF #CJK UNIFIED IDEOGRAPH
+0xF0C3 0x87F3 #CJK UNIFIED IDEOGRAPH
+0xF0C4 0x87E4 #CJK UNIFIED IDEOGRAPH
+0xF0C5 0x87D4 #CJK UNIFIED IDEOGRAPH
+0xF0C6 0x87DC #CJK UNIFIED IDEOGRAPH
+0xF0C7 0x87D3 #CJK UNIFIED IDEOGRAPH
+0xF0C8 0x87ED #CJK UNIFIED IDEOGRAPH
+0xF0C9 0x87D8 #CJK UNIFIED IDEOGRAPH
+0xF0CA 0x87E3 #CJK UNIFIED IDEOGRAPH
+0xF0CB 0x87A4 #CJK UNIFIED IDEOGRAPH
+0xF0CC 0x87D7 #CJK UNIFIED IDEOGRAPH
+0xF0CD 0x87D9 #CJK UNIFIED IDEOGRAPH
+0xF0CE 0x8801 #CJK UNIFIED IDEOGRAPH
+0xF0CF 0x87F4 #CJK UNIFIED IDEOGRAPH
+0xF0D0 0x87E8 #CJK UNIFIED IDEOGRAPH
+0xF0D1 0x87DD #CJK UNIFIED IDEOGRAPH
+0xF0D2 0x8953 #CJK UNIFIED IDEOGRAPH
+0xF0D3 0x894B #CJK UNIFIED IDEOGRAPH
+0xF0D4 0x894F #CJK UNIFIED IDEOGRAPH
+0xF0D5 0x894C #CJK UNIFIED IDEOGRAPH
+0xF0D6 0x8946 #CJK UNIFIED IDEOGRAPH
+0xF0D7 0x8950 #CJK UNIFIED IDEOGRAPH
+0xF0D8 0x8951 #CJK UNIFIED IDEOGRAPH
+0xF0D9 0x8949 #CJK UNIFIED IDEOGRAPH
+0xF0DA 0x8B2A #CJK UNIFIED IDEOGRAPH
+0xF0DB 0x8B27 #CJK UNIFIED IDEOGRAPH
+0xF0DC 0x8B23 #CJK UNIFIED IDEOGRAPH
+0xF0DD 0x8B33 #CJK UNIFIED IDEOGRAPH
+0xF0DE 0x8B30 #CJK UNIFIED IDEOGRAPH
+0xF0DF 0x8B35 #CJK UNIFIED IDEOGRAPH
+0xF0E0 0x8B47 #CJK UNIFIED IDEOGRAPH
+0xF0E1 0x8B2F #CJK UNIFIED IDEOGRAPH
+0xF0E2 0x8B3C #CJK UNIFIED IDEOGRAPH
+0xF0E3 0x8B3E #CJK UNIFIED IDEOGRAPH
+0xF0E4 0x8B31 #CJK UNIFIED IDEOGRAPH
+0xF0E5 0x8B25 #CJK UNIFIED IDEOGRAPH
+0xF0E6 0x8B37 #CJK UNIFIED IDEOGRAPH
+0xF0E7 0x8B26 #CJK UNIFIED IDEOGRAPH
+0xF0E8 0x8B36 #CJK UNIFIED IDEOGRAPH
+0xF0E9 0x8B2E #CJK UNIFIED IDEOGRAPH
+0xF0EA 0x8B24 #CJK UNIFIED IDEOGRAPH
+0xF0EB 0x8B3B #CJK UNIFIED IDEOGRAPH
+0xF0EC 0x8B3D #CJK UNIFIED IDEOGRAPH
+0xF0ED 0x8B3A #CJK UNIFIED IDEOGRAPH
+0xF0EE 0x8C42 #CJK UNIFIED IDEOGRAPH
+0xF0EF 0x8C75 #CJK UNIFIED IDEOGRAPH
+0xF0F0 0x8C99 #CJK UNIFIED IDEOGRAPH
+0xF0F1 0x8C98 #CJK UNIFIED IDEOGRAPH
+0xF0F2 0x8C97 #CJK UNIFIED IDEOGRAPH
+0xF0F3 0x8CFE #CJK UNIFIED IDEOGRAPH
+0xF0F4 0x8D04 #CJK UNIFIED IDEOGRAPH
+0xF0F5 0x8D02 #CJK UNIFIED IDEOGRAPH
+0xF0F6 0x8D00 #CJK UNIFIED IDEOGRAPH
+0xF0F7 0x8E5C #CJK UNIFIED IDEOGRAPH
+0xF0F8 0x8E62 #CJK UNIFIED IDEOGRAPH
+0xF0F9 0x8E60 #CJK UNIFIED IDEOGRAPH
+0xF0FA 0x8E57 #CJK UNIFIED IDEOGRAPH
+0xF0FB 0x8E56 #CJK UNIFIED IDEOGRAPH
+0xF0FC 0x8E5E #CJK UNIFIED IDEOGRAPH
+0xF0FD 0x8E65 #CJK UNIFIED IDEOGRAPH
+0xF0FE 0x8E67 #CJK UNIFIED IDEOGRAPH
+0xF140 0x8E5B #CJK UNIFIED IDEOGRAPH
+0xF141 0x8E5A #CJK UNIFIED IDEOGRAPH
+0xF142 0x8E61 #CJK UNIFIED IDEOGRAPH
+0xF143 0x8E5D #CJK UNIFIED IDEOGRAPH
+0xF144 0x8E69 #CJK UNIFIED IDEOGRAPH
+0xF145 0x8E54 #CJK UNIFIED IDEOGRAPH
+0xF146 0x8F46 #CJK UNIFIED IDEOGRAPH
+0xF147 0x8F47 #CJK UNIFIED IDEOGRAPH
+0xF148 0x8F48 #CJK UNIFIED IDEOGRAPH
+0xF149 0x8F4B #CJK UNIFIED IDEOGRAPH
+0xF14A 0x9128 #CJK UNIFIED IDEOGRAPH
+0xF14B 0x913A #CJK UNIFIED IDEOGRAPH
+0xF14C 0x913B #CJK UNIFIED IDEOGRAPH
+0xF14D 0x913E #CJK UNIFIED IDEOGRAPH
+0xF14E 0x91A8 #CJK UNIFIED IDEOGRAPH
+0xF14F 0x91A5 #CJK UNIFIED IDEOGRAPH
+0xF150 0x91A7 #CJK UNIFIED IDEOGRAPH
+0xF151 0x91AF #CJK UNIFIED IDEOGRAPH
+0xF152 0x91AA #CJK UNIFIED IDEOGRAPH
+0xF153 0x93B5 #CJK UNIFIED IDEOGRAPH
+0xF154 0x938C #CJK UNIFIED IDEOGRAPH
+0xF155 0x9392 #CJK UNIFIED IDEOGRAPH
+0xF156 0x93B7 #CJK UNIFIED IDEOGRAPH
+0xF157 0x939B #CJK UNIFIED IDEOGRAPH
+0xF158 0x939D #CJK UNIFIED IDEOGRAPH
+0xF159 0x9389 #CJK UNIFIED IDEOGRAPH
+0xF15A 0x93A7 #CJK UNIFIED IDEOGRAPH
+0xF15B 0x938E #CJK UNIFIED IDEOGRAPH
+0xF15C 0x93AA #CJK UNIFIED IDEOGRAPH
+0xF15D 0x939E #CJK UNIFIED IDEOGRAPH
+0xF15E 0x93A6 #CJK UNIFIED IDEOGRAPH
+0xF15F 0x9395 #CJK UNIFIED IDEOGRAPH
+0xF160 0x9388 #CJK UNIFIED IDEOGRAPH
+0xF161 0x9399 #CJK UNIFIED IDEOGRAPH
+0xF162 0x939F #CJK UNIFIED IDEOGRAPH
+0xF163 0x938D #CJK UNIFIED IDEOGRAPH
+0xF164 0x93B1 #CJK UNIFIED IDEOGRAPH
+0xF165 0x9391 #CJK UNIFIED IDEOGRAPH
+0xF166 0x93B2 #CJK UNIFIED IDEOGRAPH
+0xF167 0x93A4 #CJK UNIFIED IDEOGRAPH
+0xF168 0x93A8 #CJK UNIFIED IDEOGRAPH
+0xF169 0x93B4 #CJK UNIFIED IDEOGRAPH
+0xF16A 0x93A3 #CJK UNIFIED IDEOGRAPH
+0xF16B 0x93A5 #CJK UNIFIED IDEOGRAPH
+0xF16C 0x95D2 #CJK UNIFIED IDEOGRAPH
+0xF16D 0x95D3 #CJK UNIFIED IDEOGRAPH
+0xF16E 0x95D1 #CJK UNIFIED IDEOGRAPH
+0xF16F 0x96B3 #CJK UNIFIED IDEOGRAPH
+0xF170 0x96D7 #CJK UNIFIED IDEOGRAPH
+0xF171 0x96DA #CJK UNIFIED IDEOGRAPH
+0xF172 0x5DC2 #CJK UNIFIED IDEOGRAPH
+0xF173 0x96DF #CJK UNIFIED IDEOGRAPH
+0xF174 0x96D8 #CJK UNIFIED IDEOGRAPH
+0xF175 0x96DD #CJK UNIFIED IDEOGRAPH
+0xF176 0x9723 #CJK UNIFIED IDEOGRAPH
+0xF177 0x9722 #CJK UNIFIED IDEOGRAPH
+0xF178 0x9725 #CJK UNIFIED IDEOGRAPH
+0xF179 0x97AC #CJK UNIFIED IDEOGRAPH
+0xF17A 0x97AE #CJK UNIFIED IDEOGRAPH
+0xF17B 0x97A8 #CJK UNIFIED IDEOGRAPH
+0xF17C 0x97AB #CJK UNIFIED IDEOGRAPH
+0xF17D 0x97A4 #CJK UNIFIED IDEOGRAPH
+0xF17E 0x97AA #CJK UNIFIED IDEOGRAPH
+0xF1A1 0x97A2 #CJK UNIFIED IDEOGRAPH
+0xF1A2 0x97A5 #CJK UNIFIED IDEOGRAPH
+0xF1A3 0x97D7 #CJK UNIFIED IDEOGRAPH
+0xF1A4 0x97D9 #CJK UNIFIED IDEOGRAPH
+0xF1A5 0x97D6 #CJK UNIFIED IDEOGRAPH
+0xF1A6 0x97D8 #CJK UNIFIED IDEOGRAPH
+0xF1A7 0x97FA #CJK UNIFIED IDEOGRAPH
+0xF1A8 0x9850 #CJK UNIFIED IDEOGRAPH
+0xF1A9 0x9851 #CJK UNIFIED IDEOGRAPH
+0xF1AA 0x9852 #CJK UNIFIED IDEOGRAPH
+0xF1AB 0x98B8 #CJK UNIFIED IDEOGRAPH
+0xF1AC 0x9941 #CJK UNIFIED IDEOGRAPH
+0xF1AD 0x993C #CJK UNIFIED IDEOGRAPH
+0xF1AE 0x993A #CJK UNIFIED IDEOGRAPH
+0xF1AF 0x9A0F #CJK UNIFIED IDEOGRAPH
+0xF1B0 0x9A0B #CJK UNIFIED IDEOGRAPH
+0xF1B1 0x9A09 #CJK UNIFIED IDEOGRAPH
+0xF1B2 0x9A0D #CJK UNIFIED IDEOGRAPH
+0xF1B3 0x9A04 #CJK UNIFIED IDEOGRAPH
+0xF1B4 0x9A11 #CJK UNIFIED IDEOGRAPH
+0xF1B5 0x9A0A #CJK UNIFIED IDEOGRAPH
+0xF1B6 0x9A05 #CJK UNIFIED IDEOGRAPH
+0xF1B7 0x9A07 #CJK UNIFIED IDEOGRAPH
+0xF1B8 0x9A06 #CJK UNIFIED IDEOGRAPH
+0xF1B9 0x9AC0 #CJK UNIFIED IDEOGRAPH
+0xF1BA 0x9ADC #CJK UNIFIED IDEOGRAPH
+0xF1BB 0x9B08 #CJK UNIFIED IDEOGRAPH
+0xF1BC 0x9B04 #CJK UNIFIED IDEOGRAPH
+0xF1BD 0x9B05 #CJK UNIFIED IDEOGRAPH
+0xF1BE 0x9B29 #CJK UNIFIED IDEOGRAPH
+0xF1BF 0x9B35 #CJK UNIFIED IDEOGRAPH
+0xF1C0 0x9B4A #CJK UNIFIED IDEOGRAPH
+0xF1C1 0x9B4C #CJK UNIFIED IDEOGRAPH
+0xF1C2 0x9B4B #CJK UNIFIED IDEOGRAPH
+0xF1C3 0x9BC7 #CJK UNIFIED IDEOGRAPH
+0xF1C4 0x9BC6 #CJK UNIFIED IDEOGRAPH
+0xF1C5 0x9BC3 #CJK UNIFIED IDEOGRAPH
+0xF1C6 0x9BBF #CJK UNIFIED IDEOGRAPH
+0xF1C7 0x9BC1 #CJK UNIFIED IDEOGRAPH
+0xF1C8 0x9BB5 #CJK UNIFIED IDEOGRAPH
+0xF1C9 0x9BB8 #CJK UNIFIED IDEOGRAPH
+0xF1CA 0x9BD3 #CJK UNIFIED IDEOGRAPH
+0xF1CB 0x9BB6 #CJK UNIFIED IDEOGRAPH
+0xF1CC 0x9BC4 #CJK UNIFIED IDEOGRAPH
+0xF1CD 0x9BB9 #CJK UNIFIED IDEOGRAPH
+0xF1CE 0x9BBD #CJK UNIFIED IDEOGRAPH
+0xF1CF 0x9D5C #CJK UNIFIED IDEOGRAPH
+0xF1D0 0x9D53 #CJK UNIFIED IDEOGRAPH
+0xF1D1 0x9D4F #CJK UNIFIED IDEOGRAPH
+0xF1D2 0x9D4A #CJK UNIFIED IDEOGRAPH
+0xF1D3 0x9D5B #CJK UNIFIED IDEOGRAPH
+0xF1D4 0x9D4B #CJK UNIFIED IDEOGRAPH
+0xF1D5 0x9D59 #CJK UNIFIED IDEOGRAPH
+0xF1D6 0x9D56 #CJK UNIFIED IDEOGRAPH
+0xF1D7 0x9D4C #CJK UNIFIED IDEOGRAPH
+0xF1D8 0x9D57 #CJK UNIFIED IDEOGRAPH
+0xF1D9 0x9D52 #CJK UNIFIED IDEOGRAPH
+0xF1DA 0x9D54 #CJK UNIFIED IDEOGRAPH
+0xF1DB 0x9D5F #CJK UNIFIED IDEOGRAPH
+0xF1DC 0x9D58 #CJK UNIFIED IDEOGRAPH
+0xF1DD 0x9D5A #CJK UNIFIED IDEOGRAPH
+0xF1DE 0x9E8E #CJK UNIFIED IDEOGRAPH
+0xF1DF 0x9E8C #CJK UNIFIED IDEOGRAPH
+0xF1E0 0x9EDF #CJK UNIFIED IDEOGRAPH
+0xF1E1 0x9F01 #CJK UNIFIED IDEOGRAPH
+0xF1E2 0x9F00 #CJK UNIFIED IDEOGRAPH
+0xF1E3 0x9F16 #CJK UNIFIED IDEOGRAPH
+0xF1E4 0x9F25 #CJK UNIFIED IDEOGRAPH
+0xF1E5 0x9F2B #CJK UNIFIED IDEOGRAPH
+0xF1E6 0x9F2A #CJK UNIFIED IDEOGRAPH
+0xF1E7 0x9F29 #CJK UNIFIED IDEOGRAPH
+0xF1E8 0x9F28 #CJK UNIFIED IDEOGRAPH
+0xF1E9 0x9F4C #CJK UNIFIED IDEOGRAPH
+0xF1EA 0x9F55 #CJK UNIFIED IDEOGRAPH
+0xF1EB 0x5134 #CJK UNIFIED IDEOGRAPH
+0xF1EC 0x5135 #CJK UNIFIED IDEOGRAPH
+0xF1ED 0x5296 #CJK UNIFIED IDEOGRAPH
+0xF1EE 0x52F7 #CJK UNIFIED IDEOGRAPH
+0xF1EF 0x53B4 #CJK UNIFIED IDEOGRAPH
+0xF1F0 0x56AB #CJK UNIFIED IDEOGRAPH
+0xF1F1 0x56AD #CJK UNIFIED IDEOGRAPH
+0xF1F2 0x56A6 #CJK UNIFIED IDEOGRAPH
+0xF1F3 0x56A7 #CJK UNIFIED IDEOGRAPH
+0xF1F4 0x56AA #CJK UNIFIED IDEOGRAPH
+0xF1F5 0x56AC #CJK UNIFIED IDEOGRAPH
+0xF1F6 0x58DA #CJK UNIFIED IDEOGRAPH
+0xF1F7 0x58DD #CJK UNIFIED IDEOGRAPH
+0xF1F8 0x58DB #CJK UNIFIED IDEOGRAPH
+0xF1F9 0x5912 #CJK UNIFIED IDEOGRAPH
+0xF1FA 0x5B3D #CJK UNIFIED IDEOGRAPH
+0xF1FB 0x5B3E #CJK UNIFIED IDEOGRAPH
+0xF1FC 0x5B3F #CJK UNIFIED IDEOGRAPH
+0xF1FD 0x5DC3 #CJK UNIFIED IDEOGRAPH
+0xF1FE 0x5E70 #CJK UNIFIED IDEOGRAPH
+0xF240 0x5FBF #CJK UNIFIED IDEOGRAPH
+0xF241 0x61FB #CJK UNIFIED IDEOGRAPH
+0xF242 0x6507 #CJK UNIFIED IDEOGRAPH
+0xF243 0x6510 #CJK UNIFIED IDEOGRAPH
+0xF244 0x650D #CJK UNIFIED IDEOGRAPH
+0xF245 0x6509 #CJK UNIFIED IDEOGRAPH
+0xF246 0x650C #CJK UNIFIED IDEOGRAPH
+0xF247 0x650E #CJK UNIFIED IDEOGRAPH
+0xF248 0x6584 #CJK UNIFIED IDEOGRAPH
+0xF249 0x65DE #CJK UNIFIED IDEOGRAPH
+0xF24A 0x65DD #CJK UNIFIED IDEOGRAPH
+0xF24B 0x66DE #CJK UNIFIED IDEOGRAPH
+0xF24C 0x6AE7 #CJK UNIFIED IDEOGRAPH
+0xF24D 0x6AE0 #CJK UNIFIED IDEOGRAPH
+0xF24E 0x6ACC #CJK UNIFIED IDEOGRAPH
+0xF24F 0x6AD1 #CJK UNIFIED IDEOGRAPH
+0xF250 0x6AD9 #CJK UNIFIED IDEOGRAPH
+0xF251 0x6ACB #CJK UNIFIED IDEOGRAPH
+0xF252 0x6ADF #CJK UNIFIED IDEOGRAPH
+0xF253 0x6ADC #CJK UNIFIED IDEOGRAPH
+0xF254 0x6AD0 #CJK UNIFIED IDEOGRAPH
+0xF255 0x6AEB #CJK UNIFIED IDEOGRAPH
+0xF256 0x6ACF #CJK UNIFIED IDEOGRAPH
+0xF257 0x6ACD #CJK UNIFIED IDEOGRAPH
+0xF258 0x6ADE #CJK UNIFIED IDEOGRAPH
+0xF259 0x6B60 #CJK UNIFIED IDEOGRAPH
+0xF25A 0x6BB0 #CJK UNIFIED IDEOGRAPH
+0xF25B 0x6C0C #CJK UNIFIED IDEOGRAPH
+0xF25C 0x7019 #CJK UNIFIED IDEOGRAPH
+0xF25D 0x7027 #CJK UNIFIED IDEOGRAPH
+0xF25E 0x7020 #CJK UNIFIED IDEOGRAPH
+0xF25F 0x7016 #CJK UNIFIED IDEOGRAPH
+0xF260 0x702B #CJK UNIFIED IDEOGRAPH
+0xF261 0x7021 #CJK UNIFIED IDEOGRAPH
+0xF262 0x7022 #CJK UNIFIED IDEOGRAPH
+0xF263 0x7023 #CJK UNIFIED IDEOGRAPH
+0xF264 0x7029 #CJK UNIFIED IDEOGRAPH
+0xF265 0x7017 #CJK UNIFIED IDEOGRAPH
+0xF266 0x7024 #CJK UNIFIED IDEOGRAPH
+0xF267 0x701C #CJK UNIFIED IDEOGRAPH
+0xF268 0x702A #CJK UNIFIED IDEOGRAPH
+0xF269 0x720C #CJK UNIFIED IDEOGRAPH
+0xF26A 0x720A #CJK UNIFIED IDEOGRAPH
+0xF26B 0x7207 #CJK UNIFIED IDEOGRAPH
+0xF26C 0x7202 #CJK UNIFIED IDEOGRAPH
+0xF26D 0x7205 #CJK UNIFIED IDEOGRAPH
+0xF26E 0x72A5 #CJK UNIFIED IDEOGRAPH
+0xF26F 0x72A6 #CJK UNIFIED IDEOGRAPH
+0xF270 0x72A4 #CJK UNIFIED IDEOGRAPH
+0xF271 0x72A3 #CJK UNIFIED IDEOGRAPH
+0xF272 0x72A1 #CJK UNIFIED IDEOGRAPH
+0xF273 0x74CB #CJK UNIFIED IDEOGRAPH
+0xF274 0x74C5 #CJK UNIFIED IDEOGRAPH
+0xF275 0x74B7 #CJK UNIFIED IDEOGRAPH
+0xF276 0x74C3 #CJK UNIFIED IDEOGRAPH
+0xF277 0x7516 #CJK UNIFIED IDEOGRAPH
+0xF278 0x7660 #CJK UNIFIED IDEOGRAPH
+0xF279 0x77C9 #CJK UNIFIED IDEOGRAPH
+0xF27A 0x77CA #CJK UNIFIED IDEOGRAPH
+0xF27B 0x77C4 #CJK UNIFIED IDEOGRAPH
+0xF27C 0x77F1 #CJK UNIFIED IDEOGRAPH
+0xF27D 0x791D #CJK UNIFIED IDEOGRAPH
+0xF27E 0x791B #CJK UNIFIED IDEOGRAPH
+0xF2A1 0x7921 #CJK UNIFIED IDEOGRAPH
+0xF2A2 0x791C #CJK UNIFIED IDEOGRAPH
+0xF2A3 0x7917 #CJK UNIFIED IDEOGRAPH
+0xF2A4 0x791E #CJK UNIFIED IDEOGRAPH
+0xF2A5 0x79B0 #CJK UNIFIED IDEOGRAPH
+0xF2A6 0x7A67 #CJK UNIFIED IDEOGRAPH
+0xF2A7 0x7A68 #CJK UNIFIED IDEOGRAPH
+0xF2A8 0x7C33 #CJK UNIFIED IDEOGRAPH
+0xF2A9 0x7C3C #CJK UNIFIED IDEOGRAPH
+0xF2AA 0x7C39 #CJK UNIFIED IDEOGRAPH
+0xF2AB 0x7C2C #CJK UNIFIED IDEOGRAPH
+0xF2AC 0x7C3B #CJK UNIFIED IDEOGRAPH
+0xF2AD 0x7CEC #CJK UNIFIED IDEOGRAPH
+0xF2AE 0x7CEA #CJK UNIFIED IDEOGRAPH
+0xF2AF 0x7E76 #CJK UNIFIED IDEOGRAPH
+0xF2B0 0x7E75 #CJK UNIFIED IDEOGRAPH
+0xF2B1 0x7E78 #CJK UNIFIED IDEOGRAPH
+0xF2B2 0x7E70 #CJK UNIFIED IDEOGRAPH
+0xF2B3 0x7E77 #CJK UNIFIED IDEOGRAPH
+0xF2B4 0x7E6F #CJK UNIFIED IDEOGRAPH
+0xF2B5 0x7E7A #CJK UNIFIED IDEOGRAPH
+0xF2B6 0x7E72 #CJK UNIFIED IDEOGRAPH
+0xF2B7 0x7E74 #CJK UNIFIED IDEOGRAPH
+0xF2B8 0x7E68 #CJK UNIFIED IDEOGRAPH
+0xF2B9 0x7F4B #CJK UNIFIED IDEOGRAPH
+0xF2BA 0x7F4A #CJK UNIFIED IDEOGRAPH
+0xF2BB 0x7F83 #CJK UNIFIED IDEOGRAPH
+0xF2BC 0x7F86 #CJK UNIFIED IDEOGRAPH
+0xF2BD 0x7FB7 #CJK UNIFIED IDEOGRAPH
+0xF2BE 0x7FFD #CJK UNIFIED IDEOGRAPH
+0xF2BF 0x7FFE #CJK UNIFIED IDEOGRAPH
+0xF2C0 0x8078 #CJK UNIFIED IDEOGRAPH
+0xF2C1 0x81D7 #CJK UNIFIED IDEOGRAPH
+0xF2C2 0x81D5 #CJK UNIFIED IDEOGRAPH
+0xF2C3 0x8264 #CJK UNIFIED IDEOGRAPH
+0xF2C4 0x8261 #CJK UNIFIED IDEOGRAPH
+0xF2C5 0x8263 #CJK UNIFIED IDEOGRAPH
+0xF2C6 0x85EB #CJK UNIFIED IDEOGRAPH
+0xF2C7 0x85F1 #CJK UNIFIED IDEOGRAPH
+0xF2C8 0x85ED #CJK UNIFIED IDEOGRAPH
+0xF2C9 0x85D9 #CJK UNIFIED IDEOGRAPH
+0xF2CA 0x85E1 #CJK UNIFIED IDEOGRAPH
+0xF2CB 0x85E8 #CJK UNIFIED IDEOGRAPH
+0xF2CC 0x85DA #CJK UNIFIED IDEOGRAPH
+0xF2CD 0x85D7 #CJK UNIFIED IDEOGRAPH
+0xF2CE 0x85EC #CJK UNIFIED IDEOGRAPH
+0xF2CF 0x85F2 #CJK UNIFIED IDEOGRAPH
+0xF2D0 0x85F8 #CJK UNIFIED IDEOGRAPH
+0xF2D1 0x85D8 #CJK UNIFIED IDEOGRAPH
+0xF2D2 0x85DF #CJK UNIFIED IDEOGRAPH
+0xF2D3 0x85E3 #CJK UNIFIED IDEOGRAPH
+0xF2D4 0x85DC #CJK UNIFIED IDEOGRAPH
+0xF2D5 0x85D1 #CJK UNIFIED IDEOGRAPH
+0xF2D6 0x85F0 #CJK UNIFIED IDEOGRAPH
+0xF2D7 0x85E6 #CJK UNIFIED IDEOGRAPH
+0xF2D8 0x85EF #CJK UNIFIED IDEOGRAPH
+0xF2D9 0x85DE #CJK UNIFIED IDEOGRAPH
+0xF2DA 0x85E2 #CJK UNIFIED IDEOGRAPH
+0xF2DB 0x8800 #CJK UNIFIED IDEOGRAPH
+0xF2DC 0x87FA #CJK UNIFIED IDEOGRAPH
+0xF2DD 0x8803 #CJK UNIFIED IDEOGRAPH
+0xF2DE 0x87F6 #CJK UNIFIED IDEOGRAPH
+0xF2DF 0x87F7 #CJK UNIFIED IDEOGRAPH
+0xF2E0 0x8809 #CJK UNIFIED IDEOGRAPH
+0xF2E1 0x880C #CJK UNIFIED IDEOGRAPH
+0xF2E2 0x880B #CJK UNIFIED IDEOGRAPH
+0xF2E3 0x8806 #CJK UNIFIED IDEOGRAPH
+0xF2E4 0x87FC #CJK UNIFIED IDEOGRAPH
+0xF2E5 0x8808 #CJK UNIFIED IDEOGRAPH
+0xF2E6 0x87FF #CJK UNIFIED IDEOGRAPH
+0xF2E7 0x880A #CJK UNIFIED IDEOGRAPH
+0xF2E8 0x8802 #CJK UNIFIED IDEOGRAPH
+0xF2E9 0x8962 #CJK UNIFIED IDEOGRAPH
+0xF2EA 0x895A #CJK UNIFIED IDEOGRAPH
+0xF2EB 0x895B #CJK UNIFIED IDEOGRAPH
+0xF2EC 0x8957 #CJK UNIFIED IDEOGRAPH
+0xF2ED 0x8961 #CJK UNIFIED IDEOGRAPH
+0xF2EE 0x895C #CJK UNIFIED IDEOGRAPH
+0xF2EF 0x8958 #CJK UNIFIED IDEOGRAPH
+0xF2F0 0x895D #CJK UNIFIED IDEOGRAPH
+0xF2F1 0x8959 #CJK UNIFIED IDEOGRAPH
+0xF2F2 0x8988 #CJK UNIFIED IDEOGRAPH
+0xF2F3 0x89B7 #CJK UNIFIED IDEOGRAPH
+0xF2F4 0x89B6 #CJK UNIFIED IDEOGRAPH
+0xF2F5 0x89F6 #CJK UNIFIED IDEOGRAPH
+0xF2F6 0x8B50 #CJK UNIFIED IDEOGRAPH
+0xF2F7 0x8B48 #CJK UNIFIED IDEOGRAPH
+0xF2F8 0x8B4A #CJK UNIFIED IDEOGRAPH
+0xF2F9 0x8B40 #CJK UNIFIED IDEOGRAPH
+0xF2FA 0x8B53 #CJK UNIFIED IDEOGRAPH
+0xF2FB 0x8B56 #CJK UNIFIED IDEOGRAPH
+0xF2FC 0x8B54 #CJK UNIFIED IDEOGRAPH
+0xF2FD 0x8B4B #CJK UNIFIED IDEOGRAPH
+0xF2FE 0x8B55 #CJK UNIFIED IDEOGRAPH
+0xF340 0x8B51 #CJK UNIFIED IDEOGRAPH
+0xF341 0x8B42 #CJK UNIFIED IDEOGRAPH
+0xF342 0x8B52 #CJK UNIFIED IDEOGRAPH
+0xF343 0x8B57 #CJK UNIFIED IDEOGRAPH
+0xF344 0x8C43 #CJK UNIFIED IDEOGRAPH
+0xF345 0x8C77 #CJK UNIFIED IDEOGRAPH
+0xF346 0x8C76 #CJK UNIFIED IDEOGRAPH
+0xF347 0x8C9A #CJK UNIFIED IDEOGRAPH
+0xF348 0x8D06 #CJK UNIFIED IDEOGRAPH
+0xF349 0x8D07 #CJK UNIFIED IDEOGRAPH
+0xF34A 0x8D09 #CJK UNIFIED IDEOGRAPH
+0xF34B 0x8DAC #CJK UNIFIED IDEOGRAPH
+0xF34C 0x8DAA #CJK UNIFIED IDEOGRAPH
+0xF34D 0x8DAD #CJK UNIFIED IDEOGRAPH
+0xF34E 0x8DAB #CJK UNIFIED IDEOGRAPH
+0xF34F 0x8E6D #CJK UNIFIED IDEOGRAPH
+0xF350 0x8E78 #CJK UNIFIED IDEOGRAPH
+0xF351 0x8E73 #CJK UNIFIED IDEOGRAPH
+0xF352 0x8E6A #CJK UNIFIED IDEOGRAPH
+0xF353 0x8E6F #CJK UNIFIED IDEOGRAPH
+0xF354 0x8E7B #CJK UNIFIED IDEOGRAPH
+0xF355 0x8EC2 #CJK UNIFIED IDEOGRAPH
+0xF356 0x8F52 #CJK UNIFIED IDEOGRAPH
+0xF357 0x8F51 #CJK UNIFIED IDEOGRAPH
+0xF358 0x8F4F #CJK UNIFIED IDEOGRAPH
+0xF359 0x8F50 #CJK UNIFIED IDEOGRAPH
+0xF35A 0x8F53 #CJK UNIFIED IDEOGRAPH
+0xF35B 0x8FB4 #CJK UNIFIED IDEOGRAPH
+0xF35C 0x9140 #CJK UNIFIED IDEOGRAPH
+0xF35D 0x913F #CJK UNIFIED IDEOGRAPH
+0xF35E 0x91B0 #CJK UNIFIED IDEOGRAPH
+0xF35F 0x91AD #CJK UNIFIED IDEOGRAPH
+0xF360 0x93DE #CJK UNIFIED IDEOGRAPH
+0xF361 0x93C7 #CJK UNIFIED IDEOGRAPH
+0xF362 0x93CF #CJK UNIFIED IDEOGRAPH
+0xF363 0x93C2 #CJK UNIFIED IDEOGRAPH
+0xF364 0x93DA #CJK UNIFIED IDEOGRAPH
+0xF365 0x93D0 #CJK UNIFIED IDEOGRAPH
+0xF366 0x93F9 #CJK UNIFIED IDEOGRAPH
+0xF367 0x93EC #CJK UNIFIED IDEOGRAPH
+0xF368 0x93CC #CJK UNIFIED IDEOGRAPH
+0xF369 0x93D9 #CJK UNIFIED IDEOGRAPH
+0xF36A 0x93A9 #CJK UNIFIED IDEOGRAPH
+0xF36B 0x93E6 #CJK UNIFIED IDEOGRAPH
+0xF36C 0x93CA #CJK UNIFIED IDEOGRAPH
+0xF36D 0x93D4 #CJK UNIFIED IDEOGRAPH
+0xF36E 0x93EE #CJK UNIFIED IDEOGRAPH
+0xF36F 0x93E3 #CJK UNIFIED IDEOGRAPH
+0xF370 0x93D5 #CJK UNIFIED IDEOGRAPH
+0xF371 0x93C4 #CJK UNIFIED IDEOGRAPH
+0xF372 0x93CE #CJK UNIFIED IDEOGRAPH
+0xF373 0x93C0 #CJK UNIFIED IDEOGRAPH
+0xF374 0x93D2 #CJK UNIFIED IDEOGRAPH
+0xF375 0x93E7 #CJK UNIFIED IDEOGRAPH
+0xF376 0x957D #CJK UNIFIED IDEOGRAPH
+0xF377 0x95DA #CJK UNIFIED IDEOGRAPH
+0xF378 0x95DB #CJK UNIFIED IDEOGRAPH
+0xF379 0x96E1 #CJK UNIFIED IDEOGRAPH
+0xF37A 0x9729 #CJK UNIFIED IDEOGRAPH
+0xF37B 0x972B #CJK UNIFIED IDEOGRAPH
+0xF37C 0x972C #CJK UNIFIED IDEOGRAPH
+0xF37D 0x9728 #CJK UNIFIED IDEOGRAPH
+0xF37E 0x9726 #CJK UNIFIED IDEOGRAPH
+0xF3A1 0x97B3 #CJK UNIFIED IDEOGRAPH
+0xF3A2 0x97B7 #CJK UNIFIED IDEOGRAPH
+0xF3A3 0x97B6 #CJK UNIFIED IDEOGRAPH
+0xF3A4 0x97DD #CJK UNIFIED IDEOGRAPH
+0xF3A5 0x97DE #CJK UNIFIED IDEOGRAPH
+0xF3A6 0x97DF #CJK UNIFIED IDEOGRAPH
+0xF3A7 0x985C #CJK UNIFIED IDEOGRAPH
+0xF3A8 0x9859 #CJK UNIFIED IDEOGRAPH
+0xF3A9 0x985D #CJK UNIFIED IDEOGRAPH
+0xF3AA 0x9857 #CJK UNIFIED IDEOGRAPH
+0xF3AB 0x98BF #CJK UNIFIED IDEOGRAPH
+0xF3AC 0x98BD #CJK UNIFIED IDEOGRAPH
+0xF3AD 0x98BB #CJK UNIFIED IDEOGRAPH
+0xF3AE 0x98BE #CJK UNIFIED IDEOGRAPH
+0xF3AF 0x9948 #CJK UNIFIED IDEOGRAPH
+0xF3B0 0x9947 #CJK UNIFIED IDEOGRAPH
+0xF3B1 0x9943 #CJK UNIFIED IDEOGRAPH
+0xF3B2 0x99A6 #CJK UNIFIED IDEOGRAPH
+0xF3B3 0x99A7 #CJK UNIFIED IDEOGRAPH
+0xF3B4 0x9A1A #CJK UNIFIED IDEOGRAPH
+0xF3B5 0x9A15 #CJK UNIFIED IDEOGRAPH
+0xF3B6 0x9A25 #CJK UNIFIED IDEOGRAPH
+0xF3B7 0x9A1D #CJK UNIFIED IDEOGRAPH
+0xF3B8 0x9A24 #CJK UNIFIED IDEOGRAPH
+0xF3B9 0x9A1B #CJK UNIFIED IDEOGRAPH
+0xF3BA 0x9A22 #CJK UNIFIED IDEOGRAPH
+0xF3BB 0x9A20 #CJK UNIFIED IDEOGRAPH
+0xF3BC 0x9A27 #CJK UNIFIED IDEOGRAPH
+0xF3BD 0x9A23 #CJK UNIFIED IDEOGRAPH
+0xF3BE 0x9A1E #CJK UNIFIED IDEOGRAPH
+0xF3BF 0x9A1C #CJK UNIFIED IDEOGRAPH
+0xF3C0 0x9A14 #CJK UNIFIED IDEOGRAPH
+0xF3C1 0x9AC2 #CJK UNIFIED IDEOGRAPH
+0xF3C2 0x9B0B #CJK UNIFIED IDEOGRAPH
+0xF3C3 0x9B0A #CJK UNIFIED IDEOGRAPH
+0xF3C4 0x9B0E #CJK UNIFIED IDEOGRAPH
+0xF3C5 0x9B0C #CJK UNIFIED IDEOGRAPH
+0xF3C6 0x9B37 #CJK UNIFIED IDEOGRAPH
+0xF3C7 0x9BEA #CJK UNIFIED IDEOGRAPH
+0xF3C8 0x9BEB #CJK UNIFIED IDEOGRAPH
+0xF3C9 0x9BE0 #CJK UNIFIED IDEOGRAPH
+0xF3CA 0x9BDE #CJK UNIFIED IDEOGRAPH
+0xF3CB 0x9BE4 #CJK UNIFIED IDEOGRAPH
+0xF3CC 0x9BE6 #CJK UNIFIED IDEOGRAPH
+0xF3CD 0x9BE2 #CJK UNIFIED IDEOGRAPH
+0xF3CE 0x9BF0 #CJK UNIFIED IDEOGRAPH
+0xF3CF 0x9BD4 #CJK UNIFIED IDEOGRAPH
+0xF3D0 0x9BD7 #CJK UNIFIED IDEOGRAPH
+0xF3D1 0x9BEC #CJK UNIFIED IDEOGRAPH
+0xF3D2 0x9BDC #CJK UNIFIED IDEOGRAPH
+0xF3D3 0x9BD9 #CJK UNIFIED IDEOGRAPH
+0xF3D4 0x9BE5 #CJK UNIFIED IDEOGRAPH
+0xF3D5 0x9BD5 #CJK UNIFIED IDEOGRAPH
+0xF3D6 0x9BE1 #CJK UNIFIED IDEOGRAPH
+0xF3D7 0x9BDA #CJK UNIFIED IDEOGRAPH
+0xF3D8 0x9D77 #CJK UNIFIED IDEOGRAPH
+0xF3D9 0x9D81 #CJK UNIFIED IDEOGRAPH
+0xF3DA 0x9D8A #CJK UNIFIED IDEOGRAPH
+0xF3DB 0x9D84 #CJK UNIFIED IDEOGRAPH
+0xF3DC 0x9D88 #CJK UNIFIED IDEOGRAPH
+0xF3DD 0x9D71 #CJK UNIFIED IDEOGRAPH
+0xF3DE 0x9D80 #CJK UNIFIED IDEOGRAPH
+0xF3DF 0x9D78 #CJK UNIFIED IDEOGRAPH
+0xF3E0 0x9D86 #CJK UNIFIED IDEOGRAPH
+0xF3E1 0x9D8B #CJK UNIFIED IDEOGRAPH
+0xF3E2 0x9D8C #CJK UNIFIED IDEOGRAPH
+0xF3E3 0x9D7D #CJK UNIFIED IDEOGRAPH
+0xF3E4 0x9D6B #CJK UNIFIED IDEOGRAPH
+0xF3E5 0x9D74 #CJK UNIFIED IDEOGRAPH
+0xF3E6 0x9D75 #CJK UNIFIED IDEOGRAPH
+0xF3E7 0x9D70 #CJK UNIFIED IDEOGRAPH
+0xF3E8 0x9D69 #CJK UNIFIED IDEOGRAPH
+0xF3E9 0x9D85 #CJK UNIFIED IDEOGRAPH
+0xF3EA 0x9D73 #CJK UNIFIED IDEOGRAPH
+0xF3EB 0x9D7B #CJK UNIFIED IDEOGRAPH
+0xF3EC 0x9D82 #CJK UNIFIED IDEOGRAPH
+0xF3ED 0x9D6F #CJK UNIFIED IDEOGRAPH
+0xF3EE 0x9D79 #CJK UNIFIED IDEOGRAPH
+0xF3EF 0x9D7F #CJK UNIFIED IDEOGRAPH
+0xF3F0 0x9D87 #CJK UNIFIED IDEOGRAPH
+0xF3F1 0x9D68 #CJK UNIFIED IDEOGRAPH
+0xF3F2 0x9E94 #CJK UNIFIED IDEOGRAPH
+0xF3F3 0x9E91 #CJK UNIFIED IDEOGRAPH
+0xF3F4 0x9EC0 #CJK UNIFIED IDEOGRAPH
+0xF3F5 0x9EFC #CJK UNIFIED IDEOGRAPH
+0xF3F6 0x9F2D #CJK UNIFIED IDEOGRAPH
+0xF3F7 0x9F40 #CJK UNIFIED IDEOGRAPH
+0xF3F8 0x9F41 #CJK UNIFIED IDEOGRAPH
+0xF3F9 0x9F4D #CJK UNIFIED IDEOGRAPH
+0xF3FA 0x9F56 #CJK UNIFIED IDEOGRAPH
+0xF3FB 0x9F57 #CJK UNIFIED IDEOGRAPH
+0xF3FC 0x9F58 #CJK UNIFIED IDEOGRAPH
+0xF3FD 0x5337 #CJK UNIFIED IDEOGRAPH
+0xF3FE 0x56B2 #CJK UNIFIED IDEOGRAPH
+0xF440 0x56B5 #CJK UNIFIED IDEOGRAPH
+0xF441 0x56B3 #CJK UNIFIED IDEOGRAPH
+0xF442 0x58E3 #CJK UNIFIED IDEOGRAPH
+0xF443 0x5B45 #CJK UNIFIED IDEOGRAPH
+0xF444 0x5DC6 #CJK UNIFIED IDEOGRAPH
+0xF445 0x5DC7 #CJK UNIFIED IDEOGRAPH
+0xF446 0x5EEE #CJK UNIFIED IDEOGRAPH
+0xF447 0x5EEF #CJK UNIFIED IDEOGRAPH
+0xF448 0x5FC0 #CJK UNIFIED IDEOGRAPH
+0xF449 0x5FC1 #CJK UNIFIED IDEOGRAPH
+0xF44A 0x61F9 #CJK UNIFIED IDEOGRAPH
+0xF44B 0x6517 #CJK UNIFIED IDEOGRAPH
+0xF44C 0x6516 #CJK UNIFIED IDEOGRAPH
+0xF44D 0x6515 #CJK UNIFIED IDEOGRAPH
+0xF44E 0x6513 #CJK UNIFIED IDEOGRAPH
+0xF44F 0x65DF #CJK UNIFIED IDEOGRAPH
+0xF450 0x66E8 #CJK UNIFIED IDEOGRAPH
+0xF451 0x66E3 #CJK UNIFIED IDEOGRAPH
+0xF452 0x66E4 #CJK UNIFIED IDEOGRAPH
+0xF453 0x6AF3 #CJK UNIFIED IDEOGRAPH
+0xF454 0x6AF0 #CJK UNIFIED IDEOGRAPH
+0xF455 0x6AEA #CJK UNIFIED IDEOGRAPH
+0xF456 0x6AE8 #CJK UNIFIED IDEOGRAPH
+0xF457 0x6AF9 #CJK UNIFIED IDEOGRAPH
+0xF458 0x6AF1 #CJK UNIFIED IDEOGRAPH
+0xF459 0x6AEE #CJK UNIFIED IDEOGRAPH
+0xF45A 0x6AEF #CJK UNIFIED IDEOGRAPH
+0xF45B 0x703C #CJK UNIFIED IDEOGRAPH
+0xF45C 0x7035 #CJK UNIFIED IDEOGRAPH
+0xF45D 0x702F #CJK UNIFIED IDEOGRAPH
+0xF45E 0x7037 #CJK UNIFIED IDEOGRAPH
+0xF45F 0x7034 #CJK UNIFIED IDEOGRAPH
+0xF460 0x7031 #CJK UNIFIED IDEOGRAPH
+0xF461 0x7042 #CJK UNIFIED IDEOGRAPH
+0xF462 0x7038 #CJK UNIFIED IDEOGRAPH
+0xF463 0x703F #CJK UNIFIED IDEOGRAPH
+0xF464 0x703A #CJK UNIFIED IDEOGRAPH
+0xF465 0x7039 #CJK UNIFIED IDEOGRAPH
+0xF466 0x7040 #CJK UNIFIED IDEOGRAPH
+0xF467 0x703B #CJK UNIFIED IDEOGRAPH
+0xF468 0x7033 #CJK UNIFIED IDEOGRAPH
+0xF469 0x7041 #CJK UNIFIED IDEOGRAPH
+0xF46A 0x7213 #CJK UNIFIED IDEOGRAPH
+0xF46B 0x7214 #CJK UNIFIED IDEOGRAPH
+0xF46C 0x72A8 #CJK UNIFIED IDEOGRAPH
+0xF46D 0x737D #CJK UNIFIED IDEOGRAPH
+0xF46E 0x737C #CJK UNIFIED IDEOGRAPH
+0xF46F 0x74BA #CJK UNIFIED IDEOGRAPH
+0xF470 0x76AB #CJK UNIFIED IDEOGRAPH
+0xF471 0x76AA #CJK UNIFIED IDEOGRAPH
+0xF472 0x76BE #CJK UNIFIED IDEOGRAPH
+0xF473 0x76ED #CJK UNIFIED IDEOGRAPH
+0xF474 0x77CC #CJK UNIFIED IDEOGRAPH
+0xF475 0x77CE #CJK UNIFIED IDEOGRAPH
+0xF476 0x77CF #CJK UNIFIED IDEOGRAPH
+0xF477 0x77CD #CJK UNIFIED IDEOGRAPH
+0xF478 0x77F2 #CJK UNIFIED IDEOGRAPH
+0xF479 0x7925 #CJK UNIFIED IDEOGRAPH
+0xF47A 0x7923 #CJK UNIFIED IDEOGRAPH
+0xF47B 0x7927 #CJK UNIFIED IDEOGRAPH
+0xF47C 0x7928 #CJK UNIFIED IDEOGRAPH
+0xF47D 0x7924 #CJK UNIFIED IDEOGRAPH
+0xF47E 0x7929 #CJK UNIFIED IDEOGRAPH
+0xF4A1 0x79B2 #CJK UNIFIED IDEOGRAPH
+0xF4A2 0x7A6E #CJK UNIFIED IDEOGRAPH
+0xF4A3 0x7A6C #CJK UNIFIED IDEOGRAPH
+0xF4A4 0x7A6D #CJK UNIFIED IDEOGRAPH
+0xF4A5 0x7AF7 #CJK UNIFIED IDEOGRAPH
+0xF4A6 0x7C49 #CJK UNIFIED IDEOGRAPH
+0xF4A7 0x7C48 #CJK UNIFIED IDEOGRAPH
+0xF4A8 0x7C4A #CJK UNIFIED IDEOGRAPH
+0xF4A9 0x7C47 #CJK UNIFIED IDEOGRAPH
+0xF4AA 0x7C45 #CJK UNIFIED IDEOGRAPH
+0xF4AB 0x7CEE #CJK UNIFIED IDEOGRAPH
+0xF4AC 0x7E7B #CJK UNIFIED IDEOGRAPH
+0xF4AD 0x7E7E #CJK UNIFIED IDEOGRAPH
+0xF4AE 0x7E81 #CJK UNIFIED IDEOGRAPH
+0xF4AF 0x7E80 #CJK UNIFIED IDEOGRAPH
+0xF4B0 0x7FBA #CJK UNIFIED IDEOGRAPH
+0xF4B1 0x7FFF #CJK UNIFIED IDEOGRAPH
+0xF4B2 0x8079 #CJK UNIFIED IDEOGRAPH
+0xF4B3 0x81DB #CJK UNIFIED IDEOGRAPH
+0xF4B4 0x81D9 #CJK UNIFIED IDEOGRAPH
+0xF4B5 0x820B #CJK UNIFIED IDEOGRAPH
+0xF4B6 0x8268 #CJK UNIFIED IDEOGRAPH
+0xF4B7 0x8269 #CJK UNIFIED IDEOGRAPH
+0xF4B8 0x8622 #CJK UNIFIED IDEOGRAPH
+0xF4B9 0x85FF #CJK UNIFIED IDEOGRAPH
+0xF4BA 0x8601 #CJK UNIFIED IDEOGRAPH
+0xF4BB 0x85FE #CJK UNIFIED IDEOGRAPH
+0xF4BC 0x861B #CJK UNIFIED IDEOGRAPH
+0xF4BD 0x8600 #CJK UNIFIED IDEOGRAPH
+0xF4BE 0x85F6 #CJK UNIFIED IDEOGRAPH
+0xF4BF 0x8604 #CJK UNIFIED IDEOGRAPH
+0xF4C0 0x8609 #CJK UNIFIED IDEOGRAPH
+0xF4C1 0x8605 #CJK UNIFIED IDEOGRAPH
+0xF4C2 0x860C #CJK UNIFIED IDEOGRAPH
+0xF4C3 0x85FD #CJK UNIFIED IDEOGRAPH
+0xF4C4 0x8819 #CJK UNIFIED IDEOGRAPH
+0xF4C5 0x8810 #CJK UNIFIED IDEOGRAPH
+0xF4C6 0x8811 #CJK UNIFIED IDEOGRAPH
+0xF4C7 0x8817 #CJK UNIFIED IDEOGRAPH
+0xF4C8 0x8813 #CJK UNIFIED IDEOGRAPH
+0xF4C9 0x8816 #CJK UNIFIED IDEOGRAPH
+0xF4CA 0x8963 #CJK UNIFIED IDEOGRAPH
+0xF4CB 0x8966 #CJK UNIFIED IDEOGRAPH
+0xF4CC 0x89B9 #CJK UNIFIED IDEOGRAPH
+0xF4CD 0x89F7 #CJK UNIFIED IDEOGRAPH
+0xF4CE 0x8B60 #CJK UNIFIED IDEOGRAPH
+0xF4CF 0x8B6A #CJK UNIFIED IDEOGRAPH
+0xF4D0 0x8B5D #CJK UNIFIED IDEOGRAPH
+0xF4D1 0x8B68 #CJK UNIFIED IDEOGRAPH
+0xF4D2 0x8B63 #CJK UNIFIED IDEOGRAPH
+0xF4D3 0x8B65 #CJK UNIFIED IDEOGRAPH
+0xF4D4 0x8B67 #CJK UNIFIED IDEOGRAPH
+0xF4D5 0x8B6D #CJK UNIFIED IDEOGRAPH
+0xF4D6 0x8DAE #CJK UNIFIED IDEOGRAPH
+0xF4D7 0x8E86 #CJK UNIFIED IDEOGRAPH
+0xF4D8 0x8E88 #CJK UNIFIED IDEOGRAPH
+0xF4D9 0x8E84 #CJK UNIFIED IDEOGRAPH
+0xF4DA 0x8F59 #CJK UNIFIED IDEOGRAPH
+0xF4DB 0x8F56 #CJK UNIFIED IDEOGRAPH
+0xF4DC 0x8F57 #CJK UNIFIED IDEOGRAPH
+0xF4DD 0x8F55 #CJK UNIFIED IDEOGRAPH
+0xF4DE 0x8F58 #CJK UNIFIED IDEOGRAPH
+0xF4DF 0x8F5A #CJK UNIFIED IDEOGRAPH
+0xF4E0 0x908D #CJK UNIFIED IDEOGRAPH
+0xF4E1 0x9143 #CJK UNIFIED IDEOGRAPH
+0xF4E2 0x9141 #CJK UNIFIED IDEOGRAPH
+0xF4E3 0x91B7 #CJK UNIFIED IDEOGRAPH
+0xF4E4 0x91B5 #CJK UNIFIED IDEOGRAPH
+0xF4E5 0x91B2 #CJK UNIFIED IDEOGRAPH
+0xF4E6 0x91B3 #CJK UNIFIED IDEOGRAPH
+0xF4E7 0x940B #CJK UNIFIED IDEOGRAPH
+0xF4E8 0x9413 #CJK UNIFIED IDEOGRAPH
+0xF4E9 0x93FB #CJK UNIFIED IDEOGRAPH
+0xF4EA 0x9420 #CJK UNIFIED IDEOGRAPH
+0xF4EB 0x940F #CJK UNIFIED IDEOGRAPH
+0xF4EC 0x9414 #CJK UNIFIED IDEOGRAPH
+0xF4ED 0x93FE #CJK UNIFIED IDEOGRAPH
+0xF4EE 0x9415 #CJK UNIFIED IDEOGRAPH
+0xF4EF 0x9410 #CJK UNIFIED IDEOGRAPH
+0xF4F0 0x9428 #CJK UNIFIED IDEOGRAPH
+0xF4F1 0x9419 #CJK UNIFIED IDEOGRAPH
+0xF4F2 0x940D #CJK UNIFIED IDEOGRAPH
+0xF4F3 0x93F5 #CJK UNIFIED IDEOGRAPH
+0xF4F4 0x9400 #CJK UNIFIED IDEOGRAPH
+0xF4F5 0x93F7 #CJK UNIFIED IDEOGRAPH
+0xF4F6 0x9407 #CJK UNIFIED IDEOGRAPH
+0xF4F7 0x940E #CJK UNIFIED IDEOGRAPH
+0xF4F8 0x9416 #CJK UNIFIED IDEOGRAPH
+0xF4F9 0x9412 #CJK UNIFIED IDEOGRAPH
+0xF4FA 0x93FA #CJK UNIFIED IDEOGRAPH
+0xF4FB 0x9409 #CJK UNIFIED IDEOGRAPH
+0xF4FC 0x93F8 #CJK UNIFIED IDEOGRAPH
+0xF4FD 0x940A #CJK UNIFIED IDEOGRAPH
+0xF4FE 0x93FF #CJK UNIFIED IDEOGRAPH
+0xF540 0x93FC #CJK UNIFIED IDEOGRAPH
+0xF541 0x940C #CJK UNIFIED IDEOGRAPH
+0xF542 0x93F6 #CJK UNIFIED IDEOGRAPH
+0xF543 0x9411 #CJK UNIFIED IDEOGRAPH
+0xF544 0x9406 #CJK UNIFIED IDEOGRAPH
+0xF545 0x95DE #CJK UNIFIED IDEOGRAPH
+0xF546 0x95E0 #CJK UNIFIED IDEOGRAPH
+0xF547 0x95DF #CJK UNIFIED IDEOGRAPH
+0xF548 0x972E #CJK UNIFIED IDEOGRAPH
+0xF549 0x972F #CJK UNIFIED IDEOGRAPH
+0xF54A 0x97B9 #CJK UNIFIED IDEOGRAPH
+0xF54B 0x97BB #CJK UNIFIED IDEOGRAPH
+0xF54C 0x97FD #CJK UNIFIED IDEOGRAPH
+0xF54D 0x97FE #CJK UNIFIED IDEOGRAPH
+0xF54E 0x9860 #CJK UNIFIED IDEOGRAPH
+0xF54F 0x9862 #CJK UNIFIED IDEOGRAPH
+0xF550 0x9863 #CJK UNIFIED IDEOGRAPH
+0xF551 0x985F #CJK UNIFIED IDEOGRAPH
+0xF552 0x98C1 #CJK UNIFIED IDEOGRAPH
+0xF553 0x98C2 #CJK UNIFIED IDEOGRAPH
+0xF554 0x9950 #CJK UNIFIED IDEOGRAPH
+0xF555 0x994E #CJK UNIFIED IDEOGRAPH
+0xF556 0x9959 #CJK UNIFIED IDEOGRAPH
+0xF557 0x994C #CJK UNIFIED IDEOGRAPH
+0xF558 0x994B #CJK UNIFIED IDEOGRAPH
+0xF559 0x9953 #CJK UNIFIED IDEOGRAPH
+0xF55A 0x9A32 #CJK UNIFIED IDEOGRAPH
+0xF55B 0x9A34 #CJK UNIFIED IDEOGRAPH
+0xF55C 0x9A31 #CJK UNIFIED IDEOGRAPH
+0xF55D 0x9A2C #CJK UNIFIED IDEOGRAPH
+0xF55E 0x9A2A #CJK UNIFIED IDEOGRAPH
+0xF55F 0x9A36 #CJK UNIFIED IDEOGRAPH
+0xF560 0x9A29 #CJK UNIFIED IDEOGRAPH
+0xF561 0x9A2E #CJK UNIFIED IDEOGRAPH
+0xF562 0x9A38 #CJK UNIFIED IDEOGRAPH
+0xF563 0x9A2D #CJK UNIFIED IDEOGRAPH
+0xF564 0x9AC7 #CJK UNIFIED IDEOGRAPH
+0xF565 0x9ACA #CJK UNIFIED IDEOGRAPH
+0xF566 0x9AC6 #CJK UNIFIED IDEOGRAPH
+0xF567 0x9B10 #CJK UNIFIED IDEOGRAPH
+0xF568 0x9B12 #CJK UNIFIED IDEOGRAPH
+0xF569 0x9B11 #CJK UNIFIED IDEOGRAPH
+0xF56A 0x9C0B #CJK UNIFIED IDEOGRAPH
+0xF56B 0x9C08 #CJK UNIFIED IDEOGRAPH
+0xF56C 0x9BF7 #CJK UNIFIED IDEOGRAPH
+0xF56D 0x9C05 #CJK UNIFIED IDEOGRAPH
+0xF56E 0x9C12 #CJK UNIFIED IDEOGRAPH
+0xF56F 0x9BF8 #CJK UNIFIED IDEOGRAPH
+0xF570 0x9C40 #CJK UNIFIED IDEOGRAPH
+0xF571 0x9C07 #CJK UNIFIED IDEOGRAPH
+0xF572 0x9C0E #CJK UNIFIED IDEOGRAPH
+0xF573 0x9C06 #CJK UNIFIED IDEOGRAPH
+0xF574 0x9C17 #CJK UNIFIED IDEOGRAPH
+0xF575 0x9C14 #CJK UNIFIED IDEOGRAPH
+0xF576 0x9C09 #CJK UNIFIED IDEOGRAPH
+0xF577 0x9D9F #CJK UNIFIED IDEOGRAPH
+0xF578 0x9D99 #CJK UNIFIED IDEOGRAPH
+0xF579 0x9DA4 #CJK UNIFIED IDEOGRAPH
+0xF57A 0x9D9D #CJK UNIFIED IDEOGRAPH
+0xF57B 0x9D92 #CJK UNIFIED IDEOGRAPH
+0xF57C 0x9D98 #CJK UNIFIED IDEOGRAPH
+0xF57D 0x9D90 #CJK UNIFIED IDEOGRAPH
+0xF57E 0x9D9B #CJK UNIFIED IDEOGRAPH
+0xF5A1 0x9DA0 #CJK UNIFIED IDEOGRAPH
+0xF5A2 0x9D94 #CJK UNIFIED IDEOGRAPH
+0xF5A3 0x9D9C #CJK UNIFIED IDEOGRAPH
+0xF5A4 0x9DAA #CJK UNIFIED IDEOGRAPH
+0xF5A5 0x9D97 #CJK UNIFIED IDEOGRAPH
+0xF5A6 0x9DA1 #CJK UNIFIED IDEOGRAPH
+0xF5A7 0x9D9A #CJK UNIFIED IDEOGRAPH
+0xF5A8 0x9DA2 #CJK UNIFIED IDEOGRAPH
+0xF5A9 0x9DA8 #CJK UNIFIED IDEOGRAPH
+0xF5AA 0x9D9E #CJK UNIFIED IDEOGRAPH
+0xF5AB 0x9DA3 #CJK UNIFIED IDEOGRAPH
+0xF5AC 0x9DBF #CJK UNIFIED IDEOGRAPH
+0xF5AD 0x9DA9 #CJK UNIFIED IDEOGRAPH
+0xF5AE 0x9D96 #CJK UNIFIED IDEOGRAPH
+0xF5AF 0x9DA6 #CJK UNIFIED IDEOGRAPH
+0xF5B0 0x9DA7 #CJK UNIFIED IDEOGRAPH
+0xF5B1 0x9E99 #CJK UNIFIED IDEOGRAPH
+0xF5B2 0x9E9B #CJK UNIFIED IDEOGRAPH
+0xF5B3 0x9E9A #CJK UNIFIED IDEOGRAPH
+0xF5B4 0x9EE5 #CJK UNIFIED IDEOGRAPH
+0xF5B5 0x9EE4 #CJK UNIFIED IDEOGRAPH
+0xF5B6 0x9EE7 #CJK UNIFIED IDEOGRAPH
+0xF5B7 0x9EE6 #CJK UNIFIED IDEOGRAPH
+0xF5B8 0x9F30 #CJK UNIFIED IDEOGRAPH
+0xF5B9 0x9F2E #CJK UNIFIED IDEOGRAPH
+0xF5BA 0x9F5B #CJK UNIFIED IDEOGRAPH
+0xF5BB 0x9F60 #CJK UNIFIED IDEOGRAPH
+0xF5BC 0x9F5E #CJK UNIFIED IDEOGRAPH
+0xF5BD 0x9F5D #CJK UNIFIED IDEOGRAPH
+0xF5BE 0x9F59 #CJK UNIFIED IDEOGRAPH
+0xF5BF 0x9F91 #CJK UNIFIED IDEOGRAPH
+0xF5C0 0x513A #CJK UNIFIED IDEOGRAPH
+0xF5C1 0x5139 #CJK UNIFIED IDEOGRAPH
+0xF5C2 0x5298 #CJK UNIFIED IDEOGRAPH
+0xF5C3 0x5297 #CJK UNIFIED IDEOGRAPH
+0xF5C4 0x56C3 #CJK UNIFIED IDEOGRAPH
+0xF5C5 0x56BD #CJK UNIFIED IDEOGRAPH
+0xF5C6 0x56BE #CJK UNIFIED IDEOGRAPH
+0xF5C7 0x5B48 #CJK UNIFIED IDEOGRAPH
+0xF5C8 0x5B47 #CJK UNIFIED IDEOGRAPH
+0xF5C9 0x5DCB #CJK UNIFIED IDEOGRAPH
+0xF5CA 0x5DCF #CJK UNIFIED IDEOGRAPH
+0xF5CB 0x5EF1 #CJK UNIFIED IDEOGRAPH
+0xF5CC 0x61FD #CJK UNIFIED IDEOGRAPH
+0xF5CD 0x651B #CJK UNIFIED IDEOGRAPH
+0xF5CE 0x6B02 #CJK UNIFIED IDEOGRAPH
+0xF5CF 0x6AFC #CJK UNIFIED IDEOGRAPH
+0xF5D0 0x6B03 #CJK UNIFIED IDEOGRAPH
+0xF5D1 0x6AF8 #CJK UNIFIED IDEOGRAPH
+0xF5D2 0x6B00 #CJK UNIFIED IDEOGRAPH
+0xF5D3 0x7043 #CJK UNIFIED IDEOGRAPH
+0xF5D4 0x7044 #CJK UNIFIED IDEOGRAPH
+0xF5D5 0x704A #CJK UNIFIED IDEOGRAPH
+0xF5D6 0x7048 #CJK UNIFIED IDEOGRAPH
+0xF5D7 0x7049 #CJK UNIFIED IDEOGRAPH
+0xF5D8 0x7045 #CJK UNIFIED IDEOGRAPH
+0xF5D9 0x7046 #CJK UNIFIED IDEOGRAPH
+0xF5DA 0x721D #CJK UNIFIED IDEOGRAPH
+0xF5DB 0x721A #CJK UNIFIED IDEOGRAPH
+0xF5DC 0x7219 #CJK UNIFIED IDEOGRAPH
+0xF5DD 0x737E #CJK UNIFIED IDEOGRAPH
+0xF5DE 0x7517 #CJK UNIFIED IDEOGRAPH
+0xF5DF 0x766A #CJK UNIFIED IDEOGRAPH
+0xF5E0 0x77D0 #CJK UNIFIED IDEOGRAPH
+0xF5E1 0x792D #CJK UNIFIED IDEOGRAPH
+0xF5E2 0x7931 #CJK UNIFIED IDEOGRAPH
+0xF5E3 0x792F #CJK UNIFIED IDEOGRAPH
+0xF5E4 0x7C54 #CJK UNIFIED IDEOGRAPH
+0xF5E5 0x7C53 #CJK UNIFIED IDEOGRAPH
+0xF5E6 0x7CF2 #CJK UNIFIED IDEOGRAPH
+0xF5E7 0x7E8A #CJK UNIFIED IDEOGRAPH
+0xF5E8 0x7E87 #CJK UNIFIED IDEOGRAPH
+0xF5E9 0x7E88 #CJK UNIFIED IDEOGRAPH
+0xF5EA 0x7E8B #CJK UNIFIED IDEOGRAPH
+0xF5EB 0x7E86 #CJK UNIFIED IDEOGRAPH
+0xF5EC 0x7E8D #CJK UNIFIED IDEOGRAPH
+0xF5ED 0x7F4D #CJK UNIFIED IDEOGRAPH
+0xF5EE 0x7FBB #CJK UNIFIED IDEOGRAPH
+0xF5EF 0x8030 #CJK UNIFIED IDEOGRAPH
+0xF5F0 0x81DD #CJK UNIFIED IDEOGRAPH
+0xF5F1 0x8618 #CJK UNIFIED IDEOGRAPH
+0xF5F2 0x862A #CJK UNIFIED IDEOGRAPH
+0xF5F3 0x8626 #CJK UNIFIED IDEOGRAPH
+0xF5F4 0x861F #CJK UNIFIED IDEOGRAPH
+0xF5F5 0x8623 #CJK UNIFIED IDEOGRAPH
+0xF5F6 0x861C #CJK UNIFIED IDEOGRAPH
+0xF5F7 0x8619 #CJK UNIFIED IDEOGRAPH
+0xF5F8 0x8627 #CJK UNIFIED IDEOGRAPH
+0xF5F9 0x862E #CJK UNIFIED IDEOGRAPH
+0xF5FA 0x8621 #CJK UNIFIED IDEOGRAPH
+0xF5FB 0x8620 #CJK UNIFIED IDEOGRAPH
+0xF5FC 0x8629 #CJK UNIFIED IDEOGRAPH
+0xF5FD 0x861E #CJK UNIFIED IDEOGRAPH
+0xF5FE 0x8625 #CJK UNIFIED IDEOGRAPH
+0xF640 0x8829 #CJK UNIFIED IDEOGRAPH
+0xF641 0x881D #CJK UNIFIED IDEOGRAPH
+0xF642 0x881B #CJK UNIFIED IDEOGRAPH
+0xF643 0x8820 #CJK UNIFIED IDEOGRAPH
+0xF644 0x8824 #CJK UNIFIED IDEOGRAPH
+0xF645 0x881C #CJK UNIFIED IDEOGRAPH
+0xF646 0x882B #CJK UNIFIED IDEOGRAPH
+0xF647 0x884A #CJK UNIFIED IDEOGRAPH
+0xF648 0x896D #CJK UNIFIED IDEOGRAPH
+0xF649 0x8969 #CJK UNIFIED IDEOGRAPH
+0xF64A 0x896E #CJK UNIFIED IDEOGRAPH
+0xF64B 0x896B #CJK UNIFIED IDEOGRAPH
+0xF64C 0x89FA #CJK UNIFIED IDEOGRAPH
+0xF64D 0x8B79 #CJK UNIFIED IDEOGRAPH
+0xF64E 0x8B78 #CJK UNIFIED IDEOGRAPH
+0xF64F 0x8B45 #CJK UNIFIED IDEOGRAPH
+0xF650 0x8B7A #CJK UNIFIED IDEOGRAPH
+0xF651 0x8B7B #CJK UNIFIED IDEOGRAPH
+0xF652 0x8D10 #CJK UNIFIED IDEOGRAPH
+0xF653 0x8D14 #CJK UNIFIED IDEOGRAPH
+0xF654 0x8DAF #CJK UNIFIED IDEOGRAPH
+0xF655 0x8E8E #CJK UNIFIED IDEOGRAPH
+0xF656 0x8E8C #CJK UNIFIED IDEOGRAPH
+0xF657 0x8F5E #CJK UNIFIED IDEOGRAPH
+0xF658 0x8F5B #CJK UNIFIED IDEOGRAPH
+0xF659 0x8F5D #CJK UNIFIED IDEOGRAPH
+0xF65A 0x9146 #CJK UNIFIED IDEOGRAPH
+0xF65B 0x9144 #CJK UNIFIED IDEOGRAPH
+0xF65C 0x9145 #CJK UNIFIED IDEOGRAPH
+0xF65D 0x91B9 #CJK UNIFIED IDEOGRAPH
+0xF65E 0x943F #CJK UNIFIED IDEOGRAPH
+0xF65F 0x943B #CJK UNIFIED IDEOGRAPH
+0xF660 0x9436 #CJK UNIFIED IDEOGRAPH
+0xF661 0x9429 #CJK UNIFIED IDEOGRAPH
+0xF662 0x943D #CJK UNIFIED IDEOGRAPH
+0xF663 0x943C #CJK UNIFIED IDEOGRAPH
+0xF664 0x9430 #CJK UNIFIED IDEOGRAPH
+0xF665 0x9439 #CJK UNIFIED IDEOGRAPH
+0xF666 0x942A #CJK UNIFIED IDEOGRAPH
+0xF667 0x9437 #CJK UNIFIED IDEOGRAPH
+0xF668 0x942C #CJK UNIFIED IDEOGRAPH
+0xF669 0x9440 #CJK UNIFIED IDEOGRAPH
+0xF66A 0x9431 #CJK UNIFIED IDEOGRAPH
+0xF66B 0x95E5 #CJK UNIFIED IDEOGRAPH
+0xF66C 0x95E4 #CJK UNIFIED IDEOGRAPH
+0xF66D 0x95E3 #CJK UNIFIED IDEOGRAPH
+0xF66E 0x9735 #CJK UNIFIED IDEOGRAPH
+0xF66F 0x973A #CJK UNIFIED IDEOGRAPH
+0xF670 0x97BF #CJK UNIFIED IDEOGRAPH
+0xF671 0x97E1 #CJK UNIFIED IDEOGRAPH
+0xF672 0x9864 #CJK UNIFIED IDEOGRAPH
+0xF673 0x98C9 #CJK UNIFIED IDEOGRAPH
+0xF674 0x98C6 #CJK UNIFIED IDEOGRAPH
+0xF675 0x98C0 #CJK UNIFIED IDEOGRAPH
+0xF676 0x9958 #CJK UNIFIED IDEOGRAPH
+0xF677 0x9956 #CJK UNIFIED IDEOGRAPH
+0xF678 0x9A39 #CJK UNIFIED IDEOGRAPH
+0xF679 0x9A3D #CJK UNIFIED IDEOGRAPH
+0xF67A 0x9A46 #CJK UNIFIED IDEOGRAPH
+0xF67B 0x9A44 #CJK UNIFIED IDEOGRAPH
+0xF67C 0x9A42 #CJK UNIFIED IDEOGRAPH
+0xF67D 0x9A41 #CJK UNIFIED IDEOGRAPH
+0xF67E 0x9A3A #CJK UNIFIED IDEOGRAPH
+0xF6A1 0x9A3F #CJK UNIFIED IDEOGRAPH
+0xF6A2 0x9ACD #CJK UNIFIED IDEOGRAPH
+0xF6A3 0x9B15 #CJK UNIFIED IDEOGRAPH
+0xF6A4 0x9B17 #CJK UNIFIED IDEOGRAPH
+0xF6A5 0x9B18 #CJK UNIFIED IDEOGRAPH
+0xF6A6 0x9B16 #CJK UNIFIED IDEOGRAPH
+0xF6A7 0x9B3A #CJK UNIFIED IDEOGRAPH
+0xF6A8 0x9B52 #CJK UNIFIED IDEOGRAPH
+0xF6A9 0x9C2B #CJK UNIFIED IDEOGRAPH
+0xF6AA 0x9C1D #CJK UNIFIED IDEOGRAPH
+0xF6AB 0x9C1C #CJK UNIFIED IDEOGRAPH
+0xF6AC 0x9C2C #CJK UNIFIED IDEOGRAPH
+0xF6AD 0x9C23 #CJK UNIFIED IDEOGRAPH
+0xF6AE 0x9C28 #CJK UNIFIED IDEOGRAPH
+0xF6AF 0x9C29 #CJK UNIFIED IDEOGRAPH
+0xF6B0 0x9C24 #CJK UNIFIED IDEOGRAPH
+0xF6B1 0x9C21 #CJK UNIFIED IDEOGRAPH
+0xF6B2 0x9DB7 #CJK UNIFIED IDEOGRAPH
+0xF6B3 0x9DB6 #CJK UNIFIED IDEOGRAPH
+0xF6B4 0x9DBC #CJK UNIFIED IDEOGRAPH
+0xF6B5 0x9DC1 #CJK UNIFIED IDEOGRAPH
+0xF6B6 0x9DC7 #CJK UNIFIED IDEOGRAPH
+0xF6B7 0x9DCA #CJK UNIFIED IDEOGRAPH
+0xF6B8 0x9DCF #CJK UNIFIED IDEOGRAPH
+0xF6B9 0x9DBE #CJK UNIFIED IDEOGRAPH
+0xF6BA 0x9DC5 #CJK UNIFIED IDEOGRAPH
+0xF6BB 0x9DC3 #CJK UNIFIED IDEOGRAPH
+0xF6BC 0x9DBB #CJK UNIFIED IDEOGRAPH
+0xF6BD 0x9DB5 #CJK UNIFIED IDEOGRAPH
+0xF6BE 0x9DCE #CJK UNIFIED IDEOGRAPH
+0xF6BF 0x9DB9 #CJK UNIFIED IDEOGRAPH
+0xF6C0 0x9DBA #CJK UNIFIED IDEOGRAPH
+0xF6C1 0x9DAC #CJK UNIFIED IDEOGRAPH
+0xF6C2 0x9DC8 #CJK UNIFIED IDEOGRAPH
+0xF6C3 0x9DB1 #CJK UNIFIED IDEOGRAPH
+0xF6C4 0x9DAD #CJK UNIFIED IDEOGRAPH
+0xF6C5 0x9DCC #CJK UNIFIED IDEOGRAPH
+0xF6C6 0x9DB3 #CJK UNIFIED IDEOGRAPH
+0xF6C7 0x9DCD #CJK UNIFIED IDEOGRAPH
+0xF6C8 0x9DB2 #CJK UNIFIED IDEOGRAPH
+0xF6C9 0x9E7A #CJK UNIFIED IDEOGRAPH
+0xF6CA 0x9E9C #CJK UNIFIED IDEOGRAPH
+0xF6CB 0x9EEB #CJK UNIFIED IDEOGRAPH
+0xF6CC 0x9EEE #CJK UNIFIED IDEOGRAPH
+0xF6CD 0x9EED #CJK UNIFIED IDEOGRAPH
+0xF6CE 0x9F1B #CJK UNIFIED IDEOGRAPH
+0xF6CF 0x9F18 #CJK UNIFIED IDEOGRAPH
+0xF6D0 0x9F1A #CJK UNIFIED IDEOGRAPH
+0xF6D1 0x9F31 #CJK UNIFIED IDEOGRAPH
+0xF6D2 0x9F4E #CJK UNIFIED IDEOGRAPH
+0xF6D3 0x9F65 #CJK UNIFIED IDEOGRAPH
+0xF6D4 0x9F64 #CJK UNIFIED IDEOGRAPH
+0xF6D5 0x9F92 #CJK UNIFIED IDEOGRAPH
+0xF6D6 0x4EB9 #CJK UNIFIED IDEOGRAPH
+0xF6D7 0x56C6 #CJK UNIFIED IDEOGRAPH
+0xF6D8 0x56C5 #CJK UNIFIED IDEOGRAPH
+0xF6D9 0x56CB #CJK UNIFIED IDEOGRAPH
+0xF6DA 0x5971 #CJK UNIFIED IDEOGRAPH
+0xF6DB 0x5B4B #CJK UNIFIED IDEOGRAPH
+0xF6DC 0x5B4C #CJK UNIFIED IDEOGRAPH
+0xF6DD 0x5DD5 #CJK UNIFIED IDEOGRAPH
+0xF6DE 0x5DD1 #CJK UNIFIED IDEOGRAPH
+0xF6DF 0x5EF2 #CJK UNIFIED IDEOGRAPH
+0xF6E0 0x6521 #CJK UNIFIED IDEOGRAPH
+0xF6E1 0x6520 #CJK UNIFIED IDEOGRAPH
+0xF6E2 0x6526 #CJK UNIFIED IDEOGRAPH
+0xF6E3 0x6522 #CJK UNIFIED IDEOGRAPH
+0xF6E4 0x6B0B #CJK UNIFIED IDEOGRAPH
+0xF6E5 0x6B08 #CJK UNIFIED IDEOGRAPH
+0xF6E6 0x6B09 #CJK UNIFIED IDEOGRAPH
+0xF6E7 0x6C0D #CJK UNIFIED IDEOGRAPH
+0xF6E8 0x7055 #CJK UNIFIED IDEOGRAPH
+0xF6E9 0x7056 #CJK UNIFIED IDEOGRAPH
+0xF6EA 0x7057 #CJK UNIFIED IDEOGRAPH
+0xF6EB 0x7052 #CJK UNIFIED IDEOGRAPH
+0xF6EC 0x721E #CJK UNIFIED IDEOGRAPH
+0xF6ED 0x721F #CJK UNIFIED IDEOGRAPH
+0xF6EE 0x72A9 #CJK UNIFIED IDEOGRAPH
+0xF6EF 0x737F #CJK UNIFIED IDEOGRAPH
+0xF6F0 0x74D8 #CJK UNIFIED IDEOGRAPH
+0xF6F1 0x74D5 #CJK UNIFIED IDEOGRAPH
+0xF6F2 0x74D9 #CJK UNIFIED IDEOGRAPH
+0xF6F3 0x74D7 #CJK UNIFIED IDEOGRAPH
+0xF6F4 0x766D #CJK UNIFIED IDEOGRAPH
+0xF6F5 0x76AD #CJK UNIFIED IDEOGRAPH
+0xF6F6 0x7935 #CJK UNIFIED IDEOGRAPH
+0xF6F7 0x79B4 #CJK UNIFIED IDEOGRAPH
+0xF6F8 0x7A70 #CJK UNIFIED IDEOGRAPH
+0xF6F9 0x7A71 #CJK UNIFIED IDEOGRAPH
+0xF6FA 0x7C57 #CJK UNIFIED IDEOGRAPH
+0xF6FB 0x7C5C #CJK UNIFIED IDEOGRAPH
+0xF6FC 0x7C59 #CJK UNIFIED IDEOGRAPH
+0xF6FD 0x7C5B #CJK UNIFIED IDEOGRAPH
+0xF6FE 0x7C5A #CJK UNIFIED IDEOGRAPH
+0xF740 0x7CF4 #CJK UNIFIED IDEOGRAPH
+0xF741 0x7CF1 #CJK UNIFIED IDEOGRAPH
+0xF742 0x7E91 #CJK UNIFIED IDEOGRAPH
+0xF743 0x7F4F #CJK UNIFIED IDEOGRAPH
+0xF744 0x7F87 #CJK UNIFIED IDEOGRAPH
+0xF745 0x81DE #CJK UNIFIED IDEOGRAPH
+0xF746 0x826B #CJK UNIFIED IDEOGRAPH
+0xF747 0x8634 #CJK UNIFIED IDEOGRAPH
+0xF748 0x8635 #CJK UNIFIED IDEOGRAPH
+0xF749 0x8633 #CJK UNIFIED IDEOGRAPH
+0xF74A 0x862C #CJK UNIFIED IDEOGRAPH
+0xF74B 0x8632 #CJK UNIFIED IDEOGRAPH
+0xF74C 0x8636 #CJK UNIFIED IDEOGRAPH
+0xF74D 0x882C #CJK UNIFIED IDEOGRAPH
+0xF74E 0x8828 #CJK UNIFIED IDEOGRAPH
+0xF74F 0x8826 #CJK UNIFIED IDEOGRAPH
+0xF750 0x882A #CJK UNIFIED IDEOGRAPH
+0xF751 0x8825 #CJK UNIFIED IDEOGRAPH
+0xF752 0x8971 #CJK UNIFIED IDEOGRAPH
+0xF753 0x89BF #CJK UNIFIED IDEOGRAPH
+0xF754 0x89BE #CJK UNIFIED IDEOGRAPH
+0xF755 0x89FB #CJK UNIFIED IDEOGRAPH
+0xF756 0x8B7E #CJK UNIFIED IDEOGRAPH
+0xF757 0x8B84 #CJK UNIFIED IDEOGRAPH
+0xF758 0x8B82 #CJK UNIFIED IDEOGRAPH
+0xF759 0x8B86 #CJK UNIFIED IDEOGRAPH
+0xF75A 0x8B85 #CJK UNIFIED IDEOGRAPH
+0xF75B 0x8B7F #CJK UNIFIED IDEOGRAPH
+0xF75C 0x8D15 #CJK UNIFIED IDEOGRAPH
+0xF75D 0x8E95 #CJK UNIFIED IDEOGRAPH
+0xF75E 0x8E94 #CJK UNIFIED IDEOGRAPH
+0xF75F 0x8E9A #CJK UNIFIED IDEOGRAPH
+0xF760 0x8E92 #CJK UNIFIED IDEOGRAPH
+0xF761 0x8E90 #CJK UNIFIED IDEOGRAPH
+0xF762 0x8E96 #CJK UNIFIED IDEOGRAPH
+0xF763 0x8E97 #CJK UNIFIED IDEOGRAPH
+0xF764 0x8F60 #CJK UNIFIED IDEOGRAPH
+0xF765 0x8F62 #CJK UNIFIED IDEOGRAPH
+0xF766 0x9147 #CJK UNIFIED IDEOGRAPH
+0xF767 0x944C #CJK UNIFIED IDEOGRAPH
+0xF768 0x9450 #CJK UNIFIED IDEOGRAPH
+0xF769 0x944A #CJK UNIFIED IDEOGRAPH
+0xF76A 0x944B #CJK UNIFIED IDEOGRAPH
+0xF76B 0x944F #CJK UNIFIED IDEOGRAPH
+0xF76C 0x9447 #CJK UNIFIED IDEOGRAPH
+0xF76D 0x9445 #CJK UNIFIED IDEOGRAPH
+0xF76E 0x9448 #CJK UNIFIED IDEOGRAPH
+0xF76F 0x9449 #CJK UNIFIED IDEOGRAPH
+0xF770 0x9446 #CJK UNIFIED IDEOGRAPH
+0xF771 0x973F #CJK UNIFIED IDEOGRAPH
+0xF772 0x97E3 #CJK UNIFIED IDEOGRAPH
+0xF773 0x986A #CJK UNIFIED IDEOGRAPH
+0xF774 0x9869 #CJK UNIFIED IDEOGRAPH
+0xF775 0x98CB #CJK UNIFIED IDEOGRAPH
+0xF776 0x9954 #CJK UNIFIED IDEOGRAPH
+0xF777 0x995B #CJK UNIFIED IDEOGRAPH
+0xF778 0x9A4E #CJK UNIFIED IDEOGRAPH
+0xF779 0x9A53 #CJK UNIFIED IDEOGRAPH
+0xF77A 0x9A54 #CJK UNIFIED IDEOGRAPH
+0xF77B 0x9A4C #CJK UNIFIED IDEOGRAPH
+0xF77C 0x9A4F #CJK UNIFIED IDEOGRAPH
+0xF77D 0x9A48 #CJK UNIFIED IDEOGRAPH
+0xF77E 0x9A4A #CJK UNIFIED IDEOGRAPH
+0xF7A1 0x9A49 #CJK UNIFIED IDEOGRAPH
+0xF7A2 0x9A52 #CJK UNIFIED IDEOGRAPH
+0xF7A3 0x9A50 #CJK UNIFIED IDEOGRAPH
+0xF7A4 0x9AD0 #CJK UNIFIED IDEOGRAPH
+0xF7A5 0x9B19 #CJK UNIFIED IDEOGRAPH
+0xF7A6 0x9B2B #CJK UNIFIED IDEOGRAPH
+0xF7A7 0x9B3B #CJK UNIFIED IDEOGRAPH
+0xF7A8 0x9B56 #CJK UNIFIED IDEOGRAPH
+0xF7A9 0x9B55 #CJK UNIFIED IDEOGRAPH
+0xF7AA 0x9C46 #CJK UNIFIED IDEOGRAPH
+0xF7AB 0x9C48 #CJK UNIFIED IDEOGRAPH
+0xF7AC 0x9C3F #CJK UNIFIED IDEOGRAPH
+0xF7AD 0x9C44 #CJK UNIFIED IDEOGRAPH
+0xF7AE 0x9C39 #CJK UNIFIED IDEOGRAPH
+0xF7AF 0x9C33 #CJK UNIFIED IDEOGRAPH
+0xF7B0 0x9C41 #CJK UNIFIED IDEOGRAPH
+0xF7B1 0x9C3C #CJK UNIFIED IDEOGRAPH
+0xF7B2 0x9C37 #CJK UNIFIED IDEOGRAPH
+0xF7B3 0x9C34 #CJK UNIFIED IDEOGRAPH
+0xF7B4 0x9C32 #CJK UNIFIED IDEOGRAPH
+0xF7B5 0x9C3D #CJK UNIFIED IDEOGRAPH
+0xF7B6 0x9C36 #CJK UNIFIED IDEOGRAPH
+0xF7B7 0x9DDB #CJK UNIFIED IDEOGRAPH
+0xF7B8 0x9DD2 #CJK UNIFIED IDEOGRAPH
+0xF7B9 0x9DDE #CJK UNIFIED IDEOGRAPH
+0xF7BA 0x9DDA #CJK UNIFIED IDEOGRAPH
+0xF7BB 0x9DCB #CJK UNIFIED IDEOGRAPH
+0xF7BC 0x9DD0 #CJK UNIFIED IDEOGRAPH
+0xF7BD 0x9DDC #CJK UNIFIED IDEOGRAPH
+0xF7BE 0x9DD1 #CJK UNIFIED IDEOGRAPH
+0xF7BF 0x9DDF #CJK UNIFIED IDEOGRAPH
+0xF7C0 0x9DE9 #CJK UNIFIED IDEOGRAPH
+0xF7C1 0x9DD9 #CJK UNIFIED IDEOGRAPH
+0xF7C2 0x9DD8 #CJK UNIFIED IDEOGRAPH
+0xF7C3 0x9DD6 #CJK UNIFIED IDEOGRAPH
+0xF7C4 0x9DF5 #CJK UNIFIED IDEOGRAPH
+0xF7C5 0x9DD5 #CJK UNIFIED IDEOGRAPH
+0xF7C6 0x9DDD #CJK UNIFIED IDEOGRAPH
+0xF7C7 0x9EB6 #CJK UNIFIED IDEOGRAPH
+0xF7C8 0x9EF0 #CJK UNIFIED IDEOGRAPH
+0xF7C9 0x9F35 #CJK UNIFIED IDEOGRAPH
+0xF7CA 0x9F33 #CJK UNIFIED IDEOGRAPH
+0xF7CB 0x9F32 #CJK UNIFIED IDEOGRAPH
+0xF7CC 0x9F42 #CJK UNIFIED IDEOGRAPH
+0xF7CD 0x9F6B #CJK UNIFIED IDEOGRAPH
+0xF7CE 0x9F95 #CJK UNIFIED IDEOGRAPH
+0xF7CF 0x9FA2 #CJK UNIFIED IDEOGRAPH
+0xF7D0 0x513D #CJK UNIFIED IDEOGRAPH
+0xF7D1 0x5299 #CJK UNIFIED IDEOGRAPH
+0xF7D2 0x58E8 #CJK UNIFIED IDEOGRAPH
+0xF7D3 0x58E7 #CJK UNIFIED IDEOGRAPH
+0xF7D4 0x5972 #CJK UNIFIED IDEOGRAPH
+0xF7D5 0x5B4D #CJK UNIFIED IDEOGRAPH
+0xF7D6 0x5DD8 #CJK UNIFIED IDEOGRAPH
+0xF7D7 0x882F #CJK UNIFIED IDEOGRAPH
+0xF7D8 0x5F4F #CJK UNIFIED IDEOGRAPH
+0xF7D9 0x6201 #CJK UNIFIED IDEOGRAPH
+0xF7DA 0x6203 #CJK UNIFIED IDEOGRAPH
+0xF7DB 0x6204 #CJK UNIFIED IDEOGRAPH
+0xF7DC 0x6529 #CJK UNIFIED IDEOGRAPH
+0xF7DD 0x6525 #CJK UNIFIED IDEOGRAPH
+0xF7DE 0x6596 #CJK UNIFIED IDEOGRAPH
+0xF7DF 0x66EB #CJK UNIFIED IDEOGRAPH
+0xF7E0 0x6B11 #CJK UNIFIED IDEOGRAPH
+0xF7E1 0x6B12 #CJK UNIFIED IDEOGRAPH
+0xF7E2 0x6B0F #CJK UNIFIED IDEOGRAPH
+0xF7E3 0x6BCA #CJK UNIFIED IDEOGRAPH
+0xF7E4 0x705B #CJK UNIFIED IDEOGRAPH
+0xF7E5 0x705A #CJK UNIFIED IDEOGRAPH
+0xF7E6 0x7222 #CJK UNIFIED IDEOGRAPH
+0xF7E7 0x7382 #CJK UNIFIED IDEOGRAPH
+0xF7E8 0x7381 #CJK UNIFIED IDEOGRAPH
+0xF7E9 0x7383 #CJK UNIFIED IDEOGRAPH
+0xF7EA 0x7670 #CJK UNIFIED IDEOGRAPH
+0xF7EB 0x77D4 #CJK UNIFIED IDEOGRAPH
+0xF7EC 0x7C67 #CJK UNIFIED IDEOGRAPH
+0xF7ED 0x7C66 #CJK UNIFIED IDEOGRAPH
+0xF7EE 0x7E95 #CJK UNIFIED IDEOGRAPH
+0xF7EF 0x826C #CJK UNIFIED IDEOGRAPH
+0xF7F0 0x863A #CJK UNIFIED IDEOGRAPH
+0xF7F1 0x8640 #CJK UNIFIED IDEOGRAPH
+0xF7F2 0x8639 #CJK UNIFIED IDEOGRAPH
+0xF7F3 0x863C #CJK UNIFIED IDEOGRAPH
+0xF7F4 0x8631 #CJK UNIFIED IDEOGRAPH
+0xF7F5 0x863B #CJK UNIFIED IDEOGRAPH
+0xF7F6 0x863E #CJK UNIFIED IDEOGRAPH
+0xF7F7 0x8830 #CJK UNIFIED IDEOGRAPH
+0xF7F8 0x8832 #CJK UNIFIED IDEOGRAPH
+0xF7F9 0x882E #CJK UNIFIED IDEOGRAPH
+0xF7FA 0x8833 #CJK UNIFIED IDEOGRAPH
+0xF7FB 0x8976 #CJK UNIFIED IDEOGRAPH
+0xF7FC 0x8974 #CJK UNIFIED IDEOGRAPH
+0xF7FD 0x8973 #CJK UNIFIED IDEOGRAPH
+0xF7FE 0x89FE #CJK UNIFIED IDEOGRAPH
+0xF840 0x8B8C #CJK UNIFIED IDEOGRAPH
+0xF841 0x8B8E #CJK UNIFIED IDEOGRAPH
+0xF842 0x8B8B #CJK UNIFIED IDEOGRAPH
+0xF843 0x8B88 #CJK UNIFIED IDEOGRAPH
+0xF844 0x8C45 #CJK UNIFIED IDEOGRAPH
+0xF845 0x8D19 #CJK UNIFIED IDEOGRAPH
+0xF846 0x8E98 #CJK UNIFIED IDEOGRAPH
+0xF847 0x8F64 #CJK UNIFIED IDEOGRAPH
+0xF848 0x8F63 #CJK UNIFIED IDEOGRAPH
+0xF849 0x91BC #CJK UNIFIED IDEOGRAPH
+0xF84A 0x9462 #CJK UNIFIED IDEOGRAPH
+0xF84B 0x9455 #CJK UNIFIED IDEOGRAPH
+0xF84C 0x945D #CJK UNIFIED IDEOGRAPH
+0xF84D 0x9457 #CJK UNIFIED IDEOGRAPH
+0xF84E 0x945E #CJK UNIFIED IDEOGRAPH
+0xF84F 0x97C4 #CJK UNIFIED IDEOGRAPH
+0xF850 0x97C5 #CJK UNIFIED IDEOGRAPH
+0xF851 0x9800 #CJK UNIFIED IDEOGRAPH
+0xF852 0x9A56 #CJK UNIFIED IDEOGRAPH
+0xF853 0x9A59 #CJK UNIFIED IDEOGRAPH
+0xF854 0x9B1E #CJK UNIFIED IDEOGRAPH
+0xF855 0x9B1F #CJK UNIFIED IDEOGRAPH
+0xF856 0x9B20 #CJK UNIFIED IDEOGRAPH
+0xF857 0x9C52 #CJK UNIFIED IDEOGRAPH
+0xF858 0x9C58 #CJK UNIFIED IDEOGRAPH
+0xF859 0x9C50 #CJK UNIFIED IDEOGRAPH
+0xF85A 0x9C4A #CJK UNIFIED IDEOGRAPH
+0xF85B 0x9C4D #CJK UNIFIED IDEOGRAPH
+0xF85C 0x9C4B #CJK UNIFIED IDEOGRAPH
+0xF85D 0x9C55 #CJK UNIFIED IDEOGRAPH
+0xF85E 0x9C59 #CJK UNIFIED IDEOGRAPH
+0xF85F 0x9C4C #CJK UNIFIED IDEOGRAPH
+0xF860 0x9C4E #CJK UNIFIED IDEOGRAPH
+0xF861 0x9DFB #CJK UNIFIED IDEOGRAPH
+0xF862 0x9DF7 #CJK UNIFIED IDEOGRAPH
+0xF863 0x9DEF #CJK UNIFIED IDEOGRAPH
+0xF864 0x9DE3 #CJK UNIFIED IDEOGRAPH
+0xF865 0x9DEB #CJK UNIFIED IDEOGRAPH
+0xF866 0x9DF8 #CJK UNIFIED IDEOGRAPH
+0xF867 0x9DE4 #CJK UNIFIED IDEOGRAPH
+0xF868 0x9DF6 #CJK UNIFIED IDEOGRAPH
+0xF869 0x9DE1 #CJK UNIFIED IDEOGRAPH
+0xF86A 0x9DEE #CJK UNIFIED IDEOGRAPH
+0xF86B 0x9DE6 #CJK UNIFIED IDEOGRAPH
+0xF86C 0x9DF2 #CJK UNIFIED IDEOGRAPH
+0xF86D 0x9DF0 #CJK UNIFIED IDEOGRAPH
+0xF86E 0x9DE2 #CJK UNIFIED IDEOGRAPH
+0xF86F 0x9DEC #CJK UNIFIED IDEOGRAPH
+0xF870 0x9DF4 #CJK UNIFIED IDEOGRAPH
+0xF871 0x9DF3 #CJK UNIFIED IDEOGRAPH
+0xF872 0x9DE8 #CJK UNIFIED IDEOGRAPH
+0xF873 0x9DED #CJK UNIFIED IDEOGRAPH
+0xF874 0x9EC2 #CJK UNIFIED IDEOGRAPH
+0xF875 0x9ED0 #CJK UNIFIED IDEOGRAPH
+0xF876 0x9EF2 #CJK UNIFIED IDEOGRAPH
+0xF877 0x9EF3 #CJK UNIFIED IDEOGRAPH
+0xF878 0x9F06 #CJK UNIFIED IDEOGRAPH
+0xF879 0x9F1C #CJK UNIFIED IDEOGRAPH
+0xF87A 0x9F38 #CJK UNIFIED IDEOGRAPH
+0xF87B 0x9F37 #CJK UNIFIED IDEOGRAPH
+0xF87C 0x9F36 #CJK UNIFIED IDEOGRAPH
+0xF87D 0x9F43 #CJK UNIFIED IDEOGRAPH
+0xF87E 0x9F4F #CJK UNIFIED IDEOGRAPH
+0xF8A1 0x9F71 #CJK UNIFIED IDEOGRAPH
+0xF8A2 0x9F70 #CJK UNIFIED IDEOGRAPH
+0xF8A3 0x9F6E #CJK UNIFIED IDEOGRAPH
+0xF8A4 0x9F6F #CJK UNIFIED IDEOGRAPH
+0xF8A5 0x56D3 #CJK UNIFIED IDEOGRAPH
+0xF8A6 0x56CD #CJK UNIFIED IDEOGRAPH
+0xF8A7 0x5B4E #CJK UNIFIED IDEOGRAPH
+0xF8A8 0x5C6D #CJK UNIFIED IDEOGRAPH
+0xF8A9 0x652D #CJK UNIFIED IDEOGRAPH
+0xF8AA 0x66ED #CJK UNIFIED IDEOGRAPH
+0xF8AB 0x66EE #CJK UNIFIED IDEOGRAPH
+0xF8AC 0x6B13 #CJK UNIFIED IDEOGRAPH
+0xF8AD 0x705F #CJK UNIFIED IDEOGRAPH
+0xF8AE 0x7061 #CJK UNIFIED IDEOGRAPH
+0xF8AF 0x705D #CJK UNIFIED IDEOGRAPH
+0xF8B0 0x7060 #CJK UNIFIED IDEOGRAPH
+0xF8B1 0x7223 #CJK UNIFIED IDEOGRAPH
+0xF8B2 0x74DB #CJK UNIFIED IDEOGRAPH
+0xF8B3 0x74E5 #CJK UNIFIED IDEOGRAPH
+0xF8B4 0x77D5 #CJK UNIFIED IDEOGRAPH
+0xF8B5 0x7938 #CJK UNIFIED IDEOGRAPH
+0xF8B6 0x79B7 #CJK UNIFIED IDEOGRAPH
+0xF8B7 0x79B6 #CJK UNIFIED IDEOGRAPH
+0xF8B8 0x7C6A #CJK UNIFIED IDEOGRAPH
+0xF8B9 0x7E97 #CJK UNIFIED IDEOGRAPH
+0xF8BA 0x7F89 #CJK UNIFIED IDEOGRAPH
+0xF8BB 0x826D #CJK UNIFIED IDEOGRAPH
+0xF8BC 0x8643 #CJK UNIFIED IDEOGRAPH
+0xF8BD 0x8838 #CJK UNIFIED IDEOGRAPH
+0xF8BE 0x8837 #CJK UNIFIED IDEOGRAPH
+0xF8BF 0x8835 #CJK UNIFIED IDEOGRAPH
+0xF8C0 0x884B #CJK UNIFIED IDEOGRAPH
+0xF8C1 0x8B94 #CJK UNIFIED IDEOGRAPH
+0xF8C2 0x8B95 #CJK UNIFIED IDEOGRAPH
+0xF8C3 0x8E9E #CJK UNIFIED IDEOGRAPH
+0xF8C4 0x8E9F #CJK UNIFIED IDEOGRAPH
+0xF8C5 0x8EA0 #CJK UNIFIED IDEOGRAPH
+0xF8C6 0x8E9D #CJK UNIFIED IDEOGRAPH
+0xF8C7 0x91BE #CJK UNIFIED IDEOGRAPH
+0xF8C8 0x91BD #CJK UNIFIED IDEOGRAPH
+0xF8C9 0x91C2 #CJK UNIFIED IDEOGRAPH
+0xF8CA 0x946B #CJK UNIFIED IDEOGRAPH
+0xF8CB 0x9468 #CJK UNIFIED IDEOGRAPH
+0xF8CC 0x9469 #CJK UNIFIED IDEOGRAPH
+0xF8CD 0x96E5 #CJK UNIFIED IDEOGRAPH
+0xF8CE 0x9746 #CJK UNIFIED IDEOGRAPH
+0xF8CF 0x9743 #CJK UNIFIED IDEOGRAPH
+0xF8D0 0x9747 #CJK UNIFIED IDEOGRAPH
+0xF8D1 0x97C7 #CJK UNIFIED IDEOGRAPH
+0xF8D2 0x97E5 #CJK UNIFIED IDEOGRAPH
+0xF8D3 0x9A5E #CJK UNIFIED IDEOGRAPH
+0xF8D4 0x9AD5 #CJK UNIFIED IDEOGRAPH
+0xF8D5 0x9B59 #CJK UNIFIED IDEOGRAPH
+0xF8D6 0x9C63 #CJK UNIFIED IDEOGRAPH
+0xF8D7 0x9C67 #CJK UNIFIED IDEOGRAPH
+0xF8D8 0x9C66 #CJK UNIFIED IDEOGRAPH
+0xF8D9 0x9C62 #CJK UNIFIED IDEOGRAPH
+0xF8DA 0x9C5E #CJK UNIFIED IDEOGRAPH
+0xF8DB 0x9C60 #CJK UNIFIED IDEOGRAPH
+0xF8DC 0x9E02 #CJK UNIFIED IDEOGRAPH
+0xF8DD 0x9DFE #CJK UNIFIED IDEOGRAPH
+0xF8DE 0x9E07 #CJK UNIFIED IDEOGRAPH
+0xF8DF 0x9E03 #CJK UNIFIED IDEOGRAPH
+0xF8E0 0x9E06 #CJK UNIFIED IDEOGRAPH
+0xF8E1 0x9E05 #CJK UNIFIED IDEOGRAPH
+0xF8E2 0x9E00 #CJK UNIFIED IDEOGRAPH
+0xF8E3 0x9E01 #CJK UNIFIED IDEOGRAPH
+0xF8E4 0x9E09 #CJK UNIFIED IDEOGRAPH
+0xF8E5 0x9DFF #CJK UNIFIED IDEOGRAPH
+0xF8E6 0x9DFD #CJK UNIFIED IDEOGRAPH
+0xF8E7 0x9E04 #CJK UNIFIED IDEOGRAPH
+0xF8E8 0x9EA0 #CJK UNIFIED IDEOGRAPH
+0xF8E9 0x9F1E #CJK UNIFIED IDEOGRAPH
+0xF8EA 0x9F46 #CJK UNIFIED IDEOGRAPH
+0xF8EB 0x9F74 #CJK UNIFIED IDEOGRAPH
+0xF8EC 0x9F75 #CJK UNIFIED IDEOGRAPH
+0xF8ED 0x9F76 #CJK UNIFIED IDEOGRAPH
+0xF8EE 0x56D4 #CJK UNIFIED IDEOGRAPH
+0xF8EF 0x652E #CJK UNIFIED IDEOGRAPH
+0xF8F0 0x65B8 #CJK UNIFIED IDEOGRAPH
+0xF8F1 0x6B18 #CJK UNIFIED IDEOGRAPH
+0xF8F2 0x6B19 #CJK UNIFIED IDEOGRAPH
+0xF8F3 0x6B17 #CJK UNIFIED IDEOGRAPH
+0xF8F4 0x6B1A #CJK UNIFIED IDEOGRAPH
+0xF8F5 0x7062 #CJK UNIFIED IDEOGRAPH
+0xF8F6 0x7226 #CJK UNIFIED IDEOGRAPH
+0xF8F7 0x72AA #CJK UNIFIED IDEOGRAPH
+0xF8F8 0x77D8 #CJK UNIFIED IDEOGRAPH
+0xF8F9 0x77D9 #CJK UNIFIED IDEOGRAPH
+0xF8FA 0x7939 #CJK UNIFIED IDEOGRAPH
+0xF8FB 0x7C69 #CJK UNIFIED IDEOGRAPH
+0xF8FC 0x7C6B #CJK UNIFIED IDEOGRAPH
+0xF8FD 0x7CF6 #CJK UNIFIED IDEOGRAPH
+0xF8FE 0x7E9A #CJK UNIFIED IDEOGRAPH
+0xF940 0x7E98 #CJK UNIFIED IDEOGRAPH
+0xF941 0x7E9B #CJK UNIFIED IDEOGRAPH
+0xF942 0x7E99 #CJK UNIFIED IDEOGRAPH
+0xF943 0x81E0 #CJK UNIFIED IDEOGRAPH
+0xF944 0x81E1 #CJK UNIFIED IDEOGRAPH
+0xF945 0x8646 #CJK UNIFIED IDEOGRAPH
+0xF946 0x8647 #CJK UNIFIED IDEOGRAPH
+0xF947 0x8648 #CJK UNIFIED IDEOGRAPH
+0xF948 0x8979 #CJK UNIFIED IDEOGRAPH
+0xF949 0x897A #CJK UNIFIED IDEOGRAPH
+0xF94A 0x897C #CJK UNIFIED IDEOGRAPH
+0xF94B 0x897B #CJK UNIFIED IDEOGRAPH
+0xF94C 0x89FF #CJK UNIFIED IDEOGRAPH
+0xF94D 0x8B98 #CJK UNIFIED IDEOGRAPH
+0xF94E 0x8B99 #CJK UNIFIED IDEOGRAPH
+0xF94F 0x8EA5 #CJK UNIFIED IDEOGRAPH
+0xF950 0x8EA4 #CJK UNIFIED IDEOGRAPH
+0xF951 0x8EA3 #CJK UNIFIED IDEOGRAPH
+0xF952 0x946E #CJK UNIFIED IDEOGRAPH
+0xF953 0x946D #CJK UNIFIED IDEOGRAPH
+0xF954 0x946F #CJK UNIFIED IDEOGRAPH
+0xF955 0x9471 #CJK UNIFIED IDEOGRAPH
+0xF956 0x9473 #CJK UNIFIED IDEOGRAPH
+0xF957 0x9749 #CJK UNIFIED IDEOGRAPH
+0xF958 0x9872 #CJK UNIFIED IDEOGRAPH
+0xF959 0x995F #CJK UNIFIED IDEOGRAPH
+0xF95A 0x9C68 #CJK UNIFIED IDEOGRAPH
+0xF95B 0x9C6E #CJK UNIFIED IDEOGRAPH
+0xF95C 0x9C6D #CJK UNIFIED IDEOGRAPH
+0xF95D 0x9E0B #CJK UNIFIED IDEOGRAPH
+0xF95E 0x9E0D #CJK UNIFIED IDEOGRAPH
+0xF95F 0x9E10 #CJK UNIFIED IDEOGRAPH
+0xF960 0x9E0F #CJK UNIFIED IDEOGRAPH
+0xF961 0x9E12 #CJK UNIFIED IDEOGRAPH
+0xF962 0x9E11 #CJK UNIFIED IDEOGRAPH
+0xF963 0x9EA1 #CJK UNIFIED IDEOGRAPH
+0xF964 0x9EF5 #CJK UNIFIED IDEOGRAPH
+0xF965 0x9F09 #CJK UNIFIED IDEOGRAPH
+0xF966 0x9F47 #CJK UNIFIED IDEOGRAPH
+0xF967 0x9F78 #CJK UNIFIED IDEOGRAPH
+0xF968 0x9F7B #CJK UNIFIED IDEOGRAPH
+0xF969 0x9F7A #CJK UNIFIED IDEOGRAPH
+0xF96A 0x9F79 #CJK UNIFIED IDEOGRAPH
+0xF96B 0x571E #CJK UNIFIED IDEOGRAPH
+0xF96C 0x7066 #CJK UNIFIED IDEOGRAPH
+0xF96D 0x7C6F #CJK UNIFIED IDEOGRAPH
+0xF96E 0x883C #CJK UNIFIED IDEOGRAPH
+0xF96F 0x8DB2 #CJK UNIFIED IDEOGRAPH
+0xF970 0x8EA6 #CJK UNIFIED IDEOGRAPH
+0xF971 0x91C3 #CJK UNIFIED IDEOGRAPH
+0xF972 0x9474 #CJK UNIFIED IDEOGRAPH
+0xF973 0x9478 #CJK UNIFIED IDEOGRAPH
+0xF974 0x9476 #CJK UNIFIED IDEOGRAPH
+0xF975 0x9475 #CJK UNIFIED IDEOGRAPH
+0xF976 0x9A60 #CJK UNIFIED IDEOGRAPH
+0xF977 0x9C74 #CJK UNIFIED IDEOGRAPH
+0xF978 0x9C73 #CJK UNIFIED IDEOGRAPH
+0xF979 0x9C71 #CJK UNIFIED IDEOGRAPH
+0xF97A 0x9C75 #CJK UNIFIED IDEOGRAPH
+0xF97B 0x9E14 #CJK UNIFIED IDEOGRAPH
+0xF97C 0x9E13 #CJK UNIFIED IDEOGRAPH
+0xF97D 0x9EF6 #CJK UNIFIED IDEOGRAPH
+0xF97E 0x9F0A #CJK UNIFIED IDEOGRAPH
+0xF9A1 0x9FA4 #CJK UNIFIED IDEOGRAPH
+0xF9A2 0x7068 #CJK UNIFIED IDEOGRAPH
+0xF9A3 0x7065 #CJK UNIFIED IDEOGRAPH
+0xF9A4 0x7CF7 #CJK UNIFIED IDEOGRAPH
+0xF9A5 0x866A #CJK UNIFIED IDEOGRAPH
+0xF9A6 0x883E #CJK UNIFIED IDEOGRAPH
+0xF9A7 0x883D #CJK UNIFIED IDEOGRAPH
+0xF9A8 0x883F #CJK UNIFIED IDEOGRAPH
+0xF9A9 0x8B9E #CJK UNIFIED IDEOGRAPH
+0xF9AA 0x8C9C #CJK UNIFIED IDEOGRAPH
+0xF9AB 0x8EA9 #CJK UNIFIED IDEOGRAPH
+0xF9AC 0x8EC9 #CJK UNIFIED IDEOGRAPH
+0xF9AD 0x974B #CJK UNIFIED IDEOGRAPH
+0xF9AE 0x9873 #CJK UNIFIED IDEOGRAPH
+0xF9AF 0x9874 #CJK UNIFIED IDEOGRAPH
+0xF9B0 0x98CC #CJK UNIFIED IDEOGRAPH
+0xF9B1 0x9961 #CJK UNIFIED IDEOGRAPH
+0xF9B2 0x99AB #CJK UNIFIED IDEOGRAPH
+0xF9B3 0x9A64 #CJK UNIFIED IDEOGRAPH
+0xF9B4 0x9A66 #CJK UNIFIED IDEOGRAPH
+0xF9B5 0x9A67 #CJK UNIFIED IDEOGRAPH
+0xF9B6 0x9B24 #CJK UNIFIED IDEOGRAPH
+0xF9B7 0x9E15 #CJK UNIFIED IDEOGRAPH
+0xF9B8 0x9E17 #CJK UNIFIED IDEOGRAPH
+0xF9B9 0x9F48 #CJK UNIFIED IDEOGRAPH
+0xF9BA 0x6207 #CJK UNIFIED IDEOGRAPH
+0xF9BB 0x6B1E #CJK UNIFIED IDEOGRAPH
+0xF9BC 0x7227 #CJK UNIFIED IDEOGRAPH
+0xF9BD 0x864C #CJK UNIFIED IDEOGRAPH
+0xF9BE 0x8EA8 #CJK UNIFIED IDEOGRAPH
+0xF9BF 0x9482 #CJK UNIFIED IDEOGRAPH
+0xF9C0 0x9480 #CJK UNIFIED IDEOGRAPH
+0xF9C1 0x9481 #CJK UNIFIED IDEOGRAPH
+0xF9C2 0x9A69 #CJK UNIFIED IDEOGRAPH
+0xF9C3 0x9A68 #CJK UNIFIED IDEOGRAPH
+0xF9C4 0x9B2E #CJK UNIFIED IDEOGRAPH
+0xF9C5 0x9E19 #CJK UNIFIED IDEOGRAPH
+0xF9C6 0x7229 #CJK UNIFIED IDEOGRAPH
+0xF9C7 0x864B #CJK UNIFIED IDEOGRAPH
+0xF9C8 0x8B9F #CJK UNIFIED IDEOGRAPH
+0xF9C9 0x9483 #CJK UNIFIED IDEOGRAPH
+0xF9CA 0x9C79 #CJK UNIFIED IDEOGRAPH
+0xF9CB 0x9EB7 #CJK UNIFIED IDEOGRAPH
+0xF9CC 0x7675 #CJK UNIFIED IDEOGRAPH
+0xF9CD 0x9A6B #CJK UNIFIED IDEOGRAPH
+0xF9CE 0x9C7A #CJK UNIFIED IDEOGRAPH
+0xF9CF 0x9E1D #CJK UNIFIED IDEOGRAPH
+0xF9D0 0x7069 #CJK UNIFIED IDEOGRAPH
+0xF9D1 0x706A #CJK UNIFIED IDEOGRAPH
+0xF9D2 0x9EA4 #CJK UNIFIED IDEOGRAPH
+0xF9D3 0x9F7E #CJK UNIFIED IDEOGRAPH
+0xF9D4 0x9F49 #CJK UNIFIED IDEOGRAPH
+0xF9D5 0x9F98 #CJK UNIFIED IDEOGRAPH
+0xF9D6 0x7881 #CJK UNIFIED IDEOGRAPH
+0xF9D7 0x92B9 #CJK UNIFIED IDEOGRAPH
+0xF9D8 0x88CF #CJK UNIFIED IDEOGRAPH
+0xF9D9 0x58BB #CJK UNIFIED IDEOGRAPH
+0xF9DA 0x6052 #CJK UNIFIED IDEOGRAPH
+0xF9DB 0x7CA7 #CJK UNIFIED IDEOGRAPH
+0xF9DC 0x5AFA #CJK UNIFIED IDEOGRAPH
+0xF9DD 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xF9DE 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xF9DF 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xF9E0 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xF9E1 0x256C #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xF9E2 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xF9E3 0x255A #BOX DRAWINGS DOUBLE UP AND RIGHT
+0xF9E4 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xF9E5 0x255D #BOX DRAWINGS DOUBLE UP AND LEFT
+0xF9E6 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xF9E7 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xF9E8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xF9E9 0x255E #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xF9EA 0x256A #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xF9EB 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xF9EC 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xF9ED 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xF9EE 0x255B #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xF9EF 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xF9F0 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xF9F1 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xF9F2 0x255F #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xF9F3 0x256B #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xF9F4 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xF9F5 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xF9F6 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xF9F7 0x255C #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xF9F8 0x2551 #BOX DRAWINGS DOUBLE VERTICAL
+0xF9F9 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL
+0xF9FA 0x256D #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xF9FB 0x256E #BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xF9FC 0x2570 #BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xF9FD 0x256F #BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xF9FE 0x2593 #DARK SHADE
diff --git a/source/codepages/CPISO8859-1.TXT b/source/codepages/CPISO8859-1.TXT
new file mode 100755
index 00000000000..ec1d7633521
--- /dev/null
+++ b/source/codepages/CPISO8859-1.TXT
@@ -0,0 +1,230 @@
+#
+# Name: ISO 8859-1 (1987) to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 16 January 1995
+# Authors: Tim Greenwood <greenwood@r2me2.enet.dec.com>
+# John H. Jenkins <John_Jenkins@taligent.com>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-1 (1987) characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-1 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-1 order
+#
+# Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x00A1 # INVERTED EXCLAMATION MARK
+0xA2 0x00A2 # CENT SIGN
+0xA3 0x00A3 # POUND SIGN
+0xA4 0x00A4 # CURRENCY SIGN
+0xA5 0x00A5 # YEN SIGN
+0xA6 0x00A6 # BROKEN BAR
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x00A8 # DIAERESIS
+0xA9 0x00A9 # COPYRIGHT SIGN
+0xAA 0x00AA # FEMININE ORDINAL INDICATOR
+0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC # NOT SIGN
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x00AE # REGISTERED SIGN
+0xAF 0x00AF # MACRON
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x00B1 # PLUS-MINUS SIGN
+0xB2 0x00B2 # SUPERSCRIPT TWO
+0xB3 0x00B3 # SUPERSCRIPT THREE
+0xB4 0x00B4 # ACUTE ACCENT
+0xB5 0x00B5 # MICRO SIGN
+0xB6 0x00B6 # PILCROW SIGN
+0xB7 0x00B7 # MIDDLE DOT
+0xB8 0x00B8 # CEDILLA
+0xB9 0x00B9 # SUPERSCRIPT ONE
+0xBA 0x00BA # MASCULINE ORDINAL INDICATOR
+0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x00BC # VULGAR FRACTION ONE QUARTER
+0xBD 0x00BD # VULGAR FRACTION ONE HALF
+0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS
+0xBF 0x00BF # INVERTED QUESTION MARK
+0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE
+0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE
+0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE
+0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6 0x00C6 # LATIN CAPITAL LETTER AE
+0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE
+0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
+0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE
+0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE
+0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic)
+0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE
+0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE
+0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
+0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE
+0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7 0x00D7 # MULTIPLICATION SIGN
+0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE
+0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE
+0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE
+0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic)
+0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German)
+0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE
+0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
+0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE
+0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
+0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE
+0xE6 0x00E6 # LATIN SMALL LETTER AE
+0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA
+0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE
+0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
+0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS
+0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE
+0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE
+0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS
+0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic)
+0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE
+0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE
+0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE
+0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
+0xF7 0x00F7 # DIVISION SIGN
+0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE
+0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE
+0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE
+0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
+0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE
+0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic)
+0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/source/codepages/CPISO8859-13.TXT b/source/codepages/CPISO8859-13.TXT
new file mode 100755
index 00000000000..655acd6aba5
--- /dev/null
+++ b/source/codepages/CPISO8859-13.TXT
@@ -0,0 +1,229 @@
+#
+# Name: ISO 8859-13 to Unicode
+# Unicode version: 1.1
+# Table version: 0.2
+# Table format: Format A
+# Date: 19 February 2001
+# Authors: Toomas Soome <tsoome@ut.ee>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-13 characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-13 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-13 order
+#
+# Any comments or problems, contact <tsoome@ut.ee>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x201D # RIGHT DOUBLE QUOTATION MARK
+0xA2 0x00A2 # CENT SIGN
+0xA3 0x00A3 # POUND SIGN
+0xA4 0x00A4 # CURRENCY SIGN
+0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK
+0xA6 0x00A6 # BROKEN BAR
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE
+0xA9 0x00A9 # COPYRIGHT SIGN
+0xAA 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA
+0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC # NOT SIGN
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x00AE # REGISTERED SIGN
+0xAF 0x00C6 # LATIN CAPITAL LETTER AE
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x00B1 # PLUS-MINUS SIGN
+0xB2 0x00B2 # SUPERSCRIPT TWO
+0xB3 0x00B3 # SUPERSCRIPT THREE
+0xB4 0x201C # LEFT DOUBLE QUOTATION MARK
+0xB5 0x00B5 # MICRO SIGN
+0xB6 0x00B6 # PILCROW SIGN
+0xB7 0x00B7 # MIDDLE DOT
+0xB8 0x00F8 # LATIN SMALL LETTER O WITH STROKE
+0xB9 0x00B9 # SUPERSCRIPT ONE
+0xBA 0x0157 # LATIN SMALL LETTER R WITH CEDILLA
+0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x00BC # VULGAR FRACTION ONE QUARTER
+0xBD 0x00BD # VULGAR FRACTION ONE HALF
+0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS
+0xBF 0x00E6 # LATIN SMALL LETTER AE
+0xC0 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK
+0xC1 0x012E # LATIN CAPITAL LETTER I WITH OGONEK
+0xC2 0x0100 # LATIN CAPITAL LETTER A WITH MACRON
+0xC3 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE
+0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK
+0xC7 0x0112 # LATIN CAPITAL LETTER E WITH MACRON
+0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON
+0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
+0xCA 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE
+0xCB 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xCC 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA
+0xCD 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA
+0xCE 0x012A # LATIN CAPITAL LETTER I WITH MACRON
+0xCF 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA
+0xD0 0x0160 # LATIN CAPITAL LETTER S WITH CARON
+0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE
+0xD2 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA
+0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
+0xD4 0x014C # LATIN CAPITAL LETTER O WITH MACRON
+0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE
+0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7 0x00D7 # MULTIPLICATION SIGN
+0xD8 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK
+0xD9 0x0141 # LATIN CAPITAL LETTER L WITH STROKE
+0xDA 0x015A # LATIN CAPITAL LETTER S WITH ACUTE
+0xDB 0x016A # LATIN CAPITAL LETTER U WITH MACRON
+0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xDE 0x017D # LATIN CAPITAL LETTER Z WITH CARON
+0xDF 0x00DF # LATIN SMALL LETTER SHARP S
+0xE0 0x0105 # LATIN SMALL LETTER A WITH OGONEK
+0xE1 0x012F # LATIN SMALL LETTER I WITH OGONEK
+0xE2 0x0101 # LATIN SMALL LETTER A WITH MACRON
+0xE3 0x0107 # LATIN SMALL LETTER C WITH ACUTE
+0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
+0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE
+0xE6 0x0119 # LATIN SMALL LETTER E WITH OGONEK
+0xE7 0x0113 # LATIN SMALL LETTER E WITH MACRON
+0xE8 0x010D # LATIN SMALL LETTER C WITH CARON
+0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
+0xEA 0x017A # LATIN SMALL LETTER Z WITH ACUTE
+0xEB 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE
+0xEC 0x0123 # LATIN SMALL LETTER G WITH CEDILLA
+0xED 0x0137 # LATIN SMALL LETTER K WITH CEDILLA
+0xEE 0x012B # LATIN SMALL LETTER I WITH MACRON
+0xEF 0x013C # LATIN SMALL LETTER L WITH CEDILLA
+0xF0 0x0161 # LATIN SMALL LETTER S WITH CARON
+0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE
+0xF2 0x0146 # LATIN SMALL LETTER N WITH CEDILLA
+0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xF4 0x014D # LATIN SMALL LETTER O WITH MACRON
+0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE
+0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
+0xF7 0x00F7 # DIVISION SIGN
+0xF8 0x0173 # LATIN SMALL LETTER U WITH OGONEK
+0xF9 0x0142 # LATIN SMALL LETTER L WITH STROKE
+0xFA 0x015B # LATIN SMALL LETTER S WITH ACUTE
+0xFB 0x016B # LATIN SMALL LETTER U WITH MACRON
+0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
+0xFD 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE
+0xFE 0x017E # LATIN SMALL LETTER Z WITH CARON
+0xFF 0x2019 # RIGHT SINGLE QUOTATION MARK
diff --git a/source/codepages/CPISO8859-15.TXT b/source/codepages/CPISO8859-15.TXT
new file mode 100755
index 00000000000..dc23eafeb01
--- /dev/null
+++ b/source/codepages/CPISO8859-15.TXT
@@ -0,0 +1,229 @@
+#
+# Name: ISO 8859-15 to Unicode
+# Unicode version: 1.1
+# Table version: 0.2
+# Table format: Format A
+# Date: 01 may 2001
+# Authors: Toomas Soome <tsoome@ut.ee>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-15 characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-15 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-15 order
+#
+# Any comments or problems, contact <tsoome@ut.ee>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x00A1 # INVERTED EXCLAMATION MARK
+0xA2 0x00A2 # CENT SIGN
+0xA3 0x00A3 # POUND SIGN
+0xA4 0x20AC # EURO SIGN
+0xA5 0x00A5 # YEN SIGN
+0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON
+0xA9 0x00A9 # COPYRIGHT SIGN
+0xAA 0x00AA # FEMININE ORDINAL INDICATOR
+0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC # NOT SIGN
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x00AE # REGISTERED SIGN
+0xAF 0x00AF # MACRON
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x00B1 # PLUS-MINUS SIGN
+0xB2 0x00B2 # SUPERSCRIPT TWO
+0xB3 0x00B3 # SUPERSCRIPT THREE
+0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON
+0xB5 0x00B5 # MICRO SIGN
+0xB6 0x00B6 # PILCROW SIGN
+0xB7 0x00B7 # MIDDLE DOT
+0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON
+0xB9 0x00B9 # SUPERSCRIPT ONE
+0xBA 0x00BA # MASCULINE ORDINAL INDICATOR
+0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x0152 # LATIN CAPITAL LIGATURE OE
+0xBD 0x0153 # LATIN SMALL LIGATURE OE
+0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xBF 0x00BF # INVERTED QUESTION MARK
+0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE
+0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE
+0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE
+0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6 0x00C6 # LATIN CAPITAL LETTER AE
+0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE
+0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
+0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE
+0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE
+0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic)
+0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE
+0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE
+0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
+0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE
+0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7 0x00D7 # MULTIPLICATION SIGN
+0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE
+0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE
+0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE
+0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic)
+0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German)
+0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE
+0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
+0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE
+0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
+0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE
+0xE6 0x00E6 # LATIN SMALL LETTER AE
+0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA
+0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE
+0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
+0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS
+0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE
+0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE
+0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS
+0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic)
+0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE
+0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE
+0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE
+0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
+0xF7 0x00F7 # DIVISION SIGN
+0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE
+0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE
+0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE
+0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
+0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE
+0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic)
+0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/source/codepages/CPISO8859-2.TXT b/source/codepages/CPISO8859-2.TXT
new file mode 100755
index 00000000000..e6f4fb0a566
--- /dev/null
+++ b/source/codepages/CPISO8859-2.TXT
@@ -0,0 +1,230 @@
+#
+# Name: ISO 8859-2 (1987) to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 16 January 1995
+# Authors: Tim Greenwood <greenwood@r2me2.enet.dec.com>
+# John H. Jenkins <John_Jenkins@taligent.com>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-2 (1987) characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-2 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-2 order
+#
+# Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK
+0xA2 0x02D8 # BREVE
+0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE
+0xA4 0x00A4 # CURRENCY SIGN
+0xA5 0x013D # LATIN CAPITAL LETTER L WITH CARON
+0xA6 0x015A # LATIN CAPITAL LETTER S WITH ACUTE
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x00A8 # DIAERESIS
+0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON
+0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA
+0xAB 0x0164 # LATIN CAPITAL LETTER T WITH CARON
+0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON
+0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK
+0xB2 0x02DB # OGONEK
+0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE
+0xB4 0x00B4 # ACUTE ACCENT
+0xB5 0x013E # LATIN SMALL LETTER L WITH CARON
+0xB6 0x015B # LATIN SMALL LETTER S WITH ACUTE
+0xB7 0x02C7 # CARON
+0xB8 0x00B8 # CEDILLA
+0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON
+0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA
+0xBB 0x0165 # LATIN SMALL LETTER T WITH CARON
+0xBC 0x017A # LATIN SMALL LETTER Z WITH ACUTE
+0xBD 0x02DD # DOUBLE ACUTE ACCENT
+0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON
+0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE
+0xC0 0x0154 # LATIN CAPITAL LETTER R WITH ACUTE
+0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE
+0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE
+0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5 0x0139 # LATIN CAPITAL LETTER L WITH ACUTE
+0xC6 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE
+0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON
+0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
+0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK
+0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC 0x011A # LATIN CAPITAL LETTER E WITH CARON
+0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE
+0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF 0x010E # LATIN CAPITAL LETTER D WITH CARON
+0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE
+0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE
+0xD2 0x0147 # LATIN CAPITAL LETTER N WITH CARON
+0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
+0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7 0x00D7 # MULTIPLICATION SIGN
+0xD8 0x0158 # LATIN CAPITAL LETTER R WITH CARON
+0xD9 0x016E # LATIN CAPITAL LETTER U WITH RING ABOVE
+0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE
+0xDB 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE 0x0162 # LATIN CAPITAL LETTER T WITH CEDILLA
+0xDF 0x00DF # LATIN SMALL LETTER SHARP S
+0xE0 0x0155 # LATIN SMALL LETTER R WITH ACUTE
+0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
+0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE
+0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
+0xE5 0x013A # LATIN SMALL LETTER L WITH ACUTE
+0xE6 0x0107 # LATIN SMALL LETTER C WITH ACUTE
+0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA
+0xE8 0x010D # LATIN SMALL LETTER C WITH CARON
+0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
+0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK
+0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS
+0xEC 0x011B # LATIN SMALL LETTER E WITH CARON
+0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE
+0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF 0x010F # LATIN SMALL LETTER D WITH CARON
+0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE
+0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE
+0xF2 0x0148 # LATIN SMALL LETTER N WITH CARON
+0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
+0xF7 0x00F7 # DIVISION SIGN
+0xF8 0x0159 # LATIN SMALL LETTER R WITH CARON
+0xF9 0x016F # LATIN SMALL LETTER U WITH RING ABOVE
+0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE
+0xFB 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
+0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE
+0xFE 0x0163 # LATIN SMALL LETTER T WITH CEDILLA
+0xFF 0x02D9 # DOT ABOVE
diff --git a/source/codepages/CPISO8859-5.TXT b/source/codepages/CPISO8859-5.TXT
new file mode 100755
index 00000000000..ae7a76ef643
--- /dev/null
+++ b/source/codepages/CPISO8859-5.TXT
@@ -0,0 +1,230 @@
+#
+# Name: ISO 8859-5 (1988) to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 16 January 1995
+# Authors: Tim Greenwood <greenwood@r2me2.enet.dec.com>
+# John H. Jenkins <John_Jenkins@taligent.com>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-5 (1988) characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-5 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-5 order
+#
+# Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x0401 # CYRILLIC CAPITAL LETTER IO
+0xA2 0x0402 # CYRILLIC CAPITAL LETTER DJE
+0xA3 0x0403 # CYRILLIC CAPITAL LETTER GJE
+0xA4 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xA5 0x0405 # CYRILLIC CAPITAL LETTER DZE
+0xA6 0x0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xA7 0x0407 # CYRILLIC CAPITAL LETTER YI
+0xA8 0x0408 # CYRILLIC CAPITAL LETTER JE
+0xA9 0x0409 # CYRILLIC CAPITAL LETTER LJE
+0xAA 0x040A # CYRILLIC CAPITAL LETTER NJE
+0xAB 0x040B # CYRILLIC CAPITAL LETTER TSHE
+0xAC 0x040C # CYRILLIC CAPITAL LETTER KJE
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x040E # CYRILLIC CAPITAL LETTER SHORT U
+0xAF 0x040F # CYRILLIC CAPITAL LETTER DZHE
+0xB0 0x0410 # CYRILLIC CAPITAL LETTER A
+0xB1 0x0411 # CYRILLIC CAPITAL LETTER BE
+0xB2 0x0412 # CYRILLIC CAPITAL LETTER VE
+0xB3 0x0413 # CYRILLIC CAPITAL LETTER GHE
+0xB4 0x0414 # CYRILLIC CAPITAL LETTER DE
+0xB5 0x0415 # CYRILLIC CAPITAL LETTER IE
+0xB6 0x0416 # CYRILLIC CAPITAL LETTER ZHE
+0xB7 0x0417 # CYRILLIC CAPITAL LETTER ZE
+0xB8 0x0418 # CYRILLIC CAPITAL LETTER I
+0xB9 0x0419 # CYRILLIC CAPITAL LETTER SHORT I
+0xBA 0x041A # CYRILLIC CAPITAL LETTER KA
+0xBB 0x041B # CYRILLIC CAPITAL LETTER EL
+0xBC 0x041C # CYRILLIC CAPITAL LETTER EM
+0xBD 0x041D # CYRILLIC CAPITAL LETTER EN
+0xBE 0x041E # CYRILLIC CAPITAL LETTER O
+0xBF 0x041F # CYRILLIC CAPITAL LETTER PE
+0xC0 0x0420 # CYRILLIC CAPITAL LETTER ER
+0xC1 0x0421 # CYRILLIC CAPITAL LETTER ES
+0xC2 0x0422 # CYRILLIC CAPITAL LETTER TE
+0xC3 0x0423 # CYRILLIC CAPITAL LETTER U
+0xC4 0x0424 # CYRILLIC CAPITAL LETTER EF
+0xC5 0x0425 # CYRILLIC CAPITAL LETTER HA
+0xC6 0x0426 # CYRILLIC CAPITAL LETTER TSE
+0xC7 0x0427 # CYRILLIC CAPITAL LETTER CHE
+0xC8 0x0428 # CYRILLIC CAPITAL LETTER SHA
+0xC9 0x0429 # CYRILLIC CAPITAL LETTER SHCHA
+0xCA 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN
+0xCB 0x042B # CYRILLIC CAPITAL LETTER YERU
+0xCC 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN
+0xCD 0x042D # CYRILLIC CAPITAL LETTER E
+0xCE 0x042E # CYRILLIC CAPITAL LETTER YU
+0xCF 0x042F # CYRILLIC CAPITAL LETTER YA
+0xD0 0x0430 # CYRILLIC SMALL LETTER A
+0xD1 0x0431 # CYRILLIC SMALL LETTER BE
+0xD2 0x0432 # CYRILLIC SMALL LETTER VE
+0xD3 0x0433 # CYRILLIC SMALL LETTER GHE
+0xD4 0x0434 # CYRILLIC SMALL LETTER DE
+0xD5 0x0435 # CYRILLIC SMALL LETTER IE
+0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE
+0xD7 0x0437 # CYRILLIC SMALL LETTER ZE
+0xD8 0x0438 # CYRILLIC SMALL LETTER I
+0xD9 0x0439 # CYRILLIC SMALL LETTER SHORT I
+0xDA 0x043A # CYRILLIC SMALL LETTER KA
+0xDB 0x043B # CYRILLIC SMALL LETTER EL
+0xDC 0x043C # CYRILLIC SMALL LETTER EM
+0xDD 0x043D # CYRILLIC SMALL LETTER EN
+0xDE 0x043E # CYRILLIC SMALL LETTER O
+0xDF 0x043F # CYRILLIC SMALL LETTER PE
+0xE0 0x0440 # CYRILLIC SMALL LETTER ER
+0xE1 0x0441 # CYRILLIC SMALL LETTER ES
+0xE2 0x0442 # CYRILLIC SMALL LETTER TE
+0xE3 0x0443 # CYRILLIC SMALL LETTER U
+0xE4 0x0444 # CYRILLIC SMALL LETTER EF
+0xE5 0x0445 # CYRILLIC SMALL LETTER HA
+0xE6 0x0446 # CYRILLIC SMALL LETTER TSE
+0xE7 0x0447 # CYRILLIC SMALL LETTER CHE
+0xE8 0x0448 # CYRILLIC SMALL LETTER SHA
+0xE9 0x0449 # CYRILLIC SMALL LETTER SHCHA
+0xEA 0x044A # CYRILLIC SMALL LETTER HARD SIGN
+0xEB 0x044B # CYRILLIC SMALL LETTER YERU
+0xEC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN
+0xED 0x044D # CYRILLIC SMALL LETTER E
+0xEE 0x044E # CYRILLIC SMALL LETTER YU
+0xEF 0x044F # CYRILLIC SMALL LETTER YA
+0xF0 0x2116 # NUMERO SIGN
+0xF1 0x0451 # CYRILLIC SMALL LETTER IO
+0xF2 0x0452 # CYRILLIC SMALL LETTER DJE
+0xF3 0x0453 # CYRILLIC SMALL LETTER GJE
+0xF4 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE
+0xF5 0x0455 # CYRILLIC SMALL LETTER DZE
+0xF6 0x0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xF7 0x0457 # CYRILLIC SMALL LETTER YI
+0xF8 0x0458 # CYRILLIC SMALL LETTER JE
+0xF9 0x0459 # CYRILLIC SMALL LETTER LJE
+0xFA 0x045A # CYRILLIC SMALL LETTER NJE
+0xFB 0x045B # CYRILLIC SMALL LETTER TSHE
+0xFC 0x045C # CYRILLIC SMALL LETTER KJE
+0xFD 0x00A7 # SECTION SIGN
+0xFE 0x045E # CYRILLIC SMALL LETTER SHORT U
+0xFF 0x045F # CYRILLIC SMALL LETTER DZHE
diff --git a/source/codepages/CPISO8859-7.TXT b/source/codepages/CPISO8859-7.TXT
new file mode 100755
index 00000000000..f9ea8515e54
--- /dev/null
+++ b/source/codepages/CPISO8859-7.TXT
@@ -0,0 +1,224 @@
+#
+# Name: ISO 8859-7 (1987) to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 16 January 1995
+# Authors: Tim Greenwood <greenwood@r2me2.enet.dec.com>
+# John H. Jenkins <John_Jenkins@taligent.com>
+#
+# Copyright (c) 1991-1995 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode. Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-7 (1987) characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-7 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-7 order
+#
+# Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x02BD # MODIFIER LETTER REVERSED COMMA
+0xA2 0x02BC # MODIFIER LETTER APOSTROPHE
+0xA3 0x00A3 # POUND SIGN
+0xA6 0x00A6 # BROKEN BAR
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x00A8 # DIAERESIS
+0xA9 0x00A9 # COPYRIGHT SIGN
+0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC # NOT SIGN
+0xAD 0x00AD # SOFT HYPHEN
+0xAF 0x2015 # HORIZONTAL BAR
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x00B1 # PLUS-MINUS SIGN
+0xB2 0x00B2 # SUPERSCRIPT TWO
+0xB3 0x00B3 # SUPERSCRIPT THREE
+0xB4 0x0384 # GREEK TONOS
+0xB5 0x0385 # GREEK DIALYTIKA TONOS
+0xB6 0x0386 # GREEK CAPITAL LETTER ALPHA WITH TONOS
+0xB7 0x00B7 # MIDDLE DOT
+0xB8 0x0388 # GREEK CAPITAL LETTER EPSILON WITH TONOS
+0xB9 0x0389 # GREEK CAPITAL LETTER ETA WITH TONOS
+0xBA 0x038A # GREEK CAPITAL LETTER IOTA WITH TONOS
+0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x038C # GREEK CAPITAL LETTER OMICRON WITH TONOS
+0xBD 0x00BD # VULGAR FRACTION ONE HALF
+0xBE 0x038E # GREEK CAPITAL LETTER UPSILON WITH TONOS
+0xBF 0x038F # GREEK CAPITAL LETTER OMEGA WITH TONOS
+0xC0 0x0390 # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0xC1 0x0391 # GREEK CAPITAL LETTER ALPHA
+0xC2 0x0392 # GREEK CAPITAL LETTER BETA
+0xC3 0x0393 # GREEK CAPITAL LETTER GAMMA
+0xC4 0x0394 # GREEK CAPITAL LETTER DELTA
+0xC5 0x0395 # GREEK CAPITAL LETTER EPSILON
+0xC6 0x0396 # GREEK CAPITAL LETTER ZETA
+0xC7 0x0397 # GREEK CAPITAL LETTER ETA
+0xC8 0x0398 # GREEK CAPITAL LETTER THETA
+0xC9 0x0399 # GREEK CAPITAL LETTER IOTA
+0xCA 0x039A # GREEK CAPITAL LETTER KAPPA
+0xCB 0x039B # GREEK CAPITAL LETTER LAMDA
+0xCC 0x039C # GREEK CAPITAL LETTER MU
+0xCD 0x039D # GREEK CAPITAL LETTER NU
+0xCE 0x039E # GREEK CAPITAL LETTER XI
+0xCF 0x039F # GREEK CAPITAL LETTER OMICRON
+0xD0 0x03A0 # GREEK CAPITAL LETTER PI
+0xD1 0x03A1 # GREEK CAPITAL LETTER RHO
+0xD3 0x03A3 # GREEK CAPITAL LETTER SIGMA
+0xD4 0x03A4 # GREEK CAPITAL LETTER TAU
+0xD5 0x03A5 # GREEK CAPITAL LETTER UPSILON
+0xD6 0x03A6 # GREEK CAPITAL LETTER PHI
+0xD7 0x03A7 # GREEK CAPITAL LETTER CHI
+0xD8 0x03A8 # GREEK CAPITAL LETTER PSI
+0xD9 0x03A9 # GREEK CAPITAL LETTER OMEGA
+0xDA 0x03AA # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0xDB 0x03AB # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0xDC 0x03AC # GREEK SMALL LETTER ALPHA WITH TONOS
+0xDD 0x03AD # GREEK SMALL LETTER EPSILON WITH TONOS
+0xDE 0x03AE # GREEK SMALL LETTER ETA WITH TONOS
+0xDF 0x03AF # GREEK SMALL LETTER IOTA WITH TONOS
+0xE0 0x03B0 # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0xE1 0x03B1 # GREEK SMALL LETTER ALPHA
+0xE2 0x03B2 # GREEK SMALL LETTER BETA
+0xE3 0x03B3 # GREEK SMALL LETTER GAMMA
+0xE4 0x03B4 # GREEK SMALL LETTER DELTA
+0xE5 0x03B5 # GREEK SMALL LETTER EPSILON
+0xE6 0x03B6 # GREEK SMALL LETTER ZETA
+0xE7 0x03B7 # GREEK SMALL LETTER ETA
+0xE8 0x03B8 # GREEK SMALL LETTER THETA
+0xE9 0x03B9 # GREEK SMALL LETTER IOTA
+0xEA 0x03BA # GREEK SMALL LETTER KAPPA
+0xEB 0x03BB # GREEK SMALL LETTER LAMDA
+0xEC 0x03BC # GREEK SMALL LETTER MU
+0xED 0x03BD # GREEK SMALL LETTER NU
+0xEE 0x03BE # GREEK SMALL LETTER XI
+0xEF 0x03BF # GREEK SMALL LETTER OMICRON
+0xF0 0x03C0 # GREEK SMALL LETTER PI
+0xF1 0x03C1 # GREEK SMALL LETTER RHO
+0xF2 0x03C2 # GREEK SMALL LETTER FINAL SIGMA
+0xF3 0x03C3 # GREEK SMALL LETTER SIGMA
+0xF4 0x03C4 # GREEK SMALL LETTER TAU
+0xF5 0x03C5 # GREEK SMALL LETTER UPSILON
+0xF6 0x03C6 # GREEK SMALL LETTER PHI
+0xF7 0x03C7 # GREEK SMALL LETTER CHI
+0xF8 0x03C8 # GREEK SMALL LETTER PSI
+0xF9 0x03C9 # GREEK SMALL LETTER OMEGA
+0xFA 0x03CA # GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xFB 0x03CB # GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xFC 0x03CC # GREEK SMALL LETTER OMICRON WITH TONOS
+0xFD 0x03CD # GREEK SMALL LETTER UPSILON WITH TONOS
+0xFE 0x03CE # GREEK SMALL LETTER OMEGA WITH TONOS
diff --git a/source/codepages/CPISO8859-8.TXT b/source/codepages/CPISO8859-8.TXT
new file mode 100755
index 00000000000..4e75088f6d1
--- /dev/null
+++ b/source/codepages/CPISO8859-8.TXT
@@ -0,0 +1,240 @@
+#
+# Name: ISO 8859-8 to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 15 February 2002
+# Authors: Alexander Bokovoy <ab@alt-linux.org>
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# ISO 8859-8 (Hewbrew) characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-8 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-8 order
+#
+0x00 0x0000 # NULL (NUL)
+0x01 0x0001 # START OF HEADING (SOH)
+0x02 0x0002 # START OF TEXT (STX)
+0x03 0x0003 # END OF TEXT (ETX)
+0x04 0x0004 # END OF TRANSMISSION (EOT)
+0x05 0x0005 # ENQUIRY (ENQ)
+0x06 0x0006 # ACKNOWLEDGE (ACK)
+0x07 0x0007 # BELL (BEL)
+0x08 0x0008 # BACKSPACE (BS)
+0x09 0x0009 # CHARACTER TABULATION (HT)
+0x0a 0x000A # LINE FEED (LF)
+0x0b 0x000B # LINE TABULATION (VT)
+0x0c 0x000C # FORM FEED (FF)
+0x0d 0x000D # CARRIAGE RETURN (CR)
+0x0e 0x000E # SHIFT OUT (SO)
+0x0f 0x000F # SHIFT IN (SI)
+0x10 0x0010 # DATALINK ESCAPE (DLE)
+0x11 0x0011 # DEVICE CONTROL ONE (DC1)
+0x12 0x0012 # DEVICE CONTROL TWO (DC2)
+0x13 0x0013 # DEVICE CONTROL THREE (DC3)
+0x14 0x0014 # DEVICE CONTROL FOUR (DC4)
+0x15 0x0015 # NEGATIVE ACKNOWLEDGE (NAK)
+0x16 0x0016 # SYNCHRONOUS IDLE (SYN)
+0x17 0x0017 # END OF TRANSMISSION BLOCK (ETB)
+0x18 0x0018 # CANCEL (CAN)
+0x19 0x0019 # END OF MEDIUM (EM)
+0x1a 0x001A # SUBSTITUTE (SUB)
+0x1b 0x001B # ESCAPE (ESC)
+0x1c 0x001C # FILE SEPARATOR (IS4)
+0x1d 0x001D # GROUP SEPARATOR (IS3)
+0x1e 0x001E # RECORD SEPARATOR (IS2)
+0x1f 0x001F # UNIT SEPARATOR (IS1)
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2a 0x002A # ASTERISK
+0x2b 0x002B # PLUS SIGN
+0x2c 0x002C # COMMA
+0x2d 0x002D # HYPHEN-MINUS
+0x2e 0x002E # FULL STOP
+0x2f 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3a 0x003A # COLON
+0x3b 0x003B # SEMICOLON
+0x3c 0x003C # LESS-THAN SIGN
+0x3d 0x003D # EQUALS SIGN
+0x3e 0x003E # GREATER-THAN SIGN
+0x3f 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4a 0x004A # LATIN CAPITAL LETTER J
+0x4b 0x004B # LATIN CAPITAL LETTER K
+0x4c 0x004C # LATIN CAPITAL LETTER L
+0x4d 0x004D # LATIN CAPITAL LETTER M
+0x4e 0x004E # LATIN CAPITAL LETTER N
+0x4f 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5a 0x005A # LATIN CAPITAL LETTER Z
+0x5b 0x005B # LEFT SQUARE BRACKET
+0x5c 0x005C # REVERSE SOLIDUS
+0x5d 0x005D # RIGHT SQUARE BRACKET
+0x5e 0x005E # CIRCUMFLEX ACCENT
+0x5f 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6a 0x006A # LATIN SMALL LETTER J
+0x6b 0x006B # LATIN SMALL LETTER K
+0x6c 0x006C # LATIN SMALL LETTER L
+0x6d 0x006D # LATIN SMALL LETTER M
+0x6e 0x006E # LATIN SMALL LETTER N
+0x6f 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7a 0x007A # LATIN SMALL LETTER Z
+0x7b 0x007B # LEFT CURLY BRACKET
+0x7c 0x007C # VERTICAL LINE
+0x7d 0x007D # RIGHT CURLY BRACKET
+0x7e 0x007E # TILDE
+0x7f 0x007F # DELETE (DEL)
+0x80 0x0080 # PADDING CHARACTER (PAD)
+0x81 0x0081 # HIGH OCTET PRESET (HOP)
+0x82 0x0082 # BREAK PERMITTED HERE (BPH)
+0x83 0x0083 # NO BREAK HERE (NBH)
+0x84 0x0084 # INDEX (IND)
+0x85 0x0085 # NEXT LINE (NEL)
+0x86 0x0086 # START OF SELECTED AREA (SSA)
+0x87 0x0087 # END OF SELECTED AREA (ESA)
+0x88 0x0088 # CHARACTER TABULATION SET (HTS)
+0x89 0x0089 # CHARACTER TABULATION WITH JUSTIFICATION (HTJ)
+0x8a 0x008A # LINE TABULATION SET (VTS)
+0x8b 0x008B # PARTIAL LINE FORWARD (PLD)
+0x8c 0x008C # PARTIAL LINE BACKWARD (PLU)
+0x8d 0x008D # REVERSE LINE FEED (RI)
+0x8e 0x008E # SINGLE-SHIFT TWO (SS2)
+0x8f 0x008F # SINGLE-SHIFT THREE (SS3)
+0x90 0x0090 # DEVICE CONTROL STRING (DCS)
+0x91 0x0091 # PRIVATE USE ONE (PU1)
+0x92 0x0092 # PRIVATE USE TWO (PU2)
+0x93 0x0093 # SET TRANSMIT STATE (STS)
+0x94 0x0094 # CANCEL CHARACTER (CCH)
+0x95 0x0095 # MESSAGE WAITING (MW)
+0x96 0x0096 # START OF GUARDED AREA (SPA)
+0x97 0x0097 # END OF GUARDED AREA (EPA)
+0x98 0x0098 # START OF STRING (SOS)
+0x99 0x0099 # SINGLE GRAPHIC CHARACTER INTRODUCER (SGCI)
+0x9a 0x009A # SINGLE CHARACTER INTRODUCER (SCI)
+0x9b 0x009B # CONTROL SEQUENCE INTRODUCER (CSI)
+0x9c 0x009C # STRING TERMINATOR (ST)
+0x9d 0x009D # OPERATING SYSTEM COMMAND (OSC)
+0x9e 0x009E # PRIVACY MESSAGE (PM)
+0x9f 0x009F # APPLICATION PROGRAM COMMAND (APC)
+0xa0 0x00A0 # NO-BREAK SPACE
+0xa2 0x00A2 # CENT SIGN
+0xa3 0x00A3 # POUND SIGN
+0xa4 0x00A4 # CURRENCY SIGN
+0xa5 0x00A5 # YEN SIGN
+0xa6 0x00A6 # BROKEN BAR
+0xa7 0x00A7 # SECTION SIGN
+0xa8 0x00A8 # DIAERESIS
+0xa9 0x00A9 # COPYRIGHT SIGN
+0xaa 0x00D7 # MULTIPLICATION SIGN
+0xab 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xac 0x00AC # NOT SIGN
+0xad 0x00AD # SOFT HYPHEN
+0xae 0x00AE # REGISTERED SIGN
+0xaf 0x00AF # MACRON
+0xb0 0x00B0 # DEGREE SIGN
+0xb1 0x00B1 # PLUS-MINUS SIGN
+0xb2 0x00B2 # SUPERSCRIPT TWO
+0xb3 0x00B3 # SUPERSCRIPT THREE
+0xb4 0x00B4 # ACUTE ACCENT
+0xb5 0x00B5 # MICRO SIGN
+0xb6 0x00B6 # PILCROW SIGN
+0xb7 0x00B7 # MIDDLE DOT
+0xb8 0x00B8 # CEDILLA
+0xb9 0x00B9 # SUPERSCRIPT ONE
+0xba 0x00F7 # DIVISION SIGN
+0xbb 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xbc 0x00BC # VULGAR FRACTION ONE QUARTER
+0xbd 0x00BD # VULGAR FRACTION ONE HALF
+0xbe 0x00BE # VULGAR FRACTION THREE QUARTERS
+0xdf 0x2017 # DOUBLE LOW LINE
+0xe0 0x05D0 # HEBREW LETTER ALEF
+0xe1 0x05D1 # HEBREW LETTER BET
+0xe2 0x05D2 # HEBREW LETTER GIMEL
+0xe3 0x05D3 # HEBREW LETTER DALET
+0xe4 0x05D4 # HEBREW LETTER HE
+0xe5 0x05D5 # HEBREW LETTER VAV
+0xe6 0x05D6 # HEBREW LETTER ZAYIN
+0xe7 0x05D7 # HEBREW LETTER HET
+0xe8 0x05D8 # HEBREW LETTER TET
+0xe9 0x05D9 # HEBREW LETTER YOD
+0xea 0x05DA # HEBREW LETTER FINAL KAF
+0xeb 0x05DB # HEBREW LETTER KAF
+0xec 0x05DC # HEBREW LETTER LAMED
+0xed 0x05DD # HEBREW LETTER FINAL MEM
+0xee 0x05DE # HEBREW LETTER MEM
+0xef 0x05DF # HEBREW LETTER FINAL NUN
+0xf0 0x05E0 # HEBREW LETTER NUN
+0xf1 0x05E1 # HEBREW LETTER SAMEKH
+0xf2 0x05E2 # HEBREW LETTER AYIN
+0xf3 0x05E3 # HEBREW LETTER FINAL PE
+0xf4 0x05E4 # HEBREW LETTER PE
+0xf5 0x05E5 # HEBREW LETTER FINAL TSADI
+0xf6 0x05E6 # HEBREW LETTER TSADI
+0xf7 0x05E7 # HEBREW LETTER QOF
+0xf8 0x05E8 # HEBREW LETTER RESH
+0xf9 0x05E9 # HEBREW LETTER SHIN
+0xfa 0x05EA # HEBREW LETTER TAV
+0xfd 0x200E # LEFT-TO-RIGHT MARK
+0xfe 0x200F # RIGHT-TO-LEFT MARK
diff --git a/source/codepages/CPISO8859-9.TXT b/source/codepages/CPISO8859-9.TXT
new file mode 100755
index 00000000000..7c84caf002f
--- /dev/null
+++ b/source/codepages/CPISO8859-9.TXT
@@ -0,0 +1,222 @@
+#
+# Name: ISO 8859-9 to Unicode
+# Unicode version: 1.1
+# Table version: 0.1
+# Table format: Format A
+# Date: 7 January 2001
+# Authors: Deniz Akkus <akkus@alum.mit.edu>
+#
+# General notes:
+#
+# This table contains data on how
+# ISO 8859-9 characters map into Unicode.
+#
+# Format: Three tab-separated columns
+# Column #1 is the ISO 8859-9 code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in ISO 8859-9 order
+#
+# Any comments or problems, contact <akkus@alum.mit.edu>
+#
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0xA0 0x00A0 # NO-BREAK SPACE
+0xA1 0x00A1 # INVERTED EXCLAMATION MARK
+0xA2 0x00A2 # CENT SIGN
+0xA3 0x00A3 # POUND SIGN
+0xA4 0x00A4 # CURRENCY SIGN
+0xA5 0x00A5 # YEN SIGN
+0xA6 0x00A6 # BROKEN BAR
+0xA7 0x00A7 # SECTION SIGN
+0xA8 0x00A8 # DIAERESIS
+0xA9 0x00A9 # COPYRIGHT SIGN
+0xAA 0x00AA # FEMININE ORDINAL INDICATOR
+0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC 0x00AC # NOT SIGN
+0xAD 0x00AD # SOFT HYPHEN
+0xAE 0x00AE # REGISTERED SIGN
+0xAF 0x00AF # MACRON
+0xB0 0x00B0 # DEGREE SIGN
+0xB1 0x00B1 # PLUS-MINUS SIGN
+0xB2 0x00B2 # SUPERSCRIPT TWO
+0xB3 0x00B3 # SUPERSCRIPT THREE
+0xB4 0x00B4 # ACUTE ACCENT
+0xB5 0x00B5 # MICRO SIGN
+0xB6 0x00B6 # PILCROW SIGN
+0xB7 0x00B7 # MIDDLE DOT
+0xB8 0x00B8 # CEDILLA
+0xB9 0x00B9 # SUPERSCRIPT ONE
+0xBA 0x00BA # MASCULINE ORDINAL INDICATOR
+0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC 0x00BC # VULGAR FRACTION ONE QUARTER
+0xBD 0x00BD # VULGAR FRACTION ONE HALF
+0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS
+0xBF 0x00BF # INVERTED QUESTION MARK
+0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE
+0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE
+0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE
+0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6 0x00C6 # LATIN CAPITAL LETTER AE
+0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE
+0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
+0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE
+0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE
+0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0 0x011E # LATIN CAPITAL LETTER G WITH BREVE
+0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE
+0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE
+0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
+0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE
+0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7 0x00D7 # MULTIPLICATION SIGN
+0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE
+0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE
+0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE
+0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0xDE 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA
+0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German)
+0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE
+0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
+0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE
+0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
+0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE
+0xE6 0x00E6 # LATIN SMALL LETTER AE
+0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA
+0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE
+0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
+0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS
+0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE
+0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE
+0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS
+0xF0 0x011F # LATIN SMALL LETTER G WITH BREVE
+0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE
+0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE
+0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
+0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE
+0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
+0xF7 0x00F7 # DIVISION SIGN
+0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE
+0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE
+0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE
+0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
+0xFD 0x0131 # LATIN SMALL LETTER DOTLESS I
+0xFE 0x015F # LATIN SMALL LETTER S WITH CEDILLA
+0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS
+
+
+
+
+
+
+
+
+
diff --git a/source/codepages/CPKOI8-R.TXT b/source/codepages/CPKOI8-R.TXT
new file mode 100755
index 00000000000..510561005c0
--- /dev/null
+++ b/source/codepages/CPKOI8-R.TXT
@@ -0,0 +1,302 @@
+#
+# Name: KOI8-R (RFC1489) to Unicode
+# Unicode version: 3.0
+# Table version: 1.0
+# Table format: Format A
+# Date: 18 August 1999
+# Authors: Helmut Richter <richter@lrz.de>
+#
+# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose. No
+# warranties of any kind are expressed or implied. The recipient
+# agrees to determine applicability of information provided. If this
+# file has been provided on optical media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Unicode, Inc. hereby grants the right to freely use the information
+# supplied in this file in the creation of products supporting the
+# Unicode Standard, and to make copies of this file in any form for
+# internal or external distribution as long as this notice remains
+# attached.
+#
+# General notes:
+#
+# This table contains the data the Unicode Consortium has on how
+# KOI8-R characters map into Unicode. The underlying document is the
+# mapping described in RFC 1489. No statements are made as to whether
+# this mapping is the same as the mapping defined as "Code Page 878"
+# with some vendors.
+#
+# Format: Three tab-separated columns
+# Column #1 is the KOI8-R code (in hex as 0xXX)
+# Column #2 is the Unicode (in hex as 0xXXXX)
+# Column #3 the Unicode name (follows a comment sign, '#')
+#
+# The entries are in KOI8-R order.
+#
+# Version history
+# 1.0 version: created.
+#
+# Any comments or problems, contact <errata@unicode.org>
+# Please note that <errata@unicode.org> is an archival address;
+# notices will be checked, but do not expect an immediate response.
+#
+0x00 0x0000 # NULL
+0x01 0x0001 # START OF HEADING
+0x02 0x0002 # START OF TEXT
+0x03 0x0003 # END OF TEXT
+0x04 0x0004 # END OF TRANSMISSION
+0x05 0x0005 # ENQUIRY
+0x06 0x0006 # ACKNOWLEDGE
+0x07 0x0007 # BELL
+0x08 0x0008 # BACKSPACE
+0x09 0x0009 # HORIZONTAL TABULATION
+0x0A 0x000A # LINE FEED
+0x0B 0x000B # VERTICAL TABULATION
+0x0C 0x000C # FORM FEED
+0x0D 0x000D # CARRIAGE RETURN
+0x0E 0x000E # SHIFT OUT
+0x0F 0x000F # SHIFT IN
+0x10 0x0010 # DATA LINK ESCAPE
+0x11 0x0011 # DEVICE CONTROL ONE
+0x12 0x0012 # DEVICE CONTROL TWO
+0x13 0x0013 # DEVICE CONTROL THREE
+0x14 0x0014 # DEVICE CONTROL FOUR
+0x15 0x0015 # NEGATIVE ACKNOWLEDGE
+0x16 0x0016 # SYNCHRONOUS IDLE
+0x17 0x0017 # END OF TRANSMISSION BLOCK
+0x18 0x0018 # CANCEL
+0x19 0x0019 # END OF MEDIUM
+0x1A 0x001A # SUBSTITUTE
+0x1B 0x001B # ESCAPE
+0x1C 0x001C # FILE SEPARATOR
+0x1D 0x001D # GROUP SEPARATOR
+0x1E 0x001E # RECORD SEPARATOR
+0x1F 0x001F # UNIT SEPARATOR
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0x7F 0x007F # DELETE
+0x80 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL
+0x81 0x2502 # BOX DRAWINGS LIGHT VERTICAL
+0x82 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x83 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT
+0x85 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT
+0x86 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x87 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x88 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x89 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x8A 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x8B 0x2580 # UPPER HALF BLOCK
+0x8C 0x2584 # LOWER HALF BLOCK
+0x8D 0x2588 # FULL BLOCK
+0x8E 0x258C # LEFT HALF BLOCK
+0x8F 0x2590 # RIGHT HALF BLOCK
+0x90 0x2591 # LIGHT SHADE
+0x91 0x2592 # MEDIUM SHADE
+0x92 0x2593 # DARK SHADE
+0x93 0x2320 # TOP HALF INTEGRAL
+0x94 0x25A0 # BLACK SQUARE
+0x95 0x2219 # BULLET OPERATOR
+0x96 0x221A # SQUARE ROOT
+0x97 0x2248 # ALMOST EQUAL TO
+0x98 0x2264 # LESS-THAN OR EQUAL TO
+0x99 0x2265 # GREATER-THAN OR EQUAL TO
+0x9A 0x00A0 # NO-BREAK SPACE
+0x9B 0x2321 # BOTTOM HALF INTEGRAL
+0x9C 0x00B0 # DEGREE SIGN
+0x9D 0x00B2 # SUPERSCRIPT TWO
+0x9E 0x00B7 # MIDDLE DOT
+0x9F 0x00F7 # DIVISION SIGN
+0xA0 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL
+0xA1 0x2551 # BOX DRAWINGS DOUBLE VERTICAL
+0xA2 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xA3 0x0451 # CYRILLIC SMALL LETTER IO
+0xA4 0x2553 # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xA5 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xA6 0x2555 # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xA7 0x2556 # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xA8 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xA9 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xAA 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xAB 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT
+0xAC 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xAD 0x255C # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xAE 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT
+0xAF 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xB0 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xB1 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xB2 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO
+0xB4 0x2562 # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xB5 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xB6 0x2564 # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xB7 0x2565 # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xB8 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xB9 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xBA 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xBB 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xBC 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xBD 0x256B # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xBE 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xBF 0x00A9 # COPYRIGHT SIGN
+0xC0 0x044E # CYRILLIC SMALL LETTER YU
+0xC1 0x0430 # CYRILLIC SMALL LETTER A
+0xC2 0x0431 # CYRILLIC SMALL LETTER BE
+0xC3 0x0446 # CYRILLIC SMALL LETTER TSE
+0xC4 0x0434 # CYRILLIC SMALL LETTER DE
+0xC5 0x0435 # CYRILLIC SMALL LETTER IE
+0xC6 0x0444 # CYRILLIC SMALL LETTER EF
+0xC7 0x0433 # CYRILLIC SMALL LETTER GHE
+0xC8 0x0445 # CYRILLIC SMALL LETTER HA
+0xC9 0x0438 # CYRILLIC SMALL LETTER I
+0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I
+0xCB 0x043A # CYRILLIC SMALL LETTER KA
+0xCC 0x043B # CYRILLIC SMALL LETTER EL
+0xCD 0x043C # CYRILLIC SMALL LETTER EM
+0xCE 0x043D # CYRILLIC SMALL LETTER EN
+0xCF 0x043E # CYRILLIC SMALL LETTER O
+0xD0 0x043F # CYRILLIC SMALL LETTER PE
+0xD1 0x044F # CYRILLIC SMALL LETTER YA
+0xD2 0x0440 # CYRILLIC SMALL LETTER ER
+0xD3 0x0441 # CYRILLIC SMALL LETTER ES
+0xD4 0x0442 # CYRILLIC SMALL LETTER TE
+0xD5 0x0443 # CYRILLIC SMALL LETTER U
+0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE
+0xD7 0x0432 # CYRILLIC SMALL LETTER VE
+0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN
+0xD9 0x044B # CYRILLIC SMALL LETTER YERU
+0xDA 0x0437 # CYRILLIC SMALL LETTER ZE
+0xDB 0x0448 # CYRILLIC SMALL LETTER SHA
+0xDC 0x044D # CYRILLIC SMALL LETTER E
+0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA
+0xDE 0x0447 # CYRILLIC SMALL LETTER CHE
+0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN
+0xE0 0x042E # CYRILLIC CAPITAL LETTER YU
+0xE1 0x0410 # CYRILLIC CAPITAL LETTER A
+0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE
+0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE
+0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE
+0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE
+0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF
+0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE
+0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA
+0xE9 0x0418 # CYRILLIC CAPITAL LETTER I
+0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I
+0xEB 0x041A # CYRILLIC CAPITAL LETTER KA
+0xEC 0x041B # CYRILLIC CAPITAL LETTER EL
+0xED 0x041C # CYRILLIC CAPITAL LETTER EM
+0xEE 0x041D # CYRILLIC CAPITAL LETTER EN
+0xEF 0x041E # CYRILLIC CAPITAL LETTER O
+0xF0 0x041F # CYRILLIC CAPITAL LETTER PE
+0xF1 0x042F # CYRILLIC CAPITAL LETTER YA
+0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER
+0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES
+0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE
+0xF5 0x0423 # CYRILLIC CAPITAL LETTER U
+0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE
+0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE
+0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN
+0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU
+0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE
+0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA
+0xFC 0x042D # CYRILLIC CAPITAL LETTER E
+0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA
+0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE
+0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN
diff --git a/source/codepages/CPKOI8-U.TXT b/source/codepages/CPKOI8-U.TXT
new file mode 100755
index 00000000000..46fb409ee76
--- /dev/null
+++ b/source/codepages/CPKOI8-U.TXT
@@ -0,0 +1,262 @@
+#
+# UNIX Ukrainian (koi8-u) to UNICODE translation table
+#
+# Based on koi8u_uni.tbl from lynx 2.8.2 distribution
+# by porokh
+#
+0x00 0x0000 # NULL
+0x01 0x0001 # START OF HEADING
+0x02 0x0002 # START OF TEXT
+0x03 0x0003 # END OF TEXT
+0x04 0x0004 # END OF TRANSMISSION
+0x05 0x0005 # ENQUIRY
+0x06 0x0006 # ACKNOWLEDGE
+0x07 0x0007 # BELL
+0x08 0x0008 # BACKSPACE
+0x09 0x0009 # HORIZONTAL TABULATION
+0x0A 0x000A # LINE FEED
+0x0B 0x000B # VERTICAL TABULATION
+0x0C 0x000C # FORM FEED
+0x0D 0x000D # CARRIAGE RETURN
+0x0E 0x000E # SHIFT OUT
+0x0F 0x000F # SHIFT IN
+0x10 0x0010 # DATA LINK ESCAPE
+0x11 0x0011 # DEVICE CONTROL ONE
+0x12 0x0012 # DEVICE CONTROL TWO
+0x13 0x0013 # DEVICE CONTROL THREE
+0x14 0x0014 # DEVICE CONTROL FOUR
+0x15 0x0015 # NEGATIVE ACKNOWLEDGE
+0x16 0x0016 # SYNCHRONOUS IDLE
+0x17 0x0017 # END OF TRANSMISSION BLOCK
+0x18 0x0018 # CANCEL
+0x19 0x0019 # END OF MEDIUM
+0x1A 0x001A # SUBSTITUTE
+0x1B 0x001B # ESCAPE
+0x1C 0x001C # FILE SEPARATOR
+0x1D 0x001D # GROUP SEPARATOR
+0x1E 0x001E # RECORD SEPARATOR
+0x1F 0x001F # UNIT SEPARATOR
+0x20 0x0020 # SPACE
+0x21 0x0021 # EXCLAMATION MARK
+0x22 0x0022 # QUOTATION MARK
+0x23 0x0023 # NUMBER SIGN
+0x24 0x0024 # DOLLAR SIGN
+0x25 0x0025 # PERCENT SIGN
+0x26 0x0026 # AMPERSAND
+0x27 0x0027 # APOSTROPHE
+0x28 0x0028 # LEFT PARENTHESIS
+0x29 0x0029 # RIGHT PARENTHESIS
+0x2A 0x002A # ASTERISK
+0x2B 0x002B # PLUS SIGN
+0x2C 0x002C # COMMA
+0x2D 0x002D # HYPHEN-MINUS
+0x2E 0x002E # FULL STOP
+0x2F 0x002F # SOLIDUS
+0x30 0x0030 # DIGIT ZERO
+0x31 0x0031 # DIGIT ONE
+0x32 0x0032 # DIGIT TWO
+0x33 0x0033 # DIGIT THREE
+0x34 0x0034 # DIGIT FOUR
+0x35 0x0035 # DIGIT FIVE
+0x36 0x0036 # DIGIT SIX
+0x37 0x0037 # DIGIT SEVEN
+0x38 0x0038 # DIGIT EIGHT
+0x39 0x0039 # DIGIT NINE
+0x3A 0x003A # COLON
+0x3B 0x003B # SEMICOLON
+0x3C 0x003C # LESS-THAN SIGN
+0x3D 0x003D # EQUALS SIGN
+0x3E 0x003E # GREATER-THAN SIGN
+0x3F 0x003F # QUESTION MARK
+0x40 0x0040 # COMMERCIAL AT
+0x41 0x0041 # LATIN CAPITAL LETTER A
+0x42 0x0042 # LATIN CAPITAL LETTER B
+0x43 0x0043 # LATIN CAPITAL LETTER C
+0x44 0x0044 # LATIN CAPITAL LETTER D
+0x45 0x0045 # LATIN CAPITAL LETTER E
+0x46 0x0046 # LATIN CAPITAL LETTER F
+0x47 0x0047 # LATIN CAPITAL LETTER G
+0x48 0x0048 # LATIN CAPITAL LETTER H
+0x49 0x0049 # LATIN CAPITAL LETTER I
+0x4A 0x004A # LATIN CAPITAL LETTER J
+0x4B 0x004B # LATIN CAPITAL LETTER K
+0x4C 0x004C # LATIN CAPITAL LETTER L
+0x4D 0x004D # LATIN CAPITAL LETTER M
+0x4E 0x004E # LATIN CAPITAL LETTER N
+0x4F 0x004F # LATIN CAPITAL LETTER O
+0x50 0x0050 # LATIN CAPITAL LETTER P
+0x51 0x0051 # LATIN CAPITAL LETTER Q
+0x52 0x0052 # LATIN CAPITAL LETTER R
+0x53 0x0053 # LATIN CAPITAL LETTER S
+0x54 0x0054 # LATIN CAPITAL LETTER T
+0x55 0x0055 # LATIN CAPITAL LETTER U
+0x56 0x0056 # LATIN CAPITAL LETTER V
+0x57 0x0057 # LATIN CAPITAL LETTER W
+0x58 0x0058 # LATIN CAPITAL LETTER X
+0x59 0x0059 # LATIN CAPITAL LETTER Y
+0x5A 0x005A # LATIN CAPITAL LETTER Z
+0x5B 0x005B # LEFT SQUARE BRACKET
+0x5C 0x005C # REVERSE SOLIDUS
+0x5D 0x005D # RIGHT SQUARE BRACKET
+0x5E 0x005E # CIRCUMFLEX ACCENT
+0x5F 0x005F # LOW LINE
+0x60 0x0060 # GRAVE ACCENT
+0x61 0x0061 # LATIN SMALL LETTER A
+0x62 0x0062 # LATIN SMALL LETTER B
+0x63 0x0063 # LATIN SMALL LETTER C
+0x64 0x0064 # LATIN SMALL LETTER D
+0x65 0x0065 # LATIN SMALL LETTER E
+0x66 0x0066 # LATIN SMALL LETTER F
+0x67 0x0067 # LATIN SMALL LETTER G
+0x68 0x0068 # LATIN SMALL LETTER H
+0x69 0x0069 # LATIN SMALL LETTER I
+0x6A 0x006A # LATIN SMALL LETTER J
+0x6B 0x006B # LATIN SMALL LETTER K
+0x6C 0x006C # LATIN SMALL LETTER L
+0x6D 0x006D # LATIN SMALL LETTER M
+0x6E 0x006E # LATIN SMALL LETTER N
+0x6F 0x006F # LATIN SMALL LETTER O
+0x70 0x0070 # LATIN SMALL LETTER P
+0x71 0x0071 # LATIN SMALL LETTER Q
+0x72 0x0072 # LATIN SMALL LETTER R
+0x73 0x0073 # LATIN SMALL LETTER S
+0x74 0x0074 # LATIN SMALL LETTER T
+0x75 0x0075 # LATIN SMALL LETTER U
+0x76 0x0076 # LATIN SMALL LETTER V
+0x77 0x0077 # LATIN SMALL LETTER W
+0x78 0x0078 # LATIN SMALL LETTER X
+0x79 0x0079 # LATIN SMALL LETTER Y
+0x7A 0x007A # LATIN SMALL LETTER Z
+0x7B 0x007B # LEFT CURLY BRACKET
+0x7C 0x007C # VERTICAL LINE
+0x7D 0x007D # RIGHT CURLY BRACKET
+0x7E 0x007E # TILDE
+0x7F 0x007F # DELETE
+0x80 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL
+0x81 0x2502 # BOX DRAWINGS LIGHT VERTICAL
+0x82 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x83 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT
+0x85 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT
+0x86 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x87 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x88 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x89 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x8A 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x8B 0x2580 # UPPER HALF BLOCK
+0x8C 0x2584 # LOWER HALF BLOCK
+0x8D 0x2588 # FULL BLOCK
+0x8E 0x258C # LEFT HALF BLOCK
+0x8F 0x2590 # RIGHT HALF BLOCK
+0x90 0x2591 # LIGHT SHADE
+0x91 0x2592 # MEDIUM SHADE
+0x92 0x2593 # DARK SHADE
+0x93 0x2320 # TOP HALF INTEGRAL
+0x94 0x25A0 # BLACK SQUARE
+0x95 0x2219 # BULLET OPERATOR
+0x96 0x221A # SQUARE ROOT
+0x97 0x2248 # ALMOST EQUAL TO
+0x98 0x2264 # LESS THAN OR EQUAL TO
+0x99 0x2265 # GREATER THAN OR EQUAL TO
+0x9A 0x00A0 # NO-BREAK SPACE
+0x9B 0x2321 # BOTTOM HALF INTEGRAL
+0x9C 0x00B0 # DEGREE SIGN
+0x9D 0x00B2 # SUPERSCRIPT TWO
+0x9E 0x00B7 # MIDDLE DOT
+0x9F 0x00F7 # DIVISION SIGN
+0xA0 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL
+0xA1 0x2551 # BOX DRAWINGS DOUBLE VERTICAL
+0xA2 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xA3 0x0451 # CYRILLIC SMALL LETTER IO
+0xA4 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE
+0xA5 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xA6 0x0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xA7 0x0457 # CYRILLIC SMALL LETTER YI (UKRAINIAN)
+0xA8 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xA9 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xAA 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xAB 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT
+0xAC 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xAD 0x0491 # CYRILLIC SMALL LETTER GHE WITH UPTURN
+0xAE 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT
+0xAF 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xB0 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xB1 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xB2 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO
+0xB4 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xB5 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xB6 0x0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xB7 0x0407 # CYRILLIC CAPITAL LETTER YI (UKRAINIAN)
+0xB8 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xB9 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xBA 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xBB 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xBC 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xBD 0x0490 # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0xBE 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xBF 0x00A9 # COPYRIGHT SIGN
+0xC0 0x044E # CYRILLIC SMALL LETTER YU
+0xC1 0x0430 # CYRILLIC SMALL LETTER A
+0xC2 0x0431 # CYRILLIC SMALL LETTER BE
+0xC3 0x0446 # CYRILLIC SMALL LETTER TSE
+0xC4 0x0434 # CYRILLIC SMALL LETTER DE
+0xC5 0x0435 # CYRILLIC SMALL LETTER IE
+0xC6 0x0444 # CYRILLIC SMALL LETTER EF
+0xC7 0x0433 # CYRILLIC SMALL LETTER GHE
+0xC8 0x0445 # CYRILLIC SMALL LETTER KHA
+0xC9 0x0438 # CYRILLIC SMALL LETTER I
+0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I
+0xCB 0x043A # CYRILLIC SMALL LETTER KA
+0xCC 0x043B # CYRILLIC SMALL LETTER EL
+0xCD 0x043C # CYRILLIC SMALL LETTER EM
+0xCE 0x043D # CYRILLIC SMALL LETTER EN
+0xCF 0x043E # CYRILLIC SMALL LETTER O
+0xD0 0x043F # CYRILLIC SMALL LETTER PE
+0xD1 0x044F # CYRILLIC SMALL LETTER YA
+0xD2 0x0440 # CYRILLIC SMALL LETTER ER
+0xD3 0x0441 # CYRILLIC SMALL LETTER ES
+0xD4 0x0442 # CYRILLIC SMALL LETTER TE
+0xD5 0x0443 # CYRILLIC SMALL LETTER U
+0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE
+0xD7 0x0432 # CYRILLIC SMALL LETTER VE
+0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN
+0xD9 0x044B # CYRILLIC SMALL LETTER YERU
+0xDA 0x0437 # CYRILLIC SMALL LETTER ZE
+0xDB 0x0448 # CYRILLIC SMALL LETTER SHA
+0xDC 0x044D # CYRILLIC SMALL LETTER E
+0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA
+0xDE 0x0447 # CYRILLIC SMALL LETTER CHE
+0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN
+0xE0 0x042E # CYRILLIC CAPITAL LETTER YU
+0xE1 0x0410 # CYRILLIC CAPITAL LETTER A
+0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE
+0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE
+0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE
+0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE
+0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF
+0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE
+0xE8 0x0425 # CYRILLIC CAPITAL LETTER KHA
+0xE9 0x0418 # CYRILLIC CAPITAL LETTER I
+0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I
+0xEB 0x041A # CYRILLIC CAPITAL LETTER KA
+0xEC 0x041B # CYRILLIC CAPITAL LETTER EL
+0xED 0x041C # CYRILLIC CAPITAL LETTER EM
+0xEE 0x041D # CYRILLIC CAPITAL LETTER EN
+0xEF 0x041E # CYRILLIC CAPITAL LETTER O
+0xF0 0x041F # CYRILLIC CAPITAL LETTER PE
+0xF1 0x042F # CYRILLIC CAPITAL LETTER YA
+0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER
+0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES
+0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE
+0xF5 0x0423 # CYRILLIC CAPITAL LETTER U
+0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE
+0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE
+0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN
+0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU
+0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE
+0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA
+0xFC 0x042D # CYRILLIC CAPITAL LETTER E
+0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA
+0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE
+0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN
diff --git a/source/codepages/UnicodeData-Latest.txt b/source/codepages/UnicodeData-Latest.txt
new file mode 100755
index 00000000000..6a54d3d74e9
--- /dev/null
+++ b/source/codepages/UnicodeData-Latest.txt
@@ -0,0 +1,10617 @@
+0000;<control>;Cc;0;BN;;;;;N;NULL;;;;
+0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;
+0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;
+0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;
+0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;
+0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;
+0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;
+0007;<control>;Cc;0;BN;;;;;N;BELL;;;;
+0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;
+0009;<control>;Cc;0;S;;;;;N;HORIZONTAL TABULATION;;;;
+000A;<control>;Cc;0;B;;;;;N;LINE FEED;;;;
+000B;<control>;Cc;0;S;;;;;N;VERTICAL TABULATION;;;;
+000C;<control>;Cc;0;WS;;;;;N;FORM FEED;;;;
+000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN;;;;
+000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;
+000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;
+0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;
+0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;
+0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;
+0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;
+0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;
+0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;
+0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;
+0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;
+0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;
+0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;
+001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;
+001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;
+001C;<control>;Cc;0;B;;;;;N;FILE SEPARATOR;;;;
+001D;<control>;Cc;0;B;;;;;N;GROUP SEPARATOR;;;;
+001E;<control>;Cc;0;B;;;;;N;RECORD SEPARATOR;;;;
+001F;<control>;Cc;0;S;;;;;N;UNIT SEPARATOR;;;;
+0020;SPACE;Zs;0;WS;;;;;N;;;;;
+0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;
+0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;
+0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;
+0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+0026;AMPERSAND;Po;0;ON;;;;;N;;;;;
+0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;
+0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;
+0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;
+002A;ASTERISK;Po;0;ON;;;;;N;;;;;
+002B;PLUS SIGN;Sm;0;ET;;;;;N;;;;;
+002C;COMMA;Po;0;CS;;;;;N;;;;;
+002D;HYPHEN-MINUS;Pd;0;ET;;;;;N;;;;;
+002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;
+002F;SOLIDUS;Po;0;ES;;;;;N;SLASH;;;;
+0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;
+0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;
+0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;
+0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;
+0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;
+0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;
+0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;
+0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
+0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;
+0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;
+003A;COLON;Po;0;CS;;;;;N;;;;;
+003B;SEMICOLON;Po;0;ON;;;;;N;;;;;
+003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
+003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;
+0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;
+0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
+0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;
+0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;
+0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;
+0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;
+0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;
+0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;
+0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;
+0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;
+004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;
+004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;
+004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;
+004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;
+004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;
+004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;
+0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;
+0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;
+0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;
+0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;
+0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;
+0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;
+0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;
+0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;
+0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;
+0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;
+005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;
+005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;
+005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;
+005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;
+005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;
+005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;
+0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;
+0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
+0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042
+0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043
+0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044
+0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045
+0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046
+0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047
+0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048
+0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049
+006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A
+006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B
+006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C
+006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D
+006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E
+006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F
+0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050
+0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051
+0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052
+0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053
+0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054
+0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055
+0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056
+0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057
+0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058
+0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059
+007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
+007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;
+007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;
+007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;
+007E;TILDE;Sm;0;ON;;;;;N;;;;;
+007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;
+0080;<control>;Cc;0;BN;;;;;N;;;;;
+0081;<control>;Cc;0;BN;;;;;N;;;;;
+0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;
+0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;
+0084;<control>;Cc;0;BN;;;;;N;INDEX;;;;
+0085;<control>;Cc;0;B;;;;;N;NEXT LINE;;;;
+0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;
+0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;
+0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;
+0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;
+008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;
+008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE DOWN;;;;
+008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE UP;;;;
+008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;
+008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;
+008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;
+0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;
+0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;
+0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;
+0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;
+0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;
+0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;
+0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;
+0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;
+0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;
+0099;<control>;Cc;0;BN;;;;;N;;;;;
+009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;
+009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;
+009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;
+009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;
+009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;
+009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;
+00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
+00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;
+00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;
+00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;
+00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;
+00A7;SECTION SIGN;So;0;ON;;;;;N;;;;;
+00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;
+00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;
+00AA;FEMININE ORDINAL INDICATOR;Ll;0;L;<super> 0061;;;;N;;;;;
+00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;;
+00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;
+00AD;SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;
+00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;
+00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;
+00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;
+00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;
+00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;2;2;2;N;SUPERSCRIPT DIGIT TWO;;;;
+00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;3;3;3;N;SUPERSCRIPT DIGIT THREE;;;;
+00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;
+00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C
+00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;;
+00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;
+00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;1;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
+00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L;<super> 006F;;;;N;;;;;
+00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;;
+00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
+00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
+00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;
+00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;
+00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;
+00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;
+00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;
+00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;
+00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;
+00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;
+00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6;
+00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;
+00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;
+00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;
+00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;
+00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;
+00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;
+00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;
+00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;
+00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;
+00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0;
+00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;
+00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;
+00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;
+00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;
+00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;
+00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;
+00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;
+00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;
+00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;
+00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;
+00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;
+00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;
+00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;
+00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE;
+00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;;
+00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0
+00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1
+00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2
+00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3
+00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4
+00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5
+00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6
+00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7
+00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8
+00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9
+00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA
+00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB
+00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC
+00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD
+00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE
+00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF
+00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0
+00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1
+00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2
+00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3
+00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4
+00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5
+00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6
+00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8
+00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9
+00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA
+00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB
+00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC
+00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD
+00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE
+00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178
+0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101;
+0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100
+0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103;
+0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102
+0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105;
+0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104
+0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107;
+0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106
+0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109;
+0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108
+010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B;
+010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A
+010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;
+010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C
+010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F;
+010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E
+0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111;
+0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110
+0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113;
+0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112
+0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115;
+0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114
+0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117;
+0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116
+0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119;
+0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118
+011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B;
+011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A
+011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D;
+011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C
+011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F;
+011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E
+0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121;
+0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120
+0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123;
+0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122
+0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125;
+0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124
+0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127;
+0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126
+0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129;
+0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128
+012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
+012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
+012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D;
+012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C
+012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F;
+012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E
+0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069;
+0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
+0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L;<compat> 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133;
+0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
+0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135;
+0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134
+0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137;
+0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136
+0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;;
+0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
+013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139
+013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C;
+013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B
+013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E;
+013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D
+013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
+0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L;<compat> 006C 00B7;;;;N;;;013F;;013F
+0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142;
+0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141
+0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144;
+0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143
+0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146;
+0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145
+0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148;
+0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
+0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L;<compat> 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;;
+014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B;
+014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A
+014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D;
+014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C
+014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F;
+014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E
+0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151;
+0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150
+0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153;
+0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152
+0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155;
+0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154
+0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157;
+0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156
+0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159;
+0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158
+015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B;
+015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A
+015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D;
+015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C
+015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F;
+015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E
+0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161;
+0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160
+0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163;
+0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162
+0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165;
+0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164
+0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167;
+0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166
+0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169;
+0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168
+016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B;
+016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A
+016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D;
+016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C
+016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F;
+016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E
+0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171;
+0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170
+0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173;
+0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172
+0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175;
+0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174
+0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177;
+0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176
+0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF;
+0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A;
+017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179
+017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C;
+017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B
+017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E;
+017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D
+017F;LATIN SMALL LETTER LONG S;Ll;0;L;<compat> 0073;;;;N;;;0053;;0053
+0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;;;
+0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253;
+0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183;
+0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182
+0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185;
+0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184
+0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254;
+0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188;
+0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187
+0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256;
+018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257;
+018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C;
+018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B
+018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;;
+018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD;
+018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259;
+0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B;
+0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192;
+0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191
+0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260;
+0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263;
+0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6
+0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269;
+0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268;
+0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199;
+0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198
+019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;;;
+019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;;
+019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F;
+019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272;
+019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;;;
+019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275;
+01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1;
+01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0
+01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3;
+01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2
+01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5;
+01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4
+01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280;
+01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8;
+01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7
+01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283;
+01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;;
+01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;;
+01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD;
+01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC
+01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288;
+01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0;
+01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF
+01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A;
+01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B;
+01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4;
+01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3
+01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6;
+01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5
+01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292;
+01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9;
+01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8
+01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;;
+01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;;
+01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD;
+01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC
+01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;;
+01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7
+01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;;
+01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;;
+01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;;
+01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;;
+01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L;<compat> 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5
+01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L;<compat> 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;
+01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L;<compat> 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5
+01C7;LATIN CAPITAL LETTER LJ;Lu;0;L;<compat> 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8
+01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L;<compat> 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;
+01C9;LATIN SMALL LETTER LJ;Ll;0;L;<compat> 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8
+01CA;LATIN CAPITAL LETTER NJ;Lu;0;L;<compat> 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB
+01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L;<compat> 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;
+01CC;LATIN SMALL LETTER NJ;Ll;0;L;<compat> 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB
+01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE;
+01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD
+01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0;
+01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF
+01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2;
+01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1
+01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4;
+01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3
+01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;
+01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5
+01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;
+01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7
+01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;
+01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9
+01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;
+01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB
+01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E
+01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;
+01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE
+01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;
+01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0
+01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3;
+01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2
+01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;
+01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4
+01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;
+01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6
+01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;
+01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8
+01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
+01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA
+01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED;
+01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC
+01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF;
+01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE
+01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;;
+01F1;LATIN CAPITAL LETTER DZ;Lu;0;L;<compat> 0044 005A;;;;N;;;;01F3;01F2
+01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L;<compat> 0044 007A;;;;N;;;01F1;01F3;
+01F3;LATIN SMALL LETTER DZ;Ll;0;L;<compat> 0064 007A;;;;N;;;01F1;;01F2
+01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5;
+01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4
+01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195;
+01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF;
+01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9;
+01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8
+01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB;
+01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA
+01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD;
+01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC
+01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF;
+01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE
+0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201;
+0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200
+0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203;
+0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202
+0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205;
+0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204
+0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207;
+0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206
+0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209;
+0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208
+020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B;
+020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A
+020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D;
+020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C
+020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F;
+020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E
+0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211;
+0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210
+0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213;
+0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212
+0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215;
+0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214
+0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217;
+0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216
+0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219;
+0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218
+021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B;
+021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A
+021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D;
+021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C
+021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F;
+021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E
+0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223;
+0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222
+0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225;
+0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224
+0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227;
+0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226
+0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229;
+0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228
+022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B;
+022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A
+022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D;
+022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C
+022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F;
+022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E
+0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231;
+0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230
+0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233;
+0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232
+0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;;;
+0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;;;
+0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;;
+0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181
+0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186
+0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;;
+0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189
+0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A
+0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;;
+0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F
+025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;
+025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190
+025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;;
+025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;
+025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;
+025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;
+0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193
+0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;;
+0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;
+0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194
+0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;
+0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;;
+0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;;
+0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;
+0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197
+0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196
+026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;;
+026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;;
+026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;
+026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;
+026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C
+0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;;;
+0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D
+0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;;
+0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;;
+0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F
+0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;;
+0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;;
+0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;;
+0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;;
+027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;;
+027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;;;
+027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;;
+027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;
+0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6
+0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;
+0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;;
+0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9
+0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
+0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
+0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;
+0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;;
+0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE
+0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;;;
+028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1
+028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2
+028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;;;
+028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;;
+028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;;
+028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;;
+0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;;
+0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;;
+0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7
+0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;;
+0294;LATIN LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;;;
+0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;;
+0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;;
+0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;;
+0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;;
+0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;;
+029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;
+029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;
+029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;
+029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;;
+029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;;
+029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;
+02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;
+02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;
+02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;;
+02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;;
+02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;;
+02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;;
+02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;;
+02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;;
+02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;;
+02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02B0;MODIFIER LETTER SMALL H;Lm;0;L;<super> 0068;;;;N;;;;;
+02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L;<super> 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;;
+02B2;MODIFIER LETTER SMALL J;Lm;0;L;<super> 006A;;;;N;;;;;
+02B3;MODIFIER LETTER SMALL R;Lm;0;L;<super> 0072;;;;N;;;;;
+02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L;<super> 0279;;;;N;;;;;
+02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L;<super> 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;;
+02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L;<super> 0281;;;;N;;;;;
+02B7;MODIFIER LETTER SMALL W;Lm;0;L;<super> 0077;;;;N;;;;;
+02B8;MODIFIER LETTER SMALL Y;Lm;0;L;<super> 0079;;;;N;;;;;
+02B9;MODIFIER LETTER PRIME;Sk;0;ON;;;;;N;;;;;
+02BA;MODIFIER LETTER DOUBLE PRIME;Sk;0;ON;;;;;N;;;;;
+02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;;
+02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;;
+02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;;
+02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;;
+02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;;
+02C7;CARON;Sk;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;;
+02C8;MODIFIER LETTER VERTICAL LINE;Sk;0;ON;;;;;N;;;;;
+02C9;MODIFIER LETTER MACRON;Sk;0;ON;;;;;N;;Mandarin Chinese first tone;;;
+02CA;MODIFIER LETTER ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;;
+02CB;MODIFIER LETTER GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;;
+02CC;MODIFIER LETTER LOW VERTICAL LINE;Sk;0;ON;;;;;N;;;;;
+02CD;MODIFIER LETTER LOW MACRON;Sk;0;ON;;;;;N;;;;;
+02CE;MODIFIER LETTER LOW GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;;
+02CF;MODIFIER LETTER LOW ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;;
+02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;;
+02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;;
+02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;;
+02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;;
+02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D8;BREVE;Sk;0;ON;<compat> 0020 0306;;;;N;SPACING BREVE;;;;
+02D9;DOT ABOVE;Sk;0;ON;<compat> 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;;
+02DA;RING ABOVE;Sk;0;ON;<compat> 0020 030A;;;;N;SPACING RING ABOVE;;;;
+02DB;OGONEK;Sk;0;ON;<compat> 0020 0328;;;;N;SPACING OGONEK;;;;
+02DC;SMALL TILDE;Sk;0;ON;<compat> 0020 0303;;;;N;SPACING TILDE;;;;
+02DD;DOUBLE ACUTE ACCENT;Sk;0;ON;<compat> 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;;
+02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;;
+02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;;
+02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L;<super> 0263;;;;N;;;;;
+02E1;MODIFIER LETTER SMALL L;Lm;0;L;<super> 006C;;;;N;;;;;
+02E2;MODIFIER LETTER SMALL S;Lm;0;L;<super> 0073;;;;N;;;;;
+02E3;MODIFIER LETTER SMALL X;Lm;0;L;<super> 0078;;;;N;;;;;
+02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L;<super> 0295;;;;N;;;;;
+02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EC;MODIFIER LETTER VOICING;Sk;0;ON;;;;;N;;;;;
+02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;;
+02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;;
+0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;;
+0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia;;;
+0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;;
+0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;;
+0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;;
+0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;;
+0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;;
+0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;;
+0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;;
+0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;;
+030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;;
+030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;;
+030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;;
+030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;Tonos;;;
+030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;;
+030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;;
+0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;;
+0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;;
+0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;;
+0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;;
+0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;;
+0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;;
+0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;;
+0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;;
+0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;;
+0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;;
+031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;;
+031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;;
+031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;;
+031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;;
+031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;;
+031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;;
+0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;;
+0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;;
+0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;;
+0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;;
+0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;;
+0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;;
+0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;;
+0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;;
+0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;;
+0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;;
+032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;;
+032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;;
+032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;;
+032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;;
+032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;;
+032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;;
+0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;;
+0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;;
+0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;;
+0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;;
+0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;;
+0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;;
+0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;;
+0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;;
+0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;;
+0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;;
+033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;;
+033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;;
+033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;;
+033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;;
+033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;;
+033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;;
+0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;;
+0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;;
+0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;;
+0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;;
+0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;;
+0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399
+0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
+0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;;
+034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;;
+034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;;
+034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;;
+034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;;
+0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;;
+0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;;
+0374;GREEK NUMERAL SIGN;Sk;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;;
+0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;;
+037A;GREEK YPOGEGRAMMENI;Lm;0;L;<compat> 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;;
+037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;;
+0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;
+0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;
+0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;
+0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;;
+0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD;
+0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE;
+038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF;
+038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC;
+038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD;
+038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE;
+0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;;
+0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1;
+0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2;
+0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3;
+0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4;
+0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5;
+0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6;
+0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7;
+0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
+0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9;
+039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA;
+039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB;
+039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC;
+039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD;
+039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE;
+039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF;
+03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0;
+03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1;
+03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3;
+03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4;
+03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5;
+03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6;
+03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7;
+03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8;
+03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9;
+03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA;
+03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB;
+03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386
+03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388
+03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389
+03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A
+03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;;
+03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391
+03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392
+03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393
+03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394
+03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395
+03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396
+03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397
+03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
+03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399
+03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A
+03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B
+03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C
+03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D
+03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E
+03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F
+03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0
+03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1
+03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4
+03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5
+03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6
+03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7
+03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8
+03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9
+03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA
+03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB
+03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C
+03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E
+03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F
+03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392
+03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
+03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L;<compat> 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;;
+03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;;
+03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;;
+03D5;GREEK PHI SYMBOL;Ll;0;L;<compat> 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6
+03D6;GREEK PI SYMBOL;Ll;0;L;<compat> 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0
+03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;;;
+03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB;
+03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA
+03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD;
+03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC
+03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF;
+03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE
+03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1;
+03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0
+03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3;
+03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2
+03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5;
+03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4
+03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7;
+03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6
+03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9;
+03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8
+03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB;
+03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA
+03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED;
+03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC
+03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF;
+03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE
+03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A
+03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1
+03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03A3;;03A3
+03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;;
+0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450;
+0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451;
+0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452;
+0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453;
+0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454;
+0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455;
+0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456;
+0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457;
+0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458;
+0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459;
+040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A;
+040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B;
+040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C;
+040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D;
+040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E;
+040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F;
+0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;
+0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431;
+0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432;
+0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433;
+0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434;
+0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435;
+0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436;
+0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437;
+0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438;
+0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439;
+041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A;
+041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B;
+041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C;
+041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D;
+041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E;
+041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F;
+0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440;
+0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441;
+0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442;
+0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443;
+0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444;
+0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445;
+0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446;
+0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447;
+0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448;
+0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449;
+042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A;
+042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B;
+042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C;
+042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D;
+042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E;
+042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F;
+0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410
+0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411
+0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412
+0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413
+0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414
+0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415
+0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416
+0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417
+0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418
+0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419
+043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A
+043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B
+043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C
+043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D
+043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E
+043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F
+0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420
+0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421
+0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422
+0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423
+0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424
+0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425
+0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426
+0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427
+0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428
+0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429
+044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
+044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B
+044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C
+044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D
+044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E
+044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F
+0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400
+0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401
+0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402
+0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403
+0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404
+0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405
+0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406
+0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407
+0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408
+0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409
+045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A
+045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B
+045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C
+045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D
+045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E
+045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F
+0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461;
+0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460
+0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463;
+0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462
+0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465;
+0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464
+0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467;
+0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466
+0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469;
+0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468
+046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B;
+046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A
+046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D;
+046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C
+046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F;
+046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E
+0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471;
+0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470
+0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473;
+0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472
+0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475;
+0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474
+0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477;
+0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476
+0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479;
+0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478
+047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B;
+047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A
+047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D;
+047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C
+047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F;
+047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E
+0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481;
+0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480
+0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;;
+0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;;
+0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;;
+0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;;
+0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;;
+0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;
+0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D;
+048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C
+048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F;
+048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E
+0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491;
+0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490
+0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493;
+0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492
+0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495;
+0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494
+0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497;
+0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496
+0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499;
+0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498
+049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B;
+049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A
+049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D;
+049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C
+049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F;
+049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E
+04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1;
+04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0
+04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3;
+04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2
+04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5;
+04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4
+04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7;
+04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6
+04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9;
+04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8
+04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB;
+04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA
+04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD;
+04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC
+04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF;
+04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE
+04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1;
+04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0
+04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3;
+04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2
+04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5;
+04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4
+04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7;
+04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6
+04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9;
+04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8
+04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB;
+04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA
+04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD;
+04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC
+04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF;
+04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE
+04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;;
+04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2;
+04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1
+04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4;
+04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3
+04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8;
+04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7
+04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC;
+04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB
+04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1;
+04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0
+04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3;
+04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2
+04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5;
+04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4
+04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7;
+04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6
+04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9;
+04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8
+04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB;
+04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA
+04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD;
+04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC
+04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF;
+04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE
+04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1;
+04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0
+04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3;
+04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2
+04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5;
+04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4
+04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7;
+04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6
+04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9;
+04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8
+04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB;
+04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA
+04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED;
+04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC
+04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF;
+04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE
+04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1;
+04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0
+04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3;
+04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2
+04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5;
+04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4
+04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9;
+04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8
+0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;
+0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;
+0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;
+0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564;
+0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565;
+0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566;
+0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567;
+0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568;
+0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569;
+053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A;
+053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B;
+053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C;
+053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D;
+053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E;
+053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F;
+0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570;
+0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571;
+0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572;
+0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573;
+0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574;
+0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575;
+0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576;
+0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577;
+0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578;
+0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579;
+054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;
+054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B;
+054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C;
+054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D;
+054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E;
+054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F;
+0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580;
+0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581;
+0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582;
+0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583;
+0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584;
+0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585;
+0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586;
+0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;;
+055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;;
+055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;;
+055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;;
+055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;;
+055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;;
+0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531
+0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532
+0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533
+0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534
+0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535
+0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536
+0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537
+0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538
+0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539
+056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A
+056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B
+056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C
+056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D
+056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E
+056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F
+0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540
+0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541
+0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542
+0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543
+0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544
+0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545
+0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546
+0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547
+0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548
+0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549
+057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A
+057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B
+057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C
+057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D
+057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E
+057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F
+0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550
+0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551
+0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552
+0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553
+0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554
+0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555
+0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556
+0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;
+0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;
+058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;
+0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;
+0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;
+0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;
+0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;;
+0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;;
+0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;;
+0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;;
+0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;;
+0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;;
+059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;;
+059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;;
+059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;;
+059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;;
+059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;;
+059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;;
+05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;;
+05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;;
+05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;;
+05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;;
+05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;;
+05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;;
+05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;;
+05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;;
+05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;;
+05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;;
+05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;;
+05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;;
+05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;;
+05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;;
+05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;;
+05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;;
+05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;;
+05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;;
+05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;;
+05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;;
+05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;;
+05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;;
+05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;;
+05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;;
+05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;;
+05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;;
+05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;;
+05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;;
+05BE;HEBREW PUNCTUATION MAQAF;Po;0;R;;;;;N;;;;;
+05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;;
+05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;;
+05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;;
+05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;;
+05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;;
+05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;;
+05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;;
+05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;;
+05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;;
+05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;;
+05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;;
+05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;;
+05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;;
+05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;;
+05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;;
+05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;;
+05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;;
+05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
+05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;;
+05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;;
+05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;;
+05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;;
+05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;;
+05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;;
+05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;;
+05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;;
+05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;;
+05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;;
+05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;;
+05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;;
+05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;;
+05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;;
+05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;;
+05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;;
+060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;;
+061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
+061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
+0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;
+0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;
+0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;
+0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;;
+0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;;
+0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;;
+0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;;
+0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;;
+0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;;
+062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;;
+062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;;
+062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;;
+062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;;
+062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;;
+062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;;
+0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;;
+0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;;
+0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;;
+0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;;
+0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;;
+0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;;
+0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;;
+0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;;
+0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;;
+063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;;
+0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;;
+0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;;
+0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;;
+0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;;
+0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;;
+0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;;
+0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;;
+0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;;
+0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;;
+064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;;
+064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;;
+064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;;
+064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;;
+064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;;
+064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;;
+0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;;
+0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;;
+0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;;
+0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;;
+0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
+0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;
+0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;
+0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;
+0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;
+0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;
+0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;
+0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;
+0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;
+0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;
+0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;
+066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;;
+066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;;
+066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;;
+0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;;
+0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;;
+0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;;
+0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;;
+0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;;
+0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL;<compat> 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;;
+0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL;<compat> 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;;
+0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL;<compat> 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;;
+0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL;<compat> 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;;
+0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;;
+067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;;
+067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;;
+067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;;
+067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;;
+067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;;
+067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;;
+0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;;
+0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;;
+0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;;
+0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;;
+0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;;
+0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;;
+0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;;
+0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;;
+0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;;
+0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;;
+068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
+068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;;
+068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;;
+068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;;
+068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;;
+0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;;
+0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;;
+0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;;
+0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;;
+0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;;
+0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;;
+0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;;
+0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;;
+0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;;
+069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;;
+06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;;
+06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;;
+06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;;
+06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;;
+06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;;
+06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;;
+06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;;
+06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;;
+06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;;
+06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;;
+06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;;
+06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;;
+06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;;
+06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;;
+06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;;
+06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;;
+06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;;
+06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;;
+06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;;
+06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;;
+06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;;
+06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;;
+06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;;
+06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;;
+06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;;
+06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;;
+06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;;
+06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;;
+06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;;
+06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;;
+06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;;
+06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;;
+06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;;
+06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;;
+06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;;
+06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;;
+06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;;
+06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;;
+06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;;
+06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;;
+06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;;
+06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;;
+06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
+06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
+06DD;ARABIC END OF AYAH;Me;0;NSM;;;;;N;;;;;
+06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;;
+06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
+06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
+06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
+06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;;
+06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;;
+06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;;
+06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;;
+06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;;
+06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;;
+06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;;
+06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;;
+06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;;
+06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;;
+06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;;
+06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;;
+06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;;
+06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;;
+06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;;
+06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;;
+06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;;
+06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;;
+06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;;
+06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;;
+06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;;
+06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;;
+06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;;
+06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;;
+0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;;
+0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;;
+0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;;
+0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;;
+0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;;
+070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;
+070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;
+070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;
+070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;;
+0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;
+0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;
+0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;
+0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;;
+0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;;
+0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;;
+0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;;
+0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;;
+0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;;
+071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;;
+071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;;
+071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;;
+071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;;
+071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;;
+0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;;
+0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;;
+0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;;
+0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;;
+0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;;
+0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;;
+0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;;
+0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;;
+0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;;
+0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;;
+072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;;
+072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;;
+072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;;
+0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;;
+0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;;
+073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;;
+073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;;
+0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;;
+0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;;
+0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;;
+0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;;
+074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;;
+0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;;
+0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;;
+0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;;
+0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;;
+0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;;
+0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;;
+0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;;
+0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;;
+078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;;
+078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;;
+078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;;
+078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;;
+078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;;
+078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;;
+0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;;
+0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;;
+0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;;
+0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;;
+0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;;
+0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;;
+0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;;
+0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;;
+0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;;
+079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;;
+079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;;
+079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;;
+079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;;
+079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;;
+079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;;
+07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;;
+07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;;
+07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;;
+07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;;
+07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;;
+07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;;
+07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;;
+07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;;
+07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;;
+07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;;
+07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;;
+07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;;
+07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;;
+07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;;
+07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;;
+07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;;
+07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;;
+0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;;
+0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
+0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;;
+0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;;
+0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;;
+090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;;
+090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;;
+090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;;
+090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;;
+0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;;
+0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;;
+0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;;
+0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;;
+0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;;
+0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;;
+0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;;
+0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;
+091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;;
+091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;
+091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;;
+091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;
+091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;
+091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;;
+0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;;
+0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;;
+0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;;
+0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;;
+092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;;
+092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;
+092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;;
+092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;
+092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;;
+092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;;
+0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;;
+0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;;
+0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;;
+0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;;
+0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;;
+0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
+0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
+093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
+0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
+094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;
+0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;
+0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;
+0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;
+0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;
+095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;
+095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;;
+095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;;
+095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;;
+095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;;
+095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;;
+0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;;
+0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;;
+0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;;
+0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;;
+0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;;
+0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;;
+098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;;
+098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;;
+0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;;
+0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;;
+0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;;
+0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;;
+0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;;
+0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;;
+099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;;
+099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;;
+099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;;
+099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;;
+099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;;
+099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;;
+09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;;
+09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;;
+09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;;
+09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;;
+09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;;
+09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;;
+09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;;
+09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;;
+09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;;
+09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;;
+09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;;
+09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;;
+09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;;
+09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;;
+09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;;
+09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;;
+09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;;
+09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;;
+09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;;
+09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;;
+09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;;
+09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;;
+09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;;
+09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;;
+09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;;
+09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;;
+09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;;
+09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;;
+09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;;
+09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;;
+09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;;
+09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;;
+09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
+09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
+0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
+0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;;
+0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;;
+0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;;
+0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;;
+0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;;
+0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;;
+0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;;
+0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;;
+0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;;
+0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;;
+0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;;
+0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;;
+0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;;
+0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;;
+0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;;
+0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;;
+0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;;
+0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;;
+0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;;
+0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;;
+0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;;
+0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;;
+0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;;
+0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;;
+0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;;
+0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;;
+0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;;
+0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;;
+0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;;
+0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;;
+0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;;
+0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;;
+0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;;
+0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;;
+0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;;
+0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;;
+0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;;
+0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;;
+0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;;
+0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;;
+0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;;
+0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;;
+0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;;
+0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;;
+0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;;
+0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;;
+0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;;
+0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;;
+0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;;
+0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;;
+0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;;
+0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;;
+0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;;
+0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;;
+0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;;
+0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;;
+0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;;
+0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;;
+0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;;
+0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;;
+0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;;
+0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;;
+0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;;
+0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;;
+0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;;
+0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;;
+0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;;
+0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;;
+0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;;
+0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;;
+0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;;
+0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;;
+0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;;
+0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;;
+0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;;
+0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;;
+0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;;
+0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;;
+0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;;
+0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;;
+0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;
+0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;
+0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;
+0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;;
+0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;;
+0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;
+0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0B83;TAMIL SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;
+0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;;
+0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;;
+0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;;
+0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;;
+0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;;
+0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;;
+0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;;
+0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;;
+0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;;
+0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;;
+0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;;
+0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;;
+0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;;
+0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;;
+0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;;
+0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;;
+0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;;
+0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;;
+0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;;
+0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;;
+0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;;
+0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;;
+0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;;
+0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;;
+0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;;
+0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;;
+0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;;
+0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;;
+0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;;
+0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;;
+0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;;
+0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;;
+0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;;
+0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;;
+0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;;
+0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;;
+0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;;
+0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;;
+0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;;
+0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;;
+0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;;
+0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;;
+0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;;
+0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;;
+0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;;
+0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;;
+0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;;
+0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;;
+0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;;
+0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;;
+0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;;
+0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;;
+0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;;
+0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;;
+0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;;
+0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;;
+0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;;
+0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;;
+0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;;
+0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;;
+0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;;
+0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;;
+0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;;
+0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;;
+0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;;
+0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;
+0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;
+0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;
+0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;
+0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;
+0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
+0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
+0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
+0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;;
+0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;;
+0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;
+0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;
+0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;;
+0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;;
+0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;;
+0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;;
+0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;;
+0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;;
+0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;;
+0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;;
+0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;;
+0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;;
+0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;;
+0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;;
+0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;;
+0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;;
+0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;;
+0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;;
+0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;;
+0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;;
+0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;;
+0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;;
+0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;;
+0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;;
+0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;;
+0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;;
+0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;;
+0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;;
+0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;;
+0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;;
+0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;;
+0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0CBF;KANNADA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;;
+0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0CC6;KANNADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;;
+0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;;
+0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;;
+0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;;
+0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
+0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
+0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;
+0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;
+0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;;
+0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;;
+0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;;
+0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;;
+0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;;
+0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;;
+0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;;
+0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;;
+0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;;
+0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;;
+0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;;
+0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;;
+0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;;
+0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;;
+0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;;
+0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;;
+0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;;
+0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;
+0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;
+0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;
+0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;
+0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;;
+0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;;
+0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;;
+0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;;
+0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;;
+0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;;
+0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;;
+0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;;
+0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
+0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
+0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;;
+0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;
+0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;
+0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;
+0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;
+0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;
+0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;;
+0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;;
+0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;;
+0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;;
+0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;;
+0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;;
+0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;;
+0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;;
+0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;;
+0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;;
+0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;;
+0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;;
+0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;;
+0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;;
+0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;;
+0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;;
+0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;;
+0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;;
+0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;;
+0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;;
+0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;;
+0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;;
+0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;;
+0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;;
+0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;;
+0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;;
+0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;;
+0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;;
+0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;;
+0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;
+0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;
+0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;
+0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;;
+0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;;
+0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;;
+0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;;
+0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;;
+0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;;
+0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;;
+0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;;
+0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;;
+0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;;
+0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;;
+0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;;
+0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;;
+0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;;
+0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;;
+0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;;
+0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;;
+0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;;
+0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;;
+0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;;
+0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;;
+0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;;
+0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;;
+0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;;
+0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;;
+0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;;
+0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;;
+0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;;
+0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;;
+0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;;
+0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;;
+0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;;
+0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;;
+0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;;
+0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;;
+0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;;
+0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;;
+0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;;
+0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;;
+0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;;
+0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;;
+0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;;
+0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;;
+0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;;
+0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;;
+0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;;
+0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;;
+0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;;
+0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;;
+0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;;
+0E33;THAI CHARACTER SARA AM;Lo;0;L;<compat> 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;;
+0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;;
+0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;;
+0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;;
+0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;;
+0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;;
+0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;;
+0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;;
+0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;;
+0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;;
+0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;;
+0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;;
+0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;;
+0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;;
+0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;;
+0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;;
+0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;;
+0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;;
+0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;;
+0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;;
+0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;;
+0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;;
+0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;;
+0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;;
+0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;;
+0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;;
+0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;;
+0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;
+0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;
+0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;
+0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;
+0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;
+0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;
+0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;
+0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;
+0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;
+0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;
+0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;
+0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;
+0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;
+0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;
+0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;;
+0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;
+0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;
+0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;
+0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;
+0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;
+0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;
+0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;
+0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;
+0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;
+0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;
+0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;
+0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;
+0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;
+0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;;
+0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;;
+0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
+0EB3;LAO VOWEL SIGN AM;Lo;0;L;<compat> 0ECD 0EB2;;;;N;;;;;
+0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;
+0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;
+0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;
+0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;
+0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;
+0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
+0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;;
+0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
+0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
+0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;;
+0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;;
+0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;;
+0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;;
+0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;;
+0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
+0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
+0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
+0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;
+0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;
+0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;
+0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;;
+0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;;
+0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;;
+0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;;
+0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;;
+0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;;
+0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;;
+0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;;
+0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;;
+0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;;
+0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;;
+0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L;<noBreak> 0F0B;;;;N;;tsek tar;;;
+0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;;
+0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;;
+0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;;
+0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;;
+0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;;
+0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;;
+0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;;
+0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;;
+0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;;
+0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;;
+0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;;
+0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;;
+0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;;
+0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;;
+0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;;
+0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;;
+0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;;
+0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;;
+0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;;
+0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;;N;;;;;
+0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;;N;;;;;
+0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;;N;;;;;
+0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;;N;;;;;
+0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;;N;;;;;
+0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;;N;;;;;
+0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;;N;;;;;
+0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;;N;;;;;
+0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;;N;;;;;
+0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;;N;;;;;
+0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;;
+0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;;
+0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;;
+0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;;
+0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;;
+0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;;
+0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;N;;gug ta yun;;;
+0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;N;;gug ta ye;;;
+0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;N;TIBETAN LEFT BRACE;ang kang yun;;;
+0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;N;TIBETAN RIGHT BRACE;ang kang ye;;;
+0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;;
+0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;;
+0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;;
+0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;;
+0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;;
+0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;;
+0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;;
+0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;;
+0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;;
+0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;;
+0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;;
+0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;;
+0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;;
+0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;;
+0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;;
+0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;;
+0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;;
+0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;;
+0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;;
+0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;;
+0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;;
+0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;;
+0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;;
+0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;;
+0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;;
+0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;;
+0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;;
+0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;;
+0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;;
+0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;;
+0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;;
+0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;;
+0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;;
+0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;;
+0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;;
+0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;;
+0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;;
+0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;;
+0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;;
+0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;;
+0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;;
+0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;;
+0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;;
+0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;;
+0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM;<compat> 0FB2 0F81;;;;N;;;;;
+0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;;
+0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM;<compat> 0FB3 0F81;;;;N;;;;;
+0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;;
+0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;;
+0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;;
+0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;;
+0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;;
+0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;;
+0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;;
+0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;;
+0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;;
+0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;;
+0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;;
+0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;;
+0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;;
+0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;;
+0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;;
+0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;;
+0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;;
+0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;;
+0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
+0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
+0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
+0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;;
+0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
+0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
+0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
+0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
+0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
+0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;;
+0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;;
+0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;;
+0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;;
+0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;;
+0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
+0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
+0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
+0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;;
+0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
+0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
+0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
+0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
+0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;;
+0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
+0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
+0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
+0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
+0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;;
+0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;;
+0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
+0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
+0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;;
+0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;;
+0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;;
+0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
+0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
+0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;;
+0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
+0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
+0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
+0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;;
+0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;;
+0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;;
+0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;;
+0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;;
+0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;;
+0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;;
+0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;;
+0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;;
+0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;;
+0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;;
+0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;;
+0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;;
+0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;;
+0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;;
+0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;;
+0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;;
+0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;;
+0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;;
+0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;;
+1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;
+1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;
+1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;
+1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;;
+1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;;
+1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;;
+1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;;
+1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;;
+1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;;
+1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;;
+100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;;
+100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;;
+100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;;
+100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;;
+100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;;
+100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;;
+1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;;
+1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;;
+1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;;
+1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;;
+1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;;
+1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;;
+1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;;
+1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;;
+1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;;
+1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;;
+101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;;
+101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;;
+101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;;
+101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;;
+101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;;
+101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;;
+1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;;
+1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;;
+1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;;
+1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;;
+1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;;
+1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;;
+1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;;
+1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;;
+102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;;
+102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;;
+1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;;
+104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;;
+104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;;
+104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;;
+104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;;
+104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;;
+1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;;
+1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;;
+1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;;
+10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;;
+10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;;
+10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;;
+10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;;
+10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;;
+10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;;
+10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;;
+10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;;
+10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;;
+10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;;
+10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;;
+10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;;
+10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;;
+10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;;
+10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;;
+10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;;
+10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;;
+10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;;
+10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;;
+10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;;
+10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;;
+10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;;
+10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;;
+10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;;
+10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;;
+10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;;
+10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;;
+10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;;
+10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;;
+10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;;
+10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;;
+10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;;
+10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;;
+10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;;
+10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;;
+10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;;
+10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;;
+10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;;
+10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;;
+10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;;
+10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;;
+10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;;
+10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;;
+10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;;
+10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;;
+10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;;
+10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;;
+10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;;
+10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;;
+10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;;
+10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;;
+10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;;
+10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;;
+10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;;
+10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;;
+10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;;
+1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;;
+1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;;
+1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;;
+1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;;
+1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;;
+1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;;
+1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;;
+1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;;
+1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;;
+110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;;
+110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;;
+110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;;
+110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;;
+110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;;
+110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;;
+1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;;
+1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;;
+1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;;
+1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;;
+1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
+111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
+111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;;
+1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
+1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;;
+112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;;
+112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;;
+112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
+1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;;
+1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;;
+113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
+113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;;
+113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;;
+113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;;
+1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
+1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;;
+1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;;
+1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;;
+114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;;
+114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;;
+114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;;
+114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;;
+114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;;
+1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;;
+1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;;
+1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;;
+1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;;
+1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;;
+1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;;
+1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;;
+1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;;
+1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;;
+1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;;
+1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;;
+116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;;
+116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;;
+116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;;
+116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;;
+116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;;
+116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;;
+1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;;
+1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;;
+1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;;
+1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;;
+1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;;
+1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;;
+1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;;
+1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;;
+1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;;
+1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;;
+117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;;
+117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;;
+117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;;
+117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;;
+117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;;
+117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;;
+1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;;
+1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;;
+1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;;
+1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;;
+1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;;
+1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;;
+1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;;
+1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;;
+1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;;
+1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;;
+118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;;
+118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;;
+118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;;
+118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;;
+118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;;
+118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;;
+1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;;
+1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;;
+1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;;
+1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;;
+1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;;
+1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;;
+1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;;
+1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;;
+1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;;
+1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;;
+119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;;
+119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;;
+119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;;
+119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;;
+119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;;
+119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;;
+11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;;
+11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;;
+11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;;
+11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;;
+11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;;
+11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;;
+11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;;
+11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;;
+11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;;
+11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;;
+11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;;
+11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;;
+11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;;
+11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;;
+11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;;
+11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;;
+11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;;
+11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;;
+11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;;
+11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;;
+11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;;
+11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;;
+11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;;
+11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;;
+11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;;
+11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;;
+11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;;
+11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;;
+11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;;
+11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;;
+11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;;
+11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
+11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;;
+11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;;
+11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
+11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
+11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
+11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;;
+11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;;
+11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;;
+11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;;
+11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;;
+11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
+11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;;
+11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;;
+11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;;
+11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;;
+11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;;
+1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;;
+1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;;
+1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
+1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;;
+120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
+120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;;
+1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;;
+1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;;
+1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;;
+1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;;
+1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;;
+1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;;
+1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;;
+1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;;
+1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;;
+121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
+121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;;
+1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;;
+1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;;
+1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;;
+1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;;
+1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;;
+1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;;
+1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;;
+1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;;
+1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;;
+122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;;
+122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;;
+122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;;
+1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;;
+1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
+1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;;
+1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
+123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;;
+123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
+123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;;
+1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;;
+1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;;
+1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;;
+1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;;
+1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;;
+124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;;
+124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;;
+124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;;
+124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;;
+1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;;
+1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;;
+1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;;
+1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;;
+1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;;
+1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;;
+1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;;
+1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;;
+125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;;
+125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;;
+125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;;
+125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;;
+1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;;
+1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
+1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;;
+1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;;
+126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
+126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;;
+126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;;
+1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;;
+1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
+1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;;
+1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;;
+127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
+127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;;
+1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;;
+1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;;
+1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;;
+1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;;
+1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;;
+1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;;
+128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;;
+128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;;
+128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;;
+128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;;
+1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;;
+1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
+1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;;
+1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
+1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;;
+129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
+129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
+129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;;
+12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;;
+12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;;
+12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;;
+12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;;
+12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;;
+12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;;
+12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;;
+12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;;
+12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;;
+12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
+12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;;
+12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;;
+12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;;
+12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;;
+12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;;
+12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;;
+12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;;
+12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;;
+12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;;
+12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;;
+12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;;
+12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;;
+12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;;
+12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;;
+12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;;
+12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;;
+12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;;
+12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;;
+12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;;
+12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
+12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;;
+12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;;
+12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;;
+12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;;
+12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;;
+12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;;
+12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;;
+12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;;
+12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
+12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;;
+12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
+12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;;
+12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
+12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;;
+12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;;
+12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;;
+12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
+12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;;
+12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;;
+12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
+12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;;
+12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;;
+12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;;
+12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;;
+1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;;
+1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;;
+1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
+1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;;
+1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;;
+1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;;
+130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
+130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;;
+1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;;
+1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;;
+1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;;
+1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;;
+1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;;
+131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;;
+131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;;
+1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;;
+1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;;
+1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;;
+1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
+1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;;
+1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;;
+1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;;
+1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;;
+132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;;
+132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;;
+132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;;
+1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;;
+1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;;
+1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;;
+1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;;
+1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;;
+1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;;
+1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;;
+1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;;
+1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;;
+1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;;
+133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;;
+133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;;
+133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;;
+133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;;
+133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;;
+133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;;
+1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;;
+1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;;
+1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;;
+1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;;
+1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;;
+1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;;
+1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;;
+1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;;
+134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
+134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;;
+134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;;
+1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;;
+1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
+1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;;
+1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;;
+1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;
+1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;
+135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;
+1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;
+1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;
+1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;
+1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;;
+1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;;
+1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;;
+1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;;
+1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+1369;ETHIOPIC DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+136A;ETHIOPIC DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+136B;ETHIOPIC DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+136C;ETHIOPIC DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+136D;ETHIOPIC DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+136E;ETHIOPIC DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+136F;ETHIOPIC DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1370;ETHIOPIC DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1371;ETHIOPIC DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;;
+1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
+1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
+137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;;
+137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
+13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;;
+13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;;
+13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;;
+13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;;
+13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;;
+13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;;
+13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;;
+13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;;
+13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;;
+13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;;
+13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;;
+13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;;
+13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;;
+13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;;
+13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;;
+13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;;
+13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;;
+13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;;
+13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;;
+13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;;
+13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;;
+13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;;
+13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;;
+13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;;
+13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;;
+13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;;
+13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;;
+13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;;
+13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;;
+13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;;
+13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;;
+13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;;
+13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;;
+13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;;
+13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;;
+13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;;
+13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;;
+13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;;
+13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;;
+13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;;
+13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;;
+13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;;
+13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;;
+13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;;
+13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;;
+13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;;
+13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;;
+13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;;
+13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;;
+13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;;
+13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;;
+13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;;
+13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;;
+13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;;
+13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;;
+13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;;
+13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;;
+13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;;
+13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;;
+13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;;
+13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;;
+13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;;
+13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;;
+13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;;
+13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;;
+13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;;
+13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;;
+13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;;
+13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;;
+13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;;
+13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;;
+13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;;
+13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;;
+13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;;
+13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;;
+13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;;
+13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;;
+13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;;
+13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;;
+13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;;
+13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;;
+13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;;
+13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;;
+13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;;
+13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;;
+1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;
+1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;
+1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;;
+1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;;
+1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;;
+1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;;
+1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;;
+1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;;
+1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;;
+140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;;
+140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;;
+140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;;
+140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;;
+140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;;
+140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;;
+1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;;
+1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;;
+1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;;
+1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;;
+1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;;
+1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;;
+1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;;
+1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;;
+1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;;
+1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;;
+141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;;
+141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;;
+141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;;
+141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;;
+141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;;
+1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;;
+1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;;
+1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;;
+1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;;
+1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;;
+1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;;
+1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;;
+1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;;
+1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;;
+1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;;
+142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;;
+142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;;
+142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;;
+142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;;
+142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;;
+142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;;
+1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;;
+1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;;
+1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;;
+1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;;
+1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;;
+1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;;
+1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;;
+1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;;
+1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;;
+1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;;
+143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;;
+143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;;
+143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;;
+143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;;
+143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;;
+143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;;
+1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;;
+1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;;
+1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;;
+1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;;
+1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;;
+1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;;
+1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;;
+1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;;
+144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;;
+144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;;
+144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;;
+144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;;
+144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;;
+144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;;
+1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;;
+1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;;
+1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;;
+1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;;
+1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;;
+1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;;
+1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;;
+1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;;
+1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;;
+1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;;
+145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;;
+145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;;
+145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;;
+145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;;
+145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;;
+145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;;
+1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;;
+1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;;
+1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;;
+1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;;
+1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;;
+1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;;
+1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;;
+1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;;
+1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;;
+1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;;
+146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;;
+146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;;
+146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;;
+146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;;
+146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;;
+146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;;
+1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;;
+1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;;
+1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;;
+1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;;
+1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;;
+1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;;
+1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;;
+1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;;
+1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;;
+1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;;
+147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;;
+147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;;
+147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;;
+147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;;
+147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;;
+147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;;
+1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;;
+1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;;
+1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;;
+1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;;
+1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;;
+1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;;
+1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;;
+1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;;
+1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;;
+1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;;
+148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;;
+148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;;
+148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;;
+148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;;
+148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;;
+148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;;
+1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;;
+1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;;
+1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;;
+1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;;
+1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;;
+1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;;
+1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;;
+1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;;
+1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;;
+1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;;
+149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;;
+149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;;
+149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;;
+149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;;
+149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;;
+149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;;
+14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;;
+14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;;
+14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;;
+14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;;
+14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;;
+14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;;
+14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;;
+14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;;
+14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;;
+14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;;
+14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;;
+14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;;
+14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;;
+14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;;
+14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;;
+14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;;
+14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;;
+14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;;
+14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;;
+14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;;
+14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;;
+14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;;
+14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;;
+14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;;
+14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;;
+14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;;
+14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;;
+14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;;
+14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;;
+14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;;
+14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;;
+14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;;
+14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;;
+14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;;
+14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;;
+14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;;
+14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;;
+14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;;
+14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;;
+14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;;
+14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;;
+14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;;
+14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;;
+14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;;
+14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;;
+14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;;
+14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;;
+14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;;
+14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;;
+14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;;
+14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;;
+14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;;
+14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;;
+14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;;
+14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;;
+14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;;
+14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;;
+14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;;
+14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;;
+14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;;
+14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;;
+14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;;
+14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;;
+14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;;
+14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;;
+14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;;
+14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;;
+14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;;
+14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;;
+14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;;
+14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;;
+14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;;
+14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;;
+14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;;
+14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;;
+14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;;
+14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;;
+14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;;
+14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;;
+14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;;
+14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;;
+14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;;
+14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;;
+14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;;
+14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;;
+14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;;
+14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;;
+14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;;
+14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;;
+14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;;
+14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;;
+14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;;
+14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;;
+14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;;
+14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;;
+14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;;
+1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;;
+1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;;
+1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;;
+1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;;
+1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;;
+1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;;
+1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;;
+1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;;
+1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;;
+1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;;
+150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;;
+150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;;
+150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;;
+150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;;
+150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;;
+150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;;
+1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;;
+1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;;
+1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;;
+1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;;
+1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;;
+1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;;
+1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;;
+1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;;
+1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;;
+1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;;
+151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;;
+151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;;
+151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;;
+151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;;
+151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;;
+151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;;
+1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;;
+1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;;
+1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;;
+1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;;
+1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;;
+1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;;
+1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;;
+1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;;
+1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;;
+1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;;
+152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;;
+152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;;
+152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;;
+152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;;
+152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;;
+152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;;
+1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;;
+1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;;
+1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;;
+1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;;
+1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;;
+1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;;
+1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;;
+1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;;
+1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;;
+1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;;
+153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;;
+153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;;
+153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;;
+153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;;
+153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;;
+153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;;
+1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;;
+1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;;
+1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;;
+1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;;
+1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;;
+1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;;
+1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;;
+1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;;
+1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;;
+1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;;
+154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;;
+154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;;
+154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;;
+154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;;
+154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;;
+154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;;
+1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;;
+1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;;
+1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;;
+1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;;
+1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;;
+1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;;
+1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;;
+1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;;
+1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;;
+1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;;
+155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;;
+155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;;
+155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;;
+155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;;
+155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;;
+155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;;
+1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;;
+1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;;
+1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;;
+1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;;
+1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;;
+1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;;
+1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;;
+1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;;
+1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;;
+1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;;
+156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;;
+156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;;
+156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;;
+156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;;
+156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;;
+156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;;
+1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;;
+1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;;
+1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;;
+1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;;
+1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;;
+1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;;
+1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;;
+1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;;
+1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;;
+1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;;
+157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;;
+157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;;
+157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;;
+157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;;
+157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;;
+157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;;
+1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;;
+1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;;
+1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;;
+1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;;
+1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;;
+1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;;
+1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;;
+1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;;
+1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;;
+1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;;
+158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;;
+158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;;
+158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;;
+158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;;
+158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;;
+158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;;
+1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;;
+1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;;
+1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;;
+1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;;
+1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;;
+1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;;
+1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;;
+1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;;
+1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;;
+1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;;
+159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;;
+159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;;
+159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;;
+159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;;
+159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;;
+159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;;
+15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;;
+15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;;
+15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;;
+15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;;
+15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;;
+15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;;
+15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;;
+15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;;
+15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;;
+15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;;
+15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;;
+15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;;
+15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;;
+15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;;
+15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;;
+15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;;
+15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;;
+15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;;
+15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;;
+15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;;
+15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;;
+15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;;
+15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;;
+15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;;
+15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;;
+15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;;
+15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;;
+15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;;
+15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;;
+15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;;
+15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;;
+15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;;
+15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;;
+15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;;
+15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;;
+15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;;
+15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;;
+15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;;
+15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;;
+15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;;
+15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;;
+15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;;
+15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;;
+15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;;
+15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;;
+15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;;
+15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;;
+15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;;
+15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;;
+15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;;
+15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;;
+15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;;
+15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;;
+15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;;
+15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;;
+15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;;
+15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;;
+15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;;
+15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;;
+15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;;
+15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;;
+15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;;
+15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;;
+15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;;
+15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;;
+15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;;
+15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;;
+15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;;
+15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;;
+15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;;
+15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;;
+15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;;
+15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;;
+15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;;
+15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;;
+15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;;
+15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;;
+15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;;
+15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;;
+15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;;
+15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;;
+15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;;
+15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;;
+15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;;
+15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;;
+15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;;
+15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;;
+15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;;
+15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;;
+15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;;
+15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;;
+15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;;
+15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;;
+15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;;
+15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;;
+15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;;
+1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;;
+1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;;
+1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;;
+1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;;
+1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;;
+1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;;
+1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;;
+1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;;
+1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;;
+1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;;
+160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;;
+160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;;
+160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;;
+160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;;
+160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;;
+160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;;
+1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;;
+1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;;
+1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;;
+1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;;
+1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;;
+1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;;
+1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;;
+1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;;
+1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;;
+1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;;
+161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;;
+161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;;
+161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;;
+161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;;
+161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;;
+161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;;
+1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;;
+1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;;
+1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;;
+1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;;
+1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;;
+1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;;
+1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;;
+1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;;
+1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;;
+1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;;
+162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;;
+162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;;
+162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;;
+162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;;
+162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;;
+162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;;
+1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;;
+1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;;
+1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;;
+1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;;
+1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;;
+1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;;
+1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;;
+1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;;
+1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;;
+1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;;
+163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;;
+163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;;
+163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;;
+163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;;
+163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;;
+163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;;
+1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;;
+1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;;
+1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;;
+1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;;
+1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;;
+1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;;
+1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;;
+1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;;
+1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;;
+1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;;
+164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;;
+164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;;
+164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;;
+164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;;
+164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;;
+164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;;
+1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;;
+1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;;
+1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;;
+1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;;
+1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;;
+1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;;
+1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;;
+1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;;
+1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;;
+1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;;
+165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;;
+165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;;
+165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;;
+165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;;
+165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;;
+165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;;
+1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;;
+1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;;
+1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;;
+1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;;
+1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;;
+1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;;
+1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;;
+1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;;
+1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;;
+1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;;
+166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;
+166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;
+166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;
+166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;;
+166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;
+166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;
+1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;
+1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;;
+1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;;
+1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;;
+1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;;
+1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;;
+1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;;
+1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
+1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;;
+1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;;
+1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;;
+1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;;
+1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;;
+1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;;
+1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;;
+1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;;
+1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;;
+168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;;
+168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;;
+168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;;
+168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;;
+168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;;
+168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;;
+1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;;
+1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;;
+1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;;
+1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;;
+1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;;
+1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;;
+1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;;
+1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;;
+1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;;
+1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;;
+169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;;
+169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;N;;;;;
+169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;N;;;;;
+16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;;
+16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;;
+16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;;
+16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;;
+16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;;
+16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;;
+16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;;
+16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;;
+16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;;
+16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;;
+16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;;
+16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;;
+16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;;
+16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;;
+16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;;
+16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;;
+16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;;
+16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;;
+16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;;
+16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;;
+16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;;
+16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;;
+16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;;
+16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;;
+16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;;
+16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;;
+16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;;
+16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;;
+16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;;
+16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;;
+16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;;
+16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;;
+16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;;
+16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;;
+16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;;
+16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;;
+16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;;
+16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;;
+16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;;
+16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;;
+16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;;
+16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;;
+16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;;
+16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;;
+16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;;
+16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;;
+16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;;
+16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;;
+16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;;
+16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;;
+16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;;
+16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;;
+16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;;
+16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;;
+16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;;
+16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;;
+16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;;
+16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;;
+16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;;
+16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;;
+16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;;
+16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;;
+16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;;
+16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;;
+16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;;
+16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;;
+16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;;
+16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;;
+16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;;
+16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;;
+16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;;
+16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EE;RUNIC ARLAUG SYMBOL;No;0;L;;;;17;N;;golden number 17;;;
+16EF;RUNIC TVIMADUR SYMBOL;No;0;L;;;;18;N;;golden number 18;;;
+16F0;RUNIC BELGTHOR SYMBOL;No;0;L;;;;19;N;;golden number 19;;;
+1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;;
+1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;;
+1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;;
+1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;;
+1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;;
+1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;;
+1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;;
+1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;;
+1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;;
+1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;;
+178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;;
+178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;;
+178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;;
+178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;;
+178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;;
+178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;;
+1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;;
+1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;;
+1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;;
+1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;;
+1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;;
+1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;;
+1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;;
+1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;;
+1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;;
+1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;;
+179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;;
+179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;;
+179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;;
+179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;;
+179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;;
+179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;;
+17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;;
+17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;;
+17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;;
+17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;;
+17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;;
+17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;;
+17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;;
+17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;;
+17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;;
+17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;;
+17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;;
+17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;;
+17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;;
+17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;;
+17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;;
+17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;;
+17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;;
+17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;
+17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;
+17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;
+17B4;KHMER VOWEL INHERENT AQ;Mc;0;L;;;;;N;;;;;
+17B5;KHMER VOWEL INHERENT AA;Mc;0;L;;;;;N;;;;;
+17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;;
+17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;;
+17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;;
+17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
+17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;;
+17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;;
+17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;;
+17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;;
+17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;;
+17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;;
+17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;;
+17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;;
+17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;;
+17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;;
+17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;;
+17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;;
+17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;;
+17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;;
+17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;;
+17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;;
+17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;;
+17D7;KHMER SIGN LEK TOO;Po;0;L;;;;;N;;;;;
+17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;;
+17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;;
+17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;;
+17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;;
+17DC;KHMER SIGN AVAKRAHASANYA;Po;0;L;;;;;N;;;;;
+17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;;
+1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;;
+1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;;
+1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;;
+1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;;
+1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;;
+1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;
+1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;;
+1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;;
+1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;;
+180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;;
+180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Cf;0;BN;;;;;N;;;;;
+180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Cf;0;BN;;;;;N;;;;;
+180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Cf;0;BN;;;;;N;;;;;
+180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
+1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;;
+1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;;
+1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;;
+1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;;
+1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;;
+1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;;
+1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;;
+1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;;
+1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;;
+1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;;
+182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;;
+182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;;
+182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;;
+182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;;
+182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;;
+182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;;
+1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;;
+1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;;
+1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;;
+1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;;
+1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;;
+1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;;
+1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;;
+1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;;
+183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;;
+183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;;
+183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;;
+1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;;
+1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;;
+1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
+1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;;
+1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;;
+1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;;
+1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;;
+1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;;
+1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;;
+1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;;
+184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;;
+184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;;
+184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;;
+184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;;
+184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;;
+184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;;
+1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;;
+1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;;
+1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;;
+1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;;
+1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;;
+1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;;
+1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;;
+1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;;
+1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;
+1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;;
+185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;;
+185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;;
+185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;;
+185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;;
+185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;;
+185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;;
+1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;;
+1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;;
+1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;;
+1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;;
+1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;;
+1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;;
+1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;;
+1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;;
+1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;;
+1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;;
+186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;;
+186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;;
+186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;;
+186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;;
+186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;;
+186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;;
+1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;;
+1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;;
+1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;;
+1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;;
+1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;;
+1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;;
+1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;;
+1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;;
+1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;;
+1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;;
+1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;
+1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;
+1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;
+1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;;
+1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;;
+1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;
+1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;
+1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;
+188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;;
+188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;;
+188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;;
+188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;;
+1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;;
+1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;;
+1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;;
+1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;;
+1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;;
+189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;;
+189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;;
+189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;;
+18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;;
+18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;;
+18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;;
+18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;;
+18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;;
+18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;;
+18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;;
+1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01;
+1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00
+1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03;
+1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02
+1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05;
+1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04
+1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;
+1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06
+1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09;
+1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08
+1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B;
+1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A
+1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D;
+1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C
+1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F;
+1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E
+1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11;
+1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10
+1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13;
+1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12
+1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15;
+1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14
+1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17;
+1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16
+1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19;
+1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18
+1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B;
+1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A
+1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D;
+1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C
+1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F;
+1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E
+1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21;
+1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20
+1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23;
+1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22
+1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25;
+1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24
+1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27;
+1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26
+1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29;
+1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28
+1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B;
+1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A
+1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D;
+1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C
+1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F;
+1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E
+1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31;
+1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30
+1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33;
+1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32
+1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35;
+1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34
+1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37;
+1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36
+1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39;
+1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38
+1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B;
+1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A
+1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D;
+1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C
+1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F;
+1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E
+1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41;
+1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40
+1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43;
+1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42
+1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45;
+1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44
+1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47;
+1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46
+1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49;
+1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48
+1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B;
+1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A
+1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D;
+1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C
+1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F;
+1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E
+1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51;
+1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50
+1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53;
+1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52
+1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55;
+1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54
+1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57;
+1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56
+1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59;
+1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58
+1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B;
+1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A
+1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D;
+1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C
+1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F;
+1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E
+1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61;
+1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60
+1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63;
+1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62
+1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65;
+1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64
+1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67;
+1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66
+1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69;
+1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68
+1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B;
+1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A
+1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D;
+1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C
+1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F;
+1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E
+1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71;
+1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70
+1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73;
+1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72
+1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75;
+1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74
+1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77;
+1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76
+1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79;
+1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78
+1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B;
+1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A
+1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D;
+1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C
+1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F;
+1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E
+1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81;
+1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80
+1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83;
+1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82
+1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85;
+1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84
+1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87;
+1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86
+1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89;
+1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88
+1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B;
+1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A
+1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D;
+1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C
+1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F;
+1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E
+1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91;
+1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90
+1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93;
+1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92
+1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95;
+1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94
+1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;;
+1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;;
+1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;;
+1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;;
+1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L;<compat> 0061 02BE;;;;N;;;;;
+1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60
+1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1;
+1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0
+1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3;
+1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2
+1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5;
+1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4
+1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7;
+1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6
+1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9;
+1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8
+1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB;
+1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA
+1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD;
+1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC
+1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF;
+1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE
+1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1;
+1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0
+1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3;
+1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2
+1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5;
+1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4
+1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7;
+1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6
+1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9;
+1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8
+1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB;
+1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA
+1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD;
+1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC
+1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF;
+1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE
+1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1;
+1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0
+1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3;
+1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2
+1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5;
+1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4
+1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7;
+1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6
+1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9;
+1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8
+1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB;
+1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA
+1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD;
+1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
+1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF;
+1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE
+1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1;
+1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0
+1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3;
+1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2
+1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5;
+1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4
+1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7;
+1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6
+1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9;
+1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
+1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB;
+1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA
+1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD;
+1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC
+1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF;
+1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE
+1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1;
+1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0
+1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3;
+1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2
+1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5;
+1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4
+1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7;
+1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6
+1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9;
+1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8
+1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB;
+1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA
+1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED;
+1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC
+1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF;
+1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE
+1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1;
+1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0
+1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3;
+1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2
+1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5;
+1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4
+1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7;
+1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6
+1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9;
+1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8
+1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08
+1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09
+1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A
+1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B
+1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C
+1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D
+1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E
+1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F
+1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00;
+1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01;
+1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02;
+1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03;
+1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04;
+1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05;
+1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06;
+1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07;
+1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18
+1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19
+1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A
+1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B
+1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C
+1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D
+1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10;
+1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11;
+1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12;
+1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13;
+1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14;
+1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15;
+1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28
+1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29
+1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A
+1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B
+1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C
+1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D
+1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E
+1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F
+1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20;
+1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21;
+1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22;
+1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23;
+1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24;
+1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25;
+1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26;
+1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27;
+1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38
+1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39
+1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A
+1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B
+1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C
+1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D
+1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E
+1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F
+1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30;
+1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31;
+1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32;
+1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33;
+1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34;
+1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35;
+1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36;
+1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37;
+1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48
+1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49
+1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A
+1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B
+1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C
+1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D
+1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40;
+1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41;
+1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42;
+1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43;
+1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44;
+1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45;
+1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;;
+1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59
+1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;;
+1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B
+1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;;
+1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D
+1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;;
+1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F
+1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51;
+1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53;
+1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55;
+1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57;
+1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68
+1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69
+1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A
+1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B
+1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C
+1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D
+1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E
+1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F
+1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60;
+1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61;
+1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62;
+1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63;
+1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64;
+1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65;
+1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66;
+1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67;
+1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA
+1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB
+1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8
+1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9
+1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA
+1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB
+1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA
+1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB
+1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8
+1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9
+1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA
+1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB
+1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA
+1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB
+1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88
+1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89
+1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A
+1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B
+1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C
+1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D
+1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E
+1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F
+1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80;
+1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81;
+1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82;
+1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83;
+1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84;
+1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85;
+1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86;
+1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87;
+1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98
+1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99
+1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A
+1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B
+1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C
+1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D
+1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E
+1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F
+1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90;
+1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91;
+1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92;
+1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93;
+1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94;
+1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95;
+1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96;
+1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97;
+1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8
+1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9
+1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA
+1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB
+1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC
+1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD
+1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE
+1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF
+1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0;
+1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1;
+1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2;
+1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3;
+1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4;
+1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5;
+1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6;
+1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7;
+1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8
+1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9
+1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;;
+1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC
+1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;;
+1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;;
+1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;;
+1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0;
+1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1;
+1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70;
+1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71;
+1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3;
+1FBD;GREEK KORONIS;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399
+1FBF;GREEK PSILI;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FC0;GREEK PERISPOMENI;Sk;0;ON;<compat> 0020 0342;;;;N;;;;;
+1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;;
+1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;;
+1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC
+1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;;
+1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;;
+1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;;
+1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72;
+1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73;
+1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74;
+1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75;
+1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3;
+1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;;
+1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;;
+1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;;
+1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8
+1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9
+1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;;
+1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;;
+1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;;
+1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;;
+1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0;
+1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1;
+1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76;
+1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77;
+1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;;
+1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;;
+1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;;
+1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8
+1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9
+1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;;
+1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;;
+1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;;
+1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC
+1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;;
+1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;;
+1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0;
+1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1;
+1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A;
+1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B;
+1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5;
+1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;;
+1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;;
+1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;;
+1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;;
+1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC
+1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;;
+1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;;
+1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;;
+1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78;
+1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79;
+1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C;
+1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D;
+1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3;
+1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;;
+1FFE;GREEK DASIA;Sk;0;ON;<compat> 0020 0314;;;;N;;;;;
+2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
+2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
+2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
+2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200B;ZERO WIDTH SPACE;Zs;0;BN;;;;;N;;;;;
+200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
+200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
+200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;
+200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;
+2010;HYPHEN;Pd;0;ON;;;;;N;;;;;
+2011;NON-BREAKING HYPHEN;Pd;0;ON;<noBreak> 2010;;;;N;;;;;
+2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;;
+2013;EN DASH;Pd;0;ON;;;;;N;;;;;
+2014;EM DASH;Pd;0;ON;;;;;N;;;;;
+2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;;
+2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;;
+2017;DOUBLE LOW LINE;Po;0;ON;<compat> 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;;
+2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;;
+2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;;
+201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;;
+201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;;
+201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;;
+201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;;
+201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;;
+201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;;
+2020;DAGGER;Po;0;ON;;;;;N;;;;;
+2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;;
+2022;BULLET;Po;0;ON;;;;;N;;;;;
+2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;;
+2024;ONE DOT LEADER;Po;0;ON;<compat> 002E;;;;N;;;;;
+2025;TWO DOT LEADER;Po;0;ON;<compat> 002E 002E;;;;N;;;;;
+2026;HORIZONTAL ELLIPSIS;Po;0;ON;<compat> 002E 002E 002E;;;;N;;;;;
+2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;;
+2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
+2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;
+202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;;
+202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;;
+202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;;
+202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;;
+202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;;
+202F;NARROW NO-BREAK SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
+2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
+2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
+2032;PRIME;Po;0;ET;;;;;N;;;;;
+2033;DOUBLE PRIME;Po;0;ET;<compat> 2032 2032;;;;N;;;;;
+2034;TRIPLE PRIME;Po;0;ET;<compat> 2032 2032 2032;;;;N;;;;;
+2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;;
+2036;REVERSED DOUBLE PRIME;Po;0;ON;<compat> 2035 2035;;;;N;;;;;
+2037;REVERSED TRIPLE PRIME;Po;0;ON;<compat> 2035 2035 2035;;;;N;;;;;
+2038;CARET;Po;0;ON;;;;;N;;;;;
+2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;;
+203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;;
+203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;;
+203C;DOUBLE EXCLAMATION MARK;Po;0;ON;<compat> 0021 0021;;;;N;;;;;
+203D;INTERROBANG;Po;0;ON;;;;;N;;;;;
+203E;OVERLINE;Po;0;ON;<compat> 0020 0305;;;;N;SPACING OVERSCORE;;;;
+203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;;
+2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;;
+2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;;
+2042;ASTERISM;Po;0;ON;;;;;N;;;;;
+2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;;
+2044;FRACTION SLASH;Sm;0;ON;;;;;N;;;;;
+2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;;
+2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;;
+2048;QUESTION EXCLAMATION MARK;Po;0;ON;<compat> 003F 0021;;;;N;;;;;
+2049;EXCLAMATION QUESTION MARK;Po;0;ON;<compat> 0021 003F;;;;N;;;;;
+204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;;
+204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;;
+204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+2070;SUPERSCRIPT ZERO;No;0;EN;<super> 0030;0;0;0;N;SUPERSCRIPT DIGIT ZERO;;;;
+2074;SUPERSCRIPT FOUR;No;0;EN;<super> 0034;4;4;4;N;SUPERSCRIPT DIGIT FOUR;;;;
+2075;SUPERSCRIPT FIVE;No;0;EN;<super> 0035;5;5;5;N;SUPERSCRIPT DIGIT FIVE;;;;
+2076;SUPERSCRIPT SIX;No;0;EN;<super> 0036;6;6;6;N;SUPERSCRIPT DIGIT SIX;;;;
+2077;SUPERSCRIPT SEVEN;No;0;EN;<super> 0037;7;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;;
+2078;SUPERSCRIPT EIGHT;No;0;EN;<super> 0038;8;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;;
+2079;SUPERSCRIPT NINE;No;0;EN;<super> 0039;9;9;9;N;SUPERSCRIPT DIGIT NINE;;;;
+207A;SUPERSCRIPT PLUS SIGN;Sm;0;ET;<super> 002B;;;;N;;;;;
+207B;SUPERSCRIPT MINUS;Sm;0;ET;<super> 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;;
+207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON;<super> 003D;;;;N;;;;;
+207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON;<super> 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;;
+207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<super> 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;;
+207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L;<super> 006E;;;;N;;;;;
+2080;SUBSCRIPT ZERO;No;0;EN;<sub> 0030;0;0;0;N;SUBSCRIPT DIGIT ZERO;;;;
+2081;SUBSCRIPT ONE;No;0;EN;<sub> 0031;1;1;1;N;SUBSCRIPT DIGIT ONE;;;;
+2082;SUBSCRIPT TWO;No;0;EN;<sub> 0032;2;2;2;N;SUBSCRIPT DIGIT TWO;;;;
+2083;SUBSCRIPT THREE;No;0;EN;<sub> 0033;3;3;3;N;SUBSCRIPT DIGIT THREE;;;;
+2084;SUBSCRIPT FOUR;No;0;EN;<sub> 0034;4;4;4;N;SUBSCRIPT DIGIT FOUR;;;;
+2085;SUBSCRIPT FIVE;No;0;EN;<sub> 0035;5;5;5;N;SUBSCRIPT DIGIT FIVE;;;;
+2086;SUBSCRIPT SIX;No;0;EN;<sub> 0036;6;6;6;N;SUBSCRIPT DIGIT SIX;;;;
+2087;SUBSCRIPT SEVEN;No;0;EN;<sub> 0037;7;7;7;N;SUBSCRIPT DIGIT SEVEN;;;;
+2088;SUBSCRIPT EIGHT;No;0;EN;<sub> 0038;8;8;8;N;SUBSCRIPT DIGIT EIGHT;;;;
+2089;SUBSCRIPT NINE;No;0;EN;<sub> 0039;9;9;9;N;SUBSCRIPT DIGIT NINE;;;;
+208A;SUBSCRIPT PLUS SIGN;Sm;0;ET;<sub> 002B;;;;N;;;;;
+208B;SUBSCRIPT MINUS;Sm;0;ET;<sub> 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;;
+208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON;<sub> 003D;;;;N;;;;;
+208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON;<sub> 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;;
+208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<sub> 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;;
+20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;
+20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;
+20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;;
+20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;;
+20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;;
+20A8;RUPEE SIGN;Sc;0;ET;<compat> 0052 0073;;;;N;;;;;
+20A9;WON SIGN;Sc;0;ET;;;;;N;;;;;
+20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;;
+20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;;
+20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;;
+20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;;
+20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;;
+20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;;
+20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
+20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
+20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
+20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;;
+20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;;
+20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;;
+20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;;
+20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;;
+20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;;
+20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;;
+20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;;
+20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;;
+20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;;
+20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;
+20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;
+20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;
+20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;
+20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;;
+20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;
+20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;
+2100;ACCOUNT OF;So;0;ON;<compat> 0061 002F 0063;;;;N;;;;;
+2101;ADDRESSED TO THE SUBJECT;So;0;ON;<compat> 0061 002F 0073;;;;N;;;;;
+2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L;<font> 0043;;;;N;DOUBLE-STRUCK C;;;;
+2103;DEGREE CELSIUS;So;0;ON;<compat> 00B0 0043;;;;N;DEGREES CENTIGRADE;;;;
+2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;;
+2105;CARE OF;So;0;ON;<compat> 0063 002F 006F;;;;N;;;;;
+2106;CADA UNA;So;0;ON;<compat> 0063 002F 0075;;;;N;;;;;
+2107;EULER CONSTANT;Lu;0;L;<compat> 0190;;;;N;EULERS;;;;
+2108;SCRUPLE;So;0;ON;;;;;N;;;;;
+2109;DEGREE FAHRENHEIT;So;0;ON;<compat> 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;;
+210A;SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+210B;SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;SCRIPT H;;;;
+210C;BLACK-LETTER CAPITAL H;Lu;0;L;<font> 0048;;;;N;BLACK-LETTER H;;;;
+210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L;<font> 0048;;;;N;DOUBLE-STRUCK H;;;;
+210E;PLANCK CONSTANT;Ll;0;L;<font> 0068;;;;N;;;;;
+210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L;<font> 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;;
+2110;SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;SCRIPT I;;;;
+2111;BLACK-LETTER CAPITAL I;Lu;0;L;<font> 0049;;;;N;BLACK-LETTER I;;;;
+2112;SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;SCRIPT L;;;;
+2113;SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;;
+2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
+2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
+2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
+2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;;
+2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
+211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
+211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
+211C;BLACK-LETTER CAPITAL R;Lu;0;L;<font> 0052;;;;N;BLACK-LETTER R;;;;
+211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L;<font> 0052;;;;N;DOUBLE-STRUCK R;;;;
+211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;;
+211F;RESPONSE;So;0;ON;;;;;N;;;;;
+2120;SERVICE MARK;So;0;ON;<super> 0053 004D;;;;N;;;;;
+2121;TELEPHONE SIGN;So;0;ON;<compat> 0054 0045 004C;;;;N;T E L SYMBOL;;;;
+2122;TRADE MARK SIGN;So;0;ON;<super> 0054 004D;;;;N;TRADEMARK;;;;
+2123;VERSICLE;So;0;ON;;;;;N;;;;;
+2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L;<font> 005A;;;;N;DOUBLE-STRUCK Z;;;;
+2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;;
+2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9;
+2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;;
+2128;BLACK-LETTER CAPITAL Z;Lu;0;L;<font> 005A;;;;N;BLACK-LETTER Z;;;;
+2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;;
+212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
+212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5;
+212C;SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;SCRIPT B;;;;
+212D;BLACK-LETTER CAPITAL C;Lu;0;L;<font> 0043;;;;N;BLACK-LETTER C;;;;
+212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;;
+212F;SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+2130;SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;SCRIPT E;;;;
+2131;SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;SCRIPT F;;;;
+2132;TURNED CAPITAL F;So;0;ON;;;;;N;TURNED F;;;;
+2133;SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;SCRIPT M;;;;
+2134;SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+2135;ALEF SYMBOL;Lo;0;L;<compat> 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;;
+2136;BET SYMBOL;Lo;0;L;<compat> 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;;
+2137;GIMEL SYMBOL;Lo;0;L;<compat> 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;;
+2138;DALET SYMBOL;Lo;0;L;<compat> 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;;
+2139;INFORMATION SOURCE;Ll;0;L;<font> 0069;;;;N;;;;;
+213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;;
+2153;VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;
+2154;VULGAR FRACTION TWO THIRDS;No;0;ON;<fraction> 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;;
+2155;VULGAR FRACTION ONE FIFTH;No;0;ON;<fraction> 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;;
+2156;VULGAR FRACTION TWO FIFTHS;No;0;ON;<fraction> 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;;
+2157;VULGAR FRACTION THREE FIFTHS;No;0;ON;<fraction> 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;;
+2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON;<fraction> 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;;
+2159;VULGAR FRACTION ONE SIXTH;No;0;ON;<fraction> 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;;
+215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON;<fraction> 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;;
+215B;VULGAR FRACTION ONE EIGHTH;No;0;ON;<fraction> 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;;
+215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON;<fraction> 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;;
+215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON;<fraction> 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;;
+215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON;<fraction> 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;;
+215F;FRACTION NUMERATOR ONE;No;0;ON;<fraction> 0031 2044;;;1;N;;;;;
+2160;ROMAN NUMERAL ONE;Nl;0;L;<compat> 0049;;;1;N;;;;2170;
+2161;ROMAN NUMERAL TWO;Nl;0;L;<compat> 0049 0049;;;2;N;;;;2171;
+2162;ROMAN NUMERAL THREE;Nl;0;L;<compat> 0049 0049 0049;;;3;N;;;;2172;
+2163;ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0049 0056;;;4;N;;;;2173;
+2164;ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0056;;;5;N;;;;2174;
+2165;ROMAN NUMERAL SIX;Nl;0;L;<compat> 0056 0049;;;6;N;;;;2175;
+2166;ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0056 0049 0049;;;7;N;;;;2176;
+2167;ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0056 0049 0049 0049;;;8;N;;;;2177;
+2168;ROMAN NUMERAL NINE;Nl;0;L;<compat> 0049 0058;;;9;N;;;;2178;
+2169;ROMAN NUMERAL TEN;Nl;0;L;<compat> 0058;;;10;N;;;;2179;
+216A;ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0058 0049;;;11;N;;;;217A;
+216B;ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0058 0049 0049;;;12;N;;;;217B;
+216C;ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 004C;;;50;N;;;;217C;
+216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0043;;;100;N;;;;217D;
+216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0044;;;500;N;;;;217E;
+216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 004D;;;1000;N;;;;217F;
+2170;SMALL ROMAN NUMERAL ONE;Nl;0;L;<compat> 0069;;;1;N;;;2160;;2160
+2171;SMALL ROMAN NUMERAL TWO;Nl;0;L;<compat> 0069 0069;;;2;N;;;2161;;2161
+2172;SMALL ROMAN NUMERAL THREE;Nl;0;L;<compat> 0069 0069 0069;;;3;N;;;2162;;2162
+2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0069 0076;;;4;N;;;2163;;2163
+2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0076;;;5;N;;;2164;;2164
+2175;SMALL ROMAN NUMERAL SIX;Nl;0;L;<compat> 0076 0069;;;6;N;;;2165;;2165
+2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0076 0069 0069;;;7;N;;;2166;;2166
+2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0076 0069 0069 0069;;;8;N;;;2167;;2167
+2178;SMALL ROMAN NUMERAL NINE;Nl;0;L;<compat> 0069 0078;;;9;N;;;2168;;2168
+2179;SMALL ROMAN NUMERAL TEN;Nl;0;L;<compat> 0078;;;10;N;;;2169;;2169
+217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0078 0069;;;11;N;;;216A;;216A
+217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0078 0069 0069;;;12;N;;;216B;;216B
+217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 006C;;;50;N;;;216C;;216C
+217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0063;;;100;N;;;216D;;216D
+217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0064;;;500;N;;;216E;;216E
+217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 006D;;;1000;N;;;216F;;216F
+2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;;
+2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;;
+2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;;
+2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Nl;0;L;;;;;N;;;;;
+2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;
+2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;
+2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
+2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;;
+2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
+2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;;
+2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;;
+2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;;
+2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;;
+2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;;
+219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;;
+219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;;
+219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;;
+219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;;
+219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;;
+219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;;
+21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;;
+21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;;
+21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;;
+21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;;
+21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;;
+21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;;
+21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;;
+21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;;
+21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;;
+21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;;
+21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;;
+21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;;
+21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;;
+21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;;
+21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;;
+21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;;
+21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;;
+21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;;
+21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;;
+21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;;
+21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;;
+21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;;
+21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;;
+21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;;
+21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;;
+21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;;
+21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;;
+21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;;
+21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;;
+21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;;
+21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;;
+21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;;
+21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;;
+21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;;
+21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;;
+21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;;
+21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;;
+21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;;
+21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;;
+21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;;
+21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;;
+21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;;
+21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;;
+21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;;
+21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;;
+21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;;
+21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;;
+21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;;
+21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;;
+21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;;
+21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;;
+21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;;
+21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;;
+21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;;
+21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;;
+21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;;
+21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;;
+21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;;
+21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;;
+21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;;
+21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;;
+21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;;
+21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;;
+21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;;
+21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;;
+21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;;
+21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;;
+21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;;
+21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;;
+21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
+21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;;
+21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;;
+2200;FOR ALL;Sm;0;ON;;;;;N;;;;;
+2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;;
+2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;;
+2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;;
+2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;;
+2205;EMPTY SET;Sm;0;ON;;;;;N;;;;;
+2206;INCREMENT;Sm;0;ON;;;;;N;;;;;
+2207;NABLA;Sm;0;ON;;;;;N;;;;;
+2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;;
+220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;;
+220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220E;END OF PROOF;Sm;0;ON;;;;;N;;;;;
+220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;;
+2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;;
+2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;;
+2212;MINUS SIGN;Sm;0;ET;;;;;N;;;;;
+2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;;
+2214;DOT PLUS;Sm;0;ON;;;;;N;;;;;
+2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2216;SET MINUS;Sm;0;ON;;;;;Y;;;;;
+2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;;
+221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;;
+221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;;
+221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;;
+221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;;
+221E;INFINITY;Sm;0;ON;;;;;N;;;;;
+221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;;
+2220;ANGLE;Sm;0;ON;;;;;Y;;;;;
+2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;;
+2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;;
+2223;DIVIDES;Sm;0;ON;;;;;N;;;;;
+2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;;
+2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;;
+2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2229;INTERSECTION;Sm;0;ON;;;;;N;;;;;
+222A;UNION;Sm;0;ON;;;;;N;;;;;
+222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222C;DOUBLE INTEGRAL;Sm;0;ON;<compat> 222B 222B;;;;Y;;;;;
+222D;TRIPLE INTEGRAL;Sm;0;ON;<compat> 222B 222B 222B;;;;Y;;;;;
+222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222F;SURFACE INTEGRAL;Sm;0;ON;<compat> 222E 222E;;;;Y;;;;;
+2230;VOLUME INTEGRAL;Sm;0;ON;<compat> 222E 222E 222E;;;;Y;;;;;
+2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2234;THEREFORE;Sm;0;ON;;;;;N;;;;;
+2235;BECAUSE;Sm;0;ON;;;;;N;;;;;
+2236;RATIO;Sm;0;ON;;;;;N;;;;;
+2237;PROPORTION;Sm;0;ON;;;;;N;;;;;
+2238;DOT MINUS;Sm;0;ON;;;;;N;;;;;
+2239;EXCESS;Sm;0;ON;;;;;Y;;;;;
+223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;;
+223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;;
+223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;;
+223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;;
+223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;;
+2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;;
+2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;;
+2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;;
+2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;;
+2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;;
+224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;;
+224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;;
+2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;;
+2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;;
+2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;;
+2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;
+2259;ESTIMATES;Sm;0;ON;;;;;N;;;;;
+225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;;
+225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;;
+225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;;
+225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;;
+225E;MEASURED BY;Sm;0;ON;;;;;N;;;;;
+225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;;
+2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;;
+2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;;
+2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;;
+2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;;
+2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;;
+2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;;
+2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;;
+2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;;
+226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;;
+226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;;
+226C;BETWEEN;Sm;0;ON;;;;;N;;;;;
+226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;;
+226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;;
+226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;;
+2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;;
+2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;;
+2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;;
+2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;;
+2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;;
+2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;;
+2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;;
+2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;;
+2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;;
+2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;;
+227A;PRECEDES;Sm;0;ON;;;;;Y;;;;;
+227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;;
+2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;;
+2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;;
+2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;;
+2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;;
+2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;;
+2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;;
+2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;;
+228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;;
+228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;;
+228C;MULTISET;Sm;0;ON;;;;;Y;;;;;
+228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;;
+228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;;
+228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;;
+2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;;
+2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;;
+2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;;
+2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;;
+229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;;
+229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;;
+229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;;
+22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;;
+22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
+22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;;
+22A5;UP TACK;Sm;0;ON;;;;;N;;;;;
+22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;;
+22A7;MODELS;Sm;0;ON;;;;;Y;;;;;
+22A8;TRUE;Sm;0;ON;;;;;Y;;;;;
+22A9;FORCES;Sm;0;ON;;;;;Y;;;;;
+22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;;
+22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;;
+22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;;
+22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;;
+22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;;
+22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;;
+22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;;
+22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;;
+22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;;
+22BB;XOR;Sm;0;ON;;;;;N;;;;;
+22BC;NAND;Sm;0;ON;;;;;N;;;;;
+22BD;NOR;Sm;0;ON;;;;;N;;;;;
+22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;;
+22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;;
+22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;;
+22C8;BOWTIE;Sm;0;ON;;;;;N;;;;;
+22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;;
+22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;;
+22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;;
+22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;;
+22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;;
+22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;;
+22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;;
+22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;;
+22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;;
+22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;;
+22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;;
+22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;;
+22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;;
+22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;;
+22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;;
+22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;;
+22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;;
+22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;;
+22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;;
+22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;;
+22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;;
+22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;;
+22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;;
+22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;;
+2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;;
+2302;HOUSE;So;0;ON;;;;;N;;;;;
+2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;;
+2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;;
+2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
+2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
+2307;WAVY LINE;So;0;ON;;;;;N;;;;;
+2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;;
+2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;;
+230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;;
+230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;;
+230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
+230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
+230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
+230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;;
+2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;;
+2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;;
+2312;ARC;So;0;ON;;;;;N;;;;;
+2313;SEGMENT;So;0;ON;;;;;N;;;;;
+2314;SECTOR;So;0;ON;;;;;N;;;;;
+2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;;
+2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;;
+2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;;
+2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;;
+2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;;
+231A;WATCH;So;0;ON;;;;;N;;;;;
+231B;HOURGLASS;So;0;ON;;;;;N;;;;;
+231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;;
+231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;;
+231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;;
+231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;;
+2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2322;FROWN;So;0;ON;;;;;N;;;;;
+2323;SMILE;So;0;ON;;;;;N;;;;;
+2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;;
+2325;OPTION KEY;So;0;ON;;;;;N;;;;;
+2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;;
+2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;;
+2328;KEYBOARD;So;0;ON;;;;;N;;;;;
+2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;;
+232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;;
+232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;;
+232C;BENZENE RING;So;0;ON;;;;;N;;;;;
+232D;CYLINDRICITY;So;0;ON;;;;;N;;;;;
+232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;;
+232F;SYMMETRY;So;0;ON;;;;;N;;;;;
+2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;;
+2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;;
+2332;CONICAL TAPER;So;0;ON;;;;;N;;;;;
+2333;SLOPE;So;0;ON;;;;;N;;;;;
+2334;COUNTERBORE;So;0;ON;;;;;N;;;;;
+2335;COUNTERSINK;So;0;ON;;;;;N;;;;;
+2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;;
+2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;;
+2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;;
+2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;;
+233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;;
+233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;;
+233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;;
+233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;;
+233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;;
+233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;;
+2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;;
+2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;;
+2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;;
+2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;;
+2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;;
+2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;;
+2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;;
+2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;;
+2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;;
+2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;;
+234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;;
+234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;;
+234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;;
+234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;;
+234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;;
+234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;;
+2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;;
+2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;;
+2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;;
+2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;;
+2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;;
+2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;;
+2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;;
+2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;;
+2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;;
+2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;;
+235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;;
+235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;;
+235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;;
+235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;;
+235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;;
+235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;;
+2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;;
+2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;;
+2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;;
+2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;;
+2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;;
+2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;;
+2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;;
+2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;;
+2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;;
+2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;;
+236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;;
+236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;;
+236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;;
+236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;;
+236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;;
+236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;;
+2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;;
+2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;;
+2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;;
+2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;;
+2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;;
+2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;;
+2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;;
+2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;;
+2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;;
+2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;;
+237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;;
+237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;;
+237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;;
+237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;
+237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;;
+2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;;
+2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;;
+2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;;
+2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;;
+2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2388;HELM SYMBOL;So;0;ON;;;;;N;;;;;
+2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;;
+238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;;
+238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;;
+238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;;
+238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;;
+238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;;
+238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;;
+2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;;
+2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;;
+2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;;
+2398;NEXT PAGE;So;0;ON;;;;;N;;;;;
+2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
+2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
+2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
+2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;;
+2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;;
+2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;;
+2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;;
+2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;;
+2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;;
+2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;;
+240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;;
+240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;;
+240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;;
+240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;;
+240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;;
+240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;;
+2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;;
+2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;;
+2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;;
+2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;;
+2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;;
+2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;;
+2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;;
+2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;;
+2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;;
+2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;;
+241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;;
+241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;;
+241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;;
+241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;;
+241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;;
+241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;;
+2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;;
+2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;;
+2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;;
+2423;OPEN BOX;So;0;ON;;;;;N;;;;;
+2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;;
+2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;;
+2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;;
+2440;OCR HOOK;So;0;ON;;;;;N;;;;;
+2441;OCR CHAIR;So;0;ON;;;;;N;;;;;
+2442;OCR FORK;So;0;ON;;;;;N;;;;;
+2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;;
+2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;;
+2445;OCR BOW TIE;So;0;ON;;;;;N;;;;;
+2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;;
+2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;;
+2448;OCR DASH;So;0;ON;;;;;N;;;;;
+2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;;
+244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;;
+2460;CIRCLED DIGIT ONE;No;0;EN;<circle> 0031;;1;1;N;;;;;
+2461;CIRCLED DIGIT TWO;No;0;EN;<circle> 0032;;2;2;N;;;;;
+2462;CIRCLED DIGIT THREE;No;0;EN;<circle> 0033;;3;3;N;;;;;
+2463;CIRCLED DIGIT FOUR;No;0;EN;<circle> 0034;;4;4;N;;;;;
+2464;CIRCLED DIGIT FIVE;No;0;EN;<circle> 0035;;5;5;N;;;;;
+2465;CIRCLED DIGIT SIX;No;0;EN;<circle> 0036;;6;6;N;;;;;
+2466;CIRCLED DIGIT SEVEN;No;0;EN;<circle> 0037;;7;7;N;;;;;
+2467;CIRCLED DIGIT EIGHT;No;0;EN;<circle> 0038;;8;8;N;;;;;
+2468;CIRCLED DIGIT NINE;No;0;EN;<circle> 0039;;9;9;N;;;;;
+2469;CIRCLED NUMBER TEN;No;0;EN;<circle> 0031 0030;;;10;N;;;;;
+246A;CIRCLED NUMBER ELEVEN;No;0;EN;<circle> 0031 0031;;;11;N;;;;;
+246B;CIRCLED NUMBER TWELVE;No;0;EN;<circle> 0031 0032;;;12;N;;;;;
+246C;CIRCLED NUMBER THIRTEEN;No;0;EN;<circle> 0031 0033;;;13;N;;;;;
+246D;CIRCLED NUMBER FOURTEEN;No;0;EN;<circle> 0031 0034;;;14;N;;;;;
+246E;CIRCLED NUMBER FIFTEEN;No;0;EN;<circle> 0031 0035;;;15;N;;;;;
+246F;CIRCLED NUMBER SIXTEEN;No;0;EN;<circle> 0031 0036;;;16;N;;;;;
+2470;CIRCLED NUMBER SEVENTEEN;No;0;EN;<circle> 0031 0037;;;17;N;;;;;
+2471;CIRCLED NUMBER EIGHTEEN;No;0;EN;<circle> 0031 0038;;;18;N;;;;;
+2472;CIRCLED NUMBER NINETEEN;No;0;EN;<circle> 0031 0039;;;19;N;;;;;
+2473;CIRCLED NUMBER TWENTY;No;0;EN;<circle> 0032 0030;;;20;N;;;;;
+2474;PARENTHESIZED DIGIT ONE;No;0;EN;<compat> 0028 0031 0029;;1;1;N;;;;;
+2475;PARENTHESIZED DIGIT TWO;No;0;EN;<compat> 0028 0032 0029;;2;2;N;;;;;
+2476;PARENTHESIZED DIGIT THREE;No;0;EN;<compat> 0028 0033 0029;;3;3;N;;;;;
+2477;PARENTHESIZED DIGIT FOUR;No;0;EN;<compat> 0028 0034 0029;;4;4;N;;;;;
+2478;PARENTHESIZED DIGIT FIVE;No;0;EN;<compat> 0028 0035 0029;;5;5;N;;;;;
+2479;PARENTHESIZED DIGIT SIX;No;0;EN;<compat> 0028 0036 0029;;6;6;N;;;;;
+247A;PARENTHESIZED DIGIT SEVEN;No;0;EN;<compat> 0028 0037 0029;;7;7;N;;;;;
+247B;PARENTHESIZED DIGIT EIGHT;No;0;EN;<compat> 0028 0038 0029;;8;8;N;;;;;
+247C;PARENTHESIZED DIGIT NINE;No;0;EN;<compat> 0028 0039 0029;;9;9;N;;;;;
+247D;PARENTHESIZED NUMBER TEN;No;0;EN;<compat> 0028 0031 0030 0029;;;10;N;;;;;
+247E;PARENTHESIZED NUMBER ELEVEN;No;0;EN;<compat> 0028 0031 0031 0029;;;11;N;;;;;
+247F;PARENTHESIZED NUMBER TWELVE;No;0;EN;<compat> 0028 0031 0032 0029;;;12;N;;;;;
+2480;PARENTHESIZED NUMBER THIRTEEN;No;0;EN;<compat> 0028 0031 0033 0029;;;13;N;;;;;
+2481;PARENTHESIZED NUMBER FOURTEEN;No;0;EN;<compat> 0028 0031 0034 0029;;;14;N;;;;;
+2482;PARENTHESIZED NUMBER FIFTEEN;No;0;EN;<compat> 0028 0031 0035 0029;;;15;N;;;;;
+2483;PARENTHESIZED NUMBER SIXTEEN;No;0;EN;<compat> 0028 0031 0036 0029;;;16;N;;;;;
+2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;EN;<compat> 0028 0031 0037 0029;;;17;N;;;;;
+2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;EN;<compat> 0028 0031 0038 0029;;;18;N;;;;;
+2486;PARENTHESIZED NUMBER NINETEEN;No;0;EN;<compat> 0028 0031 0039 0029;;;19;N;;;;;
+2487;PARENTHESIZED NUMBER TWENTY;No;0;EN;<compat> 0028 0032 0030 0029;;;20;N;;;;;
+2488;DIGIT ONE FULL STOP;No;0;EN;<compat> 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;;
+2489;DIGIT TWO FULL STOP;No;0;EN;<compat> 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;;
+248A;DIGIT THREE FULL STOP;No;0;EN;<compat> 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;;
+248B;DIGIT FOUR FULL STOP;No;0;EN;<compat> 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;;
+248C;DIGIT FIVE FULL STOP;No;0;EN;<compat> 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;;
+248D;DIGIT SIX FULL STOP;No;0;EN;<compat> 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;;
+248E;DIGIT SEVEN FULL STOP;No;0;EN;<compat> 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;;
+248F;DIGIT EIGHT FULL STOP;No;0;EN;<compat> 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;;
+2490;DIGIT NINE FULL STOP;No;0;EN;<compat> 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;;
+2491;NUMBER TEN FULL STOP;No;0;EN;<compat> 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;;
+2492;NUMBER ELEVEN FULL STOP;No;0;EN;<compat> 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;;
+2493;NUMBER TWELVE FULL STOP;No;0;EN;<compat> 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;;
+2494;NUMBER THIRTEEN FULL STOP;No;0;EN;<compat> 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;;
+2495;NUMBER FOURTEEN FULL STOP;No;0;EN;<compat> 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;;
+2496;NUMBER FIFTEEN FULL STOP;No;0;EN;<compat> 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;;
+2497;NUMBER SIXTEEN FULL STOP;No;0;EN;<compat> 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;;
+2498;NUMBER SEVENTEEN FULL STOP;No;0;EN;<compat> 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;;
+2499;NUMBER EIGHTEEN FULL STOP;No;0;EN;<compat> 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;;
+249A;NUMBER NINETEEN FULL STOP;No;0;EN;<compat> 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;;
+249B;NUMBER TWENTY FULL STOP;No;0;EN;<compat> 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;;
+249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L;<compat> 0028 0061 0029;;;;N;;;;;
+249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L;<compat> 0028 0062 0029;;;;N;;;;;
+249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L;<compat> 0028 0063 0029;;;;N;;;;;
+249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L;<compat> 0028 0064 0029;;;;N;;;;;
+24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L;<compat> 0028 0065 0029;;;;N;;;;;
+24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L;<compat> 0028 0066 0029;;;;N;;;;;
+24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L;<compat> 0028 0067 0029;;;;N;;;;;
+24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L;<compat> 0028 0068 0029;;;;N;;;;;
+24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L;<compat> 0028 0069 0029;;;;N;;;;;
+24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L;<compat> 0028 006A 0029;;;;N;;;;;
+24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L;<compat> 0028 006B 0029;;;;N;;;;;
+24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L;<compat> 0028 006C 0029;;;;N;;;;;
+24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L;<compat> 0028 006D 0029;;;;N;;;;;
+24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L;<compat> 0028 006E 0029;;;;N;;;;;
+24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L;<compat> 0028 006F 0029;;;;N;;;;;
+24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L;<compat> 0028 0070 0029;;;;N;;;;;
+24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L;<compat> 0028 0071 0029;;;;N;;;;;
+24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L;<compat> 0028 0072 0029;;;;N;;;;;
+24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L;<compat> 0028 0073 0029;;;;N;;;;;
+24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L;<compat> 0028 0074 0029;;;;N;;;;;
+24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L;<compat> 0028 0075 0029;;;;N;;;;;
+24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L;<compat> 0028 0076 0029;;;;N;;;;;
+24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L;<compat> 0028 0077 0029;;;;N;;;;;
+24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L;<compat> 0028 0078 0029;;;;N;;;;;
+24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L;<compat> 0028 0079 0029;;;;N;;;;;
+24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L;<compat> 0028 007A 0029;;;;N;;;;;
+24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L;<circle> 0041;;;;N;;;;24D0;
+24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L;<circle> 0042;;;;N;;;;24D1;
+24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;24D2;
+24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L;<circle> 0044;;;;N;;;;24D3;
+24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L;<circle> 0045;;;;N;;;;24D4;
+24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L;<circle> 0046;;;;N;;;;24D5;
+24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L;<circle> 0047;;;;N;;;;24D6;
+24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L;<circle> 0048;;;;N;;;;24D7;
+24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L;<circle> 0049;;;;N;;;;24D8;
+24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L;<circle> 004A;;;;N;;;;24D9;
+24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L;<circle> 004B;;;;N;;;;24DA;
+24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L;<circle> 004C;;;;N;;;;24DB;
+24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L;<circle> 004D;;;;N;;;;24DC;
+24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L;<circle> 004E;;;;N;;;;24DD;
+24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L;<circle> 004F;;;;N;;;;24DE;
+24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L;<circle> 0050;;;;N;;;;24DF;
+24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L;<circle> 0051;;;;N;;;;24E0;
+24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;24E1;
+24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L;<circle> 0053;;;;N;;;;24E2;
+24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L;<circle> 0054;;;;N;;;;24E3;
+24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L;<circle> 0055;;;;N;;;;24E4;
+24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L;<circle> 0056;;;;N;;;;24E5;
+24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L;<circle> 0057;;;;N;;;;24E6;
+24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L;<circle> 0058;;;;N;;;;24E7;
+24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L;<circle> 0059;;;;N;;;;24E8;
+24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L;<circle> 005A;;;;N;;;;24E9;
+24D0;CIRCLED LATIN SMALL LETTER A;So;0;L;<circle> 0061;;;;N;;;24B6;;24B6
+24D1;CIRCLED LATIN SMALL LETTER B;So;0;L;<circle> 0062;;;;N;;;24B7;;24B7
+24D2;CIRCLED LATIN SMALL LETTER C;So;0;L;<circle> 0063;;;;N;;;24B8;;24B8
+24D3;CIRCLED LATIN SMALL LETTER D;So;0;L;<circle> 0064;;;;N;;;24B9;;24B9
+24D4;CIRCLED LATIN SMALL LETTER E;So;0;L;<circle> 0065;;;;N;;;24BA;;24BA
+24D5;CIRCLED LATIN SMALL LETTER F;So;0;L;<circle> 0066;;;;N;;;24BB;;24BB
+24D6;CIRCLED LATIN SMALL LETTER G;So;0;L;<circle> 0067;;;;N;;;24BC;;24BC
+24D7;CIRCLED LATIN SMALL LETTER H;So;0;L;<circle> 0068;;;;N;;;24BD;;24BD
+24D8;CIRCLED LATIN SMALL LETTER I;So;0;L;<circle> 0069;;;;N;;;24BE;;24BE
+24D9;CIRCLED LATIN SMALL LETTER J;So;0;L;<circle> 006A;;;;N;;;24BF;;24BF
+24DA;CIRCLED LATIN SMALL LETTER K;So;0;L;<circle> 006B;;;;N;;;24C0;;24C0
+24DB;CIRCLED LATIN SMALL LETTER L;So;0;L;<circle> 006C;;;;N;;;24C1;;24C1
+24DC;CIRCLED LATIN SMALL LETTER M;So;0;L;<circle> 006D;;;;N;;;24C2;;24C2
+24DD;CIRCLED LATIN SMALL LETTER N;So;0;L;<circle> 006E;;;;N;;;24C3;;24C3
+24DE;CIRCLED LATIN SMALL LETTER O;So;0;L;<circle> 006F;;;;N;;;24C4;;24C4
+24DF;CIRCLED LATIN SMALL LETTER P;So;0;L;<circle> 0070;;;;N;;;24C5;;24C5
+24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L;<circle> 0071;;;;N;;;24C6;;24C6
+24E1;CIRCLED LATIN SMALL LETTER R;So;0;L;<circle> 0072;;;;N;;;24C7;;24C7
+24E2;CIRCLED LATIN SMALL LETTER S;So;0;L;<circle> 0073;;;;N;;;24C8;;24C8
+24E3;CIRCLED LATIN SMALL LETTER T;So;0;L;<circle> 0074;;;;N;;;24C9;;24C9
+24E4;CIRCLED LATIN SMALL LETTER U;So;0;L;<circle> 0075;;;;N;;;24CA;;24CA
+24E5;CIRCLED LATIN SMALL LETTER V;So;0;L;<circle> 0076;;;;N;;;24CB;;24CB
+24E6;CIRCLED LATIN SMALL LETTER W;So;0;L;<circle> 0077;;;;N;;;24CC;;24CC
+24E7;CIRCLED LATIN SMALL LETTER X;So;0;L;<circle> 0078;;;;N;;;24CD;;24CD
+24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L;<circle> 0079;;;;N;;;24CE;;24CE
+24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L;<circle> 007A;;;;N;;;24CF;;24CF
+24EA;CIRCLED DIGIT ZERO;No;0;EN;<circle> 0030;;0;0;N;;;;;
+2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;;
+2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;;
+2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;;
+2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;;
+2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;;
+2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;;
+2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;;
+2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;;
+2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;;
+2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;;
+250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;;
+250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;;
+250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;;
+250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;;
+250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;;
+250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;;
+2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;;
+2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;;
+2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;;
+2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;;
+2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;;
+2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;;
+2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;;
+2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;;
+2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;;
+2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;;
+251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;;
+251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;;
+251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;;
+251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;;
+251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;;
+251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;;
+2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;;
+2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;;
+2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;;
+2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;;
+2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;;
+2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;;
+2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;;
+2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;;
+2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;;
+252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;;
+252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;;
+252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;;
+252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;;
+252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;;
+252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;;
+2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;;
+2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;;
+2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;;
+2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;;
+2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;;
+2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;;
+2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;;
+2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;;
+2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;;
+2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;;
+253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;;
+253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;;
+253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;;
+253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;;
+253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;;
+253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;;
+2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;;
+2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;;
+2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;;
+2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;;
+2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;;
+2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;;
+2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;;
+2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;;
+2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;;
+254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;;
+254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;;
+254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;;
+254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;;
+254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;;
+254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;;
+2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;;
+2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;;
+2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;;
+2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;;
+2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;;
+2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;;
+2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;;
+2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;;
+2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;;
+2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;;
+255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;;
+255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;;
+255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;;
+255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;;
+255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;;
+255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;;
+2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;;
+2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;;
+2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;;
+2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;;
+2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;;
+2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;;
+2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;;
+2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;;
+2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;;
+2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;;
+256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;;
+256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;;
+256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;;
+256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;;
+256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;;
+256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;;
+2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;;
+2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;;
+2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;;
+2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;;
+2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;;
+2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;;
+2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;;
+2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;;
+2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;;
+2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;;
+257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;;
+257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;;
+257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;;
+257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;;
+257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;;
+257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;;
+2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;;
+2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2588;FULL BLOCK;So;0;ON;;;;;N;;;;;
+2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;;
+258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;;
+258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;
+2591;LIGHT SHADE;So;0;ON;;;;;N;;;;;
+2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+2593;DARK SHADE;So;0;ON;;;;;N;;;;;
+2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;;
+25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;;
+25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;;
+25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;
+25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;
+25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;;
+25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;;
+25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;;
+25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;;
+25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;;
+25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;;
+25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;;
+25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;;
+25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;;
+25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;;
+25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;;
+25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;;
+25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;;
+25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;;
+25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;;
+25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;;
+25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;;
+25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;;
+25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;;
+25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;;
+25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;;
+25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;;
+25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;;
+25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;;
+25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+25C9;FISHEYE;So;0;ON;;;;;N;;;;;
+25CA;LOZENGE;So;0;ON;;;;;N;;;;;
+25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;;
+25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25CE;BULLSEYE;So;0;ON;;;;;N;;;;;
+25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;;
+25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E6;WHITE BULLET;So;0;ON;;;;;N;;;;;
+25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;;
+25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;;
+25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;;
+25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;;
+25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+2601;CLOUD;So;0;ON;;;;;N;;;;;
+2602;UMBRELLA;So;0;ON;;;;;N;;;;;
+2603;SNOWMAN;So;0;ON;;;;;N;;;;;
+2604;COMET;So;0;ON;;;;;N;;;;;
+2605;BLACK STAR;So;0;ON;;;;;N;;;;;
+2606;WHITE STAR;So;0;ON;;;;;N;;;;;
+2607;LIGHTNING;So;0;ON;;;;;N;;;;;
+2608;THUNDERSTORM;So;0;ON;;;;;N;;;;;
+2609;SUN;So;0;ON;;;;;N;;;;;
+260A;ASCENDING NODE;So;0;ON;;;;;N;;;;;
+260B;DESCENDING NODE;So;0;ON;;;;;N;;;;;
+260C;CONJUNCTION;So;0;ON;;;;;N;;;;;
+260D;OPPOSITION;So;0;ON;;;;;N;;;;;
+260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;;
+260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;;
+2610;BALLOT BOX;So;0;ON;;;;;N;;;;;
+2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;;
+2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;;
+2613;SALTIRE;So;0;ON;;;;;N;;;;;
+2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
+2621;CAUTION SIGN;So;0;ON;;;;;N;;;;;
+2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;;
+2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;;
+2624;CADUCEUS;So;0;ON;;;;;N;;;;;
+2625;ANKH;So;0;ON;;;;;N;;;;;
+2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;;
+2627;CHI RHO;So;0;ON;;;;;N;;;;;
+2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;;
+2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;;
+262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;;
+262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;;
+262C;ADI SHAKTI;So;0;ON;;;;;N;;;;;
+262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;;
+262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;;
+262F;YIN YANG;So;0;ON;;;;;N;;;;;
+2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;;
+2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;;
+2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;;
+2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;;
+2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;;
+2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;;
+2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;;
+2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;;
+2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;;
+263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;;
+263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;;
+263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263F;MERCURY;So;0;ON;;;;;N;;;;;
+2640;FEMALE SIGN;So;0;ON;;;;;N;;;;;
+2641;EARTH;So;0;ON;;;;;N;;;;;
+2642;MALE SIGN;So;0;ON;;;;;N;;;;;
+2643;JUPITER;So;0;ON;;;;;N;;;;;
+2644;SATURN;So;0;ON;;;;;N;;;;;
+2645;URANUS;So;0;ON;;;;;N;;;;;
+2646;NEPTUNE;So;0;ON;;;;;N;;;;;
+2647;PLUTO;So;0;ON;;;;;N;;;;;
+2648;ARIES;So;0;ON;;;;;N;;;;;
+2649;TAURUS;So;0;ON;;;;;N;;;;;
+264A;GEMINI;So;0;ON;;;;;N;;;;;
+264B;CANCER;So;0;ON;;;;;N;;;;;
+264C;LEO;So;0;ON;;;;;N;;;;;
+264D;VIRGO;So;0;ON;;;;;N;;;;;
+264E;LIBRA;So;0;ON;;;;;N;;;;;
+264F;SCORPIUS;So;0;ON;;;;;N;;;;;
+2650;SAGITTARIUS;So;0;ON;;;;;N;;;;;
+2651;CAPRICORN;So;0;ON;;;;;N;;;;;
+2652;AQUARIUS;So;0;ON;;;;;N;;;;;
+2653;PISCES;So;0;ON;;;;;N;;;;;
+2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;;
+2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;;
+2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;;
+2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;;
+2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;;
+265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;;
+265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;;
+265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;;
+265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;;
+265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;;
+2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;;
+2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;;
+2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;;
+2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;;
+2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;;
+2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;;
+2668;HOT SPRINGS;So;0;ON;;;;;N;;;;;
+2669;QUARTER NOTE;So;0;ON;;;;;N;;;;;
+266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;;
+266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;;
+266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;;
+266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;;
+266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;;
+266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;;
+2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;
+2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;
+2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;
+2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;
+2708;AIRPLANE;So;0;ON;;;;;N;;;;;
+2709;ENVELOPE;So;0;ON;;;;;N;;;;;
+270C;VICTORY HAND;So;0;ON;;;;;N;;;;;
+270D;WRITING HAND;So;0;ON;;;;;N;;;;;
+270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+270F;PENCIL;So;0;ON;;;;;N;;;;;
+2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+2711;WHITE NIB;So;0;ON;;;;;N;;;;;
+2712;BLACK NIB;So;0;ON;;;;;N;;;;;
+2713;CHECK MARK;So;0;ON;;;;;N;;;;;
+2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
+2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2717;BALLOT X;So;0;ON;;;;;N;;;;;
+2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;;
+2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;;
+271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;;
+271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;;
+271D;LATIN CROSS;So;0;ON;;;;;N;;;;;
+271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
+271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;;
+2720;MALTESE CROSS;So;0;ON;;;;;N;;;;;
+2721;STAR OF DAVID;So;0;ON;;;;;N;;;;;
+2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
+272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;
+272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;
+272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;;
+272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;;
+2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;;
+2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;;
+2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;;
+273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;;
+273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;;
+2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;;
+2744;SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2747;SPARKLE;So;0;ON;;;;;N;;;;;
+2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;;
+2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;
+2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;
+2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;
+2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;
+2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;;
+2766;FLORAL HEART;So;0;ON;;;;;N;;;;;
+2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;;
+2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;;
+2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;;
+2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;;
+277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;;
+277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;;
+277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;;
+277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;;
+277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;;
+277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;;
+2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;;
+2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;;
+2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;;
+2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;;
+2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;;
+2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;;
+2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;;
+2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;;
+278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;;
+278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;;
+278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;;
+278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;;
+278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;;
+278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;;
+2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;
+2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;
+2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;
+2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;
+2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;
+279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;
+279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;;
+279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;;
+279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;;
+279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;;
+279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;;
+27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;;
+27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;;
+27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;;
+27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;;
+27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;;
+27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;;
+27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;;
+27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;;
+27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;;
+27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;
+27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;
+27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;;
+27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;;
+27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;;
+27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;;
+27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;
+27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;
+27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;
+2800;BRAILLE PATTERN BLANK;So;0;ON;;;;;N;;;;;
+2801;BRAILLE PATTERN DOTS-1;So;0;ON;;;;;N;;;;;
+2802;BRAILLE PATTERN DOTS-2;So;0;ON;;;;;N;;;;;
+2803;BRAILLE PATTERN DOTS-12;So;0;ON;;;;;N;;;;;
+2804;BRAILLE PATTERN DOTS-3;So;0;ON;;;;;N;;;;;
+2805;BRAILLE PATTERN DOTS-13;So;0;ON;;;;;N;;;;;
+2806;BRAILLE PATTERN DOTS-23;So;0;ON;;;;;N;;;;;
+2807;BRAILLE PATTERN DOTS-123;So;0;ON;;;;;N;;;;;
+2808;BRAILLE PATTERN DOTS-4;So;0;ON;;;;;N;;;;;
+2809;BRAILLE PATTERN DOTS-14;So;0;ON;;;;;N;;;;;
+280A;BRAILLE PATTERN DOTS-24;So;0;ON;;;;;N;;;;;
+280B;BRAILLE PATTERN DOTS-124;So;0;ON;;;;;N;;;;;
+280C;BRAILLE PATTERN DOTS-34;So;0;ON;;;;;N;;;;;
+280D;BRAILLE PATTERN DOTS-134;So;0;ON;;;;;N;;;;;
+280E;BRAILLE PATTERN DOTS-234;So;0;ON;;;;;N;;;;;
+280F;BRAILLE PATTERN DOTS-1234;So;0;ON;;;;;N;;;;;
+2810;BRAILLE PATTERN DOTS-5;So;0;ON;;;;;N;;;;;
+2811;BRAILLE PATTERN DOTS-15;So;0;ON;;;;;N;;;;;
+2812;BRAILLE PATTERN DOTS-25;So;0;ON;;;;;N;;;;;
+2813;BRAILLE PATTERN DOTS-125;So;0;ON;;;;;N;;;;;
+2814;BRAILLE PATTERN DOTS-35;So;0;ON;;;;;N;;;;;
+2815;BRAILLE PATTERN DOTS-135;So;0;ON;;;;;N;;;;;
+2816;BRAILLE PATTERN DOTS-235;So;0;ON;;;;;N;;;;;
+2817;BRAILLE PATTERN DOTS-1235;So;0;ON;;;;;N;;;;;
+2818;BRAILLE PATTERN DOTS-45;So;0;ON;;;;;N;;;;;
+2819;BRAILLE PATTERN DOTS-145;So;0;ON;;;;;N;;;;;
+281A;BRAILLE PATTERN DOTS-245;So;0;ON;;;;;N;;;;;
+281B;BRAILLE PATTERN DOTS-1245;So;0;ON;;;;;N;;;;;
+281C;BRAILLE PATTERN DOTS-345;So;0;ON;;;;;N;;;;;
+281D;BRAILLE PATTERN DOTS-1345;So;0;ON;;;;;N;;;;;
+281E;BRAILLE PATTERN DOTS-2345;So;0;ON;;;;;N;;;;;
+281F;BRAILLE PATTERN DOTS-12345;So;0;ON;;;;;N;;;;;
+2820;BRAILLE PATTERN DOTS-6;So;0;ON;;;;;N;;;;;
+2821;BRAILLE PATTERN DOTS-16;So;0;ON;;;;;N;;;;;
+2822;BRAILLE PATTERN DOTS-26;So;0;ON;;;;;N;;;;;
+2823;BRAILLE PATTERN DOTS-126;So;0;ON;;;;;N;;;;;
+2824;BRAILLE PATTERN DOTS-36;So;0;ON;;;;;N;;;;;
+2825;BRAILLE PATTERN DOTS-136;So;0;ON;;;;;N;;;;;
+2826;BRAILLE PATTERN DOTS-236;So;0;ON;;;;;N;;;;;
+2827;BRAILLE PATTERN DOTS-1236;So;0;ON;;;;;N;;;;;
+2828;BRAILLE PATTERN DOTS-46;So;0;ON;;;;;N;;;;;
+2829;BRAILLE PATTERN DOTS-146;So;0;ON;;;;;N;;;;;
+282A;BRAILLE PATTERN DOTS-246;So;0;ON;;;;;N;;;;;
+282B;BRAILLE PATTERN DOTS-1246;So;0;ON;;;;;N;;;;;
+282C;BRAILLE PATTERN DOTS-346;So;0;ON;;;;;N;;;;;
+282D;BRAILLE PATTERN DOTS-1346;So;0;ON;;;;;N;;;;;
+282E;BRAILLE PATTERN DOTS-2346;So;0;ON;;;;;N;;;;;
+282F;BRAILLE PATTERN DOTS-12346;So;0;ON;;;;;N;;;;;
+2830;BRAILLE PATTERN DOTS-56;So;0;ON;;;;;N;;;;;
+2831;BRAILLE PATTERN DOTS-156;So;0;ON;;;;;N;;;;;
+2832;BRAILLE PATTERN DOTS-256;So;0;ON;;;;;N;;;;;
+2833;BRAILLE PATTERN DOTS-1256;So;0;ON;;;;;N;;;;;
+2834;BRAILLE PATTERN DOTS-356;So;0;ON;;;;;N;;;;;
+2835;BRAILLE PATTERN DOTS-1356;So;0;ON;;;;;N;;;;;
+2836;BRAILLE PATTERN DOTS-2356;So;0;ON;;;;;N;;;;;
+2837;BRAILLE PATTERN DOTS-12356;So;0;ON;;;;;N;;;;;
+2838;BRAILLE PATTERN DOTS-456;So;0;ON;;;;;N;;;;;
+2839;BRAILLE PATTERN DOTS-1456;So;0;ON;;;;;N;;;;;
+283A;BRAILLE PATTERN DOTS-2456;So;0;ON;;;;;N;;;;;
+283B;BRAILLE PATTERN DOTS-12456;So;0;ON;;;;;N;;;;;
+283C;BRAILLE PATTERN DOTS-3456;So;0;ON;;;;;N;;;;;
+283D;BRAILLE PATTERN DOTS-13456;So;0;ON;;;;;N;;;;;
+283E;BRAILLE PATTERN DOTS-23456;So;0;ON;;;;;N;;;;;
+283F;BRAILLE PATTERN DOTS-123456;So;0;ON;;;;;N;;;;;
+2840;BRAILLE PATTERN DOTS-7;So;0;ON;;;;;N;;;;;
+2841;BRAILLE PATTERN DOTS-17;So;0;ON;;;;;N;;;;;
+2842;BRAILLE PATTERN DOTS-27;So;0;ON;;;;;N;;;;;
+2843;BRAILLE PATTERN DOTS-127;So;0;ON;;;;;N;;;;;
+2844;BRAILLE PATTERN DOTS-37;So;0;ON;;;;;N;;;;;
+2845;BRAILLE PATTERN DOTS-137;So;0;ON;;;;;N;;;;;
+2846;BRAILLE PATTERN DOTS-237;So;0;ON;;;;;N;;;;;
+2847;BRAILLE PATTERN DOTS-1237;So;0;ON;;;;;N;;;;;
+2848;BRAILLE PATTERN DOTS-47;So;0;ON;;;;;N;;;;;
+2849;BRAILLE PATTERN DOTS-147;So;0;ON;;;;;N;;;;;
+284A;BRAILLE PATTERN DOTS-247;So;0;ON;;;;;N;;;;;
+284B;BRAILLE PATTERN DOTS-1247;So;0;ON;;;;;N;;;;;
+284C;BRAILLE PATTERN DOTS-347;So;0;ON;;;;;N;;;;;
+284D;BRAILLE PATTERN DOTS-1347;So;0;ON;;;;;N;;;;;
+284E;BRAILLE PATTERN DOTS-2347;So;0;ON;;;;;N;;;;;
+284F;BRAILLE PATTERN DOTS-12347;So;0;ON;;;;;N;;;;;
+2850;BRAILLE PATTERN DOTS-57;So;0;ON;;;;;N;;;;;
+2851;BRAILLE PATTERN DOTS-157;So;0;ON;;;;;N;;;;;
+2852;BRAILLE PATTERN DOTS-257;So;0;ON;;;;;N;;;;;
+2853;BRAILLE PATTERN DOTS-1257;So;0;ON;;;;;N;;;;;
+2854;BRAILLE PATTERN DOTS-357;So;0;ON;;;;;N;;;;;
+2855;BRAILLE PATTERN DOTS-1357;So;0;ON;;;;;N;;;;;
+2856;BRAILLE PATTERN DOTS-2357;So;0;ON;;;;;N;;;;;
+2857;BRAILLE PATTERN DOTS-12357;So;0;ON;;;;;N;;;;;
+2858;BRAILLE PATTERN DOTS-457;So;0;ON;;;;;N;;;;;
+2859;BRAILLE PATTERN DOTS-1457;So;0;ON;;;;;N;;;;;
+285A;BRAILLE PATTERN DOTS-2457;So;0;ON;;;;;N;;;;;
+285B;BRAILLE PATTERN DOTS-12457;So;0;ON;;;;;N;;;;;
+285C;BRAILLE PATTERN DOTS-3457;So;0;ON;;;;;N;;;;;
+285D;BRAILLE PATTERN DOTS-13457;So;0;ON;;;;;N;;;;;
+285E;BRAILLE PATTERN DOTS-23457;So;0;ON;;;;;N;;;;;
+285F;BRAILLE PATTERN DOTS-123457;So;0;ON;;;;;N;;;;;
+2860;BRAILLE PATTERN DOTS-67;So;0;ON;;;;;N;;;;;
+2861;BRAILLE PATTERN DOTS-167;So;0;ON;;;;;N;;;;;
+2862;BRAILLE PATTERN DOTS-267;So;0;ON;;;;;N;;;;;
+2863;BRAILLE PATTERN DOTS-1267;So;0;ON;;;;;N;;;;;
+2864;BRAILLE PATTERN DOTS-367;So;0;ON;;;;;N;;;;;
+2865;BRAILLE PATTERN DOTS-1367;So;0;ON;;;;;N;;;;;
+2866;BRAILLE PATTERN DOTS-2367;So;0;ON;;;;;N;;;;;
+2867;BRAILLE PATTERN DOTS-12367;So;0;ON;;;;;N;;;;;
+2868;BRAILLE PATTERN DOTS-467;So;0;ON;;;;;N;;;;;
+2869;BRAILLE PATTERN DOTS-1467;So;0;ON;;;;;N;;;;;
+286A;BRAILLE PATTERN DOTS-2467;So;0;ON;;;;;N;;;;;
+286B;BRAILLE PATTERN DOTS-12467;So;0;ON;;;;;N;;;;;
+286C;BRAILLE PATTERN DOTS-3467;So;0;ON;;;;;N;;;;;
+286D;BRAILLE PATTERN DOTS-13467;So;0;ON;;;;;N;;;;;
+286E;BRAILLE PATTERN DOTS-23467;So;0;ON;;;;;N;;;;;
+286F;BRAILLE PATTERN DOTS-123467;So;0;ON;;;;;N;;;;;
+2870;BRAILLE PATTERN DOTS-567;So;0;ON;;;;;N;;;;;
+2871;BRAILLE PATTERN DOTS-1567;So;0;ON;;;;;N;;;;;
+2872;BRAILLE PATTERN DOTS-2567;So;0;ON;;;;;N;;;;;
+2873;BRAILLE PATTERN DOTS-12567;So;0;ON;;;;;N;;;;;
+2874;BRAILLE PATTERN DOTS-3567;So;0;ON;;;;;N;;;;;
+2875;BRAILLE PATTERN DOTS-13567;So;0;ON;;;;;N;;;;;
+2876;BRAILLE PATTERN DOTS-23567;So;0;ON;;;;;N;;;;;
+2877;BRAILLE PATTERN DOTS-123567;So;0;ON;;;;;N;;;;;
+2878;BRAILLE PATTERN DOTS-4567;So;0;ON;;;;;N;;;;;
+2879;BRAILLE PATTERN DOTS-14567;So;0;ON;;;;;N;;;;;
+287A;BRAILLE PATTERN DOTS-24567;So;0;ON;;;;;N;;;;;
+287B;BRAILLE PATTERN DOTS-124567;So;0;ON;;;;;N;;;;;
+287C;BRAILLE PATTERN DOTS-34567;So;0;ON;;;;;N;;;;;
+287D;BRAILLE PATTERN DOTS-134567;So;0;ON;;;;;N;;;;;
+287E;BRAILLE PATTERN DOTS-234567;So;0;ON;;;;;N;;;;;
+287F;BRAILLE PATTERN DOTS-1234567;So;0;ON;;;;;N;;;;;
+2880;BRAILLE PATTERN DOTS-8;So;0;ON;;;;;N;;;;;
+2881;BRAILLE PATTERN DOTS-18;So;0;ON;;;;;N;;;;;
+2882;BRAILLE PATTERN DOTS-28;So;0;ON;;;;;N;;;;;
+2883;BRAILLE PATTERN DOTS-128;So;0;ON;;;;;N;;;;;
+2884;BRAILLE PATTERN DOTS-38;So;0;ON;;;;;N;;;;;
+2885;BRAILLE PATTERN DOTS-138;So;0;ON;;;;;N;;;;;
+2886;BRAILLE PATTERN DOTS-238;So;0;ON;;;;;N;;;;;
+2887;BRAILLE PATTERN DOTS-1238;So;0;ON;;;;;N;;;;;
+2888;BRAILLE PATTERN DOTS-48;So;0;ON;;;;;N;;;;;
+2889;BRAILLE PATTERN DOTS-148;So;0;ON;;;;;N;;;;;
+288A;BRAILLE PATTERN DOTS-248;So;0;ON;;;;;N;;;;;
+288B;BRAILLE PATTERN DOTS-1248;So;0;ON;;;;;N;;;;;
+288C;BRAILLE PATTERN DOTS-348;So;0;ON;;;;;N;;;;;
+288D;BRAILLE PATTERN DOTS-1348;So;0;ON;;;;;N;;;;;
+288E;BRAILLE PATTERN DOTS-2348;So;0;ON;;;;;N;;;;;
+288F;BRAILLE PATTERN DOTS-12348;So;0;ON;;;;;N;;;;;
+2890;BRAILLE PATTERN DOTS-58;So;0;ON;;;;;N;;;;;
+2891;BRAILLE PATTERN DOTS-158;So;0;ON;;;;;N;;;;;
+2892;BRAILLE PATTERN DOTS-258;So;0;ON;;;;;N;;;;;
+2893;BRAILLE PATTERN DOTS-1258;So;0;ON;;;;;N;;;;;
+2894;BRAILLE PATTERN DOTS-358;So;0;ON;;;;;N;;;;;
+2895;BRAILLE PATTERN DOTS-1358;So;0;ON;;;;;N;;;;;
+2896;BRAILLE PATTERN DOTS-2358;So;0;ON;;;;;N;;;;;
+2897;BRAILLE PATTERN DOTS-12358;So;0;ON;;;;;N;;;;;
+2898;BRAILLE PATTERN DOTS-458;So;0;ON;;;;;N;;;;;
+2899;BRAILLE PATTERN DOTS-1458;So;0;ON;;;;;N;;;;;
+289A;BRAILLE PATTERN DOTS-2458;So;0;ON;;;;;N;;;;;
+289B;BRAILLE PATTERN DOTS-12458;So;0;ON;;;;;N;;;;;
+289C;BRAILLE PATTERN DOTS-3458;So;0;ON;;;;;N;;;;;
+289D;BRAILLE PATTERN DOTS-13458;So;0;ON;;;;;N;;;;;
+289E;BRAILLE PATTERN DOTS-23458;So;0;ON;;;;;N;;;;;
+289F;BRAILLE PATTERN DOTS-123458;So;0;ON;;;;;N;;;;;
+28A0;BRAILLE PATTERN DOTS-68;So;0;ON;;;;;N;;;;;
+28A1;BRAILLE PATTERN DOTS-168;So;0;ON;;;;;N;;;;;
+28A2;BRAILLE PATTERN DOTS-268;So;0;ON;;;;;N;;;;;
+28A3;BRAILLE PATTERN DOTS-1268;So;0;ON;;;;;N;;;;;
+28A4;BRAILLE PATTERN DOTS-368;So;0;ON;;;;;N;;;;;
+28A5;BRAILLE PATTERN DOTS-1368;So;0;ON;;;;;N;;;;;
+28A6;BRAILLE PATTERN DOTS-2368;So;0;ON;;;;;N;;;;;
+28A7;BRAILLE PATTERN DOTS-12368;So;0;ON;;;;;N;;;;;
+28A8;BRAILLE PATTERN DOTS-468;So;0;ON;;;;;N;;;;;
+28A9;BRAILLE PATTERN DOTS-1468;So;0;ON;;;;;N;;;;;
+28AA;BRAILLE PATTERN DOTS-2468;So;0;ON;;;;;N;;;;;
+28AB;BRAILLE PATTERN DOTS-12468;So;0;ON;;;;;N;;;;;
+28AC;BRAILLE PATTERN DOTS-3468;So;0;ON;;;;;N;;;;;
+28AD;BRAILLE PATTERN DOTS-13468;So;0;ON;;;;;N;;;;;
+28AE;BRAILLE PATTERN DOTS-23468;So;0;ON;;;;;N;;;;;
+28AF;BRAILLE PATTERN DOTS-123468;So;0;ON;;;;;N;;;;;
+28B0;BRAILLE PATTERN DOTS-568;So;0;ON;;;;;N;;;;;
+28B1;BRAILLE PATTERN DOTS-1568;So;0;ON;;;;;N;;;;;
+28B2;BRAILLE PATTERN DOTS-2568;So;0;ON;;;;;N;;;;;
+28B3;BRAILLE PATTERN DOTS-12568;So;0;ON;;;;;N;;;;;
+28B4;BRAILLE PATTERN DOTS-3568;So;0;ON;;;;;N;;;;;
+28B5;BRAILLE PATTERN DOTS-13568;So;0;ON;;;;;N;;;;;
+28B6;BRAILLE PATTERN DOTS-23568;So;0;ON;;;;;N;;;;;
+28B7;BRAILLE PATTERN DOTS-123568;So;0;ON;;;;;N;;;;;
+28B8;BRAILLE PATTERN DOTS-4568;So;0;ON;;;;;N;;;;;
+28B9;BRAILLE PATTERN DOTS-14568;So;0;ON;;;;;N;;;;;
+28BA;BRAILLE PATTERN DOTS-24568;So;0;ON;;;;;N;;;;;
+28BB;BRAILLE PATTERN DOTS-124568;So;0;ON;;;;;N;;;;;
+28BC;BRAILLE PATTERN DOTS-34568;So;0;ON;;;;;N;;;;;
+28BD;BRAILLE PATTERN DOTS-134568;So;0;ON;;;;;N;;;;;
+28BE;BRAILLE PATTERN DOTS-234568;So;0;ON;;;;;N;;;;;
+28BF;BRAILLE PATTERN DOTS-1234568;So;0;ON;;;;;N;;;;;
+28C0;BRAILLE PATTERN DOTS-78;So;0;ON;;;;;N;;;;;
+28C1;BRAILLE PATTERN DOTS-178;So;0;ON;;;;;N;;;;;
+28C2;BRAILLE PATTERN DOTS-278;So;0;ON;;;;;N;;;;;
+28C3;BRAILLE PATTERN DOTS-1278;So;0;ON;;;;;N;;;;;
+28C4;BRAILLE PATTERN DOTS-378;So;0;ON;;;;;N;;;;;
+28C5;BRAILLE PATTERN DOTS-1378;So;0;ON;;;;;N;;;;;
+28C6;BRAILLE PATTERN DOTS-2378;So;0;ON;;;;;N;;;;;
+28C7;BRAILLE PATTERN DOTS-12378;So;0;ON;;;;;N;;;;;
+28C8;BRAILLE PATTERN DOTS-478;So;0;ON;;;;;N;;;;;
+28C9;BRAILLE PATTERN DOTS-1478;So;0;ON;;;;;N;;;;;
+28CA;BRAILLE PATTERN DOTS-2478;So;0;ON;;;;;N;;;;;
+28CB;BRAILLE PATTERN DOTS-12478;So;0;ON;;;;;N;;;;;
+28CC;BRAILLE PATTERN DOTS-3478;So;0;ON;;;;;N;;;;;
+28CD;BRAILLE PATTERN DOTS-13478;So;0;ON;;;;;N;;;;;
+28CE;BRAILLE PATTERN DOTS-23478;So;0;ON;;;;;N;;;;;
+28CF;BRAILLE PATTERN DOTS-123478;So;0;ON;;;;;N;;;;;
+28D0;BRAILLE PATTERN DOTS-578;So;0;ON;;;;;N;;;;;
+28D1;BRAILLE PATTERN DOTS-1578;So;0;ON;;;;;N;;;;;
+28D2;BRAILLE PATTERN DOTS-2578;So;0;ON;;;;;N;;;;;
+28D3;BRAILLE PATTERN DOTS-12578;So;0;ON;;;;;N;;;;;
+28D4;BRAILLE PATTERN DOTS-3578;So;0;ON;;;;;N;;;;;
+28D5;BRAILLE PATTERN DOTS-13578;So;0;ON;;;;;N;;;;;
+28D6;BRAILLE PATTERN DOTS-23578;So;0;ON;;;;;N;;;;;
+28D7;BRAILLE PATTERN DOTS-123578;So;0;ON;;;;;N;;;;;
+28D8;BRAILLE PATTERN DOTS-4578;So;0;ON;;;;;N;;;;;
+28D9;BRAILLE PATTERN DOTS-14578;So;0;ON;;;;;N;;;;;
+28DA;BRAILLE PATTERN DOTS-24578;So;0;ON;;;;;N;;;;;
+28DB;BRAILLE PATTERN DOTS-124578;So;0;ON;;;;;N;;;;;
+28DC;BRAILLE PATTERN DOTS-34578;So;0;ON;;;;;N;;;;;
+28DD;BRAILLE PATTERN DOTS-134578;So;0;ON;;;;;N;;;;;
+28DE;BRAILLE PATTERN DOTS-234578;So;0;ON;;;;;N;;;;;
+28DF;BRAILLE PATTERN DOTS-1234578;So;0;ON;;;;;N;;;;;
+28E0;BRAILLE PATTERN DOTS-678;So;0;ON;;;;;N;;;;;
+28E1;BRAILLE PATTERN DOTS-1678;So;0;ON;;;;;N;;;;;
+28E2;BRAILLE PATTERN DOTS-2678;So;0;ON;;;;;N;;;;;
+28E3;BRAILLE PATTERN DOTS-12678;So;0;ON;;;;;N;;;;;
+28E4;BRAILLE PATTERN DOTS-3678;So;0;ON;;;;;N;;;;;
+28E5;BRAILLE PATTERN DOTS-13678;So;0;ON;;;;;N;;;;;
+28E6;BRAILLE PATTERN DOTS-23678;So;0;ON;;;;;N;;;;;
+28E7;BRAILLE PATTERN DOTS-123678;So;0;ON;;;;;N;;;;;
+28E8;BRAILLE PATTERN DOTS-4678;So;0;ON;;;;;N;;;;;
+28E9;BRAILLE PATTERN DOTS-14678;So;0;ON;;;;;N;;;;;
+28EA;BRAILLE PATTERN DOTS-24678;So;0;ON;;;;;N;;;;;
+28EB;BRAILLE PATTERN DOTS-124678;So;0;ON;;;;;N;;;;;
+28EC;BRAILLE PATTERN DOTS-34678;So;0;ON;;;;;N;;;;;
+28ED;BRAILLE PATTERN DOTS-134678;So;0;ON;;;;;N;;;;;
+28EE;BRAILLE PATTERN DOTS-234678;So;0;ON;;;;;N;;;;;
+28EF;BRAILLE PATTERN DOTS-1234678;So;0;ON;;;;;N;;;;;
+28F0;BRAILLE PATTERN DOTS-5678;So;0;ON;;;;;N;;;;;
+28F1;BRAILLE PATTERN DOTS-15678;So;0;ON;;;;;N;;;;;
+28F2;BRAILLE PATTERN DOTS-25678;So;0;ON;;;;;N;;;;;
+28F3;BRAILLE PATTERN DOTS-125678;So;0;ON;;;;;N;;;;;
+28F4;BRAILLE PATTERN DOTS-35678;So;0;ON;;;;;N;;;;;
+28F5;BRAILLE PATTERN DOTS-135678;So;0;ON;;;;;N;;;;;
+28F6;BRAILLE PATTERN DOTS-235678;So;0;ON;;;;;N;;;;;
+28F7;BRAILLE PATTERN DOTS-1235678;So;0;ON;;;;;N;;;;;
+28F8;BRAILLE PATTERN DOTS-45678;So;0;ON;;;;;N;;;;;
+28F9;BRAILLE PATTERN DOTS-145678;So;0;ON;;;;;N;;;;;
+28FA;BRAILLE PATTERN DOTS-245678;So;0;ON;;;;;N;;;;;
+28FB;BRAILLE PATTERN DOTS-1245678;So;0;ON;;;;;N;;;;;
+28FC;BRAILLE PATTERN DOTS-345678;So;0;ON;;;;;N;;;;;
+28FD;BRAILLE PATTERN DOTS-1345678;So;0;ON;;;;;N;;;;;
+28FE;BRAILLE PATTERN DOTS-2345678;So;0;ON;;;;;N;;;;;
+28FF;BRAILLE PATTERN DOTS-12345678;So;0;ON;;;;;N;;;;;
+2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
+2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
+2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
+2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;;
+2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;;
+2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;;
+2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;;
+2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;;
+2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;;
+2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;;
+2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;;
+2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;;
+2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;;
+2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;;
+2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;;
+2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;;
+2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;;
+2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;;
+2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;;
+2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;;
+2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;;
+2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;;
+2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;;
+2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;;
+2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;;
+2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;;
+2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;;
+2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;;
+2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;;
+2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;;
+2E9F;CJK RADICAL MOTHER;So;0;ON;<compat> 6BCD;;;;N;;;;;
+2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;;
+2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;;
+2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;;
+2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;;
+2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;;
+2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;;
+2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;;
+2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;;
+2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;;
+2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;;
+2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;;
+2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;;
+2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;;
+2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;;
+2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;;
+2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;;
+2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;;
+2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;;
+2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;;
+2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;;
+2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;;
+2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;;
+2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;;
+2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;;
+2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;;
+2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;;
+2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;;
+2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;;
+2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;;
+2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;;
+2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;;
+2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;;
+2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;;
+2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;;
+2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;;
+2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;;
+2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;;
+2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;;
+2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;;
+2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;;
+2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;;
+2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;;
+2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;;
+2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;;
+2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;;
+2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;;
+2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;;
+2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;;
+2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;;
+2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;;
+2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;;
+2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;;
+2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;;
+2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;;
+2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;;
+2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;;
+2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;;
+2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;;
+2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;;
+2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;;
+2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;;
+2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;;
+2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;;
+2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;;
+2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;;
+2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;;
+2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;;
+2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;;
+2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;;
+2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;;
+2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;;
+2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;;
+2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;;
+2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;;
+2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;;
+2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;;
+2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;;
+2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON;<compat> 9F9F;;;;N;;;;;
+2F00;KANGXI RADICAL ONE;So;0;ON;<compat> 4E00;;;;N;;;;;
+2F01;KANGXI RADICAL LINE;So;0;ON;<compat> 4E28;;;;N;;;;;
+2F02;KANGXI RADICAL DOT;So;0;ON;<compat> 4E36;;;;N;;;;;
+2F03;KANGXI RADICAL SLASH;So;0;ON;<compat> 4E3F;;;;N;;;;;
+2F04;KANGXI RADICAL SECOND;So;0;ON;<compat> 4E59;;;;N;;;;;
+2F05;KANGXI RADICAL HOOK;So;0;ON;<compat> 4E85;;;;N;;;;;
+2F06;KANGXI RADICAL TWO;So;0;ON;<compat> 4E8C;;;;N;;;;;
+2F07;KANGXI RADICAL LID;So;0;ON;<compat> 4EA0;;;;N;;;;;
+2F08;KANGXI RADICAL MAN;So;0;ON;<compat> 4EBA;;;;N;;;;;
+2F09;KANGXI RADICAL LEGS;So;0;ON;<compat> 513F;;;;N;;;;;
+2F0A;KANGXI RADICAL ENTER;So;0;ON;<compat> 5165;;;;N;;;;;
+2F0B;KANGXI RADICAL EIGHT;So;0;ON;<compat> 516B;;;;N;;;;;
+2F0C;KANGXI RADICAL DOWN BOX;So;0;ON;<compat> 5182;;;;N;;;;;
+2F0D;KANGXI RADICAL COVER;So;0;ON;<compat> 5196;;;;N;;;;;
+2F0E;KANGXI RADICAL ICE;So;0;ON;<compat> 51AB;;;;N;;;;;
+2F0F;KANGXI RADICAL TABLE;So;0;ON;<compat> 51E0;;;;N;;;;;
+2F10;KANGXI RADICAL OPEN BOX;So;0;ON;<compat> 51F5;;;;N;;;;;
+2F11;KANGXI RADICAL KNIFE;So;0;ON;<compat> 5200;;;;N;;;;;
+2F12;KANGXI RADICAL POWER;So;0;ON;<compat> 529B;;;;N;;;;;
+2F13;KANGXI RADICAL WRAP;So;0;ON;<compat> 52F9;;;;N;;;;;
+2F14;KANGXI RADICAL SPOON;So;0;ON;<compat> 5315;;;;N;;;;;
+2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON;<compat> 531A;;;;N;;;;;
+2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON;<compat> 5338;;;;N;;;;;
+2F17;KANGXI RADICAL TEN;So;0;ON;<compat> 5341;;;;N;;;;;
+2F18;KANGXI RADICAL DIVINATION;So;0;ON;<compat> 535C;;;;N;;;;;
+2F19;KANGXI RADICAL SEAL;So;0;ON;<compat> 5369;;;;N;;;;;
+2F1A;KANGXI RADICAL CLIFF;So;0;ON;<compat> 5382;;;;N;;;;;
+2F1B;KANGXI RADICAL PRIVATE;So;0;ON;<compat> 53B6;;;;N;;;;;
+2F1C;KANGXI RADICAL AGAIN;So;0;ON;<compat> 53C8;;;;N;;;;;
+2F1D;KANGXI RADICAL MOUTH;So;0;ON;<compat> 53E3;;;;N;;;;;
+2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON;<compat> 56D7;;;;N;;;;;
+2F1F;KANGXI RADICAL EARTH;So;0;ON;<compat> 571F;;;;N;;;;;
+2F20;KANGXI RADICAL SCHOLAR;So;0;ON;<compat> 58EB;;;;N;;;;;
+2F21;KANGXI RADICAL GO;So;0;ON;<compat> 5902;;;;N;;;;;
+2F22;KANGXI RADICAL GO SLOWLY;So;0;ON;<compat> 590A;;;;N;;;;;
+2F23;KANGXI RADICAL EVENING;So;0;ON;<compat> 5915;;;;N;;;;;
+2F24;KANGXI RADICAL BIG;So;0;ON;<compat> 5927;;;;N;;;;;
+2F25;KANGXI RADICAL WOMAN;So;0;ON;<compat> 5973;;;;N;;;;;
+2F26;KANGXI RADICAL CHILD;So;0;ON;<compat> 5B50;;;;N;;;;;
+2F27;KANGXI RADICAL ROOF;So;0;ON;<compat> 5B80;;;;N;;;;;
+2F28;KANGXI RADICAL INCH;So;0;ON;<compat> 5BF8;;;;N;;;;;
+2F29;KANGXI RADICAL SMALL;So;0;ON;<compat> 5C0F;;;;N;;;;;
+2F2A;KANGXI RADICAL LAME;So;0;ON;<compat> 5C22;;;;N;;;;;
+2F2B;KANGXI RADICAL CORPSE;So;0;ON;<compat> 5C38;;;;N;;;;;
+2F2C;KANGXI RADICAL SPROUT;So;0;ON;<compat> 5C6E;;;;N;;;;;
+2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON;<compat> 5C71;;;;N;;;;;
+2F2E;KANGXI RADICAL RIVER;So;0;ON;<compat> 5DDB;;;;N;;;;;
+2F2F;KANGXI RADICAL WORK;So;0;ON;<compat> 5DE5;;;;N;;;;;
+2F30;KANGXI RADICAL ONESELF;So;0;ON;<compat> 5DF1;;;;N;;;;;
+2F31;KANGXI RADICAL TURBAN;So;0;ON;<compat> 5DFE;;;;N;;;;;
+2F32;KANGXI RADICAL DRY;So;0;ON;<compat> 5E72;;;;N;;;;;
+2F33;KANGXI RADICAL SHORT THREAD;So;0;ON;<compat> 5E7A;;;;N;;;;;
+2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON;<compat> 5E7F;;;;N;;;;;
+2F35;KANGXI RADICAL LONG STRIDE;So;0;ON;<compat> 5EF4;;;;N;;;;;
+2F36;KANGXI RADICAL TWO HANDS;So;0;ON;<compat> 5EFE;;;;N;;;;;
+2F37;KANGXI RADICAL SHOOT;So;0;ON;<compat> 5F0B;;;;N;;;;;
+2F38;KANGXI RADICAL BOW;So;0;ON;<compat> 5F13;;;;N;;;;;
+2F39;KANGXI RADICAL SNOUT;So;0;ON;<compat> 5F50;;;;N;;;;;
+2F3A;KANGXI RADICAL BRISTLE;So;0;ON;<compat> 5F61;;;;N;;;;;
+2F3B;KANGXI RADICAL STEP;So;0;ON;<compat> 5F73;;;;N;;;;;
+2F3C;KANGXI RADICAL HEART;So;0;ON;<compat> 5FC3;;;;N;;;;;
+2F3D;KANGXI RADICAL HALBERD;So;0;ON;<compat> 6208;;;;N;;;;;
+2F3E;KANGXI RADICAL DOOR;So;0;ON;<compat> 6236;;;;N;;;;;
+2F3F;KANGXI RADICAL HAND;So;0;ON;<compat> 624B;;;;N;;;;;
+2F40;KANGXI RADICAL BRANCH;So;0;ON;<compat> 652F;;;;N;;;;;
+2F41;KANGXI RADICAL RAP;So;0;ON;<compat> 6534;;;;N;;;;;
+2F42;KANGXI RADICAL SCRIPT;So;0;ON;<compat> 6587;;;;N;;;;;
+2F43;KANGXI RADICAL DIPPER;So;0;ON;<compat> 6597;;;;N;;;;;
+2F44;KANGXI RADICAL AXE;So;0;ON;<compat> 65A4;;;;N;;;;;
+2F45;KANGXI RADICAL SQUARE;So;0;ON;<compat> 65B9;;;;N;;;;;
+2F46;KANGXI RADICAL NOT;So;0;ON;<compat> 65E0;;;;N;;;;;
+2F47;KANGXI RADICAL SUN;So;0;ON;<compat> 65E5;;;;N;;;;;
+2F48;KANGXI RADICAL SAY;So;0;ON;<compat> 66F0;;;;N;;;;;
+2F49;KANGXI RADICAL MOON;So;0;ON;<compat> 6708;;;;N;;;;;
+2F4A;KANGXI RADICAL TREE;So;0;ON;<compat> 6728;;;;N;;;;;
+2F4B;KANGXI RADICAL LACK;So;0;ON;<compat> 6B20;;;;N;;;;;
+2F4C;KANGXI RADICAL STOP;So;0;ON;<compat> 6B62;;;;N;;;;;
+2F4D;KANGXI RADICAL DEATH;So;0;ON;<compat> 6B79;;;;N;;;;;
+2F4E;KANGXI RADICAL WEAPON;So;0;ON;<compat> 6BB3;;;;N;;;;;
+2F4F;KANGXI RADICAL DO NOT;So;0;ON;<compat> 6BCB;;;;N;;;;;
+2F50;KANGXI RADICAL COMPARE;So;0;ON;<compat> 6BD4;;;;N;;;;;
+2F51;KANGXI RADICAL FUR;So;0;ON;<compat> 6BDB;;;;N;;;;;
+2F52;KANGXI RADICAL CLAN;So;0;ON;<compat> 6C0F;;;;N;;;;;
+2F53;KANGXI RADICAL STEAM;So;0;ON;<compat> 6C14;;;;N;;;;;
+2F54;KANGXI RADICAL WATER;So;0;ON;<compat> 6C34;;;;N;;;;;
+2F55;KANGXI RADICAL FIRE;So;0;ON;<compat> 706B;;;;N;;;;;
+2F56;KANGXI RADICAL CLAW;So;0;ON;<compat> 722A;;;;N;;;;;
+2F57;KANGXI RADICAL FATHER;So;0;ON;<compat> 7236;;;;N;;;;;
+2F58;KANGXI RADICAL DOUBLE X;So;0;ON;<compat> 723B;;;;N;;;;;
+2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON;<compat> 723F;;;;N;;;;;
+2F5A;KANGXI RADICAL SLICE;So;0;ON;<compat> 7247;;;;N;;;;;
+2F5B;KANGXI RADICAL FANG;So;0;ON;<compat> 7259;;;;N;;;;;
+2F5C;KANGXI RADICAL COW;So;0;ON;<compat> 725B;;;;N;;;;;
+2F5D;KANGXI RADICAL DOG;So;0;ON;<compat> 72AC;;;;N;;;;;
+2F5E;KANGXI RADICAL PROFOUND;So;0;ON;<compat> 7384;;;;N;;;;;
+2F5F;KANGXI RADICAL JADE;So;0;ON;<compat> 7389;;;;N;;;;;
+2F60;KANGXI RADICAL MELON;So;0;ON;<compat> 74DC;;;;N;;;;;
+2F61;KANGXI RADICAL TILE;So;0;ON;<compat> 74E6;;;;N;;;;;
+2F62;KANGXI RADICAL SWEET;So;0;ON;<compat> 7518;;;;N;;;;;
+2F63;KANGXI RADICAL LIFE;So;0;ON;<compat> 751F;;;;N;;;;;
+2F64;KANGXI RADICAL USE;So;0;ON;<compat> 7528;;;;N;;;;;
+2F65;KANGXI RADICAL FIELD;So;0;ON;<compat> 7530;;;;N;;;;;
+2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON;<compat> 758B;;;;N;;;;;
+2F67;KANGXI RADICAL SICKNESS;So;0;ON;<compat> 7592;;;;N;;;;;
+2F68;KANGXI RADICAL DOTTED TENT;So;0;ON;<compat> 7676;;;;N;;;;;
+2F69;KANGXI RADICAL WHITE;So;0;ON;<compat> 767D;;;;N;;;;;
+2F6A;KANGXI RADICAL SKIN;So;0;ON;<compat> 76AE;;;;N;;;;;
+2F6B;KANGXI RADICAL DISH;So;0;ON;<compat> 76BF;;;;N;;;;;
+2F6C;KANGXI RADICAL EYE;So;0;ON;<compat> 76EE;;;;N;;;;;
+2F6D;KANGXI RADICAL SPEAR;So;0;ON;<compat> 77DB;;;;N;;;;;
+2F6E;KANGXI RADICAL ARROW;So;0;ON;<compat> 77E2;;;;N;;;;;
+2F6F;KANGXI RADICAL STONE;So;0;ON;<compat> 77F3;;;;N;;;;;
+2F70;KANGXI RADICAL SPIRIT;So;0;ON;<compat> 793A;;;;N;;;;;
+2F71;KANGXI RADICAL TRACK;So;0;ON;<compat> 79B8;;;;N;;;;;
+2F72;KANGXI RADICAL GRAIN;So;0;ON;<compat> 79BE;;;;N;;;;;
+2F73;KANGXI RADICAL CAVE;So;0;ON;<compat> 7A74;;;;N;;;;;
+2F74;KANGXI RADICAL STAND;So;0;ON;<compat> 7ACB;;;;N;;;;;
+2F75;KANGXI RADICAL BAMBOO;So;0;ON;<compat> 7AF9;;;;N;;;;;
+2F76;KANGXI RADICAL RICE;So;0;ON;<compat> 7C73;;;;N;;;;;
+2F77;KANGXI RADICAL SILK;So;0;ON;<compat> 7CF8;;;;N;;;;;
+2F78;KANGXI RADICAL JAR;So;0;ON;<compat> 7F36;;;;N;;;;;
+2F79;KANGXI RADICAL NET;So;0;ON;<compat> 7F51;;;;N;;;;;
+2F7A;KANGXI RADICAL SHEEP;So;0;ON;<compat> 7F8A;;;;N;;;;;
+2F7B;KANGXI RADICAL FEATHER;So;0;ON;<compat> 7FBD;;;;N;;;;;
+2F7C;KANGXI RADICAL OLD;So;0;ON;<compat> 8001;;;;N;;;;;
+2F7D;KANGXI RADICAL AND;So;0;ON;<compat> 800C;;;;N;;;;;
+2F7E;KANGXI RADICAL PLOW;So;0;ON;<compat> 8012;;;;N;;;;;
+2F7F;KANGXI RADICAL EAR;So;0;ON;<compat> 8033;;;;N;;;;;
+2F80;KANGXI RADICAL BRUSH;So;0;ON;<compat> 807F;;;;N;;;;;
+2F81;KANGXI RADICAL MEAT;So;0;ON;<compat> 8089;;;;N;;;;;
+2F82;KANGXI RADICAL MINISTER;So;0;ON;<compat> 81E3;;;;N;;;;;
+2F83;KANGXI RADICAL SELF;So;0;ON;<compat> 81EA;;;;N;;;;;
+2F84;KANGXI RADICAL ARRIVE;So;0;ON;<compat> 81F3;;;;N;;;;;
+2F85;KANGXI RADICAL MORTAR;So;0;ON;<compat> 81FC;;;;N;;;;;
+2F86;KANGXI RADICAL TONGUE;So;0;ON;<compat> 820C;;;;N;;;;;
+2F87;KANGXI RADICAL OPPOSE;So;0;ON;<compat> 821B;;;;N;;;;;
+2F88;KANGXI RADICAL BOAT;So;0;ON;<compat> 821F;;;;N;;;;;
+2F89;KANGXI RADICAL STOPPING;So;0;ON;<compat> 826E;;;;N;;;;;
+2F8A;KANGXI RADICAL COLOR;So;0;ON;<compat> 8272;;;;N;;;;;
+2F8B;KANGXI RADICAL GRASS;So;0;ON;<compat> 8278;;;;N;;;;;
+2F8C;KANGXI RADICAL TIGER;So;0;ON;<compat> 864D;;;;N;;;;;
+2F8D;KANGXI RADICAL INSECT;So;0;ON;<compat> 866B;;;;N;;;;;
+2F8E;KANGXI RADICAL BLOOD;So;0;ON;<compat> 8840;;;;N;;;;;
+2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON;<compat> 884C;;;;N;;;;;
+2F90;KANGXI RADICAL CLOTHES;So;0;ON;<compat> 8863;;;;N;;;;;
+2F91;KANGXI RADICAL WEST;So;0;ON;<compat> 897E;;;;N;;;;;
+2F92;KANGXI RADICAL SEE;So;0;ON;<compat> 898B;;;;N;;;;;
+2F93;KANGXI RADICAL HORN;So;0;ON;<compat> 89D2;;;;N;;;;;
+2F94;KANGXI RADICAL SPEECH;So;0;ON;<compat> 8A00;;;;N;;;;;
+2F95;KANGXI RADICAL VALLEY;So;0;ON;<compat> 8C37;;;;N;;;;;
+2F96;KANGXI RADICAL BEAN;So;0;ON;<compat> 8C46;;;;N;;;;;
+2F97;KANGXI RADICAL PIG;So;0;ON;<compat> 8C55;;;;N;;;;;
+2F98;KANGXI RADICAL BADGER;So;0;ON;<compat> 8C78;;;;N;;;;;
+2F99;KANGXI RADICAL SHELL;So;0;ON;<compat> 8C9D;;;;N;;;;;
+2F9A;KANGXI RADICAL RED;So;0;ON;<compat> 8D64;;;;N;;;;;
+2F9B;KANGXI RADICAL RUN;So;0;ON;<compat> 8D70;;;;N;;;;;
+2F9C;KANGXI RADICAL FOOT;So;0;ON;<compat> 8DB3;;;;N;;;;;
+2F9D;KANGXI RADICAL BODY;So;0;ON;<compat> 8EAB;;;;N;;;;;
+2F9E;KANGXI RADICAL CART;So;0;ON;<compat> 8ECA;;;;N;;;;;
+2F9F;KANGXI RADICAL BITTER;So;0;ON;<compat> 8F9B;;;;N;;;;;
+2FA0;KANGXI RADICAL MORNING;So;0;ON;<compat> 8FB0;;;;N;;;;;
+2FA1;KANGXI RADICAL WALK;So;0;ON;<compat> 8FB5;;;;N;;;;;
+2FA2;KANGXI RADICAL CITY;So;0;ON;<compat> 9091;;;;N;;;;;
+2FA3;KANGXI RADICAL WINE;So;0;ON;<compat> 9149;;;;N;;;;;
+2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON;<compat> 91C6;;;;N;;;;;
+2FA5;KANGXI RADICAL VILLAGE;So;0;ON;<compat> 91CC;;;;N;;;;;
+2FA6;KANGXI RADICAL GOLD;So;0;ON;<compat> 91D1;;;;N;;;;;
+2FA7;KANGXI RADICAL LONG;So;0;ON;<compat> 9577;;;;N;;;;;
+2FA8;KANGXI RADICAL GATE;So;0;ON;<compat> 9580;;;;N;;;;;
+2FA9;KANGXI RADICAL MOUND;So;0;ON;<compat> 961C;;;;N;;;;;
+2FAA;KANGXI RADICAL SLAVE;So;0;ON;<compat> 96B6;;;;N;;;;;
+2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON;<compat> 96B9;;;;N;;;;;
+2FAC;KANGXI RADICAL RAIN;So;0;ON;<compat> 96E8;;;;N;;;;;
+2FAD;KANGXI RADICAL BLUE;So;0;ON;<compat> 9751;;;;N;;;;;
+2FAE;KANGXI RADICAL WRONG;So;0;ON;<compat> 975E;;;;N;;;;;
+2FAF;KANGXI RADICAL FACE;So;0;ON;<compat> 9762;;;;N;;;;;
+2FB0;KANGXI RADICAL LEATHER;So;0;ON;<compat> 9769;;;;N;;;;;
+2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON;<compat> 97CB;;;;N;;;;;
+2FB2;KANGXI RADICAL LEEK;So;0;ON;<compat> 97ED;;;;N;;;;;
+2FB3;KANGXI RADICAL SOUND;So;0;ON;<compat> 97F3;;;;N;;;;;
+2FB4;KANGXI RADICAL LEAF;So;0;ON;<compat> 9801;;;;N;;;;;
+2FB5;KANGXI RADICAL WIND;So;0;ON;<compat> 98A8;;;;N;;;;;
+2FB6;KANGXI RADICAL FLY;So;0;ON;<compat> 98DB;;;;N;;;;;
+2FB7;KANGXI RADICAL EAT;So;0;ON;<compat> 98DF;;;;N;;;;;
+2FB8;KANGXI RADICAL HEAD;So;0;ON;<compat> 9996;;;;N;;;;;
+2FB9;KANGXI RADICAL FRAGRANT;So;0;ON;<compat> 9999;;;;N;;;;;
+2FBA;KANGXI RADICAL HORSE;So;0;ON;<compat> 99AC;;;;N;;;;;
+2FBB;KANGXI RADICAL BONE;So;0;ON;<compat> 9AA8;;;;N;;;;;
+2FBC;KANGXI RADICAL TALL;So;0;ON;<compat> 9AD8;;;;N;;;;;
+2FBD;KANGXI RADICAL HAIR;So;0;ON;<compat> 9ADF;;;;N;;;;;
+2FBE;KANGXI RADICAL FIGHT;So;0;ON;<compat> 9B25;;;;N;;;;;
+2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON;<compat> 9B2F;;;;N;;;;;
+2FC0;KANGXI RADICAL CAULDRON;So;0;ON;<compat> 9B32;;;;N;;;;;
+2FC1;KANGXI RADICAL GHOST;So;0;ON;<compat> 9B3C;;;;N;;;;;
+2FC2;KANGXI RADICAL FISH;So;0;ON;<compat> 9B5A;;;;N;;;;;
+2FC3;KANGXI RADICAL BIRD;So;0;ON;<compat> 9CE5;;;;N;;;;;
+2FC4;KANGXI RADICAL SALT;So;0;ON;<compat> 9E75;;;;N;;;;;
+2FC5;KANGXI RADICAL DEER;So;0;ON;<compat> 9E7F;;;;N;;;;;
+2FC6;KANGXI RADICAL WHEAT;So;0;ON;<compat> 9EA5;;;;N;;;;;
+2FC7;KANGXI RADICAL HEMP;So;0;ON;<compat> 9EBB;;;;N;;;;;
+2FC8;KANGXI RADICAL YELLOW;So;0;ON;<compat> 9EC3;;;;N;;;;;
+2FC9;KANGXI RADICAL MILLET;So;0;ON;<compat> 9ECD;;;;N;;;;;
+2FCA;KANGXI RADICAL BLACK;So;0;ON;<compat> 9ED1;;;;N;;;;;
+2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON;<compat> 9EF9;;;;N;;;;;
+2FCC;KANGXI RADICAL FROG;So;0;ON;<compat> 9EFD;;;;N;;;;;
+2FCD;KANGXI RADICAL TRIPOD;So;0;ON;<compat> 9F0E;;;;N;;;;;
+2FCE;KANGXI RADICAL DRUM;So;0;ON;<compat> 9F13;;;;N;;;;;
+2FCF;KANGXI RADICAL RAT;So;0;ON;<compat> 9F20;;;;N;;;;;
+2FD0;KANGXI RADICAL NOSE;So;0;ON;<compat> 9F3B;;;;N;;;;;
+2FD1;KANGXI RADICAL EVEN;So;0;ON;<compat> 9F4A;;;;N;;;;;
+2FD2;KANGXI RADICAL TOOTH;So;0;ON;<compat> 9F52;;;;N;;;;;
+2FD3;KANGXI RADICAL DRAGON;So;0;ON;<compat> 9F8D;;;;N;;;;;
+2FD4;KANGXI RADICAL TURTLE;So;0;ON;<compat> 9F9C;;;;N;;;;;
+2FD5;KANGXI RADICAL FLUTE;So;0;ON;<compat> 9FA0;;;;N;;;;;
+2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;;
+2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;;
+2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;;
+2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;;
+2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;;
+2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;;
+2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;;
+2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;;
+2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;;
+2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;;
+2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;;
+2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;;
+3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
+3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;;
+3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;;
+3003;DITTO MARK;Po;0;ON;;;;;N;;;;;
+3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;;
+3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
+3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;;
+3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;;
+3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;;
+3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;;
+300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;;
+300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;;
+300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;;
+300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;;
+300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;;
+300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;;
+3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;;
+3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;;
+3012;POSTAL MARK;So;0;ON;;;;;N;;;;;
+3013;GETA MARK;So;0;ON;;;;;N;;;;;
+3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;;
+3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;;
+3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;;
+3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;;
+3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;;
+3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;;
+301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;;
+301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;;
+301C;WAVE DASH;Pd;0;ON;;;;;N;;;;;
+301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
+301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;;
+3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;;
+3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;;
+3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;
+3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;;
+3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;;
+3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;;
+3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;;
+3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;;
+3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;;
+302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;;
+302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;
+302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;
+302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;
+302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
+302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
+3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;
+3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;
+3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;
+3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;;
+3036;CIRCLED POSTAL MARK;So;0;ON;<compat> 3012;;;;N;;;;;
+3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;;
+3038;HANGZHOU NUMERAL TEN;Nl;0;L;<compat> 5341;;;10;N;;;;;
+3039;HANGZHOU NUMERAL TWENTY;Nl;0;L;<compat> 5344;;;20;N;;;;;
+303A;HANGZHOU NUMERAL THIRTY;Nl;0;L;<compat> 5345;;;30;N;;;;;
+303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;;
+303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;;
+3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;;
+3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;;
+3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;;
+3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;;
+3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;;
+304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;;
+304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;;
+304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;;
+304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;;
+304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;;
+3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;;
+3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;;
+3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;;
+3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;;
+3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;;
+3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;;
+3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;;
+3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;;
+3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;;
+3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;;
+305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;;
+305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;;
+305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;;
+305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;;
+305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;;
+305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;;
+3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;;
+3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;;
+3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;;
+3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;;
+3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;;
+3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;;
+3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;;
+3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;;
+3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;;
+306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;;
+306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;;
+306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;;
+306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;;
+306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;;
+306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;;
+3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;;
+3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;;
+3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;;
+3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;;
+3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;;
+3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;;
+3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;;
+3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;;
+3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;;
+3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;;
+307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;;
+307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;;
+307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;;
+307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;;
+307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;;
+307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;;
+3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;;
+3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;;
+3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;;
+3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;;
+3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;;
+3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;;
+3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;;
+308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;;
+308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;;
+308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;;
+308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;;
+308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;;
+3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;;
+3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;;
+3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;;
+3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;;
+3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;;
+3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;;
+309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;;
+309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;
+309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;
+309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;;
+30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;;
+30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;;
+30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;;
+30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;;
+30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;;
+30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;;
+30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;;
+30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;;
+30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;;
+30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;;
+30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;;
+30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;;
+30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;;
+30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;;
+30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;;
+30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;;
+30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;;
+30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;;
+30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;;
+30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;;
+30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;;
+30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;;
+30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;;
+30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;;
+30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;;
+30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;;
+30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;;
+30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;;
+30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;;
+30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;;
+30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;;
+30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;;
+30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;;
+30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
+30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
+30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;;
+30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;;
+30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;;
+30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;;
+30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;;
+30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;;
+30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;;
+30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;;
+30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;;
+30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;;
+30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;;
+30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;;
+30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;;
+30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;;
+30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;;
+30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;;
+30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;;
+30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;;
+30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;;
+30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;;
+30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;;
+30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;;
+30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;;
+30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;;
+30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;;
+30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;;
+30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;;
+30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;;
+30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;;
+30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;;
+30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;;
+30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;;
+30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;;
+30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;;
+30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;;
+30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;;
+30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;;
+30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;;
+30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;;
+30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
+30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
+30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;;
+30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;;
+30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;;
+30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;;
+30FB;KATAKANA MIDDLE DOT;Pc;0;ON;;;;;N;;;;;
+30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;;
+30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;;
+3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;;
+3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;;
+3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;;
+3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;;
+3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;;
+310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;;
+310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;;
+310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;;
+310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;;
+310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;;
+310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;;
+3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;;
+3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;;
+3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;;
+3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;;
+3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;;
+3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;;
+3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;;
+3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;;
+3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;;
+3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;;
+311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;;
+311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;;
+311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;;
+311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;;
+311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;;
+311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;;
+3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;;
+3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;;
+3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;;
+3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;;
+3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;;
+3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;;
+3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;;
+3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;;
+3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;;
+3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;;
+312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;;
+312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
+312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
+3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
+3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;
+3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
+3134;HANGUL LETTER NIEUN;Lo;0;L;<compat> 1102;;;;N;;;;;
+3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<compat> 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;;
+3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<compat> 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;;
+3137;HANGUL LETTER TIKEUT;Lo;0;L;<compat> 1103;;;;N;HANGUL LETTER DIGEUD;;;;
+3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L;<compat> 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;;
+3139;HANGUL LETTER RIEUL;Lo;0;L;<compat> 1105;;;;N;HANGUL LETTER LIEUL;;;;
+313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<compat> 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;;
+313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<compat> 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;;
+313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<compat> 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;;
+313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L;<compat> 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;;
+313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<compat> 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;;
+313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<compat> 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;;
+3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<compat> 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;;
+3141;HANGUL LETTER MIEUM;Lo;0;L;<compat> 1106;;;;N;;;;;
+3142;HANGUL LETTER PIEUP;Lo;0;L;<compat> 1107;;;;N;HANGUL LETTER BIEUB;;;;
+3143;HANGUL LETTER SSANGPIEUP;Lo;0;L;<compat> 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;;
+3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L;<compat> 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;;
+3145;HANGUL LETTER SIOS;Lo;0;L;<compat> 1109;;;;N;;;;;
+3146;HANGUL LETTER SSANGSIOS;Lo;0;L;<compat> 110A;;;;N;HANGUL LETTER SSANG SIOS;;;;
+3147;HANGUL LETTER IEUNG;Lo;0;L;<compat> 110B;;;;N;;;;;
+3148;HANGUL LETTER CIEUC;Lo;0;L;<compat> 110C;;;;N;HANGUL LETTER JIEUJ;;;;
+3149;HANGUL LETTER SSANGCIEUC;Lo;0;L;<compat> 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;;
+314A;HANGUL LETTER CHIEUCH;Lo;0;L;<compat> 110E;;;;N;HANGUL LETTER CIEUC;;;;
+314B;HANGUL LETTER KHIEUKH;Lo;0;L;<compat> 110F;;;;N;HANGUL LETTER KIYEOK;;;;
+314C;HANGUL LETTER THIEUTH;Lo;0;L;<compat> 1110;;;;N;HANGUL LETTER TIEUT;;;;
+314D;HANGUL LETTER PHIEUPH;Lo;0;L;<compat> 1111;;;;N;HANGUL LETTER PIEUP;;;;
+314E;HANGUL LETTER HIEUH;Lo;0;L;<compat> 1112;;;;N;;;;;
+314F;HANGUL LETTER A;Lo;0;L;<compat> 1161;;;;N;;;;;
+3150;HANGUL LETTER AE;Lo;0;L;<compat> 1162;;;;N;;;;;
+3151;HANGUL LETTER YA;Lo;0;L;<compat> 1163;;;;N;;;;;
+3152;HANGUL LETTER YAE;Lo;0;L;<compat> 1164;;;;N;;;;;
+3153;HANGUL LETTER EO;Lo;0;L;<compat> 1165;;;;N;;;;;
+3154;HANGUL LETTER E;Lo;0;L;<compat> 1166;;;;N;;;;;
+3155;HANGUL LETTER YEO;Lo;0;L;<compat> 1167;;;;N;;;;;
+3156;HANGUL LETTER YE;Lo;0;L;<compat> 1168;;;;N;;;;;
+3157;HANGUL LETTER O;Lo;0;L;<compat> 1169;;;;N;;;;;
+3158;HANGUL LETTER WA;Lo;0;L;<compat> 116A;;;;N;;;;;
+3159;HANGUL LETTER WAE;Lo;0;L;<compat> 116B;;;;N;;;;;
+315A;HANGUL LETTER OE;Lo;0;L;<compat> 116C;;;;N;;;;;
+315B;HANGUL LETTER YO;Lo;0;L;<compat> 116D;;;;N;;;;;
+315C;HANGUL LETTER U;Lo;0;L;<compat> 116E;;;;N;;;;;
+315D;HANGUL LETTER WEO;Lo;0;L;<compat> 116F;;;;N;;;;;
+315E;HANGUL LETTER WE;Lo;0;L;<compat> 1170;;;;N;;;;;
+315F;HANGUL LETTER WI;Lo;0;L;<compat> 1171;;;;N;;;;;
+3160;HANGUL LETTER YU;Lo;0;L;<compat> 1172;;;;N;;;;;
+3161;HANGUL LETTER EU;Lo;0;L;<compat> 1173;;;;N;;;;;
+3162;HANGUL LETTER YI;Lo;0;L;<compat> 1174;;;;N;;;;;
+3163;HANGUL LETTER I;Lo;0;L;<compat> 1175;;;;N;;;;;
+3164;HANGUL FILLER;Lo;0;L;<compat> 1160;;;;N;HANGUL CAE OM;;;;
+3165;HANGUL LETTER SSANGNIEUN;Lo;0;L;<compat> 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;;
+3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L;<compat> 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;;
+3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L;<compat> 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;;
+3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L;<compat> 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;;
+3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L;<compat> 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;;
+316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L;<compat> 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;;
+316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L;<compat> 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;;
+316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L;<compat> 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;;
+316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L;<compat> 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;;
+316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L;<compat> 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;;
+316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L;<compat> 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;;
+3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L;<compat> 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;;
+3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L;<compat> 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;;
+3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L;<compat> 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;;
+3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L;<compat> 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;;
+3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L;<compat> 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;;
+3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L;<compat> 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;;
+3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L;<compat> 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;;
+3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L;<compat> 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;;
+3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L;<compat> 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;;
+3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L;<compat> 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;;
+317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L;<compat> 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;;
+317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L;<compat> 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;;
+317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L;<compat> 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;;
+317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L;<compat> 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;;
+317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L;<compat> 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;;
+317F;HANGUL LETTER PANSIOS;Lo;0;L;<compat> 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;;
+3180;HANGUL LETTER SSANGIEUNG;Lo;0;L;<compat> 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;;
+3181;HANGUL LETTER YESIEUNG;Lo;0;L;<compat> 114C;;;;N;HANGUL LETTER NGIEUNG;;;;
+3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L;<compat> 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;;
+3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L;<compat> 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;;
+3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L;<compat> 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;;
+3185;HANGUL LETTER SSANGHIEUH;Lo;0;L;<compat> 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;;
+3186;HANGUL LETTER YEORINHIEUH;Lo;0;L;<compat> 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;;
+3187;HANGUL LETTER YO-YA;Lo;0;L;<compat> 1184;;;;N;HANGUL LETTER YOYA;;;;
+3188;HANGUL LETTER YO-YAE;Lo;0;L;<compat> 1185;;;;N;HANGUL LETTER YOYAE;;;;
+3189;HANGUL LETTER YO-I;Lo;0;L;<compat> 1188;;;;N;HANGUL LETTER YOI;;;;
+318A;HANGUL LETTER YU-YEO;Lo;0;L;<compat> 1191;;;;N;HANGUL LETTER YUYEO;;;;
+318B;HANGUL LETTER YU-YE;Lo;0;L;<compat> 1192;;;;N;HANGUL LETTER YUYE;;;;
+318C;HANGUL LETTER YU-I;Lo;0;L;<compat> 1194;;;;N;HANGUL LETTER YUI;;;;
+318D;HANGUL LETTER ARAEA;Lo;0;L;<compat> 119E;;;;N;HANGUL LETTER ALAE A;;;;
+318E;HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;
+3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;;
+3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;;
+3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L;<super> 4E00;;;;N;KAERITEN ITI;Kaeriten;;;
+3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L;<super> 4E8C;;;;N;KAERITEN NI;Kaeriten;;;
+3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L;<super> 4E09;;;;N;KAERITEN SAN;Kaeriten;;;
+3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L;<super> 56DB;;;;N;KAERITEN SI;Kaeriten;;;
+3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L;<super> 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;;
+3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L;<super> 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;;
+3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L;<super> 4E0B;;;;N;KAERITEN GE;Kaeriten;;;
+3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L;<super> 7532;;;;N;KAERITEN KOU;Kaeriten;;;
+319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L;<super> 4E59;;;;N;KAERITEN OTU;Kaeriten;;;
+319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L;<super> 4E19;;;;N;KAERITEN HEI;Kaeriten;;;
+319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L;<super> 4E01;;;;N;KAERITEN TEI;Kaeriten;;;
+319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L;<super> 5929;;;;N;KAERITEN TEN;Kaeriten;;;
+319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L;<super> 5730;;;;N;KAERITEN TI;Kaeriten;;;
+319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L;<super> 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;;
+31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;;
+31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;;
+31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;;
+31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;;
+31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;;
+31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;;
+31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;;
+31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;;
+31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;;
+31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;;
+31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;;
+31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;;
+31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;;
+31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;;
+31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;;
+31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;;
+31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;;
+31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;;
+31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;;
+31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;;
+31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;;
+31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;
+31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;
+31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;
+3200;PARENTHESIZED HANGUL KIYEOK;So;0;L;<compat> 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;;
+3201;PARENTHESIZED HANGUL NIEUN;So;0;L;<compat> 0028 1102 0029;;;;N;;;;;
+3202;PARENTHESIZED HANGUL TIKEUT;So;0;L;<compat> 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;;
+3203;PARENTHESIZED HANGUL RIEUL;So;0;L;<compat> 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;;
+3204;PARENTHESIZED HANGUL MIEUM;So;0;L;<compat> 0028 1106 0029;;;;N;;;;;
+3205;PARENTHESIZED HANGUL PIEUP;So;0;L;<compat> 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;;
+3206;PARENTHESIZED HANGUL SIOS;So;0;L;<compat> 0028 1109 0029;;;;N;;;;;
+3207;PARENTHESIZED HANGUL IEUNG;So;0;L;<compat> 0028 110B 0029;;;;N;;;;;
+3208;PARENTHESIZED HANGUL CIEUC;So;0;L;<compat> 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;;
+3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L;<compat> 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;;
+320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L;<compat> 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;;
+320B;PARENTHESIZED HANGUL THIEUTH;So;0;L;<compat> 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;;
+320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L;<compat> 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;;
+320D;PARENTHESIZED HANGUL HIEUH;So;0;L;<compat> 0028 1112 0029;;;;N;;;;;
+320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L;<compat> 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;;
+320F;PARENTHESIZED HANGUL NIEUN A;So;0;L;<compat> 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;;
+3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L;<compat> 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;;
+3211;PARENTHESIZED HANGUL RIEUL A;So;0;L;<compat> 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;;
+3212;PARENTHESIZED HANGUL MIEUM A;So;0;L;<compat> 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;;
+3213;PARENTHESIZED HANGUL PIEUP A;So;0;L;<compat> 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;;
+3214;PARENTHESIZED HANGUL SIOS A;So;0;L;<compat> 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;;
+3215;PARENTHESIZED HANGUL IEUNG A;So;0;L;<compat> 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;;
+3216;PARENTHESIZED HANGUL CIEUC A;So;0;L;<compat> 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;;
+3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L;<compat> 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;;
+3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L;<compat> 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;;
+3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L;<compat> 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;;
+321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L;<compat> 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;;
+321B;PARENTHESIZED HANGUL HIEUH A;So;0;L;<compat> 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;;
+321C;PARENTHESIZED HANGUL CIEUC U;So;0;L;<compat> 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;;
+3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L;<compat> 0028 4E00 0029;;;;N;;;;;
+3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L;<compat> 0028 4E8C 0029;;;;N;;;;;
+3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L;<compat> 0028 4E09 0029;;;;N;;;;;
+3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L;<compat> 0028 56DB 0029;;;;N;;;;;
+3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L;<compat> 0028 4E94 0029;;;;N;;;;;
+3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L;<compat> 0028 516D 0029;;;;N;;;;;
+3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L;<compat> 0028 4E03 0029;;;;N;;;;;
+3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L;<compat> 0028 516B 0029;;;;N;;;;;
+3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L;<compat> 0028 4E5D 0029;;;;N;;;;;
+3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L;<compat> 0028 5341 0029;;;;N;;;;;
+322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L;<compat> 0028 6708 0029;;;;N;;;;;
+322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L;<compat> 0028 706B 0029;;;;N;;;;;
+322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L;<compat> 0028 6C34 0029;;;;N;;;;;
+322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L;<compat> 0028 6728 0029;;;;N;;;;;
+322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L;<compat> 0028 91D1 0029;;;;N;;;;;
+322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L;<compat> 0028 571F 0029;;;;N;;;;;
+3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L;<compat> 0028 65E5 0029;;;;N;;;;;
+3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L;<compat> 0028 682A 0029;;;;N;;;;;
+3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L;<compat> 0028 6709 0029;;;;N;;;;;
+3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L;<compat> 0028 793E 0029;;;;N;;;;;
+3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L;<compat> 0028 540D 0029;;;;N;;;;;
+3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L;<compat> 0028 7279 0029;;;;N;;;;;
+3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L;<compat> 0028 8CA1 0029;;;;N;;;;;
+3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L;<compat> 0028 795D 0029;;;;N;;;;;
+3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L;<compat> 0028 52B4 0029;;;;N;;;;;
+3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L;<compat> 0028 4EE3 0029;;;;N;;;;;
+323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L;<compat> 0028 547C 0029;;;;N;;;;;
+323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L;<compat> 0028 5B66 0029;;;;N;;;;;
+323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L;<compat> 0028 76E3 0029;;;;N;;;;;
+323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L;<compat> 0028 4F01 0029;;;;N;;;;;
+323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L;<compat> 0028 8CC7 0029;;;;N;;;;;
+323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L;<compat> 0028 5354 0029;;;;N;;;;;
+3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L;<compat> 0028 796D 0029;;;;N;;;;;
+3241;PARENTHESIZED IDEOGRAPH REST;So;0;L;<compat> 0028 4F11 0029;;;;N;;;;;
+3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L;<compat> 0028 81EA 0029;;;;N;;;;;
+3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L;<compat> 0028 81F3 0029;;;;N;;;;;
+3260;CIRCLED HANGUL KIYEOK;So;0;L;<circle> 1100;;;;N;CIRCLED HANGUL GIYEOG;;;;
+3261;CIRCLED HANGUL NIEUN;So;0;L;<circle> 1102;;;;N;;;;;
+3262;CIRCLED HANGUL TIKEUT;So;0;L;<circle> 1103;;;;N;CIRCLED HANGUL DIGEUD;;;;
+3263;CIRCLED HANGUL RIEUL;So;0;L;<circle> 1105;;;;N;CIRCLED HANGUL LIEUL;;;;
+3264;CIRCLED HANGUL MIEUM;So;0;L;<circle> 1106;;;;N;;;;;
+3265;CIRCLED HANGUL PIEUP;So;0;L;<circle> 1107;;;;N;CIRCLED HANGUL BIEUB;;;;
+3266;CIRCLED HANGUL SIOS;So;0;L;<circle> 1109;;;;N;;;;;
+3267;CIRCLED HANGUL IEUNG;So;0;L;<circle> 110B;;;;N;;;;;
+3268;CIRCLED HANGUL CIEUC;So;0;L;<circle> 110C;;;;N;CIRCLED HANGUL JIEUJ;;;;
+3269;CIRCLED HANGUL CHIEUCH;So;0;L;<circle> 110E;;;;N;CIRCLED HANGUL CIEUC;;;;
+326A;CIRCLED HANGUL KHIEUKH;So;0;L;<circle> 110F;;;;N;CIRCLED HANGUL KIYEOK;;;;
+326B;CIRCLED HANGUL THIEUTH;So;0;L;<circle> 1110;;;;N;CIRCLED HANGUL TIEUT;;;;
+326C;CIRCLED HANGUL PHIEUPH;So;0;L;<circle> 1111;;;;N;CIRCLED HANGUL PIEUP;;;;
+326D;CIRCLED HANGUL HIEUH;So;0;L;<circle> 1112;;;;N;;;;;
+326E;CIRCLED HANGUL KIYEOK A;So;0;L;<circle> 1100 1161;;;;N;CIRCLED HANGUL GA;;;;
+326F;CIRCLED HANGUL NIEUN A;So;0;L;<circle> 1102 1161;;;;N;CIRCLED HANGUL NA;;;;
+3270;CIRCLED HANGUL TIKEUT A;So;0;L;<circle> 1103 1161;;;;N;CIRCLED HANGUL DA;;;;
+3271;CIRCLED HANGUL RIEUL A;So;0;L;<circle> 1105 1161;;;;N;CIRCLED HANGUL LA;;;;
+3272;CIRCLED HANGUL MIEUM A;So;0;L;<circle> 1106 1161;;;;N;CIRCLED HANGUL MA;;;;
+3273;CIRCLED HANGUL PIEUP A;So;0;L;<circle> 1107 1161;;;;N;CIRCLED HANGUL BA;;;;
+3274;CIRCLED HANGUL SIOS A;So;0;L;<circle> 1109 1161;;;;N;CIRCLED HANGUL SA;;;;
+3275;CIRCLED HANGUL IEUNG A;So;0;L;<circle> 110B 1161;;;;N;CIRCLED HANGUL A;;;;
+3276;CIRCLED HANGUL CIEUC A;So;0;L;<circle> 110C 1161;;;;N;CIRCLED HANGUL JA;;;;
+3277;CIRCLED HANGUL CHIEUCH A;So;0;L;<circle> 110E 1161;;;;N;CIRCLED HANGUL CA;;;;
+3278;CIRCLED HANGUL KHIEUKH A;So;0;L;<circle> 110F 1161;;;;N;CIRCLED HANGUL KA;;;;
+3279;CIRCLED HANGUL THIEUTH A;So;0;L;<circle> 1110 1161;;;;N;CIRCLED HANGUL TA;;;;
+327A;CIRCLED HANGUL PHIEUPH A;So;0;L;<circle> 1111 1161;;;;N;CIRCLED HANGUL PA;;;;
+327B;CIRCLED HANGUL HIEUH A;So;0;L;<circle> 1112 1161;;;;N;CIRCLED HANGUL HA;;;;
+327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;;
+3280;CIRCLED IDEOGRAPH ONE;No;0;L;<circle> 4E00;;;1;N;;;;;
+3281;CIRCLED IDEOGRAPH TWO;No;0;L;<circle> 4E8C;;;2;N;;;;;
+3282;CIRCLED IDEOGRAPH THREE;No;0;L;<circle> 4E09;;;3;N;;;;;
+3283;CIRCLED IDEOGRAPH FOUR;No;0;L;<circle> 56DB;;;4;N;;;;;
+3284;CIRCLED IDEOGRAPH FIVE;No;0;L;<circle> 4E94;;;5;N;;;;;
+3285;CIRCLED IDEOGRAPH SIX;No;0;L;<circle> 516D;;;6;N;;;;;
+3286;CIRCLED IDEOGRAPH SEVEN;No;0;L;<circle> 4E03;;;7;N;;;;;
+3287;CIRCLED IDEOGRAPH EIGHT;No;0;L;<circle> 516B;;;8;N;;;;;
+3288;CIRCLED IDEOGRAPH NINE;No;0;L;<circle> 4E5D;;;9;N;;;;;
+3289;CIRCLED IDEOGRAPH TEN;No;0;L;<circle> 5341;;;10;N;;;;;
+328A;CIRCLED IDEOGRAPH MOON;So;0;L;<circle> 6708;;;;N;;;;;
+328B;CIRCLED IDEOGRAPH FIRE;So;0;L;<circle> 706B;;;;N;;;;;
+328C;CIRCLED IDEOGRAPH WATER;So;0;L;<circle> 6C34;;;;N;;;;;
+328D;CIRCLED IDEOGRAPH WOOD;So;0;L;<circle> 6728;;;;N;;;;;
+328E;CIRCLED IDEOGRAPH METAL;So;0;L;<circle> 91D1;;;;N;;;;;
+328F;CIRCLED IDEOGRAPH EARTH;So;0;L;<circle> 571F;;;;N;;;;;
+3290;CIRCLED IDEOGRAPH SUN;So;0;L;<circle> 65E5;;;;N;;;;;
+3291;CIRCLED IDEOGRAPH STOCK;So;0;L;<circle> 682A;;;;N;;;;;
+3292;CIRCLED IDEOGRAPH HAVE;So;0;L;<circle> 6709;;;;N;;;;;
+3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L;<circle> 793E;;;;N;;;;;
+3294;CIRCLED IDEOGRAPH NAME;So;0;L;<circle> 540D;;;;N;;;;;
+3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L;<circle> 7279;;;;N;;;;;
+3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L;<circle> 8CA1;;;;N;;;;;
+3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L;<circle> 795D;;;;N;;;;;
+3298;CIRCLED IDEOGRAPH LABOR;So;0;L;<circle> 52B4;;;;N;;;;;
+3299;CIRCLED IDEOGRAPH SECRET;So;0;L;<circle> 79D8;;;;N;;;;;
+329A;CIRCLED IDEOGRAPH MALE;So;0;L;<circle> 7537;;;;N;;;;;
+329B;CIRCLED IDEOGRAPH FEMALE;So;0;L;<circle> 5973;;;;N;;;;;
+329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L;<circle> 9069;;;;N;;;;;
+329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L;<circle> 512A;;;;N;;;;;
+329E;CIRCLED IDEOGRAPH PRINT;So;0;L;<circle> 5370;;;;N;;;;;
+329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L;<circle> 6CE8;;;;N;;;;;
+32A0;CIRCLED IDEOGRAPH ITEM;So;0;L;<circle> 9805;;;;N;;;;;
+32A1;CIRCLED IDEOGRAPH REST;So;0;L;<circle> 4F11;;;;N;;;;;
+32A2;CIRCLED IDEOGRAPH COPY;So;0;L;<circle> 5199;;;;N;;;;;
+32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L;<circle> 6B63;;;;N;;;;;
+32A4;CIRCLED IDEOGRAPH HIGH;So;0;L;<circle> 4E0A;;;;N;;;;;
+32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L;<circle> 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;;
+32A6;CIRCLED IDEOGRAPH LOW;So;0;L;<circle> 4E0B;;;;N;;;;;
+32A7;CIRCLED IDEOGRAPH LEFT;So;0;L;<circle> 5DE6;;;;N;;;;;
+32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L;<circle> 53F3;;;;N;;;;;
+32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L;<circle> 533B;;;;N;;;;;
+32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L;<circle> 5B97;;;;N;;;;;
+32AB;CIRCLED IDEOGRAPH STUDY;So;0;L;<circle> 5B66;;;;N;;;;;
+32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L;<circle> 76E3;;;;N;;;;;
+32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L;<circle> 4F01;;;;N;;;;;
+32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L;<circle> 8CC7;;;;N;;;;;
+32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L;<circle> 5354;;;;N;;;;;
+32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L;<circle> 591C;;;;N;;;;;
+32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L;<compat> 0031 6708;;;;N;;;;;
+32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L;<compat> 0032 6708;;;;N;;;;;
+32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L;<compat> 0033 6708;;;;N;;;;;
+32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L;<compat> 0034 6708;;;;N;;;;;
+32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L;<compat> 0035 6708;;;;N;;;;;
+32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L;<compat> 0036 6708;;;;N;;;;;
+32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L;<compat> 0037 6708;;;;N;;;;;
+32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L;<compat> 0038 6708;;;;N;;;;;
+32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L;<compat> 0039 6708;;;;N;;;;;
+32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L;<compat> 0031 0030 6708;;;;N;;;;;
+32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L;<compat> 0031 0031 6708;;;;N;;;;;
+32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L;<compat> 0031 0032 6708;;;;N;;;;;
+32D0;CIRCLED KATAKANA A;So;0;L;<circle> 30A2;;;;N;;;;;
+32D1;CIRCLED KATAKANA I;So;0;L;<circle> 30A4;;;;N;;;;;
+32D2;CIRCLED KATAKANA U;So;0;L;<circle> 30A6;;;;N;;;;;
+32D3;CIRCLED KATAKANA E;So;0;L;<circle> 30A8;;;;N;;;;;
+32D4;CIRCLED KATAKANA O;So;0;L;<circle> 30AA;;;;N;;;;;
+32D5;CIRCLED KATAKANA KA;So;0;L;<circle> 30AB;;;;N;;;;;
+32D6;CIRCLED KATAKANA KI;So;0;L;<circle> 30AD;;;;N;;;;;
+32D7;CIRCLED KATAKANA KU;So;0;L;<circle> 30AF;;;;N;;;;;
+32D8;CIRCLED KATAKANA KE;So;0;L;<circle> 30B1;;;;N;;;;;
+32D9;CIRCLED KATAKANA KO;So;0;L;<circle> 30B3;;;;N;;;;;
+32DA;CIRCLED KATAKANA SA;So;0;L;<circle> 30B5;;;;N;;;;;
+32DB;CIRCLED KATAKANA SI;So;0;L;<circle> 30B7;;;;N;;;;;
+32DC;CIRCLED KATAKANA SU;So;0;L;<circle> 30B9;;;;N;;;;;
+32DD;CIRCLED KATAKANA SE;So;0;L;<circle> 30BB;;;;N;;;;;
+32DE;CIRCLED KATAKANA SO;So;0;L;<circle> 30BD;;;;N;;;;;
+32DF;CIRCLED KATAKANA TA;So;0;L;<circle> 30BF;;;;N;;;;;
+32E0;CIRCLED KATAKANA TI;So;0;L;<circle> 30C1;;;;N;;;;;
+32E1;CIRCLED KATAKANA TU;So;0;L;<circle> 30C4;;;;N;;;;;
+32E2;CIRCLED KATAKANA TE;So;0;L;<circle> 30C6;;;;N;;;;;
+32E3;CIRCLED KATAKANA TO;So;0;L;<circle> 30C8;;;;N;;;;;
+32E4;CIRCLED KATAKANA NA;So;0;L;<circle> 30CA;;;;N;;;;;
+32E5;CIRCLED KATAKANA NI;So;0;L;<circle> 30CB;;;;N;;;;;
+32E6;CIRCLED KATAKANA NU;So;0;L;<circle> 30CC;;;;N;;;;;
+32E7;CIRCLED KATAKANA NE;So;0;L;<circle> 30CD;;;;N;;;;;
+32E8;CIRCLED KATAKANA NO;So;0;L;<circle> 30CE;;;;N;;;;;
+32E9;CIRCLED KATAKANA HA;So;0;L;<circle> 30CF;;;;N;;;;;
+32EA;CIRCLED KATAKANA HI;So;0;L;<circle> 30D2;;;;N;;;;;
+32EB;CIRCLED KATAKANA HU;So;0;L;<circle> 30D5;;;;N;;;;;
+32EC;CIRCLED KATAKANA HE;So;0;L;<circle> 30D8;;;;N;;;;;
+32ED;CIRCLED KATAKANA HO;So;0;L;<circle> 30DB;;;;N;;;;;
+32EE;CIRCLED KATAKANA MA;So;0;L;<circle> 30DE;;;;N;;;;;
+32EF;CIRCLED KATAKANA MI;So;0;L;<circle> 30DF;;;;N;;;;;
+32F0;CIRCLED KATAKANA MU;So;0;L;<circle> 30E0;;;;N;;;;;
+32F1;CIRCLED KATAKANA ME;So;0;L;<circle> 30E1;;;;N;;;;;
+32F2;CIRCLED KATAKANA MO;So;0;L;<circle> 30E2;;;;N;;;;;
+32F3;CIRCLED KATAKANA YA;So;0;L;<circle> 30E4;;;;N;;;;;
+32F4;CIRCLED KATAKANA YU;So;0;L;<circle> 30E6;;;;N;;;;;
+32F5;CIRCLED KATAKANA YO;So;0;L;<circle> 30E8;;;;N;;;;;
+32F6;CIRCLED KATAKANA RA;So;0;L;<circle> 30E9;;;;N;;;;;
+32F7;CIRCLED KATAKANA RI;So;0;L;<circle> 30EA;;;;N;;;;;
+32F8;CIRCLED KATAKANA RU;So;0;L;<circle> 30EB;;;;N;;;;;
+32F9;CIRCLED KATAKANA RE;So;0;L;<circle> 30EC;;;;N;;;;;
+32FA;CIRCLED KATAKANA RO;So;0;L;<circle> 30ED;;;;N;;;;;
+32FB;CIRCLED KATAKANA WA;So;0;L;<circle> 30EF;;;;N;;;;;
+32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;
+32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;
+32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;
+3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;
+3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;
+3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;
+3303;SQUARE AARU;So;0;L;<square> 30A2 30FC 30EB;;;;N;SQUARED AARU;;;;
+3304;SQUARE ININGU;So;0;L;<square> 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;;
+3305;SQUARE INTI;So;0;L;<square> 30A4 30F3 30C1;;;;N;SQUARED INTI;;;;
+3306;SQUARE UON;So;0;L;<square> 30A6 30A9 30F3;;;;N;SQUARED UON;;;;
+3307;SQUARE ESUKUUDO;So;0;L;<square> 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;;
+3308;SQUARE EEKAA;So;0;L;<square> 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;;
+3309;SQUARE ONSU;So;0;L;<square> 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;;
+330A;SQUARE OOMU;So;0;L;<square> 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;;
+330B;SQUARE KAIRI;So;0;L;<square> 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;;
+330C;SQUARE KARATTO;So;0;L;<square> 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;;
+330D;SQUARE KARORII;So;0;L;<square> 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;;
+330E;SQUARE GARON;So;0;L;<square> 30AC 30ED 30F3;;;;N;SQUARED GARON;;;;
+330F;SQUARE GANMA;So;0;L;<square> 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;;
+3310;SQUARE GIGA;So;0;L;<square> 30AE 30AC;;;;N;SQUARED GIGA;;;;
+3311;SQUARE GINII;So;0;L;<square> 30AE 30CB 30FC;;;;N;SQUARED GINII;;;;
+3312;SQUARE KYURII;So;0;L;<square> 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;;
+3313;SQUARE GIRUDAA;So;0;L;<square> 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;;
+3314;SQUARE KIRO;So;0;L;<square> 30AD 30ED;;;;N;SQUARED KIRO;;;;
+3315;SQUARE KIROGURAMU;So;0;L;<square> 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;;
+3316;SQUARE KIROMEETORU;So;0;L;<square> 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;;
+3317;SQUARE KIROWATTO;So;0;L;<square> 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;;
+3318;SQUARE GURAMU;So;0;L;<square> 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;;
+3319;SQUARE GURAMUTON;So;0;L;<square> 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;;
+331A;SQUARE KURUZEIRO;So;0;L;<square> 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;;
+331B;SQUARE KUROONE;So;0;L;<square> 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;;
+331C;SQUARE KEESU;So;0;L;<square> 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;;
+331D;SQUARE KORUNA;So;0;L;<square> 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;;
+331E;SQUARE KOOPO;So;0;L;<square> 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;;
+331F;SQUARE SAIKURU;So;0;L;<square> 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;;
+3320;SQUARE SANTIIMU;So;0;L;<square> 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;;
+3321;SQUARE SIRINGU;So;0;L;<square> 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;;
+3322;SQUARE SENTI;So;0;L;<square> 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;;
+3323;SQUARE SENTO;So;0;L;<square> 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;;
+3324;SQUARE DAASU;So;0;L;<square> 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;;
+3325;SQUARE DESI;So;0;L;<square> 30C7 30B7;;;;N;SQUARED DESI;;;;
+3326;SQUARE DORU;So;0;L;<square> 30C9 30EB;;;;N;SQUARED DORU;;;;
+3327;SQUARE TON;So;0;L;<square> 30C8 30F3;;;;N;SQUARED TON;;;;
+3328;SQUARE NANO;So;0;L;<square> 30CA 30CE;;;;N;SQUARED NANO;;;;
+3329;SQUARE NOTTO;So;0;L;<square> 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;;
+332A;SQUARE HAITU;So;0;L;<square> 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;;
+332B;SQUARE PAASENTO;So;0;L;<square> 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;;
+332C;SQUARE PAATU;So;0;L;<square> 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;;
+332D;SQUARE BAARERU;So;0;L;<square> 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;;
+332E;SQUARE PIASUTORU;So;0;L;<square> 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;;
+332F;SQUARE PIKURU;So;0;L;<square> 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;;
+3330;SQUARE PIKO;So;0;L;<square> 30D4 30B3;;;;N;SQUARED PIKO;;;;
+3331;SQUARE BIRU;So;0;L;<square> 30D3 30EB;;;;N;SQUARED BIRU;;;;
+3332;SQUARE HUARADDO;So;0;L;<square> 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;;
+3333;SQUARE HUIITO;So;0;L;<square> 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;;
+3334;SQUARE BUSSYERU;So;0;L;<square> 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;;
+3335;SQUARE HURAN;So;0;L;<square> 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;;
+3336;SQUARE HEKUTAARU;So;0;L;<square> 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;;
+3337;SQUARE PESO;So;0;L;<square> 30DA 30BD;;;;N;SQUARED PESO;;;;
+3338;SQUARE PENIHI;So;0;L;<square> 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;;
+3339;SQUARE HERUTU;So;0;L;<square> 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;;
+333A;SQUARE PENSU;So;0;L;<square> 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;;
+333B;SQUARE PEEZI;So;0;L;<square> 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;;
+333C;SQUARE BEETA;So;0;L;<square> 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;;
+333D;SQUARE POINTO;So;0;L;<square> 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;;
+333E;SQUARE BORUTO;So;0;L;<square> 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;;
+333F;SQUARE HON;So;0;L;<square> 30DB 30F3;;;;N;SQUARED HON;;;;
+3340;SQUARE PONDO;So;0;L;<square> 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;;
+3341;SQUARE HOORU;So;0;L;<square> 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;;
+3342;SQUARE HOON;So;0;L;<square> 30DB 30FC 30F3;;;;N;SQUARED HOON;;;;
+3343;SQUARE MAIKURO;So;0;L;<square> 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;;
+3344;SQUARE MAIRU;So;0;L;<square> 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;;
+3345;SQUARE MAHHA;So;0;L;<square> 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;;
+3346;SQUARE MARUKU;So;0;L;<square> 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;;
+3347;SQUARE MANSYON;So;0;L;<square> 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;;
+3348;SQUARE MIKURON;So;0;L;<square> 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;;
+3349;SQUARE MIRI;So;0;L;<square> 30DF 30EA;;;;N;SQUARED MIRI;;;;
+334A;SQUARE MIRIBAARU;So;0;L;<square> 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;;
+334B;SQUARE MEGA;So;0;L;<square> 30E1 30AC;;;;N;SQUARED MEGA;;;;
+334C;SQUARE MEGATON;So;0;L;<square> 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;;
+334D;SQUARE MEETORU;So;0;L;<square> 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;;
+334E;SQUARE YAADO;So;0;L;<square> 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;;
+334F;SQUARE YAARU;So;0;L;<square> 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;;
+3350;SQUARE YUAN;So;0;L;<square> 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;;
+3351;SQUARE RITTORU;So;0;L;<square> 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;;
+3352;SQUARE RIRA;So;0;L;<square> 30EA 30E9;;;;N;SQUARED RIRA;;;;
+3353;SQUARE RUPII;So;0;L;<square> 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;;
+3354;SQUARE RUUBURU;So;0;L;<square> 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;;
+3355;SQUARE REMU;So;0;L;<square> 30EC 30E0;;;;N;SQUARED REMU;;;;
+3356;SQUARE RENTOGEN;So;0;L;<square> 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;;
+3357;SQUARE WATTO;So;0;L;<square> 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;;
+3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L;<compat> 0030 70B9;;;;N;;;;;
+3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L;<compat> 0031 70B9;;;;N;;;;;
+335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L;<compat> 0032 70B9;;;;N;;;;;
+335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L;<compat> 0033 70B9;;;;N;;;;;
+335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L;<compat> 0034 70B9;;;;N;;;;;
+335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L;<compat> 0035 70B9;;;;N;;;;;
+335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L;<compat> 0036 70B9;;;;N;;;;;
+335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L;<compat> 0037 70B9;;;;N;;;;;
+3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L;<compat> 0038 70B9;;;;N;;;;;
+3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L;<compat> 0039 70B9;;;;N;;;;;
+3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L;<compat> 0031 0030 70B9;;;;N;;;;;
+3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L;<compat> 0031 0031 70B9;;;;N;;;;;
+3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L;<compat> 0031 0032 70B9;;;;N;;;;;
+3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L;<compat> 0031 0033 70B9;;;;N;;;;;
+3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L;<compat> 0031 0034 70B9;;;;N;;;;;
+3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L;<compat> 0031 0035 70B9;;;;N;;;;;
+3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L;<compat> 0031 0036 70B9;;;;N;;;;;
+3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L;<compat> 0031 0037 70B9;;;;N;;;;;
+336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L;<compat> 0031 0038 70B9;;;;N;;;;;
+336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L;<compat> 0031 0039 70B9;;;;N;;;;;
+336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L;<compat> 0032 0030 70B9;;;;N;;;;;
+336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L;<compat> 0032 0031 70B9;;;;N;;;;;
+336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L;<compat> 0032 0032 70B9;;;;N;;;;;
+336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L;<compat> 0032 0033 70B9;;;;N;;;;;
+3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L;<compat> 0032 0034 70B9;;;;N;;;;;
+3371;SQUARE HPA;So;0;L;<square> 0068 0050 0061;;;;N;;;;;
+3372;SQUARE DA;So;0;L;<square> 0064 0061;;;;N;;;;;
+3373;SQUARE AU;So;0;L;<square> 0041 0055;;;;N;;;;;
+3374;SQUARE BAR;So;0;L;<square> 0062 0061 0072;;;;N;;;;;
+3375;SQUARE OV;So;0;L;<square> 006F 0056;;;;N;;;;;
+3376;SQUARE PC;So;0;L;<square> 0070 0063;;;;N;;;;;
+337B;SQUARE ERA NAME HEISEI;So;0;L;<square> 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;;
+337C;SQUARE ERA NAME SYOUWA;So;0;L;<square> 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;;
+337D;SQUARE ERA NAME TAISYOU;So;0;L;<square> 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;;
+337E;SQUARE ERA NAME MEIZI;So;0;L;<square> 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;;
+337F;SQUARE CORPORATION;So;0;L;<square> 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;;
+3380;SQUARE PA AMPS;So;0;L;<square> 0070 0041;;;;N;SQUARED PA AMPS;;;;
+3381;SQUARE NA;So;0;L;<square> 006E 0041;;;;N;SQUARED NA;;;;
+3382;SQUARE MU A;So;0;L;<square> 03BC 0041;;;;N;SQUARED MU A;;;;
+3383;SQUARE MA;So;0;L;<square> 006D 0041;;;;N;SQUARED MA;;;;
+3384;SQUARE KA;So;0;L;<square> 006B 0041;;;;N;SQUARED KA;;;;
+3385;SQUARE KB;So;0;L;<square> 004B 0042;;;;N;SQUARED KB;;;;
+3386;SQUARE MB;So;0;L;<square> 004D 0042;;;;N;SQUARED MB;;;;
+3387;SQUARE GB;So;0;L;<square> 0047 0042;;;;N;SQUARED GB;;;;
+3388;SQUARE CAL;So;0;L;<square> 0063 0061 006C;;;;N;SQUARED CAL;;;;
+3389;SQUARE KCAL;So;0;L;<square> 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;;
+338A;SQUARE PF;So;0;L;<square> 0070 0046;;;;N;SQUARED PF;;;;
+338B;SQUARE NF;So;0;L;<square> 006E 0046;;;;N;SQUARED NF;;;;
+338C;SQUARE MU F;So;0;L;<square> 03BC 0046;;;;N;SQUARED MU F;;;;
+338D;SQUARE MU G;So;0;L;<square> 03BC 0067;;;;N;SQUARED MU G;;;;
+338E;SQUARE MG;So;0;L;<square> 006D 0067;;;;N;SQUARED MG;;;;
+338F;SQUARE KG;So;0;L;<square> 006B 0067;;;;N;SQUARED KG;;;;
+3390;SQUARE HZ;So;0;L;<square> 0048 007A;;;;N;SQUARED HZ;;;;
+3391;SQUARE KHZ;So;0;L;<square> 006B 0048 007A;;;;N;SQUARED KHZ;;;;
+3392;SQUARE MHZ;So;0;L;<square> 004D 0048 007A;;;;N;SQUARED MHZ;;;;
+3393;SQUARE GHZ;So;0;L;<square> 0047 0048 007A;;;;N;SQUARED GHZ;;;;
+3394;SQUARE THZ;So;0;L;<square> 0054 0048 007A;;;;N;SQUARED THZ;;;;
+3395;SQUARE MU L;So;0;L;<square> 03BC 2113;;;;N;SQUARED MU L;;;;
+3396;SQUARE ML;So;0;L;<square> 006D 2113;;;;N;SQUARED ML;;;;
+3397;SQUARE DL;So;0;L;<square> 0064 2113;;;;N;SQUARED DL;;;;
+3398;SQUARE KL;So;0;L;<square> 006B 2113;;;;N;SQUARED KL;;;;
+3399;SQUARE FM;So;0;L;<square> 0066 006D;;;;N;SQUARED FM;;;;
+339A;SQUARE NM;So;0;L;<square> 006E 006D;;;;N;SQUARED NM;;;;
+339B;SQUARE MU M;So;0;L;<square> 03BC 006D;;;;N;SQUARED MU M;;;;
+339C;SQUARE MM;So;0;L;<square> 006D 006D;;;;N;SQUARED MM;;;;
+339D;SQUARE CM;So;0;L;<square> 0063 006D;;;;N;SQUARED CM;;;;
+339E;SQUARE KM;So;0;L;<square> 006B 006D;;;;N;SQUARED KM;;;;
+339F;SQUARE MM SQUARED;So;0;L;<square> 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;;
+33A0;SQUARE CM SQUARED;So;0;L;<square> 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;;
+33A1;SQUARE M SQUARED;So;0;L;<square> 006D 00B2;;;;N;SQUARED M SQUARED;;;;
+33A2;SQUARE KM SQUARED;So;0;L;<square> 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;;
+33A3;SQUARE MM CUBED;So;0;L;<square> 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;;
+33A4;SQUARE CM CUBED;So;0;L;<square> 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;;
+33A5;SQUARE M CUBED;So;0;L;<square> 006D 00B3;;;;N;SQUARED M CUBED;;;;
+33A6;SQUARE KM CUBED;So;0;L;<square> 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;;
+33A7;SQUARE M OVER S;So;0;L;<square> 006D 2215 0073;;;;N;SQUARED M OVER S;;;;
+33A8;SQUARE M OVER S SQUARED;So;0;L;<square> 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;;
+33A9;SQUARE PA;So;0;L;<square> 0050 0061;;;;N;SQUARED PA;;;;
+33AA;SQUARE KPA;So;0;L;<square> 006B 0050 0061;;;;N;SQUARED KPA;;;;
+33AB;SQUARE MPA;So;0;L;<square> 004D 0050 0061;;;;N;SQUARED MPA;;;;
+33AC;SQUARE GPA;So;0;L;<square> 0047 0050 0061;;;;N;SQUARED GPA;;;;
+33AD;SQUARE RAD;So;0;L;<square> 0072 0061 0064;;;;N;SQUARED RAD;;;;
+33AE;SQUARE RAD OVER S;So;0;L;<square> 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;;
+33AF;SQUARE RAD OVER S SQUARED;So;0;L;<square> 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;;
+33B0;SQUARE PS;So;0;L;<square> 0070 0073;;;;N;SQUARED PS;;;;
+33B1;SQUARE NS;So;0;L;<square> 006E 0073;;;;N;SQUARED NS;;;;
+33B2;SQUARE MU S;So;0;L;<square> 03BC 0073;;;;N;SQUARED MU S;;;;
+33B3;SQUARE MS;So;0;L;<square> 006D 0073;;;;N;SQUARED MS;;;;
+33B4;SQUARE PV;So;0;L;<square> 0070 0056;;;;N;SQUARED PV;;;;
+33B5;SQUARE NV;So;0;L;<square> 006E 0056;;;;N;SQUARED NV;;;;
+33B6;SQUARE MU V;So;0;L;<square> 03BC 0056;;;;N;SQUARED MU V;;;;
+33B7;SQUARE MV;So;0;L;<square> 006D 0056;;;;N;SQUARED MV;;;;
+33B8;SQUARE KV;So;0;L;<square> 006B 0056;;;;N;SQUARED KV;;;;
+33B9;SQUARE MV MEGA;So;0;L;<square> 004D 0056;;;;N;SQUARED MV MEGA;;;;
+33BA;SQUARE PW;So;0;L;<square> 0070 0057;;;;N;SQUARED PW;;;;
+33BB;SQUARE NW;So;0;L;<square> 006E 0057;;;;N;SQUARED NW;;;;
+33BC;SQUARE MU W;So;0;L;<square> 03BC 0057;;;;N;SQUARED MU W;;;;
+33BD;SQUARE MW;So;0;L;<square> 006D 0057;;;;N;SQUARED MW;;;;
+33BE;SQUARE KW;So;0;L;<square> 006B 0057;;;;N;SQUARED KW;;;;
+33BF;SQUARE MW MEGA;So;0;L;<square> 004D 0057;;;;N;SQUARED MW MEGA;;;;
+33C0;SQUARE K OHM;So;0;L;<square> 006B 03A9;;;;N;SQUARED K OHM;;;;
+33C1;SQUARE M OHM;So;0;L;<square> 004D 03A9;;;;N;SQUARED M OHM;;;;
+33C2;SQUARE AM;So;0;L;<square> 0061 002E 006D 002E;;;;N;SQUARED AM;;;;
+33C3;SQUARE BQ;So;0;L;<square> 0042 0071;;;;N;SQUARED BQ;;;;
+33C4;SQUARE CC;So;0;L;<square> 0063 0063;;;;N;SQUARED CC;;;;
+33C5;SQUARE CD;So;0;L;<square> 0063 0064;;;;N;SQUARED CD;;;;
+33C6;SQUARE C OVER KG;So;0;L;<square> 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;;
+33C7;SQUARE CO;So;0;L;<square> 0043 006F 002E;;;;N;SQUARED CO;;;;
+33C8;SQUARE DB;So;0;L;<square> 0064 0042;;;;N;SQUARED DB;;;;
+33C9;SQUARE GY;So;0;L;<square> 0047 0079;;;;N;SQUARED GY;;;;
+33CA;SQUARE HA;So;0;L;<square> 0068 0061;;;;N;SQUARED HA;;;;
+33CB;SQUARE HP;So;0;L;<square> 0048 0050;;;;N;SQUARED HP;;;;
+33CC;SQUARE IN;So;0;L;<square> 0069 006E;;;;N;SQUARED IN;;;;
+33CD;SQUARE KK;So;0;L;<square> 004B 004B;;;;N;SQUARED KK;;;;
+33CE;SQUARE KM CAPITAL;So;0;L;<square> 004B 004D;;;;N;SQUARED KM CAPITAL;;;;
+33CF;SQUARE KT;So;0;L;<square> 006B 0074;;;;N;SQUARED KT;;;;
+33D0;SQUARE LM;So;0;L;<square> 006C 006D;;;;N;SQUARED LM;;;;
+33D1;SQUARE LN;So;0;L;<square> 006C 006E;;;;N;SQUARED LN;;;;
+33D2;SQUARE LOG;So;0;L;<square> 006C 006F 0067;;;;N;SQUARED LOG;;;;
+33D3;SQUARE LX;So;0;L;<square> 006C 0078;;;;N;SQUARED LX;;;;
+33D4;SQUARE MB SMALL;So;0;L;<square> 006D 0062;;;;N;SQUARED MB SMALL;;;;
+33D5;SQUARE MIL;So;0;L;<square> 006D 0069 006C;;;;N;SQUARED MIL;;;;
+33D6;SQUARE MOL;So;0;L;<square> 006D 006F 006C;;;;N;SQUARED MOL;;;;
+33D7;SQUARE PH;So;0;L;<square> 0050 0048;;;;N;SQUARED PH;;;;
+33D8;SQUARE PM;So;0;L;<square> 0070 002E 006D 002E;;;;N;SQUARED PM;;;;
+33D9;SQUARE PPM;So;0;L;<square> 0050 0050 004D;;;;N;SQUARED PPM;;;;
+33DA;SQUARE PR;So;0;L;<square> 0050 0052;;;;N;SQUARED PR;;;;
+33DB;SQUARE SR;So;0;L;<square> 0073 0072;;;;N;SQUARED SR;;;;
+33DC;SQUARE SV;So;0;L;<square> 0053 0076;;;;N;SQUARED SV;;;;
+33DD;SQUARE WB;So;0;L;<square> 0057 0062;;;;N;SQUARED WB;;;;
+33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L;<compat> 0031 65E5;;;;N;;;;;
+33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L;<compat> 0032 65E5;;;;N;;;;;
+33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L;<compat> 0033 65E5;;;;N;;;;;
+33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L;<compat> 0034 65E5;;;;N;;;;;
+33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L;<compat> 0035 65E5;;;;N;;;;;
+33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L;<compat> 0036 65E5;;;;N;;;;;
+33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L;<compat> 0037 65E5;;;;N;;;;;
+33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L;<compat> 0038 65E5;;;;N;;;;;
+33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L;<compat> 0039 65E5;;;;N;;;;;
+33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L;<compat> 0031 0030 65E5;;;;N;;;;;
+33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L;<compat> 0031 0031 65E5;;;;N;;;;;
+33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L;<compat> 0031 0032 65E5;;;;N;;;;;
+33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L;<compat> 0031 0033 65E5;;;;N;;;;;
+33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L;<compat> 0031 0034 65E5;;;;N;;;;;
+33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L;<compat> 0031 0035 65E5;;;;N;;;;;
+33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L;<compat> 0031 0036 65E5;;;;N;;;;;
+33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L;<compat> 0031 0037 65E5;;;;N;;;;;
+33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L;<compat> 0031 0038 65E5;;;;N;;;;;
+33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L;<compat> 0031 0039 65E5;;;;N;;;;;
+33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L;<compat> 0032 0030 65E5;;;;N;;;;;
+33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L;<compat> 0032 0031 65E5;;;;N;;;;;
+33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L;<compat> 0032 0032 65E5;;;;N;;;;;
+33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L;<compat> 0032 0033 65E5;;;;N;;;;;
+33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L;<compat> 0032 0034 65E5;;;;N;;;;;
+33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L;<compat> 0032 0035 65E5;;;;N;;;;;
+33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L;<compat> 0032 0036 65E5;;;;N;;;;;
+33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L;<compat> 0032 0037 65E5;;;;N;;;;;
+33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L;<compat> 0032 0038 65E5;;;;N;;;;;
+33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L;<compat> 0032 0039 65E5;;;;N;;;;;
+33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L;<compat> 0033 0030 65E5;;;;N;;;;;
+33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;
+3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
+4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
+9FA5;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
+A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
+A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;;
+A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;;
+A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;;
+A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;;
+A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;;
+A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;;
+A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;;
+A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;;
+A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;;
+A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;;
+A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;;
+A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;;
+A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;;
+A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;;
+A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;;
+A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;;
+A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;;
+A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;;
+A015;YI SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;;
+A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;;
+A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;;
+A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;;
+A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;;
+A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;;
+A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;;
+A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;;
+A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;;
+A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;;
+A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;;
+A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;;
+A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;;
+A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;;
+A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;;
+A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;;
+A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;;
+A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;;
+A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;;
+A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;;
+A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;;
+A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;;
+A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;;
+A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;;
+A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;;
+A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;;
+A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;;
+A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;;
+A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;;
+A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;;
+A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;;
+A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;;
+A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;;
+A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;;
+A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;;
+A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;;
+A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;;
+A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;;
+A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;;
+A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;;
+A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;;
+A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;;
+A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;;
+A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;;
+A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;;
+A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;;
+A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;;
+A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;;
+A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;;
+A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;;
+A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;;
+A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;;
+A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;;
+A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;;
+A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;;
+A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;;
+A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;;
+A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;;
+A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;;
+A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;;
+A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;;
+A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;;
+A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;;
+A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;;
+A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;;
+A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;;
+A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;;
+A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;;
+A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;;
+A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;;
+A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;;
+A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;;
+A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;;
+A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;;
+A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;;
+A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;;
+A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;;
+A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;;
+A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;;
+A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;;
+A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;;
+A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;;
+A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;;
+A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;;
+A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;;
+A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;;
+A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;;
+A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;;
+A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;;
+A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;;
+A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;;
+A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;;
+A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;;
+A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;;
+A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;;
+A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;;
+A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;;
+A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;;
+A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;;
+A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;;
+A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;;
+A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;;
+A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;;
+A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;;
+A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;;
+A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;;
+A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;;
+A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;;
+A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;;
+A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;;
+A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;;
+A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;;
+A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;;
+A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;;
+A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;;
+A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;;
+A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;;
+A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;;
+A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;;
+A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;;
+A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;;
+A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;;
+A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;;
+A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;;
+A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;;
+A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;;
+A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;;
+A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;;
+A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;;
+A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;;
+A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;;
+A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;;
+A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;;
+A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;;
+A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;;
+A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;;
+A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;;
+A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;;
+A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;;
+A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;;
+A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;;
+A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;;
+A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;;
+A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;;
+A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;;
+A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;;
+A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;;
+A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;;
+A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;;
+A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;;
+A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;;
+A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;;
+A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;;
+A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;;
+A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;;
+A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;;
+A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;;
+A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;;
+A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;;
+A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;;
+A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;;
+A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;;
+A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;;
+A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;;
+A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;;
+A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;;
+A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;;
+A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;;
+A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;;
+A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;;
+A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;;
+A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;;
+A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;;
+A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;;
+A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;;
+A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;;
+A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;;
+A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;;
+A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;;
+A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;;
+A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;;
+A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;;
+A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;;
+A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;;
+A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;;
+A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;;
+A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;;
+A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;;
+A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;;
+A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;;
+A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;;
+A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;;
+A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;;
+A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;;
+A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;;
+A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;;
+A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;;
+A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;;
+A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;;
+A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;;
+A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;;
+A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;;
+A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;;
+A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;;
+A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;;
+A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;;
+A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;;
+A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;;
+A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;;
+A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;;
+A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;;
+A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;;
+A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;;
+A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;;
+A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;;
+A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;;
+A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;;
+A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;;
+A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;;
+A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;;
+A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;;
+A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;;
+A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;;
+A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;;
+A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;;
+A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;;
+A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;;
+A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;;
+A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;;
+A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;;
+A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;;
+A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;;
+A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;;
+A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;;
+A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;;
+A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;;
+A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;;
+A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;;
+A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;;
+A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;;
+A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;;
+A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;;
+A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;;
+A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;;
+A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;;
+A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;;
+A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;;
+A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;;
+A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;;
+A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;;
+A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;;
+A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;;
+A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;;
+A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;;
+A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;;
+A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;;
+A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;;
+A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;;
+A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;;
+A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;;
+A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;;
+A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;;
+A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;;
+A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;;
+A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;;
+A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;;
+A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;;
+A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;;
+A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;;
+A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;;
+A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;;
+A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;;
+A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;;
+A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;;
+A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;;
+A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
+A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;;
+A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;;
+A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;;
+A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;;
+A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;;
+A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
+A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;;
+A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;;
+A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;;
+A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
+A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;;
+A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;;
+A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
+A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;;
+A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;;
+A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;;
+A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
+A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;;
+A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;;
+A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;;
+A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;;
+A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;;
+A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;;
+A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;;
+A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;;
+A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;;
+A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;;
+A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;;
+A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;;
+A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;;
+A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;;
+A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;;
+A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;;
+A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;;
+A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;;
+A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;;
+A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;;
+A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;;
+A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;;
+A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;;
+A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;;
+A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;;
+A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;;
+A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;;
+A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;;
+A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;;
+A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;;
+A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;;
+A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;;
+A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;;
+A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;;
+A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;;
+A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;;
+A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;;
+A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;;
+A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;;
+A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;;
+A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;;
+A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;;
+A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;;
+A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;;
+A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;;
+A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;;
+A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;;
+A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;;
+A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;;
+A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;;
+A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;;
+A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;;
+A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;;
+A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;;
+A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;;
+A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;;
+A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;;
+A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;;
+A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;;
+A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;;
+A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;;
+A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;;
+A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;;
+A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;;
+A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;;
+A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;;
+A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;;
+A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;;
+A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;;
+A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;;
+A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;;
+A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;;
+A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;;
+A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;;
+A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;;
+A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;;
+A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;;
+A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;;
+A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;;
+A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;;
+A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;;
+A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;;
+A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;;
+A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;;
+A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;;
+A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;;
+A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;;
+A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;;
+A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;;
+A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;;
+A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;;
+A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;;
+A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;;
+A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;;
+A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;;
+A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;;
+A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;;
+A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;;
+A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;;
+A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;;
+A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;;
+A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;;
+A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;;
+A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;;
+A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;;
+A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;;
+A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;;
+A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;;
+A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;;
+A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;;
+A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;;
+A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;;
+A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;;
+A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;;
+A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;;
+A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;;
+A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;;
+A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;;
+A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;;
+A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;;
+A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;;
+A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;;
+A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;;
+A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;;
+A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;;
+A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;;
+A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;;
+A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;;
+A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;;
+A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;;
+A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;;
+A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;;
+A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;;
+A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;;
+A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;;
+A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;;
+A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;;
+A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;;
+A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;;
+A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;;
+A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;;
+A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;;
+A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;;
+A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;;
+A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;;
+A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;;
+A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;;
+A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;;
+A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;;
+A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;;
+A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;;
+A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;;
+A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;;
+A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;;
+A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;;
+A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;;
+A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;;
+A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;;
+A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;;
+A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;;
+A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;;
+A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;;
+A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;;
+A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;;
+A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;;
+A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;;
+A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;;
+A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;;
+A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;;
+A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;;
+A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;;
+A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;;
+A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;;
+A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;;
+A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;;
+A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;;
+A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;;
+A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;;
+A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;;
+A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;;
+A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;;
+A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;;
+A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;;
+A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;;
+A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;;
+A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;;
+A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;;
+A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;;
+A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;;
+A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;;
+A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;;
+A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;;
+A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;;
+A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;;
+A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;;
+A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;;
+A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;;
+A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;;
+A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;;
+A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;;
+A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;;
+A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;;
+A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;;
+A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;;
+A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;;
+A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;;
+A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;;
+A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;;
+A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;;
+A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;;
+A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;;
+A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;;
+A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;;
+A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;;
+A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;;
+A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;;
+A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;;
+A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;;
+A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;;
+A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;;
+A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;;
+A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;;
+A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;;
+A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;;
+A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;;
+A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;;
+A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;;
+A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;;
+A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;;
+A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;;
+A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;;
+A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;;
+A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;;
+A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;;
+A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;;
+A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;;
+A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;;
+A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;;
+A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;;
+A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;;
+A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;;
+A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;;
+A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;;
+A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;;
+A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;;
+A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;;
+A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;;
+A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;;
+A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;;
+A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;;
+A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;;
+A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;;
+A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;;
+A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;;
+A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;;
+A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;;
+A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;;
+A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;;
+A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;;
+A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;;
+A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;;
+A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;;
+A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;;
+A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;;
+A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;;
+A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;;
+A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;;
+A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;;
+A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;;
+A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;;
+A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;;
+A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;;
+A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;;
+A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;;
+A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;;
+A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;;
+A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;;
+A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;;
+A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;;
+A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;;
+A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;;
+A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;;
+A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;;
+A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;;
+A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;;
+A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;;
+A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;;
+A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;;
+A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;;
+A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;;
+A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;;
+A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;;
+A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;;
+A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;;
+A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;;
+A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;;
+A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;;
+A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;;
+A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;;
+A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;;
+A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;;
+A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;;
+A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;;
+A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;;
+A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;;
+A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;;
+A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;;
+A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;;
+A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;;
+A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;;
+A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;;
+A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;;
+A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;;
+A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;;
+A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;;
+A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;;
+A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;;
+A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;;
+A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;;
+A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;;
+A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;;
+A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;;
+A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;;
+A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;;
+A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
+A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;;
+A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;;
+A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;;
+A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;;
+A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;;
+A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;;
+A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;;
+A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
+A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;;
+A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;;
+A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
+A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;;
+A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;;
+A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
+A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;;
+A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;;
+A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
+A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;;
+A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;;
+A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;;
+A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;;
+A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;;
+A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;;
+A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;;
+A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;;
+A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;;
+A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;;
+A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;;
+A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;;
+A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;;
+A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;;
+A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;;
+A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;;
+A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;;
+A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;;
+A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;;
+A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;;
+A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;;
+A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;;
+A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;;
+A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;;
+A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;;
+A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;;
+A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;;
+A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;;
+A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;;
+A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;;
+A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;;
+A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;;
+A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;;
+A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;;
+A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;;
+A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;;
+A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;;
+A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;;
+A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;;
+A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;;
+A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;;
+A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;;
+A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;;
+A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;;
+A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;;
+A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;;
+A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;;
+A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;;
+A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;;
+A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;;
+A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;;
+A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;;
+A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;;
+A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;;
+A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;;
+A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;;
+A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;;
+A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;;
+A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;;
+A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;;
+A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;;
+A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;;
+A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;;
+A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;;
+A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;;
+A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;;
+A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;;
+A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
+A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;;
+A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;;
+A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;;
+A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;;
+A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;;
+A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;;
+A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
+A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;;
+A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;;
+A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;;
+A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
+A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;;
+A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;;
+A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
+A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;;
+A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;;
+A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;;
+A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
+A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;;
+A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;;
+A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;;
+A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;;
+A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;;
+A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;;
+A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;;
+A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;;
+A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;;
+A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;;
+A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;;
+A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;;
+A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;;
+A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;;
+A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;;
+A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;;
+A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;;
+A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;;
+A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;;
+A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;;
+A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;;
+A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;;
+A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;;
+A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;;
+A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;;
+A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;;
+A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;;
+A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;;
+A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;;
+A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;;
+A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;;
+A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;;
+A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;;
+A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;;
+A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;;
+A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;;
+A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;;
+A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;;
+A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;;
+A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;;
+A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;;
+A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;;
+A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;;
+A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;;
+A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;;
+A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;;
+A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;;
+A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;;
+A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;;
+A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;;
+A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;;
+A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;;
+A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;;
+A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;;
+A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;;
+A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;;
+A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;;
+A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;;
+A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;;
+A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;;
+A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;;
+A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;;
+A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;;
+A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;;
+A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;;
+A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;;
+A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;;
+A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;;
+A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;;
+A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;;
+A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;;
+A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;;
+A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;;
+A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;;
+A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;;
+A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;;
+A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;;
+A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;;
+A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;;
+A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;;
+A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;;
+A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;;
+A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;;
+A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;;
+A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;;
+A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;;
+A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;;
+A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;;
+A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;;
+A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;;
+A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;;
+A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;;
+A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;;
+A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;;
+A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;;
+A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;;
+A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;;
+A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;;
+A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;;
+A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;;
+A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;;
+A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;;
+A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;;
+A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;;
+A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;;
+A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;;
+A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;;
+A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;;
+A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;;
+A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;;
+A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;;
+A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;;
+A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;;
+A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;;
+A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;;
+A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;;
+A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;;
+A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;;
+A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;;
+A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;;
+A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;;
+A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;;
+A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;;
+A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;;
+A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;;
+A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;;
+A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;;
+A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;;
+A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;;
+A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;;
+A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;;
+A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;;
+A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;;
+A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;;
+A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;;
+A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;;
+A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;;
+A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;;
+A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;;
+A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;;
+A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;;
+A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;;
+A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;;
+A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;;
+A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;;
+A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;;
+A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;;
+A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;;
+A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;;
+A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;;
+A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;;
+A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;;
+A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;;
+A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;;
+A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;;
+A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;;
+A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;;
+A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;;
+A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;;
+A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;;
+A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;;
+A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;;
+A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;;
+A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;;
+A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;;
+A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;;
+A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;;
+A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;;
+A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;;
+A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;;
+A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;;
+A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;;
+A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;;
+A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;;
+A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;;
+A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;;
+A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;;
+A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;;
+A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;;
+A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;;
+A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;;
+A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;;
+A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;;
+A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;;
+A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;;
+A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;;
+A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;;
+A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;;
+A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;;
+A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;;
+A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;;
+A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;;
+A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;;
+A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;;
+A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;;
+A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;;
+A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;;
+A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;;
+A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;;
+A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;;
+A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;;
+A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;;
+A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;;
+A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;;
+A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;;
+A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;;
+A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;;
+A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;;
+A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;;
+A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;;
+A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;;
+A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;;
+A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;;
+A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;;
+A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;;
+A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;;
+A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;;
+A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;;
+A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;;
+A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;;
+A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;;
+A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;;
+A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
+A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;;
+A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;;
+A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;;
+A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;;
+A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;;
+A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;;
+A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;;
+A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;;
+A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;;
+A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
+A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;;
+A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;;
+A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
+A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;;
+A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;;
+A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;;
+A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;;
+A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;;
+A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;;
+A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;;
+A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;;
+A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;;
+A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;;
+A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;;
+A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;;
+A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;;
+A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;;
+A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;;
+A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;;
+A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;;
+A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;;
+A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;;
+A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;;
+A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;;
+A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;;
+A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;;
+A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;;
+A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;;
+A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;;
+A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;;
+A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;;
+A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;;
+A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;;
+A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;;
+A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;;
+A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;;
+A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;;
+A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;;
+A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;;
+A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;;
+A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;;
+A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;;
+A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;;
+A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;;
+A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;;
+A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;;
+A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;;
+A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;;
+A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;;
+A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;;
+A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;;
+A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;;
+A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;;
+A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;;
+A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;;
+A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;;
+A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;;
+A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;;
+A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;;
+A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;;
+A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;;
+A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;;
+A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;;
+A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;;
+A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;;
+A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;;
+A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;;
+A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;;
+A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;;
+A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;;
+A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;;
+A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;;
+A491;YI RADICAL LI;So;0;ON;;;;;N;;;;;
+A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;;
+A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;;
+A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;;
+A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;;
+A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;;
+A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;;
+A498;YI RADICAL MI;So;0;ON;;;;;N;;;;;
+A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;;
+A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;;
+A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;;
+A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;;
+A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;;
+A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;;
+A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;;
+A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;;
+A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;;
+A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;;
+A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;;
+A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;;
+A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;;
+A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;;
+A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;;
+A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;;
+A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;;
+A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;;
+A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;;
+A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;;
+A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;;
+A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;;
+A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;;
+A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;;
+A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;;
+A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;;
+A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;;
+A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;;
+A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;;
+A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;;
+A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;;
+A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;;
+A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;;
+A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;;
+A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;;
+A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;;
+A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;;
+A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;;
+A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;;
+A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;;
+A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;;
+AC00;<Hangul Syllable, First>;Lo;0;L;;;;;N;;;;;
+D7A3;<Hangul Syllable, Last>;Lo;0;L;;;;;N;;;;;
+D800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+E000;<Private Use, First>;Co;0;L;;;;;N;;;;;
+F8FF;<Private Use, Last>;Co;0;L;;;;;N;;;;;
+F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;;
+F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;;
+F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;;
+F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;;
+F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;;
+F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;;
+F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;;
+F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;;
+F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;;
+F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;;
+F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;;
+F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;;
+F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;;
+F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;;
+F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;;
+F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;;
+F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;;
+F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;;
+F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;;
+F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;;
+F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;;
+F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;;
+F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;;
+F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;;
+F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;;
+F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;;
+F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;;
+F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;;
+F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;;
+F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;;
+F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;;
+F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;;
+F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;;
+F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;;
+F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;;
+F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;;
+F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;;
+F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;;
+F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;;
+F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;;
+F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;;
+F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;;
+F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;;
+F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;;
+F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;;
+F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;;
+F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;;
+F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;;
+F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;;
+F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;;
+F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;;
+F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;;
+F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;;
+F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;;
+F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;;
+F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;;
+F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;;
+F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;;
+F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;;
+F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;;
+F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;;
+F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;;
+F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;;
+F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;;
+F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;;
+F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;;
+F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;;
+F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;;
+F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;;
+F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;;
+F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;;
+F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;;
+F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;;
+F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;;
+F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;;
+F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;;
+F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;;
+F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;;
+F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;;
+F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;;
+F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;;
+F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;96FB;;;;N;;;;;
+F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;;
+F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;;
+F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;;
+F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;;
+F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;;
+F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;;
+F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;;
+F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;;
+F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;;
+F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;;
+F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;;
+F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;;
+F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;;
+F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;;
+F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;;
+F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;;
+F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;;
+F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;;
+F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;;
+F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;;
+F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;;
+F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;;
+F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;;
+F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;;
+F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;;
+F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;;N;;;;;
+F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;;
+F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;;
+F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;;
+F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;;
+F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;;
+F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;;
+F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;;
+F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;;N;;;;;
+F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;;
+F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;;
+F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;;
+F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;;
+F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;;N;;;;;
+F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;;
+F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;;
+F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;;
+F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;;
+F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;;
+F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;;
+F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;;
+F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;;
+F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;;
+F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;;
+F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;;
+F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;;
+F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;;
+F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;;
+F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;;
+F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;;
+F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;;
+F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;;
+F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;;
+F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;;
+F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;;
+F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;;
+F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;;
+F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;;
+F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;;
+F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;;
+F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;;
+F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;;
+F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;;
+F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;;
+F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;;
+F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;;
+F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;;
+F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;;
+F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;;
+F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;;
+F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;;
+F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;;
+F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;;
+F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;;
+F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;;
+F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;;
+F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;;
+F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;;
+F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;;
+F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;;
+F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;;
+F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;;
+F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;;
+F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;;
+F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;;
+F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;;
+F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;;
+F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;;
+F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;;
+F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;;
+F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;;
+F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;;N;;;;;
+F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;;
+F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;;
+F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;;
+F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;;
+F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;;
+F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;;
+F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;;
+F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;;
+F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;;
+F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;;
+F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;;
+F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;;
+F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;;
+F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;;
+F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;;
+F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;;
+F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;;
+F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;;
+F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;;
+F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;;
+F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;;
+F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;;
+F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;;
+F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;;
+F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;;
+F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;;
+F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;;
+F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;;
+F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;;
+F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;;
+F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;;N;;;;;
+F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;;
+F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;;N;;;;;
+F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;;
+F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;;
+F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;;
+F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;;
+F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;;
+F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;;
+F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;;
+F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;;
+F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;;
+F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;;
+F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;;
+F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;;
+F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;;
+F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;;
+F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;;
+F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;;
+F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;;
+F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;;
+F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;;
+F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;;
+F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;;
+F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;;
+F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;;
+F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;;
+F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;;
+F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;;
+F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;;
+F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;;
+F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;;
+F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;;
+F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;;
+F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;;
+F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;;
+F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;;
+F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;;
+F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;;
+F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;;
+F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;;
+F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;;
+F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;;
+F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;;
+F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;;N;;;;;
+F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;;
+F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;;
+FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;;
+FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;;
+FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;;
+FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;;
+FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;;
+FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;;
+FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;;
+FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;;
+FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;;
+FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;;
+FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;;
+FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;;
+FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;;
+FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;;
+FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;;
+FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;;
+FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;;
+FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;;
+FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;;
+FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;;
+FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;;
+FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;;
+FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;;
+FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;;
+FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;;
+FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;;
+FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;;
+FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;;
+FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;;
+FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;;
+FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;;
+FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;;
+FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;;
+FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;;
+FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;;
+FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;;
+FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;;
+FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;;
+FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;;
+FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;;
+FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;;
+FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;;
+FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;
+FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;
+FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;
+FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;
+FB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;
+FB01;LATIN SMALL LIGATURE FI;Ll;0;L;<compat> 0066 0069;;;;N;;;;;
+FB02;LATIN SMALL LIGATURE FL;Ll;0;L;<compat> 0066 006C;;;;N;;;;;
+FB03;LATIN SMALL LIGATURE FFI;Ll;0;L;<compat> 0066 0066 0069;;;;N;;;;;
+FB04;LATIN SMALL LIGATURE FFL;Ll;0;L;<compat> 0066 0066 006C;;;;N;;;;;
+FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L;<compat> 017F 0074;;;;N;;;;;
+FB06;LATIN SMALL LIGATURE ST;Ll;0;L;<compat> 0073 0074;;;;N;;;;;
+FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L;<compat> 0574 0576;;;;N;;;;;
+FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L;<compat> 0574 0565;;;;N;;;;;
+FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L;<compat> 0574 056B;;;;N;;;;;
+FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L;<compat> 057E 0576;;;;N;;;;;
+FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L;<compat> 0574 056D;;;;N;;;;;
+FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;;
+FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;;
+FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;;
+FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R;<font> 05E2;;;;N;;;;;
+FB21;HEBREW LETTER WIDE ALEF;Lo;0;R;<font> 05D0;;;;N;;;;;
+FB22;HEBREW LETTER WIDE DALET;Lo;0;R;<font> 05D3;;;;N;;;;;
+FB23;HEBREW LETTER WIDE HE;Lo;0;R;<font> 05D4;;;;N;;;;;
+FB24;HEBREW LETTER WIDE KAF;Lo;0;R;<font> 05DB;;;;N;;;;;
+FB25;HEBREW LETTER WIDE LAMED;Lo;0;R;<font> 05DC;;;;N;;;;;
+FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R;<font> 05DD;;;;N;;;;;
+FB27;HEBREW LETTER WIDE RESH;Lo;0;R;<font> 05E8;;;;N;;;;;
+FB28;HEBREW LETTER WIDE TAV;Lo;0;R;<font> 05EA;;;;N;;;;;
+FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ET;<font> 002B;;;;N;;;;;
+FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;;
+FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;;
+FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;;
+FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;;
+FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;;
+FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;;
+FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;;
+FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;;
+FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;;
+FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;;
+FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;;
+FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;;
+FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;;
+FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;;
+FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;;
+FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;;
+FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;;
+FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;;
+FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;;
+FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;;
+FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;;
+FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;;
+FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;;
+FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;;
+FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;;
+FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;;
+FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;;
+FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;;
+FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;;
+FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;;
+FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;;
+FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;;
+FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R;<compat> 05D0 05DC;;;;N;;;;;
+FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL;<isolated> 0671;;;;N;;;;;
+FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL;<final> 0671;;;;N;;;;;
+FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL;<isolated> 067B;;;;N;;;;;
+FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL;<final> 067B;;;;N;;;;;
+FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL;<initial> 067B;;;;N;;;;;
+FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL;<medial> 067B;;;;N;;;;;
+FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL;<isolated> 067E;;;;N;;;;;
+FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL;<final> 067E;;;;N;;;;;
+FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL;<initial> 067E;;;;N;;;;;
+FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL;<medial> 067E;;;;N;;;;;
+FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0680;;;;N;;;;;
+FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL;<final> 0680;;;;N;;;;;
+FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL;<initial> 0680;;;;N;;;;;
+FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL;<medial> 0680;;;;N;;;;;
+FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067A;;;;N;;;;;
+FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL;<final> 067A;;;;N;;;;;
+FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL;<initial> 067A;;;;N;;;;;
+FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL;<medial> 067A;;;;N;;;;;
+FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067F;;;;N;;;;;
+FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL;<final> 067F;;;;N;;;;;
+FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL;<initial> 067F;;;;N;;;;;
+FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL;<medial> 067F;;;;N;;;;;
+FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL;<isolated> 0679;;;;N;;;;;
+FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL;<final> 0679;;;;N;;;;;
+FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL;<initial> 0679;;;;N;;;;;
+FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL;<medial> 0679;;;;N;;;;;
+FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL;<isolated> 06A4;;;;N;;;;;
+FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL;<final> 06A4;;;;N;;;;;
+FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL;<initial> 06A4;;;;N;;;;;
+FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL;<medial> 06A4;;;;N;;;;;
+FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A6;;;;N;;;;;
+FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL;<final> 06A6;;;;N;;;;;
+FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL;<initial> 06A6;;;;N;;;;;
+FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A6;;;;N;;;;;
+FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL;<isolated> 0684;;;;N;;;;;
+FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL;<final> 0684;;;;N;;;;;
+FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL;<initial> 0684;;;;N;;;;;
+FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL;<medial> 0684;;;;N;;;;;
+FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL;<isolated> 0683;;;;N;;;;;
+FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL;<final> 0683;;;;N;;;;;
+FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL;<initial> 0683;;;;N;;;;;
+FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL;<medial> 0683;;;;N;;;;;
+FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL;<isolated> 0686;;;;N;;;;;
+FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL;<final> 0686;;;;N;;;;;
+FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL;<initial> 0686;;;;N;;;;;
+FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL;<medial> 0686;;;;N;;;;;
+FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0687;;;;N;;;;;
+FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL;<final> 0687;;;;N;;;;;
+FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL;<initial> 0687;;;;N;;;;;
+FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL;<medial> 0687;;;;N;;;;;
+FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068D;;;;N;;;;;
+FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL;<final> 068D;;;;N;;;;;
+FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068C;;;;N;;;;;
+FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL;<final> 068C;;;;N;;;;;
+FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL;<isolated> 068E;;;;N;;;;;
+FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL;<final> 068E;;;;N;;;;;
+FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL;<isolated> 0688;;;;N;;;;;
+FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL;<final> 0688;;;;N;;;;;
+FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL;<isolated> 0698;;;;N;;;;;
+FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL;<final> 0698;;;;N;;;;;
+FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL;<isolated> 0691;;;;N;;;;;
+FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL;<final> 0691;;;;N;;;;;
+FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A9;;;;N;;;;;
+FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL;<final> 06A9;;;;N;;;;;
+FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL;<initial> 06A9;;;;N;;;;;
+FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A9;;;;N;;;;;
+FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL;<isolated> 06AF;;;;N;;;;;
+FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL;<final> 06AF;;;;N;;;;;
+FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL;<initial> 06AF;;;;N;;;;;
+FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL;<medial> 06AF;;;;N;;;;;
+FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL;<isolated> 06B3;;;;N;;;;;
+FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL;<final> 06B3;;;;N;;;;;
+FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL;<initial> 06B3;;;;N;;;;;
+FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL;<medial> 06B3;;;;N;;;;;
+FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL;<isolated> 06B1;;;;N;;;;;
+FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL;<final> 06B1;;;;N;;;;;
+FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL;<initial> 06B1;;;;N;;;;;
+FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL;<medial> 06B1;;;;N;;;;;
+FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL;<isolated> 06BA;;;;N;;;;;
+FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL;<final> 06BA;;;;N;;;;;
+FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL;<isolated> 06BB;;;;N;;;;;
+FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL;<final> 06BB;;;;N;;;;;
+FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL;<initial> 06BB;;;;N;;;;;
+FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL;<medial> 06BB;;;;N;;;;;
+FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06C0;;;;N;;;;;
+FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL;<final> 06C0;;;;N;;;;;
+FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL;<isolated> 06C1;;;;N;;;;;
+FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL;<final> 06C1;;;;N;;;;;
+FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL;<initial> 06C1;;;;N;;;;;
+FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL;<medial> 06C1;;;;N;;;;;
+FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL;<isolated> 06BE;;;;N;;;;;
+FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL;<final> 06BE;;;;N;;;;;
+FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL;<initial> 06BE;;;;N;;;;;
+FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL;<medial> 06BE;;;;N;;;;;
+FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;
+FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;
+FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;
+FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;
+FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
+FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
+FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
+FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL;<medial> 06AD;;;;N;;;;;
+FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL;<isolated> 06C7;;;;N;;;;;
+FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL;<final> 06C7;;;;N;;;;;
+FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL;<isolated> 06C6;;;;N;;;;;
+FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL;<final> 06C6;;;;N;;;;;
+FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL;<isolated> 06C8;;;;N;;;;;
+FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL;<final> 06C8;;;;N;;;;;
+FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0677;;;;N;;;;;
+FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL;<isolated> 06CB;;;;N;;;;;
+FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL;<final> 06CB;;;;N;;;;;
+FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL;<isolated> 06C5;;;;N;;;;;
+FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL;<final> 06C5;;;;N;;;;;
+FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL;<isolated> 06C9;;;;N;;;;;
+FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL;<final> 06C9;;;;N;;;;;
+FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL;<isolated> 06D0;;;;N;;;;;
+FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL;<final> 06D0;;;;N;;;;;
+FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL;<initial> 06D0;;;;N;;;;;
+FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL;<medial> 06D0;;;;N;;;;;
+FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0649;;;;N;;;;;
+FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL;<medial> 0649;;;;N;;;;;
+FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0626 0627;;;;N;;;;;
+FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL;<final> 0626 0627;;;;N;;;;;
+FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D5;;;;N;;;;;
+FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL;<final> 0626 06D5;;;;N;;;;;
+FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL;<isolated> 0626 0648;;;;N;;;;;
+FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL;<final> 0626 0648;;;;N;;;;;
+FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C7;;;;N;;;;;
+FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL;<final> 0626 06C7;;;;N;;;;;
+FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C6;;;;N;;;;;
+FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL;<final> 0626 06C6;;;;N;;;;;
+FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C8;;;;N;;;;;
+FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL;<final> 0626 06C8;;;;N;;;;;
+FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D0;;;;N;;;;;
+FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL;<final> 0626 06D0;;;;N;;;;;
+FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL;<initial> 0626 06D0;;;;N;;;;;
+FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0626 0649;;;;N;;;;;
+FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL;<isolated> 06CC;;;;N;;;;;
+FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL;<final> 06CC;;;;N;;;;;
+FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL;<initial> 06CC;;;;N;;;;;
+FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL;<medial> 06CC;;;;N;;;;;
+FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 062C;;;;N;;;;;
+FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0626 062D;;;;N;;;;;
+FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 0645;;;;N;;;;;
+FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0626 064A;;;;N;;;;;
+FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 062C;;;;N;;;;;
+FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062D;;;;N;;;;;
+FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062E;;;;N;;;;;
+FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 0645;;;;N;;;;;
+FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0628 0649;;;;N;;;;;
+FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0628 064A;;;;N;;;;;
+FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 062C;;;;N;;;;;
+FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062D;;;;N;;;;;
+FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062E;;;;N;;;;;
+FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 0645;;;;N;;;;;
+FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062A 0649;;;;N;;;;;
+FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062A 064A;;;;N;;;;;
+FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 062C;;;;N;;;;;
+FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 0645;;;;N;;;;;
+FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062B 0649;;;;N;;;;;
+FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062B 064A;;;;N;;;;;
+FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062C 062D;;;;N;;;;;
+FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C 0645;;;;N;;;;;
+FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 062C;;;;N;;;;;
+FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 0645;;;;N;;;;;
+FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 062C;;;;N;;;;;
+FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062E 062D;;;;N;;;;;
+FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 0645;;;;N;;;;;
+FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 062C;;;;N;;;;;
+FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062D;;;;N;;;;;
+FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062E;;;;N;;;;;
+FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 0645;;;;N;;;;;
+FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0635 062D;;;;N;;;;;
+FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0645;;;;N;;;;;
+FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 062C;;;;N;;;;;
+FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062D;;;;N;;;;;
+FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062E;;;;N;;;;;
+FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 0645;;;;N;;;;;
+FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0637 062D;;;;N;;;;;
+FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0637 0645;;;;N;;;;;
+FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0638 0645;;;;N;;;;;
+FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 062C;;;;N;;;;;
+FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 0645;;;;N;;;;;
+FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 062C;;;;N;;;;;
+FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 0645;;;;N;;;;;
+FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 062C;;;;N;;;;;
+FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062D;;;;N;;;;;
+FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062E;;;;N;;;;;
+FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 0645;;;;N;;;;;
+FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0641 0649;;;;N;;;;;
+FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0641 064A;;;;N;;;;;
+FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0642 062D;;;;N;;;;;
+FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0642 0645;;;;N;;;;;
+FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0642 0649;;;;N;;;;;
+FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0642 064A;;;;N;;;;;
+FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0643 0627;;;;N;;;;;
+FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 062C;;;;N;;;;;
+FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062D;;;;N;;;;;
+FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062E;;;;N;;;;;
+FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0644;;;;N;;;;;
+FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0645;;;;N;;;;;
+FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0643 0649;;;;N;;;;;
+FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0643 064A;;;;N;;;;;
+FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 062C;;;;N;;;;;
+FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062D;;;;N;;;;;
+FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062E;;;;N;;;;;
+FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 0645;;;;N;;;;;
+FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0644 0649;;;;N;;;;;
+FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0644 064A;;;;N;;;;;
+FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 062C;;;;N;;;;;
+FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D;;;;N;;;;;
+FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062E;;;;N;;;;;
+FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 0645;;;;N;;;;;
+FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0645 0649;;;;N;;;;;
+FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0645 064A;;;;N;;;;;
+FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 062C;;;;N;;;;;
+FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062D;;;;N;;;;;
+FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062E;;;;N;;;;;
+FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 0645;;;;N;;;;;
+FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0646 0649;;;;N;;;;;
+FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0646 064A;;;;N;;;;;
+FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 062C;;;;N;;;;;
+FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 0645;;;;N;;;;;
+FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0647 0649;;;;N;;;;;
+FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0647 064A;;;;N;;;;;
+FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 062C;;;;N;;;;;
+FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062D;;;;N;;;;;
+FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062E;;;;N;;;;;
+FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 0645;;;;N;;;;;
+FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 064A 0649;;;;N;;;;;
+FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A 064A;;;;N;;;;;
+FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0630 0670;;;;N;;;;;
+FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0631 0670;;;;N;;;;;
+FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0649 0670;;;;N;;;;;
+FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C 0651;;;;N;;;;;
+FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D 0651;;;;N;;;;;
+FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E 0651;;;;N;;;;;
+FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F 0651;;;;N;;;;;
+FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650 0651;;;;N;;;;;
+FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651 0670;;;;N;;;;;
+FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL;<final> 0626 0631;;;;N;;;;;
+FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0626 0632;;;;N;;;;;
+FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL;<final> 0626 0645;;;;N;;;;;
+FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL;<final> 0626 0646;;;;N;;;;;
+FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL;<final> 0626 064A;;;;N;;;;;
+FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL;<final> 0628 0631;;;;N;;;;;
+FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0628 0632;;;;N;;;;;
+FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0628 0645;;;;N;;;;;
+FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL;<final> 0628 0646;;;;N;;;;;
+FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0628 0649;;;;N;;;;;
+FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 064A;;;;N;;;;;
+FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL;<final> 062A 0631;;;;N;;;;;
+FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062A 0632;;;;N;;;;;
+FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062A 0645;;;;N;;;;;
+FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062A 0646;;;;N;;;;;
+FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0649;;;;N;;;;;
+FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 064A;;;;N;;;;;
+FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL;<final> 062B 0631;;;;N;;;;;
+FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062B 0632;;;;N;;;;;
+FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062B 0645;;;;N;;;;;
+FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062B 0646;;;;N;;;;;
+FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062B 0649;;;;N;;;;;
+FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062B 064A;;;;N;;;;;
+FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0641 0649;;;;N;;;;;
+FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 064A;;;;N;;;;;
+FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0642 0649;;;;N;;;;;
+FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 064A;;;;N;;;;;
+FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL;<final> 0643 0627;;;;N;;;;;
+FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL;<final> 0643 0644;;;;N;;;;;
+FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645;;;;N;;;;;
+FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0643 0649;;;;N;;;;;
+FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 064A;;;;N;;;;;
+FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 0645;;;;N;;;;;
+FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 0649;;;;N;;;;;
+FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 064A;;;;N;;;;;
+FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0645 0627;;;;N;;;;;
+FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0645 0645;;;;N;;;;;
+FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL;<final> 0646 0631;;;;N;;;;;
+FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0646 0632;;;;N;;;;;
+FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 0645;;;;N;;;;;
+FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL;<final> 0646 0646;;;;N;;;;;
+FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0649;;;;N;;;;;
+FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 064A;;;;N;;;;;
+FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL;<final> 0649 0670;;;;N;;;;;
+FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL;<final> 064A 0631;;;;N;;;;;
+FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 064A 0632;;;;N;;;;;
+FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645;;;;N;;;;;
+FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL;<final> 064A 0646;;;;N;;;;;
+FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 064A 0649;;;;N;;;;;
+FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 064A;;;;N;;;;;
+FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0626 062C;;;;N;;;;;
+FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0626 062D;;;;N;;;;;
+FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0626 062E;;;;N;;;;;
+FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0626 0645;;;;N;;;;;
+FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0626 0647;;;;N;;;;;
+FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0628 062C;;;;N;;;;;
+FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0628 062D;;;;N;;;;;
+FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0628 062E;;;;N;;;;;
+FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0628 0645;;;;N;;;;;
+FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0628 0647;;;;N;;;;;
+FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C;;;;N;;;;;
+FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 062D;;;;N;;;;;
+FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 062E;;;;N;;;;;
+FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645;;;;N;;;;;
+FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 062A 0647;;;;N;;;;;
+FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062B 0645;;;;N;;;;;
+FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 062D;;;;N;;;;;
+FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062C 0645;;;;N;;;;;
+FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062D 062C;;;;N;;;;;
+FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062D 0645;;;;N;;;;;
+FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062E 062C;;;;N;;;;;
+FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062E 0645;;;;N;;;;;
+FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062C;;;;N;;;;;
+FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062D;;;;N;;;;;
+FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0633 062E;;;;N;;;;;
+FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645;;;;N;;;;;
+FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D;;;;N;;;;;
+FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0635 062E;;;;N;;;;;
+FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645;;;;N;;;;;
+FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062C;;;;N;;;;;
+FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0636 062D;;;;N;;;;;
+FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0636 062E;;;;N;;;;;
+FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 0645;;;;N;;;;;
+FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 062D;;;;N;;;;;
+FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0638 0645;;;;N;;;;;
+FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C;;;;N;;;;;
+FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645;;;;N;;;;;
+FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 063A 062C;;;;N;;;;;
+FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 063A 0645;;;;N;;;;;
+FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062C;;;;N;;;;;
+FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0641 062D;;;;N;;;;;
+FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0641 062E;;;;N;;;;;
+FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 0645;;;;N;;;;;
+FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 062D;;;;N;;;;;
+FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0642 0645;;;;N;;;;;
+FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0643 062C;;;;N;;;;;
+FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0643 062D;;;;N;;;;;
+FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0643 062E;;;;N;;;;;
+FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL;<initial> 0643 0644;;;;N;;;;;
+FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645;;;;N;;;;;
+FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C;;;;N;;;;;
+FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 062D;;;;N;;;;;
+FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0644 062E;;;;N;;;;;
+FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645;;;;N;;;;;
+FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0644 0647;;;;N;;;;;
+FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C;;;;N;;;;;
+FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062D;;;;N;;;;;
+FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062E;;;;N;;;;;
+FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 0645;;;;N;;;;;
+FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C;;;;N;;;;;
+FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062D;;;;N;;;;;
+FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0646 062E;;;;N;;;;;
+FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 0645;;;;N;;;;;
+FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0646 0647;;;;N;;;;;
+FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 062C;;;;N;;;;;
+FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645;;;;N;;;;;
+FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL;<initial> 0647 0670;;;;N;;;;;
+FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 064A 062C;;;;N;;;;;
+FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 064A 062D;;;;N;;;;;
+FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 064A 062E;;;;N;;;;;
+FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645;;;;N;;;;;
+FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 064A 0647;;;;N;;;;;
+FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0626 0645;;;;N;;;;;
+FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0626 0647;;;;N;;;;;
+FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0628 0645;;;;N;;;;;
+FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0628 0647;;;;N;;;;;
+FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062A 0645;;;;N;;;;;
+FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062A 0647;;;;N;;;;;
+FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062B 0645;;;;N;;;;;
+FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062B 0647;;;;N;;;;;
+FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 0645;;;;N;;;;;
+FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0633 0647;;;;N;;;;;
+FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 0645;;;;N;;;;;
+FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0634 0647;;;;N;;;;;
+FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL;<medial> 0643 0644;;;;N;;;;;
+FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0643 0645;;;;N;;;;;
+FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0644 0645;;;;N;;;;;
+FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0646 0645;;;;N;;;;;
+FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0646 0647;;;;N;;;;;
+FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 064A 0645;;;;N;;;;;
+FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 064A 0647;;;;N;;;;;
+FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E 0651;;;;N;;;;;
+FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F 0651;;;;N;;;;;
+FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650 0651;;;;N;;;;;
+FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0637 0649;;;;N;;;;;
+FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0637 064A;;;;N;;;;;
+FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0639 0649;;;;N;;;;;
+FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0639 064A;;;;N;;;;;
+FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 063A 0649;;;;N;;;;;
+FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 063A 064A;;;;N;;;;;
+FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0633 0649;;;;N;;;;;
+FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0633 064A;;;;N;;;;;
+FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0634 0649;;;;N;;;;;
+FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0634 064A;;;;N;;;;;
+FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062D 0649;;;;N;;;;;
+FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062D 064A;;;;N;;;;;
+FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062C 0649;;;;N;;;;;
+FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062C 064A;;;;N;;;;;
+FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062E 0649;;;;N;;;;;
+FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062E 064A;;;;N;;;;;
+FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0649;;;;N;;;;;
+FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0635 064A;;;;N;;;;;
+FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0636 0649;;;;N;;;;;
+FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0636 064A;;;;N;;;;;
+FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 062C;;;;N;;;;;
+FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062D;;;;N;;;;;
+FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062E;;;;N;;;;;
+FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 0645;;;;N;;;;;
+FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0634 0631;;;;N;;;;;
+FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0633 0631;;;;N;;;;;
+FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0635 0631;;;;N;;;;;
+FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0636 0631;;;;N;;;;;
+FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0637 0649;;;;N;;;;;
+FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 064A;;;;N;;;;;
+FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0649;;;;N;;;;;
+FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 064A;;;;N;;;;;
+FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0649;;;;N;;;;;
+FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 064A;;;;N;;;;;
+FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 0649;;;;N;;;;;
+FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 064A;;;;N;;;;;
+FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0634 0649;;;;N;;;;;
+FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 064A;;;;N;;;;;
+FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0649;;;;N;;;;;
+FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 064A;;;;N;;;;;
+FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0649;;;;N;;;;;
+FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 064A;;;;N;;;;;
+FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062E 0649;;;;N;;;;;
+FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062E 064A;;;;N;;;;;
+FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0635 0649;;;;N;;;;;
+FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 064A;;;;N;;;;;
+FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 0649;;;;N;;;;;
+FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 064A;;;;N;;;;;
+FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL;<final> 0634 062C;;;;N;;;;;
+FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL;<final> 0634 062D;;;;N;;;;;
+FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 062E;;;;N;;;;;
+FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645;;;;N;;;;;
+FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0634 0631;;;;N;;;;;
+FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0633 0631;;;;N;;;;;
+FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL;<final> 0635 0631;;;;N;;;;;
+FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL;<final> 0636 0631;;;;N;;;;;
+FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062C;;;;N;;;;;
+FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0634 062D;;;;N;;;;;
+FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 062E;;;;N;;;;;
+FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645;;;;N;;;;;
+FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0633 0647;;;;N;;;;;
+FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0634 0647;;;;N;;;;;
+FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645;;;;N;;;;;
+FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 062C;;;;N;;;;;
+FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062D;;;;N;;;;;
+FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062E;;;;N;;;;;
+FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 062C;;;;N;;;;;
+FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062D;;;;N;;;;;
+FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062E;;;;N;;;;;
+FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;;;;
+FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;
+FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;
+FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
+FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
+FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
+FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
+FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
+FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
+FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 0645;;;;N;;;;;
+FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062E 0645;;;;N;;;;;
+FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062C;;;;N;;;;;
+FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062D;;;;N;;;;;
+FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062E;;;;N;;;;;
+FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 062C 0645 062D;;;;N;;;;;
+FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 0645 062D;;;;N;;;;;
+FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 0645 064A;;;;N;;;;;
+FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0645 0649;;;;N;;;;;
+FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062D 062C;;;;N;;;;;
+FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062C 062D;;;;N;;;;;
+FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062C 0649;;;;N;;;;;
+FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0633 0645 062D;;;;N;;;;;
+FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062D;;;;N;;;;;
+FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062C;;;;N;;;;;
+FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0633 0645 0645;;;;N;;;;;
+FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 0645;;;;N;;;;;
+FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL;<final> 0635 062D 062D;;;;N;;;;;
+FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D 062D;;;;N;;;;;
+FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0635 0645 0645;;;;N;;;;;
+FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 062D 0645;;;;N;;;;;
+FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062D 0645;;;;N;;;;;
+FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062C 064A;;;;N;;;;;
+FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 0645 062E;;;;N;;;;;
+FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 0645 062E;;;;N;;;;;
+FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645 0645;;;;N;;;;;
+FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645 0645;;;;N;;;;;
+FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 062D 0649;;;;N;;;;;
+FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0636 062E 0645;;;;N;;;;;
+FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062E 0645;;;;N;;;;;
+FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0637 0645 062D;;;;N;;;;;
+FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 0645 062D;;;;N;;;;;
+FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645 0645;;;;N;;;;;
+FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 0645 064A;;;;N;;;;;
+FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 062C 0645;;;;N;;;;;
+FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 0645 0645;;;;N;;;;;
+FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645 0645;;;;N;;;;;
+FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0645 0649;;;;N;;;;;
+FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 063A 0645 0645;;;;N;;;;;
+FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 0645 064A;;;;N;;;;;
+FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0645 0649;;;;N;;;;;
+FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0641 062E 0645;;;;N;;;;;
+FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062E 0645;;;;N;;;;;
+FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0642 0645 062D;;;;N;;;;;
+FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0642 0645 0645;;;;N;;;;;
+FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062D 0645;;;;N;;;;;
+FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062D 064A;;;;N;;;;;
+FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 062D 0649;;;;N;;;;;
+FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 062C;;;;N;;;;;
+FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 062C;;;;N;;;;;
+FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062E 0645;;;;N;;;;;
+FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062E 0645;;;;N;;;;;
+FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0644 0645 062D;;;;N;;;;;
+FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062D;;;;N;;;;;
+FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 062C;;;;N;;;;;
+FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 0645;;;;N;;;;;
+FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062D 064A;;;;N;;;;;
+FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062D;;;;N;;;;;
+FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C 0645;;;;N;;;;;
+FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 062C;;;;N;;;;;
+FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 0645;;;;N;;;;;
+FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062E;;;;N;;;;;
+FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 062C;;;;N;;;;;
+FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 0645;;;;N;;;;;
+FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062D 0645;;;;N;;;;;
+FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062D 0649;;;;N;;;;;
+FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 062C 0645;;;;N;;;;;
+FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C 0645;;;;N;;;;;
+FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062C 0649;;;;N;;;;;
+FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 0645 064A;;;;N;;;;;
+FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0645 0649;;;;N;;;;;
+FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645 0645;;;;N;;;;;
+FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645 0645;;;;N;;;;;
+FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062E 064A;;;;N;;;;;
+FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062C 064A;;;;N;;;;;
+FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062C 0649;;;;N;;;;;
+FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062E 064A;;;;N;;;;;
+FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062E 0649;;;;N;;;;;
+FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 0645 064A;;;;N;;;;;
+FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0645 0649;;;;N;;;;;
+FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 0645 064A;;;;N;;;;;
+FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 062D 0649;;;;N;;;;;
+FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0645 0649;;;;N;;;;;
+FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062E 0649;;;;N;;;;;
+FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 062D 064A;;;;N;;;;;
+FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062D 064A;;;;N;;;;;
+FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 062D 064A;;;;N;;;;;
+FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062C 064A;;;;N;;;;;
+FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 0645 064A;;;;N;;;;;
+FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062D 064A;;;;N;;;;;
+FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062C 064A;;;;N;;;;;
+FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 0645 064A;;;;N;;;;;
+FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 0645 064A;;;;N;;;;;
+FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 0645 064A;;;;N;;;;;
+FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062D 064A;;;;N;;;;;
+FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 0645 062D;;;;N;;;;;
+FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062D 0645;;;;N;;;;;
+FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 0645 064A;;;;N;;;;;
+FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 0645 064A;;;;N;;;;;
+FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062C 062D;;;;N;;;;;
+FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062E 064A;;;;N;;;;;
+FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 0645;;;;N;;;;;
+FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645 0645;;;;N;;;;;
+FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 0645;;;;N;;;;;
+FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0646 062C 062D;;;;N;;;;;
+FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 062D 064A;;;;N;;;;;
+FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 062C 064A;;;;N;;;;;
+FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062C 064A;;;;N;;;;;
+FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 0645 064A;;;;N;;;;;
+FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062D 064A;;;;N;;;;;
+FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645 0645;;;;N;;;;;
+FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C 0645;;;;N;;;;;
+FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
+FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
+FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
+FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
+FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
+FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
+FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL;<isolated> 0627 0643 0628 0631;;;;N;;;;;
+FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D 0645 062F;;;;N;;;;;
+FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0639 0645;;;;N;;;;;
+FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL;<isolated> 0631 0633 0648 0644;;;;N;;;;;
+FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL;<isolated> 0639 0644 064A 0647;;;;N;;;;;
+FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL;<isolated> 0648 0633 0644 0645;;;;N;;;;;
+FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0649;;;;N;;;;;
+FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;;
+FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
+FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;
+FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;
+FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;
+FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;;
+FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;;
+FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON;<vertical> 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;;
+FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON;<vertical> 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;;
+FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON;<vertical> 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;;
+FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON;<vertical> 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;;
+FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<vertical> 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;;
+FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<vertical> 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;;
+FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;<vertical> 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;;
+FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;<vertical> 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;;
+FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;<vertical> 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;;
+FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;<vertical> 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;;
+FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON;<vertical> 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;;
+FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON;<vertical> 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;;
+FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON;<vertical> 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;;
+FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON;<vertical> 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;;
+FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON;<vertical> 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;;
+FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON;<vertical> 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;;
+FE49;DASHED OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DASHED OVERSCORE;;;;
+FE4A;CENTRELINE OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;;
+FE4B;WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING WAVY OVERSCORE;;;;
+FE4C;DOUBLE WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;;
+FE4D;DASHED LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING DASHED UNDERSCORE;;;;
+FE4E;CENTRELINE LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;;
+FE4F;WAVY LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING WAVY UNDERSCORE;;;;
+FE50;SMALL COMMA;Po;0;CS;<small> 002C;;;;N;;;;;
+FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON;<small> 3001;;;;N;;;;;
+FE52;SMALL FULL STOP;Po;0;CS;<small> 002E;;;;N;SMALL PERIOD;;;;
+FE54;SMALL SEMICOLON;Po;0;ON;<small> 003B;;;;N;;;;;
+FE55;SMALL COLON;Po;0;CS;<small> 003A;;;;N;;;;;
+FE56;SMALL QUESTION MARK;Po;0;ON;<small> 003F;;;;N;;;;;
+FE57;SMALL EXCLAMATION MARK;Po;0;ON;<small> 0021;;;;N;;;;;
+FE58;SMALL EM DASH;Pd;0;ON;<small> 2014;;;;N;;;;;
+FE59;SMALL LEFT PARENTHESIS;Ps;0;ON;<small> 0028;;;;N;SMALL OPENING PARENTHESIS;;;;
+FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON;<small> 0029;;;;N;SMALL CLOSING PARENTHESIS;;;;
+FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON;<small> 007B;;;;N;SMALL OPENING CURLY BRACKET;;;;
+FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON;<small> 007D;;;;N;SMALL CLOSING CURLY BRACKET;;;;
+FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<small> 3014;;;;N;SMALL OPENING TORTOISE SHELL BRACKET;;;;
+FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<small> 3015;;;;N;SMALL CLOSING TORTOISE SHELL BRACKET;;;;
+FE5F;SMALL NUMBER SIGN;Po;0;ET;<small> 0023;;;;N;;;;;
+FE60;SMALL AMPERSAND;Po;0;ON;<small> 0026;;;;N;;;;;
+FE61;SMALL ASTERISK;Po;0;ON;<small> 002A;;;;N;;;;;
+FE62;SMALL PLUS SIGN;Sm;0;ET;<small> 002B;;;;N;;;;;
+FE63;SMALL HYPHEN-MINUS;Pd;0;ET;<small> 002D;;;;N;;;;;
+FE64;SMALL LESS-THAN SIGN;Sm;0;ON;<small> 003C;;;;N;;;;;
+FE65;SMALL GREATER-THAN SIGN;Sm;0;ON;<small> 003E;;;;N;;;;;
+FE66;SMALL EQUALS SIGN;Sm;0;ON;<small> 003D;;;;N;;;;;
+FE68;SMALL REVERSE SOLIDUS;Po;0;ON;<small> 005C;;;;N;SMALL BACKSLASH;;;;
+FE69;SMALL DOLLAR SIGN;Sc;0;ET;<small> 0024;;;;N;;;;;
+FE6A;SMALL PERCENT SIGN;Po;0;ET;<small> 0025;;;;N;;;;;
+FE6B;SMALL COMMERCIAL AT;Po;0;ON;<small> 0040;;;;N;;;;;
+FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;;
+FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL;<medial> 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;;
+FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;;
+FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;;
+FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E;;;;N;ARABIC SPACING FATHAH;;;;
+FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;;
+FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;;
+FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;;
+FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650;;;;N;ARABIC SPACING KASRAH;;;;
+FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;;
+FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;;
+FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL;<medial> 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;;
+FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL;<isolated> 0020 0652;;;;N;ARABIC SPACING SUKUN;;;;
+FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL;<medial> 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;;
+FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL;<isolated> 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;;
+FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;;
+FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;;
+FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;;
+FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;;
+FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;;
+FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;;
+FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;;
+FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;;
+FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;;
+FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;;
+FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL;<initial> 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;;
+FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL;<medial> 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;;
+FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;;
+FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL;<final> 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;;
+FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL;<isolated> 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;;
+FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL;<final> 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;;
+FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL;<initial> 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;;
+FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL;<medial> 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;;
+FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL;<isolated> 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;;
+FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL;<final> 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;;
+FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL;<isolated> 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;;
+FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL;<final> 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;;
+FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL;<initial> 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;;
+FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL;<medial> 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;;
+FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL;<isolated> 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;;
+FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL;<final> 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;;
+FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL;<initial> 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;;
+FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL;<medial> 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;;
+FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;;
+FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL;<final> 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;;
+FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL;<initial> 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;;
+FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL;<medial> 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;;
+FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL;<isolated> 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;;
+FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL;<final> 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;;
+FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL;<initial> 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;;
+FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL;<medial> 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;;
+FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;;
+FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL;<final> 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;;
+FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL;<initial> 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;;
+FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL;<medial> 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;;
+FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL;<isolated> 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;;
+FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL;<final> 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;;
+FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL;<isolated> 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;;
+FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL;<final> 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;;
+FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL;<isolated> 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;;
+FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL;<final> 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;;
+FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL;<isolated> 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;;
+FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL;<final> 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;;
+FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL;<isolated> 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;;
+FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL;<final> 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;;
+FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL;<initial> 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;;
+FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL;<medial> 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;;
+FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL;<isolated> 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;;
+FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL;<final> 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;;
+FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL;<initial> 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;;
+FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL;<medial> 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;;
+FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL;<isolated> 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;;
+FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL;<final> 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;;
+FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL;<initial> 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;;
+FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL;<medial> 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;;
+FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL;<isolated> 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;;
+FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL;<final> 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;;
+FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL;<initial> 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;;
+FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL;<medial> 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;;
+FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL;<isolated> 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;;
+FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL;<final> 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;;
+FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL;<initial> 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;;
+FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL;<medial> 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;;
+FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL;<isolated> 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;;
+FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL;<final> 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;;
+FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL;<initial> 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;;
+FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL;<medial> 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;;
+FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL;<isolated> 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;;
+FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL;<final> 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;;
+FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL;<initial> 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;;
+FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL;<medial> 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;;
+FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL;<isolated> 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;;
+FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL;<final> 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;;
+FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL;<initial> 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;;
+FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL;<medial> 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;;
+FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL;<isolated> 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;;
+FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL;<final> 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;;
+FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL;<initial> 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;;
+FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL;<medial> 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;;
+FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL;<isolated> 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;;
+FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL;<final> 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;;
+FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL;<initial> 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;;
+FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL;<medial> 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;;
+FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL;<isolated> 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;;
+FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL;<final> 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;;
+FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL;<initial> 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;;
+FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL;<medial> 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;;
+FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL;<isolated> 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;;
+FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL;<final> 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;;
+FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL;<initial> 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;;
+FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL;<medial> 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;;
+FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;;
+FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL;<final> 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;;
+FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL;<initial> 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;;
+FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL;<medial> 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;;
+FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL;<isolated> 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;;
+FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL;<final> 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;;
+FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL;<initial> 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;;
+FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL;<medial> 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;;
+FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL;<isolated> 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;;
+FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL;<final> 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;;
+FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL;<initial> 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;;
+FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL;<medial> 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;;
+FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL;<isolated> 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;;
+FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL;<final> 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;;
+FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;;
+FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;;
+FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;;
+FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL;<final> 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;;
+FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL;<initial> 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;;
+FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL;<medial> 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;;
+FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;;
+FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;;
+FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;
+FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON;<wide> 0021;;;;N;;;;;
+FF02;FULLWIDTH QUOTATION MARK;Po;0;ON;<wide> 0022;;;;N;;;;;
+FF03;FULLWIDTH NUMBER SIGN;Po;0;ET;<wide> 0023;;;;N;;;;;
+FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET;<wide> 0024;;;;N;;;;;
+FF05;FULLWIDTH PERCENT SIGN;Po;0;ET;<wide> 0025;;;;N;;;;;
+FF06;FULLWIDTH AMPERSAND;Po;0;ON;<wide> 0026;;;;N;;;;;
+FF07;FULLWIDTH APOSTROPHE;Po;0;ON;<wide> 0027;;;;N;;;;;
+FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON;<wide> 0028;;;;N;FULLWIDTH OPENING PARENTHESIS;;;;
+FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON;<wide> 0029;;;;N;FULLWIDTH CLOSING PARENTHESIS;;;;
+FF0A;FULLWIDTH ASTERISK;Po;0;ON;<wide> 002A;;;;N;;;;;
+FF0B;FULLWIDTH PLUS SIGN;Sm;0;ET;<wide> 002B;;;;N;;;;;
+FF0C;FULLWIDTH COMMA;Po;0;CS;<wide> 002C;;;;N;;;;;
+FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ET;<wide> 002D;;;;N;;;;;
+FF0E;FULLWIDTH FULL STOP;Po;0;CS;<wide> 002E;;;;N;FULLWIDTH PERIOD;;;;
+FF0F;FULLWIDTH SOLIDUS;Po;0;ES;<wide> 002F;;;;N;FULLWIDTH SLASH;;;;
+FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN;<wide> 0030;0;0;0;N;;;;;
+FF11;FULLWIDTH DIGIT ONE;Nd;0;EN;<wide> 0031;1;1;1;N;;;;;
+FF12;FULLWIDTH DIGIT TWO;Nd;0;EN;<wide> 0032;2;2;2;N;;;;;
+FF13;FULLWIDTH DIGIT THREE;Nd;0;EN;<wide> 0033;3;3;3;N;;;;;
+FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN;<wide> 0034;4;4;4;N;;;;;
+FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN;<wide> 0035;5;5;5;N;;;;;
+FF16;FULLWIDTH DIGIT SIX;Nd;0;EN;<wide> 0036;6;6;6;N;;;;;
+FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN;<wide> 0037;7;7;7;N;;;;;
+FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN;<wide> 0038;8;8;8;N;;;;;
+FF19;FULLWIDTH DIGIT NINE;Nd;0;EN;<wide> 0039;9;9;9;N;;;;;
+FF1A;FULLWIDTH COLON;Po;0;CS;<wide> 003A;;;;N;;;;;
+FF1B;FULLWIDTH SEMICOLON;Po;0;ON;<wide> 003B;;;;N;;;;;
+FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON;<wide> 003C;;;;N;;;;;
+FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON;<wide> 003D;;;;N;;;;;
+FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON;<wide> 003E;;;;N;;;;;
+FF1F;FULLWIDTH QUESTION MARK;Po;0;ON;<wide> 003F;;;;N;;;;;
+FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON;<wide> 0040;;;;N;;;;;
+FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L;<wide> 0041;;;;N;;;;FF41;
+FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L;<wide> 0042;;;;N;;;;FF42;
+FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L;<wide> 0043;;;;N;;;;FF43;
+FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L;<wide> 0044;;;;N;;;;FF44;
+FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L;<wide> 0045;;;;N;;;;FF45;
+FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L;<wide> 0046;;;;N;;;;FF46;
+FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L;<wide> 0047;;;;N;;;;FF47;
+FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L;<wide> 0048;;;;N;;;;FF48;
+FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L;<wide> 0049;;;;N;;;;FF49;
+FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L;<wide> 004A;;;;N;;;;FF4A;
+FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L;<wide> 004B;;;;N;;;;FF4B;
+FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L;<wide> 004C;;;;N;;;;FF4C;
+FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L;<wide> 004D;;;;N;;;;FF4D;
+FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L;<wide> 004E;;;;N;;;;FF4E;
+FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L;<wide> 004F;;;;N;;;;FF4F;
+FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L;<wide> 0050;;;;N;;;;FF50;
+FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L;<wide> 0051;;;;N;;;;FF51;
+FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L;<wide> 0052;;;;N;;;;FF52;
+FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L;<wide> 0053;;;;N;;;;FF53;
+FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L;<wide> 0054;;;;N;;;;FF54;
+FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L;<wide> 0055;;;;N;;;;FF55;
+FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L;<wide> 0056;;;;N;;;;FF56;
+FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L;<wide> 0057;;;;N;;;;FF57;
+FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L;<wide> 0058;;;;N;;;;FF58;
+FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L;<wide> 0059;;;;N;;;;FF59;
+FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L;<wide> 005A;;;;N;;;;FF5A;
+FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON;<wide> 005B;;;;N;FULLWIDTH OPENING SQUARE BRACKET;;;;
+FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON;<wide> 005C;;;;N;FULLWIDTH BACKSLASH;;;;
+FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON;<wide> 005D;;;;N;FULLWIDTH CLOSING SQUARE BRACKET;;;;
+FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;
+FF3F;FULLWIDTH LOW LINE;Pc;0;ON;<wide> 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;;
+FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;
+FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L;<wide> 0061;;;;N;;;FF21;;FF21
+FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L;<wide> 0062;;;;N;;;FF22;;FF22
+FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L;<wide> 0063;;;;N;;;FF23;;FF23
+FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L;<wide> 0064;;;;N;;;FF24;;FF24
+FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L;<wide> 0065;;;;N;;;FF25;;FF25
+FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L;<wide> 0066;;;;N;;;FF26;;FF26
+FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L;<wide> 0067;;;;N;;;FF27;;FF27
+FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L;<wide> 0068;;;;N;;;FF28;;FF28
+FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L;<wide> 0069;;;;N;;;FF29;;FF29
+FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L;<wide> 006A;;;;N;;;FF2A;;FF2A
+FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L;<wide> 006B;;;;N;;;FF2B;;FF2B
+FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L;<wide> 006C;;;;N;;;FF2C;;FF2C
+FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L;<wide> 006D;;;;N;;;FF2D;;FF2D
+FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L;<wide> 006E;;;;N;;;FF2E;;FF2E
+FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L;<wide> 006F;;;;N;;;FF2F;;FF2F
+FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L;<wide> 0070;;;;N;;;FF30;;FF30
+FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L;<wide> 0071;;;;N;;;FF31;;FF31
+FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L;<wide> 0072;;;;N;;;FF32;;FF32
+FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L;<wide> 0073;;;;N;;;FF33;;FF33
+FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L;<wide> 0074;;;;N;;;FF34;;FF34
+FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L;<wide> 0075;;;;N;;;FF35;;FF35
+FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L;<wide> 0076;;;;N;;;FF36;;FF36
+FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L;<wide> 0077;;;;N;;;FF37;;FF37
+FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L;<wide> 0078;;;;N;;;FF38;;FF38
+FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L;<wide> 0079;;;;N;;;FF39;;FF39
+FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L;<wide> 007A;;;;N;;;FF3A;;FF3A
+FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON;<wide> 007B;;;;N;FULLWIDTH OPENING CURLY BRACKET;;;;
+FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON;<wide> 007C;;;;N;FULLWIDTH VERTICAL BAR;;;;
+FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON;<wide> 007D;;;;N;FULLWIDTH CLOSING CURLY BRACKET;;;;
+FF5E;FULLWIDTH TILDE;Sm;0;ON;<wide> 007E;;;;N;FULLWIDTH SPACING TILDE;;;;
+FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON;<narrow> 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;;
+FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON;<narrow> 300C;;;;N;HALFWIDTH OPENING CORNER BRACKET;;;;
+FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON;<narrow> 300D;;;;N;HALFWIDTH CLOSING CORNER BRACKET;;;;
+FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON;<narrow> 3001;;;;N;;;;;
+FF65;HALFWIDTH KATAKANA MIDDLE DOT;Pc;0;ON;<narrow> 30FB;;;;N;;;;;
+FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L;<narrow> 30F2;;;;N;;;;;
+FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L;<narrow> 30A1;;;;N;;;;;
+FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L;<narrow> 30A3;;;;N;;;;;
+FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L;<narrow> 30A5;;;;N;;;;;
+FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L;<narrow> 30A7;;;;N;;;;;
+FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L;<narrow> 30A9;;;;N;;;;;
+FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L;<narrow> 30E3;;;;N;;;;;
+FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L;<narrow> 30E5;;;;N;;;;;
+FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L;<narrow> 30E7;;;;N;;;;;
+FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L;<narrow> 30C3;;;;N;;;;;
+FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;<narrow> 30FC;;;;N;;;;;
+FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L;<narrow> 30A2;;;;N;;;;;
+FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L;<narrow> 30A4;;;;N;;;;;
+FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L;<narrow> 30A6;;;;N;;;;;
+FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L;<narrow> 30A8;;;;N;;;;;
+FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L;<narrow> 30AA;;;;N;;;;;
+FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L;<narrow> 30AB;;;;N;;;;;
+FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L;<narrow> 30AD;;;;N;;;;;
+FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L;<narrow> 30AF;;;;N;;;;;
+FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L;<narrow> 30B1;;;;N;;;;;
+FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L;<narrow> 30B3;;;;N;;;;;
+FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L;<narrow> 30B5;;;;N;;;;;
+FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L;<narrow> 30B7;;;;N;;;;;
+FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L;<narrow> 30B9;;;;N;;;;;
+FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L;<narrow> 30BB;;;;N;;;;;
+FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L;<narrow> 30BD;;;;N;;;;;
+FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L;<narrow> 30BF;;;;N;;;;;
+FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L;<narrow> 30C1;;;;N;;;;;
+FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L;<narrow> 30C4;;;;N;;;;;
+FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L;<narrow> 30C6;;;;N;;;;;
+FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L;<narrow> 30C8;;;;N;;;;;
+FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L;<narrow> 30CA;;;;N;;;;;
+FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L;<narrow> 30CB;;;;N;;;;;
+FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L;<narrow> 30CC;;;;N;;;;;
+FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L;<narrow> 30CD;;;;N;;;;;
+FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L;<narrow> 30CE;;;;N;;;;;
+FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L;<narrow> 30CF;;;;N;;;;;
+FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L;<narrow> 30D2;;;;N;;;;;
+FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L;<narrow> 30D5;;;;N;;;;;
+FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L;<narrow> 30D8;;;;N;;;;;
+FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L;<narrow> 30DB;;;;N;;;;;
+FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L;<narrow> 30DE;;;;N;;;;;
+FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L;<narrow> 30DF;;;;N;;;;;
+FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L;<narrow> 30E0;;;;N;;;;;
+FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L;<narrow> 30E1;;;;N;;;;;
+FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L;<narrow> 30E2;;;;N;;;;;
+FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L;<narrow> 30E4;;;;N;;;;;
+FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L;<narrow> 30E6;;;;N;;;;;
+FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L;<narrow> 30E8;;;;N;;;;;
+FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L;<narrow> 30E9;;;;N;;;;;
+FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L;<narrow> 30EA;;;;N;;;;;
+FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L;<narrow> 30EB;;;;N;;;;;
+FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L;<narrow> 30EC;;;;N;;;;;
+FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L;<narrow> 30ED;;;;N;;;;;
+FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L;<narrow> 30EF;;;;N;;;;;
+FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L;<narrow> 30F3;;;;N;;;;;
+FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;;
+FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;;
+FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L;<narrow> 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;;
+FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L;<narrow> 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;;
+FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L;<narrow> 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;;
+FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;
+FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L;<narrow> 3134;;;;N;;;;;
+FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<narrow> 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;;
+FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<narrow> 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;;
+FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L;<narrow> 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;;
+FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L;<narrow> 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;;
+FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L;<narrow> 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;;
+FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<narrow> 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;;
+FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<narrow> 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;;
+FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<narrow> 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;;
+FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L;<narrow> 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;;
+FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<narrow> 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;;
+FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<narrow> 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;;
+FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<narrow> 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;;
+FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L;<narrow> 3141;;;;N;;;;;
+FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L;<narrow> 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;;
+FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L;<narrow> 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;;
+FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L;<narrow> 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;;
+FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L;<narrow> 3145;;;;N;;;;;
+FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L;<narrow> 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;;
+FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L;<narrow> 3147;;;;N;;;;;
+FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L;<narrow> 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;;
+FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L;<narrow> 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;;
+FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L;<narrow> 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;;
+FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L;<narrow> 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;;
+FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L;<narrow> 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;;
+FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L;<narrow> 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;;
+FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L;<narrow> 314E;;;;N;;;;;
+FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L;<narrow> 314F;;;;N;;;;;
+FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L;<narrow> 3150;;;;N;;;;;
+FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L;<narrow> 3151;;;;N;;;;;
+FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L;<narrow> 3152;;;;N;;;;;
+FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L;<narrow> 3153;;;;N;;;;;
+FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L;<narrow> 3154;;;;N;;;;;
+FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L;<narrow> 3155;;;;N;;;;;
+FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L;<narrow> 3156;;;;N;;;;;
+FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L;<narrow> 3157;;;;N;;;;;
+FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L;<narrow> 3158;;;;N;;;;;
+FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L;<narrow> 3159;;;;N;;;;;
+FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L;<narrow> 315A;;;;N;;;;;
+FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L;<narrow> 315B;;;;N;;;;;
+FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L;<narrow> 315C;;;;N;;;;;
+FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L;<narrow> 315D;;;;N;;;;;
+FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L;<narrow> 315E;;;;N;;;;;
+FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L;<narrow> 315F;;;;N;;;;;
+FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L;<narrow> 3160;;;;N;;;;;
+FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L;<narrow> 3161;;;;N;;;;;
+FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L;<narrow> 3162;;;;N;;;;;
+FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;
+FFE0;FULLWIDTH CENT SIGN;Sc;0;ET;<wide> 00A2;;;;N;;;;;
+FFE1;FULLWIDTH POUND SIGN;Sc;0;ET;<wide> 00A3;;;;N;;;;;
+FFE2;FULLWIDTH NOT SIGN;Sm;0;ON;<wide> 00AC;;;;N;;;;;
+FFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;;
+FFE4;FULLWIDTH BROKEN BAR;So;0;ON;<wide> 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;;
+FFE5;FULLWIDTH YEN SIGN;Sc;0;ET;<wide> 00A5;;;;N;;;;;
+FFE6;FULLWIDTH WON SIGN;Sc;0;ET;<wide> 20A9;;;;N;;;;;
+FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON;<narrow> 2502;;;;N;;;;;
+FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON;<narrow> 2190;;;;N;;;;;
+FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON;<narrow> 2191;;;;N;;;;;
+FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON;<narrow> 2192;;;;N;;;;;
+FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON;<narrow> 2193;;;;N;;;;;
+FFED;HALFWIDTH BLACK SQUARE;So;0;ON;<narrow> 25A0;;;;N;;;;;
+FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON;<narrow> 25CB;;;;N;;;;;
+FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;BN;;;;;N;;;;;
+FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;BN;;;;;N;;;;;
+FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;BN;;;;;N;;;;;
+FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
+FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
diff --git a/source/codepages/codepage_def.1125 b/source/codepages/codepage_def.1125
new file mode 100755
index 00000000000..491445fad44
--- /dev/null
+++ b/source/codepages/codepage_def.1125
@@ -0,0 +1,168 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 1125 - OS/2 Ukrainian Cyrillic
+# defines lower->upper mapping.
+# Written by Oleg Deribas ( older@iname.com )
+
+# The columns are :
+# lower upper map to lower map to upper
+#
+ 97 65 True True
+ 98 66 True True
+ 99 67 True True
+ 100 68 True True
+ 101 69 True True
+ 102 70 True True
+ 103 71 True True
+ 104 72 True True
+ 105 73 True True
+ 106 74 True True
+ 107 75 True True
+ 108 76 True True
+ 109 77 True True
+ 110 78 True True
+ 111 79 True True
+ 112 80 True True
+ 113 81 True True
+ 114 82 True True
+ 115 83 True True
+ 116 84 True True
+ 117 85 True True
+ 118 86 True True
+ 119 87 True True
+ 120 88 True True
+ 121 89 True True
+ 122 90 True True
+ 160 128 True True
+ 161 129 True True
+ 162 130 True True
+ 163 131 True True
+ 164 132 True True
+ 165 133 True True
+ 166 134 True True
+ 167 135 True True
+ 168 136 True True
+ 169 137 True True
+ 170 138 True True
+ 171 139 True True
+ 172 140 True True
+ 173 141 True True
+ 174 142 True True
+ 175 143 True True
+ 224 144 True True
+ 225 145 True True
+ 226 146 True True
+ 227 147 True True
+ 228 148 True True
+ 229 149 True True
+ 230 150 True True
+ 231 151 True True
+ 232 152 True True
+ 233 153 True True
+ 234 154 True True
+ 235 155 True True
+ 236 156 True True
+ 237 157 True True
+ 238 158 True True
+ 239 159 True True
+ 241 240 True True
+ 243 242 True True
+ 245 244 True True
+ 247 246 True True
+ 33 0 False False
+ 35 0 False False
+ 36 0 False False
+ 37 0 False False
+ 38 0 False False
+ 39 0 False False
+ 40 0 False False
+ 41 0 False False
+ 45 0 False False
+ 48 0 False False
+ 49 0 False False
+ 50 0 False False
+ 51 0 False False
+ 52 0 False False
+ 53 0 False False
+ 54 0 False False
+ 55 0 False False
+ 56 0 False False
+ 57 0 False False
+ 64 0 False False
+ 94 0 False False
+ 95 0 False False
+ 96 0 False False
+ 123 0 False False
+ 125 0 False False
+ 126 0 False False
+ 127 0 False False
+ 176 0 False False
+ 177 0 False False
+ 178 0 False False
+ 179 0 False False
+ 180 0 False False
+ 181 0 False False
+ 182 0 False False
+ 183 0 False False
+ 184 0 False False
+ 185 0 False False
+ 186 0 False False
+ 187 0 False False
+ 188 0 False False
+ 189 0 False False
+ 190 0 False False
+ 191 0 False False
+ 192 0 False False
+ 193 0 False False
+ 194 0 False False
+ 195 0 False False
+ 196 0 False False
+ 197 0 False False
+ 198 0 False False
+ 199 0 False False
+ 200 0 False False
+ 201 0 False False
+ 202 0 False False
+ 203 0 False False
+ 204 0 False False
+ 205 0 False False
+ 206 0 False False
+ 207 0 False False
+ 208 0 False False
+ 209 0 False False
+ 210 0 False False
+ 211 0 False False
+ 212 0 False False
+ 213 0 False False
+ 214 0 False False
+ 215 0 False False
+ 216 0 False False
+ 217 0 False False
+ 218 0 False False
+ 219 0 False False
+ 220 0 False False
+ 221 0 False False
+ 222 0 False False
+ 223 0 False False
+ 248 0 False False
+ 249 0 False False
+ 250 0 False False
+ 251 0 False False
+ 252 0 False False
+ 253 0 False False
+ 254 0 False False
+ 255 0 False False
diff --git a/source/codepages/codepage_def.1251 b/source/codepages/codepage_def.1251
new file mode 100755
index 00000000000..cf68911ee2f
--- /dev/null
+++ b/source/codepages/codepage_def.1251
@@ -0,0 +1,56 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 1251 - AmigaOS Cyrillic
+# defines lower->upper mapping.
+# Written by Michael Malyshev ( Michael_Malyshev@mail.ru )
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0xA8 0xB8 True True
+ 0xC0 0xE0 True True
+ 0xC1 0xE1 True True
+ 0xC2 0xE2 True True
+ 0xC3 0xE3 True True
+ 0xC4 0xE4 True True
+ 0xC5 0xE5 True True
+ 0xC6 0xE6 True True
+ 0xC7 0xE7 True True
+ 0xC8 0xE8 True True
+ 0xC9 0xE9 True True
+ 0xCA 0xEA True True
+ 0xCB 0xEB True True
+ 0xCC 0xEC True True
+ 0xCD 0xED True True
+ 0xCE 0xEE True True
+ 0xCF 0xEF True True
+ 0xD0 0xF0 True True
+ 0xD1 0xF1 True True
+ 0xD2 0xF2 True True
+ 0xD3 0xF3 True True
+ 0xD4 0xF4 True True
+ 0xD5 0xF5 True True
+ 0xD6 0xF6 True True
+ 0xD7 0xF7 True True
+ 0xD8 0xF8 True True
+ 0xD9 0xF9 True True
+ 0xDA 0xFA True True
+ 0xDB 0xFB True True
+ 0xDC 0xFC True True
+ 0xDD 0xFD True True
+ 0xDE 0xFE True True
+ 0xDF 0xFF True True
diff --git a/source/codepages/codepage_def.437 b/source/codepages/codepage_def.437
new file mode 100755
index 00000000000..d357c074e44
--- /dev/null
+++ b/source/codepages/codepage_def.437
@@ -0,0 +1,70 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 437 - MS-DOS Latin US
+# defines lower->upper mapping.
+# Written by Jeremy Allison <jallison@whistle.com>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x87 0x80 True True
+ 0x81 0x9A True True
+ 0x82 0x90 True True
+ 0x83 0x41 True False
+ 0x84 0x8E True True
+ 0x85 0x41 True False
+ 0x86 0x8F True True
+ 0x88 0x45 True False
+ 0x89 0x45 True False
+ 0x8A 0x45 True False
+ 0x8B 0x49 True False
+ 0x8C 0x49 True False
+ 0x8D 0x49 True False
+ 0x91 0x92 True True
+ 0x93 0x4F True False
+ 0x94 0x99 True True
+ 0x95 0x4F True False
+ 0x96 0x55 True False
+ 0x97 0x55 True False
+ 0x9B 0 False False
+ 0x9C 0 False False
+ 0x9D 0 False False
+ 0xA0 0x41 True False
+ 0xA1 0x49 True False
+ 0xA2 0x4F True False
+ 0xA3 0x55 True False
+ 0xA4 0xA5 True True
+ 0xA8 0 False False
+ 0xAD 0 False False
+ 0xAE 0 False False
+ 0xAF 0 False False
+ 0xE0 0 False False
+ 0xE1 0 False False
+ 0xE2 0 False False
+ 0xE3 0 False False
+ 0xE4 0 False False
+ 0xE5 0 False False
+ 0xE6 0 False False
+ 0xE7 0 False False
+ 0xE8 0 False False
+ 0xE9 0 False False
+ 0xEA 0 False False
+ 0xEB 0 False False
+ 0xEC 0 False False
+ 0xED 0 False False
+ 0xEE 0 False False
+ 0xEF 0 False False
diff --git a/source/codepages/codepage_def.737 b/source/codepages/codepage_def.737
new file mode 100755
index 00000000000..9da99f3f3b0
--- /dev/null
+++ b/source/codepages/codepage_def.737
@@ -0,0 +1,58 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 737 - Windows '95 Greek
+# defines lower->upper mapping.
+# Written by Manousaridis Haris <genesis@the.forthnet.gr>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x87 0x80 True True
+ 0x98 0x80 True True
+ 0x99 0x81 True True
+ 0x9A 0x82 True True
+ 0x9B 0x83 True True
+ 0x9C 0x84 True True
+ 0x9D 0x85 True True
+ 0x9E 0x86 True True
+ 0x9F 0x87 True True
+ 0xA0 0x88 True True
+ 0xA1 0x89 True True
+ 0xA2 0x8A True True
+ 0xA3 0x8B True True
+ 0xA4 0x8C True True
+ 0xA5 0x8D True True
+ 0xA6 0x8E True True
+ 0xA7 0x8F True True
+ 0xA8 0x90 True True
+ 0xA9 0x91 True True
+ 0xAA 0x91 True True
+ 0xAB 0x92 True True
+ 0xAC 0x93 True True
+ 0xAD 0x94 True True
+ 0xAE 0x95 True True
+ 0xAF 0x96 True True
+ 0xE0 0x97 True True
+ 0xE1 0xEA True True
+ 0xE2 0xEB True True
+ 0xE3 0xEC True True
+ 0xE4 0xF4 True True
+ 0xE5 0xED True True
+ 0xE6 0xEE True True
+ 0xE7 0xEF True True
+ 0xE8 0xF5 True True
+ 0xE9 0xF0 True True
diff --git a/source/codepages/codepage_def.775 b/source/codepages/codepage_def.775
new file mode 100755
index 00000000000..e475b109799
--- /dev/null
+++ b/source/codepages/codepage_def.775
@@ -0,0 +1,117 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 775 - MS-DOS Baltic Rim
+# defines lower->upper mapping.
+# Written by Ded Marazm <DedMarazm@mail.lv>
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x87 0x80 True True
+ 0x81 0x9A True True
+ 0x82 0x90 True True
+ 0x83 0xA0 True True
+ 0x84 0x8E True True
+ 0x85 0x95 True True
+ 0x86 0x8F True True
+ 0x88 0xAD True True
+ 0x89 0xED True True
+ 0x8B 0x8A True True
+ 0x8C 0xA1 True True
+ 0xA5 0x8D True True
+ 0x91 0x92 True True
+ 0x93 0xE2 True True
+ 0x94 0x99 True True
+ 0x98 0x97 True True
+ 0x9B 0x9D True True
+ 0xA2 0xE0 True True
+ 0xA4 0xA3 True True
+ 0xD0 0xB5 True True
+ 0xD1 0xB6 True True
+ 0xD2 0xB7 True True
+ 0xD3 0xB8 True True
+ 0xD4 0xBD True True
+ 0xD5 0xBE True True
+ 0xD6 0xC6 True True
+ 0xD7 0xC7 True True
+ 0xD8 0xCF True True
+ 0xE7 0xE3 True True
+ 0xE4 0xE5 True True
+ 0xE9 0xE8 True True
+ 0xEB 0xEA True True
+ 0xEC 0xEE True True
+ 0x96 0 False False
+ 0x9C 0 False False
+ 0x9E 0 False False
+ 0x9F 0 False False
+ 0xA6 0 False False
+ 0xA7 0 False False
+ 0xA8 0 False False
+ 0xA9 0 False False
+ 0xAA 0 False False
+ 0xAB 0 False False
+ 0xAC 0 False False
+ 0xAE 0 False False
+ 0xAF 0 False False
+ 0xB0 0 False False
+ 0xB1 0 False False
+ 0xB2 0 False False
+ 0xB3 0 False False
+ 0xB4 0 False False
+ 0xB9 0 False False
+ 0xBA 0 False False
+ 0xBB 0 False False
+ 0xBC 0 False False
+ 0xBF 0 False False
+ 0xC0 0 False False
+ 0xC1 0 False False
+ 0xC2 0 False False
+ 0xC3 0 False False
+ 0xC4 0 False False
+ 0xC5 0 False False
+ 0xC8 0 False False
+ 0xC9 0 False False
+ 0xCA 0 False False
+ 0xCB 0 False False
+ 0xCC 0 False False
+ 0xCD 0 False False
+ 0xCE 0 False False
+ 0xD9 0 False False
+ 0xDA 0 False False
+ 0xDB 0 False False
+ 0xDC 0 False False
+ 0xDD 0 False False
+ 0xDE 0 False False
+ 0xDF 0 False False
+ 0xE1 0 False False
+ 0xE6 0 False False
+ 0xEF 0 False False
+ 0xF0 0 False False
+ 0xF1 0 False False
+ 0xF2 0 False False
+ 0xF3 0 False False
+ 0xF4 0 False False
+ 0xF5 0 False False
+ 0xF6 0 False False
+ 0xF7 0 False False
+ 0xF8 0 False False
+ 0xF9 0 False False
+ 0xFA 0 False False
+ 0xFB 0 False False
+ 0xFC 0 False False
+ 0xFD 0 False False
+ 0xFE 0 False False
+ 0xFF 0 False False
diff --git a/source/codepages/codepage_def.850 b/source/codepages/codepage_def.850
new file mode 100755
index 00000000000..e2466a707af
--- /dev/null
+++ b/source/codepages/codepage_def.850
@@ -0,0 +1,54 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 850 - MS-DOS Latin 1
+# defines lower->upper mapping.
+# Written by Jeremy Allison (jallison@whistle.com)
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x85 0xB7 True True
+ 0xA0 0xB5 True True
+ 0x83 0xB6 True True
+ 0xC6 0xC7 True True
+ 0x84 0x8E True True
+ 0x86 0x8F True True
+ 0x91 0x92 True True
+ 0x87 0x80 True True
+ 0x8A 0xD4 True True
+ 0x82 0x90 True True
+ 0x88 0xD2 True True
+ 0x89 0xD3 True True
+ 0x8D 0xDE True True
+ 0xA1 0xD6 True True
+ 0x8C 0xD7 True True
+ 0x8B 0xD8 True True
+ 0xD0 0xD1 True True
+ 0xA4 0xA5 True True
+ 0x95 0xE3 True True
+ 0xA2 0xE0 True True
+ 0x93 0xE2 True True
+ 0xE4 0xE5 True True
+ 0x94 0x99 True True
+ 0x9B 0x9D True True
+ 0x97 0xEB True True
+ 0xA3 0xE9 True True
+ 0x96 0xEA True True
+ 0x81 0x9A True True
+ 0xEC 0xED True True
+ 0xE7 0xE8 True True
+ 0x9C 0 False False
diff --git a/source/codepages/codepage_def.852 b/source/codepages/codepage_def.852
new file mode 100755
index 00000000000..76f6f7de4a6
--- /dev/null
+++ b/source/codepages/codepage_def.852
@@ -0,0 +1,64 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 852 - MS-DOS Latin 2
+# defines lower->upper mapping.
+# Written by Leos Bitto <bitto@altec.cz>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x81 0x9A True True
+ 0x82 0x90 True True
+ 0x83 0xB6 True True
+ 0x84 0x8E True True
+ 0x85 0xDE True True
+ 0x86 0x8F True True
+ 0x87 0x80 True True
+ 0x88 0x9D True True
+ 0x89 0xD3 True True
+ 0x8B 0x8A True True
+ 0x8C 0xD7 True True
+ 0x92 0x91 True True
+ 0x93 0xE2 True True
+ 0x94 0x99 True True
+ 0x96 0x95 True True
+ 0x98 0x97 True True
+ 0x9C 0x9B True True
+ 0x9F 0xAC True True
+ 0xA0 0xB5 True True
+ 0xA1 0xD6 True True
+ 0xA2 0xE0 True True
+ 0xA3 0xE9 True True
+ 0xA5 0xA4 True True
+ 0xA7 0xA6 True True
+ 0xA9 0xA8 True True
+ 0xAB 0x8D True True
+ 0xAD 0xB8 True True
+ 0xBE 0xBD True True
+ 0xC7 0xC6 True True
+ 0xD0 0xD1 True True
+ 0xD4 0xD2 True True
+ 0xD8 0xB7 True True
+ 0xE4 0xE3 True True
+ 0xE5 0xD5 True True
+ 0xE7 0xE6 True True
+ 0xEA 0xE8 True True
+ 0xEC 0xED True True
+ 0xEE 0xDD True True
+ 0xFB 0xEB True True
+ 0xFD 0xFC True True
+ 0xFF 0xFF True True
diff --git a/source/codepages/codepage_def.857 b/source/codepages/codepage_def.857
new file mode 100755
index 00000000000..ee26da7ad67
--- /dev/null
+++ b/source/codepages/codepage_def.857
@@ -0,0 +1,55 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 857 - MS-DOS Latin 5
+# defines lower->upper mapping.
+# Written by Deniz Akkus (akkus@alum.mit.edu)
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x85 0xB7 True True #A WITH GRAVE
+ 0xA0 0xB5 True True #A WITH ACUTE
+ 0x83 0xB6 True True #A WITH CIRCUMFLEX
+ 0xC6 0xC7 True True #A WITH TILDE
+ 0x84 0x8E True True #A WITH DIAERESIS
+ 0x86 0x8F True True #A WITH RING ABOVE
+ 0x91 0x92 True True #LIGATURE AE
+ 0x87 0x80 True True #C WITH CEDILLA
+ 0x8A 0xD4 True True #E WITH GRAVE
+ 0x82 0x90 True True #E WITH ACUTE
+ 0x88 0xD2 True True #E WITH CIRCUMFLEX
+ 0x89 0xD3 True True #E WITH DIAERESIS
+ 0x8D 0x49 True True #DOTLESS I
+ 0xA1 0xD6 True True #I WITH ACUTE
+ 0x8C 0xD7 True True #I WITH CIRCUMFLEX
+ 0x8B 0xD8 True True #I WITH DIAERESIS
+ 0xA4 0xA5 True True #N WITH TILDE
+ 0x95 0xE3 True True #O WITH GRAVE
+ 0xA2 0xE0 True True #O WITH ACUTE
+ 0x93 0xE2 True True #O WITH CIRCUMFLEX
+ 0xE4 0xE5 True True #O WITH TILDE
+ 0x94 0x99 True True #O WITH DIAERESIS
+ 0x9B 0x9D True True #O WITH STROKE
+ 0x97 0xEB True True #U WITH GRAVE
+ 0xA3 0xE9 True True #U WITH ACUTE
+ 0x96 0xEA True True #U WITH CIRCUMFLEX
+ 0x81 0x9A True True #U WITH DIAERESIS
+ 0xEC 0xDE True True #I WITH GRAVE
+ 0x69 0x98 True True #I WITH DOT ABOVE
+ 0xA7 0xA6 True True #G WITH BREVE
+ 0x9f 0x9e True True #S with cedilla
+
diff --git a/source/codepages/codepage_def.861 b/source/codepages/codepage_def.861
new file mode 100755
index 00000000000..b73fc576d85
--- /dev/null
+++ b/source/codepages/codepage_def.861
@@ -0,0 +1,135 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 861 - MS-DOS Icelandic
+# defines lower->upper mapping.
+# Written by Magn=FAs G=EDslason <magnus@hi.is>
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+ 0x85 0x41 True False # =E0
+ 0xA0 0xA4 True True # =E1 =C1
+ 0x83 0x41 True False # =E2
+ 0x84 0x8E True True # =E4 =C4
+ 0x86 0x8F True True # =E5 =C5
+ 0x91 0x92 True True # =E6 =C6
+ 0x87 0x80 True True # =E7 =C7
+ 0x8A 0x45 True False # =E8
+ 0x82 0x90 True True # =E9 =C9
+ 0x88 0x45 True False # =EA
+ 0x89 0x45 True False # =EB
+ 0xA1 0xA5 True True # =ED =CD
+ 0x8C 0x8B True True # =F0 =D0
+ 0xA2 0xA6 True True # =F3 =D3
+ 0x93 0x4F True False # =F4
+ 0x94 0x99 True True # =F6 =D6
+ 0x9B 0x9D True True # =F8 =D8
+ 0xA3 0xA7 True True # =FA =DA
+ 0x96 0x55 True False # =FB
+ 0x81 0x9A True True # =FC =DC
+ 0x98 0x97 True True # =FD =DD
+ 0x95 0x8D True True # =FE =DE
+ 0x9C 0 False False
+ 0x9E 0 False False
+ 0x9F 0 False False
+ 0xA8 0 False False
+ 0xA9 0 False False
+ 0xAA 0 False False
+ 0xAB 0 False False
+ 0xAC 0 False False
+ 0xAD 0 False False
+ 0xAE 0 False False
+ 0xAF 0 False False
+ 0xB0 0 False False
+ 0xB1 0 False False
+ 0xB2 0 False False
+ 0xB3 0 False False
+ 0xB4 0 False False
+ 0xB5 0 False False
+ 0xB6 0 False False
+ 0xB7 0 False False
+ 0xB8 0 False False
+ 0xB9 0 False False
+ 0xBA 0 False False
+ 0xBB 0 False False
+ 0xBC 0 False False
+ 0xBD 0 False False
+ 0xBE 0 False False
+ 0xBF 0 False False
+ 0xC0 0 False False
+ 0xC1 0 False False
+ 0xC2 0 False False
+ 0xC3 0 False False
+ 0xC4 0 False False
+ 0xC5 0 False False
+ 0xC6 0 False False
+ 0xC7 0 False False
+ 0xC8 0 False False
+ 0xC9 0 False False
+ 0xCA 0 False False
+ 0xCB 0 False False
+ 0xCC 0 False False
+ 0xCD 0 False False
+ 0xCE 0 False False
+ 0xCF 0 False False
+ 0xD0 0 False False
+ 0xD1 0 False False
+ 0xD2 0 False False
+ 0xD3 0 False False
+ 0xD4 0 False False
+ 0xD5 0 False False
+ 0xD6 0 False False
+ 0xD7 0 False False
+ 0xD8 0 False False
+ 0xD9 0 False False
+ 0xDA 0 False False
+ 0xDB 0 False False
+ 0xDC 0 False False
+ 0xDD 0 False False
+ 0xDE 0 False False
+ 0xDF 0 False False
+ 0xE0 0 False False
+ 0xE1 0 False False
+ 0xE2 0 False False
+ 0xE3 0 False False
+ 0xE4 0 False False
+ 0xE5 0 False False
+ 0xE6 0 False False
+ 0xE7 0 False False
+ 0xE8 0 False False
+ 0xE9 0 False False
+ 0xEA 0 False False
+ 0xEB 0 False False
+ 0xEC 0 False False
+ 0xED 0 False False
+ 0xEE 0 False False
+ 0xEF 0 False False
+ 0xF0 0 False False
+ 0xF1 0 False False
+ 0xF2 0 False False
+ 0xF3 0 False False
+ 0xF4 0 False False
+ 0xF5 0 False False
+ 0xF6 0 False False
+ 0xF7 0 False False
+ 0xF8 0 False False
+ 0xF9 0 False False
+ 0xFA 0 False False
+ 0xFB 0 False False
+ 0xFC 0 False False
+ 0xFD 0 False False
+ 0xFE 0 False False
+ 0xFF 0 False False
diff --git a/source/codepages/codepage_def.862 b/source/codepages/codepage_def.862
new file mode 100755
index 00000000000..df8aaf98662
--- /dev/null
+++ b/source/codepages/codepage_def.862
@@ -0,0 +1,52 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 862 - Hebrew
+# defines lower->upper mapping.
+# Written by Alexander Bokovoy (ab@alt-linux.org)
+
+# The columns are :
+# lower upper map to lower map to upper
+#
+0x74 0x54 True True
+0x63 0x43 True True
+0x75 0x55 True True
+0x64 0x44 True True
+0x76 0x56 True True
+0x65 0x45 True True
+0x77 0x57 True True
+0x66 0x46 True True
+0x78 0x58 True True
+0x67 0x47 True True
+0x79 0x59 True True
+0x68 0x48 True True
+0x69 0x49 True True
+0x7a 0x5a True True
+0x6a 0x4a True True
+0x6b 0x4b True True
+0x6c 0x4c True True
+0x6d 0x4d True True
+0x6e 0x4e True True
+0x6f 0x4f True True
+0xa4 0xa5 True True
+0xe5 0xe4 True True
+0xed 0xe8 True True
+0x70 0x50 True True
+0x71 0x51 True True
+0x61 0x41 True True
+0x72 0x52 True True
+0x62 0x42 True True
+0x73 0x53 True True
diff --git a/source/codepages/codepage_def.866 b/source/codepages/codepage_def.866
new file mode 100755
index 00000000000..c28d288be0b
--- /dev/null
+++ b/source/codepages/codepage_def.866
@@ -0,0 +1,168 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for Code Page 866 - MS-DOS Cyrillic
+# defines lower->upper mapping.
+# Written by ODiP ( odip@biogate.com )
+
+# The columns are :
+# lower upper map to lower map to upper
+#
+ 97 65 True True
+ 98 66 True True
+ 99 67 True True
+ 100 68 True True
+ 101 69 True True
+ 102 70 True True
+ 103 71 True True
+ 104 72 True True
+ 105 73 True True
+ 106 74 True True
+ 107 75 True True
+ 108 76 True True
+ 109 77 True True
+ 110 78 True True
+ 111 79 True True
+ 112 80 True True
+ 113 81 True True
+ 114 82 True True
+ 115 83 True True
+ 116 84 True True
+ 117 85 True True
+ 118 86 True True
+ 119 87 True True
+ 120 88 True True
+ 121 89 True True
+ 122 90 True True
+ 160 128 True True
+ 161 129 True True
+ 162 130 True True
+ 163 131 True True
+ 164 132 True True
+ 165 133 True True
+ 166 134 True True
+ 167 135 True True
+ 168 136 True True
+ 169 137 True True
+ 170 138 True True
+ 171 139 True True
+ 172 140 True True
+ 173 141 True True
+ 174 142 True True
+ 175 143 True True
+ 224 144 True True
+ 225 145 True True
+ 226 146 True True
+ 227 147 True True
+ 228 148 True True
+ 229 149 True True
+ 230 150 True True
+ 231 151 True True
+ 232 152 True True
+ 233 153 True True
+ 234 154 True True
+ 235 155 True True
+ 236 156 True True
+ 237 157 True True
+ 238 158 True True
+ 239 159 True True
+ 241 240 True True
+ 243 242 True True
+ 245 244 True True
+ 247 246 True True
+ 33 0 False False
+ 35 0 False False
+ 36 0 False False
+ 37 0 False False
+ 38 0 False False
+ 39 0 False False
+ 40 0 False False
+ 41 0 False False
+ 45 0 False False
+ 48 0 False False
+ 49 0 False False
+ 50 0 False False
+ 51 0 False False
+ 52 0 False False
+ 53 0 False False
+ 54 0 False False
+ 55 0 False False
+ 56 0 False False
+ 57 0 False False
+ 64 0 False False
+ 94 0 False False
+ 95 0 False False
+ 96 0 False False
+ 123 0 False False
+ 125 0 False False
+ 126 0 False False
+ 127 0 False False
+ 176 0 False False
+ 177 0 False False
+ 178 0 False False
+ 179 0 False False
+ 180 0 False False
+ 181 0 False False
+ 182 0 False False
+ 183 0 False False
+ 184 0 False False
+ 185 0 False False
+ 186 0 False False
+ 187 0 False False
+ 188 0 False False
+ 189 0 False False
+ 190 0 False False
+ 191 0 False False
+ 192 0 False False
+ 193 0 False False
+ 194 0 False False
+ 195 0 False False
+ 196 0 False False
+ 197 0 False False
+ 198 0 False False
+ 199 0 False False
+ 200 0 False False
+ 201 0 False False
+ 202 0 False False
+ 203 0 False False
+ 204 0 False False
+ 205 0 False False
+ 206 0 False False
+ 207 0 False False
+ 208 0 False False
+ 209 0 False False
+ 210 0 False False
+ 211 0 False False
+ 212 0 False False
+ 213 0 False False
+ 214 0 False False
+ 215 0 False False
+ 216 0 False False
+ 217 0 False False
+ 218 0 False False
+ 219 0 False False
+ 220 0 False False
+ 221 0 False False
+ 222 0 False False
+ 223 0 False False
+ 248 0 False False
+ 249 0 False False
+ 250 0 False False
+ 251 0 False False
+ 252 0 False False
+ 253 0 False False
+ 254 0 False False
+ 255 0 False False
diff --git a/source/po/genmsg b/source/codepages/codepage_def.932
index 08d5bd222f8..5d636ae420a 100755
--- a/source/po/genmsg
+++ b/source/codepages/codepage_def.932
@@ -1,40 +1,23 @@
-#!/bin/sh
-# Copyright (C) 2003 TAKAHASHI Motonobu <monyo@samba.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-FILES='../web/swat.c ../web/statuspage.c ../param/loadparm.c'
-LANGS='en ja tr pl fr de it'
-
-XGETTEXT=xgettext
-MSGMERGE=msgmerge
-
-WIDTH=256
-
-$XGETTEXT --default-domain="i18n_swat" \
- --add-comments \
- --keyword=_ --keyword=N_ \
- --width=${WIDTH} \
- $FILES
-
-for lang in $LANGS; do
- echo -n $lang
- mv ${lang}.msg ${lang}.msg.old
- $MSGMERGE --width=${WIDTH} ${lang}.msg.old i18n_swat.po -o ${lang}.msg
-done
-
-rm i18n_swat.po
+# Codepage definition file for IBM Code Page 932 - MS-DOS Japanese SJIS
+# defines lower->upper mapping.
+# Written by Jeremy Allison <jallison@whistle.com>
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
diff --git a/source/codepages/codepage_def.936 b/source/codepages/codepage_def.936
new file mode 100755
index 00000000000..400b60a6330
--- /dev/null
+++ b/source/codepages/codepage_def.936
@@ -0,0 +1,24 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 936 - MS-DOS Simplified Chinese.
+# defines lower->upper mapping.
+# Written by Jeremy Allison <jallison@whistle.com>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+# This file is intentionaly empty - no mappings are done.
diff --git a/source/codepages/codepage_def.949 b/source/codepages/codepage_def.949
new file mode 100755
index 00000000000..e3507904b58
--- /dev/null
+++ b/source/codepages/codepage_def.949
@@ -0,0 +1,24 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 949 - MS-DOS Korean Hangul
+# defines lower->upper mapping.
+# Written by Jeremy Allison <jallison@whistle.com>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+# This file is intentionaly empty - no mappings are done.
diff --git a/source/codepages/codepage_def.950 b/source/codepages/codepage_def.950
new file mode 100755
index 00000000000..8c6d56a5366
--- /dev/null
+++ b/source/codepages/codepage_def.950
@@ -0,0 +1,24 @@
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Codepage definition file for IBM Code Page 950 - MS-DOS Traditional Chinese
+# defines lower->upper mapping.
+# Written by Jeremy Allison <jallison@whistle.com>
+
+# The columns are :
+# lower upper map upper to lower map lower to upper
+#
+# This file is intentionaly empty - no mappings are done.
diff --git a/source/codepages/lowcase.dat b/source/codepages/lowcase.dat
deleted file mode 100644
index 62b6e2e952b..00000000000
--- a/source/codepages/lowcase.dat
+++ /dev/null
Binary files differ
diff --git a/source/codepages/upcase.dat b/source/codepages/upcase.dat
deleted file mode 100644
index bb6f9beb4e3..00000000000
--- a/source/codepages/upcase.dat
+++ /dev/null
Binary files differ
diff --git a/source/codepages/valid.dat b/source/codepages/valid.dat
deleted file mode 100644
index 78c14b33f0f..00000000000
--- a/source/codepages/valid.dat
+++ /dev/null
Binary files differ
diff --git a/source/config.guess b/source/config.guess
index 78f6b92cd30..bcdc0742b73 100755
--- a/source/config.guess
+++ b/source/config.guess
@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
-timestamp='2003-01-10'
+timestamp='2001-11-26'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ timestamp='2003-01-10'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Originally written by Per Bothner <per@bothner.com>.
+# Originally written by Per Bothner <bothner@cygnus.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
@@ -88,41 +88,30 @@ if test $# != 0; then
exit 1
fi
-trap 'exit 1' 1 2 15
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int dummy(){}" > $dummy.c ;
+ for c in cc gcc c89 ; do
+ ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+ if test $? = 0 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
+ rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ;'
+esac'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -146,23 +135,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ # Determine the machine/vendor (is the vendor relevant).
+ case "${UNAME_MACHINE}" in
+ amiga) machine=m68k-unknown ;;
+ arm32) machine=arm-unknown ;;
+ atari*) machine=m68k-atari ;;
+ sun3*) machine=m68k-sun ;;
+ mac68k) machine=m68k-apple ;;
+ macppc) machine=powerpc-apple ;;
+ hp3[0-9][05]) machine=m68k-hp ;;
+ ibmrt|romp-ibm) machine=romp-ibm ;;
+ sparc*) machine=`uname -p`-unknown ;;
+ *) machine=${UNAME_MACHINE}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ case "${UNAME_MACHINE}" in
+ i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
@@ -179,18 +168,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
@@ -235,9 +213,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
- *:MicroBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
- exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -246,7 +221,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- eval $set_cc_for_build
cat <<EOF >$dummy.s
.data
\$Lformat:
@@ -272,9 +246,10 @@ main:
jsr \$26,exit
.end main
EOF
- $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
+ eval $set_cc_for_build
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
- case `$dummy` in
+ case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
@@ -296,11 +271,9 @@ EOF
2-1307)
UNAME_MACHINE="alphaev68"
;;
- 3-1307)
- UNAME_MACHINE="alphaev7"
- ;;
esac
fi
+ rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha\ *:Windows_NT*:*)
@@ -318,9 +291,6 @@ EOF
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
@@ -341,10 +311,6 @@ EOF
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
- DRS?6000:UNIX_SV:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7 && exit 0 ;;
- esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
@@ -373,7 +339,7 @@ EOF
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
@@ -451,20 +417,15 @@ EOF
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c \
- && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && exit 0
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit 0 ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
@@ -537,7 +498,8 @@ EOF
exit(0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -546,7 +508,7 @@ EOF
fi
exit 0 ;;
*:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
@@ -635,21 +597,11 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- # avoid double evaluation of $set_cc_for_build
- test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
@@ -683,7 +635,8 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -729,6 +682,9 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
@@ -741,15 +697,18 @@ EOF
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
- *:UNICOS/mp:*:*)
- echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
@@ -766,18 +725,7 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
- # Determine whether the default compiler uses glibc.
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #if __GLIBC__ >= 2
- LIBC=gnu
- #else
- LIBC=
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -788,17 +736,11 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
- x86:Interix*:3*)
- echo i586-pc-interix3
- exit 0 ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
+ echo i386-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
@@ -819,48 +761,16 @@ EOF
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux
exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+ big) echo mips-unknown-linux-gnu && exit 0 ;;
+ little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+ esac
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
@@ -909,8 +819,7 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ ld_supported_targets=`cd /; ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
@@ -922,7 +831,7 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0 ;;
+ exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0 ;;
@@ -934,28 +843,32 @@ EOF
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #ifdef __INTEL_COMPILER
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-pc-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
@@ -972,23 +885,6 @@ EOF
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit 0 ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -1010,19 +906,22 @@ EOF
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
&& UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1046,15 +945,9 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit 0 ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -1071,6 +964,9 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
@@ -1142,9 +1038,6 @@ EOF
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
@@ -1152,24 +1045,18 @@ EOF
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
- case `uname -p` in
- *86) UNAME_PROCESSOR=i686 ;;
- powerpc) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
+ if test "${UNAME_MACHINE}" = "x86pc"; then
UNAME_MACHINE=pc
fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ echo `uname -p`-${UNAME_MACHINE}-nto-qnx
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
- NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1192,6 +1079,11 @@ EOF
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
@@ -1210,6 +1102,12 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1330,7 +1228,8 @@ main ()
}
EOF
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
# Apollos put the system type in the environment.
diff --git a/source/configure.developer b/source/configure.developer
index a7074acfd3a..fbd7c99533f 100755
--- a/source/configure.developer
+++ b/source/configure.developer
@@ -1,2 +1,4 @@
#!/bin/sh
-`dirname $0`/configure --enable-developer "$@"
+CFLAGS="$CFLAGS -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD -DDEVELOPER"
+export CFLAGS
+`dirname $0`/configure $*
diff --git a/source/configure.in b/source/configure.in
index f23f60626a7..c4f0c7aab85 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -1,42 +1,29 @@
dnl Process this file with autoconf to produce a configure script.
-
-dnl We must use autotools 2.53 or above
-AC_PREREQ(2.53)
AC_INIT(include/includes.h)
AC_CONFIG_HEADER(include/config.h)
-AC_DISABLE_STATIC
-AC_ENABLE_SHARED
-
#################################################
# Directory handling stuff to support both the
# legacy SAMBA directories and FHS compliant
# ones...
AC_PREFIX_DEFAULT(/usr/local/samba)
-lockdir="\${VARDIR}/locks"
-piddir="\${VARDIR}/locks"
-mandir="\${prefix}/man"
-logfilebase="\${VARDIR}"
-privatedir="\${prefix}/private"
-libdir="\${prefix}/lib"
-configdir="\${LIBDIR}"
-swatdir="\${prefix}/swat"
-
AC_ARG_WITH(fhs,
[ --with-fhs Use FHS-compliant paths (default=no)],
-[ case "$withval" in
- yes)
- lockdir="\${VARDIR}/lib/samba"
- piddir="\${VARDIR}/run"
- mandir="\${prefix}/share/man"
+ codepagedir="\$(DATADIR)/samba/codepages"
+ configdir="${sysconfdir}/samba"
+ lockdir="\${VARDIR}/cache/samba"
+ piddir="\$(VARDIR)/run/samba"
logfilebase="\${VARDIR}/log/samba"
privatedir="\${CONFIGDIR}/private"
- libdir="\${prefix}/lib/samba"
- configdir="${sysconfdir}/samba"
- swatdir="\${DATADIR}/samba/swat"
- ;;
- esac])
+ swatdir="\${DATADIR}/samba/swat",
+ codepagedir="\$(LIBDIR)/codepages"
+ configdir="\$(LIBDIR)"
+ logfilebase="\$(VARDIR)"
+ lockdir="\${VARDIR}/locks"
+ piddir="\$(VARDIR)/locks"
+ privatedir="\${prefix}/private"
+ swatdir="\${prefix}/swat")
#################################################
# set private directory location
@@ -105,7 +92,7 @@ AC_ARG_WITH(swatdir,
#################################################
# set configuration directory location
AC_ARG_WITH(configdir,
-[ --with-configdir=DIR Where to put configuration files ($libdir)],
+[ --with-configdir=DIR Where to put configuration files (\$libdir)],
[ case "$withval" in
yes|no)
#
@@ -119,72 +106,38 @@ AC_ARG_WITH(configdir,
esac])
#################################################
-# set log directory location
-AC_ARG_WITH(logfilebase,
-[ --with-logfilebase=DIR Where to put log files ($VARDIR)],
+# set codepage directory location
+AC_ARG_WITH(codepagedir,
+[ --with-codepagedir=DIR Where to put codepage files (\$libdir/codepages)],
[ case "$withval" in
yes|no)
#
# Just in case anybody does it
#
- AC_MSG_WARN([--with-logfilebase called without argument - will use default])
+ AC_MSG_WARN([--with-codepagedir called without argument - will use default])
;;
* )
- logfilebase="$withval"
+ codepagedir="$withval"
;;
esac])
#################################################
-# set lib directory location
-AC_ARG_WITH(libdir,
-[ --with-libdir=DIR Where to put libdir ($libdir)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody does it
- #
- AC_MSG_WARN([--with-libdir without argument - will use default])
- ;;
- * )
- libdir="$withval"
- ;;
- esac])
-
-#################################################
-# set lib directory location
-AC_ARG_WITH(mandir,
-[ --with-mandir=DIR Where to put man pages ($mandir)],
+# set log directory location
+AC_ARG_WITH(logfilebase,
+[ --with-logfilebase=DIR Where to put log files (\$(VARDIR))],
[ case "$withval" in
yes|no)
#
# Just in case anybody does it
#
- AC_MSG_WARN([--with-mandir without argument - will use default])
+ AC_MSG_WARN([--with-logfilebase called without argument - will use default])
;;
* )
- mandir="$withval"
+ logfilebase="$withval"
;;
esac])
-AC_ARG_WITH(cfenc,
-[ --with-cfenc=HEADERDIR Use internal CoreFoundation encoding API
- for optimization (Mac OS X/Darwin only)],
-[
-# May be in source $withval/CoreFoundation/StringEncodings.subproj.
-# Should have been in framework $withval/CoreFoundation.framework/Headers.
-for d in \
- $withval/CoreFoundation/StringEncodings.subproj \
- $withval/StringEncodings.subproj \
- $withval/CoreFoundation.framework/Headers \
- $withval/Headers \
- $withval
-do
- if test -r $d/CFStringEncodingConverter.h; then
- ln -sfh $d include/CoreFoundation
- fi
-done
-])
-
+AC_SUBST(codepagedir)
AC_SUBST(configdir)
AC_SUBST(lockdir)
AC_SUBST(piddir)
@@ -196,31 +149,28 @@ AC_SUBST(sbindir)
dnl Unique-to-Samba variables we'll be playing with.
AC_SUBST(SHELL)
+AC_SUBST(RUNPROG)
+AC_SUBST(MPROGS)
AC_SUBST(LDSHFLAGS)
AC_SUBST(SONAMEFLAG)
-AC_SUBST(SHLD)
+AC_SUBST(SHLD)
AC_SUBST(HOST_OS)
-AC_SUBST(PICFLAGS)
+AC_SUBST(PAM_MOD)
+AC_SUBST(PDBEDIT)
+AC_SUBST(WRAP)
+AC_SUBST(WRAP32)
+AC_SUBST(WRAPPROG)
+AC_SUBST(PICFLAG)
AC_SUBST(PICSUFFIX)
AC_SUBST(SHLIBEXT)
-AC_SUBST(INSTALLCLIENT)
+AC_SUBST(BLDSHARED)
AC_SUBST(INSTALLCLIENTCMD_SH)
AC_SUBST(INSTALLCLIENTCMD_A)
AC_SUBST(LIBSMBCLIENT_SHARED)
AC_SUBST(LIBSMBCLIENT)
-AC_SUBST(PRINT_LIBS)
-AC_SUBST(AUTH_LIBS)
-AC_SUBST(ACL_LIBS)
-AC_SUBST(PASSDB_LIBS)
-AC_SUBST(IDMAP_LIBS)
-AC_SUBST(KRB5_LIBS)
-AC_SUBST(LDAP_LIBS)
-AC_SUBST(SHLIB_PROGS)
-AC_SUBST(SMBWRAPPER)
-AC_SUBST(EXTRA_BIN_PROGS)
-AC_SUBST(EXTRA_SBIN_PROGS)
-AC_SUBST(EXTRA_ALL_TARGETS)
-AC_SUBST(CONFIG_LIBS)
+
+# compile with optimization and without debugging by default
+CFLAGS="-O ${CFLAGS}"
AC_ARG_ENABLE(debug,
[ --enable-debug Turn on compiler debugging information (default=no)],
@@ -228,64 +178,19 @@ AC_ARG_ENABLE(debug,
CFLAGS="${CFLAGS} -g"
fi])
-AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
- [if eval "test x$enable_developer = xyes"; then
- developer=yes
- CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
- fi])
-
-AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
- [if eval "test x$enable_krb5developer = xyes"; then
- developer=yes
- CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
- fi])
-
-AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc Enable heap debugging [default=no]])
-if test "x$enable_dmalloc" = xyes
-then
- AC_DEFINE(ENABLE_DMALLOC, 1, [Define to turn on dmalloc debugging])
- AC_DEFINE(DMALLOC_FUNC_CHECK, 1,
- [Define to check invariants around some common functions])
- LIBS="$LIBS -ldmalloc"
-fi
dnl Checks for programs.
-
-##
-## for some reason this macro resets the CFLAGS
-## so save and restore
-##
-OLD_CFLAGS=${CFLAGS}
AC_PROG_CC
-CFLAGS=${OLD_CFLAGS}
-
-OLD_CFLAGS=${CFLAGS}
-AC_PROG_CPP
-CFLAGS=${OLD_CFLAGS}
-
AC_PROG_INSTALL
AC_PROG_AWK
-AC_PATH_PROG(PERL, perl)
-
-AC_CHECK_TOOL(AR, ar)
-
-# compile with optimization and without debugging by default, but
-# allow people to set their own preference.
-if test "x$CFLAGS" = x
-then
- CFLAGS="-O ${CFLAGS}"
-fi
-
dnl Check if we use GNU ld
LD=ld
AC_PROG_LD_GNU
-
-dnl needed before AC_TRY_COMPILE
-AC_ISC_POSIX
-
dnl look for executable suffix
AC_EXEEXT
+AC_PATH_PROG(passwd_program, passwd, /bin/passwd)
+AC_SUBST(passwd_program)
dnl Check if C compiler understands -c and -o at the same time
AC_PROG_CC_C_O
@@ -296,53 +201,15 @@ else
fi
AC_SUBST(BROKEN_CC)
-dnl Check if the C compiler understands -Werror
-AC_CACHE_CHECK([that the C compiler understands -Werror],samba_cv_HAVE_Werror, [
- AC_TRY_RUN_STRICT([
- int main(void)
- {
- return 0;
- }],[-Werror],[$CPPFLAGS],[$LDFLAGS],
- samba_cv_HAVE_Werror=yes,samba_cv_HAVE_Werror=no,samba_cv_HAVE_Werror=cross)])
-if test x"$samba_cv_HAVE_Werror" = x"yes"; then
- Werror_FLAGS="-Werror"
-else
-dnl Check if the C compiler understands -w2
-AC_CACHE_CHECK([that the C compiler understands -w2],samba_cv_HAVE_w2, [
- AC_TRY_RUN_STRICT([
- int main(void)
- {
- return 0;
- }],[-w2],[$CPPFLAGS],[$LDFLAGS],
- samba_cv_HAVE_w2=yes,samba_cv_HAVE_w2=no,samba_cv_HAVE_w2=cross)])
-if test x"$samba_cv_HAVE_w2" = x"yes"; then
- Werror_FLAGS="-w2"
-fi
-fi
-
dnl Check if the C compiler understands volatile (it should, being ANSI).
AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [
AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0],
samba_cv_volatile=yes,samba_cv_volatile=no)])
if test x"$samba_cv_volatile" = x"yes"; then
- AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile])
+ AC_DEFINE(HAVE_VOLATILE)
fi
-UNAME_S=`(uname -s) 2>/dev/null` || UNAME_S="unknown"
-AC_MSG_CHECKING(uname -s)
-AC_MSG_RESULT(${UNAME_S})
-
-UNAME_R=`(uname -r) 2>/dev/null` || UNAME_R="unknown"
-AC_MSG_CHECKING(uname -r)
-AC_MSG_RESULT(${UNAME_R})
-
-UNAME_M=`(uname -m) 2>/dev/null` || UNAME_M="unknown"
-AC_MSG_CHECKING(uname -m)
-AC_MSG_RESULT(${UNAME_M})
-UNAME_P=`(uname -p) 2>/dev/null` || UNAME_P="unknown"
-AC_MSG_CHECKING(uname -p)
-AC_MSG_RESULT(${UNAME_P})
AC_CANONICAL_SYSTEM
@@ -356,30 +223,16 @@ AC_VALIDATE_CACHE_SYSTEM_TYPE
DYNEXP=
-dnl Add modules that have to be built by default here
-dnl These have to be built static:
-default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
-
-dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437"
-
-if test "x$developer" = xyes; then
- default_static_modules="$default_static_modules rpc_echo"
- default_shared_modules="$default_shared_modules charset_weird"
-fi
-
#
# Config CPPFLAG settings for strange OS's that must be set
-# before other tests. Do NOT invoke AC_CHECK_HEADERS within this
-# case statement; its first reference must be unconditional.
+# before other tests.
#
case "$host_os" in
# Try to work out if this is the native HPUX compiler that uses the -Ae flag.
*hpux*)
-
AC_PROG_CC_FLAG(Ae)
# mmap on HPUX is completely broken...
- AC_DEFINE(MMAP_BLACKLIST, 1, [Whether MMAP is broken])
+ AC_DEFINE(MMAP_BLACKLIST)
if test $ac_cv_prog_cc_Ae = yes; then
CPPFLAGS="$CPPFLAGS -Ae"
fi
@@ -391,32 +244,34 @@ case "$host_os" in
case `uname -r` in
*9*|*10*)
CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4 -DMAX_POSITIVE_LOCK_OFFSET=0x1ffffffffffLL"
- AC_DEFINE(USE_BOTH_CRYPT_CALLS, 1, [Whether to use both of HPUX' crypt calls])
- AC_DEFINE(_HPUX_SOURCE, 1, [Whether to use HPUX extensions])
- AC_DEFINE(_POSIX_SOURCE, 1, [Whether to use POSIX compatible functions])
- AC_DEFINE(_ALIGNMENT_REQUIRED,1,[Required alignment])
- AC_DEFINE(_MAX_ALIGNMENT,4,[Maximum alignment])
+ AC_DEFINE(USE_BOTH_CRYPT_CALLS)
+ AC_DEFINE(_HPUX_SOURCE)
+ AC_DEFINE(_POSIX_SOURCE)
+ AC_DEFINE(_ALIGNMENT_REQUIRED,1)
+ AC_DEFINE(_MAX_ALIGNMENT,4)
;;
*11*)
CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4 -DMAX_POSITIVE_LOCK_OFFSET=0x1ffffffffffLL"
- AC_DEFINE(USE_BOTH_CRYPT_CALLS, 1, [Whether to use both of HPUX' crypt calls])
- AC_DEFINE(_HPUX_SOURCE, 1, [Whether to use HPUX extensions])
- AC_DEFINE(_POSIX_SOURCE, 1, [Whether to use POSIX compatible functions])
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to use large file support])
- AC_DEFINE(_ALIGNMENT_REQUIRED, 1, [Required alignment])
- AC_DEFINE(_MAX_ALIGNMENT, 4, [Maximum alignment])
+ AC_DEFINE(_HPUX_SOURCE)
+ AC_DEFINE(_POSIX_SOURCE)
+ AC_DEFINE(_LARGEFILE64_SOURCE)
+ AC_DEFINE(POSIX_ACL_NEEDS_MASK)
+ AC_DEFINE(_ALIGNMENT_REQUIRED,1)
+ AC_DEFINE(_MAX_ALIGNMENT,4)
+ AC_DEFINE(USE_BOTH_CRYPT_CALLS)
;;
esac
DYNEXP="-Wl,-E"
;;
+
#
# CRAY Unicos has broken const handling
- *unicos*)
- AC_MSG_RESULT([disabling const])
- CPPFLAGS="$CPPFLAGS -Dconst="
- ;;
-
+ *unicos*)
+ AC_MSG_RESULT([disabling const])
+ CPPFLAGS="$CPPFLAGS -Dconst="
+ ;;
+
#
# AIX4.x doesn't even admit to having large
# files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
@@ -424,7 +279,7 @@ case "$host_os" in
*aix4*)
AC_MSG_RESULT([enabling large file support])
CPPFLAGS="$CPPFLAGS -D_LARGE_FILES"
- AC_DEFINE(_LARGE_FILES, 1, [Whether to enable large file support])
+ AC_DEFINE(_LARGE_FILES)
;;
#
# Defines needed for Solaris 2.6/2.7 aka 7.0 to make it admit
@@ -434,10 +289,7 @@ case "$host_os" in
# compile work using gcc 2.7 and 2.8, whereas using the Sun
# recommendation makes the compile fail on gcc2.7. JRA.
#
-# Solaris uses SYSV printing. Make sure to set that here. --jerry
-#
*solaris*)
- AC_DEFINE(SYSV, 1, [Whether to enable System V compatibility])
case `uname -r` in
5.0*|5.1*|5.2*|5.3*|5.5*)
AC_MSG_RESULT([no large file support])
@@ -451,32 +303,23 @@ case "$host_os" in
case "$ac_cv_gcc_compiler_version_number" in
*"gcc version 2.6"*|*"gcc version 2.7"*)
CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
+ AC_DEFINE(_LARGEFILE64_SOURCE)
;;
*)
CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
- AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
+ AC_DEFINE(_LARGEFILE64_SOURCE)
+ AC_DEFINE(_FILE_OFFSET_BITS,64)
;;
esac
else
CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
- AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
+ AC_DEFINE(_LARGEFILE64_SOURCE)
+ AC_DEFINE(_FILE_OFFSET_BITS,64)
fi
;;
esac
;;
#
-# IRIX uses SYSV printing. Make sure to set that here
-#
- *irix*)
- AC_DEFINE(SYSV, 1, [Whether to enable System V compatibility])
- ;;
- *freebsd*)
- AC_DEFINE(FREEBSD, 1, [Whether the host os is FreeBSD])
- ;;
-#
# VOS may need to have POSIX support and System V compatibility enabled.
#
*vos*)
@@ -484,8 +327,8 @@ case "$host_os" in
*-D_POSIX_C_SOURCE*)
;;
*)
- CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200112L"
- AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Whether to enable POSIX support])
+ CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=199506L"
+ AC_DEFINE(_POSIX_C_SOURCE, 199506L, [Whether to enable POSIX support])
;;
esac
case "$CPPFLAGS" in
@@ -516,7 +359,7 @@ exit(1);
CPPFLAGS="$old_CPPFLAGS"
if test x$SINIX_LFS_SUPPORT = xyes ; then
CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
+ AC_DEFINE(_LARGEFILE64_SOURCE)
CFLAGS="`getconf LFS64_CFLAGS` $CFLAGS"
LDFLAGS="`getconf LFS64_LDFLAGS` $LDFLAGS"
LIBS="`getconf LFS64_LIBS` $LIBS"
@@ -534,8 +377,6 @@ exit(1);
AC_TRY_RUN([
#include <unistd.h>
#include <sys/utsname.h>
-#include <string.h>
-#include <stdlib.h>
main() {
#if _LFS64_LARGEFILE == 1
struct utsname uts;
@@ -556,7 +397,7 @@ main() {
/* Ensure this is kernel 2.4 or higher */
uname(&uts);
- release = strdup(uts.release);
+ release = uts.release;
major = atoi(strsep(&release, "."));
minor = atoi(strsep(&release, "."));
@@ -568,38 +409,16 @@ main() {
#endif
}
], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross])
- CPPFLAGS="$old_CPPFLAGS"
- if test x$LINUX_LFS_SUPPORT = xyes ; then
- CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
- AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
- AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
- fi
- AC_MSG_RESULT([$LINUX_LFS_SUPPORT])
- ;;
-
-#
-# MacOS X is the *only* system that uses compose character in utf8. This
-# is so horribly broken....
-#
- *darwin*)
- AC_DEFINE(BROKEN_UNICODE_COMPOSE_CHARACTERS, 1, [Does this system use unicode compose characters])
-# Add Fink directories for various packages, like dlcompat.
-# Note: iconv does that explicitly below, but other packages
-# don't.
- CPPFLAGS="$CPPFLAGS -I/sw/include"
- LDFLAGS="$LDFLAGS -L/sw/lib"
-
-# If we have dlsym_prepend_underscore (from Fink's dlcompat),
-# use that instead of plain dlsym.
-
- AC_CHECK_LIB(dl,dlopen)
- AC_CHECK_FUNCS(dlsym_prepend_underscore,[CPPFLAGS="$CPPFLAGS -Ddlsym=dlsym_prepend_underscore"])
-
-# Add a system specific charset module.
+ CPPFLAGS="$old_CPPFLAGS"
+ if test x$LINUX_LFS_SUPPORT = xyes ; then
+ CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS"
+ AC_DEFINE(_LARGEFILE64_SOURCE)
+ AC_DEFINE(_FILE_OFFSET_BITS,64)
+ AC_DEFINE(_GNU_SOURCE)
+ fi
+ AC_MSG_RESULT([$LINUX_LFS_SUPPORT])
+ ;;
- default_shared_modules="$default_shared_modules charset_macosxfs"
- ;;
*hurd*)
AC_MSG_CHECKING([for LFS support])
old_CPPFLAGS="$CPPFLAGS"
@@ -616,8 +435,8 @@ exit(1);
CPPFLAGS="$old_CPPFLAGS"
if test x$GLIBC_LFS_SUPPORT = xyes ; then
CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
- AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
- AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
+ AC_DEFINE(_LARGEFILE64_SOURCE)
+ AC_DEFINE(_GNU_SOURCE)
fi
AC_MSG_RESULT([$GLIBC_LFS_SUPPORT])
;;
@@ -631,24 +450,13 @@ AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h)
-AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
+AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
+AC_CHECK_HEADERS(stdlib.h string.h strings.h syslog.h sys/file.h)
AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h)
-AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
-AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
+AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h sys/socket.h)
+AC_CHECK_HEADERS(syslog.h sys/syslog.h sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
-AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h dlfcn.h)
-AC_CHECK_HEADERS(sys/syslog.h syslog.h execinfo.h)
-AC_CHECK_HEADERS(langinfo.h locale.h)
-
-# Look for Darwin headers
-old_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="-Iinclude $CPPFLAGS"
-AC_CHECK_HEADERS([CoreFoundation/CFStringEncodingConverter.h], [], [AC_CHECK_HEADERS([CFStringEncodingConverter.h])])
-CPPFLAGS="$old_CPPFLAGS"
-
-# In valgrind 1.0.x, it's just valgrind.h. In 1.9.x+ there's a
-# subdirectory of headers.
-AC_CHECK_HEADERS(valgrind.h valgrind/valgrind.h valgrind/memcheck.h)
+AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h dlfcn.h synch.h pthread.h nsswitch.h)
#
# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
@@ -659,19 +467,25 @@ case "$host_os" in
AC_TRY_COMPILE([#include <shadow.h>],[struct spwd testme],
ac_cv_header_shadow_h=yes,ac_cv_header_shadow_h=no)
if test x"$ac_cv_header_shadow_h" = x"yes"; then
- AC_DEFINE(HAVE_SHADOW_H,1,[Whether we have shadow.h])
+ AC_DEFINE(HAVE_SHADOW_H)
fi
;;
esac
AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
-AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h)
+AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/cdefs.h glob.h)
+AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
# For experimental utmp support (lastlog on some BSD-like systems)
AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h)
+# For quotas on Veritas VxFS filesystems
+AC_CHECK_HEADERS(sys/fs/vx_quota.h)
+
+# For quotas on Linux XFS filesystems
+AC_CHECK_HEADERS(linux/xqm.h)
+
AC_CHECK_SIZEOF(int,cross)
AC_CHECK_SIZEOF(long,cross)
AC_CHECK_SIZEOF(short,cross)
@@ -705,16 +519,20 @@ if test x$enable_cups != xno; then
AC_PATH_PROG(CUPS_CONFIG, cups-config)
if test "x$CUPS_CONFIG" != x; then
- AC_DEFINE(HAVE_CUPS,1,[Whether we have CUPS])
+ AC_DEFINE(HAVE_CUPS)
CFLAGS="$CFLAGS `$CUPS_CONFIG --cflags`"
LDFLAGS="$LDFLAGS `$CUPS_CONFIG --ldflags`"
- PRINT_LIBS="$PRINT_LIBS `$CUPS_CONFIG --libs`"
+ LIBS="$LIBS `$CUPS_CONFIG --libs`"
fi
fi
############################################
-# we need dlopen/dlclose/dlsym/dlerror for PAM, the password database plugins and the plugin loading code
-AC_SEARCH_LIBS(dlopen, [dl])
+# we need dlopen/dlclose/dlsym/dlerror for PAM, the password database plugins and the new VFS code
+AC_CHECK_FUNCS(dlopen)
+if test x"$ac_cv_func_dlopen" = x"no"; then
+ AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl";
+ AC_DEFINE(HAVE_DLOPEN)])
+fi
# dlopen/dlclose/dlsym/dlerror will be checked again later and defines will be set then
############################################
@@ -723,37 +541,19 @@ AC_CACHE_CHECK([for immediate structures],samba_cv_immediate_structures, [
AC_TRY_COMPILE([
#include <stdio.h>],
[
- typedef struct {unsigned x;} FOOBAR;
- #define X_FOOBAR(x) ((FOOBAR) { x })
- #define FOO_ONE X_FOOBAR(1)
- FOOBAR f = FOO_ONE;
- static struct {
- FOOBAR y;
+ typedef struct {unsigned x;} FOOBAR;
+#define X_FOOBAR(x) ((FOOBAR) { x })
+#define FOO_ONE X_FOOBAR(1)
+ FOOBAR f = FOO_ONE;
+ static struct {
+ FOOBAR y;
} f2[] = {
{FOO_ONE}
- };
+ };
],
samba_cv_immediate_structures=yes,samba_cv_immediate_structures=no)])
if test x"$samba_cv_immediate_structures" = x"yes"; then
- AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES,1,[Whether the compiler supports immediate structures])
-fi
-
-############################################
-# check if the compiler can do immediate structures
-AC_CACHE_CHECK([if the compiler will optimize out function calls],samba_cv_optimize_out_funcation_calls, [
- AC_TRY_LINK([
-#include <stdio.h>],
-[
- if (0) {
- this_function_does_not_exist();
- } else {
- return 1;
- }
-
-],
- samba_cv_optimize_out_funcation_calls=yes,samba_cv_optimize_out_funcation_calls=no)])
-if test x"$samba_cv_optimize_out_funcation_calls" = x"yes"; then
- AC_DEFINE(HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS,1,[Whether the compiler will optimize out function calls])
+ AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES)
fi
############################################
@@ -771,10 +571,9 @@ AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [
],
samba_cv_unixsocket=yes,samba_cv_unixsocket=no)])
if test x"$samba_cv_unixsocket" = x"yes"; then
- AC_DEFINE(HAVE_UNIXSOCKET,1,[If we need to build with unixscoket support])
+ AC_DEFINE(HAVE_UNIXSOCKET)
fi
-
AC_CACHE_CHECK([for socklen_t type],samba_cv_socklen_t, [
AC_TRY_COMPILE([
#include <sys/types.h>
@@ -783,9 +582,9 @@ AC_CACHE_CHECK([for socklen_t type],samba_cv_socklen_t, [
#include <stddef.h>
#endif
#include <sys/socket.h>],[socklen_t i = 0],
- samba_cv_socklen_t=yes,samba_cv_socklen_t=no)])
+ samba_cv_socklen_t=yes,samba_cv_socklen_t=no)])
if test x"$samba_cv_socklen_t" = x"yes"; then
- AC_DEFINE(HAVE_SOCKLEN_T_TYPE,1,[Whether we have the variable type socklen_t])
+ AC_DEFINE(HAVE_SOCKLEN_T_TYPE)
fi
AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [
@@ -798,7 +597,7 @@ AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [
#include <signal.h>],[sig_atomic_t i = 0],
samba_cv_sig_atomic_t=yes,samba_cv_sig_atomic_t=no)])
if test x"$samba_cv_sig_atomic_t" = x"yes"; then
- AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type])
+ AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE)
fi
# stupid headers have the functions but no declaration. grrrr.
@@ -817,7 +616,7 @@ AC_CACHE_CHECK([for real setresuid],samba_cv_have_setresuid,[
main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);}],
samba_cv_have_setresuid=yes,samba_cv_have_setresuid=no,samba_cv_have_setresuid=cross)])
if test x"$samba_cv_have_setresuid" = x"yes"; then
- AC_DEFINE(HAVE_SETRESUID,1,[Whether the system has setresuid])
+ AC_DEFINE(HAVE_SETRESUID)
fi
# Do the same check for setresguid...
@@ -828,7 +627,7 @@ AC_CACHE_CHECK([for real setresgid],samba_cv_have_setresgid,[
main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}],
samba_cv_have_setresgid=yes,samba_cv_have_setresgid=no,samba_cv_have_setresgid=cross)])
if test x"$samba_cv_have_setresgid" = x"yes"; then
- AC_DEFINE(HAVE_SETRESGID,1,[Whether the system has setresgid])
+ AC_DEFINE(HAVE_SETRESGID)
fi
AC_FUNC_MEMCMP
@@ -840,7 +639,7 @@ test "${with_readline+set}" != "set" && with_readline=yes
# test for where we get readline() from
AC_MSG_CHECKING(whether to use readline)
AC_ARG_WITH(readline,
-[ --with-readline[=DIR] Look for readline include/libs in DIR (default=auto) ],
+[ --with-readline[=DIR] Look for readline include/libs in DIR (default=auto)],
[ case "$with_readline" in
yes)
AC_MSG_RESULT(yes)
@@ -849,12 +648,12 @@ AC_ARG_WITH(readline,
AC_CHECK_HEADERS(readline/history.h)
AC_CHECK_HEADERS(readline.h readline/readline.h,[
- for termlib in ncurses curses termcap terminfo termlib tinfo; do
+ for termlib in ncurses curses termcap terminfo termlib; do
AC_CHECK_LIB(${termlib}, tgetent, [TERMLIBS="-l${termlib}"; break])
done
AC_CHECK_LIB(readline, rl_callback_handler_install,
[TERMLIBS="-lreadline $TERMLIBS"
- AC_DEFINE(HAVE_LIBREADLINE,1,[Whether the system has readline])
+ AC_DEFINE(HAVE_LIBREADLINE)
break], [TERMLIBS=], $TERMLIBS)])
;;
no)
@@ -884,7 +683,7 @@ AC_ARG_WITH(readline,
TERMCPPFLAGS="-I$with_readline/include"
CPPFLAGS="-I$with_readline/include $CPPFLAGS"
TERMLIBS="-lreadline $TERMLIBS"
- AC_DEFINE(HAVE_LIBREADLINE,1,[Whether the system has readline])
+ AC_DEFINE(HAVE_LIBREADLINE)
break], [TERMLIBS= CPPFLAGS=$_cppflags], $TERMLIBS)])
LDFLAGS=$_ldflags
@@ -895,15 +694,6 @@ AC_ARG_WITH(readline,
AC_SUBST(TERMLIBS)
AC_SUBST(TERMLDFLAGS)
-# The readline API changed slightly from readline3 to readline4, so
-# code will generate warnings on one of them unless we have a few
-# special cases.
-AC_CHECK_LIB(readline, rl_completion_matches,
- [AC_DEFINE(HAVE_NEW_LIBREADLINE, 1,
- [Do we have rl_completion_matches?])],
- [],
- [$TERMLIBS])
-
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
@@ -934,23 +724,28 @@ if test x"$ac_cv_func_connect" = x"no"; then
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
- AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()])
+ AC_DEFINE(HAVE_CONNECT)
fi
fi
###############################################
-# test for where we get yp_get_default_domain() from
-AC_SEARCH_LIBS(yp_get_default_domain, [nsl])
+# test for where we get get_yp_default_domain() from
AC_CHECK_FUNCS(yp_get_default_domain)
+if test x"$ac_cv_func_yp_get_default_domain" = x"no"; then
+ AC_CHECK_LIB(nsl, yp_get_default_domain, [LIBS="$LIBS -lnsl";
+ AC_DEFINE(HAVE_YP_GET_DEFAULT_DOMAIN)])
+fi
# Check if we have execl, if not we need to compile smbrun.
AC_CHECK_FUNCS(execl)
if test x"$ac_cv_func_execl" = x"no"; then
- EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/smbrun\$(EXEEXT)"
+ RUNPROG="bin/smbrun\$(EXEEXT)"
+else
+ RUNPROG=""
fi
-AC_CHECK_FUNCS(dlopen dlclose dlsym dlerror waitpid getcwd strdup strndup strnlen strtoul strerror chown fchown chmod fchmod chroot link mknod mknod64)
-AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset strlcpy strlcat setpgid)
+AC_CHECK_FUNCS(dlopen dlclose dlsym dlerror waitpid getcwd strdup strndup strnlen strtoul strerror chown fchown chmod fchmod chroot link)
+AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset strlcpy strlcat setpgid mknod mknod64)
AC_CHECK_FUNCS(memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid)
AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent)
AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf realpath)
@@ -958,12 +753,7 @@ AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate
AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf)
AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink)
-AC_CHECK_FUNCS(syslog vsyslog timegm)
-AC_CHECK_FUNCS(setlocale nl_langinfo)
-# setbuffer, shmget, shm_open are needed for smbtorture
-AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols)
-AC_CHECK_HEADERS(libexc.h)
-AC_CHECK_LIB(exc, trace_back_stack)
+AC_CHECK_FUNCS(syslog vsyslog)
# syscall() is needed for smbwrapper.
AC_CHECK_FUNCS(syscall)
@@ -976,7 +766,7 @@ AC_CHECK_FUNCS(_stat _lstat _fstat __stat __lstat __fstat)
AC_CHECK_FUNCS(_acl __acl _facl __facl _open __open _chdir __chdir)
AC_CHECK_FUNCS(_close __close _fchdir __fchdir _fcntl __fcntl)
AC_CHECK_FUNCS(getdents _getdents __getdents _lseek __lseek _read __read)
-AC_CHECK_FUNCS(getdirentries _write __write _fork __fork)
+AC_CHECK_FUNCS(_write __write _fork __fork)
AC_CHECK_FUNCS(_stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64)
AC_CHECK_FUNCS(__sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64)
AC_CHECK_FUNCS(pread _pread __pread pread64 _pread64 __pread64)
@@ -984,38 +774,6 @@ AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64)
AC_CHECK_FUNCS(open64 _open64 __open64 creat64)
#
-#
-#
-case "$host_os" in
- *linux*)
- # glibc <= 2.3.2 has a broken getgrouplist
- AC_TRY_RUN([
-#include <unistd.h>
-#include <sys/utsname.h>
-main() {
- /* glibc up to 2.3 has a broken getgrouplist */
-#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
- int libc_major = __GLIBC__;
- int libc_minor = __GLIBC_MINOR__;
-
- if (libc_major < 2)
- exit(1);
- if ((libc_major == 2) && (libc_minor <= 3))
- exit(1);
-#endif
- exit(0);
-}
-], [linux_getgrouplist_ok=yes], [linux_getgrouplist_ok=no])
- if test x"$linux_getgrouplist_ok" = x"yes"; then
- AC_DEFINE(HAVE_GETGROUPLIST, 1, [Have good getgrouplist])
- fi
- ;;
- *)
- AC_CHECK_FUNCS(getgrouplist)
- ;;
-esac
-
-#
# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
#
@@ -1029,7 +787,7 @@ if test x$ac_cv_func_stat64 = xno ; then
], [struct stat64 st64; exit(stat64(".",&st64));], [ac_cv_func_stat64=yes])
AC_MSG_RESULT([$ac_cv_func_stat64])
if test x$ac_cv_func_stat64 = xyes ; then
- AC_DEFINE(HAVE_STAT64,1,[Whether stat64() is available])
+ AC_DEFINE(HAVE_STAT64)
fi
fi
@@ -1043,7 +801,7 @@ if test x$ac_cv_func_lstat64 = xno ; then
], [struct stat64 st64; exit(lstat64(".",&st64));], [ac_cv_func_lstat64=yes])
AC_MSG_RESULT([$ac_cv_func_lstat64])
if test x$ac_cv_func_lstat64 = xyes ; then
- AC_DEFINE(HAVE_LSTAT64,[Whether lstat64() is available])
+ AC_DEFINE(HAVE_LSTAT64)
fi
fi
@@ -1057,13 +815,20 @@ if test x$ac_cv_func_fstat64 = xno ; then
], [struct stat64 st64; exit(fstat64(0,&st64));], [ac_cv_func_fstat64=yes])
AC_MSG_RESULT([$ac_cv_func_fstat64])
if test x$ac_cv_func_fstat64 = xyes ; then
- AC_DEFINE(HAVE_FSTAT64,1,[Whether fstat64() is available])
+ AC_DEFINE(HAVE_FSTAT64)
fi
fi
-#####################################
-# we might need the resolv library on some systems
-AC_CHECK_LIB(resolv, dn_expand)
+#
+# If no strcasecmp, check for it in some known places
+# It is in -lresolv on ReliantUNIX and UnixWare
+# -lresolve *must* follow -lnsl for name resolution to work properly
+#
+
+if test x$ac_cv_func_strcasecmp = xno ; then
+ AC_CHECK_LIB(resolv,strcasecmp,[LIBS="$LIBS -lresolv"]
+ AC_DEFINE(HAVE_STRCASECMP))
+fi
#
# Check for the functions putprpwnam, set_auth_parameters,
@@ -1089,116 +854,106 @@ AC_LIBTESTFUNC(sec, bigcrypt)
AC_LIBTESTFUNC(security, getprpwnam)
AC_LIBTESTFUNC(sec, getprpwnam)
-############################################
-# Check if we have libattr
-AC_SEARCH_LIBS(getxattr, [attr])
-AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
-AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
-AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
-AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
-AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
-
-# Assume non-shared by default and override below
-BLDSHARED="false"
+# this bit needs to be modified for each OS that is suported by
+# smbwrapper. You need to specify how to created a shared library and
+# how to compile C code to produce PIC object files
# these are the defaults, good for lots of systems
HOST_OS="$host_os"
LDSHFLAGS="-shared"
SONAMEFLAG="#"
-SHLD="\${CC} \${CFLAGS}"
-PICFLAGS=""
-PICSUFFIX="po"
+SHLD="\${CC}"
+PICFLAG=""
+PICSUFFIX="po.o"
SHLIBEXT="so"
+# Assume non-shared by default and override below
+BLDSHARED="false"
+AC_MSG_CHECKING([ability to build shared libraries])
-if test "$enable_shared" = "yes"; then
- # this bit needs to be modified for each OS that is suported by
- # smbwrapper. You need to specify how to created a shared library and
- # how to compile C code to produce PIC object files
-
- AC_MSG_CHECKING([ability to build shared libraries])
-
- # and these are for particular systems
- case "$host_os" in
- *linux*) AC_DEFINE(LINUX,1,[Whether the host os is linux])
+# and these are for particular systems
+case "$host_os" in
+ *linux*) AC_DEFINE(LINUX)
BLDSHARED="true"
- LDSHFLAGS="-shared"
+ LDSHFLAGS="-shared"
DYNEXP="-Wl,--export-dynamic"
- PICFLAGS="-fPIC"
+ PICFLAG="-fPIC"
SONAMEFLAG="-Wl,-soname="
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
- *solaris*) AC_DEFINE(SUNOS5,1,[Whether the host os is solaris])
+ *solaris*) AC_DEFINE(SUNOS5)
BLDSHARED="true"
LDSHFLAGS="-G"
SONAMEFLAG="-h "
if test "${GCC}" = "yes"; then
- PICFLAGS="-fPIC"
+ PICFLAG="-fPIC"
if test "${ac_cv_prog_gnu_ld}" = "yes"; then
DYNEXP="-Wl,-E"
fi
else
- PICFLAGS="-KPIC"
+ PICFLAG="-KPIC"
## ${CFLAGS} added for building 64-bit shared
## libs using Sun's Compiler
LDSHFLAGS="-G \${CFLAGS}"
+ POBAD_CC=""
PICSUFFIX="po.o"
fi
- AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
- AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
- ;;
- *sunos*) AC_DEFINE(SUNOS4,1,[Whether the host os is sunos4])
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ AC_DEFINE(BROKEN_GETGRNAM)
+ ;;
+ *sunos*) AC_DEFINE(SUNOS4)
BLDSHARED="true"
LDSHFLAGS="-G"
SONAMEFLAG="-Wl,-h,"
- PICFLAGS="-KPIC" # Is this correct for SunOS
+ PICFLAG="-KPIC" # Is this correct for SunOS
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
- AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
- ;;
- *netbsd* | *freebsd*) BLDSHARED="true"
+ AC_DEFINE(BROKEN_GETGRNAM)
+ ;;
+ *freebsd*) BLDSHARED="true"
LDSHFLAGS="-shared"
DYNEXP="-Wl,--export-dynamic"
SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC -DPIC"
- AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
- AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
- ;;
+ PICFLAG="-fPIC -DPIC"
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ AC_DEFINE(BROKEN_GETGRNAM)
+ ;;
*openbsd*) BLDSHARED="true"
LDSHFLAGS="-shared"
DYNEXP="-Wl,-Bdynamic"
SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC"
- AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
- AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
- ;;
- *irix*) AC_DEFINE(IRIX,1,[Whether the host os is irix])
+ PICFLAG="-fPIC"
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ AC_DEFINE(BROKEN_GETGRNAM)
+ ;;
+ *irix*) AC_DEFINE(IRIX)
case "$host_os" in
- *irix6*) AC_DEFINE(IRIX6,1,[Whether the host os is irix6])
+ *irix6*) AC_DEFINE(IRIX6)
;;
esac
+ ATTEMPT_WRAP32_BUILD=yes
BLDSHARED="true"
LDSHFLAGS="-set_version sgi1.0 -shared"
SONAMEFLAG="-soname "
- SHLD="\${LD}"
+ SHLD="\${LD}"
if test "${GCC}" = "yes"; then
- PICFLAGS="-fPIC"
+ PICFLAG="-fPIC"
else
- PICFLAGS="-KPIC"
+ PICFLAG="-KPIC"
fi
- AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block])
- ;;
- *aix*) AC_DEFINE(AIX,1,[Whether the host os is aix])
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ ;;
+ *aix*) AC_DEFINE(AIX)
BLDSHARED="true"
- LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok"
+ LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry"
DYNEXP="-Wl,-brtl,-bexpall"
- PICFLAGS="-O2"
+ PICFLAG="-O2"
if test "${GCC}" != "yes"; then
## for funky AIX compiler using strncpy()
CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000"
fi
- AC_DEFINE(STAT_ST_BLOCKSIZE,DEV_BSIZE,[The size of a block])
- ;;
- *hpux*) AC_DEFINE(HPUX,1,[Whether the host os is HPUX])
+ AC_DEFINE(STAT_ST_BLOCKSIZE,DEV_BSIZE)
+ ;;
+ *hpux*) AC_DEFINE(HPUX)
SHLIBEXT="sl"
# Use special PIC flags for the native HP-UX compiler.
if test $ac_cv_prog_cc_Ae = yes; then
@@ -1206,57 +961,54 @@ if test "$enable_shared" = "yes"; then
SHLD="/usr/bin/ld"
LDSHFLAGS="-B symbolic -b -z"
SONAMEFLAG="+h "
- PICFLAGS="+z"
- elif test "${GCC}" = "yes"; then
- PICFLAGS="-fPIC"
+ PICFLAG="+z"
fi
DYNEXP="-Wl,-E"
- AC_DEFINE(STAT_ST_BLOCKSIZE,8192,[The size of a block])
- AC_DEFINE(POSIX_ACL_NEEDS_MASK,1,[Does a POSIX ACL need a mask element])
+ AC_DEFINE(STAT_ST_BLOCKSIZE,8192)
+ AC_DEFINE(POSIX_ACL_NEEDS_MASK)
;;
- *qnx*) AC_DEFINE(QNX,1,[Whether the host os is qnx])
+ *qnx*) AC_DEFINE(QNX)
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
- *osf*) AC_DEFINE(OSF1,1,[Whether the host os is osf1])
+ *osf*) AC_DEFINE(OSF1)
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-fPIC"
+ PICFLAG="-fPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
- AC_DEFINE(BROKEN_GETGRNAM,1,[Does getgrnam work correctly])
- ;;
- *sco*) AC_DEFINE(SCO,1,[Whether the host os is sco unix])
+ AC_DEFINE(BROKEN_GETGRNAM)
+ ;;
+ *sco*) AC_DEFINE(SCO)
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
- *unixware*) AC_DEFINE(UNIXWARE,1,[Whether the host os is unixware])
+ *unixware*) AC_DEFINE(UNIXWARE)
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
- PICFLAGS="-KPIC"
+ PICFLAG="-KPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
- ;;
- *next2*) AC_DEFINE(NEXT2,1,[Whether the host os is NeXT v2])
+ ;;
+ *next2*) AC_DEFINE(NEXT2)
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man])
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
- *sysv4*) AC_DEFINE(SYSV,1,[Whether this is a system V system])
+ *sysv4*)
case "$host" in
*-univel-*) if [ test "$GCC" != yes ]; then
- AC_DEFINE(HAVE_MEMSET,1,[Whether memset() is available])
- fi
- LDSHFLAGS="-G"
- DYNEXP="-Bexport"
+ AC_DEFINE(HAVE_MEMSET)
+ fi
+ LDSHFLAGS="-G"
+ DYNEXP="-Bexport"
;;
- *mips-sni-sysv4*) AC_DEFINE(RELIANTUNIX,1,[Whether the host os is reliantunix]);;
+ *mips-sni-sysv4*) AC_DEFINE(RELIANTUNIX);;
esac
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
-
- *sysv5*) AC_DEFINE(SYSV,1,[Whether this is a system V system])
+ *sysv5*)
if [ test "$GCC" != yes ]; then
- AC_DEFINE(HAVE_MEMSET,1,[Whether memset() is available])
+ AC_DEFINE(HAVE_MEMSET)
fi
LDSHFLAGS="-G"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
@@ -1265,43 +1017,35 @@ if test "$enable_shared" = "yes"; then
BLDSHARED="false"
LDSHFLAGS=""
;;
-
- *darwin*) AC_DEFINE(DARWINOS,1,[Whether the host os is Darwin/MacOSX])
- BLDSHARED="true"
- LDSHFLAGS="-bundle -flat_namespace -undefined suppress"
- SHLIBEXT="dylib"
- AC_DEFINE(STAT_ST_BLOCKSIZE,512)
- ;;
-
*)
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
- esac
- AC_SUBST(DYNEXP)
- AC_MSG_RESULT($BLDSHARED)
- AC_MSG_CHECKING([linker flags for shared libraries])
- AC_MSG_RESULT([$LDSHFLAGS])
- AC_MSG_CHECKING([compiler flags for position-independent code])
- AC_MSG_RESULT([$PICFLAGS])
+esac
+AC_SUBST(DYNEXP)
+AC_MSG_RESULT($BLDSHARED)
+AC_MSG_CHECKING([linker flags for shared libraries])
+AC_MSG_RESULT([$LDSHFLAGS])
+AC_MSG_CHECKING([compiler flags for position-independent code])
+AC_MSG_RESULT([$PICFLAGS])
+
+# try to work out how to produce pic code with this compiler
+if test x$PICFLAG = x; then
+ AC_PROG_CC_FLAG(fpic)
+ if test $ac_cv_prog_cc_fpic = yes; then
+ PICFLAG="-fpic";
+ fi
fi
-
-#######################################################
-# test whether building a shared library actually works
-if test $BLDSHARED = true; then
-AC_CACHE_CHECK([whether building shared libraries actually works],
- [ac_cv_shlib_works],[
- ac_cv_shlib_works=no
- # try building a trivial shared library
- $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o \
- shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c && \
- $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" \
- shlib.$PICSUFFIX && \
- ac_cv_shlib_works=yes
- rm -f "shlib.$SHLIBEXT" shlib.$PICSUFFIX
-])
-if test $ac_cv_shlib_works = no; then
- BLDSHARED=false
+if test x$PICFLAG = x; then
+ AC_PROG_CC_FLAG(KPIC)
+ if test $ac_cv_prog_cc_KPIC = yes; then
+ PICFLAG="-KPIC";
+ fi
fi
+if test x$PICFLAG = x; then
+ AC_PROG_CC_FLAG(Kpic)
+ if test $ac_cv_prog_cc_Kpic = yes; then
+ PICFLAG="-Kpic";
+ fi
fi
################
@@ -1311,7 +1055,7 @@ AC_TRY_RUN([#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
samba_cv_have_longlong=yes,samba_cv_have_longlong=no,samba_cv_have_longlong=cross)])
if test x"$samba_cv_have_longlong" = x"yes"; then
- AC_DEFINE(HAVE_LONGLONG,1,[Whether the host supports long long's])
+ AC_DEFINE(HAVE_LONGLONG)
fi
#
@@ -1322,7 +1066,7 @@ AC_CACHE_CHECK([for LL suffix on long long integers],samba_cv_compiler_supports_
AC_TRY_COMPILE([#include <stdio.h>],[long long i = 0x8000000000LL],
samba_cv_compiler_supports_ll=yes,samba_cv_compiler_supports_ll=no)])
if test x"$samba_cv_compiler_supports_ll" = x"yes"; then
- AC_DEFINE(COMPILER_SUPPORTS_LL,1,[Whether the compiler supports the LL prefix on long long integers])
+ AC_DEFINE(COMPILER_SUPPORTS_LL)
fi
@@ -1332,7 +1076,7 @@ AC_TRY_RUN([#include <stdio.h>
main() { exit((sizeof(off_t) == 8) ? 0 : 1); }],
samba_cv_SIZEOF_OFF_T=yes,samba_cv_SIZEOF_OFF_T=no,samba_cv_SIZEOF_OFF_T=cross)])
if test x"$samba_cv_SIZEOF_OFF_T" = x"yes"; then
- AC_DEFINE(SIZEOF_OFF_T,8,[The size of the 'off_t' type])
+ AC_DEFINE(SIZEOF_OFF_T,8)
fi
AC_CACHE_CHECK([for off64_t],samba_cv_HAVE_OFF64_T,[
@@ -1345,7 +1089,7 @@ AC_TRY_RUN([
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
samba_cv_HAVE_OFF64_T=yes,samba_cv_HAVE_OFF64_T=no,samba_cv_HAVE_OFF64_T=cross)])
if test x"$samba_cv_HAVE_OFF64_T" = x"yes"; then
- AC_DEFINE(HAVE_OFF64_T,1,[Whether off64_t is available])
+ AC_DEFINE(HAVE_OFF64_T)
fi
AC_CACHE_CHECK([for 64 bit ino_t],samba_cv_SIZEOF_INO_T,[
@@ -1354,7 +1098,7 @@ AC_TRY_RUN([#include <stdio.h>
main() { exit((sizeof(ino_t) == 8) ? 0 : 1); }],
samba_cv_SIZEOF_INO_T=yes,samba_cv_SIZEOF_INO_T=no,samba_cv_SIZEOF_INO_T=cross)])
if test x"$samba_cv_SIZEOF_INO_T" = x"yes"; then
- AC_DEFINE(SIZEOF_INO_T,8,[The size of the 'ino_t' type])
+ AC_DEFINE(SIZEOF_INO_T,8)
fi
AC_CACHE_CHECK([for ino64_t],samba_cv_HAVE_INO64_T,[
@@ -1367,7 +1111,7 @@ AC_TRY_RUN([
main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
samba_cv_HAVE_INO64_T=yes,samba_cv_HAVE_INO64_T=no,samba_cv_HAVE_INO64_T=cross)])
if test x"$samba_cv_HAVE_INO64_T" = x"yes"; then
- AC_DEFINE(HAVE_INO64_T,1,[Whether the 'ino64_t' type is available])
+ AC_DEFINE(HAVE_INO64_T)
fi
AC_CACHE_CHECK([for dev64_t],samba_cv_HAVE_DEV64_T,[
@@ -1380,7 +1124,7 @@ AC_TRY_RUN([
main() { struct stat64 st; dev64_t s; if (sizeof(dev_t) == sizeof(dev64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
samba_cv_HAVE_DEV64_T=yes,samba_cv_HAVE_DEV64_T=no,samba_cv_HAVE_DEV64_T=cross)])
if test x"$samba_cv_HAVE_DEV64_T" = x"yes"; then
- AC_DEFINE(HAVE_DEV64_T,1,[Whether the 'dev64_t' type is available])
+ AC_DEFINE(HAVE_DEV64_T)
fi
AC_CACHE_CHECK([for struct dirent64],samba_cv_HAVE_STRUCT_DIRENT64,[
@@ -1393,7 +1137,7 @@ AC_TRY_COMPILE([
[struct dirent64 de;],
samba_cv_HAVE_STRUCT_DIRENT64=yes,samba_cv_HAVE_STRUCT_DIRENT64=no)])
if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes" && test x"$ac_cv_func_readdir64" = x"yes"; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64,1,[Whether the 'dirent64' struct is available])
+ AC_DEFINE(HAVE_STRUCT_DIRENT64)
fi
AC_CACHE_CHECK([for major macro],samba_cv_HAVE_DEVICE_MAJOR_FN,[
@@ -1405,7 +1149,7 @@ AC_TRY_RUN([
main() { dev_t dev; int i = major(dev); return 0; }],
samba_cv_HAVE_DEVICE_MAJOR_FN=yes,samba_cv_HAVE_DEVICE_MAJOR_FN=no,samba_cv_HAVE_DEVICE_MAJOR_FN=cross)])
if test x"$samba_cv_HAVE_DEVICE_MAJOR_FN" = x"yes"; then
- AC_DEFINE(HAVE_DEVICE_MAJOR_FN,1,[Whether the major macro for dev_t is available])
+ AC_DEFINE(HAVE_DEVICE_MAJOR_FN)
fi
AC_CACHE_CHECK([for minor macro],samba_cv_HAVE_DEVICE_MINOR_FN,[
@@ -1417,7 +1161,19 @@ AC_TRY_RUN([
main() { dev_t dev; int i = minor(dev); return 0; }],
samba_cv_HAVE_DEVICE_MINOR_FN=yes,samba_cv_HAVE_DEVICE_MINOR_FN=no,samba_cv_HAVE_DEVICE_MINOR_FN=cross)])
if test x"$samba_cv_HAVE_DEVICE_MINOR_FN" = x"yes"; then
- AC_DEFINE(HAVE_DEVICE_MINOR_FN,1,[Whether the minor macro for dev_t is available])
+ AC_DEFINE(HAVE_DEVICE_MINOR_FN)
+fi
+
+AC_CACHE_CHECK([for makedev macro],samba_cv_HAVE_MAKEDEV_FN,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev = makedev(1,2); return 0; }],
+samba_cv_HAVE_MAKEDEV_FN=yes,samba_cv_HAVE_MAKEDEV_FN=no,samba_cv_HAVE_MAKEDEV_FN=cross)])
+if test x"$samba_cv_HAVE_MAKEDEV_FN" = x"yes"; then
+ AC_DEFINE(MAKEDEV_FN)
fi
AC_CACHE_CHECK([for unsigned char],samba_cv_HAVE_UNSIGNED_CHAR,[
@@ -1425,7 +1181,7 @@ AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
samba_cv_HAVE_UNSIGNED_CHAR=yes,samba_cv_HAVE_UNSIGNED_CHAR=no,samba_cv_HAVE_UNSIGNED_CHAR=cross)])
if test x"$samba_cv_HAVE_UNSIGNED_CHAR" = x"yes"; then
- AC_DEFINE(HAVE_UNSIGNED_CHAR,1,[Whether the 'unsigned char' type is available])
+ AC_DEFINE(HAVE_UNSIGNED_CHAR)
fi
AC_CACHE_CHECK([for sin_len in sock],samba_cv_HAVE_SOCK_SIN_LEN,[
@@ -1435,7 +1191,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct sockaddr_in sock; sock.sin_len = sizeof(sock);],
samba_cv_HAVE_SOCK_SIN_LEN=yes,samba_cv_HAVE_SOCK_SIN_LEN=no)])
if test x"$samba_cv_HAVE_SOCK_SIN_LEN" = x"yes"; then
- AC_DEFINE(HAVE_SOCK_SIN_LEN,1,[Whether the sockaddr_in struct has a sin_len property])
+ AC_DEFINE(HAVE_SOCK_SIN_LEN)
fi
AC_CACHE_CHECK([whether seekdir returns void],samba_cv_SEEKDIR_RETURNS_VOID,[
@@ -1444,14 +1200,21 @@ AC_TRY_COMPILE([#include <sys/types.h>
void seekdir(DIR *d, long loc) { return; }],[return 0;],
samba_cv_SEEKDIR_RETURNS_VOID=yes,samba_cv_SEEKDIR_RETURNS_VOID=no)])
if test x"$samba_cv_SEEKDIR_RETURNS_VOID" = x"yes"; then
- AC_DEFINE(SEEKDIR_RETURNS_VOID,1,[Whether seekdir returns void])
+ AC_DEFINE(SEEKDIR_RETURNS_VOID)
+fi
+
+AC_CACHE_CHECK([for __FILE__ macro],samba_cv_HAVE_FILE_MACRO,[
+AC_TRY_COMPILE([#include <stdio.h>], [printf("%s\n", __FILE__);],
+samba_cv_HAVE_FILE_MACRO=yes,samba_cv_HAVE_FILE_MACRO=no)])
+if test x"$samba_cv_HAVE_FILE_MACRO" = x"yes"; then
+ AC_DEFINE(HAVE_FILE_MACRO)
fi
AC_CACHE_CHECK([for __FUNCTION__ macro],samba_cv_HAVE_FUNCTION_MACRO,[
AC_TRY_COMPILE([#include <stdio.h>], [printf("%s\n", __FUNCTION__);],
samba_cv_HAVE_FUNCTION_MACRO=yes,samba_cv_HAVE_FUNCTION_MACRO=no)])
if test x"$samba_cv_HAVE_FUNCTION_MACRO" = x"yes"; then
- AC_DEFINE(HAVE_FUNCTION_MACRO,1,[Whether there is a __FUNCTION__ macro])
+ AC_DEFINE(HAVE_FUNCTION_MACRO)
fi
AC_CACHE_CHECK([if gettimeofday takes tz argument],samba_cv_HAVE_GETTIMEOFDAY_TZ,[
@@ -1461,55 +1224,45 @@ AC_TRY_RUN([
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
samba_cv_HAVE_GETTIMEOFDAY_TZ=yes,samba_cv_HAVE_GETTIMEOFDAY_TZ=no,samba_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
- AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday() is available])
+ AC_DEFINE(HAVE_GETTIMEOFDAY_TZ)
fi
-AC_CACHE_CHECK([for va_copy],samba_cv_HAVE_VA_COPY,[
+AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE_VA_COPY,[
AC_TRY_LINK([#include <stdarg.h>
-va_list ap1,ap2;], [va_copy(ap1,ap2);],
-samba_cv_HAVE_VA_COPY=yes,
-samba_cv_HAVE_VA_COPY=no)])
+va_list ap1,ap2;], [__va_copy(ap1,ap2);],
+samba_cv_HAVE_VA_COPY=yes,samba_cv_HAVE_VA_COPY=no)])
if test x"$samba_cv_HAVE_VA_COPY" = x"yes"; then
- AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
-else
- AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE___VA_COPY,[
- AC_TRY_LINK([#include <stdarg.h>
- va_list ap1,ap2;], [__va_copy(ap1,ap2);],
- samba_cv_HAVE___VA_COPY=yes,
- samba_cv_HAVE___VA_COPY=no)])
- if test x"$samba_cv_HAVE___VA_COPY" = x"yes"; then
- AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available])
- fi
+ AC_DEFINE(HAVE_VA_COPY)
fi
AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[
AC_TRY_RUN([
#include <sys/types.h>
#include <stdarg.h>
-void foo(const char *format, ...) {
- va_list ap;
- int len;
- char buf[5];
+void foo(const char *format, ...) {
+ va_list ap;
+ int len;
+ char buf[5];
- va_start(ap, format);
- len = vsnprintf(buf, 0, format, ap);
- va_end(ap);
- if (len != 5) exit(1);
+ va_start(ap, format);
+ len = vsnprintf(buf, 0, format, ap);
+ va_end(ap);
+ if (len != 5) exit(1);
- va_start(ap, format);
- len = vsnprintf(0, 0, format, ap);
- va_end(ap);
- if (len != 5) exit(1);
+ va_start(ap, format);
+ len = vsnprintf(0, 0, format, ap);
+ va_end(ap);
+ if (len != 5) exit(1);
- if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
+ if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
- exit(0);
+ exit(0);
}
main() { foo("hello"); }
],
samba_cv_HAVE_C99_VSNPRINTF=yes,samba_cv_HAVE_C99_VSNPRINTF=no,samba_cv_HAVE_C99_VSNPRINTF=cross)])
if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
- AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf])
+ AC_DEFINE(HAVE_C99_VSNPRINTF)
fi
AC_CACHE_CHECK([for broken readdir],samba_cv_HAVE_BROKEN_READDIR,[
@@ -1520,7 +1273,7 @@ if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
di->d_name[0] == 0) exit(0); exit(1);} ],
samba_cv_HAVE_BROKEN_READDIR=yes,samba_cv_HAVE_BROKEN_READDIR=no,samba_cv_HAVE_BROKEN_READDIR=cross)])
if test x"$samba_cv_HAVE_BROKEN_READDIR" = x"yes"; then
- AC_DEFINE(HAVE_BROKEN_READDIR,1,[Whether readdir() is broken])
+ AC_DEFINE(HAVE_BROKEN_READDIR)
fi
AC_CACHE_CHECK([for utimbuf],samba_cv_HAVE_UTIMBUF,[
@@ -1529,12 +1282,9 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));],
samba_cv_HAVE_UTIMBUF=yes,samba_cv_HAVE_UTIMBUF=no,samba_cv_HAVE_UTIMBUF=cross)])
if test x"$samba_cv_HAVE_UTIMBUF" = x"yes"; then
- AC_DEFINE(HAVE_UTIMBUF,1,[Whether struct utimbuf is available])
+ AC_DEFINE(HAVE_UTIMBUF)
fi
-##############
-# Check utmp details, but only if our OS offers utmp.h
-if test x"$ac_cv_header_utmp_h" = x"yes"; then
dnl utmp and utmpx come in many flavours
dnl We need to check for many of them
dnl But we don't need to do each and every one, because our code uses
@@ -1548,7 +1298,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_name[0] = 'a';],
samba_cv_HAVE_UT_UT_NAME=yes,samba_cv_HAVE_UT_UT_NAME=no,samba_cv_HAVE_UT_UT_NAME=cross)])
if test x"$samba_cv_HAVE_UT_UT_NAME" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_NAME,1,[Whether the utmp struct has a property ut_name])
+ AC_DEFINE(HAVE_UT_UT_NAME)
fi
AC_CACHE_CHECK([for ut_user in utmp],samba_cv_HAVE_UT_UT_USER,[
@@ -1557,7 +1307,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_user[0] = 'a';],
samba_cv_HAVE_UT_UT_USER=yes,samba_cv_HAVE_UT_UT_USER=no,samba_cv_HAVE_UT_UT_USER=cross)])
if test x"$samba_cv_HAVE_UT_UT_USER" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_USER,1,[Whether the utmp struct has a property ut_user])
+ AC_DEFINE(HAVE_UT_UT_USER)
fi
AC_CACHE_CHECK([for ut_id in utmp],samba_cv_HAVE_UT_UT_ID,[
@@ -1566,7 +1316,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_id[0] = 'a';],
samba_cv_HAVE_UT_UT_ID=yes,samba_cv_HAVE_UT_UT_ID=no,samba_cv_HAVE_UT_UT_ID=cross)])
if test x"$samba_cv_HAVE_UT_UT_ID" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_ID,1,[Whether the utmp struct has a property ut_id])
+ AC_DEFINE(HAVE_UT_UT_ID)
fi
AC_CACHE_CHECK([for ut_host in utmp],samba_cv_HAVE_UT_UT_HOST,[
@@ -1575,7 +1325,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_host[0] = 'a';],
samba_cv_HAVE_UT_UT_HOST=yes,samba_cv_HAVE_UT_UT_HOST=no,samba_cv_HAVE_UT_UT_HOST=cross)])
if test x"$samba_cv_HAVE_UT_UT_HOST" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_HOST,1,[Whether the utmp struct has a property ut_host])
+ AC_DEFINE(HAVE_UT_UT_HOST)
fi
AC_CACHE_CHECK([for ut_time in utmp],samba_cv_HAVE_UT_UT_TIME,[
@@ -1584,7 +1334,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; time_t t; ut.ut_time = t;],
samba_cv_HAVE_UT_UT_TIME=yes,samba_cv_HAVE_UT_UT_TIME=no,samba_cv_HAVE_UT_UT_TIME=cross)])
if test x"$samba_cv_HAVE_UT_UT_TIME" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_TIME,1,[Whether the utmp struct has a property ut_time])
+ AC_DEFINE(HAVE_UT_UT_TIME)
fi
AC_CACHE_CHECK([for ut_tv in utmp],samba_cv_HAVE_UT_UT_TV,[
@@ -1593,7 +1343,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; struct timeval tv; ut.ut_tv = tv;],
samba_cv_HAVE_UT_UT_TV=yes,samba_cv_HAVE_UT_UT_TV=no,samba_cv_HAVE_UT_UT_TV=cross)])
if test x"$samba_cv_HAVE_UT_UT_TV" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_TV,1,[Whether the utmp struct has a property ut_tv])
+ AC_DEFINE(HAVE_UT_UT_TV)
fi
AC_CACHE_CHECK([for ut_type in utmp],samba_cv_HAVE_UT_UT_TYPE,[
@@ -1602,7 +1352,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_type = 0;],
samba_cv_HAVE_UT_UT_TYPE=yes,samba_cv_HAVE_UT_UT_TYPE=no,samba_cv_HAVE_UT_UT_TYPE=cross)])
if test x"$samba_cv_HAVE_UT_UT_TYPE" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_TYPE,1,[Whether the utmp struct has a property ut_type])
+ AC_DEFINE(HAVE_UT_UT_TYPE)
fi
AC_CACHE_CHECK([for ut_pid in utmp],samba_cv_HAVE_UT_UT_PID,[
@@ -1611,7 +1361,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_pid = 0;],
samba_cv_HAVE_UT_UT_PID=yes,samba_cv_HAVE_UT_UT_PID=no,samba_cv_HAVE_UT_UT_PID=cross)])
if test x"$samba_cv_HAVE_UT_UT_PID" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_PID,1,[Whether the utmp struct has a property ut_pid])
+ AC_DEFINE(HAVE_UT_UT_PID)
fi
AC_CACHE_CHECK([for ut_exit in utmp],samba_cv_HAVE_UT_UT_EXIT,[
@@ -1620,7 +1370,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_exit.e_exit = 0;],
samba_cv_HAVE_UT_UT_EXIT=yes,samba_cv_HAVE_UT_UT_EXIT=no,samba_cv_HAVE_UT_UT_EXIT=cross)])
if test x"$samba_cv_HAVE_UT_UT_EXIT" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_EXIT,1,[Whether the utmp struct has a property ut_exit])
+ AC_DEFINE(HAVE_UT_UT_EXIT)
fi
AC_CACHE_CHECK([for ut_addr in utmp],samba_cv_HAVE_UT_UT_ADDR,[
@@ -1629,7 +1379,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmp ut; ut.ut_addr = 0;],
samba_cv_HAVE_UT_UT_ADDR=yes,samba_cv_HAVE_UT_UT_ADDR=no,samba_cv_HAVE_UT_UT_ADDR=cross)])
if test x"$samba_cv_HAVE_UT_UT_ADDR" = x"yes"; then
- AC_DEFINE(HAVE_UT_UT_ADDR,1,[Whether the utmp struct has a property ut_addr])
+ AC_DEFINE(HAVE_UT_UT_ADDR)
fi
if test x$ac_cv_func_pututline = xyes ; then
@@ -1639,7 +1389,7 @@ if test x$ac_cv_func_pututline = xyes ; then
[struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);],
samba_cv_PUTUTLINE_RETURNS_UTMP=yes,samba_cv_PUTUTLINE_RETURNS_UTMP=no)])
if test x"$samba_cv_PUTUTLINE_RETURNS_UTMP" = x"yes"; then
- AC_DEFINE(PUTUTLINE_RETURNS_UTMP,1,[Whether pututline returns pointer])
+ AC_DEFINE(PUTUTLINE_RETURNS_UTMP)
fi
fi
@@ -1649,158 +1399,9 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct utmpx ux; ux.ut_syslen = 0;],
samba_cv_HAVE_UX_UT_SYSLEN=yes,samba_cv_HAVE_UX_UT_SYSLEN=no,samba_cv_HAVE_UX_UT_SYSLEN=cross)])
if test x"$samba_cv_HAVE_UX_UT_SYSLEN" = x"yes"; then
- AC_DEFINE(HAVE_UX_UT_SYSLEN,1,[Whether the utmpx struct has a property ut_syslen])
+ AC_DEFINE(HAVE_UX_UT_SYSLEN)
fi
-fi
-# end utmp details
-
-
-ICONV_LOCATION=standard
-LOOK_DIRS="/usr /usr/local /sw /opt"
-AC_ARG_WITH(libiconv,
-[ --with-libiconv=BASEDIR Use libiconv in BASEDIR/lib and BASEDIR/include (default=auto) ],
-[
- if test "$withval" = "no" ; then
- AC_MSG_ERROR([argument to --with-libiconv must be a directory])
- else
- if test "$withval" != "yes" ; then
- ICONV_PATH_SPEC=yes
- LOOK_DIRS="$withval"
- fi
- fi
-])
-
-ICONV_FOUND="no"
-libext=""
-for i in $LOOK_DIRS ; do
- save_LIBS=$LIBS
- save_LDFLAGS=$LDFLAGS
- save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS -I$i/include"
-dnl This is here to handle -withval stuff for --with-libiconv
-dnl Perhaps we should always add a -L
-
-dnl Check lib and lib32 library variants to cater for IRIX ABI-specific
-dnl installation paths.
- for l in "lib" "lib32" ; do
- LDFLAGS="$LDFLAGS -L$i/$l"
- LIBS=
- export LDFLAGS LIBS CPPFLAGS
-dnl Try to find iconv(3)
- jm_ICONV($i)
- if test "$ICONV_FOUND" = yes; then
- libext="$l"
- break;
- fi
- done
-
- if test "$ICONV_FOUND" = yes; then
- LDFLAGS=$save_LDFLAGS
- LIB_ADD_DIR(LDFLAGS, "$i/$libext")
- CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
- LIBS="$save_LIBS"
- ICONV_LOCATION=$i
- export LDFLAGS LIBS CPPFLAGS
-dnl Now, check for a working iconv ... we want to do it here because
-dnl there might be a working iconv further down the list of LOOK_DIRS
-
- ############
- # check for iconv in libc
- ic_save_LIBS="$LIBS"
- if test x"$ICONV_PATH_SPEC" = "xyes" ; then
- LIBS="$LIBS -L$ICONV_LOCATION/lib"
- fi
- if test x"$jm_cv_lib_iconv" != x; then
- LIBS="$LIBS -l$jm_cv_lib_iconv"
- fi
-dnl AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[
- default_dos_charset=no
- default_display_charset=no
- default_unix_charset=no
-
- # check for default dos charset name
- for j in CP850 IBM850 ; do
- rjs_CHARSET($j)
- if test x"$ICONV_CHARSET" = x"$j"; then
- default_dos_charset="\"$j\""
- break
- fi
- done
- # check for default display charset name
- for j in ASCII 646 ; do
- rjs_CHARSET($j)
- if test x"$ICONV_CHARSET" = x"$j"; then
- default_display_charset="\"$j\""
- break
- fi
- done
- # check for default unix charset name
- for j in UTF-8 UTF8 ; do
- rjs_CHARSET($j)
- if test x"$ICONV_CHARSET" = x"$j"; then
- default_unix_charset="\"$j\""
- break
- fi
- done
-
- if test "$default_dos_charset" != "no" -a \
- "$default_dos_charset" != "cross" -a \
- "$default_display_charset" != "no" -a \
- "$default_display_charset" != "cross" -a \
- "$default_unix_charset" != "no" -a \
- "$default_unix_charset" != "cross"
- then
- samba_cv_HAVE_NATIVE_ICONV=yes
- else if test "$default_dos_charset" = "cross" -o \
- "$default_display_charset" = "cross" -o \
- "$default_unix_charset" = "cross"
- then
- samba_cv_HAVE_NATIVE_ICONV=cross
- else
- samba_cv_HAVE_NATIVE_ICONV=no
- fi
- fi
-dnl ])
-
- LIBS="$ic_save_LIBS"
- if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then
- CPPFLAGS=$save_CPPFLAGS
- LDFLAGS=$save_LDFLAGS
- LIBS=$save_LIBS
- if test x"$jm_cv_lib_iconv" != x; then
- LIBS="$LIBS -l$jm_cv_lib_iconv"
- fi
- dnl Add the flags we need to CPPFLAGS and LDFLAGS
- CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
- LIB_ADD_DIR(LDFLAGS, "$i/$libext")
- export CPPFLAGS
- AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv])
- AC_DEFINE_UNQUOTED(DEFAULT_DOS_CHARSET,$default_dos_charset,[Default dos charset name])
- AC_DEFINE_UNQUOTED(DEFAULT_DISPLAY_CHARSET,$default_display_charset,[Default display charset name])
- AC_DEFINE_UNQUOTED(DEFAULT_UNIX_CHARSET,$default_unix_charset,[Default unix charset name])
- break
- fi
-dnl We didn't find a working iconv, so keep going
- fi
-dnl We only need to clean these up here for the next pass through the loop
- CPPFLAGS=$save_CPPFLAGS
- LDFLAGS=$save_LDFLAGS
- LIBS=$save_LIBS
- export LDFLAGS LIBS CPPFLAGS
-done
-unset libext
-
-
-if test x"$ICONV_FOUND" = x"no" -o x"$samba_cv_HAVE_NATIVE_ICONV" != x"yes" ; then
- AC_MSG_WARN([Sufficient support for iconv function was not found.
- Install libiconv from http://freshmeat.net/projects/libiconv/ for better charset compatibility!])
- AC_DEFINE_UNQUOTED(DEFAULT_DOS_CHARSET,"ASCII",[Default dos charset name])
- AC_DEFINE_UNQUOTED(DEFAULT_DISPLAY_CHARSET,"ASCII",[Default display charset name])
- AC_DEFINE_UNQUOTED(DEFAULT_UNIX_CHARSET,"UTF8",[Default unix charset name])
-fi
-
-
AC_CACHE_CHECK([for Linux kernel oplocks],samba_cv_HAVE_KERNEL_OPLOCKS_LINUX,[
AC_TRY_RUN([
#include <sys/types.h>
@@ -1815,7 +1416,7 @@ main() {
],
samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=yes,samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=no,samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=cross)])
if test x"$samba_cv_HAVE_KERNEL_OPLOCKS_LINUX" = x"yes"; then
- AC_DEFINE(HAVE_KERNEL_OPLOCKS_LINUX,1,[Whether to use linux kernel oplocks])
+ AC_DEFINE(HAVE_KERNEL_OPLOCKS_LINUX)
fi
AC_CACHE_CHECK([for kernel change notify support],samba_cv_HAVE_KERNEL_CHANGE_NOTIFY,[
@@ -1831,8 +1432,8 @@ main() {
}
],
samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=yes,samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=no,samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=cross)])
-if test x"$samba_cv_HAVE_KERNEL_CHANGE_NOTIFY" = x"yes"; then
- AC_DEFINE(HAVE_KERNEL_CHANGE_NOTIFY,1,[Whether kernel notifies changes])
+if test x"$samba_cv_HAVE_KERNEL_CHANGE_NOTIFY" = x"yes" && test x"$target_cpu" != x"s390"; then
+ AC_DEFINE(HAVE_KERNEL_CHANGE_NOTIFY)
fi
AC_CACHE_CHECK([for kernel share modes],samba_cv_HAVE_KERNEL_SHARE_MODES,[
@@ -1851,7 +1452,7 @@ main() {
],
samba_cv_HAVE_KERNEL_SHARE_MODES=yes,samba_cv_HAVE_KERNEL_SHARE_MODES=no,samba_cv_HAVE_KERNEL_SHARE_MODES=cross)])
if test x"$samba_cv_HAVE_KERNEL_SHARE_MODES" = x"yes"; then
- AC_DEFINE(HAVE_KERNEL_SHARE_MODES,1,[Whether the kernel supports share modes])
+ AC_DEFINE(HAVE_KERNEL_SHARE_MODES)
fi
@@ -1863,7 +1464,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[oplock_stat_t t; t.os_state = OP_REVOKE; t.os_dev = 1; t.os_ino = 1;],
samba_cv_HAVE_KERNEL_OPLOCKS_IRIX=yes,samba_cv_HAVE_KERNEL_OPLOCKS_IRIX=no)])
if test x"$samba_cv_HAVE_KERNEL_OPLOCKS_IRIX" = x"yes"; then
- AC_DEFINE(HAVE_KERNEL_OPLOCKS_IRIX,1,[Whether IRIX kernel oplock type definitions are available])
+ AC_DEFINE(HAVE_KERNEL_OPLOCKS_IRIX)
fi
AC_CACHE_CHECK([for irix specific capabilities],samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES,[
@@ -1881,7 +1482,7 @@ main() {
],
samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes,samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=no,samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross)])
if test x"$samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES" = x"yes"; then
- AC_DEFINE(HAVE_IRIX_SPECIFIC_CAPABILITIES,1,[Whether IRIX specific capabilities are available])
+ AC_DEFINE(HAVE_IRIX_SPECIFIC_CAPABILITIES)
fi
#
@@ -1897,7 +1498,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[int16 testvar;],
samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes,samba_cv_HAVE_INT16_FROM_RPC_RPC_H=no)])
if test x"$samba_cv_HAVE_INT16_FROM_RPC_RPC_H" = x"yes"; then
- AC_DEFINE(HAVE_INT16_FROM_RPC_RPC_H,1,[Whether int16 typedef is included by rpc/rpc.h])
+ AC_DEFINE(HAVE_INT16_FROM_RPC_RPC_H)
fi
AC_CACHE_CHECK([for uint16 typedef included by rpc/rpc.h],samba_cv_HAVE_UINT16_FROM_RPC_RPC_H,[
@@ -1908,7 +1509,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[uint16 testvar;],
samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes,samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=no)])
if test x"$samba_cv_HAVE_UINT16_FROM_RPC_RPC_H" = x"yes"; then
- AC_DEFINE(HAVE_UINT16_FROM_RPC_RPC_H,1,[Whether uint16 typedef is included by rpc/rpc.h])
+ AC_DEFINE(HAVE_UINT16_FROM_RPC_RPC_H)
fi
AC_CACHE_CHECK([for int32 typedef included by rpc/rpc.h],samba_cv_HAVE_INT32_FROM_RPC_RPC_H,[
@@ -1919,7 +1520,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[int32 testvar;],
samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes,samba_cv_HAVE_INT32_FROM_RPC_RPC_H=no)])
if test x"$samba_cv_HAVE_INT32_FROM_RPC_RPC_H" = x"yes"; then
- AC_DEFINE(HAVE_INT32_FROM_RPC_RPC_H,1,[Whether int32 typedef is included by rpc/rpc.h])
+ AC_DEFINE(HAVE_INT32_FROM_RPC_RPC_H)
fi
AC_CACHE_CHECK([for uint32 typedef included by rpc/rpc.h],samba_cv_HAVE_UINT32_FROM_RPC_RPC_H,[
@@ -1930,7 +1531,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[uint32 testvar;],
samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes,samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=no)])
if test x"$samba_cv_HAVE_UINT32_FROM_RPC_RPC_H" = x"yes"; then
- AC_DEFINE(HAVE_UINT32_FROM_RPC_RPC_H,1,[Whether uint32 typedef is included by rpc/rpc.h])
+ AC_DEFINE(HAVE_UINT32_FROM_RPC_RPC_H)
fi
dnl
@@ -1952,7 +1553,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[int testvar;],
samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no,samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=yes)])
if test x"$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" = x"yes"; then
- AC_DEFINE(HAVE_RPC_AUTH_ERROR_CONFLICT,1,[Whether there is a conflicting AUTH_ERROR define in rpc/rpc.h])
+ AC_DEFINE(HAVE_RPC_AUTH_ERROR_CONFLICT)
fi
AC_MSG_CHECKING([for test routines])
@@ -1965,24 +1566,14 @@ AC_CACHE_CHECK([for ftruncate extend],samba_cv_HAVE_FTRUNCATE_EXTEND,[
AC_TRY_RUN([#include "${srcdir-.}/tests/ftruncate.c"],
samba_cv_HAVE_FTRUNCATE_EXTEND=yes,samba_cv_HAVE_FTRUNCATE_EXTEND=no,samba_cv_HAVE_FTRUNCATE_EXTEND=cross)])
if test x"$samba_cv_HAVE_FTRUNCATE_EXTEND" = x"yes"; then
- AC_DEFINE(HAVE_FTRUNCATE_EXTEND,1,[Truncate extend])
-fi
-
-AC_CACHE_CHECK([for AF_LOCAL socket support], samba_cv_HAVE_WORKING_AF_LOCAL, [
-AC_TRY_RUN([#include "${srcdir-.}/tests/unixsock.c"],
- samba_cv_HAVE_WORKING_AF_LOCAL=yes,
- samba_cv_HAVE_WORKING_AF_LOCAL=no,
- samba_cv_HAVE_WORKING_AF_LOCAL=cross)])
-if test x"$samba_cv_HAVE_WORKING_AF_LOCAL" != xno
-then
- AC_DEFINE(HAVE_WORKING_AF_LOCAL, 1, [Define if you have working AF_LOCAL sockets])
+ AC_DEFINE(HAVE_FTRUNCATE_EXTEND)
fi
AC_CACHE_CHECK([for broken getgroups],samba_cv_HAVE_BROKEN_GETGROUPS,[
AC_TRY_RUN([#include "${srcdir-.}/tests/getgroups.c"],
samba_cv_HAVE_BROKEN_GETGROUPS=yes,samba_cv_HAVE_BROKEN_GETGROUPS=no,samba_cv_HAVE_BROKEN_GETGROUPS=cross)])
if test x"$samba_cv_HAVE_BROKEN_GETGROUPS" = x"yes"; then
- AC_DEFINE(HAVE_BROKEN_GETGROUPS,1,[Whether getgroups is broken])
+ AC_DEFINE(HAVE_BROKEN_GETGROUPS)
fi
AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
@@ -1990,7 +1581,6 @@ SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper"
AC_TRY_COMPILE([
#define REPLACE_GETPASS 1
-#define NO_PROTO_H 1
#define NO_CONFIG_H 1
#define main dont_declare_main
#include "${srcdir-.}/lib/getsmbpass.c"
@@ -1999,7 +1589,7 @@ AC_TRY_COMPILE([
CPPFLAGS="$SAVE_CPPFLAGS"
])
if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then
- AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced])
+ AC_DEFINE(REPLACE_GETPASS)
fi
AC_CACHE_CHECK([for broken inet_ntoa],samba_cv_REPLACE_INET_NTOA,[
@@ -2016,7 +1606,7 @@ if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
exit(1);}],
samba_cv_REPLACE_INET_NTOA=yes,samba_cv_REPLACE_INET_NTOA=no,samba_cv_REPLACE_INET_NTOA=cross)])
if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
- AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
+ AC_DEFINE(REPLACE_INET_NTOA)
fi
AC_CACHE_CHECK([for secure mkstemp],samba_cv_HAVE_SECURE_MKSTEMP,[
@@ -2038,7 +1628,7 @@ samba_cv_HAVE_SECURE_MKSTEMP=yes,
samba_cv_HAVE_SECURE_MKSTEMP=no,
samba_cv_HAVE_SECURE_MKSTEMP=cross)])
if test x"$samba_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
- AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure])
+ AC_DEFINE(HAVE_SECURE_MKSTEMP)
fi
AC_CACHE_CHECK([for sysconf(_SC_NGROUPS_MAX)],samba_cv_SYSCONF_SC_NGROUPS_MAX,[
@@ -2046,22 +1636,14 @@ AC_TRY_RUN([#include <unistd.h>
main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); }],
samba_cv_SYSCONF_SC_NGROUPS_MAX=yes,samba_cv_SYSCONF_SC_NGROUPS_MAX=no,samba_cv_SYSCONF_SC_NGROUPS_MAX=cross)])
if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then
- AC_DEFINE(SYSCONF_SC_NGROUPS_MAX,1,[Whether sysconf(_SC_NGROUPS_MAX) is available])
-fi
-
-AC_CACHE_CHECK([for sysconf(_SC_NPROC_ONLN)],samba_cv_SYSCONF_SC_NPROC_ONLN,[
-AC_TRY_RUN([#include <unistd.h>
-main() { exit(sysconf(_SC_NPROC_ONLN) == -1 ? 1 : 0); }],
-samba_cv_SYSCONF_SC_NPROC_ONLN=yes,samba_cv_SYSCONF_SC_NPROC_ONLN=no,samba_cv_SYSCONF_SC_NPROC_ONLN=cross)])
-if test x"$samba_cv_SYSCONF_SC_NPROC_ONLN" = x"yes"; then
- AC_DEFINE(SYSCONF_SC_NPROC_ONLN,1,[Whether sysconf(_SC_NPROC_ONLN) is available])
+ AC_DEFINE(SYSCONF_SC_NGROUPS_MAX)
fi
AC_CACHE_CHECK([for root],samba_cv_HAVE_ROOT,[
AC_TRY_RUN([main() { exit(getuid() != 0); }],
samba_cv_HAVE_ROOT=yes,samba_cv_HAVE_ROOT=no,samba_cv_HAVE_ROOT=cross)])
if test x"$samba_cv_HAVE_ROOT" = x"yes"; then
- AC_DEFINE(HAVE_ROOT,1,[Whether current user is root])
+ AC_DEFINE(HAVE_ROOT)
else
AC_MSG_WARN(running as non-root will disable some tests)
fi
@@ -2077,7 +1659,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_AIX=yes,samba_cv_HAVE_IFACE_AIX=no,samba_cv_HAVE_IFACE_AIX=cross)])
if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available])
+ iface=yes;AC_DEFINE(HAVE_IFACE_AIX)
fi
if test $iface = no; then
@@ -2089,7 +1671,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_IFCONF=yes,samba_cv_HAVE_IFACE_IFCONF=no,samba_cv_HAVE_IFACE_IFCONF=cross)])
if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available])
+ iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF)
fi
fi
@@ -2102,7 +1684,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_IFREQ=yes,samba_cv_HAVE_IFACE_IFREQ=no,samba_cv_HAVE_IFACE_IFREQ=cross)])
if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available])
+ iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ)
fi
fi
@@ -2119,7 +1701,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/util_sec.c"],
samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)])
if test x"$samba_cv_USE_SETRESUID" = x"yes"; then
- seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available])
+ seteuid=yes;AC_DEFINE(USE_SETRESUID)
fi
fi
@@ -2133,7 +1715,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/util_sec.c"],
samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)])
if test x"$samba_cv_USE_SETREUID" = x"yes"; then
- seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available])
+ seteuid=yes;AC_DEFINE(USE_SETREUID)
fi
fi
@@ -2146,7 +1728,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/util_sec.c"],
samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)])
if test x"$samba_cv_USE_SETEUID" = x"yes"; then
- seteuid=yes;AC_DEFINE(USE_SETEUID,1,[Whether seteuid() is available])
+ seteuid=yes;AC_DEFINE(USE_SETEUID)
fi
fi
@@ -2159,7 +1741,7 @@ AC_TRY_RUN([
#include "${srcdir-.}/lib/util_sec.c"],
samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)])
if test x"$samba_cv_USE_SETUIDX" = x"yes"; then
- seteuid=yes;AC_DEFINE(USE_SETUIDX,1,[Whether setuidx() is available])
+ seteuid=yes;AC_DEFINE(USE_SETUIDX)
fi
fi
@@ -2168,28 +1750,28 @@ AC_CACHE_CHECK([for working mmap],samba_cv_HAVE_MMAP,[
AC_TRY_RUN([#include "${srcdir-.}/tests/shared_mmap.c"],
samba_cv_HAVE_MMAP=yes,samba_cv_HAVE_MMAP=no,samba_cv_HAVE_MMAP=cross)])
if test x"$samba_cv_HAVE_MMAP" = x"yes"; then
- AC_DEFINE(HAVE_MMAP,1,[Whether mmap works])
+ AC_DEFINE(HAVE_MMAP)
fi
AC_CACHE_CHECK([for ftruncate needs root],samba_cv_FTRUNCATE_NEEDS_ROOT,[
AC_TRY_RUN([#include "${srcdir-.}/tests/ftruncroot.c"],
samba_cv_FTRUNCATE_NEEDS_ROOT=yes,samba_cv_FTRUNCATE_NEEDS_ROOT=no,samba_cv_FTRUNCATE_NEEDS_ROOT=cross)])
if test x"$samba_cv_FTRUNCATE_NEEDS_ROOT" = x"yes"; then
- AC_DEFINE(FTRUNCATE_NEEDS_ROOT,1,[Whether ftruncate() needs root])
+ AC_DEFINE(FTRUNCATE_NEEDS_ROOT)
fi
AC_CACHE_CHECK([for fcntl locking],samba_cv_HAVE_FCNTL_LOCK,[
AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock.c"],
samba_cv_HAVE_FCNTL_LOCK=yes,samba_cv_HAVE_FCNTL_LOCK=no,samba_cv_HAVE_FCNTL_LOCK=cross)])
if test x"$samba_cv_HAVE_FCNTL_LOCK" = x"yes"; then
- AC_DEFINE(HAVE_FCNTL_LOCK,1,[Whether fcntl locking is available])
+ AC_DEFINE(HAVE_FCNTL_LOCK)
fi
AC_CACHE_CHECK([for broken (glibc2.1/x86) 64 bit fcntl locking],samba_cv_HAVE_BROKEN_FCNTL64_LOCKS,[
AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock64.c"],
samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=no,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross)])
if test x"$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" = x"yes"; then
- AC_DEFINE(HAVE_BROKEN_FCNTL64_LOCKS,1,[Whether fcntl64 locks are broken])
+ AC_DEFINE(HAVE_BROKEN_FCNTL64_LOCKS)
else
@@ -2223,7 +1805,7 @@ exit(1);
samba_cv_HAVE_STRUCT_FLOCK64=yes,samba_cv_HAVE_STRUCT_FLOCK64=no,samba_cv_HAVE_STRUCT_FLOCK64=cross)])
if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
- AC_DEFINE(HAVE_STRUCT_FLOCK64,1,[Whether the flock64 struct is available])
+ AC_DEFINE(HAVE_STRUCT_FLOCK64)
fi
fi
@@ -2234,7 +1816,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct stat st; st.st_blocks = 0;],
samba_cv_HAVE_STAT_ST_BLOCKS=yes,samba_cv_HAVE_STAT_ST_BLOCKS=no,samba_cv_HAVE_STAT_ST_BLOCKS=cross)])
if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then
- AC_DEFINE(HAVE_STAT_ST_BLOCKS,1,[Whether the stat struct has a st_block property])
+ AC_DEFINE(HAVE_STAT_ST_BLOCKS)
fi
AC_CACHE_CHECK([for st_blksize in struct stat],samba_cv_HAVE_STAT_ST_BLKSIZE,[
@@ -2244,7 +1826,7 @@ AC_TRY_COMPILE([#include <sys/types.h>
[struct stat st; st.st_blksize = 0;],
samba_cv_HAVE_STAT_ST_BLKSIZE=yes,samba_cv_HAVE_STAT_ST_BLKSIZE=no,samba_cv_HAVE_STAT_ST_BLKSIZE=cross)])
if test x"$samba_cv_HAVE_STAT_ST_BLKSIZE" = x"yes"; then
- AC_DEFINE(HAVE_STAT_ST_BLKSIZE,1,[Whether the stat struct has a st_blksize property])
+ AC_DEFINE(HAVE_STAT_ST_BLKSIZE)
fi
case "$host_os" in
@@ -2260,22 +1842,20 @@ AC_TRY_COMPILE([
],[int i;],
samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no,samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes)])
if test x"$samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then
- AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS,1,[Broken RedHat 7.2 system header files])
+ AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS)
fi
;;
esac
AC_CACHE_CHECK([for broken nisplus include files],samba_cv_BROKEN_NISPLUS_INCLUDE_FILES,[
-AC_TRY_COMPILE([
-#include <sys/types.h>
-#include <sys/acl.h>
+AC_TRY_COMPILE([#include <sys/acl.h>
#if defined(HAVE_RPCSVC_NIS_H)
#include <rpcsvc/nis.h>
#endif],
[int i;],
samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no,samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes)])
if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
- AC_DEFINE(BROKEN_NISPLUS_INCLUDE_FILES,1,[Whether the nisplus include files are broken])
+ AC_DEFINE(BROKEN_NISPLUS_INCLUDE_FILES)
fi
@@ -2283,27 +1863,33 @@ fi
# check for smbwrapper support
AC_MSG_CHECKING(whether to use smbwrapper)
AC_ARG_WITH(smbwrapper,
-[ --with-smbwrapper Include SMB wrapper support (default=no) ],
+[ --with-smbwrapper Include SMB wrapper support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_SMBWRAPPER,1,[Whether to include smbwrapper support])
+ AC_DEFINE(WITH_SMBWRAPPER)
WRAPPROG="bin/smbsh\$(EXEEXT)"
WRAP="bin/smbwrapper.$SHLIBEXT"
+ if test x$ATTEMPT_WRAP32_BUILD = x; then
+ WRAP32=""
+ else
+ WRAP32=bin/smbwrapper.32.$SHLIBEXT
+ fi
+
# Conditions under which smbwrapper should not be built.
- if test x$PICFLAGS = x; then
+ if test x$PICFLAG = x; then
echo No support for PIC code - disabling smbwrapper and smbsh
WRAPPROG=""
WRAP=""
+ WRAP32=""
elif test x$ac_cv_func_syscall = xno; then
AC_MSG_RESULT([No syscall() -- disabling smbwrapper and smbsh])
WRAPPROG=""
WRAP=""
+ WRAP32=""
fi
- EXTRA_ALL_TARGETS="$EXTRA_ALL_TARGETS $WRAPPROG $WRAP"
- SMBWRAPPER="$WRAPPROG $WRAP"
;;
*)
AC_MSG_RESULT(no)
@@ -2313,15 +1899,14 @@ AC_ARG_WITH(smbwrapper,
)
#################################################
-# check for AFS clear-text auth support
-samba_cv_WITH_AFS=no
-AC_MSG_CHECKING(whether to use AFS clear-text auth)
+# check for the AFS filesystem
+AC_MSG_CHECKING(whether to use AFS)
AC_ARG_WITH(afs,
-[ --with-afs Include AFS clear-text auth support (default=no) ],
+[ --with-afs Include AFS support (default=no)],
[ case "$withval" in
- yes|auto)
- AC_MSG_RESULT($withval)
- samba_cv_WITH_AFS=$withval
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_AFS)
;;
*)
AC_MSG_RESULT(no)
@@ -2330,16 +1915,16 @@ AC_ARG_WITH(afs,
AC_MSG_RESULT(no)
)
-####################################################
-# check for Linux-specific AFS fake-kaserver support
-samba_cv_WITH_FAKE_KASERVER=no
-AC_MSG_CHECKING(whether to use AFS fake-kaserver)
-AC_ARG_WITH(fake-kaserver,
-[ --with-fake-kaserver Include AFS fake-kaserver support (default=no) ],
+
+#################################################
+# check for the DFS auth system
+AC_MSG_CHECKING(whether to use DCE/DFS auth)
+AC_ARG_WITH(dfs,
+[ --with-dce-dfs Include DCE/DFS support (default=no)],
[ case "$withval" in
- yes|auto)
- AC_MSG_RESULT($withval)
- samba_cv_WITH_FAKE_KASERVER=$withval
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_DFS)
;;
*)
AC_MSG_RESULT(no)
@@ -2349,49 +1934,18 @@ AC_ARG_WITH(fake-kaserver,
)
#################################################
-# decide whether we can support WITH_AFS and / or WITH_FAKE_KASERVER
-if test x"$samba_cv_WITH_AFS" != x"no" ||
- test x"$samba_cv_WITH_FAKE_KASERVER" != x"no"; then
-
- # see if this box has the afs-headers in /usr/include/afs
- AC_MSG_CHECKING(for /usr/include/afs)
- if test -d /usr/include/afs; then
- CFLAGS="$CFLAGS -I/usr/include/afs"
- CPPFLAGS="$CPPFLAGS -I/usr/include/afs"
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-
- # check for afs.h
- have_afs_headers=no
- AC_CHECK_HEADERS(afs.h afs/afs.h)
- if test x"$ac_cv_header_afs_h" = x"no" && test x"$ac_cv_header_afs_afs_h" = x"no"; then
- if test x"$samba_cv_WITH_FAKE_KASERVER" = x"auto" ||
- test x"$samba_cv_WITH_AFS" = x"auto"; then
- AC_MSG_WARN([AFS cannot be supported without afs.h])
- else
- AC_MSG_ERROR([AFS cannot be supported without afs.h])
- fi
- else
- have_afs_headers=yes
- fi
-fi
-
-if test x"$samba_cv_WITH_FAKE_KASERVER" != x"no" && test x"$have_afs_headers" == x"yes"; then
- AC_DEFINE(WITH_FAKE_KASERVER,1,[Whether to include AFS fake-kaserver support])
-fi
-
-#################################################
-# check whether to compile AFS/NT ACL mapping module
-samba_cv_WITH_VFS_AFSACL=no
-AC_MSG_CHECKING(whether to use AFS fake-kaserver)
-AC_ARG_WITH(vfs-afsacl,
-[ --with-vfs-afsacl Include AFS to NT ACL mapping module (default=no) ],
+# check for Kerberos IV auth system
+AC_MSG_CHECKING(whether to use Kerberos IV)
+AC_ARG_WITH(krb4,
+[ --with-krb4=base-dir Include Kerberos IV support (default=no)],
[ case "$withval" in
- yes|auto)
- AC_MSG_RESULT($withval)
- samba_cv_WITH_VFS_AFSACL=yes
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(KRB4_AUTH)
+ AC_CHECK_LIB(resolv, dn_expand)
+ LIBS="$LIBS -lkrb -ldes"
+ CFLAGS="$CFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
;;
*)
AC_MSG_RESULT(no)
@@ -2400,23 +1954,18 @@ AC_ARG_WITH(vfs-afsacl,
AC_MSG_RESULT(no)
)
-if test x"$samba_cv_WITH_VFS_AFSACL" == x"yes"; then
- default_shared_modules="$default_shared_modules vfs_afsacl"
-fi
-
-if test x"$samba_cv_WITH_AFS" != x"no" && test x"$have_afs_headers" = x"yes"; then
- AC_DEFINE(WITH_AFS,1,[Whether to include AFS clear-text auth support])
-fi
-
#################################################
-# check for the DFS clear-text auth system
-AC_MSG_CHECKING(whether to use DFS clear-text auth)
-AC_ARG_WITH(dfs,
-[ --with-dce-dfs Include DCE/DFS clear-text auth support (default=no)],
+# check for Kerberos 5 auth system
+AC_MSG_CHECKING(whether to use Kerberos 5)
+AC_ARG_WITH(krb5,
+[ --with-krb5=base-dir Include Kerberos 5 support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_DFS,1,[Whether to include DFS support])
+ AC_DEFINE(KRB5_AUTH)
+ LIBS="$LIBS -ldes425 -lkrb5 -lcrypto -lcom_err"
+ CFLAGS="$CFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
;;
*)
AC_MSG_RESULT(no)
@@ -2425,485 +1974,15 @@ AC_ARG_WITH(dfs,
AC_MSG_RESULT(no)
)
-########################################################
-# Compile with LDAP support?
-
-with_ldap_support=auto
-AC_MSG_CHECKING([for LDAP support])
-
-AC_ARG_WITH(ldap,
-[ --with-ldap LDAP support (default yes)],
-[ case "$withval" in
- yes|no)
- with_ldap_support=$withval
- ;;
- esac ])
-
-AC_MSG_RESULT($with_ldap_support)
-
-SMBLDAP=""
-AC_SUBST(SMBLDAP)
-SMBLDAPUTIL=""
-AC_SUBST(SMBLDAPUTIL)
-if test x"$with_ldap_support" != x"no"; then
-
- ##################################################################
- # first test for ldap.h and lber.h
- # (ldap.h is required for this test)
- AC_CHECK_HEADERS(ldap.h lber.h)
-
- if test x"$ac_cv_header_ldap_h" != x"yes"; then
- if test x"$with_ldap_support" = x"yes"; then
- AC_MSG_ERROR(ldap.h is needed for LDAP support)
- else
- AC_MSG_WARN(ldap.h is needed for LDAP support)
- fi
-
- with_ldap_support=no
- fi
-fi
-
-if test x"$with_ldap_support" != x"no"; then
- ac_save_LIBS=$LIBS
-
- ##################################################################
- # we might need the lber lib on some systems. To avoid link errors
- # this test must be before the libldap test
- AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf)
-
- ########################################################
- # now see if we can find the ldap libs in standard paths
- AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init)
-
- AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS)
-
- ########################################################
- # If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
- # Check found in pam_ldap 145.
- AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS)
-
- LIBS="$LIBS $LDAP_LIBS"
- AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [
- AC_TRY_COMPILE([
- #include <lber.h>
- #include <ldap.h>],
- [ldap_set_rebind_proc(0, 0, 0);],
- [smb_ldap_cv_ldap_set_rebind_proc=3],
- [smb_ldap_cv_ldap_set_rebind_proc=2]
- )
- ])
-
- AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
-
- AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS)
-
- if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then
- AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
- default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
- default_shared_modules="$default_shared_modules config_ldap";
- SMBLDAP="lib/smbldap.o"
- SMBLDAPUTIL="lib/smbldap_util.o"
- with_ldap_support=yes
- AC_MSG_CHECKING(whether LDAP support is used)
- AC_MSG_RESULT(yes)
- else
- if test x"$with_ldap_support" = x"yes"; then
- AC_MSG_ERROR(libldap is needed for LDAP support)
- else
- AC_MSG_WARN(libldap is needed for LDAP support)
- fi
-
- LDAP_LIBS=""
- with_ldap_support=no
- fi
- LIBS=$ac_save_LIBS
-fi
-
-
-#################################################
-# active directory support
-
-with_ads_support=auto
-AC_MSG_CHECKING([for Active Directory and krb5 support])
-
-AC_ARG_WITH(ads,
-[ --with-ads Active Directory support (default auto)],
-[ case "$withval" in
- yes|no)
- with_ads_support="$withval"
- ;;
- esac ])
-
-AC_MSG_RESULT($with_ads_support)
-
-FOUND_KRB5=no
-KRB5_LIBS=""
-
-if test x"$with_ldap_support" != x"yes"; then
- if test x"$with_ads_support" = x"yes"; then
- AC_MSG_ERROR(Active Directory Support requires LDAP support)
- elif test x"$with_ads_support" != x"no"; then
- AC_MSG_WARN(Active Directory Support requires LDAP support)
- fi
- with_ads_support=no
-fi
-
-if test x"$with_ads_support" != x"no"; then
-
- # Do no harm to the values of CFLAGS and LIBS while testing for
- # Kerberos support.
-
- #################################################
- # check for krb5-config from recent MIT and Heimdal kerberos 5
- AC_PATH_PROG(KRB5_CONFIG, krb5-config)
- AC_MSG_CHECKING(for working krb5-config)
- if test -x "$KRB5_CONFIG"; then
- ac_save_CFLAGS=$CFLAGS
- CFLAGS="";export CFLAGS
- ac_save_LDFLAGS=$LDFLAGS
- LDFLAGS="";export LDFLAGS
- KRB5_LIBS="`$KRB5_CONFIG --libs gssapi`"
- KRB5_CFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- KRB5_CPPFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- CFLAGS=$ac_save_CFLAGS;export CFLAGS
- LDFLAGS=$ac_save_LDFLAGS;export LDFLAGS
- FOUND_KRB5=yes
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no. Fallback to previous krb5 detection strategy)
- fi
-
- if test x$FOUND_KRB5 = x"no"; then
- #################################################
- # check for location of Kerberos 5 install
- AC_MSG_CHECKING(for kerberos 5 install path)
- AC_ARG_WITH(krb5,
- [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
- [ case "$withval" in
- no)
- AC_MSG_RESULT(no krb5-path given)
- ;;
- yes)
- AC_MSG_RESULT(/usr)
- FOUND_KRB5=yes
- ;;
- *)
- AC_MSG_RESULT($withval)
- KRB5_CFLAGS="-I$withval/include"
- KRB5_CPPFLAGS="-I$withval/include"
- KRB5_LDFLAGS="-L$withval/lib"
- FOUND_KRB5=yes
- ;;
- esac ],
- AC_MSG_RESULT(no krb5-path given)
- )
- fi
-
- if test x$FOUND_KRB5 = x"no"; then
- #################################################
- # see if this box has the SuSE location for the heimdal krb implementation
- AC_MSG_CHECKING(for /usr/include/heimdal)
- if test -d /usr/include/heimdal; then
- if test -f /usr/lib/heimdal/lib/libkrb5.a; then
- KRB5_CFLAGS="-I/usr/include/heimdal"
- KRB5_CPPFLAGS="-I/usr/include/heimdal"
- KRB5_LDFLAGS="-L/usr/lib/heimdal/lib"
- AC_MSG_RESULT(yes)
- else
- KRB5_CFLAGS="-I/usr/include/heimdal"
- KRB5_CPPFLAGS="-I/usr/include/heimdal"
- AC_MSG_RESULT(yes)
- fi
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- if test x$FOUND_KRB5 = x"no"; then
- #################################################
- # see if this box has the RedHat location for kerberos
- AC_MSG_CHECKING(for /usr/kerberos)
- if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then
- KRB5_LDFLAGS="-L/usr/kerberos/lib"
- KRB5_CFLAGS="-I/usr/kerberos/include"
- KRB5_CPPFLAGS="-I/usr/kerberos/include"
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- ac_save_CFLAGS=$CFLAGS
- ac_save_CPPFLAGS=$CPPFLAGS
- ac_save_LDFLAGS=$LDFLAGS
-
- CFLAGS="$CFLAGS $KRB5_CFLAGS"
- CPPFLAGS="$CPPFLAGS $KRB5_CPPFLAGS"
- LDFLAGS="$LDFLAGS $KRB5_LDFLAGS"
-
- KRB5_LIBS="$KRB5_LDFLAGS $KRB5_LIBS"
-
- # now check for krb5.h. Some systems have the libraries without the headers!
- # note that this check is done here to allow for different kerberos
- # include paths
- AC_CHECK_HEADERS(krb5.h)
-
- if test x"$ac_cv_header_krb5_h" = x"no"; then
-
- # Give a warning if AD support was not explicitly requested,
- # i.e with_ads_support = auto, otherwise die with an error.
-
- if test x"$with_ads_support" = x"yes"; then
- AC_MSG_ERROR([Active Directory cannot be supported without krb5.h])
- else
- AC_MSG_WARN([Active Directory cannot be supported without krb5.h])
- fi
-
- # Turn off AD support and restore CFLAGS and LIBS variables
-
- with_ads_support="no"
-
- CFLAGS=$ac_save_CFLAGS
- CPPFLAGS=$ac_save_CPPFLAGS
- LDFLAGS=$ac_save_LDFLAGS
- fi
-fi
-
-# Now we have determined whether we really want ADS support
-
-if test x"$with_ads_support" != x"no"; then
- ac_save_LIBS=$LIBS
-
- # now check for gssapi headers. This is also done here to allow for
- # different kerberos include paths
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h)
-
- ##################################################################
- # we might need the k5crypto and com_err libraries on some systems
- AC_CHECK_LIB_EXT(com_err, KRB5_LIBS, _et_list)
- AC_CHECK_LIB_EXT(k5crypto, KRB5_LIBS, krb5_encrypt_data)
-
- # Heimdal checks.
- AC_CHECK_LIB_EXT(crypto, KRB5_LIBS, des_set_key)
- AC_CHECK_LIB_EXT(asn1, KRB5_LIBS, copy_Authenticator)
- AC_CHECK_LIB_EXT(roken, KRB5_LIBS, roken_getaddrinfo_hostspec)
-
- # Heimdal checks. On static Heimdal gssapi must be linked before krb5.
- AC_CHECK_LIB_EXT(gssapi, KRB5_LIBS, gss_display_status,[],[],
- AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available]))
-
- ########################################################
- # now see if we can find the krb5 libs in standard paths
- # or as specified above
- AC_CHECK_LIB_EXT(krb5, KRB5_LIBS, krb5_mk_req_extended)
-
- ########################################################
- # now see if we can find the gssapi libs in standard paths
- AC_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[],
- AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available]))
-
- AC_CHECK_FUNC_EXT(krb5_set_real_time, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_set_default_in_tkt_etypes, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_set_default_tgs_ktypes, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_principal2salt, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_use_enctype, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_string_to_key, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_get_pw_salt, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_string_to_key_salt, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_auth_con_setkey, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_auth_con_setuseruserkey, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_locate_kdc, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_free_data_contents, $KRB5_LIBS)
- AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS)
-
- LIBS="$LIBS $KRB5_LIBS"
-
- AC_CACHE_CHECK([for addrtype in krb5_address],
- samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_address kaddr; kaddr.addrtype = ADDRTYPE_INET;],
- samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=yes,
- samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=no)])
-
- if test x"$samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS" = x"yes"; then
- AC_DEFINE(HAVE_ADDRTYPE_IN_KRB5_ADDRESS,1,
- [Whether the krb5_address struct has a addrtype property])
- fi
-
- AC_CACHE_CHECK([for addr_type in krb5_address],
- samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_address kaddr; kaddr.addr_type = KRB5_ADDRESS_INET;],
- samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=yes,
- samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=no)])
-
- if test x"$samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS" = x"yes"; then
- AC_DEFINE(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,1,
- [Whether the krb5_address struct has a addr_type property])
- fi
-
- AC_CACHE_CHECK([for enc_part2 in krb5_ticket],
- samba_cv_HAVE_KRB5_TKT_ENC_PART2,
- [AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_ticket tkt; tkt.enc_part2->authorization_data[0]->contents = NULL;],
- samba_cv_HAVE_KRB5_TKT_ENC_PART2=yes,samba_cv_HAVE_KRB5_TKT_ENC_PART2=no)])
-
- if test x"$samba_cv_HAVE_KRB5_TKT_ENC_PART2" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_TKT_ENC_PART2,1,
- [Whether the krb5_ticket struct has a enc_part2 property])
- fi
-
- AC_CACHE_CHECK([for keyvalue in krb5_keyblock],
- samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_keyblock key; key.keyvalue.data = NULL;],
- samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=yes,
- samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=no)])
-
- if test x"$samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_KEYBLOCK_KEYVALUE,1,
- [Whether the krb5_keyblock struct has a keyvalue property])
- fi
-
- AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC_MD5],
- samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_enctype enctype; enctype = ENCTYPE_ARCFOUR_HMAC_MD5;],
- samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=yes,
- samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=no)])
- AC_CACHE_CHECK([for KEYTYPE_ARCFOUR_56],
- samba_cv_HAVE_KEYTYPE_ARCFOUR_56,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_keytype keytype; keytype = KEYTYPE_ARCFOUR_56;],
- samba_cv_HAVE_KEYTYPE_ARCFOUR_56=yes,
- samba_cv_HAVE_KEYTYPE_ARCFOUR_56=no)])
-# Heimdals with KEYTYPE_ARCFOUR but not KEYTYPE_ARCFOUR_56 are broken
-# w.r.t. arcfour and windows, so we must not enable it here
- if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes" -a\
- x"$samba_cv_HAVE_KEYTYPE_ARCFOUR_56" = x"yes"; then
- AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1,
- [Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available])
- fi
-
- AC_CACHE_CHECK([for AP_OPTS_USE_SUBKEY],
- samba_cv_HAVE_AP_OPTS_USE_SUBKEY,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_flags ap_options; ap_options = AP_OPTS_USE_SUBKEY;],
- samba_cv_HAVE_AP_OPTS_USE_SUBKEY=yes,
- samba_cv_HAVE_AP_OPTS_USE_SUBKEY=no)])
-
- if test x"$samba_cv_HAVE_AP_OPTS_USE_SUBKEY" = x"yes"; then
- AC_DEFINE(HAVE_AP_OPTS_USE_SUBKEY,1,
- [Whether the AP_OPTS_USE_SUBKEY ap option is available])
- fi
-
- AC_CACHE_CHECK([for the krb5_princ_component macro],
- samba_cv_HAVE_KRB5_PRINC_COMPONENT,[
- AC_TRY_LINK([#include <krb5.h>],
- [const krb5_data *pkdata; krb5_context context; krb5_principal principal; pkdata = krb5_princ_component(context, principal, 0);],
- samba_cv_HAVE_KRB5_PRINC_COMPONENT=yes,
- samba_cv_HAVE_KRB5_PRINC_COMPONENT=no)])
-
- if test x"$samba_cv_HAVE_KRB5_PRINC_COMPONENT" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_PRINC_COMPONENT,1,
- [Whether krb5_princ_component is available])
- fi
-
- AC_CACHE_CHECK([for key in krb5_keytab_entry],
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_keytab_entry entry; krb5_keyblock e; entry.key = e;],
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=yes,
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=no)])
-
- if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEY,1,
- [Whether krb5_keytab_entry has key member])
- fi
-
- AC_CACHE_CHECK([for keyblock in krb5_keytab_entry],
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,[
- AC_TRY_COMPILE([#include <krb5.h>],
- [krb5_keytab_entry entry; entry.keyblock.keytype = 0;],
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=yes,
- samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK=no)])
-
- if test x"$samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK,1,
- [Whether krb5_keytab_entry has keyblock member])
- fi
-
- if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then
- AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support])
- AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
- AC_MSG_CHECKING(whether Active Directory and krb5 support is used)
- AC_MSG_RESULT(yes)
- else
- if test x"$with_ads_support" = x"yes"; then
- AC_MSG_ERROR(libkrb5 is needed for Active Directory support)
- else
- AC_MSG_WARN(libkrb5 is needed for Active Directory support)
- fi
- KRB5_LIBS=""
- with_ads_support=no
- fi
- LIBS="$ac_save_LIBS"
-fi
-
-########################################################
-# Compile experimental passdb backends?
-# (pdb_xml, pdb_mysql, pdb_pgsql)
-AC_MSG_CHECKING(whether to build experimental passdb libraries)
-AC_ARG_WITH(expsam,
-[ --with-expsam=<list> Include experimental passdb libraries (default=no)]
-[ Valid choices include (comma separated list): ]
-[ xml, mysql & pgsql],
-[ expsam_pdb_modules=`echo "$withval" | sed 's/,/ /g'`
- if test "z$expsam_pdb_modules" = "zyes"; then
- expsam_pdb_modules="xml mysql pgsql"
- fi
- AC_MSG_RESULT($expsam_pdb_modules)
- for i in $expsam_pdb_modules
- do
- case "$i" in
- xml|all|yes)
- ## pdb_xml
- AM_PATH_XML2([2.0.0],[default_shared_modules="$default_shared_modules pdb_xml"],[AC_MSG_ERROR([Can't find XML libraries while XML support is requested])])
- CFLAGS="$CFLAGS $XML_CFLAGS"
- ;;
- mysql|all|yes)
- ## pdb_mysql
- AM_PATH_MYSQL([default_shared_modules="$default_shared_modules pdb_mysql"],[AC_MSG_ERROR([Can't find MySQL libraries while MySQL support is requested])])
- CFLAGS="$CFLAGS $MYSQL_CFLAGS"
- ;;
- pgsql|all|yes)
- ## pdb_pgsql
- AM_PATH_PGSQL([default_shared_modules="$default_shared_modules pdb_pgsql"],[])
- CFLAGS="$CFLAGS $PGSQL_CFLAGS"
- ;;
- no)
- ;;
- *)
- echo "Unknown module name \"$i\"! Exiting..."
- exit 1
- ;;
- esac
- done ],
- AC_MSG_RESULT(no)
-)
-
#################################################
# check for automount support
-AC_MSG_CHECKING(whether to use automount)
+AC_MSG_CHECKING(whether to use AUTOMOUNT)
AC_ARG_WITH(automount,
-[ --with-automount Include automount support (default=no)],
+[ --with-automount Include AUTOMOUNT support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_AUTOMOUNT,1,[Whether to include automount support])
+ AC_DEFINE(WITH_AUTOMOUNT)
;;
*)
AC_MSG_RESULT(no)
@@ -2914,16 +1993,16 @@ AC_ARG_WITH(automount,
#################################################
# check for smbmount support
-AC_MSG_CHECKING(whether to use smbmount)
+AC_MSG_CHECKING(whether to use SMBMOUNT)
AC_ARG_WITH(smbmount,
-[ --with-smbmount Include smbmount (Linux only) support (default=no)],
+[ --with-smbmount Include SMBMOUNT (Linux only) support (default=no)],
[ case "$withval" in
yes)
case "$host_os" in
*linux*)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_SMBMOUNT,1,[Whether to build smbmount])
- EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/smbmount bin/smbmnt bin/smbumount"
+ AC_DEFINE(WITH_SMBMOUNT)
+ MPROGS="bin/smbmount bin/smbmnt bin/smbumount"
;;
*)
AC_MSG_ERROR(not on a linux system!)
@@ -2932,30 +2011,25 @@ AC_ARG_WITH(smbmount,
;;
*)
AC_MSG_RESULT(no)
+ MPROGS=
;;
esac ],
AC_MSG_RESULT(no)
+ MPROGS=
)
#################################################
-# check for a PAM clear-text auth, accounts, password and session support
+# check for a PAM password database
with_pam_for_crypt=no
-AC_MSG_CHECKING(whether to use PAM)
+AC_MSG_CHECKING(whether to use PAM password database)
AC_ARG_WITH(pam,
-[ --with-pam Include PAM support (default=no)],
+[ --with-pam Include PAM password database support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- if test x"$ac_cv_header_security_pam_appl_h" = x"no"; then
- if test x"$ac_cv_header_security_pam_modules_h" = x"no"; then
- if test x"$ac_cv_header_security__pam_macros_h" = x"no"; then
- AC_MSG_ERROR(--with-pam specified but no PAM headers found)
- fi
- fi
- fi
- AC_DEFINE(WITH_PAM,1,[Whether to include PAM support])
- AUTH_LIBS="$AUTH_LIBS -lpam"
+ AC_DEFINE(WITH_PAM)
+ LIBS="$LIBS -lpam"
with_pam_for_crypt=yes
;;
*)
@@ -2966,28 +2040,28 @@ AC_ARG_WITH(pam,
)
# we can't build a pam module if we don't have pam.
-AC_CHECK_LIB(pam, pam_get_data, [AC_DEFINE(HAVE_LIBPAM,1,[Whether libpam is available])])
+AC_CHECK_LIB(pam, pam_get_data, [AC_DEFINE(HAVE_LIBPAM)])
#################################################
# check for pam_smbpass support
AC_MSG_CHECKING(whether to use pam_smbpass)
AC_ARG_WITH(pam_smbpass,
-[ --with-pam_smbpass Build PAM module for authenticating against passdb backends (default=no)],
+[ --with-pam_smbpass Include the smbpass PAM module (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- # Conditions under which pam_smbpass should not be built.
+# Conditions under which pam_smbpass should not be built.
- if test x$PICFLAGS = x; then
- AC_MSG_ERROR([No support for PIC code])
- elif test x"$ac_cv_header_security_pam_appl_h" = x"no"; then
- AC_MSG_ERROR([No security/pam_appl.h found])
+ if test x$PICFLAG = x; then
+ AC_MSG_RESULT([No support for PIC code - disabling pam_smbpass])
+ PAM_MOD=""
elif test x$ac_cv_lib_pam_pam_get_data = xno; then
- AC_MSG_ERROR([No libpam found])
+ AC_MSG_RESULT([No libpam found -- disabling pam_smbpass])
+ PAM_MOD=""
else
- AUTH_LIBS="$AUTH_LIBS -lpam"
- SHLIB_PROGS="$SHLIB_PROGS bin/pam_smbpass.$SHLIBEXT"
+ AC_DEFINE(WITH_PAM_SMBPASS)
+ PAM_MOD="bin/pam_smbpass.so"
fi
;;
*)
@@ -2999,10 +2073,15 @@ AC_ARG_WITH(pam_smbpass,
###############################################
-# test for where we get crypt() from
-AC_SEARCH_LIBS(crypt, [crypt],
- [test "$ac_cv_search_crypt" = "none required" || AUTH_LIBS="-lcrypt $AUTH_LIBS"
- AC_DEFINE(HAVE_CRYPT,1,[Whether the system has the crypt() function])])
+# test for where we get crypt() from, but only
+# if not using PAM
+if test $with_pam_for_crypt = no; then
+AC_CHECK_FUNCS(crypt)
+if test x"$ac_cv_func_crypt" = x"no"; then
+ AC_CHECK_LIB(crypt, crypt, [LIBS="$LIBS -lcrypt";
+ AC_DEFINE(HAVE_CRYPT)])
+fi
+fi
##
## moved after the check for -lcrypt in order to
@@ -3012,13 +2091,10 @@ AC_SEARCH_LIBS(crypt, [crypt],
##
if test $with_pam_for_crypt = no; then
AC_CACHE_CHECK([for a crypt that needs truncated salt],samba_cv_HAVE_TRUNCATED_SALT,[
-crypt_LIBS="$LIBS"
-LIBS="$AUTH_LIBS $LIBS"
AC_TRY_RUN([#include "${srcdir-.}/tests/crypttest.c"],
- samba_cv_HAVE_TRUNCATED_SALT=no,samba_cv_HAVE_TRUNCATED_SALT=yes,samba_cv_HAVE_TRUNCATED_SALT=cross)
-LIBS="$crypt_LIBS"])
+ samba_cv_HAVE_TRUNCATED_SALT=no,samba_cv_HAVE_TRUNCATED_SALT=yes,samba_cv_HAVE_TRUNCATED_SALT=cross)])
if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then
- AC_DEFINE(HAVE_TRUNCATED_SALT,1,[Whether crypt needs truncated salt])
+ AC_DEFINE(HAVE_TRUNCATED_SALT)
fi
fi
@@ -3029,15 +2105,59 @@ fi
##
########################################################################################
+## set the with_smbpasswd_sam as the default
+with_smbpasswd_sam=yes
+
+
+
#################################################
-# check for a LDAP password database configuration backwards compatibility
-AC_MSG_CHECKING(whether to use LDAP SAM 2.2 compatible configuration)
+# check for a TDB password database
+AC_MSG_CHECKING(whether to use TDB SAM database)
+AC_ARG_WITH(tdbsam,
+[ --with-tdbsam Include experimental TDB SAM support (default=no)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_TDB_SAM)
+ with_smbpasswd_sam=no
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+#################################################
+# check for a LDAP password database
+AC_MSG_CHECKING(whether to use LDAP SAM database)
AC_ARG_WITH(ldapsam,
-[ --with-ldapsam Include LDAP SAM 2.2 compatible configuration (default=no)],
+[ --with-ldapsam Include experimental LDAP SAM support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_LDAP_SAMCONFIG,1,[Whether to include 2.2 compatible LDAP SAM configuration])
+ AC_DEFINE(WITH_LDAP_SAM)
+ LDAPLIBS="-lldap"
+ AC_CHECK_LIB(lber, ber_bvfree, [LDAPLIBS="$LDAPLIBS -llber"])
+ ## remove -lresolv as this should be included by the -lsasl dependency
+ ## in the OpenLDAP clients. By not requiring it specifically, we avoid
+ ## issues on platforms that don't have it
+ LDAPLIBS="$LDAPLIBS"
+ old_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $LDAPLIBS"
+ AC_CHECK_FUNCS(ldap_start_tls_s)
+ LDFLAGS="$old_LDFLAGS"
+ with_smbpasswd_sam=no
+ AC_SUBST(LDAPLIBS)
+AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, samba_cv_ldap_set_rebind_proc, [
+AC_TRY_COMPILE([
+#include <lber.h>
+#include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [samba_cv_ldap_set_rebind_proc=3], [samba_cv_ldap_set_rebind_proc=2]) ])
+if test x"$samba_cv_ldap_set_rebind_proc" = x"3"; then
+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS,3)
+else
+ AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS,2)
+fi
;;
*)
AC_MSG_RESULT(no)
@@ -3046,6 +2166,39 @@ AC_ARG_WITH(ldapsam,
AC_MSG_RESULT(no)
)
+
+#################################################
+# check for a NISPLUS password database
+AC_MSG_CHECKING(whether to use NISPLUS SAM database)
+AC_ARG_WITH(nisplussam,
+[ --with-nisplussam Include NISPLUS SAM support (default=no)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_NISPLUS_SAM)
+ with_smbpasswd_sam=no
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+################################################
+# This test should come last because the
+# smbpasswd SAM is only used if another format
+# has not been defined
+AC_MSG_CHECKING(whether to use traditional smbpasswd file)
+if test $with_smbpasswd_sam = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_SMBPASSWD_SAM)
+ PDBEDIT=""
+else
+ AC_MSG_RESULT(no)
+ PDBEDIT="bin/pdbedit\$(EXEEXT)"
+fi
+
########################################################################################
##
## END OF TESTS FOR SAM BACKENDS.
@@ -3060,7 +2213,75 @@ AC_ARG_WITH(nisplus-home,
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_NISPLUS_HOME,1,[Whether to include nisplus_home support])
+ AC_DEFINE(WITH_NISPLUS_HOME)
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+#################################################
+# check for the secure socket layer
+AC_MSG_CHECKING(whether to use SSL)
+AC_ARG_WITH(ssl,
+[ --with-ssl Include SSL support (default=no)
+ --with-sslinc=DIR Where the SSL includes are (defaults to /usr/local/ssl/include)
+ --with-ssllib=DIR Where the SSL libraries are (defaults to /usr/local/ssl/lib)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_SSL)
+ withval="/usr/local/ssl" # default
+
+ if test "${with_sslinc+set}" = set; then
+
+ withval="$with_sslinc"
+ case "$withval" in
+ yes|no)
+ echo "configure: warning: --with-sslinc called without argument - will use default" 1>&w
+ CFLAGS="-I/usr/local/ssl/include $CFLAGS"
+ ;;
+ * )
+ CFLAGS="-I${withval} $CFLAGS"
+ ;;
+ esac
+
+ else
+
+ CFLAGS="-I/usr/local/ssl/include $CFLAGS"
+
+ fi
+
+ if test "${with_ssllib+set}" = set; then
+
+ withval="$with_ssllib"
+ case "$withval" in
+ yes|no)
+ echo "configure: warning: --with-ssllib called without argument - will use default" 1>&w
+ LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
+ ;;
+ * )
+ LDFLAGS="-L${withval}/lib $LDFLAGS"
+ ;;
+ esac
+
+ else
+
+ LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
+
+ fi
+
+ LIBS="-lssl -lcrypto $LIBS"
+
+# if test ! -d ${withval}; then
+# echo "configure: error: called with --with-ssl, but ssl base directory ${withval} does not exist or is not a directory. Aborting config" 1>&2
+# exit 1
+# fi
+
+ CFLAGS="-DHAVE_CRYPT_DECL $CFLAGS" # Damn, SSLeay defines its own
+
;;
*)
AC_MSG_RESULT(no)
@@ -3077,7 +2298,7 @@ AC_ARG_WITH(syslog,
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_SYSLOG,1,[Whether to include experimental syslog support])
+ AC_DEFINE(WITH_SYSLOG)
;;
*)
AC_MSG_RESULT(no)
@@ -3094,7 +2315,7 @@ AC_ARG_WITH(profiling-data,
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_PROFILE,1,[Whether to use profiling])
+ AC_DEFINE(WITH_PROFILE)
;;
*)
AC_MSG_RESULT(no)
@@ -3106,357 +2327,58 @@ AC_ARG_WITH(profiling-data,
#################################################
# check for experimental disk-quotas support
+QUOTAOBJS=smbd/noquotas.o
-samba_cv_WITH_QUOTAS=auto
-samba_cv_TRY_QUOTAS=no
-samba_cv_RUN_QUOTA_TESTS=auto
-samba_cv_WITH_SYS_QUOTAS=auto
-samba_cv_TRY_SYS_QUOTAS=no
-samba_cv_SYSQUOTA_FOUND=no;
-
-AC_MSG_CHECKING(whether to try disk-quotas support)
+AC_MSG_CHECKING(whether to support disk-quotas)
AC_ARG_WITH(quotas,
-[ --with-quotas Include disk-quota support (default=no)],
+[ --with-quotas Include experimental disk-quota support (default=no)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- samba_cv_WITH_QUOTAS=yes
- samba_cv_TRY_QUOTAS=yes
- samba_cv_RUN_QUOTA_TESTS=yes
- #set sys quotas to auto in this case
- samba_cv_TRY_SYS_QUOTAS=auto
- ;;
- auto)
- AC_MSG_RESULT(auto)
- samba_cv_WITH_QUOTAS=auto
- samba_cv_TRY_QUOTAS=auto
- samba_cv_RUN_QUOTA_TESTS=auto
- #set sys quotas to auto in this case
- samba_cv_TRY_SYS_QUOTAS=auto
- ;;
- no)
- AC_MSG_RESULT(no)
- samba_cv_WITH_QUOTAS=no
- samba_cv_TRY_QUOTAS=no
- samba_cv_RUN_QUOTA_TESTS=no
+ QUOTAOBJS=smbd/quotas.o
;;
*)
- AC_MSG_RESULT(${samba_cv_TRY_QUOTAS})
- ;;
- esac ],
- AC_MSG_RESULT(${samba_cv_TRY_QUOTAS})
-)
-
-AC_MSG_CHECKING(whether to try the new lib/sysquotas.c interface)
-AC_ARG_WITH(sys-quotas,
-[ --with-sys-quotas Include lib/sysquotas.c support (default=auto)],
-[ case "$withval" in
- yes)
- AC_MSG_RESULT(yes)
- samba_cv_WITH_SYS_QUOTAS=yes
- samba_cv_TRY_SYS_QUOTAS=yes
- samba_cv_RUN_QUOTA_TESTS=yes
- ;;
- auto)
- AC_MSG_RESULT(auto)
- samba_cv_WITH_SYS_QUOTAS=auto
- samba_cv_TRY_SYS_QUOTAS=auto
- samba_cv_RUN_QUOTA_TESTS=auto
- ;;
- no)
AC_MSG_RESULT(no)
- samba_cv_WITH_SYS_QUOTAS=no
- samba_cv_TRY_SYS_QUOTAS=no
- ;;
- *)
- AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS})
;;
esac ],
- AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS})
+ AC_MSG_RESULT(no)
)
-
-if test x"$samba_cv_TRY_SYS_QUOTAS" = x"auto"; then
-AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os})
- case "$host_os" in
- *linux*)
- AC_MSG_RESULT(yes)
- samba_cv_TRY_SYS_QUOTAS=yes
- samba_cv_RUN_QUOTA_TESTS=yes
- samba_cv_SYSQUOTA_FOUND=yes
- AC_DEFINE(HAVE_QUOTACTL_LINUX,1,[Whether Linux quota support is available])
- samba_cv_sysquotas_file="lib/sysquotas_linux.c"
- AC_DEFINE(HAVE_LINUX_XFS_QUOTAS,1,[Whether Linux xfs quota support is available])
- samba_cv_found_xfs_header=yes
- ;;
- *)
- AC_MSG_RESULT(no)
- samba_cv_TRY_SYS_QUOTAS=no
- ;;
- esac
-fi
-
-#############################################
-# only check for quota stuff if --with-quotas
-if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then
-
-# some broken header files need this
-AC_CHECK_HEADER(asm/types.h,[
- AC_DEFINE(HAVE_ASM_TYPES_H,1,[check for <asm/types.h>])
- AC_ADD_INCLUDE(<asm/types.h>)
- ])
-
-# For quotas on Veritas VxFS filesystems
-AC_CHECK_HEADERS(sys/fs/vx_quota.h)
-
-# For sys/quota.h and linux/quota.h
-AC_CHECK_HEADERS(sys/quota.h)
-
-if test x"$samba_cv_found_xfs_header" != x"yes"; then
-# if we have xfs quota support <sys/quota.h> (IRIX) we should use it
-AC_CACHE_CHECK([for XFS QUOTA in <sys/quota.h>],samba_cv_HAVE_SYS_QUOTA_XFS, [
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ASM_TYPES_H
-#include <asm/types.h>
-#endif
-#include <sys/quota.h>
-],[int i = Q_XGETQUOTA;],
-samba_cv_HAVE_SYS_QUOTA_XFS=yes,samba_cv_HAVE_SYS_QUOTA_XFS=no)])
-if test "$samba_cv_HAVE_SYS_QUOTA_XFS"x = "yes"x; then
- samba_cv_found_xfs_header=yes
-fi
-fi
-
-# if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX
-AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#ifdef HAVE_SYS_QUOTA_H
-#include <sys/quota.h>
-#endif
-],[
-struct dqblk D;
-D.dqb_fsoftlimit = 0;],
-samba_cv_HAVE_DQB_FSOFTLIMIT=yes,samba_cv_HAVE_DQB_FSOFTLIMIT=no)])
-if test "$samba_cv_HAVE_DQB_FSOFTLIMIT"x = "yes"x; then
- AC_DEFINE(HAVE_DQB_FSOFTLIMIT,1,[struct dqblk .dqb_fsoftlimit])
-fi
-
-##################
-# look for a working quota system
-
-if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
-AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[
-AC_TRY_RUN_STRICT([
-#define HAVE_QUOTACTL_4A 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
- samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)])
-if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then
- samba_cv_SYSQUOTA_FOUND=yes;
- AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available])
- samba_cv_sysquotas_file="lib/sysquotas_4A.c"
-fi
-fi
-
-if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
-AC_CACHE_CHECK([for int quotactl(const char *path, int cmd, int id, char *addr)],samba_cv_HAVE_QUOTACTL_4B,[
-AC_TRY_RUN_STRICT([
-#define HAVE_QUOTACTL_4B 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
- samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)])
-if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then
- echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api"
- samba_cv_SYSQUOTA_FOUND=yes;
- AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available])
- samba_cv_sysquotas_file="lib/sysquotas_4B.c"
-fi
-fi
-
-if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
-AC_CACHE_CHECK([for CRAY int quotactl (char *spec, int request, char *arg)],samba_cv_HAVE_QUOTACTL_3,[
-AC_TRY_RUN_STRICT([
-#define HAVE_QUOTACTL_3 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
- samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)])
-if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then
- echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api"
- samba_cv_SYSQUOTA_FOUND=yes;
- AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available])
- samba_cv_sysquotas_file="lib/sysquotas_3.c"
-fi
-fi
-
-#################################################
-# check for mntent.h and struct mntent
-AC_CHECK_HEADERS(mntent.h)
-#################################################
-# check for setmntent,getmntent,endmntent
-AC_CHECK_FUNCS(setmntent getmntent endmntent)
-
-#################################################
-# check for devnm.h and struct mntent
-AC_CHECK_HEADERS(devnm.h)
-#################################################
-# check for devnm
-AC_CHECK_FUNCS(devnm)
-
-if test x"$samba_cv_WITH_SYS_QUOTAS" = x"yes"; then
- if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
- # if --with-sys-quotas=yes then build it
- # you have can use the get/set quota command smb.conf
- # options then
- samba_cv_SYSQUOTA_FOUND=auto
- fi
- if test x"$samba_cv_TRY_SYS_QUOTAS" != x"yes"; then
- # if --with-sys-quotas=yes then build it
- # you have can use the get/set quota command smb.conf
- # options then
- samba_cv_TRY_SYS_QUOTAS=auto
- fi
-fi
-
-if test x"$samba_cv_SYSQUOTA_FOUND" != x"no"; then
-AC_CACHE_CHECK([whether the sys_quota interface works],samba_cv_SYSQUOTA_WORKS,[
-SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#define NO_PROTO_H 1
-#define NO_CONFIG_H 1
-#define HAVE_SYS_QUOTAS 1
-#include "${srcdir-.}/${samba_cv_sysquotas_file}"
-#include "${srcdir-.}/lib/sysquotas.c"
-],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no)
-CPPFLAGS="$SAVE_CPPFLAGS"
-])
-if test x"$samba_cv_SYSQUOTA_WORKS" = x"yes"; then
-AC_MSG_CHECKING(whether to use the new lib/sysquotas.c interface)
- if test x"$samba_cv_TRY_SYS_QUOTAS" != x"no"; then
- AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support])
- AC_DEFINE(HAVE_SYS_QUOTAS,1,[Whether the new lib/sysquotas.c interface can be used])
- samba_cv_WE_USE_SYS_QUOTAS=yes
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-fi
-fi
-
-if test x"$samba_cv_SYSQUOTA_FOUND" != x"no" -a x"$samba_cv_found_xfs_header" = x"yes"; then
-AC_CACHE_CHECK([whether the sys_quota interface works with XFS],samba_cv_SYSQUOTA_WORKS_XFS,[
-SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#define NO_PROTO_H 1
-#define NO_CONFIG_H 1
-#define HAVE_SYS_QUOTAS 1
-#define HAVE_XFS_QUOTAS 1
-#include "${srcdir-.}/lib/sysquotas_xfs.c"
-],[],samba_cv_SYSQUOTA_WORKS_XFS=yes,samba_cv_SYSQUOTA_WORKS_XFS=no)
-CPPFLAGS="$SAVE_CPPFLAGS"
-])
-if test x"$samba_cv_SYSQUOTA_WORKS_XFS" = x"yes"; then
- if test x"$samba_cv_WE_USE_SYS_QUOTAS" = x"yes"; then
- AC_DEFINE(HAVE_XFS_QUOTAS,1,[Whether xfs quota support is available])
- fi
-fi
-fi
-
-AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[
-SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#define NO_PROTO_H 1
-#define NO_CONFIG_H 1
-#include "${srcdir-.}/smbd/quotas.c"
-],[],samba_cv_QUOTA_WORKS=yes,samba_cv_QUOTA_WORKS=no)
-CPPFLAGS="$SAVE_CPPFLAGS"
-])
-if test x"$samba_cv_QUOTA_WORKS" = x"yes"; then
-AC_MSG_CHECKING(whether to use the old quota support)
- if test x"$samba_cv_WE_USE_SYS_QUOTAS" != x"yes"; then
- if test x"$samba_cv_TRY_QUOTAS" != x"no"; then
- AC_DEFINE(WITH_QUOTAS,1,[Whether to use disk quota support])
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
- else
- AC_MSG_RESULT(no)
- fi
-fi
-
-####################
-# End of quota check samba_cv_RUN_QUOTA_TESTS
-fi
+AC_SUBST(QUOTAOBJS)
#################################################
# check for experimental utmp accounting
AC_MSG_CHECKING(whether to support utmp accounting)
-WITH_UTMP=yes
AC_ARG_WITH(utmp,
-[ --with-utmp Include utmp accounting (default, if supported by OS)],
+[ --with-utmp Include experimental utmp accounting (default=no)],
[ case "$withval" in
- no)
- WITH_UTMP=no
- ;;
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_UTMP)
+ ;;
*)
- WITH_UTMP=yes
- ;;
+ AC_MSG_RESULT(no)
+ ;;
esac ],
+ AC_MSG_RESULT(no)
)
-# utmp requires utmp.h
-# Note similar check earlier, when checking utmp details.
-
-if test x"$WITH_UTMP" = x"yes" -a x"$ac_cv_header_utmp_h" = x"no"; then
- utmp_no_reason=", no utmp.h on $host_os"
- WITH_UTMP=no
-fi
-
-# Display test results
-
-if test x"$WITH_UTMP" = x"yes"; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_UTMP,1,[Whether to include experimental utmp accounting])
-else
- AC_MSG_RESULT(no$utmp_no_reason)
-fi
-
#################################################
-# choose native language(s) of man pages
-AC_MSG_CHECKING(chosen man pages' language(s))
-AC_ARG_WITH(manpages-langs,
-[ --with-manpages-langs={en,ja,pl} Choose man pages' language(s). (en)],
+# check for MS Dfs support
+
+AC_MSG_CHECKING(whether to support Microsoft Dfs)
+AC_ARG_WITH(msdfs,
+[ --with-msdfs Include MS Dfs support (default=no)],
[ case "$withval" in
- yes|no)
- AC_MSG_WARN(--with-manpages-langs called without argument - will use default)
- manlangs="en"
- ;;
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_MSDFS)
+ ;;
*)
- manlangs="$withval"
- ;;
- esac
-
- AC_MSG_RESULT($manlangs)
- manlangs=`echo $manlangs | sed "s/,/ /g"` # replacing commas with spaces to produce a list
- AC_SUBST(manlangs)],
-
- [manlangs="en"
- AC_MSG_RESULT($manlangs)
- AC_SUBST(manlangs)]
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
)
#################################################
@@ -3464,54 +2386,31 @@ AC_ARG_WITH(manpages-langs,
INSTALLCLIENTCMD_SH=:
INSTALLCLIENTCMD_A=:
-INSTALLCLIENT=
LIBSMBCLIENT_SHARED=
LIBSMBCLIENT=
AC_MSG_CHECKING(whether to build the libsmbclient shared library)
AC_ARG_WITH(libsmbclient,
-[ --with-libsmbclient Build the libsmbclient shared library (default=yes if shared libs supported)],
+[ --with-libsmbclient Build the libsmbclient shared library (default=no)],
[ case "$withval" in
- no)
- AC_MSG_RESULT(no)
- ;;
- *)
+ yes)
if test $BLDSHARED = true; then
INSTALLCLIENTCMD_SH="\$(INSTALLCMD)"
- ## build the static version of libsmbclient as well
- INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
LIBSMBCLIENT_SHARED=bin/libsmbclient.$SHLIBEXT
LIBSMBCLIENT=libsmbclient
AC_MSG_RESULT(yes)
else
- enable_static=yes
- AC_MSG_RESULT(no shared library support -- will supply static library)
- fi
- if test $enable_static = yes; then
INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
LIBSMBCLIENT=libsmbclient
+ AC_MSG_RESULT(no shared library support -- will supply static library)
fi
- INSTALLCLIENT=installclientlib
;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
esac ],
-[
-# if unspecified, default is to built it iff possible.
- if test $BLDSHARED = true; then
- INSTALLCLIENTCMD_SH="\$(INSTALLCMD)"
- LIBSMBCLIENT_SHARED=bin/libsmbclient.$SHLIBEXT
- LIBSMBCLIENT=libsmbclient
- AC_MSG_RESULT(yes)
- else
- enable_static=yes
- AC_MSG_RESULT(no shared library support -- will supply static library)
- fi
- if test $enable_static = yes; then
- INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
- LIBSMBCLIENT=libsmbclient
- fi]
- INSTALLCLIENT=installclientlib
+ AC_MSG_RESULT(no)
)
-
#################################################
# these tests are taken from the GNU fileutils package
AC_CHECKING(how to get filesystem space usage)
@@ -3537,7 +2436,7 @@ if test $space = no; then
fu_cv_sys_stat_statvfs64=cross)])
if test $fu_cv_sys_stat_statvfs64 = yes; then
space=yes
- AC_DEFINE(STAT_STATVFS64,1,[Whether statvfs64() is available])
+ AC_DEFINE(STAT_STATVFS64)
fi
fi
@@ -3557,7 +2456,7 @@ if test $space = no; then
fu_cv_sys_stat_statvfs=no)])
if test $fu_cv_sys_stat_statvfs = yes; then
space=yes
- AC_DEFINE(STAT_STATVFS,1,[Whether statvfs() is available])
+ AC_DEFINE(STAT_STATVFS)
fi
fi
@@ -3581,7 +2480,7 @@ if test $space = no; then
AC_MSG_RESULT($fu_cv_sys_stat_statfs3_osf1)
if test $fu_cv_sys_stat_statfs3_osf1 = yes; then
space=yes
- AC_DEFINE(STAT_STATFS3_OSF1,1,[Whether statfs requires 3 arguments])
+ AC_DEFINE(STAT_STATFS3_OSF1)
fi
fi
@@ -3612,7 +2511,7 @@ member (AIX, 4.3BSD)])
AC_MSG_RESULT($fu_cv_sys_stat_statfs2_bsize)
if test $fu_cv_sys_stat_statfs2_bsize = yes; then
space=yes
- AC_DEFINE(STAT_STATFS2_BSIZE,1,[Whether statfs requires two arguments and struct statfs has bsize property])
+ AC_DEFINE(STAT_STATFS2_BSIZE)
fi
fi
@@ -3633,7 +2532,7 @@ if test $space = no; then
AC_MSG_RESULT($fu_cv_sys_stat_statfs4)
if test $fu_cv_sys_stat_statfs4 = yes; then
space=yes
- AC_DEFINE(STAT_STATFS4,1,[Whether statfs requires 4 arguments])
+ AC_DEFINE(STAT_STATFS4)
fi
fi
@@ -3661,7 +2560,7 @@ member (4.4BSD and NetBSD)])
AC_MSG_RESULT($fu_cv_sys_stat_statfs2_fsize)
if test $fu_cv_sys_stat_statfs2_fsize = yes; then
space=yes
- AC_DEFINE(STAT_STATFS2_FSIZE,1,[Whether statfs requires 2 arguments and struct statfs has fsize])
+ AC_DEFINE(STAT_STATFS2_FSIZE)
fi
fi
@@ -3692,7 +2591,7 @@ if test $space = no; then
AC_MSG_RESULT($fu_cv_sys_stat_fs_data)
if test $fu_cv_sys_stat_fs_data = yes; then
space=yes
- AC_DEFINE(STAT_STATFS2_FS_DATA,1,[Whether statfs requires 2 arguments and struct fs_data is available])
+ AC_DEFINE(STAT_STATFS2_FS_DATA)
fi
fi
@@ -3704,7 +2603,7 @@ fi
# If we don't have all of these then disable large
# file support.
#
-AC_MSG_CHECKING([if large file support can be enabled])
+AC_MSG_CHECKING(if large file support can be enabled)
AC_TRY_COMPILE([
#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
#include <sys/types.h>
@@ -3715,30 +2614,32 @@ __COMPILE_ERROR_
[int i],
samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes,samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=no)
if test x"$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT" = x"yes"; then
- AC_DEFINE(HAVE_EXPLICIT_LARGEFILE_SUPPORT,1,[Whether large file support can be enabled])
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_EXPLICIT_LARGEFILE_SUPPORT)
+else
+ AC_MSG_RESULT(no)
fi
-AC_MSG_RESULT([$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT])
AC_ARG_WITH(spinlocks,
-[ --with-spinlocks Use spin locks instead of fcntl locks (default=no) ])
+[ --with-spinlocks Use spin locks instead of fcntl locks (default=no)])
if test "x$with_spinlocks" = "xyes"; then
- AC_DEFINE(USE_SPINLOCKS,1,[Whether to use spin locks instead of fcntl locks])
+ AC_DEFINE(USE_SPINLOCKS)
case "$host_cpu" in
sparc)
- AC_DEFINE(SPARC_SPINLOCKS,1,[Whether to use sparc spinlocks])
+ AC_DEFINE(SPARC_SPINLOCKS)
;;
i386|i486|i586|i686)
- AC_DEFINE(INTEL_SPINLOCKS,1,[Whether to use intel spinlocks])
+ AC_DEFINE(INTEL_SPINLOCKS)
;;
mips)
- AC_DEFINE(MIPS_SPINLOCKS,1,[Whether to use mips spinlocks])
+ AC_DEFINE(MIPS_SPINLOCKS)
;;
powerpc)
- AC_DEFINE(POWERPC_SPINLOCKS,1,[Whether to use powerpc spinlocks])
+ AC_DEFINE(POWERPC_SPINLOCKS)
;;
esac
fi
@@ -3752,108 +2653,77 @@ AC_ARG_WITH(acl-support,
[ case "$withval" in
yes)
- case "$host_os" in
- *sysv5*)
- AC_MSG_RESULT(Using UnixWare ACLs)
- AC_DEFINE(HAVE_UNIXWARE_ACLS,1,[Whether UnixWare ACLs are available])
- ;;
- *solaris*)
- AC_MSG_RESULT(Using solaris ACLs)
- AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether solaris ACLs are available])
- ;;
- *hpux*)
- AC_MSG_RESULT(Using HPUX ACLs)
- AC_DEFINE(HAVE_HPUX_ACLS,1,[Whether HPUX ACLs are available])
- ;;
- *irix*)
- AC_MSG_RESULT(Using IRIX ACLs)
- AC_DEFINE(HAVE_IRIX_ACLS,1,[Whether IRIX ACLs are available])
- ;;
- *aix*)
- AC_MSG_RESULT(Using AIX ACLs)
- AC_DEFINE(HAVE_AIX_ACLS,1,[Whether AIX ACLs are available])
- ;;
- *osf*)
- AC_MSG_RESULT(Using Tru64 ACLs)
- AC_DEFINE(HAVE_TRU64_ACLS,1,[Whether Tru64 ACLs are available])
- ACL_LIBS="$ACL_LIBS -lpacl"
- ;;
- *freebsd5*)
- AC_MSG_RESULT(Using FreeBSD posix ACLs)
- AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether FreeBSD POSIX ACLs are available])
- AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
- ;;
- *linux*)
- AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
- AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
- AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
- acl_LIBS=$LIBS
- LIBS="$LIBS -lacl"
- AC_TRY_LINK([#include <sys/types.h>
-#include <sys/acl.h>],
-[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);],
-samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)
- LIBS=$acl_LIBS])
- if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
- AC_MSG_RESULT(Using posix ACLs)
- AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
- AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[
- acl_LIBS=$LIBS
- LIBS="$LIBS -lacl"
- AC_TRY_LINK([#include <sys/types.h>
-#include <sys/acl.h>],
-[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);],
-samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)
- LIBS=$acl_LIBS])
- if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
- AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
- fi
- fi
- ;;
- *)
- AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
- AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
- acl_LIBS=$LIBS
- LIBS="$LIBS -lacl"
- AC_TRY_LINK([#include <sys/types.h>
+ case "$host_os" in
+ *sysv5*)
+ AC_MSG_RESULT(Using UnixWare ACLs)
+ AC_DEFINE(HAVE_UNIXWARE_ACLS)
+ ;;
+ *solaris*)
+ AC_MSG_RESULT(Using solaris ACLs)
+ AC_DEFINE(HAVE_SOLARIS_ACLS)
+ ;;
+ *hpux*)
+ AC_MSG_RESULT(Using HPUX ACLs)
+ AC_DEFINE(HAVE_HPUX_ACLS)
+ ;;
+ *irix*)
+ AC_MSG_RESULT(Using IRIX ACLs)
+ AC_DEFINE(HAVE_IRIX_ACLS)
+ ;;
+ *aix*)
+ AC_MSG_RESULT(Using AIX ACLs)
+ AC_DEFINE(HAVE_AIX_ACLS)
+ ;;
+ *osf*)
+ AC_MSG_RESULT(Using Tru64 ACLs)
+ AC_DEFINE(HAVE_TRU64_ACLS)
+ LIBS="$LIBS -lpacl"
+ ;;
+ *)
+ AC_CHECK_LIB(acl,acl_get_file)
+ AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
+ AC_TRY_LINK([#include <sys/types.h>
#include <sys/acl.h>],
[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);],
-samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)
- LIBS=$acl_LIBS])
+samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)])
if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
- AC_MSG_RESULT(Using posix ACLs)
- AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
+ AC_MSG_RESULT(Using posix ACLs)
+ AC_DEFINE(HAVE_POSIX_ACLS)
AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[
- acl_LIBS=$LIBS
- LIBS="$LIBS -lacl"
AC_TRY_LINK([#include <sys/types.h>
#include <sys/acl.h>],
[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);],
-samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)
- LIBS=$acl_LIBS])
+samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)])
if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
- AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
+ AC_DEFINE(HAVE_ACL_GET_PERM_NP)
fi
fi
- ;;
- esac
- ;;
+ ;;
+ esac
+ ;;
*)
AC_MSG_RESULT(no)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
+ AC_DEFINE(HAVE_NO_ACLS)
;;
esac ],
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support should be built in])
+ AC_DEFINE(HAVE_NO_ACLS)
AC_MSG_RESULT(no)
)
#################################################
+# check for the historical SAMBA installation
+
+if test "x$prefix" = xNONE -a "$sbindir" = "\${exec_prefix}/sbin"; then
+ # Put all binaries under the /usr/local/samba/bin directory.
+ sbindir="$bindir"
+fi
+
+#################################################
# check for sendfile support
-with_sendfile_support=yes
-AC_MSG_CHECKING(whether to check to support sendfile)
+AC_MSG_CHECKING(whether to check for support sendfile)
AC_ARG_WITH(sendfile-support,
-[ --with-sendfile-support Check for sendfile support (default=yes)],
+[ --with-sendfile-support Check for sendfile support (default=no)],
[ case "$withval" in
yes)
@@ -3897,16 +2767,16 @@ ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)])
if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE64,1,[Whether 64-bit sendfile() is available])
- AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
+ AC_DEFINE(HAVE_SENDFILE64)
+ AC_DEFINE(LINUX_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
elif test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
- AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
+ AC_DEFINE(HAVE_SENDFILE)
+ AC_DEFINE(LINUX_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
elif test x"$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then
- AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used])
+ AC_DEFINE(LINUX_BROKEN_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
@@ -3916,13 +2786,18 @@ samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)]
AC_CACHE_CHECK([for freebsd sendfile support],samba_cv_HAVE_SENDFILE,[
AC_TRY_LINK([\
#include <sys/types.h>
-#include <unistd.h>
#include <sys/socket.h>
#include <sys/uio.h>],
[\
- int fromfd, tofd, ret, total=0;
+#define NULL (void *)0
+ int fromfd, tofd, ret, total;
off_t offset, nwritten;
- struct sf_hdtr hdr;
+ struct sf_hdtr {
+ struct iovec *headers;
+ int hdr_cnt;
+ struct iovec *trailers;
+ int trl_cnt;
+ } hdr;
struct iovec hdtrl;
hdr.headers = &hdtrl;
hdr.hdr_cnt = 1;
@@ -3935,9 +2810,9 @@ samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)]
samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() support is available])
- AC_DEFINE(FREEBSD_SENDFILE_API,1,[Whether the FreeBSD sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included])
+ AC_DEFINE(HAVE_SENDFILE)
+ AC_DEFINE(FREEBSD_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
@@ -3962,9 +2837,9 @@ samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
],
samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)])
if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE64,1,[Whether sendfile64() is available])
- AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included])
+ AC_DEFINE(HAVE_SENDFILE64)
+ AC_DEFINE(HPUX_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
@@ -3987,16 +2862,16 @@ samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)])
],
samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
- AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included])
+ AC_DEFINE(HAVE_SENDFILE)
+ AC_DEFINE(HPUX_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
;;
*solaris*)
- AC_CHECK_LIB(sendfile,sendfilev)
+ LIBS="$LIBS -lsendfile"
AC_CACHE_CHECK([for solaris sendfilev64 support],samba_cv_HAVE_SENDFILEV64,[
AC_TRY_LINK([\
#include <sys/sendfile.h>],
@@ -4023,9 +2898,9 @@ samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
samba_cv_HAVE_SENDFILEV64=yes,samba_cv_HAVE_SENDFILEV64=no)])
if test x"$samba_cv_HAVE_SENDFILEV64" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILEV64,1,[Whether sendfilev64() is available])
- AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the soloris sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included])
+ AC_DEFINE(HAVE_SENDFILEV64)
+ AC_DEFINE(SOLARIS_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
@@ -4056,9 +2931,9 @@ samba_cv_HAVE_SENDFILEV64=yes,samba_cv_HAVE_SENDFILEV64=no)])
samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)])
if test x"$samba_cv_HAVE_SENDFILEV" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILEV,1,[Whether sendfilev() is available])
- AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the solaris sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether to include sendfile() support])
+ AC_DEFINE(HAVE_SENDFILEV)
+ AC_DEFINE(SOLARIS_SENDFILE_API)
+ AC_DEFINE(WITH_SENDFILE)
else
AC_MSG_RESULT(no);
fi
@@ -4072,75 +2947,40 @@ samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)])
AC_MSG_RESULT(no)
;;
esac ],
- AC_MSG_RESULT(yes)
+ AC_MSG_RESULT(no)
)
-
#################################################
# Check whether winbind is supported on this platform. If so we need to
-# build and install client programs, sbin programs and shared libraries
+# build and install client programs (WINBIND_TARGETS), sbin programs
+# (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS).
AC_MSG_CHECKING(whether to build winbind)
# Initially, the value of $host_os decides whether winbind is supported
-HAVE_WINBIND=yes
-
-# Define the winbind shared library name and any specific linker flags
-# it needs to be built with.
-
-WINBIND_NSS="nsswitch/libnss_winbind.$SHLIBEXT"
-WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
-WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
-
-case "$host_os" in
- *linux*)
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o"
- ;;
- *freebsd5*)
- # FreeBSD winbind client is implemented as a wrapper around
- # the Linux version.
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_freebsd.o \
- nsswitch/winbind_nss_linux.o"
- WINBIND_NSS="nsswitch/nss_winbind.$SHLIBEXT"
- WINBIND_WINS_NSS="nsswitch/nss_wins.$SHLIBEXT"
- ;;
- *irix*)
- # IRIX has differently named shared libraries
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o"
- WINBIND_NSS="nsswitch/libns_winbind.$SHLIBEXT"
- WINBIND_WINS_NSS="nsswitch/libns_wins.$SHLIBEXT"
- ;;
+case "$host_os" in
+ *linux*|*irix*)
+ HAVE_WINBIND=yes
+ ;;
*solaris*)
- # Solaris winbind client is implemented as a wrapper around
- # the Linux version.
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o \
- nsswitch/winbind_nss_linux.o"
+ HAVE_WINBIND=yes
+ WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o"
WINBIND_NSS_EXTRA_LIBS="-lsocket"
;;
*hpux11*)
+ HAVE_WINBIND=yes
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o"
+ ;;
+ *aix4*)
+ HAVE_WINBIND=yes
;;
- *aix*)
- # AIX has even differently named shared libraries. No
- # WINS support has been implemented yet.
- WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_aix.o"
- WINBIND_NSS_LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-ewb_aix_init"
- WINBIND_NSS="nsswitch/WINBIND"
- WINBIND_WINS_NSS=""
- ;;
- *)
+ *)
HAVE_WINBIND=no
- winbind_no_reason=", unsupported on $host_os"
+ winbind_no_reason=", unsupported on $host_os"
;;
esac
-AC_SUBST(WINBIND_NSS)
-AC_SUBST(WINBIND_WINS_NSS)
-AC_SUBST(WINBIND_NSS_LDSHFLAGS)
-AC_SUBST(WINBIND_NSS_EXTRA_OBJS)
-AC_SUBST(WINBIND_NSS_EXTRA_LIBS)
-
# Check the setting of --with-winbindd
AC_ARG_WITH(winbind,
@@ -4169,257 +3009,173 @@ fi
# Display test results
if test x"$HAVE_WINBIND" = x"yes"; then
+
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_WINBIND,1,[Whether to build winbind])
- EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)"
- EXTRA_SBIN_PROGS="$EXTRA_SBIN_PROGS bin/winbindd\$(EXEEXT)"
- if test $BLDSHARED = true; then
- SHLIB_PROGS="$SHLIB_PROGS $WINBIND_NSS $WINBIND_WINS_NSS"
+ AC_MSG_CHECKING(whether to enable winbind auth challenge/response code)
+ AC_ARG_WITH(winbind-auth-challenge,
+ [ --with-winbind-auth-challenge Enable winbindd_pam_auth_crap() functionality (default no)],
+ [
+ case "$withval" in
+ yes)
+ AC_DEFINE(WITH_WINBIND_AUTH_CRAP)
+ AC_MSG_RESULT(yes)
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+ )
+
+# Check for FreeBSD problem with getgroups
+
+ WINBIND_TARGETS="bin/wbinfo\$(EXEEXT)"
+ WINBIND_STARGETS="bin/winbindd\$(EXEEXT)"
+ case "$host_os" in
+ *irix*)
+ WINBIND_LTARGETS="nsswitch/libns_winbind.so"
+ ;;
+ *)
+ WINBIND_LTARGETS="nsswitch/libnss_winbind.so"
+ ;;
+ esac
+
+
+ case "$with_pam" in
+ yes)
+ WINBIND_PAM_TARGETS="nsswitch/pam_winbind.so"
+ ;;
+ esac
+
+# Check for Horrible winbindd ldap hack.
+
+ AC_MSG_CHECKING(whether to enable winbind ldap hack)
+ AC_ARG_WITH(winbind-ldap-hack,
+ [ --with-winbind-ldap-hack Enable winbindd_ldap_hack() functionality (default no)],
+ [
+ case "$withval" in
+ yes)
+ AC_DEFINE(WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK)
+ LIBS="$LIBS -lldap";
+ AC_MSG_RESULT(yes)
+ ;;
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+ )
- if test x"$with_pam" = x"yes"; then
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/pam_winbind.$SHLIBEXT"
- fi
- fi
else
AC_MSG_RESULT(no$winbind_no_reason)
+
+ WINBIND_TARGETS=""
+ WINBIND_STARGETS=""
+ WINBIND_LTARGETS=""
+ WINBIND_PAM_TARGETS=""
+fi
+
+
+# Check for FreeBSD problem with getgroups
+# It returns EGID too many times in the list of groups
+# and causes a security problem
+AC_CACHE_CHECK([whether or not getgroups returns EGID too many times],
+ samba_cv_have_getgroups_too_many_egids,[AC_TRY_RUN([
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ gid_t groups[10];
+ int n = 10;
+
+ n = getgroups(n, &groups);
+ /* Could actually pass back the number of EGIDs there ... */
+ exit((n > 1 && groups[0] == getegid() && groups[1] == getegid()) ? 1 : 0);
+}],
+ samba_cv_have_getgroups_too_many_egids=no,samba_cv_have_getgroups_too_many_egids=yes, samba_cv_have_getgroups_too_many_egids=cross)])
+if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
+ AC_DEFINE(HAVE_GETGROUPS_TOO_MANY_EGIDS)
fi
+# Substitution time!
+
+AC_SUBST(WINBIND_TARGETS)
+AC_SUBST(WINBIND_STARGETS)
+AC_SUBST(WINBIND_LTARGETS)
+AC_SUBST(WINBIND_PAM_TARGETS)
+AC_SUBST(WINBIND_NSS_EXTRA_OBJS)
+AC_SUBST(WINBIND_NSS_EXTRA_LIBS)
+
# Solaris has some extra fields in struct passwd that need to be
-# initialised otherwise nscd crashes.
-
-AC_CHECK_MEMBER(struct passwd.pw_comment,
- AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),,
- [#include <pwd.h>])
+# initialised otherwise nscd crashes. Unfortunately autoconf < 2.50
+# doesn't have the AC_CHECK_MEMBER macro which would be handy for checking
+# this.
-AC_CHECK_MEMBER(struct passwd.pw_age,
- AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),,
- [#include <pwd.h>])
+#AC_CHECK_MEMBER(struct passwd.pw_comment,
+# AC_DEFINE(HAVE_PASSWD_PW_COMMENT, 1, [Defined if struct passwd has pw_comment field]),
+# [#include <pwd.h>])
+
+AC_CACHE_CHECK([whether struct passwd has pw_comment],samba_cv_passwd_pw_comment, [
+ AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_comment;],
+ samba_cv_passwd_pw_comment=yes,samba_cv_passwd_pw_comment=no)])
+if test x"$samba_cv_passwd_pw_comment" = x"yes"; then
+ AC_DEFINE(HAVE_PASSWD_PW_COMMENT)
+fi
+
+#AC_CHECK_MEMBER(struct passwd.pw_age,
+# AC_DEFINE(HAVE_PASSWD_PW_AGE, 1, [Defined if struct passwd has pw_age field]),
+# [#include <pwd.h>])
+
+AC_CACHE_CHECK([whether struct passwd has pw_age],samba_cv_passwd_pw_age, [
+ AC_TRY_COMPILE([#include <pwd.h>],[struct passwd p; p.pw_age;],
+ samba_cv_passwd_pw_age=yes,samba_cv_passwd_pw_age=no)])
+if test x"$samba_cv_passwd_pw_age" = x"yes"; then
+ AC_DEFINE(HAVE_PASSWD_PW_AGE)
+fi
#################################################
-# Check to see if we should use the included popt
+# Check to see if we should use the included popt
AC_ARG_WITH(included-popt,
[ --with-included-popt use bundled popt library, not from system],
-[
+[
case "$withval" in
- yes)
- INCLUDED_POPT=yes
- ;;
+ yes)
+ INCLUDED_POPT=yes
+ ;;
no)
- INCLUDED_POPT=no
+ INCLUDED_POPT=no
;;
esac ],
)
if test x"$INCLUDED_POPT" != x"yes"; then
AC_CHECK_LIB(popt, poptGetContext,
- INCLUDED_POPT=no, INCLUDED_POPT=yes)
+ INCLUDED_POPT=no, INCLUDED_POPT=yes)
fi
AC_MSG_CHECKING(whether to use included popt)
if test x"$INCLUDED_POPT" = x"yes"; then
- AC_MSG_RESULT(yes)
+ AC_MSG_RESULT($srcdir/popt)
BUILD_POPT='$(POPT_OBJS)'
- POPTLIBS='$(POPT_OBJS)'
FLAGS1="-I$srcdir/popt"
else
AC_MSG_RESULT(no)
- BUILD_POPT=""
- POPTLIBS="-lpopt"
+ LIBS="$LIBS -lpopt"
fi
AC_SUBST(BUILD_POPT)
-AC_SUBST(POPTLIBS)
AC_SUBST(FLAGS1)
#################################################
-# Check if the user wants Python
-
-# At the moment, you can use this to set which Python binary to link
-# against. (Libraries built for Python2.2 can't be used by 2.1,
-# though they can coexist in different directories.) In the future
-# this might make the Python stuff be built by default.
-
-# Defaulting python breaks the clean target if python isn't installed
-
-PYTHON=
-
-AC_ARG_WITH(python,
-[ --with-python=PYTHONNAME build Python libraries],
-[ case "${withval-python}" in
- yes)
- PYTHON=python
- EXTRA_ALL_TARGETS="$EXTRA_ALL_TARGETS python_ext"
- ;;
- no)
- PYTHON=
- ;;
- *)
- PYTHON=${withval-python}
- ;;
- esac ])
-AC_SUBST(PYTHON)
-
-for i in `echo $default_static_modules | sed -e's/,/ /g'`
-do
- eval MODULE_DEFAULT_$i=STATIC
-done
-
-for i in `echo $default_shared_modules | sed -e's/,/ /g'`
-do
- dnl Fall back to static if we cannot build shared libraries
- eval MODULE_DEFAULT_$i=STATIC
-
- if test $BLDSHARED = true; then
- eval MODULE_DEFAULT_$i=SHARED
- fi
-done
-
-dnl Always built these modules static
-MODULE_pdb_guest=STATIC
-MODULE_rpc_spoolss=STATIC
-MODULE_rpc_srv=STATIC
-MODULE_idmap_tdb=STATIC
-MODULE_gums_tdbsam2=STATIC
-
-AC_ARG_WITH(static-modules,
-[ --with-static-modules=MODULES Comma-seperated list of names of modules to statically link in],
-[ if test $withval; then
- for i in `echo $withval | sed -e's/,/ /g'`
- do
- eval MODULE_$i=STATIC
- done
-fi ])
-
-AC_ARG_WITH(shared-modules,
-[ --with-shared-modules=MODULES Comma-seperated list of names of modules to build shared],
-[ if test $withval; then
- for i in `echo $withval | sed -e's/,/ /g'`
- do
- eval MODULE_$i=SHARED
- done
-fi ])
-
-###########################################################################
-## contributed pdb_modules
-
-SMB_MODULE(pdb_xml, passdb/pdb_xml.o, "bin/xml.$SHLIBEXT", PDB,
- [ PASSDB_LIBS="$PASSDB_LIBS $XML_LIBS" ] )
-SMB_MODULE(pdb_mysql, passdb/pdb_mysql.o, "bin/mysql.$SHLIBEXT", PDB,
- [ PASSDB_LIBS="$PASSDB_LIBS $MYSQL_LIBS" ] )
-SMB_MODULE(pdb_pgsql, passdb/pdb_pgsql.o, "bin/pgsql.$SHLIBEXT", PDB,
- [ PASSDB_LIBS="$PASSDB_LIBS $PGSQL_LIBS" ] )
-
-## end of contributed pdb_modules
-###########################################################################
-
-SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o, "bin/ldapsam.$SHLIBEXT", PDB,
- [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] )
-SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB)
-SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
-SMB_MODULE(pdb_guest, passdb/pdb_guest.o, "bin/guest.$SHLIBEXT", PDB)
-SMB_MODULE(pdb_gums, [passdb/pdb_gums.o \$(GUMS_OBJ)], "bin/gums.$SHLIBEXT", PDB)
-SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o)
-
-SMB_MODULE(gums_tdbsam2, sam/gums_tdbsam2.o, "bin/tdbsam2.$SHLIBEXT", GUMS)
-SMB_SUBSYSTEM(GUMS)
-
-SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_epmapper, \$(RPC_EPMAPPER_OBJ), "bin/librpc_epmapper.$SHLIBEXT",
- RPC)
-SMB_SUBSYSTEM(RPC,smbd/server.o)
-
-SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP)
-SMB_SUBSYSTEM(IDMAP,sam/idmap.o)
-
-SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_CP850, modules/CP850.o, "bin/CP850.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_CP437, modules/CP437.o, "bin/CP437.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_macosxfs, modules/charset_macosxfs.o,"bin/macosxfs.$SHLIBEXT", CHARSET)
-SMB_SUBSYSTEM(CHARSET,lib/iconv.o)
-
-SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH)
-SMB_SUBSYSTEM(AUTH,auth/auth.o)
-
-SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), "bin/recycle.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_audit, \$(VFS_AUDIT_OBJ), "bin/audit.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_extd_audit, \$(VFS_EXTD_AUDIT_OBJ), "bin/extd_audit.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK_OBJ), "bin/netatalk.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
-SMB_SUBSYSTEM(VFS,smbd/vfs.o)
-
-SMB_MODULE(config_ldap, param/config_ldap.o, "bin/config_ldap.$SHLIBEXT", CONFIG, [ CONFIG_LIBS="$CONFIG_LIBS $LDAP_LIBS" "$SMBLDAP" ])
-SMB_SUBSYSTEM(CONFIG, param/modconf.o)
-
-AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
-
-#################################################
-# do extra things if we are running insure
-
-if test "${ac_cv_prog_CC}" = "insure"; then
- CPPFLAGS="$CPPFLAGS -D__INSURE__"
-fi
-
-#################################################
-# Display summary of libraries detected
-
-AC_MSG_RESULT([Using libraries:])
-AC_MSG_RESULT([ LIBS = $LIBS])
-if test x"$with_ads_support" != x"no"; then
- AC_MSG_RESULT([ KRB5_LIBS = $KRB5_LIBS])
-fi
-if test x"$with_ldap_support" != x"no"; then
- AC_MSG_RESULT([ LDAP_LIBS = $LDAP_LIBS])
-fi
-AC_MSG_RESULT([ AUTH_LIBS = $AUTH_LIBS])
-
-#################################################
# final configure stuff
-
AC_MSG_CHECKING([configure summary])
AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
- AC_MSG_RESULT(yes),
- AC_MSG_ERROR([summary failure. Aborting config]); exit 1;,
- AC_MSG_WARN([cannot run when cross-compiling]))
+ AC_MSG_RESULT(yes),
+ AC_MSG_ERROR([summary failure. Aborting config]); exit 1;,
+ AC_MSG_WARN([cannot run when cross-compiling]))
builddir=`pwd`
AC_SUBST(builddir)
-dnl Remove -L/usr/lib/? from LDFLAGS and LIBS
-LIB_REMOVE_USR_LIB(LDFLAGS)
-LIB_REMOVE_USR_LIB(LIBS)
-
-dnl Remove -I/usr/include/? from CFLAGS and CPPFLAGS
-CFLAGS_REMOVE_USR_INCLUDE(CFLAGS)
-CFLAGS_REMOVE_USR_INCLUDE(CPPFLAGS)
-
-AC_OUTPUT(include/stamp-h Makefile script/findsmb smbadduser script/gen-8bit-gap.sh)
-
-#################################################
-# Print very concise instructions on building/use
-if test "x$enable_dmalloc" = xyes
-then
- AC_MSG_RESULT([Note: The dmalloc debug library will be included. To turn it on use])
- AC_MSG_RESULT([ \$ eval \`dmalloc samba\`.])
-fi
+AC_OUTPUT(include/stamp-h Makefile script/findsmb)
diff --git a/source/configure.nodebug.developer b/source/configure.nodebug.developer
new file mode 100755
index 00000000000..65e21b4bdf4
--- /dev/null
+++ b/source/configure.nodebug.developer
@@ -0,0 +1,3 @@
+#!/bin/sh
+CFLAGS="-Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"; export CFLAGS
+./configure $*
diff --git a/source/dynconfig.c b/source/dynconfig.c
deleted file mode 100644
index 34c716926cc..00000000000
--- a/source/dynconfig.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Copyright (C) 2001 by Martin Pool <mbp@samba.org>
- Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * @file dynconfig.c
- *
- * @brief Global configurations, initialized to configured defaults.
- *
- * This file should be the only file that depends on path
- * configuration (--prefix, etc), so that if ./configure is re-run,
- * all programs will be appropriately updated. Everything else in
- * Samba should import extern variables from here, rather than relying
- * on preprocessor macros.
- *
- * Eventually some of these may become even more variable, so that
- * they can for example consistently be set across the whole of Samba
- * by command-line parameters, config file entries, or environment
- * variables.
- *
- * @todo Perhaps eventually these should be merged into the parameter
- * table? There's kind of a chicken-and-egg situation there...
- **/
-
-char const *dyn_SBINDIR = SBINDIR,
- *dyn_BINDIR = BINDIR,
- *dyn_SWATDIR = SWATDIR;
-
-pstring dyn_CONFIGFILE = CONFIGFILE; /**< Location of smb.conf file. **/
-
-/** Log file directory. **/
-pstring dyn_LOGFILEBASE = LOGFILEBASE;
-
-/** Statically configured LanMan hosts. **/
-pstring dyn_LMHOSTSFILE = LMHOSTSFILE;
-
-/**
- * @brief Samba library directory.
- *
- * @sa lib_path() to get the path to a file inside the LIBDIR.
- **/
-pstring dyn_LIBDIR = LIBDIR;
-const fstring dyn_SHLIBEXT = SHLIBEXT;
-
-/**
- * @brief Directory holding lock files.
- *
- * Not writable, but used to set a default in the parameter table.
- **/
-const pstring dyn_LOCKDIR = LOCKDIR;
-const pstring dyn_PIDDIR = PIDDIR;
-
-const pstring dyn_SMB_PASSWD_FILE = SMB_PASSWD_FILE;
-const pstring dyn_PRIVATE_DIR = PRIVATE_DIR;
diff --git a/source/groupdb/aliasdb.c b/source/groupdb/aliasdb.c
new file mode 100755
index 00000000000..33b9fcc37f5
--- /dev/null
+++ b/source/groupdb/aliasdb.c
@@ -0,0 +1,388 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Pasesword and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Caseson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mases Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern fstring global_sam_name;
+
+/*
+ * NOTE. All these functions are abstracted into a structure
+ * that points to the correct function for the selected database. JRA.
+ */
+
+static struct aliasdb_ops *aldb_ops;
+
+/***************************************************************
+ Initialise the alias db operations.
+***************************************************************/
+
+BOOL initialise_alias_db(void)
+{
+ if (aldb_ops)
+ {
+ return True;
+ }
+
+#ifdef WITH_NISPLUS
+ aldb_ops = nisplus_initialise_alias_db();
+#elif defined(WITH_LDAP)
+ aldb_ops = ldap_initialise_alias_db();
+#else
+ aldb_ops = file_initialise_alias_db();
+#endif
+
+ return (aldb_ops != NULL);
+}
+
+/*
+ * Functions that return/manipulate a LOCAL_GRP.
+ */
+
+/************************************************************************
+ Utility function to search alias database by gid: the LOCAL_GRP
+ structure does not have a gid member, so we have to convert here
+ from gid to alias rid.
+*************************************************************************/
+LOCAL_GRP *iterate_getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return iterate_getaliasrid(pwdb_gid_to_alias_rid(gid), mem, num_mem);
+}
+
+/************************************************************************
+ Utility function to search alias database by rid. use this if your database
+ does not have search facilities.
+*************************************************************************/
+LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ LOCAL_GRP *als = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by rid: 0x%x\n", rid));
+
+ /* Open the alias database file - not for update. */
+ fp = startaliasent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open alias database.\n"));
+ return NULL;
+ }
+
+ while ((als = getaliasent(fp, mem, num_mem)) != NULL && als->rid != rid)
+ {
+ }
+
+ if (als != NULL)
+ {
+ DEBUG(10, ("found alias %s by rid: 0x%x\n", als->name, rid));
+ }
+
+ endaliasent(fp);
+ return als;
+}
+
+/************************************************************************
+ Utility function to search alias database by name. use this if your database
+ does not have search facilities.
+*************************************************************************/
+LOCAL_GRP *iterate_getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ LOCAL_GRP *als = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by name: %s\n", name));
+
+ /* Open the alias database file - not for update. */
+ fp = startaliasent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open alias database.\n"));
+ return NULL;
+ }
+
+ while ((als = getaliasent(fp, mem, num_mem)) != NULL && !strequal(als->name, name))
+ {
+ }
+
+ if (als != NULL)
+ {
+ DEBUG(10, ("found by name: %s\n", name));
+ }
+
+ endaliasent(fp);
+ return als;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainalias list.
+ *************************************************************************/
+BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als)
+{
+ LOCAL_GRP *talss;
+
+ if (alss == NULL || num_alss == NULL || als == NULL)
+ return False;
+
+ talss = (LOCAL_GRP *)Realloc((*alss), ((*num_alss)+1) * sizeof(LOCAL_GRP));
+ if (talss == NULL) {
+ if (*alss)
+ free(*alss);
+ return False;
+ } else
+ (*alss) = talss;
+
+ DEBUG(10,("adding alias %s(%s)\n", als->name, als->comment));
+
+ fstrcpy((*alss)[(*num_alss)].name , als->name);
+ fstrcpy((*alss)[(*num_alss)].comment, als->comment);
+ (*alss)[(*num_alss)].rid = als->rid;
+
+ (*num_alss)++;
+
+ return True;
+}
+
+/*************************************************************************
+ checks to see if a user is a member of a domain alias
+ *************************************************************************/
+static BOOL user_is_member(char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
+{
+ int i;
+ pstring name;
+ slprintf(name, sizeof(name)-1, "\\%s\\%s", global_sam_name, user_name);
+
+ for (i = 0; i < num_mem; i++)
+ {
+ DEBUG(10,("searching against user %s...\n", mem[i].name));
+ if (strequal(mem[i].name, name))
+ {
+ DEBUG(10,("searching for user %s: found\n", name));
+ return True;
+ }
+ }
+ DEBUG(10,("searching for user %s: not found\n", name));
+ return False;
+}
+
+/*************************************************************************
+ gets an array of aliases that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL iterate_getuseraliasnam(char *user_name, LOCAL_GRP **alss, int *num_alss)
+{
+ LOCAL_GRP *als;
+ LOCAL_GRP_MEMBER *mem = NULL;
+ int num_mem = 0;
+ void *fp = NULL;
+
+ DEBUG(10, ("search for useralias by name: %s\n", user_name));
+
+ if (user_name == NULL || als == NULL || num_alss == NULL)
+ {
+ return False;
+ }
+
+ (*alss) = NULL;
+ (*num_alss) = 0;
+
+ /* Open the alias database file - not for update. */
+ fp = startaliasent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open alias database.\n"));
+ return False;
+ }
+
+ /* iterate through all aliases. search members for required user */
+ while ((als = getaliasent(fp, &mem, &num_mem)) != NULL)
+ {
+ DEBUG(5,("alias name %s members: %d\n", als->name, num_mem));
+ if (num_mem != 0 && mem != NULL)
+ {
+ BOOL ret = True;
+ if (user_is_member(user_name, mem, num_mem))
+ {
+ ret = add_domain_alias(alss, num_alss, als);
+ }
+
+ free(mem);
+ mem = NULL;
+ num_mem = 0;
+
+ if (!ret)
+ {
+ (*num_alss) = 0;
+ break;
+ }
+ }
+ }
+
+ if ((*num_alss) != 0)
+ {
+ DEBUG(10, ("found %d user aliases:\n", (*num_alss)));
+ }
+
+ endaliasent(fp);
+ return True;
+}
+
+/*************************************************************************
+ gets an array of aliases that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss)
+{
+ LOCAL_GRP *als;
+ void *fp = NULL;
+
+ DEBUG(10, ("enum user aliases\n"));
+
+ if (als == NULL || num_alss == NULL)
+ {
+ return False;
+ }
+
+ (*alss) = NULL;
+ (*num_alss) = 0;
+
+ /* Open the alias database file - not for update. */
+ fp = startaliasent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open alias database.\n"));
+ return False;
+ }
+
+ /* iterate through all aliases. */
+ while ((als = getaliasent(fp, NULL, NULL)) != NULL)
+ {
+ if (!add_domain_alias(alss, num_alss, als))
+ {
+ DEBUG(0,("unable to add alias while enumerating\n"));
+ return False;
+ }
+ }
+
+ if ((*num_alss) != 0)
+ {
+ DEBUG(10, ("found %d user aliases:\n", (*num_alss)));
+ }
+
+ endaliasent(fp);
+ return True;
+}
+
+/***************************************************************
+ Start to enumerate the alias database list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+void *startaliasent(BOOL update)
+{
+ return aldb_ops->startaliasent(update);
+}
+
+/***************************************************************
+ End enumeration of the alias database list.
+****************************************************************/
+
+void endaliasent(void *vp)
+{
+ aldb_ops->endaliasent(vp);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the alias database list.
+ *************************************************************************/
+
+LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return aldb_ops->getaliasent(vp, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to add an entry to the alias database file.
+*************************************************************************/
+
+BOOL add_alias_entry(LOCAL_GRP *newals)
+{
+ return aldb_ops->add_alias_entry(newals);
+}
+
+/************************************************************************
+ Routine to search the alias database file for an entry matching the aliasname.
+ and then replace the entry.
+************************************************************************/
+
+BOOL mod_alias_entry(LOCAL_GRP* als)
+{
+ return aldb_ops->mod_alias_entry(als);
+}
+
+/************************************************************************
+ Routine to search alias database by name.
+*************************************************************************/
+
+LOCAL_GRP *getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return aldb_ops->getaliasnam(name, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search alias database by alias rid.
+*************************************************************************/
+
+LOCAL_GRP *getaliasrid(uint32 alias_rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return aldb_ops->getaliasrid(alias_rid, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search alias database by gid.
+*************************************************************************/
+
+LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return aldb_ops->getaliasgid(gid, mem, num_mem);
+}
+
+/*************************************************************************
+ gets an array of aliases that a user is in.
+ *************************************************************************/
+BOOL getuseraliasnam(char *user_name, LOCAL_GRP **als, int *num_alss)
+{
+ return aldb_ops->getuseraliasnam(user_name, als, num_alss);
+}
+
+/*************************************************************
+ initialises a LOCAL_GRP.
+ **************************************************************/
+
+void aldb_init_als(LOCAL_GRP *als)
+{
+ if (als == NULL) return;
+ ZERO_STRUCTP(als);
+}
+
diff --git a/source/groupdb/aliasfile.c b/source/groupdb/aliasfile.c
new file mode 100755
index 00000000000..0844a420a0a
--- /dev/null
+++ b/source/groupdb/aliasfile.c
@@ -0,0 +1,289 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#ifdef USE_SMBPASS_DB
+
+static int al_file_lock_depth = 0;
+
+static char s_readbuf[1024];
+
+/***************************************************************
+ Start to enumerate the aliasdb list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startalsfilepwent(BOOL update)
+{
+ return startfilepwent(lp_smb_alias_file(),
+ s_readbuf, sizeof(s_readbuf),
+ &al_file_lock_depth, update);
+}
+
+/***************************************************************
+ End enumeration of the aliasdb list.
+****************************************************************/
+
+static void endalsfilepwent(void *vp)
+{
+ endfilepwent(vp, &al_file_lock_depth);
+}
+
+/*************************************************************************
+ Return the current position in the aliasdb list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static SMB_BIG_UINT getalsfilepwpos(void *vp)
+{
+ return getfilepwpos(vp);
+}
+
+/*************************************************************************
+ Set the current position in the aliasdb list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static BOOL setalsfilepwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return setfilepwpos(vp, tok);
+}
+
+static BOOL make_alias_line(char *p, int max_len,
+ LOCAL_GRP *als,
+ LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ int i;
+ int len;
+ len = slprintf(p, max_len-1, "%s:%s:%d:", als->name, als->comment, als->rid);
+
+ if (len == -1)
+ {
+ DEBUG(0,("make_alias_line: cannot create entry\n"));
+ return False;
+ }
+
+ p += len;
+ max_len -= len;
+
+ if (mem == NULL || num_mem == NULL)
+ {
+ return True;
+ }
+
+ for (i = 0; i < (*num_mem); i++)
+ {
+ len = strlen((*mem)[i].name);
+ p = safe_strcpy(p, (*mem)[i].name, max_len);
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("make_alias_line: out of space for aliases!\n"));
+ return False;
+ }
+
+ max_len -= len;
+
+ if (i != (*num_mem)-1)
+ {
+ *p = ',';
+ p++;
+ max_len--;
+ }
+ }
+
+ return True;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainalias list.
+ *************************************************************************/
+static char *get_alias_members(char *p, int *num_mem, LOCAL_GRP_MEMBER **members)
+{
+ fstring name;
+
+ if (num_mem == NULL || members == NULL)
+ return NULL;
+
+ (*num_mem) = 0;
+ (*members) = NULL;
+
+ while (next_token(&p, name, ",", sizeof(fstring))) {
+ LOCAL_GRP_MEMBER *mbrs;
+ DOM_SID sid;
+ uint8 type;
+
+ if (lookup_sid(name, &sid, &type)) {
+ mbrs = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
+ (*num_mem)++;
+ } else {
+ DEBUG(0,("alias database: could not resolve alias named %s\n", name));
+ continue;
+ }
+ if (mbrs == NULL) {
+ if (*members)
+ free(*members);
+ return NULL;
+ } else
+ (*members) = mbrs;
+ fstrcpy((*members)[(*num_mem)-1].name, name);
+ (*members)[(*num_mem)-1].sid_use = type;
+ sid_copy(&(*members)[(*num_mem)-1].sid, &sid);
+ }
+ return p;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainalias list.
+ *************************************************************************/
+static LOCAL_GRP *getalsfilepwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ /* Static buffers we will return. */
+ static LOCAL_GRP al_buf;
+
+ int gidval;
+
+ pstring linebuf;
+ char *p;
+ size_t linebuf_len;
+
+ aldb_init_als(&al_buf);
+
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+ while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ {
+ /* get alias name */
+
+ p = strncpyn(al_buf.name, linebuf, sizeof(al_buf.name), ':');
+ if (p == NULL)
+ {
+ DEBUG(0, ("getalsfilepwent: malformed alias entry (no :)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* get alias comment */
+
+ p = strncpyn(al_buf.comment, p, sizeof(al_buf.comment), ':');
+ if (p == NULL)
+ {
+ DEBUG(0, ("getalsfilepwent: malformed alias entry (no :)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* Get alias gid. */
+
+ p = Atoic(p, &gidval, ":");
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("getalsfilepwent: malformed alias entry (no : after uid)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* now get the user's aliases. there are a maximum of 32 */
+
+ if (mem != NULL && num_mem != NULL)
+ {
+ (*mem) = NULL;
+ (*num_mem) = 0;
+
+ p = get_alias_members(p, num_mem, mem);
+ if (p == NULL)
+ {
+ DEBUG(0, ("getalsfilepwent: malformed alias entry (no : after members)\n"));
+ }
+ }
+
+ /* ok, set up the static data structure and return it */
+
+ al_buf.rid = pwdb_gid_to_alias_rid((gid_t)gidval);
+
+ make_alias_line(linebuf, sizeof(linebuf), &al_buf, mem, num_mem);
+ DEBUG(10,("line: '%s'\n", linebuf));
+
+ return &al_buf;
+ }
+
+ DEBUG(5,("getalsfilepwent: end of file reached.\n"));
+ return NULL;
+}
+
+/************************************************************************
+ Routine to add an entry to the aliasdb file.
+*************************************************************************/
+
+static BOOL add_alsfileals_entry(LOCAL_GRP *newals)
+{
+ DEBUG(0, ("add_alsfileals_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the aliasdb file for an entry matching the aliasname.
+ and then modify its alias entry. We can't use the startalspwent()/
+ getalspwent()/endalspwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out alias or NO PASS
+************************************************************************/
+
+static BOOL mod_alsfileals_entry(LOCAL_GRP* als)
+{
+ DEBUG(0, ("mod_alsfileals_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+
+static struct aliasdb_ops file_ops =
+{
+ startalsfilepwent,
+ endalsfilepwent,
+ getalsfilepwpos,
+ setalsfilepwpos,
+
+ iterate_getaliasnam, /* In aliasdb.c */
+ iterate_getaliasgid, /* In aliasdb.c */
+ iterate_getaliasrid, /* In aliasdb.c */
+ getalsfilepwent,
+
+ add_alsfileals_entry,
+ mod_alsfileals_entry,
+
+ iterate_getuseraliasnam /* in aliasdb.c */
+};
+
+struct aliasdb_ops *file_initialise_alias_db(void)
+{
+ return &file_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void als_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/groupdb/groupdb.c b/source/groupdb/groupdb.c
new file mode 100755
index 00000000000..3bbc8f66d7c
--- /dev/null
+++ b/source/groupdb/groupdb.c
@@ -0,0 +1,384 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ * NOTE. All these functions are abstracted into a structure
+ * that points to the correct function for the selected database. JRA.
+ */
+
+static struct groupdb_ops *gpdb_ops;
+
+/***************************************************************
+ Initialise the group db operations.
+***************************************************************/
+
+BOOL initialise_group_db(void)
+{
+ if (gpdb_ops)
+ {
+ return True;
+ }
+
+#ifdef WITH_NISPLUS
+ gpdb_ops = nisplus_initialise_group_db();
+#elif defined(WITH_LDAP)
+ gpdb_ops = ldap_initialise_group_db();
+#else
+ gpdb_ops = file_initialise_group_db();
+#endif
+
+ return (gpdb_ops != NULL);
+}
+
+/*
+ * Functions that return/manipulate a DOMAIN_GRP.
+ */
+
+/************************************************************************
+ Utility function to search group database by gid: the DOMAIN_GRP
+ structure does not have a gid member, so we have to convert here
+ from gid to group rid.
+*************************************************************************/
+DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ return iterate_getgrouprid(pwdb_gid_to_group_rid(gid), mem, num_mem);
+}
+
+/************************************************************************
+ Utility function to search group database by rid. use this if your database
+ does not have search facilities.
+*************************************************************************/
+DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ DOMAIN_GRP *grp = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by rid: 0x%x\n", rid));
+
+ /* Open the group database file - not for update. */
+ fp = startgroupent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open group database.\n"));
+ return NULL;
+ }
+
+ while ((grp = getgroupent(fp, mem, num_mem)) != NULL && grp->rid != rid)
+ {
+ }
+
+ if (grp != NULL)
+ {
+ DEBUG(10, ("found group %s by rid: 0x%x\n", grp->name, rid));
+ }
+
+ endgroupent(fp);
+ return grp;
+}
+
+/************************************************************************
+ Utility function to search group database by name. use this if your database
+ does not have search facilities.
+*************************************************************************/
+DOMAIN_GRP *iterate_getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ DOMAIN_GRP *grp = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by name: %s\n", name));
+
+ /* Open the group database file - not for update. */
+ fp = startgroupent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open group database.\n"));
+ return NULL;
+ }
+
+ while ((grp = getgroupent(fp, mem, num_mem)) != NULL && !strequal(grp->name, name))
+ {
+ }
+
+ if (grp != NULL)
+ {
+ DEBUG(10, ("found by name: %s\n", name));
+ }
+
+ endgroupent(fp);
+ return grp;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomaingroup list.
+ *************************************************************************/
+BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
+{
+ DOMAIN_GRP *tgrps;
+
+ if (grps == NULL || num_grps == NULL || grp == NULL)
+ return False;
+
+ tgrps = (DOMAIN_GRP *)Realloc((*grps), ((*num_grps)+1) * sizeof(DOMAIN_GRP));
+ if (tgrps == NULL) {
+ if (*grps)
+ free(*grps);
+ return False;
+ } else
+ (*grps) = tgrps;
+
+ DEBUG(10,("adding group %s(%s)\n", grp->name, grp->comment));
+
+ fstrcpy((*grps)[(*num_grps)].name , grp->name);
+ fstrcpy((*grps)[(*num_grps)].comment, grp->comment);
+ (*grps)[(*num_grps)].attr = grp->attr;
+ (*grps)[(*num_grps)].rid = grp->rid ;
+
+ (*num_grps)++;
+
+ return True;
+}
+
+/*************************************************************************
+ checks to see if a user is a member of a domain group
+ *************************************************************************/
+static BOOL user_is_member(char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
+{
+ int i;
+ for (i = 0; i < num_mem; i++)
+ {
+ DEBUG(10,("searching against user %s...\n", mem[i].name));
+ if (strequal(mem[i].name, user_name))
+ {
+ DEBUG(10,("searching for user %s: found\n", user_name));
+ return True;
+ }
+ }
+ DEBUG(10,("searching for user %s: not found\n", user_name));
+ return False;
+}
+
+/*************************************************************************
+ gets an array of groups that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL iterate_getusergroupsnam(char *user_name, DOMAIN_GRP **grps, int *num_grps)
+{
+ DOMAIN_GRP *grp;
+ DOMAIN_GRP_MEMBER *mem = NULL;
+ int num_mem = 0;
+ void *fp = NULL;
+
+ DEBUG(10, ("search for usergroups by name: %s\n", user_name));
+
+ if (user_name == NULL || grp == NULL || num_grps == NULL)
+ {
+ return False;
+ }
+
+ (*grps) = NULL;
+ (*num_grps) = 0;
+
+ /* Open the group database file - not for update. */
+ fp = startgroupent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open group database.\n"));
+ return False;
+ }
+
+ /* iterate through all groups. search members for required user */
+ while ((grp = getgroupent(fp, &mem, &num_mem)) != NULL)
+ {
+ DEBUG(5,("group name %s members: %d\n", grp->name, num_mem));
+ if (num_mem != 0 && mem != NULL)
+ {
+ BOOL ret = True;
+ if (user_is_member(user_name, mem, num_mem))
+ {
+ ret = add_domain_group(grps, num_grps, grp);
+ }
+
+ free(mem);
+ mem = NULL;
+ num_mem = 0;
+
+ if (!ret)
+ {
+ (*num_grps) = 0;
+ break;
+ }
+ }
+ }
+
+ if ((*num_grps) != 0)
+ {
+ DEBUG(10, ("found %d user groups:\n", (*num_grps)));
+ }
+
+ endgroupent(fp);
+ return True;
+}
+
+/*************************************************************************
+ gets an array of groups that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps)
+{
+ DOMAIN_GRP *grp;
+ void *fp = NULL;
+
+ DEBUG(10, ("enum user groups\n"));
+
+ if (grp == NULL || num_grps == NULL)
+ {
+ return False;
+ }
+
+ (*grps) = NULL;
+ (*num_grps) = 0;
+
+ /* Open the group database file - not for update. */
+ fp = startgroupent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open group database.\n"));
+ return False;
+ }
+
+ /* iterate through all groups. */
+ while ((grp = getgroupent(fp, NULL, NULL)) != NULL)
+ {
+ if (!add_domain_group(grps, num_grps, grp))
+ {
+ DEBUG(0,("unable to add group while enumerating\n"));
+ return False;
+ }
+ }
+
+ if ((*num_grps) != 0)
+ {
+ DEBUG(10, ("found %d user groups:\n", (*num_grps)));
+ }
+
+ endgroupent(fp);
+ return True;
+}
+
+/***************************************************************
+ Start to enumerate the group database list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+void *startgroupent(BOOL update)
+{
+ return gpdb_ops->startgroupent(update);
+}
+
+/***************************************************************
+ End enumeration of the group database list.
+****************************************************************/
+
+void endgroupent(void *vp)
+{
+ gpdb_ops->endgroupent(vp);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the group database list.
+ *************************************************************************/
+
+DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ return gpdb_ops->getgroupent(vp, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to add an entry to the group database file.
+*************************************************************************/
+
+BOOL add_group_entry(DOMAIN_GRP *newgrp)
+{
+ return gpdb_ops->add_group_entry(newgrp);
+}
+
+/************************************************************************
+ Routine to search the group database file for an entry matching the groupname.
+ and then replace the entry.
+************************************************************************/
+
+BOOL mod_group_entry(DOMAIN_GRP* grp)
+{
+ return gpdb_ops->mod_group_entry(grp);
+}
+
+/************************************************************************
+ Routine to search group database by name.
+*************************************************************************/
+
+DOMAIN_GRP *getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ return gpdb_ops->getgroupnam(name, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search group database by group rid.
+*************************************************************************/
+
+DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ return gpdb_ops->getgrouprid(group_rid, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search group database by gid.
+*************************************************************************/
+
+DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ return gpdb_ops->getgroupgid(gid, mem, num_mem);
+}
+
+/*************************************************************************
+ gets an array of groups that a user is in.
+ *************************************************************************/
+BOOL getusergroupsnam(char *user_name, DOMAIN_GRP **grp, int *num_grps)
+{
+ return gpdb_ops->getusergroupsnam(user_name, grp, num_grps);
+}
+
+/*************************************************************
+ initialises a DOMAIN_GRP.
+ **************************************************************/
+
+void gpdb_init_grp(DOMAIN_GRP *grp)
+{
+ if (grp == NULL) return;
+ ZERO_STRUCTP(grp);
+}
+
diff --git a/source/groupdb/groupfile.c b/source/groupdb/groupfile.c
new file mode 100755
index 00000000000..7f3cec5c180
--- /dev/null
+++ b/source/groupdb/groupfile.c
@@ -0,0 +1,285 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#ifdef USE_SMBPASS_DB
+
+static int gp_file_lock_depth = 0;
+
+static char s_readbuf[1024];
+
+/***************************************************************
+ Start to enumerate the grppasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startgrpfilepwent(BOOL update)
+{
+ return startfilepwent(lp_smb_group_file(),
+ s_readbuf, sizeof(s_readbuf),
+ &gp_file_lock_depth, update);
+}
+
+/***************************************************************
+ End enumeration of the grppasswd list.
+****************************************************************/
+
+static void endgrpfilepwent(void *vp)
+{
+ endfilepwent(vp, &gp_file_lock_depth);
+}
+
+/*************************************************************************
+ Return the current position in the grppasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static SMB_BIG_UINT getgrpfilepwpos(void *vp)
+{
+ return getfilepwpos(vp);
+}
+
+/*************************************************************************
+ Set the current position in the grppasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static BOOL setgrpfilepwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return setfilepwpos(vp, tok);
+}
+
+static BOOL make_group_line(char *p, int max_len,
+ DOMAIN_GRP *grp,
+ DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ int i;
+ int len;
+ len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
+
+ if (len == -1)
+ {
+ DEBUG(0,("make_group_line: cannot create entry\n"));
+ return False;
+ }
+
+ p += len;
+ max_len -= len;
+
+ if (mem == NULL || num_mem == NULL)
+ {
+ return True;
+ }
+
+ for (i = 0; i < (*num_mem); i++)
+ {
+ len = strlen((*mem)[i].name);
+ p = safe_strcpy(p, (*mem)[i].name, max_len);
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("make_group_line: out of space for groups!\n"));
+ return False;
+ }
+
+ max_len -= len;
+
+ if (i != (*num_mem)-1)
+ {
+ *p = ',';
+ p++;
+ max_len--;
+ }
+ }
+
+ return True;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomaingroup list.
+ *************************************************************************/
+static char *get_group_members(char *p, int *num_mem, DOMAIN_GRP_MEMBER **members)
+{
+ fstring name;
+
+ if (num_mem == NULL || members == NULL)
+ {
+ return NULL;
+ }
+
+ (*num_mem) = 0;
+ (*members) = NULL;
+
+ while (next_token(&p, name, ",", sizeof(fstring)))
+ {
+ DOMAIN_GRP_MEMBER *mbrs;
+
+ mbrs = (DOMAIN_GRP_MEMBER *)Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
+ if (mbrs == NULL) {
+ if (*members)
+ free(*members);
+ return NULL;
+ } else
+ (*members) = mbrs;
+ fstrcpy((*members)[(*num_mem)].name, name);
+ (*members)[(*num_mem)].attr = 0x07;
+ (*num_mem)++;
+ }
+ return p;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomaingroup list.
+ *************************************************************************/
+static DOMAIN_GRP *getgrpfilepwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ /* Static buffers we will return. */
+ static DOMAIN_GRP gp_buf;
+
+ int gidval;
+
+ pstring linebuf;
+ char *p;
+ size_t linebuf_len;
+
+ gpdb_init_grp(&gp_buf);
+
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+ while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ {
+ /* get group name */
+
+ p = strncpyn(gp_buf.name, linebuf, sizeof(gp_buf.name), ':');
+ if (p == NULL)
+ {
+ DEBUG(0, ("getgrpfilepwent: malformed group entry (no :)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* get group comment */
+
+ p = strncpyn(gp_buf.comment, p, sizeof(gp_buf.comment), ':');
+ if (p == NULL)
+ {
+ DEBUG(0, ("getgrpfilepwent: malformed group entry (no :)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* Get group gid. */
+
+ p = Atoic(p, &gidval, ":");
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("getgrpfilepwent: malformed group entry (no : after uid)\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* now get the user's groups. there are a maximum of 32 */
+
+ if (mem != NULL && num_mem != NULL)
+ {
+ (*mem) = NULL;
+ (*num_mem) = 0;
+
+ p = get_group_members(p, num_mem, mem);
+ if (p == NULL)
+ {
+ DEBUG(0, ("getgrpfilepwent: malformed group entry (no : after members)\n"));
+ }
+ }
+
+ /* ok, set up the static data structure and return it */
+
+ gp_buf.rid = pwdb_gid_to_group_rid((gid_t)gidval);
+ gp_buf.attr = 0x07;
+
+ make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
+ DEBUG(10,("line: '%s'\n", linebuf));
+
+ return &gp_buf;
+ }
+
+ DEBUG(5,("getgrpfilepwent: end of file reached.\n"));
+ return NULL;
+}
+
+/************************************************************************
+ Routine to add an entry to the grppasswd file.
+*************************************************************************/
+
+static BOOL add_grpfilegrp_entry(DOMAIN_GRP *newgrp)
+{
+ DEBUG(0, ("add_grpfilegrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the grppasswd file for an entry matching the groupname.
+ and then modify its group entry. We can't use the startgrppwent()/
+ getgrppwent()/endgrppwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out group or NO PASS
+************************************************************************/
+
+static BOOL mod_grpfilegrp_entry(DOMAIN_GRP* grp)
+{
+ DEBUG(0, ("mod_grpfilegrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+
+static struct groupdb_ops file_ops =
+{
+ startgrpfilepwent,
+ endgrpfilepwent,
+ getgrpfilepwpos,
+ setgrpfilepwpos,
+
+ iterate_getgroupnam, /* In groupdb.c */
+ iterate_getgroupgid, /* In groupdb.c */
+ iterate_getgrouprid, /* In groupdb.c */
+ getgrpfilepwent,
+
+ add_grpfilegrp_entry,
+ mod_grpfilegrp_entry,
+
+ iterate_getusergroupsnam /* in groupdb.c */
+};
+
+struct groupdb_ops *file_initialise_group_db(void)
+{
+ return &file_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void grppass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
deleted file mode 100644
index d476f5cac13..00000000000
--- a/source/groupdb/mapping.c
+++ /dev/null
@@ -1,1438 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2001.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-static TDB_CONTEXT *tdb; /* used for driver files */
-
-#define DATABASE_VERSION_V1 1 /* native byte format. */
-#define DATABASE_VERSION_V2 2 /* le format. */
-
-#define GROUP_PREFIX "UNIXGROUP/"
-
-/* Alias memberships are stored reverse, as memberships. The performance
- * critical operation is to determine the aliases a SID is member of, not
- * listing alias members. So we store a list of alias SIDs a SID is member of
- * hanging of the member as key.
- */
-#define MEMBEROF_PREFIX "MEMBEROF/"
-
-/****************************************************************************
-dump the mapping group mapping to a text file
-****************************************************************************/
-char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
-{
- static fstring group_type;
-
- switch(name_use) {
- case SID_NAME_USER:
- fstrcpy(group_type,"User");
- break;
- case SID_NAME_DOM_GRP:
- fstrcpy(group_type,"Domain group");
- break;
- case SID_NAME_DOMAIN:
- fstrcpy(group_type,"Domain");
- break;
- case SID_NAME_ALIAS:
- fstrcpy(group_type,"Local group");
- break;
- case SID_NAME_WKN_GRP:
- fstrcpy(group_type,"Builtin group");
- break;
- case SID_NAME_DELETED:
- fstrcpy(group_type,"Deleted");
- break;
- case SID_NAME_INVALID:
- fstrcpy(group_type,"Invalid");
- break;
- case SID_NAME_UNKNOWN:
- default:
- fstrcpy(group_type,"Unknown type");
- break;
- }
-
- fstrcpy(group, group_type);
- return group_type;
-}
-
-/****************************************************************************
-initialise first time the mapping list - called from init_group_mapping()
-****************************************************************************/
-static BOOL default_group_mapping(void)
-{
- DOM_SID sid_admins;
- DOM_SID sid_users;
- DOM_SID sid_guests;
- fstring str_admins;
- fstring str_users;
- fstring str_guests;
-
- /* Add the Wellknown groups */
-
- add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", "");
- add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", "");
- add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", "");
- add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", "");
- add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", "");
- add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", "");
- add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", "");
- add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", "");
- add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", "");
-
- /* Add the defaults domain groups */
-
- sid_copy(&sid_admins, get_global_sam_sid());
- sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
- sid_to_string(str_admins, &sid_admins);
- add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "");
-
- sid_copy(&sid_users, get_global_sam_sid());
- sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS);
- sid_to_string(str_users, &sid_users);
- add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "");
-
- sid_copy(&sid_guests, get_global_sam_sid());
- sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
- sid_to_string(str_guests, &sid_guests);
- add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "");
-
- return True;
-}
-
-/****************************************************************************
- Open the group mapping tdb.
-****************************************************************************/
-
-static BOOL init_group_mapping(void)
-{
- static pid_t local_pid;
- const char *vstring = "INFO/version";
- int32 vers_id;
-
- if (tdb && local_pid == sys_getpid())
- return True;
- tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open group mapping database\n"));
- return False;
- }
-
- local_pid = sys_getpid();
-
- /* handle a Samba upgrade */
- tdb_lock_bystring(tdb, vstring, 0);
-
- /* Cope with byte-reversed older versions of the db. */
- vers_id = tdb_fetch_int32(tdb, vstring);
- if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
- /* Written on a bigendian machine with old fetch_int code. Save as le. */
- tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
- vers_id = DATABASE_VERSION_V2;
- }
-
- if (vers_id != DATABASE_VERSION_V2) {
- tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
- }
-
- tdb_unlock_bystring(tdb, vstring);
-
- /* write a list of default groups */
- if(!default_group_mapping())
- return False;
-
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
-{
- TDB_DATA kbuf, dbuf;
- pstring key, buf;
- fstring string_sid="";
- int len;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- sid_to_string(string_sid, &map->sid);
-
- len = tdb_pack(buf, sizeof(buf), "ddff",
- map->gid, map->sid_name_use, map->nt_name, map->comment);
-
- if (len > sizeof(buf))
- return False;
-
- slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- dbuf.dsize = len;
- dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False;
-
- return True;
-}
-
-/****************************************************************************
-initialise first time the mapping list
-****************************************************************************/
-BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
-{
- GROUP_MAP map;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- map.gid=gid;
- if (!string_to_sid(&map.sid, sid)) {
- DEBUG(0, ("string_to_sid failed: %s", sid));
- return False;
- }
-
- map.sid_name_use=sid_name_use;
- fstrcpy(map.nt_name, nt_name);
- fstrcpy(map.comment, comment);
-
- return pdb_add_group_mapping_entry(&map);
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
-{
- TDB_DATA kbuf, dbuf;
- pstring key;
- fstring string_sid;
- int ret = 0;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- /* the key is the SID, retrieving is direct */
-
- sid_to_string(string_sid, &sid);
- slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- return False;
-
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
-
- SAFE_FREE(dbuf.dptr);
-
- if ( ret == -1 ) {
- DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n"));
- return False;
- }
-
- sid_copy(&map->sid, &sid);
-
- return True;
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
-{
- TDB_DATA kbuf, dbuf, newkey;
- fstring string_sid;
- int ret;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- /* we need to enumerate the TDB to find the GID */
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-
- string_to_sid(&map->sid, string_sid);
-
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
-
- SAFE_FREE(dbuf.dptr);
-
- if ( ret == -1 ) {
- DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n"));
- return False;
- }
-
- if (gid==map->gid) {
- SAFE_FREE(kbuf.dptr);
- return True;
- }
- }
-
- return False;
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
-{
- TDB_DATA kbuf, dbuf, newkey;
- fstring string_sid;
- int ret;
-
- if(!init_group_mapping()) {
- DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n"));
- return(False);
- }
-
- /* we need to enumerate the TDB to find the name */
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-
- string_to_sid(&map->sid, string_sid);
-
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
-
- SAFE_FREE(dbuf.dptr);
-
- if ( ret == -1 ) {
- DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n"));
- return False;
- }
-
- if (StrCaseCmp(name, map->nt_name)==0) {
- SAFE_FREE(kbuf.dptr);
- return True;
- }
- }
-
- return False;
-}
-
-/****************************************************************************
- Remove a group mapping entry.
-****************************************************************************/
-
-static BOOL group_map_remove(const DOM_SID *sid)
-{
- TDB_DATA kbuf, dbuf;
- pstring key;
- fstring string_sid;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- /* the key is the SID, retrieving is direct */
-
- sid_to_string(string_sid, sid);
- slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- return False;
-
- SAFE_FREE(dbuf.dptr);
-
- if(tdb_delete(tdb, kbuf) != TDB_SUCCESS)
- return False;
-
- return True;
-}
-
-/****************************************************************************
- Enumerate the group mapping.
-****************************************************************************/
-
-static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
- int *num_entries, BOOL unix_only)
-{
- TDB_DATA kbuf, dbuf, newkey;
- fstring string_sid;
- fstring group_type;
- GROUP_MAP map;
- GROUP_MAP *mapt;
- int ret;
- int entries=0;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- *num_entries=0;
- *rmap=NULL;
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
- &map.gid, &map.sid_name_use, &map.nt_name, &map.comment);
-
- SAFE_FREE(dbuf.dptr);
-
- if ( ret == -1 ) {
- DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
- continue;
- }
-
- /* list only the type or everything if UNKNOWN */
- if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) {
- DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
- continue;
- }
-
- if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
- DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
- continue;
- }
-
- string_to_sid(&map.sid, string_sid);
-
- decode_sid_name_use(group_type, map.sid_name_use);
- DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
-
- mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
- if (!mapt) {
- DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
- SAFE_FREE(*rmap);
- return False;
- }
- else
- (*rmap) = mapt;
-
- mapt[entries].gid = map.gid;
- sid_copy( &mapt[entries].sid, &map.sid);
- mapt[entries].sid_name_use = map.sid_name_use;
- fstrcpy(mapt[entries].nt_name, map.nt_name);
- fstrcpy(mapt[entries].comment, map.comment);
-
- entries++;
-
- }
-
- *num_entries=entries;
-
- return True;
-}
-
-/* This operation happens on session setup, so it should better be fast. We
- * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
-
-static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
-{
- fstring key, string_sid;
- TDB_DATA kbuf, dbuf;
- const char *p;
-
- *num = 0;
- *sids = NULL;
-
- if (!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- sid_to_string(string_sid, sid);
- slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
-
- dbuf = tdb_fetch(tdb, kbuf);
-
- if (dbuf.dptr == NULL) {
- return NT_STATUS_OK;
- }
-
- p = dbuf.dptr;
-
- while (next_token(&p, string_sid, " ", sizeof(string_sid))) {
-
- DOM_SID alias;
-
- if (!string_to_sid(&alias, string_sid))
- continue;
-
- add_sid_to_array(&alias, sids, num);
-
- if (sids == NULL)
- return NT_STATUS_NO_MEMORY;
- }
-
- SAFE_FREE(dbuf.dptr);
- return NT_STATUS_OK;
-}
-
-static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
-{
- DOM_SID *sids;
- int i, num;
-
- /* This feels the wrong way round, but the on-disk data structure
- * dictates it this way. */
- if (!NT_STATUS_IS_OK(alias_memberships(member, &sids, &num)))
- return False;
-
- for (i=0; i<num; i++) {
- if (sid_compare(alias, &sids[i]) == 0) {
- SAFE_FREE(sids);
- return True;
- }
- }
- SAFE_FREE(sids);
- return False;
-}
-
-static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
-{
- GROUP_MAP map;
- TDB_DATA kbuf, dbuf;
- pstring key;
- fstring string_sid;
- char *new_memberstring;
- int result;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (!get_group_map_from_sid(*alias, &map))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- if ( (map.sid_name_use != SID_NAME_ALIAS) &&
- (map.sid_name_use != SID_NAME_WKN_GRP) )
- return NT_STATUS_NO_SUCH_ALIAS;
-
- if (is_aliasmem(alias, member))
- return NT_STATUS_MEMBER_IN_ALIAS;
-
- sid_to_string(string_sid, member);
- slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
-
- dbuf = tdb_fetch(tdb, kbuf);
-
- sid_to_string(string_sid, alias);
-
- if (dbuf.dptr != NULL) {
- asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr),
- string_sid);
- } else {
- new_memberstring = strdup(string_sid);
- }
-
- if (new_memberstring == NULL)
- return NT_STATUS_NO_MEMORY;
-
- SAFE_FREE(dbuf.dptr);
- dbuf.dsize = strlen(new_memberstring)+1;
- dbuf.dptr = new_memberstring;
-
- result = tdb_store(tdb, kbuf, dbuf, 0);
-
- SAFE_FREE(new_memberstring);
-
- return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED);
-}
-
-struct aliasmem_closure {
- const DOM_SID *alias;
- DOM_SID **sids;
- int *num;
-};
-
-static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
- void *state)
-{
- struct aliasmem_closure *closure = (struct aliasmem_closure *)state;
- const char *p;
- fstring alias_string;
-
- if (strncmp(key.dptr, MEMBEROF_PREFIX,
- strlen(MEMBEROF_PREFIX)) != 0)
- return 0;
-
- p = data.dptr;
-
- while (next_token(&p, alias_string, " ", sizeof(alias_string))) {
-
- DOM_SID alias, member;
- const char *member_string;
-
-
- if (!string_to_sid(&alias, alias_string))
- continue;
-
- if (sid_compare(closure->alias, &alias) != 0)
- continue;
-
- /* Ok, we found the alias we're looking for in the membership
- * list currently scanned. The key represents the alias
- * member. Add that. */
-
- member_string = strchr(key.dptr, '/');
-
- /* Above we tested for MEMBEROF_PREFIX which includes the
- * slash. */
-
- SMB_ASSERT(member_string != NULL);
- member_string += 1;
-
- if (!string_to_sid(&member, member_string))
- continue;
-
- add_sid_to_array(&member, closure->sids, closure->num);
- }
-
- return 0;
-}
-
-static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num)
-{
- GROUP_MAP map;
- struct aliasmem_closure closure;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (!get_group_map_from_sid(*alias, &map))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- if ( (map.sid_name_use != SID_NAME_ALIAS) &&
- (map.sid_name_use != SID_NAME_WKN_GRP) )
- return NT_STATUS_NO_SUCH_ALIAS;
-
- *sids = NULL;
- *num = 0;
-
- closure.alias = alias;
- closure.sids = sids;
- closure.num = num;
-
- tdb_traverse(tdb, collect_aliasmem, &closure);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
-{
- NTSTATUS result;
- DOM_SID *sids;
- int i, num;
- BOOL found = False;
- char *member_string;
- TDB_DATA kbuf, dbuf;
- pstring key;
- fstring sid_string;
-
- result = alias_memberships(member, &sids, &num);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- for (i=0; i<num; i++) {
- if (sid_compare(&sids[i], alias) == 0) {
- found = True;
- break;
- }
- }
-
- if (!found) {
- SAFE_FREE(sids);
- return NT_STATUS_MEMBER_NOT_IN_ALIAS;
- }
-
- if (i < num)
- sids[i] = sids[num-1];
-
- num -= 1;
-
- sid_to_string(sid_string, member);
- slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_string);
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
-
- if (num == 0)
- return tdb_delete(tdb, kbuf) == 0 ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-
- member_string = strdup("");
-
- if (member_string == NULL) {
- SAFE_FREE(sids);
- return NT_STATUS_NO_MEMORY;
- }
-
- for (i=0; i<num; i++) {
- char *s = member_string;
-
- sid_to_string(sid_string, &sids[i]);
- asprintf(&member_string, "%s %s", s, sid_string);
-
- SAFE_FREE(s);
- if (member_string == NULL) {
- SAFE_FREE(sids);
- return NT_STATUS_NO_MEMORY;
- }
- }
-
- dbuf.dsize = strlen(member_string)+1;
- dbuf.dptr = member_string;
-
- result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ?
- NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
-
- SAFE_FREE(sids);
- SAFE_FREE(member_string);
-
- return result;
-}
-
-/*
- *
- * High level functions
- * better to use them than the lower ones.
- *
- * we are checking if the group is in the mapping file
- * and if the group is an existing unix group
- *
- */
-
-/* get a domain group from it's SID */
-
-BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
-{
- struct group *grp;
- BOOL ret;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- DEBUG(10, ("get_domain_group_from_sid\n"));
-
- /* if the group is NOT in the database, it CAN NOT be a domain group */
-
- become_root();
- ret = pdb_getgrsid(map, sid);
- unbecome_root();
-
- if ( !ret )
- return False;
-
- DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
-
- /* if it's not a domain group, continue */
- if (map->sid_name_use!=SID_NAME_DOM_GRP) {
- return False;
- }
-
- DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
-
- if (map->gid==-1) {
- return False;
- }
-
- DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
-
- grp = getgrgid(map->gid);
- if ( !grp ) {
- DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
- return False;
- }
-
- DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
-
- return True;
-}
-
-
-/* get a local (alias) group from it's SID */
-
-BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
-{
- BOOL ret;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- /* The group is in the mapping table */
- become_root();
- ret = pdb_getgrsid(map, *sid);
- unbecome_root();
-
- if ( !ret )
- return False;
-
- if ( ( (map->sid_name_use != SID_NAME_ALIAS) &&
- (map->sid_name_use != SID_NAME_WKN_GRP) )
- || (map->gid == -1)
- || (getgrgid(map->gid) == NULL) )
- {
- return False;
- }
-
-#if 1 /* JERRY */
- /* local groups only exist in the group mapping DB so this
- is not necessary */
-
- else {
- /* the group isn't in the mapping table.
- * make one based on the unix information */
- uint32 alias_rid;
- struct group *grp;
-
- sid_peek_rid(sid, &alias_rid);
- map->gid=pdb_group_rid_to_gid(alias_rid);
-
- grp = getgrgid(map->gid);
- if ( !grp ) {
- DEBUG(3,("get_local_group_from_sid: No unix group for [%ul]\n", map->gid));
- return False;
- }
-
- map->sid_name_use=SID_NAME_ALIAS;
-
- fstrcpy(map->nt_name, grp->gr_name);
- fstrcpy(map->comment, "Local Unix Group");
-
- sid_copy(&map->sid, sid);
- }
-#endif
-
- return True;
-}
-
-/* get a builtin group from it's SID */
-
-BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
-{
- struct group *grp;
- BOOL ret;
-
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- become_root();
- ret = pdb_getgrsid(map, *sid);
- unbecome_root();
-
- if ( !ret )
- return False;
-
- if (map->sid_name_use!=SID_NAME_WKN_GRP) {
- return False;
- }
-
- if (map->gid==-1) {
- return False;
- }
-
- if ( (grp=getgrgid(map->gid)) == NULL) {
- return False;
- }
-
- return True;
-}
-
-
-
-/****************************************************************************
-Returns a GROUP_MAP struct based on the gid.
-****************************************************************************/
-BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
-{
- struct group *grp;
- BOOL ret;
-
- if(!init_group_mapping()) {
- DEBUG(0,("failed to initialize group mapping\n"));
- return(False);
- }
-
- if ( (grp=getgrgid(gid)) == NULL)
- return False;
-
- /*
- * make a group map from scratch if doesn't exist.
- */
-
- become_root();
- ret = pdb_getgrgid(map, gid);
- unbecome_root();
-
- if ( !ret ) {
- map->gid=gid;
- map->sid_name_use=SID_NAME_ALIAS;
-
- /* interim solution until we have a last RID allocated */
-
- sid_copy(&map->sid, get_global_sam_sid());
- sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid));
-
- fstrcpy(map->nt_name, grp->gr_name);
- fstrcpy(map->comment, "Local Unix Group");
- }
-
- return True;
-}
-
-/****************************************************************************
- Create a UNIX group on demand.
-****************************************************************************/
-
-int smb_create_group(char *unix_group, gid_t *new_gid)
-{
- pstring add_script;
- int ret = -1;
- int fd = 0;
-
- *new_gid = 0;
-
- /* defer to scripts */
-
- if ( *lp_addgroup_script() ) {
- pstrcpy(add_script, lp_addgroup_script());
- pstring_sub(add_script, "%g", unix_group);
- ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL);
- DEBUG(3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
- if (ret != 0)
- return ret;
-
- if (fd != 0) {
- fstring output;
-
- *new_gid = 0;
- if (read(fd, output, sizeof(output)) > 0) {
- *new_gid = (gid_t)strtoul(output, NULL, 10);
- }
-
- close(fd);
- }
-
- } else if ( winbind_create_group( unix_group, NULL ) ) {
-
- DEBUG(3,("smb_create_group: winbindd created the group (%s)\n",
- unix_group));
- ret = 0;
- }
-
- if (*new_gid == 0) {
- struct group *grp = getgrnam(unix_group);
-
- if (grp != NULL)
- *new_gid = grp->gr_gid;
- }
-
- return ret;
-}
-
-/****************************************************************************
- Delete a UNIX group on demand.
-****************************************************************************/
-
-int smb_delete_group(char *unix_group)
-{
- pstring del_script;
- int ret;
-
- /* defer to scripts */
-
- if ( *lp_delgroup_script() ) {
- pstrcpy(del_script, lp_delgroup_script());
- pstring_sub(del_script, "%g", unix_group);
- ret = smbrun(del_script,NULL);
- DEBUG(3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
- return ret;
- }
-
- if ( winbind_delete_group( unix_group ) ) {
- DEBUG(3,("smb_delete_group: winbindd deleted the group (%s)\n",
- unix_group));
- return 0;
- }
-
- return -1;
-}
-
-/****************************************************************************
- Set a user's primary UNIX group.
-****************************************************************************/
-int smb_set_primary_group(const char *unix_group, const char* unix_user)
-{
- pstring add_script;
- int ret;
-
- /* defer to scripts */
-
- if ( *lp_setprimarygroup_script() ) {
- pstrcpy(add_script, lp_setprimarygroup_script());
- all_string_sub(add_script, "%g", unix_group, sizeof(add_script));
- all_string_sub(add_script, "%u", unix_user, sizeof(add_script));
- ret = smbrun(add_script,NULL);
- DEBUG(3,("smb_set_primary_group: "
- "Running the command `%s' gave %d\n",add_script,ret));
- return ret;
- }
-
- /* Try winbindd */
-
- if ( winbind_set_user_primary_group( unix_user, unix_group ) ) {
- DEBUG(3,("smb_delete_group: winbindd set the group (%s) as the primary group for user (%s)\n",
- unix_group, unix_user));
- return 0;
- }
-
- return -1;
-}
-
-/****************************************************************************
- Add a user to a UNIX group.
-****************************************************************************/
-
-int smb_add_user_group(char *unix_group, char *unix_user)
-{
- pstring add_script;
- int ret;
-
- /* defer to scripts */
-
- if ( *lp_addusertogroup_script() ) {
- pstrcpy(add_script, lp_addusertogroup_script());
- pstring_sub(add_script, "%g", unix_group);
- pstring_sub(add_script, "%u", unix_user);
- ret = smbrun(add_script,NULL);
- DEBUG(3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
- return ret;
- }
-
- /* Try winbindd */
-
- if ( winbind_add_user_to_group( unix_user, unix_group ) ) {
- DEBUG(3,("smb_delete_group: winbindd added user (%s) to the group (%s)\n",
- unix_user, unix_group));
- return -1;
- }
-
- return -1;
-}
-
-/****************************************************************************
- Delete a user from a UNIX group
-****************************************************************************/
-
-int smb_delete_user_group(const char *unix_group, const char *unix_user)
-{
- pstring del_script;
- int ret;
-
- /* defer to scripts */
-
- if ( *lp_deluserfromgroup_script() ) {
- pstrcpy(del_script, lp_deluserfromgroup_script());
- pstring_sub(del_script, "%g", unix_group);
- pstring_sub(del_script, "%u", unix_user);
- ret = smbrun(del_script,NULL);
- DEBUG(3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
- return ret;
- }
-
- /* Try winbindd */
-
- if ( winbind_remove_user_from_group( unix_user, unix_group ) ) {
- DEBUG(3,("smb_delete_group: winbindd removed user (%s) from the group (%s)\n",
- unix_user, unix_group));
- return 0;
- }
-
- return -1;
-}
-
-
-NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid)
-{
- return get_group_map_from_sid(sid, map) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid)
-{
- return get_group_map_from_gid(gid, map) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- const char *name)
-{
- return get_group_map_from_ntname(name, map) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_INSERT) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_REPLACE) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
- DOM_SID sid)
-{
- return group_map_remove(&sid) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only)
-{
- return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_find_alias(struct pdb_methods *methods,
- const char *name, DOM_SID *sid)
-{
- GROUP_MAP map;
-
- if (!pdb_getgrnam(&map, name))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- if ((map.sid_name_use != SID_NAME_WKN_GRP) &&
- (map.sid_name_use != SID_NAME_ALIAS))
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- sid_copy(sid, &map.sid);
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
- const char *name, uint32 *rid)
-{
- DOM_SID sid;
- enum SID_NAME_USE type;
- uint32 new_rid;
- gid_t gid;
-
- GROUP_MAP map;
-
- if (lookup_name(get_global_sam_name(), name, &sid, &type))
- return NT_STATUS_ALIAS_EXISTS;
-
- if (!winbind_allocate_rid(&new_rid))
- return NT_STATUS_ACCESS_DENIED;
-
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, new_rid);
-
- /* Here we allocate the gid */
- if (!winbind_sid_to_gid(&gid, &sid)) {
- DEBUG(0, ("Could not get gid for new RID\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- map.gid = gid;
- sid_copy(&map.sid, &sid);
- map.sid_name_use = SID_NAME_ALIAS;
- fstrcpy(map.nt_name, name);
- fstrcpy(map.comment, "");
-
- if (!pdb_add_group_mapping_entry(&map)) {
- DEBUG(0, ("Could not add group mapping entry for alias %s\n",
- name));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- *rid = new_rid;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
- const DOM_SID *sid)
-{
- return pdb_delete_group_mapping_entry(*sid) ?
- NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
-}
-
-NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
- const DOM_SID *sid,
- uint32 start_idx, uint32 max_entries,
- uint32 *num_aliases,
- struct acct_info **info)
-{
- extern DOM_SID global_sid_Builtin;
-
- GROUP_MAP *map;
- int i, num_maps;
- enum SID_NAME_USE type = SID_NAME_UNKNOWN;
-
- if (sid_compare(sid, get_global_sam_sid()) == 0)
- type = SID_NAME_ALIAS;
-
- if (sid_compare(sid, &global_sid_Builtin) == 0)
- type = SID_NAME_WKN_GRP;
-
- if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
- (num_maps == 0)) {
- *num_aliases = 0;
- *info = NULL;
- goto done;
- }
-
- if (start_idx > num_maps) {
- *num_aliases = 0;
- *info = NULL;
- goto done;
- }
-
- *num_aliases = num_maps - start_idx;
-
- if (*num_aliases > max_entries)
- *num_aliases = max_entries;
-
- *info = malloc(sizeof(struct acct_info) * (*num_aliases));
-
- for (i=0; i<*num_aliases; i++) {
- fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
- fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
- sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
- }
-
- done:
- SAFE_FREE(map);
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
- const DOM_SID *sid,
- struct acct_info *info)
-{
- GROUP_MAP map;
-
- if (!pdb_getgrsid(&map, *sid))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- fstrcpy(info->acct_name, map.nt_name);
- fstrcpy(info->acct_desc, map.comment);
- sid_peek_rid(&map.sid, &info->rid);
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
- const DOM_SID *sid,
- struct acct_info *info)
-{
- GROUP_MAP map;
-
- if (!pdb_getgrsid(&map, *sid))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- fstrcpy(map.comment, info->acct_desc);
-
- if (!pdb_update_group_mapping_entry(&map))
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias, const DOM_SID *member)
-{
- return add_aliasmem(alias, member);
-}
-
-NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias, const DOM_SID *member)
-{
- return del_aliasmem(alias, member);
-}
-
-NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias, DOM_SID **members,
- int *num_members)
-{
- return enum_aliasmem(alias, members, num_members);
-}
-
-NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num)
-{
- return alias_memberships(sid, aliases, num);
-}
-
-/**********************************************************************
- no ops for passdb backends that don't implement group mapping
- *********************************************************************/
-
-NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- const char *name)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods,
- DOM_SID sid)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only)
-{
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/****************************************************************************
- These need to be redirected through pdb_interface.c
-****************************************************************************/
-BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info)
-{
- GROUP_MAP map;
- BOOL res;
-
- become_root();
- res = get_domain_group_from_sid(*sid, &map);
- unbecome_root();
-
- if (!res)
- return False;
-
- fstrcpy(info->acct_name, map.nt_name);
- fstrcpy(info->acct_desc, map.comment);
- sid_peek_rid(sid, &info->rid);
- return True;
-}
-
-BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info)
-{
- GROUP_MAP map;
-
- if (!get_domain_group_from_sid(*sid, &map))
- return False;
-
- fstrcpy(map.nt_name, info->acct_name);
- fstrcpy(map.comment, info->acct_desc);
-
- return pdb_update_group_mapping_entry(&map);
-}
-
-
diff --git a/source/include/MacExtensions.h b/source/include/MacExtensions.h
index d09370ed9f7..1c57690ba47 100644
--- a/source/include/MacExtensions.h
+++ b/source/include/MacExtensions.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) John H Terpstra 1996-1998
@@ -86,7 +87,7 @@ typedef struct _SambaAfpInfo
**
** We will be using infromation levels that are betwwen 0x300 and 0x399 for all Macintosh
** extentions calls. The first of these will be the SMB_MAC_QUERY_FS_INFO level which
-** will allow the server to return the MacQueryFSInfo structure. All fields are Little
+** will allow the server to return the MacQueryFSInfo structure. All feilds are Little
** Endian unless other wise specified.
*/
#define SMB_MAC_QUERY_FS_INFO 0x301
diff --git a/source/include/ads.h b/source/include/ads.h
deleted file mode 100644
index 4daa65e796d..00000000000
--- a/source/include/ads.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- header for ads (active directory) library routines
-
- basically this is a wrapper around ldap
-*/
-
-typedef struct {
- void *ld; /* the active ldap structure */
- struct in_addr ldap_ip; /* the ip of the active connection, if any */
- time_t last_attempt; /* last attempt to reconnect */
- int ldap_port;
-
- int is_mine; /* do I own this structure's memory? */
-
- /* info needed to find the server */
- struct {
- char *realm;
- char *workgroup;
- char *ldap_server;
- char *ldap_uri;
- int foreign; /* set to 1 if connecting to a foreign realm */
- } server;
-
- /* info needed to authenticate */
- struct {
- char *realm;
- char *password;
- char *user_name;
- char *kdc_server;
- unsigned flags;
- int time_offset;
- time_t expire;
- } auth;
-
- /* info derived from the servers config */
- struct {
- char *realm;
- char *bind_path;
- char *ldap_server_name;
- time_t current_time;
- } config;
-} ADS_STRUCT;
-
-/* there are 5 possible types of errors the ads subsystem can produce */
-enum ads_error_type {ENUM_ADS_ERROR_KRB5, ENUM_ADS_ERROR_GSS,
- ENUM_ADS_ERROR_LDAP, ENUM_ADS_ERROR_SYSTEM, ENUM_ADS_ERROR_NT};
-
-typedef struct {
- enum ads_error_type error_type;
- union err_state{
- int rc;
- NTSTATUS nt_status;
- } err;
- /* For error_type = ENUM_ADS_ERROR_GSS minor_status describe GSS API error */
- /* Where rc represents major_status of GSS API error */
- int minor_status;
-} ADS_STATUS;
-
-#ifdef HAVE_ADS
-typedef LDAPMod **ADS_MODLIST;
-#else
-typedef void **ADS_MODLIST;
-#endif
-
-/* macros to simplify error returning */
-#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc)
-#define ADS_ERROR_LDAP(rc) ads_build_error(ENUM_ADS_ERROR_LDAP, rc, 0)
-#define ADS_ERROR_SYSTEM(rc) ads_build_error(ENUM_ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
-#define ADS_ERROR_KRB5(rc) ads_build_error(ENUM_ADS_ERROR_KRB5, rc, 0)
-#define ADS_ERROR_GSS(rc, minor) ads_build_error(ENUM_ADS_ERROR_GSS, rc, minor)
-#define ADS_ERROR_NT(rc) ads_build_nt_error(ENUM_ADS_ERROR_NT,rc)
-
-#define ADS_ERR_OK(status) ((status.error_type == ENUM_ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0))
-#define ADS_SUCCESS ADS_ERROR(0)
-
-/* time between reconnect attempts */
-#define ADS_RECONNECT_TIME 5
-
-/* timeout on searches */
-#define ADS_SEARCH_TIMEOUT 10
-
-/* ldap control oids */
-#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319"
-#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339"
-#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473"
-#define ADS_PERMIT_MODIFY_OID "1.2.840.113556.1.4.1413"
-
-/* UserFlags for userAccountControl */
-#define UF_SCRIPT 0x00000001
-#define UF_ACCOUNTDISABLE 0x00000002
-#define UF_UNUSED_1 0x00000004
-#define UF_HOMEDIR_REQUIRED 0x00000008
-
-#define UF_LOCKOUT 0x00000010
-#define UF_PASSWD_NOTREQD 0x00000020
-#define UF_PASSWD_CANT_CHANGE 0x00000040
-#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080
-
-#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100
-#define UF_NORMAL_ACCOUNT 0x00000200
-#define UF_UNUSED_2 0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
-
-#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
-#define UF_SERVER_TRUST_ACCOUNT 0x00002000
-#define UF_UNUSED_3 0x00004000
-#define UF_UNUSED_4 0x00008000
-
-#define UF_DONT_EXPIRE_PASSWD 0x00010000
-#define UF_MNS_LOGON_ACCOUNT 0x00020000
-#define UF_SMARTCARD_REQUIRED 0x00040000
-#define UF_TRUSTED_FOR_DELEGATION 0x00080000
-
-#define UF_NOT_DELEGATED 0x00100000
-#define UF_USE_DES_KEY_ONLY 0x00200000
-#define UF_DONT_REQUIRE_PREAUTH 0x00400000
-#define UF_UNUSED_5 0x00800000
-
-#define UF_UNUSED_6 0x01000000
-#define UF_UNUSED_7 0x02000000
-#define UF_UNUSED_8 0x04000000
-#define UF_UNUSED_9 0x08000000
-
-#define UF_UNUSED_10 0x10000000
-#define UF_UNUSED_11 0x20000000
-#define UF_UNUSED_12 0x40000000
-#define UF_UNUSED_13 0x80000000
-
-#define UF_MACHINE_ACCOUNT_MASK (\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_ACCOUNT_TYPE_MASK (\
- UF_TEMP_DUPLICATE_ACCOUNT |\
- UF_NORMAL_ACCOUNT |\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_SETTABLE_BITS (\
- UF_SCRIPT |\
- UF_ACCOUNTDISABLE |\
- UF_HOMEDIR_REQUIRED |\
- UF_LOCKOUT |\
- UF_PASSWD_NOTREQD |\
- UF_PASSWD_CANT_CHANGE |\
- UF_ACCOUNT_TYPE_MASK | \
- UF_DONT_EXPIRE_PASSWD | \
- UF_MNS_LOGON_ACCOUNT |\
- UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
- UF_SMARTCARD_REQUIRED |\
- UF_TRUSTED_FOR_DELEGATION |\
- UF_NOT_DELEGATED |\
- UF_USE_DES_KEY_ONLY |\
- UF_DONT_REQUIRE_PREAUTH \
- )
-
-/* sAMAccountType */
-#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */
-#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
-#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */
-#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
-#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */
-#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */
-
-#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
-
-/* groupType */
-#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP 0x80000005 /* -2147483643 */
-#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP 0x80000004 /* -2147483644 */
-#define GTYPE_SECURITY_GLOBAL_GROUP 0x80000002 /* -2147483646 */
-#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */
-#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */
-#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */
-
-/* Mailslot or cldap getdcname response flags */
-#define ADS_PDC 0x00000001 /* DC is PDC */
-#define ADS_GC 0x00000004 /* DC is a GC of forest */
-#define ADS_LDAP 0x00000008 /* DC is an LDAP server */
-#define ADS_DS 0x00000010 /* DC supports DS */
-#define ADS_KDC 0x00000020 /* DC is running KDC */
-#define ADS_TIMESERV 0x00000040 /* DC is running time services */
-#define ADS_CLOSEST 0x00000080 /* DC is closest to client */
-#define ADS_WRITABLE 0x00000100 /* DC has writable DS */
-#define ADS_GOOD_TIMESERV 0x00000200 /* DC has hardware clock
- (and running time) */
-#define ADS_NDNC 0x00000400 /* DomainName is non-domain NC serviced
- by LDAP server */
-#define ADS_PINGS 0x0000FFFF /* Ping response */
-#define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/
-#define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */
-#define ADS_DNS_FOREST 0x80000000 /* DnsForestName is a DNS name */
-
-/* DomainCntrollerAddressType */
-#define ADS_INET_ADDRESS 0x00000001
-#define ADS_NETBIOS_ADDRESS 0x00000002
-
-
-/* ads auth control flags */
-#define ADS_AUTH_DISABLE_KERBEROS 0x01
-#define ADS_AUTH_NO_BIND 0x02
-#define ADS_AUTH_ANON_BIND 0x04
-#define ADS_AUTH_SIMPLE_BIND 0x08
-#define ADS_AUTH_ALLOW_NTLMSSP 0x10
-
-/* Kerberos environment variable names */
-#define KRB5_ENV_CCNAME "KRB5CCNAME"
-
-/* Heimdal uses a slightly different name */
-#if defined(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5)
-#define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
-#endif
-
-/* The older versions of heimdal that don't have this
- define don't seem to use it anyway. I'm told they
- always use a subkey */
-#ifndef HAVE_AP_OPTS_USE_SUBKEY
-#define AP_OPTS_USE_SUBKEY 0
-#endif
diff --git a/source/include/adt_tree.h b/source/include/adt_tree.h
deleted file mode 100644
index 12e2ea5cc53..00000000000
--- a/source/include/adt_tree.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Generic Abstract Data Types
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef ADT_TREE_H
-#define ADT_TREE_H
-
-typedef struct _tree_node {
- struct _tree_node *parent;
- struct _tree_node **children;
- int num_children;
- char *key;
- void *data_p;
-} TREE_NODE;
-
-typedef struct _tree_root {
- TREE_NODE *root;
- int (*compare)(void* x, void *y);
- void (*free_func)(void *p);
-} SORTED_TREE;
-
-#endif
diff --git a/source/include/asn_1.h b/source/include/asn_1.h
deleted file mode 100644
index 796c8bb7404..00000000000
--- a/source/include/asn_1.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- simple ASN1 code
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _ASN_1_H
-#define _ASN_1_H
-
-struct nesting {
- off_t start;
- size_t taglen; /* for parsing */
- struct nesting *next;
-};
-
-typedef struct {
- uint8 *data;
- size_t length;
- off_t ofs;
- struct nesting *nesting;
- BOOL has_error;
-} ASN1_DATA;
-
-
-#define ASN1_APPLICATION(x) ((x)+0x60)
-#define ASN1_SEQUENCE(x) ((x)+0x30)
-#define ASN1_CONTEXT(x) ((x)+0xa0)
-#define ASN1_GENERAL_STRING 0x1b
-#define ASN1_OCTET_STRING 0x4
-#define ASN1_OID 0x6
-#define ASN1_BOOLEAN 0x1
-#define ASN1_INTEGER 0x2
-#define ASN1_ENUMERATED 0xa
-#define ASN1_SET 0x31
-
-#define ASN1_MAX_OIDS 20
-
-/* some well known object IDs */
-#define OID_SPNEGO "1 3 6 1 5 5 2"
-#define OID_NTLMSSP "1 3 6 1 4 1 311 2 2 10"
-#define OID_KERBEROS5_OLD "1 2 840 48018 1 2 2"
-#define OID_KERBEROS5 "1 2 840 113554 1 2 2"
-
-#define SPNEGO_NEG_RESULT_ACCEPT 0
-#define SPNEGO_NEG_RESULT_INCOMPLETE 1
-#define SPNEGO_NEG_RESULT_REJECT 2
-
-/* not really ASN.1, but RFC 1964 */
-#define TOK_ID_KRB_AP_REQ (uchar*)"\x01\x00"
-#define TOK_ID_KRB_AP_REP (uchar*)"\x02\x00"
-#define TOK_ID_KRB_ERROR (uchar*)"\x03\x00"
-#define TOK_ID_GSS_GETMIC (uchar*)"\x01\x01"
-#define TOK_ID_GSS_WRAP (uchar*)"\x02\x01"
-
-#endif /* _ASN_1_H */
diff --git a/source/include/auth.h b/source/include/auth.h
deleted file mode 100644
index e7a760881a9..00000000000
--- a/source/include/auth.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef _SMBAUTH_H_
-#define _SMBAUTH_H_
-/*
- Unix SMB/CIFS implementation.
- Standardised Authentication types
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* AUTH_STR - string */
-typedef struct normal_string
-{
- int len;
- char *str;
-} AUTH_STR;
-
-typedef struct auth_usersupplied_info
-{
-
- DATA_BLOB lm_resp;
- DATA_BLOB nt_resp;
- DATA_BLOB lm_interactive_pwd;
- DATA_BLOB nt_interactive_pwd;
- DATA_BLOB plaintext_password;
-
- BOOL encrypted;
-
- AUTH_STR client_domain; /* domain name string */
- AUTH_STR domain; /* domain name after mapping */
- AUTH_STR internal_username; /* username after mapping */
- AUTH_STR smb_name; /* username before mapping */
- AUTH_STR wksta_name; /* workstation name (netbios calling name) unicode string */
-
-} auth_usersupplied_info;
-
-#define SAM_FILL_NAME 0x01
-#define SAM_FILL_INFO3 0x02
-#define SAM_FILL_SAM 0x04
-#define SAM_FILL_UNIX 0x08
-#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX)
-
-typedef struct auth_serversupplied_info
-{
- BOOL guest;
-
- uid_t uid;
- gid_t gid;
-
- /* This groups info is needed for when we become_user() for this uid */
- int n_groups;
- gid_t *groups;
-
- /* NT group information taken from the info3 structure */
-
- NT_USER_TOKEN *ptok;
- PRIVILEGE_SET *privs;
-
- DATA_BLOB user_session_key;
- DATA_BLOB lm_session_key;
-
- uint32 sam_fill_level; /* How far is this structure filled? */
-
- SAM_ACCOUNT *sam_account;
-
- void *pam_handle;
-
- char *unix_name;
-
-} auth_serversupplied_info;
-
-struct auth_context {
- DATA_BLOB challenge;
-
- /* Who set this up in the first place? */
- const char *challenge_set_by;
-
- BOOL challenge_may_be_modified;
-
- struct auth_methods *challenge_set_method;
- /* What order are the various methods in? Try to stop it changing under us */
- struct auth_methods *auth_method_list;
-
- TALLOC_CTX *mem_ctx;
- const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context);
- NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context,
- const struct auth_usersupplied_info *user_info,
- struct auth_serversupplied_info **server_info);
- NTSTATUS (*nt_status_squash)(NTSTATUS nt_status);
- void (*free)(struct auth_context **auth_context);
-};
-
-typedef struct auth_methods
-{
- struct auth_methods *prev, *next;
- const char *name; /* What name got this module */
-
- NTSTATUS (*auth)(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info);
-
- DATA_BLOB (*get_chal)(const struct auth_context *auth_context,
- void **my_private_data,
- TALLOC_CTX *mem_ctx);
-
- /* Used to keep tabs on things like the cli for SMB server authentication */
- void *private_data;
-
- /* Function to clean up the above arbitary structure */
- void (*free_private_data)(void **private_data);
-
- /* Function to send a keepalive message on the above structure */
- void (*send_keepalive)(void **private_data);
-
-} auth_methods;
-
-typedef NTSTATUS (*auth_init_function)(struct auth_context *, const char *, struct auth_methods **);
-
-struct auth_init_function_entry {
- const char *name;
- /* Function to create a member of the authmethods list */
-
- auth_init_function init;
-
- struct auth_init_function_entry *prev, *next;
-};
-
-typedef struct auth_ntlmssp_state
-{
- TALLOC_CTX *mem_ctx;
- struct auth_context *auth_context;
- struct auth_serversupplied_info *server_info;
- struct ntlmssp_state *ntlmssp_state;
-} AUTH_NTLMSSP_STATE;
-
-#define AUTH_INTERFACE_VERSION 1
-
-#endif /* _SMBAUTH_H_ */
diff --git a/source/include/authdata.h b/source/include/authdata.h
deleted file mode 100644
index 9d80745fb06..00000000000
--- a/source/include/authdata.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Kerberos authorization data
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _AUTHDATA_H
-#define _AUTHDATA_H
-
-#include "rpc_misc.h"
-
-#define PAC_TYPE_LOGON_INFO 1
-#define PAC_TYPE_SERVER_CHECKSUM 6
-#define PAC_TYPE_PRIVSVR_CHECKSUM 7
-#define PAC_TYPE_UNKNOWN_10 10
-
-typedef struct unknown_type_10 {
- NTTIME unknown_time;
- uint16 len;
- uint16 *username; /* might not be null terminated, so not UNISTR */
-} UNKNOWN_TYPE_10;
-
-typedef struct pac_signature_data {
- uint32 type;
- uint8 *signature;
-} PAC_SIGNATURE_DATA;
-
-typedef struct group_membership {
- uint32 rid;
- uint32 attrs;
-} GROUP_MEMBERSHIP;
-
-typedef struct group_membership_array {
- uint32 count;
- GROUP_MEMBERSHIP *group_membership;
-} GROUP_MEMBERSHIP_ARRAY;
-
-typedef struct krb_sid_and_attrs {
- uint32 sid_ptr;
- uint32 attrs;
- DOM_SID2 *sid;
-} KRB_SID_AND_ATTRS;
-
-typedef struct krb_sid_and_attr_array {
- uint32 count;
- KRB_SID_AND_ATTRS *krb_sid_and_attrs;
-} KRB_SID_AND_ATTR_ARRAY;
-
-
-/* This is awfully similar to a samr_user_info_23, but not identical.
- Many of the field names have been swiped from there, because it is
- so similar that they are likely the same, but many have been verified.
- Some are in a different order, though... */
-typedef struct pac_logon_info {
- NTTIME logon_time; /* logon time */
- NTTIME logoff_time; /* logoff time */
- NTTIME kickoff_time; /* kickoff time */
- NTTIME pass_last_set_time; /* password last set time */
- NTTIME pass_can_change_time; /* password can change time */
- NTTIME pass_must_change_time; /* password must change time */
-
- UNIHDR hdr_user_name; /* user name unicode string header */
- UNIHDR hdr_full_name; /* user's full name unicode string header */
- UNIHDR hdr_logon_script; /* these last 4 appear to be in a different */
- UNIHDR hdr_profile_path; /* order than in the info23 */
- UNIHDR hdr_home_dir;
- UNIHDR hdr_dir_drive;
-
- uint16 logon_count; /* number of times user has logged onto domain */
- uint16 reserved12;
-
- uint32 user_rid;
- uint32 group_rid;
- uint32 group_count;
- uint32 group_membership_ptr;
- uint32 user_flags;
-
- uint32 reserved13[4];
- UNIHDR hdr_dom_controller;
- UNIHDR hdr_dom_name;
-
- uint32 ptr_dom_sid;
-
- uint32 reserved16[2];
- uint32 reserved17; /* looks like it may be acb_info */
- uint32 reserved18[7];
-
- uint32 sid_count;
- uint32 ptr_extra_sids;
-
- uint32 ptr_res_group_dom_sid;
- uint32 res_group_count;
- uint32 ptr_res_groups;
-
- UNISTR2 uni_user_name; /* user name unicode string header */
- UNISTR2 uni_full_name; /* user's full name unicode string header */
- UNISTR2 uni_logon_script; /* these last 4 appear to be in a different*/
- UNISTR2 uni_profile_path; /* order than in the info23 */
- UNISTR2 uni_home_dir;
- UNISTR2 uni_dir_drive;
- UNISTR2 uni_dom_controller;
- UNISTR2 uni_dom_name;
- DOM_SID2 dom_sid;
- GROUP_MEMBERSHIP_ARRAY groups;
- KRB_SID_AND_ATTR_ARRAY extra_sids;
- DOM_SID2 res_group_dom_sid;
- GROUP_MEMBERSHIP_ARRAY res_groups;
-
-} PAC_LOGON_INFO;
-
-typedef struct pac_info_ctr
-{
- union
- {
- PAC_LOGON_INFO *logon_info;
- PAC_SIGNATURE_DATA *srv_cksum;
- PAC_SIGNATURE_DATA *privsrv_cksum;
- UNKNOWN_TYPE_10 *type_10;
- } pac;
-} PAC_INFO_CTR;
-
-typedef struct pac_info_hdr {
- uint32 type;
- uint32 size;
- uint32 offset;
- uint32 offsethi;
- PAC_INFO_CTR *ctr;
-} PAC_INFO_HDR;
-
-typedef struct pac_data {
- uint32 num_buffers;
- uint32 version;
- PAC_INFO_HDR *pac_info_hdr_ptr;
-} PAC_DATA;
-
-
-#endif
diff --git a/source/include/byteorder.h b/source/include/byteorder.h
index 0eef5573066..c262dd2d337 100644
--- a/source/include/byteorder.h
+++ b/source/include/byteorder.h
@@ -105,7 +105,7 @@ it also defines lots of intermediate macros, just ignore those :-)
#define CAREFUL_ALIGNMENT 1
#endif
-#define CVAL(buf,pos) ((unsigned)(((const unsigned char *)(buf))[pos]))
+#define CVAL(buf,pos) (((const unsigned char *)(buf))[pos])
#define CVAL_NC(buf,pos) (((unsigned char *)(buf))[pos]) /* Non-const version of CVAL */
#define PVAL(buf,pos) (CVAL(buf,pos))
#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
diff --git a/source/include/charset.h b/source/include/charset.h
index 7a9b12ef55d..567c11a61d2 100644
--- a/source/include/charset.h
+++ b/source/include/charset.h
@@ -1,8 +1,11 @@
+#ifndef _CHARSET_H
+#define _CHARSET_H
+
/*
- Unix SMB/CIFS implementation.
- charset defines
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 2002
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Character set handling
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,109 +22,70 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this defines the charset types used in samba */
-typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t;
+#ifndef CHARSET_C
-#define NUM_CHARSETS 5
+extern char *dos_char_map;
+extern char *upper_char_map;
+extern char *lower_char_map;
+extern void add_char_string(const char *s);
+extern void charset_initialise(void);
-/*
- * for each charset we have a function that pushes from that charset to a ucs2
- * buffer, and a function that pulls from ucs2 buffer to that charset.
- * */
+#ifdef toupper
+#undef toupper
+#endif
+
+#ifdef tolower
+#undef tolower
+#endif
+
+#ifdef isupper
+#undef isupper
+#endif
+
+#ifdef islower
+#undef islower
+#endif
+
+#ifdef isdoschar
+#undef isdoschar
+#endif
+
+#ifdef isspace
+#undef isspace
+#endif
-struct charset_functions {
- const char *name;
- size_t (*pull)(void *, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- struct charset_functions *prev, *next;
-};
+#define toupper(c) (upper_char_map[((c)&0xff)] & 0xff)
+#define tolower(c) (lower_char_map[((c)&0xff)] & 0xff)
+#define isupper(c) (((c)&0xff) != tolower((c)&0xff))
+#define islower(c) (((c)&0xff) != toupper((c)&0xff))
+#define isdoschar(c) (dos_char_map[((c)&0xff)] != 0)
+#define isspace(c) ((c)==' ' || (c) == '\t')
-/*
- * This is auxiliary struct used by source/script/gen-8-bit-gap.sh script
- * during generation of an encoding table for charset module
- * */
+/* this is used to determine if a character is safe to use in
+ something that may be put on a command line */
+#define issafe(c) (isalnum((c&0xff)) || strchr("-._",c))
+#endif
-struct charset_gap_table {
- uint16 start;
- uint16 end;
- int32 idx;
-};
+/* Dynamic codepage files defines. */
-/*
- * Define stub for charset module which implements 8-bit encoding with gaps.
- * Encoding tables for such module should be produced from glibc's CHARMAPs
- * using script source/script/gen-8bit-gap.sh
- * CHARSETNAME is CAPITALIZED charset name
- *
- * */
-#define SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CHARSETNAME) \
-static size_t CHARSETNAME ## _push(void *cd, char **inbuf, size_t *inbytesleft, \
- char **outbuf, size_t *outbytesleft) \
-{ \
- while (*inbytesleft >= 2 && *outbytesleft >= 1) { \
- int i; \
- int done = 0; \
- \
- uint16 ch = SVAL(*inbuf,0); \
- \
- for (i=0; from_idx[i].start != 0xffff; i++) { \
- if ((from_idx[i].start <= ch) && (from_idx[i].end >= ch)) { \
- ((unsigned char*)(*outbuf))[0] = from_ucs2[from_idx[i].idx+ch]; \
- (*inbytesleft) -= 2; \
- (*outbytesleft) -= 1; \
- (*inbuf) += 2; \
- (*outbuf) += 1; \
- done = 1; \
- break; \
- } \
- } \
- if (!done) { \
- errno = EINVAL; \
- return -1; \
- } \
- \
- } \
- \
- if (*inbytesleft == 1) { \
- errno = EINVAL; \
- return -1; \
- } \
- \
- if (*inbytesleft > 1) { \
- errno = E2BIG; \
- return -1; \
- } \
- \
- return 0; \
-} \
- \
-static size_t CHARSETNAME ## _pull(void *cd, char **inbuf, size_t *inbytesleft, \
- char **outbuf, size_t *outbytesleft) \
-{ \
- while (*inbytesleft >= 1 && *outbytesleft >= 2) { \
- *(uint16*)(*outbuf) = to_ucs2[((unsigned char*)(*inbuf))[0]]; \
- (*inbytesleft) -= 1; \
- (*outbytesleft) -= 2; \
- (*inbuf) += 1; \
- (*outbuf) += 2; \
- } \
- \
- if (*inbytesleft > 0) { \
- errno = E2BIG; \
- return -1; \
- } \
- \
- return 0; \
-} \
- \
-struct charset_functions CHARSETNAME ## _functions = \
- {#CHARSETNAME, CHARSETNAME ## _pull, CHARSETNAME ## _push}; \
- \
-NTSTATUS charset_ ## CHARSETNAME ## _init(void) \
-{ \
- return smb_register_charset(& CHARSETNAME ## _functions); \
-} \
+/* Version id for dynamically loadable codepage files. */
+#define CODEPAGE_FILE_VERSION_ID 0x1
+/* Version 1 codepage file header size. */
+#define CODEPAGE_HEADER_SIZE 8
+/* Offsets for codepage file header entries. */
+#define CODEPAGE_VERSION_OFFSET 0
+#define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2
+#define CODEPAGE_LENGTH_OFFSET 4
+/* Version id for dynamically loadable unicode map files. */
+#define UNICODE_MAP_FILE_VERSION_ID 0x8001
+/* Version 0x80000001 unicode map file header size. */
+#define UNICODE_MAP_HEADER_SIZE 30
+#define UNICODE_MAP_CODEPAGE_ID_SIZE 20
+/* Offsets for unicode map file header entries. */
+#define UNICODE_MAP_VERSION_OFFSET 0
+#define UNICODE_MAP_CLIENT_CODEPAGE_OFFSET 2
+#define UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET 22
+#define UNICODE_MAP_UNICODE_TO_CP_LENGTH_OFFSET 26
+#endif /* _CHARSET_H */
diff --git a/source/include/client.h b/source/include/client.h
index 968b73f0b41..5ee42fd02d3 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
@@ -28,7 +29,6 @@
will be a multiple of the page size on almost any system */
#define CLI_BUFFER_SIZE (0xFFFF)
-
/*
* These definitions depend on smb.h
*/
@@ -70,6 +70,7 @@ struct cli_state {
int rap_error;
int privileges;
+ fstring eff_name;
fstring desthost;
fstring user_name;
fstring domain;
@@ -91,15 +92,15 @@ struct cli_state {
struct in_addr dest_ip;
struct pwd_info pwd;
- DATA_BLOB secblob; /* cryptkey or negTokenInit */
+ unsigned char cryptkey[8];
uint32 sesskey;
int serverzone;
uint32 servertime;
int readbraw_supported;
int writebraw_supported;
int timeout; /* in milliseconds. */
- size_t max_xmit;
- size_t max_mux;
+ int max_xmit;
+ int max_mux;
char *outbuf;
char *inbuf;
unsigned int bufsize;
@@ -109,42 +110,25 @@ struct cli_state {
TALLOC_CTX *mem_ctx;
- smb_sign_info sign_info;
-
- /* the session key for this CLI, outside
- any per-pipe authenticaion */
- DATA_BLOB user_session_key;
-
/*
* Only used in NT domain calls.
*/
- int pipe_idx; /* Index (into list of known pipes)
- of the pipe we're talking to,
- if any */
-
+ uint32 nt_error; /* NT RPC error code. */
uint16 nt_pipe_fnum; /* Pipe handle. */
-
- /* Secure pipe parameters */
- int pipe_auth_flags;
-
- uint16 saved_netlogon_pipe_fnum; /* The "first" pipe to get
- the session key for the
- schannel. */
- struct netsec_auth_struct auth_info;
-
- NTLMSSP_STATE *ntlmssp_pipe_state;
-
unsigned char sess_key[16]; /* Current session key. */
+ unsigned char ntlmssp_hash[258]; /* ntlmssp data. */
+ uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */
+ uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */
+ uint32 ntlmssp_seq_num; /* ntlmssp sequence number */
DOM_CRED clnt_cred; /* Client credential. */
fstring mach_acct; /* MYNAME$. */
fstring srv_name_slash; /* \\remote server. */
fstring clnt_name_slash; /* \\local client. */
uint16 max_xmit_frag;
uint16 max_recv_frag;
-
- BOOL use_kerberos;
- BOOL use_spnego;
+ vuser_key key;
+ uint32 ntlmssp_flags;
BOOL use_oplocks; /* should we use oplocks? */
BOOL use_level_II_oplocks; /* should we use level II oplocks? */
@@ -155,15 +139,8 @@ struct cli_state {
BOOL force_dos_errors;
/* was this structure allocated by cli_initialise? If so, then
- free in cli_shutdown() */
+ free in cli_shutdown() */
BOOL allocated;
-
- /* Name of the pipe we're talking to, if any */
- fstring pipe_name;
};
-#define CLI_FULL_CONNECTION_DONT_SPNEGO 0x0001
-#define CLI_FULL_CONNECTION_USE_KERBEROS 0x0002
-#define CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK 0x0004
-
#endif /* _CLIENT_H */
diff --git a/source/include/clitar.h b/source/include/clitar.h
index b7731172d61..ad76191fb75 100644
--- a/source/include/clitar.h
+++ b/source/include/clitar.h
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 3.0
* clitar file format
* Copyright (C) Andrew Tridgell 2000
*
diff --git a/source/include/debug.h b/source/include/debug.h
index 52e06b9360b..3e3fd083b75 100644
--- a/source/include/debug.h
+++ b/source/include/debug.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB debug stuff
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) John H Terpstra 1996-1998
@@ -35,18 +36,16 @@
/* I know the __attribute__ stuff is ugly, but it does ensure we get the
arguemnts to DEBUG() right. We have got them wrong too often in the
past.
- The PRINTFLIKE comment does the equivalent for SGI MIPSPro.
*/
-/* PRINTFLIKE1 */
int Debug1( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
-/* PRINTFLIKE1 */
BOOL dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
-BOOL dbghdr( int level, const char *file, const char *func, int line );
-
-extern XFILE *dbf;
-extern pstring debugf;
/* If we have these macros, we can add additional info to the header. */
+#ifdef HAVE_FILE_MACRO
+#define FILE_MACRO (__FILE__)
+#else
+#define FILE_MACRO ("")
+#endif
#ifdef HAVE_FUNCTION_MACRO
#define FUNCTION_MACRO (__FUNCTION__)
@@ -64,7 +63,7 @@ extern pstring debugf;
* because some references would expand incorrectly.
*/
#define DEBUGLEVEL *debug_level
-extern int DEBUGLEVEL;
+
/*
* Define all new debug classes here. A class is represented by an entry in
@@ -77,31 +76,18 @@ extern int DEBUGLEVEL;
* at the start of the file (after #include "includes.h") will default to
* using index zero, so it will behaive just like it always has.
*/
-#define DBGC_ALL 0 /* index equivalent to DEBUGLEVEL */
-
-#define DBGC_TDB 1
-#define DBGC_PRINTDRIVERS 2
-#define DBGC_LANMAN 3
-#define DBGC_SMB 4
-#define DBGC_RPC_PARSE 5
-#define DBGC_RPC_SRV 6
-#define DBGC_RPC_CLI 7
-#define DBGC_PASSDB 8
-#define DBGC_SAM 9
-#define DBGC_AUTH 10
-#define DBGC_WINBIND 11
-#define DBGC_VFS 12
-#define DBGC_IDMAP 13
-#define DBGC_QUOTA 14
-#define DBGC_ACLS 15
-
-/* So you can define DBGC_CLASS before including debug.h */
-#ifndef DBGC_CLASS
#define DBGC_CLASS 0 /* override as shown above */
-#endif
+#define DBGC_ALL 0 /* index equivalent to DEBUGLEVEL */
+
+#define DBGC_TDB 1
+#define DBGC_PRINTDRIVERS 2
+#define DBGC_LANMAN 3
+
+#define DBGC_LAST 4 /* MUST be last class value + 1 */
+
+
+extern int DEBUGLEVEL_CLASS[DBGC_LAST];
-extern int *DEBUGLEVEL_CLASS;
-extern BOOL *DEBUGLEVEL_CLASS_ISSET;
/* Debugging macros
*
@@ -119,7 +105,7 @@ extern BOOL *DEBUGLEVEL_CLASS_ISSET;
* generate a header using the default macros for file, line, and
* function name. Returns True if the debug level was <= DEBUGLEVEL.
*
- * Example: if( DEBUGLVLC( DBGC_TDB, 2 ) ) dbgtext( "Some text.\n" );
+ * Example: if( DEBUGLVL( DBGC_TDB, 2 ) ) dbgtext( "Some text.\n" );
*
* DEBUG()
* If the 'file specific' debug class level >= level OR the system-wide
@@ -129,7 +115,7 @@ extern BOOL *DEBUGLEVEL_CLASS_ISSET;
* previous debug output was unterminated (i.e. no '\n').
* See debug.c:dbghdr() for more info.
*
- * Example: DEBUG( 2, ("Some text and a value %d.\n", value) );
+ * Example: DEBUG( 2, ("Some text and a valu %d.\n", value) );
*
* DEBUGC()
* If the 'macro specified' debug class level >= level OR the system-wide
@@ -139,64 +125,52 @@ extern BOOL *DEBUGLEVEL_CLASS_ISSET;
* previous debug output was unterminated (i.e. no '\n').
* See debug.c:dbghdr() for more info.
*
- * Example: DEBUGC( DBGC_TDB, 2, ("Some text and a value %d.\n", value) );
+ * Example: DEBUG( DBGC_TDB, 2, ("Some text and a valu %d.\n", value) );
*
* DEBUGADD(), DEBUGADDC()
* Same as DEBUG() and DEBUGC() except the text is appended to the previous
* DEBUG(), DEBUGC(), DEBUGADD(), DEBUGADDC() with out another interviening
* header.
*
- * Example: DEBUGADD( 2, ("Some text and a value %d.\n", value) );
- * DEBUGADDC( DBGC_TDB, 2, ("Some text and a value %d.\n", value) );
+ * Example: DEBUGADD( 2, ("Some text and a valu %d.\n", value) );
+ * DEBUGADDC( DBGC_TDB, 2, ("Some text and a valu %d.\n", value) );
*
* Note: If the debug class has not be redeined (see above) then the optimizer
* will remove the extra conditional test.
*/
#define DEBUGLVL( level ) \
- ( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
- && dbghdr( level, __FILE__, FUNCTION_MACRO, (__LINE__) ) )
+ ( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) )
#define DEBUGLVLC( dbgc_class, level ) \
- ( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
- && dbghdr( level, __FILE__, FUNCTION_MACRO, (__LINE__) ) )
+ ( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) )
#define DEBUG( level, body ) \
- (void)( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
- && (dbghdr( level, __FILE__, FUNCTION_MACRO, (__LINE__) )) \
+ (void)( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && (dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) )) \
&& (dbgtext body) )
#define DEBUGC( dbgc_class, level, body ) \
- (void)( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
- && (dbghdr( level, __FILE__, FUNCTION_MACRO, (__LINE__) )) \
+ (void)( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && (dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) )) \
&& (dbgtext body) )
#define DEBUGADD( level, body ) \
- (void)( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ (void)( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbgtext body) )
#define DEBUGADDC( dbgc_class, level, body ) \
- (void)( ((level) <= MAX_DEBUG_LEVEL) && \
- ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
- (!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
- DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ (void)( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbgtext body) )
#endif
diff --git a/source/include/dlinklist.h b/source/include/dlinklist.h
index 794aea75766..cf75404c561 100644
--- a/source/include/dlinklist.h
+++ b/source/include/dlinklist.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
some simple double linked list macros
Copyright (C) Andrew Tridgell 1998
diff --git a/source/include/doserr.h b/source/include/doserr.h
index 576aeda2bf7..783af7e7961 100644
--- a/source/include/doserr.h
+++ b/source/include/doserr.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
DOS error code constants
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) John H Terpstra 1996-2000
@@ -82,28 +83,13 @@
#define ERRnoipc 66 /* don't support ipc */
/* These errors seem to be only returned by the NT printer driver system */
-#define ERRdriveralreadyinstalled 1795 /* ERROR_PRINTER_DRIVER_ALREADY_INSTALLED */
-#define ERRunknownprinterport 1796 /* ERROR_UNKNOWN_PORT */
+
#define ERRunknownprinterdriver 1797 /* ERROR_UNKNOWN_PRINTER_DRIVER */
-#define ERRunknownprintprocessor 1798 /* ERROR_UNKNOWN_PRINTPROCESSOR */
-#define ERRinvalidseparatorfile 1799 /* ERROR_INVALID_SEPARATOR_FILE */
-#define ERRinvalidjobpriority 1800 /* ERROR_INVALID_PRIORITY */
#define ERRinvalidprintername 1801 /* ERROR_INVALID_PRINTER_NAME */
#define ERRprinteralreadyexists 1802 /* ERROR_PRINTER_ALREADY_EXISTS */
-#define ERRinvalidprintercommand 1803 /* ERROR_INVALID_PRINTER_COMMAND */
#define ERRinvaliddatatype 1804 /* ERROR_INVALID_DATATYPE */
#define ERRinvalidenvironment 1805 /* ERROR_INVALID_ENVIRONMENT */
-
-#define ERRunknownprintmonitor 3000 /* ERROR_UNKNOWN_PRINT_MONITOR */
#define ERRprinterdriverinuse 3001 /* ERROR_PRINTER_DRIVER_IN_USE */
-#define ERRspoolfilenotfound 3002 /* ERROR_SPOOL_FILE_NOT_FOUND */
-#define ERRnostartdoc 3003 /* ERROR_SPL_NO_STARTDOC */
-#define ERRnoaddjob 3004 /* ERROR_SPL_NO_ADDJOB */
-#define ERRprintprocessoralreadyinstalled 3005 /* ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED */
-#define ERRprintmonitoralreadyinstalled 3006 /* ERROR_PRINT_MONITOR_ALREADY_INSTALLED */
-#define ERRinvalidprintmonitor 3007 /* ERROR_INVALID_PRINT_MONITOR */
-#define ERRprintmonitorinuse 3008 /* ERROR_PRINT_MONITOR_IN_USE */
-#define ERRprinterhasjobsqueued 3009 /* ERROR_PRINTER_HAS_JOBS_QUEUED */
/* Error codes for the ERRSRV class */
@@ -163,61 +149,38 @@
/* these are win32 error codes. There are only a few places where
these matter for Samba, primarily in the NT printing code */
#define WERR_OK W_ERROR(0)
-#define WERR_BADFUNC W_ERROR(1)
#define WERR_BADFILE W_ERROR(2)
#define WERR_ACCESS_DENIED W_ERROR(5)
#define WERR_BADFID W_ERROR(6)
-#define WERR_NOMEM W_ERROR(8)
-#define WERR_GENERAL_FAILURE W_ERROR(31)
-#define WERR_NOT_SUPPORTED W_ERROR(50)
-#define WERR_PRINTQ_FULL W_ERROR(61)
-#define WERR_NO_SPOOL_SPACE W_ERROR(62)
+#define WERR_BADFUNC W_ERROR(1)
+#define WERR_INSUFFICIENT_BUFFER W_ERROR(122)
#define WERR_NO_SUCH_SHARE W_ERROR(67)
#define WERR_ALREADY_EXISTS W_ERROR(80)
-#define WERR_BAD_PASSWORD W_ERROR(86)
#define WERR_INVALID_PARAM W_ERROR(87)
-#define WERR_INSUFFICIENT_BUFFER W_ERROR(122)
+#define WERR_NOT_SUPPORTED W_ERROR(50)
+#define WERR_BAD_PASSWORD W_ERROR(86)
+#define WERR_NOMEM W_ERROR(8)
#define WERR_INVALID_NAME W_ERROR(123)
#define WERR_UNKNOWN_LEVEL W_ERROR(124)
#define WERR_OBJECT_PATH_INVALID W_ERROR(161)
#define WERR_NO_MORE_ITEMS W_ERROR(259)
#define WERR_MORE_DATA W_ERROR(234)
-#define WERR_INVALID_OWNER W_ERROR(1307)
#define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
-#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
+#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(1797)
+#define WERR_INVALID_PRINTER_NAME W_ERROR(1801)
+#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(1802)
+#define WERR_INVALID_DATATYPE W_ERROR(1804)
+#define WERR_INVALID_ENVIRONMENT W_ERROR(1805)
#define WERR_INVALID_FORM_NAME W_ERROR(1902)
#define WERR_INVALID_FORM_SIZE W_ERROR(1903)
#define WERR_BUF_TOO_SMALL W_ERROR(2123)
#define WERR_JOB_NOT_FOUND W_ERROR(2151)
#define WERR_DEST_NOT_FOUND W_ERROR(2152)
#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320)
+#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(3001)
#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105)
-#define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled)
-#define WERR_UNKNOWN_PORT W_ERROR(ERRunknownprinterport)
-#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(ERRunknownprinterdriver)
-#define WERR_UNKNOWN_PRINTPROCESSOR W_ERROR(ERRunknownprintprocessor)
-#define WERR_INVALID_SEPARATOR_FILE W_ERROR(ERRinvalidseparatorfile)
-#define WERR_INVALID_PRIORITY W_ERROR(ERRinvalidjobpriority)
-#define WERR_INVALID_PRINTER_NAME W_ERROR(ERRinvalidprintername)
-#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(ERRprinteralreadyexists)
-#define WERR_INVALID_PRINTER_COMMAND W_ERROR(ERRinvalidprintercommand)
-#define WERR_INVALID_DATATYPE W_ERROR(ERRinvaliddatatype)
-#define WERR_INVALID_ENVIRONMENT W_ERROR(ERRinvalidenvironment)
-
-#define WERR_UNKNOWN_PRINT_MONITOR W_ERROR(ERRunknownprintmonitor)
-#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(ERRprinterdriverinuse)
-#define WERR_SPOOL_FILE_NOT_FOUND W_ERROR(ERRspoolfilenotfound)
-#define WERR_SPL_NO_STARTDOC W_ERROR(ERRnostartdoc)
-#define WERR_SPL_NO_ADDJOB W_ERROR(ERRnoaddjob)
-#define WERR_PRINT_PROCESSOR_ALREADY_INSTALLED W_ERROR(ERRprintprocessoralreadyinstalled)
-#define WERR_PRINT_MONITOR_ALREADY_INSTALLED W_ERROR(ERRprintmonitoralreadyinstalled)
-#define WERR_INVALID_PRINT_MONITOR W_ERROR(ERRinvalidprintmonitor)
-#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse)
-#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued)
-
-
/* DFS errors */
#ifndef NERR_BASE
diff --git a/source/include/dynconfig.h b/source/include/dynconfig.h
deleted file mode 100644
index a74d77e41f7..00000000000
--- a/source/include/dynconfig.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Copyright (C) 2001 by Martin Pool <mbp@samba.org>
- Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/**
- * @file dynconfig.h
- *
- * @brief Exported global configurations.
- **/
-
-extern char const *dyn_SBINDIR,
- *dyn_BINDIR,
- *dyn_SWATDIR;
-
-extern pstring dyn_CONFIGFILE;
-extern pstring dyn_LOGFILEBASE, dyn_LMHOSTSFILE;
-extern pstring dyn_LIBDIR;
-extern const fstring dyn_SHLIBEXT;
-extern const pstring dyn_LOCKDIR;
-extern const pstring dyn_PIDDIR;
-extern const pstring dyn_SMB_PASSWD_FILE;
-extern const pstring dyn_PRIVATE_DIR;
diff --git a/source/include/fake_file.h b/source/include/fake_file.h
deleted file mode 100644
index cfcd16f6830..00000000000
--- a/source/include/fake_file.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- FAKE FILE suppport, for faking up special files windows want access to
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _FAKE_FILE_H
-#define _FAKE_FILE_H
-
-enum FAKE_FILE_TYPE {
- FAKE_FILE_TYPE_NONE = 0,
- FAKE_FILE_TYPE_QUOTA
-};
-
-/*
-we now get the unix name --metze
-#define FAKE_FILE_NAME_QUOTA "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"
-*/
-#define FAKE_FILE_NAME_QUOTA "$Extend/$Quota:$Q:$INDEX_ALLOCATION"
-
-typedef struct _FAKE_FILE_HANDLE {
- enum FAKE_FILE_TYPE type;
- TALLOC_CTX *mem_ctx;
- void *pd; /* for private data */
- void (*free_pd)(void **pd); /* free private_data */
-} FAKE_FILE_HANDLE;
-
-typedef struct _FAKE_FILE {
- const char *name;
- enum FAKE_FILE_TYPE type;
- void *(*init_pd)(TALLOC_CTX *men_ctx);
- void (*free_pd)(void **pd);
-} FAKE_FILE;
-
-
-#endif /* _FAKE_FILE_H */
diff --git a/source/include/genparser.h b/source/include/genparser.h
deleted file mode 100644
index f28cd78249d..00000000000
--- a/source/include/genparser.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- Copyright (C) Andrew Tridgell <genstruct@tridgell.net> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _GENPARSER_H
-#define _GENPARSER_H
-
-/* these macros are needed for genstruct auto-parsers */
-#ifndef GENSTRUCT
-#define GENSTRUCT
-#define _LEN(x)
-#define _NULLTERM
-#endif
-
-/*
- automatic marshalling/unmarshalling system for C structures
-*/
-
-/* flag to mark a fixed size array as actually being null terminated */
-#define FLAG_NULLTERM 1
-#define FLAG_ALWAYS 2
-
-struct enum_struct {
- const char *name;
- unsigned value;
-};
-
-/* intermediate dumps are stored in one of these */
-struct parse_string {
- unsigned allocated;
- unsigned length;
- char *s;
-};
-
-typedef int (*gen_dump_fn)(TALLOC_CTX *, struct parse_string *, const char *ptr, unsigned indent);
-typedef int (*gen_parse_fn)(TALLOC_CTX *, char *ptr, const char *str);
-
-/* genstruct.pl generates arrays of these */
-struct parse_struct {
- const char *name;
- unsigned ptr_count;
- unsigned size;
- unsigned offset;
- unsigned array_len;
- const char *dynamic_len;
- unsigned flags;
- gen_dump_fn dump_fn;
- gen_parse_fn parse_fn;
-};
-
-#define DUMP_PARSE_DECL(type) \
- int gen_dump_ ## type(TALLOC_CTX *, struct parse_string *, const char *, unsigned); \
- int gen_parse_ ## type(TALLOC_CTX *, char *, const char *);
-
-DUMP_PARSE_DECL(char)
-DUMP_PARSE_DECL(int)
-DUMP_PARSE_DECL(unsigned)
-DUMP_PARSE_DECL(double)
-DUMP_PARSE_DECL(float)
-
-#define gen_dump_unsigned_char gen_dump_char
-#define gen_parse_unsigned_char gen_parse_char
-
-#endif /* _GENPARSER_H */
diff --git a/source/include/genparser_samba.h b/source/include/genparser_samba.h
deleted file mode 100644
index 213d51da876..00000000000
--- a/source/include/genparser_samba.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Copyright (C) Simo Sorce <idra@samba.org> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _GENPARSER_SAMBA_H
-#define _GENPARSER_SAMBA_H
-
-const struct parse_struct pinfo_security_ace_info[] = {
-{"type", 0, sizeof(uint8), offsetof(struct security_ace_info, type), 0, NULL, 0, gen_dump_uint8, gen_parse_uint8},
-{"flags", 0, sizeof(uint8), offsetof(struct security_ace_info, flags), 0, NULL, 0, gen_dump_uint8, gen_parse_uint8},
-{"size", 0, sizeof(uint16), offsetof(struct security_ace_info, size), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
-{"info", 0, sizeof(char), offsetof(struct security_ace_info, info), 0, NULL, 0, gen_dump_SEC_ACCESS, gen_parse_SEC_ACCESS},
-{"obj_flags", 0, sizeof(uint32), offsetof(struct security_ace_info, obj_flags), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"obj_guid", 0, sizeof(char), offsetof(struct security_ace_info, obj_guid), 0, NULL, 0, gen_dump_GUID, gen_parse_GUID},
-{"inh_guid", 0, sizeof(char), offsetof(struct security_ace_info, inh_guid), 0, NULL, 0, gen_dump_GUID, gen_parse_GUID},
-{"trustee", 0, sizeof(char), offsetof(struct security_ace_info, trustee), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
-{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
-
-const struct parse_struct pinfo_security_acl_info[] = {
-{"revision", 0, sizeof(uint16), offsetof(struct security_acl_info, revision), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
-{"size", 0, sizeof(uint16), offsetof(struct security_acl_info, size), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
-{"num_aces", 0, sizeof(uint32), offsetof(struct security_acl_info, num_aces), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"ace", 1, sizeof(struct security_ace_info), offsetof(struct security_acl_info, ace), 0, "size", 0, gen_dump_SEC_ACE, gen_parse_SEC_ACE},
-{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
-
-const struct parse_struct pinfo_security_descriptor_info[] = {
-{"revision", 0, sizeof(uint16), offsetof(struct security_descriptor_info, revision), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
-{"type", 0, sizeof(uint16), offsetof(struct security_descriptor_info, type), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
-{"off_owner_sid", 0, sizeof(uint32), offsetof(struct security_descriptor_info, off_owner_sid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"off_grp_sid", 0, sizeof(uint32), offsetof(struct security_descriptor_info, off_grp_sid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"off_sacl", 0, sizeof(uint32), offsetof(struct security_descriptor_info, off_sacl), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"off_dacl", 0, sizeof(uint32), offsetof(struct security_descriptor_info, off_dacl), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"dacl", 1, sizeof(struct security_acl_info), offsetof(struct security_descriptor_info, dacl), 0, NULL, 0, gen_dump_SEC_ACL, gen_parse_SEC_ACL},
-{"sacl", 1, sizeof(struct security_acl_info), offsetof(struct security_descriptor_info, sacl), 0, NULL, 0, gen_dump_SEC_ACL, gen_parse_SEC_ACL},
-{"owner_sid", 1, sizeof(char), offsetof(struct security_descriptor_info, owner_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
-{"grp_sid", 1, sizeof(char), offsetof(struct security_descriptor_info, grp_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
-{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
-
-const struct parse_struct pinfo_luid_attr_info[] = {
-{"attr", 0, sizeof(uint32), offsetof(struct LUID_ATTR, attr), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
-{"luid", 1, sizeof(LUID), offsetof(struct LUID_ATTR, luid), 0, NULL, 0, gen_dump_LUID, gen_parse_LUID},
-{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
-
-const struct parse_struct pinfo_data_blob_info[] = {
-{"length", 0, sizeof(int), offsetof(DATA_BLOB, length), 0, NULL, 0, gen_dump_int, gen_parse_int},
-{"data", 1, sizeof(char), offsetof(DATA_BLOB, data), 0, "length", 0, gen_dump_char, gen_parse_char},
-{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
-
-#endif /* _GENPARSER_SAMBA_H */
diff --git a/source/include/gums.h b/source/include/gums.h
deleted file mode 100644
index d16a839bc4b..00000000000
--- a/source/include/gums.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- GUMS structures
- Copyright (C) Simo Sorce 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _GUMS_H
-#define _GUMS_H
-
-#define GUMS_VERSION_MAJOR 0
-#define GUMS_VERSION_MINOR 1
-#define GUMS_OBJECT_VERSION 1
-#define GUMS_PRIVILEGE_VERSION 1
-#define GUMS_INTERFACE_VERSION 1
-
-#define GUMS_OBJ_DOMAIN 0x10
-#define GUMS_OBJ_NORMAL_USER 0x20
-#define GUMS_OBJ_GROUP 0x30
-#define GUMS_OBJ_ALIAS 0x31
-
-/* define value types */
-#define GUMS_SET_PRIMARY_GROUP 0x1
-#define GUMS_SET_SEC_DESC 0x2
-
-#define GUMS_SET_NAME 0x10
-#define GUMS_SET_DESCRIPTION 0x11
-#define GUMS_SET_FULL_NAME 0x12
-
-/* user specific type values */
-#define GUMS_SET_LOGON_TIME 0x20
-#define GUMS_SET_LOGOFF_TIME 0x21
-#define GUMS_SET_KICKOFF_TIME 0x23
-#define GUMS_SET_PASS_LAST_SET_TIME 0x24
-#define GUMS_SET_PASS_CAN_CHANGE_TIME 0x25
-#define GUMS_SET_PASS_MUST_CHANGE_TIME 0x26
-
-
-#define GUMS_SET_HOME_DIRECTORY 0x31
-#define GUMS_SET_DRIVE 0x32
-#define GUMS_SET_LOGON_SCRIPT 0x33
-#define GUMS_SET_PROFILE_PATH 0x34
-#define GUMS_SET_WORKSTATIONS 0x35
-#define GUMS_SET_UNKNOWN_STRING 0x36
-#define GUMS_SET_MUNGED_DIAL 0x37
-
-#define GUMS_SET_LM_PASSWORD 0x40
-#define GUMS_SET_NT_PASSWORD 0x41
-#define GUMS_SET_PLAINTEXT_PASSWORD 0x42
-#define GUMS_SET_UNKNOWN_3 0x43
-#define GUMS_SET_LOGON_DIVS 0x44
-#define GUMS_SET_HOURS_LEN 0x45
-#define GUMS_SET_HOURS 0x46
-#define GUMS_SET_BAD_PASSWORD_COUNT 0x47
-#define GUMS_SET_LOGON_COUNT 0x48
-#define GUMS_SET_UNKNOWN_6 0x49
-
-#define GUMS_SET_MUST_CHANGE_PASS 0x50
-#define GUMS_SET_CANNOT_CHANGE_PASS 0x51
-#define GUMS_SET_PASS_NEVER_EXPIRE 0x52
-#define GUMS_SET_ACCOUNT_DISABLED 0x53
-#define GUMS_SET_ACCOUNT_LOCKOUT 0x54
-
-/*group specific type values */
-#define GUMS_ADD_SID_LIST 0x60
-#define GUMS_DEL_SID_LIST 0x61
-#define GUMS_SET_SID_LIST 0x62
-
-GENSTRUCT struct gums_user
-{
- DOM_SID *group_sid; /* Primary Group SID */
-
- NTTIME logon_time; /* logon time */
- NTTIME logoff_time; /* logoff time */
- NTTIME kickoff_time; /* kickoff time */
- NTTIME pass_last_set_time; /* password last set time */
- NTTIME pass_can_change_time; /* password can change time */
- NTTIME pass_must_change_time; /* password must change time */
-
- char *full_name; _NULLTERM /* user's full name string */
- char *home_dir; _NULLTERM /* home directory string */
- char *dir_drive; _NULLTERM /* home directory drive string */
- char *logon_script; _NULLTERM /* logon script string */
- char *profile_path; _NULLTERM /* profile path string */
- char *workstations; _NULLTERM /* login from workstations string */
- char *unknown_str; _NULLTERM /* don't know what this is, yet. */
- char *munged_dial; _NULLTERM /* munged path name and dial-back tel number */
-
- DATA_BLOB lm_pw; /* .data is Null if no password */
- DATA_BLOB nt_pw; /* .data is Null if no password */
-
- uint16 acct_ctrl; /* account type & status flags */
- uint16 logon_divs; /* 168 - number of hours in a week */
- uint32 hours_len; /* normally 21 bytes */
- uint8 *hours; _LEN(hours_len) /* normally 21 bytes (depends on hours_len) */
-
- uint16 bad_password_count; /* 0 */
- uint16 logon_count; /* 0 */
- uint32 unknown_3; /* 0x00ff ffff */
- uint32 unknown_6; /* 0x0000 04ec */
-
-};
-
-GENSTRUCT struct gums_group
-{
- uint32 count; /* Number of SIDs */
- DOM_SID *members; _LEN(count) /* SID array */
-
-};
-
-GENSTRUCT struct gums_domain
-{
- uint32 next_rid;
-
-};
-
-GENSTRUCT struct gums_object
-{
- TALLOC_CTX *mem_ctx;
-
- uint32 type; /* Object Type */
- uint32 version; /* Object Version */
- uint32 seq_num; /* Object Sequence Number */
-
- SEC_DESC *sec_desc; /* Security Descriptor */
-
- DOM_SID *sid; /* Object Sid */
- char *name; _NULLTERM /* Object Name - it should be in DOMAIN\NAME format */
- char *description; _NULLTERM /* Object Description */
-
- struct gums_user *user;
- struct gums_group *group;
- struct gums_domain *domain;
-
-};
-
-GENSTRUCT struct gums_privilege
-{
- TALLOC_CTX *mem_ctx;
-
- uint32 version; /* Object Version */
- uint32 seq_num; /* Object Sequence Number */
-
- char *name; _NULLTERM /* Object Name */
- char *description; _NULLTERM /* Object Description */
-
- LUID_ATTR *privilege; /* Privilege Type */
-
- uint32 count;
- DOM_SID *members; _LEN(count)
-
-};
-
-typedef struct gums_user GUMS_USER;
-typedef struct gums_group GUMS_GROUP;
-typedef struct gums_domain GUMS_DOMAIN;
-typedef struct gums_object GUMS_OBJECT;
-typedef struct gums_privilege GUMS_PRIVILEGE;
-
-typedef struct gums_data_set
-{
- int type; /* GUMS_SET_xxx */
- void *data;
-
-} GUMS_DATA_SET;
-
-typedef struct gums_commit_set
-{
- TALLOC_CTX *mem_ctx;
-
- uint32 type; /* Object type */
- DOM_SID sid; /* Object Sid */
- uint32 count; /* number of changes */
- GUMS_DATA_SET *data;
-
-} GUMS_COMMIT_SET;
-
-typedef struct gums_priv_commit_set
-{
- TALLOC_CTX *mem_ctx;
-
- uint32 type; /* Object type */
- char *name; /* Object Sid */
- uint32 count; /* number of changes */
- GUMS_DATA_SET *data;
-
-} GUMS_PRIV_COMMIT_SET;
-
-
-typedef struct gums_functions
-{
- /* module data */
- TALLOC_CTX *mem_ctx;
- char *name;
- void *private_data;
- void (*free_private_data)(void **);
-
- /* Generic object functions */
-
- NTSTATUS (*get_domain_sid) (DOM_SID *sid, const char* name);
- NTSTATUS (*set_domain_sid) (const DOM_SID *sid);
-
- NTSTATUS (*get_sequence_number) (void);
-
- NTSTATUS (*new_object) (DOM_SID *sid, const char *name, const int obj_type);
- NTSTATUS (*delete_object) (const DOM_SID *sid);
-
- NTSTATUS (*get_object_from_sid) (GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type);
- NTSTATUS (*get_object_from_name) (GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type);
- /* This function is used to get the list of all objects changed since b_time, it is
- used to support PDC<->BDC synchronization */
- NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time);
-
- NTSTATUS (*enumerate_objects_start) (void **handle, const DOM_SID *sid, const int obj_type);
- NTSTATUS (*enumerate_objects_get_next) (GUMS_OBJECT **object, void *handle);
- NTSTATUS (*enumerate_objects_stop) (void *handle);
-
- /* This function MUST be used ONLY by PDC<->BDC replication code or recovery tools.
- Never use this function to update an object in the database, use set_object_values() */
- NTSTATUS (*set_object) (GUMS_OBJECT *object);
-
- /* set object values function */
- NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set);
-
- /* Group related functions */
- NTSTATUS (*add_members_to_group) (const DOM_SID *group, const DOM_SID **members);
- NTSTATUS (*delete_members_from_group) (const DOM_SID *group, const DOM_SID **members);
- NTSTATUS (*enumerate_group_members) (DOM_SID **members, const DOM_SID *sid, const int type);
-
- NTSTATUS (*get_sid_groups) (DOM_SID **groups, const DOM_SID *sid);
-
- NTSTATUS (*lock_sid) (const DOM_SID *sid);
- NTSTATUS (*unlock_sid) (const DOM_SID *sid);
-
- /* privileges related functions */
-
- NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name);
- NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members);
- NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members);
- NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members);
- NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs);
-
- /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
- NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
-
-} GUMS_FUNCTIONS;
-
-typedef NTSTATUS (*gums_init_function)(
- struct gums_functions *,
- const char *);
-
-struct gums_init_function_entry {
-
- const char *name;
- gums_init_function init_fn;
- struct gums_init_function_entry *prev, *next;
-};
-
-#endif /* _GUMS_H */
diff --git a/source/include/hash.h b/source/include/hash.h
index 40cc8b7cab3..80a1aaae50e 100644
--- a/source/include/hash.h
+++ b/source/include/hash.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
Copyright (C) Ying Chen 2000.
@@ -66,8 +67,8 @@ typedef struct hash_element {
typedef struct hash_table {
ubi_dlList *buckets;
ubi_dlList lru_chain;
- unsigned num_elements;
- unsigned size;
+ int num_elements;
+ int size;
compare_function comp_func;
} hash_table;
diff --git a/source/include/hmacmd5.h b/source/include/hmacmd5.h
deleted file mode 100644
index 6b53a6fd074..00000000000
--- a/source/include/hmacmd5.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Interface header: Scheduler service
- Copyright (C) Luke Kenneth Casson Leighton 1996-1999
- Copyright (C) Andrew Tridgell 1992-1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _HMAC_MD5_H
-
-typedef struct
-{
- struct MD5Context ctx;
- uchar k_ipad[65];
- uchar k_opad[65];
-
-} HMACMD5Context;
-
-#endif /* _HMAC_MD5_H */
diff --git a/source/include/idmap.h b/source/include/idmap.h
deleted file mode 100644
index 20b1015285e..00000000000
--- a/source/include/idmap.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _IDMAP_H_
-#define _IDMAP_H_
-/*
- Unix SMB/CIFS implementation.
-
- Idmap headers
-
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
- Copyright (C) Simo Sorce 2003
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#define SMB_IDMAP_INTERFACE_VERSION 2
-
-
-#define ID_EMPTY 0x00
-#define ID_USERID 0x01
-#define ID_GROUPID 0x02
-#define ID_OTHER 0x04
-
-#define ID_TYPEMASK 0x0f
-
-#define ID_QUERY_ONLY 0x10
-
-/* Filled out by IDMAP backends */
-struct idmap_methods {
-
- /* Called when backend is first loaded */
- NTSTATUS (*init)( char *params );
-
- NTSTATUS (*allocate_rid)(uint32 *rid, int rid_type);
- NTSTATUS (*allocate_id)(unid_t *id, int id_type);
- NTSTATUS (*get_sid_from_id)(DOM_SID *sid, unid_t id, int id_type);
- NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, const DOM_SID *sid);
- NTSTATUS (*set_mapping)(const DOM_SID *sid, unid_t id, int id_type);
-
- /* Called when backend is unloaded */
- NTSTATUS (*close)(void);
-
- /* Called to dump backend status */
- void (*status)(void);
-};
-#endif /* _IDMAP_H_ */
diff --git a/source/include/includes.h b/source/include/includes.h
index dd93c813d3d..88dd6cd867a 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -1,10 +1,10 @@
#ifndef _INCLUDES_H
#define _INCLUDES_H
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Machine customisation and include handling
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) 2002 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,22 +45,20 @@
#undef HAVE_TERMIOS_H
#endif
-#ifdef __GNUC__
-/** Use gcc attribute to check printf fns. a1 is the 1-based index of
- * the parameter containing the format, and a2 the index of the first
- * argument. **/
-#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
-#else
-#define PRINTF_ATTRIBUTE(a1, a2)
+#ifdef LINUX
+#ifndef DEFAULT_PRINTING
+#define DEFAULT_PRINTING PRINT_BSD
+#endif
+#ifndef PRINTCAP_NAME
+#define PRINTCAP_NAME "/etc/printcap"
+#endif
#endif
+/* use gcc attribute to check printf fns */
#ifdef __GNUC__
-/** gcc attribute used on function parameters so that it does not emit
- * warnings about them being unused. **/
-# define UNUSED(param) param __attribute__ ((unused))
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
-# define UNUSED(param) param
-/** Feel free to add definitions for other compilers here. */
+#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#ifdef RELIANTUNIX
@@ -207,16 +205,12 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
-
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
-#else
-#ifdef HAVE_SYS_SYSLOG_H
-#include <sys/syslog.h>
-#endif
#endif
-
+#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
+#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
@@ -324,6 +318,10 @@
#define PASSWORD_LENGTH 16
#endif /* HAVE_SYS_SECURITY_H */
+#ifdef HAVE_COMPAT_H
+#include <compat.h>
+#endif
+
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
@@ -332,15 +330,10 @@
#include <poll.h>
#endif
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-
#ifdef HAVE_SYS_CAPABILITY_H
-#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
+#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H)
#define _I386_STATFS_H
-#define _PPC_STATFS_H
#define BROKEN_REDHAT_7_STATFS_WORKAROUND
#endif
@@ -348,7 +341,6 @@
#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
#undef _I386_STATFS_H
-#undef _PPC_STATFS_H
#undef BROKEN_REDHAT_7_STATFS_WORKAROUND
#endif
@@ -385,91 +377,6 @@
#include <sys/shm.h>
#endif /* HAVE_SYS_SHM_H */
-#ifdef HAVE_NATIVE_ICONV
-#ifdef HAVE_ICONV
-#include <iconv.h>
-#endif
-#ifdef HAVE_GICONV
-#include <giconv.h>
-#endif
-#ifdef HAVE_BICONV
-#include <biconv.h>
-#endif
-#endif
-
-#if HAVE_KRB5_H
-#include <krb5.h>
-#else
-#undef HAVE_KRB5
-#endif
-
-#if HAVE_LBER_H
-#include <lber.h>
-#endif
-
-#if HAVE_LDAP_H
-#include <ldap.h>
-#else
-#undef HAVE_LDAP
-#endif
-
-#if HAVE_GSSAPI_H
-#include <gssapi.h>
-#endif
-
-#if HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#endif
-
-#if HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-
-#if HAVE_COM_ERR_H
-#include <com_err.h>
-#endif
-
-#if HAVE_SYS_ATTRIBUTES_H
-#include <sys/attributes.h>
-#endif
-
-/* mutually exclusive (SuSE 8.2) */
-#if HAVE_ATTR_XATTR_H
-#include <attr/xattr.h>
-#elif HAVE_SYS_XATTR_H
-#include <sys/xattr.h>
-#endif
-
-#if HAVE_LOCALE_H
-#include <locale.h>
-#endif
-
-#if HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
-
-/* Special macros that are no-ops except when run under Valgrind on
- * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
-#if HAVE_VALGRIND_MEMCHECK_H
- /* memcheck.h includes valgrind.h */
-#include <valgrind/memcheck.h>
-#elif HAVE_VALGRIND_H
-#include <valgrind.h>
-#endif
-
-/* If we have --enable-developer and the valgrind header is present,
- * then we're OK to use it. Set a macro so this logic can be done only
- * once. */
-#if defined(DEVELOPER) && (HAVE_VALGRIND_H || HAVE_VALGRIND_VALGRIND_H)
-#define VALGRIND
-#endif
-
-
-/* we support ADS if we want it and have krb5 and ldap libs */
-#if defined(WITH_ADS) && defined(HAVE_KRB5) && defined(HAVE_LDAP)
-#define HAVE_ADS
-#endif
-
/*
* Define VOLATILE if needed.
*/
@@ -615,18 +522,6 @@ typedef int socklen_t;
# endif
#endif
-#if defined(HAVE_LONGLONG)
-#define SMB_BIG_UINT unsigned long long
-#define SMB_BIG_INT long long
-#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
-#else
-#define SMB_BIG_UINT unsigned long
-#define SMB_BIG_INT long
-#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
-#endif
-
-#define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8)
-
/* this should really be a 64 bit type if possible */
#define br_off SMB_BIG_UINT
@@ -654,7 +549,7 @@ typedef int socklen_t;
#define SOFF_T_R(p, ofs, v) (SIVAL(p,(ofs)+4,v),SIVAL(p,ofs,0))
#define IVAL_TO_SMB_OFF_T(buf,off) ((SMB_OFF_T)(( ((uint32)(IVAL((buf),(off)))) & 0xFFFFFFFF )))
#define IVAL2_TO_SMB_BIG_UINT(buf,off) ( (((SMB_BIG_UINT)(IVAL((buf),(off)))) & ((SMB_BIG_UINT)0xFFFFFFFF)) | \
- (( ((SMB_BIG_UINT)(IVAL((buf),(off+4)))) & ((SMB_BIG_UINT)0xFFFFFFFF) ) << 32 ) )
+ (( ((SMB_BIG_UINT)(IVAL((buf),(off+4)))) & ((SMB_BIG_UINT)0xFFFFFFFF) ) << 32 ) )
#endif
/*
@@ -717,6 +612,18 @@ typedef int socklen_t;
# endif
#endif
+#if defined(HAVE_LONGLONG)
+#define SMB_BIG_UINT unsigned long long
+#define SMB_BIG_INT long long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
+#else
+#define SMB_BIG_UINT unsigned long
+#define SMB_BIG_INT long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
+#endif
+
+#define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8)
+
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
@@ -730,6 +637,11 @@ extern char *sys_errlist[];
#define strerror(i) sys_errlist[i]
#endif
+#ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+#endif
+
#ifndef HAVE_ERRNO_DECL
extern int errno;
#endif
@@ -744,30 +656,20 @@ extern int errno;
#define NGROUPS_MAX 32 /* Guess... */
#endif
-/* Our own pstrings and fstrings */
-#include "pstring.h"
-
/* Lists, trees, caching, database... */
-#include "xfile.h"
-#include "intl.h"
#include "ubi_sLinkList.h"
#include "ubi_dLinkList.h"
#include "dlinklist.h"
#include "../tdb/tdb.h"
#include "../tdb/spinlock.h"
-#include "../tdb/tdbutil.h"
#include "talloc.h"
-#include "nt_status.h"
-#include "ads.h"
#include "interfaces.h"
#include "hash.h"
#include "trans2.h"
#include "nterr.h"
#include "ntioctl.h"
+#include "secrets.h"
#include "messages.h"
-#include "charset.h"
-#include "dynconfig.h"
-#include "adt_tree.h"
#include "util_getent.h"
@@ -778,67 +680,32 @@ extern int errno;
#include "debugparse.h"
#include "version.h"
-
-#include "privileges.h"
-
#include "smb.h"
-
+#include "smbw.h"
#include "nameserv.h"
-#include "secrets.h"
-
#include "byteorder.h"
-#include "rpc_creds.h"
-
-#include "mapping.h"
-
-#include "passdb.h"
+#include "kanji.h"
+#include "charset.h"
#include "ntdomain.h"
-#include "rpc_misc.h"
-
-#include "rpc_secdes.h"
-
-#include "genparser.h"
-
-#include "gums.h"
-
-#include "nt_printing.h"
-
#include "msdfs.h"
-#include "smbprofile.h"
-
-#include "rap.h"
-
-#include "md5.h"
-#include "hmacmd5.h"
-
-#include "ntlmssp.h"
-
-#include "auth.h"
-
-#include "idmap.h"
-
-#include "client.h"
+#include "profile.h"
-#include "smbw.h"
-
-#include "session.h"
+#include "mapping.h"
-#include "asn_1.h"
+#include "rap.h"
#include "popt.h"
#include "mangle.h"
-#include "module.h"
-
-#include "nsswitch/winbind_client.h"
-
-#include "spnego.h"
+#ifndef MAXCODEPAGELINES
+#define MAXCODEPAGELINES 256
+#endif
/*
* Type for wide character dirent structure.
@@ -863,13 +730,6 @@ typedef struct smb_wpasswd {
wpstring pw_shell;
} SMB_STRUCT_WPASSWD;
-/* used in net.c */
-struct functable {
- const char *funcname;
- int (*fn)(int argc, const char **argv);
-};
-
-
/* Defines for wisXXX functions. */
#define UNI_UPPER 0x1
#define UNI_LOWER 0x2
@@ -877,28 +737,13 @@ struct functable {
#define UNI_XDIGIT 0x8
#define UNI_SPACE 0x10
-#include "nsswitch/winbind_nss.h"
-
-/* forward declaration from printing.h to get around
- header file dependencies */
-
-struct printjob;
-
-struct smb_ldap_privates;
-
-/* forward declarations from smbldap.c */
-
-#include "smbldap.h"
-#include "modconf.h"
+#include "nsswitch/sys_nss.h"
/***** automatically generated prototypes *****/
-#ifndef NO_PROTO_H
#include "proto.h"
-#endif
/* String routines */
-#include "srvstr.h"
#include "safe_string.h"
#ifdef __COMPAR_FN_T
@@ -909,6 +754,19 @@ struct smb_ldap_privates;
#define QSORT_CAST (int (*)(const void *, const void *))
#endif
+/* this guess needs to be improved (tridge) */
+#if (defined(STAT_STATVFS) || defined(STAT_STATVFS64)) && !defined(SYSV)
+#define SYSV 1
+#endif
+
+/*
+ * Veritas File System. Often in addition to native.
+ * Quotas different.
+ */
+#if defined(HAVE_SYS_FS_VX_QUOTA_H)
+#define VXFS_QUOTA
+#endif
+
#ifndef DEFAULT_PRINTING
#ifdef HAVE_CUPS
#define DEFAULT_PRINTING PRINT_CUPS
@@ -930,14 +788,14 @@ struct smb_ldap_privates;
#define SIGCLD SIGCHLD
#endif
-#ifndef SIGRTMIN
-#define SIGRTMIN 32
-#endif
-
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
+#if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP) && !defined(WITH_TDB_SAM))
+#define USE_SMBPASS_DB 1
+#endif
+
#if defined(HAVE_PUTPRPWNAM) && defined(AUTH_CLEARTEXT_SEG_CHARS)
#define OSF1_ENH_SEC 1
#endif
@@ -962,6 +820,10 @@ struct smb_ldap_privates;
#define SYNC_DNS 1
#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 256
+#endif
+
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
@@ -986,12 +848,26 @@ struct smb_ldap_privates;
#define ULTRIX_AUTH 1
#endif
-#ifndef HAVE_STRDUP
-char *strdup(const char *s);
+#ifdef HAVE_LIBREADLINE
+# ifdef HAVE_READLINE_READLINE_H
+# include <readline/readline.h>
+# ifdef HAVE_READLINE_HISTORY_H
+# include <readline/history.h>
+# endif
+# else
+# ifdef HAVE_READLINE_H
+# include <readline.h>
+# ifdef HAVE_HISTORY_H
+# include <history.h>
+# endif
+# else
+# undef HAVE_LIBREADLINE
+# endif
+# endif
#endif
-#ifndef HAVE_STRNDUP
-char *strndup(const char *s, size_t size);
+#ifndef HAVE_STRDUP
+char *strdup(const char *s);
#endif
#ifndef HAVE_MEMMOVE
@@ -1034,10 +910,6 @@ size_t strnlen(const char *s, size_t n);
unsigned long strtoul(const char *nptr, char **endptr, int base);
#endif
-#ifndef HAVE_SETENV
-int setenv(const char *name, const char *value, int overwrite);
-#endif
-
#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL))
/* stupid glibc */
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
@@ -1049,6 +921,10 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
int vasprintf(char **ptr, const char *format, va_list ap);
#endif
+#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET)
+#define bzero(a,b) memset((a),'\0',(b))
+#endif
+
#ifdef REPLACE_GETPASS
#define getpass(prompt) getsmbpass((prompt))
#endif
@@ -1081,19 +957,12 @@ int vasprintf(char **ptr, const char *format, va_list ap);
#define DEFAULT_SOCKET_OPTIONS ""
#endif
-/* Load header file for dynamic linking stuff */
+/* Load header file for libdl stuff */
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
-/* dmalloc -- free heap debugger (dmalloc.org). This should be near
- * the *bottom* of include files so as not to conflict. */
-#ifdef ENABLE_DMALLOC
-# include <dmalloc.h>
-#endif
-
-
/* Some POSIX definitions for those without */
#ifndef S_IFDIR
@@ -1207,7 +1076,6 @@ extern int DEBUGLEVEL;
#define F_SETLKW 14
#endif
-
/* Needed for sys_dlopen/sys_dlsym/sys_dlclose */
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL 0
@@ -1221,16 +1089,8 @@ extern int DEBUGLEVEL;
#define RTLD_NOW 0
#endif
-/* needed for some systems without iconv. Doesn't really matter
- what error code we use */
-#ifndef EILSEQ
-#define EILSEQ EIO
-#endif
-
/* add varargs prototypes with printf checking */
-int fdprintf(int , const char *, ...) PRINTF_ATTRIBUTE(2,3);
-int d_printf(const char *, ...) PRINTF_ATTRIBUTE(1,2);
-int d_fprintf(FILE *f, const char *, ...) PRINTF_ATTRIBUTE(2,3);
+int fdprintf(int , char *, ...) PRINTF_ATTRIBUTE(2,3);
#ifndef HAVE_SNPRINTF_DECL
int snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4);
#endif
@@ -1238,96 +1098,17 @@ int snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4);
int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3);
#endif
-/* Fix prototype problem with non-C99 compliant snprintf implementations, esp
- HPUX 11. Don't change the sense of this #if statement. Read the comments
- in lib/snprint.c if you think you need to. See also bugzilla bug 174. */
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-#define snprintf smb_snprintf
-#endif
-
-void sys_adminlog(int priority, const char *format_str, ...) PRINTF_ATTRIBUTE(2,3);
-
-int pstr_sprintf(pstring s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-int fstr_sprintf(fstring s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-
-int d_vfprintf(FILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0);
-
-int smb_xvasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0);
-
/* we used to use these fns, but now we have good replacements
for snprintf and vsnprintf */
#define slprintf snprintf
#define vslprintf vsnprintf
-
/* we need to use __va_copy() on some platforms */
#ifdef HAVE_VA_COPY
-#define VA_COPY(dest, src) va_copy(dest, src)
-#else
-#ifdef HAVE___VA_COPY
#define VA_COPY(dest, src) __va_copy(dest, src)
#else
#define VA_COPY(dest, src) (dest) = (src)
#endif
-#endif
-
-#ifndef HAVE_TIMEGM
-time_t timegm(struct tm *tm);
-#endif
-
-/*
- * Veritas File System. Often in addition to native.
- * Quotas different.
- */
-#if defined(HAVE_SYS_FS_VX_QUOTA_H)
-#define VXFS_QUOTA
-#endif
-
-#if defined(HAVE_KRB5)
-
-#ifndef HAVE_KRB5_SET_REAL_TIME
-krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds);
-#endif
-
-#ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES
-krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc);
-#endif
-
-#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY)
-krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock);
-#endif
-
-/* Samba wrapper function for krb5 functionality. */
-void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
-int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
-void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt);
-krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
-krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
-krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
-void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
-BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote);
-#endif /* HAVE_KRB5 */
-
-/* TRUE and FALSE are part of the C99 standard and gcc, but
- unfortunately many vendor compilers don't support them. Use True
- and False instead. */
-
-#ifdef TRUE
-#undef TRUE
-#endif
-#define TRUE __ERROR__XX__DONT_USE_TRUE
-
-#ifdef FALSE
-#undef FALSE
-#endif
-#define FALSE __ERROR__XX__DONT_USE_FALSE
-
-/* If we have blacklisted mmap() try to avoid using it accidentally by
- undefining the HAVE_MMAP symbol. */
-
-#ifdef MMAP_BLACKLIST
-#undef HAVE_MMAP
-#endif
#endif /* _INCLUDES_H */
+
diff --git a/source/include/intl.h b/source/include/intl.h
deleted file mode 100644
index 01fa3bad976..00000000000
--- a/source/include/intl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- internationalisation headers
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/* ideally we would have a static mapping, but that precludes
- dynamic loading. This is a reasonable compromise */
-#define _(x) lang_msg_rotate(x)
-#define N_(x) (x)
diff --git a/source/include/kanji.h b/source/include/kanji.h
new file mode 100755
index 00000000000..bbe7da3719c
--- /dev/null
+++ b/source/include/kanji.h
@@ -0,0 +1,745 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Kanji Extensions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
+ and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
+ and add all jis codes sequence at 1995.8.16
+ Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
+ and add upper/lower case conversion 1997.8.21
+*/
+#ifndef _KANJI_H_
+#define _KANJI_H_
+
+/* FOR SHIFT JIS CODE */
+#define is_shift_jis(c) \
+ ((0x81 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0x9f) \
+ || (0xe0 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xfc))
+#define is_shift_jis2(c) \
+ (0x40 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xfc \
+ && ((const unsigned char) (c)) != 0x7f)
+#define is_kana(c) ((0xa0 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xdf))
+
+/* case conversion */
+#define is_sj_upper2(c) \
+ ((0x60 <= (const unsigned char) (c)) && ((const unsigned char) (c) <= 0x79))
+#define is_sj_lower2(c) \
+ ((0x81 <= (const unsigned char) (c)) && ((const unsigned char) (c) <= 0x9A))
+#define sjis_alph 0x82
+#define is_sj_alph(c) (sjis_alph == (const unsigned char) (c))
+#define is_sj_upper(c1, c2) (is_sj_alph (c1) && is_sj_upper2 (c2))
+#define is_sj_lower(c1, c2) (is_sj_alph (c1) && is_sj_lower2 (c2))
+#define sj_toupper2(c) \
+ (is_sj_lower2 (c) ? ((const int) ((const unsigned char) (c) - 0x81 + 0x60)) : \
+ ((int) (const unsigned char) (c)))
+#define sj_tolower2(c) \
+ (is_sj_upper2 (c) ? ((const int) ((const unsigned char) (c) - 0x60 + 0x81)) : \
+ ((const int) (const unsigned char) (c)))
+
+#define is_sj_ru_upper2(c) \
+ ((0x40 <= (const unsigned char) (c)) && ((const unsigned char) (c) <= 0x60))
+#define is_sj_ru_lower2(c) \
+ (((0x70 <= (const unsigned char) (c)) && ((const unsigned char) (c) <= 0x7e)) || \
+ ((0x80 <= (const unsigned char) (c)) && ((const unsigned char) (c) <= 0x91)))
+#define sjis_russian 0x84
+#define is_sj_russian(c) (sjis_russian == (const unsigned char) (c))
+#define is_sj_ru_upper(c1, c2) (is_sj_russian (c1) && is_sj_ru_upper2 (c2))
+#define is_sj_ru_lower(c1, c2) (is_sj_russian (c1) && is_sj_ru_lower2 (c2))
+#define sj_ru_toupper2(c) \
+ (is_sj_ru_lower2 (c) ? ((const int) ((const unsigned char) (c) + \
+ (((const unsigned char)(c) >= 0x4f) ? (0x70 - 0x40) : (0x80 - 0x4f)))) : \
+ ((const int) (const unsigned char) (c)))
+#define sj_ru_tolower2(c) \
+ (is_sj_ru_upper2 (c) ? ((const int) ((const unsigned char) (c) - \
+ (((const unsigned char)(c) >= 0x80) ? (0x70 - 0x40) : (0x80 - 0x4f)))) : \
+ ((const int) (const unsigned char) (c)))
+
+#ifdef _KANJI_C_
+/* FOR EUC CODE */
+#define euc_kana (0x8e)
+#define is_euc_kana(c) (((const unsigned char) (c)) == euc_kana)
+#define is_euc(c) (0xa0 < ((const unsigned char) (c)) && ((const unsigned char) (c)) < 0xff)
+
+#define euc_sup (0x8f)
+#define is_euc_sup(c) (((const unsigned char ) (c)) == euc_sup)
+
+/* FOR JIS CODE */
+/* default jis third shift code, use for output */
+#ifndef JIS_KSO
+#define JIS_KSO 'B'
+#endif
+#ifndef JIS_KSI
+#define JIS_KSI 'J'
+#endif
+/* in: \E$B or \E$@ */
+/* out: \E(J or \E(B or \E(H */
+#define jis_esc (0x1b)
+#define jis_so (0x0e)
+#define jis_so1 ('$')
+#define jis_so2 ('B')
+#define jis_si (0x0f)
+#define jis_si1 ('(')
+#define jis_si2 ('J')
+#define is_esc(c) (((const unsigned char) (c)) == jis_esc)
+#define is_so1(c) (((const unsigned char) (c)) == jis_so1)
+#define is_so2(c) (((const unsigned char) (c)) == jis_so2 || ((const unsigned char) (c)) == '@')
+#define is_si1(c) (((const unsigned char) (c)) == jis_si1)
+#define is_si2(c) (((const unsigned char) (c)) == jis_si2 || ((const unsigned char) (c)) == 'B' \
+ || ((const unsigned char) (c)) == 'H')
+#define is_so(c) (((const unsigned char) (c)) == jis_so)
+#define is_si(c) (((const unsigned char) (c)) == jis_si)
+#define junet_kana1 ('(')
+#define junet_kana2 ('I')
+#define is_juk1(c) (((const unsigned char) (c)) == junet_kana1)
+#define is_juk2(c) (((const unsigned char) (c)) == junet_kana2)
+
+#define _KJ_ROMAN (0)
+#define _KJ_KANJI (1)
+#define _KJ_KANA (2)
+
+/* FOR HEX */
+#define HEXTAG ':'
+#define hex2bin(x) \
+ ( ((const int) '0' <= ((const int) (x)) && ((const int) (x)) <= (const int)'9')? \
+ (((const int) (x))-(const int)'0'): \
+ ((const int) 'a'<= ((const int) (x)) && ((const int) (x))<= (const int) 'f')? \
+ (((const int) (x)) - (const int)'a'+10): \
+ (((const int) (x)) - (const int)'A'+10) )
+#define bin2hex(x) \
+ ( (((const int) (x)) >= 10)? (((const int) (x))-10 + (const int) 'a'): (((const int) (x)) + (const int) '0') )
+
+/* For Hangul (Korean - code page 949). */
+#define is_hangul(c) ((0x81 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xfd))
+
+/* For traditional Chinese (known as Big5 encoding - code page 950). */
+#define is_big5_c1(c) ((0xa1 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xf9))
+
+/* For simplified Chinese (code page - 936). */
+#define is_simpch_c1(c) ((0xa1 <= ((const unsigned char) (c)) && ((const unsigned char) (c)) <= 0xf7))
+
+#else /* not _KANJI_C_ */
+
+/*
+ * The following is needed for AIX systems that have
+ * their own #defines for strchr, strrchr, strstr
+ * and strtok.
+ */
+
+#ifdef strchr
+#undef strchr
+#endif /* strchr */
+
+#ifdef strrchr
+#undef strrchr
+#endif /* strrchr */
+
+#ifdef strstr
+#undef strstr
+#endif /* strstr */
+
+#ifdef strtok
+#undef strtok
+#endif /* strtok */
+
+/* Ensure we use our definitions in all other files than kanji.c. */
+
+/* Function pointers we will replace. */
+extern char *(*multibyte_strchr)(const char *s, int c);
+extern char *(*multibyte_strrchr)(const char *s, int c);
+extern char *(*multibyte_strstr)(const char *s1, const char *s2);
+extern char *(*multibyte_strtok)(char *s1, const char *s2);
+extern char *(*_dos_to_unix)(char *str);
+extern char *(*_dos_to_unix_static)(const char *str);
+extern char *(*_unix_to_dos)(char *str);
+extern char *(*_unix_to_dos_static)(const char *str);
+extern char *(*_dos_to_dos_static)(const char *str);
+extern BOOL (*is_multibyte_char)(char c);
+extern int (*_skip_multibyte_char)(char c);
+
+#define strchr(s1, c) ((*multibyte_strchr)((s1), (c)))
+#define strrchr(s1, c) ((*multibyte_strrchr)((s1), (c)))
+#define strstr(s1, s2) ((*multibyte_strstr)((s1), (s2)))
+#define strtok(s1, s2) ((*multibyte_strtok)((s1), (s2)))
+#define dos_to_unix(x) ((*_dos_to_unix)(x))
+#define dos_to_unix_static(x) ((*_dos_to_unix_static)(x))
+#define unix_to_dos(x) ((*_unix_to_dos)(x))
+#define unix_to_dos_static(x) ((*_unix_to_dos_static)(x))
+#define dos_to_dos_static(x) ((*_dos_to_dos)(x))
+#define skip_multibyte_char(c) ((*_skip_multibyte_char)((c)))
+
+#endif /* _KANJI_C_ */
+
+#define UNKNOWN_CODE (-1)
+#define SJIS_CODE (0)
+#define EUC_CODE (1)
+#define JIS7_CODE (2)
+#define JIS8_CODE (3)
+#define JUNET_CODE (4)
+#define HEX_CODE (5)
+#define CAP_CODE (6)
+#define DOSV_CODE SJIS_CODE
+#define EUC3_CODE (7)
+#define UTF8_CODE (8)
+
+#ifdef _KANJI_C_
+
+/* For conversion */
+
+#define EXTSJISC(c) (0xf0 <= ((const unsigned char)(c)) \
+ && ((const unsigned char)(c) <= 0xfc))
+#define GETAHI (0x81)
+#define GETALO (0xac)
+
+typedef struct _sjis_regur_t {
+ int start;
+ int end;
+ int rstart;
+} sjis_regur_t;
+
+/* When Converting to EUC and JIS, there is no room for
+ * these SJIS codes whose hi byte is larger than 0xf0.
+ *
+ * So we must drop or convert it to harmless code.
+ * This is not standard way, so it is ad hoc but practical.
+ * It is also thought of backward and future compatibility.
+ *
+ * Miura.
+ */
+
+static sjis_regur_t sjisconv[] = {
+{0xfa40, 0xfa49, 0xeeef},
+{0xfa4a, 0xfa53, 0x8754},
+{0xfa54, 0xfa54, 0x81ca},
+{0xfa55, 0xfa57, 0xeefa},
+{0xfa58, 0xfa58, 0x878a},
+{0xfa59, 0xfa59, 0x8782},
+{0xfa5a, 0xfa5a, 0x8784},
+{0xfa5b, 0xfa5b, 0x81e6},
+{0xfa5c, 0xfa7e, 0xed40},
+{0xfa80, 0xfa9b, 0xed63},
+{0xfa9c, 0xfafc, 0xed80},
+{0xfb40, 0xfb5b, 0xede1},
+{0xfb5c, 0xfb7e, 0xee40},
+{0xfb80, 0xfb9b, 0xee63},
+{0xfb9c, 0xfbfc, 0xee80},
+{0xfc40, 0xfc4b, 0xeee1}
+};
+#define SJISCONVTBLSIZ (sizeof(sjisconv) / sizeof(sjis_regur_t))
+
+static sjis_regur_t sjisrev[] = {
+{0x81ca, 0x81ca, 0xfa54},
+{0x81e6, 0x81e6, 0xfa5b},
+{0x8754, 0x875d, 0xfa4a},
+{0x8782, 0x8782, 0xfa59},
+{0x8784, 0x8784, 0xfa5a},
+{0x878a, 0x878a, 0xfa58},
+{0xed40, 0xed62, 0xfa5c},
+{0xed63, 0xed7e, 0xfa80},
+{0xed80, 0xede0, 0xfa9c},
+{0xede1, 0xedfc, 0xfb40},
+{0xee40, 0xee62, 0xfb5c},
+{0xee63, 0xee7e, 0xfb80},
+{0xee80, 0xeee0, 0xfb9c},
+{0xeee1, 0xeeec, 0xfc40},
+{0xeeef, 0xeef8, 0xfa40},
+{0xeefa, 0xeefc, 0xfa55}
+};
+#define SJISREVTBLSIZ (sizeof(sjisrev) / sizeof(sjis_regur_t))
+
+/* EUC3BYTE DEFINITIONS */
+
+typedef struct _sjis_euc_map_t {
+ int sjis;
+ int euc;
+} sjis_euc_map_t;
+
+static sjis_euc_map_t euc3conv2[] = {
+{0x8754 , 0xf3fd},
+{0x8755 , 0xf3fe},
+{0x8756 , 0xf4a1},
+{0x8757 , 0xf4a2},
+{0x8758 , 0xf4a3},
+{0x8759 , 0xf4a4},
+{0x875a , 0xf4a5},
+{0x875b , 0xf4a6},
+{0x875c , 0xf4a7},
+{0x875d , 0xf4a8},
+{0x8782 , 0xf4ac},
+{0x8784 , 0xf4ad},
+{0x878a , 0xf4ab}
+};
+#define EUC3CONV2TBLSIZ (sizeof(euc3conv2) / sizeof(sjis_euc_map_t))
+
+
+/* IBM Kanji to EUC 3byte */
+static int euc3conv[] = {
+/* 0xfa40 */
+0xf3f3, 0xf3f4, 0xf3f5, 0xf3f6, 0xf3f7, 0xf3f8, 0xf3f9, 0xf3fa, 0xf3fb, 0xf3fc, 0xf3fd, 0xf3fe, 0xf4a1, 0xf4a2, 0xf4a3, 0xf4a4,
+/* 0xfa50 */
+0xf4a5, 0xf4a6, 0xf4a7, 0xf4a8, 0, 0xa2c3, 0xf4a9, 0xf4aa, 0xf4ab, 0xf4ac, 0xf4ad, 0, 0xd4e3, 0xdcdf, 0xe4e9, 0xe3f8,
+/* 0xfa60 */
+0xd9a1, 0xb1bb, 0xf4ae, 0xc2ad, 0xc3fc, 0xe4d0, 0xc2bf, 0xbcf4, 0xb0a9, 0xb0c8, 0xf4af, 0xb0d2, 0xb0d4, 0xb0e3, 0xb0ee, 0xb1a7,
+/* 0xfa70 */
+0xb1a3, 0xb1ac, 0xb1a9, 0xb1be, 0xb1df, 0xb1d8, 0xb1c8, 0xb1d7, 0xb1e3, 0xb1f4, 0xb1e1, 0xb2a3, 0xf4b0, 0xb2bb, 0xb2e6,
+/* 0xfa80 */
+0xb2ed, 0xb2f5, 0xb2fc, 0xf4b1, 0xb3b5, 0xb3d8, 0xb3db, 0xb3e5, 0xb3ee, 0xb3fb, 0xf4b2, 0xf4b3, 0xb4c0, 0xb4c7, 0xb4d0, 0xb4de,
+/* 0xfa90 */
+0xf4b4, 0xb5aa, 0xf4b5, 0xb5af, 0xb5c4, 0xb5e8, 0xf4b6, 0xb7c2, 0xb7e4, 0xb7e8, 0xb7e7, 0xf4b7, 0xf4b8, 0xf4b9, 0xb8ce, 0xb8e1,
+/* 0xfaa0 */
+0xb8f5, 0xb8f7, 0xb8f8, 0xb8fc, 0xb9af, 0xb9b7, 0xbabe, 0xbadb, 0xcdaa, 0xbae1, 0xf4ba, 0xbaeb, 0xbbb3, 0xbbb8, 0xf4bb, 0xbbca,
+/* 0xfab0 */
+0xf4bc, 0xf4bd, 0xbbd0, 0xbbde, 0xbbf4, 0xbbf5, 0xbbf9, 0xbce4, 0xbced, 0xbcfe, 0xf4be, 0xbdc2, 0xbde7, 0xf4bf, 0xbdf0, 0xbeb0,
+/* 0xfac0 */
+0xbeac, 0xf4c0, 0xbeb3, 0xbebd, 0xbecd, 0xbec9, 0xbee4, 0xbfa8, 0xbfc9, 0xc0c4, 0xc0e4, 0xc0f4, 0xc1a6, 0xf4c1, 0xc1f5, 0xc1fc,
+/* 0xfad0 */
+0xf4c2, 0xc1f8, 0xc2ab, 0xc2a1, 0xc2a5, 0xf4c3, 0xc2b8, 0xc2ba, 0xf4c4, 0xc2c4, 0xc2d2, 0xc2d7, 0xc2db, 0xc2de, 0xc2ed, 0xc2f0,
+/* 0xfae0 */
+0xf4c5, 0xc3a1, 0xc3b5, 0xc3c9, 0xc3b9, 0xf4c6, 0xc3d8, 0xc3fe, 0xf4c7, 0xc4cc, 0xf4c8, 0xc4d9, 0xc4ea, 0xc4fd, 0xf4c9, 0xc5a7,
+/* 0xfaf0 */
+ 0xc5b5, 0xc5b6, 0xf4ca, 0xc5d5, 0xc6b8, 0xc6d7, 0xc6e0, 0xc6ea, 0xc6e3, 0xc7a1, 0xc7ab, 0xc7c7, 0xc7c3,
+/* 0xfb40 */
+ 0xc7cb, 0xc7cf, 0xc7d9, 0xf4cb, 0xf4cc, 0xc7e6, 0xc7ee, 0xc7fc, 0xc7eb, 0xc7f0, 0xc8b1, 0xc8e5, 0xc8f8, 0xc9a6, 0xc9ab, 0xc9ad,
+/* 0xfb50 */
+ 0xf4cd, 0xc9ca, 0xc9d3, 0xc9e9, 0xc9e3, 0xc9fc, 0xc9f4, 0xc9f5, 0xf4ce, 0xcab3, 0xcabd, 0xcaef, 0xcaf1, 0xcbae, 0xf4cf, 0xcbca,
+/* 0xfb60 */
+ 0xcbe6, 0xcbea, 0xcbf0, 0xcbf4, 0xcbee, 0xcca5, 0xcbf9, 0xccab, 0xccae, 0xccad, 0xccb2, 0xccc2, 0xccd0, 0xccd9, 0xf4d0, 0xcdbb,
+/* 0xfb70 */
+0xf4d1, 0xcebb, 0xf4d2, 0xceba, 0xcec3, 0xf4d3, 0xcef2, 0xb3dd, 0xcfd5, 0xcfe2, 0xcfe9, 0xcfed, 0xf4d4, 0xf4d5, 0xf4d6,
+/* 0xfb80 */
+ 0xf4d7, 0xd0e5, 0xf4d8, 0xd0e9, 0xd1e8, 0xf4d9, 0xf4da, 0xd1ec, 0xd2bb, 0xf4db, 0xd3e1, 0xd3e8, 0xd4a7, 0xf4dc, 0xf4dd, 0xd4d4,
+/* 0xfb90 */
+ 0xd4f2, 0xd5ae, 0xf4de, 0xd7de, 0xf4df, 0xd8a2, 0xd8b7, 0xd8c1, 0xd8d1, 0xd8f4, 0xd9c6, 0xd9c8, 0xd9d1, 0xf4e0, 0xf4e1, 0xf4e2,
+/* 0xfba0 */
+ 0xf4e3, 0xf4e4, 0xdcd3, 0xddc8, 0xddd4, 0xddea, 0xddfa, 0xdea4, 0xdeb0, 0xf4e5, 0xdeb5, 0xdecb, 0xf4e6, 0xdfb9, 0xf4e7, 0xdfc3,
+/* 0xfbb0 */
+ 0xf4e8, 0xf4e9, 0xe0d9, 0xf4ea, 0xf4eb, 0xe1e2, 0xf4ec, 0xf4ed, 0xf4ee, 0xe2c7, 0xe3a8, 0xe3a6, 0xe3a9, 0xe3af, 0xe3b0, 0xe3aa,
+/* 0xfbc0 */
+ 0xe3ab, 0xe3bc, 0xe3c1, 0xe3bf, 0xe3d5, 0xe3d8, 0xe3d6, 0xe3df, 0xe3e3, 0xe3e1, 0xe3d4, 0xe3e9, 0xe4a6, 0xe3f1, 0xe3f2, 0xe4cb,
+/* 0xfbd0 */
+ 0xe4c1, 0xe4c3, 0xe4be, 0xf4ef, 0xe4c0, 0xe4c7, 0xe4bf, 0xe4e0, 0xe4de, 0xe4d1, 0xf4f0, 0xe4dc, 0xe4d2, 0xe4db, 0xe4d4, 0xe4fa,
+/* 0xfbe0 */
+ 0xe4ef, 0xe5b3, 0xe5bf, 0xe5c9, 0xe5d0, 0xe5e2, 0xe5ea, 0xe5eb, 0xf4f1, 0xf4f2, 0xf4f3, 0xe6e8, 0xe6ef, 0xe7ac, 0xf4f4, 0xe7ae,
+/* 0xfbf0 */
+ 0xf4f5, 0xe7b1, 0xf4f6, 0xe7b2, 0xe8b1, 0xe8b6, 0xf4f7, 0xf4f8, 0xe8dd, 0xf4f9, 0xf4fa, 0xe9d1, 0xf4fb,
+/* 0xfc40 */
+ 0xe9ed, 0xeacd, 0xf4fc, 0xeadb, 0xeae6, 0xeaea, 0xeba5, 0xebfb, 0xebfa, 0xf4fd, 0xecd6, 0xf4fe
+};
+
+#define EUC3CONVTBLSIZ (sizeof(euc3conv) / sizeof(int))
+
+/* EUC3byte to SJIS Code */
+
+typedef struct _sjis_euc_revmap_t {
+ int euc;
+ int sjis;
+} sjis_euc_revmap_t;
+
+static sjis_euc_revmap_t euc3rev[] = {
+{0xa2c3, 0xfa55},
+{0xb0a9, 0xfa68},
+{0xb0c8, 0xfa69},
+{0xb0d2, 0xfa6b},
+{0xb0d4, 0xfa6c},
+{0xb0e3, 0xfa6d},
+{0xb0ee, 0xfa6e},
+{0xb1a3, 0xfa70},
+{0xb1a7, 0xfa6f},
+{0xb1a9, 0xfa72},
+{0xb1ac, 0xfa71},
+{0xb1bb, 0xfa61},
+{0xb1be, 0xfa73},
+{0xb1c8, 0xfa76},
+{0xb1d7, 0xfa77},
+{0xb1d8, 0xfa75},
+{0xb1df, 0xfa74},
+{0xb1e1, 0xfa7a},
+{0xb1e3, 0xfa78},
+{0xb1f4, 0xfa79},
+{0xb2a3, 0xfa7b},
+{0xb2bb, 0xfa7d},
+{0xb2e6, 0xfa7e},
+{0xb2ed, 0xfa80},
+{0xb2f5, 0xfa81},
+{0xb2fc, 0xfa82},
+{0xb3b5, 0xfa84},
+{0xb3d8, 0xfa85},
+{0xb3db, 0xfa86},
+{0xb3dd, 0xfb77},
+{0xb3e5, 0xfa87},
+{0xb3ee, 0xfa88},
+{0xb3fb, 0xfa89},
+{0xb4c0, 0xfa8c},
+{0xb4c7, 0xfa8d},
+{0xb4d0, 0xfa8e},
+{0xb4de, 0xfa8f},
+{0xb5aa, 0xfa91},
+{0xb5af, 0xfa93},
+{0xb5c4, 0xfa94},
+{0xb5e8, 0xfa95},
+{0xb7c2, 0xfa97},
+{0xb7e4, 0xfa98},
+{0xb7e7, 0xfa9a},
+{0xb7e8, 0xfa99},
+{0xb8ce, 0xfa9e},
+{0xb8e1, 0xfa9f},
+{0xb8f5, 0xfaa0},
+{0xb8f7, 0xfaa1},
+{0xb8f8, 0xfaa2},
+{0xb8fc, 0xfaa3},
+{0xb9af, 0xfaa4},
+{0xb9b7, 0xfaa5},
+{0xbabe, 0xfaa6},
+{0xbadb, 0xfaa7},
+{0xbae1, 0xfaa9},
+{0xbaeb, 0xfaab},
+{0xbbb3, 0xfaac},
+{0xbbb8, 0xfaad},
+{0xbbca, 0xfaaf},
+{0xbbd0, 0xfab2},
+{0xbbde, 0xfab3},
+{0xbbf4, 0xfab4},
+{0xbbf5, 0xfab5},
+{0xbbf9, 0xfab6},
+{0xbce4, 0xfab7},
+{0xbced, 0xfab8},
+{0xbcf4, 0xfa67},
+{0xbcfe, 0xfab9},
+{0xbdc2, 0xfabb},
+{0xbde7, 0xfabc},
+{0xbdf0, 0xfabe},
+{0xbeac, 0xfac0},
+{0xbeb0, 0xfabf},
+{0xbeb3, 0xfac2},
+{0xbebd, 0xfac3},
+{0xbec9, 0xfac5},
+{0xbecd, 0xfac4},
+{0xbee4, 0xfac6},
+{0xbfa8, 0xfac7},
+{0xbfc9, 0xfac8},
+{0xc0c4, 0xfac9},
+{0xc0e4, 0xfaca},
+{0xc0f4, 0xfacb},
+{0xc1a6, 0xfacc},
+{0xc1f5, 0xface},
+{0xc1f8, 0xfad1},
+{0xc1fc, 0xfacf},
+{0xc2a1, 0xfad3},
+{0xc2a5, 0xfad4},
+{0xc2ab, 0xfad2},
+{0xc2ad, 0xfa63},
+{0xc2b8, 0xfad6},
+{0xc2ba, 0xfad7},
+{0xc2bf, 0xfa66},
+{0xc2c4, 0xfad9},
+{0xc2d2, 0xfada},
+{0xc2d7, 0xfadb},
+{0xc2db, 0xfadc},
+{0xc2de, 0xfadd},
+{0xc2ed, 0xfade},
+{0xc2f0, 0xfadf},
+{0xc3a1, 0xfae1},
+{0xc3b5, 0xfae2},
+{0xc3b9, 0xfae4},
+{0xc3c9, 0xfae3},
+{0xc3d8, 0xfae6},
+{0xc3fc, 0xfa64},
+{0xc3fe, 0xfae7},
+{0xc4cc, 0xfae9},
+{0xc4d9, 0xfaeb},
+{0xc4ea, 0xfaec},
+{0xc4fd, 0xfaed},
+{0xc5a7, 0xfaef},
+{0xc5b5, 0xfaf0},
+{0xc5b6, 0xfaf1},
+{0xc5d5, 0xfaf3},
+{0xc6b8, 0xfaf4},
+{0xc6d7, 0xfaf5},
+{0xc6e0, 0xfaf6},
+{0xc6e3, 0xfaf8},
+{0xc6ea, 0xfaf7},
+{0xc7a1, 0xfaf9},
+{0xc7ab, 0xfafa},
+{0xc7c3, 0xfafc},
+{0xc7c7, 0xfafb},
+{0xc7cb, 0xfb40},
+{0xc7cf, 0xfb41},
+{0xc7d9, 0xfb42},
+{0xc7e6, 0xfb45},
+{0xc7eb, 0xfb48},
+{0xc7ee, 0xfb46},
+{0xc7f0, 0xfb49},
+{0xc7fc, 0xfb47},
+{0xc8b1, 0xfb4a},
+{0xc8e5, 0xfb4b},
+{0xc8f8, 0xfb4c},
+{0xc9a6, 0xfb4d},
+{0xc9ab, 0xfb4e},
+{0xc9ad, 0xfb4f},
+{0xc9ca, 0xfb51},
+{0xc9d3, 0xfb52},
+{0xc9e3, 0xfb54},
+{0xc9e9, 0xfb53},
+{0xc9f4, 0xfb56},
+{0xc9f5, 0xfb57},
+{0xc9fc, 0xfb55},
+{0xcab3, 0xfb59},
+{0xcabd, 0xfb5a},
+{0xcaef, 0xfb5b},
+{0xcaf1, 0xfb5c},
+{0xcbae, 0xfb5d},
+{0xcbca, 0xfb5f},
+{0xcbe6, 0xfb60},
+{0xcbea, 0xfb61},
+{0xcbee, 0xfb64},
+{0xcbf0, 0xfb62},
+{0xcbf4, 0xfb63},
+{0xcbf9, 0xfb66},
+{0xcca5, 0xfb65},
+{0xccab, 0xfb67},
+{0xccad, 0xfb69},
+{0xccae, 0xfb68},
+{0xccb2, 0xfb6a},
+{0xccc2, 0xfb6b},
+{0xccd0, 0xfb6c},
+{0xccd9, 0xfb6d},
+{0xcdaa, 0xfaa8},
+{0xcdbb, 0xfb6f},
+{0xceba, 0xfb73},
+{0xcebb, 0xfb71},
+{0xcec3, 0xfb74},
+{0xcef2, 0xfb76},
+{0xcfd5, 0xfb78},
+{0xcfe2, 0xfb79},
+{0xcfe9, 0xfb7a},
+{0xcfed, 0xfb7b},
+{0xd0e5, 0xfb81},
+{0xd0e9, 0xfb83},
+{0xd1e8, 0xfb84},
+{0xd1ec, 0xfb87},
+{0xd2bb, 0xfb88},
+{0xd3e1, 0xfb8a},
+{0xd3e8, 0xfb8b},
+{0xd4a7, 0xfb8c},
+{0xd4d4, 0xfb8f},
+{0xd4e3, 0xfa5c},
+{0xd4f2, 0xfb90},
+{0xd5ae, 0xfb91},
+{0xd7de, 0xfb93},
+{0xd8a2, 0xfb95},
+{0xd8b7, 0xfb96},
+{0xd8c1, 0xfb97},
+{0xd8d1, 0xfb98},
+{0xd8f4, 0xfb99},
+{0xd9a1, 0xfa60},
+{0xd9c6, 0xfb9a},
+{0xd9c8, 0xfb9b},
+{0xd9d1, 0xfb9c},
+{0xdcd3, 0xfba2},
+{0xdcdf, 0xfa5d},
+{0xddc8, 0xfba3},
+{0xddd4, 0xfba4},
+{0xddea, 0xfba5},
+{0xddfa, 0xfba6},
+{0xdea4, 0xfba7},
+{0xdeb0, 0xfba8},
+{0xdeb5, 0xfbaa},
+{0xdecb, 0xfbab},
+{0xdfb9, 0xfbad},
+{0xdfc3, 0xfbaf},
+{0xe0d9, 0xfbb2},
+{0xe1e2, 0xfbb5},
+{0xe2c7, 0xfbb9},
+{0xe3a6, 0xfbbb},
+{0xe3a8, 0xfbba},
+{0xe3a9, 0xfbbc},
+{0xe3aa, 0xfbbf},
+{0xe3ab, 0xfbc0},
+{0xe3af, 0xfbbd},
+{0xe3b0, 0xfbbe},
+{0xe3bc, 0xfbc1},
+{0xe3bf, 0xfbc3},
+{0xe3c1, 0xfbc2},
+{0xe3d4, 0xfbca},
+{0xe3d5, 0xfbc4},
+{0xe3d6, 0xfbc6},
+{0xe3d8, 0xfbc5},
+{0xe3df, 0xfbc7},
+{0xe3e1, 0xfbc9},
+{0xe3e3, 0xfbc8},
+{0xe3e9, 0xfbcb},
+{0xe3f1, 0xfbcd},
+{0xe3f2, 0xfbce},
+{0xe3f8, 0xfa5f},
+{0xe4a6, 0xfbcc},
+{0xe4be, 0xfbd2},
+{0xe4bf, 0xfbd6},
+{0xe4c0, 0xfbd4},
+{0xe4c1, 0xfbd0},
+{0xe4c3, 0xfbd1},
+{0xe4c7, 0xfbd5},
+{0xe4cb, 0xfbcf},
+{0xe4d0, 0xfa65},
+{0xe4d1, 0xfbd9},
+{0xe4d2, 0xfbdc},
+{0xe4d4, 0xfbde},
+{0xe4db, 0xfbdd},
+{0xe4dc, 0xfbdb},
+{0xe4de, 0xfbd8},
+{0xe4e0, 0xfbd7},
+{0xe4e9, 0xfa5e},
+{0xe4ef, 0xfbe0},
+{0xe4fa, 0xfbdf},
+{0xe5b3, 0xfbe1},
+{0xe5bf, 0xfbe2},
+{0xe5c9, 0xfbe3},
+{0xe5d0, 0xfbe4},
+{0xe5e2, 0xfbe5},
+{0xe5ea, 0xfbe6},
+{0xe5eb, 0xfbe7},
+{0xe6e8, 0xfbeb},
+{0xe6ef, 0xfbec},
+{0xe7ac, 0xfbed},
+{0xe7ae, 0xfbef},
+{0xe7b1, 0xfbf1},
+{0xe7b2, 0xfbf3},
+{0xe8b1, 0xfbf4},
+{0xe8b6, 0xfbf5},
+{0xe8dd, 0xfbf8},
+{0xe9d1, 0xfbfb},
+{0xe9ed, 0xfc40},
+{0xeacd, 0xfc41},
+{0xeadb, 0xfc43},
+{0xeae6, 0xfc44},
+{0xeaea, 0xfc45},
+{0xeba5, 0xfc46},
+{0xebfa, 0xfc48},
+{0xebfb, 0xfc47},
+{0xecd6, 0xfc4a},
+{0xf3f3, 0xfa40},
+{0xf3f4, 0xfa41},
+{0xf3f5, 0xfa42},
+{0xf3f6, 0xfa43},
+{0xf3f7, 0xfa44},
+{0xf3f8, 0xfa45},
+{0xf3f9, 0xfa46},
+{0xf3fa, 0xfa47},
+{0xf3fb, 0xfa48},
+{0xf3fc, 0xfa49},
+{0xf3fd, 0xfa4a},
+{0xf3fe, 0xfa4b},
+{0xf4a1, 0xfa4c},
+{0xf4a2, 0xfa4d},
+{0xf4a3, 0xfa4e},
+{0xf4a4, 0xfa4f},
+{0xf4a5, 0xfa50},
+{0xf4a6, 0xfa51},
+{0xf4a7, 0xfa52},
+{0xf4a8, 0xfa53},
+{0xf4a9, 0xfa56},
+{0xf4aa, 0xfa57},
+{0xf4ab, 0xfa58},
+{0xf4ac, 0xfa59},
+{0xf4ad, 0xfa5a},
+{0xf4ae, 0xfa62},
+{0xf4af, 0xfa6a},
+{0xf4b0, 0xfa7c},
+{0xf4b1, 0xfa83},
+{0xf4b2, 0xfa8a},
+{0xf4b3, 0xfa8b},
+{0xf4b4, 0xfa90},
+{0xf4b5, 0xfa92},
+{0xf4b6, 0xfa96},
+{0xf4b7, 0xfa9b},
+{0xf4b8, 0xfa9c},
+{0xf4b9, 0xfa9d},
+{0xf4ba, 0xfaaa},
+{0xf4bb, 0xfaae},
+{0xf4bc, 0xfab0},
+{0xf4bd, 0xfab1},
+{0xf4be, 0xfaba},
+{0xf4bf, 0xfabd},
+{0xf4c0, 0xfac1},
+{0xf4c1, 0xfacd},
+{0xf4c2, 0xfad0},
+{0xf4c3, 0xfad5},
+{0xf4c4, 0xfad8},
+{0xf4c5, 0xfae0},
+{0xf4c6, 0xfae5},
+{0xf4c7, 0xfae8},
+{0xf4c8, 0xfaea},
+{0xf4c9, 0xfaee},
+{0xf4ca, 0xfaf2},
+{0xf4cb, 0xfb43},
+{0xf4cc, 0xfb44},
+{0xf4cd, 0xfb50},
+{0xf4ce, 0xfb58},
+{0xf4cf, 0xfb5e},
+{0xf4d0, 0xfb6e},
+{0xf4d1, 0xfb70},
+{0xf4d2, 0xfb72},
+{0xf4d3, 0xfb75},
+{0xf4d4, 0xfb7c},
+{0xf4d5, 0xfb7d},
+{0xf4d6, 0xfb7e},
+{0xf4d7, 0xfb80},
+{0xf4d8, 0xfb82},
+{0xf4d9, 0xfb85},
+{0xf4da, 0xfb86},
+{0xf4db, 0xfb89},
+{0xf4dc, 0xfb8d},
+{0xf4dd, 0xfb8e},
+{0xf4de, 0xfb92},
+{0xf4df, 0xfb94},
+{0xf4e0, 0xfb9d},
+{0xf4e1, 0xfb9e},
+{0xf4e2, 0xfb9f},
+{0xf4e3, 0xfba0},
+{0xf4e4, 0xfba1},
+{0xf4e5, 0xfba9},
+{0xf4e6, 0xfbac},
+{0xf4e7, 0xfbae},
+{0xf4e8, 0xfbb0},
+{0xf4e9, 0xfbb1},
+{0xf4ea, 0xfbb3},
+{0xf4eb, 0xfbb4},
+{0xf4ec, 0xfbb6},
+{0xf4ed, 0xfbb7},
+{0xf4ee, 0xfbb8},
+{0xf4ef, 0xfbd3},
+{0xf4f0, 0xfbda},
+{0xf4f1, 0xfbe8},
+{0xf4f2, 0xfbe9},
+{0xf4f3, 0xfbea},
+{0xf4f4, 0xfbee},
+{0xf4f5, 0xfbf0},
+{0xf4f6, 0xfbf2},
+{0xf4f7, 0xfbf6},
+{0xf4f8, 0xfbf7},
+{0xf4f9, 0xfbf9},
+{0xf4fa, 0xfbfa},
+{0xf4fb, 0xfbfc},
+{0xf4fc, 0xfc42},
+{0xf4fd, 0xfc49},
+{0xf4fe, 0xfc4b},
+};
+
+#define EUC3REVTBLSIZ (sizeof(euc3rev) / sizeof(sjis_euc_revmap_t))
+
+#endif /* _KANJI_C_ */
+#endif /* _KANJI_H_ */
diff --git a/source/include/libsmb_internal.h b/source/include/libsmb_internal.h
deleted file mode 100644
index 21fe47d4b29..00000000000
--- a/source/include/libsmb_internal.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _LIBSMB_INTERNAL_H_
-#define _LIBSMB_INTERNAL_H_
-
-#define SMBC_MAX_NAME 1023
-#define SMBC_FILE_MODE (S_IFREG | 0444)
-#define SMBC_DIR_MODE (S_IFDIR | 0555)
-
-
-#include "../include/libsmbclient.h"
-
-
-struct _SMBCSRV {
- struct cli_state cli;
- dev_t dev;
- BOOL no_pathinfo2;
- int server_fd;
-
- SMBCSRV *next, *prev;
-
-};
-
-/*
- * Keep directory entries in a list
- */
-struct smbc_dir_list {
- struct smbc_dir_list *next;
- struct smbc_dirent *dirent;
-};
-
-
-/*
- * Structure for open file management
- */
-struct _SMBCFILE {
- int cli_fd;
- char *fname;
- off_t offset;
- struct _SMBCSRV *srv;
- BOOL file;
- struct smbc_dir_list *dir_list, *dir_end, *dir_next;
- int dir_type, dir_error;
-
- SMBCFILE *next, *prev;
-};
-
-
-struct smbc_internal_data {
-
- /** INTERNAL: is this handle initialized ?
- */
- int _initialized;
-
- /** INTERNAL: dirent pointer location
- */
- char _dirent[512];
-
- /** INTERNAL: server connection list
- */
- SMBCSRV * _servers;
-
- /** INTERNAL: open file/dir list
- */
- SMBCFILE * _files;
-};
-
-
-#endif
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index 68c4a053d1b..98701b2693e 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -1,12 +1,10 @@
/*=====================================================================
Unix SMB/Netbios implementation.
+ Version 2.0
SMB client library API definitions
Copyright (C) Andrew Tridgell 1998
Copyright (C) Richard Sharpe 2000
Copyright (C) John Terpsra 2000
- Copyright (C) Tom Jansen (Ninja ISD) 2002
- Copyright (C) Derrell Lipman 2003
-
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,10 +34,6 @@
* \ingroup libsmbclient
* Data structures, types, and constants
*/
-/** \defgroup callback Callback function types
-* \ingroup libsmbclient
-* Callback functions
-*/
/** \defgroup file File Functions
* \ingroup libsmbclient
* Functions used to access individual file contents
@@ -56,7 +50,7 @@
* \ingroup libsmbclient
* Functions used to access printing functionality
*/
-/** \defgroup misc Miscellaneous Functions
+/** \defgroup attribute Miscellaneous Functions
* \ingroup libsmbclient
* Functions that don't fit in to other categories
*/
@@ -66,10 +60,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <utime.h>
-
-#define SMBC_BASE_FD 10000 /* smallest file descriptor returned */
+#define SMBC_MAX_NAME 1023
#define SMBC_WORKGROUP 1
#define SMBC_SERVER 2
#define SMBC_FILE_SHARE 3
@@ -80,6 +72,12 @@
#define SMBC_FILE 8
#define SMBC_LINK 9
+#define SMBC_FILE_MODE (S_IFREG | 0444)
+#define SMBC_DIR_MODE (S_IFDIR | 0555)
+
+#define SMBC_MAX_FD 10000
+
+
/**@ingroup structure
* Structure that represents a directory entry.
*
@@ -96,56 +94,44 @@ struct smbc_dirent
SMBC_DIR=7,
SMBC_FILE=8,
SMBC_LINK=9,*/
- unsigned int smbc_type;
+ uint smbc_type;
/** Length of this smbc_dirent in bytes
*/
- unsigned int dirlen;
+ uint dirlen;
/** The length of the comment string in bytes (includes null
* terminator)
*/
- unsigned int commentlen;
+ uint commentlen;
/** Points to the null terminated comment string
*/
char *comment;
/** The length of the name string in bytes (includes null
* terminator)
*/
- unsigned int namelen;
+ uint namelen;
/** Points to the null terminated name string
*/
char name[1];
};
-/*
- * Flags for smbc_setxattr()
- * Specify a bitwise OR of these, or 0 to add or replace as necessary
- */
-#define SMBC_XATTR_FLAG_CREATE 0x1 /* fail if attr already exists */
-#define SMBC_XATTR_FLAG_REPLACE 0x2 /* fail if attr does not exist */
-
-
-#ifndef ENOATTR
-# define ENOATTR ENOENT /* No such attribute */
-#endif
-
-
+#ifndef _CLIENT_H
+typedef unsigned short uint16;
/**@ingroup structure
* Structure that represents a print job.
*
*/
-#ifndef _CLIENT_H
struct print_job_info
{
/** numeric ID of the print job
*/
- unsigned short id;
+ uint16 id;
/** represents print job priority (lower numbers mean higher priority)
*/
- unsigned short priority;
+ uint16 priority;
/** Size of the print job
*/
@@ -164,29 +150,10 @@ struct print_job_info
*/
time_t t;
};
-#endif /* _CLIENT_H */
-
-
-/**@ingroup structure
- * Server handle
- */
-typedef struct _SMBCSRV SMBCSRV;
+#endif
-/**@ingroup structure
- * File or directory handle
- */
-typedef struct _SMBCFILE SMBCFILE;
/**@ingroup structure
- * File or directory handle
- */
-typedef struct _SMBCCTX SMBCCTX;
-
-
-
-
-
-/**@ingroup callback
* Authentication callback function type.
*
* Type for the the authentication function called by the library to
@@ -222,301 +189,14 @@ typedef void (*smbc_get_auth_data_fn)(const char *srv,
char *pw, int pwlen);
-/**@ingroup callback
+/**@ingroup structure
* Print job info callback function type.
*
* @param i pointer to print job information structure
*
*/
-typedef void (*smbc_list_print_job_fn)(struct print_job_info *i);
-
-
-/**@ingroup callback
- * Check if a server is still good
- *
- * @param c pointer to smb context
- *
- * @param srv pointer to server to check
- *
- * @return 0 when connection is good. 1 on error.
- *
- */
-typedef int (*smbc_check_server_fn)(SMBCCTX * c, SMBCSRV *srv);
-
-/**@ingroup callback
- * Remove a server if unused
- *
- * @param c pointer to smb context
- *
- * @param srv pointer to server to remove
- *
- * @return 0 on success. 1 on failure.
- *
- */
-typedef int (*smbc_remove_unused_server_fn)(SMBCCTX * c, SMBCSRV *srv);
-
-
-/**@ingroup callback
- * Add a server to the cache system
- *
- * @param c pointer to smb context
- *
- * @param srv pointer to server to add
- *
- * @param server server name
- *
- * @param share share name
- *
- * @param workgroup workgroup used to connect
- *
- * @param username username used to connect
- *
- * @return 0 on success. 1 on failure.
- *
- */
-typedef int (*smbc_add_cached_srv_fn) (SMBCCTX * c, SMBCSRV *srv,
- const char * server, const char * share,
- const char * workgroup, const char * username);
-
-/**@ingroup callback
- * Look up a server in the cache system
- *
- * @param c pointer to smb context
- *
- * @param server server name to match
- *
- * @param share share name to match
- *
- * @param workgroup workgroup to match
- *
- * @param username username to match
- *
- * @return pointer to SMBCSRV on success. NULL on failure.
- *
- */
-typedef SMBCSRV * (*smbc_get_cached_srv_fn) (SMBCCTX * c, const char * server,
- const char * share, const char * workgroup,
- const char * username);
-
-/**@ingroup callback
- * Check if a server is still good
- *
- * @param c pointer to smb context
- *
- * @param srv pointer to server to remove
- *
- * @return 0 when found and removed. 1 on failure.
- *
- */
-typedef int (*smbc_remove_cached_srv_fn)(SMBCCTX * c, SMBCSRV *srv);
-
-
-/**@ingroup callback
- * Try to remove all servers from the cache system and disconnect
- *
- * @param c pointer to smb context
- *
- * @return 0 when found and removed. 1 on failure.
- *
- */
-typedef int (*smbc_purge_cached_fn) (SMBCCTX * c);
-
-
-
-
-/**@ingroup structure
- * Structure that contains a client context information
- * This structure is know as SMBCCTX
- */
-struct _SMBCCTX {
- /** debug level
- */
- int debug;
-
- /** netbios name used for making connections
- */
- char * netbios_name;
-
- /** workgroup name used for making connections
- */
- char * workgroup;
-
- /** username used for making connections
- */
- char * user;
-
- /** timeout used for waiting on connections / response data (in milliseconds)
- */
- int timeout;
-
- /** callable functions for files:
- * For usage and return values see the smbc_* functions
- */
- SMBCFILE * (*open) (SMBCCTX *c, const char *fname, int flags, mode_t mode);
- SMBCFILE * (*creat) (SMBCCTX *c, const char *path, mode_t mode);
- ssize_t (*read) (SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);
- ssize_t (*write) (SMBCCTX *c, SMBCFILE *file, void *buf, size_t count);
- int (*unlink) (SMBCCTX *c, const char *fname);
- int (*rename) (SMBCCTX *ocontext, const char *oname,
- SMBCCTX *ncontext, const char *nname);
- off_t (*lseek) (SMBCCTX *c, SMBCFILE * file, off_t offset, int whence);
- int (*stat) (SMBCCTX *c, const char *fname, struct stat *st);
- int (*fstat) (SMBCCTX *c, SMBCFILE *file, struct stat *st);
- int (*close) (SMBCCTX *c, SMBCFILE *file);
-
- /** callable functions for dirs
- */
- SMBCFILE * (*opendir) (SMBCCTX *c, const char *fname);
- int (*closedir)(SMBCCTX *c, SMBCFILE *dir);
- struct smbc_dirent * (*readdir)(SMBCCTX *c, SMBCFILE *dir);
- int (*getdents)(SMBCCTX *c, SMBCFILE *dir,
- struct smbc_dirent *dirp, int count);
- int (*mkdir) (SMBCCTX *c, const char *fname, mode_t mode);
- int (*rmdir) (SMBCCTX *c, const char *fname);
- off_t (*telldir) (SMBCCTX *c, SMBCFILE *dir);
- int (*lseekdir)(SMBCCTX *c, SMBCFILE *dir, off_t offset);
- int (*fstatdir)(SMBCCTX *c, SMBCFILE *dir, struct stat *st);
- int (*chmod)(SMBCCTX *c, const char *fname, mode_t mode);
- int (*utimes)(SMBCCTX *c,
- const char *fname, struct timeval *tbuf);
- int (*setxattr)(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size,
- int flags);
- int (*getxattr)(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size);
- int (*removexattr)(SMBCCTX *context,
- const char *fname,
- const char *name);
- int (*listxattr)(SMBCCTX *context,
- const char *fname,
- char *list,
- size_t size);
-
- /** callable functions for printing
- */
- int (*print_file)(SMBCCTX *c_file, const char *fname,
- SMBCCTX *c_print, const char *printq);
- SMBCFILE * (*open_print_job)(SMBCCTX *c, const char *fname);
- int (*list_print_jobs)(SMBCCTX *c, const char *fname, smbc_list_print_job_fn fn);
- int (*unlink_print_job)(SMBCCTX *c, const char *fname, int id);
-
-
- /** Callbacks
- * These callbacks _always_ have to be initialized because they will not be checked
- * at dereference for increased speed.
- */
- struct _smbc_callbacks {
- /** authentication function callback: called upon auth requests
- */
- smbc_get_auth_data_fn auth_fn;
-
- /** check if a server is still good
- */
- smbc_check_server_fn check_server_fn;
-
- /** remove a server if unused
- */
- smbc_remove_unused_server_fn remove_unused_server_fn;
-
- /** Cache subsystem
- * For an example cache system see samba/source/libsmb/libsmb_cache.c
- * Cache subsystem functions follow.
- */
-
- /** server cache addition
- */
- smbc_add_cached_srv_fn add_cached_srv_fn;
-
- /** server cache lookup
- */
- smbc_get_cached_srv_fn get_cached_srv_fn;
-
- /** server cache removal
- */
- smbc_remove_cached_srv_fn remove_cached_srv_fn;
-
- /** server cache purging, try to remove all cached servers (disconnect)
- */
- smbc_purge_cached_fn purge_cached_fn;
- } callbacks;
-
-
- /** Space to store private data of the server cache.
- */
- struct smbc_server_cache * server_cache;
-
- /** INTERNAL DATA
- * do _NOT_ touch this from your program !
- */
- struct smbc_internal_data * internal;
-
-};
-
-
-/**@ingroup misc
- * Create a new SBMCCTX (a context).
- *
- * Must be called before the context is passed to smbc_context_init()
- *
- * @return The given SMBCCTX pointer on success, NULL on error with errno set:
- * - ENOMEM Out of memory
- *
- * @see smbc_free_context(), smbc_init_context()
- *
- * @note Do not forget to smbc_init_context() the returned SMBCCTX pointer !
- */
-SMBCCTX * smbc_new_context(void);
-
-/**@ingroup misc
- * Delete a SBMCCTX (a context) acquired from smbc_new_context().
- *
- * The context will be deleted if possible.
- *
- * @param context A pointer to a SMBCCTX obtained from smbc_new_context()
- *
- * @param shutdown_ctx If 1, all connections and files will be closed even if they are busy.
- *
- *
- * @return Returns 0 on succes. Returns 1 on failure with errno set:
- * - EBUSY Server connections are still used, Files are open or cache
- * could not be purged
- * - EBADF context == NULL
- *
- * @see smbc_new_context()
- *
- * @note It is advised to clean up all the contexts with shutdown_ctx set to 1
- * just before exit()'ing. When shutdown_ctx is 0, this function can be
- * use in periodical cleanup functions for example.
- */
-int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
-
+typedef void (*smbc_get_print_job_info)(struct print_job_info *i);
-/**@ingroup misc
- * Initialize a SBMCCTX (a context).
- *
- * Must be called before using any SMBCCTX API function
- *
- * @param context A pointer to a SMBCCTX obtained from smbc_new_context()
- *
- * @return A pointer to the given SMBCCTX on success, NULL on error with errno set:
- * - EBADF NULL context given
- * - ENOMEM Out of memory
- * - ENOENT The smb.conf file would not load
- *
- * @see smbc_new_context()
- *
- * @note my_context = smbc_init_context(smbc_new_context()) is perfectly safe,
- * but it might leak memory on smbc_context_init() failure. Avoid this.
- * You'll have to call smbc_free_context() yourself on failure.
- */
-
-SMBCCTX * smbc_init_context(SMBCCTX * context);
/**@ingroup misc
* Initialize the samba client library.
@@ -535,32 +215,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context);
* - ENOENT The smb.conf file would not load
*
*/
-
int smbc_init(smbc_get_auth_data_fn fn, int debug);
-/**@ingroup misc
- * Set or retrieve the compatibility library's context pointer
- *
- * @param context New context to use, or NULL. If a new context is provided,
- * it must have allocated with smbc_new_context() and
- * initialized with smbc_init_context(), followed, optionally,
- * by some manual changes to some of the non-internal fields.
- *
- * @return The old context.
- *
- * @see smbc_new_context(), smbc_init_context(), smbc_init()
- *
- * @note This function may be called prior to smbc_init() to force
- * use of the next context without any internal calls to
- * smbc_new_context() or smbc_init_context(). It may also
- * be called after smbc_init() has already called those two
- * functions, to replace the existing context with a new one.
- * Care should be taken, in this latter case, to ensure that
- * the server cache and any data allocated by the
- * authentication functions have been freed, if necessary.
- */
-
-SMBCCTX * smbc_set_context(SMBCCTX * new_context);
/**@ingroup file
* Open a file on an SMB server.
@@ -613,9 +269,9 @@ SMBCCTX * smbc_set_context(SMBCCTX * new_context);
* try again with an empty username and password. This
* often gets mapped to the guest account on some machines.
*/
-
int smbc_open(const char *furl, int flags, mode_t mode);
+
/**@ingroup file
* Create a file on an SMB server.
*
@@ -647,9 +303,9 @@ int smbc_open(const char *furl, int flags, mode_t mode);
* @see smbc_open()
*
*/
-
int smbc_creat(const char *furl, mode_t mode);
+
/**@ingroup file
* Read from a file using an opened file handle.
*
@@ -1071,807 +727,6 @@ int smbc_chown(const char *url, uid_t owner, gid_t group);
*/
int smbc_chmod(const char *url, mode_t mode);
-/**@ingroup attribute
- * Change the last modification time on a file
- *
- * @param url The smb url of the file or directory to change
- * the modification time of
- *
- * @param tbuf A timeval structure which contains the desired
- * modification time. NOTE: Only the tv_sec field is
- * used. The tv_usec (microseconds) portion is ignored.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - EPERM Permission was denied.
- *
- */
-int smbc_utimes(const char *url, struct timeval *tbuf);
-
-#ifdef HAVE_UTIME_H
-/**@ingroup attribute
- * Change the last modification time on a file
- *
- * @param url The smb url of the file or directory to change
- * the modification time of
- *
- * @param utbuf A utimebuf structure which contains the desired
- * modification time. NOTE: Although the structure contains
- * an access time as well, the access time value is ignored.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- *
- */
-int smbc_utime(const char *fname, struct utimbuf *utbuf);
-#endif
-
-/**@ingroup attribute
- * Set extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list)
- *
- * @param url The smb url of the file or directory to set extended
- * attributes for.
- *
- * @param name The name of an attribute to be changed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter should contain a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value The value to be assigned to the specified attribute name.
- * This buffer should contain only the attribute value if the
- * name was of the "system.nt_sec_desc.<attribute_name>"
- * form. If the name was of the "system.nt_sec_desc.*" form
- * then a complete security descriptor, with name:value pairs
- * separated by tabs, commas, or newlines (not spaces!),
- * should be provided in this value buffer. A complete
- * security descriptor will contain one or more entries
- * selected from the following:
- *
- * REVISION:<revision number>
- * OWNER:<sid or name>
- * GROUP:<sid or name>
- * ACL:<sid or name>:<type>/<flags>/<mask>
- *
- * The revision of the ACL specifies the internal Windows NT
- * ACL revision for the security descriptor. If not specified
- * it defaults to 1. Using values other than 1 may cause
- * strange behaviour.
- *
- * The owner and group specify the owner and group sids for
- * the object. If the attribute name (either '*+' with a
- * complete security descriptor, or individual 'owner+' or
- * 'group+' attribute names) ended with a plus sign, the
- * specified name is resolved to a SID value, using the
- * server on which the file or directory resides. Otherwise,
- * the value should be provided in SID-printable format as
- * S-1-x-y-z, and is used directly. The <sid or name>
- * associated with the ACL: attribute should be provided
- * similarly.
- *
- * @param size The number of the bytes of data in the value buffer
- *
- * @param flags A bit-wise OR of zero or more of the following:
- * SMBC_XATTR_FLAG_CREATE -
- * fail if the named attribute already exists
- * SMBC_XATTR_FLAG_REPLACE -
- * fail if the attribute does not already exist
- *
- * If neither flag is specified, the specified attributes
- * will be added or replace existing attributes of the same
- * name, as necessary.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note Attribute names are compared in a case-insensitive
- * fashion. All of the following are equivalent, although
- * the all-lower-case name is the preferred format:
- * system.nt_sec_desc.owner
- * SYSTEM.NT_SEC_DESC.OWNER
- * sYsTeM.nt_sEc_desc.owNER
- *
- */
-int smbc_setxattr(const char *url,
- const char *name,
- const void *value,
- size_t size,
- int flags);
-
-
-/**@ingroup attribute
- * Set extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list). The
- * POSIX function which this maps to would act on a symbolic link rather than
- * acting on what the symbolic link points to, but with no symbolic links in
- * SMB file systems, this function is functionally identical to
- * smbc_setxattr().
- *
- * @param url The smb url of the file or directory to set extended
- * attributes for.
- *
- * @param name The name of an attribute to be changed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter should contain a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value The value to be assigned to the specified attribute name.
- * This buffer should contain only the attribute value if the
- * name was of the "system.nt_sec_desc.<attribute_name>"
- * form. If the name was of the "system.nt_sec_desc.*" form
- * then a complete security descriptor, with name:value pairs
- * separated by tabs, commas, or newlines (not spaces!),
- * should be provided in this value buffer. A complete
- * security descriptor will contain one or more entries
- * selected from the following:
- *
- * REVISION:<revision number>
- * OWNER:<sid or name>
- * GROUP:<sid or name>
- * ACL:<sid or name>:<type>/<flags>/<mask>
- *
- * The revision of the ACL specifies the internal Windows NT
- * ACL revision for the security descriptor. If not specified
- * it defaults to 1. Using values other than 1 may cause
- * strange behaviour.
- *
- * The owner and group specify the owner and group sids for
- * the object. If the attribute name (either '*+' with a
- * complete security descriptor, or individual 'owner+' or
- * 'group+' attribute names) ended with a plus sign, the
- * specified name is resolved to a SID value, using the
- * server on which the file or directory resides. Otherwise,
- * the value should be provided in SID-printable format as
- * S-1-x-y-z, and is used directly. The <sid or name>
- * associated with the ACL: attribute should be provided
- * similarly.
- *
- * @param size The number of the bytes of data in the value buffer
- *
- * @param flags A bit-wise OR of zero or more of the following:
- * SMBC_XATTR_FLAG_CREATE -
- * fail if the named attribute already exists
- * SMBC_XATTR_FLAG_REPLACE -
- * fail if the attribute does not already exist
- *
- * If neither flag is specified, the specified attributes
- * will be added or replace existing attributes of the same
- * name, as necessary.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note Attribute names are compared in a case-insensitive
- * fashion. All of the following are equivalent, although
- * the all-lower-case name is the preferred format:
- * system.nt_sec_desc.owner
- * SYSTEM.NT_SEC_DESC.OWNER
- * sYsTeM.nt_sEc_desc.owNER
- *
- */
-int smbc_lsetxattr(const char *url,
- const char *name,
- const void *value,
- size_t size,
- int flags);
-
-
-/**@ingroup attribute
- * Set extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list)
- *
- * @param fd A file descriptor associated with an open file (as
- * previously returned by smbc_open(), to get extended
- * attributes for.
- *
- * @param name The name of an attribute to be changed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter should contain a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value The value to be assigned to the specified attribute name.
- * This buffer should contain only the attribute value if the
- * name was of the "system.nt_sec_desc.<attribute_name>"
- * form. If the name was of the "system.nt_sec_desc.*" form
- * then a complete security descriptor, with name:value pairs
- * separated by tabs, commas, or newlines (not spaces!),
- * should be provided in this value buffer. A complete
- * security descriptor will contain one or more entries
- * selected from the following:
- *
- * REVISION:<revision number>
- * OWNER:<sid or name>
- * GROUP:<sid or name>
- * ACL:<sid or name>:<type>/<flags>/<mask>
- *
- * The revision of the ACL specifies the internal Windows NT
- * ACL revision for the security descriptor. If not specified
- * it defaults to 1. Using values other than 1 may cause
- * strange behaviour.
- *
- * The owner and group specify the owner and group sids for
- * the object. If the attribute name (either '*+' with a
- * complete security descriptor, or individual 'owner+' or
- * 'group+' attribute names) ended with a plus sign, the
- * specified name is resolved to a SID value, using the
- * server on which the file or directory resides. Otherwise,
- * the value should be provided in SID-printable format as
- * S-1-x-y-z, and is used directly. The <sid or name>
- * associated with the ACL: attribute should be provided
- * similarly.
- *
- * @param size The number of the bytes of data in the value buffer
- *
- * @param flags A bit-wise OR of zero or more of the following:
- * SMBC_XATTR_FLAG_CREATE -
- * fail if the named attribute already exists
- * SMBC_XATTR_FLAG_REPLACE -
- * fail if the attribute does not already exist
- *
- * If neither flag is specified, the specified attributes
- * will be added or replace existing attributes of the same
- * name, as necessary.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note Attribute names are compared in a case-insensitive
- * fashion. All of the following are equivalent, although
- * the all-lower-case name is the preferred format:
- * system.nt_sec_desc.owner
- * SYSTEM.NT_SEC_DESC.OWNER
- * sYsTeM.nt_sEc_desc.owNER
- *
- */
-int smbc_fsetxattr(int fd,
- const char *name,
- const void *value,
- size_t size,
- int flags);
-
-
-/**@ingroup attribute
- * Get extended attributes for a file.
- *
- * @param url The smb url of the file or directory to get extended
- * attributes for.
- *
- * @param name The name of an attribute to be retrieved. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value A pointer to a buffer in which the value of the specified
- * attribute will be placed (unless size is zero).
- *
- * @param size The size of the buffer pointed to by value. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold the attribute value will be returned,
- * but nothing will be placed into the value buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_getxattr(const char *url,
- const char *name,
- const void *value,
- size_t size);
-
-
-/**@ingroup attribute
- * Get extended attributes for a file. The POSIX function which this maps to
- * would act on a symbolic link rather than acting on what the symbolic link
- * points to, but with no symbolic links in SMB file systems, this function
- * is functionally identical to smbc_getxattr().
- *
- * @param url The smb url of the file or directory to get extended
- * attributes for.
- *
- * @param name The name of an attribute to be retrieved. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value A pointer to a buffer in which the value of the specified
- * attribute will be placed (unless size is zero).
- *
- * @param size The size of the buffer pointed to by value. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold the attribute value will be returned,
- * but nothing will be placed into the value buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_lgetxattr(const char *url,
- const char *name,
- const void *value,
- size_t size);
-
-
-/**@ingroup attribute
- * Get extended attributes for a file.
- *
- * @param fd A file descriptor associated with an open file (as
- * previously returned by smbc_open(), to get extended
- * attributes for.
- *
- * @param name The name of an attribute to be retrieved. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @param value A pointer to a buffer in which the value of the specified
- * attribute will be placed (unless size is zero).
- *
- * @param size The size of the buffer pointed to by value. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold the attribute value will be returned,
- * but nothing will be placed into the value buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * or one of the parameters is not of a correct
- * form
- * - ENOMEM No memory was available for internal needs
- * - EEXIST If the attribute already exists and the flag
- * SMBC_XATTR_FLAG_CREAT was specified
- * - ENOATTR If the attribute does not exist and the flag
- * SMBC_XATTR_FLAG_REPLACE was specified
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_fgetxattr(int fd,
- const char *name,
- const void *value,
- size_t size);
-
-
-/**@ingroup attribute
- * Remove extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list)
- *
- * @param url The smb url of the file or directory to remove the extended
- * attributes for.
- *
- * @param name The name of an attribute to be removed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_removexattr(const char *url,
- const char *name);
-
-
-/**@ingroup attribute
- * Remove extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list) The POSIX
- * function which this maps to would act on a symbolic link rather than acting
- * on what the symbolic link points to, but with no symbolic links in SMB file
- * systems, this function is functionally identical to smbc_removexattr().
- *
- * @param url The smb url of the file or directory to remove the extended
- * attributes for.
- *
- * @param name The name of an attribute to be removed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_lremovexattr(const char *url,
- const char *name);
-
-
-/**@ingroup attribute
- * Remove extended attributes for a file. This is used for modifying a file's
- * security descriptor (i.e. owner, group, and access control list)
- *
- * @param fd A file descriptor associated with an open file (as
- * previously returned by smbc_open(), to get extended
- * attributes for.
- *
- * @param name The name of an attribute to be removed. Names are of
- * one of the following forms:
- *
- * system.nt_sec_desc.<attribute name>
- * system.nt_sec_desc.*
- * system.nt_sec_desc.*+
- *
- * where <attribute name> is one of:
- *
- * revision
- * owner
- * owner+
- * group
- * group+
- * acl:<name or sid>
- * acl+:<name or sid>
- *
- * In the forms "system.nt_sec_desc.*" and
- * "system.nt_sec_desc.*+", the asterisk and plus signs are
- * literal, i.e. the string is provided exactly as shown, and
- * the value parameter will return a complete security
- * descriptor with name:value pairs separated by tabs,
- * commas, or newlines (not spaces!).
- *
- * The plus sign ('+') indicates that SIDs should be mapped
- * to names. Without the plus sign, SIDs are not mapped;
- * rather they are simply converted to a string format.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- */
-int smbc_fremovexattr(int fd,
- const char *name);
-
-
-/**@ingroup attribute
- * List the supported extended attribute names associated with a file
- *
- * @param url The smb url of the file or directory to list the extended
- * attributes for.
- *
- * @param list A pointer to a buffer in which the list of attributes for
- * the specified file or directory will be placed (unless
- * size is zero).
- *
- * @param size The size of the buffer pointed to by list. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold all of the attribute names will be
- * returned, but nothing will be placed into the list buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note This function always returns all attribute names supported
- * by NT file systems, regardless of wether the referenced
- * file system supports extended attributes (e.g. a Windows
- * 2000 machine supports extended attributes if NTFS is used,
- * but not if FAT is used, and Windows 98 doesn't support
- * extended attributes at all. Whether this is a feature or
- * a bug is yet to be decided.
- */
-int smbc_listxattr(const char *url,
- char *list,
- size_t size);
-
-/**@ingroup attribute
- * List the supported extended attribute names associated with a file The
- * POSIX function which this maps to would act on a symbolic link rather than
- * acting on what the symbolic link points to, but with no symbolic links in
- * SMB file systems, this function is functionally identical to
- * smbc_listxattr().
- *
- * @param url The smb url of the file or directory to list the extended
- * attributes for.
- *
- * @param list A pointer to a buffer in which the list of attributes for
- * the specified file or directory will be placed (unless
- * size is zero).
- *
- * @param size The size of the buffer pointed to by list. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold all of the attribute names will be
- * returned, but nothing will be placed into the list buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note This function always returns all attribute names supported
- * by NT file systems, regardless of wether the referenced
- * file system supports extended attributes (e.g. a Windows
- * 2000 machine supports extended attributes if NTFS is used,
- * but not if FAT is used, and Windows 98 doesn't support
- * extended attributes at all. Whether this is a feature or
- * a bug is yet to be decided.
- */
-int smbc_llistxattr(const char *url,
- char *list,
- size_t size);
-
-/**@ingroup attribute
- * List the supported extended attribute names associated with a file
- *
- * @param fd A file descriptor associated with an open file (as
- * previously returned by smbc_open(), to get extended
- * attributes for.
- *
- * @param list A pointer to a buffer in which the list of attributes for
- * the specified file or directory will be placed (unless
- * size is zero).
- *
- * @param size The size of the buffer pointed to by list. This parameter
- * may also be zero, in which case the size of the buffer
- * required to hold all of the attribute names will be
- * returned, but nothing will be placed into the list buffer.
- *
- * @return 0 on success, < 0 on error with errno set:
- * - EINVAL The client library is not properly initialized
- * - ENOMEM No memory was available for internal needs
- * - EPERM Permission was denied.
- * - ENOTSUP The referenced file system does not support
- * extended attributes
- *
- * @note This function always returns all attribute names supported
- * by NT file systems, regardless of wether the referenced
- * file system supports extended attributes (e.g. a Windows
- * 2000 machine supports extended attributes if NTFS is used,
- * but not if FAT is used, and Windows 98 doesn't support
- * extended attributes at all. Whether this is a feature or
- * a bug is yet to be decided.
- */
-int smbc_flistxattr(int fd,
- char *list,
- size_t size);
/**@ingroup print
* Print a file given the name in fname. It would be a URL ...
@@ -1916,7 +771,7 @@ int smbc_open_print_job(const char *fname);
* - EINVAL fname was NULL or smbc_init not called
* - EACCES ???
*/
-int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
+int smbc_list_print_jobs(const char *purl, smbc_get_print_job_info fn);
/**@ingroup print
* Delete a print job
@@ -1932,16 +787,5 @@ int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
*/
int smbc_unlink_print_job(const char *purl, int id);
-/**@ingroup callback
- * Remove a server from the cached server list it's unused.
- *
- * @param context pointer to smb context
- *
- * @param srv pointer to server to remove
- *
- * @return On success, 0 is returned. 1 is returned if the server could not
- * be removed. Also useable outside libsmbclient.
- */
-int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv);
#endif /* SMBCLIENT_H_INCLUDED */
diff --git a/source/include/local.h b/source/include/local.h
index 540365047a2..a593722b304 100644
--- a/source/include/local.h
+++ b/source/include/local.h
@@ -10,15 +10,6 @@
#define WORKGROUP "WORKGROUP"
#endif
-/* the maximum debug level to compile into the code. This assumes a good
- optimising compiler that can remove unused code
- for embedded or low-memory systems set this to a value like 2 to get
- only important messages. This gives *much* smaller binaries
-*/
-#ifndef MAX_DEBUG_LEVEL
-#define MAX_DEBUG_LEVEL 1000
-#endif
-
/* This defines the section name in the configuration file that will contain */
/* global parameters - that is, parameters relating to the whole server, not */
/* just services. This name is then reserved, and may not be used as a */
@@ -73,11 +64,16 @@
#define MAX_PASS_LEN 200
/* separators for lists */
-#define LIST_SEP " \t,;\n\r"
+#define LIST_SEP " \t,;:\n\r"
/* wchar separators for lists */
#define LIST_SEP_W wchar_list_sep
+#ifndef LOCKDIR
+/* this should have been set in the Makefile */
+#define LOCKDIR "/tmp/samba"
+#endif
+
/* this is where browse lists are kept in the lock dir */
#define SERVER_LIST "browse.dat"
@@ -113,7 +109,7 @@
#endif
/* the size of the uid cache used to reduce valid user checks */
-#define VUID_CACHE_SIZE 32
+#define UID_CACHE_SIZE 4
/* the following control timings of various actions. Don't change
them unless you know what you are doing. These are all in seconds */
@@ -166,6 +162,9 @@
it are worked out */
#define USE_READ_PREDICTION 0
+/* name of directory that netatalk uses to store macintosh resource forks */
+#define APPLEDOUBLE ".AppleDouble/"
+
/*
* Default passwd chat script.
*/
@@ -179,20 +178,8 @@
than 62*62 for the current code */
#define MAX_SESSION_ID 3000
-/* For the benifit of PAM and the 'session exec' scripts, we fake up a terminal
- name. This can be in one of two forms: The first for systems not using
- utmp (and therefore not constrained as to length or the need for a number
- < 3000 or so) and the second for systems with this 'well behaved terminal
- like name' constraint.
-*/
-
#ifndef SESSION_TEMPLATE
-/* Paramaters are 'pid' and 'vuid' */
-#define SESSION_TEMPLATE "smb/%lu/%d"
-#endif
-
-#ifndef SESSION_UTMP_TEMPLATE
-#define SESSION_UTMP_TEMPLATE "smb/%d"
+#define SESSION_TEMPLATE "smb/%d"
#endif
/* the maximum age in seconds of a password. Should be a lp_ parameter */
@@ -201,33 +188,12 @@
/* Allocation roundup. */
#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000
-/* shall we deny oplocks to clients that get timeouts? */
-#define FASCIST_OPLOCK_BACKOFF 1
-
-/* this enables the "rabbit pellet" fix for SMBwritebraw */
-#define RABBIT_PELLET_FIX 1
-
/* Max number of jobs per print queue. */
#define PRINT_MAX_JOBID 10000
/* Max number of open RPC pipes. */
#define MAX_OPEN_PIPES 2048
-/* Tuning for server auth mutex. */
-#define CLI_AUTH_TIMEOUT 5000 /* In milli-seconds. */
-#define NUM_CLI_AUTH_CONNECT_RETRIES 3
-/* Number in seconds to wait for the mutex. This must be less than 30 seconds. */
-#define SERVER_MUTEX_WAIT_TIME ( ((NUM_CLI_AUTH_CONNECT_RETRIES) * ((CLI_AUTH_TIMEOUT)/1000)) + 5)
-/* Number in seconds for winbindd to wait for the mutex. Make this 2 * smbd wait time. */
-#define WINBIND_SERVER_MUTEX_WAIT_TIME (( ((NUM_CLI_AUTH_CONNECT_RETRIES) * ((CLI_AUTH_TIMEOUT)/1000)) + 5)*2)
-
/* Max number of simultaneous winbindd socket connections. */
#define WINBINDD_MAX_SIMULTANEOUS_CLIENTS 200
-
-/* Buffer size to use when printing backtraces */
-#define BACKTRACE_STACK_SIZE 64
-
-/* size of listen() backlog in smbd */
-#define SMBD_LISTEN_BACKLOG 50
-
#endif
diff --git a/source/include/mangle.h b/source/include/mangle.h
index 1d7cdf73628..769278d828b 100644
--- a/source/include/mangle.h
+++ b/source/include/mangle.h
@@ -9,6 +9,6 @@ struct mangle_fns {
BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards);
void (*reset)(void);
BOOL (*check_cache)(char *s);
- void (*name_map)(char *OutName, BOOL need83, BOOL cache83, int default_case);
+ void (*name_map)(char *OutName, BOOL need83, BOOL cache83);
};
#endif /* _MANGLE_H_ */
diff --git a/source/include/mapping.h b/source/include/mapping.h
index fdaa2b04532..a9f0149bad1 100644
--- a/source/include/mapping.h
+++ b/source/include/mapping.h
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Jean François Micouleau 1998-2001.
@@ -19,15 +20,29 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ENUM_ONLY_MAPPED True
-#define ENUM_ALL_MAPPED False
-
typedef struct _GROUP_MAP {
- struct pdb_methods *methods;
gid_t gid;
DOM_SID sid;
enum SID_NAME_USE sid_name_use;
fstring nt_name;
fstring comment;
+ uint32 privilege;
} GROUP_MAP;
+typedef struct _PRIVS {
+ uint32 se_priv;
+ const char *priv;
+ const char *description;
+} PRIVS;
+
+#define SE_PRIV_NONE 0x0000
+#define SE_PRIV_ADD_USERS 0x0001
+#define SE_PRIV_ADD_MACHINES 0x0002
+#define SE_PRIV_PRINT_OPERATOR 0x0004
+#define SE_PRIV_ALL 0xffff
+
+#define PRIV_ALL_INDEX 4
+
+
+#define ENUM_ONLY_MAPPED True
+#define ENUM_ALL_MAPPED False
diff --git a/source/include/md5.h b/source/include/md5.h
deleted file mode 100644
index 6665171e7c5..00000000000
--- a/source/include/md5.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef MD5_H
-#define MD5_H
-#ifndef HEADER_MD5_H
-/* Try to avoid clashes with OpenSSL */
-#define HEADER_MD5_H
-#endif
-
-struct MD5Context {
- uint32 buf[4];
- uint32 bits[2];
- unsigned char in[64];
-};
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, unsigned char const *buf,
- unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-
-/*
- * This is needed to make RSAREF happy on some MS-DOS compilers.
- */
-typedef struct MD5Context MD5_CTX;
-
-#endif /* !MD5_H */
diff --git a/source/include/messages.h b/source/include/messages.h
index 37e9372cdaa..c38ca761af6 100644
--- a/source/include/messages.h
+++ b/source/include/messages.h
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
messages.c header
Copyright (C) Andrew Tridgell 2000
- Copyright (C) 2001, 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,41 +31,18 @@
#define MSG_DEBUGLEVEL 6
#define MSG_REQ_PROFILELEVEL 7
#define MSG_PROFILELEVEL 8
-#define MSG_REQ_POOL_USAGE 9
-#define MSG_POOL_USAGE 10
-
-/* If dmalloc is included, set a steady-state mark */
-#define MSG_REQ_DMALLOC_MARK 11
-
-/* If dmalloc is included, dump to the dmalloc log a description of
- * what has changed since the last MARK */
-#define MSG_REQ_DMALLOC_LOG_CHANGED 12
-
-#define MSG_SHUTDOWN 13
/* nmbd messages */
#define MSG_FORCE_ELECTION 1001
-#define MSG_WINS_NEW_ENTRY 1002
-/* printing messages */
-/* #define MSG_PRINTER_NOTIFY 2001*/ /* Obsolete */
-#define MSG_PRINTER_DRVUPGRADE 2002
-#define MSG_PRINTER_NOTIFY2 2003
-#define MSG_PRINTERDATA_INIT_RESET 2004
+/* rpc messages */
+#define MSG_PRINTER_NOTIFY 2001
+#define MSG_PRINTER_DRVUPGRADE 2002
/* smbd messages */
#define MSG_SMB_CONF_UPDATED 3001
#define MSG_SMB_FORCE_TDIS 3002
#define MSG_SMB_SAM_SYNC 3003
#define MSG_SMB_SAM_REPL 3004
-#define MSG_SMB_UNLOCK 3005
-
-/* Flags to classify messages - used in message_send_all() */
-/* Sender will filter by flag. */
-
-#define FLAG_MSG_GENERAL 0x0001
-#define FLAG_MSG_SMBD 0x0002
-#define FLAG_MSG_NMBD 0x0004
-#define FLAG_MSG_PRINTING 0x0008
-
+#define MSG_SMB_UNLOCK 3005
#endif
diff --git a/source/include/modconf.h b/source/include/modconf.h
deleted file mode 100644
index f5cc5ef4889..00000000000
--- a/source/include/modconf.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _MODCONF_H_
-#define _MODCONF_H_
-/*
- Unix SMB/CIFS implementation.
-
- ModConf headers
-
- Copyright (C) Simo Sorce 2003
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#define SAMBA_CONFIG_INTERFACE_VERSION 1
-
-/* Filled out by config backends */
-struct config_functions {
- NTSTATUS (*init)(char *params);
- NTSTATUS (*load)(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *));
- NTSTATUS (*close)(void);
-};
-#endif /* _MODCONF_H_ */
diff --git a/source/include/module.h b/source/include/module.h
deleted file mode 100644
index c41310c7f75..00000000000
--- a/source/include/module.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Handling of idle/exit events
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _MODULE_H
-#define _MODULE_H
-
-/* Module support */
-typedef NTSTATUS (init_module_function) (void);
-
-
-typedef int smb_event_id_t;
-#define SMB_EVENT_ID_INVALID (-1)
-
-#define SMB_IDLE_EVENT_DEFAULT_INTERVAL 180
-#define SMB_IDLE_EVENT_MIN_INTERVAL 30
-
-typedef void (smb_idle_event_fn)(void **data,time_t *interval,time_t now);
-
-typedef void (smb_exit_event_fn)(void **data);
-
-#endif /* _MODULE_H */
diff --git a/source/include/msdfs.h b/source/include/msdfs.h
index 32aa7ecef25..8c887e4d213 100644
--- a/source/include/msdfs.h
+++ b/source/include/msdfs.h
@@ -59,20 +59,19 @@ struct dfs_path
pstring reqpath;
};
+#ifdef WITH_MSDFS
+
#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \
{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \
lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \
dfs_redirect(name,conn,False)) \
- return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \
- ERRSRV, ERRbadpath);; }
+ return(dfs_path_error(inbuf,outbuf)); }
#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf) \
{ if ( (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) || \
((get_remote_arch() == RA_WIN95) && lp_msdfs_root(SNUM(conn))) ) \
if (lp_host_msdfs() && dfs_redirect(name,conn,True)) \
- return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \
- ERRSRV, ERRbadpath);; }
-
+ return(dfs_path_error(inbuf,outbuf)); }
#define init_dfsroot(conn, inbuf, outbuf) \
{ if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { \
@@ -82,4 +81,12 @@ struct dfs_path
| SVAL(outbuf, smb_vwv2)); \
} }
+#else
+/* Stub macros */
+#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) ;
+#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf) ;
+#define init_dfsroot(conn, inbuf, outbuf) ;
+
+#endif
+
#endif /* _MSDFS_H */
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index ec3d56c06b7..91e88ee6b1c 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -1,7 +1,8 @@
#ifndef _NAMESERV_H_
#define _NAMESERV_H_
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios header - version 2
Copyright (C) Andrew Tridgell 1994-1998
@@ -21,12 +22,6 @@
*/
-#define INFO_VERSION "INFO/version"
-#define INFO_COUNT "INFO/num_entries"
-#define INFO_ID_HIGH "INFO/id_high"
-#define INFO_ID_LOW "INFO/id_low"
-#define ENTRY_PREFIX "ENTRY/"
-
#define PERMANENT_TTL 0
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
@@ -89,33 +84,6 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH,
/* Mask applied to outgoing NetBIOS flags. */
#define NB_FLGMSK 0xE0
-/* The wins flags. Looks like the nbflags ! */
-#define WINS_UNIQUE 0x00 /* Unique record */
-#define WINS_NGROUP 0x01 /* Normal Group eg: 1B */
-#define WINS_SGROUP 0x02 /* Special Group eg: 1C */
-#define WINS_MHOMED 0x03 /* MultiHomed */
-
-#define WINS_ACTIVE 0x00 /* active record */
-#define WINS_RELEASED 0x04 /* released record */
-#define WINS_TOMBSTONED 0x08 /* tombstoned record */
-#define WINS_DELETED 0x0C /* deleted record */
-
-#define WINS_STATE_MASK 0x0C
-
-#define WINS_LOCAL 0x00 /* local record */
-#define WINS_REMOTE 0x10 /* remote record */
-
-#define WINS_BNODE 0x00 /* Broadcast node */
-#define WINS_PNODE 0x20 /* PtP node */
-#define WINS_MNODE 0x40 /* Mixed node */
-#define WINS_HNODE 0x60 /* Hybrid node */
-
-#define WINS_NONSTATIC 0x00 /* dynamic record */
-#define WINS_STATIC 0x80 /* static record */
-
-#define WINS_STATE_ACTIVE(p) (((p)->data.wins_flags & WINS_STATE_MASK) == WINS_ACTIVE)
-
-
/* NetBIOS flag identifier. */
#define NAME_GROUP(p) ((p)->data.nb_flags & NB_GROUP)
#define NAME_BFLAG(p) (((p)->data.nb_flags & NB_NODETYPEMASK) == NB_BFLAG)
@@ -176,116 +144,119 @@ enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME,
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET};
-enum master_state {
- MST_NONE,
- MST_POTENTIAL,
- MST_BACKUP,
- MST_MSB,
- MST_BROWSER,
- MST_UNBECOMING_MASTER
+enum master_state
+{
+ MST_NONE,
+ MST_POTENTIAL,
+ MST_BACKUP,
+ MST_MSB,
+ MST_BROWSER,
+ MST_UNBECOMING_MASTER
};
-enum domain_state {
- DOMAIN_NONE,
- DOMAIN_WAIT,
- DOMAIN_MST
+enum domain_state
+{
+ DOMAIN_NONE,
+ DOMAIN_WAIT,
+ DOMAIN_MST
};
-enum logon_state {
- LOGON_NONE,
- LOGON_WAIT,
- LOGON_SRV
+enum logon_state
+{
+ LOGON_NONE,
+ LOGON_WAIT,
+ LOGON_SRV
};
struct subnet_record;
-struct nmb_data {
- uint16 nb_flags; /* Netbios flags. */
- int num_ips; /* Number of ip entries. */
- struct in_addr *ip; /* The ip list for this name. */
-
- enum name_source source; /* Where the name came from. */
+struct nmb_data
+{
+ uint16 nb_flags; /* Netbios flags. */
+ int num_ips; /* Number of ip entries. */
+ struct in_addr *ip; /* The ip list for this name. */
- time_t death_time; /* The time the record must be removed (do not remove if 0). */
- time_t refresh_time; /* The time the record should be refreshed. */
-
- SMB_BIG_UINT id; /* unique id */
- struct in_addr wins_ip; /* the adress of the wins server this record comes from */
+ enum name_source source; /* Where the name came from. */
- int wins_flags; /* similar to the netbios flags but different ! */
+ time_t death_time; /* The time the record must be removed (do not remove if 0). */
+ time_t refresh_time; /* The time the record should be refreshed. */
};
/* This structure represents an entry in a local netbios name list. */
-struct name_record {
- ubi_trNode node[1];
- struct subnet_record *subnet;
- struct nmb_name name; /* The netbios name. */
- struct nmb_data data; /* The netbios data. */
-};
+struct name_record
+ {
+ ubi_trNode node[1];
+ struct subnet_record *subnet;
+ struct nmb_name name; /* The netbios name. */
+ struct nmb_data data; /* The netbios data. */
+ };
/* Browser cache for synchronising browse lists. */
-struct browse_cache_record {
- ubi_dlNode node[1];
- unstring lmb_name;
- unstring work_group;
- struct in_addr ip;
- time_t sync_time;
- time_t death_time; /* The time the record must be removed. */
-};
+struct browse_cache_record
+ {
+ ubi_dlNode node[1];
+ pstring lmb_name;
+ pstring work_group;
+ struct in_addr ip;
+ time_t sync_time;
+ time_t death_time; /* The time the record must be removed. */
+ };
/* This is used to hold the list of servers in my domain, and is
contained within lists of domains. */
-struct server_record {
- struct server_record *next;
- struct server_record *prev;
+struct server_record
+{
+ struct server_record *next;
+ struct server_record *prev;
- struct subnet_record *subnet;
+ struct subnet_record *subnet;
- struct server_info_struct serv;
- time_t death_time;
+ struct server_info_struct serv;
+ time_t death_time;
};
/* A workgroup structure. It contains a list of servers. */
-struct work_record {
- struct work_record *next;
- struct work_record *prev;
+struct work_record
+{
+ struct work_record *next;
+ struct work_record *prev;
- struct subnet_record *subnet;
+ struct subnet_record *subnet;
- struct server_record *serverlist;
+ struct server_record *serverlist;
- /* Stage of development from non-local-master up to local-master browser. */
- enum master_state mst_state;
+ /* Stage of development from non-local-master up to local-master browser. */
+ enum master_state mst_state;
- /* Stage of development from non-domain-master to domain-master browser. */
- enum domain_state dom_state;
+ /* Stage of development from non-domain-master to domain-master browser. */
+ enum domain_state dom_state;
- /* Stage of development from non-logon-server to logon server. */
- enum logon_state log_state;
+ /* Stage of development from non-logon-server to logon server. */
+ enum logon_state log_state;
- /* Work group info. */
- unstring work_group;
- int token; /* Used when communicating with backup browsers. */
- unstring local_master_browser_name; /* Current local master browser. */
+ /* Work group info. */
+ fstring work_group;
+ int token; /* Used when communicating with backup browsers. */
+ fstring local_master_browser_name; /* Current local master browser. */
- /* Announce info. */
- time_t lastannounce_time;
- int announce_interval;
- BOOL needannounce;
+ /* Announce info. */
+ time_t lastannounce_time;
+ int announce_interval;
+ BOOL needannounce;
- /* Timeout time for this workgroup. 0 means permanent. */
- time_t death_time;
+ /* Timeout time for this workgroup. 0 means permanent. */
+ time_t death_time;
- /* Election info */
- BOOL RunningElection;
- BOOL needelection;
- int ElectionCount;
- uint32 ElectionCriterion;
+ /* Election info */
+ BOOL RunningElection;
+ BOOL needelection;
+ int ElectionCount;
+ uint32 ElectionCriterion;
- /* Domain master browser info. Used for efficient syncs. */
- struct nmb_name dmb_name;
- struct in_addr dmb_addr;
+ /* Domain master browser info. Used for efficient syncs. */
+ struct nmb_name dmb_name;
+ struct in_addr dmb_addr;
};
/* typedefs needed to define copy & free functions for userdata. */
@@ -297,10 +268,10 @@ typedef void (*userdata_free_fn)(struct userdata_struct *);
/* Structure to define any userdata passed around. */
struct userdata_struct {
- userdata_copy_fn copy_fn;
- userdata_free_fn free_fn;
- unsigned int userdata_len;
- char data[16]; /* 16 is to ensure alignment/padding on all systems */
+ userdata_copy_fn copy_fn;
+ userdata_free_fn free_fn;
+ unsigned int userdata_len;
+ char data[16]; /* 16 is to ensure alignment/padding on all systems */
};
struct response_record;
@@ -374,32 +345,33 @@ typedef void (*node_status_fail_function)( struct subnet_record *,
/* Initiated name queries are recorded in this list to track any responses. */
-struct response_record {
- struct response_record *next;
- struct response_record *prev;
+struct response_record
+{
+ struct response_record *next;
+ struct response_record *prev;
- uint16 response_id;
+ uint16 response_id;
- /* Callbacks for packets received or not. */
- response_function resp_fn;
- timeout_response_function timeout_fn;
+ /* Callbacks for packets received or not. */
+ response_function resp_fn;
+ timeout_response_function timeout_fn;
- /* Callbacks for the request succeeding or not. */
- success_function success_fn;
- fail_function fail_fn;
+ /* Callbacks for the request succeeding or not. */
+ success_function success_fn;
+ fail_function fail_fn;
- struct packet_struct *packet;
+ struct packet_struct *packet;
- struct userdata_struct *userdata;
+ struct userdata_struct *userdata;
- int num_msgs;
+ int num_msgs;
- time_t repeat_time;
- time_t repeat_interval;
- int repeat_count;
+ time_t repeat_time;
+ time_t repeat_interval;
+ int repeat_count;
- /* Recursion protection. */
- BOOL in_expiration_processing;
+ /* Recursion protection. */
+ BOOL in_expiration_processing;
};
/* A subnet structure. It contains a list of workgroups and netbios names. */
@@ -411,44 +383,44 @@ struct response_record {
*/
enum subnet_type {
- NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */
- UNICAST_SUBNET = 1, /* Subnet for unicast packets. */
- REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */
- WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */
+ NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */
+ UNICAST_SUBNET = 1, /* Subnet for unicast packets. */
+ REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */
+ WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */
};
-struct subnet_record {
- struct subnet_record *next;
- struct subnet_record *prev;
+struct subnet_record
+{
+ struct subnet_record *next;
+ struct subnet_record *prev;
- char *subnet_name; /* For Debug identification. */
- enum subnet_type type; /* To catagorize the subnet. */
+ char *subnet_name; /* For Debug identification. */
+ enum subnet_type type; /* To catagorize the subnet. */
- struct work_record *workgrouplist; /* List of workgroups. */
- ubi_trRoot namelist[1]; /* List of netbios names. */
- struct response_record *responselist; /* List of responses expected. */
+ struct work_record *workgrouplist; /* List of workgroups. */
+ ubi_trRoot namelist[1]; /* List of netbios names. */
+ struct response_record *responselist; /* List of responses expected. */
- BOOL namelist_changed;
- BOOL work_changed;
+ BOOL namelist_changed;
+ BOOL work_changed;
- struct in_addr bcast_ip;
- struct in_addr mask_ip;
- struct in_addr myip;
- int nmb_sock; /* socket to listen for unicast 137. */
- int dgram_sock; /* socket to listen for unicast 138. */
+ struct in_addr bcast_ip;
+ struct in_addr mask_ip;
+ struct in_addr myip;
+ int nmb_sock; /* socket to listen for unicast 137. */
+ int dgram_sock; /* socket to listen for unicast 138. */
};
/* A resource record. */
struct res_rec {
- struct nmb_name rr_name;
- int rr_type;
- int rr_class;
- int ttl;
- int rdlength;
- char rdata[MAX_DGRAM_SIZE];
+ struct nmb_name rr_name;
+ int rr_type;
+ int rr_class;
+ int ttl;
+ int rdlength;
+ char rdata[MAX_DGRAM_SIZE];
};
-/* Define these so we can pass info back to caller of name_query */
#define NM_FLAGS_RS 0x80 /* Response. Cheat */
#define NM_FLAGS_AA 0x40 /* Authoritative */
#define NM_FLAGS_TC 0x20 /* Truncated */
@@ -457,34 +429,35 @@ struct res_rec {
#define NM_FLAGS_B 0x01 /* Broadcast */
/* An nmb packet. */
-struct nmb_packet {
- struct {
- int name_trn_id;
- int opcode;
- BOOL response;
- struct {
- BOOL bcast;
- BOOL recursion_available;
- BOOL recursion_desired;
- BOOL trunc;
- BOOL authoritative;
- } nm_flags;
- int rcode;
- int qdcount;
- int ancount;
- int nscount;
- int arcount;
- } header;
-
- struct {
- struct nmb_name question_name;
- int question_type;
- int question_class;
- } question;
-
- struct res_rec *answers;
- struct res_rec *nsrecs;
- struct res_rec *additional;
+struct nmb_packet
+{
+ struct {
+ int name_trn_id;
+ int opcode;
+ BOOL response;
+ struct {
+ BOOL bcast;
+ BOOL recursion_available;
+ BOOL recursion_desired;
+ BOOL trunc;
+ BOOL authoritative;
+ } nm_flags;
+ int rcode;
+ int qdcount;
+ int ancount;
+ int nscount;
+ int arcount;
+ } header;
+
+ struct {
+ struct nmb_name question_name;
+ int question_type;
+ int question_class;
+ } question;
+
+ struct res_rec *answers;
+ struct res_rec *nsrecs;
+ struct res_rec *additional;
};
/* msg_type field options - from rfc1002. */
@@ -500,23 +473,23 @@ struct nmb_packet {
/* A datagram - this normally contains SMB data in the data[] array. */
struct dgram_packet {
- struct {
- int msg_type;
- struct {
- enum node_type node_type;
- BOOL first;
- BOOL more;
- } flags;
- int dgm_id;
- struct in_addr source_ip;
- int source_port;
- int dgm_length;
- int packet_offset;
- } header;
- struct nmb_name source_name;
- struct nmb_name dest_name;
- int datasize;
- char data[MAX_DGRAM_SIZE];
+ struct {
+ int msg_type;
+ struct {
+ enum node_type node_type;
+ BOOL first;
+ BOOL more;
+ } flags;
+ int dgm_id;
+ struct in_addr source_ip;
+ int source_port;
+ int dgm_length;
+ int packet_offset;
+ } header;
+ struct nmb_name source_name;
+ struct nmb_name dest_name;
+ int datasize;
+ char data[MAX_DGRAM_SIZE];
};
/* Define a structure used to queue packets. This will be a linked
@@ -524,18 +497,18 @@ struct dgram_packet {
struct packet_struct
{
- struct packet_struct *next;
- struct packet_struct *prev;
- BOOL locked;
- struct in_addr ip;
- int port;
- int fd;
- time_t timestamp;
- enum packet_type packet_type;
- union {
- struct nmb_packet nmb;
- struct dgram_packet dgram;
- } packet;
+ struct packet_struct *next;
+ struct packet_struct *prev;
+ BOOL locked;
+ struct in_addr ip;
+ int port;
+ int fd;
+ time_t timestamp;
+ enum packet_type packet_type;
+ union {
+ struct nmb_packet nmb;
+ struct dgram_packet dgram;
+ } packet;
};
/* NETLOGON opcodes */
@@ -546,8 +519,7 @@ struct packet_struct
#define SAMLOGON 18
#define SAMLOGON_R 19
#define SAMLOGON_UNK_R 21
-#define SAMLOGON_AD_UNK_R 23
-#define SAMLOGON_AD_R 25
+
/* Ids for netbios packet types. */
@@ -592,12 +564,6 @@ struct packet_struct
affects non-permanent self names (in seconds) */
#define MAX_REFRESH_TIME (60*20)
-/* The Extinction interval: 4 days, time a node will stay in released state */
-#define EXTINCTION_INTERVAL (4*24*60*60)
-
-/* The Extinction time-out: 1 day, time a node will stay in deleted state */
-#define EXTINCTION_TIMEOUT (24*60*60)
-
/* Macro's to enumerate subnets either with or without
the UNICAST subnet. */
@@ -610,18 +576,6 @@ extern struct subnet_record *remote_broadcast_subnet;
#define NEXT_SUBNET_EXCLUDING_UNICAST(x) ((x)->next)
#define NEXT_SUBNET_INCLUDING_UNICAST(x) (get_next_subnet_maybe_unicast((x)))
-/* wins replication record used between nmbd and wrepld */
-typedef struct _WINS_RECORD {
- char name[17];
- char type;
- int nb_flags;
- int wins_flags;
- SMB_BIG_UINT id;
- int num_ips;
- struct in_addr ip[25];
- struct in_addr wins_ip;
-} WINS_RECORD;
-
/* To be removed. */
enum state_type { TEST };
#endif /* _NAMESERV_H_ */
diff --git a/source/include/nt_printing.h b/source/include/nt_printing.h
index 762b1c69170..b9f5716e9ee 100644
--- a/source/include/nt_printing.h
+++ b/source/include/nt_printing.h
@@ -174,86 +174,14 @@ typedef struct nt_printer_driver_info_level
NT_PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
} NT_PRINTER_DRIVER_INFO_LEVEL;
-/* predefined registry key names for printer data */
-
-#define SPOOL_PRINTERDATA_KEY "PrinterDriverData"
-#define SPOOL_DSSPOOLER_KEY "DsSpooler"
-#define SPOOL_DSDRIVER_KEY "DsDriver"
-#define SPOOL_DSUSER_KEY "DsUser"
-#define SPOOL_PNPDATA_KEY "PnPData"
-#define SPOOL_OID_KEY "OID"
-
-/* predefined value names for printer data */
-#define SPOOL_REG_ASSETNUMBER "assetNumber"
-#define SPOOL_REG_BYTESPERMINUTE "bytesPerMinute"
-#define SPOOL_REG_DEFAULTPRIORITY "defaultPriority"
-#define SPOOL_REG_DESCRIPTION "description"
-#define SPOOL_REG_DRIVERNAME "driverName"
-#define SPOOL_REG_DRIVERVERSION "driverVersion"
-#define SPOOL_REG_FLAGS "flags"
-#define SPOOL_REG_LOCATION "location"
-#define SPOOL_REG_OPERATINGSYSTEM "operatingSystem"
-#define SPOOL_REG_OPERATINGSYSTEMHOTFIX "operatingSystemHotfix"
-#define SPOOL_REG_OPERATINGSYSTEMSERVICEPACK "operatingSystemServicePack"
-#define SPOOL_REG_OPERATINGSYSTEMVERSION "operatingSystemVersion"
-#define SPOOL_REG_PORTNAME "portName"
-#define SPOOL_REG_PRINTATTRIBUTES "printAttributes"
-#define SPOOL_REG_PRINTBINNAMES "printBinNames"
-#define SPOOL_REG_PRINTCOLLATE "printCollate"
-#define SPOOL_REG_PRINTCOLOR "printColor"
-#define SPOOL_REG_PRINTDUPLEXSUPPORTED "printDuplexSupported"
-#define SPOOL_REG_PRINTENDTIME "printEndTime"
-#define SPOOL_REG_PRINTERNAME "printerName"
-#define SPOOL_REG_PRINTFORMNAME "printFormName"
-#define SPOOL_REG_PRINTKEEPPRINTEDJOBS "printKeepPrintedJobs"
-#define SPOOL_REG_PRINTLANGUAGE "printLanguage"
-#define SPOOL_REG_PRINTMACADDRESS "printMACAddress"
-#define SPOOL_REG_PRINTMAXCOPIES "printMaxCopies"
-#define SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED "printMaxResolutionSupported"
-#define SPOOL_REG_PRINTMAXXEXTENT "printMaxXExtent"
-#define SPOOL_REG_PRINTMAXYEXTENT "printMaxYExtent"
-#define SPOOL_REG_PRINTMEDIAREADY "printMediaReady"
-#define SPOOL_REG_PRINTMEDIASUPPORTED "printMediaSupported"
-#define SPOOL_REG_PRINTMEMORY "printMemory"
-#define SPOOL_REG_PRINTMINXEXTENT "printMinXExtent"
-#define SPOOL_REG_PRINTMINYEXTENT "printMinYExtent"
-#define SPOOL_REG_PRINTNETWORKADDRESS "printNetworkAddress"
-#define SPOOL_REG_PRINTNOTIFY "printNotify"
-#define SPOOL_REG_PRINTNUMBERUP "printNumberUp"
-#define SPOOL_REG_PRINTORIENTATIONSSUPPORTED "printOrientationsSupported"
-#define SPOOL_REG_PRINTOWNER "printOwner"
-#define SPOOL_REG_PRINTPAGESPERMINUTE "printPagesPerMinute"
-#define SPOOL_REG_PRINTRATE "printRate"
-#define SPOOL_REG_PRINTRATEUNIT "printRateUnit"
-#define SPOOL_REG_PRINTSEPARATORFILE "printSeparatorFile"
-#define SPOOL_REG_PRINTSHARENAME "printShareName"
-#define SPOOL_REG_PRINTSPOOLING "printSpooling"
-#define SPOOL_REGVAL_PRINTWHILESPOOLING "PrintWhileSpooling"
-#define SPOOL_REGVAL_PRINTAFTERSPOOLED "PrintAfterSpooled"
-#define SPOOL_REGVAL_PRINTDIRECT "PrintDirect"
-#define SPOOL_REG_PRINTSTAPLINGSUPPORTED "printStaplingSupported"
-#define SPOOL_REG_PRINTSTARTTIME "printStartTime"
-#define SPOOL_REG_PRINTSTATUS "printStatus"
-#define SPOOL_REG_PRIORITY "priority"
-#define SPOOL_REG_SERVERNAME "serverName"
-#define SPOOL_REG_SHORTSERVERNAME "shortServerName"
-#define SPOOL_REG_UNCNAME "uNCName"
-#define SPOOL_REG_URL "url"
-#define SPOOL_REG_VERSIONNUMBER "versionNumber"
-
-/* container for a single registry key */
-
-typedef struct {
- char *name;
- REGVAL_CTR values;
-} NT_PRINTER_KEY;
-
-/* container for all printer data */
-
-typedef struct {
- int num_keys;
- NT_PRINTER_KEY *keys;
-} NT_PRINTER_DATA;
+typedef struct nt_printer_param
+{
+ fstring value;
+ uint32 type;
+ uint8 *data;
+ int data_len;
+ struct nt_printer_param *next;
+} NT_PRINTER_PARAM;
#define MAXDEVICENAME 32
@@ -320,8 +248,9 @@ typedef struct nt_printer_info_level_2
fstring printprocessor;
fstring datatype;
fstring parameters;
- NT_PRINTER_DATA data;
+ NT_PRINTER_PARAM *specific;
SEC_DESC_BUF *secdesc_buf;
+ /* not used but ... and how ??? */
uint32 changeid;
uint32 c_setprinter;
uint32 setuptime;
@@ -405,80 +334,4 @@ typedef struct _form
#define VS_VERSION_INFO_SIZE (sizeof(VS_SIGNATURE)+4+VS_MINOR_OFFSET+4) /* not true size! */
#define VS_NE_BUF_SIZE 4096 /* Must be > 2*VS_VERSION_INFO_SIZE */
-/* Notify spoolss clients that something has changed. The
- notification data is either stored in two uint32 values or a
- variable length array. */
-
-#define SPOOLSS_NOTIFY_MSG_UNIX_JOBID 0x0001 /* Job id is unix */
-
-typedef struct spoolss_notify_msg {
- fstring printer; /* Name of printer notified */
- uint32 type; /* Printer or job notify */
- uint32 field; /* Notify field changed */
- uint32 id; /* Job id */
- uint32 len; /* Length of data, 0 for two uint32 value */
- uint32 flags;
- union {
- uint32 value[2];
- char *data;
- } notify;
-} SPOOLSS_NOTIFY_MSG;
-
-typedef struct {
- fstring printername;
- uint32 num_msgs;
- SPOOLSS_NOTIFY_MSG *msgs;
-} SPOOLSS_NOTIFY_MSG_GROUP;
-
-typedef struct {
- TALLOC_CTX *ctx;
- uint32 num_groups;
- SPOOLSS_NOTIFY_MSG_GROUP *msg_groups;
-} SPOOLSS_NOTIFY_MSG_CTR;
-
-#define PRINTER_HANDLE_IS_PRINTER 0
-#define PRINTER_HANDLE_IS_PRINTSERVER 1
-
-/* structure to store the printer handles */
-/* and a reference to what it's pointing to */
-/* and the notify info asked about */
-/* that's the central struct */
-typedef struct _Printer{
- struct _Printer *prev, *next;
- BOOL document_started;
- BOOL page_started;
- uint32 jobid; /* jobid in printing backend */
- BOOL printer_type;
- TALLOC_CTX *ctx;
- union {
- fstring handlename;
- fstring printerservername;
- } dev;
- uint32 type;
- uint32 access_granted;
- struct {
- uint32 flags;
- uint32 options;
- fstring localmachine;
- uint32 printerlocal;
- SPOOL_NOTIFY_OPTION *option;
- POLICY_HND client_hnd;
- BOOL client_connected;
- uint32 change;
- /* are we in a FindNextPrinterChangeNotify() call? */
- BOOL fnpcn;
- } notify;
- struct {
- fstring machine;
- fstring user;
- } client;
-
- /* devmode sent in the OpenPrinter() call */
- NT_DEVICEMODE *nt_devmode;
-
- /* cache the printer info */
- NT_PRINTER_INFO_LEVEL *printer_info;
-
-} Printer_entry;
-
#endif /* NT_PRINTING_H_ */
diff --git a/source/include/nt_status.h b/source/include/nt_status.h
deleted file mode 100644
index 9747f73eb18..00000000000
--- a/source/include/nt_status.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup, plus a whole lot more.
-
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _NT_STATUS_H
-#define _NT_STATUS_H
-
-/* The Splint code analysis tool doesn't like immediate structures. */
-
-#ifdef _SPLINT_ /* http://www.splint.org */
-#undef HAVE_IMMEDIATE_STRUCTURES
-#endif
-
-/* the following rather strange looking definitions of NTSTATUS and WERROR
- and there in order to catch common coding errors where different error types
- are mixed up. This is especially important as we slowly convert Samba
- from using BOOL for internal functions
-*/
-
-#if defined(HAVE_IMMEDIATE_STRUCTURES)
-typedef struct {uint32 v;} NTSTATUS;
-#define NT_STATUS(x) ((NTSTATUS) { x })
-#define NT_STATUS_V(x) ((x).v)
-#else
-typedef uint32 NTSTATUS;
-#define NT_STATUS(x) (x)
-#define NT_STATUS_V(x) (x)
-#endif
-
-#if defined(HAVE_IMMEDIATE_STRUCTURES)
-typedef struct {uint32 v;} WERROR;
-#define W_ERROR(x) ((WERROR) { x })
-#define W_ERROR_V(x) ((x).v)
-#else
-typedef uint32 WERROR;
-#define W_ERROR(x) (x)
-#define W_ERROR_V(x) (x)
-#endif
-
-#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0)
-#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000)
-#define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y))
-#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0)
-#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y))
-
-#endif
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 4e6795a85d5..14c6065de87 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
@@ -23,22 +24,6 @@
#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
#define _NT_DOMAIN_H
-struct uuid
-{
- uint32 time_low;
- uint16 time_mid;
- uint16 time_hi_and_version;
- uint8 clock_seq[2];
- uint8 node[6];
-};
-#define UUID_SIZE 16
-
-#define UUID_FLAT_SIZE 16
-typedef struct uuid_flat
-{
- uint8 info[UUID_FLAT_SIZE];
-} UUID_FLAT;
-
/* dce/rpc support */
#include "rpc_dce.h"
@@ -172,47 +157,20 @@ struct dcinfo
uchar md4pw[16]; /* md4(machine password) */
fstring mach_acct; /* Machine name we've authenticated. */
-
- fstring remote_machine; /* Machine name we've authenticated. */
-
- BOOL challenge_sent;
- BOOL got_session_key;
- BOOL authenticated;
-
};
-typedef struct pipe_rpc_fns {
-
- struct pipe_rpc_fns *next, *prev;
-
- /* RPC function table associated with the current rpc_bind (associated by context) */
-
- struct api_struct *cmds;
- int n_cmds;
- uint32 context_id;
-
-} PIPE_RPC_FNS;
-
-/*
- * DCE/RPC-specific samba-internal-specific handling of data on
- * NamedPipes.
- */
-
typedef struct pipes_struct
{
struct pipes_struct *next, *prev;
-
+ int pnum;
connection_struct *conn;
uint16 vuid; /* points to the unauthenticated user that opened this pipe. */
-
+ BOOL open; /* open connection */
+ uint16 device_state;
+ uint16 priority;
fstring name;
fstring pipe_srv_name;
-
- /* linked list of rpc dispatch tables associated
- with the open rpc contexts */
-
- PIPE_RPC_FNS *contexts;
-
+
RPC_HDR hdr; /* Incoming RPC header. */
RPC_HDR_REQ hdr_req; /* Incoming request header. */
@@ -224,13 +182,6 @@ typedef struct pipes_struct
uint32 ntlmssp_seq_num;
struct dcinfo dc; /* Keeps the creds data. */
- /* Hmm. In my understanding the authentication happens
- implicitly later, so there are no two stages for
- schannel. */
-
- BOOL netsec_auth_validated;
- struct netsec_auth_struct netsec_auth;
-
/*
* Windows user info.
*/
@@ -245,8 +196,6 @@ typedef struct pipes_struct
fstring pipe_user_name;
struct current_user pipe_user;
- DATA_BLOB session_key;
-
/*
* Set to true when an RPC bind has been done on this pipe.
*/
@@ -258,11 +207,11 @@ typedef struct pipes_struct
*/
BOOL fault_state;
-
+
/*
* Set to true when we should return fault PDU's for a bad handle.
*/
-
+
BOOL bad_handle_fault_state;
/*
@@ -283,6 +232,10 @@ typedef struct pipes_struct
output_data out_data;
+ /* When replying to an SMBtrans, this is the maximum amount of
+ data that can be sent in the initial reply. */
+ int max_trans_reply;
+
/* talloc context to use when allocating memory on this pipe. */
TALLOC_CTX *mem_ctx;
@@ -291,83 +244,6 @@ typedef struct pipes_struct
} pipes_struct;
-typedef struct smb_np_struct
-{
- struct smb_np_struct *next, *prev;
- int pnum;
- connection_struct *conn;
- uint16 vuid; /* points to the unauthenticated user that opened this pipe. */
- BOOL open; /* open connection */
- uint16 device_state;
- uint16 priority;
- fstring name;
-
- /* When replying to an SMBtrans, this is the maximum amount of
- data that can be sent in the initial reply. */
- int max_trans_reply;
-
- /*
- * NamedPipe state information.
- *
- * (e.g. typecast a np_struct, above).
- */
- void *np_state;
-
- /*
- * NamedPipe functions, to be called to perform
- * Named Pipe transactions on request from an
- * SMB client.
- */
-
- /* call to create a named pipe connection.
- * returns: state information representing the connection.
- * is stored in np_state, above.
- */
- void * (*namedpipe_create)(char *pipe_name,
- connection_struct *conn, uint16 vuid);
-
- /* call to perform a write / read namedpipe transaction.
- * TransactNamedPipe is weird: it returns whether there
- * is more data outstanding to be read, and the
- * caller is expected to take note and follow up with
- * read requests.
- */
- ssize_t (*namedpipe_transact)(void *np_state,
- char *data, int len,
- char *rdata, int rlen,
- BOOL *pipe_outstanding);
-
- /* call to perform a write namedpipe operation
- */
- ssize_t (*namedpipe_write)(void * np_state,
- char *data, size_t n);
-
- /* call to perform a read namedpipe operation.
- *
- * NOTE: the only reason that the pipe_outstanding
- * argument is here is because samba does not use
- * the namedpipe_transact function yet: instead,
- * it performs the same as what namedpipe_transact
- * does - a write, followed by a read.
- *
- * when samba is modified to use namedpipe_transact,
- * the pipe_outstanding argument may be removed.
- */
- ssize_t (*namedpipe_read)(void * np_state,
- char *data, size_t max_len,
- BOOL *pipe_outstanding);
-
- /* call to close a namedpipe.
- * function is expected to perform all cleanups
- * necessary, free all memory etc.
- *
- * returns True if cleanup was successful (not that
- * we particularly care).
- */
- BOOL (*namedpipe_close)(void * np_state);
-
-} smb_np_struct;
-
struct api_struct
{
const char *name;
@@ -382,6 +258,13 @@ typedef struct
} rid_name;
+struct acct_info
+{
+ fstring acct_name; /* account name */
+ fstring acct_desc; /* account name */
+ uint32 rid; /* domain-relative RID */
+};
+
/*
* higher order functions for use with msrpc client code
*/
@@ -397,9 +280,6 @@ typedef struct
/* security descriptor structures */
#include "rpc_secdes.h"
-/* pac */
-#include "authdata.h"
-
/* different dce/rpc pipes */
#include "rpc_lsa.h"
#include "rpc_netlogon.h"
@@ -409,9 +289,6 @@ typedef struct
#include "rpc_wkssvc.h"
#include "rpc_spoolss.h"
#include "rpc_dfs.h"
-#include "rpc_ds.h"
-#include "rpc_echo.h"
-#include "rpc_epmapper.h"
-#include "rpc_shutdown.h"
+#include "sids.h"
#endif /* _NT_DOMAIN_H */
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 19c70cffcc9..fa96869b63a 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NT error code constants
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) John H Terpstra 1996-2000
@@ -29,13 +30,15 @@
#define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005)
#define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a)
-#define STATUS_MORE_ENTRIES NT_STATUS(0x0105)
-#define STATUS_SOME_UNMAPPED NT_STATUS(0x0107)
#define ERROR_INVALID_PARAMETER NT_STATUS(0x0057)
#define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a)
-#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c)
+#define STATUS_MORE_ENTRIES NT_STATUS(0x0105)
+#define STATUS_SOME_UNMAPPED NT_STATUS(0x0107)
#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c)
+#define STATUS_MORE_ENTRIES NT_STATUS(0x0105)
+#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c)
+
/* Win32 Error codes extracted using a loop in smbclient then printing a
netmon sniff to a file. */
@@ -558,7 +561,6 @@
#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265)
#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266)
#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267)
-#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275)
#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */
#endif /* _NTERR_H */
diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h
index 9814c88e5e5..4749842ddc5 100644
--- a/source/include/ntioctl.h
+++ b/source/include/ntioctl.h
@@ -23,65 +23,4 @@
we only need the sparse flag
*/
-#ifndef _NTIOCTL_H
-#define _NTIOCTL_H
-
-/* IOCTL information */
-/* List of ioctl function codes that look to be of interest to remote clients like this. */
-/* Need to do some experimentation to make sure they all work remotely. */
-/* Some of the following such as the encryption/compression ones would be */
-/* invoked from tools via a specialized hook into the VFS rather than via the */
-/* standard vfs entry points */
-#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000
-#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004
-#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008
-#define FSCTL_LOCK_VOLUME 0x00090018
-#define FSCTL_UNLOCK_VOLUME 0x0009001C
-#define FSCTL_GET_COMPRESSION 0x0009003C
-#define FSCTL_SET_COMPRESSION 0x0009C040
-#define FSCTL_REQUEST_FILTER_OPLOCK 0x0009008C
-#define FSCTL_FIND_FILES_BY_SID 0x0009008F
-#define FSCTL_FILESYS_GET_STATISTICS 0x00090090
-#define FSCTL_SET_REPARSE_POINT 0x000900A4
-#define FSCTL_GET_REPARSE_POINT 0x000900A8
-#define FSCTL_DELETE_REPARSE_POINT 0x000900AC
-#define FSCTL_0x000900C0 0x000900C0
-#define FSCTL_SET_SPARSE 0x000900C4
-#define FSCTL_SET_ZERO_DATA 0x000900C8
-#define FSCTL_SET_ENCRYPTION 0x000900D7
-#define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB
-#define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF
-#define FSCTL_READ_RAW_ENCRYPTED 0x000900E3
-#define FSCTL_SIS_COPYFILE 0x00090100
-#define FSCTL_SIS_LINK_FILES 0x0009C104
-
-#define FSCTL_GET_SHADOW_COPY_DATA 0x00144064 /* KJC -- Shadow Copy information */
-
-#if 0
-#define FSCTL_SECURITY_ID_CHECK
-#define FSCTL_DISMOUNT_VOLUME
-#define FSCTL_GET_NTFS_FILE_RECORD
-#define FSCTL_ALLOW_EXTENDED_DASD_IO
-#define FSCTL_RECALL_FILE
-#define FSCTL_QUERY_ALLOCATED_RANGES
-
-#endif
-
-#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
-#define IO_REPARSE_TAG_HSM 0xC0000004
-#define IO_REPARSE_TAG_SIS 0x80000007
-
-
-/* For FSCTL_GET_SHADOW_COPY_DATA ...*/
-typedef char SHADOW_COPY_LABEL[25];
-
-typedef struct shadow_copy_data {
- TALLOC_CTX *mem_ctx;
- /* Total number of shadow volumes currently mounted */
- uint32 num_volumes;
- /* Concatenated list of labels */
- SHADOW_COPY_LABEL *labels;
-} SHADOW_COPY_DATA;
-
-
-#endif /* _NTIOCTL_H */
+#define NTIOCTL_SET_SPARSE 0x900c4
diff --git a/source/include/ntlmssp.h b/source/include/ntlmssp.h
deleted file mode 100644
index 24ac7967615..00000000000
--- a/source/include/ntlmssp.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* NTLMSSP mode */
-enum NTLMSSP_ROLE
-{
- NTLMSSP_SERVER,
- NTLMSSP_CLIENT
-};
-
-/* NTLMSSP message types */
-enum NTLM_MESSAGE_TYPE
-{
- NTLMSSP_INITIAL = 0 /* samba internal state */,
- NTLMSSP_NEGOTIATE = 1,
- NTLMSSP_CHALLENGE = 2,
- NTLMSSP_AUTH = 3,
- NTLMSSP_UNKNOWN = 4
-};
-
-/* NTLMSSP negotiation flags */
-#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
-#define NTLMSSP_NEGOTIATE_OEM 0x00000002
-#define NTLMSSP_REQUEST_TARGET 0x00000004
-#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* Message integrity */
-#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* Message confidentiality */
-#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
-#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
-#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
-#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
-#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
-#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
-#define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
-#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
-#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
-#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
-#define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
-
-#define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
-#define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
-#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
-#define NTLMSSP_CHAL_TARGET_INFO 0x00800000
-#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */
-#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
-#define NTLMSSP_NEGOTIATE_080000000 0x80000000
-
-#define NTLMSSP_NAME_TYPE_SERVER 0x01
-#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
-#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03
-#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04
-
-typedef struct ntlmssp_state
-{
- TALLOC_CTX *mem_ctx;
- unsigned int ref_count;
- enum NTLMSSP_ROLE role;
- enum server_types server_role;
- uint32 expected_state;
-
- BOOL unicode;
- BOOL use_ntlmv2;
- char *user;
- char *domain;
- char *workstation;
- char *password;
- char *server_domain;
-
- DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */
-
- DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */
- DATA_BLOB lm_resp;
- DATA_BLOB nt_resp;
- DATA_BLOB session_key;
-
- uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */
-
- void *auth_context;
-
- /**
- * Callback to get the 'challenge' used for NTLM authentication.
- *
- * @param ntlmssp_state This structure
- * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication
- *
- */
- const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state);
-
- /**
- * Callback to find if the challenge used by NTLM authentication may be modified
- *
- * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the
- * current 'security=server' implementation..
- *
- * @param ntlmssp_state This structure
- * @return Can the challenge be set to arbitary values?
- *
- */
- BOOL (*may_set_challenge)(const struct ntlmssp_state *ntlmssp_state);
-
- /**
- * Callback to set the 'challenge' used for NTLM authentication.
- *
- * The callback may use the void *auth_context to store state information, but the same value is always available
- * from the DATA_BLOB chal on this structure.
- *
- * @param ntlmssp_state This structure
- * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
- *
- */
- NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge);
-
- /**
- * Callback to check the user's password.
- *
- * The callback must reads the feilds of this structure for the information it needs on the user
- * @param ntlmssp_state This structure
- * @param nt_session_key If an NT session key is returned by the authentication process, return it here
- * @param lm_session_key If an LM session key is returned by the authentication process, return it here
- *
- */
- NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
-
- const char *(*get_global_myname)(void);
- const char *(*get_domain)(void);
-
- /* SMB Signing */
-
- uint32 ntlmssp_seq_num;
-
- /* ntlmv2 */
- unsigned char send_sign_const[16];
- unsigned char send_seal_const[16];
- unsigned char recv_sign_const[16];
- unsigned char recv_seal_const[16];
-
- unsigned char send_sign_hash[258];
- unsigned char send_seal_hash[258];
- unsigned char recv_sign_hash[258];
- unsigned char recv_seal_hash[258];
-
- /* ntlmv1 */
- unsigned char ntlmssp_hash[258];
-
- /* it turns out that we don't always get the
- response in at the time we want to process it.
- Store it here, until we need it */
- DATA_BLOB stored_response;
-
-} NTLMSSP_STATE;
-
diff --git a/source/include/ntquotas.h b/source/include/ntquotas.h
deleted file mode 100644
index dac1173770b..00000000000
--- a/source/include/ntquotas.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NT QUOTA code constants
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _NTQUOTAS_H
-#define _NTQUOTAS_H
-
-/*
- * details for Quota Flags:
- *
- * 0x20 Log Limit: log if the user exceeds his Hard Quota
- * 0x10 Log Warn: log if the user exceeds his Soft Quota
- * 0x02 Deny Disk: deny disk access when the user exceeds his Hard Quota
- * 0x01 Enable Quotas: enable quota for this fs
- *
- */
-
-#define QUOTAS_ENABLED 0x0001
-#define QUOTAS_DENY_DISK 0x0002
-#define QUOTAS_LOG_VIOLATIONS 0x0004
-#define CONTENT_INDEX_DISABLED 0x0008
-#define QUOTAS_LOG_THRESHOLD 0x0010
-#define QUOTAS_LOG_LIMIT 0x0020
-#define LOG_VOLUME_THRESHOLD 0x0040
-#define LOG_VOLUME_LIMIT 0x0080
-#define QUOTAS_INCOMPLETE 0x0100
-#define QUOTAS_REBUILDING 0x0200
-#define QUOTAS_0400 0x0400
-#define QUOTAS_0800 0x0800
-#define QUOTAS_1000 0x1000
-#define QUOTAS_2000 0x2000
-#define QUOTAS_4000 0x4000
-#define QUOTAS_8000 0x8000
-
-#define SMB_NTQUOTAS_NO_LIMIT ((SMB_BIG_UINT)(-1))
-#define SMB_NTQUOTAS_NO_ENTRY ((SMB_BIG_UINT)(-2))
-#define SMB_NTQUOTAS_NO_SPACE ((SMB_BIG_UINT)(0))
-#define SMB_NTQUOTAS_1_B (SMB_BIG_UINT)0x0000000000000001
-#define SMB_NTQUOTAS_1KB (SMB_BIG_UINT)0x0000000000000400
-#define SMB_NTQUOTAS_1MB (SMB_BIG_UINT)0x0000000000100000
-#define SMB_NTQUOTAS_1GB (SMB_BIG_UINT)0x0000000040000000
-#define SMB_NTQUOTAS_1TB (SMB_BIG_UINT)0x0000010000000000
-#define SMB_NTQUOTAS_1PB (SMB_BIG_UINT)0x0004000000000000
-#define SMB_NTQUOTAS_1EB (SMB_BIG_UINT)0x1000000000000000
-
-enum SMB_QUOTA_TYPE {
- SMB_INVALID_QUOTA_TYPE = -1,
- SMB_USER_FS_QUOTA_TYPE = 1,
- SMB_USER_QUOTA_TYPE = 2,
- SMB_GROUP_FS_QUOTA_TYPE = 3,/* not used yet */
- SMB_GROUP_QUOTA_TYPE = 4 /* not in use yet, maybe for disk_free queries */
-};
-
-typedef struct _SMB_NTQUOTA_STRUCT {
- enum SMB_QUOTA_TYPE qtype;
- SMB_BIG_UINT usedspace;
- SMB_BIG_UINT softlim;
- SMB_BIG_UINT hardlim;
- uint32 qflags;
- DOM_SID sid;
-} SMB_NTQUOTA_STRUCT;
-
-typedef struct _SMB_NTQUOTA_LIST {
- struct _SMB_NTQUOTA_LIST *prev,*next;
- TALLOC_CTX *mem_ctx;
- uid_t uid;
- SMB_NTQUOTA_STRUCT *quotas;
-} SMB_NTQUOTA_LIST;
-
-typedef struct _SMB_NTQUOTA_HANDLE {
- BOOL valid;
- SMB_NTQUOTA_LIST *quota_list;
- SMB_NTQUOTA_LIST *tmp_list;
-} SMB_NTQUOTA_HANDLE;
-
-#define CHECK_NTQUOTA_HANDLE_OK(fsp,conn) (FNUM_OK(fsp,conn) &&\
- (fsp)->fake_file_handle &&\
- ((fsp)->fake_file_handle->type == FAKE_FILE_TYPE_QUOTA) &&\
- (fsp)->fake_file_handle->pd)
-
-#endif /*_NTQUOTAS_H */
diff --git a/source/include/passdb.h b/source/include/passdb.h
deleted file mode 100644
index abe3ac1dc0a..00000000000
--- a/source/include/passdb.h
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- passdb structures and parameters
- Copyright (C) Gerald Carter 2001
- Copyright (C) Luke Kenneth Casson Leighton 1998 - 2000
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Simo Sorce 2003
- Copyright (C) Rafal Szczesniak 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PASSDB_H
-#define _PASSDB_H
-
-
-/*
- * fields_present flags meanings
- * same names as found in samba4 idl files
- */
-
-#define ACCT_USERNAME 0x00000001
-#define ACCT_FULL_NAME 0x00000002
-#define ACCT_RID 0x00000004
-#define ACCT_PRIMARY_GID 0x00000008
-#define ACCT_ADMIN_DESC 0x00000010
-#define ACCT_DESCRIPTION 0x00000020
-#define ACCT_HOME_DIR 0x00000040
-#define ACCT_HOME_DRIVE 0x00000080
-#define ACCT_LOGON_SCRIPT 0x00000100
-#define ACCT_PROFILE 0x00000200
-#define ACCT_WORKSTATIONS 0x00000400
-#define ACCT_LAST_LOGON 0x00000800
-#define ACCT_LAST_LOGOFF 0x00001000
-#define ACCT_LOGON_HOURS 0x00002000
-#define ACCT_BAD_PWD_COUNT 0x00004000
-#define ACCT_NUM_LOGONS 0x00008000
-#define ACCT_ALLOW_PWD_CHANGE 0x00010000
-#define ACCT_FORCE_PWD_CHANGE 0x00020000
-#define ACCT_LAST_PWD_CHANGE 0x00040000
-#define ACCT_EXPIRY 0x00080000
-#define ACCT_FLAGS 0x00100000
-#define ACCT_CALLBACK 0x00200000
-#define ACCT_COUNTRY_CODE 0x00400000
-#define ACCT_CODE_PAGE 0x00800000
-#define ACCT_NT_PWD_SET 0x01000000
-#define ACCT_LM_PWD_SET 0x02000000
-#define ACCT_PRIVATEDATA 0x04000000
-#define ACCT_EXPIRED_FLAG 0x08000000
-#define ACCT_SEC_DESC 0x10000000
-#define ACCT_OWF_PWD 0x20000000
-
-/*
- * bit flags representing initialized fields in SAM_ACCOUNT
- */
-enum pdb_elements {
- PDB_UNINIT,
- PDB_SMBHOME,
- PDB_PROFILE,
- PDB_DRIVE,
- PDB_LOGONSCRIPT,
- PDB_LOGONTIME,
- PDB_LOGOFFTIME,
- PDB_KICKOFFTIME,
- PDB_BAD_PASSWORD_TIME,
- PDB_CANCHANGETIME,
- PDB_MUSTCHANGETIME,
- PDB_PLAINTEXT_PW,
- PDB_USERNAME,
- PDB_FULLNAME,
- PDB_DOMAIN,
- PDB_NTUSERNAME,
- PDB_HOURSLEN,
- PDB_LOGONDIVS,
- PDB_USERSID,
- PDB_GROUPSID,
- PDB_ACCTCTRL,
- PDB_PASSLASTSET,
- PDB_UNIXHOMEDIR,
- PDB_ACCTDESC,
- PDB_WORKSTATIONS,
- PDB_UNKNOWNSTR,
- PDB_MUNGEDDIAL,
- PDB_HOURS,
- PDB_FIELDS_PRESENT,
- PDB_BAD_PASSWORD_COUNT,
- PDB_LOGON_COUNT,
- PDB_UNKNOWN6,
- PDB_LMPASSWD,
- PDB_NTPASSWD,
- PDB_BACKEND_PRIVATE_DATA,
-
- /* this must be the last element */
- PDB_COUNT
-};
-
-enum pdb_group_elements {
- PDB_GROUP_NAME,
- PDB_GROUP_SID,
- PDB_GROUP_SID_NAME_USE,
- PDB_GROUP_MEMBERS,
-
- /* this must be the last element */
- PDB_GROUP_COUNT
-};
-
-enum pdb_trust_passwd_elements {
- PDB_TRUST_PASS,
- PDB_TRUST_SID,
- PDB_TRUST_NAME,
- PDB_TRUST_MODTIME,
- PDB_TRUST_FLAGS,
-
- PDB_TRUST_COUNT
-};
-
-enum pdb_value_state {
- PDB_DEFAULT=0,
- PDB_SET,
- PDB_CHANGED
-};
-
-#define IS_SAM_SET(x, flag) (pdb_get_init_flags(x, flag) == PDB_SET)
-#define IS_SAM_CHANGED(x, flag) (pdb_get_init_flags(x, flag) == PDB_CHANGED)
-#define IS_SAM_DEFAULT(x, flag) (pdb_get_init_flags(x, flag) == PDB_DEFAULT)
-
-/* cache for bad password lockout data, to be used on replicated SAMs */
-typedef struct logon_cache_struct
-{
- time_t entry_timestamp;
- uint16 acct_ctrl;
- uint16 bad_password_count;
- time_t bad_password_time;
-} LOGIN_CACHE;
-
-typedef struct sam_passwd
-{
- TALLOC_CTX *mem_ctx;
-
- void (*free_fn)(struct sam_passwd **);
-
- struct pdb_methods *methods;
-
- struct user_data {
- /* initialization flags */
- struct bitmap *change_flags;
- struct bitmap *set_flags;
-
- time_t logon_time; /* logon time */
- time_t logoff_time; /* logoff time */
- time_t kickoff_time; /* kickoff time */
- time_t bad_password_time; /* last bad password entered */
- time_t pass_last_set_time; /* password last set time */
- time_t pass_can_change_time; /* password can change time */
- time_t pass_must_change_time; /* password must change time */
-
- const char * username; /* UNIX username string */
- const char * domain; /* Windows Domain name */
- const char * nt_username; /* Windows username string */
- const char * full_name; /* user's full name string */
- const char * unix_home_dir; /* UNIX home directory string */
- const char * home_dir; /* home directory string */
- const char * dir_drive; /* home directory drive string */
- const char * logon_script; /* logon script string */
- const char * profile_path; /* profile path string */
- const char * acct_desc ; /* user description string */
- const char * workstations; /* login from workstations string */
- const char * unknown_str ; /* don't know what this is, yet. */
- const char * munged_dial ; /* munged path name and dial-back tel number */
-
- DOM_SID user_sid; /* Primary User SID */
- DOM_SID group_sid; /* Primary Group SID */
-
- DATA_BLOB lm_pw; /* .data is Null if no password */
- DATA_BLOB nt_pw; /* .data is Null if no password */
- char* plaintext_pw; /* is Null if not available */
-
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
- uint32 fields_present; /* 0x00ff ffff */
-
- uint16 logon_divs; /* 168 - number of hours in a week */
- uint32 hours_len; /* normally 21 bytes */
- uint8 hours[MAX_HOURS_LEN];
-
- /* Was unknown_5. */
- uint16 bad_password_count;
- uint16 logon_count;
-
- uint32 unknown_6; /* 0x0000 04ec */
- /* a tag for who added the private methods */
- const struct pdb_methods *backend_private_methods;
- void *backend_private_data;
- void (*backend_private_data_free_fn)(void **);
- } private;
-
- /* Lets see if the remaining code can get the hint that you
- are meant to use the pdb_...() functions. */
-
-} SAM_ACCOUNT;
-
-typedef struct sam_group {
- TALLOC_CTX *mem_ctx;
-
- void (*free_fn)(struct sam_group **);
-
- struct pdb_methods *methods;
-
- struct group_data {
- /* initialization flags */
- struct bitmap *change_flags;
- struct bitmap *set_flags;
-
- const char *name; /* Windows group name string */
-
- DOM_SID sid; /* Group SID */
- enum SID_NAME_USE sid_name_use; /* Group type */
-
- uint32 mem_num; /* Number of member SIDs */
- DOM_SID *members; /* SID array */
- } private;
-
-} SAM_GROUP;
-
-
-typedef struct _GROUP_INFO {
- struct pdb_methods *methods;
- DOM_SID sid;
- enum SID_NAME_USE sid_name_use;
- fstring nt_name;
- fstring comment;
-} GROUP_INFO;
-
-struct acct_info
-{
- fstring acct_name; /* account name */
- fstring acct_desc; /* account name */
- uint32 rid; /* domain-relative RID */
-};
-
-typedef struct sam_trust_passwd {
- TALLOC_CTX *mem_ctx;
-
- void (*free_fn)(struct sam_trust_passwd **);
-
- struct pdb_methods *methods;
-
- struct trust_passwd_data {
- uint16 flags; /* flags */
- size_t uni_name_len; /* unicode name length */
- smb_ucs2_t uni_name[32]; /* unicode domain name */
- fstring pass; /* trust password */
- time_t mod_time; /* last change time */
- DOM_SID domain_sid; /* trusted domain sid */
- } private;
-
-} SAM_TRUST_PASSWD;
-
-
-
-/*****************************************************************
- Functions to be implemented by the new (v2) passdb API
-****************************************************************/
-
-/*
- * This next constant specifies the version number of the PASSDB interface
- * this SAMBA will load. Increment this if *ANY* changes are made to the interface.
- */
-
-#define PASSDB_INTERFACE_VERSION 9
-
-typedef struct pdb_context
-{
- struct pdb_methods *pdb_methods;
- struct pdb_methods *pwent_methods;
-
- /* These functions are wrappers for the functions listed above.
- They may do extra things like re-reading a SAM_ACCOUNT on update */
-
- NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update);
-
- void (*pdb_endsampwent)(struct pdb_context *);
-
- NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
-
- NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
-
- NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
-
- NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
-
- NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
-
- NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
-
- /* group mapping functions: to be removed */
-
- NTSTATUS (*pdb_getgrsid)(struct pdb_context *context, GROUP_MAP *map, DOM_SID sid);
-
- NTSTATUS (*pdb_getgrgid)(struct pdb_context *context, GROUP_MAP *map, gid_t gid);
-
- NTSTATUS (*pdb_getgrnam)(struct pdb_context *context, GROUP_MAP *map, const char *name);
-
- NTSTATUS (*pdb_add_group_mapping_entry)(struct pdb_context *context,
- GROUP_MAP *map);
-
- NTSTATUS (*pdb_update_group_mapping_entry)(struct pdb_context *context,
- GROUP_MAP *map);
-
- NTSTATUS (*pdb_delete_group_mapping_entry)(struct pdb_context *context,
- DOM_SID sid);
-
- NTSTATUS (*pdb_enum_group_mapping)(struct pdb_context *context,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only);
-
- NTSTATUS (*pdb_find_alias)(struct pdb_context *context,
- const char *name, DOM_SID *sid);
-
- NTSTATUS (*pdb_create_alias)(struct pdb_context *context,
- const char *name, uint32 *rid);
-
- NTSTATUS (*pdb_delete_alias)(struct pdb_context *context,
- const DOM_SID *sid);
-
- NTSTATUS (*pdb_enum_aliases)(struct pdb_context *context,
- const DOM_SID *domain_sid,
- uint32 start_idx, uint32 num_entries,
- uint32 *num_aliases,
- struct acct_info **aliases);
-
- NTSTATUS (*pdb_get_aliasinfo)(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info);
-
- NTSTATUS (*pdb_set_aliasinfo)(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info);
-
- NTSTATUS (*pdb_add_aliasmem)(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member);
-
- NTSTATUS (*pdb_del_aliasmem)(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member);
-
- NTSTATUS (*pdb_enum_aliasmem)(struct pdb_context *context,
- const DOM_SID *alias,
- DOM_SID **members, int *num_members);
-
- NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
- const DOM_SID *alias,
- DOM_SID **aliases,
- int *num);
-
- /* group functions */
-
- NTSTATUS (*pdb_get_group_info_by_sid)(struct pdb_context *context, GROUP_INFO *info, const DOM_SID *group);
-
- NTSTATUS (*pdb_get_group_list)(struct pdb_context *context, GROUP_INFO **info, const enum SID_NAME_USE sid_name_use, int *num_groups);
-
- NTSTATUS (*pdb_get_group_sids)(struct pdb_context *context, const DOM_SID *group, DOM_SID **members, int *num_members);
-
- NTSTATUS (*pdb_add_group)(struct pdb_context *context, const SAM_GROUP *group);
-
- NTSTATUS (*pdb_update_group)(struct pdb_context *context, const SAM_GROUP *group);
-
- NTSTATUS (*pdb_delete_group)(struct pdb_context *context, const DOM_SID *group);
-
- NTSTATUS (*pdb_add_sid_to_group)(struct pdb_context *context, const DOM_SID *group, const DOM_SID *member);
-
- NTSTATUS (*pdb_remove_sid_from_group)(struct pdb_context *context, const DOM_SID *group, const DOM_SID *member);
-
- NTSTATUS (*pdb_get_group_info_by_name)(struct pdb_context *context, GROUP_INFO *info, const char *name);
-
- NTSTATUS (*pdb_get_group_info_by_nt_name)(struct pdb_context *context, GROUP_INFO *info, const char *nt_name);
-
- NTSTATUS (*pdb_get_group_uids)(struct pdb_context *context, const DOM_SID *group, uid_t **members, int *num_members);
-
- /* trust password functions */
-
- NTSTATUS (*pdb_settrustpwent)(struct pdb_context *context);
-
- void (*pdb_endtrustpwent)(struct pdb_context *);
-
- NTSTATUS (*pdb_gettrustpwent)(struct pdb_context *context, SAM_TRUST_PASSWD *trust);
-
- NTSTATUS (*pdb_gettrustpwnam)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const char *dom_name);
-
- NTSTATUS (*pdb_gettrustpwsid)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const DOM_SID *sid);
-
- NTSTATUS (*pdb_add_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust);
-
- NTSTATUS (*pdb_update_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust);
-
- NTSTATUS (*pdb_delete_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust);
-
- /* privileges functions */
-
- NTSTATUS (*pdb_lsa_create_account)(struct pdb_context *context, const DOM_SID *sid);
-
- NTSTATUS (*pdb_lsa_enumerate_accounts)(struct pdb_context *context, DOM_SID **sid, int *sid_count);
-
- NTSTATUS (*pdb_add_privilege_to_sid)(struct pdb_context *context, const char *priv_name, const DOM_SID *sid);
-
- NTSTATUS (*pdb_remove_privilege_from_sid)(struct pdb_context *context, const char *priv_name, const DOM_SID *sid);
-
- NTSTATUS (*pdb_get_privilege_set)(struct pdb_context *context, DOM_SID *user_sids, int num_sids, PRIVILEGE_SET *privs);
-
- NTSTATUS (*pdb_get_privilege_entry)(struct pdb_context *context, const char *privname, DOM_SID **sid_list, int *sid_count);
-
- void (*free_fn)(struct pdb_context **);
-
- TALLOC_CTX *mem_ctx;
-
-} PDB_CONTEXT;
-
-typedef struct pdb_methods
-{
- const char *name; /* What name got this module */
- struct pdb_context *parent;
-
- /* Use macros from dlinklist.h on these two */
- struct pdb_methods *next;
- struct pdb_methods *prev;
-
- NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update);
-
- void (*endsampwent)(struct pdb_methods *);
-
- NTSTATUS (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user);
-
- NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
-
- NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
-
- NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
-
- NTSTATUS (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
-
- NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username);
-
- /* group mapping functions: to be removed */
-
- NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid);
-
- NTSTATUS (*getgrgid)(struct pdb_methods *methods, GROUP_MAP *map, gid_t gid);
-
- NTSTATUS (*getgrnam)(struct pdb_methods *methods, GROUP_MAP *map, const char *name);
-
- NTSTATUS (*add_group_mapping_entry)(struct pdb_methods *methods,
- GROUP_MAP *map);
-
- NTSTATUS (*update_group_mapping_entry)(struct pdb_methods *methods,
- GROUP_MAP *map);
-
- NTSTATUS (*delete_group_mapping_entry)(struct pdb_methods *methods,
- DOM_SID sid);
-
- NTSTATUS (*enum_group_mapping)(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only);
-
- NTSTATUS (*find_alias)(struct pdb_methods *methods,
- const char *name, DOM_SID *sid);
-
- NTSTATUS (*create_alias)(struct pdb_methods *methods,
- const char *name, uint32 *rid);
-
- NTSTATUS (*delete_alias)(struct pdb_methods *methods,
- const DOM_SID *sid);
-
- NTSTATUS (*enum_aliases)(struct pdb_methods *methods,
- const DOM_SID *domain_sid,
- uint32 start_idx, uint32 max_entries,
- uint32 *num_aliases, struct acct_info **info);
-
- NTSTATUS (*get_aliasinfo)(struct pdb_methods *methods,
- const DOM_SID *sid,
- struct acct_info *info);
-
- NTSTATUS (*set_aliasinfo)(struct pdb_methods *methods,
- const DOM_SID *sid,
- struct acct_info *info);
-
- NTSTATUS (*add_aliasmem)(struct pdb_methods *methods,
- const DOM_SID *alias, const DOM_SID *member);
- NTSTATUS (*del_aliasmem)(struct pdb_methods *methods,
- const DOM_SID *alias, const DOM_SID *member);
- NTSTATUS (*enum_aliasmem)(struct pdb_methods *methods,
- const DOM_SID *alias, DOM_SID **members,
- int *num_members);
- NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num);
-
- /* group functions */
-
- NTSTATUS (*get_group_info_by_sid)(struct pdb_methods *methods, GROUP_INFO *info, const DOM_SID *group);
-
- NTSTATUS (*get_group_list)(struct pdb_methods *methods, GROUP_INFO **info, const enum SID_NAME_USE sid_name_use, int *num_groups);
-
- NTSTATUS (*get_group_sids)(struct pdb_methods *methods, const DOM_SID *group, DOM_SID **members, int *num_members);
-
- NTSTATUS (*add_group)(struct pdb_methods *methods, const SAM_GROUP *group);
-
- NTSTATUS (*update_group)(struct pdb_methods *methods, const SAM_GROUP *group);
-
- NTSTATUS (*delete_group)(struct pdb_methods *methods, const DOM_SID *group);
-
- NTSTATUS (*add_sid_to_group)(struct pdb_methods *methods, const DOM_SID *group, const DOM_SID *member);
-
- NTSTATUS (*remove_sid_from_group)(struct pdb_methods *methods, const DOM_SID *group, const DOM_SID *member);
-
- NTSTATUS (*get_group_info_by_name)(struct pdb_methods *methods, GROUP_INFO *info, const char *name);
-
- NTSTATUS (*get_group_info_by_nt_name)(struct pdb_methods *methods, GROUP_INFO *info, const char *nt_name);
-
- NTSTATUS (*get_group_uids)(struct pdb_methods *methods, const DOM_SID *group, uid_t **members, int *num_members);
-
- void *private_data; /* Private data of some kind */
-
- void (*free_private_data)(void **);
-
- /* trust password functions */
-
- NTSTATUS (*settrustpwent)(struct pdb_methods *methods);
-
- void (*endtrustpwent)(struct pdb_methods *);
-
- NTSTATUS (*gettrustpwent)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust);
-
- NTSTATUS (*gettrustpwnam)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const char *name);
-
- NTSTATUS (*gettrustpwsid)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid);
-
- NTSTATUS (*add_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust);
-
- NTSTATUS (*update_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust);
-
- NTSTATUS (*delete_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust);
-
- /* privileges functions */
-
- NTSTATUS (*lsa_create_account)(struct pdb_methods *methods, const DOM_SID *sid);
-
- NTSTATUS (*lsa_enumerate_accounts)(struct pdb_methods *methods, DOM_SID **sid, int *num_entries);
-
- NTSTATUS (*add_privilege_to_sid)(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid);
-
- NTSTATUS (*remove_privilege_from_sid)(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid);
-
- NTSTATUS (*get_privilege_set)(struct pdb_methods *methods, DOM_SID *user_sids, int num_sids, PRIVILEGE_SET *privs);
-
- NTSTATUS (*get_privilege_entry)(struct pdb_methods *methods, const char *privname, DOM_SID **sid_list, int *sid_count);
-
-} PDB_METHODS;
-
-typedef NTSTATUS (*pdb_init_function)(struct pdb_context *,
- struct pdb_methods **,
- const char *);
-
-struct pdb_init_function_entry {
- const char *name;
- /* Function to create a member of the pdb_methods list */
- pdb_init_function init;
- struct pdb_init_function_entry *prev, *next;
-};
-
-enum sql_search_field { SQL_SEARCH_NONE = 0, SQL_SEARCH_USER_SID = 1, SQL_SEARCH_USER_NAME = 2};
-
-#endif /* _PASSDB_H */
diff --git a/source/include/popt_common.h b/source/include/popt_common.h
deleted file mode 100644
index 6db30fbc0ac..00000000000
--- a/source/include/popt_common.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Common popt arguments
- Copyright (C) Jelmer Vernooij 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _POPT_COMMON_H
-#define _POPT_COMMON_H
-
-/* Common popt structures */
-extern struct poptOption popt_common_samba[];
-extern struct poptOption popt_common_connection[];
-extern struct poptOption popt_common_version[];
-extern struct poptOption popt_common_credentials[];
-
-#ifndef POPT_TABLEEND
-#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
-#endif
-
-#define POPT_COMMON_SAMBA { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_samba, 0, "Common samba options:", NULL },
-#define POPT_COMMON_CONNECTION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_connection, 0, "Connection options:", NULL },
-#define POPT_COMMON_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version, 0, "Common samba options:", NULL },
-#define POPT_COMMON_CREDENTIALS { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_credentials, 0, "Authentication options:", NULL },
-
-struct user_auth_info {
- pstring username;
- pstring password;
- BOOL got_pass;
- BOOL use_kerberos;
- int signing_state;
-};
-
-extern struct user_auth_info cmdline_auth_info;
-
-#endif /* _POPT_COMMON_H */
diff --git a/source/include/printing.h b/source/include/printing.h
index bf7c61b251e..181adb344a5 100644
--- a/source/include/printing.h
+++ b/source/include/printing.h
@@ -2,7 +2,8 @@
#define PRINTING_H_
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
printing definitions
Copyright (C) Andrew Tridgell 1992-2000
@@ -21,6 +22,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "includes.h"
+
/*
This file defines the low-level printing system interfaces used by the
SAMBA printing subsystem.
@@ -41,7 +44,6 @@ struct printjob {
fstring jobname; /* the job name given to us by the client */
fstring user; /* the user who started the job */
fstring queuename; /* service number of printer for this job */
- NT_DEVICEMODE *nt_devmode;
};
/* Information for print interfaces */
@@ -70,22 +72,6 @@ extern struct printif cups_printif;
#define MAX_CACHE_VALID_TIME 3600
#define PRINT_SPOOL_PREFIX "smbprn."
-#define PRINT_DATABASE_VERSION 5
-
-/* There can be this many printing tdb's open, plus any locked ones. */
-#define MAX_PRINT_DBS_OPEN 1
-
-struct tdb_print_db {
- struct tdb_print_db *next, *prev;
- TDB_CONTEXT *tdb;
- int ref_count;
- fstring printer_name;
-};
-
-/*
- * Used for print notify
- */
-
-#define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST"
+#define PRINT_DATABASE_VERSION 4
#endif /* PRINTING_H_ */
diff --git a/source/include/privileges.h b/source/include/privileges.h
deleted file mode 100644
index 1a6d3e94840..00000000000
--- a/source/include/privileges.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
- Copyright (C) Simo Sorce 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef PRIVILEGES_H
-#define PRIVILEGES_H
-
-#define PRIV_ALL_INDEX 30
-
-#define SE_NONE 0
-#define SE_ASSIGN_PRIMARY_TOKEN 1
-#define SE_CREATE_TOKEN 2
-#define SE_LOCK_MEMORY 3
-#define SE_INCREASE_QUOTA 4
-#define SE_UNSOLICITED_INPUT 5
-#define SE_MACHINE_ACCOUNT 6
-#define SE_TCB 7
-#define SE_SECURITY 8
-#define SE_TAKE_OWNERSHIP 9
-#define SE_LOAD_DRIVER 10
-#define SE_SYSTEM_PROFILE 11
-#define SE_SYSTEM_TIME 12
-#define SE_PROF_SINGLE_PROCESS 13
-#define SE_INC_BASE_PRIORITY 14
-#define SE_CREATE_PAGEFILE 15
-#define SE_CREATE_PERMANENT 16
-#define SE_BACKUP 17
-#define SE_RESTORE 18
-#define SE_SHUTDOWN 19
-#define SE_DEBUG 20
-#define SE_AUDIT 21
-#define SE_SYSTEM_ENVIRONMENT 22
-#define SE_CHANGE_NOTIFY 23
-#define SE_REMOTE_SHUTDOWN 24
-#define SE_UNDOCK 25
-#define SE_SYNC_AGENT 26
-#define SE_ENABLE_DELEGATION 27
-#define SE_PRINT_OPERATOR 28
-#define SE_ADD_USERS 29
-#define SE_ALL_PRIVS 0xffff
-
-#define PR_NONE 0x0000
-#define PR_LOG_ON_LOCALLY 0x0001
-#define PR_ACCESS_FROM_NETWORK 0x0002
-#define PR_LOG_ON_BATCH_JOB 0x0004
-#define PR_LOG_ON_SERVICE 0x0010
-
-#ifndef _BOOL
-typedef int BOOL;
-#define _BOOL /* So we don't typedef BOOL again in vfs.h */
-#endif
-
-typedef struct LUID
-{
- uint32 low;
- uint32 high;
-} LUID;
-
-typedef struct LUID_ATTR
-{
- LUID luid;
- uint32 attr;
-} LUID_ATTR;
-
-typedef struct privilege_set
-{
- TALLOC_CTX *mem_ctx;
- BOOL ext_ctx;
- uint32 count;
- uint32 control;
- LUID_ATTR *set;
-} PRIVILEGE_SET;
-
-typedef struct _PRIVS {
- uint32 se_priv;
- const char *priv;
- const char *description;
-} PRIVS;
-
-
-#endif /* PRIVILEGES_H */
diff --git a/source/include/smbprofile.h b/source/include/profile.h
index e494faf7da6..e393c34815c 100644..100755
--- a/source/include/smbprofile.h
+++ b/source/include/profile.h
@@ -1,7 +1,8 @@
#ifndef _PROFILE_H_
#define _PROFILE_H_
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
store smbd profiling information in shared memory
Copyright (C) Andrew Tridgell 1999
@@ -34,7 +35,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
#define PROF_SHMEM_KEY ((key_t)0x07021999)
#define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 9
+#define PROF_SHM_VERSION 7
/* time values in the following structure are in microseconds */
@@ -60,15 +61,9 @@ struct profile_stats {
unsigned syscall_read_count;
unsigned syscall_read_time;
unsigned syscall_read_bytes; /* bytes read with read syscall */
- unsigned syscall_pread_count;
- unsigned syscall_pread_time;
- unsigned syscall_pread_bytes; /* bytes read with pread syscall */
unsigned syscall_write_count;
unsigned syscall_write_time;
unsigned syscall_write_bytes; /* bytes written with write syscall */
- unsigned syscall_pwrite_count;
- unsigned syscall_pwrite_time;
- unsigned syscall_pwrite_bytes; /* bytes written with pwrite syscall */
unsigned syscall_lseek_count;
unsigned syscall_lseek_time;
unsigned syscall_sendfile_count;
@@ -114,10 +109,6 @@ struct profile_stats {
unsigned syscall_mknod_time;
unsigned syscall_realpath_count;
unsigned syscall_realpath_time;
- unsigned syscall_get_quota_count;
- unsigned syscall_get_quota_time;
- unsigned syscall_set_quota_count;
- unsigned syscall_set_quota_time;
/* stat cache counters */
unsigned statcache_lookups;
unsigned statcache_misses;
@@ -259,8 +250,6 @@ struct profile_stats {
unsigned SMBntcreateX_time;
unsigned SMBntcancel_count; /* NT cancel */
unsigned SMBntcancel_time;
- unsigned SMBntrename_count; /* NT rename file */
- unsigned SMBntrename_time;
unsigned SMBsplopen_count; /* open print spool file */
unsigned SMBsplopen_time;
unsigned SMBsplwr_count; /* write to print spool file */
@@ -338,10 +327,6 @@ struct profile_stats {
unsigned NT_transact_rename_time;
unsigned NT_transact_query_security_desc_count;
unsigned NT_transact_query_security_desc_time;
- unsigned NT_transact_get_user_quota_count;
- unsigned NT_transact_get_user_quota_time;
- unsigned NT_transact_set_user_quota_count;
- unsigned NT_transact_set_user_quota_time;
/* These are ACL manipulation calls */
unsigned get_nt_acl_count;
unsigned get_nt_acl_time;
diff --git a/source/include/rap.h b/source/include/rap.h
index 993dfa7e335..24b70251b77 100755
--- a/source/include/rap.h
+++ b/source/include/rap.h
@@ -1,5 +1,6 @@
/*
Samba Unix/Linux SMB client library
+ Version 3.0
RAP (SMB Remote Procedure Calls) defines and structures
Copyright (C) Steve French 2001 (sfrench@us.ibm.com)
Copyright (C) Jim McDonough 2001 (jmcd@us.ibm.com)
diff --git a/source/include/rpc_brs.h b/source/include/rpc_brs.h
index cd0928d470f..99ba8f2dd07 100644
--- a/source/include/rpc_brs.h
+++ b/source/include/rpc_brs.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
diff --git a/source/include/rpc_client.h b/source/include/rpc_client.h
index bce9ec7f273..270545c2a3f 100644
--- a/source/include/rpc_client.h
+++ b/source/include/rpc_client.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Elrond 2000
diff --git a/source/include/rpc_client_proto.h b/source/include/rpc_client_proto.h
new file mode 100755
index 00000000000..aa22b1996a8
--- /dev/null
+++ b/source/include/rpc_client_proto.h
@@ -0,0 +1,232 @@
+#ifndef _RPC_CLIENT_PROTO_H_
+#define _RPC_CLIENT_PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from lib/util_list.c */
+
+BOOL copy_policy_hnd (POLICY_HND *dest, const POLICY_HND *src);
+BOOL compare_rpc_hnd_node(const RPC_HND_NODE *x,
+ const RPC_HND_NODE *y);
+BOOL RpcHndList_set_connection(const POLICY_HND *hnd,
+ struct cli_connection *con);
+BOOL RpcHndList_del_connection(const POLICY_HND *hnd);
+struct cli_connection* RpcHndList_get_connection(const POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_connect.c */
+
+void init_connections(void);
+void free_connections(void);
+void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds);
+struct _cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_con_ok(struct cli_connection *con);
+
+/*The following definitions come from rpc_client/cli_login.c */
+
+BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
+BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
+ uint32 smb_userid_low, char *password,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
+ uint32 smb_userid_low, char lm_chal[8],
+ char *lm_chal_resp, char *nt_chal_resp,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_lsarpc.c */
+
+BOOL do_lsa_open_policy(struct cli_state *cli,
+ char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos);
+BOOL do_lsa_query_info_pol(struct cli_state *cli,
+ POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid);
+BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd);
+BOOL cli_lsa_get_domain_sid(struct cli_state *cli, char *server);
+uint32 lsa_open_policy(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+uint32 lsa_close(POLICY_HND *hnd);
+uint32 lsa_lookup_sids(POLICY_HND *hnd, int num_sids, DOM_SID *sids,
+ char ***names, uint32 **types, int *num_names);
+uint32 lsa_lookup_names(POLICY_HND *hnd, int num_names, char **names,
+ DOM_SID **sids, uint32 **types, int *num_sids);
+
+/*The following definitions come from rpc_client/cli_netlogon.c */
+
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
+BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal);
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
+BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+BOOL change_trust_account_password( char *domain, char *remote_machine_list);
+
+/*The following definitions come from rpc_client/cli_pipe.c */
+
+BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
+ prs_struct *data, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name);
+void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
+BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
+void cli_nt_session_close(struct cli_state *cli);
+
+/*The following definitions come from rpc_client/cli_reg.c */
+
+BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+ POLICY_HND *reg_hnd);
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd);
+BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
+ char *class, uint32 *class_len,
+ uint32 *num_subkeys, uint32 *max_subkeylen,
+ uint32 *max_subkeysize, uint32 *num_values,
+ uint32 *max_valnamelen, uint32 *max_valbufsize,
+ uint32 *sec_desc, NTTIME *mod_time);
+BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk);
+BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_value, uint32* key_type);
+BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf);
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf);
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name);
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name);
+BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *sam_access,
+ POLICY_HND *key);
+BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
+ int key_index, char *key_name,
+ uint32 *unk_1, uint32 *unk_2,
+ time_t *mod_time);
+BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
+ char *val_name, uint32 type, BUFFER3 *data);
+BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
+ int val_index, int max_valnamelen, int max_valbufsize,
+ fstring val_name,
+ uint32 *val_type, BUFFER2 *value);
+BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, uint32 unk_0,
+ POLICY_HND *key_hnd);
+BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_samr.c */
+
+BOOL get_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol_open_domain, uint32 user_rid,
+ uint32 *num_groups, DOM_GID *gid);
+BOOL get_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USER_INFO_21 *usr);
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+ char *srv_name, char *user_name,
+ char nt_newpass[516], uchar nt_oldhash[16],
+ char lm_newpass[516], uchar lm_oldhash[16]);
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name);
+BOOL do_samr_query_dom_info(struct cli_state *cli,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL do_samr_enum_dom_users(struct cli_state *cli,
+ POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info **sam,
+ int *num_sam_users);
+BOOL do_samr_connect(struct cli_state *cli,
+ char *srv_name, uint32 unknown_0,
+ POLICY_HND *connect_pol);
+BOOL do_samr_open_user(struct cli_state *cli,
+ POLICY_HND *pol, uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol);
+BOOL do_samr_open_domain(struct cli_state *cli,
+ POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+ POLICY_HND *domain_pol);
+BOOL do_samr_query_unknown_12(struct cli_state *cli,
+ POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
+ uint32 *num_aliases,
+ fstring als_names [MAX_LOOKUP_SIDS],
+ uint32 num_als_users[MAX_LOOKUP_SIDS]);
+BOOL do_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid);
+BOOL do_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_spoolss_notify.c */
+
+BOOL spoolss_disconnect_from_client( struct cli_state *cli);
+BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine);
+BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, uint32 *status, POLICY_HND *handle);
+BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle,
+ uint32 change_low, uint32 change_high, uint32 *status);
+BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle, uint32 *status);
+
+/*The following definitions come from rpc_client/cli_srvsvc.c */
+
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
+ char *server_name,
+ uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
+ uint32 preferred_len, ENUM_HND *hnd);
+BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_use.c */
+
+void init_cli_use(void);
+void free_cli_use(void);
+struct cli_state *cli_net_use_add(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL reuse, BOOL *is_new);
+BOOL cli_net_use_del(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL force_close, BOOL *connection_closed);
+void cli_net_use_enum(uint32 *num_cons, struct use_info ***use);
+void cli_use_wait_keyboard(void);
+
+/*The following definitions come from rpc_client/cli_wkssvc.c */
+
+BOOL do_wks_query_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value,
+ WKS_INFO_100 *wks100);
+
+/*The following definitions come from rpc_client/ncacn_np_use.c */
+
+BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL reuse, BOOL *is_new_connection);
+#endif /* _PROTO_H_ */
diff --git a/source/include/rpc_creds.h b/source/include/rpc_creds.h
index 3022b172899..0ab508ffe70 100644
--- a/source/include/rpc_creds.h
+++ b/source/include/rpc_creds.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996-1999
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index 8266fc861f1..0b44b3fe554 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
@@ -46,56 +47,66 @@ enum RPC_PKT_TYPE
#define RPC_FLG_LAST 0x02
#define RPC_FLG_NOCALL 0x20
-#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1 /* ALWAYS_SIGN|NEG_NTLM|NEG_LM|NEG_SEAL|NEG_SIGN|NEG_UNICODE */
+/* NTLMSSP message types */
+enum NTLM_MESSAGE_TYPE
+{
+ NTLMSSP_NEGOTIATE = 1,
+ NTLMSSP_CHALLENGE = 2,
+ NTLMSSP_AUTH = 3,
+ NTLMSSP_UNKNOWN = 4
+};
+
+/* NTLMSSP negotiation flags */
+#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
+#define NTLMSSP_NEGOTIATE_OEM 0x00000002
+#define NTLMSSP_REQUEST_TARGET 0x00000004
+#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
+#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
+#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
+#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
+#define NTLMSSP_NEGOTIATE_00001000 0x00001000
+#define NTLMSSP_NEGOTIATE_00002000 0x00002000
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
+#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
+#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
+#define NTLMSSP_NEGOTIATE_128 0x20000000
+#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
+
+#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1
/* NTLMSSP signature version */
#define NTLMSSP_SIGN_VERSION 0x01
-/* NTLMSSP auth type */
+/* NTLMSSP auth type and level. */
#define NTLMSSP_AUTH_TYPE 0xa
+#define NTLMSSP_AUTH_LEVEL 0x6
-/* DCE-RPC standard identifiers to indicate
- signing or sealing of an RPC pipe */
-#define RPC_PIPE_AUTH_SIGN_LEVEL 0x5
-#define RPC_PIPE_AUTH_SEAL_LEVEL 0x6
-
-/* Netlogon schannel auth type and level */
-#define NETSEC_AUTH_TYPE 0x44
-#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
-#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
-#define RPC_AUTH_NETSEC_CHK_LEN 0x20
+/* Maximum PDU fragment size. */
+#define MAX_PDU_FRAG_LEN 0x1630
-/* The 7 here seems to be required to get Win2k not to downgrade us
- to NT4. Actually, anything other than 1ff would seem to do... */
-#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
-
-#define NETLOGON_NEG_SCHANNEL 0x40000000
+/*
+ * Actual structure of a DCE UUID
+ */
-enum netsec_direction
+typedef struct rpc_uuid
{
- SENDER_IS_INITIATOR,
- SENDER_IS_ACCEPTOR
-};
+ uint32 time_low;
+ uint16 time_mid;
+ uint16 time_hi_and_version;
+ uint8 remaining[8];
+} RPC_UUID;
-/* Internal Flags to indicate what type of authentication on the pipe */
-#define AUTH_PIPE_SIGN 0x0001
-#define AUTH_PIPE_SEAL 0x0002
-#define AUTH_PIPE_NTLMSSP 0x0004
-#define AUTH_PIPE_NETSEC 0x0008
-
-/* Maximum PDU fragment size. */
-/* #define MAX_PDU_FRAG_LEN 0x1630 this is what wnt sets */
-#define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
+#define RPC_UUID_LEN 16
/* RPC_IFACE */
typedef struct rpc_iface_info
{
- struct uuid uuid; /* 16 bytes of rpc interface identification */
+ RPC_UUID uuid; /* 16 bytes of rpc interface identification */
uint32 version; /* the interface version number */
} RPC_IFACE;
-#define RPC_IFACE_LEN (UUID_SIZE + 4)
+#define RPC_IFACE_LEN (RPC_UUID_LEN + 4)
struct pipe_id_info
{
@@ -128,8 +139,8 @@ typedef struct rpc_hdr_info
typedef struct rpc_hdr_req_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
- uint16 context_id; /* presentation context identifier */
- uint16 opnum; /* opnum */
+ uint16 context_id; /* 0 - presentation context identifier */
+ uint16 opnum; /* opnum */
} RPC_HDR_REQ;
@@ -204,43 +215,15 @@ typedef struct rpc_hdr_auth_info
{
uint8 auth_type; /* 0x0a */
uint8 auth_level; /* 0x06 */
- uint8 padding;
- uint8 reserved; /* padding */
+ uint8 stub_type_len; /* don't know */
+ uint8 padding; /* padding */
- uint32 auth_context; /* pointer */
+ uint32 unknown; /* pointer */
} RPC_HDR_AUTH;
#define RPC_HDR_AUTH_LEN 8
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind request */
-/* RPC_AUTH_NETSEC_NEG */
-typedef struct rpc_auth_netsec_neg_info
-{
- uint32 type1; /* Always zero ? */
- uint32 type2; /* Types 0x3 and 0x13 seen. Check AcquireSecurityContext() docs.... */
- fstring domain; /* calling workstations's domain */
- fstring myname; /* calling workstation's name */
-} RPC_AUTH_NETSEC_NEG;
-
-/* attached to the end of encrypted rpc requests and responses */
-/* RPC_AUTH_NETSEC_CHK */
-typedef struct rpc_auth_netsec_chk_info
-{
- uint8 sig [8]; /* 77 00 7a 00 ff ff 00 00 */
- uint8 packet_digest[8]; /* checksum over the packet, MD5'ed with session key */
- uint8 seq_num[8]; /* verifier, seq num */
- uint8 confounder[8]; /* random 8-byte nonce */
-} RPC_AUTH_NETSEC_CHK;
-
-struct netsec_auth_struct
-{
- uchar sess_key[16];
- uint32 seq_num;
- int auth_flags;
-};
-
/* RPC_BIND_REQ - ms req bind */
typedef struct rpc_bind_req_info
{
@@ -290,8 +273,8 @@ typedef struct rpc_hdr_ba_info
/* RPC_AUTH_VERIFIER */
typedef struct rpc_auth_verif_info
{
- fstring signature; /* "NTLMSSP".. Ok, not quite anymore */
- uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) and 5 for schannel */
+ fstring signature; /* "NTLMSSP" */
+ uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) */
} RPC_AUTH_VERIFIER;
@@ -358,4 +341,5 @@ typedef struct rpc_auth_ntlmssp_chk_info
#define RPC_AUTH_NTLMSSP_CHK_LEN 16
+
#endif /* _DCE_RPC_H */
diff --git a/source/include/rpc_dfs.h b/source/include/rpc_dfs.h
index 39316a5d541..5222d6b3565 100644
--- a/source/include/rpc_dfs.h
+++ b/source/include/rpc_dfs.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Samba parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996 - 2000
diff --git a/source/include/rpc_ds.h b/source/include/rpc_ds.h
deleted file mode 100644
index e06918730a4..00000000000
--- a/source/include/rpc_ds.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Gerald Carter 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _RPC_DS_H /* _RPC_LSA_H */
-#define _RPC_DS_H
-
-#include "rpc_misc.h"
-
-
-/* Opcodes available on PIPE_LSARPC_DS */
-
-#define DS_GETPRIMDOMINFO 0x00
-#define DS_NOP 0xFF /* no op -- placeholder */
-
-/* Opcodes available on PIPE_NETLOGON */
-
-#define DS_ENUM_DOM_TRUSTS 0x28
-
-
-/* macros for RPC's */
-
-/* DSROLE_PRIMARY_DOMAIN_INFO_BASIC */
-
-/* flags */
-
-#define DSROLE_PRIMARY_DS_RUNNING 0x00000001
-#define DSROLE_PRIMARY_DS_MIXED_MODE 0x00000002
-#define DSROLE_UPGRADE_IN_PROGRESS 0x00000004
-#define DSROLE_PRIMARY_DOMAIN_GUID_PRESENT 0x01000000
-
-/* machine role */
-
-#define DSROLE_STANDALONE_SRV 2
-#define DSROLE_DOMAIN_MEMBER_SRV 3
-#define DSROLE_BDC 4
-#define DSROLE_PDC 5
-
-
-typedef struct
-{
- uint16 machine_role;
- uint16 unknown; /* 0x6173 -- maybe just alignment? */
-
- uint32 flags;
-
- uint32 netbios_ptr;
- uint32 dnsname_ptr;
- uint32 forestname_ptr;
-
- struct uuid domain_guid;
-
- UNISTR2 netbios_domain;
-
- UNISTR2 dns_domain; /* our dns domain */
- UNISTR2 forest_domain; /* root domain of the forest to which we belong */
-} DSROLE_PRIMARY_DOMAIN_INFO_BASIC;
-
-typedef struct
-{
- DSROLE_PRIMARY_DOMAIN_INFO_BASIC *basic;
-} DS_DOMINFO_CTR;
-
-/* info levels for ds_getprimdominfo() */
-
-#define DsRolePrimaryDomainInfoBasic 1
-
-
-/* DS_Q_GETPRIMDOMINFO - DsGetPrimaryDomainInformation() request */
-typedef struct
-{
- uint16 level;
-} DS_Q_GETPRIMDOMINFO;
-
-/* DS_R_GETPRIMDOMINFO - DsGetPrimaryDomainInformation() response */
-typedef struct
-{
- uint32 ptr;
-
- uint16 level;
- uint16 unknown0; /* 0x455c -- maybe just alignment? */
-
- DS_DOMINFO_CTR info;
-
- NTSTATUS status;
-} DS_R_GETPRIMDOMINFO;
-
-typedef struct {
- /* static portion of structure */
- uint32 netbios_ptr;
- uint32 dns_ptr;
- uint32 flags;
- uint32 parent_index;
- uint32 trust_type;
- uint32 trust_attributes;
- uint32 sid_ptr;
- struct uuid guid;
-
- UNISTR2 netbios_domain;
- UNISTR2 dns_domain;
- DOM_SID2 sid;
-
-} DS_DOMAIN_TRUSTS;
-
-struct ds_domain_trust {
- /* static portion of structure */
- uint32 flags;
- uint32 parent_index;
- uint32 trust_type;
- uint32 trust_attributes;
- struct uuid guid;
-
- DOM_SID sid;
- char *netbios_domain;
- char *dns_domain;
-};
-
-typedef struct {
-
- uint32 ptr;
- uint32 max_count;
- DS_DOMAIN_TRUSTS *trusts;
-
-} DS_DOMAIN_TRUSTS_CTR;
-
-#define DS_DOMAIN_IN_FOREST 0x0001 /* domains in the forest to which
- we belong; even different domain trees */
-#define DS_DOMAIN_DIRECT_OUTBOUND 0x0002 /* trusted domains */
-#define DS_DOMAIN_TREE_ROOT 0x0004 /* root of our forest; also available in
- DsRoleGetPrimaryDomainInfo() */
-#define DS_DOMAIN_PRIMARY 0x0008 /* our domain */
-#define DS_DOMAIN_NATIVE_MODE 0x0010 /* native mode AD servers */
-#define DS_DOMAIN_DIRECT_INBOUND 0x0020 /* trusting domains */
-
-/* DS_Q_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() request */
-typedef struct
-{
- uint32 server_ptr;
- UNISTR2 server;
- uint32 flags;
-
-} DS_Q_ENUM_DOM_TRUSTS;
-
-/* DS_R_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() response */
-typedef struct
-{
- uint32 num_domains;
- DS_DOMAIN_TRUSTS_CTR domains;
-
- NTSTATUS status;
-
-} DS_R_ENUM_DOM_TRUSTS;
-
-
-#endif /* _RPC_DS_H */
diff --git a/source/include/rpc_echo.h b/source/include/rpc_echo.h
deleted file mode 100644
index 6b4ea6abfba..00000000000
--- a/source/include/rpc_echo.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Samba rpcecho definitions.
-
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _RPC_ECHO_H
-#define _RPC_ECHO_H
-
-#define ECHO_ADD_ONE 0x00
-#define ECHO_DATA 0x01
-#define ECHO_SINK_DATA 0x02
-#define ECHO_SOURCE_DATA 0x03
-
-typedef struct echo_q_add_one
-{
- uint32 request;
-} ECHO_Q_ADD_ONE;
-
-typedef struct echo_r_add_one
-{
- uint32 response;
-} ECHO_R_ADD_ONE;
-
-typedef struct echo_q_echo_data
-{
- uint32 size;
- char *data;
-} ECHO_Q_ECHO_DATA;
-
-typedef struct echo_r_echo_data
-{
- uint32 size;
- char *data;
-} ECHO_R_ECHO_DATA;
-
-typedef struct echo_q_source_data
-{
- uint32 size;
-} ECHO_Q_SOURCE_DATA;
-
-typedef struct echo_r_source_data
-{
- uint32 size;
- char *data;
-} ECHO_R_SOURCE_DATA;
-
-typedef struct echo_q_sink_data
-{
- uint32 size;
- char *data;
-} ECHO_Q_SINK_DATA;
-
-typedef struct echo_r_sink_data
-{
- int dummy; /* unused */
-} ECHO_R_SINK_DATA;
-
-#endif
diff --git a/source/include/rpc_epmapper.h b/source/include/rpc_epmapper.h
deleted file mode 100644
index bbca6ac1f28..00000000000
--- a/source/include/rpc_epmapper.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Endpoint mapper data definitions
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define EPM_HANDLE_LEN 20
-
-/* ordinal for the mapping interface */
-
-#define EPM_MAP_PIPE_NAME 0x03
-
-/* some of the different connection protocols and their IDs from Windows */
-
-#define EPM_FLOOR_UUID 0x0d /* floor contains UUID */
-#define EPM_FLOOR_RPC 0x0b /* tower is for connection-oriented rpc */
-#define EPM_FLOOR_TCP 0x07 /* floor contains tcp port number */
-#define EPM_FLOOR_IP 0x09 /* floor contains IP address */
-#define EPM_FLOOR_NMPIPES 0x0f /* floor contains remote named pipe name */
-#define EPM_FLOOR_LRPC 0x10 /* floor contains local named pipe name */
-#define EPM_FLOOR_NETBIOS 0x11 /* floor contains netbios address */
-#define EPM_FLOOR_NETBEUI 0x12 /* floor contains netbeui address */
-#define EPM_FLOOR_SOCKET 0x20
-
-#define EPM_PIPE_NM "epmapper"
-
-#define MAX_TOWERS 1
-
-typedef struct
-{
- uint8 data[EPM_HANDLE_LEN];
-} EPM_HANDLE;
-
-typedef struct
-{
- struct {
- uint16 length;
- uint8 protocol;
- struct {
- struct uuid uuid;
- uint16 version;
- } uuid;
- } lhs;
- struct {
- uint16 length;
- uint16 unknown;
- struct {
- uint16 port;
- } tcp;
- struct {
- uint8 addr[4];
- } ip;
- char string[MAXHOSTNAMELEN+3]; /* hostname + \\ + null term */
- } rhs;
-} EPM_FLOOR;
-
-typedef struct
-{
- uint32 max_length;
- uint32 length;
- uint16 num_floors;
- EPM_FLOOR *floors;
- uint8 unknown;
-} EPM_TOWER;
-
-typedef struct
-{
- EPM_HANDLE handle;
- uint32 tower_ref_id;
- EPM_TOWER *tower;
- EPM_HANDLE term_handle; /* in/out */
- uint32 max_towers;
-} EPM_Q_MAP;
-
-typedef struct
-{
- uint32 max_count;
- uint32 offset;
- uint32 count;
- uint32 *tower_ref_ids;
- EPM_TOWER *towers;
-} EPM_TOWER_ARRAY;
-
-typedef struct
-{
- EPM_HANDLE handle;
- uint32 num_results;
- EPM_TOWER_ARRAY *results;
- uint32 status;
-} EPM_R_MAP;
-
-
-/* port mapping entries to be read */
-
-typedef struct _mapper_entries{
- uint8 protocol ;
- RPC_IFACE uuid_info ; /* needs to be zeroed if no specific uuid */
- uint16 port ;
- char pipe_name[40] ;
- char srv_name[20] ;
- uint8 srv_port[4] ;
- char func_name[16][16]; /* array of up to 16 functions available */
-} mapper_entries;
-
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index 29a9cd7306b..ccdce6f2636 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -25,13 +25,20 @@
#include "rpc_misc.h"
-/* Opcodes available on PIPE_LSARPC */
-
-#if 0 /* UNIMPLEMENTED */
-
-#define LSA_LOOKUPSIDS2 0x39
+enum SID_NAME_USE
+{
+ SID_NAME_USE_NONE = 0,/* NOTUSED */
+ SID_NAME_USER = 1, /* user */
+ SID_NAME_DOM_GRP = 2, /* domain group */
+ SID_NAME_DOMAIN = 3, /* domain: don't know what this is */
+ SID_NAME_ALIAS = 4, /* local group */
+ SID_NAME_WKN_GRP = 5, /* well-known group */
+ SID_NAME_DELETED = 6, /* deleted account: needed for c2 rating */
+ SID_NAME_INVALID = 7, /* invalid account */
+ SID_NAME_UNKNOWN = 8 /* oops. */
+};
-#endif
+/* Opcodes available on PIPE_LSARPC */
#define LSA_CLOSE 0x00
#define LSA_DELETE 0x01
@@ -79,7 +86,6 @@
#define LSA_RETRPRIVDATA 0x2b
#define LSA_OPENPOLICY2 0x2c
#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */
-#define LSA_QUERYINFO2 0x2e
/* XXXX these are here to get a compile! */
#define LSA_LOOKUPRIDS 0xFD
@@ -268,49 +274,12 @@ typedef struct lsa_r_query_info
} LSA_R_QUERY_INFO;
-/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/
-typedef struct lsa_dns_dom_info
-{
- UNIHDR hdr_nb_dom_name; /* netbios domain name */
- UNIHDR hdr_dns_dom_name;
- UNIHDR hdr_forest_name;
-
- struct uuid dom_guid; /* domain GUID */
-
- UNISTR2 uni_nb_dom_name;
- UNISTR2 uni_dns_dom_name;
- UNISTR2 uni_forest_name;
-
- uint32 ptr_dom_sid;
- DOM_SID2 dom_sid; /* domain SID */
-} LSA_DNS_DOM_INFO;
-
-typedef union lsa_info2_union
-{
- LSA_DNS_DOM_INFO dns_dom_info;
-} LSA_INFO2_UNION;
-
-/* LSA_Q_QUERY_INFO2 - LSA query info */
-typedef struct lsa_q_query_info2
-{
- POLICY_HND pol; /* policy handle */
- uint16 info_class; /* info class */
-} LSA_Q_QUERY_INFO2;
-
-typedef struct lsa_r_query_info2
-{
- uint32 ptr; /* pointer to info struct */
- uint16 info_class;
- LSA_INFO2_UNION info; /* so far the only one */
- NTSTATUS status;
-} LSA_R_QUERY_INFO2;
-
/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
typedef struct lsa_enum_trust_dom_info
{
POLICY_HND pol; /* policy handle */
- uint32 enum_context; /* enumeration context handle */
- uint32 preferred_len; /* preferred maximum length */
+ uint32 enum_context; /* enumeration context handle */
+ uint32 preferred_len; /* preferred maximum length */
} LSA_Q_ENUM_TRUST_DOM;
@@ -521,55 +490,6 @@ typedef struct lsa_r_enum_privs
NTSTATUS status;
} LSA_R_ENUM_PRIVS;
-/* LSA_Q_ENUM_ACCT_RIGHTS - LSA enum account rights */
-typedef struct
-{
- POLICY_HND pol; /* policy handle */
- DOM_SID2 sid;
-} LSA_Q_ENUM_ACCT_RIGHTS;
-
-/* LSA_R_ENUM_ACCT_RIGHTS - LSA enum account rights */
-typedef struct
-{
- uint32 count;
- UNISTR2_ARRAY rights;
- NTSTATUS status;
-} LSA_R_ENUM_ACCT_RIGHTS;
-
-
-/* LSA_Q_ADD_ACCT_RIGHTS - LSA add account rights */
-typedef struct
-{
- POLICY_HND pol; /* policy handle */
- DOM_SID2 sid;
- UNISTR2_ARRAY rights;
- uint32 count;
-} LSA_Q_ADD_ACCT_RIGHTS;
-
-/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */
-typedef struct
-{
- NTSTATUS status;
-} LSA_R_ADD_ACCT_RIGHTS;
-
-
-/* LSA_Q_REMOVE_ACCT_RIGHTS - LSA remove account rights */
-typedef struct
-{
- POLICY_HND pol; /* policy handle */
- DOM_SID2 sid;
- uint32 removeall;
- UNISTR2_ARRAY rights;
- uint32 count;
-} LSA_Q_REMOVE_ACCT_RIGHTS;
-
-/* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */
-typedef struct
-{
- NTSTATUS status;
-} LSA_R_REMOVE_ACCT_RIGHTS;
-
-
/* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */
typedef struct lsa_q_priv_get_dispname
{
@@ -635,20 +555,6 @@ typedef struct lsa_r_unk_get_connuser
} LSA_R_UNK_GET_CONNUSER;
-typedef struct lsa_q_createaccount
-{
- POLICY_HND pol; /* policy handle */
- DOM_SID2 sid;
- uint32 access; /* access */
-} LSA_Q_CREATEACCOUNT;
-
-typedef struct lsa_r_createaccount
-{
- POLICY_HND pol; /* policy handle */
- NTSTATUS status;
-} LSA_R_CREATEACCOUNT;
-
-
typedef struct lsa_q_openaccount
{
POLICY_HND pol; /* policy handle */
@@ -667,11 +573,31 @@ typedef struct lsa_q_enumprivsaccount
POLICY_HND pol; /* policy handle */
} LSA_Q_ENUMPRIVSACCOUNT;
+
+typedef struct LUID
+{
+ uint32 low;
+ uint32 high;
+} LUID;
+
+typedef struct LUID_ATTR
+{
+ LUID luid;
+ uint32 attr;
+} LUID_ATTR ;
+
+typedef struct privilege_set
+{
+ uint32 count;
+ uint32 control;
+ LUID_ATTR *set;
+} PRIVILEGE_SET;
+
typedef struct lsa_r_enumprivsaccount
{
uint32 ptr;
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
NTSTATUS status;
} LSA_R_ENUMPRIVSACCOUNT;
@@ -717,7 +643,7 @@ typedef struct lsa_q_addprivs
{
POLICY_HND pol; /* policy handle */
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
} LSA_Q_ADDPRIVS;
typedef struct lsa_r_addprivs
@@ -732,7 +658,7 @@ typedef struct lsa_q_removeprivs
uint32 allrights;
uint32 ptr;
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
} LSA_Q_REMOVEPRIVS;
typedef struct lsa_r_removeprivs
@@ -742,3 +668,5 @@ typedef struct lsa_r_removeprivs
#endif /* _RPC_LSA_H */
+
+
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index 0c6eee3650a..558c28459e3 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
@@ -26,29 +27,18 @@
#ifndef _RPC_MISC_H /* _RPC_MISC_H */
#define _RPC_MISC_H
-#define SMB_RPC_INTERFACE_VERSION 1
+
/* well-known RIDs - Relative IDs */
/* RIDs - Well-known users ... */
#define DOMAIN_USER_RID_ADMIN (0x000001F4L)
#define DOMAIN_USER_RID_GUEST (0x000001F5L)
-#define DOMAIN_USER_RID_KRBTGT (0x000001F6L)
/* RIDs - well-known groups ... */
#define DOMAIN_GROUP_RID_ADMINS (0x00000200L)
#define DOMAIN_GROUP_RID_USERS (0x00000201L)
#define DOMAIN_GROUP_RID_GUESTS (0x00000202L)
-#define DOMAIN_GROUP_RID_COMPUTERS (0x00000203L)
-
-#define DOMAIN_GROUP_RID_CONTROLLERS (0x00000204L)
-#define DOMAIN_GROUP_RID_CERT_ADMINS (0x00000205L)
-#define DOMAIN_GROUP_RID_SCHEMA_ADMINS (0x00000206L)
-#define DOMAIN_GROUP_RID_ENTERPRISE_ADMINS (0x00000207L)
-
-/* is the following the right number? I bet it is --simo
-#define DOMAIN_GROUP_RID_POLICY_ADMINS (0x00000208L)
-*/
/* RIDs - well-known aliases ... */
#define BUILTIN_ALIAS_RID_ADMINS (0x00000220L)
@@ -62,17 +52,12 @@
#define BUILTIN_ALIAS_RID_BACKUP_OPS (0x00000227L)
#define BUILTIN_ALIAS_RID_REPLICATOR (0x00000228L)
-#define BUILTIN_ALIAS_RID_RAS_SERVERS (0x00000229L)
-#define BUILTIN_ALIAS_RID_PRE_2K_ACCESS (0x0000022aL)
/*
* Masks for mappings between unix uid and gid types and
* NT RIDS.
*/
-
-#define BASE_RID (0x000003E8L)
-
/* Take the bottom bit. */
#define RID_TYPE_MASK 1
#define RID_MULTIPLIER 2
@@ -86,42 +71,49 @@ typedef struct enum_hnd_info
{
uint32 ptr_hnd; /* pointer to enumeration handle */
uint32 handle; /* enumeration handle */
+
} ENUM_HND;
/* LOOKUP_LEVEL - switch value */
typedef struct lookup_level_info
{
- uint16 value;
+ uint16 value;
+
} LOOKUP_LEVEL;
/* DOM_SID2 - security id */
typedef struct sid_info_2
{
uint32 num_auths; /* length, bytes, including length of len :-) */
+
DOM_SID sid;
+
} DOM_SID2;
/* STRHDR - string header */
typedef struct header_info
{
- uint16 str_str_len;
- uint16 str_max_len;
- uint32 buffer; /* non-zero */
+ uint16 str_str_len;
+ uint16 str_max_len;
+ uint32 buffer; /* non-zero */
+
} STRHDR;
/* UNIHDR - unicode string header */
typedef struct unihdr_info
{
- uint16 uni_str_len;
- uint16 uni_max_len;
- uint32 buffer; /* usually has a value of 4 */
+ uint16 uni_str_len;
+ uint16 uni_max_len;
+ uint32 buffer; /* usually has a value of 4 */
+
} UNIHDR;
/* UNIHDR2 - unicode string header and undocumented buffer */
typedef struct unihdr2_info
{
- UNIHDR unihdr;
- uint32 buffer; /* 32 bit buffer pointer */
+ UNIHDR unihdr;
+ uint32 buffer; /* 32 bit buffer pointer */
+
} UNIHDR2;
/* clueless as to what maximum length should be */
@@ -132,15 +124,16 @@ typedef struct unihdr2_info
/* UNISTR - unicode string size and buffer */
typedef struct unistr_info
{
- /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
- uint16 *buffer;
+ /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
+ uint16 *buffer;
} UNISTR;
/* BUFHDR - buffer header */
typedef struct bufhdr_info
{
- uint32 buf_max_len;
- uint32 buf_len;
+ uint32 buf_max_len;
+ uint32 buf_len;
+
} BUFHDR;
/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
@@ -148,47 +141,51 @@ typedef struct bufhdr_info
/* of a unicode string different from the other \PIPE\ writers */
typedef struct buffer2_info
{
- uint32 buf_max_len;
- uint32 offset;
- uint32 buf_len;
- /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
- uint16 *buffer;
+ uint32 buf_max_len;
+ uint32 undoc;
+ uint32 buf_len;
+ /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
+ uint16 *buffer;
+
} BUFFER2;
/* BUFFER3 */
typedef struct buffer3_info
{
- uint32 buf_max_len;
- uint8 *buffer; /* Data */
- uint32 buf_len;
+ uint32 buf_max_len;
+ uint8 *buffer; /* Data */
+ uint32 buf_len;
+
} BUFFER3;
/* BUFFER5 */
typedef struct buffer5_info
{
- uint32 buf_len;
- uint16 *buffer; /* data */
+ uint32 buf_len;
+ uint16 *buffer; /* data */
} BUFFER5;
/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
typedef struct unistr2_info
{
- uint32 uni_max_len;
- uint32 offset;
- uint32 uni_str_len;
- /* unicode characters. ***MUST*** be little-endian.
- **must** be null-terminated and the uni_str_len should include
- the NULL character */
- uint16 *buffer;
+ uint32 uni_max_len;
+ uint32 undoc;
+ uint32 uni_str_len;
+ /* unicode characters. ***MUST*** be little-endian.
+ **must** be null-terminated and the uni_str_len should include
+ the NULL character */
+ uint16 *buffer;
+
} UNISTR2;
/* STRING2 - string size (in uint8 chars) and buffer */
typedef struct string2_info
{
- uint32 str_max_len;
- uint32 offset;
- uint32 str_str_len;
- uint8 *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
+ uint32 str_max_len;
+ uint32 undoc;
+ uint32 str_str_len;
+ uint8 *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
+
} STRING2;
/* UNISTR3 - XXXX not sure about this structure */
@@ -199,38 +196,6 @@ typedef struct unistr3_info
} UNISTR3;
-/* an element in a unicode string array */
-typedef struct
-{
- uint16 length;
- uint16 size;
- uint32 ref_id;
- UNISTR2 string;
-} UNISTR2_ARRAY_EL;
-
-/* an array of unicode strings */
-typedef struct
-{
- uint32 ref_id;
- uint32 count;
- UNISTR2_ARRAY_EL *strings;
-} UNISTR2_ARRAY;
-
-
-/* an element in a sid array */
-typedef struct
-{
- uint32 ref_id;
- DOM_SID2 sid;
-} SID_ARRAY_EL;
-
-/* an array of sids */
-typedef struct
-{
- uint32 ref_id;
- uint32 count;
- SID_ARRAY_EL *sids;
-} SID_ARRAY;
/* DOM_RID2 - domain RID structure for ntlsa pipe */
typedef struct domrid2_info
@@ -255,77 +220,85 @@ typedef struct domrid3_info
/* DOM_RID4 - rid + user attributes */
typedef struct domrid4_info
{
- uint32 unknown;
- uint16 attr;
- uint32 rid; /* user RID */
+ uint32 unknown;
+ uint16 attr;
+ uint32 rid; /* user RID */
+
} DOM_RID4;
/* DOM_CLNT_SRV - client / server names */
typedef struct clnt_srv_info
{
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_comp_name; /* client machine name */
+ uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server name */
+ uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_comp_name; /* client machine name */
+
} DOM_CLNT_SRV;
/* DOM_LOG_INFO - login info */
typedef struct log_info
{
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- UNISTR2 uni_acct_name; /* account name */
- uint16 sec_chan; /* secure channel type */
- UNISTR2 uni_comp_name; /* client machine name */
+ uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server name */
+ UNISTR2 uni_acct_name; /* account name */
+ uint16 sec_chan; /* secure channel type */
+ UNISTR2 uni_comp_name; /* client machine name */
+
} DOM_LOG_INFO;
/* DOM_CHAL - challenge info */
typedef struct chal_info
{
- uchar data[8]; /* credentials */
+ uchar data[8]; /* credentials */
} DOM_CHAL;
/* DOM_CREDs - timestamped client or server credentials */
typedef struct cred_info
{
- DOM_CHAL challenge; /* credentials */
- UTIME timestamp; /* credential time-stamp */
+ DOM_CHAL challenge; /* credentials */
+ UTIME timestamp; /* credential time-stamp */
} DOM_CRED;
/* DOM_CLNT_INFO - client info */
typedef struct clnt_info
{
- DOM_LOG_INFO login;
- DOM_CRED cred;
+ DOM_LOG_INFO login;
+ DOM_CRED cred;
+
} DOM_CLNT_INFO;
/* DOM_CLNT_INFO2 - client info */
typedef struct clnt_info2
{
- DOM_CLNT_SRV login;
- uint32 ptr_cred;
- DOM_CRED cred;
+ DOM_CLNT_SRV login;
+ uint32 ptr_cred;
+ DOM_CRED cred;
+
} DOM_CLNT_INFO2;
/* DOM_LOGON_ID - logon id */
typedef struct logon_info
{
- uint32 low;
- uint32 high;
+ uint32 low;
+ uint32 high;
+
} DOM_LOGON_ID;
/* OWF INFO */
typedef struct owf_info
{
- uint8 data[16];
+ uint8 data[16];
+
} OWF_INFO;
/* DOM_GID - group id + user attributes */
typedef struct gid_info
{
- uint32 g_rid; /* a group RID */
- uint32 attr;
+ uint32 g_rid; /* a group RID */
+ uint32 attr;
+
} DOM_GID;
/* POLICY_HND */
@@ -336,16 +309,6 @@ typedef struct lsa_policy_info
uint16 data3;
uint16 data4;
uint8 data5[8];
-#ifdef __INSURE__
-
- /* To prevent the leakage of policy handles mallocate a bit of
- memory when a policy handle is created and free it when the
- handle is closed. This should cause Insure to flag an error
- when policy handles are overwritten or fall out of scope without
- being freed. */
-
- char *marker;
-#endif
} POLICY_HND;
/*
@@ -404,5 +367,5 @@ typedef struct buffer4_info
}
BUFFER4;
-enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
+
#endif /* _RPC_MISC_H */
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index a5b93b0238a..e4e31b8ea8f 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
Copyright (C) Paul Ashton 1997
- Copyright (C) Jean François Micouleau 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,19 +26,17 @@
/* NETLOGON pipe */
-#define NET_SAMLOGON 0x02
-#define NET_SAMLOGOFF 0x03
-#define NET_REQCHAL 0x04
-#define NET_AUTH 0x05
-#define NET_SRVPWSET 0x06
-#define NET_SAM_DELTAS 0x07
-#define NET_LOGON_CTRL 0x0c
-#define NET_GETDCNAME 0x0d
-#define NET_AUTH2 0x0f
-#define NET_LOGON_CTRL2 0x0e
-#define NET_SAM_SYNC 0x10
-#define NET_TRUST_DOM_LIST 0x13
-#define NET_AUTH3 0x1a
+#define NET_SAMLOGON 0x02
+#define NET_SAMLOGOFF 0x03
+#define NET_REQCHAL 0x04
+#define NET_AUTH 0x05
+#define NET_SRVPWSET 0x06
+#define NET_SAM_DELTAS 0x07
+#define NET_LOGON_CTRL 0x0c
+#define NET_AUTH2 0x0f
+#define NET_LOGON_CTRL2 0x0e
+#define NET_SAM_SYNC 0x10
+#define NET_TRUST_DOM_LIST 0x13
/* Secure Channel types. used in NetrServerAuthenticate negotiation */
#define SEC_CHAN_WKSTA 2
@@ -46,27 +44,20 @@
#define SEC_CHAN_BDC 6
/* Returned delta types */
-#define SAM_DELTA_DOMAIN_INFO 0x01
-#define SAM_DELTA_GROUP_INFO 0x02
-#define SAM_DELTA_RENAME_GROUP 0x04
-#define SAM_DELTA_ACCOUNT_INFO 0x05
-#define SAM_DELTA_RENAME_USER 0x07
-#define SAM_DELTA_GROUP_MEM 0x08
-#define SAM_DELTA_ALIAS_INFO 0x09
-#define SAM_DELTA_RENAME_ALIAS 0x0b
-#define SAM_DELTA_ALIAS_MEM 0x0c
-#define SAM_DELTA_POLICY_INFO 0x0d
-#define SAM_DELTA_TRUST_DOMS 0x0e
-#define SAM_DELTA_PRIVS_INFO 0x10 /* DT_DELTA_ACCOUNTS */
-#define SAM_DELTA_SECRET_INFO 0x12
-#define SAM_DELTA_DELETE_GROUP 0x14
-#define SAM_DELTA_DELETE_USER 0x15
-#define SAM_DELTA_MODIFIED_COUNT 0x16
+#define SAM_DELTA_DOMAIN_INFO 0x01 /* Domain */
+#define SAM_DELTA_GROUP_INFO 0x02 /* Domain groups */
+#define SAM_DELTA_ACCOUNT_INFO 0x05 /* Users */
+#define SAM_DELTA_GROUP_MEM 0x08 /* Group membership */
+#define SAM_DELTA_ALIAS_INFO 0x09 /* Local groups */
+#define SAM_DELTA_ALIAS_MEM 0x0C /* Local group membership */
+#define SAM_DELTA_UNKNOWN 0x0D /* Privilige stuff */
+#define SAM_DELTA_UNKNOWN2 0x10 /* Privilige stuff */
+#define SAM_DELTA_SAM_STAMP 0x16 /* Some kind of journal record? */
/* SAM database types */
#define SAM_DATABASE_DOMAIN 0x00 /* Domain users and groups */
#define SAM_DATABASE_BUILTIN 0x01 /* BUILTIN users and groups */
-#define SAM_DATABASE_PRIVS 0x02 /* Privileges */
+#define SAM_DATABASE_PRIVS 0x02 /* Priviliges? */
#if 0
/* I think this is correct - it's what gets parsed on the wire. JRA. */
@@ -157,7 +148,7 @@ typedef struct net_user_info_3
uint32 buffer_groups; /* undocumented buffer pointer to groups. */
uint32 user_flgs; /* user flags */
- uint8 user_sess_key[16]; /* user session key */
+ uint8 user_sess_key[16]; /* unused user session key */
UNIHDR hdr_logon_srv; /* logon server unicode string header */
UNIHDR hdr_logon_dom; /* logon domain unicode string header */
@@ -299,25 +290,6 @@ typedef struct net_r_logon_ctrl2_info
} NET_R_LOGON_CTRL2;
-/* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */
-
-typedef struct net_q_getdcname
-{
- uint32 ptr_logon_server;
- UNISTR2 uni_logon_server;
- uint32 ptr_domainname;
- UNISTR2 uni_domainname;
-} NET_Q_GETDCNAME;
-
-/* NET_R_GETDCNAME - Ask a DC for a trusted DC name */
-
-typedef struct net_r_getdcname
-{
- uint32 ptr_dcname;
- UNISTR2 uni_dcname;
- NTSTATUS status;
-} NET_R_GETDCNAME;
-
/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
typedef struct net_q_trust_dom_info
{
@@ -397,23 +369,6 @@ typedef struct net_r_auth2_info
NTSTATUS status; /* return code */
} NET_R_AUTH_2;
-/* NET_Q_AUTH_3 */
-typedef struct net_q_auth3_info
-{
- DOM_LOG_INFO clnt_id; /* client identification info */
- DOM_CHAL clnt_chal; /* client-calculated credentials */
- NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */
-} NET_Q_AUTH_3;
-
-/* NET_R_AUTH_3 */
-typedef struct net_r_auth3_info
-{
- DOM_CHAL srv_chal; /* server-calculated credentials */
- NEG_FLAGS srv_flgs; /* usually 0x6007 ffff */
- uint32 unknown; /* 0x0000045b */
- NTSTATUS status; /* return code */
-} NET_R_AUTH_3;
-
/* NET_Q_SRV_PWSET */
typedef struct net_q_srv_pwset_info
@@ -735,132 +690,13 @@ typedef struct sam_alias_mem_info_info
} SAM_ALIAS_MEM_INFO;
-
-/* SAM_DELTA_POLICY (0x0D) */
-typedef struct
-{
- uint32 max_log_size; /* 0x5000 */
- UINT64_S audit_retention_period; /* 0 */
- uint32 auditing_mode; /* 0 */
- uint32 num_events;
- uint32 ptr_events;
- UNIHDR hdr_dom_name;
- uint32 sid_ptr;
-
- uint32 paged_pool_limit; /* 0x02000000 */
- uint32 non_paged_pool_limit; /* 0x00100000 */
- uint32 min_workset_size; /* 0x00010000 */
- uint32 max_workset_size; /* 0x0f000000 */
- uint32 page_file_limit; /* 0 */
- UINT64_S time_limit; /* 0 */
- NTTIME modify_time; /* 0x3c*/
- NTTIME create_time; /* a7080110 */
- BUFHDR2 hdr_sec_desc;
-
- uint32 num_event_audit_options;
- uint32 event_audit_option;
-
- UNISTR2 domain_name;
- DOM_SID2 domain_sid;
-
- BUFFER4 buf_sec_desc;
-} SAM_DELTA_POLICY;
-
-/* SAM_DELTA_TRUST_DOMS */
-typedef struct
-{
- uint32 buf_size;
- SEC_DESC *sec_desc;
- DOM_SID2 sid;
- UNIHDR hdr_domain;
-
- uint32 unknown0;
- uint32 unknown1;
- uint32 unknown2;
-
- uint32 buf_size2;
- uint32 ptr;
-
- uint32 unknown3;
- UNISTR2 domain;
-
-} SAM_DELTA_TRUSTDOMS;
-
-/* SAM_DELTA_PRIVS (0x10) */
-typedef struct
-{
- DOM_SID2 sid;
-
- uint32 priv_count;
- uint32 priv_control;
-
- uint32 priv_attr_ptr;
- uint32 priv_name_ptr;
-
- uint32 paged_pool_limit; /* 0x02000000 */
- uint32 non_paged_pool_limit; /* 0x00100000 */
- uint32 min_workset_size; /* 0x00010000 */
- uint32 max_workset_size; /* 0x0f000000 */
- uint32 page_file_limit; /* 0 */
- UINT64_S time_limit; /* 0 */
- uint32 system_flags; /* 1 */
- BUFHDR2 hdr_sec_desc;
-
- uint32 buf_size2;
-
- uint32 attribute_count;
- uint32 *attributes;
-
- uint32 privlist_count;
- UNIHDR *hdr_privslist;
- UNISTR2 *uni_privslist;
-
- BUFFER4 buf_sec_desc;
-} SAM_DELTA_PRIVS;
-
-/* SAM_DELTA_SECRET */
-typedef struct
-{
- uint32 buf_size;
- SEC_DESC *sec_desc;
- UNISTR2 secret;
-
- uint32 count1;
- uint32 count2;
- uint32 ptr;
- NTTIME time1;
- uint32 count3;
- uint32 count4;
- uint32 ptr2;
- NTTIME time2;
- uint32 unknow1;
-
- uint32 buf_size2;
- uint32 ptr3;
- uint32 unknow2; /* 0x0 12 times */
-
- uint32 chal_len;
- uint32 reserved1; /* 0 */
- uint32 chal_len2;
- uint8 chal[16];
-
- uint32 key_len;
- uint32 reserved2; /* 0 */
- uint32 key_len2;
- uint8 key[8];
-
- uint32 buf_size3;
- SEC_DESC *sec_desc2;
-
-} SAM_DELTA_SECRET;
-
-/* SAM_DELTA_MOD_COUNT (0x16) */
+/* SAM_DELTA_STAMP (0x16) */
typedef struct
{
uint32 seqnum;
uint32 dom_mod_count_ptr;
UINT64_S dom_mod_count; /* domain mod count at last sync */
-} SAM_DELTA_MOD_COUNT;
+} SAM_DELTA_STAMP;
typedef union sam_delta_ctr_info
{
@@ -870,11 +706,7 @@ typedef union sam_delta_ctr_info
SAM_GROUP_MEM_INFO grp_mem_info;
SAM_ALIAS_INFO alias_info ;
SAM_ALIAS_MEM_INFO als_mem_info;
- SAM_DELTA_POLICY policy_info;
- SAM_DELTA_PRIVS privs_info;
- SAM_DELTA_MOD_COUNT mod_count;
- SAM_DELTA_TRUSTDOMS trustdoms_info;
- SAM_DELTA_SECRET secret_info;
+ SAM_DELTA_STAMP stamp;
} SAM_DELTA_CTR;
/* NET_R_SAM_SYNC */
diff --git a/source/include/rpc_parse.h b/source/include/rpc_parse.h
index 73fbcb2b1be..5a302b1af33 100644
--- a/source/include/rpc_parse.h
+++ b/source/include/rpc_parse.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h
index 46ec88283df..8fe40be6f7f 100644
--- a/source/include/rpc_reg.h
+++ b/source/include/rpc_reg.h
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997.
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
- Copyright (C) Paul Ashton 1997.
- Copyright (C) Gerald Carter 2002.
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,124 +25,44 @@
#define _RPC_REG_H
-/* winreg pipe defines
- NOT IMPLEMENTED !!
+/* winreg pipe defines */
+#define REG_OPEN_HKCR 0x00
#define _REG_UNK_01 0x01
+#define REG_OPEN_HKLM 0x02
#define _REG_UNK_03 0x03
+#define REG_OPEN_HKU 0x04
+#define REG_CLOSE 0x05
#define REG_CREATE_KEY 0x06
#define REG_DELETE_KEY 0x07
#define REG_DELETE_VALUE 0x08
+#define REG_ENUM_KEY 0x09
+#define REG_ENUM_VALUE 0x0a
#define REG_FLUSH_KEY 0x0b
#define REG_GET_KEY_SEC 0x0c
#define _REG_UNK_0D 0x0d
#define _REG_UNK_0E 0x0e
+#define REG_OPEN_ENTRY 0x0f
+#define REG_QUERY_KEY 0x10
+#define REG_INFO 0x11
#define _REG_UNK_12 0x12
#define _REG_UNK_13 0x13
+#define _REG_UNK_14 0x14
#define REG_SET_KEY_SEC 0x15
#define REG_CREATE_VALUE 0x16
#define _REG_UNK_17 0x17
-*/
-
-/* Implemented */
-#define REG_OPEN_HKCR 0x00
-#define REG_OPEN_HKLM 0x02
-#define REG_OPEN_HKU 0x04
-#define REG_CLOSE 0x05
-#define REG_ENUM_KEY 0x09
-#define REG_ENUM_VALUE 0x0a
-#define REG_OPEN_ENTRY 0x0f
-#define REG_QUERY_KEY 0x10
-#define REG_INFO 0x11
#define REG_SHUTDOWN 0x18
#define REG_ABORT_SHUTDOWN 0x19
-#define REG_SAVE_KEY 0x14 /* no idea what the real name is */
-#define REG_UNKNOWN_1A 0x1a
-
+#define REG_UNK_1A 0x1a
#define HKEY_CLASSES_ROOT 0x80000000
#define HKEY_CURRENT_USER 0x80000001
#define HKEY_LOCAL_MACHINE 0x80000002
#define HKEY_USERS 0x80000003
-#define KEY_HKLM "HKLM"
-#define KEY_HKU "HKU"
-#define KEY_HKCR "HKCR"
-#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
-#define KEY_TREE_ROOT ""
-
-/* Registry data types */
-
-#define REG_NONE 0
-#define REG_SZ 1
-#define REG_EXPAND_SZ 2
-#define REG_BINARY 3
-#define REG_DWORD 4
-#define REG_DWORD_LE 4 /* DWORD, little endian */
-#define REG_DWORD_BE 5 /* DWORD, big endian */
-#define REG_LINK 6
-#define REG_MULTI_SZ 7
-#define REG_RESOURCE_LIST 8
-#define REG_FULL_RESOURCE_DESCRIPTOR 9
-#define REG_RESOURCE_REQUIREMENTS_LIST 10
-
-/* structure to contain registry values */
-
-typedef struct {
- fstring valuename;
- uint16 type;
- uint32 size; /* in bytes */
- uint8 *data_p;
-} REGISTRY_VALUE;
-
-/* container for regostry values */
-
-typedef struct {
- TALLOC_CTX *ctx;
- uint32 num_values;
- REGISTRY_VALUE **values;
-} REGVAL_CTR;
-
-/* container for registry subkey names */
-
-typedef struct {
- TALLOC_CTX *ctx;
- uint32 num_subkeys;
- char **subkeys;
-} REGSUBKEY_CTR;
-
-
-/*
- * container for function pointers to enumeration routines
- * for vitural registry view
- */
-
-typedef struct {
- /* functions for enumerating subkeys and values */
- int (*subkey_fn)( char *key, REGSUBKEY_CTR *subkeys);
- int (*value_fn) ( char *key, REGVAL_CTR *val );
- BOOL (*store_subkeys_fn)( char *key, REGSUBKEY_CTR *subkeys );
- BOOL (*store_values_fn)( char *key, REGVAL_CTR *val );
-} REGISTRY_OPS;
-
-typedef struct {
- const char *keyname; /* full path to name of key */
- REGISTRY_OPS *ops; /* registry function hooks */
-} REGISTRY_HOOK;
-
-
-
-/* structure to store the registry handles */
-
-typedef struct _RegistryKey {
-
- struct _RegistryKey *prev, *next;
-
- POLICY_HND hnd;
- pstring name; /* full name of registry key */
- REGISTRY_HOOK *hook;
-
-} REGISTRY_KEY;
-
+#define REG_SZ 1
+#define REG_BINARY 3
+#define REG_DWORD 4
+#define REG_MULTI_SZ 7
/* REG_Q_OPEN_HKCR */
typedef struct q_reg_open_hkcr_info
@@ -169,7 +89,7 @@ typedef struct q_reg_open_hklm_info
uint32 ptr;
uint16 unknown_0; /* 0xE084 - 16 bit unknown */
uint16 unknown_1; /* random. changes */
- uint32 access_mask;
+ uint32 access_mask; /* 0x0000 0002 - 32 bit unknown */
}
REG_Q_OPEN_HKLM;
@@ -188,17 +108,17 @@ REG_R_OPEN_HKLM;
typedef struct q_reg_open_hku_info
{
uint32 ptr;
- uint16 unknown_0;
- uint16 unknown_1;
- uint32 access_mask;
+ uint16 unknown_0; /* 0xE084 - 16 bit unknown */
+ uint16 unknown_1; /* random. changes */
+ uint32 level; /* 0x0000 0002 - 32 bit unknown */
} REG_Q_OPEN_HKU;
/* REG_R_OPEN_HKU */
typedef struct r_reg_open_hku_info
{
- POLICY_HND pol; /* policy handle */
- NTSTATUS status; /* return status */
+ POLICY_HND pol; /* policy handle */
+ NTSTATUS status; /* return status */
} REG_R_OPEN_HKU;
@@ -308,7 +228,6 @@ typedef struct q_reg_query_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
-
} REG_Q_ENUM_VALUE;
/* REG_R_ENUM_VALUE */
@@ -321,7 +240,7 @@ typedef struct r_reg_enum_value_info
uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
uint32 ptr_value; /* pointer */
- BUFFER2 buf_value; /* value, in byte buffer */
+ BUFFER2 *buf_value; /* value, in byte buffer */
uint32 ptr1; /* pointer */
uint32 len_value1; /* */
@@ -423,7 +342,7 @@ typedef struct r_reg_query_key_info
uint32 num_subkeys;
uint32 max_subkeylen;
- uint32 reserved; /* 0x0000 0000 - according to MSDN (max_subkeysize?) */
+ uint32 max_subkeysize; /* 0x0000 0000 */
uint32 num_values;
uint32 max_valnamelen;
uint32 max_valbufsize;
@@ -435,43 +354,20 @@ typedef struct r_reg_query_key_info
} REG_R_QUERY_KEY;
-/* REG_Q_UNKNOWN_1A */
+/* REG_Q_UNK_1A */
typedef struct q_reg_unk_1a_info
{
POLICY_HND pol; /* policy handle */
-} REG_Q_UNKNOWN_1A;
+} REG_Q_UNK_1A;
-/* REG_R_UNKNOWN_1A */
+/* REG_R_UNK_1A */
typedef struct r_reg_unk_1a_info
{
uint32 unknown; /* 0x0500 0000 */
NTSTATUS status; /* return status */
-} REG_R_UNKNOWN_1A;
-
-
-/* REG_Q_UNKNOWN_1A */
-typedef struct q_reg_unknown_14
-{
- POLICY_HND pol; /* policy handle */
-
- UNIHDR hdr_file; /* unicode product type header */
- UNISTR2 uni_file; /* local filename to save key as from regedt32.exe */
- /* e.g. "c:\temp\test.dat" */
-
- uint32 unknown; /* 0x0000 0000 */
-
-} REG_Q_SAVE_KEY;
-
-
-/* REG_R_UNKNOWN_1A */
-typedef struct r_reg_unknown_14
-{
- NTSTATUS status; /* return status */
-
-} REG_R_SAVE_KEY;
-
+} REG_R_UNK_1A;
/* REG_Q_CLOSE */
@@ -567,7 +463,7 @@ typedef struct r_reg_info_info
uint32 type; /* key datatype */
uint32 ptr_uni_val; /* key value pointer */
- BUFFER2 uni_val; /* key value */
+ BUFFER2 *uni_val; /* key value */
uint32 ptr_max_len;
uint32 buf_max_len;
@@ -589,7 +485,7 @@ typedef struct q_reg_open_entry_info
UNISTR2 uni_name; /* unicode registry string name */
uint32 unknown_0; /* 32 bit unknown - 0x0000 0000 */
- uint32 access_desired;
+ uint32 unknown_1; /* 32 bit unknown - 0x0200 0000 */
} REG_Q_OPEN_ENTRY;
@@ -612,8 +508,7 @@ typedef struct q_reg_shutdown_info
UNIHDR hdr_msg; /* shutdown message */
UNISTR2 uni_msg; /* seconds */
uint32 timeout; /* seconds */
- uint8 force; /* boolean: force shutdown */
- uint8 reboot; /* boolean: reboot on shutdown */
+ uint16 flags;
} REG_Q_SHUTDOWN;
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 089941de3aa..7e515ec275b 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -1,12 +1,11 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Paul Ashton 1997-2000
- Copyright (C) Jean François Micouleau 1998-2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
+ Copyright (C) Jean François Micouleau 1998-2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,8 +25,10 @@
#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
#define _RPC_SAMR_H
+
#include "rpc_misc.h"
+
/*******************************************************************
the following information comes from a QuickView on samsrv.dll,
and gives an idea of exactly what is needed:
@@ -79,7 +80,7 @@ SamrTestPrivateFunctionsUser
#define SAMR_CONNECT_ANON 0x00
#define SAMR_CLOSE_HND 0x01
-#define SAMR_SET_SEC_OBJECT 0x02
+#define SAMR_UNKNOWN_2 0x02 /* set sec object? */
#define SAMR_QUERY_SEC_OBJECT 0x03
#define SAMR_UNKNOWN_4 0x04 /* profile info? */
@@ -127,7 +128,7 @@ SamrTestPrivateFunctionsUser
#define SAMR_UNKNOWN_2a 0x2a
#define SAMR_UNKNOWN_2b 0x2b
#define SAMR_GET_USRDOM_PWINFO 0x2c
-#define SAMR_REMOVE_SID_FOREIGN_DOMAIN 0x2d
+#define SAMR_UNKNOWN_2D 0x2d
#define SAMR_UNKNOWN_2E 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */
#define SAMR_UNKNOWN_2f 0x2f
#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO
@@ -144,7 +145,16 @@ SamrTestPrivateFunctionsUser
#define SAMR_GET_DOM_PWINFO 0x38
#define SAMR_CONNECT 0x39
#define SAMR_SET_USERINFO 0x3A
-#define SAMR_CONNECT4 0x3E
+
+
+typedef struct _DISP_USER_INFO {
+ SAM_ACCOUNT *sam;
+} DISP_USER_INFO;
+
+typedef struct _DISP_GROUP_INFO {
+ DOMAIN_GRP *grp;
+} DISP_GROUP_INFO;
+
typedef struct logon_hours_info
{
@@ -183,21 +193,15 @@ typedef struct sam_user_info_23
uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
- uint32 fields_present; /* 0x09f8 27fa */
+ uint32 unknown_3; /* 0x09f8 27fa */
uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
/* uint8 pad[2] */
uint32 ptr_logon_hrs; /* pointer to logon hours */
- /* Was unknown_5. */
- uint16 bad_password_count;
- uint16 logon_count;
-
- uint8 padding1[6];
-
- uint8 passmustchange; /* 0x00 must change = 0x01 */
+ uint8 padding1[8];
- uint8 padding2;
+ uint32 unknown_5; /* 0x0001 0000 */
uint8 pass[516];
@@ -308,22 +312,15 @@ typedef struct sam_user_info_21
uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
- /* Was unknown_3 */
- uint32 fields_present; /* 0x00ff ffff */
+ uint32 unknown_3; /* 0x00ff ffff */
uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
/* uint8 pad[2] */
uint32 ptr_logon_hrs; /* unknown pointer */
- /* Was unknown_5. */
- uint16 bad_password_count;
- uint16 logon_count;
+ uint32 unknown_5; /* 0x0002 0000 */
- uint8 padding1[6];
-
- uint8 passmustchange; /* 0x00 must change = 0x01 */
-
- uint8 padding2;
+ uint8 padding1[8];
UNISTR2 uni_user_name; /* username unicode string */
UNISTR2 uni_full_name; /* user's full name unicode string */
@@ -343,8 +340,6 @@ typedef struct sam_user_info_21
} SAM_USER_INFO_21;
-#define PASS_MUST_CHANGE_AT_NEXT_LOGON 0x01
-#define PASS_DONT_CHANGE_AT_NEXT_LOGON 0x00
/* SAM_USER_INFO_20 */
typedef struct sam_user_info_20
@@ -457,26 +452,6 @@ typedef struct r_samr_usrdom_pwinfo_info
} SAMR_R_GET_USRDOM_PWINFO;
-/****************************************************************************
-SAMR_Q_SET_SEC_OBJ - info level 4.
-*****************************************************************************/
-
-/* SAMR_Q_SET_SEC_OBJ - */
-typedef struct q_samr_set_sec_obj_info
-{
- POLICY_HND pol; /* policy handle */
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION 0x0000 0004 */
- SEC_DESC_BUF *buf;
-
-} SAMR_Q_SET_SEC_OBJ;
-
-/* SAMR_R_SET_SEC_OBJ - */
-typedef struct r_samr_set_sec_obj_info
-{
- NTSTATUS status; /* return status */
-
-} SAMR_R_SET_SEC_OBJ;
-
/****************************************************************************
SAMR_Q_QUERY_SEC_OBJ - info level 4. returns SIDs.
@@ -1076,7 +1051,6 @@ typedef struct samr_group_info3
typedef struct samr_group_info4
{
- uint16 level;
UNIHDR hdr_acct_desc;
UNISTR2 uni_acct_desc;
@@ -1485,7 +1459,7 @@ typedef struct r_samr_create_user_info
{
POLICY_HND user_pol; /* policy handle associated with user */
- uint32 access_granted;
+ uint32 unknown_0; /* 0x0007 03ff */
uint32 user_rid; /* user RID */
NTSTATUS status; /* return status */
@@ -1708,19 +1682,6 @@ typedef struct r_samr_connect_info
} SAMR_R_CONNECT;
-/* SAMR_Q_CONNECT4 */
-typedef struct q_samr_connect4_info
-{
- uint32 ptr_srv_name; /* pointer to server name */
- UNISTR2 uni_srv_name;
-
- uint32 unk_0; /* possible server name type, 1 for IP num, 2 for name */
- uint32 access_mask;
-} SAMR_Q_CONNECT4;
-
-/* SAMR_R_CONNECT4 - same format as connect */
-typedef struct r_samr_connect_info SAMR_R_CONNECT4;
-
/* SAMR_Q_GET_DOM_PWINFO */
typedef struct q_samr_get_dom_pwinfo
{
@@ -1740,8 +1701,9 @@ typedef struct r_samr_get_dom_pwinfo
* turned out to 12. 3 uint32's + NT_STATUS == 16 bytes. Tested
* using NT and 2k. --jerry
*/
- uint16 unk_0;
+ uint32 unk_0;
uint32 unk_1;
+ uint32 unk_2;
NTSTATUS status;
} SAMR_R_GET_DOM_PWINFO;
@@ -1791,21 +1753,21 @@ typedef struct r_samr_chgpasswd_user_info
} SAMR_R_CHGPASSWD_USER;
-/* SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN */
-typedef struct q_samr_remove_sid_foreign_domain_info
+/* SAMR_Q_UNKNOWN_2D */
+typedef struct q_samr_unknown_2d_info
{
POLICY_HND dom_pol; /* policy handle */
DOM_SID2 sid; /* SID */
-} SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN;
+} SAMR_Q_UNKNOWN_2D;
-/* SAMR_R_REMOVE_SID_FOREIGN_DOMAIN */
-typedef struct r_samr_remove_sid_foreign_domain_info
+/* SAMR_R_UNKNOWN_2D - probably an open */
+typedef struct r_samr_unknown_2d_info
{
NTSTATUS status; /* return status */
-} SAMR_R_REMOVE_SID_FOREIGN_DOMAIN;
+} SAMR_R_UNKNOWN_2D;
@@ -1858,4 +1820,6 @@ typedef struct r_samr_set_domain_info
} SAMR_R_SET_DOMAIN_INFO;
+
#endif /* _RPC_SAMR_H */
+
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index 56145ac024c..25daf1ceba5 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
@@ -22,55 +23,30 @@
#ifndef _RPC_SECDES_H /* _RPC_SECDES_H */
#define _RPC_SECDES_H
-#define SEC_RIGHTS_QUERY_VALUE 0x00000001
-#define SEC_RIGHTS_SET_VALUE 0x00000002
-#define SEC_RIGHTS_CREATE_SUBKEY 0x00000004
-#define SEC_RIGHTS_ENUM_SUBKEYS 0x00000008
-#define SEC_RIGHTS_NOTIFY 0x00000010
-#define SEC_RIGHTS_CREATE_LINK 0x00000020
-#define SEC_RIGHTS_READ 0x00020019
-#define SEC_RIGHTS_FULL_CONTROL 0x000f003f
-#define SEC_RIGHTS_MAXIMUM_ALLOWED 0x02000000
-
-/* for ADS */
-#define SEC_RIGHTS_LIST_CONTENTS 0x4
-#define SEC_RIGHTS_LIST_OBJECT 0x80
-#define SEC_RIGHTS_READ_ALL_PROP 0x10
-#define SEC_RIGHTS_READ_PERMS 0x20000
-#define SEC_RIGHTS_WRITE_ALL_VALID 0x8
-#define SEC_RIGHTS_WRITE_ALL_PROP 0x20
-#define SEC_RIGHTS_MODIFY_OWNER 0x80000
-#define SEC_RIGHTS_MODIFY_PERMS 0x40000
-#define SEC_RIGHTS_CREATE_CHILD 0x1
-#define SEC_RIGHTS_DELETE_CHILD 0x2
-#define SEC_RIGHTS_DELETE_SUBTREE 0x40
-#define SEC_RIGHTS_DELETE 0x10000 /* advanced/special/object/delete */
-#define SEC_RIGHTS_EXTENDED 0x100 /* change/reset password, receive/send as*/
-#define SEC_RIGHTS_CHANGE_PASSWD SEC_RIGHTS_EXTENDED
-#define SEC_RIGHTS_RESET_PASSWD SEC_RIGHTS_EXTENDED
-#define SEC_RIGHTS_FULL_CTRL 0xf01ff
-
-#define SEC_ACE_OBJECT_PRESENT 0x00000001 /* thanks for Jim McDonough <jmcd@us.ibm.com> */
-#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002
-
-#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1
-#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2
+#define SEC_RIGHTS_QUERY_VALUE 0x00000001
+#define SEC_RIGHTS_SET_VALUE 0x00000002
+#define SEC_RIGHTS_CREATE_SUBKEY 0x00000004
+#define SEC_RIGHTS_ENUM_SUBKEYS 0x00000008
+#define SEC_RIGHTS_NOTIFY 0x00000010
+#define SEC_RIGHTS_CREATE_LINK 0x00000020
+
+#define SEC_RIGHTS_READ 0x00020019
+#define SEC_RIGHTS_FULL_CONTROL 0x000f003f
+#define SEC_RIGHTS_MAXIMUM_ALLOWED 0x02000000
+
+#define SEC_ACE_TYPE_ACCESS_ALLOWED 0x0
+#define SEC_ACE_TYPE_ACCESS_DENIED 0x1
+#define SEC_ACE_TYPE_SYSTEM_AUDIT 0x2
+#define SEC_ACE_TYPE_SYSTEM_ALARM 0x3
+
+#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1
+#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2
#define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4
-#define SEC_ACE_FLAG_INHERIT_ONLY 0x8
-#define SEC_ACE_FLAG_INHERITED_ACE 0x10 /* New for Windows 2000 */
-#define SEC_ACE_FLAG_VALID_INHERIT 0xf
-#define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40
-#define SEC_ACE_FLAG_FAILED_ACCESS 0x80
-
-#define SEC_ACE_TYPE_ACCESS_ALLOWED 0x0
-#define SEC_ACE_TYPE_ACCESS_DENIED 0x1
-#define SEC_ACE_TYPE_SYSTEM_AUDIT 0x2
-#define SEC_ACE_TYPE_SYSTEM_ALARM 0x3
-#define SEC_ACE_TYPE_ALLOWED_COMPOUND 0x4
-#define SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT 0x5
-#define SEC_ACE_TYPE_ACCESS_DENIED_OBJECT 0x6
-#define SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT 0x7
-#define SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT 0x8
+#define SEC_ACE_FLAG_INHERIT_ONLY 0x8
+#define SEC_ACE_FLAG_INHERITED_ACE 0x10 /* New for Windows 2000 */
+#define SEC_ACE_FLAG_VALID_INHERIT 0xf
+#define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40
+#define SEC_ACE_FLAG_FAILED_ACCESS 0x80
#define SEC_DESC_OWNER_DEFAULTED 0x0001
#define SEC_DESC_GROUP_DEFAULTED 0x0002
@@ -78,48 +54,39 @@
#define SEC_DESC_DACL_DEFAULTED 0x0008
#define SEC_DESC_SACL_PRESENT 0x0010
#define SEC_DESC_SACL_DEFAULTED 0x0020
-#define SEC_DESC_DACL_TRUSTED 0x0040
-#define SEC_DESC_SERVER_SECURITY 0x0080
/*
* New Windows 2000 bits.
*/
-#define SE_DESC_DACL_AUTO_INHERIT_REQ 0x0100
-#define SE_DESC_SACL_AUTO_INHERIT_REQ 0x0200
-#define SE_DESC_DACL_AUTO_INHERITED 0x0400
-#define SE_DESC_SACL_AUTO_INHERITED 0x0800
+#define SE_DESC_DACL_AUTO_INHERIT_REQ 0x0100
+#define SE_DESC_SACL_AUTO_INHERIT_REQ 0x0200
+#define SE_DESC_DACL_AUTO_INHERITED 0x0400
+#define SE_DESC_SACL_AUTO_INHERITED 0x0800
#define SE_DESC_DACL_PROTECTED 0x1000
#define SE_DESC_SACL_PROTECTED 0x2000
-/* Don't know what this means. */
-#define SEC_DESC_RM_CONTROL_VALID 0x4000
-
#define SEC_DESC_SELF_RELATIVE 0x8000
/* security information */
-#define OWNER_SECURITY_INFORMATION 0x00000001
-#define GROUP_SECURITY_INFORMATION 0x00000002
-#define DACL_SECURITY_INFORMATION 0x00000004
-#define SACL_SECURITY_INFORMATION 0x00000008
-/* Extra W2K flags. */
-#define UNPROTECTED_SACL_SECURITY_INFORMATION 0x10000000
-#define UNPROTECTED_DACL_SECURITY_INFORMATION 0x20000000
-#define PROTECTED_SACL_SECURITY_INFORMATION 0x40000000
-#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000
+
+#define OWNER_SECURITY_INFORMATION 0x00000001
+#define GROUP_SECURITY_INFORMATION 0x00000002
+#define DACL_SECURITY_INFORMATION 0x00000004
+#define SACL_SECURITY_INFORMATION 0x00000008
#define ALL_SECURITY_INFORMATION (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|\
- DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION|\
- UNPROTECTED_SACL_SECURITY_INFORMATION|\
- UNPROTECTED_DACL_SECURITY_INFORMATION|\
- PROTECTED_SACL_SECURITY_INFORMATION|\
- PROTECTED_DACL_SECURITY_INFORMATION)
+ DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION)
+#ifndef _SEC_ACCESS
/* SEC_ACCESS */
typedef struct security_info_info
{
uint32 mask;
} SEC_ACCESS;
+#define _SEC_ACCESS
+#endif
+#ifndef _SEC_ACE
/* SEC_ACE */
typedef struct security_ace_info
{
@@ -128,17 +95,11 @@ typedef struct security_ace_info
uint16 size;
SEC_ACCESS info;
-
- /* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
- uint32 obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
- struct uuid obj_guid; /* object GUID */
- struct uuid inh_guid; /* inherited object GUID */
- /* eof object stuff */
-
DOM_SID trustee;
} SEC_ACE;
-#define SEC_ACE_HEADER_SIZE (2 * sizeof(uint8) + sizeof(uint16) + sizeof(uint32))
+#define _SEC_ACE
+#endif
#ifndef ACL_REVISION
#define ACL_REVISION 0x3
@@ -159,7 +120,6 @@ typedef struct security_acl_info
SEC_ACE *ace;
} SEC_ACL;
-#define SEC_ACL_HEADER_SIZE (2 * sizeof(uint16) + sizeof(uint32))
#define _SEC_ACL
#endif
@@ -185,7 +145,6 @@ typedef struct security_descriptor_info
DOM_SID *grp_sid;
} SEC_DESC;
-#define SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32))
#define _SEC_DESC
#endif
@@ -220,250 +179,4 @@ typedef struct standard_mapping {
uint32 std_all;
} STANDARD_MAPPING;
-
-/* Security Access Masks Rights */
-
-#define SPECIFIC_RIGHTS_MASK 0x0000FFFF
-#define STANDARD_RIGHTS_MASK 0x00FF0000
-#define GENERIC_RIGHTS_MASK 0xF0000000
-
-#define SEC_RIGHT_SYSTEM_SECURITY 0x01000000
-#define SEC_RIGHT_MAXIMUM_ALLOWED 0x02000000
-
-/* Generic access rights */
-
-#define GENERIC_RIGHT_ALL_ACCESS 0x10000000
-#define GENERIC_RIGHT_EXECUTE_ACCESS 0x20000000
-#define GENERIC_RIGHT_WRITE_ACCESS 0x40000000
-#define GENERIC_RIGHT_READ_ACCESS 0x80000000
-
-/* Standard access rights. */
-
-#define STD_RIGHT_DELETE_ACCESS 0x00010000
-#define STD_RIGHT_READ_CONTROL_ACCESS 0x00020000
-#define STD_RIGHT_WRITE_DAC_ACCESS 0x00040000
-#define STD_RIGHT_WRITE_OWNER_ACCESS 0x00080000
-#define STD_RIGHT_SYNCHRONIZE_ACCESS 0x00100000
-
-#define STD_RIGHT_ALL_ACCESS 0x001F0000
-
-/* Combinations of standard masks. */
-#define STANDARD_RIGHTS_ALL_ACCESS STD_RIGHT_ALL_ACCESS /* 0x001f0000 */
-#define STANDARD_RIGHTS_EXECUTE_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */
-#define STANDARD_RIGHTS_READ_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */
-#define STANDARD_RIGHTS_WRITE_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */
-#define STANDARD_RIGHTS_REQUIRED_ACCESS \
- (STD_RIGHT_DELETE_ACCESS | \
- STD_RIGHT_READ_CONTROL_ACCESS | \
- STD_RIGHT_WRITE_DAC_ACCESS | \
- STD_RIGHT_WRITE_OWNER_ACCESS) /* 0x000f0000 */
-
-/* File Object specific access rights */
-
-#define SA_RIGHT_FILE_READ_DATA 0x00000001
-#define SA_RIGHT_FILE_WRITE_DATA 0x00000002
-#define SA_RIGHT_FILE_APPEND_DATA 0x00000004
-#define SA_RIGHT_FILE_READ_EA 0x00000008
-#define SA_RIGHT_FILE_WRITE_EA 0x00000010
-#define SA_RIGHT_FILE_EXECUTE 0x00000020
-#define SA_RIGHT_FILE_DELETE_CHILD 0x00000040
-#define SA_RIGHT_FILE_READ_ATTRIBUTES 0x00000080
-#define SA_RIGHT_FILE_WRITE_ATTRIBUTES 0x00000100
-
-#define SA_RIGHT_FILE_ALL_ACCESS 0x000001FF
-
-#define GENERIC_RIGHTS_FILE_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- STD_RIGHT_SYNCHRONIZE_ACCESS | \
- SA_RIGHT_FILE_ALL_ACCESS)
-
-#define GENERIC_RIGHTS_FILE_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- STD_RIGHT_SYNCHRONIZE_ACCESS | \
- SA_RIGHT_FILE_READ_DATA | \
- SA_RIGHT_FILE_READ_ATTRIBUTES | \
- SA_RIGHT_FILE_READ_EA)
-
-#define GENERIC_RIGHTS_FILE_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- STD_RIGHT_SYNCHRONIZE_ACCESS | \
- SA_RIGHT_FILE_WRITE_DATA | \
- SA_RIGHT_FILE_WRITE_ATTRIBUTES | \
- SA_RIGHT_FILE_WRITE_EA | \
- SA_RIGHT_FILE_APPEND_DATA)
-
-#define GENERIC_RIGHTS_FILE_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_FILE_READ_ATTRIBUTES | \
- SA_RIGHT_FILE_EXECUTE)
-
-
-/* SAM server specific access rights */
-
-#define SA_RIGHT_SAM_CONNECT_SERVER 0x00000001
-#define SA_RIGHT_SAM_SHUTDOWN_SERVER 0x00000002
-#define SA_RIGHT_SAM_INITIALISE_SERVER 0x00000004
-#define SA_RIGHT_SAM_CREATE_DOMAIN 0x00000008
-#define SA_RIGHT_SAM_ENUM_DOMAINS 0x00000010
-#define SA_RIGHT_SAM_OPEN_DOMAIN 0x00000020
-
-#define SA_RIGHT_SAM_ALL_ACCESS 0x0000003F
-
-#define GENERIC_RIGHTS_SAM_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- SA_RIGHT_SAM_ALL_ACCESS)
-
-#define GENERIC_RIGHTS_SAM_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_SAM_ENUM_DOMAINS)
-
-#define GENERIC_RIGHTS_SAM_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_SAM_CREATE_DOMAIN | \
- SA_RIGHT_SAM_INITIALISE_SERVER | \
- SA_RIGHT_SAM_SHUTDOWN_SERVER)
-
-#define GENERIC_RIGHTS_SAM_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_SAM_OPEN_DOMAIN | \
- SA_RIGHT_SAM_CONNECT_SERVER)
-
-
-/* Domain Object specific access rights */
-
-#define SA_RIGHT_DOMAIN_LOOKUP_INFO_1 0x00000001
-#define SA_RIGHT_DOMAIN_SET_INFO_1 0x00000002
-#define SA_RIGHT_DOMAIN_LOOKUP_INFO_2 0x00000004
-#define SA_RIGHT_DOMAIN_SET_INFO_2 0x00000008
-#define SA_RIGHT_DOMAIN_CREATE_USER 0x00000010
-#define SA_RIGHT_DOMAIN_CREATE_GROUP 0x00000020
-#define SA_RIGHT_DOMAIN_CREATE_ALIAS 0x00000040
-#define SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM 0x00000080
-#define SA_RIGHT_DOMAIN_ENUM_ACCOUNTS 0x00000100
-#define SA_RIGHT_DOMAIN_OPEN_ACCOUNT 0x00000200
-#define SA_RIGHT_DOMAIN_SET_INFO_3 0x00000400
-
-#define SA_RIGHT_DOMAIN_ALL_ACCESS 0x000007FF
-
-#define GENERIC_RIGHTS_DOMAIN_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- SA_RIGHT_DOMAIN_ALL_ACCESS)
-
-#define GENERIC_RIGHTS_DOMAIN_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM | \
- SA_RIGHT_DOMAIN_LOOKUP_INFO_2)
-
-#define GENERIC_RIGHTS_DOMAIN_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_DOMAIN_SET_INFO_3 | \
- SA_RIGHT_DOMAIN_CREATE_ALIAS | \
- SA_RIGHT_DOMAIN_CREATE_GROUP | \
- SA_RIGHT_DOMAIN_CREATE_USER | \
- SA_RIGHT_DOMAIN_SET_INFO_2 | \
- SA_RIGHT_DOMAIN_SET_INFO_1)
-
-#define GENERIC_RIGHTS_DOMAIN_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_DOMAIN_OPEN_ACCOUNT | \
- SA_RIGHT_DOMAIN_ENUM_ACCOUNTS | \
- SA_RIGHT_DOMAIN_LOOKUP_INFO_1)
-
-
-/* User Object specific access rights */
-
-#define SA_RIGHT_USER_GET_NAME_ETC 0x00000001
-#define SA_RIGHT_USER_GET_LOCALE 0x00000002
-#define SA_RIGHT_USER_SET_LOC_COM 0x00000004
-#define SA_RIGHT_USER_GET_LOGONINFO 0x00000008
-#define SA_RIGHT_USER_ACCT_FLAGS_EXPIRY 0x00000010
-#define SA_RIGHT_USER_SET_ATTRIBUTES 0x00000020
-#define SA_RIGHT_USER_CHANGE_PASSWORD 0x00000040
-#define SA_RIGHT_USER_SET_PASSWORD 0x00000080
-#define SA_RIGHT_USER_GET_GROUPS 0x00000100
-#define SA_RIGHT_USER_READ_GROUP_MEM 0x00000200
-#define SA_RIGHT_USER_CHANGE_GROUP_MEM 0x00000400
-
-#define SA_RIGHT_USER_ALL_ACCESS 0x000007FF
-
-#define GENERIC_RIGHTS_USER_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- SA_RIGHT_USER_ALL_ACCESS) /* 0x000f07ff */
-
-#define GENERIC_RIGHTS_USER_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_USER_READ_GROUP_MEM | \
- SA_RIGHT_USER_GET_GROUPS | \
- SA_RIGHT_USER_ACCT_FLAGS_EXPIRY | \
- SA_RIGHT_USER_GET_LOGONINFO | \
- SA_RIGHT_USER_GET_LOCALE) /* 0x0002031a */
-
-#define GENERIC_RIGHTS_USER_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_USER_CHANGE_PASSWORD | \
- SA_RIGHT_USER_SET_LOC_COM) /* 0x00020044 */
-
-#define GENERIC_RIGHTS_USER_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_USER_CHANGE_PASSWORD | \
- SA_RIGHT_USER_GET_NAME_ETC ) /* 0x00020041 */
-
-
-/* Group Object specific access rights */
-
-#define SA_RIGHT_GROUP_LOOKUP_INFO 0x00000001
-#define SA_RIGHT_GROUP_SET_INFO 0x00000002
-#define SA_RIGHT_GROUP_ADD_MEMBER 0x00000004
-#define SA_RIGHT_GROUP_REMOVE_MEMBER 0x00000008
-#define SA_RIGHT_GROUP_GET_MEMBERS 0x00000010
-
-#define SA_RIGHT_GROUP_ALL_ACCESS 0x0000001F
-
-#define GENERIC_RIGHTS_GROUP_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- SA_RIGHT_GROUP_ALL_ACCESS) /* 0x000f001f */
-
-#define GENERIC_RIGHTS_GROUP_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_GROUP_GET_MEMBERS) /* 0x00020010 */
-
-#define GENERIC_RIGHTS_GROUP_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_GROUP_REMOVE_MEMBER | \
- SA_RIGHT_GROUP_ADD_MEMBER | \
- SA_RIGHT_GROUP_SET_INFO ) /* 0x0002000e */
-
-#define GENERIC_RIGHTS_GROUP_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_GROUP_LOOKUP_INFO) /* 0x00020001 */
-
-
-/* Alias Object specific access rights */
-
-#define SA_RIGHT_ALIAS_ADD_MEMBER 0x00000001
-#define SA_RIGHT_ALIAS_REMOVE_MEMBER 0x00000002
-#define SA_RIGHT_ALIAS_GET_MEMBERS 0x00000004
-#define SA_RIGHT_ALIAS_LOOKUP_INFO 0x00000008
-#define SA_RIGHT_ALIAS_SET_INFO 0x00000010
-
-#define SA_RIGHT_ALIAS_ALL_ACCESS 0x0000001F
-
-#define GENERIC_RIGHTS_ALIAS_ALL_ACCESS \
- (STANDARD_RIGHTS_REQUIRED_ACCESS| \
- SA_RIGHT_ALIAS_ALL_ACCESS) /* 0x000f001f */
-
-#define GENERIC_RIGHTS_ALIAS_READ \
- (STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_ALIAS_GET_MEMBERS ) /* 0x00020004 */
-
-#define GENERIC_RIGHTS_ALIAS_WRITE \
- (STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_ALIAS_REMOVE_MEMBER | \
- SA_RIGHT_ALIAS_ADD_MEMBER | \
- SA_RIGHT_ALIAS_SET_INFO ) /* 0x00020013 */
-
-#define GENERIC_RIGHTS_ALIAS_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE_ACCESS | \
- SA_RIGHT_ALIAS_LOOKUP_INFO ) /* 0x00020008 */
-
#endif /* _RPC_SECDES_H */
diff --git a/source/include/rpc_shutdown.h b/source/include/rpc_shutdown.h
deleted file mode 100644
index b8e50b835f5..00000000000
--- a/source/include/rpc_shutdown.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _RPC_SHUTDOWN_H /* _RPC_SHUTDOWN_H */
-#define _RPC_SHUTDOWN_H
-
-
-/* Implemented */
-#define SHUTDOWN_INIT 0x00
-#define SHUTDOWN_ABORT 0x01
-/* NOT IMPLEMENTED
-#define SHUTDOWN_INIT_EX 0x02
-*/
-
-/* SHUTDOWN_Q_INIT */
-typedef struct q_shutodwn_init_info
-{
- uint32 ptr_server;
- uint16 server;
- uint32 ptr_msg;
- UNIHDR hdr_msg; /* shutdown message */
- UNISTR2 uni_msg; /* seconds */
- uint32 timeout; /* seconds */
- uint8 force; /* boolean: force shutdown */
- uint8 reboot; /* boolean: reboot on shutdown */
-
-} SHUTDOWN_Q_INIT;
-
-/* SHUTDOWN_R_INIT */
-typedef struct r_shutdown_init_info
-{
- NTSTATUS status; /* return status */
-
-} SHUTDOWN_R_INIT;
-
-/* SHUTDOWN_Q_ABORT */
-typedef struct q_shutdown_abort_info
-{
- uint32 ptr_server;
- uint16 server;
-
-} SHUTDOWN_Q_ABORT;
-
-/* SHUTDOWN_R_ABORT */
-typedef struct r_shutdown_abort_info
-{
- NTSTATUS status; /* return status */
-
-} SHUTDOWN_R_ABORT;
-
-
-#endif /* _RPC_SHUTDOWN_H */
-
diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h
index d9fc0c6a6ab..7e29f3f2437 100755
--- a/source/include/rpc_spoolss.h
+++ b/source/include/rpc_spoolss.h
@@ -25,6 +25,9 @@
#ifndef _RPC_SPOOLSS_H /* _RPC_SPOOLSS_H */
#define _RPC_SPOOLSS_H
+#define INTEGER 1
+#define STRING 2
+
/* spoolss pipe: this are the calls which are not implemented ...
#define SPOOLSS_GETPRINTERDRIVER 0x0b
#define SPOOLSS_READPRINTER 0x16
@@ -50,6 +53,9 @@
#define SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION0x3e
#define SPOOLSS_SPOOLERINIT 0x3f
#define SPOOLSS_RESETPRINTEREX 0x40
+#define SPOOLSS_DELETEPRINTERDATAEX 0x51
+#define SPOOLSS_DELETEPRINTERDRIVEREX 0x54
+#define SPOOLSS_ADDPRINTERDRIVEREX 0x59
*/
/* those are implemented */
@@ -105,10 +111,6 @@
#define SPOOLSS_GETPRINTERDATAEX 0x4e
#define SPOOLSS_ENUMPRINTERDATAEX 0x4f
#define SPOOLSS_ENUMPRINTERKEY 0x50
-#define SPOOLSS_DELETEPRINTERDATAEX 0x51
-#define SPOOLSS_DELETEPRINTERKEY 0x52
-#define SPOOLSS_DELETEPRINTERDRIVEREX 0x54
-#define SPOOLSS_ADDPRINTERDRIVEREX 0x59
#define PRINTER_CONTROL_UNPAUSE 0x00000000
@@ -117,7 +119,6 @@
#define PRINTER_CONTROL_PURGE 0x00000003
#define PRINTER_CONTROL_SET_STATUS 0x00000004
-#define PRINTER_STATUS_OK 0x00000000
#define PRINTER_STATUS_PAUSED 0x00000001
#define PRINTER_STATUS_ERROR 0x00000002
#define PRINTER_STATUS_PENDING_DELETION 0x00000004
@@ -158,18 +159,17 @@
/* JOB status codes. */
-#define JOB_STATUS_QUEUED 0x0000
-#define JOB_STATUS_PAUSED 0x0001
-#define JOB_STATUS_ERROR 0x0002
-#define JOB_STATUS_DELETING 0x0004
-#define JOB_STATUS_SPOOLING 0x0008
-#define JOB_STATUS_PRINTING 0x0010
-#define JOB_STATUS_OFFLINE 0x0020
-#define JOB_STATUS_PAPEROUT 0x0040
-#define JOB_STATUS_PRINTED 0x0080
-#define JOB_STATUS_DELETED 0x0100
-#define JOB_STATUS_BLOCKED 0x0200
-#define JOB_STATUS_USER_INTERVENTION 0x0400
+#define JOB_STATUS_PAUSED 0x001
+#define JOB_STATUS_ERROR 0x002
+#define JOB_STATUS_DELETING 0x004
+#define JOB_STATUS_SPOOLING 0x008
+#define JOB_STATUS_PRINTING 0x010
+#define JOB_STATUS_OFFLINE 0x020
+#define JOB_STATUS_PAPEROUT 0x040
+#define JOB_STATUS_PRINTED 0x080
+#define JOB_STATUS_DELETED 0x100
+#define JOB_STATUS_BLOCKED 0x200
+#define JOB_STATUS_USER_INTERVENTION 0x400
/* ACE masks for the various print permissions */
@@ -196,13 +196,9 @@
#define JOB_WRITE STANDARD_RIGHTS_WRITE_ACCESS|JOB_ACCESS_ADMINISTER
#define JOB_EXECUTE STANDARD_RIGHTS_EXECUTE_ACCESS|JOB_ACCESS_ADMINISTER
-/* Notify field types */
-
-#define NOTIFY_ONE_VALUE 1 /* Notify data is stored in value1 */
-#define NOTIFY_TWO_VALUE 2 /* Notify data is stored in value2 */
-#define NOTIFY_POINTER 3 /* Data is a pointer to a buffer */
-#define NOTIFY_STRING 4 /* Data is a pointer to a buffer w/length */
-#define NOTIFY_SECDESC 5 /* Data is a security descriptor */
+#define ONE_VALUE 1
+#define TWO_VALUE 2
+#define POINTER 3
#define PRINTER_NOTIFY_TYPE 0x00
#define JOB_NOTIFY_TYPE 0x01
@@ -371,11 +367,6 @@ PRINTER_MESSAGE_INFO;
#define PRINTER_ATTRIBUTE_ENABLE_BIDI 0x00000800
#define PRINTER_ATTRIBUTE_RAW_ONLY 0x00001000
-#define PRINTER_ATTRIBUTE_PUBLISHED 0x00002000
-
-#define PRINTER_ATTRIBUTE_SAMBA (PRINTER_ATTRIBUTE_RAW_ONLY|\
- PRINTER_ATTRIBUTE_SHARED|\
- PRINTER_ATTRIBUTE_LOCAL)
#define NO_PRIORITY 0
#define MAX_PRIORITY 99
@@ -406,23 +397,8 @@ PRINTER_MESSAGE_INFO;
#define PRINTER_ENUM_ICON7 0x00400000
#define PRINTER_ENUM_ICON8 0x00800000
-/* FLAGS for SPOOLSS_DELETEPRINTERDRIVEREX */
-
-#define DPD_DELETE_UNUSED_FILES 0x00000001
-#define DPD_DELETE_SPECIFIC_VERSION 0x00000002
-#define DPD_DELETE_ALL_FILES 0x00000004
-
#define DRIVER_ANY_VERSION 0xffffffff
#define DRIVER_MAX_VERSION 4
-
-/* FLAGS for SPOOLSS_ADDPRINTERDRIVEREX */
-
-#define APD_STRICT_UPGRADE 0x00000001
-#define APD_STRICT_DOWNGRADE 0x00000002
-#define APD_COPY_ALL_FILES 0x00000004
-#define APD_COPY_NEW_FILES 0x00000008
-
-
/* this struct is undocumented */
/* thanks to the ddk ... */
typedef struct spool_user_1
@@ -706,23 +682,6 @@ typedef struct spool_r_deleteprinterdriver
}
SPOOL_R_DELETEPRINTERDRIVER;
-typedef struct spool_q_deleteprinterdriverex
-{
- uint32 server_ptr;
- UNISTR2 server;
- UNISTR2 arch;
- UNISTR2 driver;
- uint32 delete_flags;
- uint32 version;
-}
-SPOOL_Q_DELETEPRINTERDRIVEREX;
-
-typedef struct spool_r_deleteprinterdriverex
-{
- WERROR status;
-}
-SPOOL_R_DELETEPRINTERDRIVEREX;
-
typedef struct spool_doc_info_1
{
@@ -807,16 +766,15 @@ typedef struct spool_notify_info_data
uint16 field;
uint32 reserved;
uint32 id;
- union {
+ union
+ {
uint32 value[2];
- struct {
+ struct
+ {
uint32 length;
uint16 *string;
- } data;
- struct {
- uint32 size;
- SEC_DESC *desc;
- } sd;
+ }
+ data;
}
notify_data;
uint32 size;
@@ -994,18 +952,6 @@ typedef struct printer_info_5
}
PRINTER_INFO_5;
-#define SPOOL_DS_PUBLISH 1
-#define SPOOL_DS_UPDATE 2
-#define SPOOL_DS_UNPUBLISH 4
-#define SPOOL_DS_PENDING 0x80000000
-
-typedef struct printer_info_7
-{
- UNISTR guid; /* text form of printer guid */
- uint32 action;
-}
-PRINTER_INFO_7;
-
typedef struct spool_q_enumprinters
{
uint32 flags;
@@ -1257,8 +1203,8 @@ typedef struct job_info_ctr_info
{
union
{
- JOB_INFO_1 *job_info_1;
- JOB_INFO_2 *job_info_2;
+ JOB_INFO_1 **job_info_1;
+ JOB_INFO_2 **job_info_2;
void *info;
} job;
@@ -1302,12 +1248,6 @@ typedef struct s_port_info_2
}
PORT_INFO_2;
-/* Port Type bits */
-#define PORT_TYPE_WRITE 0x0001
-#define PORT_TYPE_READ 0x0002
-#define PORT_TYPE_REDIRECTED 0x0004
-#define PORT_TYPE_NET_ATTACHED 0x0008
-
typedef struct spool_q_enumports
{
uint32 name_ptr;
@@ -1503,14 +1443,6 @@ typedef struct spool_printer_info_level_3
}
SPOOL_PRINTER_INFO_LEVEL_3;
-typedef struct spool_printer_info_level_7
-{
- uint32 guid_ptr;
- uint32 action;
- UNISTR2 guid;
-}
-SPOOL_PRINTER_INFO_LEVEL_7;
-
typedef struct spool_printer_info_level
{
uint32 level;
@@ -1518,7 +1450,6 @@ typedef struct spool_printer_info_level
SPOOL_PRINTER_INFO_LEVEL_1 *info_1;
SPOOL_PRINTER_INFO_LEVEL_2 *info_2;
SPOOL_PRINTER_INFO_LEVEL_3 *info_3;
- SPOOL_PRINTER_INFO_LEVEL_7 *info_7;
}
SPOOL_PRINTER_INFO_LEVEL;
@@ -1719,22 +1650,6 @@ typedef struct spool_r_addprinterdriver
}
SPOOL_R_ADDPRINTERDRIVER;
-typedef struct spool_q_addprinterdriverex
-{
- uint32 server_name_ptr;
- UNISTR2 server_name;
- uint32 level;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL info;
- uint32 copy_flags;
-}
-SPOOL_Q_ADDPRINTERDRIVEREX;
-
-typedef struct spool_r_addprinterdriverex
-{
- WERROR status;
-}
-SPOOL_R_ADDPRINTERDRIVEREX;
-
typedef struct driver_directory_1
{
@@ -2123,21 +2038,6 @@ typedef struct spool_r_setprinterdataex
SPOOL_R_SETPRINTERDATAEX;
-typedef struct spool_q_deleteprinterdataex
-{
- POLICY_HND handle;
- UNISTR2 keyname;
- UNISTR2 valuename;
-}
-SPOOL_Q_DELETEPRINTERDATAEX;
-
-typedef struct spool_r_deleteprinterdataex
-{
- WERROR status;
-}
-SPOOL_R_DELETEPRINTERDATAEX;
-
-
typedef struct spool_q_enumprinterkey
{
POLICY_HND handle;
@@ -2154,19 +2054,6 @@ typedef struct spool_r_enumprinterkey
}
SPOOL_R_ENUMPRINTERKEY;
-typedef struct spool_q_deleteprinterkey
-{
- POLICY_HND handle;
- UNISTR2 keyname;
-}
-SPOOL_Q_DELETEPRINTERKEY;
-
-typedef struct spool_r_deleteprinterkey
-{
- WERROR status;
-}
-SPOOL_R_DELETEPRINTERKEY;
-
typedef struct printer_enum_values
{
UNISTR valuename;
diff --git a/source/include/rpc_srvsvc.h b/source/include/rpc_srvsvc.h
index 5ebb77a8c21..8458074619f 100644
--- a/source/include/rpc_srvsvc.h
+++ b/source/include/rpc_srvsvc.h
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
Copyright (C) Paul Ashton 1997
- Copyright (C) Nigel Williams 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,25 +24,24 @@
#ifndef _RPC_SRVSVC_H /* _RPC_SRVSVC_H */
#define _RPC_SRVSVC_H
+
/* srvsvc pipe */
-#define SRV_NET_CONN_ENUM 0x08
-#define SRV_NET_FILE_ENUM 0x09
-#define SRV_NET_FILE_CLOSE 0x0b
-#define SRV_NET_SESS_ENUM 0x0c
-#define SRV_NET_SHARE_ADD 0x0e
-#define SRV_NET_SHARE_ENUM_ALL 0x0f
-#define SRV_NET_SHARE_GET_INFO 0x10
-#define SRV_NET_SHARE_SET_INFO 0x11
-#define SRV_NET_SHARE_DEL 0x12
-#define SRV_NET_SHARE_DEL_STICKY 0x13
-#define SRV_NET_SRV_GET_INFO 0x15
-#define SRV_NET_SRV_SET_INFO 0x16
-#define SRV_NET_DISK_ENUM 0x17
-#define SRV_NET_REMOTE_TOD 0x1c
-#define SRV_NET_NAME_VALIDATE 0x21
-#define SRV_NET_SHARE_ENUM 0x24
-#define SRV_NET_FILE_QUERY_SECDESC 0x27
-#define SRV_NET_FILE_SET_SECDESC 0x28
+#define SRV_NETCONNENUM 0x08
+#define SRV_NETFILEENUM 0x09
+#define SRV_NETSESSENUM 0x0c
+#define SRV_NET_SHARE_ADD 0x0e
+#define SRV_NETSHAREENUM_ALL 0x0f
+#define SRV_NET_SHARE_GET_INFO 0x10
+#define SRV_NET_SHARE_SET_INFO 0x11
+#define SRV_NET_SHARE_DEL 0x12
+#define SRV_NET_SRV_GET_INFO 0x15
+#define SRV_NET_SRV_SET_INFO 0x16
+#define SRV_NET_DISK_ENUM 0x17
+#define SRV_NET_REMOTE_TOD 0x1c
+#define SRV_NET_NAME_VALIDATE 0x21
+#define SRV_NETSHAREENUM 0x24
+#define SRV_NETFILEQUERYSECDESC 0x27
+#define SRV_NETFILESETSECDESC 0x28
#define MAX_SERVER_DISK_ENTRIES 15
@@ -56,7 +55,7 @@ typedef struct disk_enum_container {
uint32 entries_read;
uint32 unknown;
uint32 disk_info_ptr;
- DISK_INFO *disk_info;
+ DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES];
} DISK_ENUM_CONTAINER;
typedef struct net_srv_disk_enum {
@@ -167,9 +166,6 @@ typedef struct q_net_sess_enum_info
uint32 ptr_qual_name; /* pointer (to qualifier name) */
UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
- uint32 ptr_user_name; /* pointer (to user name */
- UNISTR2 uni_user_name; /* user name */
-
uint32 sess_level; /* session level */
SRV_SESS_INFO_CTR *ctr;
@@ -296,29 +292,6 @@ typedef struct r_net_conn_enum_info
} SRV_R_NET_CONN_ENUM;
-/* SH_INFO_0 */
-typedef struct ptr_share_info0
-{
- uint32 ptr_netname; /* pointer to net name. */
-} SH_INFO_0;
-
-/* SH_INFO_0_STR (level 0 share info strings) */
-typedef struct str_share_info0
-{
- SH_INFO_0 *ptrs;
-
- UNISTR2 uni_netname; /* unicode string of net name */
-
-} SH_INFO_0_STR;
-
-/* SRV_SHARE_INFO_0 */
-typedef struct share_info_0_info
-{
- SH_INFO_0 info_0;
- SH_INFO_0_STR info_0_str;
-
-} SRV_SHARE_INFO_0;
-
/* SH_INFO_1 (pointers to level 1 share info strings) */
typedef struct ptr_share_info1
{
@@ -331,8 +304,6 @@ typedef struct ptr_share_info1
/* SH_INFO_1_STR (level 1 share info strings) */
typedef struct str_share_info1
{
- SH_INFO_1 *ptrs;
-
UNISTR2 uni_netname; /* unicode string of net name */
UNISTR2 uni_remark; /* unicode string of comment */
@@ -363,8 +334,6 @@ typedef struct ptr_share_info2
/* SH_INFO_2_STR (level 2 share info strings) */
typedef struct str_share_info2
{
- SH_INFO_2 *ptrs;
-
UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */
UNISTR2 uni_remark; /* unicode string of comment (e.g "Logon server share") */
UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
@@ -412,8 +381,6 @@ typedef struct ptr_share_info502
uint32 num_uses; /* current uses */
uint32 ptr_path; /* pointer to path name */
uint32 ptr_passwd; /* pointer to password */
- uint32 reserved; /* this holds the space taken by the sd in the rpc packet */
- uint32 reserved_offset; /* required for _post operation when marshalling */
uint32 sd_size; /* size of security descriptor */
uint32 ptr_sd; /* pointer to security descriptor */
@@ -429,7 +396,6 @@ typedef struct str_share_info502
UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
UNISTR2 uni_passwd; /* unicode string of password - presumably for share level security (e.g NULL) */
- uint32 reserved;
uint32 sd_size;
SEC_DESC *sd;
@@ -443,63 +409,12 @@ typedef struct share_info_502_info
} SRV_SHARE_INFO_502;
-typedef struct ptr_share_info1004
-{
- uint32 ptr_remark;
-
-} SH_INFO_1004;
-
-typedef struct str_share_info1004
-{
- SH_INFO_1004 *ptrs;
-
- UNISTR2 uni_remark;
-
-} SH_INFO_1004_STR;
-
-typedef struct ptr_info_1004_info
-{
- SH_INFO_1004 info_1004;
- SH_INFO_1004_STR info_1004_str;
-} SRV_SHARE_INFO_1004;
-
-#define SHARE_1005_IN_DFS 0x00000001
-#define SHARE_1005_DFS_ROOT 0x00000002
-/* use the CSC policy mask and shift to match up with the smb.conf parm */
-#define SHARE_1005_CSC_POLICY_MASK 0x00000030
-#define SHARE_1005_CSC_POLICY_SHIFT 4
-
+/* SRV_SHARE_INFO_1005 */
typedef struct share_info_1005_info
{
- uint32 share_info_flags;
+ uint32 misc_flags;
} SRV_SHARE_INFO_1005;
-typedef struct share_info_1006_info
-{
- uint32 max_uses;
-} SRV_SHARE_INFO_1006;
-
-typedef struct ptr_share_info1007
-{
- uint32 flags;
- uint32 ptr_AlternateDirectoryName;
-
-} SH_INFO_1007;
-
-typedef struct str_share_info1007
-{
- SH_INFO_1007 *ptrs;
-
- UNISTR2 uni_AlternateDirectoryName;
-
-} SH_INFO_1007_STR;
-
-typedef struct ptr_info_1007_info
-{
- SH_INFO_1007 info_1007;
- SH_INFO_1007_STR info_1007_str;
-} SRV_SHARE_INFO_1007;
-
/* SRV_SHARE_INFO_1501 */
typedef struct share_info_1501_info
{
@@ -518,16 +433,10 @@ typedef struct srv_share_info_ctr_info
uint32 num_entries2;
union {
- SRV_SHARE_INFO_0 *info0;
- SRV_SHARE_INFO_1 *info1; /* share info level 1 */
- SRV_SHARE_INFO_2 *info2; /* share info level 2 */
- SRV_SHARE_INFO_501 *info501; /* share info level 501 */
- SRV_SHARE_INFO_502 *info502; /* share info level 502 */
- SRV_SHARE_INFO_1004 *info1004;
- SRV_SHARE_INFO_1005 *info1005;
- SRV_SHARE_INFO_1006 *info1006;
- SRV_SHARE_INFO_1007 *info1007;
- SRV_SHARE_INFO_1501 *info1501;
+ SRV_SHARE_INFO_1 *info1; /* share info level 1 */
+ SRV_SHARE_INFO_2 *info2; /* share info level 2 */
+ SRV_SHARE_INFO_501 *info501; /* share info level 501 */
+ SRV_SHARE_INFO_502 *info502; /* share info level 502 */
void *info;
} share;
@@ -573,21 +482,19 @@ typedef struct q_net_share_get_info_info
} SRV_Q_NET_SHARE_GET_INFO;
+/* JRA. NB. We also need level 1004 and 1006 here. */
+
/* SRV_SHARE_INFO */
typedef struct srv_share_info {
uint32 switch_value;
uint32 ptr_share_ctr;
union {
- SRV_SHARE_INFO_0 info0;
SRV_SHARE_INFO_1 info1;
SRV_SHARE_INFO_2 info2;
SRV_SHARE_INFO_501 info501;
SRV_SHARE_INFO_502 info502;
- SRV_SHARE_INFO_1004 info1004;
SRV_SHARE_INFO_1005 info1005;
- SRV_SHARE_INFO_1006 info1006;
- SRV_SHARE_INFO_1007 info1007;
SRV_SHARE_INFO_1501 info1501;
} share;
} SRV_SHARE_INFO;
@@ -611,16 +518,12 @@ typedef struct q_net_share_set_info_info
SRV_SHARE_INFO info;
- uint32 ptr_parm_error;
- uint32 parm_error;
-
} SRV_Q_NET_SHARE_SET_INFO;
/* SRV_R_NET_SHARE_SET_INFO */
typedef struct r_net_share_set_info
{
- uint32 ptr_parm_error;
- uint32 parm_error;
+ uint32 switch_value; /* switch value */
WERROR status; /* return status */
@@ -636,17 +539,12 @@ typedef struct q_net_share_add
SRV_SHARE_INFO info;
- uint32 ptr_err_index; /* pointer to error index */
- uint32 err_index; /* index in info to field in error */
-
} SRV_Q_NET_SHARE_ADD;
/* SRV_R_NET_SHARE_ADD */
typedef struct r_net_share_add
{
-
- uint32 ptr_parm_error;
- uint32 parm_error;
+ uint32 switch_value; /* switch value */
WERROR status; /* return status */
@@ -658,7 +556,6 @@ typedef struct q_net_share_del
uint32 ptr_srv_name;
UNISTR2 uni_srv_name;
UNISTR2 uni_share_name;
- uint32 reserved;
} SRV_Q_NET_SHARE_DEL;
@@ -688,6 +585,10 @@ typedef struct str_file_info3_info
} FILE_INFO_3_STR;
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_FILE_ENTRIES 32
+
/* SRV_FILE_INFO_3 */
typedef struct srv_file_info_3
{
@@ -695,23 +596,22 @@ typedef struct srv_file_info_3
uint32 ptr_file_info; /* Buffer */
uint32 num_entries_read2; /* EntriesRead */
- FILE_INFO_3 info_3; /* file entry details */
- FILE_INFO_3_STR info_3_str; /* file entry strings */
+
+ FILE_INFO_3 info_3 [MAX_FILE_ENTRIES]; /* file entry details */
+ FILE_INFO_3_STR info_3_str[MAX_FILE_ENTRIES]; /* file entry strings */
+
} SRV_FILE_INFO_3;
/* SRV_FILE_INFO_CTR */
typedef struct srv_file_info_3_info
{
uint32 switch_value; /* switch value */
- uint32 ptr_file_info; /* pointer to file info union */
-
- uint32 num_entries;
- uint32 ptr_entries;
- uint32 num_entries2;
+ uint32 ptr_file_ctr; /* pointer to file info union */
union
- {
- SRV_FILE_INFO_3 *info3;
- } file;
+ {
+ SRV_FILE_INFO_3 info3; /* file info with 0 entries */
+
+ } file;
} SRV_FILE_INFO_CTR;
@@ -725,12 +625,9 @@ typedef struct q_net_file_enum_info
uint32 ptr_qual_name; /* pointer (to qualifier name) */
UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
- uint32 ptr_user_name; /* pointer (to user name) */
- UNISTR2 uni_user_name; /* user name */
-
uint32 file_level; /* file level */
- SRV_FILE_INFO_CTR ctr;
+ SRV_FILE_INFO_CTR *ctr;
uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
ENUM_HND enum_hnd;
@@ -743,7 +640,7 @@ typedef struct r_net_file_enum_info
{
uint32 file_level; /* file level */
- SRV_FILE_INFO_CTR ctr;
+ SRV_FILE_INFO_CTR *ctr;
uint32 total_entries; /* total number of files */
ENUM_HND enum_hnd;
@@ -752,21 +649,6 @@ typedef struct r_net_file_enum_info
} SRV_R_NET_FILE_ENUM;
-/* SRV_Q_NET_FILE_CLOSE */
-typedef struct q_net_file_close
-{
- uint32 ptr_srv_name; /* pointer to server name */
- UNISTR2 uni_srv_name; /* server name */
-
- uint32 file_id;
-} SRV_Q_NET_FILE_CLOSE;
-
-/* SRV_R_NET_FILE_CLOSE */
-typedef struct r_net_file_close
-{
- WERROR status; /* return status */
-} SRV_R_NET_FILE_CLOSE;
-
/* SRV_INFO_100 */
typedef struct srv_info_100_info
{
@@ -950,5 +832,4 @@ typedef struct r_net_file_set_secdesc
{
WERROR status;
} SRV_R_NET_FILE_SET_SECDESC;
-
#endif /* _RPC_SRVSVC_H */
diff --git a/source/include/rpc_wkssvc.h b/source/include/rpc_wkssvc.h
index adc37c255b2..57a70b4798e 100644
--- a/source/include/rpc_wkssvc.h
+++ b/source/include/rpc_wkssvc.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
diff --git a/source/include/safe_string.h b/source/include/safe_string.h
index b22c5efcc99..4517d824a58 100644
--- a/source/include/safe_string.h
+++ b/source/include/safe_string.h
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Safe string handling routines.
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,11 +22,6 @@
#ifndef _SAFE_STRING_H
#define _SAFE_STRING_H
-#ifndef _SPLINT_ /* http://www.splint.org */
-
-/* Some macros to ensure people don't use buffer overflow vulnerable string
- functions. */
-
#ifdef bcopy
#undef bcopy
#endif /* bcopy */
@@ -47,72 +42,10 @@
#endif /* sprintf */
#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
-/*
- * strcasecmp/strncasecmp aren't an error, but it means you're not thinking about
- * multibyte. Don't use them. JRA.
- */
-#ifdef strcasecmp
-#undef strcasecmp
-#endif
-#define strcasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
-
-#ifdef strncasecmp
-#undef strncasecmp
-#endif
-#define strncasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
-
-#endif /* !_SPLINT_ */
-
-#ifdef DEVELOPER
-#define SAFE_STRING_FUNCTION_NAME FUNCTION_MACRO
-#define SAFE_STRING_LINE __LINE__
-#else
-#define SAFE_STRING_FUNCTION_NAME ("")
-#define SAFE_STRING_LINE (0)
-#endif
-
-/* We need a number of different prototypes for our
- non-existant fuctions */
-char * __unsafe_string_function_usage_here__(void);
-
-size_t __unsafe_string_function_usage_here_size_t__(void);
-
-size_t __unsafe_string_function_usage_here_char__(void);
-
-#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
-
-/* if the compiler will optimize out function calls, then use this to tell if we are
- have the correct types (this works only where sizeof() returns the size of the buffer, not
- the size of the pointer). */
-
-#define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
-
-#define fstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(fstring)) \
- ? __unsafe_string_function_usage_here_char__() \
- : (((d)[sizeof(fstring)-1]) = '\0'))
-#define pstrterminate(d) (CHECK_STRING_SIZE(d, sizeof(pstring)) \
- ? __unsafe_string_function_usage_here_char__() \
- : (((d)[sizeof(pstring)-1]) = '\0'))
-
-#define wpstrcpy(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcpy_w((d),(s),sizeof(wpstring)))
-#define wpstrcat(d,s) ((sizeof(d) != sizeof(wpstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcat_w((d),(s),sizeof(wpstring)))
-#define wfstrcpy(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcpy_w((d),(s),sizeof(wfstring)))
-#define wfstrcat(d,s) ((sizeof(d) != sizeof(wfstring) && sizeof(d) != sizeof(smb_ucs2_t *)) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcat_w((d),(s),sizeof(wfstring)))
-
-#define push_pstring_base(dest, src, pstring_base) \
- (CHECK_STRING_SIZE(pstring_base, sizeof(pstring)) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE))
-
-#else /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
+#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1)
+#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1)
+#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
+#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
#define fstrterminate(d) (((d)[sizeof(fstring)-1]) = '\0')
#define pstrterminate(d) (((d)[sizeof(pstring)-1]) = '\0')
@@ -122,107 +55,4 @@ size_t __unsafe_string_function_usage_here_char__(void);
#define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
#define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
-#define push_pstring_base(dest, src, pstring_base) \
- push_ascii(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1, STR_TERMINATE)
-
-#endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */
-
-#define safe_strcpy_base(dest, src, base, size) \
- safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
-
-/* String copy functions - macro hell below adds 'type checking' (limited,
- but the best we can do in C) and may tag with function name/number to
- record the last 'clobber region' on that string */
-
-#define pstrcpy(d,s) safe_strcpy((d), (s),sizeof(pstring)-1)
-#define pstrcat(d,s) safe_strcat((d), (s),sizeof(pstring)-1)
-#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
-#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
-#define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1)
-#define unstrcpy(d,s) safe_strcpy((d), (s),sizeof(unstring)-1)
-
-/* the addition of the DEVELOPER checks in safe_strcpy means we must
- * update a lot of code. To make this a little easier here are some
- * functions that provide the lengths with less pain */
-#define pstrcpy_base(dest, src, pstring_base) \
- safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
-
-
-/* Inside the _fn variants of these is a call to clobber_region(), -
- * which might destroy the stack on a buggy function. We help the
- * debugging process by putting the function and line who last caused
- * a clobbering into a static buffer. If the program crashes at
- * address 0xf1f1f1f1 then this function is probably, but not
- * necessarily, to blame. */
-
-/* overmalloc_safe_strcpy: DEPRECATED! Used when you know the
- * destination buffer is longer than maxlength, but you don't know how
- * long. This is not a good situation, because we can't do the normal
- * sanity checks. Don't use in new code! */
-
-#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
-#define safe_strcpy(dest,src,maxlength) safe_strcpy_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
-#define safe_strcat(dest,src,maxlength) safe_strcat_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE,dest,src,maxlength)
-#define push_string(base_ptr, dest, src, dest_len, flags) push_string_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, flags)
-#define pull_string(base_ptr, dest, src, dest_len, src_len, flags) pull_string_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, src_len, flags)
-#define clistr_push(cli, dest, src, dest_len, flags) clistr_push_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, cli, dest, src, dest_len, flags)
-#define clistr_pull(cli, dest, src, dest_len, src_len, flags) clistr_pull_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, cli, dest, src, dest_len, src_len, flags)
-#define srvstr_push(base_ptr, dest, src, dest_len, flags) srvstr_push_fn2(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, base_ptr, dest, src, dest_len, flags)
-
-#define alpha_strcpy(dest,src,other_safe_chars,maxlength) alpha_strcpy_fn(SAFE_STRING_FUNCTION_NAME,SAFE_STRING_LINE,dest,src,other_safe_chars,maxlength)
-#define StrnCpy(dest,src,n) StrnCpy_fn(SAFE_STRING_FUNCTION_NAME,SAFE_STRING_LINE,dest,src,n)
-
-#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
-
-/* if the compiler will optimize out function calls, then use this to tell if we are
- have the correct types (this works only where sizeof() returns the size of the buffer, not
- the size of the pointer). */
-
-#define safe_strcpy_fn2(fn_name, fn_line, d, s, max_len) \
- (CHECK_STRING_SIZE(d, max_len+1) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcpy_fn(fn_name, fn_line, (d), (s), (max_len)))
-
-#define safe_strcat_fn2(fn_name, fn_line, d, s, max_len) \
- (CHECK_STRING_SIZE(d, max_len+1) \
- ? __unsafe_string_function_usage_here__() \
- : safe_strcat_fn(fn_name, fn_line, (d), (s), (max_len)))
-
-#define push_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \
- (CHECK_STRING_SIZE(dest, dest_len) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : push_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags))
-
-#define pull_string_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags) \
- (CHECK_STRING_SIZE(dest, dest_len) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : pull_string_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, src_len, flags))
-
-#define clistr_push_fn2(fn_name, fn_line, cli, dest, src, dest_len, flags) \
- (CHECK_STRING_SIZE(dest, dest_len) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : clistr_push_fn(fn_name, fn_line, cli, dest, src, dest_len, flags))
-
-#define clistr_pull_fn2(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags) \
- (CHECK_STRING_SIZE(dest, dest_len) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : clistr_pull_fn(fn_name, fn_line, cli, dest, src, dest_len, srclen, flags))
-
-#define srvstr_push_fn2(fn_name, fn_line, base_ptr, dest, src, dest_len, flags) \
- (CHECK_STRING_SIZE(dest, dest_len) \
- ? __unsafe_string_function_usage_here_size_t__() \
- : srvstr_push_fn(fn_name, fn_line, base_ptr, dest, src, dest_len, flags))
-
-#else
-
-#define safe_strcpy_fn2 safe_strcpy_fn
-#define safe_strcat_fn2 safe_strcat_fn
-#define push_string_fn2 push_string_fn
-#define pull_string_fn2 pull_string_fn
-#define clistr_push_fn2 clistr_push_fn
-#define clistr_pull_fn2 clistr_pull_fn
-#define srvstr_push_fn2 srvstr_push_fn
-
-#endif
-
#endif
diff --git a/source/include/samba_linux_quota.h b/source/include/samba_linux_quota.h
index 02b3e5169b1..d5ba1199ef1 100644
--- a/source/include/samba_linux_quota.h
+++ b/source/include/samba_linux_quota.h
@@ -1,7 +1,8 @@
#ifndef _SAMBA_LINUX_QUOTA_H_
-#define _SAMBA_LINUX_QUOTA_H_
+
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.x
Copyright (C) Andrew Tridgell 1994-2002
This program is free software; you can redistribute it and/or modify
@@ -32,8 +33,6 @@
by JRA.
*/
-#undef QUOTABLOCK_SIZE
-
#ifndef _QUOTAIO_LINUX_V1
#define _QUOTAIO_LINUX_V1
@@ -86,9 +85,6 @@ struct v1_dqstats {
#ifndef Q_V1_GETQUOTA
#define Q_V1_GETQUOTA 0x300
#endif
-#ifndef Q_V1_SETQUOTA
-#define Q_V1_SETQUOTA 0x400
-#endif
#endif /* _QUOTAIO_LINUX_V1 */
@@ -235,7 +231,7 @@ long quotactl __P((int, const char *, qid_t, caddr_t));
#define V2_DQINFOOFF sizeof(struct v2_disk_dqheader) /* Offset of info header in file */
#define V2_DQBLKSIZE_BITS 10
#define V2_DQBLKSIZE (1 << V2_DQBLKSIZE_BITS) /* Size of block with quota structures */
-#define V2_DQTREEOFF 1 /* Offset of tree in file in blOcks */
+#define V2_DQTREEOFF 1 /* Offset of tree in file in blocks */
#define V2_DQTREEDEPTH 4 /* Depth of quota tree */
#define V2_DQSTRINBLK ((V2_DQBLKSIZE - sizeof(struct v2_disk_dqdbheader)) / sizeof(struct v2_disk_dqblk)) /* Number of entries in one blocks */
#define V2_GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
@@ -323,12 +319,170 @@ struct v2_dqstats {
#ifndef Q_V2_GETQUOTA
#define Q_V2_GETQUOTA 0x0D00
#endif
-#ifndef Q_V2_SETQUOTA
-#define Q_V2_SETQUOTA 0x0E00
-#endif
#endif /* _QUOTAIO_LINUX_V2 */
+#ifndef _QUOTAIO_LINUX_XFS
+#define _QUOTAIO_LINUX_XFS
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <linux/types.h>
+
+#define XQM_CMD(cmd) ( ('X'<<8)+(cmd) )
+#define IS_XQM_CMD(cmd) ( ((int)(cmd)>>8) == 'X' )
+
+/*
+ * Disk quota - quotactl(2) commands for XFS Quota Manager (XQM).
+ */
+#define Q_XQUOTAON XQM_CMD(0x1) /* enable quota accounting/enforcement */
+#define Q_XQUOTAOFF XQM_CMD(0x2) /* disable quota accounting/enforcement */
+#define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits & usage */
+#define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */
+#define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */
+#define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */
+
+/*
+ * fs_disk_quota structure:
+ *
+ * This contains the current quota information regarding a user/proj/group.
+ * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of
+ * 512 bytes.
+ */
+#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
+typedef struct fs_disk_quota {
+ u_int8_t d_version; /* version of this structure */
+ u_int8_t d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
+ u_int16_t d_fieldmask; /* field specifier */
+ u_int32_t d_id; /* user, project, or group ID */
+ u_int64_t d_blk_hardlimit; /* absolute limit on disk blks */
+ u_int64_t d_blk_softlimit; /* preferred limit on disk blks */
+ u_int64_t d_ino_hardlimit; /* maximum # allocated inodes */
+ u_int64_t d_ino_softlimit; /* preferred inode limit */
+ u_int64_t d_bcount; /* # disk blocks owned by the user */
+ u_int64_t d_icount; /* # inodes owned by the user */
+ int32_t d_itimer; /* zero if within inode limits */
+ /* if not, we refuse service */
+ int32_t d_btimer; /* similar to above; for disk blocks */
+ u_int16_t d_iwarns; /* # warnings issued wrt num inodes */
+ u_int16_t d_bwarns; /* # warnings issued wrt disk blocks */
+ int32_t d_padding2; /* padding2 - for future use */
+ u_int64_t d_rtb_hardlimit; /* absolute limit on realtime blks */
+ u_int64_t d_rtb_softlimit; /* preferred limit on RT disk blks */
+ u_int64_t d_rtbcount; /* # realtime blocks owned */
+ int32_t d_rtbtimer; /* similar to above; for RT disk blks */
+ u_int16_t d_rtbwarns; /* # warnings issued wrt RT disk blks */
+ int16_t d_padding3; /* padding3 - for future use */
+ char d_padding4[8]; /* yet more padding */
+} fs_disk_quota_t;
+
+/*
+ * These fields are sent to Q_XSETQLIM to specify fields that need to change.
+ */
+#define FS_DQ_ISOFT (1<<0)
+#define FS_DQ_IHARD (1<<1)
+#define FS_DQ_BSOFT (1<<2)
+#define FS_DQ_BHARD (1<<3)
+#define FS_DQ_RTBSOFT (1<<4)
+#define FS_DQ_RTBHARD (1<<5)
+#define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \
+ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD)
+/*
+ * These timers can only be set in super user's dquot. For others, timers are
+ * automatically started and stopped. Superusers timer values set the limits
+ * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values
+ * defined below are used.
+ * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
+ */
+#define FS_DQ_BTIMER (1<<6)
+#define FS_DQ_ITIMER (1<<7)
+#define FS_DQ_RTBTIMER (1<<8)
+#define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
+
+/*
+ * The following constants define the default amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure). These may be modified by the quotactl(2)
+ * system call with the Q_XSETQLIM command.
+ */
+#define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */
+#define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */
+
+/*
+ * Various flags related to quotactl(2). Only relevant to XFS filesystems.
+ */
+#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
+#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
+#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
+#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
+
+#define XFS_USER_QUOTA (1<<0) /* user quota type */
+#define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */
+#define XFS_GROUP_QUOTA (1<<2) /* group quota type */
+
+/*
+ * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
+ * Provides a centralized way to get meta infomation about the quota subsystem.
+ * eg. space taken up for user and group quotas, number of dquots currently
+ * incore.
+ */
+#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */
+
+/*
+ * Some basic infomation about 'quota files'.
+ */
+typedef struct fs_qfilestat {
+ u_int64_t qfs_ino; /* inode number */
+ u_int64_t qfs_nblks; /* number of BBs 512-byte-blks */
+ u_int32_t qfs_nextents; /* number of extents */
+} fs_qfilestat_t;
+
+typedef struct fs_quota_stat {
+ u_int8_t qs_version; /* version number for future changes */
+ u_int16_t qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
+ u_int8_t qs_pad; /* unused */
+ fs_qfilestat_t qs_uquota; /* user quota storage information */
+ fs_qfilestat_t qs_gquota; /* group quota storage information */
+ u_int32_t qs_incoredqs; /* number of dquots incore */
+ int32_t qs_btimelimit; /* limit for blks timer */
+ int32_t qs_itimelimit; /* limit for inodes timer */
+ int32_t qs_rtbtimelimit; /* limit for rt blks timer */
+ u_int16_t qs_bwarnlimit; /* limit for num warnings */
+ u_int16_t qs_iwarnlimit; /* limit for num warnings */
+} fs_quota_stat_t;
+
+#endif /* _QUOTAIO_LINUX_XFS */
+
#ifndef QUOTABLOCK_SIZE
#define QUOTABLOCK_SIZE 1024
#endif
diff --git a/source/include/samba_xfs_quota.h b/source/include/samba_xfs_quota.h
deleted file mode 100644
index 1db435064a6..00000000000
--- a/source/include/samba_xfs_quota.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef _SAMBA_LINUX_XFS_H_
-#define _SAMBA_LINUX_XFS_H_
-
-#ifndef _QUOTAIO_LINUX_XFS
-#define _QUOTAIO_LINUX_XFS
-
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include <linux/types.h>
-
-#define XQM_CMD(cmd) ( ('X'<<8)+(cmd) )
-#define IS_XQM_CMD(cmd) ( ((int)(cmd)>>8) == 'X' )
-
-/*
- * Disk quota - quotactl(2) commands for XFS Quota Manager (XQM).
- */
-#define Q_XQUOTAON XQM_CMD(0x1) /* enable quota accounting/enforcement */
-#define Q_XQUOTAOFF XQM_CMD(0x2) /* disable quota accounting/enforcement */
-#define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits & usage */
-#define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */
-#define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */
-#define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */
-
-/*
- * fs_disk_quota structure:
- *
- * This contains the current quota information regarding a user/proj/group.
- * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of
- * 512 bytes.
- */
-#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
-typedef struct fs_disk_quota {
- u_int8_t d_version; /* version of this structure */
- u_int8_t d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
- u_int16_t d_fieldmask; /* field specifier */
- u_int32_t d_id; /* user, project, or group ID */
- u_int64_t d_blk_hardlimit; /* absolute limit on disk blks */
- u_int64_t d_blk_softlimit; /* preferred limit on disk blks */
- u_int64_t d_ino_hardlimit; /* maximum # allocated inodes */
- u_int64_t d_ino_softlimit; /* preferred inode limit */
- u_int64_t d_bcount; /* # disk blocks owned by the user */
- u_int64_t d_icount; /* # inodes owned by the user */
- int32_t d_itimer; /* zero if within inode limits */
- /* if not, we refuse service */
- int32_t d_btimer; /* similar to above; for disk blocks */
- u_int16_t d_iwarns; /* # warnings issued wrt num inodes */
- u_int16_t d_bwarns; /* # warnings issued wrt disk blocks */
- int32_t d_padding2; /* padding2 - for future use */
- u_int64_t d_rtb_hardlimit; /* absolute limit on realtime blks */
- u_int64_t d_rtb_softlimit; /* preferred limit on RT disk blks */
- u_int64_t d_rtbcount; /* # realtime blocks owned */
- int32_t d_rtbtimer; /* similar to above; for RT disk blks */
- u_int16_t d_rtbwarns; /* # warnings issued wrt RT disk blks */
- int16_t d_padding3; /* padding3 - for future use */
- char d_padding4[8]; /* yet more padding */
-} fs_disk_quota_t;
-
-/*
- * These fields are sent to Q_XSETQLIM to specify fields that need to change.
- */
-#define FS_DQ_ISOFT (1<<0)
-#define FS_DQ_IHARD (1<<1)
-#define FS_DQ_BSOFT (1<<2)
-#define FS_DQ_BHARD (1<<3)
-#define FS_DQ_RTBSOFT (1<<4)
-#define FS_DQ_RTBHARD (1<<5)
-#define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \
- FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD)
-/*
- * These timers can only be set in super user's dquot. For others, timers are
- * automatically started and stopped. Superusers timer values set the limits
- * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values
- * defined below are used.
- * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
- */
-#define FS_DQ_BTIMER (1<<6)
-#define FS_DQ_ITIMER (1<<7)
-#define FS_DQ_RTBTIMER (1<<8)
-#define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
-
-/*
- * The following constants define the default amount of time given a user
- * before the soft limits are treated as hard limits (usually resulting
- * in an allocation failure). These may be modified by the quotactl(2)
- * system call with the Q_XSETQLIM command.
- */
-#define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */
-#define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */
-
-/*
- * Various flags related to quotactl(2). Only relevant to XFS filesystems.
- */
-#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
-#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
-#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
-#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
-
-#define XFS_USER_QUOTA (1<<0) /* user quota type */
-#define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */
-#define XFS_GROUP_QUOTA (1<<2) /* group quota type */
-
-/*
- * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
- * Provides a centralized way to get meta infomation about the quota subsystem.
- * eg. space taken up for user and group quotas, number of dquots currently
- * incore.
- */
-#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */
-
-/*
- * Some basic infomation about 'quota files'.
- */
-typedef struct fs_qfilestat {
- u_int64_t qfs_ino; /* inode number */
- u_int64_t qfs_nblks; /* number of BBs 512-byte-blks */
- u_int32_t qfs_nextents; /* number of extents */
-} fs_qfilestat_t;
-
-typedef struct fs_quota_stat {
- u_int8_t qs_version; /* version number for future changes */
- u_int16_t qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
- u_int8_t qs_pad; /* unused */
- fs_qfilestat_t qs_uquota; /* user quota storage information */
- fs_qfilestat_t qs_gquota; /* group quota storage information */
- u_int32_t qs_incoredqs; /* number of dquots incore */
- int32_t qs_btimelimit; /* limit for blks timer */
- int32_t qs_itimelimit; /* limit for inodes timer */
- int32_t qs_rtbtimelimit; /* limit for rt blks timer */
- u_int16_t qs_bwarnlimit; /* limit for num warnings */
- u_int16_t qs_iwarnlimit; /* limit for num warnings */
-} fs_quota_stat_t;
-
-#endif /* _QUOTAIO_LINUX_XFS */
-
-#endif /* _SAMBA_LINUX_XFS_H_ */
diff --git a/source/include/secrets.h b/source/include/secrets.h
index 8c393940586..55158885feb 100644
--- a/source/include/secrets.h
+++ b/source/include/secrets.h
@@ -21,85 +21,19 @@
#ifndef _SECRETS_H
#define _SECRETS_H
-/* the first one is for the hashed password (NT4 style) the latter
- for plaintext (ADS)
-*/
#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
-#define SECRETS_MACHINE_PASSWORD "SECRETS/MACHINE_PASSWORD"
-#define SECRETS_MACHINE_LAST_CHANGE_TIME "SECRETS/MACHINE_LAST_CHANGE_TIME"
-#define SECRETS_MACHINE_SEC_CHANNEL_TYPE "SECRETS/MACHINE_SEC_CHANNEL_TYPE"
-#define SECRETS_MACHINE_TRUST_ACCOUNT_NAME "SECRETS/SECRETS_MACHINE_TRUST_ACCOUNT_NAME"
-/* this one is for storing trusted domain account password */
-#define SECRETS_DOMTRUST_ACCT_PASS "SECRETS/$DOMTRUST.ACC"
-
-/* The domain sid and our sid are stored here even though they aren't
- really secret. */
#define SECRETS_DOMAIN_SID "SECRETS/SID"
#define SECRETS_SAM_SID "SAM/SID"
-/* The domain GUID and server GUID (NOT the same) are also not secret */
-#define SECRETS_DOMAIN_GUID "SECRETS/DOMGUID"
-#define SECRETS_SERVER_GUID "SECRETS/GUID"
-
-#define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW"
-
/* Authenticated user info is stored in secrets.tdb under these keys */
#define SECRETS_AUTH_USER "SECRETS/AUTH_USER"
#define SECRETS_AUTH_DOMAIN "SECRETS/AUTH_DOMAIN"
#define SECRETS_AUTH_PASSWORD "SECRETS/AUTH_PASSWORD"
-/* Trust password type flags */
-#define PASS_MACHINE_TRUST_NT 0x0001
-#define PASS_SERVER_TRUST_NT 0x0002
-#define PASS_DOMAIN_TRUST_NT 0x0004
-#define PASS_MACHINE_TRUST_ADS 0x0008
-#define PASS_DOMAIN_TRUST_ADS 0x0010
-
-/* structure for storing machine account password
- (ie. when samba server is member of a domain */
struct machine_acct_pass {
uint8 hash[16];
time_t mod_time;
};
-/*
- * storage structure for trusted domain
- */
-typedef struct trusted_dom_pass {
- size_t uni_name_len;
- smb_ucs2_t uni_name[32]; /* unicode domain name */
- size_t pass_len;
- fstring pass; /* trust relationship's password */
- time_t mod_time;
- DOM_SID domain_sid; /* remote domain's sid */
-} TRUSTED_DOM_PASS;
-
-/*
- * trusted domain entry/entries returned by secrets_get_trusted_domains
- * (used in _lsa_enum_trust_dom call)
- */
-typedef struct trustdom {
- smb_ucs2_t *name;
- DOM_SID sid;
-} TRUSTDOM;
-
-/*
- * Format of an OpenAFS keyfile
- */
-
-#define SECRETS_AFS_MAXKEYS 8
-
-struct afs_key {
- uint32 kvno;
- char key[8];
-};
-
-struct afs_keyfile {
- uint32 nkeys;
- struct afs_key entry[SECRETS_AFS_MAXKEYS];
-};
-
-#define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE"
-
#endif /* _SECRETS_H */
diff --git a/source/include/session.h b/source/include/session.h
deleted file mode 100644
index f613afee09a..00000000000
--- a/source/include/session.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- session handling for recording currently vailid vuids
- Copyright (C) tridge@samba.org 2001
- Copyright (C) Andew Bartlett <abartlet@samba.org> 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* a "session" is claimed when we do a SessionSetupX operation
- and is yielded when the corresponding vuid is destroyed.
-
- sessions are used to populate utmp and PAM session structures
-*/
-
-struct sessionid {
- uid_t uid;
- gid_t gid;
- fstring username;
- fstring hostname;
- fstring netbios_name;
- fstring remote_machine;
- fstring id_str;
- uint32 id_num;
- uint32 pid;
- fstring ip_addr;
-};
-
diff --git a/source/include/pstring.h b/source/include/sids.h
index 92870e4cae5..86aa58b6218 100644..100755
--- a/source/include/pstring.h
+++ b/source/include/sids.h
@@ -1,12 +1,10 @@
/*
- samba -- Unix SMB/CIFS implementation.
- Safe standardized string types
-
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) John H Terpstra 1996-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Paul Ashton 1998-2000
- Copyright (C) Martin Pool 2002
+ Copyright (C) Elrond 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,14 +21,20 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _PSTRING
+#ifndef _SIDS_H
+#define _SIDS_H
+
+extern DOM_SID global_sam_sid;
+extern fstring global_sam_name;
-#define PSTRING_LEN 1024
-#define FSTRING_LEN 256
+extern DOM_SID global_member_sid;
-typedef char pstring[PSTRING_LEN];
-typedef char fstring[FSTRING_LEN];
+extern DOM_SID global_sid_S_1_5_32; /* local well-known domain */
+extern DOM_SID global_sid_S_1_1; /* Global Domain */
+extern DOM_SID global_sid_NULL;
-#define _PSTRING
+extern const DOM_SID *global_sid_everyone;
+extern const DOM_SID *global_sid_system; /* SYSTEM */
+extern const DOM_SID *global_sid_builtin;
-#endif /* ndef _PSTRING */
+#endif /* _SIDS_H */
diff --git a/source/include/smb.h b/source/include/smb.h
index 85893fa26d1..6377be7f145 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1,13 +1,11 @@
/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup, plus a whole lot more.
-
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) John H Terpstra 1996-2002
+ Copyright (C) John H Terpstra 1996-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Paul Ashton 1998-2000
- Copyright (C) Simo Sorce 2001-2002
- Copyright (C) Martin Pool 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,15 +36,11 @@
#define NMB_PORT 137
#define DGRAM_PORT 138
-#define SMB_PORT1 445
-#define SMB_PORT2 139
-#define SMB_PORTS "445 139"
+#define SMB_PORT 139
-#define Undefined (-1)
#define False (0)
#define True (1)
#define Auto (2)
-#define Required (3)
#ifndef _BOOL
typedef int BOOL;
@@ -64,11 +58,11 @@ typedef int BOOL;
/* string manipulation flags - see clistr.c and srvstr.c */
#define STR_TERMINATE 1
-#define STR_UPPER 2
-#define STR_ASCII 4
-#define STR_UNICODE 8
-#define STR_NOALIGN 16
-#define STR_TERMINATE_ASCII 128
+#define STR_CONVERT 2
+#define STR_UPPER 4
+#define STR_ASCII 8
+#define STR_UNICODE 16
+#define STR_NOALIGN 32
/* how long to wait for secondary SMB packets (milli-seconds) */
#define SMB_SECONDARY_WAIT (60*1000)
@@ -80,19 +74,25 @@ typedef int BOOL;
#define READ_TIMEOUT 1
#define READ_EOF 2
#define READ_ERROR 3
-#define WRITE_ERROR 4 /* This error code can go into the client smb_rw_error. */
-#define READ_BAD_SIG 5
-#define DO_NOT_DO_TDIS 6 /* cli_close_connection() check for this when smbfs wants to keep tree connected */
+
+/* This error code can go into the client smb_rw_error. */
+#define WRITE_ERROR 4
#define DIR_STRUCT_SIZE 43
+/* these define all the command types recognised by the server - there
+are lots of gaps so probably there are some rare commands that are not
+implemented */
+
+#define pSETDIR '\377'
+
/* these define the attribute byte as seen by DOS */
-#define aRONLY (1L<<0) /* 0x01 */
-#define aHIDDEN (1L<<1) /* 0x02 */
-#define aSYSTEM (1L<<2) /* 0x04 */
-#define aVOLID (1L<<3) /* 0x08 */
-#define aDIR (1L<<4) /* 0x10 */
-#define aARCH (1L<<5) /* 0x20 */
+#define aRONLY (1L<<0) /* 0x01 */
+#define aHIDDEN (1L<<1) /* 0x02 */
+#define aSYSTEM (1L<<2) /* 0x04 */
+#define aVOLID (1L<<3) /* 0x08 */
+#define aDIR (1L<<4) /* 0x10 */
+#define aARCH (1L<<5) /* 0x20 */
/* deny modes */
#define DENY_DOS 0
@@ -157,10 +157,17 @@ typedef int BOOL;
#include "doserr.h"
-typedef union unid_t {
- uid_t uid;
- gid_t gid;
-} unid_t;
+#ifndef _PSTRING
+
+#define PSTRING_LEN 1024
+#define FSTRING_LEN 256
+
+typedef char pstring[PSTRING_LEN];
+typedef char fstring[FSTRING_LEN];
+
+#define _PSTRING
+
+#endif
/*
* SMB UCS2 (16-bit unicode) internal type.
@@ -172,15 +179,6 @@ typedef uint16 smb_ucs2_t;
typedef smb_ucs2_t wpstring[PSTRING_LEN];
typedef smb_ucs2_t wfstring[FSTRING_LEN];
-#ifdef WORDS_BIGENDIAN
-#define UCS2_SHIFT 8
-#else
-#define UCS2_SHIFT 0
-#endif
-
-/* turn a 7 bit character into a ucs2 character */
-#define UCS2_CHAR(c) ((c) << UCS2_SHIFT)
-
/* pipe string names */
#define PIPE_LANMAN "\\PIPE\\LANMAN"
#define PIPE_SRVSVC "\\PIPE\\srvsvc"
@@ -194,33 +192,54 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PIPE_LSARPC "\\PIPE\\lsarpc"
#define PIPE_SPOOLSS "\\PIPE\\spoolss"
#define PIPE_NETDFS "\\PIPE\\netdfs"
-#define PIPE_ECHO "\\PIPE\\rpcecho"
-#define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
-#define PIPE_EPM "\\PIPE\\epmapper"
-
-#define PIPE_NETLOGON_PLAIN "\\NETLOGON"
-
-#define PI_LSARPC 0
-#define PI_LSARPC_DS 1
-#define PI_SAMR 2
-#define PI_NETLOGON 3
-#define PI_SRVSVC 4
-#define PI_WKSSVC 5
-#define PI_WINREG 6
-#define PI_SPOOLSS 7
-#define PI_NETDFS 8
-#define PI_ECHO 9
-#define PI_SHUTDOWN 10
-#define PI_EPM 11
-#define PI_MAX_PIPES 12
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
typedef struct nttime_info
{
uint32 low;
uint32 high;
+
} NTTIME;
+#ifndef TIME_T_MIN
+#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
+ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
+#endif
+#ifndef TIME_T_MAX
+#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
+#endif
+
+
+/* the following rather strange looking definitions of NTSTATUS and WERROR
+ and there in order to catch common coding errors where different error types
+ are mixed up. This is especially important as we slowly convert Samba
+ from using BOOL for internal functions
+*/
+#if defined(HAVE_IMMEDIATE_STRUCTURES)
+typedef struct {uint32 v;} NTSTATUS;
+#define NT_STATUS(x) ((NTSTATUS) { x })
+#define NT_STATUS_V(x) ((x).v)
+#else
+typedef uint32 NTSTATUS;
+#define NT_STATUS(x) (x)
+#define NT_STATUS_V(x) (x)
+#endif
+
+#if defined(HAVE_IMMEDIATE_STRUCTURES)
+typedef struct {uint32 v;} WERROR;
+#define W_ERROR(x) ((WERROR) { x })
+#define W_ERROR_V(x) ((x).v)
+#else
+typedef uint32 WERROR;
+#define W_ERROR(x) (x)
+#define W_ERROR_V(x) (x)
+#endif
+
+#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0)
+#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000)
+#define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y))
+#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0)
+#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y))
/* Allowable account control bits */
#define ACB_DISABLED 0x0001 /* 1 = User account disabled */
@@ -237,54 +256,52 @@ typedef struct nttime_info
#define MAX_HOURS_LEN 32
-/*
- * window during which we must talk to the PDC to avoid
- * sam sync delays; expressed in seconds (15 minutes is the
- * default period for SAM replication under Windows NT 4.0
- */
-#define SAM_SYNC_WINDOW 900
+struct sam_disp_info
+{
+ uint32 user_rid; /* Primary User ID */
+ char *smb_name; /* username string */
+ char *full_name; /* user's full name string */
+};
-#ifndef MAXSUBAUTHS
-#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
-#endif
+typedef struct
+{
+ uint32 pid;
+ uint16 vuid;
-#define SID_MAX_SIZE ((size_t)(8+(MAXSUBAUTHS*4)))
+}
+vuser_key;
-/* SID Types */
-enum SID_NAME_USE
+
+struct use_info
{
- SID_NAME_USE_NONE = 0,
- SID_NAME_USER = 1, /* user */
- SID_NAME_DOM_GRP, /* domain group */
- SID_NAME_DOMAIN, /* domain sid */
- SID_NAME_ALIAS, /* local group */
- SID_NAME_WKN_GRP, /* well-known group */
- SID_NAME_DELETED, /* deleted account: needed for c2 rating */
- SID_NAME_INVALID, /* invalid account */
- SID_NAME_UNKNOWN, /* unknown sid type */
- SID_NAME_COMPUTER /* sid for a computer */
+ BOOL connected;
+ char *srv_name;
+ vuser_key key;
+ char *user_name;
+ char *domain;
};
-/**
- * @brief Security Identifier
- *
- * @sa http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/accctrl_38yn.asp
- **/
+#ifndef MAXSUBAUTHS
+#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
+#endif
+
+#ifndef _DOM_SID
+/* DOM_SID - security id */
typedef struct sid_info
{
- uint8 sid_rev_num; /**< SID revision number */
- uint8 num_auths; /**< Number of sub-authorities */
- uint8 id_auth[6]; /**< Identifier Authority */
+ uint8 sid_rev_num; /* SID revision number */
+ uint8 num_auths; /* number of sub-authorities */
+ uint8 id_auth[6]; /* Identifier Authority */
/*
- * Pointer to sub-authorities.
- *
- * @note The values in these uint32's are in *native* byteorder, not
- * neccessarily little-endian...... JRA.
+ * Note that the values in these uint32's are in *native* byteorder,
+ * not neccessarily little-endian...... JRA.
*/
- uint32 sub_auths[MAXSUBAUTHS];
+ uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
} DOM_SID;
+#define _DOM_SID
+#endif
/*
* The complete list of SIDS belonging to this user.
@@ -293,16 +310,19 @@ typedef struct sid_info
*
* token->user_sids[0] = primary user SID.
* token->user_sids[1] = primary group SID.
- * token->user_sids[2..num_sids] = supplementary group SIDS.
+ * token->user_sids[2-num_sids] = supplementary group SIDS.
*/
#define PRIMARY_USER_SID_INDEX 0
#define PRIMARY_GROUP_SID_INDEX 1
+#ifndef _NT_USER_TOKEN
typedef struct _nt_user_token {
size_t num_sids;
DOM_SID *user_sids;
} NT_USER_TOKEN;
+#define _NT_USER_TOKEN
+#endif
/*** query a local group, get a list of these: shows who is in that group ***/
@@ -373,31 +393,20 @@ typedef struct write_cache
char *data;
} write_cache;
-typedef struct
-{
- smb_ucs2_t *origname;
- smb_ucs2_t *filename;
- SMB_STRUCT_STAT *statinfo;
-} smb_filename;
-
-#include "fake_file.h"
-
typedef struct files_struct
{
struct files_struct *next, *prev;
int fnum;
struct connection_struct *conn;
int fd;
- uint16 rap_print_jobid;
+ int print_jobid;
SMB_DEV_T dev;
SMB_INO_T inode;
BOOL delete_on_close;
SMB_OFF_T pos;
SMB_BIG_UINT size;
SMB_BIG_UINT initial_allocation_size; /* Faked up initial allocation on disk. */
- SMB_BIG_UINT position_information;
mode_t mode;
- uint16 file_pid;
uint16 vuid;
write_bmpx_struct *wbmpx_ptr;
write_cache *wcp;
@@ -417,15 +426,10 @@ typedef struct files_struct
BOOL is_stat;
BOOL directory_delete_on_close;
char *fsp_name;
- FAKE_FILE_HANDLE *fake_file_handle;
} files_struct;
-#include "ntquotas.h"
-#include "sysquotas.h"
-
/* used to hold an arbitrary blob of data */
-typedef struct data_blob
-{
+typedef struct data_blob {
uint8 *data;
size_t length;
void (*free)(struct data_blob *data_blob);
@@ -438,27 +442,19 @@ typedef struct data_blob
typedef struct
{
- time_t modify_time;
- time_t status_time;
+ time_t modify_time;
+ time_t status_time;
} dir_status_struct;
-struct vuid_cache_entry
-{
- uint16 vuid;
- BOOL read_only;
- BOOL admin_user;
-};
-
-struct vuid_cache
-{
- unsigned int entries;
- struct vuid_cache_entry array[VUID_CACHE_SIZE];
+struct uid_cache {
+ int entries;
+ uid_t list[UID_CACHE_SIZE];
};
typedef struct
{
- char *name;
- BOOL is_wild;
+ char *name;
+ BOOL is_wild;
} name_compare_entry;
/* Include VFS stuff */
@@ -469,24 +465,23 @@ typedef struct
typedef struct connection_struct
{
struct connection_struct *next, *prev;
- TALLOC_CTX *mem_ctx;
unsigned cnum; /* an index passed over the wire */
int service;
BOOL force_user;
- BOOL force_group;
- struct vuid_cache vuid_cache;
+ struct uid_cache uid_cache;
void *dirptr;
BOOL printer;
BOOL ipc;
- BOOL read_only; /* Attributes for the current user of the share. */
- BOOL admin_user; /* Attributes for the current user of the share. */
+ BOOL read_only;
+ BOOL admin_user;
char *dirpath;
char *connectpath;
char *origpath;
- struct vfs_ops vfs; /* Filesystem operations */
- struct vfs_ops vfs_opaque; /* OPAQUE Filesystem operations */
- struct vfs_handle_struct *vfs_handles; /* for the new plugins */
+ struct vfs_ops vfs_ops; /* Filesystem operations */
+ /* Handle on dlopen() call */
+ void *dl_handle;
+ void *vfs_private;
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
@@ -501,16 +496,10 @@ typedef struct connection_struct
int ngroups;
gid_t *groups;
NT_USER_TOKEN *nt_user_token;
- PRIVILEGE_SET *privs;
time_t lastused;
BOOL used;
int num_files_open;
-
- BOOL case_sensitive;
- BOOL case_preserve;
- BOOL short_case_preserve;
-
name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */
name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */
name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */
@@ -526,7 +515,6 @@ struct current_user
int ngroups;
gid_t *groups;
NT_USER_TOKEN *nt_user_token;
- PRIVILEGE_SET *privs;
};
/* Defines for the sent_oplock_break field above. */
@@ -548,8 +536,7 @@ enum {LPQ_QUEUED=0,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING,LPQ_ERROR,LPQ_DELETING,
typedef struct _print_queue_struct
{
- int job; /* normally the UNIX jobid -- see note in
- printing.c:traverse_fn_delete() */
+ int job;
int size;
int page_count;
int status;
@@ -608,37 +595,82 @@ typedef struct {
#define SHAREMODE_FN(fn) \
void (*fn)(share_mode_entry *, char*)
-#define NT_HASH_LEN 16
-#define LM_HASH_LEN 16
-
/*
- * Flags for account policy.
+ * bit flags representing initialized fields in SAM_ACCOUNT
*/
-#define AP_MIN_PASSWORD_LEN 1
-#define AP_PASSWORD_HISTORY 2
-#define AP_USER_MUST_LOGON_TO_CHG_PASS 3
-#define AP_MAX_PASSWORD_AGE 4
-#define AP_MIN_PASSWORD_AGE 5
-#define AP_LOCK_ACCOUNT_DURATION 6
-#define AP_RESET_COUNT_TIME 7
-#define AP_BAD_ATTEMPT_LOCKOUT 8
-#define AP_TIME_TO_LOGOUT 9
+#define FLAG_SAM_UNINIT 0x00000000
+#define FLAG_SAM_UID 0x00000001
+#define FLAG_SAM_GID 0x00000002
+#define FLAG_SAM_SMBHOME 0x00000004
+#define FLAG_SAM_PROFILE 0x00000008
+#define FLAG_SAM_LOGONSCRIPT 0x00000010
+#define FLAG_SAM_DRIVE 0x00000020
+
+#define IS_SAM_UNIX_USER(x) \
+ (((x)->init_flag & SAM_ACCT_UNIX_UID) \
+ && ((x)->init_flag & SAM_ACCT_UNIX_GID))
+
+#define IS_SAM_SET(x, flag) ((x)->init_flag & (flag))
+
+
+typedef struct sam_passwd
+{
+ /* initiailization flags */
+ uint32 init_flag;
+
+ time_t logon_time; /* logon time */
+ time_t logoff_time; /* logoff time */
+ time_t kickoff_time; /* kickoff time */
+ time_t pass_last_set_time; /* password last set time */
+ time_t pass_can_change_time; /* password can change time */
+ time_t pass_must_change_time; /* password must change time */
+
+ pstring username; /* UNIX username string */
+ pstring domain; /* Windows Domain name */
+ pstring nt_username; /* Windows username string */
+ pstring full_name; /* user's full name string */
+ pstring home_dir; /* home directory string */
+ pstring dir_drive; /* home directory drive string */
+ pstring logon_script; /* logon script string */
+ pstring profile_path; /* profile path string */
+ pstring acct_desc ; /* user description string */
+ pstring workstations; /* login from workstations string */
+ pstring unknown_str ; /* don't know what this is, yet. */
+ pstring munged_dial ; /* munged path name and dial-back tel number */
+
+ uid_t uid; /* this is actually the unix uid_t */
+ gid_t gid; /* this is actually the unix gid_t */
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ unsigned char *lm_pw; /* Null if no password */
+ unsigned char *nt_pw; /* Null if no password */
+
+ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+ uint32 unknown_3; /* 0x00ff ffff */
+
+ uint16 logon_divs; /* 168 - number of hours in a week */
+ uint32 hours_len; /* normally 21 bytes */
+ uint8 hours[MAX_HOURS_LEN];
+
+ uint32 unknown_5; /* 0x0002 0000 */
+ uint32 unknown_6; /* 0x0000 04ec */
+
+} SAM_ACCOUNT;
/*
* Flags for local user manipulation.
*/
-#define LOCAL_ADD_USER 0x1
-#define LOCAL_DELETE_USER 0x2
-#define LOCAL_DISABLE_USER 0x4
-#define LOCAL_ENABLE_USER 0x8
-#define LOCAL_TRUST_ACCOUNT 0x10
-#define LOCAL_SET_NO_PASSWORD 0x20
-#define LOCAL_SET_PASSWORD 0x40
-#define LOCAL_SET_LDAP_ADMIN_PW 0x80
-#define LOCAL_INTERDOM_ACCOUNT 0x100
-#define LOCAL_AM_ROOT 0x200 /* Act as root */
+#define LOCAL_ADD_USER 0x01
+#define LOCAL_DELETE_USER 0x02
+#define LOCAL_DISABLE_USER 0x04
+#define LOCAL_ENABLE_USER 0x08
+#define LOCAL_TRUST_ACCOUNT 0x10
+#define LOCAL_SET_NO_PASSWORD 0x20
+#define LOCAL_SET_LDAP_ADMIN_PW 0x40
+#define LOCAL_GET_DOM_SID 0x80
/* key and data in the connections database - used in smbstatus and smbd */
struct connections_key {
@@ -657,7 +689,6 @@ struct connections_data {
char addr[24];
char machine[FSTRING_LEN];
time_t start;
- uint32 bcast_msg_flags;
};
@@ -682,7 +713,7 @@ struct locking_data {
/* the following are used by loadparm for option lists */
typedef enum
{
- P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
+ P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM,P_SEP
} parm_type;
@@ -713,31 +744,28 @@ struct parm_struct
parm_type type;
parm_class class;
void *ptr;
- BOOL (*special)(int snum, const char *, char **);
- const struct enum_list *enum_list;
+ BOOL (*special)(const char *, char **);
+ struct enum_list *enum_list;
unsigned flags;
union {
BOOL bvalue;
int ivalue;
char *svalue;
char cvalue;
- char **lvalue;
} def;
};
struct bitmap {
uint32 *b;
- unsigned int n;
+ int n;
};
-/* The following flags are used in SWAT */
-#define FLAG_BASIC 0x0001 /* Display only in BASIC view */
+#define FLAG_BASIC 0x0001 /* fundamental options */
#define FLAG_SHARE 0x0002 /* file sharing options */
#define FLAG_PRINT 0x0004 /* printing options */
#define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
#define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
-#define FLAG_ADVANCED 0x0020 /* Parameters that will be visible in advanced view */
-#define FLAG_DEVELOPER 0x0040 /* No longer used */
+#define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
#define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
#define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
#define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
@@ -757,8 +785,7 @@ struct bitmap {
#define smb_err 11
#define smb_flg 13
#define smb_flg2 14
-#define smb_pidhigh 16
-#define smb_ss_field 18
+#define smb_reb 13
#define smb_tid 28
#define smb_pid 30
#define smb_uid 32
@@ -866,7 +893,6 @@ struct bitmap {
#define SMBffirst 0x82 /* find first */
#define SMBfunique 0x83 /* find unique */
#define SMBfclose 0x84 /* find close */
-#define SMBkeepalive 0x85 /* keepalive */
#define SMBinvalid 0xFE /* invalid command */
/* Extended 2.0 protocol */
@@ -881,31 +907,25 @@ struct bitmap {
#define SMBnttranss 0xA1 /* NT transact secondary */
#define SMBntcreateX 0xA2 /* NT create and X */
#define SMBntcancel 0xA4 /* NT cancel */
-#define SMBntrename 0xA5 /* NT rename */
-
-/* These are the trans subcommands */
-#define TRANSACT_SETNAMEDPIPEHANDLESTATE 0x01
-#define TRANSACT_DCERPCCMD 0x26
-#define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53
/* These are the TRANS2 sub commands */
-#define TRANSACT2_OPEN 0x00
-#define TRANSACT2_FINDFIRST 0x01
-#define TRANSACT2_FINDNEXT 0x02
-#define TRANSACT2_QFSINFO 0x03
-#define TRANSACT2_SETFSINFO 0x04
-#define TRANSACT2_QPATHINFO 0x05
-#define TRANSACT2_SETPATHINFO 0x06
-#define TRANSACT2_QFILEINFO 0x07
-#define TRANSACT2_SETFILEINFO 0x08
-#define TRANSACT2_FSCTL 0x09
-#define TRANSACT2_IOCTL 0x0A
-#define TRANSACT2_FINDNOTIFYFIRST 0x0B
-#define TRANSACT2_FINDNOTIFYNEXT 0x0C
-#define TRANSACT2_MKDIR 0x0D
-#define TRANSACT2_SESSION_SETUP 0x0E
-#define TRANSACT2_GET_DFS_REFERRAL 0x10
-#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
+#define TRANSACT2_OPEN 0
+#define TRANSACT2_FINDFIRST 1
+#define TRANSACT2_FINDNEXT 2
+#define TRANSACT2_QFSINFO 3
+#define TRANSACT2_SETFSINFO 4
+#define TRANSACT2_QPATHINFO 5
+#define TRANSACT2_SETPATHINFO 6
+#define TRANSACT2_QFILEINFO 7
+#define TRANSACT2_SETFILEINFO 8
+#define TRANSACT2_FSCTL 9
+#define TRANSACT2_IOCTL 0xA
+#define TRANSACT2_FINDNOTIFYFIRST 0xB
+#define TRANSACT2_FINDNOTIFYNEXT 0xC
+#define TRANSACT2_MKDIR 0xD
+#define TRANSACT2_SESSION_SETUP 0xE
+#define TRANSACT2_GET_DFS_REFERRAL 0x10
+#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
/* These are the NT transact sub commands. */
#define NT_TRANSACT_CREATE 1
@@ -914,13 +934,6 @@ struct bitmap {
#define NT_TRANSACT_NOTIFY_CHANGE 4
#define NT_TRANSACT_RENAME 5
#define NT_TRANSACT_QUERY_SECURITY_DESC 6
-#define NT_TRANSACT_GET_USER_QUOTA 7
-#define NT_TRANSACT_SET_USER_QUOTA 8
-
-/* These are the NT transact_get_user_quota sub commands */
-#define TRANSACT_GET_USER_QUOTA_LIST_CONTINUE 0x0000
-#define TRANSACT_GET_USER_QUOTA_LIST_START 0x0100
-#define TRANSACT_GET_USER_QUOTA_FOR_SID 0x0101
/* Relevant IOCTL codes */
#define IOCTL_QUERY_JOB_INFO 0x530060
@@ -1018,38 +1031,42 @@ struct bitmap {
#define PIPE_RAW_MODE 0x4
#define PIPE_START_MESSAGE 0x8
-/* File Specific access rights */
-#define FILE_READ_DATA 0x00000001
-#define FILE_WRITE_DATA 0x00000002
-#define FILE_APPEND_DATA 0x00000004
-#define FILE_READ_EA 0x00000008 /* File and directory */
-#define FILE_WRITE_EA 0x00000010 /* File and directory */
-#define FILE_EXECUTE 0x00000020
-#define FILE_DELETE_CHILD 0x00000040
-#define FILE_READ_ATTRIBUTES 0x00000080
-#define FILE_WRITE_ATTRIBUTES 0x00000100
-
-#define FILE_ALL_ACCESS 0x000001FF
-
-/* Directory specific access rights */
-#define FILE_LIST_DIRECTORY 0x00000001
-#define FILE_ADD_FILE 0x00000002
-#define FILE_ADD_SUBDIRECTORY 0x00000004
-#define FILE_TRAVERSE 0x00000020
-#define FILE_DELETE_CHILD 0x00000040
+/* these are the constants used in the above call. */
+/* DesiredAccess */
+/* File Specific access rights. */
+#define FILE_READ_DATA 0x001
+#define FILE_WRITE_DATA 0x002
+#define FILE_APPEND_DATA 0x004
+#define FILE_READ_EA 0x008
+#define FILE_WRITE_EA 0x010
+#define FILE_EXECUTE 0x020
+#define FILE_DELETE_CHILD 0x040
+#define FILE_READ_ATTRIBUTES 0x080
+#define FILE_WRITE_ATTRIBUTES 0x100
+
+#define FILE_ALL_ACCESS 0x1FF
/* the desired access to use when opening a pipe */
#define DESIRED_ACCESS_PIPE 0x2019f
/* Generic access masks & rights. */
+#define SPECIFIC_RIGHTS_MASK 0x00FFFFL
+#define STANDARD_RIGHTS_MASK 0xFF0000L
#define DELETE_ACCESS (1L<<16) /* 0x00010000 */
#define READ_CONTROL_ACCESS (1L<<17) /* 0x00020000 */
#define WRITE_DAC_ACCESS (1L<<18) /* 0x00040000 */
#define WRITE_OWNER_ACCESS (1L<<19) /* 0x00080000 */
#define SYNCHRONIZE_ACCESS (1L<<20) /* 0x00100000 */
-#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */
-#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */
+/* Combinations of standard masks. */
+#define STANDARD_RIGHTS_ALL_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS) /* 0x001f0000 */
+#define STANDARD_RIGHTS_EXECUTE_ACCESS (READ_CONTROL_ACCESS) /* 0x00020000 */
+#define STANDARD_RIGHTS_READ_ACCESS (READ_CONTROL_ACCESS) /* 0x00200000 */
+#define STANDARD_RIGHTS_REQUIRED_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS) /* 0x000f0000 */
+#define STANDARD_RIGHTS_WRITE_ACCESS (READ_CONTROL_ACCESS) /* 0x00020000 */
+
+#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */
+#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */
#define GENERIC_ALL_ACCESS (1<<28) /* 0x10000000 */
#define GENERIC_EXECUTE_ACCESS (1<<29) /* 0x20000000 */
#define GENERIC_WRITE_ACCESS (1<<30) /* 0x40000000 */
@@ -1095,7 +1112,6 @@ struct bitmap {
#define REQUEST_OPLOCK 2
#define REQUEST_BATCH_OPLOCK 4
#define OPEN_DIRECTORY 8
-#define EXTENDED_RESPONSE_REQUIRED 0x10
/* ShareAccess field. */
#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */
@@ -1161,30 +1177,19 @@ struct bitmap {
/* Flag for NT transact rename call. */
#define RENAME_REPLACE_IF_EXISTS 1
-/* flags for SMBntrename call (from Samba4) */
-#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102 /* ???? */
-#define RENAME_FLAG_HARD_LINK 0x103
-#define RENAME_FLAG_RENAME 0x104
-#define RENAME_FLAG_COPY 0x105
-
/* Filesystem Attributes. */
-#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
-#define FILE_CASE_PRESERVED_NAMES 0x00000002
-#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_CASE_SENSITIVE_SEARCH 0x01
+#define FILE_CASE_PRESERVED_NAMES 0x02
+#define FILE_UNICODE_ON_DISK 0x04
/* According to cifs9f, this is 4, not 8 */
/* Acconding to testing, this actually sets the security attribute! */
-#define FILE_PERSISTENT_ACLS 0x00000008
-#define FILE_FILE_COMPRESSION 0x00000010
-#define FILE_VOLUME_QUOTAS 0x00000020
-#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
-#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
-#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
-#define FS_LFN_APIS 0x00004000
-#define FILE_VOLUME_IS_COMPRESSED 0x00008000
-#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
-#define FILE_SUPPORTS_ENCRYPTION 0x00020000
-#define FILE_NAMED_STREAMS 0x00040000
-#define FILE_READ_ONLY_VOLUME 0x00080000
+#define FILE_PERSISTENT_ACLS 0x08
+/* These entries added from cifs9f --tsb */
+#define FILE_FILE_COMPRESSION 0x10
+#define FILE_VOLUME_QUOTAS 0x20
+/* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */
+#define FILE_VOLUME_SPARSE_FILE 0x40
+#define FILE_VOLUME_IS_COMPRESSED 0x8000
/* ChangeNotify flags. */
#define FILE_NOTIFY_CHANGE_FILE 0x001
@@ -1208,6 +1213,26 @@ struct bitmap {
#define SMB_SUCCESS 0 /* The request was successful. */
+#ifdef HAVE_STDARG_H
+int slprintf(char *str, int n, char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (__printf__, 3, 4)))
+#endif
+;
+#else
+int slprintf();
+#endif
+
+#ifdef HAVE_STDARG_H
+int fdprintf(int fd, char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (__printf__, 2, 3)))
+#endif
+;
+#else
+int fdprintf();
+#endif
+
#ifdef WITH_DFS
void dfs_unlogin(void);
extern int dcelogin_atmost_once;
@@ -1259,7 +1284,7 @@ char *strdup(char *s);
* History:
* Version 4.0 - never made public
* Version 4.10 - New to 1.9.16p2, lost in space 1.9.16p3 to 1.9.16p9
- * - Reappeared in 1.9.16p11 with fixed smbd services
+ * - Reappeared in 1.9.16p11 with fixed smbd services
* Version 4.20 - To indicate that nmbd and browsing now works better
* Version 4.50 - Set at release of samba-2.2.0 by JHT
*
@@ -1267,7 +1292,7 @@ char *strdup(char *s);
* Setting this above 4.9 can have undesired side-effects.
* This may change again in Samba-3.0 after further testing. JHT
*/
-
+
#define DEFAULT_MAJOR_VERSION 0x04
#define DEFAULT_MINOR_VERSION 0x09
@@ -1276,24 +1301,22 @@ char *strdup(char *s);
#define BROWSER_CONSTANT 0xaa55
/* Sercurity mode bits. */
-#define NEGOTIATE_SECURITY_USER_LEVEL 0x01
-#define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE 0x02
-#define NEGOTIATE_SECURITY_SIGNATURES_ENABLED 0x04
-#define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08
+#define NEGOTIATE_SECURITY_USER_LEVEL 0x01
+#define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE 0x02
+#define NEGOTIATE_SECURITY_SIGNATURES_ENABLED 0x04
+#define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08
/* NT Flags2 bits - cifs6.txt section 3.1.2 */
-#define FLAGS2_LONG_PATH_COMPONENTS 0x0001
-#define FLAGS2_EXTENDED_ATTRIBUTES 0x0002
-#define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004
-#define FLAGS2_IS_LONG_NAME 0x0040
-#define FLAGS2_EXTENDED_SECURITY 0x0800
-#define FLAGS2_DFS_PATHNAMES 0x1000
-#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
-#define FLAGS2_32_BIT_ERROR_CODES 0x4000
-#define FLAGS2_UNICODE_STRINGS 0x8000
-
-#define FLAGS2_WIN2K_SIGNATURE 0xC852 /* Hack alert ! For now... JRA. */
+#define FLAGS2_LONG_PATH_COMPONENTS 0x0001
+#define FLAGS2_EXTENDED_ATTRIBUTES 0x0002
+#define FLAGS2_IS_LONG_NAME 0x0040
+#define FLAGS2_DFS_PATHNAMES 0x1000
+#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
+#define FLAGS2_32_BIT_ERROR_CODES 0x4000
+#define FLAGS2_UNICODE_STRINGS 0x8000
+
+#define FLAGS2_WIN2K_SIGNATURE 0xC852 /* Hack alert ! For now... JRA. */
/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
@@ -1319,7 +1342,7 @@ char *strdup(char *s);
enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
/* security levels */
-enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN,SEC_ADS};
+enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN};
/* server roles */
enum server_types
@@ -1345,15 +1368,17 @@ enum schema_types {SCHEMA_COMPAT, SCHEMA_AD, SCHEMA_SAMBA};
/* LDAP SSL options */
enum ldap_ssl_types {LDAP_SSL_ON, LDAP_SSL_OFF, LDAP_SSL_START_TLS};
-/* LDAP PASSWD SYNC methods */
-enum ldap_passwd_sync_types {LDAP_PASSWD_SYNC_ON, LDAP_PASSWD_SYNC_OFF, LDAP_PASSWD_SYNC_ONLY};
-
/* Remote architectures we know about. */
enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_WINXP, RA_WIN2K3, RA_SAMBA};
/* case handling */
enum case_handling {CASE_LOWER,CASE_UPPER};
+#ifdef WITH_SSL
+/* SSL version options */
+enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
+#endif /* WITH_SSL */
+
/*
* Global value meaing that the smb_uid field should be
* ingored (in share level security and protocol level == CORE)
@@ -1362,6 +1387,30 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
#define UID_FIELD_INVALID 0
#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */
+/* Defines needed for multi-codepage support. */
+#define MSDOS_LATIN_1_CODEPAGE 850
+#define KANJI_CODEPAGE 932
+#define HANGUL_CODEPAGE 949
+#define BIG5_CODEPAGE 950
+#define SIMPLIFIED_CHINESE_CODEPAGE 936
+
+#ifdef KANJI
+/*
+ * Default client code page - Japanese
+ */
+#define DEFAULT_CLIENT_CODE_PAGE KANJI_CODEPAGE
+#else /* KANJI */
+/*
+ * Default client code page - 850 - Western European
+ */
+#define DEFAULT_CLIENT_CODE_PAGE MSDOS_LATIN_1_CODEPAGE
+#endif /* KANJI */
+
+/* Global val set if multibyte codepage. */
+extern int global_is_multibyte_codepage;
+
+#define get_character_len(x) (global_is_multibyte_codepage ? skip_multibyte_char((x)) : 0)
+
/*
* Size of buffer to use when moving files across filesystems.
*/
@@ -1514,36 +1563,66 @@ struct cnotify_fns {
#include "smb_macros.h"
-#define MAX_NETBIOSNAME_LEN 16
-/* DOS character, NetBIOS namestring. Type used on the wire. */
-typedef char nstring[MAX_NETBIOSNAME_LEN];
-/* Unix character, NetBIOS namestring. Type used to manipulate name in nmbd. */
-typedef char unstring[MAX_NETBIOSNAME_LEN*4];
-
/* A netbios name structure. */
struct nmb_name {
- nstring name;
- char scope[64];
- unsigned int name_type;
+ char name[17];
+ char scope[64];
+ unsigned int name_type;
};
/* A netbios node status array element. */
struct node_status {
- nstring name;
+ char name[16];
unsigned char type;
unsigned char flags;
};
+
+
+#define AGENT_CMD_CON 0
+#define AGENT_CMD_CON_ANON 2
+#define AGENT_CMD_CON_REUSE 1
+
struct pwd_info
{
BOOL null_pwd;
BOOL cleartext;
+ BOOL crypted;
fstring password;
+ uchar smb_lm_pwd[16];
+ uchar smb_nt_pwd[16];
+
+ uchar smb_lm_owf[24];
+ uchar smb_nt_owf[128];
+ uint32 nt_owf_len;
+
+ uchar lm_cli_chal[8];
+ uchar nt_cli_chal[128];
+ uint32 nt_cli_chal_len;
+
+ uchar sess_key[16];
};
+/*
+ * Network Computing Architechture Context Name Named Pipe
+ * See MSDN docs for more information
+ */
+struct ncacn_np
+{
+ fstring pipe_name;
+ struct cli_state *smb;
+ uint16 fnum;
+ BOOL initialised;
+};
+
+#include "rpc_creds.h"
+#include "rpc_misc.h"
+#include "rpc_secdes.h"
+#include "nt_printing.h"
+
typedef struct user_struct
{
struct user_struct *next, *prev;
@@ -1552,10 +1631,6 @@ typedef struct user_struct
gid_t gid; /* gid of a validated user */
userdom_struct user;
- char *homedir;
- char *unix_homedir;
- char *logon_script;
-
BOOL guest;
/* following groups stuff added by ih */
@@ -1564,19 +1639,10 @@ typedef struct user_struct
gid_t *groups;
NT_USER_TOKEN *nt_user_token;
- PRIVILEGE_SET *privs;
-
- DATA_BLOB session_key;
-
- char *session_keystr; /* used by utmp and pam session code.
- TDB key string */
- int homes_snum;
-
- struct auth_serversupplied_info *server_info;
+ int session_id; /* used by utmp and pam session code */
} user_struct;
-
struct unix_error_map {
int unix_error;
int dos_class;
@@ -1584,16 +1650,12 @@ struct unix_error_map {
NTSTATUS nt_error;
};
-/*
#include "ntdomain.h"
#include "client.h"
-*/
/*
- * Size of new password account encoding string. This is enough space to
- * hold 11 ACB characters, plus the surrounding [] and a terminating null.
- * Do not change unless you are adding new ACB bits!
+ * Size of new password account encoding string. DO NOT CHANGE.
*/
#define NEW_PW_FORMAT_SPACE_PADDED_LEN 14
@@ -1625,61 +1687,6 @@ struct unix_error_map {
#define SAFE_NETBIOS_CHARS ". -_"
-/* generic iconv conversion structure */
-typedef struct {
- size_t (*direct)(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*pull)(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- void *cd_direct, *cd_pull, *cd_push;
- char *from_name, *to_name;
-} *smb_iconv_t;
-
-/* The maximum length of a trust account password.
- Used when we randomly create it, 15 char passwords
- exceed NT4's max password length */
-
-#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
-
-#include "popt_common.h"
-
-#define PORT_NONE 0
-#ifndef LDAP_PORT
-#define LDAP_PORT 389
-#endif
-
-/* used by the IP comparison function */
-struct ip_service {
- struct in_addr ip;
- unsigned port;
-};
-
-/* Used by the SMB signing functions. */
-
-typedef struct smb_sign_info {
- void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si);
- BOOL (*check_incoming_message)(char *inbuf, struct smb_sign_info *si, BOOL expected_ok);
- void (*free_signing_context)(struct smb_sign_info *si);
- void *signing_context;
-
- BOOL negotiated_smb_signing;
- BOOL allow_smb_signing;
- BOOL doing_signing;
- BOOL mandatory_signing;
- BOOL seen_valid; /* Have I ever seen a validly signed packet? */
-} smb_sign_info;
-
-struct ea_struct {
- uint8 flags;
- char *name;
- DATA_BLOB value;
-};
-
-/* EA names used internally in Samba. KEEP UP TO DATE with prohibited_ea_names in trans2.c !. */
-#define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
-/* EA to use for DOS attributes */
-#define SAMBA_XATTR_DOS_ATTRIB "user.DOSATTRIB"
+#include "nsswitch/winbindd_nss.h"
#endif /* _SMB_H */
diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h
index 2bde6caeda1..53adf39dbc5 100644
--- a/source/include/smb_acls.h
+++ b/source/include/smb_acls.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.x
Portable SMB ACL interface
Copyright (C) Jeremy Allison 2000
@@ -20,6 +21,9 @@
#ifndef _SMB_ACLS_H
#define _SMB_ACLS_H
+
+#include "includes.h"
+
#if defined(HAVE_POSIX_ACLS)
/* This is an identity mapping (just remove the SMB_). */
@@ -195,7 +199,7 @@ typedef struct SMB_ACL_T {
/* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
-#include <acl.h>
+#include "/usr/include/acl.h"
typedef uint *SMB_ACL_PERMSET_T;
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index bcbaa64f863..5c51f9f6db5 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) John H Terpstra 1996-1999
@@ -26,7 +27,6 @@
/* Misc bit macros */
#define BOOLSTR(b) ((b) ? "Yes" : "No")
-#define BITSETB(ptr,bit) ((((char *)ptr)[0] & (1<<(bit)))!=0)
#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
/* for readability... */
@@ -36,15 +36,9 @@
#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
-#ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */
-
-/**
- * Free memory if the pointer and zero the pointer.
- *
- * @note You are explicitly allowed to pass NULL pointers -- they will
- * always be ignored.
- **/
-#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
#endif
/* zero a structure */
@@ -77,12 +71,6 @@
#define OPEN_CONN(conn) ((conn) && (conn)->open)
#define IS_IPC(conn) ((conn) && (conn)->ipc)
#define IS_PRINT(conn) ((conn) && (conn)->printer)
-#define FSP_BELONGS_CONN(fsp,conn) do {\
- extern struct current_user current_user;\
- if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
- return(ERROR_DOS(ERRDOS,ERRbadfid));\
- } while(0)
-
#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
#define CHECK_FSP(fsp,conn) do {\
@@ -104,14 +92,13 @@
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
-/* the service number for the [globals] defaults */
-#define GLOBAL_SECTION_SNUM (-1)
/* translates a connection number into a service number */
-#define SNUM(conn) ((conn)?(conn)->service:GLOBAL_SECTION_SNUM)
-
+#define SNUM(conn) ((conn)?(conn)->service:-1)
/* access various service details */
#define SERVICE(snum) (lp_servicename(snum))
+#define PRINTCAP (lp_printcapname())
+#define PRINTCOMMAND(snum) (lp_printcommand(snum))
#define PRINTERNAME(snum) (lp_printername(snum))
#define CAN_WRITE(conn) (!conn->read_only)
#define VALID_SNUM(snum) (lp_snum_ok(snum))
@@ -122,9 +109,9 @@
#define MAP_HIDDEN(conn) ((conn) && lp_map_hidden((conn)->service))
#define MAP_SYSTEM(conn) ((conn) && lp_map_system((conn)->service))
#define MAP_ARCHIVE(conn) ((conn) && lp_map_archive((conn)->service))
-#define IS_HIDDEN_PATH(conn,path) ((conn) && is_in_path((path),(conn)->hide_list,(conn)->case_sensitive))
-#define IS_VETO_PATH(conn,path) ((conn) && is_in_path((path),(conn)->veto_list,(conn)->case_sensitive))
-#define IS_VETO_OPLOCK_PATH(conn,path) ((conn) && is_in_path((path),(conn)->veto_oplock_list,(conn)->case_sensitive))
+#define IS_HIDDEN_PATH(conn,path) ((conn) && is_in_path((path),(conn)->hide_list))
+#define IS_VETO_PATH(conn,path) ((conn) && is_in_path((path),(conn)->veto_list))
+#define IS_VETO_OPLOCK_PATH(conn,path) ((conn) && is_in_path((path),(conn)->veto_oplock_list))
/*
* Used by the stat cache code to check if a returned
@@ -134,6 +121,8 @@
#define VALID_STAT(st) ((st).st_nlink != 0)
#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
+#define SMBENCRYPT() (lp_encrypted_passwords())
+
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
@@ -171,10 +160,9 @@
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
-#define ERROR_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,False,__LINE__,__FILE__)
-#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,True,__LINE__,__FILE__)
-#define ERROR_NT(status) error_packet(outbuf,status,0,0,False,__LINE__,__FILE__)
-#define ERROR_BOTH(status,class,code) error_packet(outbuf,status,class,code,False,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,status,0,0,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,__LINE__,__FILE__)
+#define ERROR_BOTH(nterr,class,x) error_packet(outbuf,nterr,class,x,__LINE__,__FILE__)
/* this is how errors are generated */
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
@@ -185,9 +173,6 @@
#define smb_buf(buf) (((char *)(buf)) + smb_size + CVAL(buf,smb_wct)*2)
#define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2))
-/* the remaining number of bytes in smb buffer 'buf' from pointer 'p'. */
-#define smb_bufrem(buf, p) (smb_buflen(buf)-PTR_DIFF(p, smb_buf(buf)))
-
/* Note that chain_size must be available as an extern int to this macro. */
#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
@@ -209,7 +194,6 @@ true if two IP addresses are equal
****************************************************************************/
#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
-#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
/*****************************************************************
splits out the last subkey of a key
@@ -236,6 +220,7 @@ copy an IP address from one buffer to another
#define putip(dest,src) memcpy(dest,src,4)
+
/*******************************************************************
Return True if a server has CIFS UNIX capabilities.
********************************************************************/
@@ -246,9 +231,7 @@ copy an IP address from one buffer to another
Make a filename into unix format.
****************************************************************************/
-#define IS_DIRECTORY_SEP(c) ((c) == '\\' || (c) == '/')
#define unix_format(fname) string_replace(fname,'\\','/')
-#define unix_format_w(fname) string_replace_w(fname, UCS2_CHAR('\\'), UCS2_CHAR('/'))
/****************************************************************************
Make a file into DOS format.
@@ -256,10 +239,52 @@ copy an IP address from one buffer to another
#define dos_format(fname) string_replace(fname,'/','\\')
-/*****************************************************************************
- Check to see if we are a DO for this domain
-*****************************************************************************/
+/*******************************************************************
+ vfs stat wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_stat(conn, fname, st) ((conn)->vfs_ops.stat((conn), dos_to_unix_static((fname)),(st)))
+
+/*******************************************************************
+ vfs lstat wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_lstat(conn, fname, st) ((conn)->vfs_ops.lstat((conn), dos_to_unix_static((fname)),(st)))
+
+/*******************************************************************
+ vfs fstat wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_fstat(fsp, fd, st) ((fsp)->conn->vfs_ops.fstat((fsp),(fd),(st)))
+
+/*******************************************************************
+ vfs rmdir wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_rmdir(conn,fname) ((conn)->vfs_ops.rmdir((conn),dos_to_unix_static((fname))))
+
+/*******************************************************************
+ vfs Unlink wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_unlink(conn, fname) ((conn)->vfs_ops.unlink((conn),dos_to_unix_static((fname))))
+
+/*******************************************************************
+ vfs chmod wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_chmod(conn,fname,mode) ((conn)->vfs_ops.chmod((conn),dos_to_unix_static((fname)),(mode)))
+
+/*******************************************************************
+ vfs chown wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_chown(conn,fname,uid,gid) ((conn)->vfs_ops.chown((conn),dos_to_unix_static((fname)),(uid),(gid)))
+
+/*******************************************************************
+ A wrapper for vfs_chdir().
+********************************************************************/
-#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC)
+#define vfs_chdir(conn,fname) ((conn)->vfs_ops.chdir((conn),dos_to_unix_static((fname))))
#endif /* _SMB_MACROS_H */
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
deleted file mode 100644
index f41d4865754..00000000000
--- a/source/include/smbldap.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- Unix SMB/CIFS mplementation.
- LDAP protocol helper functions for SAMBA
- Copyright (C) Gerald Carter 2001-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef _SMBLDAP_H
-#define _SMBLDAP_H
-
-#ifdef HAVE_LDAP
-
-/* specify schema versions between 2.2. and 3.0 */
-
-#define SCHEMAVER_SAMBAACCOUNT 1
-#define SCHEMAVER_SAMBASAMACCOUNT 2
-
-/* objectclass names */
-
-#define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount"
-#define LDAP_OBJ_SAMBAACCOUNT "sambaAccount"
-#define LDAP_OBJ_GROUPMAP "sambaGroupMapping"
-#define LDAP_OBJ_DOMINFO "sambaDomain"
-#define LDAP_OBJ_IDPOOL "sambaUnixIdPool"
-#define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry"
-#define LDAP_OBJ_SID_ENTRY "sambaSidEntry"
-#define LDAP_OBJ_PRIVILEGE "sambaPrivilege"
-#define LDAP_OBJ_TRUST_PASSWORD "sambaTrustPassword"
-
-#define LDAP_OBJ_ACCOUNT "account"
-#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
-#define LDAP_OBJ_POSIXGROUP "posixGroup"
-#define LDAP_OBJ_OU "organizationalUnit"
-
-/* some generic attributes that get reused a lot */
-
-#define LDAP_ATTRIBUTE_SID "sambaSID"
-#define LDAP_ATTRIBUTE_UIDNUMBER "uidNumber"
-#define LDAP_ATTRIBUTE_GIDNUMBER "gidNumber"
-#define LDAP_ATTRIBUTE_SID_LIST "sambaSIDList"
-#define LDAP_ATTRIBUTE_PRIVILEGE_LIST "sambaPrivilegeList"
-
-/* attribute map table indexes */
-
-#define LDAP_ATTR_LIST_END 0
-#define LDAP_ATTR_UID 1
-#define LDAP_ATTR_UIDNUMBER 2
-#define LDAP_ATTR_GIDNUMBER 3
-#define LDAP_ATTR_UNIX_HOME 4
-#define LDAP_ATTR_PWD_LAST_SET 5
-#define LDAP_ATTR_PWD_CAN_CHANGE 6
-#define LDAP_ATTR_PWD_MUST_CHANGE 7
-#define LDAP_ATTR_LOGON_TIME 8
-#define LDAP_ATTR_LOGOFF_TIME 9
-#define LDAP_ATTR_KICKOFF_TIME 10
-#define LDAP_ATTR_CN 11
-#define LDAP_ATTR_DISPLAY_NAME 12
-#define LDAP_ATTR_HOME_PATH 13
-#define LDAP_ATTR_LOGON_SCRIPT 14
-#define LDAP_ATTR_PROFILE_PATH 15
-#define LDAP_ATTR_DESC 16
-#define LDAP_ATTR_USER_WKS 17
-#define LDAP_ATTR_USER_SID 18
-#define LDAP_ATTR_USER_RID 18
-#define LDAP_ATTR_PRIMARY_GROUP_SID 19
-#define LDAP_ATTR_PRIMARY_GROUP_RID 20
-#define LDAP_ATTR_LMPW 21
-#define LDAP_ATTR_NTPW 22
-#define LDAP_ATTR_DOMAIN 23
-#define LDAP_ATTR_OBJCLASS 24
-#define LDAP_ATTR_ACB_INFO 25
-#define LDAP_ATTR_NEXT_USERRID 26
-#define LDAP_ATTR_NEXT_GROUPRID 27
-#define LDAP_ATTR_DOM_SID 28
-#define LDAP_ATTR_HOME_DRIVE 29
-#define LDAP_ATTR_GROUP_SID 30
-#define LDAP_ATTR_GROUP_TYPE 31
-#define LDAP_ATTR_SID 32
-#define LDAP_ATTR_ALGORITHMIC_RID_BASE 33
-#define LDAP_ATTR_NEXT_RID 34
-#define LDAP_ATTR_BAD_PASSWORD_COUNT 35
-#define LDAP_ATTR_LOGON_COUNT 36
-#define LDAP_ATTR_MUNGED_DIAL 37
-#define LDAP_ATTR_BAD_PASSWORD_TIME 38
-
-#define LDAP_ATTR_SID_LIST 40
-#define LDAP_ATTR_PRIV_LIST 41
-
-#define LDAP_ATTR_TRUST_PASSWD_FLAGS 42
-
-typedef struct _attrib_map_entry {
- int attrib;
- const char *name;
-} ATTRIB_MAP_ENTRY;
-
-
-/* structures */
-
-extern ATTRIB_MAP_ENTRY attrib_map_v22[];
-extern ATTRIB_MAP_ENTRY attrib_map_v30[];
-extern ATTRIB_MAP_ENTRY dominfo_attr_list[];
-extern ATTRIB_MAP_ENTRY groupmap_attr_list[];
-extern ATTRIB_MAP_ENTRY privilege_attr_list[];
-extern ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[];
-extern ATTRIB_MAP_ENTRY idpool_attr_list[];
-extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
-
-/* Function declarations -- not included in proto.h so we don't
- have to worry about LDAP structure types */
-
-const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key );
-char** get_attr_list( ATTRIB_MAP_ENTRY table[] );
-void free_attr_list( char **list );
-void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value);
-void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
- LDAPMod ***mods,
- const char *attribute, const char *newval);
-BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, char *value,
- int max_len);
-BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, pstring value);
-
-/**
- * Struct to keep the state for all the ldap stuff
- *
- */
-
-struct smbldap_state {
- LDAP *ldap_struct;
- time_t last_ping;
- /* retrive-once info */
- const char *uri;
- char *bind_dn;
- char *bind_secret;
-
- unsigned int num_failures;
-
- time_t last_use;
- smb_event_id_t event_id;
-
- struct timeval last_rebind;
-};
-
-#endif /* HAVE_LDAP */
-
-struct smbldap_state;
-
-#endif /* _SMBLDAP_H */
-
diff --git a/source/include/spnego.h b/source/include/spnego.h
deleted file mode 100644
index b6492ee3c8a..00000000000
--- a/source/include/spnego.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- RFC2478 Compliant SPNEGO implementation
-
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef SAMBA_SPNEGO_H
-#define SAMBA_SPNEGO_H
-
-#define SPNEGO_DELEG_FLAG 0x01
-#define SPNEGO_MUTUAL_FLAG 0x02
-#define SPNEGO_REPLAY_FLAG 0x04
-#define SPNEGO_SEQUENCE_FLAG 0x08
-#define SPNEGO_ANON_FLAG 0x10
-#define SPNEGO_CONF_FLAG 0x20
-#define SPNEGO_INTEG_FLAG 0x40
-#define SPNEGO_REQ_FLAG 0x80
-
-#define SPNEGO_NEG_TOKEN_INIT 0
-#define SPNEGO_NEG_TOKEN_TARG 1
-
-typedef enum _spnego_negResult {
- SPNEGO_ACCEPT_COMPLETED = 0,
- SPNEGO_ACCEPT_INCOMPLETE = 1,
- SPNEGO_REJECT = 2
-} negResult_t;
-
-typedef struct spnego_negTokenInit {
- const char **mechTypes;
- int reqFlags;
- DATA_BLOB mechToken;
- DATA_BLOB mechListMIC;
-} negTokenInit_t;
-
-typedef struct spnego_negTokenTarg {
- uint8 negResult;
- const char *supportedMech;
- DATA_BLOB responseToken;
- DATA_BLOB mechListMIC;
-} negTokenTarg_t;
-
-typedef struct spnego_spnego {
- int type;
- negTokenInit_t negTokenInit;
- negTokenTarg_t negTokenTarg;
-} SPNEGO_DATA;
-
-#endif
diff --git a/source/include/srvstr.h b/source/include/srvstr.h
deleted file mode 100644
index 04db59cf012..00000000000
--- a/source/include/srvstr.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- server specific string routines
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define srvstr_pull(base_ptr, dest, src, dest_len, src_len, flags) \
- pull_string(base_ptr, dest, src, dest_len, src_len, flags)
-
-/* pull a string from the smb_buf part of a packet. In this case the
- string can either be null terminated or it can be terminated by the
- end of the smbbuf area
-*/
-
-#define srvstr_pull_buf(inbuf, dest, src, dest_len, flags) \
- pull_string(inbuf, dest, src, dest_len, smb_bufrem(inbuf, src), flags)
-
diff --git a/source/include/sysquotas.h b/source/include/sysquotas.h
deleted file mode 100644
index bfb9466b392..00000000000
--- a/source/include/sysquotas.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SYS QUOTA code constants
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _SYSQUOTAS_H
-#define _SYSQUOTAS_H
-
-#ifdef HAVE_SYS_QUOTAS
-
-#if defined(HAVE_MNTENT_H)&&defined(HAVE_SETMNTENT)&&defined(HAVE_GETMNTENT)&&defined(HAVE_ENDMNTENT)
-#include <mntent.h>
-#define HAVE_MNTENT 1
-/*#endif defined(HAVE_MNTENT_H)&&defined(HAVE_SETMNTENT)&&defined(HAVE_GETMNTENT)&&defined(HAVE_ENDMNTENT) */
-#elif defined(HAVE_DEVNM_H)&&defined(HAVE_DEVNM)
-#include <devnm.h>
-#endif /* defined(HAVE_DEVNM_H)&&defined(HAVE_DEVNM) */
-
-#endif /* HAVE_SYS_QUOTAS */
-
-
-/**************************************************
- Some stuff for the sys_quota api.
- **************************************************/
-
-#define SMB_QUOTAS_NO_LIMIT ((SMB_BIG_UINT)(0))
-#define SMB_QUOTAS_NO_SPACE ((SMB_BIG_UINT)(1))
-
-#define SMB_QUOTAS_SET_NO_LIMIT(dp) \
-{\
- (dp)->softlimit = SMB_QUOTAS_NO_LIMIT;\
- (dp)->hardlimit = SMB_QUOTAS_NO_LIMIT;\
- (dp)->isoftlimit = SMB_QUOTAS_NO_LIMIT;\
- (dp)->ihardlimit = SMB_QUOTAS_NO_LIMIT;\
-}
-
-#define SMB_QUOTAS_SET_NO_SPACE(dp) \
-{\
- (dp)->softlimit = SMB_QUOTAS_NO_SPACE;\
- (dp)->hardlimit = SMB_QUOTAS_NO_SPACE;\
- (dp)->isoftlimit = SMB_QUOTAS_NO_SPACE;\
- (dp)->ihardlimit = SMB_QUOTAS_NO_SPACE;\
-}
-
-typedef struct _SMB_DISK_QUOTA {
- enum SMB_QUOTA_TYPE qtype;
- SMB_BIG_UINT bsize;
- SMB_BIG_UINT hardlimit; /* In bsize units. */
- SMB_BIG_UINT softlimit; /* In bsize units. */
- SMB_BIG_UINT curblocks; /* In bsize units. */
- SMB_BIG_UINT ihardlimit; /* inode hard limit. */
- SMB_BIG_UINT isoftlimit; /* inode soft limit. */
- SMB_BIG_UINT curinodes; /* Current used inodes. */
- uint32 qflags;
-} SMB_DISK_QUOTA;
-
-#ifndef QUOTABLOCK_SIZE
-#define QUOTABLOCK_SIZE 1024
-#endif
-
-#endif /*_SYSQUOTAS_H */
diff --git a/source/include/talloc.h b/source/include/talloc.h
index 433b52ec954..64a58830413 100644
--- a/source/include/talloc.h
+++ b/source/include/talloc.h
@@ -30,30 +30,9 @@
/**
* talloc allocation pool. All allocated blocks can be freed in one go.
**/
-
-struct talloc_chunk {
- struct talloc_chunk *next;
- size_t size;
- void *ptr;
-};
-
-struct talloc_ctx {
- struct talloc_chunk *list;
- size_t total_alloc_size;
-
- /** The name recorded for this pool, if any. Should describe
- * the purpose for which it was allocated. The string is
- * allocated within the pool. **/
- char *name;
-
- /** Pointer to the next allocate talloc pool, so that we can
- * summarize all talloc memory usage. **/
- struct talloc_ctx *next_ctx;
-};
-
typedef struct talloc_ctx TALLOC_CTX;
-TALLOC_CTX *talloc_init(char const *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
+TALLOC_CTX *talloc_init_named(char const *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
char *talloc_vasprintf(TALLOC_CTX *t, const char *fmt, va_list ap)
PRINTF_ATTRIBUTE(2, 0);
diff --git a/source/include/tdbsam2_parse_info.h b/source/include/tdbsam2_parse_info.h
deleted file mode 100644
index 35eeaeb2d2c..00000000000
--- a/source/include/tdbsam2_parse_info.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* This is an automatically generated file - DO NOT EDIT! */
-
diff --git a/source/include/trans2.h b/source/include/trans2.h
index 3106cd092ab..7f5cf1818bf 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB transaction2 handling
Copyright (C) Jeremy Allison 1994-2002.
@@ -206,9 +207,7 @@ Byte offset Type name description
#define SMB_QUERY_FS_SIZE_INFO 0x103
#define SMB_QUERY_FS_DEVICE_INFO 0x104
#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105
-#if 0
-#define SMB_QUERY_FS_QUOTA_INFO
-#endif
+
#define l2_vol_fdateCreation 0
#define l2_vol_cch 4
@@ -224,24 +223,17 @@ Byte offset Type name description
#define SMB_QUERY_FILE_ALL_INFO 0x107
#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108
#define SMB_QUERY_FILE_STREAM_INFO 0x109
-#define SMB_QUERY_COMPRESSION_INFO 0x10b
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
#define SMB_FIND_FILE_NAMES_INFO 0x103
#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104
-#define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105
-#define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106
#define SMB_SET_FILE_BASIC_INFO 0x101
#define SMB_SET_FILE_DISPOSITION_INFO 0x102
#define SMB_SET_FILE_ALLOCATION_INFO 0x103
#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
-/* Query FS info. */
-#define SMB_INFO_ALLOCATION 1
-#define SMB_INFO_VOLUME 2
-
/*
* Thursby MAC extensions....
*/
@@ -325,7 +317,7 @@ Byte offset Type name description
#define SMB_FS_SIZE_INFORMATION 1003
#define SMB_FS_DEVICE_INFORMATION 1004
#define SMB_FS_ATTRIBUTE_INFORMATION 1005
-#define SMB_FS_QUOTA_INFORMATION 1006
+#define SMB_FS_CONTROL_INFORMATION 1006
#define SMB_FS_FULL_SIZE_INFORMATION 1007
#define SMB_FS_OBJECTID_INFORMATION 1008
@@ -350,10 +342,11 @@ Byte offset Type name description
#define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF
#define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF
-
+
#define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF
#define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF
+
/*
Offset Size Name
0 LARGE_INTEGER EndOfFile File size
diff --git a/source/include/unicode_map_table1.h b/source/include/unicode_map_table1.h
new file mode 100755
index 00000000000..6040b937777
--- /dev/null
+++ b/source/include/unicode_map_table1.h
@@ -0,0 +1,9450 @@
+{0x0000,0x0000,0},
+{0x0001,0x0001,0},
+{0x0002,0x0002,0},
+{0x0003,0x0003,0},
+{0x0004,0x0004,0},
+{0x0005,0x0005,0},
+{0x0006,0x0006,0},
+{0x0007,0x0007,0},
+{0x0008,0x0008,0},
+{0x0009,0x0009,UNI_SPACE},
+{0x000A,0x000A,UNI_SPACE},
+{0x000B,0x000B,UNI_SPACE},
+{0x000C,0x000C,UNI_SPACE},
+{0x000D,0x000D,UNI_SPACE},
+{0x000E,0x000E,0},
+{0x000F,0x000F,0},
+{0x0010,0x0010,0},
+{0x0011,0x0011,0},
+{0x0012,0x0012,0},
+{0x0013,0x0013,0},
+{0x0014,0x0014,0},
+{0x0015,0x0015,0},
+{0x0016,0x0016,0},
+{0x0017,0x0017,0},
+{0x0018,0x0018,0},
+{0x0019,0x0019,0},
+{0x001A,0x001A,0},
+{0x001B,0x001B,0},
+{0x001C,0x001C,0},
+{0x001D,0x001D,0},
+{0x001E,0x001E,0},
+{0x001F,0x001F,0},
+{0x0020,0x0020,UNI_SPACE},
+{0x0021,0x0021,0},
+{0x0022,0x0022,0},
+{0x0023,0x0023,0},
+{0x0024,0x0024,0},
+{0x0025,0x0025,0},
+{0x0026,0x0026,0},
+{0x0027,0x0027,0},
+{0x0028,0x0028,0},
+{0x0029,0x0029,0},
+{0x002A,0x002A,0},
+{0x002B,0x002B,0},
+{0x002C,0x002C,0},
+{0x002D,0x002D,0},
+{0x002E,0x002E,0},
+{0x002F,0x002F,0},
+{0x0030,0x0030,UNI_DIGIT|UNI_XDIGIT},
+{0x0031,0x0031,UNI_DIGIT|UNI_XDIGIT},
+{0x0032,0x0032,UNI_DIGIT|UNI_XDIGIT},
+{0x0033,0x0033,UNI_DIGIT|UNI_XDIGIT},
+{0x0034,0x0034,UNI_DIGIT|UNI_XDIGIT},
+{0x0035,0x0035,UNI_DIGIT|UNI_XDIGIT},
+{0x0036,0x0036,UNI_DIGIT|UNI_XDIGIT},
+{0x0037,0x0037,UNI_DIGIT|UNI_XDIGIT},
+{0x0038,0x0038,UNI_DIGIT|UNI_XDIGIT},
+{0x0039,0x0039,UNI_DIGIT|UNI_XDIGIT},
+{0x003A,0x003A,0},
+{0x003B,0x003B,0},
+{0x003C,0x003C,0},
+{0x003D,0x003D,0},
+{0x003E,0x003E,0},
+{0x003F,0x003F,0},
+{0x0040,0x0040,0},
+{0x0061,0x0041,UNI_UPPER|UNI_XDIGIT},
+{0x0062,0x0042,UNI_UPPER|UNI_XDIGIT},
+{0x0063,0x0043,UNI_UPPER|UNI_XDIGIT},
+{0x0064,0x0044,UNI_UPPER|UNI_XDIGIT},
+{0x0065,0x0045,UNI_UPPER|UNI_XDIGIT},
+{0x0066,0x0046,UNI_UPPER|UNI_XDIGIT},
+{0x0067,0x0047,UNI_UPPER},
+{0x0068,0x0048,UNI_UPPER},
+{0x0069,0x0049,UNI_UPPER},
+{0x006A,0x004A,UNI_UPPER},
+{0x006B,0x004B,UNI_UPPER},
+{0x006C,0x004C,UNI_UPPER},
+{0x006D,0x004D,UNI_UPPER},
+{0x006E,0x004E,UNI_UPPER},
+{0x006F,0x004F,UNI_UPPER},
+{0x0070,0x0050,UNI_UPPER},
+{0x0071,0x0051,UNI_UPPER},
+{0x0072,0x0052,UNI_UPPER},
+{0x0073,0x0053,UNI_UPPER},
+{0x0074,0x0054,UNI_UPPER},
+{0x0075,0x0055,UNI_UPPER},
+{0x0076,0x0056,UNI_UPPER},
+{0x0077,0x0057,UNI_UPPER},
+{0x0078,0x0058,UNI_UPPER},
+{0x0079,0x0059,UNI_UPPER},
+{0x007A,0x005A,UNI_UPPER},
+{0x005B,0x005B,0},
+{0x005C,0x005C,0},
+{0x005D,0x005D,0},
+{0x005E,0x005E,0},
+{0x005F,0x005F,0},
+{0x0060,0x0060,0},
+{0x0061,0x0041,UNI_LOWER|UNI_XDIGIT},
+{0x0062,0x0042,UNI_LOWER|UNI_XDIGIT},
+{0x0063,0x0043,UNI_LOWER|UNI_XDIGIT},
+{0x0064,0x0044,UNI_LOWER|UNI_XDIGIT},
+{0x0065,0x0045,UNI_LOWER|UNI_XDIGIT},
+{0x0066,0x0046,UNI_LOWER|UNI_XDIGIT},
+{0x0067,0x0047,UNI_LOWER},
+{0x0068,0x0048,UNI_LOWER},
+{0x0069,0x0049,UNI_LOWER},
+{0x006A,0x004A,UNI_LOWER},
+{0x006B,0x004B,UNI_LOWER},
+{0x006C,0x004C,UNI_LOWER},
+{0x006D,0x004D,UNI_LOWER},
+{0x006E,0x004E,UNI_LOWER},
+{0x006F,0x004F,UNI_LOWER},
+{0x0070,0x0050,UNI_LOWER},
+{0x0071,0x0051,UNI_LOWER},
+{0x0072,0x0052,UNI_LOWER},
+{0x0073,0x0053,UNI_LOWER},
+{0x0074,0x0054,UNI_LOWER},
+{0x0075,0x0055,UNI_LOWER},
+{0x0076,0x0056,UNI_LOWER},
+{0x0077,0x0057,UNI_LOWER},
+{0x0078,0x0058,UNI_LOWER},
+{0x0079,0x0059,UNI_LOWER},
+{0x007A,0x005A,UNI_LOWER},
+{0x007B,0x007B,0},
+{0x007C,0x007C,0},
+{0x007D,0x007D,0},
+{0x007E,0x007E,0},
+{0x007F,0x007F,0},
+{0x0080,0x0080,0},
+{0x0081,0x0081,0},
+{0x0082,0x0082,0},
+{0x0083,0x0083,0},
+{0x0084,0x0084,0},
+{0x0085,0x0085,0},
+{0x0086,0x0086,0},
+{0x0087,0x0087,0},
+{0x0088,0x0088,0},
+{0x0089,0x0089,0},
+{0x008A,0x008A,0},
+{0x008B,0x008B,0},
+{0x008C,0x008C,0},
+{0x008D,0x008D,0},
+{0x008E,0x008E,0},
+{0x008F,0x008F,0},
+{0x0090,0x0090,0},
+{0x0091,0x0091,0},
+{0x0092,0x0092,0},
+{0x0093,0x0093,0},
+{0x0094,0x0094,0},
+{0x0095,0x0095,0},
+{0x0096,0x0096,0},
+{0x0097,0x0097,0},
+{0x0098,0x0098,0},
+{0x0099,0x0099,0},
+{0x009A,0x009A,0},
+{0x009B,0x009B,0},
+{0x009C,0x009C,0},
+{0x009D,0x009D,0},
+{0x009E,0x009E,0},
+{0x009F,0x009F,0},
+{0x00A0,0x00A0,0},
+{0x00A1,0x00A1,0},
+{0x00A2,0x00A2,0},
+{0x00A3,0x00A3,0},
+{0x00A4,0x00A4,0},
+{0x00A5,0x00A5,0},
+{0x00A6,0x00A6,0},
+{0x00A7,0x00A7,0},
+{0x00A8,0x00A8,0},
+{0x00A9,0x00A9,0},
+{0x00AA,0x00AA,UNI_LOWER},
+{0x00AB,0x00AB,0},
+{0x00AC,0x00AC,0},
+{0x00AD,0x00AD,0},
+{0x00AE,0x00AE,0},
+{0x00AF,0x00AF,0},
+{0x00B0,0x00B0,0},
+{0x00B1,0x00B1,0},
+{0x00B2,0x00B2,0},
+{0x00B3,0x00B3,0},
+{0x00B4,0x00B4,0},
+{0x00B5,0x039C,UNI_LOWER},
+{0x00B6,0x00B6,0},
+{0x00B7,0x00B7,0},
+{0x00B8,0x00B8,0},
+{0x00B9,0x00B9,0},
+{0x00BA,0x00BA,UNI_LOWER},
+{0x00BB,0x00BB,0},
+{0x00BC,0x00BC,0},
+{0x00BD,0x00BD,0},
+{0x00BE,0x00BE,0},
+{0x00BF,0x00BF,0},
+{0x00E0,0x00C0,UNI_UPPER},
+{0x00E1,0x00C1,UNI_UPPER},
+{0x00E2,0x00C2,UNI_UPPER},
+{0x00E3,0x00C3,UNI_UPPER},
+{0x00E4,0x00C4,UNI_UPPER},
+{0x00E5,0x00C5,UNI_UPPER},
+{0x00E6,0x00C6,UNI_UPPER},
+{0x00E7,0x00C7,UNI_UPPER},
+{0x00E8,0x00C8,UNI_UPPER},
+{0x00E9,0x00C9,UNI_UPPER},
+{0x00EA,0x00CA,UNI_UPPER},
+{0x00EB,0x00CB,UNI_UPPER},
+{0x00EC,0x00CC,UNI_UPPER},
+{0x00ED,0x00CD,UNI_UPPER},
+{0x00EE,0x00CE,UNI_UPPER},
+{0x00EF,0x00CF,UNI_UPPER},
+{0x00F0,0x00D0,UNI_UPPER},
+{0x00F1,0x00D1,UNI_UPPER},
+{0x00F2,0x00D2,UNI_UPPER},
+{0x00F3,0x00D3,UNI_UPPER},
+{0x00F4,0x00D4,UNI_UPPER},
+{0x00F5,0x00D5,UNI_UPPER},
+{0x00F6,0x00D6,UNI_UPPER},
+{0x00D7,0x00D7,0},
+{0x00F8,0x00D8,UNI_UPPER},
+{0x00F9,0x00D9,UNI_UPPER},
+{0x00FA,0x00DA,UNI_UPPER},
+{0x00FB,0x00DB,UNI_UPPER},
+{0x00FC,0x00DC,UNI_UPPER},
+{0x00FD,0x00DD,UNI_UPPER},
+{0x00FE,0x00DE,UNI_UPPER},
+{0x00DF,0x00DF,UNI_LOWER},
+{0x00E0,0x00C0,UNI_LOWER},
+{0x00E1,0x00C1,UNI_LOWER},
+{0x00E2,0x00C2,UNI_LOWER},
+{0x00E3,0x00C3,UNI_LOWER},
+{0x00E4,0x00C4,UNI_LOWER},
+{0x00E5,0x00C5,UNI_LOWER},
+{0x00E6,0x00C6,UNI_LOWER},
+{0x00E7,0x00C7,UNI_LOWER},
+{0x00E8,0x00C8,UNI_LOWER},
+{0x00E9,0x00C9,UNI_LOWER},
+{0x00EA,0x00CA,UNI_LOWER},
+{0x00EB,0x00CB,UNI_LOWER},
+{0x00EC,0x00CC,UNI_LOWER},
+{0x00ED,0x00CD,UNI_LOWER},
+{0x00EE,0x00CE,UNI_LOWER},
+{0x00EF,0x00CF,UNI_LOWER},
+{0x00F0,0x00D0,UNI_LOWER},
+{0x00F1,0x00D1,UNI_LOWER},
+{0x00F2,0x00D2,UNI_LOWER},
+{0x00F3,0x00D3,UNI_LOWER},
+{0x00F4,0x00D4,UNI_LOWER},
+{0x00F5,0x00D5,UNI_LOWER},
+{0x00F6,0x00D6,UNI_LOWER},
+{0x00F7,0x00F7,0},
+{0x00F8,0x00D8,UNI_LOWER},
+{0x00F9,0x00D9,UNI_LOWER},
+{0x00FA,0x00DA,UNI_LOWER},
+{0x00FB,0x00DB,UNI_LOWER},
+{0x00FC,0x00DC,UNI_LOWER},
+{0x00FD,0x00DD,UNI_LOWER},
+{0x00FE,0x00DE,UNI_LOWER},
+{0x00FF,0x0178,UNI_LOWER},
+{0x0101,0x0100,UNI_UPPER},
+{0x0101,0x0100,UNI_LOWER},
+{0x0103,0x0102,UNI_UPPER},
+{0x0103,0x0102,UNI_LOWER},
+{0x0105,0x0104,UNI_UPPER},
+{0x0105,0x0104,UNI_LOWER},
+{0x0107,0x0106,UNI_UPPER},
+{0x0107,0x0106,UNI_LOWER},
+{0x0109,0x0108,UNI_UPPER},
+{0x0109,0x0108,UNI_LOWER},
+{0x010B,0x010A,UNI_UPPER},
+{0x010B,0x010A,UNI_LOWER},
+{0x010D,0x010C,UNI_UPPER},
+{0x010D,0x010C,UNI_LOWER},
+{0x010F,0x010E,UNI_UPPER},
+{0x010F,0x010E,UNI_LOWER},
+{0x0111,0x0110,UNI_UPPER},
+{0x0111,0x0110,UNI_LOWER},
+{0x0113,0x0112,UNI_UPPER},
+{0x0113,0x0112,UNI_LOWER},
+{0x0115,0x0114,UNI_UPPER},
+{0x0115,0x0114,UNI_LOWER},
+{0x0117,0x0116,UNI_UPPER},
+{0x0117,0x0116,UNI_LOWER},
+{0x0119,0x0118,UNI_UPPER},
+{0x0119,0x0118,UNI_LOWER},
+{0x011B,0x011A,UNI_UPPER},
+{0x011B,0x011A,UNI_LOWER},
+{0x011D,0x011C,UNI_UPPER},
+{0x011D,0x011C,UNI_LOWER},
+{0x011F,0x011E,UNI_UPPER},
+{0x011F,0x011E,UNI_LOWER},
+{0x0121,0x0120,UNI_UPPER},
+{0x0121,0x0120,UNI_LOWER},
+{0x0123,0x0122,UNI_UPPER},
+{0x0123,0x0122,UNI_LOWER},
+{0x0125,0x0124,UNI_UPPER},
+{0x0125,0x0124,UNI_LOWER},
+{0x0127,0x0126,UNI_UPPER},
+{0x0127,0x0126,UNI_LOWER},
+{0x0129,0x0128,UNI_UPPER},
+{0x0129,0x0128,UNI_LOWER},
+{0x012B,0x012A,UNI_UPPER},
+{0x012B,0x012A,UNI_LOWER},
+{0x012D,0x012C,UNI_UPPER},
+{0x012D,0x012C,UNI_LOWER},
+{0x012F,0x012E,UNI_UPPER},
+{0x012F,0x012E,UNI_LOWER},
+{0x0069,0x0130,UNI_UPPER},
+{0x0131,0x0049,UNI_LOWER},
+{0x0133,0x0132,UNI_UPPER},
+{0x0133,0x0132,UNI_LOWER},
+{0x0135,0x0134,UNI_UPPER},
+{0x0135,0x0134,UNI_LOWER},
+{0x0137,0x0136,UNI_UPPER},
+{0x0137,0x0136,UNI_LOWER},
+{0x0138,0x0138,UNI_LOWER},
+{0x013A,0x0139,UNI_UPPER},
+{0x013A,0x0139,UNI_LOWER},
+{0x013C,0x013B,UNI_UPPER},
+{0x013C,0x013B,UNI_LOWER},
+{0x013E,0x013D,UNI_UPPER},
+{0x013E,0x013D,UNI_LOWER},
+{0x0140,0x013F,UNI_UPPER},
+{0x0140,0x013F,UNI_LOWER},
+{0x0142,0x0141,UNI_UPPER},
+{0x0142,0x0141,UNI_LOWER},
+{0x0144,0x0143,UNI_UPPER},
+{0x0144,0x0143,UNI_LOWER},
+{0x0146,0x0145,UNI_UPPER},
+{0x0146,0x0145,UNI_LOWER},
+{0x0148,0x0147,UNI_UPPER},
+{0x0148,0x0147,UNI_LOWER},
+{0x0149,0x0149,UNI_LOWER},
+{0x014B,0x014A,UNI_UPPER},
+{0x014B,0x014A,UNI_LOWER},
+{0x014D,0x014C,UNI_UPPER},
+{0x014D,0x014C,UNI_LOWER},
+{0x014F,0x014E,UNI_UPPER},
+{0x014F,0x014E,UNI_LOWER},
+{0x0151,0x0150,UNI_UPPER},
+{0x0151,0x0150,UNI_LOWER},
+{0x0153,0x0152,UNI_UPPER},
+{0x0153,0x0152,UNI_LOWER},
+{0x0155,0x0154,UNI_UPPER},
+{0x0155,0x0154,UNI_LOWER},
+{0x0157,0x0156,UNI_UPPER},
+{0x0157,0x0156,UNI_LOWER},
+{0x0159,0x0158,UNI_UPPER},
+{0x0159,0x0158,UNI_LOWER},
+{0x015B,0x015A,UNI_UPPER},
+{0x015B,0x015A,UNI_LOWER},
+{0x015D,0x015C,UNI_UPPER},
+{0x015D,0x015C,UNI_LOWER},
+{0x015F,0x015E,UNI_UPPER},
+{0x015F,0x015E,UNI_LOWER},
+{0x0161,0x0160,UNI_UPPER},
+{0x0161,0x0160,UNI_LOWER},
+{0x0163,0x0162,UNI_UPPER},
+{0x0163,0x0162,UNI_LOWER},
+{0x0165,0x0164,UNI_UPPER},
+{0x0165,0x0164,UNI_LOWER},
+{0x0167,0x0166,UNI_UPPER},
+{0x0167,0x0166,UNI_LOWER},
+{0x0169,0x0168,UNI_UPPER},
+{0x0169,0x0168,UNI_LOWER},
+{0x016B,0x016A,UNI_UPPER},
+{0x016B,0x016A,UNI_LOWER},
+{0x016D,0x016C,UNI_UPPER},
+{0x016D,0x016C,UNI_LOWER},
+{0x016F,0x016E,UNI_UPPER},
+{0x016F,0x016E,UNI_LOWER},
+{0x0171,0x0170,UNI_UPPER},
+{0x0171,0x0170,UNI_LOWER},
+{0x0173,0x0172,UNI_UPPER},
+{0x0173,0x0172,UNI_LOWER},
+{0x0175,0x0174,UNI_UPPER},
+{0x0175,0x0174,UNI_LOWER},
+{0x0177,0x0176,UNI_UPPER},
+{0x0177,0x0176,UNI_LOWER},
+{0x00FF,0x0178,UNI_UPPER},
+{0x017A,0x0179,UNI_UPPER},
+{0x017A,0x0179,UNI_LOWER},
+{0x017C,0x017B,UNI_UPPER},
+{0x017C,0x017B,UNI_LOWER},
+{0x017E,0x017D,UNI_UPPER},
+{0x017E,0x017D,UNI_LOWER},
+{0x017F,0x0053,UNI_LOWER},
+{0x0180,0x0180,UNI_LOWER},
+{0x0253,0x0181,UNI_UPPER},
+{0x0183,0x0182,UNI_UPPER},
+{0x0183,0x0182,UNI_LOWER},
+{0x0185,0x0184,UNI_UPPER},
+{0x0185,0x0184,UNI_LOWER},
+{0x0254,0x0186,UNI_UPPER},
+{0x0188,0x0187,UNI_UPPER},
+{0x0188,0x0187,UNI_LOWER},
+{0x0256,0x0189,UNI_UPPER},
+{0x0257,0x018A,UNI_UPPER},
+{0x018C,0x018B,UNI_UPPER},
+{0x018C,0x018B,UNI_LOWER},
+{0x018D,0x018D,UNI_LOWER},
+{0x01DD,0x018E,UNI_UPPER},
+{0x0259,0x018F,UNI_UPPER},
+{0x025B,0x0190,UNI_UPPER},
+{0x0192,0x0191,UNI_UPPER},
+{0x0192,0x0191,UNI_LOWER},
+{0x0260,0x0193,UNI_UPPER},
+{0x0263,0x0194,UNI_UPPER},
+{0x0195,0x01F6,UNI_LOWER},
+{0x0269,0x0196,UNI_UPPER},
+{0x0268,0x0197,UNI_UPPER},
+{0x0199,0x0198,UNI_UPPER},
+{0x0199,0x0198,UNI_LOWER},
+{0x019A,0x019A,UNI_LOWER},
+{0x019B,0x019B,UNI_LOWER},
+{0x026F,0x019C,UNI_UPPER},
+{0x0272,0x019D,UNI_UPPER},
+{0x019E,0x019E,UNI_LOWER},
+{0x0275,0x019F,UNI_UPPER},
+{0x01A1,0x01A0,UNI_UPPER},
+{0x01A1,0x01A0,UNI_LOWER},
+{0x01A3,0x01A2,UNI_UPPER},
+{0x01A3,0x01A2,UNI_LOWER},
+{0x01A5,0x01A4,UNI_UPPER},
+{0x01A5,0x01A4,UNI_LOWER},
+{0x0280,0x01A6,UNI_UPPER},
+{0x01A8,0x01A7,UNI_UPPER},
+{0x01A8,0x01A7,UNI_LOWER},
+{0x0283,0x01A9,UNI_UPPER},
+{0x01AA,0x01AA,UNI_LOWER},
+{0x01AB,0x01AB,UNI_LOWER},
+{0x01AD,0x01AC,UNI_UPPER},
+{0x01AD,0x01AC,UNI_LOWER},
+{0x0288,0x01AE,UNI_UPPER},
+{0x01B0,0x01AF,UNI_UPPER},
+{0x01B0,0x01AF,UNI_LOWER},
+{0x028A,0x01B1,UNI_UPPER},
+{0x028B,0x01B2,UNI_UPPER},
+{0x01B4,0x01B3,UNI_UPPER},
+{0x01B4,0x01B3,UNI_LOWER},
+{0x01B6,0x01B5,UNI_UPPER},
+{0x01B6,0x01B5,UNI_LOWER},
+{0x0292,0x01B7,UNI_UPPER},
+{0x01B9,0x01B8,UNI_UPPER},
+{0x01B9,0x01B8,UNI_LOWER},
+{0x01BA,0x01BA,UNI_LOWER},
+{0x01BB,0x01BB,0},
+{0x01BD,0x01BC,UNI_UPPER},
+{0x01BD,0x01BC,UNI_LOWER},
+{0x01BE,0x01BE,UNI_LOWER},
+{0x01BF,0x01F7,UNI_LOWER},
+{0x01C0,0x01C0,0},
+{0x01C1,0x01C1,0},
+{0x01C2,0x01C2,0},
+{0x01C3,0x01C3,0},
+{0x01C6,0x01C4,UNI_UPPER},
+{0x01C6,0x01C4,0},
+{0x01C6,0x01C4,UNI_LOWER},
+{0x01C9,0x01C7,UNI_UPPER},
+{0x01C9,0x01C7,0},
+{0x01C9,0x01C7,UNI_LOWER},
+{0x01CC,0x01CA,UNI_UPPER},
+{0x01CC,0x01CA,0},
+{0x01CC,0x01CA,UNI_LOWER},
+{0x01CE,0x01CD,UNI_UPPER},
+{0x01CE,0x01CD,UNI_LOWER},
+{0x01D0,0x01CF,UNI_UPPER},
+{0x01D0,0x01CF,UNI_LOWER},
+{0x01D2,0x01D1,UNI_UPPER},
+{0x01D2,0x01D1,UNI_LOWER},
+{0x01D4,0x01D3,UNI_UPPER},
+{0x01D4,0x01D3,UNI_LOWER},
+{0x01D6,0x01D5,UNI_UPPER},
+{0x01D6,0x01D5,UNI_LOWER},
+{0x01D8,0x01D7,UNI_UPPER},
+{0x01D8,0x01D7,UNI_LOWER},
+{0x01DA,0x01D9,UNI_UPPER},
+{0x01DA,0x01D9,UNI_LOWER},
+{0x01DC,0x01DB,UNI_UPPER},
+{0x01DC,0x01DB,UNI_LOWER},
+{0x01DD,0x018E,UNI_LOWER},
+{0x01DF,0x01DE,UNI_UPPER},
+{0x01DF,0x01DE,UNI_LOWER},
+{0x01E1,0x01E0,UNI_UPPER},
+{0x01E1,0x01E0,UNI_LOWER},
+{0x01E3,0x01E2,UNI_UPPER},
+{0x01E3,0x01E2,UNI_LOWER},
+{0x01E5,0x01E4,UNI_UPPER},
+{0x01E5,0x01E4,UNI_LOWER},
+{0x01E7,0x01E6,UNI_UPPER},
+{0x01E7,0x01E6,UNI_LOWER},
+{0x01E9,0x01E8,UNI_UPPER},
+{0x01E9,0x01E8,UNI_LOWER},
+{0x01EB,0x01EA,UNI_UPPER},
+{0x01EB,0x01EA,UNI_LOWER},
+{0x01ED,0x01EC,UNI_UPPER},
+{0x01ED,0x01EC,UNI_LOWER},
+{0x01EF,0x01EE,UNI_UPPER},
+{0x01EF,0x01EE,UNI_LOWER},
+{0x01F0,0x01F0,UNI_LOWER},
+{0x01F3,0x01F1,UNI_UPPER},
+{0x01F3,0x01F1,0},
+{0x01F3,0x01F1,UNI_LOWER},
+{0x01F5,0x01F4,UNI_UPPER},
+{0x01F5,0x01F4,UNI_LOWER},
+{0x0195,0x01F6,UNI_UPPER},
+{0x01BF,0x01F7,UNI_UPPER},
+{0x01F9,0x01F8,UNI_UPPER},
+{0x01F9,0x01F8,UNI_LOWER},
+{0x01FB,0x01FA,UNI_UPPER},
+{0x01FB,0x01FA,UNI_LOWER},
+{0x01FD,0x01FC,UNI_UPPER},
+{0x01FD,0x01FC,UNI_LOWER},
+{0x01FF,0x01FE,UNI_UPPER},
+{0x01FF,0x01FE,UNI_LOWER},
+{0x0201,0x0200,UNI_UPPER},
+{0x0201,0x0200,UNI_LOWER},
+{0x0203,0x0202,UNI_UPPER},
+{0x0203,0x0202,UNI_LOWER},
+{0x0205,0x0204,UNI_UPPER},
+{0x0205,0x0204,UNI_LOWER},
+{0x0207,0x0206,UNI_UPPER},
+{0x0207,0x0206,UNI_LOWER},
+{0x0209,0x0208,UNI_UPPER},
+{0x0209,0x0208,UNI_LOWER},
+{0x020B,0x020A,UNI_UPPER},
+{0x020B,0x020A,UNI_LOWER},
+{0x020D,0x020C,UNI_UPPER},
+{0x020D,0x020C,UNI_LOWER},
+{0x020F,0x020E,UNI_UPPER},
+{0x020F,0x020E,UNI_LOWER},
+{0x0211,0x0210,UNI_UPPER},
+{0x0211,0x0210,UNI_LOWER},
+{0x0213,0x0212,UNI_UPPER},
+{0x0213,0x0212,UNI_LOWER},
+{0x0215,0x0214,UNI_UPPER},
+{0x0215,0x0214,UNI_LOWER},
+{0x0217,0x0216,UNI_UPPER},
+{0x0217,0x0216,UNI_LOWER},
+{0x0219,0x0218,UNI_UPPER},
+{0x0219,0x0218,UNI_LOWER},
+{0x021B,0x021A,UNI_UPPER},
+{0x021B,0x021A,UNI_LOWER},
+{0x021D,0x021C,UNI_UPPER},
+{0x021D,0x021C,UNI_LOWER},
+{0x021F,0x021E,UNI_UPPER},
+{0x021F,0x021E,UNI_LOWER},
+{0x0220,0x0220,0},
+{0x0221,0x0221,0},
+{0x0223,0x0222,UNI_UPPER},
+{0x0223,0x0222,UNI_LOWER},
+{0x0225,0x0224,UNI_UPPER},
+{0x0225,0x0224,UNI_LOWER},
+{0x0227,0x0226,UNI_UPPER},
+{0x0227,0x0226,UNI_LOWER},
+{0x0229,0x0228,UNI_UPPER},
+{0x0229,0x0228,UNI_LOWER},
+{0x022B,0x022A,UNI_UPPER},
+{0x022B,0x022A,UNI_LOWER},
+{0x022D,0x022C,UNI_UPPER},
+{0x022D,0x022C,UNI_LOWER},
+{0x022F,0x022E,UNI_UPPER},
+{0x022F,0x022E,UNI_LOWER},
+{0x0231,0x0230,UNI_UPPER},
+{0x0231,0x0230,UNI_LOWER},
+{0x0233,0x0232,UNI_UPPER},
+{0x0233,0x0232,UNI_LOWER},
+{0x0234,0x0234,0},
+{0x0235,0x0235,0},
+{0x0236,0x0236,0},
+{0x0237,0x0237,0},
+{0x0238,0x0238,0},
+{0x0239,0x0239,0},
+{0x023A,0x023A,0},
+{0x023B,0x023B,0},
+{0x023C,0x023C,0},
+{0x023D,0x023D,0},
+{0x023E,0x023E,0},
+{0x023F,0x023F,0},
+{0x0240,0x0240,0},
+{0x0241,0x0241,0},
+{0x0242,0x0242,0},
+{0x0243,0x0243,0},
+{0x0244,0x0244,0},
+{0x0245,0x0245,0},
+{0x0246,0x0246,0},
+{0x0247,0x0247,0},
+{0x0248,0x0248,0},
+{0x0249,0x0249,0},
+{0x024A,0x024A,0},
+{0x024B,0x024B,0},
+{0x024C,0x024C,0},
+{0x024D,0x024D,0},
+{0x024E,0x024E,0},
+{0x024F,0x024F,0},
+{0x0250,0x0250,UNI_LOWER},
+{0x0251,0x0251,UNI_LOWER},
+{0x0252,0x0252,UNI_LOWER},
+{0x0253,0x0181,UNI_LOWER},
+{0x0254,0x0186,UNI_LOWER},
+{0x0255,0x0255,UNI_LOWER},
+{0x0256,0x0189,UNI_LOWER},
+{0x0257,0x018A,UNI_LOWER},
+{0x0258,0x0258,UNI_LOWER},
+{0x0259,0x018F,UNI_LOWER},
+{0x025A,0x025A,UNI_LOWER},
+{0x025B,0x0190,UNI_LOWER},
+{0x025C,0x025C,UNI_LOWER},
+{0x025D,0x025D,UNI_LOWER},
+{0x025E,0x025E,UNI_LOWER},
+{0x025F,0x025F,UNI_LOWER},
+{0x0260,0x0193,UNI_LOWER},
+{0x0261,0x0261,UNI_LOWER},
+{0x0262,0x0262,UNI_LOWER},
+{0x0263,0x0194,UNI_LOWER},
+{0x0264,0x0264,UNI_LOWER},
+{0x0265,0x0265,UNI_LOWER},
+{0x0266,0x0266,UNI_LOWER},
+{0x0267,0x0267,UNI_LOWER},
+{0x0268,0x0197,UNI_LOWER},
+{0x0269,0x0196,UNI_LOWER},
+{0x026A,0x026A,UNI_LOWER},
+{0x026B,0x026B,UNI_LOWER},
+{0x026C,0x026C,UNI_LOWER},
+{0x026D,0x026D,UNI_LOWER},
+{0x026E,0x026E,UNI_LOWER},
+{0x026F,0x019C,UNI_LOWER},
+{0x0270,0x0270,UNI_LOWER},
+{0x0271,0x0271,UNI_LOWER},
+{0x0272,0x019D,UNI_LOWER},
+{0x0273,0x0273,UNI_LOWER},
+{0x0274,0x0274,UNI_LOWER},
+{0x0275,0x019F,UNI_LOWER},
+{0x0276,0x0276,UNI_LOWER},
+{0x0277,0x0277,UNI_LOWER},
+{0x0278,0x0278,UNI_LOWER},
+{0x0279,0x0279,UNI_LOWER},
+{0x027A,0x027A,UNI_LOWER},
+{0x027B,0x027B,UNI_LOWER},
+{0x027C,0x027C,UNI_LOWER},
+{0x027D,0x027D,UNI_LOWER},
+{0x027E,0x027E,UNI_LOWER},
+{0x027F,0x027F,UNI_LOWER},
+{0x0280,0x01A6,UNI_LOWER},
+{0x0281,0x0281,UNI_LOWER},
+{0x0282,0x0282,UNI_LOWER},
+{0x0283,0x01A9,UNI_LOWER},
+{0x0284,0x0284,UNI_LOWER},
+{0x0285,0x0285,UNI_LOWER},
+{0x0286,0x0286,UNI_LOWER},
+{0x0287,0x0287,UNI_LOWER},
+{0x0288,0x01AE,UNI_LOWER},
+{0x0289,0x0289,UNI_LOWER},
+{0x028A,0x01B1,UNI_LOWER},
+{0x028B,0x01B2,UNI_LOWER},
+{0x028C,0x028C,UNI_LOWER},
+{0x028D,0x028D,UNI_LOWER},
+{0x028E,0x028E,UNI_LOWER},
+{0x028F,0x028F,UNI_LOWER},
+{0x0290,0x0290,UNI_LOWER},
+{0x0291,0x0291,UNI_LOWER},
+{0x0292,0x01B7,UNI_LOWER},
+{0x0293,0x0293,UNI_LOWER},
+{0x0294,0x0294,UNI_LOWER},
+{0x0295,0x0295,UNI_LOWER},
+{0x0296,0x0296,UNI_LOWER},
+{0x0297,0x0297,UNI_LOWER},
+{0x0298,0x0298,UNI_LOWER},
+{0x0299,0x0299,UNI_LOWER},
+{0x029A,0x029A,UNI_LOWER},
+{0x029B,0x029B,UNI_LOWER},
+{0x029C,0x029C,UNI_LOWER},
+{0x029D,0x029D,UNI_LOWER},
+{0x029E,0x029E,UNI_LOWER},
+{0x029F,0x029F,UNI_LOWER},
+{0x02A0,0x02A0,UNI_LOWER},
+{0x02A1,0x02A1,UNI_LOWER},
+{0x02A2,0x02A2,UNI_LOWER},
+{0x02A3,0x02A3,UNI_LOWER},
+{0x02A4,0x02A4,UNI_LOWER},
+{0x02A5,0x02A5,UNI_LOWER},
+{0x02A6,0x02A6,UNI_LOWER},
+{0x02A7,0x02A7,UNI_LOWER},
+{0x02A8,0x02A8,UNI_LOWER},
+{0x02A9,0x02A9,UNI_LOWER},
+{0x02AA,0x02AA,UNI_LOWER},
+{0x02AB,0x02AB,UNI_LOWER},
+{0x02AC,0x02AC,UNI_LOWER},
+{0x02AD,0x02AD,UNI_LOWER},
+{0x02AE,0x02AE,0},
+{0x02AF,0x02AF,0},
+{0x02B0,0x02B0,0},
+{0x02B1,0x02B1,0},
+{0x02B2,0x02B2,0},
+{0x02B3,0x02B3,0},
+{0x02B4,0x02B4,0},
+{0x02B5,0x02B5,0},
+{0x02B6,0x02B6,0},
+{0x02B7,0x02B7,0},
+{0x02B8,0x02B8,0},
+{0x02B9,0x02B9,0},
+{0x02BA,0x02BA,0},
+{0x02BB,0x02BB,0},
+{0x02BC,0x02BC,0},
+{0x02BD,0x02BD,0},
+{0x02BE,0x02BE,0},
+{0x02BF,0x02BF,0},
+{0x02C0,0x02C0,0},
+{0x02C1,0x02C1,0},
+{0x02C2,0x02C2,0},
+{0x02C3,0x02C3,0},
+{0x02C4,0x02C4,0},
+{0x02C5,0x02C5,0},
+{0x02C6,0x02C6,0},
+{0x02C7,0x02C7,0},
+{0x02C8,0x02C8,0},
+{0x02C9,0x02C9,0},
+{0x02CA,0x02CA,0},
+{0x02CB,0x02CB,0},
+{0x02CC,0x02CC,0},
+{0x02CD,0x02CD,0},
+{0x02CE,0x02CE,0},
+{0x02CF,0x02CF,0},
+{0x02D0,0x02D0,0},
+{0x02D1,0x02D1,0},
+{0x02D2,0x02D2,0},
+{0x02D3,0x02D3,0},
+{0x02D4,0x02D4,0},
+{0x02D5,0x02D5,0},
+{0x02D6,0x02D6,0},
+{0x02D7,0x02D7,0},
+{0x02D8,0x02D8,0},
+{0x02D9,0x02D9,0},
+{0x02DA,0x02DA,0},
+{0x02DB,0x02DB,0},
+{0x02DC,0x02DC,0},
+{0x02DD,0x02DD,0},
+{0x02DE,0x02DE,0},
+{0x02DF,0x02DF,0},
+{0x02E0,0x02E0,0},
+{0x02E1,0x02E1,0},
+{0x02E2,0x02E2,0},
+{0x02E3,0x02E3,0},
+{0x02E4,0x02E4,0},
+{0x02E5,0x02E5,0},
+{0x02E6,0x02E6,0},
+{0x02E7,0x02E7,0},
+{0x02E8,0x02E8,0},
+{0x02E9,0x02E9,0},
+{0x02EA,0x02EA,0},
+{0x02EB,0x02EB,0},
+{0x02EC,0x02EC,0},
+{0x02ED,0x02ED,0},
+{0x02EE,0x02EE,0},
+{0x02EF,0x02EF,0},
+{0x02F0,0x02F0,0},
+{0x02F1,0x02F1,0},
+{0x02F2,0x02F2,0},
+{0x02F3,0x02F3,0},
+{0x02F4,0x02F4,0},
+{0x02F5,0x02F5,0},
+{0x02F6,0x02F6,0},
+{0x02F7,0x02F7,0},
+{0x02F8,0x02F8,0},
+{0x02F9,0x02F9,0},
+{0x02FA,0x02FA,0},
+{0x02FB,0x02FB,0},
+{0x02FC,0x02FC,0},
+{0x02FD,0x02FD,0},
+{0x02FE,0x02FE,0},
+{0x02FF,0x02FF,0},
+{0x0300,0x0300,0},
+{0x0301,0x0301,0},
+{0x0302,0x0302,0},
+{0x0303,0x0303,0},
+{0x0304,0x0304,0},
+{0x0305,0x0305,0},
+{0x0306,0x0306,0},
+{0x0307,0x0307,0},
+{0x0308,0x0308,0},
+{0x0309,0x0309,0},
+{0x030A,0x030A,0},
+{0x030B,0x030B,0},
+{0x030C,0x030C,0},
+{0x030D,0x030D,0},
+{0x030E,0x030E,0},
+{0x030F,0x030F,0},
+{0x0310,0x0310,0},
+{0x0311,0x0311,0},
+{0x0312,0x0312,0},
+{0x0313,0x0313,0},
+{0x0314,0x0314,0},
+{0x0315,0x0315,0},
+{0x0316,0x0316,0},
+{0x0317,0x0317,0},
+{0x0318,0x0318,0},
+{0x0319,0x0319,0},
+{0x031A,0x031A,0},
+{0x031B,0x031B,0},
+{0x031C,0x031C,0},
+{0x031D,0x031D,0},
+{0x031E,0x031E,0},
+{0x031F,0x031F,0},
+{0x0320,0x0320,0},
+{0x0321,0x0321,0},
+{0x0322,0x0322,0},
+{0x0323,0x0323,0},
+{0x0324,0x0324,0},
+{0x0325,0x0325,0},
+{0x0326,0x0326,0},
+{0x0327,0x0327,0},
+{0x0328,0x0328,0},
+{0x0329,0x0329,0},
+{0x032A,0x032A,0},
+{0x032B,0x032B,0},
+{0x032C,0x032C,0},
+{0x032D,0x032D,0},
+{0x032E,0x032E,0},
+{0x032F,0x032F,0},
+{0x0330,0x0330,0},
+{0x0331,0x0331,0},
+{0x0332,0x0332,0},
+{0x0333,0x0333,0},
+{0x0334,0x0334,0},
+{0x0335,0x0335,0},
+{0x0336,0x0336,0},
+{0x0337,0x0337,0},
+{0x0338,0x0338,0},
+{0x0339,0x0339,0},
+{0x033A,0x033A,0},
+{0x033B,0x033B,0},
+{0x033C,0x033C,0},
+{0x033D,0x033D,0},
+{0x033E,0x033E,0},
+{0x033F,0x033F,0},
+{0x0340,0x0340,0},
+{0x0341,0x0341,0},
+{0x0342,0x0342,0},
+{0x0343,0x0343,0},
+{0x0344,0x0344,0},
+{0x0345,0x0399,0},
+{0x0346,0x0346,0},
+{0x0347,0x0347,0},
+{0x0348,0x0348,0},
+{0x0349,0x0349,0},
+{0x034A,0x034A,0},
+{0x034B,0x034B,0},
+{0x034C,0x034C,0},
+{0x034D,0x034D,0},
+{0x034E,0x034E,0},
+{0x034F,0x034F,0},
+{0x0350,0x0350,0},
+{0x0351,0x0351,0},
+{0x0352,0x0352,0},
+{0x0353,0x0353,0},
+{0x0354,0x0354,0},
+{0x0355,0x0355,0},
+{0x0356,0x0356,0},
+{0x0357,0x0357,0},
+{0x0358,0x0358,0},
+{0x0359,0x0359,0},
+{0x035A,0x035A,0},
+{0x035B,0x035B,0},
+{0x035C,0x035C,0},
+{0x035D,0x035D,0},
+{0x035E,0x035E,0},
+{0x035F,0x035F,0},
+{0x0360,0x0360,0},
+{0x0361,0x0361,0},
+{0x0362,0x0362,0},
+{0x0363,0x0363,0},
+{0x0364,0x0364,0},
+{0x0365,0x0365,0},
+{0x0366,0x0366,0},
+{0x0367,0x0367,0},
+{0x0368,0x0368,0},
+{0x0369,0x0369,0},
+{0x036A,0x036A,0},
+{0x036B,0x036B,0},
+{0x036C,0x036C,0},
+{0x036D,0x036D,0},
+{0x036E,0x036E,0},
+{0x036F,0x036F,0},
+{0x0370,0x0370,0},
+{0x0371,0x0371,0},
+{0x0372,0x0372,0},
+{0x0373,0x0373,0},
+{0x0374,0x0374,0},
+{0x0375,0x0375,0},
+{0x0376,0x0376,0},
+{0x0377,0x0377,0},
+{0x0378,0x0378,0},
+{0x0379,0x0379,0},
+{0x037A,0x037A,0},
+{0x037B,0x037B,0},
+{0x037C,0x037C,0},
+{0x037D,0x037D,0},
+{0x037E,0x037E,0},
+{0x037F,0x037F,0},
+{0x0380,0x0380,0},
+{0x0381,0x0381,0},
+{0x0382,0x0382,0},
+{0x0383,0x0383,0},
+{0x0384,0x0384,0},
+{0x0385,0x0385,0},
+{0x03AC,0x0386,UNI_UPPER},
+{0x0387,0x0387,0},
+{0x03AD,0x0388,UNI_UPPER},
+{0x03AE,0x0389,UNI_UPPER},
+{0x03AF,0x038A,UNI_UPPER},
+{0x038B,0x038B,0},
+{0x03CC,0x038C,UNI_UPPER},
+{0x038D,0x038D,0},
+{0x03CD,0x038E,UNI_UPPER},
+{0x03CE,0x038F,UNI_UPPER},
+{0x0390,0x0390,UNI_LOWER},
+{0x03B1,0x0391,UNI_UPPER},
+{0x03B2,0x0392,UNI_UPPER},
+{0x03B3,0x0393,UNI_UPPER},
+{0x03B4,0x0394,UNI_UPPER},
+{0x03B5,0x0395,UNI_UPPER},
+{0x03B6,0x0396,UNI_UPPER},
+{0x03B7,0x0397,UNI_UPPER},
+{0x03B8,0x0398,UNI_UPPER},
+{0x03B9,0x0399,UNI_UPPER},
+{0x03BA,0x039A,UNI_UPPER},
+{0x03BB,0x039B,UNI_UPPER},
+{0x03BC,0x039C,UNI_UPPER},
+{0x03BD,0x039D,UNI_UPPER},
+{0x03BE,0x039E,UNI_UPPER},
+{0x03BF,0x039F,UNI_UPPER},
+{0x03C0,0x03A0,UNI_UPPER},
+{0x03C1,0x03A1,UNI_UPPER},
+{0x03A2,0x03A2,0},
+{0x03C3,0x03A3,UNI_UPPER},
+{0x03C4,0x03A4,UNI_UPPER},
+{0x03C5,0x03A5,UNI_UPPER},
+{0x03C6,0x03A6,UNI_UPPER},
+{0x03C7,0x03A7,UNI_UPPER},
+{0x03C8,0x03A8,UNI_UPPER},
+{0x03C9,0x03A9,UNI_UPPER},
+{0x03CA,0x03AA,UNI_UPPER},
+{0x03CB,0x03AB,UNI_UPPER},
+{0x03AC,0x0386,UNI_LOWER},
+{0x03AD,0x0388,UNI_LOWER},
+{0x03AE,0x0389,UNI_LOWER},
+{0x03AF,0x038A,UNI_LOWER},
+{0x03B0,0x03B0,UNI_LOWER},
+{0x03B1,0x0391,UNI_LOWER},
+{0x03B2,0x0392,UNI_LOWER},
+{0x03B3,0x0393,UNI_LOWER},
+{0x03B4,0x0394,UNI_LOWER},
+{0x03B5,0x0395,UNI_LOWER},
+{0x03B6,0x0396,UNI_LOWER},
+{0x03B7,0x0397,UNI_LOWER},
+{0x03B8,0x0398,UNI_LOWER},
+{0x03B9,0x0399,UNI_LOWER},
+{0x03BA,0x039A,UNI_LOWER},
+{0x03BB,0x039B,UNI_LOWER},
+{0x03BC,0x039C,UNI_LOWER},
+{0x03BD,0x039D,UNI_LOWER},
+{0x03BE,0x039E,UNI_LOWER},
+{0x03BF,0x039F,UNI_LOWER},
+{0x03C0,0x03A0,UNI_LOWER},
+{0x03C1,0x03A1,UNI_LOWER},
+{0x03C2,0x03A3,UNI_LOWER},
+{0x03C3,0x03A3,UNI_LOWER},
+{0x03C4,0x03A4,UNI_LOWER},
+{0x03C5,0x03A5,UNI_LOWER},
+{0x03C6,0x03A6,UNI_LOWER},
+{0x03C7,0x03A7,UNI_LOWER},
+{0x03C8,0x03A8,UNI_LOWER},
+{0x03C9,0x03A9,UNI_LOWER},
+{0x03CA,0x03AA,UNI_LOWER},
+{0x03CB,0x03AB,UNI_LOWER},
+{0x03CC,0x038C,UNI_LOWER},
+{0x03CD,0x038E,UNI_LOWER},
+{0x03CE,0x038F,UNI_LOWER},
+{0x03CF,0x03CF,0},
+{0x03D0,0x0392,UNI_LOWER},
+{0x03D1,0x0398,UNI_LOWER},
+{0x03D2,0x03D2,UNI_UPPER},
+{0x03D3,0x03D3,UNI_UPPER},
+{0x03D4,0x03D4,UNI_UPPER},
+{0x03D5,0x03A6,UNI_LOWER},
+{0x03D6,0x03A0,UNI_LOWER},
+{0x03D7,0x03D7,UNI_LOWER},
+{0x03D8,0x03D8,0},
+{0x03D9,0x03D9,0},
+{0x03DB,0x03DA,UNI_UPPER},
+{0x03DB,0x03DA,UNI_LOWER},
+{0x03DD,0x03DC,UNI_UPPER},
+{0x03DD,0x03DC,UNI_LOWER},
+{0x03DF,0x03DE,UNI_UPPER},
+{0x03DF,0x03DE,UNI_LOWER},
+{0x03E1,0x03E0,UNI_UPPER},
+{0x03E1,0x03E0,UNI_LOWER},
+{0x03E3,0x03E2,UNI_UPPER},
+{0x03E3,0x03E2,UNI_LOWER},
+{0x03E5,0x03E4,UNI_UPPER},
+{0x03E5,0x03E4,UNI_LOWER},
+{0x03E7,0x03E6,UNI_UPPER},
+{0x03E7,0x03E6,UNI_LOWER},
+{0x03E9,0x03E8,UNI_UPPER},
+{0x03E9,0x03E8,UNI_LOWER},
+{0x03EB,0x03EA,UNI_UPPER},
+{0x03EB,0x03EA,UNI_LOWER},
+{0x03ED,0x03EC,UNI_UPPER},
+{0x03ED,0x03EC,UNI_LOWER},
+{0x03EF,0x03EE,UNI_UPPER},
+{0x03EF,0x03EE,UNI_LOWER},
+{0x03F0,0x039A,UNI_LOWER},
+{0x03F1,0x03A1,UNI_LOWER},
+{0x03F2,0x03A3,UNI_LOWER},
+{0x03F3,0x03F3,UNI_LOWER},
+{0x03F4,0x03F4,0},
+{0x03F5,0x03F5,0},
+{0x03F6,0x03F6,0},
+{0x03F7,0x03F7,0},
+{0x03F8,0x03F8,0},
+{0x03F9,0x03F9,0},
+{0x03FA,0x03FA,0},
+{0x03FB,0x03FB,0},
+{0x03FC,0x03FC,0},
+{0x03FD,0x03FD,0},
+{0x03FE,0x03FE,0},
+{0x03FF,0x03FF,0},
+{0x0450,0x0400,UNI_UPPER},
+{0x0451,0x0401,UNI_UPPER},
+{0x0452,0x0402,UNI_UPPER},
+{0x0453,0x0403,UNI_UPPER},
+{0x0454,0x0404,UNI_UPPER},
+{0x0455,0x0405,UNI_UPPER},
+{0x0456,0x0406,UNI_UPPER},
+{0x0457,0x0407,UNI_UPPER},
+{0x0458,0x0408,UNI_UPPER},
+{0x0459,0x0409,UNI_UPPER},
+{0x045A,0x040A,UNI_UPPER},
+{0x045B,0x040B,UNI_UPPER},
+{0x045C,0x040C,UNI_UPPER},
+{0x045D,0x040D,UNI_UPPER},
+{0x045E,0x040E,UNI_UPPER},
+{0x045F,0x040F,UNI_UPPER},
+{0x0430,0x0410,UNI_UPPER},
+{0x0431,0x0411,UNI_UPPER},
+{0x0432,0x0412,UNI_UPPER},
+{0x0433,0x0413,UNI_UPPER},
+{0x0434,0x0414,UNI_UPPER},
+{0x0435,0x0415,UNI_UPPER},
+{0x0436,0x0416,UNI_UPPER},
+{0x0437,0x0417,UNI_UPPER},
+{0x0438,0x0418,UNI_UPPER},
+{0x0439,0x0419,UNI_UPPER},
+{0x043A,0x041A,UNI_UPPER},
+{0x043B,0x041B,UNI_UPPER},
+{0x043C,0x041C,UNI_UPPER},
+{0x043D,0x041D,UNI_UPPER},
+{0x043E,0x041E,UNI_UPPER},
+{0x043F,0x041F,UNI_UPPER},
+{0x0440,0x0420,UNI_UPPER},
+{0x0441,0x0421,UNI_UPPER},
+{0x0442,0x0422,UNI_UPPER},
+{0x0443,0x0423,UNI_UPPER},
+{0x0444,0x0424,UNI_UPPER},
+{0x0445,0x0425,UNI_UPPER},
+{0x0446,0x0426,UNI_UPPER},
+{0x0447,0x0427,UNI_UPPER},
+{0x0448,0x0428,UNI_UPPER},
+{0x0449,0x0429,UNI_UPPER},
+{0x044A,0x042A,UNI_UPPER},
+{0x044B,0x042B,UNI_UPPER},
+{0x044C,0x042C,UNI_UPPER},
+{0x044D,0x042D,UNI_UPPER},
+{0x044E,0x042E,UNI_UPPER},
+{0x044F,0x042F,UNI_UPPER},
+{0x0430,0x0410,UNI_LOWER},
+{0x0431,0x0411,UNI_LOWER},
+{0x0432,0x0412,UNI_LOWER},
+{0x0433,0x0413,UNI_LOWER},
+{0x0434,0x0414,UNI_LOWER},
+{0x0435,0x0415,UNI_LOWER},
+{0x0436,0x0416,UNI_LOWER},
+{0x0437,0x0417,UNI_LOWER},
+{0x0438,0x0418,UNI_LOWER},
+{0x0439,0x0419,UNI_LOWER},
+{0x043A,0x041A,UNI_LOWER},
+{0x043B,0x041B,UNI_LOWER},
+{0x043C,0x041C,UNI_LOWER},
+{0x043D,0x041D,UNI_LOWER},
+{0x043E,0x041E,UNI_LOWER},
+{0x043F,0x041F,UNI_LOWER},
+{0x0440,0x0420,UNI_LOWER},
+{0x0441,0x0421,UNI_LOWER},
+{0x0442,0x0422,UNI_LOWER},
+{0x0443,0x0423,UNI_LOWER},
+{0x0444,0x0424,UNI_LOWER},
+{0x0445,0x0425,UNI_LOWER},
+{0x0446,0x0426,UNI_LOWER},
+{0x0447,0x0427,UNI_LOWER},
+{0x0448,0x0428,UNI_LOWER},
+{0x0449,0x0429,UNI_LOWER},
+{0x044A,0x042A,UNI_LOWER},
+{0x044B,0x042B,UNI_LOWER},
+{0x044C,0x042C,UNI_LOWER},
+{0x044D,0x042D,UNI_LOWER},
+{0x044E,0x042E,UNI_LOWER},
+{0x044F,0x042F,UNI_LOWER},
+{0x0450,0x0400,UNI_LOWER},
+{0x0451,0x0401,UNI_LOWER},
+{0x0452,0x0402,UNI_LOWER},
+{0x0453,0x0403,UNI_LOWER},
+{0x0454,0x0404,UNI_LOWER},
+{0x0455,0x0405,UNI_LOWER},
+{0x0456,0x0406,UNI_LOWER},
+{0x0457,0x0407,UNI_LOWER},
+{0x0458,0x0408,UNI_LOWER},
+{0x0459,0x0409,UNI_LOWER},
+{0x045A,0x040A,UNI_LOWER},
+{0x045B,0x040B,UNI_LOWER},
+{0x045C,0x040C,UNI_LOWER},
+{0x045D,0x040D,UNI_LOWER},
+{0x045E,0x040E,UNI_LOWER},
+{0x045F,0x040F,UNI_LOWER},
+{0x0461,0x0460,UNI_UPPER},
+{0x0461,0x0460,UNI_LOWER},
+{0x0463,0x0462,UNI_UPPER},
+{0x0463,0x0462,UNI_LOWER},
+{0x0465,0x0464,UNI_UPPER},
+{0x0465,0x0464,UNI_LOWER},
+{0x0467,0x0466,UNI_UPPER},
+{0x0467,0x0466,UNI_LOWER},
+{0x0469,0x0468,UNI_UPPER},
+{0x0469,0x0468,UNI_LOWER},
+{0x046B,0x046A,UNI_UPPER},
+{0x046B,0x046A,UNI_LOWER},
+{0x046D,0x046C,UNI_UPPER},
+{0x046D,0x046C,UNI_LOWER},
+{0x046F,0x046E,UNI_UPPER},
+{0x046F,0x046E,UNI_LOWER},
+{0x0471,0x0470,UNI_UPPER},
+{0x0471,0x0470,UNI_LOWER},
+{0x0473,0x0472,UNI_UPPER},
+{0x0473,0x0472,UNI_LOWER},
+{0x0475,0x0474,UNI_UPPER},
+{0x0475,0x0474,UNI_LOWER},
+{0x0477,0x0476,UNI_UPPER},
+{0x0477,0x0476,UNI_LOWER},
+{0x0479,0x0478,UNI_UPPER},
+{0x0479,0x0478,UNI_LOWER},
+{0x047B,0x047A,UNI_UPPER},
+{0x047B,0x047A,UNI_LOWER},
+{0x047D,0x047C,UNI_UPPER},
+{0x047D,0x047C,UNI_LOWER},
+{0x047F,0x047E,UNI_UPPER},
+{0x047F,0x047E,UNI_LOWER},
+{0x0481,0x0480,UNI_UPPER},
+{0x0481,0x0480,UNI_LOWER},
+{0x0482,0x0482,0},
+{0x0483,0x0483,0},
+{0x0484,0x0484,0},
+{0x0485,0x0485,0},
+{0x0486,0x0486,0},
+{0x0487,0x0487,0},
+{0x0488,0x0488,0},
+{0x0489,0x0489,0},
+{0x048A,0x048A,0},
+{0x048B,0x048B,0},
+{0x048D,0x048C,UNI_UPPER},
+{0x048D,0x048C,UNI_LOWER},
+{0x048F,0x048E,UNI_UPPER},
+{0x048F,0x048E,UNI_LOWER},
+{0x0491,0x0490,UNI_UPPER},
+{0x0491,0x0490,UNI_LOWER},
+{0x0493,0x0492,UNI_UPPER},
+{0x0493,0x0492,UNI_LOWER},
+{0x0495,0x0494,UNI_UPPER},
+{0x0495,0x0494,UNI_LOWER},
+{0x0497,0x0496,UNI_UPPER},
+{0x0497,0x0496,UNI_LOWER},
+{0x0499,0x0498,UNI_UPPER},
+{0x0499,0x0498,UNI_LOWER},
+{0x049B,0x049A,UNI_UPPER},
+{0x049B,0x049A,UNI_LOWER},
+{0x049D,0x049C,UNI_UPPER},
+{0x049D,0x049C,UNI_LOWER},
+{0x049F,0x049E,UNI_UPPER},
+{0x049F,0x049E,UNI_LOWER},
+{0x04A1,0x04A0,UNI_UPPER},
+{0x04A1,0x04A0,UNI_LOWER},
+{0x04A3,0x04A2,UNI_UPPER},
+{0x04A3,0x04A2,UNI_LOWER},
+{0x04A5,0x04A4,UNI_UPPER},
+{0x04A5,0x04A4,UNI_LOWER},
+{0x04A7,0x04A6,UNI_UPPER},
+{0x04A7,0x04A6,UNI_LOWER},
+{0x04A9,0x04A8,UNI_UPPER},
+{0x04A9,0x04A8,UNI_LOWER},
+{0x04AB,0x04AA,UNI_UPPER},
+{0x04AB,0x04AA,UNI_LOWER},
+{0x04AD,0x04AC,UNI_UPPER},
+{0x04AD,0x04AC,UNI_LOWER},
+{0x04AF,0x04AE,UNI_UPPER},
+{0x04AF,0x04AE,UNI_LOWER},
+{0x04B1,0x04B0,UNI_UPPER},
+{0x04B1,0x04B0,UNI_LOWER},
+{0x04B3,0x04B2,UNI_UPPER},
+{0x04B3,0x04B2,UNI_LOWER},
+{0x04B5,0x04B4,UNI_UPPER},
+{0x04B5,0x04B4,UNI_LOWER},
+{0x04B7,0x04B6,UNI_UPPER},
+{0x04B7,0x04B6,UNI_LOWER},
+{0x04B9,0x04B8,UNI_UPPER},
+{0x04B9,0x04B8,UNI_LOWER},
+{0x04BB,0x04BA,UNI_UPPER},
+{0x04BB,0x04BA,UNI_LOWER},
+{0x04BD,0x04BC,UNI_UPPER},
+{0x04BD,0x04BC,UNI_LOWER},
+{0x04BF,0x04BE,UNI_UPPER},
+{0x04BF,0x04BE,UNI_LOWER},
+{0x04C0,0x04C0,UNI_UPPER},
+{0x04C2,0x04C1,UNI_UPPER},
+{0x04C2,0x04C1,UNI_LOWER},
+{0x04C4,0x04C3,UNI_UPPER},
+{0x04C4,0x04C3,UNI_LOWER},
+{0x04C5,0x04C5,0},
+{0x04C6,0x04C6,0},
+{0x04C8,0x04C7,UNI_UPPER},
+{0x04C8,0x04C7,UNI_LOWER},
+{0x04C9,0x04C9,0},
+{0x04CA,0x04CA,0},
+{0x04CC,0x04CB,UNI_UPPER},
+{0x04CC,0x04CB,UNI_LOWER},
+{0x04CD,0x04CD,0},
+{0x04CE,0x04CE,0},
+{0x04CF,0x04CF,0},
+{0x04D1,0x04D0,UNI_UPPER},
+{0x04D1,0x04D0,UNI_LOWER},
+{0x04D3,0x04D2,UNI_UPPER},
+{0x04D3,0x04D2,UNI_LOWER},
+{0x04D5,0x04D4,UNI_UPPER},
+{0x04D5,0x04D4,UNI_LOWER},
+{0x04D7,0x04D6,UNI_UPPER},
+{0x04D7,0x04D6,UNI_LOWER},
+{0x04D9,0x04D8,UNI_UPPER},
+{0x04D9,0x04D8,UNI_LOWER},
+{0x04DB,0x04DA,UNI_UPPER},
+{0x04DB,0x04DA,UNI_LOWER},
+{0x04DD,0x04DC,UNI_UPPER},
+{0x04DD,0x04DC,UNI_LOWER},
+{0x04DF,0x04DE,UNI_UPPER},
+{0x04DF,0x04DE,UNI_LOWER},
+{0x04E1,0x04E0,UNI_UPPER},
+{0x04E1,0x04E0,UNI_LOWER},
+{0x04E3,0x04E2,UNI_UPPER},
+{0x04E3,0x04E2,UNI_LOWER},
+{0x04E5,0x04E4,UNI_UPPER},
+{0x04E5,0x04E4,UNI_LOWER},
+{0x04E7,0x04E6,UNI_UPPER},
+{0x04E7,0x04E6,UNI_LOWER},
+{0x04E9,0x04E8,UNI_UPPER},
+{0x04E9,0x04E8,UNI_LOWER},
+{0x04EB,0x04EA,UNI_UPPER},
+{0x04EB,0x04EA,UNI_LOWER},
+{0x04ED,0x04EC,UNI_UPPER},
+{0x04ED,0x04EC,UNI_LOWER},
+{0x04EF,0x04EE,UNI_UPPER},
+{0x04EF,0x04EE,UNI_LOWER},
+{0x04F1,0x04F0,UNI_UPPER},
+{0x04F1,0x04F0,UNI_LOWER},
+{0x04F3,0x04F2,UNI_UPPER},
+{0x04F3,0x04F2,UNI_LOWER},
+{0x04F5,0x04F4,UNI_UPPER},
+{0x04F5,0x04F4,UNI_LOWER},
+{0x04F6,0x04F6,0},
+{0x04F7,0x04F7,0},
+{0x04F9,0x04F8,UNI_UPPER},
+{0x04F9,0x04F8,UNI_LOWER},
+{0x04FA,0x04FA,0},
+{0x04FB,0x04FB,0},
+{0x04FC,0x04FC,0},
+{0x04FD,0x04FD,0},
+{0x04FE,0x04FE,0},
+{0x04FF,0x04FF,0},
+{0x0500,0x0500,0},
+{0x0501,0x0501,0},
+{0x0502,0x0502,0},
+{0x0503,0x0503,0},
+{0x0504,0x0504,0},
+{0x0505,0x0505,0},
+{0x0506,0x0506,0},
+{0x0507,0x0507,0},
+{0x0508,0x0508,0},
+{0x0509,0x0509,0},
+{0x050A,0x050A,0},
+{0x050B,0x050B,0},
+{0x050C,0x050C,0},
+{0x050D,0x050D,0},
+{0x050E,0x050E,0},
+{0x050F,0x050F,0},
+{0x0510,0x0510,0},
+{0x0511,0x0511,0},
+{0x0512,0x0512,0},
+{0x0513,0x0513,0},
+{0x0514,0x0514,0},
+{0x0515,0x0515,0},
+{0x0516,0x0516,0},
+{0x0517,0x0517,0},
+{0x0518,0x0518,0},
+{0x0519,0x0519,0},
+{0x051A,0x051A,0},
+{0x051B,0x051B,0},
+{0x051C,0x051C,0},
+{0x051D,0x051D,0},
+{0x051E,0x051E,0},
+{0x051F,0x051F,0},
+{0x0520,0x0520,0},
+{0x0521,0x0521,0},
+{0x0522,0x0522,0},
+{0x0523,0x0523,0},
+{0x0524,0x0524,0},
+{0x0525,0x0525,0},
+{0x0526,0x0526,0},
+{0x0527,0x0527,0},
+{0x0528,0x0528,0},
+{0x0529,0x0529,0},
+{0x052A,0x052A,0},
+{0x052B,0x052B,0},
+{0x052C,0x052C,0},
+{0x052D,0x052D,0},
+{0x052E,0x052E,0},
+{0x052F,0x052F,0},
+{0x0530,0x0530,0},
+{0x0561,0x0531,UNI_UPPER},
+{0x0562,0x0532,UNI_UPPER},
+{0x0563,0x0533,UNI_UPPER},
+{0x0564,0x0534,UNI_UPPER},
+{0x0565,0x0535,UNI_UPPER},
+{0x0566,0x0536,UNI_UPPER},
+{0x0567,0x0537,UNI_UPPER},
+{0x0568,0x0538,UNI_UPPER},
+{0x0569,0x0539,UNI_UPPER},
+{0x056A,0x053A,UNI_UPPER},
+{0x056B,0x053B,UNI_UPPER},
+{0x056C,0x053C,UNI_UPPER},
+{0x056D,0x053D,UNI_UPPER},
+{0x056E,0x053E,UNI_UPPER},
+{0x056F,0x053F,UNI_UPPER},
+{0x0570,0x0540,UNI_UPPER},
+{0x0571,0x0541,UNI_UPPER},
+{0x0572,0x0542,UNI_UPPER},
+{0x0573,0x0543,UNI_UPPER},
+{0x0574,0x0544,UNI_UPPER},
+{0x0575,0x0545,UNI_UPPER},
+{0x0576,0x0546,UNI_UPPER},
+{0x0577,0x0547,UNI_UPPER},
+{0x0578,0x0548,UNI_UPPER},
+{0x0579,0x0549,UNI_UPPER},
+{0x057A,0x054A,UNI_UPPER},
+{0x057B,0x054B,UNI_UPPER},
+{0x057C,0x054C,UNI_UPPER},
+{0x057D,0x054D,UNI_UPPER},
+{0x057E,0x054E,UNI_UPPER},
+{0x057F,0x054F,UNI_UPPER},
+{0x0580,0x0550,UNI_UPPER},
+{0x0581,0x0551,UNI_UPPER},
+{0x0582,0x0552,UNI_UPPER},
+{0x0583,0x0553,UNI_UPPER},
+{0x0584,0x0554,UNI_UPPER},
+{0x0585,0x0555,UNI_UPPER},
+{0x0586,0x0556,UNI_UPPER},
+{0x0557,0x0557,0},
+{0x0558,0x0558,0},
+{0x0559,0x0559,0},
+{0x055A,0x055A,0},
+{0x055B,0x055B,0},
+{0x055C,0x055C,0},
+{0x055D,0x055D,0},
+{0x055E,0x055E,0},
+{0x055F,0x055F,0},
+{0x0560,0x0560,0},
+{0x0561,0x0531,UNI_LOWER},
+{0x0562,0x0532,UNI_LOWER},
+{0x0563,0x0533,UNI_LOWER},
+{0x0564,0x0534,UNI_LOWER},
+{0x0565,0x0535,UNI_LOWER},
+{0x0566,0x0536,UNI_LOWER},
+{0x0567,0x0537,UNI_LOWER},
+{0x0568,0x0538,UNI_LOWER},
+{0x0569,0x0539,UNI_LOWER},
+{0x056A,0x053A,UNI_LOWER},
+{0x056B,0x053B,UNI_LOWER},
+{0x056C,0x053C,UNI_LOWER},
+{0x056D,0x053D,UNI_LOWER},
+{0x056E,0x053E,UNI_LOWER},
+{0x056F,0x053F,UNI_LOWER},
+{0x0570,0x0540,UNI_LOWER},
+{0x0571,0x0541,UNI_LOWER},
+{0x0572,0x0542,UNI_LOWER},
+{0x0573,0x0543,UNI_LOWER},
+{0x0574,0x0544,UNI_LOWER},
+{0x0575,0x0545,UNI_LOWER},
+{0x0576,0x0546,UNI_LOWER},
+{0x0577,0x0547,UNI_LOWER},
+{0x0578,0x0548,UNI_LOWER},
+{0x0579,0x0549,UNI_LOWER},
+{0x057A,0x054A,UNI_LOWER},
+{0x057B,0x054B,UNI_LOWER},
+{0x057C,0x054C,UNI_LOWER},
+{0x057D,0x054D,UNI_LOWER},
+{0x057E,0x054E,UNI_LOWER},
+{0x057F,0x054F,UNI_LOWER},
+{0x0580,0x0550,UNI_LOWER},
+{0x0581,0x0551,UNI_LOWER},
+{0x0582,0x0552,UNI_LOWER},
+{0x0583,0x0553,UNI_LOWER},
+{0x0584,0x0554,UNI_LOWER},
+{0x0585,0x0555,UNI_LOWER},
+{0x0586,0x0556,UNI_LOWER},
+{0x0587,0x0587,UNI_LOWER},
+{0x0588,0x0588,0},
+{0x0589,0x0589,0},
+{0x058A,0x058A,0},
+{0x058B,0x058B,0},
+{0x058C,0x058C,0},
+{0x058D,0x058D,0},
+{0x058E,0x058E,0},
+{0x058F,0x058F,0},
+{0x0590,0x0590,0},
+{0x0591,0x0591,0},
+{0x0592,0x0592,0},
+{0x0593,0x0593,0},
+{0x0594,0x0594,0},
+{0x0595,0x0595,0},
+{0x0596,0x0596,0},
+{0x0597,0x0597,0},
+{0x0598,0x0598,0},
+{0x0599,0x0599,0},
+{0x059A,0x059A,0},
+{0x059B,0x059B,0},
+{0x059C,0x059C,0},
+{0x059D,0x059D,0},
+{0x059E,0x059E,0},
+{0x059F,0x059F,0},
+{0x05A0,0x05A0,0},
+{0x05A1,0x05A1,0},
+{0x05A2,0x05A2,0},
+{0x05A3,0x05A3,0},
+{0x05A4,0x05A4,0},
+{0x05A5,0x05A5,0},
+{0x05A6,0x05A6,0},
+{0x05A7,0x05A7,0},
+{0x05A8,0x05A8,0},
+{0x05A9,0x05A9,0},
+{0x05AA,0x05AA,0},
+{0x05AB,0x05AB,0},
+{0x05AC,0x05AC,0},
+{0x05AD,0x05AD,0},
+{0x05AE,0x05AE,0},
+{0x05AF,0x05AF,0},
+{0x05B0,0x05B0,0},
+{0x05B1,0x05B1,0},
+{0x05B2,0x05B2,0},
+{0x05B3,0x05B3,0},
+{0x05B4,0x05B4,0},
+{0x05B5,0x05B5,0},
+{0x05B6,0x05B6,0},
+{0x05B7,0x05B7,0},
+{0x05B8,0x05B8,0},
+{0x05B9,0x05B9,0},
+{0x05BA,0x05BA,0},
+{0x05BB,0x05BB,0},
+{0x05BC,0x05BC,0},
+{0x05BD,0x05BD,0},
+{0x05BE,0x05BE,0},
+{0x05BF,0x05BF,0},
+{0x05C0,0x05C0,0},
+{0x05C1,0x05C1,0},
+{0x05C2,0x05C2,0},
+{0x05C3,0x05C3,0},
+{0x05C4,0x05C4,0},
+{0x05C5,0x05C5,0},
+{0x05C6,0x05C6,0},
+{0x05C7,0x05C7,0},
+{0x05C8,0x05C8,0},
+{0x05C9,0x05C9,0},
+{0x05CA,0x05CA,0},
+{0x05CB,0x05CB,0},
+{0x05CC,0x05CC,0},
+{0x05CD,0x05CD,0},
+{0x05CE,0x05CE,0},
+{0x05CF,0x05CF,0},
+{0x05D0,0x05D0,0},
+{0x05D1,0x05D1,0},
+{0x05D2,0x05D2,0},
+{0x05D3,0x05D3,0},
+{0x05D4,0x05D4,0},
+{0x05D5,0x05D5,0},
+{0x05D6,0x05D6,0},
+{0x05D7,0x05D7,0},
+{0x05D8,0x05D8,0},
+{0x05D9,0x05D9,0},
+{0x05DA,0x05DA,0},
+{0x05DB,0x05DB,0},
+{0x05DC,0x05DC,0},
+{0x05DD,0x05DD,0},
+{0x05DE,0x05DE,0},
+{0x05DF,0x05DF,0},
+{0x05E0,0x05E0,0},
+{0x05E1,0x05E1,0},
+{0x05E2,0x05E2,0},
+{0x05E3,0x05E3,0},
+{0x05E4,0x05E4,0},
+{0x05E5,0x05E5,0},
+{0x05E6,0x05E6,0},
+{0x05E7,0x05E7,0},
+{0x05E8,0x05E8,0},
+{0x05E9,0x05E9,0},
+{0x05EA,0x05EA,0},
+{0x05EB,0x05EB,0},
+{0x05EC,0x05EC,0},
+{0x05ED,0x05ED,0},
+{0x05EE,0x05EE,0},
+{0x05EF,0x05EF,0},
+{0x05F0,0x05F0,0},
+{0x05F1,0x05F1,0},
+{0x05F2,0x05F2,0},
+{0x05F3,0x05F3,0},
+{0x05F4,0x05F4,0},
+{0x05F5,0x05F5,0},
+{0x05F6,0x05F6,0},
+{0x05F7,0x05F7,0},
+{0x05F8,0x05F8,0},
+{0x05F9,0x05F9,0},
+{0x05FA,0x05FA,0},
+{0x05FB,0x05FB,0},
+{0x05FC,0x05FC,0},
+{0x05FD,0x05FD,0},
+{0x05FE,0x05FE,0},
+{0x05FF,0x05FF,0},
+{0x0600,0x0600,0},
+{0x0601,0x0601,0},
+{0x0602,0x0602,0},
+{0x0603,0x0603,0},
+{0x0604,0x0604,0},
+{0x0605,0x0605,0},
+{0x0606,0x0606,0},
+{0x0607,0x0607,0},
+{0x0608,0x0608,0},
+{0x0609,0x0609,0},
+{0x060A,0x060A,0},
+{0x060B,0x060B,0},
+{0x060C,0x060C,0},
+{0x060D,0x060D,0},
+{0x060E,0x060E,0},
+{0x060F,0x060F,0},
+{0x0610,0x0610,0},
+{0x0611,0x0611,0},
+{0x0612,0x0612,0},
+{0x0613,0x0613,0},
+{0x0614,0x0614,0},
+{0x0615,0x0615,0},
+{0x0616,0x0616,0},
+{0x0617,0x0617,0},
+{0x0618,0x0618,0},
+{0x0619,0x0619,0},
+{0x061A,0x061A,0},
+{0x061B,0x061B,0},
+{0x061C,0x061C,0},
+{0x061D,0x061D,0},
+{0x061E,0x061E,0},
+{0x061F,0x061F,0},
+{0x0620,0x0620,0},
+{0x0621,0x0621,0},
+{0x0622,0x0622,0},
+{0x0623,0x0623,0},
+{0x0624,0x0624,0},
+{0x0625,0x0625,0},
+{0x0626,0x0626,0},
+{0x0627,0x0627,0},
+{0x0628,0x0628,0},
+{0x0629,0x0629,0},
+{0x062A,0x062A,0},
+{0x062B,0x062B,0},
+{0x062C,0x062C,0},
+{0x062D,0x062D,0},
+{0x062E,0x062E,0},
+{0x062F,0x062F,0},
+{0x0630,0x0630,0},
+{0x0631,0x0631,0},
+{0x0632,0x0632,0},
+{0x0633,0x0633,0},
+{0x0634,0x0634,0},
+{0x0635,0x0635,0},
+{0x0636,0x0636,0},
+{0x0637,0x0637,0},
+{0x0638,0x0638,0},
+{0x0639,0x0639,0},
+{0x063A,0x063A,0},
+{0x063B,0x063B,0},
+{0x063C,0x063C,0},
+{0x063D,0x063D,0},
+{0x063E,0x063E,0},
+{0x063F,0x063F,0},
+{0x0640,0x0640,0},
+{0x0641,0x0641,0},
+{0x0642,0x0642,0},
+{0x0643,0x0643,0},
+{0x0644,0x0644,0},
+{0x0645,0x0645,0},
+{0x0646,0x0646,0},
+{0x0647,0x0647,0},
+{0x0648,0x0648,0},
+{0x0649,0x0649,0},
+{0x064A,0x064A,0},
+{0x064B,0x064B,0},
+{0x064C,0x064C,0},
+{0x064D,0x064D,0},
+{0x064E,0x064E,0},
+{0x064F,0x064F,0},
+{0x0650,0x0650,0},
+{0x0651,0x0651,0},
+{0x0652,0x0652,0},
+{0x0653,0x0653,0},
+{0x0654,0x0654,0},
+{0x0655,0x0655,0},
+{0x0656,0x0656,0},
+{0x0657,0x0657,0},
+{0x0658,0x0658,0},
+{0x0659,0x0659,0},
+{0x065A,0x065A,0},
+{0x065B,0x065B,0},
+{0x065C,0x065C,0},
+{0x065D,0x065D,0},
+{0x065E,0x065E,0},
+{0x065F,0x065F,0},
+{0x0660,0x0660,0},
+{0x0661,0x0661,0},
+{0x0662,0x0662,0},
+{0x0663,0x0663,0},
+{0x0664,0x0664,0},
+{0x0665,0x0665,0},
+{0x0666,0x0666,0},
+{0x0667,0x0667,0},
+{0x0668,0x0668,0},
+{0x0669,0x0669,0},
+{0x066A,0x066A,0},
+{0x066B,0x066B,0},
+{0x066C,0x066C,0},
+{0x066D,0x066D,0},
+{0x066E,0x066E,0},
+{0x066F,0x066F,0},
+{0x0670,0x0670,0},
+{0x0671,0x0671,0},
+{0x0672,0x0672,0},
+{0x0673,0x0673,0},
+{0x0674,0x0674,0},
+{0x0675,0x0675,0},
+{0x0676,0x0676,0},
+{0x0677,0x0677,0},
+{0x0678,0x0678,0},
+{0x0679,0x0679,0},
+{0x067A,0x067A,0},
+{0x067B,0x067B,0},
+{0x067C,0x067C,0},
+{0x067D,0x067D,0},
+{0x067E,0x067E,0},
+{0x067F,0x067F,0},
+{0x0680,0x0680,0},
+{0x0681,0x0681,0},
+{0x0682,0x0682,0},
+{0x0683,0x0683,0},
+{0x0684,0x0684,0},
+{0x0685,0x0685,0},
+{0x0686,0x0686,0},
+{0x0687,0x0687,0},
+{0x0688,0x0688,0},
+{0x0689,0x0689,0},
+{0x068A,0x068A,0},
+{0x068B,0x068B,0},
+{0x068C,0x068C,0},
+{0x068D,0x068D,0},
+{0x068E,0x068E,0},
+{0x068F,0x068F,0},
+{0x0690,0x0690,0},
+{0x0691,0x0691,0},
+{0x0692,0x0692,0},
+{0x0693,0x0693,0},
+{0x0694,0x0694,0},
+{0x0695,0x0695,0},
+{0x0696,0x0696,0},
+{0x0697,0x0697,0},
+{0x0698,0x0698,0},
+{0x0699,0x0699,0},
+{0x069A,0x069A,0},
+{0x069B,0x069B,0},
+{0x069C,0x069C,0},
+{0x069D,0x069D,0},
+{0x069E,0x069E,0},
+{0x069F,0x069F,0},
+{0x06A0,0x06A0,0},
+{0x06A1,0x06A1,0},
+{0x06A2,0x06A2,0},
+{0x06A3,0x06A3,0},
+{0x06A4,0x06A4,0},
+{0x06A5,0x06A5,0},
+{0x06A6,0x06A6,0},
+{0x06A7,0x06A7,0},
+{0x06A8,0x06A8,0},
+{0x06A9,0x06A9,0},
+{0x06AA,0x06AA,0},
+{0x06AB,0x06AB,0},
+{0x06AC,0x06AC,0},
+{0x06AD,0x06AD,0},
+{0x06AE,0x06AE,0},
+{0x06AF,0x06AF,0},
+{0x06B0,0x06B0,0},
+{0x06B1,0x06B1,0},
+{0x06B2,0x06B2,0},
+{0x06B3,0x06B3,0},
+{0x06B4,0x06B4,0},
+{0x06B5,0x06B5,0},
+{0x06B6,0x06B6,0},
+{0x06B7,0x06B7,0},
+{0x06B8,0x06B8,0},
+{0x06B9,0x06B9,0},
+{0x06BA,0x06BA,0},
+{0x06BB,0x06BB,0},
+{0x06BC,0x06BC,0},
+{0x06BD,0x06BD,0},
+{0x06BE,0x06BE,0},
+{0x06BF,0x06BF,0},
+{0x06C0,0x06C0,0},
+{0x06C1,0x06C1,0},
+{0x06C2,0x06C2,0},
+{0x06C3,0x06C3,0},
+{0x06C4,0x06C4,0},
+{0x06C5,0x06C5,0},
+{0x06C6,0x06C6,0},
+{0x06C7,0x06C7,0},
+{0x06C8,0x06C8,0},
+{0x06C9,0x06C9,0},
+{0x06CA,0x06CA,0},
+{0x06CB,0x06CB,0},
+{0x06CC,0x06CC,0},
+{0x06CD,0x06CD,0},
+{0x06CE,0x06CE,0},
+{0x06CF,0x06CF,0},
+{0x06D0,0x06D0,0},
+{0x06D1,0x06D1,0},
+{0x06D2,0x06D2,0},
+{0x06D3,0x06D3,0},
+{0x06D4,0x06D4,0},
+{0x06D5,0x06D5,0},
+{0x06D6,0x06D6,0},
+{0x06D7,0x06D7,0},
+{0x06D8,0x06D8,0},
+{0x06D9,0x06D9,0},
+{0x06DA,0x06DA,0},
+{0x06DB,0x06DB,0},
+{0x06DC,0x06DC,0},
+{0x06DD,0x06DD,0},
+{0x06DE,0x06DE,0},
+{0x06DF,0x06DF,0},
+{0x06E0,0x06E0,0},
+{0x06E1,0x06E1,0},
+{0x06E2,0x06E2,0},
+{0x06E3,0x06E3,0},
+{0x06E4,0x06E4,0},
+{0x06E5,0x06E5,0},
+{0x06E6,0x06E6,0},
+{0x06E7,0x06E7,0},
+{0x06E8,0x06E8,0},
+{0x06E9,0x06E9,0},
+{0x06EA,0x06EA,0},
+{0x06EB,0x06EB,0},
+{0x06EC,0x06EC,0},
+{0x06ED,0x06ED,0},
+{0x06EE,0x06EE,0},
+{0x06EF,0x06EF,0},
+{0x06F0,0x06F0,0},
+{0x06F1,0x06F1,0},
+{0x06F2,0x06F2,0},
+{0x06F3,0x06F3,0},
+{0x06F4,0x06F4,0},
+{0x06F5,0x06F5,0},
+{0x06F6,0x06F6,0},
+{0x06F7,0x06F7,0},
+{0x06F8,0x06F8,0},
+{0x06F9,0x06F9,0},
+{0x06FA,0x06FA,0},
+{0x06FB,0x06FB,0},
+{0x06FC,0x06FC,0},
+{0x06FD,0x06FD,0},
+{0x06FE,0x06FE,0},
+{0x06FF,0x06FF,0},
+{0x0700,0x0700,0},
+{0x0701,0x0701,0},
+{0x0702,0x0702,0},
+{0x0703,0x0703,0},
+{0x0704,0x0704,0},
+{0x0705,0x0705,0},
+{0x0706,0x0706,0},
+{0x0707,0x0707,0},
+{0x0708,0x0708,0},
+{0x0709,0x0709,0},
+{0x070A,0x070A,0},
+{0x070B,0x070B,0},
+{0x070C,0x070C,0},
+{0x070D,0x070D,0},
+{0x070E,0x070E,0},
+{0x070F,0x070F,0},
+{0x0710,0x0710,0},
+{0x0711,0x0711,0},
+{0x0712,0x0712,0},
+{0x0713,0x0713,0},
+{0x0714,0x0714,0},
+{0x0715,0x0715,0},
+{0x0716,0x0716,0},
+{0x0717,0x0717,0},
+{0x0718,0x0718,0},
+{0x0719,0x0719,0},
+{0x071A,0x071A,0},
+{0x071B,0x071B,0},
+{0x071C,0x071C,0},
+{0x071D,0x071D,0},
+{0x071E,0x071E,0},
+{0x071F,0x071F,0},
+{0x0720,0x0720,0},
+{0x0721,0x0721,0},
+{0x0722,0x0722,0},
+{0x0723,0x0723,0},
+{0x0724,0x0724,0},
+{0x0725,0x0725,0},
+{0x0726,0x0726,0},
+{0x0727,0x0727,0},
+{0x0728,0x0728,0},
+{0x0729,0x0729,0},
+{0x072A,0x072A,0},
+{0x072B,0x072B,0},
+{0x072C,0x072C,0},
+{0x072D,0x072D,0},
+{0x072E,0x072E,0},
+{0x072F,0x072F,0},
+{0x0730,0x0730,0},
+{0x0731,0x0731,0},
+{0x0732,0x0732,0},
+{0x0733,0x0733,0},
+{0x0734,0x0734,0},
+{0x0735,0x0735,0},
+{0x0736,0x0736,0},
+{0x0737,0x0737,0},
+{0x0738,0x0738,0},
+{0x0739,0x0739,0},
+{0x073A,0x073A,0},
+{0x073B,0x073B,0},
+{0x073C,0x073C,0},
+{0x073D,0x073D,0},
+{0x073E,0x073E,0},
+{0x073F,0x073F,0},
+{0x0740,0x0740,0},
+{0x0741,0x0741,0},
+{0x0742,0x0742,0},
+{0x0743,0x0743,0},
+{0x0744,0x0744,0},
+{0x0745,0x0745,0},
+{0x0746,0x0746,0},
+{0x0747,0x0747,0},
+{0x0748,0x0748,0},
+{0x0749,0x0749,0},
+{0x074A,0x074A,0},
+{0x074B,0x074B,0},
+{0x074C,0x074C,0},
+{0x074D,0x074D,0},
+{0x074E,0x074E,0},
+{0x074F,0x074F,0},
+{0x0750,0x0750,0},
+{0x0751,0x0751,0},
+{0x0752,0x0752,0},
+{0x0753,0x0753,0},
+{0x0754,0x0754,0},
+{0x0755,0x0755,0},
+{0x0756,0x0756,0},
+{0x0757,0x0757,0},
+{0x0758,0x0758,0},
+{0x0759,0x0759,0},
+{0x075A,0x075A,0},
+{0x075B,0x075B,0},
+{0x075C,0x075C,0},
+{0x075D,0x075D,0},
+{0x075E,0x075E,0},
+{0x075F,0x075F,0},
+{0x0760,0x0760,0},
+{0x0761,0x0761,0},
+{0x0762,0x0762,0},
+{0x0763,0x0763,0},
+{0x0764,0x0764,0},
+{0x0765,0x0765,0},
+{0x0766,0x0766,0},
+{0x0767,0x0767,0},
+{0x0768,0x0768,0},
+{0x0769,0x0769,0},
+{0x076A,0x076A,0},
+{0x076B,0x076B,0},
+{0x076C,0x076C,0},
+{0x076D,0x076D,0},
+{0x076E,0x076E,0},
+{0x076F,0x076F,0},
+{0x0770,0x0770,0},
+{0x0771,0x0771,0},
+{0x0772,0x0772,0},
+{0x0773,0x0773,0},
+{0x0774,0x0774,0},
+{0x0775,0x0775,0},
+{0x0776,0x0776,0},
+{0x0777,0x0777,0},
+{0x0778,0x0778,0},
+{0x0779,0x0779,0},
+{0x077A,0x077A,0},
+{0x077B,0x077B,0},
+{0x077C,0x077C,0},
+{0x077D,0x077D,0},
+{0x077E,0x077E,0},
+{0x077F,0x077F,0},
+{0x0780,0x0780,0},
+{0x0781,0x0781,0},
+{0x0782,0x0782,0},
+{0x0783,0x0783,0},
+{0x0784,0x0784,0},
+{0x0785,0x0785,0},
+{0x0786,0x0786,0},
+{0x0787,0x0787,0},
+{0x0788,0x0788,0},
+{0x0789,0x0789,0},
+{0x078A,0x078A,0},
+{0x078B,0x078B,0},
+{0x078C,0x078C,0},
+{0x078D,0x078D,0},
+{0x078E,0x078E,0},
+{0x078F,0x078F,0},
+{0x0790,0x0790,0},
+{0x0791,0x0791,0},
+{0x0792,0x0792,0},
+{0x0793,0x0793,0},
+{0x0794,0x0794,0},
+{0x0795,0x0795,0},
+{0x0796,0x0796,0},
+{0x0797,0x0797,0},
+{0x0798,0x0798,0},
+{0x0799,0x0799,0},
+{0x079A,0x079A,0},
+{0x079B,0x079B,0},
+{0x079C,0x079C,0},
+{0x079D,0x079D,0},
+{0x079E,0x079E,0},
+{0x079F,0x079F,0},
+{0x07A0,0x07A0,0},
+{0x07A1,0x07A1,0},
+{0x07A2,0x07A2,0},
+{0x07A3,0x07A3,0},
+{0x07A4,0x07A4,0},
+{0x07A5,0x07A5,0},
+{0x07A6,0x07A6,0},
+{0x07A7,0x07A7,0},
+{0x07A8,0x07A8,0},
+{0x07A9,0x07A9,0},
+{0x07AA,0x07AA,0},
+{0x07AB,0x07AB,0},
+{0x07AC,0x07AC,0},
+{0x07AD,0x07AD,0},
+{0x07AE,0x07AE,0},
+{0x07AF,0x07AF,0},
+{0x07B0,0x07B0,0},
+{0x07B1,0x07B1,0},
+{0x07B2,0x07B2,0},
+{0x07B3,0x07B3,0},
+{0x07B4,0x07B4,0},
+{0x07B5,0x07B5,0},
+{0x07B6,0x07B6,0},
+{0x07B7,0x07B7,0},
+{0x07B8,0x07B8,0},
+{0x07B9,0x07B9,0},
+{0x07BA,0x07BA,0},
+{0x07BB,0x07BB,0},
+{0x07BC,0x07BC,0},
+{0x07BD,0x07BD,0},
+{0x07BE,0x07BE,0},
+{0x07BF,0x07BF,0},
+{0x07C0,0x07C0,0},
+{0x07C1,0x07C1,0},
+{0x07C2,0x07C2,0},
+{0x07C3,0x07C3,0},
+{0x07C4,0x07C4,0},
+{0x07C5,0x07C5,0},
+{0x07C6,0x07C6,0},
+{0x07C7,0x07C7,0},
+{0x07C8,0x07C8,0},
+{0x07C9,0x07C9,0},
+{0x07CA,0x07CA,0},
+{0x07CB,0x07CB,0},
+{0x07CC,0x07CC,0},
+{0x07CD,0x07CD,0},
+{0x07CE,0x07CE,0},
+{0x07CF,0x07CF,0},
+{0x07D0,0x07D0,0},
+{0x07D1,0x07D1,0},
+{0x07D2,0x07D2,0},
+{0x07D3,0x07D3,0},
+{0x07D4,0x07D4,0},
+{0x07D5,0x07D5,0},
+{0x07D6,0x07D6,0},
+{0x07D7,0x07D7,0},
+{0x07D8,0x07D8,0},
+{0x07D9,0x07D9,0},
+{0x07DA,0x07DA,0},
+{0x07DB,0x07DB,0},
+{0x07DC,0x07DC,0},
+{0x07DD,0x07DD,0},
+{0x07DE,0x07DE,0},
+{0x07DF,0x07DF,0},
+{0x07E0,0x07E0,0},
+{0x07E1,0x07E1,0},
+{0x07E2,0x07E2,0},
+{0x07E3,0x07E3,0},
+{0x07E4,0x07E4,0},
+{0x07E5,0x07E5,0},
+{0x07E6,0x07E6,0},
+{0x07E7,0x07E7,0},
+{0x07E8,0x07E8,0},
+{0x07E9,0x07E9,0},
+{0x07EA,0x07EA,0},
+{0x07EB,0x07EB,0},
+{0x07EC,0x07EC,0},
+{0x07ED,0x07ED,0},
+{0x07EE,0x07EE,0},
+{0x07EF,0x07EF,0},
+{0x07F0,0x07F0,0},
+{0x07F1,0x07F1,0},
+{0x07F2,0x07F2,0},
+{0x07F3,0x07F3,0},
+{0x07F4,0x07F4,0},
+{0x07F5,0x07F5,0},
+{0x07F6,0x07F6,0},
+{0x07F7,0x07F7,0},
+{0x07F8,0x07F8,0},
+{0x07F9,0x07F9,0},
+{0x07FA,0x07FA,0},
+{0x07FB,0x07FB,0},
+{0x07FC,0x07FC,0},
+{0x07FD,0x07FD,0},
+{0x07FE,0x07FE,0},
+{0x07FF,0x07FF,0},
+{0x0800,0x0800,0},
+{0x0801,0x0801,0},
+{0x0802,0x0802,0},
+{0x0803,0x0803,0},
+{0x0804,0x0804,0},
+{0x0805,0x0805,0},
+{0x0806,0x0806,0},
+{0x0807,0x0807,0},
+{0x0808,0x0808,0},
+{0x0809,0x0809,0},
+{0x080A,0x080A,0},
+{0x080B,0x080B,0},
+{0x080C,0x080C,0},
+{0x080D,0x080D,0},
+{0x080E,0x080E,0},
+{0x080F,0x080F,0},
+{0x0810,0x0810,0},
+{0x0811,0x0811,0},
+{0x0812,0x0812,0},
+{0x0813,0x0813,0},
+{0x0814,0x0814,0},
+{0x0815,0x0815,0},
+{0x0816,0x0816,0},
+{0x0817,0x0817,0},
+{0x0818,0x0818,0},
+{0x0819,0x0819,0},
+{0x081A,0x081A,0},
+{0x081B,0x081B,0},
+{0x081C,0x081C,0},
+{0x081D,0x081D,0},
+{0x081E,0x081E,0},
+{0x081F,0x081F,0},
+{0x0820,0x0820,0},
+{0x0821,0x0821,0},
+{0x0822,0x0822,0},
+{0x0823,0x0823,0},
+{0x0824,0x0824,0},
+{0x0825,0x0825,0},
+{0x0826,0x0826,0},
+{0x0827,0x0827,0},
+{0x0828,0x0828,0},
+{0x0829,0x0829,0},
+{0x082A,0x082A,0},
+{0x082B,0x082B,0},
+{0x082C,0x082C,0},
+{0x082D,0x082D,0},
+{0x082E,0x082E,0},
+{0x082F,0x082F,0},
+{0x0830,0x0830,0},
+{0x0831,0x0831,0},
+{0x0832,0x0832,0},
+{0x0833,0x0833,0},
+{0x0834,0x0834,0},
+{0x0835,0x0835,0},
+{0x0836,0x0836,0},
+{0x0837,0x0837,0},
+{0x0838,0x0838,0},
+{0x0839,0x0839,0},
+{0x083A,0x083A,0},
+{0x083B,0x083B,0},
+{0x083C,0x083C,0},
+{0x083D,0x083D,0},
+{0x083E,0x083E,0},
+{0x083F,0x083F,0},
+{0x0840,0x0840,0},
+{0x0841,0x0841,0},
+{0x0842,0x0842,0},
+{0x0843,0x0843,0},
+{0x0844,0x0844,0},
+{0x0845,0x0845,0},
+{0x0846,0x0846,0},
+{0x0847,0x0847,0},
+{0x0848,0x0848,0},
+{0x0849,0x0849,0},
+{0x084A,0x084A,0},
+{0x084B,0x084B,0},
+{0x084C,0x084C,0},
+{0x084D,0x084D,0},
+{0x084E,0x084E,0},
+{0x084F,0x084F,0},
+{0x0850,0x0850,0},
+{0x0851,0x0851,0},
+{0x0852,0x0852,0},
+{0x0853,0x0853,0},
+{0x0854,0x0854,0},
+{0x0855,0x0855,0},
+{0x0856,0x0856,0},
+{0x0857,0x0857,0},
+{0x0858,0x0858,0},
+{0x0859,0x0859,0},
+{0x085A,0x085A,0},
+{0x085B,0x085B,0},
+{0x085C,0x085C,0},
+{0x085D,0x085D,0},
+{0x085E,0x085E,0},
+{0x085F,0x085F,0},
+{0x0860,0x0860,0},
+{0x0861,0x0861,0},
+{0x0862,0x0862,0},
+{0x0863,0x0863,0},
+{0x0864,0x0864,0},
+{0x0865,0x0865,0},
+{0x0866,0x0866,0},
+{0x0867,0x0867,0},
+{0x0868,0x0868,0},
+{0x0869,0x0869,0},
+{0x086A,0x086A,0},
+{0x086B,0x086B,0},
+{0x086C,0x086C,0},
+{0x086D,0x086D,0},
+{0x086E,0x086E,0},
+{0x086F,0x086F,0},
+{0x0870,0x0870,0},
+{0x0871,0x0871,0},
+{0x0872,0x0872,0},
+{0x0873,0x0873,0},
+{0x0874,0x0874,0},
+{0x0875,0x0875,0},
+{0x0876,0x0876,0},
+{0x0877,0x0877,0},
+{0x0878,0x0878,0},
+{0x0879,0x0879,0},
+{0x087A,0x087A,0},
+{0x087B,0x087B,0},
+{0x087C,0x087C,0},
+{0x087D,0x087D,0},
+{0x087E,0x087E,0},
+{0x087F,0x087F,0},
+{0x0880,0x0880,0},
+{0x0881,0x0881,0},
+{0x0882,0x0882,0},
+{0x0883,0x0883,0},
+{0x0884,0x0884,0},
+{0x0885,0x0885,0},
+{0x0886,0x0886,0},
+{0x0887,0x0887,0},
+{0x0888,0x0888,0},
+{0x0889,0x0889,0},
+{0x088A,0x088A,0},
+{0x088B,0x088B,0},
+{0x088C,0x088C,0},
+{0x088D,0x088D,0},
+{0x088E,0x088E,0},
+{0x088F,0x088F,0},
+{0x0890,0x0890,0},
+{0x0891,0x0891,0},
+{0x0892,0x0892,0},
+{0x0893,0x0893,0},
+{0x0894,0x0894,0},
+{0x0895,0x0895,0},
+{0x0896,0x0896,0},
+{0x0897,0x0897,0},
+{0x0898,0x0898,0},
+{0x0899,0x0899,0},
+{0x089A,0x089A,0},
+{0x089B,0x089B,0},
+{0x089C,0x089C,0},
+{0x089D,0x089D,0},
+{0x089E,0x089E,0},
+{0x089F,0x089F,0},
+{0x08A0,0x08A0,0},
+{0x08A1,0x08A1,0},
+{0x08A2,0x08A2,0},
+{0x08A3,0x08A3,0},
+{0x08A4,0x08A4,0},
+{0x08A5,0x08A5,0},
+{0x08A6,0x08A6,0},
+{0x08A7,0x08A7,0},
+{0x08A8,0x08A8,0},
+{0x08A9,0x08A9,0},
+{0x08AA,0x08AA,0},
+{0x08AB,0x08AB,0},
+{0x08AC,0x08AC,0},
+{0x08AD,0x08AD,0},
+{0x08AE,0x08AE,0},
+{0x08AF,0x08AF,0},
+{0x08B0,0x08B0,0},
+{0x08B1,0x08B1,0},
+{0x08B2,0x08B2,0},
+{0x08B3,0x08B3,0},
+{0x08B4,0x08B4,0},
+{0x08B5,0x08B5,0},
+{0x08B6,0x08B6,0},
+{0x08B7,0x08B7,0},
+{0x08B8,0x08B8,0},
+{0x08B9,0x08B9,0},
+{0x08BA,0x08BA,0},
+{0x08BB,0x08BB,0},
+{0x08BC,0x08BC,0},
+{0x08BD,0x08BD,0},
+{0x08BE,0x08BE,0},
+{0x08BF,0x08BF,0},
+{0x08C0,0x08C0,0},
+{0x08C1,0x08C1,0},
+{0x08C2,0x08C2,0},
+{0x08C3,0x08C3,0},
+{0x08C4,0x08C4,0},
+{0x08C5,0x08C5,0},
+{0x08C6,0x08C6,0},
+{0x08C7,0x08C7,0},
+{0x08C8,0x08C8,0},
+{0x08C9,0x08C9,0},
+{0x08CA,0x08CA,0},
+{0x08CB,0x08CB,0},
+{0x08CC,0x08CC,0},
+{0x08CD,0x08CD,0},
+{0x08CE,0x08CE,0},
+{0x08CF,0x08CF,0},
+{0x08D0,0x08D0,0},
+{0x08D1,0x08D1,0},
+{0x08D2,0x08D2,0},
+{0x08D3,0x08D3,0},
+{0x08D4,0x08D4,0},
+{0x08D5,0x08D5,0},
+{0x08D6,0x08D6,0},
+{0x08D7,0x08D7,0},
+{0x08D8,0x08D8,0},
+{0x08D9,0x08D9,0},
+{0x08DA,0x08DA,0},
+{0x08DB,0x08DB,0},
+{0x08DC,0x08DC,0},
+{0x08DD,0x08DD,0},
+{0x08DE,0x08DE,0},
+{0x08DF,0x08DF,0},
+{0x08E0,0x08E0,0},
+{0x08E1,0x08E1,0},
+{0x08E2,0x08E2,0},
+{0x08E3,0x08E3,0},
+{0x08E4,0x08E4,0},
+{0x08E5,0x08E5,0},
+{0x08E6,0x08E6,0},
+{0x08E7,0x08E7,0},
+{0x08E8,0x08E8,0},
+{0x08E9,0x08E9,0},
+{0x08EA,0x08EA,0},
+{0x08EB,0x08EB,0},
+{0x08EC,0x08EC,0},
+{0x08ED,0x08ED,0},
+{0x08EE,0x08EE,0},
+{0x08EF,0x08EF,0},
+{0x08F0,0x08F0,0},
+{0x08F1,0x08F1,0},
+{0x08F2,0x08F2,0},
+{0x08F3,0x08F3,0},
+{0x08F4,0x08F4,0},
+{0x08F5,0x08F5,0},
+{0x08F6,0x08F6,0},
+{0x08F7,0x08F7,0},
+{0x08F8,0x08F8,0},
+{0x08F9,0x08F9,0},
+{0x08FA,0x08FA,0},
+{0x08FB,0x08FB,0},
+{0x08FC,0x08FC,0},
+{0x08FD,0x08FD,0},
+{0x08FE,0x08FE,0},
+{0x08FF,0x08FF,0},
+{0x0900,0x0900,0},
+{0x0901,0x0901,0},
+{0x0902,0x0902,0},
+{0x0903,0x0903,0},
+{0x0904,0x0904,0},
+{0x0905,0x0905,0},
+{0x0906,0x0906,0},
+{0x0907,0x0907,0},
+{0x0908,0x0908,0},
+{0x0909,0x0909,0},
+{0x090A,0x090A,0},
+{0x090B,0x090B,0},
+{0x090C,0x090C,0},
+{0x090D,0x090D,0},
+{0x090E,0x090E,0},
+{0x090F,0x090F,0},
+{0x0910,0x0910,0},
+{0x0911,0x0911,0},
+{0x0912,0x0912,0},
+{0x0913,0x0913,0},
+{0x0914,0x0914,0},
+{0x0915,0x0915,0},
+{0x0916,0x0916,0},
+{0x0917,0x0917,0},
+{0x0918,0x0918,0},
+{0x0919,0x0919,0},
+{0x091A,0x091A,0},
+{0x091B,0x091B,0},
+{0x091C,0x091C,0},
+{0x091D,0x091D,0},
+{0x091E,0x091E,0},
+{0x091F,0x091F,0},
+{0x0920,0x0920,0},
+{0x0921,0x0921,0},
+{0x0922,0x0922,0},
+{0x0923,0x0923,0},
+{0x0924,0x0924,0},
+{0x0925,0x0925,0},
+{0x0926,0x0926,0},
+{0x0927,0x0927,0},
+{0x0928,0x0928,0},
+{0x0929,0x0929,0},
+{0x092A,0x092A,0},
+{0x092B,0x092B,0},
+{0x092C,0x092C,0},
+{0x092D,0x092D,0},
+{0x092E,0x092E,0},
+{0x092F,0x092F,0},
+{0x0930,0x0930,0},
+{0x0931,0x0931,0},
+{0x0932,0x0932,0},
+{0x0933,0x0933,0},
+{0x0934,0x0934,0},
+{0x0935,0x0935,0},
+{0x0936,0x0936,0},
+{0x0937,0x0937,0},
+{0x0938,0x0938,0},
+{0x0939,0x0939,0},
+{0x093A,0x093A,0},
+{0x093B,0x093B,0},
+{0x093C,0x093C,0},
+{0x093D,0x093D,0},
+{0x093E,0x093E,0},
+{0x093F,0x093F,0},
+{0x0940,0x0940,0},
+{0x0941,0x0941,0},
+{0x0942,0x0942,0},
+{0x0943,0x0943,0},
+{0x0944,0x0944,0},
+{0x0945,0x0945,0},
+{0x0946,0x0946,0},
+{0x0947,0x0947,0},
+{0x0948,0x0948,0},
+{0x0949,0x0949,0},
+{0x094A,0x094A,0},
+{0x094B,0x094B,0},
+{0x094C,0x094C,0},
+{0x094D,0x094D,0},
+{0x094E,0x094E,0},
+{0x094F,0x094F,0},
+{0x0950,0x0950,0},
+{0x0951,0x0951,0},
+{0x0952,0x0952,0},
+{0x0953,0x0953,0},
+{0x0954,0x0954,0},
+{0x0955,0x0955,0},
+{0x0956,0x0956,0},
+{0x0957,0x0957,0},
+{0x0958,0x0958,0},
+{0x0959,0x0959,0},
+{0x095A,0x095A,0},
+{0x095B,0x095B,0},
+{0x095C,0x095C,0},
+{0x095D,0x095D,0},
+{0x095E,0x095E,0},
+{0x095F,0x095F,0},
+{0x0960,0x0960,0},
+{0x0961,0x0961,0},
+{0x0962,0x0962,0},
+{0x0963,0x0963,0},
+{0x0964,0x0964,0},
+{0x0965,0x0965,0},
+{0x0966,0x0966,0},
+{0x0967,0x0967,0},
+{0x0968,0x0968,0},
+{0x0969,0x0969,0},
+{0x096A,0x096A,0},
+{0x096B,0x096B,0},
+{0x096C,0x096C,0},
+{0x096D,0x096D,0},
+{0x096E,0x096E,0},
+{0x096F,0x096F,0},
+{0x0970,0x0970,0},
+{0x0971,0x0971,0},
+{0x0972,0x0972,0},
+{0x0973,0x0973,0},
+{0x0974,0x0974,0},
+{0x0975,0x0975,0},
+{0x0976,0x0976,0},
+{0x0977,0x0977,0},
+{0x0978,0x0978,0},
+{0x0979,0x0979,0},
+{0x097A,0x097A,0},
+{0x097B,0x097B,0},
+{0x097C,0x097C,0},
+{0x097D,0x097D,0},
+{0x097E,0x097E,0},
+{0x097F,0x097F,0},
+{0x0980,0x0980,0},
+{0x0981,0x0981,0},
+{0x0982,0x0982,0},
+{0x0983,0x0983,0},
+{0x0984,0x0984,0},
+{0x0985,0x0985,0},
+{0x0986,0x0986,0},
+{0x0987,0x0987,0},
+{0x0988,0x0988,0},
+{0x0989,0x0989,0},
+{0x098A,0x098A,0},
+{0x098B,0x098B,0},
+{0x098C,0x098C,0},
+{0x098D,0x098D,0},
+{0x098E,0x098E,0},
+{0x098F,0x098F,0},
+{0x0990,0x0990,0},
+{0x0991,0x0991,0},
+{0x0992,0x0992,0},
+{0x0993,0x0993,0},
+{0x0994,0x0994,0},
+{0x0995,0x0995,0},
+{0x0996,0x0996,0},
+{0x0997,0x0997,0},
+{0x0998,0x0998,0},
+{0x0999,0x0999,0},
+{0x099A,0x099A,0},
+{0x099B,0x099B,0},
+{0x099C,0x099C,0},
+{0x099D,0x099D,0},
+{0x099E,0x099E,0},
+{0x099F,0x099F,0},
+{0x09A0,0x09A0,0},
+{0x09A1,0x09A1,0},
+{0x09A2,0x09A2,0},
+{0x09A3,0x09A3,0},
+{0x09A4,0x09A4,0},
+{0x09A5,0x09A5,0},
+{0x09A6,0x09A6,0},
+{0x09A7,0x09A7,0},
+{0x09A8,0x09A8,0},
+{0x09A9,0x09A9,0},
+{0x09AA,0x09AA,0},
+{0x09AB,0x09AB,0},
+{0x09AC,0x09AC,0},
+{0x09AD,0x09AD,0},
+{0x09AE,0x09AE,0},
+{0x09AF,0x09AF,0},
+{0x09B0,0x09B0,0},
+{0x09B1,0x09B1,0},
+{0x09B2,0x09B2,0},
+{0x09B3,0x09B3,0},
+{0x09B4,0x09B4,0},
+{0x09B5,0x09B5,0},
+{0x09B6,0x09B6,0},
+{0x09B7,0x09B7,0},
+{0x09B8,0x09B8,0},
+{0x09B9,0x09B9,0},
+{0x09BA,0x09BA,0},
+{0x09BB,0x09BB,0},
+{0x09BC,0x09BC,0},
+{0x09BD,0x09BD,0},
+{0x09BE,0x09BE,0},
+{0x09BF,0x09BF,0},
+{0x09C0,0x09C0,0},
+{0x09C1,0x09C1,0},
+{0x09C2,0x09C2,0},
+{0x09C3,0x09C3,0},
+{0x09C4,0x09C4,0},
+{0x09C5,0x09C5,0},
+{0x09C6,0x09C6,0},
+{0x09C7,0x09C7,0},
+{0x09C8,0x09C8,0},
+{0x09C9,0x09C9,0},
+{0x09CA,0x09CA,0},
+{0x09CB,0x09CB,0},
+{0x09CC,0x09CC,0},
+{0x09CD,0x09CD,0},
+{0x09CE,0x09CE,0},
+{0x09CF,0x09CF,0},
+{0x09D0,0x09D0,0},
+{0x09D1,0x09D1,0},
+{0x09D2,0x09D2,0},
+{0x09D3,0x09D3,0},
+{0x09D4,0x09D4,0},
+{0x09D5,0x09D5,0},
+{0x09D6,0x09D6,0},
+{0x09D7,0x09D7,0},
+{0x09D8,0x09D8,0},
+{0x09D9,0x09D9,0},
+{0x09DA,0x09DA,0},
+{0x09DB,0x09DB,0},
+{0x09DC,0x09DC,0},
+{0x09DD,0x09DD,0},
+{0x09DE,0x09DE,0},
+{0x09DF,0x09DF,0},
+{0x09E0,0x09E0,0},
+{0x09E1,0x09E1,0},
+{0x09E2,0x09E2,0},
+{0x09E3,0x09E3,0},
+{0x09E4,0x09E4,0},
+{0x09E5,0x09E5,0},
+{0x09E6,0x09E6,0},
+{0x09E7,0x09E7,0},
+{0x09E8,0x09E8,0},
+{0x09E9,0x09E9,0},
+{0x09EA,0x09EA,0},
+{0x09EB,0x09EB,0},
+{0x09EC,0x09EC,0},
+{0x09ED,0x09ED,0},
+{0x09EE,0x09EE,0},
+{0x09EF,0x09EF,0},
+{0x09F0,0x09F0,0},
+{0x09F1,0x09F1,0},
+{0x09F2,0x09F2,0},
+{0x09F3,0x09F3,0},
+{0x09F4,0x09F4,0},
+{0x09F5,0x09F5,0},
+{0x09F6,0x09F6,0},
+{0x09F7,0x09F7,0},
+{0x09F8,0x09F8,0},
+{0x09F9,0x09F9,0},
+{0x09FA,0x09FA,0},
+{0x09FB,0x09FB,0},
+{0x09FC,0x09FC,0},
+{0x09FD,0x09FD,0},
+{0x09FE,0x09FE,0},
+{0x09FF,0x09FF,0},
+{0x0A00,0x0A00,0},
+{0x0A01,0x0A01,0},
+{0x0A02,0x0A02,0},
+{0x0A03,0x0A03,0},
+{0x0A04,0x0A04,0},
+{0x0A05,0x0A05,0},
+{0x0A06,0x0A06,0},
+{0x0A07,0x0A07,0},
+{0x0A08,0x0A08,0},
+{0x0A09,0x0A09,0},
+{0x0A0A,0x0A0A,0},
+{0x0A0B,0x0A0B,0},
+{0x0A0C,0x0A0C,0},
+{0x0A0D,0x0A0D,0},
+{0x0A0E,0x0A0E,0},
+{0x0A0F,0x0A0F,0},
+{0x0A10,0x0A10,0},
+{0x0A11,0x0A11,0},
+{0x0A12,0x0A12,0},
+{0x0A13,0x0A13,0},
+{0x0A14,0x0A14,0},
+{0x0A15,0x0A15,0},
+{0x0A16,0x0A16,0},
+{0x0A17,0x0A17,0},
+{0x0A18,0x0A18,0},
+{0x0A19,0x0A19,0},
+{0x0A1A,0x0A1A,0},
+{0x0A1B,0x0A1B,0},
+{0x0A1C,0x0A1C,0},
+{0x0A1D,0x0A1D,0},
+{0x0A1E,0x0A1E,0},
+{0x0A1F,0x0A1F,0},
+{0x0A20,0x0A20,0},
+{0x0A21,0x0A21,0},
+{0x0A22,0x0A22,0},
+{0x0A23,0x0A23,0},
+{0x0A24,0x0A24,0},
+{0x0A25,0x0A25,0},
+{0x0A26,0x0A26,0},
+{0x0A27,0x0A27,0},
+{0x0A28,0x0A28,0},
+{0x0A29,0x0A29,0},
+{0x0A2A,0x0A2A,0},
+{0x0A2B,0x0A2B,0},
+{0x0A2C,0x0A2C,0},
+{0x0A2D,0x0A2D,0},
+{0x0A2E,0x0A2E,0},
+{0x0A2F,0x0A2F,0},
+{0x0A30,0x0A30,0},
+{0x0A31,0x0A31,0},
+{0x0A32,0x0A32,0},
+{0x0A33,0x0A33,0},
+{0x0A34,0x0A34,0},
+{0x0A35,0x0A35,0},
+{0x0A36,0x0A36,0},
+{0x0A37,0x0A37,0},
+{0x0A38,0x0A38,0},
+{0x0A39,0x0A39,0},
+{0x0A3A,0x0A3A,0},
+{0x0A3B,0x0A3B,0},
+{0x0A3C,0x0A3C,0},
+{0x0A3D,0x0A3D,0},
+{0x0A3E,0x0A3E,0},
+{0x0A3F,0x0A3F,0},
+{0x0A40,0x0A40,0},
+{0x0A41,0x0A41,0},
+{0x0A42,0x0A42,0},
+{0x0A43,0x0A43,0},
+{0x0A44,0x0A44,0},
+{0x0A45,0x0A45,0},
+{0x0A46,0x0A46,0},
+{0x0A47,0x0A47,0},
+{0x0A48,0x0A48,0},
+{0x0A49,0x0A49,0},
+{0x0A4A,0x0A4A,0},
+{0x0A4B,0x0A4B,0},
+{0x0A4C,0x0A4C,0},
+{0x0A4D,0x0A4D,0},
+{0x0A4E,0x0A4E,0},
+{0x0A4F,0x0A4F,0},
+{0x0A50,0x0A50,0},
+{0x0A51,0x0A51,0},
+{0x0A52,0x0A52,0},
+{0x0A53,0x0A53,0},
+{0x0A54,0x0A54,0},
+{0x0A55,0x0A55,0},
+{0x0A56,0x0A56,0},
+{0x0A57,0x0A57,0},
+{0x0A58,0x0A58,0},
+{0x0A59,0x0A59,0},
+{0x0A5A,0x0A5A,0},
+{0x0A5B,0x0A5B,0},
+{0x0A5C,0x0A5C,0},
+{0x0A5D,0x0A5D,0},
+{0x0A5E,0x0A5E,0},
+{0x0A5F,0x0A5F,0},
+{0x0A60,0x0A60,0},
+{0x0A61,0x0A61,0},
+{0x0A62,0x0A62,0},
+{0x0A63,0x0A63,0},
+{0x0A64,0x0A64,0},
+{0x0A65,0x0A65,0},
+{0x0A66,0x0A66,0},
+{0x0A67,0x0A67,0},
+{0x0A68,0x0A68,0},
+{0x0A69,0x0A69,0},
+{0x0A6A,0x0A6A,0},
+{0x0A6B,0x0A6B,0},
+{0x0A6C,0x0A6C,0},
+{0x0A6D,0x0A6D,0},
+{0x0A6E,0x0A6E,0},
+{0x0A6F,0x0A6F,0},
+{0x0A70,0x0A70,0},
+{0x0A71,0x0A71,0},
+{0x0A72,0x0A72,0},
+{0x0A73,0x0A73,0},
+{0x0A74,0x0A74,0},
+{0x0A75,0x0A75,0},
+{0x0A76,0x0A76,0},
+{0x0A77,0x0A77,0},
+{0x0A78,0x0A78,0},
+{0x0A79,0x0A79,0},
+{0x0A7A,0x0A7A,0},
+{0x0A7B,0x0A7B,0},
+{0x0A7C,0x0A7C,0},
+{0x0A7D,0x0A7D,0},
+{0x0A7E,0x0A7E,0},
+{0x0A7F,0x0A7F,0},
+{0x0A80,0x0A80,0},
+{0x0A81,0x0A81,0},
+{0x0A82,0x0A82,0},
+{0x0A83,0x0A83,0},
+{0x0A84,0x0A84,0},
+{0x0A85,0x0A85,0},
+{0x0A86,0x0A86,0},
+{0x0A87,0x0A87,0},
+{0x0A88,0x0A88,0},
+{0x0A89,0x0A89,0},
+{0x0A8A,0x0A8A,0},
+{0x0A8B,0x0A8B,0},
+{0x0A8C,0x0A8C,0},
+{0x0A8D,0x0A8D,0},
+{0x0A8E,0x0A8E,0},
+{0x0A8F,0x0A8F,0},
+{0x0A90,0x0A90,0},
+{0x0A91,0x0A91,0},
+{0x0A92,0x0A92,0},
+{0x0A93,0x0A93,0},
+{0x0A94,0x0A94,0},
+{0x0A95,0x0A95,0},
+{0x0A96,0x0A96,0},
+{0x0A97,0x0A97,0},
+{0x0A98,0x0A98,0},
+{0x0A99,0x0A99,0},
+{0x0A9A,0x0A9A,0},
+{0x0A9B,0x0A9B,0},
+{0x0A9C,0x0A9C,0},
+{0x0A9D,0x0A9D,0},
+{0x0A9E,0x0A9E,0},
+{0x0A9F,0x0A9F,0},
+{0x0AA0,0x0AA0,0},
+{0x0AA1,0x0AA1,0},
+{0x0AA2,0x0AA2,0},
+{0x0AA3,0x0AA3,0},
+{0x0AA4,0x0AA4,0},
+{0x0AA5,0x0AA5,0},
+{0x0AA6,0x0AA6,0},
+{0x0AA7,0x0AA7,0},
+{0x0AA8,0x0AA8,0},
+{0x0AA9,0x0AA9,0},
+{0x0AAA,0x0AAA,0},
+{0x0AAB,0x0AAB,0},
+{0x0AAC,0x0AAC,0},
+{0x0AAD,0x0AAD,0},
+{0x0AAE,0x0AAE,0},
+{0x0AAF,0x0AAF,0},
+{0x0AB0,0x0AB0,0},
+{0x0AB1,0x0AB1,0},
+{0x0AB2,0x0AB2,0},
+{0x0AB3,0x0AB3,0},
+{0x0AB4,0x0AB4,0},
+{0x0AB5,0x0AB5,0},
+{0x0AB6,0x0AB6,0},
+{0x0AB7,0x0AB7,0},
+{0x0AB8,0x0AB8,0},
+{0x0AB9,0x0AB9,0},
+{0x0ABA,0x0ABA,0},
+{0x0ABB,0x0ABB,0},
+{0x0ABC,0x0ABC,0},
+{0x0ABD,0x0ABD,0},
+{0x0ABE,0x0ABE,0},
+{0x0ABF,0x0ABF,0},
+{0x0AC0,0x0AC0,0},
+{0x0AC1,0x0AC1,0},
+{0x0AC2,0x0AC2,0},
+{0x0AC3,0x0AC3,0},
+{0x0AC4,0x0AC4,0},
+{0x0AC5,0x0AC5,0},
+{0x0AC6,0x0AC6,0},
+{0x0AC7,0x0AC7,0},
+{0x0AC8,0x0AC8,0},
+{0x0AC9,0x0AC9,0},
+{0x0ACA,0x0ACA,0},
+{0x0ACB,0x0ACB,0},
+{0x0ACC,0x0ACC,0},
+{0x0ACD,0x0ACD,0},
+{0x0ACE,0x0ACE,0},
+{0x0ACF,0x0ACF,0},
+{0x0AD0,0x0AD0,0},
+{0x0AD1,0x0AD1,0},
+{0x0AD2,0x0AD2,0},
+{0x0AD3,0x0AD3,0},
+{0x0AD4,0x0AD4,0},
+{0x0AD5,0x0AD5,0},
+{0x0AD6,0x0AD6,0},
+{0x0AD7,0x0AD7,0},
+{0x0AD8,0x0AD8,0},
+{0x0AD9,0x0AD9,0},
+{0x0ADA,0x0ADA,0},
+{0x0ADB,0x0ADB,0},
+{0x0ADC,0x0ADC,0},
+{0x0ADD,0x0ADD,0},
+{0x0ADE,0x0ADE,0},
+{0x0ADF,0x0ADF,0},
+{0x0AE0,0x0AE0,0},
+{0x0AE1,0x0AE1,0},
+{0x0AE2,0x0AE2,0},
+{0x0AE3,0x0AE3,0},
+{0x0AE4,0x0AE4,0},
+{0x0AE5,0x0AE5,0},
+{0x0AE6,0x0AE6,0},
+{0x0AE7,0x0AE7,0},
+{0x0AE8,0x0AE8,0},
+{0x0AE9,0x0AE9,0},
+{0x0AEA,0x0AEA,0},
+{0x0AEB,0x0AEB,0},
+{0x0AEC,0x0AEC,0},
+{0x0AED,0x0AED,0},
+{0x0AEE,0x0AEE,0},
+{0x0AEF,0x0AEF,0},
+{0x0AF0,0x0AF0,0},
+{0x0AF1,0x0AF1,0},
+{0x0AF2,0x0AF2,0},
+{0x0AF3,0x0AF3,0},
+{0x0AF4,0x0AF4,0},
+{0x0AF5,0x0AF5,0},
+{0x0AF6,0x0AF6,0},
+{0x0AF7,0x0AF7,0},
+{0x0AF8,0x0AF8,0},
+{0x0AF9,0x0AF9,0},
+{0x0AFA,0x0AFA,0},
+{0x0AFB,0x0AFB,0},
+{0x0AFC,0x0AFC,0},
+{0x0AFD,0x0AFD,0},
+{0x0AFE,0x0AFE,0},
+{0x0AFF,0x0AFF,0},
+{0x0B00,0x0B00,0},
+{0x0B01,0x0B01,0},
+{0x0B02,0x0B02,0},
+{0x0B03,0x0B03,0},
+{0x0B04,0x0B04,0},
+{0x0B05,0x0B05,0},
+{0x0B06,0x0B06,0},
+{0x0B07,0x0B07,0},
+{0x0B08,0x0B08,0},
+{0x0B09,0x0B09,0},
+{0x0B0A,0x0B0A,0},
+{0x0B0B,0x0B0B,0},
+{0x0B0C,0x0B0C,0},
+{0x0B0D,0x0B0D,0},
+{0x0B0E,0x0B0E,0},
+{0x0B0F,0x0B0F,0},
+{0x0B10,0x0B10,0},
+{0x0B11,0x0B11,0},
+{0x0B12,0x0B12,0},
+{0x0B13,0x0B13,0},
+{0x0B14,0x0B14,0},
+{0x0B15,0x0B15,0},
+{0x0B16,0x0B16,0},
+{0x0B17,0x0B17,0},
+{0x0B18,0x0B18,0},
+{0x0B19,0x0B19,0},
+{0x0B1A,0x0B1A,0},
+{0x0B1B,0x0B1B,0},
+{0x0B1C,0x0B1C,0},
+{0x0B1D,0x0B1D,0},
+{0x0B1E,0x0B1E,0},
+{0x0B1F,0x0B1F,0},
+{0x0B20,0x0B20,0},
+{0x0B21,0x0B21,0},
+{0x0B22,0x0B22,0},
+{0x0B23,0x0B23,0},
+{0x0B24,0x0B24,0},
+{0x0B25,0x0B25,0},
+{0x0B26,0x0B26,0},
+{0x0B27,0x0B27,0},
+{0x0B28,0x0B28,0},
+{0x0B29,0x0B29,0},
+{0x0B2A,0x0B2A,0},
+{0x0B2B,0x0B2B,0},
+{0x0B2C,0x0B2C,0},
+{0x0B2D,0x0B2D,0},
+{0x0B2E,0x0B2E,0},
+{0x0B2F,0x0B2F,0},
+{0x0B30,0x0B30,0},
+{0x0B31,0x0B31,0},
+{0x0B32,0x0B32,0},
+{0x0B33,0x0B33,0},
+{0x0B34,0x0B34,0},
+{0x0B35,0x0B35,0},
+{0x0B36,0x0B36,0},
+{0x0B37,0x0B37,0},
+{0x0B38,0x0B38,0},
+{0x0B39,0x0B39,0},
+{0x0B3A,0x0B3A,0},
+{0x0B3B,0x0B3B,0},
+{0x0B3C,0x0B3C,0},
+{0x0B3D,0x0B3D,0},
+{0x0B3E,0x0B3E,0},
+{0x0B3F,0x0B3F,0},
+{0x0B40,0x0B40,0},
+{0x0B41,0x0B41,0},
+{0x0B42,0x0B42,0},
+{0x0B43,0x0B43,0},
+{0x0B44,0x0B44,0},
+{0x0B45,0x0B45,0},
+{0x0B46,0x0B46,0},
+{0x0B47,0x0B47,0},
+{0x0B48,0x0B48,0},
+{0x0B49,0x0B49,0},
+{0x0B4A,0x0B4A,0},
+{0x0B4B,0x0B4B,0},
+{0x0B4C,0x0B4C,0},
+{0x0B4D,0x0B4D,0},
+{0x0B4E,0x0B4E,0},
+{0x0B4F,0x0B4F,0},
+{0x0B50,0x0B50,0},
+{0x0B51,0x0B51,0},
+{0x0B52,0x0B52,0},
+{0x0B53,0x0B53,0},
+{0x0B54,0x0B54,0},
+{0x0B55,0x0B55,0},
+{0x0B56,0x0B56,0},
+{0x0B57,0x0B57,0},
+{0x0B58,0x0B58,0},
+{0x0B59,0x0B59,0},
+{0x0B5A,0x0B5A,0},
+{0x0B5B,0x0B5B,0},
+{0x0B5C,0x0B5C,0},
+{0x0B5D,0x0B5D,0},
+{0x0B5E,0x0B5E,0},
+{0x0B5F,0x0B5F,0},
+{0x0B60,0x0B60,0},
+{0x0B61,0x0B61,0},
+{0x0B62,0x0B62,0},
+{0x0B63,0x0B63,0},
+{0x0B64,0x0B64,0},
+{0x0B65,0x0B65,0},
+{0x0B66,0x0B66,0},
+{0x0B67,0x0B67,0},
+{0x0B68,0x0B68,0},
+{0x0B69,0x0B69,0},
+{0x0B6A,0x0B6A,0},
+{0x0B6B,0x0B6B,0},
+{0x0B6C,0x0B6C,0},
+{0x0B6D,0x0B6D,0},
+{0x0B6E,0x0B6E,0},
+{0x0B6F,0x0B6F,0},
+{0x0B70,0x0B70,0},
+{0x0B71,0x0B71,0},
+{0x0B72,0x0B72,0},
+{0x0B73,0x0B73,0},
+{0x0B74,0x0B74,0},
+{0x0B75,0x0B75,0},
+{0x0B76,0x0B76,0},
+{0x0B77,0x0B77,0},
+{0x0B78,0x0B78,0},
+{0x0B79,0x0B79,0},
+{0x0B7A,0x0B7A,0},
+{0x0B7B,0x0B7B,0},
+{0x0B7C,0x0B7C,0},
+{0x0B7D,0x0B7D,0},
+{0x0B7E,0x0B7E,0},
+{0x0B7F,0x0B7F,0},
+{0x0B80,0x0B80,0},
+{0x0B81,0x0B81,0},
+{0x0B82,0x0B82,0},
+{0x0B83,0x0B83,0},
+{0x0B84,0x0B84,0},
+{0x0B85,0x0B85,0},
+{0x0B86,0x0B86,0},
+{0x0B87,0x0B87,0},
+{0x0B88,0x0B88,0},
+{0x0B89,0x0B89,0},
+{0x0B8A,0x0B8A,0},
+{0x0B8B,0x0B8B,0},
+{0x0B8C,0x0B8C,0},
+{0x0B8D,0x0B8D,0},
+{0x0B8E,0x0B8E,0},
+{0x0B8F,0x0B8F,0},
+{0x0B90,0x0B90,0},
+{0x0B91,0x0B91,0},
+{0x0B92,0x0B92,0},
+{0x0B93,0x0B93,0},
+{0x0B94,0x0B94,0},
+{0x0B95,0x0B95,0},
+{0x0B96,0x0B96,0},
+{0x0B97,0x0B97,0},
+{0x0B98,0x0B98,0},
+{0x0B99,0x0B99,0},
+{0x0B9A,0x0B9A,0},
+{0x0B9B,0x0B9B,0},
+{0x0B9C,0x0B9C,0},
+{0x0B9D,0x0B9D,0},
+{0x0B9E,0x0B9E,0},
+{0x0B9F,0x0B9F,0},
+{0x0BA0,0x0BA0,0},
+{0x0BA1,0x0BA1,0},
+{0x0BA2,0x0BA2,0},
+{0x0BA3,0x0BA3,0},
+{0x0BA4,0x0BA4,0},
+{0x0BA5,0x0BA5,0},
+{0x0BA6,0x0BA6,0},
+{0x0BA7,0x0BA7,0},
+{0x0BA8,0x0BA8,0},
+{0x0BA9,0x0BA9,0},
+{0x0BAA,0x0BAA,0},
+{0x0BAB,0x0BAB,0},
+{0x0BAC,0x0BAC,0},
+{0x0BAD,0x0BAD,0},
+{0x0BAE,0x0BAE,0},
+{0x0BAF,0x0BAF,0},
+{0x0BB0,0x0BB0,0},
+{0x0BB1,0x0BB1,0},
+{0x0BB2,0x0BB2,0},
+{0x0BB3,0x0BB3,0},
+{0x0BB4,0x0BB4,0},
+{0x0BB5,0x0BB5,0},
+{0x0BB6,0x0BB6,0},
+{0x0BB7,0x0BB7,0},
+{0x0BB8,0x0BB8,0},
+{0x0BB9,0x0BB9,0},
+{0x0BBA,0x0BBA,0},
+{0x0BBB,0x0BBB,0},
+{0x0BBC,0x0BBC,0},
+{0x0BBD,0x0BBD,0},
+{0x0BBE,0x0BBE,0},
+{0x0BBF,0x0BBF,0},
+{0x0BC0,0x0BC0,0},
+{0x0BC1,0x0BC1,0},
+{0x0BC2,0x0BC2,0},
+{0x0BC3,0x0BC3,0},
+{0x0BC4,0x0BC4,0},
+{0x0BC5,0x0BC5,0},
+{0x0BC6,0x0BC6,0},
+{0x0BC7,0x0BC7,0},
+{0x0BC8,0x0BC8,0},
+{0x0BC9,0x0BC9,0},
+{0x0BCA,0x0BCA,0},
+{0x0BCB,0x0BCB,0},
+{0x0BCC,0x0BCC,0},
+{0x0BCD,0x0BCD,0},
+{0x0BCE,0x0BCE,0},
+{0x0BCF,0x0BCF,0},
+{0x0BD0,0x0BD0,0},
+{0x0BD1,0x0BD1,0},
+{0x0BD2,0x0BD2,0},
+{0x0BD3,0x0BD3,0},
+{0x0BD4,0x0BD4,0},
+{0x0BD5,0x0BD5,0},
+{0x0BD6,0x0BD6,0},
+{0x0BD7,0x0BD7,0},
+{0x0BD8,0x0BD8,0},
+{0x0BD9,0x0BD9,0},
+{0x0BDA,0x0BDA,0},
+{0x0BDB,0x0BDB,0},
+{0x0BDC,0x0BDC,0},
+{0x0BDD,0x0BDD,0},
+{0x0BDE,0x0BDE,0},
+{0x0BDF,0x0BDF,0},
+{0x0BE0,0x0BE0,0},
+{0x0BE1,0x0BE1,0},
+{0x0BE2,0x0BE2,0},
+{0x0BE3,0x0BE3,0},
+{0x0BE4,0x0BE4,0},
+{0x0BE5,0x0BE5,0},
+{0x0BE6,0x0BE6,0},
+{0x0BE7,0x0BE7,0},
+{0x0BE8,0x0BE8,0},
+{0x0BE9,0x0BE9,0},
+{0x0BEA,0x0BEA,0},
+{0x0BEB,0x0BEB,0},
+{0x0BEC,0x0BEC,0},
+{0x0BED,0x0BED,0},
+{0x0BEE,0x0BEE,0},
+{0x0BEF,0x0BEF,0},
+{0x0BF0,0x0BF0,0},
+{0x0BF1,0x0BF1,0},
+{0x0BF2,0x0BF2,0},
+{0x0BF3,0x0BF3,0},
+{0x0BF4,0x0BF4,0},
+{0x0BF5,0x0BF5,0},
+{0x0BF6,0x0BF6,0},
+{0x0BF7,0x0BF7,0},
+{0x0BF8,0x0BF8,0},
+{0x0BF9,0x0BF9,0},
+{0x0BFA,0x0BFA,0},
+{0x0BFB,0x0BFB,0},
+{0x0BFC,0x0BFC,0},
+{0x0BFD,0x0BFD,0},
+{0x0BFE,0x0BFE,0},
+{0x0BFF,0x0BFF,0},
+{0x0C00,0x0C00,0},
+{0x0C01,0x0C01,0},
+{0x0C02,0x0C02,0},
+{0x0C03,0x0C03,0},
+{0x0C04,0x0C04,0},
+{0x0C05,0x0C05,0},
+{0x0C06,0x0C06,0},
+{0x0C07,0x0C07,0},
+{0x0C08,0x0C08,0},
+{0x0C09,0x0C09,0},
+{0x0C0A,0x0C0A,0},
+{0x0C0B,0x0C0B,0},
+{0x0C0C,0x0C0C,0},
+{0x0C0D,0x0C0D,0},
+{0x0C0E,0x0C0E,0},
+{0x0C0F,0x0C0F,0},
+{0x0C10,0x0C10,0},
+{0x0C11,0x0C11,0},
+{0x0C12,0x0C12,0},
+{0x0C13,0x0C13,0},
+{0x0C14,0x0C14,0},
+{0x0C15,0x0C15,0},
+{0x0C16,0x0C16,0},
+{0x0C17,0x0C17,0},
+{0x0C18,0x0C18,0},
+{0x0C19,0x0C19,0},
+{0x0C1A,0x0C1A,0},
+{0x0C1B,0x0C1B,0},
+{0x0C1C,0x0C1C,0},
+{0x0C1D,0x0C1D,0},
+{0x0C1E,0x0C1E,0},
+{0x0C1F,0x0C1F,0},
+{0x0C20,0x0C20,0},
+{0x0C21,0x0C21,0},
+{0x0C22,0x0C22,0},
+{0x0C23,0x0C23,0},
+{0x0C24,0x0C24,0},
+{0x0C25,0x0C25,0},
+{0x0C26,0x0C26,0},
+{0x0C27,0x0C27,0},
+{0x0C28,0x0C28,0},
+{0x0C29,0x0C29,0},
+{0x0C2A,0x0C2A,0},
+{0x0C2B,0x0C2B,0},
+{0x0C2C,0x0C2C,0},
+{0x0C2D,0x0C2D,0},
+{0x0C2E,0x0C2E,0},
+{0x0C2F,0x0C2F,0},
+{0x0C30,0x0C30,0},
+{0x0C31,0x0C31,0},
+{0x0C32,0x0C32,0},
+{0x0C33,0x0C33,0},
+{0x0C34,0x0C34,0},
+{0x0C35,0x0C35,0},
+{0x0C36,0x0C36,0},
+{0x0C37,0x0C37,0},
+{0x0C38,0x0C38,0},
+{0x0C39,0x0C39,0},
+{0x0C3A,0x0C3A,0},
+{0x0C3B,0x0C3B,0},
+{0x0C3C,0x0C3C,0},
+{0x0C3D,0x0C3D,0},
+{0x0C3E,0x0C3E,0},
+{0x0C3F,0x0C3F,0},
+{0x0C40,0x0C40,0},
+{0x0C41,0x0C41,0},
+{0x0C42,0x0C42,0},
+{0x0C43,0x0C43,0},
+{0x0C44,0x0C44,0},
+{0x0C45,0x0C45,0},
+{0x0C46,0x0C46,0},
+{0x0C47,0x0C47,0},
+{0x0C48,0x0C48,0},
+{0x0C49,0x0C49,0},
+{0x0C4A,0x0C4A,0},
+{0x0C4B,0x0C4B,0},
+{0x0C4C,0x0C4C,0},
+{0x0C4D,0x0C4D,0},
+{0x0C4E,0x0C4E,0},
+{0x0C4F,0x0C4F,0},
+{0x0C50,0x0C50,0},
+{0x0C51,0x0C51,0},
+{0x0C52,0x0C52,0},
+{0x0C53,0x0C53,0},
+{0x0C54,0x0C54,0},
+{0x0C55,0x0C55,0},
+{0x0C56,0x0C56,0},
+{0x0C57,0x0C57,0},
+{0x0C58,0x0C58,0},
+{0x0C59,0x0C59,0},
+{0x0C5A,0x0C5A,0},
+{0x0C5B,0x0C5B,0},
+{0x0C5C,0x0C5C,0},
+{0x0C5D,0x0C5D,0},
+{0x0C5E,0x0C5E,0},
+{0x0C5F,0x0C5F,0},
+{0x0C60,0x0C60,0},
+{0x0C61,0x0C61,0},
+{0x0C62,0x0C62,0},
+{0x0C63,0x0C63,0},
+{0x0C64,0x0C64,0},
+{0x0C65,0x0C65,0},
+{0x0C66,0x0C66,0},
+{0x0C67,0x0C67,0},
+{0x0C68,0x0C68,0},
+{0x0C69,0x0C69,0},
+{0x0C6A,0x0C6A,0},
+{0x0C6B,0x0C6B,0},
+{0x0C6C,0x0C6C,0},
+{0x0C6D,0x0C6D,0},
+{0x0C6E,0x0C6E,0},
+{0x0C6F,0x0C6F,0},
+{0x0C70,0x0C70,0},
+{0x0C71,0x0C71,0},
+{0x0C72,0x0C72,0},
+{0x0C73,0x0C73,0},
+{0x0C74,0x0C74,0},
+{0x0C75,0x0C75,0},
+{0x0C76,0x0C76,0},
+{0x0C77,0x0C77,0},
+{0x0C78,0x0C78,0},
+{0x0C79,0x0C79,0},
+{0x0C7A,0x0C7A,0},
+{0x0C7B,0x0C7B,0},
+{0x0C7C,0x0C7C,0},
+{0x0C7D,0x0C7D,0},
+{0x0C7E,0x0C7E,0},
+{0x0C7F,0x0C7F,0},
+{0x0C80,0x0C80,0},
+{0x0C81,0x0C81,0},
+{0x0C82,0x0C82,0},
+{0x0C83,0x0C83,0},
+{0x0C84,0x0C84,0},
+{0x0C85,0x0C85,0},
+{0x0C86,0x0C86,0},
+{0x0C87,0x0C87,0},
+{0x0C88,0x0C88,0},
+{0x0C89,0x0C89,0},
+{0x0C8A,0x0C8A,0},
+{0x0C8B,0x0C8B,0},
+{0x0C8C,0x0C8C,0},
+{0x0C8D,0x0C8D,0},
+{0x0C8E,0x0C8E,0},
+{0x0C8F,0x0C8F,0},
+{0x0C90,0x0C90,0},
+{0x0C91,0x0C91,0},
+{0x0C92,0x0C92,0},
+{0x0C93,0x0C93,0},
+{0x0C94,0x0C94,0},
+{0x0C95,0x0C95,0},
+{0x0C96,0x0C96,0},
+{0x0C97,0x0C97,0},
+{0x0C98,0x0C98,0},
+{0x0C99,0x0C99,0},
+{0x0C9A,0x0C9A,0},
+{0x0C9B,0x0C9B,0},
+{0x0C9C,0x0C9C,0},
+{0x0C9D,0x0C9D,0},
+{0x0C9E,0x0C9E,0},
+{0x0C9F,0x0C9F,0},
+{0x0CA0,0x0CA0,0},
+{0x0CA1,0x0CA1,0},
+{0x0CA2,0x0CA2,0},
+{0x0CA3,0x0CA3,0},
+{0x0CA4,0x0CA4,0},
+{0x0CA5,0x0CA5,0},
+{0x0CA6,0x0CA6,0},
+{0x0CA7,0x0CA7,0},
+{0x0CA8,0x0CA8,0},
+{0x0CA9,0x0CA9,0},
+{0x0CAA,0x0CAA,0},
+{0x0CAB,0x0CAB,0},
+{0x0CAC,0x0CAC,0},
+{0x0CAD,0x0CAD,0},
+{0x0CAE,0x0CAE,0},
+{0x0CAF,0x0CAF,0},
+{0x0CB0,0x0CB0,0},
+{0x0CB1,0x0CB1,0},
+{0x0CB2,0x0CB2,0},
+{0x0CB3,0x0CB3,0},
+{0x0CB4,0x0CB4,0},
+{0x0CB5,0x0CB5,0},
+{0x0CB6,0x0CB6,0},
+{0x0CB7,0x0CB7,0},
+{0x0CB8,0x0CB8,0},
+{0x0CB9,0x0CB9,0},
+{0x0CBA,0x0CBA,0},
+{0x0CBB,0x0CBB,0},
+{0x0CBC,0x0CBC,0},
+{0x0CBD,0x0CBD,0},
+{0x0CBE,0x0CBE,0},
+{0x0CBF,0x0CBF,0},
+{0x0CC0,0x0CC0,0},
+{0x0CC1,0x0CC1,0},
+{0x0CC2,0x0CC2,0},
+{0x0CC3,0x0CC3,0},
+{0x0CC4,0x0CC4,0},
+{0x0CC5,0x0CC5,0},
+{0x0CC6,0x0CC6,0},
+{0x0CC7,0x0CC7,0},
+{0x0CC8,0x0CC8,0},
+{0x0CC9,0x0CC9,0},
+{0x0CCA,0x0CCA,0},
+{0x0CCB,0x0CCB,0},
+{0x0CCC,0x0CCC,0},
+{0x0CCD,0x0CCD,0},
+{0x0CCE,0x0CCE,0},
+{0x0CCF,0x0CCF,0},
+{0x0CD0,0x0CD0,0},
+{0x0CD1,0x0CD1,0},
+{0x0CD2,0x0CD2,0},
+{0x0CD3,0x0CD3,0},
+{0x0CD4,0x0CD4,0},
+{0x0CD5,0x0CD5,0},
+{0x0CD6,0x0CD6,0},
+{0x0CD7,0x0CD7,0},
+{0x0CD8,0x0CD8,0},
+{0x0CD9,0x0CD9,0},
+{0x0CDA,0x0CDA,0},
+{0x0CDB,0x0CDB,0},
+{0x0CDC,0x0CDC,0},
+{0x0CDD,0x0CDD,0},
+{0x0CDE,0x0CDE,0},
+{0x0CDF,0x0CDF,0},
+{0x0CE0,0x0CE0,0},
+{0x0CE1,0x0CE1,0},
+{0x0CE2,0x0CE2,0},
+{0x0CE3,0x0CE3,0},
+{0x0CE4,0x0CE4,0},
+{0x0CE5,0x0CE5,0},
+{0x0CE6,0x0CE6,0},
+{0x0CE7,0x0CE7,0},
+{0x0CE8,0x0CE8,0},
+{0x0CE9,0x0CE9,0},
+{0x0CEA,0x0CEA,0},
+{0x0CEB,0x0CEB,0},
+{0x0CEC,0x0CEC,0},
+{0x0CED,0x0CED,0},
+{0x0CEE,0x0CEE,0},
+{0x0CEF,0x0CEF,0},
+{0x0CF0,0x0CF0,0},
+{0x0CF1,0x0CF1,0},
+{0x0CF2,0x0CF2,0},
+{0x0CF3,0x0CF3,0},
+{0x0CF4,0x0CF4,0},
+{0x0CF5,0x0CF5,0},
+{0x0CF6,0x0CF6,0},
+{0x0CF7,0x0CF7,0},
+{0x0CF8,0x0CF8,0},
+{0x0CF9,0x0CF9,0},
+{0x0CFA,0x0CFA,0},
+{0x0CFB,0x0CFB,0},
+{0x0CFC,0x0CFC,0},
+{0x0CFD,0x0CFD,0},
+{0x0CFE,0x0CFE,0},
+{0x0CFF,0x0CFF,0},
+{0x0D00,0x0D00,0},
+{0x0D01,0x0D01,0},
+{0x0D02,0x0D02,0},
+{0x0D03,0x0D03,0},
+{0x0D04,0x0D04,0},
+{0x0D05,0x0D05,0},
+{0x0D06,0x0D06,0},
+{0x0D07,0x0D07,0},
+{0x0D08,0x0D08,0},
+{0x0D09,0x0D09,0},
+{0x0D0A,0x0D0A,0},
+{0x0D0B,0x0D0B,0},
+{0x0D0C,0x0D0C,0},
+{0x0D0D,0x0D0D,0},
+{0x0D0E,0x0D0E,0},
+{0x0D0F,0x0D0F,0},
+{0x0D10,0x0D10,0},
+{0x0D11,0x0D11,0},
+{0x0D12,0x0D12,0},
+{0x0D13,0x0D13,0},
+{0x0D14,0x0D14,0},
+{0x0D15,0x0D15,0},
+{0x0D16,0x0D16,0},
+{0x0D17,0x0D17,0},
+{0x0D18,0x0D18,0},
+{0x0D19,0x0D19,0},
+{0x0D1A,0x0D1A,0},
+{0x0D1B,0x0D1B,0},
+{0x0D1C,0x0D1C,0},
+{0x0D1D,0x0D1D,0},
+{0x0D1E,0x0D1E,0},
+{0x0D1F,0x0D1F,0},
+{0x0D20,0x0D20,0},
+{0x0D21,0x0D21,0},
+{0x0D22,0x0D22,0},
+{0x0D23,0x0D23,0},
+{0x0D24,0x0D24,0},
+{0x0D25,0x0D25,0},
+{0x0D26,0x0D26,0},
+{0x0D27,0x0D27,0},
+{0x0D28,0x0D28,0},
+{0x0D29,0x0D29,0},
+{0x0D2A,0x0D2A,0},
+{0x0D2B,0x0D2B,0},
+{0x0D2C,0x0D2C,0},
+{0x0D2D,0x0D2D,0},
+{0x0D2E,0x0D2E,0},
+{0x0D2F,0x0D2F,0},
+{0x0D30,0x0D30,0},
+{0x0D31,0x0D31,0},
+{0x0D32,0x0D32,0},
+{0x0D33,0x0D33,0},
+{0x0D34,0x0D34,0},
+{0x0D35,0x0D35,0},
+{0x0D36,0x0D36,0},
+{0x0D37,0x0D37,0},
+{0x0D38,0x0D38,0},
+{0x0D39,0x0D39,0},
+{0x0D3A,0x0D3A,0},
+{0x0D3B,0x0D3B,0},
+{0x0D3C,0x0D3C,0},
+{0x0D3D,0x0D3D,0},
+{0x0D3E,0x0D3E,0},
+{0x0D3F,0x0D3F,0},
+{0x0D40,0x0D40,0},
+{0x0D41,0x0D41,0},
+{0x0D42,0x0D42,0},
+{0x0D43,0x0D43,0},
+{0x0D44,0x0D44,0},
+{0x0D45,0x0D45,0},
+{0x0D46,0x0D46,0},
+{0x0D47,0x0D47,0},
+{0x0D48,0x0D48,0},
+{0x0D49,0x0D49,0},
+{0x0D4A,0x0D4A,0},
+{0x0D4B,0x0D4B,0},
+{0x0D4C,0x0D4C,0},
+{0x0D4D,0x0D4D,0},
+{0x0D4E,0x0D4E,0},
+{0x0D4F,0x0D4F,0},
+{0x0D50,0x0D50,0},
+{0x0D51,0x0D51,0},
+{0x0D52,0x0D52,0},
+{0x0D53,0x0D53,0},
+{0x0D54,0x0D54,0},
+{0x0D55,0x0D55,0},
+{0x0D56,0x0D56,0},
+{0x0D57,0x0D57,0},
+{0x0D58,0x0D58,0},
+{0x0D59,0x0D59,0},
+{0x0D5A,0x0D5A,0},
+{0x0D5B,0x0D5B,0},
+{0x0D5C,0x0D5C,0},
+{0x0D5D,0x0D5D,0},
+{0x0D5E,0x0D5E,0},
+{0x0D5F,0x0D5F,0},
+{0x0D60,0x0D60,0},
+{0x0D61,0x0D61,0},
+{0x0D62,0x0D62,0},
+{0x0D63,0x0D63,0},
+{0x0D64,0x0D64,0},
+{0x0D65,0x0D65,0},
+{0x0D66,0x0D66,0},
+{0x0D67,0x0D67,0},
+{0x0D68,0x0D68,0},
+{0x0D69,0x0D69,0},
+{0x0D6A,0x0D6A,0},
+{0x0D6B,0x0D6B,0},
+{0x0D6C,0x0D6C,0},
+{0x0D6D,0x0D6D,0},
+{0x0D6E,0x0D6E,0},
+{0x0D6F,0x0D6F,0},
+{0x0D70,0x0D70,0},
+{0x0D71,0x0D71,0},
+{0x0D72,0x0D72,0},
+{0x0D73,0x0D73,0},
+{0x0D74,0x0D74,0},
+{0x0D75,0x0D75,0},
+{0x0D76,0x0D76,0},
+{0x0D77,0x0D77,0},
+{0x0D78,0x0D78,0},
+{0x0D79,0x0D79,0},
+{0x0D7A,0x0D7A,0},
+{0x0D7B,0x0D7B,0},
+{0x0D7C,0x0D7C,0},
+{0x0D7D,0x0D7D,0},
+{0x0D7E,0x0D7E,0},
+{0x0D7F,0x0D7F,0},
+{0x0D80,0x0D80,0},
+{0x0D81,0x0D81,0},
+{0x0D82,0x0D82,0},
+{0x0D83,0x0D83,0},
+{0x0D84,0x0D84,0},
+{0x0D85,0x0D85,0},
+{0x0D86,0x0D86,0},
+{0x0D87,0x0D87,0},
+{0x0D88,0x0D88,0},
+{0x0D89,0x0D89,0},
+{0x0D8A,0x0D8A,0},
+{0x0D8B,0x0D8B,0},
+{0x0D8C,0x0D8C,0},
+{0x0D8D,0x0D8D,0},
+{0x0D8E,0x0D8E,0},
+{0x0D8F,0x0D8F,0},
+{0x0D90,0x0D90,0},
+{0x0D91,0x0D91,0},
+{0x0D92,0x0D92,0},
+{0x0D93,0x0D93,0},
+{0x0D94,0x0D94,0},
+{0x0D95,0x0D95,0},
+{0x0D96,0x0D96,0},
+{0x0D97,0x0D97,0},
+{0x0D98,0x0D98,0},
+{0x0D99,0x0D99,0},
+{0x0D9A,0x0D9A,0},
+{0x0D9B,0x0D9B,0},
+{0x0D9C,0x0D9C,0},
+{0x0D9D,0x0D9D,0},
+{0x0D9E,0x0D9E,0},
+{0x0D9F,0x0D9F,0},
+{0x0DA0,0x0DA0,0},
+{0x0DA1,0x0DA1,0},
+{0x0DA2,0x0DA2,0},
+{0x0DA3,0x0DA3,0},
+{0x0DA4,0x0DA4,0},
+{0x0DA5,0x0DA5,0},
+{0x0DA6,0x0DA6,0},
+{0x0DA7,0x0DA7,0},
+{0x0DA8,0x0DA8,0},
+{0x0DA9,0x0DA9,0},
+{0x0DAA,0x0DAA,0},
+{0x0DAB,0x0DAB,0},
+{0x0DAC,0x0DAC,0},
+{0x0DAD,0x0DAD,0},
+{0x0DAE,0x0DAE,0},
+{0x0DAF,0x0DAF,0},
+{0x0DB0,0x0DB0,0},
+{0x0DB1,0x0DB1,0},
+{0x0DB2,0x0DB2,0},
+{0x0DB3,0x0DB3,0},
+{0x0DB4,0x0DB4,0},
+{0x0DB5,0x0DB5,0},
+{0x0DB6,0x0DB6,0},
+{0x0DB7,0x0DB7,0},
+{0x0DB8,0x0DB8,0},
+{0x0DB9,0x0DB9,0},
+{0x0DBA,0x0DBA,0},
+{0x0DBB,0x0DBB,0},
+{0x0DBC,0x0DBC,0},
+{0x0DBD,0x0DBD,0},
+{0x0DBE,0x0DBE,0},
+{0x0DBF,0x0DBF,0},
+{0x0DC0,0x0DC0,0},
+{0x0DC1,0x0DC1,0},
+{0x0DC2,0x0DC2,0},
+{0x0DC3,0x0DC3,0},
+{0x0DC4,0x0DC4,0},
+{0x0DC5,0x0DC5,0},
+{0x0DC6,0x0DC6,0},
+{0x0DC7,0x0DC7,0},
+{0x0DC8,0x0DC8,0},
+{0x0DC9,0x0DC9,0},
+{0x0DCA,0x0DCA,0},
+{0x0DCB,0x0DCB,0},
+{0x0DCC,0x0DCC,0},
+{0x0DCD,0x0DCD,0},
+{0x0DCE,0x0DCE,0},
+{0x0DCF,0x0DCF,0},
+{0x0DD0,0x0DD0,0},
+{0x0DD1,0x0DD1,0},
+{0x0DD2,0x0DD2,0},
+{0x0DD3,0x0DD3,0},
+{0x0DD4,0x0DD4,0},
+{0x0DD5,0x0DD5,0},
+{0x0DD6,0x0DD6,0},
+{0x0DD7,0x0DD7,0},
+{0x0DD8,0x0DD8,0},
+{0x0DD9,0x0DD9,0},
+{0x0DDA,0x0DDA,0},
+{0x0DDB,0x0DDB,0},
+{0x0DDC,0x0DDC,0},
+{0x0DDD,0x0DDD,0},
+{0x0DDE,0x0DDE,0},
+{0x0DDF,0x0DDF,0},
+{0x0DE0,0x0DE0,0},
+{0x0DE1,0x0DE1,0},
+{0x0DE2,0x0DE2,0},
+{0x0DE3,0x0DE3,0},
+{0x0DE4,0x0DE4,0},
+{0x0DE5,0x0DE5,0},
+{0x0DE6,0x0DE6,0},
+{0x0DE7,0x0DE7,0},
+{0x0DE8,0x0DE8,0},
+{0x0DE9,0x0DE9,0},
+{0x0DEA,0x0DEA,0},
+{0x0DEB,0x0DEB,0},
+{0x0DEC,0x0DEC,0},
+{0x0DED,0x0DED,0},
+{0x0DEE,0x0DEE,0},
+{0x0DEF,0x0DEF,0},
+{0x0DF0,0x0DF0,0},
+{0x0DF1,0x0DF1,0},
+{0x0DF2,0x0DF2,0},
+{0x0DF3,0x0DF3,0},
+{0x0DF4,0x0DF4,0},
+{0x0DF5,0x0DF5,0},
+{0x0DF6,0x0DF6,0},
+{0x0DF7,0x0DF7,0},
+{0x0DF8,0x0DF8,0},
+{0x0DF9,0x0DF9,0},
+{0x0DFA,0x0DFA,0},
+{0x0DFB,0x0DFB,0},
+{0x0DFC,0x0DFC,0},
+{0x0DFD,0x0DFD,0},
+{0x0DFE,0x0DFE,0},
+{0x0DFF,0x0DFF,0},
+{0x0E00,0x0E00,0},
+{0x0E01,0x0E01,0},
+{0x0E02,0x0E02,0},
+{0x0E03,0x0E03,0},
+{0x0E04,0x0E04,0},
+{0x0E05,0x0E05,0},
+{0x0E06,0x0E06,0},
+{0x0E07,0x0E07,0},
+{0x0E08,0x0E08,0},
+{0x0E09,0x0E09,0},
+{0x0E0A,0x0E0A,0},
+{0x0E0B,0x0E0B,0},
+{0x0E0C,0x0E0C,0},
+{0x0E0D,0x0E0D,0},
+{0x0E0E,0x0E0E,0},
+{0x0E0F,0x0E0F,0},
+{0x0E10,0x0E10,0},
+{0x0E11,0x0E11,0},
+{0x0E12,0x0E12,0},
+{0x0E13,0x0E13,0},
+{0x0E14,0x0E14,0},
+{0x0E15,0x0E15,0},
+{0x0E16,0x0E16,0},
+{0x0E17,0x0E17,0},
+{0x0E18,0x0E18,0},
+{0x0E19,0x0E19,0},
+{0x0E1A,0x0E1A,0},
+{0x0E1B,0x0E1B,0},
+{0x0E1C,0x0E1C,0},
+{0x0E1D,0x0E1D,0},
+{0x0E1E,0x0E1E,0},
+{0x0E1F,0x0E1F,0},
+{0x0E20,0x0E20,0},
+{0x0E21,0x0E21,0},
+{0x0E22,0x0E22,0},
+{0x0E23,0x0E23,0},
+{0x0E24,0x0E24,0},
+{0x0E25,0x0E25,0},
+{0x0E26,0x0E26,0},
+{0x0E27,0x0E27,0},
+{0x0E28,0x0E28,0},
+{0x0E29,0x0E29,0},
+{0x0E2A,0x0E2A,0},
+{0x0E2B,0x0E2B,0},
+{0x0E2C,0x0E2C,0},
+{0x0E2D,0x0E2D,0},
+{0x0E2E,0x0E2E,0},
+{0x0E2F,0x0E2F,0},
+{0x0E30,0x0E30,0},
+{0x0E31,0x0E31,0},
+{0x0E32,0x0E32,0},
+{0x0E33,0x0E33,0},
+{0x0E34,0x0E34,0},
+{0x0E35,0x0E35,0},
+{0x0E36,0x0E36,0},
+{0x0E37,0x0E37,0},
+{0x0E38,0x0E38,0},
+{0x0E39,0x0E39,0},
+{0x0E3A,0x0E3A,0},
+{0x0E3B,0x0E3B,0},
+{0x0E3C,0x0E3C,0},
+{0x0E3D,0x0E3D,0},
+{0x0E3E,0x0E3E,0},
+{0x0E3F,0x0E3F,0},
+{0x0E40,0x0E40,0},
+{0x0E41,0x0E41,0},
+{0x0E42,0x0E42,0},
+{0x0E43,0x0E43,0},
+{0x0E44,0x0E44,0},
+{0x0E45,0x0E45,0},
+{0x0E46,0x0E46,0},
+{0x0E47,0x0E47,0},
+{0x0E48,0x0E48,0},
+{0x0E49,0x0E49,0},
+{0x0E4A,0x0E4A,0},
+{0x0E4B,0x0E4B,0},
+{0x0E4C,0x0E4C,0},
+{0x0E4D,0x0E4D,0},
+{0x0E4E,0x0E4E,0},
+{0x0E4F,0x0E4F,0},
+{0x0E50,0x0E50,0},
+{0x0E51,0x0E51,0},
+{0x0E52,0x0E52,0},
+{0x0E53,0x0E53,0},
+{0x0E54,0x0E54,0},
+{0x0E55,0x0E55,0},
+{0x0E56,0x0E56,0},
+{0x0E57,0x0E57,0},
+{0x0E58,0x0E58,0},
+{0x0E59,0x0E59,0},
+{0x0E5A,0x0E5A,0},
+{0x0E5B,0x0E5B,0},
+{0x0E5C,0x0E5C,0},
+{0x0E5D,0x0E5D,0},
+{0x0E5E,0x0E5E,0},
+{0x0E5F,0x0E5F,0},
+{0x0E60,0x0E60,0},
+{0x0E61,0x0E61,0},
+{0x0E62,0x0E62,0},
+{0x0E63,0x0E63,0},
+{0x0E64,0x0E64,0},
+{0x0E65,0x0E65,0},
+{0x0E66,0x0E66,0},
+{0x0E67,0x0E67,0},
+{0x0E68,0x0E68,0},
+{0x0E69,0x0E69,0},
+{0x0E6A,0x0E6A,0},
+{0x0E6B,0x0E6B,0},
+{0x0E6C,0x0E6C,0},
+{0x0E6D,0x0E6D,0},
+{0x0E6E,0x0E6E,0},
+{0x0E6F,0x0E6F,0},
+{0x0E70,0x0E70,0},
+{0x0E71,0x0E71,0},
+{0x0E72,0x0E72,0},
+{0x0E73,0x0E73,0},
+{0x0E74,0x0E74,0},
+{0x0E75,0x0E75,0},
+{0x0E76,0x0E76,0},
+{0x0E77,0x0E77,0},
+{0x0E78,0x0E78,0},
+{0x0E79,0x0E79,0},
+{0x0E7A,0x0E7A,0},
+{0x0E7B,0x0E7B,0},
+{0x0E7C,0x0E7C,0},
+{0x0E7D,0x0E7D,0},
+{0x0E7E,0x0E7E,0},
+{0x0E7F,0x0E7F,0},
+{0x0E80,0x0E80,0},
+{0x0E81,0x0E81,0},
+{0x0E82,0x0E82,0},
+{0x0E83,0x0E83,0},
+{0x0E84,0x0E84,0},
+{0x0E85,0x0E85,0},
+{0x0E86,0x0E86,0},
+{0x0E87,0x0E87,0},
+{0x0E88,0x0E88,0},
+{0x0E89,0x0E89,0},
+{0x0E8A,0x0E8A,0},
+{0x0E8B,0x0E8B,0},
+{0x0E8C,0x0E8C,0},
+{0x0E8D,0x0E8D,0},
+{0x0E8E,0x0E8E,0},
+{0x0E8F,0x0E8F,0},
+{0x0E90,0x0E90,0},
+{0x0E91,0x0E91,0},
+{0x0E92,0x0E92,0},
+{0x0E93,0x0E93,0},
+{0x0E94,0x0E94,0},
+{0x0E95,0x0E95,0},
+{0x0E96,0x0E96,0},
+{0x0E97,0x0E97,0},
+{0x0E98,0x0E98,0},
+{0x0E99,0x0E99,0},
+{0x0E9A,0x0E9A,0},
+{0x0E9B,0x0E9B,0},
+{0x0E9C,0x0E9C,0},
+{0x0E9D,0x0E9D,0},
+{0x0E9E,0x0E9E,0},
+{0x0E9F,0x0E9F,0},
+{0x0EA0,0x0EA0,0},
+{0x0EA1,0x0EA1,0},
+{0x0EA2,0x0EA2,0},
+{0x0EA3,0x0EA3,0},
+{0x0EA4,0x0EA4,0},
+{0x0EA5,0x0EA5,0},
+{0x0EA6,0x0EA6,0},
+{0x0EA7,0x0EA7,0},
+{0x0EA8,0x0EA8,0},
+{0x0EA9,0x0EA9,0},
+{0x0EAA,0x0EAA,0},
+{0x0EAB,0x0EAB,0},
+{0x0EAC,0x0EAC,0},
+{0x0EAD,0x0EAD,0},
+{0x0EAE,0x0EAE,0},
+{0x0EAF,0x0EAF,0},
+{0x0EB0,0x0EB0,0},
+{0x0EB1,0x0EB1,0},
+{0x0EB2,0x0EB2,0},
+{0x0EB3,0x0EB3,0},
+{0x0EB4,0x0EB4,0},
+{0x0EB5,0x0EB5,0},
+{0x0EB6,0x0EB6,0},
+{0x0EB7,0x0EB7,0},
+{0x0EB8,0x0EB8,0},
+{0x0EB9,0x0EB9,0},
+{0x0EBA,0x0EBA,0},
+{0x0EBB,0x0EBB,0},
+{0x0EBC,0x0EBC,0},
+{0x0EBD,0x0EBD,0},
+{0x0EBE,0x0EBE,0},
+{0x0EBF,0x0EBF,0},
+{0x0EC0,0x0EC0,0},
+{0x0EC1,0x0EC1,0},
+{0x0EC2,0x0EC2,0},
+{0x0EC3,0x0EC3,0},
+{0x0EC4,0x0EC4,0},
+{0x0EC5,0x0EC5,0},
+{0x0EC6,0x0EC6,0},
+{0x0EC7,0x0EC7,0},
+{0x0EC8,0x0EC8,0},
+{0x0EC9,0x0EC9,0},
+{0x0ECA,0x0ECA,0},
+{0x0ECB,0x0ECB,0},
+{0x0ECC,0x0ECC,0},
+{0x0ECD,0x0ECD,0},
+{0x0ECE,0x0ECE,0},
+{0x0ECF,0x0ECF,0},
+{0x0ED0,0x0ED0,0},
+{0x0ED1,0x0ED1,0},
+{0x0ED2,0x0ED2,0},
+{0x0ED3,0x0ED3,0},
+{0x0ED4,0x0ED4,0},
+{0x0ED5,0x0ED5,0},
+{0x0ED6,0x0ED6,0},
+{0x0ED7,0x0ED7,0},
+{0x0ED8,0x0ED8,0},
+{0x0ED9,0x0ED9,0},
+{0x0EDA,0x0EDA,0},
+{0x0EDB,0x0EDB,0},
+{0x0EDC,0x0EDC,0},
+{0x0EDD,0x0EDD,0},
+{0x0EDE,0x0EDE,0},
+{0x0EDF,0x0EDF,0},
+{0x0EE0,0x0EE0,0},
+{0x0EE1,0x0EE1,0},
+{0x0EE2,0x0EE2,0},
+{0x0EE3,0x0EE3,0},
+{0x0EE4,0x0EE4,0},
+{0x0EE5,0x0EE5,0},
+{0x0EE6,0x0EE6,0},
+{0x0EE7,0x0EE7,0},
+{0x0EE8,0x0EE8,0},
+{0x0EE9,0x0EE9,0},
+{0x0EEA,0x0EEA,0},
+{0x0EEB,0x0EEB,0},
+{0x0EEC,0x0EEC,0},
+{0x0EED,0x0EED,0},
+{0x0EEE,0x0EEE,0},
+{0x0EEF,0x0EEF,0},
+{0x0EF0,0x0EF0,0},
+{0x0EF1,0x0EF1,0},
+{0x0EF2,0x0EF2,0},
+{0x0EF3,0x0EF3,0},
+{0x0EF4,0x0EF4,0},
+{0x0EF5,0x0EF5,0},
+{0x0EF6,0x0EF6,0},
+{0x0EF7,0x0EF7,0},
+{0x0EF8,0x0EF8,0},
+{0x0EF9,0x0EF9,0},
+{0x0EFA,0x0EFA,0},
+{0x0EFB,0x0EFB,0},
+{0x0EFC,0x0EFC,0},
+{0x0EFD,0x0EFD,0},
+{0x0EFE,0x0EFE,0},
+{0x0EFF,0x0EFF,0},
+{0x0F00,0x0F00,0},
+{0x0F01,0x0F01,0},
+{0x0F02,0x0F02,0},
+{0x0F03,0x0F03,0},
+{0x0F04,0x0F04,0},
+{0x0F05,0x0F05,0},
+{0x0F06,0x0F06,0},
+{0x0F07,0x0F07,0},
+{0x0F08,0x0F08,0},
+{0x0F09,0x0F09,0},
+{0x0F0A,0x0F0A,0},
+{0x0F0B,0x0F0B,0},
+{0x0F0C,0x0F0C,0},
+{0x0F0D,0x0F0D,0},
+{0x0F0E,0x0F0E,0},
+{0x0F0F,0x0F0F,0},
+{0x0F10,0x0F10,0},
+{0x0F11,0x0F11,0},
+{0x0F12,0x0F12,0},
+{0x0F13,0x0F13,0},
+{0x0F14,0x0F14,0},
+{0x0F15,0x0F15,0},
+{0x0F16,0x0F16,0},
+{0x0F17,0x0F17,0},
+{0x0F18,0x0F18,0},
+{0x0F19,0x0F19,0},
+{0x0F1A,0x0F1A,0},
+{0x0F1B,0x0F1B,0},
+{0x0F1C,0x0F1C,0},
+{0x0F1D,0x0F1D,0},
+{0x0F1E,0x0F1E,0},
+{0x0F1F,0x0F1F,0},
+{0x0F20,0x0F20,0},
+{0x0F21,0x0F21,0},
+{0x0F22,0x0F22,0},
+{0x0F23,0x0F23,0},
+{0x0F24,0x0F24,0},
+{0x0F25,0x0F25,0},
+{0x0F26,0x0F26,0},
+{0x0F27,0x0F27,0},
+{0x0F28,0x0F28,0},
+{0x0F29,0x0F29,0},
+{0x0F2A,0x0F2A,0},
+{0x0F2B,0x0F2B,0},
+{0x0F2C,0x0F2C,0},
+{0x0F2D,0x0F2D,0},
+{0x0F2E,0x0F2E,0},
+{0x0F2F,0x0F2F,0},
+{0x0F30,0x0F30,0},
+{0x0F31,0x0F31,0},
+{0x0F32,0x0F32,0},
+{0x0F33,0x0F33,0},
+{0x0F34,0x0F34,0},
+{0x0F35,0x0F35,0},
+{0x0F36,0x0F36,0},
+{0x0F37,0x0F37,0},
+{0x0F38,0x0F38,0},
+{0x0F39,0x0F39,0},
+{0x0F3A,0x0F3A,0},
+{0x0F3B,0x0F3B,0},
+{0x0F3C,0x0F3C,0},
+{0x0F3D,0x0F3D,0},
+{0x0F3E,0x0F3E,0},
+{0x0F3F,0x0F3F,0},
+{0x0F40,0x0F40,0},
+{0x0F41,0x0F41,0},
+{0x0F42,0x0F42,0},
+{0x0F43,0x0F43,0},
+{0x0F44,0x0F44,0},
+{0x0F45,0x0F45,0},
+{0x0F46,0x0F46,0},
+{0x0F47,0x0F47,0},
+{0x0F48,0x0F48,0},
+{0x0F49,0x0F49,0},
+{0x0F4A,0x0F4A,0},
+{0x0F4B,0x0F4B,0},
+{0x0F4C,0x0F4C,0},
+{0x0F4D,0x0F4D,0},
+{0x0F4E,0x0F4E,0},
+{0x0F4F,0x0F4F,0},
+{0x0F50,0x0F50,0},
+{0x0F51,0x0F51,0},
+{0x0F52,0x0F52,0},
+{0x0F53,0x0F53,0},
+{0x0F54,0x0F54,0},
+{0x0F55,0x0F55,0},
+{0x0F56,0x0F56,0},
+{0x0F57,0x0F57,0},
+{0x0F58,0x0F58,0},
+{0x0F59,0x0F59,0},
+{0x0F5A,0x0F5A,0},
+{0x0F5B,0x0F5B,0},
+{0x0F5C,0x0F5C,0},
+{0x0F5D,0x0F5D,0},
+{0x0F5E,0x0F5E,0},
+{0x0F5F,0x0F5F,0},
+{0x0F60,0x0F60,0},
+{0x0F61,0x0F61,0},
+{0x0F62,0x0F62,0},
+{0x0F63,0x0F63,0},
+{0x0F64,0x0F64,0},
+{0x0F65,0x0F65,0},
+{0x0F66,0x0F66,0},
+{0x0F67,0x0F67,0},
+{0x0F68,0x0F68,0},
+{0x0F69,0x0F69,0},
+{0x0F6A,0x0F6A,0},
+{0x0F6B,0x0F6B,0},
+{0x0F6C,0x0F6C,0},
+{0x0F6D,0x0F6D,0},
+{0x0F6E,0x0F6E,0},
+{0x0F6F,0x0F6F,0},
+{0x0F70,0x0F70,0},
+{0x0F71,0x0F71,0},
+{0x0F72,0x0F72,0},
+{0x0F73,0x0F73,0},
+{0x0F74,0x0F74,0},
+{0x0F75,0x0F75,0},
+{0x0F76,0x0F76,0},
+{0x0F77,0x0F77,0},
+{0x0F78,0x0F78,0},
+{0x0F79,0x0F79,0},
+{0x0F7A,0x0F7A,0},
+{0x0F7B,0x0F7B,0},
+{0x0F7C,0x0F7C,0},
+{0x0F7D,0x0F7D,0},
+{0x0F7E,0x0F7E,0},
+{0x0F7F,0x0F7F,0},
+{0x0F80,0x0F80,0},
+{0x0F81,0x0F81,0},
+{0x0F82,0x0F82,0},
+{0x0F83,0x0F83,0},
+{0x0F84,0x0F84,0},
+{0x0F85,0x0F85,0},
+{0x0F86,0x0F86,0},
+{0x0F87,0x0F87,0},
+{0x0F88,0x0F88,0},
+{0x0F89,0x0F89,0},
+{0x0F8A,0x0F8A,0},
+{0x0F8B,0x0F8B,0},
+{0x0F8C,0x0F8C,0},
+{0x0F8D,0x0F8D,0},
+{0x0F8E,0x0F8E,0},
+{0x0F8F,0x0F8F,0},
+{0x0F90,0x0F90,0},
+{0x0F91,0x0F91,0},
+{0x0F92,0x0F92,0},
+{0x0F93,0x0F93,0},
+{0x0F94,0x0F94,0},
+{0x0F95,0x0F95,0},
+{0x0F96,0x0F96,0},
+{0x0F97,0x0F97,0},
+{0x0F98,0x0F98,0},
+{0x0F99,0x0F99,0},
+{0x0F9A,0x0F9A,0},
+{0x0F9B,0x0F9B,0},
+{0x0F9C,0x0F9C,0},
+{0x0F9D,0x0F9D,0},
+{0x0F9E,0x0F9E,0},
+{0x0F9F,0x0F9F,0},
+{0x0FA0,0x0FA0,0},
+{0x0FA1,0x0FA1,0},
+{0x0FA2,0x0FA2,0},
+{0x0FA3,0x0FA3,0},
+{0x0FA4,0x0FA4,0},
+{0x0FA5,0x0FA5,0},
+{0x0FA6,0x0FA6,0},
+{0x0FA7,0x0FA7,0},
+{0x0FA8,0x0FA8,0},
+{0x0FA9,0x0FA9,0},
+{0x0FAA,0x0FAA,0},
+{0x0FAB,0x0FAB,0},
+{0x0FAC,0x0FAC,0},
+{0x0FAD,0x0FAD,0},
+{0x0FAE,0x0FAE,0},
+{0x0FAF,0x0FAF,0},
+{0x0FB0,0x0FB0,0},
+{0x0FB1,0x0FB1,0},
+{0x0FB2,0x0FB2,0},
+{0x0FB3,0x0FB3,0},
+{0x0FB4,0x0FB4,0},
+{0x0FB5,0x0FB5,0},
+{0x0FB6,0x0FB6,0},
+{0x0FB7,0x0FB7,0},
+{0x0FB8,0x0FB8,0},
+{0x0FB9,0x0FB9,0},
+{0x0FBA,0x0FBA,0},
+{0x0FBB,0x0FBB,0},
+{0x0FBC,0x0FBC,0},
+{0x0FBD,0x0FBD,0},
+{0x0FBE,0x0FBE,0},
+{0x0FBF,0x0FBF,0},
+{0x0FC0,0x0FC0,0},
+{0x0FC1,0x0FC1,0},
+{0x0FC2,0x0FC2,0},
+{0x0FC3,0x0FC3,0},
+{0x0FC4,0x0FC4,0},
+{0x0FC5,0x0FC5,0},
+{0x0FC6,0x0FC6,0},
+{0x0FC7,0x0FC7,0},
+{0x0FC8,0x0FC8,0},
+{0x0FC9,0x0FC9,0},
+{0x0FCA,0x0FCA,0},
+{0x0FCB,0x0FCB,0},
+{0x0FCC,0x0FCC,0},
+{0x0FCD,0x0FCD,0},
+{0x0FCE,0x0FCE,0},
+{0x0FCF,0x0FCF,0},
+{0x0FD0,0x0FD0,0},
+{0x0FD1,0x0FD1,0},
+{0x0FD2,0x0FD2,0},
+{0x0FD3,0x0FD3,0},
+{0x0FD4,0x0FD4,0},
+{0x0FD5,0x0FD5,0},
+{0x0FD6,0x0FD6,0},
+{0x0FD7,0x0FD7,0},
+{0x0FD8,0x0FD8,0},
+{0x0FD9,0x0FD9,0},
+{0x0FDA,0x0FDA,0},
+{0x0FDB,0x0FDB,0},
+{0x0FDC,0x0FDC,0},
+{0x0FDD,0x0FDD,0},
+{0x0FDE,0x0FDE,0},
+{0x0FDF,0x0FDF,0},
+{0x0FE0,0x0FE0,0},
+{0x0FE1,0x0FE1,0},
+{0x0FE2,0x0FE2,0},
+{0x0FE3,0x0FE3,0},
+{0x0FE4,0x0FE4,0},
+{0x0FE5,0x0FE5,0},
+{0x0FE6,0x0FE6,0},
+{0x0FE7,0x0FE7,0},
+{0x0FE8,0x0FE8,0},
+{0x0FE9,0x0FE9,0},
+{0x0FEA,0x0FEA,0},
+{0x0FEB,0x0FEB,0},
+{0x0FEC,0x0FEC,0},
+{0x0FED,0x0FED,0},
+{0x0FEE,0x0FEE,0},
+{0x0FEF,0x0FEF,0},
+{0x0FF0,0x0FF0,0},
+{0x0FF1,0x0FF1,0},
+{0x0FF2,0x0FF2,0},
+{0x0FF3,0x0FF3,0},
+{0x0FF4,0x0FF4,0},
+{0x0FF5,0x0FF5,0},
+{0x0FF6,0x0FF6,0},
+{0x0FF7,0x0FF7,0},
+{0x0FF8,0x0FF8,0},
+{0x0FF9,0x0FF9,0},
+{0x0FFA,0x0FFA,0},
+{0x0FFB,0x0FFB,0},
+{0x0FFC,0x0FFC,0},
+{0x0FFD,0x0FFD,0},
+{0x0FFE,0x0FFE,0},
+{0x0FFF,0x0FFF,0},
+{0x1000,0x1000,0},
+{0x1001,0x1001,0},
+{0x1002,0x1002,0},
+{0x1003,0x1003,0},
+{0x1004,0x1004,0},
+{0x1005,0x1005,0},
+{0x1006,0x1006,0},
+{0x1007,0x1007,0},
+{0x1008,0x1008,0},
+{0x1009,0x1009,0},
+{0x100A,0x100A,0},
+{0x100B,0x100B,0},
+{0x100C,0x100C,0},
+{0x100D,0x100D,0},
+{0x100E,0x100E,0},
+{0x100F,0x100F,0},
+{0x1010,0x1010,0},
+{0x1011,0x1011,0},
+{0x1012,0x1012,0},
+{0x1013,0x1013,0},
+{0x1014,0x1014,0},
+{0x1015,0x1015,0},
+{0x1016,0x1016,0},
+{0x1017,0x1017,0},
+{0x1018,0x1018,0},
+{0x1019,0x1019,0},
+{0x101A,0x101A,0},
+{0x101B,0x101B,0},
+{0x101C,0x101C,0},
+{0x101D,0x101D,0},
+{0x101E,0x101E,0},
+{0x101F,0x101F,0},
+{0x1020,0x1020,0},
+{0x1021,0x1021,0},
+{0x1022,0x1022,0},
+{0x1023,0x1023,0},
+{0x1024,0x1024,0},
+{0x1025,0x1025,0},
+{0x1026,0x1026,0},
+{0x1027,0x1027,0},
+{0x1028,0x1028,0},
+{0x1029,0x1029,0},
+{0x102A,0x102A,0},
+{0x102B,0x102B,0},
+{0x102C,0x102C,0},
+{0x102D,0x102D,0},
+{0x102E,0x102E,0},
+{0x102F,0x102F,0},
+{0x1030,0x1030,0},
+{0x1031,0x1031,0},
+{0x1032,0x1032,0},
+{0x1033,0x1033,0},
+{0x1034,0x1034,0},
+{0x1035,0x1035,0},
+{0x1036,0x1036,0},
+{0x1037,0x1037,0},
+{0x1038,0x1038,0},
+{0x1039,0x1039,0},
+{0x103A,0x103A,0},
+{0x103B,0x103B,0},
+{0x103C,0x103C,0},
+{0x103D,0x103D,0},
+{0x103E,0x103E,0},
+{0x103F,0x103F,0},
+{0x1040,0x1040,0},
+{0x1041,0x1041,0},
+{0x1042,0x1042,0},
+{0x1043,0x1043,0},
+{0x1044,0x1044,0},
+{0x1045,0x1045,0},
+{0x1046,0x1046,0},
+{0x1047,0x1047,0},
+{0x1048,0x1048,0},
+{0x1049,0x1049,0},
+{0x104A,0x104A,0},
+{0x104B,0x104B,0},
+{0x104C,0x104C,0},
+{0x104D,0x104D,0},
+{0x104E,0x104E,0},
+{0x104F,0x104F,0},
+{0x1050,0x1050,0},
+{0x1051,0x1051,0},
+{0x1052,0x1052,0},
+{0x1053,0x1053,0},
+{0x1054,0x1054,0},
+{0x1055,0x1055,0},
+{0x1056,0x1056,0},
+{0x1057,0x1057,0},
+{0x1058,0x1058,0},
+{0x1059,0x1059,0},
+{0x105A,0x105A,0},
+{0x105B,0x105B,0},
+{0x105C,0x105C,0},
+{0x105D,0x105D,0},
+{0x105E,0x105E,0},
+{0x105F,0x105F,0},
+{0x1060,0x1060,0},
+{0x1061,0x1061,0},
+{0x1062,0x1062,0},
+{0x1063,0x1063,0},
+{0x1064,0x1064,0},
+{0x1065,0x1065,0},
+{0x1066,0x1066,0},
+{0x1067,0x1067,0},
+{0x1068,0x1068,0},
+{0x1069,0x1069,0},
+{0x106A,0x106A,0},
+{0x106B,0x106B,0},
+{0x106C,0x106C,0},
+{0x106D,0x106D,0},
+{0x106E,0x106E,0},
+{0x106F,0x106F,0},
+{0x1070,0x1070,0},
+{0x1071,0x1071,0},
+{0x1072,0x1072,0},
+{0x1073,0x1073,0},
+{0x1074,0x1074,0},
+{0x1075,0x1075,0},
+{0x1076,0x1076,0},
+{0x1077,0x1077,0},
+{0x1078,0x1078,0},
+{0x1079,0x1079,0},
+{0x107A,0x107A,0},
+{0x107B,0x107B,0},
+{0x107C,0x107C,0},
+{0x107D,0x107D,0},
+{0x107E,0x107E,0},
+{0x107F,0x107F,0},
+{0x1080,0x1080,0},
+{0x1081,0x1081,0},
+{0x1082,0x1082,0},
+{0x1083,0x1083,0},
+{0x1084,0x1084,0},
+{0x1085,0x1085,0},
+{0x1086,0x1086,0},
+{0x1087,0x1087,0},
+{0x1088,0x1088,0},
+{0x1089,0x1089,0},
+{0x108A,0x108A,0},
+{0x108B,0x108B,0},
+{0x108C,0x108C,0},
+{0x108D,0x108D,0},
+{0x108E,0x108E,0},
+{0x108F,0x108F,0},
+{0x1090,0x1090,0},
+{0x1091,0x1091,0},
+{0x1092,0x1092,0},
+{0x1093,0x1093,0},
+{0x1094,0x1094,0},
+{0x1095,0x1095,0},
+{0x1096,0x1096,0},
+{0x1097,0x1097,0},
+{0x1098,0x1098,0},
+{0x1099,0x1099,0},
+{0x109A,0x109A,0},
+{0x109B,0x109B,0},
+{0x109C,0x109C,0},
+{0x109D,0x109D,0},
+{0x109E,0x109E,0},
+{0x109F,0x109F,0},
+{0x10A0,0x10A0,UNI_UPPER},
+{0x10A1,0x10A1,UNI_UPPER},
+{0x10A2,0x10A2,UNI_UPPER},
+{0x10A3,0x10A3,UNI_UPPER},
+{0x10A4,0x10A4,UNI_UPPER},
+{0x10A5,0x10A5,UNI_UPPER},
+{0x10A6,0x10A6,UNI_UPPER},
+{0x10A7,0x10A7,UNI_UPPER},
+{0x10A8,0x10A8,UNI_UPPER},
+{0x10A9,0x10A9,UNI_UPPER},
+{0x10AA,0x10AA,UNI_UPPER},
+{0x10AB,0x10AB,UNI_UPPER},
+{0x10AC,0x10AC,UNI_UPPER},
+{0x10AD,0x10AD,UNI_UPPER},
+{0x10AE,0x10AE,UNI_UPPER},
+{0x10AF,0x10AF,UNI_UPPER},
+{0x10B0,0x10B0,UNI_UPPER},
+{0x10B1,0x10B1,UNI_UPPER},
+{0x10B2,0x10B2,UNI_UPPER},
+{0x10B3,0x10B3,UNI_UPPER},
+{0x10B4,0x10B4,UNI_UPPER},
+{0x10B5,0x10B5,UNI_UPPER},
+{0x10B6,0x10B6,UNI_UPPER},
+{0x10B7,0x10B7,UNI_UPPER},
+{0x10B8,0x10B8,UNI_UPPER},
+{0x10B9,0x10B9,UNI_UPPER},
+{0x10BA,0x10BA,UNI_UPPER},
+{0x10BB,0x10BB,UNI_UPPER},
+{0x10BC,0x10BC,UNI_UPPER},
+{0x10BD,0x10BD,UNI_UPPER},
+{0x10BE,0x10BE,UNI_UPPER},
+{0x10BF,0x10BF,UNI_UPPER},
+{0x10C0,0x10C0,UNI_UPPER},
+{0x10C1,0x10C1,UNI_UPPER},
+{0x10C2,0x10C2,UNI_UPPER},
+{0x10C3,0x10C3,UNI_UPPER},
+{0x10C4,0x10C4,UNI_UPPER},
+{0x10C5,0x10C5,UNI_UPPER},
+{0x10C6,0x10C6,0},
+{0x10C7,0x10C7,0},
+{0x10C8,0x10C8,0},
+{0x10C9,0x10C9,0},
+{0x10CA,0x10CA,0},
+{0x10CB,0x10CB,0},
+{0x10CC,0x10CC,0},
+{0x10CD,0x10CD,0},
+{0x10CE,0x10CE,0},
+{0x10CF,0x10CF,0},
+{0x10D0,0x10D0,0},
+{0x10D1,0x10D1,0},
+{0x10D2,0x10D2,0},
+{0x10D3,0x10D3,0},
+{0x10D4,0x10D4,0},
+{0x10D5,0x10D5,0},
+{0x10D6,0x10D6,0},
+{0x10D7,0x10D7,0},
+{0x10D8,0x10D8,0},
+{0x10D9,0x10D9,0},
+{0x10DA,0x10DA,0},
+{0x10DB,0x10DB,0},
+{0x10DC,0x10DC,0},
+{0x10DD,0x10DD,0},
+{0x10DE,0x10DE,0},
+{0x10DF,0x10DF,0},
+{0x10E0,0x10E0,0},
+{0x10E1,0x10E1,0},
+{0x10E2,0x10E2,0},
+{0x10E3,0x10E3,0},
+{0x10E4,0x10E4,0},
+{0x10E5,0x10E5,0},
+{0x10E6,0x10E6,0},
+{0x10E7,0x10E7,0},
+{0x10E8,0x10E8,0},
+{0x10E9,0x10E9,0},
+{0x10EA,0x10EA,0},
+{0x10EB,0x10EB,0},
+{0x10EC,0x10EC,0},
+{0x10ED,0x10ED,0},
+{0x10EE,0x10EE,0},
+{0x10EF,0x10EF,0},
+{0x10F0,0x10F0,0},
+{0x10F1,0x10F1,0},
+{0x10F2,0x10F2,0},
+{0x10F3,0x10F3,0},
+{0x10F4,0x10F4,0},
+{0x10F5,0x10F5,0},
+{0x10F6,0x10F6,0},
+{0x10F7,0x10F7,0},
+{0x10F8,0x10F8,0},
+{0x10F9,0x10F9,0},
+{0x10FA,0x10FA,0},
+{0x10FB,0x10FB,0},
+{0x10FC,0x10FC,0},
+{0x10FD,0x10FD,0},
+{0x10FE,0x10FE,0},
+{0x10FF,0x10FF,0},
+{0x1100,0x1100,0},
+{0x1101,0x1101,0},
+{0x1102,0x1102,0},
+{0x1103,0x1103,0},
+{0x1104,0x1104,0},
+{0x1105,0x1105,0},
+{0x1106,0x1106,0},
+{0x1107,0x1107,0},
+{0x1108,0x1108,0},
+{0x1109,0x1109,0},
+{0x110A,0x110A,0},
+{0x110B,0x110B,0},
+{0x110C,0x110C,0},
+{0x110D,0x110D,0},
+{0x110E,0x110E,0},
+{0x110F,0x110F,0},
+{0x1110,0x1110,0},
+{0x1111,0x1111,0},
+{0x1112,0x1112,0},
+{0x1113,0x1113,0},
+{0x1114,0x1114,0},
+{0x1115,0x1115,0},
+{0x1116,0x1116,0},
+{0x1117,0x1117,0},
+{0x1118,0x1118,0},
+{0x1119,0x1119,0},
+{0x111A,0x111A,0},
+{0x111B,0x111B,0},
+{0x111C,0x111C,0},
+{0x111D,0x111D,0},
+{0x111E,0x111E,0},
+{0x111F,0x111F,0},
+{0x1120,0x1120,0},
+{0x1121,0x1121,0},
+{0x1122,0x1122,0},
+{0x1123,0x1123,0},
+{0x1124,0x1124,0},
+{0x1125,0x1125,0},
+{0x1126,0x1126,0},
+{0x1127,0x1127,0},
+{0x1128,0x1128,0},
+{0x1129,0x1129,0},
+{0x112A,0x112A,0},
+{0x112B,0x112B,0},
+{0x112C,0x112C,0},
+{0x112D,0x112D,0},
+{0x112E,0x112E,0},
+{0x112F,0x112F,0},
+{0x1130,0x1130,0},
+{0x1131,0x1131,0},
+{0x1132,0x1132,0},
+{0x1133,0x1133,0},
+{0x1134,0x1134,0},
+{0x1135,0x1135,0},
+{0x1136,0x1136,0},
+{0x1137,0x1137,0},
+{0x1138,0x1138,0},
+{0x1139,0x1139,0},
+{0x113A,0x113A,0},
+{0x113B,0x113B,0},
+{0x113C,0x113C,0},
+{0x113D,0x113D,0},
+{0x113E,0x113E,0},
+{0x113F,0x113F,0},
+{0x1140,0x1140,0},
+{0x1141,0x1141,0},
+{0x1142,0x1142,0},
+{0x1143,0x1143,0},
+{0x1144,0x1144,0},
+{0x1145,0x1145,0},
+{0x1146,0x1146,0},
+{0x1147,0x1147,0},
+{0x1148,0x1148,0},
+{0x1149,0x1149,0},
+{0x114A,0x114A,0},
+{0x114B,0x114B,0},
+{0x114C,0x114C,0},
+{0x114D,0x114D,0},
+{0x114E,0x114E,0},
+{0x114F,0x114F,0},
+{0x1150,0x1150,0},
+{0x1151,0x1151,0},
+{0x1152,0x1152,0},
+{0x1153,0x1153,0},
+{0x1154,0x1154,0},
+{0x1155,0x1155,0},
+{0x1156,0x1156,0},
+{0x1157,0x1157,0},
+{0x1158,0x1158,0},
+{0x1159,0x1159,0},
+{0x115A,0x115A,0},
+{0x115B,0x115B,0},
+{0x115C,0x115C,0},
+{0x115D,0x115D,0},
+{0x115E,0x115E,0},
+{0x115F,0x115F,0},
+{0x1160,0x1160,0},
+{0x1161,0x1161,0},
+{0x1162,0x1162,0},
+{0x1163,0x1163,0},
+{0x1164,0x1164,0},
+{0x1165,0x1165,0},
+{0x1166,0x1166,0},
+{0x1167,0x1167,0},
+{0x1168,0x1168,0},
+{0x1169,0x1169,0},
+{0x116A,0x116A,0},
+{0x116B,0x116B,0},
+{0x116C,0x116C,0},
+{0x116D,0x116D,0},
+{0x116E,0x116E,0},
+{0x116F,0x116F,0},
+{0x1170,0x1170,0},
+{0x1171,0x1171,0},
+{0x1172,0x1172,0},
+{0x1173,0x1173,0},
+{0x1174,0x1174,0},
+{0x1175,0x1175,0},
+{0x1176,0x1176,0},
+{0x1177,0x1177,0},
+{0x1178,0x1178,0},
+{0x1179,0x1179,0},
+{0x117A,0x117A,0},
+{0x117B,0x117B,0},
+{0x117C,0x117C,0},
+{0x117D,0x117D,0},
+{0x117E,0x117E,0},
+{0x117F,0x117F,0},
+{0x1180,0x1180,0},
+{0x1181,0x1181,0},
+{0x1182,0x1182,0},
+{0x1183,0x1183,0},
+{0x1184,0x1184,0},
+{0x1185,0x1185,0},
+{0x1186,0x1186,0},
+{0x1187,0x1187,0},
+{0x1188,0x1188,0},
+{0x1189,0x1189,0},
+{0x118A,0x118A,0},
+{0x118B,0x118B,0},
+{0x118C,0x118C,0},
+{0x118D,0x118D,0},
+{0x118E,0x118E,0},
+{0x118F,0x118F,0},
+{0x1190,0x1190,0},
+{0x1191,0x1191,0},
+{0x1192,0x1192,0},
+{0x1193,0x1193,0},
+{0x1194,0x1194,0},
+{0x1195,0x1195,0},
+{0x1196,0x1196,0},
+{0x1197,0x1197,0},
+{0x1198,0x1198,0},
+{0x1199,0x1199,0},
+{0x119A,0x119A,0},
+{0x119B,0x119B,0},
+{0x119C,0x119C,0},
+{0x119D,0x119D,0},
+{0x119E,0x119E,0},
+{0x119F,0x119F,0},
+{0x11A0,0x11A0,0},
+{0x11A1,0x11A1,0},
+{0x11A2,0x11A2,0},
+{0x11A3,0x11A3,0},
+{0x11A4,0x11A4,0},
+{0x11A5,0x11A5,0},
+{0x11A6,0x11A6,0},
+{0x11A7,0x11A7,0},
+{0x11A8,0x11A8,0},
+{0x11A9,0x11A9,0},
+{0x11AA,0x11AA,0},
+{0x11AB,0x11AB,0},
+{0x11AC,0x11AC,0},
+{0x11AD,0x11AD,0},
+{0x11AE,0x11AE,0},
+{0x11AF,0x11AF,0},
+{0x11B0,0x11B0,0},
+{0x11B1,0x11B1,0},
+{0x11B2,0x11B2,0},
+{0x11B3,0x11B3,0},
+{0x11B4,0x11B4,0},
+{0x11B5,0x11B5,0},
+{0x11B6,0x11B6,0},
+{0x11B7,0x11B7,0},
+{0x11B8,0x11B8,0},
+{0x11B9,0x11B9,0},
+{0x11BA,0x11BA,0},
+{0x11BB,0x11BB,0},
+{0x11BC,0x11BC,0},
+{0x11BD,0x11BD,0},
+{0x11BE,0x11BE,0},
+{0x11BF,0x11BF,0},
+{0x11C0,0x11C0,0},
+{0x11C1,0x11C1,0},
+{0x11C2,0x11C2,0},
+{0x11C3,0x11C3,0},
+{0x11C4,0x11C4,0},
+{0x11C5,0x11C5,0},
+{0x11C6,0x11C6,0},
+{0x11C7,0x11C7,0},
+{0x11C8,0x11C8,0},
+{0x11C9,0x11C9,0},
+{0x11CA,0x11CA,0},
+{0x11CB,0x11CB,0},
+{0x11CC,0x11CC,0},
+{0x11CD,0x11CD,0},
+{0x11CE,0x11CE,0},
+{0x11CF,0x11CF,0},
+{0x11D0,0x11D0,0},
+{0x11D1,0x11D1,0},
+{0x11D2,0x11D2,0},
+{0x11D3,0x11D3,0},
+{0x11D4,0x11D4,0},
+{0x11D5,0x11D5,0},
+{0x11D6,0x11D6,0},
+{0x11D7,0x11D7,0},
+{0x11D8,0x11D8,0},
+{0x11D9,0x11D9,0},
+{0x11DA,0x11DA,0},
+{0x11DB,0x11DB,0},
+{0x11DC,0x11DC,0},
+{0x11DD,0x11DD,0},
+{0x11DE,0x11DE,0},
+{0x11DF,0x11DF,0},
+{0x11E0,0x11E0,0},
+{0x11E1,0x11E1,0},
+{0x11E2,0x11E2,0},
+{0x11E3,0x11E3,0},
+{0x11E4,0x11E4,0},
+{0x11E5,0x11E5,0},
+{0x11E6,0x11E6,0},
+{0x11E7,0x11E7,0},
+{0x11E8,0x11E8,0},
+{0x11E9,0x11E9,0},
+{0x11EA,0x11EA,0},
+{0x11EB,0x11EB,0},
+{0x11EC,0x11EC,0},
+{0x11ED,0x11ED,0},
+{0x11EE,0x11EE,0},
+{0x11EF,0x11EF,0},
+{0x11F0,0x11F0,0},
+{0x11F1,0x11F1,0},
+{0x11F2,0x11F2,0},
+{0x11F3,0x11F3,0},
+{0x11F4,0x11F4,0},
+{0x11F5,0x11F5,0},
+{0x11F6,0x11F6,0},
+{0x11F7,0x11F7,0},
+{0x11F8,0x11F8,0},
+{0x11F9,0x11F9,0},
+{0x11FA,0x11FA,0},
+{0x11FB,0x11FB,0},
+{0x11FC,0x11FC,0},
+{0x11FD,0x11FD,0},
+{0x11FE,0x11FE,0},
+{0x11FF,0x11FF,0},
+{0x1200,0x1200,0},
+{0x1201,0x1201,0},
+{0x1202,0x1202,0},
+{0x1203,0x1203,0},
+{0x1204,0x1204,0},
+{0x1205,0x1205,0},
+{0x1206,0x1206,0},
+{0x1207,0x1207,0},
+{0x1208,0x1208,0},
+{0x1209,0x1209,0},
+{0x120A,0x120A,0},
+{0x120B,0x120B,0},
+{0x120C,0x120C,0},
+{0x120D,0x120D,0},
+{0x120E,0x120E,0},
+{0x120F,0x120F,0},
+{0x1210,0x1210,0},
+{0x1211,0x1211,0},
+{0x1212,0x1212,0},
+{0x1213,0x1213,0},
+{0x1214,0x1214,0},
+{0x1215,0x1215,0},
+{0x1216,0x1216,0},
+{0x1217,0x1217,0},
+{0x1218,0x1218,0},
+{0x1219,0x1219,0},
+{0x121A,0x121A,0},
+{0x121B,0x121B,0},
+{0x121C,0x121C,0},
+{0x121D,0x121D,0},
+{0x121E,0x121E,0},
+{0x121F,0x121F,0},
+{0x1220,0x1220,0},
+{0x1221,0x1221,0},
+{0x1222,0x1222,0},
+{0x1223,0x1223,0},
+{0x1224,0x1224,0},
+{0x1225,0x1225,0},
+{0x1226,0x1226,0},
+{0x1227,0x1227,0},
+{0x1228,0x1228,0},
+{0x1229,0x1229,0},
+{0x122A,0x122A,0},
+{0x122B,0x122B,0},
+{0x122C,0x122C,0},
+{0x122D,0x122D,0},
+{0x122E,0x122E,0},
+{0x122F,0x122F,0},
+{0x1230,0x1230,0},
+{0x1231,0x1231,0},
+{0x1232,0x1232,0},
+{0x1233,0x1233,0},
+{0x1234,0x1234,0},
+{0x1235,0x1235,0},
+{0x1236,0x1236,0},
+{0x1237,0x1237,0},
+{0x1238,0x1238,0},
+{0x1239,0x1239,0},
+{0x123A,0x123A,0},
+{0x123B,0x123B,0},
+{0x123C,0x123C,0},
+{0x123D,0x123D,0},
+{0x123E,0x123E,0},
+{0x123F,0x123F,0},
+{0x1240,0x1240,0},
+{0x1241,0x1241,0},
+{0x1242,0x1242,0},
+{0x1243,0x1243,0},
+{0x1244,0x1244,0},
+{0x1245,0x1245,0},
+{0x1246,0x1246,0},
+{0x1247,0x1247,0},
+{0x1248,0x1248,0},
+{0x1249,0x1249,0},
+{0x124A,0x124A,0},
+{0x124B,0x124B,0},
+{0x124C,0x124C,0},
+{0x124D,0x124D,0},
+{0x124E,0x124E,0},
+{0x124F,0x124F,0},
+{0x1250,0x1250,0},
+{0x1251,0x1251,0},
+{0x1252,0x1252,0},
+{0x1253,0x1253,0},
+{0x1254,0x1254,0},
+{0x1255,0x1255,0},
+{0x1256,0x1256,0},
+{0x1257,0x1257,0},
+{0x1258,0x1258,0},
+{0x1259,0x1259,0},
+{0x125A,0x125A,0},
+{0x125B,0x125B,0},
+{0x125C,0x125C,0},
+{0x125D,0x125D,0},
+{0x125E,0x125E,0},
+{0x125F,0x125F,0},
+{0x1260,0x1260,0},
+{0x1261,0x1261,0},
+{0x1262,0x1262,0},
+{0x1263,0x1263,0},
+{0x1264,0x1264,0},
+{0x1265,0x1265,0},
+{0x1266,0x1266,0},
+{0x1267,0x1267,0},
+{0x1268,0x1268,0},
+{0x1269,0x1269,0},
+{0x126A,0x126A,0},
+{0x126B,0x126B,0},
+{0x126C,0x126C,0},
+{0x126D,0x126D,0},
+{0x126E,0x126E,0},
+{0x126F,0x126F,0},
+{0x1270,0x1270,0},
+{0x1271,0x1271,0},
+{0x1272,0x1272,0},
+{0x1273,0x1273,0},
+{0x1274,0x1274,0},
+{0x1275,0x1275,0},
+{0x1276,0x1276,0},
+{0x1277,0x1277,0},
+{0x1278,0x1278,0},
+{0x1279,0x1279,0},
+{0x127A,0x127A,0},
+{0x127B,0x127B,0},
+{0x127C,0x127C,0},
+{0x127D,0x127D,0},
+{0x127E,0x127E,0},
+{0x127F,0x127F,0},
+{0x1280,0x1280,0},
+{0x1281,0x1281,0},
+{0x1282,0x1282,0},
+{0x1283,0x1283,0},
+{0x1284,0x1284,0},
+{0x1285,0x1285,0},
+{0x1286,0x1286,0},
+{0x1287,0x1287,0},
+{0x1288,0x1288,0},
+{0x1289,0x1289,0},
+{0x128A,0x128A,0},
+{0x128B,0x128B,0},
+{0x128C,0x128C,0},
+{0x128D,0x128D,0},
+{0x128E,0x128E,0},
+{0x128F,0x128F,0},
+{0x1290,0x1290,0},
+{0x1291,0x1291,0},
+{0x1292,0x1292,0},
+{0x1293,0x1293,0},
+{0x1294,0x1294,0},
+{0x1295,0x1295,0},
+{0x1296,0x1296,0},
+{0x1297,0x1297,0},
+{0x1298,0x1298,0},
+{0x1299,0x1299,0},
+{0x129A,0x129A,0},
+{0x129B,0x129B,0},
+{0x129C,0x129C,0},
+{0x129D,0x129D,0},
+{0x129E,0x129E,0},
+{0x129F,0x129F,0},
+{0x12A0,0x12A0,0},
+{0x12A1,0x12A1,0},
+{0x12A2,0x12A2,0},
+{0x12A3,0x12A3,0},
+{0x12A4,0x12A4,0},
+{0x12A5,0x12A5,0},
+{0x12A6,0x12A6,0},
+{0x12A7,0x12A7,0},
+{0x12A8,0x12A8,0},
+{0x12A9,0x12A9,0},
+{0x12AA,0x12AA,0},
+{0x12AB,0x12AB,0},
+{0x12AC,0x12AC,0},
+{0x12AD,0x12AD,0},
+{0x12AE,0x12AE,0},
+{0x12AF,0x12AF,0},
+{0x12B0,0x12B0,0},
+{0x12B1,0x12B1,0},
+{0x12B2,0x12B2,0},
+{0x12B3,0x12B3,0},
+{0x12B4,0x12B4,0},
+{0x12B5,0x12B5,0},
+{0x12B6,0x12B6,0},
+{0x12B7,0x12B7,0},
+{0x12B8,0x12B8,0},
+{0x12B9,0x12B9,0},
+{0x12BA,0x12BA,0},
+{0x12BB,0x12BB,0},
+{0x12BC,0x12BC,0},
+{0x12BD,0x12BD,0},
+{0x12BE,0x12BE,0},
+{0x12BF,0x12BF,0},
+{0x12C0,0x12C0,0},
+{0x12C1,0x12C1,0},
+{0x12C2,0x12C2,0},
+{0x12C3,0x12C3,0},
+{0x12C4,0x12C4,0},
+{0x12C5,0x12C5,0},
+{0x12C6,0x12C6,0},
+{0x12C7,0x12C7,0},
+{0x12C8,0x12C8,0},
+{0x12C9,0x12C9,0},
+{0x12CA,0x12CA,0},
+{0x12CB,0x12CB,0},
+{0x12CC,0x12CC,0},
+{0x12CD,0x12CD,0},
+{0x12CE,0x12CE,0},
+{0x12CF,0x12CF,0},
+{0x12D0,0x12D0,0},
+{0x12D1,0x12D1,0},
+{0x12D2,0x12D2,0},
+{0x12D3,0x12D3,0},
+{0x12D4,0x12D4,0},
+{0x12D5,0x12D5,0},
+{0x12D6,0x12D6,0},
+{0x12D7,0x12D7,0},
+{0x12D8,0x12D8,0},
+{0x12D9,0x12D9,0},
+{0x12DA,0x12DA,0},
+{0x12DB,0x12DB,0},
+{0x12DC,0x12DC,0},
+{0x12DD,0x12DD,0},
+{0x12DE,0x12DE,0},
+{0x12DF,0x12DF,0},
+{0x12E0,0x12E0,0},
+{0x12E1,0x12E1,0},
+{0x12E2,0x12E2,0},
+{0x12E3,0x12E3,0},
+{0x12E4,0x12E4,0},
+{0x12E5,0x12E5,0},
+{0x12E6,0x12E6,0},
+{0x12E7,0x12E7,0},
+{0x12E8,0x12E8,0},
+{0x12E9,0x12E9,0},
+{0x12EA,0x12EA,0},
+{0x12EB,0x12EB,0},
+{0x12EC,0x12EC,0},
+{0x12ED,0x12ED,0},
+{0x12EE,0x12EE,0},
+{0x12EF,0x12EF,0},
+{0x12F0,0x12F0,0},
+{0x12F1,0x12F1,0},
+{0x12F2,0x12F2,0},
+{0x12F3,0x12F3,0},
+{0x12F4,0x12F4,0},
+{0x12F5,0x12F5,0},
+{0x12F6,0x12F6,0},
+{0x12F7,0x12F7,0},
+{0x12F8,0x12F8,0},
+{0x12F9,0x12F9,0},
+{0x12FA,0x12FA,0},
+{0x12FB,0x12FB,0},
+{0x12FC,0x12FC,0},
+{0x12FD,0x12FD,0},
+{0x12FE,0x12FE,0},
+{0x12FF,0x12FF,0},
+{0x1300,0x1300,0},
+{0x1301,0x1301,0},
+{0x1302,0x1302,0},
+{0x1303,0x1303,0},
+{0x1304,0x1304,0},
+{0x1305,0x1305,0},
+{0x1306,0x1306,0},
+{0x1307,0x1307,0},
+{0x1308,0x1308,0},
+{0x1309,0x1309,0},
+{0x130A,0x130A,0},
+{0x130B,0x130B,0},
+{0x130C,0x130C,0},
+{0x130D,0x130D,0},
+{0x130E,0x130E,0},
+{0x130F,0x130F,0},
+{0x1310,0x1310,0},
+{0x1311,0x1311,0},
+{0x1312,0x1312,0},
+{0x1313,0x1313,0},
+{0x1314,0x1314,0},
+{0x1315,0x1315,0},
+{0x1316,0x1316,0},
+{0x1317,0x1317,0},
+{0x1318,0x1318,0},
+{0x1319,0x1319,0},
+{0x131A,0x131A,0},
+{0x131B,0x131B,0},
+{0x131C,0x131C,0},
+{0x131D,0x131D,0},
+{0x131E,0x131E,0},
+{0x131F,0x131F,0},
+{0x1320,0x1320,0},
+{0x1321,0x1321,0},
+{0x1322,0x1322,0},
+{0x1323,0x1323,0},
+{0x1324,0x1324,0},
+{0x1325,0x1325,0},
+{0x1326,0x1326,0},
+{0x1327,0x1327,0},
+{0x1328,0x1328,0},
+{0x1329,0x1329,0},
+{0x132A,0x132A,0},
+{0x132B,0x132B,0},
+{0x132C,0x132C,0},
+{0x132D,0x132D,0},
+{0x132E,0x132E,0},
+{0x132F,0x132F,0},
+{0x1330,0x1330,0},
+{0x1331,0x1331,0},
+{0x1332,0x1332,0},
+{0x1333,0x1333,0},
+{0x1334,0x1334,0},
+{0x1335,0x1335,0},
+{0x1336,0x1336,0},
+{0x1337,0x1337,0},
+{0x1338,0x1338,0},
+{0x1339,0x1339,0},
+{0x133A,0x133A,0},
+{0x133B,0x133B,0},
+{0x133C,0x133C,0},
+{0x133D,0x133D,0},
+{0x133E,0x133E,0},
+{0x133F,0x133F,0},
+{0x1340,0x1340,0},
+{0x1341,0x1341,0},
+{0x1342,0x1342,0},
+{0x1343,0x1343,0},
+{0x1344,0x1344,0},
+{0x1345,0x1345,0},
+{0x1346,0x1346,0},
+{0x1347,0x1347,0},
+{0x1348,0x1348,0},
+{0x1349,0x1349,0},
+{0x134A,0x134A,0},
+{0x134B,0x134B,0},
+{0x134C,0x134C,0},
+{0x134D,0x134D,0},
+{0x134E,0x134E,0},
+{0x134F,0x134F,0},
+{0x1350,0x1350,0},
+{0x1351,0x1351,0},
+{0x1352,0x1352,0},
+{0x1353,0x1353,0},
+{0x1354,0x1354,0},
+{0x1355,0x1355,0},
+{0x1356,0x1356,0},
+{0x1357,0x1357,0},
+{0x1358,0x1358,0},
+{0x1359,0x1359,0},
+{0x135A,0x135A,0},
+{0x135B,0x135B,0},
+{0x135C,0x135C,0},
+{0x135D,0x135D,0},
+{0x135E,0x135E,0},
+{0x135F,0x135F,0},
+{0x1360,0x1360,0},
+{0x1361,0x1361,0},
+{0x1362,0x1362,0},
+{0x1363,0x1363,0},
+{0x1364,0x1364,0},
+{0x1365,0x1365,0},
+{0x1366,0x1366,0},
+{0x1367,0x1367,0},
+{0x1368,0x1368,0},
+{0x1369,0x1369,0},
+{0x136A,0x136A,0},
+{0x136B,0x136B,0},
+{0x136C,0x136C,0},
+{0x136D,0x136D,0},
+{0x136E,0x136E,0},
+{0x136F,0x136F,0},
+{0x1370,0x1370,0},
+{0x1371,0x1371,0},
+{0x1372,0x1372,0},
+{0x1373,0x1373,0},
+{0x1374,0x1374,0},
+{0x1375,0x1375,0},
+{0x1376,0x1376,0},
+{0x1377,0x1377,0},
+{0x1378,0x1378,0},
+{0x1379,0x1379,0},
+{0x137A,0x137A,0},
+{0x137B,0x137B,0},
+{0x137C,0x137C,0},
+{0x137D,0x137D,0},
+{0x137E,0x137E,0},
+{0x137F,0x137F,0},
+{0x1380,0x1380,0},
+{0x1381,0x1381,0},
+{0x1382,0x1382,0},
+{0x1383,0x1383,0},
+{0x1384,0x1384,0},
+{0x1385,0x1385,0},
+{0x1386,0x1386,0},
+{0x1387,0x1387,0},
+{0x1388,0x1388,0},
+{0x1389,0x1389,0},
+{0x138A,0x138A,0},
+{0x138B,0x138B,0},
+{0x138C,0x138C,0},
+{0x138D,0x138D,0},
+{0x138E,0x138E,0},
+{0x138F,0x138F,0},
+{0x1390,0x1390,0},
+{0x1391,0x1391,0},
+{0x1392,0x1392,0},
+{0x1393,0x1393,0},
+{0x1394,0x1394,0},
+{0x1395,0x1395,0},
+{0x1396,0x1396,0},
+{0x1397,0x1397,0},
+{0x1398,0x1398,0},
+{0x1399,0x1399,0},
+{0x139A,0x139A,0},
+{0x139B,0x139B,0},
+{0x139C,0x139C,0},
+{0x139D,0x139D,0},
+{0x139E,0x139E,0},
+{0x139F,0x139F,0},
+{0x13A0,0x13A0,0},
+{0x13A1,0x13A1,0},
+{0x13A2,0x13A2,0},
+{0x13A3,0x13A3,0},
+{0x13A4,0x13A4,0},
+{0x13A5,0x13A5,0},
+{0x13A6,0x13A6,0},
+{0x13A7,0x13A7,0},
+{0x13A8,0x13A8,0},
+{0x13A9,0x13A9,0},
+{0x13AA,0x13AA,0},
+{0x13AB,0x13AB,0},
+{0x13AC,0x13AC,0},
+{0x13AD,0x13AD,0},
+{0x13AE,0x13AE,0},
+{0x13AF,0x13AF,0},
+{0x13B0,0x13B0,0},
+{0x13B1,0x13B1,0},
+{0x13B2,0x13B2,0},
+{0x13B3,0x13B3,0},
+{0x13B4,0x13B4,0},
+{0x13B5,0x13B5,0},
+{0x13B6,0x13B6,0},
+{0x13B7,0x13B7,0},
+{0x13B8,0x13B8,0},
+{0x13B9,0x13B9,0},
+{0x13BA,0x13BA,0},
+{0x13BB,0x13BB,0},
+{0x13BC,0x13BC,0},
+{0x13BD,0x13BD,0},
+{0x13BE,0x13BE,0},
+{0x13BF,0x13BF,0},
+{0x13C0,0x13C0,0},
+{0x13C1,0x13C1,0},
+{0x13C2,0x13C2,0},
+{0x13C3,0x13C3,0},
+{0x13C4,0x13C4,0},
+{0x13C5,0x13C5,0},
+{0x13C6,0x13C6,0},
+{0x13C7,0x13C7,0},
+{0x13C8,0x13C8,0},
+{0x13C9,0x13C9,0},
+{0x13CA,0x13CA,0},
+{0x13CB,0x13CB,0},
+{0x13CC,0x13CC,0},
+{0x13CD,0x13CD,0},
+{0x13CE,0x13CE,0},
+{0x13CF,0x13CF,0},
+{0x13D0,0x13D0,0},
+{0x13D1,0x13D1,0},
+{0x13D2,0x13D2,0},
+{0x13D3,0x13D3,0},
+{0x13D4,0x13D4,0},
+{0x13D5,0x13D5,0},
+{0x13D6,0x13D6,0},
+{0x13D7,0x13D7,0},
+{0x13D8,0x13D8,0},
+{0x13D9,0x13D9,0},
+{0x13DA,0x13DA,0},
+{0x13DB,0x13DB,0},
+{0x13DC,0x13DC,0},
+{0x13DD,0x13DD,0},
+{0x13DE,0x13DE,0},
+{0x13DF,0x13DF,0},
+{0x13E0,0x13E0,0},
+{0x13E1,0x13E1,0},
+{0x13E2,0x13E2,0},
+{0x13E3,0x13E3,0},
+{0x13E4,0x13E4,0},
+{0x13E5,0x13E5,0},
+{0x13E6,0x13E6,0},
+{0x13E7,0x13E7,0},
+{0x13E8,0x13E8,0},
+{0x13E9,0x13E9,0},
+{0x13EA,0x13EA,0},
+{0x13EB,0x13EB,0},
+{0x13EC,0x13EC,0},
+{0x13ED,0x13ED,0},
+{0x13EE,0x13EE,0},
+{0x13EF,0x13EF,0},
+{0x13F0,0x13F0,0},
+{0x13F1,0x13F1,0},
+{0x13F2,0x13F2,0},
+{0x13F3,0x13F3,0},
+{0x13F4,0x13F4,0},
+{0x13F5,0x13F5,0},
+{0x13F6,0x13F6,0},
+{0x13F7,0x13F7,0},
+{0x13F8,0x13F8,0},
+{0x13F9,0x13F9,0},
+{0x13FA,0x13FA,0},
+{0x13FB,0x13FB,0},
+{0x13FC,0x13FC,0},
+{0x13FD,0x13FD,0},
+{0x13FE,0x13FE,0},
+{0x13FF,0x13FF,0},
+{0x1400,0x1400,0},
+{0x1401,0x1401,0},
+{0x1402,0x1402,0},
+{0x1403,0x1403,0},
+{0x1404,0x1404,0},
+{0x1405,0x1405,0},
+{0x1406,0x1406,0},
+{0x1407,0x1407,0},
+{0x1408,0x1408,0},
+{0x1409,0x1409,0},
+{0x140A,0x140A,0},
+{0x140B,0x140B,0},
+{0x140C,0x140C,0},
+{0x140D,0x140D,0},
+{0x140E,0x140E,0},
+{0x140F,0x140F,0},
+{0x1410,0x1410,0},
+{0x1411,0x1411,0},
+{0x1412,0x1412,0},
+{0x1413,0x1413,0},
+{0x1414,0x1414,0},
+{0x1415,0x1415,0},
+{0x1416,0x1416,0},
+{0x1417,0x1417,0},
+{0x1418,0x1418,0},
+{0x1419,0x1419,0},
+{0x141A,0x141A,0},
+{0x141B,0x141B,0},
+{0x141C,0x141C,0},
+{0x141D,0x141D,0},
+{0x141E,0x141E,0},
+{0x141F,0x141F,0},
+{0x1420,0x1420,0},
+{0x1421,0x1421,0},
+{0x1422,0x1422,0},
+{0x1423,0x1423,0},
+{0x1424,0x1424,0},
+{0x1425,0x1425,0},
+{0x1426,0x1426,0},
+{0x1427,0x1427,0},
+{0x1428,0x1428,0},
+{0x1429,0x1429,0},
+{0x142A,0x142A,0},
+{0x142B,0x142B,0},
+{0x142C,0x142C,0},
+{0x142D,0x142D,0},
+{0x142E,0x142E,0},
+{0x142F,0x142F,0},
+{0x1430,0x1430,0},
+{0x1431,0x1431,0},
+{0x1432,0x1432,0},
+{0x1433,0x1433,0},
+{0x1434,0x1434,0},
+{0x1435,0x1435,0},
+{0x1436,0x1436,0},
+{0x1437,0x1437,0},
+{0x1438,0x1438,0},
+{0x1439,0x1439,0},
+{0x143A,0x143A,0},
+{0x143B,0x143B,0},
+{0x143C,0x143C,0},
+{0x143D,0x143D,0},
+{0x143E,0x143E,0},
+{0x143F,0x143F,0},
+{0x1440,0x1440,0},
+{0x1441,0x1441,0},
+{0x1442,0x1442,0},
+{0x1443,0x1443,0},
+{0x1444,0x1444,0},
+{0x1445,0x1445,0},
+{0x1446,0x1446,0},
+{0x1447,0x1447,0},
+{0x1448,0x1448,0},
+{0x1449,0x1449,0},
+{0x144A,0x144A,0},
+{0x144B,0x144B,0},
+{0x144C,0x144C,0},
+{0x144D,0x144D,0},
+{0x144E,0x144E,0},
+{0x144F,0x144F,0},
+{0x1450,0x1450,0},
+{0x1451,0x1451,0},
+{0x1452,0x1452,0},
+{0x1453,0x1453,0},
+{0x1454,0x1454,0},
+{0x1455,0x1455,0},
+{0x1456,0x1456,0},
+{0x1457,0x1457,0},
+{0x1458,0x1458,0},
+{0x1459,0x1459,0},
+{0x145A,0x145A,0},
+{0x145B,0x145B,0},
+{0x145C,0x145C,0},
+{0x145D,0x145D,0},
+{0x145E,0x145E,0},
+{0x145F,0x145F,0},
+{0x1460,0x1460,0},
+{0x1461,0x1461,0},
+{0x1462,0x1462,0},
+{0x1463,0x1463,0},
+{0x1464,0x1464,0},
+{0x1465,0x1465,0},
+{0x1466,0x1466,0},
+{0x1467,0x1467,0},
+{0x1468,0x1468,0},
+{0x1469,0x1469,0},
+{0x146A,0x146A,0},
+{0x146B,0x146B,0},
+{0x146C,0x146C,0},
+{0x146D,0x146D,0},
+{0x146E,0x146E,0},
+{0x146F,0x146F,0},
+{0x1470,0x1470,0},
+{0x1471,0x1471,0},
+{0x1472,0x1472,0},
+{0x1473,0x1473,0},
+{0x1474,0x1474,0},
+{0x1475,0x1475,0},
+{0x1476,0x1476,0},
+{0x1477,0x1477,0},
+{0x1478,0x1478,0},
+{0x1479,0x1479,0},
+{0x147A,0x147A,0},
+{0x147B,0x147B,0},
+{0x147C,0x147C,0},
+{0x147D,0x147D,0},
+{0x147E,0x147E,0},
+{0x147F,0x147F,0},
+{0x1480,0x1480,0},
+{0x1481,0x1481,0},
+{0x1482,0x1482,0},
+{0x1483,0x1483,0},
+{0x1484,0x1484,0},
+{0x1485,0x1485,0},
+{0x1486,0x1486,0},
+{0x1487,0x1487,0},
+{0x1488,0x1488,0},
+{0x1489,0x1489,0},
+{0x148A,0x148A,0},
+{0x148B,0x148B,0},
+{0x148C,0x148C,0},
+{0x148D,0x148D,0},
+{0x148E,0x148E,0},
+{0x148F,0x148F,0},
+{0x1490,0x1490,0},
+{0x1491,0x1491,0},
+{0x1492,0x1492,0},
+{0x1493,0x1493,0},
+{0x1494,0x1494,0},
+{0x1495,0x1495,0},
+{0x1496,0x1496,0},
+{0x1497,0x1497,0},
+{0x1498,0x1498,0},
+{0x1499,0x1499,0},
+{0x149A,0x149A,0},
+{0x149B,0x149B,0},
+{0x149C,0x149C,0},
+{0x149D,0x149D,0},
+{0x149E,0x149E,0},
+{0x149F,0x149F,0},
+{0x14A0,0x14A0,0},
+{0x14A1,0x14A1,0},
+{0x14A2,0x14A2,0},
+{0x14A3,0x14A3,0},
+{0x14A4,0x14A4,0},
+{0x14A5,0x14A5,0},
+{0x14A6,0x14A6,0},
+{0x14A7,0x14A7,0},
+{0x14A8,0x14A8,0},
+{0x14A9,0x14A9,0},
+{0x14AA,0x14AA,0},
+{0x14AB,0x14AB,0},
+{0x14AC,0x14AC,0},
+{0x14AD,0x14AD,0},
+{0x14AE,0x14AE,0},
+{0x14AF,0x14AF,0},
+{0x14B0,0x14B0,0},
+{0x14B1,0x14B1,0},
+{0x14B2,0x14B2,0},
+{0x14B3,0x14B3,0},
+{0x14B4,0x14B4,0},
+{0x14B5,0x14B5,0},
+{0x14B6,0x14B6,0},
+{0x14B7,0x14B7,0},
+{0x14B8,0x14B8,0},
+{0x14B9,0x14B9,0},
+{0x14BA,0x14BA,0},
+{0x14BB,0x14BB,0},
+{0x14BC,0x14BC,0},
+{0x14BD,0x14BD,0},
+{0x14BE,0x14BE,0},
+{0x14BF,0x14BF,0},
+{0x14C0,0x14C0,0},
+{0x14C1,0x14C1,0},
+{0x14C2,0x14C2,0},
+{0x14C3,0x14C3,0},
+{0x14C4,0x14C4,0},
+{0x14C5,0x14C5,0},
+{0x14C6,0x14C6,0},
+{0x14C7,0x14C7,0},
+{0x14C8,0x14C8,0},
+{0x14C9,0x14C9,0},
+{0x14CA,0x14CA,0},
+{0x14CB,0x14CB,0},
+{0x14CC,0x14CC,0},
+{0x14CD,0x14CD,0},
+{0x14CE,0x14CE,0},
+{0x14CF,0x14CF,0},
+{0x14D0,0x14D0,0},
+{0x14D1,0x14D1,0},
+{0x14D2,0x14D2,0},
+{0x14D3,0x14D3,0},
+{0x14D4,0x14D4,0},
+{0x14D5,0x14D5,0},
+{0x14D6,0x14D6,0},
+{0x14D7,0x14D7,0},
+{0x14D8,0x14D8,0},
+{0x14D9,0x14D9,0},
+{0x14DA,0x14DA,0},
+{0x14DB,0x14DB,0},
+{0x14DC,0x14DC,0},
+{0x14DD,0x14DD,0},
+{0x14DE,0x14DE,0},
+{0x14DF,0x14DF,0},
+{0x14E0,0x14E0,0},
+{0x14E1,0x14E1,0},
+{0x14E2,0x14E2,0},
+{0x14E3,0x14E3,0},
+{0x14E4,0x14E4,0},
+{0x14E5,0x14E5,0},
+{0x14E6,0x14E6,0},
+{0x14E7,0x14E7,0},
+{0x14E8,0x14E8,0},
+{0x14E9,0x14E9,0},
+{0x14EA,0x14EA,0},
+{0x14EB,0x14EB,0},
+{0x14EC,0x14EC,0},
+{0x14ED,0x14ED,0},
+{0x14EE,0x14EE,0},
+{0x14EF,0x14EF,0},
+{0x14F0,0x14F0,0},
+{0x14F1,0x14F1,0},
+{0x14F2,0x14F2,0},
+{0x14F3,0x14F3,0},
+{0x14F4,0x14F4,0},
+{0x14F5,0x14F5,0},
+{0x14F6,0x14F6,0},
+{0x14F7,0x14F7,0},
+{0x14F8,0x14F8,0},
+{0x14F9,0x14F9,0},
+{0x14FA,0x14FA,0},
+{0x14FB,0x14FB,0},
+{0x14FC,0x14FC,0},
+{0x14FD,0x14FD,0},
+{0x14FE,0x14FE,0},
+{0x14FF,0x14FF,0},
+{0x1500,0x1500,0},
+{0x1501,0x1501,0},
+{0x1502,0x1502,0},
+{0x1503,0x1503,0},
+{0x1504,0x1504,0},
+{0x1505,0x1505,0},
+{0x1506,0x1506,0},
+{0x1507,0x1507,0},
+{0x1508,0x1508,0},
+{0x1509,0x1509,0},
+{0x150A,0x150A,0},
+{0x150B,0x150B,0},
+{0x150C,0x150C,0},
+{0x150D,0x150D,0},
+{0x150E,0x150E,0},
+{0x150F,0x150F,0},
+{0x1510,0x1510,0},
+{0x1511,0x1511,0},
+{0x1512,0x1512,0},
+{0x1513,0x1513,0},
+{0x1514,0x1514,0},
+{0x1515,0x1515,0},
+{0x1516,0x1516,0},
+{0x1517,0x1517,0},
+{0x1518,0x1518,0},
+{0x1519,0x1519,0},
+{0x151A,0x151A,0},
+{0x151B,0x151B,0},
+{0x151C,0x151C,0},
+{0x151D,0x151D,0},
+{0x151E,0x151E,0},
+{0x151F,0x151F,0},
+{0x1520,0x1520,0},
+{0x1521,0x1521,0},
+{0x1522,0x1522,0},
+{0x1523,0x1523,0},
+{0x1524,0x1524,0},
+{0x1525,0x1525,0},
+{0x1526,0x1526,0},
+{0x1527,0x1527,0},
+{0x1528,0x1528,0},
+{0x1529,0x1529,0},
+{0x152A,0x152A,0},
+{0x152B,0x152B,0},
+{0x152C,0x152C,0},
+{0x152D,0x152D,0},
+{0x152E,0x152E,0},
+{0x152F,0x152F,0},
+{0x1530,0x1530,0},
+{0x1531,0x1531,0},
+{0x1532,0x1532,0},
+{0x1533,0x1533,0},
+{0x1534,0x1534,0},
+{0x1535,0x1535,0},
+{0x1536,0x1536,0},
+{0x1537,0x1537,0},
+{0x1538,0x1538,0},
+{0x1539,0x1539,0},
+{0x153A,0x153A,0},
+{0x153B,0x153B,0},
+{0x153C,0x153C,0},
+{0x153D,0x153D,0},
+{0x153E,0x153E,0},
+{0x153F,0x153F,0},
+{0x1540,0x1540,0},
+{0x1541,0x1541,0},
+{0x1542,0x1542,0},
+{0x1543,0x1543,0},
+{0x1544,0x1544,0},
+{0x1545,0x1545,0},
+{0x1546,0x1546,0},
+{0x1547,0x1547,0},
+{0x1548,0x1548,0},
+{0x1549,0x1549,0},
+{0x154A,0x154A,0},
+{0x154B,0x154B,0},
+{0x154C,0x154C,0},
+{0x154D,0x154D,0},
+{0x154E,0x154E,0},
+{0x154F,0x154F,0},
+{0x1550,0x1550,0},
+{0x1551,0x1551,0},
+{0x1552,0x1552,0},
+{0x1553,0x1553,0},
+{0x1554,0x1554,0},
+{0x1555,0x1555,0},
+{0x1556,0x1556,0},
+{0x1557,0x1557,0},
+{0x1558,0x1558,0},
+{0x1559,0x1559,0},
+{0x155A,0x155A,0},
+{0x155B,0x155B,0},
+{0x155C,0x155C,0},
+{0x155D,0x155D,0},
+{0x155E,0x155E,0},
+{0x155F,0x155F,0},
+{0x1560,0x1560,0},
+{0x1561,0x1561,0},
+{0x1562,0x1562,0},
+{0x1563,0x1563,0},
+{0x1564,0x1564,0},
+{0x1565,0x1565,0},
+{0x1566,0x1566,0},
+{0x1567,0x1567,0},
+{0x1568,0x1568,0},
+{0x1569,0x1569,0},
+{0x156A,0x156A,0},
+{0x156B,0x156B,0},
+{0x156C,0x156C,0},
+{0x156D,0x156D,0},
+{0x156E,0x156E,0},
+{0x156F,0x156F,0},
+{0x1570,0x1570,0},
+{0x1571,0x1571,0},
+{0x1572,0x1572,0},
+{0x1573,0x1573,0},
+{0x1574,0x1574,0},
+{0x1575,0x1575,0},
+{0x1576,0x1576,0},
+{0x1577,0x1577,0},
+{0x1578,0x1578,0},
+{0x1579,0x1579,0},
+{0x157A,0x157A,0},
+{0x157B,0x157B,0},
+{0x157C,0x157C,0},
+{0x157D,0x157D,0},
+{0x157E,0x157E,0},
+{0x157F,0x157F,0},
+{0x1580,0x1580,0},
+{0x1581,0x1581,0},
+{0x1582,0x1582,0},
+{0x1583,0x1583,0},
+{0x1584,0x1584,0},
+{0x1585,0x1585,0},
+{0x1586,0x1586,0},
+{0x1587,0x1587,0},
+{0x1588,0x1588,0},
+{0x1589,0x1589,0},
+{0x158A,0x158A,0},
+{0x158B,0x158B,0},
+{0x158C,0x158C,0},
+{0x158D,0x158D,0},
+{0x158E,0x158E,0},
+{0x158F,0x158F,0},
+{0x1590,0x1590,0},
+{0x1591,0x1591,0},
+{0x1592,0x1592,0},
+{0x1593,0x1593,0},
+{0x1594,0x1594,0},
+{0x1595,0x1595,0},
+{0x1596,0x1596,0},
+{0x1597,0x1597,0},
+{0x1598,0x1598,0},
+{0x1599,0x1599,0},
+{0x159A,0x159A,0},
+{0x159B,0x159B,0},
+{0x159C,0x159C,0},
+{0x159D,0x159D,0},
+{0x159E,0x159E,0},
+{0x159F,0x159F,0},
+{0x15A0,0x15A0,0},
+{0x15A1,0x15A1,0},
+{0x15A2,0x15A2,0},
+{0x15A3,0x15A3,0},
+{0x15A4,0x15A4,0},
+{0x15A5,0x15A5,0},
+{0x15A6,0x15A6,0},
+{0x15A7,0x15A7,0},
+{0x15A8,0x15A8,0},
+{0x15A9,0x15A9,0},
+{0x15AA,0x15AA,0},
+{0x15AB,0x15AB,0},
+{0x15AC,0x15AC,0},
+{0x15AD,0x15AD,0},
+{0x15AE,0x15AE,0},
+{0x15AF,0x15AF,0},
+{0x15B0,0x15B0,0},
+{0x15B1,0x15B1,0},
+{0x15B2,0x15B2,0},
+{0x15B3,0x15B3,0},
+{0x15B4,0x15B4,0},
+{0x15B5,0x15B5,0},
+{0x15B6,0x15B6,0},
+{0x15B7,0x15B7,0},
+{0x15B8,0x15B8,0},
+{0x15B9,0x15B9,0},
+{0x15BA,0x15BA,0},
+{0x15BB,0x15BB,0},
+{0x15BC,0x15BC,0},
+{0x15BD,0x15BD,0},
+{0x15BE,0x15BE,0},
+{0x15BF,0x15BF,0},
+{0x15C0,0x15C0,0},
+{0x15C1,0x15C1,0},
+{0x15C2,0x15C2,0},
+{0x15C3,0x15C3,0},
+{0x15C4,0x15C4,0},
+{0x15C5,0x15C5,0},
+{0x15C6,0x15C6,0},
+{0x15C7,0x15C7,0},
+{0x15C8,0x15C8,0},
+{0x15C9,0x15C9,0},
+{0x15CA,0x15CA,0},
+{0x15CB,0x15CB,0},
+{0x15CC,0x15CC,0},
+{0x15CD,0x15CD,0},
+{0x15CE,0x15CE,0},
+{0x15CF,0x15CF,0},
+{0x15D0,0x15D0,0},
+{0x15D1,0x15D1,0},
+{0x15D2,0x15D2,0},
+{0x15D3,0x15D3,0},
+{0x15D4,0x15D4,0},
+{0x15D5,0x15D5,0},
+{0x15D6,0x15D6,0},
+{0x15D7,0x15D7,0},
+{0x15D8,0x15D8,0},
+{0x15D9,0x15D9,0},
+{0x15DA,0x15DA,0},
+{0x15DB,0x15DB,0},
+{0x15DC,0x15DC,0},
+{0x15DD,0x15DD,0},
+{0x15DE,0x15DE,0},
+{0x15DF,0x15DF,0},
+{0x15E0,0x15E0,0},
+{0x15E1,0x15E1,0},
+{0x15E2,0x15E2,0},
+{0x15E3,0x15E3,0},
+{0x15E4,0x15E4,0},
+{0x15E5,0x15E5,0},
+{0x15E6,0x15E6,0},
+{0x15E7,0x15E7,0},
+{0x15E8,0x15E8,0},
+{0x15E9,0x15E9,0},
+{0x15EA,0x15EA,0},
+{0x15EB,0x15EB,0},
+{0x15EC,0x15EC,0},
+{0x15ED,0x15ED,0},
+{0x15EE,0x15EE,0},
+{0x15EF,0x15EF,0},
+{0x15F0,0x15F0,0},
+{0x15F1,0x15F1,0},
+{0x15F2,0x15F2,0},
+{0x15F3,0x15F3,0},
+{0x15F4,0x15F4,0},
+{0x15F5,0x15F5,0},
+{0x15F6,0x15F6,0},
+{0x15F7,0x15F7,0},
+{0x15F8,0x15F8,0},
+{0x15F9,0x15F9,0},
+{0x15FA,0x15FA,0},
+{0x15FB,0x15FB,0},
+{0x15FC,0x15FC,0},
+{0x15FD,0x15FD,0},
+{0x15FE,0x15FE,0},
+{0x15FF,0x15FF,0},
+{0x1600,0x1600,0},
+{0x1601,0x1601,0},
+{0x1602,0x1602,0},
+{0x1603,0x1603,0},
+{0x1604,0x1604,0},
+{0x1605,0x1605,0},
+{0x1606,0x1606,0},
+{0x1607,0x1607,0},
+{0x1608,0x1608,0},
+{0x1609,0x1609,0},
+{0x160A,0x160A,0},
+{0x160B,0x160B,0},
+{0x160C,0x160C,0},
+{0x160D,0x160D,0},
+{0x160E,0x160E,0},
+{0x160F,0x160F,0},
+{0x1610,0x1610,0},
+{0x1611,0x1611,0},
+{0x1612,0x1612,0},
+{0x1613,0x1613,0},
+{0x1614,0x1614,0},
+{0x1615,0x1615,0},
+{0x1616,0x1616,0},
+{0x1617,0x1617,0},
+{0x1618,0x1618,0},
+{0x1619,0x1619,0},
+{0x161A,0x161A,0},
+{0x161B,0x161B,0},
+{0x161C,0x161C,0},
+{0x161D,0x161D,0},
+{0x161E,0x161E,0},
+{0x161F,0x161F,0},
+{0x1620,0x1620,0},
+{0x1621,0x1621,0},
+{0x1622,0x1622,0},
+{0x1623,0x1623,0},
+{0x1624,0x1624,0},
+{0x1625,0x1625,0},
+{0x1626,0x1626,0},
+{0x1627,0x1627,0},
+{0x1628,0x1628,0},
+{0x1629,0x1629,0},
+{0x162A,0x162A,0},
+{0x162B,0x162B,0},
+{0x162C,0x162C,0},
+{0x162D,0x162D,0},
+{0x162E,0x162E,0},
+{0x162F,0x162F,0},
+{0x1630,0x1630,0},
+{0x1631,0x1631,0},
+{0x1632,0x1632,0},
+{0x1633,0x1633,0},
+{0x1634,0x1634,0},
+{0x1635,0x1635,0},
+{0x1636,0x1636,0},
+{0x1637,0x1637,0},
+{0x1638,0x1638,0},
+{0x1639,0x1639,0},
+{0x163A,0x163A,0},
+{0x163B,0x163B,0},
+{0x163C,0x163C,0},
+{0x163D,0x163D,0},
+{0x163E,0x163E,0},
+{0x163F,0x163F,0},
+{0x1640,0x1640,0},
+{0x1641,0x1641,0},
+{0x1642,0x1642,0},
+{0x1643,0x1643,0},
+{0x1644,0x1644,0},
+{0x1645,0x1645,0},
+{0x1646,0x1646,0},
+{0x1647,0x1647,0},
+{0x1648,0x1648,0},
+{0x1649,0x1649,0},
+{0x164A,0x164A,0},
+{0x164B,0x164B,0},
+{0x164C,0x164C,0},
+{0x164D,0x164D,0},
+{0x164E,0x164E,0},
+{0x164F,0x164F,0},
+{0x1650,0x1650,0},
+{0x1651,0x1651,0},
+{0x1652,0x1652,0},
+{0x1653,0x1653,0},
+{0x1654,0x1654,0},
+{0x1655,0x1655,0},
+{0x1656,0x1656,0},
+{0x1657,0x1657,0},
+{0x1658,0x1658,0},
+{0x1659,0x1659,0},
+{0x165A,0x165A,0},
+{0x165B,0x165B,0},
+{0x165C,0x165C,0},
+{0x165D,0x165D,0},
+{0x165E,0x165E,0},
+{0x165F,0x165F,0},
+{0x1660,0x1660,0},
+{0x1661,0x1661,0},
+{0x1662,0x1662,0},
+{0x1663,0x1663,0},
+{0x1664,0x1664,0},
+{0x1665,0x1665,0},
+{0x1666,0x1666,0},
+{0x1667,0x1667,0},
+{0x1668,0x1668,0},
+{0x1669,0x1669,0},
+{0x166A,0x166A,0},
+{0x166B,0x166B,0},
+{0x166C,0x166C,0},
+{0x166D,0x166D,0},
+{0x166E,0x166E,0},
+{0x166F,0x166F,0},
+{0x1670,0x1670,0},
+{0x1671,0x1671,0},
+{0x1672,0x1672,0},
+{0x1673,0x1673,0},
+{0x1674,0x1674,0},
+{0x1675,0x1675,0},
+{0x1676,0x1676,0},
+{0x1677,0x1677,0},
+{0x1678,0x1678,0},
+{0x1679,0x1679,0},
+{0x167A,0x167A,0},
+{0x167B,0x167B,0},
+{0x167C,0x167C,0},
+{0x167D,0x167D,0},
+{0x167E,0x167E,0},
+{0x167F,0x167F,0},
+{0x1680,0x1680,0},
+{0x1681,0x1681,0},
+{0x1682,0x1682,0},
+{0x1683,0x1683,0},
+{0x1684,0x1684,0},
+{0x1685,0x1685,0},
+{0x1686,0x1686,0},
+{0x1687,0x1687,0},
+{0x1688,0x1688,0},
+{0x1689,0x1689,0},
+{0x168A,0x168A,0},
+{0x168B,0x168B,0},
+{0x168C,0x168C,0},
+{0x168D,0x168D,0},
+{0x168E,0x168E,0},
+{0x168F,0x168F,0},
+{0x1690,0x1690,0},
+{0x1691,0x1691,0},
+{0x1692,0x1692,0},
+{0x1693,0x1693,0},
+{0x1694,0x1694,0},
+{0x1695,0x1695,0},
+{0x1696,0x1696,0},
+{0x1697,0x1697,0},
+{0x1698,0x1698,0},
+{0x1699,0x1699,0},
+{0x169A,0x169A,0},
+{0x169B,0x169B,0},
+{0x169C,0x169C,0},
+{0x169D,0x169D,0},
+{0x169E,0x169E,0},
+{0x169F,0x169F,0},
+{0x16A0,0x16A0,0},
+{0x16A1,0x16A1,0},
+{0x16A2,0x16A2,0},
+{0x16A3,0x16A3,0},
+{0x16A4,0x16A4,0},
+{0x16A5,0x16A5,0},
+{0x16A6,0x16A6,0},
+{0x16A7,0x16A7,0},
+{0x16A8,0x16A8,0},
+{0x16A9,0x16A9,0},
+{0x16AA,0x16AA,0},
+{0x16AB,0x16AB,0},
+{0x16AC,0x16AC,0},
+{0x16AD,0x16AD,0},
+{0x16AE,0x16AE,0},
+{0x16AF,0x16AF,0},
+{0x16B0,0x16B0,0},
+{0x16B1,0x16B1,0},
+{0x16B2,0x16B2,0},
+{0x16B3,0x16B3,0},
+{0x16B4,0x16B4,0},
+{0x16B5,0x16B5,0},
+{0x16B6,0x16B6,0},
+{0x16B7,0x16B7,0},
+{0x16B8,0x16B8,0},
+{0x16B9,0x16B9,0},
+{0x16BA,0x16BA,0},
+{0x16BB,0x16BB,0},
+{0x16BC,0x16BC,0},
+{0x16BD,0x16BD,0},
+{0x16BE,0x16BE,0},
+{0x16BF,0x16BF,0},
+{0x16C0,0x16C0,0},
+{0x16C1,0x16C1,0},
+{0x16C2,0x16C2,0},
+{0x16C3,0x16C3,0},
+{0x16C4,0x16C4,0},
+{0x16C5,0x16C5,0},
+{0x16C6,0x16C6,0},
+{0x16C7,0x16C7,0},
+{0x16C8,0x16C8,0},
+{0x16C9,0x16C9,0},
+{0x16CA,0x16CA,0},
+{0x16CB,0x16CB,0},
+{0x16CC,0x16CC,0},
+{0x16CD,0x16CD,0},
+{0x16CE,0x16CE,0},
+{0x16CF,0x16CF,0},
+{0x16D0,0x16D0,0},
+{0x16D1,0x16D1,0},
+{0x16D2,0x16D2,0},
+{0x16D3,0x16D3,0},
+{0x16D4,0x16D4,0},
+{0x16D5,0x16D5,0},
+{0x16D6,0x16D6,0},
+{0x16D7,0x16D7,0},
+{0x16D8,0x16D8,0},
+{0x16D9,0x16D9,0},
+{0x16DA,0x16DA,0},
+{0x16DB,0x16DB,0},
+{0x16DC,0x16DC,0},
+{0x16DD,0x16DD,0},
+{0x16DE,0x16DE,0},
+{0x16DF,0x16DF,0},
+{0x16E0,0x16E0,0},
+{0x16E1,0x16E1,0},
+{0x16E2,0x16E2,0},
+{0x16E3,0x16E3,0},
+{0x16E4,0x16E4,0},
+{0x16E5,0x16E5,0},
+{0x16E6,0x16E6,0},
+{0x16E7,0x16E7,0},
+{0x16E8,0x16E8,0},
+{0x16E9,0x16E9,0},
+{0x16EA,0x16EA,0},
+{0x16EB,0x16EB,0},
+{0x16EC,0x16EC,0},
+{0x16ED,0x16ED,0},
+{0x16EE,0x16EE,0},
+{0x16EF,0x16EF,0},
+{0x16F0,0x16F0,0},
+{0x16F1,0x16F1,0},
+{0x16F2,0x16F2,0},
+{0x16F3,0x16F3,0},
+{0x16F4,0x16F4,0},
+{0x16F5,0x16F5,0},
+{0x16F6,0x16F6,0},
+{0x16F7,0x16F7,0},
+{0x16F8,0x16F8,0},
+{0x16F9,0x16F9,0},
+{0x16FA,0x16FA,0},
+{0x16FB,0x16FB,0},
+{0x16FC,0x16FC,0},
+{0x16FD,0x16FD,0},
+{0x16FE,0x16FE,0},
+{0x16FF,0x16FF,0},
+{0x1700,0x1700,0},
+{0x1701,0x1701,0},
+{0x1702,0x1702,0},
+{0x1703,0x1703,0},
+{0x1704,0x1704,0},
+{0x1705,0x1705,0},
+{0x1706,0x1706,0},
+{0x1707,0x1707,0},
+{0x1708,0x1708,0},
+{0x1709,0x1709,0},
+{0x170A,0x170A,0},
+{0x170B,0x170B,0},
+{0x170C,0x170C,0},
+{0x170D,0x170D,0},
+{0x170E,0x170E,0},
+{0x170F,0x170F,0},
+{0x1710,0x1710,0},
+{0x1711,0x1711,0},
+{0x1712,0x1712,0},
+{0x1713,0x1713,0},
+{0x1714,0x1714,0},
+{0x1715,0x1715,0},
+{0x1716,0x1716,0},
+{0x1717,0x1717,0},
+{0x1718,0x1718,0},
+{0x1719,0x1719,0},
+{0x171A,0x171A,0},
+{0x171B,0x171B,0},
+{0x171C,0x171C,0},
+{0x171D,0x171D,0},
+{0x171E,0x171E,0},
+{0x171F,0x171F,0},
+{0x1720,0x1720,0},
+{0x1721,0x1721,0},
+{0x1722,0x1722,0},
+{0x1723,0x1723,0},
+{0x1724,0x1724,0},
+{0x1725,0x1725,0},
+{0x1726,0x1726,0},
+{0x1727,0x1727,0},
+{0x1728,0x1728,0},
+{0x1729,0x1729,0},
+{0x172A,0x172A,0},
+{0x172B,0x172B,0},
+{0x172C,0x172C,0},
+{0x172D,0x172D,0},
+{0x172E,0x172E,0},
+{0x172F,0x172F,0},
+{0x1730,0x1730,0},
+{0x1731,0x1731,0},
+{0x1732,0x1732,0},
+{0x1733,0x1733,0},
+{0x1734,0x1734,0},
+{0x1735,0x1735,0},
+{0x1736,0x1736,0},
+{0x1737,0x1737,0},
+{0x1738,0x1738,0},
+{0x1739,0x1739,0},
+{0x173A,0x173A,0},
+{0x173B,0x173B,0},
+{0x173C,0x173C,0},
+{0x173D,0x173D,0},
+{0x173E,0x173E,0},
+{0x173F,0x173F,0},
+{0x1740,0x1740,0},
+{0x1741,0x1741,0},
+{0x1742,0x1742,0},
+{0x1743,0x1743,0},
+{0x1744,0x1744,0},
+{0x1745,0x1745,0},
+{0x1746,0x1746,0},
+{0x1747,0x1747,0},
+{0x1748,0x1748,0},
+{0x1749,0x1749,0},
+{0x174A,0x174A,0},
+{0x174B,0x174B,0},
+{0x174C,0x174C,0},
+{0x174D,0x174D,0},
+{0x174E,0x174E,0},
+{0x174F,0x174F,0},
+{0x1750,0x1750,0},
+{0x1751,0x1751,0},
+{0x1752,0x1752,0},
+{0x1753,0x1753,0},
+{0x1754,0x1754,0},
+{0x1755,0x1755,0},
+{0x1756,0x1756,0},
+{0x1757,0x1757,0},
+{0x1758,0x1758,0},
+{0x1759,0x1759,0},
+{0x175A,0x175A,0},
+{0x175B,0x175B,0},
+{0x175C,0x175C,0},
+{0x175D,0x175D,0},
+{0x175E,0x175E,0},
+{0x175F,0x175F,0},
+{0x1760,0x1760,0},
+{0x1761,0x1761,0},
+{0x1762,0x1762,0},
+{0x1763,0x1763,0},
+{0x1764,0x1764,0},
+{0x1765,0x1765,0},
+{0x1766,0x1766,0},
+{0x1767,0x1767,0},
+{0x1768,0x1768,0},
+{0x1769,0x1769,0},
+{0x176A,0x176A,0},
+{0x176B,0x176B,0},
+{0x176C,0x176C,0},
+{0x176D,0x176D,0},
+{0x176E,0x176E,0},
+{0x176F,0x176F,0},
+{0x1770,0x1770,0},
+{0x1771,0x1771,0},
+{0x1772,0x1772,0},
+{0x1773,0x1773,0},
+{0x1774,0x1774,0},
+{0x1775,0x1775,0},
+{0x1776,0x1776,0},
+{0x1777,0x1777,0},
+{0x1778,0x1778,0},
+{0x1779,0x1779,0},
+{0x177A,0x177A,0},
+{0x177B,0x177B,0},
+{0x177C,0x177C,0},
+{0x177D,0x177D,0},
+{0x177E,0x177E,0},
+{0x177F,0x177F,0},
+{0x1780,0x1780,0},
+{0x1781,0x1781,0},
+{0x1782,0x1782,0},
+{0x1783,0x1783,0},
+{0x1784,0x1784,0},
+{0x1785,0x1785,0},
+{0x1786,0x1786,0},
+{0x1787,0x1787,0},
+{0x1788,0x1788,0},
+{0x1789,0x1789,0},
+{0x178A,0x178A,0},
+{0x178B,0x178B,0},
+{0x178C,0x178C,0},
+{0x178D,0x178D,0},
+{0x178E,0x178E,0},
+{0x178F,0x178F,0},
+{0x1790,0x1790,0},
+{0x1791,0x1791,0},
+{0x1792,0x1792,0},
+{0x1793,0x1793,0},
+{0x1794,0x1794,0},
+{0x1795,0x1795,0},
+{0x1796,0x1796,0},
+{0x1797,0x1797,0},
+{0x1798,0x1798,0},
+{0x1799,0x1799,0},
+{0x179A,0x179A,0},
+{0x179B,0x179B,0},
+{0x179C,0x179C,0},
+{0x179D,0x179D,0},
+{0x179E,0x179E,0},
+{0x179F,0x179F,0},
+{0x17A0,0x17A0,0},
+{0x17A1,0x17A1,0},
+{0x17A2,0x17A2,0},
+{0x17A3,0x17A3,0},
+{0x17A4,0x17A4,0},
+{0x17A5,0x17A5,0},
+{0x17A6,0x17A6,0},
+{0x17A7,0x17A7,0},
+{0x17A8,0x17A8,0},
+{0x17A9,0x17A9,0},
+{0x17AA,0x17AA,0},
+{0x17AB,0x17AB,0},
+{0x17AC,0x17AC,0},
+{0x17AD,0x17AD,0},
+{0x17AE,0x17AE,0},
+{0x17AF,0x17AF,0},
+{0x17B0,0x17B0,0},
+{0x17B1,0x17B1,0},
+{0x17B2,0x17B2,0},
+{0x17B3,0x17B3,0},
+{0x17B4,0x17B4,0},
+{0x17B5,0x17B5,0},
+{0x17B6,0x17B6,0},
+{0x17B7,0x17B7,0},
+{0x17B8,0x17B8,0},
+{0x17B9,0x17B9,0},
+{0x17BA,0x17BA,0},
+{0x17BB,0x17BB,0},
+{0x17BC,0x17BC,0},
+{0x17BD,0x17BD,0},
+{0x17BE,0x17BE,0},
+{0x17BF,0x17BF,0},
+{0x17C0,0x17C0,0},
+{0x17C1,0x17C1,0},
+{0x17C2,0x17C2,0},
+{0x17C3,0x17C3,0},
+{0x17C4,0x17C4,0},
+{0x17C5,0x17C5,0},
+{0x17C6,0x17C6,0},
+{0x17C7,0x17C7,0},
+{0x17C8,0x17C8,0},
+{0x17C9,0x17C9,0},
+{0x17CA,0x17CA,0},
+{0x17CB,0x17CB,0},
+{0x17CC,0x17CC,0},
+{0x17CD,0x17CD,0},
+{0x17CE,0x17CE,0},
+{0x17CF,0x17CF,0},
+{0x17D0,0x17D0,0},
+{0x17D1,0x17D1,0},
+{0x17D2,0x17D2,0},
+{0x17D3,0x17D3,0},
+{0x17D4,0x17D4,0},
+{0x17D5,0x17D5,0},
+{0x17D6,0x17D6,0},
+{0x17D7,0x17D7,0},
+{0x17D8,0x17D8,0},
+{0x17D9,0x17D9,0},
+{0x17DA,0x17DA,0},
+{0x17DB,0x17DB,0},
+{0x17DC,0x17DC,0},
+{0x17DD,0x17DD,0},
+{0x17DE,0x17DE,0},
+{0x17DF,0x17DF,0},
+{0x17E0,0x17E0,0},
+{0x17E1,0x17E1,0},
+{0x17E2,0x17E2,0},
+{0x17E3,0x17E3,0},
+{0x17E4,0x17E4,0},
+{0x17E5,0x17E5,0},
+{0x17E6,0x17E6,0},
+{0x17E7,0x17E7,0},
+{0x17E8,0x17E8,0},
+{0x17E9,0x17E9,0},
+{0x17EA,0x17EA,0},
+{0x17EB,0x17EB,0},
+{0x17EC,0x17EC,0},
+{0x17ED,0x17ED,0},
+{0x17EE,0x17EE,0},
+{0x17EF,0x17EF,0},
+{0x17F0,0x17F0,0},
+{0x17F1,0x17F1,0},
+{0x17F2,0x17F2,0},
+{0x17F3,0x17F3,0},
+{0x17F4,0x17F4,0},
+{0x17F5,0x17F5,0},
+{0x17F6,0x17F6,0},
+{0x17F7,0x17F7,0},
+{0x17F8,0x17F8,0},
+{0x17F9,0x17F9,0},
+{0x17FA,0x17FA,0},
+{0x17FB,0x17FB,0},
+{0x17FC,0x17FC,0},
+{0x17FD,0x17FD,0},
+{0x17FE,0x17FE,0},
+{0x17FF,0x17FF,0},
+{0x1800,0x1800,0},
+{0x1801,0x1801,0},
+{0x1802,0x1802,0},
+{0x1803,0x1803,0},
+{0x1804,0x1804,0},
+{0x1805,0x1805,0},
+{0x1806,0x1806,0},
+{0x1807,0x1807,0},
+{0x1808,0x1808,0},
+{0x1809,0x1809,0},
+{0x180A,0x180A,0},
+{0x180B,0x180B,0},
+{0x180C,0x180C,0},
+{0x180D,0x180D,0},
+{0x180E,0x180E,0},
+{0x180F,0x180F,0},
+{0x1810,0x1810,0},
+{0x1811,0x1811,0},
+{0x1812,0x1812,0},
+{0x1813,0x1813,0},
+{0x1814,0x1814,0},
+{0x1815,0x1815,0},
+{0x1816,0x1816,0},
+{0x1817,0x1817,0},
+{0x1818,0x1818,0},
+{0x1819,0x1819,0},
+{0x181A,0x181A,0},
+{0x181B,0x181B,0},
+{0x181C,0x181C,0},
+{0x181D,0x181D,0},
+{0x181E,0x181E,0},
+{0x181F,0x181F,0},
+{0x1820,0x1820,0},
+{0x1821,0x1821,0},
+{0x1822,0x1822,0},
+{0x1823,0x1823,0},
+{0x1824,0x1824,0},
+{0x1825,0x1825,0},
+{0x1826,0x1826,0},
+{0x1827,0x1827,0},
+{0x1828,0x1828,0},
+{0x1829,0x1829,0},
+{0x182A,0x182A,0},
+{0x182B,0x182B,0},
+{0x182C,0x182C,0},
+{0x182D,0x182D,0},
+{0x182E,0x182E,0},
+{0x182F,0x182F,0},
+{0x1830,0x1830,0},
+{0x1831,0x1831,0},
+{0x1832,0x1832,0},
+{0x1833,0x1833,0},
+{0x1834,0x1834,0},
+{0x1835,0x1835,0},
+{0x1836,0x1836,0},
+{0x1837,0x1837,0},
+{0x1838,0x1838,0},
+{0x1839,0x1839,0},
+{0x183A,0x183A,0},
+{0x183B,0x183B,0},
+{0x183C,0x183C,0},
+{0x183D,0x183D,0},
+{0x183E,0x183E,0},
+{0x183F,0x183F,0},
+{0x1840,0x1840,0},
+{0x1841,0x1841,0},
+{0x1842,0x1842,0},
+{0x1843,0x1843,0},
+{0x1844,0x1844,0},
+{0x1845,0x1845,0},
+{0x1846,0x1846,0},
+{0x1847,0x1847,0},
+{0x1848,0x1848,0},
+{0x1849,0x1849,0},
+{0x184A,0x184A,0},
+{0x184B,0x184B,0},
+{0x184C,0x184C,0},
+{0x184D,0x184D,0},
+{0x184E,0x184E,0},
+{0x184F,0x184F,0},
+{0x1850,0x1850,0},
+{0x1851,0x1851,0},
+{0x1852,0x1852,0},
+{0x1853,0x1853,0},
+{0x1854,0x1854,0},
+{0x1855,0x1855,0},
+{0x1856,0x1856,0},
+{0x1857,0x1857,0},
+{0x1858,0x1858,0},
+{0x1859,0x1859,0},
+{0x185A,0x185A,0},
+{0x185B,0x185B,0},
+{0x185C,0x185C,0},
+{0x185D,0x185D,0},
+{0x185E,0x185E,0},
+{0x185F,0x185F,0},
+{0x1860,0x1860,0},
+{0x1861,0x1861,0},
+{0x1862,0x1862,0},
+{0x1863,0x1863,0},
+{0x1864,0x1864,0},
+{0x1865,0x1865,0},
+{0x1866,0x1866,0},
+{0x1867,0x1867,0},
+{0x1868,0x1868,0},
+{0x1869,0x1869,0},
+{0x186A,0x186A,0},
+{0x186B,0x186B,0},
+{0x186C,0x186C,0},
+{0x186D,0x186D,0},
+{0x186E,0x186E,0},
+{0x186F,0x186F,0},
+{0x1870,0x1870,0},
+{0x1871,0x1871,0},
+{0x1872,0x1872,0},
+{0x1873,0x1873,0},
+{0x1874,0x1874,0},
+{0x1875,0x1875,0},
+{0x1876,0x1876,0},
+{0x1877,0x1877,0},
+{0x1878,0x1878,0},
+{0x1879,0x1879,0},
+{0x187A,0x187A,0},
+{0x187B,0x187B,0},
+{0x187C,0x187C,0},
+{0x187D,0x187D,0},
+{0x187E,0x187E,0},
+{0x187F,0x187F,0},
+{0x1880,0x1880,0},
+{0x1881,0x1881,0},
+{0x1882,0x1882,0},
+{0x1883,0x1883,0},
+{0x1884,0x1884,0},
+{0x1885,0x1885,0},
+{0x1886,0x1886,0},
+{0x1887,0x1887,0},
+{0x1888,0x1888,0},
+{0x1889,0x1889,0},
+{0x188A,0x188A,0},
+{0x188B,0x188B,0},
+{0x188C,0x188C,0},
+{0x188D,0x188D,0},
+{0x188E,0x188E,0},
+{0x188F,0x188F,0},
+{0x1890,0x1890,0},
+{0x1891,0x1891,0},
+{0x1892,0x1892,0},
+{0x1893,0x1893,0},
+{0x1894,0x1894,0},
+{0x1895,0x1895,0},
+{0x1896,0x1896,0},
+{0x1897,0x1897,0},
+{0x1898,0x1898,0},
+{0x1899,0x1899,0},
+{0x189A,0x189A,0},
+{0x189B,0x189B,0},
+{0x189C,0x189C,0},
+{0x189D,0x189D,0},
+{0x189E,0x189E,0},
+{0x189F,0x189F,0},
+{0x18A0,0x18A0,0},
+{0x18A1,0x18A1,0},
+{0x18A2,0x18A2,0},
+{0x18A3,0x18A3,0},
+{0x18A4,0x18A4,0},
+{0x18A5,0x18A5,0},
+{0x18A6,0x18A6,0},
+{0x18A7,0x18A7,0},
+{0x18A8,0x18A8,0},
+{0x18A9,0x18A9,0},
+{0x18AA,0x18AA,0},
+{0x18AB,0x18AB,0},
+{0x18AC,0x18AC,0},
+{0x18AD,0x18AD,0},
+{0x18AE,0x18AE,0},
+{0x18AF,0x18AF,0},
+{0x18B0,0x18B0,0},
+{0x18B1,0x18B1,0},
+{0x18B2,0x18B2,0},
+{0x18B3,0x18B3,0},
+{0x18B4,0x18B4,0},
+{0x18B5,0x18B5,0},
+{0x18B6,0x18B6,0},
+{0x18B7,0x18B7,0},
+{0x18B8,0x18B8,0},
+{0x18B9,0x18B9,0},
+{0x18BA,0x18BA,0},
+{0x18BB,0x18BB,0},
+{0x18BC,0x18BC,0},
+{0x18BD,0x18BD,0},
+{0x18BE,0x18BE,0},
+{0x18BF,0x18BF,0},
+{0x18C0,0x18C0,0},
+{0x18C1,0x18C1,0},
+{0x18C2,0x18C2,0},
+{0x18C3,0x18C3,0},
+{0x18C4,0x18C4,0},
+{0x18C5,0x18C5,0},
+{0x18C6,0x18C6,0},
+{0x18C7,0x18C7,0},
+{0x18C8,0x18C8,0},
+{0x18C9,0x18C9,0},
+{0x18CA,0x18CA,0},
+{0x18CB,0x18CB,0},
+{0x18CC,0x18CC,0},
+{0x18CD,0x18CD,0},
+{0x18CE,0x18CE,0},
+{0x18CF,0x18CF,0},
+{0x18D0,0x18D0,0},
+{0x18D1,0x18D1,0},
+{0x18D2,0x18D2,0},
+{0x18D3,0x18D3,0},
+{0x18D4,0x18D4,0},
+{0x18D5,0x18D5,0},
+{0x18D6,0x18D6,0},
+{0x18D7,0x18D7,0},
+{0x18D8,0x18D8,0},
+{0x18D9,0x18D9,0},
+{0x18DA,0x18DA,0},
+{0x18DB,0x18DB,0},
+{0x18DC,0x18DC,0},
+{0x18DD,0x18DD,0},
+{0x18DE,0x18DE,0},
+{0x18DF,0x18DF,0},
+{0x18E0,0x18E0,0},
+{0x18E1,0x18E1,0},
+{0x18E2,0x18E2,0},
+{0x18E3,0x18E3,0},
+{0x18E4,0x18E4,0},
+{0x18E5,0x18E5,0},
+{0x18E6,0x18E6,0},
+{0x18E7,0x18E7,0},
+{0x18E8,0x18E8,0},
+{0x18E9,0x18E9,0},
+{0x18EA,0x18EA,0},
+{0x18EB,0x18EB,0},
+{0x18EC,0x18EC,0},
+{0x18ED,0x18ED,0},
+{0x18EE,0x18EE,0},
+{0x18EF,0x18EF,0},
+{0x18F0,0x18F0,0},
+{0x18F1,0x18F1,0},
+{0x18F2,0x18F2,0},
+{0x18F3,0x18F3,0},
+{0x18F4,0x18F4,0},
+{0x18F5,0x18F5,0},
+{0x18F6,0x18F6,0},
+{0x18F7,0x18F7,0},
+{0x18F8,0x18F8,0},
+{0x18F9,0x18F9,0},
+{0x18FA,0x18FA,0},
+{0x18FB,0x18FB,0},
+{0x18FC,0x18FC,0},
+{0x18FD,0x18FD,0},
+{0x18FE,0x18FE,0},
+{0x18FF,0x18FF,0},
+{0x1900,0x1900,0},
+{0x1901,0x1901,0},
+{0x1902,0x1902,0},
+{0x1903,0x1903,0},
+{0x1904,0x1904,0},
+{0x1905,0x1905,0},
+{0x1906,0x1906,0},
+{0x1907,0x1907,0},
+{0x1908,0x1908,0},
+{0x1909,0x1909,0},
+{0x190A,0x190A,0},
+{0x190B,0x190B,0},
+{0x190C,0x190C,0},
+{0x190D,0x190D,0},
+{0x190E,0x190E,0},
+{0x190F,0x190F,0},
+{0x1910,0x1910,0},
+{0x1911,0x1911,0},
+{0x1912,0x1912,0},
+{0x1913,0x1913,0},
+{0x1914,0x1914,0},
+{0x1915,0x1915,0},
+{0x1916,0x1916,0},
+{0x1917,0x1917,0},
+{0x1918,0x1918,0},
+{0x1919,0x1919,0},
+{0x191A,0x191A,0},
+{0x191B,0x191B,0},
+{0x191C,0x191C,0},
+{0x191D,0x191D,0},
+{0x191E,0x191E,0},
+{0x191F,0x191F,0},
+{0x1920,0x1920,0},
+{0x1921,0x1921,0},
+{0x1922,0x1922,0},
+{0x1923,0x1923,0},
+{0x1924,0x1924,0},
+{0x1925,0x1925,0},
+{0x1926,0x1926,0},
+{0x1927,0x1927,0},
+{0x1928,0x1928,0},
+{0x1929,0x1929,0},
+{0x192A,0x192A,0},
+{0x192B,0x192B,0},
+{0x192C,0x192C,0},
+{0x192D,0x192D,0},
+{0x192E,0x192E,0},
+{0x192F,0x192F,0},
+{0x1930,0x1930,0},
+{0x1931,0x1931,0},
+{0x1932,0x1932,0},
+{0x1933,0x1933,0},
+{0x1934,0x1934,0},
+{0x1935,0x1935,0},
+{0x1936,0x1936,0},
+{0x1937,0x1937,0},
+{0x1938,0x1938,0},
+{0x1939,0x1939,0},
+{0x193A,0x193A,0},
+{0x193B,0x193B,0},
+{0x193C,0x193C,0},
+{0x193D,0x193D,0},
+{0x193E,0x193E,0},
+{0x193F,0x193F,0},
+{0x1940,0x1940,0},
+{0x1941,0x1941,0},
+{0x1942,0x1942,0},
+{0x1943,0x1943,0},
+{0x1944,0x1944,0},
+{0x1945,0x1945,0},
+{0x1946,0x1946,0},
+{0x1947,0x1947,0},
+{0x1948,0x1948,0},
+{0x1949,0x1949,0},
+{0x194A,0x194A,0},
+{0x194B,0x194B,0},
+{0x194C,0x194C,0},
+{0x194D,0x194D,0},
+{0x194E,0x194E,0},
+{0x194F,0x194F,0},
+{0x1950,0x1950,0},
+{0x1951,0x1951,0},
+{0x1952,0x1952,0},
+{0x1953,0x1953,0},
+{0x1954,0x1954,0},
+{0x1955,0x1955,0},
+{0x1956,0x1956,0},
+{0x1957,0x1957,0},
+{0x1958,0x1958,0},
+{0x1959,0x1959,0},
+{0x195A,0x195A,0},
+{0x195B,0x195B,0},
+{0x195C,0x195C,0},
+{0x195D,0x195D,0},
+{0x195E,0x195E,0},
+{0x195F,0x195F,0},
+{0x1960,0x1960,0},
+{0x1961,0x1961,0},
+{0x1962,0x1962,0},
+{0x1963,0x1963,0},
+{0x1964,0x1964,0},
+{0x1965,0x1965,0},
+{0x1966,0x1966,0},
+{0x1967,0x1967,0},
+{0x1968,0x1968,0},
+{0x1969,0x1969,0},
+{0x196A,0x196A,0},
+{0x196B,0x196B,0},
+{0x196C,0x196C,0},
+{0x196D,0x196D,0},
+{0x196E,0x196E,0},
+{0x196F,0x196F,0},
+{0x1970,0x1970,0},
+{0x1971,0x1971,0},
+{0x1972,0x1972,0},
+{0x1973,0x1973,0},
+{0x1974,0x1974,0},
+{0x1975,0x1975,0},
+{0x1976,0x1976,0},
+{0x1977,0x1977,0},
+{0x1978,0x1978,0},
+{0x1979,0x1979,0},
+{0x197A,0x197A,0},
+{0x197B,0x197B,0},
+{0x197C,0x197C,0},
+{0x197D,0x197D,0},
+{0x197E,0x197E,0},
+{0x197F,0x197F,0},
+{0x1980,0x1980,0},
+{0x1981,0x1981,0},
+{0x1982,0x1982,0},
+{0x1983,0x1983,0},
+{0x1984,0x1984,0},
+{0x1985,0x1985,0},
+{0x1986,0x1986,0},
+{0x1987,0x1987,0},
+{0x1988,0x1988,0},
+{0x1989,0x1989,0},
+{0x198A,0x198A,0},
+{0x198B,0x198B,0},
+{0x198C,0x198C,0},
+{0x198D,0x198D,0},
+{0x198E,0x198E,0},
+{0x198F,0x198F,0},
+{0x1990,0x1990,0},
+{0x1991,0x1991,0},
+{0x1992,0x1992,0},
+{0x1993,0x1993,0},
+{0x1994,0x1994,0},
+{0x1995,0x1995,0},
+{0x1996,0x1996,0},
+{0x1997,0x1997,0},
+{0x1998,0x1998,0},
+{0x1999,0x1999,0},
+{0x199A,0x199A,0},
+{0x199B,0x199B,0},
+{0x199C,0x199C,0},
+{0x199D,0x199D,0},
+{0x199E,0x199E,0},
+{0x199F,0x199F,0},
+{0x19A0,0x19A0,0},
+{0x19A1,0x19A1,0},
+{0x19A2,0x19A2,0},
+{0x19A3,0x19A3,0},
+{0x19A4,0x19A4,0},
+{0x19A5,0x19A5,0},
+{0x19A6,0x19A6,0},
+{0x19A7,0x19A7,0},
+{0x19A8,0x19A8,0},
+{0x19A9,0x19A9,0},
+{0x19AA,0x19AA,0},
+{0x19AB,0x19AB,0},
+{0x19AC,0x19AC,0},
+{0x19AD,0x19AD,0},
+{0x19AE,0x19AE,0},
+{0x19AF,0x19AF,0},
+{0x19B0,0x19B0,0},
+{0x19B1,0x19B1,0},
+{0x19B2,0x19B2,0},
+{0x19B3,0x19B3,0},
+{0x19B4,0x19B4,0},
+{0x19B5,0x19B5,0},
+{0x19B6,0x19B6,0},
+{0x19B7,0x19B7,0},
+{0x19B8,0x19B8,0},
+{0x19B9,0x19B9,0},
+{0x19BA,0x19BA,0},
+{0x19BB,0x19BB,0},
+{0x19BC,0x19BC,0},
+{0x19BD,0x19BD,0},
+{0x19BE,0x19BE,0},
+{0x19BF,0x19BF,0},
+{0x19C0,0x19C0,0},
+{0x19C1,0x19C1,0},
+{0x19C2,0x19C2,0},
+{0x19C3,0x19C3,0},
+{0x19C4,0x19C4,0},
+{0x19C5,0x19C5,0},
+{0x19C6,0x19C6,0},
+{0x19C7,0x19C7,0},
+{0x19C8,0x19C8,0},
+{0x19C9,0x19C9,0},
+{0x19CA,0x19CA,0},
+{0x19CB,0x19CB,0},
+{0x19CC,0x19CC,0},
+{0x19CD,0x19CD,0},
+{0x19CE,0x19CE,0},
+{0x19CF,0x19CF,0},
+{0x19D0,0x19D0,0},
+{0x19D1,0x19D1,0},
+{0x19D2,0x19D2,0},
+{0x19D3,0x19D3,0},
+{0x19D4,0x19D4,0},
+{0x19D5,0x19D5,0},
+{0x19D6,0x19D6,0},
+{0x19D7,0x19D7,0},
+{0x19D8,0x19D8,0},
+{0x19D9,0x19D9,0},
+{0x19DA,0x19DA,0},
+{0x19DB,0x19DB,0},
+{0x19DC,0x19DC,0},
+{0x19DD,0x19DD,0},
+{0x19DE,0x19DE,0},
+{0x19DF,0x19DF,0},
+{0x19E0,0x19E0,0},
+{0x19E1,0x19E1,0},
+{0x19E2,0x19E2,0},
+{0x19E3,0x19E3,0},
+{0x19E4,0x19E4,0},
+{0x19E5,0x19E5,0},
+{0x19E6,0x19E6,0},
+{0x19E7,0x19E7,0},
+{0x19E8,0x19E8,0},
+{0x19E9,0x19E9,0},
+{0x19EA,0x19EA,0},
+{0x19EB,0x19EB,0},
+{0x19EC,0x19EC,0},
+{0x19ED,0x19ED,0},
+{0x19EE,0x19EE,0},
+{0x19EF,0x19EF,0},
+{0x19F0,0x19F0,0},
+{0x19F1,0x19F1,0},
+{0x19F2,0x19F2,0},
+{0x19F3,0x19F3,0},
+{0x19F4,0x19F4,0},
+{0x19F5,0x19F5,0},
+{0x19F6,0x19F6,0},
+{0x19F7,0x19F7,0},
+{0x19F8,0x19F8,0},
+{0x19F9,0x19F9,0},
+{0x19FA,0x19FA,0},
+{0x19FB,0x19FB,0},
+{0x19FC,0x19FC,0},
+{0x19FD,0x19FD,0},
+{0x19FE,0x19FE,0},
+{0x19FF,0x19FF,0},
+{0x1A00,0x1A00,0},
+{0x1A01,0x1A01,0},
+{0x1A02,0x1A02,0},
+{0x1A03,0x1A03,0},
+{0x1A04,0x1A04,0},
+{0x1A05,0x1A05,0},
+{0x1A06,0x1A06,0},
+{0x1A07,0x1A07,0},
+{0x1A08,0x1A08,0},
+{0x1A09,0x1A09,0},
+{0x1A0A,0x1A0A,0},
+{0x1A0B,0x1A0B,0},
+{0x1A0C,0x1A0C,0},
+{0x1A0D,0x1A0D,0},
+{0x1A0E,0x1A0E,0},
+{0x1A0F,0x1A0F,0},
+{0x1A10,0x1A10,0},
+{0x1A11,0x1A11,0},
+{0x1A12,0x1A12,0},
+{0x1A13,0x1A13,0},
+{0x1A14,0x1A14,0},
+{0x1A15,0x1A15,0},
+{0x1A16,0x1A16,0},
+{0x1A17,0x1A17,0},
+{0x1A18,0x1A18,0},
+{0x1A19,0x1A19,0},
+{0x1A1A,0x1A1A,0},
+{0x1A1B,0x1A1B,0},
+{0x1A1C,0x1A1C,0},
+{0x1A1D,0x1A1D,0},
+{0x1A1E,0x1A1E,0},
+{0x1A1F,0x1A1F,0},
+{0x1A20,0x1A20,0},
+{0x1A21,0x1A21,0},
+{0x1A22,0x1A22,0},
+{0x1A23,0x1A23,0},
+{0x1A24,0x1A24,0},
+{0x1A25,0x1A25,0},
+{0x1A26,0x1A26,0},
+{0x1A27,0x1A27,0},
+{0x1A28,0x1A28,0},
+{0x1A29,0x1A29,0},
+{0x1A2A,0x1A2A,0},
+{0x1A2B,0x1A2B,0},
+{0x1A2C,0x1A2C,0},
+{0x1A2D,0x1A2D,0},
+{0x1A2E,0x1A2E,0},
+{0x1A2F,0x1A2F,0},
+{0x1A30,0x1A30,0},
+{0x1A31,0x1A31,0},
+{0x1A32,0x1A32,0},
+{0x1A33,0x1A33,0},
+{0x1A34,0x1A34,0},
+{0x1A35,0x1A35,0},
+{0x1A36,0x1A36,0},
+{0x1A37,0x1A37,0},
+{0x1A38,0x1A38,0},
+{0x1A39,0x1A39,0},
+{0x1A3A,0x1A3A,0},
+{0x1A3B,0x1A3B,0},
+{0x1A3C,0x1A3C,0},
+{0x1A3D,0x1A3D,0},
+{0x1A3E,0x1A3E,0},
+{0x1A3F,0x1A3F,0},
+{0x1A40,0x1A40,0},
+{0x1A41,0x1A41,0},
+{0x1A42,0x1A42,0},
+{0x1A43,0x1A43,0},
+{0x1A44,0x1A44,0},
+{0x1A45,0x1A45,0},
+{0x1A46,0x1A46,0},
+{0x1A47,0x1A47,0},
+{0x1A48,0x1A48,0},
+{0x1A49,0x1A49,0},
+{0x1A4A,0x1A4A,0},
+{0x1A4B,0x1A4B,0},
+{0x1A4C,0x1A4C,0},
+{0x1A4D,0x1A4D,0},
+{0x1A4E,0x1A4E,0},
+{0x1A4F,0x1A4F,0},
+{0x1A50,0x1A50,0},
+{0x1A51,0x1A51,0},
+{0x1A52,0x1A52,0},
+{0x1A53,0x1A53,0},
+{0x1A54,0x1A54,0},
+{0x1A55,0x1A55,0},
+{0x1A56,0x1A56,0},
+{0x1A57,0x1A57,0},
+{0x1A58,0x1A58,0},
+{0x1A59,0x1A59,0},
+{0x1A5A,0x1A5A,0},
+{0x1A5B,0x1A5B,0},
+{0x1A5C,0x1A5C,0},
+{0x1A5D,0x1A5D,0},
+{0x1A5E,0x1A5E,0},
+{0x1A5F,0x1A5F,0},
+{0x1A60,0x1A60,0},
+{0x1A61,0x1A61,0},
+{0x1A62,0x1A62,0},
+{0x1A63,0x1A63,0},
+{0x1A64,0x1A64,0},
+{0x1A65,0x1A65,0},
+{0x1A66,0x1A66,0},
+{0x1A67,0x1A67,0},
+{0x1A68,0x1A68,0},
+{0x1A69,0x1A69,0},
+{0x1A6A,0x1A6A,0},
+{0x1A6B,0x1A6B,0},
+{0x1A6C,0x1A6C,0},
+{0x1A6D,0x1A6D,0},
+{0x1A6E,0x1A6E,0},
+{0x1A6F,0x1A6F,0},
+{0x1A70,0x1A70,0},
+{0x1A71,0x1A71,0},
+{0x1A72,0x1A72,0},
+{0x1A73,0x1A73,0},
+{0x1A74,0x1A74,0},
+{0x1A75,0x1A75,0},
+{0x1A76,0x1A76,0},
+{0x1A77,0x1A77,0},
+{0x1A78,0x1A78,0},
+{0x1A79,0x1A79,0},
+{0x1A7A,0x1A7A,0},
+{0x1A7B,0x1A7B,0},
+{0x1A7C,0x1A7C,0},
+{0x1A7D,0x1A7D,0},
+{0x1A7E,0x1A7E,0},
+{0x1A7F,0x1A7F,0},
+{0x1A80,0x1A80,0},
+{0x1A81,0x1A81,0},
+{0x1A82,0x1A82,0},
+{0x1A83,0x1A83,0},
+{0x1A84,0x1A84,0},
+{0x1A85,0x1A85,0},
+{0x1A86,0x1A86,0},
+{0x1A87,0x1A87,0},
+{0x1A88,0x1A88,0},
+{0x1A89,0x1A89,0},
+{0x1A8A,0x1A8A,0},
+{0x1A8B,0x1A8B,0},
+{0x1A8C,0x1A8C,0},
+{0x1A8D,0x1A8D,0},
+{0x1A8E,0x1A8E,0},
+{0x1A8F,0x1A8F,0},
+{0x1A90,0x1A90,0},
+{0x1A91,0x1A91,0},
+{0x1A92,0x1A92,0},
+{0x1A93,0x1A93,0},
+{0x1A94,0x1A94,0},
+{0x1A95,0x1A95,0},
+{0x1A96,0x1A96,0},
+{0x1A97,0x1A97,0},
+{0x1A98,0x1A98,0},
+{0x1A99,0x1A99,0},
+{0x1A9A,0x1A9A,0},
+{0x1A9B,0x1A9B,0},
+{0x1A9C,0x1A9C,0},
+{0x1A9D,0x1A9D,0},
+{0x1A9E,0x1A9E,0},
+{0x1A9F,0x1A9F,0},
+{0x1AA0,0x1AA0,0},
+{0x1AA1,0x1AA1,0},
+{0x1AA2,0x1AA2,0},
+{0x1AA3,0x1AA3,0},
+{0x1AA4,0x1AA4,0},
+{0x1AA5,0x1AA5,0},
+{0x1AA6,0x1AA6,0},
+{0x1AA7,0x1AA7,0},
+{0x1AA8,0x1AA8,0},
+{0x1AA9,0x1AA9,0},
+{0x1AAA,0x1AAA,0},
+{0x1AAB,0x1AAB,0},
+{0x1AAC,0x1AAC,0},
+{0x1AAD,0x1AAD,0},
+{0x1AAE,0x1AAE,0},
+{0x1AAF,0x1AAF,0},
+{0x1AB0,0x1AB0,0},
+{0x1AB1,0x1AB1,0},
+{0x1AB2,0x1AB2,0},
+{0x1AB3,0x1AB3,0},
+{0x1AB4,0x1AB4,0},
+{0x1AB5,0x1AB5,0},
+{0x1AB6,0x1AB6,0},
+{0x1AB7,0x1AB7,0},
+{0x1AB8,0x1AB8,0},
+{0x1AB9,0x1AB9,0},
+{0x1ABA,0x1ABA,0},
+{0x1ABB,0x1ABB,0},
+{0x1ABC,0x1ABC,0},
+{0x1ABD,0x1ABD,0},
+{0x1ABE,0x1ABE,0},
+{0x1ABF,0x1ABF,0},
+{0x1AC0,0x1AC0,0},
+{0x1AC1,0x1AC1,0},
+{0x1AC2,0x1AC2,0},
+{0x1AC3,0x1AC3,0},
+{0x1AC4,0x1AC4,0},
+{0x1AC5,0x1AC5,0},
+{0x1AC6,0x1AC6,0},
+{0x1AC7,0x1AC7,0},
+{0x1AC8,0x1AC8,0},
+{0x1AC9,0x1AC9,0},
+{0x1ACA,0x1ACA,0},
+{0x1ACB,0x1ACB,0},
+{0x1ACC,0x1ACC,0},
+{0x1ACD,0x1ACD,0},
+{0x1ACE,0x1ACE,0},
+{0x1ACF,0x1ACF,0},
+{0x1AD0,0x1AD0,0},
+{0x1AD1,0x1AD1,0},
+{0x1AD2,0x1AD2,0},
+{0x1AD3,0x1AD3,0},
+{0x1AD4,0x1AD4,0},
+{0x1AD5,0x1AD5,0},
+{0x1AD6,0x1AD6,0},
+{0x1AD7,0x1AD7,0},
+{0x1AD8,0x1AD8,0},
+{0x1AD9,0x1AD9,0},
+{0x1ADA,0x1ADA,0},
+{0x1ADB,0x1ADB,0},
+{0x1ADC,0x1ADC,0},
+{0x1ADD,0x1ADD,0},
+{0x1ADE,0x1ADE,0},
+{0x1ADF,0x1ADF,0},
+{0x1AE0,0x1AE0,0},
+{0x1AE1,0x1AE1,0},
+{0x1AE2,0x1AE2,0},
+{0x1AE3,0x1AE3,0},
+{0x1AE4,0x1AE4,0},
+{0x1AE5,0x1AE5,0},
+{0x1AE6,0x1AE6,0},
+{0x1AE7,0x1AE7,0},
+{0x1AE8,0x1AE8,0},
+{0x1AE9,0x1AE9,0},
+{0x1AEA,0x1AEA,0},
+{0x1AEB,0x1AEB,0},
+{0x1AEC,0x1AEC,0},
+{0x1AED,0x1AED,0},
+{0x1AEE,0x1AEE,0},
+{0x1AEF,0x1AEF,0},
+{0x1AF0,0x1AF0,0},
+{0x1AF1,0x1AF1,0},
+{0x1AF2,0x1AF2,0},
+{0x1AF3,0x1AF3,0},
+{0x1AF4,0x1AF4,0},
+{0x1AF5,0x1AF5,0},
+{0x1AF6,0x1AF6,0},
+{0x1AF7,0x1AF7,0},
+{0x1AF8,0x1AF8,0},
+{0x1AF9,0x1AF9,0},
+{0x1AFA,0x1AFA,0},
+{0x1AFB,0x1AFB,0},
+{0x1AFC,0x1AFC,0},
+{0x1AFD,0x1AFD,0},
+{0x1AFE,0x1AFE,0},
+{0x1AFF,0x1AFF,0},
+{0x1B00,0x1B00,0},
+{0x1B01,0x1B01,0},
+{0x1B02,0x1B02,0},
+{0x1B03,0x1B03,0},
+{0x1B04,0x1B04,0},
+{0x1B05,0x1B05,0},
+{0x1B06,0x1B06,0},
+{0x1B07,0x1B07,0},
+{0x1B08,0x1B08,0},
+{0x1B09,0x1B09,0},
+{0x1B0A,0x1B0A,0},
+{0x1B0B,0x1B0B,0},
+{0x1B0C,0x1B0C,0},
+{0x1B0D,0x1B0D,0},
+{0x1B0E,0x1B0E,0},
+{0x1B0F,0x1B0F,0},
+{0x1B10,0x1B10,0},
+{0x1B11,0x1B11,0},
+{0x1B12,0x1B12,0},
+{0x1B13,0x1B13,0},
+{0x1B14,0x1B14,0},
+{0x1B15,0x1B15,0},
+{0x1B16,0x1B16,0},
+{0x1B17,0x1B17,0},
+{0x1B18,0x1B18,0},
+{0x1B19,0x1B19,0},
+{0x1B1A,0x1B1A,0},
+{0x1B1B,0x1B1B,0},
+{0x1B1C,0x1B1C,0},
+{0x1B1D,0x1B1D,0},
+{0x1B1E,0x1B1E,0},
+{0x1B1F,0x1B1F,0},
+{0x1B20,0x1B20,0},
+{0x1B21,0x1B21,0},
+{0x1B22,0x1B22,0},
+{0x1B23,0x1B23,0},
+{0x1B24,0x1B24,0},
+{0x1B25,0x1B25,0},
+{0x1B26,0x1B26,0},
+{0x1B27,0x1B27,0},
+{0x1B28,0x1B28,0},
+{0x1B29,0x1B29,0},
+{0x1B2A,0x1B2A,0},
+{0x1B2B,0x1B2B,0},
+{0x1B2C,0x1B2C,0},
+{0x1B2D,0x1B2D,0},
+{0x1B2E,0x1B2E,0},
+{0x1B2F,0x1B2F,0},
+{0x1B30,0x1B30,0},
+{0x1B31,0x1B31,0},
+{0x1B32,0x1B32,0},
+{0x1B33,0x1B33,0},
+{0x1B34,0x1B34,0},
+{0x1B35,0x1B35,0},
+{0x1B36,0x1B36,0},
+{0x1B37,0x1B37,0},
+{0x1B38,0x1B38,0},
+{0x1B39,0x1B39,0},
+{0x1B3A,0x1B3A,0},
+{0x1B3B,0x1B3B,0},
+{0x1B3C,0x1B3C,0},
+{0x1B3D,0x1B3D,0},
+{0x1B3E,0x1B3E,0},
+{0x1B3F,0x1B3F,0},
+{0x1B40,0x1B40,0},
+{0x1B41,0x1B41,0},
+{0x1B42,0x1B42,0},
+{0x1B43,0x1B43,0},
+{0x1B44,0x1B44,0},
+{0x1B45,0x1B45,0},
+{0x1B46,0x1B46,0},
+{0x1B47,0x1B47,0},
+{0x1B48,0x1B48,0},
+{0x1B49,0x1B49,0},
+{0x1B4A,0x1B4A,0},
+{0x1B4B,0x1B4B,0},
+{0x1B4C,0x1B4C,0},
+{0x1B4D,0x1B4D,0},
+{0x1B4E,0x1B4E,0},
+{0x1B4F,0x1B4F,0},
+{0x1B50,0x1B50,0},
+{0x1B51,0x1B51,0},
+{0x1B52,0x1B52,0},
+{0x1B53,0x1B53,0},
+{0x1B54,0x1B54,0},
+{0x1B55,0x1B55,0},
+{0x1B56,0x1B56,0},
+{0x1B57,0x1B57,0},
+{0x1B58,0x1B58,0},
+{0x1B59,0x1B59,0},
+{0x1B5A,0x1B5A,0},
+{0x1B5B,0x1B5B,0},
+{0x1B5C,0x1B5C,0},
+{0x1B5D,0x1B5D,0},
+{0x1B5E,0x1B5E,0},
+{0x1B5F,0x1B5F,0},
+{0x1B60,0x1B60,0},
+{0x1B61,0x1B61,0},
+{0x1B62,0x1B62,0},
+{0x1B63,0x1B63,0},
+{0x1B64,0x1B64,0},
+{0x1B65,0x1B65,0},
+{0x1B66,0x1B66,0},
+{0x1B67,0x1B67,0},
+{0x1B68,0x1B68,0},
+{0x1B69,0x1B69,0},
+{0x1B6A,0x1B6A,0},
+{0x1B6B,0x1B6B,0},
+{0x1B6C,0x1B6C,0},
+{0x1B6D,0x1B6D,0},
+{0x1B6E,0x1B6E,0},
+{0x1B6F,0x1B6F,0},
+{0x1B70,0x1B70,0},
+{0x1B71,0x1B71,0},
+{0x1B72,0x1B72,0},
+{0x1B73,0x1B73,0},
+{0x1B74,0x1B74,0},
+{0x1B75,0x1B75,0},
+{0x1B76,0x1B76,0},
+{0x1B77,0x1B77,0},
+{0x1B78,0x1B78,0},
+{0x1B79,0x1B79,0},
+{0x1B7A,0x1B7A,0},
+{0x1B7B,0x1B7B,0},
+{0x1B7C,0x1B7C,0},
+{0x1B7D,0x1B7D,0},
+{0x1B7E,0x1B7E,0},
+{0x1B7F,0x1B7F,0},
+{0x1B80,0x1B80,0},
+{0x1B81,0x1B81,0},
+{0x1B82,0x1B82,0},
+{0x1B83,0x1B83,0},
+{0x1B84,0x1B84,0},
+{0x1B85,0x1B85,0},
+{0x1B86,0x1B86,0},
+{0x1B87,0x1B87,0},
+{0x1B88,0x1B88,0},
+{0x1B89,0x1B89,0},
+{0x1B8A,0x1B8A,0},
+{0x1B8B,0x1B8B,0},
+{0x1B8C,0x1B8C,0},
+{0x1B8D,0x1B8D,0},
+{0x1B8E,0x1B8E,0},
+{0x1B8F,0x1B8F,0},
+{0x1B90,0x1B90,0},
+{0x1B91,0x1B91,0},
+{0x1B92,0x1B92,0},
+{0x1B93,0x1B93,0},
+{0x1B94,0x1B94,0},
+{0x1B95,0x1B95,0},
+{0x1B96,0x1B96,0},
+{0x1B97,0x1B97,0},
+{0x1B98,0x1B98,0},
+{0x1B99,0x1B99,0},
+{0x1B9A,0x1B9A,0},
+{0x1B9B,0x1B9B,0},
+{0x1B9C,0x1B9C,0},
+{0x1B9D,0x1B9D,0},
+{0x1B9E,0x1B9E,0},
+{0x1B9F,0x1B9F,0},
+{0x1BA0,0x1BA0,0},
+{0x1BA1,0x1BA1,0},
+{0x1BA2,0x1BA2,0},
+{0x1BA3,0x1BA3,0},
+{0x1BA4,0x1BA4,0},
+{0x1BA5,0x1BA5,0},
+{0x1BA6,0x1BA6,0},
+{0x1BA7,0x1BA7,0},
+{0x1BA8,0x1BA8,0},
+{0x1BA9,0x1BA9,0},
+{0x1BAA,0x1BAA,0},
+{0x1BAB,0x1BAB,0},
+{0x1BAC,0x1BAC,0},
+{0x1BAD,0x1BAD,0},
+{0x1BAE,0x1BAE,0},
+{0x1BAF,0x1BAF,0},
+{0x1BB0,0x1BB0,0},
+{0x1BB1,0x1BB1,0},
+{0x1BB2,0x1BB2,0},
+{0x1BB3,0x1BB3,0},
+{0x1BB4,0x1BB4,0},
+{0x1BB5,0x1BB5,0},
+{0x1BB6,0x1BB6,0},
+{0x1BB7,0x1BB7,0},
+{0x1BB8,0x1BB8,0},
+{0x1BB9,0x1BB9,0},
+{0x1BBA,0x1BBA,0},
+{0x1BBB,0x1BBB,0},
+{0x1BBC,0x1BBC,0},
+{0x1BBD,0x1BBD,0},
+{0x1BBE,0x1BBE,0},
+{0x1BBF,0x1BBF,0},
+{0x1BC0,0x1BC0,0},
+{0x1BC1,0x1BC1,0},
+{0x1BC2,0x1BC2,0},
+{0x1BC3,0x1BC3,0},
+{0x1BC4,0x1BC4,0},
+{0x1BC5,0x1BC5,0},
+{0x1BC6,0x1BC6,0},
+{0x1BC7,0x1BC7,0},
+{0x1BC8,0x1BC8,0},
+{0x1BC9,0x1BC9,0},
+{0x1BCA,0x1BCA,0},
+{0x1BCB,0x1BCB,0},
+{0x1BCC,0x1BCC,0},
+{0x1BCD,0x1BCD,0},
+{0x1BCE,0x1BCE,0},
+{0x1BCF,0x1BCF,0},
+{0x1BD0,0x1BD0,0},
+{0x1BD1,0x1BD1,0},
+{0x1BD2,0x1BD2,0},
+{0x1BD3,0x1BD3,0},
+{0x1BD4,0x1BD4,0},
+{0x1BD5,0x1BD5,0},
+{0x1BD6,0x1BD6,0},
+{0x1BD7,0x1BD7,0},
+{0x1BD8,0x1BD8,0},
+{0x1BD9,0x1BD9,0},
+{0x1BDA,0x1BDA,0},
+{0x1BDB,0x1BDB,0},
+{0x1BDC,0x1BDC,0},
+{0x1BDD,0x1BDD,0},
+{0x1BDE,0x1BDE,0},
+{0x1BDF,0x1BDF,0},
+{0x1BE0,0x1BE0,0},
+{0x1BE1,0x1BE1,0},
+{0x1BE2,0x1BE2,0},
+{0x1BE3,0x1BE3,0},
+{0x1BE4,0x1BE4,0},
+{0x1BE5,0x1BE5,0},
+{0x1BE6,0x1BE6,0},
+{0x1BE7,0x1BE7,0},
+{0x1BE8,0x1BE8,0},
+{0x1BE9,0x1BE9,0},
+{0x1BEA,0x1BEA,0},
+{0x1BEB,0x1BEB,0},
+{0x1BEC,0x1BEC,0},
+{0x1BED,0x1BED,0},
+{0x1BEE,0x1BEE,0},
+{0x1BEF,0x1BEF,0},
+{0x1BF0,0x1BF0,0},
+{0x1BF1,0x1BF1,0},
+{0x1BF2,0x1BF2,0},
+{0x1BF3,0x1BF3,0},
+{0x1BF4,0x1BF4,0},
+{0x1BF5,0x1BF5,0},
+{0x1BF6,0x1BF6,0},
+{0x1BF7,0x1BF7,0},
+{0x1BF8,0x1BF8,0},
+{0x1BF9,0x1BF9,0},
+{0x1BFA,0x1BFA,0},
+{0x1BFB,0x1BFB,0},
+{0x1BFC,0x1BFC,0},
+{0x1BFD,0x1BFD,0},
+{0x1BFE,0x1BFE,0},
+{0x1BFF,0x1BFF,0},
+{0x1C00,0x1C00,0},
+{0x1C01,0x1C01,0},
+{0x1C02,0x1C02,0},
+{0x1C03,0x1C03,0},
+{0x1C04,0x1C04,0},
+{0x1C05,0x1C05,0},
+{0x1C06,0x1C06,0},
+{0x1C07,0x1C07,0},
+{0x1C08,0x1C08,0},
+{0x1C09,0x1C09,0},
+{0x1C0A,0x1C0A,0},
+{0x1C0B,0x1C0B,0},
+{0x1C0C,0x1C0C,0},
+{0x1C0D,0x1C0D,0},
+{0x1C0E,0x1C0E,0},
+{0x1C0F,0x1C0F,0},
+{0x1C10,0x1C10,0},
+{0x1C11,0x1C11,0},
+{0x1C12,0x1C12,0},
+{0x1C13,0x1C13,0},
+{0x1C14,0x1C14,0},
+{0x1C15,0x1C15,0},
+{0x1C16,0x1C16,0},
+{0x1C17,0x1C17,0},
+{0x1C18,0x1C18,0},
+{0x1C19,0x1C19,0},
+{0x1C1A,0x1C1A,0},
+{0x1C1B,0x1C1B,0},
+{0x1C1C,0x1C1C,0},
+{0x1C1D,0x1C1D,0},
+{0x1C1E,0x1C1E,0},
+{0x1C1F,0x1C1F,0},
+{0x1C20,0x1C20,0},
+{0x1C21,0x1C21,0},
+{0x1C22,0x1C22,0},
+{0x1C23,0x1C23,0},
+{0x1C24,0x1C24,0},
+{0x1C25,0x1C25,0},
+{0x1C26,0x1C26,0},
+{0x1C27,0x1C27,0},
+{0x1C28,0x1C28,0},
+{0x1C29,0x1C29,0},
+{0x1C2A,0x1C2A,0},
+{0x1C2B,0x1C2B,0},
+{0x1C2C,0x1C2C,0},
+{0x1C2D,0x1C2D,0},
+{0x1C2E,0x1C2E,0},
+{0x1C2F,0x1C2F,0},
+{0x1C30,0x1C30,0},
+{0x1C31,0x1C31,0},
+{0x1C32,0x1C32,0},
+{0x1C33,0x1C33,0},
+{0x1C34,0x1C34,0},
+{0x1C35,0x1C35,0},
+{0x1C36,0x1C36,0},
+{0x1C37,0x1C37,0},
+{0x1C38,0x1C38,0},
+{0x1C39,0x1C39,0},
+{0x1C3A,0x1C3A,0},
+{0x1C3B,0x1C3B,0},
+{0x1C3C,0x1C3C,0},
+{0x1C3D,0x1C3D,0},
+{0x1C3E,0x1C3E,0},
+{0x1C3F,0x1C3F,0},
+{0x1C40,0x1C40,0},
+{0x1C41,0x1C41,0},
+{0x1C42,0x1C42,0},
+{0x1C43,0x1C43,0},
+{0x1C44,0x1C44,0},
+{0x1C45,0x1C45,0},
+{0x1C46,0x1C46,0},
+{0x1C47,0x1C47,0},
+{0x1C48,0x1C48,0},
+{0x1C49,0x1C49,0},
+{0x1C4A,0x1C4A,0},
+{0x1C4B,0x1C4B,0},
+{0x1C4C,0x1C4C,0},
+{0x1C4D,0x1C4D,0},
+{0x1C4E,0x1C4E,0},
+{0x1C4F,0x1C4F,0},
+{0x1C50,0x1C50,0},
+{0x1C51,0x1C51,0},
+{0x1C52,0x1C52,0},
+{0x1C53,0x1C53,0},
+{0x1C54,0x1C54,0},
+{0x1C55,0x1C55,0},
+{0x1C56,0x1C56,0},
+{0x1C57,0x1C57,0},
+{0x1C58,0x1C58,0},
+{0x1C59,0x1C59,0},
+{0x1C5A,0x1C5A,0},
+{0x1C5B,0x1C5B,0},
+{0x1C5C,0x1C5C,0},
+{0x1C5D,0x1C5D,0},
+{0x1C5E,0x1C5E,0},
+{0x1C5F,0x1C5F,0},
+{0x1C60,0x1C60,0},
+{0x1C61,0x1C61,0},
+{0x1C62,0x1C62,0},
+{0x1C63,0x1C63,0},
+{0x1C64,0x1C64,0},
+{0x1C65,0x1C65,0},
+{0x1C66,0x1C66,0},
+{0x1C67,0x1C67,0},
+{0x1C68,0x1C68,0},
+{0x1C69,0x1C69,0},
+{0x1C6A,0x1C6A,0},
+{0x1C6B,0x1C6B,0},
+{0x1C6C,0x1C6C,0},
+{0x1C6D,0x1C6D,0},
+{0x1C6E,0x1C6E,0},
+{0x1C6F,0x1C6F,0},
+{0x1C70,0x1C70,0},
+{0x1C71,0x1C71,0},
+{0x1C72,0x1C72,0},
+{0x1C73,0x1C73,0},
+{0x1C74,0x1C74,0},
+{0x1C75,0x1C75,0},
+{0x1C76,0x1C76,0},
+{0x1C77,0x1C77,0},
+{0x1C78,0x1C78,0},
+{0x1C79,0x1C79,0},
+{0x1C7A,0x1C7A,0},
+{0x1C7B,0x1C7B,0},
+{0x1C7C,0x1C7C,0},
+{0x1C7D,0x1C7D,0},
+{0x1C7E,0x1C7E,0},
+{0x1C7F,0x1C7F,0},
+{0x1C80,0x1C80,0},
+{0x1C81,0x1C81,0},
+{0x1C82,0x1C82,0},
+{0x1C83,0x1C83,0},
+{0x1C84,0x1C84,0},
+{0x1C85,0x1C85,0},
+{0x1C86,0x1C86,0},
+{0x1C87,0x1C87,0},
+{0x1C88,0x1C88,0},
+{0x1C89,0x1C89,0},
+{0x1C8A,0x1C8A,0},
+{0x1C8B,0x1C8B,0},
+{0x1C8C,0x1C8C,0},
+{0x1C8D,0x1C8D,0},
+{0x1C8E,0x1C8E,0},
+{0x1C8F,0x1C8F,0},
+{0x1C90,0x1C90,0},
+{0x1C91,0x1C91,0},
+{0x1C92,0x1C92,0},
+{0x1C93,0x1C93,0},
+{0x1C94,0x1C94,0},
+{0x1C95,0x1C95,0},
+{0x1C96,0x1C96,0},
+{0x1C97,0x1C97,0},
+{0x1C98,0x1C98,0},
+{0x1C99,0x1C99,0},
+{0x1C9A,0x1C9A,0},
+{0x1C9B,0x1C9B,0},
+{0x1C9C,0x1C9C,0},
+{0x1C9D,0x1C9D,0},
+{0x1C9E,0x1C9E,0},
+{0x1C9F,0x1C9F,0},
+{0x1CA0,0x1CA0,0},
+{0x1CA1,0x1CA1,0},
+{0x1CA2,0x1CA2,0},
+{0x1CA3,0x1CA3,0},
+{0x1CA4,0x1CA4,0},
+{0x1CA5,0x1CA5,0},
+{0x1CA6,0x1CA6,0},
+{0x1CA7,0x1CA7,0},
+{0x1CA8,0x1CA8,0},
+{0x1CA9,0x1CA9,0},
+{0x1CAA,0x1CAA,0},
+{0x1CAB,0x1CAB,0},
+{0x1CAC,0x1CAC,0},
+{0x1CAD,0x1CAD,0},
+{0x1CAE,0x1CAE,0},
+{0x1CAF,0x1CAF,0},
+{0x1CB0,0x1CB0,0},
+{0x1CB1,0x1CB1,0},
+{0x1CB2,0x1CB2,0},
+{0x1CB3,0x1CB3,0},
+{0x1CB4,0x1CB4,0},
+{0x1CB5,0x1CB5,0},
+{0x1CB6,0x1CB6,0},
+{0x1CB7,0x1CB7,0},
+{0x1CB8,0x1CB8,0},
+{0x1CB9,0x1CB9,0},
+{0x1CBA,0x1CBA,0},
+{0x1CBB,0x1CBB,0},
+{0x1CBC,0x1CBC,0},
+{0x1CBD,0x1CBD,0},
+{0x1CBE,0x1CBE,0},
+{0x1CBF,0x1CBF,0},
+{0x1CC0,0x1CC0,0},
+{0x1CC1,0x1CC1,0},
+{0x1CC2,0x1CC2,0},
+{0x1CC3,0x1CC3,0},
+{0x1CC4,0x1CC4,0},
+{0x1CC5,0x1CC5,0},
+{0x1CC6,0x1CC6,0},
+{0x1CC7,0x1CC7,0},
+{0x1CC8,0x1CC8,0},
+{0x1CC9,0x1CC9,0},
+{0x1CCA,0x1CCA,0},
+{0x1CCB,0x1CCB,0},
+{0x1CCC,0x1CCC,0},
+{0x1CCD,0x1CCD,0},
+{0x1CCE,0x1CCE,0},
+{0x1CCF,0x1CCF,0},
+{0x1CD0,0x1CD0,0},
+{0x1CD1,0x1CD1,0},
+{0x1CD2,0x1CD2,0},
+{0x1CD3,0x1CD3,0},
+{0x1CD4,0x1CD4,0},
+{0x1CD5,0x1CD5,0},
+{0x1CD6,0x1CD6,0},
+{0x1CD7,0x1CD7,0},
+{0x1CD8,0x1CD8,0},
+{0x1CD9,0x1CD9,0},
+{0x1CDA,0x1CDA,0},
+{0x1CDB,0x1CDB,0},
+{0x1CDC,0x1CDC,0},
+{0x1CDD,0x1CDD,0},
+{0x1CDE,0x1CDE,0},
+{0x1CDF,0x1CDF,0},
+{0x1CE0,0x1CE0,0},
+{0x1CE1,0x1CE1,0},
+{0x1CE2,0x1CE2,0},
+{0x1CE3,0x1CE3,0},
+{0x1CE4,0x1CE4,0},
+{0x1CE5,0x1CE5,0},
+{0x1CE6,0x1CE6,0},
+{0x1CE7,0x1CE7,0},
+{0x1CE8,0x1CE8,0},
+{0x1CE9,0x1CE9,0},
+{0x1CEA,0x1CEA,0},
+{0x1CEB,0x1CEB,0},
+{0x1CEC,0x1CEC,0},
+{0x1CED,0x1CED,0},
+{0x1CEE,0x1CEE,0},
+{0x1CEF,0x1CEF,0},
+{0x1CF0,0x1CF0,0},
+{0x1CF1,0x1CF1,0},
+{0x1CF2,0x1CF2,0},
+{0x1CF3,0x1CF3,0},
+{0x1CF4,0x1CF4,0},
+{0x1CF5,0x1CF5,0},
+{0x1CF6,0x1CF6,0},
+{0x1CF7,0x1CF7,0},
+{0x1CF8,0x1CF8,0},
+{0x1CF9,0x1CF9,0},
+{0x1CFA,0x1CFA,0},
+{0x1CFB,0x1CFB,0},
+{0x1CFC,0x1CFC,0},
+{0x1CFD,0x1CFD,0},
+{0x1CFE,0x1CFE,0},
+{0x1CFF,0x1CFF,0},
+{0x1D00,0x1D00,0},
+{0x1D01,0x1D01,0},
+{0x1D02,0x1D02,0},
+{0x1D03,0x1D03,0},
+{0x1D04,0x1D04,0},
+{0x1D05,0x1D05,0},
+{0x1D06,0x1D06,0},
+{0x1D07,0x1D07,0},
+{0x1D08,0x1D08,0},
+{0x1D09,0x1D09,0},
+{0x1D0A,0x1D0A,0},
+{0x1D0B,0x1D0B,0},
+{0x1D0C,0x1D0C,0},
+{0x1D0D,0x1D0D,0},
+{0x1D0E,0x1D0E,0},
+{0x1D0F,0x1D0F,0},
+{0x1D10,0x1D10,0},
+{0x1D11,0x1D11,0},
+{0x1D12,0x1D12,0},
+{0x1D13,0x1D13,0},
+{0x1D14,0x1D14,0},
+{0x1D15,0x1D15,0},
+{0x1D16,0x1D16,0},
+{0x1D17,0x1D17,0},
+{0x1D18,0x1D18,0},
+{0x1D19,0x1D19,0},
+{0x1D1A,0x1D1A,0},
+{0x1D1B,0x1D1B,0},
+{0x1D1C,0x1D1C,0},
+{0x1D1D,0x1D1D,0},
+{0x1D1E,0x1D1E,0},
+{0x1D1F,0x1D1F,0},
+{0x1D20,0x1D20,0},
+{0x1D21,0x1D21,0},
+{0x1D22,0x1D22,0},
+{0x1D23,0x1D23,0},
+{0x1D24,0x1D24,0},
+{0x1D25,0x1D25,0},
+{0x1D26,0x1D26,0},
+{0x1D27,0x1D27,0},
+{0x1D28,0x1D28,0},
+{0x1D29,0x1D29,0},
+{0x1D2A,0x1D2A,0},
+{0x1D2B,0x1D2B,0},
+{0x1D2C,0x1D2C,0},
+{0x1D2D,0x1D2D,0},
+{0x1D2E,0x1D2E,0},
+{0x1D2F,0x1D2F,0},
+{0x1D30,0x1D30,0},
+{0x1D31,0x1D31,0},
+{0x1D32,0x1D32,0},
+{0x1D33,0x1D33,0},
+{0x1D34,0x1D34,0},
+{0x1D35,0x1D35,0},
+{0x1D36,0x1D36,0},
+{0x1D37,0x1D37,0},
+{0x1D38,0x1D38,0},
+{0x1D39,0x1D39,0},
+{0x1D3A,0x1D3A,0},
+{0x1D3B,0x1D3B,0},
+{0x1D3C,0x1D3C,0},
+{0x1D3D,0x1D3D,0},
+{0x1D3E,0x1D3E,0},
+{0x1D3F,0x1D3F,0},
+{0x1D40,0x1D40,0},
+{0x1D41,0x1D41,0},
+{0x1D42,0x1D42,0},
+{0x1D43,0x1D43,0},
+{0x1D44,0x1D44,0},
+{0x1D45,0x1D45,0},
+{0x1D46,0x1D46,0},
+{0x1D47,0x1D47,0},
+{0x1D48,0x1D48,0},
+{0x1D49,0x1D49,0},
+{0x1D4A,0x1D4A,0},
+{0x1D4B,0x1D4B,0},
+{0x1D4C,0x1D4C,0},
+{0x1D4D,0x1D4D,0},
+{0x1D4E,0x1D4E,0},
+{0x1D4F,0x1D4F,0},
+{0x1D50,0x1D50,0},
+{0x1D51,0x1D51,0},
+{0x1D52,0x1D52,0},
+{0x1D53,0x1D53,0},
+{0x1D54,0x1D54,0},
+{0x1D55,0x1D55,0},
+{0x1D56,0x1D56,0},
+{0x1D57,0x1D57,0},
+{0x1D58,0x1D58,0},
+{0x1D59,0x1D59,0},
+{0x1D5A,0x1D5A,0},
+{0x1D5B,0x1D5B,0},
+{0x1D5C,0x1D5C,0},
+{0x1D5D,0x1D5D,0},
+{0x1D5E,0x1D5E,0},
+{0x1D5F,0x1D5F,0},
+{0x1D60,0x1D60,0},
+{0x1D61,0x1D61,0},
+{0x1D62,0x1D62,0},
+{0x1D63,0x1D63,0},
+{0x1D64,0x1D64,0},
+{0x1D65,0x1D65,0},
+{0x1D66,0x1D66,0},
+{0x1D67,0x1D67,0},
+{0x1D68,0x1D68,0},
+{0x1D69,0x1D69,0},
+{0x1D6A,0x1D6A,0},
+{0x1D6B,0x1D6B,0},
+{0x1D6C,0x1D6C,0},
+{0x1D6D,0x1D6D,0},
+{0x1D6E,0x1D6E,0},
+{0x1D6F,0x1D6F,0},
+{0x1D70,0x1D70,0},
+{0x1D71,0x1D71,0},
+{0x1D72,0x1D72,0},
+{0x1D73,0x1D73,0},
+{0x1D74,0x1D74,0},
+{0x1D75,0x1D75,0},
+{0x1D76,0x1D76,0},
+{0x1D77,0x1D77,0},
+{0x1D78,0x1D78,0},
+{0x1D79,0x1D79,0},
+{0x1D7A,0x1D7A,0},
+{0x1D7B,0x1D7B,0},
+{0x1D7C,0x1D7C,0},
+{0x1D7D,0x1D7D,0},
+{0x1D7E,0x1D7E,0},
+{0x1D7F,0x1D7F,0},
+{0x1D80,0x1D80,0},
+{0x1D81,0x1D81,0},
+{0x1D82,0x1D82,0},
+{0x1D83,0x1D83,0},
+{0x1D84,0x1D84,0},
+{0x1D85,0x1D85,0},
+{0x1D86,0x1D86,0},
+{0x1D87,0x1D87,0},
+{0x1D88,0x1D88,0},
+{0x1D89,0x1D89,0},
+{0x1D8A,0x1D8A,0},
+{0x1D8B,0x1D8B,0},
+{0x1D8C,0x1D8C,0},
+{0x1D8D,0x1D8D,0},
+{0x1D8E,0x1D8E,0},
+{0x1D8F,0x1D8F,0},
+{0x1D90,0x1D90,0},
+{0x1D91,0x1D91,0},
+{0x1D92,0x1D92,0},
+{0x1D93,0x1D93,0},
+{0x1D94,0x1D94,0},
+{0x1D95,0x1D95,0},
+{0x1D96,0x1D96,0},
+{0x1D97,0x1D97,0},
+{0x1D98,0x1D98,0},
+{0x1D99,0x1D99,0},
+{0x1D9A,0x1D9A,0},
+{0x1D9B,0x1D9B,0},
+{0x1D9C,0x1D9C,0},
+{0x1D9D,0x1D9D,0},
+{0x1D9E,0x1D9E,0},
+{0x1D9F,0x1D9F,0},
+{0x1DA0,0x1DA0,0},
+{0x1DA1,0x1DA1,0},
+{0x1DA2,0x1DA2,0},
+{0x1DA3,0x1DA3,0},
+{0x1DA4,0x1DA4,0},
+{0x1DA5,0x1DA5,0},
+{0x1DA6,0x1DA6,0},
+{0x1DA7,0x1DA7,0},
+{0x1DA8,0x1DA8,0},
+{0x1DA9,0x1DA9,0},
+{0x1DAA,0x1DAA,0},
+{0x1DAB,0x1DAB,0},
+{0x1DAC,0x1DAC,0},
+{0x1DAD,0x1DAD,0},
+{0x1DAE,0x1DAE,0},
+{0x1DAF,0x1DAF,0},
+{0x1DB0,0x1DB0,0},
+{0x1DB1,0x1DB1,0},
+{0x1DB2,0x1DB2,0},
+{0x1DB3,0x1DB3,0},
+{0x1DB4,0x1DB4,0},
+{0x1DB5,0x1DB5,0},
+{0x1DB6,0x1DB6,0},
+{0x1DB7,0x1DB7,0},
+{0x1DB8,0x1DB8,0},
+{0x1DB9,0x1DB9,0},
+{0x1DBA,0x1DBA,0},
+{0x1DBB,0x1DBB,0},
+{0x1DBC,0x1DBC,0},
+{0x1DBD,0x1DBD,0},
+{0x1DBE,0x1DBE,0},
+{0x1DBF,0x1DBF,0},
+{0x1DC0,0x1DC0,0},
+{0x1DC1,0x1DC1,0},
+{0x1DC2,0x1DC2,0},
+{0x1DC3,0x1DC3,0},
+{0x1DC4,0x1DC4,0},
+{0x1DC5,0x1DC5,0},
+{0x1DC6,0x1DC6,0},
+{0x1DC7,0x1DC7,0},
+{0x1DC8,0x1DC8,0},
+{0x1DC9,0x1DC9,0},
+{0x1DCA,0x1DCA,0},
+{0x1DCB,0x1DCB,0},
+{0x1DCC,0x1DCC,0},
+{0x1DCD,0x1DCD,0},
+{0x1DCE,0x1DCE,0},
+{0x1DCF,0x1DCF,0},
+{0x1DD0,0x1DD0,0},
+{0x1DD1,0x1DD1,0},
+{0x1DD2,0x1DD2,0},
+{0x1DD3,0x1DD3,0},
+{0x1DD4,0x1DD4,0},
+{0x1DD5,0x1DD5,0},
+{0x1DD6,0x1DD6,0},
+{0x1DD7,0x1DD7,0},
+{0x1DD8,0x1DD8,0},
+{0x1DD9,0x1DD9,0},
+{0x1DDA,0x1DDA,0},
+{0x1DDB,0x1DDB,0},
+{0x1DDC,0x1DDC,0},
+{0x1DDD,0x1DDD,0},
+{0x1DDE,0x1DDE,0},
+{0x1DDF,0x1DDF,0},
+{0x1DE0,0x1DE0,0},
+{0x1DE1,0x1DE1,0},
+{0x1DE2,0x1DE2,0},
+{0x1DE3,0x1DE3,0},
+{0x1DE4,0x1DE4,0},
+{0x1DE5,0x1DE5,0},
+{0x1DE6,0x1DE6,0},
+{0x1DE7,0x1DE7,0},
+{0x1DE8,0x1DE8,0},
+{0x1DE9,0x1DE9,0},
+{0x1DEA,0x1DEA,0},
+{0x1DEB,0x1DEB,0},
+{0x1DEC,0x1DEC,0},
+{0x1DED,0x1DED,0},
+{0x1DEE,0x1DEE,0},
+{0x1DEF,0x1DEF,0},
+{0x1DF0,0x1DF0,0},
+{0x1DF1,0x1DF1,0},
+{0x1DF2,0x1DF2,0},
+{0x1DF3,0x1DF3,0},
+{0x1DF4,0x1DF4,0},
+{0x1DF5,0x1DF5,0},
+{0x1DF6,0x1DF6,0},
+{0x1DF7,0x1DF7,0},
+{0x1DF8,0x1DF8,0},
+{0x1DF9,0x1DF9,0},
+{0x1DFA,0x1DFA,0},
+{0x1DFB,0x1DFB,0},
+{0x1DFC,0x1DFC,0},
+{0x1DFD,0x1DFD,0},
+{0x1DFE,0x1DFE,0},
+{0x1DFF,0x1DFF,0},
+{0x1E01,0x1E00,UNI_UPPER},
+{0x1E01,0x1E00,UNI_LOWER},
+{0x1E03,0x1E02,UNI_UPPER},
+{0x1E03,0x1E02,UNI_LOWER},
+{0x1E05,0x1E04,UNI_UPPER},
+{0x1E05,0x1E04,UNI_LOWER},
+{0x1E07,0x1E06,UNI_UPPER},
+{0x1E07,0x1E06,UNI_LOWER},
+{0x1E09,0x1E08,UNI_UPPER},
+{0x1E09,0x1E08,UNI_LOWER},
+{0x1E0B,0x1E0A,UNI_UPPER},
+{0x1E0B,0x1E0A,UNI_LOWER},
+{0x1E0D,0x1E0C,UNI_UPPER},
+{0x1E0D,0x1E0C,UNI_LOWER},
+{0x1E0F,0x1E0E,UNI_UPPER},
+{0x1E0F,0x1E0E,UNI_LOWER},
+{0x1E11,0x1E10,UNI_UPPER},
+{0x1E11,0x1E10,UNI_LOWER},
+{0x1E13,0x1E12,UNI_UPPER},
+{0x1E13,0x1E12,UNI_LOWER},
+{0x1E15,0x1E14,UNI_UPPER},
+{0x1E15,0x1E14,UNI_LOWER},
+{0x1E17,0x1E16,UNI_UPPER},
+{0x1E17,0x1E16,UNI_LOWER},
+{0x1E19,0x1E18,UNI_UPPER},
+{0x1E19,0x1E18,UNI_LOWER},
+{0x1E1B,0x1E1A,UNI_UPPER},
+{0x1E1B,0x1E1A,UNI_LOWER},
+{0x1E1D,0x1E1C,UNI_UPPER},
+{0x1E1D,0x1E1C,UNI_LOWER},
+{0x1E1F,0x1E1E,UNI_UPPER},
+{0x1E1F,0x1E1E,UNI_LOWER},
+{0x1E21,0x1E20,UNI_UPPER},
+{0x1E21,0x1E20,UNI_LOWER},
+{0x1E23,0x1E22,UNI_UPPER},
+{0x1E23,0x1E22,UNI_LOWER},
+{0x1E25,0x1E24,UNI_UPPER},
+{0x1E25,0x1E24,UNI_LOWER},
+{0x1E27,0x1E26,UNI_UPPER},
+{0x1E27,0x1E26,UNI_LOWER},
+{0x1E29,0x1E28,UNI_UPPER},
+{0x1E29,0x1E28,UNI_LOWER},
+{0x1E2B,0x1E2A,UNI_UPPER},
+{0x1E2B,0x1E2A,UNI_LOWER},
+{0x1E2D,0x1E2C,UNI_UPPER},
+{0x1E2D,0x1E2C,UNI_LOWER},
+{0x1E2F,0x1E2E,UNI_UPPER},
+{0x1E2F,0x1E2E,UNI_LOWER},
+{0x1E31,0x1E30,UNI_UPPER},
+{0x1E31,0x1E30,UNI_LOWER},
+{0x1E33,0x1E32,UNI_UPPER},
+{0x1E33,0x1E32,UNI_LOWER},
+{0x1E35,0x1E34,UNI_UPPER},
+{0x1E35,0x1E34,UNI_LOWER},
+{0x1E37,0x1E36,UNI_UPPER},
+{0x1E37,0x1E36,UNI_LOWER},
+{0x1E39,0x1E38,UNI_UPPER},
+{0x1E39,0x1E38,UNI_LOWER},
+{0x1E3B,0x1E3A,UNI_UPPER},
+{0x1E3B,0x1E3A,UNI_LOWER},
+{0x1E3D,0x1E3C,UNI_UPPER},
+{0x1E3D,0x1E3C,UNI_LOWER},
+{0x1E3F,0x1E3E,UNI_UPPER},
+{0x1E3F,0x1E3E,UNI_LOWER},
+{0x1E41,0x1E40,UNI_UPPER},
+{0x1E41,0x1E40,UNI_LOWER},
+{0x1E43,0x1E42,UNI_UPPER},
+{0x1E43,0x1E42,UNI_LOWER},
+{0x1E45,0x1E44,UNI_UPPER},
+{0x1E45,0x1E44,UNI_LOWER},
+{0x1E47,0x1E46,UNI_UPPER},
+{0x1E47,0x1E46,UNI_LOWER},
+{0x1E49,0x1E48,UNI_UPPER},
+{0x1E49,0x1E48,UNI_LOWER},
+{0x1E4B,0x1E4A,UNI_UPPER},
+{0x1E4B,0x1E4A,UNI_LOWER},
+{0x1E4D,0x1E4C,UNI_UPPER},
+{0x1E4D,0x1E4C,UNI_LOWER},
+{0x1E4F,0x1E4E,UNI_UPPER},
+{0x1E4F,0x1E4E,UNI_LOWER},
+{0x1E51,0x1E50,UNI_UPPER},
+{0x1E51,0x1E50,UNI_LOWER},
+{0x1E53,0x1E52,UNI_UPPER},
+{0x1E53,0x1E52,UNI_LOWER},
+{0x1E55,0x1E54,UNI_UPPER},
+{0x1E55,0x1E54,UNI_LOWER},
+{0x1E57,0x1E56,UNI_UPPER},
+{0x1E57,0x1E56,UNI_LOWER},
+{0x1E59,0x1E58,UNI_UPPER},
+{0x1E59,0x1E58,UNI_LOWER},
+{0x1E5B,0x1E5A,UNI_UPPER},
+{0x1E5B,0x1E5A,UNI_LOWER},
+{0x1E5D,0x1E5C,UNI_UPPER},
+{0x1E5D,0x1E5C,UNI_LOWER},
+{0x1E5F,0x1E5E,UNI_UPPER},
+{0x1E5F,0x1E5E,UNI_LOWER},
+{0x1E61,0x1E60,UNI_UPPER},
+{0x1E61,0x1E60,UNI_LOWER},
+{0x1E63,0x1E62,UNI_UPPER},
+{0x1E63,0x1E62,UNI_LOWER},
+{0x1E65,0x1E64,UNI_UPPER},
+{0x1E65,0x1E64,UNI_LOWER},
+{0x1E67,0x1E66,UNI_UPPER},
+{0x1E67,0x1E66,UNI_LOWER},
+{0x1E69,0x1E68,UNI_UPPER},
+{0x1E69,0x1E68,UNI_LOWER},
+{0x1E6B,0x1E6A,UNI_UPPER},
+{0x1E6B,0x1E6A,UNI_LOWER},
+{0x1E6D,0x1E6C,UNI_UPPER},
+{0x1E6D,0x1E6C,UNI_LOWER},
+{0x1E6F,0x1E6E,UNI_UPPER},
+{0x1E6F,0x1E6E,UNI_LOWER},
+{0x1E71,0x1E70,UNI_UPPER},
+{0x1E71,0x1E70,UNI_LOWER},
+{0x1E73,0x1E72,UNI_UPPER},
+{0x1E73,0x1E72,UNI_LOWER},
+{0x1E75,0x1E74,UNI_UPPER},
+{0x1E75,0x1E74,UNI_LOWER},
+{0x1E77,0x1E76,UNI_UPPER},
+{0x1E77,0x1E76,UNI_LOWER},
+{0x1E79,0x1E78,UNI_UPPER},
+{0x1E79,0x1E78,UNI_LOWER},
+{0x1E7B,0x1E7A,UNI_UPPER},
+{0x1E7B,0x1E7A,UNI_LOWER},
+{0x1E7D,0x1E7C,UNI_UPPER},
+{0x1E7D,0x1E7C,UNI_LOWER},
+{0x1E7F,0x1E7E,UNI_UPPER},
+{0x1E7F,0x1E7E,UNI_LOWER},
+{0x1E81,0x1E80,UNI_UPPER},
+{0x1E81,0x1E80,UNI_LOWER},
+{0x1E83,0x1E82,UNI_UPPER},
+{0x1E83,0x1E82,UNI_LOWER},
+{0x1E85,0x1E84,UNI_UPPER},
+{0x1E85,0x1E84,UNI_LOWER},
+{0x1E87,0x1E86,UNI_UPPER},
+{0x1E87,0x1E86,UNI_LOWER},
+{0x1E89,0x1E88,UNI_UPPER},
+{0x1E89,0x1E88,UNI_LOWER},
+{0x1E8B,0x1E8A,UNI_UPPER},
+{0x1E8B,0x1E8A,UNI_LOWER},
+{0x1E8D,0x1E8C,UNI_UPPER},
+{0x1E8D,0x1E8C,UNI_LOWER},
+{0x1E8F,0x1E8E,UNI_UPPER},
+{0x1E8F,0x1E8E,UNI_LOWER},
+{0x1E91,0x1E90,UNI_UPPER},
+{0x1E91,0x1E90,UNI_LOWER},
+{0x1E93,0x1E92,UNI_UPPER},
+{0x1E93,0x1E92,UNI_LOWER},
+{0x1E95,0x1E94,UNI_UPPER},
+{0x1E95,0x1E94,UNI_LOWER},
+{0x1E96,0x1E96,UNI_LOWER},
+{0x1E97,0x1E97,UNI_LOWER},
+{0x1E98,0x1E98,UNI_LOWER},
+{0x1E99,0x1E99,UNI_LOWER},
+{0x1E9A,0x1E9A,UNI_LOWER},
+{0x1E9B,0x1E60,UNI_LOWER},
+{0x1E9C,0x1E9C,0},
+{0x1E9D,0x1E9D,0},
+{0x1E9E,0x1E9E,0},
+{0x1E9F,0x1E9F,0},
+{0x1EA1,0x1EA0,UNI_UPPER},
+{0x1EA1,0x1EA0,UNI_LOWER},
+{0x1EA3,0x1EA2,UNI_UPPER},
+{0x1EA3,0x1EA2,UNI_LOWER},
+{0x1EA5,0x1EA4,UNI_UPPER},
+{0x1EA5,0x1EA4,UNI_LOWER},
+{0x1EA7,0x1EA6,UNI_UPPER},
+{0x1EA7,0x1EA6,UNI_LOWER},
+{0x1EA9,0x1EA8,UNI_UPPER},
+{0x1EA9,0x1EA8,UNI_LOWER},
+{0x1EAB,0x1EAA,UNI_UPPER},
+{0x1EAB,0x1EAA,UNI_LOWER},
+{0x1EAD,0x1EAC,UNI_UPPER},
+{0x1EAD,0x1EAC,UNI_LOWER},
+{0x1EAF,0x1EAE,UNI_UPPER},
+{0x1EAF,0x1EAE,UNI_LOWER},
+{0x1EB1,0x1EB0,UNI_UPPER},
+{0x1EB1,0x1EB0,UNI_LOWER},
+{0x1EB3,0x1EB2,UNI_UPPER},
+{0x1EB3,0x1EB2,UNI_LOWER},
+{0x1EB5,0x1EB4,UNI_UPPER},
+{0x1EB5,0x1EB4,UNI_LOWER},
+{0x1EB7,0x1EB6,UNI_UPPER},
+{0x1EB7,0x1EB6,UNI_LOWER},
+{0x1EB9,0x1EB8,UNI_UPPER},
+{0x1EB9,0x1EB8,UNI_LOWER},
+{0x1EBB,0x1EBA,UNI_UPPER},
+{0x1EBB,0x1EBA,UNI_LOWER},
+{0x1EBD,0x1EBC,UNI_UPPER},
+{0x1EBD,0x1EBC,UNI_LOWER},
+{0x1EBF,0x1EBE,UNI_UPPER},
+{0x1EBF,0x1EBE,UNI_LOWER},
+{0x1EC1,0x1EC0,UNI_UPPER},
+{0x1EC1,0x1EC0,UNI_LOWER},
+{0x1EC3,0x1EC2,UNI_UPPER},
+{0x1EC3,0x1EC2,UNI_LOWER},
+{0x1EC5,0x1EC4,UNI_UPPER},
+{0x1EC5,0x1EC4,UNI_LOWER},
+{0x1EC7,0x1EC6,UNI_UPPER},
+{0x1EC7,0x1EC6,UNI_LOWER},
+{0x1EC9,0x1EC8,UNI_UPPER},
+{0x1EC9,0x1EC8,UNI_LOWER},
+{0x1ECB,0x1ECA,UNI_UPPER},
+{0x1ECB,0x1ECA,UNI_LOWER},
+{0x1ECD,0x1ECC,UNI_UPPER},
+{0x1ECD,0x1ECC,UNI_LOWER},
+{0x1ECF,0x1ECE,UNI_UPPER},
+{0x1ECF,0x1ECE,UNI_LOWER},
+{0x1ED1,0x1ED0,UNI_UPPER},
+{0x1ED1,0x1ED0,UNI_LOWER},
+{0x1ED3,0x1ED2,UNI_UPPER},
+{0x1ED3,0x1ED2,UNI_LOWER},
+{0x1ED5,0x1ED4,UNI_UPPER},
+{0x1ED5,0x1ED4,UNI_LOWER},
+{0x1ED7,0x1ED6,UNI_UPPER},
+{0x1ED7,0x1ED6,UNI_LOWER},
+{0x1ED9,0x1ED8,UNI_UPPER},
+{0x1ED9,0x1ED8,UNI_LOWER},
+{0x1EDB,0x1EDA,UNI_UPPER},
+{0x1EDB,0x1EDA,UNI_LOWER},
+{0x1EDD,0x1EDC,UNI_UPPER},
+{0x1EDD,0x1EDC,UNI_LOWER},
+{0x1EDF,0x1EDE,UNI_UPPER},
+{0x1EDF,0x1EDE,UNI_LOWER},
+{0x1EE1,0x1EE0,UNI_UPPER},
+{0x1EE1,0x1EE0,UNI_LOWER},
+{0x1EE3,0x1EE2,UNI_UPPER},
+{0x1EE3,0x1EE2,UNI_LOWER},
+{0x1EE5,0x1EE4,UNI_UPPER},
+{0x1EE5,0x1EE4,UNI_LOWER},
+{0x1EE7,0x1EE6,UNI_UPPER},
+{0x1EE7,0x1EE6,UNI_LOWER},
+{0x1EE9,0x1EE8,UNI_UPPER},
+{0x1EE9,0x1EE8,UNI_LOWER},
+{0x1EEB,0x1EEA,UNI_UPPER},
+{0x1EEB,0x1EEA,UNI_LOWER},
+{0x1EED,0x1EEC,UNI_UPPER},
+{0x1EED,0x1EEC,UNI_LOWER},
+{0x1EEF,0x1EEE,UNI_UPPER},
+{0x1EEF,0x1EEE,UNI_LOWER},
+{0x1EF1,0x1EF0,UNI_UPPER},
+{0x1EF1,0x1EF0,UNI_LOWER},
+{0x1EF3,0x1EF2,UNI_UPPER},
+{0x1EF3,0x1EF2,UNI_LOWER},
+{0x1EF5,0x1EF4,UNI_UPPER},
+{0x1EF5,0x1EF4,UNI_LOWER},
+{0x1EF7,0x1EF6,UNI_UPPER},
+{0x1EF7,0x1EF6,UNI_LOWER},
+{0x1EF9,0x1EF8,UNI_UPPER},
+{0x1EF9,0x1EF8,UNI_LOWER},
+{0x1EFA,0x1EFA,0},
+{0x1EFB,0x1EFB,0},
+{0x1EFC,0x1EFC,0},
+{0x1EFD,0x1EFD,0},
+{0x1EFE,0x1EFE,0},
+{0x1EFF,0x1EFF,0},
+{0x1F00,0x1F08,UNI_LOWER},
+{0x1F01,0x1F09,UNI_LOWER},
+{0x1F02,0x1F0A,UNI_LOWER},
+{0x1F03,0x1F0B,UNI_LOWER},
+{0x1F04,0x1F0C,UNI_LOWER},
+{0x1F05,0x1F0D,UNI_LOWER},
+{0x1F06,0x1F0E,UNI_LOWER},
+{0x1F07,0x1F0F,UNI_LOWER},
+{0x1F00,0x1F08,UNI_UPPER},
+{0x1F01,0x1F09,UNI_UPPER},
+{0x1F02,0x1F0A,UNI_UPPER},
+{0x1F03,0x1F0B,UNI_UPPER},
+{0x1F04,0x1F0C,UNI_UPPER},
+{0x1F05,0x1F0D,UNI_UPPER},
+{0x1F06,0x1F0E,UNI_UPPER},
+{0x1F07,0x1F0F,UNI_UPPER},
+{0x1F10,0x1F18,UNI_LOWER},
+{0x1F11,0x1F19,UNI_LOWER},
+{0x1F12,0x1F1A,UNI_LOWER},
+{0x1F13,0x1F1B,UNI_LOWER},
+{0x1F14,0x1F1C,UNI_LOWER},
+{0x1F15,0x1F1D,UNI_LOWER},
+{0x1F16,0x1F16,0},
+{0x1F17,0x1F17,0},
+{0x1F10,0x1F18,UNI_UPPER},
+{0x1F11,0x1F19,UNI_UPPER},
+{0x1F12,0x1F1A,UNI_UPPER},
+{0x1F13,0x1F1B,UNI_UPPER},
+{0x1F14,0x1F1C,UNI_UPPER},
+{0x1F15,0x1F1D,UNI_UPPER},
+{0x1F1E,0x1F1E,0},
+{0x1F1F,0x1F1F,0},
+{0x1F20,0x1F28,UNI_LOWER},
+{0x1F21,0x1F29,UNI_LOWER},
+{0x1F22,0x1F2A,UNI_LOWER},
+{0x1F23,0x1F2B,UNI_LOWER},
+{0x1F24,0x1F2C,UNI_LOWER},
+{0x1F25,0x1F2D,UNI_LOWER},
+{0x1F26,0x1F2E,UNI_LOWER},
+{0x1F27,0x1F2F,UNI_LOWER},
+{0x1F20,0x1F28,UNI_UPPER},
+{0x1F21,0x1F29,UNI_UPPER},
+{0x1F22,0x1F2A,UNI_UPPER},
+{0x1F23,0x1F2B,UNI_UPPER},
+{0x1F24,0x1F2C,UNI_UPPER},
+{0x1F25,0x1F2D,UNI_UPPER},
+{0x1F26,0x1F2E,UNI_UPPER},
+{0x1F27,0x1F2F,UNI_UPPER},
+{0x1F30,0x1F38,UNI_LOWER},
+{0x1F31,0x1F39,UNI_LOWER},
+{0x1F32,0x1F3A,UNI_LOWER},
+{0x1F33,0x1F3B,UNI_LOWER},
+{0x1F34,0x1F3C,UNI_LOWER},
+{0x1F35,0x1F3D,UNI_LOWER},
+{0x1F36,0x1F3E,UNI_LOWER},
+{0x1F37,0x1F3F,UNI_LOWER},
+{0x1F30,0x1F38,UNI_UPPER},
+{0x1F31,0x1F39,UNI_UPPER},
+{0x1F32,0x1F3A,UNI_UPPER},
+{0x1F33,0x1F3B,UNI_UPPER},
+{0x1F34,0x1F3C,UNI_UPPER},
+{0x1F35,0x1F3D,UNI_UPPER},
+{0x1F36,0x1F3E,UNI_UPPER},
+{0x1F37,0x1F3F,UNI_UPPER},
+{0x1F40,0x1F48,UNI_LOWER},
+{0x1F41,0x1F49,UNI_LOWER},
+{0x1F42,0x1F4A,UNI_LOWER},
+{0x1F43,0x1F4B,UNI_LOWER},
+{0x1F44,0x1F4C,UNI_LOWER},
+{0x1F45,0x1F4D,UNI_LOWER},
+{0x1F46,0x1F46,0},
+{0x1F47,0x1F47,0},
+{0x1F40,0x1F48,UNI_UPPER},
+{0x1F41,0x1F49,UNI_UPPER},
+{0x1F42,0x1F4A,UNI_UPPER},
+{0x1F43,0x1F4B,UNI_UPPER},
+{0x1F44,0x1F4C,UNI_UPPER},
+{0x1F45,0x1F4D,UNI_UPPER},
+{0x1F4E,0x1F4E,0},
+{0x1F4F,0x1F4F,0},
+{0x1F50,0x1F50,UNI_LOWER},
+{0x1F51,0x1F59,UNI_LOWER},
+{0x1F52,0x1F52,UNI_LOWER},
+{0x1F53,0x1F5B,UNI_LOWER},
+{0x1F54,0x1F54,UNI_LOWER},
+{0x1F55,0x1F5D,UNI_LOWER},
+{0x1F56,0x1F56,UNI_LOWER},
+{0x1F57,0x1F5F,UNI_LOWER},
+{0x1F58,0x1F58,0},
+{0x1F51,0x1F59,UNI_UPPER},
+{0x1F5A,0x1F5A,0},
+{0x1F53,0x1F5B,UNI_UPPER},
+{0x1F5C,0x1F5C,0},
+{0x1F55,0x1F5D,UNI_UPPER},
+{0x1F5E,0x1F5E,0},
+{0x1F57,0x1F5F,UNI_UPPER},
+{0x1F60,0x1F68,UNI_LOWER},
+{0x1F61,0x1F69,UNI_LOWER},
+{0x1F62,0x1F6A,UNI_LOWER},
+{0x1F63,0x1F6B,UNI_LOWER},
+{0x1F64,0x1F6C,UNI_LOWER},
+{0x1F65,0x1F6D,UNI_LOWER},
+{0x1F66,0x1F6E,UNI_LOWER},
+{0x1F67,0x1F6F,UNI_LOWER},
+{0x1F60,0x1F68,UNI_UPPER},
+{0x1F61,0x1F69,UNI_UPPER},
+{0x1F62,0x1F6A,UNI_UPPER},
+{0x1F63,0x1F6B,UNI_UPPER},
+{0x1F64,0x1F6C,UNI_UPPER},
+{0x1F65,0x1F6D,UNI_UPPER},
+{0x1F66,0x1F6E,UNI_UPPER},
+{0x1F67,0x1F6F,UNI_UPPER},
+{0x1F70,0x1FBA,UNI_LOWER},
+{0x1F71,0x1FBB,UNI_LOWER},
+{0x1F72,0x1FC8,UNI_LOWER},
+{0x1F73,0x1FC9,UNI_LOWER},
+{0x1F74,0x1FCA,UNI_LOWER},
+{0x1F75,0x1FCB,UNI_LOWER},
+{0x1F76,0x1FDA,UNI_LOWER},
+{0x1F77,0x1FDB,UNI_LOWER},
+{0x1F78,0x1FF8,UNI_LOWER},
+{0x1F79,0x1FF9,UNI_LOWER},
+{0x1F7A,0x1FEA,UNI_LOWER},
+{0x1F7B,0x1FEB,UNI_LOWER},
+{0x1F7C,0x1FFA,UNI_LOWER},
+{0x1F7D,0x1FFB,UNI_LOWER},
+{0x1F7E,0x1F7E,0},
+{0x1F7F,0x1F7F,0},
+{0x1F80,0x1F88,UNI_LOWER},
+{0x1F81,0x1F89,UNI_LOWER},
+{0x1F82,0x1F8A,UNI_LOWER},
+{0x1F83,0x1F8B,UNI_LOWER},
+{0x1F84,0x1F8C,UNI_LOWER},
+{0x1F85,0x1F8D,UNI_LOWER},
+{0x1F86,0x1F8E,UNI_LOWER},
+{0x1F87,0x1F8F,UNI_LOWER},
+{0x1F80,0x1F88,0},
+{0x1F81,0x1F89,0},
+{0x1F82,0x1F8A,0},
+{0x1F83,0x1F8B,0},
+{0x1F84,0x1F8C,0},
+{0x1F85,0x1F8D,0},
+{0x1F86,0x1F8E,0},
+{0x1F87,0x1F8F,0},
+{0x1F90,0x1F98,UNI_LOWER},
+{0x1F91,0x1F99,UNI_LOWER},
+{0x1F92,0x1F9A,UNI_LOWER},
+{0x1F93,0x1F9B,UNI_LOWER},
+{0x1F94,0x1F9C,UNI_LOWER},
+{0x1F95,0x1F9D,UNI_LOWER},
+{0x1F96,0x1F9E,UNI_LOWER},
+{0x1F97,0x1F9F,UNI_LOWER},
+{0x1F90,0x1F98,0},
+{0x1F91,0x1F99,0},
+{0x1F92,0x1F9A,0},
+{0x1F93,0x1F9B,0},
+{0x1F94,0x1F9C,0},
+{0x1F95,0x1F9D,0},
+{0x1F96,0x1F9E,0},
+{0x1F97,0x1F9F,0},
+{0x1FA0,0x1FA8,UNI_LOWER},
+{0x1FA1,0x1FA9,UNI_LOWER},
+{0x1FA2,0x1FAA,UNI_LOWER},
+{0x1FA3,0x1FAB,UNI_LOWER},
+{0x1FA4,0x1FAC,UNI_LOWER},
+{0x1FA5,0x1FAD,UNI_LOWER},
+{0x1FA6,0x1FAE,UNI_LOWER},
+{0x1FA7,0x1FAF,UNI_LOWER},
+{0x1FA0,0x1FA8,0},
+{0x1FA1,0x1FA9,0},
+{0x1FA2,0x1FAA,0},
+{0x1FA3,0x1FAB,0},
+{0x1FA4,0x1FAC,0},
+{0x1FA5,0x1FAD,0},
+{0x1FA6,0x1FAE,0},
+{0x1FA7,0x1FAF,0},
+{0x1FB0,0x1FB8,UNI_LOWER},
+{0x1FB1,0x1FB9,UNI_LOWER},
+{0x1FB2,0x1FB2,UNI_LOWER},
+{0x1FB3,0x1FBC,UNI_LOWER},
+{0x1FB4,0x1FB4,UNI_LOWER},
+{0x1FB5,0x1FB5,0},
+{0x1FB6,0x1FB6,UNI_LOWER},
+{0x1FB7,0x1FB7,UNI_LOWER},
+{0x1FB0,0x1FB8,UNI_UPPER},
+{0x1FB1,0x1FB9,UNI_UPPER},
+{0x1F70,0x1FBA,UNI_UPPER},
+{0x1F71,0x1FBB,UNI_UPPER},
+{0x1FB3,0x1FBC,0},
+{0x1FBD,0x1FBD,0},
+{0x1FBE,0x0399,UNI_LOWER},
+{0x1FBF,0x1FBF,0},
+{0x1FC0,0x1FC0,0},
+{0x1FC1,0x1FC1,0},
+{0x1FC2,0x1FC2,UNI_LOWER},
+{0x1FC3,0x1FCC,UNI_LOWER},
+{0x1FC4,0x1FC4,UNI_LOWER},
+{0x1FC5,0x1FC5,0},
+{0x1FC6,0x1FC6,UNI_LOWER},
+{0x1FC7,0x1FC7,UNI_LOWER},
+{0x1F72,0x1FC8,UNI_UPPER},
+{0x1F73,0x1FC9,UNI_UPPER},
+{0x1F74,0x1FCA,UNI_UPPER},
+{0x1F75,0x1FCB,UNI_UPPER},
+{0x1FC3,0x1FCC,0},
+{0x1FCD,0x1FCD,0},
+{0x1FCE,0x1FCE,0},
+{0x1FCF,0x1FCF,0},
+{0x1FD0,0x1FD8,UNI_LOWER},
+{0x1FD1,0x1FD9,UNI_LOWER},
+{0x1FD2,0x1FD2,UNI_LOWER},
+{0x1FD3,0x1FD3,UNI_LOWER},
+{0x1FD4,0x1FD4,0},
+{0x1FD5,0x1FD5,0},
+{0x1FD6,0x1FD6,UNI_LOWER},
+{0x1FD7,0x1FD7,UNI_LOWER},
+{0x1FD0,0x1FD8,UNI_UPPER},
+{0x1FD1,0x1FD9,UNI_UPPER},
+{0x1F76,0x1FDA,UNI_UPPER},
+{0x1F77,0x1FDB,UNI_UPPER},
+{0x1FDC,0x1FDC,0},
+{0x1FDD,0x1FDD,0},
+{0x1FDE,0x1FDE,0},
+{0x1FDF,0x1FDF,0},
+{0x1FE0,0x1FE8,UNI_LOWER},
+{0x1FE1,0x1FE9,UNI_LOWER},
+{0x1FE2,0x1FE2,UNI_LOWER},
+{0x1FE3,0x1FE3,UNI_LOWER},
+{0x1FE4,0x1FE4,UNI_LOWER},
+{0x1FE5,0x1FEC,UNI_LOWER},
+{0x1FE6,0x1FE6,UNI_LOWER},
+{0x1FE7,0x1FE7,UNI_LOWER},
+{0x1FE0,0x1FE8,UNI_UPPER},
+{0x1FE1,0x1FE9,UNI_UPPER},
+{0x1F7A,0x1FEA,UNI_UPPER},
+{0x1F7B,0x1FEB,UNI_UPPER},
+{0x1FE5,0x1FEC,UNI_UPPER},
+{0x1FED,0x1FED,0},
+{0x1FEE,0x1FEE,0},
+{0x1FEF,0x1FEF,0},
+{0x1FF0,0x1FF0,0},
+{0x1FF1,0x1FF1,0},
+{0x1FF2,0x1FF2,UNI_LOWER},
+{0x1FF3,0x1FFC,UNI_LOWER},
+{0x1FF4,0x1FF4,UNI_LOWER},
+{0x1FF5,0x1FF5,0},
+{0x1FF6,0x1FF6,UNI_LOWER},
+{0x1FF7,0x1FF7,UNI_LOWER},
+{0x1F78,0x1FF8,UNI_UPPER},
+{0x1F79,0x1FF9,UNI_UPPER},
+{0x1F7C,0x1FFA,UNI_UPPER},
+{0x1F7D,0x1FFB,UNI_UPPER},
+{0x1FF3,0x1FFC,0},
+{0x1FFD,0x1FFD,0},
+{0x1FFE,0x1FFE,0},
+{0x1FFF,0x1FFF,0},
+{0x2000,0x2000,0},
+{0x2001,0x2001,0},
+{0x2002,0x2002,0},
+{0x2003,0x2003,0},
+{0x2004,0x2004,0},
+{0x2005,0x2005,0},
+{0x2006,0x2006,0},
+{0x2007,0x2007,0},
+{0x2008,0x2008,0},
+{0x2009,0x2009,0},
+{0x200A,0x200A,0},
+{0x200B,0x200B,0},
+{0x200C,0x200C,0},
+{0x200D,0x200D,0},
+{0x200E,0x200E,0},
+{0x200F,0x200F,0},
+{0x2010,0x2010,0},
+{0x2011,0x2011,0},
+{0x2012,0x2012,0},
+{0x2013,0x2013,0},
+{0x2014,0x2014,0},
+{0x2015,0x2015,0},
+{0x2016,0x2016,0},
+{0x2017,0x2017,0},
+{0x2018,0x2018,0},
+{0x2019,0x2019,0},
+{0x201A,0x201A,0},
+{0x201B,0x201B,0},
+{0x201C,0x201C,0},
+{0x201D,0x201D,0},
+{0x201E,0x201E,0},
+{0x201F,0x201F,0},
+{0x2020,0x2020,0},
+{0x2021,0x2021,0},
+{0x2022,0x2022,0},
+{0x2023,0x2023,0},
+{0x2024,0x2024,0},
+{0x2025,0x2025,0},
+{0x2026,0x2026,0},
+{0x2027,0x2027,0},
+{0x2028,0x2028,0},
+{0x2029,0x2029,0},
+{0x202A,0x202A,0},
+{0x202B,0x202B,0},
+{0x202C,0x202C,0},
+{0x202D,0x202D,0},
+{0x202E,0x202E,0},
+{0x202F,0x202F,0},
+{0x2030,0x2030,0},
+{0x2031,0x2031,0},
+{0x2032,0x2032,0},
+{0x2033,0x2033,0},
+{0x2034,0x2034,0},
+{0x2035,0x2035,0},
+{0x2036,0x2036,0},
+{0x2037,0x2037,0},
+{0x2038,0x2038,0},
+{0x2039,0x2039,0},
+{0x203A,0x203A,0},
+{0x203B,0x203B,0},
+{0x203C,0x203C,0},
+{0x203D,0x203D,0},
+{0x203E,0x203E,0},
+{0x203F,0x203F,0},
+{0x2040,0x2040,0},
+{0x2041,0x2041,0},
+{0x2042,0x2042,0},
+{0x2043,0x2043,0},
+{0x2044,0x2044,0},
+{0x2045,0x2045,0},
+{0x2046,0x2046,0},
+{0x2047,0x2047,0},
+{0x2048,0x2048,0},
+{0x2049,0x2049,0},
+{0x204A,0x204A,0},
+{0x204B,0x204B,0},
+{0x204C,0x204C,0},
+{0x204D,0x204D,0},
+{0x204E,0x204E,0},
+{0x204F,0x204F,0},
+{0x2050,0x2050,0},
+{0x2051,0x2051,0},
+{0x2052,0x2052,0},
+{0x2053,0x2053,0},
+{0x2054,0x2054,0},
+{0x2055,0x2055,0},
+{0x2056,0x2056,0},
+{0x2057,0x2057,0},
+{0x2058,0x2058,0},
+{0x2059,0x2059,0},
+{0x205A,0x205A,0},
+{0x205B,0x205B,0},
+{0x205C,0x205C,0},
+{0x205D,0x205D,0},
+{0x205E,0x205E,0},
+{0x205F,0x205F,0},
+{0x2060,0x2060,0},
+{0x2061,0x2061,0},
+{0x2062,0x2062,0},
+{0x2063,0x2063,0},
+{0x2064,0x2064,0},
+{0x2065,0x2065,0},
+{0x2066,0x2066,0},
+{0x2067,0x2067,0},
+{0x2068,0x2068,0},
+{0x2069,0x2069,0},
+{0x206A,0x206A,0},
+{0x206B,0x206B,0},
+{0x206C,0x206C,0},
+{0x206D,0x206D,0},
+{0x206E,0x206E,0},
+{0x206F,0x206F,0},
+{0x2070,0x2070,0},
+{0x2071,0x2071,0},
+{0x2072,0x2072,0},
+{0x2073,0x2073,0},
+{0x2074,0x2074,0},
+{0x2075,0x2075,0},
+{0x2076,0x2076,0},
+{0x2077,0x2077,0},
+{0x2078,0x2078,0},
+{0x2079,0x2079,0},
+{0x207A,0x207A,0},
+{0x207B,0x207B,0},
+{0x207C,0x207C,0},
+{0x207D,0x207D,0},
+{0x207E,0x207E,0},
+{0x207F,0x207F,UNI_LOWER},
+{0x2080,0x2080,0},
+{0x2081,0x2081,0},
+{0x2082,0x2082,0},
+{0x2083,0x2083,0},
+{0x2084,0x2084,0},
+{0x2085,0x2085,0},
+{0x2086,0x2086,0},
+{0x2087,0x2087,0},
+{0x2088,0x2088,0},
+{0x2089,0x2089,0},
+{0x208A,0x208A,0},
+{0x208B,0x208B,0},
+{0x208C,0x208C,0},
+{0x208D,0x208D,0},
+{0x208E,0x208E,0},
+{0x208F,0x208F,0},
+{0x2090,0x2090,0},
+{0x2091,0x2091,0},
+{0x2092,0x2092,0},
+{0x2093,0x2093,0},
+{0x2094,0x2094,0},
+{0x2095,0x2095,0},
+{0x2096,0x2096,0},
+{0x2097,0x2097,0},
+{0x2098,0x2098,0},
+{0x2099,0x2099,0},
+{0x209A,0x209A,0},
+{0x209B,0x209B,0},
+{0x209C,0x209C,0},
+{0x209D,0x209D,0},
+{0x209E,0x209E,0},
+{0x209F,0x209F,0},
+{0x20A0,0x20A0,0},
+{0x20A1,0x20A1,0},
+{0x20A2,0x20A2,0},
+{0x20A3,0x20A3,0},
+{0x20A4,0x20A4,0},
+{0x20A5,0x20A5,0},
+{0x20A6,0x20A6,0},
+{0x20A7,0x20A7,0},
+{0x20A8,0x20A8,0},
+{0x20A9,0x20A9,0},
+{0x20AA,0x20AA,0},
+{0x20AB,0x20AB,0},
+{0x20AC,0x20AC,0},
+{0x20AD,0x20AD,0},
+{0x20AE,0x20AE,0},
+{0x20AF,0x20AF,0},
+{0x20B0,0x20B0,0},
+{0x20B1,0x20B1,0},
+{0x20B2,0x20B2,0},
+{0x20B3,0x20B3,0},
+{0x20B4,0x20B4,0},
+{0x20B5,0x20B5,0},
+{0x20B6,0x20B6,0},
+{0x20B7,0x20B7,0},
+{0x20B8,0x20B8,0},
+{0x20B9,0x20B9,0},
+{0x20BA,0x20BA,0},
+{0x20BB,0x20BB,0},
+{0x20BC,0x20BC,0},
+{0x20BD,0x20BD,0},
+{0x20BE,0x20BE,0},
+{0x20BF,0x20BF,0},
+{0x20C0,0x20C0,0},
+{0x20C1,0x20C1,0},
+{0x20C2,0x20C2,0},
+{0x20C3,0x20C3,0},
+{0x20C4,0x20C4,0},
+{0x20C5,0x20C5,0},
+{0x20C6,0x20C6,0},
+{0x20C7,0x20C7,0},
+{0x20C8,0x20C8,0},
+{0x20C9,0x20C9,0},
+{0x20CA,0x20CA,0},
+{0x20CB,0x20CB,0},
+{0x20CC,0x20CC,0},
+{0x20CD,0x20CD,0},
+{0x20CE,0x20CE,0},
+{0x20CF,0x20CF,0},
+{0x20D0,0x20D0,0},
+{0x20D1,0x20D1,0},
+{0x20D2,0x20D2,0},
+{0x20D3,0x20D3,0},
+{0x20D4,0x20D4,0},
+{0x20D5,0x20D5,0},
+{0x20D6,0x20D6,0},
+{0x20D7,0x20D7,0},
+{0x20D8,0x20D8,0},
+{0x20D9,0x20D9,0},
+{0x20DA,0x20DA,0},
+{0x20DB,0x20DB,0},
+{0x20DC,0x20DC,0},
+{0x20DD,0x20DD,0},
+{0x20DE,0x20DE,0},
+{0x20DF,0x20DF,0},
+{0x20E0,0x20E0,0},
+{0x20E1,0x20E1,0},
+{0x20E2,0x20E2,0},
+{0x20E3,0x20E3,0},
+{0x20E4,0x20E4,0},
+{0x20E5,0x20E5,0},
+{0x20E6,0x20E6,0},
+{0x20E7,0x20E7,0},
+{0x20E8,0x20E8,0},
+{0x20E9,0x20E9,0},
+{0x20EA,0x20EA,0},
+{0x20EB,0x20EB,0},
+{0x20EC,0x20EC,0},
+{0x20ED,0x20ED,0},
+{0x20EE,0x20EE,0},
+{0x20EF,0x20EF,0},
+{0x20F0,0x20F0,0},
+{0x20F1,0x20F1,0},
+{0x20F2,0x20F2,0},
+{0x20F3,0x20F3,0},
+{0x20F4,0x20F4,0},
+{0x20F5,0x20F5,0},
+{0x20F6,0x20F6,0},
+{0x20F7,0x20F7,0},
+{0x20F8,0x20F8,0},
+{0x20F9,0x20F9,0},
+{0x20FA,0x20FA,0},
+{0x20FB,0x20FB,0},
+{0x20FC,0x20FC,0},
+{0x20FD,0x20FD,0},
+{0x20FE,0x20FE,0},
+{0x20FF,0x20FF,0},
+{0x2100,0x2100,0},
+{0x2101,0x2101,0},
+{0x2102,0x2102,UNI_UPPER},
+{0x2103,0x2103,0},
+{0x2104,0x2104,0},
+{0x2105,0x2105,0},
+{0x2106,0x2106,0},
+{0x2107,0x2107,UNI_UPPER},
+{0x2108,0x2108,0},
+{0x2109,0x2109,0},
+{0x210A,0x210A,UNI_LOWER},
+{0x210B,0x210B,UNI_UPPER},
+{0x210C,0x210C,UNI_UPPER},
+{0x210D,0x210D,UNI_UPPER},
+{0x210E,0x210E,UNI_LOWER},
+{0x210F,0x210F,UNI_LOWER},
+{0x2110,0x2110,UNI_UPPER},
+{0x2111,0x2111,UNI_UPPER},
+{0x2112,0x2112,UNI_UPPER},
+{0x2113,0x2113,UNI_LOWER},
+{0x2114,0x2114,0},
+{0x2115,0x2115,UNI_UPPER},
+{0x2116,0x2116,0},
+{0x2117,0x2117,0},
+{0x2118,0x2118,0},
+{0x2119,0x2119,UNI_UPPER},
+{0x211A,0x211A,UNI_UPPER},
+{0x211B,0x211B,UNI_UPPER},
+{0x211C,0x211C,UNI_UPPER},
+{0x211D,0x211D,UNI_UPPER},
+{0x211E,0x211E,0},
+{0x211F,0x211F,0},
+{0x2120,0x2120,0},
+{0x2121,0x2121,0},
+{0x2122,0x2122,0},
+{0x2123,0x2123,0},
+{0x2124,0x2124,UNI_UPPER},
+{0x2125,0x2125,0},
+{0x03C9,0x2126,UNI_UPPER},
+{0x2127,0x2127,0},
+{0x2128,0x2128,UNI_UPPER},
+{0x2129,0x2129,0},
+{0x006B,0x212A,UNI_UPPER},
+{0x00E5,0x212B,UNI_UPPER},
+{0x212C,0x212C,UNI_UPPER},
+{0x212D,0x212D,UNI_UPPER},
+{0x212E,0x212E,0},
+{0x212F,0x212F,UNI_LOWER},
+{0x2130,0x2130,UNI_UPPER},
+{0x2131,0x2131,UNI_UPPER},
+{0x2132,0x2132,0},
+{0x2133,0x2133,UNI_UPPER},
+{0x2134,0x2134,UNI_LOWER},
+{0x2135,0x2135,0},
+{0x2136,0x2136,0},
+{0x2137,0x2137,0},
+{0x2138,0x2138,0},
+{0x2139,0x2139,UNI_LOWER},
+{0x213A,0x213A,0},
+{0x213B,0x213B,0},
+{0x213C,0x213C,0},
+{0x213D,0x213D,0},
+{0x213E,0x213E,0},
+{0x213F,0x213F,0},
+{0x2140,0x2140,0},
+{0x2141,0x2141,0},
+{0x2142,0x2142,0},
+{0x2143,0x2143,0},
+{0x2144,0x2144,0},
+{0x2145,0x2145,0},
+{0x2146,0x2146,0},
+{0x2147,0x2147,0},
+{0x2148,0x2148,0},
+{0x2149,0x2149,0},
+{0x214A,0x214A,0},
+{0x214B,0x214B,0},
+{0x214C,0x214C,0},
+{0x214D,0x214D,0},
+{0x214E,0x214E,0},
+{0x214F,0x214F,0},
+{0x2150,0x2150,0},
+{0x2151,0x2151,0},
+{0x2152,0x2152,0},
+{0x2153,0x2153,0},
+{0x2154,0x2154,0},
+{0x2155,0x2155,0},
+{0x2156,0x2156,0},
+{0x2157,0x2157,0},
+{0x2158,0x2158,0},
+{0x2159,0x2159,0},
+{0x215A,0x215A,0},
+{0x215B,0x215B,0},
+{0x215C,0x215C,0},
+{0x215D,0x215D,0},
+{0x215E,0x215E,0},
+{0x215F,0x215F,0},
+{0x2170,0x2160,0},
+{0x2171,0x2161,0},
+{0x2172,0x2162,0},
+{0x2173,0x2163,0},
+{0x2174,0x2164,0},
+{0x2175,0x2165,0},
+{0x2176,0x2166,0},
+{0x2177,0x2167,0},
+{0x2178,0x2168,0},
+{0x2179,0x2169,0},
+{0x217A,0x216A,0},
+{0x217B,0x216B,0},
+{0x217C,0x216C,0},
+{0x217D,0x216D,0},
+{0x217E,0x216E,0},
+{0x217F,0x216F,0},
+{0x2170,0x2160,0},
+{0x2171,0x2161,0},
+{0x2172,0x2162,0},
+{0x2173,0x2163,0},
+{0x2174,0x2164,0},
+{0x2175,0x2165,0},
+{0x2176,0x2166,0},
+{0x2177,0x2167,0},
+{0x2178,0x2168,0},
+{0x2179,0x2169,0},
+{0x217A,0x216A,0},
+{0x217B,0x216B,0},
+{0x217C,0x216C,0},
+{0x217D,0x216D,0},
+{0x217E,0x216E,0},
+{0x217F,0x216F,0},
+{0x2180,0x2180,0},
+{0x2181,0x2181,0},
+{0x2182,0x2182,0},
+{0x2183,0x2183,0},
+{0x2184,0x2184,0},
+{0x2185,0x2185,0},
+{0x2186,0x2186,0},
+{0x2187,0x2187,0},
+{0x2188,0x2188,0},
+{0x2189,0x2189,0},
+{0x218A,0x218A,0},
+{0x218B,0x218B,0},
+{0x218C,0x218C,0},
+{0x218D,0x218D,0},
+{0x218E,0x218E,0},
+{0x218F,0x218F,0},
+{0x2190,0x2190,0},
+{0x2191,0x2191,0},
+{0x2192,0x2192,0},
+{0x2193,0x2193,0},
+{0x2194,0x2194,0},
+{0x2195,0x2195,0},
+{0x2196,0x2196,0},
+{0x2197,0x2197,0},
+{0x2198,0x2198,0},
+{0x2199,0x2199,0},
+{0x219A,0x219A,0},
+{0x219B,0x219B,0},
+{0x219C,0x219C,0},
+{0x219D,0x219D,0},
+{0x219E,0x219E,0},
+{0x219F,0x219F,0},
+{0x21A0,0x21A0,0},
+{0x21A1,0x21A1,0},
+{0x21A2,0x21A2,0},
+{0x21A3,0x21A3,0},
+{0x21A4,0x21A4,0},
+{0x21A5,0x21A5,0},
+{0x21A6,0x21A6,0},
+{0x21A7,0x21A7,0},
+{0x21A8,0x21A8,0},
+{0x21A9,0x21A9,0},
+{0x21AA,0x21AA,0},
+{0x21AB,0x21AB,0},
+{0x21AC,0x21AC,0},
+{0x21AD,0x21AD,0},
+{0x21AE,0x21AE,0},
+{0x21AF,0x21AF,0},
+{0x21B0,0x21B0,0},
+{0x21B1,0x21B1,0},
+{0x21B2,0x21B2,0},
+{0x21B3,0x21B3,0},
+{0x21B4,0x21B4,0},
+{0x21B5,0x21B5,0},
+{0x21B6,0x21B6,0},
+{0x21B7,0x21B7,0},
+{0x21B8,0x21B8,0},
+{0x21B9,0x21B9,0},
+{0x21BA,0x21BA,0},
+{0x21BB,0x21BB,0},
+{0x21BC,0x21BC,0},
+{0x21BD,0x21BD,0},
+{0x21BE,0x21BE,0},
+{0x21BF,0x21BF,0},
+{0x21C0,0x21C0,0},
+{0x21C1,0x21C1,0},
+{0x21C2,0x21C2,0},
+{0x21C3,0x21C3,0},
+{0x21C4,0x21C4,0},
+{0x21C5,0x21C5,0},
+{0x21C6,0x21C6,0},
+{0x21C7,0x21C7,0},
+{0x21C8,0x21C8,0},
+{0x21C9,0x21C9,0},
+{0x21CA,0x21CA,0},
+{0x21CB,0x21CB,0},
+{0x21CC,0x21CC,0},
+{0x21CD,0x21CD,0},
+{0x21CE,0x21CE,0},
+{0x21CF,0x21CF,0},
+{0x21D0,0x21D0,0},
+{0x21D1,0x21D1,0},
+{0x21D2,0x21D2,0},
+{0x21D3,0x21D3,0},
+{0x21D4,0x21D4,0},
+{0x21D5,0x21D5,0},
+{0x21D6,0x21D6,0},
+{0x21D7,0x21D7,0},
+{0x21D8,0x21D8,0},
+{0x21D9,0x21D9,0},
+{0x21DA,0x21DA,0},
+{0x21DB,0x21DB,0},
+{0x21DC,0x21DC,0},
+{0x21DD,0x21DD,0},
+{0x21DE,0x21DE,0},
+{0x21DF,0x21DF,0},
+{0x21E0,0x21E0,0},
+{0x21E1,0x21E1,0},
+{0x21E2,0x21E2,0},
+{0x21E3,0x21E3,0},
+{0x21E4,0x21E4,0},
+{0x21E5,0x21E5,0},
+{0x21E6,0x21E6,0},
+{0x21E7,0x21E7,0},
+{0x21E8,0x21E8,0},
+{0x21E9,0x21E9,0},
+{0x21EA,0x21EA,0},
+{0x21EB,0x21EB,0},
+{0x21EC,0x21EC,0},
+{0x21ED,0x21ED,0},
+{0x21EE,0x21EE,0},
+{0x21EF,0x21EF,0},
+{0x21F0,0x21F0,0},
+{0x21F1,0x21F1,0},
+{0x21F2,0x21F2,0},
+{0x21F3,0x21F3,0},
+{0x21F4,0x21F4,0},
+{0x21F5,0x21F5,0},
+{0x21F6,0x21F6,0},
+{0x21F7,0x21F7,0},
+{0x21F8,0x21F8,0},
+{0x21F9,0x21F9,0},
+{0x21FA,0x21FA,0},
+{0x21FB,0x21FB,0},
+{0x21FC,0x21FC,0},
+{0x21FD,0x21FD,0},
+{0x21FE,0x21FE,0},
+{0x21FF,0x21FF,0},
+{0x2200,0x2200,0},
+{0x2201,0x2201,0},
+{0x2202,0x2202,0},
+{0x2203,0x2203,0},
+{0x2204,0x2204,0},
+{0x2205,0x2205,0},
+{0x2206,0x2206,0},
+{0x2207,0x2207,0},
+{0x2208,0x2208,0},
+{0x2209,0x2209,0},
+{0x220A,0x220A,0},
+{0x220B,0x220B,0},
+{0x220C,0x220C,0},
+{0x220D,0x220D,0},
+{0x220E,0x220E,0},
+{0x220F,0x220F,0},
+{0x2210,0x2210,0},
+{0x2211,0x2211,0},
+{0x2212,0x2212,0},
+{0x2213,0x2213,0},
+{0x2214,0x2214,0},
+{0x2215,0x2215,0},
+{0x2216,0x2216,0},
+{0x2217,0x2217,0},
+{0x2218,0x2218,0},
+{0x2219,0x2219,0},
+{0x221A,0x221A,0},
+{0x221B,0x221B,0},
+{0x221C,0x221C,0},
+{0x221D,0x221D,0},
+{0x221E,0x221E,0},
+{0x221F,0x221F,0},
+{0x2220,0x2220,0},
+{0x2221,0x2221,0},
+{0x2222,0x2222,0},
+{0x2223,0x2223,0},
+{0x2224,0x2224,0},
+{0x2225,0x2225,0},
+{0x2226,0x2226,0},
+{0x2227,0x2227,0},
+{0x2228,0x2228,0},
+{0x2229,0x2229,0},
+{0x222A,0x222A,0},
+{0x222B,0x222B,0},
+{0x222C,0x222C,0},
+{0x222D,0x222D,0},
+{0x222E,0x222E,0},
+{0x222F,0x222F,0},
+{0x2230,0x2230,0},
+{0x2231,0x2231,0},
+{0x2232,0x2232,0},
+{0x2233,0x2233,0},
+{0x2234,0x2234,0},
+{0x2235,0x2235,0},
+{0x2236,0x2236,0},
+{0x2237,0x2237,0},
+{0x2238,0x2238,0},
+{0x2239,0x2239,0},
+{0x223A,0x223A,0},
+{0x223B,0x223B,0},
+{0x223C,0x223C,0},
+{0x223D,0x223D,0},
+{0x223E,0x223E,0},
+{0x223F,0x223F,0},
+{0x2240,0x2240,0},
+{0x2241,0x2241,0},
+{0x2242,0x2242,0},
+{0x2243,0x2243,0},
+{0x2244,0x2244,0},
+{0x2245,0x2245,0},
+{0x2246,0x2246,0},
+{0x2247,0x2247,0},
+{0x2248,0x2248,0},
+{0x2249,0x2249,0},
+{0x224A,0x224A,0},
+{0x224B,0x224B,0},
+{0x224C,0x224C,0},
+{0x224D,0x224D,0},
+{0x224E,0x224E,0},
+{0x224F,0x224F,0},
+{0x2250,0x2250,0},
+{0x2251,0x2251,0},
+{0x2252,0x2252,0},
+{0x2253,0x2253,0},
+{0x2254,0x2254,0},
+{0x2255,0x2255,0},
+{0x2256,0x2256,0},
+{0x2257,0x2257,0},
+{0x2258,0x2258,0},
+{0x2259,0x2259,0},
+{0x225A,0x225A,0},
+{0x225B,0x225B,0},
+{0x225C,0x225C,0},
+{0x225D,0x225D,0},
+{0x225E,0x225E,0},
+{0x225F,0x225F,0},
+{0x2260,0x2260,0},
+{0x2261,0x2261,0},
+{0x2262,0x2262,0},
+{0x2263,0x2263,0},
+{0x2264,0x2264,0},
+{0x2265,0x2265,0},
+{0x2266,0x2266,0},
+{0x2267,0x2267,0},
+{0x2268,0x2268,0},
+{0x2269,0x2269,0},
+{0x226A,0x226A,0},
+{0x226B,0x226B,0},
+{0x226C,0x226C,0},
+{0x226D,0x226D,0},
+{0x226E,0x226E,0},
+{0x226F,0x226F,0},
+{0x2270,0x2270,0},
+{0x2271,0x2271,0},
+{0x2272,0x2272,0},
+{0x2273,0x2273,0},
+{0x2274,0x2274,0},
+{0x2275,0x2275,0},
+{0x2276,0x2276,0},
+{0x2277,0x2277,0},
+{0x2278,0x2278,0},
+{0x2279,0x2279,0},
+{0x227A,0x227A,0},
+{0x227B,0x227B,0},
+{0x227C,0x227C,0},
+{0x227D,0x227D,0},
+{0x227E,0x227E,0},
+{0x227F,0x227F,0},
+{0x2280,0x2280,0},
+{0x2281,0x2281,0},
+{0x2282,0x2282,0},
+{0x2283,0x2283,0},
+{0x2284,0x2284,0},
+{0x2285,0x2285,0},
+{0x2286,0x2286,0},
+{0x2287,0x2287,0},
+{0x2288,0x2288,0},
+{0x2289,0x2289,0},
+{0x228A,0x228A,0},
+{0x228B,0x228B,0},
+{0x228C,0x228C,0},
+{0x228D,0x228D,0},
+{0x228E,0x228E,0},
+{0x228F,0x228F,0},
+{0x2290,0x2290,0},
+{0x2291,0x2291,0},
+{0x2292,0x2292,0},
+{0x2293,0x2293,0},
+{0x2294,0x2294,0},
+{0x2295,0x2295,0},
+{0x2296,0x2296,0},
+{0x2297,0x2297,0},
+{0x2298,0x2298,0},
+{0x2299,0x2299,0},
+{0x229A,0x229A,0},
+{0x229B,0x229B,0},
+{0x229C,0x229C,0},
+{0x229D,0x229D,0},
+{0x229E,0x229E,0},
+{0x229F,0x229F,0},
+{0x22A0,0x22A0,0},
+{0x22A1,0x22A1,0},
+{0x22A2,0x22A2,0},
+{0x22A3,0x22A3,0},
+{0x22A4,0x22A4,0},
+{0x22A5,0x22A5,0},
+{0x22A6,0x22A6,0},
+{0x22A7,0x22A7,0},
+{0x22A8,0x22A8,0},
+{0x22A9,0x22A9,0},
+{0x22AA,0x22AA,0},
+{0x22AB,0x22AB,0},
+{0x22AC,0x22AC,0},
+{0x22AD,0x22AD,0},
+{0x22AE,0x22AE,0},
+{0x22AF,0x22AF,0},
+{0x22B0,0x22B0,0},
+{0x22B1,0x22B1,0},
+{0x22B2,0x22B2,0},
+{0x22B3,0x22B3,0},
+{0x22B4,0x22B4,0},
+{0x22B5,0x22B5,0},
+{0x22B6,0x22B6,0},
+{0x22B7,0x22B7,0},
+{0x22B8,0x22B8,0},
+{0x22B9,0x22B9,0},
+{0x22BA,0x22BA,0},
+{0x22BB,0x22BB,0},
+{0x22BC,0x22BC,0},
+{0x22BD,0x22BD,0},
+{0x22BE,0x22BE,0},
+{0x22BF,0x22BF,0},
+{0x22C0,0x22C0,0},
+{0x22C1,0x22C1,0},
+{0x22C2,0x22C2,0},
+{0x22C3,0x22C3,0},
+{0x22C4,0x22C4,0},
+{0x22C5,0x22C5,0},
+{0x22C6,0x22C6,0},
+{0x22C7,0x22C7,0},
+{0x22C8,0x22C8,0},
+{0x22C9,0x22C9,0},
+{0x22CA,0x22CA,0},
+{0x22CB,0x22CB,0},
+{0x22CC,0x22CC,0},
+{0x22CD,0x22CD,0},
+{0x22CE,0x22CE,0},
+{0x22CF,0x22CF,0},
+{0x22D0,0x22D0,0},
+{0x22D1,0x22D1,0},
+{0x22D2,0x22D2,0},
+{0x22D3,0x22D3,0},
+{0x22D4,0x22D4,0},
+{0x22D5,0x22D5,0},
+{0x22D6,0x22D6,0},
+{0x22D7,0x22D7,0},
+{0x22D8,0x22D8,0},
+{0x22D9,0x22D9,0},
+{0x22DA,0x22DA,0},
+{0x22DB,0x22DB,0},
+{0x22DC,0x22DC,0},
+{0x22DD,0x22DD,0},
+{0x22DE,0x22DE,0},
+{0x22DF,0x22DF,0},
+{0x22E0,0x22E0,0},
+{0x22E1,0x22E1,0},
+{0x22E2,0x22E2,0},
+{0x22E3,0x22E3,0},
+{0x22E4,0x22E4,0},
+{0x22E5,0x22E5,0},
+{0x22E6,0x22E6,0},
+{0x22E7,0x22E7,0},
+{0x22E8,0x22E8,0},
+{0x22E9,0x22E9,0},
+{0x22EA,0x22EA,0},
+{0x22EB,0x22EB,0},
+{0x22EC,0x22EC,0},
+{0x22ED,0x22ED,0},
+{0x22EE,0x22EE,0},
+{0x22EF,0x22EF,0},
+{0x22F0,0x22F0,0},
+{0x22F1,0x22F1,0},
+{0x22F2,0x22F2,0},
+{0x22F3,0x22F3,0},
+{0x22F4,0x22F4,0},
+{0x22F5,0x22F5,0},
+{0x22F6,0x22F6,0},
+{0x22F7,0x22F7,0},
+{0x22F8,0x22F8,0},
+{0x22F9,0x22F9,0},
+{0x22FA,0x22FA,0},
+{0x22FB,0x22FB,0},
+{0x22FC,0x22FC,0},
+{0x22FD,0x22FD,0},
+{0x22FE,0x22FE,0},
+{0x22FF,0x22FF,0},
+{0x2300,0x2300,0},
+{0x2301,0x2301,0},
+{0x2302,0x2302,0},
+{0x2303,0x2303,0},
+{0x2304,0x2304,0},
+{0x2305,0x2305,0},
+{0x2306,0x2306,0},
+{0x2307,0x2307,0},
+{0x2308,0x2308,0},
+{0x2309,0x2309,0},
+{0x230A,0x230A,0},
+{0x230B,0x230B,0},
+{0x230C,0x230C,0},
+{0x230D,0x230D,0},
+{0x230E,0x230E,0},
+{0x230F,0x230F,0},
+{0x2310,0x2310,0},
+{0x2311,0x2311,0},
+{0x2312,0x2312,0},
+{0x2313,0x2313,0},
+{0x2314,0x2314,0},
+{0x2315,0x2315,0},
+{0x2316,0x2316,0},
+{0x2317,0x2317,0},
+{0x2318,0x2318,0},
+{0x2319,0x2319,0},
+{0x231A,0x231A,0},
+{0x231B,0x231B,0},
+{0x231C,0x231C,0},
+{0x231D,0x231D,0},
+{0x231E,0x231E,0},
+{0x231F,0x231F,0},
+{0x2320,0x2320,0},
+{0x2321,0x2321,0},
+{0x2322,0x2322,0},
+{0x2323,0x2323,0},
+{0x2324,0x2324,0},
+{0x2325,0x2325,0},
+{0x2326,0x2326,0},
+{0x2327,0x2327,0},
+{0x2328,0x2328,0},
+{0x2329,0x2329,0},
+{0x232A,0x232A,0},
+{0x232B,0x232B,0},
+{0x232C,0x232C,0},
+{0x232D,0x232D,0},
+{0x232E,0x232E,0},
+{0x232F,0x232F,0},
+{0x2330,0x2330,0},
+{0x2331,0x2331,0},
+{0x2332,0x2332,0},
+{0x2333,0x2333,0},
+{0x2334,0x2334,0},
+{0x2335,0x2335,0},
+{0x2336,0x2336,0},
+{0x2337,0x2337,0},
+{0x2338,0x2338,0},
+{0x2339,0x2339,0},
+{0x233A,0x233A,0},
+{0x233B,0x233B,0},
+{0x233C,0x233C,0},
+{0x233D,0x233D,0},
+{0x233E,0x233E,0},
+{0x233F,0x233F,0},
+{0x2340,0x2340,0},
+{0x2341,0x2341,0},
+{0x2342,0x2342,0},
+{0x2343,0x2343,0},
+{0x2344,0x2344,0},
+{0x2345,0x2345,0},
+{0x2346,0x2346,0},
+{0x2347,0x2347,0},
+{0x2348,0x2348,0},
+{0x2349,0x2349,0},
+{0x234A,0x234A,0},
+{0x234B,0x234B,0},
+{0x234C,0x234C,0},
+{0x234D,0x234D,0},
+{0x234E,0x234E,0},
+{0x234F,0x234F,0},
+{0x2350,0x2350,0},
+{0x2351,0x2351,0},
+{0x2352,0x2352,0},
+{0x2353,0x2353,0},
+{0x2354,0x2354,0},
+{0x2355,0x2355,0},
+{0x2356,0x2356,0},
+{0x2357,0x2357,0},
+{0x2358,0x2358,0},
+{0x2359,0x2359,0},
+{0x235A,0x235A,0},
+{0x235B,0x235B,0},
+{0x235C,0x235C,0},
+{0x235D,0x235D,0},
+{0x235E,0x235E,0},
+{0x235F,0x235F,0},
+{0x2360,0x2360,0},
+{0x2361,0x2361,0},
+{0x2362,0x2362,0},
+{0x2363,0x2363,0},
+{0x2364,0x2364,0},
+{0x2365,0x2365,0},
+{0x2366,0x2366,0},
+{0x2367,0x2367,0},
+{0x2368,0x2368,0},
+{0x2369,0x2369,0},
+{0x236A,0x236A,0},
+{0x236B,0x236B,0},
+{0x236C,0x236C,0},
+{0x236D,0x236D,0},
+{0x236E,0x236E,0},
+{0x236F,0x236F,0},
+{0x2370,0x2370,0},
+{0x2371,0x2371,0},
+{0x2372,0x2372,0},
+{0x2373,0x2373,0},
+{0x2374,0x2374,0},
+{0x2375,0x2375,0},
+{0x2376,0x2376,0},
+{0x2377,0x2377,0},
+{0x2378,0x2378,0},
+{0x2379,0x2379,0},
+{0x237A,0x237A,0},
+{0x237B,0x237B,0},
+{0x237C,0x237C,0},
+{0x237D,0x237D,0},
+{0x237E,0x237E,0},
+{0x237F,0x237F,0},
+{0x2380,0x2380,0},
+{0x2381,0x2381,0},
+{0x2382,0x2382,0},
+{0x2383,0x2383,0},
+{0x2384,0x2384,0},
+{0x2385,0x2385,0},
+{0x2386,0x2386,0},
+{0x2387,0x2387,0},
+{0x2388,0x2388,0},
+{0x2389,0x2389,0},
+{0x238A,0x238A,0},
+{0x238B,0x238B,0},
+{0x238C,0x238C,0},
+{0x238D,0x238D,0},
+{0x238E,0x238E,0},
+{0x238F,0x238F,0},
+{0x2390,0x2390,0},
+{0x2391,0x2391,0},
+{0x2392,0x2392,0},
+{0x2393,0x2393,0},
+{0x2394,0x2394,0},
+{0x2395,0x2395,0},
+{0x2396,0x2396,0},
+{0x2397,0x2397,0},
+{0x2398,0x2398,0},
+{0x2399,0x2399,0},
+{0x239A,0x239A,0},
+{0x239B,0x239B,0},
+{0x239C,0x239C,0},
+{0x239D,0x239D,0},
+{0x239E,0x239E,0},
+{0x239F,0x239F,0},
+{0x23A0,0x23A0,0},
+{0x23A1,0x23A1,0},
+{0x23A2,0x23A2,0},
+{0x23A3,0x23A3,0},
+{0x23A4,0x23A4,0},
+{0x23A5,0x23A5,0},
+{0x23A6,0x23A6,0},
+{0x23A7,0x23A7,0},
+{0x23A8,0x23A8,0},
+{0x23A9,0x23A9,0},
+{0x23AA,0x23AA,0},
+{0x23AB,0x23AB,0},
+{0x23AC,0x23AC,0},
+{0x23AD,0x23AD,0},
+{0x23AE,0x23AE,0},
+{0x23AF,0x23AF,0},
+{0x23B0,0x23B0,0},
+{0x23B1,0x23B1,0},
+{0x23B2,0x23B2,0},
+{0x23B3,0x23B3,0},
+{0x23B4,0x23B4,0},
+{0x23B5,0x23B5,0},
+{0x23B6,0x23B6,0},
+{0x23B7,0x23B7,0},
+{0x23B8,0x23B8,0},
+{0x23B9,0x23B9,0},
+{0x23BA,0x23BA,0},
+{0x23BB,0x23BB,0},
+{0x23BC,0x23BC,0},
+{0x23BD,0x23BD,0},
+{0x23BE,0x23BE,0},
+{0x23BF,0x23BF,0},
+{0x23C0,0x23C0,0},
+{0x23C1,0x23C1,0},
+{0x23C2,0x23C2,0},
+{0x23C3,0x23C3,0},
+{0x23C4,0x23C4,0},
+{0x23C5,0x23C5,0},
+{0x23C6,0x23C6,0},
+{0x23C7,0x23C7,0},
+{0x23C8,0x23C8,0},
+{0x23C9,0x23C9,0},
+{0x23CA,0x23CA,0},
+{0x23CB,0x23CB,0},
+{0x23CC,0x23CC,0},
+{0x23CD,0x23CD,0},
+{0x23CE,0x23CE,0},
+{0x23CF,0x23CF,0},
+{0x23D0,0x23D0,0},
+{0x23D1,0x23D1,0},
+{0x23D2,0x23D2,0},
+{0x23D3,0x23D3,0},
+{0x23D4,0x23D4,0},
+{0x23D5,0x23D5,0},
+{0x23D6,0x23D6,0},
+{0x23D7,0x23D7,0},
+{0x23D8,0x23D8,0},
+{0x23D9,0x23D9,0},
+{0x23DA,0x23DA,0},
+{0x23DB,0x23DB,0},
+{0x23DC,0x23DC,0},
+{0x23DD,0x23DD,0},
+{0x23DE,0x23DE,0},
+{0x23DF,0x23DF,0},
+{0x23E0,0x23E0,0},
+{0x23E1,0x23E1,0},
+{0x23E2,0x23E2,0},
+{0x23E3,0x23E3,0},
+{0x23E4,0x23E4,0},
+{0x23E5,0x23E5,0},
+{0x23E6,0x23E6,0},
+{0x23E7,0x23E7,0},
+{0x23E8,0x23E8,0},
+{0x23E9,0x23E9,0},
+{0x23EA,0x23EA,0},
+{0x23EB,0x23EB,0},
+{0x23EC,0x23EC,0},
+{0x23ED,0x23ED,0},
+{0x23EE,0x23EE,0},
+{0x23EF,0x23EF,0},
+{0x23F0,0x23F0,0},
+{0x23F1,0x23F1,0},
+{0x23F2,0x23F2,0},
+{0x23F3,0x23F3,0},
+{0x23F4,0x23F4,0},
+{0x23F5,0x23F5,0},
+{0x23F6,0x23F6,0},
+{0x23F7,0x23F7,0},
+{0x23F8,0x23F8,0},
+{0x23F9,0x23F9,0},
+{0x23FA,0x23FA,0},
+{0x23FB,0x23FB,0},
+{0x23FC,0x23FC,0},
+{0x23FD,0x23FD,0},
+{0x23FE,0x23FE,0},
+{0x23FF,0x23FF,0},
+{0x2400,0x2400,0},
+{0x2401,0x2401,0},
+{0x2402,0x2402,0},
+{0x2403,0x2403,0},
+{0x2404,0x2404,0},
+{0x2405,0x2405,0},
+{0x2406,0x2406,0},
+{0x2407,0x2407,0},
+{0x2408,0x2408,0},
+{0x2409,0x2409,0},
+{0x240A,0x240A,0},
+{0x240B,0x240B,0},
+{0x240C,0x240C,0},
+{0x240D,0x240D,0},
+{0x240E,0x240E,0},
+{0x240F,0x240F,0},
+{0x2410,0x2410,0},
+{0x2411,0x2411,0},
+{0x2412,0x2412,0},
+{0x2413,0x2413,0},
+{0x2414,0x2414,0},
+{0x2415,0x2415,0},
+{0x2416,0x2416,0},
+{0x2417,0x2417,0},
+{0x2418,0x2418,0},
+{0x2419,0x2419,0},
+{0x241A,0x241A,0},
+{0x241B,0x241B,0},
+{0x241C,0x241C,0},
+{0x241D,0x241D,0},
+{0x241E,0x241E,0},
+{0x241F,0x241F,0},
+{0x2420,0x2420,0},
+{0x2421,0x2421,0},
+{0x2422,0x2422,0},
+{0x2423,0x2423,0},
+{0x2424,0x2424,0},
+{0x2425,0x2425,0},
+{0x2426,0x2426,0},
+{0x2427,0x2427,0},
+{0x2428,0x2428,0},
+{0x2429,0x2429,0},
+{0x242A,0x242A,0},
+{0x242B,0x242B,0},
+{0x242C,0x242C,0},
+{0x242D,0x242D,0},
+{0x242E,0x242E,0},
+{0x242F,0x242F,0},
+{0x2430,0x2430,0},
+{0x2431,0x2431,0},
+{0x2432,0x2432,0},
+{0x2433,0x2433,0},
+{0x2434,0x2434,0},
+{0x2435,0x2435,0},
+{0x2436,0x2436,0},
+{0x2437,0x2437,0},
+{0x2438,0x2438,0},
+{0x2439,0x2439,0},
+{0x243A,0x243A,0},
+{0x243B,0x243B,0},
+{0x243C,0x243C,0},
+{0x243D,0x243D,0},
+{0x243E,0x243E,0},
+{0x243F,0x243F,0},
+{0x2440,0x2440,0},
+{0x2441,0x2441,0},
+{0x2442,0x2442,0},
+{0x2443,0x2443,0},
+{0x2444,0x2444,0},
+{0x2445,0x2445,0},
+{0x2446,0x2446,0},
+{0x2447,0x2447,0},
+{0x2448,0x2448,0},
+{0x2449,0x2449,0},
+{0x244A,0x244A,0},
+{0x244B,0x244B,0},
+{0x244C,0x244C,0},
+{0x244D,0x244D,0},
+{0x244E,0x244E,0},
+{0x244F,0x244F,0},
+{0x2450,0x2450,0},
+{0x2451,0x2451,0},
+{0x2452,0x2452,0},
+{0x2453,0x2453,0},
+{0x2454,0x2454,0},
+{0x2455,0x2455,0},
+{0x2456,0x2456,0},
+{0x2457,0x2457,0},
+{0x2458,0x2458,0},
+{0x2459,0x2459,0},
+{0x245A,0x245A,0},
+{0x245B,0x245B,0},
+{0x245C,0x245C,0},
+{0x245D,0x245D,0},
+{0x245E,0x245E,0},
+{0x245F,0x245F,0},
+{0x2460,0x2460,0},
+{0x2461,0x2461,0},
+{0x2462,0x2462,0},
+{0x2463,0x2463,0},
+{0x2464,0x2464,0},
+{0x2465,0x2465,0},
+{0x2466,0x2466,0},
+{0x2467,0x2467,0},
+{0x2468,0x2468,0},
+{0x2469,0x2469,0},
+{0x246A,0x246A,0},
+{0x246B,0x246B,0},
+{0x246C,0x246C,0},
+{0x246D,0x246D,0},
+{0x246E,0x246E,0},
+{0x246F,0x246F,0},
+{0x2470,0x2470,0},
+{0x2471,0x2471,0},
+{0x2472,0x2472,0},
+{0x2473,0x2473,0},
+{0x2474,0x2474,0},
+{0x2475,0x2475,0},
+{0x2476,0x2476,0},
+{0x2477,0x2477,0},
+{0x2478,0x2478,0},
+{0x2479,0x2479,0},
+{0x247A,0x247A,0},
+{0x247B,0x247B,0},
+{0x247C,0x247C,0},
+{0x247D,0x247D,0},
+{0x247E,0x247E,0},
+{0x247F,0x247F,0},
+{0x2480,0x2480,0},
+{0x2481,0x2481,0},
+{0x2482,0x2482,0},
+{0x2483,0x2483,0},
+{0x2484,0x2484,0},
+{0x2485,0x2485,0},
+{0x2486,0x2486,0},
+{0x2487,0x2487,0},
+{0x2488,0x2488,0},
+{0x2489,0x2489,0},
+{0x248A,0x248A,0},
+{0x248B,0x248B,0},
+{0x248C,0x248C,0},
+{0x248D,0x248D,0},
+{0x248E,0x248E,0},
+{0x248F,0x248F,0},
+{0x2490,0x2490,0},
+{0x2491,0x2491,0},
+{0x2492,0x2492,0},
+{0x2493,0x2493,0},
+{0x2494,0x2494,0},
+{0x2495,0x2495,0},
+{0x2496,0x2496,0},
+{0x2497,0x2497,0},
+{0x2498,0x2498,0},
+{0x2499,0x2499,0},
+{0x249A,0x249A,0},
+{0x249B,0x249B,0},
+{0x249C,0x249C,0},
+{0x249D,0x249D,0},
+{0x249E,0x249E,0},
+{0x249F,0x249F,0},
+{0x24A0,0x24A0,0},
+{0x24A1,0x24A1,0},
+{0x24A2,0x24A2,0},
+{0x24A3,0x24A3,0},
+{0x24A4,0x24A4,0},
+{0x24A5,0x24A5,0},
+{0x24A6,0x24A6,0},
+{0x24A7,0x24A7,0},
+{0x24A8,0x24A8,0},
+{0x24A9,0x24A9,0},
+{0x24AA,0x24AA,0},
+{0x24AB,0x24AB,0},
+{0x24AC,0x24AC,0},
+{0x24AD,0x24AD,0},
+{0x24AE,0x24AE,0},
+{0x24AF,0x24AF,0},
+{0x24B0,0x24B0,0},
+{0x24B1,0x24B1,0},
+{0x24B2,0x24B2,0},
+{0x24B3,0x24B3,0},
+{0x24B4,0x24B4,0},
+{0x24B5,0x24B5,0},
+{0x24D0,0x24B6,0},
+{0x24D1,0x24B7,0},
+{0x24D2,0x24B8,0},
+{0x24D3,0x24B9,0},
+{0x24D4,0x24BA,0},
+{0x24D5,0x24BB,0},
+{0x24D6,0x24BC,0},
+{0x24D7,0x24BD,0},
+{0x24D8,0x24BE,0},
+{0x24D9,0x24BF,0},
+{0x24DA,0x24C0,0},
+{0x24DB,0x24C1,0},
+{0x24DC,0x24C2,0},
+{0x24DD,0x24C3,0},
+{0x24DE,0x24C4,0},
+{0x24DF,0x24C5,0},
+{0x24E0,0x24C6,0},
+{0x24E1,0x24C7,0},
+{0x24E2,0x24C8,0},
+{0x24E3,0x24C9,0},
+{0x24E4,0x24CA,0},
+{0x24E5,0x24CB,0},
+{0x24E6,0x24CC,0},
+{0x24E7,0x24CD,0},
+{0x24E8,0x24CE,0},
+{0x24E9,0x24CF,0},
+{0x24D0,0x24B6,0},
+{0x24D1,0x24B7,0},
+{0x24D2,0x24B8,0},
+{0x24D3,0x24B9,0},
+{0x24D4,0x24BA,0},
+{0x24D5,0x24BB,0},
+{0x24D6,0x24BC,0},
+{0x24D7,0x24BD,0},
+{0x24D8,0x24BE,0},
+{0x24D9,0x24BF,0},
+{0x24DA,0x24C0,0},
+{0x24DB,0x24C1,0},
+{0x24DC,0x24C2,0},
+{0x24DD,0x24C3,0},
+{0x24DE,0x24C4,0},
+{0x24DF,0x24C5,0},
+{0x24E0,0x24C6,0},
+{0x24E1,0x24C7,0},
+{0x24E2,0x24C8,0},
+{0x24E3,0x24C9,0},
+{0x24E4,0x24CA,0},
+{0x24E5,0x24CB,0},
+{0x24E6,0x24CC,0},
+{0x24E7,0x24CD,0},
+{0x24E8,0x24CE,0},
+{0x24E9,0x24CF,0},
diff --git a/source/include/unicode_map_table2.h b/source/include/unicode_map_table2.h
new file mode 100755
index 00000000000..637a6b063eb
--- /dev/null
+++ b/source/include/unicode_map_table2.h
@@ -0,0 +1,1280 @@
+{0xFB00,0xFB00,UNI_LOWER},
+{0xFB01,0xFB01,UNI_LOWER},
+{0xFB02,0xFB02,UNI_LOWER},
+{0xFB03,0xFB03,UNI_LOWER},
+{0xFB04,0xFB04,UNI_LOWER},
+{0xFB05,0xFB05,UNI_LOWER},
+{0xFB06,0xFB06,UNI_LOWER},
+{0xFB07,0xFB07,0},
+{0xFB08,0xFB08,0},
+{0xFB09,0xFB09,0},
+{0xFB0A,0xFB0A,0},
+{0xFB0B,0xFB0B,0},
+{0xFB0C,0xFB0C,0},
+{0xFB0D,0xFB0D,0},
+{0xFB0E,0xFB0E,0},
+{0xFB0F,0xFB0F,0},
+{0xFB10,0xFB10,0},
+{0xFB11,0xFB11,0},
+{0xFB12,0xFB12,0},
+{0xFB13,0xFB13,UNI_LOWER},
+{0xFB14,0xFB14,UNI_LOWER},
+{0xFB15,0xFB15,UNI_LOWER},
+{0xFB16,0xFB16,UNI_LOWER},
+{0xFB17,0xFB17,UNI_LOWER},
+{0xFB18,0xFB18,0},
+{0xFB19,0xFB19,0},
+{0xFB1A,0xFB1A,0},
+{0xFB1B,0xFB1B,0},
+{0xFB1C,0xFB1C,0},
+{0xFB1D,0xFB1D,0},
+{0xFB1E,0xFB1E,0},
+{0xFB1F,0xFB1F,0},
+{0xFB20,0xFB20,0},
+{0xFB21,0xFB21,0},
+{0xFB22,0xFB22,0},
+{0xFB23,0xFB23,0},
+{0xFB24,0xFB24,0},
+{0xFB25,0xFB25,0},
+{0xFB26,0xFB26,0},
+{0xFB27,0xFB27,0},
+{0xFB28,0xFB28,0},
+{0xFB29,0xFB29,0},
+{0xFB2A,0xFB2A,0},
+{0xFB2B,0xFB2B,0},
+{0xFB2C,0xFB2C,0},
+{0xFB2D,0xFB2D,0},
+{0xFB2E,0xFB2E,0},
+{0xFB2F,0xFB2F,0},
+{0xFB30,0xFB30,0},
+{0xFB31,0xFB31,0},
+{0xFB32,0xFB32,0},
+{0xFB33,0xFB33,0},
+{0xFB34,0xFB34,0},
+{0xFB35,0xFB35,0},
+{0xFB36,0xFB36,0},
+{0xFB37,0xFB37,0},
+{0xFB38,0xFB38,0},
+{0xFB39,0xFB39,0},
+{0xFB3A,0xFB3A,0},
+{0xFB3B,0xFB3B,0},
+{0xFB3C,0xFB3C,0},
+{0xFB3D,0xFB3D,0},
+{0xFB3E,0xFB3E,0},
+{0xFB3F,0xFB3F,0},
+{0xFB40,0xFB40,0},
+{0xFB41,0xFB41,0},
+{0xFB42,0xFB42,0},
+{0xFB43,0xFB43,0},
+{0xFB44,0xFB44,0},
+{0xFB45,0xFB45,0},
+{0xFB46,0xFB46,0},
+{0xFB47,0xFB47,0},
+{0xFB48,0xFB48,0},
+{0xFB49,0xFB49,0},
+{0xFB4A,0xFB4A,0},
+{0xFB4B,0xFB4B,0},
+{0xFB4C,0xFB4C,0},
+{0xFB4D,0xFB4D,0},
+{0xFB4E,0xFB4E,0},
+{0xFB4F,0xFB4F,0},
+{0xFB50,0xFB50,0},
+{0xFB51,0xFB51,0},
+{0xFB52,0xFB52,0},
+{0xFB53,0xFB53,0},
+{0xFB54,0xFB54,0},
+{0xFB55,0xFB55,0},
+{0xFB56,0xFB56,0},
+{0xFB57,0xFB57,0},
+{0xFB58,0xFB58,0},
+{0xFB59,0xFB59,0},
+{0xFB5A,0xFB5A,0},
+{0xFB5B,0xFB5B,0},
+{0xFB5C,0xFB5C,0},
+{0xFB5D,0xFB5D,0},
+{0xFB5E,0xFB5E,0},
+{0xFB5F,0xFB5F,0},
+{0xFB60,0xFB60,0},
+{0xFB61,0xFB61,0},
+{0xFB62,0xFB62,0},
+{0xFB63,0xFB63,0},
+{0xFB64,0xFB64,0},
+{0xFB65,0xFB65,0},
+{0xFB66,0xFB66,0},
+{0xFB67,0xFB67,0},
+{0xFB68,0xFB68,0},
+{0xFB69,0xFB69,0},
+{0xFB6A,0xFB6A,0},
+{0xFB6B,0xFB6B,0},
+{0xFB6C,0xFB6C,0},
+{0xFB6D,0xFB6D,0},
+{0xFB6E,0xFB6E,0},
+{0xFB6F,0xFB6F,0},
+{0xFB70,0xFB70,0},
+{0xFB71,0xFB71,0},
+{0xFB72,0xFB72,0},
+{0xFB73,0xFB73,0},
+{0xFB74,0xFB74,0},
+{0xFB75,0xFB75,0},
+{0xFB76,0xFB76,0},
+{0xFB77,0xFB77,0},
+{0xFB78,0xFB78,0},
+{0xFB79,0xFB79,0},
+{0xFB7A,0xFB7A,0},
+{0xFB7B,0xFB7B,0},
+{0xFB7C,0xFB7C,0},
+{0xFB7D,0xFB7D,0},
+{0xFB7E,0xFB7E,0},
+{0xFB7F,0xFB7F,0},
+{0xFB80,0xFB80,0},
+{0xFB81,0xFB81,0},
+{0xFB82,0xFB82,0},
+{0xFB83,0xFB83,0},
+{0xFB84,0xFB84,0},
+{0xFB85,0xFB85,0},
+{0xFB86,0xFB86,0},
+{0xFB87,0xFB87,0},
+{0xFB88,0xFB88,0},
+{0xFB89,0xFB89,0},
+{0xFB8A,0xFB8A,0},
+{0xFB8B,0xFB8B,0},
+{0xFB8C,0xFB8C,0},
+{0xFB8D,0xFB8D,0},
+{0xFB8E,0xFB8E,0},
+{0xFB8F,0xFB8F,0},
+{0xFB90,0xFB90,0},
+{0xFB91,0xFB91,0},
+{0xFB92,0xFB92,0},
+{0xFB93,0xFB93,0},
+{0xFB94,0xFB94,0},
+{0xFB95,0xFB95,0},
+{0xFB96,0xFB96,0},
+{0xFB97,0xFB97,0},
+{0xFB98,0xFB98,0},
+{0xFB99,0xFB99,0},
+{0xFB9A,0xFB9A,0},
+{0xFB9B,0xFB9B,0},
+{0xFB9C,0xFB9C,0},
+{0xFB9D,0xFB9D,0},
+{0xFB9E,0xFB9E,0},
+{0xFB9F,0xFB9F,0},
+{0xFBA0,0xFBA0,0},
+{0xFBA1,0xFBA1,0},
+{0xFBA2,0xFBA2,0},
+{0xFBA3,0xFBA3,0},
+{0xFBA4,0xFBA4,0},
+{0xFBA5,0xFBA5,0},
+{0xFBA6,0xFBA6,0},
+{0xFBA7,0xFBA7,0},
+{0xFBA8,0xFBA8,0},
+{0xFBA9,0xFBA9,0},
+{0xFBAA,0xFBAA,0},
+{0xFBAB,0xFBAB,0},
+{0xFBAC,0xFBAC,0},
+{0xFBAD,0xFBAD,0},
+{0xFBAE,0xFBAE,0},
+{0xFBAF,0xFBAF,0},
+{0xFBB0,0xFBB0,0},
+{0xFBB1,0xFBB1,0},
+{0xFBB2,0xFBB2,0},
+{0xFBB3,0xFBB3,0},
+{0xFBB4,0xFBB4,0},
+{0xFBB5,0xFBB5,0},
+{0xFBB6,0xFBB6,0},
+{0xFBB7,0xFBB7,0},
+{0xFBB8,0xFBB8,0},
+{0xFBB9,0xFBB9,0},
+{0xFBBA,0xFBBA,0},
+{0xFBBB,0xFBBB,0},
+{0xFBBC,0xFBBC,0},
+{0xFBBD,0xFBBD,0},
+{0xFBBE,0xFBBE,0},
+{0xFBBF,0xFBBF,0},
+{0xFBC0,0xFBC0,0},
+{0xFBC1,0xFBC1,0},
+{0xFBC2,0xFBC2,0},
+{0xFBC3,0xFBC3,0},
+{0xFBC4,0xFBC4,0},
+{0xFBC5,0xFBC5,0},
+{0xFBC6,0xFBC6,0},
+{0xFBC7,0xFBC7,0},
+{0xFBC8,0xFBC8,0},
+{0xFBC9,0xFBC9,0},
+{0xFBCA,0xFBCA,0},
+{0xFBCB,0xFBCB,0},
+{0xFBCC,0xFBCC,0},
+{0xFBCD,0xFBCD,0},
+{0xFBCE,0xFBCE,0},
+{0xFBCF,0xFBCF,0},
+{0xFBD0,0xFBD0,0},
+{0xFBD1,0xFBD1,0},
+{0xFBD2,0xFBD2,0},
+{0xFBD3,0xFBD3,0},
+{0xFBD4,0xFBD4,0},
+{0xFBD5,0xFBD5,0},
+{0xFBD6,0xFBD6,0},
+{0xFBD7,0xFBD7,0},
+{0xFBD8,0xFBD8,0},
+{0xFBD9,0xFBD9,0},
+{0xFBDA,0xFBDA,0},
+{0xFBDB,0xFBDB,0},
+{0xFBDC,0xFBDC,0},
+{0xFBDD,0xFBDD,0},
+{0xFBDE,0xFBDE,0},
+{0xFBDF,0xFBDF,0},
+{0xFBE0,0xFBE0,0},
+{0xFBE1,0xFBE1,0},
+{0xFBE2,0xFBE2,0},
+{0xFBE3,0xFBE3,0},
+{0xFBE4,0xFBE4,0},
+{0xFBE5,0xFBE5,0},
+{0xFBE6,0xFBE6,0},
+{0xFBE7,0xFBE7,0},
+{0xFBE8,0xFBE8,0},
+{0xFBE9,0xFBE9,0},
+{0xFBEA,0xFBEA,0},
+{0xFBEB,0xFBEB,0},
+{0xFBEC,0xFBEC,0},
+{0xFBED,0xFBED,0},
+{0xFBEE,0xFBEE,0},
+{0xFBEF,0xFBEF,0},
+{0xFBF0,0xFBF0,0},
+{0xFBF1,0xFBF1,0},
+{0xFBF2,0xFBF2,0},
+{0xFBF3,0xFBF3,0},
+{0xFBF4,0xFBF4,0},
+{0xFBF5,0xFBF5,0},
+{0xFBF6,0xFBF6,0},
+{0xFBF7,0xFBF7,0},
+{0xFBF8,0xFBF8,0},
+{0xFBF9,0xFBF9,0},
+{0xFBFA,0xFBFA,0},
+{0xFBFB,0xFBFB,0},
+{0xFBFC,0xFBFC,0},
+{0xFBFD,0xFBFD,0},
+{0xFBFE,0xFBFE,0},
+{0xFBFF,0xFBFF,0},
+{0xFC00,0xFC00,0},
+{0xFC01,0xFC01,0},
+{0xFC02,0xFC02,0},
+{0xFC03,0xFC03,0},
+{0xFC04,0xFC04,0},
+{0xFC05,0xFC05,0},
+{0xFC06,0xFC06,0},
+{0xFC07,0xFC07,0},
+{0xFC08,0xFC08,0},
+{0xFC09,0xFC09,0},
+{0xFC0A,0xFC0A,0},
+{0xFC0B,0xFC0B,0},
+{0xFC0C,0xFC0C,0},
+{0xFC0D,0xFC0D,0},
+{0xFC0E,0xFC0E,0},
+{0xFC0F,0xFC0F,0},
+{0xFC10,0xFC10,0},
+{0xFC11,0xFC11,0},
+{0xFC12,0xFC12,0},
+{0xFC13,0xFC13,0},
+{0xFC14,0xFC14,0},
+{0xFC15,0xFC15,0},
+{0xFC16,0xFC16,0},
+{0xFC17,0xFC17,0},
+{0xFC18,0xFC18,0},
+{0xFC19,0xFC19,0},
+{0xFC1A,0xFC1A,0},
+{0xFC1B,0xFC1B,0},
+{0xFC1C,0xFC1C,0},
+{0xFC1D,0xFC1D,0},
+{0xFC1E,0xFC1E,0},
+{0xFC1F,0xFC1F,0},
+{0xFC20,0xFC20,0},
+{0xFC21,0xFC21,0},
+{0xFC22,0xFC22,0},
+{0xFC23,0xFC23,0},
+{0xFC24,0xFC24,0},
+{0xFC25,0xFC25,0},
+{0xFC26,0xFC26,0},
+{0xFC27,0xFC27,0},
+{0xFC28,0xFC28,0},
+{0xFC29,0xFC29,0},
+{0xFC2A,0xFC2A,0},
+{0xFC2B,0xFC2B,0},
+{0xFC2C,0xFC2C,0},
+{0xFC2D,0xFC2D,0},
+{0xFC2E,0xFC2E,0},
+{0xFC2F,0xFC2F,0},
+{0xFC30,0xFC30,0},
+{0xFC31,0xFC31,0},
+{0xFC32,0xFC32,0},
+{0xFC33,0xFC33,0},
+{0xFC34,0xFC34,0},
+{0xFC35,0xFC35,0},
+{0xFC36,0xFC36,0},
+{0xFC37,0xFC37,0},
+{0xFC38,0xFC38,0},
+{0xFC39,0xFC39,0},
+{0xFC3A,0xFC3A,0},
+{0xFC3B,0xFC3B,0},
+{0xFC3C,0xFC3C,0},
+{0xFC3D,0xFC3D,0},
+{0xFC3E,0xFC3E,0},
+{0xFC3F,0xFC3F,0},
+{0xFC40,0xFC40,0},
+{0xFC41,0xFC41,0},
+{0xFC42,0xFC42,0},
+{0xFC43,0xFC43,0},
+{0xFC44,0xFC44,0},
+{0xFC45,0xFC45,0},
+{0xFC46,0xFC46,0},
+{0xFC47,0xFC47,0},
+{0xFC48,0xFC48,0},
+{0xFC49,0xFC49,0},
+{0xFC4A,0xFC4A,0},
+{0xFC4B,0xFC4B,0},
+{0xFC4C,0xFC4C,0},
+{0xFC4D,0xFC4D,0},
+{0xFC4E,0xFC4E,0},
+{0xFC4F,0xFC4F,0},
+{0xFC50,0xFC50,0},
+{0xFC51,0xFC51,0},
+{0xFC52,0xFC52,0},
+{0xFC53,0xFC53,0},
+{0xFC54,0xFC54,0},
+{0xFC55,0xFC55,0},
+{0xFC56,0xFC56,0},
+{0xFC57,0xFC57,0},
+{0xFC58,0xFC58,0},
+{0xFC59,0xFC59,0},
+{0xFC5A,0xFC5A,0},
+{0xFC5B,0xFC5B,0},
+{0xFC5C,0xFC5C,0},
+{0xFC5D,0xFC5D,0},
+{0xFC5E,0xFC5E,0},
+{0xFC5F,0xFC5F,0},
+{0xFC60,0xFC60,0},
+{0xFC61,0xFC61,0},
+{0xFC62,0xFC62,0},
+{0xFC63,0xFC63,0},
+{0xFC64,0xFC64,0},
+{0xFC65,0xFC65,0},
+{0xFC66,0xFC66,0},
+{0xFC67,0xFC67,0},
+{0xFC68,0xFC68,0},
+{0xFC69,0xFC69,0},
+{0xFC6A,0xFC6A,0},
+{0xFC6B,0xFC6B,0},
+{0xFC6C,0xFC6C,0},
+{0xFC6D,0xFC6D,0},
+{0xFC6E,0xFC6E,0},
+{0xFC6F,0xFC6F,0},
+{0xFC70,0xFC70,0},
+{0xFC71,0xFC71,0},
+{0xFC72,0xFC72,0},
+{0xFC73,0xFC73,0},
+{0xFC74,0xFC74,0},
+{0xFC75,0xFC75,0},
+{0xFC76,0xFC76,0},
+{0xFC77,0xFC77,0},
+{0xFC78,0xFC78,0},
+{0xFC79,0xFC79,0},
+{0xFC7A,0xFC7A,0},
+{0xFC7B,0xFC7B,0},
+{0xFC7C,0xFC7C,0},
+{0xFC7D,0xFC7D,0},
+{0xFC7E,0xFC7E,0},
+{0xFC7F,0xFC7F,0},
+{0xFC80,0xFC80,0},
+{0xFC81,0xFC81,0},
+{0xFC82,0xFC82,0},
+{0xFC83,0xFC83,0},
+{0xFC84,0xFC84,0},
+{0xFC85,0xFC85,0},
+{0xFC86,0xFC86,0},
+{0xFC87,0xFC87,0},
+{0xFC88,0xFC88,0},
+{0xFC89,0xFC89,0},
+{0xFC8A,0xFC8A,0},
+{0xFC8B,0xFC8B,0},
+{0xFC8C,0xFC8C,0},
+{0xFC8D,0xFC8D,0},
+{0xFC8E,0xFC8E,0},
+{0xFC8F,0xFC8F,0},
+{0xFC90,0xFC90,0},
+{0xFC91,0xFC91,0},
+{0xFC92,0xFC92,0},
+{0xFC93,0xFC93,0},
+{0xFC94,0xFC94,0},
+{0xFC95,0xFC95,0},
+{0xFC96,0xFC96,0},
+{0xFC97,0xFC97,0},
+{0xFC98,0xFC98,0},
+{0xFC99,0xFC99,0},
+{0xFC9A,0xFC9A,0},
+{0xFC9B,0xFC9B,0},
+{0xFC9C,0xFC9C,0},
+{0xFC9D,0xFC9D,0},
+{0xFC9E,0xFC9E,0},
+{0xFC9F,0xFC9F,0},
+{0xFCA0,0xFCA0,0},
+{0xFCA1,0xFCA1,0},
+{0xFCA2,0xFCA2,0},
+{0xFCA3,0xFCA3,0},
+{0xFCA4,0xFCA4,0},
+{0xFCA5,0xFCA5,0},
+{0xFCA6,0xFCA6,0},
+{0xFCA7,0xFCA7,0},
+{0xFCA8,0xFCA8,0},
+{0xFCA9,0xFCA9,0},
+{0xFCAA,0xFCAA,0},
+{0xFCAB,0xFCAB,0},
+{0xFCAC,0xFCAC,0},
+{0xFCAD,0xFCAD,0},
+{0xFCAE,0xFCAE,0},
+{0xFCAF,0xFCAF,0},
+{0xFCB0,0xFCB0,0},
+{0xFCB1,0xFCB1,0},
+{0xFCB2,0xFCB2,0},
+{0xFCB3,0xFCB3,0},
+{0xFCB4,0xFCB4,0},
+{0xFCB5,0xFCB5,0},
+{0xFCB6,0xFCB6,0},
+{0xFCB7,0xFCB7,0},
+{0xFCB8,0xFCB8,0},
+{0xFCB9,0xFCB9,0},
+{0xFCBA,0xFCBA,0},
+{0xFCBB,0xFCBB,0},
+{0xFCBC,0xFCBC,0},
+{0xFCBD,0xFCBD,0},
+{0xFCBE,0xFCBE,0},
+{0xFCBF,0xFCBF,0},
+{0xFCC0,0xFCC0,0},
+{0xFCC1,0xFCC1,0},
+{0xFCC2,0xFCC2,0},
+{0xFCC3,0xFCC3,0},
+{0xFCC4,0xFCC4,0},
+{0xFCC5,0xFCC5,0},
+{0xFCC6,0xFCC6,0},
+{0xFCC7,0xFCC7,0},
+{0xFCC8,0xFCC8,0},
+{0xFCC9,0xFCC9,0},
+{0xFCCA,0xFCCA,0},
+{0xFCCB,0xFCCB,0},
+{0xFCCC,0xFCCC,0},
+{0xFCCD,0xFCCD,0},
+{0xFCCE,0xFCCE,0},
+{0xFCCF,0xFCCF,0},
+{0xFCD0,0xFCD0,0},
+{0xFCD1,0xFCD1,0},
+{0xFCD2,0xFCD2,0},
+{0xFCD3,0xFCD3,0},
+{0xFCD4,0xFCD4,0},
+{0xFCD5,0xFCD5,0},
+{0xFCD6,0xFCD6,0},
+{0xFCD7,0xFCD7,0},
+{0xFCD8,0xFCD8,0},
+{0xFCD9,0xFCD9,0},
+{0xFCDA,0xFCDA,0},
+{0xFCDB,0xFCDB,0},
+{0xFCDC,0xFCDC,0},
+{0xFCDD,0xFCDD,0},
+{0xFCDE,0xFCDE,0},
+{0xFCDF,0xFCDF,0},
+{0xFCE0,0xFCE0,0},
+{0xFCE1,0xFCE1,0},
+{0xFCE2,0xFCE2,0},
+{0xFCE3,0xFCE3,0},
+{0xFCE4,0xFCE4,0},
+{0xFCE5,0xFCE5,0},
+{0xFCE6,0xFCE6,0},
+{0xFCE7,0xFCE7,0},
+{0xFCE8,0xFCE8,0},
+{0xFCE9,0xFCE9,0},
+{0xFCEA,0xFCEA,0},
+{0xFCEB,0xFCEB,0},
+{0xFCEC,0xFCEC,0},
+{0xFCED,0xFCED,0},
+{0xFCEE,0xFCEE,0},
+{0xFCEF,0xFCEF,0},
+{0xFCF0,0xFCF0,0},
+{0xFCF1,0xFCF1,0},
+{0xFCF2,0xFCF2,0},
+{0xFCF3,0xFCF3,0},
+{0xFCF4,0xFCF4,0},
+{0xFCF5,0xFCF5,0},
+{0xFCF6,0xFCF6,0},
+{0xFCF7,0xFCF7,0},
+{0xFCF8,0xFCF8,0},
+{0xFCF9,0xFCF9,0},
+{0xFCFA,0xFCFA,0},
+{0xFCFB,0xFCFB,0},
+{0xFCFC,0xFCFC,0},
+{0xFCFD,0xFCFD,0},
+{0xFCFE,0xFCFE,0},
+{0xFCFF,0xFCFF,0},
+{0xFD00,0xFD00,0},
+{0xFD01,0xFD01,0},
+{0xFD02,0xFD02,0},
+{0xFD03,0xFD03,0},
+{0xFD04,0xFD04,0},
+{0xFD05,0xFD05,0},
+{0xFD06,0xFD06,0},
+{0xFD07,0xFD07,0},
+{0xFD08,0xFD08,0},
+{0xFD09,0xFD09,0},
+{0xFD0A,0xFD0A,0},
+{0xFD0B,0xFD0B,0},
+{0xFD0C,0xFD0C,0},
+{0xFD0D,0xFD0D,0},
+{0xFD0E,0xFD0E,0},
+{0xFD0F,0xFD0F,0},
+{0xFD10,0xFD10,0},
+{0xFD11,0xFD11,0},
+{0xFD12,0xFD12,0},
+{0xFD13,0xFD13,0},
+{0xFD14,0xFD14,0},
+{0xFD15,0xFD15,0},
+{0xFD16,0xFD16,0},
+{0xFD17,0xFD17,0},
+{0xFD18,0xFD18,0},
+{0xFD19,0xFD19,0},
+{0xFD1A,0xFD1A,0},
+{0xFD1B,0xFD1B,0},
+{0xFD1C,0xFD1C,0},
+{0xFD1D,0xFD1D,0},
+{0xFD1E,0xFD1E,0},
+{0xFD1F,0xFD1F,0},
+{0xFD20,0xFD20,0},
+{0xFD21,0xFD21,0},
+{0xFD22,0xFD22,0},
+{0xFD23,0xFD23,0},
+{0xFD24,0xFD24,0},
+{0xFD25,0xFD25,0},
+{0xFD26,0xFD26,0},
+{0xFD27,0xFD27,0},
+{0xFD28,0xFD28,0},
+{0xFD29,0xFD29,0},
+{0xFD2A,0xFD2A,0},
+{0xFD2B,0xFD2B,0},
+{0xFD2C,0xFD2C,0},
+{0xFD2D,0xFD2D,0},
+{0xFD2E,0xFD2E,0},
+{0xFD2F,0xFD2F,0},
+{0xFD30,0xFD30,0},
+{0xFD31,0xFD31,0},
+{0xFD32,0xFD32,0},
+{0xFD33,0xFD33,0},
+{0xFD34,0xFD34,0},
+{0xFD35,0xFD35,0},
+{0xFD36,0xFD36,0},
+{0xFD37,0xFD37,0},
+{0xFD38,0xFD38,0},
+{0xFD39,0xFD39,0},
+{0xFD3A,0xFD3A,0},
+{0xFD3B,0xFD3B,0},
+{0xFD3C,0xFD3C,0},
+{0xFD3D,0xFD3D,0},
+{0xFD3E,0xFD3E,0},
+{0xFD3F,0xFD3F,0},
+{0xFD40,0xFD40,0},
+{0xFD41,0xFD41,0},
+{0xFD42,0xFD42,0},
+{0xFD43,0xFD43,0},
+{0xFD44,0xFD44,0},
+{0xFD45,0xFD45,0},
+{0xFD46,0xFD46,0},
+{0xFD47,0xFD47,0},
+{0xFD48,0xFD48,0},
+{0xFD49,0xFD49,0},
+{0xFD4A,0xFD4A,0},
+{0xFD4B,0xFD4B,0},
+{0xFD4C,0xFD4C,0},
+{0xFD4D,0xFD4D,0},
+{0xFD4E,0xFD4E,0},
+{0xFD4F,0xFD4F,0},
+{0xFD50,0xFD50,0},
+{0xFD51,0xFD51,0},
+{0xFD52,0xFD52,0},
+{0xFD53,0xFD53,0},
+{0xFD54,0xFD54,0},
+{0xFD55,0xFD55,0},
+{0xFD56,0xFD56,0},
+{0xFD57,0xFD57,0},
+{0xFD58,0xFD58,0},
+{0xFD59,0xFD59,0},
+{0xFD5A,0xFD5A,0},
+{0xFD5B,0xFD5B,0},
+{0xFD5C,0xFD5C,0},
+{0xFD5D,0xFD5D,0},
+{0xFD5E,0xFD5E,0},
+{0xFD5F,0xFD5F,0},
+{0xFD60,0xFD60,0},
+{0xFD61,0xFD61,0},
+{0xFD62,0xFD62,0},
+{0xFD63,0xFD63,0},
+{0xFD64,0xFD64,0},
+{0xFD65,0xFD65,0},
+{0xFD66,0xFD66,0},
+{0xFD67,0xFD67,0},
+{0xFD68,0xFD68,0},
+{0xFD69,0xFD69,0},
+{0xFD6A,0xFD6A,0},
+{0xFD6B,0xFD6B,0},
+{0xFD6C,0xFD6C,0},
+{0xFD6D,0xFD6D,0},
+{0xFD6E,0xFD6E,0},
+{0xFD6F,0xFD6F,0},
+{0xFD70,0xFD70,0},
+{0xFD71,0xFD71,0},
+{0xFD72,0xFD72,0},
+{0xFD73,0xFD73,0},
+{0xFD74,0xFD74,0},
+{0xFD75,0xFD75,0},
+{0xFD76,0xFD76,0},
+{0xFD77,0xFD77,0},
+{0xFD78,0xFD78,0},
+{0xFD79,0xFD79,0},
+{0xFD7A,0xFD7A,0},
+{0xFD7B,0xFD7B,0},
+{0xFD7C,0xFD7C,0},
+{0xFD7D,0xFD7D,0},
+{0xFD7E,0xFD7E,0},
+{0xFD7F,0xFD7F,0},
+{0xFD80,0xFD80,0},
+{0xFD81,0xFD81,0},
+{0xFD82,0xFD82,0},
+{0xFD83,0xFD83,0},
+{0xFD84,0xFD84,0},
+{0xFD85,0xFD85,0},
+{0xFD86,0xFD86,0},
+{0xFD87,0xFD87,0},
+{0xFD88,0xFD88,0},
+{0xFD89,0xFD89,0},
+{0xFD8A,0xFD8A,0},
+{0xFD8B,0xFD8B,0},
+{0xFD8C,0xFD8C,0},
+{0xFD8D,0xFD8D,0},
+{0xFD8E,0xFD8E,0},
+{0xFD8F,0xFD8F,0},
+{0xFD90,0xFD90,0},
+{0xFD91,0xFD91,0},
+{0xFD92,0xFD92,0},
+{0xFD93,0xFD93,0},
+{0xFD94,0xFD94,0},
+{0xFD95,0xFD95,0},
+{0xFD96,0xFD96,0},
+{0xFD97,0xFD97,0},
+{0xFD98,0xFD98,0},
+{0xFD99,0xFD99,0},
+{0xFD9A,0xFD9A,0},
+{0xFD9B,0xFD9B,0},
+{0xFD9C,0xFD9C,0},
+{0xFD9D,0xFD9D,0},
+{0xFD9E,0xFD9E,0},
+{0xFD9F,0xFD9F,0},
+{0xFDA0,0xFDA0,0},
+{0xFDA1,0xFDA1,0},
+{0xFDA2,0xFDA2,0},
+{0xFDA3,0xFDA3,0},
+{0xFDA4,0xFDA4,0},
+{0xFDA5,0xFDA5,0},
+{0xFDA6,0xFDA6,0},
+{0xFDA7,0xFDA7,0},
+{0xFDA8,0xFDA8,0},
+{0xFDA9,0xFDA9,0},
+{0xFDAA,0xFDAA,0},
+{0xFDAB,0xFDAB,0},
+{0xFDAC,0xFDAC,0},
+{0xFDAD,0xFDAD,0},
+{0xFDAE,0xFDAE,0},
+{0xFDAF,0xFDAF,0},
+{0xFDB0,0xFDB0,0},
+{0xFDB1,0xFDB1,0},
+{0xFDB2,0xFDB2,0},
+{0xFDB3,0xFDB3,0},
+{0xFDB4,0xFDB4,0},
+{0xFDB5,0xFDB5,0},
+{0xFDB6,0xFDB6,0},
+{0xFDB7,0xFDB7,0},
+{0xFDB8,0xFDB8,0},
+{0xFDB9,0xFDB9,0},
+{0xFDBA,0xFDBA,0},
+{0xFDBB,0xFDBB,0},
+{0xFDBC,0xFDBC,0},
+{0xFDBD,0xFDBD,0},
+{0xFDBE,0xFDBE,0},
+{0xFDBF,0xFDBF,0},
+{0xFDC0,0xFDC0,0},
+{0xFDC1,0xFDC1,0},
+{0xFDC2,0xFDC2,0},
+{0xFDC3,0xFDC3,0},
+{0xFDC4,0xFDC4,0},
+{0xFDC5,0xFDC5,0},
+{0xFDC6,0xFDC6,0},
+{0xFDC7,0xFDC7,0},
+{0xFDC8,0xFDC8,0},
+{0xFDC9,0xFDC9,0},
+{0xFDCA,0xFDCA,0},
+{0xFDCB,0xFDCB,0},
+{0xFDCC,0xFDCC,0},
+{0xFDCD,0xFDCD,0},
+{0xFDCE,0xFDCE,0},
+{0xFDCF,0xFDCF,0},
+{0xFDD0,0xFDD0,0},
+{0xFDD1,0xFDD1,0},
+{0xFDD2,0xFDD2,0},
+{0xFDD3,0xFDD3,0},
+{0xFDD4,0xFDD4,0},
+{0xFDD5,0xFDD5,0},
+{0xFDD6,0xFDD6,0},
+{0xFDD7,0xFDD7,0},
+{0xFDD8,0xFDD8,0},
+{0xFDD9,0xFDD9,0},
+{0xFDDA,0xFDDA,0},
+{0xFDDB,0xFDDB,0},
+{0xFDDC,0xFDDC,0},
+{0xFDDD,0xFDDD,0},
+{0xFDDE,0xFDDE,0},
+{0xFDDF,0xFDDF,0},
+{0xFDE0,0xFDE0,0},
+{0xFDE1,0xFDE1,0},
+{0xFDE2,0xFDE2,0},
+{0xFDE3,0xFDE3,0},
+{0xFDE4,0xFDE4,0},
+{0xFDE5,0xFDE5,0},
+{0xFDE6,0xFDE6,0},
+{0xFDE7,0xFDE7,0},
+{0xFDE8,0xFDE8,0},
+{0xFDE9,0xFDE9,0},
+{0xFDEA,0xFDEA,0},
+{0xFDEB,0xFDEB,0},
+{0xFDEC,0xFDEC,0},
+{0xFDED,0xFDED,0},
+{0xFDEE,0xFDEE,0},
+{0xFDEF,0xFDEF,0},
+{0xFDF0,0xFDF0,0},
+{0xFDF1,0xFDF1,0},
+{0xFDF2,0xFDF2,0},
+{0xFDF3,0xFDF3,0},
+{0xFDF4,0xFDF4,0},
+{0xFDF5,0xFDF5,0},
+{0xFDF6,0xFDF6,0},
+{0xFDF7,0xFDF7,0},
+{0xFDF8,0xFDF8,0},
+{0xFDF9,0xFDF9,0},
+{0xFDFA,0xFDFA,0},
+{0xFDFB,0xFDFB,0},
+{0xFDFC,0xFDFC,0},
+{0xFDFD,0xFDFD,0},
+{0xFDFE,0xFDFE,0},
+{0xFDFF,0xFDFF,0},
+{0xFE00,0xFE00,0},
+{0xFE01,0xFE01,0},
+{0xFE02,0xFE02,0},
+{0xFE03,0xFE03,0},
+{0xFE04,0xFE04,0},
+{0xFE05,0xFE05,0},
+{0xFE06,0xFE06,0},
+{0xFE07,0xFE07,0},
+{0xFE08,0xFE08,0},
+{0xFE09,0xFE09,0},
+{0xFE0A,0xFE0A,0},
+{0xFE0B,0xFE0B,0},
+{0xFE0C,0xFE0C,0},
+{0xFE0D,0xFE0D,0},
+{0xFE0E,0xFE0E,0},
+{0xFE0F,0xFE0F,0},
+{0xFE10,0xFE10,0},
+{0xFE11,0xFE11,0},
+{0xFE12,0xFE12,0},
+{0xFE13,0xFE13,0},
+{0xFE14,0xFE14,0},
+{0xFE15,0xFE15,0},
+{0xFE16,0xFE16,0},
+{0xFE17,0xFE17,0},
+{0xFE18,0xFE18,0},
+{0xFE19,0xFE19,0},
+{0xFE1A,0xFE1A,0},
+{0xFE1B,0xFE1B,0},
+{0xFE1C,0xFE1C,0},
+{0xFE1D,0xFE1D,0},
+{0xFE1E,0xFE1E,0},
+{0xFE1F,0xFE1F,0},
+{0xFE20,0xFE20,0},
+{0xFE21,0xFE21,0},
+{0xFE22,0xFE22,0},
+{0xFE23,0xFE23,0},
+{0xFE24,0xFE24,0},
+{0xFE25,0xFE25,0},
+{0xFE26,0xFE26,0},
+{0xFE27,0xFE27,0},
+{0xFE28,0xFE28,0},
+{0xFE29,0xFE29,0},
+{0xFE2A,0xFE2A,0},
+{0xFE2B,0xFE2B,0},
+{0xFE2C,0xFE2C,0},
+{0xFE2D,0xFE2D,0},
+{0xFE2E,0xFE2E,0},
+{0xFE2F,0xFE2F,0},
+{0xFE30,0xFE30,0},
+{0xFE31,0xFE31,0},
+{0xFE32,0xFE32,0},
+{0xFE33,0xFE33,0},
+{0xFE34,0xFE34,0},
+{0xFE35,0xFE35,0},
+{0xFE36,0xFE36,0},
+{0xFE37,0xFE37,0},
+{0xFE38,0xFE38,0},
+{0xFE39,0xFE39,0},
+{0xFE3A,0xFE3A,0},
+{0xFE3B,0xFE3B,0},
+{0xFE3C,0xFE3C,0},
+{0xFE3D,0xFE3D,0},
+{0xFE3E,0xFE3E,0},
+{0xFE3F,0xFE3F,0},
+{0xFE40,0xFE40,0},
+{0xFE41,0xFE41,0},
+{0xFE42,0xFE42,0},
+{0xFE43,0xFE43,0},
+{0xFE44,0xFE44,0},
+{0xFE45,0xFE45,0},
+{0xFE46,0xFE46,0},
+{0xFE47,0xFE47,0},
+{0xFE48,0xFE48,0},
+{0xFE49,0xFE49,0},
+{0xFE4A,0xFE4A,0},
+{0xFE4B,0xFE4B,0},
+{0xFE4C,0xFE4C,0},
+{0xFE4D,0xFE4D,0},
+{0xFE4E,0xFE4E,0},
+{0xFE4F,0xFE4F,0},
+{0xFE50,0xFE50,0},
+{0xFE51,0xFE51,0},
+{0xFE52,0xFE52,0},
+{0xFE53,0xFE53,0},
+{0xFE54,0xFE54,0},
+{0xFE55,0xFE55,0},
+{0xFE56,0xFE56,0},
+{0xFE57,0xFE57,0},
+{0xFE58,0xFE58,0},
+{0xFE59,0xFE59,0},
+{0xFE5A,0xFE5A,0},
+{0xFE5B,0xFE5B,0},
+{0xFE5C,0xFE5C,0},
+{0xFE5D,0xFE5D,0},
+{0xFE5E,0xFE5E,0},
+{0xFE5F,0xFE5F,0},
+{0xFE60,0xFE60,0},
+{0xFE61,0xFE61,0},
+{0xFE62,0xFE62,0},
+{0xFE63,0xFE63,0},
+{0xFE64,0xFE64,0},
+{0xFE65,0xFE65,0},
+{0xFE66,0xFE66,0},
+{0xFE67,0xFE67,0},
+{0xFE68,0xFE68,0},
+{0xFE69,0xFE69,0},
+{0xFE6A,0xFE6A,0},
+{0xFE6B,0xFE6B,0},
+{0xFE6C,0xFE6C,0},
+{0xFE6D,0xFE6D,0},
+{0xFE6E,0xFE6E,0},
+{0xFE6F,0xFE6F,0},
+{0xFE70,0xFE70,0},
+{0xFE71,0xFE71,0},
+{0xFE72,0xFE72,0},
+{0xFE73,0xFE73,0},
+{0xFE74,0xFE74,0},
+{0xFE75,0xFE75,0},
+{0xFE76,0xFE76,0},
+{0xFE77,0xFE77,0},
+{0xFE78,0xFE78,0},
+{0xFE79,0xFE79,0},
+{0xFE7A,0xFE7A,0},
+{0xFE7B,0xFE7B,0},
+{0xFE7C,0xFE7C,0},
+{0xFE7D,0xFE7D,0},
+{0xFE7E,0xFE7E,0},
+{0xFE7F,0xFE7F,0},
+{0xFE80,0xFE80,0},
+{0xFE81,0xFE81,0},
+{0xFE82,0xFE82,0},
+{0xFE83,0xFE83,0},
+{0xFE84,0xFE84,0},
+{0xFE85,0xFE85,0},
+{0xFE86,0xFE86,0},
+{0xFE87,0xFE87,0},
+{0xFE88,0xFE88,0},
+{0xFE89,0xFE89,0},
+{0xFE8A,0xFE8A,0},
+{0xFE8B,0xFE8B,0},
+{0xFE8C,0xFE8C,0},
+{0xFE8D,0xFE8D,0},
+{0xFE8E,0xFE8E,0},
+{0xFE8F,0xFE8F,0},
+{0xFE90,0xFE90,0},
+{0xFE91,0xFE91,0},
+{0xFE92,0xFE92,0},
+{0xFE93,0xFE93,0},
+{0xFE94,0xFE94,0},
+{0xFE95,0xFE95,0},
+{0xFE96,0xFE96,0},
+{0xFE97,0xFE97,0},
+{0xFE98,0xFE98,0},
+{0xFE99,0xFE99,0},
+{0xFE9A,0xFE9A,0},
+{0xFE9B,0xFE9B,0},
+{0xFE9C,0xFE9C,0},
+{0xFE9D,0xFE9D,0},
+{0xFE9E,0xFE9E,0},
+{0xFE9F,0xFE9F,0},
+{0xFEA0,0xFEA0,0},
+{0xFEA1,0xFEA1,0},
+{0xFEA2,0xFEA2,0},
+{0xFEA3,0xFEA3,0},
+{0xFEA4,0xFEA4,0},
+{0xFEA5,0xFEA5,0},
+{0xFEA6,0xFEA6,0},
+{0xFEA7,0xFEA7,0},
+{0xFEA8,0xFEA8,0},
+{0xFEA9,0xFEA9,0},
+{0xFEAA,0xFEAA,0},
+{0xFEAB,0xFEAB,0},
+{0xFEAC,0xFEAC,0},
+{0xFEAD,0xFEAD,0},
+{0xFEAE,0xFEAE,0},
+{0xFEAF,0xFEAF,0},
+{0xFEB0,0xFEB0,0},
+{0xFEB1,0xFEB1,0},
+{0xFEB2,0xFEB2,0},
+{0xFEB3,0xFEB3,0},
+{0xFEB4,0xFEB4,0},
+{0xFEB5,0xFEB5,0},
+{0xFEB6,0xFEB6,0},
+{0xFEB7,0xFEB7,0},
+{0xFEB8,0xFEB8,0},
+{0xFEB9,0xFEB9,0},
+{0xFEBA,0xFEBA,0},
+{0xFEBB,0xFEBB,0},
+{0xFEBC,0xFEBC,0},
+{0xFEBD,0xFEBD,0},
+{0xFEBE,0xFEBE,0},
+{0xFEBF,0xFEBF,0},
+{0xFEC0,0xFEC0,0},
+{0xFEC1,0xFEC1,0},
+{0xFEC2,0xFEC2,0},
+{0xFEC3,0xFEC3,0},
+{0xFEC4,0xFEC4,0},
+{0xFEC5,0xFEC5,0},
+{0xFEC6,0xFEC6,0},
+{0xFEC7,0xFEC7,0},
+{0xFEC8,0xFEC8,0},
+{0xFEC9,0xFEC9,0},
+{0xFECA,0xFECA,0},
+{0xFECB,0xFECB,0},
+{0xFECC,0xFECC,0},
+{0xFECD,0xFECD,0},
+{0xFECE,0xFECE,0},
+{0xFECF,0xFECF,0},
+{0xFED0,0xFED0,0},
+{0xFED1,0xFED1,0},
+{0xFED2,0xFED2,0},
+{0xFED3,0xFED3,0},
+{0xFED4,0xFED4,0},
+{0xFED5,0xFED5,0},
+{0xFED6,0xFED6,0},
+{0xFED7,0xFED7,0},
+{0xFED8,0xFED8,0},
+{0xFED9,0xFED9,0},
+{0xFEDA,0xFEDA,0},
+{0xFEDB,0xFEDB,0},
+{0xFEDC,0xFEDC,0},
+{0xFEDD,0xFEDD,0},
+{0xFEDE,0xFEDE,0},
+{0xFEDF,0xFEDF,0},
+{0xFEE0,0xFEE0,0},
+{0xFEE1,0xFEE1,0},
+{0xFEE2,0xFEE2,0},
+{0xFEE3,0xFEE3,0},
+{0xFEE4,0xFEE4,0},
+{0xFEE5,0xFEE5,0},
+{0xFEE6,0xFEE6,0},
+{0xFEE7,0xFEE7,0},
+{0xFEE8,0xFEE8,0},
+{0xFEE9,0xFEE9,0},
+{0xFEEA,0xFEEA,0},
+{0xFEEB,0xFEEB,0},
+{0xFEEC,0xFEEC,0},
+{0xFEED,0xFEED,0},
+{0xFEEE,0xFEEE,0},
+{0xFEEF,0xFEEF,0},
+{0xFEF0,0xFEF0,0},
+{0xFEF1,0xFEF1,0},
+{0xFEF2,0xFEF2,0},
+{0xFEF3,0xFEF3,0},
+{0xFEF4,0xFEF4,0},
+{0xFEF5,0xFEF5,0},
+{0xFEF6,0xFEF6,0},
+{0xFEF7,0xFEF7,0},
+{0xFEF8,0xFEF8,0},
+{0xFEF9,0xFEF9,0},
+{0xFEFA,0xFEFA,0},
+{0xFEFB,0xFEFB,0},
+{0xFEFC,0xFEFC,0},
+{0xFEFD,0xFEFD,0},
+{0xFEFE,0xFEFE,0},
+{0xFEFF,0xFEFF,0},
+{0xFF00,0xFF00,0},
+{0xFF01,0xFF01,0},
+{0xFF02,0xFF02,0},
+{0xFF03,0xFF03,0},
+{0xFF04,0xFF04,0},
+{0xFF05,0xFF05,0},
+{0xFF06,0xFF06,0},
+{0xFF07,0xFF07,0},
+{0xFF08,0xFF08,0},
+{0xFF09,0xFF09,0},
+{0xFF0A,0xFF0A,0},
+{0xFF0B,0xFF0B,0},
+{0xFF0C,0xFF0C,0},
+{0xFF0D,0xFF0D,0},
+{0xFF0E,0xFF0E,0},
+{0xFF0F,0xFF0F,0},
+{0xFF10,0xFF10,0},
+{0xFF11,0xFF11,0},
+{0xFF12,0xFF12,0},
+{0xFF13,0xFF13,0},
+{0xFF14,0xFF14,0},
+{0xFF15,0xFF15,0},
+{0xFF16,0xFF16,0},
+{0xFF17,0xFF17,0},
+{0xFF18,0xFF18,0},
+{0xFF19,0xFF19,0},
+{0xFF1A,0xFF1A,0},
+{0xFF1B,0xFF1B,0},
+{0xFF1C,0xFF1C,0},
+{0xFF1D,0xFF1D,0},
+{0xFF1E,0xFF1E,0},
+{0xFF1F,0xFF1F,0},
+{0xFF20,0xFF20,0},
+{0xFF41,0xFF21,UNI_UPPER},
+{0xFF42,0xFF22,UNI_UPPER},
+{0xFF43,0xFF23,UNI_UPPER},
+{0xFF44,0xFF24,UNI_UPPER},
+{0xFF45,0xFF25,UNI_UPPER},
+{0xFF46,0xFF26,UNI_UPPER},
+{0xFF47,0xFF27,UNI_UPPER},
+{0xFF48,0xFF28,UNI_UPPER},
+{0xFF49,0xFF29,UNI_UPPER},
+{0xFF4A,0xFF2A,UNI_UPPER},
+{0xFF4B,0xFF2B,UNI_UPPER},
+{0xFF4C,0xFF2C,UNI_UPPER},
+{0xFF4D,0xFF2D,UNI_UPPER},
+{0xFF4E,0xFF2E,UNI_UPPER},
+{0xFF4F,0xFF2F,UNI_UPPER},
+{0xFF50,0xFF30,UNI_UPPER},
+{0xFF51,0xFF31,UNI_UPPER},
+{0xFF52,0xFF32,UNI_UPPER},
+{0xFF53,0xFF33,UNI_UPPER},
+{0xFF54,0xFF34,UNI_UPPER},
+{0xFF55,0xFF35,UNI_UPPER},
+{0xFF56,0xFF36,UNI_UPPER},
+{0xFF57,0xFF37,UNI_UPPER},
+{0xFF58,0xFF38,UNI_UPPER},
+{0xFF59,0xFF39,UNI_UPPER},
+{0xFF5A,0xFF3A,UNI_UPPER},
+{0xFF3B,0xFF3B,0},
+{0xFF3C,0xFF3C,0},
+{0xFF3D,0xFF3D,0},
+{0xFF3E,0xFF3E,0},
+{0xFF3F,0xFF3F,0},
+{0xFF40,0xFF40,0},
+{0xFF41,0xFF21,UNI_LOWER},
+{0xFF42,0xFF22,UNI_LOWER},
+{0xFF43,0xFF23,UNI_LOWER},
+{0xFF44,0xFF24,UNI_LOWER},
+{0xFF45,0xFF25,UNI_LOWER},
+{0xFF46,0xFF26,UNI_LOWER},
+{0xFF47,0xFF27,UNI_LOWER},
+{0xFF48,0xFF28,UNI_LOWER},
+{0xFF49,0xFF29,UNI_LOWER},
+{0xFF4A,0xFF2A,UNI_LOWER},
+{0xFF4B,0xFF2B,UNI_LOWER},
+{0xFF4C,0xFF2C,UNI_LOWER},
+{0xFF4D,0xFF2D,UNI_LOWER},
+{0xFF4E,0xFF2E,UNI_LOWER},
+{0xFF4F,0xFF2F,UNI_LOWER},
+{0xFF50,0xFF30,UNI_LOWER},
+{0xFF51,0xFF31,UNI_LOWER},
+{0xFF52,0xFF32,UNI_LOWER},
+{0xFF53,0xFF33,UNI_LOWER},
+{0xFF54,0xFF34,UNI_LOWER},
+{0xFF55,0xFF35,UNI_LOWER},
+{0xFF56,0xFF36,UNI_LOWER},
+{0xFF57,0xFF37,UNI_LOWER},
+{0xFF58,0xFF38,UNI_LOWER},
+{0xFF59,0xFF39,UNI_LOWER},
+{0xFF5A,0xFF3A,UNI_LOWER},
+{0xFF5B,0xFF5B,0},
+{0xFF5C,0xFF5C,0},
+{0xFF5D,0xFF5D,0},
+{0xFF5E,0xFF5E,0},
+{0xFF5F,0xFF5F,0},
+{0xFF60,0xFF60,0},
+{0xFF61,0xFF61,0},
+{0xFF62,0xFF62,0},
+{0xFF63,0xFF63,0},
+{0xFF64,0xFF64,0},
+{0xFF65,0xFF65,0},
+{0xFF66,0xFF66,0},
+{0xFF67,0xFF67,0},
+{0xFF68,0xFF68,0},
+{0xFF69,0xFF69,0},
+{0xFF6A,0xFF6A,0},
+{0xFF6B,0xFF6B,0},
+{0xFF6C,0xFF6C,0},
+{0xFF6D,0xFF6D,0},
+{0xFF6E,0xFF6E,0},
+{0xFF6F,0xFF6F,0},
+{0xFF70,0xFF70,0},
+{0xFF71,0xFF71,0},
+{0xFF72,0xFF72,0},
+{0xFF73,0xFF73,0},
+{0xFF74,0xFF74,0},
+{0xFF75,0xFF75,0},
+{0xFF76,0xFF76,0},
+{0xFF77,0xFF77,0},
+{0xFF78,0xFF78,0},
+{0xFF79,0xFF79,0},
+{0xFF7A,0xFF7A,0},
+{0xFF7B,0xFF7B,0},
+{0xFF7C,0xFF7C,0},
+{0xFF7D,0xFF7D,0},
+{0xFF7E,0xFF7E,0},
+{0xFF7F,0xFF7F,0},
+{0xFF80,0xFF80,0},
+{0xFF81,0xFF81,0},
+{0xFF82,0xFF82,0},
+{0xFF83,0xFF83,0},
+{0xFF84,0xFF84,0},
+{0xFF85,0xFF85,0},
+{0xFF86,0xFF86,0},
+{0xFF87,0xFF87,0},
+{0xFF88,0xFF88,0},
+{0xFF89,0xFF89,0},
+{0xFF8A,0xFF8A,0},
+{0xFF8B,0xFF8B,0},
+{0xFF8C,0xFF8C,0},
+{0xFF8D,0xFF8D,0},
+{0xFF8E,0xFF8E,0},
+{0xFF8F,0xFF8F,0},
+{0xFF90,0xFF90,0},
+{0xFF91,0xFF91,0},
+{0xFF92,0xFF92,0},
+{0xFF93,0xFF93,0},
+{0xFF94,0xFF94,0},
+{0xFF95,0xFF95,0},
+{0xFF96,0xFF96,0},
+{0xFF97,0xFF97,0},
+{0xFF98,0xFF98,0},
+{0xFF99,0xFF99,0},
+{0xFF9A,0xFF9A,0},
+{0xFF9B,0xFF9B,0},
+{0xFF9C,0xFF9C,0},
+{0xFF9D,0xFF9D,0},
+{0xFF9E,0xFF9E,0},
+{0xFF9F,0xFF9F,0},
+{0xFFA0,0xFFA0,0},
+{0xFFA1,0xFFA1,0},
+{0xFFA2,0xFFA2,0},
+{0xFFA3,0xFFA3,0},
+{0xFFA4,0xFFA4,0},
+{0xFFA5,0xFFA5,0},
+{0xFFA6,0xFFA6,0},
+{0xFFA7,0xFFA7,0},
+{0xFFA8,0xFFA8,0},
+{0xFFA9,0xFFA9,0},
+{0xFFAA,0xFFAA,0},
+{0xFFAB,0xFFAB,0},
+{0xFFAC,0xFFAC,0},
+{0xFFAD,0xFFAD,0},
+{0xFFAE,0xFFAE,0},
+{0xFFAF,0xFFAF,0},
+{0xFFB0,0xFFB0,0},
+{0xFFB1,0xFFB1,0},
+{0xFFB2,0xFFB2,0},
+{0xFFB3,0xFFB3,0},
+{0xFFB4,0xFFB4,0},
+{0xFFB5,0xFFB5,0},
+{0xFFB6,0xFFB6,0},
+{0xFFB7,0xFFB7,0},
+{0xFFB8,0xFFB8,0},
+{0xFFB9,0xFFB9,0},
+{0xFFBA,0xFFBA,0},
+{0xFFBB,0xFFBB,0},
+{0xFFBC,0xFFBC,0},
+{0xFFBD,0xFFBD,0},
+{0xFFBE,0xFFBE,0},
+{0xFFBF,0xFFBF,0},
+{0xFFC0,0xFFC0,0},
+{0xFFC1,0xFFC1,0},
+{0xFFC2,0xFFC2,0},
+{0xFFC3,0xFFC3,0},
+{0xFFC4,0xFFC4,0},
+{0xFFC5,0xFFC5,0},
+{0xFFC6,0xFFC6,0},
+{0xFFC7,0xFFC7,0},
+{0xFFC8,0xFFC8,0},
+{0xFFC9,0xFFC9,0},
+{0xFFCA,0xFFCA,0},
+{0xFFCB,0xFFCB,0},
+{0xFFCC,0xFFCC,0},
+{0xFFCD,0xFFCD,0},
+{0xFFCE,0xFFCE,0},
+{0xFFCF,0xFFCF,0},
+{0xFFD0,0xFFD0,0},
+{0xFFD1,0xFFD1,0},
+{0xFFD2,0xFFD2,0},
+{0xFFD3,0xFFD3,0},
+{0xFFD4,0xFFD4,0},
+{0xFFD5,0xFFD5,0},
+{0xFFD6,0xFFD6,0},
+{0xFFD7,0xFFD7,0},
+{0xFFD8,0xFFD8,0},
+{0xFFD9,0xFFD9,0},
+{0xFFDA,0xFFDA,0},
+{0xFFDB,0xFFDB,0},
+{0xFFDC,0xFFDC,0},
+{0xFFDD,0xFFDD,0},
+{0xFFDE,0xFFDE,0},
+{0xFFDF,0xFFDF,0},
+{0xFFE0,0xFFE0,0},
+{0xFFE1,0xFFE1,0},
+{0xFFE2,0xFFE2,0},
+{0xFFE3,0xFFE3,0},
+{0xFFE4,0xFFE4,0},
+{0xFFE5,0xFFE5,0},
+{0xFFE6,0xFFE6,0},
+{0xFFE7,0xFFE7,0},
+{0xFFE8,0xFFE8,0},
+{0xFFE9,0xFFE9,0},
+{0xFFEA,0xFFEA,0},
+{0xFFEB,0xFFEB,0},
+{0xFFEC,0xFFEC,0},
+{0xFFED,0xFFED,0},
+{0xFFEE,0xFFEE,0},
+{0xFFEF,0xFFEF,0},
+{0xFFF0,0xFFF0,0},
+{0xFFF1,0xFFF1,0},
+{0xFFF2,0xFFF2,0},
+{0xFFF3,0xFFF3,0},
+{0xFFF4,0xFFF4,0},
+{0xFFF5,0xFFF5,0},
+{0xFFF6,0xFFF6,0},
+{0xFFF7,0xFFF7,0},
+{0xFFF8,0xFFF8,0},
+{0xFFF9,0xFFF9,0},
+{0xFFFA,0xFFFA,0},
+{0xFFFB,0xFFFB,0},
+{0xFFFC,0xFFFC,0},
+{0xFFFD,0xFFFD,0},
+{0xFFFE,0xFFFE,0},
+{0xFFFF,0xFFFF,0},
diff --git a/source/include/util_getent.h b/source/include/util_getent.h
index b67758ba230..5d4674ddefa 100644
--- a/source/include/util_getent.h
+++ b/source/include/util_getent.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Samba utility functions
Copyright (C) Simo Sorce 2001
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 8caf64fd99d..9e5c8659526 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -1,10 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
VFS structures and parameters
- Copyright (C) Jeremy Allison 1999-2003
- Copyright (C) Tim Potter 1999
- Copyright (C) Alexander Bokovoy 2002
- Copyright (C) Stefan (metze) Metzmacher 2003
+ Copyright (C) Tim Potter 1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,8 +17,6 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- This work was sponsored by Optifacio Software Services, Inc.
*/
#ifndef _VFS_H
@@ -45,445 +41,101 @@
/* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */
/* Changed to version 3 for POSIX acl extensions. JRA. */
-/* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */
-/* Changed to version 5 for sendfile addition. JRA. */
-/* Changed to version 6 for the new module system, fixed cascading and quota functions. --metze */
-/* Changed to version 7 to include the get_nt_acl info parameter. JRA. */
-/* Changed to version 8 includes EA calls. JRA. */
-/* Changed to version 9 to include the get_shadow_data call. --metze */
-/* Changed to version 10 to include pread/pwrite calls. */
-#define SMB_VFS_INTERFACE_VERSION 10
-
-
-/* to bug old modules witch are trying to compile with the old functions */
-#define vfs_init __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore(void) { __ERROR_please_port_this_module_to_SMB_VFS_INTERFACE_VERSION_8_donot_use_vfs_init_anymore };
-#define lp_parm_string __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string { \
- __ERROR_please_port_lp_parm_string_to_lp_parm_const_string_or_lp_parm_talloc_string };
-#define lp_vfs_options __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead { \
- __ERROR_please_donot_use_lp_vfs_options_anymore_use_lp_parm_xxxx_functions_instead };
-
-/*
- All intercepted VFS operations must be declared as static functions inside module source
- in order to keep smbd namespace unpolluted. See source of audit, extd_audit, fake_perms and recycle
- example VFS modules for more details.
-*/
+/* Changed to version 4 for sendfile extension. JRA. */
+#define SMB_VFS_INTERFACE_VERSION 4
/* VFS operations structure */
-struct vfs_handle_struct;
struct connection_struct;
struct files_struct;
struct security_descriptor_info;
-/*
- Available VFS operations. These values must be in sync with vfs_ops struct
- (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops).
- In particular, if new operations are added to vfs_ops, appropriate constants
- should be added to vfs_op_type so that order of them kept same as in vfs_ops.
-*/
+struct vfs_ops {
-typedef enum _vfs_op_type {
- SMB_VFS_OP_NOOP = -1,
-
/* Disk operations */
-
- SMB_VFS_OP_CONNECT = 0,
- SMB_VFS_OP_DISCONNECT,
- SMB_VFS_OP_DISK_FREE,
- SMB_VFS_OP_GET_QUOTA,
- SMB_VFS_OP_SET_QUOTA,
- SMB_VFS_OP_GET_SHADOW_COPY_DATA,
-
-
+
+ int (*connect)(struct connection_struct *conn, const char *service, const char *user);
+ void (*disconnect)(struct connection_struct *conn);
+ SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
+
/* Directory operations */
- SMB_VFS_OP_OPENDIR,
- SMB_VFS_OP_READDIR,
- SMB_VFS_OP_MKDIR,
- SMB_VFS_OP_RMDIR,
- SMB_VFS_OP_CLOSEDIR,
-
+ DIR *(*opendir)(struct connection_struct *conn, const char *fname);
+ struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp);
+ int (*mkdir)(struct connection_struct *conn, const char *path, mode_t mode);
+ int (*rmdir)(struct connection_struct *conn, const char *path);
+ int (*closedir)(struct connection_struct *conn, DIR *dir);
+
/* File operations */
-
- SMB_VFS_OP_OPEN,
- SMB_VFS_OP_CLOSE,
- SMB_VFS_OP_READ,
- SMB_VFS_OP_PREAD,
- SMB_VFS_OP_WRITE,
- SMB_VFS_OP_PWRITE,
- SMB_VFS_OP_LSEEK,
- SMB_VFS_OP_SENDFILE,
- SMB_VFS_OP_RENAME,
- SMB_VFS_OP_FSYNC,
- SMB_VFS_OP_STAT,
- SMB_VFS_OP_FSTAT,
- SMB_VFS_OP_LSTAT,
- SMB_VFS_OP_UNLINK,
- SMB_VFS_OP_CHMOD,
- SMB_VFS_OP_FCHMOD,
- SMB_VFS_OP_CHOWN,
- SMB_VFS_OP_FCHOWN,
- SMB_VFS_OP_CHDIR,
- SMB_VFS_OP_GETWD,
- SMB_VFS_OP_UTIME,
- SMB_VFS_OP_FTRUNCATE,
- SMB_VFS_OP_LOCK,
- SMB_VFS_OP_SYMLINK,
- SMB_VFS_OP_READLINK,
- SMB_VFS_OP_LINK,
- SMB_VFS_OP_MKNOD,
- SMB_VFS_OP_REALPATH,
+
+ int (*open)(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
+ int (*close)(struct files_struct *fsp, int fd);
+ ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n);
+ ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n);
+ SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
+ ssize_t (*sendfile)(int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
+ int (*rename)(struct connection_struct *conn, const char *old, const char *new);
+ int (*fsync)(struct files_struct *fsp, int fd);
+ int (*stat)(struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
+ int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+ int (*lstat)(struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
+ int (*unlink)(struct connection_struct *conn, const char *path);
+ int (*chmod)(struct connection_struct *conn, const char *path, mode_t mode);
+ int (*fchmod)(struct files_struct *fsp, int fd, mode_t mode);
+ int (*chown)(struct connection_struct *conn, const char *path, uid_t uid, gid_t gid);
+ int (*fchown)(struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
+ int (*chdir)(struct connection_struct *conn, const char *path);
+ char *(*getwd)(struct connection_struct *conn, char *buf);
+ int (*utime)(struct connection_struct *conn, const char *path, struct utimbuf *times);
+ int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset);
+ BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+ int (*symlink)(struct connection_struct *conn, const char *oldpath, const char *newpath);
+ int (*readlink)(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
+ int (*link)(struct connection_struct *conn, const char *oldpath, const char *newpath);
+ int (*mknod)(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
+ char *(*realpath)(struct connection_struct *conn, const char *path, char *resolved_path);
/* NT ACL operations. */
- SMB_VFS_OP_FGET_NT_ACL,
- SMB_VFS_OP_GET_NT_ACL,
- SMB_VFS_OP_FSET_NT_ACL,
- SMB_VFS_OP_SET_NT_ACL,
+ size_t (*fget_nt_acl)(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc);
+ size_t (*get_nt_acl)(struct files_struct *fsp, const char *name, struct security_descriptor_info **ppdesc);
+ BOOL (*fset_nt_acl)(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
+ BOOL (*set_nt_acl)(struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
/* POSIX ACL operations. */
- SMB_VFS_OP_CHMOD_ACL,
- SMB_VFS_OP_FCHMOD_ACL,
-
- SMB_VFS_OP_SYS_ACL_GET_ENTRY,
- SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
- SMB_VFS_OP_SYS_ACL_GET_PERMSET,
- SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
- SMB_VFS_OP_SYS_ACL_GET_FILE,
- SMB_VFS_OP_SYS_ACL_GET_FD,
- SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
- SMB_VFS_OP_SYS_ACL_ADD_PERM,
- SMB_VFS_OP_SYS_ACL_TO_TEXT,
- SMB_VFS_OP_SYS_ACL_INIT,
- SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
- SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
- SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
- SMB_VFS_OP_SYS_ACL_SET_PERMSET,
- SMB_VFS_OP_SYS_ACL_VALID,
- SMB_VFS_OP_SYS_ACL_SET_FILE,
- SMB_VFS_OP_SYS_ACL_SET_FD,
- SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
- SMB_VFS_OP_SYS_ACL_GET_PERM,
- SMB_VFS_OP_SYS_ACL_FREE_TEXT,
- SMB_VFS_OP_SYS_ACL_FREE_ACL,
- SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
-
- /* EA operations. */
- SMB_VFS_OP_GETXATTR,
- SMB_VFS_OP_LGETXATTR,
- SMB_VFS_OP_FGETXATTR,
- SMB_VFS_OP_LISTXATTR,
- SMB_VFS_OP_LLISTXATTR,
- SMB_VFS_OP_FLISTXATTR,
- SMB_VFS_OP_REMOVEXATTR,
- SMB_VFS_OP_LREMOVEXATTR,
- SMB_VFS_OP_FREMOVEXATTR,
- SMB_VFS_OP_SETXATTR,
- SMB_VFS_OP_LSETXATTR,
- SMB_VFS_OP_FSETXATTR,
-
- /* This should always be last enum value */
-
- SMB_VFS_OP_LAST
-} vfs_op_type;
-
-/*
- Please keep vfs_op_type, struct vfs_fn_pointers and struct vfs_handles_pointers in sync.
-*/
-struct vfs_ops {
- struct vfs_fn_pointers {
- /* Disk operations */
-
- int (*connect)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user);
- void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn);
- SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
- int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
- int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
- int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels);
-
- /* Directory operations */
-
- DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname);
- struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
- int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
- int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir);
-
- /* File operations */
-
- int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode);
- int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
- ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n);
- ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset);
- ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n);
- ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset);
- SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence);
- ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
- int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new);
- int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
- int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
- int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
- int (*lstat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
- int (*unlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*chmod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
- int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
- int (*chown)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid);
- int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
- int (*chdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- char *(*getwd)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *buf);
- int (*utime)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct utimbuf *times);
- int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
- BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
- int (*symlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*readlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
- int (*link)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*mknod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
- char *(*realpath)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *resolved_path);
-
- /* NT ACL operations. */
-
- size_t (*fget_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info, struct security_descriptor_info **ppdesc);
- size_t (*get_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor_info **ppdesc);
- BOOL (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
- BOOL (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
-
- /* POSIX ACL operations. */
-
- int (*chmod_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, mode_t mode);
- int (*fchmod_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
-
- int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
- int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
- int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
- void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
- SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
- SMB_ACL_T (*sys_acl_get_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
- int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
- SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, struct connection_struct *conn, int count);
- int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
- int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
- int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
- int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_valid)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl );
- int (*sys_acl_set_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
- int (*sys_acl_set_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_ACL_T theacl);
- int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- int (*sys_acl_free_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *text);
- int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T posix_acl);
- int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
-
- /* EA operations. */
- ssize_t (*getxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
- ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
- ssize_t (*fgetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size);
- ssize_t (*listxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
- ssize_t (*llistxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
- ssize_t (*flistxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size);
- int (*removexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
- int (*lremovexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
- int (*fremovexattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name);
- int (*setxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
- int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
- int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags);
-
- } ops;
-
- struct vfs_handles_pointers {
- /* Disk operations */
-
- struct vfs_handle_struct *connect;
- struct vfs_handle_struct *disconnect;
- struct vfs_handle_struct *disk_free;
- struct vfs_handle_struct *get_quota;
- struct vfs_handle_struct *set_quota;
- struct vfs_handle_struct *get_shadow_copy_data;
-
- /* Directory operations */
-
- struct vfs_handle_struct *opendir;
- struct vfs_handle_struct *readdir;
- struct vfs_handle_struct *mkdir;
- struct vfs_handle_struct *rmdir;
- struct vfs_handle_struct *closedir;
-
- /* File operations */
-
- struct vfs_handle_struct *open;
- struct vfs_handle_struct *close;
- struct vfs_handle_struct *read;
- struct vfs_handle_struct *pread;
- struct vfs_handle_struct *write;
- struct vfs_handle_struct *pwrite;
- struct vfs_handle_struct *lseek;
- struct vfs_handle_struct *sendfile;
- struct vfs_handle_struct *rename;
- struct vfs_handle_struct *fsync;
- struct vfs_handle_struct *stat;
- struct vfs_handle_struct *fstat;
- struct vfs_handle_struct *lstat;
- struct vfs_handle_struct *unlink;
- struct vfs_handle_struct *chmod;
- struct vfs_handle_struct *fchmod;
- struct vfs_handle_struct *chown;
- struct vfs_handle_struct *fchown;
- struct vfs_handle_struct *chdir;
- struct vfs_handle_struct *getwd;
- struct vfs_handle_struct *utime;
- struct vfs_handle_struct *ftruncate;
- struct vfs_handle_struct *lock;
- struct vfs_handle_struct *symlink;
- struct vfs_handle_struct *readlink;
- struct vfs_handle_struct *link;
- struct vfs_handle_struct *mknod;
- struct vfs_handle_struct *realpath;
-
- /* NT ACL operations. */
-
- struct vfs_handle_struct *fget_nt_acl;
- struct vfs_handle_struct *get_nt_acl;
- struct vfs_handle_struct *fset_nt_acl;
- struct vfs_handle_struct *set_nt_acl;
-
- /* POSIX ACL operations. */
-
- struct vfs_handle_struct *chmod_acl;
- struct vfs_handle_struct *fchmod_acl;
-
- struct vfs_handle_struct *sys_acl_get_entry;
- struct vfs_handle_struct *sys_acl_get_tag_type;
- struct vfs_handle_struct *sys_acl_get_permset;
- struct vfs_handle_struct *sys_acl_get_qualifier;
- struct vfs_handle_struct *sys_acl_get_file;
- struct vfs_handle_struct *sys_acl_get_fd;
- struct vfs_handle_struct *sys_acl_clear_perms;
- struct vfs_handle_struct *sys_acl_add_perm;
- struct vfs_handle_struct *sys_acl_to_text;
- struct vfs_handle_struct *sys_acl_init;
- struct vfs_handle_struct *sys_acl_create_entry;
- struct vfs_handle_struct *sys_acl_set_tag_type;
- struct vfs_handle_struct *sys_acl_set_qualifier;
- struct vfs_handle_struct *sys_acl_set_permset;
- struct vfs_handle_struct *sys_acl_valid;
- struct vfs_handle_struct *sys_acl_set_file;
- struct vfs_handle_struct *sys_acl_set_fd;
- struct vfs_handle_struct *sys_acl_delete_def_file;
- struct vfs_handle_struct *sys_acl_get_perm;
- struct vfs_handle_struct *sys_acl_free_text;
- struct vfs_handle_struct *sys_acl_free_acl;
- struct vfs_handle_struct *sys_acl_free_qualifier;
-
- /* EA operations. */
- struct vfs_handle_struct *getxattr;
- struct vfs_handle_struct *lgetxattr;
- struct vfs_handle_struct *fgetxattr;
- struct vfs_handle_struct *listxattr;
- struct vfs_handle_struct *llistxattr;
- struct vfs_handle_struct *flistxattr;
- struct vfs_handle_struct *removexattr;
- struct vfs_handle_struct *lremovexattr;
- struct vfs_handle_struct *fremovexattr;
- struct vfs_handle_struct *setxattr;
- struct vfs_handle_struct *lsetxattr;
- struct vfs_handle_struct *fsetxattr;
-
- } handles;
+ int (*chmod_acl)(struct connection_struct *conn, const char *name, mode_t mode);
+ int (*fchmod_acl)(struct files_struct *fsp, int fd, mode_t mode);
+
+ int (*sys_acl_get_entry)(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+ int (*sys_acl_get_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+ int (*sys_acl_get_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+ void * (*sys_acl_get_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
+ SMB_ACL_T (*sys_acl_get_file)(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
+ SMB_ACL_T (*sys_acl_get_fd)(struct files_struct *fsp, int fd);
+ int (*sys_acl_clear_perms)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_add_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ char * (*sys_acl_to_text)(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
+ SMB_ACL_T (*sys_acl_init)(struct connection_struct *conn, int count);
+ int (*sys_acl_create_entry)(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+ int (*sys_acl_set_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+ int (*sys_acl_set_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
+ int (*sys_acl_set_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_valid)(struct connection_struct *conn, SMB_ACL_T theacl );
+ int (*sys_acl_set_file)(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+ int (*sys_acl_set_fd)(struct files_struct *fsp, int fd, SMB_ACL_T theacl);
+ int (*sys_acl_delete_def_file)(struct connection_struct *conn, const char *path);
+ int (*sys_acl_get_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ int (*sys_acl_free_text)(struct connection_struct *conn, char *text);
+ int (*sys_acl_free_acl)(struct connection_struct *conn, SMB_ACL_T posix_acl);
+ int (*sys_acl_free_qualifier)(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
};
-/*
- Possible VFS operation layers (per-operation)
-
- These values are used by VFS subsystem when building vfs_ops for connection
- from multiple VFS modules. Internally, Samba differentiates only opaque and
- transparent layers at this process. Other types are used for providing better
- diagnosing facilities.
-
- Most modules will provide transparent layers. Opaque layer is for modules
- which implement actual file system calls (like DB-based VFS). For example,
- default POSIX VFS which is built in into Samba is an opaque VFS module.
-
- Other layer types (audit, splitter, scanner) were designed to provide different
- degree of transparency and for diagnosing VFS module behaviour.
-
- Each module can implement several layers at the same time provided that only
- one layer is used per each operation.
-
-*/
-
-typedef enum _vfs_op_layer {
- SMB_VFS_LAYER_NOOP = -1, /* - For using in VFS module to indicate end of array */
- /* of operations description */
- SMB_VFS_LAYER_OPAQUE = 0, /* - Final level, does not call anything beyond itself */
- SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */
- /* possibly changing passed data */
- SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging may not */
- /* use Samba VFS */
- SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */
- /* then combines result */
- SMB_VFS_LAYER_SCANNER /* - Checks data and possibly initiates additional */
- /* file activity like logging to files _inside_ samba VFS */
-} vfs_op_layer;
-
-/*
- VFS operation description. Each VFS module registers an array of vfs_op_tuple to VFS subsystem,
- which describes all operations this module is willing to intercept.
- VFS subsystem initializes then the conn->vfs_ops and conn->vfs_opaque_ops structs
- using this information.
-*/
-
-typedef struct _vfs_op_tuple {
- void* op;
- vfs_op_type type;
- vfs_op_layer layer;
-} vfs_op_tuple;
-
-
-typedef struct vfs_handle_struct {
- struct vfs_handle_struct *next, *prev;
- const char *param;
- struct vfs_ops vfs_next;
- struct connection_struct *conn;
- void *data;
- void (*free_data)(void **data);
-} vfs_handle_struct;
-
-
-#define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \
- if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \
- DEBUG(0,("%s() failed to get vfs_handle->data!\n",FUNCTION_MACRO)); \
- ret; \
- } \
-}
-
-#define SMB_VFS_HANDLE_SET_DATA(handle, datap, free_fn, type, ret) { \
- if (!(handle)) { \
- DEBUG(0,("%s() failed to set handle->data!\n",FUNCTION_MACRO)); \
- ret; \
- } else { \
- if ((handle)->free_data) { \
- (handle)->free_data(&(handle)->data); \
- } \
- (handle)->data = (void *)datap; \
- (handle)->free_data = free_fn; \
- } \
-}
-
-#define SMB_VFS_HANDLE_FREE_DATA(handle) { \
- if ((handle) && (handle)->free_data) { \
- (handle)->free_data(&(handle)->data); \
- } \
-}
-
-/* Check whether module-specific data handle was already allocated or not */
-#define SMB_VFS_HANDLE_TEST_DATA(handle) ( !(handle) || !(handle)->data ? False : True )
-
-#define SMB_VFS_OP(x) ((void *) x)
-
-
-#include "vfs_macros.h"
+struct vfs_options {
+ struct vfs_options *prev, *next;
+ char *name;
+ char *value;
+};
#endif /* _VFS_H */
diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
deleted file mode 100644
index 1ec1c5a7789..00000000000
--- a/source/include/vfs_macros.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- VFS wrapper macros
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _VFS_MACROS_H
-#define _VFS_MACROS_H
-
-/*******************************************************************
- Don't access conn->vfs.ops.* directly!!!
- Use this macros!
- (Fixes should go also into the vfs_opaque_* and vfs_next_* macros!)
-********************************************************************/
-
-/* Disk operations */
-#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect((conn)->vfs.handles.connect, (conn), (service), (user)))
-#define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect, (conn)))
-#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-
-/* Directory operations */
-#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
-#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
-#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
-
-/* File operations */
-#define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode)))
-#define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close((fsp)->conn->vfs.handles.close, (fsp), (fd)))
-#define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n)))
-#define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs.ops.write((fsp)->conn->vfs.handles.write, (fsp), (fd), (data), (n)))
-#define SMB_VFS_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pwrite((fsp)->conn->vfs.handles.pwrite, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs.ops.lseek((fsp)->conn->vfs.handles.lseek, (fsp), (fd), (offset), (whence)))
-#define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs.ops.sendfile((fsp)->conn->vfs.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (conn), (old), (new)))
-#define SMB_VFS_FSYNC(fsp, fd) ((fsp)->conn->vfs.ops.fsync((fsp)->conn->vfs.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (conn), (fname), (sbuf)))
-#define SMB_VFS_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs.ops.fstat((fsp)->conn->vfs.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (conn), (path)))
-#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (conn), (path), (mode)))
-#define SMB_VFS_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod((fsp)->conn->vfs.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (conn), (path), (uid), (gid)))
-#define SMB_VFS_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs.ops.fchown((fsp)->conn->vfs.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (conn), (path)))
-#define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (conn), (buf)))
-#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (conn), (path), (times)))
-#define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset)))
-#define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
-#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_LINK(conn, oldpath, newpath) ((conn)->vfs.ops.link((conn)->vfs.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_MKNOD(conn, path, mode, dev) ((conn)->vfs.ops.mknod((conn)->vfs.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (conn), (path), (resolved_path)))
-
-/* NT ACL operations. */
-#define SMB_VFS_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
-#define SMB_VFS_GET_NT_ACL(fsp, name, security_info, ppdesc) ((fsp)->conn->vfs.ops.get_nt_acl((fsp)->conn->vfs.handles.get_nt_acl, (fsp), (name), (security_info), (ppdesc)))
-#define SMB_VFS_FSET_NT_ACL(fsp, fd, security_info_sent, psd) ((fsp)->conn->vfs.ops.fset_nt_acl((fsp)->conn->vfs.handles.fset_nt_acl, (fsp), (fd), (security_info_sent), (psd)))
-#define SMB_VFS_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs.ops.set_nt_acl((fsp)->conn->vfs.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
-
-/* POSIX ACL operations. */
-#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (conn), (name), (mode)))
-#define SMB_VFS_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod_acl((fsp)->conn->vfs.handles.chmod_acl, (fsp), (fd), (mode)))
-
-#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs.ops.sys_acl_get_permset((conn)->vfs.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs.ops.sys_acl_get_qualifier((conn)->vfs.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs.ops.sys_acl_get_file((conn)->vfs.handles.sys_acl_get_file, (conn), (path_p), (type)))
-#define SMB_VFS_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs.ops.sys_acl_get_fd((fsp)->conn->vfs.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs.ops.sys_acl_clear_perms((conn)->vfs.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_add_perm((conn)->vfs.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs.ops.sys_acl_to_text((conn)->vfs.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_SYS_ACL_INIT(conn, count) ((conn)->vfs.ops.sys_acl_init((conn)->vfs.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs.ops.sys_acl_create_entry((conn)->vfs.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs.ops.sys_acl_set_tag_type((conn)->vfs.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs.ops.sys_acl_set_qualifier((conn)->vfs.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs.ops.sys_acl_set_permset((conn)->vfs.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_SYS_ACL_VALID(conn, theacl) ((conn)->vfs.ops.sys_acl_valid((conn)->vfs.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs.ops.sys_acl_set_file((conn)->vfs.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
-#define SMB_VFS_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs.ops.sys_acl_set_fd((fsp)->conn->vfs.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs.ops.sys_acl_delete_def_file((conn)->vfs.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_get_perm((conn)->vfs.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs.ops.sys_acl_free_text((conn)->vfs.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs.ops.sys_acl_free_acl((conn)->vfs.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs.ops.sys_acl_free_qualifier((conn)->vfs.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
-
-/* EA operations. */
-#define SMB_VFS_GETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.getxattr((conn)->vfs.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_LGETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.lgetxattr((conn)->vfs.handles.lgetxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs.ops.fgetxattr((fsp)->conn->vfs.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_LISTXATTR(conn,path,list,size) ((conn)->vfs.ops.listxattr((conn)->vfs.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_LLISTXATTR(conn,path,list,size) ((conn)->vfs.ops.llistxattr((conn)->vfs.handles.llistxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs.ops.flistxattr((fsp)->conn->vfs.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_REMOVEXATTR(conn,path,name) ((conn)->vfs.ops.removexattr((conn)->vfs.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_LREMOVEXATTR(conn,path,name) ((conn)->vfs.ops.lremovexattr((conn)->vfs.handles.lremovexattr,(conn),(path),(name)))
-#define SMB_VFS_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs.ops.fremovexattr((fsp)->conn->vfs.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.setxattr((conn)->vfs.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs.ops.fsetxattr((fsp)->conn->vfs.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
-
-/*******************************************************************
- Don't access conn->vfs_opaque.ops directly!!!
- Use this macros!
- (Fixes should also go into the vfs_* and vfs_next_* macros!)
-********************************************************************/
-
-/* Disk operations */
-#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect((conn)->vfs_opaque.handles.connect, (conn), (service), (user)))
-#define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect, (conn)))
-#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-
-/* Directory operations */
-#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
-#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
-#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
-
-/* File operations */
-#define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode)))
-#define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close((fsp)->conn->vfs_opaque.handles.close, (fsp), (fd)))
-#define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n)))
-#define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.write((fsp)->conn->vfs_opaque.handles.write, (fsp), (fd), (data), (n)))
-#define SMB_VFS_OPAQUE_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pwrite((fsp)->conn->vfs_opaque.handles.pwrite, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs_opaque.ops.lseek((fsp)->conn->vfs_opaque.handles.lseek, (fsp), (fd), (offset), (whence)))
-#define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs_opaque.ops.sendfile((fsp)->conn->vfs_opaque.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (conn), (old), (new)))
-#define SMB_VFS_OPAQUE_FSYNC(fsp, fd) ((fsp)->conn->vfs_opaque.ops.fsync((fsp)->conn->vfs_opaque.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (conn), (fname), (sbuf)))
-#define SMB_VFS_OPAQUE_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs_opaque.ops.fstat((fsp)->conn->vfs_opaque.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (conn), (path)))
-#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (conn), (path), (mode)))
-#define SMB_VFS_OPAQUE_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod((fsp)->conn->vfs_opaque.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (conn), (path), (uid), (gid)))
-#define SMB_VFS_OPAQUE_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs_opaque.ops.fchown((fsp)->conn->vfs_opaque.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (conn), (path)))
-#define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (conn), (buf)))
-#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (conn), (path), (times)))
-#define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset)))
-#define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
-#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_OPAQUE_LINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.link((conn)->vfs_opaque.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_OPAQUE_MKNOD(conn, path, mode, dev) ((conn)->vfs_opaque.ops.mknod((conn)->vfs_opaque.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (conn), (path), (resolved_path)))
-
-/* NT ACL operations. */
-#define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
-#define SMB_VFS_OPAQUE_GET_NT_ACL(fsp, name, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.get_nt_acl((fsp)->conn->vfs_opaque.handles.get_nt_acl, (fsp), (name), (security_info), (ppdesc)))
-#define SMB_VFS_OPAQUE_FSET_NT_ACL(fsp, fd, security_info_sent, psd) ((fsp)->conn->vfs_opaque.ops.fset_nt_acl((fsp)->conn->vfs_opaque.handles.fset_nt_acl, (fsp), (fd), (security_info_sent), (psd)))
-#define SMB_VFS_OPAQUE_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs_opaque.ops.set_nt_acl((fsp)->conn->vfs_opaque.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
-
-/* POSIX ACL operations. */
-#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (conn), (name), (mode)))
-#define SMB_VFS_OPAQUE_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod_acl((fsp)->conn->vfs_opaque.handles.chmod_acl, (fsp), (fd), (mode)))
-
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs_opaque.ops.sys_acl_get_permset((conn)->vfs_opaque.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs_opaque.ops.sys_acl_get_qualifier((conn)->vfs_opaque.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs_opaque.ops.sys_acl_get_file((conn)->vfs_opaque.handles.sys_acl_get_file, (conn), (path_p), (type)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs_opaque.ops.sys_acl_get_fd((fsp)->conn->vfs_opaque.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_OPAQUE_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs_opaque.ops.sys_acl_clear_perms((conn)->vfs_opaque.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_OPAQUE_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_add_perm((conn)->vfs_opaque.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_OPAQUE_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs_opaque.ops.sys_acl_to_text((conn)->vfs_opaque.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_OPAQUE_SYS_ACL_INIT(conn, count) ((conn)->vfs_opaque.ops.sys_acl_init((conn)->vfs_opaque.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_OPAQUE_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs_opaque.ops.sys_acl_create_entry((conn)->vfs_opaque.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs_opaque.ops.sys_acl_set_tag_type((conn)->vfs_opaque.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs_opaque.ops.sys_acl_set_qualifier((conn)->vfs_opaque.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs_opaque.ops.sys_acl_set_permset((conn)->vfs_opaque.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_OPAQUE_SYS_ACL_VALID(conn, theacl) ((conn)->vfs_opaque.ops.sys_acl_valid((conn)->vfs_opaque.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs_opaque.ops.sys_acl_set_file((conn)->vfs_opaque.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs_opaque.ops.sys_acl_set_fd((fsp)->conn->vfs_opaque.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs_opaque.ops.sys_acl_delete_def_file((conn)->vfs_opaque.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_get_perm((conn)->vfs_opaque.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs_opaque.ops.sys_acl_free_text((conn)->vfs_opaque.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs_opaque.ops.sys_acl_free_acl((conn)->vfs_opaque.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs_opaque.ops.sys_acl_free_qualifier((conn)->vfs_opaque.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
-
-/* EA operations. */
-#define SMB_VFS_OPAQUE_GETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.getxattr((conn)->vfs_opaque.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_OPAQUE_LGETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.lgetxattr((conn)->vfs_opaque.handles.lgetxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_OPAQUE_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs_opaque.ops.fgetxattr((fsp)->conn->vfs_opaque.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_OPAQUE_LISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.listxattr((conn)->vfs_opaque.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_OPAQUE_LLISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.llistxattr((conn)->vfs_opaque.handles.llistxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_OPAQUE_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs_opaque.ops.flistxattr((fsp)->conn->vfs_opaque.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_OPAQUE_REMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.removexattr((conn)->vfs_opaque.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_OPAQUE_LREMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.lremovexattr((conn)->vfs_opaque.handles.lremovexattr,(conn),(path),(name)))
-#define SMB_VFS_OPAQUE_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs_opaque.ops.fremovexattr((fsp)->conn->vfs_opaque.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_OPAQUE_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.setxattr((conn)->vfs_opaque.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_OPAQUE_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs_opaque.ops.fsetxattr((fsp)->conn->vfs_opaque.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
-
-/*******************************************************************
- Don't access handle->vfs_next.ops.* directly!!!
- Use this macros!
- (Fixes should go also into the vfs_* and vfs_opaque_* macros!)
-********************************************************************/
-
-/* Disk operations */
-#define SMB_VFS_NEXT_CONNECT(handle, conn, service, user) ((handle)->vfs_next.ops.connect((handle)->vfs_next.handles.connect, (conn), (service), (user)))
-#define SMB_VFS_NEXT_DISCONNECT(handle, conn) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect, (conn)))
-#define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-
-/* Directory operations */
-#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
-#define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path)))
-#define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir))
-
-/* File operations */
-#define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode)))
-#define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close((handle)->vfs_next.handles.close, (fsp), (fd)))
-#define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n)))
-#define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.write((handle)->vfs_next.handles.write, (fsp), (fd), (data), (n)))
-#define SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pwrite((handle)->vfs_next.handles.pwrite, (fsp), (fd), (data), (n), (off)))
-#define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) ((handle)->vfs_next.ops.lseek((handle)->vfs_next.handles.lseek, (fsp), (fd), (offset), (whence)))
-#define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) ((handle)->vfs_next.ops.sendfile((handle)->vfs_next.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_NEXT_RENAME(handle, conn, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (conn), (old), (new)))
-#define SMB_VFS_NEXT_FSYNC(handle, fsp, fd) ((handle)->vfs_next.ops.fsync((handle)->vfs_next.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (conn), (fname), (sbuf)))
-#define SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf) ((handle)->vfs_next.ops.fstat((handle)->vfs_next.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_NEXT_UNLINK(handle, conn, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (conn), (path)))
-#define SMB_VFS_NEXT_CHMOD(handle, conn, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (conn), (path), (mode)))
-#define SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod((handle)->vfs_next.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (conn), (path), (uid), (gid)))
-#define SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid) ((handle)->vfs_next.ops.fchown((handle)->vfs_next.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_NEXT_CHDIR(handle, conn, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (conn), (path)))
-#define SMB_VFS_NEXT_GETWD(handle, conn, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (conn), (buf)))
-#define SMB_VFS_NEXT_UTIME(handle, conn, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (conn), (path), (times)))
-#define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset)))
-#define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
-#define SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.link((handle)->vfs_next.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev) ((handle)->vfs_next.ops.mknod((handle)->vfs_next.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (conn), (path), (resolved_path)))
-
-/* NT ACL operations. */
-#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, fd, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
-#define SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc) ((handle)->vfs_next.ops.get_nt_acl((handle)->vfs_next.handles.get_nt_acl, (fsp), (name), (security_info), (ppdesc)))
-#define SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent, psd) ((handle)->vfs_next.ops.fset_nt_acl((handle)->vfs_next.handles.fset_nt_acl, (fsp), (fd), (security_info_sent), (psd)))
-#define SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd) ((handle)->vfs_next.ops.set_nt_acl((handle)->vfs_next.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
-
-/* POSIX ACL operations. */
-#define SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (conn), (name), (mode)))
-#define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod_acl((handle)->vfs_next.handles.chmod_acl, (fsp), (fd), (mode)))
-
-#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d, permset_p) ((handle)->vfs_next.ops.sys_acl_get_permset((handle)->vfs_next.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d) ((handle)->vfs_next.ops.sys_acl_get_qualifier((handle)->vfs_next.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type) ((handle)->vfs_next.ops.sys_acl_get_file((handle)->vfs_next.handles.sys_acl_get_file, (conn), (path_p), (type)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, fd) ((handle)->vfs_next.ops.sys_acl_get_fd((handle)->vfs_next.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset) ((handle)->vfs_next.ops.sys_acl_clear_perms((handle)->vfs_next.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_add_perm((handle)->vfs_next.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen) ((handle)->vfs_next.ops.sys_acl_to_text((handle)->vfs_next.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count) ((handle)->vfs_next.ops.sys_acl_init((handle)->vfs_next.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry) ((handle)->vfs_next.ops.sys_acl_create_entry((handle)->vfs_next.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry, tagtype) ((handle)->vfs_next.ops.sys_acl_set_tag_type((handle)->vfs_next.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual) ((handle)->vfs_next.ops.sys_acl_set_qualifier((handle)->vfs_next.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset) ((handle)->vfs_next.ops.sys_acl_set_permset((handle)->vfs_next.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl) ((handle)->vfs_next.ops.sys_acl_valid((handle)->vfs_next.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, theacl) ((handle)->vfs_next.ops.sys_acl_set_file((handle)->vfs_next.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, fd, theacl) ((handle)->vfs_next.ops.sys_acl_set_fd((handle)->vfs_next.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path) ((handle)->vfs_next.ops.sys_acl_delete_def_file((handle)->vfs_next.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_get_perm((handle)->vfs_next.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text) ((handle)->vfs_next.ops.sys_acl_free_text((handle)->vfs_next.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl) ((handle)->vfs_next.ops.sys_acl_free_acl((handle)->vfs_next.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier, tagtype) ((handle)->vfs_next.ops.sys_acl_free_qualifier((handle)->vfs_next.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
-
-/* EA operations. */
-#define SMB_VFS_NEXT_GETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.getxattr((handle)->vfs_next.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_NEXT_LGETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.lgetxattr((handle)->vfs_next.handles.lgetxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_NEXT_FGETXATTR(handle,fsp,fd,name,value,size) ((handle)->vfs_next.ops.fgetxattr((handle)->vfs_next.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_NEXT_LISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.listxattr((handle)->vfs_next.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_NEXT_LLISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.llistxattr((handle)->vfs_next.handles.llistxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_NEXT_FLISTXATTR(handle,fsp,fd,list,size) ((handle)->vfs_next.ops.flistxattr((handle)->vfs_next.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_NEXT_REMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.removexattr((handle)->vfs_next.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_NEXT_LREMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.lremovexattr((handle)->vfs_next.handles.lremovexattr,(conn),(path),(name)))
-#define SMB_VFS_NEXT_FREMOVEXATTR(handle,fsp,fd,name) ((handle)->vfs_next.ops.fremovexattr((handle)->vfs_next.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_NEXT_SETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.setxattr((handle)->vfs_next.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_NEXT_LSETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_NEXT_FSETXATTR(handle,fsp,fd,name,value,size,flags) ((handle)->vfs_next.ops.fsetxattr((handle)->vfs_next.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
-
-#endif /* _VFS_MACROS_H */
diff --git a/source/include/vt_mode.h b/source/include/vt_mode.h
new file mode 100755
index 00000000000..85b481122ee
--- /dev/null
+++ b/source/include/vt_mode.h
@@ -0,0 +1,48 @@
+/* vt_mode.h */
+/*
+support vtp-sessions
+
+written by Christian A. Lademann <cal@zls.com>
+*/
+
+/*
+02.05.95:cal:ported to samba-1.9.13
+*/
+
+#ifndef __vt_mode_h__
+# define __vt_mode_h__
+
+# define VT_CLOSED 0
+# define VT_OPEN 1
+
+# define MS_NONE 0
+# define MS_PTY 1
+# define MS_STREAM 2
+# define MS_VTY 3
+
+# define VT_MAXREAD 32
+
+
+# undef EXTERN
+
+# ifndef __vt_mode_c__
+# define EXTERN extern
+# define DEFAULT(v)
+# else
+# define EXTERN
+# define DEFAULT(v) =(v)
+# endif
+
+ EXTERN int VT_Status DEFAULT(VT_CLOSED),
+ VT_Fd DEFAULT(-1),
+ VT_ChildPID DEFAULT(-1);
+
+ EXTERN BOOL VT_Mode DEFAULT(False),
+ VT_ChildDied DEFAULT(False);
+
+ EXTERN char *VT_Line DEFAULT(NULL);
+
+# undef EXTERN
+
+
+#endif /* __vt_mode_h__ */
diff --git a/source/include/xfile.h b/source/include/xfile.h
deleted file mode 100644
index 89fa9d1e118..00000000000
--- a/source/include/xfile.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- stdio replacement
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _XFILE_H_
-#define _XFILE_H_
-/*
- see xfile.c for explanations
-*/
-
-typedef struct {
- int fd;
- char *buf;
- char *next;
- int bufsize;
- int bufused;
- int open_flags;
- int buftype;
- int flags;
-} XFILE;
-
-extern XFILE *x_stdin, *x_stdout, *x_stderr;
-
-/* buffering type */
-#define X_IOFBF 0
-#define X_IOLBF 1
-#define X_IONBF 2
-
-#define x_getc(f) x_fgetc(f)
-
-int x_vfprintf(XFILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2, 0);
-int x_fprintf(XFILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
-#endif /* _XFILE_H_ */
diff --git a/source/internals.doc b/source/internals.doc
new file mode 100755
index 00000000000..971f2567388
--- /dev/null
+++ b/source/internals.doc
@@ -0,0 +1,212 @@
+internals.txt, 8 May 1996
+Written by David Chappell <David.Chappell@mail.trincoll.edu>.
+
+This document describes some of the internal functions which must be
+understood by anyone wishing to add features to Samba.
+
+
+
+
+
+=============================================================================
+This section describes the macros defined in byteorder.h. These macros
+are used extensively in the Samba code.
+
+-----------------------------------------------------------------------------
+CVAL(buf,pos)
+
+returns the byte at offset pos within buffer buf as an unsigned character.
+
+-----------------------------------------------------------------------------
+PVAL(buf,pos)
+
+returns the value of CVAL(buf,pos) cast to type unsigned integer.
+
+-----------------------------------------------------------------------------
+SCVAL(buf,pos,val)
+
+sets the byte at offset pos within buffer buf to value val.
+
+-----------------------------------------------------------------------------
+SVAL(buf,pos)
+
+returns the value of the unsigned short (16 bit) little-endian integer at
+offset pos within buffer buf. An integer of this type is sometimes
+refered to as "USHORT".
+
+-----------------------------------------------------------------------------
+IVAL(buf,pos)
+
+returns the value of the unsigned 32 bit little-endian integer at offset
+pos within buffer buf.
+
+-----------------------------------------------------------------------------
+SVALS(buf,pos)
+
+returns the value of the signed short (16 bit) little-endian integer at
+offset pos within buffer buf.
+
+-----------------------------------------------------------------------------
+IVALS(buf,pos)
+
+returns the value of the signed 32 bit little-endian integer at offset pos
+within buffer buf.
+
+-----------------------------------------------------------------------------
+SSVAL(buf,pos,val)
+
+sets the unsigned short (16 bit) little-endian integer at offset pos within
+buffer buf to value val.
+
+-----------------------------------------------------------------------------
+SIVAL(buf,pos,val)
+
+sets the unsigned 32 bit little-endian integer at offset pos within buffer
+buf to the value val.
+
+-----------------------------------------------------------------------------
+SSVALS(buf,pos,val)
+
+sets the short (16 bit) signed little-endian integer at offset pos within
+buffer buf to the value val.
+
+-----------------------------------------------------------------------------
+SIVALS(buf,pos,val)
+
+sets the signed 32 bit little-endian integer at offset pos withing buffer
+buf to the value val.
+
+-----------------------------------------------------------------------------
+RSVAL(buf,pos)
+
+returns the value of the unsigned short (16 bit) big-endian integer at
+offset pos within buffer buf.
+
+-----------------------------------------------------------------------------
+RIVAL(buf,pos)
+
+returns the value of the unsigned 32 bit big-endian integer at offset
+pos within buffer buf.
+
+-----------------------------------------------------------------------------
+RSSVAL(buf,pos,val)
+
+sets the value of the unsigned short (16 bit) big-endian integer at
+offset pos within buffer buf to value val.
+refered to as "USHORT".
+
+-----------------------------------------------------------------------------
+RSIVAL(buf,pos,val)
+
+sets the value of the unsigned 32 bit big-endian integer at offset
+pos within buffer buf to value val.
+
+
+
+
+
+=============================================================================
+This section describes the functions need to make a LAN Manager RPC call.
+This information had been obtained by examining the Samba code and the LAN
+Manager 2.0 API documentation. It should not be considered entirely
+reliable.
+
+-----------------------------------------------------------------------------
+call_api(int prcnt, int drcnt, int mprcnt, int mdrcnt,
+ char *param, char *data, char **rparam, char **rdata);
+
+This function is defined in client.c. It uses an SMB transaction to call a
+remote api.
+
+The parameters are as follows:
+
+prcnt: the number of bytes of parameters begin sent.
+drcnt: the number of bytes of data begin sent.
+mprcnt: the maximum number of bytes of parameters which should be returned
+mdrcnt: the maximum number of bytes of data which should be returned
+param: a pointer to the parameters to be sent.
+data: a pointer to the data to be sent.
+rparam: a pointer to a pointer which will be set to point to the returned
+ paramters. The caller of call_api() must deallocate this memory.
+rdata: a pointer to a pointer which will be set to point to the returned
+ data. The caller of call_api() must deallocate this memory.
+
+-----------------------------------------------------------------------------
+These are the parameters which you ought to send, in the order of their
+appearance in the parameter block:
+
+* An unsigned 16 bit integer API number. You should set this value with
+SSVAL(). I do not know where these numbers are described.
+
+* An ASCIIZ string describing the parameters to the API function as defined
+in the LAN Manager documentation. The first parameter, which is the server
+name, is ommited. This string is based uppon the API function as described
+in the manual, not the data which is actually passed.
+
+* An ASCIIZ string describing the data structure which ought to be returned.
+
+* Any parameters which appear in the function call, as defined in the LAN
+Manager API documentation, after the "Server" and up to and including the
+"uLevel" parameters.
+
+* An unsigned 16 bit integer which gives the size in bytes of the buffer we
+will use to receive the returned array of data structures. Presumably this
+should be the same as mdrcnt. This value should be set with SSVAL().
+
+* An ASCIIZ string describing substructures which should be returned. If no
+substructures apply, this string is of zero length.
+
+-----------------------------------------------------------------------------
+The code in client.c always calls call_api() with no data. It is unclear
+when a non-zero length data buffer would be sent.
+
+-----------------------------------------------------------------------------
+The returned parameters (pointed to by rparam), in their order of appearance
+are:
+
+* An unsigned 16 bit integer which contains the API function's return code.
+This value should be read with SVAL().
+
+* An adjustment which tells the amount by which pointers in the returned
+data should be adjusted. This value should be read with SVAL(). Basically,
+the address of the start of the returned data buffer should have the returned
+pointer value added to it and then have this value subtracted from it in
+order to obtain the currect offset into the returned data buffer.
+
+* A count of the number of elements in the array of structures returned.
+It is also possible that this may sometimes be the number of bytes returned.
+
+-----------------------------------------------------------------------------
+When call_api() returns, rparam points to the returned parameters. The
+first if these is the result code. It will be zero if the API call
+suceeded. This value by be read with "SVAL(rparam,0)".
+
+The second parameter may be read as "SVAL(rparam,2)". It is a 16 bit offset
+which indicates what the base address of the returned data buffer was when
+it was built on the server. It should be used to correct pointer before
+use.
+
+The returned data buffer contains the array of returned data structures.
+Note that all pointers must be adjusted before use. The function
+fix_char_ptr() in client.c can be used for this purpose.
+
+The third parameter (which may be read as "SVAL(rparam,4)") has something to
+do with indicating the amount of data returned or possibly the amount of
+data which can be returned if enough buffer space is allowed.
+
+-----------------------------------------------------------------------------
+Certain data structures are described by means of ASCIIz strings containing
+code characters. These are the code characters:
+
+W a type byte little-endian unsigned integer
+N a count of substructures which follow
+D a four byte little-endian unsigned integer
+B a byte (with optional count expressed as trailing ASCII digits)
+z a four byte offset to a NULL terminated string
+l a four byte offset to non-string user data
+b an offset to data (with count expressed as trailing ASCII digits)
+r pointer to returned data buffer???
+L length in bytes of returned data buffer???
+h number of bytes of information available???
+
+----------------------------------------------------------------------------
diff --git a/source/intl/lang_tdb.c b/source/intl/lang_tdb.c
deleted file mode 100644
index fe2ad5b2fce..00000000000
--- a/source/intl/lang_tdb.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- tdb based replacement for gettext
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static TDB_CONTEXT *tdb;
-
-/* the currently selected language */
-static char *current_lang;
-
-
-/* load a msg file into the tdb */
-static BOOL load_msg(const char *msg_file)
-{
- char **lines;
- int num_lines, i;
- char *msgid, *msgstr;
- TDB_DATA key, data;
-
- lines = file_lines_load(msg_file, &num_lines);
-
- if (!lines) {
- return False;
- }
-
- if (tdb_lockall(tdb) != 0) return False;
-
- /* wipe the db */
- tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
-
- msgid = NULL;
-
- for (i=0;i<num_lines;i++) {
- if (strncmp(lines[i], "msgid \"", 7) == 0) {
- msgid = lines[i] + 7;
- }
- if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) {
- msgstr = lines[i] + 8;
- trim_char(msgid, '\0', '\"');
- trim_char(msgstr, '\0', '\"');
- if (*msgstr == 0) {
- msgstr = msgid;
- }
- all_string_sub(msgid, "\\n", "\n", 0);
- all_string_sub(msgstr, "\\n", "\n", 0);
- key.dptr = msgid;
- key.dsize = strlen(msgid)+1;
- data.dptr = msgstr;
- data.dsize = strlen(msgstr)+1;
- tdb_store(tdb, key, data, 0);
- msgid = NULL;
- }
- }
-
- file_lines_free(lines);
- tdb_unlockall(tdb);
-
- return True;
-}
-
-
-/* work out what language to use from locale variables */
-static const char *get_lang(void)
-{
- const char *vars[] = {"LANGUAGE", "LC_ALL", "LC_LANG", "LANG", NULL};
- int i;
- char *p;
-
- for (i=0; vars[i]; i++) {
- if ((p = getenv(vars[i]))) {
- return p;
- }
- }
-
- return NULL;
-}
-
-/* initialise the message translation subsystem. If the "lang" argument
- is NULL then get the language from the normal environment variables */
-BOOL lang_tdb_init(const char *lang)
-{
- char *path = NULL;
- char *msg_path = NULL;
- struct stat st;
- static int initialised;
- time_t loadtime;
- BOOL result = False;
-
- /* we only want to init once per process, unless given
- an override */
- if (initialised && !lang)
- return True;
-
- if (initialised) {
- /* we are re-initialising, free up any old init */
- if (tdb) {
- tdb_close(tdb);
- tdb = NULL;
- }
- SAFE_FREE(current_lang);
- }
-
- initialised = 1;
-
- if (!lang) {
- /* no lang given, use environment */
- lang = get_lang();
- }
-
- /* if no lang then we don't translate */
- if (!lang)
- return True;
-
- asprintf(&msg_path, "%s.msg", lib_path((const char *)lang));
- if (stat(msg_path, &st) != 0) {
- /* the msg file isn't available */
- DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path,
- strerror(errno)));
- goto done;
- }
-
- asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang);
-
- DEBUG(10, ("lang_tdb_init: loading %s\n", path));
-
- tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
- if (!tdb) {
- tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!tdb) {
- DEBUG(10, ("lang_tdb_init: %s: %s\n", path,
- strerror(errno)));
- goto done;
- }
- current_lang = strdup(lang);
- result = True;
- goto done;
- }
-
- loadtime = tdb_fetch_int32(tdb, "/LOADTIME/");
-
- if (loadtime == -1 || loadtime < st.st_mtime) {
- load_msg(msg_path);
- tdb_store_int32(tdb, "/LOADTIME/", (int)time(NULL));
- }
-
- current_lang = strdup(lang);
- result = True;
-
- done:
- SAFE_FREE(msg_path);
- SAFE_FREE(path);
-
- return result;
-}
-
-/* translate a msgid to a message string in the current language
- returns a string that must be freed by calling lang_msg_free()
-*/
-const char *lang_msg(const char *msgid)
-{
- TDB_DATA key, data;
- const char *p;
- char *q, *msgid_quoted;
- int count;
-
- lang_tdb_init(NULL);
-
- if (!tdb) return msgid;
-
- /* Due to the way quotes in msgids are escaped in the msg file we
- must replace " with \" before doing a lookup in the tdb. */
-
- count = 0;
-
- for(p = msgid; *p; p++) {
- if (*p == '\"')
- count++;
- }
-
- if (!(msgid_quoted = malloc(strlen(msgid) + count + 1)))
- return msgid;
-
- /* string_sub() is unsuitable here as it replaces some punctuation
- chars with underscores. */
-
- for(p = msgid, q = msgid_quoted; *p; p++) {
- if (*p == '\"') {
- *q = '\\';
- q++;
- }
- *q = *p;
- q++;
- }
-
- *q = 0;
-
- key.dptr = (char *)msgid_quoted;
- key.dsize = strlen(msgid_quoted)+1;
-
- data = tdb_fetch(tdb, key);
-
- free(msgid_quoted);
-
- /* if the message isn't found then we still need to return a pointer
- that can be freed. Pity. */
- if (!data.dptr)
- return strdup(msgid);
-
- return (const char *)data.dptr;
-}
-
-
-/* free up a string from lang_msg() */
-void lang_msg_free(const char *msgstr)
-{
- if (!tdb) return;
- free((void *)msgstr);
-}
-
-
-/*
- when the _() translation macro is used there is no obvious place to free
- the resulting string and there is no easy way to give a static pointer.
- All we can do is rotate between some static buffers and hope a single d_printf()
- doesn't have more calls to _() than the number of buffers
-*/
-const char *lang_msg_rotate(const char *msgid)
-{
-#define NUM_LANG_BUFS 16
- char *msgstr;
- static pstring bufs[NUM_LANG_BUFS];
- static int next;
-
- msgstr = (char *)lang_msg(msgid);
- if (!msgstr) return msgid;
-
- pstrcpy(bufs[next], msgstr);
- msgstr = bufs[next];
-
- next = (next+1) % NUM_LANG_BUFS;
-
- return msgstr;
-}
-
-
-/*
- return the current language - needed for language file mappings
-*/
-char *lang_tdb_current(void)
-{
- return current_lang;
-}
diff --git a/source/intl/linux-msg.sed b/source/intl/linux-msg.sed
deleted file mode 100644
index 5918e720a9a..00000000000
--- a/source/intl/linux-msg.sed
+++ /dev/null
@@ -1,100 +0,0 @@
-# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file
-# Copyright (C) 1995 Free Software Foundation, Inc.
-# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-# The first directive in the .msg should be the definition of the
-# message set number. We use always set number 1.
-#
-1 {
- i\
-$set 1 # Automatically created by po2msg.sed
- h
- s/.*/0/
- x
-}
-#
-# Mitch's old catalog format does not allow comments.
-#
-# We copy the original message as a comment into the .msg file.
-#
-/^msgid/ {
- s/msgid[ ]*"//
-#
-# This does not work now with the new format.
-# /"$/! {
-# s/\\$//
-# s/$/ ... (more lines following)"/
-# }
- x
-# The following nice solution is by
-# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
- td
-# Increment a decimal number in pattern space.
-# First hide trailing `9' digits.
- :d
- s/9\(_*\)$/_\1/
- td
-# Assure at least one digit is available.
- s/^\(_*\)$/0\1/
-# Increment the last digit.
- s/8\(_*\)$/9\1/
- s/7\(_*\)$/8\1/
- s/6\(_*\)$/7\1/
- s/5\(_*\)$/6\1/
- s/4\(_*\)$/5\1/
- s/3\(_*\)$/4\1/
- s/2\(_*\)$/3\1/
- s/1\(_*\)$/2\1/
- s/0\(_*\)$/1\1/
-# Convert the hidden `9' digits to `0's.
- s/_/0/g
- x
- G
- s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p
-}
-#
-# The .msg file contains, other then the .po file, only the translations
-# but each given a unique ID. Starting from 1 and incrementing by 1 for
-# each message we assign them to the messages.
-# It is important that the .po file used to generate the cat-id-tbl.c file
-# (with po-to-tbl) is the same as the one used here. (At least the order
-# of declarations must not be changed.)
-#
-/^msgstr/ {
- s/msgstr[ ]*"\(.*\)"/# \1/
-# Clear substitution flag.
- tb
-# Append the next line.
- :b
- N
-# Look whether second part is continuation line.
- s/\(.*\n\)"\(.*\)"/\1\2/
-# Yes, then branch.
- ta
- P
- D
-# Note that D includes a jump to the start!!
-# We found a continuation line. But before printing insert '\'.
- :a
- s/\(.*\)\(\n.*\)/\1\\\2/
- P
-# We cannot use D here.
- s/.*\n\(.*\)/\1/
- tb
-}
-d
diff --git a/source/lib/access.c b/source/lib/access.c
index f03f5daf333..131b5917e3e 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -10,25 +10,25 @@
#include "includes.h"
+/* Delimiters for lists of daemons or clients. */
+static const char *sep = ", \t";
+
#define FAIL (-1)
#define ALLONES ((uint32)0xFFFFFFFF)
/* masked_match - match address against netnumber/netmask */
-static BOOL masked_match(const char *tok, const char *slash, const char *s)
+static int masked_match(char *tok, char *slash, char *s)
{
uint32 net;
uint32 mask;
uint32 addr;
- fstring tok_cpy;
if ((addr = interpret_addr(s)) == INADDR_NONE)
return (False);
-
- fstrcpy(tok_cpy, tok);
- tok_cpy[PTR_DIFF(slash,tok)] = '\0';
- net = interpret_addr(tok_cpy);
- tok_cpy[PTR_DIFF(slash,tok)] = '/';
+ *slash = 0;
+ net = interpret_addr(tok);
+ *slash = '/';
if (strlen(slash + 1) > 2) {
mask = interpret_addr(slash + 1);
@@ -43,15 +43,15 @@ static BOOL masked_match(const char *tok, const char *slash, const char *s)
return (False);
}
- return ((addr & mask) == (net & mask));
+ return ((addr & mask) == net);
}
/* string_match - match string against token */
-static BOOL string_match(const char *tok,const char *s, char *invalid_char)
+static int string_match(char *tok,char *s, char *invalid_char)
{
size_t tok_len;
size_t str_len;
- const char *cut;
+ char *cut;
*invalid_char = '\0';
@@ -66,12 +66,11 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
* return True if the string is a (host) member of the
* netgroup. Return True if the token fully matches the
* string. If the token is a netnumber/netmask pair, return
- * True if the address is a member of the specified subnet.
- */
+ * True if the address is a member of the specified subnet. */
if (tok[0] == '.') { /* domain: match last fields */
if ((str_len = strlen(s)) > (tok_len = strlen(tok))
- && strequal(tok, s + str_len - tok_len))
+ && strcasecmp(tok, s + str_len - tok_len) == 0)
return (True);
} else if (tok[0] == '@') { /* netgroup: look it up */
#ifdef HAVE_NETGROUP
@@ -79,8 +78,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
char *hostname = NULL;
BOOL netgroup_ok = False;
- if (!mydomain)
- yp_get_default_domain(&mydomain);
+ if (!mydomain) yp_get_default_domain(&mydomain);
if (!mydomain) {
DEBUG(0,("Unable to get default yp domain.\n"));
@@ -101,48 +99,48 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
SAFE_FREE(hostname);
- if (netgroup_ok)
- return(True);
+ if (netgroup_ok) return(True);
#else
DEBUG(0,("access: netgroup support is not configured\n"));
return (False);
#endif
- } else if (strequal(tok, "ALL")) { /* all: match any */
+ } else if (strcasecmp(tok, "ALL") == 0) { /* all: match any */
return (True);
- } else if (strequal(tok, "FAIL")) { /* fail: match any */
+ } else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */
return (FAIL);
- } else if (strequal(tok, "LOCAL")) { /* local: no dots */
- if (strchr_m(s, '.') == 0 && !strequal(s, "unknown"))
+ } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
+ if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
return (True);
- } else if (strequal(tok, s)) { /* match host name or address */
+ } else if (!strcasecmp(tok, s)) { /* match host name or address */
return (True);
} else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
if (strncmp(tok, s, tok_len) == 0)
return (True);
- } else if ((cut = strchr_m(tok, '/')) != 0) { /* netnumber/netmask */
+ } else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
if (isdigit((int)s[0]) && masked_match(tok, cut, s))
return (True);
- } else if (strchr_m(tok, '*') != 0) {
+ } else if (strchr(tok, '*') != 0) {
*invalid_char = '*';
- } else if (strchr_m(tok, '?') != 0) {
+ } else if (strchr(tok, '?') != 0) {
*invalid_char = '?';
}
return (False);
}
+
/* client_match - match host name and address against token */
-static BOOL client_match(const char *tok, const char *item)
+static int client_match(char *tok,char *item)
{
- const char **client = (const char **)item;
- BOOL match;
+ char **client = (char **)item;
+ int match;
char invalid_char = '\0';
- /*
- * Try to match the address first. If that fails, try to match the host
- * name if available.
- */
+ /*
+ * Try to match the address first. If that fails, try to match the host
+ * name if available.
+ */
- if ((match = string_match(tok, client[1], &invalid_char)) == 0) {
+ if ((match = string_match(tok, client[1], &invalid_char)) == 0) {
if(invalid_char)
DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
@@ -155,51 +153,59 @@ token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
}
- return (match);
+ return (match);
}
/* list_match - match an item against a list of tokens with exceptions */
-static BOOL list_match(const char **list,const char *item,
- BOOL (*match_fn)(const char *, const char *))
+/* (All modifications are marked with the initials "jkf") */
+static int list_match(char *list,char *item, int (*match_fn)(char *, char *))
{
- BOOL match = False;
-
- if (!list)
- return False;
-
- /*
- * Process tokens one at a time. We have exhausted all possible matches
- * when we reach an "EXCEPT" token or the end of the list. If we do find
- * a match, look for an "EXCEPT" list and recurse to determine whether
- * the match is affected by any exceptions.
- */
-
- for (; *list ; list++) {
- if (strequal(*list, "EXCEPT")) /* EXCEPT: give up */
- break;
- if ((match = (*match_fn) (*list, item))) /* True or FAIL */
- break;
+ char *tok;
+ char *listcopy; /* jkf */
+ int match = False;
+
+ /*
+ * jkf@soton.ac.uk -- 31 August 1994 -- Stop list_match()
+ * overwriting the list given as its first parameter.
+ */
+
+ /* jkf -- can get called recursively with NULL list */
+ listcopy = (list == 0) ? (char *)0 : strdup(list);
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
+ break;
+ if ((match = (*match_fn) (tok, item))) /* True or FAIL */
+ break;
+ }
+ /* Process exceptions to True or FAIL matches. */
+
+ if (match != False) {
+ while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0 || list_match((char *) 0, item, match_fn) == False) {
+ SAFE_FREE(listcopy); /* jkf */
+ return (match);
}
- /* Process exceptions to True or FAIL matches. */
+ }
- if (match != False) {
- while (*list && !strequal(*list, "EXCEPT"))
- list++;
-
- for (; *list; list++) {
- if ((*match_fn) (*list, item)) /* Exception Found */
- return False;
- }
- }
-
- return (match);
+ SAFE_FREE(listcopy); /* jkf */
+ return (False);
}
+
/* return true if access should be allowed */
-static BOOL allow_access_internal(const char **deny_list,const char **allow_list,
- const char *cname, const char *caddr)
+BOOL allow_access(char *deny_list,char *allow_list,
+ char *cname,char *caddr)
{
- const char *client[2];
+ char *client[2];
client[0] = cname;
client[1] = caddr;
@@ -211,9 +217,9 @@ static BOOL allow_access_internal(const char **deny_list,const char **allow_list
* Patch from Steve Langasek vorlon@netexpress.net.
*/
if (deny_list &&
- list_match(deny_list,(const char *)client,client_match) &&
+ list_match(deny_list,(char *)client,client_match) &&
(!allow_list ||
- !list_match(allow_list,(const char *)client, client_match))) {
+ !list_match(allow_list,(char *)client, client_match))) {
return False;
}
return True;
@@ -228,106 +234,111 @@ static BOOL allow_access_internal(const char **deny_list,const char **allow_list
/* if there is an allow list but no deny list then allow only hosts
on the allow list */
if (!deny_list || *deny_list == 0)
- return(list_match(allow_list,(const char *)client,client_match));
+ return(list_match(allow_list,(char *)client,client_match));
/* if theres a deny list but no allow list then allow
all hosts not on the deny list */
if (!allow_list || *allow_list == 0)
- return(!list_match(deny_list,(const char *)client,client_match));
+ return(!list_match(deny_list,(char *)client,client_match));
- /* if there are both types of list then allow all hosts on the
+ /* if there are both type of list then allow all hosts on the
allow list */
- if (list_match(allow_list,(const char *)client,client_match))
+ if (list_match(allow_list,(char *)client,client_match))
return (True);
- /* if there are both types of list and it's not on the allow then
+ /* if there are both type of list and it's not on the allow then
allow it if its not on the deny */
- if (list_match(deny_list,(const char *)client,client_match))
+ if (list_match(deny_list,(char *)client,client_match))
return (False);
return (True);
}
-/* return true if access should be allowed */
-BOOL allow_access(const char **deny_list, const char **allow_list,
- const char *cname, const char *caddr)
-{
- BOOL ret;
- char *nc_cname = smb_xstrdup(cname);
- char *nc_caddr = smb_xstrdup(caddr);
-
- ret = allow_access_internal(deny_list, allow_list, nc_cname, nc_caddr);
-
- SAFE_FREE(nc_cname);
- SAFE_FREE(nc_caddr);
- return ret;
-}
-
/* return true if the char* contains ip addrs only. Used to avoid
gethostbyaddr() calls */
-
-static BOOL only_ipaddrs_in_list(const char** list)
+static BOOL only_ipaddrs_in_list(const char* list)
{
- BOOL only_ip = True;
-
- if (!list)
- return True;
+ BOOL only_ip = True;
+ char *listcopy,
+ *tok;
- for (; *list ; list++) {
+ listcopy = strdup(list);
+
+ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep))
+ {
/* factor out the special strings */
- if (strequal(*list, "ALL") || strequal(*list, "FAIL") ||
- strequal(*list, "EXCEPT")) {
+ if (!strcasecmp(tok, "ALL") || !strcasecmp(tok, "FAIL") ||
+ !strcasecmp(tok, "EXCEPT"))
+ {
continue;
}
- if (!is_ipaddress(*list)) {
+ if (!is_ipaddress(tok))
+ {
/*
* if we failed, make sure that it was not because the token
* was a network/netmask pair. Only network/netmask pairs
* have a '/' in them
*/
- if ((strchr_m(*list, '/')) == NULL) {
+ if (strchr(tok, '/') == NULL)
+ {
only_ip = False;
- DEBUG(3,("only_ipaddrs_in_list: list has non-ip address (%s)\n", *list));
+ DEBUG(3,("only_ipaddrs_in_list: list [%s] has non-ip address %s\n", list, tok));
break;
}
}
}
+ SAFE_FREE(listcopy);
+
return only_ip;
}
/* return true if access should be allowed to a service for a socket */
-BOOL check_access(int sock, const char **allow_list, const char **deny_list)
+BOOL check_access(int sock, char *allow_list, char *deny_list)
{
BOOL ret = False;
BOOL only_ip = False;
+ char *deny = NULL;
+ char *allow = NULL;
- if ((!deny_list || *deny_list==0) && (!allow_list || *allow_list==0))
+ DEBUG(10,("check_access: allow = %s, deny = %s\n",
+ allow_list ? allow_list : "NULL",
+ deny_list ? deny_list : "NULL"));
+
+ if (deny_list)
+ deny = strdup(deny_list);
+ if (allow_list)
+ allow = strdup(allow_list);
+
+ if ((!deny || *deny==0) && (!allow || *allow==0))
ret = True;
if (!ret) {
/* bypass gethostbyaddr() calls if the lists only contain IP addrs */
- if (only_ipaddrs_in_list(allow_list) && only_ipaddrs_in_list(deny_list)) {
+ if (only_ipaddrs_in_list(allow) && only_ipaddrs_in_list(deny)) {
only_ip = True;
DEBUG (3, ("check_access: no hostnames in host allow/deny list.\n"));
- ret = allow_access(deny_list,allow_list, "", get_peer_addr(sock));
+ ret = allow_access(deny,allow, "", get_socket_addr(sock));
} else {
DEBUG (3, ("check_access: hostnames in host allow/deny list.\n"));
- ret = allow_access(deny_list,allow_list, get_peer_name(sock,True),
- get_peer_addr(sock));
+ ret = allow_access(deny,allow, get_socket_name(sock),
+ get_socket_addr(sock));
}
if (ret) {
DEBUG(2,("Allowed connection from %s (%s)\n",
- only_ip ? "" : get_peer_name(sock,True),
- get_peer_addr(sock)));
+ only_ip ? "" : get_socket_name(sock),
+ get_socket_addr(sock)));
} else {
DEBUG(0,("Denied connection from %s (%s)\n",
- only_ip ? "" : get_peer_name(sock,True),
- get_peer_addr(sock)));
+ only_ip ? "" : get_socket_name(sock),
+ get_socket_addr(sock)));
}
}
+ SAFE_FREE(deny);
+ SAFE_FREE(allow);
+
return(ret);
}
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
deleted file mode 100644
index c2c63493a6f..00000000000
--- a/source/lib/account_pol.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * account policy storage
- * Copyright (C) Jean François Micouleau 1998-2001.
- * Copyright (C) Andrew Bartlett 2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-static TDB_CONTEXT *tdb; /* used for driver files */
-
-#define DATABASE_VERSION 1
-
-/****************************************************************************
- Open the account policy tdb.
-****************************************************************************/
-
-BOOL init_account_policy(void)
-{
- static pid_t local_pid;
- const char *vstring = "INFO/version";
- uint32 version;
-
- if (tdb && local_pid == sys_getpid())
- return True;
- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open account policy database\n"));
- return False;
- }
-
- local_pid = sys_getpid();
-
- /* handle a Samba upgrade */
- tdb_lock_bystring(tdb, vstring,0);
- if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
- tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
-
- account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */
- account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */
- account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */
- account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */
- account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */
- account_policy_set(AP_LOCK_ACCOUNT_DURATION, 30); /* lockout for 30 minutes */
- account_policy_set(AP_RESET_COUNT_TIME, 30); /* reset after 30 minutes */
- account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, 0); /* don't lockout */
- account_policy_set(AP_TIME_TO_LOGOUT, -1); /* don't force logout */
- }
- tdb_unlock_bystring(tdb, vstring);
-
- return True;
-}
-
-static const struct {
- int field;
- const char *string;
-} account_policy_names[] = {
- {AP_MIN_PASSWORD_LEN, "min password length"},
- {AP_PASSWORD_HISTORY, "password history"},
- {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
- {AP_MAX_PASSWORD_AGE, "maximum password age"},
- {AP_MIN_PASSWORD_AGE,"minimum password age"},
- {AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
- {AP_RESET_COUNT_TIME, "reset count minutes"},
- {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
- {AP_TIME_TO_LOGOUT, "disconnect time"},
- {0, NULL}
-};
-
-/****************************************************************************
-Get the account policy name as a string from its #define'ed number
-****************************************************************************/
-
-static const char *decode_account_policy_name(int field)
-{
- int i;
- for (i=0; account_policy_names[i].string; i++) {
- if (field == account_policy_names[i].field)
- return account_policy_names[i].string;
- }
- return NULL;
-
-}
-
-/****************************************************************************
-Get the account policy name as a string from its #define'ed number
-****************************************************************************/
-
-int account_policy_name_to_fieldnum(const char *name)
-{
- int i;
- for (i=0; account_policy_names[i].string; i++) {
- if (strcmp(name, account_policy_names[i].string) == 0)
- return account_policy_names[i].field;
- }
- return 0;
-
-}
-
-
-/****************************************************************************
-****************************************************************************/
-BOOL account_policy_get(int field, uint32 *value)
-{
- fstring name;
-
- if(!init_account_policy())return False;
-
- *value = 0;
-
- fstrcpy(name, decode_account_policy_name(field));
- if (!*name) {
- DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field));
- return False;
- }
- if (!tdb_fetch_uint32(tdb, name, value)) {
- DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for efild %d (%s), returning 0", field, name));
- return False;
- }
- DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
- return True;
-}
-
-
-/****************************************************************************
-****************************************************************************/
-BOOL account_policy_set(int field, uint32 value)
-{
- fstring name;
-
- if(!init_account_policy())return False;
-
- fstrcpy(name, decode_account_policy_name(field));
- if (!*name) {
- DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field));
- return False;
- }
-
- if (!tdb_store_uint32(tdb, name, value)) {
- DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u", field, name, value));
- return False;
- }
-
- DEBUG(10,("account_policy_set: %s:%d\n", name, value));
-
- return True;
-}
-
diff --git a/source/lib/adt_tree.c b/source/lib/adt_tree.c
deleted file mode 100644
index bd857e205ac..00000000000
--- a/source/lib/adt_tree.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Generic Abstract Data Types
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-
-/**************************************************************************
- Initialize the tree's root. The cmp_fn is a callback function used
- for comparision of two children
- *************************************************************************/
-
-static BOOL trim_tree_keypath( char *path, char **base, char **new_path )
-{
- char *p;
-
- *new_path = *base = NULL;
-
- if ( !path )
- return False;
-
- *base = path;
-
- p = strchr( path, '/' );
-
- if ( p ) {
- *p = '\0';
- *new_path = p+1;
- }
-
- return True;
-}
-
-
-/**************************************************************************
- Initialize the tree's root. The cmp_fn is a callback function used
- for comparision of two children
- *************************************************************************/
-
-SORTED_TREE* sorted_tree_init( void *data_p,
- int (cmp_fn)(void*, void*),
- void (free_fn)(void*) )
-{
- SORTED_TREE *tree = NULL;
-
- if ( !(tree = (SORTED_TREE*)malloc( sizeof(SORTED_TREE) )) )
- return NULL;
-
- ZERO_STRUCTP( tree );
-
- tree->compare = cmp_fn;
- tree->free_func = free_fn;
-
- if ( !(tree->root = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) {
- SAFE_FREE( tree );
- return NULL;
- }
-
- ZERO_STRUCTP( tree->root );
- tree->root->data_p = data_p;
-
- return tree;
-}
-
-
-/**************************************************************************
- Delete a tree and free all allocated memory
- *************************************************************************/
-
-static void sorted_tree_destroy_children( TREE_NODE *root )
-{
- int i;
-
- if ( !root )
- return;
-
- for ( i=0; i<root->num_children; i++ )
- {
- sorted_tree_destroy_children( root->children[i] );
- }
-
- SAFE_FREE( root->children );
- SAFE_FREE( root->key );
-
- return;
-}
-
-/**************************************************************************
- Delete a tree and free all allocated memory
- *************************************************************************/
-
-void sorted_tree_destroy( SORTED_TREE *tree )
-{
- if ( tree->root )
- sorted_tree_destroy_children( tree->root );
-
- if ( tree->free_func )
- tree->free_func( tree->root );
-
- SAFE_FREE( tree );
-}
-
-/**************************************************************************
- Find the next child given a key string
- *************************************************************************/
-
-static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
-{
- TREE_NODE *infant = NULL;
- TREE_NODE **siblings;
- int i;
-
- if ( !(infant = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) )
- return NULL;
-
- ZERO_STRUCTP( infant );
-
- infant->key = strdup( key );
- infant->parent = node;
-
- siblings = Realloc( node->children, sizeof(TREE_NODE*)*(node->num_children+1) );
-
- if ( siblings )
- node->children = siblings;
-
- node->num_children++;
-
- /* first child */
-
- if ( node->num_children == 1 ) {
- DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n",
- node->key ? node->key : "NULL", infant->key ));
- node->children[0] = infant;
- }
- else
- {
- /*
- * multiple siblings .... (at least 2 children)
- *
- * work from the end of the list forward
- * The last child is not set at this point
- * Insert the new infanct in ascending order
- * from left to right
- */
-
- for ( i = node->num_children-1; i>=1; i-- )
- {
- DEBUG(11,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n",
- infant->key, node->children[i-1]->key));
-
- /* the strings should never match assuming that we
- have called sorted_tree_find_child() first */
-
- if ( StrCaseCmp( infant->key, node->children[i-1]->key ) > 0 ) {
- DEBUG(11,("sorted_tree_birth_child: storing infant in i == [%d]\n",
- i));
- node->children[i] = infant;
- break;
- }
-
- /* bump everything towards the end on slot */
-
- node->children[i] = node->children[i-1];
- }
-
- DEBUG(11,("sorted_tree_birth_child: Exiting loop (i == [%d])\n", i ));
-
- /* if we haven't found the correct slot yet, the child
- will be first in the list */
-
- if ( i == 0 )
- node->children[0] = infant;
- }
-
- return infant;
-}
-
-/**************************************************************************
- Find the next child given a key string
- *************************************************************************/
-
-static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key )
-{
- TREE_NODE *next = NULL;
- int i, result;
-
- if ( !node ) {
- DEBUG(0,("sorted_tree_find_child: NULL node passed into function!\n"));
- return NULL;
- }
-
- if ( !key ) {
- DEBUG(0,("sorted_tree_find_child: NULL key string passed into function!\n"));
- return NULL;
- }
-
- for ( i=0; i<node->num_children; i++ )
- {
- DEBUG(11,("sorted_tree_find_child: child key => [%s]\n",
- node->children[i]->key));
-
- result = StrCaseCmp( node->children[i]->key, key );
-
- if ( result == 0 )
- next = node->children[i];
-
- /* if result > 0 then we've gone to far because
- the list of children is sorted by key name
- If result == 0, then we have a match */
-
- if ( result > 0 )
- break;
- }
-
- DEBUG(11,("sorted_tree_find_child: %s [%s]\n",
- next ? "Found" : "Did not find", key ));
-
- return next;
-}
-
-/**************************************************************************
- Add a new node into the tree given a key path and a blob of data
- *************************************************************************/
-
-BOOL sorted_tree_add( SORTED_TREE *tree, const char *path, void *data_p )
-{
- char *str, *base, *path2;
- TREE_NODE *current, *next;
- BOOL ret = True;
-
- DEBUG(8,("sorted_tree_add: Enter\n"));
-
- if ( !path || *path != '/' ) {
- DEBUG(0,("sorted_tree_add: Attempt to add a node with a bad path [%s]\n",
- path ? path : "NULL" ));
- return False;
- }
-
- if ( !tree ) {
- DEBUG(0,("sorted_tree_add: Attempt to add a node to an uninitialized tree!\n"));
- return False;
- }
-
- /* move past the first '/' */
-
- path++;
- path2 = strdup( path );
- if ( !path2 ) {
- DEBUG(0,("sorted_tree_add: strdup() failed on string [%s]!?!?!\n", path));
- return False;
- }
-
-
- /*
- * this works sort of like a 'mkdir -p' call, possibly
- * creating an entire path to the new node at once
- * The path should be of the form /<key1>/<key2>/...
- */
-
- base = path2;
- str = path2;
- current = tree->root;
-
- do {
- /* break off the remaining part of the path */
-
- str = strchr( str, '/' );
- if ( str )
- *str = '\0';
-
- /* iterate to the next child--birth it if necessary */
-
- next = sorted_tree_find_child( current, base );
- if ( !next ) {
- next = sorted_tree_birth_child( current, base );
- if ( !next ) {
- DEBUG(0,("sorted_tree_add: Failed to create new child!\n"));
- ret = False;
- goto done;
- }
- }
- current = next;
-
- /* setup the next part of the path */
-
- base = str;
- if ( base ) {
- *base = '/';
- base++;
- str = base;
- }
-
- } while ( base != NULL );
-
- current->data_p = data_p;
-
- DEBUG(10,("sorted_tree_add: Successfully added node [%s] to tree\n",
- path ));
-
- DEBUG(8,("sorted_tree_add: Exit\n"));
-
-done:
- SAFE_FREE( path2 );
- return ret;
-}
-
-
-/**************************************************************************
- Recursive routine to print out all children of a TREE_NODE
- *************************************************************************/
-
-static void sorted_tree_print_children( TREE_NODE *node, int debug, const char *path )
-{
- int i;
- int num_children;
- pstring path2;
-
- if ( !node )
- return;
-
-
- if ( node->key )
- DEBUG(debug,("%s: [%s] (%s)\n", path ? path : "NULL", node->key,
- node->data_p ? "data" : "NULL" ));
-
- *path2 = '\0';
- if ( path )
- pstrcpy( path2, path );
- pstrcat( path2, node->key ? node->key : "NULL" );
- pstrcat( path2, "/" );
-
- num_children = node->num_children;
- for ( i=0; i<num_children; i++ )
- sorted_tree_print_children( node->children[i], debug, path2 );
-
-
-}
-
-/**************************************************************************
- Dump the kys for a tree to the log file
- *************************************************************************/
-
-void sorted_tree_print_keys( SORTED_TREE *tree, int debug )
-{
- int i;
- int num_children = tree->root->num_children;
-
- if ( tree->root->key )
- DEBUG(debug,("ROOT/: [%s] (%s)\n", tree->root->key,
- tree->root->data_p ? "data" : "NULL" ));
-
- for ( i=0; i<num_children; i++ ) {
- sorted_tree_print_children( tree->root->children[i], debug,
- tree->root->key ? tree->root->key : "ROOT/" );
- }
-
-}
-
-/**************************************************************************
- return the data_p for for the node in tree matching the key string
- The key string is the full path. We must break it apart and walk
- the tree
- *************************************************************************/
-
-void* sorted_tree_find( SORTED_TREE *tree, char *key )
-{
- char *keystr, *base, *str, *p;
- TREE_NODE *current;
- void *result = NULL;
-
- DEBUG(10,("sorted_tree_find: Enter [%s]\n", key ? key : "NULL" ));
-
- /* sanity checks first */
-
- if ( !key ) {
- DEBUG(0,("sorted_tree_find: Attempt to search tree using NULL search string!\n"));
- return NULL;
- }
-
- if ( !tree ) {
- DEBUG(0,("sorted_tree_find: Attempt to search an uninitialized tree using string [%s]!\n",
- key ? key : "NULL" ));
- return NULL;
- }
-
- if ( !tree->root )
- return NULL;
-
- /* make a copy to play with */
-
- if ( *key == '/' )
- keystr = strdup( key+1 );
- else
- keystr = strdup( key );
-
- if ( !keystr ) {
- DEBUG(0,("sorted_tree_find: strdup() failed on string [%s]!?!?!\n", key));
- return NULL;
- }
-
- /* start breaking the path apart */
-
- p = keystr;
- current = tree->root;
-
- if ( tree->root->data_p )
- result = tree->root->data_p;
-
- do
- {
- /* break off the remaining part of the path */
-
- trim_tree_keypath( p, &base, &str );
-
- DEBUG(11,("sorted_tree_find: [loop] base => [%s], new_path => [%s]\n",
- base, str));
-
- /* iterate to the next child */
-
- current = sorted_tree_find_child( current, base );
-
- /*
- * the idea is that the data_p for a parent should
- * be inherited by all children, but allow it to be
- * overridden farther down
- */
-
- if ( current && current->data_p )
- result = current->data_p;
-
- /* reset the path pointer 'p' to the remaining part of the key string */
-
- p = str;
-
- } while ( str && current );
-
- /* result should be the data_p from the lowest match node in the tree */
- if ( result )
- DEBUG(11,("sorted_tree_find: Found data_p!\n"));
-
- SAFE_FREE( keystr );
-
- DEBUG(10,("sorted_tree_find: Exit\n"));
-
- return result;
-}
-
-
diff --git a/source/lib/afs.c b/source/lib/afs.c
deleted file mode 100644
index 0830a3a0e7f..00000000000
--- a/source/lib/afs.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Generate AFS tickets
- * Copyright (C) Volker Lendecke 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#ifdef WITH_FAKE_KASERVER
-
-#include <afs/stds.h>
-#include <afs/afs.h>
-#include <afs/auth.h>
-#include <afs/venus.h>
-#include <asm/unistd.h>
-#include <openssl/des.h>
-
-struct ClearToken {
- uint32 AuthHandle;
- char HandShakeKey[8];
- uint32 ViceId;
- uint32 BeginTimestamp;
- uint32 EndTimestamp;
-};
-
-static char *afs_encode_token(const char *cell, const DATA_BLOB ticket,
- const struct ClearToken *ct)
-{
- char *base64_ticket;
- char *result;
-
- DATA_BLOB key = data_blob(ct->HandShakeKey, 8);
- char *base64_key;
-
- base64_ticket = base64_encode_data_blob(ticket);
- if (base64_ticket == NULL)
- return NULL;
-
- base64_key = base64_encode_data_blob(key);
- if (base64_key == NULL) {
- free(base64_ticket);
- return NULL;
- }
-
- asprintf(&result, "%s\n%u\n%s\n%u\n%u\n%u\n%s\n", cell,
- ct->AuthHandle, base64_key, ct->ViceId, ct->BeginTimestamp,
- ct->EndTimestamp, base64_ticket);
-
- DEBUG(10, ("Got ticket string:\n%s\n", result));
-
- free(base64_ticket);
- free(base64_key);
-
- return result;
-}
-
-/* Create a ClearToken and an encrypted ticket. ClearToken has not yet the
- * ViceId set, this should be set by the caller. */
-
-static BOOL afs_createtoken(const char *username, const char *cell,
- DATA_BLOB *ticket, struct ClearToken *ct)
-{
- fstring clear_ticket;
- char *p = clear_ticket;
- uint32 len;
- uint32 now;
-
- struct afs_key key;
- des_key_schedule key_schedule;
-
- if (!secrets_init())
- return False;
-
- if (!secrets_fetch_afs_key(cell, &key)) {
- DEBUG(1, ("Could not fetch AFS service key\n"));
- return False;
- }
-
- ct->AuthHandle = key.kvno;
-
- /* Build the ticket. This is going to be encrypted, so in our
- way we fill in ct while we still have the unencrypted
- form. */
-
- p = clear_ticket;
-
- /* The byte-order */
- *p = 1;
- p += 1;
-
- /* "Alice", the client username */
- strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
- p += strlen(p)+1;
- strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
- p += strlen(p)+1;
- strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
- p += strlen(p)+1;
-
- /* Alice's network layer address. At least Openafs-1.2.10
- ignores this, so we fill in a dummy value here. */
- SIVAL(p, 0, 0);
- p += 4;
-
- /* We need to create a session key */
- generate_random_buffer(p, 8, False);
-
- /* Our client code needs the the key in the clear, it does not
- know the server-key ... */
- memcpy(ct->HandShakeKey, p, 8);
-
- p += 8;
-
- /* Ticket lifetime. We fake everything here, so go as long as
- possible. This is in 5-minute intervals, so 255 is 21 hours
- and 15 minutes.*/
- *p = 255;
- p += 1;
-
- /* Ticket creation time */
- now = time(NULL);
- SIVAL(p, 0, now);
- ct->BeginTimestamp = now;
-
- ct->EndTimestamp = now + (255*60*5);
- if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
- ct->BeginTimestamp += 1; /* Lifetime must be even */
- }
- p += 4;
-
- /* And here comes Bob's name and instance, in this case the
- AFS server. */
- strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
- p += strlen(p)+1;
- strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
- p += strlen(p)+1;
-
- /* And zero-pad to a multiple of 8 bytes */
- len = PTR_DIFF(p, clear_ticket);
- if (len & 7) {
- uint32 extra_space = 8-(len & 7);
- memset(p, 0, extra_space);
- p+=extra_space;
- }
- len = PTR_DIFF(p, clear_ticket);
-
- des_key_sched((const_des_cblock *)key.key, key_schedule);
- des_pcbc_encrypt(clear_ticket, clear_ticket,
- len, key_schedule, (C_Block *)key.key, 1);
-
- ZERO_STRUCT(key);
-
- *ticket = data_blob(clear_ticket, len);
-
- return True;
-}
-
-char *afs_createtoken_str(const char *username, const char *cell)
-{
- DATA_BLOB ticket;
- struct ClearToken ct;
- char *result;
-
- if (!afs_createtoken(username, cell, &ticket, &ct))
- return NULL;
-
- result = afs_encode_token(cell, ticket, &ct);
-
- data_blob_free(&ticket);
-
- return result;
-}
-
-/*
- This routine takes a radical approach completely bypassing the
- Kerberos idea of security and using AFS simply as an intelligent
- file backend. Samba has persuaded itself somehow that the user is
- actually correctly identified and then we create a ticket that the
- AFS server hopefully accepts using its KeyFile that the admin has
- kindly stored to our secrets.tdb.
-
- Thanks to the book "Network Security -- PRIVATE Communication in a
- PUBLIC World" by Charlie Kaufman, Radia Perlman and Mike Speciner
- Kerberos 4 tickets are not really hard to construct.
-
- For the comments "Alice" is the User to be auth'ed, and "Bob" is the
- AFS server. */
-
-BOOL afs_login(connection_struct *conn)
-{
- DATA_BLOB ticket;
- pstring afs_username;
- char *cell;
- BOOL result;
- char *ticket_str;
-
- struct ClearToken ct;
-
- pstrcpy(afs_username, lp_afs_username_map());
- standard_sub_conn(conn, afs_username, sizeof(afs_username));
-
- /* The pts command always generates completely lower-case user
- * names. */
- strlower_m(afs_username);
-
- cell = strchr(afs_username, '@');
-
- if (cell == NULL) {
- DEBUG(1, ("AFS username doesn't contain a @, "
- "could not find cell\n"));
- return False;
- }
-
- *cell = '\0';
- cell += 1;
-
- DEBUG(10, ("Trying to log into AFS for user %s@%s\n",
- afs_username, cell));
-
- if (!afs_createtoken(afs_username, cell, &ticket, &ct))
- return False;
-
- /* For which Unix-UID do we want to set the token? */
- ct.ViceId = getuid();
-
- ticket_str = afs_encode_token(cell, ticket, &ct);
-
- result = afs_settoken_str(ticket_str);
-
- SAFE_FREE(ticket_str);
-
- data_blob_free(&ticket);
-
- return result;
-}
-
-#else
-
-BOOL afs_login(connection_struct *conn)
-{
- return True;
-}
-
-char *afs_createtoken_str(const char *username, const char *cell)
-{
- return False;
-}
-
-#endif /* WITH_FAKE_KASERVER */
diff --git a/source/lib/afs_settoken.c b/source/lib/afs_settoken.c
deleted file mode 100644
index eb10c4c66d4..00000000000
--- a/source/lib/afs_settoken.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Generate AFS tickets
- * Copyright (C) Volker Lendecke 2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#ifdef WITH_FAKE_KASERVER
-
-#include <afs/stds.h>
-#include <afs/afs.h>
-#include <afs/auth.h>
-#include <afs/venus.h>
-#include <asm/unistd.h>
-#include <openssl/des.h>
-
-_syscall5(int, afs_syscall, int, subcall,
- char *, path,
- int, cmd,
- char *, cmarg,
- int, follow);
-
-struct ClearToken {
- uint32 AuthHandle;
- char HandShakeKey[8];
- uint32 ViceId;
- uint32 BeginTimestamp;
- uint32 EndTimestamp;
-};
-
-static BOOL afs_decode_token(const char *string, char **cell,
- DATA_BLOB *ticket, struct ClearToken *ct)
-{
- DATA_BLOB blob;
- struct ClearToken result_ct;
-
- char *s = strdup(string);
-
- char *t;
-
- if ((t = strtok(s, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- *cell = strdup(t);
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
- DEBUG(10, ("sscanf AuthHandle failed\n"));
- return False;
- }
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- blob = base64_decode_data_blob(t);
-
- if ( (blob.data == NULL) ||
- (blob.length != sizeof(result_ct.HandShakeKey) )) {
- DEBUG(10, ("invalid key: %x/%d\n", (uint32)blob.data,
- blob.length));
- return False;
- }
-
- memcpy(result_ct.HandShakeKey, blob.data, blob.length);
-
- data_blob_free(&blob);
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
- DEBUG(10, ("sscanf ViceId failed\n"));
- return False;
- }
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
- DEBUG(10, ("sscanf BeginTimestamp failed\n"));
- return False;
- }
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
- DEBUG(10, ("sscanf EndTimestamp failed\n"));
- return False;
- }
-
- if ((t = strtok(NULL, "\n")) == NULL) {
- DEBUG(10, ("strtok failed\n"));
- return False;
- }
-
- blob = base64_decode_data_blob(t);
-
- if (blob.data == NULL) {
- DEBUG(10, ("Could not get ticket\n"));
- return False;
- }
-
- *ticket = blob;
- *ct = result_ct;
-
- return True;
-}
-
-/*
- Put an AFS token into the Kernel so that it can authenticate against
- the AFS server. This assumes correct local uid settings.
-
- This is currently highly Linux and OpenAFS-specific. The correct API
- call for this would be ktc_SetToken. But to do that we would have to
- import a REALLY big bunch of libraries which I would currently like
- to avoid.
-*/
-
-static BOOL afs_settoken(const char *cell,
- const struct ClearToken *ctok,
- DATA_BLOB ticket)
-{
- int ret;
- struct {
- char *in, *out;
- uint16 in_size, out_size;
- } iob;
-
- char buf[1024];
- char *p = buf;
- int tmp;
-
- memcpy(p, &ticket.length, sizeof(uint32));
- p += sizeof(uint32);
- memcpy(p, ticket.data, ticket.length);
- p += ticket.length;
-
- tmp = sizeof(struct ClearToken);
- memcpy(p, &tmp, sizeof(uint32));
- p += sizeof(uint32);
- memcpy(p, ctok, tmp);
- p += tmp;
-
- tmp = 0;
-
- memcpy(p, &tmp, sizeof(uint32));
- p += sizeof(uint32);
-
- tmp = strlen(cell);
- if (tmp >= MAXKTCREALMLEN) {
- DEBUG(1, ("Realm too long\n"));
- return False;
- }
-
- strncpy(p, cell, tmp);
- p += tmp;
- *p = 0;
- p +=1;
-
- iob.in = buf;
- iob.in_size = PTR_DIFF(p,buf);
- iob.out = buf;
- iob.out_size = sizeof(buf);
-
-#if 0
- file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
-#endif
-
- ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
-
- DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
- return (ret == 0);
-}
-
-BOOL afs_settoken_str(const char *token_string)
-{
- DATA_BLOB ticket;
- struct ClearToken ct;
- BOOL result;
- char *cell;
-
- if (!afs_decode_token(token_string, &cell, &ticket, &ct))
- return False;
-
- if (geteuid() != 0)
- ct.ViceId = getuid();
-
- result = afs_settoken(cell, &ct, ticket);
-
- SAFE_FREE(cell);
- data_blob_free(&ticket);
-
- return result;
-}
-
-#else
-
-BOOL afs_settoken_str(const char *token_string)
-{
- return False;
-}
-
-#endif
diff --git a/source/lib/bitmap.c b/source/lib/bitmap.c
index 3fa20cdd112..6a327a5d95f 100644
--- a/source/lib/bitmap.c
+++ b/source/lib/bitmap.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
simple bitmap functions
Copyright (C) Andrew Tridgell 1992-1998
@@ -21,7 +22,8 @@
#include "includes.h"
/* these functions provide a simple way to allocate integers from a
- pool without repetition */
+ pool without repitition */
+
/****************************************************************************
allocate a bitmap of the specified size
@@ -60,44 +62,6 @@ void bitmap_free(struct bitmap *bm)
}
/****************************************************************************
-talloc a bitmap
-****************************************************************************/
-struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n)
-{
- struct bitmap *bm;
-
- if (!mem_ctx) return NULL;
-
- bm = (struct bitmap *)talloc(mem_ctx, sizeof(*bm));
-
- if (!bm) return NULL;
-
- bm->n = n;
- bm->b = (uint32 *)talloc(mem_ctx, sizeof(bm->b[0])*(n+31)/32);
- if (!bm->b) {
- return NULL;
- }
-
- memset(bm->b, 0, sizeof(bm->b[0])*(n+31)/32);
-
- return bm;
-}
-
-/****************************************************************************
-copy as much of the source bitmap as will fit in the destination bitmap.
-****************************************************************************/
-
-int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src)
-{
- int count = MIN(dst->n, src->n);
-
- SMB_ASSERT(dst->b != src->b);
- memcpy(dst->b, src->b, sizeof(dst->b[0])*(count+31)/32);
-
- return count;
-}
-
-/****************************************************************************
set a bit in a bitmap
****************************************************************************/
BOOL bitmap_set(struct bitmap *bm, unsigned i)
@@ -143,7 +107,7 @@ wraparound
****************************************************************************/
int bitmap_find(struct bitmap *bm, unsigned ofs)
{
- unsigned int i, j;
+ int i, j;
if (ofs > bm->n) ofs = 0;
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index b9791931a35..583744a486a 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -1,10 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Character set conversion Extensions
- Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Simo Sorce 2001
- Copyright (C) Martin Pool 2003
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,1318 +20,486 @@
*/
#include "includes.h"
+#define CTRLZ 26
+#define SPC 32
-/**
- * @file
- *
- * @brief Character-set conversion routines built on our iconv.
- *
- * @note Samba's internal character set (at least in the 3.0 series)
- * is always the same as the one for the Unix filesystem. It is
- * <b>not</b> necessarily UTF-8 and may be different on machines that
- * need i18n filenames to be compatible with Unix software. It does
- * have to be a superset of ASCII. All multibyte sequences must start
- * with a byte with the high bit set.
- *
- * @sa lib/iconv.c
- */
-
-
-static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
-static BOOL conv_silent; /* Should we do a debug if the conversion fails ? */
-
-/**
- * Return the name of a charset to give to iconv().
- **/
-static const char *charset_name(charset_t ch)
-{
- const char *ret = NULL;
-
- if (ch == CH_UCS2) ret = "UCS-2LE";
- else if (ch == CH_UNIX) ret = lp_unix_charset();
- else if (ch == CH_DOS) ret = lp_dos_charset();
- else if (ch == CH_DISPLAY) ret = lp_display_charset();
- else if (ch == CH_UTF8) ret = "UTF8";
+static char cvtbuf[sizeof(pstring)];
-#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
- if (ret && !strcmp(ret, "LOCALE")) {
- const char *ln = NULL;
+static BOOL mapsinited = 0;
-#ifdef HAVE_SETLOCALE
- setlocale(LC_ALL, "");
-#endif
- ln = nl_langinfo(CODESET);
- if (ln) {
- /* Check whether the charset name is supported
- by iconv */
- smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
- if (handle == (smb_iconv_t) -1) {
- DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
- ln = NULL;
- } else {
- DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
- smb_iconv_close(handle);
- }
- }
- ret = ln;
- }
-#endif
+static char unix2dos[256];
+static char dos2unix[256];
- if (!ret || !*ret) ret = "ASCII";
- return ret;
-}
+static void initmaps(void) {
+ int k;
-void lazy_initialize_conv(void)
-{
- static int initialized = False;
+ for (k = 0; k < 256; k++) unix2dos[k] = k;
+ for (k = 0; k < 256; k++) dos2unix[k] = k;
- if (!initialized) {
- initialized = True;
- load_case_tables();
- init_iconv();
- }
+ mapsinited = True;
}
-/**
- * Initialize iconv conversion descriptors.
- *
- * This is called the first time it is needed, and also called again
- * every time the configuration is reloaded, because the charset or
- * codepage might have changed.
- **/
-void init_iconv(void)
-{
- int c1, c2;
- BOOL did_reload = False;
-
- /* so that charset_name() works we need to get the UNIX<->UCS2 going
- first */
- if (!conv_handles[CH_UNIX][CH_UCS2])
- conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open("UCS-2LE", "ASCII");
-
- if (!conv_handles[CH_UCS2][CH_UNIX])
- conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE");
-
- for (c1=0;c1<NUM_CHARSETS;c1++) {
- for (c2=0;c2<NUM_CHARSETS;c2++) {
- const char *n1 = charset_name((charset_t)c1);
- const char *n2 = charset_name((charset_t)c2);
- if (conv_handles[c1][c2] &&
- strcmp(n1, conv_handles[c1][c2]->from_name) == 0 &&
- strcmp(n2, conv_handles[c1][c2]->to_name) == 0)
- continue;
-
- did_reload = True;
-
- if (conv_handles[c1][c2])
- smb_iconv_close(conv_handles[c1][c2]);
-
- conv_handles[c1][c2] = smb_iconv_open(n2,n1);
- if (conv_handles[c1][c2] == (smb_iconv_t)-1) {
- DEBUG(0,("init_iconv: Conversion from %s to %s not supported\n",
- charset_name((charset_t)c1), charset_name((charset_t)c2)));
- if (c1 != CH_UCS2) {
- n1 = "ASCII";
- }
- if (c2 != CH_UCS2) {
- n2 = "ASCII";
- }
- DEBUG(0,("init_iconv: Attempting to replace with conversion from %s to %s\n",
- n1, n2 ));
- conv_handles[c1][c2] = smb_iconv_open(n2,n1);
- if (!conv_handles[c1][c2]) {
- DEBUG(0,("init_iconv: Conversion from %s to %s failed", n1, n2));
- smb_panic("init_iconv: conv_handle initialization failed.");
- }
- }
- }
- }
-
- if (did_reload) {
- /* XXX: Does this really get called every time the dos
- * codepage changes? */
- /* XXX: Is the did_reload test too strict? */
- conv_silent = True;
- init_doschar_table();
- init_valid_table();
- conv_silent = False;
- }
-}
-
-/**
- * Convert string from one encoding to another, making error checking etc
- * Slow path version - uses (slow) iconv.
- *
- * @param src pointer to source string (multibyte or singlebyte)
- * @param srclen length of the source string in bytes
- * @param dest pointer to destination string (multibyte or singlebyte)
- * @param destlen maximal length allowed for string
- * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
- * @returns the number of bytes occupied in the destination
- *
- * Ensure the srclen contains the terminating zero.
- *
- **/
-
-static size_t convert_string_internal(charset_t from, charset_t to,
- void const *src, size_t srclen,
- void *dest, size_t destlen, BOOL allow_bad_conv)
-{
- size_t i_len, o_len;
- size_t retval;
- const char* inbuf = (const char*)src;
- char* outbuf = (char*)dest;
- smb_iconv_t descriptor;
-
- lazy_initialize_conv();
-
- descriptor = conv_handles[from][to];
-
- if (srclen == (size_t)-1) {
- if (from == CH_UCS2) {
- srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
- } else {
- srclen = strlen((const char *)src)+1;
- }
- }
-
-
- if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
- if (!conv_silent)
- DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
- return (size_t)-1;
- }
-
- i_len=srclen;
- o_len=destlen;
-
- again:
-
- retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len);
- if(retval==(size_t)-1) {
- const char *reason="unknown error";
- switch(errno) {
- case EINVAL:
- reason="Incomplete multibyte sequence";
- if (!conv_silent)
- DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
- if (allow_bad_conv)
- goto use_as_is;
- break;
- case E2BIG:
- reason="No more room";
- if (!conv_silent)
- DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
- (unsigned long)srclen, (unsigned long)destlen));
- /* we are not sure we need srclen bytes,
- may be more, may be less.
- We only know we need more than destlen
- bytes ---simo */
- break;
- case EILSEQ:
- reason="Illegal multibyte sequence";
- if (!conv_silent)
- DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
- if (allow_bad_conv)
- goto use_as_is;
- break;
- default:
- if (!conv_silent)
- DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
- break;
- }
- /* smb_panic(reason); */
- }
- return destlen-o_len;
-
- use_as_is:
-
- /*
- * Conversion not supported. This is actually an error, but there are so
- * many misconfigured iconv systems and smb.conf's out there we can't just
- * fail. Do a very bad conversion instead.... JRA.
- */
-
- {
- if (o_len == 0 || i_len == 0)
- return destlen - o_len;
-
- if (from == CH_UCS2 && to != CH_UCS2) {
- /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
- if (i_len < 2)
- return destlen - o_len;
- if (i_len >= 2) {
- *outbuf = inbuf[0];
-
- outbuf++;
- o_len--;
-
- inbuf += 2;
- i_len -= 2;
- }
+static void update_map(const char *str) {
+ const char *p;
- if (o_len == 0 || i_len == 0)
- return destlen - o_len;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else if (from != CH_UCS2 && to == CH_UCS2) {
- /* Can't convert to ucs2 - just widen by adding zero. */
- if (o_len < 2)
- return destlen - o_len;
-
- outbuf[0] = inbuf[0];
- outbuf[1] = '\0';
-
- inbuf++;
- i_len--;
-
- outbuf += 2;
- o_len -= 2;
-
- if (o_len == 0 || i_len == 0)
- return destlen - o_len;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else if (from != CH_UCS2 && to != CH_UCS2) {
- /* Failed multibyte to multibyte. Just copy 1 char and
- try again. */
- outbuf[0] = inbuf[0];
-
- inbuf++;
- i_len--;
-
- outbuf++;
- o_len--;
-
- if (o_len == 0 || i_len == 0)
- return destlen - o_len;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else {
- /* Keep compiler happy.... */
- return destlen - o_len;
- }
- }
+ for (p = str; *p; p++) {
+ if (p[1]) {
+ unix2dos[(unsigned char)*p] = p[1];
+ dos2unix[(unsigned char)p[1]] = *p;
+ p++;
+ }
+ }
}
-/**
- * Convert string from one encoding to another, making error checking etc
- * Fast path version - handles ASCII first.
- *
- * @param src pointer to source string (multibyte or singlebyte)
- * @param srclen length of the source string in bytes, or -1 for nul terminated.
- * @param dest pointer to destination string (multibyte or singlebyte)
- * @param destlen maximal length allowed for string - *NEVER* -1.
- * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
- * @returns the number of bytes occupied in the destination
- *
- * Ensure the srclen contains the terminating zero.
- *
- * This function has been hand-tuned to provide a fast path.
- * Don't change unless you really know what you are doing. JRA.
- **/
-
-size_t convert_string(charset_t from, charset_t to,
- void const *src, size_t srclen,
- void *dest, size_t destlen, BOOL allow_bad_conv)
+static void setupmaps(void)
{
- /*
- * NB. We deliberately don't do a strlen here if srclen == -1.
- * This is very expensive over millions of calls and is taken
- * care of in the slow path in convert_string_internal. JRA.
- */
-
-#ifdef DEVELOPER
- SMB_ASSERT(destlen != (size_t)-1);
-#endif
+ int i;
+ if (!mapsinited) initmaps();
- if (srclen == 0)
- return 0;
-
- if (from != CH_UCS2 && to != CH_UCS2) {
- const unsigned char *p = (const unsigned char *)src;
- unsigned char *q = (unsigned char *)dest;
- size_t slen = srclen;
- size_t dlen = destlen;
- unsigned char lastp;
- size_t retval = 0;
-
- /* If all characters are ascii, fast path here. */
- while (slen && dlen) {
- if ((lastp = *p) <= 0x7f) {
- *q++ = *p++;
- if (slen != (size_t)-1) {
- slen--;
- }
- dlen--;
- retval++;
- if (!lastp)
- break;
- } else {
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- goto general_case;
+ /* Do not map undefined characters to some accidental code */
+ for (i = 128; i < 256; i++)
+ {
+#if 0 /* JERRY */
+ /* Win2k & XP don't like the Ctrl-Z apparently */
+ /* patch from Toomas.Soome@microlink.ee */
+ unix2dos[i] = CTRLZ;
+ dos2unix[i] = CTRLZ;
#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ unix2dos[i] = SPC;
+ dos2unix[i] = SPC;
#endif
- }
- }
- return retval;
- } else if (from == CH_UCS2 && to != CH_UCS2) {
- const unsigned char *p = (const unsigned char *)src;
- unsigned char *q = (unsigned char *)dest;
- size_t retval = 0;
- size_t slen = srclen;
- size_t dlen = destlen;
- unsigned char lastp;
-
- /* If all characters are ascii, fast path here. */
- while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
- if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
- *q++ = *p;
- if (slen != (size_t)-1) {
- slen -= 2;
- }
- p += 2;
- dlen--;
- retval++;
- if (!lastp)
- break;
- } else {
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- goto general_case;
-#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
-#endif
- }
- }
- return retval;
- } else if (from != CH_UCS2 && to == CH_UCS2) {
- const unsigned char *p = (const unsigned char *)src;
- unsigned char *q = (unsigned char *)dest;
- size_t retval = 0;
- size_t slen = srclen;
- size_t dlen = destlen;
- unsigned char lastp;
-
- /* If all characters are ascii, fast path here. */
- while (slen && (dlen >= 2)) {
- if ((lastp = *p) <= 0x7F) {
- *q++ = *p++;
- *q++ = '\0';
- if (slen != (size_t)-1) {
- slen--;
- }
- dlen -= 2;
- retval += 2;
- if (!lastp)
- break;
- } else {
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- goto general_case;
-#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
-#endif
- }
- }
- return retval;
- }
-
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- general_case:
-#endif
- return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);
-}
-
-/**
- * Convert between character sets, allocating a new buffer for the result.
- *
- * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
- * @param srclen length of source buffer.
- * @param dest always set at least to NULL
- * @note -1 is not accepted for srclen.
- *
- * @returns Size in bytes of the converted string; or -1 in case of error.
- *
- * Ensure the srclen contains the terminating zero.
- *
- * I hate the goto's in this function. It's embarressing.....
- * There has to be a cleaner way to do this. JRA.
- **/
-
-size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
- void const *src, size_t srclen, void **dest, BOOL allow_bad_conv)
-{
- size_t i_len, o_len, destlen = MAX(srclen, 512);
- size_t retval;
- const char *inbuf = (const char *)src;
- char *outbuf = NULL, *ob = NULL;
- smb_iconv_t descriptor;
-
- *dest = NULL;
-
- if (src == NULL || srclen == (size_t)-1)
- return (size_t)-1;
- if (srclen == 0)
- return 0;
-
- lazy_initialize_conv();
-
- descriptor = conv_handles[from][to];
-
- if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
- if (!conv_silent)
- DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
- return (size_t)-1;
- }
-
- convert:
-
- if ((destlen*2) < destlen) {
- /* wrapped ! abort. */
- if (!conv_silent)
- DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
- if (!ctx)
- SAFE_FREE(outbuf);
- return (size_t)-1;
- } else {
- destlen = destlen * 2;
- }
-
- if (ctx)
- ob = (char *)talloc_realloc(ctx, ob, destlen);
- else
- ob = (char *)Realloc(ob, destlen);
-
- if (!ob) {
- DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
- if (!ctx)
- SAFE_FREE(outbuf);
- return (size_t)-1;
- } else {
- outbuf = ob;
- }
- i_len = srclen;
- o_len = destlen;
-
- again:
-
- retval = smb_iconv(descriptor,
- (char **)&inbuf, &i_len,
- &outbuf, &o_len);
- if(retval == (size_t)-1) {
- const char *reason="unknown error";
- switch(errno) {
- case EINVAL:
- reason="Incomplete multibyte sequence";
- if (!conv_silent)
- DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
- if (allow_bad_conv)
- goto use_as_is;
- break;
- case E2BIG:
- goto convert;
- case EILSEQ:
- reason="Illegal multibyte sequence";
- if (!conv_silent)
- DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
- if (allow_bad_conv)
- goto use_as_is;
- break;
- }
- if (!conv_silent)
- DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
- /* smb_panic(reason); */
- return (size_t)-1;
- }
-
- out:
-
- destlen = destlen - o_len;
- if (ctx)
- *dest = (char *)talloc_realloc(ctx,ob,destlen);
- else
- *dest = (char *)Realloc(ob,destlen);
- if (destlen && !*dest) {
- DEBUG(0, ("convert_string_allocate: out of memory!\n"));
- if (!ctx)
- SAFE_FREE(ob);
- return (size_t)-1;
- }
-
- return destlen;
-
- use_as_is:
-
- /*
- * Conversion not supported. This is actually an error, but there are so
- * many misconfigured iconv systems and smb.conf's out there we can't just
- * fail. Do a very bad conversion instead.... JRA.
- */
-
- {
- if (o_len == 0 || i_len == 0)
- goto out;
-
- if (from == CH_UCS2 && to != CH_UCS2) {
- /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
- if (i_len < 2)
- goto out;
-
- if (i_len >= 2) {
- *outbuf = inbuf[0];
-
- outbuf++;
- o_len--;
-
- inbuf += 2;
- i_len -= 2;
- }
-
- if (o_len == 0 || i_len == 0)
- goto out;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else if (from != CH_UCS2 && to == CH_UCS2) {
- /* Can't convert to ucs2 - just widen by adding zero. */
- if (o_len < 2)
- goto out;
-
- outbuf[0] = inbuf[0];
- outbuf[1] = '\0';
-
- inbuf++;
- i_len--;
-
- outbuf += 2;
- o_len -= 2;
-
- if (o_len == 0 || i_len == 0)
- goto out;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else if (from != CH_UCS2 && to != CH_UCS2) {
- /* Failed multibyte to multibyte. Just copy 1 char and
- try again. */
- outbuf[0] = inbuf[0];
-
- inbuf++;
- i_len--;
-
- outbuf++;
- o_len--;
-
- if (o_len == 0 || i_len == 0)
- goto out;
-
- /* Keep trying with the next char... */
- goto again;
-
- } else {
- /* Keep compiler happy.... */
- goto out;
- }
- }
-}
-
-/**
- * Convert between character sets, allocating a new buffer using talloc for the result.
- *
- * @param srclen length of source buffer.
- * @param dest always set at least to NULL
- * @note -1 is not accepted for srclen.
- *
- * @returns Size in bytes of the converted string; or -1 in case of error.
- **/
-static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
- void const *src, size_t srclen, void **dest, BOOL allow_bad_conv)
-{
- size_t dest_len;
-
- *dest = NULL;
- dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest, allow_bad_conv);
- if (dest_len == (size_t)-1)
- return (size_t)-1;
- if (*dest == NULL)
- return (size_t)-1;
- return dest_len;
-}
+ }
+}
+
+static void init_iso8859_1(int codepage) {
+
+ setupmaps();
+
+ if (codepage == 437) {
+ /* MSDOS Code Page 437 -> ISO-8859-1 */
+ update_map("\xA1\xAD\xA2\x98\xA3\x9C\xA4\xED\xA5\x9D\xA6\xB3\xA7\xEE");
+ update_map("\xAA\xA6\xAB\xAE\xAC\xAA\xAE\xE9\xAF\xC4");
+ update_map("\xB0\xF8\xB1\xF1\xB2\xFD\xB5\xE6\xB7\xFA\xBA\xA7\xBC\xAC\xBD\xAB\xBF\xA8");
+ update_map("\xC0\x85\xC1\xA0\xC2\x83\xC4\x8E\xC5\x8F\xC6\x92\xC7\x80\xC8\x8A");
+ update_map("\xC9\x90\xCA\x88\xCB\x89\xCC\x8D\xCD\xA1\xCE\x8C\xCF\x8B");
+ update_map("\xD1\xA5\xD2\x96\xD3\xA2\xD4\x93\xD6\x99\xD9\x97\xDA\xA3\xDB\x96\xDC\x9A\xDF\xE1");
+ update_map("\xE0\x85\xE1\xA0\xE2\x83\xE4\x84\xE5\x86\xE6\x91\xE7\x87\xE8\x8A\xE9\x82\xEA\x88\xEB\x89\xEC\x8D\xED\xA1\xEE\x8C\xEF\x8B");
+ update_map("\xF0\xEB\xF1\xA4\xF2\x95\xF3\xA2\xF4\x93\xF6\x94\xF7\xF6\xF8\xED\xF9\x97\xFA\xA3\xFB\x96\xFC\x81\xFF\x98");
+ } else {
+ /* MSDOS Code Page 850 -> ISO-8859-1 */
+ update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
+ update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
+ update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
+ update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
+ update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
+ update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
+ update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
+ update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
+ update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
+ update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
+ update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
+ update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+ }
+}
+
+static void init_iso8859_15(int codepage) {
+
+ setupmaps();
+
+
+ if (codepage == 775) {
+ /* MSDOS Code Page 775 -> ISO-8859-15 this is for estonian */
+update_map("\240\377\242\226\243\234\246\276\247\365");
+update_map("\250\325\251\250\253\256\254\252\255\360\256\251");
+update_map("\260\370\261\361\262\375\263\374\264\317\265\346\266\364\267\372");
+update_map("\270\330\271\373\273\257");
+update_map("\304\216\305\217\306\222");
+update_map("\311\220");
+update_map("\323\340\325\345\326\231\327\236");
+update_map("\330\235\334\232\337\341");
+update_map("\344\204\345\206\346\221");
+update_map("\351\202");
+update_map("\363\242\365\344\366\224\367\366");
+update_map("\370\233\374\201");
+ } else {
+ /* MSDOS Code Page 850 -> ISO-8859-15 */
+update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\321\247\365");
+update_map("\250\320\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
+update_map("\260\370\261\361\262\375\263\374\264\350\265\346\266\364\267\372");
+update_map("\270\347\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
+update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
+update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
+update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
+update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
+update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
+update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
+update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
+update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+}
+}
+
+/* Init for eastern european languages. */
+
+static void init_iso8859_2(void) {
+
+ setupmaps();
+
+/*
+ * Tranlation table created by Petr Hubeny <psh@capitol.cz>
+ * Requires client code page = 852
+ * and character set = ISO8859-2 in smb.conf
+ */
-size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
-{
- size_t size;
- smb_ucs2_t *buffer;
-
- size = push_ucs2_allocate(&buffer, src);
- if (size == (size_t)-1) {
- smb_panic("failed to create UCS2 buffer");
- }
- if (!strupper_w(buffer) && (dest == src)) {
- free(buffer);
- return srclen;
- }
-
- size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);
- free(buffer);
- return size;
+/* MSDOS Code Page 852 -> ISO-8859-2 */
+update_map("\240\377"); /* Fix for non-breaking space */
+update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365");
+update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275");
+update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363");
+update_map("\270\367\271\347\272\255\273\234\274\253\275\361\276\247\277\276");
+update_map("\300\350\301\265\302\266\303\306\304\216\305\221\306\217\307\200");
+update_map("\310\254\311\220\312\250\313\323\314\267\315\326\316\327\317\322");
+update_map("\320\321\321\343\322\325\323\340\324\342\325\212\326\231\327\236");
+update_map("\330\374\331\336\332\351\333\353\334\232\335\355\336\335\337\341");
+update_map("\340\352\341\240\342\203\343\307\344\204\345\222\346\206\347\207");
+update_map("\350\237\351\202\352\251\353\211\354\330\355\241\356\214\357\324");
+update_map("\360\320\361\344\362\345\363\242\364\223\365\213\366\224\367\366");
+update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372");
}
-/**
- strdup() a unix string to upper case.
- Max size is pstring.
-**/
+/* Init for russian language (iso8859-5) */
-char *strdup_upper(const char *s)
+/* Added by Max Khon <max@iclub.nsu.ru> */
+/* 1125 mapping added by Alexander Bokovoy <a.bokovoy@sam-solutions.net> */
+static void init_iso8859_5(int codepage)
{
- pstring out_buffer;
- const unsigned char *p = (const unsigned char *)s;
- unsigned char *q = (unsigned char *)out_buffer;
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- while (1) {
- if (*p & 0x80)
- break;
- *q++ = toupper(*p);
- if (!*p)
- break;
- p++;
- if (p - ( const unsigned char *)s >= sizeof(pstring))
- break;
- }
-
- if (*p) {
- /* MB case. */
- size_t size;
- wpstring buffer;
- size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer), True);
- if (size == (size_t)-1) {
- return NULL;
- }
-
- strupper_w(buffer);
-
- size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True);
- if (size == (size_t)-1) {
- return NULL;
- }
- }
-
- return strdup(out_buffer);
+ setupmaps();
+
+ if (codepage == 1125) {
+/* MSDOS Code Page 1125 -> ISO8859-5 */
+update_map ("\360\374\361\361\340\340\341\341\320\240\342\342\321\241\300\220");
+update_map ("\364\365\343\343\322\242\301\221\260\200\344\344\323\243\302\222");
+update_map ("\261\201\366\367\241\360\345\345\324\244\303\223\262\202\367\371");
+update_map ("\346\346\325\245\304\224\263\203\347\347\326\246\305\225\264\204");
+update_map ("\244\364\350\350\327\247\306\226\265\205\351\351\330\250\307\227");
+update_map ("\266\206\246\366\331\251\310\230\267\207\247\370\311\231\270\210");
+update_map ("\271\211");
+ } else {
+/* MSDOS Code Page 866 -> ISO8859-5 */
+update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
+update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
+update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227");
+update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237");
+update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247");
+update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257");
+update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
+update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
+update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
+update_map("\360\374\240\377");
+ }
+}
+
+/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
+
+static void init_iso8859_7(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 737 -> ISO-8859-7 (Greek-Hellenic) */
+
+update_map("\301\200\302\201\303\202\304\203\305\204\306\205\307\206");
+update_map("\310\207\311\210\312\211\313\212\314\213\315\214\316\215\317\216");
+update_map("\320\217\321\220\323\221\324\222\325\223\326\224\327\225");
+update_map("\330\226\331\227");
+update_map("\341\230\342\231\343\232\344\233\345\234\346\235\347\236");
+update_map("\350\237\351\240\352\241\353\242\354\243\355\244\356\245\357\246");
+update_map("\360\247\361\250\362\252\363\251\364\253\365\254\366\255\367\256");
+update_map("\370\257\371\340");
+update_map("\332\364\333\365\334\341\335\342\336\343\337\345");
+update_map("\372\344\373\350\374\346\375\347\376\351");
+update_map("\266\352");
+update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
+}
+
+/* Added by Yedidyah Bar-David (didi@tau.ac.il) */
+
+static void init_iso8859_8(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 862 -> ISO-8859-8 (Hebrew) */
+
+update_map("\340\200\341\201\342\202\343\203\344\204\345\205\346\206\347\207");
+update_map("\350\210\351\211\352\212\353\213\354\214\355\215\356\216\357\217");
+update_map("\360\220\361\221\362\222\363\223\364\224\365\225\366\226\367\227");
+update_map("\370\230\371\231\372\232");
+}
+
+/* Added by Deniz Akkus (akkus@alum.mit.edu) */
+
+static void init_iso8859_9(void)
+{
+ setupmaps();
+
+ /* MSDOS Code Page 857 -> ISO-8859-9 (Turkish) */
+
+ update_map("\xa0\xff\xa1\xad\xa2\xbd\xa3\x9c\xa4\xcf\xA5\xbe\xa6\xdd\xa7\xf5");
+ update_map("\xa8\xf9\xa9\xb8\xaa\xd1\xab\xae\xac\xaa\xad\xf0\xae\xa9\xaf\xee");
+ update_map("\xb0\xf8\xb1\xf1\xb2\xfd\xb3\xfc\xb4\xef\xb5\xe6\xb6\xf4\xb7\xfa");
+ update_map("\xb8\xf7\xb9\xfb\xba\xd0\xbb\xaf\xbc\xac\xbd\xab\xbe\xf3\xbf\xa8");
+ update_map("\xc0\xb7\xc1\xb5\xc2\xb6\xc3\xc7\xc4\x8e\xc5\x8f\xc6\x92\xc7\x80");
+ update_map("\xc8\xd4\xc9\x90\xca\xd2\xcb\xd3\xcc\xde\xcd\xd6\xce\xd7\xcf\xd8");
+ update_map("\xd0\xa6\xd1\xa5\xd2\xe3\xd3\xe0\xd4\xe2\xd5\xe5\xd6\x99\xd7\xe8");
+ update_map("\xd8\x9d\xd9\xeb\xda\xe9\xdb\xea\xdc\x9a\xdd\x98\xde\x9e\xdf\xe1");
+ update_map("\xe0\x85\xe1\xa0\xe2\x83\xe3\xc6\xe4\x84\xe5\x86\xe6\x91\xe7\x87");
+ update_map("\xe8\x8a\xe9\x82\xea\x88\xeb\x89\xec\xec\xed\xa1\xee\x8c\xef\x8b");
+ update_map("\xf0\xa7\xf1\xa4\xf2\x95\xf3\xa2\xf4\x93\xf5\xe4\xf6\x94\xf7\xf6");
+ update_map("\xf8\x9b\xf9\x97\xfa\xa3\xfb\x96\xfc\x81\xfd\x8d\xfe\x9f\xff\xed");
+}
+
+/* init for Baltic Rim */
+
+static void init_iso8859_13(void) {
+
+ setupmaps();
+
+ /* MSDOS Code Page 775 -> ISO-8859-13 */
+update_map("\240\377\241\246\242\226\243\234\244\237\245\367\246\247\247\365");
+update_map("\250\235\251\250\252\212\253\256\254\252\255\360\256\251\257\222");
+update_map("\260\370\261\361\262\375\263\374\264\362\265\346\266\364\267\372");
+update_map("\270\233\271\373\272\213\273\257\274\254\275\253\276\363\277\221");
+update_map("\300\265\301\275\302\240\303\200\304\216\305\217\306\267\307\355");
+update_map("\310\266\311\220\312\215\313\270\314\225\315\350\316\241\317\352");
+update_map("\320\276\321\343\322\356\323\340\324\342\325\345\326\231\327\236");
+update_map("\330\306\331\255\332\227\333\307\334\232\335\243\336\317\337\341");
+update_map("\340\320\341\324\342\203\343\207\344\204\345\206\346\322\347\211");
+update_map("\350\321\351\202\352\245\353\323\354\205\355\351\356\214\357\353");
+update_map("\360\325\361\347\362\354\363\242\364\223\365\344\366\224\367\366");
+update_map("\370\326\371\210\372\230\373\327\374\201\375\244\376\330\377\357");
+}
+
+/* Init for russian language (koi8) */
+
+static void init_koi8_r(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 866 -> KOI8-R */
+update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
+update_map("\210\302\211\301\212\305\213\337\214\334\215\333\216\335\217\336");
+update_map("\220\260\221\261\222\262\223\364\224\376\225\371\226\373\227\367");
+update_map("\230\363\231\362\232\377\233\365\234\370\235\375\236\372\237\366");
+update_map("\240\315\241\272\242\325\243\361\244\326\245\311\246\270\247\267");
+update_map("\250\273\251\324\252\323\253\310\254\276\255\275\256\274\257\306");
+update_map("\260\307\261\314\262\265\263\360\264\266\265\271\266\321\267\322");
+update_map("\270\313\271\317\272\320\273\312\274\330\275\327\276\316\277\374");
+update_map("\300\356\301\240\302\241\303\346\304\244\305\245\306\344\307\243");
+update_map("\310\345\311\250\312\251\313\252\314\253\315\254\316\255\317\256");
+update_map("\320\257\321\357\322\340\323\341\324\342\325\343\326\246\327\242");
+update_map("\330\354\331\353\332\247\333\350\334\355\335\351\336\347\337\352");
+update_map("\340\236\341\200\342\201\343\226\344\204\345\205\346\224\347\203");
+update_map("\350\225\351\210\352\211\353\212\354\213\355\214\356\215\357\216");
+update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
+update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
}
-size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
-{
- size_t size;
- smb_ucs2_t *buffer = NULL;
-
- size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
- (void **) &buffer, True);
- if (size == (size_t)-1 || !buffer) {
- smb_panic("failed to create UCS2 buffer");
- }
- if (!strlower_w(buffer) && (dest == src)) {
- SAFE_FREE(buffer);
- return srclen;
- }
- size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);
- SAFE_FREE(buffer);
- return size;
-}
-
-/**
- strdup() a unix string to lower case.
-**/
+/* Init for Bulgarian, Belarussian, and variants of Russian and Ukrainian locales */
+/* Patch from Alexander Bokovoy. */
+
+static void init_1251(int codepage)
+{
+ setupmaps();
+
+ if (codepage == 866) {
+/* MSDOS Code Page 866 -> 1251 */
+update_map ("\240\377\241\366\242\367\244\375");
+update_map ("\250\360\252\362\257\364");
+update_map ("\260\370\267\372");
+update_map ("\270\361\271\374\272\363\277\365");
+update_map ("\300\200\301\201\302\202\303\203\304\204\305\205\306\206\307\207");
+update_map ("\310\210\311\211\312\212\313\213\314\214\315\215\316\216\317\217");
+update_map ("\320\220\321\221\322\222\323\223\324\224\325\225\326\226\327\227");
+update_map ("\330\230\331\231\332\232\333\233\334\234\335\235\336\236\337\237");
+update_map ("\340\240\341\241\342\242\343\243\344\244\345\245\346\246\347\247");
+update_map ("\350\250\351\251\352\252\353\253\354\254\355\255\356\256\357\257");
+update_map ("\360\340\361\341\362\342\363\343\364\344\365\345\366\346\367\347");
+update_map ("\370\350\371\351\372\352\373\353\374\354\375\355\376\356\377\357");
+ } else {
+/* MSDOS Code Page 1125 (Ukranian) -> 1251 */
+update_map ("\271\374\270\361\360\340\361\341\340\240\362\342\341\241\320\220");
+update_map ("\272\365\363\343\342\242\321\221\300\200\364\344\343\243\322\222");
+update_map ("\301\201\263\367\250\360\365\345\344\244\323\223\302\202\277\371");
+update_map ("\366\346\345\245\324\224\303\203\367\347\346\246\325\225\304\204");
+update_map ("\252\364\370\350\347\247\326\226\305\205\371\351\350\250\327\227");
+update_map ("\306\206\262\366\351\251\330\230\307\207\257\370\331\231\310\210");
+update_map ("\311\211\245\362\264\363");
+ }
+}
+
+
+/* Init for ukrainian language (koi8-u) */
+/* Added by Oleg Deribas <older@iname.com> */
+
+static void init_koi8_u(int codepage)
+{
+ setupmaps();
+
+ if (codepage == 866) {
+ /* MSDOS Code Page 866 -> KOI8-U */
+ update_map("\x80\xC4\x81\xB3\x82\xDA\x83\xBF\x84\xC0\x85\xD9\x86\xC3\x87\xB4\x88\xC2");
+ update_map("\x89\xC1\x8A\xC5\x8B\xDF\x8C\xDC\x8D\xDB\x8E\xDD\x8F\xDE\x90\xB0\x91\xB1");
+ update_map("\x92\xB2\x94\xFE\x95\xF9\x96\xFB\x9A\xFF\x9C\xF8\x9E\xFA\xA0\xCD\xA1\xBA");
+ update_map("\xA2\xD5\xA3\xF1\xA4\xF3\xA5\xC9\xA7\xF5\xA8\xBB\xA9\xD4\xAA\xD3\xAB\xC8");
+ update_map("\xAC\xBE\xAE\xBC\xAF\xC6\xB0\xC7\xB1\xCC\xB2\xB5\xB3\xF0\xB4\xF2\xB5\xB9");
+ update_map("\xB7\xF4\xB8\xCB\xB9\xCF\xBA\xD0\xBB\xCA\xBC\xD8\xBE\xCE\xC0\xEE\xC1\xA0");
+ update_map("\xC2\xA1\xC3\xE6\xC4\xA4\xC5\xA5\xC6\xE4\xC7\xA3\xC8\xE5\xC9\xA8\xCA\xA9");
+ update_map("\xCB\xAA\xCC\xAB\xCD\xAC\xCE\xAD\xCF\xAE\xD0\xAF\xD1\xEF\xD2\xE0\xD3\xE1");
+ update_map("\xD4\xE2\xD5\xE3\xD6\xA6\xD7\xA2\xD8\xEC\xD9\xEB\xDA\xA7\xDB\xE8\xDC\xED");
+ update_map("\xDD\xE9\xDE\xE7\xDF\xEA\xE0\x9E\xE1\x80\xE2\x81\xE3\x96\xE4\x84\xE5\x85");
+ update_map("\xE6\x94\xE7\x83\xE8\x95\xE9\x88\xEA\x89\xEB\x8A\xEC\x8B\xED\x8C\xEE\x8D");
+ update_map("\xEF\x8E\xF0\x8F\xF1\x9F\xF2\x90\xF3\x91\xF4\x92\xF5\x93\xF6\x86\xF7\x82");
+ update_map("\xF8\x9C\xF9\x9B\xFA\x87\xFB\x98\xFC\x9D\xFD\x99\xFE\x97\xFF\x9A");
+ } else {
+ /* MSDOS Code Page 1125 -> KOI8-U */
+ update_map("\x80\xC4\x81\xB3\x82\xDA\x83\xBF\x84\xC0\x85\xD9\x86\xC3\x87\xB4\x88\xC2\x89\xC1");
+ update_map("\x8A\xC5\x8B\xDF\x8C\xDC\x8D\xDB\x8E\xDD\x8F\xDE\x90\xB0\x91\xB1\x92\xB2\x94\xFE");
+ update_map("\x96\xFB\x9A\xFF\x9E\xFA\xA0\xCD\xA1\xBA\xA2\xD5\xA3\xF1\xA4\xF5\xA5\xC9\xA6\xF7");
+ update_map("\xA7\xF9\xA8\xBB\xA9\xD4\xAA\xD3\xAB\xC8\xAC\xBE\xAD\xF3\xAE\xBC\xAF\xC6\xB0\xC7");
+ update_map("\xB1\xCC\xB2\xB5\xB3\xF0\xB4\xF4\xB5\xB9\xB6\xF6\xB7\xF8\xB8\xCB\xB9\xCF\xBA\xD0");
+ update_map("\xBB\xCA\xBC\xD8\xBD\xF2\xBE\xCE\xC0\xEE\xC1\xA0\xC2\xA1\xC3\xE6\xC4\xA4\xC5\xA5");
+ update_map("\xC6\xE4\xC7\xA3\xC8\xE5\xC9\xA8\xCA\xA9\xCB\xAA\xCC\xAB\xCD\xAC\xCE\xAD\xCF\xAE");
+ update_map("\xD0\xAF\xD1\xEF\xD2\xE0\xD3\xE1\xD4\xE2\xD5\xE3\xD6\xA6\xD7\xA2\xD8\xEC\xD9\xEB");
+ update_map("\xDA\xA7\xDB\xE8\xDC\xED\xDD\xE9\xDE\xE7\xDF\xEA\xE0\x9E\xE1\x80\xE2\x81\xE3\x96");
+ update_map("\xE4\x84\xE5\x85\xE6\x94\xE7\x83\xE8\x95\xE9\x88\xEA\x89\xEB\x8A\xEC\x8B\xED\x8C");
+ update_map("\xEE\x8D\xEF\x8E\xF0\x8F\xF1\x9F\xF2\x90\xF3\x91\xF4\x92\xF5\x93\xF6\x86\xF7\x82");
+ update_map("\xF8\x9C\xF9\x9B\xFA\x87\xFB\x98\xFC\x9D\xFD\x99\xFE\x97\xFF\x9A");
+ }
+}
+
+/* Init for ROMAN-8 (HP-UX) */
+
+static void init_roman8(void) {
+
+ setupmaps();
+
+/* MSDOS Code Page 850 -> ROMAN8 */
+update_map("\240\377\241\267\242\266\243\324\244\322\245\323\246\327\247\330");
+update_map("\250\357\253\371\255\353\256\352\257\234");
+update_map("\260\356\261\355\262\354\263\370\264\200\265\207\266\245\267\244");
+update_map("\270\255\271\250\272\317\273\234\274\276\275\365\276\237\277\275");
+update_map("\300\203\301\210\302\223\303\226\304\240\305\202\306\242\307\243");
+update_map("\310\205\311\212\312\225\313\227\314\204\315\211\316\224\317\201");
+update_map("\320\217\321\214\322\235\323\222\324\206\325\241\326\233\327\221");
+update_map("\330\216\331\215\332\231\333\232\334\220\335\213\336\341\337\342");
+update_map("\340\265\341\307\342\306\343\321\344\320\345\326\346\336\347\340");
+update_map("\350\343\351\345\352\344\355\351\357\230");
+update_map("\360\350\361\347\362\372\363\346\364\364\365\363\366\360\367\254");
+update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
+}
+
+/*
+ * Convert unix to dos
+ */
-char *strdup_lower(const char *s)
+char *unix2dos_format_static(const char *str)
{
- size_t size;
- smb_ucs2_t *buffer = NULL;
- char *out_buffer;
-
- size = push_ucs2_allocate(&buffer, s);
- if (size == -1 || !buffer) {
- return NULL;
- }
+ const char *p;
+ char *dp;
- strlower_w(buffer);
-
- size = pull_ucs2_allocate(&out_buffer, buffer);
- SAFE_FREE(buffer);
+ if (!mapsinited)
+ initmaps();
- if (size == (size_t)-1) {
+ if (!str)
return NULL;
- }
-
- return out_buffer;
-}
-
-static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
-{
- if (flags & (STR_NOALIGN|STR_ASCII))
- return 0;
- return PTR_DIFF(p, base_ptr) & 1;
-}
-
-
-/**
- * Copy a string from a char* unix src to a dos codepage string destination.
- *
- * @return the number of bytes occupied by the string in the destination.
- *
- * @param flags can include
- * <dl>
- * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
- * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
- * </dl>
- *
- * @param dest_len the maximum length in bytes allowed in the
- * destination. If @p dest_len is -1 then no maximum is used.
- **/
-size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
-{
- size_t src_len = strlen(src);
- pstring tmpbuf;
-
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
-
- if (flags & STR_UPPER) {
- pstrcpy(tmpbuf, src);
- strupper_m(tmpbuf);
- src = tmpbuf;
- }
-
- if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
- src_len++;
-
- return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
-}
-
-size_t push_ascii_fstring(void *dest, const char *src)
-{
- return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
-}
-
-size_t push_ascii_pstring(void *dest, const char *src)
-{
- return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
-}
-
-/********************************************************************
- Push an nstring - ensure null terminated. Written by
- moriyama@miraclelinux.com (MORIYAMA Masayuki).
-********************************************************************/
-
-size_t push_ascii_nstring(void *dest, const char *src)
-{
- size_t i, buffer_len, dest_len;
- smb_ucs2_t *buffer;
-
- conv_silent = True;
- buffer_len = push_ucs2_allocate(&buffer, src);
- if (buffer_len == (size_t)-1) {
- smb_panic("failed to create UCS2 buffer");
- }
-
- /* We're using buffer_len below to count ucs2 characters, not bytes. */
- buffer_len /= sizeof(smb_ucs2_t);
-
- dest_len = 0;
- for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {
- unsigned char mb[10];
- /* Convert one smb_ucs2_t character at a time. */
- size_t mb_len = convert_string(CH_UCS2, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);
- if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {
- memcpy((char *)dest + dest_len, mb, mb_len);
- dest_len += mb_len;
- } else {
- errno = E2BIG;
- break;
- }
- }
- ((char *)dest)[dest_len] = '\0';
-
- SAFE_FREE(buffer);
- conv_silent = False;
- return dest_len;
-}
-
-/**
- * Copy a string from a dos codepage source to a unix char* destination.
- *
- * The resulting string in "dest" is always null terminated.
- *
- * @param flags can have:
- * <dl>
- * <dt>STR_TERMINATE</dt>
- * <dd>STR_TERMINATE means the string in @p src
- * is null terminated, and src_len is ignored.</dd>
- * </dl>
- *
- * @param src_len is the length of the source area in bytes.
- * @returns the number of bytes occupied by the string in @p src.
- **/
-size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
-{
- size_t ret;
-
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
-
- if (flags & STR_TERMINATE) {
- if (src_len == (size_t)-1) {
- src_len = strlen(src) + 1;
- } else {
- size_t len = strnlen(src, src_len);
- if (len < src_len)
- len++;
- src_len = len;
- }
- }
-
- ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True);
- if (ret == (size_t)-1) {
- dest_len = 0;
- }
-
- if (dest_len)
- dest[MIN(ret, dest_len-1)] = 0;
- else
- dest[0] = 0;
-
- return src_len;
-}
-
-size_t pull_ascii_pstring(char *dest, const void *src)
-{
- return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
-}
-
-size_t pull_ascii_fstring(char *dest, const void *src)
-{
- return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
-}
-
-/* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
-
-size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
-{
- return pull_ascii(dest, src, dest_len, sizeof(nstring), STR_TERMINATE);
-}
-
-/**
- * Copy a string from a char* src to a unicode destination.
- *
- * @returns the number of bytes occupied by the string in the destination.
- *
- * @param flags can have:
- *
- * <dl>
- * <dt>STR_TERMINATE <dd>means include the null termination.
- * <dt>STR_UPPER <dd>means uppercase in the destination.
- * <dt>STR_NOALIGN <dd>means don't do alignment.
- * </dl>
- *
- * @param dest_len is the maximum length allowed in the
- * destination. If dest_len is -1 then no maxiumum is used.
- **/
-
-size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
-{
- size_t len=0;
- size_t src_len;
- size_t ret;
-
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
-
- if (flags & STR_TERMINATE)
- src_len = (size_t)-1;
- else
- src_len = strlen(src);
-
- if (ucs2_align(base_ptr, dest, flags)) {
- *(char *)dest = 0;
- dest = (void *)((char *)dest + 1);
- if (dest_len)
- dest_len--;
- len++;
- }
-
- /* ucs2 is always a multiple of 2 bytes */
- dest_len &= ~1;
-
- ret = convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len, True);
- if (ret == (size_t)-1) {
- return 0;
- }
-
- len += ret;
-
- if (flags & STR_UPPER) {
- smb_ucs2_t *dest_ucs2 = dest;
- size_t i;
- for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) {
- smb_ucs2_t v = toupper_w(dest_ucs2[i]);
- if (v != dest_ucs2[i]) {
- dest_ucs2[i] = v;
- }
- }
- }
-
- return len;
-}
-
-
-/**
- * Copy a string from a unix char* src to a UCS2 destination,
- * allocating a buffer using talloc().
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- * or -1 in case of error.
- **/
-size_t push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True);
-}
-
-
-/**
- * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- * or -1 in case of error.
- **/
-
-size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True);
-}
-
-/**
- Copy a string from a char* src to a UTF-8 destination.
- Return the number of bytes occupied by the string in the destination
- Flags can have:
- STR_TERMINATE means include the null termination
- STR_UPPER means uppercase in the destination
- dest_len is the maximum length allowed in the destination. If dest_len
- is -1 then no maxiumum is used.
-**/
-
-static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
-{
- size_t src_len = strlen(src);
- pstring tmpbuf;
-
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
-
- if (flags & STR_UPPER) {
- pstrcpy(tmpbuf, src);
- strupper_m(tmpbuf);
- src = tmpbuf;
- }
-
- if (flags & STR_TERMINATE)
- src_len++;
-
- return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
-}
-
-size_t push_utf8_fstring(void *dest, const char *src)
-{
- return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
-}
-
-/**
- * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
-
-size_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest, True);
-}
-
-/**
- * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
-
-size_t push_utf8_allocate(char **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, True);
-}
-
-/**
- Copy a string from a ucs2 source to a unix char* destination.
- Flags can have:
- STR_TERMINATE means the string in src is null terminated.
- STR_NOALIGN means don't try to align.
- if STR_TERMINATE is set then src_len is ignored if it is -1.
- src_len is the length of the source area in bytes
- Return the number of bytes occupied by the string in src.
- The resulting string in "dest" is always null terminated.
-**/
-
-size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
-{
- size_t ret;
-
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
-
- if (ucs2_align(base_ptr, src, flags)) {
- src = (const void *)((const char *)src + 1);
- if (src_len != (size_t)-1)
- src_len--;
- }
-
- if (flags & STR_TERMINATE) {
- /* src_len -1 is the default for null terminated strings. */
- if (src_len != (size_t)-1) {
- size_t len = strnlen_w(src, src_len/2);
- if (len < src_len/2)
- len++;
- src_len = len*2;
- }
- }
-
- /* ucs2 is always a multiple of 2 bytes */
- if (src_len != (size_t)-1)
- src_len &= ~1;
-
- ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len, True);
- if (ret == (size_t)-1) {
- return 0;
- }
-
- if (src_len == (size_t)-1)
- src_len = ret*2;
-
- if (dest_len)
- dest[MIN(ret, dest_len-1)] = 0;
- else
- dest[0] = 0;
-
- return src_len;
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = unix2dos[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
}
-size_t pull_ucs2_pstring(char *dest, const void *src)
+char *unix2dos_format(char *str)
{
- return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
-}
-
-size_t pull_ucs2_fstring(char *dest, const void *src)
-{
- return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
-}
+ char *p;
-/**
- * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
+ if (!mapsinited)
+ initmaps();
-size_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src)
-{
- size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True);
+ if (!str)
+ return NULL;
+ for (p = str; *p; p++)
+ *p = unix2dos[(unsigned char)*p];
+ return str;
}
-/**
- * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
+/*
+ * Convert dos to unix
+ */
-size_t pull_ucs2_allocate(char **dest, const smb_ucs2_t *src)
+char *dos2unix_format_static(const char *str)
{
- size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
- *dest = NULL;
- return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True);
-}
+ const char *p;
+ char *dp;
-/**
- * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
+ if (!mapsinited)
+ initmaps();
-size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True);
+ if (!str)
+ return NULL;
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = dos2unix[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
}
-/**
- * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer
- *
- * @param dest always set at least to NULL
- *
- * @returns The number of bytes occupied by the string in the destination
- **/
-
-size_t pull_utf8_allocate(char **dest, const char *src)
-{
- size_t src_len = strlen(src)+1;
- *dest = NULL;
- return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True);
-}
-
-/**
- Copy a string from a char* src to a unicode or ascii
- dos codepage destination choosing unicode or ascii based on the
- flags in the SMB buffer starting at base_ptr.
- Return the number of bytes occupied by the string in the destination.
- flags can have:
- STR_TERMINATE means include the null termination.
- STR_UPPER means uppercase in the destination.
- STR_ASCII use ascii even with unicode packet.
- STR_NOALIGN means don't do alignment.
- dest_len is the maximum length allowed in the destination. If dest_len
- is -1 then no maxiumum is used.
-**/
-
-size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
+char *dos2unix_format(char *str)
{
-#ifdef DEVELOPER
- /* We really need to zero fill here, not clobber
- * region, as we want to ensure that valgrind thinks
- * all of the outgoing buffer has been written to
- * so a send() or write() won't trap an error.
- * JRA.
- */
-#if 0
- if (dest_len != (size_t)-1)
- clobber_region(function, line, dest, dest_len);
-#else
- if (dest_len != (size_t)-1)
- memset(dest, '\0', dest_len);
-#endif
-#endif
+ char *p;
- if (!(flags & STR_ASCII) && \
- ((flags & STR_UNICODE || \
- (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
- return push_ucs2(base_ptr, dest, src, dest_len, flags);
- }
- return push_ascii(dest, src, dest_len, flags);
-}
-
-
-/**
- Copy a string from a unicode or ascii source (depending on
- the packet flags) to a char* destination.
- Flags can have:
- STR_TERMINATE means the string in src is null terminated.
- STR_UNICODE means to force as unicode.
- STR_ASCII use ascii even with unicode packet.
- STR_NOALIGN means don't do alignment.
- if STR_TERMINATE is set then src_len is ignored is it is -1
- src_len is the length of the source area in bytes.
- Return the number of bytes occupied by the string in src.
- The resulting string in "dest" is always null terminated.
-**/
-
-size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
-{
-#ifdef DEVELOPER
- if (dest_len != (size_t)-1)
- clobber_region(function, line, dest, dest_len);
-#endif
+ if (!mapsinited)
+ initmaps();
- if (!(flags & STR_ASCII) && \
- ((flags & STR_UNICODE || \
- (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
- return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
- }
- return pull_ascii(dest, src, dest_len, src_len, flags);
-}
+ if (!str)
+ return NULL;
-size_t align_string(const void *base_ptr, const char *p, int flags)
-{
- if (!(flags & STR_ASCII) && \
- ((flags & STR_UNICODE || \
- (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
- return ucs2_align(base_ptr, p, flags);
- }
- return 0;
+ for (p = str; *p; p++)
+ *p = dos2unix[(unsigned char)*p];
+ return str;
}
-/****************************************************************
- Calculate the size (in bytes) of the next multibyte character in
- our internal character set. Note that p must be pointing to a
- valid mb char, not within one.
-****************************************************************/
-size_t next_mb_char_size(const char *s)
-{
- size_t i;
-
- if (!(*s & 0x80))
- return 1; /* ascii. */
-
- conv_silent = True;
- for ( i = 1; i <=4; i++ ) {
- smb_ucs2_t uc;
- if (convert_string(CH_UNIX, CH_UCS2, s, i, &uc, 2, False) == 2) {
-#if 0 /* JRATEST */
- DEBUG(10,("next_mb_char_size: size %u at string %s\n",
- (unsigned int)i, s));
-#endif
- conv_silent = False;
- return i;
- }
- }
- /* We're hosed - we don't know how big this is... */
- DEBUG(10,("next_mb_char_size: unknown size at string %s\n", s));
- conv_silent = False;
- return 1;
+/*
+ * Interpret character set.
+ */
+void interpret_character_set(char *str, int codepage)
+{
+ if (strequal (str, "iso8859-1")) {
+ init_iso8859_1(codepage);
+ } else if (strequal (str, "iso8859-2")) {
+ init_iso8859_2();
+ } else if (strequal (str, "iso8859-5")) {
+ init_iso8859_5(codepage);
+ } else if (strequal (str, "iso8859-8")) {
+ init_iso8859_8();
+ } else if (strequal (str, "iso8859-7")) {
+ init_iso8859_7();
+ } else if (strequal (str, "iso8859-9")) {
+ init_iso8859_9();
+ } else if (strequal (str, "iso8859-13")) {
+ init_iso8859_13();
+ } else if (strequal (str, "iso8859-15")) {
+ init_iso8859_15(codepage);
+ } else if (strequal (str, "koi8-r")) {
+ init_koi8_r();
+ } else if (strequal (str, "koi8-u")) {
+ init_koi8_u(codepage);
+ } else if (strequal (str, "1251u")) {
+ init_1251(1125);
+ } else if (strequal (str, "1251")) {
+ init_1251(866);
+ } else if (strequal (str, "roman8")) {
+ init_roman8();
+ } else {
+ DEBUG(0,("unrecognized character set %s\n", str));
+ }
+
+ load_unix_unicode_map(str, True);
}
diff --git a/source/lib/charset.c b/source/lib/charset.c
new file mode 100755
index 00000000000..78500c6c89c
--- /dev/null
+++ b/source/lib/charset.c
@@ -0,0 +1,398 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Character set handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define CHARSET_C
+#include "includes.h"
+
+/*
+ * Codepage definitions.
+ */
+
+#if !defined(KANJI)
+/* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */
+unsigned char cp_850[][4] = {
+/* dec col/row oct hex description */
+/* 133 08/05 205 85 a grave */
+/* 183 11/07 267 B7 A grave */ {0x85,0xB7,1,1},
+/* 160 10/00 240 A0 a acute */
+/* 181 11/05 265 B5 A acute */ {0xA0,0xB5,1,1},
+/* 131 08/03 203 83 a circumflex */
+/* 182 11/06 266 B6 A circumflex */ {0x83,0xB6,1,1},
+/* 198 12/06 306 C6 a tilde */
+/* 199 12/07 307 C7 A tilde */ {0xC6,0xC7,1,1},
+/* 132 08/04 204 84 a diaeresis */
+/* 142 08/14 216 8E A diaeresis */ {0x84,0x8E,1,1},
+/* 134 08/06 206 86 a ring */
+/* 143 08/15 217 8F A ring */ {0x86,0x8F,1,1},
+/* 145 09/01 221 91 ae diphthong */
+/* 146 09/02 222 92 AE diphthong */ {0x91,0x92,1,1},
+/* 135 08/07 207 87 c cedilla */
+/* 128 08/00 200 80 C cedilla */ {0x87,0x80,1,1},
+/* 138 08/10 212 8A e grave */
+/* 212 13/04 324 D4 E grave */ {0x8A,0xD4,1,1},
+/* 130 08/02 202 82 e acute */
+/* 144 09/00 220 90 E acute */ {0x82,0x90,1,1},
+/* 136 08/08 210 88 e circumflex */
+/* 210 13/02 322 D2 E circumflex */ {0x88,0xD2,1,1},
+/* 137 08/09 211 89 e diaeresis */
+/* 211 13/03 323 D3 E diaeresis */ {0x89,0xD3,1,1},
+/* 141 08/13 215 8D i grave */
+/* 222 13/14 336 DE I grave */ {0x8D,0xDE,1,1},
+/* 161 10/01 241 A1 i acute */
+/* 214 13/06 326 D6 I acute */ {0xA1,0xD6,1,1},
+/* 140 08/12 214 8C i circumflex */
+/* 215 13/07 327 D7 I circumflex */ {0x8C,0xD7,1,1},
+/* 139 08/11 213 8B i diaeresis */
+/* 216 13/08 330 D8 I diaeresis */ {0x8B,0xD8,1,1},
+/* 208 13/00 320 D0 Icelandic eth */
+/* 209 13/01 321 D1 Icelandic Eth */ {0xD0,0xD1,1,1},
+/* 164 10/04 244 A4 n tilde */
+/* 165 10/05 245 A5 N tilde */ {0xA4,0xA5,1,1},
+/* 149 09/05 225 95 o grave */
+/* 227 14/03 343 E3 O grave */ {0x95,0xE3,1,1},
+/* 162 10/02 242 A2 o acute */
+/* 224 14/00 340 E0 O acute */ {0xA2,0xE0,1,1},
+/* 147 09/03 223 93 o circumflex */
+/* 226 14/02 342 E2 O circumflex */ {0x93,0xE2,1,1},
+/* 228 14/04 344 E4 o tilde */
+/* 229 14/05 345 E5 O tilde */ {0xE4,0xE5,1,1},
+/* 148 09/04 224 94 o diaeresis */
+/* 153 09/09 231 99 O diaeresis */ {0x94,0x99,1,1},
+/* 155 09/11 233 9B o slash */
+/* 157 09/13 235 9D O slash */ {0x9B,0x9D,1,1},
+/* 151 09/07 227 97 u grave */
+/* 235 14/11 353 EB U grave */ {0x97,0xEB,1,1},
+/* 163 10/03 243 A3 u acute */
+/* 233 14/09 351 E9 U acute */ {0xA3,0xE9,1,1},
+/* 150 09/06 226 96 u circumflex */
+/* 234 14/10 352 EA U circumflex */ {0x96,0xEA,1,1},
+/* 129 08/01 201 81 u diaeresis */
+/* 154 09/10 232 9A U diaeresis */ {0x81,0x9A,1,1},
+/* 236 14/12 354 EC y acute */
+/* 237 14/13 355 ED Y acute */ {0xEC,0xED,1,1},
+/* 231 14/07 347 E7 Icelandic thorn */
+/* 232 14/08 350 E8 Icelandic Thorn */ {0xE7,0xE8,1,1},
+
+ {0x9C,0,0,0}, /* Pound */
+ {0,0,0,0}
+};
+#else /* KANJI */
+/* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */
+unsigned char cp_932[][4] = {
+ {0,0,0,0}
+};
+#endif /* KANJI */
+
+char xx_dos_char_map[256];
+char xx_upper_char_map[256];
+char xx_lower_char_map[256];
+
+char *dos_char_map = xx_dos_char_map;
+char *upper_char_map = xx_upper_char_map;
+char *lower_char_map = xx_lower_char_map;
+
+/*
+ * This code has been extended to deal with ascynchronous mappings
+ * like MS-DOS Latin US (Code page 437) where things like :
+ * a acute are capitalized to 'A', but the reverse mapping
+ * must not hold true. This allows the filename case insensitive
+ * matching in do_match() to work, as the DOS/Win95/NT client
+ * uses 'A' as a mask to match against characters like a acute.
+ * This is the meaning behind the parameters that allow a
+ * mapping from lower to upper, but not upper to lower.
+ */
+
+static void add_dos_char(int lower, BOOL map_lower_to_upper,
+ int upper, BOOL map_upper_to_lower)
+{
+ lower &= 0xff;
+ upper &= 0xff;
+ DEBUGADD( 6, ( "Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n",
+ lower, upper,
+ map_lower_to_upper ? "True" : "False",
+ map_upper_to_lower ? "True" : "False" ) );
+ if (lower) dos_char_map[lower] = 1;
+ if (upper) dos_char_map[upper] = 1;
+ lower_char_map[lower] = (char)lower; /* Define tolower(lower) */
+ upper_char_map[upper] = (char)upper; /* Define toupper(upper) */
+ if (lower && upper) {
+ if(map_upper_to_lower)
+ lower_char_map[upper] = (char)lower;
+ if(map_lower_to_upper)
+ upper_char_map[lower] = (char)upper;
+ }
+}
+
+/****************************************************************************
+initialise the charset arrays
+****************************************************************************/
+void charset_initialise(void)
+{
+ int i;
+
+#ifdef LC_ALL
+ /* include <locale.h> in includes.h if available for OS */
+ /* we take only standard 7-bit ASCII definitions from ctype */
+ setlocale(LC_ALL,"C");
+#endif
+
+ for (i= 0;i<=255;i++) {
+ dos_char_map[i] = 0;
+ }
+
+ for (i=0;i<=127;i++) {
+ if (isalnum(i) || strchr("._^$~!#%&-{}()@'`",(char)i))
+ add_dos_char(i,False,0,False);
+ }
+
+ for (i=0; i<=255; i++) {
+ char c = (char)i;
+ upper_char_map[i] = lower_char_map[i] = c;
+
+ /* Some systems have buggy isupper/islower for characters
+ above 127. Best not to rely on them. */
+ if(i < 128) {
+ if (isupper((int)c)) lower_char_map[i] = tolower(c);
+ if (islower((int)c)) upper_char_map[i] = toupper(c);
+ }
+ }
+}
+
+/****************************************************************************
+load the client codepage.
+****************************************************************************/
+
+typedef unsigned char (*codepage_p)[4];
+
+static codepage_p load_client_codepage( int client_codepage )
+{
+ pstring codepage_file_name;
+ unsigned char buf[8];
+ int fd = -1;
+ SMB_OFF_T size;
+ codepage_p cp_p = NULL;
+ SMB_STRUCT_STAT st;
+
+ DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage));
+
+ if(strlen(lp_codepagedir()) + 14 > sizeof(codepage_file_name))
+ {
+ DEBUG(0,("load_client_codepage: filename too long to load\n"));
+ return NULL;
+ }
+
+ pstrcpy(codepage_file_name, lp_codepagedir());
+ pstrcat(codepage_file_name, "/");
+ pstrcat(codepage_file_name, "codepage.");
+ slprintf(&codepage_file_name[strlen(codepage_file_name)],
+ sizeof(pstring)-(strlen(codepage_file_name)+1)-1,
+ "%03d",
+ client_codepage);
+
+ if(sys_stat(codepage_file_name,&st)!=0)
+ {
+ DEBUG(0,("load_client_codepage: filename %s does not exist.\n",
+ codepage_file_name));
+ return NULL;
+ }
+
+ /* Check if it is at least big enough to hold the required
+ data. Should be 2 byte version, 2 byte codepage, 4 byte length,
+ plus zero or more bytes of data. Note that the data cannot be more
+ than 4 * MAXCODEPAGELINES bytes.
+ */
+ size = st.st_size;
+
+ if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES))
+ {
+ DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \
+code page file (size=%d).\n", codepage_file_name, (int)size));
+ return NULL;
+ }
+
+ /* Read the first 8 bytes of the codepage file - check
+ the version number and code page number. All the data
+ is held in little endian format.
+ */
+
+ if((fd = open(codepage_file_name, O_RDONLY)) == -1)
+ {
+ DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n",
+ codepage_file_name, strerror(errno)));
+ return NULL;
+ }
+
+ if (read(fd, buf, CODEPAGE_HEADER_SIZE)!=CODEPAGE_HEADER_SIZE)
+ {
+ DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n",
+ codepage_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /* Check the version value */
+ if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID)
+ {
+ DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \
+Needed %hu, got %hu.\n",
+ codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID,
+ SVAL(buf,CODEPAGE_VERSION_OFFSET)));
+ goto clean_and_exit;
+ }
+
+ /* Check the codepage matches */
+ if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage)
+ {
+ DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \
+Needed %hu, got %hu.\n",
+ codepage_file_name, (uint16)client_codepage,
+ SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET)));
+ goto clean_and_exit;
+ }
+
+ /* Check the length is correct. */
+ if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != (size - CODEPAGE_HEADER_SIZE))
+ {
+ DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \
+Needed %u, got %u.\n", codepage_file_name, (uint32)(size - CODEPAGE_HEADER_SIZE),
+ IVAL(buf,CODEPAGE_LENGTH_OFFSET)));
+ goto clean_and_exit;
+ }
+
+ size -= CODEPAGE_HEADER_SIZE; /* Remove header */
+
+ /* Make sure the size is a multiple of 4. */
+ if((size % 4 ) != 0)
+ {
+ DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \
+multiple of 4.\n", codepage_file_name));
+ goto clean_and_exit;
+ }
+
+ /* Allocate space for the code page file and read it all in. */
+ if((cp_p = (codepage_p)malloc( size + 4 )) == NULL)
+ {
+ DEBUG(0,("load_client_codepage: malloc fail.\n"));
+ goto clean_and_exit;
+ }
+
+ if(read(fd, (char *)cp_p, size)!=size)
+ {
+ DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n",
+ codepage_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /* Ensure array is correctly terminated. */
+ memset(((char *)cp_p) + size, '\0', 4);
+
+ close(fd);
+ return cp_p;
+
+clean_and_exit:
+
+ /* pseudo destructor :-) */
+
+ if(fd != -1)
+ close(fd);
+ SAFE_FREE(cp_p);
+ return NULL;
+}
+
+/****************************************************************************
+ Initialise the client codepage.
+****************************************************************************/
+
+void codepage_initialise(int client_codepage)
+{
+ int i;
+ static codepage_p cp = NULL;
+
+ if(cp != NULL)
+ {
+ DEBUG(6,
+ ("codepage_initialise: called twice - ignoring second client code page = %d\n",
+ client_codepage));
+ return;
+ }
+
+ DEBUG(6,("codepage_initialise: client code page = %d\n", client_codepage));
+
+ /*
+ * Known client codepages - these can be added to.
+ */
+ cp = load_client_codepage( client_codepage );
+
+ if(cp == NULL)
+ {
+#ifdef KANJI
+ DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
+for code page %d failed. Using default client codepage 932\n",
+ lp_codepagedir(), client_codepage, client_codepage));
+ cp = cp_932;
+ client_codepage = KANJI_CODEPAGE;
+#else /* KANJI */
+ DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
+for code page %d failed. Using default client codepage 850\n",
+ lp_codepagedir(), client_codepage, client_codepage));
+ cp = cp_850;
+ client_codepage = MSDOS_LATIN_1_CODEPAGE;
+#endif /* KANJI */
+ }
+
+ /*
+ * Setup the function pointers for the loaded codepage.
+ */
+ initialize_multibyte_vectors( client_codepage );
+
+ if(cp)
+ {
+ for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++)
+ add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
+ }
+
+ /* Try and load the unicode map. */
+ load_dos_unicode_map(client_codepage);
+ load_unix_unicode_map("iso8859-1", False); /* This will be reset by character set = XXX */
+}
+
+/*******************************************************************
+add characters depending on a string passed by the user
+********************************************************************/
+void add_char_string(const char *s)
+{
+ char *extra_chars = (char *)strdup(s);
+ char *t;
+ if (!extra_chars) return;
+
+ for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) {
+ char c1=0,c2=0;
+ int i1=0,i2=0;
+ if (isdigit((unsigned char)*t) || (*t)=='-') {
+ sscanf(t,"%i:%i",&i1,&i2);
+ add_dos_char(i1,True,i2,True);
+ } else {
+ sscanf(t,"%c:%c",&c1,&c2);
+ add_dos_char((unsigned char)c1,True,(unsigned char)c2, True);
+ }
+ }
+
+ SAFE_FREE(extra_chars);
+}
diff --git a/source/lib/clobber.c b/source/lib/clobber.c
deleted file mode 100644
index fb3a0dc2815..00000000000
--- a/source/lib/clobber.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions
- Copyright (C) Martin Pool 2003
- Copyright (C) Andrew Bartlett 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef DEVELOPER
-const char *global_clobber_region_function;
-unsigned int global_clobber_region_line;
-#endif
-
-/**
- * In developer builds, clobber a region of memory.
- *
- * If we think a string buffer is longer than it really is, this ought
- * to make the failure obvious, by segfaulting (if in the heap) or by
- * killing the return address (on the stack), or by trapping under a
- * memory debugger.
- *
- * This is meant to catch possible string overflows, even if the
- * actual string copied is not big enough to cause an overflow.
- *
- * In addition, under Valgrind the buffer is marked as uninitialized.
- **/
-void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
-{
-#ifdef DEVELOPER
- global_clobber_region_function = fn;
- global_clobber_region_line = line;
-
- /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */
- memset(dest, 0xF1, len);
-#ifdef VALGRIND
- /* Even though we just wrote to this, from the application's
- * point of view it is not initialized.
- *
- * (This is not redundant with the clobbering above. The
- * marking might not actually take effect if we're not running
- * under valgrind.) */
- VALGRIND_MAKE_WRITABLE(dest, len);
-#endif /* VALGRIND */
-#endif /* DEVELOPER */
-}
diff --git a/source/lib/crc32.c b/source/lib/crc32.c
index da3aeaa901d..e026fbf8615 100644
--- a/source/lib/crc32.c
+++ b/source/lib/crc32.c
@@ -8,7 +8,7 @@
#include "includes.h"
-static const unsigned long CRCTable[256] =
+static unsigned long CRCTable[256] =
{
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,
0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,
@@ -55,9 +55,10 @@ static const unsigned long CRCTable[256] =
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
};
-uint32 crc32_calc_buffer( const char *buffer, uint32 count)
+uint32 crc32_calc_buffer( char *buffer, uint32 count)
{
- uint32 crc=0xffffffff, i;
+ uint32 crc=0xffffffff;
+ int i;
for(i=0;i<count;i++)
crc = (crc>>8) ^ CRCTable[(buffer[i] ^ crc) & 0xff];
crc^=0xffffffff;
diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c
deleted file mode 100644
index 83afc591a15..00000000000
--- a/source/lib/data_blob.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Easy management of byte-length data
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*******************************************************************
- free() a data blob
-*******************************************************************/
-static void free_data_blob(DATA_BLOB *d)
-{
- if ((d) && (d->free)) {
- SAFE_FREE(d->data);
- }
-}
-
-/*******************************************************************
- construct a data blob, must be freed with data_blob_free()
- you can pass NULL for p and get a blank data blob
-*******************************************************************/
-DATA_BLOB data_blob(const void *p, size_t length)
-{
- DATA_BLOB ret;
-
- if (!length) {
- ZERO_STRUCT(ret);
- return ret;
- }
-
- if (p) {
- ret.data = smb_xmemdup(p, length);
- } else {
- ret.data = smb_xmalloc(length);
- }
- ret.length = length;
- ret.free = free_data_blob;
- return ret;
-}
-
-/*******************************************************************
- construct a data blob, using supplied TALLOC_CTX
-*******************************************************************/
-DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
-{
- DATA_BLOB ret;
-
- if (!length) {
- ZERO_STRUCT(ret);
- return ret;
- }
-
- if (p) {
- ret.data = talloc_memdup(mem_ctx, p, length);
- if (ret.data == NULL)
- smb_panic("data_blob_talloc: talloc_memdup failed.\n");
- } else {
- ret.data = talloc(mem_ctx, length);
- if (ret.data == NULL)
- smb_panic("data_blob_talloc: talloc failed.\n");
- }
-
- ret.length = length;
- ret.free = NULL;
- return ret;
-}
-
-/*******************************************************************
-free a data blob
-*******************************************************************/
-void data_blob_free(DATA_BLOB *d)
-{
- if (d) {
- if (d->free) {
- (d->free)(d);
- }
- d->length = 0;
- }
-}
-
-/*******************************************************************
-clear a DATA_BLOB's contents
-*******************************************************************/
-static void data_blob_clear(DATA_BLOB *d)
-{
- if (d->data) {
- memset(d->data, 0, d->length);
- }
-}
-
-/*******************************************************************
-free a data blob and clear its contents
-*******************************************************************/
-void data_blob_clear_free(DATA_BLOB *d)
-{
- data_blob_clear(d);
- data_blob_free(d);
-}
-
diff --git a/source/lib/debug.c b/source/lib/debug.c
index b0d8ff35230..b32a58c17cd 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Elrond 2002
- Copyright (C) Simo Sorce 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,7 +26,7 @@
*
* FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
* format_bufr[FORMAT_BUFR_MAX] should always be reserved
- * for a terminating null byte.
+ * for a terminating nul byte.
*/
#define FORMAT_BUFR_MAX ( sizeof( format_bufr ) - 1 )
@@ -74,37 +73,20 @@
*
* dbf - Global debug file handle.
* debugf - Debug file name.
+ * append_log - If True, then the output file will be opened in append
+ * mode.
* DEBUGLEVEL - System-wide debug message limit. Messages with message-
* levels higher than DEBUGLEVEL will not be processed.
*/
-XFILE *dbf = NULL;
+FILE *dbf = NULL;
pstring debugf = "";
-BOOL debug_warn_unknown_class = True;
-BOOL debug_auto_add_unknown_class = True;
-BOOL AllowDebugChange = True;
-
-/*
- used to check if the user specified a
- logfile on the command line
-*/
-BOOL override_logfile;
-
-
-/*
- * This is to allow assignment to DEBUGLEVEL before the debug
- * system has been initialised.
- */
-static int debug_all_class_hack = 1;
-static BOOL debug_all_class_isset_hack = True;
-
-static int debug_num_classes = 0;
-int *DEBUGLEVEL_CLASS = &debug_all_class_hack;
-BOOL *DEBUGLEVEL_CLASS_ISSET = &debug_all_class_isset_hack;
-
-/* DEBUGLEVEL is #defined to *debug_level */
-int DEBUGLEVEL = &debug_all_class_hack;
+BOOL append_log = False;
+int DEBUGLEVEL_CLASS[DBGC_LAST];
+int DEBUGLEVEL = DEBUGLEVEL_CLASS;
+BOOL AllowDebugChange = True;
+int parsed_debuglevel_class[DBGC_LAST];
/* -------------------------------------------------------------------------- **
* Internal variables.
@@ -143,122 +125,40 @@ static size_t format_pos = 0;
static BOOL log_overflow = False;
/*
- * Define all the debug class selection names here. Names *MUST NOT* contain
- * white space. There must be one name for each DBGC_<class name>, and they
- * must be in the table in the order of DBGC_<class name>..
- */
-static const char *default_classname_table[] = {
- "all", /* DBGC_ALL; index refs traditional DEBUGLEVEL */
- "tdb", /* DBGC_TDB */
+* Define all the debug class selection names here. Names *MUST NOT* contain
+* white space. There must be one name for each DBGC_<class name>, and they
+* must be in the table in the order of DBGC_<class name>..
+*/
+const char *classname_table[] = {
+ "all", /* DBGC_ALL; index references traditional DEBUGLEVEL */
+ "tdb", /* DBGC_TDB */
"printdrivers", /* DBGC_PRINTDRIVERS */
- "lanman", /* DBGC_LANMAN */
- "smb", /* DBGC_SMB */
- "rpc_parse", /* DBGC_RPC_PARSE */
- "rpc_srv", /* DBGC_RPC_SRV */
- "rpc_cli", /* DBGC_RPC_CLI */
- "passdb", /* DBGC_PASSDB */
- "sam", /* DBGC_SAM */
- "auth", /* DBGC_AUTH */
- "winbind", /* DBGC_WINBIND */
- "vfs", /* DBGC_VFS */
- "idmap", /* DBGC_IDMAP */
- "quota", /* DBGC_QUOTA */
- "acls", /* DBGC_QUOTA */
- NULL
+ "lanman", /* DBGC_LANMAN */
};
-static char **classname_table = NULL;
-
/* -------------------------------------------------------------------------- **
* Functions...
*/
-
-/****************************************************************************
-utility lists registered debug class names's
-****************************************************************************/
-
-#define MAX_CLASS_NAME_SIZE 1024
-
-static char *debug_list_class_names_and_levels(void)
-{
- int i, dim;
- char **list;
- char *buf = NULL;
- char *b;
- BOOL err = False;
-
- if (DEBUGLEVEL_CLASS == &debug_all_class_hack)
- return NULL;
-
- list = calloc(debug_num_classes + 1, sizeof(char *));
- if (!list)
- return NULL;
-
- /* prepare strings */
- for (i = 0, dim = 0; i < debug_num_classes; i++) {
- int l = asprintf(&list[i],
- "%s:%d ",
- classname_table[i],
- DEBUGLEVEL_CLASS_ISSET[i]?DEBUGLEVEL_CLASS[i]:DEBUGLEVEL);
- if (l < 0 || l > MAX_CLASS_NAME_SIZE) {
- err = True;
- goto done;
- }
- dim += l;
- }
-
- /* create single string list - add space for newline */
- b = buf = malloc(dim+1);
- if (!buf) {
- err = True;
- goto done;
- }
- for (i = 0; i < debug_num_classes; i++) {
- int l = strlen(list[i]);
- strncpy(b, list[i], l);
- b = b + l;
- }
- b[-1] = '\n'; /* replace last space with newline */
- b[0] = '\0'; /* null terminate string */
-
-done:
- /* free strings list */
- for (i = 0; i < debug_num_classes; i++)
- if (list[i]) free(list[i]);
- free(list);
-
- if (err) {
- if (buf)
- free(buf);
- return NULL;
- } else {
- return buf;
- }
-}
-
/****************************************************************************
utility access to debug class names's
****************************************************************************/
-const char *debug_classname_from_index(int ndx)
+const char* debug_classname_from_index(int ndx)
{
- if (ndx < 0 || ndx >= debug_num_classes)
- return NULL;
- else
- return classname_table[ndx];
+ return classname_table[ndx];
}
/****************************************************************************
-utility to translate names to debug class index's (internal version)
+utility to translate names to debug class index's
****************************************************************************/
-static int debug_lookup_classname_int(const char* classname)
+int debug_lookup_classname(char* classname)
{
int i;
if (!classname) return -1;
- for (i=0; i < debug_num_classes; i++) {
+ for (i=0; i<DBGC_LAST; i++) {
if (strcmp(classname, classname_table[i])==0)
return i;
}
@@ -266,148 +166,34 @@ static int debug_lookup_classname_int(const char* classname)
}
/****************************************************************************
-Add a new debug class to the system
-****************************************************************************/
-int debug_add_class(const char *classname)
-{
- int ndx;
- void *new_ptr;
-
- if (!classname)
- return -1;
-
- /* check the init has yet been called */
- debug_init();
-
- ndx = debug_lookup_classname_int(classname);
- if (ndx >= 0)
- return ndx;
- ndx = debug_num_classes;
-
- new_ptr = DEBUGLEVEL_CLASS;
- if (DEBUGLEVEL_CLASS == &debug_all_class_hack)
- {
- /* Initial loading... */
- new_ptr = NULL;
- }
- new_ptr = Realloc(new_ptr,
- sizeof(int) * (debug_num_classes + 1));
- if (!new_ptr)
- return -1;
- DEBUGLEVEL_CLASS = new_ptr;
- DEBUGLEVEL_CLASS[ndx] = 0;
-
- /* debug_level is the pointer used for the DEBUGLEVEL-thingy */
- if (ndx==0)
- {
- /* Transfer the initial level from debug_all_class_hack */
- DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL;
- }
- debug_level = DEBUGLEVEL_CLASS;
-
- new_ptr = DEBUGLEVEL_CLASS_ISSET;
- if (new_ptr == &debug_all_class_isset_hack)
- {
- new_ptr = NULL;
- }
- new_ptr = Realloc(new_ptr,
- sizeof(BOOL) * (debug_num_classes + 1));
- if (!new_ptr)
- return -1;
- DEBUGLEVEL_CLASS_ISSET = new_ptr;
- DEBUGLEVEL_CLASS_ISSET[ndx] = False;
-
- new_ptr = Realloc(classname_table,
- sizeof(char *) * (debug_num_classes + 1));
- if (!new_ptr)
- return -1;
- classname_table = new_ptr;
-
- classname_table[ndx] = strdup(classname);
- if (! classname_table[ndx])
- return -1;
-
- debug_num_classes++;
-
- return ndx;
-}
-
-/****************************************************************************
-utility to translate names to debug class index's (public version)
-****************************************************************************/
-int debug_lookup_classname(const char *classname)
-{
- int ndx;
-
- if (!classname || !*classname) return -1;
-
- ndx = debug_lookup_classname_int(classname);
-
- if (ndx != -1)
- return ndx;
-
- if (debug_warn_unknown_class)
- {
- DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
- classname));
- }
- if (debug_auto_add_unknown_class)
- {
- return debug_add_class(classname);
- }
- return -1;
-}
-
-
-/****************************************************************************
-dump the current registered debug levels
-****************************************************************************/
-static void debug_dump_status(int level)
-{
- int q;
-
- DEBUG(level, ("INFO: Current debug levels:\n"));
- for (q = 0; q < debug_num_classes; q++)
- {
- DEBUGADD(level, (" %s: %s/%d\n",
- classname_table[q],
- (DEBUGLEVEL_CLASS_ISSET[q]
- ? "True" : "False"),
- DEBUGLEVEL_CLASS[q]));
- }
-}
-
-/****************************************************************************
parse the debug levels from smbcontrol. Example debug level parameter:
printdrivers:7
****************************************************************************/
-static BOOL debug_parse_params(char **params)
+BOOL debug_parse_params(char **params, int *debuglevel_class)
{
int i, ndx;
char *class_name;
char *class_level;
+
+ /* Set the new debug level array to the current DEBUGLEVEL array */
+ memcpy(debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
- if (!params)
- return False;
-
- /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
+ /* Allow DBGC_ALL to be specifies w/o requiring its class name e.g."10"
* v.s. "all:10", this is the traditional way to set DEBUGLEVEL
*/
if (isdigit((int)params[0][0])) {
- DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
- DEBUGLEVEL_CLASS_ISSET[DBGC_ALL] = True;
+ debuglevel_class[DBGC_ALL] = atoi(params[0]);
i = 1; /* start processing at the next params */
}
else
- i = 0; /* DBGC_ALL not specified OR class name was included */
+ i = 0; /* DBGC_ALL not specified OR calss name was included */
/* Fill in new debug class levels */
- for (; i < debug_num_classes && params[i]; i++) {
+ for (; i < DBGC_LAST && params[i]; i++) {
if ((class_name=strtok(params[i],":")) &&
(class_level=strtok(NULL, "\0")) &&
((ndx = debug_lookup_classname(class_name)) != -1)) {
- DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
- DEBUGLEVEL_CLASS_ISSET[ndx] = True;
+ debuglevel_class[ndx] = atoi(class_level);
} else {
DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
return False;
@@ -422,96 +208,69 @@ parse the debug levels from smb.conf. Example debug level string:
3 tdb:5 printdrivers:7
Note: the 1st param has no "name:" preceeding it.
****************************************************************************/
-BOOL debug_parse_levels(const char *params_str)
+BOOL debug_parse_levels(char *params_str)
{
- char **params;
+ int i;
+ char *params[DBGC_LAST];
+ int debuglevel_class[DBGC_LAST];
- /* Just in case */
- debug_init();
+ ZERO_ARRAY(params);
+ ZERO_ARRAY(debuglevel_class);
- if (AllowDebugChange == False)
- return True;
+ if ((params[0]=strtok(params_str," ,"))) {
+ for (i=1; i<DBGC_LAST;i++) {
+ if ((params[i]=strtok(NULL," ,"))==NULL)
+ break;
+ }
+ }
+ else
+ return False;
- params = str_list_make(params_str, NULL);
+ if (AllowDebugChange == False) {
+ int old_debuglevel_class[DBGC_LAST];
- if (debug_parse_params(params))
- {
- debug_dump_status(5);
- str_list_free(&params);
+ /* save current debug level */
+ memcpy(old_debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
+ if (debug_parse_params(params, debuglevel_class))
+ memcpy(parsed_debuglevel_class, debuglevel_class, sizeof(DEBUGLEVEL_CLASS));
+ memcpy(DEBUGLEVEL_CLASS, old_debuglevel_class, sizeof(old_debuglevel_class));
return True;
- } else {
- str_list_free(&params);
- return False;
}
+ if (debug_parse_params(params, debuglevel_class)) {
+ debug_message(MSG_DEBUG, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
+ return True;
+ } else
+ return False;
}
/****************************************************************************
receive a "set debug level" message
****************************************************************************/
-static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
+void debug_message(int msg_type, pid_t src, void *buf, size_t len)
{
- const char *params_str = buf;
+ int i;
- /* Check, it's a proper string! */
- if (params_str[len-1] != '\0')
- {
- DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
- (unsigned int)src, (unsigned int)getpid()));
- return;
+ /* Set the new DEBUGLEVEL_CLASS array from the pased array */
+ memcpy(DEBUGLEVEL_CLASS, buf, sizeof(DEBUGLEVEL_CLASS));
+
+ DEBUG(1,("INFO: Debug class %s level = %d (pid %u from pid %u)\n",
+ classname_table[DBGC_ALL],
+ DEBUGLEVEL_CLASS[DBGC_ALL], (unsigned int)getpid(), (unsigned int)src));
+
+ for (i=1; i<DBGC_LAST; i++) {
+ if (DEBUGLEVEL_CLASS[i])
+ DEBUGADD(1,("INFO: Debug class %s level = %d\n",
+ classname_table[i], DEBUGLEVEL_CLASS[i]));
}
-
- DEBUG(3, ("INFO: Remote set of debug to `%s' (pid %u from pid %u)\n",
- params_str, (unsigned int)getpid(), (unsigned int)src));
-
- debug_parse_levels(params_str);
}
/****************************************************************************
send a "set debug level" message
****************************************************************************/
-void debug_message_send(pid_t pid, const char *params_str)
+void debug_message_send(pid_t pid, int level)
{
- if (!params_str)
- return;
- message_send_pid(pid, MSG_DEBUG, params_str, strlen(params_str) + 1,
- False);
-}
-
-/****************************************************************************
- Return current debug level.
-****************************************************************************/
-
-static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
-{
- char *message = debug_list_class_names_and_levels();
-
- DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
- message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
-
- SAFE_FREE(message);
-}
-
-/****************************************************************************
-Init debugging (one time stuff)
-****************************************************************************/
-void debug_init(void)
-{
- static BOOL initialised = False;
- const char **p;
-
- if (initialised)
- return;
-
- initialised = True;
-
- message_register(MSG_DEBUG, debug_message);
- message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message);
-
- for(p = default_classname_table; *p; p++)
- {
- debug_add_class(*p);
- }
+ message_send_pid(pid, MSG_DEBUG, &level, sizeof(int), False);
}
@@ -521,7 +280,7 @@ void debug_init(void)
*/
void setup_logging(const char *pname, BOOL interactive)
{
- debug_init();
+ message_register(MSG_DEBUG, debug_message);
/* reset to allow multiple setup calls, going from interactive to
non-interactive */
@@ -530,18 +289,16 @@ void setup_logging(const char *pname, BOOL interactive)
if (interactive) {
stdout_logging = True;
- dbf = x_stdout;
- x_setbuf( x_stdout, NULL );
+ dbf = stdout;
}
#ifdef WITH_SYSLOG
else {
- const char *p = strrchr_m( pname,'/' );
+ char *p = strrchr( pname,'/' );
if (p)
pname = p + 1;
#ifdef LOG_DAEMON
openlog( pname, LOG_PID, SYSLOG_FACILITY );
-#else
- /* for old systems that have no facility codes. */
+#else /* for old systems that have no facility codes. */
openlog( pname, LOG_PID );
#endif
}
@@ -561,8 +318,7 @@ BOOL reopen_logs( void )
{
pstring fname;
mode_t oldumask;
- XFILE *new_dbf = NULL;
- XFILE *old_dbf = NULL;
+ FILE *new_dbf = NULL;
BOOL ret = True;
if (stdout_logging)
@@ -580,22 +336,25 @@ BOOL reopen_logs( void )
pstrcpy(fname, logfname);
}
- pstrcpy( debugf, fname );
- new_dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644);
+ pstrcpy(debugf, fname);
+
+ if (append_log)
+ new_dbf = sys_fopen( debugf, "a" );
+ else
+ new_dbf = sys_fopen( debugf, "w" );
if (!new_dbf) {
log_overflow = True;
DEBUG(0, ("Unable to open new log file %s: %s\n", debugf, strerror(errno)));
log_overflow = False;
if (dbf)
- x_fflush(dbf);
+ fflush(dbf);
ret = False;
} else {
- x_setbuf(new_dbf, NULL);
- old_dbf = dbf;
+ setbuf(new_dbf, NULL);
+ if (dbf)
+ (void) fclose(dbf);
dbf = new_dbf;
- if (old_dbf)
- (void) x_fclose(old_dbf);
}
/* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
@@ -605,12 +364,6 @@ BOOL reopen_logs( void )
force_check_log_size();
(void)umask(oldumask);
- /* Take over stderr to catch ouput into logs */
- if (dbf && sys_dup2(x_fileno(dbf), 2) == -1) {
- close_low_fds(True); /* Close stderr too, if dup2 can't point it
- at the logfile */
- }
-
return ret;
}
@@ -631,7 +384,7 @@ BOOL need_to_check_log_size( void )
{
int maxlog;
- if( debug_count < 100 )
+ if( debug_count++ < 100 )
return( False );
maxlog = lp_max_log_size() * 1024;
@@ -665,7 +418,7 @@ void check_log_size( void )
maxlog = lp_max_log_size() * 1024;
- if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
+ if( sys_fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
(void)reopen_logs();
if( dbf && get_file_size( debugf ) > maxlog ) {
pstring name;
@@ -686,13 +439,13 @@ void check_log_size( void )
if(dbf == NULL) {
/* This code should only be reached in very strange
- * circumstances. If we merely fail to open the new log we
- * should stick with the old one. ergo this should only be
- * reached when opening the logs for the first time: at
- * startup or when the log level is increased from zero.
- * -dwg 6 June 2000
- */
- dbf = x_fopen( "/dev/console", O_WRONLY, 0);
+ circumstances. If we merely fail to open the new log we
+ should stick with the old one. ergo this should only be
+ reached when opening the logs for the first time: at
+ startup or when the log level is increased from zero.
+ -dwg 6 June 2000
+ */
+ dbf = sys_fopen( "/dev/console", "w" );
if(dbf) {
DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
debugf ));
@@ -716,13 +469,11 @@ void check_log_size( void )
va_list ap;
int old_errno = errno;
- debug_count++;
-
if( stdout_logging )
{
va_start( ap, format_str );
if(dbf)
- (void)x_vfprintf( dbf, format_str, ap );
+ (void)vfprintf( dbf, format_str, ap );
va_end( ap );
errno = old_errno;
return( 0 );
@@ -736,11 +487,14 @@ void check_log_size( void )
{
mode_t oldumask = umask( 022 );
- dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
+ if( append_log )
+ dbf = sys_fopen( debugf, "a" );
+ else
+ dbf = sys_fopen( debugf, "w" );
(void)umask( oldumask );
if( dbf )
{
- x_setbuf( dbf, NULL );
+ setbuf( dbf, NULL );
}
else
{
@@ -789,10 +543,10 @@ void check_log_size( void )
{
va_start( ap, format_str );
if(dbf)
- (void)x_vfprintf( dbf, format_str, ap );
+ (void)vfprintf( dbf, format_str, ap );
va_end( ap );
if(dbf)
- (void)x_fflush( dbf );
+ (void)fflush( dbf );
}
errno = old_errno;
@@ -882,14 +636,14 @@ void dbgflush( void )
{
bufr_print();
if(dbf)
- (void)x_fflush( dbf );
+ (void)fflush( dbf );
} /* dbgflush */
/* ************************************************************************** **
* Print a Debug Header.
*
* Input: level - Debug level of the message (not the system-wide debug
- * level. )
+ * level.
* file - Pointer to a string containing the name of the file
* from which this function was called, or an empty string
* if the __FILE__ macro is not implemented.
diff --git a/source/lib/dmallocmsg.c b/source/lib/dmallocmsg.c
deleted file mode 100644
index a83ed518d7c..00000000000
--- a/source/lib/dmallocmsg.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- samba -- Unix SMB/CIFS implementation.
- Copyright (C) 2002 by Martin Pool
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * @file dmallocmsg.c
- *
- * Glue code to cause dmalloc info to come out when we receive a prod
- * over samba messaging.
- **/
-
-#ifdef ENABLE_DMALLOC
-static unsigned long our_dm_mark = 0;
-#endif /* ENABLE_DMALLOC */
-
-
-/**
- * Respond to a POOL_USAGE message by sending back string form of memory
- * usage stats.
- **/
-static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
- void *UNUSED(buf), size_t UNUSED(len))
-{
-#ifdef ENABLE_DMALLOC
- our_dm_mark = dmalloc_mark();
- DEBUG(2,("Got MSG_REQ_DMALLOC_MARK: mark set\n"));
-#else
- DEBUG(2,("Got MSG_REQ_DMALLOC_MARK but dmalloc not in this process\n"));
-#endif
-}
-
-
-
-static void msg_req_dmalloc_log_changed(int UNUSED(msg_type),
- pid_t UNUSED(src_pid),
- void *UNUSED(buf), size_t UNUSED(len))
-{
-#ifdef ENABLE_DMALLOC
- dmalloc_log_changed(our_dm_mark, True, True, True);
- DEBUG(2,("Got MSG_REQ_DMALLOC_LOG_CHANGED: done\n"));
-#else
- DEBUG(2,("Got MSG_REQ_DMALLOC_LOG_CHANGED but dmalloc not in this process\n"));
-#endif
-}
-
-
-/**
- * Register handler for MSG_REQ_POOL_USAGE
- **/
-void register_dmalloc_msgs(void)
-{
- message_register(MSG_REQ_DMALLOC_MARK, msg_req_dmalloc_mark);
- message_register(MSG_REQ_DMALLOC_LOG_CHANGED, msg_req_dmalloc_log_changed);
- DEBUG(2, ("Registered MSG_REQ_DMALLOC_MARK and LOG_CHANGED\n"));
-}
diff --git a/source/lib/domain_namemap.c b/source/lib/domain_namemap.c
new file mode 100755
index 00000000000..81b519a88d6
--- /dev/null
+++ b/source/lib/domain_namemap.c
@@ -0,0 +1,1300 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Jeremy Allison 1998.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * UNIX gid and Local or Domain SID resolution. This module resolves
+ * only those entries in the map files, it is *NOT* responsible for
+ * resolving UNIX groups not listed: that is an entirely different
+ * matter, altogether...
+ */
+
+/*
+ *
+ *
+
+ format of the file is:
+
+ unixname NT Group name
+ unixname Domain Admins (well-known Domain Group)
+ unixname DOMAIN_NAME\NT Group name
+ unixname OTHER_DOMAIN_NAME\NT Group name
+ unixname DOMAIN_NAME\Domain Admins (well-known Domain Group)
+ ....
+
+ if the DOMAIN_NAME\ component is left off, then your own domain is assumed.
+
+ *
+ *
+ */
+
+
+#include "includes.h"
+
+extern fstring global_myworkgroup;
+extern DOM_SID global_member_sid;
+extern fstring global_sam_name;
+extern DOM_SID global_sam_sid;
+extern DOM_SID global_sid_S_1_5_20;
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uid_t pwdb_user_rid_to_uid(uint32 user_rid)
+{
+ return ((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER;
+}
+
+/*******************************************************************
+ converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_group_rid_to_gid(uint32 group_rid)
+{
+ return ((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER;
+}
+
+/*******************************************************************
+ converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_alias_rid_to_gid(uint32 alias_rid)
+{
+ return ((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER;
+}
+
+/*******************************************************************
+ converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_gid_to_group_rid(uint32 gid)
+{
+ uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
+ return grp_rid;
+}
+
+/******************************************************************
+ converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_gid_to_alias_rid(uint32 gid)
+{
+ uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
+ return alias_rid;
+}
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_uid_to_user_rid(uint32 uid)
+{
+ uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
+ return user_rid;
+}
+
+/******************************************************************
+ converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+static BOOL pwdb_sam_sid_to_unixid(DOM_SID *sid, uint8 type, uint32 *id)
+{
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ if (!sid_equal(&global_sam_sid, &tmp_sid))
+ {
+ return False;
+ }
+
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ *id = pwdb_user_rid_to_uid(rid);
+ return True;
+ }
+ case SID_NAME_ALIAS:
+ {
+ *id = pwdb_alias_rid_to_gid(rid);
+ return True;
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ *id = pwdb_group_rid_to_gid(rid);
+ return True;
+ }
+ }
+ return False;
+}
+
+/******************************************************************
+ converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+static BOOL pwdb_unixid_to_sam_sid(uint32 id, uint8 type, DOM_SID *sid)
+{
+ sid_copy(sid, &global_sam_sid);
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ sid_append_rid(sid, pwdb_uid_to_user_rid(id));
+ return True;
+ }
+ case SID_NAME_ALIAS:
+ {
+ sid_append_rid(sid, pwdb_gid_to_alias_rid(id));
+ return True;
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ sid_append_rid(sid, pwdb_gid_to_group_rid(id));
+ return True;
+ }
+ }
+ return False;
+}
+
+/*******************************************************************
+ Decides if a RID is a well known RID.
+ ********************************************************************/
+static BOOL pwdb_rid_is_well_known(uint32 rid)
+{
+ return (rid < 1000);
+}
+
+/*******************************************************************
+ determines a rid's type. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 pwdb_rid_type(uint32 rid)
+{
+ /* lkcl i understand that NT attaches an enumeration to a RID
+ * such that it can be identified as either a user, group etc
+ * type: SID_ENUM_TYPE.
+ */
+ if (pwdb_rid_is_well_known(rid))
+ {
+ /*
+ * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
+ * and DOMAIN_USER_RID_GUEST.
+ */
+ if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
+ {
+ return RID_TYPE_USER;
+ }
+ if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
+ {
+ return RID_TYPE_GROUP;
+ }
+ if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
+ {
+ return RID_TYPE_ALIAS;
+ }
+ }
+ return (rid & RID_TYPE_MASK);
+}
+
+/*******************************************************************
+ checks whether rid is a user rid. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+BOOL pwdb_rid_is_user(uint32 rid)
+{
+ return pwdb_rid_type(rid) == RID_TYPE_USER;
+}
+
+/**************************************************************************
+ Groupname map functionality. The code loads a groupname map file and
+ (currently) loads it into a linked list. This is slow and memory
+ hungry, but can be changed into a more efficient storage format
+ if the demands on it become excessive.
+***************************************************************************/
+
+typedef struct name_map
+{
+ ubi_slNode next;
+ DOM_NAME_MAP grp;
+
+} name_map_entry;
+
+static ubi_slList groupname_map_list;
+static ubi_slList aliasname_map_list;
+static ubi_slList ntusrname_map_list;
+
+static void delete_name_entry(name_map_entry *gmep)
+{
+ SAFE_FREE(gmep->grp.nt_name);
+ SAFE_FREE(gmep->grp.nt_domain);
+ SAFE_FREE(gmep->grp.unix_name);
+ SAFE_FREE(gmep);
+}
+
+/**************************************************************************
+ Delete all the entries in the name map list.
+***************************************************************************/
+
+static void delete_map_list(ubi_slList *map_list)
+{
+ name_map_entry *gmep;
+
+ while ((gmep = (name_map_entry *)ubi_slRemHead(map_list )) != NULL)
+ {
+ delete_name_entry(gmep);
+ }
+}
+
+
+/**************************************************************************
+ makes a group sid out of a domain sid and a _unix_ gid.
+***************************************************************************/
+static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
+{
+ int ret = False;
+ fstring sid_str;
+
+ if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
+ {
+ DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
+ grp->nt_domain));
+ return False;
+ }
+
+ if (sid_equal(&grp->sid, &global_sid_S_1_5_20))
+ {
+ /*
+ * only builtin aliases are recognised in S-1-5-20
+ */
+ DEBUG(10,("make_mydomain_sid: group %s in builtin domain\n",
+ grp->nt_name));
+
+ if (lookup_builtin_alias_name(grp->nt_name, "BUILTIN", &grp->sid, &grp->type) != 0x0)
+ {
+ DEBUG(0,("unix group %s mapped to an unrecognised BUILTIN domain name %s\n",
+ grp->unix_name, grp->nt_name));
+ return False;
+ }
+ ret = True;
+ }
+ else if (lookup_wk_user_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
+ {
+ if (type != DOM_MAP_USER)
+ {
+ DEBUG(0,("well-known NT user %s\\%s listed in wrong map file\n",
+ grp->nt_domain, grp->nt_name));
+ return False;
+ }
+ ret = True;
+ }
+ else if (lookup_wk_group_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
+ {
+ if (type != DOM_MAP_DOMAIN)
+ {
+ DEBUG(0,("well-known NT group %s\\%s listed in wrong map file\n",
+ grp->nt_domain, grp->nt_name));
+ return False;
+ }
+ ret = True;
+ }
+ else
+ {
+ switch (type)
+ {
+ case DOM_MAP_USER:
+ {
+ grp->type = SID_NAME_USER;
+ break;
+ }
+ case DOM_MAP_DOMAIN:
+ {
+ grp->type = SID_NAME_DOM_GRP;
+ break;
+ }
+ case DOM_MAP_LOCAL:
+ {
+ grp->type = SID_NAME_ALIAS;
+ break;
+ }
+ }
+
+ ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid);
+ }
+
+ sid_to_string(sid_str, &grp->sid);
+ DEBUG(10,("nt name %s\\%s gid %d mapped to %s\n",
+ grp->nt_domain, grp->nt_name, grp->unix_id, sid_str));
+ return ret;
+}
+
+/**************************************************************************
+ makes a group sid out of an nt domain, nt group name or a unix group name.
+***************************************************************************/
+static BOOL unix_name_to_nt_name_info(DOM_NAME_MAP *map, DOM_MAP_TYPE type)
+{
+ /*
+ * Attempt to get the unix gid_t for this name.
+ */
+
+ DEBUG(5,("unix_name_to_nt_name_info: unix_name:%s\n", map->unix_name));
+
+ if (type == DOM_MAP_USER)
+ {
+ const struct passwd *pwptr = Get_Pwnam(map->unix_name, False);
+ if (pwptr == NULL)
+ {
+ DEBUG(0,("unix_name_to_nt_name_info: Get_Pwnam for user %s\
+failed. Error was %s.\n", map->unix_name, strerror(errno) ));
+ return False;
+ }
+
+ map->unix_id = (uint32)pwptr->pw_uid;
+ }
+ else
+ {
+ struct group *gptr = getgrnam(map->unix_name);
+ if (gptr == NULL)
+ {
+ DEBUG(0,("unix_name_to_nt_name_info: getgrnam for group %s\
+failed. Error was %s.\n", map->unix_name, strerror(errno) ));
+ return False;
+ }
+
+ map->unix_id = (uint32)gptr->gr_gid;
+ }
+
+ DEBUG(5,("unix_name_to_nt_name_info: unix gid:%d\n", map->unix_id));
+
+ /*
+ * Now map the name to an NT SID+RID.
+ */
+
+ if (map->nt_domain != NULL && !strequal(map->nt_domain, global_sam_name))
+ {
+ /* Must add client-call lookup code here, to
+ * resolve remote domain's sid and the group's rid,
+ * in that domain.
+ *
+ * NOTE: it is _incorrect_ to put code here that assumes
+ * we are responsible for lookups for foriegn domains' RIDs.
+ *
+ * for foriegn domains for which we are *NOT* the PDC, all
+ * we can be responsible for is the unix gid_t to which
+ * the foriegn SID+rid maps to, on this _local_ machine.
+ * we *CANNOT* make any short-cuts or assumptions about
+ * RIDs in a foriegn domain.
+ */
+
+ if (!map_domain_name_to_sid(&map->sid, &(map->nt_domain)))
+ {
+ DEBUG(0,("unix_name_to_nt_name_info: no known sid for %s\n",
+ map->nt_domain));
+ return False;
+ }
+ }
+
+ return make_mydomain_sid(map, type);
+}
+
+static BOOL make_name_entry(name_map_entry **new_ep,
+ char *nt_domain, char *nt_group, char *unix_group,
+ DOM_MAP_TYPE type)
+{
+ /*
+ * Create the list entry and add it onto the list.
+ */
+
+ DEBUG(5,("make_name_entry:%s,%s,%s\n", nt_domain, nt_group, unix_group));
+
+ (*new_ep) = (name_map_entry *)malloc(sizeof(name_map_entry));
+ if ((*new_ep) == NULL)
+ {
+ DEBUG(0,("make_name_entry: malloc fail for name_map_entry.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(*new_ep);
+
+ (*new_ep)->grp.nt_name = strdup(nt_group );
+ (*new_ep)->grp.nt_domain = strdup(nt_domain );
+ (*new_ep)->grp.unix_name = strdup(unix_group);
+
+ if ((*new_ep)->grp.nt_name == NULL ||
+ (*new_ep)->grp.unix_name == NULL)
+ {
+ DEBUG(0,("make_name_entry: malloc fail for names in name_map_entry.\n"));
+ delete_name_entry((*new_ep));
+ return False;
+ }
+
+ /*
+ * look up the group names, make the Group-SID and unix gid
+ */
+
+ if (!unix_name_to_nt_name_info(&(*new_ep)->grp, type))
+ {
+ delete_name_entry((*new_ep));
+ return False;
+ }
+
+ return True;
+}
+
+/**************************************************************************
+ Load a name map file. Sets last accessed timestamp.
+***************************************************************************/
+static ubi_slList *load_name_map(DOM_MAP_TYPE type)
+{
+ static time_t groupmap_file_last_modified = (time_t)0;
+ static time_t aliasmap_file_last_modified = (time_t)0;
+ static time_t ntusrmap_file_last_modified = (time_t)0;
+ static BOOL initialised_group = False;
+ static BOOL initialised_alias = False;
+ static BOOL initialised_ntusr = False;
+ char *groupname_map_file = lp_groupname_map();
+ char *aliasname_map_file = lp_aliasname_map();
+ char *ntusrname_map_file = lp_ntusrname_map();
+
+ FILE *fp;
+ char *s;
+ pstring buf;
+ name_map_entry *new_ep;
+
+ time_t *file_last_modified = NULL;
+ int *initialised = NULL;
+ char *map_file = NULL;
+ ubi_slList *map_list = NULL;
+
+ switch (type)
+ {
+ case DOM_MAP_DOMAIN:
+ {
+ file_last_modified = &groupmap_file_last_modified;
+ initialised = &initialised_group;
+ map_file = groupname_map_file;
+ map_list = &groupname_map_list;
+
+ break;
+ }
+ case DOM_MAP_LOCAL:
+ {
+ file_last_modified = &aliasmap_file_last_modified;
+ initialised = &initialised_alias;
+ map_file = aliasname_map_file;
+ map_list = &aliasname_map_list;
+
+ break;
+ }
+ case DOM_MAP_USER:
+ {
+ file_last_modified = &ntusrmap_file_last_modified;
+ initialised = &initialised_ntusr;
+ map_file = ntusrname_map_file;
+ map_list = &ntusrname_map_list;
+
+ break;
+ }
+ }
+
+ if (!(*initialised))
+ {
+ DEBUG(10,("initialising map %s\n", map_file));
+ ubi_slInitList(map_list);
+ (*initialised) = True;
+ }
+
+ if (!*map_file)
+ {
+ return map_list;
+ }
+
+ /*
+ * Load the file.
+ */
+
+ fp = open_file_if_modified(map_file, "r", file_last_modified);
+ if (!fp)
+ {
+ return map_list;
+ }
+
+ /*
+ * Throw away any previous list.
+ */
+ delete_map_list(map_list);
+
+ DEBUG(4,("load_name_map: Scanning name map %s\n",map_file));
+
+ while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
+ {
+ pstring unixname;
+ pstring nt_name;
+ fstring nt_domain;
+ fstring ntname;
+ char *p;
+
+ DEBUG(10,("Read line |%s|\n", s));
+
+ memset(nt_name, 0, sizeof(nt_name));
+
+ if (!*s || strchr("#;",*s))
+ continue;
+
+ if (!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
+ continue;
+
+ if (!next_token(&s,nt_name, "\t\n\r=", sizeof(nt_name)))
+ continue;
+
+ trim_string(unixname, " ", " ");
+ trim_string(nt_name, " ", " ");
+
+ if (!*nt_name)
+ continue;
+
+ if (!*unixname)
+ continue;
+
+ p = strchr(nt_name, '\\');
+
+ if (p == NULL)
+ {
+ memset(nt_domain, 0, sizeof(nt_domain));
+ fstrcpy(ntname, nt_name);
+ }
+ else
+ {
+ *p = 0;
+ p++;
+ fstrcpy(nt_domain, nt_name);
+ fstrcpy(ntname , p);
+ }
+
+ if (make_name_entry(&new_ep, nt_domain, ntname, unixname, type))
+ {
+ ubi_slAddTail(map_list, (ubi_slNode *)new_ep);
+ DEBUG(5,("unixname = %s, ntname = %s\\%s type = %d\n",
+ new_ep->grp.unix_name,
+ new_ep->grp.nt_domain,
+ new_ep->grp.nt_name,
+ new_ep->grp.type));
+ }
+ }
+
+ DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
+ ubi_slCount(map_list)));
+
+ fclose(fp);
+
+ return map_list;
+}
+
+static void copy_grp_map_entry(DOM_NAME_MAP *grp, const DOM_NAME_MAP *from)
+{
+ sid_copy(&grp->sid, &from->sid);
+ grp->unix_id = from->unix_id;
+ grp->nt_name = from->nt_name;
+ grp->nt_domain = from->nt_domain;
+ grp->unix_name = from->unix_name;
+ grp->type = from->type;
+}
+
+#if 0
+/***********************************************************
+ Lookup unix name.
+************************************************************/
+static BOOL map_unixname(DOM_MAP_TYPE type,
+ char *unixname, DOM_NAME_MAP *grp_info)
+{
+ name_map_entry *gmep;
+ ubi_slList *map_list;
+
+ /*
+ * Initialise and load if not already loaded.
+ */
+ map_list = load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (strequal(gmep->grp.unix_name, unixname))
+ {
+ copy_grp_map_entry(grp_info, &gmep->grp);
+ DEBUG(7,("map_unixname: Mapping unix name %s to nt group %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+#endif
+
+/***********************************************************
+ Lookup nt name.
+************************************************************/
+static BOOL map_ntname(DOM_MAP_TYPE type, char *ntname, char *ntdomain,
+ DOM_NAME_MAP *grp_info)
+{
+ name_map_entry *gmep;
+ ubi_slList *map_list;
+
+ /*
+ * Initialise and load if not already loaded.
+ */
+ map_list = load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (strequal(gmep->grp.nt_name , ntname) &&
+ strequal(gmep->grp.nt_domain, ntdomain))
+ {
+ copy_grp_map_entry(grp_info, &gmep->grp);
+ DEBUG(7,("map_ntname: Mapping unix name %s to nt name %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+
+/***********************************************************
+ Lookup by SID
+************************************************************/
+static BOOL map_sid(DOM_MAP_TYPE type,
+ DOM_SID *psid, DOM_NAME_MAP *grp_info)
+{
+ name_map_entry *gmep;
+ ubi_slList *map_list;
+
+ /*
+ * Initialise and load if not already loaded.
+ */
+ map_list = load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (sid_equal(&gmep->grp.sid, psid))
+ {
+ copy_grp_map_entry(grp_info, &gmep->grp);
+ DEBUG(7,("map_sid: Mapping unix name %s to nt name %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/***********************************************************
+ Lookup by gid_t.
+************************************************************/
+static BOOL map_unixid(DOM_MAP_TYPE type, uint32 unix_id, DOM_NAME_MAP *grp_info)
+{
+ name_map_entry *gmep;
+ ubi_slList *map_list;
+
+ /*
+ * Initialise and load if not already loaded.
+ */
+ map_list = load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ fstring sid_str;
+ sid_to_string(sid_str, &gmep->grp.sid);
+ DEBUG(10,("map_unixid: enum entry unix group %s %d nt %s %s\n",
+ gmep->grp.unix_name, gmep->grp.unix_id, gmep->grp.nt_name, sid_str));
+ if (gmep->grp.unix_id == unix_id)
+ {
+ copy_grp_map_entry(grp_info, &gmep->grp);
+ DEBUG(7,("map_unixid: Mapping unix name %s to nt name %s type %d\n",
+ gmep->grp.unix_name, gmep->grp.nt_name, gmep->grp.type));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/***********************************************************
+ *
+ * Call four functions to resolve unix group ids and either
+ * local group SIDs or domain group SIDs listed in the local group
+ * or domain group map files.
+ *
+ * Note that it is *NOT* the responsibility of these functions to
+ * resolve entries that are not in the map files.
+ *
+ * Any SID can be in the map files (i.e from any Domain).
+ *
+ ***********************************************************/
+
+#if 0
+
+/***********************************************************
+ Lookup a UNIX Group entry by name.
+************************************************************/
+BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info)
+{
+ return map_unixname(DOM_MAP_DOMAIN, group_name, grp_info);
+}
+
+/***********************************************************
+ Lookup a UNIX Alias entry by name.
+************************************************************/
+BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info)
+{
+ return map_unixname(DOM_MAP_LOCAL, alias_name, grp_info);
+}
+
+/***********************************************************
+ Lookup an Alias name entry
+************************************************************/
+BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info)
+{
+ return map_ntname(DOM_MAP_LOCAL, ntalias_name, nt_domain, grp_info);
+}
+
+/***********************************************************
+ Lookup a Group entry
+************************************************************/
+BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info)
+{
+ return map_ntname(DOM_MAP_DOMAIN, ntgroup_name, nt_domain, grp_info);
+}
+
+#endif
+
+/***********************************************************
+ Lookup a Username entry by name.
+************************************************************/
+static BOOL map_nt_username(char *nt_name, char *nt_domain, DOM_NAME_MAP *grp_info)
+{
+ return map_ntname(DOM_MAP_USER, nt_name, nt_domain, grp_info);
+}
+
+/***********************************************************
+ Lookup a Username entry by SID.
+************************************************************/
+static BOOL map_username_sid(DOM_SID *sid, DOM_NAME_MAP *grp_info)
+{
+ return map_sid(DOM_MAP_USER, sid, grp_info);
+}
+
+/***********************************************************
+ Lookup a Username SID entry by uid.
+************************************************************/
+static BOOL map_username_uid(uid_t gid, DOM_NAME_MAP *grp_info)
+{
+ return map_unixid(DOM_MAP_USER, (uint32)gid, grp_info);
+}
+
+/***********************************************************
+ Lookup an Alias SID entry by name.
+************************************************************/
+BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
+{
+ return map_sid(DOM_MAP_LOCAL, psid, grp_info);
+}
+
+/***********************************************************
+ Lookup a Group entry by sid.
+************************************************************/
+BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
+{
+ return map_sid(DOM_MAP_DOMAIN, psid, grp_info);
+}
+
+/***********************************************************
+ Lookup an Alias SID entry by gid_t.
+************************************************************/
+static BOOL map_alias_gid(gid_t gid, DOM_NAME_MAP *grp_info)
+{
+ return map_unixid(DOM_MAP_LOCAL, (uint32)gid, grp_info);
+}
+
+/***********************************************************
+ Lookup a Group SID entry by gid_t.
+************************************************************/
+static BOOL map_group_gid( gid_t gid, DOM_NAME_MAP *grp_info)
+{
+ return map_unixid(DOM_MAP_DOMAIN, (uint32)gid, grp_info);
+}
+
+
+/************************************************************************
+ Routine to look up User details by UNIX name
+*************************************************************************/
+BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp)
+{
+ uid_t uid;
+ DEBUG(10,("lookupsmbpwnam: unix user name %s\n", unix_usr_name));
+ if (nametouid(unix_usr_name, &uid))
+ {
+ return lookupsmbpwuid(uid, grp);
+ }
+ else
+ {
+ return False;
+ }
+}
+
+/************************************************************************
+ Routine to look up a remote nt name
+*************************************************************************/
+static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
+{
+ struct cli_state cli;
+ POLICY_HND lsa_pol;
+ fstring srv_name;
+ extern struct ntuser_creds *usr_creds;
+ struct ntuser_creds usr;
+
+ BOOL res3 = True;
+ BOOL res4 = True;
+ uint32 num_sids;
+ DOM_SID *sids;
+ uint8 *types;
+ char *names[1];
+
+ usr_creds = &usr;
+
+ ZERO_STRUCT(usr);
+ pwd_set_nullpwd(&usr.pwd);
+
+ DEBUG(5,("lookup_remote_ntname: %s\n", ntname));
+
+ if (!cli_connect_serverlist(&cli, lp_passwordserver()))
+ {
+ return False;
+ }
+
+ names[0] = ntname;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli.desthost);
+ strupper(srv_name);
+
+ /* lookup domain controller; receive a policy handle */
+ res3 = res3 ? lsa_open_policy( srv_name,
+ &lsa_pol, True) : False;
+
+ /* send lsa lookup sids call */
+ res4 = res3 ? lsa_lookup_names( &lsa_pol,
+ 1, names,
+ &sids, &types, &num_sids) : False;
+
+ res3 = res3 ? lsa_close(&lsa_pol) : False;
+
+ if (res4 && res3 && sids != NULL && types != NULL)
+ {
+ sid_copy(sid, &sids[0]);
+ *type = types[0];
+ }
+ else
+ {
+ res3 = False;
+ }
+ SAFE_FREE(types);
+ SAFE_FREE(sids);
+
+ return res3 && res4;
+}
+
+/************************************************************************
+ Routine to look up a remote nt name
+*************************************************************************/
+static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
+ DOM_NAME_MAP *gmep)
+{
+ /*
+ * check with the PDC to see if it owns the name. if so,
+ * the SID is resolved with the PDC database.
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+ if (lookup_remote_ntname(fullntname, &gmep->sid, &gmep->type))
+ {
+ if (sid_front_equal(&gmep->sid, &global_member_sid) &&
+ strequal(gmep->nt_domain, global_myworkgroup) &&
+ gmep->type == expected_type)
+ {
+ return True;
+ }
+ return False;
+ }
+ }
+
+ /*
+ * ... otherwise, it's one of ours. map the sid ourselves,
+ * which can only happen in our own SAM database.
+ */
+
+ if (!strequal(gmep->nt_domain, global_sam_name))
+ {
+ return False;
+ }
+ if (!pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid))
+ {
+ return False;
+ }
+
+ return True;
+}
+
+/*
+ * used by lookup functions below
+ */
+
+static fstring nt_name;
+static fstring unix_name;
+static fstring nt_domain;
+
+/*************************************************************************
+ looks up a uid, returns User Information.
+*************************************************************************/
+BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
+{
+ DEBUG(10,("lookupsmbpwuid: unix uid %d\n", uid));
+ if (map_username_uid(uid, gmep))
+ {
+ return True;
+ }
+#if 0
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+#endif
+ {
+ gmep->nt_name = nt_name;
+ gmep->unix_name = unix_name;
+ gmep->nt_domain = nt_domain;
+
+ gmep->unix_id = (uint32)uid;
+
+ /*
+ * ok, assume it's one of ours. then double-check it
+ * if we are a member of a domain
+ */
+
+ gmep->type = SID_NAME_USER;
+ fstrcpy(gmep->nt_name, uidtoname(uid));
+ fstrcpy(gmep->unix_name, gmep->nt_name);
+
+ /*
+ * here we should do a LsaLookupNames() call
+ * to check the status of the name with the PDC.
+ * if the PDC know nothing of the name, it's ours.
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+#if 0
+ lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
+#endif
+ }
+
+ /*
+ * ok, it's one of ours.
+ */
+
+ gmep->nt_domain = global_sam_name;
+ pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
+
+ return True;
+ }
+
+ /* oops. */
+
+ return False;
+}
+
+/*************************************************************************
+ looks up by NT name, returns User Information.
+*************************************************************************/
+BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep)
+{
+ DEBUG(10,("lookupsmbpwntnam: nt user name %s\n", fullntname));
+
+ if (!split_domain_name(fullntname, nt_domain, nt_name))
+ {
+ return False;
+ }
+
+ if (map_nt_username(nt_name, nt_domain, gmep))
+ {
+ return True;
+ }
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+ {
+ uid_t uid;
+ gmep->nt_name = nt_name;
+ gmep->unix_name = unix_name;
+ gmep->nt_domain = nt_domain;
+
+ /*
+ * ok, it's one of ours. we therefore "create" an nt user named
+ * after the unix user. this is the point where "appliance mode"
+ * should get its teeth in, as unix users won't really exist,
+ * they will only be numbers...
+ */
+
+ gmep->type = SID_NAME_USER;
+ fstrcpy(gmep->unix_name, gmep->nt_name);
+ if (!nametouid(gmep->unix_name, &uid))
+ {
+ return False;
+ }
+ gmep->unix_id = (uint32)uid;
+
+ return get_sid_and_type(fullntname, gmep->type, gmep);
+ }
+
+ /* oops. */
+
+ return False;
+}
+
+/*************************************************************************
+ looks up by RID, returns User Information.
+*************************************************************************/
+BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
+{
+ fstring sid_str;
+ sid_to_string(sid_str, sid);
+ DEBUG(10,("lookupsmbpwsid: nt sid %s\n", sid_str));
+
+ if (map_username_sid(sid, gmep))
+ {
+ return True;
+ }
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+ {
+ gmep->nt_name = nt_name;
+ gmep->unix_name = unix_name;
+ gmep->nt_domain = nt_domain;
+
+ /*
+ * here we should do a LsaLookupNames() call
+ * to check the status of the name with the PDC.
+ * if the PDC know nothing of the name, it's ours.
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+#if 0
+ if (lookup_remote_sid(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
+#endif
+ }
+
+ /*
+ * ok, it's one of ours. we therefore "create" an nt user named
+ * after the unix user. this is the point where "appliance mode"
+ * should get its teeth in, as unix users won't really exist,
+ * they will only be numbers...
+ */
+
+ gmep->type = SID_NAME_USER;
+ sid_copy(&gmep->sid, sid);
+ if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
+ {
+ return False;
+ }
+ fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
+ fstrcpy(gmep->unix_name, gmep->nt_name);
+ gmep->nt_domain = global_sam_name;
+
+ return True;
+ }
+
+ /* oops. */
+
+ return False;
+}
+
+/************************************************************************
+ Routine to look up group / alias / well-known group RID by UNIX name
+*************************************************************************/
+BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp)
+{
+ gid_t gid;
+ DEBUG(10,("lookupsmbgrpnam: unix user group %s\n", unix_grp_name));
+ if (nametogid(unix_grp_name, &gid))
+ {
+ return lookupsmbgrpgid(gid, grp);
+ }
+ else
+ {
+ return False;
+ }
+}
+
+/*************************************************************************
+ looks up a SID, returns name map entry
+*************************************************************************/
+BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
+{
+ fstring sid_str;
+ sid_to_string(sid_str, sid);
+ DEBUG(10,("lookupsmbgrpsid: nt sid %s\n", sid_str));
+
+ if (map_alias_sid(sid, gmep))
+ {
+ return True;
+ }
+ if (map_group_sid(sid, gmep))
+ {
+ return True;
+ }
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+ {
+ gmep->nt_name = nt_name;
+ gmep->unix_name = unix_name;
+ gmep->nt_domain = nt_domain;
+
+ /*
+ * here we should do a LsaLookupNames() call
+ * to check the status of the name with the PDC.
+ * if the PDC know nothing of the name, it's ours.
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+#if 0
+ lsa_lookup_sids(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
+#endif
+ }
+
+ /*
+ * ok, it's one of ours. we therefore "create" an nt group or
+ * alias name named after the unix group. this is the point
+ * where "appliance mode" should get its teeth in, as unix
+ * groups won't really exist, they will only be numbers...
+ */
+
+ /* name is not explicitly mapped
+ * with map files or the PDC
+ * so we are responsible for it...
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+ /* ... as a LOCAL group. */
+ gmep->type = SID_NAME_ALIAS;
+ }
+ else
+ {
+ /* ... as a DOMAIN group. */
+ gmep->type = SID_NAME_DOM_GRP;
+ }
+
+ sid_copy(&gmep->sid, sid);
+ if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
+ {
+ return False;
+ }
+ fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
+ fstrcpy(gmep->unix_name, gmep->nt_name);
+ gmep->nt_domain = global_sam_name;
+
+ return True;
+ }
+
+ /* oops */
+ return False;
+}
+
+/*************************************************************************
+ looks up a gid, returns RID and type local, domain or well-known domain group
+*************************************************************************/
+BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
+{
+ DEBUG(10,("lookupsmbgrpgid: unix gid %d\n", (int)gid));
+ if (map_alias_gid(gid, gmep))
+ {
+ return True;
+ }
+ if (map_group_gid(gid, gmep))
+ {
+ return True;
+ }
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+ {
+ gmep->nt_name = nt_name;
+ gmep->unix_name = unix_name;
+ gmep->nt_domain = nt_domain;
+
+ gmep->unix_id = (uint32)gid;
+
+ /*
+ * here we should do a LsaLookupNames() call
+ * to check the status of the name with the PDC.
+ * if the PDC know nothing of the name, it's ours.
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+#if 0
+ if (lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
+ {
+ return True;
+ }
+#endif
+ }
+
+ /*
+ * ok, it's one of ours. we therefore "create" an nt group or
+ * alias name named after the unix group. this is the point
+ * where "appliance mode" should get its teeth in, as unix
+ * groups won't really exist, they will only be numbers...
+ */
+
+ /* name is not explicitly mapped
+ * with map files or the PDC
+ * so we are responsible for it...
+ */
+
+ if (lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+ /* ... as a LOCAL group. */
+ gmep->type = SID_NAME_ALIAS;
+ }
+ else
+ {
+ /* ... as a DOMAIN group. */
+ gmep->type = SID_NAME_DOM_GRP;
+ }
+ fstrcpy(gmep->nt_name, gidtoname(gid));
+ fstrcpy(gmep->unix_name, gmep->nt_name);
+
+ return get_sid_and_type(gmep->nt_name, gmep->type, gmep);
+ }
+
+ /* oops */
+ return False;
+}
+
diff --git a/source/lib/dprintf.c b/source/lib/dprintf.c
deleted file mode 100644
index c62a1f41d10..00000000000
--- a/source/lib/dprintf.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- display print functions
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/*
- this module provides functions for printing internal strings in the "display charset"
- This charset may be quite different from the chosen unix charset
-
- Eventually these functions will need to take care of column count constraints
-
- The d_ prefix on print functions in Samba refers to the display character set
- conversion
-*/
-
-#include "includes.h"
-
- int d_vfprintf(FILE *f, const char *format, va_list ap)
-{
- char *p, *p2;
- int ret, maxlen, clen;
- const char *msgstr;
- va_list ap2;
-
- /* do any message translations */
- msgstr = lang_msg(format);
- if (!msgstr) return -1;
-
- VA_COPY(ap2, ap);
-
- ret = vasprintf(&p, msgstr, ap2);
-
- lang_msg_free(msgstr);
-
- if (ret <= 0) return ret;
-
- /* now we have the string in unix format, convert it to the display
- charset, but beware of it growing */
- maxlen = ret*2;
-again:
- p2 = malloc(maxlen);
- if (!p2) {
- SAFE_FREE(p);
- return -1;
- }
- clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, True);
-
- if (clen >= maxlen) {
- /* it didn't fit - try a larger buffer */
- maxlen *= 2;
- SAFE_FREE(p2);
- goto again;
- }
-
- /* good, its converted OK */
- SAFE_FREE(p);
- ret = fwrite(p2, 1, clen, f);
- SAFE_FREE(p2);
-
- return ret;
-}
-
-
- int d_fprintf(FILE *f, const char *format, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, format);
- ret = d_vfprintf(f, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-static FILE *outfile;
-
- int d_printf(const char *format, ...)
-{
- int ret;
- va_list ap;
-
- if (!outfile) outfile = stdout;
-
- va_start(ap, format);
- ret = d_vfprintf(outfile, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-/* interactive programs need a way of tell d_*() to write to stderr instead
- of stdout */
-void display_set_stderr(void)
-{
- outfile = stderr;
-}
diff --git a/source/lib/dummyroot.c b/source/lib/dummyroot.c
deleted file mode 100644
index c8465cb791a..00000000000
--- a/source/lib/dummyroot.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Stupid dummy functions required due to the horrible dependency mess
- in Samba. */
-
-void become_root(void)
-{
- return;
-}
-
-void unbecome_root(void)
-{
- return;
-}
diff --git a/source/lib/dummysmbd.c b/source/lib/dummysmbd.c
deleted file mode 100644
index 17bc3217743..00000000000
--- a/source/lib/dummysmbd.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Gerald (Jerry) Carter 2004.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Stupid dummy functions required due to the horrible dependency mess
- in Samba. */
-
-void decrement_smbd_process_count( void )
-{
- return;
-}
-
diff --git a/source/lib/error.c b/source/lib/error.c
new file mode 100755
index 00000000000..f97a0e51ae5
--- /dev/null
+++ b/source/lib/error.c
@@ -0,0 +1,76 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9
+ * Unix/DOS/NT error code conversions
+ * Copyright (C) Tim Potter 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/* Mapping between Unix, DOS and NT error numbers */
+
+struct unix_error_map unix_dos_nt_errmap[] = {
+ { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+ { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+ { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
+ { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR },
+ { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+ { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+ { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION},
+ { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
+#ifdef EDQUOT
+ { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
+#endif
+#ifdef ENOTEMPTY
+ { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
+#endif
+#ifdef EXDEV
+ { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
+#endif
+#ifdef EROFS
+ { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED },
+#endif
+#ifdef ENAMETOOLONG
+ { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID },
+#endif
+ { 0, 0, 0, NT_STATUS_OK }
+};
+
+/*********************************************************************
+ Map an NT error code from a Unix error code.
+*********************************************************************/
+
+NTSTATUS map_nt_error_from_unix(int unix_error)
+{
+ int i = 0;
+
+ if (unix_error == 0)
+ return NT_STATUS_OK;
+
+ /* Look through list */
+ while(unix_dos_nt_errmap[i].unix_error != 0) {
+ if (unix_dos_nt_errmap[i].unix_error == unix_error)
+ return unix_dos_nt_errmap[i].nt_error;
+ i++;
+ }
+
+ /* Default return */
+ return NT_STATUS_ACCESS_DENIED;
+}
diff --git a/source/lib/fault.c b/source/lib/fault.c
index d8364ff2257..8d08fccd24c 100644
--- a/source/lib/fault.c
+++ b/source/lib/fault.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Critical Fault handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -22,6 +23,7 @@
static void (*cont_fn)(void *);
+
/*******************************************************************
report a fault
********************************************************************/
@@ -34,8 +36,8 @@ static void fault_report(int sig)
counter++;
DEBUG(0,("===============================================================\n"));
- DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),SAMBA_VERSION_STRING));
- DEBUG(0,("\nPlease read the appendix Bugs of the Samba HOWTO collection\n"));
+ DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),VERSION));
+ DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
DEBUG(0,("===============================================================\n"));
smb_panic("internal error");
@@ -48,9 +50,6 @@ static void fault_report(int sig)
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL);
#endif
-#ifdef SIGABRT
- CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);
-#endif
return; /* this should cause a core dump */
}
exit(1);
@@ -77,7 +76,4 @@ void fault_setup(void (*fn)(void *))
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
#endif
-#ifdef SIGABRT
- CatchSignal(SIGABRT,SIGNAL_CAST sig_fault);
-#endif
}
diff --git a/source/lib/fsusage.c b/source/lib/fsusage.c
index bb7cff06453..1bff1f953e0 100644
--- a/source/lib/fsusage.c
+++ b/source/lib/fsusage.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0.
functions to calculate the free disk space
Copyright (C) Andrew Tridgell 1998-2000
diff --git a/source/lib/gencache.c b/source/lib/gencache.c
deleted file mode 100644
index 39e727c24fa..00000000000
--- a/source/lib/gencache.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Generic, persistent and shared between processes cache mechanism for use
- by various parts of the Samba code
-
- Copyright (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_TDB
-
-#define TIMEOUT_LEN 12
-#define CACHE_DATA_FMT "%12u/%s"
-
-static TDB_CONTEXT *cache;
-
-/**
- * @file gencache.c
- * @brief Generic, persistent and shared between processes cache mechanism
- * for use by various parts of the Samba code
- *
- **/
-
-
-/**
- * Cache initialisation function. Opens cache tdb file or creates
- * it if does not exist.
- *
- * @return true on successful initialisation of the cache or
- * false on failure
- **/
-
-BOOL gencache_init(void)
-{
- char* cache_fname = NULL;
-
- /* skip file open if it's already opened */
- if (cache) return True;
-
- asprintf(&cache_fname, "%s/%s", lp_lockdir(), "gencache.tdb");
- if (cache_fname)
- DEBUG(5, ("Opening cache file at %s\n", cache_fname));
- else {
- DEBUG(0, ("Filename allocation failed.\n"));
- return False;
- }
-
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0644);
-
- SAFE_FREE(cache_fname);
- if (!cache) {
- DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
- return False;
- }
- return True;
-}
-
-
-/**
- * Cache shutdown function. Closes opened cache tdb file.
- *
- * @return true on successful closing the cache or
- * false on failure during cache shutdown
- **/
-
-BOOL gencache_shutdown(void)
-{
- /* tdb_close routine returns -1 on error */
- if (!cache) return False;
- DEBUG(5, ("Closing cache file\n"));
- return tdb_close(cache) != -1;
-}
-
-
-/**
- * Set an entry in the cache file. If there's no such
- * one, then add it.
- *
- * @param keystr string that represents a key of this entry
- * @param value text representation value being cached
- * @param timeout time when the value is expired
- *
- * @retval true when entry is successfuly stored
- * @retval false on failure
- **/
-
-BOOL gencache_set(const char *keystr, const char *value, time_t timeout)
-{
- int ret;
- TDB_DATA keybuf, databuf;
- char* valstr = NULL;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && value);
-
- if (!gencache_init()) return False;
-
- asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value);
- if (!valstr)
- return False;
-
- keybuf.dptr = strdup(keystr);
- keybuf.dsize = strlen(keystr)+1;
- databuf.dptr = strdup(valstr);
- databuf.dsize = strlen(valstr)+1;
- DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
- " %s (%d seconds %s)\n", keybuf.dptr, value,ctime(&timeout),
- (int)(timeout - time(NULL)),
- timeout > time(NULL) ? "ahead" : "in the past"));
-
- ret = tdb_store(cache, keybuf, databuf, 0);
- SAFE_FREE(valstr);
- SAFE_FREE(keybuf.dptr);
- SAFE_FREE(databuf.dptr);
-
- return ret == 0;
-}
-
-
-/**
- * Set existing entry to the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param valstr text representation value being cached
- * @param timeout time when the value is expired
- *
- * @retval true when entry is successfuly set
- * @retval false on failure
- **/
-
-BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout)
-{
- int ret = -1;
- TDB_DATA keybuf, databuf;
- char *old_valstr, *datastr;
- time_t old_timeout;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && valstr);
-
- if (!gencache_init()) return False;
-
- /*
- * Check whether entry exists in the cache
- * Don't verify gencache_get exit code, since the entry may be expired
- */
- gencache_get(keystr, &old_valstr, &old_timeout);
-
- if (!(old_valstr && old_timeout)) return False;
-
- DEBUG(10, ("Setting cache entry with key = %s; old value = %s and old timeout \
- = %s\n", keystr, old_valstr, ctime(&old_timeout)));
-
- asprintf(&datastr, CACHE_DATA_FMT, (int)timeout, valstr);
- keybuf.dptr = strdup(keystr);
- keybuf.dsize = strlen(keystr)+1;
- databuf.dptr = strdup(datastr);
- databuf.dsize = strlen(datastr)+1;
- DEBUGADD(10, ("New value = %s, new timeout = %s (%d seconds %s)", valstr,
- ctime(&timeout), (int)(timeout - time(NULL)),
- timeout > time(NULL) ? "ahead" : "in the past"));
-
-
- ret = tdb_store(cache, keybuf, databuf, TDB_REPLACE);
-
- SAFE_FREE(datastr);
- SAFE_FREE(old_valstr);
- SAFE_FREE(keybuf.dptr);
- SAFE_FREE(databuf.dptr);
-
- return ret == 0;
-}
-
-
-/**
- * Delete one entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- *
- * @retval true upon successful deletion
- * @retval false in case of failure
- **/
-
-BOOL gencache_del(const char *keystr)
-{
- int ret;
- TDB_DATA keybuf;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
-
- if (!gencache_init()) return False;
-
- keybuf.dptr = strdup(keystr);
- keybuf.dsize = strlen(keystr)+1;
- DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
- ret = tdb_delete(cache, keybuf);
-
- SAFE_FREE(keybuf.dptr);
- return ret == 0;
-}
-
-
-/**
- * Get existing entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param valstr buffer that is allocated and filled with the entry value
- * buffer's disposing must be done outside
- * @param timeout pointer to a time_t that is filled with entry's
- * timeout
- *
- * @retval true when entry is successfuly fetched
- * @retval False for failure
- **/
-
-BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
-{
- TDB_DATA keybuf, databuf;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
-
- if (!gencache_init())
- return False;
-
- keybuf.dptr = strdup(keystr);
- keybuf.dsize = strlen(keystr)+1;
- databuf = tdb_fetch(cache, keybuf);
- SAFE_FREE(keybuf.dptr);
-
- if (databuf.dptr && databuf.dsize > TIMEOUT_LEN) {
- char* entry_buf = strndup(databuf.dptr, databuf.dsize);
- char *v;
- time_t t;
-
- v = (char*)malloc(sizeof(char) *
- (databuf.dsize - TIMEOUT_LEN));
-
- SAFE_FREE(databuf.dptr);
- sscanf(entry_buf, CACHE_DATA_FMT, (int*)&t, v);
- SAFE_FREE(entry_buf);
-
- DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
- "timeout = %s\n", t > time(NULL) ? "valid" :
- "expired", keystr, v, ctime(&t)));
-
- if (valstr)
- *valstr = v;
- else
- SAFE_FREE(v);
-
- if (timeout)
- *timeout = t;
-
- return t > time(NULL);
-
- } else {
- SAFE_FREE(databuf.dptr);
-
- if (valstr)
- *valstr = NULL;
-
- if (timeout)
- timeout = NULL;
-
- DEBUG(10, ("Cache entry with key = %s couldn't be found\n",
- keystr));
-
- return False;
- }
-}
-
-
-/**
- * Iterate through all entries which key matches to specified pattern
- *
- * @param fn pointer to the function that will be supplied with each single
- * matching cache entry (key, value and timeout) as an arguments
- * @param data void pointer to an arbitrary data that is passed directly to the fn
- * function on each call
- * @param keystr_pattern pattern the existing entries' keys are matched to
- *
- **/
-
-void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
- void* data, const char* keystr_pattern)
-{
- TDB_LIST_NODE *node, *first_node;
- TDB_DATA databuf;
- char *keystr = NULL, *valstr = NULL, *entry = NULL;
- time_t timeout = 0;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(fn && keystr_pattern);
-
- if (!gencache_init()) return;
-
- DEBUG(5, ("Searching cache keys with pattern %s\n", keystr_pattern));
- node = tdb_search_keys(cache, keystr_pattern);
- first_node = node;
-
- while (node) {
- /* ensure null termination of the key string */
- keystr = strndup(node->node_key.dptr, node->node_key.dsize);
-
- /*
- * We don't use gencache_get function, because we need to iterate through
- * all of the entries. Validity verification is up to fn routine.
- */
- databuf = tdb_fetch(cache, node->node_key);
- if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) {
- SAFE_FREE(databuf.dptr);
- SAFE_FREE(keystr);
- node = node->next;
- continue;
- }
- entry = strndup(databuf.dptr, databuf.dsize);
- SAFE_FREE(databuf.dptr);
- valstr = (char*)malloc(sizeof(char) * (databuf.dsize - TIMEOUT_LEN));
- sscanf(entry, CACHE_DATA_FMT, (int*)(&timeout), valstr);
-
- DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
- keystr, valstr, ctime(&timeout)));
- fn(keystr, valstr, timeout, data);
-
- SAFE_FREE(valstr);
- SAFE_FREE(entry);
- SAFE_FREE(keystr);
- node = node->next;
- }
-
- tdb_search_list_free(first_node);
-}
-
-/********************************************************************
- lock a key
-********************************************************************/
-
-int gencache_lock_entry( const char *key )
-{
- if (!gencache_init())
- return -1;
-
- return tdb_lock_bystring(cache, key, 0);
-}
-
-/********************************************************************
- unlock a key
-********************************************************************/
-
-void gencache_unlock_entry( const char *key )
-{
- if (!gencache_init())
- return;
-
- tdb_unlock_bystring(cache, key);
- return;
-}
-
-
diff --git a/source/lib/genparser.c b/source/lib/genparser.c
deleted file mode 100644
index 7476b5d0aff..00000000000
--- a/source/lib/genparser.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- Copyright (C) Andrew Tridgell <genstruct@tridgell.net> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- automatic marshalling/unmarshalling system for C structures
-*/
-
-#include "includes.h"
-
-/* see if a range of memory is all zero. Used to prevent dumping of zero elements */
-static int all_zero(const char *ptr, unsigned size)
-{
- int i;
- if (!ptr) return 1;
- for (i=0;i<size;i++) {
- if (ptr[i]) return 0;
- }
- return 1;
-}
-
-/* encode a buffer of bytes into a escaped string */
-static char *encode_bytes(TALLOC_CTX *mem_ctx, const char *ptr, unsigned len)
-{
- const char *hexdig = "0123456789abcdef";
- char *ret, *p;
- unsigned i;
- ret = talloc(mem_ctx, len*3 + 1); /* worst case size */
- if (!ret) return NULL;
- for (p=ret,i=0;i<len;i++) {
- if (isalnum(ptr[i]) || isspace(ptr[i]) ||
- (ispunct(ptr[i]) && !strchr("\\{}", ptr[i]))) {
- *p++ = ptr[i];
- } else {
- unsigned char c = *(unsigned char *)(ptr+i);
- if (c == 0 && all_zero(ptr+i, len-i)) break;
- p[0] = '\\';
- p[1] = hexdig[c>>4];
- p[2] = hexdig[c&0xF];
- p += 3;
- }
- }
-
- *p = 0;
-
- return ret;
-}
-
-/* decode an escaped string from encode_bytes() into a buffer */
-static char *decode_bytes(TALLOC_CTX *mem_ctx, const char *s, unsigned *len)
-{
- char *ret, *p;
- unsigned i;
- int slen = strlen(s) + 1;
-
- ret = talloc(mem_ctx, slen); /* worst case length */
- if (!ret)
- return NULL;
- memset(ret, 0, slen);
-
- if (*s == '{') s++;
-
- for (p=ret,i=0;s[i];i++) {
- if (s[i] == '}') {
- break;
- } else if (s[i] == '\\') {
- unsigned v;
- if (sscanf(&s[i+1], "%02x", &v) != 1 || v > 255) {
- return NULL;
- }
- *(unsigned char *)p = v;
- p++;
- i += 2;
- } else {
- *p++ = s[i];
- }
- }
- *p = 0;
-
- (*len) = (unsigned)(p - ret);
-
- return ret;
-}
-
-/* the add*() functions deal with adding things to a struct
- parse_string */
-
-/* allocate more space if needed */
-static int addgen_alloc(TALLOC_CTX *mem_ctx, struct parse_string *p, int n)
-{
- if (p->length + n <= p->allocated) return 0;
- p->allocated = p->length + n + 200;
- p->s = talloc_realloc(mem_ctx, p->s, p->allocated);
- if (!p->s) {
- errno = ENOMEM;
- return -1;
- }
- return 0;
-}
-
-/* add a character to the buffer */
-static int addchar(TALLOC_CTX *mem_ctx, struct parse_string *p, char c)
-{
- if (addgen_alloc(mem_ctx, p, 2) != 0) {
- return -1;
- }
- p->s[p->length++] = c;
- p->s[p->length] = 0;
- return 0;
-}
-
-/* add a string to the buffer */
-int addstr(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *s)
-{
- int len = strlen(s);
- if (addgen_alloc(mem_ctx, p, len+1) != 0) {
- return -1;
- }
- memcpy(p->s + p->length, s, len+1);
- p->length += len;
- return 0;
-}
-
-/* add a string to the buffer with a tab prefix */
-static int addtabbed(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *s, unsigned indent)
-{
- int len = strlen(s);
- if (addgen_alloc(mem_ctx, p, indent+len+1) != 0) {
- return -1;
- }
- while (indent--) {
- p->s[p->length++] = '\t';
- }
- memcpy(p->s + p->length, s, len+1);
- p->length += len;
- return 0;
-}
-
-/* note! this can only be used for results up to 60 chars wide! */
-int addshort(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *fmt, ...)
-{
- char buf[60];
- int n;
- va_list ap;
- va_start(ap, fmt);
- n = vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- if (addgen_alloc(mem_ctx, p, n + 1) != 0) {
- return -1;
- }
- if (n != 0) {
- memcpy(p->s + p->length, buf, n);
- }
- p->length += n;
- p->s[p->length] = 0;
- return 0;
-}
-
-/*
- this is here to make it easier for people to write dump functions
- for their own types
- */
-int gen_addgen(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *fmt, ...)
-{
- char *buf = NULL;
- int n;
- va_list ap;
- va_start(ap, fmt);
- n = vasprintf(&buf, fmt, ap);
- va_end(ap);
- if (addgen_alloc(mem_ctx, p, n + 1) != 0) {
- if (buf) free(buf);
- return -1;
- }
- if (n != 0) {
- memcpy(p->s + p->length, buf, n);
- }
- p->length += n;
- p->s[p->length] = 0;
- if (buf) free(buf);
- return 0;
-}
-
-/* dump a enumerated type */
-int gen_dump_enum(TALLOC_CTX *mem_ctx,
- const struct enum_struct *einfo,
- struct parse_string *p,
- const char *ptr,
- unsigned indent)
-{
- unsigned v = *(unsigned *)ptr;
- int i;
- for (i=0;einfo[i].name;i++) {
- if (v == einfo[i].value) {
- addstr(mem_ctx, p, einfo[i].name);
- return 0;
- }
- }
- /* hmm, maybe we should just fail? */
- return gen_dump_unsigned(mem_ctx, p, ptr, indent);
-}
-
-/* dump a single non-array element, hanlding struct and enum */
-static int gen_dump_one(TALLOC_CTX *mem_ctx,
- struct parse_string *p,
- const struct parse_struct *pinfo,
- const char *ptr,
- unsigned indent)
-{
- if (pinfo->dump_fn == gen_dump_char && pinfo->ptr_count == 1) {
- char *s = encode_bytes(mem_ctx, ptr, strlen(ptr));
- if (addchar(mem_ctx, p,'{') ||
- addstr(mem_ctx, p, s) ||
- addstr(mem_ctx, p, "}")) {
- return -1;
- }
- return 0;
- }
-
- return pinfo->dump_fn(mem_ctx, p, ptr, indent);
-}
-
-/* handle dumping of an array of arbitrary type */
-static int gen_dump_array(TALLOC_CTX *mem_ctx,
- struct parse_string *p,
- const struct parse_struct *pinfo,
- const char *ptr,
- int array_len,
- int indent)
-{
- int i, count=0;
-
- /* special handling of fixed length strings */
- if (array_len != 0 &&
- pinfo->ptr_count == 0 &&
- pinfo->dump_fn == gen_dump_char) {
- char *s = encode_bytes(mem_ctx, ptr, array_len);
- if (!s) return -1;
- if (addtabbed(mem_ctx, p, pinfo->name, indent) ||
- addstr(mem_ctx, p, " = {") ||
- addstr(mem_ctx, p, s) ||
- addstr(mem_ctx, p, "}\n")) {
- return -1;
- }
- return 0;
- }
-
- for (i=0;i<array_len;i++) {
- const char *p2 = ptr;
- unsigned size = pinfo->size;
-
- /* generic pointer dereference */
- if (pinfo->ptr_count) {
- p2 = *(const char **)ptr;
- size = sizeof(void *);
- }
-
- if ((count || pinfo->ptr_count) &&
- !(pinfo->flags & FLAG_ALWAYS) &&
- all_zero(ptr, size)) {
- ptr += size;
- continue;
- }
- if (count == 0) {
- if (addtabbed(mem_ctx, p, pinfo->name, indent) ||
- addshort(mem_ctx, p, " = %u:", i)) {
- return -1;
- }
- } else {
- if (addshort(mem_ctx, p, ", %u:", i) != 0) {
- return -1;
- }
- }
- if (gen_dump_one(mem_ctx, p, pinfo, p2, indent) != 0) {
- return -1;
- }
- ptr += size;
- count++;
- }
- if (count) {
- return addstr(mem_ctx, p, "\n");
- }
- return 0;
-}
-
-/* find a variable by name in a loaded structure and return its value
- as an integer. Used to support dynamic arrays */
-static int find_var(const struct parse_struct *pinfo,
- const char *data,
- const char *var)
-{
- int i;
- const char *ptr;
-
- /* this allows for constant lengths */
- if (isdigit(*var)) {
- return atoi(var);
- }
-
- for (i=0;pinfo[i].name;i++) {
- if (strcmp(pinfo[i].name, var) == 0) break;
- }
- if (!pinfo[i].name) return -1;
-
- ptr = data + pinfo[i].offset;
-
- switch (pinfo[i].size) {
- case sizeof(int):
- return *(int *)ptr;
- case sizeof(char):
- return *(char *)ptr;
- }
-
- return -1;
-}
-
-
-int gen_dump_struct(TALLOC_CTX *mem_ctx,
- const struct parse_struct *pinfo,
- struct parse_string *p,
- const char *ptr,
- unsigned indent)
-{
- char *s = gen_dump(mem_ctx, pinfo, ptr, indent+1);
- if (!s) return -1;
- if (addstr(mem_ctx, p, "{\n") ||
- addstr(mem_ctx, p, s) ||
- addtabbed(mem_ctx, p, "}", indent)) {
- return -1;
- }
- return 0;
-}
-
-static int gen_dump_string(TALLOC_CTX *mem_ctx,
- struct parse_string *p,
- const struct parse_struct *pinfo,
- const char *data,
- unsigned indent)
-{
- const char *ptr = *(char **)data;
- char *s = encode_bytes(mem_ctx, ptr, strlen(ptr));
- if (addtabbed(mem_ctx, p, pinfo->name, indent) ||
- addstr(mem_ctx, p, " = ") ||
- addchar(mem_ctx, p, '{') ||
- addstr(mem_ctx, p, s) ||
- addstr(mem_ctx, p, "}\n")) {
- return -1;
- }
- return 0;
-}
-
-/*
- find the length of a nullterm array
-*/
-static int len_nullterm(const char *ptr, int size, int array_len)
-{
- int len;
-
- if (size == 1) {
- len = strnlen(ptr, array_len);
- } else {
- for (len=0; len < array_len; len++) {
- if (all_zero(ptr+len*size, size)) break;
- }
- }
-
- if (len == 0) len = 1;
-
- return len;
-}
-
-
-/* the generic dump routine. Scans the parse information for this structure
- and processes it recursively */
-char *gen_dump(TALLOC_CTX *mem_ctx,
- const struct parse_struct *pinfo,
- const char *data,
- unsigned indent)
-{
- struct parse_string p;
- int i;
-
- p.length = 0;
- p.allocated = 0;
- p.s = NULL;
-
- if (addstr(mem_ctx, &p, "") != 0) {
- return NULL;
- }
-
- for (i=0;pinfo[i].name;i++) {
- const char *ptr = data + pinfo[i].offset;
- unsigned size = pinfo[i].size;
-
- if (pinfo[i].ptr_count) {
- size = sizeof(void *);
- }
-
- /* special handling for array types */
- if (pinfo[i].array_len) {
- unsigned len = pinfo[i].array_len;
- if (pinfo[i].flags & FLAG_NULLTERM) {
- len = len_nullterm(ptr, size, len);
- }
- if (gen_dump_array(mem_ctx, &p, &pinfo[i], ptr,
- len, indent)) {
- goto failed;
- }
- continue;
- }
-
- /* and dynamically sized arrays */
- if (pinfo[i].dynamic_len) {
- int len = find_var(pinfo, data, pinfo[i].dynamic_len);
- struct parse_struct p2 = pinfo[i];
- if (len < 0) {
- goto failed;
- }
- if (len > 0) {
- if (pinfo[i].flags & FLAG_NULLTERM) {
- len = len_nullterm(*(char **)ptr,
- pinfo[i].size, len);
- }
- p2.ptr_count--;
- p2.dynamic_len = NULL;
- if (gen_dump_array(mem_ctx, &p, &p2,
- *(char **)ptr,
- len, indent) != 0) {
- goto failed;
- }
- }
- continue;
- }
-
- /* don't dump zero elements */
- if (!(pinfo[i].flags & FLAG_ALWAYS) && all_zero(ptr, size)) continue;
-
- /* assume char* is a null terminated string */
- if (pinfo[i].size == 1 && pinfo[i].ptr_count == 1 &&
- pinfo[i].dump_fn == gen_dump_char) {
- if (gen_dump_string(mem_ctx, &p, &pinfo[i], ptr, indent) != 0) {
- goto failed;
- }
- continue;
- }
-
- /* generic pointer dereference */
- if (pinfo[i].ptr_count) {
- ptr = *(const char **)ptr;
- }
-
- if (addtabbed(mem_ctx, &p, pinfo[i].name, indent) ||
- addstr(mem_ctx, &p, " = ") ||
- gen_dump_one(mem_ctx, &p, &pinfo[i], ptr, indent) ||
- addstr(mem_ctx, &p, "\n")) {
- goto failed;
- }
- }
- return p.s;
-
-failed:
- return NULL;
-}
-
-/* search for a character in a string, skipping over sections within
- matching braces */
-static char *match_braces(char *s, char c)
-{
- int depth = 0;
- while (*s) {
- switch (*s) {
- case '}':
- depth--;
- break;
- case '{':
- depth++;
- break;
- }
- if (depth == 0 && *s == c) {
- return s;
- }
- s++;
- }
- return s;
-}
-
-/* parse routine for enumerated types */
-int gen_parse_enum(TALLOC_CTX *mem_ctx,
- const struct enum_struct *einfo,
- char *ptr,
- const char *str)
-{
- unsigned v;
- int i;
-
- if (isdigit(*str)) {
- if (sscanf(str, "%u", &v) != 1) {
- errno = EINVAL;
- return -1;
- }
- *(unsigned *)ptr = v;
- return 0;
- }
-
- for (i=0;einfo[i].name;i++) {
- if (strcmp(einfo[i].name, str) == 0) {
- *(unsigned *)ptr = einfo[i].value;
- return 0;
- }
- }
-
- /* unknown enum value?? */
- return -1;
-}
-
-
-/* parse all base types */
-static int gen_parse_base(TALLOC_CTX *mem_ctx,
- const struct parse_struct *pinfo,
- char *ptr,
- const char *str)
-{
- if (pinfo->parse_fn == gen_parse_char && pinfo->ptr_count==1) {
- unsigned len;
- char *s = decode_bytes(mem_ctx, str, &len);
- if (!s) return -1;
- *(char **)ptr = s;
- return 0;
- }
-
- if (pinfo->ptr_count) {
- unsigned size = pinfo->ptr_count>1?sizeof(void *):pinfo->size;
- struct parse_struct p2 = *pinfo;
- *(void **)ptr = talloc(mem_ctx, size);
- if (! *(void **)ptr) {
- return -1;
- }
- memset(*(void **)ptr, 0, size);
- ptr = *(char **)ptr;
- p2.ptr_count--;
- return gen_parse_base(mem_ctx, &p2, ptr, str);
- }
-
- return pinfo->parse_fn(mem_ctx, ptr, str);
-}
-
-/* parse a generic array */
-static int gen_parse_array(TALLOC_CTX *mem_ctx,
- const struct parse_struct *pinfo,
- char *ptr,
- const char *str,
- int array_len)
-{
- char *p, *p2;
- unsigned size = pinfo->size;
-
- /* special handling of fixed length strings */
- if (array_len != 0 &&
- pinfo->ptr_count == 0 &&
- pinfo->dump_fn == gen_dump_char) {
- unsigned len = 0;
- char *s = decode_bytes(mem_ctx, str, &len);
- if (!s || (len > array_len)) return -1;
- memset(ptr, 0, array_len);
- memcpy(ptr, s, len);
- return 0;
- }
-
- if (pinfo->ptr_count) {
- size = sizeof(void *);
- }
-
- while (*str) {
- unsigned idx;
- int done;
-
- idx = atoi(str);
- p = strchr(str,':');
- if (!p) break;
- p++;
- p2 = match_braces(p, ',');
- done = (*p2 != ',');
- *p2 = 0;
-
- if (*p == '{') {
- p++;
- p[strlen(p)-1] = 0;
- }
-
- if (gen_parse_base(mem_ctx, pinfo, ptr + idx*size, p) != 0) {
- return -1;
- }
-
- if (done) break;
- str = p2+1;
- }
-
- return 0;
-}
-
-/* parse one element, hanlding dynamic and static arrays */
-static int gen_parse_one(TALLOC_CTX *mem_ctx,
- const struct parse_struct *pinfo,
- const char *name,
- char *data,
- const char *str)
-{
- int i;
- for (i=0;pinfo[i].name;i++) {
- if (strcmp(pinfo[i].name, name) == 0) {
- break;
- }
- }
- if (pinfo[i].name == NULL) {
- return 0;
- }
-
- if (pinfo[i].array_len) {
- return gen_parse_array(mem_ctx, &pinfo[i],
- data+pinfo[i].offset,
- str, pinfo[i].array_len);
- }
-
- if (pinfo[i].dynamic_len) {
- int len = find_var(pinfo, data, pinfo[i].dynamic_len);
- if (len < 0) {
- errno = EINVAL;
- return -1;
- }
- if (len > 0) {
- struct parse_struct p2 = pinfo[i];
- char *ptr;
- unsigned size = pinfo[i].ptr_count>1?sizeof(void*):pinfo[i].size;
- ptr = talloc(mem_ctx, len*size);
- if (!ptr) {
- errno = ENOMEM;
- return -1;
- }
- memset(ptr, 0, len*size);
- *((char **)(data + pinfo[i].offset)) = ptr;
- p2.ptr_count--;
- p2.dynamic_len = NULL;
- return gen_parse_array(mem_ctx, &p2, ptr, str, len);
- }
- return 0;
- }
-
- return gen_parse_base(mem_ctx, &pinfo[i], data + pinfo[i].offset, str);
-}
-
-int gen_parse_struct(TALLOC_CTX * mem_ctx, const struct parse_struct *pinfo, char *ptr, const char *str)
-{
- return gen_parse(mem_ctx, pinfo, ptr, str);
-}
-
-/* the main parse routine */
-int gen_parse(TALLOC_CTX *mem_ctx, const struct parse_struct *pinfo, char *data, const char *s)
-{
- char *str, *s0;
-
- s0 = talloc_strdup(mem_ctx, s);
- str = s0;
-
- while (*str) {
- char *p;
- char *name;
- char *value;
-
- /* skip leading whitespace */
- while (isspace(*str)) str++;
-
- p = strchr(str, '=');
- if (!p) break;
- value = p+1;
- while (p > str && isspace(*(p-1))) {
- p--;
- }
-
- *p = 0;
- name = str;
-
- while (isspace(*value)) value++;
-
- if (*value == '{') {
- str = match_braces(value, '}');
- value++;
- } else {
- str = match_braces(value, '\n');
- }
-
- *str++ = 0;
-
- if (gen_parse_one(mem_ctx, pinfo, name, data, value) != 0) {
- return -1;
- }
- }
-
- return 0;
-}
-
-
-
-/* for convenience supply some standard dumpers and parsers here */
-
-int gen_parse_char(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(unsigned char *)ptr = atoi(str);
- return 0;
-}
-
-int gen_parse_int(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(int *)ptr = atoi(str);
- return 0;
-}
-
-int gen_parse_unsigned(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(unsigned *)ptr = strtoul(str, NULL, 10);
- return 0;
-}
-
-int gen_parse_time_t(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(time_t *)ptr = strtoul(str, NULL, 10);
- return 0;
-}
-
-int gen_parse_double(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(double *)ptr = atof(str);
- return 0;
-}
-
-int gen_parse_float(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(float *)ptr = atof(str);
- return 0;
-}
-
-int gen_dump_char(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(unsigned char *)(ptr));
-}
-
-int gen_dump_int(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%d", *(int *)(ptr));
-}
-
-int gen_dump_unsigned(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(unsigned *)(ptr));
-}
-
-int gen_dump_time_t(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(time_t *)(ptr));
-}
-
-int gen_dump_double(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%lg", *(double *)(ptr));
-}
-
-int gen_dump_float(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%g", *(float *)(ptr));
-}
diff --git a/source/lib/genparser_samba.c b/source/lib/genparser_samba.c
deleted file mode 100644
index 8f469a46d6a..00000000000
--- a/source/lib/genparser_samba.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- Copyright (C) Andrew Tridgell <genstruct@tridgell.net> 2002
- Copyright (C) Simo Sorce <idra@samba.org> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "genparser_samba.h"
-
-/* PARSE functions */
-
-int gen_parse_uint8(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(uint8 *)ptr = atoi(str);
- return 0;
-}
-
-int gen_parse_uint16(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(uint16 *)ptr = atoi(str);
- return 0;
-}
-
-int gen_parse_uint32(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- *(uint32 *)ptr = strtoul(str, NULL, 10);
- return 0;
-}
-
-int gen_parse_NTTIME(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- if(sscanf(str, "%u,%u", &(((NTTIME *)(ptr))->high), &(((NTTIME *)(ptr))->low)) != 2) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-int gen_parse_DOM_SID(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- if(!string_to_sid((DOM_SID *)ptr, str)) return -1;
- return 0;
-}
-
-int gen_parse_SEC_ACCESS(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- ((SEC_ACCESS *)ptr)->mask = strtoul(str, NULL, 10);
- return 0;
-}
-
-int gen_parse_GUID(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- int info[UUID_FLAT_SIZE];
- int i;
- char *sc;
- char *p;
- char *m;
-
- m = strdup(str);
- if (!m) return -1;
- sc = m;
-
- memset(info, 0, sizeof(info));
- for (i = 0; i < UUID_FLAT_SIZE; i++) {
- p = strchr(sc, ',');
- if (p != NULL) p = '\0';
- info[i] = atoi(sc);
- if (p != NULL) sc = p + 1;
- }
- free(m);
-
- for (i = 0; i < UUID_FLAT_SIZE; i++) {
- ((UUID_FLAT *)ptr)->info[i] = info[i];
- }
-
- return 0;
-}
-
-int gen_parse_SEC_ACE(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- return gen_parse_struct(mem_ctx, pinfo_security_ace_info, ptr, str);
-}
-
-int gen_parse_SEC_ACL(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- return gen_parse_struct(mem_ctx, pinfo_security_acl_info, ptr, str);
-}
-
-int gen_parse_SEC_DESC(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- return gen_parse_struct(mem_ctx, pinfo_security_descriptor_info, ptr, str);
-}
-
-int gen_parse_LUID_ATTR(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- return gen_parse_struct(mem_ctx, pinfo_luid_attr_info, ptr, str);
-}
-
-int gen_parse_LUID(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- if(sscanf(str, "%u,%u", &(((LUID *)(ptr))->high), &(((LUID *)(ptr))->low)) != 2) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-int gen_parse_DATA_BLOB(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- return gen_parse_struct(mem_ctx, pinfo_data_blob_info, ptr, str);
-}
-
-int gen_parse_TALLOC_CTX(TALLOC_CTX *mem_ctx, char *ptr, const char *str)
-{
- (TALLOC_CTX *)ptr = NULL;
- return 0;
-}
-
-/* DUMP functions */
-
-int gen_dump_uint8(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(uint8 *)(ptr));
-}
-
-int gen_dump_uint16(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(uint16 *)(ptr));
-}
-
-int gen_dump_uint32(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", *(uint32 *)(ptr));
-}
-
-int gen_dump_NTTIME(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- uint32 low, high;
-
- high = ((NTTIME *)(ptr))->high;
- low = ((NTTIME *)(ptr))->low;
- return addshort(mem_ctx, p, "%u,%u", high, low);
-}
-
-int gen_dump_DOM_SID(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- fstring sidstr;
-
- sid_to_string(sidstr, (DOM_SID *)ptr);
- return addstr(mem_ctx, p, sidstr);
-}
-
-int gen_dump_SEC_ACCESS(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "%u", ((SEC_ACCESS *)ptr)->mask);
-}
-
-int gen_dump_GUID(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- int i, r;
-
- for (i = 0; i < (UUID_FLAT_SIZE - 1); i++) {
- if (!(r = addshort(mem_ctx, p, "%d,", ((UUID_FLAT *)ptr)->info[i]))) return r;
- }
- return addshort(mem_ctx, p, "%d", ((UUID_FLAT *)ptr)->info[i]);
-}
-
-int gen_dump_SEC_ACE(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return gen_dump_struct(mem_ctx, pinfo_security_ace_info, p, ptr, indent);
-}
-
-int gen_dump_SEC_ACL(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return gen_dump_struct(mem_ctx, pinfo_security_acl_info, p, ptr, indent);
-}
-
-int gen_dump_SEC_DESC(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return gen_dump_struct(mem_ctx, pinfo_security_descriptor_info, p, ptr, indent);
-}
-
-int gen_dump_LUID_ATTR(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return gen_dump_struct(mem_ctx, pinfo_luid_attr_info, p, ptr, indent);
-}
-
-int gen_dump_LUID(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- uint32 low, high;
-
- high = ((LUID *)(ptr))->high;
- low = ((LUID *)(ptr))->low;
- return addshort(mem_ctx, p, "%u,%u", high, low);
-}
-
-int gen_dump_DATA_BLOB(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return gen_dump_struct(mem_ctx, pinfo_data_blob_info, p, ptr, indent);
-}
-
-int gen_dump_TALLOC_CTX(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent)
-{
- return addshort(mem_ctx, p, "TALLOC_CTX");
-}
diff --git a/source/lib/genrand.c b/source/lib/genrand.c
index bc9f21c6403..009c62fcf35 100644
--- a/source/lib/genrand.c
+++ b/source/lib/genrand.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2
Functions to create reasonable random numbers for crypto use.
@@ -24,8 +25,8 @@
static unsigned char hash[258];
static uint32 counter;
-static unsigned char *reseed_data;
-static size_t reseed_data_size;
+unsigned char *reseed_data;
+size_t reseed_data_size;
/****************************************************************
Copy any user given reseed data.
@@ -146,10 +147,18 @@ static int do_reseed(BOOL use_fd, int fd)
return fd;
}
+#ifdef __INSURE__
+ memset(seed_inbuf, '\0', sizeof(seed_inbuf));
+#endif
+
/* Add in some secret file contents */
do_filehash("/etc/shadow", &seed_inbuf[0]);
+#ifdef WITH_TDB_SAM
+ do_filehash(lp_tdb_passwd_file(), &seed_inbuf[16]);
+#else
do_filehash(lp_smb_passwd_file(), &seed_inbuf[16]);
+#endif
/*
* Add in the root encrypted password.
@@ -157,14 +166,13 @@ static int do_reseed(BOOL use_fd, int fd)
* seriously this will be secret.
*/
- pw = getpwnam_alloc("root");
+ pw = sys_getpwnam("root");
if (pw && pw->pw_passwd) {
size_t i;
unsigned char md4_tmp[16];
mdfour(md4_tmp, (unsigned char *)pw->pw_passwd, strlen(pw->pw_passwd));
for (i=0;i<16;i++)
seed_inbuf[8+i] ^= md4_tmp[i];
- passwd_free(&pw);
}
/*
@@ -259,7 +267,7 @@ char *generate_random_str(size_t len)
len = sizeof(retstr) -1;
generate_random_buffer( retstr, len, False);
for (i = 0; i < len; i++)
- retstr[i] = c_list[ retstr[i] % (sizeof(c_list)-1) ];
+ retstr[i] = c_list[ retstr[i] % sizeof(c_list) ];
retstr[i] = '\0';
diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c
index df5e0359aa2..f0c24710e00 100644
--- a/source/lib/getsmbpass.c
+++ b/source/lib/getsmbpass.c
@@ -83,96 +83,71 @@ static int tcsetattr(int fd, int flags, struct sgttyb *t)
static struct termios t;
#endif /* SYSV_TERMIO */
-static SIG_ATOMIC_T gotintr;
-static int in_fd = -1;
-
-/***************************************************************
- Signal function to tell us were ^C'ed.
-****************************************************************/
-
-static void gotintr_sig(void)
-{
- gotintr = 1;
- if (in_fd != -1)
- close(in_fd); /* Safe way to force a return. */
- in_fd = -1;
-}
-
-char *getsmbpass(const char *prompt)
+char *getsmbpass(const char *prompt)
{
- FILE *in, *out;
- int echo_off;
- static char buf[256];
- static size_t bufsize = sizeof(buf);
- size_t nread;
-
- /* Catch problematic signals */
- CatchSignal(SIGINT, SIGNAL_CAST gotintr_sig);
-
- /* Try to write to and read from the terminal if we can.
- If we can't open the terminal, use stderr and stdin. */
-
- in = fopen ("/dev/tty", "w+");
- if (in == NULL) {
- in = stdin;
- out = stderr;
- } else {
- out = in;
- }
-
- setvbuf(in, NULL, _IONBF, 0);
-
- /* Turn echoing off if it is on now. */
-
- if (tcgetattr (fileno (in), &t) == 0) {
- if (ECHO_IS_ON(t)) {
- TURN_ECHO_OFF(t);
- echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
- TURN_ECHO_ON(t);
- } else {
- echo_off = 0;
- }
- } else {
- echo_off = 0;
- }
-
- /* Write the prompt. */
- fputs(prompt, out);
- fflush(out);
-
- /* Read the password. */
- buf[0] = 0;
- if (!gotintr) {
- in_fd = fileno(in);
- fgets(buf, bufsize, in);
- }
- nread = strlen(buf);
- if (buf[nread - 1] == '\n')
- buf[nread - 1] = '\0';
-
- /* Restore echoing. */
- if (echo_off) {
- if (gotintr && in_fd == -1)
- in = fopen ("/dev/tty", "w+");
- if (in != NULL)
- tcsetattr (fileno (in), TCSANOW, &t);
- }
-
- fprintf(out, "\n");
- fflush(out);
-
- if (in != stdin) /* We opened the terminal; now close it. */
- fclose(in);
-
- /* Catch problematic signals */
- CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
-
- if (gotintr) {
- printf("Interupted by signal.\n");
- fflush(stdout);
- exit(1);
+ FILE *in, *out;
+ int echo_off;
+ static char buf[256];
+ static size_t bufsize = sizeof(buf);
+ size_t nread;
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST SIG_IGN);
+
+ /* Try to write to and read from the terminal if we can.
+ If we can't open the terminal, use stderr and stdin. */
+
+ in = fopen ("/dev/tty", "w+");
+ if (in == NULL)
+ {
+ in = stdin;
+ out = stderr;
+ }
+ else
+ out = in;
+
+ setvbuf(in, NULL, _IONBF, 0);
+
+ /* Turn echoing off if it is on now. */
+
+ if (tcgetattr (fileno (in), &t) == 0)
+ {
+ if (ECHO_IS_ON(t))
+ {
+ TURN_ECHO_OFF(t);
+ echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
+ TURN_ECHO_ON(t);
}
- return buf;
+ else
+ echo_off = 0;
+ }
+ else
+ echo_off = 0;
+
+ /* Write the prompt. */
+ fputs (prompt, out);
+ fflush (out);
+
+ /* Read the password. */
+ buf[0] = 0;
+ fgets(buf, bufsize, in);
+ nread = strlen(buf);
+ if (buf[nread - 1] == '\n')
+ buf[nread - 1] = '\0';
+
+ /* Restore echoing. */
+ if (echo_off)
+ (void) tcsetattr (fileno (in), TCSANOW, &t);
+
+ if (in != stdin)
+ /* We opened the terminal; now close it. */
+ fclose (in);
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
+
+ printf("\n");
+ return buf;
}
#else
diff --git a/source/lib/hash.c b/source/lib/hash.c
index 18b6534dec2..0f12ba73b1f 100644
--- a/source/lib/hash.c
+++ b/source/lib/hash.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
Copyright (C) Ying Chen 2000.
Copyright (C) Jeremy Allison 2000.
@@ -28,7 +29,7 @@
#include "includes.h"
static BOOL enlarge_hash_table(hash_table *table);
-static unsigned primes[] =
+static int primes[] =
{17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411};
/****************************************************************************
@@ -47,9 +48,9 @@ static unsigned primes[] =
****************************************************************************
*/
-BOOL hash_table_init(hash_table *table, unsigned num_buckets, compare_function compare_func)
+BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func)
{
- unsigned i;
+ int i;
ubi_dlList *bucket;
table->num_elements = 0;
@@ -84,20 +85,21 @@ BOOL hash_table_init(hash_table *table, unsigned num_buckets, compare_function c
* For the last few chars that cannot be int'ed, use char instead.
* The function returns the bucket index number for the hashed
* key.
- * JRA. Use a djb-algorithm hash for speed.
**************************************************************
*/
static int string_hash(int hash_size, const char *key)
{
- u32 n = 0;
- const char *p;
- for (p = key; *p != '\0'; p++) {
- n = ((n << 5) + n) ^ (u32)(*p);
- }
- return (n % hash_size);
+ u32 value; /* Used to compute the hash value. */
+ u32 i; /* Used to cycle through random values. */
+
+ for (value = 0x238F13AF, i=0; key[i]; i++)
+ value = (value + (key[i] << (i*5 % 24)));
+
+ return (1103515243 * value + 12345) % hash_size;
}
+
/* *************************************************************************
* Search the hash table for the entry in the hash chain.
* The function returns the pointer to the
@@ -117,7 +119,7 @@ static hash_element *hash_chain_find(hash_table *table, ubi_dlList *hash_chain,
{
hash_element *hash_elem;
ubi_dlNodePtr lru_item;
- unsigned int i = 0;
+ int i = 0;
for (hash_elem = (hash_element *)(ubi_dlFirst(hash_chain)); i < hash_chain->count;
i++, hash_elem = (hash_element *)(ubi_dlNext(hash_elem))) {
@@ -300,7 +302,7 @@ static BOOL enlarge_hash_table(hash_table *table)
void hash_clear(hash_table *table)
{
- unsigned int i;
+ int i;
ubi_dlList *bucket = table->buckets;
hash_element *hash_elem;
for (i = 0; i < table->size; bucket++, i++) {
diff --git a/source/lib/hmacmd5.c b/source/lib/hmacmd5.c
deleted file mode 100644
index f436fd30c0e..00000000000
--- a/source/lib/hmacmd5.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- HMAC MD5 code for use in NTLMv2
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Andrew Tridgell 1992-2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* taken direct from rfc2104 implementation and modified for suitable use
- * for ntlmv2.
- */
-
-#include "includes.h"
-
-/***********************************************************************
- the rfc 2104 version of hmac_md5 initialisation.
-***********************************************************************/
-void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx)
-{
- int i;
-
- /* if key is longer than 64 bytes reset it to key=MD5(key) */
- if (key_len > 64)
- {
- uchar tk[16];
- struct MD5Context tctx;
-
- MD5Init(&tctx);
- MD5Update(&tctx, key, key_len);
- MD5Final(tk, &tctx);
-
- key = tk;
- key_len = 16;
- }
-
- /* start out by storing key in pads */
- ZERO_STRUCT(ctx->k_ipad);
- ZERO_STRUCT(ctx->k_opad);
- memcpy( ctx->k_ipad, key, key_len);
- memcpy( ctx->k_opad, key, key_len);
-
- /* XOR key with ipad and opad values */
- for (i=0; i<64; i++)
- {
- ctx->k_ipad[i] ^= 0x36;
- ctx->k_opad[i] ^= 0x5c;
- }
-
- MD5Init(&ctx->ctx);
- MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-}
-
-/***********************************************************************
- the microsoft version of hmac_md5 initialisation.
-***********************************************************************/
-void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
- HMACMD5Context *ctx)
-{
- int i;
-
- /* if key is longer than 64 bytes truncate it */
- if (key_len > 64)
- {
- key_len = 64;
- }
-
- /* start out by storing key in pads */
- ZERO_STRUCT(ctx->k_ipad);
- ZERO_STRUCT(ctx->k_opad);
- memcpy( ctx->k_ipad, key, key_len);
- memcpy( ctx->k_opad, key, key_len);
-
- /* XOR key with ipad and opad values */
- for (i=0; i<64; i++) {
- ctx->k_ipad[i] ^= 0x36;
- ctx->k_opad[i] ^= 0x5c;
- }
-
- MD5Init(&ctx->ctx);
- MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-}
-
-/***********************************************************************
- update hmac_md5 "inner" buffer
-***********************************************************************/
-void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx)
-{
- MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */
-}
-
-/***********************************************************************
- finish off hmac_md5 "inner" buffer and generate outer one.
-***********************************************************************/
-void hmac_md5_final(uchar *digest, HMACMD5Context *ctx)
-
-{
- struct MD5Context ctx_o;
-
- MD5Final(digest, &ctx->ctx);
-
- MD5Init(&ctx_o);
- MD5Update(&ctx_o, ctx->k_opad, 64);
- MD5Update(&ctx_o, digest, 16);
- MD5Final(digest, &ctx_o);
-}
-
-/***********************************************************
- single function to calculate an HMAC MD5 digest from data.
- use the microsoft hmacmd5 init method because the key is 16 bytes.
-************************************************************/
-void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest)
-{
- HMACMD5Context ctx;
- hmac_md5_init_limK_to_64(key, 16, &ctx);
- if (data_len != 0)
- {
- hmac_md5_update(data, data_len, &ctx);
- }
- hmac_md5_final(digest, &ctx);
-}
-
diff --git a/source/lib/iconv.c b/source/lib/iconv.c
deleted file mode 100644
index 7df73192f24..00000000000
--- a/source/lib/iconv.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- minimal iconv implementation
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 2002,2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- * We have to use strcasecmp here as the character conversions
- * haven't been initialised yet. JRA.
- */
-
-#undef strcasecmp
-
-/**
- * @file
- *
- * @brief Samba wrapper/stub for iconv character set conversion.
- *
- * iconv is the XPG2 interface for converting between character
- * encodings. This file provides a Samba wrapper around it, and also
- * a simple reimplementation that is used if the system does not
- * implement iconv.
- *
- * Samba only works with encodings that are supersets of ASCII: ascii
- * characters like whitespace can be tested for directly, multibyte
- * sequences start with a byte with the high bit set, and strings are
- * terminated by a nul byte.
- *
- * Note that the only function provided by iconv is conversion between
- * characters. It doesn't directly support operations like
- * uppercasing or comparison. We have to convert to UCS-2 and compare
- * there.
- *
- * @sa Samba Developers Guide
- **/
-
-static size_t ascii_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ascii_push(void *,char **, size_t *, char **, size_t *);
-static size_t latin1_push(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_pull(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_push(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_push(void *,char **, size_t *, char **, size_t *);
-static size_t iconv_copy(void *,char **, size_t *, char **, size_t *);
-
-static struct charset_functions builtin_functions[] = {
- {"UCS-2LE", iconv_copy, iconv_copy},
- {"UTF8", utf8_pull, utf8_push},
- {"ASCII", ascii_pull, ascii_push},
- {"646", ascii_pull, ascii_push},
- {"ISO-8859-1", ascii_pull, latin1_push},
- {"UCS2-HEX", ucs2hex_pull, ucs2hex_push},
- {NULL, NULL, NULL}
-};
-
-static struct charset_functions *charsets = NULL;
-
-static struct charset_functions *find_charset_functions(const char *name)
-{
- struct charset_functions *c = charsets;
-
- while(c) {
- if (strcasecmp(name, c->name) == 0) {
- return c;
- }
- c = c->next;
- }
-
- return NULL;
-}
-
-NTSTATUS smb_register_charset(struct charset_functions *funcs)
-{
- if (!funcs) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5, ("Attempting to register new charset %s\n", funcs->name));
- /* Check whether we already have this charset... */
- if (find_charset_functions(funcs->name)) {
- DEBUG(0, ("Duplicate charset %s, not registering\n", funcs->name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- funcs->next = funcs->prev = NULL;
- DEBUG(5, ("Registered charset %s\n", funcs->name));
- DLIST_ADD(charsets, funcs);
- return NT_STATUS_OK;
-}
-
-static void lazy_initialize_iconv(void)
-{
- static BOOL initialized;
- int i;
-
- if (!initialized) {
- initialized = True;
- for(i = 0; builtin_functions[i].name; i++)
- smb_register_charset(&builtin_functions[i]);
- static_init_charset;
- }
-}
-
-/* if there was an error then reset the internal state,
- this ensures that we don't have a shift state remaining for
- character sets like SJIS */
-static size_t sys_iconv(void *cd,
- char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
-#ifdef HAVE_NATIVE_ICONV
- size_t ret = iconv((iconv_t)cd,
- inbuf, inbytesleft,
- outbuf, outbytesleft);
- if (ret == (size_t)-1) iconv(cd, NULL, NULL, NULL, NULL);
- return ret;
-#else
- errno = EINVAL;
- return -1;
-#endif
-}
-
-/**
- * This is a simple portable iconv() implementaion.
- *
- * It only knows about a very small number of character sets - just
- * enough that Samba works on systems that don't have iconv.
- **/
-size_t smb_iconv(smb_iconv_t cd,
- char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- char cvtbuf[2048];
- char *bufp = cvtbuf;
- size_t bufsize;
-
- /* in many cases we can go direct */
- if (cd->direct) {
- return cd->direct(cd->cd_direct,
- (char **)inbuf, inbytesleft, outbuf, outbytesleft);
- }
-
-
- /* otherwise we have to do it chunks at a time */
- while (*inbytesleft > 0) {
- bufp = cvtbuf;
- bufsize = sizeof(cvtbuf);
-
- if (cd->pull(cd->cd_pull,
- (char **)inbuf, inbytesleft, &bufp, &bufsize) == -1
- && errno != E2BIG) return -1;
-
- bufp = cvtbuf;
- bufsize = sizeof(cvtbuf) - bufsize;
-
- if (cd->push(cd->cd_push,
- &bufp, &bufsize,
- outbuf, outbytesleft) == -1) return -1;
- }
-
- return 0;
-}
-
-/*
- simple iconv_open() wrapper
- */
-smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
-{
- smb_iconv_t ret;
- struct charset_functions *from, *to;
-
- lazy_initialize_iconv();
- from = charsets;
- to = charsets;
-
- ret = (smb_iconv_t)malloc(sizeof(*ret));
- if (!ret) {
- errno = ENOMEM;
- return (smb_iconv_t)-1;
- }
- memset(ret, 0, sizeof(*ret));
-
- ret->from_name = strdup(fromcode);
- ret->to_name = strdup(tocode);
-
- /* check for the simplest null conversion */
- if (strcasecmp(fromcode, tocode) == 0) {
- ret->direct = iconv_copy;
- return ret;
- }
-
- /* check if we have a builtin function for this conversion */
- from = find_charset_functions(fromcode);
- if(from)ret->pull = from->pull;
-
- to = find_charset_functions(tocode);
- if(to)ret->push = to->push;
-
- /* check if we can use iconv for this conversion */
-#ifdef HAVE_NATIVE_ICONV
- if (!ret->pull) {
- ret->cd_pull = iconv_open("UCS-2LE", fromcode);
- if (ret->cd_pull != (iconv_t)-1)
- ret->pull = sys_iconv;
- }
-
- if (!ret->push) {
- ret->cd_push = iconv_open(tocode, "UCS-2LE");
- if (ret->cd_push != (iconv_t)-1)
- ret->push = sys_iconv;
- }
-#endif
-
- /* check if there is a module available that can do this conversion */
- if (!ret->pull && NT_STATUS_IS_OK(smb_probe_module("charset", fromcode))) {
- if(!(from = find_charset_functions(fromcode)))
- DEBUG(0, ("Module %s doesn't provide charset %s!\n", fromcode, fromcode));
- else
- ret->pull = from->pull;
- }
-
- if (!ret->push && NT_STATUS_IS_OK(smb_probe_module("charset", tocode))) {
- if(!(to = find_charset_functions(tocode)))
- DEBUG(0, ("Module %s doesn't provide charset %s!\n", tocode, tocode));
- else
- ret->push = to->push;
- }
-
- if (!ret->push || !ret->pull) {
- SAFE_FREE(ret->from_name);
- SAFE_FREE(ret->to_name);
- SAFE_FREE(ret);
- errno = EINVAL;
- return (smb_iconv_t)-1;
- }
-
- /* check for conversion to/from ucs2 */
- if (strcasecmp(fromcode, "UCS-2LE") == 0 && to) {
- ret->direct = to->push;
- ret->push = ret->pull = NULL;
- return ret;
- }
-
- if (strcasecmp(tocode, "UCS-2LE") == 0 && from) {
- ret->direct = from->pull;
- ret->push = ret->pull = NULL;
- return ret;
- }
-
- /* Check if we can do the conversion direct */
-#ifdef HAVE_NATIVE_ICONV
- if (strcasecmp(fromcode, "UCS-2LE") == 0) {
- ret->direct = sys_iconv;
- ret->cd_direct = ret->cd_push;
- ret->cd_push = NULL;
- return ret;
- }
- if (strcasecmp(tocode, "UCS-2LE") == 0) {
- ret->direct = sys_iconv;
- ret->cd_direct = ret->cd_pull;
- ret->cd_pull = NULL;
- return ret;
- }
-#endif
-
- return ret;
-}
-
-/*
- simple iconv_close() wrapper
-*/
-int smb_iconv_close (smb_iconv_t cd)
-{
-#ifdef HAVE_NATIVE_ICONV
- if (cd->cd_direct) iconv_close((iconv_t)cd->cd_direct);
- if (cd->cd_pull) iconv_close((iconv_t)cd->cd_pull);
- if (cd->cd_push) iconv_close((iconv_t)cd->cd_push);
-#endif
-
- SAFE_FREE(cd->from_name);
- SAFE_FREE(cd->to_name);
-
- memset(cd, 0, sizeof(*cd));
- SAFE_FREE(cd);
- return 0;
-}
-
-
-/**********************************************************************
- the following functions implement the builtin character sets in Samba
- and also the "test" character sets that are designed to test
- multi-byte character set support for english users
-***********************************************************************/
-
-static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- (*outbuf)[0] = (*inbuf)[0];
- (*outbuf)[1] = 0;
- (*inbytesleft) -= 1;
- (*outbytesleft) -= 2;
- (*inbuf) += 1;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int ir_count=0;
-
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- (*outbuf)[0] = (*inbuf)[0] & 0x7F;
- if ((*inbuf)[1]) ir_count++;
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return ir_count;
-}
-
-static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int ir_count=0;
-
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- (*outbuf)[0] = (*inbuf)[0];
- if ((*inbuf)[1]) ir_count++;
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return ir_count;
-}
-
-static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- unsigned v;
-
- if ((*inbuf)[0] != '@') {
- /* seven bit ascii case */
- (*outbuf)[0] = (*inbuf)[0];
- (*outbuf)[1] = 0;
- (*inbytesleft) -= 1;
- (*outbytesleft) -= 2;
- (*inbuf) += 1;
- (*outbuf) += 2;
- continue;
- }
- /* it's a hex character */
- if (*inbytesleft < 5) {
- errno = EINVAL;
- return -1;
- }
-
- if (sscanf(&(*inbuf)[1], "%04x", &v) != 1) {
- errno = EILSEQ;
- return -1;
- }
-
- (*outbuf)[0] = v&0xff;
- (*outbuf)[1] = v>>8;
- (*inbytesleft) -= 5;
- (*outbytesleft) -= 2;
- (*inbuf) += 5;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- char buf[6];
-
- if ((*inbuf)[1] == 0 &&
- ((*inbuf)[0] & 0x80) == 0 &&
- (*inbuf)[0] != '@') {
- (*outbuf)[0] = (*inbuf)[0];
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- continue;
- }
- if (*outbytesleft < 5) {
- errno = E2BIG;
- return -1;
- }
- snprintf(buf, 6, "@%04x", SVAL(*inbuf, 0));
- memcpy(*outbuf, buf, 5);
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 5;
- (*inbuf) += 2;
- (*outbuf) += 5;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-
-static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int n;
-
- n = MIN(*inbytesleft, *outbytesleft);
-
- memmove(*outbuf, *inbuf, n);
-
- (*inbytesleft) -= n;
- (*outbytesleft) -= n;
- (*inbuf) += n;
- (*outbuf) += n;
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t utf8_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- unsigned char *c = (unsigned char *)*inbuf;
- unsigned char *uc = (unsigned char *)*outbuf;
- int len = 1;
-
- if ((c[0] & 0x80) == 0) {
- uc[0] = c[0];
- uc[1] = 0;
- } else if ((c[0] & 0xf0) == 0xe0) {
- if (*inbytesleft < 3) {
- DEBUG(0,("short utf8 char\n"));
- goto badseq;
- }
- uc[1] = ((c[0]&0xF)<<4) | ((c[1]>>2)&0xF);
- uc[0] = (c[1]<<6) | (c[2]&0x3f);
- len = 3;
- } else if ((c[0] & 0xe0) == 0xc0) {
- if (*inbytesleft < 2) {
- DEBUG(0,("short utf8 char\n"));
- goto badseq;
- }
- uc[1] = (c[0]>>2) & 0x7;
- uc[0] = (c[0]<<6) | (c[1]&0x3f);
- len = 2;
- }
-
- (*inbuf) += len;
- (*inbytesleft) -= len;
- (*outbytesleft) -= 2;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-
-badseq:
- errno = EINVAL;
- return -1;
-}
-
-static size_t utf8_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- unsigned char *c = (unsigned char *)*outbuf;
- unsigned char *uc = (unsigned char *)*inbuf;
- int len=1;
-
- if (uc[1] & 0xf8) {
- if (*outbytesleft < 3) {
- DEBUG(0,("short utf8 write\n"));
- goto toobig;
- }
- c[0] = 0xe0 | (uc[1]>>4);
- c[1] = 0x80 | ((uc[1]&0xF)<<2) | (uc[0]>>6);
- c[2] = 0x80 | (uc[0]&0x3f);
- len = 3;
- } else if (uc[1] | (uc[0] & 0x80)) {
- if (*outbytesleft < 2) {
- DEBUG(0,("short utf8 write\n"));
- goto toobig;
- }
- c[0] = 0xc0 | (uc[1]<<2) | (uc[0]>>6);
- c[1] = 0x80 | (uc[0]&0x3f);
- len = 2;
- } else {
- c[0] = uc[0];
- }
-
-
- (*inbytesleft) -= 2;
- (*outbytesleft) -= len;
- (*inbuf) += 2;
- (*outbuf) += len;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-
-toobig:
- errno = E2BIG;
- return -1;
-}
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 4d8010e31bc..e5cbd337f1f 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
multiple interface handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -26,7 +27,7 @@ static int total_probed;
struct in_addr allones_ip;
struct in_addr loopback_ip;
-static struct interface *local_interfaces;
+static struct interface *local_interfaces = NULL;
#define ALLONES ((uint32)0xFFFFFFFF)
#define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
@@ -38,7 +39,8 @@ Try and find an interface that matches an ip. If we cannot, return NULL
static struct interface *iface_find(struct in_addr ip, BOOL CheckMask)
{
struct interface *i;
- if (is_zero_ip(ip)) return local_interfaces;
+ if (is_zero_ip(ip))
+ return local_interfaces;
for (i=local_interfaces;i;i=i->next)
if (CheckMask) {
@@ -94,18 +96,18 @@ This handles the following different forms:
4) ip/mask
5) bcast/mask
****************************************************************************/
-static void interpret_interface(const char *token)
+static void interpret_interface(char *token)
{
struct in_addr ip, nmask;
char *p;
int i, added=0;
- zero_ip(&ip);
- zero_ip(&nmask);
+ zero_ip(&ip);
+ zero_ip(&nmask);
/* first check if it is an interface name */
for (i=0;i<total_probed;i++) {
- if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
+ if (ms_fnmatch(token, probed_ifaces[i].name) == 0) {
add_interface(probed_ifaces[i].ip,
probed_ifaces[i].netmask);
added = 1;
@@ -114,7 +116,7 @@ static void interpret_interface(const char *token)
if (added) return;
/* maybe it is a DNS name */
- p = strchr_m(token,'/');
+ p = strchr(token,'/');
if (!p) {
ip = *interpret_addr2(token);
for (i=0;i<total_probed;i++) {
@@ -162,7 +164,8 @@ load the list of network interfaces
****************************************************************************/
void load_interfaces(void)
{
- const char **ptr;
+ const char *ptr;
+ fstring token;
int i;
struct iface_struct ifaces[MAX_INTERFACES];
@@ -190,7 +193,7 @@ void load_interfaces(void)
/* if we don't have a interfaces line then use all broadcast capable
interfaces except loopback */
- if (!ptr || !*ptr || !**ptr) {
+ if (!ptr || !*ptr) {
if (total_probed <= 0) {
DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
exit(1);
@@ -205,11 +208,8 @@ void load_interfaces(void)
return;
}
- if (ptr) {
- while (*ptr) {
- interpret_interface(*ptr);
- ptr++;
- }
+ while (next_token(&ptr,token,NULL,sizeof(token))) {
+ interpret_interface(token);
}
if (!local_interfaces) {
@@ -276,6 +276,19 @@ int iface_count(void)
}
/****************************************************************************
+ True if we have two or more interfaces.
+ **************************************************************************/
+BOOL we_are_multihomed(void)
+{
+ static int multi = -1;
+
+ if(multi == -1)
+ multi = (iface_count() > 1 ? True : False);
+
+ return multi;
+}
+
+/****************************************************************************
return the Nth interface
**************************************************************************/
struct interface *get_interface(int n)
@@ -318,21 +331,40 @@ struct in_addr *iface_n_bcast(int n)
}
+/****************************************************************************
+this function provides a simple hash of the configured interfaces. It is
+used to detect a change in interfaces to tell us whether to discard
+the current wins.dat file.
+Note that the result is independent of the order of the interfaces
+ **************************************************************************/
+unsigned iface_hash(void)
+{
+ unsigned ret = 0;
+ struct interface *i;
+
+ for (i=local_interfaces;i;i=i->next) {
+ unsigned x1 = (unsigned)str_checksum(inet_ntoa(i->ip));
+ unsigned x2 = (unsigned)str_checksum(inet_ntoa(i->nmask));
+ ret ^= (x1 ^ x2);
+ }
+
+ return ret;
+}
+
+
/* these 3 functions return the ip/bcast/nmask for the interface
most appropriate for the given ip address. If they can't find
an appropriate interface they return the requested field of the
first known interface. */
-struct in_addr *iface_ip(struct in_addr ip)
+struct in_addr *iface_bcast(struct in_addr ip)
{
struct interface *i = iface_find(ip, True);
- return(i ? &i->ip : &local_interfaces->ip);
+ return(i ? &i->bcast : &local_interfaces->bcast);
}
-/*
- return True if a IP is directly reachable on one of our interfaces
-*/
-BOOL iface_local(struct in_addr ip)
+struct in_addr *iface_ip(struct in_addr ip)
{
- return iface_find(ip, True) ? True : False;
+ struct interface *i = iface_find(ip, True);
+ return(i ? &i->ip : &local_interfaces->ip);
}
diff --git a/source/lib/interfaces.c b/source/lib/interfaces.c
index 96f4b4cd94f..9e8c979aa7b 100644
--- a/source/lib/interfaces.c
+++ b/source/lib/interfaces.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
return a list of network interfaces
Copyright (C) Andrew Tridgell 1998
@@ -38,7 +39,6 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
-#include <sys/time.h>
#include <net/if.h>
#ifdef AUTOCONF_TEST
diff --git a/source/lib/kanji.c b/source/lib/kanji.c
new file mode 100755
index 00000000000..1f7372d6b73
--- /dev/null
+++ b/source/lib/kanji.c
@@ -0,0 +1,1722 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Kanji Extensions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
+ and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
+ and add all jis codes sequence type at 1995.8.16
+ Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
+ Adding features about Machine dependent codes and User Defined Codes
+ by Hiroshi MIURA <miura@samba.gr.jp> 2000.3.19
+*/
+
+#define _KANJI_C_
+#include "includes.h"
+
+/*
+ * Function pointers that get overridden when multi-byte code pages
+ * are loaded.
+ */
+
+const char *(*multibyte_strchr)(const char *, int ) = (const char *(*)(const char *, int )) strchr;
+const char *(*multibyte_strrchr)(const char *, int ) = (const char *(*)(const char *, int )) strrchr;
+const char *(*multibyte_strstr)(const char *, const char *) = (const char *(*)(const char *, const char *)) strstr;
+char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const char *)) strtok;
+
+/*
+ * Kanji is treated differently here due to historical accident of
+ * it being the first non-English codepage added to Samba.
+ * The define 'KANJI' is being overloaded to mean 'use kanji codepage
+ * by default' and also 'this is the filename-to-disk conversion
+ * method to use'. This really should be removed and all control
+ * over this left in the smb.conf parameters 'client codepage'
+ * and 'coding system'.
+ */
+
+#ifndef KANJI
+
+/*
+ * Set the default conversion to be the functions in
+ * charcnv.c.
+ */
+
+static size_t skip_non_multibyte_char(char);
+static BOOL not_multibyte_char_1(char);
+
+char *(*_dos_to_unix)(char *) = dos2unix_format;
+char *(*_dos_to_unix_static)(const char *) = dos2unix_format_static;
+char *(*_unix_to_dos)(char *) = unix2dos_format;
+char *(*_unix_to_dos_static)(const char *) = unix2dos_format_static;
+size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
+BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
+
+#else /* KANJI */
+
+/*
+ * Set the default conversion to be the function
+ * sj_to_sj in this file.
+ */
+
+static char *sj_to_sj(char *from);
+static char *sj_to_sj_static(const char *from);
+static size_t skip_kanji_multibyte_char(char);
+static BOOL is_kanji_multibyte_char_1(char);
+
+char *(*_dos_to_unix)(char *) = sj_to_sj;
+char *(*_dos_to_unix_static)(const char *) = sj_to_sj_static;
+char *(*_unix_to_dos)(char *) = sj_to_sj;
+char *(*_unix_to_dos_static)(const char *) = sj_to_sj_static;
+size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
+int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
+
+#endif /* KANJI */
+
+BOOL global_is_multibyte_codepage = False;
+
+/* jis si/so sequence */
+static char jis_kso = JIS_KSO;
+static char jis_ksi = JIS_KSI;
+static char hex_tag = HEXTAG;
+
+/*******************************************************************
+ SHIFT JIS functions
+********************************************************************/
+
+/*******************************************************************
+ search token from S1 separated any char of S2
+ S1 contains SHIFT JIS chars.
+********************************************************************/
+
+static char *sj_strtok(char *s1, const char *s2)
+{
+ static char *s = NULL;
+ char *q;
+ if (!s1) {
+ if (!s) {
+ return NULL;
+ }
+ s1 = s;
+ }
+ for (q = s1; *s1; ) {
+ if (is_shift_jis (*s1)) {
+ s1 += 2;
+ } else if (is_kana (*s1)) {
+ s1++;
+ } else {
+ char *p = strchr (s2, *s1);
+ if (p) {
+ if (s1 != q) {
+ s = s1 + 1;
+ *s1 = '\0';
+ return q;
+ }
+ q = s1 + 1;
+ }
+ s1++;
+ }
+ }
+ s = NULL;
+ if (*q) {
+ return q;
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ search string S2 from S1
+ S1 contains SHIFT JIS chars.
+********************************************************************/
+
+static const char *sj_strstr(const char *s1, const char *s2)
+{
+ size_t len = strlen (s2);
+ if (!*s2)
+ return (const char *) s1;
+ for (;*s1;) {
+ if (*s1 == *s2) {
+ if (strncmp (s1, s2, len) == 0)
+ return (const char *) s1;
+ }
+ if (is_shift_jis (*s1)) {
+ s1 += 2;
+ } else {
+ s1++;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search char C from beginning of S.
+ S contains SHIFT JIS chars.
+********************************************************************/
+
+static const char *sj_strchr (const char *s, int c)
+{
+ for (; *s; ) {
+ if (*s == c)
+ return (const char *) s;
+ if (is_shift_jis (*s)) {
+ s += 2;
+ } else {
+ s++;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search char C end of S.
+ S contains SHIFT JIS chars.
+********************************************************************/
+
+static const char *sj_strrchr(const char *s, int c)
+{
+ const char *q;
+
+ for (q = 0; *s; ) {
+ if (*s == c) {
+ q = (const char *) s;
+ }
+ if (is_shift_jis (*s)) {
+ s += 2;
+ } else {
+ s++;
+ }
+ }
+ return q;
+}
+
+/*******************************************************************
+ Kanji multibyte char skip function.
+*******************************************************************/
+
+static size_t skip_kanji_multibyte_char(char c)
+{
+ if(is_shift_jis(c)) {
+ return 2;
+ } else if (is_kana(c)) {
+ return 1;
+ }
+ return 0;
+}
+
+/*******************************************************************
+ Kanji multibyte char identification.
+*******************************************************************/
+
+static BOOL is_kanji_multibyte_char_1(char c)
+{
+ return is_shift_jis(c);
+}
+
+/*******************************************************************
+ The following functions are the only ones needed to do multibyte
+ support for Hangul, Big5 and Simplified Chinese. Most of the
+ real work for these codepages is done in the generic multibyte
+ functions. The only reason these functions are needed at all
+ is that the is_xxx(c) calls are really preprocessor macros.
+********************************************************************/
+
+/*******************************************************************
+ Hangul (Korean - code page 949) function.
+********************************************************************/
+
+static BOOL hangul_is_multibyte_char_1(char c)
+{
+ return is_hangul(c);
+}
+
+/*******************************************************************
+ Big5 Traditional Chinese (code page 950) function.
+********************************************************************/
+
+static BOOL big5_is_multibyte_char_1(char c)
+{
+ return is_big5_c1(c);
+}
+
+/*******************************************************************
+ Simplified Chinese (code page 936) function.
+********************************************************************/
+
+static BOOL simpch_is_multibyte_char_1(char c)
+{
+ return is_simpch_c1(c);
+}
+
+/*******************************************************************
+ Generic multibyte functions - used by Hangul, Big5 and Simplified
+ Chinese codepages.
+********************************************************************/
+
+/*******************************************************************
+ search token from S1 separated any char of S2
+ S1 contains generic multibyte chars.
+********************************************************************/
+
+static char *generic_multibyte_strtok(char *s1, const char *s2)
+{
+ static char *s = NULL;
+ char *q;
+ if (!s1) {
+ if (!s) {
+ return NULL;
+ }
+ s1 = s;
+ }
+ for (q = s1; *s1; ) {
+ if ((*is_multibyte_char_1)(*s1)) {
+ s1 += 2;
+ } else {
+ char *p = strchr (s2, *s1);
+ if (p) {
+ if (s1 != q) {
+ s = s1 + 1;
+ *s1 = '\0';
+ return q;
+ }
+ q = s1 + 1;
+ }
+ s1++;
+ }
+ }
+ s = NULL;
+ if (*q) {
+ return q;
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ search string S2 from S1
+ S1 contains generic multibyte chars.
+********************************************************************/
+
+static const char *generic_multibyte_strstr(const char *s1, const char *s2)
+{
+ size_t len = strlen (s2);
+ if (!*s2)
+ return (const char *) s1;
+ for (;*s1;) {
+ if (*s1 == *s2) {
+ if (strncmp (s1, s2, len) == 0)
+ return (const char *) s1;
+ }
+ if ((*is_multibyte_char_1)(*s1)) {
+ s1 += 2;
+ } else {
+ s1++;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search char C from beginning of S.
+ S contains generic multibyte chars.
+********************************************************************/
+
+static const char *generic_multibyte_strchr(const char *s, int c)
+{
+ for (; *s; ) {
+ if (*s == c)
+ return (const char *) s;
+ if ((*is_multibyte_char_1)(*s)) {
+ s += 2;
+ } else {
+ s++;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search char C end of S.
+ S contains generic multibyte chars.
+********************************************************************/
+
+static const char *generic_multibyte_strrchr(const char *s, int c)
+{
+ const char *q;
+
+ for (q = 0; *s; ) {
+ if (*s == c) {
+ q = (const char *) s;
+ }
+ if ((*is_multibyte_char_1)(*s)) {
+ s += 2;
+ } else {
+ s++;
+ }
+ }
+ return q;
+}
+
+/*******************************************************************
+ Generic multibyte char skip function.
+*******************************************************************/
+
+static size_t skip_generic_multibyte_char(char c)
+{
+ if( (*is_multibyte_char_1)(c)) {
+ return 2;
+ }
+ return 0;
+}
+
+/*******************************************************************
+ Code conversion
+********************************************************************/
+
+/* convesion buffer */
+static char cvtbuf[2*sizeof(pstring)];
+
+/*******************************************************************
+ EUC <-> SJIS
+********************************************************************/
+
+static int euc2sjis (int hi, int lo)
+{
+ int w;
+ int maxidx = SJISREVTBLSIZ;
+ int minidx = 0;
+ int i = 2;
+
+ if (hi & 1) {
+ hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
+ w = (hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61));
+ } else {
+ hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
+ w = (hi << 8) | (lo - 2);
+ }
+ if ( (0x87 < hi ) && (hi < 0xed ) ) {
+ return w;
+ }
+ while ( maxidx >= minidx ) {
+ if ( sjisrev[i].start > w ) {
+ maxidx = i-1;
+ } else if ( w > sjisrev[i].end ) {
+ minidx = i+1;
+ } else {
+ w -= sjisrev[i].start;
+ w += sjisrev[i].rstart;
+ break;
+ }
+ i = (int)( minidx + (maxidx - minidx) % 2 );
+ }
+ return w;
+}
+
+static int sjis2euc (int hi, int lo)
+{
+ int minidx = 0;
+ int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
+ int i = ( 0 + SJISCONVTBLSIZ ) % 2;
+ int w = (int)((hi << 8) | lo);
+
+ if ( (sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end) ) {
+ while (maxidx >= minidx) {
+ if ( sjisconv[i].start > w ) {
+ maxidx = i-1;
+ } else if (w > sjisconv[i].end) {
+ minidx = i+1;
+ } else {
+ w -= sjisconv[i].start;
+ w += sjisconv[i].rstart;
+ break;
+ }
+ i = (int)( minidx + (maxidx-minidx)%2 );
+ }
+ hi = (int) ((w >> 8) & 0xff);
+ lo = (int) (w & 0xff);
+ }
+ if (hi >= 0xf0) {
+ hi = GETAHI;
+ lo = GETALO;
+ }
+ if (lo >= 0x9f)
+ return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
+ else
+ return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
+ (lo + (lo >= 0x7f ? 0x60 : 0x61));
+}
+
+/*******************************************************************
+ Convert FROM contain SHIFT JIS codes to EUC codes
+ return converted buffer
+********************************************************************/
+
+static char *sj_to_euc_static(const char *from)
+{
+ char *out;
+
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ if (is_shift_jis (*from)) {
+ int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code & 0xff;
+ from += 2;
+ } else if (is_kana (*from)) {
+ *out++ = (char)euc_kana;
+ *out++ = *from++;
+ } else {
+ *out++ = *from++;
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *sj_to_euc(char *from)
+{
+ pstrcpy(from, sj_to_euc_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain EUC codes to SHIFT JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *euc_to_sj_static(const char *from)
+{
+ char *out;
+
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
+ if (is_euc (*from)) {
+ int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code & 0xff;
+ from += 2;
+ } else if (is_euc_kana (*from)) {
+ *out++ = from[1];
+ from += 2;
+ } else {
+ *out++ = *from++;
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *euc_to_sj(char *from)
+{
+ pstrcpy(from, euc_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ EUC3 <-> SJIS
+********************************************************************/
+static int sjis3euc (int hi, int lo, int *len)
+{
+ int i,w;
+ int minidx;
+ int maxidx;
+
+ w = (int)((hi << 8) | lo);
+
+ /* no sjis */
+ if ( ( 0x40 >= lo ) && (lo >= 0xfc) && (lo == 0x7f )) {
+ w = (GETAHI << 8) | GETALO;
+
+ /* IBM Extended Kanji */
+ } else if (( w == 0xfa54 )||( w == 0x81ca )) {
+ *len = 2;
+ return (0xa2cc);
+
+ } else if (( w == 0xfa5b )||( w == 0x81e6)) {
+ *len = 2;
+ return (0xa2e8);
+
+ } else if (( 0xfa <= hi ) && ( hi <= 0xfc ) ) {
+ i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
+ if ( i <= EUC3CONVTBLSIZ ){
+ *len = 3;
+ return euc3conv[i];
+ }
+
+/* NEC selected IBM Extend Kanji */
+ /* there are 3 code that is not good for conv */
+ } else if (( 0x8754 <= w ) && ( w <= 0x878a)) {
+ minidx = 0;
+ maxidx = EUC3CONV2TBLSIZ;
+ i = minidx + (maxidx - minidx) % 2;
+ while ( maxidx >= minidx ) {
+ if ( euc3conv2[i].sjis > w ) {
+ maxidx = i-1;
+ } else if ( w > euc3conv2[i].sjis ) {
+ minidx = i+1;
+ } else {
+ *len = 3;
+ return (euc3conv2[i].euc);
+ }
+ i = (int)( minidx + (maxidx - minidx) % 2 );
+ }
+ /* else normal EUC */
+
+ } else if (( w == 0xeef9 ) || ( w == 0x81ca )) {
+ *len = 2;
+ return (0xa2cc);
+
+ } else if (( 0xed <= hi ) && ( hi <= 0xef )) {
+ minidx = 0;
+ maxidx = SJISREVTBLSIZ;
+ i = 10;
+ while ( maxidx >= minidx ) {
+ if ( sjisrev[i].start > w ) {
+ maxidx = i-1;
+ } else if ( w > sjisrev[i].end ) {
+ minidx = i+1;
+ } else {
+ w -= sjisrev[i].start;
+ w += sjisrev[i].rstart;
+ break;
+ }
+ i = (int)( minidx + (maxidx - minidx) % 2 );
+ }
+ if ( w >= 0xfa40 ) {
+ i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
+ if ( i <= EUC3CONVTBLSIZ ){
+ *len = 3;
+ return euc3conv[i];
+ } else {
+ w = (GETAHI << 8) | GETALO;
+ }
+ }
+ /* else normal EUC */
+
+/* UDC half low*/
+/* this area maps to the G2 UDC area: 0xf5a1 -- 0xfefe */
+ } else if ((0xf0 <= hi) && (hi <= 0xf4)) {
+ *len = 2;
+ if (lo >= 0x9f) {
+ return (((hi * 2 - 0xea) << 8) | (lo + 2));
+ } else {
+ return (((hi * 2 - 0xeb) << 8) | (lo + (lo >=0x7f ? 0x60: 0x61 )));
+ }
+
+/* UDC half high*/
+/* this area maps to the G3 UDC area: 0xf8f5a1 -- 0xf8fefe */
+ } else if ((0xf5 <= hi) && (hi <= 0xf9)) {
+ *len = 3;
+ if (lo >= 0x9f) {
+ return (((hi*2 - 0xf4) << 8) | (lo + 2));
+ } else {
+ return (((hi*2 - 0xf5) << 8) | (lo + (lo >= 0x7f ? 0x60: 0x61 )));
+ }
+ /* ....checked all special case */
+ }
+
+ /* These Normal 2 byte EUC */
+ *len = 2;
+ hi = (int) ((w >> 8) & 0xff);
+ lo = (int) (w & 0xff);
+
+ if (hi >= 0xf0) { /* Check range */
+ hi = GETAHI;
+ lo = GETALO;
+ }
+
+ if (lo >= 0x9f)
+ return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
+ else
+ return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
+ (lo + (lo >= 0x7f ? 0x60 : 0x61));
+}
+
+static int euc3sjis (int hi, int lo, BOOL is_3byte)
+{
+ int w;
+
+ w = (int)((hi << 8) | lo);
+ if (is_3byte) {
+ if (( 0xf5 <= hi) && ( hi <= 0xfe)) {
+ /* UDC half high*/
+ /* this area maps to the G3 UDC area */
+ /* 0xf8f5a1 -- 0xf8fefe --> 0xf540 -- 0xf9fc */
+ if (hi & 1) {
+ return (((hi / 2 + 0x7b) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
+ } else {
+ return (((hi / 2 + 0x7a) << 8) | (lo - 2));
+ }
+ } else {
+ /* Using map table */
+ int minidx = 0;
+ int maxidx = EUC3REVTBLSIZ;
+ int i = minidx + (maxidx - minidx) % 2;
+
+ while ( maxidx >= minidx ) {
+ if (euc3rev[i].euc > w) {
+ maxidx = i-1;
+ } else if (euc3rev[i].euc < w) {
+ minidx = i+1;
+ } else {
+ return (euc3rev[i].sjis);
+ }
+ i = (int)( minidx + ( maxidx - minidx ) % 2);
+ }
+ return ((GETAHI << 8 ) | GETALO);
+ }
+ } else { /* is_2byte */
+ if ((0xf5 <= hi) && (hi <= 0xfe)) {
+ /* UDC half low*/
+ /* this area maps to the G2 UDC area */
+ /* 0xf5a1 -- 0xfefe --> 0xf040 -- 0xf4fc */
+ if (hi & 1) {
+ return (((hi / 2 + 0x76) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
+ } else {
+ return (((hi / 2 + 0x75) << 8) | (lo - 2));
+ }
+ } else { /* Normal EUC */
+ if (hi & 1) {
+ hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
+ return ((hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
+ } else {
+ hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
+ return ((hi << 8) | (lo - 2));
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ Convert FROM contain SHIFT JIS codes to EUC codes (with SS2)
+ return converted buffer
+********************************************************************/
+
+static char *sj_to_euc3_static(const char *from)
+{
+ char *out;
+ int len;
+
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4);) {
+ if (is_shift_jis (*from)) {
+ int code = sjis3euc ((int) from[0] & 0xff, (int) from[1] & 0xff, &len);
+ if (len == 3) {
+ *out++ = (char)euc_sup;
+ }
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code & 0xff;
+ from += 2;
+ } else if (is_kana (*from)) {
+ *out++ = (char)euc_kana;
+ *out++ = *from++;
+ } else {
+ *out++ = *from++;
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *sj_to_euc3(char *from)
+{
+ pstrcpy(from, sj_to_euc3_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain EUC codes (with Sup-Kanji) to SHIFT JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *euc3_to_sj_static(const char *from)
+{
+ char *out;
+
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
+ if (is_euc_sup (*from)) {
+ int code = euc3sjis((int) from[1] & 0xff, (int) from[2] & 0xff, True);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code & 0xff;
+ from += 3;
+ } else if (is_euc (*from)) {
+ int code = euc3sjis ((int) from[0] & 0xff, (int) from[1] & 0xff,False);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code & 0xff;
+ from += 2;
+ } else if (is_euc_kana (*from)) {
+ *out++ = from[1];
+ from += 2;
+ } else {
+ *out++ = *from++;
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *euc3_to_sj(char *from)
+{
+ pstrcpy(from, euc3_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ JIS7,JIS8,JUNET <-> SJIS
+********************************************************************/
+
+static int sjis2jis(int hi, int lo)
+{
+ int minidx = 0;
+ int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
+ int i = (0 + SJISCONVTBLSIZ) % 2;
+ int w = (int)((hi << 8) | lo);
+
+ if ((sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end)) {
+ while (maxidx >= minidx) {
+ if (sjisconv[i].start > w) {
+ maxidx = i-1;
+ } else if (w > sjisconv[i].end) {
+ minidx = i+1;
+ } else {
+ w -= sjisconv[i].start;
+ w += sjisconv[i].rstart;
+ break;
+ }
+ i = (int)( minidx + (maxidx-minidx) %2 );
+ }
+ hi = (int) ((w >> 8) & 0xff);
+ lo = (int) (w & 0xff);
+ }
+ if (hi >= 0xf0) {
+ hi = GETAHI;
+ lo = GETALO;
+ }
+ if (lo >= 0x9f)
+ return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
+ else
+ return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
+ (lo - (lo >= 0x7f ? 0x20 : 0x1f));
+}
+
+static int jis2sjis(int hi, int lo)
+{
+ int w;
+ int minidx = 0;
+ int maxidx = SJISREVTBLSIZ;
+ int i = 2;
+
+ if (hi & 1) {
+ hi = hi / 2 + (hi < 0x5f ? 0x71 : 0xb1);
+ w = (hi << 8) | (lo + (lo >= 0x60 ? 0x20 : 0x1f));
+ } else {
+ hi = hi / 2 + (hi < 0x5f ? 0x70 : 0xb0);
+ w = (hi << 8) | (lo + 0x7e);
+ }
+
+ if (( 0x87 < hi ) && ( hi < 0xed )) {
+ return w;
+ }
+ while (maxidx >= minidx) {
+ if (sjisrev[i].start > w) {
+ maxidx = i-1;
+ } else if (w > sjisrev[i].end) {
+ minidx = i+1;
+ } else {
+ w -= sjisrev[i].start;
+ w += sjisrev[i].rstart;
+ break;
+ }
+ i = (int)( minidx + (maxidx-minidx) %2 );
+ }
+ return w;
+}
+
+/*******************************************************************
+ Convert FROM contain JIS codes to SHIFT JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *jis8_to_sj_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ if (is_esc (*from)) {
+ if (is_so1 (from[1]) && is_so2 (from[2])) {
+ shifted = _KJ_KANJI;
+ from += 3;
+ } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+ shifted = _KJ_ROMAN;
+ from += 3;
+ } else { /* sequence error */
+ goto normal;
+ }
+ } else {
+
+normal:
+
+ switch (shifted) {
+ default:
+ case _KJ_ROMAN:
+ *out++ = *from++;
+ break;
+ case _KJ_KANJI:
+ {
+ int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ break;
+ }
+ }
+ }
+ }
+
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *jis8_to_sj(char *from)
+{
+ pstrcpy(from, jis8_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain SHIFT JIS codes to JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *sj_to_jis8_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ if (is_shift_jis (*from)) {
+ int code;
+ switch (shifted) {
+ case _KJ_ROMAN: /* to KANJI */
+ *out++ = jis_esc;
+ *out++ = jis_so1;
+ *out++ = jis_kso;
+ shifted = _KJ_KANJI;
+ break;
+ }
+ code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ } else {
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out++ = *from++;
+ }
+ }
+
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *sj_to_jis8(char *from)
+{
+ pstrcpy(from, sj_to_jis8_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *jis7_to_sj_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ if (is_esc (*from)) {
+ if (is_so1 (from[1]) && is_so2 (from[2])) {
+ shifted = _KJ_KANJI;
+ from += 3;
+ } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+ shifted = _KJ_ROMAN;
+ from += 3;
+ } else { /* sequence error */
+ goto normal;
+ }
+ } else if (is_so (*from)) {
+ shifted = _KJ_KANA; /* to KANA */
+ from++;
+ } else if (is_si (*from)) {
+ shifted = _KJ_ROMAN; /* to ROMAN */
+ from++;
+ } else {
+ normal:
+ switch (shifted) {
+ default:
+ case _KJ_ROMAN:
+ *out++ = *from++;
+ break;
+ case _KJ_KANJI:
+ {
+ int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ }
+ break;
+ case _KJ_KANA:
+ *out++ = ((int) from[0]) + 0x80;
+ break;
+ }
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *jis7_to_sj(char *from)
+{
+ pstrcpy(from, jis7_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *sj_to_jis7_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ if (is_shift_jis (*from)) {
+ int code;
+ switch (shifted) {
+ case _KJ_KANA:
+ *out++ = jis_si; /* to ROMAN and through down */
+ case _KJ_ROMAN: /* to KANJI */
+ *out++ = jis_esc;
+ *out++ = jis_so1;
+ *out++ = jis_kso;
+ shifted = _KJ_KANJI;
+ break;
+ }
+ code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ } else if (is_kana (from[0])) {
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ case _KJ_ROMAN: /* to KANA */
+ *out++ = jis_so;
+ shifted = _KJ_KANA;
+ break;
+ }
+ *out++ = ((int) *from++) - 0x80;
+ } else {
+ switch (shifted) {
+ case _KJ_KANA:
+ *out++ = jis_si; /* to ROMAN */
+ shifted = _KJ_ROMAN;
+ break;
+ case _KJ_KANJI: /* to ROMAN */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out++ = *from++;
+ }
+ }
+ switch (shifted) {
+ case _KJ_KANA:
+ *out++ = jis_si; /* to ROMAN */
+ break;
+ case _KJ_KANJI: /* to ROMAN */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ break;
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *sj_to_jis7(char *from)
+{
+ pstrcpy(from, sj_to_jis7_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
+ return converted buffer
+********************************************************************/
+
+static char *junet_to_sj_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ if (is_esc (*from)) {
+ if (is_so1 (from[1]) && is_so2 (from[2])) {
+ shifted = _KJ_KANJI;
+ from += 3;
+ } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+ shifted = _KJ_ROMAN;
+ from += 3;
+ } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
+ shifted = _KJ_KANA;
+ from += 3;
+ } else { /* sequence error */
+ goto normal;
+ }
+ } else {
+ normal:
+ switch (shifted) {
+ default:
+ case _KJ_ROMAN:
+ *out++ = *from++;
+ break;
+ case _KJ_KANJI:
+ {
+ int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ }
+ break;
+ case _KJ_KANA:
+ *out++ = ((int) from[0]) + 0x80;
+ break;
+ }
+ }
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *junet_to_sj(char *from)
+{
+ pstrcpy(from, junet_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
+ return converted buffer
+********************************************************************/
+
+static char *sj_to_junet_static(const char *from)
+{
+ char *out;
+ int shifted;
+
+ shifted = _KJ_ROMAN;
+ for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ if (is_shift_jis (*from)) {
+ int code;
+ switch (shifted) {
+ case _KJ_KANA:
+ case _KJ_ROMAN: /* to KANJI */
+ *out++ = jis_esc;
+ *out++ = jis_so1;
+ *out++ = jis_so2;
+ shifted = _KJ_KANJI;
+ break;
+ }
+ code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ } else if (is_kana (from[0])) {
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN */
+ case _KJ_ROMAN: /* to KANA */
+ *out++ = jis_esc;
+ *out++ = junet_kana1;
+ *out++ = junet_kana2;
+ shifted = _KJ_KANA;
+ break;
+ }
+ *out++ = ((int) *from++) - 0x80;
+ } else {
+ switch (shifted) {
+ case _KJ_KANA:
+ case _KJ_KANJI: /* to ROMAN */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_si2;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out++ = *from++;
+ }
+ }
+ switch (shifted) {
+ case _KJ_KANA:
+ case _KJ_KANJI: /* to ROMAN */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_si2;
+ break;
+ }
+ *out = 0;
+ return cvtbuf;
+}
+
+static char *sj_to_junet(char *from)
+{
+ pstrcpy(from, sj_to_junet_static(from));
+ return from;
+}
+
+/*******************************************************************
+ HEX <-> SJIS
+********************************************************************/
+/* ":xx" -> a byte */
+
+static char *hex_to_sj_static(const char *from)
+{
+ const char *sp;
+ char *dp;
+
+ sp = from;
+ dp = cvtbuf;
+ while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
+ if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
+ *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
+ sp += 3;
+ } else
+ *dp++ = *sp++;
+ }
+ *dp = '\0';
+ return cvtbuf;
+}
+
+static char *hex_to_sj(char *from)
+{
+ pstrcpy(from, hex_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ kanji/kana -> ":xx"
+********************************************************************/
+
+static char *sj_to_hex_static(const char *from)
+{
+ const unsigned char *sp;
+ unsigned char *dp;
+
+ sp = (const uchar *)from;
+ dp = (unsigned char*) cvtbuf;
+ while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
+ if (is_kana(*sp)) {
+ *dp++ = hex_tag;
+ *dp++ = bin2hex (((*sp)>>4)&0x0f);
+ *dp++ = bin2hex ((*sp)&0x0f);
+ sp++;
+ } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
+ *dp++ = hex_tag;
+ *dp++ = bin2hex (((*sp)>>4)&0x0f);
+ *dp++ = bin2hex ((*sp)&0x0f);
+ sp++;
+ *dp++ = hex_tag;
+ *dp++ = bin2hex (((*sp)>>4)&0x0f);
+ *dp++ = bin2hex ((*sp)&0x0f);
+ sp++;
+ } else
+ *dp++ = *sp++;
+ }
+ *dp = '\0';
+ return cvtbuf;
+}
+
+static char *sj_to_hex(char *from)
+{
+ pstrcpy(from, sj_to_hex_static(from));
+ return from;
+}
+
+/*******************************************************************
+ CAP <-> SJIS
+********************************************************************/
+/* ":xx" CAP -> a byte */
+static char *cap_to_sj_static(const char *from)
+{
+ const char *sp;
+ char *dp;
+
+ sp = (const char *) from;
+ dp = cvtbuf;
+ while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
+ /*
+ * The only change between this and hex_to_sj is here. sj_to_cap only
+ * translates characters greater or equal to 0x80 - make sure that here
+ * we only do the reverse (that's why the strchr is used rather than
+ * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson).
+ */
+ if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit((int)sp[2])) {
+ *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
+ sp += 3;
+ } else
+ *dp++ = *sp++;
+ }
+ *dp = '\0';
+ return cvtbuf;
+}
+
+static char *cap_to_sj(char *from)
+{
+ pstrcpy(from, cap_to_sj_static(from));
+ return from;
+}
+
+/*******************************************************************
+ kanji/kana -> ":xx" - CAP format.
+********************************************************************/
+static char *sj_to_cap_static(const char *from)
+{
+ const unsigned char *sp;
+ unsigned char *dp;
+
+ sp = (const uchar *)from;
+ dp = (unsigned char*) cvtbuf;
+ while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
+ if (*sp >= 0x80) {
+ *dp++ = hex_tag;
+ *dp++ = bin2hex (((*sp)>>4)&0x0f);
+ *dp++ = bin2hex ((*sp)&0x0f);
+ sp++;
+ } else {
+ *dp++ = *sp++;
+ }
+ }
+ *dp = '\0';
+ return cvtbuf;
+}
+
+static char *sj_to_cap(char *from)
+{
+ pstrcpy(from, sj_to_cap_static(from));
+ return from;
+}
+
+/*******************************************************************
+ sj to sj
+********************************************************************/
+
+static char *sj_to_sj_static(const char *from)
+{
+ pstrcpy (cvtbuf, from);
+ return cvtbuf;
+}
+
+static char *sj_to_sj(char *from)
+{
+ return from;
+}
+
+/*******************************************************************
+ cp to utf8
+********************************************************************/
+static char *cp_to_utf8_static(const char *from)
+{
+ unsigned char *dst;
+ const unsigned char *src;
+ smb_ucs2_t val;
+ int w;
+ size_t len;
+
+ src = (const unsigned char *)from;
+ dst = (unsigned char *)cvtbuf;
+ while (*src && (((char *)dst - cvtbuf) < sizeof(cvtbuf)-4)) {
+ len = _skip_multibyte_char(*src);
+ if ( len == 2 ) {
+ w = (int)(*src++ & 0xff);
+ w = (int)((w << 8)|(*src++ & 0xff));
+ } else {
+ w = (int)(*src++ & 0xff);
+ }
+ val = doscp2ucs2(w);
+
+ if ( val <= 0x7f ) {
+ *dst++ = (char)(val & 0xff);
+ } else if ( val <= 0x7ff ){
+ *dst++ = (char)( 0xc0 | ((val >> 6) & 0xff));
+ *dst++ = (char)( 0x80 | ( val & 0x3f ));
+ } else {
+ *dst++ = (char)( 0xe0 | ((val >> 12) & 0x0f));
+ *dst++ = (char)( 0x80 | ((val >> 6) & 0x3f));
+ *dst++ = (char)( 0x80 | (val & 0x3f));
+ }
+
+ }
+ *dst++='\0';
+ return cvtbuf;
+}
+
+static char *cp_to_utf8(char *from)
+{
+ pstrcpy(from, cp_to_utf8_static(from));
+ return from;
+}
+
+/*******************************************************************
+ utf8 to cp
+********************************************************************/
+static char *utf8_to_cp_static(const char *from)
+{
+ const unsigned char *src;
+ unsigned char *dst;
+ smb_ucs2_t val;
+ int w;
+
+ src = (const unsigned char *)from;
+ dst = (unsigned char *)cvtbuf;
+
+ while (*src && ((char *)dst - cvtbuf < sizeof(cvtbuf)-4)) {
+ val = (*src++ & 0xff);
+ if (val < 0x80) {
+ *dst++ = (char)(val & 0x7f);
+ } else if ((0xc0 <= val) && (val <= 0xdf)
+ && (0x80 <= *src) && (*src <= 0xbf)) {
+ w = ucs2doscp( ((val & 31) << 6) | ((*src++) & 63 ));
+ *dst++ = (char)((w >> 8) & 0xff);
+ *dst++ = (char)(w & 0xff);
+ } else {
+ val = (val & 0x0f) << 12;
+ val |= ((*src++ & 0x3f) << 6);
+ val |= (*src++ & 0x3f);
+ w = ucs2doscp(val);
+ *dst++ = (char)((w >> 8) & 0xff);
+ *dst++ = (char)(w & 0xff);
+ }
+ }
+ *dst++='\0';
+ return cvtbuf;
+}
+
+static char *utf8_to_cp(char *from)
+{
+ pstrcpy(from, utf8_to_cp_static(from));
+ return from;
+}
+
+/************************************************************************
+ conversion:
+ _dos_to_unix _unix_to_dos
+************************************************************************/
+
+static void setup_string_function(int codes)
+{
+ switch (codes) {
+ default:
+ _dos_to_unix = dos2unix_format;
+ _dos_to_unix_static = dos2unix_format_static;
+ _unix_to_dos = unix2dos_format;
+ _unix_to_dos_static = unix2dos_format_static;
+ break;
+
+ case SJIS_CODE:
+ _dos_to_unix = sj_to_sj;
+ _dos_to_unix_static = sj_to_sj_static;
+ _unix_to_dos = sj_to_sj;
+ _unix_to_dos_static = sj_to_sj_static;
+ break;
+
+ case EUC_CODE:
+ _dos_to_unix = sj_to_euc;
+ _dos_to_unix_static = sj_to_euc_static;
+ _unix_to_dos = euc_to_sj;
+ _unix_to_dos_static = euc_to_sj_static;
+ break;
+
+ case JIS7_CODE:
+ _dos_to_unix = sj_to_jis7;
+ _dos_to_unix_static = sj_to_jis7_static;
+ _unix_to_dos = jis7_to_sj;
+ _unix_to_dos_static = jis7_to_sj_static;
+ break;
+
+ case JIS8_CODE:
+ _dos_to_unix = sj_to_jis8;
+ _dos_to_unix_static = sj_to_jis8_static;
+ _unix_to_dos = jis8_to_sj;
+ _unix_to_dos_static = jis8_to_sj_static;
+ break;
+
+ case JUNET_CODE:
+ _dos_to_unix = sj_to_junet;
+ _dos_to_unix_static = sj_to_junet_static;
+ _unix_to_dos = junet_to_sj;
+ _unix_to_dos_static = junet_to_sj_static;
+ break;
+
+ case HEX_CODE:
+ _dos_to_unix = sj_to_hex;
+ _dos_to_unix_static = sj_to_hex_static;
+ _unix_to_dos = hex_to_sj;
+ _unix_to_dos_static = hex_to_sj_static;
+ break;
+
+ case CAP_CODE:
+ _dos_to_unix = sj_to_cap;
+ _dos_to_unix_static = sj_to_cap_static;
+ _unix_to_dos = cap_to_sj;
+ _unix_to_dos_static = cap_to_sj_static;
+ break;
+
+ case UTF8_CODE:
+ _dos_to_unix = cp_to_utf8;
+ _dos_to_unix_static = cp_to_utf8_static;
+ _unix_to_dos = utf8_to_cp;
+ _unix_to_dos_static = utf8_to_cp_static;
+ break;
+
+ case EUC3_CODE:
+ _dos_to_unix = sj_to_euc3;
+ _dos_to_unix_static = sj_to_euc3_static;
+ _unix_to_dos = euc3_to_sj;
+ _unix_to_dos_static = euc3_to_sj_static;
+ break;
+ }
+}
+
+/************************************************************************
+ Interpret coding system.
+************************************************************************/
+
+void interpret_coding_system(const char *str)
+{
+ int codes = UNKNOWN_CODE;
+
+ if (strequal (str, "sjis")) {
+ codes = SJIS_CODE;
+ } else if (strequal (str, "euc")) {
+ codes = EUC_CODE;
+ } else if (strequal (str, "cap")) {
+ codes = CAP_CODE;
+ hex_tag = HEXTAG;
+ } else if (strequal (str, "hex")) {
+ codes = HEX_CODE;
+ hex_tag = HEXTAG;
+ } else if (!strncasecmp (str, "hex", 3)) {
+ codes = HEX_CODE;
+ hex_tag = (str[3] ? str[3] : HEXTAG);
+ } else if (strequal (str, "j8bb")) {
+ codes = JIS8_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'B';
+ } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
+ codes = JIS8_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'J';
+ } else if (strequal (str, "j8bh")) {
+ codes = JIS8_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'H';
+ } else if (strequal (str, "j8@b")) {
+ codes = JIS8_CODE;
+ jis_kso = '@';
+ jis_ksi = 'B';
+ } else if (strequal (str, "j8@j")) {
+ codes = JIS8_CODE;
+ jis_kso = '@';
+ jis_ksi = 'J';
+ } else if (strequal (str, "j8@h")) {
+ codes = JIS8_CODE;
+ jis_kso = '@';
+ jis_ksi = 'H';
+ } else if (strequal (str, "j7bb")) {
+ codes = JIS7_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'B';
+ } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
+ codes = JIS7_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'J';
+ } else if (strequal (str, "j7bh")) {
+ codes = JIS7_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'H';
+ } else if (strequal (str, "j7@b")) {
+ codes = JIS7_CODE;
+ jis_kso = '@';
+ jis_ksi = 'B';
+ } else if (strequal (str, "j7@j")) {
+ codes = JIS7_CODE;
+ jis_kso = '@';
+ jis_ksi = 'J';
+ } else if (strequal (str, "j7@h")) {
+ codes = JIS7_CODE;
+ jis_kso = '@';
+ jis_ksi = 'H';
+ } else if (strequal (str, "jubb")) {
+ codes = JUNET_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'B';
+ } else if (strequal (str, "jubj") || strequal (str, "junet")) {
+ codes = JUNET_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'J';
+ } else if (strequal (str, "jubh")) {
+ codes = JUNET_CODE;
+ jis_kso = 'B';
+ jis_ksi = 'H';
+ } else if (strequal (str, "ju@b")) {
+ codes = JUNET_CODE;
+ jis_kso = '@';
+ jis_ksi = 'B';
+ } else if (strequal (str, "ju@j")) {
+ codes = JUNET_CODE;
+ jis_kso = '@';
+ jis_ksi = 'J';
+ } else if (strequal (str, "ju@h")) {
+ codes = JUNET_CODE;
+ jis_kso = '@';
+ jis_ksi = 'H';
+ } else if (strequal (str, "utf8")) {
+ codes = UTF8_CODE;
+ } else if (strequal (str, "euc3")) {
+ codes = EUC3_CODE;
+ }
+ setup_string_function (codes);
+}
+
+/*******************************************************************
+ Non multibyte char function.
+*******************************************************************/
+
+static size_t skip_non_multibyte_char(char c)
+{
+ return 0;
+}
+
+/*******************************************************************
+ Function that always says a character isn't multibyte.
+*******************************************************************/
+
+static BOOL not_multibyte_char_1(char c)
+{
+ return False;
+}
+
+/*******************************************************************
+ Setup the function pointers for the functions that are replaced
+ when multi-byte codepages are used.
+
+ The dos_to_unix and unix_to_dos function pointers are only
+ replaced by setup_string_function called by interpret_coding_system
+ above.
+*******************************************************************/
+
+void initialize_multibyte_vectors( int client_codepage)
+{
+ switch( client_codepage )
+ {
+ case KANJI_CODEPAGE:
+ multibyte_strchr = sj_strchr;
+ multibyte_strrchr = sj_strrchr;
+ multibyte_strstr = sj_strstr;
+ multibyte_strtok = sj_strtok;
+ _skip_multibyte_char = skip_kanji_multibyte_char;
+ is_multibyte_char_1 = is_kanji_multibyte_char_1;
+ global_is_multibyte_codepage = True;
+ break;
+ case HANGUL_CODEPAGE:
+ multibyte_strchr = generic_multibyte_strchr;
+ multibyte_strrchr = generic_multibyte_strrchr;
+ multibyte_strstr = generic_multibyte_strstr;
+ multibyte_strtok = generic_multibyte_strtok;
+ _skip_multibyte_char = skip_generic_multibyte_char;
+ is_multibyte_char_1 = hangul_is_multibyte_char_1;
+ global_is_multibyte_codepage = True;
+ break;
+ case BIG5_CODEPAGE:
+ multibyte_strchr = generic_multibyte_strchr;
+ multibyte_strrchr = generic_multibyte_strrchr;
+ multibyte_strstr = generic_multibyte_strstr;
+ multibyte_strtok = generic_multibyte_strtok;
+ _skip_multibyte_char = skip_generic_multibyte_char;
+ is_multibyte_char_1 = big5_is_multibyte_char_1;
+ global_is_multibyte_codepage = True;
+ break;
+ case SIMPLIFIED_CHINESE_CODEPAGE:
+ multibyte_strchr = generic_multibyte_strchr;
+ multibyte_strrchr = generic_multibyte_strrchr;
+ multibyte_strstr = generic_multibyte_strstr;
+ multibyte_strtok = generic_multibyte_strtok;
+ _skip_multibyte_char = skip_generic_multibyte_char;
+ is_multibyte_char_1 = simpch_is_multibyte_char_1;
+ global_is_multibyte_codepage = True;
+ break;
+ /*
+ * Single char size code page.
+ */
+ default:
+ multibyte_strchr = (const char *(*)(const char *, int )) strchr;
+ multibyte_strrchr = (const char *(*)(const char *, int )) strrchr;
+ multibyte_strstr = (const char *(*)(const char *, const char *)) strstr;
+ multibyte_strtok = (char *(*)(char *, const char *)) strtok;
+ _skip_multibyte_char = skip_non_multibyte_char;
+ is_multibyte_char_1 = not_multibyte_char_1;
+ global_is_multibyte_codepage = False;
+ break;
+ }
+}
+/* *******************************************************
+ function(s) for "dynamic" encoding of SWAT output.
+ in this version, only dos_to_dos, dos_to_unix, unix_to_dos
+ are used for bug fix. conversion to web encoding
+ (to catalog file encoding) is not needed because
+ they are using same character codes.
+ **************************************************** */
+static char *no_conversion_static(const char *str)
+{
+ static pstring temp;
+ pstrcpy(temp, str);
+ return temp;
+}
+char *(*_dos_to_dos_static)(const char *) = no_conversion_static;
diff --git a/source/lib/ldap_escape.c b/source/lib/ldap_escape.c
deleted file mode 100644
index 9e88b4999cc..00000000000
--- a/source/lib/ldap_escape.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ldap filter argument escaping
-
- Copyright (C) 1998, 1999, 2000 Luke Howard <lukeh@padl.com>,
- Copyright (C) 2003 Andrew Bartlett <abartlet@samba.org>
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * Escape a parameter to an LDAP filter string, so they cannot contain
- * embeded ( ) * or \ chars which may cause it not to parse correctly.
- *
- * @param s The input string
- *
- * @return A string allocated with malloc(), containing the escaped string,
- * and to be free()ed by the caller.
- **/
-
-char *escape_ldap_string_alloc(const char *s)
-{
- size_t len = strlen(s)+1;
- char *output = malloc(len);
- char *output_tmp;
- const char *sub;
- int i = 0;
- char *p = output;
-
- while (*s)
- {
- switch (*s)
- {
- case '*':
- sub = "\\2a";
- break;
- case '(':
- sub = "\\28";
- break;
- case ')':
- sub = "\\29";
- break;
- case '\\':
- sub = "\\5c";
- break;
- default:
- sub = NULL;
- break;
- }
-
- if (sub) {
- len = len + 3;
- output_tmp = realloc(output, len);
- if (!output_tmp) {
- SAFE_FREE(output);
- return NULL;
- }
- output = output_tmp;
-
- p = &output[i];
- strncpy (p, sub, 3);
- p += 3;
- i += 3;
-
- } else {
- *p = *s;
- p++;
- i++;
- }
- s++;
- }
-
- *p = '\0';
- return output;
-}
diff --git a/source/lib/md4.c b/source/lib/md4.c
index 6803b7e8831..30f2b6b8c6b 100644
--- a/source/lib/md4.c
+++ b/source/lib/md4.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
@@ -100,7 +101,7 @@ static void mdfour64(uint32 *M)
X[j] = 0;
}
-static void copy64(uint32 *M, const unsigned char *in)
+static void copy64(uint32 *M, unsigned char *in)
{
int i;
@@ -109,7 +110,7 @@ static void copy64(uint32 *M, const unsigned char *in)
(in[i*4+1]<<8) | (in[i*4+0]<<0);
}
-static void copy4(unsigned char *out, uint32 x)
+static void copy4(unsigned char *out,uint32 x)
{
out[0] = x&0xFF;
out[1] = (x>>8)&0xFF;
@@ -118,7 +119,7 @@ static void copy4(unsigned char *out, uint32 x)
}
/* produce a md4 message digest from data of length n bytes */
-void mdfour(unsigned char *out, const unsigned char *in, int n)
+void mdfour(unsigned char *out, unsigned char *in, int n)
{
unsigned char buf[128];
uint32 M[16];
diff --git a/source/lib/md5.c b/source/lib/md5.c
deleted file mode 100644
index 2121b170479..00000000000
--- a/source/lib/md5.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-/* This code slightly modified to fit into Samba by
- abartlet@samba.org Jun 2001 */
-
-#include "includes.h"
-
-#include "md5.h"
-
-static void MD5Transform(uint32 buf[4], uint32 const in[16]);
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void byteReverse(unsigned char *buf, unsigned longs)
-{
- uint32 t;
- do {
- t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(uint32 *) buf = t;
- buf += 4;
- } while (--longs);
-}
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(struct MD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
- register uint32 t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memmove(p, buf, len);
- return;
- }
- memmove(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
- buf += t;
- len -= t;
- }
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memmove(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memmove(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
- unsigned int count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((uint32 *) ctx->in)[14] = ctx->bits[0];
- ((uint32 *) ctx->in)[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memmove(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void MD5Transform(uint32 buf[4], uint32 const in[16])
-{
- register uint32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
diff --git a/source/lib/messages.c b/source/lib/messages.c
index 8706ede7065..ac6e61473a9 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -3,7 +3,6 @@
Samba internal messaging functions
Copyright (C) Andrew Tridgell 2000
Copyright (C) 2001 by Martin Pool
- Copyright (C) 2002 by Jeremy Allison
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,11 +20,11 @@
*/
/**
- @defgroup messages Internal messaging framework
- @{
- @file messages.c
-
- @brief Module for internal messaging between Samba daemons.
+ @defgroups messages Internal messaging framework
+ @{
+ @file messages.c
+
+ This module is used for internal messaging between Samba daemons.
The idea is that if a part of Samba wants to do communication with
another Samba process then it will do a message_register() of a
@@ -36,9 +35,6 @@
use that to reply by message_send_pid(). See ping_message() for a
simple example.
- @caution Dispatch functions must be able to cope with incoming
- messages on an *odd* byte boundary.
-
This system doesn't have any inherent size limitations but is not
very efficient for large messages or when messages are sent in very
quick succession.
@@ -83,7 +79,7 @@ static void sig_usr1(void)
A useful function for testing the message system.
****************************************************************************/
-static void ping_message(int msg_type, pid_t src, void *buf, size_t len)
+void ping_message(int msg_type, pid_t src, void *buf, size_t len)
{
const char *msg = buf ? buf : "none";
DEBUG(1,("INFO: Received PING message from PID %u [%s]\n",(unsigned int)src, msg));
@@ -91,6 +87,16 @@ static void ping_message(int msg_type, pid_t src, void *buf, size_t len)
}
/****************************************************************************
+ Return current debug level.
+****************************************************************************/
+
+void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
+{
+ DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
+ message_send_pid(src, MSG_DEBUGLEVEL, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS), True);
+}
+
+/****************************************************************************
Initialise the messaging functions.
****************************************************************************/
@@ -110,11 +116,7 @@ BOOL message_init(void)
CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1);
message_register(MSG_PING, ping_message);
-
- /* Register some debugging related messages */
-
- register_msg_pool_usage();
- register_dmalloc_msgs();
+ message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message);
return True;
}
@@ -142,13 +144,6 @@ static TDB_DATA message_key_pid(pid_t pid)
static BOOL message_notify(pid_t pid)
{
- /*
- * Doing kill with a non-positive pid causes messages to be
- * sent to places we don't want.
- */
-
- SMB_ASSERT(pid > 0);
-
if (kill(pid, SIGUSR1) == -1) {
if (errno == ESRCH) {
DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
@@ -165,22 +160,13 @@ static BOOL message_notify(pid_t pid)
Send a message to a particular pid.
****************************************************************************/
-static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
- BOOL duplicates_allowed, unsigned int timeout)
+BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
+ BOOL duplicates_allowed)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
- TDB_DATA old_dbuf;
struct message_rec rec;
- char *ptr;
- struct message_rec prec;
-
- /*
- * Doing kill with a non-positive pid causes messages to be
- * sent to places we don't want.
- */
-
- SMB_ASSERT(pid > 0);
+ void *p;
rec.msg_version = MESSAGE_VERSION;
rec.msg_type = msg_type;
@@ -190,277 +176,173 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
kbuf = message_key_pid(pid);
- dbuf.dptr = (void *)malloc(len + sizeof(rec));
- if (!dbuf.dptr)
- return False;
-
- memcpy(dbuf.dptr, &rec, sizeof(rec));
- if (len > 0)
- memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);
-
- dbuf.dsize = len + sizeof(rec);
-
- if (duplicates_allowed) {
-
- /* If duplicates are allowed we can just append the message and return. */
-
- /* lock the record for the destination */
- if (timeout) {
- if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
- DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
- return False;
- }
- } else {
- if (tdb_chainlock(tdb, kbuf) == -1) {
- DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
- return False;
- }
- }
- tdb_append(tdb, kbuf, dbuf);
- tdb_chainunlock(tdb, kbuf);
-
- SAFE_FREE(dbuf.dptr);
- errno = 0; /* paranoia */
- return message_notify(pid);
- }
-
/* lock the record for the destination */
- if (timeout) {
- if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
- DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
- return False;
- }
- } else {
- if (tdb_chainlock(tdb, kbuf) == -1) {
- DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
- return False;
- }
- }
+ tdb_chainlock(tdb, kbuf);
- old_dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb, kbuf);
- if (!old_dbuf.dptr) {
+ if (!dbuf.dptr) {
/* its a new record */
+ p = (void *)malloc(len + sizeof(rec));
+ if (!p) goto failed;
- tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- tdb_chainunlock(tdb, kbuf);
+ memcpy(p, &rec, sizeof(rec));
+ if (len > 0) memcpy((void *)((char*)p+sizeof(rec)), buf, len);
- SAFE_FREE(dbuf.dptr);
- errno = 0; /* paranoia */
- return message_notify(pid);
+ dbuf.dptr = p;
+ dbuf.dsize = len + sizeof(rec);
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ SAFE_FREE(p);
+ goto ok;
}
- /* Not a new record. Check for duplicates. */
-
- for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) {
- /*
- * First check if the message header matches, then, if it's a non-zero
- * sized message, check if the data matches. If so it's a duplicate and
- * we can discard it. JRA.
- */
-
- if (!memcmp(ptr, &rec, sizeof(rec))) {
- if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
- tdb_chainunlock(tdb, kbuf);
- DEBUG(10,("message_send_pid_internal: discarding duplicate message.\n"));
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(old_dbuf.dptr);
- return True;
+ if (!duplicates_allowed) {
+ char *ptr;
+ struct message_rec prec;
+
+ for(ptr = (char *)dbuf.dptr; ptr < dbuf.dptr + dbuf.dsize; ) {
+ /*
+ * First check if the message header matches, then, if it's a non-zero
+ * sized message, check if the data matches. If so it's a duplicate and
+ * we can discard it. JRA.
+ */
+
+ if (!memcmp(ptr, &rec, sizeof(rec))) {
+ if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
+ DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
+ SAFE_FREE(dbuf.dptr);
+ tdb_chainunlock(tdb, kbuf);
+ return True;
+ }
}
+ memcpy(&prec, ptr, sizeof(prec));
+ ptr += sizeof(rec) + prec.len;
}
- memcpy(&prec, ptr, sizeof(prec));
- ptr += sizeof(rec) + prec.len;
}
/* we're adding to an existing entry */
+ p = (void *)malloc(dbuf.dsize + len + sizeof(rec));
+ if (!p) goto failed;
- tdb_append(tdb, kbuf, dbuf);
- tdb_chainunlock(tdb, kbuf);
+ memcpy(p, dbuf.dptr, dbuf.dsize);
+ memcpy((void *)((char*)p+dbuf.dsize), &rec, sizeof(rec));
+ if (len > 0) memcpy((void *)((char*)p+dbuf.dsize+sizeof(rec)), buf, len);
- SAFE_FREE(old_dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
+ dbuf.dptr = p;
+ dbuf.dsize += len + sizeof(rec);
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
SAFE_FREE(dbuf.dptr);
+ ok:
+ tdb_chainunlock(tdb, kbuf);
errno = 0; /* paranoia */
return message_notify(pid);
-}
-
-/****************************************************************************
- Send a message to a particular pid - no timeout.
-****************************************************************************/
-
-BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
-{
- return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);
-}
-
-/****************************************************************************
- Send a message to a particular pid, with timeout in seconds.
-****************************************************************************/
-
-BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, size_t len,
- BOOL duplicates_allowed, unsigned int timeout)
-{
- return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout);
-}
-
-/****************************************************************************
- Count the messages pending for a particular pid. Expensive....
-****************************************************************************/
-
-unsigned int messages_pending_for_pid(pid_t pid)
-{
- TDB_DATA kbuf;
- TDB_DATA dbuf;
- char *buf;
- unsigned int message_count = 0;
-
- kbuf = message_key_pid(sys_getpid());
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (dbuf.dptr == NULL || dbuf.dsize == 0) {
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
- for (buf = dbuf.dptr; dbuf.dsize > sizeof(struct message_rec);) {
- struct message_rec rec;
- memcpy(&rec, buf, sizeof(rec));
- buf += (sizeof(rec) + rec.len);
- dbuf.dsize -= (sizeof(rec) + rec.len);
- message_count++;
- }
-
- SAFE_FREE(dbuf.dptr);
- return message_count;
+ failed:
+ tdb_chainunlock(tdb, kbuf);
+ errno = 0; /* paranoia */
+ return False;
}
/****************************************************************************
- Retrieve all messages for the current process.
+ Retrieve the next message for the current process.
****************************************************************************/
-static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
+static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
- TDB_DATA null_dbuf;
-
- ZERO_STRUCT(null_dbuf);
-
- *msgs_buf = NULL;
- *total_len = 0;
+ struct message_rec rec;
kbuf = message_key_pid(sys_getpid());
- if (tdb_chainlock(tdb, kbuf) == -1)
- return False;
-
+ tdb_chainlock(tdb, kbuf);
+
dbuf = tdb_fetch(tdb, kbuf);
- /*
- * Replace with an empty record to keep the allocated
- * space in the tdb.
- */
- tdb_store(tdb, kbuf, null_dbuf, TDB_REPLACE);
- tdb_chainunlock(tdb, kbuf);
-
- if (dbuf.dptr == NULL || dbuf.dsize == 0) {
- SAFE_FREE(dbuf.dptr);
- return False;
- }
-
- *msgs_buf = dbuf.dptr;
- *total_len = dbuf.dsize;
-
- return True;
-}
-
-/****************************************************************************
- Parse out the next message for the current process.
-****************************************************************************/
-
-static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t *src, char **buf, size_t *len)
-{
- struct message_rec rec;
- char *ret_buf = *buf;
-
- *buf = NULL;
- *len = 0;
-
- if (total_len - (ret_buf - msgs_buf) < sizeof(rec))
- return False;
+ if (dbuf.dptr == NULL || dbuf.dsize == 0) goto failed;
- memcpy(&rec, ret_buf, sizeof(rec));
- ret_buf += sizeof(rec);
+ memcpy(&rec, dbuf.dptr, sizeof(rec));
if (rec.msg_version != MESSAGE_VERSION) {
DEBUG(0,("message version %d received (expected %d)\n", rec.msg_version, MESSAGE_VERSION));
- return False;
+ goto failed;
}
if (rec.len > 0) {
- if (total_len - (ret_buf - msgs_buf) < rec.len)
- return False;
+ (*buf) = (void *)malloc(rec.len);
+ if (!(*buf)) goto failed;
+
+ memcpy(*buf, dbuf.dptr+sizeof(rec), rec.len);
+ } else {
+ *buf = NULL;
}
*len = rec.len;
*msg_type = rec.msg_type;
*src = rec.src;
- *buf = ret_buf;
+ if (dbuf.dsize - (sizeof(rec)+rec.len) > 0)
+ memmove(dbuf.dptr, dbuf.dptr+sizeof(rec)+rec.len, dbuf.dsize - (sizeof(rec)+rec.len));
+ dbuf.dsize -= sizeof(rec)+rec.len;
+
+ if (dbuf.dsize == 0)
+ tdb_delete(tdb, kbuf);
+ else
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+
+ SAFE_FREE(dbuf.dptr);
+ tdb_chainunlock(tdb, kbuf);
return True;
+
+ failed:
+ tdb_chainunlock(tdb, kbuf);
+ return False;
}
/****************************************************************************
Receive and dispatch any messages pending for this process.
Notice that all dispatch handlers for a particular msg_type get called,
so you can register multiple handlers for a message.
- *NOTE*: Dispatch functions must be able to cope with incoming
- messages on an *odd* byte boundary.
****************************************************************************/
void message_dispatch(void)
{
int msg_type;
pid_t src;
- char *buf;
- char *msgs_buf;
- size_t len, total_len;
+ void *buf;
+ size_t len;
struct dispatch_fns *dfn;
int n_handled;
- if (!received_signal)
- return;
+ if (!received_signal) return;
DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));
received_signal = 0;
- if (!retrieve_all_messages(&msgs_buf, &total_len))
- return;
-
- for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
+ while (message_recv(&msg_type, &src, &buf, &len)) {
DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%u\n",
msg_type, (unsigned int) src));
n_handled = 0;
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
- dfn->fn(msg_type, src, len ? (void *)buf : NULL, len);
+ dfn->fn(msg_type, src, buf, len);
n_handled++;
}
}
if (!n_handled) {
DEBUG(5,("message_dispatch: warning: no handlers registed for "
- "msg_type %d in pid %u\n",
- msg_type, (unsigned int)sys_getpid()));
+ "msg_type %d in pid%u\n",
+ msg_type, (unsigned int)getpid()));
}
+ SAFE_FREE(buf);
}
- SAFE_FREE(msgs_buf);
}
/****************************************************************************
Register a dispatch function for a particular message type.
- *NOTE*: Dispatch functions must be able to cope with incoming
- messages on an *odd* byte boundary.
****************************************************************************/
void message_register(int msg_type,
@@ -504,11 +386,10 @@ void message_deregister(int msg_type)
struct msg_all {
int msg_type;
- uint32 msg_flag;
const void *buf;
size_t len;
BOOL duplicates;
- int n_sent;
+ int n_sent;
};
/****************************************************************************
@@ -528,20 +409,13 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
if (crec.cnum != -1)
return 0;
- /* Don't send if the receiver hasn't registered an interest. */
-
- if(!(crec.bcast_msg_flags & msg_all->msg_flag))
- return 0;
-
- /* If the msg send fails because the pid was not found (i.e. smbd died),
+ /* if the msg send fails because the pid was not found (i.e. smbd died),
* the msg has already been deleted from the messages.tdb.*/
-
if (!message_send_pid(crec.pid, msg_all->msg_type,
msg_all->buf, msg_all->len,
msg_all->duplicates)) {
- /* If the pid was not found delete the entry from connections.tdb */
-
+ /* if the pid was not found delete the entry from connections.tdb */
if (errno == ESRCH) {
DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
(unsigned int)crec.pid, crec.cnum, crec.name));
@@ -562,7 +436,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
* @param n_sent Set to the number of messages sent. This should be
* equal to the number of processes, but be careful for races.
*
- * @retval True for success.
+ * @return True for success.
**/
BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
const void *buf, size_t len,
@@ -572,17 +446,6 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
struct msg_all msg_all;
msg_all.msg_type = msg_type;
- if (msg_type < 1000)
- msg_all.msg_flag = FLAG_MSG_GENERAL;
- else if (msg_type > 1000 && msg_type < 2000)
- msg_all.msg_flag = FLAG_MSG_NMBD;
- else if (msg_type > 2000 && msg_type < 3000)
- msg_all.msg_flag = FLAG_MSG_PRINTING;
- else if (msg_type > 3000 && msg_type < 4000)
- msg_all.msg_flag = FLAG_MSG_SMBD;
- else
- return False;
-
msg_all.buf = buf;
msg_all.len = len;
msg_all.duplicates = duplicates_allowed;
@@ -593,4 +456,3 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
*n_sent = msg_all.n_sent;
return True;
}
-/** @} **/
diff --git a/source/lib/module.c b/source/lib/module.c
deleted file mode 100644
index 2abe918ef44..00000000000
--- a/source/lib/module.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- module loading system
-
- Copyright (C) Jelmer Vernooij 2002-2003
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_DLOPEN
-
-/* Load a dynamic module. Only log a level 0 error if we are not checking
- for the existence of a module (probling). */
-
-static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe)
-{
- void *handle;
- init_module_function *init;
- NTSTATUS status;
- const char *error;
-
- /* Always try to use LAZY symbol resolving; if the plugin has
- * backwards compatibility, there might be symbols in the
- * plugin referencing to old (removed) functions
- */
- handle = sys_dlopen(module_name, RTLD_LAZY);
-
- if(!handle) {
- int level = is_probe ? 3 : 0;
- error = sys_dlerror();
- DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : ""));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- init = (init_module_function *)sys_dlsym(handle, "init_module");
-
- /* we must check sys_dlerror() to determine if it worked, because
- sys_dlsym() can validly return NULL */
- error = sys_dlerror();
- if (error) {
- DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n",
- module_name, error));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- status = init();
-
- DEBUG(2, ("Module '%s' loaded\n", module_name));
-
- return status;
-}
-
-NTSTATUS smb_load_module(const char *module_name)
-{
- return do_smb_load_module(module_name, False);
-}
-
-/* Load all modules in list and return number of
- * modules that has been successfully loaded */
-int smb_load_modules(const char **modules)
-{
- int i;
- int success = 0;
-
- for(i = 0; modules[i]; i++){
- if(NT_STATUS_IS_OK(smb_load_module(modules[i]))) {
- success++;
- }
- }
-
- DEBUG(2, ("%d modules successfully loaded\n", success));
-
- return success;
-}
-
-NTSTATUS smb_probe_module(const char *subsystem, const char *module)
-{
- pstring full_path;
-
- /* Check for absolute path */
-
- /* if we make any 'samba multibyte string'
- calls here, we break
- for loading string modules */
-
- DEBUG(5, ("Probing module '%s'\n", module));
-
- if (module[0] == '/')
- return do_smb_load_module(module, True);
-
- pstrcpy(full_path, lib_path(subsystem));
- pstrcat(full_path, "/");
- pstrcat(full_path, module);
- pstrcat(full_path, ".");
- pstrcat(full_path, shlib_ext());
-
- DEBUG(5, ("Probing module '%s': Trying to load from %s\n", module, full_path));
-
- return do_smb_load_module(full_path, True);
-}
-
-#else /* HAVE_DLOPEN */
-
-NTSTATUS smb_load_module(const char *module_name)
-{
- DEBUG(0,("This samba executable has not been built with plugin support\n"));
- return NT_STATUS_NOT_SUPPORTED;
-}
-
-int smb_load_modules(const char **modules)
-{
- DEBUG(0,("This samba executable has not been built with plugin support\n"));
- return -1;
-}
-
-NTSTATUS smb_probe_module(const char *subsystem, const char *module)
-{
- DEBUG(0,("This samba executable has not been built with plugin support, not probing\n"));
- return NT_STATUS_NOT_SUPPORTED;
-}
-
-#endif /* HAVE_DLOPEN */
-
-void init_modules(void)
-{
- /* FIXME: This can cause undefined symbol errors :
- * smb_register_vfs() isn't available in nmbd, for example */
- if(lp_preload_modules())
- smb_load_modules(lp_preload_modules());
-}
-
-
-/***************************************************************************
- * This Function registers a idle event
- *
- * the registered funtions are run periodically
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-static smb_event_id_t smb_idle_event_id = 1;
-
-struct smb_idle_list_ent {
- struct smb_idle_list_ent *prev,*next;
- smb_event_id_t id;
- smb_idle_event_fn *fn;
- void *data;
- time_t interval;
- time_t lastrun;
-};
-
-static struct smb_idle_list_ent *smb_idle_event_list = NULL;
-
-smb_event_id_t smb_register_idle_event(smb_idle_event_fn *fn, void *data, time_t interval)
-{
- struct smb_idle_list_ent *event;
-
- if (!fn) {
- return SMB_EVENT_ID_INVALID;
- }
-
- event = (struct smb_idle_list_ent *)malloc(sizeof(struct smb_idle_list_ent));
- if (!event) {
- DEBUG(0,("malloc() failed!\n"));
- return SMB_EVENT_ID_INVALID;
- }
- event->fn = fn;
- event->data = data;
- event->interval = interval;
- event->lastrun = 0;
- event->id = smb_idle_event_id++;
-
- DLIST_ADD(smb_idle_event_list,event);
-
- return event->id;
-}
-
-BOOL smb_unregister_idle_event(smb_event_id_t id)
-{
- struct smb_idle_list_ent *event = smb_idle_event_list;
-
- while(event) {
- if (event->id == id) {
- DLIST_REMOVE(smb_idle_event_list,event);
- SAFE_FREE(event);
- return True;
- }
- event = event->next;
- }
-
- return False;
-}
-
-void smb_run_idle_events(time_t now)
-{
- struct smb_idle_list_ent *event = smb_idle_event_list;
-
- while (event) {
- struct smb_idle_list_ent *next = event->next;
- time_t interval;
-
- if (event->interval <= 0) {
- interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL;
- } else if (event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) {
- interval = event->interval;
- } else {
- interval = SMB_IDLE_EVENT_MIN_INTERVAL;
- }
- if (now >(event->lastrun+interval)) {
- event->lastrun = now;
- event->fn(&event->data,&event->interval,now);
- }
- event = next;
- }
-
- return;
-}
-
-/***************************************************************************
- * This Function registers a exit event
- *
- * the registered functions are run on exit()
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-
-struct smb_exit_list_ent {
- struct smb_exit_list_ent *prev,*next;
- smb_event_id_t id;
- smb_exit_event_fn *fn;
- void *data;
-};
-
-static struct smb_exit_list_ent *smb_exit_event_list = NULL;
-
-smb_event_id_t smb_register_exit_event(smb_exit_event_fn *fn, void *data)
-{
- struct smb_exit_list_ent *event;
- static smb_event_id_t smb_exit_event_id = 1;
-
- if (!fn) {
- return SMB_EVENT_ID_INVALID;
- }
-
- event = (struct smb_exit_list_ent *)malloc(sizeof(struct smb_exit_list_ent));
- if (!event) {
- DEBUG(0,("malloc() failed!\n"));
- return SMB_EVENT_ID_INVALID;
- }
- event->fn = fn;
- event->data = data;
- event->id = smb_exit_event_id++;
-
- DLIST_ADD(smb_exit_event_list,event);
-
- return event->id;
-}
-
-BOOL smb_unregister_exit_event(smb_event_id_t id)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
-
- while(event) {
- if (event->id == id) {
- DLIST_REMOVE(smb_exit_event_list,event);
- SAFE_FREE(event);
- return True;
- }
- event = event->next;
- }
-
- return False;
-}
-
-void smb_run_exit_events(void)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
- struct smb_exit_list_ent *tmp = NULL;
-
- while (event) {
- event->fn(&event->data);
- tmp = event;
- event = event->next;
- /* exit event should only run one time :-)*/
- SAFE_FREE(tmp);
- }
-
- /* the list is empty now...*/
- smb_exit_event_list = NULL;
-
- return;
-}
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index 24232c3b523..87e40049e05 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
filename matching routine
Copyright (C) Andrew Tridgell 1992-1998
@@ -23,83 +24,70 @@
*/
-#if FNMATCH_TEST
-#include <stdio.h>
-#include <stdlib.h>
-#else
#include "includes.h"
-#endif
/*
bugger. we need a separate wildcard routine for older versions
of the protocol. This is not yet perfect, but its a lot
- better than what we had */
-static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
- const smb_ucs2_t *string,
- BOOL case_sensitive)
+ better thaan what we had */
+static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
{
- const smb_ucs2_t *p = pattern, *n = string;
- smb_ucs2_t c;
+ const char *p = pattern, *n = string;
+ char c;
- if (strcmp_wa(p, "?")==0 && strcmp_wa(n, ".")) goto match;
+ if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match;
while ((c = *p++)) {
switch (c) {
- case UCS2_CHAR('.'):
+ case '.':
if (! *n) goto next;
- if (*n != UCS2_CHAR('.')) goto nomatch;
+ /* if (! *n && ! *p) goto match; */
+ if (*n != '.') goto nomatch;
n++;
break;
- case UCS2_CHAR('?'):
+ case '?':
if (! *n) goto next;
- if ((*n == UCS2_CHAR('.') &&
- n[1] != UCS2_CHAR('.')) || ! *n)
- goto next;
+ if ((*n == '.' && n[1] != '.') || ! *n) goto next;
n++;
break;
- case UCS2_CHAR('>'):
+ case '>':
if (! *n) goto next;
- if (n[0] == UCS2_CHAR('.')) {
- if (! n[1] && ms_fnmatch_lanman_core(p, n+1, case_sensitive) == 0) goto match;
- if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
+ if (n[0] == '.') {
+ if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
goto nomatch;
}
n++;
break;
- case UCS2_CHAR('*'):
+ case '*':
if (! *n) goto next;
if (! *p) goto match;
for (; *n; n++) {
- if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
}
break;
- case UCS2_CHAR('<'):
+ case '<':
for (; *n; n++) {
- if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
- if (*n == UCS2_CHAR('.') &&
- !strchr_w(n+1,UCS2_CHAR('.'))) {
+ if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (*n == '.' && !strchr(n+1,'.')) {
n++;
break;
}
}
break;
- case UCS2_CHAR('"'):
- if (*n == 0 && ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
- if (*n != UCS2_CHAR('.')) goto nomatch;
+ case '"':
+ if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (*n != '.') goto nomatch;
n++;
break;
default:
- if (case_sensitive) {
- if (c != *n) goto nomatch;
- } else {
- if (tolower_w(c) != tolower_w(*n)) goto nomatch;
- }
+ if (c != *n) goto nomatch;
n++;
}
}
@@ -113,7 +101,7 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
return -1;
next:
- if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
goto nomatch;
match:
@@ -123,23 +111,19 @@ next:
return 0;
}
-static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern,
- const smb_ucs2_t *string, BOOL case_sensitive)
+static int ms_fnmatch_lanman1(const char *pattern, const char *string)
{
- if (!strpbrk_wa(pattern, "?*<>\"")) {
- smb_ucs2_t s[] = {UCS2_CHAR('.'), 0};
- if (strcmp_wa(string,"..") == 0) string = s;
- return strcasecmp_w(pattern, string);
+ if (!strpbrk(pattern, "?*<>\"")) {
+ if (strcmp(string,"..") == 0) string = ".";
+ return strcasecmp(pattern, string);
}
- if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) {
- smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0};
- smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0};
- return ms_fnmatch_lanman_core(pattern, dotdot, case_sensitive) &&
- ms_fnmatch_lanman_core(pattern, dot, case_sensitive);
+ if (strcmp(string,"..") == 0 || strcmp(string,".") == 0) {
+ return ms_fnmatch_lanman_core(pattern, "..") &&
+ ms_fnmatch_lanman_core(pattern, ".");
}
- return ms_fnmatch_lanman_core(pattern, string, case_sensitive);
+ return ms_fnmatch_lanman_core(pattern, string);
}
@@ -151,61 +135,57 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern,
Returns 0 on match, -1 on fail.
*/
-static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string,
- int protocol, BOOL case_sensitive)
+int ms_fnmatch(const char *pattern, const char *string)
{
- const smb_ucs2_t *p = pattern, *n = string;
- smb_ucs2_t c;
+ const char *p = pattern, *n = string;
+ char c;
+ extern int Protocol;
- if (protocol <= PROTOCOL_LANMAN2) {
- return ms_fnmatch_lanman1(pattern, string, case_sensitive);
+ if (Protocol <= PROTOCOL_LANMAN2) {
+ return ms_fnmatch_lanman1(pattern, string);
}
while ((c = *p++)) {
switch (c) {
- case UCS2_CHAR('?'):
+ case '?':
if (! *n) return -1;
n++;
break;
- case UCS2_CHAR('>'):
- if (n[0] == UCS2_CHAR('.')) {
- if (! n[1] && ms_fnmatch_w(p, n+1, protocol, case_sensitive) == 0) return 0;
- if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
+ case '>':
+ if (n[0] == '.') {
+ if (! n[1] && ms_fnmatch(p, n+1) == 0) return 0;
+ if (ms_fnmatch(p, n) == 0) return 0;
return -1;
}
- if (! *n) return ms_fnmatch_w(p, n, protocol, case_sensitive);
+ if (! *n) return ms_fnmatch(p, n);
n++;
break;
- case UCS2_CHAR('*'):
+ case '*':
for (; *n; n++) {
- if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
+ if (ms_fnmatch(p, n) == 0) return 0;
}
break;
- case UCS2_CHAR('<'):
+ case '<':
for (; *n; n++) {
- if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
- if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) {
+ if (ms_fnmatch(p, n) == 0) return 0;
+ if (*n == '.' && !strchr(n+1,'.')) {
n++;
break;
}
}
break;
- case UCS2_CHAR('"'):
- if (*n == 0 && ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
- if (*n != UCS2_CHAR('.')) return -1;
+ case '"':
+ if (*n == 0 && ms_fnmatch(p, n) == 0) return 0;
+ if (*n != '.') return -1;
n++;
break;
default:
- if (case_sensitive) {
- if (c != *n) return -1;
- } else {
- if (tolower_w(c) != tolower_w(*n)) return -1;
- }
+ if (c != *n) return -1;
n++;
}
}
@@ -214,36 +194,3 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string,
return -1;
}
-
-int ms_fnmatch(const char *pattern, const char *string, int protocol,
- BOOL case_senstive)
-{
- wpstring buffer_pattern, buffer_string;
- int ret;
- size_t size;
-
- size = push_ucs2(NULL, buffer_pattern, pattern, sizeof(buffer_pattern), STR_TERMINATE);
- if (size == (size_t)-1) {
- return -1;
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
- }
-
- size = push_ucs2(NULL, buffer_string, string, sizeof(buffer_string), STR_TERMINATE);
- if (size == (size_t)-1) {
- return -1;
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
- }
-
- ret = ms_fnmatch_w(buffer_pattern, buffer_string, protocol, case_senstive);
- DEBUG(10,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret));
-
- return ret;
-}
-
-/* a generic fnmatch function - uses for non-CIFS pattern matching */
-int gen_fnmatch(const char *pattern, const char *string)
-{
- return ms_fnmatch(pattern, string, PROTOCOL_NT1, True);
-}
diff --git a/source/lib/netatalk.c b/source/lib/netatalk.c
new file mode 100755
index 00000000000..e1913f5379b
--- /dev/null
+++ b/source/lib/netatalk.c
@@ -0,0 +1,157 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ netatalk.c : routines for improving interaction between Samba and netatalk.
+ Copyright (C) John D. Blair <jdblair@cobaltnet.com> 1998
+ Cobalt Networks, Inc.
+*/
+
+#include "includes.h"
+
+#ifdef WITH_NETATALK
+
+/*****************
+ ntalk_resourcepath: creates the path to the netatalk resource fork for
+ a given file
+
+ fname: normal filename
+ doublename: buffer that will contain the location of the resource fork
+ length: length of this buffer (to prevent overflows)
+
+ NOTE: doesn't currently gracefully deal with buffer overflows- it just
+ doesn't allow them to occur.
+******************/
+void ntalk_resourcepath(const char *fname, char *doublename, const int length)
+{
+ int i;
+ int charnum;
+ int lastslash;
+ char appledouble[] = APPLEDOUBLE;
+
+ /* copy fname to doublename and find last slash */
+ for (i = 0; (fname[i] != 0) && (i <= length); i++) {
+ if (fname[i] == '/') {
+ lastslash = i;
+ }
+ doublename[i] = fname[i];
+ }
+ lastslash++; /* location just after last slash */
+
+ /* insert .AppleDouble */
+ charnum = lastslash;
+ for (i = 0; (appledouble[i] != 0) && (i <= length); i++) {
+ doublename[charnum] = appledouble[i];
+ charnum++;
+ }
+
+ /* append last part of file name */
+ for (i = lastslash; (fname[i] != 0) && (i <= length); i++) {
+ doublename[charnum] = fname[i];
+ charnum++;
+ }
+
+ doublename[charnum] = 0;
+}
+
+/**********************
+ ntalk_mkresdir: creates a new .AppleDouble directory (if necessary)
+ for the resource fork of a specified file
+**********************/
+int ntalk_mkresdir(const char *fname)
+{
+ char fdir[255];
+ int i;
+ int lastslash;
+ SMB_STRUCT_STAT dirstats;
+ char appledouble[] = APPLEDOUBLE;
+
+ /* find directory containing fname */
+ for (i = 0; (fname[i] != 0) && (i <= 254); i++) {
+ fdir[i] = fname[i];
+ if (fdir[i] == '/') {
+ lastslash = i;
+ }
+ }
+ lastslash++;
+ fdir[lastslash] = 0;
+ sys_lstat(fdir, &dirstats);
+
+ /* append .AppleDouble */
+ for (i = 0; (appledouble[i] != 0) && (lastslash <= 254); i++) {
+ fdir[lastslash] = appledouble[i];
+ lastslash++;
+ }
+ fdir[lastslash] = 0;
+
+ /* create this directory */
+ /* silently ignore EEXIST error */
+ if ((mkdir(fdir, dirstats.st_mode) < 0) && (errno != EEXIST)) {
+ return errno;
+ }
+
+ /* set ownership of this dir to the same as its parent */
+ /* holy race condition, batman! */
+ /* warning: this doesn't check for errors */
+ chown(fdir, dirstats.st_uid, dirstats.st_gid);
+
+ printf("%s\n", fdir);
+
+ return 1;
+}
+
+/**********************
+ ntalk_unlink: unlink a file and its resource fork
+**********************/
+int ntalk_unlink(const char *fname)
+{
+ char buf[255];
+
+ ntalk_resourcepath(fname, buf, 255);
+ unlink(buf);
+ return unlink(fname);
+}
+
+/**********************
+ ntalk_chown: chown a file and its resource fork
+**********************/
+int ntalk_chown(const char *fname, const uid_t uid, const gid_t gid)
+{
+ char buf[255];
+
+ ntalk_resourcepath(fname, buf, 255);
+ chown(buf, uid, gid);
+ return chown(fname, uid, gid);
+}
+
+/**********************
+ ntalk_chmod: chmod a file and its resource fork
+**********************/
+int ntalk_chmod(const char *fname, mode_t perms)
+{
+ char buf[255];
+
+ ntalk_resourcepath(fname, buf, 255);
+ chmod(buf, perms);
+ return chmod(fname, perms);
+}
+
+
+#endif /* WITH_NETATALK */
diff --git a/source/lib/pam_errors.c b/source/lib/pam_errors.c
index 212d3831fd5..68653e0f63b 100644
--- a/source/lib/pam_errors.c
+++ b/source/lib/pam_errors.c
@@ -28,7 +28,7 @@
#endif
/* PAM -> NT_STATUS map */
-static const struct {
+static struct {
int pam_code;
NTSTATUS ntstatus;
} pam_to_nt_status_map[] = {
@@ -36,7 +36,7 @@ static const struct {
{PAM_SYMBOL_ERR, NT_STATUS_UNSUCCESSFUL},
{PAM_SERVICE_ERR, NT_STATUS_UNSUCCESSFUL},
{PAM_SYSTEM_ERR, NT_STATUS_UNSUCCESSFUL},
- {PAM_BUF_ERR, NT_STATUS_NO_MEMORY},
+ {PAM_BUF_ERR, NT_STATUS_UNSUCCESSFUL},
{PAM_PERM_DENIED, NT_STATUS_ACCESS_DENIED},
{PAM_AUTH_ERR, NT_STATUS_WRONG_PASSWORD},
{PAM_CRED_INSUFFICIENT, NT_STATUS_INSUFFICIENT_LOGON_INFO}, /* FIXME: Is this correct? */
@@ -58,7 +58,7 @@ static const struct {
};
/* NT_STATUS -> PAM map */
-static const struct {
+static struct {
NTSTATUS ntstatus;
int pam_code;
} nt_status_to_pam_map[] = {
@@ -67,10 +67,7 @@ static const struct {
{NT_STATUS_WRONG_PASSWORD, PAM_AUTH_ERR},
{NT_STATUS_LOGON_FAILURE, PAM_AUTH_ERR},
{NT_STATUS_ACCOUNT_EXPIRED, PAM_ACCT_EXPIRED},
- {NT_STATUS_PASSWORD_EXPIRED, PAM_AUTHTOK_EXPIRED},
{NT_STATUS_PASSWORD_MUST_CHANGE, PAM_NEW_AUTHTOK_REQD},
- {NT_STATUS_ACCOUNT_LOCKED_OUT, PAM_MAXTRIES},
- {NT_STATUS_NO_MEMORY, PAM_BUF_ERR},
{NT_STATUS_OK, PAM_SUCCESS}
};
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index 1a462bf1287..5715afbb4f9 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -1,7 +1,8 @@
/* this code is broken - there is a race condition with the unlink (tridge) */
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
pidfile handling
Copyright (C) Andrew Tridgell 1998
@@ -22,6 +23,7 @@
#include "includes.h"
+
#ifndef O_NONBLOCK
#define O_NONBLOCK
#endif
@@ -100,7 +102,7 @@ void pidfile_create(const char *name)
memset(buf, 0, sizeof(buf));
slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) sys_getpid());
- if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) {
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
DEBUG(0,("ERROR: can't write to file %s: %s\n",
pidFile, strerror(errno)));
exit(1);
diff --git a/source/lib/popt_common.c b/source/lib/popt_common.c
deleted file mode 100644
index 6c35213d43a..00000000000
--- a/source/lib/popt_common.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Common popt routines
-
- Copyright (C) Tim Potter 2001,2002
- Copyright (C) Jelmer Vernooij 2002,2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* Handle command line options:
- * -d,--debuglevel
- * -s,--configfile
- * -O,--socket-options
- * -V,--version
- * -l,--log-base
- * -n,--netbios-name
- * -W,--workgroup
- * -i,--scope
- */
-
-extern pstring user_socket_options;
-extern BOOL AllowDebugChange;
-extern BOOL override_logfile;
-
-struct user_auth_info cmdline_auth_info;
-
-static void popt_common_callback(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg, const void *data)
-{
- pstring logfile;
- const char *pname;
-
- /* Find out basename of current program */
- pname = strrchr_m(poptGetInvocationName(con),'/');
-
- if (!pname)
- pname = poptGetInvocationName(con);
- else
- pname++;
-
- if (reason == POPT_CALLBACK_REASON_PRE) {
- pstr_sprintf(logfile, "%s/log.%s", dyn_LOGFILEBASE, pname);
- lp_set_logfile(logfile);
- return;
- }
-
- switch(opt->val) {
- case 'd':
- if (arg) {
- debug_parse_levels(arg);
- AllowDebugChange = False;
- }
- break;
-
- case 'V':
- printf( "Version %s\n", SAMBA_VERSION_STRING);
- exit(0);
- break;
-
- case 'O':
- if (arg) {
- pstrcpy(user_socket_options,arg);
- }
- break;
-
- case 's':
- if (arg) {
- pstrcpy(dyn_CONFIGFILE, arg);
- }
- break;
-
- case 'n':
- if (arg) {
- set_global_myname(arg);
- }
- break;
-
- case 'l':
- if (arg) {
- pstr_sprintf(logfile, "%s/log.%s", arg, pname);
- lp_set_logfile(logfile);
- override_logfile = True;
- }
- break;
-
- case 'i':
- if (arg) {
- set_global_scope(arg);
- }
- break;
-
- case 'W':
- if (arg) {
- set_global_myworkgroup(arg);
- }
- break;
- }
-}
-
-struct poptOption popt_common_connection[] = {
- { NULL, 0, POPT_ARG_CALLBACK, popt_common_callback },
- { "socket-options", 'O', POPT_ARG_STRING, NULL, 'O', "socket options to use",
- "SOCKETOPTIONS" },
- { "netbiosname", 'n', POPT_ARG_STRING, NULL, 'n', "Primary netbios name", "NETBIOSNAME" },
- { "workgroup", 'W', POPT_ARG_STRING, NULL, 'W', "Set the workgroup name", "WORKGROUP" },
- { "scope", 'i', POPT_ARG_STRING, NULL, 'i', "Use this Netbios scope", "SCOPE" },
-
- POPT_TABLEEND
-};
-
-struct poptOption popt_common_samba[] = {
- { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, popt_common_callback },
- { "debuglevel", 'd', POPT_ARG_STRING, NULL, 'd', "Set debug level", "DEBUGLEVEL" },
- { "configfile", 's', POPT_ARG_STRING, NULL, 's', "Use alternative configuration file", "CONFIGFILE" },
- { "log-basename", 'l', POPT_ARG_STRING, NULL, 'l', "Basename for log/debug files", "LOGFILEBASE" },
- { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
- POPT_TABLEEND
-};
-
-struct poptOption popt_common_version[] = {
- { NULL, 0, POPT_ARG_CALLBACK, popt_common_callback },
- { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
- POPT_TABLEEND
-};
-
-
-
-/****************************************************************************
- * get a password from a a file or file descriptor
- * exit on failure
- * ****************************************************************************/
-static void get_password_file(struct user_auth_info *a)
-{
- int fd = -1;
- char *p;
- BOOL close_it = False;
- pstring spec;
- char pass[128];
-
- if ((p = getenv("PASSWD_FD")) != NULL) {
- pstrcpy(spec, "descriptor ");
- pstrcat(spec, p);
- sscanf(p, "%d", &fd);
- close_it = False;
- } else if ((p = getenv("PASSWD_FILE")) != NULL) {
- fd = sys_open(p, O_RDONLY, 0);
- pstrcpy(spec, p);
- if (fd < 0) {
- fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- close_it = True;
- }
-
- for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
- p && p - pass < sizeof(pass);) {
- switch (read(fd, p, 1)) {
- case 1:
- if (*p != '\n' && *p != '\0') {
- *++p = '\0'; /* advance p, and null-terminate pass */
- break;
- }
- case 0:
- if (p - pass) {
- *p = '\0'; /* null-terminate it, just in case... */
- p = NULL; /* then force the loop condition to become false */
- break;
- } else {
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, "empty password\n");
- exit(1);
- }
-
- default:
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- }
- pstrcpy(a->password, pass);
- if (close_it)
- close(fd);
-}
-
-static void get_credentials_file(const char *file, struct user_auth_info *info)
-{
- XFILE *auth;
- fstring buf;
- uint16 len = 0;
- char *ptr, *val, *param;
-
- if ((auth=x_fopen(file, O_RDONLY, 0)) == NULL)
- {
- /* fail if we can't open the credentials file */
- d_printf("ERROR: Unable to open credentials file!\n");
- exit(-1);
- }
-
- while (!x_feof(auth))
- {
- /* get a line from the file */
- if (!x_fgets(buf, sizeof(buf), auth))
- continue;
- len = strlen(buf);
-
- if ((len) && (buf[len-1]=='\n'))
- {
- buf[len-1] = '\0';
- len--;
- }
- if (len == 0)
- continue;
-
- /* break up the line into parameter & value.
- * will need to eat a little whitespace possibly */
- param = buf;
- if (!(ptr = strchr_m (buf, '=')))
- continue;
-
- val = ptr+1;
- *ptr = '\0';
-
- /* eat leading white space */
- while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
- val++;
-
- if (strwicmp("password", param) == 0)
- {
- pstrcpy(info->password, val);
- info->got_pass = True;
- }
- else if (strwicmp("username", param) == 0)
- pstrcpy(info->username, val);
- else if (strwicmp("domain", param) == 0)
- set_global_myworkgroup(val);
- memset(buf, 0, sizeof(buf));
- }
- x_fclose(auth);
-}
-
-/* Handle command line options:
- * -U,--user
- * -A,--authentication-file
- * -k,--use-kerberos
- * -N,--no-pass
- * -S,--signing
- * -P --machine-pass
- */
-
-
-static void popt_common_credentials_callback(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg, const void *data)
-{
- char *p;
-
- if (reason == POPT_CALLBACK_REASON_PRE) {
- cmdline_auth_info.use_kerberos = False;
- cmdline_auth_info.got_pass = False;
- cmdline_auth_info.signing_state = Undefined;
- pstrcpy(cmdline_auth_info.username, "GUEST");
-
- if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME"));
-
- if (getenv("USER")) {
- pstrcpy(cmdline_auth_info.username,getenv("USER"));
-
- if ((p = strchr_m(cmdline_auth_info.username,'%'))) {
- *p = 0;
- pstrcpy(cmdline_auth_info.password,p+1);
- cmdline_auth_info.got_pass = True;
- memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(cmdline_auth_info.password));
- }
- }
-
- if (getenv("PASSWD")) {
- pstrcpy(cmdline_auth_info.password,getenv("PASSWD"));
- cmdline_auth_info.got_pass = True;
- }
-
- if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
- get_password_file(&cmdline_auth_info);
- cmdline_auth_info.got_pass = True;
- }
-
- return;
- }
-
- switch(opt->val) {
- case 'U':
- {
- char *lp;
-
- pstrcpy(cmdline_auth_info.username,arg);
- if ((lp=strchr_m(cmdline_auth_info.username,'%'))) {
- *lp = 0;
- pstrcpy(cmdline_auth_info.password,lp+1);
- cmdline_auth_info.got_pass = True;
- memset(strchr_m(arg,'%')+1,'X',strlen(cmdline_auth_info.password));
- }
- }
- break;
-
- case 'A':
- get_credentials_file(arg, &cmdline_auth_info);
- break;
-
- case 'k':
-#ifndef HAVE_KRB5
- d_printf("No kerberos support compiled in\n");
- exit(1);
-#else
- cmdline_auth_info.use_kerberos = True;
- cmdline_auth_info.got_pass = True;
-#endif
- break;
-
- case 'S':
- {
- cmdline_auth_info.signing_state = -1;
- if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false"))
- cmdline_auth_info.signing_state = False;
- else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true") ||
- strequal(arg, "auto") )
- cmdline_auth_info.signing_state = True;
- else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced"))
- cmdline_auth_info.signing_state = Required;
- else {
- fprintf(stderr, "Unknown signing option %s\n", arg );
- exit(1);
- }
- }
- break;
- case 'P':
- {
- char *opt_password = NULL;
- /* it is very useful to be able to make ads queries as the
- machine account for testing purposes and for domain leave */
-
- if (!secrets_init()) {
- d_printf("ERROR: Unable to open secrets database\n");
- exit(1);
- }
-
- opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- if (!opt_password) {
- d_printf("ERROR: Unable to fetch machine password\n");
- exit(1);
- }
- pstr_sprintf(cmdline_auth_info.username, "%s$",
- global_myname());
- pstrcpy(cmdline_auth_info.password,opt_password);
- SAFE_FREE(opt_password);
-
- /* machine accounts only work with kerberos */
- cmdline_auth_info.use_kerberos = True;
- cmdline_auth_info.got_pass = True;
- }
- break;
- }
-}
-
-
-
-struct poptOption popt_common_credentials[] = {
- { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, popt_common_credentials_callback },
- { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
- { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" },
- { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" },
- { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
- { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
- {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
- POPT_TABLEEND
-};
diff --git a/source/lib/privileges.c b/source/lib/privileges.c
deleted file mode 100644
index 83016bb7a7b..00000000000
--- a/source/lib/privileges.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Privileges handling functions
- Copyright (C) Jean François Micouleau 1998-2001
- Copyright (C) Simo Sorce 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* defines */
-
-#define ALLOC_CHECK(ptr, err, label, str) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
-#define NTSTATUS_CHECK(err, label, str1, str2) do { if (!NT_STATUS_IS_OK(err)) { DEBUG(0, ("%s: %s failed!\n", str1, str2)); } } while(0)
-
-PRIVS privs[] = {
- {SE_ASSIGN_PRIMARY_TOKEN, "SeAssignPrimaryTokenPrivilege", "Assign Primary Token"},
- {SE_CREATE_TOKEN, "SeCreateTokenPrivilege", "Create Token"},
- {SE_LOCK_MEMORY, "SeLockMemoryPrivilege", "Lock Memory"},
- {SE_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege", "Increase Quota"},
- {SE_UNSOLICITED_INPUT, "SeUnsolicitedInputPrivilege", "Unsolicited Input"},
- {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Can add Machine Accounts to the Domain"},
- {SE_TCB, "SeTcbPrivilege", "TCB"},
- {SE_SECURITY, "SeSecurityPrivilege", "Security Privilege"},
- {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take Ownership Privilege"},
- {SE_LOAD_DRIVER, "SeLocalDriverPrivilege", "Local Driver Privilege"},
- {SE_SYSTEM_PROFILE, "SeSystemProfilePrivilege", "System Profile Privilege"},
- {SE_SYSTEM_TIME, "SeSystemtimePrivilege", "System Time"},
- {SE_PROF_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege", "Profile Single Process Privilege"},
- {SE_INC_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege", "Increase Base Priority Privilege"},
- {SE_CREATE_PAGEFILE, "SeCreatePagefilePrivilege", "Create Pagefile Privilege"},
- {SE_CREATE_PERMANENT, "SeCreatePermanentPrivilege", "Create Permanent"},
- {SE_BACKUP, "SeBackupPrivilege", "Backup Privilege"},
- {SE_RESTORE, "SeRestorePrivilege", "Restore Privilege"},
- {SE_SHUTDOWN, "SeShutdownPrivilege", "Shutdown Privilege"},
- {SE_DEBUG, "SeDebugPrivilege", "Debug Privilege"},
- {SE_AUDIT, "SeAuditPrivilege", "Audit"},
- {SE_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege", "System Environment Privilege"},
- {SE_CHANGE_NOTIFY, "SeChangeNotifyPrivilege", "Change Notify"},
- {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Remote Shutdown Privilege"},
- {SE_UNDOCK, "SeUndockPrivilege", "Undock"},
- {SE_SYNC_AGENT, "SeSynchronizationAgentPrivilege", "Synchronization Agent"},
- {SE_ENABLE_DELEGATION, "SeEnableDelegationPrivilege", "Enable Delegation"},
- {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Printer Operator"},
- {SE_ADD_USERS, "SeAddUsersPrivilege", "Add Users"},
- {SE_ALL_PRIVS, "SeAllPrivileges", "All Privileges"}
-};
-
-
-/****************************************************************************
- duplicate alloc luid_attr
- ****************************************************************************/
-NTSTATUS dupalloc_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)
-{
- NTSTATUS ret;
- int i;
-
- /* don't crash if the source pointer is NULL (since we don't
- do priviledges now anyways) */
-
- if ( !old_la )
- return NT_STATUS_OK;
-
- *new_la = (LUID_ATTR *)talloc(mem_ctx, count*sizeof(LUID_ATTR));
- ALLOC_CHECK(new_la, ret, done, "dupalloc_luid_attr");
-
- for (i=0; i<count; i++) {
- (*new_la)[i].luid.high = old_la[i].luid.high;
- (*new_la)[i].luid.low = old_la[i].luid.low;
- (*new_la)[i].attr = old_la[i].attr;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-/****************************************************************************
- initialise a privilege list
- ****************************************************************************/
-NTSTATUS init_privilege(PRIVILEGE_SET **priv_set)
-{
- NTSTATUS ret;
- TALLOC_CTX *mem_ctx = talloc_init("privilege set");
- ALLOC_CHECK(mem_ctx, ret, done, "init_privilege");
-
- *priv_set = talloc_zero(mem_ctx, sizeof(PRIVILEGE_SET));
- ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
-
- (*priv_set)->mem_ctx = mem_ctx;
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-NTSTATUS init_priv_with_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **priv_set)
-{
- NTSTATUS ret;
-
- *priv_set = talloc_zero(mem_ctx, sizeof(PRIVILEGE_SET));
- ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
-
- (*priv_set)->mem_ctx = mem_ctx;
- (*priv_set)->ext_ctx = True;
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-void reset_privilege(PRIVILEGE_SET *priv_set)
-{
- priv_set->count = 0;
- priv_set->control = 0;
- priv_set->set = NULL;
-}
-
-void destroy_privilege(PRIVILEGE_SET **priv_set)
-{
- if (priv_set == NULL || *priv_set == NULL)
- return;
-
- reset_privilege(*priv_set);
- if (!((*priv_set)->ext_ctx))
- /* mem_ctx is local, destroy it */
- talloc_destroy((*priv_set)->mem_ctx);
- *priv_set = NULL;
-}
-
-/****************************************************************************
- add a privilege to a privilege array
- ****************************************************************************/
-NTSTATUS add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- NTSTATUS ret;
- LUID_ATTR *new_set;
-
- /* check if the privilege is not already in the list */
- if (NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
- return NT_STATUS_UNSUCCESSFUL;
-
- /* we can allocate memory to add the new privilege */
-
- new_set = (LUID_ATTR *)talloc_realloc(priv_set->mem_ctx, priv_set->set, (priv_set->count + 1) * (sizeof(LUID_ATTR)));
- ALLOC_CHECK(new_set, ret, done, "add_privilege");
-
- new_set[priv_set->count].luid.high = set.luid.high;
- new_set[priv_set->count].luid.low = set.luid.low;
- new_set[priv_set->count].attr = set.attr;
-
- priv_set->count++;
- priv_set->set = new_set;
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-NTSTATUS add_privilege_by_name(PRIVILEGE_SET *priv_set, const char *name)
-{
- int e;
-
- for (e = 0; privs[e].se_priv != SE_ALL_PRIVS; e++) {
- if (StrCaseCmp(privs[e].priv, name) == 0) {
- LUID_ATTR la;
-
- la.attr = 0;
- la.luid.high = 0;
- la.luid.low = privs[e].se_priv;
-
- return add_privilege(priv_set, la);
- }
- }
-
- DEBUG(1, ("add_privilege_by_name: No Such Privilege Found (%s)\n", name));
-
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/****************************************************************************
- add all the privileges to a privilege array
- ****************************************************************************/
-NTSTATUS add_all_privilege(PRIVILEGE_SET *priv_set)
-{
- NTSTATUS result = NT_STATUS_OK;
- LUID_ATTR set;
-
- set.attr = 0;
- set.luid.high = 0;
-
- /* TODO: set a proper list of privileges */
- set.luid.low = SE_ADD_USERS;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
-
- set.luid.low = SE_MACHINE_ACCOUNT;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
-
- set.luid.low = SE_PRINT_OPERATOR;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
-
- return result;
-}
-
-/****************************************************************************
- check if the privilege list is empty
- ****************************************************************************/
-NTSTATUS check_empty_privilege(PRIVILEGE_SET *priv_set)
-{
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (priv_set->count == 0)
- return NT_STATUS_OK;
-
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/****************************************************************************
- check if the privilege is in the privilege list
- ****************************************************************************/
-NTSTATUS check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- int i;
-
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* if the list is empty, obviously we can't have it */
- if (NT_STATUS_IS_OK(check_empty_privilege(priv_set)))
- return NT_STATUS_UNSUCCESSFUL;
-
- for (i = 0; i < priv_set->count; i++) {
- LUID_ATTR *cur_set;
-
- cur_set = &priv_set->set[i];
- /* check only the low and high part. Checking the attr field has no meaning */
- if ( (cur_set->luid.low == set.luid.low) &&
- (cur_set->luid.high == set.luid.high) ) {
- return NT_STATUS_OK;
- }
- }
-
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/****************************************************************************
- remove a privilege from a privilege array
- ****************************************************************************/
-NTSTATUS remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- NTSTATUS ret;
- LUID_ATTR *new_set;
- LUID_ATTR *old_set;
- int i,j;
-
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* check if the privilege is in the list */
- if (!NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
- return NT_STATUS_UNSUCCESSFUL;
-
- /* special case if it's the only privilege in the list */
- if (priv_set->count == 1) {
- reset_privilege(priv_set);
- return NT_STATUS_OK;
- }
-
- /*
- * the privilege is there, create a new list,
- * and copy the other privileges
- */
-
- old_set = priv_set->set;
-
- new_set = (LUID_ATTR *)talloc(priv_set->mem_ctx, (priv_set->count - 1) * (sizeof(LUID_ATTR)));
- ALLOC_CHECK(new_set, ret, done, "remove_privilege");
-
- for (i=0, j=0; i < priv_set->count; i++) {
- if ( (old_set[i].luid.low == set.luid.low) &&
- (old_set[i].luid.high == set.luid.high) ) {
- continue;
- }
-
- new_set[j].luid.low = old_set[i].luid.low;
- new_set[j].luid.high = old_set[i].luid.high;
- new_set[j].attr = old_set[i].attr;
-
- j++;
- }
-
- if (j != priv_set->count - 1) {
- DEBUG(0,("remove_privilege: mismatch ! difference is not -1\n"));
- DEBUGADD(0,("old count:%d, new count:%d\n", priv_set->count, j));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- /* ok everything is fine */
-
- priv_set->count--;
- priv_set->set = new_set;
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-/****************************************************************************
- duplicates a privilege array
- the new privilege set must be passed inited
- (use init_privilege or init_priv_with_ctx)
- ****************************************************************************/
-NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set)
-{
- NTSTATUS ret;
- LUID_ATTR *new_set;
- LUID_ATTR *old_set;
- int i;
-
- if (new_priv_set == NULL || priv_set == NULL)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* special case if there are no privileges in the list */
- if (priv_set->count == 0) {
- return NT_STATUS_OK;
- }
-
- /*
- * create a new list,
- * and copy the other privileges
- */
-
- old_set = priv_set->set;
-
- new_set = (LUID_ATTR *)talloc(new_priv_set->mem_ctx, (priv_set->count) * (sizeof(LUID_ATTR)));
- ALLOC_CHECK(new_set, ret, done, "dup_priv_set");
-
- for (i=0; i < priv_set->count; i++) {
-
- new_set[i].luid.low = old_set[i].luid.low;
- new_set[i].luid.high = old_set[i].luid.high;
- new_set[i].attr = old_set[i].attr;
- }
-
- new_priv_set->count = priv_set->count;
- new_priv_set->control = priv_set->control;
- new_priv_set->set = new_set;
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-
-NTSTATUS user_has_privilege(struct current_user *user, uint32 privilege)
-{
- LUID_ATTR set;
-
- set.attr = 0;
- set.luid.high = 0;
- set.luid.low = privilege;
-
- return check_priv_in_privilege(user->privs, set);
-}
-
-BOOL luid_to_privilege_name(const LUID *set, fstring name)
-{
- int i;
-
- if (set->high != 0)
- return False;
-
- for (i=1; i<PRIV_ALL_INDEX-1; i++) {
- if (set->low == privs[i].se_priv) {
- fstrcpy(name, privs[i].priv);
- return True;
- }
- }
- return False;
-}
diff --git a/source/lib/readline.c b/source/lib/readline.c
index 78b99fd7fb0..91f9a1b31d5 100644
--- a/source/lib/readline.c
+++ b/source/lib/readline.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Samba readline wrapper implementation
Copyright (C) Simo Sorce 2001
Copyright (C) Andrew Tridgell 2001
@@ -21,88 +22,26 @@
#include "includes.h"
-#ifdef HAVE_LIBREADLINE
-# ifdef HAVE_READLINE_READLINE_H
-# include <readline/readline.h>
-# ifdef HAVE_READLINE_HISTORY_H
-# include <readline/history.h>
-# endif
-# else
-# ifdef HAVE_READLINE_H
-# include <readline.h>
-# ifdef HAVE_HISTORY_H
-# include <history.h>
-# endif
-# else
-# undef HAVE_LIBREADLINE
-# endif
-# endif
-#endif
-
-#ifdef HAVE_NEW_LIBREADLINE
-# define RL_COMPLETION_CAST (rl_completion_func_t *)
-#else
-/* This type is missing from libreadline<4.0 (approximately) */
-# define RL_COMPLETION_CAST
-#endif /* HAVE_NEW_LIBREADLINE */
-
/****************************************************************************
Display the prompt and wait for input. Call callback() regularly
****************************************************************************/
-static char *smb_readline_replacement(char *prompt, void (*callback)(void),
- char **(completion_fn)(const char *text, int start, int end))
-{
- fd_set fds;
- static pstring line;
- struct timeval timeout;
- int fd = x_fileno(x_stdin);
- char *ret;
-
- x_fprintf(dbf, "%s", prompt);
- x_fflush(dbf);
-
- while (1) {
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
- ret = x_fgets(line, sizeof(line), x_stdin);
- return ret;
- }
- if (callback)
- callback();
- }
-}
-
-/****************************************************************************
- Display the prompt and wait for input. Call callback() regularly.
-****************************************************************************/
-
char *smb_readline(char *prompt, void (*callback)(void),
char **(completion_fn)(const char *text, int start, int end))
{
-#if HAVE_LIBREADLINE
- if (isatty(x_fileno(x_stdin))) {
- char *ret;
+ char *ret;
+ int fd = fileno(stdin);
- /* Aargh! Readline does bizzare things with the terminal width
- that mucks up expect(1). Set CLI_NO_READLINE in the environment
- to force readline not to be used. */
+#if HAVE_LIBREADLINE
- if (getenv("CLI_NO_READLINE"))
- return smb_readline_replacement(prompt, callback, completion_fn);
+ /*
+ * Current versions of readline on Linux seem to have
+ * problems with EOF on a pipe.
+ */
- if (completion_fn) {
- /* The callback prototype has changed slightly between
- different versions of Readline, so the same function
- works in all of them to date, but we get compiler
- warnings in some. */
- rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
- }
+ if (isatty(fd)) {
+ if (completion_fn)
+ rl_attempted_completion_function = completion_fn;
if (callback)
rl_event_hook = (Function *)callback;
@@ -112,36 +51,36 @@ char *smb_readline(char *prompt, void (*callback)(void),
return ret;
} else
#endif
- return smb_readline_replacement(prompt, callback, completion_fn);
-}
+ {
+ fd_set fds;
+ extern FILE *dbf;
+ static pstring line;
+ struct timeval timeout;
-/****************************************************************************
- * return line buffer text
- ****************************************************************************/
-const char *smb_readline_get_line_buffer(void)
-{
-#if defined(HAVE_LIBREADLINE)
- return rl_line_buffer;
-#else
- return NULL;
-#endif
-}
+ fprintf(dbf, "%s", prompt);
+ fflush(dbf);
+ while (1) {
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
-/****************************************************************************
- * set completion append character
- ***************************************************************************/
-void smb_readline_ca_char(char c)
-{
-#if defined(HAVE_LIBREADLINE)
- rl_completion_append_character = c;
-#endif
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+
+ if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
+ ret = fgets(line, sizeof(line), stdin);
+ return ret;
+ }
+ if (callback)
+ callback();
+ }
+ }
}
/****************************************************************************
history
****************************************************************************/
-int cmd_history(void)
+void cmd_history(void)
{
#if defined(HAVE_LIBREADLINE)
HIST_ENTRY **hlist;
@@ -155,7 +94,4 @@ int cmd_history(void)
#else
DEBUG(0,("no history without readline support\n"));
#endif
-
- return 0;
}
-
diff --git a/source/lib/replace.c b/source/lib/replace.c
index fe1cfc04eb1..370b6dfebf2 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -47,7 +47,7 @@ ftruncate for operating systems that don't have it
{
size_t len = strlen(s);
size_t ret = len;
- if (bufsize <= 0) return 0;
+ if (bufsize == 0) return 0;
if (len >= bufsize) len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
@@ -65,9 +65,6 @@ ftruncate for operating systems that don't have it
size_t len2 = strlen(s);
size_t ret = len1 + len2;
- if (len1 >= bufsize) {
- return 0;
- }
if (len1+len2 >= bufsize) {
len2 = bufsize - (len1+1);
}
@@ -331,8 +328,13 @@ char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
+#if WORDS_BIGENDIAN
slprintf(buf, 17, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
+#else /* WORDS_BIGENDIAN */
+ slprintf(buf, 17, "%d.%d.%d.%d",
+ (int)p[3], (int)p[2], (int)p[1], (int)p[0]);
+#endif /* WORDS_BIGENDIAN */
return buf;
}
#endif /* REPLACE_INET_NTOA */
@@ -412,41 +414,3 @@ char *rep_inet_ntoa(struct in_addr ip)
return setvbuf(stream, (char *)NULL, _IOLBF, 0);
}
#endif /* HAVE_SETLINEBUF */
-
-#ifndef HAVE_VSYSLOG
-#ifdef HAVE_SYSLOG
- void vsyslog (int facility_priority, char *format, va_list arglist)
-{
- char *msg = NULL;
- vasprintf(&msg, format, arglist);
- if (!msg)
- return;
- syslog(facility_priority, "%s", msg);
- SAFE_FREE(msg);
-}
-#endif /* HAVE_SYSLOG */
-#endif /* HAVE_VSYSLOG */
-
-
-#ifndef HAVE_TIMEGM
-/*
- yes, I know this looks insane, but its really needed. The function in the
- Linux timegm() manpage does not work on solaris.
-*/
- time_t timegm(struct tm *tm)
-{
- struct tm tm2, tm3;
- time_t t;
-
- tm2 = *tm;
-
- t = mktime(&tm2);
- tm3 = *localtime(&t);
- tm2 = *tm;
- tm2.tm_isdst = tm3.tm_isdst;
- t = mktime(&tm2);
- t -= TimeDiff(t);
-
- return t;
-}
-#endif
diff --git a/source/lib/replace1.c b/source/lib/replace1.c
deleted file mode 100644
index e1be56eb128..00000000000
--- a/source/lib/replace1.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- replacement routines for broken systems
- Copyright (C) Andrew Tridgell 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
- void replace1_dummy(void);
- void replace1_dummy(void) {}
-
-#ifndef HAVE_SETENV
- int setenv(const char *name, const char *value, int overwrite)
-{
- char *p = NULL;
- int ret = -1;
-
- asprintf(&p, "%s=%s", name, value);
-
- if (overwrite || getenv(name)) {
- if (p) ret = putenv(p);
- } else {
- ret = 0;
- }
-
- return ret;
-}
-#endif
diff --git a/source/lib/secace.c b/source/lib/secace.c
deleted file mode 100644
index 8c54c970433..00000000000
--- a/source/lib/secace.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_ACE handling functions
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*******************************************************************
- Check if ACE has OBJECT type.
-********************************************************************/
-
-BOOL sec_ace_object(uint8 type)
-{
- if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
- type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
- type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
- type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
- return True;
- }
- return False;
-}
-
-/*******************************************************************
- copy a SEC_ACE structure.
-********************************************************************/
-void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
-{
- ace_dest->type = ace_src->type;
- ace_dest->flags = ace_src->flags;
- ace_dest->size = ace_src->size;
- ace_dest->info.mask = ace_src->info.mask;
- ace_dest->obj_flags = ace_src->obj_flags;
- memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, sizeof(struct uuid));
- memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, sizeof(struct uuid));
- sid_copy(&ace_dest->trustee, &ace_src->trustee);
-}
-
-/*******************************************************************
- Sets up a SEC_ACE structure.
-********************************************************************/
-
-void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
-{
- t->type = type;
- t->flags = flag;
- t->size = sid_size(sid) + 8;
- t->info = mask;
-
- ZERO_STRUCTP(&t->trustee);
- sid_copy(&t->trustee, sid);
-}
-
-/*******************************************************************
- adds new SID with its permissions to ACE list
-********************************************************************/
-
-NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
-{
- unsigned int i = 0;
-
- if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
-
- *num += 1;
-
- if((new[0] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 0)
- return NT_STATUS_NO_MEMORY;
-
- for (i = 0; i < *num - 1; i ++)
- sec_ace_copy(&(*new)[i], &old[i]);
-
- (*new)[i].type = 0;
- (*new)[i].flags = 0;
- (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
- (*new)[i].info.mask = mask;
- sid_copy(&(*new)[i].trustee, sid);
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- modify SID's permissions at ACL
-********************************************************************/
-
-NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
-{
- unsigned int i = 0;
-
- if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
-
- for (i = 0; i < num; i ++) {
- if (sid_compare(&ace[i].trustee, sid) == 0) {
- ace[i].info.mask = mask;
- return NT_STATUS_OK;
- }
- }
- return NT_STATUS_NOT_FOUND;
-}
-
-/*******************************************************************
- delete SID from ACL
-********************************************************************/
-
-NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, uint32 *num, DOM_SID *sid)
-{
- unsigned int i = 0;
- unsigned int n_del = 0;
-
- if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
-
- if((new[0] = (SEC_ACE *) talloc_zero(ctx, (*num) * sizeof(SEC_ACE))) == 0)
- return NT_STATUS_NO_MEMORY;
-
- for (i = 0; i < *num; i ++) {
- if (sid_compare(&old[i].trustee, sid) != 0)
- sec_ace_copy(&(*new)[i], &old[i]);
- else
- n_del ++;
- }
- if (n_del == 0)
- return NT_STATUS_NOT_FOUND;
- else {
- *num -= n_del;
- return NT_STATUS_OK;
- }
-}
-
-/*******************************************************************
- Compares two SEC_ACE structures
-********************************************************************/
-
-BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
-{
- /* Trivial case */
-
- if (!s1 && !s2) return True;
-
- /* Check top level stuff */
-
- if (s1->type != s2->type || s1->flags != s2->flags ||
- s1->info.mask != s2->info.mask) {
- return False;
- }
-
- /* Check SID */
-
- if (!sid_equal(&s1->trustee, &s2->trustee)) {
- return False;
- }
-
- return True;
-}
-
-int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
-{
- int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
- int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
-
- if (a1_inh == a2_inh)
- return 0;
-
- if (!a1_inh && a2_inh)
- return -1;
- return 1;
-}
-
-/*******************************************************************
- Comparison function to apply the order explained below in a group.
-*******************************************************************/
-
-int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
-{
- if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
- (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
- return -1;
-
- if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
- (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
- return 1;
-
- /* Both access denied or access allowed. */
-
- /* 1. ACEs that apply to the object itself */
-
- if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
- (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
- return -1;
- else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
- (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
- return 1;
-
- /* 2. ACEs that apply to a subobject of the object, such as
- * a property set or property. */
-
- if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
- !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
- return -1;
- else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
- !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
- return 1;
-
- return 0;
-}
-
-/*******************************************************************
- Functions to convert a SEC_DESC ACE DACL list into canonical order.
- JRA.
-
---- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
-
-The following describes the preferred order:
-
- To ensure that noninherited ACEs have precedence over inherited ACEs,
- place all noninherited ACEs in a group before any inherited ACEs.
- This ordering ensures, for example, that a noninherited access-denied ACE
- is enforced regardless of any inherited ACE that allows access.
-
- Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
- 1. Access-denied ACEs that apply to the object itself
- 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
- 3. Access-allowed ACEs that apply to the object itself
- 4. Access-allowed ACEs that apply to a subobject of the object"
-
-********************************************************************/
-
-void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
-{
- unsigned int i;
-
- if (!srclist || num_aces == 0)
- return;
-
- /* Sort so that non-inherited ACE's come first. */
- qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
-
- /* Find the boundary between non-inherited ACEs. */
- for (i = 0; i < num_aces; i++ ) {
- SEC_ACE *curr_ace = &srclist[i];
-
- if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
- break;
- }
-
- /* i now points at entry number of the first inherited ACE. */
-
- /* Sort the non-inherited ACEs. */
- if (i)
- qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
-
- /* Now sort the inherited ACEs. */
- if (num_aces - i)
- qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
-}
-
-/*******************************************************************
- Check if this ACE has a SID in common with the token.
-********************************************************************/
-
-BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
-{
- size_t i;
-
- for (i = 0; i < token->num_sids; i++) {
- if (sid_equal(&ace->trustee, &token->user_sids[i]))
- return True;
- }
-
- return False;
-}
diff --git a/source/lib/secacl.c b/source/lib/secacl.c
deleted file mode 100644
index 756685a8216..00000000000
--- a/source/lib/secacl.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_ACL handling routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*******************************************************************
- Create a SEC_ACL structure.
-********************************************************************/
-
-SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
-{
- SEC_ACL *dst;
- int i;
-
- if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
- return NULL;
-
- dst->revision = revision;
- dst->num_aces = num_aces;
- dst->size = SEC_ACL_HEADER_SIZE;
-
- /* Now we need to return a non-NULL address for the ace list even
- if the number of aces required is zero. This is because there
- is a distinct difference between a NULL ace and an ace with zero
- entries in it. This is achieved by checking that num_aces is a
- positive number. */
-
- if ((num_aces) &&
- ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
- == NULL)) {
- return NULL;
- }
-
- for (i = 0; i < num_aces; i++) {
- dst->ace[i] = ace_list[i]; /* Structure copy. */
- dst->size += ace_list[i].size;
- }
-
- return dst;
-}
-
-/*******************************************************************
- Duplicate a SEC_ACL structure.
-********************************************************************/
-
-SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
-}
-
-/*******************************************************************
- Compares two SEC_ACL structures
-********************************************************************/
-
-BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
-{
- unsigned int i, j;
-
- /* Trivial cases */
-
- if (!s1 && !s2) return True;
- if (!s1 || !s2) return False;
-
- /* Check top level stuff */
-
- if (s1->revision != s2->revision) {
- DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
- s1->revision, s2->revision));
- return False;
- }
-
- if (s1->num_aces != s2->num_aces) {
- DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
- s1->revision, s2->revision));
- return False;
- }
-
- /* The ACEs could be in any order so check each ACE in s1 against
- each ACE in s2. */
-
- for (i = 0; i < s1->num_aces; i++) {
- BOOL found = False;
-
- for (j = 0; j < s2->num_aces; j++) {
- if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
- found = True;
- break;
- }
- }
-
- if (!found) return False;
- }
-
- return True;
-}
diff --git a/source/lib/secdesc.c b/source/lib/secdesc.c
deleted file mode 100644
index 411185dbfa6..00000000000
--- a/source/lib/secdesc.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_DESC handling functions
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*******************************************************************
- Works out the linearization size of a SEC_DESC.
-********************************************************************/
-
-size_t sec_desc_size(SEC_DESC *psd)
-{
- size_t offset;
-
- if (!psd) return 0;
-
- offset = SEC_DESC_HEADER_SIZE;
-
- /* don't align */
-
- if (psd->owner_sid != NULL)
- offset += sid_size(psd->owner_sid);
-
- if (psd->grp_sid != NULL)
- offset += sid_size(psd->grp_sid);
-
- if (psd->sacl != NULL)
- offset += psd->sacl->size;
-
- if (psd->dacl != NULL)
- offset += psd->dacl->size;
-
- return offset;
-}
-
-/*******************************************************************
- Compares two SEC_DESC structures
-********************************************************************/
-
-BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
-{
- /* Trivial case */
-
- if (!s1 && !s2) {
- goto done;
- }
-
- /* Check top level stuff */
-
- if (s1->revision != s2->revision) {
- DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
- s1->revision, s2->revision));
- return False;
- }
-
- if (s1->type!= s2->type) {
- DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
- s1->type, s2->type));
- return False;
- }
-
- /* Check owner and group */
-
- if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
- fstring str1, str2;
-
- sid_to_string(str1, s1->owner_sid);
- sid_to_string(str2, s2->owner_sid);
-
- DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
- str1, str2));
- return False;
- }
-
- if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
- fstring str1, str2;
-
- sid_to_string(str1, s1->grp_sid);
- sid_to_string(str2, s2->grp_sid);
-
- DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
- str1, str2));
- return False;
- }
-
- /* Check ACLs present in one but not the other */
-
- if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
- (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
- DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
- return False;
- }
-
- /* Sigh - we have to do it the hard way by iterating over all
- the ACEs in the ACLs */
-
- if (!sec_acl_equal(s1->dacl, s2->dacl) ||
- !sec_acl_equal(s1->sacl, s2->sacl)) {
- DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
- return False;
- }
-
- done:
- DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
- return True;
-}
-
-/*******************************************************************
- Merge part of security descriptor old_sec in to the empty sections of
- security descriptor new_sec.
-********************************************************************/
-
-SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
-{
- DOM_SID *owner_sid, *group_sid;
- SEC_DESC_BUF *return_sdb;
- SEC_ACL *dacl, *sacl;
- SEC_DESC *psd = NULL;
- uint16 secdesc_type;
- size_t secdesc_size;
-
- /* Copy over owner and group sids. There seems to be no flag for
- this so just check the pointer values. */
-
- owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
- old_sdb->sec->owner_sid;
-
- group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
- old_sdb->sec->grp_sid;
-
- secdesc_type = new_sdb->sec->type;
-
- /* Ignore changes to the system ACL. This has the effect of making
- changes through the security tab audit button not sticking.
- Perhaps in future Samba could implement these settings somehow. */
-
- sacl = NULL;
- secdesc_type &= ~SEC_DESC_SACL_PRESENT;
-
- /* Copy across discretionary ACL */
-
- if (secdesc_type & SEC_DESC_DACL_PRESENT) {
- dacl = new_sdb->sec->dacl;
- } else {
- dacl = old_sdb->sec->dacl;
- }
-
- /* Create new security descriptor from bits */
-
- psd = make_sec_desc(ctx, new_sdb->sec->revision, secdesc_type,
- owner_sid, group_sid, sacl, dacl, &secdesc_size);
-
- return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
-
- return(return_sdb);
-}
-
-/*******************************************************************
- Creates a SEC_DESC structure
-********************************************************************/
-
-SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
- DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
-{
- SEC_DESC *dst;
- uint32 offset = 0;
-
- *sd_size = 0;
-
- if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
- return NULL;
-
- dst->revision = revision;
- dst->type = type;
-
- if (sacl)
- dst->type |= SEC_DESC_SACL_PRESENT;
- if (dacl)
- dst->type |= SEC_DESC_DACL_PRESENT;
-
- dst->off_owner_sid = 0;
- dst->off_grp_sid = 0;
- dst->off_sacl = 0;
- dst->off_dacl = 0;
-
- if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
- goto error_exit;
-
- if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
- goto error_exit;
-
- if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
- goto error_exit;
-
- if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
- goto error_exit;
-
- offset = SEC_DESC_HEADER_SIZE;
-
- /*
- * Work out the linearization sizes.
- */
-
- if (dst->sacl != NULL) {
- dst->off_sacl = offset;
- offset += dst->sacl->size;
- }
- if (dst->dacl != NULL) {
- dst->off_dacl = offset;
- offset += dst->dacl->size;
- }
-
- if (dst->owner_sid != NULL) {
- dst->off_owner_sid = offset;
- offset += sid_size(dst->owner_sid);
- }
-
- if (dst->grp_sid != NULL) {
- dst->off_grp_sid = offset;
- offset += sid_size(dst->grp_sid);
- }
-
- *sd_size = (size_t)offset;
- return dst;
-
-error_exit:
-
- *sd_size = 0;
- return NULL;
-}
-
-/*******************************************************************
- Duplicate a SEC_DESC structure.
-********************************************************************/
-
-SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
-{
- size_t dummy;
-
- if(src == NULL)
- return NULL;
-
- return make_sec_desc( ctx, src->revision, src->type,
- src->owner_sid, src->grp_sid, src->sacl,
- src->dacl, &dummy);
-}
-
-/*******************************************************************
- Creates a SEC_DESC structure with typical defaults.
-********************************************************************/
-
-SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *dacl, size_t *sd_size)
-{
- return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- owner_sid, grp_sid, NULL, dacl, sd_size);
-}
-
-/*******************************************************************
- Creates a SEC_DESC_BUF structure.
-********************************************************************/
-
-SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
-{
- SEC_DESC_BUF *dst;
-
- if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
- return NULL;
-
- /* max buffer size (allocated size) */
- dst->max_len = (uint32)len;
- dst->len = (uint32)len;
-
- if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
- return NULL;
- }
-
- dst->ptr = 0x1;
-
- return dst;
-}
-
-/*******************************************************************
- Duplicates a SEC_DESC_BUF structure.
-********************************************************************/
-
-SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_desc_buf( ctx, src->len, src->sec);
-}
-
-/*******************************************************************
- Add a new SID with its permissions to SEC_DESC.
-********************************************************************/
-
-NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
-{
- SEC_DESC *sd = 0;
- SEC_ACL *dacl = 0;
- SEC_ACE *ace = 0;
- NTSTATUS status;
-
- *sd_size = 0;
-
- if (!ctx || !psd || !sid || !sd_size)
- return NT_STATUS_INVALID_PARAMETER;
-
- status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
- psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
- return NT_STATUS_UNSUCCESSFUL;
-
- *psd = sd;
- sd = 0;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Modify a SID's permissions in a SEC_DESC.
-********************************************************************/
-
-NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
-{
- NTSTATUS status;
-
- if (!sd || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Delete a SID from a SEC_DESC.
-********************************************************************/
-
-NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
-{
- SEC_DESC *sd = 0;
- SEC_ACL *dacl = 0;
- SEC_ACE *ace = 0;
- NTSTATUS status;
-
- *sd_size = 0;
-
- if (!ctx || !psd[0] || !sid || !sd_size)
- return NT_STATUS_INVALID_PARAMETER;
-
- status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
- psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size)))
- return NT_STATUS_UNSUCCESSFUL;
-
- *psd = sd;
- sd = 0;
- return NT_STATUS_OK;
-}
-
-/* Create a child security descriptor using another security descriptor as
- the parent container. This child object can either be a container or
- non-container object. */
-
-SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
- BOOL child_container)
-{
- SEC_DESC_BUF *sdb;
- SEC_DESC *sd;
- SEC_ACL *new_dacl, *the_acl;
- SEC_ACE *new_ace_list = NULL;
- unsigned int new_ace_list_ndx = 0, i;
- size_t size;
-
- /* Currently we only process the dacl when creating the child. The
- sacl should also be processed but this is left out as sacls are
- not implemented in Samba at the moment.*/
-
- the_acl = parent_ctr->dacl;
-
- if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
- return NULL;
-
- for (i = 0; the_acl && i < the_acl->num_aces; i++) {
- SEC_ACE *ace = &the_acl->ace[i];
- SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
- uint8 new_flags = 0;
- BOOL inherit = False;
- fstring sid_str;
-
- /* The OBJECT_INHERIT_ACE flag causes the ACE to be
- inherited by non-container children objects. Container
- children objects will inherit it as an INHERIT_ONLY
- ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
-
- if (!child_container) {
- new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
- } else {
- new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- }
-
- inherit = True;
- }
-
- /* The CONAINER_INHERIT_ACE flag means all child container
- objects will inherit and use the ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
- if (!child_container) {
- inherit = False;
- } else {
- new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
- }
- }
-
- /* The INHERIT_ONLY_ACE is not used by the se_access_check()
- function for the parent container, but is inherited by
- all child objects as a normal ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
- /* Move along, nothing to see here */
- }
-
- /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
- is inherited by child objects but not grandchildren
- objects. We clear the object inherit and container
- inherit flags in the inherited ACE. */
-
- if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
- new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
- SEC_ACE_FLAG_CONTAINER_INHERIT);
- }
-
- /* Add ACE to ACE list */
-
- if (!inherit)
- continue;
-
- init_sec_access(&new_ace->info, ace->info.mask);
- init_sec_ace(new_ace, &ace->trustee, ace->type,
- new_ace->info, new_flags);
-
- sid_to_string(sid_str, &ace->trustee);
-
- DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
- " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
- ace->type, ace->flags, ace->info.mask,
- sid_str, new_ace->type, new_ace->flags,
- new_ace->info.mask));
-
- new_ace_list_ndx++;
- }
-
- /* Create child security descriptor to return */
-
- new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
-
- /* Use the existing user and group sids. I don't think this is
- correct. Perhaps the user and group should be passed in as
- parameters by the caller? */
-
- sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- parent_ctr->owner_sid,
- parent_ctr->grp_sid,
- parent_ctr->sacl,
- new_dacl, &size);
-
- sdb = make_sec_desc_buf(ctx, size, sd);
-
- return sdb;
-}
-
-/*******************************************************************
- Sets up a SEC_ACCESS structure.
-********************************************************************/
-
-void init_sec_access(SEC_ACCESS *t, uint32 mask)
-{
- t->mask = mask;
-}
-
diff --git a/source/lib/sendfile.c b/source/lib/sendfile.c
index 4aa76a0c74a..ccebd25cc1a 100644
--- a/source/lib/sendfile.c
+++ b/source/lib/sendfile.c
@@ -38,7 +38,7 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
{
size_t total=0;
ssize_t ret;
- size_t hdr_len = 0;
+ ssize_t hdr_len = 0;
/*
* Send the header first.
@@ -161,7 +161,7 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
vec[0].sfv_fd = SFV_FD_SELF;
vec[0].sfv_flag = 0;
- vec[0].sfv_off = (off_t)header->data;
+ vec[0].sfv_off = header->data;
vec[0].sfv_len = hdr_len = header->length;
vec[1].sfv_fd = fromfd;
diff --git a/source/lib/server_mutex.c b/source/lib/server_mutex.c
deleted file mode 100644
index 3e5512c7342..00000000000
--- a/source/lib/server_mutex.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Authenticate against a remote domain
- Copyright (C) Andrew Tridgell 1992-2002
- Copyright (C) Andrew Bartlett 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* For reasons known only to MS, many of their NT/Win2k versions
- need serialised access only. Two connections at the same time
- may (in certain situations) cause connections to be reset,
- or access to be denied.
-
- This locking allows smbd's mutlithread architecture to look
- like the single-connection that NT makes. */
-
-static char *mutex_server_name;
-
-BOOL grab_server_mutex(const char *name)
-{
- mutex_server_name = strdup(name);
- if (!mutex_server_name) {
- DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name));
- return False;
- }
- if (!secrets_named_mutex(mutex_server_name, 10)) {
- DEBUG(10,("grab_server_mutex: failed for %s\n", name));
- SAFE_FREE(mutex_server_name);
- return False;
- }
-
- return True;
-}
-
-void release_server_mutex(void)
-{
- if (mutex_server_name) {
- secrets_named_mutex_release(mutex_server_name);
- SAFE_FREE(mutex_server_name);
- }
-}
diff --git a/source/lib/signal.c b/source/lib/signal.c
index bff4b91c1a0..9c78fad8862 100644
--- a/source/lib/signal.c
+++ b/source/lib/signal.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
signal handling functions
Copyright (C) Andrew Tridgell 1998
@@ -57,6 +58,8 @@ static void sig_cld_leave_status(int signum)
#if !defined(HAVE_SIGACTION)
CatchSignal(SIGCLD, sig_cld_leave_status);
+#else
+ ;
#endif
}
@@ -94,11 +97,10 @@ void BlockSignals(BOOL block,int signum)
2) The signal should be blocked during handler execution.
********************************************************************/
-void (*CatchSignal(int signum,void (*handler)(int )))(int)
+void CatchSignal(int signum,void (*handler)(int ))
{
#ifdef HAVE_SIGACTION
struct sigaction act;
- struct sigaction oldact;
ZERO_STRUCT(act);
@@ -112,11 +114,10 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int)
#endif
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,signum);
- sigaction(signum,&act,&oldact);
- return oldact.sa_handler;
+ sigaction(signum,&act,NULL);
#else /* !HAVE_SIGACTION */
/* FIXME: need to handle sigvec and systems with broken signal() */
- return signal(signum, handler);
+ signal(signum, handler);
#endif
}
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
deleted file mode 100644
index 0a39986364e..00000000000
--- a/source/lib/smbldap.c
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- Unix SMB/CIFS mplementation.
- LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
- Copyright (C) Gerald Carter 2001-2003
- Copyright (C) Shahms King 2001
- Copyright (C) Andrew Bartlett 2002-2003
- Copyright (C) Stefan (metze) Metzmacher 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "includes.h"
-#include "smbldap.h"
-
-#ifndef LDAP_OPT_SUCCESS
-#define LDAP_OPT_SUCCESS 0
-#endif
-
-/* Try not to hit the up or down server forever */
-
-#define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
-#define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
-
-#define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */
-
-
-/* attributes used by Samba 2.2 */
-
-ATTRIB_MAP_ENTRY attrib_map_v22[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
- { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "logonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_PATH, "smbHome" },
- { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
- { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
- { LDAP_ATTR_PROFILE_PATH, "profilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "userWorkstations"},
- { LDAP_ATTR_USER_RID, "rid" },
- { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
- { LDAP_ATTR_LMPW, "lmPassword" },
- { LDAP_ATTR_NTPW, "ntPassword" },
- { LDAP_ATTR_DOMAIN, "domain" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "acctFlags" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used by Samba 3.0's sambaSamAccount */
-
-ATTRIB_MAP_ENTRY attrib_map_v30[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
- { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
- { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
- { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
- { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
- { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
- { LDAP_ATTR_LMPW, "sambaLMPassword" },
- { LDAP_ATTR_NTPW, "sambaNTPassword" },
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
- { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
- { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
- { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used for allocating RIDs */
-
-ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_NEXT_RID, "sambaNextRid" },
- { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
- { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
- { LDAP_ATTR_DOM_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_LIST_END, NULL },
-};
-
-/* Samba 3.0 group mapping attributes */
-
-ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
- { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
- { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_SID_LIST, "sambaSIDList" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
- { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_SID_LIST, "sambaSIDList" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* idmap_ldap sambaUnixIdPool */
-
-ATTRIB_MAP_ENTRY idpool_attr_list[] = {
- { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
- { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
- { LDAP_ATTR_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
- { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* privileges */
-
-ATTRIB_MAP_ENTRY privilege_attr_list[] = {
- { LDAP_ATTR_SID, LDAP_ATTRIBUTE_SID },
- { LDAP_ATTR_PRIV_LIST, "sambaPrivilegeList" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/**********************************************************************
- perform a simple table lookup and return the attribute name
- **********************************************************************/
-
- const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
-{
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- if ( table[i].attrib == key )
- return table[i].name;
- i++;
- }
-
- return NULL;
-}
-
-
-/**********************************************************************
- Return the list of attribute names from a mapping table
- **********************************************************************/
-
- char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
-{
- char **names;
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END )
- i++;
- i++;
-
- names = (char**)malloc( sizeof(char*)*i );
- if ( !names ) {
- DEBUG(0,("get_attr_list: out of memory\n"));
- return NULL;
- }
-
- i = 0;
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- names[i] = strdup( table[i].name );
- i++;
- }
- names[i] = NULL;
-
- return names;
-}
-
-/*********************************************************************
- Cleanup
- ********************************************************************/
-
- void free_attr_list( char **list )
-{
- int i = 0;
-
- if ( !list )
- return;
-
- while ( list[i] ) {
- SAFE_FREE( list[i] );
- i+=1;
- }
-
- SAFE_FREE( list );
-}
-
-/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldap_pw(char **dn, char** pw)
-{
- char *key = NULL;
- size_t size;
-
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
- }
-
- *pw=secrets_fetch(key, &size);
- SAFE_FREE(key);
-
- if (!size) {
- /* Upgrade 2.2 style entry */
- char *p;
- char* old_style_key = strdup(*dn);
- char *data;
- fstring old_style_pw;
-
- if (!old_style_key) {
- DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
- return False;
- }
-
- for (p=old_style_key; *p; p++)
- if (*p == ',') *p = '/';
-
- data=secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
-
- size = MIN(size, sizeof(fstring)-1);
- strncpy(old_style_pw, data, size);
- old_style_pw[size] = 0;
-
- SAFE_FREE(data);
-
- if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
- if (!secrets_delete(old_style_key)) {
- DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
- }
-
- return True;
-}
-
-/*******************************************************************
- Search an attribute and return the first value found.
-******************************************************************/
-
- BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, char *value,
- int max_len)
-{
- char **values;
-
- if ( !attribute )
- return False;
-
- value[0] = '\0';
-
- if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
- DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
-
- return False;
- }
-
- if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {
- DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
- attribute, values[0]));
- ldap_value_free(values);
- return False;
- }
-
- ldap_value_free(values);
-#ifdef DEBUG_PASSWORDS
- DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
-#endif
- return True;
-}
-
- BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, pstring value)
-{
- return smbldap_get_single_attribute(ldap_struct, entry,
- attribute, value,
- sizeof(pstring));
-}
-
-/************************************************************************
- Routine to manage the LDAPMod structure array
- manage memory used by the array, by each struct, and values
- ***********************************************************************/
-
- void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
-{
- LDAPMod **mods;
- int i;
- int j;
-
- mods = *modlist;
-
- /* sanity checks on the mod values */
-
- if (attribute == NULL || *attribute == '\0')
- return;
-#if 0 /* commented out after discussion with abartlet. Do not reenable.
- left here so other so re-add similar code --jerry */
- if (value == NULL || *value == '\0')
- return;
-#endif
-
- if (mods == NULL)
- {
- mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
- if (mods == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[0] = NULL;
- }
-
- for (i = 0; mods[i] != NULL; ++i) {
- if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
- break;
- }
-
- if (mods[i] == NULL)
- {
- mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
- if (mods == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
- if (mods[i] == NULL)
- {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
- }
- mods[i]->mod_op = modop;
- mods[i]->mod_values = NULL;
- mods[i]->mod_type = strdup(attribute);
- mods[i + 1] = NULL;
- }
-
- if (value != NULL)
- {
- char *utf8_value = NULL;
-
- j = 0;
- if (mods[i]->mod_values != NULL) {
- for (; mods[i]->mod_values[j] != NULL; j++);
- }
- mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
- (j + 2) * sizeof (char *));
-
- if (mods[i]->mod_values == NULL) {
- DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
- return;
- }
-
- if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
- DEBUG (0, ("make_a_mod: String conversion failure!\n"));
- return;
- }
-
- mods[i]->mod_values[j] = utf8_value;
-
- mods[i]->mod_values[j + 1] = NULL;
- }
- *modlist = mods;
-}
-
-/**********************************************************************
- Set attribute to newval in LDAP, regardless of what value the
- attribute had in LDAP before.
-*********************************************************************/
-
- void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
- LDAPMod ***mods,
- const char *attribute, const char *newval)
-{
- char oldval[2048]; /* current largest allowed value is mungeddial */
- BOOL existed;
-
- if (existing != NULL) {
- existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
- } else {
- existed = False;
- *oldval = '\0';
- }
-
- /* all of our string attributes are case insensitive */
-
- if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
-
- /* Believe it or not, but LDAP will deny a delete and
- an add at the same time if the values are the
- same... */
- return;
- }
-
- if (existed) {
- /* There has been no value before, so don't delete it.
- * Here's a possible race: We might end up with
- * duplicate attributes */
- /* By deleting exactly the value we found in the entry this
- * should be race-free in the sense that the LDAP-Server will
- * deny the complete operation if somebody changed the
- * attribute behind our back. */
- /* This will also allow modifying single valued attributes
- * in Novell NDS. In NDS you have to first remove attribute and then
- * you could add new value */
-
- smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
- }
-
- /* Regardless of the real operation (add or modify)
- we add the new value here. We rely on deleting
- the old value, should it exist. */
-
- if ((newval != NULL) && (strlen(newval) > 0)) {
- smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
- }
-}
-
-/**********************************************************************
- Some varients of the LDAP rebind code do not pass in the third 'arg'
- pointer to a void*, so we try and work around it by assuming that the
- value of the 'LDAP *' pointer is the same as the one we had passed in
- **********************************************************************/
-
-struct smbldap_state_lookup {
- LDAP *ld;
- struct smbldap_state *smbldap_state;
- struct smbldap_state_lookup *prev, *next;
-};
-
-static struct smbldap_state_lookup *smbldap_state_lookup_list;
-
-static struct smbldap_state *smbldap_find_state(LDAP *ld)
-{
- struct smbldap_state_lookup *t;
-
- for (t = smbldap_state_lookup_list; t; t = t->next) {
- if (t->ld == ld) {
- return t->smbldap_state;
- }
- }
- return NULL;
-}
-
-static void smbldap_delete_state(struct smbldap_state *smbldap_state)
-{
- struct smbldap_state_lookup *t;
-
- for (t = smbldap_state_lookup_list; t; t = t->next) {
- if (t->smbldap_state == smbldap_state) {
- DLIST_REMOVE(smbldap_state_lookup_list, t);
- SAFE_FREE(t);
- return;
- }
- }
-}
-
-static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
-{
- struct smbldap_state *tmp_ldap_state;
- struct smbldap_state_lookup *t;
- struct smbldap_state_lookup *tmp;
-
- if ((tmp_ldap_state = smbldap_find_state(ld))) {
- SMB_ASSERT(tmp_ldap_state == smbldap_state);
- return;
- }
-
- t = smb_xmalloc(sizeof(*t));
- ZERO_STRUCTP(t);
-
- DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
- t->ld = ld;
- t->smbldap_state = smbldap_state;
-}
-
-/*******************************************************************
- open a connection to the ldap server.
-******************************************************************/
-static int smbldap_open_connection (struct smbldap_state *ldap_state)
-
-{
- int rc = LDAP_SUCCESS;
- int version;
- BOOL ldap_v3 = False;
- LDAP **ldap_struct = &ldap_state->ldap_struct;
-
-#ifdef HAVE_LDAP_INITIALIZE
- DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
-
- if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
- DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
- return rc;
- }
-#else
-
- /* Parse the string manually */
-
- {
- int port = 0;
- fstring protocol;
- fstring host;
- const char *p = ldap_state->uri;
- SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
-
- /* skip leading "URL:" (if any) */
- if ( strnequal( p, "URL:", 4 ) ) {
- p += 4;
- }
-
- sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
-
- if (port == 0) {
- if (strequal(protocol, "ldap")) {
- port = LDAP_PORT;
- } else if (strequal(protocol, "ldaps")) {
- port = LDAPS_PORT;
- } else {
- DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
- }
- }
-
- if ((*ldap_struct = ldap_init(host, port)) == NULL) {
- DEBUG(0, ("ldap_init failed !\n"));
- return LDAP_OPERATIONS_ERROR;
- }
-
- if (strequal(protocol, "ldaps")) {
-#ifdef LDAP_OPT_X_TLS
- int tls = LDAP_OPT_X_TLS_HARD;
- if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
- {
- DEBUG(0, ("Failed to setup a TLS session\n"));
- }
-
- DEBUG(3,("LDAPS option set...!\n"));
-#else
- DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
- return LDAP_OPERATIONS_ERROR;
-#endif
- }
- }
-#endif
-
- /* Store the LDAP pointer in a lookup list */
-
- smbldap_store_state(*ldap_struct, ldap_state);
-
- /* Upgrade to LDAPv3 if possible */
-
- if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
- {
- if (version != LDAP_VERSION3)
- {
- version = LDAP_VERSION3;
- if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
- ldap_v3 = True;
- }
- } else {
- ldap_v3 = True;
- }
- }
-
- if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
-#ifdef LDAP_OPT_X_TLS
- if (ldap_v3) {
- if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
- {
- DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
- ldap_err2string(rc)));
- return rc;
- }
- DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
- } else {
-
- DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
- return LDAP_OPERATIONS_ERROR;
- }
-#else
- DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
- return LDAP_OPERATIONS_ERROR;
-#endif
- }
-
- DEBUG(2, ("smbldap_open_connection: connection opened\n"));
- return rc;
-}
-
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
- int *methodp, int freeit, void *arg)
-{
- struct smbldap_state *ldap_state = arg;
-
- /** @TODO Should we be doing something to check what servers we rebind to?
- Could we get a referral to a machine that we don't want to give our
- username and password to? */
-
- if (freeit) {
- SAFE_FREE(*whop);
- memset(*credp, '\0', strlen(*credp));
- SAFE_FREE(*credp);
- } else {
- DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
-
- *whop = strdup(ldap_state->bind_dn);
- if (!*whop) {
- return LDAP_NO_MEMORY;
- }
- *credp = strdup(ldap_state->bind_secret);
- if (!*credp) {
- SAFE_FREE(*whop);
- return LDAP_NO_MEMORY;
- }
- *methodp = LDAP_AUTH_SIMPLE;
- }
-
- gettimeofday(&(ldap_state->last_rebind),NULL);
-
- return 0;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
- and actually does the connection.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int rebindproc_connect_with_state (LDAP *ldap_struct,
- LDAP_CONST char *url,
- ber_tag_t request,
- ber_int_t msgid, void *arg)
-{
- struct smbldap_state *ldap_state = arg;
- int rc;
- DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
-
- /** @TODO Should we be doing something to check what servers we rebind to?
- Could we get a referral to a machine that we don't want to give our
- username and password to? */
-
- rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
-
- gettimeofday(&(ldap_state->last_rebind),NULL);
-
- return rc;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- Add a rebind function for authenticated referrals
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
- int *method, int freeit )
-{
- struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
-
- return rebindproc_with_state(ldap_struct, whop, credp,
- method, freeit, ldap_state);
-
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- this also does the connection, but no void*.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
- ber_int_t msgid)
-{
- struct smbldap_state *ldap_state = smbldap_find_state(ld);
-
- return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
- ldap_state);
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- connect to the ldap server under system privilege.
-******************************************************************/
-static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
-{
- int rc;
- char *ldap_dn;
- char *ldap_secret;
-
- /* get the password */
- if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
- {
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
- return LDAP_INVALID_CREDENTIALS;
- }
-
- ldap_state->bind_dn = ldap_dn;
- ldap_state->bind_secret = ldap_secret;
-
- /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
- (OpenLDAP) doesnt' seem to support it */
-
- DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
- ldap_state->uri, ldap_dn));
-
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2
- ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3
- ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
-# endif
-#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-# if LDAP_SET_REBIND_PROC_ARGS == 2
- ldap_set_rebind_proc(ldap_struct, &rebindproc);
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3
- ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
-# endif
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
- rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(ldap_state->num_failures ? 2 : 0,
- ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
- ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
- ld_error ? ld_error : "(unknown)"));
- SAFE_FREE(ld_error);
- ldap_state->num_failures++;
- return rc;
- }
-
- ldap_state->num_failures = 0;
-
- DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
- return rc;
-}
-
-/**********************************************************************
-Connect to LDAP server (called before every ldap operation)
-*********************************************************************/
-static int smbldap_open(struct smbldap_state *ldap_state)
-{
- int rc;
- SMB_ASSERT(ldap_state);
-
-#ifndef NO_LDAP_SECURITY
- if (geteuid() != 0) {
- DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
- return LDAP_INSUFFICIENT_ACCESS;
- }
-#endif
-
- if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
- struct sockaddr_un addr;
- socklen_t len = sizeof(addr);
- int sd;
- if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
- getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
- /* the other end has died. reopen. */
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- ldap_state->last_ping = (time_t)0;
- } else {
- ldap_state->last_ping = time(NULL);
- }
- }
-
- if (ldap_state->ldap_struct != NULL) {
- DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
- return LDAP_SUCCESS;
- }
-
- if ((rc = smbldap_open_connection(ldap_state))) {
- return rc;
- }
-
- if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- return rc;
- }
-
-
- ldap_state->last_ping = time(NULL);
- DEBUG(4,("The LDAP server is succesful connected\n"));
-
- return LDAP_SUCCESS;
-}
-
-/**********************************************************************
-Disconnect from LDAP server
-*********************************************************************/
-static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
-{
- if (!ldap_state)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (ldap_state->ldap_struct != NULL) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- }
-
- smbldap_delete_state(ldap_state);
-
- DEBUG(5,("The connection to the LDAP server was closed\n"));
- /* maybe free the results here --metze */
-
-
-
- return NT_STATUS_OK;
-}
-
-int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
-{
- int rc;
-
- SMB_ASSERT(ldap_state && attempts);
-
- if (*attempts != 0) {
- unsigned int sleep_time;
- uint8 rand_byte;
-
- /* Sleep for a random timeout */
- rand_byte = (char)(sys_random());
-
- sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
- /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
- on average.
- */
- DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
- sleep_time));
- smb_msleep(sleep_time);
- }
- (*attempts)++;
-
- if ((rc = smbldap_open(ldap_state))) {
- DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
- return rc;
- }
-
- return LDAP_SUCCESS;
-}
-
-
-/*********************************************************************
- ********************************************************************/
-
-int smbldap_search(struct smbldap_state *ldap_state,
- const char *base, int scope, const char *filter,
- char *attrs[], int attrsonly,
- LDAPMessage **res)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_filter;
-
- SMB_ASSERT(ldap_state);
-
- DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n",
- base, filter, scope));
-
- if (ldap_state->last_rebind.tv_sec > 0) {
- struct timeval tval;
- int tdiff = 0;
- int sleep_time = 0;
-
- ZERO_STRUCT(tval);
-
- gettimeofday(&tval,NULL);
-
- tdiff = 1000000 *(tval.tv_sec - ldap_state->last_rebind.tv_sec) +
- (tval.tv_usec - ldap_state->last_rebind.tv_usec);
-
- sleep_time = ((1000*lp_ldap_replication_sleep())-tdiff)/1000;
-
- if (sleep_time > 0) {
- /* we wait for the LDAP replication */
- DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time));
- smb_msleep(sleep_time);
- DEBUG(5,("smbldap_search: go on!\n"));
- ZERO_STRUCT(ldap_state->last_rebind);
- }
- }
-
- if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
- utf8_filter, attrs, attrsonly, res);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
- SAFE_FREE(utf8_filter);
- return rc;
-}
-
-int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-int smbldap_extended_operation(struct smbldap_state *ldap_state,
- LDAP_CONST char *reqoid, struct berval *reqdata,
- LDAPControl **serverctrls, LDAPControl **clientctrls,
- char **retoidp, struct berval **retdatap)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
-
- if (!ldap_state)
- return (-1);
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata,
- serverctrls, clientctrls, retoidp, retdatap);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
- return rc;
-}
-
-/*******************************************************************
- run the search by name.
-******************************************************************/
-int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
- char **search_attr, LDAPMessage ** result)
-{
- int scope = LDAP_SCOPE_SUBTREE;
- int rc;
-
- rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
- SAFE_FREE(ld_error);
- }
-
- return rc;
-}
-
-static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
-{
- struct smbldap_state *state = (struct smbldap_state *)(*data);
-
- if (state->ldap_struct == NULL) {
- DEBUG(10,("ldap connection not connected...\n"));
- return;
- }
-
- if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
- DEBUG(10,("ldap connection not idle...\n"));
- return;
- }
-
- DEBUG(7,("ldap connection idle...closing connection\n"));
- smbldap_close(state);
-}
-
-/**********************************************************************
- Housekeeping
- *********************************************************************/
-
-void smbldap_free_struct(struct smbldap_state **ldap_state)
-{
- smbldap_close(*ldap_state);
-
- if ((*ldap_state)->bind_secret) {
- memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
- }
-
- SAFE_FREE((*ldap_state)->bind_dn);
- SAFE_FREE((*ldap_state)->bind_secret);
-
- smb_unregister_idle_event((*ldap_state)->event_id);
-
- *ldap_state = NULL;
-
- /* No need to free any further, as it is talloc()ed */
-}
-
-
-/**********************************************************************
- Intitalise the 'general' ldap structures, on which ldap operations may be conducted
- *********************************************************************/
-
-NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state)
-{
- *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
- if (!*smbldap_state) {
- DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (location) {
- (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
- } else {
- (*smbldap_state)->uri = "ldap://localhost";
- }
-
- (*smbldap_state)->event_id =
- smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
- SMBLDAP_IDLE_TIME);
-
- if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
- DEBUG(0,("Failed to register LDAP idle event!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX.
-********************************************************************/
-
-char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
-{
- char *utf8_dn, *unix_dn;
-
- utf8_dn = ldap_get_dn(ld, entry);
- if (!utf8_dn) {
- DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
- return NULL;
- }
- if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
- DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
- return NULL;
- }
- ldap_memfree(utf8_dn);
- return unix_dn;
-}
diff --git a/source/lib/smbldap_util.c b/source/lib/smbldap_util.c
deleted file mode 100644
index f6097599bc5..00000000000
--- a/source/lib/smbldap_util.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- Unix SMB/CIFS mplementation.
- LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
- Copyright (C) Gerald Carter 2001-2003
- Copyright (C) Shahms King 2001
- Copyright (C) Andrew Bartlett 2002-2003
- Copyright (C) Stefan (metze) Metzmacher 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "includes.h"
-#include "smbldap.h"
-
-/**********************************************************************
- Add the sambaDomain to LDAP, so we don't have to search for this stuff
- again. This is a once-add operation for now.
-
- TODO: Add other attributes, and allow modification.
-*********************************************************************/
-static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
- const char *domain_name)
-{
- fstring sid_string;
- fstring algorithmic_rid_base_string;
- pstring filter, dn;
- LDAPMod **mods = NULL;
- int rc;
- int ldap_op;
- LDAPMessage *result = NULL;
- int num_result;
- char **attr_list;
- uid_t u_low, u_high;
- gid_t g_low, g_high;
- uint32 rid_low, rid_high;
-
- slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name, LDAP_OBJ_DOMINFO);
-
- attr_list = get_attr_list( dominfo_attr_list );
- rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- num_result = ldap_count_entries(ldap_state->ldap_struct, result);
-
- if (num_result > 1) {
- DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Check if we need to add an entry */
- DEBUG(3,("Adding new domain\n"));
- ldap_op = LDAP_MOD_ADD;
-
- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name, lp_ldap_suffix());
-
- /* Free original search */
- ldap_msgfree(result);
-
- /* make the changes - the entry *must* not already have samba attributes */
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name);
-
- /* If we don't have an entry, then ask secrets.tdb for what it thinks.
- It may choose to make it up */
-
- sid_to_string(sid_string, get_global_sam_sid());
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
-
- slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
- smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
- algorithmic_rid_base_string);
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
-
- /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
- TODO: fix all the places where the line between idmap and normal operations
- needed by smbd gets fuzzy --jerry 2003-08-11 */
-
- if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
- && get_free_rid_range(&rid_low, &rid_high) )
- {
- fstring rid_str;
-
- fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
- DEBUG(10,("setting next available user rid [%s]\n", rid_str));
- smbldap_set_mod(&mods, LDAP_MOD_ADD,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
- rid_str);
-
- fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
- DEBUG(10,("setting next available group rid [%s]\n", rid_str));
- smbldap_set_mod(&mods, LDAP_MOD_ADD,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
- rid_str);
-
- }
-
-
- switch(ldap_op)
- {
- case LDAP_MOD_ADD:
- rc = smbldap_add(ldap_state, dn, mods);
- break;
- case LDAP_MOD_REPLACE:
- rc = smbldap_modify(ldap_state, dn, mods);
- break;
- default:
- DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (rc!=LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n",
- ldap_op == LDAP_MOD_ADD ? "add" : "modify",
- dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
-
- ldap_mods_free(mods, True);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name));
- ldap_mods_free(mods, True);
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
-Search for the domain info entry
-*********************************************************************/
-NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
- LDAPMessage ** result, const char *domain_name,
- BOOL try_add)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- pstring filter;
- int rc;
- char **attr_list;
- int count;
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_DOMINFO,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
- domain_name);
-
- DEBUG(2, ("Searching for:[%s]\n", filter));
-
-
- attr_list = get_attr_list( dominfo_attr_list );
- rc = smbldap_search_suffix(ldap_state, filter, attr_list , result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
- DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
- } else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) {
- DEBUG(3, ("Got no domain info entries for domain\n"));
- ldap_msgfree(*result);
- *result = NULL;
- if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) {
- return smbldap_search_domain_info(ldap_state, result, domain_name, False);
- }
- else {
- DEBUG(0, ("Adding domain info for %s failed with %s\n",
- domain_name, nt_errstr(ret)));
- return ret;
- }
- } else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) {
- DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
- count, domain_name));
- ldap_msgfree(*result);
- *result = NULL;
- return ret;
- } else {
- return NT_STATUS_OK;
- }
-
- return ret;
-}
-
diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c
index 592543bc43b..1ace6e3a991 100644
--- a/source/lib/smbrun.c
+++ b/source/lib/smbrun.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
run a command as a specified user
Copyright (C) Andrew Tridgell 1992-1998
@@ -143,7 +144,7 @@ int smbrun(char *cmd, int *outfd)
/* point our stdout at the file we want output to go into */
if (outfd) {
close(1);
- if (sys_dup2(*outfd,1) != 1) {
+ if (dup2(*outfd,1) != 1) {
DEBUG(2,("Failed to create stdout file descriptor\n"));
close(*outfd);
exit(80);
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index 5b0cfa1ab33..2f738cdbba2 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -1,8 +1,4 @@
/*
- * NOTE: If you change this file, please merge it into rsync, samba, etc.
- */
-
-/*
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell (papowell@astart.com)
* It may be used for any purpose as long as this notice remains intact
@@ -57,57 +53,17 @@
* got rid of fcvt code (twas buggy and made testing harder)
* added C99 semantics
*
- * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0
- * actually print args for %g and %e
- *
- * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0
- * Since includes.h isn't included here, VA_COPY has to be defined here. I don't
- * see any include file that is guaranteed to be here, so I'm defining it
- * locally. Fixes AIX and Solaris builds.
- *
- * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13
- * put the ifdef for HAVE_VA_COPY in one place rather than in lots of
- * functions
- *
- * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4
- * Fix usage of va_list passed as an arg. Use __va_copy before using it
- * when it exists.
- *
- * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14
- * Fix incorrect zpadlen handling in fmtfp.
- * Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it.
- * few mods to make it easier to compile the tests.
- * addedd the "Ollie" test to the floating point ones.
- *
- * Martin Pool (mbp@samba.org) April 2003
- * Remove NO_CONFIG_H so that the test case can be built within a source
- * tree with less trouble.
- * Remove unnecessary SAFE_FREE() definition.
- *
- * Martin Pool (mbp@samba.org) May 2003
- * Put in a prototype for dummy_snprintf() to quiet compiler warnings.
- *
- * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even
- * if the C library has some snprintf functions already.
**************************************************************/
-#ifndef NO_CONFIG_H
+#ifndef NO_CONFIG_H /* for some tests */
#include "config.h"
#else
#define NULL 0
-#endif
+#endif
#ifdef TEST_SNPRINTF /* need math library headers for testing */
-
-/* In test mode, we pretend that this system doesn't have any snprintf
- * functions, regardless of what config.h says. */
-# undef HAVE_SNPRINTF
-# undef HAVE_VSNPRINTF
-# undef HAVE_C99_VSNPRINTF
-# undef HAVE_ASPRINTF
-# undef HAVE_VASPRINTF
-# include <math.h>
-#endif /* TEST_SNPRINTF */
+#include <math.h>
+#endif
#ifdef HAVE_STRING_H
#include <string.h>
@@ -129,9 +85,8 @@
/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
#include <stdio.h>
/* make the compiler happy with an empty file */
- void dummy_snprintf(void);
void dummy_snprintf(void) {}
-#endif /* HAVE_SNPRINTF, etc */
+#else
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
@@ -145,17 +100,29 @@
#define LLONG long
#endif
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
-#define VA_COPY(dest, src) va_copy(dest, src)
-#else
-#ifdef HAVE___VA_COPY
#define VA_COPY(dest, src) __va_copy(dest, src)
#else
#define VA_COPY(dest, src) (dest) = (src)
#endif
#endif
+static size_t dopr(char *buffer, size_t maxlen, const char *format,
+ va_list args_in);
+static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
+ char *value, int flags, int min, int max);
+static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
+ long value, int base, int min, int max, int flags);
+static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
+ LDOUBLE fvalue, int min, int max, int flags);
+static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
+
/*
* dopr(): poor man's version of doprintf
*/
@@ -190,19 +157,6 @@
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
#endif
-/* yes this really must be a ||. Don't muck with this (tridge) */
-#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-
-static size_t dopr(char *buffer, size_t maxlen, const char *format,
- va_list args_in);
-static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max);
-static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
-
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in)
{
char ch;
@@ -216,9 +170,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
int cflags;
size_t currlen;
va_list args;
-
- VA_COPY(args, args_in);
+ VA_COPY(args, args_in);
+
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
@@ -669,7 +623,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int caps = 0;
- int idx;
+ int index;
double intpart;
double fracpart;
double temp;
@@ -728,11 +682,11 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
do {
temp = intpart*0.1;
my_modf(temp, &intpart);
- idx = (int) ((temp -intpart +0.05)* 10.0);
- /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
- /* printf ("%llf, %f, %x\n", temp, intpart, idx); */
+ index = (int) ((temp -intpart +0.05)* 10.0);
+ /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
+ /* printf ("%llf, %f, %x\n", temp, intpart, index); */
iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while (intpart && (iplace < 311));
if (iplace == 311) iplace--;
iconvert[iplace] = 0;
@@ -743,11 +697,11 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
do {
temp = fracpart*0.1;
my_modf(temp, &fracpart);
- idx = (int) ((temp -fracpart +0.05)* 10.0);
- /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */
- /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */
+ index = (int) ((temp -fracpart +0.05)* 10.0);
+ /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
+ /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while(fracpart && (fplace < 311));
if (fplace == 311) fplace--;
}
@@ -817,20 +771,24 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
(*currlen)++;
}
+/* yes this really must be a ||. Don't muck with this (tridge) */
+#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
return dopr(str, count, fmt, args);
}
#endif
-/* yes this really must be a ||. Don't muck with this (tridge)
+/* yes this really must be a ||. Don't muck wiith this (tridge)
*
* The logic for these two is that we need our own definition if the
* OS *either* has no definition of *sprintf, or if it does have one
- * that doesn't work properly according to the autoconf test.
+ * that doesn't work properly according to the autoconf test. Perhaps
+ * these should really be smb_snprintf to avoid conflicts with buggy
+ * linkers? -- mbp
*/
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
-int smb_snprintf(char *str,size_t count,const char *fmt,...)
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF)
+ int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
va_list ap;
@@ -849,17 +807,14 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...)
{
int ret;
va_list ap2;
-
- VA_COPY(ap2, ap);
+ VA_COPY(ap2, ap);
ret = vsnprintf(NULL, 0, format, ap2);
if (ret <= 0) return ret;
(*ptr) = (char *)malloc(ret+1);
if (!*ptr) return -1;
-
VA_COPY(ap2, ap);
-
ret = vsnprintf(*ptr, ret+1, format, ap2);
return ret;
@@ -882,6 +837,20 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...)
}
#endif
+#ifndef HAVE_VSYSLOG
+#ifdef HAVE_SYSLOG
+ void vsyslog (int facility_priority, char *format, va_list arglist)
+{
+ char *msg = NULL;
+ vasprintf(&msg, format, arglist);
+ if (!msg)
+ return;
+ syslog(facility_priority, "%s", msg);
+ SAFE_FREE(msg);
+}
+#endif /* HAVE_SYSLOG */
+#endif /* HAVE_VSYSLOG */
+
#ifdef TEST_SNPRINTF
int sprintf(char *str,const char *fmt,...);
@@ -908,9 +877,8 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...)
"-16.16f",
NULL
};
- double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996,
- 0.9996, 1.996, 4.136, 5.030201, 0.00205,
- /* END LIST */ 0};
+ double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
+ 0.9996, 1.996, 4.136, 5.030201, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
@@ -1018,4 +986,4 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...)
return 0;
}
-#endif /* TEST_SNPRINTF */
+#endif /* SNPRINTF_TEST */
diff --git a/source/lib/sock_exec.c b/source/lib/sock_exec.c
deleted file mode 100644
index 52c5a8ce52c..00000000000
--- a/source/lib/sock_exec.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Tim Potter 2000-2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*******************************************************************
-this is like socketpair but uses tcp. It is used by the Samba
-regression test code
-The function guarantees that nobody else can attach to the socket,
-or if they do that this function fails and the socket gets closed
-returns 0 on success, -1 on failure
-the resulting file descriptors are symmetrical
- ******************************************************************/
-static int socketpair_tcp(int fd[2])
-{
- int listener;
- struct sockaddr_in sock;
- struct sockaddr_in sock2;
- socklen_t socklen = sizeof(sock);
- int connect_done = 0;
-
- fd[0] = fd[1] = listener = -1;
-
- memset(&sock, 0, sizeof(sock));
-
- if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
-
- memset(&sock2, 0, sizeof(sock2));
-#ifdef HAVE_SOCK_SIN_LEN
- sock2.sin_len = sizeof(sock2);
-#endif
- sock2.sin_family = PF_INET;
-
- bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
-
- if (listen(listener, 1) != 0) goto failed;
-
- if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
-
- if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
-
- set_blocking(fd[1], 0);
-
- sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
- if (errno != EINPROGRESS) goto failed;
- } else {
- connect_done = 1;
- }
-
- if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
-
- close(listener);
- if (connect_done == 0) {
- if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
- && errno != EISCONN) goto failed;
- }
-
- set_blocking(fd[1], 1);
-
- /* all OK! */
- return 0;
-
- failed:
- if (fd[0] != -1) close(fd[0]);
- if (fd[1] != -1) close(fd[1]);
- if (listener != -1) close(listener);
- return -1;
-}
-
-
-/*******************************************************************
-run a program on a local tcp socket, this is used to launch smbd
-when regression testing
-the return value is a socket which is attached to a subprocess
-running "prog". stdin and stdout are attached. stderr is left
-attached to the original stderr
- ******************************************************************/
-int sock_exec(const char *prog)
-{
- int fd[2];
- if (socketpair_tcp(fd) != 0) {
- DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
- return -1;
- }
- if (fork() == 0) {
- close(fd[0]);
- close(0);
- close(1);
- dup(fd[1]);
- dup(fd[1]);
- exit(system(prog));
- }
- close(fd[1]);
- return fd[0];
-}
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index fed11c22982..97250bc9780 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
string substitution functions
Copyright (C) Andrew Tridgell 1992-2000
@@ -24,115 +25,34 @@
fstring local_machine="";
fstring remote_arch="UNKNOWN";
userdom_struct current_user_info;
+pstring samlogon_user="";
+BOOL sam_logon_in_ssb = False;
fstring remote_proto="UNKNOWN";
-
-static fstring remote_machine;
+fstring remote_machine="";
static fstring smb_user_name;
-/**
- * Set the 'local' machine name
- * @param local_name the name we are being called
- * @param if this is the 'final' name for us, not be be changed again
- */
-
-void set_local_machine_name(const char* local_name, BOOL perm)
-{
- static BOOL already_perm = False;
- fstring tmp_local_machine;
-
- /*
- * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
- * arrggg!!!
- */
-
- if (strequal(local_name, "*SMBSERVER"))
- return;
-
- if (strequal(local_name, "*SMBSERV"))
- return;
-
- if (already_perm)
- return;
-
- already_perm = perm;
-
- fstrcpy(tmp_local_machine,local_name);
- trim_char(tmp_local_machine,' ',' ');
- alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
- strlower_m(local_machine);
-}
-
-/**
- * Set the 'remote' machine name
- * @param remote_name the name our client wants to be called by
- * @param if this is the 'final' name for them, not be be changed again
- */
-
-void set_remote_machine_name(const char* remote_name, BOOL perm)
-{
- static BOOL already_perm = False;
- fstring tmp_remote_machine;
-
- if (already_perm)
- return;
-
- already_perm = perm;
-
- fstrcpy(tmp_remote_machine,remote_name);
- trim_char(tmp_remote_machine,' ',' ');
- alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
- strlower_m(remote_machine);
-}
-
-const char* get_remote_machine_name(void)
-{
- return remote_machine;
-}
-
-const char* get_local_machine_name(void)
-{
- if (!*local_machine) {
- return global_myname();
- }
-
- return local_machine;
-}
-
-/*******************************************************************
- Setup the string used by %U substitution.
-********************************************************************/
+/*
+ setup the string used by %U substitution
+*/
void sub_set_smb_name(const char *name)
{
fstring tmp;
- /* don't let anonymous logins override the name */
- if (! *name)
- return;
+ /* ignore anonymous settings */
+ if (! *name) return;
fstrcpy(tmp,name);
- trim_char(tmp,' ',' ');
- strlower_m(tmp);
+ trim_string(tmp," "," ");
+ strlower(tmp);
alpha_strcpy(smb_user_name,tmp,SAFE_NETBIOS_CHARS,sizeof(smb_user_name)-1);
}
-char* sub_get_smb_name( void )
+const char* get_remote_machine_name(void)
{
- return smb_user_name;
+ return remote_machine;
}
-/*******************************************************************
- Setup the strings used by substitutions. Called per packet. Ensure
- %U name is set correctly also.
-********************************************************************/
-
-void set_current_user_info(const userdom_struct *pcui)
-{
- current_user_info = *pcui;
- /* The following is safe as current_user_info.smb_name
- * has already been sanitised in register_vuid. */
- fstrcpy(smb_user_name, current_user_info.smb_name);
-}
/*******************************************************************
Given a pointer to a %$(NAME) expand it as an environment variable.
@@ -158,7 +78,7 @@ static size_t expand_env_var(char *p, int len)
* Look for the terminating ')'.
*/
- if ((q = strchr_m(p,')')) == NULL) {
+ if ((q = strchr(p,')')) == NULL) {
DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
return 2;
}
@@ -190,71 +110,11 @@ static size_t expand_env_var(char *p, int len)
}
/*******************************************************************
- Given a pointer to a %$(NAME) in p and the whole string in str
- expand it as an environment variable.
- Return a new allocated and expanded string.
- Based on code by Branko Cibej <branko.cibej@hermes.si>
- When this is called p points at the '%' character.
- May substitute multiple occurrencies of the same env var.
-********************************************************************/
-
-
-static char * realloc_expand_env_var(char *str, char *p)
-{
- char *envname;
- char *envval;
- char *q, *r;
- int copylen;
-
- if (p[0] != '%' || p[1] != '$' || p[2] != '(')
- return str;
-
- /*
- * Look for the terminating ')'.
- */
-
- if ((q = strchr_m(p,')')) == NULL) {
- DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
- return str;
- }
-
- /*
- * Extract the name from within the %$(NAME) string.
- */
-
- r = p + 3;
- copylen = q - r;
- envname = (char *)malloc(copylen + 1 + 4); /* reserve space for use later add %$() chars */
- if (envname == NULL) return NULL;
- strncpy(envname,r,copylen);
- envname[copylen] = '\0';
-
- if ((envval = getenv(envname)) == NULL) {
- DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
- SAFE_FREE(envname);
- return str;
- }
-
- /*
- * Copy the full %$(NAME) into envname so it
- * can be replaced.
- */
-
- copylen = q + 1 - p;
- strncpy(envname,p,copylen);
- envname[copylen] = '\0';
- r = realloc_string_sub(str, envname, envval);
- SAFE_FREE(envname);
- if (r == NULL) return NULL;
- return r;
-}
-
-/*******************************************************************
Patch from jkf@soton.ac.uk
Added this to implement %p (NIS auto-map version of %H)
*******************************************************************/
-static char *automount_path(const char *user_name)
+static char *automount_path(char *user_name)
{
static pstring server_path;
@@ -270,7 +130,7 @@ static char *automount_path(const char *user_name)
char *automount_value = automount_lookup(user_name);
if(strlen(automount_value) > 0) {
- home_path_start = strchr_m(automount_value,':');
+ home_path_start = strchr(automount_value,':');
if (home_path_start != NULL) {
DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
home_path_start?(home_path_start+1):""));
@@ -294,18 +154,18 @@ static char *automount_path(const char *user_name)
moved out to a separate function.
*******************************************************************/
-static const char *automount_server(const char *user_name)
+static char *automount_server(char *user_name)
{
+ extern pstring global_myname;
static pstring server_name;
- const char *local_machine_name = get_local_machine_name();
/* use the local machine name as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
- if (local_machine_name && *local_machine_name)
- pstrcpy(server_name, local_machine_name);
+ if (*local_machine)
+ pstrcpy(server_name, local_machine);
else
- pstrcpy(server_name, global_myname());
-
+ pstrcpy(server_name, global_myname);
+
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map()) {
@@ -327,34 +187,29 @@ static const char *automount_server(const char *user_name)
/****************************************************************************
Do some standard substitutions in a string.
- len is the length in bytes of the space allowed in string str. If zero means
- don't allow expansions.
****************************************************************************/
-void standard_sub_basic(const char *smb_name, char *str,size_t len)
+void standard_sub_basic(char *str, int len)
{
+ extern pstring global_myname;
char *p, *s;
fstring pidstr;
struct passwd *pass;
- const char *local_machine_name = get_local_machine_name();
- for (s=str; (p=strchr_m(s, '%'));s=p) {
+ for (s=str; (p=strchr(s, '%'));s=p) {
fstring tmp_str;
- int l = (int)len - (int)(p-str);
-
- if (l < 0)
- l = 0;
+ int l = len - (int)(p-str);
switch (*(p+1)) {
case 'U' :
- fstrcpy(tmp_str, smb_name);
- strlower_m(tmp_str);
+ fstrcpy(tmp_str, sam_logon_in_ssb?samlogon_user:smb_user_name);
+ strlower(tmp_str);
string_sub(p,"%U",tmp_str,l);
break;
case 'G' :
- fstrcpy(tmp_str, smb_name);
- if ((pass = Get_Pwnam(tmp_str))!=NULL) {
+ fstrcpy(tmp_str, sam_logon_in_ssb?samlogon_user:smb_user_name);
+ if ((pass = Get_Pwnam(tmp_str, False))!=NULL) {
string_sub(p,"%G",gidtoname(pass->pw_gid),l);
} else {
p += 2;
@@ -362,54 +217,33 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
break;
case 'D' :
fstrcpy(tmp_str, current_user_info.domain);
- strupper_m(tmp_str);
+ strupper(tmp_str);
string_sub(p,"%D", tmp_str,l);
break;
- case 'I' :
- string_sub(p,"%I", client_addr(),l);
- break;
- case 'i' :
- string_sub(p,"%i", client_socket_addr(),l);
- break;
+ case 'I' : string_sub(p,"%I", client_addr(),l); break;
case 'L' :
- if (local_machine_name && *local_machine_name)
- string_sub(p,"%L", local_machine_name,l);
+ if (*local_machine)
+ string_sub(p,"%L", local_machine,l);
else {
pstring temp_name;
- pstrcpy(temp_name, global_myname());
- strlower_m(temp_name);
+ pstrcpy(temp_name, global_myname);
+ strlower(temp_name);
string_sub(p,"%L", temp_name,l);
}
break;
- case 'M' :
- string_sub(p,"%M", client_name(),l);
- break;
- case 'R' :
- string_sub(p,"%R", remote_proto,l);
- break;
- case 'T' :
- string_sub(p,"%T", timestring(False),l);
- break;
- case 'a' :
- string_sub(p,"%a", remote_arch,l);
- break;
+ case 'M' : string_sub(p,"%M", client_name(),l); break;
+ case 'R' : string_sub(p,"%R", remote_proto,l); break;
+ case 'T' : string_sub(p,"%T", timestring(False),l); break;
+ case 'a' : string_sub(p,"%a", remote_arch,l); break;
case 'd' :
slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid());
string_sub(p,"%d", pidstr,l);
break;
- case 'h' :
- string_sub(p,"%h", myhostname(),l);
- break;
- case 'm' :
- string_sub(p,"%m", get_remote_machine_name(),l);
- break;
- case 'v' :
- string_sub(p,"%v", SAMBA_VERSION_STRING,l);
- break;
- case '$' :
- p += expand_env_var(p,l);
- break; /* Expand environment variables */
+ case 'h' : string_sub(p,"%h", myhostname(),l); break;
+ case 'm' : string_sub(p,"%m", remote_machine,l); break;
+ case 'v' : string_sub(p,"%v", VERSION,l); break;
+ case '$' : p += expand_env_var(p,l); break; /* Expand environment variables */
case '\0':
p++;
break; /* don't run off the end of the string */
@@ -420,34 +254,34 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
}
}
-static void standard_sub_advanced(int snum, const char *user,
- const char *connectpath, gid_t gid,
- const char *smb_name, char *str, size_t len)
+/****************************************************************************
+ Do some standard substitutions in a string.
+****************************************************************************/
+
+void standard_sub_advanced(int snum, char *user, const char *connectpath, gid_t gid, char *str, int len)
{
char *p, *s, *home;
- for (s=str; (p=strchr_m(s, '%'));s=p) {
- int l = (int)len - (int)(p-str);
-
- if (l < 0)
- l = 0;
-
+ for (s=str; (p=strchr(s, '%'));s=p) {
+ int l = len - (int)(p-str);
+
switch (*(p+1)) {
- case 'N' :
- string_sub(p,"%N", automount_server(user),l);
- break;
+ case 'N' : string_sub(p,"%N", automount_server(user),l); break;
case 'H':
- if ((home = get_user_home_dir(user)))
+ if ((home = get_user_home_dir(user))) {
string_sub(p,"%H",home, l);
- else
+ } else {
p += 2;
+ }
break;
case 'P':
string_sub(p,"%P", connectpath, l);
break;
+
case 'S':
string_sub(p,"%S", lp_servicename(snum), l);
break;
+
case 'g':
string_sub(p,"%g", gidtoname(gid), l);
break;
@@ -474,317 +308,54 @@ static void standard_sub_advanced(int snum, const char *user,
}
}
- standard_sub_basic(smb_name, str, len);
+ standard_sub_basic(str,len);
}
/****************************************************************************
Do some standard substitutions in a string.
- This function will return an allocated string that have to be freed.
****************************************************************************/
-char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str)
+void standard_sub_conn(connection_struct *conn, char *str, int len)
{
- char *a, *t;
- a = alloc_sub_basic(smb_name, str);
- if (!a) return NULL;
- t = talloc_strdup(mem_ctx, a);
- SAFE_FREE(a);
- return t;
-}
-
-char *alloc_sub_basic(const char *smb_name, const char *str)
-{
- char *b, *p, *s, *t, *r, *a_string;
- fstring pidstr;
- struct passwd *pass;
- const char *local_machine_name = get_local_machine_name();
-
- /* workaround to prevent a crash while lookinf at bug #687 */
-
- if ( !str ) {
- DEBUG(0,("alloc_sub_basic: NULL source string! This should not happen\n"));
- return NULL;
- }
-
- a_string = strdup(str);
- if (a_string == NULL) {
- DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
- return NULL;
- }
-
- for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
-
- r = NULL;
- b = t = a_string;
-
- switch (*(p+1)) {
- case 'U' :
- r = strdup_lower(smb_name);
- if (r == NULL) goto error;
- t = realloc_string_sub(t, "%U", r);
- break;
- case 'G' :
- r = strdup(smb_name);
- if (r == NULL) goto error;
- if ((pass = Get_Pwnam(r))!=NULL) {
- t = realloc_string_sub(t, "%G", gidtoname(pass->pw_gid));
- }
- break;
- case 'D' :
- r = strdup_upper(current_user_info.domain);
- if (r == NULL) goto error;
- t = realloc_string_sub(t, "%D", r);
- break;
- case 'I' :
- t = realloc_string_sub(t, "%I", client_addr());
- break;
- case 'L' :
- if (local_machine_name && *local_machine_name)
- t = realloc_string_sub(t, "%L", local_machine_name);
- else
- t = realloc_string_sub(t, "%L", global_myname());
- break;
- case 'N':
- t = realloc_string_sub(t, "%N", automount_server(smb_name));
- break;
- case 'M' :
- t = realloc_string_sub(t, "%M", client_name());
- break;
- case 'R' :
- t = realloc_string_sub(t, "%R", remote_proto);
- break;
- case 'T' :
- t = realloc_string_sub(t, "%T", timestring(False));
- break;
- case 'a' :
- t = realloc_string_sub(t, "%a", remote_arch);
- break;
- case 'd' :
- slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid());
- t = realloc_string_sub(t, "%d", pidstr);
- break;
- case 'h' :
- t = realloc_string_sub(t, "%h", myhostname());
- break;
- case 'm' :
- t = realloc_string_sub(t, "%m", remote_machine);
- break;
- case 'v' :
- t = realloc_string_sub(t, "%v", SAMBA_VERSION_STRING);
- break;
- case '$' :
- t = realloc_expand_env_var(t, p); /* Expand environment variables */
- break;
-
- default:
- break;
- }
-
- p++;
- SAFE_FREE(r);
- if (t == NULL) goto error;
- a_string = t;
- }
-
- return a_string;
-error:
- SAFE_FREE(a_string);
- return NULL;
+ standard_sub_advanced(SNUM(conn), conn->user, conn->connectpath, conn->gid, str, len);
}
/****************************************************************************
- Do some specific substitutions in a string.
- This function will return an allocated string that have to be freed.
+ Like standard_sub but for a homes share where snum still points to the [homes]
+ share. No user specific snum created yet so servicename should be the username.
****************************************************************************/
-char *talloc_sub_specified(TALLOC_CTX *mem_ctx,
- const char *input_string,
- const char *username,
- const char *domain,
- uid_t uid,
- gid_t gid)
-{
- char *a, *t;
- a = alloc_sub_specified(input_string, username, domain, uid, gid);
- if (!a) return NULL;
- t = talloc_strdup(mem_ctx, a);
- SAFE_FREE(a);
- return t;
-}
-
-char *alloc_sub_specified(const char *input_string,
- const char *username,
- const char *domain,
- uid_t uid,
- gid_t gid)
-{
- char *a_string, *ret_string;
- char *b, *p, *s, *t;
-
- a_string = strdup(input_string);
- if (a_string == NULL) {
- DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
- return NULL;
- }
-
- for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
-
- b = t = a_string;
-
- switch (*(p+1)) {
- case 'U' :
- t = realloc_string_sub(t, "%U", username);
- break;
- case 'u' :
- t = realloc_string_sub(t, "%u", username);
- break;
- case 'G' :
- if (gid != -1) {
- t = realloc_string_sub(t, "%G", gidtoname(gid));
- } else {
- t = realloc_string_sub(t, "%G", "NO_GROUP");
- }
- break;
- case 'g' :
- if (gid != -1) {
- t = realloc_string_sub(t, "%g", gidtoname(gid));
- } else {
- t = realloc_string_sub(t, "%g", "NO_GROUP");
- }
- break;
- case 'D' :
- t = realloc_string_sub(t, "%D", domain);
- break;
- case 'N' :
- t = realloc_string_sub(t, "%N", automount_server(username));
- break;
- default:
- break;
- }
-
- p++;
- if (t == NULL) {
- SAFE_FREE(a_string);
- return NULL;
- }
- a_string = t;
- }
-
- ret_string = alloc_sub_basic(username, a_string);
- SAFE_FREE(a_string);
- return ret_string;
-}
-
-char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
- int snum,
- const char *user,
- const char *connectpath,
- gid_t gid,
- const char *smb_name,
- const char *str)
+void standard_sub_home(int snum, char *user, char *str, int len)
{
- char *a, *t;
- a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str);
- if (!a) return NULL;
- t = talloc_strdup(mem_ctx, a);
- SAFE_FREE(a);
- return t;
-}
-
-char *alloc_sub_advanced(int snum, const char *user,
- const char *connectpath, gid_t gid,
- const char *smb_name, const char *str)
-{
- char *a_string, *ret_string;
- char *b, *p, *s, *t, *h;
+ char *p, *s;
- a_string = strdup(str);
- if (a_string == NULL) {
- DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
- return NULL;
- }
-
- for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
-
- b = t = a_string;
+ for (s=str; (p=strchr(s, '%'));s=p) {
+ int l = len - (int)(p-str);
switch (*(p+1)) {
- case 'N' :
- t = realloc_string_sub(t, "%N", automount_server(user));
- break;
- case 'H':
- if ((h = get_user_home_dir(user)))
- t = realloc_string_sub(t, "%H", h);
- break;
- case 'P':
- t = realloc_string_sub(t, "%P", connectpath);
- break;
case 'S':
- t = realloc_string_sub(t, "%S", lp_servicename(snum));
+ string_sub(p,"%S", user, l);
break;
- case 'g':
- t = realloc_string_sub(t, "%g", gidtoname(gid));
- break;
- case 'u':
- t = realloc_string_sub(t, "%u", user);
- break;
-
- /* Patch from jkf@soton.ac.uk Left the %N (NIS
- * server name) in standard_sub_basic as it is
- * a feature for logon servers, hence uses the
- * username. The %p (NIS server path) code is
- * here as it is used instead of the default
- * "path =" string in [homes] and so needs the
- * service name, not the username. */
case 'p':
- t = realloc_string_sub(t, "%p", automount_path(lp_servicename(snum)));
+ string_sub(p,"%p", automount_path(user), l);
break;
+ case '\0':
+ p++;
+ break; /* don't run off the end of the string */
- default:
+ default: p+=2;
break;
}
-
- p++;
- if (t == NULL) {
- SAFE_FREE(a_string);
- return NULL;
- }
- a_string = t;
}
- ret_string = alloc_sub_basic(smb_name, a_string);
- SAFE_FREE(a_string);
- return ret_string;
-}
-
-/****************************************************************************
- Do some standard substitutions in a string.
-****************************************************************************/
-
-void standard_sub_conn(connection_struct *conn, char *str, size_t len)
-{
- standard_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
- conn->gid, smb_user_name, str, len);
-}
-
-char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
-{
- return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
- conn->connectpath, conn->gid,
- smb_user_name, str);
-}
-
-char *alloc_sub_conn(connection_struct *conn, const char *str)
-{
- return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
- conn->gid, smb_user_name, str);
+ standard_sub_advanced(snum, user, "", -1, str, len);
}
/****************************************************************************
Like standard_sub but by snum.
****************************************************************************/
-void standard_sub_snum(int snum, char *str, size_t len)
+void standard_sub_snum(int snum, char *str, int len)
{
extern struct current_user current_user;
static uid_t cached_uid = -1;
@@ -797,6 +368,23 @@ void standard_sub_snum(int snum, char *str, size_t len)
cached_uid = current_user.uid;
}
- standard_sub_advanced(snum, cached_user, "", -1,
- smb_user_name, str, len);
+ standard_sub_advanced(snum, cached_user, "", -1, str, len);
+}
+
+/*******************************************************************
+ Substitute strings with useful parameters.
+********************************************************************/
+
+void standard_sub_vuser(char *str, int len, user_struct *vuser)
+{
+ standard_sub_advanced(-1, vuser->user.unix_name, "", -1, str, len);
+}
+
+/*******************************************************************
+ Substitute strings with useful parameters.
+********************************************************************/
+
+void standard_sub_vsnum(char *str, int len, user_struct *vuser, int snum)
+{
+ standard_sub_advanced(snum, vuser->user.unix_name, "", -1, str, len);
}
diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c
index 00d06e4a5ae..21814383697 100644
--- a/source/lib/sysacls.c
+++ b/source/lib/sysacls.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.
Samba system utilities for ACL support.
Copyright (C) Jeremy Allison 2000.
@@ -158,7 +159,7 @@ int sys_acl_valid( SMB_ACL_T theacl )
return acl_valid(theacl);
}
-int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
{
return acl_set_file(name, acltype, theacl);
}
@@ -644,7 +645,13 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
break;
case SMB_ACL_USER:
- id = uidtoname(ap->a_id);
+ if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
+ slprintf(idbuf, sizeof(idbuf)-1, "%ld",
+ (long)ap->a_id);
+ id = idbuf;
+ } else {
+ id = pw->pw_name;
+ }
case SMB_ACL_USER_OBJ:
tag = "user";
break;
@@ -1197,7 +1204,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
* can use the relative path.
*/
- return sys_acl_get_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
+ return sys_acl_get_file(dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_ACCESS);
}
int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
@@ -1275,7 +1282,13 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
break;
case SMB_ACL_USER:
- id = uidtoname(ap->a_id);
+ if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
+ slprintf(idbuf, sizeof(idbuf)-1, "%ld",
+ (long)ap->a_id);
+ id = idbuf;
+ } else {
+ id = pw->pw_name;
+ }
case SMB_ACL_USER_OBJ:
tag = "user";
break;
@@ -1322,7 +1335,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
maxlen += nbytes + 20 * (acl_d->count - i);
if ((text = Realloc(oldtext, maxlen)) == NULL) {
- free(oldtext);
+ SAFE_FREE(oldtext);
errno = ENOMEM;
return NULL;
}
@@ -1852,9 +1865,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
ret = acl(name, ACL_SET, acl_count, acl_p);
- if (acl_buf) {
- free(acl_buf);
- }
+ SAFE_FREE(acl_buf);
return ret;
}
@@ -1881,7 +1892,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
* can use the relative path.
*/
- return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);
+ return sys_acl_set_file(dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_ACCESS, acl_d);
}
int sys_acl_delete_def_file(const char *path)
@@ -1906,13 +1917,13 @@ int sys_acl_delete_def_file(const char *path)
int sys_acl_free_text(char *text)
{
- free(text);
+ SAFE_FREE(text);
return 0;
}
int sys_acl_free_acl(SMB_ACL_T acl_d)
{
- free(acl_d);
+ SAFE_FREE(acl_d);
return 0;
}
@@ -2926,7 +2937,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
}
- rc = chacl(name,file_acl,file_acl->acl_len);
+ rc = chacl((char *)name,file_acl,file_acl->acl_len);
DEBUG(10,("errno is %d\n",errno));
DEBUG(10,("return code is %d\n",rc));
SAFE_FREE(file_acl);
diff --git a/source/lib/sysquotas.c b/source/lib/sysquotas.c
deleted file mode 100644
index 1c5c7e8bd4f..00000000000
--- a/source/lib/sysquotas.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- System QUOTA function wrappers
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-#ifdef HAVE_SYS_QUOTAS
-
-#if defined(HAVE_QUOTACTL_4A)
-
-/*#endif HAVE_QUOTACTL_4A */
-#elif defined(HAVE_QUOTACTL_4B)
-
-#error HAVE_QUOTACTL_4B not implemeted
-
-/*#endif HAVE_QUOTACTL_4B */
-#elif defined(HAVE_QUOTACTL_3)
-
-#error HAVE_QUOTACTL_3 not implemented
-
-/* #endif HAVE_QUOTACTL_3 */
-#else /* NO_QUOTACTL_USED */
-
-#endif /* NO_QUOTACTL_USED */
-
-#ifdef HAVE_MNTENT
-static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char **fs)
-{
- int ret = -1;
- SMB_STRUCT_STAT S;
- FILE *fp;
- struct mntent *mnt;
- SMB_DEV_T devno;
-
- /* find the block device file */
-
- if (!path||!mntpath||!bdev||!fs)
- smb_panic("sys_path_to_bdev: called with NULL pointer");
-
- (*mntpath) = NULL;
- (*bdev) = NULL;
- (*fs) = NULL;
-
- if ( sys_stat(path, &S) == -1 )
- return (-1);
-
- devno = S.st_dev ;
-
- fp = setmntent(MOUNTED,"r");
-
- while ((mnt = getmntent(fp))) {
- if ( sys_stat(mnt->mnt_dir,&S) == -1 )
- continue ;
-
- if (S.st_dev == devno) {
- (*mntpath) = strdup(mnt->mnt_dir);
- (*bdev) = strdup(mnt->mnt_fsname);
- (*fs) = strdup(mnt->mnt_type);
- if ((*mntpath)&&(*bdev)&&(*fs)) {
- ret = 0;
- } else {
- SAFE_FREE(*mntpath);
- SAFE_FREE(*bdev);
- SAFE_FREE(*fs);
- ret = -1;
- }
-
- break;
- }
- }
-
- endmntent(fp) ;
-
- return ret;
-}
-/* #endif HAVE_MNTENT */
-#elif defined(HAVE_DEVNM)
-
-/* we have this on HPUX, ... */
-static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char **fs)
-{
- int ret = -1;
- char dev_disk[256];
- SMB_STRUCT_STAT S;
-
- if (!path||!mntpath||!bdev||!fs)
- smb_panic("sys_path_to_bdev: called with NULL pointer");
-
- (*mntpath) = NULL;
- (*bdev) = NULL;
- (*fs) = NULL;
-
- /* find the block device file */
-
- if ((ret=sys_stat(path, &S))!=0) {
- return ret;
- }
-
- if ((ret=devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1))!=0) {
- return ret;
- }
-
- /* we should get the mntpath right...
- * but I don't know how
- * --metze
- */
- (*mntpath) = strdup(path);
- (*bdev) = strdup(dev_disk);
- if ((*mntpath)&&(*bdev)) {
- ret = 0;
- } else {
- SAFE_FREE(*mntpath);
- SAFE_FREE(*bdev);
- ret = -1;
- }
-
-
- return ret;
-}
-
-/* #endif HAVE_DEVNM */
-#else
-/* we should fake this up...*/
-static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char **fs)
-{
- int ret = -1;
-
- if (!path||!mntpath||!bdev||!fs)
- smb_panic("sys_path_to_bdev: called with NULL pointer");
-
- (*mntpath) = NULL;
- (*bdev) = NULL;
- (*fs) = NULL;
-
- (*mntpath) = strdup(path);
- if (*mntpath) {
- ret = 0;
- } else {
- SAFE_FREE(*mntpath);
- ret = -1;
- }
-
- return ret;
-}
-#endif
-
-/*********************************************************************
- Now the list of all filesystem specific quota systems we have found
-**********************************************************************/
-static struct {
- const char *name;
- int (*get_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
- int (*set_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
-} sys_quota_backends[] = {
-#ifdef HAVE_XFS_QUOTAS
- {"xfs", sys_get_xfs_quota, sys_set_xfs_quota},
-#endif /* HAVE_XFS_QUOTAS */
- {NULL, NULL, NULL}
-};
-
-static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- const char *get_quota_command;
-
- get_quota_command = lp_get_quota_command();
- if (get_quota_command && *get_quota_command) {
- const char *p;
- char *p2;
- char **lines;
- pstring syscmd;
- int _id = -1;
-
- switch(qtype) {
- case SMB_USER_QUOTA_TYPE:
- case SMB_USER_FS_QUOTA_TYPE:
- _id = id.uid;
- break;
- case SMB_GROUP_QUOTA_TYPE:
- case SMB_GROUP_FS_QUOTA_TYPE:
- _id = id.gid;
- break;
- default:
- DEBUG(0,("invalid quota type.\n"));
- return -1;
- }
-
- slprintf(syscmd, sizeof(syscmd)-1,
- "%s \"%s\" %d %d",
- get_quota_command, path, qtype, _id);
-
- DEBUG (3, ("get_quota: Running command %s\n", syscmd));
-
- lines = file_lines_pload(syscmd, NULL);
- if (lines) {
- char *line = lines[0];
-
- DEBUG (3, ("Read output from get_quota, \"%s\"\n", line));
-
- /* we need to deal with long long unsigned here, if supported */
-
- dp->qflags = (enum SMB_QUOTA_TYPE)strtoul(line, &p2, 10);
- p = p2;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->curblocks = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->softlimit = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->hardlimit = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->curinodes = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->isoftlimit = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->ihardlimit = STR_TO_SMB_BIG_UINT(p, &p);
- else
- goto invalid_param;
- while (p && *p && isspace(*p))
- p++;
- if (p && *p)
- dp->bsize = STR_TO_SMB_BIG_UINT(p, NULL);
- else
- dp->bsize = 1024;
- file_lines_free(lines);
- DEBUG (3, ("Parsed output of get_quota, ...\n"));
-
-#ifdef LARGE_SMB_OFF_T
- DEBUGADD (5,(
- "qflags:%u curblocks:%llu softlimit:%llu hardlimit:%llu\n"
- "curinodes:%llu isoftlimit:%llu ihardlimit:%llu bsize:%llu\n",
- dp->qflags,(long long unsigned)dp->curblocks,
- (long long unsigned)dp->softlimit,(long long unsigned)dp->hardlimit,
- (long long unsigned)dp->curinodes,
- (long long unsigned)dp->isoftlimit,(long long unsigned)dp->ihardlimit,
- (long long unsigned)dp->bsize));
-#else /* LARGE_SMB_OFF_T */
- DEBUGADD (5,(
- "qflags:%u curblocks:%lu softlimit:%lu hardlimit:%lu\n"
- "curinodes:%lu isoftlimit:%lu ihardlimit:%lu bsize:%lu\n",
- dp->qflags,(long unsigned)dp->curblocks,
- (long unsigned)dp->softlimit,(long unsigned)dp->hardlimit,
- (long unsigned)dp->curinodes,
- (long unsigned)dp->isoftlimit,(long unsigned)dp->ihardlimit,
- (long unsigned)dp->bsize));
-#endif /* LARGE_SMB_OFF_T */
- return 0;
- }
-
- DEBUG (0, ("get_quota_command failed!\n"));
- return -1;
- }
-
- errno = ENOSYS;
- return -1;
-
-invalid_param:
- DEBUG(0,("The output of get_quota_command is invalid!\n"));
- return -1;
-}
-
-static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- const char *set_quota_command;
-
- set_quota_command = lp_set_quota_command();
- if (set_quota_command && *set_quota_command) {
- char **lines;
- pstring syscmd;
- int _id = -1;
-
- switch(qtype) {
- case SMB_USER_QUOTA_TYPE:
- case SMB_USER_FS_QUOTA_TYPE:
- _id = id.uid;
- break;
- case SMB_GROUP_QUOTA_TYPE:
- case SMB_GROUP_FS_QUOTA_TYPE:
- _id = id.gid;
- break;
- default:
- return -1;
- }
-
-#ifdef LARGE_SMB_OFF_T
- slprintf(syscmd, sizeof(syscmd)-1,
- "%s \"%s\" %d %d "
- "%u %llu %llu "
- "%llu %llu %llu ",
- set_quota_command, path, qtype, _id, dp->qflags,
- (long long unsigned)dp->softlimit,(long long unsigned)dp->hardlimit,
- (long long unsigned)dp->isoftlimit,(long long unsigned)dp->ihardlimit,
- (long long unsigned)dp->bsize);
-#else /* LARGE_SMB_OFF_T */
- slprintf(syscmd, sizeof(syscmd)-1,
- "%s \"%s\" %d %d "
- "%u %lu %lu "
- "%lu %lu %lu ",
- set_quota_command, path, qtype, _id, dp->qflags,
- (long unsigned)dp->softlimit,(long unsigned)dp->hardlimit,
- (long unsigned)dp->isoftlimit,(long unsigned)dp->ihardlimit,
- (long unsigned)dp->bsize);
-#endif /* LARGE_SMB_OFF_T */
-
-
-
- DEBUG (3, ("get_quota: Running command %s\n", syscmd));
-
- lines = file_lines_pload(syscmd, NULL);
- if (lines) {
- char *line = lines[0];
-
- DEBUG (3, ("Read output from set_quota, \"%s\"\n", line));
-
- file_lines_free(lines);
-
- return 0;
- }
- DEBUG (0, ("set_quota_command failed!\n"));
- return -1;
- }
-
- errno = ENOSYS;
- return -1;
-}
-
-int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- int i;
- BOOL ready = False;
- char *mntpath = NULL;
- char *bdev = NULL;
- char *fs = NULL;
-
- if (!path||!dp)
- smb_panic("sys_get_quota: called with NULL pointer");
-
- if (command_get_quota(path, qtype, id, dp)==0) {
- return 0;
- } else if (errno != ENOSYS) {
- return -1;
- }
-
- if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) {
- DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path));
- return ret;
- }
-
- errno = 0;
- DEBUG(10,("sys_get_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid()));
-
- for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) {
- if (strcmp(fs,sys_quota_backends[i].name)==0) {
- ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp);
- if (ret!=0) {
- DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
- fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
- } else {
- DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
- fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
- }
- ready = True;
- break;
- }
- }
-
- if (!ready) {
- /* use the default vfs quota functions */
- ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp);
- if (ret!=0) {
- DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s\n",
- "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
- } else {
- DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
- "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
- }
- }
-
- SAFE_FREE(mntpath);
- SAFE_FREE(bdev);
- SAFE_FREE(fs);
-
- if ((ret!=0)&& (errno == EDQUOT)) {
- DEBUG(10,("sys_get_quota() warning over quota!\n"));
- return 0;
- }
-
- return ret;
-}
-
-int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- int i;
- BOOL ready = False;
- char *mntpath = NULL;
- char *bdev = NULL;
- char *fs = NULL;
-
- /* find the block device file */
-
- if (!path||!dp)
- smb_panic("get_smb_quota: called with NULL pointer");
-
- if (command_set_quota(path, qtype, id, dp)==0) {
- return 0;
- } else if (errno != ENOSYS) {
- return -1;
- }
-
- if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) {
- DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path));
- return ret;
- }
-
- errno = 0;
- DEBUG(10,("sys_set_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid()));
-
- for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) {
- if (strcmp(fs,sys_quota_backends[i].name)==0) {
- ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp);
- if (ret!=0) {
- DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
- fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
- } else {
- DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
- fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
- }
- ready = True;
- break;
- }
- }
-
- if (!ready) {
- /* use the default vfs quota functions */
- ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp);
- if (ret!=0) {
- DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
- "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
- } else {
- DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
- "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
- }
- }
-
- SAFE_FREE(mntpath);
- SAFE_FREE(bdev);
- SAFE_FREE(fs);
-
- if ((ret!=0)&& (errno == EDQUOT)) {
- DEBUG(10,("sys_set_quota() warning over quota!\n"));
- return 0;
- }
-
- return ret;
-}
-
-#else /* HAVE_SYS_QUOTAS */
- void dummy_sysquotas_c(void)
-{
- return;
-}
-#endif /* HAVE_SYS_QUOTAS */
-
diff --git a/source/lib/sysquotas_4A.c b/source/lib/sysquotas_4A.c
deleted file mode 100644
index ffb4123799d..00000000000
--- a/source/lib/sysquotas_4A.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- System QUOTA function wrappers for QUOTACTL_4A
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-#ifdef HAVE_QUOTACTL_4A
-/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
-/* this is used by: HPUX,IRIX */
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ASM_TYPES_H
-#include <asm/types.h>
-#endif
-
-#ifdef HAVE_SYS_QUOTA_H
-#include <sys/quota.h>
-#endif
-
-#ifndef Q_SETQLIM
-#define Q_SETQLIM Q_SETQUOTA
-#endif
-
-#ifndef QCMD
-#define QCMD(x,y) x
-#endif
-
-#ifndef QCMD
-#define QCMD(x,y) x
-#endif
-
-#ifdef GRPQUOTA
-#define HAVE_GROUP_QUOTA
-#endif
-
-#ifndef QUOTABLOCK_SIZE
-#define QUOTABLOCK_SIZE DEV_BSIZE
-#endif
-
-#ifdef HAVE_DQB_FSOFTLIMIT
-#define dqb_isoftlimit dqb_fsoftlimit
-#define dqb_ihardlimit dqb_fhardlimit
-#define dqb_curinodes dqb_curfiles
-#endif
-
-#ifdef INITQFNAMES
-#define USERQUOTAFILE_EXTENSION ".user"
-#else
-#define USERQUOTAFILE_EXTENSION ""
-#endif
-
-#if !defined(QUOTAFILENAME) && defined(QFILENAME)
-#define QUOTAFILENAME QFILENAME
-#endif
-
-/****************************************************************************
- Abstract out the quotactl_4A get calls.
-****************************************************************************/
-int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- struct dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
- ZERO_STRUCT(*dp);
- dp->qtype = qtype;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- if ((D.dqb_curblocks==0)&&
- (D.dqb_bsoftlimit==0)&&
- (D.dqb_bhardlimit==0)) {
- /* the upper layer functions don't want empty quota records...*/
- return -1;
- }
-
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- if ((D.dqb_curblocks==0)&&
- (D.dqb_bsoftlimit==0)&&
- (D.dqb_bhardlimit==0)) {
- /* the upper layer functions don't want empty quota records...*/
- return -1;
- }
-
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- id.uid = getuid();
-
- DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- ret = 0;
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- id.gid = getgid();
-
- DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- ret = 0;
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- }
-
- dp->bsize = bsize;
- dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
- dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
- dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
-
-
- dp->qflags = qflags;
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the quotactl_4A set calls.
-****************************************************************************/
-int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- uint32 oldqflags = 0;
- struct dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- if (bsize == dp->bsize) {
- D.dqb_bsoftlimit = dp->softlimit;
- D.dqb_bhardlimit = dp->hardlimit;
- D.dqb_ihardlimit = dp->ihardlimit;
- D.dqb_isoftlimit = dp->isoftlimit;
- } else {
- D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
- D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
- D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
- D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
- }
-
- qflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (void *)&D);
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (void *)&D);
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- /* this stuff didn't work as it should:
- * switching on/off quota via quotactl()
- * didn't work!
- * So we just return 0
- * --metze
- *
- * On HPUX we didn't have the mount path,
- * we need to fix sys_path_to_bdev()
- *
- */
- id.uid = getuid();
- DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
-#if 0
- ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D);
-
- if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
- if (ret == 0) {
- char *quota_file = NULL;
-
- asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
- if (quota_file == NULL) {
- DEBUG(0,("asprintf() failed!\n"));
- errno = ENOMEM;
- return -1;
- }
-
- ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), bdev, -1,(void *)quota_file);
- } else {
- ret = 0;
- }
- } else {
- if (ret != 0) {
- /* turn off */
- ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), bdev, -1, (void *)0);
- } else {
- ret = 0;
- }
- }
-
- DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
- ret,errno,strerror(errno),id.uid,bdev));
-#else
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- if (oldqflags == qflags) {
- ret = 0;
- } else {
- ret = -1;
- }
-#endif
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- /* this stuff didn't work as it should:
- * switching on/off quota via quotactl()
- * didn't work!
- * So we just return 0
- * --metze
- *
- * On HPUX we didn't have the mount path,
- * we need to fix sys_path_to_bdev()
- *
- */
- id.gid = getgid();
- DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
-#if 0
- ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
-
- if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
- if (ret == 0) {
- char *quota_file = NULL;
-
- asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
- if (quota_file == NULL) {
- DEBUG(0,("asprintf() failed!\n"));
- errno = ENOMEM;
- return -1;
- }
-
- ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(void *)quota_file);
- } else {
- ret = 0;
- }
- } else {
- if (ret != 0) {
- /* turn off */
- ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (void *)0);
- } else {
- ret = 0;
- }
- }
-
- DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
- ret,errno,strerror(errno),id.gid,bdev));
-#else
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- if (oldqflags == qflags) {
- ret = 0;
- } else {
- ret = -1;
- }
-#endif
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-#else /* HAVE_QUOTACTL_4A */
- void dummy_sysquotas_4A(void){}
-#endif /* HAVE_QUOTACTL_4A */
diff --git a/source/lib/sysquotas_linux.c b/source/lib/sysquotas_linux.c
deleted file mode 100644
index 3867c1b0f9b..00000000000
--- a/source/lib/sysquotas_linux.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- System QUOTA function wrappers for LINUX
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-#ifdef HAVE_QUOTACTL_LINUX
-
-#include "samba_linux_quota.h"
-
-/****************************************************************************
- Abstract out the v1 Linux quota get calls.
-****************************************************************************/
-static int sys_get_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- struct v1_kern_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- dp->bsize = bsize;
- dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
- dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
- dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
-
-
- dp->qflags = qflags;
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the v1 Linux quota set calls.
-****************************************************************************/
-static int sys_set_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- uint32 oldqflags = 0;
- struct v1_kern_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- if (bsize == dp->bsize) {
- D.dqb_bsoftlimit = dp->softlimit;
- D.dqb_bhardlimit = dp->hardlimit;
- D.dqb_ihardlimit = dp->ihardlimit;
- D.dqb_isoftlimit = dp->isoftlimit;
- } else {
- D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
- D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
- D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
- D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
- }
-
- qflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- ret = quotactl(QCMD(Q_V1_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- ret = quotactl(QCMD(Q_V1_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the v2 Linux quota get calls.
-****************************************************************************/
-static int sys_get_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- struct v2_kern_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- dp->bsize = bsize;
- dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
- dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
- dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize;
-
-
- dp->qflags = qflags;
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the v2 Linux quota set calls.
-****************************************************************************/
-static int sys_set_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- uint32 oldqflags = 0;
- struct v2_kern_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- if (bsize == dp->bsize) {
- D.dqb_bsoftlimit = dp->softlimit;
- D.dqb_bhardlimit = dp->hardlimit;
- D.dqb_ihardlimit = dp->ihardlimit;
- D.dqb_isoftlimit = dp->isoftlimit;
- } else {
- D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
- D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
- D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
- D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
- }
-
- qflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- ret = quotactl(QCMD(Q_V2_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- ret = quotactl(QCMD(Q_V2_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the generic Linux quota get calls.
-****************************************************************************/
-static int sys_get_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- struct if_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
- return ret;
- }
-
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- qflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- dp->bsize = bsize;
- dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
- dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
- dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize;
-
-
- dp->qflags = qflags;
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the gen Linux quota set calls.
-****************************************************************************/
-static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- uint32 oldqflags = 0;
- struct if_dqblk D;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- ZERO_STRUCT(D);
-
- if (bsize == dp->bsize) {
- D.dqb_bsoftlimit = dp->softlimit;
- D.dqb_bhardlimit = dp->hardlimit;
- D.dqb_ihardlimit = dp->ihardlimit;
- D.dqb_isoftlimit = dp->isoftlimit;
- } else {
- D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
- D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
- D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
- D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
- }
-
- qflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
- break;
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
- oldqflags |= QUOTAS_DENY_DISK;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the Linux quota get calls.
-****************************************************************************/
-int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
-
- if (!path||!bdev||!dp)
- smb_panic("sys_set_vfs_quota: called with NULL pointer");
-
- ZERO_STRUCT(*dp);
- dp->qtype = qtype;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- case SMB_GROUP_QUOTA_TYPE:
- if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- if ((ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- return ret;
- }
- }
- }
-
- if ((dp->curblocks==0)&&
- (dp->softlimit==0)&&
- (dp->hardlimit==0)) {
- /* the upper layer functions don't want empty quota records...*/
- return -1;
- }
-
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- id.uid = getuid();
-
- if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
- }
- }
-
- ret = 0;
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- id.gid = getgid();
-
- if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
- ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
- }
- }
-
- ret = 0;
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the Linux quota set calls.
-****************************************************************************/
-int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 oldqflags = 0;
-
- if (!path||!bdev||!dp)
- smb_panic("sys_set_vfs_quota: called with NULL pointer");
-
- oldqflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- case SMB_GROUP_QUOTA_TYPE:
- if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) {
- if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) {
- if ((ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp))) {
- return ret;
- }
- }
- }
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- id.uid = getuid();
-
- if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) {
- if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) {
- ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
- }
- }
-
- if (oldqflags == dp->qflags) {
- ret = 0;
- } else {
- ret = -1;
- }
- break;
- case SMB_GROUP_FS_QUOTA_TYPE:
- id.gid = getgid();
-
- if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) {
- if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) {
- ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
- }
- }
-
- if (oldqflags == dp->qflags) {
- ret = 0;
- } else {
- ret = -1;
- }
-
- break;
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-#else /* HAVE_QUOTACTL_LINUX */
- void dummy_sysquotas_linux(void){}
-#endif /* HAVE_QUOTACTL_LINUX */
diff --git a/source/lib/sysquotas_xfs.c b/source/lib/sysquotas_xfs.c
deleted file mode 100644
index 9fe4ec0d992..00000000000
--- a/source/lib/sysquotas_xfs.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- System QUOTA function wrappers for XFS
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-#ifndef HAVE_SYS_QUOTAS
-#ifdef HAVE_XFS_QUOTAS
-#undef HAVE_XFS_QUOTAS
-#endif
-#endif
-
-#ifdef HAVE_XFS_QUOTAS
-
-#ifdef HAVE_LINUX_XFS_QUOTAS
-#include "samba_linux_quota.h"
-#include "samba_xfs_quota.h"
-#define HAVE_GROUP_QUOTA
-#else /* IRIX */
-#include <sys/quota.h>
-#endif
-
-/* on IRIX */
-#ifndef Q_XQUOTAON
-#define Q_XQUOTAON Q_QUOTAON
-#endif /* Q_XQUOTAON */
-#ifndef Q_XQUOTAOFF
-#define Q_XQUOTAOFF Q_QUOTAOFF
-#endif /* Q_XQUOTAOFF */
-#ifndef Q_XGETQSTAT
-#define Q_XGETQSTAT Q_GETQSTAT
-#endif /* Q_XGETQSTAT */
-
-/* currently doesn't support Group and Project quotas on IRIX
- */
-
-#ifndef QCMD
-#define QCMD(x,y) x
-#endif
-
-/*
- * IRIX has BBSIZE in <sys/param.h>
- */
-#ifndef BBSHIFT
-#define BBSHIFT 9
-#endif /* BBSHIFT */
-#ifndef BBSIZE
-#define BBSIZE (1<<BBSHIFT)
-#endif /* BBSIZE */
-
-/****************************************************************************
- Abstract out the XFS Quota Manager quota get call.
-****************************************************************************/
-int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
- struct fs_disk_quota D;
- struct fs_quota_stat F;
- ZERO_STRUCT(D);
- ZERO_STRUCT(F);
-
- if (!bdev||!dp)
- smb_panic("sys_get_xfs_quota: called with NULL pointer");
-
- ZERO_STRUCT(*dp);
- dp->qtype = qtype;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
- return ret;
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
- return ret;
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
-
- if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
- qflags |= QUOTAS_DENY_DISK;
- }
- else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
- qflags |= QUOTAS_ENABLED;
- }
-
- ret = 0;
-
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
-
- if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
- qflags |= QUOTAS_DENY_DISK;
- }
- else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
- qflags |= QUOTAS_ENABLED;
- }
-
- ret = 0;
-
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- }
-
- dp->bsize = bsize;
- dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
- dp->curinodes = (SMB_BIG_UINT)D.d_icount;
- dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
- dp->qflags = qflags;
-
- return ret;
-}
-
-/****************************************************************************
- Abstract out the XFS Quota Manager quota set call.
-****************************************************************************/
-int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
- int ret = -1;
- uint32 qflags = 0;
- SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
- struct fs_disk_quota D;
- struct fs_quota_stat F;
- int q_on = 0;
- int q_off = 0;
- ZERO_STRUCT(D);
- ZERO_STRUCT(F);
-
- if (!bdev||!dp)
- smb_panic("sys_set_xfs_quota: called with NULL pointer");
-
- if (bsize == dp->bsize) {
- D.d_blk_softlimit = dp->softlimit;
- D.d_blk_hardlimit = dp->hardlimit;
- D.d_ino_hardlimit = dp->ihardlimit;
- D.d_ino_softlimit = dp->isoftlimit;
- } else {
- D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
- D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
- D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
- D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;
- }
-
- qflags = dp->qflags;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
- path, bdev, (unsigned)id.uid));
-
- D.d_fieldmask |= FS_DQ_LIMIT_MASK;
- ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
- path, bdev, (unsigned)id.gid));
-
- D.d_fieldmask |= FS_DQ_LIMIT_MASK;
- ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
- path, bdev, (unsigned)id.uid));
-
- quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
-
- if (qflags & QUOTAS_DENY_DISK) {
- if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
- q_on |= XFS_QUOTA_UDQ_ENFD;
- if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
- q_on |= XFS_QUOTA_UDQ_ACCT;
-
- if (q_on != 0) {
- ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
- } else {
- ret = 0;
- }
-
- } else if (qflags & QUOTAS_ENABLED) {
- if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
- q_off |= XFS_QUOTA_UDQ_ENFD;
-
- if (q_off != 0) {
- ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
- } else {
- ret = 0;
- }
-
- if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
- q_on |= XFS_QUOTA_UDQ_ACCT;
-
- if (q_on != 0) {
- ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
- } else {
- ret = 0;
- }
- } else {
-#if 0
- /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
- * only swittching off XFS_QUOTA_UDQ_ACCT work
- */
- if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
- q_off |= XFS_QUOTA_UDQ_ENFD;
- if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
- q_off |= XFS_QUOTA_UDQ_ACCT;
-
- if (q_off !=0) {
- ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
- } else {
- ret = 0;
- }
-#else
- ret = -1;
-#endif
- }
-
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
- path, bdev, (unsigned)id.gid));
-
- quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
-
- if (qflags & QUOTAS_DENY_DISK) {
- if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
- q_on |= XFS_QUOTA_GDQ_ENFD;
- if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
- q_on |= XFS_QUOTA_GDQ_ACCT;
-
- if (q_on != 0) {
- ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
- } else {
- ret = 0;
- }
-
- } else if (qflags & QUOTAS_ENABLED) {
- if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
- q_off |= XFS_QUOTA_GDQ_ENFD;
-
- if (q_off != 0) {
- ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
- } else {
- ret = 0;
- }
-
- if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
- q_on |= XFS_QUOTA_GDQ_ACCT;
-
- if (q_on != 0) {
- ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
- } else {
- ret = 0;
- }
- } else {
-#if 0
- /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
- * only swittching off XFS_QUOTA_UDQ_ACCT work
- */
- if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
- q_off |= XFS_QUOTA_GDQ_ENFD;
- if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
- q_off |= XFS_QUOTA_GDQ_ACCT;
-
- if (q_off !=0) {
- ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
- } else {
- ret = 0;
- }
-#else
- ret = -1;
-#endif
- }
-
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- }
-
- return ret;
-}
-
-#else /* HAVE_XFS_QUOTAS */
- void dummy_sysquotas_xfs(void){}
-#endif /* HAVE_XFS_QUOTAS */
diff --git a/source/lib/system.c b/source/lib/system.c
index a0007ec83cd..b19816df4b9 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba system utilities
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998-2002
@@ -100,47 +101,6 @@ ssize_t sys_write(int fd, const void *buf, size_t count)
return ret;
}
-
-/*******************************************************************
-A pread wrapper that will deal with EINTR and 64-bit file offsets.
-********************************************************************/
-
-#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
-ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
-{
- ssize_t ret;
-
- do {
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
- ret = pread64(fd, buf, count, off);
-#else
- ret = pread(fd, buf, count, off);
-#endif
- } while (ret == -1 && errno == EINTR);
- return ret;
-}
-#endif
-
-/*******************************************************************
-A write wrapper that will deal with EINTR and 64-bit file offsets.
-********************************************************************/
-
-#if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
-ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
-{
- ssize_t ret;
-
- do {
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
- ret = pwrite64(fd, buf, count, off);
-#else
- ret = pwrite(fd, buf, count, off);
-#endif
- } while (ret == -1 && errno == EINTR);
- return ret;
-}
-#endif
-
/*******************************************************************
A send wrapper that will deal with EINTR.
********************************************************************/
@@ -490,8 +450,6 @@ int sys_chown(const char *fname,uid_t uid,gid_t gid)
DEBUG(1,("WARNING: no chown!\n"));
done=1;
}
- errno = ENOSYS;
- return -1;
#else
return(chown(fname,uid,gid));
#endif
@@ -529,7 +487,7 @@ struct hostent *sys_gethostbyname(const char *name)
/* Does this name have any dots in it? If so, make no change */
- if (strchr_m(name, '.'))
+ if (strchr(name, '.'))
return(gethostbyname(name));
/* Get my hostname, which should have domain name
@@ -539,7 +497,7 @@ struct hostent *sys_gethostbyname(const char *name)
gethostname(hostname, sizeof(hostname) - 1);
hostname[sizeof(hostname) - 1] = 0;
- if ((domain = strchr_m(hostname, '.')) == NULL)
+ if ((domain = strchr(hostname, '.')) == NULL)
return(gethostbyname(name));
/* Attach domain name to query and do modified query.
@@ -736,6 +694,7 @@ int sys_getgroups(int setlen, gid_t *gidset)
#endif /* HAVE_BROKEN_GETGROUPS */
}
+#ifdef HAVE_SETGROUPS
/**************************************************************************
Wrapper for setgroups. Deals with broken (int) case. Automatically used
@@ -744,11 +703,6 @@ int sys_getgroups(int setlen, gid_t *gidset)
int sys_setgroups(int setlen, gid_t *gidset)
{
-#if !defined(HAVE_SETGROUPS)
- errno = ENOSYS;
- return -1;
-#endif /* HAVE_SETGROUPS */
-
#if !defined(HAVE_BROKEN_GETGROUPS)
return setgroups(setlen, gidset);
#else
@@ -788,6 +742,89 @@ int sys_setgroups(int setlen, gid_t *gidset)
return 0 ;
#endif /* HAVE_BROKEN_GETGROUPS */
}
+#else /* No setgroups. */
+int sys_setgroups(int setlen, gid_t *gidset)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif /* HAVE_SETGROUPS */
+
+/*
+ * We only wrap pw_name and pw_passwd for now as these
+ * are the only potentially modified fields.
+ */
+
+/**************************************************************************
+ Helper function for getpwnam/getpwuid wrappers.
+****************************************************************************/
+
+struct saved_pw {
+ fstring pw_name;
+ fstring pw_passwd;
+ fstring pw_gecos;
+ pstring pw_dir;
+ pstring pw_shell;
+ struct passwd pass;
+};
+
+static struct saved_pw pw_mod; /* This is the structure returned - can be modified. */
+static struct saved_pw pw_cache; /* This is the structure saved - used to check cache. */
+
+static int num_lookups; /* Counter so we don't always use cache. */
+#ifndef PW_RET_CACHE_MAX_LOOKUPS
+#define PW_RET_CACHE_MAX_LOOKUPS 100
+#endif
+
+static void copy_pwent(struct saved_pw *dst, struct passwd *pass)
+{
+ memcpy((char *)&dst->pass, pass, sizeof(struct passwd));
+
+ fstrcpy(dst->pw_name, pass->pw_name);
+ dst->pass.pw_name = dst->pw_name;
+
+ fstrcpy(dst->pw_passwd, pass->pw_passwd);
+ dst->pass.pw_passwd = dst->pw_passwd;
+
+ fstrcpy(dst->pw_gecos, pass->pw_gecos);
+ dst->pass.pw_gecos = dst->pw_gecos;
+
+ pstrcpy(dst->pw_dir, pass->pw_dir);
+ dst->pass.pw_dir = dst->pw_dir;
+
+ pstrcpy(dst->pw_shell, pass->pw_shell);
+ dst->pass.pw_shell = dst->pw_shell;
+}
+
+static struct passwd *setup_pwret(struct passwd *pass)
+{
+ if (pass == NULL) {
+ /* Clear the caches. */
+ memset(&pw_cache, '\0', sizeof(struct saved_pw));
+ memset(&pw_mod, '\0', sizeof(struct saved_pw));
+ num_lookups = 0;
+ return NULL;
+ }
+
+ copy_pwent( &pw_mod, pass);
+
+ if (pass != &pw_cache.pass) {
+
+ /* If it's a cache miss we must also refill the cache. */
+
+ copy_pwent( &pw_cache, pass);
+ num_lookups = 1;
+
+ } else {
+
+ /* Cache hit. */
+
+ num_lookups++;
+ num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
+ }
+
+ return &pw_mod.pass;
+}
/**************************************************************************
Wrappers for setpwent(), getpwent() and endpwent()
@@ -795,41 +832,49 @@ int sys_setgroups(int setlen, gid_t *gidset)
void sys_setpwent(void)
{
+ setup_pwret(NULL); /* Clear cache. */
setpwent();
}
struct passwd *sys_getpwent(void)
{
- return getpwent();
+ return setup_pwret(getpwent());
}
void sys_endpwent(void)
{
+ setup_pwret(NULL); /* Clear cache. */
endpwent();
}
/**************************************************************************
- Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
+ Wrapper for getpwnam(). Always returns a static that can be modified.
****************************************************************************/
struct passwd *sys_getpwnam(const char *name)
{
- return getpwnam(name);
-}
+ if (!name || !name[0])
+ return NULL;
-struct passwd *sys_getpwuid(uid_t uid)
-{
- return getpwuid(uid);
-}
+ /* check for a cache hit first */
+ if (num_lookups && pw_cache.pass.pw_name && !strcmp(name, pw_cache.pass.pw_name)) {
+ return setup_pwret(&pw_cache.pass);
+ }
-struct group *sys_getgrnam(const char *name)
-{
- return getgrnam(name);
+ return setup_pwret(getpwnam(name));
}
-struct group *sys_getgrgid(gid_t gid)
+/**************************************************************************
+ Wrapper for getpwuid(). Always returns a static that can be modified.
+****************************************************************************/
+
+struct passwd *sys_getpwuid(uid_t uid)
{
- return getgrgid(gid);
+ if (num_lookups && pw_cache.pass.pw_name && (uid == pw_cache.pass.pw_uid)) {
+ return setup_pwret(&pw_cache.pass);
+ }
+
+ return setup_pwret(getpwuid(uid));
}
#if 0 /* NOT CURRENTLY USED - JRA */
@@ -1264,319 +1309,30 @@ const char *sys_dlerror(void)
#endif
}
-int sys_dup2(int oldfd, int newfd)
-{
-#if defined(HAVE_DUP2)
- return dup2(oldfd, newfd);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
/**************************************************************************
Wrapper for Admin Logs.
****************************************************************************/
- void sys_adminlog(int priority, const char *format_str, ...)
+void sys_adminlog(int priority, const char *format_str, ...)
{
va_list ap;
int ret;
- char *msgbuf = NULL;
+ char **msgbuf = NULL;
+
+ if (!lp_admin_log())
+ return;
va_start( ap, format_str );
- ret = vasprintf( &msgbuf, format_str, ap );
+ ret = vasprintf( msgbuf, format_str, ap );
va_end( ap );
if (ret == -1)
return;
#if defined(HAVE_SYSLOG)
- syslog( priority, "%s", msgbuf );
-#else
- DEBUG(0,("%s", msgbuf ));
-#endif
- SAFE_FREE(msgbuf);
-}
-
-/**************************************************************************
- Wrappers for extented attribute calls. Based on the Linux package with
- support for IRIX also. Expand as other systems have them.
-****************************************************************************/
-
-ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
-{
-#if defined(HAVE_GETXATTR)
- return getxattr(path, name, value, size);
-#elif defined(HAVE_ATTR_GET)
- int retval, flags = 0;
- int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
-
- return retval ? retval : valuelength;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
-{
-#if defined(HAVE_LGETXATTR)
- return lgetxattr(path, name, value, size);
-#elif defined(HAVE_ATTR_GET)
- int retval, flags = ATTR_DONTFOLLOW;
- int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
-
- return retval ? retval : valuelength;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
-{
-#if defined(HAVE_FGETXATTR)
- return fgetxattr(filedes, name, value, size);
-#elif defined(HAVE_ATTR_GETF)
- int retval, flags = 0;
- int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
-
- return retval ? retval : valuelength;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-#if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
-static char attr_buffer[ATTR_MAX_VALUELEN];
-
-static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
-{
- int retval = 0, index;
- attrlist_cursor_t *cursor = 0;
- int total_size = 0;
- attrlist_t * al = (attrlist_t *)attr_buffer;
- attrlist_ent_t *ae;
- size_t ent_size, left = size;
- char *bp = list;
-
- while (True) {
- if (filedes)
- retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
- else
- retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
- if (retval) break;
- for (index = 0; index < al->al_count; index++) {
- ae = ATTR_ENTRY(attr_buffer, index);
- ent_size = strlen(ae->a_name) + sizeof("user.");
- if (left >= ent_size) {
- strncpy(bp, "user.", sizeof("user."));
- strncat(bp, ae->a_name, ent_size - sizeof("user."));
- bp += ent_size;
- left -= ent_size;
- } else if (size) {
- errno = ERANGE;
- retval = -1;
- break;
- }
- total_size += ent_size;
- }
- if (al->al_more == 0) break;
- }
- if (retval == 0) {
- flags |= ATTR_ROOT;
- cursor = 0;
- while (True) {
- if (filedes)
- retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
- else
- retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
- if (retval) break;
- for (index = 0; index < al->al_count; index++) {
- ae = ATTR_ENTRY(attr_buffer, index);
- ent_size = strlen(ae->a_name) + sizeof("system.");
- if (left >= ent_size) {
- strncpy(bp, "system.", sizeof("system."));
- strncat(bp, ae->a_name, ent_size - sizeof("system."));
- bp += ent_size;
- left -= ent_size;
- } else if (size) {
- errno = ERANGE;
- retval = -1;
- break;
- }
- total_size += ent_size;
- }
- if (al->al_more == 0) break;
- }
- }
- return (ssize_t)(retval ? retval : total_size);
-}
-
-#endif
-
-ssize_t sys_listxattr (const char *path, char *list, size_t size)
-{
-#if defined(HAVE_LISTXATTR)
- return listxattr(path, list, size);
-#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
- return irix_attr_list(path, 0, list, size, 0);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-ssize_t sys_llistxattr (const char *path, char *list, size_t size)
-{
-#if defined(HAVE_LLISTXATTR)
- return llistxattr(path, list, size);
-#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
- return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-ssize_t sys_flistxattr (int filedes, char *list, size_t size)
-{
-#if defined(HAVE_FLISTXATTR)
- return flistxattr(filedes, list, size);
-#elif defined(HAVE_ATTR_LISTF)
- return irix_attr_list(NULL, filedes, list, size, 0);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_removexattr (const char *path, const char *name)
-{
-#if defined(HAVE_REMOVEXATTR)
- return removexattr(path, name);
-#elif defined(HAVE_ATTR_REMOVE)
- int flags = 0;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- return attr_remove(path, attrname, flags);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_lremovexattr (const char *path, const char *name)
-{
-#if defined(HAVE_LREMOVEXATTR)
- return lremovexattr(path, name);
-#elif defined(HAVE_ATTR_REMOVE)
- int flags = ATTR_DONTFOLLOW;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- return attr_remove(path, attrname, flags);
+ syslog( priority, "%s", *msgbuf );
#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_fremovexattr (int filedes, const char *name)
-{
-#if defined(HAVE_FREMOVEXATTR)
- return fremovexattr(filedes, name);
-#elif defined(HAVE_ATTR_REMOVEF)
- int flags = 0;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
-
- return attr_removef(filedes, attrname, flags);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-#if !defined(HAVE_SETXATTR)
-#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
-#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
-#endif
-
-int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
-{
-#if defined(HAVE_SETXATTR)
- return setxattr(path, name, value, size, flags);
-#elif defined(HAVE_ATTR_SET)
- int myflags = 0;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
- if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
- if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
-
- return attr_set(path, attrname, (const char *)value, size, myflags);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
-{
-#if defined(HAVE_LSETXATTR)
- return lsetxattr(path, name, value, size, flags);
-#elif defined(HAVE_ATTR_SET)
- int myflags = ATTR_DONTFOLLOW;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
- if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
- if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
-
- return attr_set(path, attrname, (const char *)value, size, myflags);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
-{
-#if defined(HAVE_FSETXATTR)
- return fsetxattr(filedes, name, value, size, flags);
-#elif defined(HAVE_ATTR_SETF)
- int myflags = 0;
- char *attrname = strchr(name,'.') +1;
-
- if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
- if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
- if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
-
- return attr_setf(filedes, attrname, (const char *)value, size, myflags);
-#else
- errno = ENOSYS;
- return -1;
+ DEBUG(0,("%s", *msgbuf ));
#endif
+ SAFE_FREE(*msgbuf);
}
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
deleted file mode 100644
index 55c2338ebd6..00000000000
--- a/source/lib/system_smbd.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- system call wrapper interface.
- Copyright (C) Andrew Tridgell 2002
- Copyright (C) Andrew Barteltt 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- This file may assume linkage with smbd - for things like become_root()
- etc.
-*/
-
-#include "includes.h"
-
-#ifndef HAVE_GETGROUPLIST
-/*
- This is a *much* faster way of getting the list of groups for a user
- without changing the current supplemenrary group list. The old
- method used getgrent() which could take 20 minutes on a really big
- network with hundeds of thousands of groups and users. The new method
- takes a couple of seconds.
-
- NOTE!! this function only works if it is called as root!
- */
-static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
-{
- gid_t *gids_saved;
- int ret, ngrp_saved, num_gids;
-
- if (non_root_mode()) {
- *grpcnt = 0;
- return 0;
- }
-
- /* work out how many groups we need to save */
- ngrp_saved = getgroups(0, NULL);
- if (ngrp_saved == -1) {
- /* this shouldn't happen */
- return -1;
- }
-
- gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1));
- if (!gids_saved) {
- errno = ENOMEM;
- return -1;
- }
-
- ngrp_saved = getgroups(ngrp_saved, gids_saved);
- if (ngrp_saved == -1) {
- SAFE_FREE(gids_saved);
- /* very strange! */
- return -1;
- }
-
- if (initgroups(user, gid) != 0) {
- DEBUG(0, ("getgrouplist_internals: initgroups() failed!\n"));
- SAFE_FREE(gids_saved);
- return -1;
- }
-
- /* this must be done to cope with systems that put the current egid in the
- return from getgroups() */
- save_re_gid();
- set_effective_gid(gid);
- setgid(gid);
-
- num_gids = getgroups(0, NULL);
- if (num_gids + 1 > *grpcnt) {
- *grpcnt = num_gids + 1;
- ret = -1;
- } else {
- ret = getgroups(*grpcnt - 1, &groups[1]);
- if (ret >= 0) {
- groups[0] = gid;
- *grpcnt = ret + 1;
- }
-
- /* remove any duplicates gids in the list */
-
- remove_duplicate_gids( grpcnt, groups );
- }
-
- restore_re_gid();
-
- if (sys_setgroups(ngrp_saved, gids_saved) != 0) {
- /* yikes! */
- DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n"));
- smb_panic("getgrouplist: failed to reset group list!\n");
- free(gids_saved);
- return -1;
- }
-
- free(gids_saved);
- return ret;
-}
-#endif
-
-int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
-{
- char *p;
- int retval;
-
- DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
-
- /* see if we should disable winbindd lookups for local users */
- if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) {
- if ( !winbind_off() )
- DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
- WINBINDD_DONT_ENV));
- else
- DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n",
- user));
- }
-
-#ifdef HAVE_GETGROUPLIST
- retval = getgrouplist(user, gid, groups, grpcnt);
-#else
- become_root();
- retval = getgrouplist_internals(user, gid, groups, grpcnt);
- unbecome_root();
-#endif
-
- /* allow winbindd lookups */
- winbind_on();
-
- return retval;
-}
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index 093a221fd3d..8c722e1ff78 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -54,6 +54,27 @@
#include "includes.h"
+struct talloc_chunk {
+ struct talloc_chunk *next;
+ size_t size;
+ void *ptr;
+};
+
+
+struct talloc_ctx {
+ struct talloc_chunk *list;
+ size_t total_alloc_size;
+
+ /** The name recorded for this pool, if any. Should describe
+ * the purpose for which it was allocated. The string is
+ * allocated within the pool. **/
+ char *name;
+
+ /** Pointer to the next allocate talloc pool, so that we can
+ * summarize all talloc memory usage. **/
+ struct talloc_ctx *next_ctx;
+};
+
/**
* Start of linked list of all talloc pools.
@@ -61,7 +82,7 @@
* @todo We should turn the global list off when using Insure++,
* otherwise all the memory will be seen as still reachable.
**/
-static TALLOC_CTX *list_head = NULL;
+TALLOC_CTX *list_head = NULL;
/**
@@ -96,7 +117,7 @@ static void talloc_disenroll(TALLOC_CTX *t)
/** Create a new talloc context. **/
-static TALLOC_CTX *talloc_init_internal(void)
+TALLOC_CTX *talloc_init(void)
{
TALLOC_CTX *t;
@@ -115,27 +136,18 @@ static TALLOC_CTX *talloc_init_internal(void)
/**
* Create a new talloc context, with a name specifying its purpose.
+ * Please call this in preference to talloc_init().
**/
-
- TALLOC_CTX *talloc_init(char const *fmt, ...)
+ TALLOC_CTX *talloc_init_named(char const *fmt, ...)
{
TALLOC_CTX *t;
va_list ap;
- t = talloc_init_internal();
+ t = talloc_init();
if (t && fmt) {
- /*
- * t->name must not be talloced.
- * as destroying the pool would destroy it. JRA.
- */
- t->name = NULL;
va_start(ap, fmt);
- vasprintf(&t->name, fmt, ap);
+ t->name = talloc_vasprintf(t, fmt, ap);
va_end(ap);
- if (!t->name) {
- talloc_destroy(t);
- t = NULL;
- }
}
return t;
@@ -222,7 +234,6 @@ void talloc_destroy(TALLOC_CTX *t)
talloc_destroy_pool(t);
talloc_disenroll(t);
- SAFE_FREE(t->name);
memset(t, 0, sizeof(TALLOC_CTX));
SAFE_FREE(t);
}
@@ -276,33 +287,6 @@ char *talloc_strdup(TALLOC_CTX *t, const char *p)
return NULL;
}
-/** strdup_upper with a talloc */
-char *talloc_strdup_upper(TALLOC_CTX *t, const char *p)
-{
- char *r;
- if (p) {
- char *q = strdup_upper(p);
- if (q) {
- r = talloc_strdup(t, q);
- SAFE_FREE(q);
- return r;
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
-}
-
-/** strdup_w with a talloc */
-smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
-{
- if (p)
- return talloc_memdup(t, p, (strlen_w(p) + 1) * sizeof(smb_ucs2_t));
- else
- return NULL;
-}
-
/**
* Perform string formatting, and return a pointer to newly allocated
* memory holding the result, inside a memory pool.
@@ -325,8 +309,7 @@ smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
char *ret;
va_list ap2;
- VA_COPY(ap2, ap);
-
+ VA_COPY(ap2, ap); /* for systems were va_list is a struct */
len = vsnprintf(NULL, 0, fmt, ap2);
ret = talloc(t, len+1);
@@ -369,7 +352,6 @@ smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
va_list ap2;
VA_COPY(ap2, ap);
-
s_len = strlen(s);
len = vsnprintf(NULL, 0, fmt, ap2);
@@ -377,7 +359,6 @@ smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
if (!s) return NULL;
VA_COPY(ap2, ap);
-
vsnprintf(s+s_len, len+1, fmt, ap2);
return s;
@@ -418,7 +399,7 @@ char *talloc_describe_all(TALLOC_CTX *rt)
if (it->name)
fstrcpy(what, it->name);
else
- slprintf(what, sizeof(what), "@%p", it);
+ slprintf(what, sizeof what, "@%p", it);
s = talloc_asprintf_append(rt, s, "%-40s %8u %8u\n",
what,
diff --git a/source/lib/tallocmsg.c b/source/lib/tallocmsg.c
deleted file mode 100644
index bbe1ee60a46..00000000000
--- a/source/lib/tallocmsg.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- samba -- Unix SMB/CIFS implementation.
- Copyright (C) 2001, 2002 by Martin Pool
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * @file tallocmsg.c
- *
- * Glue code between talloc profiling and the Samba messaging system.
- **/
-
-
-/**
- * Respond to a POOL_USAGE message by sending back string form of memory
- * usage stats.
- **/
-void msg_pool_usage(int msg_type, pid_t src_pid,
- void *UNUSED(buf), size_t UNUSED(len))
-{
- char *reply;
- TALLOC_CTX *reply_pool = talloc_init("msg_pool_usage");
-
- SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE);
-
- DEBUG(2,("Got POOL_USAGE\n"));
-
- reply = talloc_describe_all(reply_pool);
-
- message_send_pid(src_pid, MSG_POOL_USAGE,
- reply, strlen(reply)+1, True);
-
- talloc_destroy(reply_pool);
-}
-
-/**
- * Register handler for MSG_REQ_POOL_USAGE
- **/
-void register_msg_pool_usage(void)
-{
- message_register(MSG_REQ_POOL_USAGE, msg_pool_usage);
- DEBUG(2, ("Registered MSG_REQ_POOL_USAGE\n"));
-}
diff --git a/source/lib/talloctort.c b/source/lib/talloctort.c
deleted file mode 100644
index 0cdf693bb91..00000000000
--- a/source/lib/talloctort.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba temporary memory allocation functions -- torturer
- Copyright (C) 2001 by Martin Pool <mbp@samba.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define NCTX 10
-#define NOBJ 20
-
-int main(void)
-{
- int i;
- TALLOC_CTX *ctx[NCTX];
-
- for (i = 0; i < NCTX; i++) {
- ctx[i] = talloc_init("torture(%d)", i);
- }
-
- for (i = 0; i < NCTX; i++) {
- int j;
- for (j = 0; j < NOBJ; j++) {
- char *p;
- size_t size = 1<<(i/3+j);
-
- p = talloc(ctx[i], size);
- if (!p) {
- fprintf(stderr,
- "failed to talloc %.0f bytes\n",
- (double) size);
- exit(1);
- }
-
- memset(p, 'A' + j, size);
- }
- }
-
- for (i = 0; i < NCTX; i++) {
- printf("talloc@%p %-40s %ldkB\n", ctx[i],
- talloc_pool_name(ctx[i]),
- (unsigned long)talloc_pool_size(ctx[i]) >> 10);
- }
-
- printf("%s", talloc_describe_all(ctx[0]));
-
- for (i = NCTX - 1; i >= 0; i--)
- talloc_destroy(ctx[i]);
-
- return 0;
-}
diff --git a/source/lib/time.c b/source/lib/time.c
index faca2cba879..aa433a769c6 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -1,8 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
time handling functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Andrew Tridgell 1992-1998
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -32,24 +33,15 @@ int extra_time_offset = 0;
#define CHAR_BIT 8
#endif
-#ifndef TIME_T_MIN
-#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
- : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
-#endif
-#ifndef TIME_T_MAX
-#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
-#endif
-
-void get_nttime_max(NTTIME *t)
-{
- /* FIXME: This is incorrect */
- unix_to_nt_time(t, get_time_t_max());
-}
-
/*******************************************************************
External access to time_t_min and time_t_max.
********************************************************************/
+time_t get_time_t_min(void)
+{
+ return TIME_T_MIN;
+}
+
time_t get_time_t_max(void)
{
return TIME_T_MAX;
@@ -129,7 +121,7 @@ static int get_serverzone(void)
/* Re-read the smb serverzone value */
-static struct timeval start_time_hires;
+static struct timeval start_time_hires;
void TimeInit(void)
{
@@ -145,11 +137,11 @@ void TimeInit(void)
done before a daemon fork then this is the start time from the parent
daemon start. JRA.
***********************************************************************/
-
+
void get_process_uptime(struct timeval *ret_time)
{
struct timeval time_now_hires;
-
+
GetTimeOfDay(&time_now_hires);
ret_time->tv_sec = time_now_hires.tv_sec - start_time_hires.tv_sec;
ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;
@@ -308,8 +300,7 @@ time_t nt_time_to_unix(NTTIME *nt)
time_t l_time_min = TIME_T_MIN;
time_t l_time_max = TIME_T_MAX;
- if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff))
- return(0);
+ if (nt->high == 0) return(0);
d = ((double)nt->high)*4.0*(double)(1<<30);
d += (nt->low&0xFFF00000);
@@ -318,11 +309,8 @@ time_t nt_time_to_unix(NTTIME *nt)
/* now adjust by 369 years to make the secs since 1970 */
d -= TIME_FIXUP_CONSTANT;
- if (d <= l_time_min)
- return (l_time_min);
-
- if (d >= l_time_max)
- return (l_time_max);
+ if (!(l_time_min <= d && d <= l_time_max))
+ return(0);
ret = (time_t)(d+0.5);
@@ -334,14 +322,13 @@ time_t nt_time_to_unix(NTTIME *nt)
}
/****************************************************************************
- Convert a NTTIME structure to a time_t.
- It's originally in "100ns units".
+convert a NTTIME structure to a time_t
+It's originally in "100ns units"
- This is an absolute version of the one above.
- By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970
- if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
+this is an absolute version of the one above.
+By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970
+if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
****************************************************************************/
-
time_t nt_time_to_unix_abs(NTTIME *nt)
{
double d;
@@ -371,9 +358,15 @@ time_t nt_time_to_unix_abs(NTTIME *nt)
ret = (time_t)(d+0.5);
+ /* this takes us from kludge-GMT to real GMT */
+ ret -= get_serverzone();
+ ret += LocTimeDiff(ret);
+
return(ret);
}
+
+
/****************************************************************************
interprets an nt time into a unix time_t
****************************************************************************/
@@ -424,13 +417,12 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
}
/****************************************************************************
- Convert a time_t to a NTTIME structure
+convert a time_t to a NTTIME structure
- This is an absolute version of the one above.
- By absolute I mean, it doesn't adjust from 1/1/1970 to 1/1/1601
- If the nttime_t was 5 seconds, the NTTIME is 5 seconds. JFM
+this is an absolute version of the one above.
+By absolute I mean, it doesn't adjust from 1/1/1970 to 1/1/1601
+if the nttime_t was 5 seconds, the NTTIME is 5 seconds. JFM
****************************************************************************/
-
void unix_to_nt_time_abs(NTTIME *nt, time_t t)
{
double d;
@@ -454,6 +446,9 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t)
return;
}
+ /* this converts GMT to kludge-GMT */
+ t -= LocTimeDiff(t) - get_serverzone();
+
d = (double)(t);
d *= 1.0e7;
@@ -465,9 +460,10 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t)
nt->low=~nt->low;
}
+
/****************************************************************************
-take a Unix time and convert to an NTTIME structure and place in buffer
-pointed to by p.
+take an NTTIME structure, containing high / low time. convert to unix time.
+lkclXXXX this may need 2 SIVALs not a memcpy. we'll see...
****************************************************************************/
void put_long_date(char *p,time_t t)
{
@@ -482,7 +478,7 @@ check if it's a null mtime
****************************************************************************/
BOOL null_mtime(time_t mtime)
{
- if (mtime == 0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1)
+ if (mtime == 0 || mtime == 0xFFFFFFFF || mtime == (time_t)-1)
return(True);
return(False);
}
@@ -693,7 +689,7 @@ char *timestring(BOOL hires)
".%06ld",
(long)tp.tv_usec);
} else {
- strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
+ strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm);
}
#else
if (hires) {
@@ -744,13 +740,3 @@ void init_nt_time(NTTIME *nt)
nt->high = 0x7FFFFFFF;
nt->low = 0xFFFFFFFF;
}
-
-/****************************************************************************
-check if NTTIME is 0
-****************************************************************************/
-BOOL nt_time_is_zero(NTTIME *nt)
-{
- if(nt->high==0)
- return True;
- return False;
-}
diff --git a/source/lib/username.c b/source/lib/username.c
index ac5530b5c71..263ffb57aed 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Username handling
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1997-2001.
@@ -22,61 +23,62 @@
#include "includes.h"
/* internal functions */
-static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (const char *), int N);
-static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (const char *), int N);
+static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (char *), int N);
+static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
/*****************************************************************
Check if a user or group name is local (this is a *local* name for
*local* people, there's nothing for you here...).
*****************************************************************/
-static BOOL name_is_local(const char *name)
+BOOL name_is_local(const char *name)
{
- return !(strchr_m(name, *lp_winbind_separator()));
+ return !strchr(name, *lp_winbind_separator());
}
-/*****************************************************************
- Splits passed user or group name to domain and user/group name parts
- Returns True if name was splitted and False otherwise.
-*****************************************************************/
+/****************************************************************************
+ Get a users home directory.
+****************************************************************************/
-BOOL split_domain_and_name(const char *name, char *domain, char* username)
+char *get_user_home_dir(char *user)
{
- char *p = strchr(name,*lp_winbind_separator());
-
-
- /* Parse a string of the form DOMAIN/user into a domain and a user */
- DEBUG(10,("split_domain_and_name: checking whether name |%s| local or not\n", name));
-
- if (p) {
- fstrcpy(username, p+1);
- fstrcpy(domain, name);
- domain[PTR_DIFF(p, name)] = 0;
- } else if (lp_winbind_use_default_domain()) {
- fstrcpy(username, name);
- fstrcpy(domain, lp_workgroup());
- } else {
- return False;
- }
+ static struct passwd *pass;
- DEBUG(10,("split_domain_and_name: all is fine, domain is |%s| and name is |%s|\n", domain, username));
- return True;
+ pass = Get_Pwnam(user, False);
+ if (!pass)
+ return(NULL);
+ /* Return home directory from struct passwd. */
+ return(pass->pw_dir);
}
/****************************************************************************
- Get a users home directory.
+ Get a users home service directory.
****************************************************************************/
-char *get_user_home_dir(const char *user)
+char *get_user_service_home_dir(char *user)
{
static struct passwd *pass;
+ int snum;
/* Ensure the user exists. */
- pass = Get_Pwnam(user);
-
+ pass = Get_Pwnam(user, False);
if (!pass)
return(NULL);
+
+ /* If a path is specified in [homes] then use it instead of the
+ user's home directory from struct passwd. */
+
+ if ((snum = lp_servicenumber(HOMES_NAME)) != -1) {
+ static pstring home_dir;
+
+ pstrcpy(home_dir, lp_pathname(snum));
+ standard_sub_home(snum, user, home_dir, sizeof(home_dir));
+
+ if (home_dir[0])
+ return home_dir;
+ }
+
/* Return home directory from struct passwd. */
return(pass->pw_dir);
@@ -97,7 +99,7 @@ BOOL map_username(char *user)
{
static BOOL initialised=False;
static fstring last_from,last_to;
- XFILE *f;
+ FILE *f;
char *mapfile = lp_username_map();
char *s;
pstring buf;
@@ -123,7 +125,7 @@ BOOL map_username(char *user)
return True;
}
- f = x_fopen(mapfile,O_RDONLY, 0);
+ f = sys_fopen(mapfile,"r");
if (!f) {
DEBUG(0,("can't open username map %s. Error %s\n",mapfile, strerror(errno) ));
return False;
@@ -133,8 +135,7 @@ BOOL map_username(char *user)
while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
char *unixname = s;
- char *dosname = strchr_m(unixname,'=');
- char **dosuserlist;
+ char *dosname = strchr(unixname,'=');
BOOL return_if_mapped = False;
if (!dosname)
@@ -144,15 +145,15 @@ BOOL map_username(char *user)
while (isspace((int)*unixname))
unixname++;
-
if ('!' == *unixname) {
return_if_mapped = True;
unixname++;
+
while (*unixname && isspace((int)*unixname))
unixname++;
}
- if (!*unixname || strchr_m("#;",*unixname))
+ if (!*unixname || strchr("#;",*unixname))
continue;
{
@@ -163,29 +164,20 @@ BOOL map_username(char *user)
}
}
- dosuserlist = str_list_make(dosname, NULL);
- if (!dosuserlist) {
- DEBUG(0,("Unable to build user list\n"));
- return False;
- }
-
- if (strchr_m(dosname,'*') || user_in_list(user, (const char **)dosuserlist, NULL, 0)) {
+ if (strchr(dosname,'*') || user_in_list(user,dosname)) {
DEBUG(3,("Mapped user %s to %s\n",user,unixname));
mapped_user = True;
fstrcpy(last_from,user);
sscanf(unixname,"%s",user);
fstrcpy(last_to,user);
- if(return_if_mapped) {
- str_list_free (&dosuserlist);
- x_fclose(f);
+ if(return_if_mapped) {
+ fclose(f);
return True;
}
}
-
- str_list_free (&dosuserlist);
}
- x_fclose(f);
+ fclose(f);
/*
* Setup the last_from and last_to as an optimization so
@@ -198,116 +190,107 @@ BOOL map_username(char *user)
}
/****************************************************************************
- * A wrapper for sys_getpwnam(). The following variations are tried:
- * - as transmitted
- * - in all lower case if this differs from transmitted
- * - in all upper case if this differs from transmitted
- * - using lp_usernamelevel() for permutations.
+ Get_Pwnam wrapper.
****************************************************************************/
-static struct passwd *Get_Pwnam_ret = NULL;
-
-static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
+static struct passwd *_Get_Pwnam(char *s)
{
- struct passwd *ret = NULL;
-
- if (!user2 || !(*user2))
- return(NULL);
-
- if (!user || !(*user))
- return(NULL);
+ struct passwd *ret;
- /* Try in all lower case first as this is the most
- common case on UNIX systems */
- strlower_m(user2);
- DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
- ret = getpwnam_alloc(user2);
- if(ret)
- goto done;
-
- /* Try as given, if username wasn't originally lowercase */
- if(strcmp(user, user2) != 0) {
- DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n", user));
- ret = getpwnam_alloc(user);
- if(ret)
- goto done;
+ ret = sys_getpwnam(s);
+ if (ret) {
+#ifdef HAVE_GETPWANAM
+ struct passwd_adjunct *pwret;
+ pwret = getpwanam(s);
+ if (pwret && pwret->pwa_passwd)
+ pstrcpy(ret->pw_passwd,pwret->pwa_passwd);
+#endif
}
- /* Try as uppercase, if username wasn't originally uppercase */
- strupper_m(user2);
- if(strcmp(user, user2) != 0) {
- DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n", user2));
- ret = getpwnam_alloc(user2);
- if(ret)
- goto done;
- }
+ return(ret);
+}
- /* Try all combinations up to usernamelevel */
- strlower_m(user2);
- DEBUG(5,("Checking combinations of %d uppercase letters in %s\n", lp_usernamelevel(), user2));
- ret = uname_string_combinations(user2, getpwnam_alloc, lp_usernamelevel());
+/****************************************************************************
+ A wrapper for getpwnam(). The following variations are tried...
+ - in all lower case
+ - as transmitted IF a different case
+ - in all upper case IF that is different from the transmitted username
+ - using the lp_usernamelevel() for permutations
+ Note that this can change user! The user name is in Unix code page.
+****************************************************************************/
-done:
- DEBUG(5,("Get_Pwnam_internals %s find user [%s]!\n",ret ? "did":"didn't", user));
+struct passwd *Get_Pwnam(char *user,BOOL allow_change)
+{
+ fstring user2, orig_username;
+ int usernamelevel = lp_usernamelevel();
+ struct passwd *ret;
- /* This call used to just return the 'passwd' static buffer.
- This could then have accidental reuse implications, so
- we now malloc a copy, and free it in the next use.
+ if (!user || !(*user))
+ return(NULL);
- This should cause the (ab)user to segfault if it
- uses an old struct.
-
- This is better than useing the wrong data in security
- critical operations.
+ /* make a few copies to work with */
+ fstrcpy(orig_username, user);
+ if (!allow_change) {
+ /* allow_change was False, so make a copy and temporarily
+ assign the char* user to the temp copy */
+ fstrcpy(user2,user);
+ user = &user2[0];
+ }
- The real fix is to make the callers free the returned
- malloc'ed data.
- */
+ /* try in all lower case first as this is the most
+ common case on UNIX systems */
+ unix_to_dos(user);
+ strlower(user);
+ dos_to_unix(user);
- if (Get_Pwnam_ret) {
- passwd_free(&Get_Pwnam_ret);
- }
+ ret = _Get_Pwnam(user);
+ if (ret)
+ return(ret);
- Get_Pwnam_ret = ret;
-
- return ret;
-}
+ /* try as transmitted, but only if the original username
+ gives us a different case */
+ if (strcmp(user, orig_username) != 0) {
+ ret = _Get_Pwnam(orig_username);
+ if (ret) {
+ if (allow_change)
+ fstrcpy(user, orig_username);
-/****************************************************************************
- Get_Pwnam wrapper without modification.
- NOTE: This with NOT modify 'user'!
-****************************************************************************/
+ return(ret);
+ }
+ }
-struct passwd *Get_Pwnam(const char *user)
-{
- fstring user2;
- struct passwd *ret;
+ /* finally, try in all caps if that is a new case */
+ unix_to_dos(user);
+ strupper(user);
+ dos_to_unix(user);
- if ( *user == '\0' ) {
- DEBUG(10,("Get_Pwnam: empty username!\n"));
- return NULL;
+ if (strcmp(user, orig_username) != 0) {
+ ret = _Get_Pwnam(user);
+ if (ret)
+ return(ret);
}
- fstrcpy(user2, user);
+ /* Try all combinations up to usernamelevel. */
+ unix_to_dos(user);
+ strlower(user);
+ dos_to_unix(user);
- DEBUG(5,("Finding user %s\n", user));
+ ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
- ret = Get_Pwnam_internals(user, user2);
-
- return ret;
+ if (ret)
+ return(ret);
+
+ return(NULL);
}
/****************************************************************************
- Check if a user is in a netgroup user list. If at first we don't succeed,
- try lower case.
+ Check if a user is in a netgroup user list.
****************************************************************************/
-static BOOL user_in_netgroup_list(const char *user, const char *ngname)
+static BOOL user_in_netgroup_list(char *user,char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
- fstring lowercase_user, lowercase_ngname;
-
if (mydomain == NULL)
yp_get_default_domain(&mydomain);
@@ -319,24 +302,10 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
user, mydomain, ngname));
DEBUG(5,("innetgr is %s\n", innetgr(ngname, NULL, user, mydomain)
- ? "TRUE" : "FALSE"));
+ ? "True" : "False"));
if (innetgr(ngname, NULL, user, mydomain))
return (True);
-
- /*
- * Ok, innetgr is case sensitive. Try once more with lowercase
- * just in case. Attempt to fix #703. JRA.
- */
-
- fstrcpy(lowercase_user, user);
- strlower_m(lowercase_user);
- fstrcpy(lowercase_ngname, ngname);
- strlower_m(lowercase_ngname);
-
- if (innetgr(lowercase_ngname, NULL, lowercase_user, mydomain))
- return (True);
-
#endif /* HAVE_NETGROUP */
return False;
}
@@ -345,81 +314,55 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
Check if a user is in a winbind group.
****************************************************************************/
-static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL *winbind_answered)
+static BOOL user_in_winbind_group_list(char *user,char *gname, BOOL *winbind_answered)
{
+ int num_groups;
int i;
- gid_t gid, gid_low, gid_high;
+ gid_t *groups = NULL;
+ gid_t gid;
BOOL ret = False;
- static gid_t *groups = NULL;
- static int num_groups = 0;
- static fstring last_user = "";
*winbind_answered = False;
- if ((gid = nametogid(gname)) == (gid_t)-1) {
- DEBUG(0,("user_in_winbind_group_list: nametogid for group %s failed.\n",
- gname ));
- goto err;
- }
-
- if (!lp_idmap_gid(&gid_low, &gid_high)) {
- DEBUG(4, ("winbind gid range not configured, therefore %s cannot be a winbind group\n", gname));
- goto err;
- }
-
- if (gid < gid_low || gid > gid_high) {
- DEBUG(4, ("group %s is not a winbind group\n", gname));
- goto err;
- }
+ /*
+ * Get the gid's that this user belongs to.
+ */
- /* try to user the last user we looked up */
- /* otherwise fall back to lookups */
-
- if ( !strequal( last_user, user ) || !groups )
- {
- /* clear any cached information */
-
- SAFE_FREE(groups);
- fstrcpy( last_user, "" );
-
- /*
- * Get the gid's that this user belongs to.
- */
+ if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
+ return False;
- if ((num_groups = winbind_getgroups(user, &groups)) == -1)
- return False;
-
- if ( num_groups == -1 )
- return False;
+ if (num_groups == 0) {
+ *winbind_answered = True;
+ return False;
+ }
- if ( num_groups == 0 ) {
- *winbind_answered = True;
- return False;
- }
-
- /* save the last username */
-
- fstrcpy( last_user, user );
-
- }
- else
- DEBUG(10,("user_in_winbind_group_list: using cached user groups for [%s]\n", user));
+ if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
+ DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
+ goto err;
+ }
- if ( DEBUGLEVEL >= 10 ) {
- DEBUG(10,("user_in_winbind_group_list: using groups -- "));
- for ( i=0; i<num_groups; i++ )
- DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
- DEBUGADD(10,("\n"));
+ if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
+ DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
+failed with error %s\n", strerror(errno) ));
+ goto err;
}
- /*
- * Now we have the gid list for this user - convert the gname
- * to a gid_t via either winbind or the local UNIX lookup and do the comparison.
- */
+ /*
+ * Now we have the gid list for this user - convert the gname
+ * to a gid_t via either winbind or the local UNIX lookup and do the comparison.
+ */
+
+ if ((gid = nametogid(gname)) == (gid_t)-1) {
+ DEBUG(0,("user_in_winbind_group_list: winbind_lookup_name for group %s failed.\n",
+ gname ));
+ goto err;
+ }
for (i = 0; i < num_groups; i++) {
if (gid == groups[i]) {
- ret = True;
+ ret = True;
+ DEBUG(10,("user_in_winbind_group_list: user |%s| is in group |%s|\n",
+ user, gname ));
break;
}
}
@@ -437,11 +380,12 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
/****************************************************************************
Check if a user is in a UNIX group.
+ Names are in UNIX character set format.
****************************************************************************/
-BOOL user_in_unix_group_list(const char *user,const char *gname)
+static BOOL user_in_unix_group_list(char *user,const char *gname)
{
- struct passwd *pass = Get_Pwnam(user);
+ struct passwd *pass = Get_Pwnam(user,False);
struct sys_userlist *user_list;
struct sys_userlist *member;
@@ -453,7 +397,7 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
*/
if (pass) {
- if (strequal(gname,gidtoname(pass->pw_gid))) {
+ if (strequal_unix(gname, gidtoname(pass->pw_gid))) {
DEBUG(10,("user_in_unix_group_list: group %s is primary group.\n", gname ));
return True;
}
@@ -468,8 +412,9 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
for (member = user_list; member; member = member->next) {
DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n",
user, member->unix_name ));
- if (strequal(member->unix_name,user)) {
+ if (strequal_unix(member->unix_name,user)) {
free_userlist(user_list);
+ DEBUG(10,("user_in_unix_group_list: user |%s| is in group |%s|\n", user, gname));
return(True);
}
}
@@ -480,29 +425,13 @@ BOOL user_in_unix_group_list(const char *user,const char *gname)
/****************************************************************************
Check if a user is in a group list. Ask winbind first, then use UNIX.
+ Names are in UNIX character set format.
****************************************************************************/
-BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups, size_t n_groups)
+BOOL user_in_group_list(char *user,char *gname)
{
BOOL winbind_answered = False;
BOOL ret;
- gid_t gid;
- unsigned i;
-
- gid = nametogid(gname);
- if (gid == (gid_t)-1)
- return False;
-
- if (groups && n_groups > 0) {
- for (i=0; i < n_groups; i++) {
- if (groups[i] == gid) {
- return True;
- }
- }
- return False;
- }
-
- /* fallback if we don't yet have the group list */
ret = user_in_winbind_group_list(user, gname, &winbind_answered);
if (!winbind_answered)
@@ -516,48 +445,51 @@ BOOL user_in_group_list(const char *user, const char *gname, gid_t *groups, size
/****************************************************************************
Check if a user is in a user list - can check combinations of UNIX
and netgroup lists.
+ Names are in UNIX character set format.
****************************************************************************/
-BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_groups)
+BOOL user_in_list(char *user,char *list)
{
- if (!list || !*list)
- return False;
+ pstring tok;
+ const char *p=list;
- DEBUG(10,("user_in_list: checking user %s in list\n", user));
+ DEBUG(10,("user_in_list: checking user %s in list %s\n", user, list));
- while (*list) {
+ while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
- DEBUG(10,("user_in_list: checking user |%s| against |%s|\n", user, *list));
+ DEBUG(10,("user_in_list: checking user |%s| against |%s|\n", user, tok));
/*
* Check raw username.
*/
- if (strequal(user, *list))
+ if (strequal_unix(user,tok)) {
+ DEBUG(10,("user_in_list: user |%s| matches |%s|\n", user, tok));
return(True);
+ }
/*
* Now check to see if any combination
* of UNIX and netgroups has been specified.
*/
- if(**list == '@') {
+ if(*tok == '@') {
/*
* Old behaviour. Check netgroup list
* followed by UNIX list.
*/
- if(user_in_netgroup_list(user, *list +1))
+ if(user_in_netgroup_list(user,&tok[1]))
return True;
- if(user_in_group_list(user, *list +1, groups, n_groups))
+ if(user_in_group_list(user,&tok[1]))
return True;
- } else if (**list == '+') {
+ } else if (*tok == '+') {
- if((*(*list +1)) == '&') {
+ if(tok[1] == '&') {
/*
* Search UNIX list followed by netgroup.
*/
- if(user_in_group_list(user, *list +2, groups, n_groups))
+ if(user_in_group_list(user,&tok[2]))
return True;
- if(user_in_netgroup_list(user, *list +2))
+ if(user_in_netgroup_list(user,&tok[2]))
return True;
} else {
@@ -566,28 +498,28 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
* Just search UNIX list.
*/
- if(user_in_group_list(user, *list +1, groups, n_groups))
+ if(user_in_group_list(user,&tok[1]))
return True;
}
- } else if (**list == '&') {
+ } else if (*tok == '&') {
- if(*(*list +1) == '+') {
+ if(tok[1] == '+') {
/*
* Search netgroup list followed by UNIX list.
*/
- if(user_in_netgroup_list(user, *list +2))
+ if(user_in_netgroup_list(user,&tok[2]))
return True;
- if(user_in_group_list(user, *list +2, groups, n_groups))
+ if(user_in_group_list(user,&tok[2]))
return True;
} else {
/*
* Just search netgroup list.
*/
- if(user_in_netgroup_list(user, *list +1))
+ if(user_in_netgroup_list(user,&tok[1]))
return True;
}
- } else if (!name_is_local(*list)) {
+ } else if (!name_is_local(tok)) {
/*
* If user name did not match and token is not
* a unix group and the token has a winbind separator in the
@@ -598,40 +530,19 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
enum SID_NAME_USE name_type;
BOOL winbind_answered = False;
BOOL ret;
- fstring groupname, domain;
-
- /* Parse a string of the form DOMAIN/user into a domain and a user */
-
- char *p = strchr(*list,*lp_winbind_separator());
-
- DEBUG(10,("user_in_list: checking if user |%s| is in winbind group |%s|\n", user, *list));
-
- if (p) {
- fstrcpy(groupname, p+1);
- fstrcpy(domain, *list);
- domain[PTR_DIFF(p, *list)] = 0;
-
- /* Check to see if name is a Windows group; Win2k native mode DCs
- will return domain local groups; while NT4 or mixed mode 2k DCs
- will not */
-
- if ( winbind_lookup_name(domain, groupname, &g_sid, &name_type)
- && ( name_type==SID_NAME_DOM_GRP ||
- (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) )
- {
-
- /* Check if user name is in the Windows group */
- ret = user_in_winbind_group_list(user, *list, &winbind_answered);
-
- if (winbind_answered && ret == True) {
- DEBUG(10,("user_in_list: user |%s| is in winbind group |%s|\n", user, *list));
- return ret;
- }
+
+ /* Check to see if name is a Windows group */
+ if (winbind_lookup_name(NULL, tok, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+
+ /* Check if user name is in the Windows group */
+ ret = user_in_winbind_group_list(user, tok, &winbind_answered);
+
+ if (winbind_answered && ret == True) {
+ DEBUG(10,("user_in_list: user |%s| is in group |%s|\n", user, tok));
+ return ret;
}
}
}
-
- list++;
}
return(False);
}
@@ -645,7 +556,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
it assumes the string starts lowercased
****************************************************************************/
-static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(const char *),int N)
+static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(char *),int N)
{
ssize_t len = (ssize_t)strlen(s);
int i;
@@ -675,7 +586,7 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
it assumes the string starts lowercased
****************************************************************************/
-static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(const char *),int N)
+static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(char *),int N)
{
int n;
struct passwd *ret;
@@ -688,3 +599,32 @@ static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(c
return(NULL);
}
+
+/****************************************************************************
+these wrappers allow appliance mode to work. In appliance mode the username
+takes the form DOMAIN/user
+****************************************************************************/
+struct passwd *smb_getpwnam(char *user, BOOL allow_change)
+{
+ struct passwd *pw;
+ char *p;
+ char *sep;
+ extern pstring global_myname;
+
+ pw = Get_Pwnam(user, allow_change);
+ if (pw)
+ return pw;
+
+ /*
+ * If it is a domain qualified name and it isn't in our password
+ * database but the domain portion matches our local machine name then
+ * lookup just the username portion locally.
+ */
+
+ sep = lp_winbind_separator();
+ p = strchr(user,*sep);
+ if (p && strncasecmp(global_myname, user, strlen(global_myname))==0)
+ return Get_Pwnam(p+1, allow_change);
+
+ return NULL;
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 527e1376d1c..bbcbc2e60cd 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Jeremy Allison 2001
Copyright (C) Simo Sorce 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,13 +46,16 @@
#include <rpcsvc/nis.h>
-#else /* !WITH_NISPLUS_HOME */
-
-#include "rpcsvc/ypclnt.h"
-
#endif /* WITH_NISPLUS_HOME */
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
+#ifdef WITH_SSL
+#include <openssl/ssl.h>
+#undef Realloc /* SSLeay defines this and samba has a function of this name */
+extern SSL *ssl;
+extern int sslFd;
+#endif /* WITH_SSL */
+
int Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
@@ -63,212 +66,35 @@ int chain_size = 0;
int trans_num = 0;
-static enum remote_arch_types ra_type = RA_UNKNOWN;
-pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
-
-/***********************************************************************
- Definitions for all names.
-***********************************************************************/
-
-static char *smb_myname;
-static char *smb_myworkgroup;
-static char *smb_scope;
-static int smb_num_netbios_names;
-static char **smb_my_netbios_names;
-
-/***********************************************************************
- Allocate and set myname. Ensure upper case.
-***********************************************************************/
-
-BOOL set_global_myname(const char *myname)
-{
- SAFE_FREE(smb_myname);
- smb_myname = strdup(myname);
- if (!smb_myname)
- return False;
- strupper_m(smb_myname);
- return True;
-}
-
-const char *global_myname(void)
-{
- return smb_myname;
-}
-
-/***********************************************************************
- Allocate and set myworkgroup. Ensure upper case.
-***********************************************************************/
-
-BOOL set_global_myworkgroup(const char *myworkgroup)
-{
- SAFE_FREE(smb_myworkgroup);
- smb_myworkgroup = strdup(myworkgroup);
- if (!smb_myworkgroup)
- return False;
- strupper_m(smb_myworkgroup);
- return True;
-}
-
-const char *lp_workgroup(void)
-{
- return smb_myworkgroup;
-}
-
-/***********************************************************************
- Allocate and set scope. Ensure upper case.
-***********************************************************************/
-
-BOOL set_global_scope(const char *scope)
-{
- SAFE_FREE(smb_scope);
- smb_scope = strdup(scope);
- if (!smb_scope)
- return False;
- strupper_m(smb_scope);
- return True;
-}
-
-/*********************************************************************
- Ensure scope is never null string.
-*********************************************************************/
-
-const char *global_scope(void)
-{
- if (!smb_scope)
- set_global_scope("");
- return smb_scope;
-}
-
-static void free_netbios_names_array(void)
-{
- int i;
-
- for (i = 0; i < smb_num_netbios_names; i++)
- SAFE_FREE(smb_my_netbios_names[i]);
-
- SAFE_FREE(smb_my_netbios_names);
- smb_num_netbios_names = 0;
-}
-
-static BOOL allocate_my_netbios_names_array(size_t number)
-{
- free_netbios_names_array();
-
- smb_num_netbios_names = number + 1;
- smb_my_netbios_names = (char **)malloc( sizeof(char *) * smb_num_netbios_names );
-
- if (!smb_my_netbios_names)
- return False;
-
- memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
- return True;
-}
-
-static BOOL set_my_netbios_names(const char *name, int i)
-{
- SAFE_FREE(smb_my_netbios_names[i]);
-
- smb_my_netbios_names[i] = strdup(name);
- if (!smb_my_netbios_names[i])
- return False;
- strupper_m(smb_my_netbios_names[i]);
- return True;
-}
-
-const char *my_netbios_names(int i)
-{
- return smb_my_netbios_names[i];
-}
-
-BOOL set_netbios_aliases(const char **str_array)
-{
- size_t namecount;
-
- /* Work out the max number of netbios aliases that we have */
- for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
- ;
+/*
+ case handling on filenames
+*/
+int case_default = CASE_LOWER;
- if ( global_myname() && *global_myname())
- namecount++;
+/* the following control case operations - they are put here so the
+ client can link easily */
+BOOL case_sensitive;
+BOOL case_preserve;
+BOOL use_mangled_map = False;
+BOOL short_case_preserve;
+BOOL case_mangle;
- /* Allocate space for the netbios aliases */
- if (!allocate_my_netbios_names_array(namecount))
- return False;
+static enum remote_arch_types ra_type = RA_UNKNOWN;
+pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
- /* Use the global_myname string first */
- namecount=0;
- if ( global_myname() && *global_myname()) {
- set_my_netbios_names( global_myname(), namecount );
- namecount++;
- }
+pstring global_myname = "";
+fstring global_myworkgroup = "";
+char **my_netbios_names;
- if (str_array) {
- size_t i;
- for ( i = 0; str_array[i] != NULL; i++) {
- size_t n;
- BOOL duplicate = False;
-
- /* Look for duplicates */
- for( n=0; n<namecount; n++ ) {
- if( strequal( str_array[i], my_netbios_names(n) ) ) {
- duplicate = True;
- break;
- }
- }
- if (!duplicate) {
- if (!set_my_netbios_names(str_array[i], namecount))
- return False;
- namecount++;
- }
- }
- }
- return True;
-}
/****************************************************************************
- Common name initialization code.
-****************************************************************************/
-
-BOOL init_names(void)
-{
- extern fstring local_machine;
- char *p;
- int n;
-
- if (global_myname() == NULL || *global_myname() == '\0') {
- if (!set_global_myname(myhostname())) {
- DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
- return False;
- }
- }
-
- if (!set_netbios_aliases(lp_netbios_aliases())) {
- DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
- return False;
- }
-
- fstrcpy( local_machine, global_myname() );
- trim_char( local_machine, ' ', ' ' );
- p = strchr( local_machine, ' ' );
- if (p)
- *p = 0;
- strlower_m( local_machine );
-
- DEBUG( 5, ("Netbios name list:-\n") );
- for( n=0; my_netbios_names(n); n++ )
- DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names(n) ) );
-
- return( True );
-}
-
-/**************************************************************************n
Find a suitable temporary directory. The result should be copied immediately
as it may be overwritten by a subsequent call.
****************************************************************************/
const char *tmpdir(void)
{
- char *p;
+ const char *p;
if ((p = getenv("TMPDIR")))
return p;
return "/tmp";
@@ -278,7 +104,7 @@ const char *tmpdir(void)
Determine whether we are in the specified group.
****************************************************************************/
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
{
int i;
@@ -296,7 +122,7 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
Like atoi but gets the value up to the separator character.
****************************************************************************/
-static const char *Atoic(const char *p, int *n, const char *c)
+const char *Atoic(const char *p, int *n, const char *c)
{
if (!isdigit((int)*p)) {
DEBUG(5, ("Atoic: malformed number\n"));
@@ -308,7 +134,7 @@ static const char *Atoic(const char *p, int *n, const char *c)
while ((*p) && isdigit((int)*p))
p++;
- if (strchr_m(c, *p) == NULL) {
+ if (strchr(c, *p) == NULL) {
DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
return NULL;
}
@@ -332,9 +158,10 @@ const char *get_numlist(const char *p, uint32 **num, int *count)
while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
uint32 *tn;
-
+
tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
- if (tn == NULL) {
+ if (tn == NULL)
+ {
SAFE_FREE(*num);
return NULL;
} else
@@ -351,7 +178,7 @@ const char *get_numlist(const char *p, uint32 **num, int *count)
Check if a file exists - call vfs_file_exist for samba files.
********************************************************************/
-BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
+BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_STAT st;
if (!sbuf)
@@ -383,66 +210,61 @@ time_t file_modtime(const char *fname)
BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
{
- SMB_STRUCT_STAT st2;
- BOOL ret;
+ SMB_STRUCT_STAT st2;
+ BOOL ret;
- if (!st)
- st = &st2;
+ if (!st) st = &st2;
- if (sys_stat(dname,st) != 0)
- return(False);
+ if (sys_stat(dname,st) != 0)
+ return(False);
- ret = S_ISDIR(st->st_mode);
- if(!ret)
- errno = ENOTDIR;
- return ret;
+ ret = S_ISDIR(st->st_mode);
+ if(!ret)
+ errno = ENOTDIR;
+ return ret;
}
/*******************************************************************
- Returns the size in bytes of the named file.
+returns the size in bytes of the named file
********************************************************************/
-
SMB_OFF_T get_file_size(char *file_name)
{
- SMB_STRUCT_STAT buf;
- buf.st_size = 0;
- if(sys_stat(file_name,&buf) != 0)
- return (SMB_OFF_T)-1;
- return(buf.st_size);
+ SMB_STRUCT_STAT buf;
+ buf.st_size = 0;
+ if(sys_stat(file_name,&buf) != 0)
+ return (SMB_OFF_T)-1;
+ return(buf.st_size);
}
/*******************************************************************
- Return a string representing an attribute for a file.
+return a string representing an attribute for a file
********************************************************************/
-
char *attrib_string(uint16 mode)
{
- static fstring attrstr;
+ static fstring attrstr;
- attrstr[0] = 0;
+ attrstr[0] = 0;
- if (mode & aVOLID) fstrcat(attrstr,"V");
- if (mode & aDIR) fstrcat(attrstr,"D");
- if (mode & aARCH) fstrcat(attrstr,"A");
- if (mode & aHIDDEN) fstrcat(attrstr,"H");
- if (mode & aSYSTEM) fstrcat(attrstr,"S");
- if (mode & aRONLY) fstrcat(attrstr,"R");
+ if (mode & aVOLID) fstrcat(attrstr,"V");
+ if (mode & aDIR) fstrcat(attrstr,"D");
+ if (mode & aARCH) fstrcat(attrstr,"A");
+ if (mode & aHIDDEN) fstrcat(attrstr,"H");
+ if (mode & aSYSTEM) fstrcat(attrstr,"S");
+ if (mode & aRONLY) fstrcat(attrstr,"R");
- return(attrstr);
+ return(attrstr);
}
/*******************************************************************
- Show a smb message structure.
+ show a smb message structure
********************************************************************/
-
void show_msg(char *buf)
{
int i;
int bcc=0;
- if (!DEBUGLVL(5))
- return;
-
+ if (DEBUGLEVEL < 5) return;
+
DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
smb_len(buf),
(int)CVAL(buf,smb_com),
@@ -451,48 +273,49 @@ void show_msg(char *buf)
(int)SVAL(buf,smb_err),
(int)CVAL(buf,smb_flg),
(int)SVAL(buf,smb_flg2)));
- DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
+ DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
(int)SVAL(buf,smb_tid),
(int)SVAL(buf,smb_pid),
(int)SVAL(buf,smb_uid),
- (int)SVAL(buf,smb_mid)));
- DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
+ (int)SVAL(buf,smb_mid),
+ (int)CVAL(buf,smb_wct)));
for (i=0;i<(int)CVAL(buf,smb_wct);i++)
- DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
+ {
+ DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
-
+ }
+
bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
- DEBUGADD(5,("smb_bcc=%d\n",bcc));
+ DEBUG(5,("smb_bcc=%d\n",bcc));
- if (DEBUGLEVEL < 10)
- return;
+ if (DEBUGLEVEL < 10) return;
if (DEBUGLEVEL < 50)
+ {
bcc = MIN(bcc, 512);
+ }
- dump_data(10, smb_buf(buf), bcc);
+ dump_data(10, smb_buf(buf), bcc);
}
/*******************************************************************
- Set the length and marker of an smb packet.
+ set the length and marker of an smb packet
********************************************************************/
-
void smb_setlen(char *buf,int len)
{
- _smb_setlen(buf,len);
+ _smb_setlen(buf,len);
- SCVAL(buf,4,0xFF);
- SCVAL(buf,5,'S');
- SCVAL(buf,6,'M');
- SCVAL(buf,7,'B');
+ SCVAL(buf,4,0xFF);
+ SCVAL(buf,5,'S');
+ SCVAL(buf,6,'M');
+ SCVAL(buf,7,'B');
}
/*******************************************************************
- Setup the word count and byte count for a smb message.
+ setup the word count and byte count for a smb message
********************************************************************/
-
int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
{
if (zero)
@@ -504,9 +327,8 @@ int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
}
/*******************************************************************
- Setup only the byte count for a smb message.
+ setup only the byte count for a smb message
********************************************************************/
-
int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
@@ -516,161 +338,155 @@ int set_message_bcc(char *buf,int num_bytes)
}
/*******************************************************************
- Setup only the byte count for a smb message, using the end of the
- message as a marker.
+ setup only the byte count for a smb message, using the end of the
+ message as a marker
********************************************************************/
-
int set_message_end(void *outbuf,void *end_ptr)
{
return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
}
/*******************************************************************
- Reduce a file name, removing .. elements.
+reduce a file name, removing .. elements.
********************************************************************/
-
void dos_clean_name(char *s)
{
- char *p=NULL;
+ char *p=NULL;
- DEBUG(3,("dos_clean_name [%s]\n",s));
+ DEBUG(3,("dos_clean_name [%s]\n",s));
- /* remove any double slashes */
- all_string_sub(s, "\\\\", "\\", 0);
+ /* remove any double slashes */
+ all_string_sub(s, "\\\\", "\\", 0);
- while ((p = strstr_m(s,"\\..\\")) != NULL) {
- pstring s1;
+ while ((p = strstr(s,"\\..\\")) != NULL)
+ {
+ pstring s1;
- *p = 0;
- pstrcpy(s1,p+3);
+ *p = 0;
+ pstrcpy(s1,p+3);
- if ((p=strrchr_m(s,'\\')) != NULL)
- *p = 0;
- else
- *s = 0;
- pstrcat(s,s1);
- }
+ if ((p=strrchr(s,'\\')) != NULL)
+ *p = 0;
+ else
+ *s = 0;
+ pstrcat(s,s1);
+ }
- trim_string(s,NULL,"\\..");
+ trim_string(s,NULL,"\\..");
- all_string_sub(s, "\\.\\", "\\", 0);
+ all_string_sub(s, "\\.\\", "\\", 0);
}
/*******************************************************************
- Reduce a file name, removing .. elements.
+reduce a file name, removing .. elements.
********************************************************************/
-
void unix_clean_name(char *s)
{
- char *p=NULL;
+ char *p=NULL;
- DEBUG(3,("unix_clean_name [%s]\n",s));
+ DEBUG(3,("unix_clean_name [%s]\n",s));
- /* remove any double slashes */
- all_string_sub(s, "//","/", 0);
+ /* remove any double slashes */
+ all_string_sub(s, "//","/", 0);
- /* Remove leading ./ characters */
- if(strncmp(s, "./", 2) == 0) {
- trim_string(s, "./", NULL);
- if(*s == 0)
- pstrcpy(s,"./");
- }
+ /* Remove leading ./ characters */
+ if(strncmp(s, "./", 2) == 0) {
+ trim_string(s, "./", NULL);
+ if(*s == 0)
+ pstrcpy(s,"./");
+ }
- while ((p = strstr_m(s,"/../")) != NULL) {
- pstring s1;
+ while ((p = strstr(s,"/../")) != NULL)
+ {
+ pstring s1;
- *p = 0;
- pstrcpy(s1,p+3);
+ *p = 0;
+ pstrcpy(s1,p+3);
- if ((p=strrchr_m(s,'/')) != NULL)
- *p = 0;
- else
- *s = 0;
- pstrcat(s,s1);
- }
+ if ((p=strrchr(s,'/')) != NULL)
+ *p = 0;
+ else
+ *s = 0;
+ pstrcat(s,s1);
+ }
- trim_string(s,NULL,"/..");
+ trim_string(s,NULL,"/..");
}
/****************************************************************************
- Make a dir struct.
+ make a dir struct
****************************************************************************/
-
-void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL case_sensitive)
+void make_dir_struct(char *buf,const char *mask,const char *fname,SMB_OFF_T size,int mode,time_t date)
{
- char *p;
- pstring mask2;
+ char *p;
+ pstring mask2;
- pstrcpy(mask2,mask);
+ pstrcpy(mask2,mask);
- if ((mode & aDIR) != 0)
- size = 0;
+ if ((mode & aDIR) != 0)
+ size = 0;
- memset(buf+1,' ',11);
- if ((p = strchr_m(mask2,'.')) != NULL) {
- *p = 0;
- push_ascii(buf+1,mask2,8, 0);
- push_ascii(buf+9,p+1,3, 0);
- *p = '.';
- } else
- push_ascii(buf+1,mask2,11, 0);
+ memset(buf+1,' ',11);
+ if ((p = strchr(mask2,'.')) != NULL)
+ {
+ *p = 0;
+ memcpy(buf+1,mask2,MIN(strlen(mask2),8));
+ memcpy(buf+9,p+1,MIN(strlen(p+1),3));
+ *p = '.';
+ }
+ else
+ memcpy(buf+1,mask2,MIN(strlen(mask2),11));
- memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
- SCVAL(buf,21,mode);
- put_dos_date(buf,22,date);
- SSVAL(buf,26,size & 0xFFFF);
- SSVAL(buf,28,(size >> 16)&0xFFFF);
- push_ascii(buf+30,fname,12, case_sensitive ? 0 : STR_UPPER);
- DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
+ memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
+ SCVAL(buf,21,mode);
+ put_dos_date(buf,22,date);
+ SSVAL(buf,26,size & 0xFFFF);
+ SSVAL(buf,28,(size >> 16)&0xFFFF);
+ StrnCpy(buf+30,fname,12);
+ if (!case_sensitive)
+ strupper(buf+30);
+ DEBUG(8,("put name [%s] into dir struct\n",buf+30));
}
+
/*******************************************************************
- Close the low 3 fd's and open dev/null in their place.
+close the low 3 fd's and open dev/null in their place
********************************************************************/
-
-void close_low_fds(BOOL stderr_too)
+void close_low_fds(void)
{
#ifndef VALGRIND
- int fd;
- int i;
-
- close(0);
- close(1);
-
- if (stderr_too)
- close(2);
-
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- if (i == 2 && !stderr_too)
- continue;
-
- fd = sys_open("/dev/null",O_RDWR,0);
- if (fd < 0)
- fd = sys_open("/dev/null",O_WRONLY,0);
- if (fd < 0) {
- DEBUG(0,("Can't open /dev/null\n"));
- return;
- }
- if (fd != i) {
- DEBUG(0,("Didn't get file descriptor %d\n",i));
- return;
- }
- }
+ int fd;
+ int i;
+ close(0); close(1);
+#ifndef __INSURE__
+ close(2);
+#endif
+ /* try and use up these file descriptors, so silly
+ library routines writing to stdout etc won't cause havoc */
+ for (i=0;i<3;i++) {
+ fd = sys_open("/dev/null",O_RDWR,0);
+ if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
+ if (fd < 0) {
+ DEBUG(0,("Can't open /dev/null\n"));
+ return;
+ }
+ if (fd != i) {
+ DEBUG(0,("Didn't get file descriptor %d\n",i));
+ return;
+ }
+ }
#endif
}
/****************************************************************************
- Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
- else
- if SYSV use O_NDELAY
- if BSD use FNDELAY
+Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+else
+if SYSV use O_NDELAY
+if BSD use FNDELAY
****************************************************************************/
-
int set_blocking(int fd, BOOL set)
{
- int val;
+ int val;
#ifdef O_NONBLOCK
#define FLAG_TO_SET O_NONBLOCK
#else
@@ -681,13 +497,13 @@ int set_blocking(int fd, BOOL set)
#endif
#endif
- if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
- return -1;
- if(set) /* Turn blocking on - ie. clear nonblock flag */
- val &= ~FLAG_TO_SET;
- else
- val |= FLAG_TO_SET;
- return sys_fcntl_long( fd, F_SETFL, val);
+ if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
+ return -1;
+ if(set) /* Turn blocking on - ie. clear nonblock flag */
+ val &= ~FLAG_TO_SET;
+ else
+ val |= FLAG_TO_SET;
+ return sys_fcntl_long( fd, F_SETFL, val);
#undef FLAG_TO_SET
}
@@ -756,7 +572,7 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
Sleep for a specified number of milliseconds.
********************************************************************/
-void smb_msleep(unsigned int t)
+void msleep(unsigned int t)
{
unsigned int tdiff=0;
struct timeval tval,t1,t2;
@@ -793,12 +609,10 @@ void smb_msleep(unsigned int t)
Become a daemon, discarding the controlling terminal.
****************************************************************************/
-void become_daemon(BOOL Fork)
+void become_daemon(void)
{
- if (Fork) {
- if (sys_fork()) {
- _exit(0);
- }
+ if (sys_fork()) {
+ _exit(0);
}
/* detach from the terminal */
@@ -815,12 +629,11 @@ void become_daemon(BOOL Fork)
#endif /* HAVE_SETSID */
/* Close fd's 0,1,2. Needed if started by rsh */
- close_low_fds(False); /* Don't close stderr, let the debug system
- attach it to the logfile */
+ close_low_fds();
}
/****************************************************************************
- Put up a yes/no prompt.
+ Put up a yes/no prompt
****************************************************************************/
BOOL yesno(char *p)
@@ -862,23 +675,10 @@ void *Realloc(void *p,size_t size)
return(ret);
}
-void *Realloc_zero(void *ptr, size_t size)
-{
- void *tptr = NULL;
-
- tptr = Realloc(ptr, size);
- if(tptr == NULL)
- return NULL;
-
- memset((char *)tptr,'\0',size);
-
- return tptr;
-}
-
/****************************************************************************
Free memory, checks for NULL.
- Use directly SAFE_FREE()
- Exists only because we need to pass a function pointer somewhere --SSS
+use directly SAFE_FREE()
+exist only because we need to pass a function pointer somewhere --SSS
****************************************************************************/
void safe_free(void *p)
@@ -907,8 +707,7 @@ BOOL get_myname(char *my_name)
if (my_name) {
/* split off any parts after an initial . */
- char *p = strchr_m(hostname,'.');
-
+ char *p = strchr(hostname,'.');
if (p)
*p = 0;
@@ -919,80 +718,27 @@ BOOL get_myname(char *my_name)
}
/****************************************************************************
- Get my own canonical name, including domain.
-****************************************************************************/
-
-BOOL get_mydnsfullname(fstring my_dnsname)
-{
- static fstring dnshostname;
- struct hostent *hp;
-
- if (!*dnshostname) {
- /* get my host name */
- if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
- *dnshostname = '\0';
- DEBUG(0,("gethostname failed\n"));
- return False;
- }
-
- /* Ensure null termination. */
- dnshostname[sizeof(dnshostname)-1] = '\0';
-
- /* Ensure we get the cannonical name. */
- if (!(hp = sys_gethostbyname(dnshostname))) {
- *dnshostname = '\0';
- return False;
- }
- fstrcpy(dnshostname, hp->h_name);
- }
- fstrcpy(my_dnsname, dnshostname);
- return True;
-}
-
-/****************************************************************************
- Get my own domain name.
-****************************************************************************/
-
-BOOL get_mydnsdomname(fstring my_domname)
-{
- fstring domname;
- char *p;
-
- *my_domname = '\0';
- if (!get_mydnsfullname(domname)) {
- return False;
- }
- p = strchr_m(domname, '.');
- if (p) {
- p++;
- fstrcpy(my_domname, p);
- }
-
- return False;
-}
-
-/****************************************************************************
Interpret a protocol description string, with a default.
****************************************************************************/
-int interpret_protocol(const char *str,int def)
-{
- if (strequal(str,"NT1"))
- return(PROTOCOL_NT1);
- if (strequal(str,"LANMAN2"))
- return(PROTOCOL_LANMAN2);
- if (strequal(str,"LANMAN1"))
- return(PROTOCOL_LANMAN1);
- if (strequal(str,"CORE"))
- return(PROTOCOL_CORE);
- if (strequal(str,"COREPLUS"))
- return(PROTOCOL_COREPLUS);
- if (strequal(str,"CORE+"))
- return(PROTOCOL_COREPLUS);
+int interpret_protocol(char *str,int def)
+{
+ if (strequal(str,"NT1"))
+ return(PROTOCOL_NT1);
+ if (strequal(str,"LANMAN2"))
+ return(PROTOCOL_LANMAN2);
+ if (strequal(str,"LANMAN1"))
+ return(PROTOCOL_LANMAN1);
+ if (strequal(str,"CORE"))
+ return(PROTOCOL_CORE);
+ if (strequal(str,"COREPLUS"))
+ return(PROTOCOL_COREPLUS);
+ if (strequal(str,"CORE+"))
+ return(PROTOCOL_COREPLUS);
- DEBUG(0,("Unrecognised protocol level %s\n",str));
+ DEBUG(0,("Unrecognised protocol level %s\n",str));
- return(def);
+ return(def);
}
/****************************************************************************
@@ -1001,72 +747,67 @@ int interpret_protocol(const char *str,int def)
BOOL is_ipaddress(const char *str)
{
- BOOL pure_address = True;
- int i;
+ BOOL pure_address = True;
+ int i;
- for (i=0; pure_address && str[i]; i++)
- if (!(isdigit((int)str[i]) || str[i] == '.'))
- pure_address = False;
+ for (i=0; pure_address && str[i]; i++)
+ if (!(isdigit((int)str[i]) || str[i] == '.'))
+ pure_address = False;
- /* Check that a pure number is not misinterpreted as an IP */
- pure_address = pure_address && (strchr_m(str, '.') != NULL);
+ /* Check that a pure number is not misinterpreted as an IP */
+ pure_address = pure_address && (strchr(str, '.') != NULL);
- return pure_address;
+ return pure_address;
}
/****************************************************************************
- Interpret an internet address or name into an IP address in 4 byte form.
+interpret an internet address or name into an IP address in 4 byte form
****************************************************************************/
uint32 interpret_addr(const char *str)
{
- struct hostent *hp;
- uint32 res;
+ struct hostent *hp;
+ uint32 res;
- if (strcmp(str,"0.0.0.0") == 0)
- return(0);
- if (strcmp(str,"255.255.255.255") == 0)
- return(0xFFFFFFFF);
+ if (strcmp(str,"0.0.0.0") == 0) return(0);
+ if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
/* if it's in the form of an IP address then get the lib to interpret it */
- if (is_ipaddress(str)) {
- res = inet_addr(str);
- } else {
- /* otherwise assume it's a network name of some sort and use
- sys_gethostbyname */
- if ((hp = sys_gethostbyname(str)) == 0) {
- DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
- return 0;
- }
-
- if(hp->h_addr == NULL) {
- DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
- return 0;
- }
- putip((char *)&res,(char *)hp->h_addr);
- }
+ if (is_ipaddress(str)) {
+ res = inet_addr(str);
+ } else {
+ /* otherwise assume it's a network name of some sort and use
+ sys_gethostbyname */
+ if ((hp = sys_gethostbyname(str)) == 0) {
+ DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
+ return 0;
+ }
+ if(hp->h_addr == NULL) {
+ DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
+ return 0;
+ }
+ putip((char *)&res,(char *)hp->h_addr);
+ }
- if (res == (uint32)-1)
- return(0);
+ if (res == (uint32)-1) return(0);
- return(res);
+ return(res);
}
/*******************************************************************
- A convenient addition to interpret_addr().
-******************************************************************/
-
+ a convenient addition to interpret_addr()
+ ******************************************************************/
struct in_addr *interpret_addr2(const char *str)
{
- static struct in_addr ret;
- uint32 a = interpret_addr(str);
- ret.s_addr = a;
- return(&ret);
+ static struct in_addr ret;
+ uint32 a = interpret_addr(str);
+ ret.s_addr = a;
+ return(&ret);
}
/*******************************************************************
- Check if an IP is the 0.0.0.0.
-******************************************************************/
+ Check if an IP is the 0.0.0.0
+ ******************************************************************/
BOOL is_zero_ip(struct in_addr ip)
{
@@ -1076,20 +817,20 @@ BOOL is_zero_ip(struct in_addr ip)
}
/*******************************************************************
- Set an IP to 0.0.0.0.
-******************************************************************/
+ Set an IP to 0.0.0.0
+ ******************************************************************/
void zero_ip(struct in_addr *ip)
{
- static BOOL init;
- static struct in_addr ipzero;
+ static BOOL init;
+ static struct in_addr ipzero;
- if (!init) {
- ipzero = *interpret_addr2("0.0.0.0");
- init = True;
- }
+ if (!init) {
+ ipzero = *interpret_addr2("0.0.0.0");
+ init = True;
+ }
- *ip = ipzero;
+ *ip = ipzero;
}
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
@@ -1100,19 +841,20 @@ void zero_ip(struct in_addr *ip)
static void strip_mount_options( pstring *str)
{
- if (**str == '-') {
- char *p = *str;
- while(*p && !isspace(*p))
- p++;
- while(*p && isspace(*p))
- p++;
- if(*p) {
- pstring tmp_str;
-
- pstrcpy(tmp_str, p);
- pstrcpy(*str, tmp_str);
- }
- }
+ if (**str == '-')
+ {
+ char *p = *str;
+ while(*p && !isspace(*p))
+ p++;
+ while(*p && isspace(*p))
+ p++;
+ if(*p) {
+ pstring tmp_str;
+
+ pstrcpy(tmp_str, p);
+ pstrcpy(*str, tmp_str);
+ }
+ }
}
/*******************************************************************
@@ -1123,147 +865,154 @@ static void strip_mount_options( pstring *str)
*******************************************************************/
#ifdef WITH_NISPLUS_HOME
-char *automount_lookup(const char *user_name)
+char *automount_lookup(char *user_name)
{
- static fstring last_key = "";
- static pstring last_value = "";
+ static fstring last_key = "";
+ static pstring last_value = "";
- char *nis_map = (char *)lp_nis_home_map_name();
+ char *nis_map = (char *)lp_nis_home_map_name();
- char buffer[NIS_MAXATTRVAL + 1];
- nis_result *result;
- nis_object *object;
- entry_obj *entry;
+ char buffer[NIS_MAXATTRVAL + 1];
+ nis_result *result;
+ nis_object *object;
+ entry_obj *entry;
- if (strcmp(user_name, last_key)) {
- slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
- DEBUG(5, ("NIS+ querystring: %s\n", buffer));
+ if (strcmp(user_name, last_key))
+ {
+ slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
+ DEBUG(5, ("NIS+ querystring: %s\n", buffer));
- if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
- if (result->status != NIS_SUCCESS) {
- DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
- fstrcpy(last_key, ""); pstrcpy(last_value, "");
- } else {
- object = result->objects.objects_val;
- if (object->zo_data.zo_type == ENTRY_OBJ) {
- entry = &object->zo_data.objdata_u.en_data;
- DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
- DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
+ if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL))
+ {
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
+ fstrcpy(last_key, ""); pstrcpy(last_value, "");
+ }
+ else
+ {
+ object = result->objects.objects_val;
+ if (object->zo_data.zo_type == ENTRY_OBJ)
+ {
+ entry = &object->zo_data.objdata_u.en_data;
+ DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
+ DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
- pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
- pstring_sub(last_value, "&", user_name);
- fstrcpy(last_key, user_name);
- }
- }
- }
- nis_freeresult(result);
- }
+ pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
+ pstring_sub(last_value, "&", user_name);
+ fstrcpy(last_key, user_name);
+ }
+ }
+ }
+ nis_freeresult(result);
+ }
- strip_mount_options(&last_value);
+ strip_mount_options(&last_value);
- DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
- return last_value;
+ DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
+ return last_value;
}
#else /* WITH_NISPLUS_HOME */
-
-char *automount_lookup(const char *user_name)
+char *automount_lookup(char *user_name)
{
- static fstring last_key = "";
- static pstring last_value = "";
+ static fstring last_key = "";
+ static pstring last_value = "";
- int nis_error; /* returned by yp all functions */
- char *nis_result; /* yp_match inits this */
- int nis_result_len; /* and set this */
- char *nis_domain; /* yp_get_default_domain inits this */
- char *nis_map = (char *)lp_nis_home_map_name();
+ int nis_error; /* returned by yp all functions */
+ char *nis_result; /* yp_match inits this */
+ int nis_result_len; /* and set this */
+ char *nis_domain; /* yp_get_default_domain inits this */
+ char *nis_map = (char *)lp_nis_home_map_name();
- if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
- DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
- return last_value;
- }
+ if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
+ DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
+ return last_value;
+ }
- DEBUG(5, ("NIS Domain: %s\n", nis_domain));
-
- if (!strcmp(user_name, last_key)) {
- nis_result = last_value;
- nis_result_len = strlen(last_value);
- nis_error = 0;
- } else {
- if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
- &nis_result, &nis_result_len)) == 0) {
- if (!nis_error && nis_result_len >= sizeof(pstring)) {
- nis_result_len = sizeof(pstring)-1;
- }
- fstrcpy(last_key, user_name);
- strncpy(last_value, nis_result, nis_result_len);
- last_value[nis_result_len] = '\0';
- strip_mount_options(&last_value);
-
- } else if(nis_error == YPERR_KEY) {
-
- /* If Key lookup fails user home server is not in nis_map
- use default information for server, and home directory */
- last_value[0] = 0;
- DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
- user_name, nis_map));
- DEBUG(3, ("using defaults for server and home directory\n"));
- } else {
- DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
- yperr_string(nis_error), user_name, nis_map));
- }
- }
+ DEBUG(5, ("NIS Domain: %s\n", nis_domain));
+
+ if (!strcmp(user_name, last_key)) {
+ nis_result = last_value;
+ nis_result_len = strlen(last_value);
+ nis_error = 0;
+
+ } else {
- DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
- return last_value;
+ if ((nis_error = yp_match(nis_domain, nis_map,
+ user_name, strlen(user_name),
+ &nis_result, &nis_result_len)) == 0) {
+ if (!nis_error && nis_result_len >= sizeof(pstring)) {
+ nis_result_len = sizeof(pstring)-1;
+ }
+ fstrcpy(last_key, user_name);
+ strncpy(last_value, nis_result, nis_result_len);
+ last_value[nis_result_len] = '\0';
+ strip_mount_options(&last_value);
+
+ } else if(nis_error == YPERR_KEY) {
+
+ /* If Key lookup fails user home server is not in nis_map
+ use default information for server, and home directory */
+ last_value[0] = 0;
+ DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
+ user_name, nis_map));
+ DEBUG(3, ("using defaults for server and home directory\n"));
+ } else {
+ DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
+ yperr_string(nis_error), user_name, nis_map));
+ }
+ }
+
+
+ DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
+ return last_value;
}
#endif /* WITH_NISPLUS_HOME */
#endif
+
/*******************************************************************
- Are two IPs on the same subnet?
+are two IPs on the same subnet?
********************************************************************/
-
BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
{
- uint32 net1,net2,nmask;
+ uint32 net1,net2,nmask;
- nmask = ntohl(mask.s_addr);
- net1 = ntohl(ip1.s_addr);
- net2 = ntohl(ip2.s_addr);
+ nmask = ntohl(mask.s_addr);
+ net1 = ntohl(ip1.s_addr);
+ net2 = ntohl(ip2.s_addr);
- return((net1 & nmask) == (net2 & nmask));
+ return((net1 & nmask) == (net2 & nmask));
}
/****************************************************************************
- Check if a process exists. Does this work on all unixes?
+check if a process exists. Does this work on all unixes?
****************************************************************************/
BOOL process_exists(pid_t pid)
{
- /* Doing kill with a non-positive pid causes messages to be
- * sent to places we don't want. */
- SMB_ASSERT(pid > 0);
return(kill(pid,0) == 0 || errno != ESRCH);
}
+
/*******************************************************************
Convert a uid into a user name.
********************************************************************/
-const char *uidtoname(uid_t uid)
+char *uidtoname(uid_t uid)
{
static fstring name;
struct passwd *pass;
- pass = getpwuid_alloc(uid);
- if (pass) {
- fstrcpy(name, pass->pw_name);
- passwd_free(&pass);
- } else {
- slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
- }
- return name;
+ if (winbind_uidtoname(name, uid))
+ return name;
+
+ pass = sys_getpwuid(uid);
+ if (pass)
+ return(pass->pw_name);
+ slprintf(name, sizeof(name) - 1, "%d",(int)uid);
+ return(name);
}
@@ -1276,6 +1025,9 @@ char *gidtoname(gid_t gid)
static fstring name;
struct group *grp;
+ if (winbind_gidtoname(name, gid))
+ return name;
+
grp = getgrgid(gid);
if (grp)
return(grp->gr_name);
@@ -1284,34 +1036,34 @@ char *gidtoname(gid_t gid)
}
/*******************************************************************
- Convert a user name into a uid.
+ Convert a user name into a uid. If winbindd is present uses this.
********************************************************************/
-uid_t nametouid(const char *name)
+uid_t nametouid(char *name)
{
struct passwd *pass;
char *p;
uid_t u;
- pass = getpwnam_alloc(name);
- if (pass) {
- u = pass->pw_uid;
- passwd_free(&pass);
- return u;
- }
-
u = (uid_t)strtol(name, &p, 0);
if ((p != name) && (*p == '\0'))
return u;
+ if (winbind_nametouid(&u, name))
+ return u;
+
+ pass = sys_getpwnam(name);
+ if (pass)
+ return(pass->pw_uid);
return (uid_t)-1;
}
/*******************************************************************
- Convert a name to a gid_t if possible. Return -1 if not a group.
+ Convert a name to a gid_t if possible. Return -1 if not a group. If winbindd
+ is present does a shortcut lookup...
********************************************************************/
-gid_t nametogid(const char *name)
+gid_t nametogid(char *name)
{
struct group *grp;
char *p;
@@ -1321,149 +1073,47 @@ gid_t nametogid(const char *name)
if ((p != name) && (*p == '\0'))
return g;
- grp = sys_getgrnam(name);
+ if (winbind_nametogid(&g, name))
+ return g;
+
+ grp = getgrnam(name);
if (grp)
return(grp->gr_gid);
return (gid_t)-1;
}
/*******************************************************************
- legacy wrapper for smb_panic2()
+something really nasty happened - panic!
********************************************************************/
-void smb_panic( const char *why )
+void smb_panic(const char *why)
{
- smb_panic2( why, True );
-}
-
-/*******************************************************************
- Something really nasty happened - panic !
-********************************************************************/
-
-#ifdef HAVE_LIBEXC_H
-#include <libexc.h>
-#endif
-
-void smb_panic2(const char *why, BOOL decrement_pid_count )
-{
- char *cmd;
- int result;
-#ifdef HAVE_BACKTRACE_SYMBOLS
- void *backtrace_stack[BACKTRACE_STACK_SIZE];
- size_t backtrace_size;
- char **backtrace_strings;
-#endif
-
-#ifdef DEVELOPER
- {
- extern char *global_clobber_region_function;
- extern unsigned int global_clobber_region_line;
-
- if (global_clobber_region_function) {
- DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
- global_clobber_region_function,
- global_clobber_region_line));
- }
- }
-#endif
-
- /* only smbd needs to decrement the smbd counter in connections.tdb */
- if ( decrement_pid_count )
- decrement_smbd_process_count();
-
- cmd = lp_panic_action();
+ char *cmd = lp_panic_action();
if (cmd && *cmd) {
- DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
- result = system(cmd);
-
- if (result == -1)
- DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
- strerror(errno)));
- else
- DEBUG(0, ("smb_panic(): action returned status %d\n",
- WEXITSTATUS(result)));
+ system(cmd);
}
DEBUG(0,("PANIC: %s\n", why));
-
-#ifdef HAVE_BACKTRACE_SYMBOLS
- /* get the backtrace (stack frames) */
- backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
- backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
-
- DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
- (unsigned long)backtrace_size));
-
- if (backtrace_strings) {
- int i;
-
- for (i = 0; i < backtrace_size; i++)
- DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
-
- /* Leak the backtrace_strings, rather than risk what free() might do */
- }
-
-#elif HAVE_LIBEXC
-
-#define NAMESIZE 32 /* Arbitrary */
-
- /* The IRIX libexc library provides an API for unwinding the stack. See
- * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
- * since we are about to abort anyway, it hardly matters.
- *
- * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this
- * will fail with a nasty message upon failing to open the /proc entry.
- */
- {
- __uint64_t addrs[BACKTRACE_STACK_SIZE];
- char * names[BACKTRACE_STACK_SIZE];
- char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
-
- int i;
- int levels;
-
- ZERO_ARRAY(addrs);
- ZERO_ARRAY(names);
- ZERO_ARRAY(namebuf);
-
- for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
- names[i] = namebuf + (i * NAMESIZE);
- }
-
- levels = trace_back_stack(0, addrs, names,
- BACKTRACE_STACK_SIZE, NAMESIZE);
-
- DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
- for (i = 0; i < levels; i++) {
- DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
- }
- }
-#undef NAMESIZE
-#endif
-
dbgflush();
abort();
}
-/*******************************************************************
- A readdir wrapper which just returns the file name.
- ********************************************************************/
-const char *readdirname(DIR *p)
+/*******************************************************************
+a readdir wrapper which just returns the file name
+********************************************************************/
+char *readdirname(DIR *p)
{
SMB_STRUCT_DIRENT *ptr;
char *dname;
- if (!p)
- return(NULL);
+ if (!p) return(NULL);
ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
- if (!ptr)
- return(NULL);
+ if (!ptr) return(NULL);
dname = ptr->d_name;
#ifdef NEXT2
- if (telldir(p) < 0)
- return(NULL);
+ if (telldir(p) < 0) return(NULL);
#endif
#ifdef HAVE_BROKEN_READDIR
@@ -1487,41 +1137,48 @@ const char *readdirname(DIR *p)
of a path matches a (possibly wildcarded) entry in a namelist.
********************************************************************/
-BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
-{
- pstring last_component;
- char *p;
-
- DEBUG(8, ("is_in_path: %s\n", name));
-
- /* if we have no list it's obviously not in the path */
- if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
- DEBUG(8,("is_in_path: no name list.\n"));
- return False;
- }
-
- /* Get the last component of the unix name. */
- p = strrchr_m(name, '/');
- strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
- last_component[sizeof(last_component)-1] = '\0';
-
- for(; namelist->name != NULL; namelist++) {
- if(namelist->is_wild) {
- if (mask_match(last_component, namelist->name, case_sensitive)) {
- DEBUG(8,("is_in_path: mask match succeeded\n"));
- return True;
- }
- } else {
- if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
- (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
- DEBUG(8,("is_in_path: match succeeded\n"));
- return True;
- }
- }
- }
- DEBUG(8,("is_in_path: match not found\n"));
+BOOL is_in_path(const char *name, name_compare_entry *namelist)
+{
+ pstring last_component;
+ char *p;
+
+ DEBUG(8, ("is_in_path: %s\n", name));
+
+ /* if we have no list it's obviously not in the path */
+ if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
+ {
+ DEBUG(8,("is_in_path: no name list.\n"));
+ return False;
+ }
+
+ /* Get the last component of the unix name. */
+ p = strrchr(name, '/');
+ strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
+ last_component[sizeof(last_component)-1] = '\0';
+
+ for(; namelist->name != NULL; namelist++)
+ {
+ if(namelist->is_wild)
+ {
+ if (mask_match(last_component, namelist->name, case_sensitive))
+ {
+ DEBUG(8,("is_in_path: mask match succeeded\n"));
+ return True;
+ }
+ }
+ else
+ {
+ if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
+ (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
+ {
+ DEBUG(8,("is_in_path: match succeeded\n"));
+ return True;
+ }
+ }
+ }
+ DEBUG(8,("is_in_path: match not found\n"));
- return False;
+ return False;
}
/*******************************************************************
@@ -1539,83 +1196,90 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit
void set_namearray(name_compare_entry **ppname_array, char *namelist)
{
- char *name_end;
- char *nameptr = namelist;
- int num_entries = 0;
- int i;
-
- (*ppname_array) = NULL;
-
- if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
- return;
-
- /* We need to make two passes over the string. The
- first to count the number of elements, the second
- to split it.
- */
-
- while(*nameptr) {
- if ( *nameptr == '/' ) {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- name_end = strchr_m(nameptr, '/');
-
- /* oops - the last check for a / didn't find one. */
- if (name_end == NULL)
- break;
-
- /* next segment please */
- nameptr = name_end + 1;
- num_entries++;
- }
-
- if(num_entries == 0)
- return;
+ char *name_end;
+ char *nameptr = namelist;
+ int num_entries = 0;
+ int i;
+
+ (*ppname_array) = NULL;
+
+ if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
+ return;
+
+ /* We need to make two passes over the string. The
+ first to count the number of elements, the second
+ to split it.
+ */
+ while(*nameptr)
+ {
+ if ( *nameptr == '/' )
+ {
+ /* cope with multiple (useless) /s) */
+ nameptr++;
+ continue;
+ }
+ /* find the next / */
+ name_end = strchr(nameptr, '/');
- if(( (*ppname_array) = (name_compare_entry *)malloc(
- (num_entries + 1) * sizeof(name_compare_entry))) == NULL) {
- DEBUG(0,("set_namearray: malloc fail\n"));
- return;
- }
+ /* oops - the last check for a / didn't find one. */
+ if (name_end == NULL)
+ break;
- /* Now copy out the names */
- nameptr = namelist;
- i = 0;
- while(*nameptr) {
- if ( *nameptr == '/' ) {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- if ((name_end = strchr_m(nameptr, '/')) != NULL)
- *name_end = 0;
+ /* next segment please */
+ nameptr = name_end + 1;
+ num_entries++;
+ }
- /* oops - the last check for a / didn't find one. */
- if(name_end == NULL)
- break;
+ if(num_entries == 0)
+ return;
- (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
- if(((*ppname_array)[i].name = strdup(nameptr)) == NULL) {
- DEBUG(0,("set_namearray: malloc fail (1)\n"));
- return;
- }
+ if(( (*ppname_array) = (name_compare_entry *)malloc(
+ (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
+ {
+ DEBUG(0,("set_namearray: malloc fail\n"));
+ return;
+ }
- /* next segment please */
- nameptr = name_end + 1;
- i++;
- }
+ /* Now copy out the names */
+ nameptr = namelist;
+ i = 0;
+ while(*nameptr)
+ {
+ if ( *nameptr == '/' )
+ {
+ /* cope with multiple (useless) /s) */
+ nameptr++;
+ continue;
+ }
+ /* find the next / */
+ if ((name_end = strchr(nameptr, '/')) != NULL)
+ {
+ *name_end = 0;
+ }
+
+ /* oops - the last check for a / didn't find one. */
+ if(name_end == NULL)
+ break;
+
+ (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
+ if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
+ {
+ DEBUG(0,("set_namearray: malloc fail (1)\n"));
+ return;
+ }
+
+ /* next segment please */
+ nameptr = name_end + 1;
+ i++;
+ }
- (*ppname_array)[i].name = NULL;
+ (*ppname_array)[i].name = NULL;
- return;
+ return;
}
/****************************************************************************
- Routine to free a namearray.
+routine to free a namearray.
****************************************************************************/
void free_namearray(name_compare_entry *name_array)
@@ -1627,6 +1291,7 @@ void free_namearray(name_compare_entry *name_array)
for(i=0; name_array[i].name!=NULL; i++)
SAFE_FREE(name_array[i].name);
+
SAFE_FREE(name_array);
}
@@ -1637,67 +1302,67 @@ void free_namearray(name_compare_entry *name_array)
BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
- SMB_STRUCT_FLOCK lock;
- int ret;
+ SMB_STRUCT_FLOCK lock;
+ int ret;
- DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+ DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = offset;
- lock.l_len = count;
- lock.l_pid = 0;
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = offset;
+ lock.l_len = count;
+ lock.l_pid = 0;
- ret = sys_fcntl_ptr(fd,op,&lock);
+ ret = sys_fcntl_ptr(fd,op,&lock);
- if (ret == -1 && errno != 0)
- DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
+ if (ret == -1 && errno != 0)
+ DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
- /* a lock query */
- if (op == SMB_F_GETLK) {
- if ((ret != -1) &&
- (lock.l_type != F_UNLCK) &&
- (lock.l_pid != 0) &&
- (lock.l_pid != sys_getpid())) {
- DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
- return(True);
- }
+ /* a lock query */
+ if (op == SMB_F_GETLK)
+ {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) &&
+ (lock.l_pid != sys_getpid()))
+ {
+ DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
+ return(True);
+ }
- /* it must be not locked or locked by me */
- return(False);
- }
+ /* it must be not locked or locked by me */
+ return(False);
+ }
- /* a lock set or unset */
- if (ret == -1) {
- DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
- (double)offset,(double)count,op,type,strerror(errno)));
- return(False);
- }
+ /* a lock set or unset */
+ if (ret == -1)
+ {
+ DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset,(double)count,op,type,strerror(errno)));
+ return(False);
+ }
- /* everything went OK */
- DEBUG(8,("fcntl_lock: Lock call successful\n"));
+ /* everything went OK */
+ DEBUG(8,("fcntl_lock: Lock call successful\n"));
- return(True);
+ return(True);
}
/*******************************************************************
- Is the name specified one of my netbios names.
- Returns true if it is equal, false otherwise.
+is the name specified one of my netbios names
+returns true is it is equal, false otherwise
********************************************************************/
-
-BOOL is_myname(const char *s)
+BOOL is_myname(char *s)
{
- int n;
- BOOL ret = False;
+ int n;
+ BOOL ret = False;
- for (n=0; my_netbios_names(n); n++) {
- if (strequal(my_netbios_names(n), s)) {
- ret=True;
- break;
- }
- }
- DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
- return(ret);
+ for (n=0; my_netbios_names[n]; n++) {
+ if (strequal(my_netbios_names[n], s))
+ ret=True;
+ }
+ DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
+ return(ret);
}
/********************************************************************
@@ -1718,14 +1383,19 @@ const char* get_my_primary_ip (void)
return ip_string;
}
-BOOL is_myname_or_ipaddr(const char *s)
+
+BOOL is_myname_or_ipaddr(char *s)
{
+ const char *ptr;
+ pstring nbname;
+
/* optimize for the common case */
- if (strequal(s, global_myname()))
+ if (strequal(s, global_myname))
return True;
/* maybe its an IP address? */
- if (is_ipaddress(s)) {
+ if (is_ipaddress(s))
+ {
struct iface_struct nics[MAX_INTERFACES];
int i, n;
uint32 ip;
@@ -1740,150 +1410,159 @@ BOOL is_myname_or_ipaddr(const char *s)
return True;
}
}
-
+
/* check for an alias */
- if (is_myname(s))
- return True;
+ ptr = lp_netbios_aliases();
+ while ( next_token(&ptr, nbname, NULL, sizeof(nbname)) )
+ {
+ if (StrCaseCmp(s, nbname) == 0)
+ return True;
+ }
+
/* no match */
return False;
-}
-/*******************************************************************
- Is the name specified our workgroup/domain.
- Returns true if it is equal, false otherwise.
-********************************************************************/
-
-BOOL is_myworkgroup(const char *s)
-{
- BOOL ret = False;
-
- if (strequal(s, lp_workgroup())) {
- ret=True;
- }
-
- DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
- return(ret);
}
-/*******************************************************************
- we distinguish between 2K and XP by the "Native Lan Manager" string
- WinXP => "Windows 2002 5.1"
- Win2k => "Windows 2000 5.0"
- NT4 => "Windows NT 4.0"
- Win9x => "Windows 4.0"
- Windows 2003 doesn't set the native lan manager string but
- they do set the domain to "Windows 2003 5.2" (probably a bug).
-********************************************************************/
-
-void ra_lanman_string( const char *native_lanman )
-{
- if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
- set_remote_arch( RA_WINXP );
- else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
- set_remote_arch( RA_WIN2K3 );
-}
/*******************************************************************
- Set the horrid remote_arch string based on an enum.
+set the horrid remote_arch string based on an enum.
********************************************************************/
-
void set_remote_arch(enum remote_arch_types type)
{
- extern fstring remote_arch;
- ra_type = type;
- switch( type ) {
- case RA_WFWG:
- fstrcpy(remote_arch, "WfWg");
- break;
- case RA_OS2:
- fstrcpy(remote_arch, "OS2");
- break;
- case RA_WIN95:
- fstrcpy(remote_arch, "Win95");
- break;
- case RA_WINNT:
- fstrcpy(remote_arch, "WinNT");
- break;
- case RA_WIN2K:
- fstrcpy(remote_arch, "Win2K");
- break;
- case RA_WINXP:
- fstrcpy(remote_arch, "WinXP");
- break;
- case RA_WIN2K3:
- fstrcpy(remote_arch, "Win2K3");
- break;
- case RA_SAMBA:
- fstrcpy(remote_arch,"Samba");
- break;
- default:
- ra_type = RA_UNKNOWN;
- fstrcpy(remote_arch, "UNKNOWN");
- break;
- }
-
- DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
+ extern fstring remote_arch;
+ ra_type = type;
+ switch( type )
+ {
+ case RA_WFWG:
+ fstrcpy(remote_arch, "WfWg");
+ return;
+ case RA_OS2:
+ fstrcpy(remote_arch, "OS2");
+ return;
+ case RA_WIN95:
+ fstrcpy(remote_arch, "Win95");
+ return;
+ case RA_WINNT:
+ fstrcpy(remote_arch, "WinNT");
+ return;
+ case RA_WIN2K:
+ fstrcpy(remote_arch, "Win2K");
+ return;
+ case RA_WINXP:
+ fstrcpy(remote_arch, "WinXP");
+ return;
+ case RA_WIN2K3:
+ fstrcpy(remote_arch, "Win2K3");
+ return;
+ case RA_SAMBA:
+ fstrcpy(remote_arch,"Samba");
+ return;
+ default:
+ ra_type = RA_UNKNOWN;
+ fstrcpy(remote_arch, "UNKNOWN");
+ break;
+ }
}
/*******************************************************************
Get the remote_arch type.
********************************************************************/
-
enum remote_arch_types get_remote_arch(void)
{
- return ra_type;
+ return ra_type;
}
-void print_asc(int level, const unsigned char *buf,int len)
+
+void out_ascii(FILE *f, unsigned char *buf,int len)
{
int i;
for (i=0;i<len;i++)
- DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
+ {
+ fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
+ }
}
-void dump_data(int level, const char *buf1,int len)
+void out_data(FILE *f,char *buf1,int len, int per_line)
{
- const unsigned char *buf = (const unsigned char *)buf1;
+ unsigned char *buf = (unsigned char *)buf1;
int i=0;
- if (len<=0) return;
+ if (len<=0)
+ {
+ return;
+ }
- if (!DEBUGLVL(level)) return;
-
- DEBUGADD(level,("[%03X] ",i));
- for (i=0;i<len;) {
- DEBUGADD(level,("%02X ",(int)buf[i]));
+ fprintf(f, "[%03X] ",i);
+ for (i=0;i<len;)
+ {
+ fprintf(f, "%02X ",(int)buf[i]);
i++;
- if (i%8 == 0) DEBUGADD(level,(" "));
- if (i%16 == 0) {
- print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
- print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
- if (i<len) DEBUGADD(level,("[%03X] ",i));
+ if (i%(per_line/2) == 0) fprintf(f, " ");
+ if (i%per_line == 0)
+ {
+ out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
+ out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
+ if (i<len) fprintf(f, "[%03X] ",i);
}
}
- if (i%16) {
+ if ((i%per_line) != 0)
+ {
int n;
- n = 16 - (i%16);
- DEBUGADD(level,(" "));
- if (n>8) DEBUGADD(level,(" "));
- while (n--) DEBUGADD(level,(" "));
- n = MIN(8,i%16);
- print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
- n = (i%16) - n;
- if (n>0) print_asc(level,&buf[i-n],n);
- DEBUGADD(level,("\n"));
- }
+
+ n = per_line - (i%per_line);
+ fprintf(f, " ");
+ if (n>(per_line/2)) fprintf(f, " ");
+ while (n--)
+ {
+ fprintf(f, " ");
+ }
+ n = MIN(per_line/2,i%per_line);
+ out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
+ n = (i%per_line) - n;
+ if (n>0) out_ascii(f,&buf[i-n],n);
+ fprintf(f, "\n");
+ }
}
-void dump_data_pw(const char *msg, const uchar * data, size_t len)
+void print_asc(int level, unsigned char *buf,int len)
{
-#ifdef DEBUG_PASSWORD
- DEBUG(11, ("%s", msg));
- if (data != NULL && len > 0)
- {
- dump_data(11, data, len);
- }
-#endif
+ int i;
+ for (i=0;i<len;i++)
+ DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
+}
+
+void dump_data(int level,char *buf1,int len)
+{
+ unsigned char *buf = (unsigned char *)buf1;
+ int i=0;
+ if (len<=0) return;
+
+ DEBUG(level,("[%03X] ",i));
+ for (i=0;i<len;) {
+ DEBUG(level,("%02X ",(int)buf[i]));
+ i++;
+ if (i%8 == 0) DEBUG(level,(" "));
+ if (i%16 == 0) {
+ print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
+ print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
+ if (i<len) DEBUG(level,("[%03X] ",i));
+ }
+ }
+ if (i%16) {
+ int n;
+
+ n = 16 - (i%16);
+ DEBUG(level,(" "));
+ if (n>8) DEBUG(level,(" "));
+ while (n--) DEBUG(level,(" "));
+
+ n = MIN(8,i%16);
+ print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
+ n = (i%16) - n;
+ if (n>0) print_asc(level,&buf[i-n],n);
+ DEBUG(level,("\n"));
+ }
}
char *tab_depth(int depth)
@@ -1895,14 +1574,15 @@ char *tab_depth(int depth)
}
/*****************************************************************************
- Provide a checksum on a string
-
- Input: s - the null-terminated character string for which the checksum
- will be calculated.
-
- Output: The checksum value calculated for s.
-*****************************************************************************/
-
+ * Provide a checksum on a string
+ *
+ * Input: s - the null-terminated character string for which the checksum
+ * will be calculated.
+ *
+ * Output: The checksum value calculated for s.
+ *
+ * ****************************************************************************
+ */
int str_checksum(const char *s)
{
int res = 0;
@@ -1916,22 +1596,23 @@ int str_checksum(const char *s)
i++;
}
return(res);
-}
+} /* str_checksum */
+
+
/*****************************************************************
- Zero a memory area then free it. Used to catch bugs faster.
+zero a memory area then free it. Used to catch bugs faster
*****************************************************************/
-
void zero_free(void *p, size_t size)
{
memset(p, 0, size);
SAFE_FREE(p);
}
+
/*****************************************************************
- Set our open file limit to a requested max and return the limit.
+set our open file limit to a requested max and return the limit
*****************************************************************/
-
int set_maxfiles(int requested_max)
{
#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
@@ -1946,7 +1627,7 @@ int set_maxfiles(int requested_max)
}
/*
- * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
+ * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
* account for the extra fd we need
* as well as the log files and standard
* handles etc. Save the limit we want to set in case
@@ -1999,7 +1680,7 @@ int set_maxfiles(int requested_max)
return saved_current_limit;
#endif
- if((int)rlp.rlim_cur > saved_current_limit)
+ if((int)rlp.rlim_cur > saved_current_limit)
return saved_current_limit;
return rlp.rlim_cur;
@@ -2012,43 +1693,53 @@ int set_maxfiles(int requested_max)
}
/*****************************************************************
- Splits out the start of the key (HKLM or HKU) and the rest of the key.
-*****************************************************************/
-
+ splits out the start of the key (HKLM or HKU) and the rest of the key
+ *****************************************************************/
BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
{
pstring tmp;
if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
+ {
return False;
+ }
(*reg_type) = 0;
DEBUG(10, ("reg_split_key: hive %s\n", tmp));
if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
+ {
(*reg_type) = HKEY_LOCAL_MACHINE;
+ }
else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
+ {
(*reg_type) = HKEY_USERS;
- else {
+ }
+ else
+ {
DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
return False;
}
- if (next_token(&full_keyname, tmp, "\n\r", sizeof(tmp)))
+ if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
+ {
fstrcpy(key_name, tmp);
+ }
else
+ {
key_name[0] = 0;
+ }
DEBUG(10, ("reg_split_key: name %s\n", key_name));
return True;
}
+
/*****************************************************************
- Possibly replace mkstemp if it is broken.
+possibly replace mkstemp if it is broken
*****************************************************************/
-
int smb_mkstemp(char *template)
{
#if HAVE_SECURE_MKSTEMP
@@ -2057,8 +1748,7 @@ int smb_mkstemp(char *template)
/* have a reasonable go at emulating it. Hope that
the system mktemp() isn't completly hopeless */
char *p = mktemp(template);
- if (!p)
- return -1;
+ if (!p) return -1;
return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
#endif
}
@@ -2072,17 +1762,14 @@ void *smb_xmalloc(size_t size)
void *p;
if (size == 0)
smb_panic("smb_xmalloc: called with zero size.\n");
- if ((p = malloc(size)) == NULL) {
- DEBUG(0, ("smb_xmalloc() failed to allocate %lu bytes\n", (unsigned long)size));
+ if ((p = malloc(size)) == NULL)
smb_panic("smb_xmalloc: malloc fail.\n");
- }
return p;
}
/**
Memdup with smb_panic on fail.
**/
-
void *smb_xmemdup(const void *p, size_t size)
{
void *p2;
@@ -2094,7 +1781,6 @@ void *smb_xmemdup(const void *p, size_t size)
/**
strdup that aborts on malloc fail.
**/
-
char *smb_xstrdup(const char *s)
{
char *s1 = strdup(s);
@@ -2103,23 +1789,10 @@ char *smb_xstrdup(const char *s)
return s1;
}
-/**
- strndup that aborts on malloc fail.
-**/
-
-char *smb_xstrndup(const char *s, size_t n)
-{
- char *s1 = strndup(s, n);
- if (!s1)
- smb_panic("smb_xstrndup: malloc fail\n");
- return s1;
-}
-
/*
vasprintf that aborts on malloc fail
*/
-
- int smb_xvasprintf(char **ptr, const char *format, va_list ap)
+int smb_xvasprintf(char **ptr, const char *format, va_list ap)
{
int n;
va_list ap2;
@@ -2127,52 +1800,51 @@ char *smb_xstrndup(const char *s, size_t n)
VA_COPY(ap2, ap);
n = vasprintf(ptr, format, ap2);
- if (n == -1 || ! *ptr)
+ if (n == -1 || ! *ptr) {
smb_panic("smb_xvasprintf: out of memory");
+ }
return n;
}
/*****************************************************************
- Like strdup but for memory.
-*****************************************************************/
-
-void *memdup(const void *p, size_t size)
+like strdup but for memory
+ *****************************************************************/
+void *memdup(void *p, size_t size)
{
void *p2;
- if (size == 0)
- return NULL;
+ if (size == 0) return NULL;
p2 = malloc(size);
- if (!p2)
- return NULL;
+ if (!p2) return NULL;
memcpy(p2, p, size);
return p2;
}
/*****************************************************************
- Get local hostname and cache result.
-*****************************************************************/
-
+get local hostname and cache result
+ *****************************************************************/
char *myhostname(void)
{
static pstring ret;
- if (ret[0] == 0)
+ if (ret[0] == 0) {
get_myname(ret);
+ }
return ret;
}
-/*****************************************************************
- A useful function for returning a path in the Samba lock directory.
-*****************************************************************/
+/*****************************************************************
+a useful function for returning a path in the Samba lock directory
+ *****************************************************************/
char *lock_path(const char *name)
{
static pstring fname;
pstrcpy(fname,lp_lockdir());
- trim_char(fname,'\0','/');
+ trim_string(fname,"","/");
- if (!directory_exist(fname,NULL))
+ if (!directory_exist(fname,NULL)) {
mkdir(fname,0755);
+ }
pstrcat(fname,"/");
pstrcat(fname,name);
@@ -2181,51 +1853,25 @@ char *lock_path(const char *name)
}
/*****************************************************************
- A useful function for returning a path in the Samba pid directory.
-*****************************************************************/
-
-char *pid_path(const char *name)
+a useful function for returning a path in the Samba pid directory
+ *****************************************************************/
+char *pid_path(char *name)
{
static pstring fname;
pstrcpy(fname,lp_piddir());
- trim_char(fname,'\0','/');
-
- if (!directory_exist(fname,NULL))
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
mkdir(fname,0755);
-
+ }
+
pstrcat(fname,"/");
pstrcat(fname,name);
return fname;
}
-/**
- * @brief Returns an absolute path to a file in the Samba lib directory.
- *
- * @param name File to find, relative to LIBDIR.
- *
- * @retval Pointer to a static #pstring containing the full path.
- **/
-
-char *lib_path(const char *name)
-{
- static pstring fname;
- fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
- return fname;
-}
-
-/**
- * @brief Returns the platform specific shared library extension.
- *
- * @retval Pointer to a static #fstring containing the extension.
- **/
-
-const char *shlib_ext(void)
-{
- return dyn_SHLIBEXT;
-}
-
/*******************************************************************
Given a filename - get its directory name
NB: Returned in static storage. Caveats:
@@ -2243,7 +1889,7 @@ char *parent_dirname(const char *path)
return(NULL);
pstrcpy(dirpath, path);
- p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
+ p = strrchr(dirpath, '/'); /* Find final '/', if any */
if (!p) {
pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
} else {
@@ -2256,10 +1902,9 @@ char *parent_dirname(const char *path)
/*******************************************************************
- Determine if a pattern contains any Microsoft wildcard characters.
-*******************************************************************/
-
-BOOL ms_has_wild(const char *s)
+determine if a pattern contains any Microsoft wildcard characters
+ *******************************************************************/
+BOOL ms_has_wild(char *s)
{
char c;
while ((c = *s++)) {
@@ -2275,59 +1920,34 @@ BOOL ms_has_wild(const char *s)
return False;
}
-BOOL ms_has_wild_w(const smb_ucs2_t *s)
-{
- smb_ucs2_t c;
- if (!s) return False;
- while ((c = *s++)) {
- switch (c) {
- case UCS2_CHAR('*'):
- case UCS2_CHAR('?'):
- case UCS2_CHAR('<'):
- case UCS2_CHAR('>'):
- case UCS2_CHAR('"'):
- return True;
- }
- }
- return False;
-}
-
/*******************************************************************
- A wrapper that handles case sensitivity and the special handling
- of the ".." name.
-*******************************************************************/
-
+ a wrapper that handles case sensitivity and the special handling
+ of the ".." name
+ *******************************************************************/
BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
{
- if (strcmp(string,"..") == 0)
- string = ".";
- if (strcmp(pattern,".") == 0)
- return False;
+ fstring p2, s2;
+ if (strcmp(string,"..") == 0) string = ".";
+ if (strcmp(pattern,".") == 0) return False;
- return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0;
-}
-
-/*******************************************************************
- A wrapper that handles a list of patters and calls mask_match()
- on each. Returns True if any of the patterns match.
-*******************************************************************/
+ if (is_case_sensitive) {
+ return ms_fnmatch(pattern, string) == 0;
+ }
-BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
-{
- while (listLen-- > 0) {
- if (mask_match(string, *list++, is_case_sensitive))
- return True;
- }
- return False;
+ fstrcpy(p2, pattern);
+ fstrcpy(s2, string);
+ strlower(p2);
+ strlower(s2);
+ return ms_fnmatch(p2, s2) == 0;
}
/*********************************************************
Recursive routine that is called by unix_wild_match.
*********************************************************/
-static BOOL unix_do_match(const char *regexp, const char *str)
+static BOOL unix_do_match(char *regexp, char *str)
{
- const char *p;
+ char *p;
for( p = regexp; *p && *str; ) {
@@ -2426,15 +2046,15 @@ static BOOL unix_do_match(const char *regexp, const char *str)
Simple case insensitive interface to a UNIX wildcard matcher.
*******************************************************************/
-BOOL unix_wild_match(const char *pattern, const char *string)
+BOOL unix_wild_match(char *pattern, char *string)
{
pstring p2, s2;
char *p;
pstrcpy(p2, pattern);
pstrcpy(s2, string);
- strlower_m(p2);
- strlower_m(s2);
+ strlower(p2);
+ strlower(s2);
/* Remove any *? and ** from the pattern as they are meaningless */
for(p = p2; *p; p++)
@@ -2447,6 +2067,84 @@ BOOL unix_wild_match(const char *pattern, const char *string)
return unix_do_match(p2, s2) == 0;
}
+/*******************************************************************
+ free() a data blob
+*******************************************************************/
+
+static void free_data_blob(DATA_BLOB *d)
+{
+ if ((d) && (d->free)) {
+ SAFE_FREE(d->data);
+ }
+}
+
+/*******************************************************************
+ construct a data blob, must be freed with data_blob_free()
+ you can pass NULL for p and get a blank data blob
+*******************************************************************/
+
+DATA_BLOB data_blob(const void *p, size_t length)
+{
+ DATA_BLOB ret;
+
+ if (!length) {
+ ZERO_STRUCT(ret);
+ return ret;
+ }
+
+ if (p) {
+ ret.data = smb_xmemdup(p, length);
+ } else {
+ ret.data = smb_xmalloc(length);
+ }
+ ret.length = length;
+ ret.free = free_data_blob;
+ return ret;
+}
+
+/*******************************************************************
+ construct a data blob, using supplied TALLOC_CTX
+*******************************************************************/
+
+DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
+{
+ DATA_BLOB ret;
+
+ if (!p || !length) {
+ ZERO_STRUCT(ret);
+ return ret;
+ }
+
+ ret.data = talloc_memdup(mem_ctx, p, length);
+ if (ret.data == NULL)
+ smb_panic("data_blob_talloc: talloc_memdup failed.\n");
+
+ ret.length = length;
+ ret.free = NULL;
+ return ret;
+}
+
+/*******************************************************************
+free a data blob
+*******************************************************************/
+void data_blob_free(DATA_BLOB *d)
+{
+ if (d) {
+ if (d->free) {
+ (d->free)(d);
+ }
+ }
+}
+
+/*******************************************************************
+clear a DATA_BLOB's contents
+*******************************************************************/
+void data_blob_clear(DATA_BLOB *d)
+{
+ if (d->data) {
+ memset(d->data, 0, d->length);
+ }
+}
#ifdef __INSURE__
@@ -2455,15 +2153,12 @@ This routine is a trick to immediately catch errors when debugging
with insure. A xterm with a gdb is popped up when insure catches
a error. It is Linux specific.
********************************************************************/
-
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
{
static int (*fn)();
int ret;
char pidstr[10];
- /* you can get /usr/bin/backtrace from
- http://samba.org/ftp/unpacked/junkcode/backtrace */
- pstring cmd = "/usr/bin/backtrace %d";
+ pstring cmd = "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'";
slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
pstring_sub(cmd, "%d", pidstr);
@@ -2472,11 +2167,6 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
static void *h;
h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
fn = dlsym(h, "_Insure_trap_error");
-
- if (!h || h == _Insure_trap_error) {
- h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
- fn = dlsym(h, "_Insure_trap_error");
- }
}
ret = fn(a1, a2, a3, a4, a5, a6);
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index bd505ac921c..45f4f0a0b76 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -1,6 +1,5 @@
/*
- * Unix SMB/CIFS implementation.
- * SMB parameters and setup
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
* Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
*
* This program is free software; you can redistribute it and/or modify it under
@@ -20,11 +19,6 @@
#include "includes.h"
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
-
static int gotalarm;
/***************************************************************
@@ -45,10 +39,9 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
{
SMB_STRUCT_FLOCK lock;
int ret;
- void (*oldsig_handler)(int);
gotalarm = 0;
- oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
lock.l_type = type;
lock.l_whence = SEEK_SET;
@@ -60,7 +53,7 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
/* Note we must *NOT* use sys_fcntl here ! JRA */
ret = fcntl(fd, SMB_F_SETLKW, &lock);
alarm(0);
- CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
if (gotalarm) {
DEBUG(0, ("do_file_lock: failed to %s file.\n",
@@ -261,7 +254,7 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
continue;
}
- p = (unsigned char *) strchr_m(linebuf, ':');
+ p = (unsigned char *) strchr(linebuf, ':');
if (p == NULL)
{
DEBUG(0, ("getfileline: malformed line entry (no :)\n"));
@@ -278,31 +271,40 @@ read a line from a file with possible \ continuation chars.
Blanks at the start or end of a line are stripped.
The string will be allocated if s2 is NULL
****************************************************************************/
-char *fgets_slash(char *s2,int maxlen,XFILE *f)
+char *fgets_slash(char *s2,int maxlen,FILE *f)
{
char *s=s2;
int len = 0;
int c;
BOOL start_of_line = True;
- if (x_feof(f))
+ if (feof(f))
return(NULL);
if (maxlen <2) return(NULL);
if (!s2)
{
+ char *t;
+
maxlen = MIN(maxlen,8);
- s = (char *)malloc(maxlen);
+ t = (char *)Realloc(s,maxlen);
+ if (!t) {
+ DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
+ SAFE_FREE(s);
+ return(NULL);
+ } else
+ s = t;
}
- if (!s) return(NULL);
+ if (!s)
+ return(NULL);
*s = 0;
while (len < maxlen-1)
{
- c = x_getc(f);
+ c = getc(f);
switch (c)
{
case '\r':
@@ -331,18 +333,18 @@ char *fgets_slash(char *s2,int maxlen,XFILE *f)
s[len++] = c;
s[len] = 0;
}
- if (!s2 && len > maxlen-3)
- {
- char *t;
-
- maxlen *= 2;
- t = (char *)Realloc(s,maxlen);
- if (!t) {
- DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
- SAFE_FREE(s);
- return(NULL);
- } else s = t;
- }
+ if (!s2 && len > maxlen-3) {
+ char *t;
+
+ maxlen *= 2;
+ t = (char *)Realloc(s,maxlen);
+ if (!t) {
+ DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
+ SAFE_FREE(s);
+ return(NULL);
+ } else
+ s = t;
+ }
}
return(s);
}
@@ -351,7 +353,7 @@ char *fgets_slash(char *s2,int maxlen,XFILE *f)
/****************************************************************************
load from a pipe into memory
****************************************************************************/
-char *file_pload(char *syscmd, size_t *size)
+char *file_pload(const char *syscmd, size_t *size)
{
int fd, n;
char *p, *tp;
@@ -367,19 +369,17 @@ char *file_pload(char *syscmd, size_t *size)
while ((n = read(fd, buf, sizeof(buf))) > 0) {
tp = Realloc(p, total + n + 1);
if (!tp) {
- DEBUG(0,("file_pload: failed to expand buffer!\n"));
+ DEBUG(0,("file_pload: failed to exand buffer!\n"));
close(fd);
SAFE_FREE(p);
return NULL;
- } else p = tp;
+ } else
+ p = tp;
memcpy(p+total, buf, n);
total += n;
}
if (p) p[total] = 0;
- /* FIXME: Perhaps ought to check that the command completed
- * successfully (returned 0); if not the data may be
- * truncated. */
sys_pclose(fd);
if (size) *size = total;
@@ -433,48 +433,10 @@ char *file_load(const char *fname, size_t *size)
}
-/*******************************************************************
-mmap (if possible) or read a file
-********************************************************************/
-void *map_file(char *fname, size_t size)
-{
- size_t s2 = 0;
- void *p = NULL;
-#ifdef HAVE_MMAP
- if (lp_use_mmap()) {
- int fd;
- fd = open(fname, O_RDONLY, 0);
- if (fd == -1) {
- DEBUG(2,("Failed to load %s - %s\n", fname, strerror(errno)));
- return NULL;
- }
- p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
- close(fd);
- if (p == MAP_FAILED) {
- DEBUG(1,("Failed to mmap %s - %s\n", fname, strerror(errno)));
- return NULL;
- }
- }
-#endif
- if (!p) {
- p = file_load(fname, &s2);
- if (!p) return NULL;
- if (s2 != size) {
- DEBUG(1,("incorrect size for %s - got %lu expected %lu\n",
- fname, (unsigned long)s2, (unsigned long)size));
- if (p) free(p);
- return NULL;
- }
- }
-
- return p;
-}
-
-
/****************************************************************************
parse a buffer into lines
****************************************************************************/
-static char **file_lines_parse(char *p, size_t size, int *numlines)
+static char **file_lines_parse(char *p, size_t size, int *numlines, BOOL convert)
{
int i;
char *s, **ret;
@@ -503,15 +465,21 @@ static char **file_lines_parse(char *p, size_t size, int *numlines)
if (s[0] == '\r') s[0] = 0;
}
+ if (convert) {
+ for (i = 0; ret[i]; i++)
+ unix_to_dos(ret[i]);
+ }
+
return ret;
}
/****************************************************************************
load a file into memory and return an array of pointers to lines in the file
-must be freed with file_lines_free().
+must be freed with file_lines_free(). If convert is true calls unix_to_dos on
+the list.
****************************************************************************/
-char **file_lines_load(const char *fname, int *numlines)
+char **file_lines_load(const char *fname, int *numlines, BOOL convert)
{
char *p;
size_t size;
@@ -519,7 +487,7 @@ char **file_lines_load(const char *fname, int *numlines)
p = file_load(fname, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines);
+ return file_lines_parse(p, size, numlines, convert);
}
/****************************************************************************
@@ -527,7 +495,7 @@ load a fd into memory and return an array of pointers to lines in the file
must be freed with file_lines_free(). If convert is true calls unix_to_dos on
the list.
****************************************************************************/
-char **fd_lines_load(int fd, int *numlines)
+char **fd_lines_load(int fd, int *numlines, BOOL convert)
{
char *p;
size_t size;
@@ -535,15 +503,16 @@ char **fd_lines_load(int fd, int *numlines)
p = fd_load(fd, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines);
+ return file_lines_parse(p, size, numlines, convert);
}
/****************************************************************************
load a pipe into memory and return an array of pointers to lines in the data
-must be freed with file_lines_free().
+must be freed with file_lines_free(). If convert is true calls unix_to_dos on
+the list.
****************************************************************************/
-char **file_lines_pload(char *syscmd, int *numlines)
+char **file_lines_pload(const char *syscmd, int *numlines, BOOL convert)
{
char *p;
size_t size;
@@ -551,7 +520,7 @@ char **file_lines_pload(char *syscmd, int *numlines)
p = file_pload(syscmd, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines);
+ return file_lines_parse(p, size, numlines, convert);
}
/****************************************************************************
@@ -587,20 +556,3 @@ void file_lines_slashcont(char **lines)
}
}
}
-
-/*
- save a lump of data into a file. Mostly used for debugging
-*/
-BOOL file_save(const char *fname, void *packet, size_t length)
-{
- int fd;
- fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (fd == -1) {
- return False;
- }
- if (write(fd, packet, length) != (size_t)length) {
- return False;
- }
- close(fd);
- return True;
-}
diff --git a/source/lib/util_getent.c b/source/lib/util_getent.c
index 4431d6a2a47..05b6f0c2358 100644
--- a/source/lib/util_getent.c
+++ b/source/lib/util_getent.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Samba utility functions
Copyright (C) Simo Sorce 2001
Copyright (C) Jeremy Allison 2001
@@ -21,6 +22,27 @@
#include "includes.h"
+#if 0
+static void print_grent_list(struct sys_grent *glist)
+{
+ DEBUG(100, ("print_grent_list: %x\n", glist ));
+ while (glist) {
+ DEBUG(100,("glist: %x ", glist));
+ if (glist->gr_name)
+ DEBUG(100,(": gr_name = (%x) %s ", glist->gr_name, glist->gr_name));
+ if (glist->gr_passwd)
+ DEBUG(100,(": gr_passwd = (%x) %s ", glist->gr_passwd, glist->gr_passwd));
+ if (glist->gr_mem) {
+ int i;
+ for (i = 0; glist->gr_mem[i]; i++)
+ DEBUG(100,(" : gr_mem[%d] = (%x) %s ", i, glist->gr_mem[i], glist->gr_mem[i]));
+ }
+ DEBUG(100,(": gr_next = %x\n", glist->next ));
+ glist = glist->next;
+ }
+ DEBUG(100,("FINISHED !\n\n"));
+}
+#endif
/****************************************************************
Returns a single linked list of group entries.
@@ -156,15 +178,15 @@ struct sys_pwent * getpwent_list(void)
pent->pw_uid = pwd->pw_uid;
pent->pw_gid = pwd->pw_gid;
if (pwd->pw_gecos) {
- if ((pent->pw_gecos = strdup(pwd->pw_gecos)) == NULL)
+ if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL)
goto err;
}
if (pwd->pw_dir) {
- if ((pent->pw_dir = strdup(pwd->pw_dir)) == NULL)
+ if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL)
goto err;
}
if (pwd->pw_shell) {
- if ((pent->pw_shell = strdup(pwd->pw_shell)) == NULL)
+ if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL)
goto err;
}
@@ -228,7 +250,7 @@ static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_he
free_userlist(list_head);
return NULL;
}
- entry->unix_name = (char *)strdup(grp->gr_mem[i]);
+ entry->unix_name = strdup(grp->gr_mem[i]);
if (entry->unix_name == NULL) {
SAFE_FREE(entry);
free_userlist(list_head);
@@ -249,35 +271,24 @@ struct sys_userlist *get_users_in_group(const char *gname)
{
struct sys_userlist *list_head = NULL;
struct group *gptr;
- fstring domain;
- fstring groupname;
- DOM_SID sid;
- enum SID_NAME_USE name_type;
- /* No point using winbind if we can't split it in the
- first place */
- if (split_domain_and_name(gname, domain, groupname)) {
+ /*
+ * If we're doing this via winbindd, don't do the
+ * entire group list enumeration as we know this is
+ * pointless (and slow).
+ */
- /*
- * If we're doing this via winbindd, don't do the
- * entire group list enumeration as we know this is
- * pointless (and slow).
- */
-
- if (winbind_lookup_name(domain, groupname, &sid, &name_type)
- && name_type == SID_NAME_DOM_GRP) {
- if ((gptr = (struct group *)getgrnam(gname)) == NULL)
- return NULL;
- return add_members_to_userlist(list_head, gptr);
- }
+ if (strchr(gname,*lp_winbind_separator())) {
+ if ((gptr = (struct group *)getgrnam(gname)) == NULL)
+ return NULL;
+ return add_members_to_userlist(list_head, gptr);
}
-
+
#if !defined(BROKEN_GETGRNAM)
if ((gptr = (struct group *)getgrnam(gname)) == NULL)
return NULL;
return add_members_to_userlist(list_head, gptr);
#else
- /* BROKEN_GETGRNAM - True64 */
setgrent();
while((gptr = getgrent()) != NULL) {
if (strequal(gname, gptr->gr_name)) {
@@ -304,48 +315,3 @@ void free_userlist(struct sys_userlist *list_head)
SAFE_FREE(old_head);
}
}
-
-/****************************************************************
-****************************************************************/
-
-static int int_compare( int *a, int *b )
-{
- if ( *a == *b )
- return 0;
- else if ( *a < *b )
- return -1;
- else
- return 1;
-}
-
-void remove_duplicate_gids( int *num_groups, gid_t *groups )
-{
- int i;
- int count = *num_groups;
-
- if ( *num_groups <= 0 || !groups )
- return;
-
-
- DEBUG(8,("remove_duplicate_gids: Enter %d gids\n", *num_groups));
-
- qsort( groups, *num_groups, sizeof(gid_t), QSORT_CAST int_compare );
-
- for ( i=1; i<count; ) {
- if ( groups[i-1] == groups[i] ) {
- memmove( &groups[i-1], &groups[i], (count - i + 1)*sizeof(gid_t) );
-
- /* decrement the total number of groups and do not increment
- the loop counter */
- count--;
- continue;
- }
- i++;
- }
-
- *num_groups = count;
-
- DEBUG(8,("remove_duplicate_gids: Exit %d gids\n", *num_groups));
-
- return;
-}
diff --git a/source/lib/util_pw.c b/source/lib/util_pw.c
deleted file mode 100644
index 9d075a05e88..00000000000
--- a/source/lib/util_pw.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Safe versions of getpw* calls
-
- Copyright (C) Andrew Bartlett 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static struct passwd *alloc_copy_passwd(const struct passwd *from)
-{
- struct passwd *ret = smb_xmalloc(sizeof(struct passwd));
- ZERO_STRUCTP(ret);
- ret->pw_name = smb_xstrdup(from->pw_name);
- ret->pw_passwd = smb_xstrdup(from->pw_passwd);
- ret->pw_uid = from->pw_uid;
- ret->pw_gid = from->pw_gid;
- ret->pw_gecos = smb_xstrdup(from->pw_gecos);
- ret->pw_dir = smb_xstrdup(from->pw_dir);
- ret->pw_shell = smb_xstrdup(from->pw_shell);
- return ret;
-}
-
-void passwd_free (struct passwd **buf)
-{
- if (!*buf) {
- DEBUG(0, ("attempted double-free of allocated passwd\n"));
- return;
- }
-
- SAFE_FREE((*buf)->pw_name);
- SAFE_FREE((*buf)->pw_passwd);
- SAFE_FREE((*buf)->pw_gecos);
- SAFE_FREE((*buf)->pw_dir);
- SAFE_FREE((*buf)->pw_shell);
-
- SAFE_FREE(*buf);
-}
-
-struct passwd *getpwnam_alloc(const char *name)
-{
- struct passwd *temp;
-
- temp = sys_getpwnam(name);
-
- if (!temp) {
-#if 0
- if (errno == ENOMEM) {
- /* what now? */
- }
-#endif
- return NULL;
- }
-
- return alloc_copy_passwd(temp);
-}
-
-struct passwd *getpwuid_alloc(uid_t uid)
-{
- struct passwd *temp;
-
- temp = sys_getpwuid(uid);
-
- if (!temp) {
-#if 0
- if (errno == ENOMEM) {
- /* what now? */
- }
-#endif
- return NULL;
- }
-
- return alloc_copy_passwd(temp);
-}
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
index cb0f46e2f9d..b80ba6e8046 100644
--- a/source/lib/util_seaccess.c
+++ b/source/lib/util_seaccess.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
Copyright (C) Tim Potter 2000.
Copyright (C) Re-written by Jeremy Allison 2000.
@@ -20,15 +21,31 @@
*/
#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
-extern DOM_SID global_sid_Builtin;
+/**********************************************************************************
+ Check if this ACE has a SID in common with the token.
+**********************************************************************************/
+
+static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
+{
+ size_t i;
+
+ for (i = 0; i < token->num_sids; i++) {
+ if (sid_equal(&ace->trustee, &token->user_sids[i]))
+ return True;
+ }
+
+ return False;
+}
/*********************************************************************************
Check an ACE against a SID. We return the remaining needed permission
bits not yet granted. Zero means permission allowed (no more needed bits).
**********************************************************************************/
-static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_desired,
+static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
NTSTATUS *status)
{
uint32 mask = ace->info.mask;
@@ -88,7 +105,7 @@ static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_des
include other bits requested.
**********************************************************************************/
-static BOOL get_max_access( SEC_ACL *the_acl, const NT_USER_TOKEN *token, uint32 *granted,
+static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted,
uint32 desired,
NTSTATUS *status)
{
@@ -210,7 +227,7 @@ void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
"Access-Checking" document in MSDN.
*****************************************************************************/
-BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
+BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted,
NTSTATUS *status)
{
@@ -248,13 +265,12 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
}
/* The user sid is the first in the token */
- if (DEBUGLVL(3)) {
- DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) ));
-
- for (i = 1; i < token->num_sids; i++) {
- DEBUGADD(3, ("se_access_check: also %s\n",
- sid_to_string(sid_str, &token->user_sids[i])));
- }
+
+ DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) ));
+
+ for (i = 1; i < token->num_sids; i++) {
+ DEBUG(3, ("se_access_check: also %s\n",
+ sid_to_string(sid_str, &token->user_sids[i])));
}
/* Is the token the owner of the SID ? */
@@ -284,7 +300,7 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
SEC_ACE *ace = &the_acl->ace[i];
- DEBUGADD(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
+ DEBUG(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
(unsigned int)i, ace->type, ace->flags,
sid_to_string(sid_str, &ace->trustee),
(unsigned int) ace->info.mask,
@@ -293,7 +309,7 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
if (NT_STATUS_V(*status)) {
*acc_granted = 0;
- DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, nt_errstr(*status)));
+ DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, get_nt_error_msg(*status)));
return False;
}
}
@@ -316,42 +332,116 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
return False;
}
+/* Create a child security descriptor using another security descriptor as
+ the parent container. This child object can either be a container or
+ non-container object. */
-/*******************************************************************
- samr_make_sam_obj_sd
- ********************************************************************/
-
-NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
+ BOOL child_container)
{
- extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
+ SEC_DESC_BUF *sdb;
+ SEC_DESC *sd;
+ SEC_ACL *new_dacl, *the_acl;
+ SEC_ACE *new_ace_list = NULL;
+ int new_ace_list_ndx = 0, i;
+ size_t size;
+
+ /* Currently we only process the dacl when creating the child. The
+ sacl should also be processed but this is left out as sacls are
+ not implemented in Samba at the moment.*/
- SEC_ACE ace[3];
- SEC_ACCESS mask;
+ the_acl = parent_ctr->dacl;
- SEC_ACL *psa = NULL;
+ if (!(new_ace_list = talloc(ctx, sizeof(SEC_ACE) * the_acl->num_aces)))
+ return NULL;
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+ for (i = 0; the_acl && i < the_acl->num_aces; i++) {
+ SEC_ACE *ace = &the_acl->ace[i];
+ SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
+ uint8 new_flags = 0;
+ BOOL inherit = False;
+ fstring sid_str;
+
+ /* The OBJECT_INHERIT_ACE flag causes the ACE to be
+ inherited by non-container children objects. Container
+ children objects will inherit it as an INHERIT_ONLY
+ ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
+
+ if (!child_container) {
+ new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
+ } else {
+ new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ inherit = True;
+ }
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+ /* The CONAINER_INHERIT_ACE flag means all child container
+ objects will inherit and use the ACE. */
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
+ if (!child_container) {
+ inherit = False;
+ } else {
+ new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
+ }
+ }
+
+ /* The INHERIT_ONLY_ACE is not used by the se_access_check()
+ function for the parent container, but is inherited by
+ all child objects as a normal ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ /* Move along, nothing to see here */
+ }
+
+ /* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
+ is inherited by child objects but not grandchildren
+ objects. We clear the object inherit and container
+ inherit flags in the inherited ACE. */
+
+ if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
+ SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+
+ /* Add ACE to ACE list */
+
+ if (!inherit)
+ continue;
+
+ init_sec_access(&new_ace->info, ace->info.mask);
+ init_sec_ace(new_ace, &ace->trustee, ace->type,
+ new_ace->info, new_flags);
+
+ sid_to_string(sid_str, &ace->trustee);
+
+ DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
+ " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
+ ace->type, ace->flags, ace->info.mask,
+ sid_str, new_ace->type, new_ace->flags,
+ new_ace->info.mask));
+
+ new_ace_list_ndx++;
+ }
+
+ /* Create child security descriptor to return */
+
+ new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_access(&mask, GENERIC_RIGHTS_SAM_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ /* Use the existing user and group sids. I don't think this is
+ correct. Perhaps the user and group should be passed in as
+ parameters by the caller? */
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
+ sd = make_sec_desc(ctx, SEC_DESC_REVISION,
+ parent_ctr->owner_sid,
+ parent_ctr->grp_sid,
+ parent_ctr->sacl,
+ new_dacl, &size);
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
+ sdb = make_sec_desc_buf(ctx, size, sd);
- return NT_STATUS_OK;
+ return sdb;
}
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index 26be27ea515..08209190def 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
Copyright (C) Jeremy Allison 1998.
rewritten for version 2.0.6 by Tridge
@@ -177,22 +178,13 @@ void gain_root_group_privilege(void)
/****************************************************************************
- Set effective uid, and possibly the real uid too.
- We want to end up with either:
-
- ruid==uid and euid==uid
-
- or
-
- ruid==0 and euid==uid
-
- depending on what the local OS will allow us to regain root from.
+ Set *only* the effective uid.
+ we want to end up with ruid==0 and euid==uid
****************************************************************************/
void set_effective_uid(uid_t uid)
{
#if USE_SETRESUID
- /* Set the effective as well as the real uid. */
- setresuid(uid,uid,-1);
+ setresuid(-1,uid,-1);
#endif
#if USE_SETREUID
@@ -274,11 +266,11 @@ void restore_re_uid(void)
assert_uid(saved_ruid, saved_euid);
}
-
/****************************************************************************
- save the real and effective gid for later restoration. Used by the
+ Save the real and effective gid for later restoration. Used by the
getgroups code
****************************************************************************/
+
void save_re_gid(void)
{
saved_rgid = getgid();
@@ -286,8 +278,9 @@ void save_re_gid(void)
}
/****************************************************************************
- and restore them!
+ And restore them!
****************************************************************************/
+
void restore_re_gid(void)
{
#if USE_SETRESUID
@@ -308,7 +301,6 @@ void restore_re_gid(void)
assert_gid(saved_rgid, saved_egid);
}
-
/****************************************************************************
set the real AND effective uid to the current effective uid in a way that
allows root to be regained.
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 6b27fc84ddb..2b37162f943 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -1,12 +1,10 @@
/*
Unix SMB/CIFS implementation.
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
- Copyright (C) Jeremy Allison 1999
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Simo Sorce 2002
-
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
+ Copyright (C) Jeremy Allison 1999
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +22,13 @@
#include "includes.h"
+/* NOTE! the global_sam_sid is the SID of our local SAM. This is only
+ equal to the domain SID when we are a DC, otherwise its our
+ workstation SID */
+DOM_SID global_sam_sid;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
/*
* Some useful sids
*/
@@ -31,32 +36,71 @@
DOM_SID global_sid_World_Domain; /* Everyone domain */
DOM_SID global_sid_World; /* Everyone */
DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
+DOM_SID global_sid_Creator_Owner; /* Creator Owner */
+DOM_SID global_sid_Creator_Group; /* Creator Group */
DOM_SID global_sid_NT_Authority; /* NT Authority */
-DOM_SID global_sid_System; /* System */
DOM_SID global_sid_NULL; /* NULL sid */
DOM_SID global_sid_Authenticated_Users; /* All authenticated rids */
-DOM_SID global_sid_Network; /* Network rids */
-
-DOM_SID global_sid_Creator_Owner; /* Creator Owner */
-DOM_SID global_sid_Creator_Group; /* Creator Group */
-DOM_SID global_sid_Anonymous; /* Anonymous login */
-
-DOM_SID global_sid_Builtin; /* Local well-known domain */
-DOM_SID global_sid_Builtin_Administrators; /* Builtin administrators */
-DOM_SID global_sid_Builtin_Users; /* Builtin users */
-DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */
-DOM_SID global_sid_Builtin_Power_Users; /* Builtin power users */
-DOM_SID global_sid_Builtin_Account_Operators; /* Builtin account operators */
-DOM_SID global_sid_Builtin_Server_Operators; /* Builtin server operators */
-DOM_SID global_sid_Builtin_Print_Operators; /* Builtin print operators */
-DOM_SID global_sid_Builtin_Backup_Operators; /* Builtin backup operators */
-DOM_SID global_sid_Builtin_Replicator; /* Builtin replicator */
-
-#define SECURITY_NULL_SID_AUTHORITY 0
-#define SECURITY_WORLD_SID_AUTHORITY 1
-#define SECURITY_LOCAL_SID_AUTHORITY 2
-#define SECURITY_CREATOR_SID_AUTHORITY 3
-#define SECURITY_NT_AUTHORITY 5
+DOM_SID global_sid_Network; /* Network rids */
+DOM_SID global_sid_Anonymous; /* Anonymous login */
+
+DOM_SID global_sid_Builtin; /* Local well-known domain */
+DOM_SID global_sid_Builtin_Administrators;
+DOM_SID global_sid_Builtin_Users;
+DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */
+
+const DOM_SID *global_sid_everyone = &global_sid_World;
+
+typedef struct _known_sid_users {
+ uint32 rid;
+ enum SID_NAME_USE sid_name_use;
+ const char *known_user_name;
+} known_sid_users;
+
+/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
+
+static known_sid_users everyone_users[] = {
+ { 0, SID_NAME_WKN_GRP, "Everyone" },
+ {0, (enum SID_NAME_USE)0, NULL}};
+
+static known_sid_users creator_owner_users[] = {
+ { 0, SID_NAME_ALIAS, "Creator Owner" },
+ { 1, SID_NAME_ALIAS, "Creator Group" },
+ {0, (enum SID_NAME_USE)0, NULL}};
+
+static known_sid_users nt_authority_users[] = {
+ { 1, SID_NAME_ALIAS, "Dialup" },
+ { 2, SID_NAME_ALIAS, "Network"},
+ { 3, SID_NAME_ALIAS, "Batch"},
+ { 4, SID_NAME_ALIAS, "Interactive"},
+ { 6, SID_NAME_ALIAS, "Service"},
+ { 7, SID_NAME_ALIAS, "AnonymousLogon"},
+ { 8, SID_NAME_ALIAS, "Proxy"},
+ { 9, SID_NAME_ALIAS, "ServerLogon"},
+ { 11, SID_NAME_ALIAS, "Authenticated Users"},
+ { 18, SID_NAME_ALIAS, "SYSTEM"},
+ { 0, (enum SID_NAME_USE)0, NULL}};
+
+static known_sid_users builtin_groups[] = {
+ { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
+ { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
+ { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
+ { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
+ { 0, (enum SID_NAME_USE)0, NULL}};
+
+#define MAX_SID_NAMES 7
+
+static struct sid_name_map_info
+{
+ DOM_SID *sid;
+ const char *name;
+ known_sid_users *known_users;
+} sid_name_map[MAX_SID_NAMES];
+
+static BOOL sid_name_map_initialized = False;
/*
* An NT compatible anonymous token.
@@ -65,50 +109,67 @@ DOM_SID global_sid_Builtin_Replicator; /* Builtin replicator */
static DOM_SID anon_sid_array[3];
NT_USER_TOKEN anonymous_token = {
- 3,
- anon_sid_array
-};
-
-static DOM_SID system_sid_array[4];
-NT_USER_TOKEN system_token = {
- 1,
- system_sid_array
-};
-
-/****************************************************************************
- Lookup string names for SID types.
-****************************************************************************/
-
-static const struct {
- enum SID_NAME_USE sid_type;
- const char *string;
-} sid_name_type[] = {
- {SID_NAME_USER, "User"},
- {SID_NAME_DOM_GRP, "Domain Group"},
- {SID_NAME_DOMAIN, "Domain"},
- {SID_NAME_ALIAS, "Local Group"},
- {SID_NAME_WKN_GRP, "Well-known Group"},
- {SID_NAME_DELETED, "Deleted Account"},
- {SID_NAME_INVALID, "Invalid Account"},
- {SID_NAME_UNKNOWN, "UNKNOWN"},
- {SID_NAME_COMPUTER, "Computer"},
-
- {(enum SID_NAME_USE)0, NULL}
+ 3,
+ anon_sid_array
};
-const char *sid_type_lookup(uint32 sid_type)
+/**************************************************************************
+ quick init function
+ *************************************************************************/
+static void init_sid_name_map (void)
{
int i = 0;
+
+ if (sid_name_map_initialized) return;
+
- /* Look through list */
- while(sid_name_type[i].sid_type != 0) {
- if (sid_name_type[i].sid_type == sid_type)
- return sid_name_type[i].string;
+ if ((lp_security() == SEC_USER) && lp_domain_logons()) {
+ sid_name_map[i].sid = &global_sam_sid;
+ sid_name_map[i].name = global_myworkgroup;
+ sid_name_map[i].known_users = NULL;
+ i++;
+ sid_name_map[i].sid = &global_sam_sid;
+ sid_name_map[i].name = global_myname;
+ sid_name_map[i].known_users = NULL;
+ i++;
+ }
+ else {
+ sid_name_map[i].sid = &global_sam_sid;
+ sid_name_map[i].name = global_myname;
+ sid_name_map[i].known_users = NULL;
i++;
}
- /* Default return */
- return "SID *TYPE* is INVALID";
+ sid_name_map[i].sid = &global_sid_Builtin;
+ sid_name_map[i].name = "BUILTIN";
+ sid_name_map[i].known_users = &builtin_groups[0];
+ i++;
+
+ sid_name_map[i].sid = &global_sid_World_Domain;
+ sid_name_map[i].name = "";
+ sid_name_map[i].known_users = &everyone_users[0];
+ i++;
+
+ sid_name_map[i].sid = &global_sid_Creator_Owner_Domain;
+ sid_name_map[i].name = "";
+ sid_name_map[i].known_users = &creator_owner_users[0];
+ i++;
+
+ sid_name_map[i].sid = &global_sid_NT_Authority;
+ sid_name_map[i].name = "NT Authority";
+ sid_name_map[i].known_users = &nt_authority_users[0];
+ i++;
+
+
+ /* end of array */
+ sid_name_map[i].sid = NULL;
+ sid_name_map[i].name = NULL;
+ sid_name_map[i].known_users = NULL;
+
+ sid_name_map_initialized = True;
+
+ return;
+
}
/****************************************************************************
@@ -117,86 +178,145 @@ const char *sid_type_lookup(uint32 sid_type)
void generate_wellknown_sids(void)
{
- static BOOL initialised = False;
-
- if (initialised)
- return;
-
- /* SECURITY_NULL_SID_AUTHORITY */
- string_to_sid(&global_sid_NULL, "S-1-0-0");
-
- /* SECURITY_WORLD_SID_AUTHORITY */
+ string_to_sid(&global_sid_Builtin, "S-1-5-32");
+ string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
+ string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
+ string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
string_to_sid(&global_sid_World_Domain, "S-1-1");
string_to_sid(&global_sid_World, "S-1-1-0");
-
- /* SECURITY_CREATOR_SID_AUTHORITY */
string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
-
- /* SECURITY_NT_AUTHORITY */
string_to_sid(&global_sid_NT_Authority, "S-1-5");
+ string_to_sid(&global_sid_NULL, "S-1-0-0");
+ string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
string_to_sid(&global_sid_Network, "S-1-5-2");
string_to_sid(&global_sid_Anonymous, "S-1-5-7");
- string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
- string_to_sid(&global_sid_System, "S-1-5-18");
-
- /* SECURITY_BUILTIN_DOMAIN_RID */
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
- string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
- string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
- string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
- string_to_sid(&global_sid_Builtin_Power_Users, "S-1-5-32-547");
- string_to_sid(&global_sid_Builtin_Account_Operators, "S-1-5-32-548");
- string_to_sid(&global_sid_Builtin_Server_Operators, "S-1-5-32-549");
- string_to_sid(&global_sid_Builtin_Print_Operators, "S-1-5-32-550");
- string_to_sid(&global_sid_Builtin_Backup_Operators, "S-1-5-32-551");
- string_to_sid(&global_sid_Builtin_Replicator, "S-1-5-32-552");
/* Create the anon token. */
sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);
+}
- /* Create the system token. */
- sid_copy( &system_token.user_sids[0], &global_sid_System);
+/**************************************************************************
+ Turns a domain SID into a name, returned in the nt_domain argument.
+***************************************************************************/
+
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain)
+{
+ fstring sid_str;
+ int i = 0;
- initialised = True;
+ sid_to_string(sid_str, sid);
+
+ if (!sid_name_map_initialized)
+ init_sid_name_map();
+
+ DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
+
+ if (nt_domain == NULL)
+ return False;
+
+ while (sid_name_map[i].sid != NULL) {
+ sid_to_string(sid_str, sid_name_map[i].sid);
+ DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str));
+ if (sid_equal(sid_name_map[i].sid, sid)) {
+ fstrcpy(nt_domain, sid_name_map[i].name);
+ DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain));
+ return True;
+ }
+ i++;
+ }
+
+ DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str));
+
+ return False;
}
/**************************************************************************
- Create the SYSTEM token.
+ Looks up a known username from one of the known domains.
***************************************************************************/
-NT_USER_TOKEN *get_system_token(void)
+BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
{
- generate_wellknown_sids(); /* The token is initialised here */
- return &system_token;
+ int i = 0;
+ struct sid_name_map_info *psnm;
+
+ if (!sid_name_map_initialized)
+ init_sid_name_map();
+
+ for(i = 0; sid_name_map[i].sid != NULL; i++) {
+ psnm = &sid_name_map[i];
+ if(sid_equal(psnm->sid, sid)) {
+ int j;
+ for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) {
+ if(rid == psnm->known_users[j].rid) {
+ DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n",
+ (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name ));
+ fstrcpy( name, psnm->known_users[j].known_user_name);
+ *psid_name_use = psnm->known_users[j].sid_name_use;
+ return True;
+ }
+ }
+ }
+ }
+
+ return False;
}
-/******************************************************************
- get the default domain/netbios name to be used when dealing
- with our passdb list of accounts
-******************************************************************/
+/**************************************************************************
+ Turns a domain name into a SID.
+ *** side-effect: if the domain name is NULL, it is set to our domain ***
+***************************************************************************/
-const char *get_global_sam_name(void)
+BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain)
{
- if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
- return lp_workgroup();
+ int i = 0;
+
+ if (nt_domain == NULL) {
+ DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n"));
+ sid_copy(sid, &global_sam_sid);
+ return True;
+ }
+
+ if (nt_domain[0] == 0) {
+ fstrcpy(nt_domain, global_myname);
+ DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain));
+ sid_copy(sid, &global_sam_sid);
+ return True;
}
- return global_myname();
+
+ DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain));
+
+ if (!sid_name_map_initialized)
+ init_sid_name_map();
+
+ while (sid_name_map[i].name != NULL) {
+ DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name));
+ if (strequal(sid_name_map[i].name, nt_domain)) {
+ fstring sid_str;
+ sid_copy(sid, sid_name_map[i].sid);
+ sid_to_string(sid_str, sid_name_map[i].sid);
+ DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str));
+ return True;
+ }
+ i++;
+ }
+
+ DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain));
+ return False;
}
/**************************************************************************
Splits a name of format \DOMAIN\name or name into its two components.
- Sets the DOMAIN name to global_myname() if it has not been specified.
+ Sets the DOMAIN name to global_myname if it has not been specified.
***************************************************************************/
void split_domain_name(const char *fullname, char *domain, char *name)
{
pstring full_name;
- const char *sep;
- char *p;
+ char *p, *sep;
sep = lp_winbind_separator();
@@ -206,15 +326,15 @@ void split_domain_name(const char *fullname, char *domain, char *name)
fullname++;
pstrcpy(full_name, fullname);
- p = strchr_m(full_name+1, '\\');
- if (!p) p = strchr_m(full_name+1, sep[0]);
+ p = strchr(full_name+1, '\\');
+ if (!p) p = strchr(full_name+1, sep[0]);
if (p != NULL) {
*p = 0;
fstrcpy(domain, full_name);
fstrcpy(name, p+1);
} else {
- fstrcpy(domain, get_global_sam_name());
+ fstrcpy(domain, global_myname);
fstrcpy(name, full_name);
}
@@ -222,62 +342,33 @@ void split_domain_name(const char *fullname, char *domain, char *name)
fullname, domain, name));
}
-/****************************************************************************
- Test if a SID is wellknown and resolvable.
-****************************************************************************/
-
-BOOL resolvable_wellknown_sid(DOM_SID *sid)
-{
- uint32 ia = (sid->id_auth[5]) +
- (sid->id_auth[4] << 8 ) +
- (sid->id_auth[3] << 16) +
- (sid->id_auth[2] << 24);
-
- if (sid->sid_rev_num != SEC_DESC_REVISION || sid->num_auths < 1)
- return False;
-
- return (ia == SECURITY_WORLD_SID_AUTHORITY ||
- ia == SECURITY_CREATOR_SID_AUTHORITY);
-}
-
/*****************************************************************
Convert a SID to an ascii string.
*****************************************************************/
char *sid_to_string(fstring sidstr_out, const DOM_SID *sid)
{
- char subauth[16];
- int i;
- uint32 ia;
-
- if (!sid) {
- fstrcpy(sidstr_out, "(NULL SID)");
- return sidstr_out;
- }
-
- /*
- * BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
- * in a range of 2^48.
- */
- ia = (sid->id_auth[5]) +
- (sid->id_auth[4] << 8 ) +
- (sid->id_auth[3] << 16) +
- (sid->id_auth[2] << 24);
-
- slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
-
- for (i = 0; i < sid->num_auths; i++) {
- slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
- fstrcat(sidstr_out, subauth);
- }
-
- return sidstr_out;
+ char subauth[16];
+ int i;
+ /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+ uint32 ia = (sid->id_auth[5]) +
+ (sid->id_auth[4] << 8 ) +
+ (sid->id_auth[3] << 16) +
+ (sid->id_auth[2] << 24);
+
+ slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
+
+ for (i = 0; i < sid->num_auths; i++) {
+ slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
+ fstrcat(sidstr_out, subauth);
+ }
+
+ return sidstr_out;
}
-/*****************************************************************
- Useful function for debug lines.
-*****************************************************************/
-
+/*
+ useful function for debug lines
+*/
const char *sid_string_static(const DOM_SID *sid)
{
static fstring sid_str;
@@ -291,64 +382,64 @@ const char *sid_string_static(const DOM_SID *sid)
BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
{
- pstring tok;
- char *q;
- const char *p;
- /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
- uint32 ia;
+ pstring tok;
+ char *q;
+ const char *p;
+ /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+ uint32 ia;
- if (StrnCaseCmp( sidstr, "S-", 2)) {
- DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
- return False;
- }
-
- memset((char *)sidout, '\0', sizeof(DOM_SID));
-
- p = q = strdup(sidstr + 2);
- if (p == NULL) {
- DEBUG(0, ("string_to_sid: out of memory!\n"));
- return False;
- }
-
- if (!next_token(&p, tok, "-", sizeof(tok))) {
- DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
- SAFE_FREE(q);
- return False;
- }
-
- /* Get the revision number. */
- sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);
-
- if (!next_token(&p, tok, "-", sizeof(tok))) {
- DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
- SAFE_FREE(q);
- return False;
- }
-
- /* identauth in decimal should be < 2^32 */
- ia = (uint32)strtoul(tok, NULL, 10);
-
- /* NOTE - the ia value is in big-endian format. */
- sidout->id_auth[0] = 0;
- sidout->id_auth[1] = 0;
- sidout->id_auth[2] = (ia & 0xff000000) >> 24;
- sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
- sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
- sidout->id_auth[5] = (ia & 0x000000ff);
-
- sidout->num_auths = 0;
-
- while(next_token(&p, tok, "-", sizeof(tok)) &&
- sidout->num_auths < MAXSUBAUTHS) {
- /*
- * NOTE - the subauths are in native machine-endian format. They
- * are converted to little-endian when linearized onto the wire.
- */
- sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
- }
-
- SAFE_FREE(q);
- return True;
+ if (StrnCaseCmp( sidstr, "S-", 2)) {
+ DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+ return False;
+ }
+
+ memset((char *)sidout, '\0', sizeof(DOM_SID));
+
+ p = q = strdup(sidstr + 2);
+ if (p == NULL) {
+ DEBUG(0, ("string_to_sid: out of memory!\n"));
+ return False;
+ }
+
+ if (!next_token(&p, tok, "-", sizeof(tok))) {
+ DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ SAFE_FREE(q);
+ return False;
+ }
+
+ /* Get the revision number. */
+ sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);
+
+ if (!next_token(&p, tok, "-", sizeof(tok))) {
+ DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ SAFE_FREE(q);
+ return False;
+ }
+
+ /* identauth in decimal should be < 2^32 */
+ ia = (uint32)strtoul(tok, NULL, 10);
+
+ /* NOTE - the ia value is in big-endian format. */
+ sidout->id_auth[0] = 0;
+ sidout->id_auth[1] = 0;
+ sidout->id_auth[2] = (ia & 0xff000000) >> 24;
+ sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
+ sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
+ sidout->id_auth[5] = (ia & 0x000000ff);
+
+ sidout->num_auths = 0;
+
+ while(next_token(&p, tok, "-", sizeof(tok)) &&
+ sidout->num_auths < MAXSUBAUTHS) {
+ /*
+ * NOTE - the subauths are in native machine-endian format. They
+ * are converted to little-endian when linearized onto the wire.
+ */
+ sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
+ }
+
+ SAFE_FREE(q);
+ return True;
}
/*****************************************************************
@@ -382,11 +473,8 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
Return the last rid from the end of a sid
*****************************************************************/
-BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid)
+BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid)
{
- if (!sid || !rid)
- return False;
-
if (sid->num_auths > 0) {
*rid = sid->sub_auths[sid->num_auths - 1];
return True;
@@ -395,28 +483,6 @@ BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid)
}
/*****************************************************************
- Return the last rid from the end of a sid
- and check the sid against the exp_dom_sid
-*****************************************************************/
-
-BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
-{
- if (!exp_dom_sid || !sid || !rid)
- return False;
-
- if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
- return False;
- }
-
- if (sid_compare_domain(exp_dom_sid, sid)!=0){
- *rid=(-1);
- return False;
- }
-
- return sid_peek_rid(sid, rid);
-}
-
-/*****************************************************************
Copies a sid
*****************************************************************/
@@ -424,7 +490,7 @@ void sid_copy(DOM_SID *dst, const DOM_SID *src)
{
int i;
- ZERO_STRUCTP(dst);
+ memset((char *)dst, '\0', sizeof(DOM_SID));
dst->sid_rev_num = src->sid_rev_num;
dst->num_auths = src->num_auths;
@@ -436,10 +502,28 @@ void sid_copy(DOM_SID *dst, const DOM_SID *src)
}
/*****************************************************************
+ Duplicates a sid - mallocs the target.
+*****************************************************************/
+
+DOM_SID *sid_dup(DOM_SID *src)
+{
+ DOM_SID *dst;
+
+ if(!src)
+ return NULL;
+
+ if((dst = malloc(sizeof(DOM_SID))) != NULL) {
+ memset(dst, '\0', sizeof(DOM_SID));
+ sid_copy( dst, src);
+ }
+
+ return dst;
+}
+
+/*****************************************************************
Write a sid out into on-the-wire format.
*****************************************************************/
-
-BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
+BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
{
size_t i;
@@ -456,41 +540,33 @@ BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
}
/*****************************************************************
- Parse a on-the-wire SID to a DOM_SID.
+ parse a on-the-wire SID to a DOM_SID
*****************************************************************/
-
-BOOL sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
+BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
{
int i;
- if (len < 8)
- return False;
-
- ZERO_STRUCTP(sid);
-
+ if (len < 8) return False;
sid->sid_rev_num = CVAL(inbuf, 0);
sid->num_auths = CVAL(inbuf, 1);
memcpy(sid->id_auth, inbuf+2, 6);
- if (len < 8 + sid->num_auths*4)
- return False;
- for (i=0;i<sid->num_auths;i++)
+ if (len < 8 + sid->num_auths*4) return False;
+ for (i=0;i<sid->num_auths;i++) {
sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
+ }
return True;
}
+
/*****************************************************************
Compare the auth portion of two sids.
*****************************************************************/
-
-static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
+int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
{
int i;
- if (sid1 == sid2)
- return 0;
- if (!sid1)
- return -1;
- if (!sid2)
- return 1;
+ if (sid1 == sid2) return 0;
+ if (!sid1) return -1;
+ if (!sid2) return 1;
if (sid1->sid_rev_num != sid2->sid_rev_num)
return sid1->sid_rev_num - sid2->sid_rev_num;
@@ -505,19 +581,15 @@ static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
/*****************************************************************
Compare two sids.
*****************************************************************/
-
int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
{
int i;
- if (sid1 == sid2)
- return 0;
- if (!sid1)
- return -1;
- if (!sid2)
- return 1;
+ if (sid1 == sid2) return 0;
+ if (!sid1) return -1;
+ if (!sid2) return 1;
- /* Compare most likely different rids, first: i.e start at end */
+ /* compare most likely different rids, first: i.e start at end */
if (sid1->num_auths != sid2->num_auths)
return sid1->num_auths - sid2->num_auths;
@@ -529,10 +601,9 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
}
/*****************************************************************
- See if 2 SIDs are in the same domain
- this just compares the leading sub-auths
+see if 2 SIDs are in the same domain
+this just compares the leading sub-auths
*****************************************************************/
-
int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
{
int n, i;
@@ -549,25 +620,47 @@ int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
/*****************************************************************
Compare two sids.
*****************************************************************/
-
BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
{
return sid_compare(sid1, sid2) == 0;
}
+
/*****************************************************************
- Check if the SID is the builtin SID (S-1-5-32).
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
*****************************************************************/
+BOOL sid_check_is_domain(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sam_sid);
+}
+
+/*****************************************************************
+ Check if the SID is the builtin SID (S-1-5-32).
+*****************************************************************/
BOOL sid_check_is_builtin(const DOM_SID *sid)
{
return sid_equal(sid, &global_sid_Builtin);
}
+
/*****************************************************************
- Check if the SID is one of the builtin SIDs (S-1-5-32-a).
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
*****************************************************************/
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, &global_sam_sid);
+}
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
BOOL sid_check_is_in_builtin(const DOM_SID *sid)
{
DOM_SID dom_sid;
@@ -579,11 +672,12 @@ BOOL sid_check_is_in_builtin(const DOM_SID *sid)
return sid_equal(&dom_sid, &global_sid_Builtin);
}
+
/*****************************************************************
Calculates size of a sid.
*****************************************************************/
-size_t sid_size(const DOM_SID *sid)
+size_t sid_size(DOM_SID *sid)
{
if (sid == NULL)
return 0;
@@ -606,44 +700,28 @@ BOOL non_mappable_sid(DOM_SID *sid)
if (sid_equal(&dom, &global_sid_Builtin))
return True;
+ if (sid_equal(&dom, &global_sid_Creator_Owner_Domain))
+ return True;
+
if (sid_equal(&dom, &global_sid_NT_Authority))
return True;
return False;
}
-/*****************************************************************
- Return the binary string representation of a DOM_SID.
- Caller must free.
-*****************************************************************/
-
-char *sid_binstring(const DOM_SID *sid)
+/*
+ return the binary string representation of a DOM_SID
+ caller must free
+*/
+char *sid_binstring(DOM_SID *sid)
{
char *buf, *s;
int len = sid_size(sid);
buf = malloc(len);
- if (!buf)
- return NULL;
+ if (!buf) return NULL;
sid_linearize(buf, len, sid);
s = binary_string(buf, len);
free(buf);
return s;
}
-/*******************************************************************
- Tallocs a duplicate SID.
-********************************************************************/
-
-DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
-{
- DOM_SID *dst;
-
- if(!src)
- return NULL;
-
- if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
- sid_copy( dst, src);
- }
-
- return dst;
-}
diff --git a/source/lib/util_smbd.c b/source/lib/util_smbd.c
deleted file mode 100644
index 071f20b4162..00000000000
--- a/source/lib/util_smbd.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions, used in smbd only
- Copyright (C) Andrew Tridgell 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- This function requires sys_getgrouplist - which is only
- available in smbd due to it's use of become_root() in a
- legacy systems hack.
-*/
-
-/*
- return a full list of groups for a user
-
- returns the number of groups the user is a member of. The return will include the
- users primary group.
-
- remember to free the resulting gid_t array
-
- NOTE! uses become_root() to gain correct priviages on systems
- that lack a native getgroups() call (uses initgroups and getgroups)
-*/
-int getgroups_user(const char *user, gid_t **groups)
-{
- struct passwd *pwd;
- int ngrp, max_grp;
-
- pwd = getpwnam_alloc(user);
- if (!pwd) return -1;
-
- max_grp = groups_max();
- (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp);
- if (! *groups) {
- passwd_free(&pwd);
- errno = ENOMEM;
- return -1;
- }
-
- ngrp = sys_getgrouplist(user, pwd->pw_gid, *groups, &max_grp);
- if (ngrp <= 0) {
- passwd_free(&pwd);
- free(*groups);
- return ngrp;
- }
-
- passwd_free(&pwd);
- return ngrp;
-}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 308c2fc14be..ceb73eeede7 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Tim Potter 2000-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +21,13 @@
#include "includes.h"
+#ifdef WITH_SSL
+#include <openssl/ssl.h>
+#undef Realloc /* SSLeay defines this and samba has a function of this name */
+extern SSL *ssl;
+extern int sslFd;
+#endif /* WITH_SSL */
+
/* the last IP received from */
struct in_addr lastip;
@@ -29,29 +36,6 @@ int lastport=0;
int smb_read_error = 0;
-static char *get_socket_addr(int fd)
-{
- struct sockaddr sa;
- struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
- socklen_t length = sizeof(sa);
- static fstring addr_buf;
-
- fstrcpy(addr_buf,"0.0.0.0");
-
- if (fd == -1) {
- return addr_buf;
- }
-
- if (getsockname(fd, &sa, &length) < 0) {
- DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
- return addr_buf;
- }
-
- fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
-
- return addr_buf;
-}
-
/****************************************************************************
Determine if a file descriptor is in fact a socket.
****************************************************************************/
@@ -74,7 +58,7 @@ typedef struct smb_socket_option {
int opttype;
} smb_socket_option;
-static const smb_socket_option socket_options[] = {
+smb_socket_option socket_options[] = {
{"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
{"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
{"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
@@ -118,16 +102,16 @@ static void print_socket_options(int s)
{
int value;
socklen_t vlen = 4;
- const smb_socket_option *p = &socket_options[0];
+ smb_socket_option *p = &socket_options[0];
/* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */
/* reported on samba-technical --jerry */
if ( DEBUGLEVEL >= 5 ) {
- for (; p->name != NULL; p++) {
- if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
- DEBUG(5,("Could not test socket option %s.\n", p->name));
- } else {
- DEBUG(5,("socket option %s = %d\n",p->name,value));
+ for (; p->name != NULL; p++) {
+ if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
+ DEBUG(5,("Could not test socket option %s.\n", p->name));
+ } else {
+ DEBUG(5,("socket option %s = %d\n",p->name,value));
}
}
}
@@ -147,7 +131,7 @@ void set_socket_options(int fd, const char *options)
char *p;
BOOL got_value = False;
- if ((p = strchr_m(tok,'='))) {
+ if ((p = strchr(tok,'='))) {
*p = 0;
value = atoi(p+1);
got_value = True;
@@ -209,8 +193,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
lastip = sock.sin_addr;
lastport = ntohs(sock.sin_port);
- DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n",
- inet_ntoa(lastip), lastport, (unsigned long)ret));
+ DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
+ inet_ntoa(lastip), lastport, ret));
return(ret);
}
@@ -222,149 +206,238 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
time_out = timeout in milliseconds
****************************************************************************/
-ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
+static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
- fd_set fds;
- int selrtn;
- ssize_t readret;
- size_t nread = 0;
- struct timeval timeout;
-
- /* just checking .... */
- if (maxcnt <= 0)
- return(0);
-
- smb_read_error = 0;
-
- /* Blocking read */
- if (time_out <= 0) {
- if (mincnt == 0) mincnt = maxcnt;
-
- while (nread < mincnt) {
- readret = sys_read(fd, buf + nread, maxcnt - nread);
-
- if (readret == 0) {
- DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
- smb_read_error = READ_EOF;
- return -1;
- }
-
- if (readret == -1) {
- DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
- nread += readret;
- }
- return((ssize_t)nread);
- }
-
- /* Most difficult - timeout read */
- /* If this is ever called on a disk file and
- mincnt is greater then the filesize then
- system performance will suffer severely as
- select always returns true on disk files */
-
- /* Set initial timeout */
- timeout.tv_sec = (time_t)(time_out / 1000);
- timeout.tv_usec = (long)(1000 * (time_out % 1000));
-
- for (nread=0; nread < mincnt; ) {
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
-
- /* Check if error */
- if (selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
- smb_read_error = READ_TIMEOUT;
- return -1;
- }
-
- readret = sys_read(fd, buf+nread, maxcnt-nread);
-
- if (readret == 0) {
- /* we got EOF on the file descriptor */
- DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
- smb_read_error = READ_EOF;
- return -1;
- }
-
- if (readret == -1) {
- /* the descriptor is probably dead */
- DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
-
- nread += readret;
- }
-
- /* Return the number we got */
- return (ssize_t)nread;
+ fd_set fds;
+ int selrtn;
+ ssize_t readret;
+ size_t nread = 0;
+ struct timeval timeout;
+
+ /* just checking .... */
+ if (maxcnt <= 0)
+ return(0);
+
+ smb_read_error = 0;
+
+ /* Blocking read */
+ if (time_out <= 0) {
+ if (mincnt == 0) mincnt = maxcnt;
+
+ while (nread < mincnt) {
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+ }else{
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+#endif /* WITH_SSL */
+
+ if (readret == 0) {
+ DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
+ smb_read_error = READ_EOF;
+ return -1;
+ }
+
+ if (readret == -1) {
+ DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
+ smb_read_error = READ_ERROR;
+ return -1;
+ }
+ nread += readret;
+ }
+ return((ssize_t)nread);
+ }
+
+ /* Most difficult - timeout read */
+ /* If this is ever called on a disk file and
+ mincnt is greater then the filesize then
+ system performance will suffer severely as
+ select always returns true on disk files */
+
+ /* Set initial timeout */
+ timeout.tv_sec = (time_t)(time_out / 1000);
+ timeout.tv_usec = (long)(1000 * (time_out % 1000));
+
+ for (nread=0; nread < mincnt; ) {
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+
+ selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
+
+ /* Check if error */
+ if(selrtn == -1) {
+ /* something is wrong. Maybe the socket is dead? */
+ DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
+ smb_read_error = READ_ERROR;
+ return -1;
+ }
+
+ /* Did we timeout ? */
+ if (selrtn == 0) {
+ DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
+ smb_read_error = READ_TIMEOUT;
+ return -1;
+ }
+
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+ }else{
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = sys_read(fd, buf+nread, maxcnt-nread);
+#endif /* WITH_SSL */
+
+ if (readret == 0) {
+ /* we got EOF on the file descriptor */
+ DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
+ smb_read_error = READ_EOF;
+ return -1;
+ }
+
+ if (readret == -1) {
+ /* the descriptor is probably dead */
+ DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
+ smb_read_error = READ_ERROR;
+ return -1;
+ }
+
+ nread += readret;
+ }
+
+ /* Return the number we got */
+ return((ssize_t)nread);
}
/****************************************************************************
- Read data from the client, reading exactly N bytes.
+ Read data from a fd with a timout in msec.
+ mincount = if timeout, minimum to read before returning
+ maxcount = number to be read.
+ time_out = timeout in milliseconds
****************************************************************************/
-ssize_t read_data(int fd,char *buffer,size_t N)
+ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
- ssize_t ret;
- size_t total=0;
-
- smb_read_error = 0;
+ fd_set fds;
+ int selrtn;
+ ssize_t readret;
+ size_t nread = 0;
+ struct timeval timeout;
+
+ /* just checking .... */
+ if (maxcnt <= 0)
+ return(0);
+
+ /* Blocking read */
+ if (time_out <= 0) {
+ if (mincnt == 0) mincnt = maxcnt;
+
+ while (nread < mincnt) {
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+ }else{
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+#endif /* WITH_SSL */
+
+ if (readret <= 0)
+ return readret;
+
+ nread += readret;
+ }
+ return((ssize_t)nread);
+ }
+
+ /* Most difficult - timeout read */
+ /* If this is ever called on a disk file and
+ mincnt is greater then the filesize then
+ system performance will suffer severely as
+ select always returns true on disk files */
+
+ /* Set initial timeout */
+ timeout.tv_sec = (time_t)(time_out / 1000);
+ timeout.tv_usec = (long)(1000 * (time_out % 1000));
+
+ for (nread=0; nread < mincnt; ) {
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+
+ selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
- while (total < N) {
- ret = sys_read(fd,buffer + total,N - total);
+ if(selrtn <= 0)
+ return selrtn;
+
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+ }else{
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = sys_read(fd, buf+nread, maxcnt-nread);
+#endif /* WITH_SSL */
+
+ if (readret <= 0)
+ return readret;
+
+ nread += readret;
+ }
+
+ /* Return the number we got */
+ return((ssize_t)nread);
+}
- if (ret == 0) {
- DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_EOF;
- return 0;
- }
+/****************************************************************************
+send a keepalive packet (rfc1002)
+****************************************************************************/
- if (ret == -1) {
- DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
- total += ret;
- }
- return (ssize_t)total;
+BOOL send_keepalive(int client)
+{
+ unsigned char buf[4];
+
+ buf[0] = 0x85;
+ buf[1] = buf[2] = buf[3] = 0;
+
+ return(write_socket_data(client,(char *)buf,4) == 4);
}
/****************************************************************************
- Read data from a socket, reading exactly N bytes.
+ read data from the client, reading exactly N bytes.
****************************************************************************/
-static ssize_t read_socket_data(int fd,char *buffer,size_t N)
+ssize_t read_data(int fd,char *buffer,size_t N)
{
- ssize_t ret;
+ ssize_t ret;
size_t total=0;
smb_read_error = 0;
while (total < N) {
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ ret = SSL_read(ssl, buffer + total, N - total);
+ }else{
+ ret = sys_read(fd,buffer + total,N - total);
+ }
+#else /* WITH_SSL */
ret = sys_read(fd,buffer + total,N - total);
+#endif /* WITH_SSL */
if (ret == 0) {
- DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
+ DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
smb_read_error = READ_EOF;
return 0;
}
if (ret == -1) {
- DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
+ DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
smb_read_error = READ_ERROR;
return -1;
}
@@ -383,17 +456,26 @@ ssize_t write_data(int fd,char *buffer,size_t N)
ssize_t ret;
while (total < N) {
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ ret = SSL_write(ssl,buffer + total,N - total);
+ } else {
+ ret = sys_write(fd,buffer + total,N - total);
+ }
+#else /* WITH_SSL */
ret = sys_write(fd,buffer + total,N - total);
+#endif /* WITH_SSL */
if (ret == -1) {
DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
return -1;
}
if (ret == 0)
- return total;
+ return (ssize_t)total;
- total += ret;
+ total += (size_t)ret;
}
+
return (ssize_t)total;
}
@@ -401,20 +483,28 @@ ssize_t write_data(int fd,char *buffer,size_t N)
Write data to a socket - use send rather than write.
****************************************************************************/
-static ssize_t write_socket_data(int fd,char *buffer,size_t N)
+ssize_t write_socket_data(int fd,char *buffer,size_t N)
{
size_t total=0;
ssize_t ret;
while (total < N) {
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ ret = SSL_write(ssl,buffer + total,N - total);
+ }else{
+ ret = sys_send(fd,buffer + total,N - total, 0);
+ }
+#else /* WITH_SSL */
ret = sys_send(fd,buffer + total,N - total,0);
+#endif /* WITH_SSL */
if (ret == -1) {
DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
return -1;
}
if (ret == 0)
- return total;
+ return (ssize_t)total;
total += ret;
}
@@ -422,7 +512,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N)
}
/****************************************************************************
- Write to a socket.
+write to a socket
****************************************************************************/
ssize_t write_socket(int fd,char *buf,size_t len)
@@ -441,26 +531,11 @@ ssize_t write_socket(int fd,char *buf,size_t len)
}
/****************************************************************************
- Send a keepalive packet (rfc1002).
-****************************************************************************/
-
-BOOL send_keepalive(int client)
-{
- unsigned char buf[4];
-
- buf[0] = SMBkeepalive;
- buf[1] = buf[2] = buf[3] = 0;
-
- return(write_socket_data(client,(char *)buf,4) == 4);
-}
-
-
-/****************************************************************************
- Read 4 bytes of a smb packet and return the smb length of the packet.
- Store the result in the buffer.
- This version of the function will return a length of zero on receiving
- a keepalive packet.
- Timeout is in milliseconds.
+read 4 bytes of a smb packet and return the smb length of the packet
+store the result in the buffer
+This version of the function will return a length of zero on receiving
+a keepalive packet.
+timeout is in milliseconds.
****************************************************************************/
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
@@ -473,7 +548,7 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
if (timeout > 0)
ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
else
- ok = (read_socket_data(fd,inbuf,4) == 4);
+ ok = (read_data(fd,inbuf,4) == 4);
if (!ok)
return(-1);
@@ -481,20 +556,20 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
len = smb_len(inbuf);
msg_type = CVAL(inbuf,0);
- if (msg_type == SMBkeepalive)
+ if (msg_type == 0x85)
DEBUG(5,("Got keepalive packet\n"));
}
- DEBUG(10,("got smb length of %lu\n",(unsigned long)len));
+ DEBUG(10,("got smb length of %d\n",len));
return(len);
}
/****************************************************************************
- Read 4 bytes of a smb packet and return the smb length of the packet.
- Store the result in the buffer. This version of the function will
- never return a session keepalive (length of zero).
- Timeout is in milliseconds.
+read 4 bytes of a smb packet and return the smb length of the packet
+store the result in the buffer. This version of the function will
+never return a session keepalive (length of zero).
+timeout is in milliseconds.
****************************************************************************/
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
@@ -508,25 +583,24 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
return len;
/* Ignore session keepalives. */
- if(CVAL(inbuf,0) != SMBkeepalive)
+ if(CVAL(inbuf,0) != 0x85)
break;
}
- DEBUG(10,("read_smb_length: got smb length of %lu\n",
- (unsigned long)len));
+ DEBUG(10,("read_smb_length: got smb length of %d\n",len));
return len;
}
/****************************************************************************
- Read an smb from a fd. Note that the buffer *MUST* be of size
- BUFFER_SIZE+SAFETY_MARGIN.
- The timeout is in milliseconds.
- This function will return on receipt of a session keepalive packet.
- Doesn't check the MAC on signed packets.
+ read an smb from a fd. Note that the buffer *MUST* be of size
+ BUFFER_SIZE+SAFETY_MARGIN.
+ The timeout is in milliseconds.
+ This function will return on a
+ receipt of a session keepalive packet.
****************************************************************************/
-BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
+BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
{
ssize_t len,ret;
@@ -536,7 +610,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0) {
- DEBUG(10,("receive_smb_raw: length < 0!\n"));
+ DEBUG(10,("receive_smb: length < 0 !\n"));
/*
* Correct fix. smb_read_error may have already been
@@ -546,7 +620,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
if (smb_read_error == 0)
smb_read_error = READ_ERROR;
- return False;
+ return(False);
}
/*
@@ -555,7 +629,7 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
*/
if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
- DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len));
+ DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
/*
@@ -571,45 +645,53 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
}
if(len > 0) {
- ret = read_socket_data(fd,buffer+4,len);
+ ret = read_data(fd,buffer+4,len);
if (ret != len) {
if (smb_read_error == 0)
smb_read_error = READ_ERROR;
return False;
}
-
- /* not all of samba3 properly checks for packet-termination of strings. This
- ensures that we don't run off into empty space. */
- SSVAL(buffer+4,len, 0);
}
- return True;
+ return(True);
}
/****************************************************************************
- Wrapper for receive_smb_raw().
- Checks the MAC on signed packets.
+ read an smb from a fd ignoring all keepalive packets. Note that the buffer
+ *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
+ The timeout is in milliseconds
+
+ This is exactly the same as receive_smb except that it never returns
+ a session keepalive packet (just as receive_smb used to do).
+ receive_smb was changed to return keepalives as the oplock processing means this call
+ should never go into a blocking read.
****************************************************************************/
-BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
+BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
{
- if (!receive_smb_raw(fd, buffer, timeout)) {
- return False;
- }
-
- /* Check the incoming SMB signature. */
- if (!srv_check_sign_mac(buffer, True)) {
- DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n"));
- if (smb_read_error == 0)
- smb_read_error = READ_BAD_SIG;
- return False;
- };
-
- return(True);
+ BOOL ret;
+
+ for(;;)
+ {
+ ret = receive_smb(fd, buffer, timeout);
+
+ if (!ret)
+ {
+ DEBUG(10,("client_receive_smb failed\n"));
+ show_msg(buffer);
+ return ret;
+ }
+
+ /* Ignore session keepalive packets. */
+ if(CVAL(buffer,0) != 0x85)
+ break;
+ }
+ show_msg(buffer);
+ return ret;
}
/****************************************************************************
- Send an smb to a fd.
+ send an smb to a fd
****************************************************************************/
BOOL send_smb(int fd,char *buffer)
@@ -617,10 +699,6 @@ BOOL send_smb(int fd,char *buffer)
size_t len;
size_t nwritten=0;
ssize_t ret;
-
- /* Sign the outgoing packet if required. */
- srv_calculate_sign_mac(buffer);
-
len = smb_len(buffer) + 4;
while (nwritten < len) {
@@ -637,6 +715,45 @@ BOOL send_smb(int fd,char *buffer)
}
/****************************************************************************
+send a single packet to a port on another machine
+****************************************************************************/
+
+BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
+{
+ BOOL ret;
+ int out_fd;
+ struct sockaddr_in sock_out;
+
+ /* create a socket to write to */
+ out_fd = socket(AF_INET, type, 0);
+ if (out_fd == -1)
+ {
+ DEBUG(0,("socket failed"));
+ return False;
+ }
+
+ /* set the address and port */
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
+ putip((char *)&sock_out.sin_addr,(char *)&ip);
+ sock_out.sin_port = htons( port );
+ sock_out.sin_family = AF_INET;
+
+ if (DEBUGLEVEL > 0)
+ DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
+ len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
+
+ /* send it */
+ ret = (sys_sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
+
+ if (!ret)
+ DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
+ inet_ntoa(ip),port,strerror(errno)));
+
+ close(out_fd);
+ return(ret);
+}
+
+/****************************************************************************
Open a socket of the specified type, port, and address for incoming data.
****************************************************************************/
@@ -688,7 +805,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
/* now we've got a socket - we need to bind it */
if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
- if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) {
+ if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
dbgtext( "bind failed on port %d ", port );
dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
dbgtext( "Error = %s\n", strerror(errno) );
@@ -697,120 +814,78 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
return( -1 );
}
- DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
+ DEBUG( 3, ( "bind succeeded on port %d\n", port ) );
return( res );
}
/****************************************************************************
- Create an outgoing socket. timeout is in milliseconds.
-**************************************************************************/
+ create an outgoing socket. timeout is in milliseconds.
+ **************************************************************************/
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
- struct sockaddr_in sock_out;
- int res,ret;
- int connect_loop = 10;
- int increment = 10;
-
- /* create a socket to write to */
- res = socket(PF_INET, type, 0);
- if (res == -1) {
- DEBUG(0,("socket error (%s)\n", strerror(errno)));
- return -1;
- }
+ struct sockaddr_in sock_out;
+ int res,ret;
+ int connect_loop = 250; /* 250 milliseconds */
+ int loops = (timeout) / connect_loop;
+
+ /* create a socket to write to */
+ res = socket(PF_INET, type, 0);
+ if (res == -1)
+ { DEBUG(0,("socket error\n")); return -1; }
- if (type != SOCK_STREAM)
- return(res);
+ if (type != SOCK_STREAM) return(res);
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
+ putip((char *)&sock_out.sin_addr,(char *)addr);
- sock_out.sin_port = htons( port );
- sock_out.sin_family = PF_INET;
+ sock_out.sin_port = htons( port );
+ sock_out.sin_family = PF_INET;
- /* set it non-blocking */
- set_blocking(res,False);
+ /* set it non-blocking */
+ set_blocking(res,False);
- DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
+ DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
- /* and connect it to the destination */
- connect_again:
-
- ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
-
- /* Some systems return EAGAIN when they mean EINPROGRESS */
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && (connect_loop < timeout) ) {
- smb_msleep(connect_loop);
- connect_loop += increment;
- if (increment < 250) {
- /* After 8 rounds we end up at a max of 255 msec */
- increment *= 1.5;
- }
- goto connect_again;
- }
-
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
- close(res);
- return -1;
- }
+ /* and connect it to the destination */
+connect_again:
+ ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+
+ /* Some systems return EAGAIN when they mean EINPROGRESS */
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN) && loops--) {
+ msleep(connect_loop);
+ goto connect_again;
+ }
+
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN)) {
+ DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
+ close(res);
+ return -1;
+ }
#ifdef EISCONN
-
- if (ret < 0 && errno == EISCONN) {
- errno = 0;
- ret = 0;
- }
+ if (ret < 0 && errno == EISCONN) {
+ errno = 0;
+ ret = 0;
+ }
#endif
- if (ret < 0) {
- DEBUG(2,("error connecting to %s:%d (%s)\n",
- inet_ntoa(*addr),port,strerror(errno)));
- close(res);
- return -1;
- }
-
- /* set it blocking again */
- set_blocking(res,True);
-
- return res;
-}
-
-/****************************************************************************
- Open a connected UDP socket to host on port
-**************************************************************************/
-
-int open_udp_socket(const char *host, int port)
-{
- int type = SOCK_DGRAM;
- struct sockaddr_in sock_out;
- int res;
- struct in_addr *addr;
-
- addr = interpret_addr2(host);
-
- res = socket(PF_INET, type, 0);
- if (res == -1) {
- return -1;
- }
+ if (ret < 0) {
+ DEBUG(2,("error connecting to %s:%d (%s)\n",
+ inet_ntoa(*addr),port,strerror(errno)));
+ close(res);
+ return -1;
+ }
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
- sock_out.sin_port = htons(port);
- sock_out.sin_family = PF_INET;
+ /* set it blocking again */
+ set_blocking(res,True);
- if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
- close(res);
- return -1;
- }
-
- return res;
+ return res;
}
-
/* the following 3 client_*() functions are nasty ways of allowing
some generic functions to get info that really should be hidden in
particular modules */
@@ -823,37 +898,18 @@ void client_setfd(int fd)
char *client_name(void)
{
- return get_peer_name(client_fd,False);
+ return get_socket_name(client_fd);
}
char *client_addr(void)
{
- return get_peer_addr(client_fd);
-}
-
-char *client_socket_addr(void)
-{
return get_socket_addr(client_fd);
}
-struct in_addr *client_inaddr(struct sockaddr *sa)
-{
- struct sockaddr_in *sockin = (struct sockaddr_in *) (sa);
- socklen_t length = sizeof(*sa);
-
- if (getpeername(client_fd, sa, &length) < 0) {
- DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
- return NULL;
- }
-
- return &sockin->sin_addr;
-}
-
/*******************************************************************
- Matchname - determine if host name matches IP address. Used to
- confirm a hostname lookup to prevent spoof attacks.
-******************************************************************/
-
+ matchname - determine if host name matches IP address. Used to
+ confirm a hostname lookup to prevent spoof attacks
+ ******************************************************************/
static BOOL matchname(char *remotehost,struct in_addr addr)
{
struct hostent *hp;
@@ -872,8 +928,8 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
* DNS is perverted). We always check the address list, though.
*/
- if (!strequal(remotehost, hp->h_name)
- && !strequal(remotehost, "localhost")) {
+ if (strcasecmp(remotehost, hp->h_name)
+ && strcasecmp(remotehost, "localhost")) {
DEBUG(0,("host name/name mismatch: %s != %s\n",
remotehost, hp->h_name));
return False;
@@ -881,7 +937,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
/* Look up the host address in the address list we just got. */
for (i = 0; hp->h_addr_list[i]; i++) {
- if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0)
+ if (memcmp(hp->h_addr_list[i], (void *) & addr, sizeof(addr)) == 0)
return True;
}
@@ -896,36 +952,25 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
return False;
}
+
/*******************************************************************
- Return the DNS name of the remote end of a socket.
-******************************************************************/
-
-char *get_peer_name(int fd, BOOL force_lookup)
+ return the DNS name of the remote end of a socket
+ ******************************************************************/
+char *get_socket_name(int fd)
{
static pstring name_buf;
- pstring tmp_name;
static fstring addr_buf;
struct hostent *hp;
struct in_addr addr;
char *p;
-
- /* reverse lookups can be *very* expensive, and in many
- situations won't work because many networks don't link dhcp
- with dns. To avoid the delay we avoid the lookup if
- possible */
- if (!lp_hostname_lookups() && (force_lookup == False)) {
- return get_peer_addr(fd);
- }
- p = get_peer_addr(fd);
+ p = get_socket_addr(fd);
/* it might be the same as the last one - save some DNS work */
- if (strcmp(p, addr_buf) == 0)
- return name_buf;
+ if (strcmp(p, addr_buf) == 0) return name_buf;
pstrcpy(name_buf,"UNKNOWN");
- if (fd == -1)
- return name_buf;
+ if (fd == -1) return name_buf;
fstrcpy(addr_buf, p);
@@ -943,12 +988,7 @@ char *get_peer_name(int fd, BOOL force_lookup)
}
}
- /* can't pass the same source and dest strings in when you
- use --enable-developer or the clobber_region() call will
- get you */
-
- pstrcpy( tmp_name, name_buf );
- alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
+ alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf));
if (strstr(name_buf,"..")) {
pstrcpy(name_buf, "UNKNOWN");
}
@@ -957,10 +997,9 @@ char *get_peer_name(int fd, BOOL force_lookup)
}
/*******************************************************************
- Return the IP addr of the remote end of a socket as a string.
+ return the IP addr of the remote end of a socket as a string
******************************************************************/
-
-char *get_peer_addr(int fd)
+char *get_socket_addr(int fd)
{
struct sockaddr sa;
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
@@ -1044,7 +1083,7 @@ int create_pipe_sock(const char *socket_dir,
goto out_umask;
}
- pstr_sprintf(path, "%s/%s", socket_dir, socket_name);
+ snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
unlink(path);
memset(&sunaddr, 0, sizeof(sunaddr));
@@ -1078,3 +1117,96 @@ out_umask:
return -1;
#endif /* HAVE_UNIXSOCKET */
}
+
+/*******************************************************************
+this is like socketpair but uses tcp. It is used by the Samba
+regression test code
+The function guarantees that nobody else can attach to the socket,
+or if they do that this function fails and the socket gets closed
+returns 0 on success, -1 on failure
+the resulting file descriptors are symmetrical
+ ******************************************************************/
+static int socketpair_tcp(int fd[2])
+{
+ int listener;
+ struct sockaddr_in sock;
+ struct sockaddr_in sock2;
+ socklen_t socklen = sizeof(sock);
+ int connect_done = 0;
+
+ fd[0] = fd[1] = listener = -1;
+
+ memset(&sock, 0, sizeof(sock));
+
+ if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
+
+ memset(&sock2, 0, sizeof(sock2));
+#ifdef HAVE_SOCK_SIN_LEN
+ sock2.sin_len = sizeof(sock2);
+#endif
+ sock2.sin_family = PF_INET;
+
+ bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
+
+ if (listen(listener, 1) != 0) goto failed;
+
+ if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
+
+ if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
+
+ set_blocking(fd[1], 0);
+
+ sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
+ if (errno != EINPROGRESS) goto failed;
+ } else {
+ connect_done = 1;
+ }
+
+ if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
+
+ close(listener);
+ if (connect_done == 0) {
+ if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
+ && errno != EISCONN) goto failed;
+ }
+
+ set_blocking(fd[1], 1);
+
+ /* all OK! */
+ return 0;
+
+ failed:
+ if (fd[0] != -1) close(fd[0]);
+ if (fd[1] != -1) close(fd[1]);
+ if (listener != -1) close(listener);
+ return -1;
+}
+
+
+/*******************************************************************
+run a program on a local tcp socket, this is used to launch smbd
+when regression testing
+the return value is a socket which is attached to a subprocess
+running "prog". stdin and stdout are attached. stderr is left
+attached to the original stderr
+ ******************************************************************/
+int sock_exec(const char *prog)
+{
+ int fd[2];
+ if (socketpair_tcp(fd) != 0) {
+ DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
+ return -1;
+ }
+ if (fork() == 0) {
+ close(fd[0]);
+ close(0);
+ close(1);
+ dup(fd[1]);
+ dup(fd[1]);
+ exit(system(prog));
+ }
+ close(fd[1]);
+ return fd[0];
+}
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 65ef306ed17..be1588d1e4b 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1,10 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
-
- Copyright (C) Andrew Tridgell 1992-2001
- Copyright (C) Simo Sorce 2001-2002
- Copyright (C) Martin Pool 2003
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,272 +21,307 @@
#include "includes.h"
-/**
- * @file
- * @brief String utilities.
- **/
-
-/**
- * Get the next token from a string, return False if none found.
- * Handles double-quotes.
- *
- * Based on a routine by GJC@VILLAGE.COM.
- * Extensively modified by Andrew.Tridgell@anu.edu.au
- **/
-BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
+static const char *last_ptr=NULL;
+
+void set_first_token(char *ptr)
{
- char *s;
- char *pbuf;
+ last_ptr = ptr;
+}
+
+/****************************************************************************
+ Get the next token from a string, return False if none found
+ handles double-quotes.
+Based on a routine by GJC@VILLAGE.COM.
+Extensively modified by Andrew.Tridgell@anu.edu.au
+****************************************************************************/
+
+BOOL next_token(const char **ptr,char *buff,const char *sep, size_t bufsize)
+{
+ const char *s;
BOOL quoted;
size_t len=1;
if (!ptr)
+ ptr = &last_ptr;
+ if (!ptr)
return(False);
- s = (char *)*ptr;
+ s = *ptr;
/* default to simple separators */
if (!sep)
sep = " \t\n\r";
/* find the first non sep char */
- while (*s && strchr_m(sep,*s))
+ while(*s && strchr(sep,*s))
s++;
-
+
/* nothing left? */
if (! *s)
return(False);
-
+
/* copy over the token */
- pbuf = buff;
- for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
- if (*s == '\"' || *s == '\'') {
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
+ if (*s == '\"') {
quoted = !quoted;
} else {
len++;
- *pbuf++ = *s;
+ *buff++ = *s;
}
}
-
+
*ptr = (*s) ? s+1 : s;
- *pbuf = 0;
-
+ *buff = 0;
+ last_ptr = *ptr;
+
return(True);
}
-/**
-This is like next_token but is not re-entrant and "remembers" the first
-parameter so you can pass NULL. This is useful for user interface code
-but beware the fact that it is not re-entrant!
-**/
-
-static const char *last_ptr=NULL;
-
-BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
+/****************************************************************************
+Convert list of tokens to array; dependent on above routine.
+Uses last_ptr from above - bit of a hack.
+****************************************************************************/
+char **toktocliplist(int *ctok, const char *sep)
{
- BOOL ret;
- if (!ptr)
- ptr = &last_ptr;
+ char *s= (char *)last_ptr;
+ int ictok=0;
+ char **ret, **iret;
- ret = next_token(ptr, buff, sep, bufsize);
- last_ptr = *ptr;
- return ret;
-}
+ if (!sep) sep = " \t\n\r";
-static uint16 tmpbuf[sizeof(pstring)];
+ while(*s && strchr(sep,*s)) s++;
-void set_first_token(char *ptr)
-{
- last_ptr = ptr;
-}
+ /* nothing left? */
+ if (!*s) return(NULL);
-/**
- Convert list of tokens to array; dependent on above routine.
- Uses last_ptr from above - bit of a hack.
-**/
+ do {
+ ictok++;
+ while(*s && (!strchr(sep,*s))) s++;
+ while(*s && strchr(sep,*s)) *s++=0;
+ } while(*s);
-char **toktocliplist(int *ctok, const char *sep)
-{
- char *s=(char *)last_ptr;
- int ictok=0;
- char **ret, **iret;
+ *ctok=ictok;
+ s=last_ptr;
- if (!sep)
- sep = " \t\n\r";
-
- while(*s && strchr_m(sep,*s))
- s++;
-
- /* nothing left? */
- if (!*s)
- return(NULL);
-
- do {
- ictok++;
- while(*s && (!strchr_m(sep,*s)))
- s++;
- while(*s && strchr_m(sep,*s))
- *s++=0;
- } while(*s);
-
- *ctok=ictok;
- s=(char *)last_ptr;
-
- if (!(ret=iret=malloc(ictok*sizeof(char *))))
- return NULL;
-
- while(ictok--) {
- *iret++=s;
- while(*s++)
- ;
- while(!*s)
- s++;
- }
+ if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
+
+ while(ictok--) {
+ *iret++=s;
+ while(*s++);
+ while(!*s) s++;
+ }
- return ret;
+ return ret;
}
-/**
- * Case insensitive string compararison.
- *
- * iconv does not directly give us a way to compare strings in
- * arbitrary unix character sets -- all we can is convert and then
- * compare. This is expensive.
- *
- * As an optimization, we do a first pass that considers only the
- * prefix of the strings that is entirely 7-bit. Within this, we
- * check whether they have the same value.
- *
- * Hopefully this will often give the answer without needing to copy.
- * In particular it should speed comparisons to literal ascii strings
- * or comparisons of strings that are "obviously" different.
- *
- * If we find a non-ascii character we fall back to converting via
- * iconv.
- *
- * This should never be slower than convering the whole thing, and
- * often faster.
- *
- * A different optimization would be to compare for bitwise equality
- * in the binary encoding. (It would be possible thought hairy to do
- * both simultaneously.) But in that case if they turn out to be
- * different, we'd need to restart the whole thing.
- *
- * Even better is to implement strcasecmp for each encoding and use a
- * function pointer.
- **/
+
+/*******************************************************************
+ case insensitive string compararison
+********************************************************************/
int StrCaseCmp(const char *s, const char *t)
{
+ /* compare until we run out of string, either t or s, or find a difference */
+ /* We *must* use toupper rather than tolower here due to the
+ asynchronous upper to lower mapping.
+ */
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ int diff;
+ for (;;)
+ {
+ if (!*s || !*t)
+ return toupper (*s) - toupper (*t);
+ else if (is_sj_alph (*s) && is_sj_alph (*t))
+ {
+ diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ }
+ else if (is_shift_jis (*s) && is_shift_jis (*t))
+ {
+ diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
+ if (diff)
+ return diff;
+ diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ }
+ else if (is_shift_jis (*s))
+ return 1;
+ else if (is_shift_jis (*t))
+ return -1;
+ else
+ {
+ diff = toupper (*s) - toupper (*t);
+ if (diff)
+ return diff;
+ s++;
+ t++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s && *t && toupper(*s) == toupper(*t))
+ {
+ s++;
+ t++;
+ }
- const char * ps, * pt;
- size_t size;
- smb_ucs2_t *buffer_s, *buffer_t;
- int ret;
-
- for (ps = s, pt = t; ; ps++, pt++) {
- char us, ut;
-
- if (!*ps && !*pt)
- return 0; /* both ended */
- else if (!*ps)
- return -1; /* s is a prefix */
- else if (!*pt)
- return +1; /* t is a prefix */
- else if ((*ps & 0x80) || (*pt & 0x80))
- /* not ascii anymore, do it the hard way from here on in */
- break;
-
- us = toupper(*ps);
- ut = toupper(*pt);
- if (us == ut)
- continue;
- else if (us < ut)
- return -1;
- else if (us > ut)
- return +1;
- }
-
- size = push_ucs2_allocate(&buffer_s, s);
- if (size == (size_t)-1) {
- return strcmp(s, t);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
- }
-
- size = push_ucs2_allocate(&buffer_t, t);
- if (size == (size_t)-1) {
- SAFE_FREE(buffer_s);
- return strcmp(s, t);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
- }
-
- ret = strcasecmp_w(buffer_s, buffer_t);
- SAFE_FREE(buffer_s);
- SAFE_FREE(buffer_t);
- return ret;
+ return(toupper(*s) - toupper(*t));
+ }
}
-
-/**
- Case insensitive string compararison, length limited.
-**/
+/*******************************************************************
+ case insensitive string compararison, length limited
+********************************************************************/
int StrnCaseCmp(const char *s, const char *t, size_t n)
{
- pstring buf1, buf2;
- unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
- unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
- return strncmp(buf1,buf2,n);
+ /* compare until we run out of string, either t or s, or chars */
+ /* We *must* use toupper rather than tolower here due to the
+ asynchronous upper to lower mapping.
+ */
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ int diff;
+ for (;n > 0;)
+ {
+ if (!*s || !*t)
+ return toupper (*s) - toupper (*t);
+ else if (is_sj_alph (*s) && is_sj_alph (*t))
+ {
+ diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ n -= 2;
+ }
+ else if (is_shift_jis (*s) && is_shift_jis (*t))
+ {
+ diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
+ if (diff)
+ return diff;
+ diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ n -= 2;
+ }
+ else if (is_shift_jis (*s))
+ return 1;
+ else if (is_shift_jis (*t))
+ return -1;
+ else
+ {
+ diff = toupper (*s) - toupper (*t);
+ if (diff)
+ return diff;
+ s++;
+ t++;
+ n--;
+ }
+ }
+ return 0;
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (n && *s && *t && toupper(*s) == toupper(*t))
+ {
+ s++;
+ t++;
+ n--;
+ }
+
+ /* not run out of chars - strings are different lengths */
+ if (n)
+ return(toupper(*s) - toupper(*t));
+
+ /* identical up to where we run out of chars,
+ and strings are same length */
+ return(0);
+ }
}
-/**
- * Compare 2 strings.
- *
- * @note The comparison is case-insensitive.
- **/
+/*******************************************************************
+ compare 2 strings - DOS codepage.
+********************************************************************/
BOOL strequal(const char *s1, const char *s2)
{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
+ if (s1 == s2) return(True);
+ if (!s1 || !s2) return(False);
- return(StrCaseCmp(s1,s2)==0);
+ return(StrCaseCmp(s1,s2)==0);
}
-/**
- * Compare 2 strings up to and including the nth char.
- *
- * @note The comparison is case-insensitive.
- **/
+/*******************************************************************
+ compare 2 strings - UNIX codepage.
+********************************************************************/
+BOOL strequal_unix(const char *s1, const char *s2)
+{
+ pstring dos_s1, dos_s2;
+ if (s1 == s2) return(True);
+ if (!s1 || !s2) return(False);
+
+ pstrcpy(dos_s1, unix_to_dos_static(s1));
+ pstrcpy(dos_s2, unix_to_dos_static(s2));
+ return(StrCaseCmp(dos_s1,dos_s2)==0);
+}
+
+/*******************************************************************
+ compare 2 strings up to and including the nth char.
+ ******************************************************************/
BOOL strnequal(const char *s1,const char *s2,size_t n)
{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2 || !n)
- return(False);
+ if (s1 == s2) return(True);
+ if (!s1 || !s2 || !n) return(False);
return(StrnCaseCmp(s1,s2,n)==0);
}
-/**
- Compare 2 strings (case sensitive).
-**/
-
+/*******************************************************************
+ compare 2 strings (case sensitive)
+********************************************************************/
BOOL strcsequal(const char *s1,const char *s2)
{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
+ if (s1 == s2) return(True);
+ if (!s1 || !s2) return(False);
return(strcmp(s1,s2)==0);
}
-/**
+/***************************************************************************
Do a case-insensitive, whitespace-ignoring string compare.
-**/
-
+***************************************************************************/
int strwicmp(const char *psz1, const char *psz2)
{
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
@@ -301,7 +334,8 @@ int strwicmp(const char *psz1, const char *psz2)
return (1);
/* sync the strings on first non-whitespace */
- while (1) {
+ while (1)
+ {
while (isspace((int)*psz1))
psz1++;
while (isspace((int)*psz2))
@@ -316,318 +350,588 @@ int strwicmp(const char *psz1, const char *psz2)
}
-/**
- Convert a string to upper case, but don't modify it.
-**/
+/*******************************************************************
+ convert a string to lower case
+********************************************************************/
+void strlower(char *s)
+{
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_upper (s[0], s[1]))
+ s[1] = sj_tolower2 (s[1]);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (isupper(*s))
+ *s = tolower(*s);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (isupper(*s))
+ *s = tolower(*s);
+ s++;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ convert a string to upper case
+********************************************************************/
+void strupper(char *s)
+{
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_lower (s[0], s[1]))
+ s[1] = sj_toupper2 (s[1]);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ }
+}
+
+/* Convert a string to upper case, but don't modify it */
char *strupper_static(const char *s)
{
static pstring str;
pstrcpy(str, s);
- strupper_m(str);
+ strupper(str);
return str;
}
-/**
- Convert a string to "normal" form.
-**/
-
-void strnorm(char *s, int case_default)
+/*******************************************************************
+ convert a string to "normal" form
+********************************************************************/
+void strnorm(char *s)
{
- if (case_default == CASE_UPPER)
- strupper_m(s);
- else
- strlower_m(s);
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ strupper(s);
+ else
+ strlower(s);
}
-/**
- Check if a string is in "normal" case.
-**/
-
-BOOL strisnormal(const char *s, int case_default)
+/*******************************************************************
+check if a string is in "normal" case
+********************************************************************/
+BOOL strisnormal(char *s)
{
- if (case_default == CASE_UPPER)
- return(!strhaslower(s));
-
- return(!strhasupper(s));
-}
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ return(!strhaslower(s));
+ return(!strhasupper(s));
+}
-/**
- String replace.
- NOTE: oldc and newc must be 7 bit characters
-**/
-void string_replace(pstring s,char oldc,char newc)
+/****************************************************************************
+ string replace
+****************************************************************************/
+void string_replace(char *s,char oldc,char newc)
{
- unsigned char *p;
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- for (p = (unsigned char *)s; *p; p++) {
- if (*p & 0x80) /* mb string - slow path. */
- break;
- if (*p == oldc)
- *p = newc;
- }
+ size_t skip;
- if (!*p)
- return;
-
- /* Slow (mb) path. */
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- /* With compose characters we must restart from the beginning. JRA. */
- p = s;
-#endif
- push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
- string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
- pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ while (*s) {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+ } else {
+ while (*s)
+ {
+ skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+ }
+ }
}
-/**
- Skip past some strings in a buffer.
-**/
+/*******************************************************************
+skip past some strings in a buffer
+********************************************************************/
char *skip_string(char *buf,size_t n)
{
- while (n--)
- buf += strlen(buf) + 1;
- return(buf);
+ while (n--)
+ buf += strlen(buf) + 1;
+ return(buf);
}
-/**
+/*******************************************************************
Count the number of characters in a string. Normally this will
be the same as the number of bytes in a string for single byte strings,
but will be different for multibyte.
-**/
+ 16.oct.98, jdblair@cobaltnet.com.
+********************************************************************/
size_t str_charnum(const char *s)
{
- uint16 tmpbuf2[sizeof(pstring)];
- push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
- return strlen_w(tmpbuf2);
-}
-
-/**
- Count the number of characters in a string. Normally this will
- be the same as the number of bytes in a string for single byte strings,
- but will be different for multibyte.
-**/
-
-size_t str_ascii_charnum(const char *s)
-{
- pstring tmpbuf2;
- push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
- return strlen(tmpbuf2);
-}
-
-BOOL trim_char(char *s,char cfront,char cback)
-{
- BOOL ret = False;
- char *ep;
- char *fp = s;
-
- /* Ignore null or empty strings. */
- if (!s || (s[0] == '\0'))
- return False;
-
- if (cfront) {
- while (*fp && *fp == cfront)
- fp++;
- if (!*fp) {
- /* We ate the string. */
- s[0] = '\0';
- return True;
- }
- if (fp != s)
- ret = True;
- }
-
- ep = fp + strlen(fp) - 1;
- if (cback) {
- /* Attempt ascii only. Bail for mb strings. */
- while ((ep >= fp) && (*ep == cback)) {
- ret = True;
- if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
- /* Could be mb... bail back to tim_string. */
- char fs[2], bs[2];
- if (cfront) {
- fs[0] = cfront;
- fs[1] = '\0';
- }
- bs[0] = cback;
- bs[1] = '\0';
- return trim_string(s, cfront ? fs : NULL, bs);
- } else {
- ep--;
- }
- }
- if (ep < fp) {
- /* We ate the string. */
- s[0] = '\0';
- return True;
- }
- }
-
- ep[1] = '\0';
- memmove(s, fp, ep-fp+2);
- return ret;
+ size_t len = 0;
+
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ return strlen(s);
+ } else {
+ while (*s != '\0') {
+ int skip = get_character_len(*s);
+ s += (skip ? skip : 1);
+ len++;
+ }
+ }
+ return len;
}
-/**
- Trim the specified elements off the front and back of a string.
-**/
+/*******************************************************************
+trim the specified elements off the front and back of a string
+********************************************************************/
BOOL trim_string(char *s,const char *front,const char *back)
{
- BOOL ret = False;
- size_t front_len;
- size_t back_len;
- size_t len;
+ BOOL ret = False;
+ size_t s_len;
+ size_t front_len;
+ size_t back_len;
+ char *sP;
/* Ignore null or empty strings. */
- if (!s || (s[0] == '\0'))
- return False;
- front_len = front? strlen(front) : 0;
- back_len = back? strlen(back) : 0;
+ if ( !s || (s[0] == '\0'))
+ return False;
+
+ sP = s;
+ s_len = strlen( s ) + 1;
+ front_len = (front) ? strlen( front ) + 1 : 0;
+ back_len = (back) ? strlen( back ) + 1 : 0;
+
+ /*
+ * remove "front" string from given "s", if it matches front part,
+ * repeatedly.
+ */
+ if ( front && front_len > 1 ) {
+ while (( s_len >= front_len )&&
+ ( memcmp( sP, front, front_len - 1 )) == 0 ) {
+ ret = True;
+ sP += ( front_len - 1 );
+ s_len -= ( front_len - 1 );
+ }
+ }
- len = strlen(s);
+ /*
+ * we'll memmove sP to s later, after we're done with
+ * back part removal, for minimizing copy.
+ */
+
+
+ /*
+ * We split out the multibyte code page
+ * case here for speed purposes. Under a
+ * multibyte code page we need to walk the
+ * string forwards only and multiple times.
+ * Thanks to John Blair for finding this
+ * one. JRA.
+ */
+ /*
+ * This JRA's comment is partly correct, but partly wrong.
+ * You can always check from "end" part, and if it did not match,
+ * it means there is no possibility of finding one.
+ * If you found matching point, mark them, then look from front
+ * if marking point suits multi-byte string rule.
+ * Kenichi Okuyama.
+ */
+
+ if ( back && back_len > 1 && s_len >= back_len) {
+ char *bP = sP + s_len - back_len;
+ long b_len = s_len;
+
+ while (( b_len >= back_len )&&
+ ( memcmp( bP, back, back_len - 1 ) == 0 )) {
+ bP -= ( back_len - 1 );
+ b_len -= ( back_len - 1 );
+ }
+
+ /*
+ * You're here, means you ether have found match multiple times,
+ * or you found none. If you've found match, then bP should be
+ * moving.
+ */
+ if ( bP != sP + s_len - back_len ) {
+ bP += ( back_len - 1 ); /* slide bP to first matching point. */
+
+ if( !global_is_multibyte_codepage ) {
+ /* simply terminate */
+ (*bP) = '\0';
+ s_len = b_len;
+ ret = True;
+ } else {
+ /* trace string from start. */
+ char *cP = sP;
+ while ( cP < sP + s_len - back_len ) {
+ size_t skip;
+ skip = skip_multibyte_char( *cP );
+ cP += ( skip ? skip : 1 );
+ if ( cP == bP ) {
+ /* you found the match */
+ (*bP) = '\0';
+ ret = True;
+ s_len = b_len;
+ break;
+ }
+ while (( cP > bP )&&( bP < sP + s_len - back_len )) {
+ bP += ( back_len - 1 );
+ b_len += ( back_len - 1 );
+ }
+ }
+ }
+ }
+ }
- if (front_len) {
- while (len && strncmp(s, front, front_len)==0) {
- /* Must use memmove here as src & dest can
- * easily overlap. Found by valgrind. JRA. */
- memmove(s, s+front_len, (len-front_len)+1);
- len -= front_len;
- ret=True;
- }
- }
-
- if (back_len) {
- while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
- s[len-back_len]='\0';
- len -= back_len;
- ret=True;
- }
- }
- return ret;
+ /* if front found matching point */
+ if ( sP != s ) {
+ /* slide string to buffer top */
+ memmove( s, sP, s_len );
+ }
+ return ret;
}
-/**
- Does a string have any uppercase chars in it?
-**/
+/****************************************************************************
+does a string have any uppercase chars in it?
+****************************************************************************/
BOOL strhasupper(const char *s)
{
- smb_ucs2_t *ptr;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++)
- if(isupper_w(*ptr))
- return True;
- return(False);
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ s += 2;
+ else if (is_kana (*s))
+ s++;
+ else
+ {
+ if (isupper(*s))
+ return(True);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (isupper(*s))
+ return(True);
+ s++;
+ }
+ }
+ }
+ return(False);
}
-/**
- Does a string have any lowercase chars in it?
-**/
-
+/****************************************************************************
+does a string have any lowercase chars in it?
+****************************************************************************/
BOOL strhaslower(const char *s)
{
- smb_ucs2_t *ptr;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++)
- if(islower_w(*ptr))
- return True;
- return(False);
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_upper (s[0], s[1]))
+ return(True);
+ if (is_sj_lower (s[0], s[1]))
+ return (True);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (islower(*s))
+ return(True);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (islower(*s))
+ return(True);
+ s++;
+ }
+ }
+ }
+ return(False);
}
-/**
- Find the number of 'c' chars in a string
-**/
-
+/****************************************************************************
+find the number of chars in a string
+****************************************************************************/
size_t count_chars(const char *s,char c)
{
- smb_ucs2_t *ptr;
- int count;
- smb_ucs2_t *alloc_tmpbuf = NULL;
-
- if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
- return 0;
- }
-
- for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
- if(*ptr==UCS2_CHAR(c))
- count++;
-
- SAFE_FREE(alloc_tmpbuf);
- return(count);
+ size_t count=0;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ }
+ }
+ return(count);
+}
+
+/*******************************************************************
+Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all(const char *s,char c)
+{
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ return True;
}
-/**
- Safe string copy into a known length string. maxlength does not
- include the terminating zero.
-**/
+/*******************************************************************
+safe string copy into a known length string. maxlength does not
+include the terminating zero.
+********************************************************************/
-char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
+char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
size_t len;
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
return NULL;
}
-#ifdef DEVELOPER
- clobber_region(fn,line,dest, maxlength+1);
-#endif
-
if (!src) {
*dest = 0;
return dest;
}
- len = strnlen(src, maxlength+1);
+ len = strlen(src);
if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
- (unsigned long)(len-maxlength), (unsigned long)len,
- (unsigned long)maxlength, src));
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int)(len-maxlength), src));
len = maxlength;
}
- memmove(dest, src, len);
+ memcpy(dest, src, len);
dest[len] = 0;
return dest;
}
-/**
- Safe string cat into a string. maxlength does not
- include the terminating zero.
-**/
-char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
+/*******************************************************************
+safe string cat into a string. maxlength does not
+include the terminating zero.
+********************************************************************/
+
+char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
size_t src_len, dest_len;
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
+ DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
return NULL;
}
if (!src)
return dest;
- src_len = strnlen(src, maxlength + 1);
- dest_len = strnlen(dest, maxlength + 1);
-
-#ifdef DEVELOPER
- clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
-#endif
+ src_len = strlen(src);
+ dest_len = strlen(dest);
if (src_len + dest_len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
@@ -638,28 +942,27 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size
dest[maxlength] = 0;
return NULL;
}
-
+
memcpy(&dest[dest_len], src, src_len);
dest[dest_len + src_len] = 0;
return dest;
}
-/**
+/*******************************************************************
Paranoid strcpy into a buffer of given length (includes terminating
zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
and replaces with '_'. Deliberately does *NOT* check for multibyte
characters. Don't change it !
-**/
-char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
+********************************************************************/
+
+char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
{
size_t len, i;
-
-#ifdef DEVELOPER
- clobber_region(fn, line, dest, maxlength);
-#endif
+ size_t buflen;
+ smb_ucs2_t *str_ucs, *other_ucs;
if (!dest) {
- DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
return NULL;
}
@@ -668,73 +971,78 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
return dest;
}
- len = strlen(src);
- if (len >= maxlength)
- len = maxlength - 1;
+ /* Get UCS2 version of src string*/
+
+ buflen=2*strlen(src)+2;
+ if (buflen >= (2*maxlength))
+ buflen = 2*(maxlength - 1);
+
+ str_ucs = (smb_ucs2_t*)malloc(buflen);
+ if(!str_ucs) {
+ *dest=0;
+ return dest;
+ }
+ unix_to_unicode(str_ucs, src, buflen);
+ len = strlen_w(str_ucs);
if (!other_safe_chars)
other_safe_chars = "";
+ /* Get UCS2 version of other_safe_chars string*/
+ buflen=2*strlen(other_safe_chars)+2;
+ other_ucs = (smb_ucs2_t*)malloc(buflen);
+ if(!other_ucs) {
+ *dest=0;
+ SAFE_FREE(str_ucs);
+ return dest;
+ }
+ unix_to_unicode(other_ucs, other_safe_chars, buflen);
+
for(i = 0; i < len; i++) {
- int val = (src[i] & 0xff);
- if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
- dest[i] = src[i];
+ if(isupper_w(str_ucs[i]) || islower_w(str_ucs[i]) || isdigit_w(str_ucs[i]) || strchr_w(other_ucs, str_ucs[i]))
+ ;
else
- dest[i] = '_';
+ str_ucs[i] = (smb_ucs2_t)'_'; /*This will work*/
+
}
+ unicode_to_unix(dest, str_ucs, maxlength);
- dest[i] = '\0';
+ SAFE_FREE(other_ucs);
+ SAFE_FREE(str_ucs);
return dest;
}
-/**
+/****************************************************************************
Like strncpy but always null terminates. Make sure there is room!
The variable n should always be one less than the available size.
-**/
-char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
-{
- char *d = dest;
+****************************************************************************/
-#ifdef DEVELOPER
- clobber_region(fn, line, dest, n+1);
-#endif
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
- return(NULL);
- }
-
- if (!src) {
- *dest = 0;
- return(dest);
- }
-
- while (n-- && (*d = *src)) {
- d++;
- src++;
- }
-
- *d = 0;
- return(dest);
+char *StrnCpy(char *dest,const char *src,size_t n)
+{
+ char *d = dest;
+ if (!dest) return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+ while (n-- && (*d++ = *src++)) ;
+ *d = 0;
+ return(dest);
}
-#if 0
-/**
- Like strncpy but copies up to the character marker. always null terminates.
- returns a pointer to the character marker in the source string (src).
-**/
-
-static char *strncpyn(char *dest, const char *src, size_t n, char c)
+/****************************************************************************
+like strncpy but copies up to the character marker. always null terminates.
+returns a pointer to the character marker in the source string (src).
+****************************************************************************/
+char *strncpyn(char *dest, const char *src,size_t n, char c)
{
char *p;
size_t str_len;
-#ifdef DEVELOPER
- clobber_region(dest, n+1);
-#endif
- p = strchr_m(src, c);
- if (p == NULL) {
+ p = strchr(src, c);
+ if (p == NULL)
+ {
DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
return NULL;
}
@@ -745,9 +1053,9 @@ static char *strncpyn(char *dest, const char *src, size_t n, char c)
return p;
}
-#endif
-/**
+
+/*************************************************************
Routine to get hex characters and turn them into a 16 byte array.
the array can be variable length, and any non-hex-numeric
characters are skipped. "0xnn" or "0Xnn" is specially catered
@@ -755,29 +1063,34 @@ static char *strncpyn(char *dest, const char *src, size_t n, char c)
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
-**/
-
+**************************************************************/
size_t strhex_to_str(char *p, size_t len, const char *strhex)
{
size_t i;
size_t num_chars = 0;
unsigned char lonybble, hinybble;
- const char *hexchars = "0123456789ABCDEF";
+ const char *hexchars = "0123456789ABCDEF";
char *p1 = NULL, *p2 = NULL;
- for (i = 0; i < len && strhex[i] != 0; i++) {
- if (strnequal(hexchars, "0x", 2)) {
+ for (i = 0; i < len && strhex[i] != 0; i++)
+ {
+ if (strnequal(hexchars, "0x", 2))
+ {
i++; /* skip two chars */
continue;
}
- if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
+ if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
+ {
break;
+ }
i++; /* next hex digit */
- if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
+ if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
+ {
break;
+ }
/* get the two nybbles */
hinybble = PTR_DIFF(p1, hexchars);
@@ -792,143 +1105,116 @@ size_t strhex_to_str(char *p, size_t len, const char *strhex)
return num_chars;
}
-DATA_BLOB strhex_to_data_blob(const char *strhex)
-{
- DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
-
- ret_blob.length = strhex_to_str(ret_blob.data,
- strlen(strhex),
- strhex);
-
- return ret_blob;
-}
-
-/**
- * Routine to print a buffer as HEX digits, into an allocated string.
- */
-
-void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
-{
- int i;
- char *hex_buffer;
-
- *out_hex_buffer = smb_xmalloc((len*2)+1);
- hex_buffer = *out_hex_buffer;
-
- for (i = 0; i < len; i++)
- slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
-}
-
-/**
- Check if a string is part of a list.
-**/
-
+/****************************************************************************
+check if a string is part of a list
+****************************************************************************/
BOOL in_list(char *s,char *list,BOOL casesensitive)
{
- pstring tok;
- const char *p=list;
+ pstring tok;
+ const char *p=list;
- if (!list)
- return(False);
+ if (!list) return(False);
- while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
- if (casesensitive) {
- if (strcmp(tok,s) == 0)
- return(True);
- } else {
- if (StrCaseCmp(tok,s) == 0)
- return(True);
- }
- }
- return(False);
+ while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
+ if (casesensitive) {
+ if (strcmp(tok,s) == 0)
+ return(True);
+ } else {
+ if (StrCaseCmp(tok,s) == 0)
+ return(True);
+ }
+ }
+ return(False);
}
/* this is used to prevent lots of mallocs of size 1 */
static char *null_string = NULL;
-/**
- Set a string value, allocing the space for the string
-**/
-
+/****************************************************************************
+set a string value, allocing the space for the string
+****************************************************************************/
static BOOL string_init(char **dest,const char *src)
{
- size_t l;
- if (!src)
- src = "";
-
- l = strlen(src);
-
- if (l == 0) {
- if (!null_string) {
- if((null_string = (char *)malloc(1)) == NULL) {
- DEBUG(0,("string_init: malloc fail for null_string.\n"));
- return False;
- }
- *null_string = 0;
- }
- *dest = null_string;
- } else {
- (*dest) = strdup(src);
- if ((*dest) == NULL) {
- DEBUG(0,("Out of memory in string_init\n"));
- return False;
- }
- }
- return(True);
+ size_t l;
+ if (!src)
+ src = "";
+
+ l = strlen(src);
+
+ if (l == 0)
+ {
+ if (!null_string) {
+ if((null_string = (char *)malloc(1)) == NULL) {
+ DEBUG(0,("string_init: malloc fail for null_string.\n"));
+ return False;
+ }
+ *null_string = 0;
+ }
+ *dest = null_string;
+ }
+ else
+ {
+ (*dest) = (char *)malloc(l+1);
+ if ((*dest) == NULL) {
+ DEBUG(0,("Out of memory in string_init\n"));
+ return False;
+ }
+
+ pstrcpy(*dest,src);
+ }
+ return(True);
}
-/**
- Free a string value.
-**/
-
+/****************************************************************************
+free a string value
+****************************************************************************/
void string_free(char **s)
{
- if (!s || !(*s))
- return;
- if (*s == null_string)
- *s = NULL;
- SAFE_FREE(*s);
+ if (!s || !(*s)) return;
+ if (*s == null_string)
+ *s = NULL;
+ SAFE_FREE(*s);
}
-/**
- Set a string value, deallocating any existing space, and allocing the space
- for the string
-**/
-
+/****************************************************************************
+set a string value, allocing the space for the string, and deallocating any
+existing space
+****************************************************************************/
BOOL string_set(char **dest,const char *src)
{
- string_free(dest);
- return(string_init(dest,src));
+ string_free(dest);
+
+ return(string_init(dest,src));
}
-/**
- Substitute a string for a pattern in another string. Make sure there is
- enough room!
- This routine looks for pattern in s and replaces it with
- insert. It may do multiple replacements.
+/****************************************************************************
+substitute a string for a pattern in another string. Make sure there is
+enough room!
- Any of " ; ' $ or ` in the insert string are replaced with _
- if len==0 then the string cannot be extended. This is different from the old
- use of len==0 which was for no length checks to be done.
-**/
+This routine looks for pattern in s and replaces it with
+insert. It may do multiple replacements.
-void string_sub(char *s,const char *pattern, const char *insert, size_t len)
+any of " ; ' $ or ` in the insert string are replaced with _
+if len==0 then no expansion is permitted.
+****************************************************************************/
+void string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
char *p;
ssize_t ls,lp,li, i;
- if (!insert || !pattern || !*pattern || !s)
- return;
+ if (!insert || !pattern || !s) return;
ls = (ssize_t)strlen(s);
lp = (ssize_t)strlen(pattern);
li = (ssize_t)strlen(insert);
+ if (!*pattern) return;
+
if (len == 0)
len = ls + 1; /* len is number of *bytes* */
-
- while (lp <= ls && (p = strstr_m(s,pattern))) {
+
+ while (lp <= ls && (p = strstr(s,pattern))) {
if (ls + (li-lp) >= len) {
DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
(int)(ls + (li-lp) - len),
@@ -969,99 +1255,28 @@ void pstring_sub(char *s,const char *pattern,const char *insert)
string_sub(s, pattern, insert, sizeof(pstring));
}
-/**
- Similar to string_sub, but it will accept only allocated strings
- and may realloc them so pay attention at what you pass on no
- pointers inside strings, no pstrings or const may be passed
- as string.
-**/
-
-char *realloc_string_sub(char *string, const char *pattern, const char *insert)
-{
- char *p, *in;
- char *s;
- ssize_t ls,lp,li,ld, i;
-
- if (!insert || !pattern || !*pattern || !string || !*string)
- return NULL;
-
- s = string;
-
- in = strdup(insert);
- if (!in) {
- DEBUG(0, ("realloc_string_sub: out of memory!\n"));
- return NULL;
- }
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
- ld = li - lp;
- for (i=0;i<li;i++) {
- switch (in[i]) {
- case '`':
- case '"':
- case '\'':
- case ';':
- case '$':
- case '%':
- case '\r':
- case '\n':
- in[i] = '_';
- default:
- /* ok */
- break;
- }
- }
-
- while ((p = strstr_m(s,pattern))) {
- if (ld > 0) {
- int offset = PTR_DIFF(s,string);
- char *t = Realloc(string, ls + ld + 1);
- if (!t) {
- DEBUG(0, ("realloc_string_sub: out of memory!\n"));
- SAFE_FREE(in);
- return NULL;
- }
- string = t;
- p = t + offset + (p - s);
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
- memcpy(p, in, li);
- s = p + li;
- ls += ld;
- }
- SAFE_FREE(in);
- return string;
-}
-
-/**
- Similar to string_sub() but allows for any character to be substituted.
- Use with caution!
- if len==0 then the string cannot be extended. This is different from the old
- use of len==0 which was for no length checks to be done.
-**/
-
+/****************************************************************************
+similar to string_sub() but allows for any character to be substituted.
+Use with caution!
+if len==0 then no expansion is permitted.
+****************************************************************************/
void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
char *p;
ssize_t ls,lp,li;
- if (!insert || !pattern || !s)
- return;
+ if (!insert || !pattern || !s) return;
ls = (ssize_t)strlen(s);
lp = (ssize_t)strlen(pattern);
li = (ssize_t)strlen(insert);
- if (!*pattern)
- return;
+ if (!*pattern) return;
if (len == 0)
len = ls + 1; /* len is number of *bytes* */
- while (lp <= ls && (p = strstr_m(s,pattern))) {
+ while (lp <= ls && (p = strstr(s,pattern))) {
if (ls + (li-lp) >= len) {
DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
(int)(ls + (li-lp) - len),
@@ -1077,389 +1292,76 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
}
}
-/**
- Similar to all_string_sub but for unicode strings.
- Return a new allocated unicode string.
- similar to string_sub() but allows for any character to be substituted.
- Use with caution!
-**/
-
-static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
- const smb_ucs2_t *insert)
-{
- smb_ucs2_t *r, *rp;
- const smb_ucs2_t *sp;
- size_t lr, lp, li, lt;
-
- if (!insert || !pattern || !*pattern || !s)
- return NULL;
-
- lt = (size_t)strlen_w(s);
- lp = (size_t)strlen_w(pattern);
- li = (size_t)strlen_w(insert);
-
- if (li > lp) {
- const smb_ucs2_t *st = s;
- int ld = li - lp;
- while ((sp = strstr_w(st, pattern))) {
- st = sp + lp;
- lt += ld;
- }
- }
-
- r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
- if (!r) {
- DEBUG(0, ("all_string_sub_w: out of memory!\n"));
- return NULL;
- }
-
- while ((sp = strstr_w(s, pattern))) {
- memcpy(rp, s, (sp - s));
- rp += ((sp - s) / sizeof(smb_ucs2_t));
- memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
- s = sp + lp;
- rp += li;
- }
- lr = ((rp - r) / sizeof(smb_ucs2_t));
- if (lr < lt) {
- memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
- rp += (lt - lr);
- }
- *rp = 0;
-
- return r;
-}
-
-smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
- const char *insert)
+/****************************************************************************
+ splits out the front and back at a separator.
+****************************************************************************/
+void split_at_last_component(char *path, char *front, char sep, char *back)
{
- wpstring p, i;
-
- if (!insert || !pattern || !s)
- return NULL;
- push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
- push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
- return all_string_sub_w(s, p, i);
-}
-
-#if 0
-/**
- Splits out the front and back at a separator.
-**/
-
-static void split_at_last_component(char *path, char *front, char sep, char *back)
-{
- char *p = strrchr_m(path, sep);
+ char *p = strrchr(path, sep);
if (p != NULL)
+ {
*p = 0;
-
+ }
if (front != NULL)
+ {
pstrcpy(front, path);
-
- if (p != NULL) {
+ }
+ if (p != NULL)
+ {
if (back != NULL)
+ {
pstrcpy(back, p+1);
+ }
*p = '\\';
- } else {
+ }
+ else
+ {
if (back != NULL)
+ {
back[0] = 0;
+ }
}
}
-#endif
-/**
- Write an octal as a string.
-**/
+/****************************************************************************
+write an octal as a string
+****************************************************************************/
const char *octal_string(int i)
{
static char ret[64];
- if (i == -1)
+ if (i == -1) {
return "-1";
+ }
slprintf(ret, sizeof(ret)-1, "0%o", i);
return ret;
}
-/**
- Truncate a string at a specified length.
-**/
-
-char *string_truncate(char *s, unsigned int length)
+/****************************************************************************
+truncate a string at a specified length
+****************************************************************************/
+char *string_truncate(char *s, int length)
{
- if (s && strlen(s) > length)
+ if (s && strlen(s) > length) {
s[length] = 0;
- return s;
-}
-
-/**
- Strchr and strrchr_m are very hard to do on general multi-byte strings.
- We convert via ucs2 for now.
-**/
-
-char *strchr_m(const char *src, char c)
-{
- wpstring ws;
- pstring s2;
- smb_ucs2_t *p;
- const char *s;
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
- if (*s == c)
- return (char *)s;
- }
-
- if (!*s)
- return NULL;
-
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
- /* With compose characters we must restart from the beginning. JRA. */
- s = src;
-#endif
-
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
- p = strchr_w(ws, UCS2_CHAR(c));
- if (!p)
- return NULL;
- *p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
-}
-
-char *strrchr_m(const char *s, char c)
-{
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars). Also, in Samba
- we only search for ascii characters in 'c' and that
- in all mb character sets with a compound character
- containing c, if 'c' is not a match at position
- p, then p[-1] > 0x7f. JRA. */
-
- {
- size_t len = strlen(s);
- const char *cp = s;
- BOOL got_mb = False;
-
- if (len == 0)
- return NULL;
- cp += (len - 1);
- do {
- if (c == *cp) {
- /* Could be a match. Part of a multibyte ? */
- if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
- /* Yep - go slow :-( */
- got_mb = True;
- break;
- }
- /* No - we have a match ! */
- return (char *)cp;
- }
- } while (cp-- != s);
- if (!got_mb)
- return NULL;
- }
-
- /* String contained a non-ascii char. Slow path. */
- {
- wpstring ws;
- pstring s2;
- smb_ucs2_t *p;
-
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
- p = strrchr_w(ws, UCS2_CHAR(c));
- if (!p)
- return NULL;
- *p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
- }
-}
-
-/***********************************************************************
- Return the equivalent of doing strrchr 'n' times - always going
- backwards.
-***********************************************************************/
-
-char *strnrchr_m(const char *s, char c, unsigned int n)
-{
- wpstring ws;
- pstring s2;
- smb_ucs2_t *p;
-
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
- p = strnrchr_w(ws, UCS2_CHAR(c), n);
- if (!p)
- return NULL;
- *p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
-}
-
-/***********************************************************************
- strstr_m - We convert via ucs2 for now.
-***********************************************************************/
-
-char *strstr_m(const char *src, const char *findstr)
-{
- smb_ucs2_t *p;
- smb_ucs2_t *src_w, *find_w;
- const char *s;
- char *s2;
- char *retp;
-
- size_t findstr_len = 0;
-
- /* for correctness */
- if (!findstr[0]) {
- return src;
- }
-
- /* Samba does single character findstr calls a *lot*. */
- if (findstr[1] == '\0')
- return strchr_m(src, *findstr);
-
- /* We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
- if (*s == *findstr) {
- if (!findstr_len)
- findstr_len = strlen(findstr);
-
- if (strncmp(s, findstr, findstr_len) == 0) {
- return (char *)s;
- }
- }
- }
-
- if (!*s)
- return NULL;
-
-#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
- /* 'make check' fails unless we do this */
-
- /* With compose characters we must restart from the beginning. JRA. */
- s = src;
-#endif
-
- if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
- DEBUG(0,("strstr_m: src malloc fail\n"));
- return NULL;
- }
-
- if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
- SAFE_FREE(src_w);
- DEBUG(0,("strstr_m: find malloc fail\n"));
- return NULL;
- }
-
- p = strstr_w(src_w, find_w);
-
- if (!p) {
- SAFE_FREE(src_w);
- SAFE_FREE(find_w);
- return NULL;
}
-
- *p = 0;
- if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
- SAFE_FREE(src_w);
- SAFE_FREE(find_w);
- DEBUG(0,("strstr_m: dest malloc fail\n"));
- return NULL;
- }
- retp = (char *)(s+strlen(s2));
- SAFE_FREE(src_w);
- SAFE_FREE(find_w);
- SAFE_FREE(s2);
- return retp;
-}
-
-/**
- Convert a string to lower case.
-**/
-
-void strlower_m(char *s)
-{
- size_t len;
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- while (*s && !(((unsigned char)s[0]) & 0x80)) {
- *s = tolower((unsigned char)*s);
- s++;
- }
-
- if (!*s)
- return;
-
- /* I assume that lowercased string takes the same number of bytes
- * as source string even in UTF-8 encoding. (VIV) */
- len = strlen(s) + 1;
- errno = 0;
- unix_strlower(s,len,s,len);
- /* Catch mb conversion errors that may not terminate. */
- if (errno)
- s[len-1] = '\0';
-}
-
-/**
- Convert a string to upper case.
-**/
-
-void strupper_m(char *s)
-{
- size_t len;
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- while (*s && !(((unsigned char)s[0]) & 0x80)) {
- *s = toupper((unsigned char)*s);
- s++;
- }
-
- if (!*s)
- return;
-
- /* I assume that lowercased string takes the same number of bytes
- * as source string even in multibyte encoding. (VIV) */
- len = strlen(s) + 1;
- errno = 0;
- unix_strupper(s,len,s,len);
- /* Catch mb conversion errors that may not terminate. */
- if (errno)
- s[len-1] = '\0';
+ return s;
}
-/**
- Return a RFC2254 binary string representation of a buffer.
- Used in LDAP filters.
- Caller must free.
-**/
-
+/*
+ return a RFC2254 binary string representation of a buffer
+ used in LDAP filters
+ caller must free
+*/
char *binary_string(char *buf, int len)
{
char *s;
int i, j;
const char *hex = "0123456789ABCDEF";
s = malloc(len * 3 + 1);
- if (!s)
- return NULL;
+ if (!s) return NULL;
for (j=i=0;i<len;i++) {
s[j] = '\\';
s[j+1] = hex[((unsigned char)buf[i]) >> 4];
@@ -1470,47 +1372,29 @@ char *binary_string(char *buf, int len)
return s;
}
-/**
- Just a typesafety wrapper for snprintf into a pstring.
-**/
-
- int pstr_sprintf(pstring s, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-
-/**
- Just a typesafety wrapper for snprintf into a fstring.
-**/
+#ifndef HAVE_STRNLEN
+/*******************************************************************
+ Some platforms don't have strnlen
+********************************************************************/
-int fstr_sprintf(fstring s, const char *fmt, ...)
+ size_t strnlen(const char *s, size_t n)
{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
- va_end(ap);
- return ret;
+ int i;
+ for (i=0; s[i] && i<n; i++)
+ /* noop */ ;
+ return i;
}
-
+#endif
#ifndef HAVE_STRNDUP
-/**
+/*******************************************************************
Some platforms don't have strndup.
-**/
+********************************************************************/
char *strndup(const char *s, size_t n)
{
char *ret;
-
+
n = strnlen(s, n);
ret = malloc(n+1);
if (!ret)
@@ -1521,536 +1405,3 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
return ret;
}
#endif
-
-#ifndef HAVE_STRNLEN
-/**
- Some platforms don't have strnlen
-**/
-
- size_t strnlen(const char *s, size_t n)
-{
- int i;
- for (i=0; s[i] && i<n; i++)
- /* noop */ ;
- return i;
-}
-#endif
-
-/**
- List of Strings manipulation functions
-**/
-
-#define S_LIST_ABS 16 /* List Allocation Block Size */
-
-char **str_list_make(const char *string, const char *sep)
-{
- char **list, **rlist;
- const char *str;
- char *s;
- int num, lsize;
- pstring tok;
-
- if (!string || !*string)
- return NULL;
- s = strdup(string);
- if (!s) {
- DEBUG(0,("str_list_make: Unable to allocate memory"));
- return NULL;
- }
- if (!sep) sep = LIST_SEP;
-
- num = lsize = 0;
- list = NULL;
-
- str = s;
- while (next_token(&str, tok, sep, sizeof(tok))) {
- if (num == lsize) {
- lsize += S_LIST_ABS;
- rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
- if (!rlist) {
- DEBUG(0,("str_list_make: Unable to allocate memory"));
- str_list_free(&list);
- SAFE_FREE(s);
- return NULL;
- } else
- list = rlist;
- memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
- }
-
- list[num] = strdup(tok);
- if (!list[num]) {
- DEBUG(0,("str_list_make: Unable to allocate memory"));
- str_list_free(&list);
- SAFE_FREE(s);
- return NULL;
- }
-
- num++;
- }
-
- SAFE_FREE(s);
- return list;
-}
-
-BOOL str_list_copy(char ***dest, const char **src)
-{
- char **list, **rlist;
- int num, lsize;
-
- *dest = NULL;
- if (!src)
- return False;
-
- num = lsize = 0;
- list = NULL;
-
- while (src[num]) {
- if (num == lsize) {
- lsize += S_LIST_ABS;
- rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
- if (!rlist) {
- DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
- str_list_free(&list);
- return False;
- } else
- list = rlist;
- memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
- }
-
- list[num] = strdup(src[num]);
- if (!list[num]) {
- DEBUG(0,("str_list_copy: Unable to allocate memory"));
- str_list_free(&list);
- return False;
- }
-
- num++;
- }
-
- *dest = list;
- return True;
-}
-
-/**
- * Return true if all the elements of the list match exactly.
- **/
-BOOL str_list_compare(char **list1, char **list2)
-{
- int num;
-
- if (!list1 || !list2)
- return (list1 == list2);
-
- for (num = 0; list1[num]; num++) {
- if (!list2[num])
- return False;
- if (!strcsequal(list1[num], list2[num]))
- return False;
- }
- if (list2[num])
- return False; /* if list2 has more elements than list1 fail */
-
- return True;
-}
-
-void str_list_free(char ***list)
-{
- char **tlist;
-
- if (!list || !*list)
- return;
- tlist = *list;
- for(; *tlist; tlist++)
- SAFE_FREE(*tlist);
- SAFE_FREE(*list);
-}
-
-/******************************************************************************
- version of standard_sub_basic() for string lists; uses alloc_sub_basic()
- for the work
- *****************************************************************************/
-
-BOOL str_list_sub_basic( char **list, const char *smb_name )
-{
- char *s, *tmpstr;
-
- while ( *list ) {
- s = *list;
- tmpstr = alloc_sub_basic(smb_name, s);
- if ( !tmpstr ) {
- DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
- return False;
- }
-
- *list = tmpstr;
-
- list++;
- }
-
- return True;
-}
-
-/******************************************************************************
- substritute a specific pattern in a string list
- *****************************************************************************/
-
-BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
-{
- char *p, *s, *t;
- ssize_t ls, lp, li, ld, i, d;
-
- if (!list)
- return False;
- if (!pattern)
- return False;
- if (!insert)
- return False;
-
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
- ld = li -lp;
-
- while (*list) {
- s = *list;
- ls = (ssize_t)strlen(s);
-
- while ((p = strstr_m(s, pattern))) {
- t = *list;
- d = p -t;
- if (ld) {
- t = (char *) malloc(ls +ld +1);
- if (!t) {
- DEBUG(0,("str_list_substitute: Unable to allocate memory"));
- return False;
- }
- memcpy(t, *list, d);
- memcpy(t +d +li, p +lp, ls -d -lp +1);
- SAFE_FREE(*list);
- *list = t;
- ls += ld;
- s = t +d +li;
- }
-
- for (i = 0; i < li; i++) {
- switch (insert[i]) {
- case '`':
- case '"':
- case '\'':
- case ';':
- case '$':
- case '%':
- case '\r':
- case '\n':
- t[d +i] = '_';
- break;
- default:
- t[d +i] = insert[i];
- }
- }
- }
-
-
- list++;
- }
-
- return True;
-}
-
-
-#define IPSTR_LIST_SEP ","
-#define IPSTR_LIST_CHAR ','
-
-/**
- * Add ip string representation to ipstr list. Used also
- * as part of @function ipstr_list_make
- *
- * @param ipstr_list pointer to string containing ip list;
- * MUST BE already allocated and IS reallocated if necessary
- * @param ipstr_size pointer to current size of ipstr_list (might be changed
- * as a result of reallocation)
- * @param ip IP address which is to be added to list
- * @return pointer to string appended with new ip and possibly
- * reallocated to new length
- **/
-
-char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
-{
- char* new_ipstr = NULL;
-
- /* arguments checking */
- if (!ipstr_list || !service) return NULL;
-
- /* attempt to convert ip to a string and append colon separator to it */
- if (*ipstr_list) {
- asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
- inet_ntoa(service->ip), service->port);
- SAFE_FREE(*ipstr_list);
- } else {
- asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
- }
- *ipstr_list = new_ipstr;
- return *ipstr_list;
-}
-
-
-/**
- * Allocate and initialise an ipstr list using ip adresses
- * passed as arguments.
- *
- * @param ipstr_list pointer to string meant to be allocated and set
- * @param ip_list array of ip addresses to place in the list
- * @param ip_count number of addresses stored in ip_list
- * @return pointer to allocated ip string
- **/
-
-char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
-{
- int i;
-
- /* arguments checking */
- if (!ip_list && !ipstr_list) return 0;
-
- *ipstr_list = NULL;
-
- /* process ip addresses given as arguments */
- for (i = 0; i < ip_count; i++)
- *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
-
- return (*ipstr_list);
-}
-
-
-/**
- * Parse given ip string list into array of ip addresses
- * (as ip_service structures)
- * e.g. 192.168.1.100:389,192.168.1.78, ...
- *
- * @param ipstr ip string list to be parsed
- * @param ip_list pointer to array of ip addresses which is
- * allocated by this function and must be freed by caller
- * @return number of succesfully parsed addresses
- **/
-
-int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
-{
- fstring token_str;
- size_t count;
- int i;
-
- if (!ipstr_list || !ip_list)
- return 0;
-
- count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
- if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
- DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
- return 0;
- }
-
- for ( i=0;
- next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
- i++ )
- {
- struct in_addr addr;
- unsigned port = 0;
- char *p = strchr(token_str, ':');
-
- if (p) {
- *p = 0;
- port = atoi(p+1);
- }
-
- /* convert single token to ip address */
- if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
- break;
-
- (*ip_list)[i].ip = addr;
- (*ip_list)[i].port = port;
- }
-
- return count;
-}
-
-
-/**
- * Safely free ip string list
- *
- * @param ipstr_list ip string list to be freed
- **/
-
-void ipstr_list_free(char* ipstr_list)
-{
- SAFE_FREE(ipstr_list);
-}
-
-
-/**
- Unescape a URL encoded string, in place.
-**/
-
-void rfc1738_unescape(char *buf)
-{
- char *p=buf;
-
- while (p && *p && (p=strchr_m(p,'%'))) {
- int c1 = p[1];
- int c2 = p[2];
-
- if (c1 >= '0' && c1 <= '9')
- c1 = c1 - '0';
- else if (c1 >= 'A' && c1 <= 'F')
- c1 = 10 + c1 - 'A';
- else if (c1 >= 'a' && c1 <= 'f')
- c1 = 10 + c1 - 'a';
- else {p++; continue;}
-
- if (c2 >= '0' && c2 <= '9')
- c2 = c2 - '0';
- else if (c2 >= 'A' && c2 <= 'F')
- c2 = 10 + c2 - 'A';
- else if (c2 >= 'a' && c2 <= 'f')
- c2 = 10 + c2 - 'a';
- else {p++; continue;}
-
- *p = (c1<<4) | c2;
-
- memmove(p+1, p+3, strlen(p+3)+1);
- p++;
- }
-}
-
-static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-/**
- * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
- **/
-DATA_BLOB base64_decode_data_blob(const char *s)
-{
- int bit_offset, byte_offset, idx, i, n;
- DATA_BLOB decoded = data_blob(s, strlen(s)+1);
- unsigned char *d = decoded.data;
- char *p;
-
- n=i=0;
-
- while (*s && (p=strchr_m(b64,*s))) {
- idx = (int)(p - b64);
- byte_offset = (i*6)/8;
- bit_offset = (i*6)%8;
- d[byte_offset] &= ~((1<<(8-bit_offset))-1);
- if (bit_offset < 3) {
- d[byte_offset] |= (idx << (2-bit_offset));
- n = byte_offset+1;
- } else {
- d[byte_offset] |= (idx >> (bit_offset-2));
- d[byte_offset+1] = 0;
- d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
- n = byte_offset+2;
- }
- s++; i++;
- }
-
- if (*s == '=') n -= 1;
-
- /* fix up length */
- decoded.length = n;
- return decoded;
-}
-
-/**
- * Decode a base64 string in-place - wrapper for the above
- **/
-void base64_decode_inplace(char *s)
-{
- DATA_BLOB decoded = base64_decode_data_blob(s);
- memcpy(s, decoded.data, decoded.length);
- /* null terminate */
- s[decoded.length] = '\0';
-
- data_blob_free(&decoded);
-}
-
-/**
- * Encode a base64 string into a malloc()ed string caller to free.
- *
- *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
- **/
-char * base64_encode_data_blob(DATA_BLOB data)
-{
- int bits = 0;
- int char_count = 0;
- size_t out_cnt = 0;
- size_t len = data.length;
- size_t output_len = data.length * 2;
- char *result = malloc(output_len); /* get us plenty of space */
-
- while (len-- && out_cnt < (data.length * 2) - 5) {
- int c = (unsigned char) *(data.data++);
- bits += c;
- char_count++;
- if (char_count == 3) {
- result[out_cnt++] = b64[bits >> 18];
- result[out_cnt++] = b64[(bits >> 12) & 0x3f];
- result[out_cnt++] = b64[(bits >> 6) & 0x3f];
- result[out_cnt++] = b64[bits & 0x3f];
- bits = 0;
- char_count = 0;
- } else {
- bits <<= 8;
- }
- }
- if (char_count != 0) {
- bits <<= 16 - (8 * char_count);
- result[out_cnt++] = b64[bits >> 18];
- result[out_cnt++] = b64[(bits >> 12) & 0x3f];
- if (char_count == 1) {
- result[out_cnt++] = '=';
- result[out_cnt++] = '=';
- } else {
- result[out_cnt++] = b64[(bits >> 6) & 0x3f];
- result[out_cnt++] = '=';
- }
- }
- result[out_cnt] = '\0'; /* terminate */
- return result;
-}
-
-/* read a SMB_BIG_UINT from a string */
-SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
-{
-
- SMB_BIG_UINT val = -1;
- const char *p = nptr;
-
- while (p && *p && isspace(*p))
- p++;
-#ifdef LARGE_SMB_OFF_T
- sscanf(p,"%llu",&val);
-#else /* LARGE_SMB_OFF_T */
- sscanf(p,"%lu",&val);
-#endif /* LARGE_SMB_OFF_T */
- if (entptr) {
- while (p && *p && isdigit(*p))
- p++;
- *entptr = p;
- }
-
- return val;
-}
-
-void string_append(char **left, const char *right)
-{
- int new_len = strlen(right) + 1;
-
- if (*left == NULL) {
- *left = malloc(new_len);
- *left[0] = '\0';
- } else {
- new_len += strlen(*left);
- *left = Realloc(*left, new_len);
- }
-
- if (*left == NULL)
- return;
-
- safe_strcat(*left, right, new_len-1);
-}
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index bfb5288826f..787fc417058 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-2001
- Copyright (C) Simo Sorce 2001
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,827 +21,2082 @@
#include "includes.h"
+ smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
+ (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
+ (smb_ucs2_t)'\r', 0 };
+/*
+ * The following are the codepage to ucs2 and vica versa maps.
+ * These are dynamically loaded from a unicode translation file.
+ */
+
+static smb_ucs2_t *doscp_to_ucs2;
+static uint16 *ucs2_to_doscp;
+
+static smb_ucs2_t *unixcp_to_ucs2;
+static uint16 *ucs2_to_unixcp;
+
#ifndef MAXUNI
#define MAXUNI 1024
#endif
-/* these 3 tables define the unicode case handling. They are loaded
- at startup either via mmap() or read() from the lib directory */
-static smb_ucs2_t *upcase_table;
-static smb_ucs2_t *lowcase_table;
-static uint8 *valid_table;
-
-/**
- * This table says which Unicode characters are valid dos
- * characters.
- *
- * Each value is just a single bit.
- **/
-static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */
-
-
-/**
- * Load or generate the case handling tables.
- *
- * The case tables are defined in UCS2 and don't depend on any
- * configured parameters, so they never need to be reloaded.
- **/
-void load_case_tables(void)
-{
- static int initialised;
- int i;
-
- if (initialised) return;
- initialised = 1;
-
- upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
- lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
-
- /* we would like Samba to limp along even if these tables are
- not available */
- if (!upcase_table) {
- DEBUG(1,("creating lame upcase table\n"));
- upcase_table = malloc(0x20000);
- for (i=0;i<0x10000;i++) {
- smb_ucs2_t v;
- SSVAL(&v, 0, i);
- upcase_table[v] = i;
- }
- for (i=0;i<256;i++) {
- smb_ucs2_t v;
- SSVAL(&v, 0, UCS2_CHAR(i));
- upcase_table[v] = UCS2_CHAR(islower(i)?toupper(i):i);
- }
+/*******************************************************************
+ Write a string in (little-endian) unicode format. src is in
+ the current UNIX character set. len is the length in bytes of the
+ string pointed to by dst.
+
+ if null_terminate is True then null terminate the packet (adds 2 bytes)
+
+ the return value is the length in bytes consumed by the string, including the
+ null termination if applied
+********************************************************************/
+
+size_t unix_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+{
+ size_t ret = 0;
+ while (*src && (len >= 2)) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,ret,unixcp_to_ucs2[val]);
+ ret += 2;
+ len -= 2;
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ if (null_terminate) {
+ SSVAL(dst,ret,0);
+ ret += 2;
}
+ return(ret);
+}
- if (!lowcase_table) {
- DEBUG(1,("creating lame lowcase table\n"));
- lowcase_table = malloc(0x20000);
- for (i=0;i<0x10000;i++) {
- smb_ucs2_t v;
- SSVAL(&v, 0, i);
- lowcase_table[v] = i;
- }
- for (i=0;i<256;i++) {
- smb_ucs2_t v;
- SSVAL(&v, 0, UCS2_CHAR(i));
- lowcase_table[v] = UCS2_CHAR(isupper(i)?tolower(i):i);
+/*******************************************************************
+ Write a string in (little-endian) unicode format. src is in
+ the current DOS codepage. len is the length in bytes of the
+ string pointed to by dst.
+
+ if null_terminate is True then null terminate the packet (adds 2 bytes)
+
+ the return value is the length in bytes consumed by the string, including the
+ null termination if applied
+********************************************************************/
+
+size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+{
+ size_t ret = 0;
+ while (*src && (len >= 2)) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,ret,doscp_to_ucs2[val]);
+ ret += 2;
+ len -= 2;
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ if (null_terminate) {
+ SSVAL(dst,ret,0);
+ ret += 2;
+ }
+ return(ret);
+}
+
+/*******************************************************************
+ Pull a DOS codepage string out of a UNICODE array. len is in bytes.
+********************************************************************/
+
+void unistr_to_dos(char *dest, const char *src, size_t len)
+{
+ char *destend = dest + len;
+
+ while (dest < destend) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ src += 2;
+
+ if (ucs2_val == 0)
+ break;
+
+ if (cp_val < 256)
+ *dest++ = (char)cp_val;
+ else {
+ *dest++ = (cp_val >> 8) & 0xff;
+ *dest++ = (cp_val & 0xff);
}
}
+
+ *dest = 0;
}
-/*
- see if a ucs2 character can be mapped correctly to a dos character
- and mapped back to the same character in ucs2
-*/
-int check_dos_char(smb_ucs2_t c)
+/*******************************************************************
+ Skip past a unicode string, but not more than len. Always move
+ past a terminating zero if found.
+********************************************************************/
+
+char *skip_unibuf(char *src, size_t len)
{
- lazy_initialize_conv();
-
- /* Find the right byte, and right bit within the byte; return
- * 1 or 0 */
- return (doschar_table[(c & 0xffff) / 8] & (1 << (c & 7))) != 0;
+ char *srcend = src + len;
+
+ while (src < srcend && SVAL(src,0))
+ src += 2;
+
+ if(!SVAL(src,0))
+ src += 2;
+
+ return src;
}
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ len is the filename length (ignoring any terminating zero) in uin16
+ units. Always null terminates.
+ Hack alert: uses fixed buffer(s).
+ len is in 2 byte (unicode) units.
+********************************************************************/
-static int check_dos_char_slowly(smb_ucs2_t c)
+char *dos_unistrn2(uint16 *src, int len)
{
- char buf[10];
- smb_ucs2_t c2 = 0;
- int len1, len2;
- len1 = convert_string(CH_UCS2, CH_DOS, &c, 2, buf, sizeof(buf),False);
- if (len1 == 0) return 0;
- len2 = convert_string(CH_DOS, CH_UCS2, buf, len1, &c2, 2,False);
- if (len2 != 2) return 0;
- return (c == c2);
+ static char lbufs[8][MAXUNI];
+ static int nexti;
+ char *lbuf = lbufs[nexti];
+ char *p;
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
}
+static char lbufs[8][MAXUNI];
+static int nexti;
-/**
- * Fill out doschar table the hard way, by examining each character
- **/
-void init_doschar_table(void)
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr2(uint16 *src)
{
- int i, j, byteval;
+ char *lbuf = lbufs[nexti];
+ char *p;
- /* For each byte of packed table */
-
- for (i = 0; i <= 0xffff; i += 8) {
- byteval = 0;
- for (j = 0; j <= 7; j++) {
- smb_ucs2_t c;
-
- c = i + j;
-
- if (check_dos_char_slowly(c))
- byteval |= 1 << j;
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; (p-lbuf < MAXUNI-3) && *src; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
}
- doschar_table[i/8] = byteval;
}
+
+ *p = 0;
+ return lbuf;
}
+/*******************************************************************
+Return a DOS codepage version of a little-endian unicode string
+********************************************************************/
-/**
- * Load the valid character map table from <tt>valid.dat</tt> or
- * create from the configured codepage.
- *
- * This function is called whenever the configuration is reloaded.
- * However, the valid character table is not changed if it's loaded
- * from a file, because we can't unmap files.
- **/
-void init_valid_table(void)
+char *dos_unistr2_to_str(UNISTR2 *str)
{
- static int mapped_file;
- int i;
- const char *allowed = ".!#$%&'()_-@^`~";
- uint8 *valid_file;
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
- if (mapped_file) {
- /* Can't unmap files, so stick with what we have */
- return;
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; (p - lbuf < MAXUNI-3) && (src - str->buffer < str->uni_str_len) && *src; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
}
- valid_file = map_file(lib_path("valid.dat"), 0x10000);
- if (valid_file) {
- valid_table = valid_file;
- mapped_file = 1;
- return;
+ *p = 0;
+ return lbuf;
+}
+
+/*******************************************************************
+ Put an ASCII string into a UNICODE array (uint16's).
+ use little-endian ucs2
+ ********************************************************************/
+void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
+{
+ uint16 *destend = dest + maxlen;
+ char c;
+
+ while (dest < destend) {
+ c = *(src++);
+ if (c == 0)
+ break;
+
+ SSVAL(dest, 0, c);
+ dest++;
}
- /* Otherwise, we're using a dynamically created valid_table.
- * It might need to be regenerated if the code page changed.
- * We know that we're not using a mapped file, so we can
- * free() the old one. */
- if (valid_table) free(valid_table);
+ *dest = 0;
+}
- DEBUG(2,("creating default valid table\n"));
- valid_table = malloc(0x10000);
- for (i=0;i<128;i++)
- valid_table[i] = isalnum(i) || strchr(allowed,i);
+/*******************************************************************
+ Pull an ASCII string out of a UNICODE array (uint16's).
+ ********************************************************************/
+
+void unistr_to_ascii(char *dest, const uint16 *src, int len)
+{
+ char *destend = dest + len;
+ uint16 c;
- for (;i<0x10000;i++) {
- smb_ucs2_t c;
- SSVAL(&c, 0, i);
- valid_table[i] = check_dos_char(c);
+ if (src == NULL) {
+ *dest = '\0';
+ return;
+ }
+
+ /* normal code path for a valid 'src' */
+ while (dest < destend) {
+ c = SVAL(src, 0);
+ src++;
+ if (c == 0)
+ break;
+
+ *(dest++) = (char)c;
}
+
+ *dest = 0;
+ return;
}
+/*******************************************************************
+ Convert a (little-endian) UNISTR2 structure to an ASCII string, either
+ DOS or UNIX codepage.
+********************************************************************/
+
+static void unistr2_to_mbcp(char *dest, const UNISTR2 *str, size_t maxlen, uint16 *ucs2_to_mbcp)
+{
+ char *p;
+ uint16 *src;
+ size_t len;
+
+ if (str == NULL) {
+ *dest='\0';
+ return;
+ }
+
+ src = str->buffer;
+ len = MIN(str->uni_str_len, maxlen);
+ if (len == 0) {
+ *dest='\0';
+ return;
+ }
+
+ for (p = dest; (p-dest < maxlen-3) && (src - str->buffer < str->uni_str_len) && *src; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_mbcp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+}
/*******************************************************************
- Write a string in (little-endian) unicode format. src is in
- the current DOS codepage. len is the length in bytes of the
- string pointed to by dst.
+ Convert a (little-endian) UNISTR2 structure to an ASCII string
+ Warning: this version does DOS codepage.
+********************************************************************/
- if null_terminate is True then null terminate the packet (adds 2 bytes)
+void unistr2_to_dos(char *dest, const UNISTR2 *str, size_t maxlen)
+{
+ unistr2_to_mbcp(dest, str, maxlen, ucs2_to_doscp);
+}
- the return value is the length in bytes consumed by the string, including the
- null termination if applied
+/*******************************************************************
+ Convert a (little-endian) UNISTR2 structure to an ASCII string
+ Warning: this version does UNIX codepage.
********************************************************************/
-size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+void unistr2_to_unix(char *dest, const UNISTR2 *str, size_t maxlen)
{
- return push_ucs2(NULL, dst, src, len,
- STR_UNICODE|STR_NOALIGN | (null_terminate?STR_TERMINATE:0));
+ unistr2_to_mbcp(dest, str, maxlen, ucs2_to_unixcp);
}
+/*******************************************************************
+Return a number stored in a buffer
+********************************************************************/
+
+uint32 buffer2_to_uint32(BUFFER2 *str)
+{
+ if (str->buf_len == 4)
+ return IVAL(str->buffer, 0);
+ else
+ return 0;
+}
/*******************************************************************
- Skip past a unicode string, but not more than len. Always move
- past a terminating zero if found.
+Return a DOS codepage version of a NOTunicode string
********************************************************************/
-char *skip_unibuf(char *src, size_t len)
+char *dos_buffer2_to_str(BUFFER2 *str)
{
- char *srcend = src + len;
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
- while (src < srcend && SVAL(src,0))
- src += 2;
+ nexti = (nexti+1)%8;
- if(!SVAL(src,0))
- src += 2;
+ for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2) && *src; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
- return src;
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
+ return lbuf;
}
-/* Copy a string from little-endian or big-endian unicode source (depending
- * on flags) to internal samba format destination
- */
-int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
+/*******************************************************************
+ Return a dos codepage version of a NOTunicode string
+********************************************************************/
+
+char *dos_buffer2_to_multistr(BUFFER2 *str)
{
- if (!src) {
- dest[0] = 0;
- return 0;
+ char *lbuf = lbufs[nexti];
+ char *p;
+ uint16 *src = str->buffer;
+
+ nexti = (nexti+1)%8;
+
+ for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2); src++) {
+ if (*src == 0) {
+ *p++ = ' ';
+ } else {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
}
- if(dest_len==-1) dest_len=MAXUNI-3;
- return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN);
+
+ *p = 0;
+ return lbuf;
}
-/* Copy a string from a unistr2 source to internal samba format
- destination. Use this instead of direct calls to rpcstr_pull() to avoid
- having to determine whether the source string is null terminated. */
+/*******************************************************************
+ Create a null-terminated unicode string from a null-terminated DOS
+ codepage string.
+ Return number of unicode chars copied, excluding the null character.
+ Unicode strings created are in little-endian format.
+ max_len is in bytes.
+********************************************************************/
-int rpcstr_pull_unistr2_fstring(char *dest, UNISTR2 *src)
+size_t dos_struni2(char *dst, const char *src, size_t max_len)
{
- return pull_ucs2(NULL, dest, src->buffer, sizeof(fstring),
- src->uni_str_len * 2, 0);
-}
+ size_t len = 0;
-/* Converts a string from internal samba format to unicode
- */
-int rpcstr_push(void* dest, const char *src, int dest_len, int flags)
-{
- return push_ucs2(NULL, dest, src, dest_len, flags|STR_UNICODE|STR_NOALIGN);
+ if (dst == NULL)
+ return 0;
+
+ if (src != NULL) {
+ for (; ((len*2) < max_len-2) && *src; len++, dst +=2) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,0,doscp_to_ucs2[val]);
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ }
+
+ SSVAL(dst,0,0);
+
+ return len;
}
/*******************************************************************
Return a DOS codepage version of a little-endian unicode string.
- len is the filename length (ignoring any terminating zero) in uin16
- units. Always null terminates.
Hack alert: uses fixed buffer(s).
********************************************************************/
-char *dos_unistrn2(const uint16 *src, int len)
+
+char *dos_unistr(char *buf)
{
- static char lbufs[8][MAXUNI];
- static int nexti;
char *lbuf = lbufs[nexti];
+ uint16 *src = (uint16 *)buf;
+ char *p;
+
nexti = (nexti+1)%8;
- pull_ucs2(NULL, lbuf, src, MAXUNI-3, len*2, STR_NOALIGN);
+
+ for (p = lbuf; (p-lbuf < MAXUNI-3) && *src; src++) {
+ uint16 ucs2_val = SVAL(src,0);
+ uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+ if (cp_val < 256)
+ *p++ = (char)cp_val;
+ else {
+ *p++ = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val & 0xff);
+ }
+ }
+
+ *p = 0;
return lbuf;
}
/*******************************************************************
- Convert a (little-endian) UNISTR2 structure to an ASCII string
+ returns the length in number of wide characters
+ ******************************************************************/
+int unistrlen(uint16 *s)
+{
+ int len;
+
+ if (!s)
+ return -1;
+
+ for (len=0; *s; s++,len++);
+
+ return len;
+}
+
+/*******************************************************************
+ Strcpy for unicode strings. returns length (in num of wide chars)
********************************************************************/
-void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
+
+int unistrcpy(uint16 *dst, uint16 *src)
{
- if (str == NULL) {
- *dest='\0';
- return;
+ int num_wchars = 0;
+
+ while (*src) {
+ *dst++ = *src++;
+ num_wchars++;
}
- pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
+ *dst = 0;
+
+ return num_wchars;
}
/*******************************************************************
-give a static string for displaying a UNISTR2
+ Free any existing maps.
********************************************************************/
-const char *unistr2_static(const UNISTR2 *str)
+
+static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
{
- static pstring ret;
- unistr2_to_ascii(ret, str, sizeof(ret));
- return ret;
+ /* this handles identity mappings where we share the pointer */
+ if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
+ *pp_ucs2_to_cp = NULL;
+ }
+
+ SAFE_FREE(*pp_cp_to_ucs2);
+ SAFE_FREE(*pp_ucs2_to_cp);
}
+/*******************************************************************
+ Build a default (null) codepage to unicode map.
+********************************************************************/
+
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+ int i;
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
+ DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
+ abort();
+ }
+
+ *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
+ for (i = 0; i < 65536; i++)
+ (*pp_cp_to_ucs2)[i] = i;
+}
/*******************************************************************
- duplicate a UNISTR2 string into a null terminated char*
- using a talloc context
+ Load a codepage to unicode and vica-versa map.
********************************************************************/
-char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
+
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
{
- char *s;
- int maxlen = (str->uni_str_len+1)*4;
- if (!str->buffer) return NULL;
- s = (char *)talloc(ctx, maxlen); /* convervative */
- if (!s) return NULL;
- pull_ucs2(NULL, s, str->buffer, maxlen, str->uni_str_len*2,
- STR_NOALIGN);
- return s;
+ pstring unicode_map_file_name;
+ FILE *fp = NULL;
+ SMB_STRUCT_STAT st;
+ smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
+ uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
+ size_t cp_to_ucs2_size;
+ size_t ucs2_to_cp_size;
+ size_t i;
+ size_t size;
+ char buf[UNICODE_MAP_HEADER_SIZE];
+
+ DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
+
+ if (*codepage == '\0')
+ goto clean_and_exit;
+
+ if(strlen(lp_codepagedir()) + 13 + strlen(codepage) >
+ sizeof(unicode_map_file_name)) {
+ DEBUG(0,("load_unicode_map: filename too long to load\n"));
+ goto clean_and_exit;
+ }
+
+ pstrcpy(unicode_map_file_name, lp_codepagedir());
+ pstrcat(unicode_map_file_name, "/");
+ pstrcat(unicode_map_file_name, "unicode_map.");
+ pstrcat(unicode_map_file_name, codepage);
+
+ if(sys_stat(unicode_map_file_name,&st)!=0) {
+ DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
+ unicode_map_file_name));
+ goto clean_and_exit;
+ }
+
+ size = st.st_size;
+
+ if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
+ DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
+unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
+ goto clean_and_exit;
+ }
+
+ if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
+ DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
+ DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /* Check the version value */
+ if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
+ DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
+Needed %hu, got %hu.\n",
+ unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
+ SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
+ goto clean_and_exit;
+ }
+
+ /* Check the codepage value */
+ if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
+ DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
+requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
+ goto clean_and_exit;
+ }
+
+ ucs2_to_cp_size = 2*65536;
+ if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
+ /*
+ * This is a multibyte code page.
+ */
+ cp_to_ucs2_size = 2*65536;
+ } else {
+ /*
+ * Single byte code page.
+ */
+ cp_to_ucs2_size = 2*256;
+ }
+
+ /*
+ * Free any old translation tables.
+ */
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
+ DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
+ goto clean_and_exit;
+ }
+
+ if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
+ DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
+ goto clean_and_exit;
+ }
+
+ if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
+ DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
+ DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
+ unicode_map_file_name, strerror(errno)));
+ goto clean_and_exit;
+ }
+
+ /*
+ * Now ensure the 16 bit values are in the correct endianness.
+ */
+
+ for (i = 0; i < cp_to_ucs2_size/2; i++)
+ cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
+
+ for (i = 0; i < ucs2_to_cp_size/2; i++)
+ ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
+
+ fclose(fp);
+
+ *pp_cp_to_ucs2 = cp_to_ucs2;
+ *pp_ucs2_to_cp = ucs2_to_cp;
+
+ return True;
+
+clean_and_exit:
+
+ /* pseudo destructor :-) */
+
+ if(fp != NULL)
+ fclose(fp);
+
+ free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+ return False;
}
+/*******************************************************************
+ Load a dos codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_dos_unicode_map(int codepage)
+{
+ fstring codepage_str;
+
+ slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
+ DEBUG(10,("load_dos_unicode_map: %s\n", codepage_str));
+ return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
+}
/*******************************************************************
-Return a number stored in a buffer
+ Load a UNIX codepage to unicode and vica-versa map.
********************************************************************/
-uint32 buffer2_to_uint32(BUFFER2 *str)
+BOOL load_unix_unicode_map(const char *unix_char_set, BOOL override)
{
- if (str->buf_len == 4)
- return IVAL(str->buffer, 0);
- else
- return 0;
+ static BOOL init_done;
+ fstring upper_unix_char_set;
+
+ fstrcpy(upper_unix_char_set, unix_char_set);
+ strupper(upper_unix_char_set);
+
+ DEBUG(10,("load_unix_unicode_map: %s (init_done=%d, override=%d)\n",
+ upper_unix_char_set, (int)init_done, (int)override ));
+
+ if (!init_done)
+ init_done = True;
+ else if (!override)
+ return True;
+
+ return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
}
/*******************************************************************
- Convert a wchar to upper case.
+ The following functions reproduce many of the non-UNICODE standard
+ string functions in Samba.
+********************************************************************/
+
+/*******************************************************************
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
********************************************************************/
-smb_ucs2_t toupper_w(smb_ucs2_t val)
+static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
+ size_t dst_len, const uint16 *ucs2_to_cp)
{
- return upcase_table[SVAL(&val,0)];
+ size_t dst_pos;
+
+ for(dst_pos = 0; (dst_pos < dst_len - 1) && *src;) {
+ smb_ucs2_t val = ucs2_to_cp[*src++];
+ if(val < 256) {
+ dst[dst_pos++] = (char)val;
+ } else {
+
+ if(dst_pos >= dst_len - 2)
+ break;
+
+ /*
+ * A 2 byte value is always written as
+ * high/low into the buffer stream.
+ */
+
+ dst[dst_pos++] = (char)((val >> 8) & 0xff);
+ dst[dst_pos++] = (char)(val & 0xff);
+ }
+ }
+
+ dst[dst_pos] = '\0';
+
+ return dst;
}
/*******************************************************************
- Convert a wchar to lower case.
+ Convert a multibyte string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
********************************************************************/
-smb_ucs2_t tolower_w( smb_ucs2_t val )
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+ size_t dst_len, smb_ucs2_t *cp_to_ucs2)
{
- return lowcase_table[SVAL(&val,0)];
+ size_t i;
+
+ dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
+
+ for(i = 0; (i < (dst_len - 1)) && *src;) {
+ size_t skip = skip_multibyte_char(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ dst[i++] = cp_to_ucs2[val];
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+
+ dst[i] = 0;
+ return dst;
}
/*******************************************************************
-determine if a character is lowercase
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the MB codepage format is an
+ encoded one (ie. utf8, hex). See the code in lib/kanji.c
+ for details. dst_len is in bytes.
********************************************************************/
-BOOL islower_w(smb_ucs2_t c)
+
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
{
- return upcase_table[SVAL(&c,0)] != c;
+ return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
}
/*******************************************************************
-determine if a character is uppercase
+ Convert a UNIX string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the UNIX codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
********************************************************************/
-BOOL isupper_w(smb_ucs2_t c)
+
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
+{
+ return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
+}
+
+/*******************************************************************
+ Convert a single UNICODE character to unix character. Returns the
+ number of bytes in the unix character.
+********************************************************************/
+
+size_t unicode_to_unix_char(char *dst, const smb_ucs2_t src)
+{
+ smb_ucs2_t val = ucs2_to_unixcp[src];
+ if(val < 256) {
+ *dst = (char)val;
+ return (size_t)1;
+ }
+ /*
+ * A 2 byte value is always written as
+ * high/low into the buffer stream.
+ */
+
+ dst[0] = (char)((val >> 8) & 0xff);
+ dst[1] = (char)(val & 0xff);
+ return (size_t)2;
+}
+
+/*******************************************************************
+ Convert a UNICODE string to DOS format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
{
- return lowcase_table[SVAL(&c,0)] != c;
+ return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
}
+/*******************************************************************
+ Convert a single UNICODE character to DOS codepage. Returns the
+ number of bytes in the DOS codepage character.
+********************************************************************/
+
+size_t unicode_to_dos_char(char *dst, const smb_ucs2_t src)
+{
+ smb_ucs2_t val = ucs2_to_doscp[src];
+ if(val < 256) {
+ *dst = (char)val;
+ return (size_t)1;
+ }
+ /*
+ * A 2 byte value is always written as
+ * high/low into the buffer stream.
+ */
+
+ dst[0] = (char)((val >> 8) & 0xff);
+ dst[1] = (char)(val & 0xff);
+ return (size_t)2;
+}
/*******************************************************************
-determine if a character is valid in a 8.3 name
+ Convert a DOS string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the DOS codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
********************************************************************/
-BOOL isvalid83_w(smb_ucs2_t c)
+
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
{
- return valid_table[SVAL(&c,0)] != 0;
+ return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
}
/*******************************************************************
Count the number of characters in a smb_ucs2_t string.
********************************************************************/
+
size_t strlen_w(const smb_ucs2_t *src)
{
- size_t len;
+ size_t len;
- for(len = 0; *src++; len++) ;
+ for(len = 0; *src++; len++)
+ ;
- return len;
+ return len;
}
/*******************************************************************
- Count up to max number of characters in a smb_ucs2_t string.
+ Safe wstring copy into a known length string. maxlength includes
+ the terminating zero. maxlength is in ucs2 units.
********************************************************************/
-size_t strnlen_w(const smb_ucs2_t *src, size_t max)
+
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
{
- size_t len;
+ size_t ucs2_len;
- for(len = 0; *src++ && (len < max); len++) ;
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
+ return NULL;
+ }
- return len;
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ maxlength /= sizeof(smb_ucs2_t);
+
+ ucs2_len = strlen_w(src);
+
+ if (ucs2_len >= maxlength) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
+ (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
+ unicode_to_unix(out,src,sizeof(out))) );
+ ucs2_len = maxlength - 1;
+ }
+
+ memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
+ dest[ucs2_len] = 0;
+ return dest;
}
/*******************************************************************
- Wide strchr().
+ Safe string cat into a string. maxlength includes the terminating zero.
+ maxlength is in ucs2 units.
********************************************************************/
-smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
{
- while (*s != 0) {
- if (c == *s) return (smb_ucs2_t *)s;
- s++;
- }
- if (c == *s) return (smb_ucs2_t *)s;
+ size_t ucs2_src_len, ucs2_dest_len;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
+ return NULL;
+ }
+
+ if (!src)
+ return dest;
+
+ ucs2_src_len = strlen_w(src);
+ ucs2_dest_len = strlen_w(dest);
+
+ if (ucs2_src_len + ucs2_dest_len >= maxlength) {
+ fstring out;
+ int new_len = maxlength - ucs2_dest_len - 1;
+ DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
+ (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
+ unicode_to_unix(out,src,sizeof(out))) );
+ ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
+ }
+
+ memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
+ dest[ucs2_dest_len + ucs2_src_len] = 0;
+ return dest;
+}
- return NULL;
+/*******************************************************************
+ Compare the two strings s1 and s2.
+********************************************************************/
+
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ smb_ucs2_t c1, c2;
+
+ for (;;) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 != c2)
+ return c1 - c2;
+
+ if (c1 == 0)
+ break;
+ }
+ return 0;
}
-smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
+/*******************************************************************
+ Compare the first n characters of s1 to s2. len is in ucs2 units.
+********************************************************************/
+
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
{
- return strchr_w(s, UCS2_CHAR(c));
+ smb_ucs2_t c1, c2;
+
+ for (; len != 0; --len) {
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 != c2)
+ return c1 - c2;
+
+ if (c1 == 0)
+ break;
+
+ }
+ return 0;
}
/*******************************************************************
- Wide strrchr().
+ Search string s2 from s1.
********************************************************************/
-smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+ size_t len = strlen_w(s2);
+
+ if (!*s2)
+ return (smb_ucs2_t *)s1;
+
+ for(;*s1; s1++) {
+ if (*s1 == *s2) {
+ if (strncmp_w(s1, s2, len) == 0)
+ return (smb_ucs2_t *)s1;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Search for ucs2 char c from the beginning of s.
+********************************************************************/
+
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
- const smb_ucs2_t *p = s;
- int len = strlen_w(s);
- if (len == 0) return NULL;
- p += (len - 1);
do {
- if (c == *p) return (smb_ucs2_t *)p;
- } while (p-- != s);
+ if (*s == c)
+ return (smb_ucs2_t *)s;
+ } while (*s++);
+
return NULL;
}
/*******************************************************************
- Wide version of strrchr that returns after doing strrchr 'n' times.
-********************************************************************/
+ Search for ucs2 char c from the end of s.
+********************************************************************/
-smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n)
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
- const smb_ucs2_t *p = s;
- int len = strlen_w(s);
- if (len == 0 || !n)
- return NULL;
- p += (len - 1);
+ smb_ucs2_t *retval = 0;
+
do {
- if (c == *p)
- n--;
+ if (*s == c)
+ retval = (smb_ucs2_t *)s;
+ } while (*s++);
- if (!n)
- return (smb_ucs2_t *)p;
- } while (p-- != s);
- return NULL;
+ return retval;
}
/*******************************************************************
- Wide strstr().
+ Search token from s1 separated by any ucs2 char of s2.
********************************************************************/
-smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins)
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
{
- smb_ucs2_t *r;
- size_t slen, inslen;
+ static smb_ucs2_t *s = NULL;
+ smb_ucs2_t *q;
+
+ if (!s1) {
+ if (!s)
+ return NULL;
+ s1 = s;
+ }
- if (!s || !*s || !ins || !*ins) return NULL;
- slen = strlen_w(s);
- inslen = strlen_w(ins);
- r = (smb_ucs2_t *)s;
- while ((r = strchr_w(r, *ins))) {
- if (strncmp_w(r, ins, inslen) == 0) return r;
- r++;
+ for (q = s1; *s1; s1++) {
+ smb_ucs2_t *p = strchr_w(s2, *s1);
+ if (p) {
+ if (s1 != q) {
+ s = s1 + 1;
+ *s1 = '\0';
+ return q;
+ }
+ q = s1 + 1;
+ }
}
+
+ s = NULL;
+ if (*q)
+ return q;
+
return NULL;
}
/*******************************************************************
- Convert a string to lower case.
- return True if any char is converted
+ Duplicate a ucs2 string.
********************************************************************/
-BOOL strlower_w(smb_ucs2_t *s)
+
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
{
- BOOL ret = False;
- while (*s) {
- smb_ucs2_t v = tolower_w(*s);
- if (v != *s) {
- *s = v;
- ret = True;
- }
- s++;
- }
- return ret;
+ size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
+ smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
+ if (newstr == NULL)
+ return NULL;
+ safe_strcpy_w(newstr, s, newlen);
+ return newstr;
}
/*******************************************************************
- Convert a string to upper case.
- return True if any char is converted
+ Mapping tables for UNICODE character. Allows toupper/tolower and
+ isXXX functions to work.
+
+ tridge: split into 2 pieces. This saves us 5/6 of the memory
+ with a small speed penalty
+ The magic constants are the lower/upper range of the tables two
+ parts
********************************************************************/
-BOOL strupper_w(smb_ucs2_t *s)
+
+typedef struct {
+ smb_ucs2_t lower;
+ smb_ucs2_t upper;
+ unsigned char flags;
+} smb_unicode_table_t;
+
+#define TABLE1_BOUNDARY 9450
+#define TABLE2_BOUNDARY 64256
+
+static smb_unicode_table_t map_table1[] = {
+#include "unicode_map_table1.h"
+};
+
+static smb_unicode_table_t map_table2[] = {
+#include "unicode_map_table2.h"
+};
+
+static unsigned char map_table_flags(smb_ucs2_t v)
{
- BOOL ret = False;
- while (*s) {
- smb_ucs2_t v = toupper_w(*s);
- if (v != *s) {
- *s = v;
- ret = True;
- }
- s++;
- }
- return ret;
+ if (v < TABLE1_BOUNDARY) return map_table1[v].flags;
+ if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags;
+ return 0;
+}
+
+static smb_ucs2_t map_table_lower(smb_ucs2_t v)
+{
+ if (v < TABLE1_BOUNDARY) return map_table1[v].lower;
+ if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower;
+ return v;
+}
+
+static smb_ucs2_t map_table_upper(smb_ucs2_t v)
+{
+ if (v < TABLE1_BOUNDARY) return map_table1[v].upper;
+ if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper;
+ return v;
}
/*******************************************************************
- convert a string to "normal" form
+ Is an upper case wchar.
********************************************************************/
-void strnorm_w(smb_ucs2_t *s, int case_default)
+int isupper_w( smb_ucs2_t val)
{
- if (case_default == CASE_UPPER)
- strupper_w(s);
- else
- strlower_w(s);
+ return (map_table_flags(val) & UNI_UPPER);
}
-int strcmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
+/*******************************************************************
+ Is a lower case wchar.
+********************************************************************/
+
+int islower_w( smb_ucs2_t val)
{
- while (*b && *a == *b) { a++; b++; }
- return (*a - *b);
- /* warning: if *a != *b and both are not 0 we retrun a random
- greater or lesser than 0 number not realted to which
- string is longer */
+ return (map_table_flags(val) & UNI_LOWER);
}
-int strncmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len)
+/*******************************************************************
+ Is a digit wchar.
+********************************************************************/
+
+int isdigit_w( smb_ucs2_t val)
{
- size_t n = 0;
- while ((n < len) && *b && *a == *b) { a++; b++; n++;}
- return (len - n)?(*a - *b):0;
+ return (map_table_flags(val) & UNI_DIGIT);
}
/*******************************************************************
-case insensitive string comparison
+ Is a hex digit wchar.
********************************************************************/
-int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
+
+int isxdigit_w( smb_ucs2_t val)
{
- while (*b && toupper_w(*a) == toupper_w(*b)) { a++; b++; }
- return (tolower_w(*a) - tolower_w(*b));
+ return (map_table_flags(val) & UNI_XDIGIT);
}
/*******************************************************************
-case insensitive string comparison, lenght limited
+ Is a space wchar.
********************************************************************/
-int strncasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len)
+
+int isspace_w( smb_ucs2_t val)
{
- size_t n = 0;
- while ((n < len) && *b && (toupper_w(*a) == toupper_w(*b))) { a++; b++; n++; }
- return (len - n)?(tolower_w(*a) - tolower_w(*b)):0;
+ return (map_table_flags(val) & UNI_SPACE);
}
/*******************************************************************
- compare 2 strings
+ Convert a wchar to upper case.
********************************************************************/
-BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+
+smb_ucs2_t toupper_w( smb_ucs2_t val )
{
- if (s1 == s2) return(True);
- if (!s1 || !s2) return(False);
-
- return(strcasecmp_w(s1,s2)==0);
+ return map_table_upper(val);
}
/*******************************************************************
- compare 2 strings up to and including the nth char.
- ******************************************************************/
-BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
+ Convert a wchar to lower case.
+********************************************************************/
+
+smb_ucs2_t tolower_w( smb_ucs2_t val )
{
- if (s1 == s2) return(True);
- if (!s1 || !s2 || !n) return(False);
+ return map_table_lower(val);
+}
+
+static smb_ucs2_t *last_ptr = NULL;
+
+void set_first_token_w(smb_ucs2_t *ptr)
+{
+ last_ptr = ptr;
+}
+
+/****************************************************************************
+ Get the next token from a string, return False if none found
+ handles double-quotes.
+ Based on a routine by GJC@VILLAGE.COM.
+ Extensively modified by Andrew.Tridgell@anu.edu.au
+ bufsize is in bytes.
+****************************************************************************/
+
+static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0};
+static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
+
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
+{
+ smb_ucs2_t *s;
+ BOOL quoted;
+ size_t len=1;
+
+ /*
+ * Convert bufsize to smb_ucs2_t units.
+ */
+
+ bufsize /= sizeof(smb_ucs2_t);
+
+ if (!ptr)
+ ptr = &last_ptr;
+ if (!ptr)
+ return(False);
+
+ s = *ptr;
+
+ /*
+ * Default to simple separators.
+ */
+
+ if (!sep)
+ sep = sep_list;
+
+ /*
+ * Find the first non sep char.
+ */
+
+ while(*s && strchr_w(sep,*s))
+ s++;
+
+ /*
+ * Nothing left ?
+ */
+
+ if (!*s)
+ return(False);
+
+ /*
+ * Copy over the token.
+ */
+
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
+ if (*s == quotechar) {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+ last_ptr = *ptr;
+
+ return(True);
+}
+
+/****************************************************************************
+ Convert list of tokens to array; dependent on above routine.
+ Uses last_ptr from above - bit of a hack.
+****************************************************************************/
+
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
+{
+ smb_ucs2_t *s=last_ptr;
+ int ictok=0;
+ smb_ucs2_t **ret, **iret;
+
+ if (!sep)
+ sep = sep_list;
+
+ while(*s && strchr_w(sep,*s))
+ s++;
+
+ /*
+ * Nothing left ?
+ */
+
+ if (!*s)
+ return(NULL);
+
+ do {
+ ictok++;
+ while(*s && (!strchr_w(sep,*s)))
+ s++;
+ while(*s && strchr_w(sep,*s))
+ *s++=0;
+ } while(*s);
+
+ *ctok = ictok;
+ s = last_ptr;
+
+ if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
+ return NULL;
- return(strncasecmp_w(s1,s2,n)==0);
+ while(ictok--) {
+ *iret++=s;
+ while(*s++)
+ ;
+ while(!*s)
+ s++;
+ }
+
+ return ret;
}
/*******************************************************************
-duplicate string
+ Case insensitive string compararison.
********************************************************************/
-smb_ucs2_t *strdup_w(const smb_ucs2_t *src)
+
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
{
- return strndup_w(src, 0);
+ /*
+ * Compare until we run out of string, either t or s, or find a difference.
+ */
+
+ while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
+ s++;
+ t++;
+ }
+
+ return(toupper_w(*s) - toupper_w(*t));
}
-/* if len == 0 then duplicate the whole string */
-smb_ucs2_t *strndup_w(const smb_ucs2_t *src, size_t len)
+/*******************************************************************
+ Case insensitive string compararison, length limited.
+ n is in ucs2 units.
+********************************************************************/
+
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
{
- smb_ucs2_t *dest;
-
- if (!len) len = strlen_w(src);
- dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t));
- if (!dest) {
- DEBUG(0,("strdup_w: out of memory!\n"));
- return NULL;
+ /*
+ * Compare until we run out of string, either t or s, or chars.
+ */
+
+ while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
+ s++;
+ t++;
+ n--;
}
- memcpy(dest, src, len * sizeof(smb_ucs2_t));
- dest[len] = 0;
-
- return dest;
+ /*
+ * Not run out of chars - strings are different lengths.
+ */
+
+ if (n)
+ return(toupper_w(*s) - toupper_w(*t));
+
+ /*
+ * Identical up to where we run out of chars,
+ * and strings are same length.
+ */
+
+ return(0);
}
/*******************************************************************
-copy a string with max len
+ Compare 2 strings.
********************************************************************/
-smb_ucs2_t *strncpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const size_t max)
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
{
- size_t len;
-
- if (!dest || !src) return NULL;
-
- for (len = 0; (src[len] != 0) && (len < max); len++)
- dest[len] = src[len];
- while (len < max)
- dest[len++] = 0;
-
- return dest;
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2)
+ return(False);
+
+ return(StrCaseCmp_w(s1,s2)==0);
}
+/*******************************************************************
+ Compare 2 strings up to and including the nth char. n is in ucs2
+ units.
+******************************************************************/
+
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
+{
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2 || !n)
+ return(False);
+
+ return(StrnCaseCmp_w(s1,s2,n)==0);
+}
/*******************************************************************
-append a string of len bytes and add a terminator
+ Compare 2 strings (case sensitive).
********************************************************************/
-smb_ucs2_t *strncat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const size_t max)
-{
- size_t start;
- size_t len;
-
- if (!dest || !src) return NULL;
-
- start = strlen_w(dest);
- len = strnlen_w(src, max);
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
+{
+ if (s1 == s2)
+ return(True);
+ if (!s1 || !s2)
+ return(False);
+
+ return(strcmp_w(s1,s2)==0);
+}
- memcpy(&dest[start], src, len*sizeof(smb_ucs2_t));
- dest[start+len] = 0;
-
- return dest;
+/*******************************************************************
+ Convert a string to lower case.
+********************************************************************/
+
+void strlower_w(smb_ucs2_t *s)
+{
+ while (*s) {
+ if (isupper_w(*s))
+ *s = tolower_w(*s);
+ s++;
+ }
}
-smb_ucs2_t *strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src)
-{
- size_t start;
- size_t len;
-
- if (!dest || !src) return NULL;
-
- start = strlen_w(dest);
- len = strlen_w(src);
+/*******************************************************************
+ Convert a string to upper case.
+********************************************************************/
- memcpy(&dest[start], src, len*sizeof(smb_ucs2_t));
- dest[start+len] = 0;
-
- return dest;
+void strupper_w(smb_ucs2_t *s)
+{
+ while (*s) {
+ if (islower_w(*s))
+ *s = toupper_w(*s);
+ s++;
+ }
}
+/*******************************************************************
+ Convert a string to "normal" form.
+********************************************************************/
+
+void strnorm_w(smb_ucs2_t *s)
+{
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ strupper_w(s);
+ else
+ strlower_w(s);
+}
/*******************************************************************
-replace any occurence of oldc with newc in unicode string
+ Check if a string is in "normal" case.
********************************************************************/
+BOOL strisnormal_w(smb_ucs2_t *s)
+{
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ return(!strhaslower_w(s));
+
+ return(!strhasupper_w(s));
+}
+
+/****************************************************************************
+ String replace.
+****************************************************************************/
+
void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
{
- for(;*s;s++) {
- if(*s==oldc) *s=newc;
+ while (*s) {
+ if (oldc == *s)
+ *s = newc;
+ s++;
}
}
/*******************************************************************
-trim unicode string
+ Skip past some strings in a buffer. n is in bytes.
********************************************************************/
-BOOL trim_string_w(smb_ucs2_t *s, const smb_ucs2_t *front,
- const smb_ucs2_t *back)
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
{
- BOOL ret = False;
- size_t len, front_len, back_len;
+ while (n--)
+ buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
+ return(buf);
+}
- if (!s || !*s) return False;
+/*******************************************************************
+ Count the number of characters in a string. Same as strlen_w in
+ smb_ucs2_t string units.
+********************************************************************/
- len = strlen_w(s);
+size_t str_charnum_w(const smb_ucs2_t *s)
+{
+ return strlen_w(s);
+}
- if (front && *front) {
- front_len = strlen_w(front);
- while (len && strncmp_w(s, front, front_len) == 0) {
- memmove(s, (s + front_len), (len - front_len + 1) * sizeof(smb_ucs2_t));
- len -= front_len;
- ret = True;
+/*******************************************************************
+ Trim the specified elements off the front and back of a string.
+********************************************************************/
+
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
+{
+ BOOL ret = False;
+ size_t front_len = (front && *front) ? strlen_w(front) : 0;
+ size_t back_len = (back && *back) ? strlen_w(back) : 0;
+ size_t s_len;
+
+ while (front_len && strncmp_w(s, front, front_len) == 0) {
+ smb_ucs2_t *p = s;
+ ret = True;
+
+ while (1) {
+ if (!(*p = p[front_len]))
+ break;
+ p++;
}
}
-
- if (back && *back) {
- back_len = strlen_w(back);
- while (len && strncmp_w((s + (len - back_len)), back, back_len) == 0) {
- s[len - back_len] = 0;
- len -= back_len;
+
+ if(back_len) {
+ s_len = strlen_w(s);
+ while ((s_len >= back_len) &&
+ (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
ret = True;
+ s[s_len - back_len] = 0;
+ s_len = strlen_w(s);
}
}
- return ret;
+ return(ret);
}
-/*
- The *_wa() functions take a combination of 7 bit ascii
- and wide characters They are used so that you can use string
- functions combining C string constants with ucs2 strings
+/****************************************************************************
+ Does a string have any uppercase chars in it ?
+****************************************************************************/
- The char* arguments must NOT be multibyte - to be completely sure
- of this only pass string constants */
+BOOL strhasupper_w(const smb_ucs2_t *s)
+{
+ while (*s) {
+ if (isupper_w(*s))
+ return(True);
+ s++;
+ }
+ return(False);
+}
+/****************************************************************************
+ Does a string have any lowercase chars in it ?
+****************************************************************************/
-void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
+BOOL strhaslower_w(const smb_ucs2_t *s)
{
- int i;
- for (i=0;i<PSTRING_LEN;i++) {
- dest[i] = UCS2_CHAR(src[i]);
- if (src[i] == 0) return;
+ while (*s) {
+ if (islower(*s))
+ return(True);
+ s++;
}
+ return(False);
}
-int strcmp_wa(const smb_ucs2_t *a, const char *b)
+/****************************************************************************
+ Find the number of 'c' chars in a string.
+****************************************************************************/
+
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
{
- while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
- return (*a - UCS2_CHAR(*b));
+ size_t count=0;
+
+ while (*s) {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ return(count);
}
-int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len)
+/*******************************************************************
+ Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
{
- size_t n = 0;
- while ((n < len) && *b && *a == UCS2_CHAR(*b)) { a++; b++; n++;}
- return (len - n)?(*a - UCS2_CHAR(*b)):0;
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+ while (*s) {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ return True;
}
-smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+ maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const smb_ucs2_t *other_safe_chars, size_t maxlength)
{
- while (*s != 0) {
- int i;
- for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++)
- ;
- if (p[i]) return (smb_ucs2_t *)s;
- s++;
+ size_t len, i;
+ smb_ucs2_t nullstr_w = (smb_ucs2_t)0;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
+ return NULL;
}
- return NULL;
+
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen_w(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ if (!other_safe_chars)
+ other_safe_chars = &nullstr_w;
+
+ for(i = 0; i < len; i++) {
+ smb_ucs2_t val = src[i];
+ if(isupper_w(val) ||islower_w(val) || isdigit_w(val) || strchr_w(other_safe_chars, val))
+ dest[i] = src[i];
+ else
+ dest[i] = (smb_ucs2_t)'_';
+ }
+
+ dest[i] = 0;
+
+ return dest;
}
-smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins)
+/****************************************************************************
+ Like strncpy but always null terminates. Make sure there is room !
+ The variable n should always be one less than the available size and is in
+ ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
{
- smb_ucs2_t *r;
- size_t slen, inslen;
+ smb_ucs2_t *d = dest;
+ if (!dest)
+ return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
- if (!s || !*s || !ins || !*ins) return NULL;
- slen = strlen_w(s);
- inslen = strlen(ins);
- r = (smb_ucs2_t *)s;
- while ((r = strchr_w(r, UCS2_CHAR(*ins)))) {
- if (strncmp_wa(r, ins, inslen) == 0) return r;
- r++;
+ while (n-- && (*d++ = *src++))
+ ;
+ *d = 0;
+ return(dest);
+}
+
+/****************************************************************************
+ Like strncpy but copies up to the character marker. Always null terminates.
+ returns a pointer to the character marker in the source string (src).
+ n is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
+{
+ smb_ucs2_t *p;
+ size_t str_len;
+
+ p = strchr_w(src, c);
+ if (p == NULL) {
+ fstring cval;
+ smb_ucs2_t mbcval[2];
+ mbcval[0] = c;
+ mbcval[1] = 0;
+ DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
+ unicode_to_unix(cval,mbcval,sizeof(cval)) ));
+ return NULL;
}
- return NULL;
+
+ str_len = PTR_DIFF(p, src) + 1;
+ safe_strcpy_w(dest, src, MIN(n, str_len));
+
+ return p;
}
-BOOL trim_string_wa(smb_ucs2_t *s, const char *front,
- const char *back)
+/*************************************************************
+ Routine to get hex characters and turn them into a 16 byte array.
+ The array can be variable length, and any non-hex-numeric
+ characters are skipped. "0xnn" or "0Xnn" is specially catered
+ for. len is in bytes.
+ Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
+**************************************************************/
+
+static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
+static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
+ (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
+ (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
+ (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
+
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
{
- wpstring f, b;
+ size_t i;
+ size_t num_chars = 0;
+ unsigned char lonybble, hinybble;
+ smb_ucs2_t *p1 = NULL, *p2 = NULL;
+
+ /*
+ * Convert to smb_ucs2_t units.
+ */
+
+ len /= sizeof(smb_ucs2_t);
+
+ for (i = 0; i < len && strhex[i] != 0; i++) {
+ if (strnequal_w(hexchars, hexprefix, 2)) {
+ i++; /* skip two chars */
+ continue;
+ }
+
+ if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
+ break;
+
+ i++; /* next hex digit */
+
+ if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
+ break;
+
+ /* get the two nybbles */
+ hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
+ lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
+
+ p[num_chars] = (hinybble << 4) | lonybble;
+ num_chars++;
- if (front) push_ucs2(NULL, f, front, sizeof(wpstring) - 1, STR_TERMINATE);
- else *f = 0;
- if (back) push_ucs2(NULL, b, back, sizeof(wpstring) - 1, STR_TERMINATE);
- else *b = 0;
- return trim_string_w(s, f, b);
+ p1 = NULL;
+ p2 = NULL;
+ }
+ return num_chars;
}
-/*******************************************************************
- returns the length in number of wide characters
- ******************************************************************/
-int unistrlen(uint16 *s)
+/****************************************************************************
+ Check if a string is part of a list.
+****************************************************************************/
+
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
{
- int len;
+ wpstring tok;
+ smb_ucs2_t *p=list;
+
+ if (!list)
+ return(False);
+
+ while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
+ if (casesensitive) {
+ if (strcmp_w(tok,s) == 0)
+ return(True);
+ } else {
+ if (StrCaseCmp_w(tok,s) == 0)
+ return(True);
+ }
+ }
+ return(False);
+}
- if (!s)
- return -1;
+/* This is used to prevent lots of mallocs of size 2 */
+static smb_ucs2_t *null_string = NULL;
- for (len=0; *s; s++,len++);
+/****************************************************************************
+ Set a string value, allocing the space for the string.
+****************************************************************************/
- return len;
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+ size_t l;
+
+ if (!null_string) {
+ if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
+ DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
+ return False;
+ }
+ *null_string = 0;
+ }
+
+ if (!src)
+ src = null_string;
+
+ l = strlen_w(src);
+
+ if (l == 0)
+ *dest = null_string;
+ else {
+ (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
+ if ((*dest) == NULL) {
+ DEBUG(0,("Out of memory in string_init_w\n"));
+ return False;
+ }
+
+ wpstrcpy(*dest,src);
+ }
+ return(True);
}
-/*******************************************************************
- Strcpy for unicode strings. returns length (in num of wide chars)
-********************************************************************/
+/****************************************************************************
+ Free a string value.
+****************************************************************************/
-int unistrcpy(uint16 *dst, uint16 *src)
+void string_free_w(smb_ucs2_t **s)
{
- int num_wchars = 0;
+ if (!s || !(*s))
+ return;
+ if (*s == null_string)
+ *s = NULL;
+ SAFE_FREE(*s);
+}
- while (*src) {
- *dst++ = *src++;
- num_wchars++;
+/****************************************************************************
+ Set a string value, allocing the space for the string, and deallocating any
+ existing space.
+****************************************************************************/
+
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+ string_free_w(dest);
+
+ return(string_init_w(dest,src));
+}
+
+/****************************************************************************
+ Substitute a string for a pattern in another string. Make sure there is
+ enough room !
+
+ This routine looks for pattern in s and replaces it with
+ insert. It may do multiple replacements.
+
+ Any of " ; ' $ or ` in the insert string are replaced with _
+ if len==0 then no length check is performed
+ len is in ucs2 units.
+****************************************************************************/
+
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+ smb_ucs2_t *p;
+ ssize_t ls,lp,li, i;
+
+ if (!insert || !pattern || !s)
+ return;
+
+ ls = (ssize_t)strlen_w(s);
+ lp = (ssize_t)strlen_w(pattern);
+ li = (ssize_t)strlen_w(insert);
+
+ if (!*pattern)
+ return;
+
+ while (lp <= ls && (p = strstr_w(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
+ (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+ unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+ break;
+ }
+ if (li != lp)
+ memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+ for (i=0;i<li;i++) {
+ switch (insert[i]) {
+ case (smb_ucs2_t)'`':
+ case (smb_ucs2_t)'"':
+ case (smb_ucs2_t)'\'':
+ case (smb_ucs2_t)';':
+ case (smb_ucs2_t)'$':
+ case (smb_ucs2_t)'%':
+ case (smb_ucs2_t)'\r':
+ case (smb_ucs2_t)'\n':
+ p[i] = (smb_ucs2_t)'_';
+ break;
+ default:
+ p[i] = insert[i];
+ }
+ }
+ s = p + li;
+ ls += (li-lp);
}
- *dst = 0;
+}
- return num_wchars;
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
+{
+ string_sub_w(s, pattern, insert, sizeof(wfstring));
}
-/**
- * Samba ucs2 type to UNISTR2 conversion
- *
- * @param ctx Talloc context to create the dst strcture (if null) and the
- * contents of the unicode string.
- * @param dst UNISTR2 destination. If equals null, then it's allocated.
- * @param src smb_ucs2_t source.
- * @param max_len maximum number of unicode characters to copy. If equals
- * null, then null-termination of src is taken
- *
- * @return copied UNISTR2 destination
- **/
-UNISTR2* ucs2_to_unistr2(TALLOC_CTX *ctx, UNISTR2* dst, smb_ucs2_t* src)
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
{
- size_t len;
+ string_sub_w(s, pattern, insert, sizeof(wpstring));
+}
- if (!src)
- return NULL;
- len = strlen_w(src);
+/****************************************************************************
+ Similar to string_sub() but allows for any character to be substituted.
+ Use with caution !
+ if len==0 then no length check is performed.
+****************************************************************************/
+
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+ smb_ucs2_t *p;
+ ssize_t ls,lp,li;
+
+ if (!insert || !pattern || !s)
+ return;
+
+ ls = (ssize_t)strlen_w(s);
+ lp = (ssize_t)strlen_w(pattern);
+ li = (ssize_t)strlen_w(insert);
+
+ if (!*pattern)
+ return;
- /* allocate UNISTR2 destination if not given */
- if (!dst) {
- dst = (UNISTR2*) talloc(ctx, sizeof(UNISTR2));
- if (!dst)
- return NULL;
+ while (lp <= ls && (p = strstr_w(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ fstring out;
+ DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
+ (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+ unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+ break;
+ }
+ if (li != lp)
+ memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+ memcpy(p, insert, li*sizeof(smb_ucs2_t));
+ s = p + li;
+ ls += (li-lp);
}
- if (!dst->buffer) {
- dst->buffer = (uint16*) talloc(ctx, sizeof(uint16) * (len + 1));
- if (!dst->buffer)
- return NULL;
+}
+
+/****************************************************************************
+ Splits out the front and back at a separator.
+****************************************************************************/
+
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
+{
+ smb_ucs2_t *p = strrchr_w(path, sep);
+
+ if (p != NULL)
+ *p = 0;
+
+ if (front != NULL)
+ wpstrcpy(front, path);
+
+ if (p != NULL) {
+ if (back != NULL)
+ wpstrcpy(back, p+1);
+ *p = (smb_ucs2_t)'\\';
+ } else {
+ if (back != NULL)
+ back[0] = 0;
}
-
- /* set UNISTR2 parameters */
- dst->uni_max_len = len + 1;
- dst->offset = 0;
- dst->uni_str_len = len;
-
- /* copy the actual unicode string */
- strncpy_w(dst->buffer, src, dst->uni_max_len);
-
- return dst;
+}
+
+
+/****************************************************************************
+ Write an octal as a string.
+****************************************************************************/
+
+smb_ucs2_t *octal_string_w(int i)
+{
+ static smb_ucs2_t wret[64];
+ char ret[64];
+
+ if (i == -1)
+ slprintf(ret, sizeof(ret)-1, "-1");
+ else
+ slprintf(ret, sizeof(ret)-1, "0%o", i);
+ return unix_to_unicode(wret, ret, sizeof(wret));
+}
+
+
+/****************************************************************************
+ Truncate a string at a specified length.
+ length is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
+{
+ if (s && strlen_w(s) > length)
+ s[length] = 0;
+
+ return s;
+}
+
+/******************************************************************
+ functions for UTF8 support (using in kanji.c)
+ ******************************************************************/
+smb_ucs2_t doscp2ucs2(int w)
+{
+ return ((smb_ucs2_t)doscp_to_ucs2[w]);
+}
+
+int ucs2doscp(smb_ucs2_t w)
+{
+ return ((int)ucs2_to_doscp[w]);
+}
+
+/* Temporary fix until 3.0... JRA */
+
+int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
+{
+ if(dest_len==-1)
+ dest_len=MAXUNI-3;
+
+ if (!src) {
+ dest[0] = 0;
+ return 0;
+ }
+
+ if (flags & STR_TERMINATE)
+ src_len = strlen_w(src)*2+2;
+
+ dest_len = MIN((src_len/2), (dest_len-1));
+ unistr_to_ascii(dest, src, dest_len);
+ return src_len;
}
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
deleted file mode 100644
index dc9bc920230..00000000000
--- a/source/lib/util_uuid.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * UUID server routines
- * Copyright (C) Theodore Ts'o 1996, 1997,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002, 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*
- * Offset between 15-Oct-1582 and 1-Jan-70
- */
-#define TIME_OFFSET_HIGH 0x01B21DD2
-#define TIME_OFFSET_LOW 0x13814000
-
-void smb_uuid_pack(const struct uuid uu, UUID_FLAT *ptr)
-{
- SIVAL(ptr, 0, uu.time_low);
- SSVAL(ptr, 4, uu.time_mid);
- SSVAL(ptr, 6, uu.time_hi_and_version);
- memcpy(ptr+8, uu.clock_seq, 2);
- memcpy(ptr+10, uu.node, 6);
-}
-
-void smb_uuid_unpack(const UUID_FLAT in, struct uuid *uu)
-{
- uu->time_low = IVAL(in.info, 0);
- uu->time_mid = SVAL(in.info, 4);
- uu->time_hi_and_version = SVAL(in.info, 6);
- memcpy(uu->clock_seq, in.info+8, 2);
- memcpy(uu->node, in.info+10, 6);
-}
-
-struct uuid smb_uuid_unpack_static(const UUID_FLAT in)
-{
- static struct uuid uu;
-
- smb_uuid_unpack(in, &uu);
- return uu;
-}
-
-void smb_uuid_generate_random(struct uuid *uu)
-{
- UUID_FLAT tmp;
-
- generate_random_buffer(tmp.info, sizeof(tmp.info), True);
- smb_uuid_unpack(tmp, uu);
-
- uu->clock_seq[0] = (uu->clock_seq[0] & 0x3F) | 0x80;
- uu->time_hi_and_version = (uu->time_hi_and_version & 0x0FFF) | 0x4000;
-}
-
-char *smb_uuid_to_string(const struct uuid uu)
-{
- char *out;
-
- asprintf(&out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- uu.time_low, uu.time_mid, uu.time_hi_and_version,
- uu.clock_seq[0], uu.clock_seq[1],
- uu.node[0], uu.node[1], uu.node[2],
- uu.node[3], uu.node[4], uu.node[5]);
-
- return out;
-}
-
-const char *smb_uuid_string_static(const struct uuid uu)
-{
- static char out[37];
-
- slprintf(out, sizeof(out),
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- uu.time_low, uu.time_mid, uu.time_hi_and_version,
- uu.clock_seq[0], uu.clock_seq[1],
- uu.node[0], uu.node[1], uu.node[2],
- uu.node[3], uu.node[4], uu.node[5]);
- return out;
-}
-
-BOOL smb_string_to_uuid(const char *in, struct uuid* uu)
-{
- BOOL ret = False;
- const char *ptr = in;
- char *end = (char *)in;
- int i;
-
- if (!in || !uu) goto out;
-
- uu->time_low = strtoul(ptr, &end, 16);
- if ((end - ptr) != 8 || *end != '-') goto out;
- ptr = (end + 1);
-
- uu->time_mid = strtoul(ptr, &end, 16);
- if ((end - ptr) != 4 || *end != '-') goto out;
- ptr = (end + 1);
-
- uu->time_hi_and_version = strtoul(ptr, &end, 16);
- if ((end - ptr) != 4 || *end != '-') goto out;
- ptr = (end + 1);
-
- for (i = 0; i < 2; i++) {
- int adj = 0;
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->clock_seq[i] = (*ptr - adj) << 4;
- ptr++;
-
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->clock_seq[i] |= (*ptr - adj);
- ptr++;
- }
-
- if (*ptr != '-') goto out;
- ptr++;
-
- for (i = 0; i < 6; i++) {
- int adj = 0;
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->node[i] = (*ptr - adj) << 4;
- ptr++;
-
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->node[i] |= (*ptr - adj);
- ptr++;
- }
-
- ret = True;
-out:
- return ret;
-}
diff --git a/source/lib/version.c b/source/lib/version.c
deleted file mode 100644
index 99f836c2d5b..00000000000
--- a/source/lib/version.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba Version functions
-
- Copyright (C) Stefan Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-const char *samba_version_string(void)
-{
-#ifndef SAMBA_VERSION_VENDOR_SUFFIX
- return SAMBA_VERSION_OFFICIAL_STRING;
-#else
- static fstring samba_version;
- static BOOL init_samba_version;
-
- if (init_samba_version)
- return samba_version;
-
- snprintf(samba_version,sizeof(samba_version),"%s-%s",
- SAMBA_VERSION_OFFICIAL_STRING,
- SAMBA_VERSION_VENDOR_SUFFIX);
-
- init_samba_version = True;
- return samba_version;
-#endif
-}
diff --git a/source/lib/wins_srv.c b/source/lib/wins_srv.c
index 4a54762fde7..1b0b8bc8e75 100644
--- a/source/lib/wins_srv.c
+++ b/source/lib/wins_srv.c
@@ -1,9 +1,9 @@
/*
- Unix SMB/CIFS implementation.
- Samba wins server helper functions
- Copyright (C) Andrew Tridgell 1992-2002
+ Unix SMB/Netbios implementation.
+ Version 2.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Christopher R. Hertel 2000
- Copyright (C) Tim Potter 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,335 +22,248 @@
#include "includes.h"
-/*
- This is pretty much a complete rewrite of the earlier code. The main
- aim of the rewrite is to add support for having multiple wins server
- lists, so Samba can register with multiple groups of wins servers
- and each group has a failover list of wins servers.
-
- Central to the way it all works is the idea of a wins server
- 'tag'. A wins tag is a label for a group of wins servers. For
- example if you use
-
- wins server = fred:192.168.2.10 mary:192.168.3.199 fred:192.168.2.61
-
- then you would have two groups of wins servers, one tagged with the
- name 'fred' and the other with the name 'mary'. I would usually
- recommend using interface names instead of 'fred' and 'mary' but
- they can be any alpha string.
-
- Now, how does it all work. Well, nmbd needs to register each of its
- IPs with each of its names once with each group of wins servers. So
- it tries registering with the first one mentioned in the list, then
- if that fails it marks that WINS server dead and moves onto the next
- one.
-
- In the client code things are a bit different. As each of the groups
- of wins servers is a separate name space we need to try each of the
- groups until we either succeed or we run out of wins servers to
- try. If we get a negative response from a wins server then that
- means the name doesn't exist in that group, so we give up on that
- group and move to the next group. If we don't get a response at all
- then maybe the wins server is down, in which case we need to
- failover to the next one for that group.
-
- confused yet? (tridge)
-*/
-
-/* how long a server is marked dead for */
-#define DEATH_TIME 600
-
-/* The list of dead wins servers is stored in gencache.tdb. Each server is
- marked dead from the point of view of a given source address. We keep a
- separate dead list for each src address to cope with multiple interfaces
- that are not routable to each other.
- */
-
-#define WINS_SRV_FMT "WINS_SRV_DEAD/%s,%s" /* wins_ip,src_ip */
-
-static char *wins_srv_keystr(struct in_addr wins_ip, struct in_addr src_ip)
-{
- char *keystr = NULL, *wins_ip_addr = NULL, *src_ip_addr = NULL;
-
- wins_ip_addr = strdup(inet_ntoa(wins_ip));
- src_ip_addr = strdup(inet_ntoa(src_ip));
-
- if ( !wins_ip_addr || !src_ip_addr ) {
- DEBUG(0,("wins_srv_keystr: malloc error\n"));
- goto done;
- }
-
- if (asprintf(&keystr, WINS_SRV_FMT, wins_ip_addr, src_ip_addr) == -1) {
- DEBUG(0, (": ns_srv_keystr: malloc error for key string\n"));
- }
-
-done:
- SAFE_FREE(wins_ip_addr);
- SAFE_FREE(src_ip_addr);
-
- return keystr;
-}
-
-/*
- see if an ip is on the dead list
-*/
-
-BOOL wins_srv_is_dead(struct in_addr wins_ip, struct in_addr src_ip)
-{
- char *keystr = wins_srv_keystr(wins_ip, src_ip);
- BOOL result;
-
- /* If the key exists then the WINS server has been marked as dead */
-
- result = gencache_get(keystr, NULL, NULL);
- SAFE_FREE(keystr);
-
- DEBUG(4, ("wins_srv_is_dead: %s is %s\n", inet_ntoa(wins_ip),
- result ? "dead" : "alive"));
-
- return result;
-}
-
-
-/*
- mark a wins server as being alive (for the moment)
-*/
-void wins_srv_alive(struct in_addr wins_ip, struct in_addr src_ip)
-{
- char *keystr = wins_srv_keystr(wins_ip, src_ip);
-
- gencache_del(keystr);
- SAFE_FREE(keystr);
-
- DEBUG(4, ("wins_srv_alive: marking wins server %s alive\n",
- inet_ntoa(wins_ip)));
-}
-
-/*
- mark a wins server as temporarily dead
-*/
-void wins_srv_died(struct in_addr wins_ip, struct in_addr src_ip)
-{
- char *keystr;
-
- if (is_zero_ip(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
- return;
-
- keystr = wins_srv_keystr(wins_ip, src_ip);
-
- gencache_set(keystr, "DOWN", time(NULL) + DEATH_TIME);
-
- SAFE_FREE(keystr);
-
- DEBUG(4,("Marking wins server %s dead for %u seconds from source %s\n",
- inet_ntoa(wins_ip), DEATH_TIME, inet_ntoa(src_ip)));
-}
-
-/*
- return the total number of wins servers, dead or not
-*/
-unsigned wins_srv_count(void)
-{
- const char **list;
- int count = 0;
-
- if (lp_wins_support()) {
- /* simple - just talk to ourselves */
- return 1;
- }
-
- list = lp_wins_server_list();
- for (count=0; list && list[count]; count++)
- /* nop */ ;
-
- return count;
-}
-
-/* an internal convenience structure for an IP with a short string tag
- attached */
-struct tagged_ip {
- fstring tag;
- struct in_addr ip;
-};
-
-/*
- parse an IP string that might be in tagged format
- the result is a tagged_ip structure containing the tag
- and the ip in in_addr format. If there is no tag then
- use the tag '*'
-*/
-static void parse_ip(struct tagged_ip *ip, const char *str)
-{
- char *s = strchr(str, ':');
- if (!s) {
- fstrcpy(ip->tag, "*");
- ip->ip = *interpret_addr2(str);
- return;
- }
-
- ip->ip = *interpret_addr2(s+1);
- fstrcpy(ip->tag, str);
- s = strchr(ip->tag, ':');
- if (s) *s = 0;
-}
-
-
-
-/*
- return the list of wins server tags. A 'tag' is used to distinguish
- wins server as either belonging to the same name space or a separate
- name space. Usually you would setup your 'wins server' option to
- list one or more wins server per interface and use the interface
- name as your tag, but you are free to use any tag you like.
-*/
-char **wins_srv_tags(void)
-{
- char **ret = NULL;
- int count=0, i, j;
- const char **list;
-
- if (lp_wins_support()) {
- /* give the caller something to chew on. This makes
- the rest of the logic simpler (ie. less special cases) */
- ret = (char **)malloc(sizeof(char *)*2);
- if (!ret) return NULL;
- ret[0] = strdup("*");
- ret[1] = NULL;
- return ret;
- }
-
- list = lp_wins_server_list();
- if (!list)
- return NULL;
-
- /* yes, this is O(n^2) but n is very small */
- for (i=0;list[i];i++) {
- struct tagged_ip t_ip;
-
- parse_ip(&t_ip, list[i]);
-
- /* see if we already have it */
- for (j=0;j<count;j++) {
- if (strcmp(ret[j], t_ip.tag) == 0) {
- break;
- }
- }
-
- if (j != count) {
- /* we already have it. Move along */
- continue;
- }
-
- /* add it to the list */
- ret = (char **)Realloc(ret, (count+2) * sizeof(char *));
- ret[count] = strdup(t_ip.tag);
- if (!ret[count]) break;
- count++;
- }
-
- if (count) {
- /* make sure we null terminate */
- ret[count] = NULL;
- }
-
- return ret;
-}
-
-/* free a list of wins server tags given by wins_srv_tags */
-void wins_srv_tags_free(char **list)
-{
- int i;
- if (!list) return;
- for (i=0; list[i]; i++) {
- free(list[i]);
- }
- free(list);
-}
-
-
-/*
- return the IP of the currently active wins server for the given tag,
- or the zero IP otherwise
-*/
-struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
-{
- const char **list;
- int i;
- struct tagged_ip t_ip;
-
- /* if we are a wins server then we always just talk to ourselves */
- if (lp_wins_support()) {
- extern struct in_addr loopback_ip;
- return loopback_ip;
- }
-
- list = lp_wins_server_list();
- if (!list || !list[0]) {
- struct in_addr ip;
- zero_ip(&ip);
- return ip;
- }
-
- /* find the first live one for this tag */
- for (i=0; list[i]; i++) {
- parse_ip(&t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) != 0) {
- /* not for the right tag. Move along */
- continue;
- }
- if (!wins_srv_is_dead(t_ip.ip, src_ip)) {
- fstring src_name;
- fstrcpy(src_name, inet_ntoa(src_ip));
- DEBUG(6,("Current wins server for tag '%s' with source %s is %s\n",
- tag,
- src_name,
- inet_ntoa(t_ip.ip)));
- return t_ip.ip;
- }
- }
-
- /* they're all dead - try the first one until they revive */
- for (i=0; list[i]; i++) {
- parse_ip(&t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) != 0) {
- continue;
- }
- return t_ip.ip;
- }
-
- /* this can't happen?? */
- zero_ip(&t_ip.ip);
- return t_ip.ip;
-}
-
-
-/*
- return a count of the number of IPs for a particular tag, including
- dead ones
-*/
-unsigned wins_srv_count_tag(const char *tag)
-{
- const char **list;
- int i, count=0;
-
- /* if we are a wins server then we always just talk to ourselves */
- if (lp_wins_support()) {
- return 1;
- }
-
- list = lp_wins_server_list();
- if (!list || !list[0]) {
- return 0;
- }
-
- /* find the first live one for this tag */
- for (i=0; list[i]; i++) {
- struct tagged_ip t_ip;
- parse_ip(&t_ip, list[i]);
- if (strcmp(tag, t_ip.tag) == 0) {
- count++;
- }
- }
-
- return count;
-}
+/* -------------------------------------------------------------------------- **
+ * Discussion...
+ *
+ * This module implements WINS failover.
+ *
+ * Microsoft's WINS servers provide a feature called WINS replication,
+ * which synchronises the WINS name databases between two or more servers.
+ * This means that the two servers can be used interchangably (more or
+ * less). WINS replication is particularly useful if you are trying to
+ * synchronise the WINS namespace between servers in remote locations, or
+ * if your WINS servers tend to crash a lot.
+ *
+ * WINS failover allows the client to 'switch' to a different WINS server
+ * if the current WINS server mysteriously disappears. On Windows
+ * systems, this is typically represented as 'primary' and 'secondary'
+ * WINS servers.
+ *
+ * Failover only works if the WINS servers are synced. If they are not,
+ * then
+ * a) if the primary WINS server never fails the client will never 'see'
+ * the secondary (or tertiary or...) WINS server name space.
+ * b) if the primary *does* fail, the client will be entering an
+ * unfamiliar namespace. The client itself will not be registered in
+ * that namespace and any names which match names in the previous
+ * space will likely resolve to different host IP addresses.
+ *
+ * One key thing to remember regarding WINS failover is that Samba does
+ * not (yet) implement WINS replication. For those interested, sniff port
+ * 42 (TCP? UDP? ...dunno off hand) and see what two MS WINS servers do.
+ *
+ * At this stage, only failover is implemented. The next thing is to add
+ * support for multi-WINS server registration and query (multi-membership).
+ *
+ * Multi-membership is a little wierd. The idea is that the client can
+ * register itself with multiple non-replicated WINS servers, and query
+ * all of those servers (in a prescribed sequence) to resolve a name.
+ *
+ * The implications of multi-membership are not quite clear. Worth
+ * trying, I suppose. Changes will be needed in the name query and
+ * registration code to accomodate this feature. Also, there will need to
+ * be some sort of syntax extension for the 'wins server' parameter in
+ * smb.conf. I'm thinking that a colon could be used as a separator.
+ *
+ * Of course, for each WINS namespace there might be multiple, synced WINS
+ * servers. The change to this module would likely be the addition of a
+ * linked list of linked lists.
+ *
+ * crh@samba.org
+ */
+
+/* -------------------------------------------------------------------------- **
+ * Defines...
+ *
+ * NECROMANCYCLE - The dead server retry period, in seconds. When a WINS
+ * server is declared dead, wait this many seconds before
+ * attempting to communicate with it.
+ */
+
+#define NECROMANCYCLE 600 /* 600 seconds == 10 minutes. */
+
+/* -------------------------------------------------------------------------- **
+ * Typedefs...
+ */
+
+typedef struct
+ {
+ ubi_slNode node; /* Linked list node structure. */
+ time_t mourning; /* If > current time then server is dead, Jim. */
+ char *server; /* DNS name or IP of NBNS server to query. */
+ struct in_addr ip_addr; /* Cache translated IP. */
+ } list_entry;
+
+/* -------------------------------------------------------------------------- **
+ * Private, static variables.
+ */
+
+static ubi_slNewList( wins_srv_list );
+
+/* -------------------------------------------------------------------------- **
+ * Functions...
+ */
+
+
+BOOL wins_srv_load_list( const char *src )
+ /* ------------------------------------------------------------------------ **
+ * Create or recreate the linked list of failover WINS servers.
+ *
+ * Input: src - String of DNS names and/or IP addresses delimited by the
+ * characters listed in LIST_SEP (see include/local.h).
+ *
+ * Output: True if at least one name or IP could be parsed out of the
+ * list, else False.
+ *
+ * Notes: There is no syntax checking done on the names or IPs. We do
+ * check to see if the field is an IP, in which case we copy it
+ * to the ip_addr field of the entry. Don't bother to to a host
+ * name lookup on all names now. They're done as needed in
+ * wins_srv_ip().
+ */
+ {
+ list_entry *entry;
+ const char *p = src;
+ pstring wins_id_bufr;
+ unsigned long count;
+
+ /* Empty the list. */
+ while( NULL != (entry =(list_entry *)ubi_slRemHead( wins_srv_list )) )
+ {
+ SAFE_FREE( entry->server );
+ SAFE_FREE( entry );
+ }
+ (void)ubi_slInitList( wins_srv_list ); /* shouldn't be needed */
+
+ /* Parse out the DNS names or IP addresses of the WINS servers. */
+ DEBUG( 4, ("wins_srv_load_list(): Building WINS server list:\n") );
+ while( next_token( &p, wins_id_bufr, LIST_SEP, sizeof( wins_id_bufr ) ) )
+ {
+ entry = (list_entry *)malloc( sizeof( list_entry ) );
+ if( NULL == entry )
+ {
+ DEBUG( 0, ("wins_srv_load_list(): malloc(list_entry) failed.\n") );
+ }
+ else
+ {
+ entry->mourning = 0;
+ if( NULL == (entry->server = strdup( wins_id_bufr )) )
+ {
+ SAFE_FREE( entry );
+ DEBUG( 0, ("wins_srv_load_list(): strdup(\"%s\") failed.\n", wins_id_bufr) );
+ }
+ else
+ {
+ /* Add server to list. */
+ if( is_ipaddress( wins_id_bufr ) )
+ entry->ip_addr = *interpret_addr2( wins_id_bufr );
+ else
+ entry->ip_addr = *interpret_addr2( "0.0.0.0" );
+ (void)ubi_slAddTail( wins_srv_list, entry );
+ DEBUGADD( 4, ("%s,\n", wins_id_bufr) );
+ }
+ }
+ }
+
+ count = ubi_slCount( wins_srv_list );
+ DEBUGADD( 4, ( "%d WINS server%s listed.\n", (int)count, (1==count)?"":"s" ) );
+
+ return( (count > 0) ? True : False );
+ } /* wins_srv_load_list */
+
+
+struct in_addr wins_srv_ip( void )
+ /* ------------------------------------------------------------------------ **
+ */
+ {
+ time_t now = time(NULL);
+ list_entry *entry = (list_entry *)ubi_slFirst( wins_srv_list );
+
+ while( NULL != entry )
+ {
+ if( now >= entry->mourning ) /* Found a live one. */
+ {
+ /* If we don't have the IP, look it up. */
+ if( is_zero_ip( entry->ip_addr ) )
+ entry->ip_addr = *interpret_addr2( entry->server );
+
+ /* If we still don't have the IP then kill it, else return it. */
+ if( is_zero_ip( entry->ip_addr ) )
+ entry->mourning = now + NECROMANCYCLE;
+ else
+ return( entry->ip_addr );
+ }
+ entry = (list_entry *)ubi_slNext( entry );
+ }
+
+ /* If there are no live entries, return the zero IP. */
+ return( *interpret_addr2( "0.0.0.0" ) );
+ } /* wins_srv_ip */
+
+
+void wins_srv_died( struct in_addr boothill_ip )
+ /* ------------------------------------------------------------------------ **
+ * Called to indicate that a specific WINS server has died.
+ */
+ {
+ list_entry *entry;
+
+ if( is_zero_ip( boothill_ip ) )
+ {
+ DEBUG( 4, ("wins_srv_died(): Got request to mark zero IP down.\n") );
+ return;
+ }
+
+ entry = (list_entry *)ubi_slFirst( wins_srv_list );
+ while( NULL != entry )
+ {
+ /* Match based on IP. */
+ if( ip_equal( boothill_ip, entry->ip_addr ) )
+ {
+ entry->mourning = time(NULL) + NECROMANCYCLE;
+ entry->ip_addr.s_addr = 0; /* Force a re-lookup at re-birth. */
+ DEBUG( 2, ( "wins_srv_died(): WINS server %s appears to be down.\n",
+ entry->server ) );
+ return;
+ }
+ entry = (list_entry *)ubi_slNext( entry );
+ }
+
+ if( DEBUGLVL( 1 ) )
+ {
+ dbgtext( "wins_srv_died(): Could not mark WINS server %s down.\n",
+ inet_ntoa( boothill_ip ) );
+ dbgtext( "Address not found in server list.\n" );
+ }
+ } /* wins_srv_died */
+
+
+unsigned long wins_srv_count( void )
+ /* ------------------------------------------------------------------------ **
+ * Return the total number of entries in the list, dead or alive.
+ */
+ {
+ unsigned long count = ubi_slCount( wins_srv_list );
+
+ if( DEBUGLVL( 8 ) )
+ {
+ list_entry *entry = (list_entry *)ubi_slFirst( wins_srv_list );
+ time_t now = time(NULL);
+
+ dbgtext( "wins_srv_count: WINS status: %ld servers.\n", count );
+ while( NULL != entry )
+ {
+ dbgtext( " %s <%s>: ", entry->server, inet_ntoa( entry->ip_addr ) );
+ if( now >= entry->mourning )
+ dbgtext( "alive\n" );
+ else
+ dbgtext( "dead for %d more seconds\n", (int)(entry->mourning - now) );
+
+ entry = (list_entry *)ubi_slNext( entry );
+ }
+ }
+
+ return( count );
+ } /* wins_srv_count */
+
+/* ========================================================================== */
diff --git a/source/lib/xfile.c b/source/lib/xfile.c
deleted file mode 100644
index 1534dd855e9..00000000000
--- a/source/lib/xfile.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- stdio replacement
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- stdio is very convenient, but on some systems the file descriptor
- in FILE* is 8 bits, so it fails when more than 255 files are open.
-
- XFILE replaces stdio. It is less efficient, but at least it works
- when you have lots of files open
-
- The main restriction on XFILE is that it doesn't support seeking,
- and doesn't support O_RDWR. That keeps the code simple.
-*/
-
-#include "includes.h"
-
-#define XBUFSIZE BUFSIZ
-
-static XFILE _x_stdin = { 0, NULL, NULL, XBUFSIZE, 0, O_RDONLY, X_IOFBF, 0 };
-static XFILE _x_stdout = { 1, NULL, NULL, XBUFSIZE, 0, O_WRONLY, X_IOLBF, 0 };
-static XFILE _x_stderr = { 2, NULL, NULL, 0, 0, O_WRONLY, X_IONBF, 0 };
-
-XFILE *x_stdin = &_x_stdin;
-XFILE *x_stdout = &_x_stdout;
-XFILE *x_stderr = &_x_stderr;
-
-#define X_FLAG_EOF 1
-#define X_FLAG_ERROR 2
-#define X_FLAG_EINVAL 3
-
-/* simulate setvbuf() */
-int x_setvbuf(XFILE *f, char *buf, int mode, size_t size)
-{
- x_fflush(f);
- if (f->bufused) return -1;
-
- /* on files being read full buffering is the only option */
- if ((f->open_flags & O_ACCMODE) == O_RDONLY) {
- mode = X_IOFBF;
- }
-
- /* destroy any earlier buffer */
- SAFE_FREE(f->buf);
- f->buf = 0;
- f->bufsize = 0;
- f->next = NULL;
- f->bufused = 0;
- f->buftype = mode;
-
- if (f->buftype == X_IONBF) return 0;
-
- /* if buffering then we need some size */
- if (size == 0) size = XBUFSIZE;
-
- f->bufsize = size;
- f->bufused = 0;
-
- return 0;
-}
-
-/* allocate the buffer */
-static int x_allocate_buffer(XFILE *f)
-{
- if (f->buf) return 1;
- if (f->bufsize == 0) return 0;
- f->buf = malloc(f->bufsize);
- if (!f->buf) return 0;
- f->next = f->buf;
- return 1;
-}
-
-
-/* this looks more like open() than fopen(), but that is quite deliberate.
- I want programmers to *think* about O_EXCL, O_CREAT etc not just
- get them magically added
-*/
-XFILE *x_fopen(const char *fname, int flags, mode_t mode)
-{
- XFILE *ret;
-
- ret = (XFILE *)malloc(sizeof(XFILE));
- if (!ret) return NULL;
-
- memset(ret, 0, sizeof(XFILE));
-
- if ((flags & O_ACCMODE) == O_RDWR) {
- /* we don't support RDWR in XFILE - use file
- descriptors instead */
- errno = EINVAL;
- return NULL;
- }
-
- ret->open_flags = flags;
-
- ret->fd = sys_open(fname, flags, mode);
- if (ret->fd == -1) {
- SAFE_FREE(ret);
- return NULL;
- }
-
- x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE);
-
- return ret;
-}
-
-/* simulate fclose() */
-int x_fclose(XFILE *f)
-{
- int ret;
-
- /* make sure we flush any buffered data */
- x_fflush(f);
-
- ret = close(f->fd);
- f->fd = -1;
- if (f->buf) {
- /* make sure data can't leak into a later malloc */
- memset(f->buf, 0, f->bufsize);
- SAFE_FREE(f->buf);
- }
- SAFE_FREE(f);
- return ret;
-}
-
-/* simulate fwrite() */
-size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f)
-{
- ssize_t ret;
- size_t total=0;
-
- /* we might be writing unbuffered */
- if (f->buftype == X_IONBF ||
- (!f->buf && !x_allocate_buffer(f))) {
- ret = write(f->fd, p, size*nmemb);
- if (ret == -1) return -1;
- return ret/size;
- }
-
-
- while (total < size*nmemb) {
- size_t n = f->bufsize - f->bufused;
- n = MIN(n, (size*nmemb)-total);
-
- if (n == 0) {
- /* it's full, flush it */
- x_fflush(f);
- continue;
- }
-
- memcpy(f->buf + f->bufused, total+(const char *)p, n);
- f->bufused += n;
- total += n;
- }
-
- /* when line buffered we need to flush at the last linefeed. This can
- flush a bit more than necessary, but that is harmless */
- if (f->buftype == X_IOLBF && f->bufused) {
- int i;
- for (i=(size*nmemb)-1; i>=0; i--) {
- if (*(i+(const char *)p) == '\n') {
- x_fflush(f);
- break;
- }
- }
- }
-
- return total/size;
-}
-
-/* thank goodness for asprintf() */
- int x_vfprintf(XFILE *f, const char *format, va_list ap)
-{
- char *p;
- int len, ret;
- va_list ap2;
-
- VA_COPY(ap2, ap);
-
- len = vasprintf(&p, format, ap2);
- if (len <= 0) return len;
- ret = x_fwrite(p, 1, len, f);
- SAFE_FREE(p);
- return ret;
-}
-
- int x_fprintf(XFILE *f, const char *format, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, format);
- ret = x_vfprintf(f, format, ap);
- va_end(ap);
- return ret;
-}
-
-/* at least fileno() is simple! */
-int x_fileno(XFILE *f)
-{
- return f->fd;
-}
-
-/* simulate fflush() */
-int x_fflush(XFILE *f)
-{
- int ret;
-
- if (f->flags & X_FLAG_ERROR) return -1;
-
- if ((f->open_flags & O_ACCMODE) != O_WRONLY) {
- errno = EINVAL;
- return -1;
- }
-
- if (f->bufused == 0) return 0;
-
- ret = write(f->fd, f->buf, f->bufused);
- if (ret == -1) return -1;
-
- f->bufused -= ret;
- if (f->bufused > 0) {
- f->flags |= X_FLAG_ERROR;
- memmove(f->buf, ret + (char *)f->buf, f->bufused);
- return -1;
- }
-
- return 0;
-}
-
-/* simulate setbuffer() */
-void x_setbuffer(XFILE *f, char *buf, size_t size)
-{
- x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, size);
-}
-
-/* simulate setbuf() */
-void x_setbuf(XFILE *f, char *buf)
-{
- x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, XBUFSIZE);
-}
-
-/* simulate setlinebuf() */
-void x_setlinebuf(XFILE *f)
-{
- x_setvbuf(f, NULL, X_IOLBF, 0);
-}
-
-
-/* simulate feof() */
-int x_feof(XFILE *f)
-{
- if (f->flags & X_FLAG_EOF) return 1;
- return 0;
-}
-
-/* simulate ferror() */
-int x_ferror(XFILE *f)
-{
- if (f->flags & X_FLAG_ERROR) return 1;
- return 0;
-}
-
-/* fill the read buffer */
-static void x_fillbuf(XFILE *f)
-{
- int n;
-
- if (f->bufused) return;
-
- if (!f->buf && !x_allocate_buffer(f)) return;
-
- n = read(f->fd, f->buf, f->bufsize);
- if (n <= 0) return;
- f->bufused = n;
- f->next = f->buf;
-}
-
-/* simulate fgetc() */
-int x_fgetc(XFILE *f)
-{
- int ret;
-
- if (f->flags & (X_FLAG_EOF | X_FLAG_ERROR)) return EOF;
-
- if (f->bufused == 0) x_fillbuf(f);
-
- if (f->bufused == 0) {
- f->flags |= X_FLAG_EOF;
- return EOF;
- }
-
- ret = *(unsigned char *)(f->next);
- f->next++;
- f->bufused--;
- return ret;
-}
-
-/* simulate fread */
-size_t x_fread(void *p, size_t size, size_t nmemb, XFILE *f)
-{
- size_t total = 0;
- while (total < size*nmemb) {
- int c = x_fgetc(f);
- if (c == EOF) break;
- (total+(char *)p)[0] = (char)c;
- total++;
- }
- return total/size;
-}
-
-/* simulate fgets() */
-char *x_fgets(char *s, int size, XFILE *stream)
-{
- char *s0 = s;
- int l = size;
- while (l>1) {
- int c = x_fgetc(stream);
- if (c == EOF) break;
- *s++ = (char)c;
- l--;
- if (c == '\n') break;
- }
- if (l==size || x_ferror(stream)) {
- return 0;
- }
- *s = 0;
- return s0;
-}
-
-/* trivial seek, works only for SEEK_SET and SEEK_END if SEEK_CUR is
- * set then an error is returned */
-off_t x_tseek(XFILE *f, off_t offset, int whence)
-{
- if (f->flags & X_FLAG_ERROR)
- return -1;
-
- /* only SEEK_SET and SEEK_END are supported */
- /* SEEK_CUR needs internal offset counter */
- if (whence != SEEK_SET && whence != SEEK_END) {
- f->flags |= X_FLAG_EINVAL;
- errno = EINVAL;
- return -1;
- }
-
- /* empty the buffer */
- switch (f->open_flags & O_ACCMODE) {
- case O_RDONLY:
- f->bufused = 0;
- break;
- case O_WRONLY:
- if (x_fflush(f) != 0)
- return -1;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
-
- f->flags &= ~X_FLAG_EOF;
- return (off_t)sys_lseek(f->fd, offset, whence);
-}
diff --git a/source/libads/ads_ldap.c b/source/libads/ads_ldap.c
deleted file mode 100644
index 944cb1599cc..00000000000
--- a/source/libads/ads_ldap.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind ADS backend functions
-
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#ifdef HAVE_LDAP
-
-/* convert a single name to a sid in a domain */
-NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
- int count;
- ADS_STATUS rc;
- void *res = NULL;
- char *ldap_exp;
- uint32 t;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- char *escaped_name = escape_ldap_string_alloc(name);
- char *escaped_realm = escape_ldap_string_alloc(ads->config.realm);
-
- if (!escaped_name || !escaped_realm) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
- escaped_name, escaped_name, escaped_realm) == -1) {
- DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- rc = ads_search_retry(ads, &res, ldap_exp, attrs);
- free(ldap_exp);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count != 1) {
- DEBUG(1,("name_to_sid: %s not found\n", name));
- goto done;
- }
-
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- goto done;
- }
-
- if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) {
- DEBUG(1,("No sAMAccountType for %s !?\n", name));
- goto done;
- }
-
- *type = ads_atype_map(t);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads name_to_sid mapped %s\n", name));
-
-done:
- if (res) ads_msgfree(ads, res);
-
- SAFE_FREE(escaped_name);
- SAFE_FREE(escaped_realm);
-
- return status;
-}
-
-/* convert a sid to a user or group name */
-NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "sAMAccountType", NULL};
- ADS_STATUS rc;
- void *msg = NULL;
- char *ldap_exp = NULL;
- char *sidstr = NULL;
- uint32 atype;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- if (!(sidstr = sid_binstring(sid))) {
- DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) {
- DEBUG(1,("ads_sid_to_name: asprintf failed!\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
- if (!ADS_ERR_OK(rc)) {
- status = ads_ntstatus(rc);
- DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
- goto done;
- }
-
- *name = ads_pull_username(ads, mem_ctx, msg);
- if (!*name) {
- DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- *type = ads_atype_map(atype);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads sid_to_name mapped %s\n", *name));
-
-done:
- if (msg) ads_msgfree(ads, msg);
-
- SAFE_FREE(ldap_exp);
- SAFE_FREE(sidstr);
-
- return status;
-}
-
-
-/* convert a sid to a DN */
-
-ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **dn)
-{
- ADS_STATUS rc;
- LDAPMessage *msg = NULL;
- LDAPMessage *entry = NULL;
- char *ldap_exp;
- char *sidstr = NULL;
- int count;
- char *dn2 = NULL;
-
- const char *attr[] = {
- "dn",
- NULL
- };
-
- if (!(sidstr = sid_binstring(sid))) {
- DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n"));
- rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- goto done;
- }
-
- if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) {
- DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n"));
- rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- goto done;
- }
-
- rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr);
-
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- if ((count = ads_count_replies(ads, msg)) != 1) {
- fstring sid_string;
- DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n",
- sid_to_string(sid_string, sid), count));
- rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- goto done;
- }
-
- entry = ads_first_entry(ads, msg);
-
- dn2 = ads_get_dn(ads, entry);
-
- if (!dn2) {
- rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- goto done;
- }
-
- *dn = talloc_strdup(mem_ctx, dn2);
-
- if (!*dn) {
- ads_memfree(ads, dn2);
- rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- goto done;
- }
-
- rc = ADS_ERROR_NT(NT_STATUS_OK);
-
- DEBUG(3,("ads sid_to_dn mapped %s\n", dn2));
-
- SAFE_FREE(dn2);
-done:
- if (msg) ads_msgfree(ads, msg);
- if (dn2) ads_memfree(ads, dn2);
-
- SAFE_FREE(sidstr);
-
- return rc;
-}
-
-#endif
diff --git a/source/libads/ads_status.c b/source/libads/ads_status.c
deleted file mode 100644
index 463f647f9c7..00000000000
--- a/source/libads/ads_status.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Remus Koos 2001
- Copyright (C) Andrew Bartlett 2001
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- build a ADS_STATUS structure
-*/
-ADS_STATUS ads_build_error(enum ads_error_type etype,
- int rc, int minor_status)
-{
- ADS_STATUS ret;
-
- if (etype == ENUM_ADS_ERROR_NT) {
- DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n"));
- ret.err.rc = -1;
- ret.error_type = ENUM_ADS_ERROR_SYSTEM;
- ret.minor_status = 0;
- return ret;
- }
-
- ret.err.rc = rc;
- ret.error_type = etype;
- ret.minor_status = minor_status;
- return ret;
-}
-
-ADS_STATUS ads_build_nt_error(enum ads_error_type etype,
- NTSTATUS nt_status)
-{
- ADS_STATUS ret;
-
- if (etype != ENUM_ADS_ERROR_NT) {
- DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n"));
- ret.err.rc = -1;
- ret.error_type = ENUM_ADS_ERROR_SYSTEM;
- ret.minor_status = 0;
- return ret;
- }
- ret.err.nt_status = nt_status;
- ret.error_type = etype;
- ret.minor_status = 0;
- return ret;
-}
-
-/*
- do a rough conversion between ads error codes and NT status codes
- we'll need to fill this in more
-*/
-NTSTATUS ads_ntstatus(ADS_STATUS status)
-{
- if (status.error_type == ENUM_ADS_ERROR_NT){
- return status.err.nt_status;
- }
-#ifdef HAVE_LDAP
- if ((status.error_type == ENUM_ADS_ERROR_LDAP)
- && (status.err.rc == LDAP_NO_MEMORY)) {
- return NT_STATUS_NO_MEMORY;
- }
-#endif
-#ifdef HAVE_KRB5
- if (status.error_type == ENUM_ADS_ERROR_KRB5) {
- if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) {
- return NT_STATUS_LOGON_FAILURE;
- } else if (status.err.rc == KRB5_KDC_UNREACH) {
- return NT_STATUS_NO_LOGON_SERVERS;
- }
- }
-#endif
- if (ADS_ERR_OK(status)) return NT_STATUS_OK;
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/*
- return a string for an error from a ads routine
-*/
-const char *ads_errstr(ADS_STATUS status)
-{
- uint32 msg_ctx;
- static char *ret;
-
- SAFE_FREE(ret);
- msg_ctx = 0;
-
- switch (status.error_type) {
- case ENUM_ADS_ERROR_SYSTEM:
- return strerror(status.err.rc);
-#ifdef HAVE_LDAP
- case ENUM_ADS_ERROR_LDAP:
- return ldap_err2string(status.err.rc);
-#endif
-#ifdef HAVE_KRB5
- case ENUM_ADS_ERROR_KRB5:
- return error_message(status.err.rc);
-#endif
-#ifdef HAVE_GSSAPI
- case ENUM_ADS_ERROR_GSS:
- {
- uint32 minor;
-
- gss_buffer_desc msg1, msg2;
- msg1.value = NULL;
- msg2.value = NULL;
- gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE,
- GSS_C_NULL_OID, &msg_ctx, &msg1);
- gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE,
- GSS_C_NULL_OID, &msg_ctx, &msg2);
- asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value);
- gss_release_buffer(&minor, &msg1);
- gss_release_buffer(&minor, &msg2);
- return ret;
- }
-#endif
- case ENUM_ADS_ERROR_NT:
- return get_friendly_nt_error_msg(ads_ntstatus(status));
- default:
- return "Unknown ADS error type!? (not compiled in?)";
- }
-
-}
-
-
diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c
deleted file mode 100644
index 92f37093f46..00000000000
--- a/source/libads/ads_struct.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* return a ldap dn path from a string, given separators and field name
- caller must free
-*/
-char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse)
-{
- char *p, *r;
- int numbits = 0;
- char *ret;
- int len;
-
- r = strdup(realm);
-
- if (!r || !*r)
- return r;
-
- for (p=r; *p; p++)
- if (strchr(sep, *p))
- numbits++;
-
- len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
-
- ret = malloc(len);
- if (!ret)
- return NULL;
-
- strlcpy(ret,field, len);
- p=strtok(r,sep);
- strlcat(ret, p, len);
-
- while ((p=strtok(NULL,sep))) {
- char *s;
- if (reverse)
- asprintf(&s, "%s%s,%s", field, p, ret);
- else
- asprintf(&s, "%s,%s%s", ret, field, p);
- free(ret);
- ret = s;
- }
-
- free(r);
- return ret;
-}
-
-/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a
- realm of the form AA.BB.CC
- caller must free
-*/
-char *ads_build_dn(const char *realm)
-{
- return ads_build_path(realm, ".", "dc=", 0);
-}
-
-
-#ifndef LDAP_PORT
-#define LDAP_PORT 389
-#endif
-
-/*
- initialise a ADS_STRUCT, ready for some ads_ ops
-*/
-ADS_STRUCT *ads_init(const char *realm,
- const char *workgroup,
- const char *ldap_server)
-{
- ADS_STRUCT *ads;
-
- ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads));
- ZERO_STRUCTP(ads);
-
- ads->server.realm = realm? strdup(realm) : NULL;
- ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
- ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
-
- /* we need to know if this is a foreign realm */
- if (realm && *realm && !strequal(lp_realm(), realm)) {
- ads->server.foreign = 1;
- }
- if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) {
- ads->server.foreign = 1;
- }
-
- /* the caller will own the memory by default */
- ads->is_mine = 1;
-
- return ads;
-}
-
-/*
- free the memory used by the ADS structure initialized with 'ads_init(...)'
-*/
-void ads_destroy(ADS_STRUCT **ads)
-{
- if (ads && *ads) {
- BOOL is_mine;
-
- is_mine = (*ads)->is_mine;
-#if HAVE_LDAP
- if ((*ads)->ld) ldap_unbind((*ads)->ld);
-#endif
- SAFE_FREE((*ads)->server.realm);
- SAFE_FREE((*ads)->server.workgroup);
- SAFE_FREE((*ads)->server.ldap_server);
- SAFE_FREE((*ads)->server.ldap_uri);
-
- SAFE_FREE((*ads)->auth.realm);
- SAFE_FREE((*ads)->auth.password);
- SAFE_FREE((*ads)->auth.user_name);
- SAFE_FREE((*ads)->auth.kdc_server);
-
- SAFE_FREE((*ads)->config.realm);
- SAFE_FREE((*ads)->config.bind_path);
- SAFE_FREE((*ads)->config.ldap_server_name);
-
-
- ZERO_STRUCTP(*ads);
-
- if ( is_mine )
- SAFE_FREE(*ads);
- }
-}
diff --git a/source/libads/ads_utils.c b/source/libads/ads_utils.c
deleted file mode 100644
index 1aad0bed547..00000000000
--- a/source/libads/ads_utils.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
-
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
-uint32 ads_acb2uf(uint16 acb)
-{
- uint32 uf = 0x00000000;
-
- if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE;
- if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED;
- if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD;
- if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT;
- if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT;
- if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT;
- if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
- if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT;
- if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT;
- if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD;
- if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT;
-
- return uf;
-}
-
-/*
-translated the UserFlags (userAccountControl) to ACB_CTRL Flags
-*/
-uint16 ads_uf2acb(uint32 uf)
-{
- uint16 acb = 0x0000;
-
- if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED;
- if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ;
- if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ;
- if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS;
- if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP;
- if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK;
-
- switch (uf & UF_ACCOUNT_TYPE_MASK)
- {
- case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break;
- case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break;
- case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break;
- case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break;
- case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break;
- /*Fix Me: what should we do here? */
- default: acb |= ACB_NORMAL;break;
- }
-
- return acb;
-}
-
-/*
-get the accountType from the UserFlags
-*/
-uint32 ads_uf2atype(uint32 uf)
-{
- uint32 atype = 0x00000000;
-
- if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
-
- return atype;
-}
-
-/*
-get the accountType from the groupType
-*/
-uint32 ads_gtype2atype(uint32 gtype)
-{
- uint32 atype = 0x00000000;
-
- switch(gtype) {
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_GLOBAL_GROUP:
- atype = ATYPE_SECURITY_GLOBAL_GROUP;
- break;
-
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
- break;
- }
-
- return atype;
-}
-
-/* turn a sAMAccountType into a SID_NAME_USE */
-enum SID_NAME_USE ads_atype_map(uint32 atype)
-{
- switch (atype & 0xF0000000) {
- case ATYPE_GLOBAL_GROUP:
- return SID_NAME_DOM_GRP;
- case ATYPE_SECURITY_LOCAL_GROUP:
- return SID_NAME_ALIAS;
- case ATYPE_ACCOUNT:
- return SID_NAME_USER;
- default:
- DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
- }
- return SID_NAME_UNKNOWN;
-}
diff --git a/source/libads/authdata.c b/source/libads/authdata.c
deleted file mode 100644
index 29170af377e..00000000000
--- a/source/libads/authdata.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- kerberos authorization data (PAC) utility library
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
-{
- DATA_BLOB pac_contents;
- ASN1_DATA data;
- int data_type;
-
- asn1_load(&data, *auth_data);
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_CONTEXT(0));
- asn1_read_Integer(&data, &data_type);
- asn1_end_tag(&data);
- asn1_start_tag(&data, ASN1_CONTEXT(1));
- asn1_read_OctetString(&data, &pac_contents);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_free(&data);
- return pac_contents;
-}
-
-static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10,
- prs_struct *ps, int depth)
-{
- if (NULL == type_10)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_unknown_type_10");
- depth++;
-
- if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth))
- return False;
-
- if (!prs_uint16("len", ps, depth, &type_10->len))
- return False;
-
- if (UNMARSHALLING(ps) && type_10->len) {
- type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len);
- if (!type_10->username) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
-
- if (!prs_uint16s(True, "name", ps, depth, type_10->username,
- (type_10->len / sizeof(uint16))))
- return False;
-
- return True;
-
-}
-
-
-static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
- prs_struct *ps, int depth)
-{
- if (NULL == sid_and_attr)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_krb_sids");
- depth++;
-
- if (UNMARSHALLING(ps)) {
- sid_and_attr->sid =
- (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2));
- if (!sid_and_attr->sid) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
-
- if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth))
- return False;
-
- return True;
-}
-
-
-static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
- prs_struct *ps, int depth)
-{
- if (NULL == sid_and_attr)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_krb_attrs");
- depth++;
-
- if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr))
- return False;
- if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs))
- return False;
-
- return True;
-}
-
-static BOOL pac_io_krb_sid_and_attr_array(const char *desc,
- KRB_SID_AND_ATTR_ARRAY *array,
- uint32 num,
- prs_struct *ps, int depth)
-{
- int i;
-
- if (NULL == array)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array");
- depth++;
-
-
- if (!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (UNMARSHALLING(ps)) {
- array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *)
- prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num);
- if (!array->krb_sid_and_attrs) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
-
- for (i=0; i<num; i++) {
- if (!pac_io_krb_attrs(desc,
- &array->krb_sid_and_attrs[i],
- ps, depth))
- return False;
-
- }
- for (i=0; i<num; i++) {
- if (!pac_io_krb_sids(desc,
- &array->krb_sid_and_attrs[i],
- ps, depth))
- return False;
-
- }
-
- return True;
-
-}
-
-static BOOL pac_io_group_membership(const char *desc,
- GROUP_MEMBERSHIP *membership,
- prs_struct *ps, int depth)
-{
- if (NULL == membership)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_group_membership");
- depth++;
-
- if (!prs_uint32("rid", ps, depth, &membership->rid))
- return False;
- if (!prs_uint32("attrs", ps, depth, &membership->attrs))
- return False;
-
- return True;
-}
-
-
-static BOOL pac_io_group_membership_array(const char *desc,
- GROUP_MEMBERSHIP_ARRAY *array,
- uint32 num,
- prs_struct *ps, int depth)
-{
- int i;
-
- if (NULL == array)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_group_membership_array");
- depth++;
-
-
- if (!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (UNMARSHALLING(ps)) {
- array->group_membership = (GROUP_MEMBERSHIP *)
- prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num);
- if (!array->group_membership) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
-
- for (i=0; i<num; i++) {
- if (!pac_io_group_membership(desc,
- &array->group_membership[i],
- ps, depth))
- return False;
-
- }
-
- return True;
-
-}
-
-static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
- prs_struct *ps, int depth)
-{
- uint32 garbage;
- if (NULL == info)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
- depth++;
-
- if (!prs_uint32("unknown", ps, depth, &garbage))
- return False;
- if (!prs_uint32("unknown", ps, depth, &garbage))
- return False;
- if (!prs_uint32("bufferlen", ps, depth, &garbage))
- return False;
- if (!prs_uint32("bufferlenhi", ps, depth, &garbage))
- return False;
- if (!prs_uint32("pointer", ps, depth, &garbage))
- return False;
-
- if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
- return False;
- if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
- return False;
- if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth))
- return False;
- if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time,
- ps, depth))
- return False;
- if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time,
- ps, depth))
- return False;
- if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time,
- ps, depth))
- return False;
-
- if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script,
- ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path,
- ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
- return False;
-
- if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
- return False;
- if (!prs_uint16("reserved12", ps, depth, &info->reserved12))
- return False;
- if (!prs_uint32("user_rid", ps, depth, &info->user_rid))
- return False;
- if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
- return False;
- if (!prs_uint32("group_count", ps, depth, &info->group_count))
- return False;
- /* I haven't seen this contain anything yet, but when it does
- we will have to make sure we decode the contents in the middle
- all the unistr2s ... */
- if (!prs_uint32("group_mem_ptr", ps, depth,
- &info->group_membership_ptr))
- return False;
- if (!prs_uint32("user_flags", ps, depth, &info->user_flags))
- return False;
-
- if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0]))
- return False;
- if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1]))
- return False;
- if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2]))
- return False;
- if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3]))
- return False;
-
- if (!smb_io_unihdr("hdr_dom_controller",
- &info->hdr_dom_controller, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
- return False;
-
- /* this should be followed, but just get ptr for now */
- if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid))
- return False;
-
- if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0]))
- return False;
- if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1]))
- return False;
-
- /* might be acb_info */
- if (!prs_uint32("reserved17", ps, depth, &info->reserved17))
- return False;
-
-
- if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0]))
- return False;
- if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1]))
- return False;
- if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2]))
- return False;
- if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3]))
- return False;
- if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4]))
- return False;
- if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5]))
- return False;
- if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6]))
- return False;
-
- if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
- return False;
- if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids))
- return False;
- if (!prs_uint32("ptr_res_group_dom_sid", ps, depth,
- &info->ptr_res_group_dom_sid))
- return False;
- if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count))
- return False;
- if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups))
- return False;
-
- if(!smb_io_unistr2("uni_user_name", &info->uni_user_name,
- info->hdr_user_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_full_name", &info->uni_full_name,
- info->hdr_full_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
- info->hdr_logon_script.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path,
- info->hdr_profile_path.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir,
- info->hdr_home_dir.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
- info->hdr_dir_drive.buffer, ps, depth))
- return False;
-
- if (info->group_membership_ptr) {
- if (!pac_io_group_membership_array("group membership",
- &info->groups,
- info->group_count,
- ps, depth))
- return False;
- }
-
-
- if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller,
- info->hdr_dom_controller.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
- info->hdr_dom_name.buffer, ps, depth))
- return False;
-
- if(info->ptr_dom_sid)
- if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
- return False;
-
-
- if (info->sid_count && info->ptr_extra_sids)
- if (!pac_io_krb_sid_and_attr_array("extra_sids",
- &info->extra_sids,
- info->sid_count,
- ps, depth))
- return False;
-
- if (info->ptr_res_group_dom_sid)
- if (!smb_io_dom_sid2("res_group_dom_sid",
- &info->res_group_dom_sid, ps, depth))
- return False;
-
- if (info->ptr_res_groups)
- if (!pac_io_group_membership_array("res group membership",
- &info->res_groups,
- info->res_group_count,
- ps, depth))
- return False;
-
- return True;
-}
-
-
-static BOOL pac_io_pac_signature_data(const char *desc,
- PAC_SIGNATURE_DATA *data, uint32 length,
- prs_struct *ps, int depth)
-{
- uint32 siglen = length - sizeof(uint32);
- if (NULL == data)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_pac_signature_data");
- depth++;
-
- if (!prs_uint32("type", ps, depth, &data->type))
- return False;
- if (UNMARSHALLING(ps)) {
- data->signature = (unsigned char *)prs_alloc_mem(ps, siglen);
- if (!data->signature) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
- if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen))
- return False;
-
- return True;
-}
-
-static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
- prs_struct *ps, int depth)
-{
- if (NULL == hdr)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (hdr->offset != prs_offset(ps)) {
- DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
- hdr->offset, prs_offset(ps)));
- prs_set_offset(ps, hdr->offset);
- }
-
- if (UNMARSHALLING(ps) && hdr->size > 0) {
- hdr->ctr = (PAC_INFO_CTR *)
- prs_alloc_mem(ps, sizeof(PAC_INFO_CTR));
- if (!hdr->ctr) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- }
-
- switch(hdr->type) {
- case PAC_TYPE_LOGON_INFO:
- DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
- if (UNMARSHALLING(ps))
- hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *)
- prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO));
- if (!hdr->ctr->pac.logon_info) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info,
- ps, depth))
- return False;
- break;
-
- case PAC_TYPE_SERVER_CHECKSUM:
- DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
- if (UNMARSHALLING(ps))
- hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *)
- prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
- if (!hdr->ctr->pac.srv_cksum) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum,
- hdr->size, ps, depth))
- return False;
- break;
-
- case PAC_TYPE_PRIVSVR_CHECKSUM:
- DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
- if (UNMARSHALLING(ps))
- hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *)
- prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
- if (!hdr->ctr->pac.privsrv_cksum) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- if (!pac_io_pac_signature_data(desc,
- hdr->ctr->pac.privsrv_cksum,
- hdr->size, ps, depth))
- return False;
- break;
-
- case PAC_TYPE_UNKNOWN_10:
- DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n"));
- if (UNMARSHALLING(ps))
- hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *)
- prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10));
- if (!hdr->ctr->pac.type_10) {
- DEBUG(3, ("No memory available\n"));
- return False;
- }
- if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10,
- ps, depth))
- return False;
- break;
-
- default:
- /* dont' know, so we need to skip it */
- DEBUG(3, ("unknown PAC type %d\n", hdr->type));
- prs_set_offset(ps, prs_offset(ps) + hdr->size);
- }
-
- return True;
-}
-
-static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr,
- prs_struct *ps, int depth)
-{
- if (NULL == hdr)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_pac_info_hdr");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("type", ps, depth, &hdr->type))
- return False;
- if (!prs_uint32("size", ps, depth, &hdr->size))
- return False;
- if (!prs_uint32("offset", ps, depth, &hdr->offset))
- return False;
- if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi))
- return False;
-
- return True;
-}
-
-static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
- prs_struct *ps, int depth)
-{
- int i;
-
- if (NULL == data)
- return False;
-
- prs_debug(ps, depth, desc, "pac_io_pac_data");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers))
- return False;
- if (!prs_uint32("version", ps, depth, &data->version))
- return False;
-
- if (UNMARSHALLING(ps) && data->num_buffers > 0) {
- if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *)
- prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) *
- data->num_buffers)) == NULL) {
- return False;
- }
- }
-
- for (i=0; i<data->num_buffers; i++) {
- if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps,
- depth))
- return False;
- }
-
- for (i=0; i<data->num_buffers; i++) {
- if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i],
- ps, depth))
- return False;
- }
-
- return True;
-}
-
-PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
-{
- DATA_BLOB pac_data_blob = unwrap_pac(auth_data);
- prs_struct ps;
- PAC_DATA *pac_data;
-
- DEBUG(5,("dump_pac_data\n"));
- prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
- prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
- prs_set_offset(&ps, 0);
-
- data_blob_free(&pac_data_blob);
-
- pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA));
- pac_io_pac_data("pac data", pac_data, &ps, 0);
-
- prs_mem_free(&ps);
-
- return pac_data;
-}
-
-#endif
diff --git a/source/libads/disp_sec.c b/source/libads/disp_sec.c
deleted file mode 100644
index c9de447e698..00000000000
--- a/source/libads/disp_sec.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions. ADS stuff
- Copyright (C) Alexey Kotovich 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static struct perm_mask_str {
- uint32 mask;
- const char *str;
-} perms[] = {
- {SEC_RIGHTS_FULL_CTRL, "[Full Control]"},
-
- {SEC_RIGHTS_LIST_CONTENTS, "[List Contents]"},
- {SEC_RIGHTS_LIST_OBJECT, "[List Object]"},
-
- {SEC_RIGHTS_READ_ALL_PROP, "[Read All Properties]"},
- {SEC_RIGHTS_READ_PERMS, "[Read Permissions]"},
-
- {SEC_RIGHTS_WRITE_ALL_VALID, "[All validate writes]"},
- {SEC_RIGHTS_WRITE_ALL_PROP, "[Write All Properties]"},
-
- {SEC_RIGHTS_MODIFY_PERMS, "[Modify Permissions]"},
- {SEC_RIGHTS_MODIFY_OWNER, "[Modify Owner]"},
-
- {SEC_RIGHTS_CREATE_CHILD, "[Create All Child Objects]"},
-
- {SEC_RIGHTS_DELETE, "[Delete]"},
- {SEC_RIGHTS_DELETE_SUBTREE, "[Delete Subtree]"},
- {SEC_RIGHTS_DELETE_CHILD, "[Delete All Child Objects]"},
-
- {SEC_RIGHTS_CHANGE_PASSWD, "[Change Password]"},
- {SEC_RIGHTS_RESET_PASSWD, "[Reset Password]"},
- {0, 0}
-};
-
-/* convert a security permissions into a string */
-static void ads_disp_perms(uint32 type)
-{
- int i = 0;
- int j = 0;
-
- printf("Permissions: ");
-
- if (type == SEC_RIGHTS_FULL_CTRL) {
- printf("%s\n", perms[j].str);
- return;
- }
-
- for (i = 0; i < 32; i++) {
- if (type & (1 << i)) {
- for (j = 1; perms[j].str; j ++) {
- if (perms[j].mask == (((unsigned) 1) << i)) {
- printf("\n\t%s", perms[j].str);
- }
- }
- type &= ~(1 << i);
- }
- }
-
- /* remaining bits get added on as-is */
- if (type != 0) {
- printf("[%08x]", type);
- }
- puts("");
-}
-
-/* display ACE */
-static void ads_disp_ace(SEC_ACE *sec_ace)
-{
- const char *access_type = "UNKNOWN";
-
- if (!sec_ace_object(sec_ace->type)) {
- printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x)\n",
- sec_ace->type,
- sec_ace->flags,
- sec_ace->size,
- sec_ace->info.mask);
- } else {
- printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x, object flags: 0x%x)\n",
- sec_ace->type,
- sec_ace->flags,
- sec_ace->size,
- sec_ace->info.mask,
- sec_ace->obj_flags);
- }
-
- if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
- access_type = "ALLOWED";
- } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
- access_type = "DENIED";
- } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT) {
- access_type = "SYSTEM AUDIT";
- } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
- access_type = "ALLOWED OBJECT";
- } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) {
- access_type = "DENIED OBJECT";
- } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) {
- access_type = "AUDIT OBJECT";
- }
-
- printf("access SID: %s\naccess type: %s\n",
- sid_string_static(&sec_ace->trustee), access_type);
-
- ads_disp_perms(sec_ace->info.mask);
-}
-
-/* display ACL */
-static void ads_disp_acl(SEC_ACL *sec_acl, const char *type)
-{
- if (!sec_acl)
- printf("------- (%s) ACL not present\n", type);
- else {
- printf("------- (%s) ACL (revision: %d, size: %d, number of ACEs: %d)\n",
- type,
- sec_acl->revision,
- sec_acl->size,
- sec_acl->num_aces);
- }
-}
-
-/* display SD */
-void ads_disp_sd(SEC_DESC *sd)
-{
- int i;
-
- printf("-------------- Security Descriptor (revision: %d, type: 0x%02x)\n",
- sd->revision,
- sd->type);
- printf("owner SID: %s\n", sid_string_static(sd->owner_sid));
- printf("group SID: %s\n", sid_string_static(sd->grp_sid));
-
- ads_disp_acl(sd->sacl, "system");
- for (i = 0; i < sd->sacl->num_aces; i ++)
- ads_disp_ace(&sd->sacl->ace[i]);
-
- ads_disp_acl(sd->dacl, "user");
- for (i = 0; i < sd->dacl->num_aces; i ++)
- ads_disp_ace(&sd->dacl->ace[i]);
-
- printf("-------------- End Of Security Descriptor\n");
-}
-
-
diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c
deleted file mode 100644
index 70f6f3386c7..00000000000
--- a/source/libads/kerberos.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- kerberos utility library
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Remus Koos 2001
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-/*
- we use a prompter to avoid a crash bug in the kerberos libs when
- dealing with empty passwords
- this prompter is just a string copy ...
-*/
-static krb5_error_code
-kerb_prompter(krb5_context ctx, void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[])
-{
- if (num_prompts == 0) return 0;
-
- memset(prompts[0].reply->data, 0, prompts[0].reply->length);
- if (prompts[0].reply->length > 0) {
- if (data) {
- strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1);
- prompts[0].reply->length = strlen(prompts[0].reply->data);
- } else {
- prompts[0].reply->length = 0;
- }
- }
- return 0;
-}
-
-/*
- simulate a kinit, putting the tgt in the default cache location
- remus@snapserver.com
-*/
-int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time)
-{
- krb5_context ctx;
- krb5_error_code code = 0;
- krb5_ccache cc;
- krb5_principal me;
- krb5_creds my_creds;
-
- if ((code = krb5_init_context(&ctx)))
- return code;
-
- if (time_offset != 0) {
- krb5_set_real_time(ctx, time(NULL) + time_offset, 0);
- }
-
- if ((code = krb5_cc_default(ctx, &cc))) {
- krb5_free_context(ctx);
- return code;
- }
-
- if ((code = krb5_parse_name(ctx, principal, &me))) {
- krb5_free_context(ctx);
- return code;
- }
-
- if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL,
- kerb_prompter,
- password, 0, NULL, NULL))) {
- krb5_free_principal(ctx, me);
- krb5_free_context(ctx);
- return code;
- }
-
- if ((code = krb5_cc_initialize(ctx, cc, me))) {
- krb5_free_cred_contents(ctx, &my_creds);
- krb5_free_principal(ctx, me);
- krb5_free_context(ctx);
- return code;
- }
-
- if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
- krb5_cc_close(ctx, cc);
- krb5_free_cred_contents(ctx, &my_creds);
- krb5_free_principal(ctx, me);
- krb5_free_context(ctx);
- return code;
- }
-
- if (expire_time)
- *expire_time = (time_t) my_creds.times.endtime;
-
- krb5_cc_close(ctx, cc);
- krb5_free_cred_contents(ctx, &my_creds);
- krb5_free_principal(ctx, me);
- krb5_free_context(ctx);
-
- return 0;
-}
-
-
-
-/* run kinit to setup our ccache */
-int ads_kinit_password(ADS_STRUCT *ads)
-{
- char *s;
- int ret;
-
- if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) {
- return KRB5_CC_NOMEM;
- }
-
- if (!ads->auth.password) {
- return KRB5_LIBOS_CANTREADPWD;
- }
-
- ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire);
-
- if (ret) {
- DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
- s, error_message(ret)));
- }
- free(s);
- return ret;
-}
-
-int ads_kdestroy(const char *cc_name)
-{
- krb5_error_code code;
- krb5_context ctx;
- krb5_ccache cc;
-
- if ((code = krb5_init_context (&ctx))) {
- DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code));
- return code;
- }
-
- if (!cc_name) {
- if ((code = krb5_cc_default(ctx, &cc))) {
- krb5_free_context(ctx);
- return code;
- }
- } else {
- if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) {
- DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n",
- code));
- krb5_free_context(ctx);
- return code;
- }
- }
-
- if ((code = krb5_cc_destroy (ctx, cc))) {
- DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code));
- }
-
- krb5_free_context (ctx);
- return code;
-}
-
-#endif
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
deleted file mode 100644
index 47559c1abb7..00000000000
--- a/source/libads/kerberos_verify.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- kerberos utility library
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Remus Koos 2001
- Copyright (C) Luke Howard 2003
- Copyright (C) Guenther Deschner 2003
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-/*
- verify an incoming ticket and parse out the principal name and
- authorization_data if available
-*/
-NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
- char **principal, DATA_BLOB *auth_data,
- DATA_BLOB *ap_rep,
- DATA_BLOB *session_key)
-{
- NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
- krb5_context context = NULL;
- krb5_auth_context auth_context = NULL;
- krb5_data packet;
- krb5_ticket *tkt = NULL;
- krb5_rcache rcache = NULL;
- int ret, i;
- krb5_keyblock *key = NULL;
-
- krb5_principal host_princ;
- char *host_princ_s = NULL;
- BOOL free_host_princ = False;
- BOOL got_replay_mutex = False;
-
- fstring myname;
- char *password_s = NULL;
- krb5_data password;
- krb5_enctype *enctypes = NULL;
-#if 0
- krb5_address local_addr;
- krb5_address remote_addr;
-#endif
- BOOL auth_ok = False;
-
- ZERO_STRUCT(packet);
- ZERO_STRUCT(password);
- ZERO_STRUCTP(auth_data);
- ZERO_STRUCTP(ap_rep);
-
- if (!secrets_init()) {
- DEBUG(1,("ads_verify_ticket: secrets_init failed\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- if (!password_s) {
- DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- password.data = password_s;
- password.length = strlen(password_s);
-
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- ret = krb5_set_default_realm(context, realm);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- /* This whole process is far more complex than I would
- like. We have to go through all this to allow us to store
- the secret internally, instead of using /etc/krb5.keytab */
-
- ret = krb5_auth_con_init(context, &auth_context);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- fstrcpy(myname, global_myname());
- strlower_m(myname);
- asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
- ret = krb5_parse_name(context, host_princ_s, &host_princ);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
- host_princ_s, error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- free_host_princ = True;
-
- /*
- * JRA. We must set the rcache here. This will prevent replay attacks.
- */
-
- ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- ret = krb5_auth_con_setrcache(context, auth_context, rcache);
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */
-
- if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
- DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n",
- error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5
- * code surrounding the replay cache... */
-
- if (!grab_server_mutex("replay cache mutex")) {
- DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n"));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- got_replay_mutex = True;
-
- /* We need to setup a auth context with each possible encoding type in turn. */
- for (i=0;enctypes[i];i++) {
- if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
- sret = NT_STATUS_NO_MEMORY;
- goto out;
- }
-
- if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
- continue;
- }
-
- krb5_auth_con_setuseruserkey(context, auth_context, key);
-
- krb5_free_keyblock(context, key);
-
- packet.length = ticket->length;
- packet.data = (krb5_pointer)ticket->data;
-
- if (!(ret = krb5_rd_req(context, &auth_context, &packet,
- NULL,
- NULL, NULL, &tkt))) {
- DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n",
- (unsigned int)enctypes[i] ));
- auth_ok = True;
- break;
- }
-
- DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
- ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
- (unsigned int)enctypes[i], error_message(ret)));
- }
-
- release_server_mutex();
- got_replay_mutex = False;
-
- if (!auth_ok) {
- DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
- error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- ret = krb5_mk_rep(context, auth_context, &packet);
- if (ret) {
- DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
- error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- *ap_rep = data_blob(packet.data, packet.length);
- free(packet.data);
-
- get_krb5_smb_session_key(context, auth_context, session_key, True);
- dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);
-
-#if 0
- file_save("/tmp/ticket.dat", ticket->data, ticket->length);
-#endif
-
- get_auth_data_from_tkt(auth_data, tkt);
-
- {
- TALLOC_CTX *ctx = talloc_init("pac data");
- decode_pac_data(auth_data, ctx);
- talloc_destroy(ctx);
- }
-
-#if 0
- if (tkt->enc_part2) {
- file_save("/tmp/authdata.dat",
- tkt->enc_part2->authorization_data[0]->contents,
- tkt->enc_part2->authorization_data[0]->length);
- }
-#endif
-
- if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
- principal))) {
- DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n",
- error_message(ret)));
- sret = NT_STATUS_LOGON_FAILURE;
- goto out;
- }
-
- sret = NT_STATUS_OK;
-
- out:
-
- if (got_replay_mutex)
- release_server_mutex();
-
- if (!NT_STATUS_IS_OK(sret))
- data_blob_free(auth_data);
-
- if (!NT_STATUS_IS_OK(sret))
- data_blob_free(ap_rep);
-
- if (free_host_princ)
- krb5_free_principal(context, host_princ);
-
- if (tkt != NULL)
- krb5_free_ticket(context, tkt);
- free_kerberos_etypes(context, enctypes);
- SAFE_FREE(password_s);
- SAFE_FREE(host_princ_s);
-
- if (auth_context)
- krb5_auth_con_free(context, auth_context);
-
- if (context)
- krb5_free_context(context);
-
- return sret;
-}
-
-#endif /* HAVE_KRB5 */
diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c
deleted file mode 100644
index 16d3df83e93..00000000000
--- a/source/libads/krb5_setpw.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- krb5 set password implementation
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-#define DEFAULT_KPASSWD_PORT 464
-#define KRB5_KPASSWD_VERS_CHANGEPW 1
-#define KRB5_KPASSWD_VERS_SETPW 2
-#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80
-#define KRB5_KPASSWD_ACCESSDENIED 5
-#define KRB5_KPASSWD_BAD_VERSION 6
-#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7
-
-/* Those are defined by kerberos-set-passwd-02.txt and are probably
- * not supported by M$ implementation */
-#define KRB5_KPASSWD_POLICY_REJECT 8
-#define KRB5_KPASSWD_BAD_PRINCIPAL 9
-#define KRB5_KPASSWD_ETYPE_NOSUPP 10
-
-/* This implements kerberos password change protocol as specified in
- * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt
- * as well as microsoft version of the protocol
- * as specified in kerberos-set-passwd-00.txt
- */
-static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password)
-{
- char* princ_part1 = NULL;
- char* princ_part2 = NULL;
- char* realm = NULL;
- char* c;
- char* princ;
-
- ASN1_DATA req;
- DATA_BLOB ret;
-
-
- princ = strdup(principal);
-
- if ((c = strchr(princ, '/')) == NULL) {
- c = princ;
- } else {
- *c = '\0';
- c++;
- princ_part1 = princ;
- }
-
- princ_part2 = c;
-
- if ((c = strchr(c, '@')) != NULL) {
- *c = '\0';
- c++;
- realm = c;
- }
-
- memset(&req, 0, sizeof(req));
-
- asn1_push_tag(&req, ASN1_SEQUENCE(0));
- asn1_push_tag(&req, ASN1_CONTEXT(0));
- asn1_write_OctetString(&req, password, strlen(password));
- asn1_pop_tag(&req);
-
- asn1_push_tag(&req, ASN1_CONTEXT(1));
- asn1_push_tag(&req, ASN1_SEQUENCE(0));
-
- asn1_push_tag(&req, ASN1_CONTEXT(0));
- asn1_write_Integer(&req, 1);
- asn1_pop_tag(&req);
-
- asn1_push_tag(&req, ASN1_CONTEXT(1));
- asn1_push_tag(&req, ASN1_SEQUENCE(0));
-
- if (princ_part1)
- asn1_write_GeneralString(&req, princ_part1);
-
- asn1_write_GeneralString(&req, princ_part2);
- asn1_pop_tag(&req);
- asn1_pop_tag(&req);
- asn1_pop_tag(&req);
- asn1_pop_tag(&req);
-
- asn1_push_tag(&req, ASN1_CONTEXT(2));
- asn1_write_GeneralString(&req, realm);
- asn1_pop_tag(&req);
- asn1_pop_tag(&req);
-
- ret = data_blob(req.data, req.length);
- asn1_free(&req);
-
- free(princ);
-
- return ret;
-}
-
-static krb5_error_code build_kpasswd_request(uint16 pversion,
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_data *ap_req,
- const char *princ,
- const char *passwd,
- krb5_data *packet)
-{
- krb5_error_code ret;
- krb5_data cipherpw;
- krb5_data encoded_setpw;
- krb5_replay_data replay;
- char *p;
- DATA_BLOB setpw;
-
- ret = krb5_auth_con_setflags(context,
- auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE);
- if (ret) {
- DEBUG(1,("krb5_auth_con_setflags failed (%s)\n",
- error_message(ret)));
- return ret;
- }
-
- /* handle protocol differences in chpw and setpw */
- if (pversion == KRB5_KPASSWD_VERS_CHANGEPW)
- setpw = data_blob(passwd, strlen(passwd));
- else if (pversion == KRB5_KPASSWD_VERS_SETPW ||
- pversion == KRB5_KPASSWD_VERS_SETPW_MS)
- setpw = encode_krb5_setpw(princ, passwd);
- else
- return EINVAL;
-
- encoded_setpw.data = (char *)setpw.data;
- encoded_setpw.length = setpw.length;
-
- ret = krb5_mk_priv(context, auth_context,
- &encoded_setpw, &cipherpw, &replay);
-
- data_blob_free(&setpw); /*from 'encode_krb5_setpw(...)' */
-
- if (ret) {
- DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret)));
- return ret;
- }
-
- packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6);
- if (!packet->data)
- return -1;
-
- /* see the RFC for details */
- p = ((char *)packet->data) + 2;
- RSSVAL(p, 0, pversion);
- p += 2;
- RSSVAL(p, 0, ap_req->length);
- p += 2;
- memcpy(p, ap_req->data, ap_req->length);
- p += ap_req->length;
- memcpy(p, cipherpw.data, cipherpw.length);
- p += cipherpw.length;
- packet->length = PTR_DIFF(p,packet->data);
- RSSVAL(packet->data, 0, packet->length);
-
- free(cipherpw.data); /* from 'krb5_mk_priv(...)' */
-
- return 0;
-}
-
-static const struct kpasswd_errors {
- int result_code;
- const char *error_string;
-} kpasswd_errors[] = {
- {KRB5_KPASSWD_MALFORMED, "Malformed request error"},
- {KRB5_KPASSWD_HARDERROR, "Server error"},
- {KRB5_KPASSWD_AUTHERROR, "Authentication error"},
- {KRB5_KPASSWD_SOFTERROR, "Password change rejected"},
- {KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"},
- {KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"},
- {KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"},
- {KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"},
- {KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"},
- {KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"},
- {0, NULL}
-};
-
-static krb5_error_code setpw_result_code_string(krb5_context context,
- int result_code,
- const char **code_string)
-{
- unsigned int idx = 0;
-
- while (kpasswd_errors[idx].error_string != NULL) {
- if (kpasswd_errors[idx].result_code ==
- result_code) {
- *code_string = kpasswd_errors[idx].error_string;
- return 0;
- }
- idx++;
- }
- *code_string = "Password change failed";
- return (0);
-}
-
-static krb5_error_code parse_setpw_reply(krb5_context context,
- krb5_auth_context auth_context,
- krb5_data *packet)
-{
- krb5_data ap_rep;
- char *p;
- int vnum, ret, res_code;
- krb5_data cipherresult;
- krb5_data clearresult;
- krb5_ap_rep_enc_part *ap_rep_enc;
- krb5_replay_data replay;
-
- if (packet->length < 4) {
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- p = packet->data;
-
- if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) {
- /* it's an error packet. We should parse it ... */
- DEBUG(1,("Got error packet 0x%x from kpasswd server\n",
- ((char *)packet->data)[0]));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if (RSVAL(p, 0) != packet->length) {
- DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n",
- RSVAL(p, 0), packet->length));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- p += 2;
-
- vnum = RSVAL(p, 0); p += 2;
-
- /* FIXME: According to standard there is only one type of reply */
- if (vnum != KRB5_KPASSWD_VERS_SETPW &&
- vnum != KRB5_KPASSWD_VERS_SETPW_MS &&
- vnum != KRB5_KPASSWD_VERS_CHANGEPW) {
- DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum));
- return KRB5KDC_ERR_BAD_PVNO;
- }
-
- ap_rep.length = RSVAL(p, 0); p += 2;
-
- if (p + ap_rep.length >= (char *)packet->data + packet->length) {
- DEBUG(1,("ptr beyond end of packet from kpasswd server\n"));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if (ap_rep.length == 0) {
- DEBUG(1,("got unencrypted setpw result?!\n"));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- /* verify ap_rep */
- ap_rep.data = p;
- p += ap_rep.length;
-
- ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
- if (ret) {
- DEBUG(1,("failed to rd setpw reply (%s)\n", error_message(ret)));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- krb5_free_ap_rep_enc_part(context, ap_rep_enc);
-
- cipherresult.data = p;
- cipherresult.length = ((char *)packet->data + packet->length) - p;
-
- ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
- &replay);
- if (ret) {
- DEBUG(1,("failed to decrypt setpw reply (%s)\n", error_message(ret)));
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if (clearresult.length < 2) {
- free(clearresult.data);
- ret = KRB5KRB_AP_ERR_MODIFIED;
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- p = clearresult.data;
-
- res_code = RSVAL(p, 0);
-
- free(clearresult.data);
-
- if ((res_code < KRB5_KPASSWD_SUCCESS) ||
- (res_code > KRB5_KPASSWD_ETYPE_NOSUPP)) {
- return KRB5KRB_AP_ERR_MODIFIED;
- }
-
- if(res_code == KRB5_KPASSWD_SUCCESS)
- return 0;
- else {
- const char *errstr;
- setpw_result_code_string(context, res_code, &errstr);
- DEBUG(1, ("Error changing password: %s\n", errstr));
-
- switch(res_code) {
- case KRB5_KPASSWD_ACCESSDENIED:
- return KRB5KDC_ERR_BADOPTION;
- break;
- case KRB5_KPASSWD_INITIAL_FLAG_NEEDED:
- return KRB5KDC_ERR_BADOPTION;
- /* return KV5M_ALT_METHOD; MIT-only define */
- break;
- case KRB5_KPASSWD_ETYPE_NOSUPP:
- return KRB5KDC_ERR_ETYPE_NOSUPP;
- break;
- case KRB5_KPASSWD_BAD_PRINCIPAL:
- return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
- break;
- case KRB5_KPASSWD_POLICY_REJECT:
- return KRB5KDC_ERR_POLICY;
- break;
- default:
- return KRB5KRB_ERR_GENERIC;
- break;
- }
- }
-}
-
-static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
- const char *kdc_host,
- uint16 pversion,
- krb5_creds *credsp,
- const char *princ,
- const char *newpw)
-{
- krb5_auth_context auth_context = NULL;
- krb5_data ap_req, chpw_req, chpw_rep;
- int ret, sock, addr_len;
- struct sockaddr remote_addr, local_addr;
- krb5_address local_kaddr, remote_kaddr;
-
- ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
- NULL, credsp, &ap_req);
- if (ret) {
- DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
- if (sock == -1) {
- int rc = errno;
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
- kdc_host, strerror(errno)));
- return ADS_ERROR_SYSTEM(rc);
- }
-
- addr_len = sizeof(remote_addr);
- getpeername(sock, &remote_addr, &addr_len);
- addr_len = sizeof(local_addr);
- getsockname(sock, &local_addr, &addr_len);
-
- setup_kaddr(&remote_kaddr, &remote_addr);
- setup_kaddr(&local_kaddr, &local_addr);
-
- ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
- if (ret) {
- close(sock);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- ret = build_kpasswd_request(pversion, context, auth_context, &ap_req,
- princ, newpw, &chpw_req);
- if (ret) {
- close(sock);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) {
- close(sock);
- free(chpw_req.data);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
- return ADS_ERROR_SYSTEM(errno);
- }
-
- free(chpw_req.data);
-
- chpw_rep.length = 1500;
- chpw_rep.data = (char *) malloc(chpw_rep.length);
- if (!chpw_rep.data) {
- close(sock);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
- errno = ENOMEM;
- return ADS_ERROR_SYSTEM(errno);
- }
-
- ret = read(sock, chpw_rep.data, chpw_rep.length);
- if (ret < 0) {
- close(sock);
- free(chpw_rep.data);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno)));
- return ADS_ERROR_SYSTEM(errno);
- }
-
- close(sock);
- chpw_rep.length = ret;
-
- ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr);
- if (ret) {
- free(chpw_rep.data);
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n",
- error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- ret = parse_setpw_reply(context, auth_context, &chpw_rep);
- free(chpw_rep.data);
-
- if (ret) {
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("parse_setpw_reply failed (%s)\n",
- error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- free(ap_req.data);
- krb5_auth_con_free(context, auth_context);
-
- return ADS_SUCCESS;
-}
-
-ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
- const char *newpw, int time_offset)
-{
-
- ADS_STATUS aret;
- krb5_error_code ret;
- krb5_context context;
- krb5_principal principal;
- char *princ_name;
- char *realm;
- krb5_creds creds, *credsp;
- krb5_ccache ccache;
-
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- if (time_offset != 0) {
- krb5_set_real_time(context, time(NULL) + time_offset, 0);
- }
-
- ret = krb5_cc_default(context, &ccache);
- if (ret) {
- krb5_free_context(context);
- DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- ZERO_STRUCT(creds);
-
- realm = strchr(princ, '@');
- realm++;
-
- asprintf(&princ_name, "kadmin/changepw@%s", realm);
- ret = krb5_parse_name(context, princ_name, &creds.server);
- if (ret) {
- krb5_free_context(context);
- DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
- free(princ_name);
-
- /* parse the principal we got as a function argument */
- ret = krb5_parse_name(context, princ, &principal);
- if (ret) {
- krb5_free_context(context);
- DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- krb5_princ_set_realm(context, creds.server,
- krb5_princ_realm(context, principal));
-
- ret = krb5_cc_get_principal(context, ccache, &creds.client);
- if (ret) {
- krb5_free_principal(context, principal);
- krb5_free_context(context);
- DEBUG(1,("Failed to get principal from ccache (%s)\n",
- error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
- if (ret) {
- krb5_free_principal(context, creds.client);
- krb5_free_principal(context, principal);
- krb5_free_context(context);
- DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- /* we might have to call krb5_free_creds(...) from now on ... */
-
- aret = do_krb5_kpasswd_request(context, kdc_host,
- KRB5_KPASSWD_VERS_SETPW_MS,
- credsp, princ, newpw);
-
- krb5_free_creds(context, credsp);
- krb5_free_principal(context, creds.client);
- krb5_free_principal(context, principal);
- krb5_free_context(context);
-
- return aret;
-}
-
-/*
- we use a prompter to avoid a crash bug in the kerberos libs when
- dealing with empty passwords
- this prompter is just a string copy ...
-*/
-static krb5_error_code
-kerb_prompter(krb5_context ctx, void *data,
- const char *name,
- const char *banner,
- int num_prompts,
- krb5_prompt prompts[])
-{
- if (num_prompts == 0) return 0;
-
- memset(prompts[0].reply->data, 0, prompts[0].reply->length);
- if (prompts[0].reply->length > 0) {
- if (data) {
- strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1);
- prompts[0].reply->length = strlen(prompts[0].reply->data);
- } else {
- prompts[0].reply->length = 0;
- }
- }
- return 0;
-}
-
-static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
- const char *principal,
- const char *oldpw,
- const char *newpw,
- int time_offset)
-{
- ADS_STATUS aret;
- krb5_error_code ret;
- krb5_context context;
- krb5_principal princ;
- krb5_get_init_creds_opt opts;
- krb5_creds creds;
- char *chpw_princ = NULL, *password;
-
- ret = krb5_init_context(&context);
- if (ret) {
- DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- if ((ret = krb5_parse_name(context, principal,
- &princ))) {
- krb5_free_context(context);
- DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- krb5_get_init_creds_opt_init(&opts);
- krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
- krb5_get_init_creds_opt_set_renew_life(&opts, 0);
- krb5_get_init_creds_opt_set_forwardable(&opts, 0);
- krb5_get_init_creds_opt_set_proxiable(&opts, 0);
-
- /* We have to obtain an INITIAL changepw ticket for changing password */
- asprintf(&chpw_princ, "kadmin/changepw@%s",
- (char *) krb5_princ_realm(context, princ));
- password = strdup(oldpw);
- ret = krb5_get_init_creds_password(context, &creds, princ, password,
- kerb_prompter, NULL,
- 0, chpw_princ, &opts);
- SAFE_FREE(chpw_princ);
- SAFE_FREE(password);
-
- if (ret) {
- if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
- DEBUG(1,("Password incorrect while getting initial ticket"));
- else
- DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret)));
-
- krb5_free_principal(context, princ);
- krb5_free_context(context);
- return ADS_ERROR_KRB5(ret);
- }
-
- aret = do_krb5_kpasswd_request(context, kdc_host,
- KRB5_KPASSWD_VERS_CHANGEPW,
- &creds, principal, newpw);
-
- krb5_free_principal(context, princ);
- krb5_free_context(context);
-
- return aret;
-}
-
-
-ADS_STATUS kerberos_set_password(const char *kpasswd_server,
- const char *auth_principal, const char *auth_password,
- const char *target_principal, const char *new_password,
- int time_offset)
-{
- int ret;
-
- if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) {
- DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
-
- if (!strcmp(auth_principal, target_principal))
- return ads_krb5_chg_password(kpasswd_server, target_principal,
- auth_password, new_password, time_offset);
- else
- return ads_krb5_set_password(kpasswd_server, target_principal,
- new_password, time_offset);
-}
-
-
-/**
- * Set the machine account password
- * @param ads connection to ads server
- * @param hostname machine whose password is being set
- * @param password new password
- * @return status of password change
- **/
-ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
- const char *machine_account,
- const char *password)
-{
- ADS_STATUS status;
- char *principal = NULL;
-
- /*
- we need to use the '$' form of the name here (the machine account name),
- as otherwise the server might end up setting the password for a user
- instead
- */
- asprintf(&principal, "%s@%s", machine_account, ads->config.realm);
-
- status = ads_krb5_set_password(ads->auth.kdc_server, principal,
- password, ads->auth.time_offset);
-
- free(principal);
-
- return status;
-}
-
-
-
-#endif
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
deleted file mode 100644
index 20a36dfdf5c..00000000000
--- a/source/libads/ldap.c
+++ /dev/null
@@ -1,2135 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Remus Koos 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_LDAP
-
-/**
- * @file ldap.c
- * @brief basic ldap client-side routines for ads server communications
- *
- * The routines contained here should do the necessary ldap calls for
- * ads setups.
- *
- * Important note: attribute names passed into ads_ routines must
- * already be in UTF-8 format. We do not convert them because in almost
- * all cases, they are just ascii (which is represented with the same
- * codepoints in UTF-8). This may have to change at some point
- **/
-
-
-/*
- try a connection to a given ldap server, returning True and setting the servers IP
- in the ads struct if successful
-
- TODO : add a negative connection cache in here leveraged off of the one
- found in the rpc code. --jerry
- */
-static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
-{
- char *srv;
-
- if (!server || !*server) {
- return False;
- }
-
- DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port));
-
- /* this copes with inet_ntoa brokenness */
- srv = strdup(server);
-
- ads->ld = ldap_open(srv, port);
- if (!ads->ld) {
- free(srv);
- return False;
- }
- ads->ldap_port = port;
- ads->ldap_ip = *interpret_addr2(srv);
- free(srv);
-
- return True;
-}
-
-/*
- try a connection to a given ldap server, based on URL, returning True if successful
- */
-static BOOL ads_try_connect_uri(ADS_STRUCT *ads)
-{
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
- DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n",
- ads->server.ldap_uri));
-
-
- if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) {
- return True;
- }
- DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
-
-#else
-
- DEBUG(1, ("no URL support in LDAP libs!\n"));
-#endif
-
- return False;
-}
-
-/**********************************************************************
- Try to find an AD dc using our internal name resolution routines
- Try the realm first and then then workgroup name if netbios is not
- disabled
-**********************************************************************/
-
-static BOOL ads_find_dc(ADS_STRUCT *ads)
-{
- const char *c_realm;
- int count, i=0;
- struct ip_service *ip_list;
- pstring realm;
- BOOL got_realm = False;
- BOOL use_own_domain = False;
-
- /* if the realm and workgroup are both empty, assume they are ours */
-
- /* realm */
- c_realm = ads->server.realm;
-
- if ( !c_realm || !*c_realm ) {
- /* special case where no realm and no workgroup means our own */
- if ( !ads->server.workgroup || !*ads->server.workgroup ) {
- use_own_domain = True;
- c_realm = lp_realm();
- }
- }
-
- if (c_realm && *c_realm)
- got_realm = True;
-
-again:
- /* we need to try once with the realm name and fallback to the
- netbios domain name if we fail (if netbios has not been disabled */
-
- if ( !got_realm && !lp_disable_netbios() ) {
- c_realm = ads->server.workgroup;
- if (!c_realm || !*c_realm) {
- if ( use_own_domain )
- c_realm = lp_workgroup();
- }
-
- if ( !c_realm || !*c_realm ) {
- DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n"));
- return False;
- }
- }
-
- pstrcpy( realm, c_realm );
-
- DEBUG(6,("ads_find_dc: looking for %s '%s'\n",
- (got_realm ? "realm" : "domain"), realm));
-
- if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) {
- /* fall back to netbios if we can */
- if ( got_realm && !lp_disable_netbios() ) {
- got_realm = False;
- goto again;
- }
-
- return False;
- }
-
- /* if we fail this loop, then giveup since all the IP addresses returned were dead */
- for ( i=0; i<count; i++ ) {
- /* since this is an ads conection request, default to LDAP_PORT is not set */
- int port = (ip_list[i].port!=PORT_NONE) ? ip_list[i].port : LDAP_PORT;
- fstring server;
-
- fstrcpy( server, inet_ntoa(ip_list[i].ip) );
-
- if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
- continue;
-
- if ( ads_try_connect(ads, server, port) ) {
- SAFE_FREE(ip_list);
- return True;
- }
-
- /* keep track of failures */
- add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
- }
-
- SAFE_FREE(ip_list);
-
- return False;
-}
-
-
-/**
- * Connect to the LDAP server
- * @param ads Pointer to an existing ADS_STRUCT
- * @return status of connection
- **/
-ADS_STATUS ads_connect(ADS_STRUCT *ads)
-{
- int version = LDAP_VERSION3;
- ADS_STATUS status;
-
- ads->last_attempt = time(NULL);
- ads->ld = NULL;
-
- /* try with a URL based server */
-
- if (ads->server.ldap_uri &&
- ads_try_connect_uri(ads)) {
- goto got_connection;
- }
-
- /* try with a user specified server */
- if (ads->server.ldap_server &&
- ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
- goto got_connection;
- }
-
- if (ads_find_dc(ads)) {
- goto got_connection;
- }
-
- return ADS_ERROR_SYSTEM(errno?errno:ENOENT);
-
-got_connection:
- DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip)));
-
- status = ads_server_info(ads);
- if (!ADS_ERR_OK(status)) {
- DEBUG(1,("Failed to get ldap server info\n"));
- return status;
- }
-
- ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
-
- if (!ads->auth.user_name) {
- /* by default use the machine account */
- fstring myname;
- fstrcpy(myname, global_myname());
- strlower_m(myname);
- asprintf(&ads->auth.user_name, "HOST/%s", myname);
- }
-
- if (!ads->auth.realm) {
- ads->auth.realm = strdup(ads->config.realm);
- }
-
- if (!ads->auth.kdc_server) {
- ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip));
- }
-
-#if KRB5_DNS_HACK
- /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch
- to MIT kerberos to work (tridge) */
- {
- char *env;
- asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm);
- setenv(env, ads->auth.kdc_server, 1);
- free(env);
- }
-#endif
-
- if (ads->auth.flags & ADS_AUTH_NO_BIND) {
- return ADS_SUCCESS;
- }
-
- if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
- return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL));
- }
-
- if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) {
- return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password));
- }
-
- return ads_sasl_bind(ads);
-}
-
-/*
- Duplicate a struct berval into talloc'ed memory
- */
-static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val)
-{
- struct berval *value;
-
- if (!in_val) return NULL;
-
- value = talloc_zero(ctx, sizeof(struct berval));
- if (value == NULL)
- return NULL;
- if (in_val->bv_len == 0) return value;
-
- value->bv_len = in_val->bv_len;
- value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len);
- return value;
-}
-
-/*
- Make a values list out of an array of (struct berval *)
- */
-static struct berval **ads_dup_values(TALLOC_CTX *ctx,
- const struct berval **in_vals)
-{
- struct berval **values;
- int i;
-
- if (!in_vals) return NULL;
- for (i=0; in_vals[i]; i++); /* count values */
- values = (struct berval **) talloc_zero(ctx,
- (i+1)*sizeof(struct berval *));
- if (!values) return NULL;
-
- for (i=0; in_vals[i]; i++) {
- values[i] = dup_berval(ctx, in_vals[i]);
- }
- return values;
-}
-
-/*
- UTF8-encode a values list out of an array of (char *)
- */
-static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals)
-{
- char **values;
- int i;
-
- if (!in_vals) return NULL;
- for (i=0; in_vals[i]; i++); /* count values */
- values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *));
- if (!values) return NULL;
-
- for (i=0; in_vals[i]; i++) {
- push_utf8_talloc(ctx, &values[i], in_vals[i]);
- }
- return values;
-}
-
-/*
- Pull a (char *) array out of a UTF8-encoded values list
- */
-static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals)
-{
- char **values;
- int i;
-
- if (!in_vals) return NULL;
- for (i=0; in_vals[i]; i++); /* count values */
- values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *));
- if (!values) return NULL;
-
- for (i=0; in_vals[i]; i++) {
- pull_utf8_talloc(ctx, &values[i], in_vals[i]);
- }
- return values;
-}
-
-/**
- * Do a search with paged results. cookie must be null on the first
- * call, and then returned on each subsequent call. It will be null
- * again when the entire search is complete
- * @param ads connection to ads server
- * @param bind_path Base dn for the search
- * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
- * @param expr Search expression - specified in local charset
- * @param attrs Attributes to retrieve - specified in utf8 or ascii
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @param count Number of entries retrieved on this page
- * @param cookie The paged results cookie to be returned on subsequent calls
- * @return status of search
- **/
-ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
- int scope, const char *expr,
- const char **attrs, void **res,
- int *count, void **cookie)
-{
- int rc, i, version;
- char *utf8_expr, *utf8_path, **search_attrs;
- LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols;
- BerElement *cookie_be = NULL;
- struct berval *cookie_bv= NULL;
- TALLOC_CTX *ctx;
-
- *res = NULL;
-
- if (!(ctx = talloc_init("ads_do_paged_search")))
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- /* 0 means the conversion worked but the result was empty
- so we only fail if it's -1. In any case, it always
- at least nulls out the dest */
- if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) ||
- (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) {
- rc = LDAP_NO_MEMORY;
- goto done;
- }
-
- if (!attrs || !(*attrs))
- search_attrs = NULL;
- else {
- /* This would be the utf8-encoded version...*/
- /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
- if (!(str_list_copy(&search_attrs, attrs))) {
- rc = LDAP_NO_MEMORY;
- goto done;
- }
- }
-
-
- /* Paged results only available on ldap v3 or later */
- ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
- if (version < LDAP_VERSION3) {
- rc = LDAP_NOT_SUPPORTED;
- goto done;
- }
-
- cookie_be = ber_alloc_t(LBER_USE_DER);
- if (cookie && *cookie) {
- ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie);
- ber_bvfree(*cookie); /* don't need it from last time */
- *cookie = NULL;
- } else {
- ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0);
- }
- ber_flatten(cookie_be, &cookie_bv);
- PagedResults.ldctl_oid = ADS_PAGE_CTL_OID;
- PagedResults.ldctl_iscritical = (char) 1;
- PagedResults.ldctl_value.bv_len = cookie_bv->bv_len;
- PagedResults.ldctl_value.bv_val = cookie_bv->bv_val;
-
- NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID;
- NoReferrals.ldctl_iscritical = (char) 0;
- NoReferrals.ldctl_value.bv_len = 0;
- NoReferrals.ldctl_value.bv_val = "";
-
-
- controls[0] = &NoReferrals;
- controls[1] = &PagedResults;
- controls[2] = NULL;
-
- *res = NULL;
-
- /* we need to disable referrals as the openldap libs don't
- handle them and paged results at the same time. Using them
- together results in the result record containing the server
- page control being removed from the result list (tridge/jmcd)
-
- leaving this in despite the control that says don't generate
- referrals, in case the server doesn't support it (jmcd)
- */
- ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
-
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, controls,
- NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res);
-
- ber_free(cookie_be, 1);
- ber_bvfree(cookie_bv);
-
- if (rc) {
- DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc)));
- goto done;
- }
-
- rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL,
- NULL, &rcontrols, 0);
-
- if (!rcontrols) {
- goto done;
- }
-
- for (i=0; rcontrols[i]; i++) {
- if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) == 0) {
- cookie_be = ber_init(&rcontrols[i]->ldctl_value);
- ber_scanf(cookie_be,"{iO}", (ber_int_t *) count,
- &cookie_bv);
- /* the berval is the cookie, but must be freed when
- it is all done */
- if (cookie_bv->bv_len) /* still more to do */
- *cookie=ber_bvdup(cookie_bv);
- else
- *cookie=NULL;
- ber_bvfree(cookie_bv);
- ber_free(cookie_be, 1);
- break;
- }
- }
- ldap_controls_free(rcontrols);
-
-done:
- talloc_destroy(ctx);
- /* if/when we decide to utf8-encode attrs, take out this next line */
- str_list_free(&search_attrs);
-
- return ADS_ERROR(rc);
-}
-
-
-/**
- * Get all results for a search. This uses ads_do_paged_search() to return
- * all entries in a large search.
- * @param ads connection to ads server
- * @param bind_path Base dn for the search
- * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
- * @param expr Search expression
- * @param attrs Attributes to retrieve
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @return status of search
- **/
-ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path,
- int scope, const char *expr,
- const char **attrs, void **res)
-{
- void *cookie = NULL;
- int count = 0;
- ADS_STATUS status;
-
- status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res,
- &count, &cookie);
-
- if (!ADS_ERR_OK(status)) return status;
-
- while (cookie) {
- void *res2 = NULL;
- ADS_STATUS status2;
- LDAPMessage *msg, *next;
-
- status2 = ads_do_paged_search(ads, bind_path, scope, expr,
- attrs, &res2, &count, &cookie);
-
- if (!ADS_ERR_OK(status2)) break;
-
- /* this relies on the way that ldap_add_result_entry() works internally. I hope
- that this works on all ldap libs, but I have only tested with openldap */
- for (msg = ads_first_entry(ads, res2); msg; msg = next) {
- next = ads_next_entry(ads, msg);
- ldap_add_result_entry((LDAPMessage **)res, msg);
- }
- /* note that we do not free res2, as the memory is now
- part of the main returned list */
- }
-
- return status;
-}
-
-/**
- * Run a function on all results for a search. Uses ads_do_paged_search() and
- * runs the function as each page is returned, using ads_process_results()
- * @param ads connection to ads server
- * @param bind_path Base dn for the search
- * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
- * @param expr Search expression - specified in local charset
- * @param attrs Attributes to retrieve - specified in UTF-8 or ascii
- * @param fn Function which takes attr name, values list, and data_area
- * @param data_area Pointer which is passed to function on each call
- * @return status of search
- **/
-ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path,
- int scope, const char *expr, const char **attrs,
- BOOL(*fn)(char *, void **, void *),
- void *data_area)
-{
- void *cookie = NULL;
- int count = 0;
- ADS_STATUS status;
- void *res;
-
- status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res,
- &count, &cookie);
-
- if (!ADS_ERR_OK(status)) return status;
-
- ads_process_results(ads, res, fn, data_area);
- ads_msgfree(ads, res);
-
- while (cookie) {
- status = ads_do_paged_search(ads, bind_path, scope, expr, attrs,
- &res, &count, &cookie);
-
- if (!ADS_ERR_OK(status)) break;
-
- ads_process_results(ads, res, fn, data_area);
- ads_msgfree(ads, res);
- }
-
- return status;
-}
-
-/**
- * Do a search with a timeout.
- * @param ads connection to ads server
- * @param bind_path Base dn for the search
- * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE)
- * @param expr Search expression
- * @param attrs Attributes to retrieve
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @return status of search
- **/
-ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
- const char *expr,
- const char **attrs, void **res)
-{
- struct timeval timeout;
- int rc;
- char *utf8_expr, *utf8_path, **search_attrs = NULL;
- TALLOC_CTX *ctx;
-
- if (!(ctx = talloc_init("ads_do_search"))) {
- DEBUG(1,("ads_do_search: talloc_init() failed!"));
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
- /* 0 means the conversion worked but the result was empty
- so we only fail if it's negative. In any case, it always
- at least nulls out the dest */
- if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) ||
- (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) {
- DEBUG(1,("ads_do_search: push_utf8_talloc() failed!"));
- rc = LDAP_NO_MEMORY;
- goto done;
- }
-
- if (!attrs || !(*attrs))
- search_attrs = NULL;
- else {
- /* This would be the utf8-encoded version...*/
- /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
- if (!(str_list_copy(&search_attrs, attrs)))
- {
- DEBUG(1,("ads_do_search: str_list_copy() failed!"));
- rc = LDAP_NO_MEMORY;
- goto done;
- }
- }
-
- timeout.tv_sec = ADS_SEARCH_TIMEOUT;
- timeout.tv_usec = 0;
- *res = NULL;
-
- /* see the note in ads_do_paged_search - we *must* disable referrals */
- ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
-
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, NULL, NULL,
- &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
-
- if (rc == LDAP_SIZELIMIT_EXCEEDED) {
- DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n"));
- rc = 0;
- }
-
- done:
- talloc_destroy(ctx);
- /* if/when we decide to utf8-encode attrs, take out this next line */
- str_list_free(&search_attrs);
- return ADS_ERROR(rc);
-}
-/**
- * Do a general ADS search
- * @param ads connection to ads server
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @param expr Search expression
- * @param attrs Attributes to retrieve
- * @return status of search
- **/
-ADS_STATUS ads_search(ADS_STRUCT *ads, void **res,
- const char *expr,
- const char **attrs)
-{
- return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
- expr, attrs, res);
-}
-
-/**
- * Do a search on a specific DistinguishedName
- * @param ads connection to ads server
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @param dn DistinguishName to search
- * @param attrs Attributes to retrieve
- * @return status of search
- **/
-ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res,
- const char *dn,
- const char **attrs)
-{
- return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res);
-}
-
-/**
- * Free up memory from a ads_search
- * @param ads connection to ads server
- * @param msg Search results to free
- **/
-void ads_msgfree(ADS_STRUCT *ads, void *msg)
-{
- if (!msg) return;
- ldap_msgfree(msg);
-}
-
-/**
- * Free up memory from various ads requests
- * @param ads connection to ads server
- * @param mem Area to free
- **/
-void ads_memfree(ADS_STRUCT *ads, void *mem)
-{
- SAFE_FREE(mem);
-}
-
-/**
- * Get a dn from search results
- * @param ads connection to ads server
- * @param msg Search result
- * @return dn string
- **/
-char *ads_get_dn(ADS_STRUCT *ads, void *msg)
-{
- char *utf8_dn, *unix_dn;
-
- utf8_dn = ldap_get_dn(ads->ld, msg);
-
- if (!utf8_dn) {
- DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n"));
- return NULL;
- }
-
- if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
- DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n",
- utf8_dn ));
- return NULL;
- }
- ldap_memfree(utf8_dn);
- return unix_dn;
-}
-
-/**
- * Find a machine account given a hostname
- * @param ads connection to ads server
- * @param res ** which will contain results - free res* with ads_msgfree()
- * @param host Hostname to search for
- * @return status of search
- **/
-ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host)
-{
- ADS_STATUS status;
- char *expr;
- const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
-
- /* the easiest way to find a machine account anywhere in the tree
- is to look for hostname$ */
- if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) {
- DEBUG(1, ("asprintf failed!\n"));
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- status = ads_search(ads, res, expr, attrs);
- free(expr);
- return status;
-}
-
-/**
- * Initialize a list of mods to be used in a modify request
- * @param ctx An initialized TALLOC_CTX
- * @return allocated ADS_MODLIST
- **/
-ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
-{
-#define ADS_MODLIST_ALLOC_SIZE 10
- LDAPMod **mods;
-
- if ((mods = (LDAPMod **) talloc_zero(ctx, sizeof(LDAPMod *) *
- (ADS_MODLIST_ALLOC_SIZE + 1))))
- /* -1 is safety to make sure we don't go over the end.
- need to reset it to NULL before doing ldap modify */
- mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
-
- return mods;
-}
-
-
-/*
- add an attribute to the list, with values list already constructed
-*/
-static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- int mod_op, const char *name,
- const void **invals)
-{
- int curmod;
- LDAPMod **modlist = (LDAPMod **) *mods;
- struct berval **ber_values = NULL;
- char **char_values = NULL;
-
- if (!invals) {
- mod_op = LDAP_MOD_DELETE;
- } else {
- if (mod_op & LDAP_MOD_BVALUES)
- ber_values = ads_dup_values(ctx,
- (const struct berval **)invals);
- else
- char_values = ads_push_strvals(ctx,
- (const char **) invals);
- }
-
- /* find the first empty slot */
- for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1;
- curmod++);
- if (modlist[curmod] == (LDAPMod *) -1) {
- if (!(modlist = talloc_realloc(ctx, modlist,
- (curmod+ADS_MODLIST_ALLOC_SIZE+1)*sizeof(LDAPMod *))))
- return ADS_ERROR(LDAP_NO_MEMORY);
- memset(&modlist[curmod], 0,
- ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *));
- modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
- *mods = modlist;
- }
-
- if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod))))
- return ADS_ERROR(LDAP_NO_MEMORY);
- modlist[curmod]->mod_type = talloc_strdup(ctx, name);
- if (mod_op & LDAP_MOD_BVALUES) {
- modlist[curmod]->mod_bvalues = ber_values;
- } else if (mod_op & LDAP_MOD_DELETE) {
- modlist[curmod]->mod_values = NULL;
- } else {
- modlist[curmod]->mod_values = char_values;
- }
-
- modlist[curmod]->mod_op = mod_op;
- return ADS_ERROR(LDAP_SUCCESS);
-}
-
-/**
- * Add a single string value to a mod list
- * @param ctx An initialized TALLOC_CTX
- * @param mods An initialized ADS_MODLIST
- * @param name The attribute name to add
- * @param val The value to add - NULL means DELETE
- * @return ADS STATUS indicating success of add
- **/
-ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const char *name, const char *val)
-{
- const char *values[2];
-
- values[0] = val;
- values[1] = NULL;
-
- if (!val)
- return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
- return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name,
- (const void **) values);
-}
-
-/**
- * Add an array of string values to a mod list
- * @param ctx An initialized TALLOC_CTX
- * @param mods An initialized ADS_MODLIST
- * @param name The attribute name to add
- * @param vals The array of string values to add - NULL means DELETE
- * @return ADS STATUS indicating success of add
- **/
-ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const char *name, const char **vals)
-{
- if (!vals)
- return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
- return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE,
- name, (const void **) vals);
-}
-
-/**
- * Add a single ber-encoded value to a mod list
- * @param ctx An initialized TALLOC_CTX
- * @param mods An initialized ADS_MODLIST
- * @param name The attribute name to add
- * @param val The value to add - NULL means DELETE
- * @return ADS STATUS indicating success of add
- **/
-static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const char *name, const struct berval *val)
-{
- const struct berval *values[2];
-
- values[0] = val;
- values[1] = NULL;
- if (!val)
- return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL);
- return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES,
- name, (const void **) values);
-}
-
-/**
- * Perform an ldap modify
- * @param ads connection to ads server
- * @param mod_dn DistinguishedName to modify
- * @param mods list of modifications to perform
- * @return status of modify
- **/
-ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
-{
- int ret,i;
- char *utf8_dn = NULL;
- /*
- this control is needed to modify that contains a currently
- non-existent attribute (but allowable for the object) to run
- */
- LDAPControl PermitModify = {
- ADS_PERMIT_MODIFY_OID,
- {0, NULL},
- (char) 1};
- LDAPControl *controls[2];
-
- controls[0] = &PermitModify;
- controls[1] = NULL;
-
- if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) {
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- /* find the end of the list, marked by NULL or -1 */
- for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
- /* make sure the end of the list is NULL */
- mods[i] = NULL;
- ret = ldap_modify_ext_s(ads->ld, utf8_dn,
- (LDAPMod **) mods, controls, NULL);
- SAFE_FREE(utf8_dn);
- return ADS_ERROR(ret);
-}
-
-/**
- * Perform an ldap add
- * @param ads connection to ads server
- * @param new_dn DistinguishedName to add
- * @param mods list of attributes and values for DN
- * @return status of add
- **/
-ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
-{
- int ret, i;
- char *utf8_dn = NULL;
-
- if (push_utf8_allocate(&utf8_dn, new_dn) == -1) {
- DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!"));
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- /* find the end of the list, marked by NULL or -1 */
- for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
- /* make sure the end of the list is NULL */
- mods[i] = NULL;
-
- ret = ldap_add_s(ads->ld, utf8_dn, mods);
- SAFE_FREE(utf8_dn);
- return ADS_ERROR(ret);
-}
-
-/**
- * Delete a DistinguishedName
- * @param ads connection to ads server
- * @param new_dn DistinguishedName to delete
- * @return status of delete
- **/
-ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
-{
- int ret;
- char *utf8_dn = NULL;
- if (push_utf8_allocate(&utf8_dn, del_dn) == -1) {
- DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!"));
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- ret = ldap_delete_s(ads->ld, utf8_dn);
- return ADS_ERROR(ret);
-}
-
-/**
- * Build an org unit string
- * if org unit is Computers or blank then assume a container, otherwise
- * assume a \ separated list of organisational units
- * @param org_unit Organizational unit
- * @return org unit string - caller must free
- **/
-char *ads_ou_string(const char *org_unit)
-{
- if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) {
- return strdup("cn=Computers");
- }
-
- return ads_build_path(org_unit, "\\/", "ou=", 1);
-}
-
-
-
-/*
- add a machine account to the ADS server
-*/
-static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
- uint32 account_type,
- const char *org_unit)
-{
- ADS_STATUS ret, status;
- char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr;
- char *ou_str;
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
- const char *objectClass[] = {"top", "person", "organizationalPerson",
- "user", "computer", NULL};
- const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL};
- char *psp, *psp2;
- unsigned acct_control;
- unsigned exists=0;
- LDAPMessage *res;
-
- status = ads_find_machine_acct(ads, (void **)&res, hostname);
- if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
- DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname));
- exists=1;
- }
-
- if (!(ctx = talloc_init("machine_account")))
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- ret = ADS_ERROR(LDAP_NO_MEMORY);
-
- if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname)))
- goto done;
- if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))
- goto done;
- ou_str = ads_ou_string(org_unit);
- if (!ou_str) {
- DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n"));
- goto done;
- }
- new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str,
- ads->config.bind_path);
- servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname);
- psp = talloc_asprintf(ctx, "HOST/%s.%s",
- hostname,
- ads->config.realm);
- strlower_m(&psp[5]);
- servicePrincipalName[1] = psp;
- servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname);
- psp2 = talloc_asprintf(ctx, "CIFS/%s.%s",
- hostname,
- ads->config.realm);
- strlower_m(&psp2[5]);
- servicePrincipalName[3] = psp2;
-
- free(ou_str);
- if (!new_dn)
- goto done;
-
- if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname)))
- goto done;
-
- acct_control = account_type | UF_DONT_EXPIRE_PASSWD;
-#ifndef ENCTYPE_ARCFOUR_HMAC
- acct_control |= UF_USE_DES_KEY_ONLY;
-#endif
-
- if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control)))
- goto done;
-
- if (!(mods = ads_init_mods(ctx)))
- goto done;
-
- if (!exists) {
- ads_mod_str(ctx, &mods, "cn", hostname);
- ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName);
- ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
- ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
- }
- ads_mod_str(ctx, &mods, "dNSHostName", hostname);
- ads_mod_str(ctx, &mods, "userPrincipalName", host_upn);
- ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
- ads_mod_str(ctx, &mods, "operatingSystem", "Samba");
- ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING);
-
- if (!exists)
- ret = ads_gen_add(ads, new_dn, mods);
- else
- ret = ads_gen_mod(ads, new_dn, mods);
-
- if (!ADS_ERR_OK(ret))
- goto done;
-
- /* Do not fail if we can't set security descriptor
- * it shouldn't be mandatory and probably we just
- * don't have enough rights to do it.
- */
- if (!exists) {
- status = ads_set_machine_sd(ads, hostname, new_dn);
-
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("Warning: ads_set_machine_sd: %s\n",
- ads_errstr(status)));
- }
- }
-done:
- talloc_destroy(ctx);
- return ret;
-}
-
-/*
- dump a binary result from ldap
-*/
-static void dump_binary(const char *field, struct berval **values)
-{
- int i, j;
- for (i=0; values[i]; i++) {
- printf("%s: ", field);
- for (j=0; j<values[i]->bv_len; j++) {
- printf("%02X", (unsigned char)values[i]->bv_val[j]);
- }
- printf("\n");
- }
-}
-
-static void dump_guid(const char *field, struct berval **values)
-{
- int i;
- UUID_FLAT guid;
- for (i=0; values[i]; i++) {
- memcpy(guid.info, values[i]->bv_val, sizeof(guid.info));
- printf("%s: %s\n", field,
- smb_uuid_string_static(smb_uuid_unpack_static(guid)));
- }
-}
-
-/*
- dump a sid result from ldap
-*/
-static void dump_sid(const char *field, struct berval **values)
-{
- int i;
- for (i=0; values[i]; i++) {
- DOM_SID sid;
- sid_parse(values[i]->bv_val, values[i]->bv_len, &sid);
- printf("%s: %s\n", field, sid_string_static(&sid));
- }
-}
-
-/*
- dump ntSecurityDescriptor
-*/
-static void dump_sd(const char *filed, struct berval **values)
-{
- prs_struct ps;
-
- SEC_DESC *psd = 0;
- TALLOC_CTX *ctx = 0;
-
- if (!(ctx = talloc_init("sec_io_desc")))
- return;
-
- /* prepare data */
- prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL);
- prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len);
- prs_set_offset(&ps,0);
-
- /* parse secdesc */
- if (!sec_io_desc("sd", &psd, &ps, 1)) {
- prs_mem_free(&ps);
- talloc_destroy(ctx);
- return;
- }
- if (psd) ads_disp_sd(psd);
-
- prs_mem_free(&ps);
- talloc_destroy(ctx);
-}
-
-/*
- dump a string result from ldap
-*/
-static void dump_string(const char *field, char **values)
-{
- int i;
- for (i=0; values[i]; i++) {
- printf("%s: %s\n", field, values[i]);
- }
-}
-
-/*
- dump a field from LDAP on stdout
- used for debugging
-*/
-
-static BOOL ads_dump_field(char *field, void **values, void *data_area)
-{
- const struct {
- const char *name;
- BOOL string;
- void (*handler)(const char *, struct berval **);
- } handlers[] = {
- {"objectGUID", False, dump_guid},
- {"nTSecurityDescriptor", False, dump_sd},
- {"dnsRecord", False, dump_binary},
- {"objectSid", False, dump_sid},
- {"tokenGroups", False, dump_sid},
- {NULL, True, NULL}
- };
- int i;
-
- if (!field) { /* must be end of an entry */
- printf("\n");
- return False;
- }
-
- for (i=0; handlers[i].name; i++) {
- if (StrCaseCmp(handlers[i].name, field) == 0) {
- if (!values) /* first time, indicate string or not */
- return handlers[i].string;
- handlers[i].handler(field, (struct berval **) values);
- break;
- }
- }
- if (!handlers[i].name) {
- if (!values) /* first time, indicate string conversion */
- return True;
- dump_string(field, (char **)values);
- }
- return False;
-}
-
-/**
- * Dump a result from LDAP on stdout
- * used for debugging
- * @param ads connection to ads server
- * @param res Results to dump
- **/
-
-void ads_dump(ADS_STRUCT *ads, void *res)
-{
- ads_process_results(ads, res, ads_dump_field, NULL);
-}
-
-/**
- * Walk through results, calling a function for each entry found.
- * The function receives a field name, a berval * array of values,
- * and a data area passed through from the start. The function is
- * called once with null for field and values at the end of each
- * entry.
- * @param ads connection to ads server
- * @param res Results to process
- * @param fn Function for processing each result
- * @param data_area user-defined area to pass to function
- **/
-void ads_process_results(ADS_STRUCT *ads, void *res,
- BOOL(*fn)(char *, void **, void *),
- void *data_area)
-{
- void *msg;
- TALLOC_CTX *ctx;
-
- if (!(ctx = talloc_init("ads_process_results")))
- return;
-
- for (msg = ads_first_entry(ads, res); msg;
- msg = ads_next_entry(ads, msg)) {
- char *utf8_field;
- BerElement *b;
-
- for (utf8_field=ldap_first_attribute(ads->ld,
- (LDAPMessage *)msg,&b);
- utf8_field;
- utf8_field=ldap_next_attribute(ads->ld,
- (LDAPMessage *)msg,b)) {
- struct berval **ber_vals;
- char **str_vals, **utf8_vals;
- char *field;
- BOOL string;
-
- pull_utf8_talloc(ctx, &field, utf8_field);
- string = fn(field, NULL, data_area);
-
- if (string) {
- utf8_vals = ldap_get_values(ads->ld,
- (LDAPMessage *)msg, field);
- str_vals = ads_pull_strvals(ctx,
- (const char **) utf8_vals);
- fn(field, (void **) str_vals, data_area);
- ldap_value_free(utf8_vals);
- } else {
- ber_vals = ldap_get_values_len(ads->ld,
- (LDAPMessage *)msg, field);
- fn(field, (void **) ber_vals, data_area);
-
- ldap_value_free_len(ber_vals);
- }
- ldap_memfree(utf8_field);
- }
- ber_free(b, 0);
- talloc_destroy_pool(ctx);
- fn(NULL, NULL, data_area); /* completed an entry */
-
- }
- talloc_destroy(ctx);
-}
-
-/**
- * count how many replies are in a LDAPMessage
- * @param ads connection to ads server
- * @param res Results to count
- * @return number of replies
- **/
-int ads_count_replies(ADS_STRUCT *ads, void *res)
-{
- return ldap_count_entries(ads->ld, (LDAPMessage *)res);
-}
-
-/**
- * Join a machine to a realm
- * Creates the machine account and sets the machine password
- * @param ads connection to ads server
- * @param hostname name of host to add
- * @param org_unit Organizational unit to place machine in
- * @return status of join
- **/
-ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname,
- uint32 account_type, const char *org_unit)
-{
- ADS_STATUS status;
- LDAPMessage *res;
- char *host;
-
- /* hostname must be lowercase */
- host = strdup(hostname);
- strlower_m(host);
-
- /*
- status = ads_find_machine_acct(ads, (void **)&res, host);
- if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
- DEBUG(0, ("Host account for %s already exists - deleting old account\n", host));
- status = ads_leave_realm(ads, host);
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n",
- host, ads->config.realm));
- return status;
- }
- }
- */
-
- status = ads_add_machine_acct(ads, host, account_type, org_unit);
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status)));
- return status;
- }
-
- status = ads_find_machine_acct(ads, (void **)&res, host);
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("Host account test failed\n"));
- return status;
- }
-
- free(host);
-
- return status;
-}
-
-/**
- * Delete a machine from the realm
- * @param ads connection to ads server
- * @param hostname Machine to remove
- * @return status of delete
- **/
-ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
-{
- ADS_STATUS status;
- void *res, *msg;
- char *hostnameDN, *host;
- int rc;
-
- /* hostname must be lowercase */
- host = strdup(hostname);
- strlower_m(host);
-
- status = ads_find_machine_acct(ads, &res, host);
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("Host account for %s does not exist.\n", host));
- return status;
- }
-
- msg = ads_first_entry(ads, res);
- if (!msg) {
- return ADS_ERROR_SYSTEM(ENOENT);
- }
-
- hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg);
- rc = ldap_delete_s(ads->ld, hostnameDN);
- ads_memfree(ads, hostnameDN);
- if (rc != LDAP_SUCCESS) {
- return ADS_ERROR(rc);
- }
-
- status = ads_find_machine_acct(ads, &res, host);
- if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
- DEBUG(0, ("Failed to remove host account.\n"));
- return status;
- }
-
- free(host);
-
- return status;
-}
-
-/**
- * add machine account to existing security descriptor
- * @param ads connection to ads server
- * @param hostname machine to add
- * @param dn DN of security descriptor
- * @return status
- **/
-ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
-{
- const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0};
- char *expr = 0;
- size_t sd_size = 0;
- struct berval bval = {0, NULL};
- prs_struct ps_wire;
- char *escaped_hostname = escape_ldap_string_alloc(hostname);
-
- LDAPMessage *res = 0;
- LDAPMessage *msg = 0;
- ADS_MODLIST mods = 0;
-
- NTSTATUS status;
- ADS_STATUS ret;
- DOM_SID sid;
- SEC_DESC *psd = NULL;
- TALLOC_CTX *ctx = NULL;
-
- /* Avoid segmentation fault in prs_mem_free if
- * we have to bail out before prs_init */
- ps_wire.is_dynamic = False;
-
- if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN);
-
- ret = ADS_ERROR(LDAP_SUCCESS);
-
- if (!escaped_hostname) {
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) {
- DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n"));
- SAFE_FREE(escaped_hostname);
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- SAFE_FREE(escaped_hostname);
-
- ret = ads_search(ads, (void *) &res, expr, attrs);
-
- if (!ADS_ERR_OK(ret)) return ret;
-
- if ( !(msg = ads_first_entry(ads, res) )) {
- ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- goto ads_set_sd_error;
- }
-
- if (!ads_pull_sid(ads, msg, attrs[1], &sid)) {
- ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- goto ads_set_sd_error;
- }
-
- if (!(ctx = talloc_init("sec_io_desc"))) {
- ret = ADS_ERROR(LDAP_NO_MEMORY);
- goto ads_set_sd_error;
- }
-
- if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) {
- ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- goto ads_set_sd_error;
- }
-
- status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size);
-
- if (!NT_STATUS_IS_OK(status)) {
- ret = ADS_ERROR_NT(status);
- goto ads_set_sd_error;
- }
-
- if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) {
- ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) {
- ret = ADS_ERROR(LDAP_NO_MEMORY);
- goto ads_set_sd_error;
- }
-
-#if 0
- file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size);
-#endif
- if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY);
-
- bval.bv_len = prs_offset(&ps_wire);
- bval.bv_val = talloc(ctx, bval.bv_len);
- if (!bval.bv_val) {
- ret = ADS_ERROR(LDAP_NO_MEMORY);
- goto ads_set_sd_error;
- }
-
- prs_set_offset(&ps_wire, 0);
-
- if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) {
- ret = ADS_ERROR(LDAP_NO_MEMORY);
- goto ads_set_sd_error;
- }
-
- ret = ads_mod_ber(ctx, &mods, attrs[0], &bval);
- if (ADS_ERR_OK(ret)) {
- ret = ads_gen_mod(ads, dn, mods);
- }
-
-ads_set_sd_error:
- ads_msgfree(ads, res);
- prs_mem_free(&ps_wire);
- talloc_destroy(ctx);
- return ret;
-}
-
-/**
- * pull the first entry from a ADS result
- * @param ads connection to ads server
- * @param res Results of search
- * @return first entry from result
- **/
-void *ads_first_entry(ADS_STRUCT *ads, void *res)
-{
- return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res);
-}
-
-/**
- * pull the next entry from a ADS result
- * @param ads connection to ads server
- * @param res Results of search
- * @return next entry from result
- **/
-void *ads_next_entry(ADS_STRUCT *ads, void *res)
-{
- return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res);
-}
-
-/**
- * pull a single string from a ADS result
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX to use for allocating result string
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @return Result string in talloc context
- **/
-char *ads_pull_string(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx, void *msg, const char *field)
-{
- char **values;
- char *ret = NULL;
- char *ux_string;
- size_t rc;
-
- values = ldap_get_values(ads->ld, msg, field);
- if (!values)
- return NULL;
-
- if (values[0]) {
- rc = pull_utf8_talloc(mem_ctx, &ux_string,
- values[0]);
- if (rc != (size_t)-1)
- ret = ux_string;
-
- }
- ldap_value_free(values);
- return ret;
-}
-
-/**
- * pull an array of strings from a ADS result
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX to use for allocating result string
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @return Result strings in talloc context
- **/
-char **ads_pull_strings(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx, void *msg, const char *field,
- size_t *num_values)
-{
- char **values;
- char **ret = NULL;
- int i;
-
- values = ldap_get_values(ads->ld, msg, field);
- if (!values)
- return NULL;
-
- *num_values = ldap_count_values(values);
-
- ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1));
- if (!ret) {
- ldap_value_free(values);
- return NULL;
- }
-
- for (i=0;i<*num_values;i++) {
- if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) {
- ldap_value_free(values);
- return NULL;
- }
- }
- ret[i] = NULL;
-
- ldap_value_free(values);
- return ret;
-}
-
-/**
- * pull an array of strings from a ADS result
- * (handle large multivalue attributes with range retrieval)
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX to use for allocating result string
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @param current_strings strings returned by a previous call to this function
- * @param next_attribute The next query should ask for this attribute
- * @param num_values How many values did we get this time?
- * @param more_values Are there more values to get?
- * @return Result strings in talloc context
- **/
-char **ads_pull_strings_range(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx,
- void *msg, const char *field,
- char **current_strings,
- const char **next_attribute,
- size_t *num_strings,
- BOOL *more_strings)
-{
- char *attr;
- char *expected_range_attrib, *range_attr;
- BerElement *ptr = NULL;
- char **strings;
- char **new_strings;
- size_t num_new_strings;
- unsigned long int range_start;
- unsigned long int range_end;
-
- /* we might have been given the whole lot anyway */
- if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) {
- *more_strings = False;
- return strings;
- }
-
- expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field);
-
- /* look for Range result */
- for (attr = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &ptr);
- attr;
- attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr)) {
- /* we ignore the fact that this is utf8, as all attributes are ascii... */
- if (strnequal(attr, expected_range_attrib, strlen(expected_range_attrib))) {
- range_attr = attr;
- break;
- }
- ldap_memfree(attr);
- }
- if (!attr) {
- ber_free(ptr, 0);
- /* nothing here - this field is just empty */
- *more_strings = False;
- return NULL;
- }
-
- if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu",
- &range_start, &range_end) == 2) {
- *more_strings = True;
- } else {
- if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-*",
- &range_start) == 1) {
- *more_strings = False;
- } else {
- DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n",
- range_attr));
- ldap_memfree(range_attr);
- *more_strings = False;
- return NULL;
- }
- }
-
- if ((*num_strings) != range_start) {
- DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu"
- " - aborting range retreival\n",
- range_attr, *num_strings + 1, range_start));
- ldap_memfree(range_attr);
- *more_strings = False;
- return NULL;
- }
-
- new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings);
-
- if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) {
- DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu "
- "strings in this bunch, but we only got %lu - aborting range retreival\n",
- range_attr, (unsigned long int)range_end - range_start + 1,
- (unsigned long int)num_new_strings));
- ldap_memfree(range_attr);
- *more_strings = False;
- return NULL;
- }
-
- strings = talloc_realloc(mem_ctx, current_strings,
- sizeof(*current_strings) *
- (*num_strings + num_new_strings));
-
- if (strings == NULL) {
- ldap_memfree(range_attr);
- *more_strings = False;
- return NULL;
- }
-
- memcpy(&strings[*num_strings], new_strings,
- sizeof(*new_strings) * num_new_strings);
-
- (*num_strings) += num_new_strings;
-
- if (*more_strings) {
- *next_attribute = talloc_asprintf(mem_ctx,
- "%s;range=%d-*",
- field,
- *num_strings);
-
- if (!*next_attribute) {
- DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
- ldap_memfree(range_attr);
- *more_strings = False;
- return NULL;
- }
- }
-
- ldap_memfree(range_attr);
-
- return strings;
-}
-
-/**
- * pull a single uint32 from a ADS result
- * @param ads connection to ads server
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @param v Pointer to int to store result
- * @return boolean inidicating success
-*/
-BOOL ads_pull_uint32(ADS_STRUCT *ads,
- void *msg, const char *field, uint32 *v)
-{
- char **values;
-
- values = ldap_get_values(ads->ld, msg, field);
- if (!values)
- return False;
- if (!values[0]) {
- ldap_value_free(values);
- return False;
- }
-
- *v = atoi(values[0]);
- ldap_value_free(values);
- return True;
-}
-
-/**
- * pull a single objectGUID from an ADS result
- * @param ads connection to ADS server
- * @param msg results of search
- * @param guid 37-byte area to receive text guid
- * @return boolean indicating success
- **/
-BOOL ads_pull_guid(ADS_STRUCT *ads,
- void *msg, struct uuid *guid)
-{
- char **values;
- UUID_FLAT flat_guid;
-
- values = ldap_get_values(ads->ld, msg, "objectGUID");
- if (!values)
- return False;
-
- if (values[0]) {
- memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT));
- smb_uuid_unpack(flat_guid, guid);
- ldap_value_free(values);
- return True;
- }
- ldap_value_free(values);
- return False;
-
-}
-
-
-/**
- * pull a single DOM_SID from a ADS result
- * @param ads connection to ads server
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @param sid Pointer to sid to store result
- * @return boolean inidicating success
-*/
-BOOL ads_pull_sid(ADS_STRUCT *ads,
- void *msg, const char *field, DOM_SID *sid)
-{
- struct berval **values;
- BOOL ret = False;
-
- values = ldap_get_values_len(ads->ld, msg, field);
-
- if (!values)
- return False;
-
- if (values[0])
- ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid);
-
- ldap_value_free_len(values);
- return ret;
-}
-
-/**
- * pull an array of DOM_SIDs from a ADS result
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX for allocating sid array
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @param sids pointer to sid array to allocate
- * @return the count of SIDs pulled
- **/
-int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- void *msg, const char *field, DOM_SID **sids)
-{
- struct berval **values;
- BOOL ret;
- int count, i;
-
- values = ldap_get_values_len(ads->ld, msg, field);
-
- if (!values)
- return 0;
-
- for (i=0; values[i]; i++)
- /* nop */ ;
-
- (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i);
- if (!(*sids)) {
- ldap_value_free_len(values);
- return 0;
- }
-
- count = 0;
- for (i=0; values[i]; i++) {
- ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]);
- if (ret) {
- fstring sid;
- DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count])));
- count++;
- }
- }
-
- ldap_value_free_len(values);
- return count;
-}
-
-/**
- * pull a SEC_DESC from a ADS result
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX for allocating sid array
- * @param msg Results of search
- * @param field Attribute to retrieve
- * @param sd Pointer to *SEC_DESC to store result (talloc()ed)
- * @return boolean inidicating success
-*/
-BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- void *msg, const char *field, SEC_DESC **sd)
-{
- struct berval **values;
- prs_struct ps;
- BOOL ret = False;
-
- values = ldap_get_values_len(ads->ld, msg, field);
-
- if (!values) return False;
-
- if (values[0]) {
- prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL);
- prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len);
- prs_set_offset(&ps,0);
-
- ret = sec_io_desc("sd", sd, &ps, 1);
- }
-
- ldap_value_free_len(values);
- return ret;
-}
-
-/*
- * in order to support usernames longer than 21 characters we need to
- * use both the sAMAccountName and the userPrincipalName attributes
- * It seems that not all users have the userPrincipalName attribute set
- *
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX for allocating sid array
- * @param msg Results of search
- * @return the username
- */
-char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg)
-{
- char *ret, *p;
-
- ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName");
- if (ret && (p = strchr(ret, '@'))) {
- *p = 0;
- return ret;
- }
- return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");
-}
-
-
-/**
- * find the update serial number - this is the core of the ldap cache
- * @param ads connection to ads server
- * @param ads connection to ADS server
- * @param usn Pointer to retrieved update serial number
- * @return status of search
- **/
-ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn)
-{
- const char *attrs[] = {"highestCommittedUSN", NULL};
- ADS_STATUS status;
- void *res;
-
- status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
- if (!ADS_ERR_OK(status))
- return status;
-
- if (ads_count_replies(ads, res) != 1) {
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
- ads_msgfree(ads, res);
- return ADS_SUCCESS;
-}
-
-/* parse a ADS timestring - typical string is
- '20020917091222.0Z0' which means 09:12.22 17th September
- 2002, timezone 0 */
-static time_t ads_parse_time(const char *str)
-{
- struct tm tm;
-
- ZERO_STRUCT(tm);
-
- if (sscanf(str, "%4d%2d%2d%2d%2d%2d",
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
- &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
- return 0;
- }
- tm.tm_year -= 1900;
- tm.tm_mon -= 1;
-
- return timegm(&tm);
-}
-
-
-/**
- * Find the servers name and realm - this can be done before authentication
- * The ldapServiceName field on w2k looks like this:
- * vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG
- * @param ads connection to ads server
- * @return status of search
- **/
-ADS_STATUS ads_server_info(ADS_STRUCT *ads)
-{
- const char *attrs[] = {"ldapServiceName", "currentTime", NULL};
- ADS_STATUS status;
- void *res;
- char *value;
- char *p;
- char *timestr;
- TALLOC_CTX *ctx;
-
- if (!(ctx = talloc_init("ads_server_info"))) {
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
- status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
- if (!ADS_ERR_OK(status)) return status;
-
- value = ads_pull_string(ads, ctx, res, "ldapServiceName");
- if (!value) {
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- timestr = ads_pull_string(ads, ctx, res, "currentTime");
- if (!timestr) {
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- ldap_msgfree(res);
-
- p = strchr(value, ':');
- if (!p) {
- talloc_destroy(ctx);
- DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' "
- "so was deemed invalid\n"));
- return ADS_ERROR(LDAP_DECODING_ERROR);
- }
-
- SAFE_FREE(ads->config.ldap_server_name);
-
- ads->config.ldap_server_name = strdup(p+1);
- p = strchr(ads->config.ldap_server_name, '$');
- if (!p || p[1] != '@') {
- talloc_destroy(ctx);
- DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'"
- " so was deemed invalid\n", ads->config.ldap_server_name));
- SAFE_FREE(ads->config.ldap_server_name);
- return ADS_ERROR(LDAP_DECODING_ERROR);
- }
-
- *p = 0;
-
- SAFE_FREE(ads->config.realm);
- SAFE_FREE(ads->config.bind_path);
-
- ads->config.realm = strdup(p+2);
- ads->config.bind_path = ads_build_dn(ads->config.realm);
-
- DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n",
- ads->config.ldap_server_name, ads->config.realm,
- ads->config.bind_path));
-
- ads->config.current_time = ads_parse_time(timestr);
-
- if (ads->config.current_time != 0) {
- ads->auth.time_offset = ads->config.current_time - time(NULL);
- DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset));
- }
-
- talloc_destroy(ctx);
-
- return ADS_SUCCESS;
-}
-
-/**
- * find the domain sid for our domain
- * @param ads connection to ads server
- * @param sid Pointer to domain sid
- * @return status of search
- **/
-ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
-{
- const char *attrs[] = {"objectSid", NULL};
- void *res;
- ADS_STATUS rc;
-
- rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
- attrs, &res);
- if (!ADS_ERR_OK(rc)) return rc;
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- return ADS_ERROR_SYSTEM(ENOENT);
- }
- ads_msgfree(ads, res);
-
- return ADS_SUCCESS;
-}
-
-/* this is rather complex - we need to find the allternate (netbios) name
- for the domain, but there isn't a simple query to do this. Instead
- we look for the principle names on the DCs account and find one that has
- the right form, then extract the netbios name of the domain from that
-
- NOTE! better method is this:
-
-bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName
-
-but you need to force the bind path to match the configurationNamingContext from the rootDSE
-
-*/
-ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup)
-{
- char *expr;
- ADS_STATUS rc;
- char **principles;
- char *prefix;
- int prefix_length;
- int i;
- void *res;
- const char *attrs[] = {"servicePrincipalName", NULL};
- int num_principals;
-
- (*workgroup) = NULL;
-
- asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))",
- ads->config.ldap_server_name, ads->config.realm);
- rc = ads_search(ads, &res, expr, attrs);
- free(expr);
-
- if (!ADS_ERR_OK(rc)) {
- return rc;
- }
-
- principles = ads_pull_strings(ads, mem_ctx, res,
- "servicePrincipalName", &num_principals);
-
- ads_msgfree(ads, res);
-
- if (!principles) {
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- asprintf(&prefix, "HOST/%s.%s/",
- ads->config.ldap_server_name,
- ads->config.realm);
-
- prefix_length = strlen(prefix);
-
- for (i=0;principles[i]; i++) {
- if (strnequal(principles[i], prefix, prefix_length) &&
- !strequal(ads->config.realm, principles[i]+prefix_length) &&
- !strchr(principles[i]+prefix_length, '.')) {
- /* found an alternate (short) name for the domain. */
- DEBUG(3,("Found alternate name '%s' for realm '%s'\n",
- principles[i]+prefix_length,
- ads->config.realm));
- (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length);
- break;
- }
- }
- free(prefix);
-
- if (!*workgroup) {
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- return ADS_SUCCESS;
-}
-
-#endif
diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c
deleted file mode 100644
index 1448074ea02..00000000000
--- a/source/libads/ldap_printer.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) printer utility library
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_ADS
-
-/*
- find a printer given the name and the hostname
- Note that results "res" may be allocated on return so that the
- results can be used. It should be freed using ads_msgfree.
-*/
-ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
- const char *printer, const char *servername)
-{
- ADS_STATUS status;
- char *srv_dn, **srv_cn, *s;
- const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
-
- status = ads_find_machine_acct(ads, res, servername);
- if (!ADS_ERR_OK(status)) {
- DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n",
- servername));
- return status;
- }
- srv_dn = ldap_get_dn(ads->ld, *res);
- srv_cn = ldap_explode_dn(srv_dn, 1);
- ads_msgfree(ads, *res);
-
- asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
- status = ads_search(ads, res, s, attrs);
-
- ldap_memfree(srv_dn);
- ldap_value_free(srv_cn);
- free(s);
- return status;
-}
-
-ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
-{
- char *ldap_expr;
- const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
- "serverName", "description", NULL };
-
- /* For the moment only display all printers */
-
- ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
- "(objectCategory=printQueue))";
-
- return ads_search(ads, res, ldap_expr, attrs);
-}
-
-/*
- modify a printer entry in the directory
-*/
-ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
- TALLOC_CTX *ctx, const ADS_MODLIST *mods)
-{
- return ads_gen_mod(ads, prt_dn, *mods);
-}
-
-/*
- add a printer to the directory
-*/
-ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
- TALLOC_CTX *ctx, ADS_MODLIST *mods)
-{
- ads_mod_str(ctx, mods, "objectClass", "printQueue");
- return ads_gen_add(ads, prt_dn, *mods);
-}
-
-/*
- map a REG_SZ to an ldap mod
-*/
-static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const REGISTRY_VALUE *value)
-{
- char *str_value = NULL;
- ADS_STATUS status;
-
- if (value->type != REG_SZ)
- return False;
-
- if (value->size && *((smb_ucs2_t *) value->data_p)) {
- pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
- status = ads_mod_str(ctx, mods, value->valuename, str_value);
- return ADS_ERR_OK(status);
- }
- return True;
-
-}
-
-/*
- map a REG_DWORD to an ldap mod
-*/
-static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const REGISTRY_VALUE *value)
-{
- char *str_value = NULL;
- ADS_STATUS status;
-
- if (value->type != REG_DWORD)
- return False;
- str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
- status = ads_mod_str(ctx, mods, value->valuename, str_value);
- return ADS_ERR_OK(status);
-}
-
-/*
- map a boolean REG_BINARY to an ldap mod
-*/
-static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const REGISTRY_VALUE *value)
-{
- char *str_value;
- ADS_STATUS status;
-
- if ((value->type != REG_BINARY) || (value->size != 1))
- return False;
- str_value = talloc_asprintf(ctx, "%s",
- *(value->data_p) ? "TRUE" : "FALSE");
- status = ads_mod_str(ctx, mods, value->valuename, str_value);
- return ADS_ERR_OK(status);
-}
-
-/*
- map a REG_MULTI_SZ to an ldap mod
-*/
-static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- const REGISTRY_VALUE *value)
-{
- char **str_values = NULL;
- smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
- uint32 size = 0, num_vals = 0, i=0;
- ADS_STATUS status;
-
- if (value->type != REG_MULTI_SZ)
- return False;
-
- while(cur_str && *cur_str && (size < value->size)) {
- size += 2 * (strlen_w(cur_str) + 1);
- cur_str += strlen_w(cur_str) + 1;
- num_vals++;
- };
-
- if (num_vals) {
- str_values = talloc(ctx,
- (num_vals + 1) * sizeof(smb_ucs2_t *));
- memset(str_values, '\0',
- (num_vals + 1) * sizeof(smb_ucs2_t *));
-
- cur_str = (smb_ucs2_t *) value->data_p;
- for (i=0; i < num_vals; i++)
- cur_str += pull_ucs2_talloc(ctx, &str_values[i],
- cur_str);
-
- status = ads_mod_strlist(ctx, mods, value->valuename,
- (const char **) str_values);
- return ADS_ERR_OK(status);
- }
- return True;
-}
-
-struct valmap_to_ads {
- const char *valname;
- BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
-};
-
-/*
- map a REG_SZ to an ldap mod
-*/
-static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- REGISTRY_VALUE *value)
-{
- const struct valmap_to_ads map[] = {
- {SPOOL_REG_ASSETNUMBER, map_sz},
- {SPOOL_REG_BYTESPERMINUTE, map_dword},
- {SPOOL_REG_DEFAULTPRIORITY, map_dword},
- {SPOOL_REG_DESCRIPTION, map_sz},
- {SPOOL_REG_DRIVERNAME, map_sz},
- {SPOOL_REG_DRIVERVERSION, map_dword},
- {SPOOL_REG_FLAGS, map_dword},
- {SPOOL_REG_LOCATION, map_sz},
- {SPOOL_REG_OPERATINGSYSTEM, map_sz},
- {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
- {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
- {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
- {SPOOL_REG_PORTNAME, map_multi_sz},
- {SPOOL_REG_PRINTATTRIBUTES, map_dword},
- {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
- {SPOOL_REG_PRINTCOLLATE, map_bool},
- {SPOOL_REG_PRINTCOLOR, map_bool},
- {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
- {SPOOL_REG_PRINTENDTIME, map_dword},
- {SPOOL_REG_PRINTFORMNAME, map_sz},
- {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
- {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
- {SPOOL_REG_PRINTMACADDRESS, map_sz},
- {SPOOL_REG_PRINTMAXCOPIES, map_sz},
- {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
- {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
- {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
- {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
- {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
- {SPOOL_REG_PRINTMEMORY, map_dword},
- {SPOOL_REG_PRINTMINXEXTENT, map_dword},
- {SPOOL_REG_PRINTMINYEXTENT, map_dword},
- {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
- {SPOOL_REG_PRINTNOTIFY, map_sz},
- {SPOOL_REG_PRINTNUMBERUP, map_dword},
- {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
- {SPOOL_REG_PRINTOWNER, map_sz},
- {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
- {SPOOL_REG_PRINTRATE, map_dword},
- {SPOOL_REG_PRINTRATEUNIT, map_sz},
- {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
- {SPOOL_REG_PRINTSHARENAME, map_sz},
- {SPOOL_REG_PRINTSPOOLING, map_sz},
- {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
- {SPOOL_REG_PRINTSTARTTIME, map_dword},
- {SPOOL_REG_PRINTSTATUS, map_sz},
- {SPOOL_REG_PRIORITY, map_dword},
- {SPOOL_REG_SERVERNAME, map_sz},
- {SPOOL_REG_SHORTSERVERNAME, map_sz},
- {SPOOL_REG_UNCNAME, map_sz},
- {SPOOL_REG_URL, map_sz},
- {SPOOL_REG_VERSIONNUMBER, map_dword},
- {NULL, NULL}
- };
- int i;
-
- for (i=0; map[i].valname; i++) {
- if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
- if (!map[i].fn(ctx, mods, value)) {
- DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
- } else {
- DEBUG(7, ("Mapped value %s\n", value->valuename));
- }
-
- }
- }
-}
-
-
-WERROR get_remote_printer_publishing_data(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- ADS_MODLIST *mods,
- const char *printer)
-{
- WERROR result;
- char *printername, *servername;
- REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
- BOOL got_dsdriver = False, got_dsspooler = False;
- uint32 needed, i;
- POLICY_HND pol;
-
- asprintf(&servername, "\\\\%s", cli->desthost);
- asprintf(&printername, "%s\\%s", servername, printer);
- if (!servername || !printername) {
- DEBUG(3, ("Insufficient memory\n"));
- return WERR_NOMEM;
- }
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, cli->user_name, &pol);
- if (!W_ERROR_IS_OK(result)) {
- DEBUG(3, ("Unable to open printer %s, error is %s.\n",
- printername, dos_errstr(result)));
- return result;
- }
-
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
- &pol, SPOOL_DSDRIVER_KEY, NULL);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
- NULL, &pol,
- SPOOL_DSDRIVER_KEY,
- &dsdriver_ctr);
-
- if (!W_ERROR_IS_OK(result)) {
- DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
- printername, dos_errstr(result)));
- } else {
-
- /* Have the data we need now, so start building */
- got_dsdriver = True;
- for (i=0; i < dsdriver_ctr.num_values; i++)
- map_regval_to_ads(mem_ctx, mods,
- dsdriver_ctr.values[i]);
- }
-
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
- &pol, SPOOL_DSSPOOLER_KEY,
- NULL);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
- NULL, &pol,
- SPOOL_DSSPOOLER_KEY,
- &dsspooler_ctr);
-
- if (!W_ERROR_IS_OK(result)) {
- DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
- printername, dos_errstr(result)));
- } else {
- got_dsspooler = True;
- for (i=0; i < dsspooler_ctr.num_values; i++)
- map_regval_to_ads(mem_ctx, mods,
- dsspooler_ctr.values[i]);
- }
-
- ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
-
- if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
- if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
-
- return result;
-}
-
-BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
- ADS_MODLIST *mods,
- NT_PRINTER_DATA *data)
-{
- uint32 key,val;
-
- for (key=0; key < data->num_keys; key++) {
- REGVAL_CTR ctr = data->keys[key].values;
- for (val=0; val < ctr.num_values; val++)
- map_regval_to_ads(mem_ctx, mods, ctr.values[val]);
- }
- return True;
-}
-
-#endif
diff --git a/source/libads/ldap_user.c b/source/libads/ldap_user.c
deleted file mode 100644
index 56a0d8013b2..00000000000
--- a/source/libads/ldap_user.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_ADS
-
-/*
- find a user account
-*/
-ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user)
-{
- ADS_STATUS status;
- char *ldap_exp;
- const char *attrs[] = {"*", NULL};
- char *escaped_user = escape_ldap_string_alloc(user);
- if (!escaped_user) {
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
- asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user);
- status = ads_search(ads, res, ldap_exp, attrs);
- SAFE_FREE(ldap_exp);
- SAFE_FREE(escaped_user);
- return status;
-}
-
-ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user,
- const char *container, const char *fullname)
-{
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
- ADS_STATUS status;
- const char *upn, *new_dn, *name, *controlstr;
- const char *objectClass[] = {"top", "person", "organizationalPerson",
- "user", NULL};
-
- if (fullname && *fullname) name = fullname;
- else name = user;
-
- if (!(ctx = talloc_init("ads_add_user_acct")))
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- status = ADS_ERROR(LDAP_NO_MEMORY);
-
- if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm)))
- goto done;
- if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container,
- ads->config.bind_path)))
- goto done;
- if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT)))
- goto done;
- if (!(mods = ads_init_mods(ctx)))
- goto done;
-
- ads_mod_str(ctx, &mods, "cn", name);
- ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
- ads_mod_str(ctx, &mods, "userPrincipalName", upn);
- ads_mod_str(ctx, &mods, "name", name);
- ads_mod_str(ctx, &mods, "displayName", name);
- ads_mod_str(ctx, &mods, "sAMAccountName", user);
- ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
- status = ads_gen_add(ads, new_dn, mods);
-
- done:
- talloc_destroy(ctx);
- return status;
-}
-
-ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group,
- const char *container, const char *comment)
-{
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
- ADS_STATUS status;
- char *new_dn;
- const char *objectClass[] = {"top", "group", NULL};
-
- if (!(ctx = talloc_init("ads_add_group_acct")))
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- status = ADS_ERROR(LDAP_NO_MEMORY);
-
- if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", group, container,
- ads->config.bind_path)))
- goto done;
- if (!(mods = ads_init_mods(ctx)))
- goto done;
-
- ads_mod_str(ctx, &mods, "cn", group);
- ads_mod_strlist(ctx, &mods, "objectClass",objectClass);
- ads_mod_str(ctx, &mods, "name", group);
- if (comment && *comment)
- ads_mod_str(ctx, &mods, "description", comment);
- ads_mod_str(ctx, &mods, "sAMAccountName", group);
- status = ads_gen_add(ads, new_dn, mods);
-
- done:
- talloc_destroy(ctx);
- return status;
-}
-#endif
diff --git a/source/libads/ldap_utils.c b/source/libads/ldap_utils.c
deleted file mode 100644
index 991f16c8454..00000000000
--- a/source/libads/ldap_utils.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Some Helpful wrappers on LDAP
-
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_LDAP
-/*
- a wrapper around ldap_search_s that retries depending on the error code
- this is supposed to catch dropped connections and auto-reconnect
-*/
-ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
- const char *expr,
- const char **attrs, void **res)
-{
- ADS_STATUS status;
- int count = 3;
- char *bp;
-
- *res = NULL;
-
- if (!ads->ld &&
- time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
- return ADS_ERROR(LDAP_SERVER_DOWN);
- }
-
- bp = strdup(bind_path);
-
- if (!bp) {
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- while (count--) {
- *res = NULL;
- status = ads_do_search_all(ads, bp, scope, expr, attrs, res);
- if (ADS_ERR_OK(status)) {
- DEBUG(5,("Search for %s gave %d replies\n",
- expr, ads_count_replies(ads, *res)));
- SAFE_FREE(bp);
- return status;
- }
-
- if (*res)
- ads_msgfree(ads, *res);
- *res = NULL;
-
- DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
- ads->config.realm, ads_errstr(status)));
-
- if (ads->ld) {
- ldap_unbind(ads->ld);
- }
-
- ads->ld = NULL;
- status = ads_connect(ads);
-
- if (!ADS_ERR_OK(status)) {
- DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
- ads_errstr(status)));
- ads_destroy(&ads);
- SAFE_FREE(bp);
- return status;
- }
- }
- SAFE_FREE(bp);
-
- if (!ADS_ERR_OK(status))
- DEBUG(1,("ads reopen failed after error %s\n",
- ads_errstr(status)));
-
- return status;
-}
-
-
-ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
- const char *expr,
- const char **attrs)
-{
- return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
- expr, attrs, res);
-}
-
-ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res,
- const char *dn,
- const char **attrs)
-{
- return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
- "(objectclass=*)", attrs, res);
-}
-#endif
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
deleted file mode 100644
index 1ab71c6ee51..00000000000
--- a/source/libads/sasl.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads sasl code
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_LDAP
-
-/*
- perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can
- we fit on one socket??)
-*/
-static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
-{
- const char *mechs[] = {OID_NTLMSSP, NULL};
- DATA_BLOB msg1;
- DATA_BLOB blob, chal1, chal2, auth;
- uint8 challenge[8];
- uint8 nthash[24], lmhash[24], sess_key[16];
- uint32 neg_flags;
- struct berval cred, *scred;
- ADS_STATUS status;
- int rc;
-
- if (!ads->auth.password) {
- /* No password, don't segfault below... */
- return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- neg_flags = NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_128 |
- NTLMSSP_NEGOTIATE_NTLM;
-
- memset(sess_key, 0, 16);
-
- /* generate the ntlmssp negotiate packet */
- msrpc_gen(&blob, "CddB",
- "NTLMSSP",
- NTLMSSP_NEGOTIATE,
- neg_flags,
- sess_key, 16);
-
- /* and wrap it in a SPNEGO wrapper */
- msg1 = gen_negTokenTarg(mechs, blob);
- data_blob_free(&blob);
-
- cred.bv_val = (char *)msg1.data;
- cred.bv_len = msg1.length;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
- if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
- status = ADS_ERROR(rc);
- goto failed;
- }
-
- blob = data_blob(scred->bv_val, scred->bv_len);
-
- /* the server gives us back two challenges */
- if (!spnego_parse_challenge(blob, &chal1, &chal2)) {
- DEBUG(3,("Failed to parse challenges\n"));
- status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
- goto failed;
- }
-
- data_blob_free(&blob);
-
- /* encrypt the password with the challenge */
- memcpy(challenge, chal1.data + 24, 8);
- SMBencrypt(ads->auth.password, challenge,lmhash);
- SMBNTencrypt(ads->auth.password, challenge,nthash);
-
- data_blob_free(&chal1);
- data_blob_free(&chal2);
-
- /* this generates the actual auth packet */
- msrpc_gen(&blob, "CdBBUUUBd",
- "NTLMSSP",
- NTLMSSP_AUTH,
- lmhash, 24,
- nthash, 24,
- lp_workgroup(),
- ads->auth.user_name,
- global_myname(),
- sess_key, 16,
- neg_flags);
-
- /* wrap it in SPNEGO */
- auth = spnego_gen_auth(blob);
-
- data_blob_free(&blob);
-
- /* now send the auth packet and we should be done */
- cred.bv_val = (char *)auth.data;
- cred.bv_len = auth.length;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
-
- return ADS_ERROR(rc);
-
-failed:
- return status;
-}
-
-/*
- perform a LDAP/SASL/SPNEGO/KRB5 bind
-*/
-static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal)
-{
- DATA_BLOB blob;
- struct berval cred, *scred;
- DATA_BLOB session_key;
- int rc;
-
- rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key);
-
- if (rc) {
- return ADS_ERROR_KRB5(rc);
- }
-
- /* now send the auth packet and we should be done */
- cred.bv_val = (char *)blob.data;
- cred.bv_len = blob.length;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
-
- data_blob_free(&blob);
- data_blob_free(&session_key);
-
- return ADS_ERROR(rc);
-}
-
-/*
- this performs a SASL/SPNEGO bind
-*/
-static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
-{
- struct berval *scred=NULL;
- int rc, i;
- ADS_STATUS status;
- DATA_BLOB blob;
- char *principal;
- char *OIDs[ASN1_MAX_OIDS];
- BOOL got_kerberos_mechanism = False;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
-
- if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
- status = ADS_ERROR(rc);
- goto failed;
- }
-
- blob = data_blob(scred->bv_val, scred->bv_len);
-
- ber_bvfree(scred);
-
-#if 0
- file_save("sasl_spnego.dat", blob.data, blob.length);
-#endif
-
- /* the server sent us the first part of the SPNEGO exchange in the negprot
- reply */
- if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
- data_blob_free(&blob);
- status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
- goto failed;
- }
- data_blob_free(&blob);
-
- /* make sure the server understands kerberos */
- for (i=0;OIDs[i];i++) {
- DEBUG(3,("got OID=%s\n", OIDs[i]));
- if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
- strcmp(OIDs[i], OID_KERBEROS5) == 0) {
- got_kerberos_mechanism = True;
- }
- free(OIDs[i]);
- }
- DEBUG(3,("got principal=%s\n", principal));
-
-#ifdef HAVE_KRB5
- if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
- got_kerberos_mechanism) {
- status = ads_sasl_spnego_krb5_bind(ads, principal);
- if (ADS_ERR_OK(status))
- return status;
-
- status = ADS_ERROR_KRB5(ads_kinit_password(ads));
-
- if (ADS_ERR_OK(status)) {
- status = ads_sasl_spnego_krb5_bind(ads, principal);
- }
-
- /* only fallback to NTLMSSP if allowed */
- if (ADS_ERR_OK(status) ||
- !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
- return status;
- }
- }
-#endif
-
- /* lets do NTLMSSP ... this has the big advantage that we don't need
- to sync clocks, and we don't rely on special versions of the krb5
- library for HMAC_MD4 encryption */
- return ads_sasl_spnego_ntlmssp_bind(ads);
-
-failed:
- return status;
-}
-
-#ifdef HAVE_GSSAPI
-#define MAX_GSS_PASSES 3
-
-/* this performs a SASL/gssapi bind
- we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl
- is very dependent on correctly configured DNS whereas
- this routine is much less fragile
- see RFC2078 and RFC2222 for details
-*/
-static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
-{
- uint32 minor_status;
- gss_name_t serv_name;
- gss_buffer_desc input_name;
- gss_ctx_id_t context_handle;
- gss_OID mech_type = GSS_C_NULL_OID;
- gss_buffer_desc output_token, input_token;
- uint32 ret_flags, conf_state;
- struct berval cred;
- struct berval *scred;
- int i=0;
- int gss_rc, rc;
- uint8 *p;
- uint32 max_msg_size;
- char *sname;
- unsigned sec_layer;
- ADS_STATUS status;
- krb5_principal principal;
- krb5_context ctx;
- krb5_enctype enc_types[] = {
-#ifdef ENCTYPE_ARCFOUR_HMAC
- ENCTYPE_ARCFOUR_HMAC,
-#endif
- ENCTYPE_DES_CBC_MD5,
- ENCTYPE_NULL};
- gss_OID_desc nt_principal =
- {10, "\052\206\110\206\367\022\001\002\002\002"};
-
- /* we need to fetch a service ticket as the ldap user in the
- servers realm, regardless of our realm */
- asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm);
- krb5_init_context(&ctx);
- krb5_set_default_tgs_ktypes(ctx, enc_types);
- krb5_parse_name(ctx, sname, &principal);
- free(sname);
- krb5_free_context(ctx);
-
- input_name.value = &principal;
- input_name.length = sizeof(principal);
-
- gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name);
- if (gss_rc) {
- return ADS_ERROR_GSS(gss_rc, minor_status);
- }
-
- context_handle = GSS_C_NO_CONTEXT;
-
- input_token.value = NULL;
- input_token.length = 0;
-
- for (i=0; i < MAX_GSS_PASSES; i++) {
- gss_rc = gss_init_sec_context(&minor_status,
- GSS_C_NO_CREDENTIAL,
- &context_handle,
- serv_name,
- mech_type,
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
- 0,
- NULL,
- &input_token,
- NULL,
- &output_token,
- &ret_flags,
- NULL);
-
- if (input_token.value) {
- gss_release_buffer(&minor_status, &input_token);
- }
-
- if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
- status = ADS_ERROR_GSS(gss_rc, minor_status);
- goto failed;
- }
-
- cred.bv_val = output_token.value;
- cred.bv_len = output_token.length;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
- &scred);
- if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
- status = ADS_ERROR(rc);
- goto failed;
- }
-
- if (output_token.value) {
- gss_release_buffer(&minor_status, &output_token);
- }
-
- if (scred) {
- input_token.value = scred->bv_val;
- input_token.length = scred->bv_len;
- } else {
- input_token.value = NULL;
- input_token.length = 0;
- }
-
- if (gss_rc == 0) break;
- }
-
- gss_release_name(&minor_status, &serv_name);
-
- gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
- (int *)&conf_state,NULL);
- if (gss_rc) {
- status = ADS_ERROR_GSS(gss_rc, minor_status);
- goto failed;
- }
-
- gss_release_buffer(&minor_status, &input_token);
-
- p = (uint8 *)output_token.value;
-
- file_save("sasl_gssapi.dat", output_token.value, output_token.length);
-
- max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3];
- sec_layer = *p;
-
- gss_release_buffer(&minor_status, &output_token);
-
- output_token.value = malloc(strlen(ads->config.bind_path) + 8);
- p = output_token.value;
-
- *p++ = 1; /* no sign & seal selection */
- /* choose the same size as the server gave us */
- *p++ = max_msg_size>>16;
- *p++ = max_msg_size>>8;
- *p++ = max_msg_size;
- snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
- p += strlen((const char *)p);
-
- output_token.length = PTR_DIFF(p, output_token.value);
-
- gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
- &output_token, (int *)&conf_state,
- &input_token);
- if (gss_rc) {
- status = ADS_ERROR_GSS(gss_rc, minor_status);
- goto failed;
- }
-
- free(output_token.value);
-
- cred.bv_val = input_token.value;
- cred.bv_len = input_token.length;
-
- rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL,
- &scred);
- status = ADS_ERROR(rc);
-
- gss_release_buffer(&minor_status, &input_token);
-
-failed:
- return status;
-}
-#endif
-
-/* mapping between SASL mechanisms and functions */
-static struct {
- const char *name;
- ADS_STATUS (*fn)(ADS_STRUCT *);
-} sasl_mechanisms[] = {
- {"GSS-SPNEGO", ads_sasl_spnego_bind},
-#ifdef HAVE_GSSAPI
- {"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */
-#endif
- {NULL, NULL}
-};
-
-ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
-{
- const char *attrs[] = {"supportedSASLMechanisms", NULL};
- char **values;
- ADS_STATUS status;
- int i, j;
- void *res;
-
- /* get a list of supported SASL mechanisms */
- status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
- if (!ADS_ERR_OK(status)) return status;
-
- values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms");
-
- /* try our supported mechanisms in order */
- for (i=0;sasl_mechanisms[i].name;i++) {
- /* see if the server supports it */
- for (j=0;values && values[j];j++) {
- if (strcmp(values[j], sasl_mechanisms[i].name) == 0) {
- DEBUG(4,("Found SASL mechanism %s\n", values[j]));
- status = sasl_mechanisms[i].fn(ads);
- ldap_value_free(values);
- ldap_msgfree(res);
- return status;
- }
- }
- }
-
- ldap_value_free(values);
- ldap_msgfree(res);
- return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED);
-}
-
-#endif
-
diff --git a/source/libads/util.c b/source/libads/util.c
deleted file mode 100644
index 9912a7ba831..00000000000
--- a/source/libads/util.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- krb5 set password implementation
- Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal)
-{
- char *tmp_password;
- char *password;
- char *new_password;
- char *service_principal;
- ADS_STATUS ret;
- uint32 sec_channel_type;
-
- if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) {
- DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal));
- return ADS_ERROR_SYSTEM(ENOENT);
- }
-
- tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
- new_password = strdup(tmp_password);
-
- asprintf(&service_principal, "HOST/%s", host_principal);
-
- ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset);
-
- if (!ADS_ERR_OK(ret)) goto failed;
-
- if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) {
- DEBUG(1,("Failed to save machine password\n"));
- return ADS_ERROR_SYSTEM(EACCES);
- }
-
-failed:
- SAFE_FREE(service_principal);
- SAFE_FREE(new_password);
-
- return ret;
-}
-
-
-
-#endif
diff --git a/source/libsmb/asn1.c b/source/libsmb/asn1.c
deleted file mode 100644
index ecc5e3dee64..00000000000
--- a/source/libsmb/asn1.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- simple SPNEGO routines
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* free an asn1 structure */
-void asn1_free(ASN1_DATA *data)
-{
- SAFE_FREE(data->data);
-}
-
-/* write to the ASN1 buffer, advancing the buffer pointer */
-BOOL asn1_write(ASN1_DATA *data, const void *p, int len)
-{
- if (data->has_error) return False;
- if (data->length < data->ofs+len) {
- uint8 *newp;
- newp = Realloc(data->data, data->ofs+len);
- if (!newp) {
- SAFE_FREE(data->data);
- data->has_error = True;
- return False;
- }
- data->data = newp;
- data->length = data->ofs+len;
- }
- memcpy(data->data + data->ofs, p, len);
- data->ofs += len;
- return True;
-}
-
-/* useful fn for writing a uint8 */
-BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v)
-{
- return asn1_write(data, &v, 1);
-}
-
-/* push a tag onto the asn1 data buffer. Used for nested structures */
-BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag)
-{
- struct nesting *nesting;
-
- asn1_write_uint8(data, tag);
- nesting = (struct nesting *)malloc(sizeof(struct nesting));
- if (!nesting) {
- data->has_error = True;
- return False;
- }
-
- nesting->start = data->ofs;
- nesting->next = data->nesting;
- data->nesting = nesting;
- return asn1_write_uint8(data, 0xff);
-}
-
-/* pop a tag */
-BOOL asn1_pop_tag(ASN1_DATA *data)
-{
- struct nesting *nesting;
- size_t len;
-
- nesting = data->nesting;
-
- if (!nesting) {
- data->has_error = True;
- return False;
- }
- len = data->ofs - (nesting->start+1);
- /* yes, this is ugly. We don't know in advance how many bytes the length
- of a tag will take, so we assumed 1 byte. If we were wrong then we
- need to correct our mistake */
- if (len > 255) {
- data->data[nesting->start] = 0x82;
- if (!asn1_write_uint8(data, 0)) return False;
- if (!asn1_write_uint8(data, 0)) return False;
- memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
- data->data[nesting->start+1] = len>>8;
- data->data[nesting->start+2] = len&0xff;
- } else if (len > 127) {
- data->data[nesting->start] = 0x81;
- if (!asn1_write_uint8(data, 0)) return False;
- memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
- data->data[nesting->start+1] = len;
- } else {
- data->data[nesting->start] = len;
- }
-
- data->nesting = nesting->next;
- free(nesting);
- return True;
-}
-
-
-/* write an integer */
-BOOL asn1_write_Integer(ASN1_DATA *data, int i)
-{
- if (!asn1_push_tag(data, ASN1_INTEGER)) return False;
- do {
- asn1_write_uint8(data, i);
- i = i >> 8;
- } while (i);
- return asn1_pop_tag(data);
-}
-
-/* write an object ID to a ASN1 buffer */
-BOOL asn1_write_OID(ASN1_DATA *data, const char *OID)
-{
- unsigned v, v2;
- const char *p = (const char *)OID;
- char *newp;
-
- if (!asn1_push_tag(data, ASN1_OID))
- return False;
- v = strtol(p, &newp, 10);
- p = newp;
- v2 = strtol(p, &newp, 10);
- p = newp;
- if (!asn1_write_uint8(data, 40*v + v2))
- return False;
-
- while (*p) {
- v = strtol(p, &newp, 10);
- p = newp;
- if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff));
- if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff));
- if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff));
- if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff));
- if (!asn1_write_uint8(data, v&0x7f))
- return False;
- }
- return asn1_pop_tag(data);
-}
-
-/* write an octet string */
-BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length)
-{
- asn1_push_tag(data, ASN1_OCTET_STRING);
- asn1_write(data, p, length);
- asn1_pop_tag(data);
- return !data->has_error;
-}
-
-/* write a general string */
-BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s)
-{
- asn1_push_tag(data, ASN1_GENERAL_STRING);
- asn1_write(data, s, strlen(s));
- asn1_pop_tag(data);
- return !data->has_error;
-}
-
-/* write a BOOLEAN */
-BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v)
-{
- asn1_write_uint8(data, ASN1_BOOLEAN);
- asn1_write_uint8(data, v);
- return !data->has_error;
-}
-
-/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the
- above boolean is bogus. Need to check */
-BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v)
-{
- asn1_push_tag(data, ASN1_BOOLEAN);
- asn1_write_uint8(data, v);
- asn1_pop_tag(data);
- return !data->has_error;
-}
-
-/* check a BOOLEAN */
-BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v)
-{
- uint8 b = 0;
-
- asn1_read_uint8(data, &b);
- if (b != ASN1_BOOLEAN) {
- data->has_error = True;
- return False;
- }
- asn1_read_uint8(data, &b);
- if (b != v) {
- data->has_error = True;
- return False;
- }
- return !data->has_error;
-}
-
-
-/* load a ASN1_DATA structure with a lump of data, ready to be parsed */
-BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob)
-{
- ZERO_STRUCTP(data);
- data->data = memdup(blob.data, blob.length);
- if (!data->data) {
- data->has_error = True;
- return False;
- }
- data->length = blob.length;
- return True;
-}
-
-/* read from a ASN1 buffer, advancing the buffer pointer */
-BOOL asn1_read(ASN1_DATA *data, void *p, int len)
-{
- if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) {
- data->has_error = True;
- return False;
- }
-
- if (data->ofs + len > data->length) {
- data->has_error = True;
- return False;
- }
- memcpy(p, data->data + data->ofs, len);
- data->ofs += len;
- return True;
-}
-
-/* read a uint8 from a ASN1 buffer */
-BOOL asn1_read_uint8(ASN1_DATA *data, uint8 *v)
-{
- return asn1_read(data, v, 1);
-}
-
-/* start reading a nested asn1 structure */
-BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag)
-{
- uint8 b;
- struct nesting *nesting;
-
- if (!asn1_read_uint8(data, &b))
- return False;
-
- if (b != tag) {
- data->has_error = True;
- return False;
- }
- nesting = (struct nesting *)malloc(sizeof(struct nesting));
- if (!nesting) {
- data->has_error = True;
- return False;
- }
-
- if (!asn1_read_uint8(data, &b)) {
- return False;
- }
-
- if (b & 0x80) {
- int n = b & 0x7f;
- if (!asn1_read_uint8(data, &b))
- return False;
- nesting->taglen = b;
- while (n > 1) {
- if (!asn1_read_uint8(data, &b))
- return False;
- nesting->taglen = (nesting->taglen << 8) | b;
- n--;
- }
- } else {
- nesting->taglen = b;
- }
- nesting->start = data->ofs;
- nesting->next = data->nesting;
- data->nesting = nesting;
- return !data->has_error;
-}
-
-
-/* stop reading a tag */
-BOOL asn1_end_tag(ASN1_DATA *data)
-{
- struct nesting *nesting;
-
- /* make sure we read it all */
- if (asn1_tag_remaining(data) != 0) {
- data->has_error = True;
- return False;
- }
-
- nesting = data->nesting;
-
- if (!nesting) {
- data->has_error = True;
- return False;
- }
-
- data->nesting = nesting->next;
- free(nesting);
- return True;
-}
-
-/* work out how many bytes are left in this nested tag */
-int asn1_tag_remaining(ASN1_DATA *data)
-{
- if (!data->nesting) {
- data->has_error = True;
- return -1;
- }
- return data->nesting->taglen - (data->ofs - data->nesting->start);
-}
-
-/* read an object ID from a ASN1 buffer */
-BOOL asn1_read_OID(ASN1_DATA *data, char **OID)
-{
- uint8 b;
- pstring oid;
- fstring el;
-
- if (!asn1_start_tag(data, ASN1_OID)) return False;
- asn1_read_uint8(data, &b);
-
- oid[0] = 0;
- fstr_sprintf(el, "%u", b/40);
- pstrcat(oid, el);
- fstr_sprintf(el, " %u", b%40);
- pstrcat(oid, el);
-
- while (asn1_tag_remaining(data) > 0) {
- unsigned v = 0;
- do {
- asn1_read_uint8(data, &b);
- v = (v<<7) | (b&0x7f);
- } while (!data->has_error && b & 0x80);
- fstr_sprintf(el, " %u", v);
- pstrcat(oid, el);
- }
-
- asn1_end_tag(data);
-
- *OID = strdup(oid);
-
- return !data->has_error;
-}
-
-/* check that the next object ID is correct */
-BOOL asn1_check_OID(ASN1_DATA *data, const char *OID)
-{
- char *id;
-
- if (!asn1_read_OID(data, &id)) return False;
-
- if (strcmp(id, OID) != 0) {
- data->has_error = True;
- return False;
- }
- free(id);
- return True;
-}
-
-/* read a GeneralString from a ASN1 buffer */
-BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s)
-{
- int len;
- if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False;
- len = asn1_tag_remaining(data);
- if (len < 0) {
- data->has_error = True;
- return False;
- }
- *s = malloc(len+1);
- if (! *s) {
- data->has_error = True;
- return False;
- }
- asn1_read(data, *s, len);
- (*s)[len] = 0;
- asn1_end_tag(data);
- return !data->has_error;
-}
-
-/* read a octet string blob */
-BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob)
-{
- int len;
- ZERO_STRUCTP(blob);
- if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False;
- len = asn1_tag_remaining(data);
- if (len < 0) {
- data->has_error = True;
- return False;
- }
- *blob = data_blob(NULL, len);
- asn1_read(data, blob->data, len);
- asn1_end_tag(data);
- return !data->has_error;
-}
-
-/* read an interger */
-BOOL asn1_read_Integer(ASN1_DATA *data, int *i)
-{
- uint8 b;
- *i = 0;
-
- if (!asn1_start_tag(data, ASN1_INTEGER)) return False;
- while (asn1_tag_remaining(data)>0) {
- asn1_read_uint8(data, &b);
- *i = (*i << 8) + b;
- }
- return asn1_end_tag(data);
-
-}
-
-/* check a enumarted value is correct */
-BOOL asn1_check_enumerated(ASN1_DATA *data, int v)
-{
- uint8 b;
- if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False;
- asn1_read_uint8(data, &b);
- asn1_end_tag(data);
-
- if (v != b)
- data->has_error = False;
-
- return !data->has_error;
-}
-
-/* write an enumarted value to the stream */
-BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v)
-{
- if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False;
- asn1_write_uint8(data, v);
- asn1_pop_tag(data);
- return !data->has_error;
-}
diff --git a/source/rpc_client/cli_dfs.c b/source/libsmb/cli_dfs.c
index 2136b69df07..312275926c7 100644..100755
--- a/source/rpc_client/cli_dfs.c
+++ b/source/libsmb/cli_dfs.c
@@ -20,6 +20,14 @@
#include "includes.h"
+/* Opens a SMB connection to the netdfs pipe */
+
+struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_NETDFS, creds);
+}
+
/* Query DFS support */
NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -67,8 +75,8 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *entrypath, const char *servername,
- const char *sharename, const char *comment, uint32 flags)
+ char *entrypath, char *servername, char *sharename,
+ char *comment, uint32 flags)
{
prs_struct qbuf, rbuf;
DFS_Q_DFS_ADD q;
@@ -111,8 +119,7 @@ NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *entrypath, const char *servername,
- const char *sharename)
+ char *entrypath, char *servername, char *sharename)
{
prs_struct qbuf, rbuf;
DFS_Q_DFS_REMOVE q;
@@ -154,9 +161,8 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *entrypath, const char *servername,
- const char *sharename, uint32 info_level,
- DFS_INFO_CTR *ctr)
+ char *entrypath, char *servername, char *sharename,
+ uint32 info_level, DFS_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
diff --git a/source/rpc_client/cli_lsarpc.c b/source/libsmb/cli_lsarpc.c
index 980a681387f..0a0c5323304 100644..100755
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/libsmb/cli_lsarpc.c
@@ -5,8 +5,7 @@
Copyright (C) Andrew Tridgell 1992-1997,2000,
Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
Copyright (C) Paul Ashton 1997,2000,
- Copyright (C) Elrond 2000,
- Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Elrond 2000.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,6 +37,19 @@
* security authority", which is half of a password database.
**/
+/** Opens a SMB connection and connects to the LSARPC pipe.
+ *
+ * @param cli Uninitialised client handle.
+ * @param system_name NETBIOS name of the machine to connect to.
+ * @param creds User credentials to connect as.
+ * @returns Initialised client handle.
+ */
+struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds);
+}
+
/** Open a LSA policy handle
*
* @param cli Handle on an initialised SMB connection */
@@ -87,9 +99,6 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(result = r.status)) {
*pol = r.pol;
-#ifdef __INSURE__
- pol->marker = malloc(1);
-#endif
}
done:
@@ -151,9 +160,6 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(result = r.status)) {
*pol = r.pol;
-#ifdef __INSURE__
- pol->marker = (char *)malloc(1);
-#endif
}
done:
@@ -201,9 +207,6 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
-#ifdef __INSURE__
- SAFE_FREE(pol->marker);
-#endif
*pol = r.pol;
}
@@ -214,10 +217,13 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/** Lookup a list of sids */
+/** Lookup a list of sids */
+/********************************************************************
+ Converts SIDs to names. Outgoing names are in UNIX charset.
+*********************************************************************/
NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_sids, const DOM_SID *sids,
+ POLICY_HND *pol, int num_sids, DOM_SID *sids,
char ***domains, char ***names, uint32 **types)
{
prs_struct qbuf, rbuf;
@@ -305,10 +311,8 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (dom_idx != 0xffffffff) {
- rpcstr_pull_unistr2_fstring(
- dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
- rpcstr_pull_unistr2_fstring(
- name, &t_names.uni_name[i]);
+ unistr2_to_unix(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)- 1);
+ unistr2_to_unix(name, &t_names.uni_name[i], sizeof(name) - 1);
(*names)[i] = talloc_strdup(mem_ctx, name);
(*domains)[i] = talloc_strdup(mem_ctx, dom_name);
@@ -322,7 +326,6 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
} else {
(*names)[i] = NULL;
- (*domains)[i] = NULL;
(*types)[i] = SID_NAME_UNKNOWN;
}
}
@@ -335,6 +338,9 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/** Lookup a list of names */
+/********************************************************************
+ Converts names to SIDs. Incoming names are in UNIX charset.
+*********************************************************************/
NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, int num_names,
@@ -358,6 +364,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
+ /* This call converts from UNIX to DOS charset then to unicode. */
init_q_lookup_names(mem_ctx, &q, pol, num_names, names);
if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) ||
@@ -443,7 +450,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint16 info_class,
- char **domain_name, DOM_SID **domain_sid)
+ fstring domain_name, DOM_SID *domain_sid)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_INFO q;
@@ -481,40 +488,39 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
+ ZERO_STRUCTP(domain_sid);
+ domain_name[0] = '\0';
+
switch (info_class) {
case 3:
- if (domain_name && (r.dom.id3.buffer_dom_name != 0)) {
- *domain_name = unistr2_tdup(mem_ctx,
- &r.dom.id3.
- uni_domain_name);
+ if (r.dom.id3.buffer_dom_name != 0) {
+ unistr2_to_unix(domain_name,
+ &r.dom.id3.
+ uni_domain_name,
+ sizeof (fstring) - 1);
}
- if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) {
- *domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
- if (*domain_sid) {
- sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid);
- }
+ if (r.dom.id3.buffer_dom_sid != 0) {
+ *domain_sid = r.dom.id3.dom_sid.sid;
}
break;
case 5:
- if (domain_name && (r.dom.id5.buffer_dom_name != 0)) {
- *domain_name = unistr2_tdup(mem_ctx,
- &r.dom.id5.
- uni_domain_name);
+ if (r.dom.id5.buffer_dom_name != 0) {
+ unistr2_to_unix(domain_name, &r.dom.id5.
+ uni_domain_name,
+ sizeof (fstring) - 1);
}
- if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) {
- *domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
- if (*domain_sid) {
- sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid);
- }
+ if (r.dom.id5.buffer_dom_sid != 0) {
+ *domain_sid = r.dom.id5.dom_sid.sid;
}
+
break;
-
+
default:
DEBUG(3, ("unknown info class %d\n", info_class));
break;
@@ -527,118 +533,12 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/** Query info policy2
- *
- * @param domain_name - returned remote server's domain name
- * @param dns_name - returned remote server's dns domain name
- * @param forest_name - returned remote server's forest name
- * @param domain_guid - returned remote server's domain guid
- * @param domain_sid - returned remote server's domain sid */
-
-NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint16 info_class,
- char **domain_name, char **dns_name,
- char **forest_name, struct uuid **domain_guid,
- DOM_SID **domain_sid)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_QUERY_INFO2 q;
- LSA_R_QUERY_INFO2 r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (info_class != 12)
- goto done;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_q_query2(&q, pol, info_class);
-
- if (!lsa_io_q_query_info2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_QUERYINFO2, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_info2("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- /* Return output parameters */
-
- ZERO_STRUCTP(domain_guid);
-
- if (domain_name && r.info.dns_dom_info.hdr_nb_dom_name.buffer) {
- *domain_name = unistr2_tdup(mem_ctx,
- &r.info.dns_dom_info
- .uni_nb_dom_name);
- }
- if (dns_name && r.info.dns_dom_info.hdr_dns_dom_name.buffer) {
- *dns_name = unistr2_tdup(mem_ctx,
- &r.info.dns_dom_info
- .uni_dns_dom_name);
- }
- if (forest_name && r.info.dns_dom_info.hdr_forest_name.buffer) {
- *forest_name = unistr2_tdup(mem_ctx,
- &r.info.dns_dom_info
- .uni_forest_name);
- }
-
- if (domain_guid) {
- *domain_guid = talloc(mem_ctx, sizeof(**domain_guid));
- memcpy(*domain_guid,
- &r.info.dns_dom_info.dom_guid,
- sizeof(struct uuid));
- }
-
- if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) {
- *domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
- if (*domain_sid) {
- sid_copy(*domain_sid,
- &r.info.dns_dom_info.dom_sid.sid);
- }
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/**
- * Enumerate list of trusted domains
- *
- * @param cli client state (cli_state) structure of the connection
- * @param mem_ctx memory context
- * @param pol opened lsa policy handle
- * @param enum_ctx enumeration context ie. index of first returned domain entry
- * @param pref_num_domains preferred max number of entries returned in one response
- * @param num_domains total number of trusted domains returned by response
- * @param domain_names returned trusted domain names
- * @param domain_sids returned trusted domain sids
- *
- * @return nt status code of response
- **/
+/** Enumerate list of trusted domains */
NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *enum_ctx,
- uint32 *num_domains,
- char ***domain_names, DOM_SID **domain_sids)
+ uint32 *num_domains, char ***domain_names,
+ DOM_SID **domain_sids)
{
prs_struct qbuf, rbuf;
LSA_Q_ENUM_TRUST_DOM q;
@@ -656,8 +556,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
- /* 64k is enough for about 2000 trusted domains */
- init_q_enum_trust_dom(&q, pol, *enum_ctx, 0x10000);
+ init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff);
if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
@@ -674,15 +573,16 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) {
/* An actual error ocured */
goto done;
}
+ result = NT_STATUS_OK;
+
/* Return output parameters */
if (r.num_domains) {
@@ -694,7 +594,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!*domain_names) {
DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
+ result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -702,7 +602,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
r.num_domains);
if (!domain_sids) {
DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
+ result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -711,7 +611,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
for (i = 0; i < r.num_domains; i++) {
fstring tmp;
- unistr2_to_ascii(tmp, &r.uni_domain_name[i],
+ unistr2_to_unix(tmp, &r.uni_domain_name[i],
sizeof(tmp) - 1);
(*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid);
@@ -728,7 +628,6 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-
/** Enumerate privileges*/
NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -796,7 +695,7 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
for (i = 0; i < r.count; i++) {
fstring name;
- rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
+ unistr2_to_unix( name, &r.privs[i].name, sizeof(name)-1);
(*privs_name)[i] = talloc_strdup(mem_ctx, name);
@@ -814,8 +713,7 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/** Get privilege name */
NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, const char *name,
- uint16 lang_id, uint16 lang_id_sys,
+ POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys,
fstring description, uint16 *lang_id_desc)
{
prs_struct qbuf, rbuf;
@@ -854,7 +752,7 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- rpcstr_pull_unistr2_fstring(description , &r.desc);
+ unistr2_to_unix(description ,&r.desc, sizeof(description)-1);
*lang_id_desc = r.lang_id;
done:
@@ -935,64 +833,6 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/** Create a LSA user handle
- *
- * @param cli Handle on an initialised SMB connection
- *
- * FIXME: The code is actually identical to open account
- * TODO: Check and code what the function should exactly do
- *
- * */
-
-NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access,
- POLICY_HND *user_pol)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_CREATEACCOUNT q;
- LSA_R_CREATEACCOUNT r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
-
- /* Marshall data and send request */
-
- if (!lsa_io_q_create_account("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_CREATEACCOUNT, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_create_account("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Return output parameters */
-
- if (NT_STATUS_IS_OK(result = r.status)) {
- *user_pol = r.pol;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/** Open a LSA user handle
*
* @param cli Handle on an initialised SMB connection */
@@ -1102,9 +942,9 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
for (i=0; i<r.count; i++) {
- (*set)[i].luid.low = r.set->set[i].luid.low;
- (*set)[i].luid.high = r.set->set[i].luid.high;
- (*set)[i].attr = r.set->set[i].attr;
+ (*set)[i].luid.low = r.set.set[i].luid.low;
+ (*set)[i].luid.high = r.set.set[i].luid.high;
+ (*set)[i].attr = r.set.set[i].attr;
}
*count=r.count;
@@ -1118,7 +958,7 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/** Get a privilege value given its name */
NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, const char *name, LUID *luid)
+ POLICY_HND *pol, char *name, LUID *luid)
{
prs_struct qbuf, rbuf;
LSA_Q_LOOKUPPRIVVALUE q;
@@ -1218,152 +1058,7 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-
-/* Enumerate account rights This is similar to enum_privileges but
- takes a SID directly, avoiding the open_account call.
-*/
-
-NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, DOM_SID sid,
- uint32 *count, char ***privs_name)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_ENUM_ACCT_RIGHTS q;
- LSA_R_ENUM_ACCT_RIGHTS r;
- NTSTATUS result;
- int i;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
- init_q_enum_acct_rights(&q, pol, 2, &sid);
-
- if (!lsa_io_q_enum_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUMACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!lsa_io_r_enum_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- *count = r.count;
- if (! *count) {
- goto done;
- }
-
- *privs_name = (char **)talloc(mem_ctx, (*count) * sizeof(char **));
- for (i=0;i<*count;i++) {
- pull_ucs2_talloc(mem_ctx, &(*privs_name)[i], r.rights.strings[i].string.buffer);
- }
-
-done:
-
- return result;
-}
-
-
-
-/* add account rights to an account. */
-
-NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, DOM_SID sid,
- uint32 count, const char **privs_name)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_ADD_ACCT_RIGHTS q;
- LSA_R_ADD_ACCT_RIGHTS r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
-
- /* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
- init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
-
- if (!lsa_io_q_add_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ADDACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_add_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-done:
-
- return result;
-}
-
-
-/* remove account rights for an account. */
-
-NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, DOM_SID sid, BOOL removeall,
- uint32 count, const char **privs_name)
-{
- prs_struct qbuf, rbuf;
- LSA_Q_REMOVE_ACCT_RIGHTS q;
- LSA_R_REMOVE_ACCT_RIGHTS r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
-
- /* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
- init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
-
- if (!lsa_io_q_remove_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_REMOVEACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_remove_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-done:
-
- return result;
-}
-
-
-#if 0
-
-/** An example of how to use the routines in this file. Fetch a DOMAIN
- sid. Does complete cli setup / teardown anonymously. */
+/** Fetch a DOMAIN sid. Does complete cli setup / teardown anonymously. */
BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
{
@@ -1420,7 +1115,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
goto done;
}
- if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+ if (!(cli.sec_mode & 1)) {
DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
remote_machine));
goto done;
@@ -1434,7 +1129,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
/* Fetch domain sid */
- if (!cli_nt_session_open(&cli, PI_LSARPC)) {
+ if (!cli_nt_session_open(&cli, PIPE_LSARPC)) {
DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
goto done;
}
@@ -1442,14 +1137,14 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
- nt_errstr(result) ));
+ get_nt_error_msg(result) ));
goto done;
}
result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
- nt_errstr(result) ));
+ get_nt_error_msg(result) ));
goto done;
}
@@ -1460,7 +1155,4 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
cli_shutdown(&cli);
return ret;
}
-
-#endif
-
/** @} **/
diff --git a/source/libsmb/cli_netlogon.c b/source/libsmb/cli_netlogon.c
new file mode 100755
index 00000000000..f6763016aaf
--- /dev/null
+++ b/source/libsmb/cli_netlogon.c
@@ -0,0 +1,691 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Tim Potter 2001
+ Copyright (C) Paul Ashton 1997.
+ Copyright (C) Jeremy Allison 1998.
+ Copyright (C) Andrew Bartlett 2001.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Opens a SMB connection to the netlogon pipe */
+
+struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds);
+}
+
+/* LSA Request Challenge. Sends our challenge to server, then gets
+ server response. These are used to generate the credentials. */
+
+NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_REQ_CHAL q;
+ NET_R_REQ_CHAL r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ extern pstring global_myname;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_REQCHAL */
+
+ DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
+ cli->desthost, global_myname, credstr(clnt_chal->data)));
+
+ /* store the parameters */
+ init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarhall response */
+
+ if (!net_io_r_req_chal("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ result = r.status;
+
+ /* Return result */
+
+ if (NT_STATUS_IS_OK(result)) {
+ memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data));
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/****************************************************************************
+LSA Authenticate 2
+
+Send the client credential, receive back a server credential.
+Ensure that the server credential returned matches the session key
+encrypt of the server challenge originally received. JRA.
+****************************************************************************/
+
+NTSTATUS new_cli_net_auth2(struct cli_state *cli,
+ uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_AUTH_2 q;
+ NET_R_AUTH_2 r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ extern pstring global_myname;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_AUTH2 */
+
+ DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
+ cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
+ credstr(cli->clnt_cred.challenge.data), neg_flags));
+
+ /* store the parameters */
+ init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct,
+ sec_chan, global_myname, &cli->clnt_cred.challenge,
+ neg_flags);
+
+ /* turn parameters into data stream */
+
+ if (!net_io_q_auth_2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_auth_2("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ result = r.status;
+
+ if (NT_STATUS_IS_OK(result)) {
+ UTIME zerotime;
+
+ /*
+ * Check the returned value using the initial
+ * server received challenge.
+ */
+
+ zerotime.time = 0;
+ if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal,
+ zerotime) == 0) {
+
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+ result = NT_STATUS_ACCESS_DENIED;
+ goto done;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Initialize domain session credentials */
+
+NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli,
+ uint16 sec_chan,
+ const unsigned char mach_pwd[16])
+{
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+ UTIME zerotime;
+ NTSTATUS result;
+
+ /******************* Request Challenge ********************/
+
+ generate_random_buffer(clnt_chal.data, 8, False);
+
+ /* send a client challenge; receive a server challenge */
+ result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n"));
+ return result;
+ }
+
+ /**************** Long-term Session key **************/
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, mach_pwd,
+ cli->sess_key);
+ memset((char *)cli->sess_key+8, '\0', 8);
+
+ /******************* Authenticate 2 ********************/
+
+ /* calculate auth-2 credentials */
+ zerotime.time = 0;
+ cred_create(cli->sess_key, &clnt_chal, zerotime,
+ &cli->clnt_cred.challenge);
+
+ /*
+ * Send client auth-2 challenge.
+ * Receive an auth-2 challenge response and check it.
+ */
+
+ result = new_cli_net_auth2(cli, sec_chan, 0x000001ff,
+ &srv_chal);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("new_cli_nt_setup_creds: auth2 challenge failed %s\n",
+ get_nt_error_msg(result)));
+ }
+
+ return result;
+}
+
+/* Logon Control 2 */
+
+NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 query_level)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_LOGON_CTRL2 q;
+ NET_R_LOGON_CTRL2 r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/****************************************************************************
+Generate the next creds to use. Yuck - this is a cut&paste from another
+file. They should be combined at some stage. )-:
+****************************************************************************/
+
+static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
+{
+ /*
+ * Create the new client credentials.
+ */
+
+ cli->clnt_cred.timestamp.time = time(NULL);
+
+ memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
+
+ /* Calculate the new credentials. */
+ cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
+ new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
+
+}
+
+/* Sam synchronisation */
+
+NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds,
+ uint32 database_id, uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_SYNC q;
+ NET_R_SAM_SYNC r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2,
+ &clnt_creds, ret_creds, database_id);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_sync("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+ *num_deltas = r.num_deltas2;
+ *hdr_deltas = r.hdr_deltas;
+ *deltas = r.deltas;
+
+ memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Sam synchronisation */
+
+NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, UINT64_S seqnum,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_DELTAS q;
+ NET_R_SAM_DELTAS r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ init_net_q_sam_deltas(&q, cli->srv_name_slash,
+ cli->clnt_name_slash + 2, &clnt_creds,
+ database_id, seqnum);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_deltas("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+ *num_deltas = r.num_deltas2;
+ *hdr_deltas = r.hdr_deltas;
+ *deltas = r.deltas;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Logon domain user */
+
+NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *unix_username, const char *unix_password,
+ int logon_type)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_LOGON q;
+ NET_R_SAM_LOGON r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds, dummy_rtn_creds;
+ extern pstring global_myname;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 user;
+ int validation_level = 3;
+ fstring dos_username, dos_password;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ fstrcpy(dos_username, unix_username);
+ unix_to_dos(dos_username);
+ fstrcpy(dos_password, unix_password);
+ unix_to_dos(dos_password);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ q.validation_level = validation_level;
+
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
+ dummy_rtn_creds.timestamp.time = time(NULL);
+
+ ctr.switch_value = logon_type;
+
+ switch (logon_type) {
+ case INTERACTIVE_LOGON_TYPE: {
+ unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
+
+ nt_lm_owf_gen(dos_password, nt_owf_user_pwd, lm_owf_user_pwd);
+
+ init_id_info1(&ctr.auth.id1, lp_workgroup(),
+ 0, /* param_ctrl */
+ 0xdead, 0xbeef, /* LUID? */
+ dos_username, cli->clnt_name_slash,
+ (char *)cli->sess_key, lm_owf_user_pwd,
+ nt_owf_user_pwd);
+
+ break;
+ }
+ case NET_LOGON_TYPE: {
+ uint8 chal[8];
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
+
+ generate_random_buffer(chal, 8, False);
+
+ SMBencrypt((const uchar *)dos_password, chal, local_lm_response);
+ SMBNTencrypt((const uchar *)dos_password, chal, local_nt_response);
+
+ init_id_info2(&ctr.auth.id2, lp_workgroup(),
+ 0, /* param_ctrl */
+ 0xdead, 0xbeef, /* LUID? */
+ dos_username, cli->clnt_name_slash, chal,
+ local_lm_response, 24, local_nt_response, 24);
+ break;
+ }
+ default:
+ DEBUG(0, ("switch value %d not supported\n",
+ ctr.switch_value));
+ goto done;
+ }
+
+ init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname,
+ &clnt_creds, &dummy_rtn_creds, logon_type,
+ &ctr);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.user = &user;
+
+ if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/**
+ * Logon domain user with an 'network' SAM logon
+ *
+ * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
+ **/
+
+NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *unix_username, const char *unix_domain, const char *workstation,
+ const uint8 chal[8],
+ DATA_BLOB lm_response, DATA_BLOB nt_response,
+ NET_USER_INFO_3 *info3)
+
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_LOGON q;
+ NET_R_SAM_LOGON r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds, dummy_rtn_creds;
+ NET_ID_INFO_CTR ctr;
+ extern pstring global_myname;
+ int validation_level = 3;
+ char *workstation_name_slash;
+ fstring dos_username, dos_domain;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ fstrcpy(dos_username, unix_username);
+ unix_to_dos(dos_username);
+ fstrcpy(dos_domain, unix_domain);
+ unix_to_dos(dos_domain);
+
+ workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
+
+ if (!workstation_name_slash) {
+ DEBUG(0, ("talloc_asprintf failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ q.validation_level = validation_level;
+
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
+ dummy_rtn_creds.timestamp.time = time(NULL);
+
+ ctr.switch_value = NET_LOGON_TYPE;
+
+ init_id_info2(&ctr.auth.id2, dos_domain,
+ 0, /* param_ctrl */
+ 0xdead, 0xbeef, /* LUID? */
+ dos_username, workstation_name_slash, (const uchar*)chal,
+ lm_response.data, lm_response.length, nt_response.data, nt_response.length);
+
+ init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname,
+ &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE,
+ &ctr);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.user = info3;
+
+ if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+#if 0 /* JERRY */
+
+/*
+ * Still using old implementation in rpc_client/cli_netlogon.c
+ */
+
+/***************************************************************************
+LSA Server Password Set.
+****************************************************************************/
+
+ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char* machine_name, uint8 hashed_mach_pwd[16])
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ DOM_CRED new_clnt_cred;
+ NET_Q_SRV_PWSET q_s;
+ uint16 sec_chan_type = 2;
+ NTSTATUS nt_status;
+ char *mach_acct;
+
+ gen_next_creds( cli, &new_clnt_cred);
+
+ prs_init(&qbuf , 1024, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_SRV_PWSET */
+
+ mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name);
+
+ if (!mach_acct) {
+ DEBUG(0,("talloc_asprintf failed!\n"));
+ nt_status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
+ cli->srv_name_slash, mach_acct, sec_chan_type, machine_name,
+ credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
+
+ /* store the parameters */
+ init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key,
+ mach_acct, sec_chan_type, machine_name,
+ &new_clnt_cred, (char *)hashed_mach_pwd);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) {
+ DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf))
+ {
+ NET_R_SRV_PWSET r_s;
+
+ if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) {
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ nt_status = r_s.status;
+
+ if (!NT_STATUS_IS_OK(r_s.status))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status)));
+ goto done;
+ }
+
+ /* Update the credentials. */
+ if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
+ {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return nt_status;
+}
+
+#endif /* JERRY */
diff --git a/source/libsmb/cli_pipe_util.c b/source/libsmb/cli_pipe_util.c
new file mode 100755
index 00000000000..fee4b491047
--- /dev/null
+++ b/source/libsmb/cli_pipe_util.c
@@ -0,0 +1,80 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.2
+ RPC pipe client utility functions
+ Copyright (C) Tim Potter 2001,
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Opens a SMB connection to a named pipe */
+
+struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name,
+ const char *pipe_name,
+ struct ntuser_creds *creds)
+{
+ struct in_addr dest_ip;
+ struct nmb_name calling, called;
+ fstring dest_host;
+ extern pstring global_myname;
+ struct ntuser_creds anon;
+
+ /* Initialise cli_state information */
+
+ if (!cli_initialise(cli)) {
+ return NULL;
+ }
+
+ if (!creds) {
+ ZERO_STRUCT(anon);
+ anon.pwd.null_pwd = 1;
+ creds = &anon;
+ }
+
+ cli_init_creds(cli, creds);
+
+ /* Establish a SMB connection */
+
+ if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
+ return NULL;
+ }
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ return NULL;
+ }
+
+ /* Open a NT session thingy */
+
+ if (!cli_nt_session_open(cli, pipe_name)) {
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ return cli;
+}
+
+/* Shut down a SMB connection to the SAMR pipe */
+
+void cli_pipe_shutdown(struct cli_state *cli)
+{
+ if (cli->fd != -1) cli_ulogoff(cli);
+ cli_shutdown(cli);
+}
diff --git a/source/rpc_client/cli_reg.c b/source/libsmb/cli_reg.c
index 5cfbf68fb34..c09ccabb29f 100644..100755
--- a/source/rpc_client/cli_reg.c
+++ b/source/libsmb/cli_reg.c
@@ -25,11 +25,19 @@
#include "includes.h"
+/* Opens a SMB connection to the WINREG pipe */
+
+struct cli_state *cli_winreg_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds);
+}
+
/* Shutdown a server */
NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
- const char *msg, uint32 timeout, BOOL do_reboot,
- BOOL force)
+ const char *msg, uint32 timeout, uint16 flags)
{
prs_struct qbuf;
prs_struct rbuf;
@@ -47,7 +55,7 @@ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
- init_reg_q_shutdown(&q_s, msg, timeout, do_reboot, force);
+ init_reg_q_shutdown(&q_s, msg, timeout, flags);
if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) ||
!rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf))
diff --git a/source/rpc_client/cli_samr.c b/source/libsmb/cli_samr.c
index 86f65056897..19c74965ec0 100644..100755
--- a/source/rpc_client/cli_samr.c
+++ b/source/libsmb/cli_samr.c
@@ -5,8 +5,7 @@
Copyright (C) Andrew Tridgell 1992-1997,2000,
Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
Copyright (C) Paul Ashton 1997,2000,
- Copyright (C) Elrond 2000,
- Copyright (C) Rafal Szczesniak 2002.
+ Copyright (C) Elrond 2000.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,6 +24,14 @@
#include "includes.h"
+/* Opens a SMB connection to the SAMR pipe */
+
+struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds);
+}
+
/* Connect to SAMR database */
NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -35,8 +42,6 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CONNECT r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -50,70 +55,20 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_connect(&q, cli->desthost, access_mask);
if (!samr_io_q_connect("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) {
goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_connect("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- if (NT_STATUS_IS_OK(result = r.status)) {
- *connect_pol = r.connect_pol;
-#ifdef __INSURE__
- connect_pol->marker = malloc(1);
-#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Connect to SAMR database */
-
-NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_CONNECT4 q;
- SAMR_R_CONNECT4 r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_connect4(&q, cli->desthost, access_mask);
-
- if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CONNECT4, &qbuf, &rbuf))
- goto done;
-
/* Unmarshall response */
- if (!samr_io_r_connect4("", &r, &rbuf, 0))
+ if (!samr_io_r_connect("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
*connect_pol = r.connect_pol;
-#ifdef __INSURE__
- connect_pol->marker = malloc(1);
-#endif
}
done:
@@ -133,8 +88,6 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CLOSE_HND r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_close\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -148,20 +101,19 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_close_hnd(&q, connect_pol);
if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
+ if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
-#ifdef __INSURE__
- SAFE_FREE(connect_pol->marker);
-#endif
*connect_pol = r.pol;
}
@@ -176,15 +128,13 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *connect_pol, uint32 access_mask,
- const DOM_SID *domain_sid, POLICY_HND *domain_pol)
+ DOM_SID *domain_sid, POLICY_HND *domain_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_DOMAIN q;
SAMR_R_OPEN_DOMAIN r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -198,21 +148,20 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_open_domain("", &r, &rbuf, 0))
+ if (!samr_io_r_open_domain("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
*domain_pol = r.domain_pol;
-#ifdef __INSURE__
- domain_pol->marker = malloc(1);
-#endif
}
done:
@@ -233,8 +182,6 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -248,21 +195,20 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_open_user("", &r, &rbuf, 0))
+ if (!samr_io_r_open_user("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
*user_pol = r.user_pol;
-#ifdef __INSURE__
- user_pol->marker = malloc(1);
-#endif
}
done:
@@ -283,8 +229,6 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_GROUP r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -298,21 +242,20 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_open_group("", &r, &rbuf, 0))
+ if (!samr_io_r_open_group("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
*group_pol = r.pol;
-#ifdef __INSURE__
- group_pol->marker = malloc(1);
-#endif
}
done:
@@ -322,143 +265,6 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Create domain group */
-
-NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol,
- const char *group_name,
- uint32 access_mask, POLICY_HND *group_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_CREATE_DOM_GROUP q;
- SAMR_R_CREATE_DOM_GROUP r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_create_dom_group\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
-
- if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (NT_STATUS_IS_OK(result))
- *group_pol = r.pol;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Add a domain group member */
-
-NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 rid)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_ADD_GROUPMEM q;
- SAMR_R_ADD_GROUPMEM r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_add_groupmem\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_add_groupmem(&q, group_pol, rid);
-
- if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Delete a domain group member */
-
-NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 rid)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_DEL_GROUPMEM q;
- SAMR_R_DEL_GROUPMEM r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_del_groupmem\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_del_groupmem(&q, group_pol, rid);
-
- if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* Query user info */
NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -470,8 +276,6 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_USERINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_userinfo\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -485,13 +289,15 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_userinfo(&q, user_pol, switch_value);
if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
+ if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
@@ -505,50 +311,6 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Set group info */
-
-NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_SET_GROUPINFO q;
- SAMR_R_SET_GROUPINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_set_groupinfo\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_set_groupinfo(&q, group_pol, ctr);
-
- if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* Query group info */
NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -560,8 +322,6 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_GROUPINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_groupinfo\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -575,13 +335,15 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_groupinfo(&q, group_pol, info_level);
if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
+ if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) {
goto done;
+ }
*ctr = r.ctr;
@@ -607,8 +369,6 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_USERGROUPS r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_usergroups\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -622,13 +382,15 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_usergroups(&q, user_pol);
if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
+ if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
@@ -644,50 +406,6 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Set alias info */
-
-NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_SET_ALIASINFO q;
- SAMR_R_SET_ALIASINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_set_aliasinfo\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
-
- if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* Query user aliases */
NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -698,10 +416,8 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_Q_QUERY_USERALIASES q;
SAMR_R_QUERY_USERALIASES r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- unsigned int ptr=1;
+ uint32 ptr=1;
- DEBUG(10,("cli_samr_query_useraliases\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -715,13 +431,15 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
+ if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
@@ -748,8 +466,6 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_GROUPMEM r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_groupmem\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -763,13 +479,15 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_groupmem(&q, group_pol);
if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
+ if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
@@ -786,102 +504,6 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/**
- * Enumerate domain users
- *
- * @param cli client state structure
- * @param mem_ctx talloc context
- * @param pol opened domain policy handle
- * @param start_idx starting index of enumeration, returns context for
- next enumeration
- * @param acb_mask account control bit mask (to enumerate some particular
- * kind of accounts)
- * @param size max acceptable size of response
- * @param dom_users returned array of domain user names
- * @param rids returned array of domain user RIDs
- * @param num_dom_users numer returned entries
- *
- * @return NTSTATUS returned in rpc response
- **/
-NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
- uint32 size, char ***dom_users, uint32 **rids,
- uint32 *num_dom_users)
-{
- prs_struct qbuf;
- prs_struct rbuf;
- SAMR_Q_ENUM_DOM_USERS q;
- SAMR_R_ENUM_DOM_USERS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- int i;
-
- DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* always init this */
- *num_dom_users = 0;
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Fill query structure with parameters */
-
- init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
-
- if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* unpack received stream */
-
- if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
- goto done;
-
- *start_idx = r.next_idx;
- *num_dom_users = r.num_entries2;
-
- if (r.num_entries2) {
- /* allocate memory needed to return received data */
- *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2);
- if (!*rids) {
- DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2);
- if (!*dom_users) {
- DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- /* fill output buffers with rpc response */
- for (i = 0; i < r.num_entries2; i++) {
- fstring conv_buf;
-
- (*rids)[i] = r.sam[i].rid;
- unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
- (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
- }
- }
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* Enumerate domain groups */
NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -895,8 +517,6 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 name_idx, i;
- DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -910,34 +530,34 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) {
goto done;
+ }
/* Unmarshall response */
- if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
+ if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) {
goto done;
+ }
/* Return output parameters */
result = r.status;
if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
+ NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
goto done;
+ }
*num_dom_groups = r.num_entries2;
- if (*num_dom_groups == 0)
- goto done;
-
if (!((*dom_groups) = (struct acct_info *)
talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
- result = NT_STATUS_NO_MEMORY;
+ result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
+ memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
name_idx = 0;
@@ -946,7 +566,7 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
(*dom_groups)[i].rid = r.sam[i].rid;
if (r.sam[i].hdr_name.buffer) {
- unistr2_to_ascii((*dom_groups)[i].acct_name,
+ unistr2_to_unix((*dom_groups)[i].acct_name,
&r.uni_grp_name[name_idx],
sizeof(fstring) - 1);
name_idx++;
@@ -966,8 +586,8 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_aliases,
- uint32 *num_dom_aliases)
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups)
{
prs_struct qbuf, rbuf;
SAMR_Q_ENUM_DOM_ALIASES q;
@@ -975,8 +595,6 @@ NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 name_idx, i;
- DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1009,27 +627,24 @@ NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- *num_dom_aliases = r.num_entries2;
-
- if (*num_dom_aliases == 0)
- goto done;
+ *num_dom_groups = r.num_entries2;
- if (!((*dom_aliases) = (struct acct_info *)
- talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_aliases))) {
- result = NT_STATUS_NO_MEMORY;
+ if (!((*dom_groups) = (struct acct_info *)
+ talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
+ result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
+ memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
name_idx = 0;
- for (i = 0; i < *num_dom_aliases; i++) {
+ for (i = 0; i < *num_dom_groups; i++) {
- (*dom_aliases)[i].rid = r.sam[i].rid;
+ (*dom_groups)[i].rid = r.sam[i].rid;
if (r.sam[i].hdr_name.buffer) {
- unistr2_to_ascii((*dom_aliases)[i].acct_name,
+ unistr2_to_unix((*dom_groups)[i].acct_name,
&r.uni_grp_name[name_idx],
sizeof(fstring) - 1);
name_idx++;
@@ -1057,8 +672,6 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
- DEBUG(10,("cli_samr_query_aliasmem\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1090,12 +703,6 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*num_mem = r.num_sids;
- if (*num_mem == 0) {
- *sids = NULL;
- result = NT_STATUS_OK;
- goto done;
- }
-
if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
@@ -1123,8 +730,6 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_ALIAS r;
NTSTATUS result;
- DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1154,205 +759,8 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(result = r.status)) {
*alias_pol = r.pol;
-#ifdef __INSURE__
- alias_pol->marker = malloc(1);
-#endif
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Create an alias */
-
-NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, const char *name,
- POLICY_HND *alias_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_CREATE_DOM_ALIAS q;
- SAMR_R_CREATE_DOM_ALIAS r;
- NTSTATUS result;
-
- DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_create_dom_alias(&q, domain_pol, name);
-
- if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Return output parameters */
-
- if (NT_STATUS_IS_OK(result = r.status)) {
- *alias_pol = r.alias_pol;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Add an alias member */
-
-NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, DOM_SID *member)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_ADD_ALIASMEM q;
- SAMR_R_ADD_ALIASMEM r;
- NTSTATUS result;
-
- DEBUG(10,("cli_samr_add_aliasmem"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_add_aliasmem(&q, alias_pol, member);
-
- if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Delete an alias member */
-
-NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, DOM_SID *member)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_DEL_ALIASMEM q;
- SAMR_R_DEL_ALIASMEM r;
- NTSTATUS result;
-
- DEBUG(10,("cli_samr_del_aliasmem"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_del_aliasmem(&q, alias_pol, member);
-
- if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Query alias info */
-
-NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, uint16 switch_value,
- ALIAS_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_ALIASINFO q;
- SAMR_R_QUERY_ALIASINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_query_dom_info\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
-
- if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
- goto done;
- }
-
- /* Return output parameters */
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
}
- *ctr = r.ctr;
-
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
@@ -1371,8 +779,6 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_DOMAIN_INFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_dom_info\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1411,96 +817,6 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* User change password */
-
-NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *username,
- const char *newpassword,
- const char *oldpassword )
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_CHGPASSWD_USER q;
- SAMR_R_CHGPASSWD_USER r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- uchar new_nt_password[516];
- uchar new_lm_password[516];
- uchar old_nt_hash[16];
- uchar old_lanman_hash[16];
- uchar old_nt_hash_enc[16];
- uchar old_lanman_hash_enc[16];
-
- uchar new_nt_hash[16];
- uchar new_lanman_hash[16];
-
- DEBUG(10,("cli_samr_query_dom_info\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Calculate the MD4 hash (NT compatible) of the password */
- E_md4hash(oldpassword, old_nt_hash);
- E_md4hash(newpassword, new_nt_hash);
-
- if (lp_client_lanman_auth()
- && E_deshash(newpassword, new_lanman_hash)
- && E_deshash(oldpassword, old_lanman_hash)) {
- /* E_deshash returns false for 'long' passwords (> 14
- DOS chars). This allows us to match Win2k, which
- does not store a LM hash for these passwords (which
- would reduce the effective password length to 14) */
-
- encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
-
- SamOEMhash( new_lm_password, old_nt_hash, 516);
- E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
- } else {
- ZERO_STRUCT(new_lm_password);
- ZERO_STRUCT(old_lanman_hash_enc);
- }
-
- encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
-
- SamOEMhash( new_nt_password, old_nt_hash, 516);
- E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username,
- new_nt_password,
- old_nt_hash_enc,
- new_lm_password,
- old_lanman_hash_enc);
-
- if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
- goto done;
- }
-
- /* Return output parameters */
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* This function returns the bizzare set of (max_entries, max_size) required
for the QueryDisplayInfo RPC to actually work against a domain controller
with large (10k and higher) numbers of users. These values were
@@ -1546,13 +862,9 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_DISPINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- *num_entries = 0;
-
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
@@ -1563,8 +875,15 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
*start_idx, max_entries, max_size);
- if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
+ /* XXX: Some level 0 debugs to try and identify the cause of cr1168 */
+
+ if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0)) {
+ DEBUG(0, ("cli_samr_query_dispinfo: samr_io_q_query_dispinfo failed!\n"));
+ goto done;
+ }
+
+ if (!rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
+ DEBUG(0, ("cli_samr_query_dispinfo: rpc_api_pipe_req failed!\n"));
goto done;
}
@@ -1573,6 +892,7 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
r.ctr = ctr;
if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
+ DEBUG(0, ("cli_samr_query_dispinfo: samr_io_r_query_dispinfo failed!\n"));
goto done;
}
@@ -1610,8 +930,6 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
- DEBUG(10,("cli_samr_lookup_rids\n"));
-
if (num_rids > 1000) {
DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
"more than ~1000 rids are looked up at once.\n"));
@@ -1660,7 +978,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
for (i = 0; i < r.num_names1; i++) {
fstring tmp;
- unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
+ unistr2_to_unix(tmp, &r.uni_name[i], sizeof(tmp) - 1);
(*names)[i] = talloc_strdup(mem_ctx, tmp);
(*name_types)[i] = r.type[i];
}
@@ -1686,8 +1004,6 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
- DEBUG(10,("cli_samr_lookup_names\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1742,7 +1058,7 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Create a domain user */
NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *domain_pol, char *acct_name,
uint32 acb_info, uint32 unknown,
POLICY_HND *user_pol, uint32 *rid)
{
@@ -1751,8 +1067,6 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CREATE_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1799,23 +1113,16 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
- DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_SET_USERINFO q;
SAMR_R_SET_USERINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_set_userinfo\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- if (!sess_key->length) {
- DEBUG(1, ("No user session key\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
@@ -1856,20 +1163,13 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
- DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_SET_USERINFO2 q;
SAMR_R_SET_USERINFO2 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_set_userinfo2\n"));
-
- if (!sess_key->length) {
- DEBUG(1, ("No user session key\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1906,98 +1206,6 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Delete domain group */
-
-NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_DELETE_DOM_GROUP q;
- SAMR_R_DELETE_DOM_GROUP r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_delete_dom_group\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_delete_dom_group(&q, group_pol);
-
- if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
- goto done;
- }
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Delete domain alias */
-
-NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_DELETE_DOM_ALIAS q;
- SAMR_R_DELETE_DOM_ALIAS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_delete_dom_alias\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_delete_dom_alias(&q, alias_pol);
-
- if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
- goto done;
- }
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
/* Delete domain user */
NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -2008,8 +1216,6 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_DELETE_DOM_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_delete_dom_user\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -2055,8 +1261,6 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_SEC_OBJ r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_query_sec_obj\n"));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -2091,102 +1295,3 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-
-/* Get domain password info */
-
-NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint16 *unk_0, uint16 *unk_1)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_GET_DOM_PWINFO q;
- SAMR_R_GET_DOM_PWINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_get_dom_pwinfo(&q, cli->desthost);
-
- if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (NT_STATUS_IS_OK(result)) {
- if (unk_0)
- *unk_0 = r.unk_0;
- if (unk_1)
- *unk_1 = r.unk_1;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Lookup Domain Name */
-
-NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, char *domain_name,
- DOM_SID *sid)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_LOOKUP_DOMAIN q;
- SAMR_R_LOOKUP_DOMAIN r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("cli_samr_lookup_domain\n"));
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_samr_q_lookup_domain(&q, user_pol, domain_name);
-
- if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (NT_STATUS_IS_OK(result))
- sid_copy(sid, &r.dom_sid.sid);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
diff --git a/source/rpc_client/cli_spoolss.c b/source/libsmb/cli_spoolss.c
index 8f5f2413dee..684c55ed757 100644..100755
--- a/source/rpc_client/cli_spoolss.c
+++ b/source/libsmb/cli_spoolss.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
RPC pipe client
@@ -12,12 +12,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -31,6 +31,21 @@
* @{
**/
+/** Opens a SMB connection and connects to the SPOOLSS pipe.
+ *
+ * @param cli Uninitialised client handle.
+ * @param system_name NETBIOS name of the machine to connect to.
+ * @param creds User credentials to connect as.
+ * @returns Initialised client handle.
+ */
+struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds);
+}
+
+
/**********************************************************************
Initialize a new spoolss buff for use by a client rpc
**********************************************************************/
@@ -43,22 +58,21 @@ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
buffer->struct_start = prs_offset(&buffer->prs);
}
-/*********************************************************************
- Decode various spoolss rpc's and info levels
+/*********************************************************************
+ Decode various spoolss rpc's and info levels
********************************************************************/
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
uint32 returned, PRINTER_INFO_0 **info)
{
uint32 i;
PRINTER_INFO_0 *inf;
inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
- memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
smb_io_printer_info_0("", buffer, &inf[i], 0);
@@ -69,16 +83,15 @@ static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
uint32 returned, PRINTER_INFO_1 **info)
{
uint32 i;
PRINTER_INFO_1 *inf;
inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
- memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
smb_io_printer_info_1("", buffer, &inf[i], 0);
@@ -96,9 +109,8 @@ static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
PRINTER_INFO_2 *inf;
inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
- memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
/* a little initialization as we go */
@@ -118,9 +130,8 @@ static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
PRINTER_INFO_3 *inf;
inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
- memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
inf[i].secdesc = NULL;
@@ -139,7 +150,6 @@ static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
PORT_INFO_1 *inf;
inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
- memset(inf, 0, returned*sizeof(PORT_INFO_1));
prs_set_offset(&buffer->prs, 0);
@@ -159,7 +169,6 @@ static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
PORT_INFO_2 *inf;
inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
- memset(inf, 0, returned*sizeof(PORT_INFO_2));
prs_set_offset(&buffer->prs, 0);
@@ -179,9 +188,8 @@ static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
DRIVER_INFO_1 *inf;
inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
- memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
@@ -199,9 +207,8 @@ static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
DRIVER_INFO_2 *inf;
inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
- memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
@@ -219,9 +226,8 @@ static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
DRIVER_INFO_3 *inf;
inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
- memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset=0;
for (i=0; i<returned; i++) {
smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
@@ -239,7 +245,6 @@ static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
DRIVER_DIRECTORY_1 *inf;
inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
- memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
prs_set_offset(&buffer->prs, 0);
@@ -273,10 +278,10 @@ static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/*********************************************************************************
Win32 API - OpenPrinter()
********************************************************************************/
-
+
WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *printername, const char *datatype, uint32 access_required,
- const char *station, const char *username, POLICY_HND *pol)
+ char *printername, const char *datatype, uint32 access_required,
+ char *station, char *username, POLICY_HND *pol)
{
prs_struct qbuf, rbuf;
SPOOL_Q_OPEN_PRINTER_EX q;
@@ -295,7 +300,7 @@ WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_open_printer_ex(&q, printername, datatype,
access_required, station, username);
-
+
/* Marshall data and send request */
if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
@@ -335,7 +340,7 @@ WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
********************************************************************************/
WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
+ POLICY_HND *pol)
{
prs_struct qbuf, rbuf;
SPOOL_Q_CLOSEPRINTER q;
@@ -353,7 +358,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
make_spoolss_q_closeprinter(&q, pol);
-
+
/* Marshall data and send request */
if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
@@ -403,7 +408,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 offered, uint32 *needed,
- char *name, uint32 flags, uint32 level,
+ uint32 flags, uint32 level,
uint32 *num_printers, PRINTER_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -411,68 +416,72 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SPOOL_R_ENUMPRINTERS r;
NEW_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise input parameters */
+ fstrcpy (server, cli->desthost);
+ strupper (server);
+
+ /* Initialise input parameters */
init_buffer(&buffer, offered, mem_ctx);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- make_spoolss_q_enumprinters(&q, flags, name, level, &buffer,
+ make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
offered);
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
- goto done;
+ goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
- if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
+ if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
if (needed)
*needed = r.needed;
- }
-
+ }
+
result = r.status;
-
+
/* Return output parameters */
if (!W_ERROR_IS_OK(r.status))
- goto done;
-
+ goto done;
+
if (num_printers)
*num_printers = r.returned;
if (!ctr)
goto done;
- switch (level) {
- case 0:
- decode_printer_info_0(mem_ctx, r.buffer, r.returned,
- &ctr->printers_0);
- break;
- case 1:
- decode_printer_info_1(mem_ctx, r.buffer, r.returned,
- &ctr->printers_1);
- break;
- case 2:
- decode_printer_info_2(mem_ctx, r.buffer, r.returned,
- &ctr->printers_2);
- break;
- case 3:
- decode_printer_info_3(mem_ctx, r.buffer, r.returned,
- &ctr->printers_3);
- break;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ switch (level) {
+ case 0:
+ decode_printer_info_0(mem_ctx, r.buffer, r.returned,
+ &ctr->printers_0);
+ break;
+ case 1:
+ decode_printer_info_1(mem_ctx, r.buffer, r.returned,
+ &ctr->printers_1);
+ break;
+ case 2:
+ decode_printer_info_2(mem_ctx, r.buffer, r.returned,
+ &ctr->printers_2);
+ break;
+ case 3:
+ decode_printer_info_3(mem_ctx, r.buffer, r.returned,
+ &ctr->printers_3);
+ break;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
return result;
}
@@ -499,7 +508,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 offered, uint32 *needed,
- uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
+ uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SPOOL_Q_ENUMPORTS q;
@@ -511,34 +520,34 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
+
+ /* Initialise input parameters */
- /* Initialise input parameters */
-
init_buffer(&buffer, offered, mem_ctx);
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
make_spoolss_q_enumports(&q, server, level, &buffer, offered);
-
- /* Marshall data and send request */
- if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
- goto done;
+ goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
- if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
+ if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
if (needed)
*needed = r.needed;
- }
+ }
result = r.status;
- /* Return output parameters */
+ /* Return output parameters */
if (!W_ERROR_IS_OK(result))
goto done;
@@ -548,22 +557,22 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!ctr)
goto done;
-
- switch (level) {
- case 1:
- decode_port_info_1(mem_ctx, r.buffer, r.returned,
- &ctr->port.info_1);
- break;
- case 2:
- decode_port_info_2(mem_ctx, r.buffer, r.returned,
- &ctr->port.info_2);
- break;
- }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
+ switch (level) {
+ case 1:
+ decode_port_info_1(mem_ctx, r.buffer, r.returned,
+ &ctr->port.info_1);
+ break;
+ case 2:
+ decode_port_info_2(mem_ctx, r.buffer, r.returned,
+ &ctr->port.info_2);
+ break;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
return result;
}
@@ -585,53 +594,53 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise input parameters */
+ /* Initialise input parameters */
init_buffer(&buffer, offered, mem_ctx);
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered);
-
- /* Marshall data and send request */
- if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
- goto done;
+ /* Marshall data and send request */
- /* Unmarshall response */
+ if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
goto done;
if (needed)
*needed = r.needed;
-
- /* Return output parameters */
+
+ /* Return output parameters */
result = r.status;
+
+ if (NT_STATUS_IS_OK(result)) {
+ switch (level) {
+ case 0:
+ decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
+ break;
+ case 1:
+ decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
+ break;
+ case 2:
+ decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
+ break;
+ case 3:
+ decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
+ break;
+ }
+ }
- if (W_ERROR_IS_OK(result)) {
- switch (level) {
- case 0:
- decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
- break;
- case 1:
- decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
- break;
- case 2:
- decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
- break;
- case 3:
- decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
- break;
- }
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
return result;
}
@@ -653,7 +662,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
* for details.
*
*/
-
+
WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 level,
PRINTER_INFO_CTR *ctr, uint32 command)
@@ -667,30 +676,29 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(r);
/* Initialise input parameters */
-
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command))
- goto done;
+ make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
/* Marshall data and send request */
if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
- if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
+ if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
goto done;
result = r.status;
-
+
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
+
return result;
}
@@ -720,7 +728,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 offered, uint32 *needed,
POLICY_HND *pol, uint32 level,
- const char *env, int version, PRINTER_DRIVER_CTR *ctr)
+ const char *env, PRINTER_DRIVER_CTR *ctr)
{
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTERDRIVER2 q;
@@ -732,36 +740,36 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- fstrcpy(server, cli->desthost);
- strupper_m(server);
+ fstrcpy (server, cli->desthost);
+ strupper (server);
- /* Initialise input parameters */
+ /* Initialise input parameters */
init_buffer(&buffer, offered, mem_ctx);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- make_spoolss_q_getprinterdriver2(&q, pol, env, level, version, 2,
+ make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2,
&buffer, offered);
/* Marshall data and send request */
- if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
- goto done;
+ if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
+ goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
if (needed)
*needed = r.needed;
- }
-
+ }
+
result = r.status;
- /* Return output parameters */
-
+ /* Return output parameters */
+
if (!W_ERROR_IS_OK(result))
goto done;
@@ -769,24 +777,21 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
goto done;
switch (level) {
- case 1:
- decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
- break;
- case 2:
- decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
- break;
- case 3:
- decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
- break;
- default:
- DEBUG(10, ("cli_spoolss_getprinterdriver: unknown info level %d", level));
- return WERR_UNKNOWN_LEVEL;
- }
+ case 1:
+ decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
+ break;
+ case 2:
+ decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
+ break;
+ case 3:
+ decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
+ break;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -801,40 +806,40 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
uint32 offered, uint32 *needed,
uint32 level, const char *env,
uint32 *num_drivers,
- PRINTER_DRIVER_CTR *ctr)
+ PRINTER_DRIVER_CTR *ctr)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERDRIVERS q;
- SPOOL_R_ENUMPRINTERDRIVERS r;
- NEW_BUFFER buffer;
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ENUMPRINTERDRIVERS q;
+ SPOOL_R_ENUMPRINTERDRIVERS r;
+ NEW_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
- fstring server;
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- /* Initialise input parameters */
+ /* Initialise input parameters */
init_buffer(&buffer, offered, mem_ctx);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Write the request */
make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer,
offered);
+
+ /* Marshall data and send request */
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
- goto done;
+ if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
+ goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
goto done;
@@ -846,34 +851,30 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
*num_drivers = r.returned;
result = r.status;
-
- /* Return output parameters */
+
+ /* Return output parameters */
if (W_ERROR_IS_OK(result) && (r.returned != 0)) {
*num_drivers = r.returned;
switch (level) {
- case 1:
- decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
- break;
- case 2:
- decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
- break;
- case 3:
- decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
- break;
- default:
- DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n",
- level));
- return WERR_UNKNOWN_LEVEL;
+ case 1:
+ decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
+ break;
+ case 2:
+ decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
+ break;
+ case 3:
+ decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
+ break;
+ }
}
- }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
}
@@ -899,53 +900,53 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- /* Initialise input parameters */
+ /* Initialise input parameters */
init_buffer(&buffer, offered, mem_ctx);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Write the request */
make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer,
offered);
- /* Marshall data and send request */
+ /* Marshall data and send request */
- if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
+ if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
!rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
&qbuf, &rbuf))
- goto done;
+ goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) {
if (needed)
*needed = r.needed;
- }
+ }
- /* Return output parameters */
+ /* Return output parameters */
result = r.status;
if (W_ERROR_IS_OK(result)) {
switch (level) {
- case 1:
+ case 1:
decode_printerdriverdir_1(mem_ctx, r.buffer, 1,
&ctr->info1);
- break;
- }
- }
-
+ break;
+ }
+ }
+
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- return result;
+ return result;
}
/*********************************************************************************
@@ -967,11 +968,10 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
/* Initialise input parameters */
-
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -982,11 +982,11 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
-
+
if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
goto done;
@@ -1021,12 +1021,12 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- slprintf(client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(client);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (client);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
fstrcpy (user, cli->user_name);
-
+
/* Initialise input parameters */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
@@ -1042,9 +1042,9 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
!rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
goto done;
-
- /* Unmarshall response */
+ /* Unmarshall response */
+
if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
goto done;
@@ -1068,7 +1068,7 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
*/
WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
TALLOC_CTX *mem_ctx, const char *arch,
- const char *driver)
+ char *driver)
{
prs_struct qbuf, rbuf;
SPOOL_Q_DELETEPRINTERDRIVER q;
@@ -1084,8 +1084,8 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
/* Write the request */
@@ -1094,11 +1094,11 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
goto done;
/* Unmarshall response */
-
+
if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
goto done;
@@ -1200,14 +1200,14 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
/* Initialise input parameters */
make_spoolss_q_addform(&q, handle, level, form);
-
- /* Marshall data and send request */
+
+ /* Marshall data and send request */
if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
@@ -1216,7 +1216,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Unmarshall response */
if (!spoolss_io_r_addform("", &r, &rbuf, 0))
- goto done;
+ goto done;
/* Return output parameters */
@@ -1228,7 +1228,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-
+
/** Set a form on a printer.
*
* @param cli Pointer to client state structure which is open
@@ -1243,8 +1243,8 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*/
WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle, uint32 level,
- const char *form_name, FORM *form)
+ POLICY_HND *handle, uint32 level, char *form_name,
+ FORM *form)
{
prs_struct qbuf, rbuf;
SPOOL_Q_SETFORM q;
@@ -1269,10 +1269,10 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
!rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
goto done;
- /* Unmarshall response */
-
+ /* Unmarshall response */
+
if (!spoolss_io_r_setform("", &r, &rbuf, 0))
- goto done;
+ goto done;
/* Return output parameters */
@@ -1305,8 +1305,8 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 offered, uint32 *needed,
- POLICY_HND *handle, const char *formname,
- uint32 level, FORM_1 *form)
+ POLICY_HND *handle, char *formname, uint32 level,
+ FORM_1 *form)
{
prs_struct qbuf, rbuf;
SPOOL_Q_GETFORM q;
@@ -1339,23 +1339,15 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!spoolss_io_r_getform("", &r, &rbuf, 0))
goto done;
- /* Return output parameters */
-
+ /* Return output parameters */
+
result = r.status;
if (needed)
*needed = r.needed;
- if (W_ERROR_IS_OK(result)) {
- switch(level) {
- case 1:
- smb_io_form_1("", r.buffer, form, 0);
- break;
- default:
- DEBUG(10, ("cli_spoolss_getform: unknown info level %d", level));
- return WERR_UNKNOWN_LEVEL;
- }
- }
+ if (W_ERROR_IS_OK(result))
+ smb_io_form_1("", r.buffer, form, 0);
done:
prs_mem_free(&qbuf);
@@ -1377,7 +1369,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*/
WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle, const char *form_name)
+ POLICY_HND *handle, char *form_name)
{
prs_struct qbuf, rbuf;
SPOOL_Q_DELETEFORM q;
@@ -1424,7 +1416,7 @@ static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
int i;
*forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
- prs_set_offset(&buffer->prs,0);
+ buffer->prs.data_offset = 0;
for (i = 0; i < num_forms; i++)
smb_io_form_1("", buffer, &((*forms)[i]), 0);
@@ -1500,967 +1492,47 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 num_jobs, JOB_INFO_1 **jobs)
-{
- uint32 i;
-
- *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1));
- prs_set_offset(&buffer->prs,0);
-
- for (i = 0; i < num_jobs; i++)
- smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
-}
-
-static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 num_jobs, JOB_INFO_2 **jobs)
-{
- uint32 i;
-
- *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2));
- prs_set_offset(&buffer->prs,0);
-
- for (i = 0; i < num_jobs; i++)
- smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
-}
-
-/* Enumerate jobs */
-
-WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, uint32 level, uint32 firstjob,
- uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMJOBS q;
- SPOOL_R_ENUMJOBS r;
- WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- init_buffer(&buffer, offered, mem_ctx);
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer,
- offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- *returned = r.returned;
-
- switch(level) {
- case 1:
- decode_jobs_1(mem_ctx, r.buffer, r.returned,
- &ctr->job.job_info_1);
- break;
- case 2:
- decode_jobs_2(mem_ctx, r.buffer, r.returned,
- &ctr->job.job_info_2);
- break;
- default:
- DEBUG(3, ("unsupported info level %d", level));
- break;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Set job */
-
-WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 jobid, uint32 level,
- uint32 command)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_SETJOB q;
- SPOOL_R_SETJOB r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_setjob(&q, hnd, jobid, level, command);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_setjob("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_setjob("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Get job */
-
-WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, uint32 jobid, uint32 level,
- JOB_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETJOB q;
- SPOOL_R_GETJOB r;
- WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- init_buffer(&buffer, offered, mem_ctx);
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_getjob("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getjob("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- switch(level) {
- case 1:
- decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1);
- break;
- case 2:
- decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2);
- break;
- default:
- DEBUG(3, ("unsupported info level %d", level));
- break;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Startpageprinter. Sent to notify the spooler when a page is about to be
- sent to a printer. */
-
-WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_STARTPAGEPRINTER q;
- SPOOL_R_STARTPAGEPRINTER r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_startpageprinter(&q, hnd);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Endpageprinter. Sent to notify the spooler when a page has finished
- being sent to a printer. */
-
-WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENDPAGEPRINTER q;
- SPOOL_R_ENDPAGEPRINTER r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_endpageprinter(&q, hnd);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Startdocprinter. Sent to notify the spooler that a document is about
- to be spooled for printing. */
-
-WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *docname,
- char *outputfile, char *datatype,
- uint32 *jobid)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_STARTDOCPRINTER q;
- SPOOL_R_STARTDOCPRINTER r;
- WERROR result = W_ERROR(ERRgeneral);
- uint32 level = 1;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile,
- datatype);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (W_ERROR_IS_OK(result))
- *jobid = r.jobid;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Enddocprinter. Sent to notify the spooler that a document has finished
- being spooled. */
-
-WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENDDOCPRINTER q;
- SPOOL_R_ENDDOCPRINTER r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_enddocprinter(&q, hnd);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Get printer data */
-
-WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, const char *valuename,
- REGISTRY_VALUE *value)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDATA q;
- SPOOL_R_GETPRINTERDATA r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_getprinterdata(&q, hnd, valuename, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Return output parameters */
-
- value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
- value->type = r.type;
- value->size = r.size;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, const char *keyname,
- const char *valuename,
- REGISTRY_VALUE *value)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDATAEX q;
- SPOOL_R_GETPRINTERDATAEX r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_getprinterdataex(&q, hnd, keyname, valuename, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getprinterdataex("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Return output parameters */
-
- value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
- value->type = r.type;
- value->size = r.needed;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Set printer data */
+/*********************************************************************************
+ Win32 API - SetPrinterData()
+ ********************************************************************************/
-WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, REGISTRY_VALUE *value)
+WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char* valname, char* value)
{
prs_struct qbuf, rbuf;
SPOOL_Q_SETPRINTERDATA q;
- SPOOL_R_SETPRINTERDATA r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_setprinterdata(
- &q, hnd, value->valuename, value->type, (char *)value->data_p, value->size);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *keyname,
- REGISTRY_VALUE *value)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_SETPRINTERDATAEX q;
- SPOOL_R_SETPRINTERDATAEX r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_setprinterdataex(
- &q, hnd, keyname, value->valuename, value->type, (char *)value->data_p,
- value->size);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_setprinterdataex("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Enum printer data */
-
-WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 ndx,
- uint32 value_offered, uint32 data_offered,
- uint32 *value_needed, uint32 *data_needed,
- REGISTRY_VALUE *value)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERDATA q;
- SPOOL_R_ENUMPRINTERDATA r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Return data */
-
- if (value_needed)
- *value_needed = r.realvaluesize;
-
- if (data_needed)
- *data_needed = r.realdatasize;
-
- if (value) {
- rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1,
- STR_TERMINATE);
- value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize);
- value->type = r.type;
- value->size = r.realdatasize;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, const char *keyname,
- REGVAL_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERDATAEX q;
- SPOOL_R_ENUMPRINTERDATAEX r;
+ SPOOL_R_SETPRINTERDATA r;
WERROR result = W_ERROR(ERRgeneral);
- int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumprinterdataex("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Return data */
-
- ZERO_STRUCTP(ctr);
- regval_ctr_init(ctr);
-
- for (i = 0; i < r.returned; i++) {
- PRINTER_ENUM_VALUES *v = &r.ctr.values[i];
- fstring name;
-
- rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1,
- STR_TERMINATE);
- regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Write data to printer */
-
-WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 data_size, char *data,
- uint32 *num_written)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_WRITEPRINTER q;
- SPOOL_R_WRITEPRINTER r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- /* Initialise input parameters */
- make_spoolss_q_writeprinter(&q, hnd, data_size, data);
+ /* write the request */
+ make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value);
/* Marshall data and send request */
-
- if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
+ if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
-
- if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0))
+ if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0))
goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- if (num_written)
- *num_written = r.buffer_written;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Delete printer data */
-
-WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *valuename)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_DELETEPRINTERDATA q;
- SPOOL_R_DELETEPRINTERDATA r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_deleteprinterdata(&q, hnd, valuename);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *keyname,
- char *valuename)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_DELETEPRINTERDATAEX q;
- SPOOL_R_DELETEPRINTERDATAEX r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_deleteprinterdataex("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, const char *keyname,
- uint16 **keylist, uint32 *len)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERKEY q;
- SPOOL_R_ENUMPRINTERKEY r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_enumprinterkey(&q, hnd, keyname, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinterkey("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERKEY, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumprinterkey("", &r, &rbuf, 0))
- goto done;
-
+
result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Copy results */
-
- if (keylist) {
- *keylist = (uint16 *)malloc(r.keys.buf_len * 2);
- memcpy(*keylist, r.keys.buffer, r.keys.buf_len * 2);
- if (len)
- *len = r.keys.buf_len * 2;
- }
-
- done:
+
+done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
-WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *keyname)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_DELETEPRINTERKEY q;
- SPOOL_R_DELETEPRINTERKEY r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_deleteprinterkey(&q, hnd, keyname);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_deleteprinterkey("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERKEY, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_deleteprinterkey("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
/** @} **/
diff --git a/source/libsmb/cli_srvsvc.c b/source/libsmb/cli_srvsvc.c
new file mode 100755
index 00000000000..9d33149540b
--- /dev/null
+++ b/source/libsmb/cli_srvsvc.c
@@ -0,0 +1,79 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Tim Potter 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Opens a SMB connection to the svrsvc pipe */
+
+struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds)
+{
+ return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds);
+}
+
+NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 switch_value, SRV_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SRV_Q_NET_SRV_GET_INFO q;
+ SRV_R_NET_SRV_GET_INFO r;
+ NTSTATUS result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
+
+ /* Marshall data and send request */
+
+ if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = werror_to_ntstatus(r.status);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 805b5732857..a16dc1093b2 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client connect/disconnect routines
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Andrew Bartlett 2001-2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@ static const struct {
{PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
{PROTOCOL_LANMAN1,"LANMAN1.0"},
{PROTOCOL_LANMAN2,"LM1.2X002"},
- {PROTOCOL_LANMAN2,"DOS LANMAN2.1"},
{PROTOCOL_LANMAN2,"Samba"},
{PROTOCOL_NT1,"NT LANMAN 1.0"},
{PROTOCOL_NT1,"NT LM 0.12"},
@@ -45,35 +44,31 @@ static const struct {
****************************************************************************/
static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
- const char *pass, size_t passlen, const char *workgroup)
+ const char *pass, int passlen)
{
fstring pword;
char *p;
- if (passlen > sizeof(pword)-1)
+ if (passlen > sizeof(pword)-1) {
return False;
-
- /* LANMAN servers predate NT status codes and Unicode and ignore those
- smb flags so we must disable the corresponding default capabilities
- that would otherwise cause the Unicode and NT Status flags to be
- set (and even returned by the server) */
-
- cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
+ }
/* if in share level security then don't send a password now */
- if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
+ if (!(cli->sec_mode & 1)) {
passlen = 0;
+ }
- if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
+ if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) {
/* Encrypted mode needed, and non encrypted password supplied. */
passlen = 24;
- SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
- } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
+ clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
+ SMBencrypt((uchar *)pword,cli->cryptkey,(uchar *)pword);
+ } else if ((cli->sec_mode & 2) && passlen == 24) {
/* Encrypted mode needed, and encrypted password supplied. */
memcpy(pword, pass, passlen);
} else if (passlen > 0) {
/* Plaintext mode needed, assume plaintext supplied. */
- passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+ passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
}
/* send a session setup command */
@@ -92,10 +87,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
p = smb_buf(cli->outbuf);
memcpy(p,pword,passlen);
p += passlen;
- p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
- p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
+ p += clistr_push(cli, p, user, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
@@ -104,8 +96,9 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
show_msg(cli->inbuf);
- if (cli_is_error(cli))
+ if (cli_is_error(cli)) {
return False;
+ }
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -122,17 +115,17 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
{
uint32 capabilities = CAP_NT_SMBS;
- if (!cli->force_dos_errors)
+ if (!cli->force_dos_errors) {
capabilities |= CAP_STATUS32;
+ }
- if (cli->use_level_II_oplocks)
+ if (cli->use_level_II_oplocks) {
capabilities |= CAP_LEVEL_II_OPLOCKS;
+ }
- if (cli->capabilities & CAP_UNICODE)
+ if (cli->capabilities & CAP_UNICODE) {
capabilities |= CAP_UNICODE;
-
- if (cli->capabilities & CAP_LARGE_FILES)
- capabilities |= CAP_LARGE_FILES;
+ }
return capabilities;
}
@@ -159,10 +152,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
SSVAL(cli->outbuf,smb_vwv8,0);
SIVAL(cli->outbuf,smb_vwv11,capabilities);
p = smb_buf(cli->outbuf);
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
+ p += clistr_push(cli, p, "", -1, STR_TERMINATE|STR_CONVERT); /* username */
+ p += clistr_push(cli, p, "", -1, STR_TERMINATE|STR_CONVERT); /* workgroup */
+ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
@@ -171,8 +164,9 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
show_msg(cli->inbuf);
- if (cli_is_error(cli))
+ if (cli_is_error(cli)) {
return False;
+ }
cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -194,10 +188,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
const char *pass, const char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
+ fstring pword;
+ int passlen;
char *p;
- fstring lanman;
-
- fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
+
+ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_CONVERT);
set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
@@ -208,25 +203,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
SSVAL(cli->outbuf,smb_vwv3,2);
SSVAL(cli->outbuf,smb_vwv4,cli->pid);
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
SSVAL(cli->outbuf,smb_vwv8,0);
SIVAL(cli->outbuf,smb_vwv11,capabilities);
p = smb_buf(cli->outbuf);
-
- /* check wether to send the ASCII or UNICODE version of the password */
-
- if ( (capabilities & CAP_UNICODE) == 0 ) {
- p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
- SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
- }
- else {
- p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
- SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf)));
- }
-
- p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
- p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
+ memcpy(p, pword, passlen);
+ p += passlen;
+ p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_CONVERT); /* username */
+ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_CONVERT); /* workgroup */
+ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
@@ -235,8 +221,9 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
show_msg(cli->inbuf);
- if (cli_is_error(cli))
+ if (cli_is_error(cli)) {
return False;
+ }
cli->vuid = SVAL(cli->inbuf,smb_uid);
p = smb_buf(cli->inbuf);
@@ -248,91 +235,35 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
return True;
}
-/**
- * Set the user session key for a connection
- * @param cli The cli structure to add it too
- * @param session_key The session key used. (A copy of this is taken for the cli struct)
- *
- */
-
-static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
-{
- cli->user_session_key = data_blob(session_key.data, session_key.length);
-}
/****************************************************************************
- do a NT1 NTLM/LM encrypted session setup - for when extended security
- is not negotiated.
- @param cli client state to create do session setup on
- @param user username
- @param pass *either* cleartext password (passlen !=24) or LM response.
- @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
- @param workgroup The user's domain.
+ Do a NT1 NTLM/LM encrypted session setup.
****************************************************************************/
static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
- const char *pass, size_t passlen,
- const char *ntpass, size_t ntpasslen,
+ const char *pass, int passlen,
+ const char *ntpass, int ntpasslen,
const char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
- DATA_BLOB lm_response = data_blob(NULL, 0);
- DATA_BLOB nt_response = data_blob(NULL, 0);
- DATA_BLOB session_key = data_blob(NULL, 0);
- BOOL ret = False;
+ fstring pword, ntpword;
char *p;
- if (passlen == 0) {
- /* do nothing - guest login */
- } else if (passlen != 24) {
- if (lp_client_ntlmv2_auth()) {
- DATA_BLOB server_chal;
- DATA_BLOB names_blob;
- server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
-
- /* note that the 'workgroup' here is a best guess - we don't know
- the server's domain at this point. The 'server name' is also
- dodgy...
- */
- names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
-
- if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
- &names_blob,
- &lm_response, &nt_response, &session_key)) {
- data_blob_free(&names_blob);
- data_blob_free(&server_chal);
- return False;
- }
- data_blob_free(&names_blob);
- data_blob_free(&server_chal);
-
- } else {
- uchar nt_hash[16];
- E_md4hash(pass, nt_hash);
-
- nt_response = data_blob(NULL, 24);
- SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
-
- /* non encrypted password supplied. Ignore ntpass. */
- if (lp_client_lanman_auth()) {
- lm_response = data_blob(NULL, 24);
- SMBencrypt(pass,cli->secblob.data, lm_response.data);
- } else {
- /* LM disabled, place NT# in LM field instead */
- lm_response = data_blob(nt_response.data, nt_response.length);
- }
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+ return False;
+ }
- session_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
- }
- cli_simple_set_signing(cli, session_key, nt_response);
+ if (passlen != 24) {
+ /* non encrypted password supplied. */
+ passlen = 24;
+ ntpasslen = 24;
+ clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_CONVERT);
+ clistr_push(cli, ntpword, ntpass, sizeof(ntpword), STR_TERMINATE|STR_CONVERT);
+ SMBencrypt((uchar *)pword,cli->cryptkey,(uchar *)pword);
+ SMBNTencrypt((uchar *)ntpword,cli->cryptkey,(uchar *)ntpword);
} else {
- /* pre-encrypted password supplied. Only used for
- security=server, can't do
- signing because we don't have original key */
-
- lm_response = data_blob(pass, passlen);
- nt_response = data_blob(ntpass, ntpasslen);
+ memcpy(pword, pass, passlen);
+ memcpy(ntpword, ntpass, ntpasslen);
}
/* send a session setup command */
@@ -347,399 +278,39 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
SSVAL(cli->outbuf,smb_vwv3,2);
SSVAL(cli->outbuf,smb_vwv4,cli->pid);
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
- SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
- SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
+ SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
SIVAL(cli->outbuf,smb_vwv11,capabilities);
p = smb_buf(cli->outbuf);
- if (lm_response.length) {
- memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
- }
- if (nt_response.length) {
- memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
- }
- p += clistr_push(cli, p, user, -1, STR_TERMINATE);
-
- /* Upper case here might help some NTLMv2 implementations */
- p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
- cli_setup_bcc(cli, p);
-
- if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
- ret = False;
- goto end;
- }
-
- /* show_msg(cli->inbuf); */
-
- if (cli_is_error(cli)) {
- ret = False;
- goto end;
- }
-
- /* use the returned vuid from now on */
- cli->vuid = SVAL(cli->inbuf,smb_uid);
-
- p = smb_buf(cli->inbuf);
- p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
- p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
- p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
-
- fstrcpy(cli->user_name, user);
-
- if (session_key.data) {
- /* Have plaintext orginal */
- cli_set_session_key(cli, session_key);
- }
-
- ret = True;
-end:
- data_blob_free(&lm_response);
- data_blob_free(&nt_response);
-
- if (!ret)
- data_blob_free(&session_key);
- return ret;
-}
-
-/****************************************************************************
- Send a extended security session setup blob
-****************************************************************************/
-
-static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
-{
- uint32 capabilities = cli_session_setup_capabilities(cli);
- char *p;
-
- capabilities |= CAP_EXTENDED_SECURITY;
-
- /* send a session setup command */
- memset(cli->outbuf,'\0',smb_size);
-
- set_message(cli->outbuf,12,0,True);
- SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
-
- cli_setup_packet(cli);
-
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
- SSVAL(cli->outbuf,smb_vwv3,2);
- SSVAL(cli->outbuf,smb_vwv4,1);
- SIVAL(cli->outbuf,smb_vwv5,0);
- SSVAL(cli->outbuf,smb_vwv7,blob.length);
- SIVAL(cli->outbuf,smb_vwv10,capabilities);
- p = smb_buf(cli->outbuf);
- memcpy(p, blob.data, blob.length);
- p += blob.length;
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
+ memcpy(p,pword,passlen); p += passlen;
+ memcpy(p,ntpword,ntpasslen); p += ntpasslen;
+ p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER|STR_CONVERT);
+ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER|STR_CONVERT);
+ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
- return cli_send_smb(cli);
-}
-
-/****************************************************************************
- Send a extended security session setup blob, returning a reply blob.
-****************************************************************************/
-
-static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
-{
- DATA_BLOB blob2 = data_blob(NULL, 0);
- char *p;
- size_t len;
+ cli_send_smb(cli);
if (!cli_receive_smb(cli))
- return blob2;
+ return False;
show_msg(cli->inbuf);
- if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- return blob2;
+ if (cli_is_error(cli)) {
+ return False;
}
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
p = smb_buf(cli->inbuf);
-
- blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
-
- p += blob2.length;
p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
-
- /* w2k with kerberos doesn't properly null terminate this field */
- len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf));
- p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0);
-
- return blob2;
-}
-
-#ifdef HAVE_KRB5
-
-/****************************************************************************
- Send a extended security session setup blob, returning a reply blob.
-****************************************************************************/
-
-static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
-{
- DATA_BLOB blob2 = data_blob(NULL, 0);
- if (!cli_session_setup_blob_send(cli, blob)) {
- return blob2;
- }
-
- return cli_session_setup_blob_receive(cli);
-}
-
-/****************************************************************************
- Use in-memory credentials cache
-****************************************************************************/
-
-static void use_in_memory_ccache(void) {
- setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
-}
-
-/****************************************************************************
- Do a spnego/kerberos encrypted session setup.
-****************************************************************************/
-
-static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
-{
- DATA_BLOB blob2, negTokenTarg;
- DATA_BLOB session_key_krb5;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- int rc;
-
- DEBUG(2,("Doing kerberos session setup\n"));
-
- /* generate the encapsulated kerberos5 ticket */
- rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5);
-
- if (rc) {
- DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc)));
- return ADS_ERROR_KRB5(rc);
- }
-
-#if 0
- file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
-#endif
-
- cli_simple_set_signing(cli, session_key_krb5, null_blob);
-
- blob2 = cli_session_setup_blob(cli, negTokenTarg);
-
- /* we don't need this blob for kerberos */
- data_blob_free(&blob2);
-
- cli_set_session_key(cli, session_key_krb5);
-
- data_blob_free(&negTokenTarg);
-
- if (cli_is_error(cli)) {
- if (NT_STATUS_IS_OK(cli_nt_error(cli))) {
- return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- }
- }
- return ADS_ERROR_NT(cli_nt_error(cli));
-}
-#endif /* HAVE_KRB5 */
-
-
-/****************************************************************************
- Do a spnego/NTLMSSP encrypted session setup.
-****************************************************************************/
-
-static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
- const char *pass, const char *domain)
-{
- struct ntlmssp_state *ntlmssp_state;
- NTSTATUS nt_status;
- int turn = 1;
- DATA_BLOB msg1;
- DATA_BLOB blob;
- DATA_BLOB blob_in = data_blob(NULL, 0);
- DATA_BLOB blob_out;
-
- cli_temp_set_signing(cli);
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
- return nt_status;
- }
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
- return nt_status;
- }
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
- return nt_status;
- }
-
- do {
- nt_status = ntlmssp_update(ntlmssp_state,
- blob_in, &blob_out);
- data_blob_free(&blob_in);
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- if (turn == 1) {
- /* and wrap it in a SPNEGO wrapper */
- msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
- } else {
- /* wrap it in SPNEGO */
- msg1 = spnego_gen_auth(blob_out);
- }
-
- /* now send that blob on its way */
- if (!cli_session_setup_blob_send(cli, msg1)) {
- DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- } else {
- data_blob_free(&msg1);
-
- blob = cli_session_setup_blob_receive(cli);
-
- nt_status = cli_nt_error(cli);
- if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
- if (cli->smb_rw_error == READ_BAD_SIG) {
- nt_status = NT_STATUS_ACCESS_DENIED;
- } else {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
- }
- }
- }
-
- if (!blob.length) {
- if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
- } else if ((turn == 1) &&
- NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DATA_BLOB tmp_blob = data_blob(NULL, 0);
- /* the server might give us back two challenges */
- if (!spnego_parse_challenge(blob, &blob_in,
- &tmp_blob)) {
- DEBUG(3,("Failed to parse challenges\n"));
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- data_blob_free(&tmp_blob);
- } else {
- if (!spnego_parse_auth_response(blob, nt_status,
- &blob_in)) {
- DEBUG(3,("Failed to parse auth response\n"));
- if (NT_STATUS_IS_OK(nt_status)
- || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- }
- data_blob_free(&blob);
- data_blob_free(&blob_out);
- turn++;
- } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
-
- if (NT_STATUS_IS_OK(nt_status)) {
-
- DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
- ntlmssp_state->session_key.length);
- DATA_BLOB null_blob = data_blob(NULL, 0);
-
- fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
- cli_set_session_key(cli, ntlmssp_state->session_key);
-
- if (cli_simple_set_signing(cli, key, null_blob)) {
-
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli);
-
- if (!cli_check_sign_mac(cli, True)) {
- nt_status = NT_STATUS_ACCESS_DENIED;
- }
- }
- }
-
- /* we have a reference conter on ntlmssp_state, if we are signing
- then the state will be kept by the signing engine */
-
- ntlmssp_end(&ntlmssp_state);
-
- return nt_status;
-}
-
-/****************************************************************************
- Do a spnego encrypted session setup.
-****************************************************************************/
-
-ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
- const char *pass, const char *domain)
-{
- char *principal;
- char *OIDs[ASN1_MAX_OIDS];
- int i;
- BOOL got_kerberos_mechanism = False;
- DATA_BLOB blob;
-
- DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
-
- /* the server might not even do spnego */
- if (cli->secblob.length <= 16) {
- DEBUG(3,("server didn't supply a full spnego negprot\n"));
- goto ntlmssp;
- }
-
-#if 0
- file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
-#endif
-
- /* there is 16 bytes of GUID before the real spnego packet starts */
- blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
-
- /* the server sent us the first part of the SPNEGO exchange in the negprot
- reply */
- if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
- data_blob_free(&blob);
- return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
- data_blob_free(&blob);
-
- /* make sure the server understands kerberos */
- for (i=0;OIDs[i];i++) {
- DEBUG(3,("got OID=%s\n", OIDs[i]));
- if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
- strcmp(OIDs[i], OID_KERBEROS5) == 0) {
- got_kerberos_mechanism = True;
- }
- free(OIDs[i]);
- }
- DEBUG(3,("got principal=%s\n", principal));
+ p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
fstrcpy(cli->user_name, user);
-#ifdef HAVE_KRB5
- /* If password is set we reauthenticate to kerberos server
- * and do not store results */
-
- if (got_kerberos_mechanism && cli->use_kerberos) {
- if (pass && *pass) {
- int ret;
-
- use_in_memory_ccache();
- ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
-
- if (ret){
- DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
- return ADS_ERROR_KRB5(ret);
- }
- }
-
- return cli_session_setup_kerberos(cli, principal, domain);
- }
-#endif
-
- free(principal);
-
-ntlmssp:
-
- return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain));
+ return True;
}
/****************************************************************************
@@ -759,8 +330,7 @@ BOOL cli_session_setup(struct cli_state *cli,
/* allow for workgroups as part of the username */
fstrcpy(user2, user);
- if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
- (p=strchr_m(user2,*lp_winbind_separator()))) {
+ if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/')) || (p=strchr(user2,*lp_winbind_separator())) ) {
*p = 0;
user = p+1;
workgroup = user2;
@@ -774,62 +344,30 @@ BOOL cli_session_setup(struct cli_state *cli,
flow a bit easier to understand (tridge) */
/* if its an older server then we have to use the older request format */
-
if (cli->protocol < PROTOCOL_NT1) {
- if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
- DEBUG(1, ("Server requested LM password but 'client lanman auth'"
- " is disabled\n"));
- return False;
- }
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
- !lp_client_plaintext_auth() && (*pass)) {
- DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
- " is disabled\n"));
- return False;
- }
-
- return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup);
+ return cli_session_setup_lanman2(cli, user, pass, passlen);
}
/* if no user is supplied then we have to do an anonymous connection.
passwords are ignored */
-
- if (!user || !*user)
+ if (!user || !*user) {
return cli_session_setup_guest(cli);
+ }
/* if the server is share level then send a plaintext null
password at this point. The password is sent in the tree
connect */
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
+ if ((cli->sec_mode & 1) == 0) {
return cli_session_setup_plaintext(cli, user, "", workgroup);
-
- /* if the server doesn't support encryption then we have to use
- plaintext. The second password is ignored */
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
- if (!lp_client_plaintext_auth() && (*pass)) {
- DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
- " is disabled\n"));
- return False;
- }
- return cli_session_setup_plaintext(cli, user, pass, workgroup);
}
- /* if the server supports extended security then use SPNEGO */
-
- if (cli->capabilities & CAP_EXTENDED_SECURITY) {
- ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup);
- if (!ADS_ERR_OK(status)) {
- DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
- return False;
- }
- return True;
+ /* if the server doesn't support encryption then we have to use plaintext. The
+ second password is ignored */
+ if ((cli->sec_mode & 2) == 0) {
+ return cli_session_setup_plaintext(cli, user, pass, workgroup);
}
- /* otherwise do a NT1 style session setup */
-
+ /* Do a NT1 style session setup */
return cli_session_setup_nt1(cli, user,
pass, passlen, ntpass, ntpasslen,
workgroup);
@@ -841,27 +379,28 @@ BOOL cli_session_setup(struct cli_state *cli,
BOOL cli_ulogoff(struct cli_state *cli)
{
- memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,2,0,True);
- SCVAL(cli->outbuf,smb_com,SMBulogoffX);
- cli_setup_packet(cli);
+ memset(cli->outbuf,'\0',smb_size);
+ set_message(cli->outbuf,2,0,True);
+ SCVAL(cli->outbuf,smb_com,SMBulogoffX);
+ cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli))
+ return False;
- return !cli_is_error(cli);
+ return !cli_is_error(cli);
}
/****************************************************************************
Send a tconX.
****************************************************************************/
+
BOOL cli_send_tconX(struct cli_state *cli,
const char *share, const char *dev, const char *pass, int passlen)
{
- fstring fullshare, pword;
+ fstring fullshare, pword, dos_pword;
char *p;
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
@@ -869,36 +408,24 @@ BOOL cli_send_tconX(struct cli_state *cli,
fstrcpy(cli->share, share);
/* in user level security don't send a password now */
- if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
+ if (cli->sec_mode & 1) {
passlen = 1;
pass = "";
}
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) {
- if (!lp_client_lanman_auth()) {
- DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'"
- " is disabled\n"));
- return False;
- }
-
+ if ((cli->sec_mode & 2) && *pass && passlen != 24) {
/*
* Non-encrypted passwords - convert to DOS codepage before encryption.
*/
passlen = 24;
- SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
+ clistr_push(cli, dos_pword, pass, -1, STR_CONVERT|STR_TERMINATE);
+ SMBencrypt((uchar *)dos_pword,cli->cryptkey,(uchar *)pword);
} else {
- if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
- if (!lp_client_plaintext_auth() && (*pass)) {
- DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
- " is disabled\n"));
- return False;
- }
-
+ if((cli->sec_mode & 3) == 0) {
/*
* Non-encrypted passwords - convert to DOS codepage before using.
*/
- passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
-
+ passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
} else {
memcpy(pword, pass, passlen);
}
@@ -917,8 +444,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
p = smb_buf(cli->outbuf);
memcpy(p,pword,passlen);
p += passlen;
- p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
- p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
+ p += clistr_push(cli, p, fullshare, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
+ fstrcpy(p, dev); p += strlen(dev)+1;
cli_setup_bcc(cli, p);
@@ -926,11 +453,21 @@ BOOL cli_send_tconX(struct cli_state *cli,
if (!cli_receive_smb(cli))
return False;
- if (cli_is_error(cli))
+ if (cli_is_error(cli)) {
return False;
+ }
- clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
+ fstrcpy(cli->dev, "A:");
+
+ if (cli->protocol >= PROTOCOL_NT1) {
+ clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE);
+ }
+ if (strcasecmp(share,"IPC$")==0) {
+ fstrcpy(cli->dev, "IPC");
+ }
+
+ /* only grab the device if we have a recent protocol level */
if (cli->protocol >= PROTOCOL_NT1 &&
smb_buflen(cli->inbuf) == 3) {
/* almost certainly win95 - enable bug fixes */
@@ -941,6 +478,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
return True;
}
+
/****************************************************************************
Send a tree disconnect.
****************************************************************************/
@@ -960,6 +498,7 @@ BOOL cli_tdis(struct cli_state *cli)
return !cli_is_error(cli);
}
+
/****************************************************************************
Send a negprot command.
****************************************************************************/
@@ -969,9 +508,6 @@ void cli_negprot_send(struct cli_state *cli)
char *p;
int numprots;
- if (cli->protocol < PROTOCOL_NT1)
- cli->use_spnego = False;
-
memset(cli->outbuf,'\0',smb_size);
/* setup the protocol strings */
@@ -982,7 +518,7 @@ void cli_negprot_send(struct cli_state *cli)
prots[numprots].name && prots[numprots].prot<=cli->protocol;
numprots++) {
*p++ = 2;
- p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, prots[numprots].name, -1, STR_CONVERT|STR_TERMINATE);
}
SCVAL(cli->outbuf,smb_com,SMBnegprot);
@@ -994,6 +530,7 @@ void cli_negprot_send(struct cli_state *cli)
cli_send_smb(cli);
}
+
/****************************************************************************
Send a negprot command.
****************************************************************************/
@@ -1004,9 +541,6 @@ BOOL cli_negprot(struct cli_state *cli)
int numprots;
int plength;
- if (cli->protocol < PROTOCOL_NT1)
- cli->use_spnego = False;
-
memset(cli->outbuf,'\0',smb_size);
/* setup the protocol strings */
@@ -1022,7 +556,7 @@ BOOL cli_negprot(struct cli_state *cli)
prots[numprots].name && prots[numprots].prot<=cli->protocol;
numprots++) {
*p++ = 2;
- p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, prots[numprots].name, -1, STR_CONVERT|STR_TERMINATE);
}
SCVAL(cli->outbuf,smb_com,SMBnegprot);
@@ -1041,12 +575,7 @@ BOOL cli_negprot(struct cli_state *cli)
return(False);
}
- cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
-
- if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
- DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
- return False;
- }
+ cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
if (cli->protocol >= PROTOCOL_NT1) {
/* NT protocol */
@@ -1058,47 +587,19 @@ BOOL cli_negprot(struct cli_state *cli)
cli->serverzone *= 60;
/* this time arrives in real GMT */
cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
- cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
+ memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
if (cli->capabilities & CAP_RAW_MODE) {
cli->readbraw_supported = True;
cli->writebraw_supported = True;
}
/* work out if they sent us a workgroup */
- if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
- smb_buflen(cli->inbuf) > 8) {
+ if (smb_buflen(cli->inbuf) > 8) {
clistr_pull(cli, cli->server_domain,
smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
}
-
- /*
- * As signing is slow we only turn it on if either the client or
- * the server require it. JRA.
- */
-
- if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
- /* Fail if server says signing is mandatory and we don't want to support it. */
- if (!cli->sign_info.allow_smb_signing) {
- DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
- return False;
- }
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
- } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
- /* Fail if client says signing is mandatory and the server doesn't support it. */
- if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
- DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
- return False;
- }
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
- } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
- cli->sign_info.negotiated_smb_signing = True;
- }
-
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
- cli->use_spnego = False;
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
@@ -1108,10 +609,9 @@ BOOL cli_negprot(struct cli_state *cli)
cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
- cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
+ memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
} else {
/* the old core protocol */
- cli->use_spnego = False;
cli->sec_mode = 0;
cli->serverzone = TimeDiff(time(NULL));
}
@@ -1119,14 +619,16 @@ BOOL cli_negprot(struct cli_state *cli)
cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
/* a way to force ascii SMB */
- if (getenv("CLI_FORCE_ASCII"))
+ if (getenv("CLI_FORCE_ASCII")) {
cli->capabilities &= ~CAP_UNICODE;
+ }
return True;
}
+
/****************************************************************************
- Send a session request. See rfc1002.txt 4.3 and 4.3.2.
+ Send a session request. see rfc1002.txt 4.3 and 4.3.2.
****************************************************************************/
BOOL cli_session_request(struct cli_state *cli,
@@ -1136,6 +638,10 @@ BOOL cli_session_request(struct cli_state *cli,
int len = 4;
extern pstring user_socket_options;
+ /* 445 doesn't have session request */
+ if (cli->port == 445) return True;
+
+ /* send a session request (RFC 1002) */
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
@@ -1149,12 +655,7 @@ BOOL cli_session_request(struct cli_state *cli,
name_mangle(cli->calling.name, p, cli->calling.name_type);
len += name_len(p);
- /* 445 doesn't have session request */
- if (cli->port == 445)
- return True;
-
- /* send a session request (RFC 1002) */
- /* setup the packet length
+ /* setup the packet length
* Remove four bytes from the length count, since the length
* field in the NBT Session Service header counts the number
* of bytes which follow. The cli_send_smb() function knows
@@ -1165,6 +666,10 @@ BOOL cli_session_request(struct cli_state *cli,
_smb_setlen(cli->outbuf,len);
SCVAL(cli->outbuf,0,0x81);
+#ifdef WITH_SSL
+retry:
+#endif /* WITH_SSL */
+
cli_send_smb(cli);
DEBUG(5,("Sent session request\n"));
@@ -1210,6 +715,15 @@ BOOL cli_session_request(struct cli_state *cli,
}
} /* C. Hoch 9/14/95 End */
+#ifdef WITH_SSL
+ if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
+ if (!sslutil_fd_is_ssl(cli->fd)){
+ if (sslutil_connect(cli->fd) == 0)
+ goto retry;
+ }
+ }
+#endif /* WITH_SSL */
+
if (CVAL(cli->inbuf,0) != 0x82) {
/* This is the wrong place to put the error... JRA. */
cli->rap_error = CVAL(cli->inbuf,4);
@@ -1229,10 +743,11 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
char *p;
/* reasonable default hostname */
- if (!host) host = "*SMBSERVER";
+ if (!host)
+ host = "*SMBSERVER";
fstrcpy(cli->desthost, host);
-
+
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(cli->desthost, '#'))) {
name_type = strtol(p+1, NULL, 16);
@@ -1240,10 +755,11 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
}
if (!ip || is_zero_ip(*ip)) {
- if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
- return False;
- }
- if (ip) *ip = cli->dest_ip;
+ if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
+ return False;
+ }
+ if (ip)
+ *ip = cli->dest_ip;
} else {
cli->dest_ip = *ip;
}
@@ -1260,12 +776,11 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
port, cli->timeout);
}
- if (cli->fd != -1)
- cli->port = port;
+ if (cli->fd != -1) cli->port = port;
}
if (cli->fd == -1) {
DEBUG(1,("Error connecting to %s (%s)\n",
- ip?inet_ntoa(*ip):host,strerror(errno)));
+ inet_ntoa(*ip),strerror(errno)));
return False;
}
@@ -1275,11 +790,131 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
}
/****************************************************************************
+ Establishes a connection right up to doing tconX, reading in a password.
+****************************************************************************/
+
+BOOL cli_establish_connection(struct cli_state *cli,
+ const char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ const char *service, const char *service_type,
+ BOOL do_shutdown, BOOL do_tcon)
+{
+ DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
+ nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
+ cli->user_name, cli->domain));
+
+ /* establish connection */
+
+ if ((!cli->initialised))
+ return False;
+
+ if (cli->fd == -1) {
+ if (!cli_connect(cli, dest_host, dest_ip)) {
+ DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
+ nmb_namestr(called), inet_ntoa(*dest_ip)));
+ return False;
+ }
+ }
+
+ if (!cli_session_request(cli, calling, called)) {
+ DEBUG(1,("failed session request\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (!cli_negprot(cli)) {
+ DEBUG(1,("failed negprot\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (cli->pwd.cleartext || cli->pwd.null_pwd) {
+ fstring passwd;
+ int pass_len;
+
+ if (cli->pwd.null_pwd) {
+ /* attempt null session */
+ passwd[0] = 0;
+ pass_len = 1;
+ } else {
+ /* attempt clear-text session */
+ pwd_get_cleartext(&(cli->pwd), passwd);
+ pass_len = strlen(passwd);
+ }
+
+ /* attempt clear-text session */
+ if (!cli_session_setup(cli, cli->user_name,
+ passwd, pass_len,
+ NULL, 0,
+ cli->domain)) {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+ if (do_tcon) {
+ if (!cli_send_tconX(cli, service, service_type,
+ (char*)passwd, strlen(passwd))) {
+ DEBUG(1,("failed tcon_X\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+ }
+ } else {
+ /* attempt encrypted session */
+ unsigned char nt_sess_pwd[24];
+ unsigned char lm_sess_pwd[24];
+
+ /* creates (storing a copy of) and then obtains a 24 byte password OWF */
+ pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey);
+ pwd_get_lm_nt_owf(&cli->pwd, lm_sess_pwd, nt_sess_pwd);
+
+ /* attempt encrypted session */
+ if (!cli_session_setup(cli, cli->user_name,
+ (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
+ (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
+ cli->domain)) {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+
+ DEBUG(1,("session setup ok\n"));
+
+ if (*cli->server_domain || *cli->server_os || *cli->server_type) {
+ DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+ cli->server_domain,
+ cli->server_os,
+ cli->server_type));
+ }
+
+ if (do_tcon) {
+ if (!cli_send_tconX(cli, service, service_type,
+ (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) {
+ DEBUG(1,("failed tcon_X\n"));
+ if (do_shutdown)
+ cli_shutdown(cli);
+ return False;
+ }
+ }
+ }
+
+ if (do_shutdown)
+ cli_shutdown(cli);
+
+ return True;
+}
+
+/****************************************************************************
Initialise client credentials for authenticated pipe access.
****************************************************************************/
-void init_creds(struct ntuser_creds *creds, const char* username,
- const char* domain, const char* password)
+static void init_creds(struct ntuser_creds *creds, const char* username,
+ const char* domain, const char* password, int pass_len)
{
ZERO_STRUCTP(creds);
@@ -1293,70 +928,58 @@ void init_creds(struct ntuser_creds *creds, const char* username,
}
}
-/**
- establishes a connection to after the negprot.
- @param output_cli A fully initialised cli structure, non-null only on success
- @param dest_host The netbios name of the remote host
- @param dest_ip (optional) The the destination IP, NULL for name based lookup
- @param port (optional) The destination port (0 for default)
- @param retry BOOL. Did this connection fail with a retryable error ?
+/****************************************************************************
+ Establishes a connection right up to doing tconX, password specified.
+****************************************************************************/
-*/
-NTSTATUS cli_start_connection(struct cli_state **output_cli,
- const char *my_name,
- const char *dest_host,
- struct in_addr *dest_ip, int port,
- int signing_state, int flags,
- BOOL *retry)
+NTSTATUS cli_full_connection(struct cli_state **output_cli,
+ const char *my_name, const char *dest_host,
+ struct in_addr *dest_ip, int port,
+ const char *service, const char *service_type,
+ const char *user, const char *domain,
+ const char *password, int pass_len)
{
+ struct ntuser_creds creds;
NTSTATUS nt_status;
struct nmb_name calling;
struct nmb_name called;
struct cli_state *cli;
struct in_addr ip;
-
- if (retry)
- *retry = False;
-
- if (!my_name)
- my_name = global_myname();
- if (!(cli = cli_initialise(NULL)))
- return NT_STATUS_NO_MEMORY;
+ if (!output_cli)
+ DEBUG(0, ("output_cli is NULL!?!"));
+
+ *output_cli = NULL;
make_nmb_name(&calling, my_name, 0x0);
make_nmb_name(&called , dest_host, 0x20);
+again:
+
+ if (!(cli = cli_initialise(NULL)))
+ return NT_STATUS_NO_MEMORY;
+
if (cli_set_port(cli, port) != port) {
cli_shutdown(cli);
return NT_STATUS_UNSUCCESSFUL;
}
- cli_set_timeout(cli, 10000); /* 10 seconds. */
-
- if (dest_ip)
- ip = *dest_ip;
- else
- ZERO_STRUCT(ip);
-
-again:
-
- DEBUG(3,("Connecting to host=%s\n", dest_host));
+ ip = *dest_ip;
+
+ DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service));
if (!cli_connect(cli, dest_host, &ip)) {
- DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n",
- nmb_namestr(&called), inet_ntoa(ip)));
+ DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
+ nmb_namestr(&called), inet_ntoa(*dest_ip)));
cli_shutdown(cli);
return NT_STATUS_UNSUCCESSFUL;
}
- if (retry)
- *retry = True;
-
if (!cli_session_request(cli, &calling, &called)) {
char *p;
DEBUG(1,("session request to %s failed (%s)\n",
called.name, cli_errstr(cli)));
+ cli_shutdown(cli);
if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
*p = 0;
goto again;
@@ -1368,13 +991,6 @@ again:
return NT_STATUS_UNSUCCESSFUL;
}
- cli_setup_signing_state(cli, signing_state);
-
- if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
- cli->use_spnego = False;
- else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
- cli->use_kerberos = True;
-
if (!cli_negprot(cli)) {
DEBUG(1,("failed negprot\n"));
nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -1382,75 +998,29 @@ again:
return nt_status;
}
- *output_cli = cli;
- return NT_STATUS_OK;
-}
-
-
-/**
- establishes a connection right up to doing tconX, password specified.
- @param output_cli A fully initialised cli structure, non-null only on success
- @param dest_host The netbios name of the remote host
- @param dest_ip (optional) The the destination IP, NULL for name based lookup
- @param port (optional) The destination port (0 for default)
- @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
- @param service_type The 'type' of serivice.
- @param user Username, unix string
- @param domain User's domain
- @param password User's password, unencrypted unix string.
- @param retry BOOL. Did this connection fail with a retryable error ?
-*/
-
-NTSTATUS cli_full_connection(struct cli_state **output_cli,
- const char *my_name,
- const char *dest_host,
- struct in_addr *dest_ip, int port,
- const char *service, const char *service_type,
- const char *user, const char *domain,
- const char *password, int flags,
- int signing_state,
- BOOL *retry)
-{
- struct ntuser_creds creds;
- NTSTATUS nt_status;
- struct cli_state *cli = NULL;
-
- nt_status = cli_start_connection(&cli, my_name, dest_host,
- dest_ip, port, signing_state, flags, retry);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- if (!cli_session_setup(cli, user, password, strlen(password)+1,
- password, strlen(password)+1,
+ if (!cli_session_setup(cli, user, password, pass_len, password, pass_len,
domain)) {
- if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
- && cli_session_setup(cli, "", "", 0, "", 0, domain)) {
- } else {
- nt_status = cli_nt_error(cli);
- DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status)));
- cli_shutdown(cli);
- if (NT_STATUS_IS_OK(nt_status))
- nt_status = NT_STATUS_UNSUCCESSFUL;
- return nt_status;
- }
+ DEBUG(1,("failed session setup\n"));
+ nt_status = cli_nt_error(cli);
+ cli_shutdown(cli);
+ if (NT_STATUS_IS_OK(nt_status))
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ return nt_status;
}
if (service) {
if (!cli_send_tconX(cli, service, service_type,
- password, strlen(password)+1)) {
+ password, pass_len)) {
+ DEBUG(1,("failed tcon_X\n"));
nt_status = cli_nt_error(cli);
- DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
cli_shutdown(cli);
- if (NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_IS_OK(nt_status))
nt_status = NT_STATUS_UNSUCCESSFUL;
- }
return nt_status;
}
}
- init_creds(&creds, user, domain, password);
+ init_creds(&creds, user, domain, password, pass_len);
cli_init_creds(cli, &creds);
*output_cli = cli;
@@ -1479,6 +1049,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost,
make_nmb_name(&called, desthost, 0x20);
if (!cli_session_request(cli, &calling, &called)) {
+
struct nmb_name smbservername;
make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
@@ -1494,8 +1065,8 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost,
* The name used was *SMBSERVER, don't bother with another name.
*/
- DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
-with error %s.\n", desthost, cli_errstr(cli) ));
+ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER with error %s.\n",
+ desthost, cli_errstr(cli) ));
return False;
}
@@ -1507,179 +1078,13 @@ with error %s.\n", desthost, cli_errstr(cli) ));
cli_close_connection(cli);
- if (!cli_initialise(cli) ||
- !cli_connect(cli, desthost, pdest_ip) ||
- !cli_session_request(cli, &calling, &smbservername)) {
- DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
-name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) ));
+ if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) ||
+ !cli_session_request(cli, &calling, &smbservername)) {
+ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER with error %s\n",
+ desthost, cli_errstr(cli) ));
return False;
}
}
return True;
}
-
-
-
-
-
-/****************************************************************************
- Send an old style tcon.
-****************************************************************************/
-NTSTATUS cli_raw_tcon(struct cli_state *cli,
- const char *service, const char *pass, const char *dev,
- uint16 *max_xmit, uint16 *tid)
-{
- char *p;
-
- if (!lp_client_plaintext_auth() && (*pass)) {
- DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
- " is disabled\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf, 0, 0, True);
- SCVAL(cli->outbuf,smb_com,SMBtcon);
- cli_setup_packet(cli);
-
- p = smb_buf(cli->outbuf);
- *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
- *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
- *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
-
- cli_setup_bcc(cli, p);
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- }
-
- if (cli_is_error(cli)) {
- return cli_nt_error(cli);
- }
-
- *max_xmit = SVAL(cli->inbuf, smb_vwv0);
- *tid = SVAL(cli->inbuf, smb_vwv1);
-
- return NT_STATUS_OK;
-}
-
-/* Return a cli_state pointing at the IPC$ share for the given server */
-
-struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
- struct user_auth_info *user_info)
-{
- struct cli_state *cli;
- pstring myname;
- NTSTATUS nt_status;
-
- get_myname(myname);
-
- nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC",
- user_info->username, lp_workgroup(), user_info->password,
- CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- return cli;
- } else if (is_ipaddress(server)) {
- /* windows 9* needs a correct NMB name for connections */
- fstring remote_name;
-
- if (name_status_find("*", 0, 0, *server_ip, remote_name)) {
- cli = get_ipc_connect(remote_name, server_ip, user_info);
- if (cli)
- return cli;
- }
- }
- return NULL;
-}
-
-/*
- * Given the IP address of a master browser on the network, return its
- * workgroup and connect to it.
- *
- * This function is provided to allow additional processing beyond what
- * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
- * browsers and obtain each master browsers' list of domains (in case the
- * first master browser is recently on the network and has not yet
- * synchronized with other master browsers and therefore does not yet have the
- * entire network browse list)
- */
-
-struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info)
-{
- static fstring name;
- struct cli_state *cli;
- struct in_addr server_ip;
-
- DEBUG(99, ("Looking up name of master browser %s\n",
- inet_ntoa(mb_ip->ip)));
-
- /*
- * Do a name status query to find out the name of the master browser.
- * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
- * master browser will not respond to a wildcard query (or, at least,
- * an NT4 server acting as the domain master browser will not).
- *
- * We might be able to use ONLY the query on MSBROWSE, but that's not
- * yet been tested with all Windows versions, so until it is, leave
- * the original wildcard query as the first choice and fall back to
- * MSBROWSE if the wildcard query fails.
- */
- if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) &&
- !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) {
-
- DEBUG(99, ("Could not retrieve name status for %s\n",
- inet_ntoa(mb_ip->ip)));
- return NULL;
- }
-
- if (!find_master_ip(name, &server_ip)) {
- DEBUG(99, ("Could not find master ip for %s\n", name));
- return NULL;
- }
-
- pstrcpy(workgroup, name);
-
- DEBUG(4, ("found master browser %s, %s\n",
- name, inet_ntoa(mb_ip->ip)));
-
- cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
-
- return cli;
-
-}
-
-/*
- * Return the IP address and workgroup of a master browser on the network, and
- * connect to it.
- */
-
-struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info)
-{
- struct ip_service *ip_list;
- struct cli_state *cli;
- int i, count;
-
- DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
-
- /* Go looking for workgroups by broadcasting on the local network */
-
- if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
- DEBUG(99, ("No master browsers responded\n"));
- return False;
- }
-
- for (i = 0; i < count; i++) {
- DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
-
- cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
- if (cli)
- return(cli);
- }
-
- return NULL;
-}
diff --git a/source/libsmb/clidgram.c b/source/libsmb/clidgram.c
index c4675f1938a..2511c787ca6 100644
--- a/source/libsmb/clidgram.c
+++ b/source/libsmb/clidgram.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client dgram calls
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Richard Sharpe 2001
@@ -20,6 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define NO_SYSLOG
+
#include "includes.h"
/*
@@ -51,7 +54,9 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot,
dgram->header.flags.more = False;
dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
dgram->header.source_ip.s_addr = src_ip.s_addr;
+ /*fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); */
dgram->header.source_port = ntohs(src_port);
+ fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port);
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
dgram->header.packet_offset = 0;
@@ -75,7 +80,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot,
SSVAL(ptr,smb_vwv15,1);
SSVAL(ptr,smb_vwv16,2);
p2 = smb_buf(ptr);
- fstrcpy(p2,mailslot);
+ pstrcpy(p2,mailslot);
p2 = skip_string(p2,1);
memcpy(p2,buf,len);
@@ -135,7 +140,7 @@ static char cli_backup_list[1024];
int cli_get_backup_list(const char *myname, const char *send_to_name)
{
- pstring outbuf;
+ char outbuf[15];
char *p;
struct in_addr sendto_ip, my_ip;
int dgram_sock;
@@ -262,3 +267,6 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam
return True;
}
+
+
+
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index b75d6be0a60..867b13fe8cb 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB client generic functions
Copyright (C) Andrew Tridgell 1994-1998
@@ -23,17 +24,6 @@
#include "includes.h"
/****************************************************************************
- Change the timeout (in milliseconds).
-****************************************************************************/
-
-unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout)
-{
- unsigned int old_timeout = cli->timeout;
- cli->timeout = timeout;
- return old_timeout;
-}
-
-/****************************************************************************
Change the port number used to call on.
****************************************************************************/
@@ -44,38 +34,6 @@ int cli_set_port(struct cli_state *cli, int port)
}
/****************************************************************************
- Read an smb from a fd ignoring all keepalive packets. Note that the buffer
- *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
- The timeout is in milliseconds
-
- This is exactly the same as receive_smb except that it never returns
- a session keepalive packet (just as receive_smb used to do).
- receive_smb was changed to return keepalives as the oplock processing means this call
- should never go into a blocking read.
-****************************************************************************/
-
-static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
-{
- BOOL ret;
-
- for(;;) {
- ret = receive_smb_raw(fd, buffer, timeout);
-
- if (!ret) {
- DEBUG(10,("client_receive_smb failed\n"));
- show_msg(buffer);
- return ret;
- }
-
- /* Ignore session keepalive packets. */
- if(CVAL(buffer,0) != SMBkeepalive)
- break;
- }
- show_msg(buffer);
- return ret;
-}
-
-/****************************************************************************
Recv an smb.
****************************************************************************/
@@ -89,7 +47,7 @@ BOOL cli_receive_smb(struct cli_state *cli)
return False;
again:
- ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+ ret = client_receive_smb(cli->fd,cli->inbuf,abs(cli->timeout));
if (ret) {
/* it might be an oplock break request */
@@ -108,23 +66,14 @@ BOOL cli_receive_smb(struct cli_state *cli)
}
}
- /* If the server is not responding, note that now */
-
+ /* If the server is not responding, note that now */
if (!ret) {
cli->smb_rw_error = smb_read_error;
close(cli->fd);
cli->fd = -1;
- return ret;
}
- if (!cli_check_sign_mac(cli, True)) {
- DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
- cli->smb_rw_error = READ_BAD_SIG;
- close(cli->fd);
- cli->fd = -1;
- return False;
- };
- return True;
+ return ret;
}
/****************************************************************************
@@ -141,26 +90,21 @@ BOOL cli_send_smb(struct cli_state *cli)
if (cli->fd == -1)
return False;
- cli_calculate_sign_mac(cli);
-
len = smb_len(cli->outbuf) + 4;
while (nwritten < len) {
ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
if (ret <= 0) {
- close(cli->fd);
- cli->fd = -1;
+ close(cli->fd);
+ cli->fd = -1;
cli->smb_rw_error = WRITE_ERROR;
DEBUG(0,("Error writing %d bytes to client. %d (%s)\n",
- (int)len,(int)ret, strerror(errno) ));
+ (int)len,(int)ret, strerror(errno) ));
return False;
}
nwritten += ret;
}
- /* Increment the mid so we can tell between responses. */
- cli->mid++;
- if (!cli->mid)
- cli->mid++;
+
return True;
}
@@ -170,7 +114,7 @@ BOOL cli_send_smb(struct cli_state *cli)
void cli_setup_packet(struct cli_state *cli)
{
- cli->rap_error = 0;
+ cli->rap_error = 0;
SSVAL(cli->outbuf,smb_pid,cli->pid);
SSVAL(cli->outbuf,smb_uid,cli->vuid);
SSVAL(cli->outbuf,smb_mid,cli->mid);
@@ -178,12 +122,12 @@ void cli_setup_packet(struct cli_state *cli)
uint16 flags2;
SCVAL(cli->outbuf,smb_flg,0x8);
flags2 = FLAGS2_LONG_PATH_COMPONENTS;
- if (cli->capabilities & CAP_UNICODE)
+ if (cli->capabilities & CAP_UNICODE) {
flags2 |= FLAGS2_UNICODE_STRINGS;
- if (cli->capabilities & CAP_STATUS32)
+ }
+ if (cli->capabilities & CAP_STATUS32) {
flags2 |= FLAGS2_32_BIT_ERROR_CODES;
- if (cli->use_spnego)
- flags2 |= FLAGS2_EXTENDED_SECURITY;
+ }
SSVAL(cli->outbuf,smb_flg2, flags2);
}
}
@@ -198,39 +142,21 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
}
/****************************************************************************
- Initialise credentials of a client structure.
+ Initialise a client structure.
****************************************************************************/
void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
{
/* copy_nt_creds(&cli->usr, usr); */
- fstrcpy(cli->domain , usr->domain);
- fstrcpy(cli->user_name, usr->user_name);
+ safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1);
+ safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1);
memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd));
+ cli->ntlmssp_flags = usr->ntlmssp_flags;
+ cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0;
- DEBUG(10,("cli_init_creds: user %s domain %s\n",
- cli->user_name, cli->domain));
-}
-
-/****************************************************************************
- Set the signing state (used from the command line).
-****************************************************************************/
-
-void cli_setup_signing_state(struct cli_state *cli, int signing_state)
-{
- if (signing_state == Undefined)
- return;
-
- if (signing_state == False) {
- cli->sign_info.allow_smb_signing = False;
- cli->sign_info.mandatory_signing = False;
- return;
- }
-
- cli->sign_info.allow_smb_signing = True;
-
- if (signing_state == Required)
- cli->sign_info.mandatory_signing = True;
+ DEBUG(10,("cli_init_creds: user %s domain %s flgs: %x\nntlmssp_cli_flgs:%x\n",
+ cli->user_name, cli->domain,
+ cli->ntlmssp_flags,cli->ntlmssp_cli_flgs));
}
/****************************************************************************
@@ -270,53 +196,29 @@ struct cli_state *cli_initialise(struct cli_state *cli)
cli->timeout = 20000; /* Timeout is in milliseconds. */
cli->bufsize = CLI_BUFFER_SIZE+4;
cli->max_xmit = cli->bufsize;
- cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN);
- cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN);
+ cli->outbuf = (char *)malloc(cli->bufsize);
+ cli->inbuf = (char *)malloc(cli->bufsize);
cli->oplock_handler = cli_oplock_ack;
-
- cli->use_spnego = lp_client_use_spnego();
-
- cli->capabilities = CAP_UNICODE | CAP_STATUS32;
-
/* Set the CLI_FORCE_DOSERR environment variable to test
client routines using DOS errors instead of STATUS32
ones. This intended only as a temporary hack. */
if (getenv("CLI_FORCE_DOSERR"))
cli->force_dos_errors = True;
- if (lp_client_signing())
- cli->sign_info.allow_smb_signing = True;
-
- if (lp_client_signing() == Required)
- cli->sign_info.mandatory_signing = True;
-
if (!cli->outbuf || !cli->inbuf)
goto error;
- if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL)
+ if ((cli->mem_ctx = talloc_init()) == NULL)
goto error;
memset(cli->outbuf, 0, cli->bufsize);
memset(cli->inbuf, 0, cli->bufsize);
-
-#if defined(DEVELOPER)
- /* just because we over-allocate, doesn't mean it's right to use it */
- clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);
- clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);
-#endif
-
- /* initialise signing */
- cli_null_set_signing(cli);
-
cli->nt_pipe_fnum = 0;
- cli->saved_netlogon_pipe_fnum = 0;
cli->initialised = 1;
cli->allocated = alloced_cli;
- cli->pipe_idx = -1;
-
return cli;
/* Clean up after malloc() error */
@@ -333,78 +235,27 @@ struct cli_state *cli_initialise(struct cli_state *cli)
}
/****************************************************************************
-close the session
-****************************************************************************/
-
-void cli_nt_session_close(struct cli_state *cli)
-{
- if (cli->ntlmssp_pipe_state) {
- ntlmssp_end(&cli->ntlmssp_pipe_state);
- }
-
- if (cli->nt_pipe_fnum != 0)
- cli_close(cli, cli->nt_pipe_fnum);
-
- cli->nt_pipe_fnum = 0;
- cli->pipe_idx = -1;
-}
-
-/****************************************************************************
-close the NETLOGON session holding the session key for NETSEC
-****************************************************************************/
-
-void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
-{
- if (cli->saved_netlogon_pipe_fnum != 0) {
- cli_close(cli, cli->saved_netlogon_pipe_fnum);
- cli->saved_netlogon_pipe_fnum = 0;
- }
-}
-
-/****************************************************************************
Close a client connection and free the memory without destroying cli itself.
****************************************************************************/
void cli_close_connection(struct cli_state *cli)
{
- cli_nt_session_close(cli);
- cli_nt_netlogon_netsec_session_close(cli);
-
- /*
- * tell our peer to free his resources. Wihtout this, when an
- * application attempts to do a graceful shutdown and calls
- * smbc_free_context() to clean up all connections, some connections
- * can remain active on the peer end, until some (long) timeout period
- * later. This tree disconnect forces the peer to clean up, since the
- * connection will be going away.
- *
- * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS
- * the only user for this so far is smbmount which passes opened connection
- * down to kernel's smbfs module.
- */
- if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) )
- cli_tdis(cli);
-
SAFE_FREE(cli->outbuf);
SAFE_FREE(cli->inbuf);
- cli_free_signing_context(cli);
- data_blob_free(&cli->secblob);
- data_blob_free(&cli->user_session_key);
-
- if (cli->ntlmssp_pipe_state)
- ntlmssp_end(&cli->ntlmssp_pipe_state);
-
if (cli->mem_ctx) {
talloc_destroy(cli->mem_ctx);
cli->mem_ctx = NULL;
}
+#ifdef WITH_SSL
+ if (cli->fd != -1)
+ sslutil_disconnect(cli->fd);
+#endif /* WITH_SSL */
if (cli->fd != -1)
close(cli->fd);
cli->fd = -1;
cli->smb_rw_error = 0;
-
}
/****************************************************************************
@@ -417,14 +268,14 @@ void cli_shutdown(struct cli_state *cli)
cli_close_connection(cli);
ZERO_STRUCTP(cli);
if (allocated)
- free(cli);
+ SAFE_FREE(cli);
}
/****************************************************************************
Set socket options on a open connection.
****************************************************************************/
-void cli_sockopt(struct cli_state *cli, const char *options)
+void cli_sockopt(struct cli_state *cli, char *options)
{
set_socket_options(cli->fd, options);
}
@@ -441,8 +292,9 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid)
}
/****************************************************************************
-Send a keepalive packet to the server
+ Send a keepalive packet to the server.
****************************************************************************/
+
BOOL cli_send_keepalive(struct cli_state *cli)
{
if (cli->fd == -1) {
@@ -452,7 +304,8 @@ BOOL cli_send_keepalive(struct cli_state *cli)
if (!send_keepalive(cli->fd)) {
close(cli->fd);
cli->fd = -1;
- DEBUG(0,("Error sending keepalive packet to client.\n"));
+ DEBUG(0,("Error sending keepalive packet to client. (%s)\n",
+ strerror(errno) ));
return False;
}
return True;
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index c27e1955e20..a01f74d2914 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client error handling routines
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Jelmer Vernooij 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,39 +25,34 @@
/*****************************************************
RAP error codes - a small start but will be extended.
-
- XXX: Perhaps these should move into a common function because they're
- duplicated in clirap2.c
-
*******************************************************/
static const struct
{
- int err;
- const char *message;
-} rap_errmap[] =
-{
- {5, "RAP5: User has insufficient privilege" },
- {50, "RAP50: Not supported by server" },
- {65, "RAP65: Access denied" },
- {86, "RAP86: The specified password is invalid" },
- {2220, "RAP2220: Group does not exist" },
- {2221, "RAP2221: User does not exist" },
- {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" },
- {2237, "RAP2237: User is not in group" },
- {2242, "RAP2242: The password of this user has expired." },
- {2243, "RAP2243: The password of this user cannot change." },
- {2244, "RAP2244: This password cannot be used now (password history conflict)." },
- {2245, "RAP2245: The password is shorter than required." },
- {2246, "RAP2246: The password of this user is too recent to change."},
-
- /* these really shouldn't be here ... */
- {0x80, "Not listening on called name"},
- {0x81, "Not listening for calling name"},
- {0x82, "Called name not present"},
- {0x83, "Called name present, but insufficient resources"},
-
- {0, NULL}
+ int err;
+ const char *message;
+} rap_errmap[] = {
+ {5, "RAP5: User has insufficient privilege" },
+ {50, "RAP50: Not supported by server" },
+ {65, "RAP65: Access denied" },
+ {86, "RAP86: The specified password is invalid" },
+ {2220, "RAP2220: Group does not exist" },
+ {2221, "RAP2221: User does not exist" },
+ {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" },
+ {2237, "RAP2237: User is not in group" },
+ {2242, "RAP2242: The password of this user has expired." },
+ {2243, "RAP2243: The password of this user cannot change." },
+ {2244, "RAP2244: This password cannot be used now (password history conflict)." },
+ {2245, "RAP2245: The password is shorter than required." },
+ {2246, "RAP2246: The password of this user is too recent to change."},
+
+ /* these really shouldn't be here ... */
+ {0x80, "Not listening on called name"},
+ {0x81, "Not listening for calling name"},
+ {0x82, "Called name not present"},
+ {0x83, "Called name present, but insufficient resources"},
+
+ {0, NULL}
};
/****************************************************************************
@@ -78,39 +73,35 @@ const char *cli_errstr(struct cli_state *cli)
{
static fstring cli_error_message;
uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum;
- uint8 errclass;
- int i;
-
+ uint8 errclass;
+ int i;
+
if (!cli->initialised) {
fstrcpy(cli_error_message, "[Programmer's error] cli_errstr called on unitialized cli_stat struct!\n");
return cli_error_message;
}
-
+
/* Was it server socket error ? */
if (cli->fd == -1 && cli->smb_rw_error) {
switch(cli->smb_rw_error) {
case READ_TIMEOUT:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Call timed out: server did not respond after %d milliseconds",
+ "Call timed out: server did not respond after %d milliseconds",
cli->timeout);
break;
case READ_EOF:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Call returned zero bytes (EOF)" );
+ "Call returned zero bytes (EOF)\n" );
break;
case READ_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Read error: %s", strerror(errno) );
+ "Read error: %s\n", strerror(errno) );
break;
case WRITE_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Write error: %s", strerror(errno) );
+ "Write error: %s\n", strerror(errno) );
break;
- case READ_BAD_SIG:
- slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Server packet had invalid SMB signature!");
- break;
- default:
+ default:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Unknown error code %d\n", cli->smb_rw_error );
break;
@@ -118,30 +109,30 @@ const char *cli_errstr(struct cli_state *cli)
return cli_error_message;
}
- /* Case #1: RAP error */
+ /* Case #1: RAP error */
if (cli->rap_error) {
for (i = 0; rap_errmap[i].message != NULL; i++) {
if (rap_errmap[i].err == cli->rap_error) {
return rap_errmap[i].message;
}
- }
+ }
- slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d",
+ slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d",
cli->rap_error);
return cli_error_message;
}
- /* Case #2: 32-bit NT errors */
+ /* Case #2: 32-bit NT errors */
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
- NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls));
+ NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls));
- return nt_errstr(status);
+ return get_nt_error_msg(status);
}
- cli_dos_error(cli, &errclass, &errnum);
+ cli_dos_error(cli, &errclass, &errnum);
- /* Case #3: SMB error */
+ /* Case #3: SMB error */
return cli_smb_errstr(cli);
}
@@ -189,7 +180,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)
/* Return a UNIX errno from a dos error class, error number tuple */
-static int cli_errno_from_dos(uint8 eclass, uint32 num)
+int cli_errno_from_dos(uint8 eclass, uint32 num)
{
if (eclass == ERRDOS) {
switch (num) {
@@ -225,108 +216,20 @@ static struct {
int error;
} nt_errno_map[] = {
{NT_STATUS_ACCESS_VIOLATION, EACCES},
+ {NT_STATUS_NO_SUCH_FILE, ENOENT},
+ {NT_STATUS_NO_SUCH_DEVICE, ENODEV},
{NT_STATUS_INVALID_HANDLE, EBADF},
+ {NT_STATUS_NO_MEMORY, ENOMEM},
{NT_STATUS_ACCESS_DENIED, EACCES},
{NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT},
{NT_STATUS_SHARING_VIOLATION, EBUSY},
{NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR},
{NT_STATUS_OBJECT_NAME_COLLISION, EEXIST},
{NT_STATUS_PATH_NOT_COVERED, ENOENT},
- {NT_STATUS_UNSUCCESSFUL, EINVAL},
- {NT_STATUS_NOT_IMPLEMENTED, ENOSYS},
- {NT_STATUS_IN_PAGE_ERROR, EFAULT},
- {NT_STATUS_BAD_NETWORK_NAME, ENOENT},
-#ifdef EDQUOT
- {NT_STATUS_PAGEFILE_QUOTA, EDQUOT},
- {NT_STATUS_QUOTA_EXCEEDED, EDQUOT},
- {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT},
- {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT},
-#endif
-#ifdef ETIME
- {NT_STATUS_TIMER_NOT_CANCELED, ETIME},
-#endif
- {NT_STATUS_INVALID_PARAMETER, EINVAL},
- {NT_STATUS_NO_SUCH_DEVICE, ENODEV},
- {NT_STATUS_NO_SUCH_FILE, ENOENT},
-#ifdef ENODATA
- {NT_STATUS_END_OF_FILE, ENODATA},
-#endif
-#ifdef ENOMEDIUM
- {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM},
- {NT_STATUS_NO_MEDIA, ENOMEDIUM},
-#endif
- {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE},
- {NT_STATUS_NO_MEMORY, ENOMEM},
- {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE},
- {NT_STATUS_NOT_MAPPED_VIEW, EINVAL},
- {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE},
- {NT_STATUS_ACCESS_DENIED, EACCES},
- {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS},
- {NT_STATUS_WRONG_PASSWORD, EACCES},
- {NT_STATUS_LOGON_FAILURE, EACCES},
- {NT_STATUS_INVALID_WORKSTATION, EACCES},
- {NT_STATUS_INVALID_LOGON_HOURS, EACCES},
- {NT_STATUS_PASSWORD_EXPIRED, EACCES},
- {NT_STATUS_ACCOUNT_DISABLED, EACCES},
- {NT_STATUS_DISK_FULL, ENOSPC},
- {NT_STATUS_INVALID_PIPE_STATE, EPIPE},
- {NT_STATUS_PIPE_BUSY, EPIPE},
- {NT_STATUS_PIPE_DISCONNECTED, EPIPE},
- {NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS},
- {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR},
- {NT_STATUS_NOT_SUPPORTED, ENOSYS},
- {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR},
- {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY},
- {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH},
- {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH},
- {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED},
- {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED},
- {NT_STATUS_TOO_MANY_LINKS, EMLINK},
- {NT_STATUS_NETWORK_BUSY, EBUSY},
- {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV},
-#ifdef ELIBACC
- {NT_STATUS_DLL_NOT_FOUND, ELIBACC},
-#endif
- {NT_STATUS_PIPE_BROKEN, EPIPE},
- {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED},
- {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES},
- {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE},
-#ifdef EPROTO
- {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO},
-#endif
- {NT_STATUS_FLOAT_OVERFLOW, ERANGE},
- {NT_STATUS_FLOAT_UNDERFLOW, ERANGE},
- {NT_STATUS_INTEGER_OVERFLOW, ERANGE},
- {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS},
- {NT_STATUS_PIPE_CONNECTED, EISCONN},
- {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT},
- {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE},
- {NT_STATUS_ILL_FORMED_PASSWORD, EACCES},
- {NT_STATUS_PASSWORD_RESTRICTION, EACCES},
- {NT_STATUS_ACCOUNT_RESTRICTION, EACCES},
- {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED},
- {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG},
- {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN},
- {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED},
- {NT_STATUS_CONNECTION_RESET, ENETRESET},
-#ifdef ENOTUNIQ
- {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ},
- {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ},
-#endif
- {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE},
- {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT},
- {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE},
- {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH},
- {NT_STATUS_IO_TIMEOUT, ETIMEDOUT},
- {NT_STATUS_RETRY, EAGAIN},
-#ifdef ECOMM
- {NT_STATUS_NET_WRITE_FAULT, ECOMM},
-#endif
-
{NT_STATUS(0), 0}
};
-static int cli_errno_from_nt(NTSTATUS status)
+int cli_errno_from_nt(NTSTATUS status)
{
int i;
DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status)));
@@ -371,9 +274,6 @@ BOOL cli_is_error(struct cli_state *cli)
{
uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0;
- if (cli->fd == -1 && cli->smb_rw_error != 0)
- return True;
-
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
/* Return error is error bits are set */
rcls = IVAL(cli->inbuf, smb_rcls);
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index 398c7cc4f0a..f74758b4f02 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client file operations
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Jeremy Allison 2001-2002
@@ -25,10 +26,9 @@
/****************************************************************************
Hard/Symlink a file (UNIX extensions).
- Creates new name (sym)linked to oldname.
****************************************************************************/
-static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link)
+static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
@@ -37,18 +37,16 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const
pstring data;
char *rparam=NULL, *rdata=NULL;
char *p;
- size_t oldlen = 2*(strlen(oldname)+1);
- size_t newlen = 2*(strlen(newname)+1);
memset(param, 0, sizeof(param));
SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
p = &param[6];
- p += clistr_push(cli, p, newname, MIN(newlen, sizeof(param)-6), STR_TERMINATE);
+ p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE|STR_CONVERT);
param_len = PTR_DIFF(p, param);
p = data;
- p += clistr_push(cli, p, oldname, MIN(oldlen,sizeof(data)), STR_TERMINATE);
+ p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE|STR_CONVERT);
data_len = PTR_DIFF(p, data);
if (!cli_send_trans(cli, SMBtrans2,
@@ -79,7 +77,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const
uint32 unix_perms_to_wire(mode_t perms)
{
- unsigned int ret = 0;
+ uint32 ret = 0;
ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
@@ -106,18 +104,18 @@ uint32 unix_perms_to_wire(mode_t perms)
Symlink a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname)
+BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
{
- return cli_link_internal(cli, oldname, newname, False);
+ return cli_link_internal(cli, fname_src, fname_dst, False);
}
/****************************************************************************
Hard a file (UNIX extensions).
****************************************************************************/
-BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname)
+BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
{
- return cli_link_internal(cli, oldname, newname, True);
+ return cli_link_internal(cli, fname_src, fname_dst, True);
}
/****************************************************************************
@@ -139,7 +137,7 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna
SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC);
p = &param[6];
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE|STR_CONVERT);
param_len = PTR_DIFF(p, param);
SIVAL(data,40,uid);
@@ -210,85 +208,9 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE|STR_CONVERT);
*p++ = 4;
- p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
-
- cli_setup_bcc(cli, p);
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
-
- if (cli_is_error(cli))
- return False;
-
- return True;
-}
-
-/****************************************************************************
- NT Rename a file.
-****************************************************************************/
-
-BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
-{
- char *p;
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf, 4, 0, True);
-
- SCVAL(cli->outbuf,smb_com,SMBntrename);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
- SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_RENAME);
-
- p = smb_buf(cli->outbuf);
- *p++ = 4;
- p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
- *p++ = 4;
- p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
-
- cli_setup_bcc(cli, p);
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
-
- if (cli_is_error(cli))
- return False;
-
- return True;
-}
-
-/****************************************************************************
- NT hardlink a file.
-****************************************************************************/
-
-BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
-{
- char *p;
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf, 4, 0, True);
-
- SCVAL(cli->outbuf,smb_com,SMBntrename);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
- SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_HARD_LINK);
-
- p = smb_buf(cli->outbuf);
- *p++ = 4;
- p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
- *p++ = 4;
- p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -323,7 +245,7 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
@@ -357,7 +279,7 @@ BOOL cli_mkdir(struct cli_state *cli, const char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -392,7 +314,7 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -428,19 +350,19 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
data = flag ? 1 : 0;
if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- (char *)&data, data_len, cli->max_xmit /* data, length, max */
- )) {
- return False;
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
}
if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return False;
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
}
SAFE_FREE(rdata);
@@ -454,11 +376,9 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
Used in smbtorture.
****************************************************************************/
-int cli_nt_create_full(struct cli_state *cli, const char *fname,
- uint32 CreatFlags, uint32 DesiredAccess,
+int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess,
uint32 FileAttributes, uint32 ShareAccess,
- uint32 CreateDisposition, uint32 CreateOptions,
- uint8 SecuityFlags)
+ uint32 CreateDisposition, uint32 CreateOptions)
{
char *p;
int len;
@@ -474,9 +394,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
SSVAL(cli->outbuf,smb_vwv0,0xFF);
if (cli->use_oplocks)
- CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
-
- SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags);
+ SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
+ else
+ SIVAL(cli->outbuf,smb_ntcreate_Flags, 0);
SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);
SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess);
SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes);
@@ -484,7 +404,6 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition);
SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions);
SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02);
- SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags);
p = smb_buf(cli->outbuf);
/* this alignment and termination is critical for netapp filers. Don't change */
@@ -493,7 +412,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
p += len;
SSVAL(cli->outbuf,smb_ntcreate_NameLength, len);
/* sigh. this copes with broken netapp filer behaviour */
- p += clistr_push(cli, p, "", -1, STR_TERMINATE);
+ p += clistr_push(cli, p, "", -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -515,8 +434,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)
{
- return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0);
+ return cli_nt_create_full(cli, fname, DesiredAccess, 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0);
}
/****************************************************************************
@@ -582,7 +501,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode
}
p = smb_buf(cli->outbuf);
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -624,12 +543,11 @@ BOOL cli_close(struct cli_state *cli, int fnum)
return !cli_is_error(cli);
}
-
/****************************************************************************
- send a lock with a specified locktype
+ send a lock with a specified locktype
this is used for testing LOCKING_ANDX_CANCEL_LOCK
****************************************************************************/
-NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
+NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
uint32 offset, uint32 len, int timeout, unsigned char locktype)
{
char *p;
@@ -676,11 +594,10 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
return cli_nt_error(cli);
}
-
/****************************************************************************
Lock a file.
- note that timeout is in units of 2 milliseconds
****************************************************************************/
+
BOOL cli_lock(struct cli_state *cli, int fnum,
uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
{
@@ -714,8 +631,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
cli_send_smb(cli);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
if (timeout != 0) {
- cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
}
if (!cli_receive_smb(cli)) {
@@ -817,6 +735,8 @@ BOOL cli_lock64(struct cli_state *cli, int fnum,
cli_setup_bcc(cli, p);
cli_send_smb(cli);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
+
if (timeout != 0) {
cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000);
}
@@ -881,9 +801,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
return True;
}
-
/****************************************************************************
- Do a SMBgetattrE call.
+ Do a SMBgetattrE call. The size is 32 bits.
****************************************************************************/
BOOL cli_getattrE(struct cli_state *cli, int fd,
@@ -953,7 +872,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname,
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -1004,7 +923,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE|STR_CONVERT);
*p++ = 4;
cli_setup_bcc(cli, p);
@@ -1024,15 +943,15 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
/****************************************************************************
Check for existance of a dir.
****************************************************************************/
+
BOOL cli_chkpath(struct cli_state *cli, const char *path)
{
pstring path2;
char *p;
- pstrcpy(path2,path);
- trim_char(path2,'\0','\\');
- if (!*path2)
- *path2 = '\\';
+ safe_strcpy(path2,path,sizeof(pstring));
+ trim_string(path2,NULL,"\\");
+ if (!*path2) *path2 = '\\';
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
@@ -1041,7 +960,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path)
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, path2, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, path2, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -1102,7 +1021,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, path, -1, STR_TERMINATE);
+ p += clistr_push(cli, p, path, -1, STR_TERMINATE|STR_CONVERT);
cli_setup_bcc(cli, p);
@@ -1131,288 +1050,3 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
return SVAL(cli->inbuf,smb_vwv0);
}
-
-
-/*
- send a raw ioctl - used by the torture code
-*/
-NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob)
-{
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf, 3, 0, True);
- SCVAL(cli->outbuf,smb_com,SMBioctl);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf, smb_vwv0, fnum);
- SSVAL(cli->outbuf, smb_vwv1, code>>16);
- SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF));
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- }
-
- if (cli_is_error(cli)) {
- return cli_nt_error(cli);
- }
-
- *blob = data_blob(NULL, 0);
-
- return NT_STATUS_OK;
-}
-
-/*********************************************************
- Set an extended attribute utility fn.
-*********************************************************/
-
-static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len,
- const char *ea_name, const char *ea_val, size_t ea_len)
-{
- unsigned int data_len = 0;
- char *data = NULL;
- char *rparam=NULL, *rdata=NULL;
- char *p;
- size_t ea_namelen = strlen(ea_name);
-
- data_len = 4 + 4 + ea_namelen + 1 + ea_len;
- data = malloc(data_len);
- if (!data) {
- return False;
- }
- p = data;
- SIVAL(p,0,data_len);
- p += 4;
- SCVAL(p, 0, 0); /* EA flags. */
- SCVAL(p, 1, ea_namelen);
- SSVAL(p, 2, ea_len);
- memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */
- memcpy(p+4+ea_namelen+1, ea_val, ea_len);
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- data, data_len, cli->max_xmit /* data, length, max */
- )) {
- return False;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return False;
- }
-
- SAFE_FREE(data);
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
-
- return True;
-}
-
-/*********************************************************
- Set an extended attribute on a pathname.
-*********************************************************/
-
-BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
-{
- uint16 setup = TRANSACT2_SETPATHINFO;
- unsigned int param_len = 0;
- char param[sizeof(pstring)+6];
- size_t srclen = 2*(strlen(path)+1);
- char *p;
-
- memset(param, 0, sizeof(param));
- SSVAL(param,0,SMB_INFO_SET_EA);
- p = &param[6];
-
- p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
-
- return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len);
-}
-
-/*********************************************************
- Set an extended attribute on an fnum.
-*********************************************************/
-
-BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len)
-{
- char param[6];
- uint16 setup = TRANSACT2_SETFILEINFO;
-
- memset(param, 0, 6);
- SSVAL(param,0,fnum);
- SSVAL(param,2,SMB_INFO_SET_EA);
-
- return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len);
-}
-
-/*********************************************************
- Get an extended attribute list tility fn.
-*********************************************************/
-
-static BOOL cli_get_ea_list(struct cli_state *cli,
- uint16 setup, char *param, unsigned int param_len,
- TALLOC_CTX *ctx,
- size_t *pnum_eas,
- struct ea_struct **pea_list)
-{
- unsigned int data_len = 0;
- unsigned int rparam_len, rdata_len;
- char *rparam=NULL, *rdata=NULL;
- char *p;
- size_t ea_size;
- size_t num_eas;
- BOOL ret = False;
- struct ea_struct *ea_list;
-
- *pnum_eas = 0;
- *pea_list = NULL;
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* Name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 10, /* param, length, max */
- NULL, data_len, cli->max_xmit /* data, length, max */
- )) {
- return False;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_len,
- &rdata, &rdata_len)) {
- return False;
- }
-
- if (!rdata || rdata_len < 4) {
- goto out;
- }
-
- ea_size = (size_t)IVAL(rdata,0);
- if (ea_size > rdata_len) {
- goto out;
- }
-
- if (ea_size == 0) {
- /* No EA's present. */
- ret = True;
- goto out;
- }
-
- p = rdata + 4;
- ea_size -= 4;
-
- /* Validate the EA list and count it. */
- for (num_eas = 0; ea_size >= 4; num_eas++) {
- unsigned int ea_namelen = CVAL(p,1);
- unsigned int ea_valuelen = SVAL(p,2);
- if (ea_namelen == 0) {
- goto out;
- }
- if (4 + ea_namelen + 1 + ea_valuelen > ea_size) {
- goto out;
- }
- ea_size -= 4 + ea_namelen + 1 + ea_valuelen;
- p += 4 + ea_namelen + 1 + ea_valuelen;
- }
-
- if (num_eas == 0) {
- ret = True;
- goto out;
- }
-
- *pnum_eas = num_eas;
- if (!pea_list) {
- /* Caller only wants number of EA's. */
- ret = True;
- goto out;
- }
-
- ea_list = (struct ea_struct *)talloc(ctx, num_eas*sizeof(struct ea_struct));
- if (!ea_list) {
- goto out;
- }
-
- ea_size = (size_t)IVAL(rdata,0);
- p = rdata + 4;
-
- for (num_eas = 0; num_eas < *pnum_eas; num_eas++ ) {
- struct ea_struct *ea = &ea_list[num_eas];
- fstring unix_ea_name;
- unsigned int ea_namelen = CVAL(p,1);
- unsigned int ea_valuelen = SVAL(p,2);
-
- ea->flags = CVAL(p,0);
- unix_ea_name[0] = '\0';
- pull_ascii_fstring(unix_ea_name, p + 4);
- ea->name = talloc_strdup(ctx, unix_ea_name);
- /* Ensure the value is null terminated (in case it's a string). */
- ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1);
- if (!ea->value.data) {
- goto out;
- }
- if (ea_valuelen) {
- memcpy(ea->value.data, p+4+ea_namelen+1, ea_valuelen);
- }
- ea->value.data[ea_valuelen] = 0;
- ea->value.length--;
- p += 4 + ea_namelen + 1 + ea_valuelen;
- }
-
- *pea_list = ea_list;
- ret = True;
-
- out :
-
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return ret;
-}
-
-/*********************************************************
- Get an extended attribute list from a pathname.
-*********************************************************/
-
-BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path,
- TALLOC_CTX *ctx,
- size_t *pnum_eas,
- struct ea_struct **pea_list)
-{
- uint16 setup = TRANSACT2_QPATHINFO;
- unsigned int param_len = 0;
- char param[sizeof(pstring)+6];
- char *p;
-
- p = param;
- memset(p, 0, 6);
- SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS);
- p += 6;
- p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
-
- return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list);
-}
-
-/*********************************************************
- Get an extended attribute list from an fnum.
-*********************************************************/
-
-BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum,
- TALLOC_CTX *ctx,
- size_t *pnum_eas,
- struct ea_struct **pea_list)
-{
- uint16 setup = TRANSACT2_QFILEINFO;
- char param[6];
-
- memset(param, 0, 6);
- SSVAL(param,0,fnum);
- SSVAL(param,2,SMB_INFO_SET_EA);
-
- return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list);
-}
diff --git a/source/libsmb/clifsinfo.c b/source/libsmb/clifsinfo.c
deleted file mode 100644
index 00fe189e9a9..00000000000
--- a/source/libsmb/clifsinfo.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- FS info functions
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-
-BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr)
-{
- BOOL ret = False;
- uint16 setup;
- char param[2];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
-
- if (!cli||!fs_attr)
- smb_panic("cli_get_fs_attr_info() called with NULL Pionter!");
-
- setup = TRANSACT2_QFSINFO;
-
- SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO);
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL,
- 0, 0,
- &setup, 1, 0,
- param, 2, 0,
- NULL, 0, 560)) {
- goto cleanup;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- if (rdata_count < 12) {
- goto cleanup;
- }
-
- *fs_attr = IVAL(rdata,0);
-
- /* todo: but not yet needed
- * return the other stuff
- */
-
-cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return ret;
-}
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
deleted file mode 100644
index 81797a7bfc0..00000000000
--- a/source/libsmb/clikrb5.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- simple kerberos5 routines for active directory
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Luke Howard 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#ifdef HAVE_KRB5
-
-#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE
-#define KRB5_KEY_TYPE(k) ((k)->keytype)
-#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length)
-#define KRB5_KEY_DATA(k) ((k)->keyvalue.data)
-#else
-#define KRB5_KEY_TYPE(k) ((k)->enctype)
-#define KRB5_KEY_LENGTH(k) ((k)->length)
-#define KRB5_KEY_DATA(k) ((k)->contents)
-#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
-
-#ifndef HAVE_KRB5_SET_REAL_TIME
-/*
- * This function is not in the Heimdal mainline.
- */
- krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds)
-{
- krb5_error_code ret;
- int32_t sec, usec;
-
- ret = krb5_us_timeofday(context, &sec, &usec);
- if (ret)
- return ret;
-
- context->kdc_sec_offset = seconds - sec;
- context->kdc_usec_offset = microseconds - usec;
-
- return 0;
-}
-#endif
-
-#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES)
- krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc)
-{
- return krb5_set_default_in_tkt_etypes(ctx, enc);
-}
-#endif
-
-#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS)
-/* HEIMDAL */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
-{
- pkaddr->addr_type = KRB5_ADDRESS_INET;
- pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
- pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr);
-}
-#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS)
-/* MIT */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
-{
- pkaddr->addrtype = ADDRTYPE_INET;
- pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
- pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr);
-}
-#else
- __ERROR__XX__UNKNOWN_ADDRTYPE
-#endif
-
-#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY)
- int create_kerberos_key_from_string(krb5_context context,
- krb5_principal host_princ,
- krb5_data *password,
- krb5_keyblock *key,
- krb5_enctype enctype)
-{
- int ret;
- krb5_data salt;
- krb5_encrypt_block eblock;
-
- ret = krb5_principal2salt(context, host_princ, &salt);
- if (ret) {
- DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
- return ret;
- }
- krb5_use_enctype(context, &eblock, enctype);
- ret = krb5_string_to_key(context, &eblock, key, password, &salt);
- SAFE_FREE(salt.data);
- return ret;
-}
-#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
- int create_kerberos_key_from_string(krb5_context context,
- krb5_principal host_princ,
- krb5_data *password,
- krb5_keyblock *key,
- krb5_enctype enctype)
-{
- int ret;
- krb5_salt salt;
-
- ret = krb5_get_pw_salt(context, host_princ, &salt);
- if (ret) {
- DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret)));
- return ret;
- }
- return krb5_string_to_key_salt(context, enctype, password->data,
- salt, key);
-}
-#else
- __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS
-#endif
-
-#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES)
-krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
- krb5_enctype **enctypes)
-{
- return krb5_get_permitted_enctypes(context, enctypes);
-}
-#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES)
-krb5_error_code get_kerberos_allowed_etypes(krb5_context context,
- krb5_enctype **enctypes)
-{
- return krb5_get_default_in_tkt_etypes(context, enctypes);
-}
-#else
-#error UNKNOWN_GET_ENCTYPES_FUNCTIONS
-#endif
-
- void free_kerberos_etypes(krb5_context context,
- krb5_enctype *enctypes)
-{
-#if defined(HAVE_KRB5_FREE_KTYPES)
- krb5_free_ktypes(context, enctypes);
- return;
-#else
- SAFE_FREE(enctypes);
- return;
-#endif
-}
-
-#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY)
- krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context,
- krb5_auth_context auth_context,
- krb5_keyblock *keyblock)
-{
- return krb5_auth_con_setkey(context, auth_context, keyblock);
-}
-#endif
-
- void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt)
-{
-#if defined(HAVE_KRB5_TKT_ENC_PART2)
- if (tkt->enc_part2)
- *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
- tkt->enc_part2->authorization_data[0]->length);
-#else
- if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len)
- *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data,
- tkt->ticket.authorization_data->val->ad_data.length);
-#endif
-}
-
- krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt)
-{
-#if defined(HAVE_KRB5_TKT_ENC_PART2)
- return tkt->enc_part2->client;
-#else
- return tkt->client;
-#endif
-}
-
-#if !defined(HAVE_KRB5_LOCATE_KDC)
- krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters)
-{
- krb5_krbhst_handle hnd;
- krb5_krbhst_info *hinfo;
- krb5_error_code rc;
- int num_kdcs, i;
- struct sockaddr *sa;
-
- *addr_pp = NULL;
- *naddrs = 0;
-
- rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd);
- if (rc) {
- DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc)));
- return rc;
- }
-
- for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++)
- ;
-
- krb5_krbhst_reset(ctx, hnd);
-
- if (!num_kdcs) {
- DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n"));
- krb5_krbhst_free(ctx, hnd);
- return -1;
- }
-
- sa = malloc( sizeof(struct sockaddr) * num_kdcs );
- if (!sa) {
- DEBUG(0, ("krb5_locate_kdc: malloc failed\n"));
- krb5_krbhst_free(ctx, hnd);
- naddrs = 0;
- return -1;
- }
-
- memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs );
-
- for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) {
- if (hinfo->ai->ai_family == AF_INET)
- memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr));
- }
-
- krb5_krbhst_free(ctx, hnd);
-
- *naddrs = num_kdcs;
- *addr_pp = sa;
- return 0;
-}
-#endif
-
-static BOOL ads_cleanup_expired_creds(krb5_context context,
- krb5_ccache ccache,
- krb5_creds *credsp)
-{
- krb5_error_code retval;
-
- DEBUG(3, ("Ticket in ccache[%s] expiration %s\n",
- krb5_cc_default_name(context),
- http_timestring(credsp->times.endtime)));
-
- /* we will probably need new tickets if the current ones
- will expire within 10 seconds.
- */
- if (credsp->times.endtime >= (time(NULL) + 10))
- return False;
-
- /* heimdal won't remove creds from a file ccache, and
- perhaps we shouldn't anyway, since internally we
- use memory ccaches, and a FILE one probably means that
- we're using creds obtained outside of our exectuable
- */
- if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) {
- DEBUG(5, ("We do not remove creds from a FILE ccache\n"));
- return False;
- }
-
- retval = krb5_cc_remove_cred(context, ccache, 0, credsp);
- if (retval) {
- DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n",
- error_message(retval)));
- /* If we have an error in this, we want to display it,
- but continue as though we deleted it */
- }
- return True;
-}
-
-/*
- we can't use krb5_mk_req because w2k wants the service to be in a particular format
-*/
-static krb5_error_code ads_krb5_mk_req(krb5_context context,
- krb5_auth_context *auth_context,
- const krb5_flags ap_req_options,
- const char *principal,
- krb5_ccache ccache,
- krb5_data *outbuf)
-{
- krb5_error_code retval;
- krb5_principal server;
- krb5_creds * credsp;
- krb5_creds creds;
- krb5_data in_data;
- BOOL creds_ready = False;
-
- retval = krb5_parse_name(context, principal, &server);
- if (retval) {
- DEBUG(1,("Failed to parse principal %s\n", principal));
- return retval;
- }
-
- /* obtain ticket & session key */
- ZERO_STRUCT(creds);
- if ((retval = krb5_copy_principal(context, server, &creds.server))) {
- DEBUG(1,("krb5_copy_principal failed (%s)\n",
- error_message(retval)));
- goto cleanup_princ;
- }
-
- if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) {
- DEBUG(1,("krb5_cc_get_principal failed (%s)\n",
- error_message(retval)));
- goto cleanup_creds;
- }
-
- while(!creds_ready) {
- if ((retval = krb5_get_credentials(context, 0, ccache,
- &creds, &credsp))) {
- DEBUG(1,("krb5_get_credentials failed for %s (%s)\n",
- principal, error_message(retval)));
- goto cleanup_creds;
- }
-
- /* cope with ticket being in the future due to clock skew */
- if ((unsigned)credsp->times.starttime > time(NULL)) {
- time_t t = time(NULL);
- int time_offset =(unsigned)credsp->times.starttime-t;
- DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset));
- krb5_set_real_time(context, t + time_offset + 1, 0);
- }
-
- if (!ads_cleanup_expired_creds(context, ccache, credsp))
- creds_ready = True;
- }
-
- DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n",
- principal, krb5_cc_default_name(context),
- http_timestring((unsigned)credsp->times.endtime),
- (unsigned)credsp->times.endtime));
-
- in_data.length = 0;
- retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
- &in_data, credsp, outbuf);
- if (retval) {
- DEBUG(1,("krb5_mk_req_extended failed (%s)\n",
- error_message(retval)));
- }
-
- krb5_free_creds(context, credsp);
-
-cleanup_creds:
- krb5_free_cred_contents(context, &creds);
-
-cleanup_princ:
- krb5_free_principal(context, server);
-
- return retval;
-}
-
-/*
- get a kerberos5 ticket for the given service
-*/
-int cli_krb5_get_ticket(const char *principal, time_t time_offset,
- DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
-{
- krb5_error_code retval;
- krb5_data packet;
- krb5_ccache ccdef;
- krb5_context context;
- krb5_auth_context auth_context = NULL;
- krb5_enctype enc_types[] = {
-#ifdef ENCTYPE_ARCFOUR_HMAC
- ENCTYPE_ARCFOUR_HMAC,
-#endif
- ENCTYPE_DES_CBC_MD5,
- ENCTYPE_DES_CBC_CRC,
- ENCTYPE_NULL};
-
- retval = krb5_init_context(&context);
- if (retval) {
- DEBUG(1,("krb5_init_context failed (%s)\n",
- error_message(retval)));
- goto failed;
- }
-
- if (time_offset != 0) {
- krb5_set_real_time(context, time(NULL) + time_offset, 0);
- }
-
- if ((retval = krb5_cc_default(context, &ccdef))) {
- DEBUG(1,("krb5_cc_default failed (%s)\n",
- error_message(retval)));
- goto failed;
- }
-
- if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) {
- DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n",
- error_message(retval)));
- goto failed;
- }
-
- if ((retval = ads_krb5_mk_req(context,
- &auth_context,
- AP_OPTS_USE_SUBKEY,
- principal,
- ccdef, &packet))) {
- goto failed;
- }
-
- get_krb5_smb_session_key(context, auth_context, session_key_krb5, False);
-
- *ticket = data_blob(packet.data, packet.length);
-
-/* Hmm, heimdal dooesn't have this - what's the correct call? */
-#ifdef HAVE_KRB5_FREE_DATA_CONTENTS
- krb5_free_data_contents(context, &packet);
-#endif
-
-failed:
- if ( context )
- krb5_free_context(context);
-
- return retval;
-}
-
- BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote)
- {
- krb5_keyblock *skey;
- krb5_error_code err;
- BOOL ret = False;
-
- memset(session_key, 0, 16);
-
- if (remote)
- err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
- else
- err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
- if (err == 0 && skey != NULL) {
- DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey)));
- *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
- dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
-
- ret = True;
-
- krb5_free_keyblock(context, skey);
- } else {
- DEBUG(10, ("KRB5 error getting session key %d\n", err));
- }
-
- return ret;
- }
-
-
-#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT)
- const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i )
-{
- static krb5_data kdata;
-
- kdata.data = krb5_principal_get_comp_string(context, principal, i);
- kdata.length = strlen(kdata.data);
- return &kdata;
-}
-#endif
-
-#else /* HAVE_KRB5 */
- /* this saves a few linking headaches */
-int cli_krb5_get_ticket(const char *principal, time_t time_offset,
- DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
-{
- DEBUG(0,("NO KERBEROS SUPPORT\n"));
- return 1;
-}
-
-#endif
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index ab157d48e96..5707963e191 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client directory list routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -22,13 +23,13 @@
#include "includes.h"
+
/****************************************************************************
- Interpret a long filename structure - this is mostly guesses at the moment.
- The length of the structure is returned
- The structure of a long filename depends on the info level. 260 is used
- by NT and 2 is used by OS/2
+interpret a long filename structure - this is mostly guesses at the moment
+The length of the structure is returned
+The structure of a long filename depends on the info level. 260 is used
+by NT and 2 is used by OS/2
****************************************************************************/
-
static int interpret_long_filename(struct cli_state *cli,
int level,char *p,file_info *finfo)
{
@@ -41,7 +42,8 @@ static int interpret_long_filename(struct cli_state *cli,
memcpy(finfo,&def_finfo,sizeof(*finfo));
- switch (level) {
+ switch (level)
+ {
case 1: /* OS/2 understands this */
/* these dates are converted to GMT by
make_unix_date */
@@ -53,14 +55,10 @@ static int interpret_long_filename(struct cli_state *cli,
len = CVAL(p, 26);
p += 27;
p += clistr_align_in(cli, p, 0);
- /* the len+2 below looks strange but it is
- important to cope with the differences
- between win2000 and win9x for this call
- (tridge) */
p += clistr_pull(cli, finfo->name, p,
- sizeof(finfo->name),
- len+2,
- STR_TERMINATE);
+ sizeof(finfo->name),
+ len,
+ STR_TERMINATE);
return PTR_DIFF(p, base);
case 2: /* this is what OS/2 uses mostly */
@@ -82,7 +80,7 @@ static int interpret_long_filename(struct cli_state *cli,
case 260: /* NT uses this, but also accepts 2 */
{
- size_t namelen, slen;
+ int namelen, slen;
p += 4; /* next entry offset */
p += 4; /* fileindex */
@@ -101,20 +99,13 @@ static int interpret_long_filename(struct cli_state *cli,
cheap to calculate, I suppose, as
no DST tables will be needed */
- finfo->ctime = interpret_long_date(p);
- p += 8;
- finfo->atime = interpret_long_date(p);
- p += 8;
- finfo->mtime = interpret_long_date(p);
- p += 8;
- p += 8;
- finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
- p += 8;
+ finfo->ctime = interpret_long_date(p); p += 8;
+ finfo->atime = interpret_long_date(p); p += 8;
+ finfo->mtime = interpret_long_date(p); p += 8; p += 8;
+ finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8;
p += 8; /* alloc size */
- finfo->mode = CVAL(p,0);
- p += 4;
- namelen = IVAL(p,0);
- p += 4;
+ finfo->mode = CVAL(p,0); p += 4;
+ namelen = IVAL(p,0); p += 4;
p += 4; /* EA size */
slen = SVAL(p, 0);
p += 2;
@@ -132,24 +123,20 @@ static int interpret_long_filename(struct cli_state *cli,
namelen, 0);
return SVAL(base, 0);
}
- }
+ }
DEBUG(1,("Unknown long filename format %d\n",level));
return(SVAL(p,0));
}
-/****************************************************************************
- Do a directory listing, calling fn on each file found.
-****************************************************************************/
+/****************************************************************************
+ do a directory listing, calling fn on each file found
+ ****************************************************************************/
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *, void *), void *state)
{
-#if 0
- int max_matches = 1366; /* Match W2k - was 512. */
-#else
int max_matches = 512;
-#endif
int info_level;
char *p, *p2;
pstring mask;
@@ -189,8 +176,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,6,info_level);
SIVAL(param,8,0);
p = param+12;
- p += clistr_push(cli, param+12, mask, sizeof(param)-12,
- STR_TERMINATE);
+ p += clistr_push(cli, param+12, mask, -1,
+ STR_TERMINATE|STR_CONVERT);
} else {
setup = TRANSACT2_FINDNEXT;
SSVAL(param,0,ff_dir_handle);
@@ -199,8 +186,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SIVAL(param,6,0); /* ff_resume_key */
SSVAL(param,10,8+4+2); /* continue + resume required + close on end */
p = param+12;
- p += clistr_push(cli, param+12, mask, sizeof(param)-12,
- STR_TERMINATE);
+ p += clistr_push(cli, param+12, mask, -1,
+ STR_TERMINATE|STR_CONVERT);
}
param_len = PTR_DIFF(p, param);
@@ -211,12 +198,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
&setup, 1, 0, /* setup, length, max */
param, param_len, 10, /* param, length, max */
NULL, 0,
-#if 0
- /* w2k value. */
- MIN(16384,cli->max_xmit) /* data, length, max. */
-#else
- cli->max_xmit /* data, length, max. */
-#endif
+ cli->max_xmit /* data, length, max */
)) {
break;
}
@@ -230,17 +212,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
uint8 eclass;
uint32 ecode;
cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRSRV || ecode != ERRerror)
- break;
- smb_msleep(100);
+ if (eclass != ERRSRV || ecode != ERRerror) break;
+ msleep(100);
continue;
}
if (cli_is_error(cli) || !rdata || !rparam)
break;
- if (total_received == -1)
- total_received = 0;
+ if (total_received == -1) total_received = 0;
/* parse out some important return info */
p = rparam;
@@ -263,7 +243,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
/* we might need the lastname for continuations */
if (ff_lastname > 0) {
- switch(info_level) {
+ switch(info_level)
+ {
case 260:
clistr_pull(cli, mask, p+ff_lastname,
sizeof(mask),
@@ -287,9 +268,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
if (!tdl) {
DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
break;
- } else {
- dirlist = tdl;
}
+ else dirlist = tdl;
/* put in a length for the last entry, to ensure we can chain entries
into the next packet */
@@ -309,8 +289,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
DEBUG(3,("received %d entries (eos=%d)\n",
ff_searchcount,ff_eos));
- if (ff_searchcount > 0)
- loop_count = 0;
+ if (ff_searchcount > 0) loop_count = 0;
First = False;
}
@@ -325,11 +304,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
return(total_received);
}
+
+
/****************************************************************************
- Interpret a short filename structure.
- The length of the structure is returned.
+interpret a short filename structure
+The length of the structure is returned
****************************************************************************/
-
static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo)
{
extern file_info def_finfo;
@@ -341,22 +321,20 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi
/* this date is converted to GMT by make_unix_date */
finfo->ctime = make_unix_date(p+22);
finfo->mtime = finfo->atime = finfo->ctime;
- finfo->size = IVAL(p,26);
+ finfo->size = (SMB_BIG_UINT) IVAL(p,26); /* This returns a 4 byte length, not 8 */
clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII);
- if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) {
- strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1);
- finfo->short_name[sizeof(finfo->short_name)-1] = '\0';
- }
-
+ if (strcmp(finfo->name, "..") && strcmp(finfo->name, "."))
+ fstrcpy(finfo->short_name,finfo->name);
+
return(DIR_STRUCT_SIZE);
}
/****************************************************************************
- Do a directory listing, calling fn on each file found.
- this uses the old SMBsearch interface. It is needed for testing Samba,
- but should otherwise not be used.
-****************************************************************************/
+ do a directory listing, calling fn on each file found
+ this uses the old SMBsearch interface. It is needed for testing Samba,
+ but should otherwise not be used
+ ****************************************************************************/
int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *, void *), void *state)
@@ -392,7 +370,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE);
+ p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT);
*p++ = 5;
if (first) {
SSVAL(p,0,0);
@@ -473,15 +451,16 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
return(num_received);
}
-/****************************************************************************
- Do a directory listing, calling fn on each file found.
- This auto-switches between old and new style.
-****************************************************************************/
+/****************************************************************************
+ do a directory listing, calling fn on each file found
+ this auto-switches between old and new style
+ ****************************************************************************/
int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *, void *), void *state)
{
- if (cli->protocol <= PROTOCOL_LANMAN1)
+ if (cli->protocol <= PROTOCOL_LANMAN1) {
return cli_list_old(cli, Mask, attribute, fn, state);
+ }
return cli_list_new(cli, Mask, attribute, fn, state);
}
diff --git a/source/libsmb/climessage.c b/source/libsmb/climessage.c
index 8429ca4f413..5ded79de96c 100644
--- a/source/libsmb/climessage.c
+++ b/source/libsmb/climessage.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client message handling routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -26,11 +27,12 @@
/****************************************************************************
start a message sequence
****************************************************************************/
-int cli_message_start_build(struct cli_state *cli, char *host, char *username)
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
+ int *grp)
{
char *p;
- /* construct a SMBsendstrt command */
+ /* send a SMBsendstrt command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBsendstrt);
@@ -39,19 +41,11 @@ int cli_message_start_build(struct cli_state *cli, char *host, char *username)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, username, -1, STR_ASCII|STR_TERMINATE);
+ p += clistr_push(cli, p, username, -1, STR_TERMINATE);
*p++ = 4;
- p += clistr_push(cli, p, host, -1, STR_ASCII|STR_TERMINATE);
+ p += clistr_push(cli, p, host, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
-
- return(PTR_DIFF(p, cli->outbuf));
-}
-
-BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
- int *grp)
-{
- cli_message_start_build(cli, host, username);
cli_send_smb(cli);
@@ -70,10 +64,8 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
/****************************************************************************
send a message
****************************************************************************/
-int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp)
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
{
- char *msgdos;
- int lendos;
char *p;
memset(cli->outbuf,'\0',smb_size);
@@ -86,28 +78,11 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp)
p = smb_buf(cli->outbuf);
*p++ = 1;
-
- if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos, True)) < 0 || !msgdos) {
- DEBUG(3,("Conversion failed, sending message in UNIX charset\n"));
- SSVAL(p, 0, len); p += 2;
- memcpy(p, msg, len);
- p += len;
- } else {
- SSVAL(p, 0, lendos); p += 2;
- memcpy(p, msgdos, lendos);
- p += lendos;
- SAFE_FREE(msgdos);
- }
+ SSVAL(p,0,len); p += 2;
+ memcpy(p,msg,len);
+ p += len;
cli_setup_bcc(cli, p);
-
- return(PTR_DIFF(p, cli->outbuf));
-}
-
-BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
-{
- cli_message_text_build(cli, msg, len, grp);
-
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
@@ -122,10 +97,8 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
/****************************************************************************
end a message
****************************************************************************/
-int cli_message_end_build(struct cli_state *cli, int grp)
+BOOL cli_message_end(struct cli_state *cli, int grp)
{
- char *p;
-
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
SCVAL(cli->outbuf,smb_com,SMBsendend);
@@ -134,16 +107,7 @@ int cli_message_end_build(struct cli_state *cli, int grp)
SSVAL(cli->outbuf,smb_vwv0,grp);
cli_setup_packet(cli);
-
- p = smb_buf(cli->outbuf);
-
- return(PTR_DIFF(p, cli->outbuf));
-}
-
-BOOL cli_message_end(struct cli_state *cli, int grp)
-{
- cli_message_end_build(cli, grp);
-
+
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
@@ -154,3 +118,4 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
return True;
}
+
diff --git a/source/libsmb/clioplock.c b/source/libsmb/clioplock.c
index 0ffeb1926b0..dca0e96cb4a 100644
--- a/source/libsmb/clioplock.c
+++ b/source/libsmb/clioplock.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
SMB client oplock functions
Copyright (C) Andrew Tridgell 2001
diff --git a/source/libsmb/cliprint.c b/source/libsmb/cliprint.c
index 2fb0e59acac..6785170ceed 100644
--- a/source/libsmb/cliprint.c
+++ b/source/libsmb/cliprint.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client print routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -55,7 +56,7 @@ int cli_print_queue(struct cli_state *cli,
char *rparam = NULL;
char *rdata = NULL;
char *p;
- unsigned int rdrcnt, rprcnt;
+ int rdrcnt, rprcnt;
pstring param;
int result_code=0;
int i = -1;
@@ -65,16 +66,16 @@ int cli_print_queue(struct cli_state *cli,
p = param;
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
p += 2;
- pstrcpy_base(p,"zWrLeh", param); /* parameter description? */
+ pstrcpy(p,"zWrLeh"); /* parameter description? */
p = skip_string(p,1);
- pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */
+ pstrcpy(p,"WWzWWDDzz"); /* returned data format */
p = skip_string(p,1);
- pstrcpy_base(p,cli->share, param); /* name of queue */
+ pstrcpy(p,cli->share); /* name of queue */
p = skip_string(p,1);
SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
SSVAL(p,2,1000); /* size of bytes of returned data buffer */
p += 4;
- pstrcpy_base(p,"", param); /* subformat */
+ pstrcpy(p,""); /* subformat */
p = skip_string(p,1);
DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
@@ -125,8 +126,7 @@ int cli_printjob_del(struct cli_state *cli, int job)
char *rparam = NULL;
char *rdata = NULL;
char *p;
- unsigned int rdrcnt,rprcnt;
- int ret = -1;
+ int rdrcnt,rprcnt, ret = -1;
pstring param;
memset(param,'\0',sizeof(param));
@@ -134,9 +134,9 @@ int cli_printjob_del(struct cli_state *cli, int job)
p = param;
SSVAL(p,0,81); /* DosPrintJobDel() */
p += 2;
- pstrcpy_base(p,"W", param);
+ pstrcpy(p,"W");
p = skip_string(p,1);
- pstrcpy_base(p,"", param);
+ pstrcpy(p,"");
p = skip_string(p,1);
SSVAL(p,0,job);
p += 2;
diff --git a/source/libsmb/cliquota.c b/source/libsmb/cliquota.c
deleted file mode 100644
index ed808aa1f5c..00000000000
--- a/source/libsmb/cliquota.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- client quota functions
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum)
-{
- *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA,
- 0x00000016, DESIRED_ACCESS_PIPE,
- 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_OPEN, 0x00000000, 0x03);
-
- if (*quota_fnum == (-1)) {
- return False;
- }
-
- return True;
-}
-
-void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list)
-{
- if (!qt_list)
- return;
-
- if ((*qt_list)->mem_ctx)
- talloc_destroy((*qt_list)->mem_ctx);
-
- (*qt_list) = NULL;
-
- return;
-}
-
-static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt)
-{
- int sid_len;
- SMB_NTQUOTA_STRUCT qt;
-
- ZERO_STRUCT(qt);
-
- if (!rdata||!offset||!pqt)
- smb_panic("parse_quota_record: called with NULL POINTER!\n");
-
- if (rdata_count < 40) {
- return False;
- }
-
- /* offset to next quota record.
- * 4 bytes IVAL(rdata,0)
- * unused here...
- */
- *offset = IVAL(rdata,0);
-
- /* sid len */
- sid_len = IVAL(rdata,4);
-
- if (rdata_count < 40+sid_len) {
- return False;
- }
-
- /* unknown 8 bytes in pdata
- * maybe its the change time in NTTIME
- */
-
- /* the used space 8 bytes (SMB_BIG_UINT)*/
- qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16);
-#ifdef LARGE_SMB_OFF_T
- qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(rdata,20) != 0)&&
- ((qt.usedspace != 0xFFFFFFFF)||
- (IVAL(rdata,20)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return False;
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
- qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
-#ifdef LARGE_SMB_OFF_T
- qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(rdata,28) != 0)&&
- ((qt.softlim != 0xFFFFFFFF)||
- (IVAL(rdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return False;
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
- qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
-#ifdef LARGE_SMB_OFF_T
- qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(rdata,36) != 0)&&
- ((qt.hardlim != 0xFFFFFFFF)||
- (IVAL(rdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return False;
- }
-#endif /* LARGE_SMB_OFF_T */
-
- sid_parse(rdata+40,sid_len,&qt.sid);
-
- qt.qtype = SMB_USER_QUOTA_TYPE;
-
- *pqt = qt;
-
- return True;
-}
-
-BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
-{
- BOOL ret = False;
- uint16 setup;
- char params[16];
- unsigned int data_len;
- char data[SID_MAX_SIZE+8];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
- unsigned int sid_len;
- unsigned int offset;
-
- if (!cli||!pqt)
- smb_panic("cli_get_user_quota() called with NULL Pointer!");
-
- setup = NT_TRANSACT_GET_USER_QUOTA;
-
- SSVAL(params, 0,quota_fnum);
- SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID);
- SIVAL(params, 4,0x00000024);
- SIVAL(params, 8,0x00000000);
- SIVAL(params,12,0x00000024);
-
- sid_len = sid_size(&pqt->sid);
- data_len = sid_len+8;
- SIVAL(data, 0, 0x00000000);
- SIVAL(data, 4, sid_len);
- sid_linearize(data+8, sid_len, &pqt->sid);
-
- if (!cli_send_nt_trans(cli,
- NT_TRANSACT_GET_USER_QUOTA,
- 0,
- &setup, 1, 0,
- params, 16, 4,
- data, data_len, 112)) {
- DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
-
- if (!cli_receive_nt_trans(cli,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) {
- ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt);
- } else {
- DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n"));
- ret = False;
- }
-
- cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
- return ret;
-}
-
-BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
-{
- BOOL ret = False;
- uint16 setup;
- char params[2];
- char data[112];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
- unsigned int sid_len;
- memset(data,'\0',112);
-
- if (!cli||!pqt)
- smb_panic("cli_set_user_quota() called with NULL Pointer!");
-
- setup = NT_TRANSACT_SET_USER_QUOTA;
-
- SSVAL(params,0,quota_fnum);
-
- sid_len = sid_size(&pqt->sid);
- SIVAL(data,0,0);
- SIVAL(data,4,sid_len);
- SBIG_UINT(data, 8,(SMB_BIG_UINT)0);
- SBIG_UINT(data,16,pqt->usedspace);
- SBIG_UINT(data,24,pqt->softlim);
- SBIG_UINT(data,32,pqt->hardlim);
- sid_linearize(data+40, sid_len, &pqt->sid);
-
- if (!cli_send_nt_trans(cli,
- NT_TRANSACT_SET_USER_QUOTA,
- 0,
- &setup, 1, 0,
- params, 2, 0,
- data, 112, 0)) {
- DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n"));
- goto cleanup;
- }
-
-
- if (!cli_receive_nt_trans(cli,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n"));
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
- return ret;
-}
-
-BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list)
-{
- BOOL ret = False;
- uint16 setup;
- char params[16];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
- unsigned int offset;
- const char *curdata = NULL;
- unsigned int curdata_count = 0;
- TALLOC_CTX *mem_ctx = NULL;
- SMB_NTQUOTA_STRUCT qt;
- SMB_NTQUOTA_LIST *tmp_list_ent;
-
- if (!cli||!pqt_list)
- smb_panic("cli_list_user_quota() called with NULL Pointer!");
-
- setup = NT_TRANSACT_GET_USER_QUOTA;
-
- SSVAL(params, 0,quota_fnum);
- SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START);
- SIVAL(params, 4,0x00000000);
- SIVAL(params, 8,0x00000000);
- SIVAL(params,12,0x00000000);
-
- if (!cli_send_nt_trans(cli,
- NT_TRANSACT_GET_USER_QUOTA,
- 0,
- &setup, 1, 0,
- params, 16, 4,
- NULL, 0, 2048)) {
- DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
-
- if (!cli_receive_nt_trans(cli,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- if (rdata_count == 0) {
- *pqt_list = NULL;
- return True;
- }
-
- if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
- DEBUG(0,("talloc_init() failed\n"));
- return (-1);
- }
-
- offset = 1;
- for (curdata=rdata,curdata_count=rdata_count;
- ((curdata)&&(curdata_count>=8)&&(offset>0));
- curdata +=offset,curdata_count -= offset) {
- ZERO_STRUCT(qt);
- if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
- DEBUG(1,("Failed to parse the quota record\n"));
- goto cleanup;
- }
-
- if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- return (-1);
- }
-
- if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- return (-1);
- }
-
- memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
- tmp_list_ent->mem_ctx = mem_ctx;
-
- DLIST_ADD((*pqt_list),tmp_list_ent);
- }
-
- SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);
- while(1) {
- if (!cli_send_nt_trans(cli,
- NT_TRANSACT_GET_USER_QUOTA,
- 0,
- &setup, 1, 0,
- params, 16, 4,
- NULL, 0, 2048)) {
- DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
- if (!cli_receive_nt_trans(cli,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- if (rdata_count == 0) {
- break;
- }
-
- offset = 1;
- for (curdata=rdata,curdata_count=rdata_count;
- ((curdata)&&(curdata_count>=8)&&(offset>0));
- curdata +=offset,curdata_count -= offset) {
- ZERO_STRUCT(qt);
- if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
- DEBUG(1,("Failed to parse the quota record\n"));
- goto cleanup;
- }
-
- if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- talloc_destroy(mem_ctx);
- goto cleanup;
- }
-
- if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- talloc_destroy(mem_ctx);
- goto cleanup;
- }
-
- memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
- tmp_list_ent->mem_ctx = mem_ctx;
-
- DLIST_ADD((*pqt_list),tmp_list_ent);
- }
- }
-
-
- ret = True;
- cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return ret;
-}
-
-BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
-{
- BOOL ret = False;
- uint16 setup;
- char param[2];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
- SMB_NTQUOTA_STRUCT qt;
- ZERO_STRUCT(qt);
-
- if (!cli||!pqt)
- smb_panic("cli_get_fs_quota_info() called with NULL Pointer!");
-
- setup = TRANSACT2_QFSINFO;
-
- SSVAL(param,0,SMB_FS_QUOTA_INFORMATION);
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL,
- 0, 0,
- &setup, 1, 0,
- param, 2, 0,
- NULL, 0, 560)) {
- goto cleanup;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
- if (rdata_count < 48) {
- goto cleanup;
- }
-
- /* unknown_1 24 NULL bytes in pdata*/
-
- /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
- qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
-#ifdef LARGE_SMB_OFF_T
- qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(rdata,28) != 0)&&
- ((qt.softlim != 0xFFFFFFFF)||
- (IVAL(rdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- goto cleanup;
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
- qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
-#ifdef LARGE_SMB_OFF_T
- qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(rdata,36) != 0)&&
- ((qt.hardlim != 0xFFFFFFFF)||
- (IVAL(rdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- goto cleanup;
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* quota_flags 2 bytes **/
- qt.qflags = SVAL(rdata,40);
-
- qt.qtype = SMB_USER_FS_QUOTA_TYPE;
-
- *pqt = qt;
-
- ret = True;
-cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return ret;
-}
-
-BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
-{
- BOOL ret = False;
- uint16 setup;
- char param[4];
- char data[48];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
- SMB_NTQUOTA_STRUCT qt;
- ZERO_STRUCT(qt);
- memset(data,'\0',48);
-
- if (!cli||!pqt)
- smb_panic("cli_set_fs_quota_info() called with NULL Pointer!");
-
- setup = TRANSACT2_SETFSINFO;
-
- SSVAL(param,0,quota_fnum);
- SSVAL(param,2,SMB_FS_QUOTA_INFORMATION);
-
- /* Unknown1 24 NULL bytes*/
-
- /* Default Soft Quota 8 bytes */
- SBIG_UINT(data,24,pqt->softlim);
-
- /* Default Hard Quota 8 bytes */
- SBIG_UINT(data,32,pqt->hardlim);
-
- /* Quota flag 2 bytes */
- SSVAL(data,40,pqt->qflags);
-
- /* Unknown3 6 NULL bytes */
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL,
- 0, 0,
- &setup, 1, 0,
- param, 4, 0,
- data, 48, 0)) {
- goto cleanup;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- goto cleanup;
- }
-
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
- }
-
-cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return ret;
-}
-
-static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric)
-{
- static fstring buffer;
-
- memset(buffer,'\0',sizeof(buffer));
-
- if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) {
- fstr_sprintf(buffer,"NO LIMIT");
- return buffer;
- }
-#if defined(HAVE_LONGLONG)
- fstr_sprintf(buffer,"%llu",val);
-#else
- fstr_sprintf(buffer,"%lu",val);
-#endif
- return buffer;
-}
-
-void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
-{
- if (!qt)
- smb_panic("dump_ntquota() called with NULL pointer");
-
- switch (qt->qtype) {
- case SMB_USER_FS_QUOTA_TYPE:
- {
- d_printf("File System QUOTAS:\n");
- d_printf("Limits:\n");
- d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
- d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
- d_printf("Quota Flags:\n");
- d_printf(" Quotas Enabled: %s\n",
- ((qt->qflags&QUOTAS_ENABLED)||(qt->qflags&QUOTAS_DENY_DISK))?"On":"Off");
- d_printf(" Deny Disk: %s\n",(qt->qflags&QUOTAS_DENY_DISK)?"On":"Off");
- d_printf(" Log Soft Limit: %s\n",(qt->qflags&QUOTAS_LOG_THRESHOLD)?"On":"Off");
- d_printf(" Log Hard Limit: %s\n",(qt->qflags&QUOTAS_LOG_LIMIT)?"On":"Off");
- }
- break;
- case SMB_USER_QUOTA_TYPE:
- {
- fstring username_str = {0};
-
- if (_sidtostring) {
- _sidtostring(username_str,&qt->sid,_numeric);
- } else {
- fstrcpy(username_str,sid_string_static(&qt->sid));
- }
-
- if (_verbose) {
- d_printf("Quotas for User: %s\n",username_str);
- d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric));
- d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
- d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
- } else {
- d_printf("%-30s: ",username_str);
- d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric));
- d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric));
- d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric));
- }
- }
- break;
- default:
- d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype);
- return;
- }
-}
-
-void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
-{
- SMB_NTQUOTA_LIST *cur;
-
- for (cur = *qtl;cur;cur = cur->next) {
- if (cur->quotas)
- dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring);
- }
-}
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index f8204e05d68..bea3939565f 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client RAP calls
Copyright (C) Andrew Tridgell 1994-1998
@@ -76,7 +77,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
char *rparam = NULL;
char *rdata = NULL;
char *p;
- unsigned int rdrcnt,rprcnt;
+ int rdrcnt,rprcnt;
pstring param;
memset(param, 0, sizeof(param));
@@ -85,20 +86,20 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
p = param;
SSVAL(p,0,132); /* api number */
p += 2;
- pstrcpy_base(p,"OOWb54WrLh",param);
+ pstrcpy(p,"OOWb54WrLh");
p = skip_string(p,1);
- pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param);
+ pstrcpy(p,"WB21BWDWWDDDDDDDzzzD");
p = skip_string(p,1);
SSVAL(p,0,1);
p += 2;
- pstrcpy_base(p,user,param);
- strupper_m(p);
+ pstrcpy(p,user);
+ strupper(p);
p += 21;
p++;
p += 15;
p++;
- pstrcpy_base(p, workstation, param);
- strupper_m(p);
+ pstrcpy(p, workstation);
+ strupper(p);
p += 16;
SSVAL(p, 0, CLI_BUFFER_SIZE);
p += 2;
@@ -117,8 +118,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
if (cli->rap_error == 0) {
DEBUG(4,("NetWkstaUserLogon success\n"));
cli->privileges = SVAL(p, 24);
- /* The cli->eff_name field used to be set here
- but it wasn't used anywhere else. */
+ fstrcpy(cli->eff_name,p+2);
} else {
DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error));
}
@@ -137,7 +137,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
char *rparam = NULL;
char *rdata = NULL;
char *p;
- unsigned int rdrcnt,rprcnt;
+ int rdrcnt,rprcnt;
pstring param;
int count = -1;
@@ -145,9 +145,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
p = param;
SSVAL(p,0,0); /* api number */
p += 2;
- pstrcpy_base(p,"WrLeh",param);
+ pstrcpy(p,"WrLeh");
p = skip_string(p,1);
- pstrcpy_base(p,"B13BWz",param);
+ pstrcpy(p,"B13BWz");
p = skip_string(p,1);
SSVAL(p,0,1);
/*
@@ -179,8 +179,8 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
const char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
pstring s1, s2;
- pull_ascii_pstring(s1, sname);
- pull_ascii_pstring(s2, cmnt);
+ pstrcpy(s1, dos_to_unix_static(sname));
+ pstrcpy(s2, dos_to_unix_static(cmnt));
fn(s1, type, s2, state);
}
@@ -211,7 +211,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
{
char *rparam = NULL;
char *rdata = NULL;
- unsigned int rdrcnt,rprcnt;
+ int rdrcnt,rprcnt;
char *p;
pstring param;
int uLevel = 1;
@@ -221,10 +221,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
p = param;
SSVAL(p,0,0x68); /* api number */
p += 2;
- pstrcpy_base(p,"WrLehDz", param);
+ pstrcpy(p,"WrLehDz");
p = skip_string(p,1);
- pstrcpy_base(p,"B16BBDz", param);
+ pstrcpy(p,"B16BBDz");
p = skip_string(p,1);
SSVAL(p,0,uLevel);
@@ -233,8 +233,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
SIVAL(p,0,stype);
p += 4;
- p += push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER);
-
+ p += clistr_push(cli, p, workgroup, -1,
+ STR_TERMINATE | STR_CONVERT | STR_ASCII);
+
if (cli_api(cli,
param, PTR_DIFF(p,param), 8, /* params, length, max */
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
@@ -256,12 +257,12 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
const char *cmnt = comment_offset?(rdata+comment_offset):"";
pstring s1, s2;
- if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue;
+ if (comment_offset < 0 || comment_offset > rdrcnt) continue;
stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
- pull_ascii_pstring(s1, sname);
- pull_ascii_pstring(s2, cmnt);
+ pstrcpy(s1, dos_to_unix_static(sname));
+ pstrcpy(s2, dos_to_unix_static(cmnt));
fn(s1, stype, s2, state);
}
}
@@ -281,16 +282,19 @@ Send a SamOEMChangePassword command
BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
const char *old_password)
{
- pstring param;
+ char param[16+sizeof(fstring)];
char data[532];
char *p = param;
+ fstring upper_case_old_pw;
+ fstring upper_case_new_pw;
unsigned char old_pw_hash[16];
unsigned char new_pw_hash[16];
unsigned int data_len;
unsigned int param_len = 0;
char *rparam = NULL;
char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
+ int rprcnt, rdrcnt;
+ pstring dos_new_password;
if (strlen(user) >= sizeof(fstring)-1) {
DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
@@ -299,11 +303,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
SSVAL(p,0,214); /* SamOEMChangePassword command. */
p += 2;
- pstrcpy_base(p, "zsT", param);
+ pstrcpy(p, "zsT");
p = skip_string(p,1);
- pstrcpy_base(p, "B516B16", param);
+ pstrcpy(p, "B516B16");
p = skip_string(p,1);
- pstrcpy_base(p,user, param);
+ pstrcpy(p,user);
p = skip_string(p,1);
SSVAL(p,0,532);
p += 2;
@@ -314,20 +318,22 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
* Get the Lanman hash of the old password, we
* use this as the key to make_oem_passwd_hash().
*/
- E_deshash(old_password, old_pw_hash);
+ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
+ clistr_push(cli, upper_case_old_pw, old_password, -1,STR_CONVERT|STR_TERMINATE|STR_UPPER|STR_ASCII);
+ E_P16((uchar *)upper_case_old_pw, old_pw_hash);
- encode_pw_buffer(data, new_password, STR_ASCII);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("make_oem_passwd_hash\n"));
- dump_data(100, data, 516);
-#endif
- SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);
+ clistr_push(cli, dos_new_password, new_password, -1, STR_CONVERT|STR_TERMINATE|STR_ASCII);
+
+ if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False))
+ return False;
/*
* Now place the old password hash in the data.
*/
- E_deshash(new_password, new_pw_hash);
+ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
+ clistr_push(cli, upper_case_new_pw, new_password, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER|STR_ASCII);
+
+ E_P16((uchar *)upper_case_new_pw, new_pw_hash);
E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]);
@@ -345,17 +351,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
return False;
}
- if (!cli_receive_trans(cli,SMBtrans,
+ if (cli_receive_trans(cli,SMBtrans,
&rparam, &rprcnt,
&rdata, &rdrcnt)) {
- DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n",
- user ));
- return False;
+ if (rparam)
+ cli->rap_error = SVAL(rparam,0);
}
-
- if (rparam)
- cli->rap_error = SVAL(rparam,0);
-
+
SAFE_FREE(rparam);
SAFE_FREE(rdata);
@@ -372,7 +374,6 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
{
unsigned int data_len = 0;
unsigned int param_len = 0;
- unsigned int rparam_len, rdata_len;
uint16 setup = TRANSACT2_QPATHINFO;
pstring param;
char *rparam=NULL, *rdata=NULL;
@@ -385,7 +386,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
memset(p, 0, 6);
SSVAL(p, 0, SMB_INFO_STANDARD);
p += 6;
- p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE|STR_CONVERT );
param_len = PTR_DIFF(p, param);
@@ -398,21 +399,20 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
NULL, data_len, cli->max_xmit /* data, length, max */
) &&
cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_len,
- &rdata, &rdata_len));
- if (!cli_is_dos_error(cli)) break;
- if (!ret) {
+ &rparam, &param_len,
+ &rdata, &data_len));
+ if (!ret && cli_is_dos_error(cli)) {
/* we need to work around a Win95 bug - sometimes
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
cli_dos_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
- smb_msleep(100);
+ msleep(100);
}
} while (count-- && ret==False);
- if (!ret || !rdata || rdata_len < 22) {
+ if (!ret || !rdata || data_len < 22) {
return False;
}
@@ -462,7 +462,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
memset(p, 0, 6);
SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
p += 6;
- p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE|STR_CONVERT );
param_len = PTR_DIFF(p, param);
@@ -515,49 +515,6 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
/****************************************************************************
-send a qfileinfo QUERY_FILE_NAME_INFO call
-****************************************************************************/
-BOOL cli_qfilename(struct cli_state *cli, int fnum,
- pstring name)
-{
- unsigned int data_len = 0;
- unsigned int param_len = 0;
- uint16 setup = TRANSACT2_QFILEINFO;
- pstring param;
- char *rparam=NULL, *rdata=NULL;
-
- param_len = 4;
- memset(param, 0, param_len);
- SSVAL(param, 0, fnum);
- SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO);
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- NULL, data_len, cli->max_xmit /* data, length, max */
- )) {
- return False;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return False;
- }
-
- if (!rdata || data_len < 4) {
- return False;
- }
-
- clistr_pull(cli, name, rdata+4, sizeof(pstring), IVAL(rdata, 0), STR_UNICODE);
-
- return True;
-}
-
-
-/****************************************************************************
send a qfileinfo call
****************************************************************************/
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
@@ -631,7 +588,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
/****************************************************************************
send a qfileinfo call
****************************************************************************/
-BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen)
+BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
@@ -639,13 +596,9 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd
pstring param;
char *rparam=NULL, *rdata=NULL;
- *poutdata = NULL;
- *poutlen = 0;
-
/* if its a win95 server then fail this - win95 totally screws it
up */
- if (cli->win95)
- return False;
+ if (cli->win95) return False;
param_len = 4;
@@ -669,19 +622,17 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd
return False;
}
- *poutdata = memdup(rdata, data_len);
- *poutlen = data_len;
+ memcpy(outdata, rdata, data_len);
SAFE_FREE(rdata);
SAFE_FREE(rparam);
return True;
}
-
-
/****************************************************************************
-send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call
+ Send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call.
****************************************************************************/
+
NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name)
{
unsigned int data_len = 0;
@@ -692,13 +643,13 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
int count=8;
char *p;
BOOL ret;
- unsigned int len;
+ int len;
p = param;
memset(p, 0, 6);
SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO);
p += 6;
- p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE|STR_CONVERT);
param_len = PTR_DIFF(p, param);
@@ -720,7 +671,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
uint32 ecode;
cli_dos_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
- smb_msleep(100);
+ msleep(100);
}
} while (count-- && ret==False);
@@ -734,7 +685,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, STR_UNICODE);
+ clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, 0);
SAFE_FREE(rdata);
SAFE_FREE(rparam);
diff --git a/source/libsmb/clirap2.c b/source/libsmb/clirap2.c
deleted file mode 100644
index 12a3d63aff3..00000000000
--- a/source/libsmb/clirap2.c
+++ /dev/null
@@ -1,1970 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- More client RAP (SMB Remote Procedure Calls) functions
- Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
- Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*****************************************************/
-/* */
-/* Additional RAP functionality */
-/* */
-/* RAP is the original SMB RPC, documented */
-/* by Microsoft and X/Open in the 1990s and */
-/* supported by most SMB/CIFS servers although */
-/* it is unlikely that any one implementation */
-/* supports all RAP command codes since some */
-/* are quite obsolete and a few are specific */
-/* to a particular network operating system */
-/* */
-/* Although it has largely been replaced */
-/* for complex remote admistration and management */
-/* (of servers) by the relatively newer */
-/* DCE/RPC based remote API (which better handles */
-/* large >64K data structures), there are many */
-/* important administrative and resource location */
-/* tasks and user tasks (e.g. password change) */
-/* that are performed via RAP. */
-/* */
-/* Although a few of the RAP calls are implemented */
-/* in the Samba client library already (clirap.c) */
-/* the new ones are in clirap2.c for easy patching */
-/* and integration and a corresponding header */
-/* file, rap.h, has been created. */
-/* */
-/* This is based on data from the CIFS spec */
-/* and the LAN Server and LAN Manager */
-/* Programming Reference books and published */
-/* RAP document and CIFS forum postings and */
-/* lots of trial and error */
-/* */
-/* Function names changed from API_ (as they are */
-/* in the CIFS specification) to RAP_ in order */
-/* to avoid confusion with other API calls */
-/* sent via DCE RPC */
-/* */
-/*****************************************************/
-
-/*****************************************************/
-/* */
-/* cifsrap.c already includes support for: */
-/* */
-/* WshareEnum ( API number 0, level 1) */
-/* NetServerEnum2 (API num 104, level 1) */
-/* WWkstaUserLogon (132) */
-/* SamOEMchgPasswordUser2_P (214) */
-/* */
-/* cifsprint.c already includes support for: */
-/* */
-/* WPrintJobEnum (API num 76, level 2) */
-/* WPrintJobDel (API num 81) */
-/* */
-/*****************************************************/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-#define WORDSIZE 2
-#define DWORDSIZE 4
-
-#define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
-#define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0)
-#define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
-#define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0)
-#define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
-#define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0)
-#define GETRES(p) p ? SVAL(p,0) : -1
-/* put string s at p with max len n and increment p past string */
-#define PUTSTRING(p,s,n) do {\
- push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
- p = skip_string(p,1);\
- } while(0)
-/* put string s and p, using fixed len l, and increment p by l */
-#define PUTSTRINGF(p,s,l) do {\
- push_ascii(p,s?s:"",l,STR_TERMINATE);\
- p += l;\
- } while (0)
-/* put string pointer at p, supplying offset o from rdata r, store */
-/* dword offset at p, increment p by 4 and o by length of s. This */
-/* means on the first call, you must calc the offset yourself! */
-#define PUTSTRINGP(p,s,r,o) do {\
- if (s) {\
- push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
- PUTDWORD(p,o);\
- o += strlen(s) + 1;\
- } else PUTDWORD(p,0);\
- }while(0);
-/* get asciiz string s from p, increment p past string */
-#define GETSTRING(p,s) do {\
- pull_ascii_pstring(s,p);\
- p = skip_string(p,1);\
- } while(0)
-/* get fixed length l string s from p, increment p by l */
-#define GETSTRINGF(p,s,l) do {\
- pull_ascii_pstring(s,p);\
- p += l;\
- } while(0)
-/* get string s from offset (obtained at p) from rdata r - converter c */
-#define GETSTRINGP(p,s,r,c) do {\
- uint32 off;\
- GETDWORD(p,off);\
- off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \
- pull_ascii_pstring(s, off?(r+off-c):"");\
- } while(0)
-
-static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt)
-{
- PUTWORD(param,apinum);
- if (reqfmt)
- PUTSTRING(param,reqfmt,0);
- else
- *param++ = (char) 0;
-
- if (datafmt)
- PUTSTRING(param,datafmt,0);
- else
- *param++ = (char) 0;
-
- return param;
-}
-
-
-/****************************************************************************
- call a NetGroupDelete - delete user group from remote server
-****************************************************************************/
-int cli_NetGroupDelete(struct cli_state *cli, const char *group_name )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupDel_REQ) /* parm string */
- +1 /* no ret string */
- +RAP_GROUPNAME_LEN /* group to del */
- +WORDSIZE]; /* reserved word */
-
- /* now send a SMBtrans command with api GroupDel */
- p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL);
- PUTSTRING(p, group_name, RAP_GROUPNAME_LEN);
- PUTWORD(p,0); /* reserved word MBZ on input */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- }
- else if ((res == 5) || (res == 65)) {
- DEBUG(1, ("Access Denied\n"));
- }
- else if (res == 2220) {
- DEBUG (1, ("Group does not exist\n"));
- }
- else {
- DEBUG(4,("NetGroupDelete res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetGroupDelete failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
- call a NetGroupAdd - add user group to remote server
-****************************************************************************/
-int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupAdd_REQ) /* req string */
- +sizeof(RAP_GROUP_INFO_L1) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* reserved word */
-
- char data[1024];
-
- /* offset into data of free format strings. Will be updated */
- /* by PUTSTRINGP macro and end up with total data length. */
- int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE;
-
- /* now send a SMBtrans command with api WGroupAdd */
-
- p = make_header(param, RAP_WGroupAdd,
- RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1);
- PUTWORD(p, 1); /* info level */
- PUTWORD(p, 0); /* reserved word 0 */
-
- p = data;
- PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN);
- PUTBYTE(p, 0); /* pad byte 0 */
- PUTSTRINGP(p, grinfo->comment, data, soffset);
-
- if (cli_api(cli,
- param, sizeof(param), 1024, /* Param, length, maxlen */
- data, soffset, sizeof(data), /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- } else if ((res == 5) || (res == 65)) {
- DEBUG(1, ("Access Denied\n"));
- }
- else if (res == 2223) {
- DEBUG (1, ("Group already exists\n"));
- }
- else {
- DEBUG(4,("NetGroupAdd res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetGroupAdd failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-call a NetGroupEnum - try and list user groups on a different host
-****************************************************************************/
-int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupEnum_REQ) /* parm string */
- +sizeof(RAP_GROUP_INFO_L1) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WGroupEnum,
- RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1);
- PUTWORD(p,1); /* Info level 1 */ /* add level 0 */
- PUTWORD(p,0xFFE0); /* Return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),8,
- NULL, 0, 0xFFE0 /* data area size */,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if(cli->rap_error == 234)
- DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
- else if (cli->rap_error != 0) {
- DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
- }
- }
-
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE; /* skip result */
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata;i<count;i++) {
- pstring comment;
- char groupname[RAP_GROUPNAME_LEN];
-
- GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
- p++; /* pad byte */
- GETSTRINGP(p, comment, rdata, converter);
-
- fn(groupname, comment, cli);
- }
- } else {
- DEBUG(4,("NetGroupEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetGroupEnum no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupDelUser_REQ) /* parm string */
- +1 /* no ret string */
- +RAP_GROUPNAME_LEN /* group name */
- +RAP_USERNAME_LEN]; /* user to del */
-
- /* now send a SMBtrans command with api GroupMemberAdd */
- p = make_header(param, RAP_WGroupDelUser, RAP_NetGroupDelUser_REQ, NULL);
- PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
- PUTSTRING(p,user_name,RAP_USERNAME_LEN);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- switch(res) {
- case 0:
- break;
- case 5:
- case 65:
- DEBUG(1, ("Access Denied\n"));
- break;
- case 50:
- DEBUG(1, ("Not supported by server\n"));
- break;
- case 2220:
- DEBUG(1, ("Group does not exist\n"));
- break;
- case 2221:
- DEBUG(1, ("User does not exist\n"));
- break;
- case 2237:
- DEBUG(1, ("User is not in group\n"));
- break;
- default:
- DEBUG(4,("NetGroupDelUser res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetGroupDelUser failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupAddUser_REQ) /* parm string */
- +1 /* no ret string */
- +RAP_GROUPNAME_LEN /* group name */
- +RAP_USERNAME_LEN]; /* user to add */
-
- /* now send a SMBtrans command with api GroupMemberAdd */
- p = make_header(param, RAP_WGroupAddUser, RAP_NetGroupAddUser_REQ, NULL);
- PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
- PUTSTRING(p,user_name,RAP_USERNAME_LEN);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- switch(res) {
- case 0:
- break;
- case 5:
- case 65:
- DEBUG(1, ("Access Denied\n"));
- break;
- case 50:
- DEBUG(1, ("Not supported by server\n"));
- break;
- case 2220:
- DEBUG(1, ("Group does not exist\n"));
- break;
- case 2221:
- DEBUG(1, ("User does not exist\n"));
- break;
- default:
- DEBUG(4,("NetGroupAddUser res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetGroupAddUser failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-
-int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*fn)(const char *, void *), void *state )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res = -1;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupGetUsers_REQ)/* parm string */
- +sizeof(RAP_GROUP_USERS_INFO_0) /* return string */
- +RAP_GROUPNAME_LEN /* group name */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
-
- /* now send a SMBtrans command with api GroupGetUsers */
- p = make_header(param, RAP_WGroupGetUsers,
- RAP_NetGroupGetUsers_REQ, RAP_GROUP_USERS_INFO_0);
- PUTSTRING(p,group_name,RAP_GROUPNAME_LEN-1);
- PUTWORD(p,0); /* info level 0 */
- PUTWORD(p,0xFFE0); /* return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),PTR_DIFF(p,param),
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetGroupGetUsers gave error %d\n", res));
- }
- }
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
- fstring username;
- p = rparam +WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata; i<count; i++) {
- GETSTRINGF(p, username, RAP_USERNAME_LEN);
- fn(username, state);
- }
- } else {
- DEBUG(4,("NetGroupGetUsers res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetGroupGetUsers no data returned\n"));
- }
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return res;
-}
-
-int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*fn)(const char *, void *), void *state )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res = -1;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetUserGetGroups_REQ)/* parm string */
- +sizeof(RAP_GROUP_USERS_INFO_0) /* return string */
- +RAP_USERNAME_LEN /* user name */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
-
- /* now send a SMBtrans command with api GroupGetUsers */
- p = make_header(param, RAP_WUserGetGroups,
- RAP_NetUserGetGroups_REQ, RAP_GROUP_USERS_INFO_0);
- PUTSTRING(p,user_name,RAP_USERNAME_LEN-1);
- PUTWORD(p,0); /* info level 0 */
- PUTWORD(p,0xFFE0); /* return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),PTR_DIFF(p,param),
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetUserGetGroups gave error %d\n", res));
- }
- }
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
- fstring groupname;
- p = rparam +WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata; i<count; i++) {
- GETSTRINGF(p, groupname, RAP_USERNAME_LEN);
- fn(groupname, state);
- }
- } else {
- DEBUG(4,("NetUserGetGroups res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetUserGetGroups no data returned\n"));
- }
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return res;
-}
-
-
-/****************************************************************************
- call a NetUserDelete - delete user from remote server
-****************************************************************************/
-int cli_NetUserDelete(struct cli_state *cli, const char * user_name )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetGroupDel_REQ) /* parm string */
- +1 /* no ret string */
- +RAP_USERNAME_LEN /* user to del */
- +WORDSIZE]; /* reserved word */
-
- /* now send a SMBtrans command with api UserDel */
- p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL);
- PUTSTRING(p, user_name, RAP_USERNAME_LEN);
- PUTWORD(p,0); /* reserved word MBZ on input */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- }
- else if ((res == 5) || (res == 65)) {
- DEBUG(1, ("Access Denied\n"));
- }
- else if (res == 2221) {
- DEBUG (1, ("User does not exist\n"));
- }
- else {
- DEBUG(4,("NetUserDelete res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetUserDelete failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
- call a NetUserAdd - add user to remote server
-****************************************************************************/
-int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )
-{
-
-
-
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetUserAdd2_REQ) /* req string */
- +sizeof(RAP_USER_INFO_L1) /* data string */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer length */
- +WORDSIZE]; /* reserved */
-
- char data[1024];
- /* offset into data of free format strings. Will be updated */
- /* by PUTSTRINGP macro and end up with total data length. */
- int soffset=RAP_USERNAME_LEN+1 /* user name + pad */
- + RAP_UPASSWD_LEN /* password */
- + DWORDSIZE /* password age */
- + WORDSIZE /* privilege */
- + DWORDSIZE /* home dir ptr */
- + DWORDSIZE /* comment ptr */
- + WORDSIZE /* flags */
- + DWORDSIZE; /* login script ptr*/
-
- /* now send a SMBtrans command with api NetUserAdd */
- p = make_header(param, RAP_WUserAdd2,
- RAP_NetUserAdd2_REQ, RAP_USER_INFO_L1);
- PUTWORD(p, 1); /* info level */
-
- PUTWORD(p, 0); /* pwencrypt */
- if(userinfo->passwrd)
- PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN));
- else
- PUTWORD(p, 0); /* password length */
-
- p = data;
- memset(data, '\0', soffset);
-
- PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN);
- PUTBYTE(p, 0); /* pad byte 0 */
- PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN);
- PUTDWORD(p, 0); /* pw age - n.a. on user add */
- PUTWORD(p, userinfo->priv);
- PUTSTRINGP(p, userinfo->home_dir, data, soffset);
- PUTSTRINGP(p, userinfo->comment, data, soffset);
- PUTWORD(p, userinfo->userflags);
- PUTSTRINGP(p, userinfo->logon_script, data, soffset);
-
- if (cli_api(cli,
- param, sizeof(param), 1024, /* Param, length, maxlen */
- data, soffset, sizeof(data), /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- }
- else if ((res == 5) || (res == 65)) {
- DEBUG(1, ("Access Denied\n"));
- }
- else if (res == 2224) {
- DEBUG (1, ("User already exists\n"));
- }
- else {
- DEBUG(4,("NetUserAdd res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetUserAdd failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-call a NetUserEnum - try and list users on a different host
-****************************************************************************/
-int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state)
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetUserEnum_REQ) /* parm string */
- +sizeof(RAP_USER_INFO_L1) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WUserEnum,
- RAP_NetUserEnum_REQ, RAP_USER_INFO_L1);
- PUTWORD(p,1); /* Info level 1 */
- PUTWORD(p,0xFF00); /* Return buffer size */
-
-/* BB Fix handling of large numbers of users to be returned */
- if (cli_api(cli,
- param, PTR_DIFF(p,param),8,
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (cli->rap_error != 0) {
- DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
- }
- }
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
- char username[RAP_USERNAME_LEN];
- char userpw[RAP_UPASSWD_LEN];
- pstring comment, homedir, logonscript;
- int pwage, priv, flags;
-
- p = rparam + WORDSIZE; /* skip result */
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata;i<count;i++) {
- GETSTRINGF(p, username, RAP_USERNAME_LEN);
- p++; /* pad byte */
- GETSTRINGF(p, userpw, RAP_UPASSWD_LEN);
- GETDWORD(p, pwage); /* password age */
- GETWORD(p, priv); /* 0=guest, 1=user, 2=admin */
- GETSTRINGP(p, homedir, rdata, converter);
- GETSTRINGP(p, comment, rdata, converter);
- GETWORD(p, flags);
- GETSTRINGP(p, logonscript, rdata, converter);
-
- fn(username, comment, homedir, logonscript, cli);
- }
- } else {
- DEBUG(4,("NetUserEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetUserEnum no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
- call a NetFileClose2 - close open file on another session to server
-****************************************************************************/
-int cli_NetFileClose(struct cli_state *cli, uint32 file_id )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WFileClose2_REQ) /* req string */
- +1 /* no ret string */
- +DWORDSIZE]; /* file ID */
- int res = -1;
-
- /* now send a SMBtrans command with api RNetShareEnum */
- p = make_header(param, RAP_WFileClose2, RAP_WFileClose2_REQ, NULL);
- PUTDWORD(p, file_id);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- } else if (res == 2314){
- DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
- } else {
- DEBUG(4,("NetFileClose2 res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetFileClose2 failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-call a NetFileGetInfo - get information about server file opened from other
- workstation
-****************************************************************************/
-int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const char *, const char *, uint16, uint16, uint32))
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WFileGetInfo2_REQ) /* req string */
- +sizeof(RAP_FILE_INFO_L3) /* return string */
- +DWORDSIZE /* file ID */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
-
- /* now send a SMBtrans command with api RNetShareEnum */
- p = make_header(param, RAP_WFileGetInfo2,
- RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3);
- PUTDWORD(p, file_id);
- PUTWORD(p, 3); /* info level */
- PUTWORD(p, 0x1000); /* buffer size */
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 0x1000, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
- if (res == 0 || res == ERRmoredata) {
- int converter,id, perms, locks;
- pstring fpath, fuser;
-
- p = rparam + WORDSIZE; /* skip result */
- GETWORD(p, converter);
-
- p = rdata;
- GETDWORD(p, id);
- GETWORD(p, perms);
- GETWORD(p, locks);
- GETSTRINGP(p, fpath, rdata, converter);
- GETSTRINGP(p, fuser, rdata, converter);
-
- fn(fpath, fuser, perms, locks, id);
- } else {
- DEBUG(4,("NetFileGetInfo2 res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetFileGetInfo2 failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-* Call a NetFileEnum2 - list open files on an SMB server
-*
-* PURPOSE: Remotes a NetFileEnum API call to the current server or target
-* server listing the files open via the network (and their
-* corresponding open instance ids)
-*
-* Dependencies: none
-*
-* Parameters:
-* cli - pointer to cli_state structure
-* user - if present, return only files opened by this remote user
-* base_path - if present, return only files opened below this
-* base path
-* fn - display function to invoke for each entry in the result
-*
-*
-* Returns:
-* True - success
-* False - failure
-*
-****************************************************************************/
-int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void (*fn)(const char *, const char *, uint16, uint16, uint32))
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WFileEnum2_REQ) /* req string */
- +sizeof(RAP_FILE_INFO_L3) /* return string */
- +256 /* base path (opt) */
- +RAP_USERNAME_LEN /* user name (opt) */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer size */
- +DWORDSIZE /* resume key ? */
- +DWORDSIZE]; /* resume key ? */
- int count = -1;
-
- /* now send a SMBtrans command with api RNetShareEnum */
- p = make_header(param, RAP_WFileEnum2,
- RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3);
-
- PUTSTRING(p, base_path, 256);
- PUTSTRING(p, user, RAP_USERNAME_LEN);
- PUTWORD(p, 3); /* info level */
- PUTWORD(p, 0xFF00); /* buffer size */
- PUTDWORD(p, 0); /* zero out the resume key */
- PUTDWORD(p, 0); /* or is this one the resume key? */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 0xFF00, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- int res = GETRES(rparam);
-
- if (res == 0 || res == ERRmoredata) {
- int converter, i;
-
- p = rparam + WORDSIZE; /* skip result */
- GETWORD(p, converter);
- GETWORD(p, count);
-
- p = rdata;
- for (i=0; i<count; i++) {
- int id, perms, locks;
- pstring fpath, fuser;
-
- GETDWORD(p, id);
- GETWORD(p, perms);
- GETWORD(p, locks);
- GETSTRINGP(p, fpath, rdata, converter);
- GETSTRINGP(p, fuser, rdata, converter);
-
- fn(fpath, fuser, perms, locks, id);
- } /* BB fix ERRmoredata case to send resume request */
- } else {
- DEBUG(4,("NetFileEnum2 res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetFileEnum2 failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return count;
-}
-
-/****************************************************************************
- call a NetShareAdd - share/export directory on remote server
-****************************************************************************/
-int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WShareAdd_REQ) /* req string */
- +sizeof(RAP_SHARE_INFO_L2) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* reserved word */
- char data[1024];
- /* offset to free format string section following fixed length data. */
- /* will be updated by PUTSTRINGP macro and will end up with total len */
- int soffset = RAP_SHARENAME_LEN + 1 /* share name + pad */
- + WORDSIZE /* share type */
- + DWORDSIZE /* comment pointer */
- + WORDSIZE /* permissions */
- + WORDSIZE /* max users */
- + WORDSIZE /* active users */
- + DWORDSIZE /* share path */
- + RAP_SPASSWD_LEN + 1; /* share password + pad */
-
- memset(param,'\0',sizeof(param));
- /* now send a SMBtrans command with api RNetShareAdd */
- p = make_header(param, RAP_WshareAdd,
- RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2);
- PUTWORD(p, 2); /* info level */
- PUTWORD(p, 0); /* reserved word 0 */
-
- p = data;
- PUTSTRINGF(p, sinfo->share_name, RAP_SHARENAME_LEN);
- PUTBYTE(p, 0); /* pad byte 0 */
-
- PUTWORD(p, sinfo->share_type);
- PUTSTRINGP(p, sinfo->comment, data, soffset);
- PUTWORD(p, sinfo->perms);
- PUTWORD(p, sinfo->maximum_users);
- PUTWORD(p, sinfo->active_users);
- PUTSTRINGP(p, sinfo->path, data, soffset);
- PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN);
- SCVAL(p,-1,0x0A); /* required 0x0A at end of password */
-
- if (cli_api(cli,
- param, sizeof(param), 1024, /* Param, length, maxlen */
- data, soffset, sizeof(data), /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = rparam? SVAL(rparam,0) : -1;
-
- if (res == 0) {
- /* nothing to do */
- }
- else {
- DEBUG(4,("NetShareAdd res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetShareAdd failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-/****************************************************************************
- call a NetShareDelete - unshare exported directory on remote server
-****************************************************************************/
-int cli_NetShareDelete(struct cli_state *cli, const char * share_name )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- int res;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WShareDel_REQ) /* req string */
- +1 /* no ret string */
- +RAP_SHARENAME_LEN /* share to del */
- +WORDSIZE]; /* reserved word */
-
-
- /* now send a SMBtrans command with api RNetShareDelete */
- p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL);
- PUTSTRING(p,share_name,RAP_SHARENAME_LEN);
- PUTWORD(p,0); /* reserved word MBZ on input */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
-
- if (res == 0) {
- /* nothing to do */
- }
- else {
- DEBUG(4,("NetShareDelete res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetShareDelete failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-/*************************************************************************
-*
-* Function Name: cli_get_pdc_name
-*
-* PURPOSE: Remotes a NetServerEnum API call to the current server
-* requesting the name of a server matching the server
-* type of SV_TYPE_DOMAIN_CTRL (PDC).
-*
-* Dependencies: none
-*
-* Parameters:
-* cli - pointer to cli_state structure
-* workgroup - pointer to string containing name of domain
-* pdc_name - pointer to string that will contain PDC name
-* on successful return
-*
-* Returns:
-* True - success
-* False - failure
-*
-************************************************************************/
-BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rdrcnt,rprcnt;
- char *p;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetServerEnum2_REQ) /* req string */
- +sizeof(RAP_SERVER_INFO_L1) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer size */
- +DWORDSIZE /* server type */
- +RAP_MACHNAME_LEN]; /* workgroup */
- int count = -1;
-
- *pdc_name = '\0';
-
- /* send a SMBtrans command with api NetServerEnum */
- p = make_header(param, RAP_NetServerEnum2,
- RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1);
- PUTWORD(p, 1); /* info level */
- PUTWORD(p, CLI_BUFFER_SIZE);
- PUTDWORD(p, SV_TYPE_DOMAIN_CTRL);
- PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 8, /* params, length, max */
- NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
- &rparam, &rprcnt, /* return params, return size */
- &rdata, &rdrcnt /* return data, return size */
- )) {
- cli->rap_error = GETRES(rparam);
-
- /*
- * We only really care to copy a name if the
- * API succeeded and we got back a name.
- */
- if (cli->rap_error == 0) {
- p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
- GETWORD(p, count);
- p = rdata;
-
- if (count > 0)
- GETSTRING(p, pdc_name);
- }
- else {
- DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
- "Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
- }
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return(count > 0);
-}
-
-
-/*************************************************************************
-*
-* Function Name: cli_get_server_domain
-*
-* PURPOSE: Remotes a NetWkstaGetInfo API call to the current server
-* requesting wksta_info_10 level information to determine
-* the domain the server belongs to. On success, this
-* routine sets the server_domain field in the cli_state structure
-* to the server's domain name.
-*
-* Dependencies: none
-*
-* Parameters:
-* cli - pointer to cli_state structure
-*
-* Returns:
-* True - success
-* False - failure
-*
-* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
-*
-************************************************************************/
-BOOL cli_get_server_domain(struct cli_state *cli)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rdrcnt,rprcnt;
- char *p;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WWkstaGetInfo_REQ) /* req string */
- +sizeof(RAP_WKSTA_INFO_L10) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- int res = -1;
-
- /* send a SMBtrans command with api NetWkstaGetInfo */
- p = make_header(param, RAP_WWkstaGetInfo,
- RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10);
- PUTWORD(p, 10); /* info level */
- PUTWORD(p, CLI_BUFFER_SIZE);
-
- if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */
- NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
- &rparam, &rprcnt, /* return params, return size */
- &rdata, &rdrcnt)) { /* return data, return size */
- res = GETRES(rparam);
- p = rdata;
-
- if (res == 0) {
- int converter;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
-
- p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */
- GETSTRINGP(p, cli->server_domain, rdata, converter);
- }
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return(res == 0);
-}
-
-
-/*************************************************************************
-*
-* Function Name: cli_get_server_type
-*
-* PURPOSE: Remotes a NetServerGetInfo API call to the current server
-* requesting server_info_1 level information to retrieve
-* the server type.
-*
-* Dependencies: none
-*
-* Parameters:
-* cli - pointer to cli_state structure
-* pstype - pointer to uint32 to contain returned server type
-*
-* Returns:
-* True - success
-* False - failure
-*
-* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
-*
-************************************************************************/
-BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rdrcnt,rprcnt;
- char *p;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_WserverGetInfo_REQ) /* req string */
- +sizeof(RAP_SERVER_INFO_L1) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- int res = -1;
-
- /* send a SMBtrans command with api NetServerGetInfo */
- p = make_header(param, RAP_WserverGetInfo,
- RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1);
- PUTWORD(p, 1); /* info level */
- PUTWORD(p, CLI_BUFFER_SIZE);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 8, /* params, length, max */
- NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
- &rparam, &rprcnt, /* return params, return size */
- &rdata, &rdrcnt /* return data, return size */
- )) {
-
- res = GETRES(rparam);
-
- if (res == 0 || res == ERRmoredata) {
- p = rdata;
- *pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
- }
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return(res == 0 || res == ERRmoredata);
-}
-
-
-/*************************************************************************
-*
-* Function Name: cli_ns_check_server_type
-*
-* PURPOSE: Remotes a NetServerEnum2 API call to the current server
-* requesting server_info_0 level information of machines
-* matching the given server type. If the returned server
-* list contains the machine name contained in cli->desthost
-* then we conclude the server type checks out. This routine
-* is useful to retrieve list of server's of a certain
-* type when all you have is a null session connection and
-* can't remote API calls such as NetWkstaGetInfo or
-* NetServerGetInfo.
-*
-* Dependencies: none
-*
-* Parameters:
-* cli - pointer to cli_state structure
-* workgroup - pointer to string containing domain
-* stype - server type
-*
-* Returns:
-* True - success
-* False - failure
-*
-************************************************************************/
-BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rdrcnt,rprcnt;
- char *p;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetServerEnum2_REQ) /* req string */
- +sizeof(RAP_SERVER_INFO_L0) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer size */
- +DWORDSIZE /* server type */
- +RAP_MACHNAME_LEN]; /* workgroup */
- BOOL found_server = False;
- int res = -1;
-
- /* send a SMBtrans command with api NetServerEnum */
- p = make_header(param, RAP_NetServerEnum2,
- RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0);
- PUTWORD(p, 0); /* info level 0 */
- PUTWORD(p, CLI_BUFFER_SIZE);
- PUTDWORD(p, stype);
- PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 8, /* params, length, max */
- NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
- &rparam, &rprcnt, /* return params, return size */
- &rdata, &rdrcnt /* return data, return size */
- )) {
-
- res = GETRES(rparam);
- cli->rap_error = res;
-
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- p = rdata;
- for (i = 0;i < count;i++, p += 16) {
- char ret_server[RAP_MACHNAME_LEN];
-
- GETSTRINGF(p, ret_server, RAP_MACHNAME_LEN);
- if (strequal(ret_server, cli->desthost)) {
- found_server = True;
- break;
- }
- }
- }
- else {
- DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
- "Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
- }
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return found_server;
- }
-
-
-/****************************************************************************
- perform a NetWkstaUserLogoff
-****************************************************************************/
-BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- unsigned int rdrcnt,rprcnt;
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */
- +sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */
- +RAP_USERNAME_LEN+1 /* user name+pad */
- +RAP_MACHNAME_LEN /* wksta name */
- +WORDSIZE /* buffer size */
- +WORDSIZE]; /* buffer size? */
- fstring upperbuf;
-
- memset(param, 0, sizeof(param));
-
- /* send a SMBtrans command with api NetWkstaUserLogoff */
- p = make_header(param, RAP_WWkstaUserLogoff,
- RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1);
- PUTDWORD(p, 0); /* Null pointer */
- PUTDWORD(p, 0); /* Null pointer */
- fstrcpy(upperbuf, user);
- strupper_m(upperbuf);
- PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN);
- p++; /* strange format, but ok */
- fstrcpy(upperbuf, workstation);
- strupper_m(upperbuf);
- PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN);
- PUTWORD(p, CLI_BUFFER_SIZE);
- PUTWORD(p, CLI_BUFFER_SIZE);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),1024, /* param, length, max */
- NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
- &rparam, &rprcnt, /* return params, return size */
- &rdata, &rdrcnt /* return data, return size */
- )) {
- cli->rap_error = GETRES(rparam);
-
- if (cli->rap_error != 0) {
- DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error));
- }
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
- return (cli->rap_error == 0);
-}
-
-int cli_NetPrintQEnum(struct cli_state *cli,
- void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
- void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetPrintQEnum_REQ) /* req string */
- +sizeof(RAP_PRINTQ_INFO_L2) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer size */
- +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0',sizeof(param));
- p = make_header(param, RAP_WPrintQEnum,
- RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2);
- PUTWORD(p,2); /* Info level 2 */
- PUTWORD(p,0xFFE0); /* Return buffer size */
- PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),1024,
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetPrintQEnum gave error %d\n", res));
- }
- }
-
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- p = rdata;
- for (i=0;i<count;i++) {
- pstring qname, sep_file, print_proc, dest, parms, comment;
- uint16 jobcount, priority, start_time, until_time, status;
-
- GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
- p++; /* pad */
- GETWORD(p, priority);
- GETWORD(p, start_time);
- GETWORD(p, until_time);
- GETSTRINGP(p, sep_file, rdata, converter);
- GETSTRINGP(p, print_proc, rdata, converter);
- GETSTRINGP(p, dest, rdata, converter);
- GETSTRINGP(p, parms, rdata, converter);
- GETSTRINGP(p, parms, comment, converter);
- GETWORD(p, status);
- GETWORD(p, jobcount);
-
- qfn(qname, priority, start_time, until_time, sep_file, print_proc,
- dest, parms, comment, status, jobcount);
-
- if (jobcount) {
- int j;
- for (j=0;j<jobcount;j++) {
- uint16 jid, pos, fsstatus;
- pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
- unsigned int submitted, jsize;
-
- GETWORD(p, jid);
- GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
- p++; /* pad byte */
- GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
- GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
- GETSTRINGP(p, jparms, rdata, converter);
- GETWORD(p, pos);
- GETWORD(p, fsstatus);
- GETSTRINGP(p, jstatus, rdata, converter);
- GETDWORD(p, submitted);
- GETDWORD(p, jsize);
- GETSTRINGP(p, jcomment, rdata, converter);
-
- jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
- jstatus, submitted, jsize, jcomment);
- }
- }
- }
- } else {
- DEBUG(4,("NetPrintQEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetPrintQEnum no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer,
- void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
- void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetPrintQGetInfo_REQ) /* req string */
- +sizeof(RAP_PRINTQ_INFO_L2) /* return string */
- +RAP_SHARENAME_LEN /* printer name */
- +WORDSIZE /* info level */
- +WORDSIZE /* buffer size */
- +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0',sizeof(param));
- p = make_header(param, RAP_WPrintQGetInfo,
- RAP_NetPrintQGetInfo_REQ, RAP_PRINTQ_INFO_L2);
- PUTSTRING(p, printer, RAP_SHARENAME_LEN-1);
- PUTWORD(p, 2); /* Info level 2 */
- PUTWORD(p,0xFFE0); /* Return buffer size */
- PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),1024,
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetPrintQGetInfo gave error %d\n", res));
- }
- }
-
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int rsize, converter;
- pstring qname, sep_file, print_proc, dest, parms, comment;
- uint16 jobcount, priority, start_time, until_time, status;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, rsize);
-
- p = rdata;
- GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
- p++; /* pad */
- GETWORD(p, priority);
- GETWORD(p, start_time);
- GETWORD(p, until_time);
- GETSTRINGP(p, sep_file, rdata, converter);
- GETSTRINGP(p, print_proc, rdata, converter);
- GETSTRINGP(p, dest, rdata, converter);
- GETSTRINGP(p, parms, rdata, converter);
- GETSTRINGP(p, comment, rdata, converter);
- GETWORD(p, status);
- GETWORD(p, jobcount);
- qfn(qname, priority, start_time, until_time, sep_file, print_proc,
- dest, parms, comment, status, jobcount);
- if (jobcount) {
- int j;
- for (j=0;(j<jobcount)&&(PTR_DIFF(p,rdata)< rsize);j++) {
- uint16 jid, pos, fsstatus;
- pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
- unsigned int submitted, jsize;
-
- GETWORD(p, jid);
- GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
- p++; /* pad byte */
- GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
- GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
- GETSTRINGP(p, jparms, rdata, converter);
- GETWORD(p, pos);
- GETWORD(p, fsstatus);
- GETSTRINGP(p, jstatus, rdata, converter);
- GETDWORD(p, submitted);
- GETDWORD(p, jsize);
- GETSTRINGP(p, jcomment, rdata, converter);
-
- jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
- jstatus, submitted, jsize, jcomment);
- }
- }
- } else {
- DEBUG(4,("NetPrintQGetInfo res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetPrintQGetInfo no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-call a NetServiceEnum - list running services on a different host
-****************************************************************************/
-int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetServiceEnum_REQ) /* parm string */
- +sizeof(RAP_SERVICE_INFO_L2) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WServiceEnum,
- RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2);
- PUTWORD(p,2); /* Info level 2 */
- PUTWORD(p,0xFFE0); /* Return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),8,
- NULL, 0, 0xFFE0 /* data area size */,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if(cli->rap_error == 234)
- DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
- else if (cli->rap_error != 0) {
- DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error));
- }
- }
-
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE; /* skip result */
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata;i<count;i++) {
- pstring comment;
- char servicename[RAP_SRVCNAME_LEN];
-
- GETSTRINGF(p, servicename, RAP_SRVCNAME_LEN);
- p+=8; /* pass status words */
- GETSTRINGF(p, comment, RAP_SRVCCMNT_LEN);
-
- fn(servicename, comment, cli); /* BB add status too */
- }
- } else {
- DEBUG(4,("NetServiceEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetServiceEnum no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-
-/****************************************************************************
-call a NetSessionEnum - list workstations with sessions to an SMB server
-****************************************************************************/
-int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, uint, uint, uint, char *))
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetSessionEnum_REQ) /* parm string */
- +sizeof(RAP_SESSION_INFO_L2) /* return string */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WsessionEnum,
- RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2);
- PUTWORD(p,2); /* Info level 2 */
- PUTWORD(p,0xFF); /* Return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),8,
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetSessionEnum gave error %d\n", res));
- }
- }
-
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata;i<count;i++) {
- pstring wsname, username, clitype_name;
- uint16 num_conns, num_opens, num_users;
- unsigned int sess_time, idle_time, user_flags;
-
- GETSTRINGP(p, wsname, rdata, converter);
- GETSTRINGP(p, username, rdata, converter);
- GETWORD(p, num_conns);
- GETWORD(p, num_opens);
- GETWORD(p, num_users);
- GETDWORD(p, sess_time);
- GETDWORD(p, idle_time);
- GETDWORD(p, user_flags);
- GETSTRINGP(p, clitype_name, rdata, converter);
-
- fn(wsname, username, num_conns, num_opens, num_users, sess_time,
- idle_time, user_flags, clitype_name);
- }
-
- } else {
- DEBUG(4,("NetSessionEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetSesssionEnum no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
- Call a NetSessionGetInfo - get information about other session to an SMB server.
-****************************************************************************/
-
-int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void (*fn)(const char *, const char *, uint16, uint16, uint16, uint, uint, uint, const char *))
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetSessionGetInfo_REQ) /* req string */
- +sizeof(RAP_SESSION_INFO_L2) /* return string */
- +RAP_MACHNAME_LEN /* wksta name */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WsessionGetInfo,
- RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2);
- PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
- PUTWORD(p,2); /* Info level 2 */
- PUTWORD(p,0xFF); /* Return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),PTR_DIFF(p,param),
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- cli->rap_error = SVAL(rparam,0);
- if (cli->rap_error != 0) {
- DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error));
- }
- }
-
- if (rdata) {
- res = GETRES(rparam);
-
- if (res == 0 || res == ERRmoredata) {
- int rsize, converter;
- pstring wsname, username, clitype_name;
- uint16 num_conns, num_opens, num_users;
- unsigned int sess_time, idle_time, user_flags;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, rsize);
-
- p = rdata;
- GETSTRINGP(p, wsname, rdata, converter);
- GETSTRINGP(p, username, rdata, converter);
- GETWORD(p, num_conns);
- GETWORD(p, num_opens);
- GETWORD(p, num_users);
- GETDWORD(p, sess_time);
- GETDWORD(p, idle_time);
- GETDWORD(p, user_flags);
- GETSTRINGP(p, clitype_name, rdata, converter);
-
- fn(wsname, username, num_conns, num_opens, num_users, sess_time,
- idle_time, user_flags, clitype_name);
- } else {
- DEBUG(4,("NetSessionGetInfo res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetSessionGetInfo no data returned\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-/****************************************************************************
-call a NetSessionDel - close a session to an SMB server
-****************************************************************************/
-int cli_NetSessionDel(struct cli_state *cli, const char *workstation)
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetSessionDel_REQ) /* req string */
- +1 /* no return string */
- +RAP_MACHNAME_LEN /* workstation name */
- +WORDSIZE]; /* reserved (0) */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res;
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL);
- PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
- PUTWORD(p,0); /* reserved word of 0 */
- if (cli_api(cli,
- param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 200, /* data, length, maxlen */
- &rparam, &rprcnt, /* return params, length */
- &rdata, &rdrcnt)) /* return data, length */
- {
- res = GETRES(rparam);
- cli->rap_error = res;
-
- if (res == 0) {
- /* nothing to do */
- }
- else {
- DEBUG(4,("NetFileClose2 res=%d\n", res));
- }
- } else {
- res = -1;
- DEBUG(4,("NetFileClose2 failed\n"));
- }
-
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
-
- return res;
-}
-
-
-int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, const char *username, const char *netname))
-{
- char param[WORDSIZE /* api number */
- +sizeof(RAP_NetConnectionEnum_REQ) /* req string */
- +sizeof(RAP_CONNECTION_INFO_L1) /* return string */
- +RAP_MACHNAME_LEN /* wksta name */
- +WORDSIZE /* info level */
- +WORDSIZE]; /* buffer size */
- char *p;
- char *rparam = NULL;
- char *rdata = NULL;
- unsigned int rprcnt, rdrcnt;
- int res = -1;
-
- memset(param, '\0', sizeof(param));
- p = make_header(param, RAP_WconnectionEnum,
- RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1);
- PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */
- PUTWORD(p,1); /* Info level 1 */
- PUTWORD(p,0xFFE0); /* Return buffer size */
-
- if (cli_api(cli,
- param, PTR_DIFF(p,param),PTR_DIFF(p,param),
- NULL, 0, CLI_BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt)) {
- res = GETRES(rparam);
- cli->rap_error = res;
- if (res != 0) {
- DEBUG(1,("NetConnectionEnum gave error %d\n", res));
- }
- }
- if (rdata) {
- if (res == 0 || res == ERRmoredata) {
- int i, converter, count;
-
- p = rparam + WORDSIZE;
- GETWORD(p, converter);
- GETWORD(p, count);
-
- for (i=0,p=rdata;i<count;i++) {
- pstring netname, username;
- uint16 conn_id, conn_type, num_opens, num_users;
- unsigned int conn_time;
-
- GETWORD(p,conn_id);
- GETWORD(p,conn_type);
- GETWORD(p,num_opens);
- GETWORD(p,num_users);
- GETDWORD(p,conn_time);
- GETSTRINGP(p, username, rdata, converter);
- GETSTRINGP(p, netname, rdata, converter);
-
- fn(conn_id, conn_type, num_opens, num_users, conn_time,
- username, netname);
- }
-
- } else {
- DEBUG(4,("NetConnectionEnum res=%d\n", res));
- }
- } else {
- DEBUG(4,("NetConnectionEnum no data returned\n"));
- }
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return res;
-}
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 8eac7d07d8b..0cb1a81a8b8 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client file read/write routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -50,9 +51,41 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
SSVAL(cli->outbuf,smb_vwv6,size);
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
+#ifdef LARGE_SMB_OFF_T
+ /*
+ * We only want to do the following if we understand large offsets
+ * otherwise the compiler is likely to get upset with us
+ */
if (bigoffset)
SIVAL(cli->outbuf,smb_vwv10,(offset>>32) & 0xffffffff);
+#endif /* LARGE_SMB_OFF_T */
+
+ return cli_send_smb(cli);
+}
+
+/****************************************************************************
+Issue a single SMBreadraw and don't wait for a reply.
+****************************************************************************/
+
+static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
+ size_t size, int i)
+{
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
+
+ set_message(cli->outbuf,10,0,True);
+
+ SCVAL(cli->outbuf,smb_com,SMBreadbraw);
+ SSVAL(cli->outbuf,smb_tid,cli->cnum);
+ cli_setup_packet(cli);
+
+ SSVAL(cli->outbuf,smb_vwv0,fnum);
+ SIVAL(cli->outbuf,smb_vwv1,offset);
+ SSVAL(cli->outbuf,smb_vwv2,size);
+ SSVAL(cli->outbuf,smb_vwv3,size);
+ SSVAL(cli->outbuf,smb_mid,cli->mid + i);
+
return cli_send_smb(cli);
}
@@ -92,7 +125,6 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
errors. */
if (cli_is_error(cli)) {
- BOOL recoverable_error = False;
NTSTATUS status = NT_STATUS_OK;
uint8 eclass = 0;
uint32 ecode = 0;
@@ -102,17 +134,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
else
cli_dos_error(cli, &eclass, &ecode);
- /*
- * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a
- * recoverable error, plus we have valid data in the
- * packet so don't error out here.
- */
-
if ((eclass == ERRDOS && ecode == ERRmoredata) ||
NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES))
- recoverable_error = True;
-
- if (!recoverable_error)
return -1;
}
@@ -145,43 +168,6 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
return total;
}
-#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */
-
-/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0
- you must fix ensure you don't attempt to sign the packets - data
- *will* be currupted */
-
-/****************************************************************************
-Issue a single SMBreadraw and don't wait for a reply.
-****************************************************************************/
-
-static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
- size_t size, int i)
-{
-
- if (!cli->sign_info.use_smb_signing) {
- DEBUG(0, ("Cannot use readraw and SMB Signing\n"));
- return False;
- }
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf,10,0,True);
-
- SCVAL(cli->outbuf,smb_com,SMBreadbraw);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf,smb_vwv0,fnum);
- SIVAL(cli->outbuf,smb_vwv1,offset);
- SSVAL(cli->outbuf,smb_vwv2,size);
- SSVAL(cli->outbuf,smb_vwv3,size);
- SSVAL(cli->outbuf,smb_mid,cli->mid + i);
-
- return cli_send_smb(cli);
-}
-
/****************************************************************************
Tester for the readraw call.
****************************************************************************/
@@ -243,13 +229,12 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si
return total;
}
-#endif
+
/****************************************************************************
issue a single SMBwrite and don't wait for a reply
****************************************************************************/
-static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
- uint16 mode, const char *buf,
+static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf,
size_t size, int i)
{
char *p;
@@ -285,21 +270,24 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
SIVAL(cli->outbuf,smb_vwv5,0);
SSVAL(cli->outbuf,smb_vwv7,mode);
- SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0);
/*
- * According to CIFS-TR-1p00, this following field should only
- * be set if CAP_LARGE_WRITEX is set. We should check this
- * locally. However, this check might already have been
- * done by our callers.
+ * THe following is still wrong ...
*/
+ SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0);
SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1));
SSVAL(cli->outbuf,smb_vwv10,size);
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
+#ifdef LARGE_SMB_OFF_T
+ /*
+ * We only want to do the following if we understand large offsets
+ * otherwise the compiler is likely to get upset with us
+ */
if (bigoffset)
SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff);
-
+#endif /* LARGE_SMB_OFF_T */
+
p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11);
memcpy(p, buf, size);
cli_setup_bcc(cli, p+size);
@@ -320,13 +308,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
- const char *buf, off_t offset, size_t size)
+ char *buf, off_t offset, size_t size)
{
int bwritten = 0;
int issued = 0;
int received = 0;
int mpx = MAX(cli->max_mux-1, 1);
- int block = cli->max_xmit - (smb_size+32);
+ int block = (cli->max_xmit - (smb_size+32)) & ~1023;
int blocks = (size + (block-1)) / block;
while (received < blocks) {
diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c
index 2989966f4de..8c8b2fb9754 100644
--- a/source/libsmb/clisecdesc.c
+++ b/source/libsmb/clisecdesc.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client security descriptor functions
Copyright (C) Andrew Tridgell 2000
@@ -28,12 +29,12 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
{
char param[8];
char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
+ int rparam_count=0, rdata_count=0;
prs_struct pd;
SEC_DESC *psd = NULL;
SIVAL(param, 0, fnum);
- SIVAL(param, 4, 0x7);
+ SSVAL(param, 4, 0x7);
if (!cli_send_nt_trans(cli,
NT_TRANSACT_QUERY_SECURITY_DESC,
@@ -54,8 +55,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
}
prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL);
- prs_copy_data_in(&pd, rdata, rdata_count);
- prs_set_offset(&pd,0);
+ prs_append_data(&pd, rdata, rdata_count);
+ pd.data_offset = 0;
if (!sec_io_desc("sd data", &psd, &pd, 1)) {
DEBUG(1,("Failed to parse secdesc\n"));
@@ -78,13 +79,13 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
{
char param[8];
char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
+ int rparam_count=0, rdata_count=0;
uint32 sec_info = 0;
TALLOC_CTX *mem_ctx;
prs_struct pd;
BOOL ret = False;
- if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) {
+ if ((mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("talloc_init failed.\n"));
goto cleanup;
}
@@ -112,7 +113,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
0,
NULL, 0, 0,
param, 8, 0,
- prs_data_p(&pd), prs_offset(&pd), 0)) {
+ pd.data_p, pd.data_offset, 0)) {
DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n"));
goto cleanup;
}
diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c
index e6cadc466c1..512a2f60332 100644
--- a/source/libsmb/clispnego.c
+++ b/source/libsmb/clispnego.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
simple kerberos5/SPNEGO routines
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
- Copyright (C) Luke Howard 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -74,56 +73,13 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16],
return ret;
}
-/*
- Generate a negTokenInit as used by the client side ... It has a mechType
- (OID), and a mechToken (a security blob) ...
-
- Really, we need to break out the NTLMSSP stuff as well, because it could be
- raw in the packets!
-*/
-DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob)
-{
- ASN1_DATA data;
- DATA_BLOB ret;
-
- memset(&data, 0, sizeof(data));
-
- asn1_push_tag(&data, ASN1_APPLICATION(0));
- asn1_write_OID(&data,OID_SPNEGO);
- asn1_push_tag(&data, ASN1_CONTEXT(0));
- asn1_push_tag(&data, ASN1_SEQUENCE(0));
-
- asn1_push_tag(&data, ASN1_CONTEXT(0));
- asn1_push_tag(&data, ASN1_SEQUENCE(0));
- asn1_write_OID(&data, OID);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
-
- asn1_push_tag(&data, ASN1_CONTEXT(2));
- asn1_write_OctetString(&data,blob.data,blob.length);
- asn1_pop_tag(&data);
-
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
-
- asn1_pop_tag(&data);
-
- if (data.has_error) {
- DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs));
- asn1_free(&data);
- }
-
- ret = data_blob(data.data, data.length);
- asn1_free(&data);
-
- return ret;
-}
/*
parse a negTokenInit packet giving a GUID, a list of supported
OIDs (the mechanisms) and a principal name string
*/
BOOL spnego_parse_negTokenInit(DATA_BLOB blob,
+ uint8 guid[16],
char *OIDs[ASN1_MAX_OIDS],
char **principal)
{
@@ -133,6 +89,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob,
asn1_load(&data, blob);
+ asn1_read(&data, guid, 16);
asn1_start_tag(&data,ASN1_APPLICATION(0));
asn1_check_OID(&data,OID_SPNEGO);
asn1_start_tag(&data,ASN1_CONTEXT(0));
@@ -260,7 +217,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
/*
generate a krb5 GSS-API wrapper packet given a ticket
*/
-DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2])
+static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket)
{
ASN1_DATA data;
DATA_BLOB ret;
@@ -269,8 +226,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2])
asn1_push_tag(&data, ASN1_APPLICATION(0));
asn1_write_OID(&data, OID_KERBEROS5);
-
- asn1_write(&data, tok_id, 2);
+ asn1_write_BOOLEAN(&data, 0);
asn1_write(&data, ticket.data, ticket.length);
asn1_pop_tag(&data);
@@ -288,24 +244,23 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2])
/*
parse a krb5 GSS-API wrapper packet giving a ticket
*/
-BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
+BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket)
{
BOOL ret;
ASN1_DATA data;
- int data_remaining;
+ int ata_remaining;
asn1_load(&data, blob);
asn1_start_tag(&data, ASN1_APPLICATION(0));
asn1_check_OID(&data, OID_KERBEROS5);
+ asn1_check_BOOLEAN(&data, 0);
data_remaining = asn1_tag_remaining(&data);
- if (data_remaining < 3) {
+ if (data_remaining < 1) {
data.has_error = True;
} else {
- asn1_read(&data, tok_id, 2);
- data_remaining -= 2;
- *ticket = data_blob(NULL, data_remaining);
+ *ticket = data_blob(data.data, data_remaining);
asn1_read(&data, ticket->data, ticket->length);
}
@@ -323,37 +278,31 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
kerberos session setup
*/
-int spnego_gen_negTokenTarg(const char *principal, int time_offset,
- DATA_BLOB *targ,
- DATA_BLOB *session_key_krb5)
+DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal)
{
- int retval;
- DATA_BLOB tkt, tkt_wrapped;
+ DATA_BLOB tkt, tkt_wrapped, targ;
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
- /* get a kerberos ticket for the service and extract the session key */
- retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5);
-
- if (retval)
- return retval;
+ /* get a kerberos ticket for the service */
+ tkt = krb5_get_ticket(principal);
/* wrap that up in a nice GSS-API wrapping */
- tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
+ tkt_wrapped = spnego_gen_krb5_wrap(tkt);
/* and wrap that in a shiny SPNEGO wrapper */
- *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
+ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
data_blob_free(&tkt_wrapped);
data_blob_free(&tkt);
- return retval;
+ return targ;
}
/*
parse a spnego NTLMSSP challenge packet giving two security blobs
*/
-BOOL spnego_parse_challenge(const DATA_BLOB blob,
+BOOL spnego_parse_challenge(DATA_BLOB blob,
DATA_BLOB *chal1, DATA_BLOB *chal2)
{
BOOL ret;
@@ -395,7 +344,52 @@ BOOL spnego_parse_challenge(const DATA_BLOB blob,
/*
- generate a SPNEGO auth packet. This will contain the encrypted passwords
+ generate a spnego NTLMSSP challenge packet given two security blobs
+ The second challenge is optional
+*/
+BOOL spnego_gen_challenge(DATA_BLOB *blob,
+ DATA_BLOB *chal1, DATA_BLOB *chal2)
+{
+ ASN1_DATA data;
+
+ ZERO_STRUCT(data);
+
+ asn1_push_tag(&data,ASN1_CONTEXT(1));
+ asn1_push_tag(&data,ASN1_SEQUENCE(0));
+
+ asn1_push_tag(&data,ASN1_CONTEXT(0));
+ asn1_write_enumerated(&data,1);
+ asn1_pop_tag(&data);
+
+ asn1_push_tag(&data,ASN1_CONTEXT(1));
+ asn1_write_OID(&data, OID_NTLMSSP);
+ asn1_pop_tag(&data);
+
+ asn1_push_tag(&data,ASN1_CONTEXT(2));
+ asn1_write_OctetString(&data, chal1->data, chal1->length);
+ asn1_pop_tag(&data);
+
+ /* the second challenge is optional (XP doesn't send it) */
+ if (chal2) {
+ asn1_push_tag(&data,ASN1_CONTEXT(3));
+ asn1_write_OctetString(&data, chal2->data, chal2->length);
+ asn1_pop_tag(&data);
+ }
+
+ asn1_pop_tag(&data);
+ asn1_pop_tag(&data);
+
+ if (data.has_error) {
+ return False;
+ }
+
+ *blob = data_blob(data.data, data.length);
+ asn1_free(&data);
+ return True;
+}
+
+/*
+ generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
{
@@ -420,7 +414,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
}
/*
- parse a SPNEGO auth packet. This contains the encrypted passwords
+ parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords
*/
BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
{
@@ -445,95 +439,186 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
return True;
}
+
/*
- generate a minimal SPNEGO response packet. Doesn't contain much.
-*/
-DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status,
- const char *mechOID)
+ this is a tiny msrpc packet generator. I am only using this to
+ avoid tying this code to a particular varient of our rpc code. This
+ generator is not general enough for all our rpc needs, its just
+ enough for the spnego/ntlmssp code
+
+ format specifiers are:
+
+ U = unicode string (input is unix string)
+ B = data blob (pointer + length)
+ b = data blob in header (pointer + length)
+ d = word (4 bytes)
+ C = constant ascii string
+ */
+BOOL msrpc_gen(DATA_BLOB *blob,
+ const char *format, ...)
{
- ASN1_DATA data;
- DATA_BLOB ret;
- uint8 negResult;
-
- if (NT_STATUS_IS_OK(nt_status)) {
- negResult = SPNEGO_NEG_RESULT_ACCEPT;
- } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- negResult = SPNEGO_NEG_RESULT_INCOMPLETE;
- } else {
- negResult = SPNEGO_NEG_RESULT_REJECT;
+ int i, n;
+ va_list ap;
+ char *s;
+ uint8 *b;
+ int head_size=0, data_size=0;
+ int head_ofs, data_ofs;
+
+ /* first scan the format to work out the header and body size */
+ va_start(ap, format);
+ for (i=0; format[i]; i++) {
+ switch (format[i]) {
+ case 'U':
+ s = va_arg(ap, char *);
+ head_size += 8;
+ data_size += str_charnum(s) * 2;
+ break;
+ case 'B':
+ b = va_arg(ap, uint8 *);
+ head_size += 8;
+ data_size += va_arg(ap, int);
+ break;
+ case 'b':
+ b = va_arg(ap, uint8 *);
+ head_size += va_arg(ap, int);
+ break;
+ case 'd':
+ n = va_arg(ap, int);
+ head_size += 4;
+ break;
+ case 'C':
+ s = va_arg(ap, char *);
+ head_size += str_charnum(s) + 1;
+ break;
+ }
}
-
- ZERO_STRUCT(data);
-
- asn1_push_tag(&data, ASN1_CONTEXT(1));
- asn1_push_tag(&data, ASN1_SEQUENCE(0));
- asn1_push_tag(&data, ASN1_CONTEXT(0));
- asn1_write_enumerated(&data, negResult);
- asn1_pop_tag(&data);
-
- if (reply->data != NULL) {
- asn1_push_tag(&data,ASN1_CONTEXT(1));
- asn1_write_OID(&data, mechOID);
- asn1_pop_tag(&data);
-
- asn1_push_tag(&data,ASN1_CONTEXT(2));
- asn1_write_OctetString(&data, reply->data, reply->length);
- asn1_pop_tag(&data);
+ va_end(ap);
+
+ /* allocate the space, then scan the format again to fill in the values */
+ blob->data = malloc(head_size + data_size);
+ blob->length = head_size + data_size;
+ if (!blob->data) return False;
+
+ head_ofs = 0;
+ data_ofs = head_size;
+
+ va_start(ap, format);
+ for (i=0; format[i]; i++) {
+ switch (format[i]) {
+ case 'U':
+ s = va_arg(ap, char *);
+ n = str_charnum(s);
+ SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
+ SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
+ SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
+ push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
+ data_ofs += n*2;
+ break;
+ case 'B':
+ b = va_arg(ap, uint8 *);
+ n = va_arg(ap, int);
+ SSVAL(blob->data, head_ofs, n); head_ofs += 2;
+ SSVAL(blob->data, head_ofs, n); head_ofs += 2;
+ SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
+ memcpy(blob->data+data_ofs, b, n);
+ data_ofs += n;
+ break;
+ case 'd':
+ n = va_arg(ap, int);
+ SIVAL(blob->data, head_ofs, n); head_ofs += 4;
+ break;
+ case 'b':
+ b = va_arg(ap, uint8 *);
+ n = va_arg(ap, int);
+ memcpy(blob->data + head_ofs, b, n);
+ head_ofs += n;
+ break;
+ case 'C':
+ s = va_arg(ap, char *);
+ head_ofs += push_string(NULL, blob->data+head_ofs, s, -1,
+ STR_ASCII|STR_TERMINATE);
+ break;
+ }
}
+ va_end(ap);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
-
- ret = data_blob(data.data, data.length);
- asn1_free(&data);
- return ret;
+ return True;
}
+
/*
- parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords
-*/
-BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
- DATA_BLOB *auth)
+ this is a tiny msrpc packet parser. This the the partner of msrpc_gen
+
+ format specifiers are:
+
+ U = unicode string (input is unix string)
+ B = data blob
+ b = data blob in header
+ d = word (4 bytes)
+ C = constant ascii string
+ */
+BOOL msrpc_parse(DATA_BLOB *blob,
+ const char *format, ...)
{
- ASN1_DATA data;
- uint8 negResult;
-
- if (NT_STATUS_IS_OK(nt_status)) {
- negResult = SPNEGO_NEG_RESULT_ACCEPT;
- } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- negResult = SPNEGO_NEG_RESULT_INCOMPLETE;
- } else {
- negResult = SPNEGO_NEG_RESULT_REJECT;
- }
-
- asn1_load(&data, blob);
- asn1_start_tag(&data, ASN1_CONTEXT(1));
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_CONTEXT(0));
- asn1_check_enumerated(&data, negResult);
- asn1_end_tag(&data);
-
- if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) {
- asn1_start_tag(&data,ASN1_CONTEXT(1));
- asn1_check_OID(&data, OID_NTLMSSP);
- asn1_end_tag(&data);
-
- asn1_start_tag(&data,ASN1_CONTEXT(2));
- asn1_read_OctetString(&data, auth);
- asn1_end_tag(&data);
- }
-
- asn1_end_tag(&data);
- asn1_end_tag(&data);
-
- if (data.has_error) {
- DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs));
- asn1_free(&data);
- data_blob_free(auth);
- return False;
+ int i;
+ va_list ap;
+ char **ps, *s;
+ DATA_BLOB *b;
+ int head_ofs = 0;
+ uint16 len1, len2;
+ uint32 ptr;
+ uint32 *v;
+ pstring p;
+
+ va_start(ap, format);
+ for (i=0; format[i]; i++) {
+ switch (format[i]) {
+ case 'U':
+ len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
+ /* make sure its in the right format - be strict */
+ if (len1 != len2 || (len1&1) || ptr + len1 > blob->length) {
+ return False;
+ }
+ ps = va_arg(ap, char **);
+ pull_string(NULL, p, blob->data + ptr, -1, len1,
+ STR_UNICODE|STR_NOALIGN);
+ (*ps) = strdup(p);
+ break;
+ case 'B':
+ len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
+ /* make sure its in the right format - be strict */
+ if (len1 != len2 || ptr + len1 > blob->length) {
+ return False;
+ }
+ b = (DATA_BLOB *)va_arg(ap, void *);
+ *b = data_blob(blob->data + ptr, len1);
+ break;
+ case 'b':
+ b = (DATA_BLOB *)va_arg(ap, void *);
+ len1 = va_arg(ap, unsigned);
+ *b = data_blob(blob->data + head_ofs, len1);
+ head_ofs += len1;
+ break;
+ case 'd':
+ v = va_arg(ap, uint32 *);
+ *v = IVAL(blob->data, head_ofs); head_ofs += 4;
+ break;
+ case 'C':
+ s = va_arg(ap, char *);
+ head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1,
+ blob->length - head_ofs,
+ STR_ASCII|STR_TERMINATE);
+ if (strcmp(s, p) != 0) {
+ return False;
+ }
+ break;
+ }
}
+ va_end(ap);
- asn1_free(&data);
return True;
}
-
diff --git a/source/libsmb/clistr.c b/source/libsmb/clistr.c
index c61445c0735..72178967ed5 100644
--- a/source/libsmb/clistr.c
+++ b/source/libsmb/clistr.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client string routines
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
-
+ Copyright (C) Jeremy Allison 2001
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -19,40 +20,157 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define NO_SYSLOG
+
#include "includes.h"
-size_t clistr_push_fn(const char *function, unsigned int line,
- struct cli_state *cli, void *dest,
- const char *src, int dest_len, int flags)
+#define UNICODE_FLAG(cli, flags) (!(flags & STR_ASCII) && \
+ ((flags & STR_UNICODE || \
+ (SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))))
+
+/****************************************************************************
+copy a string from a char* src to a unicode or ascii
+dos code page destination choosing unicode or ascii based on the
+cli->capabilities flag
+return the number of bytes occupied by the string in the destination
+flags can have:
+ STR_TERMINATE means include the null termination
+ STR_CONVERT means convert from unix to dos codepage
+ STR_UPPER means uppercase in the destination
+ STR_ASCII use ascii even with unicode servers
+ STR_NOALIGN means don't do alignment
+dest_len is the maximum length allowed in the destination. If dest_len
+is -1 then no maxiumum is used
+****************************************************************************/
+
+int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
{
- size_t buf_used = PTR_DIFF(dest, cli->outbuf);
- if (dest_len == -1) {
- if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) {
- DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n"));
- return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags);
- }
- return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags);
+ int len=0;
+
+ /* treat a pstring as "unlimited" length */
+ if (dest_len == -1)
+ dest_len = sizeof(pstring);
+
+ if (clistr_align_out(cli, dest, flags)) {
+ *(char *)dest = 0;
+ dest = (void *)((char *)dest + 1);
+ dest_len--;
+ len++;
+ }
+
+ if (!UNICODE_FLAG(cli, flags)) {
+ /* the server doesn't want unicode */
+ safe_strcpy(dest, src, dest_len);
+ len = strlen(dest);
+ if (flags & STR_TERMINATE)
+ len++;
+ if (flags & STR_CONVERT)
+ unix_to_dos(dest);
+ if (flags & STR_UPPER)
+ strupper(dest);
+ return len;
}
-
- /* 'normal' push into size-specified buffer */
- return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags);
+
+ /* the server likes unicode. give it the works */
+ if (flags & STR_CONVERT)
+ dos_PutUniCode(dest, unix_to_dos_static(src), dest_len, flags & STR_TERMINATE);
+ else
+ unix_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
+
+ if (flags & STR_UPPER)
+ strupper_w(dest);
+
+ len += strlen(src)*2;
+ if (flags & STR_TERMINATE)
+ len += 2;
+ return len;
}
-size_t clistr_pull_fn(const char *function, unsigned int line,
- struct cli_state *cli, char *dest, const void *src,
- int dest_len, int src_len,
- int flags)
+/****************************************************************************
+copy a string from a unicode or dos codepage source (depending on
+cli->capabilities) to a unix char* destination
+flags can have:
+ STR_TERMINATE means the string in src is null terminated
+ STR_UNICODE means to force as unicode
+ STR_NOALIGN means don't do alignment
+if STR_TERMINATE is set then src_len is ignored
+src_len is the length of the source area in bytes
+return the number of bytes occupied by the string in src
+****************************************************************************/
+
+int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
{
- return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags);
+ int len;
+
+ if (dest_len == -1)
+ dest_len = sizeof(pstring);
+
+ if (clistr_align_in(cli, src, flags)) {
+ src = (const void *)((const char *)src + 1);
+ if (src_len > 0)
+ src_len--;
+ }
+
+ if (!UNICODE_FLAG(cli, flags)) {
+ /* the server doesn't want unicode */
+ if (flags & STR_TERMINATE) {
+ safe_strcpy(dest, src, dest_len);
+ len = strlen(src)+1;
+ } else {
+ if (src_len > dest_len)
+ src_len = dest_len;
+ len = src_len;
+ memcpy(dest, src, len);
+ dest[len] = 0;
+ }
+ safe_strcpy(dest,dos_to_unix_static(dest),dest_len);
+ return len;
+ }
+
+ if (flags & STR_TERMINATE) {
+ int i;
+ src_len = strlen_w(src)*2+2;
+ for (i=0; i < src_len; i += 2) {
+ const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
+ if (c == (smb_ucs2_t)0 || (dest_len - i < 3))
+ break;
+ dest += unicode_to_unix_char(dest, c);
+ }
+ *dest++ = 0;
+ len = src_len;
+ } else {
+ int i;
+ if (dest_len*2 < src_len)
+ src_len = 2*dest_len;
+ for (i=0; i < src_len; i += 2) {
+ const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
+ dest += unicode_to_unix_char(dest, c);
+ }
+ *dest++ = 0;
+ len = src_len;
+ }
+ return len;
}
+/****************************************************************************
+ Return an alignment of either 0 or 1.
+ If unicode is not negotiated then return 0
+ otherwise return 1 if offset is off.
+****************************************************************************/
+
+static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags)
+{
+ if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags))
+ return 0;
+ return PTR_DIFF(p, buf) & 1;
+}
-size_t clistr_align_out(struct cli_state *cli, const void *p, int flags)
+int clistr_align_out(struct cli_state *cli, const void *p, int flags)
{
- return align_string(cli->outbuf, p, flags);
+ return clistr_align(cli, cli->outbuf, p, flags);
}
-size_t clistr_align_in(struct cli_state *cli, const void *p, int flags)
+int clistr_align_in(struct cli_state *cli, const void *p, int flags)
{
- return align_string(cli->inbuf, p, flags);
+ return clistr_align(cli, cli->inbuf, p, flags);
}
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index ae44ca1a779..7d91fa08bbd 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
client transaction calls
Copyright (C) Andrew Tridgell 1994-1998
@@ -31,16 +32,15 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
const char *pipe_name,
int fid, int flags,
uint16 *setup, unsigned int lsetup, unsigned int msetup,
- const char *param, unsigned int lparam, unsigned int mparam,
- const char *data, unsigned int ldata, unsigned int mdata)
+ char *param, unsigned int lparam, unsigned int mparam,
+ char *data, unsigned int ldata, unsigned int mdata)
{
- unsigned int i;
+ int i;
unsigned int this_ldata,this_lparam;
unsigned int tot_data=0,tot_param=0;
char *outdata,*outparam;
char *p;
int pipe_name_len=0;
- uint16 mid;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
@@ -51,15 +51,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
- /*
- * Save the mid we're using. We need this for finding
- * signing replies.
- */
-
- mid = cli->mid;
-
if (pipe_name) {
- pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE);
+ pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE|STR_CONVERT);
}
outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3);
@@ -92,16 +85,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
-
- if (!cli_send_smb(cli)) {
+ if (!cli_send_smb(cli))
return False;
- }
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
- if (!cli_receive_smb(cli) || cli_is_error(cli)) {
+ if (!cli_receive_smb(cli) || cli_is_error(cli))
return(False);
- }
tot_data = this_ldata;
tot_param = this_lparam;
@@ -133,29 +123,15 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
- /*
- * Save the mid we're using. We need this for finding
- * signing replies.
- */
- mid = cli->mid;
-
show_msg(cli->outbuf);
- if (!cli_send_smb(cli)) {
+ if (!cli_send_smb(cli))
return False;
- }
-
- /* Ensure we use the same mid for the secondaries. */
- cli->mid = mid;
tot_data += this_ldata;
tot_param += this_lparam;
}
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
-
- cli_signing_trans_start(cli, mid);
return(True);
}
@@ -176,10 +152,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
*data_len = *param_len = 0;
- if (!cli_receive_smb(cli)) {
- cli_signing_trans_stop(cli);
+ if (!cli_receive_smb(cli))
return False;
- }
show_msg(cli->inbuf);
@@ -188,7 +162,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
DEBUG(0,("Expected %s response, got command 0x%02x\n",
trans==SMBtrans?"SMBtrans":"SMBtrans2",
CVAL(cli->inbuf,smb_com)));
- cli_signing_trans_stop(cli);
return(False);
}
@@ -199,10 +172,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
*/
status = cli_nt_error(cli);
- if (NT_STATUS_IS_ERR(status)) {
- cli_signing_trans_stop(cli);
+ if (NT_STATUS_IS_ERR(status))
return False;
- }
/* parse out the lengths */
total_data = SVAL(cli->inbuf,smb_tdrcnt);
@@ -213,7 +184,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
tdata = Realloc(*data,total_data);
if (!tdata) {
DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n"));
- cli_signing_trans_stop(cli);
return False;
}
else
@@ -224,7 +194,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
tparam = Realloc(*param,total_param);
if (!tparam) {
DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n"));
- cli_signing_trans_stop(cli);
return False;
}
else
@@ -238,7 +207,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (this_data + *data_len > total_data ||
this_param + *param_len > total_param) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -247,7 +215,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
this_param + *param_len < this_param ||
this_param + *param_len < *param_len) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -260,7 +227,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
data_offset_out + this_data < data_offset_out ||
data_offset_out + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
if (data_offset_in > cli->bufsize ||
@@ -268,7 +234,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
data_offset_in + this_data < data_offset_in ||
data_offset_in + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -283,7 +248,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
param_offset_out + this_param < param_offset_out ||
param_offset_out + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
if (param_offset_in > cli->bufsize ||
@@ -291,7 +255,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
param_offset_in + this_param < param_offset_in ||
param_offset_in + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -303,10 +266,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (total_data <= *data_len && total_param <= *param_len)
break;
- if (!cli_receive_smb(cli)) {
- cli_signing_trans_stop(cli);
- return False;
- }
+ if (!cli_receive_smb(cli))
+ return False;
show_msg(cli->inbuf);
@@ -315,11 +276,9 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
DEBUG(0,("Expected %s response, got command 0x%02x\n",
trans==SMBtrans?"SMBtrans":"SMBtrans2",
CVAL(cli->inbuf,smb_com)));
- cli_signing_trans_stop(cli);
return(False);
}
if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
- cli_signing_trans_stop(cli);
return(False);
}
@@ -334,7 +293,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
}
- cli_signing_trans_stop(cli);
return(True);
}
@@ -352,7 +310,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
unsigned int i;
unsigned int this_ldata,this_lparam;
unsigned int tot_data=0,tot_param=0;
- uint16 mid;
char *outdata,*outparam;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
@@ -364,13 +321,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
- /*
- * Save the mid we're using. We need this for finding
- * signing replies.
- */
-
- mid = cli->mid;
-
outparam = smb_buf(cli->outbuf)+3;
outdata = outparam+this_lparam;
@@ -398,15 +348,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
- if (!cli_send_smb(cli)) {
+ if (!cli_send_smb(cli))
return False;
- }
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
- if (!cli_receive_smb(cli) || cli_is_error(cli)) {
+ if (!cli_receive_smb(cli) || cli_is_error(cli))
return(False);
- }
tot_data = this_ldata;
tot_param = this_lparam;
@@ -437,33 +385,20 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
- /*
- * Save the mid we're using. We need this for finding
- * signing replies.
- */
- mid = cli->mid;
-
show_msg(cli->outbuf);
-
- if (!cli_send_smb(cli)) {
+ if (!cli_send_smb(cli))
return False;
- }
-
- /* Ensure we use the same mid for the secondaries. */
- cli->mid = mid;
tot_data += this_ldata;
tot_param += this_lparam;
}
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
-
- cli_signing_trans_start(cli, mid);
return(True);
}
+
+
/****************************************************************************
receive a SMB nttrans response allocating the necessary memory
****************************************************************************/
@@ -482,10 +417,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*data_len = *param_len = 0;
- if (!cli_receive_smb(cli)) {
- cli_signing_trans_stop(cli);
+ if (!cli_receive_smb(cli))
return False;
- }
show_msg(cli->inbuf);
@@ -493,7 +426,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
CVAL(cli->inbuf,smb_com)));
- cli_signing_trans_stop(cli);
return(False);
}
@@ -504,21 +436,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*/
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
- cli_signing_trans_stop(cli);
+ if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
return(False);
- }
- }
-
- /*
- * Likewise for NT_STATUS_BUFFER_TOO_SMALL
- */
- if (cli_is_nt_error(cli)) {
- if (!NT_STATUS_EQUAL(cli_nt_error(cli),
- NT_STATUS_BUFFER_TOO_SMALL)) {
- cli_signing_trans_stop(cli);
- return(False);
- }
}
/* parse out the lengths */
@@ -530,7 +449,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
tdata = Realloc(*data,total_data);
if (!tdata) {
DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data));
- cli_signing_trans_stop(cli);
return False;
} else {
*data = tdata;
@@ -541,7 +459,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
tparam = Realloc(*param,total_param);
if (!tparam) {
DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param));
- cli_signing_trans_stop(cli);
return False;
} else {
*param = tparam;
@@ -555,7 +472,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (this_data + *data_len > total_data ||
this_param + *param_len > total_param) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -564,7 +480,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
this_param + *param_len < this_param ||
this_param + *param_len < *param_len) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -577,7 +492,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
data_offset_out + this_data < data_offset_out ||
data_offset_out + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
if (data_offset_in > cli->bufsize ||
@@ -585,7 +499,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
data_offset_in + this_data < data_offset_in ||
data_offset_in + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -601,7 +514,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
param_offset_out + this_param < param_offset_out ||
param_offset_out + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
if (param_offset_in > cli->bufsize ||
@@ -609,7 +521,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
param_offset_in + this_param < param_offset_in ||
param_offset_in + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
- cli_signing_trans_stop(cli);
return False;
}
@@ -622,10 +533,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (total_data <= *data_len && total_param <= *param_len)
break;
- if (!cli_receive_smb(cli)) {
- cli_signing_trans_stop(cli);
+ if (!cli_receive_smb(cli))
return False;
- }
show_msg(cli->inbuf);
@@ -633,15 +542,13 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
CVAL(cli->inbuf,smb_com)));
- cli_signing_trans_stop(cli);
return(False);
}
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
- cli_signing_trans_stop(cli);
+ if(cli->nt_pipe_fnum == 0 ||
+ !(eclass == ERRDOS && ecode == ERRmoredata))
return(False);
- }
}
/* parse out the total lengths again - they can shrink! */
if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
@@ -653,6 +560,5 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
break;
}
- cli_signing_trans_stop(cli);
return(True);
}
diff --git a/source/libsmb/conncache.c b/source/libsmb/conncache.c
deleted file mode 100644
index e6604617d68..00000000000
--- a/source/libsmb/conncache.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon connection manager
-
- Copyright (C) Tim Potter 2001
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Gerald (Jerry) Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
-
-#define CONNCACHE_ADDR 1
-#define CONNCACHE_NAME 2
-
-/* cache entry contains either a server name **or** and IP address as
- the key. This means that a server could have two entries (one for each key) */
-
-struct failed_connection_cache {
- fstring domain_name;
- fstring controller;
- time_t lookup_time;
- NTSTATUS nt_status;
- struct failed_connection_cache *prev, *next;
-};
-
-static struct failed_connection_cache *failed_connection_cache;
-
-/**********************************************************************
- Check for a previously failed connection
-**********************************************************************/
-
-NTSTATUS check_negative_conn_cache( const char *domain, const char *server )
-{
- struct failed_connection_cache *fcc;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- /* can't check if we don't have strings */
-
- if ( !domain || !server )
- return NT_STATUS_OK;
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
-
- if ( !(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller)) )
- continue; /* no match; check the next entry */
-
- /* we have a match so see if it is still current */
-
- if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT)
- {
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
- domain, server ));
-
- DLIST_REMOVE(failed_connection_cache, fcc);
- SAFE_FREE(fcc);
-
- return NT_STATUS_OK;
- }
-
- /* The timeout hasn't expired yet so return false */
-
- DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
- domain, server ));
-
- result = fcc->nt_status;
- return result;
- }
-
- /* end of function means no cache entry */
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Add an entry to the failed conneciton cache (aither a name of dotted
- decimal IP
-**********************************************************************/
-
-void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
-{
- struct failed_connection_cache *fcc;
-
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
-
- /* Check we already aren't in the cache. We always have to have
- a domain, but maybe not a specific DC name. */
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
- if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) )
- {
- DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
- domain, server ));
- return;
- }
- }
-
- /* Create negative lookup cache entry for this domain and controller */
-
- if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) )
- {
- DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
- return;
- }
-
- ZERO_STRUCTP(fcc);
-
- fstrcpy( fcc->domain_name, domain );
- fstrcpy( fcc->controller, server );
- fcc->lookup_time = time(NULL);
- fcc->nt_status = result;
-
- DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
- domain, server ));
-
- DLIST_ADD(failed_connection_cache, fcc);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void flush_negative_conn_cache( void )
-{
- struct failed_connection_cache *fcc;
-
- fcc = failed_connection_cache;
-
- while (fcc) {
- struct failed_connection_cache *fcc_next;
-
- fcc_next = fcc->next;
- DLIST_REMOVE(failed_connection_cache, fcc);
- free(fcc);
-
- fcc = fcc_next;
- }
-
-}
-
-
diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c
index 0d521bae8ac..86adf03c402 100644
--- a/source/libsmb/credentials.c
+++ b/source/libsmb/credentials.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
code to manipulate domain credentials
Copyright (C) Andrew Tridgell 1997-1998
@@ -41,8 +42,8 @@ Input: 8 byte challenge block
Output:
8 byte session key
****************************************************************************/
-void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass,
- uchar session_key[8])
+void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass,
+ uchar session_key[8])
{
uint32 sum[2];
unsigned char sum2[8];
@@ -53,7 +54,7 @@ void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const
SIVAL(sum2,0,sum[0]);
SIVAL(sum2,4,sum[1]);
- cred_hash1(session_key, sum2, pass);
+ cred_hash1(session_key, sum2,pass);
/* debug output */
DEBUG(4,("cred_session_key\n"));
diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c
index c6348568cf9..a28721308bd 100644
--- a/source/libsmb/doserr.c
+++ b/source/libsmb/doserr.c
@@ -66,14 +66,13 @@ werror_code_struct dos_errs[] =
{ "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR },
{ "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT },
{ "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
- { "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
- { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
{ NULL, W_ERROR(0) }
};
/*****************************************************************************
returns a DOS error message. not amazingly helpful, but better than a number.
*****************************************************************************/
+
const char *dos_errstr(WERROR werror)
{
static pstring msg;
diff --git a/source/libsmb/errormap.c b/source/libsmb/errormap.c
index aeb68b6596c..28b4cb04316 100644
--- a/source/libsmb/errormap.c
+++ b/source/libsmb/errormap.c
@@ -1,9 +1,8 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 3.0
* error mapping functions
* Copyright (C) Andrew Tridgell 2001
- * Copyright (C) Andrew Bartlett 2001
- * Copyright (C) Tim Potter 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +44,7 @@
*/
/* NT status -> dos error map */
-static const struct {
+static struct {
uint8 dos_class;
uint32 dos_code;
NTSTATUS ntstatus;
@@ -98,10 +97,6 @@ static const struct {
*/
{ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED},
{ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL},
-/*
- * Not an official error, as only bit 0x80000000, not bits 0xC0000000 are set.
- */
- {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW},
{ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH},
{ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION},
{ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION},
@@ -615,7 +610,7 @@ static const struct {
/* dos -> nt status error map */
-static const struct {
+static struct {
uint8 dos_class;
uint32 dos_code;
NTSTATUS ntstatus;
@@ -870,7 +865,7 @@ static const struct {
};
/* errmap NTSTATUS->Win32 */
-static const struct {
+static struct {
NTSTATUS ntstatus;
WERROR werror;
} ntstatus_to_werror_map[] = {
@@ -1414,7 +1409,7 @@ static const struct {
/*****************************************************************************
convert a dos eclas/ecode to a NT status32 code
*****************************************************************************/
-NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode)
+NTSTATUS dos_to_ntstatus(int eclass, int ecode)
{
int i;
if (eclass == 0 && ecode == 0) return NT_STATUS_OK;
@@ -1487,62 +1482,3 @@ WERROR ntstatus_to_werror(NTSTATUS error)
/* a lame guess */
return W_ERROR(NT_STATUS_V(error) & 0xffff);
}
-
-/* Mapping between Unix, DOS and NT error numbers */
-
-const struct unix_error_map unix_dos_nt_errmap[] = {
- { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
- { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
- { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND },
- { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY },
- { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR },
- { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
- { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
- { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION},
- { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
- { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
- { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
- { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY },
- { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY},
-#ifdef EDQUOT
- { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
-#endif
-#ifdef ENOTEMPTY
- { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
-#endif
-#ifdef EXDEV
- { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
-#endif
-#ifdef EROFS
- { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED },
-#endif
-#ifdef ENAMETOOLONG
- { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID },
-#endif
-#ifdef EFBIG
- { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
-#endif
- { 0, 0, 0, NT_STATUS_OK }
-};
-
-/*********************************************************************
- Map an NT error code from a Unix error code.
-*********************************************************************/
-
-NTSTATUS map_nt_error_from_unix(int unix_error)
-{
- int i = 0;
-
- if (unix_error == 0)
- return NT_STATUS_OK;
-
- /* Look through list */
- while(unix_dos_nt_errmap[i].unix_error != 0) {
- if (unix_dos_nt_errmap[i].unix_error == unix_error)
- return unix_dos_nt_errmap[i].nt_error;
- i++;
- }
-
- /* Default return */
- return NT_STATUS_ACCESS_DENIED;
-}
diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c
deleted file mode 100644
index cb40b4aaa6b..00000000000
--- a/source/libsmb/libsmb_cache.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB client library implementation (server cache)
- Copyright (C) Andrew Tridgell 1998
- Copyright (C) Richard Sharpe 2000
- Copyright (C) John Terpstra 2000
- Copyright (C) Tom Jansen (Ninja ISD) 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- * Define this to get the real SMBCFILE and SMBCSRV structures
- */
-#define _SMBC_INTERNAL
-#include "../include/libsmbclient.h"
-
-/*
- * Structure we use if internal caching mechanism is used
- * nothing fancy here.
- */
-struct smbc_server_cache {
- char *server_name;
- char *share_name;
- char *workgroup;
- char *username;
- SMBCSRV *server;
-
- struct smbc_server_cache *next, *prev;
-};
-
-
-
-/*
- * Add a new connection to the server cache.
- * This function is only used if the external cache is not enabled
- */
-static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new,
- const char * server, const char * share,
- const char * workgroup, const char * username)
-{
- struct smbc_server_cache * srvcache = NULL;
-
- if (!(srvcache = malloc(sizeof(*srvcache)))) {
- errno = ENOMEM;
- DEBUG(3, ("Not enough space for server cache allocation\n"));
- return 1;
- }
-
- ZERO_STRUCTP(srvcache);
-
- srvcache->server = new;
-
- srvcache->server_name = strdup(server);
- if (!srvcache->server_name) {
- errno = ENOMEM;
- goto failed;
- }
-
- srvcache->share_name = strdup(share);
- if (!srvcache->share_name) {
- errno = ENOMEM;
- goto failed;
- }
-
- srvcache->workgroup = strdup(workgroup);
- if (!srvcache->workgroup) {
- errno = ENOMEM;
- goto failed;
- }
-
- srvcache->username = strdup(username);
- if (!srvcache->username) {
- errno = ENOMEM;
- goto failed;
- }
-
- DLIST_ADD((context->server_cache), srvcache);
- return 0;
-
- failed:
- SAFE_FREE(srvcache->server_name);
- SAFE_FREE(srvcache->share_name);
- SAFE_FREE(srvcache->workgroup);
- SAFE_FREE(srvcache->username);
-
- return 1;
-}
-
-
-
-/*
- * Search the server cache for a server
- * returns server_fd on success, -1 on error (not found)
- * This function is only used if the external cache is not enabled
- */
-static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server,
- const char * share, const char * workgroup, const char * user)
-{
- struct smbc_server_cache * srv = NULL;
-
- /* Search the cache lines */
- for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) {
- if (strcmp(server,srv->server_name) == 0 &&
- strcmp(share,srv->share_name) == 0 &&
- strcmp(workgroup,srv->workgroup) == 0 &&
- strcmp(user, srv->username) == 0)
- return srv->server;
- }
-
- return NULL;
-}
-
-
-/*
- * Search the server cache for a server and remove it
- * returns 0 on success
- * This function is only used if the external cache is not enabled
- */
-static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server)
-{
- struct smbc_server_cache * srv = NULL;
-
- for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) {
- if (server == srv->server) {
-
- /* remove this sucker */
- DLIST_REMOVE(context->server_cache, srv);
- SAFE_FREE(srv->server_name);
- SAFE_FREE(srv->share_name);
- SAFE_FREE(srv->workgroup);
- SAFE_FREE(srv->username);
- SAFE_FREE(srv);
- return 0;
- }
- }
- /* server not found */
- return 1;
-}
-
-
-/*
- * Try to remove all the servers in cache
- * returns 1 on failure and 0 if all servers could be removed.
- */
-static int smbc_purge_cached(SMBCCTX * context)
-{
- struct smbc_server_cache * srv;
- struct smbc_server_cache * next;
- int could_not_purge_all = 0;
-
- for (srv = ((struct smbc_server_cache *) context->server_cache),
- next = (srv ? srv->next :NULL);
- srv;
- srv = next, next = (srv ? srv->next : NULL)) {
-
- if (smbc_remove_unused_server(context, srv->server)) {
- /* could not be removed */
- could_not_purge_all = 1;
- }
- }
- return could_not_purge_all;
-}
-
-
-
-/*
- * This functions initializes all server-cache related functions
- * to the default (internal) system.
- *
- * We use this to make the rest of the cache system static.
- */
-
-int smbc_default_cache_functions(SMBCCTX * context)
-{
- context->callbacks.add_cached_srv_fn = smbc_add_cached_server;
- context->callbacks.get_cached_srv_fn = smbc_get_cached_server;
- context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server;
- context->callbacks.purge_cached_fn = smbc_purge_cached;
-
- return 0;
-}
diff --git a/source/libsmb/libsmb_compat.c b/source/libsmb/libsmb_compat.c
deleted file mode 100644
index cc23835ae3d..00000000000
--- a/source/libsmb/libsmb_compat.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB client library implementation (Old interface compatibility)
- Copyright (C) Andrew Tridgell 1998
- Copyright (C) Richard Sharpe 2000
- Copyright (C) John Terpstra 2000
- Copyright (C) Tom Jansen (Ninja ISD) 2002
- Copyright (C) Derrell Lipman 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-#include "../include/libsmb_internal.h"
-
-struct smbc_compat_fdlist {
- SMBCFILE * file;
- int fd;
- struct smbc_compat_fdlist *next, *prev;
-};
-
-static SMBCCTX * statcont = NULL;
-static int smbc_compat_initialized = 0;
-static int smbc_compat_nextfd = 0;
-static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
-static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
-
-/* Find an fd and return the SMBCFILE * or NULL on failure */
-static SMBCFILE * find_fd(int fd)
-{
- struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
- while (f) {
- if (f->fd == fd)
- return f->file;
- f = f->next;
- }
- return NULL;
-}
-
-/* Add an fd, returns 0 on success, -1 on error with errno set */
-static int add_fd(SMBCFILE * file)
-{
- struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
-
- if (f) {
- /* We found one that's available */
- DLIST_REMOVE(smbc_compat_fd_avail, f);
-
- } else {
- /*
- * None were available, so allocate one. Keep the number of
- * file descriptors determinate. This allows the application
- * to allocate bitmaps or mapping of file descriptors based on
- * a known maximum number of file descriptors that will ever
- * be returned.
- */
- if (smbc_compat_nextfd >= FD_SETSIZE) {
- errno = EMFILE;
- return -1;
- }
-
- f = malloc(sizeof(struct smbc_compat_fdlist));
- if (!f) {
- errno = ENOMEM;
- return -1;
- }
-
- f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
- }
-
- f->file = file;
- DLIST_ADD(smbc_compat_fd_in_use, f);
-
- return f->fd;
-}
-
-
-
-/* Delete an fd, returns 0 on success */
-static int del_fd(int fd)
-{
- struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
-
- while (f) {
- if (f->fd == fd)
- break;
- f = f->next;
- }
-
- if (f) {
- /* found */
- DLIST_REMOVE(smbc_compat_fd_in_use, f);
- f->file = NULL;
- DLIST_ADD(smbc_compat_fd_avail, f);
- return 0;
- }
- return 1;
-}
-
-
-
-int smbc_init(smbc_get_auth_data_fn fn, int debug)
-{
- if (!smbc_compat_initialized) {
- statcont = smbc_new_context();
- if (!statcont)
- return -1;
-
- statcont->debug = debug;
- statcont->callbacks.auth_fn = fn;
-
- if (!smbc_init_context(statcont)) {
- smbc_free_context(statcont, False);
- return -1;
- }
-
- smbc_compat_initialized = 1;
-
- return 0;
- }
- return 0;
-}
-
-
-SMBCCTX *smbc_set_context(SMBCCTX * context)
-{
- SMBCCTX *old_context = statcont;
-
- if (context) {
- /* Save provided context. It must have been initialized! */
- statcont = context;
-
- /* You'd better know what you're doing. We won't help you. */
- smbc_compat_initialized = 1;
- }
-
- return old_context;
-}
-
-
-int smbc_open(const char *furl, int flags, mode_t mode)
-{
- SMBCFILE * file;
- int fd;
-
- file = statcont->open(statcont, furl, flags, mode);
- if (!file)
- return -1;
-
- fd = add_fd(file);
- if (fd == -1)
- statcont->close(statcont, file);
- return fd;
-}
-
-
-int smbc_creat(const char *furl, mode_t mode)
-{
- SMBCFILE * file;
- int fd;
-
- file = statcont->creat(statcont, furl, mode);
- if (!file)
- return -1;
-
- fd = add_fd(file);
- if (fd == -1) {
- /* Hmm... should we delete the file too ? I guess we could try */
- statcont->close(statcont, file);
- statcont->unlink(statcont, furl);
- }
- return fd;
-}
-
-
-ssize_t smbc_read(int fd, void *buf, size_t bufsize)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->read(statcont, file, buf, bufsize);
-}
-
-ssize_t smbc_write(int fd, void *buf, size_t bufsize)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->write(statcont, file, buf, bufsize);
-}
-
-off_t smbc_lseek(int fd, off_t offset, int whence)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->lseek(statcont, file, offset, whence);
-}
-
-int smbc_close(int fd)
-{
- SMBCFILE * file = find_fd(fd);
- del_fd(fd);
- return statcont->close(statcont, file);
-}
-
-int smbc_unlink(const char *fname)
-{
- return statcont->unlink(statcont, fname);
-}
-
-int smbc_rename(const char *ourl, const char *nurl)
-{
- return statcont->rename(statcont, ourl, statcont, nurl);
-}
-
-int smbc_opendir(const char *durl)
-{
- SMBCFILE * file;
- int fd;
-
- file = statcont->opendir(statcont, durl);
- if (!file)
- return -1;
-
- fd = add_fd(file);
- if (fd == -1)
- statcont->closedir(statcont, file);
-
- return fd;
-}
-
-int smbc_closedir(int dh)
-{
- SMBCFILE * file = find_fd(dh);
- del_fd(dh);
- return statcont->closedir(statcont, file);
-}
-
-int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count)
-{
- SMBCFILE * file = find_fd(dh);
- return statcont->getdents(statcont, file,dirp, count);
-}
-
-struct smbc_dirent* smbc_readdir(unsigned int dh)
-{
- SMBCFILE * file = find_fd(dh);
- return statcont->readdir(statcont, file);
-}
-
-off_t smbc_telldir(int dh)
-{
- SMBCFILE * file = find_fd(dh);
- return statcont->telldir(statcont, file);
-}
-
-int smbc_lseekdir(int fd, off_t offset)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->lseekdir(statcont, file, offset);
-}
-
-int smbc_mkdir(const char *durl, mode_t mode)
-{
- return statcont->mkdir(statcont, durl, mode);
-}
-
-int smbc_rmdir(const char *durl)
-{
- return statcont->rmdir(statcont, durl);
-}
-
-int smbc_stat(const char *url, struct stat *st)
-{
- return statcont->stat(statcont, url, st);
-}
-
-int smbc_fstat(int fd, struct stat *st)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->fstat(statcont, file, st);
-}
-
-int smbc_chmod(const char *url, mode_t mode)
-{
- return statcont->chmod(statcont, url, mode);
-}
-
-int smbc_utimes(const char *fname, struct timeval *tbuf)
-{
- return statcont->utimes(statcont, fname, tbuf);
-}
-
-#ifdef HAVE_UTIME_H
-int smbc_utime(const char *fname, struct utimbuf *utbuf)
-{
- struct timeval tv;
-
- if (utbuf == NULL)
- return statcont->utimes(statcont, fname, NULL);
-
- tv.tv_sec = utbuf->modtime;
- tv.tv_usec = 0;
- return statcont->utimes(statcont, fname, &tv);
-}
-#endif
-
-int smbc_setxattr(const char *fname,
- const char *name,
- const void *value,
- size_t size,
- int flags)
-{
- return statcont->setxattr(statcont, fname, name, value, size, flags);
-}
-
-int smbc_lsetxattr(const char *fname,
- const char *name,
- const void *value,
- size_t size,
- int flags)
-{
- return statcont->setxattr(statcont, fname, name, value, size, flags);
-}
-
-int smbc_fsetxattr(int fd,
- const char *name,
- const void *value,
- size_t size,
- int flags)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->setxattr(statcont, file->fname,
- name, value, size, flags);
-}
-
-int smbc_getxattr(const char *fname,
- const char *name,
- const void *value,
- size_t size)
-{
- return statcont->getxattr(statcont, fname, name, value, size);
-}
-
-int smbc_lgetxattr(const char *fname,
- const char *name,
- const void *value,
- size_t size)
-{
- return statcont->getxattr(statcont, fname, name, value, size);
-}
-
-int smbc_fgetxattr(int fd,
- const char *name,
- const void *value,
- size_t size)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->getxattr(statcont, file->fname, name, value, size);
-}
-
-int smbc_removexattr(const char *fname,
- const char *name)
-{
- return statcont->removexattr(statcont, fname, name);
-}
-
-int smbc_lremovexattr(const char *fname,
- const char *name)
-{
- return statcont->removexattr(statcont, fname, name);
-}
-
-int smbc_fremovexattr(int fd,
- const char *name)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->removexattr(statcont, file->fname, name);
-}
-
-int smbc_listxattr(const char *fname,
- char *list,
- size_t size)
-{
- return statcont->listxattr(statcont, fname, list, size);
-}
-
-int smbc_llistxattr(const char *fname,
- char *list,
- size_t size)
-{
- return statcont->listxattr(statcont, fname, list, size);
-}
-
-int smbc_flistxattr(int fd,
- char *list,
- size_t size)
-{
- SMBCFILE * file = find_fd(fd);
- return statcont->listxattr(statcont, file->fname, list, size);
-}
-
-int smbc_print_file(const char *fname, const char *printq)
-{
- return statcont->print_file(statcont, fname, statcont, printq);
-}
-
-int smbc_open_print_job(const char *fname)
-{
- SMBCFILE * file = statcont->open_print_job(statcont, fname);
- if (!file) return -1;
- return (int) file;
-}
-
-int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn)
-{
- return statcont->list_print_jobs(statcont, purl, fn);
-}
-
-int smbc_unlink_print_job(const char *purl, int id)
-{
- return statcont->unlink_print_job(statcont, purl, id);
-}
-
-
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 50af2237269..0444922b5c1 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -1,11 +1,10 @@
/*
Unix SMB/Netbios implementation.
+ Version 2.0
SMB client library implementation
Copyright (C) Andrew Tridgell 1998
- Copyright (C) Richard Sharpe 2000, 2002
+ Copyright (C) Richard Sharpe 2000
Copyright (C) John Terpstra 2000
- Copyright (C) Tom Jansen (Ninja ISD) 2002
- Copyright (C) Derrell Lipman 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,214 +22,88 @@
*/
#include "includes.h"
+#include "libsmbclient.h"
-#include "../include/libsmb_internal.h"
-
-/*
- * Internal flags for extended attributes
- */
-
-/* internal mode values */
-#define SMBC_XATTR_MODE_ADD 1
-#define SMBC_XATTR_MODE_REMOVE 2
-#define SMBC_XATTR_MODE_REMOVE_ALL 3
-#define SMBC_XATTR_MODE_SET 4
-#define SMBC_XATTR_MODE_CHOWN 5
-#define SMBC_XATTR_MODE_CHGRP 6
-
-#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
-
-/*We should test for this in configure ... */
-#ifndef ENOTSUP
-#define ENOTSUP EOPNOTSUPP
-#endif
-
-/*
- * Functions exported by libsmb_cache.c that we need here
+/* Structure for servers ... Held here so we don't need an include ...
+ * May be better to put in an include file
*/
-int smbc_default_cache_functions(SMBCCTX *context);
-/*
- * check if an element is part of the list.
- * FIXME: Does not belong here !
- * Can anyone put this in a macro in dlinklist.h ?
- * -- Tom
- */
-static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
- if (!p || !list) return False;
- do {
- if (p == list) return True;
- list = list->next;
- } while (list);
- return False;
-}
+struct smbc_server {
+ struct smbc_server *next, *prev;
+ struct cli_state cli;
+ dev_t dev;
+ char *server_name;
+ char *share_name;
+ char *workgroup;
+ char *username;
+ BOOL no_pathinfo2;
+};
+
+/* Keep directory entries in a list */
+struct smbc_dir_list {
+ struct smbc_dir_list *next;
+ struct smbc_dirent *dirent;
+};
+
+struct smbc_file {
+ int cli_fd;
+ int smbc_fd;
+ char *fname;
+ off_t offset;
+ struct smbc_server *srv;
+ BOOL file;
+ struct smbc_dir_list *dir_list, *dir_end, *dir_next;
+ int dir_type, dir_error;
+};
+
+int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */
+BOOL smbc_getatr(struct smbc_server *srv, char *path,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino);
extern BOOL in_client;
-
-/*
- * Is the logging working / configfile read ?
- */
+extern pstring global_myname;
static int smbc_initialized = 0;
-
-static int
-hex2int( unsigned int _char )
-{
- if ( _char >= 'A' && _char <='F')
- return _char - 'A' + 10;
- if ( _char >= 'a' && _char <='f')
- return _char - 'a' + 10;
- if ( _char >= '0' && _char <='9')
- return _char - '0';
- return -1;
-}
-
-static void
-decode_urlpart(char *segment, size_t sizeof_segment)
-{
- int old_length = strlen(segment);
- int new_length = 0;
- int new_length2 = 0;
- int i = 0;
- pstring new_segment;
- char *new_usegment = 0;
-
- if ( !old_length ) {
- return;
- }
-
- /* make a copy of the old one */
- new_usegment = (char*)malloc( old_length * 3 + 1 );
-
- while( i < old_length ) {
- int bReencode = False;
- unsigned char character = segment[ i++ ];
- if ((character <= ' ') || (character > 127))
- bReencode = True;
-
- new_usegment [ new_length2++ ] = character;
- if (character == '%' ) {
- int a = i+1 < old_length ? hex2int( segment[i] ) : -1;
- int b = i+1 < old_length ? hex2int( segment[i+1] ) : -1;
- if ((a == -1) || (b == -1)) { /* Only replace if sequence is valid */
- /* Contains stray %, make sure to re-encode! */
- bReencode = True;
- } else {
- /* Valid %xx sequence */
- character = a * 16 + b; /* Replace with value of %dd */
- if (!character)
- break; /* Stop at %00 */
-
- new_usegment [ new_length2++ ] = (unsigned char) segment[i++];
- new_usegment [ new_length2++ ] = (unsigned char) segment[i++];
- }
- }
- if (bReencode) {
- unsigned int c = character / 16;
- new_length2--;
- new_usegment [ new_length2++ ] = '%';
-
- c += (c > 9) ? ('A' - 10) : '0';
- new_usegment[ new_length2++ ] = c;
-
- c = character % 16;
- c += (c > 9) ? ('A' - 10) : '0';
- new_usegment[ new_length2++ ] = c;
- }
-
- new_segment [ new_length++ ] = character;
- }
- new_segment [ new_length ] = 0;
-
- free(new_usegment);
-
- /* realloc it with unix charset */
- pull_utf8_allocate(&new_usegment, new_segment);
-
- /* this assumes (very safely) that removing %aa sequences
- only shortens the string */
- strncpy(segment, new_usegment, sizeof_segment);
-
- free(new_usegment);
-}
+static smbc_get_auth_data_fn smbc_auth_fn = NULL;
+/*static int smbc_debug;*/
+static int smbc_start_fd;
+static struct smbc_file **smbc_file_table;
+static struct smbc_server *smbc_srvs;
+static pstring my_netbios_name;
+static pstring smbc_user;
/*
* Function to parse a path and turn it into components
*
- * The general format of an SMB URI is explain in Christopher Hertel's CIFS
- * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the
- * general format ("smb:" only; we do not look for "cifs:"), and expand on
- * what he calls "context", herein called "options" to avoid conflict with the
- * SMBCCTX context used throughout this library. We add the "mb" keyword
- * which applies as follows:
- *
- *
- * We accept:
- * smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]][?options]
- *
- * Meaning of URLs:
- *
- * smb:// show all workgroups known by the first master browser found
- * smb://?mb=.any same as smb:// (i.e. without any options)
- *
- * smb://?mb=.all show all workgroups known by every master browser found.
- * Why might you want this? In an "appliance" application
- * where the workgroup/domain being used on the local network
- * is not known ahead of time, but where one wanted to
- * provide network services via samba, a unique workgroup
- * could be used. However, when the appliance is first
- * started, the local samba instance's master browser has not
- * synchronized with the other master browser(s) on the
- * network (and might not synchronize for 12 minutes) and
- * therefore is not aware of the workgroup/ domain names
- * available on the network. This option may be used to
- * overcome the problem of a libsmbclient application
- * arbitrarily selecting the local (still ignorant) master
- * browser to obtain its list of workgroups/domains and
- * getting back a practically emmpty list. By requesting
- * the list of workgroups/domains from each found master
- * browser on the local network, a complete list of
- * workgroups/domains can be built.
- *
- * smb://?mb=name NOT YET IMPLEMENTED -- show all workgroups known by the
- * master browser whose name is "name"
- *
- * smb://name/ if name<1D> or name<1B> exists, list servers in
- * workgroup, else, if name<20> exists, list all shares
- * for server ...
- *
- * If "options" are provided, this function returns the entire option list as
- * a string, for later parsing by the caller.
+ * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]]
+ *
+ * smb:// means show all the workgroups
+ * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup,
+ * else, if name<20> exists, list all shares for server ...
*/
static const char *smbc_prefix = "smb:";
static int
-smbc_parse_path(SMBCCTX *context,
- const char *fname,
- char *server, int server_len,
- char *share, int share_len,
- char *path, int path_len,
- char *user, int user_len,
- char *password, int password_len,
- char *options, int options_len)
+smbc_parse_path(const char *fname, char *server, char *share, char *path,
+ char *user, char *password) /* FIXME, lengths of strings */
{
static pstring s;
pstring userinfo;
- const char *p;
+ char *p;
char *q, *r;
int len;
server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
- if (options != NULL && options_len > 0) {
- options[0] = (char)0;
- }
pstrcpy(s, fname);
+ /* clean_fname(s); causing problems ... */
+
/* see if it has the right prefix */
len = strlen(smbc_prefix);
- if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) {
- return -1; /* What about no smb: ? */
- }
+ if (strncmp(s,smbc_prefix,len) ||
+ (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */
p = s + len;
@@ -238,33 +111,18 @@ smbc_parse_path(SMBCCTX *context,
if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
- DEBUG(1, ("Invalid path (does not begin with smb://"));
return -1;
}
- p += 2; /* Skip the double slash */
-
- /* See if any options were specified */
- if ( (q = strrchr(p, '?')) != NULL ) {
- /* There are options. Null terminate here and point to them */
- *q++ = '\0';
-
- DEBUG(4, ("Found options '%s'", q));
-
- /* Copy the options */
- if (options != NULL && options_len > 0) {
- safe_strcpy(options, q, options_len - 1);
- }
- }
+ p += 2; /* Skip the // or \\ */
if (*p == (char)0)
- goto decoding;
+ return 0;
if (*p == '/') {
- strncpy(server, context->workgroup,
- (strlen(context->workgroup) < 16)?strlen(context->workgroup):16);
+ strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */
return 0;
}
@@ -277,23 +135,23 @@ smbc_parse_path(SMBCCTX *context,
*/
/* check that '@' occurs before '/', if '/' exists at all */
- q = strchr_m(p, '@');
- r = strchr_m(p, '/');
+ q = strchr(p, '@');
+ r = strchr(p, '/');
if (q && (!r || q < r)) {
pstring username, passwd, domain;
- const char *u = userinfo;
+ char *u = userinfo;
next_token(&p, userinfo, "@", sizeof(fstring));
username[0] = passwd[0] = domain[0] = 0;
- if (strchr_m(u, ';')) {
+ if (strchr(u, ';')) {
next_token(&u, domain, ";", sizeof(fstring));
}
- if (strchr_m(u, ':')) {
+ if (strchr(u, ':')) {
next_token(&u, username, ":", sizeof(fstring));
@@ -307,10 +165,10 @@ smbc_parse_path(SMBCCTX *context,
}
if (username[0])
- strncpy(user, username, user_len); /* FIXME, domain */
+ strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */
if (passwd[0])
- strncpy(password, passwd, password_len);
+ strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */
}
@@ -320,7 +178,7 @@ smbc_parse_path(SMBCCTX *context,
}
- if (*p == (char)0) goto decoding; /* That's it ... */
+ if (*p == (char)0) return 0; /* That's it ... */
if (!next_token(&p, share, "/", sizeof(fstring))) {
@@ -328,66 +186,27 @@ smbc_parse_path(SMBCCTX *context,
}
- safe_strcpy(path, p, path_len - 1);
-
+ pstrcpy(path, p);
+
all_string_sub(path, "/", "\\", 0);
- decoding:
- decode_urlpart(path, path_len);
- decode_urlpart(server, server_len);
- decode_urlpart(share, share_len);
- decode_urlpart(user, user_len);
- decode_urlpart(password, password_len);
-
return 0;
}
/*
- * Verify that the options specified in a URL are valid
- */
-static int smbc_check_options(char *server, char *share, char *path, char *options)
-{
- DEBUG(4, ("smbc_check_options(): server='%s' share='%s' path='%s' options='%s'\n", server, share, path, options));
-
- /* No options at all is always ok */
- if (! *options) return 0;
-
- /*
- * For right now, we only support a very few options possibilities.
- * No options are supported if server, share, or path are not empty.
- * If all are empty, then we support the following two choices right
- * now:
- *
- * mb=.any
- * mb=.all
- */
- if ((*server || *share || *path) && *options) {
- /* Invalid: options provided with server, share, or path */
- DEBUG(1, ("Found unsupported options (%s) with non-empty server, share, or path\n", options));
- return -1;
- }
-
- if (strcmp(options, "mb=.any") != 0 &&
- strcmp(options, "mb=.all") != 0) {
- DEBUG(1, ("Found unsupported options (%s)\n", options));
- return -1;
- }
-
- return 0;
-}
-
-/*
* Convert an SMB error into a UNIX error ...
*/
-static int smbc_errno(SMBCCTX *context, struct cli_state *c)
+
+int smbc_errno(struct cli_state *c)
{
- int ret = cli_errno(c);
-
+ int ret;
+
if (cli_is_dos_error(c)) {
uint8 eclass;
uint32 ecode;
cli_dos_error(c, &eclass, &ecode);
+ ret = cli_errno_from_dos(eclass, ecode);
DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n",
(int)eclass, (int)ecode, (int)ecode, ret));
@@ -395,129 +214,15 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c)
NTSTATUS status;
status = cli_nt_error(c);
+ ret = cli_errno_from_nt(status);
DEBUG(3,("smbc errno %s -> %d\n",
- nt_errstr(status), ret));
+ get_nt_error_msg(status), ret));
}
return ret;
}
-/*
- * Check a server_fd.
- * returns 0 if the server is in shape. Returns 1 on error
- *
- * Also useable outside libsmbclient to enable external cache
- * to do some checks too.
- */
-int smbc_check_server(SMBCCTX * context, SMBCSRV * server)
-{
- if ( send_keepalive(server->cli.fd) == False )
- return 1;
-
- /* connection is ok */
- return 0;
-}
-
-/*
- * Remove a server from the cached server list it's unused.
- * On success, 0 is returned. 1 is returned if the server could not be removed.
- *
- * Also useable outside libsmbclient
- */
-int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv)
-{
- SMBCFILE * file;
-
- /* are we being fooled ? */
- if (!context || !context->internal ||
- !context->internal->_initialized || !srv) return 1;
-
-
- /* Check all open files/directories for a relation with this server */
- for (file = context->internal->_files; file; file=file->next) {
- if (file->srv == srv) {
- /* Still used */
- DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n",
- srv, file));
- return 1;
- }
- }
-
- DLIST_REMOVE(context->internal->_servers, srv);
-
- cli_shutdown(&srv->cli);
-
- DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
-
- context->callbacks.remove_cached_srv_fn(context, srv);
-
- SAFE_FREE(srv);
-
- return 0;
-}
-
-SMBCSRV *find_server(SMBCCTX *context,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password)
-{
- SMBCSRV *srv;
- int auth_called = 0;
-
- check_server_cache:
-
- srv = context->callbacks.get_cached_srv_fn(context, server, share,
- workgroup, username);
-
- if (!auth_called && !srv && (!username[0] || !password[0])) {
- context->callbacks.auth_fn(server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- /*
- * However, smbc_auth_fn may have picked up info relating to
- * an existing connection, so try for an existing connection
- * again ...
- */
- auth_called = 1;
- goto check_server_cache;
-
- }
-
- if (srv) {
- if (context->callbacks.check_server_fn(context, srv)) {
- /*
- * This server is no good anymore
- * Try to remove it and check for more possible
- * servers in the cache
- */
- if (context->callbacks.remove_unused_server_fn(context,
- srv)) {
- /*
- * We could not remove the server completely,
- * remove it from the cache so we will not get
- * it again. It will be removed when the last
- * file/dir is closed.
- */
- context->callbacks.remove_cached_srv_fn(context,
- srv);
- }
-
- /*
- * Maybe there are more cached connections to this
- * server
- */
- goto check_server_cache;
- }
- return srv;
- }
-
- return NULL;
-}
-
/*
* Connect to a server, possibly on an existing connection
*
@@ -529,15 +234,15 @@ SMBCSRV *find_server(SMBCCTX *context,
* info we need, unless the username and password were passed in.
*/
-SMBCSRV *smbc_server(SMBCCTX *context,
- const char *server, const char *share,
- fstring workgroup, fstring username,
- fstring password)
+struct smbc_server *smbc_server(char *server, char *share,
+ char *workgroup, char *username,
+ char *password)
{
- SMBCSRV *srv=NULL;
+ struct smbc_server *srv=NULL;
struct cli_state c;
struct nmb_name called, calling;
- const char *server_n = server;
+ char *p, *server_n = server;
+ fstring group;
pstring ipenv;
struct in_addr ip;
int tried_reverse = 0;
@@ -545,31 +250,55 @@ SMBCSRV *smbc_server(SMBCCTX *context,
zero_ip(&ip);
ZERO_STRUCT(c);
+ /* try to use an existing connection */
+ for (srv=smbc_srvs;srv;srv=srv->next) {
+ if (strcmp(server,srv->server_name)==0 &&
+ strcmp(share,srv->share_name)==0 &&
+ strcmp(workgroup,srv->workgroup)==0 &&
+ strcmp(username, srv->username) == 0)
+ return srv;
+ }
+
if (server[0] == 0) {
errno = EPERM;
return NULL;
}
- srv = find_server(context, server, share,
- workgroup, username, password);
- if (srv)
- return srv;
+ /*
+ * Pick up the auth info here, once we know we need to connect
+ * But only if we do not have a username and password ...
+ */
+
+ if (!username[0] || !password[0])
+ smbc_auth_fn(server, share, workgroup, sizeof(fstring),
+ username, sizeof(fstring), password, sizeof(fstring));
+
+ /*
+ * However, smbc_auth_fn may have picked up info relating to an
+ * existing connection, so try for an existing connection again ...
+ */
- make_nmb_name(&calling, context->netbios_name, 0x0);
+ for (srv=smbc_srvs;srv;srv=srv->next) {
+ if (strcmp(server,srv->server_name)==0 &&
+ strcmp(share,srv->share_name)==0 &&
+ strcmp(workgroup,srv->workgroup)==0 &&
+ strcmp(username, srv->username) == 0)
+ return srv;
+ }
+
+ make_nmb_name(&calling, my_netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
-#if 0 /* djl: obsolete code? neither group nor p is used beyond here */
- if ((p=strchr_m(server_n,'#')) &&
+ if ((p=strchr(server_n,'#')) &&
(strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
fstrcpy(group, server_n);
- p = strchr_m(group,'#');
+ p = strchr(group,'#');
*p = 0;
}
-#endif
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
@@ -579,28 +308,12 @@ SMBCSRV *smbc_server(SMBCCTX *context,
zero_ip(&ip);
/* have to open a new connection */
- if (!cli_initialise(&c)) {
- errno = ENOMEM;
+ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
+ if (c.initialised) cli_shutdown(&c);
+ errno = ENOENT;
return NULL;
}
- c.timeout = context->timeout;
-
- /* Force use of port 139 for first try, so browse lists can work */
- c.port = 139;
-
- if (!cli_connect(&c, server_n, &ip)) {
- /*
- * Port 139 connection failed. Try port 445 to handle
- * connections to newer (e.g. XP) hosts with NetBIOS disabled.
- */
- c.port = 445;
- if (!cli_connect(&c, server_n, &ip)) {
- errno = ENETUNREACH;
- return NULL;
- }
- }
-
if (!cli_session_request(&c, &calling, &called)) {
cli_shutdown(&c);
if (strcmp(called.name, "*SMBSERVER")) {
@@ -658,200 +371,268 @@ SMBCSRV *smbc_server(SMBCCTX *context,
if (!cli_send_tconX(&c, share, "?????",
password, strlen(password)+1)) {
- errno = smbc_errno(context, &c);
+ errno = smbc_errno(&c);
cli_shutdown(&c);
return NULL;
}
DEBUG(4,(" tconx ok\n"));
- /*
- * Ok, we have got a nice connection
- * Let's find a free server_fd
- */
-
- srv = (SMBCSRV *)malloc(sizeof(*srv));
+ srv = (struct smbc_server *)malloc(sizeof(*srv));
if (!srv) {
errno = ENOMEM;
goto failed;
}
ZERO_STRUCTP(srv);
+
srv->cli = c;
+
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
- /* now add it to the cache (internal or external) */
- if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
- DEBUG(3, (" Failed to add server to cache\n"));
+ srv->server_name = strdup(server);
+ if (!srv->server_name) {
+ errno = ENOMEM;
goto failed;
}
-
- DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
- server, share, srv));
+ srv->share_name = strdup(share);
+ if (!srv->share_name) {
+ errno = ENOMEM;
+ goto failed;
+ }
+
+ srv->workgroup = strdup(workgroup);
+ if (!srv->workgroup) {
+ errno = ENOMEM;
+ goto failed;
+ }
+
+ srv->username = strdup(username);
+ if (!srv->username) {
+ errno = ENOMEM;
+ goto failed;
+ }
+
+ DLIST_ADD(smbc_srvs, srv);
- DLIST_ADD(context->internal->_servers, srv);
return srv;
failed:
cli_shutdown(&c);
if (!srv) return NULL;
+ SAFE_FREE(srv->server_name);
+ SAFE_FREE(srv->share_name);
+ SAFE_FREE(srv->workgroup);
+ SAFE_FREE(srv->username);
SAFE_FREE(srv);
return NULL;
}
+/*
+ *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl)
+ *
+ * We accept a *srv
+ */
+BOOL smbc_remove_unused_server(struct smbc_server * s)
+{
+ int p;
+
+ /* are we being fooled ? */
+ if (!s) return False;
+
+ /* close all open files/directories on this server */
+ for (p = 0; p < SMBC_MAX_FD; p++) {
+ if (smbc_file_table[p] &&
+ smbc_file_table[p]->srv == s) {
+ /* Still used .. DARN */
+ DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s,
+ smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd));
+ return False;
+ }
+ }
+
+ cli_shutdown(&s->cli);
+
+ SAFE_FREE(s->username);
+ SAFE_FREE(s->workgroup);
+ SAFE_FREE(s->server_name);
+ SAFE_FREE(s->share_name);
+ DLIST_REMOVE(smbc_srvs, s);
+ DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s));
+ SAFE_FREE(s);
+ return True;
+}
+
+
/*
- * Connect to a server for getting/setting attributes, possibly on an existing
- * connection. This works similarly to smbc_server().
+ *Initialise the library etc
+ *
+ * We accept valiv values for debug from 0 to 100,
+ * and insist that fn must be non-null.
*/
-SMBCSRV *smbc_attr_server(SMBCCTX *context,
- const char *server, const char *share,
- fstring workgroup,
- fstring username, fstring password,
- POLICY_HND *pol)
+
+int smbc_init(smbc_get_auth_data_fn fn, int debug)
{
- struct in_addr ip;
- struct cli_state *ipc_cli;
- NTSTATUS nt_status;
- SMBCSRV *ipc_srv=NULL;
-
- /*
- * See if we've already created this special connection. Reference
- * our "special" share name 'IPC$$'.
- */
- ipc_srv = find_server(context, server, "IPC$$",
- workgroup, username, password);
- if (!ipc_srv) {
-
- /* We didn't find a cached connection. Get the password */
- if (*password == '\0') {
- /* ... then retrieve it now. */
- context->callbacks.auth_fn(server, share,
- workgroup, sizeof(fstring),
- username, sizeof(fstring),
- password, sizeof(fstring));
- }
-
- zero_ip(&ip);
- nt_status = cli_full_connection(&ipc_cli,
- global_myname(), server,
- &ip, 0, "IPC$", "?????",
- username, workgroup,
- password, 0,
- Undefined, NULL);
- if (! NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1,("cli_full_connection failed! (%s)\n",
- nt_errstr(nt_status)));
- errno = ENOTSUP;
- return NULL;
- }
-
- if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) {
- DEBUG(1, ("cli_nt_session_open fail!\n"));
- errno = ENOTSUP;
- cli_shutdown(ipc_cli);
- return NULL;
- }
-
- /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
- but NT sends 0x2000000 so we might as well do it too. */
-
- nt_status = cli_lsa_open_policy(ipc_cli,
- ipc_cli->mem_ctx,
- True,
- GENERIC_EXECUTE_ACCESS,
- pol);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- errno = smbc_errno(context, ipc_cli);
- cli_shutdown(ipc_cli);
- return NULL;
- }
-
- ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv));
- if (!ipc_srv) {
- errno = ENOMEM;
- cli_shutdown(ipc_cli);
- return NULL;
- }
-
- ZERO_STRUCTP(ipc_srv);
- ipc_srv->cli = *ipc_cli;
-
- free(ipc_cli);
-
- /* now add it to the cache (internal or external) */
-
- errno = 0; /* let cache function set errno if it likes */
- if (context->callbacks.add_cached_srv_fn(context, ipc_srv,
- server,
- "IPC$$",
- workgroup,
- username)) {
- DEBUG(3, (" Failed to add server to cache\n"));
- if (errno == 0) {
- errno = ENOMEM;
- }
- cli_shutdown(&ipc_srv->cli);
- free(ipc_srv);
- return NULL;
- }
-
- DLIST_ADD(context->internal->_servers, ipc_srv);
- }
+ pstring conf;
+ int p, pid;
+ char *user = NULL, *home = NULL, *pname="libsmbclient";
+
+ if (!fn || debug < 0 || debug > 100) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ if (smbc_initialized) { /* Don't go through this if we have already done it */
+
+ return 0;
+
+ }
+
+ smbc_initialized = 1;
+ smbc_auth_fn = fn;
+ /* smbc_debug = debug; */
+
+ DEBUGLEVEL = -1;
+
+ setup_logging(pname, False);
+
+ /* Here we would open the smb.conf file if needed ... */
+
+ home = getenv("HOME");
+
+ slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
+
+ load_interfaces(); /* Load the list of interfaces ... */
+
+ charset_initialise();
+
+ in_client = True; /* FIXME, make a param */
+
+ if (!lp_load(conf, True, False, False)) {
+
+ /*
+ * Hmmm, what the hell do we do here ... we could not parse the
+ * config file ... We must return an error ... and keep info around
+ * about why we failed
+ */
+
+ errno = ENOENT; /* FIXME: Figure out the correct error response */
+ return -1;
+
+ }
+
+ codepage_initialise(lp_client_code_page()); /* Get a codepage */
+
+ reopen_logs(); /* Get logging working ... */
+
+ /*
+ * FIXME: Is this the best way to get the user info?
+ */
+
+ user = getenv("USER");
+ /* walk around as "guest" if no username can be found */
+ if (!user) user = strdup("guest");
+ pstrcpy(smbc_user, user); /* Save for use elsewhere */
+
+ /*
+ * We try to get our netbios name from the config. If that fails we fall
+ * back on constructing our netbios name from our hostname etc
+ */
+ if (global_myname) {
+ pstrcpy(my_netbios_name, global_myname);
+ }
+ else {
+ /*
+ * Hmmm, I want to get hostname as well, but I am too lazy for the moment
+ */
+ pid = getpid();
+ slprintf(my_netbios_name, 16, "smbc%s%d", user, pid);
+ }
+ DEBUG(0,("Using netbios name %s.\n", my_netbios_name));
+
+ name_register_wins(my_netbios_name, 0);
+
+ /*
+ * Now initialize the file descriptor array and figure out what the
+ * max open files is, so we can return FD's that are above the max
+ * open file, and separated by a guard band
+ */
+
+#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
+ do {
+ struct rlimit rlp;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlp)) {
+
+ DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno)));
+
+ smbc_start_fd = 1000000;
+
+ }
+ else {
+
+ smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */
+
+ }
+ } while ( 0 );
+#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
+
+ smbc_start_fd = 1000000;
+
+#endif
+
+ smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *));
+ if (!smbc_file_table)
+ return ENOMEM;
+
+ for (p = 0; p < SMBC_MAX_FD; p++)
+ smbc_file_table[p] = NULL;
+
+ return 0; /* Success */
- return ipc_srv;
}
/*
* Routine to open() a file ...
*/
-static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode)
+int smbc_open(const char *fname, int flags, mode_t mode)
{
fstring server, share, user, password, workgroup;
pstring path;
- SMBCSRV *srv = NULL;
- SMBCFILE *file = NULL;
+ struct smbc_server *srv = NULL;
int fd;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL; /* Best I can think of ... */
- return NULL;
+ return -1;
}
if (!fname) {
errno = EINVAL;
- return NULL;
+ return -1;
}
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return NULL;
- }
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- fstrcpy(workgroup, context->workgroup);
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
if (errno == EPERM) errno = EACCES;
- return NULL; /* smbc_server sets errno */
+ return -1; /* smbc_server sets errno */
}
@@ -864,37 +645,49 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m
}
else {
- file = malloc(sizeof(SMBCFILE));
+ int slot = 0;
- if (!file) {
+ /* Find a free slot first */
- errno = ENOMEM;
- return NULL;
+ while (smbc_file_table[slot])
+ slot++;
+
+ if (slot > SMBC_MAX_FD) {
+
+ errno = ENOMEM; /* FIXME, is this best? */
+ return -1;
}
- ZERO_STRUCTP(file);
+ smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
+
+ if (!smbc_file_table[slot]) {
+
+ errno = ENOMEM;
+ return -1;
+
+ }
if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) {
/* Handle the error ... */
- SAFE_FREE(file);
- errno = smbc_errno(context, &srv->cli);
- return NULL;
+ SAFE_FREE(smbc_file_table[slot]);
+ errno = smbc_errno(&srv->cli);
+ return -1;
}
/* Fill in file struct */
- file->cli_fd = fd;
- file->fname = strdup(fname);
- file->srv = srv;
- file->offset = 0;
- file->file = True;
+ smbc_file_table[slot]->cli_fd = fd;
+ smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
+ smbc_file_table[slot]->fname = strdup(fname);
+ smbc_file_table[slot]->srv = srv;
+ smbc_file_table[slot]->offset = 0;
+ smbc_file_table[slot]->file = True;
- DLIST_ADD(context->internal->_files, file);
- return file;
+ return smbc_file_table[slot]->smbc_fd;
}
@@ -903,15 +696,14 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m
if (fd == -1) {
int eno = 0;
- eno = smbc_errno(context, &srv->cli);
- file = context->opendir(context, fname);
- if (!file) errno = eno;
- return file;
+ eno = smbc_errno(&srv->cli);
+ fd = smbc_opendir(fname);
+ if (fd < 0) errno = eno;
+ return fd;
}
- errno = EINVAL; /* FIXME, correct errno ? */
- return NULL;
+ return 1; /* Success, with fd ... */
}
@@ -921,39 +713,38 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m
static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */
-static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode)
+int smbc_creat(const char *path, mode_t mode)
{
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
- return NULL;
+ return -1;
}
- return smbc_open_ctx(context, path, creat_bits, mode);
+ return smbc_open(path, creat_bits, mode);
}
/*
* Routine to read() a file ...
*/
-static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
+ssize_t smbc_read(int fd, void *buf, size_t count)
{
+ struct smbc_file *fe;
int ret;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count));
+ DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count));
- if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
errno = EBADF;
return -1;
@@ -969,16 +760,25 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
}
- ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count);
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe || !fe->file) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count);
if (ret < 0) {
- errno = smbc_errno(context, &file->srv->cli);
+ errno = smbc_errno(&fe->srv->cli);
return -1;
}
- file->offset += ret;
+ fe->offset += ret;
DEBUG(4, (" --> %d\n", ret));
@@ -990,19 +790,19 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
* Routine to write() a file ...
*/
-static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
+ssize_t smbc_write(int fd, void *buf, size_t count)
{
int ret;
+ struct smbc_file *fe;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
errno = EBADF;
return -1;
@@ -1018,16 +818,25 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_
}
- ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count);
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe || !fe->file) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count);
if (ret <= 0) {
- errno = smbc_errno(context, &file->srv->cli);
+ errno = smbc_errno(&fe->srv->cli);
return -1;
}
- file->offset += ret;
+ fe->offset += ret;
return ret; /* Success, 0 bytes of data ... */
}
@@ -1036,109 +845,72 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_
* Routine to close() a file ...
*/
-static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file)
+int smbc_close(int fd)
{
- SMBCSRV *srv;
+ struct smbc_file *fe;
+ struct smbc_server *srv;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
errno = EBADF;
return -1;
}
- /* IS a dir ... */
- if (!file->file) {
-
- return context->closedir(context, file);
-
- }
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!cli_close(&file->srv->cli, file->cli_fd)) {
-
- DEBUG(3, ("cli_close failed on %s. purging server.\n",
- file->fname));
- /* Deallocate slot and remove the server
- * from the server cache if unused */
- errno = smbc_errno(context, &file->srv->cli);
- srv = file->srv;
- DLIST_REMOVE(context->internal->_files, file);
- SAFE_FREE(file->fname);
- SAFE_FREE(file);
- context->callbacks.remove_unused_server_fn(context, srv);
+ if (!fe) {
+ errno = EBADF;
return -1;
}
- DLIST_REMOVE(context->internal->_files, file);
- SAFE_FREE(file->fname);
- SAFE_FREE(file);
+ if (!fe->file) {
- return 0;
-}
-
-/*
- * Get info from an SMB server on a file. Use a qpathinfo call first
- * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
- */
-static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path,
- uint16 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time,
- SMB_INO_T *ino)
-{
+ return smbc_closedir(fd);
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
-
- if (!srv->no_pathinfo2 &&
- cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
- size, mode, ino)) return True;
-
- /* if this is NT then don't bother with the getatr */
- if (srv->cli.capabilities & CAP_NT_SMBS) {
- errno = EPERM;
- return False;
- }
+ }
- if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
- a_time = c_time = m_time;
- srv->no_pathinfo2 = True;
- return True;
+ if (!cli_close(&fe->srv->cli, fe->cli_fd)) {
+ DEBUG(3, ("cli_close failed on %s (%d). purging server.\n",
+ fe->fname, fe->smbc_fd));
+ /* Deallocate slot and remove the server
+ * from the server cache if unused */
+ errno = smbc_errno(&fe->srv->cli);
+ srv = fe->srv;
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe);
+ smbc_file_table[fd - smbc_start_fd] = NULL;
+ smbc_remove_unused_server(srv);
+ return -1;
}
- errno = EPERM;
- return False;
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe);
+ smbc_file_table[fd - smbc_start_fd] = NULL;
+ return 0;
}
/*
* Routine to unlink() a file
*/
-static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
+int smbc_unlink(const char *fname)
{
fstring server, share, user, password, workgroup;
pstring path;
- SMBCSRV *srv = NULL;
+ struct smbc_server *srv = NULL;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL; /* Best I can think of ... */
return -1;
@@ -1152,22 +924,13 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
}
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- fstrcpy(workgroup, context->workgroup);
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
@@ -1193,7 +956,7 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
if (!cli_unlink(&srv->cli, path)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(&srv->cli);
if (errno == EACCES) { /* Check if the file is a directory */
@@ -1203,12 +966,12 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
time_t m_time = 0, a_time = 0, c_time = 0;
SMB_INO_T ino = 0;
- if (!smbc_getatr(context, srv, path, &mode, &size,
+ if (!smbc_getatr(srv, path, &mode, &size,
&c_time, &a_time, &m_time, &ino)) {
/* Hmmm, bad error ... What? */
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(&srv->cli);
return -1;
}
@@ -1234,17 +997,13 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
* Routine to rename() a file
*/
-static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
- SMBCCTX *ncontext, const char *nname)
+int smbc_rename(const char *oname, const char *nname)
{
fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup;
pstring path1, path2;
- SMBCSRV *srv = NULL;
+ struct smbc_server *srv = NULL;
- if (!ocontext || !ncontext ||
- !ocontext->internal || !ncontext->internal ||
- !ocontext->internal->_initialized ||
- !ncontext->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL; /* Best I can think of ... */
return -1;
@@ -1260,25 +1019,13 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
- smbc_parse_path(ocontext, oname,
- server1, sizeof(server1),
- share1, sizeof(share1),
- path1, sizeof(path1),
- user1, sizeof(user1),
- password1, sizeof(password1),
- NULL, 0);
+ smbc_parse_path(oname, server1, share1, path1, user1, password1);
- if (user1[0] == (char)0) fstrcpy(user1, ocontext->user);
+ if (user1[0] == (char)0) pstrcpy(user1, smbc_user);
- smbc_parse_path(ncontext, nname,
- server2, sizeof(server2),
- share2, sizeof(share2),
- path2, sizeof(path2),
- user2, sizeof(user2),
- password2, sizeof(password2),
- NULL, 0);
+ smbc_parse_path(nname, server2, share2, path2, user2, password2);
- if (user2[0] == (char)0) fstrcpy(user2, ncontext->user);
+ if (user2[0] == (char)0) pstrcpy(user2, smbc_user);
if (strcmp(server1, server2) || strcmp(share1, share2) ||
strcmp(user1, user2)) {
@@ -1290,9 +1037,9 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
}
- fstrcpy(workgroup, ocontext->workgroup);
- /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */
- srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1);
+ pstrcpy(workgroup, lp_workgroup());
+
+ srv = smbc_server(server1, share1, workgroup, user1, password1);
if (!srv) {
return -1;
@@ -1300,7 +1047,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
}
if (!cli_rename(&srv->cli, path1, path2)) {
- int eno = smbc_errno(ocontext, &srv->cli);
+ int eno = smbc_errno(&srv->cli);
if (eno != EEXIST ||
!cli_unlink(&srv->cli, path2) ||
@@ -1320,26 +1067,35 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
* A routine to lseek() a file
*/
-static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence)
+off_t smbc_lseek(int fd, off_t offset, int whence)
{
+ struct smbc_file *fe;
size_t size;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
errno = EBADF;
return -1;
}
- if (!file->file) {
+ if (!fe->file) {
errno = EINVAL;
return -1; /* Can't lseek a dir ... */
@@ -1348,27 +1104,23 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int
switch (whence) {
case SEEK_SET:
- file->offset = offset;
+ fe->offset = offset;
break;
case SEEK_CUR:
- file->offset += offset;
+ fe->offset += offset;
break;
case SEEK_END:
- if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL,
- NULL, NULL, NULL))
- {
- SMB_BIG_UINT b_size = size;
- if (!cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &b_size, NULL, NULL,
- NULL))
- {
+ if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
+ NULL, NULL, NULL) &&
+ !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
+ NULL)) {
+
errno = EINVAL;
return -1;
- } else
- size = b_size;
}
- file->offset = size + offset;
+ fe->offset = size + offset;
break;
default:
@@ -1377,7 +1129,7 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int
}
- return file->offset;
+ return fe->offset;
}
@@ -1386,17 +1138,9 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int
*/
static
-ino_t smbc_inode(SMBCCTX *context, const char *name)
+ino_t smbc_inode(const char *name)
{
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL;
- return -1;
-
- }
-
if (!*name) return 2; /* FIXME, why 2 ??? */
return (ino_t)str_checksum(name);
@@ -1408,7 +1152,7 @@ ino_t smbc_inode(SMBCCTX *context, const char *name)
*/
static
-int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode)
+int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode)
{
st->st_mode = 0;
@@ -1425,12 +1169,8 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size,
if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
st->st_size = size;
-#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = 512;
-#endif
-#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = (size+511)/512;
-#endif
st->st_uid = getuid();
st->st_gid = getgid();
@@ -1441,7 +1181,7 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size,
}
if (st->st_ino == 0) {
- st->st_ino = smbc_inode(context, fname);
+ st->st_ino = smbc_inode(fname);
}
return True; /* FIXME: Is this needed ? */
@@ -1449,12 +1189,47 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size,
}
/*
+ * Get info from an SMB server on a file. Use a qpathinfo call first
+ * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
+ */
+
+BOOL smbc_getatr(struct smbc_server *srv, char *path,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino)
+{
+
+ if (!smbc_initialized) {
+
+ errno = EINVAL;
+ return -1;
+
+ }
+
+ DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
+
+ if (!srv->no_pathinfo2 &&
+ cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
+ size, mode, ino)) return True;
+
+ /* if this is NT then don't bother with the getatr */
+ if (srv->cli.capabilities & CAP_NT_SMBS) return False;
+
+ if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
+ a_time = c_time = m_time;
+ srv->no_pathinfo2 = True;
+ return True;
+ }
+ return False;
+}
+
+/*
* Routine to stat a file given a name
*/
-static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
+int smbc_stat(const char *fname, struct stat *st)
{
- SMBCSRV *srv;
+ struct smbc_server *srv;
fstring server, share, user, password, workgroup;
pstring path;
time_t m_time = 0, a_time = 0, c_time = 0;
@@ -1462,8 +1237,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
uint16 mode = 0;
SMB_INO_T ino = 0;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL; /* Best I can think of ... */
return -1;
@@ -1479,38 +1253,52 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
DEBUG(4, ("smbc_stat(%s)\n", fname));
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- fstrcpy(workgroup, context->workgroup);
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
+
return -1; /* errno set by smbc_server */
+
}
- if (!smbc_getatr(context, srv, path, &mode, &size,
+ /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
+
+ mode = aDIR | aRONLY;
+
+ }
+ else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+
+ if (strcmp(path, "\\") == 0) {
+
+ mode = aDIR | aRONLY;
+
+ }
+ else {
+
+ mode = aRONLY;
+ smbc_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
+
+ }
+ else { */
+
+ if (!smbc_getatr(srv, path, &mode, &size,
&c_time, &a_time, &m_time, &ino)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(&srv->cli);
return -1;
}
st->st_ino = ino;
- smbc_setup_stat(context, st, path, size, mode);
+ smbc_setup_stat(st, path, size, mode);
st->st_atime = a_time;
st->st_ctime = c_time;
@@ -1525,55 +1313,61 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
* Routine to stat a file given an fd
*/
-static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
+int smbc_fstat(int fd, struct stat *st)
{
+ struct smbc_file *fe;
time_t c_time, a_time, m_time;
size_t size;
uint16 mode;
SMB_INO_T ino = 0;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
errno = EBADF;
return -1;
}
- if (!file->file) {
+ if (!fe->file) {
- return context->fstatdir(context, file, st);
+ return smbc_fstatdir(fd, st);
}
- if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) {
- SMB_BIG_UINT b_size = size;
- if (!cli_getattrE(&file->srv->cli, file->cli_fd,
- &mode, &b_size, &c_time, &a_time, &m_time)) {
+ if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) &&
+ !cli_getattrE(&fe->srv->cli, fe->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time)) {
errno = EINVAL;
return -1;
- } else
- size = b_size;
}
st->st_ino = ino;
- smbc_setup_stat(context, st, file->fname, size, mode);
+ smbc_setup_stat(st, fe->fname, size, mode);
st->st_atime = a_time;
st->st_ctime = c_time;
st->st_mtime = m_time;
- st->st_dev = file->srv->dev;
+ st->st_dev = fe->srv->dev;
return 0;
@@ -1581,10 +1375,19 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
/*
* Routine to open a directory
- * We accept the URL syntax explained in smbc_parse_path(), above.
+ *
+ * We want to allow:
+ *
+ * smb: which should list all the workgroups available
+ * smb:workgroup
+ * smb:workgroup//server
+ * smb://server
+ * smb://server/share
+ * smb://<IP-addr> which should list shares on server
+ * smb://<IP-addr>/share which should list files on share
*/
-static void smbc_remove_dir(SMBCFILE *dir)
+static void smbc_remove_dir(struct smbc_file *dir)
{
struct smbc_dir_list *d,*f;
@@ -1602,17 +1405,10 @@ static void smbc_remove_dir(SMBCFILE *dir)
}
-static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type)
+static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type)
{
struct smbc_dirent *dirent;
int size;
- char *u_name = NULL, *u_comment = NULL;
- size_t u_name_len = 0, u_comment_len = 0;
-
- if (name)
- u_name_len = push_utf8_allocate(&u_name, name);
- if (comment)
- u_comment_len = push_utf8_allocate(&u_comment, comment);
/*
* Allocate space for the dirent, which must be increased by the
@@ -1620,7 +1416,8 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
* The null on the name is already accounted for.
*/
- size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1;
+ size = sizeof(struct smbc_dirent) + (name?strlen(name):0) +
+ (comment?strlen(comment):0) + 1;
dirent = malloc(size);
@@ -1631,8 +1428,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
}
- ZERO_STRUCTP(dirent);
-
if (dir->dir_list == NULL) {
dir->dir_list = malloc(sizeof(struct smbc_dir_list));
@@ -1643,9 +1438,9 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
return -1;
}
- ZERO_STRUCTP(dir->dir_list);
dir->dir_end = dir->dir_next = dir->dir_list;
+
}
else {
@@ -1658,75 +1453,32 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
return -1;
}
- ZERO_STRUCTP(dir->dir_end->next);
dir->dir_end = dir->dir_end->next;
+
}
dir->dir_end->next = NULL;
dir->dir_end->dirent = dirent;
dirent->smbc_type = type;
- dirent->namelen = u_name_len;
- dirent->commentlen = u_comment_len;
+ dirent->namelen = (name?strlen(name):0);
+ dirent->commentlen = (comment?strlen(comment):0);
dirent->dirlen = size;
- strncpy(dirent->name, (u_name?u_name:""), dirent->namelen + 1);
+ strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
- strncpy(dirent->comment, (u_comment?u_comment:""), dirent->commentlen + 1);
-
- SAFE_FREE(u_comment);
- SAFE_FREE(u_name);
+ strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
return 0;
}
static void
-list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state)
-{
- SMBCFILE *dir = (SMBCFILE *)state;
- struct smbc_dir_list *dir_list;
- struct smbc_dirent *dirent;
- int dirent_type;
- int remove = 0;
-
- dirent_type = dir->dir_type;
-
- if (add_dirent(dir, name, comment, dirent_type) < 0) {
-
- /* An error occurred, what do we do? */
- /* FIXME: Add some code here */
- }
-
- /* Point to the one just added */
- dirent = dir->dir_end->dirent;
-
- /* See if this was a duplicate */
- for (dir_list = dir->dir_list;
- dir_list != dir->dir_end;
- dir_list = dir_list->next) {
- if (! remove &&
- strcmp(dir_list->dirent->name, dirent->name) == 0) {
- /* Duplicate. End end of list need to be removed. */
- remove = 1;
- }
-
- if (remove && dir_list->next == dir->dir_end) {
- /* Found the end of the list. Remove it. */
- dir->dir_end = dir_list;
- free(dir_list->next);
- dir_list->next = NULL;
- break;
- }
- }
-}
-
-static void
list_fn(const char *name, uint32 type, const char *comment, void *state)
{
- SMBCFILE *dir = (SMBCFILE *)state;
+ struct smbc_file *dir = (struct smbc_file *)state;
int dirent_type;
/* We need to process the type a little ... */
@@ -1754,6 +1506,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state)
dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */
break;
}
+
}
else dirent_type = dir->dir_type;
@@ -1763,13 +1516,14 @@ list_fn(const char *name, uint32 type, const char *comment, void *state)
/* FIXME: Add some code here */
}
+
}
static void
dir_list_fn(file_info *finfo, const char *mask, void *state)
{
- if (add_dirent((SMBCFILE *)state, finfo->name, "",
+ if (add_dirent((struct smbc_file *)state, finfo->name, "",
(finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
/* Handle an error ... */
@@ -1780,273 +1534,155 @@ dir_list_fn(file_info *finfo, const char *mask, void *state)
}
-static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
+int smbc_opendir(const char *fname)
{
- fstring server, share, user, password, options;
- pstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
- SMBCSRV *srv = NULL;
- SMBCFILE *dir = NULL;
+ struct smbc_server *srv = NULL;
struct in_addr rem_ip;
+ int slot = 0;
+
+ if (!smbc_initialized) {
- if (!context || !context->internal ||
- !context->internal->_initialized) {
- DEBUG(4, ("no valid context\n"));
errno = EINVAL;
- return NULL;
+ return -1;
}
if (!fname) {
- DEBUG(4, ("no valid fname\n"));
+
errno = EINVAL;
- return NULL;
+ return -1;
+
}
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- options, sizeof(options))) {
- DEBUG(4, ("no valid path\n"));
+ if (smbc_parse_path(fname, server, share, path, user, password)) {
+
errno = EINVAL;
- return NULL;
+ return -1;
+
}
- DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s' options='%s'\n", fname, server, share, path, options));
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- /* Ensure the options are valid */
- if (smbc_check_options(server, share, path, options)) {
- DEBUG(4, ("unacceptable options (%s)\n", options));
- errno = EINVAL;
- return NULL;
- }
+ pstrcpy(workgroup, lp_workgroup());
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ /* Get a file entry ... */
- pstrcpy(workgroup, context->workgroup);
+ slot = 0;
- dir = malloc(sizeof(*dir));
+ while (smbc_file_table[slot])
+ slot++;
- if (!dir) {
+ if (slot > SMBC_MAX_FD) {
errno = ENOMEM;
- return NULL;
+ return -1; /* FIXME, ... move into a func */
+
+ }
+
+ smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
+
+ if (!smbc_file_table[slot]) {
+
+ errno = ENOMEM;
+ return -1;
}
- ZERO_STRUCTP(dir);
+ smbc_file_table[slot]->cli_fd = 0;
+ smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
+ smbc_file_table[slot]->fname = strdup(fname);
+ smbc_file_table[slot]->srv = NULL;
+ smbc_file_table[slot]->offset = 0;
+ smbc_file_table[slot]->file = False;
+ smbc_file_table[slot]->dir_list =
+ smbc_file_table[slot]->dir_next =
+ smbc_file_table[slot]->dir_end = NULL;
- dir->cli_fd = 0;
- dir->fname = strdup(fname);
- dir->srv = NULL;
- dir->offset = 0;
- dir->file = False;
- dir->dir_list = dir->dir_next = dir->dir_end = NULL;
+ if (server[0] == (char)0) {
- if (server[0] == (char)0 &&
- (! *options || strcmp(options, "mb=.any") == 0)) {
- struct in_addr server_ip;
if (share[0] != (char)0 || path[0] != (char)0) {
-
+
errno = EINVAL;
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
+
}
- /*
- * We have server and share and path empty ... so list the
- * workgroups first try to get the LMB for our workgroup, and
- * if that fails, try the DMB
- */
+ /* We have server and share and path empty ... so list the workgroups */
+ /* first try to get the LMB for our workgroup, and if that fails, */
+ /* try the DMB */
- pstrcpy(workgroup, lp_workgroup());
+ if (!(resolve_name(lp_workgroup(), &rem_ip, 0x1d) ||
+ resolve_name(lp_workgroup(), &rem_ip, 0x1b))) {
+
+ errno = EINVAL; /* Something wrong with smb.conf? */
+ return -1;
- if (!find_master_ip(workgroup, &server_ip)) {
- struct user_auth_info u_info;
- struct cli_state *cli;
+ }
- DEBUG(4, ("Unable to find master browser for workgroup %s\n",
- workgroup));
+ smbc_file_table[slot]->dir_type = SMBC_WORKGROUP;
- /* find the name of the server ... */
- pstrcpy(u_info.username, user);
- pstrcpy(u_info.password, password);
+ /* find the name of the server ... */
- if (!(cli = get_ipc_connect_master_ip_bcast(workgroup, &u_info))) {
- DEBUG(4, ("Unable to find master browser by "
- "broadcast\n"));
- errno = ENOENT;
- return NULL;
- }
+ if (!name_status_find("*", 0, 0, rem_ip, server)) {
- fstrcpy(server, cli->desthost);
-
- cli_shutdown(cli);
- } else {
- /*
- * Do a name status query to find out the name of the
- * master browser. We use <01><02>__MSBROWSE__<02>#01 if
- * *#00 fails because a domain master browser will not
- * respond to a wildcard query (or, at least, an NT4
- * server acting as the domain master browser will not).
- *
- * We might be able to use ONLY the query on MSBROWSE, but
- * that's not yet been tested with all Windows versions,
- * so until it is, leave the original wildcard query as
- * the first choice and fall back to MSBROWSE if the
- * wildcard query fails.
- */
- if (!name_status_find("*", 0, 0x1d, server_ip, server) &&
- !name_status_find(MSBROWSE, 1, 0x1d, server_ip, server)) {
- errno = ENOENT;
- return NULL;
- }
- }
+ DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server));
+ errno = EINVAL;
+ return -1;
- DEBUG(4, ("using workgroup %s %s\n", workgroup, server));
+ }
- /*
- * Get a connection to IPC$ on the server if we do not already
- * have one
- */
-
- srv = smbc_server(context, server, "IPC$", workgroup, user, password);
- if (!srv) {
-
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
- }
-
- dir->srv = srv;
- dir->dir_type = SMBC_WORKGROUP;
+ /*
+ * Get a connection to IPC$ on the server if we do not already have one
+ */
- /* Now, list the stuff ... */
+ srv = smbc_server(server, "IPC$", workgroup, user, password);
- if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn,
- (void *)dir)) {
+ if (!srv) {
- DEBUG(1, ("Could not enumerate domains using '%s'\n", workgroup));
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- errno = cli_errno(&srv->cli);
-
- return NULL;
+
+ return -1;
}
- } else if (server[0] == (char)0 &&
- (! *options || strcmp(options, "mb=.all") == 0)) {
- int i;
- int count;
- struct ip_service *ip_list;
- struct ip_service server_addr;
- struct user_auth_info u_info;
- struct cli_state *cli;
+ smbc_file_table[slot]->srv = srv;
- if (share[0] != (char)0 || path[0] != (char)0) {
+ /* Now, list the stuff ... */
- errno = EINVAL;
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn,
+ (void *)smbc_file_table[slot])) {
+
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
- }
+ errno = cli_errno(&srv->cli);
- pstrcpy(u_info.username, user);
- pstrcpy(u_info.password, password);
+ return -1;
+
+ }
+ }
+ else { /* Server not an empty string ... Check the rest and see what gives */
- /*
- * We have server and share and path empty but options
- * requesting that we scan all master browsers for their list
- * of workgroups/domains. This implies that we must first try
- * broadcast queries to find all master browsers, and if that
- * doesn't work, then try our other methods which return only
- * a single master browser.
- */
-
- if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
- if (!find_master_ip(workgroup, &server_addr.ip)) {
-
- errno = ENOENT;
- return NULL;
- }
-
- ip_list = &server_addr;
- count = 1;
- }
-
- for (i = 0; i < count; i++) {
- DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
-
- cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info);
- fstrcpy(server, cli->desthost);
- cli_shutdown(cli);
-
- DEBUG(4, ("using workgroup %s %s\n", workgroup, server));
-
- /*
- * For each returned master browser IP address, get a
- * connection to IPC$ on the server if we do not
- * already have one, and determine the
- * workgroups/domains that it knows about.
- */
-
- srv = smbc_server(context, server,
- "IPC$", workgroup, user, password);
- if (!srv) {
-
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
- }
-
- dir->srv = srv;
- dir->dir_type = SMBC_WORKGROUP;
-
- /* Now, list the stuff ... */
-
- if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
- (void *)dir)) {
-
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- errno = cli_errno(&srv->cli);
-
- return NULL;
-
- }
- }
- } else {
- /*
- * Server not an empty string ... Check the rest and see what
- * gives
- */
if (share[0] == (char)0) {
if (path[0] != (char)0) { /* Should not have empty share with path */
errno = EINVAL;
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
@@ -2056,20 +1692,20 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
if (!is_ipaddress(server) && /* Not an IP addr so check next */
(resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */
resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */
- fstring buserver;
+ pstring buserver;
- dir->dir_type = SMBC_SERVER;
+ smbc_file_table[slot]->dir_type = SMBC_SERVER;
/*
* Get the backup list ...
*/
- if (!name_status_find(server, 0, 0, rem_ip, buserver)) {
+ if (!name_status_find("*", 0, 0, rem_ip, buserver)) {
DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server));
errno = EPERM; /* FIXME, is this correct */
- return NULL;
+ return -1;
}
@@ -2077,33 +1713,34 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
* Get a connection to IPC$ on the server if we do not already have one
*/
- srv = smbc_server(context, buserver, "IPC$", workgroup, user, password);
+ srv = smbc_server(buserver, "IPC$", workgroup, user, password);
if (!srv) {
- DEBUG(0, ("got no contact to IPC$\n"));
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
- dir->srv = srv;
+ smbc_file_table[slot]->srv = srv;
/* Now, list the servers ... */
if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn,
- (void *)dir)) {
+ (void *)smbc_file_table[slot])) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
errno = cli_errno(&srv->cli);
- return NULL;
+ return -1;
}
+
}
else {
@@ -2111,33 +1748,33 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
/* Now, list the shares ... */
- dir->dir_type = SMBC_FILE_SHARE;
+ smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(context, server, "IPC$", workgroup, user, password);
+ srv = smbc_server(server, "IPC$", workgroup, user, password);
if (!srv) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
- dir->srv = srv;
+ smbc_file_table[slot]->srv = srv;
/* Now, list the servers ... */
if (cli_RNetShareEnum(&srv->cli, list_fn,
- (void *)dir) < 0) {
+ (void *)smbc_file_table[slot]) < 0) {
errno = cli_errno(&srv->cli);
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
@@ -2145,11 +1782,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
else {
errno = ENODEV; /* Neither the workgroup nor server exists */
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
@@ -2160,43 +1797,42 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
/* Well, we connect to the server and list the directory */
- dir->dir_type = SMBC_FILE_SHARE;
+ smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- return NULL;
+ return -1;
}
- dir->srv = srv;
+ smbc_file_table[slot]->srv = srv;
/* Now, list the files ... */
pstrcat(path, "\\*");
if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn,
- (void *)dir) < 0) {
+ (void *)smbc_file_table[slot]) < 0) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
}
- errno = smbc_errno(context, &srv->cli);
- return NULL;
+ errno = smbc_errno(&srv->cli);
+ return -1;
}
}
}
- DLIST_ADD(context->internal->_files, dir);
- return dir;
+ return smbc_file_table[slot]->smbc_fd;
}
@@ -2204,34 +1840,44 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
* Routine to close a directory
*/
-static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir)
+int smbc_closedir(int fd)
{
+ struct smbc_file *fe;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
errno = EBADF;
return -1;
}
- smbc_remove_dir(dir); /* Clean it up */
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ smbc_remove_dir(fe); /* Clean it up */
- DLIST_REMOVE(context->internal->_files, dir);
+ if (fe) {
- if (dir) {
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe); /* Free the space too */
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir); /* Free the space too */
}
+ smbc_file_table[fd - smbc_start_fd] = NULL;
+
return 0;
}
@@ -2240,43 +1886,51 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir)
* Routine to get a directory entry
*/
-struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
+static char smbc_local_dirent[512]; /* Make big enough */
+
+struct smbc_dirent *smbc_readdir(unsigned int fd)
{
+ struct smbc_file *fe;
struct smbc_dirent *dirp, *dirent;
/* Check that all is ok first ... */
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
- DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n"));
return NULL;
}
- if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
errno = EBADF;
- DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n"));
return NULL;
}
- if (dir->file != False) { /* FIXME, should be dir, perhaps */
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
+
+ errno = EBADF;
+ return NULL;
+
+ }
+
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
- DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n"));
return NULL;
}
- if (!dir->dir_next) {
+ if (!fe->dir_next)
return NULL;
- }
else {
- dirent = dir->dir_next->dirent;
+ dirent = fe->dir_next->dirent;
+
if (!dirent) {
errno = ENOENT;
@@ -2286,12 +1940,12 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
/* Hmmm, do I even need to copy it? */
- memcpy(context->internal->_dirent, dirent, dirent->dirlen); /* Copy the dirent */
- dirp = (struct smbc_dirent *)context->internal->_dirent;
+ memcpy(smbc_local_dirent, dirent, dirent->dirlen); /* Copy the dirent */
+ dirp = (struct smbc_dirent *)smbc_local_dirent;
dirp->comment = (char *)(&dirp->name + dirent->namelen + 1);
- dir->dir_next = dir->dir_next->next;
+ fe->dir_next = fe->dir_next->next;
- return (struct smbc_dirent *)context->internal->_dirent;
+ return (struct smbc_dirent *)smbc_local_dirent;
}
}
@@ -2300,30 +1954,39 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
* Routine to get directory entries
*/
-static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count)
+int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count)
{
- struct smbc_dir_list *dirlist;
+ struct smbc_file *fe;
+ struct smbc_dir_list *dir;
int rem = count, reqd;
char *ndir = (char *)dirp;
/* Check that all is ok first ... */
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
errno = EBADF;
return -1;
}
- if (dir->file != False) { /* FIXME, should be dir, perhaps */
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
return -1;
@@ -2336,18 +1999,18 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
* send a request to the server to get the info.
*/
- while ((dirlist = dir->dir_next)) {
+ while ((dir = fe->dir_next)) {
struct smbc_dirent *dirent;
- if (!dirlist->dirent) {
+ if (!dir->dirent) {
errno = ENOENT; /* Bad error */
return -1;
}
- if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen +
- dirlist->dirent->commentlen + 1))) {
+ if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen +
+ dir->dirent->commentlen + 1))) {
if (rem < count) { /* We managed to copy something */
@@ -2364,7 +2027,7 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
}
- dirent = dirlist->dirent;
+ dirent = dir->dirent;
memcpy(ndir, dirent, reqd); /* Copy the data in ... */
@@ -2375,7 +2038,7 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
rem -= reqd;
- dir->dir_next = dirlist = dirlist -> next;
+ fe->dir_next = dir = dir -> next;
}
if (rem == count)
@@ -2389,14 +2052,13 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
* Routine to create a directory ...
*/
-static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
+int smbc_mkdir(const char *fname, mode_t mode)
{
- SMBCSRV *srv;
+ struct smbc_server *srv;
fstring server, share, user, password, workgroup;
pstring path;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
@@ -2412,22 +2074,13 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
DEBUG(4, ("smbc_mkdir(%s)\n", fname));
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- fstrcpy(workgroup, context->workgroup);
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
@@ -2458,7 +2111,7 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
if (!cli_mkdir(&srv->cli, path)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(&srv->cli);
return -1;
}
@@ -2485,14 +2138,13 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state)
* Routine to remove a directory
*/
-static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
+int smbc_rmdir(const char *fname)
{
- SMBCSRV *srv;
+ struct smbc_server *srv;
fstring server, share, user, password, workgroup;
pstring path;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
@@ -2508,23 +2160,13 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
DEBUG(4, ("smbc_rmdir(%s)\n", fname));
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0))
- {
- errno = EINVAL;
- return -1;
- }
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) fstrcpy(user, context->user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- fstrcpy(workgroup, context->workgroup);
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(context, server, share, workgroup, user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
if (!srv) {
@@ -2555,7 +2197,7 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
if (!cli_rmdir(&srv->cli, path)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(&srv->cli);
if (errno == EACCES) { /* Check if the dir empty or not */
@@ -2572,7 +2214,7 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
/* Fix errno to ignore latest error ... */
DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n",
- smbc_errno(context, &srv->cli)));
+ smbc_errno(&srv->cli)));
errno = EACCES;
}
@@ -2596,26 +2238,34 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
* Routine to return the current directory position
*/
-static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir)
+off_t smbc_telldir(int fd)
{
- off_t ret_val; /* Squash warnings about cast */
+ struct smbc_file *fe;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
errno = EBADF;
return -1;
}
- if (dir->file != False) { /* FIXME, should be dir, perhaps */
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
return -1;
@@ -2623,10 +2273,10 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir)
}
/*
- * We return the pointer here as the offset
+ * This causes problems on some UNIXens ... wonder who is using
+ * it ... FIXME.
*/
- ret_val = (int)dir->dir_next;
- return ret_val;
+ return (off_t) fe->dir_next;
}
@@ -2664,21 +2314,36 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list,
* Routine to seek on a directory
*/
-static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset)
+int smbc_lseekdir(int fd, off_t offset)
{
- long int l_offset = offset; /* Handle problems of size */
- struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset;
- struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL;
+ struct smbc_file *fe;
+ struct smbc_dirent *dirent = (struct smbc_dirent *)offset;
+ struct smbc_dir_list *list_ent = NULL;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
- if (dir->file != False) { /* FIXME, should be dir, perhaps */
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
+
+ errno = EBADF;
+ return -1;
+
+ }
+
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
errno = ENOTDIR;
return -1;
@@ -2689,7 +2354,7 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset)
if (dirent == NULL) { /* Seek to the begining of the list */
- dir->dir_next = dir->dir_list;
+ fe->dir_next = fe->dir_list;
return 0;
}
@@ -2697,14 +2362,14 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset)
/* Now, run down the list and make sure that the entry is OK */
/* This may need to be changed if we change the format of the list */
- if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) {
+ if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) {
errno = EINVAL; /* Bad entry */
return -1;
}
- dir->dir_next = list_ent;
+ fe->dir_next = list_ent;
return 0;
@@ -2714,11 +2379,10 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset)
* Routine to fstat a dir
*/
-static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st)
+int smbc_fstatdir(int fd, struct stat *st)
{
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
@@ -2731,921 +2395,95 @@ static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st)
}
-int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode)
-{
- SMBCSRV *srv;
- fstring server, share, user, password, workgroup;
- pstring path;
- uint16 mode;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+/*
+ * Routine to print a file on a remote server ...
+ *
+ * We open the file, which we assume to be on a remote server, and then
+ * copy it to a print file on the share specified by printq.
+ */
- errno = EINVAL; /* Best I can think of ... */
- return -1;
-
- }
+int smbc_print_file(const char *fname, const char *printq)
+{
+ int fid1, fid2, bytes, saverr, tot_bytes = 0;
+ char buf[4096];
- if (!fname) {
+ if (!smbc_initialized) {
errno = EINVAL;
return -1;
}
-
- DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
-
- if (!srv) {
- return -1; /* errno set by smbc_server */
- }
-
- mode = 0;
-
- if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
- if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
- if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
- if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
-
- if (!cli_setatr(&srv->cli, path, mode, 0)) {
- errno = smbc_errno(context, &srv->cli);
- return -1;
- }
-
- return 0;
-}
-
-int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf)
-{
- SMBCSRV *srv;
- fstring server, share, user, password, workgroup;
- pstring path;
- uint16 mode;
- time_t t = (tbuf == NULL ? time(NULL) : tbuf->tv_sec);
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL; /* Best I can think of ... */
- return -1;
-
- }
- if (!fname) {
+ if (!fname && !printq) {
errno = EINVAL;
return -1;
}
-
- DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t)));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
-
- if (!srv) {
- return -1; /* errno set by smbc_server */
- }
-
- if (!smbc_getatr(context, srv, path,
- &mode, NULL,
- NULL, NULL, NULL,
- NULL)) {
- return -1;
- }
-
- if (!cli_setatr(&srv->cli, path, mode, t)) {
- /* some servers always refuse directory changes */
- if (!(mode & aDIR)) {
- errno = smbc_errno(context, &srv->cli);
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/* The MSDN is contradictory over the ordering of ACE entries in an ACL.
- However NT4 gives a "The information may have been modified by a
- computer running Windows NT 5.0" if denied ACEs do not appear before
- allowed ACEs. */
-
-static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
-{
- if (sec_ace_equal(ace1, ace2))
- return 0;
-
- if (ace1->type != ace2->type)
- return ace2->type - ace1->type;
-
- if (sid_compare(&ace1->trustee, &ace2->trustee))
- return sid_compare(&ace1->trustee, &ace2->trustee);
-
- if (ace1->flags != ace2->flags)
- return ace1->flags - ace2->flags;
-
- if (ace1->info.mask != ace2->info.mask)
- return ace1->info.mask - ace2->info.mask;
-
- if (ace1->size != ace2->size)
- return ace1->size - ace2->size;
-
- return memcmp(ace1, ace2, sizeof(SEC_ACE));
-}
-
-
-static void sort_acl(SEC_ACL *the_acl)
-{
- uint32 i;
- if (!the_acl) return;
-
- qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare);
-
- for (i=1;i<the_acl->num_aces;) {
- if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) {
- int j;
- for (j=i; j<the_acl->num_aces-1; j++) {
- the_acl->ace[j] = the_acl->ace[j+1];
- }
- the_acl->num_aces--;
- } else {
- i++;
- }
- }
-}
-
-/* convert a SID to a string, either numeric or username/group */
-static void convert_sid_to_string(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- fstring str,
- BOOL numeric,
- DOM_SID *sid)
-{
- char **domains = NULL;
- char **names = NULL;
- uint32 *types = NULL;
-
- sid_to_string(str, sid);
-
- if (numeric) return; /* no lookup desired */
-
- /* Ask LSA to convert the sid to a name */
-
- if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx,
- pol, 1, sid, &domains,
- &names, &types)) ||
- !domains || !domains[0] || !names || !names[0]) {
- return;
- }
-
- /* Converted OK */
-
- slprintf(str, sizeof(fstring) - 1, "%s%s%s",
- domains[0], lp_winbind_separator(),
- names[0]);
-}
-
-/* convert a string to a SID, either numeric or username/group */
-static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- BOOL numeric,
- DOM_SID *sid,
- const char *str)
-{
- uint32 *types = NULL;
- DOM_SID *sids = NULL;
- BOOL result = True;
-
- if (numeric) {
- if (strncmp(str, "S-", 2) == 0) {
- return string_to_sid(sid, str);
- }
-
- result = False;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx,
- pol, 1, &str, &sids,
- &types))) {
- result = False;
- goto done;
- }
-
- sid_copy(sid, &sids[0]);
- done:
-
- return result;
-}
-
-
-/* parse an ACE in the same format as print_ace() */
-static BOOL parse_ace(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- SEC_ACE *ace,
- BOOL numeric,
- char *str)
-{
- char *p;
- const char *cp;
- fstring tok;
- unsigned atype, aflags, amask;
- DOM_SID sid;
- SEC_ACCESS mask;
- const struct perm_value *v;
- struct perm_value {
- const char *perm;
- uint32 mask;
- };
-
- /* These values discovered by inspection */
- static const struct perm_value special_values[] = {
- { "R", 0x00120089 },
- { "W", 0x00120116 },
- { "X", 0x001200a0 },
- { "D", 0x00010000 },
- { "P", 0x00040000 },
- { "O", 0x00080000 },
- { NULL, 0 },
- };
-
- static const struct perm_value standard_values[] = {
- { "READ", 0x001200a9 },
- { "CHANGE", 0x001301bf },
- { "FULL", 0x001f01ff },
- { NULL, 0 },
- };
-
-
- ZERO_STRUCTP(ace);
- p = strchr_m(str,':');
- if (!p) return False;
- *p = '\0';
- p++;
- /* Try to parse numeric form */
-
- if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
- convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
- goto done;
- }
-
- /* Try to parse text form */
-
- if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
- return False;
- }
-
- cp = p;
- if (!next_token(&cp, tok, "/", sizeof(fstring))) {
- return False;
- }
-
- if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
- } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_DENIED;
- } else {
- return False;
- }
-
- /* Only numeric form accepted for flags at present */
-
- if (!(next_token(&cp, tok, "/", sizeof(fstring)) &&
- sscanf(tok, "%i", &aflags))) {
- return False;
- }
-
- if (!next_token(&cp, tok, "/", sizeof(fstring))) {
- return False;
- }
-
- if (strncmp(tok, "0x", 2) == 0) {
- if (sscanf(tok, "%i", &amask) != 1) {
- return False;
- }
- goto done;
- }
-
- for (v = standard_values; v->perm; v++) {
- if (strcmp(tok, v->perm) == 0) {
- amask = v->mask;
- goto done;
- }
- }
-
- p = tok;
-
- while(*p) {
- BOOL found = False;
-
- for (v = special_values; v->perm; v++) {
- if (v->perm[0] == *p) {
- amask |= v->mask;
- found = True;
- }
- }
-
- if (!found) return False;
- p++;
- }
-
- if (*p) {
- return False;
- }
-
- done:
- mask.mask = amask;
- init_sec_ace(ace, &sid, atype, mask, aflags);
- return True;
-}
-
-/* add an ACE to a list of ACEs in a SEC_ACL */
-static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx)
-{
- SEC_ACL *new;
- SEC_ACE *aces;
- if (! *the_acl) {
- (*the_acl) = make_sec_acl(ctx, 3, 1, ace);
- return True;
- }
-
- aces = calloc(1+(*the_acl)->num_aces,sizeof(SEC_ACE));
- memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
- memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
- new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
- SAFE_FREE(aces);
- (*the_acl) = new;
- return True;
-}
-
-
-/* parse a ascii version of a security descriptor */
-static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx,
- struct cli_state *ipc_cli,
- POLICY_HND *pol,
- BOOL numeric,
- char *str)
-{
- const char *p = str;
- fstring tok;
- SEC_DESC *ret;
- size_t sd_size;
- DOM_SID *grp_sid=NULL, *owner_sid=NULL;
- SEC_ACL *dacl=NULL;
- int revision=1;
-
- while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
-
- if (StrnCaseCmp(tok,"REVISION:", 9) == 0) {
- revision = strtol(tok+9, NULL, 16);
- continue;
- }
-
- if (StrnCaseCmp(tok,"OWNER:", 6) == 0) {
- owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
- if (!owner_sid ||
- !convert_string_to_sid(ipc_cli, pol,
- numeric,
- owner_sid, tok+6)) {
- DEBUG(5, ("Failed to parse owner sid\n"));
- return NULL;
- }
- continue;
- }
-
- if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) {
- owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
- if (!owner_sid ||
- !convert_string_to_sid(ipc_cli, pol,
- False,
- owner_sid, tok+7)) {
- DEBUG(5, ("Failed to parse owner sid\n"));
- return NULL;
- }
- continue;
- }
-
- if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
- grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
- if (!grp_sid ||
- !convert_string_to_sid(ipc_cli, pol,
- numeric,
- grp_sid, tok+6)) {
- DEBUG(5, ("Failed to parse group sid\n"));
- return NULL;
- }
- continue;
- }
-
- if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
- grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID));
- if (!grp_sid ||
- !convert_string_to_sid(ipc_cli, pol,
- False,
- grp_sid, tok+6)) {
- DEBUG(5, ("Failed to parse group sid\n"));
- return NULL;
- }
- continue;
- }
-
- if (StrnCaseCmp(tok,"ACL:", 4) == 0) {
- SEC_ACE ace;
- if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) {
- DEBUG(5, ("Failed to parse ACL %s\n", tok));
- return NULL;
- }
- if(!add_ace(&dacl, &ace, ctx)) {
- DEBUG(5, ("Failed to add ACL %s\n", tok));
- return NULL;
- }
- continue;
- }
-
- if (StrnCaseCmp(tok,"ACL+:", 5) == 0) {
- SEC_ACE ace;
- if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) {
- DEBUG(5, ("Failed to parse ACL %s\n", tok));
- return NULL;
- }
- if(!add_ace(&dacl, &ace, ctx)) {
- DEBUG(5, ("Failed to add ACL %s\n", tok));
- return NULL;
- }
- continue;
- }
-
- DEBUG(5, ("Failed to parse security descriptor\n"));
- return NULL;
- }
-
- ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE,
- owner_sid, grp_sid, NULL, dacl, &sd_size);
-
- SAFE_FREE(grp_sid);
- SAFE_FREE(owner_sid);
-
- return ret;
-}
+ /* Try to open the file for reading ... */
-/*****************************************************
-retrieve the acls for a file
-*******************************************************/
-static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
- struct cli_state *ipc_cli, POLICY_HND *pol,
- char *filename, char *name, char *buf, int bufsize)
-{
- uint32 i;
- int n = 0;
- int n_used;
- BOOL all;
- BOOL numeric = True;
- BOOL determine_size = (bufsize == 0);
- int fnum = -1;
- SEC_DESC *sd;
- fstring sidstr;
- char *p;
-
- fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
-
- if (fnum == -1) {
- DEBUG(5, ("cacl_get failed to open %s: %s\n",
- filename, cli_errstr(cli)));
- errno = 0;
- return -1;
- }
-
- sd = cli_query_secdesc(cli, fnum, ctx);
-
- if (!sd) {
- DEBUG(5, ("cacl_get Failed to query old descriptor\n"));
- errno = 0;
- return -1;
+ if ((int)(fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) {
+
+ DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
+ return -1; /* smbc_open sets errno */
+
}
- cli_close(cli, fnum);
-
- all = (*name == '*');
- numeric = (* (name + strlen(name) - 1) != '+');
-
- n_used = 0;
-
- if (all) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "REVISION:%d", sd->revision);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "REVISION:%d", sd->revision);
- }
- } else if (StrCaseCmp(name, "revision") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%d", sd->revision);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%d", sd->revision);
- }
- }
-
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
+ /* Now, try to open the printer file for writing */
- /* Get owner and group sid */
+ if ((int)(fid2 = smbc_open_print_job(printq)) < 0) {
- if (sd->owner_sid) {
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, sd->owner_sid);
- } else {
- fstrcpy(sidstr, "");
- }
-
- if (all) {
- if (determine_size) {
- p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, ",OWNER:%s", sidstr);
- }
- } else if (StrnCaseCmp(name, "owner", 5) == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%s", sidstr);
- }
- }
-
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (sd->grp_sid) {
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, sd->grp_sid);
- } else {
- fstrcpy(sidstr, "");
- }
-
- if (all) {
- if (determine_size) {
- p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, ",GROUP:%s", sidstr);
- }
- } else if (StrnCaseCmp(name, "group", 5) == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%s", sidstr);
- }
- }
-
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
-
- /* Add aces to value buffer */
- for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
-
- SEC_ACE *ace = &sd->dacl->ace[i];
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, &ace->trustee);
-
- if (all) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",ACL:%s:%d/%d/0x%08x",
- sidstr,
- ace->type,
- ace->flags,
- ace->info.mask);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",ACL:%s:%d/%d/0x%08x",
- sidstr,
- ace->type,
- ace->flags,
- ace->info.mask);
- }
- } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
- StrCaseCmp(name + 3, sidstr) == 0) ||
- (StrnCaseCmp(name, "acl+", 4) == 0 &&
- StrCaseCmp(name + 4, sidstr) == 0)) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "%d/%d/0x%08x",
- ace->type,
- ace->flags,
- ace->info.mask);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "%d/%d/0x%08x",
- ace->type, ace->flags, ace->info.mask);
- }
- }
- if (n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
- }
-
- if (n_used == 0) {
- errno = ENOATTR;
- return -1;
- }
- return n_used;
-}
-
-
-/*****************************************************
-set the ACLs on a file given an ascii description
-*******************************************************/
-static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
- struct cli_state *ipc_cli, POLICY_HND *pol,
- const char *filename, const char *the_acl,
- int mode, int flags)
-{
- int fnum;
- int err = 0;
- SEC_DESC *sd = NULL, *old;
- SEC_ACL *dacl = NULL;
- DOM_SID *owner_sid = NULL;
- DOM_SID *grp_sid = NULL;
- uint32 i, j;
- size_t sd_size;
- int ret = 0;
- char *p;
- BOOL numeric = True;
-
- /* the_acl will be null for REMOVE_ALL operations */
- if (the_acl) {
- numeric = ((p = strchr(the_acl, ':')) != NULL &&
- p > the_acl &&
- p[-1] != '+');
-
- /* if this is to set the entire ACL... */
- if (*the_acl == '*') {
- /* ... then increment past the first colon */
- the_acl = p + 1;
- }
-
- sd = sec_desc_parse(ctx, ipc_cli, pol,
- numeric, (char *) the_acl);
-
- if (!sd) {
- errno = EINVAL;
- return -1;
- }
- }
-
- /* The desired access below is the only one I could find that works
- with NT4, W2KP and Samba */
-
- fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
-
- if (fnum == -1) {
- DEBUG(5, ("cacl_set failed to open %s: %s\n",
- filename, cli_errstr(cli)));
- errno = 0;
+ saverr = errno; /* Save errno */
+ smbc_close(fid1);
+ errno = saverr;
return -1;
- }
- old = cli_query_secdesc(cli, fnum, ctx);
-
- if (!old) {
- DEBUG(5, ("cacl_set Failed to query old descriptor\n"));
- errno = 0;
- return -1;
}
- cli_close(cli, fnum);
-
- switch (mode) {
- case SMBC_XATTR_MODE_REMOVE_ALL:
- old->dacl->num_aces = 0;
- SAFE_FREE(old->dacl->ace);
- SAFE_FREE(old->dacl);
- old->off_dacl = 0;
- dacl = old->dacl;
- break;
+ while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) {
- case SMBC_XATTR_MODE_REMOVE:
- for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- BOOL found = False;
+ tot_bytes += bytes;
- for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sec_ace_equal(&sd->dacl->ace[i],
- &old->dacl->ace[j])) {
- uint32 k;
- for (k=j; k<old->dacl->num_aces-1;k++) {
- old->dacl->ace[k] = old->dacl->ace[k+1];
- }
- old->dacl->num_aces--;
- if (old->dacl->num_aces == 0) {
- SAFE_FREE(old->dacl->ace);
- SAFE_FREE(old->dacl);
- old->off_dacl = 0;
- }
- found = True;
- dacl = old->dacl;
- break;
- }
- }
+ if ((smbc_write(fid2, buf, bytes)) < 0) {
- if (!found) {
- err = ENOATTR;
- ret = -1;
- goto failed;
- }
- }
- break;
+ saverr = errno;
+ smbc_close(fid1);
+ smbc_close(fid2);
+ errno = saverr;
- case SMBC_XATTR_MODE_ADD:
- for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- BOOL found = False;
-
- for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sid_equal(&sd->dacl->ace[i].trustee,
- &old->dacl->ace[j].trustee)) {
- if (!(flags & SMBC_XATTR_FLAG_CREATE)) {
- err = EEXIST;
- ret = -1;
- goto failed;
- }
- old->dacl->ace[j] = sd->dacl->ace[i];
- ret = -1;
- found = True;
- }
- }
-
- if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) {
- err = ENOATTR;
- ret = -1;
- goto failed;
- }
-
- for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- add_ace(&old->dacl, &sd->dacl->ace[i], ctx);
- }
}
- dacl = old->dacl;
- break;
-
- case SMBC_XATTR_MODE_SET:
- old = sd;
- owner_sid = old->owner_sid;
- grp_sid = old->grp_sid;
- dacl = old->dacl;
- break;
-
- case SMBC_XATTR_MODE_CHOWN:
- owner_sid = sd->owner_sid;
- break;
- case SMBC_XATTR_MODE_CHGRP:
- grp_sid = sd->grp_sid;
- break;
}
- /* Denied ACE entries must come before allowed ones */
- sort_acl(old->dacl);
+ saverr = errno;
- /* Create new security descriptor and set it */
- sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
- owner_sid, grp_sid, NULL, dacl, &sd_size);
+ smbc_close(fid1); /* We have to close these anyway */
+ smbc_close(fid2);
- fnum = cli_nt_create(cli, filename,
- WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
+ if (bytes < 0) {
- if (fnum == -1) {
- DEBUG(5, ("cacl_set failed to open %s: %s\n",
- filename, cli_errstr(cli)));
- errno = 0;
+ errno = saverr;
return -1;
- }
- if (!cli_set_secdesc(cli, fnum, sd)) {
- DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli)));
- ret = -1;
}
- /* Clean up */
-
- failed:
- cli_close(cli, fnum);
+ return tot_bytes;
- if (err != 0) {
- errno = err;
- }
-
- return ret;
}
+/*
+ * Open a print file to be written to by other calls
+ */
-int smbc_setxattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size,
- int flags)
+int smbc_open_print_job(const char *fname)
{
- int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server, share, user, password, workgroup;
+ fstring server, share, user, password;
pstring path;
- TALLOC_CTX *ctx;
- POLICY_HND pol;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+
+ if (!smbc_initialized) {
- errno = EINVAL; /* Best I can think of ... */
+ errno = EINVAL;
return -1;
}
@@ -3657,476 +2495,13 @@ int smbc_setxattr_ctx(SMBCCTX *context,
}
- DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
- fname, name, (int) size, (char *) value));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
- if (!srv) {
- return -1; /* errno set by smbc_server */
- }
-
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
- &pol);
- if (!ipc_srv) {
- return -1;
- }
-
- ctx = talloc_init("smbc_setxattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
-
- /*
- * Are they asking to set an access control element or to set
- * the entire access control list?
- */
- if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
-
- /* Yup. */
- char *namevalue =
- talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
- if (! namevalue) {
- errno = ENOMEM;
- ret = -1;
- } else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
- namevalue,
- (*namevalue == '*'
- ? SMBC_XATTR_MODE_SET
- : SMBC_XATTR_MODE_ADD),
- flags);
- }
- talloc_destroy(ctx);
- return ret;
- }
-
- /*
- * Are they asking to set the owner?
- */
- if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) {
-
- /* Yup. */
- char *namevalue =
- talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
- if (! namevalue) {
- errno = ENOMEM;
- ret = -1;
- } else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
- namevalue, SMBC_XATTR_MODE_CHOWN, 0);
- }
- talloc_destroy(ctx);
- return ret;
- }
-
- /*
- * Are they asking to set the group?
- */
- if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) {
-
- /* Yup. */
- char *namevalue =
- talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
- if (! namevalue) {
- errno = ENOMEM;
- ret = -1;
- } else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
- namevalue, SMBC_XATTR_MODE_CHOWN, 0);
- }
- talloc_destroy(ctx);
- return ret;
- }
-
- /* Unsupported attribute name */
- talloc_destroy(ctx);
- errno = EINVAL;
- return -1;
-}
-
-int smbc_getxattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size)
-{
- int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server, share, user, password, workgroup;
- pstring path;
- TALLOC_CTX *ctx;
- POLICY_HND pol;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL; /* Best I can think of ... */
- return -1;
-
- }
-
- if (!fname) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
- if (!srv) {
- return -1; /* errno set by smbc_server */
- }
-
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
- &pol);
- if (!ipc_srv) {
- return -1;
- }
-
- ctx = talloc_init("smbc:getxattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
-
- /* Are they requesting a supported attribute? */
- if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
-
- /* Yup. */
- ret = cacl_get(ctx, &srv->cli,
- &ipc_srv->cli, &pol,
- (char *) path, (char *) name + 19,
- (char *) value, size);
- if (ret < 0 && errno == 0) {
- errno = smbc_errno(context, &srv->cli);
- }
- talloc_destroy(ctx);
- return ret;
- }
-
- /* Unsupported attribute name */
- talloc_destroy(ctx);
- errno = EINVAL;
- return -1;
-}
-
-
-int smbc_removexattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name)
-{
- int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- fstring server, share, user, password, workgroup;
- pstring path;
- TALLOC_CTX *ctx;
- POLICY_HND pol;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL; /* Best I can think of ... */
- return -1;
-
- }
-
- if (!fname) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
- if (!srv) {
- return -1; /* errno set by smbc_server */
- }
-
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
- &pol);
- if (!ipc_srv) {
- return -1;
- }
-
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
- &pol);
- if (!ipc_srv) {
- return -1;
- }
-
- ctx = talloc_init("smbc_removexattr");
- if (!ctx) {
- errno = ENOMEM;
- return -1;
- }
-
- /* Are they asking to set the entire ACL? */
- if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
-
- /* Yup. */
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
- NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0);
- talloc_destroy(ctx);
- return ret;
- }
-
- /*
- * Are they asking to remove one or more spceific security descriptor
- * attributes?
- */
- if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
- StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
- StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
-
- /* Yup. */
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
- name + 19, SMBC_XATTR_MODE_REMOVE, 0);
- talloc_destroy(ctx);
- return ret;
- }
-
- /* Unsupported attribute name */
- talloc_destroy(ctx);
- errno = EINVAL;
- return -1;
-}
-
-int smbc_listxattr_ctx(SMBCCTX *context,
- const char *fname,
- char *list,
- size_t size)
-{
- /*
- * This isn't quite what listxattr() is supposed to do. This returns
- * the complete set of attributes, always, rather than only those
- * attribute names which actually exist for a file. Hmmm...
- */
- const char supported[] =
- "system.nt_sec_desc.revision\0"
- "system.nt_sec_desc.owner\0"
- "system.nt_sec_desc.owner+\0"
- "system.nt_sec_desc.group\0"
- "system.nt_sec_desc.group+\0"
- "system.nt_sec_desc.acl\0"
- "system.nt_sec_desc.acl+\0"
- "system.nt_sec_desc.*\0"
- "system.nt_sec_desc.*+\0"
- ;
-
- if (size == 0) {
- return sizeof(supported);
- }
-
- if (sizeof(supported) > size) {
- errno = ERANGE;
- return -1;
- }
-
- /* this can't be strcpy() because there are embedded null characters */
- memcpy(list, supported, sizeof(supported));
- return sizeof(supported);
-}
-
-
-/*
- * Open a print file to be written to by other calls
- */
-
-static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname)
-{
- fstring server, share, user, password;
- pstring path;
-
- if (!context || !context->internal ||
- !context->internal->_initialized) {
-
- errno = EINVAL;
- return NULL;
-
- }
-
- if (!fname) {
-
- errno = EINVAL;
- return NULL;
-
- }
-
- DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return NULL;
- }
-
- /* What if the path is empty, or the file exists? */
-
- return context->open(context, fname, O_WRONLY, 666);
-
-}
-
-/*
- * Routine to print a file on a remote server ...
- *
- * We open the file, which we assume to be on a remote server, and then
- * copy it to a print file on the share specified by printq.
- */
-
-static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq)
-{
- SMBCFILE *fid1, *fid2;
- int bytes, saverr, tot_bytes = 0;
- char buf[4096];
-
- if (!c_file || !c_file->internal->_initialized || !c_print ||
- !c_print->internal->_initialized) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- if (!fname && !printq) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- /* Try to open the file for reading ... */
+ DEBUG(4, ("smbc_open_print_job(%s)\n", fname));
- if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
-
- DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
- return -1; /* smbc_open sets errno */
-
- }
-
- /* Now, try to open the printer file for writing */
-
- if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
-
- saverr = errno; /* Save errno */
- c_file->close(c_file, fid1);
- errno = saverr;
- return -1;
-
- }
-
- while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) {
-
- tot_bytes += bytes;
-
- if ((c_print->write(c_print, fid2, buf, bytes)) < 0) {
-
- saverr = errno;
- c_file->close(c_file, fid1);
- c_print->close(c_print, fid2);
- errno = saverr;
-
- }
-
- }
-
- saverr = errno;
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- c_file->close(c_file, fid1); /* We have to close these anyway */
- c_print->close(c_print, fid2);
+ /* What if the path is empty, or the file exists? */
- if (bytes < 0) {
-
- errno = saverr;
- return -1;
-
- }
-
- return tot_bytes;
+ return smbc_open(fname, O_WRONLY, 666);
}
@@ -4134,60 +2509,50 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr
* Routine to list print jobs on a printer share ...
*/
-static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn)
+int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *))
{
- SMBCSRV *srv;
- fstring server, share, user, password, workgroup;
- pstring path;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
-
- errno = EINVAL;
- return -1;
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
+ DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- srv = smbc_server(context, server, share, workgroup, user, password);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
+
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* errno set by smbc_server */
+ if (!srv) {
- }
+ return -1; /* errno set by smbc_server */
- if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) {
+ }
- errno = smbc_errno(context, &srv->cli);
- return -1;
+ if (cli_print_queue(&srv->cli, fn) < 0) {
- }
-
- return 0;
+ errno = smbc_errno(&srv->cli);
+ return -1;
+
+ }
+
+ return 0;
}
@@ -4195,338 +2560,54 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li
* Delete a print job from a remote printer share
*/
-static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id)
+int smbc_unlink_print_job(const char *fname, int id)
{
- SMBCSRV *srv;
- fstring server, share, user, password, workgroup;
- pstring path;
- int err;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ int err;
- if (!context || !context->internal ||
- !context->internal->_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
-
- if (smbc_parse_path(context, fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
- errno = EINVAL;
- return -1;
- }
-
- if (user[0] == (char)0) fstrcpy(user, context->user);
-
- fstrcpy(workgroup, context->workgroup);
-
- srv = smbc_server(context, server, share, workgroup, user, password);
-
- if (!srv) {
+ DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
- return -1; /* errno set by smbc_server */
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- }
-
- if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- if (err < 0)
- errno = smbc_errno(context, &srv->cli);
- else if (err == ERRnosuchprintjob)
- errno = EINVAL;
- return -1;
-
- }
+ pstrcpy(workgroup, lp_workgroup());
- return 0;
+ srv = smbc_server(server, share, workgroup, user, password);
-}
+ if (!srv) {
-/*
- * Get a new empty handle to fill in with your own info
- */
-SMBCCTX * smbc_new_context(void)
-{
- SMBCCTX * context;
+ return -1; /* errno set by smbc_server */
- context = malloc(sizeof(SMBCCTX));
- if (!context) {
- errno = ENOMEM;
- return NULL;
- }
+ }
- ZERO_STRUCTP(context);
+ if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
- context->internal = malloc(sizeof(struct smbc_internal_data));
- if (!context->internal) {
- errno = ENOMEM;
- return NULL;
- }
+ if (err < 0)
+ errno = smbc_errno(&srv->cli);
+ else if (err == ERRnosuchprintjob)
+ errno = EINVAL;
+ return -1;
- ZERO_STRUCTP(context->internal);
-
-
- /* ADD REASONABLE DEFAULTS */
- context->debug = 0;
- context->timeout = 20000; /* 20 seconds */
-
- context->open = smbc_open_ctx;
- context->creat = smbc_creat_ctx;
- context->read = smbc_read_ctx;
- context->write = smbc_write_ctx;
- context->close = smbc_close_ctx;
- context->unlink = smbc_unlink_ctx;
- context->rename = smbc_rename_ctx;
- context->lseek = smbc_lseek_ctx;
- context->stat = smbc_stat_ctx;
- context->fstat = smbc_fstat_ctx;
- context->opendir = smbc_opendir_ctx;
- context->closedir = smbc_closedir_ctx;
- context->readdir = smbc_readdir_ctx;
- context->getdents = smbc_getdents_ctx;
- context->mkdir = smbc_mkdir_ctx;
- context->rmdir = smbc_rmdir_ctx;
- context->telldir = smbc_telldir_ctx;
- context->lseekdir = smbc_lseekdir_ctx;
- context->fstatdir = smbc_fstatdir_ctx;
- context->chmod = smbc_chmod_ctx;
- context->utimes = smbc_utimes_ctx;
- context->setxattr = smbc_setxattr_ctx;
- context->getxattr = smbc_getxattr_ctx;
- context->removexattr = smbc_removexattr_ctx;
- context->listxattr = smbc_listxattr_ctx;
- context->open_print_job = smbc_open_print_job_ctx;
- context->print_file = smbc_print_file_ctx;
- context->list_print_jobs = smbc_list_print_jobs_ctx;
- context->unlink_print_job = smbc_unlink_print_job_ctx;
-
- context->callbacks.check_server_fn = smbc_check_server;
- context->callbacks.remove_unused_server_fn = smbc_remove_unused_server;
-
- smbc_default_cache_functions(context);
-
- return context;
-}
+ }
-/*
- * Free a context
- *
- * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
- * and thus you'll be leaking memory if not handled properly.
- *
- */
-int smbc_free_context(SMBCCTX * context, int shutdown_ctx)
-{
- if (!context) {
- errno = EBADF;
- return 1;
- }
-
- if (shutdown_ctx) {
- SMBCFILE * f;
- DEBUG(1,("Performing aggressive shutdown.\n"));
-
- f = context->internal->_files;
- while (f) {
- context->close(context, f);
- f = f->next;
- }
- context->internal->_files = NULL;
-
- /* First try to remove the servers the nice way. */
- if (context->callbacks.purge_cached_fn(context)) {
- SMBCSRV * s;
- SMBCSRV * next;
- DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n"));
- s = context->internal->_servers;
- while (s) {
- DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli.fd));
- cli_shutdown(&s->cli);
- context->callbacks.remove_cached_srv_fn(context, s);
- next = s->next;
- DLIST_REMOVE(context->internal->_servers, s);
- SAFE_FREE(s);
- s = next;
- }
- context->internal->_servers = NULL;
- }
- }
- else {
- /* This is the polite way */
- if (context->callbacks.purge_cached_fn(context)) {
- DEBUG(1, ("Could not purge all servers, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- if (context->internal->_servers) {
- DEBUG(1, ("Active servers in context, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- if (context->internal->_files) {
- DEBUG(1, ("Active files in context, free_context failed.\n"));
- errno = EBUSY;
- return 1;
- }
- }
+ return 0;
- /* Things we have to clean up */
- SAFE_FREE(context->workgroup);
- SAFE_FREE(context->netbios_name);
- SAFE_FREE(context->user);
-
- DEBUG(3, ("Context %p succesfully freed\n", context));
- SAFE_FREE(context->internal);
- SAFE_FREE(context);
- return 0;
}
-
-/*
- * Initialise the library etc
- *
- * We accept a struct containing handle information.
- * valid values for info->debug from 0 to 100,
- * and insist that info->fn must be non-null.
- */
-SMBCCTX * smbc_init_context(SMBCCTX * context)
-{
- pstring conf;
- int pid;
- char *user = NULL, *home = NULL;
-
- if (!context || !context->internal) {
- errno = EBADF;
- return NULL;
- }
-
- /* Do not initialise the same client twice */
- if (context->internal->_initialized) {
- return 0;
- }
-
- if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) {
-
- errno = EINVAL;
- return NULL;
-
- }
-
- if (!smbc_initialized) {
- /* Do some library wide intialisations the first time we get called */
-
- /* Set this to what the user wants */
- DEBUGLEVEL = context->debug;
-
- setup_logging( "libsmbclient", True);
-
- /* Here we would open the smb.conf file if needed ... */
-
- home = getenv("HOME");
-
- slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
-
- load_interfaces(); /* Load the list of interfaces ... */
-
- in_client = True; /* FIXME, make a param */
-
- if (!lp_load(conf, True, False, False)) {
-
- /*
- * Well, if that failed, try the dyn_CONFIGFILE
- * Which points to the standard locn, and if that
- * fails, silently ignore it and use the internal
- * defaults ...
- */
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- DEBUG(5, ("Could not load either config file: %s or %s\n",
- conf, dyn_CONFIGFILE));
- }
- }
-
- reopen_logs(); /* Get logging working ... */
-
- /*
- * Block SIGPIPE (from lib/util_sock.c: write())
- * It is not needed and should not stop execution
- */
- BlockSignals(True, SIGPIPE);
-
- /* Done with one-time initialisation */
- smbc_initialized = 1;
-
- }
-
- if (!context->user) {
- /*
- * FIXME: Is this the best way to get the user info?
- */
- user = getenv("USER");
- /* walk around as "guest" if no username can be found */
- if (!user) context->user = strdup("guest");
- else context->user = strdup(user);
- }
-
- if (!context->netbios_name) {
- /*
- * We try to get our netbios name from the config. If that fails we fall
- * back on constructing our netbios name from our hostname etc
- */
- if (global_myname()) {
- context->netbios_name = strdup(global_myname());
- }
- else {
- /*
- * Hmmm, I want to get hostname as well, but I am too lazy for the moment
- */
- pid = sys_getpid();
- context->netbios_name = malloc(17);
- if (!context->netbios_name) {
- errno = ENOMEM;
- return NULL;
- }
- slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid);
- }
- }
-
- DEBUG(1, ("Using netbios name %s.\n", context->netbios_name));
-
- if (!context->workgroup) {
- if (lp_workgroup()) {
- context->workgroup = strdup(lp_workgroup());
- }
- else {
- /* TODO: Think about a decent default workgroup */
- context->workgroup = strdup("samba");
- }
- }
-
- DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
-
- /* shortest timeout is 1 second */
- if (context->timeout > 0 && context->timeout < 1000)
- context->timeout = 1000;
-
- /*
- * FIXME: Should we check the function pointers here?
- */
-
- context->internal->_initialized = 1;
-
- return context;
-}
diff --git a/source/libsmb/namecache.c b/source/libsmb/namecache.c
index e3e7ac4e3c2..6ab20e42741 100644
--- a/source/libsmb/namecache.c
+++ b/source/libsmb/namecache.c
@@ -1,10 +1,9 @@
/*
Unix SMB/CIFS implementation.
- NetBIOS name cache module on top of gencache mechanism.
-
- Copyright (C) Tim Potter 2002
- Copyright (C) Rafal Szczesniak 2002
+ NetBIOS name cache module.
+
+ Copyright (C) Tim Potter, 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,299 +22,244 @@
#include "includes.h"
-#define NBTKEY_FMT "NBT/%s#%02X"
+static BOOL done_namecache_init;
+static BOOL enable_namecache;
+static TDB_CONTEXT *namecache_tdb;
+struct nc_value {
+ time_t expiry; /* When entry expires */
+ int count; /* Number of addresses */
+ struct in_addr ip_list[1]; /* Address list */
+};
-/**
- * Initialise namecache system. Function calls gencache
- * initialisation function to perform necessary actions
- *
- * @return true upon successful initialisation of the cache or
- * false on failure
- **/
+/* Initialise namecache system */
BOOL namecache_enable(void)
{
- /*
- * Check if name caching disabled by setting the name cache
- * timeout to zero.
- */
+ /* Check if we have been here before, or name caching disabled
+ by setting the name cache timeout to zero. */
+
+ if (done_namecache_init)
+ return False;
+
+ done_namecache_init = True;
if (lp_name_cache_timeout() == 0) {
- DEBUG(5, ("namecache_enable: disabling netbios name cache\n"));
+ DEBUG(5, ("namecache_init: disabling netbios name cache\n"));
return False;
}
- /* Init namecache by calling gencache initialisation */
+ /* Open namecache tdb in read/write or readonly mode */
- if (!gencache_init()) {
- DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n"));
+ namecache_tdb = tdb_open_log(
+ lock_path("namecache.tdb"), 0,
+ TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
+
+ if (!namecache_tdb) {
+ DEBUG(5, ("namecache_init: could not open %s\n",
+ lock_path("namecache.tdb")));
return False;
}
- /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */
- DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
+ DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d "
"seconds\n", lp_name_cache_timeout()));
+ enable_namecache = True;
+
return True;
}
+/* Return a key for a name and name type. The caller must free
+ retval.dptr when finished. */
-/**
- * Shutdown namecache. Routine calls gencache close function
- * to safely close gencache file.
- *
- * @return true upon successful shutdown of the cache or
- * false on failure
- **/
-
-BOOL namecache_shutdown(void)
+static TDB_DATA namecache_key(const char *name, int name_type)
{
- if (!gencache_shutdown()) {
- DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n"));
- return False;
- }
-
- DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n"));
- return True;
-}
+ TDB_DATA retval;
+ char *keystr;
+
+ asprintf(&keystr, "%s#%02X", strupper_static(name), name_type);
+
+ retval.dsize = strlen(keystr) + 1;
+ retval.dptr = keystr;
+ return retval;
+}
-/**
- * Generates a key for netbios name lookups on basis of
- * netbios name and type.
- * The caller must free returned key string when finished.
- *
- * @param name netbios name string (case insensitive)
- * @param name_type netbios type of the name being looked up
- *
- * @return string consisted of uppercased name and appended
- * type number
- */
+/* Return a data value for an IP list. The caller must free
+ retval.dptr when finished. */
-static char* namecache_key(const char *name, int name_type)
+static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names,
+ time_t expiry)
{
- char *keystr;
- asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type);
+ TDB_DATA retval;
+ struct nc_value *value;
+ int size = sizeof(struct nc_value);
- return keystr;
-}
+ if (num_names > 0)
+ size += sizeof(struct in_addr) * (num_names-1);
+
+ value = (struct nc_value *)malloc(size);
+
+ memset(value, 0, size);
+ value->expiry = expiry;
+ value->count = num_names;
-/**
- * Store a name(s) in the name cache
- *
- * @param name netbios names array
- * @param name_type integer netbios name type
- * @param num_names number of names being stored
- * @param ip_list array of in_addr structures containing
- * ip addresses being stored
- **/
+ if (ip_list)
+ memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names);
-BOOL namecache_store(const char *name, int name_type,
- int num_names, struct ip_service *ip_list)
+ retval.dptr = (char *)value;
+ retval.dsize = size;
+
+ return retval;
+}
+
+/* Store a name in the name cache */
+
+void namecache_store(const char *name, int name_type,
+ int num_names, struct in_addr *ip_list)
{
+ TDB_DATA key, value;
time_t expiry;
- char *key, *value_string;
int i;
- BOOL ret;
-
- /*
- * we use gecache call to avoid annoying debug messages about
- * initialised namecache again and again...
- */
- if (!gencache_init()) return False;
-
- if ( DEBUGLEVEL >= 5 ) {
- DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
- num_names, num_names == 1 ? "": "es", name, name_type));
-
- for (i = 0; i < num_names; i++)
- DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip),
- ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
-
- DEBUGADD(5, ("\n"));
- }
-
+
+ if (!enable_namecache)
+ return;
+
+ DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
+ num_names, num_names == 1 ? "": "es", name, name_type));
+
+ for (i = 0; i < num_names; i++)
+ DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]),
+ i == (num_names - 1) ? "" : ", "));
+
+ DEBUGADD(5, ("\n"));
+
key = namecache_key(name, name_type);
- expiry = time(NULL) + lp_name_cache_timeout();
-
- /*
- * Generate string representation of ip addresses list
- * First, store the number of ip addresses and then
- * place each single ip
- */
- if (!ipstr_list_make(&value_string, ip_list, num_names)) {
- SAFE_FREE(key);
- SAFE_FREE(value_string);
- return False;
- }
-
- /* set the entry */
- ret = gencache_set(key, value_string, expiry);
- SAFE_FREE(key);
- SAFE_FREE(value_string);
- return ret;
+
+ /* Cache pdc location or dc lists for only a little while
+ otherwise if we lock on to a bad DC we can potentially be
+ out of action for the entire cache timeout time! */
+
+ if (name_type != 0x1b || name_type != 0x1c)
+ expiry = time(NULL) + 10;
+ else
+ expiry = time(NULL) + lp_name_cache_timeout();
+
+ value = namecache_value(ip_list, num_names, expiry);
+
+ tdb_store(namecache_tdb, key, value, TDB_REPLACE);
+
+ free(key.dptr);
+ free(value.dptr);
}
+/* Look up a name in the name cache. Return a mallocated list of IP
+ addresses if the name is contained in the cache. */
-/**
- * Look up a name in the cache.
- *
- * @param name netbios name to look up for
- * @param name_type netbios name type of @param name
- * @param ip_list mallocated list of IP addresses if found in the cache,
- * NULL otherwise
- * @param num_names number of entries found
- *
- * @return true upon successful fetch or
- * false if name isn't found in the cache or has expired
- **/
-
-BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_list,
- int *num_names)
+BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
+ int *num_names)
{
- char *key, *value;
- time_t timeout;
+ TDB_DATA key, value;
+ struct nc_value *data = NULL;
+ time_t now;
+ int i;
+ *ip_list = NULL;
*num_names = 0;
- /* exit now if null pointers were passed as they're required further */
- if (!ip_list || !num_names) return False;
-
- if (!gencache_init())
+ if (!enable_namecache)
return False;
- /*
- * Use gencache interface - lookup the key
- */
+ /* Read value */
+
key = namecache_key(name, name_type);
- if (!gencache_get(key, &value, &timeout)) {
- DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type));
- gencache_del(key);
- SAFE_FREE(key);
- SAFE_FREE(value);
- return False;
- } else {
- DEBUG(5, ("name %s#%02X found.\n", name, name_type));
- }
-
- /*
- * Split up the stored value into the list of IP adresses
- */
- *num_names = ipstr_list_parse(value, ip_list);
+ value = tdb_fetch(namecache_tdb, key);
- SAFE_FREE(key);
- SAFE_FREE(value);
-
- return *num_names > 0; /* true only if some ip has been fetched */
-}
+ if (!value.dptr) {
+ DEBUG(5, ("namecache_fetch: %s#%02x not found\n",
+ name, name_type));
+ goto done;
+ }
+ data = (struct nc_value *)value.dptr;
-/**
- * Delete single namecache entry. Look at the
- * gencache_iterate definition.
- *
- **/
+ /* Check expiry time */
-static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr)
-{
- gencache_del(key);
- DEBUG(5, ("Deleting entry %s\n", key));
-}
+ now = time(NULL);
+ if (now > data->expiry) {
-/**
- * Flush all names from the name cache.
- * It's done by gencache_iterate()
- *
- * @return True upon successful deletion or
- * False in case of an error
- **/
+ DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n",
+ name, name_type));
-void namecache_flush(void)
-{
- if (!gencache_init())
- return;
+ tdb_delete(namecache_tdb, key);
- /*
- * iterate through each NBT cache's entry and flush it
- * by flush_netbios_name function
- */
- gencache_iterate(flush_netbios_name, NULL, "NBT/*");
- DEBUG(5, ("Namecache flushed\n"));
-}
+ SAFE_FREE(value.dptr);
+ value = tdb_null;
-/* Construct a name status record key. */
+ goto done;
+ }
-static char *namecache_status_record_key(const char *name, int name_type1,
- int name_type2, struct in_addr keyip)
-{
- char *keystr;
+ if ((data->expiry - now) > lp_name_cache_timeout()) {
- asprintf(&keystr, "NBT/%s#%02X.%02X.%s",
- strupper_static(name), name_type1, name_type2, inet_ntoa(keyip));
- return keystr;
-}
+ /* Someone may have changed the system time on us */
-/* Store a name status record. */
+ DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n",
+ name, name_type));
-BOOL namecache_status_store(const char *keyname, int keyname_type,
- int name_type, struct in_addr keyip,
- const char *srvname)
-{
- char *key;
- time_t expiry;
- BOOL ret;
+ tdb_delete(namecache_tdb, key);
- if (!gencache_init())
- return False;
+ SAFE_FREE(value.dptr);
+ value = tdb_null;
- key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
- if (!key)
- return False;
+ goto done;
+ }
- expiry = time(NULL) + lp_name_cache_timeout();
- ret = gencache_set(key, srvname, expiry);
+ /* Extract and return namelist */
- if (ret)
- DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname ));
- else
- DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key ));
+ DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ",
+ data->count, data->count == 1 ? "" : "es", name, name_type));
+
+ if (data->count) {
+
+ *ip_list = (struct in_addr *)malloc(
+ sizeof(struct in_addr) * data->count);
+
+ memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count);
+
+ *num_names = data->count;
+
+ for (i = 0; i < *num_names; i++)
+ DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]),
+ i == (*num_names - 1) ? "" : ", "));
+
+ }
+
+ DEBUGADD(5, ("\n"));
- SAFE_FREE(key);
- return ret;
+done:
+ SAFE_FREE(key.dptr);
+ SAFE_FREE(value.dptr);
+
+ return value.dsize > 0;
}
-/* Fetch a name status record. */
+/* Flush all names from the name cache */
-BOOL namecache_status_fetch(const char *keyname, int keyname_type,
- int name_type, struct in_addr keyip, char *srvname_out)
+void namecache_flush(void)
{
- char *key = NULL;
- char *value = NULL;
- time_t timeout;
+ int result;
- if (!gencache_init())
- return False;
-
- key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
- if (!key)
- return False;
+ if (!namecache_tdb)
+ return;
- if (!gencache_get(key, &value, &timeout)) {
- DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key));
- gencache_del(key);
- SAFE_FREE(key);
- SAFE_FREE(value);
- return False;
- } else {
- DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value ));
- }
+ result = tdb_traverse(namecache_tdb, tdb_traverse_delete_fn, NULL);
- strlcpy(srvname_out, value, 16);
- SAFE_FREE(key);
- SAFE_FREE(value);
- return True;
+ if (result == -1)
+ DEBUG(5, ("namecache_flush: error deleting cache entries\n"));
+ else
+ DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n",
+ result, result == 1 ? "y" : "ies"));
}
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index b9bc4e11664..7ce8486b150 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
name query routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -32,9 +33,8 @@ static int generate_trn_id(void)
{
static int trn_id;
- if (trn_id == 0) {
+ if (trn_id == 0)
sys_srandom(sys_getpid());
- }
trn_id = sys_random();
@@ -52,8 +52,7 @@ static struct node_status *parse_node_status(char *p, int *num_names)
*num_names = CVAL(p,0);
- if (*num_names == 0)
- return NULL;
+ if (*num_names == 0) return NULL;
ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
if (!ret) return NULL;
@@ -61,17 +60,14 @@ static struct node_status *parse_node_status(char *p, int *num_names)
p++;
for (i=0;i< *num_names;i++) {
StrnCpy(ret[i].name,p,15);
- trim_char(ret[i].name,'\0',' ');
+ trim_string(ret[i].name,NULL," ");
ret[i].type = CVAL(p,15);
ret[i].flags = p[16];
p += 18;
- DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
- ret[i].type, ret[i].flags));
}
return ret;
}
-
/****************************************************************************
Do a NBT node status query on an open socket and return an array of
structures holding the returned names or NULL if the query failed.
@@ -158,196 +154,145 @@ struct node_status *node_status_query(int fd,struct nmb_name *name,
return NULL;
}
+
/****************************************************************************
- Find the first type XX name in a node status reply - used for finding
- a servers name given its IP. Return the matched name in *name.
+find the first type XX name in a node status reply - used for finding
+a servers name given its IP
+return the matched name in *name
**************************************************************************/
-BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
+BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
{
- struct node_status *status = NULL;
+ struct node_status *status;
struct nmb_name nname;
int count, i;
int sock;
- BOOL result = False;
-
- if (lp_disable_netbios()) {
- DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
- return False;
- }
-
- DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
- q_type, inet_ntoa(to_ip)));
-
- /* Check the cache first. */
-
- if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
- return True;
sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
if (sock == -1)
- goto done;
+ return False;
/* W2K PDC's seem not to respond to '*'#0. JRA */
make_nmb_name(&nname, q_name, q_type);
status = node_status_query(sock, &nname, to_ip, &count);
close(sock);
if (!status)
- goto done;
+ return False;
for (i=0;i<count;i++) {
if (status[i].type == type)
break;
}
if (i == count)
- goto done;
-
- pull_ascii_nstring(name, sizeof(fstring), status[i].name);
+ return False;
- /* Store the result in the cache. */
- /* but don't store an entry for 0x1c names here. Here we have
- a single host and DOMAIN<0x1c> names should be a list of hosts */
-
- if ( q_type != 0x1c )
- namecache_status_store(q_name, q_type, type, to_ip, name);
+ StrnCpy(name, status[i].name, 15);
- result = True;
+ dos_to_unix(name);
- done:
SAFE_FREE(status);
+ return True;
+}
- DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
+/****************************************************************************
+ Do a NetBIOS name registation to try to claim a name ...
+***************************************************************************/
+BOOL name_register(int fd, const char *name, int name_type,
+ struct in_addr name_ip, int opcode,
+ BOOL bcast,
+ struct in_addr to_ip, int *count)
+{
+ int retries = 3;
+ struct timeval tval;
+ struct packet_struct p;
+ struct packet_struct *p2;
+ struct nmb_packet *nmb = &p.packet.nmb;
+ struct in_addr register_ip;
- if (result)
- DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
+ DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
- DEBUG(10, ("\n"));
+ register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
+
+ memset((char *)&p, '\0', sizeof(p));
- return result;
-}
+ *count = 0;
-/*
- comparison function used by sort_ip_list
-*/
+ nmb->header.name_trn_id = generate_trn_id();
+ nmb->header.opcode = opcode;
+ nmb->header.response = False;
+ nmb->header.nm_flags.bcast = False;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.recursion_desired = True; /* ? */
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = True;
-static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
-{
- int max_bits1=0, max_bits2=0;
- int num_interfaces = iface_count();
- int i;
+ nmb->header.qdcount = 1;
+ nmb->header.ancount = 0;
+ nmb->header.nscount = 0;
+ nmb->header.arcount = 1;
- for (i=0;i<num_interfaces;i++) {
- struct in_addr ip;
- int bits1, bits2;
- ip = *iface_n_bcast(i);
- bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
- bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
- max_bits1 = MAX(bits1, max_bits1);
- max_bits2 = MAX(bits2, max_bits2);
- }
-
- /* bias towards directly reachable IPs */
- if (iface_local(*ip1)) {
- max_bits1 += 32;
- }
- if (iface_local(*ip2)) {
- max_bits2 += 32;
- }
+ make_nmb_name(&nmb->question.question_name, name, name_type);
- return max_bits2 - max_bits1;
-}
+ nmb->question.question_type = 0x20;
+ nmb->question.question_class = 0x1;
-/*******************************************************************
- compare 2 ldap IPs by nearness to our interfaces - used in qsort
-*******************************************************************/
+ /* Now, create the additional stuff for a registration request */
-static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
-{
- int result;
-
- if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
- return result;
-
- if ( ip1->port > ip2->port )
- return 1;
-
- if ( ip1->port < ip2->port )
- return -1;
-
- return 0;
-}
+ if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
-/*
- sort an IP list so that names that are close to one of our interfaces
- are at the top. This prevents the problem where a WINS server returns an IP that
- is not reachable from our subnet as the first match
-*/
+ DEBUG(0, ("name_register: malloc fail for additional record.\n"));
+ return False;
-static void sort_ip_list(struct in_addr *iplist, int count)
-{
- if (count <= 1) {
- return;
- }
+ }
- qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
-}
+ memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
-static void sort_ip_list2(struct ip_service *iplist, int count)
-{
- if (count <= 1) {
- return;
- }
+ nmb->additional->rr_name = nmb->question.question_name;
+ nmb->additional->rr_type = RR_TYPE_NB;
+ nmb->additional->rr_class = RR_CLASS_IN;
- qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
-}
+ /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
+ if (nmb->header.nm_flags.bcast)
+ nmb->additional->ttl = PERMANENT_TTL;
+ else
+ nmb->additional->ttl = lp_max_ttl();
-/**********************************************************************
- Remove any duplicate address/port pairs in the list
- *********************************************************************/
+ nmb->additional->rdlength = 6;
-static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
-{
- int i, j;
-
- DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
-
- /* one loop to remove duplicates */
- for ( i=0; i<count; i++ ) {
- if ( is_zero_ip(iplist[i].ip) )
- continue;
-
- for ( j=i+1; j<count; j++ ) {
- if ( ip_service_equal(iplist[i], iplist[j]) )
- zero_ip(&iplist[j].ip);
- }
- }
-
- /* one loop to clean up any holes we left */
- /* first ip should never be a zero_ip() */
- for (i = 0; i<count; ) {
- if ( is_zero_ip(iplist[i].ip) ) {
- if (i != count-1 )
- memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
- count--;
- continue;
- }
- i++;
- }
+ nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
+
+ /* Set the address for the name we are registering. */
+ putip(&nmb->additional->rdata[2], &register_ip);
+
+ p.ip = to_ip;
+ p.port = NMB_PORT;
+ p.fd = fd;
+ p.timestamp = time(NULL);
+ p.packet_type = NMB_PACKET;
+
+ GetTimeOfDay(&tval);
+
+ if (!send_packet(&p))
+ return False;
+
+ retries--;
- return count;
+ if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
+ debug_nmb_packet(p2);
+ SAFE_FREE(p2); /* No memory leaks ... */
+ }
+
+ return True;
}
/****************************************************************************
Do a netbios name query to find someones IP.
Returns an array of IP addresses or NULL if none.
*count will be set to the number of addresses returned.
- *timed_out is set if we failed by timing out
****************************************************************************/
-
struct in_addr *name_query(int fd,const char *name,int name_type,
BOOL bcast,BOOL recurse,
- struct in_addr to_ip, int *count, int *flags,
- BOOL *timed_out)
+ struct in_addr to_ip, int *count, int *flags)
{
BOOL found=False;
int i, retries = 3;
@@ -358,19 +303,10 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
struct nmb_packet *nmb = &p.packet.nmb;
struct in_addr *ip_list = NULL;
- if (lp_disable_netbios()) {
- DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
- return NULL;
- }
-
- if (timed_out) {
- *timed_out = False;
- }
-
memset((char *)&p,'\0',sizeof(p));
(*count) = 0;
(*flags) = 0;
-
+
nmb->header.name_trn_id = generate_trn_id();
nmb->header.opcode = 0;
nmb->header.response = False;
@@ -384,29 +320,29 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
nmb->header.ancount = 0;
nmb->header.nscount = 0;
nmb->header.arcount = 0;
-
+
make_nmb_name(&nmb->question.question_name,name,name_type);
-
+
nmb->question.question_type = 0x20;
nmb->question.question_class = 0x1;
-
+
p.ip = to_ip;
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
-
+
GetTimeOfDay(&tval);
-
+
if (!send_packet(&p))
return NULL;
-
+
retries--;
-
+
while (1) {
struct timeval tval2;
struct in_addr *tmp_ip_list;
-
+
GetTimeOfDay(&tval2);
if (TvalDiff(&tval,&tval2) > retry_time) {
if (!retries)
@@ -416,19 +352,19 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
GetTimeOfDay(&tval);
retries--;
}
-
+
if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
-
+
/* If we get a Negative Name Query Response from a WINS
* server, we should report it and give up.
*/
if( 0 == nmb2->header.opcode /* A query response */
- && !(bcast) /* from a WINS server */
- && nmb2->header.rcode /* Error returned */
+ && !(bcast) /* from a WINS server */
+ && nmb2->header.rcode /* Error returned */
) {
-
+
if( DEBUGLVL( 3 ) ) {
/* Only executed if DEBUGLEVEL >= 3 */
dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
@@ -453,14 +389,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
break;
}
}
+
free_packet(p2);
return( NULL );
}
-
+
if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount) {
+ nmb2->header.nm_flags.bcast ||
+ nmb2->header.rcode ||
+ !nmb2->header.ancount) {
/*
* XXXX what do we do with this? Could be a
* redirect, but we'll discard it for the
@@ -469,17 +406,17 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
free_packet(p2);
continue;
}
-
+
tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
- * ( (*count) + nmb2->answers->rdlength/6 ) );
-
+ * ( (*count) + nmb2->answers->rdlength/6 ) );
+
if (!tmp_ip_list) {
DEBUG(0,("name_query: Realloc failed.\n"));
- SAFE_FREE(ip_list);
+ SAFE_FREE(ip_list);
}
-
+
ip_list = tmp_ip_list;
-
+
if (ip_list) {
DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
for (i=0;i<nmb2->answers->rdlength/6;i++) {
@@ -489,23 +426,24 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
}
DEBUGADD(2,(")\n"));
}
-
+
found=True;
retries=0;
/* We add the flags back ... */
if (nmb2->header.response)
- (*flags) |= NM_FLAGS_RS;
+ (*flags) |= NM_FLAGS_RS;
if (nmb2->header.nm_flags.authoritative)
- (*flags) |= NM_FLAGS_AA;
+ (*flags) |= NM_FLAGS_AA;
if (nmb2->header.nm_flags.trunc)
- (*flags) |= NM_FLAGS_TC;
+ (*flags) |= NM_FLAGS_TC;
if (nmb2->header.nm_flags.recursion_desired)
- (*flags) |= NM_FLAGS_RD;
+ (*flags) |= NM_FLAGS_RD;
if (nmb2->header.nm_flags.recursion_available)
- (*flags) |= NM_FLAGS_RA;
+ (*flags) |= NM_FLAGS_RA;
if (nmb2->header.nm_flags.bcast)
- (*flags) |= NM_FLAGS_B;
+ (*flags) |= NM_FLAGS_B;
free_packet(p2);
+
/*
* If we're doing a unicast lookup we only
* expect one reply. Don't wait the full 2
@@ -516,15 +454,12 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
}
}
- /* only set timed_out if we didn't fund what we where looking for*/
-
- if ( !found && timed_out ) {
- *timed_out = True;
+ /* Reach here if we've timed out waiting for replies.. */
+ if( !bcast && !found ) {
+ /* Timed out wating for WINS server to respond. Mark it dead. */
+ wins_srv_died( to_ip );
}
- /* sort the ip list so we choose close servers first if possible */
- sort_ip_list(ip_list, *count);
-
return ip_list;
}
@@ -532,26 +467,26 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
Start parsing the lmhosts file.
*********************************************************/
-XFILE *startlmhosts(char *fname)
+FILE *startlmhosts(const char *fname)
{
- XFILE *fp = x_fopen(fname,O_RDONLY, 0);
- if (!fp) {
- DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
- return NULL;
- }
- return fp;
+ FILE *fp = sys_fopen(fname,"r");
+ if (!fp) {
+ DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
+ fname, strerror(errno)));
+ return NULL;
+ }
+ return fp;
}
/********************************************************
Parse the next line in the lmhosts file.
*********************************************************/
-BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
+BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
{
pstring line;
- while(!x_feof(fp) && !x_ferror(fp)) {
+ while(!feof(fp) && !ferror(fp)) {
pstring ip,flags,extra;
const char *ptr;
char *ptr1;
@@ -597,7 +532,7 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa
DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
- if (strchr_m(flags,'G') || strchr_m(flags,'S'))
+ if (strchr(flags,'G') || strchr(flags,'S'))
{
DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
continue;
@@ -607,7 +542,7 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa
/* Extra feature. If the name ends in '#XX', where XX is a hex number,
then only add that name type. */
- if((ptr1 = strchr_m(name, '#')) != NULL)
+ if((ptr1 = strchr(name, '#')) != NULL)
{
char *endptr;
@@ -633,54 +568,88 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa
Finish parsing the lmhosts file.
*********************************************************/
-void endlmhosts(XFILE *fp)
+void endlmhosts(FILE *fp)
{
- x_fclose(fp);
+ fclose(fp);
}
-/********************************************************
- convert an array if struct in_addrs to struct ip_service
- return False on failure. Port is set to PORT_NONE;
-*********************************************************/
-
-static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
+BOOL name_register_wins(const char *name, int name_type)
{
- int i;
+ int sock, i, return_count;
+ int num_interfaces = iface_count();
+ struct in_addr sendto_ip;
- if ( count==0 || !ip_list )
- return False;
-
- /* copy the ip address; port will be PORT_NONE */
- if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) {
- DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
- return False;
- }
-
- for ( i=0; i<count; i++ ) {
- (*return_iplist)[i].ip = ip_list[i];
- (*return_iplist)[i].port = PORT_NONE;
- }
+ /*
+ * Check if we have any interfaces, prevents a segfault later
+ */
+
+ if (num_interfaces <= 0)
+ return False; /* Should return some indication of the problem */
+
+ /*
+ * Do a broadcast register ...
+ */
+
+ if (!lp_wins_server())
+ return False;
+
+ DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server()));
+
+ sock = open_socket_in(SOCK_DGRAM, 0, 3,
+ interpret_addr("0.0.0.0"), True);
+
+ if (sock == -1) return False;
+
+ set_socket_options(sock, "SO_BROADCAST");
+
+ sendto_ip.s_addr = inet_addr(lp_wins_server());
+
+ if (num_interfaces > 1) {
+
+ for (i = 0; i < num_interfaces; i++) {
+
+ if (!name_register(sock, name, name_type, *iface_n_ip(i),
+ NMB_NAME_MULTIHOMED_REG_OPCODE,
+ True, sendto_ip, &return_count)) {
+
+ close(sock);
+ return False;
+
+ }
+
+ }
+
+ }
+ else {
+
+ if (!name_register(sock, name, name_type, *iface_n_ip(0),
+ NMB_NAME_REG_OPCODE,
+ True, sendto_ip, &return_count)) {
+
+ close(sock);
+ return False;
+
+ }
+
+ }
+
+ close(sock);
+
+ return True;
+
+}
- return True;
-}
/********************************************************
Resolve via "bcast" method.
*********************************************************/
BOOL name_resolve_bcast(const char *name, int name_type,
- struct ip_service **return_iplist, int *return_count)
+ struct in_addr **return_ip_list, int *return_count)
{
int sock, i;
int num_interfaces = iface_count();
- struct in_addr *ip_list;
- BOOL ret;
-
- if (lp_disable_netbios()) {
- DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
- return False;
- }
- *return_iplist = NULL;
+ *return_ip_list = NULL;
*return_count = 0;
/*
@@ -703,129 +672,79 @@ BOOL name_resolve_bcast(const char *name, int name_type,
struct in_addr sendto_ip;
int flags;
/* Done this way to fix compiler error on IRIX 5.x */
- sendto_ip = *iface_n_bcast(i);
- ip_list = name_query(sock, name, name_type, True,
- True, sendto_ip, return_count, &flags, NULL);
- if( ip_list )
- goto success;
+ sendto_ip = *iface_bcast(*iface_n_ip(i));
+ *return_ip_list = name_query(sock, name, name_type, True,
+ True, sendto_ip, return_count, &flags);
+ if(*return_ip_list != NULL) {
+ close(sock);
+ return True;
+ }
}
-
- /* failed - no response */
-
+
close(sock);
return False;
-
-success:
- ret = True;
- if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
- ret = False;
-
- SAFE_FREE( ip_list );
- close(sock);
- return ret;
}
/********************************************************
Resolve via "wins" method.
*********************************************************/
-BOOL resolve_wins(const char *name, int name_type,
- struct ip_service **return_iplist, int *return_count)
+static BOOL resolve_wins(const char *name, int name_type,
+ struct in_addr **return_iplist, int *return_count)
{
- int sock, t, i;
- char **wins_tags;
- struct in_addr src_ip, *ip_list = NULL;
- BOOL ret;
-
- if (lp_disable_netbios()) {
- DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
- return False;
- }
+ int sock;
+ struct in_addr wins_ip;
+ BOOL wins_ismyip;
*return_iplist = NULL;
*return_count = 0;
+ /*
+ * "wins" means do a unicast lookup to the WINS server.
+ * Ignore if there is no WINS server specified or if the
+ * WINS server is one of our interfaces (if we're being
+ * called from within nmbd - we can't do this call as we
+ * would then block).
+ */
+
DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
- if (wins_srv_count() < 1) {
+ if (lp_wins_support()) {
+ /*
+ * We're providing WINS support. Call ourselves so
+ * long as we're not nmbd.
+ */
+ extern struct in_addr loopback_ip;
+ wins_ip = loopback_ip;
+ wins_ismyip = True;
+ } else if( wins_srv_count() < 1 ) {
DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
return False;
+ } else {
+ wins_ip = wins_srv_ip();
+ wins_ismyip = ismyip(wins_ip);
}
- /* we try a lookup on each of the WINS tags in turn */
- wins_tags = wins_srv_tags();
-
- if (!wins_tags) {
- /* huh? no tags?? give up in disgust */
- return False;
- }
-
- /* the address we will be sending from */
- src_ip = *interpret_addr2(lp_socket_address());
-
- /* in the worst case we will try every wins server with every
- tag! */
- for (t=0; wins_tags && wins_tags[t]; t++) {
- int srv_count = wins_srv_count_tag(wins_tags[t]);
- for (i=0; i<srv_count; i++) {
- struct in_addr wins_ip;
- int flags;
- BOOL timed_out;
-
- wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
-
- if (global_in_nmbd && ismyip(wins_ip)) {
- /* yikes! we'll loop forever */
- continue;
- }
-
- /* skip any that have been unresponsive lately */
- if (wins_srv_is_dead(wins_ip, src_ip)) {
- continue;
- }
-
- DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
-
- sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
- if (sock == -1) {
- continue;
+ DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) );
+ if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
+ sock = open_socket_in( SOCK_DGRAM, 0, 3,
+ interpret_addr(lp_socket_address()),
+ True );
+ if (sock != -1) {
+ int flags;
+ *return_iplist = name_query( sock, name,
+ name_type, False,
+ True, wins_ip,
+ return_count, &flags);
+ if(*return_iplist != NULL) {
+ close(sock);
+ return True;
}
-
- ip_list = name_query(sock,name,name_type, False,
- True, wins_ip, return_count, &flags,
- &timed_out);
-
- /* exit loop if we got a list of addresses */
-
- if ( ip_list )
- goto success;
-
close(sock);
-
- if (timed_out) {
- /* Timed out wating for WINS server to respond. Mark it dead. */
- wins_srv_died(wins_ip, src_ip);
- } else {
- /* The name definately isn't in this
- group of WINS servers. goto the next group */
- break;
- }
}
}
- wins_srv_tags_free(wins_tags);
return False;
-
-success:
- ret = True;
- if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
- ret = False;
-
- SAFE_FREE( ip_list );
- wins_srv_tags_free(wins_tags);
- close(sock);
-
- return ret;
}
/********************************************************
@@ -833,13 +752,13 @@ success:
*********************************************************/
static BOOL resolve_lmhosts(const char *name, int name_type,
- struct ip_service **return_iplist, int *return_count)
+ struct in_addr **return_iplist, int *return_count)
{
/*
* "lmhosts" means parse the local lmhosts file.
*/
- XFILE *fp;
+ FILE *fp;
pstring lmhost_name;
int name_type2;
struct in_addr return_ip;
@@ -849,19 +768,19 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
- fp = startlmhosts(dyn_LMHOSTSFILE);
+ fp = startlmhosts( LMHOSTSFILE );
if(fp) {
while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
if (strequal(name, lmhost_name) &&
((name_type2 == -1) || (name_type == name_type2))
) {
endlmhosts(fp);
- if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
+ *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if(*return_iplist == NULL) {
DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
return False;
}
- (*return_iplist)[0].ip = return_ip;
- (*return_iplist)[0].port = PORT_NONE;
+ **return_iplist = return_ip;
*return_count = 1;
return True;
}
@@ -876,120 +795,45 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
Resolve via "hosts" method.
*********************************************************/
-static BOOL resolve_hosts(const char *name, int name_type,
- struct ip_service **return_iplist, int *return_count)
+static BOOL resolve_hosts(const char *name,
+ struct in_addr **return_iplist, int *return_count)
{
/*
* "host" means do a localhost, or dns lookup.
*/
struct hostent *hp;
-
- if ( name_type != 0x20 && name_type != 0x0) {
- DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
- return False;
- }
*return_iplist = NULL;
*return_count = 0;
- DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
- struct in_addr return_ip;
- putip((char *)&return_ip,(char *)hp->h_addr);
- *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
+ int i = 0, j;
+ while (hp->h_addr_list[i]) i++;
+ DEBUG(10, ("%d addresses returned\n", i));
+ *return_iplist = (struct in_addr *)malloc(i*sizeof(struct in_addr));
if(*return_iplist == NULL) {
DEBUG(3,("resolve_hosts: malloc fail !\n"));
return False;
}
- (*return_iplist)->ip = return_ip;
- (*return_iplist)->port = PORT_NONE;
- *return_count = 1;
+ for (j = 0; j < i; j++)
+ putip(&(*return_iplist)[j], (char *)hp->h_addr_list[j]);
+ *return_count = i;
return True;
}
return False;
}
/********************************************************
- Resolve via "ADS" method.
-*********************************************************/
-
-static BOOL resolve_ads(const char *name, int name_type,
- struct ip_service **return_iplist, int *return_count)
-{
-
-#ifdef HAVE_ADS
- if ( name_type == 0x1c ) {
- int count, i = 0;
- char *list = NULL;
- const char *ptr;
- pstring tok;
-
- /* try to lookup the _ldap._tcp.<domain> if we are using ADS */
- if ( lp_security() != SEC_ADS )
- return False;
-
- DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
- name));
-
- if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
- return False;
-
- count = count_chars(list, ' ') + 1;
- if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
- DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
- return False;
- }
-
- ptr = list;
- while (next_token(&ptr, tok, " ", sizeof(tok))) {
- unsigned port = LDAP_PORT;
- char *p = strchr(tok, ':');
- if (p) {
- *p = 0;
- port = atoi(p+1);
- }
- (*return_iplist)[i].ip = *interpret_addr2(tok);
- (*return_iplist)[i].port = port;
-
- /* make sure it is a valid IP. I considered checking the negative
- connection cache, but this is the wrong place for it. Maybe only
- as a hac. After think about it, if all of the IP addresses retuend
- from DNS are dead, what hope does a netbios name lookup have?
- The standard reason for falling back to netbios lookups is that
- our DNS server doesn't know anything about the DC's -- jerry */
-
- if ( is_zero_ip((*return_iplist)[i].ip) )
- continue;
-
- i++;
- }
- SAFE_FREE(list);
-
- *return_count = i;
-
- return True;
- } else
-#endif /* HAVE_ADS */
- {
- return False;
- }
-}
-
-/*******************************************************************
Internal interface to resolve a name into an IP address.
Use this function if the string is either an IP address, DNS
or host name or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
-
- Added support for ip addr/port to support ADS ldap servers.
- the only place we currently care about the port is in the
- resolve_hosts() when looking up DC's via SRV RR entries in DNS
-**********************************************************************/
+*********************************************************/
static BOOL internal_resolve_name(const char *name, int name_type,
- struct ip_service **return_iplist,
- int *return_count, const char *resolve_order)
+ struct in_addr **return_iplist, int *return_count)
{
pstring name_resolve_list;
fstring tok;
@@ -998,92 +842,65 @@ static BOOL internal_resolve_name(const char *name, int name_type,
BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
BOOL is_address = is_ipaddress(name);
BOOL result = False;
+ struct in_addr *nodupes_iplist;
int i;
*return_iplist = NULL;
*return_count = 0;
- DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
-
if (allzeros || allones || is_address) {
-
- if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
- DEBUG(0,("internal_resolve_name: malloc fail !\n"));
+ *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if(*return_iplist == NULL) {
+ DEBUG(3,("internal_resolve_name: malloc fail !\n"));
return False;
}
-
if(is_address) {
- /* ignore the port here */
- (*return_iplist)->port = PORT_NONE;
-
/* if it's in the form of an IP address then get the lib to interpret it */
- if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
+ if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
return False;
}
} else {
- (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
+ (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
+ *return_count = 1;
}
- *return_count = 1;
- return True;
+ return True;
}
-
- /* Check name cache */
+
+ /* Check netbios name cache */
if (namecache_fetch(name, name_type, return_iplist, return_count)) {
- /* This could be a negative response */
- return (*return_count > 0);
+ /* This could be a negative response */
+ return (*return_count > 0);
}
- /* set the name resolution order */
-
- if ( strcmp( resolve_order, "NULL") == 0 ) {
- DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
- return False;
- }
-
- if ( !resolve_order )
- pstrcpy(name_resolve_list, lp_name_resolve_order());
- else
- pstrcpy(name_resolve_list, resolve_order);
-
- if ( !name_resolve_list[0] )
+ pstrcpy(name_resolve_list, lp_name_resolve_order());
+ ptr = name_resolve_list;
+ if (!ptr || !*ptr)
ptr = "host";
- else
- ptr = name_resolve_list;
- /* iterate through the name resolution backends */
-
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (resolve_hosts(name, name_type, return_iplist, return_count)) {
+ if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
result = True;
- goto done;
- }
- } else if(strequal( tok, "ads")) {
- /* deal with 0x1c names here. This will result in a
- SRV record lookup for _ldap._tcp.<domain> if we
- are using 'security = ads' */
- if (resolve_ads(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
+ goto done;
}
} else if(strequal( tok, "lmhosts")) {
if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
+ result = True;
+ goto done;
}
} else if(strequal( tok, "wins")) {
/* don't resolve 1D via WINS */
if (name_type != 0x1D &&
- resolve_wins(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
+ resolve_wins(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
}
} else if(strequal( tok, "bcast")) {
if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
+ result = True;
+ goto done;
}
} else {
DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
@@ -1093,42 +910,60 @@ static BOOL internal_resolve_name(const char *name, int name_type,
/* All of the resolve_* functions above have returned false. */
SAFE_FREE(*return_iplist);
- *return_count = 0;
-
return False;
- done:
+ done:
/* Remove duplicate entries. Some queries, notably #1c (domain
controllers) return the PDC in iplist[0] and then all domain
controllers including the PDC in iplist[1..n]. Iterating over
the iplist when the PDC is down will cause two sets of timeouts. */
- if ( *return_count ) {
- *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
- }
+ if (*return_count && (nodupes_iplist =
+ (struct in_addr *)malloc(sizeof(struct in_addr) * (*return_count)))) {
+ int nodupes_count = 0;
+
+ /* Iterate over return_iplist looking for duplicates */
- /* Save in name cache */
- if ( DEBUGLEVEL >= 100 ) {
- for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
- DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
- name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ for (i = 0; i < *return_count; i++) {
+ BOOL is_dupe = False;
+ int j;
+
+ for (j = i + 1; j < *return_count; j++) {
+ if (ip_equal((*return_iplist)[i],
+ (*return_iplist)[j])) {
+ is_dupe = True;
+ break;
+ }
+ }
+
+ if (!is_dupe) {
+
+ /* This one not a duplicate */
+
+ nodupes_iplist[nodupes_count] = (*return_iplist)[i];
+ nodupes_count++;
+ }
+ }
+
+ /* Switcheroo with original list */
+
+ free(*return_iplist);
+
+ *return_iplist = nodupes_iplist;
+ *return_count = nodupes_count;
}
-
- namecache_store(name, name_type, *return_count, *return_iplist);
-
+
/* Display some debugging info */
-
- if ( DEBUGLEVEL >= 10 ) {
- DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
- *return_count));
-
- for (i = 0; i < *return_count; i++)
- DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
-
- DEBUG(10, ("\n"));
- }
-
+
+ DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
+ *return_count));
+
+ for (i = 0; i < *return_count; i++)
+ DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
+
+ DEBUG(10, ("\n"));
+
return result;
}
@@ -1141,7 +976,7 @@ static BOOL internal_resolve_name(const char *name, int name_type,
BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
{
- struct ip_service *ip_list = NULL;
+ struct in_addr *ip_list = NULL;
int count = 0;
if (is_ipaddress(name)) {
@@ -1149,48 +984,95 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
return True;
}
- if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
+ if(internal_resolve_name(name, name_type, &ip_list, &count)) {
int i;
-
/* only return valid addresses for TCP connections */
for (i=0; i<count; i++) {
- char *ip_str = inet_ntoa(ip_list[i].ip);
+ char *ip_str = inet_ntoa(ip_list[i]);
if (ip_str &&
- strcmp(ip_str, "255.255.255.255") != 0 &&
- strcmp(ip_str, "0.0.0.0") != 0)
- {
- *return_ip = ip_list[i].ip;
+ strcmp(ip_str, "255.255.255.255") != 0 &&
+ strcmp(ip_str, "0.0.0.0") != 0) {
+ *return_ip = ip_list[i];
SAFE_FREE(ip_list);
return True;
}
}
}
-
SAFE_FREE(ip_list);
return False;
}
+/**************************************************************************
+ Resolve a name to a list of addresses
+**************************************************************************/
+BOOL resolve_name_2(const char *name, struct in_addr **return_ip, int *count, int name_type)
+{
+
+ return internal_resolve_name(name, name_type, return_ip, count);
+
+}
+
+/********************************************************
+ resolve a name of format \\server_name or \\ipaddress
+ into a name. also, cut the \\ from the front for us.
+*********************************************************/
+
+BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
+ struct in_addr *ip)
+{
+ BOOL ret;
+ const char *sv_name = srv_name;
+
+ DEBUG(10,("resolve_srv_name: %s\n", srv_name));
+
+ if (srv_name == NULL || strequal("\\\\.", srv_name))
+ {
+ extern pstring global_myname;
+ fstrcpy(dest_host, global_myname);
+ ip = interpret_addr2("127.0.0.1");
+ return True;
+ }
+
+ if (strnequal("\\\\", srv_name, 2))
+ {
+ sv_name = &srv_name[2];
+ }
+
+ fstrcpy(dest_host, sv_name);
+ /* treat the '*' name specially - it is a magic name for the PDC */
+ if (strcmp(dest_host,"*") == 0) {
+ extern pstring global_myname;
+ ret = resolve_name(lp_workgroup(), ip, 0x1B);
+ lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
+ } else {
+ ret = resolve_name(dest_host, ip, 0x20);
+ }
+
+ if (is_ipaddress(dest_host))
+ {
+ fstrcpy(dest_host, "*SMBSERVER");
+ }
+
+ return ret;
+}
+
+
/********************************************************
Find the IP address of the master browser or DMB for a workgroup.
*********************************************************/
-BOOL find_master_ip(const char *group, struct in_addr *master_ip)
+BOOL find_master_ip(char *group, struct in_addr *master_ip)
{
- struct ip_service *ip_list = NULL;
+ struct in_addr *ip_list = NULL;
int count = 0;
- if (lp_disable_netbios()) {
- DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
- return False;
- }
-
- if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
- *master_ip = ip_list[0].ip;
+ if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
+ *master_ip = ip_list[0];
SAFE_FREE(ip_list);
return True;
}
- if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
- *master_ip = ip_list[0].ip;
+ if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
+ *master_ip = ip_list[0];
SAFE_FREE(ip_list);
return True;
}
@@ -1200,207 +1082,287 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
}
/********************************************************
- Get the IP address list of the primary domain controller
- for a domain.
+ Lookup a DC name given a Domain name and IP address.
*********************************************************/
-BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
+BOOL lookup_dc_name(const char *srcname, const char *domain,
+ struct in_addr *dc_ip, char *ret_name)
{
- struct ip_service *ip_list;
- int count;
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)
- /* Look up #1B name */
+ fstring dc_name;
+ BOOL ret;
- if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
- return False;
+ /*
+ * Due to the fact win WinNT *sucks* we must do a node status
+ * query here... JRA.
+ */
+
+ *dc_name = '\0';
+
+ ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
+
+ if(ret && *dc_name) {
+ fstrcpy(ret_name, dc_name);
+ return True;
+ }
+
+ return False;
+
+#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
- /* if we get more than 1 IP back we have to assume it is a
- multi-homed PDC and not a mess up */
+JRA - This code is broken with BDC rollover - we need to do a full
+NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
- if ( count > 1 ) {
- DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
- sort_ip_list2( ip_list, count );
+ int retries = 3;
+ int retry_time = 2000;
+ struct timeval tval;
+ struct packet_struct p;
+ struct dgram_packet *dgram = &p.packet.dgram;
+ char *ptr,*p2;
+ char tmp[4];
+ int len;
+ struct sockaddr_in sock_name;
+ int sock_len = sizeof(sock_name);
+ const char *mailslot = NET_LOGON_MAILSLOT;
+ char *mailslot_name;
+ char buffer[1024];
+ char *bufp;
+ int dgm_id = generate_trn_id();
+ int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
+
+ if(sock == -1)
+ return False;
+
+ /* Find out the transient UDP port we have been allocated. */
+ if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
+ DEBUG(0,("lookup_dc_name: Failed to get local UDP port. Error was %s\n",
+ strerror(errno)));
+ close(sock);
+ return False;
}
- *ip = ip_list[0].ip;
+ /*
+ * Create the request data.
+ */
+
+ memset(buffer,'\0',sizeof(buffer));
+ bufp = buffer;
+ SSVAL(bufp,0,QUERYFORPDC);
+ bufp += 2;
+ fstrcpy(bufp,srcname);
+ bufp += (strlen(bufp) + 1);
+ slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
+ mailslot_name = bufp;
+ bufp += (strlen(bufp) + 1);
+ bufp = ALIGN2(bufp, buffer);
+ bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True);
+ SIVAL(bufp,0,1);
+ SSVAL(bufp,4,0xFFFF);
+ SSVAL(bufp,6,0xFFFF);
+ bufp += 8;
+ len = PTR_DIFF(bufp,buffer);
+
+ memset((char *)&p,'\0',sizeof(p));
+
+ /* DIRECT GROUP or UNIQUE datagram. */
+ dgram->header.msg_type = 0x10;
+ dgram->header.flags.node_type = M_NODE;
+ dgram->header.flags.first = True;
+ dgram->header.flags.more = False;
+ dgram->header.dgm_id = dgm_id;
+ dgram->header.source_ip = *iface_ip(*pdc_ip);
+ dgram->header.source_port = ntohs(sock_name.sin_port);
+ dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
+ dgram->header.packet_offset = 0;
- SAFE_FREE(ip_list);
+ make_nmb_name(&dgram->source_name,srcname,0);
+ make_nmb_name(&dgram->dest_name,domain,0x1C);
+
+ ptr = &dgram->data[0];
+
+ /* Setup the smb part. */
+ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
+ memcpy(tmp,ptr,4);
+ set_message(ptr,17,17 + len,True);
+ memcpy(ptr,tmp,4);
+
+ CVAL(ptr,smb_com) = SMBtrans;
+ SSVAL(ptr,smb_vwv1,len);
+ SSVAL(ptr,smb_vwv11,len);
+ SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
+ SSVAL(ptr,smb_vwv13,3);
+ SSVAL(ptr,smb_vwv14,1);
+ SSVAL(ptr,smb_vwv15,1);
+ SSVAL(ptr,smb_vwv16,2);
+ p2 = smb_buf(ptr);
+ pstrcpy(p2,mailslot);
+ p2 = skip_string(p2,1);
+
+ memcpy(p2,buffer,len);
+ p2 += len;
+
+ dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
+
+ p.ip = *pdc_ip;
+ p.port = DGRAM_PORT;
+ p.fd = sock;
+ p.timestamp = time(NULL);
+ p.packet_type = DGRAM_PACKET;
+
+ GetTimeOfDay(&tval);
+
+ if (!send_packet(&p)) {
+ DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
+ close(sock);
+ return False;
+ }
+
+ retries--;
+
+ while (1) {
+ struct timeval tval2;
+ struct packet_struct *p_ret;
+
+ GetTimeOfDay(&tval2);
+ if (TvalDiff(&tval,&tval2) > retry_time) {
+ if (!retries)
+ break;
+ if (!send_packet(&p)) {
+ DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
+ close(sock);
+ return False;
+ }
+ GetTimeOfDay(&tval);
+ retries--;
+ }
- return True;
+ if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
+ struct dgram_packet *dgram2 = &p_ret->packet.dgram;
+ char *buf;
+ char *buf2;
+
+ buf = &dgram2->data[0];
+ buf -= 4;
+
+ if (CVAL(buf,smb_com) != SMBtrans) {
+ DEBUG(0,("lookup_dc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
+ CVAL(buf,smb_com), (unsigned int)SMBtrans ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ len = SVAL(buf,smb_vwv11);
+ buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+
+ if (len <= 0) {
+ DEBUG(0,("lookup_dc_name: datagram len < 0 (%d)\n", len ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ DEBUG(4,("lookup_dc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
+ nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
+ inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
+
+ if(SVAL(buf2,0) != QUERYFORPDC_R) {
+ DEBUG(0,("lookup_dc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
+ (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ buf2 += 2;
+ /* Note this is safe as it is a bounded strcpy. */
+ fstrcpy(ret_name, buf2);
+ ret_name[sizeof(fstring)-1] = '\0';
+ close(sock);
+ free_packet(p_ret);
+ return True;
+ }
+ }
+
+ close(sock);
+ return False;
+#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
}
+
/********************************************************
- Get the IP address list of the domain controllers for
- a domain.
+ Get the IP address list of the PDC/BDC's of a Domain.
*********************************************************/
-static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
- int *count, BOOL ads_only, int *ordered)
+BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
{
- fstring resolve_order;
-
- /* if we are restricted to solely using DNS for looking
- up a domain controller, make sure that host lookups
- are enabled for the 'name resolve order'. If host lookups
- are disabled and ads_only is True, then set the string to
- NULL. */
-
- fstrcpy( resolve_order, lp_name_resolve_order() );
- strlower_m( resolve_order );
- if ( ads_only ) {
- if ( strstr( resolve_order, "host" ) )
- fstrcpy( resolve_order, "ads" );
- else
- fstrcpy( resolve_order, "NULL" );
- }
+ int name_type = pdc_only ? 0x1B : 0x1C;
-
- *ordered = False;
-
- /* If it's our domain then use the 'password server' parameter. */
+ /*
+ * If it's our domain then
+ * use the 'password server' parameter.
+ */
- if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
+ if (strequal(group, lp_workgroup())) {
const char *p;
- char *pserver = lp_passwordserver(); /* UNIX charset. */
- char *port_str;
- int port;
+ char *pserver = lp_passwordserver();
fstring name;
int num_addresses = 0;
- int local_count, i, j;
- struct ip_service *return_iplist = NULL;
- struct ip_service *auto_ip_list = NULL;
- BOOL done_auto_lookup = False;
- int auto_count = 0;
-
+ struct in_addr *return_iplist = NULL;
- if (!*pserver)
- return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
+ if (! *pserver)
+ return internal_resolve_name(group, name_type, ip_list, count);
p = pserver;
-
- /*
- * if '*' appears in the "password server" list then add
- * an auto lookup to the list of manually configured
- * DC's. If any DC is listed by name, then the list should be
- * considered to be ordered
- */
-
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
if (strequal(name, "*")) {
- if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
- num_addresses += auto_count;
- done_auto_lookup = True;
- DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
+ /*
+ * Use 1C followed by 1B. This shouldn't work but with
+ * broken WINS servers it might. JRA.
+ */
+ if (!pdc_only && internal_resolve_name(group, 0x1C, ip_list, count))
+ return True;
+ return internal_resolve_name(group, 0x1B, ip_list, count);
}
- else
- num_addresses++;
+ num_addresses++;
}
+ if (num_addresses == 0)
+ return internal_resolve_name(group, name_type, ip_list, count);
- /* if we have no addresses and haven't done the auto lookup, then
- just return the list of DC's */
-
- if ( (num_addresses == 0) && !done_auto_lookup )
- return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
-
- /* maybe we just failed? */
-
- if ( num_addresses == 0 ) {
- DEBUG(4,("get_dc_list: no servers found\n"));
- return False;
- }
-
- if ( (return_iplist = (struct ip_service *)
- malloc(num_addresses * sizeof(struct ip_service))) == NULL )
- {
+ return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
+ if(return_iplist == NULL) {
DEBUG(3,("get_dc_list: malloc fail !\n"));
return False;
}
-
p = pserver;
- local_count = 0;
-
- /* fill in the return list now with real IP's */
-
- while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
- struct in_addr name_ip;
-
- /* copy any addersses from the auto lookup */
-
- if ( strequal(name, "*") ) {
- for ( j=0; j<auto_count; j++ ) {
- return_iplist[local_count].ip = auto_ip_list[j].ip;
- return_iplist[local_count].port = auto_ip_list[j].port;
- local_count++;
- }
+ *count = 0;
+ while (next_token(&p,name,LIST_SEP,sizeof(name))) {
+ struct in_addr *more_ip, *tmp;
+ int count_more;
+ if (resolve_name_2( name, &more_ip, &count_more, 0x20) == False)
continue;
+ tmp = (struct in_addr *)realloc(return_iplist,(num_addresses + count_more) * sizeof(struct in_addr));
+ if (return_iplist == NULL) {
+ DEBUG(3, ("realloc failed with %d addresses\n", num_addresses + count_more));
+ SAFE_FREE(return_iplist);
+ SAFE_FREE(more_ip);
+ return False;
}
-
-
- /* added support for address:port syntax for ads (not that I think
- anyone will ever run the LDAP server in an AD domain on something
- other than port 389 */
-
- port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
- if ( (port_str=strchr(name, ':')) != NULL ) {
- *port_str = '\0';
- port_str++;
- port = atoi( port_str );
- }
-
- /* explicit lookup; resolve_name() will handle names & IP addresses */
- if ( resolve_name( name, &name_ip, 0x20 ) ) {
- return_iplist[local_count].ip = name_ip;
- return_iplist[local_count].port = port;
- local_count++;
- *ordered = True;
- }
- }
-
- SAFE_FREE(auto_ip_list);
-
- /* need to remove duplicates in the list if we have any
- explicit password servers */
-
- if ( local_count )
- local_count = remove_duplicate_addrs2( return_iplist, local_count );
-
- if ( DEBUGLEVEL >= 4 ) {
- DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
- *ordered ? "":"un"));
- DEBUG(4,("get_dc_list: "));
- for ( i=0; i<local_count; i++ )
- DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
- DEBUGADD(4,("\n"));
+ return_iplist = tmp;
+ memmove(&return_iplist[(*count)], more_ip, count_more * sizeof(struct in_addr));
+ SAFE_FREE(more_ip); /* Done with this ... */
+ *count += count_more;
+ num_addresses += count_more - 1;
}
-
*ip_list = return_iplist;
- *count = local_count;
-
return (*count != 0);
- }
-
- DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
-
- return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
+ } else
+ return internal_resolve_name(group, name_type, ip_list, count);
}
-/*********************************************************************
- small wrapper function to get the DC list and sort it if neccessary
-*********************************************************************/
-BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
+/********************************************************
+ Get the IP address list of the Local Master Browsers
+********************************************************/
+
+BOOL get_lmb_list(struct in_addr **ip_list, int *count)
{
- BOOL ordered;
-
- DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
- (ads_only ? "ads" : lp_name_resolve_order())));
-
- if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) )
- return False;
-
- /* only sort if we don't already have an ordered list */
- if ( !ordered )
- sort_ip_list2( *ip_list, *count );
-
- return True;
+ return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);
}
-
diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c
deleted file mode 100644
index 31d759e0d2c..00000000000
--- a/source/libsmb/namequery_dc.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon connection manager
-
- Copyright (C) Tim Potter 2001
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Gerald Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-/**************************************************************************
- Find the name and IP address for a server in he realm/domain
- *************************************************************************/
-
-static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name)
-{
- ADS_STRUCT *ads;
-
- if (!realm && strequal(domain, lp_workgroup()))
- realm = lp_realm();
-
- ads = ads_init(realm, domain, NULL);
- if (!ads)
- return False;
-
- DEBUG(4,("ads_dc_name: domain=%s\n", domain));
-
-#ifdef HAVE_ADS
- /* we don't need to bind, just connect */
- ads->auth.flags |= ADS_AUTH_NO_BIND;
-
- ads_connect(ads);
-#endif
-
- if (!ads->config.realm)
- return False;
-
- fstrcpy(srv_name, ads->config.ldap_server_name);
- strupper_m(srv_name);
- *dc_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
- srv_name, inet_ntoa(*dc_ip)));
-
- return True;
-}
-
-/****************************************************************************
- Utility function to return the name of a DC. The name is guaranteed to be
- valid since we have already done a name_status_find on it
- ***************************************************************************/
-
-static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
-{
- struct ip_service *ip_list = NULL;
- struct in_addr dc_ip, exclude_ip;
- int count, i;
- BOOL use_pdc_only;
- NTSTATUS result;
-
- zero_ip(&exclude_ip);
-
- use_pdc_only = must_use_pdc(domain);
-
- /* Lookup domain controller name */
-
- if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) )
- {
- DEBUG(10,("rpc_dc_name: Atempting to lookup PDC to avoid sam sync delays\n"));
-
- /* check the connection cache and perform the node status
- lookup only if the IP is not found to be bad */
-
- if (name_status_find(domain, 0x1b, 0x20, dc_ip, srv_name) ) {
- result = check_negative_conn_cache( domain, srv_name );
- if ( NT_STATUS_IS_OK(result) )
- goto done;
- }
- /* Didn't get name, remember not to talk to this DC. */
- exclude_ip = dc_ip;
- }
-
- /* get a list of all domain controllers */
-
- if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
- DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
- return False;
- }
-
- /* Remove the entry we've already failed with (should be the PDC). */
-
- if ( use_pdc_only ) {
- for (i = 0; i < count; i++) {
- if (ip_equal( exclude_ip, ip_list[i].ip))
- zero_ip(&ip_list[i].ip);
- }
- }
-
- for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i].ip))
- continue;
-
- if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
- result = check_negative_conn_cache( domain, srv_name );
- if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i].ip;
- goto done;
- }
- }
- }
-
-
- SAFE_FREE(ip_list);
-
- /* No-one to talk to )-: */
- return False; /* Boo-hoo */
-
- done:
- /* We have the netbios name and IP address of a domain controller.
- Ideally we should sent a SAMLOGON request to determine whether
- the DC is alive and kicking. If we can catch a dead DC before
- performing a cli_connect() we can avoid a 30-second timeout. */
-
- DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
- inet_ntoa(dc_ip), domain));
-
- *ip_out = dc_ip;
-
- SAFE_FREE(ip_list);
-
- return True;
-}
-
-/**********************************************************************
- wrapper around ads and rpc methods of finds DC's
-**********************************************************************/
-
-BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out)
-{
- struct in_addr dc_ip;
- BOOL ret;
- BOOL our_domain = False;
-
- zero_ip(&dc_ip);
-
- ret = False;
-
- if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) )
- our_domain = True;
-
- /* always try to obey what the admin specified in smb.conf
- (for the local domain) */
-
- if ( (our_domain && lp_security()==SEC_ADS) || realm ) {
- ret = ads_dc_name(domain, realm, &dc_ip, srv_name);
- }
-
- if (!ret) {
- /* fall back on rpc methods if the ADS methods fail */
- ret = rpc_dc_name(domain, srv_name, &dc_ip);
- }
-
- *ip_out = dc_ip;
-
- return ret;
-}
-
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 3c25eba744f..cf5f078fc4f 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios library routines
Copyright (C) Andrew Tridgell 1994-1998
@@ -28,665 +29,636 @@ static const struct opcode_names {
const char *nmb_opcode_name;
int opcode;
} nmb_header_opcode_names[] = {
- {"Query", 0 },
- {"Registration", 5 },
- {"Release", 6 },
- {"WACK", 7 },
- {"Refresh", 8 },
- {"Refresh(altcode)", 9 },
- {"Multi-homed Registration", 15 },
- {0, -1 }
+ {"Query", 0 },
+ {"Registration", 5 },
+ {"Release", 6 },
+ {"WACK", 7 },
+ {"Refresh", 8 },
+ {"Refresh(altcode)", 9 },
+ {"Multi-homed Registration", 15 },
+ {0, -1 }
};
/****************************************************************************
- Lookup a nmb opcode name.
-****************************************************************************/
-
+ * Lookup a nmb opcode name.
+ ****************************************************************************/
static const char *lookup_opcode_name( int opcode )
{
- const struct opcode_names *op_namep;
- int i;
-
- for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
- op_namep = &nmb_header_opcode_names[i];
- if(opcode == op_namep->opcode)
- return op_namep->nmb_opcode_name;
- }
- return "<unknown opcode>";
+ const struct opcode_names *op_namep;
+ int i;
+
+ for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
+ op_namep = &nmb_header_opcode_names[i];
+ if(opcode == op_namep->opcode)
+ return op_namep->nmb_opcode_name;
+ }
+ return "<unknown opcode>";
}
/****************************************************************************
- Print out a res_rec structure.
-****************************************************************************/
-
+ print out a res_rec structure
+ ****************************************************************************/
static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
{
- int i, j;
-
- DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
- hdr,
- nmb_namestr(&res->rr_name),
- res->rr_type,
- res->rr_class,
- res->ttl ) );
-
- if( res->rdlength == 0 || res->rdata == NULL )
- return;
-
- for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
- DEBUGADD(4, (" %s %3x char ", hdr, i));
-
- for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
- unsigned char x = res->rdata[i+j];
- if (x < 32 || x > 127)
- x = '.';
+ int i, j;
+
+ DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
+ hdr,
+ nmb_namestr(&res->rr_name),
+ res->rr_type,
+ res->rr_class,
+ res->ttl ) );
+
+ if( res->rdlength == 0 || res->rdata == NULL )
+ return;
+
+ for (i = 0; i < res->rdlength; i+= 16)
+ {
+ DEBUGADD(4, (" %s %3x char ", hdr, i));
+
+ for (j = 0; j < 16; j++)
+ {
+ uchar x = res->rdata[i+j];
+ if (x < 32 || x > 127) x = '.';
- if (i+j >= res->rdlength)
- break;
- DEBUGADD(4, ("%c", x));
- }
+ if (i+j >= res->rdlength) break;
+ DEBUGADD(4, ("%c", x));
+ }
- DEBUGADD(4, (" hex "));
+ DEBUGADD(4, (" hex "));
- for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
- if (i+j >= res->rdlength)
- break;
- DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
- }
-
- DEBUGADD(4, ("\n"));
+ for (j = 0; j < 16; j++)
+ {
+ if (i+j >= res->rdlength) break;
+ DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
}
+
+ DEBUGADD(4, ("\n"));
+ }
}
/****************************************************************************
- Process a nmb packet.
-****************************************************************************/
-
+ process a nmb packet
+ ****************************************************************************/
void debug_nmb_packet(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if( DEBUGLVL( 4 ) ) {
- dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
- inet_ntoa(p->ip), p->port,
- nmb->header.name_trn_id,
- lookup_opcode_name(nmb->header.opcode),
- nmb->header.opcode,
- BOOLSTR(nmb->header.response) );
- dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
- BOOLSTR(nmb->header.nm_flags.bcast),
- BOOLSTR(nmb->header.nm_flags.recursion_available),
- BOOLSTR(nmb->header.nm_flags.recursion_desired),
- BOOLSTR(nmb->header.nm_flags.trunc),
- BOOLSTR(nmb->header.nm_flags.authoritative) );
- dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
- nmb->header.rcode,
- nmb->header.qdcount,
- nmb->header.ancount,
- nmb->header.nscount,
- nmb->header.arcount );
- }
-
- if (nmb->header.qdcount) {
- DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
- nmb_namestr(&nmb->question.question_name),
- nmb->question.question_type,
- nmb->question.question_class) );
- }
-
- if (nmb->answers && nmb->header.ancount) {
- debug_nmb_res_rec(nmb->answers,"answers");
- }
- if (nmb->nsrecs && nmb->header.nscount) {
- debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
- }
- if (nmb->additional && nmb->header.arcount) {
- debug_nmb_res_rec(nmb->additional,"additional");
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+
+ if( DEBUGLVL( 4 ) )
+ {
+ dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
+ inet_ntoa(p->ip), p->port,
+ nmb->header.name_trn_id,
+ lookup_opcode_name(nmb->header.opcode),
+ nmb->header.opcode,
+ BOOLSTR(nmb->header.response) );
+ dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
+ BOOLSTR(nmb->header.nm_flags.bcast),
+ BOOLSTR(nmb->header.nm_flags.recursion_available),
+ BOOLSTR(nmb->header.nm_flags.recursion_desired),
+ BOOLSTR(nmb->header.nm_flags.trunc),
+ BOOLSTR(nmb->header.nm_flags.authoritative) );
+ dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
+ nmb->header.rcode,
+ nmb->header.qdcount,
+ nmb->header.ancount,
+ nmb->header.nscount,
+ nmb->header.arcount );
+ }
+
+ if (nmb->header.qdcount)
+ {
+ DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
+ nmb_namestr(&nmb->question.question_name),
+ nmb->question.question_type,
+ nmb->question.question_class) );
+ }
+
+ if (nmb->answers && nmb->header.ancount)
+ {
+ debug_nmb_res_rec(nmb->answers,"answers");
+ }
+ if (nmb->nsrecs && nmb->header.nscount)
+ {
+ debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
+ }
+ if (nmb->additional && nmb->header.arcount)
+ {
+ debug_nmb_res_rec(nmb->additional,"additional");
+ }
}
/*******************************************************************
- Handle "compressed" name pointers.
-******************************************************************/
-
-static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
+ handle "compressed" name pointers
+ ******************************************************************/
+static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
BOOL *got_pointer,int *ret)
{
- int loop_count=0;
+ int loop_count=0;
- while ((ubuf[*offset] & 0xC0) == 0xC0) {
- if (!*got_pointer)
- (*ret) += 2;
- (*got_pointer)=True;
- (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
- if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
- return(False);
- }
- }
- return(True);
+ while ((ubuf[*offset] & 0xC0) == 0xC0) {
+ if (!*got_pointer) (*ret) += 2;
+ (*got_pointer)=True;
+ (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
+ if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
+ return(False);
+ }
+ }
+ return(True);
}
/*******************************************************************
- Parse a nmb name from "compressed" format to something readable
- return the space taken by the name, or 0 if the name is invalid
-******************************************************************/
-
+ parse a nmb name from "compressed" format to something readable
+ return the space taken by the name, or 0 if the name is invalid
+ ******************************************************************/
static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
{
- int m,n=0;
- unsigned char *ubuf = (unsigned char *)inbuf;
- int ret = 0;
- BOOL got_pointer=False;
- int loop_count=0;
- int offset = ofs;
-
- if (length - offset < 2)
- return(0);
-
- /* handle initial name pointers */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
- return(0);
+ int m,n=0;
+ uchar *ubuf = (uchar *)inbuf;
+ int ret = 0;
+ BOOL got_pointer=False;
+ int loop_count=0;
+ int offset = ofs;
+
+ if (length - offset < 2)
+ return(0);
+
+ /* handle initial name pointers */
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
- m = ubuf[offset];
-
- if (!m)
- return(0);
- if ((m & 0xC0) || offset+m+2 > length)
- return(0);
-
- memset((char *)name,'\0',sizeof(*name));
-
- /* the "compressed" part */
- if (!got_pointer)
- ret += m + 2;
- offset++;
- while (m > 0) {
- unsigned char c1,c2;
- c1 = ubuf[offset++]-'A';
- c2 = ubuf[offset++]-'A';
- if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
- return(0);
- name->name[n++] = (c1<<4) | c2;
- m -= 2;
- }
- name->name[n] = 0;
-
- if (n==MAX_NETBIOSNAME_LEN) {
- /* parse out the name type, its always in the 16th byte of the name */
- name->name_type = ((unsigned char)name->name[15]) & 0xff;
+ m = ubuf[offset];
+
+ if (!m)
+ return(0);
+ if ((m & 0xC0) || offset+m+2 > length)
+ return(0);
+
+ memset((char *)name,'\0',sizeof(*name));
+
+ /* the "compressed" part */
+ if (!got_pointer)
+ ret += m + 2;
+ offset++;
+ while (m > 0) {
+ uchar c1,c2;
+ c1 = ubuf[offset++]-'A';
+ c2 = ubuf[offset++]-'A';
+ if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
+ return(0);
+ name->name[n++] = (c1<<4) | c2;
+ m -= 2;
+ }
+ name->name[n] = 0;
+
+ if (n==16) {
+ /* parse out the name type,
+ its always in the 16th byte of the name */
+ name->name_type = ((uchar)name->name[15]) & 0xff;
- /* remove trailing spaces */
- name->name[15] = 0;
- n = 14;
- while (n && name->name[n]==' ')
- name->name[n--] = 0;
- }
-
- /* now the domain parts (if any) */
- n = 0;
- while (ubuf[offset]) {
- /* we can have pointers within the domain part as well */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
- return(0);
-
- m = ubuf[offset];
- /*
- * Don't allow null domain parts.
- */
- if (!m)
- return(0);
- if (!got_pointer)
- ret += m+1;
- if (n)
- name->scope[n++] = '.';
- if (m+2+offset>length || n+m+1>sizeof(name->scope))
- return(0);
- offset++;
- while (m--)
- name->scope[n++] = (char)ubuf[offset++];
-
- /*
- * Watch for malicious loops.
- */
- if (loop_count++ == 10)
- return 0;
- }
- name->scope[n++] = 0;
-
- return(ret);
+ /* remove trailing spaces */
+ name->name[15] = 0;
+ n = 14;
+ while (n && name->name[n]==' ')
+ name->name[n--] = 0;
+ }
+
+ /* now the domain parts (if any) */
+ n = 0;
+ while (ubuf[offset]) {
+ /* we can have pointers within the domain part as well */
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
+
+ m = ubuf[offset];
+ /*
+ * Don't allow null domain parts.
+ */
+ if (!m)
+ return(0);
+ if (!got_pointer)
+ ret += m+1;
+ if (n)
+ name->scope[n++] = '.';
+ if (m+2+offset>length || n+m+1>sizeof(name->scope))
+ return(0);
+ offset++;
+ while (m--)
+ name->scope[n++] = (char)ubuf[offset++];
+
+ /*
+ * Watch for malicious loops.
+ */
+ if (loop_count++ == 10)
+ return 0;
+ }
+ name->scope[n++] = 0;
+
+ return(ret);
}
-/****************************************************************************
- Put a netbios name, padding(s) and a name type into a 16 character buffer.
- name is already in DOS charset.
- [15 bytes name + padding][1 byte name type].
-****************************************************************************/
-
-static void put_name(char *dest, const char *name, int pad, unsigned int name_type)
-{
- size_t len = strlen(name);
-
- memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
- if (len < MAX_NETBIOSNAME_LEN - 1) {
- memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
- }
- dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
-}
/*******************************************************************
- Put a compressed nmb name into a buffer. Return the length of the
- compressed name.
-
- Compressed names are really weird. The "compression" doubles the
- size. The idea is that it also means that compressed names conform
- to the doman name system. See RFC1002.
-******************************************************************/
+ put a compressed nmb name into a buffer. return the length of the
+ compressed name
+ compressed names are really weird. The "compression" doubles the
+ size. The idea is that it also means that compressed names conform
+ to the doman name system. See RFC1002.
+ ******************************************************************/
static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
{
- int ret,m;
- nstring buf1;
- char *p;
-
- if (strcmp(name->name,"*") == 0) {
- /* special case for wildcard name */
- put_name(buf1, "*", '\0', name->name_type);
- } else {
- put_name(buf1, name->name, ' ', name->name_type);
- }
-
- buf[offset] = 0x20;
-
- ret = 34;
-
- for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
- buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
- buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
- }
- offset += 33;
-
- buf[offset] = 0;
-
- if (name->scope[0]) {
- /* XXXX this scope handling needs testing */
- ret += strlen(name->scope) + 1;
- safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
+ int ret,m;
+ fstring buf1;
+ char *p;
+
+ if (strcmp(name->name,"*") == 0) {
+ /* special case for wildcard name */
+ memset(buf1,'\0',20);
+ buf1[0] = '*';
+ buf1[15] = name->name_type;
+ } else {
+ slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
+ }
+
+ buf[offset] = 0x20;
+
+ ret = 34;
+
+ for (m=0;m<16;m++) {
+ buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
+ buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
+ }
+ offset += 33;
+
+ buf[offset] = 0;
+
+ if (name->scope[0]) {
+ /* XXXX this scope handling needs testing */
+ ret += strlen(name->scope) + 1;
+ pstrcpy(&buf[offset+1],name->scope);
- p = &buf[offset+1];
- while ((p = strchr_m(p,'.'))) {
- buf[offset] = PTR_DIFF(p,&buf[offset+1]);
- offset += (buf[offset] + 1);
- p = &buf[offset+1];
- }
- buf[offset] = strlen(&buf[offset+1]);
- }
-
- return(ret);
+ p = &buf[offset+1];
+ while ((p = strchr(p,'.'))) {
+ buf[offset] = PTR_DIFF(p,&buf[offset+1]);
+ offset += (buf[offset] + 1);
+ p = &buf[offset+1];
+ }
+ buf[offset] = strlen(&buf[offset+1]);
+ }
+
+ return(ret);
}
/*******************************************************************
- Useful for debugging messages.
-******************************************************************/
-
+ useful for debugging messages
+ ******************************************************************/
char *nmb_namestr(struct nmb_name *n)
{
- static int i=0;
- static fstring ret[4];
- fstring name;
- char *p = ret[i];
-
- pull_ascii_fstring(name, n->name);
- if (!n->scope[0])
- slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
- else
- slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
-
- i = (i+1)%4;
- return(p);
+ static int i=0;
+ static fstring ret[4];
+ char *p = ret[i];
+
+ if (!n->scope[0])
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
+ else
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
+
+ i = (i+1)%4;
+ return(p);
}
/*******************************************************************
- Allocate and parse some resource records.
-******************************************************************/
-
+ allocate and parse some resource records
+ ******************************************************************/
static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
struct res_rec **recs, int count)
{
- int i;
-
- *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
- if (!*recs)
- return(False);
-
- memset((char *)*recs,'\0',sizeof(**recs)*count);
-
- for (i=0;i<count;i++) {
- int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
- (*offset) += l;
- if (!l || (*offset)+10 > length) {
- SAFE_FREE(*recs);
- return(False);
- }
- (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
- (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
- (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
- (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
- (*offset) += 10;
- if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
- (*offset)+(*recs)[i].rdlength > length) {
- SAFE_FREE(*recs);
- return(False);
- }
- memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
- (*offset) += (*recs)[i].rdlength;
- }
- return(True);
+ int i;
+ *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
+ if (!*recs) return(False);
+
+ memset((char *)*recs,'\0',sizeof(**recs)*count);
+
+ for (i=0;i<count;i++) {
+ int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
+ (*offset) += l;
+ if (!l || (*offset)+10 > length) {
+ SAFE_FREE(*recs);
+ return(False);
+ }
+ (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
+ (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
+ (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
+ (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
+ (*offset) += 10;
+ if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
+ (*offset)+(*recs)[i].rdlength > length) {
+ SAFE_FREE(*recs);
+ return(False);
+ }
+ memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
+ (*offset) += (*recs)[i].rdlength;
+ }
+ return(True);
}
/*******************************************************************
- Put a resource record into a packet.
-******************************************************************/
-
+ put a resource record into a packet
+ ******************************************************************/
static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
{
- int ret=0;
- int i;
-
- for (i=0;i<count;i++) {
- int l = put_nmb_name(buf,offset,&recs[i].rr_name);
- offset += l;
- ret += l;
- RSSVAL(buf,offset,recs[i].rr_type);
- RSSVAL(buf,offset+2,recs[i].rr_class);
- RSIVAL(buf,offset+4,recs[i].ttl);
- RSSVAL(buf,offset+8,recs[i].rdlength);
- memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
- offset += 10+recs[i].rdlength;
- ret += 10+recs[i].rdlength;
- }
-
- return(ret);
+ int ret=0;
+ int i;
+
+ for (i=0;i<count;i++) {
+ int l = put_nmb_name(buf,offset,&recs[i].rr_name);
+ offset += l;
+ ret += l;
+ RSSVAL(buf,offset,recs[i].rr_type);
+ RSSVAL(buf,offset+2,recs[i].rr_class);
+ RSIVAL(buf,offset+4,recs[i].ttl);
+ RSSVAL(buf,offset+8,recs[i].rdlength);
+ memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
+ offset += 10+recs[i].rdlength;
+ ret += 10+recs[i].rdlength;
+ }
+
+ return(ret);
}
/*******************************************************************
- Put a compressed name pointer record into a packet.
-******************************************************************/
-
-static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
+ put a compressed name pointer record into a packet
+ ******************************************************************/
+static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
{
- int ret=0;
- buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
- buf[offset+1] = (ptr_offset & 0xFF);
- offset += 2;
- ret += 2;
- RSSVAL(buf,offset,rec->rr_type);
- RSSVAL(buf,offset+2,rec->rr_class);
- RSIVAL(buf,offset+4,rec->ttl);
- RSSVAL(buf,offset+8,rec->rdlength);
- memcpy(buf+offset+10,rec->rdata,rec->rdlength);
- offset += 10+rec->rdlength;
- ret += 10+rec->rdlength;
+ int ret=0;
+ buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
+ buf[offset+1] = (ptr_offset & 0xFF);
+ offset += 2;
+ ret += 2;
+ RSSVAL(buf,offset,rec->rr_type);
+ RSSVAL(buf,offset+2,rec->rr_class);
+ RSIVAL(buf,offset+4,rec->ttl);
+ RSSVAL(buf,offset+8,rec->rdlength);
+ memcpy(buf+offset+10,rec->rdata,rec->rdlength);
+ offset += 10+rec->rdlength;
+ ret += 10+rec->rdlength;
- return(ret);
+ return(ret);
}
/*******************************************************************
- Parse a dgram packet. Return False if the packet can't be parsed
- or is invalid for some reason, True otherwise.
-
- This is documented in section 4.4.1 of RFC1002.
-******************************************************************/
+ parse a dgram packet. Return False if the packet can't be parsed
+ or is invalid for some reason, True otherwise
+ this is documented in section 4.4.1 of RFC1002
+ ******************************************************************/
static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
{
- int offset;
- int flags;
-
- memset((char *)dgram,'\0',sizeof(*dgram));
-
- if (length < 14)
- return(False);
-
- dgram->header.msg_type = CVAL(inbuf,0);
- flags = CVAL(inbuf,1);
- dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
- if (flags & 1)
- dgram->header.flags.more = True;
- if (flags & 2)
- dgram->header.flags.first = True;
- dgram->header.dgm_id = RSVAL(inbuf,2);
- putip((char *)&dgram->header.source_ip,inbuf+4);
- dgram->header.source_port = RSVAL(inbuf,8);
- dgram->header.dgm_length = RSVAL(inbuf,10);
- dgram->header.packet_offset = RSVAL(inbuf,12);
-
- offset = 14;
-
- if (dgram->header.msg_type == 0x10 ||
- dgram->header.msg_type == 0x11 ||
- dgram->header.msg_type == 0x12) {
- offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
- offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
- }
+ int offset;
+ int flags;
+
+ memset((char *)dgram,'\0',sizeof(*dgram));
+
+ if (length < 14) return(False);
+
+ dgram->header.msg_type = CVAL(inbuf,0);
+ flags = CVAL(inbuf,1);
+ dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
+ if (flags & 1) dgram->header.flags.more = True;
+ if (flags & 2) dgram->header.flags.first = True;
+ dgram->header.dgm_id = RSVAL(inbuf,2);
+ putip((char *)&dgram->header.source_ip,inbuf+4);
+ dgram->header.source_port = RSVAL(inbuf,8);
+ dgram->header.dgm_length = RSVAL(inbuf,10);
+ dgram->header.packet_offset = RSVAL(inbuf,12);
+
+ offset = 14;
+
+ if (dgram->header.msg_type == 0x10 ||
+ dgram->header.msg_type == 0x11 ||
+ dgram->header.msg_type == 0x12) {
+ offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
+ offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
+ }
- if (offset >= length || (length-offset > sizeof(dgram->data)))
- return(False);
+ if (offset >= length || (length-offset > sizeof(dgram->data)))
+ return(False);
- dgram->datasize = length-offset;
- memcpy(dgram->data,inbuf+offset,dgram->datasize);
+ dgram->datasize = length-offset;
+ memcpy(dgram->data,inbuf+offset,dgram->datasize);
- return(True);
+ return(True);
}
-/*******************************************************************
- Parse a nmb packet. Return False if the packet can't be parsed
- or is invalid for some reason, True otherwise.
-******************************************************************/
+/*******************************************************************
+ parse a nmb packet. Return False if the packet can't be parsed
+ or is invalid for some reason, True otherwise
+ ******************************************************************/
static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
{
- int nm_flags,offset;
-
- memset((char *)nmb,'\0',sizeof(*nmb));
-
- if (length < 12)
- return(False);
-
- /* parse the header */
- nmb->header.name_trn_id = RSVAL(inbuf,0);
-
- DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
-
- nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
- nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
- nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
- nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
- nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
- nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
- nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
- nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
- nmb->header.rcode = CVAL(inbuf,3) & 0xF;
- nmb->header.qdcount = RSVAL(inbuf,4);
- nmb->header.ancount = RSVAL(inbuf,6);
- nmb->header.nscount = RSVAL(inbuf,8);
- nmb->header.arcount = RSVAL(inbuf,10);
+ int nm_flags,offset;
+
+ memset((char *)nmb,'\0',sizeof(*nmb));
+
+ if (length < 12) return(False);
+
+ /* parse the header */
+ nmb->header.name_trn_id = RSVAL(inbuf,0);
+
+ DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
+
+ nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
+ nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
+ nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
+ nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
+ nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
+ nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
+ nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
+ nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
+ nmb->header.rcode = CVAL(inbuf,3) & 0xF;
+ nmb->header.qdcount = RSVAL(inbuf,4);
+ nmb->header.ancount = RSVAL(inbuf,6);
+ nmb->header.nscount = RSVAL(inbuf,8);
+ nmb->header.arcount = RSVAL(inbuf,10);
- if (nmb->header.qdcount) {
- offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
- if (!offset)
- return(False);
-
- if (length - (12+offset) < 4)
- return(False);
- nmb->question.question_type = RSVAL(inbuf,12+offset);
- nmb->question.question_class = RSVAL(inbuf,12+offset+2);
-
- offset += 12+4;
- } else {
- offset = 12;
- }
-
- /* and any resource records */
- if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
- nmb->header.ancount))
- return(False);
-
- if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
- nmb->header.nscount))
- return(False);
+ if (nmb->header.qdcount) {
+ offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
+ if (!offset) return(False);
+
+ if (length - (12+offset) < 4) return(False);
+ nmb->question.question_type = RSVAL(inbuf,12+offset);
+ nmb->question.question_class = RSVAL(inbuf,12+offset+2);
+
+ offset += 12+4;
+ } else {
+ offset = 12;
+ }
+
+ /* and any resource records */
+ if (nmb->header.ancount &&
+ !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
+ nmb->header.ancount))
+ return(False);
+
+ if (nmb->header.nscount &&
+ !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
+ nmb->header.nscount))
+ return(False);
- if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
- nmb->header.arcount))
- return(False);
+ if (nmb->header.arcount &&
+ !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
+ nmb->header.arcount))
+ return(False);
- return(True);
+ return(True);
}
/*******************************************************************
- 'Copy constructor' for an nmb packet.
-******************************************************************/
-
+ 'Copy constructor' for an nmb packet
+ ******************************************************************/
static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
{
- struct nmb_packet *nmb;
- struct nmb_packet *copy_nmb;
- struct packet_struct *pkt_copy;
-
- if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
- DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
- return NULL;
- }
-
- /* Structure copy of entire thing. */
-
- *pkt_copy = *packet;
-
- /* Ensure this copy is not locked. */
- pkt_copy->locked = False;
-
- /* Ensure this copy has no resource records. */
- nmb = &packet->packet.nmb;
- copy_nmb = &pkt_copy->packet.nmb;
-
- copy_nmb->answers = NULL;
- copy_nmb->nsrecs = NULL;
- copy_nmb->additional = NULL;
-
- /* Now copy any resource records. */
-
- if (nmb->answers) {
- if((copy_nmb->answers = (struct res_rec *)
- malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
- goto free_and_exit;
- memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
- nmb->header.ancount * sizeof(struct res_rec));
- }
- if (nmb->nsrecs) {
- if((copy_nmb->nsrecs = (struct res_rec *)
- malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
- goto free_and_exit;
- memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
- nmb->header.nscount * sizeof(struct res_rec));
- }
- if (nmb->additional) {
- if((copy_nmb->additional = (struct res_rec *)
- malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
- goto free_and_exit;
- memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
- nmb->header.arcount * sizeof(struct res_rec));
- }
-
- return pkt_copy;
-
- free_and_exit:
-
- SAFE_FREE(copy_nmb->answers);
- SAFE_FREE(copy_nmb->nsrecs);
- SAFE_FREE(copy_nmb->additional);
- SAFE_FREE(pkt_copy);
-
- DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
- return NULL;
+ struct nmb_packet *nmb;
+ struct nmb_packet *copy_nmb;
+ struct packet_struct *pkt_copy;
+
+ if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
+ {
+ DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
+ return NULL;
+ }
+
+ /* Structure copy of entire thing. */
+
+ *pkt_copy = *packet;
+
+ /* Ensure this copy is not locked. */
+ pkt_copy->locked = False;
+
+ /* Ensure this copy has no resource records. */
+ nmb = &packet->packet.nmb;
+ copy_nmb = &pkt_copy->packet.nmb;
+
+ copy_nmb->answers = NULL;
+ copy_nmb->nsrecs = NULL;
+ copy_nmb->additional = NULL;
+
+ /* Now copy any resource records. */
+
+ if (nmb->answers)
+ {
+ if((copy_nmb->answers = (struct res_rec *)
+ malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
+ goto free_and_exit;
+ memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
+ nmb->header.ancount * sizeof(struct res_rec));
+ }
+ if (nmb->nsrecs)
+ {
+ if((copy_nmb->nsrecs = (struct res_rec *)
+ malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
+ goto free_and_exit;
+ memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
+ nmb->header.nscount * sizeof(struct res_rec));
+ }
+ if (nmb->additional)
+ {
+ if((copy_nmb->additional = (struct res_rec *)
+ malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
+ goto free_and_exit;
+ memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
+ nmb->header.arcount * sizeof(struct res_rec));
+ }
+
+ return pkt_copy;
+
+free_and_exit:
+
+ SAFE_FREE(copy_nmb->answers);
+ SAFE_FREE(copy_nmb->nsrecs);
+ SAFE_FREE(copy_nmb->additional);
+ SAFE_FREE(pkt_copy);
+
+ DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
+ return NULL;
}
/*******************************************************************
- 'Copy constructor' for a dgram packet.
-******************************************************************/
-
+ 'Copy constructor' for a dgram packet
+ ******************************************************************/
static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
{
- struct packet_struct *pkt_copy;
+ struct packet_struct *pkt_copy;
- if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
- DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
- return NULL;
- }
+ if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
+ {
+ DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
+ return NULL;
+ }
- /* Structure copy of entire thing. */
+ /* Structure copy of entire thing. */
- *pkt_copy = *packet;
+ *pkt_copy = *packet;
- /* Ensure this copy is not locked. */
- pkt_copy->locked = False;
+ /* Ensure this copy is not locked. */
+ pkt_copy->locked = False;
- /* There are no additional pointers in a dgram packet,
- we are finished. */
- return pkt_copy;
+ /* There are no additional pointers in a dgram packet,
+ we are finished. */
+ return pkt_copy;
}
/*******************************************************************
- 'Copy constructor' for a generic packet.
-******************************************************************/
-
+ 'Copy constructor' for a generic packet
+ ******************************************************************/
struct packet_struct *copy_packet(struct packet_struct *packet)
{
- if(packet->packet_type == NMB_PACKET)
- return copy_nmb_packet(packet);
- else if (packet->packet_type == DGRAM_PACKET)
- return copy_dgram_packet(packet);
- return NULL;
+ if(packet->packet_type == NMB_PACKET)
+ return copy_nmb_packet(packet);
+ else if (packet->packet_type == DGRAM_PACKET)
+ return copy_dgram_packet(packet);
+ return NULL;
}
/*******************************************************************
- Free up any resources associated with an nmb packet.
-******************************************************************/
-
+ free up any resources associated with an nmb packet
+ ******************************************************************/
static void free_nmb_packet(struct nmb_packet *nmb)
{
- SAFE_FREE(nmb->answers);
- SAFE_FREE(nmb->nsrecs);
- SAFE_FREE(nmb->additional);
+ SAFE_FREE(nmb->answers);
+ SAFE_FREE(nmb->nsrecs);
+ SAFE_FREE(nmb->additional);
}
/*******************************************************************
- Free up any resources associated with a dgram packet.
-******************************************************************/
-
+ free up any resources associated with a dgram packet
+ ******************************************************************/
static void free_dgram_packet(struct dgram_packet *nmb)
{
- /* We have nothing to do for a dgram packet. */
+ /* We have nothing to do for a dgram packet. */
}
/*******************************************************************
- Free up any resources associated with a packet.
-******************************************************************/
-
+ free up any resources associated with a packet
+ ******************************************************************/
void free_packet(struct packet_struct *packet)
{
- if (packet->locked)
- return;
- if (packet->packet_type == NMB_PACKET)
- free_nmb_packet(&packet->packet.nmb);
- else if (packet->packet_type == DGRAM_PACKET)
- free_dgram_packet(&packet->packet.dgram);
- ZERO_STRUCTPN(packet);
- SAFE_FREE(packet);
+ if (packet->locked)
+ return;
+ if (packet->packet_type == NMB_PACKET)
+ free_nmb_packet(&packet->packet.nmb);
+ else if (packet->packet_type == DGRAM_PACKET)
+ free_dgram_packet(&packet->packet.dgram);
+ ZERO_STRUCTPN(packet);
+ SAFE_FREE(packet);
}
/*******************************************************************
- Parse a packet buffer into a packet structure.
-******************************************************************/
-
+parse a packet buffer into a packet structure
+ ******************************************************************/
struct packet_struct *parse_packet(char *buf,int length,
enum packet_type packet_type)
{
@@ -696,8 +668,7 @@ struct packet_struct *parse_packet(char *buf,int length,
BOOL ok=False;
p = (struct packet_struct *)malloc(sizeof(*p));
- if (!p)
- return(NULL);
+ if (!p) return(NULL);
p->next = NULL;
p->prev = NULL;
@@ -726,10 +697,9 @@ struct packet_struct *parse_packet(char *buf,int length,
}
/*******************************************************************
- Read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket.
-******************************************************************/
-
+ read a packet from a socket and parse it, returning a packet ready
+ to be used or put on the queue. This assumes a UDP socket
+ ******************************************************************/
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
{
struct packet_struct *packet;
@@ -737,12 +707,10 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
int length;
length = read_udp_socket(fd,buf,sizeof(buf));
- if (length < MIN_DGRAM_SIZE)
- return(NULL);
+ if (length < MIN_DGRAM_SIZE) return(NULL);
packet = parse_packet(buf, length, packet_type);
- if (!packet)
- return NULL;
+ if (!packet) return NULL;
packet->fd = fd;
@@ -754,211 +722,203 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
return(packet);
}
-/*******************************************************************
- Send a udp packet on a already open socket.
-******************************************************************/
+/*******************************************************************
+ send a udp packet on a already open socket
+ ******************************************************************/
static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
{
- BOOL ret = False;
- int i;
- struct sockaddr_in sock_out;
-
- /* set the address and port */
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)&ip);
- sock_out.sin_port = htons( port );
- sock_out.sin_family = AF_INET;
+ BOOL ret = False;
+ int i;
+ struct sockaddr_in sock_out;
+
+ /* set the address and port */
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
+ putip((char *)&sock_out.sin_addr,(char *)&ip);
+ sock_out.sin_port = htons( port );
+ sock_out.sin_family = AF_INET;
- DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
- len, inet_ntoa(ip), port ) );
+ DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
+ len, inet_ntoa(ip), port ) );
- /*
- * Patch to fix asynch error notifications from Linux kernel.
- */
+ /*
+ * Patch to fix asynch error notifications from Linux kernel.
+ */
- for (i = 0; i < 5; i++) {
- ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
- if (ret || errno != ECONNREFUSED)
- break;
- }
+ for (i = 0; i < 5; i++) {
+ ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
+ if (ret || errno != ECONNREFUSED)
+ break;
+ }
- if (!ret)
- DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
- inet_ntoa(ip),port,strerror(errno)));
+ if (!ret)
+ DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
+ inet_ntoa(ip),port,strerror(errno)));
- if (ret)
- num_good_sends++;
+ if (ret)
+ num_good_sends++;
- return(ret);
+ return(ret);
}
/*******************************************************************
- Build a dgram packet ready for sending.
-
- XXXX This currently doesn't handle packets too big for one
- datagram. It should split them and use the packet_offset, more and
- first flags to handle the fragmentation. Yuck.
+ build a dgram packet ready for sending
- [...but it isn't clear that we would ever need to send a
- a fragmented NBT Datagram. The IP layer does its own
- fragmentation to ensure that messages can fit into the path
- MTU. It *is* important to be able to receive and rebuild
- fragmented NBT datagrams, just in case someone out there
- really has implemented this 'feature'. crh -)------ ]
+ XXXX This currently doesn't handle packets too big for one
+ datagram. It should split them and use the packet_offset, more and
+ first flags to handle the fragmentation. Yuck.
-******************************************************************/
+ [...but it isn't clear that we would ever need to send a
+ a fragmented NBT Datagram. The IP layer does its own
+ fragmentation to ensure that messages can fit into the path
+ MTU. It *is* important to be able to receive and rebuild
+ fragmented NBT datagrams, just in case someone out there
+ really has implemented this 'feature'. crh -)------ ]
+ ******************************************************************/
static int build_dgram(char *buf,struct packet_struct *p)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- unsigned char *ubuf = (unsigned char *)buf;
- int offset=0;
-
- /* put in the header */
- ubuf[0] = dgram->header.msg_type;
- ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
- if (dgram->header.flags.more)
- ubuf[1] |= 1;
- if (dgram->header.flags.first)
- ubuf[1] |= 2;
- RSSVAL(ubuf,2,dgram->header.dgm_id);
- putip(ubuf+4,(char *)&dgram->header.source_ip);
- RSSVAL(ubuf,8,dgram->header.source_port);
- RSSVAL(ubuf,12,dgram->header.packet_offset);
-
- offset = 14;
-
- if (dgram->header.msg_type == 0x10 ||
- dgram->header.msg_type == 0x11 ||
- dgram->header.msg_type == 0x12) {
- offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
- offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
- }
-
- memcpy(ubuf+offset,dgram->data,dgram->datasize);
- offset += dgram->datasize;
-
- /* automatically set the dgm_length
- * NOTE: RFC1002 says the dgm_length does *not*
- * include the fourteen-byte header. crh
- */
- dgram->header.dgm_length = (offset - 14);
- RSSVAL(ubuf,10,dgram->header.dgm_length);
-
- return(offset);
+ struct dgram_packet *dgram = &p->packet.dgram;
+ uchar *ubuf = (uchar *)buf;
+ int offset=0;
+
+ /* put in the header */
+ ubuf[0] = dgram->header.msg_type;
+ ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
+ if (dgram->header.flags.more)
+ ubuf[1] |= 1;
+ if (dgram->header.flags.first)
+ ubuf[1] |= 2;
+ RSSVAL(ubuf,2,dgram->header.dgm_id);
+ putip(ubuf+4,(char *)&dgram->header.source_ip);
+ RSSVAL(ubuf,8,dgram->header.source_port);
+ RSSVAL(ubuf,12,dgram->header.packet_offset);
+
+ offset = 14;
+
+ if (dgram->header.msg_type == 0x10 ||
+ dgram->header.msg_type == 0x11 ||
+ dgram->header.msg_type == 0x12) {
+ offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
+ offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
+ }
+
+ memcpy(ubuf+offset,dgram->data,dgram->datasize);
+ offset += dgram->datasize;
+
+ /* automatically set the dgm_length
+ * NOTE: RFC1002 says the dgm_length does *not*
+ * include the fourteen-byte header. crh
+ */
+ dgram->header.dgm_length = (offset - 14);
+ RSSVAL(ubuf,10,dgram->header.dgm_length);
+
+ return(offset);
}
/*******************************************************************
- Build a nmb name
-*******************************************************************/
-
+ build a nmb name
+ *******************************************************************/
void make_nmb_name( struct nmb_name *n, const char *name, int type)
{
- fstring unix_name;
+ extern pstring global_scope;
memset( (char *)n, '\0', sizeof(struct nmb_name) );
- fstrcpy(unix_name, name);
- strupper_m(unix_name);
- push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
+ StrnCpy( n->name, name, 15 );
+ unix_to_dos(n->name);
+ strupper( n->name );
n->name_type = (unsigned int)type & 0xFF;
- push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
+ StrnCpy( n->scope, global_scope, 63 );
+ strupper( n->scope );
}
/*******************************************************************
Compare two nmb names
-******************************************************************/
+ ******************************************************************/
BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
{
- return ((n1->name_type == n2->name_type) &&
- strequal(n1->name ,n2->name ) &&
- strequal(n1->scope,n2->scope));
+ return ((n1->name_type == n2->name_type) &&
+ strequal(n1->name ,n2->name ) &&
+ strequal(n1->scope,n2->scope));
}
/*******************************************************************
- Build a nmb packet ready for sending.
-
- XXXX this currently relies on not being passed something that expands
- to a packet too big for the buffer. Eventually this should be
- changed to set the trunc bit so the receiver can request the rest
- via tcp (when that becomes supported)
-******************************************************************/
+ build a nmb packet ready for sending
+ XXXX this currently relies on not being passed something that expands
+ to a packet too big for the buffer. Eventually this should be
+ changed to set the trunc bit so the receiver can request the rest
+ via tcp (when that becomes supported)
+ ******************************************************************/
static int build_nmb(char *buf,struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char *ubuf = (unsigned char *)buf;
- int offset=0;
-
- /* put in the header */
- RSSVAL(ubuf,offset,nmb->header.name_trn_id);
- ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.response)
- ubuf[offset+2] |= (1<<7);
- if (nmb->header.nm_flags.authoritative &&
- nmb->header.response)
- ubuf[offset+2] |= 0x4;
- if (nmb->header.nm_flags.trunc)
- ubuf[offset+2] |= 0x2;
- if (nmb->header.nm_flags.recursion_desired)
- ubuf[offset+2] |= 0x1;
- if (nmb->header.nm_flags.recursion_available &&
- nmb->header.response)
- ubuf[offset+3] |= 0x80;
- if (nmb->header.nm_flags.bcast)
- ubuf[offset+3] |= 0x10;
- ubuf[offset+3] |= (nmb->header.rcode & 0xF);
-
- RSSVAL(ubuf,offset+4,nmb->header.qdcount);
- RSSVAL(ubuf,offset+6,nmb->header.ancount);
- RSSVAL(ubuf,offset+8,nmb->header.nscount);
- RSSVAL(ubuf,offset+10,nmb->header.arcount);
+ struct nmb_packet *nmb = &p->packet.nmb;
+ uchar *ubuf = (uchar *)buf;
+ int offset=0;
+
+ /* put in the header */
+ RSSVAL(ubuf,offset,nmb->header.name_trn_id);
+ ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
+ if (nmb->header.response) ubuf[offset+2] |= (1<<7);
+ if (nmb->header.nm_flags.authoritative &&
+ nmb->header.response) ubuf[offset+2] |= 0x4;
+ if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
+ if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
+ if (nmb->header.nm_flags.recursion_available &&
+ nmb->header.response) ubuf[offset+3] |= 0x80;
+ if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
+ ubuf[offset+3] |= (nmb->header.rcode & 0xF);
+
+ RSSVAL(ubuf,offset+4,nmb->header.qdcount);
+ RSSVAL(ubuf,offset+6,nmb->header.ancount);
+ RSSVAL(ubuf,offset+8,nmb->header.nscount);
+ RSSVAL(ubuf,offset+10,nmb->header.arcount);
- offset += 12;
- if (nmb->header.qdcount) {
- /* XXXX this doesn't handle a qdcount of > 1 */
- offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
- RSSVAL(ubuf,offset,nmb->question.question_type);
- RSSVAL(ubuf,offset+2,nmb->question.question_class);
- offset += 4;
- }
-
- if (nmb->header.ancount)
- offset += put_res_rec((char *)ubuf,offset,nmb->answers,
- nmb->header.ancount);
-
- if (nmb->header.nscount)
- offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
- nmb->header.nscount);
-
- /*
- * The spec says we must put compressed name pointers
- * in the following outgoing packets :
- * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
- * NAME_RELEASE_REQUEST.
- */
-
- if((nmb->header.response == False) &&
- ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
- (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
- (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
- (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
- (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
- (nmb->header.arcount == 1)) {
-
- offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
-
- } else if (nmb->header.arcount) {
- offset += put_res_rec((char *)ubuf,offset,nmb->additional,
- nmb->header.arcount);
- }
- return(offset);
+ offset += 12;
+ if (nmb->header.qdcount) {
+ /* XXXX this doesn't handle a qdcount of > 1 */
+ offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
+ RSSVAL(ubuf,offset,nmb->question.question_type);
+ RSSVAL(ubuf,offset+2,nmb->question.question_class);
+ offset += 4;
+ }
+
+ if (nmb->header.ancount)
+ offset += put_res_rec((char *)ubuf,offset,nmb->answers,
+ nmb->header.ancount);
+
+ if (nmb->header.nscount)
+ offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
+ nmb->header.nscount);
+
+ /*
+ * The spec says we must put compressed name pointers
+ * in the following outgoing packets :
+ * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
+ * NAME_RELEASE_REQUEST.
+ */
+
+ if((nmb->header.response == False) &&
+ ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
+ (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
+ (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
+ (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
+ (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
+ (nmb->header.arcount == 1)) {
+
+ offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
+
+ } else if (nmb->header.arcount) {
+ offset += put_res_rec((char *)ubuf,offset,nmb->additional,
+ nmb->header.arcount);
+ }
+ return(offset);
}
-/*******************************************************************
- Linearise a packet.
-******************************************************************/
+/*******************************************************************
+linearise a packet
+ ******************************************************************/
int build_packet(char *buf, struct packet_struct *p)
{
int len = 0;
@@ -977,29 +937,26 @@ int build_packet(char *buf, struct packet_struct *p)
}
/*******************************************************************
- Send a packet_struct.
-******************************************************************/
-
+ send a packet_struct
+ ******************************************************************/
BOOL send_packet(struct packet_struct *p)
{
- char buf[1024];
- int len=0;
+ char buf[1024];
+ int len=0;
- memset(buf,'\0',sizeof(buf));
+ memset(buf,'\0',sizeof(buf));
- len = build_packet(buf, p);
+ len = build_packet(buf, p);
- if (!len)
- return(False);
+ if (!len) return(False);
- return(send_udp(p->fd,buf,len,p->ip,p->port));
+ return(send_udp(p->fd,buf,len,p->ip,p->port));
}
/****************************************************************************
- Receive a packet with timeout on a open UDP filedescriptor.
- The timeout is in milliseconds
-***************************************************************************/
-
+ receive a packet with timeout on a open UDP filedescriptor
+ The timeout is in milliseconds
+ ***************************************************************************/
struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
{
fd_set fds;
@@ -1026,12 +983,12 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
return(NULL);
}
-/****************************************************************************
- Receive a UDP/137 packet either via UDP or from the unexpected packet
- queue. The packet must be a reply packet and have the specified trn_id.
- The timeout is in milliseconds.
-***************************************************************************/
+/****************************************************************************
+ receive a UDP/137 packet either via UDP or from the unexpected packet
+ queue. The packet must be a reply packet and have the specified trn_id
+ The timeout is in milliseconds
+ ***************************************************************************/
struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
{
struct packet_struct *p;
@@ -1039,22 +996,20 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
p = receive_packet(fd, NMB_PACKET, t);
if (p && p->packet.nmb.header.response &&
- p->packet.nmb.header.name_trn_id == trn_id) {
+ p->packet.nmb.header.name_trn_id == trn_id) {
return p;
}
- if (p)
- free_packet(p);
+ if (p) free_packet(p);
/* try the unexpected packet queue */
return receive_unexpected(NMB_PACKET, trn_id, NULL);
}
/****************************************************************************
- Receive a UDP/138 packet either via UDP or from the unexpected packet
- queue. The packet must be a reply packet and have the specified mailslot name
- The timeout is in milliseconds.
-***************************************************************************/
-
+ receive a UDP/138 packet either via UDP or from the unexpected packet
+ queue. The packet must be a reply packet and have the specified mailslot name
+ The timeout is in milliseconds
+ ***************************************************************************/
struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
{
struct packet_struct *p;
@@ -1064,17 +1019,16 @@ struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_n
if (p && match_mailslot_name(p, mailslot_name)) {
return p;
}
- if (p)
- free_packet(p);
+ if (p) free_packet(p);
/* try the unexpected packet queue */
return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
}
+
/****************************************************************************
- See if a datagram has the right mailslot name.
+ see if a datagram has the right mailslot name
***************************************************************************/
-
BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
{
struct dgram_packet *dgram = &p->packet.dgram;
@@ -1092,76 +1046,71 @@ BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
return False;
}
-/****************************************************************************
- Return the number of bits that match between two 4 character buffers
-***************************************************************************/
-int matching_quad_bits(unsigned char *p1, unsigned char *p2)
+/****************************************************************************
+return the number of bits that match between two 4 character buffers
+ ***************************************************************************/
+static int matching_bits(uchar *p1, uchar *p2)
{
int i, j, ret = 0;
for (i=0; i<4; i++) {
- if (p1[i] != p2[i])
- break;
+ if (p1[i] != p2[i]) break;
ret += 8;
}
- if (i==4)
- return ret;
+ if (i==4) return ret;
for (j=0; j<8; j++) {
- if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
- break;
+ if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
ret++;
}
return ret;
}
-static unsigned char sort_ip[4];
-/****************************************************************************
- Compare two query reply records.
-***************************************************************************/
+static uchar sort_ip[4];
-static int name_query_comp(unsigned char *p1, unsigned char *p2)
+/****************************************************************************
+compare two query reply records
+ ***************************************************************************/
+static int name_query_comp(uchar *p1, uchar *p2)
{
- return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
+ return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
}
/****************************************************************************
- Sort a set of 6 byte name query response records so that the IPs that
- have the most leading bits in common with the specified address come first.
-***************************************************************************/
-
+sort a set of 6 byte name query response records so that the IPs that
+have the most leading bits in common with the specified address come first
+ ***************************************************************************/
void sort_query_replies(char *data, int n, struct in_addr ip)
{
- if (n <= 1)
- return;
+ if (n <= 1) return;
putip(sort_ip, (char *)&ip);
qsort(data, n, 6, QSORT_CAST name_query_comp);
}
+
#define TRUNCATE_NETBIOS_NAME 1
/*******************************************************************
- Convert, possibly using a stupid microsoft-ism which has destroyed
+ convert, possibly using a stupid microsoft-ism which has destroyed
the transport independence of netbios (for CIFS vendors that usually
use the Win95-type methods, not for NT to NT communication, which uses
DCE/RPC and therefore full-length unicode strings...) a dns name into
a netbios name.
- The netbios name (NOT necessarily null-terminated) is truncated to 15
+ the netbios name (NOT necessarily null-terminated) is truncated to 15
characters.
******************************************************************/
-
-char *dns_to_netbios_name(const char *dns_name)
+char *dns_to_netbios_name(char *dns_name)
{
- static nstring netbios_name;
+ static char netbios_name[16];
int i;
- StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1);
+ StrnCpy(netbios_name, dns_name, 15);
netbios_name[15] = 0;
#ifdef TRUNCATE_NETBIOS_NAME
@@ -1170,8 +1119,14 @@ char *dns_to_netbios_name(const char *dns_name)
netbios name up to and including the '.' this even applies, by
mistake, to workgroup (domain) names, which is _really_ daft.
*/
- for (i = 0; i >= 15; i--) {
- if (netbios_name[i] == '.') {
+ /*
+ * We need to go up, not down, to avoid netbios names like
+ * fred.xyz being produced from fred.xyz.someco.com.
+ */
+ for (i = 0; i < 15; i++)
+ {
+ if (netbios_name[i] == '.')
+ {
netbios_name[i] = 0;
break;
}
@@ -1181,152 +1136,143 @@ char *dns_to_netbios_name(const char *dns_name)
return netbios_name;
}
+
/****************************************************************************
- Interpret the weird netbios "name" into a unix fstring. Return the name type.
+interpret the weird netbios "name". Return the name type
****************************************************************************/
-
-static int name_interpret(char *in, fstring name)
+static int name_interpret(char *in,char *out)
{
- int ret;
- int len = (*in++) / 2;
- fstring out_string;
- char *out = out_string;
-
- *out=0;
-
- if (len > 30 || len<1)
- return(0);
-
- while (len--) {
- if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
- *out = 0;
- return(0);
- }
- *out = ((in[0]-'A')<<4) + (in[1]-'A');
- in += 2;
- out++;
- }
- ret = out[-1];
- out[-1] = 0;
+ int ret;
+ int len = (*in++) / 2;
+
+ *out=0;
+
+ if (len > 30 || len<1) return(0);
+
+ while (len--)
+ {
+ if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
+ *out = 0;
+ return(0);
+ }
+ *out = ((in[0]-'A')<<4) + (in[1]-'A');
+ in += 2;
+ out++;
+ }
+ *out = 0;
+ ret = out[-1];
#ifdef NETBIOS_SCOPE
- /* Handle any scope names */
- while(*in) {
- *out++ = '.'; /* Scope names are separated by periods */
- len = *(unsigned char *)in++;
- StrnCpy(out, in, len);
- out += len;
- *out=0;
- in += len;
- }
+ /* Handle any scope names */
+ while(*in)
+ {
+ *out++ = '.'; /* Scope names are separated by periods */
+ len = *(uchar *)in++;
+ StrnCpy(out, in, len);
+ out += len;
+ *out=0;
+ in += len;
+ }
#endif
- pull_ascii_fstring(name, out_string);
-
- return(ret);
+ return(ret);
}
/****************************************************************************
- Mangle a name into netbios format.
- Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
-****************************************************************************/
+mangle a name into netbios format
+ Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
+****************************************************************************/
int name_mangle( char *In, char *Out, char name_type )
-{
- int i;
- int len;
- nstring buf;
- char *p = Out;
-
- /* Safely copy the input string, In, into buf[]. */
- if (strcmp(In,"*") == 0)
- put_name(buf, "*", '\0', 0x00);
- else {
- /* We use an fstring here as mb dos names can expend x3 when
- going to utf8. */
- fstring buf_unix;
- nstring buf_dos;
-
- pull_ascii_fstring(buf_unix, In);
- strupper_m(buf_unix);
-
- push_ascii_nstring(buf_dos, buf_unix);
- put_name(buf, buf_dos, ' ', name_type);
- }
+ {
+ int i;
+ int c;
+ int len;
+ char buf[20];
+ char *p = Out;
+ extern pstring global_scope;
+
+ /* Safely copy the input string, In, into buf[]. */
+ (void)memset( buf, 0, 20 );
+ if (strcmp(In,"*") == 0)
+ buf[0] = '*';
+ else
+ (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
+
+ /* Place the length of the first field into the output buffer. */
+ p[0] = 32;
+ p++;
+
+ /* Now convert the name to the rfc1001/1002 format. */
+ for( i = 0; i < 16; i++ )
+ {
+ c = toupper( buf[i] );
+ p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
+ p[(i*2)+1] = (c & 0x000F) + 'A';
+ }
+ p += 32;
+ p[0] = '\0';
+
+ /* Add the scope string. */
+ for( i = 0, len = 0; NULL != global_scope; i++, len++ )
+ {
+ switch( global_scope[i] )
+ {
+ case '\0':
+ p[0] = len;
+ if( len > 0 )
+ p[len+1] = 0;
+ return( name_len(Out) );
+ case '.':
+ p[0] = len;
+ p += (len + 1);
+ len = -1;
+ break;
+ default:
+ p[len+1] = global_scope[i];
+ break;
+ }
+ }
+
+ return( name_len(Out) );
+ } /* name_mangle */
- /* Place the length of the first field into the output buffer. */
- p[0] = 32;
- p++;
-
- /* Now convert the name to the rfc1001/1002 format. */
- for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
- p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
- p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
- }
- p += 32;
- p[0] = '\0';
-
- /* Add the scope string. */
- for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
- switch( (global_scope())[i] ) {
- case '\0':
- p[0] = len;
- if( len > 0 )
- p[len+1] = 0;
- return( name_len(Out) );
- case '.':
- p[0] = len;
- p += (len + 1);
- len = -1;
- break;
- default:
- p[len+1] = (global_scope())[i];
- break;
- }
- }
-
- return( name_len(Out) );
-}
/****************************************************************************
- Find a pointer to a netbios name.
+find a pointer to a netbios name
****************************************************************************/
-
static char *name_ptr(char *buf,int ofs)
{
- unsigned char c = *(unsigned char *)(buf+ofs);
-
- if ((c & 0xC0) == 0xC0) {
- uint16 l = RSVAL(buf, ofs) & 0x3FFF;
- DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
- return(buf + l);
- } else {
- return(buf+ofs);
- }
+ uchar c = *(uchar *)(buf+ofs);
+
+ if ((c & 0xC0) == 0xC0)
+ {
+ uint16 l = RSVAL(buf, ofs) & 0x3FFF;
+ DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
+ return(buf + l);
+ }
+ else
+ return(buf+ofs);
}
/****************************************************************************
- Extract a netbios name from a buf (into a unix string) return name type.
+extract a netbios name from a buf
****************************************************************************/
-
-int name_extract(char *buf,int ofs, fstring name)
+int name_extract(char *buf,int ofs,char *name)
{
- char *p = name_ptr(buf,ofs);
- int d = PTR_DIFF(p,buf+ofs);
-
- name[0] = '\0';
- if (d < -50 || d > 50)
- return(0);
- return(name_interpret(p,name));
+ char *p = name_ptr(buf,ofs);
+ int d = PTR_DIFF(p,buf+ofs);
+ pstrcpy(name,"");
+ if (d < -50 || d > 50) return(0);
+ return(name_interpret(p,name));
}
/****************************************************************************
- Return the total storage length of a mangled name.
+return the total storage length of a mangled name
****************************************************************************/
-
int name_len(char *s1)
{
/* NOTE: this argument _must_ be unsigned */
- unsigned char *s = (unsigned char *)s1;
+ uchar *s = (uchar *)s1;
int len;
/* If the two high bits of the byte are set, return 2. */
@@ -1340,4 +1286,4 @@ int name_len(char *s1)
}
return(len);
-}
+} /* name_len */
diff --git a/source/libsmb/nterr.c b/source/libsmb/nterr.c
index b01451ea0fa..46f6e0ec265 100644
--- a/source/libsmb/nterr.c
+++ b/source/libsmb/nterr.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
*
@@ -28,7 +29,7 @@ typedef const struct
NTSTATUS nt_errcode;
} nt_err_code_struct;
-static nt_err_code_struct nt_errs[] =
+nt_err_code_struct nt_errs[] =
{
{ "NT_STATUS_OK", NT_STATUS_OK },
{ "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL },
@@ -533,116 +534,16 @@ static nt_err_code_struct nt_errs[] =
{ "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
{ "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
- { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT },
- { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES },
- { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
+ { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES },
{ "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
{ NULL, NT_STATUS(0) }
};
-nt_err_code_struct nt_err_desc[] =
-{
- { "Success", NT_STATUS_OK },
- { "Undetermined error", NT_STATUS_UNSUCCESSFUL },
- { "Access denied", NT_STATUS_ACCESS_DENIED },
- { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT },
- { "Must change password", NT_STATUS_PASSWORD_MUST_CHANGE },
- { "Password is too short", NT_STATUS_PWD_TOO_SHORT },
- { "Password is too recent", NT_STATUS_PWD_TOO_RECENT },
- { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT },
- { "No logon servers", NT_STATUS_NO_LOGON_SERVERS },
- { "Improperly formed account name", NT_STATUS_INVALID_ACCOUNT_NAME },
- { "User exists", NT_STATUS_USER_EXISTS },
- { "No such user", NT_STATUS_NO_SUCH_USER },
- { "Group exists", NT_STATUS_GROUP_EXISTS },
- { "No such group", NT_STATUS_NO_SUCH_GROUP },
- { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP },
- { "Wrong Password", NT_STATUS_WRONG_PASSWORD },
- { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD },
- { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION },
- { "Logon failure", NT_STATUS_LOGON_FAILURE },
- { "Account restriction", NT_STATUS_ACCOUNT_RESTRICTION },
- { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS },
- { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION },
- { "Password expired", NT_STATUS_PASSWORD_EXPIRED },
- { "Account disabled", NT_STATUS_ACCOUNT_DISABLED },
- { "Unexpected information received", NT_STATUS_INVALID_PARAMETER },
- { "Memory allocation error", NT_STATUS_NO_MEMORY },
- { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND },
- { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT },
- { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE },
- { "Not implemented", NT_STATUS_NOT_IMPLEMENTED },
- { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS },
- { "Information length mismatch", NT_STATUS_INFO_LENGTH_MISMATCH },
- { "Access violation", NT_STATUS_ACCESS_VIOLATION },
- { "Invalid handle", NT_STATUS_INVALID_HANDLE },
- { "Invalid parameter", NT_STATUS_INVALID_PARAMETER },
- { "No memory", NT_STATUS_NO_MEMORY },
- { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL },
- { "Revision mismatch", NT_STATUS_REVISION_MISMATCH },
- { "No logon servers", NT_STATUS_NO_LOGON_SERVERS },
- { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION },
- { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE },
- { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND },
- { "Server disabled", NT_STATUS_SERVER_DISABLED },
- { "Invalid pipe state", NT_STATUS_INVALID_PIPE_STATE },
- { "Named pipe busy", NT_STATUS_PIPE_BUSY },
- { "Illegal function", NT_STATUS_ILLEGAL_FUNCTION },
- { "Named pipe dicconnected", NT_STATUS_PIPE_DISCONNECTED },
- { "Named pipe closing", NT_STATUS_PIPE_CLOSING },
- { "Remote host not listening", NT_STATUS_REMOTE_NOT_LISTENING },
- { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME },
- { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL },
- { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE },
- { "Too many names", NT_STATUS_TOO_MANY_NAMES },
- { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS },
- { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE },
- { "Invalid domain state", NT_STATUS_INVALID_DOMAIN_STATE },
- { "Invalid domain role", NT_STATUS_INVALID_DOMAIN_ROLE },
- { "No such domain", NT_STATUS_NO_SUCH_DOMAIN },
- { "Domain exists", NT_STATUS_DOMAIN_EXISTS },
- { "Domain limit exceeded", NT_STATUS_DOMAIN_LIMIT_EXCEEDED },
- { "Bad logon session state", NT_STATUS_BAD_LOGON_SESSION_STATE },
- { "Logon session collision", NT_STATUS_LOGON_SESSION_COLLISION },
- { "Invalid logon type", NT_STATUS_INVALID_LOGON_TYPE },
- { "Cancelled", NT_STATUS_CANCELLED },
- { "Invalid computer name", NT_STATUS_INVALID_COMPUTER_NAME },
- { "Logon server conflict", NT_STATUS_LOGON_SERVER_CONFLICT },
- { "Time difference at domain controller", NT_STATUS_TIME_DIFFERENCE_AT_DC },
- { "Pipe broken", NT_STATUS_PIPE_BROKEN },
- { "Registry corrupt", NT_STATUS_REGISTRY_CORRUPT },
- { "Too many secrets", NT_STATUS_TOO_MANY_SECRETS },
- { "Too many SIDs", NT_STATUS_TOO_MANY_SIDS },
- { "Lanmanager cross encryption required", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED },
- { "Log file full", NT_STATUS_LOG_FILE_FULL },
- { "No trusted LSA secret", NT_STATUS_NO_TRUST_LSA_SECRET },
- { "No trusted SAM account", NT_STATUS_NO_TRUST_SAM_ACCOUNT },
- { "Trusted domain failure", NT_STATUS_TRUSTED_DOMAIN_FAILURE },
- { "Trust relationship failure", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE },
- { "Trust failure", NT_STATUS_TRUST_FAILURE },
- { "Netlogon service not started", NT_STATUS_NETLOGON_NOT_STARTED },
- { "Account expired", NT_STATUS_ACCOUNT_EXPIRED },
- { "Network credential conflict", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT },
- { "Remote session limit", NT_STATUS_REMOTE_SESSION_LIMIT },
- { "No logon interdomain trust account", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT },
- { "No logon workstation trust account", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT },
- { "No logon server trust account", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT },
- { "Domain trust inconsistent", NT_STATUS_DOMAIN_TRUST_INCONSISTENT },
- { "No user session key available", NT_STATUS_NO_USER_SESSION_KEY },
- { "User session deleted", NT_STATUS_USER_SESSION_DELETED },
- { "Insufficient server resources", NT_STATUS_INSUFF_SERVER_RESOURCES },
- { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO },
-
- { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED },
-
- { NULL, NT_STATUS(0) }
-};
-
-
/*****************************************************************************
returns an NT error message. not amazingly helpful, but better than a number.
*****************************************************************************/
-const char *nt_errstr(NTSTATUS nt_code)
+
+const char *get_nt_error_msg(NTSTATUS nt_code)
{
static pstring msg;
int idx = 0;
@@ -660,30 +561,15 @@ const char *nt_errstr(NTSTATUS nt_code)
return msg;
}
-/************************************************************************
- Print friendler version fo NT error code
- ***********************************************************************/
-
-const char *get_friendly_nt_error_msg(NTSTATUS nt_code)
+const char *nt_errstr(NTSTATUS nt_code)
{
- int idx = 0;
-
- while (nt_err_desc[idx].nt_errstr != NULL) {
- if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code))
- {
- return nt_err_desc[idx].nt_errstr;
- }
- idx++;
- }
-
- /* fall back to NT_STATUS_XXX string */
-
- return nt_errstr(nt_code);
+ return get_nt_error_msg(nt_code);
}
/*****************************************************************************
returns an NT_STATUS constant as a string for inclusion in autogen C code
*****************************************************************************/
+
const char *get_nt_error_c_code(NTSTATUS nt_code)
{
static pstring out;
@@ -701,47 +587,3 @@ const char *get_nt_error_c_code(NTSTATUS nt_code)
return out;
}
-
-/*****************************************************************************
- returns the NT_STATUS constant matching the string supplied (as an NTSTATUS)
- *****************************************************************************/
-NTSTATUS nt_status_string_to_code(char *nt_status_str)
-{
- int idx = 0;
-
- while (nt_errs[idx].nt_errstr != NULL) {
- if (strcmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) {
- return nt_errs[idx].nt_errcode;
- }
- idx++;
- }
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-
-/**
- * Squash an NT_STATUS in line with security requirements.
- * In an attempt to avoid giving the whole game away when users
- * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
- * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
- * (session setups in particular).
- *
- * @param nt_status NTSTATUS input for squashing.
- * @return the 'squashed' nt_status
- **/
-
-NTSTATUS nt_status_squash(NTSTATUS nt_status)
-{
- if NT_STATUS_IS_OK(nt_status) {
- return nt_status;
- } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
- /* Match WinXP and don't give the game away */
- return NT_STATUS_LOGON_FAILURE;
-
- } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
- /* Match WinXP and don't give the game away */
- return NT_STATUS_LOGON_FAILURE;
- } else {
- return nt_status;
- }
-}
diff --git a/source/libsmb/ntlm_check.c b/source/libsmb/ntlm_check.c
deleted file mode 100644
index 1d02b03e0c3..00000000000
--- a/source/libsmb/ntlm_check.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Andrew Bartlett 2001-2003
- Copyright (C) Gerald Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-/****************************************************************************
- Core of smb password checking routine.
-****************************************************************************/
-
-static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
- const uchar *part_passwd,
- const DATA_BLOB *sec_blob,
- DATA_BLOB *user_sess_key)
-{
- /* Finish the encryption of part_passwd. */
- uchar p24[24];
-
- if (part_passwd == NULL) {
- DEBUG(10,("No password set - DISALLOWING access\n"));
- /* No password set - always false ! */
- return False;
- }
-
- if (sec_blob->length != 8) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n",
- (unsigned long)sec_blob->length));
- return False;
- }
-
- if (nt_response->length != 24) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n",
- (unsigned long)nt_response->length));
- return False;
- }
-
- SMBOWFencrypt(part_passwd, sec_blob->data, p24);
- if (user_sess_key != NULL) {
- *user_sess_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data);
- }
-
-
-#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |\n"));
- dump_data(100, part_passwd, 16);
- DEBUGADD(100,("Password from client was |\n"));
- dump_data(100, nt_response->data, nt_response->length);
- DEBUGADD(100,("Given challenge was |\n"));
- dump_data(100, sec_blob->data, sec_blob->length);
- DEBUGADD(100,("Value from encryption was |\n"));
- dump_data(100, p24, 24);
-#endif
- return (memcmp(p24, nt_response->data, 24) == 0);
-}
-
-/****************************************************************************
- Core of smb password checking routine. (NTLMv2, LMv2)
- Note: The same code works with both NTLMv2 and LMv2.
-****************************************************************************/
-
-static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
- const uchar *part_passwd,
- const DATA_BLOB *sec_blob,
- const char *user, const char *domain,
- BOOL upper_case_domain, /* should the domain be transformed into upper case? */
- DATA_BLOB *user_sess_key)
-{
- /* Finish the encryption of part_passwd. */
- uchar kr[16];
- uchar value_from_encryption[16];
- uchar client_response[16];
- DATA_BLOB client_key_data;
-
- if (part_passwd == NULL) {
- DEBUG(10,("No password set - DISALLOWING access\n"));
- /* No password set - always False */
- return False;
- }
-
- if (sec_blob->length != 8) {
- DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n",
- (unsigned long)sec_blob->length));
- return False;
- }
-
- if (ntv2_response->length < 24) {
- /* We MUST have more than 16 bytes, or the stuff below will go
- crazy. No known implementation sends less than the 24 bytes
- for LMv2, let alone NTLMv2. */
- DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n",
- (unsigned long)ntv2_response->length));
- return False;
- }
-
- client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16);
- /*
- todo: should we be checking this for anything? We can't for LMv2,
- but for NTLMv2 it is meant to contain the current time etc.
- */
-
- memcpy(client_response, ntv2_response->data, sizeof(client_response));
-
- if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
- return False;
- }
-
- SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
- if (user_sess_key != NULL) {
- *user_sess_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
- }
-
-#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |\n"));
- dump_data(100, part_passwd, 16);
- DEBUGADD(100,("Password from client was |\n"));
- dump_data(100, ntv2_response->data, ntv2_response->length);
- DEBUGADD(100,("Variable data from client was |\n"));
- dump_data(100, client_key_data.data, client_key_data.length);
- DEBUGADD(100,("Given challenge was |\n"));
- dump_data(100, sec_blob->data, sec_blob->length);
- DEBUGADD(100,("Value from encryption was |\n"));
- dump_data(100, value_from_encryption, 16);
-#endif
- data_blob_clear_free(&client_key_data);
- return (memcmp(value_from_encryption, client_response, 16) == 0);
-}
-
-/**
- * Check a challenge-response password against the value of the NT or
- * LM password hash.
- *
- * @param mem_ctx talloc context
- * @param challenge 8-byte challenge. If all zero, forces plaintext comparison
- * @param nt_response 'unicode' NT response to the challenge, or unicode password
- * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page
- * @param username internal Samba username, for log messages
- * @param client_username username the client used
- * @param client_domain domain name the client used (may be mapped)
- * @param nt_pw MD4 unicode password from our passdb or similar
- * @param lm_pw LANMAN ASCII password from our passdb or similar
- * @param user_sess_key User session key
- * @param lm_sess_key LM session key (first 8 bytes of the LM hash)
- */
-
-NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
- const DATA_BLOB *challenge,
- const DATA_BLOB *lm_response,
- const DATA_BLOB *nt_response,
- const DATA_BLOB *lm_interactive_pwd,
- const DATA_BLOB *nt_interactive_pwd,
- const char *username,
- const char *client_username,
- const char *client_domain,
- const uint8 *lm_pw, const uint8 *nt_pw,
- DATA_BLOB *user_sess_key,
- DATA_BLOB *lm_sess_key)
-{
- static const unsigned char zeros[8];
- if (nt_pw == NULL) {
- DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n",
- username));
- }
-
- if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) {
- if (nt_interactive_pwd->length != 16) {
- DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length,
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) {
- if (user_sess_key) {
- *user_sess_key = data_blob(NULL, 16);
- SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data);
- }
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) {
- if (lm_interactive_pwd->length != 16) {
- DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length,
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- if (!lp_lanman_auth()) {
- DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) {
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
- }
-
- /* Check for cleartext netlogon. Used by Exchange 5.5. */
- if (challenge->length == sizeof(zeros) &&
- (memcmp(challenge->data, zeros, challenge->length) == 0 )) {
-
- DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n",
- username));
- if (nt_pw && nt_response->length) {
- unsigned char pwhash[16];
- mdfour(pwhash, nt_response->data, nt_response->length);
- if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) {
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- } else if (!lp_lanman_auth()) {
- DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n",
- username));
-
- } else if (lm_pw && lm_response->length) {
- uchar dospwd[14];
- uchar p16[16];
- ZERO_STRUCT(dospwd);
-
- memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd)));
- /* Only the fisrt 14 chars are considered, password need not be null terminated. */
-
- /* we *might* need to upper-case the string here */
- E_P16((const unsigned char *)dospwd, p16);
-
- if (memcmp(p16, lm_pw, sizeof(p16)) == 0) {
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
- } else {
- DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username));
- return NT_STATUS_WRONG_PASSWORD;
- }
- }
-
- if (nt_response->length != 0 && nt_response->length < 24) {
- DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n",
- (unsigned long)nt_response->length, username));
- }
-
- if (nt_response->length >= 24 && nt_pw) {
- if (nt_response->length > 24) {
- /* We have the NT MD4 hash challenge available - see if we can
- use it
- */
- DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain));
- if (smb_pwd_check_ntlmv2( nt_response,
- nt_pw, challenge,
- client_username,
- client_domain,
- False,
- user_sess_key)) {
- return NT_STATUS_OK;
- }
-
- DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain));
- if (smb_pwd_check_ntlmv2( nt_response,
- nt_pw, challenge,
- client_username,
- client_domain,
- True,
- user_sess_key)) {
- return NT_STATUS_OK;
- }
-
- DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( nt_response,
- nt_pw, challenge,
- client_username,
- "",
- False,
- user_sess_key)) {
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n"));
- return NT_STATUS_WRONG_PASSWORD;
- }
- }
-
- if (lp_ntlm_auth()) {
- /* We have the NT MD4 hash challenge available - see if we can
- use it (ie. does it exist in the smbpasswd file).
- */
- DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n"));
- if (smb_pwd_check_ntlmv1(nt_response,
- nt_pw, challenge,
- user_sess_key)) {
- /* The LM session key for this response is not very secure,
- so use it only if we otherwise allow LM authentication */
-
- if (lp_lanman_auth() && lm_pw) {
- uint8 first_8_lm_hash[16];
- memcpy(first_8_lm_hash, lm_pw, 8);
- memset(first_8_lm_hash + 8, '\0', 8);
- if (lm_sess_key) {
- *lm_sess_key = data_blob(first_8_lm_hash, 16);
- }
- }
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
- } else {
- DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n",
- username));
- /* no return, becouse we might pick up LMv2 in the LM field */
- }
- }
-
- if (lm_response->length == 0) {
- DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n",
- username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- if (lm_response->length < 24) {
- DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n",
- (unsigned long)nt_response->length, username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- if (!lp_lanman_auth()) {
- DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n",
- username));
- } else if (!lm_pw) {
- DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n",
- username));
- } else {
- DEBUG(4,("ntlm_password_check: Checking LM password\n"));
- if (smb_pwd_check_ntlmv1(lm_response,
- lm_pw, challenge,
- NULL)) {
- uint8 first_8_lm_hash[16];
- memcpy(first_8_lm_hash, lm_pw, 8);
- memset(first_8_lm_hash + 8, '\0', 8);
- if (user_sess_key) {
- *user_sess_key = data_blob(first_8_lm_hash, 16);
- }
-
- if (lm_sess_key) {
- *lm_sess_key = data_blob(first_8_lm_hash, 16);
- }
- return NT_STATUS_OK;
- }
- }
-
- if (!nt_pw) {
- DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username));
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes.
- - related to Win9X, legacy NAS pass-though authentication
- */
- DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain));
- if (smb_pwd_check_ntlmv2( lm_response,
- nt_pw, challenge,
- client_username,
- client_domain,
- False,
- NULL)) {
- return NT_STATUS_OK;
- }
-
- DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain));
- if (smb_pwd_check_ntlmv2( lm_response,
- nt_pw, challenge,
- client_username,
- client_domain,
- True,
- NULL)) {
- return NT_STATUS_OK;
- }
-
- DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( lm_response,
- nt_pw, challenge,
- client_username,
- "",
- False,
- NULL)) {
- return NT_STATUS_OK;
- }
-
- /* Apparently NT accepts NT responses in the LM field
- - I think this is related to Win9X pass-though authentication
- */
- DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n"));
- if (lp_ntlm_auth()) {
- if (smb_pwd_check_ntlmv1(lm_response,
- nt_pw, challenge,
- NULL)) {
- /* The session key for this response is still very odd.
- It not very secure, so use it only if we otherwise
- allow LM authentication */
-
- if (lp_lanman_auth() && lm_pw) {
- uint8 first_8_lm_hash[16];
- memcpy(first_8_lm_hash, lm_pw, 8);
- memset(first_8_lm_hash + 8, '\0', 8);
- if (user_sess_key) {
- *user_sess_key = data_blob(first_8_lm_hash, 16);
- }
-
- if (lm_sess_key) {
- *lm_sess_key = data_blob(first_8_lm_hash, 16);
- }
- }
- return NT_STATUS_OK;
- }
- DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username));
- } else {
- DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username));
- }
- return NT_STATUS_WRONG_PASSWORD;
-}
-
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
deleted file mode 100644
index 66d48afc463..00000000000
--- a/source/libsmb/ntlmssp.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- handle NLTMSSP, server side
-
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett 2001-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
- DATA_BLOB reply, DATA_BLOB *next_request);
-static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB in, DATA_BLOB *out);
-static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB reply, DATA_BLOB *next_request);
-static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB request, DATA_BLOB *reply);
-
-/**
- * Callbacks for NTLMSSP - for both client and server operating modes
- *
- */
-
-static const struct ntlmssp_callbacks {
- enum NTLMSSP_ROLE role;
- enum NTLM_MESSAGE_TYPE ntlmssp_command;
- NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
- DATA_BLOB in, DATA_BLOB *out);
-} ntlmssp_callbacks[] = {
- {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
- {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
- {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
- {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
- {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
- {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
-};
-
-
-/**
- * Print out the NTLMSSP flags for debugging
- * @param neg_flags The flags from the packet
- */
-
-void debug_ntlmssp_flags(uint32 neg_flags)
-{
- DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
-
- if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));
- if (neg_flags & NTLMSSP_REQUEST_TARGET)
- DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
- if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
- DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_128)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
- if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
- DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
-}
-
-/**
- * Default challenge generation code.
- *
- */
-
-static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
-{
- static uchar chal[8];
- generate_random_buffer(chal, sizeof(chal), False);
-
- return chal;
-}
-
-/**
- * Default 'we can set the challenge to anything we like' implementation
- *
- */
-
-static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
-{
- return True;
-}
-
-/**
- * Default 'we can set the challenge to anything we like' implementation
- *
- * Does not actually do anything, as the value is always in the structure anyway.
- *
- */
-
-static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
-{
- SMB_ASSERT(challenge->length == 8);
- return NT_STATUS_OK;
-}
-
-/**
- * Set a username on an NTLMSSP context - ensures it is talloc()ed
- *
- */
-
-NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user)
-{
- ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user);
- if (!ntlmssp_state->user) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
-}
-
-/**
- * Set a password on an NTLMSSP context - ensures it is talloc()ed
- *
- */
-NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password)
-{
- if (!password) {
- ntlmssp_state->password = NULL;
- } else {
- ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
- if (!ntlmssp_state->password) {
- return NT_STATUS_NO_MEMORY;
- }
- }
- return NT_STATUS_OK;
-}
-
-/**
- * Set a domain on an NTLMSSP context - ensures it is talloc()ed
- *
- */
-NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
-{
- ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
- if (!ntlmssp_state->domain) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
-}
-
-/**
- * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
- *
- */
-NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)
-{
- ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
- if (!ntlmssp_state->domain) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
-}
-
-/**
- * Store a DATA_BLOB containing an NTLMSSP response, for use later.
- * This copies the data blob
- */
-
-NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
- DATA_BLOB response)
-{
- ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx,
- response.data, response.length);
- return NT_STATUS_OK;
-}
-
-/**
- * Next state function for the NTLMSSP state machine
- *
- * @param ntlmssp_state NTLMSSP State
- * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
- * @param out The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.
- */
-
-NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
- const DATA_BLOB in, DATA_BLOB *out)
-{
- DATA_BLOB input;
- uint32 ntlmssp_command;
- int i;
-
- *out = data_blob(NULL, 0);
-
- if (!in.length && ntlmssp_state->stored_response.length) {
- input = ntlmssp_state->stored_response;
-
- /* we only want to read the stored response once - overwrite it */
- ntlmssp_state->stored_response = data_blob(NULL, 0);
- } else {
- input = in;
- }
-
- if (!input.length) {
- switch (ntlmssp_state->role) {
- case NTLMSSP_CLIENT:
- ntlmssp_command = NTLMSSP_INITIAL;
- break;
- case NTLMSSP_SERVER:
- /* 'datagram' mode - no neg packet */
- ntlmssp_command = NTLMSSP_NEGOTIATE;
- break;
- }
- } else {
- if (!msrpc_parse(&input, "Cd",
- "NTLMSSP",
- &ntlmssp_command)) {
- DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
- dump_data(2, (const char *)input.data, input.length);
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
-
- if (ntlmssp_command != ntlmssp_state->expected_state) {
- DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- for (i=0; ntlmssp_callbacks[i].fn; i++) {
- if (ntlmssp_callbacks[i].role == ntlmssp_state->role
- && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
- return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
- }
- }
-
- DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
- ntlmssp_state->role, ntlmssp_command));
-
- return NT_STATUS_INVALID_PARAMETER;
-}
-
-/**
- * End an NTLMSSP state machine
- *
- * @param ntlmssp_state NTLMSSP State, free()ed by this function
- */
-
-void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
-{
- TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
- (*ntlmssp_state)->ref_count--;
-
- if ((*ntlmssp_state)->ref_count == 0) {
- data_blob_free(&(*ntlmssp_state)->chal);
- data_blob_free(&(*ntlmssp_state)->lm_resp);
- data_blob_free(&(*ntlmssp_state)->nt_resp);
-
- talloc_destroy(mem_ctx);
- }
-
- *ntlmssp_state = NULL;
- return;
-}
-
-/**
- * Determine correct target name flags for reply, given server role
- * and negotiated flags
- *
- * @param ntlmssp_state NTLMSSP State
- * @param neg_flags The flags from the packet
- * @param chal_flags The flags to be set in the reply packet
- * @return The 'target name' string.
- */
-
-static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
- uint32 neg_flags, uint32 *chal_flags)
-{
- if (neg_flags & NTLMSSP_REQUEST_TARGET) {
- *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
- *chal_flags |= NTLMSSP_REQUEST_TARGET;
- if (ntlmssp_state->server_role == ROLE_STANDALONE) {
- *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
- return ntlmssp_state->get_global_myname();
- } else {
- *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
- return ntlmssp_state->get_domain();
- };
- } else {
- return "";
- }
-}
-
-static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
- uint32 neg_flags, BOOL allow_lm) {
- if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
- ntlmssp_state->unicode = True;
- } else {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
- ntlmssp_state->unicode = False;
- }
-
- if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
- /* other end forcing us to use LM */
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
- ntlmssp_state->use_ntlmv2 = False;
- } else {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
- }
-
- if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
- }
-
- if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
- }
-
- if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
- }
-
- if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
- }
-
- if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
- ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
- }
-
-}
-
-
-/**
- * Next state function for the Negotiate packet
- *
- * @param ntlmssp_state NTLMSSP State
- * @param request The request, as a DATA_BLOB
- * @param request The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
- */
-
-static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB request, DATA_BLOB *reply)
-{
- DATA_BLOB struct_blob;
- fstring dnsname, dnsdomname;
- uint32 neg_flags = 0;
- uint32 ntlmssp_command, chal_flags;
- char *cliname=NULL, *domname=NULL;
- const uint8 *cryptkey;
- const char *target_name;
-
- /* parse the NTLMSSP packet */
-#if 0
- file_save("ntlmssp_negotiate.dat", request.data, request.length);
-#endif
-
- if (request.length) {
- if (!msrpc_parse(&request, "CddAA",
- "NTLMSSP",
- &ntlmssp_command,
- &neg_flags,
- &cliname,
- &domname)) {
- DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
- dump_data(2, (const char *)request.data, request.length);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- SAFE_FREE(cliname);
- SAFE_FREE(domname);
-
- debug_ntlmssp_flags(neg_flags);
- }
-
- ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
-
- /* Ask our caller what challenge they would like in the packet */
- cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
-
- /* Check if we may set the challenge */
- if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
- }
-
- /* The flags we send back are not just the negotiated flags,
- * they are also 'what is in this packet'. Therfore, we
- * operate on 'chal_flags' from here on
- */
-
- chal_flags = ntlmssp_state->neg_flags;
-
- /* get the right name to fill in as 'target' */
- target_name = ntlmssp_target_name(ntlmssp_state,
- neg_flags, &chal_flags);
- if (target_name == NULL)
- return NT_STATUS_INVALID_PARAMETER;
-
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
- ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
-
-
- /* This should be a 'netbios domain -> DNS domain' mapping */
- dnsdomname[0] = '\0';
- get_mydnsdomname(dnsdomname);
- strlower_m(dnsdomname);
-
- dnsname[0] = '\0';
- get_mydnsfullname(dnsname);
-
- /* This creates the 'blob' of names that appears at the end of the packet */
- if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
- {
- const char *target_name_dns = "";
- if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
- target_name_dns = dnsdomname;
- } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
- target_name_dns = dnsname;
- }
-
- msrpc_gen(&struct_blob, "aaaaa",
- NTLMSSP_NAME_TYPE_DOMAIN, target_name,
- NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
- NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
- NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
- 0, "");
- } else {
- struct_blob = data_blob(NULL, 0);
- }
-
- {
- /* Marshel the packet in the right format, be it unicode or ASCII */
- const char *gen_string;
- if (ntlmssp_state->unicode) {
- gen_string = "CdUdbddB";
- } else {
- gen_string = "CdAdbddB";
- }
-
- msrpc_gen(reply, gen_string,
- "NTLMSSP",
- NTLMSSP_CHALLENGE,
- target_name,
- chal_flags,
- cryptkey, 8,
- 0, 0,
- struct_blob.data, struct_blob.length);
- }
-
- data_blob_free(&struct_blob);
-
- ntlmssp_state->expected_state = NTLMSSP_AUTH;
-
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-/**
- * Next state function for the Authenticate packet
- *
- * @param ntlmssp_state NTLMSSP State
- * @param request The request, as a DATA_BLOB
- * @param request The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors or NT_STATUS_OK.
- */
-
-static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB request, DATA_BLOB *reply)
-{
- DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
- DATA_BLOB user_session_key = data_blob(NULL, 0);
- DATA_BLOB lm_session_key = data_blob(NULL, 0);
- DATA_BLOB session_key = data_blob(NULL, 0);
- uint32 ntlmssp_command, auth_flags;
- NTSTATUS nt_status;
-
- /* used by NTLM2 */
- BOOL doing_ntlm2 = False;
-
- uchar session_nonce[16];
- uchar session_nonce_hash[16];
-
- const char *parse_string;
- char *domain = NULL;
- char *user = NULL;
- char *workstation = NULL;
-
- /* parse the NTLMSSP packet */
- *reply = data_blob(NULL, 0);
-
-#if 0
- file_save("ntlmssp_auth.dat", request.data, request.length);
-#endif
-
- if (ntlmssp_state->unicode) {
- parse_string = "CdBBUUUBd";
- } else {
- parse_string = "CdBBAAABd";
- }
-
- data_blob_free(&ntlmssp_state->lm_resp);
- data_blob_free(&ntlmssp_state->nt_resp);
-
- ntlmssp_state->user = NULL;
- ntlmssp_state->domain = NULL;
- ntlmssp_state->workstation = NULL;
-
- /* now the NTLMSSP encoded auth hashes */
- if (!msrpc_parse(&request, parse_string,
- "NTLMSSP",
- &ntlmssp_command,
- &ntlmssp_state->lm_resp,
- &ntlmssp_state->nt_resp,
- &domain,
- &user,
- &workstation,
- &encrypted_session_key,
- &auth_flags)) {
- DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
- dump_data(2, (const char *)request.data, request.length);
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
- data_blob_free(&encrypted_session_key);
- auth_flags = 0;
-
- /* Try again with a shorter string (Win9X truncates this packet) */
- if (ntlmssp_state->unicode) {
- parse_string = "CdBBUUU";
- } else {
- parse_string = "CdBBAAA";
- }
-
- /* now the NTLMSSP encoded auth hashes */
- if (!msrpc_parse(&request, parse_string,
- "NTLMSSP",
- &ntlmssp_command,
- &ntlmssp_state->lm_resp,
- &ntlmssp_state->nt_resp,
- &domain,
- &user,
- &workstation)) {
- DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
- dump_data(2, (const char *)request.data, request.length);
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
-
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
-
- if (auth_flags)
- ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
- data_blob_free(&encrypted_session_key);
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
- data_blob_free(&encrypted_session_key);
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
- data_blob_free(&encrypted_session_key);
- return nt_status;
- }
-
- SAFE_FREE(domain);
- SAFE_FREE(user);
- SAFE_FREE(workstation);
-
- DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
- ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
-
-#if 0
- file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
- file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
-#endif
-
- /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
- client challenge
-
- However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
- */
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
- struct MD5Context md5_session_nonce_ctx;
- SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
-
- doing_ntlm2 = True;
-
- memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
- memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
-
- MD5Init(&md5_session_nonce_ctx);
- MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
- MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
-
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
-
- /* LM response is no longer useful */
- data_blob_free(&ntlmssp_state->lm_resp);
-
- /* We changed the effective challenge - set it */
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
- data_blob_free(&encrypted_session_key);
- return nt_status;
- }
- }
- }
-
- /*
- * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
- * is required (by "ntlm auth = no" and "lm auth = no" being set in the
- * smb.conf file) and no NTLMv2 response was sent then the password check
- * will fail here. JRA.
- */
-
- /* Finally, actually ask if the password is OK */
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
- &user_session_key, &lm_session_key))) {
- data_blob_free(&encrypted_session_key);
- return nt_status;
- }
-
- dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
- dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
-
- /* Handle the different session key derivation for NTLM2 */
- if (doing_ntlm2) {
- if (user_session_key.data && user_session_key.length == 16) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
- hmac_md5(user_session_key.data, session_nonce,
- sizeof(session_nonce), session_key.data);
- DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
- dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
-
- } else {
- DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
- session_key = data_blob(NULL, 0);
- }
- } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
- if (lm_session_key.data && lm_session_key.length >= 8) {
- if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
- SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
- session_key.data);
- DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
- dump_data_pw("LM session key:\n", session_key.data, session_key.length);
- } else {
- /* use the key unmodified - it's
- * probably a NULL key from the guest
- * login */
- session_key = lm_session_key;
- }
- } else {
- DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
- session_key = data_blob(NULL, 0);
- }
- } else if (user_session_key.data) {
- session_key = user_session_key;
- DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
- dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
- } else if (lm_session_key.data) {
- session_key = lm_session_key;
- DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
- dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
- } else {
- DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
- session_key = data_blob(NULL, 0);
- }
-
- /* With KEY_EXCH, the client supplies the proposed session key,
- but encrypts it with the long-term key */
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
- if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
- data_blob_free(&encrypted_session_key);
- DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
- encrypted_session_key.length));
- return NT_STATUS_INVALID_PARAMETER;
- } else if (!session_key.data || session_key.length != 16) {
- DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
- session_key.length));
- ntlmssp_state->session_key = session_key;
- } else {
- dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
- SamOEMhash(encrypted_session_key.data,
- session_key.data,
- encrypted_session_key.length);
- ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx,
- encrypted_session_key.data,
- encrypted_session_key.length);
- dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data,
- encrypted_session_key.length);
- }
- } else {
- ntlmssp_state->session_key = session_key;
- }
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- ntlmssp_state->session_key = data_blob(NULL, 0);
- } else if (ntlmssp_state->session_key.length) {
- nt_status = ntlmssp_sign_init(ntlmssp_state);
- }
-
- data_blob_free(&encrypted_session_key);
-
- /* allow arbitarily many authentications */
- ntlmssp_state->expected_state = NTLMSSP_AUTH;
-
- return nt_status;
-}
-
-/**
- * Create an NTLMSSP state machine
- *
- * @param ntlmssp_state NTLMSSP State, allocated by this function
- */
-
-NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP context");
-
- *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
- if (!*ntlmssp_state) {
- DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*ntlmssp_state)->role = NTLMSSP_SERVER;
-
- (*ntlmssp_state)->mem_ctx = mem_ctx;
- (*ntlmssp_state)->get_challenge = get_challenge;
- (*ntlmssp_state)->set_challenge = set_challenge;
- (*ntlmssp_state)->may_set_challenge = may_set_challenge;
-
- (*ntlmssp_state)->get_global_myname = global_myname;
- (*ntlmssp_state)->get_domain = lp_workgroup;
- (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
-
- (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
-
- (*ntlmssp_state)->ref_count = 1;
-
- (*ntlmssp_state)->neg_flags =
- NTLMSSP_NEGOTIATE_128 |
- NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_NTLM2 |
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- NTLMSSP_NEGOTIATE_SIGN;
-
- return NT_STATUS_OK;
-}
-
-/*********************************************************************
- Client side NTLMSSP
-*********************************************************************/
-
-/**
- * Next state function for the Initial packet
- *
- * @param ntlmssp_state NTLMSSP State
- * @param request The request, as a DATA_BLOB. reply.data must be NULL
- * @param request The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors or NT_STATUS_OK.
- */
-
-static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
- DATA_BLOB reply, DATA_BLOB *next_request)
-{
- if (ntlmssp_state->unicode) {
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
- } else {
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
- }
-
- if (ntlmssp_state->use_ntlmv2) {
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
- }
-
- /* generate the ntlmssp negotiate packet */
- msrpc_gen(next_request, "CddAA",
- "NTLMSSP",
- NTLMSSP_NEGOTIATE,
- ntlmssp_state->neg_flags,
- ntlmssp_state->get_domain(),
- ntlmssp_state->get_global_myname());
-
- ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
-
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-/**
- * Next state function for the Challenge Packet. Generate an auth packet.
- *
- * @param ntlmssp_state NTLMSSP State
- * @param request The request, as a DATA_BLOB. reply.data must be NULL
- * @param request The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors or NT_STATUS_OK.
- */
-
-static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
- const DATA_BLOB reply, DATA_BLOB *next_request)
-{
- uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
- DATA_BLOB server_domain_blob;
- DATA_BLOB challenge_blob;
- DATA_BLOB struct_blob = data_blob(NULL, 0);
- char *server_domain;
- const char *chal_parse_string;
- const char *auth_gen_string;
- DATA_BLOB lm_response = data_blob(NULL, 0);
- DATA_BLOB nt_response = data_blob(NULL, 0);
- DATA_BLOB session_key = data_blob(NULL, 0);
- DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
- NTSTATUS nt_status;
-
- if (!msrpc_parse(&reply, "CdBd",
- "NTLMSSP",
- &ntlmssp_command,
- &server_domain_blob,
- &chal_flags)) {
- DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
- dump_data(2, (const char *)reply.data, reply.length);
-
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data_blob_free(&server_domain_blob);
-
- DEBUG(3, ("Got challenge flags:\n"));
- debug_ntlmssp_flags(chal_flags);
-
- ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
-
- if (ntlmssp_state->unicode) {
- if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
- chal_parse_string = "CdUdbddB";
- } else {
- chal_parse_string = "CdUdbdd";
- }
- auth_gen_string = "CdBBUUUBd";
- } else {
- if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
- chal_parse_string = "CdAdbddB";
- } else {
- chal_parse_string = "CdAdbdd";
- }
-
- auth_gen_string = "CdBBAAABd";
- }
-
- DEBUG(3, ("NTLMSSP: Set final flags:\n"));
- debug_ntlmssp_flags(ntlmssp_state->neg_flags);
-
- if (!msrpc_parse(&reply, chal_parse_string,
- "NTLMSSP",
- &ntlmssp_command,
- &server_domain,
- &chal_flags,
- &challenge_blob, 8,
- &unkn1, &unkn2,
- &struct_blob)) {
- DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
- dump_data(2, (const char *)reply.data, reply.length);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
- server_domain);
-
- SAFE_FREE(server_domain);
- if (challenge_blob.length != 8) {
- data_blob_free(&struct_blob);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!ntlmssp_state->password) {
- static const uchar zeros[16];
- /* do nothing - blobs are zero length */
-
- /* session key is all zeros */
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
-
- /* not doing NLTM2 without a password */
- ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
- } else if (ntlmssp_state->use_ntlmv2) {
-
- if (!struct_blob.length) {
- /* be lazy, match win2k - we can't do NTLMv2 without it */
- DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* TODO: if the remote server is standalone, then we should replace 'domain'
- with the server name as supplied above */
-
- if (!SMBNTLMv2encrypt(ntlmssp_state->user,
- ntlmssp_state->domain,
- ntlmssp_state->password, &challenge_blob,
- &struct_blob,
- &lm_response, &nt_response, &session_key)) {
- data_blob_free(&challenge_blob);
- data_blob_free(&struct_blob);
- return NT_STATUS_NO_MEMORY;
- }
- } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- struct MD5Context md5_session_nonce_ctx;
- uchar nt_hash[16];
- uchar session_nonce[16];
- uchar session_nonce_hash[16];
- uchar user_session_key[16];
- E_md4hash(ntlmssp_state->password, nt_hash);
-
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- generate_random_buffer(lm_response.data, 8, False);
- memset(lm_response.data+8, 0, 16);
-
- memcpy(session_nonce, challenge_blob.data, 8);
- memcpy(&session_nonce[8], lm_response.data, 8);
-
- MD5Init(&md5_session_nonce_ctx);
- MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
- MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
- MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
-
- DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
- DEBUG(5, ("challenge is: \n"));
- dump_data(5, (const char *)session_nonce_hash, 8);
-
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- SMBNTencrypt(ntlmssp_state->password,
- session_nonce_hash,
- nt_response.data);
-
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
-
- SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key);
- hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
- dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
- } else {
-
-
- uchar lm_hash[16];
- uchar nt_hash[16];
- E_deshash(ntlmssp_state->password, lm_hash);
- E_md4hash(ntlmssp_state->password, nt_hash);
-
- /* lanman auth is insecure, it may be disabled */
- if (lp_client_lanman_auth()) {
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- SMBencrypt(ntlmssp_state->password,challenge_blob.data,
- lm_response.data);
- }
-
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
- nt_response.data);
-
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
- if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
- && lp_client_lanman_auth()) {
- SMBsesskeygen_lmv1(lm_hash, lm_response.data,
- session_key.data);
- dump_data_pw("LM session key\n", session_key.data, session_key.length);
- } else {
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
- dump_data_pw("NT session key:\n", session_key.data, session_key.length);
- }
- }
- data_blob_free(&struct_blob);
-
- /* Key exchange encryptes a new client-generated session key with
- the password-derived key */
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
- /* Make up a new session key */
- uint8 client_session_key[16];
- generate_random_buffer(client_session_key, sizeof(client_session_key), False);
-
- /* Encrypt the new session key with the old one */
- encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
- dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
- SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
- dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
-
- /* Mark the new session key as the 'real' session key */
- data_blob_free(&session_key);
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
- }
-
- /* this generates the actual auth packet */
- if (!msrpc_gen(next_request, auth_gen_string,
- "NTLMSSP",
- NTLMSSP_AUTH,
- lm_response.data, lm_response.length,
- nt_response.data, nt_response.length,
- ntlmssp_state->domain,
- ntlmssp_state->user,
- ntlmssp_state->get_global_myname(),
- encrypted_session_key.data, encrypted_session_key.length,
- ntlmssp_state->neg_flags)) {
-
- return NT_STATUS_NO_MEMORY;
- }
-
- data_blob_free(&encrypted_session_key);
-
- data_blob_free(&ntlmssp_state->chal);
-
- ntlmssp_state->chal = challenge_blob;
- ntlmssp_state->lm_resp = lm_response;
- ntlmssp_state->nt_resp = nt_response;
- ntlmssp_state->session_key = session_key;
-
- ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
-
- if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
- DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
- return nt_status;
- }
-
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP Client context");
-
- *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
- if (!*ntlmssp_state) {
- DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*ntlmssp_state)->role = NTLMSSP_CLIENT;
-
- (*ntlmssp_state)->mem_ctx = mem_ctx;
-
- (*ntlmssp_state)->get_global_myname = global_myname;
- (*ntlmssp_state)->get_domain = lp_workgroup;
-
- (*ntlmssp_state)->unicode = True;
-
- (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
-
- (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
-
- (*ntlmssp_state)->ref_count = 1;
-
- (*ntlmssp_state)->neg_flags =
- NTLMSSP_NEGOTIATE_128 |
- NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_NTLM2 |
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- /*
- * We need to set this to allow a later SetPassword
- * via the SAMR pipe to succeed. Strange.... We could
- * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
- * */
- NTLMSSP_NEGOTIATE_SIGN |
- NTLMSSP_REQUEST_TARGET;
-
- return NT_STATUS_OK;
-}
-
diff --git a/source/libsmb/ntlmssp_parse.c b/source/libsmb/ntlmssp_parse.c
deleted file mode 100644
index 4b3043aec80..00000000000
--- a/source/libsmb/ntlmssp_parse.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- simple kerberos5/SPNEGO routines
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
- Copyright (C) Andrew Bartlett 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- this is a tiny msrpc packet generator. I am only using this to
- avoid tying this code to a particular varient of our rpc code. This
- generator is not general enough for all our rpc needs, its just
- enough for the spnego/ntlmssp code
-
- format specifiers are:
-
- U = unicode string (input is unix string)
- a = address (input is char *unix_string)
- (1 byte type, 1 byte length, unicode/ASCII string, all inline)
- A = ASCII string (input is unix string)
- B = data blob (pointer + length)
- b = data blob in header (pointer + length)
- D
- d = word (4 bytes)
- C = constant ascii string
- */
-BOOL msrpc_gen(DATA_BLOB *blob,
- const char *format, ...)
-{
- int i, n;
- va_list ap;
- char *s;
- uint8 *b;
- int head_size=0, data_size=0;
- int head_ofs, data_ofs;
-
- /* first scan the format to work out the header and body size */
- va_start(ap, format);
- for (i=0; format[i]; i++) {
- switch (format[i]) {
- case 'U':
- s = va_arg(ap, char *);
- head_size += 8;
- data_size += str_charnum(s) * 2;
- break;
- case 'A':
- s = va_arg(ap, char *);
- head_size += 8;
- data_size += str_ascii_charnum(s);
- break;
- case 'a':
- n = va_arg(ap, int);
- s = va_arg(ap, char *);
- data_size += (str_charnum(s) * 2) + 4;
- break;
- case 'B':
- b = va_arg(ap, uint8 *);
- head_size += 8;
- data_size += va_arg(ap, int);
- break;
- case 'b':
- b = va_arg(ap, uint8 *);
- head_size += va_arg(ap, int);
- break;
- case 'd':
- n = va_arg(ap, int);
- head_size += 4;
- break;
- case 'C':
- s = va_arg(ap, char *);
- head_size += str_charnum(s) + 1;
- break;
- }
- }
- va_end(ap);
-
- /* allocate the space, then scan the format again to fill in the values */
- *blob = data_blob(NULL, head_size + data_size);
-
- head_ofs = 0;
- data_ofs = head_size;
-
- va_start(ap, format);
- for (i=0; format[i]; i++) {
- switch (format[i]) {
- case 'U':
- s = va_arg(ap, char *);
- n = str_charnum(s);
- SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
- SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
- SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
- push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
- data_ofs += n*2;
- break;
- case 'A':
- s = va_arg(ap, char *);
- n = str_ascii_charnum(s);
- SSVAL(blob->data, head_ofs, n); head_ofs += 2;
- SSVAL(blob->data, head_ofs, n); head_ofs += 2;
- SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
- push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN);
- data_ofs += n;
- break;
- case 'a':
- n = va_arg(ap, int);
- SSVAL(blob->data, data_ofs, n); data_ofs += 2;
- s = va_arg(ap, char *);
- n = str_charnum(s);
- SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
- if (0 < n) {
- push_string(NULL, blob->data+data_ofs, s, n*2,
- STR_UNICODE|STR_NOALIGN);
- }
- data_ofs += n*2;
- break;
-
- case 'B':
- b = va_arg(ap, uint8 *);
- n = va_arg(ap, int);
- SSVAL(blob->data, head_ofs, n); head_ofs += 2;
- SSVAL(blob->data, head_ofs, n); head_ofs += 2;
- SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
- if (n && b) /* don't follow null pointers... */
- memcpy(blob->data+data_ofs, b, n);
- data_ofs += n;
- break;
- case 'd':
- n = va_arg(ap, int);
- SIVAL(blob->data, head_ofs, n); head_ofs += 4;
- break;
- case 'b':
- b = va_arg(ap, uint8 *);
- n = va_arg(ap, int);
- memcpy(blob->data + head_ofs, b, n);
- head_ofs += n;
- break;
- case 'C':
- s = va_arg(ap, char *);
- head_ofs += push_string(NULL, blob->data+head_ofs, s, -1,
- STR_ASCII|STR_TERMINATE);
- break;
- }
- }
- va_end(ap);
-
- return True;
-}
-
-
-/* a helpful macro to avoid running over the end of our blob */
-#define NEED_DATA(amount) \
-if ((head_ofs + amount) > blob->length) { \
- return False; \
-}
-
-/*
- this is a tiny msrpc packet parser. This the the partner of msrpc_gen
-
- format specifiers are:
-
- U = unicode string (output is unix string)
- A = ascii string
- B = data blob
- b = data blob in header
- d = word (4 bytes)
- C = constant ascii string
- */
-
-BOOL msrpc_parse(const DATA_BLOB *blob,
- const char *format, ...)
-{
- int i;
- va_list ap;
- char **ps, *s;
- DATA_BLOB *b;
- size_t head_ofs = 0;
- uint16 len1, len2;
- uint32 ptr;
- uint32 *v;
- pstring p;
-
- va_start(ap, format);
- for (i=0; format[i]; i++) {
- switch (format[i]) {
- case 'U':
- NEED_DATA(8);
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
-
- ps = va_arg(ap, char **);
- if (len1 == 0 && len2 == 0) {
- *ps = smb_xstrdup("");
- } else {
- /* make sure its in the right format - be strict */
- if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
- return False;
- }
- if (len1 & 1) {
- /* if odd length and unicode */
- return False;
- }
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
- return False;
-
- if (0 < len1) {
- pull_string(NULL, p, blob->data + ptr, sizeof(p),
- len1,
- STR_UNICODE|STR_NOALIGN);
- (*ps) = smb_xstrdup(p);
- } else {
- (*ps) = smb_xstrdup("");
- }
- }
- break;
- case 'A':
- NEED_DATA(8);
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
-
- ps = va_arg(ap, char **);
- /* make sure its in the right format - be strict */
- if (len1 == 0 && len2 == 0) {
- *ps = smb_xstrdup("");
- } else {
- if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
- return False;
- }
-
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
- return False;
-
- if (0 < len1) {
- pull_string(NULL, p, blob->data + ptr, sizeof(p),
- len1,
- STR_ASCII|STR_NOALIGN);
- (*ps) = smb_xstrdup(p);
- } else {
- (*ps) = smb_xstrdup("");
- }
- }
- break;
- case 'B':
- NEED_DATA(8);
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
-
- b = (DATA_BLOB *)va_arg(ap, void *);
- if (len1 == 0 && len2 == 0) {
- *b = data_blob(NULL, 0);
- } else {
- /* make sure its in the right format - be strict */
- if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
- return False;
- }
-
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
- return False;
-
- *b = data_blob(blob->data + ptr, len1);
- }
- break;
- case 'b':
- b = (DATA_BLOB *)va_arg(ap, void *);
- len1 = va_arg(ap, unsigned);
- /* make sure its in the right format - be strict */
- NEED_DATA(len1);
- if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data)
- return False;
-
- *b = data_blob(blob->data + head_ofs, len1);
- head_ofs += len1;
- break;
- case 'd':
- v = va_arg(ap, uint32 *);
- NEED_DATA(4);
- *v = IVAL(blob->data, head_ofs); head_ofs += 4;
- break;
- case 'C':
- s = va_arg(ap, char *);
-
- if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data)
- return False;
-
- head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p),
- blob->length - head_ofs,
- STR_ASCII|STR_TERMINATE);
- if (strcmp(s, p) != 0) {
- return False;
- }
- break;
- }
- }
- va_end(ap);
-
- return True;
-}
diff --git a/source/libsmb/ntlmssp_sign.c b/source/libsmb/ntlmssp_sign.c
deleted file mode 100644
index 2347619e57d..00000000000
--- a/source/libsmb/ntlmssp_sign.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Version 3.0
- * NTLMSSP Signing routines
- * Copyright (C) Luke Kenneth Casson Leighton 1996-2001
- * Copyright (C) Andrew Bartlett 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "includes.h"
-
-#define CLI_SIGN "session key to client-to-server signing key magic constant"
-#define CLI_SEAL "session key to client-to-server sealing key magic constant"
-#define SRV_SIGN "session key to server-to-client signing key magic constant"
-#define SRV_SEAL "session key to server-to-client sealing key magic constant"
-
-static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len)
-{
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
-
- for (ind = 0; ind < len; ind++)
- {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
- }
-
- hash[256] = index_i;
- hash[257] = index_j;
-}
-
-static void calc_hash(unsigned char hash[258], const char *k2, int k2l)
-{
- unsigned char j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++)
- {
- hash[ind] = (unsigned char)ind;
- }
-
- for (ind = 0; ind < 256; ind++)
- {
- unsigned char tc;
-
- j += (hash[ind] + k2[ind%k2l]);
-
- tc = hash[ind];
- hash[ind] = hash[j];
- hash[j] = tc;
- }
-
- hash[256] = 0;
- hash[257] = 0;
-}
-
-static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16],
- DATA_BLOB session_key,
- const char *constant)
-{
- struct MD5Context ctx3;
-
- /* NOTE: This code is currently complate fantasy - it's
- got more in common with reality than the previous code
- (the LM session key is not the right thing to use) but
- it still needs work */
-
- MD5Init(&ctx3);
- MD5Update(&ctx3, session_key.data, session_key.length);
- MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1);
- MD5Final(digest, &ctx3);
-
- calc_hash(hash, digest, 16);
-}
-
-enum ntlmssp_direction {
- NTLMSSP_SEND,
- NTLMSSP_RECEIVE
-};
-
-static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
- const uchar *data, size_t length,
- enum ntlmssp_direction direction,
- DATA_BLOB *sig)
-{
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- HMACMD5Context ctx;
- uchar seq_num[4];
- uchar digest[16];
- SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
-
- hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
- hmac_md5_update(seq_num, 4, &ctx);
- hmac_md5_update(data, length, &ctx);
- hmac_md5_final(digest, &ctx);
-
- if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
- , ntlmssp_state->ntlmssp_seq_num)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
- switch (direction) {
- case NTLMSSP_SEND:
- NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
- break;
- case NTLMSSP_RECEIVE:
- NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4);
- break;
- }
- }
- } else {
- uint32 crc;
- crc = crc32_calc_buffer((const char *)data, length);
- if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
- }
- return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
- const uchar *data, size_t length,
- DATA_BLOB *sig)
-{
- NTSTATUS nt_status;
- if (!ntlmssp_state->session_key.length) {
- DEBUG(3, ("NO session key, cannot check sign packet\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig);
-
- /* increment counter on send */
- ntlmssp_state->ntlmssp_seq_num++;
- return nt_status;
-}
-
-/**
- * Check the signature of an incoming packet
- * @note caller *must* check that the signature is the size it expects
- *
- */
-
-NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
- const uchar *data, size_t length,
- const DATA_BLOB *sig)
-{
- DATA_BLOB local_sig;
- NTSTATUS nt_status;
-
- if (!ntlmssp_state->session_key.length) {
- DEBUG(3, ("NO session key, cannot check packet signature\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- if (sig->length < 8) {
- DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n",
- (unsigned long)sig->length));
- }
-
- nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data,
- length, NTLMSSP_RECEIVE, &local_sig);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
- return nt_status;
- }
-
- if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) {
- DEBUG(5, ("BAD SIG: wanted signature of\n"));
- dump_data(5, (const char *)local_sig.data, local_sig.length);
-
- DEBUG(5, ("BAD SIG: got signature of\n"));
- dump_data(5, (const char *)(sig->data), sig->length);
-
- DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- /* increment counter on recieive */
- ntlmssp_state->ntlmssp_seq_num++;
-
- return NT_STATUS_OK;
-}
-
-
-/**
- * Seal data with the NTLMSSP algorithm
- *
- */
-
-NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
- uchar *data, size_t length,
- DATA_BLOB *sig)
-{
- if (!ntlmssp_state->session_key.length) {
- DEBUG(3, ("NO session key, cannot seal packet\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- DEBUG(10,("ntlmssp_seal_data: seal\n"));
- dump_data_pw("ntlmssp clear data\n", data, length);
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- HMACMD5Context ctx;
- char seq_num[4];
- uchar digest[16];
- SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
-
- hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
- hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
- hmac_md5_update(data, length, &ctx);
- hmac_md5_final(digest, &ctx);
-
- if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
- , ntlmssp_state->ntlmssp_seq_num)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- dump_data_pw("ntlmssp client sealing hash:\n",
- ntlmssp_state->send_seal_hash,
- sizeof(ntlmssp_state->send_seal_hash));
- NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
- dump_data_pw("ntlmssp client signing hash:\n",
- ntlmssp_state->send_sign_hash,
- sizeof(ntlmssp_state->send_sign_hash));
- NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
- } else {
- uint32 crc;
- crc = crc32_calc_buffer((const char *)data, length);
- if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- /* The order of these two operations matters - we must first seal the packet,
- then seal the sequence number - this is becouse the ntlmssp_hash is not
- constant, but is is rather updated with each iteration */
-
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
-
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
- }
- dump_data_pw("ntlmssp sealed data\n", data, length);
-
- /* increment counter on send */
- ntlmssp_state->ntlmssp_seq_num++;
-
- return NT_STATUS_OK;
-}
-
-/**
- * Unseal data with the NTLMSSP algorithm
- *
- */
-
-NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
- uchar *data, size_t length,
- DATA_BLOB *sig)
-{
- if (!ntlmssp_state->session_key.length) {
- DEBUG(3, ("NO session key, cannot unseal packet\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- DEBUG(10,("ntlmssp__unseal_data: seal\n"));
- dump_data_pw("ntlmssp sealed data\n", data, length);
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length);
- } else {
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
- }
- dump_data_pw("ntlmssp clear data\n", data, length);
-
- return ntlmssp_check_packet(ntlmssp_state, data, length, sig);
-}
-
-/**
- Initialise the state for NTLMSSP signing.
-*/
-NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
-{
- unsigned char p24[24];
- ZERO_STRUCT(p24);
-
- DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
- debug_ntlmssp_flags(ntlmssp_state->neg_flags);
-
- if (!ntlmssp_state->session_key.length) {
- DEBUG(3, ("NO session key, cannot intialise signing\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
-
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
- {
- const char *send_sign_const;
- const char *send_seal_const;
- const char *recv_sign_const;
- const char *recv_seal_const;
-
- switch (ntlmssp_state->role) {
- case NTLMSSP_CLIENT:
- send_sign_const = CLI_SIGN;
- send_seal_const = CLI_SEAL;
- recv_sign_const = SRV_SIGN;
- recv_seal_const = SRV_SEAL;
- break;
- case NTLMSSP_SERVER:
- send_sign_const = SRV_SIGN;
- send_seal_const = SRV_SEAL;
- recv_sign_const = CLI_SIGN;
- recv_seal_const = CLI_SEAL;
- break;
- }
-
- calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
- ntlmssp_state->send_sign_const,
- ntlmssp_state->session_key, send_sign_const);
- dump_data_pw("NTLMSSP send sign hash:\n",
- ntlmssp_state->send_sign_hash,
- sizeof(ntlmssp_state->send_sign_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->send_seal_hash,
- ntlmssp_state->send_seal_const,
- ntlmssp_state->session_key, send_seal_const);
- dump_data_pw("NTLMSSP send sesl hash:\n",
- ntlmssp_state->send_seal_hash,
- sizeof(ntlmssp_state->send_seal_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash,
- ntlmssp_state->recv_sign_const,
- ntlmssp_state->session_key, recv_sign_const);
- dump_data_pw("NTLMSSP receive sign hash:\n",
- ntlmssp_state->recv_sign_hash,
- sizeof(ntlmssp_state->recv_sign_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash,
- ntlmssp_state->recv_seal_const,
- ntlmssp_state->session_key, recv_seal_const);
- dump_data_pw("NTLMSSP receive seal hash:\n",
- ntlmssp_state->recv_sign_hash,
- sizeof(ntlmssp_state->recv_sign_hash));
-
- }
- else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
- if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) {
- /* can't sign or check signatures yet */
- DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n"));
-
- calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8);
- dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- } else {
- if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) {
- /* can't sign or check signatures yet */
- DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
-
- calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16);
- dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- }
-
- ntlmssp_state->ntlmssp_seq_num = 0;
-
- return NT_STATUS_OK;
-}
diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c
index dc0cbbcb7cc..335d9a7d1ab 100644
--- a/source/libsmb/passchange.c
+++ b/source/libsmb/passchange.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB client password change routine
Copyright (C) Andrew Tridgell 1994-1998
@@ -20,6 +21,9 @@
#include "includes.h"
+
+extern pstring global_myname;
+
/*************************************************************
change a password on a remote machine using IPC calls
*************************************************************/
@@ -30,9 +34,6 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
struct nmb_name calling, called;
struct cli_state cli;
struct in_addr ip;
- struct ntuser_creds creds;
-
- NTSTATUS result;
*err_str = '\0';
@@ -50,7 +51,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- make_nmb_name(&calling, global_myname() , 0x0);
+ make_nmb_name(&calling, global_myname , 0x0);
make_nmb_name(&called , remote_machine, 0x20);
if (!cli_session_request(&cli, &calling, &called)) {
@@ -69,28 +70,18 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- /* Given things like SMB signing, restrict anonymous and the like,
- try an authenticated connection first */
- if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) {
- /*
- * We should connect as the anonymous user here, in case
- * the server has "must change password" checked...
- * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
- */
+ /*
+ * We should connect as the anonymous user here, in case
+ * the server has "must change password" checked...
+ * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
+ */
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- return False;
- }
-
- init_creds(&creds, "", "", NULL);
- cli_init_creds(&cli, &creds);
- } else {
- init_creds(&creds, user_name, "", old_passwd);
- cli_init_creds(&cli, &creds);
- }
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
@@ -99,54 +90,13 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- /* Try not to give the password away to easily */
-
- cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli.pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli.pipe_auth_flags |= AUTH_PIPE_SEAL;
-
- if ( !cli_nt_session_open( &cli, PI_SAMR ) ) {
- if (lp_client_lanman_auth()) {
- if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
- slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- return False;
- }
- } else {
- slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
- remote_machine);
- cli_shutdown(&cli);
- return False;
- }
- }
-
- if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name,
- new_passwd, old_passwd))) {
-
- if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)
- || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
- /* try the old Lanman method */
- if (lp_client_lanman_auth()) {
- if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
- slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- return False;
- }
- } else {
- slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
- remote_machine);
- cli_shutdown(&cli);
- return False;
- }
- } else {
- slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
- remote_machine, get_friendly_nt_error_msg(result));
- cli_shutdown(&cli);
- return False;
- }
+ if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+ slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
}
+
cli_shutdown(&cli);
return True;
}
diff --git a/source/libsmb/pwd_cache.c b/source/libsmb/pwd_cache.c
index e010f226a02..ecbcf0d6785 100644
--- a/source/libsmb/pwd_cache.c
+++ b/source/libsmb/pwd_cache.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Password cacheing. obfuscation is planned
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
@@ -24,40 +25,228 @@
Initialises a password structure.
****************************************************************************/
-static void pwd_init(struct pwd_info *pwd)
+void pwd_init(struct pwd_info *pwd)
{
memset((char *)pwd->password , '\0', sizeof(pwd->password ));
+ memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd));
+ memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd));
+ memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf));
+ memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf));
pwd->null_pwd = True; /* safest option... */
+ pwd->cleartext = False;
+ pwd->crypted = False;
+}
+
+/****************************************************************************
+ Returns NULL password flag.
+****************************************************************************/
+
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
+{
+ return pwd->null_pwd;
+}
+
+/****************************************************************************
+ Compares two passwords. hmm, not as trivial as expected. hmm.
+****************************************************************************/
+
+BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
+{
+ if (pwd1->cleartext && pwd2->cleartext) {
+ if (strequal(pwd1->password, pwd2->password))
+ return True;
+ }
+ if (pwd1->null_pwd && pwd2->null_pwd)
+ return True;
+
+ if (!pwd1->null_pwd && !pwd2->null_pwd &&
+ !pwd1->cleartext && !pwd2->cleartext) {
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("pwd compare: nt#\n"));
+ dump_data(100, pwd1->smb_nt_pwd, 16);
+ dump_data(100, pwd2->smb_nt_pwd, 16);
+#endif
+ if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
+ return True;
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("pwd compare: lm#\n"));
+ dump_data(100, pwd1->smb_lm_pwd, 16);
+ dump_data(100, pwd2->smb_lm_pwd, 16);
+#endif
+ if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************************
+ Reads a password.
+****************************************************************************/
+
+void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
+{
+ /* grab a password */
+ char *user_pass;
+
+ pwd_init(pwd);
+
+ user_pass = (char*)getpass(passwd_report);
+
+ /*
+ * Do not assume that an empty string is a NULL password.
+ * If you do this will break the session key generation for
+ * and account with an emtpy password. If you wish to use
+ * a NULL password, use the -N option to smbclient and rpcclient
+ * --jerry
+ */
+#if 0
+ if (user_pass == NULL || user_pass[0] == 0)
+ pwd_set_nullpwd(pwd);
+ else if (do_encrypt)
+#endif
+ if (do_encrypt)
+ pwd_make_lm_nt_16(pwd, user_pass);
+ else
+ pwd_set_cleartext(pwd, user_pass);
}
/****************************************************************************
Stores a cleartext password.
****************************************************************************/
-void pwd_set_cleartext(struct pwd_info *pwd, const char *clr)
+void pwd_set_nullpwd(struct pwd_info *pwd)
{
pwd_init(pwd);
- if (clr) {
- fstrcpy(pwd->password, clr);
- pwd->null_pwd = False;
- } else {
- pwd->null_pwd = True;
- }
+ pwd->cleartext = False;
+ pwd->null_pwd = True;
+ pwd->crypted = False;
+}
+
+/****************************************************************************
+ Stores a cleartext password.
+ ****************************************************************************/
+
+void pwd_set_cleartext(struct pwd_info *pwd, const char *clr)
+{
+ pwd_init(pwd);
+ fstrcpy(pwd->password, clr);
+ unix_to_dos(pwd->password);
pwd->cleartext = True;
+ pwd->null_pwd = False;
+ pwd->crypted = False;
}
/****************************************************************************
Gets a cleartext password.
****************************************************************************/
-void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
+void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
{
- if (pwd->cleartext)
+ if (pwd->cleartext) {
fstrcpy(clr, pwd->password);
- else
+ dos_to_unix(clr);
+ } else {
clr[0] = 0;
+ }
+}
+
+/****************************************************************************
+ Stores lm and nt hashed passwords.
+****************************************************************************/
+
+void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+{
+ pwd_init(pwd);
+
+ if (lm_pwd)
+ memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
+ else
+ memset((char *)pwd->smb_lm_pwd, '\0', 16);
+
+ if (nt_pwd)
+ memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
+ else
+ memset((char *)pwd->smb_nt_pwd, '\0', 16);
+
+ pwd->null_pwd = False;
+ pwd->cleartext = False;
+ pwd->crypted = False;
+}
+
+/****************************************************************************
+ Gets lm and nt hashed passwords.
+****************************************************************************/
+
+void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+{
+ if (lm_pwd != NULL)
+ memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
+ if (nt_pwd != NULL)
+ memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
+}
+
+/****************************************************************************
+ Makes lm and nt hashed passwords.
+****************************************************************************/
+
+void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
+{
+ pstring dos_passwd;
+
+ pwd_init(pwd);
+ pstrcpy(dos_passwd, clr);
+ unix_to_dos(dos_passwd);
+
+ nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
+ pwd->null_pwd = False;
+ pwd->cleartext = False;
+ pwd->crypted = False;
}
+/****************************************************************************
+ Makes lm and nt OWF crypts.
+****************************************************************************/
+
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
+{
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, (char *)cryptkey, 8);
+#endif
+
+ SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_owf_passwd: "));
+ dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+#endif
+
+ SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm_owf_passwd: "));
+ dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+#endif
+
+ pwd->crypted = True;
+}
+
+/****************************************************************************
+ Gets lm and nt crypts.
+****************************************************************************/
+
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
+{
+ if (lm_owf != NULL)
+ memcpy(lm_owf, pwd->smb_lm_owf, 24);
+ if (nt_owf != NULL)
+ memcpy(nt_owf, pwd->smb_nt_owf, 24);
+}
diff --git a/source/libsmb/samlogon_cache.c b/source/libsmb/samlogon_cache.c
deleted file mode 100644
index 4cd642c4e35..00000000000
--- a/source/libsmb/samlogon_cache.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Net_sam_logon info3 helpers
- Copyright (C) Alexander Bokovoy 2002.
- Copyright (C) Andrew Bartlett 2002.
- Copyright (C) Gerald Carter 2003.
- Copyright (C) Tim Potter 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define NETSAMLOGON_TDB "netsamlogon_cache.tdb"
-
-static TDB_CONTEXT *netsamlogon_tdb = NULL;
-
-/***********************************************************************
- open the tdb
- ***********************************************************************/
-
-BOOL netsamlogon_cache_init(void)
-{
- if (!netsamlogon_tdb) {
- netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
- }
-
- return (netsamlogon_tdb != NULL);
-}
-
-
-/***********************************************************************
- Shutdown samlogon_cache database
-***********************************************************************/
-
-BOOL netsamlogon_cache_shutdown(void)
-{
- if(netsamlogon_tdb)
- return (tdb_close(netsamlogon_tdb) == 0);
-
- return True;
-}
-
-/***********************************************************************
- Clear cache getpwnam and getgroups entries from the winbindd cache
-***********************************************************************/
-void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user)
-{
- fstring domain;
- TDB_DATA key;
- BOOL got_tdb = False;
-
- /* We may need to call this function from smbd which will not have
- winbindd_cache.tdb open. Open the tdb if a NULL is passed. */
-
- if (!tdb) {
- tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
- TDB_DEFAULT, O_RDWR, 0600);
- if (!tdb) {
- DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n"));
- return;
- }
- got_tdb = True;
- }
-
- unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1);
-
- /* Clear U/DOMAIN/RID cache entry */
-
- asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid);
- key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */
-
- DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr));
-
- tdb_delete(tdb, key);
-
- SAFE_FREE(key.dptr);
-
- /* Clear UG/DOMAIN/RID cache entry */
-
- asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid);
- key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */
-
- DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr));
-
- tdb_delete(tdb, key);
-
- SAFE_FREE(key.dptr);
-
- if (got_tdb)
- tdb_close(tdb);
-}
-
-/***********************************************************************
- Store a NET_USER_INFO_3 structure in a tdb for later user
-***********************************************************************/
-
-BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user)
-{
- TDB_DATA data;
- fstring keystr;
- prs_struct ps;
- BOOL result = False;
- DOM_SID user_sid;
- time_t t = time(NULL);
-
-
- if (!netsamlogon_cache_init()) {
- DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB));
- return False;
- }
-
- sid_copy( &user_sid, &user->dom_sid.sid );
- sid_append_rid( &user_sid, user->user_rid );
-
- /* Prepare key as DOMAIN-SID/USER-RID string */
- slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid));
-
- DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));
-
- /* Prepare data */
-
- prs_init( &ps,MAX_PDU_FRAG_LEN , mem_ctx, MARSHALL);
-
- if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) )
- return False;
-
- if ( net_io_user_info3("", user, &ps, 0, 3) )
- {
- data.dsize = prs_offset( &ps );
- data.dptr = prs_data_p( &ps );
-
- if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1)
- result = True;
-
- prs_mem_free( &ps );
- }
-
- return result;
-}
-
-/***********************************************************************
- Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must
- free the user_info struct (malloc()'d memory)
-***********************************************************************/
-
-NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid)
-{
- NET_USER_INFO_3 *user = NULL;
- TDB_DATA data, key;
- prs_struct ps;
- fstring keystr;
- uint32 t;
-
- if (!netsamlogon_cache_init()) {
- DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB));
- return False;
- }
-
- /* Prepare key as DOMAIN-SID/USER-RID string */
- slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid));
- DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr));
- key.dptr = keystr;
- key.dsize = strlen(keystr)+1;
- data = tdb_fetch( netsamlogon_tdb, key );
-
- if ( data.dptr ) {
-
- if ( (user = (NET_USER_INFO_3*)malloc(sizeof(NET_USER_INFO_3))) == NULL )
- return NULL;
-
- prs_init( &ps, 0, mem_ctx, UNMARSHALL );
- prs_give_memory( &ps, data.dptr, data.dsize, True );
-
- if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) {
- prs_mem_free( &ps );
- return False;
- }
-
- if ( !net_io_user_info3("", user, &ps, 0, 3) ) {
- SAFE_FREE( user );
- }
-
- prs_mem_free( &ps );
-
-#if 0 /* The netsamlogon cache needs to hang around. Something about
- this feels wrong, but it is the only way we can get all of the
- groups. The old universal groups cache didn't expire either.
- --jerry */
- {
- time_t now = time(NULL);
- uint32 time_diff;
-
- /* is the entry expired? */
- time_diff = now - t;
-
- if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) {
- DEBUG(10,("netsamlogon_cache_get: cache entry expired \n"));
- tdb_delete( netsamlogon_tdb, key );
- SAFE_FREE( user );
- }
-#endif
- }
-
- return user;
-}
-
-BOOL netsamlogon_cache_have(const DOM_SID *user_sid)
-{
- TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have");
- NET_USER_INFO_3 *user = NULL;
- BOOL result;
-
- if (!mem_ctx)
- return False;
-
- user = netsamlogon_cache_get(mem_ctx, user_sid);
-
- result = (user != NULL);
-
- talloc_destroy(mem_ctx);
- SAFE_FREE(user);
-
- return result;
-}
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
deleted file mode 100644
index 7130453c0c9..00000000000
--- a/source/libsmb/smb_signing.c
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB Signing Code
- Copyright (C) Jeremy Allison 2003.
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */
-struct outstanding_packet_lookup {
- uint16 mid;
- uint32 reply_seq_num;
- struct outstanding_packet_lookup *prev, *next;
-};
-
-/* Store the data for an ongoing trans/trans2/nttrans operation. */
-struct trans_info_context {
- uint16 mid;
- uint32 send_seq_num;
- uint32 reply_seq_num;
-};
-
-struct smb_basic_signing_context {
- DATA_BLOB mac_key;
- uint32 send_seq_num;
- struct trans_info_context *trans_info;
- struct outstanding_packet_lookup *outstanding_packet_list;
-};
-
-static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 reply_seq_num)
-{
- struct outstanding_packet_lookup *t;
-
- t = smb_xmalloc(sizeof(*t));
- ZERO_STRUCTP(t);
-
- t->mid = mid;
- t->reply_seq_num = reply_seq_num;
-
- /*
- * Add to the *start* of the list not the end of the list.
- * This ensures that the *last* send sequence with this mid
- * is returned by preference.
- * This can happen if the mid wraps and one of the early
- * mid numbers didn't get a reply and is still lurking on
- * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>.
- */
-
- DLIST_ADD(*list, t);
- DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
- (unsigned int)reply_seq_num, (unsigned int)mid ));
-}
-
-static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 *reply_seq_num)
-{
- struct outstanding_packet_lookup *t;
-
- for (t = *list; t; t = t->next) {
- if (t->mid == mid) {
- *reply_seq_num = t->reply_seq_num;
- DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
- (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
- DLIST_REMOVE(*list, t);
- SAFE_FREE(t);
- return True;
- }
- }
- return False;
-}
-
-/***********************************************************
- SMB signing - Common code before we set a new signing implementation
-************************************************************/
-
-static BOOL cli_set_smb_signing_common(struct cli_state *cli)
-{
- if (!cli->sign_info.negotiated_smb_signing
- && !cli->sign_info.mandatory_signing) {
- return False;
- }
-
- if (cli->sign_info.doing_signing) {
- return False;
- }
-
- if (cli->sign_info.free_signing_context)
- cli->sign_info.free_signing_context(&cli->sign_info);
-
- /* These calls are INCOMPATIBLE with SMB signing */
- cli->readbraw_supported = False;
- cli->writebraw_supported = False;
-
- return True;
-}
-
-/***********************************************************
- SMB signing - Common code for 'real' implementations
-************************************************************/
-
-static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
-{
- if (si->mandatory_signing) {
- DEBUG(5, ("Mandatory SMB signing enabled!\n"));
- }
-
- si->doing_signing = True;
- DEBUG(5, ("SMB signing enabled!\n"));
-
- return True;
-}
-
-static void mark_packet_signed(char *outbuf)
-{
- uint16 flags2;
- flags2 = SVAL(outbuf,smb_flg2);
- flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
- SSVAL(outbuf,smb_flg2, flags2);
-}
-
-/***********************************************************
- SMB signing - NULL implementation - calculate a MAC to send.
-************************************************************/
-
-static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- /* we can't zero out the sig, as we might be trying to send a
- session request - which is NBT-level, not SMB level and doesn't
- have the field */
- return;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - check a MAC sent by server.
-************************************************************/
-
-static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
-{
- return True;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - free signing context
-************************************************************/
-
-static void null_free_signing_context(struct smb_sign_info *si)
-{
- return;
-}
-
-/**
- SMB signing - NULL implementation - setup the MAC key.
-
- @note Used as an initialisation only - it will not correctly
- shut down a real signing mechanism
-*/
-
-static BOOL null_set_signing(struct smb_sign_info *si)
-{
- si->signing_context = NULL;
-
- si->sign_outgoing_message = null_sign_outgoing_message;
- si->check_incoming_message = null_check_incoming_message;
- si->free_signing_context = null_free_signing_context;
-
- return True;
-}
-
-/**
- * Free the signing context
- */
-
-static void free_signing_context(struct smb_sign_info *si)
-{
- if (si->free_signing_context) {
- si->free_signing_context(si);
- si->signing_context = NULL;
- }
-
- null_set_signing(si);
-}
-
-
-static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok)
-{
- if (good) {
-
- if (!si->doing_signing) {
- si->doing_signing = True;
- }
-
- if (!si->seen_valid) {
- si->seen_valid = True;
- }
-
- } else {
- if (!si->mandatory_signing && !si->seen_valid) {
-
- if (!must_be_ok) {
- return True;
- }
- /* Non-mandatory signing - just turn off if this is the first bad packet.. */
- DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
- "isn't sending correct signatures. Turning off.\n"));
- si->negotiated_smb_signing = False;
- si->allow_smb_signing = False;
- si->doing_signing = False;
- free_signing_context(si);
- return True;
- } else if (!must_be_ok) {
- /* This packet is known to be unsigned */
- return True;
- } else {
- /* Mandatory signing or bad packet after signing started - fail and disconnect. */
- if (seq)
- DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
- return False;
- }
- }
- return True;
-}
-
-/***********************************************************
- SMB signing - Simple implementation - calculate a MAC on the packet
-************************************************************/
-
-static void simple_packet_signature(struct smb_basic_signing_context *data,
- const uchar *buf, uint32 seq_number,
- unsigned char calc_md5_mac[16])
-{
- const size_t offset_end_of_sig = (smb_ss_field + 8);
- unsigned char sequence_buf[8];
- struct MD5Context md5_ctx;
-
- /*
- * Firstly put the sequence number into the first 4 bytes.
- * and zero out the next 4 bytes.
- *
- * We do this here, to avoid modifying the packet.
- */
-
- DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
-
- SIVAL(sequence_buf, 0, seq_number);
- SIVAL(sequence_buf, 4, 0);
-
- /* Calculate the 16 byte MAC - but don't alter the data in the
- incoming packet.
-
- This makes for a bit of fussing about, but it's not too bad.
- */
- MD5Init(&md5_ctx);
-
- /* intialise with the key */
- MD5Update(&md5_ctx, data->mac_key.data,
- data->mac_key.length);
-
- /* copy in the first bit of the SMB header */
- MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
-
- /* copy in the sequence number, instead of the signature */
- MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
-
- /* copy in the rest of the packet in, skipping the signature */
- MD5Update(&md5_ctx, buf + offset_end_of_sig,
- smb_len(buf) - (offset_end_of_sig - 4));
-
- /* calculate the MD5 sig */
- MD5Final(calc_md5_mac, &md5_ctx);
-}
-
-
-/***********************************************************
- SMB signing - Client implementation - send the MAC.
-************************************************************/
-
-static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- unsigned char calc_md5_mac[16];
- struct smb_basic_signing_context *data = si->signing_context;
- uint32 send_seq_num;
-
- if (!si->doing_signing)
- return;
-
- /* JRA Paranioa test - we should be able to get rid of this... */
- if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
- smb_len(outbuf) ));
- abort();
- }
-
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- if (data->trans_info)
- send_seq_num = data->trans_info->send_seq_num;
- else
- send_seq_num = data->send_seq_num;
-
- simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac);
-
- DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
- dump_data(10, (const char *)calc_md5_mac, 8);
-
- memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
-
-/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote server actually verifies signatures...*/
-
- if (data->trans_info)
- return;
-
- data->send_seq_num++;
- store_sequence_for_reply(&data->outstanding_packet_list,
- SVAL(outbuf,smb_mid), data->send_seq_num);
- data->send_seq_num++;
-}
-
-/***********************************************************
- SMB signing - Client implementation - check a MAC sent by server.
-************************************************************/
-
-static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
-{
- BOOL good;
- uint32 reply_seq_number;
- uint32 saved_seq;
- unsigned char calc_md5_mac[16];
- unsigned char *server_sent_mac;
-
- struct smb_basic_signing_context *data = si->signing_context;
-
- if (!si->doing_signing)
- return True;
-
- if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
- return False;
- }
-
- if (data->trans_info) {
- reply_seq_number = data->trans_info->reply_seq_num;
- } else if (!get_sequence_for_reply(&data->outstanding_packet_list,
- SVAL(inbuf, smb_mid), &reply_seq_number)) {
- DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
- (unsigned int) SVAL(inbuf, smb_mid) ));
- return False;
- }
-
- saved_seq = reply_seq_number;
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
-
- server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
- good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-
- if (!good) {
- DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
- dump_data(5, (const char *)calc_md5_mac, 8);
-
- DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
- dump_data(5, (const char *)server_sent_mac, 8);
-#if 1 /* JRATEST */
- {
- int i;
- reply_seq_number -= 5;
- for (i = 0; i < 10; i++, reply_seq_number++) {
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
- if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
-We were expecting seq %u\n", reply_seq_number, saved_seq ));
- break;
- }
- }
- }
-#endif /* JRATEST */
-
- } else {
- DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
- dump_data(10, (const char *)server_sent_mac, 8);
- }
- return signing_good(inbuf, si, good, saved_seq, must_be_ok);
-}
-
-/***********************************************************
- SMB signing - Simple implementation - free signing context
-************************************************************/
-
-static void simple_free_signing_context(struct smb_sign_info *si)
-{
- struct smb_basic_signing_context *data = si->signing_context;
- struct outstanding_packet_lookup *list = data->outstanding_packet_list;
-
- while (list) {
- struct outstanding_packet_lookup *old_head = list;
- DLIST_REMOVE(list, list);
- SAFE_FREE(old_head);
- }
-
- data_blob_free(&data->mac_key);
-
- if (data->trans_info)
- SAFE_FREE(data->trans_info);
-
- SAFE_FREE(si->signing_context);
-
- return;
-}
-
-/***********************************************************
- SMB signing - Simple implementation - setup the MAC key.
-************************************************************/
-
-BOOL cli_simple_set_signing(struct cli_state *cli,
- const DATA_BLOB user_session_key,
- const DATA_BLOB response)
-{
- struct smb_basic_signing_context *data;
-
- if (!user_session_key.length)
- return False;
-
- if (!cli_set_smb_signing_common(cli)) {
- return False;
- }
-
- if (!set_smb_signing_real_common(&cli->sign_info)) {
- return False;
- }
-
- data = smb_xmalloc(sizeof(*data));
- memset(data, '\0', sizeof(*data));
-
- cli->sign_info.signing_context = data;
-
- data->mac_key = data_blob(NULL, response.length + user_session_key.length);
-
- memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
-
- DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
- dump_data(10, (const char *)user_session_key.data, user_session_key.length);
-
- if (response.length) {
- memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
- DEBUG(10, ("cli_simple_set_signing: response_data\n"));
- dump_data(10, (const char *)response.data, response.length);
- } else {
- DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
- }
-
- dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
-
- /* Initialise the sequence number */
- data->send_seq_num = 0;
-
- /* Initialise the list of outstanding packets */
- data->outstanding_packet_list = NULL;
-
- cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
- cli->sign_info.check_incoming_message = client_check_incoming_message;
- cli->sign_info.free_signing_context = simple_free_signing_context;
-
- return True;
-}
-
-/***********************************************************
- Tell client code we are in a multiple trans reply state.
- We call this after the last outgoing trans2 packet (which
- has incremented the sequence numbers), so we must save the
- current mid and sequence number -2.
-************************************************************/
-
-void cli_signing_trans_start(struct cli_state *cli, uint16 mid)
-{
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
-
- if (!cli->sign_info.doing_signing || !data)
- return;
-
- data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
- ZERO_STRUCTP(data->trans_info);
-
- data->trans_info->send_seq_num = data->send_seq_num-2;
- data->trans_info->mid = mid;
- data->trans_info->reply_seq_num = data->send_seq_num-1;
-
- DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
-data->send_seq_num = %u\n",
- (unsigned int)data->trans_info->mid,
- (unsigned int)data->trans_info->reply_seq_num,
- (unsigned int)data->trans_info->send_seq_num,
- (unsigned int)data->send_seq_num ));
-}
-
-/***********************************************************
- Tell client code we are out of a multiple trans reply state.
-************************************************************/
-
-void cli_signing_trans_stop(struct cli_state *cli)
-{
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
-
- if (!cli->sign_info.doing_signing || !data)
- return;
-
- DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
-data->send_seq_num = %u\n",
- (unsigned int)data->trans_info->mid,
- (unsigned int)data->trans_info->reply_seq_num,
- (unsigned int)data->trans_info->send_seq_num,
- (unsigned int)data->send_seq_num ));
-
- SAFE_FREE(data->trans_info);
- data->trans_info = NULL;
-}
-
-/***********************************************************
- SMB signing - TEMP implementation - calculate a MAC to send.
-************************************************************/
-
-static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- /* I wonder what BSRSPYL stands for - but this is what MS
- actually sends! */
- memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
- return;
-}
-
-/***********************************************************
- SMB signing - TEMP implementation - check a MAC sent by server.
-************************************************************/
-
-static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo)
-{
- return True;
-}
-
-/***********************************************************
- SMB signing - TEMP implementation - free signing context
-************************************************************/
-
-static void temp_free_signing_context(struct smb_sign_info *si)
-{
- return;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - setup the MAC key.
-************************************************************/
-
-BOOL cli_null_set_signing(struct cli_state *cli)
-{
- return null_set_signing(&cli->sign_info);
-}
-
-/***********************************************************
- SMB signing - temp implementation - setup the MAC key.
-************************************************************/
-
-BOOL cli_temp_set_signing(struct cli_state *cli)
-{
- if (!cli_set_smb_signing_common(cli)) {
- return False;
- }
-
- cli->sign_info.signing_context = NULL;
-
- cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
- cli->sign_info.check_incoming_message = temp_check_incoming_message;
- cli->sign_info.free_signing_context = temp_free_signing_context;
-
- return True;
-}
-
-void cli_free_signing_context(struct cli_state *cli)
-{
- free_signing_context(&cli->sign_info);
-}
-
-/**
- * Sign a packet with the current mechanism
- */
-
-void cli_calculate_sign_mac(struct cli_state *cli)
-{
- cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
-}
-
-/**
- * Check a packet with the current mechanism
- * @return False if we had an established signing connection
- * which had a bad checksum, True otherwise.
- */
-
-BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok)
-{
- if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) {
- free_signing_context(&cli->sign_info);
- return False;
- }
- return True;
-}
-
-/***********************************************************
- SMB signing - Server implementation - send the MAC.
-************************************************************/
-
-static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- unsigned char calc_md5_mac[16];
- struct smb_basic_signing_context *data = si->signing_context;
- uint32 send_seq_number = data->send_seq_num;
- BOOL was_deferred_packet = False;
- uint16 mid;
-
- if (!si->doing_signing) {
- return;
- }
-
- /* JRA Paranioa test - we should be able to get rid of this... */
- if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
- smb_len(outbuf) ));
- abort();
- }
-
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- mid = SVAL(outbuf, smb_mid);
-
- /* See if this is a reply for a deferred packet. */
- was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
-
- if (data->trans_info && (data->trans_info->mid == mid)) {
- /* This is a reply in a trans stream. Use the sequence
- * number associated with the stream mid. */
- send_seq_number = data->trans_info->send_seq_num;
- }
-
- simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
-
- DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
- dump_data(10, (const char *)calc_md5_mac, 8);
-
- memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
-
-/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote client actually verifies signatures...*/
-
- /* Don't mess with the sequence number for a deferred packet. */
- if (was_deferred_packet) {
- return;
- }
-
- if (!data->trans_info) {
- /* Always increment if not in a trans stream. */
- data->send_seq_num++;
- } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
- /* Increment if this is the first reply in a trans stream or a
- * packet that doesn't belong to this stream (different mid). */
- data->send_seq_num++;
- }
-}
-
-/***********************************************************
- Is an incoming packet an oplock break reply ?
-************************************************************/
-
-static BOOL is_oplock_break(char *inbuf)
-{
- if (CVAL(inbuf,smb_com) != SMBlockingX)
- return False;
-
- if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE))
- return False;
-
- DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
- return True;
-}
-
-/***********************************************************
- SMB signing - Server implementation - check a MAC sent by server.
-************************************************************/
-
-static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
-{
- BOOL good;
- struct smb_basic_signing_context *data = si->signing_context;
- uint32 reply_seq_number = data->send_seq_num;
- uint32 saved_seq;
- unsigned char calc_md5_mac[16];
- unsigned char *server_sent_mac;
- uint mid;
-
- if (!si->doing_signing)
- return True;
-
- if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
- return False;
- }
-
- mid = SVAL(inbuf, smb_mid);
-
- /* Is this part of a trans stream ? */
- if (data->trans_info && (data->trans_info->mid == mid)) {
- /* If so we don't increment the sequence. */
- reply_seq_number = data->trans_info->reply_seq_num;
- } else {
- /* We always increment the sequence number. */
- data->send_seq_num++;
-
- /* If we get an asynchronous oplock break reply and there
- * isn't a reply pending we need to re-sync the sequence
- * number.
- */
- if (is_oplock_break(inbuf)) {
- DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num));
- data->send_seq_num++;
- }
- }
-
- saved_seq = reply_seq_number;
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
-
- server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
- good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-
- if (!good) {
-
- DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
- (unsigned int)saved_seq));
- dump_data(5, (const char *)calc_md5_mac, 8);
-
- DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
- (unsigned int)saved_seq));
- dump_data(5, (const char *)server_sent_mac, 8);
-
-#if 1 /* JRATEST */
- {
- int i;
- reply_seq_number -= 5;
- for (i = 0; i < 10; i++, reply_seq_number++) {
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
- if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
-We were expecting seq %u\n", reply_seq_number, saved_seq ));
- break;
- }
- }
- }
-#endif /* JRATEST */
-
- } else {
- DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num));
- dump_data(10, (const char *)server_sent_mac, 8);
- }
-
- return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
-}
-
-/***********************************************************
- SMB signing - server API's.
-************************************************************/
-
-static struct smb_sign_info srv_sign_info = {
- null_sign_outgoing_message,
- null_check_incoming_message,
- null_free_signing_context,
- NULL,
- False,
- False,
- False,
- False
-};
-
-/***********************************************************
- Turn signing off or on for oplock break code.
-************************************************************/
-
-BOOL srv_oplock_set_signing(BOOL onoff)
-{
- BOOL ret = srv_sign_info.doing_signing;
- srv_sign_info.doing_signing = onoff;
- return ret;
-}
-
-/***********************************************************
- Called to validate an incoming packet from the client.
-************************************************************/
-
-BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok)
-{
- /* Check if it's a session keepalive. */
- if(CVAL(inbuf,0) == SMBkeepalive)
- return True;
-
- return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
-}
-
-/***********************************************************
- Called to sign an outgoing packet to the client.
-************************************************************/
-
-void srv_calculate_sign_mac(char *outbuf)
-{
- /* Check if it's a session keepalive. */
- /* JRA Paranioa test - do we ever generate these in the server ? */
- if(CVAL(outbuf,0) == SMBkeepalive)
- return;
-
- srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
-}
-
-/***********************************************************
- Called by server to defer an outgoing packet.
-************************************************************/
-
-void srv_defer_sign_response(uint16 mid)
-{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing)
- return;
-
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
-
- if (!data)
- return;
-
- store_sequence_for_reply(&data->outstanding_packet_list,
- mid, data->send_seq_num);
- data->send_seq_num++;
-}
-
-/***********************************************************
- Called to remove sequence records when a deferred packet is
- cancelled by mid. This should never find one....
-************************************************************/
-
-void srv_cancel_sign_response(uint16 mid)
-{
- struct smb_basic_signing_context *data;
- uint32 dummy_seq;
-
- if (!srv_sign_info.doing_signing)
- return;
-
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
-
- if (!data)
- return;
-
- DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
-
- while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
- ;
-}
-
-/***********************************************************
- Called by server negprot when signing has been negotiated.
-************************************************************/
-
-void srv_set_signing_negotiated(void)
-{
- srv_sign_info.allow_smb_signing = True;
- srv_sign_info.negotiated_smb_signing = True;
- if (lp_server_signing() == Required)
- srv_sign_info.mandatory_signing = True;
-
- srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
- srv_sign_info.check_incoming_message = temp_check_incoming_message;
- srv_sign_info.free_signing_context = temp_free_signing_context;
-}
-
-/***********************************************************
- Returns whether signing is active. We can't use sendfile or raw
- reads/writes if it is.
-************************************************************/
-
-BOOL srv_is_signing_active(void)
-{
- return srv_sign_info.doing_signing;
-}
-
-
-/***********************************************************
- Returns whether signing is negotiated. We can't use it unless it was
- in the negprot.
-************************************************************/
-
-BOOL srv_is_signing_negotiated(void)
-{
- return srv_sign_info.negotiated_smb_signing;
-}
-
-/***********************************************************
- Returns whether signing is actually happening
-************************************************************/
-
-BOOL srv_signing_started(void)
-{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing) {
- return False;
- }
-
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
- if (!data)
- return False;
-
- if (data->send_seq_num == 0) {
- return False;
- }
-
- return True;
-}
-
-
-/***********************************************************
- Tell server code we are in a multiple trans reply state.
-************************************************************/
-
-void srv_signing_trans_start(uint16 mid)
-{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing)
- return;
-
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
- if (!data)
- return;
-
- data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
- ZERO_STRUCTP(data->trans_info);
-
- data->trans_info->reply_seq_num = data->send_seq_num-1;
- data->trans_info->mid = mid;
- data->trans_info->send_seq_num = data->send_seq_num;
-
- DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
-data->send_seq_num = %u\n",
- (unsigned int)mid,
- (unsigned int)data->trans_info->reply_seq_num,
- (unsigned int)data->trans_info->send_seq_num,
- (unsigned int)data->send_seq_num ));
-}
-
-/***********************************************************
- Tell server code we are out of a multiple trans reply state.
-************************************************************/
-
-void srv_signing_trans_stop(void)
-{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing)
- return;
-
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
- if (!data || !data->trans_info)
- return;
-
- DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
-data->send_seq_num = %u\n",
- (unsigned int)data->trans_info->mid,
- (unsigned int)data->trans_info->reply_seq_num,
- (unsigned int)data->trans_info->send_seq_num,
- (unsigned int)data->send_seq_num ));
-
- SAFE_FREE(data->trans_info);
- data->trans_info = NULL;
-}
-
-/***********************************************************
- Turn on signing from this packet onwards.
-************************************************************/
-
-void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
-{
- struct smb_basic_signing_context *data;
-
- if (!user_session_key.length)
- return;
-
- if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
- DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
- (unsigned int)srv_sign_info.negotiated_smb_signing,
- (unsigned int)srv_sign_info.mandatory_signing ));
- return;
- }
-
- /* Once we've turned on, ignore any more sessionsetups. */
- if (srv_sign_info.doing_signing) {
- return;
- }
-
- if (srv_sign_info.free_signing_context)
- srv_sign_info.free_signing_context(&srv_sign_info);
-
- srv_sign_info.doing_signing = True;
-
- data = smb_xmalloc(sizeof(*data));
- memset(data, '\0', sizeof(*data));
-
- srv_sign_info.signing_context = data;
-
- data->mac_key = data_blob(NULL, response.length + user_session_key.length);
-
- memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
- if (response.length)
- memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
-
- dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
-
- DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
- BOOLSTR(srv_sign_info.negotiated_smb_signing),
- BOOLSTR(srv_sign_info.mandatory_signing) ));
-
- /* Initialise the sequence number */
- data->send_seq_num = 0;
-
- /* Initialise the list of outstanding packets */
- data->outstanding_packet_list = NULL;
-
- srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
- srv_sign_info.check_incoming_message = srv_check_incoming_message;
- srv_sign_info.free_signing_context = simple_free_signing_context;
-}
diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c
index ae946b4a660..440121d1265 100644
--- a/source/libsmb/smbdes.c
+++ b/source/libsmb/smbdes.c
@@ -48,7 +48,7 @@
#define uchar unsigned char
-static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
+static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
@@ -57,7 +57,7 @@ static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4};
-static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
+static uchar perm2[48] = {14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
@@ -66,7 +66,7 @@ static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32};
-static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
+static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
@@ -75,7 +75,7 @@ static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7};
-static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
+static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
@@ -84,7 +84,7 @@ static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1};
-static const uchar perm5[32] = { 16, 7, 20, 21,
+static uchar perm5[32] = { 16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
@@ -94,7 +94,7 @@ static const uchar perm5[32] = { 16, 7, 20, 21,
22, 11, 4, 25};
-static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
+static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
@@ -104,9 +104,9 @@ static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
33, 1, 41, 9, 49, 17, 57, 25};
-static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
-static const uchar sbox[8][4][16] = {
+static uchar sbox[8][4][16] = {
{{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
@@ -147,7 +147,7 @@ static const uchar sbox[8][4][16] = {
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
-static void permute(char *out, const char *in, const uchar *p, int n)
+static void permute(char *out, char *in, uchar *p, int n)
{
int i;
for (i=0;i<n;i++)
@@ -397,46 +397,6 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val)
}
}
-void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key)
-{
- unsigned char s_box[256];
- unsigned char index_i = 0;
- unsigned char index_j = 0;
- unsigned char j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++)
- {
- s_box[ind] = (unsigned char)ind;
- }
-
- for( ind = 0; ind < 256; ind++)
- {
- unsigned char tc;
-
- j += (s_box[ind] + key->data[ind%key->length]);
-
- tc = s_box[ind];
- s_box[ind] = s_box[j];
- s_box[j] = tc;
- }
- for( ind = 0; ind < len; ind++)
- {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += s_box[index_i];
-
- tc = s_box[index_i];
- s_box[index_i] = s_box[index_j];
- s_box[index_j] = tc;
-
- t = s_box[index_i] + s_box[index_j];
- data[ind] = data[ind] ^ s_box[t];
- }
-}
-
/* Decode a sam password hash into a password. The password hash is the
same method used to store passwords in the NT registry. The DES key
used is based on the RID of the user. */
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 3b8a375bea5..0218c87ec19 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -1,11 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1998
Modified by Jeremy Allison 1995.
- Copyright (C) Jeremy Allison 1995-2000.
- Copyright (C) Luke Kennethc Casson Leighton 1996-2000.
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,177 +21,101 @@
*/
#include "includes.h"
+
#include "byteorder.h"
/*
This implements the X/Open SMB password encryption
- It takes a password ('unix' string), a 8 byte "crypt key"
- and puts 24 bytes of encrypted password into p24 */
-void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24])
+ It takes a password, a 8 byte "crypt key" and puts 24 bytes of
+ encrypted password into p24 */
+void SMBencrypt(const uchar *passwd, uchar *c8, uchar *p24)
{
- uchar p21[21];
+ uchar p14[15], p21[21];
memset(p21,'\0',21);
- E_deshash(passwd, p21);
+ memset(p14,'\0',14);
+ StrnCpy((char *)p14,(const char *)passwd,14);
+
+ strupper((char *)p14);
+ E_P16(p14, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
dump_data(100, (char *)p21, 16);
- dump_data(100, (const char *)c8, 8);
+ dump_data(100, (char *)c8, 8);
dump_data(100, (char *)p24, 24);
#endif
}
-/**
+/*
* Creates the MD4 Hash of the users password in NT UNICODE.
- * @param passwd password in 'unix' charset.
- * @param p16 return password hashed with md4, caller allocated 16 byte buffer
*/
-void E_md4hash(const char *passwd, uchar p16[16])
+void E_md4hash(const uchar *passwd, uchar *p16)
{
int len;
- smb_ucs2_t wpwd[129];
+ int16 wpwd[129];
+ /* Password cannot be longer than 128 characters */
/* Password must be converted to NT unicode - null terminated. */
- push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE);
+ dos_struni2((char *)wpwd, (const char *)passwd, sizeof(wpwd));
/* Calculate length in bytes */
- len = strlen_w(wpwd) * sizeof(int16);
+ len = strlen_w((const smb_ucs2_t *)wpwd) * sizeof(smb_ucs2_t);
mdfour(p16, (unsigned char *)wpwd, len);
- ZERO_STRUCT(wpwd);
}
-/**
- * Creates the DES forward-only Hash of the users password in DOS ASCII charset
- * @param passwd password in 'unix' charset.
- * @param p16 return password hashed with DES, caller allocated 16 byte buffer
- * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True
- * @note p16 is filled in regardless
- */
-
-BOOL E_deshash(const char *passwd, uchar p16[16])
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
{
- BOOL ret = True;
- fstring dospwd;
- ZERO_STRUCT(dospwd);
-
- /* Password must be converted to DOS charset - null terminated, uppercase. */
- push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
-
- /* Only the fisrt 14 chars are considered, password need not be null terminated. */
- E_P16((const unsigned char *)dospwd, p16);
-
- if (strlen(dospwd) > 14) {
- ret = False;
- }
+ char passwd[514];
- ZERO_STRUCT(dospwd);
+ memset(passwd,'\0',514);
+ safe_strcpy( passwd, pwd, sizeof(passwd)-1);
- return ret;
-}
-
-/**
- * Creates the MD4 and DES (LM) Hash of the users password.
- * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password.
- * @param passwd password in 'unix' charset.
- * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer
- * @param p16 return password hashed with des, caller allocated 16 byte buffer
- */
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
-{
/* Calculate the MD4 hash (NT compatible) of the password */
memset(nt_p16, '\0', 16);
- E_md4hash(pwd, nt_p16);
+ E_md4hash((uchar *)passwd, nt_p16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
- dump_data(120, pwd, strlen(pwd));
+ dump_data(120, passwd, strlen(passwd));
dump_data(100, (char *)nt_p16, 16);
#endif
- E_deshash(pwd, (uchar *)p16);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
- dump_data(120, pwd, strlen(pwd));
- dump_data(100, (char *)p16, 16);
-#endif
-}
-
-/* Does both the NTLMv2 owfs of a user's password */
-BOOL ntv2_owf_gen(const uchar owf[16],
- const char *user_in, const char *domain_in,
- BOOL upper_case_domain, /* Transform the domain into UPPER case */
- uchar kr_buf[16])
-{
- smb_ucs2_t *user;
- smb_ucs2_t *domain;
-
- size_t user_byte_len;
- size_t domain_byte_len;
-
- HMACMD5Context ctx;
-
- user_byte_len = push_ucs2_allocate(&user, user_in);
- if (user_byte_len == (size_t)-1) {
- DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n"));
- return False;
- }
-
- domain_byte_len = push_ucs2_allocate(&domain, domain_in);
- if (domain_byte_len == (size_t)-1) {
- DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n"));
- return False;
- }
-
- strupper_w(user);
+ /* Mangle the passwords into Lanman format */
+ passwd[14] = '\0';
+ strupper(passwd);
- if (upper_case_domain)
- strupper_w(domain);
+ /* Calculate the SMB (lanman) hash functions of the password */
- SMB_ASSERT(user_byte_len >= 2);
- SMB_ASSERT(domain_byte_len >= 2);
-
- /* We don't want null termination */
- user_byte_len = user_byte_len - 2;
- domain_byte_len = domain_byte_len - 2;
-
- hmac_md5_init_limK_to_64(owf, 16, &ctx);
- hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx);
- hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx);
- hmac_md5_final(kr_buf, &ctx);
+ memset(p16, '\0', 16);
+ E_P16((uchar *) passwd, (uchar *)p16);
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
- dump_data(100, (const char *)user, user_byte_len);
- dump_data(100, (const char *)domain, domain_byte_len);
- dump_data(100, owf, 16);
- dump_data(100, kr_buf, 16);
+ DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, (char *)p16, 16);
#endif
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
- return True;
+ /* clear out local copy of user's password (just being paranoid). */
+ memset(passwd, '\0', sizeof(passwd));
}
/* Does the des encryption from the NT or LM MD4 hash. */
-void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24])
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
{
uchar p21[21];
-
- ZERO_STRUCT(p21);
+
+ memset(p21,'\0',21);
memcpy(p21, passwd, 16);
E_P24(p21, c8, p24);
}
/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24])
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
{
uchar p21[21];
@@ -205,7 +127,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p
#ifdef DEBUG_PASSWORD
DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
dump_data(100, (char *)p21, 21);
- dump_data(100, (const char *)ntlmchalresp, 8);
+ dump_data(100, (char *)ntlmchalresp, 8);
dump_data(100, (char *)p24, 24);
#endif
}
@@ -213,7 +135,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p
/* Does the NT MD4 hash then des encryption. */
-void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
+void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24)
{
uchar p21[21];
@@ -230,276 +152,101 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
#endif
}
-/* Does the md5 encryption from the Key Response for NTLMv2. */
-void SMBOWFencrypt_ntv2(const uchar kr[16],
- const DATA_BLOB *srv_chal,
- const DATA_BLOB *cli_chal,
- uchar resp_buf[16])
-{
- HMACMD5Context ctx;
-
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
- hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
- hmac_md5_final(resp_buf, &ctx);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
- dump_data(100, srv_chal->data, srv_chal->length);
- dump_data(100, cli_chal->data, cli_chal->length);
- dump_data(100, resp_buf, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv2(const uchar kr[16],
- const uchar * nt_resp, uint8 sess_key[16])
-{
- /* a very nice, 128 bit, variable session key */
-
- HMACMD5Context ctx;
-
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(nt_resp, 16, &ctx);
- hmac_md5_final((unsigned char *)sess_key, &ctx);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
- dump_data(100, sess_key, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv1(const uchar kr[16],
- const uchar * nt_resp, uint8 sess_key[16])
-{
- /* yes, this session key does not change - yes, this
- is a problem - but it is 128 bits */
-
- mdfour((unsigned char *)sess_key, kr, 16);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
- dump_data(100, sess_key, 16);
-#endif
-}
-
-void SMBsesskeygen_lmv1(const uchar lm_hash[16],
- const uchar lm_resp[24], /* only uses 8 */
- uint8 sess_key[16])
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
{
- /* Calculate the LM session key (effective length 40 bits,
- but changes with each session) */
-
- uchar p24[24];
- uchar partial_lm_hash[16];
-
- memcpy(partial_lm_hash, lm_hash, 8);
- memset(partial_lm_hash + 8, 0xbd, 8);
-
- SMBOWFencrypt(lm_hash, lm_resp, p24);
-
- memcpy(sess_key, p24, 16);
- sess_key[5] = 0xe5;
- sess_key[6] = 0x38;
- sess_key[7] = 0xb0;
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBsesskeygen_lmv1:\n"));
- dump_data(100, sess_key, 16);
-#endif
-}
+ int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
-void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
- const uchar lm_resp[24], /* only uses 8 */
- uint8 sess_key[16])
-{
- uchar p24[24];
- uchar partial_lm_hash[16];
-
- memcpy(partial_lm_hash, lm_hash, 8);
- memset(partial_lm_hash + 8, 0xbd, 8);
+ if (new_pw_len > 512)
+ {
+ DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
+ return False;
+ }
- SMBOWFencrypt(partial_lm_hash, lm_resp, p24);
-
- memcpy(sess_key, p24, 16);
+ /*
+ * Now setup the data area.
+ * We need to generate a random fill
+ * for this area to make it harder to
+ * decrypt. JRA.
+ */
+ generate_random_buffer((unsigned char *)data, 516, False);
+ if (unicode)
+ {
+ /* Note that passwd should be in DOS oem character set. */
+ dos_struni2( &data[512 - new_pw_len], passwd, 512);
+ }
+ else
+ {
+ /* Note that passwd should be in DOS oem character set. */
+ fstrcpy( &data[512 - new_pw_len], passwd);
+ }
+ SIVAL(data, 512, new_pw_len);
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n"));
- dump_data(100, sess_key, 16);
+ DEBUG(100,("make_oem_passwd_hash\n"));
+ dump_data(100, data, 516);
#endif
-}
-
-DATA_BLOB NTLMv2_generate_names_blob(const char *hostname,
- const char *domain)
-{
- DATA_BLOB names_blob = data_blob(NULL, 0);
-
- msrpc_gen(&names_blob, "aaa",
- NTLMSSP_NAME_TYPE_DOMAIN, domain,
- NTLMSSP_NAME_TYPE_SERVER, hostname,
- 0, "");
- return names_blob;
-}
-
-static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob)
-{
- uchar client_chal[8];
- DATA_BLOB response = data_blob(NULL, 0);
- char long_date[8];
-
- generate_random_buffer(client_chal, sizeof(client_chal), False);
-
- put_long_date(long_date, time(NULL));
-
- /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */
-
- msrpc_gen(&response, "ddbbdb",
- 0x00000101, /* Header */
- 0, /* 'Reserved' */
- long_date, 8, /* Timestamp */
- client_chal, 8, /* client challenge */
- 0, /* Unknown */
- names_blob->data, names_blob->length); /* End of name list */
-
- return response;
-}
-
-static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16],
- const DATA_BLOB *server_chal,
- const DATA_BLOB *names_blob)
-{
- uchar ntlmv2_response[16];
- DATA_BLOB ntlmv2_client_data;
- DATA_BLOB final_response;
-
- /* NTLMv2 */
- /* generate some data to pass into the response function - including
- the hostname and domain name of the server */
- ntlmv2_client_data = NTLMv2_generate_client_data(names_blob);
-
- /* Given that data, and the challenge from the server, generate a response */
- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);
-
- final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);
-
- memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));
+ SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);
- memcpy(final_response.data+sizeof(ntlmv2_response),
- ntlmv2_client_data.data, ntlmv2_client_data.length);
-
- data_blob_free(&ntlmv2_client_data);
-
- return final_response;
-}
-
-static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16],
- const DATA_BLOB *server_chal)
-{
- uchar lmv2_response[16];
- DATA_BLOB lmv2_client_data = data_blob(NULL, 8);
- DATA_BLOB final_response = data_blob(NULL, 24);
-
- /* LMv2 */
- /* client-supplied random data */
- generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False);
-
- /* Given that data, and the challenge from the server, generate a response */
- SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
- memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));
-
- /* after the first 16 bytes is the random data we generated above,
- so the server can verify us with it */
- memcpy(final_response.data+sizeof(lmv2_response),
- lmv2_client_data.data, lmv2_client_data.length);
-
- data_blob_free(&lmv2_client_data);
-
- return final_response;
-}
-
-BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password,
- const DATA_BLOB *server_chal,
- const DATA_BLOB *names_blob,
- DATA_BLOB *lm_response, DATA_BLOB *nt_response,
- DATA_BLOB *user_session_key)
-{
- uchar nt_hash[16];
- uchar ntlm_v2_hash[16];
- E_md4hash(password, nt_hash);
-
- /* We don't use the NT# directly. Instead we use it mashed up with
- the username and domain.
- This prevents username swapping during the auth exchange
- */
- if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
- return False;
- }
-
- if (nt_response) {
- *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal,
- names_blob);
- if (user_session_key) {
- *user_session_key = data_blob(NULL, 16);
-
- /* The NTLMv2 calculations also provide a session key, for signing etc later */
- /* use only the first 16 bytes of nt_response for session key */
- SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data);
- }
- }
-
- /* LMv2 */
-
- if (lm_response) {
- *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal);
- }
-
return True;
}
/***********************************************************
- encode a password buffer with a unicode password. The buffer
- is filled with random data to make it harder to attack.
+ Encode a password buffer.
************************************************************/
-BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
-{
- uchar new_pw[512];
- size_t new_pw_len;
-
- new_pw_len = push_string(NULL, new_pw,
- password,
- sizeof(new_pw), string_flags);
-
- memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len);
- generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set)
+{
+ generate_random_buffer((unsigned char *)buffer, 516, True);
- /*
+ if (new_pw_len < 0 || new_pw_len > 512)
+ return False;
+
+ if (nt_pass_set) {
+ new_pw_len *= 2;
+ dos_struni2(&buffer[512 - new_pw_len], new_pass, 256);
+ } else {
+ memcpy(&buffer[512 - new_pw_len], new_pass, new_pw_len);
+ }
+
+ /*
* The length of the new password is in the last 4 bytes of
* the data buffer.
*/
SIVAL(buffer, 512, new_pw_len);
- ZERO_STRUCT(new_pw);
+
return True;
}
-
/***********************************************************
decode a password buffer
- *new_pw_len is the length in bytes of the possibly mulitbyte
- returned password including termination.
************************************************************/
BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
int new_pwrd_size, uint32 *new_pw_len,
- int string_flags)
+ uchar nt_p16[16], uchar p16[16])
{
+ char *pw;
+
+ int uni_pw_len=0;
int byte_len=0;
+ char unicode_passwd[514];
+ char lm_ascii_passwd[514];
+ char passwd[514];
/*
Warning !!! : This function is called from some rpc call.
- The password IN the buffer may be a UNICODE string.
+ The password IN the buffer is a UNICODE string.
The password IN new_pwrd is an ASCII string
If you reuse that code somewhere else check first.
*/
+ ZERO_STRUCT(unicode_passwd);
+ ZERO_STRUCT(lm_ascii_passwd);
+ ZERO_STRUCT(passwd);
+
+ memset(nt_p16, '\0', 16);
+ memset(p16, '\0', 16);
+
/* The length of the new password is in the last 4 bytes of the data buffer. */
byte_len = IVAL(in_buffer, 512);
@@ -508,23 +255,72 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
dump_data(100, in_buffer, 516);
#endif
- /* Password cannot be longer than the size of the password buffer */
- if ( (byte_len < 0) || (byte_len > 512)) {
+ /* Password cannot be longer than 128 characters */
+ if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) {
DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len));
- DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n"));
return False;
}
+
+ uni_pw_len = byte_len/2;
+ pw = dos_unistrn2((uint16 *)(&in_buffer[512 - byte_len]), uni_pw_len);
+ memcpy(passwd, pw, uni_pw_len);
- /* decode into the return buffer. Buffer length supplied */
- *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size,
- byte_len, string_flags);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: passwd: "));
+ dump_data(100, (char *)passwd, uni_pw_len);
+ DEBUG(100,("len:%d\n", uni_pw_len));
+#endif
+ memcpy(unicode_passwd, &in_buffer[512 - byte_len], byte_len);
+
+ mdfour(nt_p16, (unsigned char *)unicode_passwd, byte_len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: nt#:"));
+ dump_data(100, (char *)nt_p16, 16);
+ DEBUG(100,("\n"));
+#endif
+
+ /* Mangle the passwords into Lanman format */
+ memcpy(lm_ascii_passwd, passwd, uni_pw_len);
+ lm_ascii_passwd[14] = '\0';
+ strupper(lm_ascii_passwd);
+
+ /* Calculate the SMB (lanman) hash functions of the password */
+ E_P16((uchar *) lm_ascii_passwd, (uchar *)p16);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("decode_pw_buffer: new_pwrd: "));
- dump_data(100, (char *)new_pwrd, *new_pw_len);
- DEBUG(100,("multibyte len:%d\n", *new_pw_len));
- DEBUG(100,("original char len:%d\n", byte_len/2));
+ DEBUG(100,("nt_lm_owf_gen: lm#:"));
+ dump_data(100, (char *)p16, 16);
+ DEBUG(100,("\n"));
#endif
+
+ /* copy the password and it's length to the return buffer */
+ *new_pw_len=uni_pw_len;
+ memcpy(new_pwrd, passwd, uni_pw_len);
+ new_pwrd[uni_pw_len]='\0';
+
+
+ /* clear out local copy of user's password (just being paranoid). */
+ ZERO_STRUCT(unicode_passwd);
+ ZERO_STRUCT(lm_ascii_passwd);
+ ZERO_STRUCT(passwd);
return True;
+
+}
+
+/* Calculate the NT owfs of a user's password */
+void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16])
+{
+ char buf[512];
+ int i;
+
+ for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++)
+ SIVAL(buf, i * 2, pwd->buffer[i]);
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ mdfour(nt_p16, (unsigned char *)buf, pwd->uni_str_len * 2);
+
+ /* clear out local copy of user's password (just being paranoid). */
+ ZERO_STRUCT(buf);
}
diff --git a/source/libsmb/smberr.c b/source/libsmb/smberr.c
index 82efbdb6898..7eeb4fff673 100644
--- a/source/libsmb/smberr.c
+++ b/source/libsmb/smberr.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Copyright (C) Andrew Tridgell 1998
This program is free software; you can redistribute it and/or modify
@@ -160,6 +161,7 @@ const struct
/****************************************************************************
return a SMB error name from a class and code
****************************************************************************/
+
const char *smb_dos_err_name(uint8 class, uint16 num)
{
static pstring ret;
@@ -196,6 +198,7 @@ const char *get_dos_error_msg(WERROR result)
/****************************************************************************
return a SMB error class name as a string.
****************************************************************************/
+
const char *smb_dos_err_class(uint8 class)
{
static pstring ret;
@@ -214,7 +217,8 @@ const char *smb_dos_err_class(uint8 class)
/****************************************************************************
return a SMB string from an SMB buffer
****************************************************************************/
-char *smb_dos_errstr(char *inbuf)
+
+const char *smb_dos_errstr(char *inbuf)
{
static pstring ret;
int class = CVAL(inbuf,smb_rcls);
@@ -249,6 +253,7 @@ char *smb_dos_errstr(char *inbuf)
/*****************************************************************************
map a unix errno to a win32 error
*****************************************************************************/
+
WERROR map_werror_from_unix(int error)
{
NTSTATUS status = map_nt_error_from_unix(error);
diff --git a/source/libsmb/spnego.c b/source/libsmb/spnego.c
deleted file mode 100644
index 50caf7b4c0e..00000000000
--- a/source/libsmb/spnego.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- RFC2478 Compliant SPNEGO implementation
-
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_AUTH
-
-static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
-{
- ZERO_STRUCTP(token);
-
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
-
- while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
- int i;
-
- switch (asn1->data[asn1->ofs]) {
- /* Read mechTypes */
- case ASN1_CONTEXT(0):
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
-
- token->mechTypes = malloc(sizeof(*token->mechTypes));
- for (i = 0; !asn1->has_error &&
- 0 < asn1_tag_remaining(asn1); i++) {
- token->mechTypes =
- realloc(token->mechTypes, (i + 2) *
- sizeof(*token->mechTypes));
- asn1_read_OID(asn1, token->mechTypes + i);
- }
- token->mechTypes[i] = NULL;
-
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
- break;
- /* Read reqFlags */
- case ASN1_CONTEXT(1):
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_Integer(asn1, &token->reqFlags);
- token->reqFlags |= SPNEGO_REQ_FLAG;
- asn1_end_tag(asn1);
- break;
- /* Read mechToken */
- case ASN1_CONTEXT(2):
- asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, &token->mechToken);
- asn1_end_tag(asn1);
- break;
- /* Read mecListMIC */
- case ASN1_CONTEXT(3):
- asn1_start_tag(asn1, ASN1_CONTEXT(3));
- if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
- asn1_read_OctetString(asn1,
- &token->mechListMIC);
- } else {
- /* RFC 2478 says we have an Octet String here,
- but W2k sends something different... */
- char *mechListMIC;
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_read_GeneralString(asn1, &mechListMIC);
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
-
- token->mechListMIC =
- data_blob(mechListMIC, strlen(mechListMIC));
- SAFE_FREE(mechListMIC);
- }
- asn1_end_tag(asn1);
- break;
- default:
- asn1->has_error = True;
- break;
- }
- }
-
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
-
- return !asn1->has_error;
-}
-
-static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
-{
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
-
- /* Write mechTypes */
- if (token->mechTypes && *token->mechTypes) {
- int i;
-
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
- for (i = 0; token->mechTypes[i]; i++) {
- asn1_write_OID(asn1, token->mechTypes[i]);
- }
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
- }
-
- /* write reqFlags */
- if (token->reqFlags & SPNEGO_REQ_FLAG) {
- int flags = token->reqFlags & ~SPNEGO_REQ_FLAG;
-
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_write_Integer(asn1, flags);
- asn1_pop_tag(asn1);
- }
-
- /* write mechToken */
- if (token->mechToken.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(2));
- asn1_write_OctetString(asn1, token->mechToken.data,
- token->mechToken.length);
- asn1_pop_tag(asn1);
- }
-
- /* write mechListMIC */
- if (token->mechListMIC.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(3));
-#if 0
- /* This is what RFC 2478 says ... */
- asn1_write_OctetString(asn1, token->mechListMIC.data,
- token->mechListMIC.length);
-#else
- /* ... but unfortunately this is what Windows
- sends/expects */
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_GENERAL_STRING);
- asn1_write(asn1, token->mechListMIC.data,
- token->mechListMIC.length);
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
-#endif
- asn1_pop_tag(asn1);
- }
-
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
-
- return !asn1->has_error;
-}
-
-static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
-{
- ZERO_STRUCTP(token);
-
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
-
- while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
- switch (asn1->data[asn1->ofs]) {
- case ASN1_CONTEXT(0):
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_ENUMERATED);
- asn1_read_uint8(asn1, &token->negResult);
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
- break;
- case ASN1_CONTEXT(1):
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_OID(asn1, &token->supportedMech);
- asn1_end_tag(asn1);
- break;
- case ASN1_CONTEXT(2):
- asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, &token->responseToken);
- asn1_end_tag(asn1);
- break;
- case ASN1_CONTEXT(3):
- asn1_start_tag(asn1, ASN1_CONTEXT(3));
- asn1_read_OctetString(asn1, &token->mechListMIC);
- asn1_end_tag(asn1);
- break;
- default:
- asn1->has_error = True;
- break;
- }
- }
-
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
-
- return !asn1->has_error;
-}
-
-static BOOL write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
-{
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
-
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_write_enumerated(asn1, token->negResult);
- asn1_pop_tag(asn1);
-
- if (token->supportedMech) {
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_write_OID(asn1, token->supportedMech);
- asn1_pop_tag(asn1);
- }
-
- if (token->responseToken.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(2));
- asn1_write_OctetString(asn1, token->responseToken.data,
- token->responseToken.length);
- asn1_pop_tag(asn1);
- }
-
- if (token->mechListMIC.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(3));
- asn1_write_OctetString(asn1, token->mechListMIC.data,
- token->mechListMIC.length);
- asn1_pop_tag(asn1);
- }
-
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
-
- return !asn1->has_error;
-}
-
-ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token)
-{
- ASN1_DATA asn1;
- ssize_t ret = -1;
-
- ZERO_STRUCTP(token);
- ZERO_STRUCT(asn1);
- asn1_load(&asn1, data);
-
- switch (asn1.data[asn1.ofs]) {
- case ASN1_APPLICATION(0):
- asn1_start_tag(&asn1, ASN1_APPLICATION(0));
- asn1_check_OID(&asn1, OID_SPNEGO);
- if (read_negTokenInit(&asn1, &token->negTokenInit)) {
- token->type = SPNEGO_NEG_TOKEN_INIT;
- }
- asn1_end_tag(&asn1);
- break;
- case ASN1_CONTEXT(1):
- if (read_negTokenTarg(&asn1, &token->negTokenTarg)) {
- token->type = SPNEGO_NEG_TOKEN_TARG;
- }
- break;
- default:
- break;
- }
-
- if (!asn1.has_error) ret = asn1.ofs;
- asn1_free(&asn1);
-
- return ret;
-}
-
-ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego)
-{
- ASN1_DATA asn1;
- ssize_t ret = -1;
-
- ZERO_STRUCT(asn1);
-
- switch (spnego->type) {
- case SPNEGO_NEG_TOKEN_INIT:
- asn1_push_tag(&asn1, ASN1_APPLICATION(0));
- asn1_write_OID(&asn1, OID_SPNEGO);
- write_negTokenInit(&asn1, &spnego->negTokenInit);
- asn1_pop_tag(&asn1);
- break;
- case SPNEGO_NEG_TOKEN_TARG:
- write_negTokenTarg(&asn1, &spnego->negTokenTarg);
- break;
- default:
- asn1.has_error = True;
- break;
- }
-
- if (!asn1.has_error) {
- *blob = data_blob(asn1.data, asn1.length);
- ret = asn1.ofs;
- }
- asn1_free(&asn1);
-
- return ret;
-}
-
-BOOL free_spnego_data(SPNEGO_DATA *spnego)
-{
- BOOL ret = True;
-
- if (!spnego) goto out;
-
- switch(spnego->type) {
- case SPNEGO_NEG_TOKEN_INIT:
- if (spnego->negTokenInit.mechTypes) {
- int i;
- for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) {
- free(spnego->negTokenInit.mechTypes[i]);
- }
- free(spnego->negTokenInit.mechTypes);
- }
- data_blob_free(&spnego->negTokenInit.mechToken);
- data_blob_free(&spnego->negTokenInit.mechListMIC);
- break;
- case SPNEGO_NEG_TOKEN_TARG:
- if (spnego->negTokenTarg.supportedMech) {
- free(spnego->negTokenTarg.supportedMech);
- }
- data_blob_free(&spnego->negTokenTarg.responseToken);
- data_blob_free(&spnego->negTokenTarg.mechListMIC);
- break;
- default:
- ret = False;
- break;
- }
- ZERO_STRUCTP(spnego);
-out:
- return ret;
-}
-
diff --git a/source/libsmb/trustdom_cache.c b/source/libsmb/trustdom_cache.c
deleted file mode 100644
index 0128d080062..00000000000
--- a/source/libsmb/trustdom_cache.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Trusted domain names cache on top of gencache.
-
- Copyright (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_ALL /* there's no proper class yet */
-
-#define TDOMKEY_FMT "TDOM/%s"
-#define TDOMTSKEY "TDOMCACHE/TIMESTAMP"
-
-
-/**
- * @file trustdom_cache.c
- *
- * Implementation of trusted domain names cache useful when
- * samba acts as domain member server. In such case, caching
- * domain names currently trusted gives a performance gain
- * because there's no need to query PDC each time we need
- * list of trusted domains
- **/
-
-
-/**
- * Initialise trustdom name caching system. Call gencache
- * initialisation routine to perform necessary activities.
- *
- * @return true upon successful cache initialisation or
- * false if cache init failed
- **/
-
-BOOL trustdom_cache_enable(void)
-{
- /* Init trustdom cache by calling gencache initialisation */
- if (!gencache_init()) {
- DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/**
- * Shutdown trustdom name caching system. Calls gencache
- * shutdown function.
- *
- * @return true upon successful cache close or
- * false if it failed
- **/
-
-BOOL trustdom_cache_shutdown(void)
-{
- /* Close trustdom cache by calling gencache shutdown */
- if (!gencache_shutdown()) {
- DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/**
- * Form up trustdom name key. It is based only
- * on domain name now.
- *
- * @param name trusted domain name
- * @return cache key for use in gencache mechanism
- **/
-
-static char* trustdom_cache_key(const char* name)
-{
- char* keystr = NULL;
- asprintf(&keystr, TDOMKEY_FMT, strupper_static(name));
-
- return keystr;
-}
-
-
-/**
- * Store trusted domain in gencache as the domain name (key)
- * and ip address of domain controller (value)
- *
- * @param name trusted domain name
- * @param alt_name alternative trusted domain name (used in ADS domains)
- * @param sid trusted domain's SID
- * @param timeout cache entry expiration time
- * @return true upon successful value storing or
- * false if store attempt failed
- **/
-
-BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
- time_t timeout)
-{
- char *key, *alt_key;
- fstring sid_string;
-
- /*
- * we use gecache call to avoid annoying debug messages
- * about initialised trustdom
- */
- if (!gencache_init()) return False;
-
- DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
- sid_string_static(sid), name));
-
- key = trustdom_cache_key(name);
- alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL;
-
- /* Generate string representation domain SID */
- sid_to_string(sid_string, sid);
-
- /*
- * try to put the names in the cache
- */
- if (alt_key) {
- return (gencache_set(alt_key, sid_string, timeout)
- && gencache_set(key, sid_string, timeout));
- }
-
- return gencache_set(key, sid_string, timeout);
-}
-
-
-/**
- * Fetch trusted domain's dc from the gencache.
- * This routine can also be used to check whether given
- * domain is currently trusted one.
- *
- * @param name trusted domain name
- * @param sid trusted domain's SID to be returned
- * @return true if entry is found or
- * false if has expired/doesn't exist
- **/
-
-BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid)
-{
- char *key, *value;
- time_t timeout;
-
- /* init the cache */
- if (!gencache_init()) return False;
-
- /* exit now if null pointers were passed as they're required further */
- if (!sid) return False;
-
- /* prepare a key and get the value */
- key = trustdom_cache_key(name);
- if (!key) return False;
-
- if (!gencache_get(key, &value, &timeout)) {
- DEBUG(5, ("no entry for trusted domain %s found.\n", name));
- SAFE_FREE(key);
- return False;
- } else {
- SAFE_FREE(key);
- DEBUG(5, ("trusted domain %s found (%s)\n", name, value));
- }
-
- /* convert ip string representation into in_addr structure */
- if(! string_to_sid(sid, value)) {
- sid = NULL;
- return False;
- }
-
- return True;
-}
-
-
-/*******************************************************************
- fetch the timestamp from the last update
-*******************************************************************/
-
-uint32 trustdom_cache_fetch_timestamp( void )
-{
- char *value;
- time_t timeout;
- uint32 timestamp;
-
- /* init the cache */
- if (!gencache_init())
- return False;
-
- if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
- DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
- return 0;
- }
-
- timestamp = atoi(value);
-
- return timestamp;
-}
-
-/*******************************************************************
- store the timestamp from the last update
-*******************************************************************/
-
-BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout )
-{
- fstring value;
-
- /* init the cache */
- if (!gencache_init())
- return False;
-
- fstr_sprintf(value, "%d", t );
-
- if (!gencache_set(TDOMTSKEY, value, timeout)) {
- DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
- return False;
- }
-
- return True;
-}
-
-
-/*******************************************************************
- lock the timestamp entry in the trustdom_cache
-*******************************************************************/
-
-BOOL trustdom_cache_lock_timestamp( void )
-{
- return gencache_lock_entry( TDOMTSKEY ) != -1;
-}
-
-/*******************************************************************
- unlock the timestamp entry in the trustdom_cache
-*******************************************************************/
-
-void trustdom_cache_unlock_timestamp( void )
-{
- gencache_unlock_entry( TDOMTSKEY );
-}
-
-/**
- * Delete single trustdom entry. Look at the
- * gencache_iterate definition.
- *
- **/
-
-static void flush_trustdom_name(const char* key, const char *value, time_t timeout, void* dptr)
-{
- gencache_del(key);
- DEBUG(5, ("Deleting entry %s\n", key));
-}
-
-
-/**
- * Flush all the trusted domains entries from the cache.
- **/
-
-void trustdom_cache_flush(void)
-{
- if (!gencache_init())
- return;
-
- /*
- * iterate through each TDOM cache's entry and flush it
- * by flush_trustdom_name function
- */
- gencache_iterate(flush_trustdom_name, NULL, trustdom_cache_key("*"));
- DEBUG(5, ("Trusted domains cache flushed\n"));
-}
-
-/********************************************************************
- update the trustdom_cache if needed
-********************************************************************/
-#define TRUSTDOM_UPDATE_INTERVAL 600
-
-void update_trustdom_cache( void )
-{
- char **domain_names;
- DOM_SID *dom_sids;
- uint32 num_domains;
- uint32 last_check;
- int time_diff;
- TALLOC_CTX *mem_ctx = NULL;
- time_t now = time(NULL);
- int i;
-
- /* get the timestamp. We have to initialise it if the last timestamp == 0 */
-
- if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 )
- trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
-
- time_diff = now - last_check;
-
- if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
- DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
- return;
- }
-
- /* lock the timestamp */
- if ( !trustdom_cache_lock_timestamp() )
- return;
-
- if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
- DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
- goto done;
- }
-
- /* get the domains and store them */
-
- if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names,
- &num_domains, &dom_sids) )
- {
- for ( i=0; i<num_domains; i++ ) {
- trustdom_cache_store( domain_names[i], NULL, &dom_sids[i],
- now+TRUSTDOM_UPDATE_INTERVAL);
- }
-
- trustdom_cache_store_timestamp( now, now+TRUSTDOM_UPDATE_INTERVAL );
- }
-
-done:
- /* unlock and we're done */
- trustdom_cache_unlock_timestamp();
-
- talloc_destroy( mem_ctx );
-
- return;
-}
diff --git a/source/libsmb/trusts_util.c b/source/libsmb/trusts_util.c
deleted file mode 100644
index b420e4fa081..00000000000
--- a/source/libsmb/trusts_util.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Routines to operate on various trust relationships
- * Copyright (C) Andrew Bartlett 2001
- * Copyright (C) Rafal Szczesniak 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*********************************************************
- Change the domain password on the PDC.
-
- Just changes the password betwen the two values specified.
-
- Caller must have the cli connected to the netlogon pipe
- already.
-**********************************************************/
-static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- unsigned char orig_trust_passwd_hash[16],
- unsigned char new_trust_passwd_hash[16],
- uint32 sec_channel_type)
-{
- NTSTATUS result;
-
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, lp_workgroup());
- if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) {
- DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
- nt_errstr(result)));
- return result;
- }
-
- result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
- nt_errstr(result)));
- }
- return result;
-}
-
-/*********************************************************
- Change the domain password on the PDC.
- Store the password ourselves, but use the supplied password
- Caller must have already setup the connection to the NETLOGON pipe
-**********************************************************/
-
-NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *domain,
- unsigned char orig_trust_passwd_hash[16],
- uint32 sec_channel_type)
-{
- unsigned char new_trust_passwd_hash[16];
- char *new_trust_passwd;
- char *str;
- NTSTATUS nt_status;
-
- /* Create a random machine account password */
- str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
- new_trust_passwd = talloc_strdup(mem_ctx, str);
-
- E_md4hash(new_trust_passwd, new_trust_passwd_hash);
-
- nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
- new_trust_passwd_hash, sec_channel_type);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
- timestring(False)));
- /*
- * Return the result of trying to write the new password
- * back into the trust account file.
- */
- if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- return nt_status;
-}
-
-/*********************************************************
- Change the domain password on the PDC.
- Do most of the legwork ourselfs. Caller must have
- already setup the connection to the NETLOGON pipe
-**********************************************************/
-
-NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- const char *domain)
-{
- unsigned char old_trust_passwd_hash[16];
- char *up_domain;
- uint32 sec_channel_type = 0;
-
- up_domain = talloc_strdup(mem_ctx, domain);
-
- if (!secrets_fetch_trust_account_password(domain,
- old_trust_passwd_hash,
- NULL, &sec_channel_type)) {
- DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return trust_pw_change_and_store_it(cli, mem_ctx, domain,
- old_trust_passwd_hash,
- sec_channel_type);
-
-}
-
-/*********************************************************************
- Enumerate the list of trusted domains from a DC
-*********************************************************************/
-
-BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
- char ***domain_names, uint32 *num_domains,
- DOM_SID **sids )
-{
- POLICY_HND pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- fstring dc_name;
- struct in_addr dc_ip;
- uint32 enum_ctx = 0;
- struct cli_state *cli = NULL;
- BOOL retry;
-
- *domain_names = NULL;
- *num_domains = 0;
- *sids = NULL;
-
- /* lookup a DC first */
-
- if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
- DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
- domain));
- return False;
- }
-
- /* setup the anonymous connection */
-
- result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
- "", "", "", 0, Undefined, &retry);
- if ( !NT_STATUS_IS_OK(result) )
- goto done;
-
- /* open the LSARPC_PIPE */
-
- if ( !cli_nt_session_open( cli, PI_LSARPC ) ) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* get a handle */
-
- result = cli_lsa_open_policy(cli, mem_ctx, True,
- POLICY_VIEW_LOCAL_INFORMATION, &pol);
- if ( !NT_STATUS_IS_OK(result) )
- goto done;
-
- /* Lookup list of trusted domains */
-
- result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
- num_domains, domain_names, sids);
- if ( !NT_STATUS_IS_OK(result) )
- goto done;
-
-done:
- /* cleanup */
- if (cli) {
- DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
- cli_shutdown( cli );
- }
-
- return NT_STATUS_IS_OK(result);
-}
-
diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c
index 97d6071e714..96b80e2e715 100644
--- a/source/libsmb/unexpected.c
+++ b/source/libsmb/unexpected.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
handle unexpected packets
Copyright (C) Andrew Tridgell 2000
@@ -146,7 +147,7 @@ check for a particular packet in the unexpected packet queue
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
const char *mailslot_name)
{
- TDB_CONTEXT *tdb2;
+ TDB_CONTEXT *tdb2 = NULL;
tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
if (!tdb2) return NULL;
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 47001c8b89c..20d76c9c792 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -172,8 +172,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck
}
if (lck1->start >= (lck2->start + lck2->size) ||
- lck2->start >= (lck1->start + lck1->size))
- return False;
+ lck2->start >= (lck1->start + lck1->size)) return False;
return True;
}
@@ -246,8 +245,8 @@ void brl_init(int read_only)
{
if (tdb)
return;
- tdb = tdb_open_ex(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
- read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644, smbd_tdb_log);
+ tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
+ read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
if (!tdb) {
DEBUG(0,("Failed to open byte range locking database\n"));
return;
@@ -306,7 +305,7 @@ static int lock_compare(struct lock_struct *lck1,
NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
- enum brl_type lock_type, BOOL *my_lock_ctx)
+ enum brl_type lock_type)
{
TDB_DATA kbuf, dbuf;
int count, i;
@@ -316,7 +315,6 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
static int last_failed = -1;
static br_off last_failed_start;
- *my_lock_ctx = False;
kbuf = locking_key(dev,ino);
dbuf.dptr = NULL;
@@ -345,9 +343,6 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
for (i=0; i<count; i++) {
if (brl_conflict(&locks[i], &lock)) {
status = NT_STATUS_LOCK_NOT_GRANTED;
- /* Did we block ourselves ? */
- if (brl_same_context(&locks[i].context, &lock.context))
- *my_lock_ctx = True;
goto fail;
}
#if ZERO_ZERO
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 42036cc70cf..0a75420c67c 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Locking functions
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1992-2000
@@ -98,15 +99,16 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
****************************************************************************/
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
- NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
+ NTSTATUS status;
if (!lp_locking(SNUM(conn)))
return NT_STATUS_OK;
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
+
DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
@@ -114,7 +116,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
lock_pid, sys_getpid(), conn->cnum,
offset, count,
- lock_type, my_lock_ctx);
+ lock_type);
if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
@@ -125,11 +127,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
*/
if (!set_posix_lock(fsp, offset, count, lock_type)) {
- if (errno == EACCES || errno == EAGAIN)
- status = NT_STATUS_FILE_LOCK_CONFLICT;
- else
- status = map_nt_error_from_unix(errno);
-
+ status = NT_STATUS_LOCK_NOT_GRANTED;
/*
* We failed to map - we must now remove the brl
* lock entry.
@@ -153,7 +151,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
****************************************************************************/
NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
int j, maxj = lp_lock_spin_count();
int sleeptime = lp_lock_sleep_time();
@@ -165,7 +163,7 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
ret = NT_STATUS_OK; /* to keep dumb compilers happy */
for (j = 0; j < maxj; j++) {
- status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
+ status = do_lock(fsp, conn, lock_pid, count, offset, lock_type);
if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
return status;
@@ -173,9 +171,6 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
/* if we do fail then return the first error code we got */
if (j == 0) {
ret = status;
- /* Don't spin if we blocked ourselves. */
- if (*my_lock_ctx)
- return ret;
}
if (sleeptime)
sys_usleep(sleeptime);
@@ -270,6 +265,67 @@ void locking_close_file(files_struct *fsp)
}
}
+#if 0
+/* Not currently used. JRA */
+
+/****************************************************************************
+ Delete a record if it is for a dead process, if check_self is true, then
+ delete any records belonging to this pid also (there shouldn't be any).
+ This function is only called on locking startup and shutdown.
+****************************************************************************/
+
+static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+{
+ struct locking_data *data;
+ share_mode_entry *shares;
+ int i, del_count=0;
+ pid_t mypid = sys_getpid();
+ BOOL check_self = *(BOOL *)state;
+ int ret = 0;
+
+ tdb_chainlock(tdb, kbuf);
+
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+
+ for (i=0;i<data->u.num_share_mode_entries;) {
+
+ if (check_self && (shares[i].pid == mypid)) {
+ DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n",
+ (unsigned int)shares[i].pid ));
+ } else if (!process_exists(shares[i].pid)) {
+ DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Entry for pid %u and it no longer exists !\n",
+ (unsigned int)shares[i].pid ));
+ } else {
+ /* Process exists, leave this record alone. */
+ i++;
+ continue;
+ }
+
+ data->u.num_share_mode_entries--;
+ memmove(&shares[i], &shares[i+1],
+ dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
+ del_count++;
+
+ }
+
+ /* the record has shrunk a bit */
+ dbuf.dsize -= del_count * sizeof(*shares);
+
+ /* store it back in the database */
+ if (data->u.num_share_mode_entries == 0) {
+ if (tdb_delete(ttdb, kbuf) == -1)
+ ret = -1;
+ } else {
+ if (tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE) == -1)
+ ret = -1;
+ }
+
+ tdb_chainunlock(tdb, kbuf);
+ return ret;
+}
+#endif
+
/****************************************************************************
Initialise the locking functions.
****************************************************************************/
@@ -283,10 +339,10 @@ BOOL locking_init(int read_only)
if (tdb)
return True;
- tdb = tdb_open_ex(lock_path("locking.tdb"),
+ tdb = tdb_open_log(lock_path("locking.tdb"),
0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
read_only?O_RDONLY:O_RDWR|O_CREAT,
- 0644, smbd_tdb_log);
+ 0644);
if (!tdb) {
DEBUG(0,("ERROR: Failed to initialise locking database\n"));
@@ -387,8 +443,8 @@ char *share_mode_str(int num, share_mode_entry *e)
static pstring share_str;
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
-pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
- num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
+pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
+ num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
(unsigned int)e->dev, (double)e->inode );
return share_str;
@@ -422,10 +478,10 @@ int get_share_modes(connection_struct *conn,
struct locking_data *data;
int num_share_modes;
share_mode_entry *shares = NULL;
- TDB_DATA key = locking_key(dev, inode);
+
*pp_shares = NULL;
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return 0;
@@ -472,7 +528,7 @@ int get_share_modes(connection_struct *conn,
/* The record has shrunk a bit */
dbuf.dsize -= del_count * sizeof(share_mode_entry);
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) {
SAFE_FREE(shares);
SAFE_FREE(dbuf.dptr);
return 0;
@@ -547,13 +603,12 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
int i, del_count=0;
share_mode_entry *shares;
ssize_t count = 0;
- TDB_DATA key = locking_key(dev, inode);
if (ppse)
*ppse = NULL;
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return -1;
@@ -594,10 +649,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
/* store it back in the database */
if (data->u.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
count = -1;
} else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
count = -1;
}
}
@@ -634,11 +689,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
struct locking_data *data;
char *p=NULL;
int size;
- TDB_DATA key = locking_key_fsp(fsp);
BOOL ret = True;
/* read in the existing share modes if any */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
if (!dbuf.dptr) {
size_t offset;
/* we'll need to create a new record */
@@ -663,7 +717,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
dbuf.dptr = p;
dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
print_share_mode_table((struct locking_data *)p);
@@ -682,10 +736,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
size = dbuf.dsize + sizeof(share_mode_entry);
p = malloc(size);
- if (!p) {
- SAFE_FREE(dbuf.dptr);
+ if (!p)
return False;
- }
memcpy(p, dbuf.dptr, sizeof(*data));
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
@@ -693,7 +745,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
SAFE_FREE(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
print_share_mode_table((struct locking_data *)p);
SAFE_FREE(p);
@@ -714,10 +766,9 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
share_mode_entry *shares;
BOOL need_store=False;
BOOL ret = True;
- TDB_DATA key = locking_key(dev, inode);
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return False;
@@ -735,10 +786,10 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
/* if the mod fn was called then store it back */
if (need_store) {
if (data->u.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
ret = False;
} else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
ret = False;
}
}
@@ -814,10 +865,9 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
struct locking_data *data;
int i;
share_mode_entry *shares;
- TDB_DATA key = locking_key(dev, inode);
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return False;
@@ -833,7 +883,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
/* store it back */
if (data->u.num_share_mode_entries) {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
+ if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) {
SAFE_FREE(dbuf.dptr);
return False;
}
diff --git a/source/locking/posix.c b/source/locking/posix.c
index 6173c80b2fd..553b8b1c57f 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Locking functions
Copyright (C) Jeremy Allison 1992-2000
@@ -149,9 +150,8 @@ static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
+ if (!dbuf.dptr)
return 0;
- }
*entries = (int *)dbuf.dptr;
count = (size_t)(dbuf.dsize / sizeof(int));
@@ -176,9 +176,8 @@ static size_t get_posix_lock_entries(files_struct *fsp, struct posix_lock **entr
dbuf = tdb_fetch(posix_lock_tdb, kbuf);
- if (!dbuf.dptr) {
+ if (!dbuf.dptr)
return 0;
- }
*entries = (struct posix_lock *)dbuf.dptr;
count = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
@@ -205,7 +204,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
/*
* No POSIX to worry about, just close.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fd);
+ ret = conn->vfs_ops.close(fsp,fsp->fd);
fsp->fd = -1;
return ret;
}
@@ -259,7 +258,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
for(i = 0; i < count; i++) {
- if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) {
+ if (conn->vfs_ops.close(fsp,fd_array[i]) == -1) {
saved_errno = errno;
}
}
@@ -278,12 +277,12 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
* Finally close the fd associated with this fsp.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fd);
+ ret = conn->vfs_ops.close(fsp,fsp->fd);
if (saved_errno != 0) {
- errno = saved_errno;
+ errno = saved_errno;
ret = -1;
- }
+ }
fsp->fd = -1;
@@ -527,12 +526,12 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
return F_WRLCK;
}
- /*
- * This return should be the most normal, as we attempt
- * to always open files read/write.
- */
+ /*
+ * This return should be the most normal, as we attempt
+ * to always open files read/write.
+ */
- return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK;
+ return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK;
}
/****************************************************************************
@@ -563,9 +562,9 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
* and the underlying system can handle 64 bit signed locks.
*/
- SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<1);
- SMB_OFF_T max_positive_lock_offset = ~mask;
+ SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
+ SMB_OFF_T mask = (mask2<<1);
+ SMB_OFF_T max_positive_lock_offset = ~mask;
#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
@@ -575,7 +574,7 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
* All offsets & counts must be 2^31 or less.
*/
- SMB_OFF_T max_positive_lock_offset = 0x7FFFFFFF;
+ SMB_OFF_T max_positive_lock_offset = 0x7FFFFFFF;
#endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
@@ -646,10 +645,11 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
int ret;
+ struct connection_struct *conn = fsp->conn;
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
- ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
+ ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
@@ -673,7 +673,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
errno = 0;
count &= 0x7fffffff;
- ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
+ ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
}
}
@@ -719,10 +719,10 @@ BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_co
*/
struct lock_list {
- struct lock_list *next;
- struct lock_list *prev;
- SMB_OFF_T start;
- SMB_OFF_T size;
+ struct lock_list *next;
+ struct lock_list *prev;
+ SMB_OFF_T start;
+ SMB_OFF_T size;
};
/****************************************************************************
@@ -997,7 +997,7 @@ BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_cou
* semantics that if a write lock is added, then it will be first in the array.
*/
- if ((l_ctx = talloc_init("set_posix_lock")) == NULL) {
+ if ((l_ctx = talloc_init()) == NULL) {
DEBUG(0,("set_posix_lock: unable to init talloc context.\n"));
return True; /* Not a fatal error. */
}
@@ -1143,7 +1143,7 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u
}
}
- if ((ul_ctx = talloc_init("release_posix_lock")) == NULL) {
+ if ((ul_ctx = talloc_init()) == NULL) {
DEBUG(0,("release_posix_lock: unable to init talloc context.\n"));
return True; /* Not a fatal error. */
}
diff --git a/source/mainpage.dox b/source/mainpage.dox
deleted file mode 100644
index 8b72f804627..00000000000
--- a/source/mainpage.dox
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
-
-@mainpage
-
-@li \ref CodingSuggestions
-
-**/
diff --git a/source/modules/CP437.c b/source/modules/CP437.c
deleted file mode 100644
index 620f6cd9b69..00000000000
--- a/source/modules/CP437.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Conversion table for CP437 charset also known as IBM437
- *
- * Copyright (C) Alexander Bokovoy 2003
- *
- * Conversion tables are generated using GNU libc 2.2.5's
- * localedata/charmaps/IBM437 table and source/script/gen-8bit-gap.sh script
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-static const uint16 to_ucs2[256] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
- 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
- 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
- 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
- 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
- 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
- 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
- 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
- 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
- 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
- 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
- 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
- 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
- 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
- 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
-};
-
-static const struct charset_gap_table from_idx[] = {
- { 0x0000, 0x007f, 0 },
- { 0x00a0, 0x00c9, -32 },
- { 0x00d1, 0x00ff, -39 },
- { 0x0192, 0x0192, -185 },
- { 0x0393, 0x0398, -697 },
- { 0x03a3, 0x03a9, -707 },
- { 0x03b1, 0x03b5, -714 },
- { 0x03c0, 0x03c6, -724 },
- { 0x207f, 0x207f, -8076 },
- { 0x20a7, 0x20a7, -8115 },
- { 0x2219, 0x221e, -8484 },
- { 0x2229, 0x2229, -8494 },
- { 0x2248, 0x2248, -8524 },
- { 0x2261, 0x2265, -8548 },
- { 0x2310, 0x2310, -8718 },
- { 0x2320, 0x2321, -8733 },
- { 0x2500, 0x2502, -9211 },
- { 0x250c, 0x251c, -9220 },
- { 0x2524, 0x2524, -9227 },
- { 0x252c, 0x252c, -9234 },
- { 0x2534, 0x2534, -9241 },
- { 0x253c, 0x253c, -9248 },
- { 0x2550, 0x256c, -9267 },
- { 0x2580, 0x2593, -9286 },
- { 0x25a0, 0x25a0, -9298 },
- { 0xffff, 0xffff, 0 }
-};
-
-static const unsigned char from_ucs2[] = {
-
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00,
- 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00,
- 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa,
- 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8,
- 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80,
- 0x00, 0x90, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00,
- 0xe1, 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91,
- 0x87, 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c,
- 0x8b, 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94,
- 0xf6, 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00,
- 0x98, 0x9f, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xe9,
- 0xe4, 0x00, 0x00, 0xe8, 0x00, 0x00, 0xea, 0xe0,
- 0x00, 0x00, 0xeb, 0xee, 0xe3, 0x00, 0x00, 0xe5,
- 0xe7, 0x00, 0xed, 0xfc, 0x9e, 0xf9, 0xfb, 0x00,
- 0x00, 0x00, 0xec, 0xef, 0xf7, 0xf0, 0x00, 0x00,
- 0xf3, 0xf2, 0xa9, 0xf4, 0xf5, 0xc4, 0x00, 0xb3,
- 0xda, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00,
- 0xc0, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00,
- 0xc3, 0xb4, 0xc2, 0xc1, 0xc5, 0xcd, 0xba, 0xd5,
- 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, 0xd4, 0xd3, 0xc8,
- 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, 0xcc, 0xb5, 0xb6,
- 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, 0xd0, 0xca, 0xd8,
- 0xd7, 0xce, 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00,
- 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00,
- 0x00, 0x00, 0xde, 0xb0, 0xb1, 0xb2, 0xfe,
-};
-
-SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CP437)
diff --git a/source/modules/CP850.c b/source/modules/CP850.c
deleted file mode 100644
index e6f70aa17af..00000000000
--- a/source/modules/CP850.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Conversion table for CP850 charset also known as IBM850.
- *
- * Copyright (C) Alexander Bokovoy 2003
- *
- * Conversion tables are generated using GNU libc 2.2.5's
- * localedata/charmaps/IBM850 table and source/script/gen-8bit-gap.sh script
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-static const uint16 to_ucs2[256] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
- 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
- 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
- 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
- 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
- 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
- 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
- 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
- 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
- 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
- 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
- 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
- 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
- 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
- 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
- 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0,
-};
-
-static const struct charset_gap_table from_idx[] = {
- /* start, end, idx */
- { 0x0000, 0x007f, 0 },
- { 0x00a0, 0x00ff, -32 },
- { 0x0131, 0x0131, -81 },
- { 0x0192, 0x0192, -177 },
- { 0x2017, 0x2017, -7989 },
- { 0x2500, 0x2502, -9245 },
- { 0x250c, 0x251c, -9254 },
- { 0x2524, 0x2524, -9261 },
- { 0x252c, 0x252c, -9268 },
- { 0x2534, 0x2534, -9275 },
- { 0x253c, 0x253c, -9282 },
- { 0x2550, 0x256c, -9301 },
- { 0x2580, 0x2588, -9320 },
- { 0x2591, 0x2593, -9328 },
- { 0x25a0, 0x25a0, -9340 },
- { 0xffff, 0xffff, 0 }
-};
-static const unsigned char from_ucs2[] = {
-
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5,
- 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee,
- 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa,
- 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8,
- 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80,
- 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8,
- 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e,
- 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1,
- 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87,
- 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
- 0xd0, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6,
- 0x9b, 0x97, 0xa3, 0x96, 0x81, 0xec, 0xe7, 0x98,
- 0xd5, 0x9f, 0xf2, 0xc4, 0x00, 0xb3, 0xda, 0x00,
- 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00,
- 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xc3, 0xb4,
- 0xc2, 0xc1, 0xc5, 0xcd, 0xba, 0x00, 0x00, 0xc9,
- 0x00, 0x00, 0xbb, 0x00, 0x00, 0xc8, 0x00, 0x00,
- 0xbc, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xb9, 0x00,
- 0x00, 0xcb, 0x00, 0x00, 0xca, 0x00, 0x00, 0xce,
- 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
- 0xdb, 0xb0, 0xb1, 0xb2, 0xfe,
-};
-
-SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CP850)
-
diff --git a/source/modules/charset_macosxfs.c b/source/modules/charset_macosxfs.c
deleted file mode 100644
index 6f50d879ba4..00000000000
--- a/source/modules/charset_macosxfs.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba charset module for Mac OS X/Darwin
- Copyright (C) Benjamin Riefenstahl 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * modules/charset_macosxfs.c
- *
- * A Samba charset module to use on Mac OS X/Darwin as the filesystem
- * and display encoding.
- *
- * Actually two implementations are provided here. The default
- * implementation is based on the official CFString API. The other is
- * based on internal CFString APIs as defined in the OpenDarwin
- * source.
- */
-
-#include "includes.h"
-
-/*
- * Include OS frameworks. These are only needed in this module.
- */
-#include <CoreFoundation/CFString.h>
-
-/*
- * See if autoconf has found us the internal headers in some form.
- */
-#if HAVE_COREFOUNDATION_CFSTRINGENCODINGCONVERTER_H
-# include <Corefoundation/CFStringEncodingConverter.h>
-# include <Corefoundation/CFUnicodePrecomposition.h>
-# define USE_INTERNAL_API 1
-#elif HAVE_CFSTRINGENCODINGCONVERTER_H
-# include <CFStringEncodingConverter.h>
-# include <CFUnicodePrecomposition.h>
-# define USE_INTERNAL_API 1
-#endif
-
-/*
- * Compile time configuration: Do we want debug output?
- */
-/* #define DEBUG_STRINGS 1 */
-
-/*
- * A simple, but efficient memory provider for our buffers.
- */
-static inline void *resize_buffer (void *buffer, size_t *size, size_t newsize)
-{
- if (newsize > *size) {
- *size = newsize + 128;
- buffer = realloc(buffer, *size);
- }
- return buffer;
-}
-
-/*
- * While there is a version of OpenDarwin for intel, the usual case is
- * big-endian PPC. So we need byte swapping to handle the
- * little-endian byte order of the network protocol. We also need an
- * additional dynamic buffer to do this work for incoming data blocks,
- * because we have to consider the original data as constant.
- *
- * We abstract the differences away by providing a simple facade with
- * these functions/macros:
- *
- * le_to_native(dst,src,len)
- * native_to_le(cp,len)
- * set_ucbuffer_with_le(buffer,bufsize,data,size)
- * set_ucbuffer_with_le_copy(buffer,bufsize,data,size,reserve)
- */
-#ifdef WORDS_BIGENDIAN
-
-static inline void swap_bytes (char * dst, const char * src, size_t len)
-{
- const char *srcend = src + len;
- while (src < srcend) {
- dst[0] = src[1];
- dst[1] = src[0];
- dst += 2;
- src += 2;
- }
-}
-static inline void swap_bytes_inplace (char * cp, size_t len)
-{
- char temp;
- char *end = cp + len;
- while (cp < end) {
- temp = cp[1];
- cp[1] = cp[0];
- cp[0] = temp;
- cp += 2;
- }
-}
-
-#define le_to_native(dst,src,len) swap_bytes(dst,src,len)
-#define native_to_le(cp,len) swap_bytes_inplace(cp,len)
-#define set_ucbuffer_with_le(buffer,bufsize,data,size) \
- set_ucbuffer_with_le_copy(buffer,bufsize,data,size,0)
-
-#else /* ! WORDS_BIGENDIAN */
-
-#define le_to_native(dst,src,len) memcpy(dst,src,len)
-#define native_to_le(cp,len) /* nothing */
-#define set_ucbuffer_with_le(buffer,bufsize,data,size) \
- (((void)(bufsize)),(UniChar*)(data))
-
-#endif
-
-static inline UniChar *set_ucbuffer_with_le_copy (
- UniChar *buffer, size_t *bufsize,
- const void *data, size_t size, size_t reserve)
-{
- buffer = resize_buffer(buffer, bufsize, size+reserve);
- le_to_native((char*)buffer,data,size);
- return buffer;
-}
-
-
-/*
- * A simple hexdump function for debugging error conditions.
- */
-#define debug_out(s) DEBUG(0,(s))
-
-#ifdef DEBUG_STRINGS
-
-static void hexdump( const char * label, const char * s, size_t len )
-{
- size_t restlen = len;
- debug_out("<<<<<<<\n");
- debug_out(label);
- debug_out("\n");
- while (restlen > 0) {
- char line[100];
- size_t i, j;
- char * d = line;
-#undef sprintf
- d += sprintf(d, "%04X ", (unsigned)(len-restlen));
- *d++ = ' ';
- for( i = 0; i<restlen && i<8; ++i ) {
- d += sprintf(d, "%02X ", ((unsigned)s[i]) & 0xFF);
- }
- for( j = i; j<8; ++j ) {
- d += sprintf(d, " ");
- }
- *d++ = ' ';
- for( i = 8; i<restlen && i<16; ++i ) {
- d += sprintf(d, "%02X ", ((unsigned)s[i]) & 0xFF);
- }
- for( j = i; j<16; ++j ) {
- d += sprintf(d, " ");
- }
- *d++ = ' ';
- for( i = 0; i<restlen && i<16; ++i ) {
- if(s[i] < ' ' || s[i] >= 0x7F || !isprint(s[i]))
- *d++ = '.';
- else
- *d++ = s[i];
- }
- *d++ = '\n';
- *d = 0;
- restlen -= i;
- s += i;
- debug_out(line);
- }
- debug_out(">>>>>>>\n");
-}
-
-#else /* !DEBUG_STRINGS */
-
-#define hexdump(label,s,len) /* nothing */
-
-#endif
-
-
-#if !USE_INTERNAL_API
-
-/*
- * An implementation based on documented Mac OS X APIs.
- *
- * This does a certain amount of memory management, creating and
- * manipulating CFString objects. We try to minimize the impact by
- * keeping those objects around and re-using them. We also use
- * external backing store for the CFStrings where this is possible and
- * benficial.
- *
- * The Unicode normalizations forms available at this level are
- * generic, not specifically for the file system. So they may not be
- * perfect fits.
- */
-static size_t macosxfs_encoding_pull(
- void *cd, /* Encoder handle */
- char **inbuf, size_t *inbytesleft, /* Script string */
- char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */
-{
- static const int script_code = kCFStringEncodingUTF8;
- static CFMutableStringRef cfstring = NULL;
- size_t outsize;
- CFRange range;
-
- (void) cd; /* UNUSED */
-
- if (0 == *inbytesleft) {
- return 0;
- }
-
- if (NULL == cfstring) {
- /*
- * A version with an external backing store as in the
- * push function should have been more efficient, but
- * testing shows, that it is actually slower (!).
- * Maybe kCFAllocatorDefault gets shortcut evaluation
- * internally, while kCFAllocatorNull doesn't.
- */
- cfstring = CFStringCreateMutable(kCFAllocatorDefault,0);
- }
-
- /*
- * Three methods of appending to a CFString, choose the most
- * efficient.
- */
- if (0 == (*inbuf)[*inbytesleft-1]) {
- CFStringAppendCString(cfstring, *inbuf, script_code);
- } else if (*inbytesleft <= 255) {
- Str255 buffer;
- buffer[0] = *inbytesleft;
- memcpy(buffer+1, *inbuf, buffer[0]);
- CFStringAppendPascalString(cfstring, buffer, script_code);
- } else {
- /*
- * We would like to use a fixed buffer and a loop
- * here, but than we can't garantee that the input is
- * well-formed UTF-8, as we are supposed to do.
- */
- static char *buffer = NULL;
- static size_t buflen = 0;
- buffer = resize_buffer(buffer, &buflen, *inbytesleft+1);
- memcpy(buffer, *inbuf, *inbytesleft);
- buffer[*inbytesleft] = 0;
- CFStringAppendCString(cfstring, *inbuf, script_code);
- }
-
- /*
- * Compose characters, using the non-canonical composition
- * form.
- */
- CFStringNormalize(cfstring, kCFStringNormalizationFormC);
-
- outsize = CFStringGetLength(cfstring);
- range = CFRangeMake(0,outsize);
-
- if (outsize == 0) {
- /*
- * HACK: smbd/mangle_hash2.c:is_legal_name() expects
- * errors here. That function will always pass 2
- * characters. smbd/open.c:check_for_pipe() cuts a
- * patchname to 10 characters blindly. Suppress the
- * debug output in those cases.
- */
- if(2 != *inbytesleft && 10 != *inbytesleft) {
- debug_out("String conversion: "
- "An unknown error occurred\n");
- hexdump("UTF8->UTF16LE (old) input",
- *inbuf, *inbytesleft);
- }
- errno = EILSEQ; /* Not sure, but this is what we have
- * actually seen. */
- return -1;
- }
- if (outsize*2 > *outbytesleft) {
- CFStringDelete(cfstring, range);
- debug_out("String conversion: "
- "Output buffer too small\n");
- hexdump("UTF8->UTF16LE (old) input",
- *inbuf, *inbytesleft);
- errno = E2BIG;
- return -1;
- }
-
- CFStringGetCharacters(cfstring, range, (UniChar*)*outbuf);
- CFStringDelete(cfstring, range);
-
- native_to_le(*outbuf, outsize*2);
-
- /*
- * Add a converted null byte, if the CFString conversions
- * prevented that until now.
- */
- if (0 == (*inbuf)[*inbytesleft-1] &&
- (0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) {
-
- if ((outsize*2+2) > *outbytesleft) {
- debug_out("String conversion: "
- "Output buffer too small\n");
- hexdump("UTF8->UTF16LE (old) input",
- *inbuf, *inbytesleft);
- errno = E2BIG;
- return -1;
- }
-
- (*outbuf)[outsize*2] = (*outbuf)[outsize*2+1] = 0;
- outsize += 2;
- }
-
- *inbuf += *inbytesleft;
- *inbytesleft = 0;
- *outbuf += outsize*2;
- *outbytesleft -= outsize*2;
-
- return 0;
-}
-
-static size_t macosxfs_encoding_push(
- void *cd, /* Encoder handle */
- char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */
- char **outbuf, size_t *outbytesleft) /* Script string */
-{
- static const int script_code = kCFStringEncodingUTF8;
- static CFMutableStringRef cfstring = NULL;
- static UniChar *buffer = NULL;
- static size_t buflen = 0;
- CFIndex outsize, cfsize, charsconverted;
-
- (void) cd; /* UNUSED */
-
- if (0 == *inbytesleft) {
- return 0;
- }
-
- /*
- * We need a buffer that can hold 4 times the original data,
- * because that is the theoretical maximum that decomposition
- * can create currently (in Unicode 4.0).
- */
- buffer = set_ucbuffer_with_le_copy(
- buffer, &buflen, *inbuf, *inbytesleft, 3 * *inbytesleft);
-
- if (NULL == cfstring) {
- cfstring = CFStringCreateMutableWithExternalCharactersNoCopy(
- kCFAllocatorDefault,
- buffer, *inbytesleft/2, buflen/2,
- kCFAllocatorNull);
- } else {
- CFStringSetExternalCharactersNoCopy(
- cfstring,
- buffer, *inbytesleft/2, buflen/2);
- }
-
- /*
- * Decompose characters, using the non-canonical decomposition
- * form.
- *
- * NB: This isn't exactly what HFS+ wants (see note on
- * kCFStringEncodingUseHFSPlusCanonical in
- * CFStringEncodingConverter.h), but AFAIK it's the best that
- * the official API can do.
- */
- CFStringNormalize(cfstring, kCFStringNormalizationFormD);
-
- cfsize = CFStringGetLength(cfstring);
- charsconverted = CFStringGetBytes(
- cfstring, CFRangeMake(0,cfsize),
- script_code, 0, False,
- *outbuf, *outbytesleft, &outsize);
-
- if (0 == charsconverted) {
- debug_out("String conversion: "
- "Buffer too small or not convertable\n");
- hexdump("UTF16LE->UTF8 (old) input",
- *inbuf, *inbytesleft);
- errno = EILSEQ; /* Probably more likely. */
- return -1;
- }
-
- /*
- * Add a converted null byte, if the CFString conversions
- * prevented that until now.
- */
- if (0 == (*inbuf)[*inbytesleft-1] && 0 == (*inbuf)[*inbytesleft-2] &&
- (0 != (*outbuf)[outsize-1])) {
-
- if (((size_t)outsize+1) > *outbytesleft) {
- debug_out("String conversion: "
- "Output buffer too small\n");
- hexdump("UTF16LE->UTF8 (old) input",
- *inbuf, *inbytesleft);
- errno = E2BIG;
- return -1;
- }
-
- (*outbuf)[outsize] = 0;
- ++outsize;
- }
-
- *inbuf += *inbytesleft;
- *inbytesleft = 0;
- *outbuf += outsize;
- *outbytesleft -= outsize;
-
- return 0;
-}
-
-#else /* USE_INTERNAL_API */
-
-/*
- * An implementation based on internal code as known from the
- * OpenDarwin CVS.
- *
- * This code doesn't need much memory management because it uses
- * functions that operate on the raw memory directly.
- *
- * The push routine here is faster and more compatible with HFS+ than
- * the other implementation above. The pull routine is only faster
- * for some strings, slightly slower for others. The pull routine
- * looses because it has to iterate over the data twice, once to
- * decode UTF-8 and than to do the character composition required by
- * Windows.
- */
-static size_t macosxfs_encoding_pull(
- void *cd, /* Encoder handle */
- char **inbuf, size_t *inbytesleft, /* Script string */
- char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */
-{
- static const int script_code = kCFStringEncodingUTF8;
- UInt32 srcCharsUsed = 0;
- UInt32 dstCharsUsed = 0;
- UInt32 result;
- uint32_t dstDecomposedUsed = 0;
- uint32_t dstPrecomposedUsed = 0;
-
- (void) cd; /* UNUSED */
-
- if (0 == *inbytesleft) {
- return 0;
- }
-
- result = CFStringEncodingBytesToUnicode(
- script_code, kCFStringEncodingComposeCombinings,
- *inbuf, *inbytesleft, &srcCharsUsed,
- (UniChar*)*outbuf, *outbytesleft, &dstCharsUsed);
-
- switch(result) {
- case kCFStringEncodingConversionSuccess:
- if (*inbytesleft == srcCharsUsed)
- break;
- else
- ; /*fall through*/
- case kCFStringEncodingInsufficientOutputBufferLength:
- debug_out("String conversion: "
- "Output buffer too small\n");
- hexdump("UTF8->UTF16LE (new) input",
- *inbuf, *inbytesleft);
- errno = E2BIG;
- return -1;
- case kCFStringEncodingInvalidInputStream:
- /*
- * HACK: smbd/mangle_hash2.c:is_legal_name() expects
- * errors here. That function will always pass 2
- * characters. smbd/open.c:check_for_pipe() cuts a
- * patchname to 10 characters blindly. Suppress the
- * debug output in those cases.
- */
- if(2 != *inbytesleft && 10 != *inbytesleft) {
- debug_out("String conversion: "
- "Invalid input sequence\n");
- hexdump("UTF8->UTF16LE (new) input",
- *inbuf, *inbytesleft);
- }
- errno = EILSEQ;
- return -1;
- case kCFStringEncodingConverterUnavailable:
- debug_out("String conversion: "
- "Unknown encoding\n");
- hexdump("UTF8->UTF16LE (new) input",
- *inbuf, *inbytesleft);
- errno = EINVAL;
- return -1;
- }
-
- /*
- * It doesn't look like CFStringEncodingBytesToUnicode() can
- * produce precomposed characters (flags=ComposeCombinings
- * doesn't do it), so we need another pass over the data here.
- * We can do this in-place, as the string can only get
- * shorter.
- *
- * (Actually in theory there should be an internal
- * decomposition and reordering before the actual composition
- * step. But we should be able to rely on that we always get
- * fully decomposed strings for input, so this can't create
- * problems in reality.)
- */
- CFUniCharPrecompose(
- (const UTF16Char *)*outbuf, dstCharsUsed, &dstDecomposedUsed,
- (UTF16Char *)*outbuf, dstCharsUsed, &dstPrecomposedUsed);
-
- native_to_le(*outbuf, dstPrecomposedUsed*2);
-
- *inbuf += srcCharsUsed;
- *inbytesleft -= srcCharsUsed;
- *outbuf += dstPrecomposedUsed*2;
- *outbytesleft -= dstPrecomposedUsed*2;
-
- return 0;
-}
-
-static size_t macosxfs_encoding_push(
- void *cd, /* Encoder handle */
- char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */
- char **outbuf, size_t *outbytesleft) /* Script string */
-{
- static const int script_code = kCFStringEncodingUTF8;
- static UniChar *buffer = NULL;
- static size_t buflen = 0;
- UInt32 srcCharsUsed=0, dstCharsUsed=0, result;
-
- (void) cd; /* UNUSED */
-
- if (0 == *inbytesleft) {
- return 0;
- }
-
- buffer = set_ucbuffer_with_le(
- buffer, &buflen, *inbuf, *inbytesleft);
-
- result = CFStringEncodingUnicodeToBytes(
- script_code, kCFStringEncodingUseHFSPlusCanonical,
- buffer, *inbytesleft/2, &srcCharsUsed,
- *outbuf, *outbytesleft, &dstCharsUsed);
-
- switch(result) {
- case kCFStringEncodingConversionSuccess:
- if (*inbytesleft/2 == srcCharsUsed)
- break;
- else
- ; /*fall through*/
- case kCFStringEncodingInsufficientOutputBufferLength:
- debug_out("String conversion: "
- "Output buffer too small\n");
- hexdump("UTF16LE->UTF8 (new) input",
- *inbuf, *inbytesleft);
- errno = E2BIG;
- return -1;
- case kCFStringEncodingInvalidInputStream:
- /*
- * HACK: smbd/open.c:check_for_pipe():is_legal_name()
- * cuts a pathname to 10 characters blindly. Suppress
- * the debug output in those cases.
- */
- if(10 != *inbytesleft) {
- debug_out("String conversion: "
- "Invalid input sequence\n");
- hexdump("UTF16LE->UTF8 (new) input",
- *inbuf, *inbytesleft);
- }
- errno = EILSEQ;
- return -1;
- case kCFStringEncodingConverterUnavailable:
- debug_out("String conversion: "
- "Unknown encoding\n");
- hexdump("UTF16LE->UTF8 (new) input",
- *inbuf, *inbytesleft);
- errno = EINVAL;
- return -1;
- }
-
- *inbuf += srcCharsUsed*2;
- *inbytesleft -= srcCharsUsed*2;
- *outbuf += dstCharsUsed;
- *outbytesleft -= dstCharsUsed;
-
- return 0;
-}
-
-#endif /* USE_INTERNAL_API */
-
-/*
- * For initialization, actually install the encoding as "macosxfs".
- */
-static struct charset_functions macosxfs_encoding_functions = {
- "MACOSXFS", macosxfs_encoding_pull, macosxfs_encoding_push
-};
-
-NTSTATUS init_module(void)
-{
- return smb_register_charset(&macosxfs_encoding_functions);
-}
-
-/* eof */
diff --git a/source/modules/developer.c b/source/modules/developer.c
deleted file mode 100644
index 7ffc3ff50d2..00000000000
--- a/source/modules/developer.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba module with developer tools
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static struct {
- char from;
- char *to;
- int len;
-} weird_table[] = {
- {'q', "^q^", 3},
- {'Q', "^Q^", 3},
- {0, NULL}
-};
-
-static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- int i;
- int done = 0;
- for (i=0;weird_table[i].from;i++) {
- if (strncmp((*inbuf),
- weird_table[i].to,
- weird_table[i].len) == 0) {
- if (*inbytesleft < weird_table[i].len) {
- DEBUG(0,("ERROR: truncated weird string\n"));
- /* smb_panic("weird_pull"); */
-
- } else {
- (*outbuf)[0] = weird_table[i].from;
- (*outbuf)[1] = 0;
- (*inbytesleft) -= weird_table[i].len;
- (*outbytesleft) -= 2;
- (*inbuf) += weird_table[i].len;
- (*outbuf) += 2;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
- (*outbuf)[0] = (*inbuf)[0];
- (*outbuf)[1] = 0;
- (*inbytesleft) -= 1;
- (*outbytesleft) -= 2;
- (*inbuf) += 1;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int ir_count=0;
-
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- int i;
- int done=0;
- for (i=0;weird_table[i].from;i++) {
- if ((*inbuf)[0] == weird_table[i].from &&
- (*inbuf)[1] == 0) {
- if (*outbytesleft < weird_table[i].len) {
- DEBUG(0,("No room for weird character\n"));
- /* smb_panic("weird_push"); */
- } else {
- memcpy(*outbuf, weird_table[i].to,
- weird_table[i].len);
- (*inbytesleft) -= 2;
- (*outbytesleft) -= weird_table[i].len;
- (*inbuf) += 2;
- (*outbuf) += weird_table[i].len;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
-
- (*outbuf)[0] = (*inbuf)[0];
- if ((*inbuf)[1]) ir_count++;
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return ir_count;
-}
-
-struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push};
-
-int charset_weird_init(void)
-{
- smb_register_charset(&weird_functions);
- return True;
-}
diff --git a/source/modules/getdate.c b/source/modules/getdate.c
deleted file mode 100644
index 491c51294e9..00000000000
--- a/source/modules/getdate.c
+++ /dev/null
@@ -1,2460 +0,0 @@
-/* A Bison parser, made by GNU Bison 1.875a. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- tAGO = 258,
- tDST = 259,
- tDAY = 260,
- tDAY_UNIT = 261,
- tDAYZONE = 262,
- tHOUR_UNIT = 263,
- tLOCAL_ZONE = 264,
- tMERIDIAN = 265,
- tMINUTE_UNIT = 266,
- tMONTH = 267,
- tMONTH_UNIT = 268,
- tSEC_UNIT = 269,
- tYEAR_UNIT = 270,
- tZONE = 271,
- tSNUMBER = 272,
- tUNUMBER = 273
- };
-#endif
-#define tAGO 258
-#define tDST 259
-#define tDAY 260
-#define tDAY_UNIT 261
-#define tDAYZONE 262
-#define tHOUR_UNIT 263
-#define tLOCAL_ZONE 264
-#define tMERIDIAN 265
-#define tMINUTE_UNIT 266
-#define tMONTH 267
-#define tMONTH_UNIT 268
-#define tSEC_UNIT 269
-#define tYEAR_UNIT 270
-#define tZONE 271
-#define tSNUMBER 272
-#define tUNUMBER 273
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 1 "getdate.y"
-
-/* Parse a string into an internal time stamp.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Originally written by Steven M. Bellovin <smb@research.att.com> while
- at the University of North Carolina at Chapel Hill. Later tweaked by
- a couple of people on Usenet. Completely overhauled by Rich $alz
- <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
-
- Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
- the right thing about local DST. Unlike previous versions, this
- version is reentrant. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# endif
-#endif
-
-/* Since the code of getdate.y is not included in the Emacs executable
- itself, there is no need to #define static in this file. Even if
- the code were included in the Emacs executable, it probably
- wouldn't do any harm to #undef it here; this will only cause
- problems if we try to write to a static variable, which I don't
- think this code needs to do. */
-#ifdef emacs
-# undef static
-#endif
-
-#include <ctype.h>
-
-#if HAVE_STDLIB_H
-# include <stdlib.h> /* for `free'; used by Bison 1.27 */
-#endif
-
-#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii (c)
-#endif
-
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
-#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
-#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
-
-/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
- - Its arg may be any int or unsigned int; it need not be an unsigned char.
- - It's guaranteed to evaluate its argument exactly once.
- - It's typically faster.
- POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
- ISDIGIT_LOCALE unless it's important to use the locale's definition
- of `digit' even when the host does not conform to POSIX. */
-#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
-
-#if STDC_HEADERS || HAVE_STRING_H
-# include <string.h>
-#endif
-
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
-
-#define EPOCH_YEAR 1970
-#define TM_YEAR_BASE 1900
-
-#define HOUR(x) ((x) * 60)
-
-/* An integer value, and the number of digits in its textual
- representation. */
-typedef struct
-{
- int value;
- int digits;
-} textint;
-
-/* An entry in the lexical lookup table. */
-typedef struct
-{
- char const *name;
- int type;
- int value;
-} table;
-
-/* Meridian: am, pm, or 24-hour style. */
-enum { MERam, MERpm, MER24 };
-
-/* Information passed to and from the parser. */
-typedef struct
-{
- /* The input string remaining to be parsed. */
- const char *input;
-
- /* N, if this is the Nth Tuesday. */
- int day_ordinal;
-
- /* Day of week; Sunday is 0. */
- int day_number;
-
- /* tm_isdst flag for the local zone. */
- int local_isdst;
-
- /* Time zone, in minutes east of UTC. */
- int time_zone;
-
- /* Style used for time. */
- int meridian;
-
- /* Gregorian year, month, day, hour, minutes, and seconds. */
- textint year;
- int month;
- int day;
- int hour;
- int minutes;
- int seconds;
-
- /* Relative year, month, day, hour, minutes, and seconds. */
- int rel_year;
- int rel_month;
- int rel_day;
- int rel_hour;
- int rel_minutes;
- int rel_seconds;
-
- /* Counts of nonterminals of various flavors parsed so far. */
- int dates_seen;
- int days_seen;
- int local_zones_seen;
- int rels_seen;
- int times_seen;
- int zones_seen;
-
- /* Table of local time zone abbrevations, terminated by a null entry. */
- table local_time_zone_table[3];
-} parser_control;
-
-#define PC (* (parser_control *) parm)
-#define YYLEX_PARAM parm
-#define YYPARSE_PARAM parm
-
-static int yyerror ();
-static int yylex ();
-
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 172 "getdate.y"
-typedef union YYSTYPE {
- int intval;
- textint textintval;
-} YYSTYPE;
-/* Line 191 of yacc.c. */
-#line 281 "getdate.c"
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 214 of yacc.c. */
-#line 293 "getdate.c"
-
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# else
-# ifndef YYSTACK_USE_ALLOCA
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-# define YYSTACK_ALLOC malloc
-# define YYSTACK_FREE free
-# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
-
-
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- short yyss;
- YYSTYPE yyvs;
- };
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- register YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (0)
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (0)
-
-#endif
-
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 52
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 22
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 12
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 54
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 64
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 273
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const unsigned char yyprhs[] =
-{
- 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
- 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
- 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
- 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
- 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
- 149, 152, 154, 156, 157
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
-{
- 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
- -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
- -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
- 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
- -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
- 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
- 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
- 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
- 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
- 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
- -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
- 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
- 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
- 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
- -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
- 14, -1, 14, -1, 18, -1, -1, 10, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
-{
- 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
- 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
- 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
- 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
- 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
- 395, 397, 402, 439, 440
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
- "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
- "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
- "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
- "local_zone", "zone", "day", "date", "rel", "relunit", "number",
- "o_merid", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
- 44, 47
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
-{
- 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
- 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
- 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
- 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 32, 33, 33
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
-{
- 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
- 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
- 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
- 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
- 2, 1, 1, 0, 1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const unsigned char yydefact[] =
-{
- 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
- 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
- 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
- 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
- 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
- 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
- 53, 25, 15, 14
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
-{
- -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 58
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -17
-static const yysigned_char yypact[] =
-{
- -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
- -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
- -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
- -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
- -7, -17, -17, -17
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yysigned_char yypgoto[] =
-{
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -10
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
-static const unsigned char yytable[] =
-{
- 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
- 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
- 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
- 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
- 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
- 63, 60, 61
-};
-
-static const unsigned char yycheck[] =
-{
- 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
- 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
- 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
- 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
- 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
- 60, 18, 18
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
-{
- 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
- 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
- 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
- 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
- 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
- 18, 18, 17, 33
-};
-
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror ("syntax error: cannot back up");\
- YYERROR; \
- } \
-while (0)
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.first_line = Rhs[1].first_line; \
- Current.first_column = Rhs[1].first_column; \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
-#endif
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval)
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (0)
-
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Token, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (cinluded). |
-`------------------------------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_stack_print (short *bottom, short *top)
-#else
-static void
-yy_stack_print (bottom, top)
- short *bottom;
- short *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yy_reduce_print (int yyrule)
-#else
-static void
-yy_reduce_print (yyrule)
- int yyrule;
-#endif
-{
- int yyi;
- unsigned int yylineno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylineno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#if YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
-yystrlen (const char *yystr)
-# else
-yystrlen (yystr)
- const char *yystr;
-# endif
-{
- register const char *yys = yystr;
-
- while (*yys++ != '\0')
- continue;
-
- return yys - yystr - 1;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-static char *
-# if defined (__STDC__) || defined (__cplusplus)
-yystpcpy (char *yydest, const char *yysrc)
-# else
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
-{
- register char *yyd = yydest;
- register const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-#endif /* !YYERROR_VERBOSE */
-
-
-
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
-
- if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- switch (yytype)
- {
- default:
- break;
- }
- YYFPRINTF (yyoutput, ")");
-}
-
-#endif /* ! YYDEBUG */
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yytype, yyvaluep)
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM);
-# else
-int yyparse ();
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
-#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
- /* The lookahead symbol. */
-int yychar;
-
-/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-
- register int yystate;
- register int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken = 0;
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- short yyssa[YYINITDEPTH];
- short *yyss = yyssa;
- register short *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- register YYSTYPE *yyvsp;
-
-
-
-#define YYPOPSTACK (yyvsp--, yyssp--)
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
-
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
-
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
-
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyoverflowlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyoverflowlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- short *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyoverflowlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
-
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
-
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
-/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
-/* yyresume: */
-
- /* First try to decide what to do without reference to lookahead token. */
-
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
-
- /* Discard the token being shifted unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- *++yyvsp = yylval;
-
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
-
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 4:
-#line 195 "getdate.y"
- { PC.times_seen++; }
- break;
-
- case 5:
-#line 197 "getdate.y"
- { PC.local_zones_seen++; }
- break;
-
- case 6:
-#line 199 "getdate.y"
- { PC.zones_seen++; }
- break;
-
- case 7:
-#line 201 "getdate.y"
- { PC.dates_seen++; }
- break;
-
- case 8:
-#line 203 "getdate.y"
- { PC.days_seen++; }
- break;
-
- case 9:
-#line 205 "getdate.y"
- { PC.rels_seen++; }
- break;
-
- case 11:
-#line 211 "getdate.y"
- {
- PC.hour = yyvsp[-1].textintval.value;
- PC.minutes = 0;
- PC.seconds = 0;
- PC.meridian = yyvsp[0].intval;
- }
- break;
-
- case 12:
-#line 218 "getdate.y"
- {
- PC.hour = yyvsp[-3].textintval.value;
- PC.minutes = yyvsp[-1].textintval.value;
- PC.seconds = 0;
- PC.meridian = yyvsp[0].intval;
- }
- break;
-
- case 13:
-#line 225 "getdate.y"
- {
- PC.hour = yyvsp[-3].textintval.value;
- PC.minutes = yyvsp[-1].textintval.value;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
- }
- break;
-
- case 14:
-#line 233 "getdate.y"
- {
- PC.hour = yyvsp[-5].textintval.value;
- PC.minutes = yyvsp[-3].textintval.value;
- PC.seconds = yyvsp[-1].textintval.value;
- PC.meridian = yyvsp[0].intval;
- }
- break;
-
- case 15:
-#line 240 "getdate.y"
- {
- PC.hour = yyvsp[-5].textintval.value;
- PC.minutes = yyvsp[-3].textintval.value;
- PC.seconds = yyvsp[-1].textintval.value;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
- }
- break;
-
- case 16:
-#line 252 "getdate.y"
- { PC.local_isdst = yyvsp[0].intval; }
- break;
-
- case 17:
-#line 254 "getdate.y"
- { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
- break;
-
- case 18:
-#line 259 "getdate.y"
- { PC.time_zone = yyvsp[0].intval; }
- break;
-
- case 19:
-#line 261 "getdate.y"
- { PC.time_zone = yyvsp[0].intval + 60; }
- break;
-
- case 20:
-#line 263 "getdate.y"
- { PC.time_zone = yyvsp[-1].intval + 60; }
- break;
-
- case 21:
-#line 268 "getdate.y"
- {
- PC.day_ordinal = 1;
- PC.day_number = yyvsp[0].intval;
- }
- break;
-
- case 22:
-#line 273 "getdate.y"
- {
- PC.day_ordinal = 1;
- PC.day_number = yyvsp[-1].intval;
- }
- break;
-
- case 23:
-#line 278 "getdate.y"
- {
- PC.day_ordinal = yyvsp[-1].textintval.value;
- PC.day_number = yyvsp[0].intval;
- }
- break;
-
- case 24:
-#line 286 "getdate.y"
- {
- PC.month = yyvsp[-2].textintval.value;
- PC.day = yyvsp[0].textintval.value;
- }
- break;
-
- case 25:
-#line 291 "getdate.y"
- {
- /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
- otherwise as MM/DD/YY.
- The goal in recognizing YYYY/MM/DD is solely to support legacy
- machine-generated dates like those in an RCS log listing. If
- you want portability, use the ISO 8601 format. */
- if (4 <= yyvsp[-4].textintval.digits)
- {
- PC.year = yyvsp[-4].textintval;
- PC.month = yyvsp[-2].textintval.value;
- PC.day = yyvsp[0].textintval.value;
- }
- else
- {
- PC.month = yyvsp[-4].textintval.value;
- PC.day = yyvsp[-2].textintval.value;
- PC.year = yyvsp[0].textintval;
- }
- }
- break;
-
- case 26:
-#line 311 "getdate.y"
- {
- /* ISO 8601 format. YYYY-MM-DD. */
- PC.year = yyvsp[-2].textintval;
- PC.month = -yyvsp[-1].textintval.value;
- PC.day = -yyvsp[0].textintval.value;
- }
- break;
-
- case 27:
-#line 318 "getdate.y"
- {
- /* e.g. 17-JUN-1992. */
- PC.day = yyvsp[-2].textintval.value;
- PC.month = yyvsp[-1].intval;
- PC.year.value = -yyvsp[0].textintval.value;
- PC.year.digits = yyvsp[0].textintval.digits;
- }
- break;
-
- case 28:
-#line 326 "getdate.y"
- {
- PC.month = yyvsp[-1].intval;
- PC.day = yyvsp[0].textintval.value;
- }
- break;
-
- case 29:
-#line 331 "getdate.y"
- {
- PC.month = yyvsp[-3].intval;
- PC.day = yyvsp[-2].textintval.value;
- PC.year = yyvsp[0].textintval;
- }
- break;
-
- case 30:
-#line 337 "getdate.y"
- {
- PC.day = yyvsp[-1].textintval.value;
- PC.month = yyvsp[0].intval;
- }
- break;
-
- case 31:
-#line 342 "getdate.y"
- {
- PC.day = yyvsp[-2].textintval.value;
- PC.month = yyvsp[-1].intval;
- PC.year = yyvsp[0].textintval;
- }
- break;
-
- case 32:
-#line 351 "getdate.y"
- {
- PC.rel_seconds = -PC.rel_seconds;
- PC.rel_minutes = -PC.rel_minutes;
- PC.rel_hour = -PC.rel_hour;
- PC.rel_day = -PC.rel_day;
- PC.rel_month = -PC.rel_month;
- PC.rel_year = -PC.rel_year;
- }
- break;
-
- case 34:
-#line 364 "getdate.y"
- { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 35:
-#line 366 "getdate.y"
- { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 36:
-#line 368 "getdate.y"
- { PC.rel_year += yyvsp[0].intval; }
- break;
-
- case 37:
-#line 370 "getdate.y"
- { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 38:
-#line 372 "getdate.y"
- { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 39:
-#line 374 "getdate.y"
- { PC.rel_month += yyvsp[0].intval; }
- break;
-
- case 40:
-#line 376 "getdate.y"
- { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 41:
-#line 378 "getdate.y"
- { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 42:
-#line 380 "getdate.y"
- { PC.rel_day += yyvsp[0].intval; }
- break;
-
- case 43:
-#line 382 "getdate.y"
- { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 44:
-#line 384 "getdate.y"
- { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 45:
-#line 386 "getdate.y"
- { PC.rel_hour += yyvsp[0].intval; }
- break;
-
- case 46:
-#line 388 "getdate.y"
- { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 47:
-#line 390 "getdate.y"
- { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 48:
-#line 392 "getdate.y"
- { PC.rel_minutes += yyvsp[0].intval; }
- break;
-
- case 49:
-#line 394 "getdate.y"
- { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 50:
-#line 396 "getdate.y"
- { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
- break;
-
- case 51:
-#line 398 "getdate.y"
- { PC.rel_seconds += yyvsp[0].intval; }
- break;
-
- case 52:
-#line 403 "getdate.y"
- {
- if (PC.dates_seen
- && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
- PC.year = yyvsp[0].textintval;
- else
- {
- if (4 < yyvsp[0].textintval.digits)
- {
- PC.dates_seen++;
- PC.day = yyvsp[0].textintval.value % 100;
- PC.month = (yyvsp[0].textintval.value / 100) % 100;
- PC.year.value = yyvsp[0].textintval.value / 10000;
- PC.year.digits = yyvsp[0].textintval.digits - 4;
- }
- else
- {
- PC.times_seen++;
- if (yyvsp[0].textintval.digits <= 2)
- {
- PC.hour = yyvsp[0].textintval.value;
- PC.minutes = 0;
- }
- else
- {
- PC.hour = yyvsp[0].textintval.value / 100;
- PC.minutes = yyvsp[0].textintval.value % 100;
- }
- PC.seconds = 0;
- PC.meridian = MER24;
- }
- }
- }
- break;
-
- case 53:
-#line 439 "getdate.y"
- { yyval.intval = MER24; }
- break;
-
- case 54:
-#line 441 "getdate.y"
- { yyval.intval = yyvsp[0].intval; }
- break;
-
-
- }
-
-/* Line 999 of yacc.c. */
-#line 1593 "getdate.c"
-
- yyvsp -= yylen;
- yyssp -= yylen;
-
-
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- YYSIZE_T yysize = 0;
- int yytype = YYTRANSLATE (yychar);
- char *yymsg;
- int yyx, yycount;
-
- yycount = 0;
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- yysize += yystrlen (yytname[yyx]) + 15, yycount++;
- yysize += yystrlen ("syntax error, unexpected ") + 1;
- yysize += yystrlen (yytname[yytype]);
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg != 0)
- {
- char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
- yyp = yystpcpy (yyp, yytname[yytype]);
-
- if (yycount < 5)
- {
- yycount = 0;
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *));
- yyx++)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- const char *yyq = ! yycount ? ", expecting " : " or ";
- yyp = yystpcpy (yyp, yyq);
- yyp = yystpcpy (yyp, yytname[yyx]);
- yycount++;
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- yyerror ("syntax error; also virtual memory exhausted");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror ("syntax error");
- }
-
-
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse lookahead token after an
- error, discard it. */
-
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- {
- /* Pop the error token. */
- YYPOPSTACK;
- /* Pop the rest of the stack. */
- while (yyss < yyssp)
- {
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
- YYPOPSTACK;
- }
- YYABORT;
- }
-
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
- yychar = YYEMPTY;
-
- }
-
- /* Else will try to reuse lookahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*----------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action. |
-`----------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
- yyvsp--;
- yystate = *--yyssp;
-
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- YYDPRINTF ((stderr, "Shifting error token, "));
-
- *++yyvsp = yylval;
-
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here. |
-`----------------------------------------------*/
-yyoverflowlab:
- yyerror ("parser stack overflow");
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
- return yyresult;
-}
-
-
-#line 444 "getdate.y"
-
-
-/* Include this file down here because bison inserts code above which
- may define-away `const'. We want the prototype for get_date to have
- the same signature as the function definition. */
-#include "modules/getdate.h"
-
-#ifndef gmtime
-struct tm *gmtime ();
-#endif
-#ifndef localtime
-struct tm *localtime ();
-#endif
-#ifndef mktime
-time_t mktime ();
-#endif
-
-static table const meridian_table[] =
-{
- { "AM", tMERIDIAN, MERam },
- { "A.M.", tMERIDIAN, MERam },
- { "PM", tMERIDIAN, MERpm },
- { "P.M.", tMERIDIAN, MERpm },
- { 0, 0, 0 }
-};
-
-static table const dst_table[] =
-{
- { "DST", tDST, 0 }
-};
-
-static table const month_and_day_table[] =
-{
- { "JANUARY", tMONTH, 1 },
- { "FEBRUARY", tMONTH, 2 },
- { "MARCH", tMONTH, 3 },
- { "APRIL", tMONTH, 4 },
- { "MAY", tMONTH, 5 },
- { "JUNE", tMONTH, 6 },
- { "JULY", tMONTH, 7 },
- { "AUGUST", tMONTH, 8 },
- { "SEPTEMBER",tMONTH, 9 },
- { "SEPT", tMONTH, 9 },
- { "OCTOBER", tMONTH, 10 },
- { "NOVEMBER", tMONTH, 11 },
- { "DECEMBER", tMONTH, 12 },
- { "SUNDAY", tDAY, 0 },
- { "MONDAY", tDAY, 1 },
- { "TUESDAY", tDAY, 2 },
- { "TUES", tDAY, 2 },
- { "WEDNESDAY",tDAY, 3 },
- { "WEDNES", tDAY, 3 },
- { "THURSDAY", tDAY, 4 },
- { "THUR", tDAY, 4 },
- { "THURS", tDAY, 4 },
- { "FRIDAY", tDAY, 5 },
- { "SATURDAY", tDAY, 6 },
- { 0, 0, 0 }
-};
-
-static table const time_units_table[] =
-{
- { "YEAR", tYEAR_UNIT, 1 },
- { "MONTH", tMONTH_UNIT, 1 },
- { "FORTNIGHT",tDAY_UNIT, 14 },
- { "WEEK", tDAY_UNIT, 7 },
- { "DAY", tDAY_UNIT, 1 },
- { "HOUR", tHOUR_UNIT, 1 },
- { "MINUTE", tMINUTE_UNIT, 1 },
- { "MIN", tMINUTE_UNIT, 1 },
- { "SECOND", tSEC_UNIT, 1 },
- { "SEC", tSEC_UNIT, 1 },
- { 0, 0, 0 }
-};
-
-/* Assorted relative-time words. */
-static table const relative_time_table[] =
-{
- { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
- { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
- { "TODAY", tMINUTE_UNIT, 0 },
- { "NOW", tMINUTE_UNIT, 0 },
- { "LAST", tUNUMBER, -1 },
- { "THIS", tUNUMBER, 0 },
- { "NEXT", tUNUMBER, 1 },
- { "FIRST", tUNUMBER, 1 },
-/*{ "SECOND", tUNUMBER, 2 }, */
- { "THIRD", tUNUMBER, 3 },
- { "FOURTH", tUNUMBER, 4 },
- { "FIFTH", tUNUMBER, 5 },
- { "SIXTH", tUNUMBER, 6 },
- { "SEVENTH", tUNUMBER, 7 },
- { "EIGHTH", tUNUMBER, 8 },
- { "NINTH", tUNUMBER, 9 },
- { "TENTH", tUNUMBER, 10 },
- { "ELEVENTH", tUNUMBER, 11 },
- { "TWELFTH", tUNUMBER, 12 },
- { "AGO", tAGO, 1 },
- { 0, 0, 0 }
-};
-
-/* The time zone table. This table is necessarily incomplete, as time
- zone abbreviations are ambiguous; e.g. Australians interpret "EST"
- as Eastern time in Australia, not as US Eastern Standard Time.
- You cannot rely on getdate to handle arbitrary time zone
- abbreviations; use numeric abbreviations like `-0500' instead. */
-static table const time_zone_table[] =
-{
- { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
- { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
- { "UTC", tZONE, HOUR ( 0) },
- { "WET", tZONE, HOUR ( 0) }, /* Western European */
- { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
- { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
- { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
- { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
- { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
- { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
- { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
- { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
- { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
- { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
- { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
- { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
- { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
- { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
- { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
- { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
- { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
- { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
- { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
- { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
- { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
- { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
- { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
- { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
- { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
- { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
- { "CET", tZONE, HOUR ( 1) }, /* Central European */
- { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
- { "MET", tZONE, HOUR ( 1) }, /* Middle European */
- { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
- { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
- { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
- { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
- { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
- { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
- { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
- { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
- { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
- { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
- { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
- { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
- { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
- { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
- { "GST", tZONE, HOUR (10) }, /* Guam Standard */
- { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
- { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
- { 0, 0, 0 }
-};
-
-/* Military time zone table. */
-static table const military_table[] =
-{
- { "A", tZONE, -HOUR ( 1) },
- { "B", tZONE, -HOUR ( 2) },
- { "C", tZONE, -HOUR ( 3) },
- { "D", tZONE, -HOUR ( 4) },
- { "E", tZONE, -HOUR ( 5) },
- { "F", tZONE, -HOUR ( 6) },
- { "G", tZONE, -HOUR ( 7) },
- { "H", tZONE, -HOUR ( 8) },
- { "I", tZONE, -HOUR ( 9) },
- { "K", tZONE, -HOUR (10) },
- { "L", tZONE, -HOUR (11) },
- { "M", tZONE, -HOUR (12) },
- { "N", tZONE, HOUR ( 1) },
- { "O", tZONE, HOUR ( 2) },
- { "P", tZONE, HOUR ( 3) },
- { "Q", tZONE, HOUR ( 4) },
- { "R", tZONE, HOUR ( 5) },
- { "S", tZONE, HOUR ( 6) },
- { "T", tZONE, HOUR ( 7) },
- { "U", tZONE, HOUR ( 8) },
- { "V", tZONE, HOUR ( 9) },
- { "W", tZONE, HOUR (10) },
- { "X", tZONE, HOUR (11) },
- { "Y", tZONE, HOUR (12) },
- { "Z", tZONE, HOUR ( 0) },
- { 0, 0, 0 }
-};
-
-
-
-static int
-to_hour (int hours, int meridian)
-{
- switch (meridian)
- {
- case MER24:
- return 0 <= hours && hours < 24 ? hours : -1;
- case MERam:
- return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
- case MERpm:
- return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
- default:
- abort ();
- }
- /* NOTREACHED */
- return 0;
-}
-
-static int
-to_year (textint textyear)
-{
- int year = textyear.value;
-
- if (year < 0)
- year = -year;
-
- /* XPG4 suggests that years 00-68 map to 2000-2068, and
- years 69-99 map to 1969-1999. */
- if (textyear.digits == 2)
- year += year < 69 ? 2000 : 1900;
-
- return year;
-}
-
-static table const *
-lookup_zone (parser_control const *pc, char const *name)
-{
- table const *tp;
-
- /* Try local zone abbreviations first; they're more likely to be right. */
- for (tp = pc->local_time_zone_table; tp->name; tp++)
- if (strcmp (name, tp->name) == 0)
- return tp;
-
- for (tp = time_zone_table; tp->name; tp++)
- if (strcmp (name, tp->name) == 0)
- return tp;
-
- return 0;
-}
-
-#if ! HAVE_TM_GMTOFF
-/* Yield the difference between *A and *B,
- measured in seconds, ignoring leap seconds.
- The body of this function is taken directly from the GNU C Library;
- see src/strftime.c. */
-static int
-tm_diff (struct tm const *a, struct tm const *b)
-{
- /* Compute intervening leap days correctly even if year is negative.
- Take care to avoid int overflow in leap day calculations,
- but it's OK to assume that A and B are close to each other. */
- int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
- int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
- int a100 = a4 / 25 - (a4 % 25 < 0);
- int b100 = b4 / 25 - (b4 % 25 < 0);
- int a400 = a100 >> 2;
- int b400 = b100 >> 2;
- int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
- int years = a->tm_year - b->tm_year;
- int days = (365 * years + intervening_leap_days
- + (a->tm_yday - b->tm_yday));
- return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
- + (a->tm_min - b->tm_min))
- + (a->tm_sec - b->tm_sec));
-}
-#endif /* ! HAVE_TM_GMTOFF */
-
-static table const *
-lookup_word (parser_control const *pc, char *word)
-{
- char *p;
- char *q;
- size_t wordlen;
- table const *tp;
- int i;
- int abbrev;
-
- /* Make it uppercase. */
- for (p = word; *p; p++)
- if (ISLOWER ((unsigned char) *p))
- *p = toupper ((unsigned char) *p);
-
- for (tp = meridian_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* See if we have an abbreviation for a month. */
- wordlen = strlen (word);
- abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
-
- for (tp = month_and_day_table; tp->name; tp++)
- if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
- return tp;
-
- if ((tp = lookup_zone (pc, word)))
- return tp;
-
- if (strcmp (word, dst_table[0].name) == 0)
- return dst_table;
-
- for (tp = time_units_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* Strip off any plural and try the units table again. */
- if (word[wordlen - 1] == 'S')
- {
- word[wordlen - 1] = '\0';
- for (tp = time_units_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
- word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
- }
-
- for (tp = relative_time_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* Military time zones. */
- if (wordlen == 1)
- for (tp = military_table; tp->name; tp++)
- if (word[0] == tp->name[0])
- return tp;
-
- /* Drop out any periods and try the time zone table again. */
- for (i = 0, p = q = word; (*p = *q); q++)
- if (*q == '.')
- i = 1;
- else
- p++;
- if (i && (tp = lookup_zone (pc, word)))
- return tp;
-
- return 0;
-}
-
-static int
-yylex (YYSTYPE *lvalp, parser_control *pc)
-{
- unsigned char c;
- int count;
-
- for (;;)
- {
- while (c = *pc->input, ISSPACE (c))
- pc->input++;
-
- if (ISDIGIT (c) || c == '-' || c == '+')
- {
- char const *p;
- int sign;
- int value;
- if (c == '-' || c == '+')
- {
- sign = c == '-' ? -1 : 1;
- c = *++pc->input;
- if (! ISDIGIT (c))
- /* skip the '-' sign */
- continue;
- }
- else
- sign = 0;
- p = pc->input;
- value = 0;
- do
- {
- value = 10 * value + c - '0';
- c = *++p;
- }
- while (ISDIGIT (c));
- lvalp->textintval.value = sign < 0 ? -value : value;
- lvalp->textintval.digits = p - pc->input;
- pc->input = p;
- return sign ? tSNUMBER : tUNUMBER;
- }
-
- if (ISALPHA (c))
- {
- char buff[20];
- char *p = buff;
- table const *tp;
-
- do
- {
- if (p < buff + sizeof buff - 1)
- *p++ = c;
- c = *++pc->input;
- }
- while (ISALPHA (c) || c == '.');
-
- *p = '\0';
- tp = lookup_word (pc, buff);
- if (! tp)
- return '?';
- lvalp->intval = tp->value;
- return tp->type;
- }
-
- if (c != '(')
- return *pc->input++;
- count = 0;
- do
- {
- c = *pc->input++;
- if (c == '\0')
- return c;
- if (c == '(')
- count++;
- else if (c == ')')
- count--;
- }
- while (count > 0);
- }
-}
-
-/* Do nothing if the parser reports an error. */
-static int
-yyerror (char *s ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-/* Parse a date/time string P. Return the corresponding time_t value,
- or (time_t) -1 if there is an error. P can be an incomplete or
- relative time specification; if so, use *NOW as the basis for the
- returned time. */
-time_t
-get_date (const char *p, const time_t *now)
-{
- time_t Start = now ? *now : time (0);
- struct tm *tmp = localtime (&Start);
- struct tm tm;
- struct tm tm0;
- parser_control pc;
-
- if (! tmp)
- return -1;
-
- pc.input = p;
- pc.year.value = tmp->tm_year + TM_YEAR_BASE;
- pc.year.digits = 4;
- pc.month = tmp->tm_mon + 1;
- pc.day = tmp->tm_mday;
- pc.hour = tmp->tm_hour;
- pc.minutes = tmp->tm_min;
- pc.seconds = tmp->tm_sec;
- tm.tm_isdst = tmp->tm_isdst;
-
- pc.meridian = MER24;
- pc.rel_seconds = 0;
- pc.rel_minutes = 0;
- pc.rel_hour = 0;
- pc.rel_day = 0;
- pc.rel_month = 0;
- pc.rel_year = 0;
- pc.dates_seen = 0;
- pc.days_seen = 0;
- pc.rels_seen = 0;
- pc.times_seen = 0;
- pc.local_zones_seen = 0;
- pc.zones_seen = 0;
-
-#if HAVE_STRUCT_TM_TM_ZONE
- pc.local_time_zone_table[0].name = tmp->tm_zone;
- pc.local_time_zone_table[0].type = tLOCAL_ZONE;
- pc.local_time_zone_table[0].value = tmp->tm_isdst;
- pc.local_time_zone_table[1].name = 0;
-
- /* Probe the names used in the next three calendar quarters, looking
- for a tm_isdst different from the one we already have. */
- {
- int quarter;
- for (quarter = 1; quarter <= 3; quarter++)
- {
- time_t probe = Start + quarter * (90 * 24 * 60 * 60);
- struct tm *probe_tm = localtime (&probe);
- if (probe_tm && probe_tm->tm_zone
- && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
- {
- {
- pc.local_time_zone_table[1].name = probe_tm->tm_zone;
- pc.local_time_zone_table[1].type = tLOCAL_ZONE;
- pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
- pc.local_time_zone_table[2].name = 0;
- }
- break;
- }
- }
- }
-#else
-#if HAVE_TZNAME
- {
-# ifndef tzname
- extern char *tzname[];
-# endif
- int i;
- for (i = 0; i < 2; i++)
- {
- pc.local_time_zone_table[i].name = tzname[i];
- pc.local_time_zone_table[i].type = tLOCAL_ZONE;
- pc.local_time_zone_table[i].value = i;
- }
- pc.local_time_zone_table[i].name = 0;
- }
-#else
- pc.local_time_zone_table[0].name = 0;
-#endif
-#endif
-
- if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
- && ! strcmp (pc.local_time_zone_table[0].name,
- pc.local_time_zone_table[1].name))
- {
- /* This locale uses the same abbrevation for standard and
- daylight times. So if we see that abbreviation, we don't
- know whether it's daylight time. */
- pc.local_time_zone_table[0].value = -1;
- pc.local_time_zone_table[1].name = 0;
- }
-
- if (yyparse (&pc) != 0
- || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
- || 1 < (pc.local_zones_seen + pc.zones_seen)
- || (pc.local_zones_seen && 1 < pc.local_isdst))
- return -1;
-
- tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
- tm.tm_mon = pc.month - 1 + pc.rel_month;
- tm.tm_mday = pc.day + pc.rel_day;
- if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
- {
- tm.tm_hour = to_hour (pc.hour, pc.meridian);
- if (tm.tm_hour < 0)
- return -1;
- tm.tm_min = pc.minutes;
- tm.tm_sec = pc.seconds;
- }
- else
- {
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
- }
-
- /* Let mktime deduce tm_isdst if we have an absolute time stamp,
- or if the relative time stamp mentions days, months, or years. */
- if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
- | pc.rel_month | pc.rel_year)
- tm.tm_isdst = -1;
-
- /* But if the input explicitly specifies local time with or without
- DST, give mktime that information. */
- if (pc.local_zones_seen)
- tm.tm_isdst = pc.local_isdst;
-
- tm0 = tm;
-
- Start = mktime (&tm);
-
- if (Start == (time_t) -1)
- {
-
- /* Guard against falsely reporting errors near the time_t boundaries
- when parsing times in other time zones. For example, if the min
- time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
- of UTC, then the min localtime value is 1970-01-01 08:00:00; if
- we apply mktime to 1970-01-01 00:00:00 we will get an error, so
- we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
- zone by 24 hours to compensate. This algorithm assumes that
- there is no DST transition within a day of the time_t boundaries. */
- if (pc.zones_seen)
- {
- tm = tm0;
- if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
- {
- tm.tm_mday++;
- pc.time_zone += 24 * 60;
- }
- else
- {
- tm.tm_mday--;
- pc.time_zone -= 24 * 60;
- }
- Start = mktime (&tm);
- }
-
- if (Start == (time_t) -1)
- return Start;
- }
-
- if (pc.days_seen && ! pc.dates_seen)
- {
- tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
- + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
- tm.tm_isdst = -1;
- Start = mktime (&tm);
- if (Start == (time_t) -1)
- return Start;
- }
-
- if (pc.zones_seen)
- {
- int delta = pc.time_zone * 60;
-#ifdef HAVE_TM_GMTOFF
- delta -= tm.tm_gmtoff;
-#else
- struct tm *gmt = gmtime (&Start);
- if (! gmt)
- return -1;
- delta -= tm_diff (&tm, gmt);
-#endif
- if ((Start < Start - delta) != (delta < 0))
- return -1; /* time_t overflow */
- Start -= delta;
- }
-
- /* Add relative hours, minutes, and seconds. Ignore leap seconds;
- i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
- leap second. Typically this is not what the user wants, but it's
- too hard to do it the other way, because the time zone indicator
- must be applied before relative times, and if mktime is applied
- again the time zone will be lost. */
- {
- time_t t0 = Start;
- long d1 = 60 * 60 * (long) pc.rel_hour;
- time_t t1 = t0 + d1;
- long d2 = 60 * (long) pc.rel_minutes;
- time_t t2 = t1 + d2;
- int d3 = pc.rel_seconds;
- time_t t3 = t2 + d3;
- if ((d1 / (60 * 60) ^ pc.rel_hour)
- | (d2 / 60 ^ pc.rel_minutes)
- | ((t0 + d1 < t0) ^ (d1 < 0))
- | ((t1 + d2 < t1) ^ (d2 < 0))
- | ((t2 + d3 < t2) ^ (d3 < 0)))
- return -1;
- Start = t3;
- }
-
- return Start;
-}
-
-#if TEST
-
-#include <stdio.h>
-
-int
-main (int ac, char **av)
-{
- char buff[BUFSIZ];
- time_t d;
-
- printf ("Enter date, or blank line to exit.\n\t> ");
- fflush (stdout);
-
- buff[BUFSIZ - 1] = 0;
- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
- {
- d = get_date (buff, 0);
- if (d == (time_t) -1)
- printf ("Bad format - couldn't convert.\n");
- else
- printf ("%s", ctime (&d));
- printf ("\t> ");
- fflush (stdout);
- }
- return 0;
-}
-#endif /* defined TEST */
-
-
diff --git a/source/modules/getdate.h b/source/modules/getdate.h
deleted file mode 100644
index 674c474f115..00000000000
--- a/source/modules/getdate.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifndef PARAMS
-# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
-# define PARAMS(Args) Args
-# else
-# define PARAMS(Args) ()
-# endif
-#endif
-
-#ifdef vms
-# include <types.h>
-# include <time.h>
-#else
-# include <sys/types.h>
-# if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-# else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-# endif
-#endif /* defined (vms) */
-
-time_t get_date PARAMS ((const char *p, const time_t *now));
diff --git a/source/modules/getdate.y b/source/modules/getdate.y
deleted file mode 100644
index aab37f4d235..00000000000
--- a/source/modules/getdate.y
+++ /dev/null
@@ -1,1115 +0,0 @@
-%{
-/* Parse a string into an internal time stamp.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Originally written by Steven M. Bellovin <smb@research.att.com> while
- at the University of North Carolina at Chapel Hill. Later tweaked by
- a couple of people on Usenet. Completely overhauled by Rich $alz
- <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
-
- Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
- the right thing about local DST. Unlike previous versions, this
- version is reentrant. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# endif
-#endif
-
-/* Since the code of getdate.y is not included in the Emacs executable
- itself, there is no need to #define static in this file. Even if
- the code were included in the Emacs executable, it probably
- wouldn't do any harm to #undef it here; this will only cause
- problems if we try to write to a static variable, which I don't
- think this code needs to do. */
-#ifdef emacs
-# undef static
-#endif
-
-#include <ctype.h>
-
-#if HAVE_STDLIB_H
-# include <stdlib.h> /* for `free'; used by Bison 1.27 */
-#endif
-
-#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii (c)
-#endif
-
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
-#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
-#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
-
-/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
- - Its arg may be any int or unsigned int; it need not be an unsigned char.
- - It's guaranteed to evaluate its argument exactly once.
- - It's typically faster.
- POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
- ISDIGIT_LOCALE unless it's important to use the locale's definition
- of `digit' even when the host does not conform to POSIX. */
-#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
-
-#if STDC_HEADERS || HAVE_STRING_H
-# include <string.h>
-#endif
-
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
-
-#define EPOCH_YEAR 1970
-#define TM_YEAR_BASE 1900
-
-#define HOUR(x) ((x) * 60)
-
-/* An integer value, and the number of digits in its textual
- representation. */
-typedef struct
-{
- int value;
- int digits;
-} textint;
-
-/* An entry in the lexical lookup table. */
-typedef struct
-{
- char const *name;
- int type;
- int value;
-} table;
-
-/* Meridian: am, pm, or 24-hour style. */
-enum { MERam, MERpm, MER24 };
-
-/* Information passed to and from the parser. */
-typedef struct
-{
- /* The input string remaining to be parsed. */
- const char *input;
-
- /* N, if this is the Nth Tuesday. */
- int day_ordinal;
-
- /* Day of week; Sunday is 0. */
- int day_number;
-
- /* tm_isdst flag for the local zone. */
- int local_isdst;
-
- /* Time zone, in minutes east of UTC. */
- int time_zone;
-
- /* Style used for time. */
- int meridian;
-
- /* Gregorian year, month, day, hour, minutes, and seconds. */
- textint year;
- int month;
- int day;
- int hour;
- int minutes;
- int seconds;
-
- /* Relative year, month, day, hour, minutes, and seconds. */
- int rel_year;
- int rel_month;
- int rel_day;
- int rel_hour;
- int rel_minutes;
- int rel_seconds;
-
- /* Counts of nonterminals of various flavors parsed so far. */
- int dates_seen;
- int days_seen;
- int local_zones_seen;
- int rels_seen;
- int times_seen;
- int zones_seen;
-
- /* Table of local time zone abbrevations, terminated by a null entry. */
- table local_time_zone_table[3];
-} parser_control;
-
-#define PC (* (parser_control *) parm)
-#define YYLEX_PARAM parm
-#define YYPARSE_PARAM parm
-
-static int yyerror ();
-static int yylex ();
-
-%}
-
-/* We want a reentrant parser. */
-%pure_parser
-
-/* This grammar has 13 shift/reduce conflicts. */
-%expect 13
-
-%union
-{
- int intval;
- textint textintval;
-}
-
-%token tAGO tDST
-
-%token <intval> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tLOCAL_ZONE tMERIDIAN
-%token <intval> tMINUTE_UNIT tMONTH tMONTH_UNIT tSEC_UNIT tYEAR_UNIT tZONE
-
-%token <textintval> tSNUMBER tUNUMBER
-
-%type <intval> o_merid
-
-%%
-
-spec:
- /* empty */
- | spec item
- ;
-
-item:
- time
- { PC.times_seen++; }
- | local_zone
- { PC.local_zones_seen++; }
- | zone
- { PC.zones_seen++; }
- | date
- { PC.dates_seen++; }
- | day
- { PC.days_seen++; }
- | rel
- { PC.rels_seen++; }
- | number
- ;
-
-time:
- tUNUMBER tMERIDIAN
- {
- PC.hour = $1.value;
- PC.minutes = 0;
- PC.seconds = 0;
- PC.meridian = $2;
- }
- | tUNUMBER ':' tUNUMBER o_merid
- {
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds = 0;
- PC.meridian = $4;
- }
- | tUNUMBER ':' tUNUMBER tSNUMBER
- {
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = $4.value % 100 + ($4.value / 100) * 60;
- }
- | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid
- {
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds = $5.value;
- PC.meridian = $6;
- }
- | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER
- {
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds = $5.value;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = $6.value % 100 + ($6.value / 100) * 60;
- }
- ;
-
-local_zone:
- tLOCAL_ZONE
- { PC.local_isdst = $1; }
- | tLOCAL_ZONE tDST
- { PC.local_isdst = $1 < 0 ? 1 : $1 + 1; }
- ;
-
-zone:
- tZONE
- { PC.time_zone = $1; }
- | tDAYZONE
- { PC.time_zone = $1 + 60; }
- | tZONE tDST
- { PC.time_zone = $1 + 60; }
- ;
-
-day:
- tDAY
- {
- PC.day_ordinal = 1;
- PC.day_number = $1;
- }
- | tDAY ','
- {
- PC.day_ordinal = 1;
- PC.day_number = $1;
- }
- | tUNUMBER tDAY
- {
- PC.day_ordinal = $1.value;
- PC.day_number = $2;
- }
- ;
-
-date:
- tUNUMBER '/' tUNUMBER
- {
- PC.month = $1.value;
- PC.day = $3.value;
- }
- | tUNUMBER '/' tUNUMBER '/' tUNUMBER
- {
- /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
- otherwise as MM/DD/YY.
- The goal in recognizing YYYY/MM/DD is solely to support legacy
- machine-generated dates like those in an RCS log listing. If
- you want portability, use the ISO 8601 format. */
- if (4 <= $1.digits)
- {
- PC.year = $1;
- PC.month = $3.value;
- PC.day = $5.value;
- }
- else
- {
- PC.month = $1.value;
- PC.day = $3.value;
- PC.year = $5;
- }
- }
- | tUNUMBER tSNUMBER tSNUMBER
- {
- /* ISO 8601 format. YYYY-MM-DD. */
- PC.year = $1;
- PC.month = -$2.value;
- PC.day = -$3.value;
- }
- | tUNUMBER tMONTH tSNUMBER
- {
- /* e.g. 17-JUN-1992. */
- PC.day = $1.value;
- PC.month = $2;
- PC.year.value = -$3.value;
- PC.year.digits = $3.digits;
- }
- | tMONTH tUNUMBER
- {
- PC.month = $1;
- PC.day = $2.value;
- }
- | tMONTH tUNUMBER ',' tUNUMBER
- {
- PC.month = $1;
- PC.day = $2.value;
- PC.year = $4;
- }
- | tUNUMBER tMONTH
- {
- PC.day = $1.value;
- PC.month = $2;
- }
- | tUNUMBER tMONTH tUNUMBER
- {
- PC.day = $1.value;
- PC.month = $2;
- PC.year = $3;
- }
- ;
-
-rel:
- relunit tAGO
- {
- PC.rel_seconds = -PC.rel_seconds;
- PC.rel_minutes = -PC.rel_minutes;
- PC.rel_hour = -PC.rel_hour;
- PC.rel_day = -PC.rel_day;
- PC.rel_month = -PC.rel_month;
- PC.rel_year = -PC.rel_year;
- }
- | relunit
- ;
-
-relunit:
- tUNUMBER tYEAR_UNIT
- { PC.rel_year += $1.value * $2; }
- | tSNUMBER tYEAR_UNIT
- { PC.rel_year += $1.value * $2; }
- | tYEAR_UNIT
- { PC.rel_year += $1; }
- | tUNUMBER tMONTH_UNIT
- { PC.rel_month += $1.value * $2; }
- | tSNUMBER tMONTH_UNIT
- { PC.rel_month += $1.value * $2; }
- | tMONTH_UNIT
- { PC.rel_month += $1; }
- | tUNUMBER tDAY_UNIT
- { PC.rel_day += $1.value * $2; }
- | tSNUMBER tDAY_UNIT
- { PC.rel_day += $1.value * $2; }
- | tDAY_UNIT
- { PC.rel_day += $1; }
- | tUNUMBER tHOUR_UNIT
- { PC.rel_hour += $1.value * $2; }
- | tSNUMBER tHOUR_UNIT
- { PC.rel_hour += $1.value * $2; }
- | tHOUR_UNIT
- { PC.rel_hour += $1; }
- | tUNUMBER tMINUTE_UNIT
- { PC.rel_minutes += $1.value * $2; }
- | tSNUMBER tMINUTE_UNIT
- { PC.rel_minutes += $1.value * $2; }
- | tMINUTE_UNIT
- { PC.rel_minutes += $1; }
- | tUNUMBER tSEC_UNIT
- { PC.rel_seconds += $1.value * $2; }
- | tSNUMBER tSEC_UNIT
- { PC.rel_seconds += $1.value * $2; }
- | tSEC_UNIT
- { PC.rel_seconds += $1; }
- ;
-
-number:
- tUNUMBER
- {
- if (PC.dates_seen
- && ! PC.rels_seen && (PC.times_seen || 2 < $1.digits))
- PC.year = $1;
- else
- {
- if (4 < $1.digits)
- {
- PC.dates_seen++;
- PC.day = $1.value % 100;
- PC.month = ($1.value / 100) % 100;
- PC.year.value = $1.value / 10000;
- PC.year.digits = $1.digits - 4;
- }
- else
- {
- PC.times_seen++;
- if ($1.digits <= 2)
- {
- PC.hour = $1.value;
- PC.minutes = 0;
- }
- else
- {
- PC.hour = $1.value / 100;
- PC.minutes = $1.value % 100;
- }
- PC.seconds = 0;
- PC.meridian = MER24;
- }
- }
- }
- ;
-
-o_merid:
- /* empty */
- { $$ = MER24; }
- | tMERIDIAN
- { $$ = $1; }
- ;
-
-%%
-
-/* Include this file down here because bison inserts code above which
- may define-away `const'. We want the prototype for get_date to have
- the same signature as the function definition. */
-#include "modules/getdate.h"
-
-#ifndef gmtime
-struct tm *gmtime ();
-#endif
-#ifndef localtime
-struct tm *localtime ();
-#endif
-#ifndef mktime
-time_t mktime ();
-#endif
-
-static table const meridian_table[] =
-{
- { "AM", tMERIDIAN, MERam },
- { "A.M.", tMERIDIAN, MERam },
- { "PM", tMERIDIAN, MERpm },
- { "P.M.", tMERIDIAN, MERpm },
- { 0, 0, 0 }
-};
-
-static table const dst_table[] =
-{
- { "DST", tDST, 0 }
-};
-
-static table const month_and_day_table[] =
-{
- { "JANUARY", tMONTH, 1 },
- { "FEBRUARY", tMONTH, 2 },
- { "MARCH", tMONTH, 3 },
- { "APRIL", tMONTH, 4 },
- { "MAY", tMONTH, 5 },
- { "JUNE", tMONTH, 6 },
- { "JULY", tMONTH, 7 },
- { "AUGUST", tMONTH, 8 },
- { "SEPTEMBER",tMONTH, 9 },
- { "SEPT", tMONTH, 9 },
- { "OCTOBER", tMONTH, 10 },
- { "NOVEMBER", tMONTH, 11 },
- { "DECEMBER", tMONTH, 12 },
- { "SUNDAY", tDAY, 0 },
- { "MONDAY", tDAY, 1 },
- { "TUESDAY", tDAY, 2 },
- { "TUES", tDAY, 2 },
- { "WEDNESDAY",tDAY, 3 },
- { "WEDNES", tDAY, 3 },
- { "THURSDAY", tDAY, 4 },
- { "THUR", tDAY, 4 },
- { "THURS", tDAY, 4 },
- { "FRIDAY", tDAY, 5 },
- { "SATURDAY", tDAY, 6 },
- { 0, 0, 0 }
-};
-
-static table const time_units_table[] =
-{
- { "YEAR", tYEAR_UNIT, 1 },
- { "MONTH", tMONTH_UNIT, 1 },
- { "FORTNIGHT",tDAY_UNIT, 14 },
- { "WEEK", tDAY_UNIT, 7 },
- { "DAY", tDAY_UNIT, 1 },
- { "HOUR", tHOUR_UNIT, 1 },
- { "MINUTE", tMINUTE_UNIT, 1 },
- { "MIN", tMINUTE_UNIT, 1 },
- { "SECOND", tSEC_UNIT, 1 },
- { "SEC", tSEC_UNIT, 1 },
- { 0, 0, 0 }
-};
-
-/* Assorted relative-time words. */
-static table const relative_time_table[] =
-{
- { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
- { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
- { "TODAY", tMINUTE_UNIT, 0 },
- { "NOW", tMINUTE_UNIT, 0 },
- { "LAST", tUNUMBER, -1 },
- { "THIS", tUNUMBER, 0 },
- { "NEXT", tUNUMBER, 1 },
- { "FIRST", tUNUMBER, 1 },
-/*{ "SECOND", tUNUMBER, 2 }, */
- { "THIRD", tUNUMBER, 3 },
- { "FOURTH", tUNUMBER, 4 },
- { "FIFTH", tUNUMBER, 5 },
- { "SIXTH", tUNUMBER, 6 },
- { "SEVENTH", tUNUMBER, 7 },
- { "EIGHTH", tUNUMBER, 8 },
- { "NINTH", tUNUMBER, 9 },
- { "TENTH", tUNUMBER, 10 },
- { "ELEVENTH", tUNUMBER, 11 },
- { "TWELFTH", tUNUMBER, 12 },
- { "AGO", tAGO, 1 },
- { 0, 0, 0 }
-};
-
-/* The time zone table. This table is necessarily incomplete, as time
- zone abbreviations are ambiguous; e.g. Australians interpret "EST"
- as Eastern time in Australia, not as US Eastern Standard Time.
- You cannot rely on getdate to handle arbitrary time zone
- abbreviations; use numeric abbreviations like `-0500' instead. */
-static table const time_zone_table[] =
-{
- { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
- { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
- { "UTC", tZONE, HOUR ( 0) },
- { "WET", tZONE, HOUR ( 0) }, /* Western European */
- { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
- { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
- { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
- { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
- { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
- { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
- { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
- { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
- { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
- { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
- { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
- { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
- { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
- { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
- { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
- { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
- { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
- { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
- { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
- { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
- { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
- { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
- { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
- { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
- { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
- { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
- { "CET", tZONE, HOUR ( 1) }, /* Central European */
- { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
- { "MET", tZONE, HOUR ( 1) }, /* Middle European */
- { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
- { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
- { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
- { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
- { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
- { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
- { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
- { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
- { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
- { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
- { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
- { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
- { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
- { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
- { "GST", tZONE, HOUR (10) }, /* Guam Standard */
- { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
- { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
- { 0, 0, 0 }
-};
-
-/* Military time zone table. */
-static table const military_table[] =
-{
- { "A", tZONE, -HOUR ( 1) },
- { "B", tZONE, -HOUR ( 2) },
- { "C", tZONE, -HOUR ( 3) },
- { "D", tZONE, -HOUR ( 4) },
- { "E", tZONE, -HOUR ( 5) },
- { "F", tZONE, -HOUR ( 6) },
- { "G", tZONE, -HOUR ( 7) },
- { "H", tZONE, -HOUR ( 8) },
- { "I", tZONE, -HOUR ( 9) },
- { "K", tZONE, -HOUR (10) },
- { "L", tZONE, -HOUR (11) },
- { "M", tZONE, -HOUR (12) },
- { "N", tZONE, HOUR ( 1) },
- { "O", tZONE, HOUR ( 2) },
- { "P", tZONE, HOUR ( 3) },
- { "Q", tZONE, HOUR ( 4) },
- { "R", tZONE, HOUR ( 5) },
- { "S", tZONE, HOUR ( 6) },
- { "T", tZONE, HOUR ( 7) },
- { "U", tZONE, HOUR ( 8) },
- { "V", tZONE, HOUR ( 9) },
- { "W", tZONE, HOUR (10) },
- { "X", tZONE, HOUR (11) },
- { "Y", tZONE, HOUR (12) },
- { "Z", tZONE, HOUR ( 0) },
- { 0, 0, 0 }
-};
-
-
-
-static int
-to_hour (int hours, int meridian)
-{
- switch (meridian)
- {
- case MER24:
- return 0 <= hours && hours < 24 ? hours : -1;
- case MERam:
- return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
- case MERpm:
- return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
- default:
- abort ();
- }
- /* NOTREACHED */
- return 0;
-}
-
-static int
-to_year (textint textyear)
-{
- int year = textyear.value;
-
- if (year < 0)
- year = -year;
-
- /* XPG4 suggests that years 00-68 map to 2000-2068, and
- years 69-99 map to 1969-1999. */
- if (textyear.digits == 2)
- year += year < 69 ? 2000 : 1900;
-
- return year;
-}
-
-static table const *
-lookup_zone (parser_control const *pc, char const *name)
-{
- table const *tp;
-
- /* Try local zone abbreviations first; they're more likely to be right. */
- for (tp = pc->local_time_zone_table; tp->name; tp++)
- if (strcmp (name, tp->name) == 0)
- return tp;
-
- for (tp = time_zone_table; tp->name; tp++)
- if (strcmp (name, tp->name) == 0)
- return tp;
-
- return 0;
-}
-
-#if ! HAVE_TM_GMTOFF
-/* Yield the difference between *A and *B,
- measured in seconds, ignoring leap seconds.
- The body of this function is taken directly from the GNU C Library;
- see src/strftime.c. */
-static int
-tm_diff (struct tm const *a, struct tm const *b)
-{
- /* Compute intervening leap days correctly even if year is negative.
- Take care to avoid int overflow in leap day calculations,
- but it's OK to assume that A and B are close to each other. */
- int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
- int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
- int a100 = a4 / 25 - (a4 % 25 < 0);
- int b100 = b4 / 25 - (b4 % 25 < 0);
- int a400 = a100 >> 2;
- int b400 = b100 >> 2;
- int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
- int years = a->tm_year - b->tm_year;
- int days = (365 * years + intervening_leap_days
- + (a->tm_yday - b->tm_yday));
- return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
- + (a->tm_min - b->tm_min))
- + (a->tm_sec - b->tm_sec));
-}
-#endif /* ! HAVE_TM_GMTOFF */
-
-static table const *
-lookup_word (parser_control const *pc, char *word)
-{
- char *p;
- char *q;
- size_t wordlen;
- table const *tp;
- int i;
- int abbrev;
-
- /* Make it uppercase. */
- for (p = word; *p; p++)
- if (ISLOWER ((unsigned char) *p))
- *p = toupper ((unsigned char) *p);
-
- for (tp = meridian_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* See if we have an abbreviation for a month. */
- wordlen = strlen (word);
- abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
-
- for (tp = month_and_day_table; tp->name; tp++)
- if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
- return tp;
-
- if ((tp = lookup_zone (pc, word)))
- return tp;
-
- if (strcmp (word, dst_table[0].name) == 0)
- return dst_table;
-
- for (tp = time_units_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* Strip off any plural and try the units table again. */
- if (word[wordlen - 1] == 'S')
- {
- word[wordlen - 1] = '\0';
- for (tp = time_units_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
- word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
- }
-
- for (tp = relative_time_table; tp->name; tp++)
- if (strcmp (word, tp->name) == 0)
- return tp;
-
- /* Military time zones. */
- if (wordlen == 1)
- for (tp = military_table; tp->name; tp++)
- if (word[0] == tp->name[0])
- return tp;
-
- /* Drop out any periods and try the time zone table again. */
- for (i = 0, p = q = word; (*p = *q); q++)
- if (*q == '.')
- i = 1;
- else
- p++;
- if (i && (tp = lookup_zone (pc, word)))
- return tp;
-
- return 0;
-}
-
-static int
-yylex (YYSTYPE *lvalp, parser_control *pc)
-{
- unsigned char c;
- int count;
-
- for (;;)
- {
- while (c = *pc->input, ISSPACE (c))
- pc->input++;
-
- if (ISDIGIT (c) || c == '-' || c == '+')
- {
- char const *p;
- int sign;
- int value;
- if (c == '-' || c == '+')
- {
- sign = c == '-' ? -1 : 1;
- c = *++pc->input;
- if (! ISDIGIT (c))
- /* skip the '-' sign */
- continue;
- }
- else
- sign = 0;
- p = pc->input;
- value = 0;
- do
- {
- value = 10 * value + c - '0';
- c = *++p;
- }
- while (ISDIGIT (c));
- lvalp->textintval.value = sign < 0 ? -value : value;
- lvalp->textintval.digits = p - pc->input;
- pc->input = p;
- return sign ? tSNUMBER : tUNUMBER;
- }
-
- if (ISALPHA (c))
- {
- char buff[20];
- char *p = buff;
- table const *tp;
-
- do
- {
- if (p < buff + sizeof buff - 1)
- *p++ = c;
- c = *++pc->input;
- }
- while (ISALPHA (c) || c == '.');
-
- *p = '\0';
- tp = lookup_word (pc, buff);
- if (! tp)
- return '?';
- lvalp->intval = tp->value;
- return tp->type;
- }
-
- if (c != '(')
- return *pc->input++;
- count = 0;
- do
- {
- c = *pc->input++;
- if (c == '\0')
- return c;
- if (c == '(')
- count++;
- else if (c == ')')
- count--;
- }
- while (count > 0);
- }
-}
-
-/* Do nothing if the parser reports an error. */
-static int
-yyerror (char *s ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-/* Parse a date/time string P. Return the corresponding time_t value,
- or (time_t) -1 if there is an error. P can be an incomplete or
- relative time specification; if so, use *NOW as the basis for the
- returned time. */
-time_t
-get_date (const char *p, const time_t *now)
-{
- time_t Start = now ? *now : time (0);
- struct tm *tmp = localtime (&Start);
- struct tm tm;
- struct tm tm0;
- parser_control pc;
-
- if (! tmp)
- return -1;
-
- pc.input = p;
- pc.year.value = tmp->tm_year + TM_YEAR_BASE;
- pc.year.digits = 4;
- pc.month = tmp->tm_mon + 1;
- pc.day = tmp->tm_mday;
- pc.hour = tmp->tm_hour;
- pc.minutes = tmp->tm_min;
- pc.seconds = tmp->tm_sec;
- tm.tm_isdst = tmp->tm_isdst;
-
- pc.meridian = MER24;
- pc.rel_seconds = 0;
- pc.rel_minutes = 0;
- pc.rel_hour = 0;
- pc.rel_day = 0;
- pc.rel_month = 0;
- pc.rel_year = 0;
- pc.dates_seen = 0;
- pc.days_seen = 0;
- pc.rels_seen = 0;
- pc.times_seen = 0;
- pc.local_zones_seen = 0;
- pc.zones_seen = 0;
-
-#if HAVE_STRUCT_TM_TM_ZONE
- pc.local_time_zone_table[0].name = tmp->tm_zone;
- pc.local_time_zone_table[0].type = tLOCAL_ZONE;
- pc.local_time_zone_table[0].value = tmp->tm_isdst;
- pc.local_time_zone_table[1].name = 0;
-
- /* Probe the names used in the next three calendar quarters, looking
- for a tm_isdst different from the one we already have. */
- {
- int quarter;
- for (quarter = 1; quarter <= 3; quarter++)
- {
- time_t probe = Start + quarter * (90 * 24 * 60 * 60);
- struct tm *probe_tm = localtime (&probe);
- if (probe_tm && probe_tm->tm_zone
- && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
- {
- {
- pc.local_time_zone_table[1].name = probe_tm->tm_zone;
- pc.local_time_zone_table[1].type = tLOCAL_ZONE;
- pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
- pc.local_time_zone_table[2].name = 0;
- }
- break;
- }
- }
- }
-#else
-#if HAVE_TZNAME
- {
-# ifndef tzname
- extern char *tzname[];
-# endif
- int i;
- for (i = 0; i < 2; i++)
- {
- pc.local_time_zone_table[i].name = tzname[i];
- pc.local_time_zone_table[i].type = tLOCAL_ZONE;
- pc.local_time_zone_table[i].value = i;
- }
- pc.local_time_zone_table[i].name = 0;
- }
-#else
- pc.local_time_zone_table[0].name = 0;
-#endif
-#endif
-
- if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
- && ! strcmp (pc.local_time_zone_table[0].name,
- pc.local_time_zone_table[1].name))
- {
- /* This locale uses the same abbrevation for standard and
- daylight times. So if we see that abbreviation, we don't
- know whether it's daylight time. */
- pc.local_time_zone_table[0].value = -1;
- pc.local_time_zone_table[1].name = 0;
- }
-
- if (yyparse (&pc) != 0
- || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
- || 1 < (pc.local_zones_seen + pc.zones_seen)
- || (pc.local_zones_seen && 1 < pc.local_isdst))
- return -1;
-
- tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
- tm.tm_mon = pc.month - 1 + pc.rel_month;
- tm.tm_mday = pc.day + pc.rel_day;
- if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
- {
- tm.tm_hour = to_hour (pc.hour, pc.meridian);
- if (tm.tm_hour < 0)
- return -1;
- tm.tm_min = pc.minutes;
- tm.tm_sec = pc.seconds;
- }
- else
- {
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
- }
-
- /* Let mktime deduce tm_isdst if we have an absolute time stamp,
- or if the relative time stamp mentions days, months, or years. */
- if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
- | pc.rel_month | pc.rel_year)
- tm.tm_isdst = -1;
-
- /* But if the input explicitly specifies local time with or without
- DST, give mktime that information. */
- if (pc.local_zones_seen)
- tm.tm_isdst = pc.local_isdst;
-
- tm0 = tm;
-
- Start = mktime (&tm);
-
- if (Start == (time_t) -1)
- {
-
- /* Guard against falsely reporting errors near the time_t boundaries
- when parsing times in other time zones. For example, if the min
- time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
- of UTC, then the min localtime value is 1970-01-01 08:00:00; if
- we apply mktime to 1970-01-01 00:00:00 we will get an error, so
- we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
- zone by 24 hours to compensate. This algorithm assumes that
- there is no DST transition within a day of the time_t boundaries. */
- if (pc.zones_seen)
- {
- tm = tm0;
- if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
- {
- tm.tm_mday++;
- pc.time_zone += 24 * 60;
- }
- else
- {
- tm.tm_mday--;
- pc.time_zone -= 24 * 60;
- }
- Start = mktime (&tm);
- }
-
- if (Start == (time_t) -1)
- return Start;
- }
-
- if (pc.days_seen && ! pc.dates_seen)
- {
- tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
- + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
- tm.tm_isdst = -1;
- Start = mktime (&tm);
- if (Start == (time_t) -1)
- return Start;
- }
-
- if (pc.zones_seen)
- {
- int delta = pc.time_zone * 60;
-#ifdef HAVE_TM_GMTOFF
- delta -= tm.tm_gmtoff;
-#else
- struct tm *gmt = gmtime (&Start);
- if (! gmt)
- return -1;
- delta -= tm_diff (&tm, gmt);
-#endif
- if ((Start < Start - delta) != (delta < 0))
- return -1; /* time_t overflow */
- Start -= delta;
- }
-
- /* Add relative hours, minutes, and seconds. Ignore leap seconds;
- i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
- leap second. Typically this is not what the user wants, but it's
- too hard to do it the other way, because the time zone indicator
- must be applied before relative times, and if mktime is applied
- again the time zone will be lost. */
- {
- time_t t0 = Start;
- long d1 = 60 * 60 * (long) pc.rel_hour;
- time_t t1 = t0 + d1;
- long d2 = 60 * (long) pc.rel_minutes;
- time_t t2 = t1 + d2;
- int d3 = pc.rel_seconds;
- time_t t3 = t2 + d3;
- if ((d1 / (60 * 60) ^ pc.rel_hour)
- | (d2 / 60 ^ pc.rel_minutes)
- | ((t0 + d1 < t0) ^ (d1 < 0))
- | ((t1 + d2 < t1) ^ (d2 < 0))
- | ((t2 + d3 < t2) ^ (d3 < 0)))
- return -1;
- Start = t3;
- }
-
- return Start;
-}
-
-#if TEST
-
-#include <stdio.h>
-
-int
-main (int ac, char **av)
-{
- char buff[BUFSIZ];
- time_t d;
-
- printf ("Enter date, or blank line to exit.\n\t> ");
- fflush (stdout);
-
- buff[BUFSIZ - 1] = 0;
- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
- {
- d = get_date (buff, 0);
- if (d == (time_t) -1)
- printf ("Bad format - couldn't convert.\n");
- else
- printf ("%s", ctime (&d));
- printf ("\t> ");
- fflush (stdout);
- }
- return 0;
-}
-#endif /* defined TEST */
diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c
deleted file mode 100644
index 550d918b43c..00000000000
--- a/source/modules/vfs_audit.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Auditing VFS module for samba. Log selected file operations to syslog
- * facility.
- *
- * Copyright (C) Tim Potter 1999-2000
- * Copyright (C) Alexander Bokovoy 2002
- * Copyright (C) Stefan (metze) Metzmacher 2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-/* Function prototypes */
-
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname);
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new);
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
-static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
-
-/* VFS operations */
-
-static vfs_op_tuple audit_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
-
- /* Directory operations */
-
- {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
-
- /* File operations */
-
- {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
-
- /* Finish VFS operations definition */
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-
-static int audit_syslog_facility(vfs_handle_struct *handle)
-{
- /* fix me: let this be configurable by:
- * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog facility",
- * audit_enum_facility,LOG_USER);
- */
- return LOG_USER;
-}
-
-
-static int audit_syslog_priority(vfs_handle_struct *handle)
-{
- /* fix me: let this be configurable by:
- * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"audit"),"syslog priority",
- * audit_enum_priority,LOG_NOTICE);
- */
- return LOG_NOTICE;
-}
-
-/* Implementation of vfs_ops. Pass everything on to the default
- operation but log event first. */
-
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
-{
- int result;
-
- openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
-
- syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
- svc, user);
-
- result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
-
- return result;
-}
-
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
- syslog(audit_syslog_priority(handle), "disconnected\n");
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
-
- return;
-}
-
-static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- DIR *result;
-
- result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
-
- syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
-
- syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
-
- syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- fname, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- int result;
-
- result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
-
- syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
-{
- int result;
-
- result = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
-
- syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
-
- syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
-
- syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
-
- syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
-NTSTATUS vfs_audit_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_op_tuples);
-}
diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c
deleted file mode 100644
index 0526276acb8..00000000000
--- a/source/modules/vfs_cap.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * CAP VFS module for Samba 3.x Version 0.3
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002-2003
- * Copyright (C) Stefan (metze) Metzmacher, 2003
- * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-/* cap functions */
-static char *capencode(char *to, const char *from);
-static char *capdecode(char *to, const char *from);
-
-static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path,
- BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_DISK_FREE(handle, conn, cappath, small_query, bsize,
- dfree, dsize);
-}
-
-static DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- pstring capname;
- capencode(capname, fname);
- return SMB_VFS_NEXT_OPENDIR(handle, conn, capname);
-}
-
-static struct dirent *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
-{
- struct dirent *result;
- DEBUG(3,("cap: cap_readdir\n"));
- result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
- if (result) {
- DEBUG(3,("cap: cap_readdir: %s\n", result->d_name));
- capdecode(result->d_name, result->d_name);
- }
- return result;
-}
-
-static int cap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_MKDIR(handle, conn, cappath, mode);
-}
-
-static int cap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_RMDIR(handle, conn, cappath);
-}
-
-static int cap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- pstring capname;
- DEBUG(3,("cap: cap_open for %s\n", fname));
- capencode(capname, fname);
- return SMB_VFS_NEXT_OPEN(handle, conn, capname, flags, mode);
-}
-
-static int cap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
-{
- pstring capold, capnew;
- capencode(capold, old);
- capencode(capnew, new);
-
- return SMB_VFS_NEXT_RENAME(handle, conn, capold, capnew);
-}
-
-static int cap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- pstring capname;
- capencode(capname, fname);
- return SMB_VFS_NEXT_STAT(handle, conn, capname, sbuf);
-}
-
-static int cap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_LSTAT(handle, conn, cappath, sbuf);
-}
-
-static int cap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_UNLINK(handle, conn, cappath);
-}
-
-static int cap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_CHMOD(handle, conn, cappath, mode);
-}
-
-static int cap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_CHOWN(handle, conn, cappath, uid, gid);
-}
-
-static int cap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- pstring cappath;
- DEBUG(3,("cap: cap_chdir for %s\n", path));
- capencode(cappath, path);
- return SMB_VFS_NEXT_CHDIR(handle, conn, cappath);
-}
-
-static int cap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_UTIME(handle, conn, cappath, times);
-}
-
-
-static BOOL cap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- pstring capoldpath, capnewpath;
- capencode(capoldpath, oldpath);
- capencode(capnewpath, newpath);
- return SMB_VFS_NEXT_SYMLINK(handle, conn, capoldpath, capnewpath);
-}
-
-static BOOL cap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_READLINK(handle, conn, cappath, buf, bufsiz);
-}
-
-static int cap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- pstring capoldpath, capnewpath;
- capencode(capoldpath, oldpath);
- capencode(capnewpath, newpath);
- return SMB_VFS_NEXT_LINK(handle, conn, capoldpath, capnewpath);
-}
-
-static int cap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_MKNOD(handle, conn, cappath, mode, dev);
-}
-
-static char *cap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
-{
- /* monyo need capencode'ed and capdecode'ed? */
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
-}
-
-static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-{
- pstring capname;
- capencode(capname, name);
- return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, capname, security_info_sent, psd);
-}
-
-static int cap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
-{
- pstring capname;
- capencode(capname, name);
-
- /* If the underlying VFS doesn't have ACL support... */
- if (!handle->vfs_next.ops.chmod_acl) {
- errno = ENOSYS;
- return -1;
- }
- return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, capname, mode);
-}
-
-static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- pstring cappath_p;
- capencode(cappath_p, path_p);
- return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, cappath_p, type);
-}
-
-static int cap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- pstring capname;
- capencode(capname, name);
- return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, capname, acltype, theacl);
-}
-
-static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, cappath);
-}
-
-static ssize_t cap_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_GETXATTR(handle, conn, cappath, capname, value, size);
-}
-
-static ssize_t cap_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t
-size)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_LGETXATTR(handle, conn, cappath, capname, value, size);
-}
-
-static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-{
- pstring capname;
- capencode(capname, name);
- return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, capname, value, size);
-}
-
-static ssize_t cap_listxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_LISTXATTR(handle, conn, cappath, list, size);
-}
-
-static ssize_t cap_llistxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- pstring cappath;
- capencode(cappath, path);
- return SMB_VFS_NEXT_LLISTXATTR(handle, conn, cappath, list, size);
-}
-
-static int cap_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_REMOVEXATTR(handle, conn, cappath, capname);
-}
-
-static int cap_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, cappath, capname);
-}
-
-static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-{
- pstring capname;
- capencode(capname, name);
- return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, fd, capname);
-}
-
-static int cap_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_SETXATTR(handle, conn, cappath, capname, value, size, flags);
-}
-
-static int cap_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- pstring cappath, capname;
- capencode(cappath, path);
- capencode(capname, name);
- return SMB_VFS_NEXT_LSETXATTR(handle, conn, cappath, capname, value, size, flags);
-}
-
-static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-{
- pstring capname;
- capencode(capname, name);
- return SMB_VFS_NEXT_FSETXATTR(handle, fsp, fd, capname, value, size, flags);
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple cap_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(cap_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Directory operations */
-
- {SMB_VFS_OP(cap_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {SMB_VFS_OP(cap_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_utime), SMB_VFS_OP_UTIME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-
- /* NT File ACL operations */
-
- {SMB_VFS_OP(cap_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
-
- {SMB_VFS_OP(cap_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(cap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* EA operations. */
- {SMB_VFS_OP(cap_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_cap_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap", cap_op_tuples);
-}
-
-/* For CAP functions */
-#define hex_tag ':'
-#define hex2bin(c) hex2bin_table[(unsigned char)(c)]
-#define bin2hex(c) bin2hex_table[(unsigned char)(c)]
-#define is_hex(s) ((s)[0] == hex_tag)
-
-static unsigned char hex2bin_table[256] = {
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
-0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
-0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
-0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
-0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
-0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
-};
-static unsigned char bin2hex_table[256] = "0123456789abcdef";
-
-/*******************************************************************
- original code -> ":xx" - CAP format
-********************************************************************/
-static char *capencode(char *to, const char *from)
-{
- pstring cvtbuf;
- char *out;
-
- if (to == from) {
- from = pstrcpy ((char *) cvtbuf, from);
- }
-
- for (out = to; *from && (out - to < sizeof(pstring)-7);) {
- /* buffer husoku error */
- if ((unsigned char)*from >= 0x80) {
- *out++ = hex_tag;
- *out++ = bin2hex (((*from)>>4)&0x0f);
- *out++ = bin2hex ((*from)&0x0f);
- from++;
- }
- else {
- *out++ = *from++;
- }
- }
- *out = '\0';
- return to;
-}
-
-/*******************************************************************
- CAP -> original code
-********************************************************************/
-/* ":xx" -> a byte */
-static char *capdecode(char *to, const char *from)
-{
- pstring cvtbuf;
- char *out;
-
- if (to == from) {
- from = pstrcpy ((char *) cvtbuf, from);
- }
- for (out = to; *from && (out - to < sizeof(pstring)-3);) {
- if (is_hex(from)) {
- *out++ = (hex2bin (from[1])<<4) | (hex2bin (from[2]));
- from += 3;
- } else {
- *out++ = *from++;
- }
- }
- *out = '\0';
- return to;
-}
diff --git a/source/modules/vfs_default_quota.c b/source/modules/vfs_default_quota.c
deleted file mode 100644
index 1294a515333..00000000000
--- a/source/modules/vfs_default_quota.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Store default Quotas in a specified quota record
- *
- * Copyright (C) Stefan (metze) Metzmacher 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-#define DEFAULT_QUOTA_NAME "default_quota"
-
-#define DEFAULT_QUOTA_UID_DEFAULT 0
-#define DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT True
-#define DEFAULT_QUOTA_GID_DEFAULT 0
-#define DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT True
-
-#define DEFAULT_QUOTA_UID(handle) \
- (uid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid",DEFAULT_QUOTA_UID_DEFAULT)
-
-#define DEFAULT_QUOTA_UID_NOLIMIT(handle) \
- lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid nolimit",DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT)
-
-#define DEFAULT_QUOTA_GID(handle) \
- (gid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid",DEFAULT_QUOTA_GID_DEFAULT)
-
-#define DEFAULT_QUOTA_GID_NOLIMIT(handle) \
- lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT)
-
-static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- int ret = -1;
-
- if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, dq))!=0) {
- return ret;
- }
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- /* we use id.uid == 0 for default quotas */
- if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
- DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
- SMB_QUOTAS_SET_NO_LIMIT(dq);
- }
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- /* we use id.gid == 0 for default quotas */
- if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
- DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
- SMB_QUOTAS_SET_NO_LIMIT(dq);
- }
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- {
- unid_t qid;
- uint32 qflags = dq->qflags;
- qid.uid = DEFAULT_QUOTA_UID(handle);
- SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
- dq->qflags = qflags;
- }
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- {
- unid_t qid;
- uint32 qflags = dq->qflags;
- qid.gid = DEFAULT_QUOTA_GID(handle);
- SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
- dq->qflags = qflags;
- }
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- break;
- }
-
- return ret;
-}
-
-static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
-{
- int ret = -1;
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- /* we use id.uid == 0 for default quotas */
- if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
- DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
- return -1;
- }
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- /* we use id.gid == 0 for default quotas */
- if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
- DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
- return -1;
- }
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- break;
- }
-
- if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, dq))!=0) {
- return ret;
- }
-
- switch (qtype) {
- case SMB_USER_QUOTA_TYPE:
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_QUOTA_TYPE:
- break;
-#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- {
- unid_t qid;
- qid.uid = DEFAULT_QUOTA_UID(handle);
- ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
- }
- break;
-#ifdef HAVE_GROUP_QUOTA
- case SMB_GROUP_FS_QUOTA_TYPE:
- {
- unid_t qid;
- qid.gid = DEFAULT_QUOTA_GID(handle);
- ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
- }
- break;
-#endif /* HAVE_GROUP_QUOTA */
- default:
- errno = ENOSYS;
- return -1;
- break;
- }
-
- return ret;
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple default_quota_ops[] = {
- {SMB_VFS_OP(default_quota_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(default_quota_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_default_quota_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, DEFAULT_QUOTA_NAME, default_quota_ops);
-}
diff --git a/source/modules/vfs_expand_msdfs.c b/source/modules/vfs_expand_msdfs.c
deleted file mode 100644
index 07fbe59825e..00000000000
--- a/source/modules/vfs_expand_msdfs.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Expand msdfs targets based on client IP
- *
- * Copyright (C) Volker Lendecke, 2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-/**********************************************************
- Under mapfile we expect a table of the following format:
-
- IP-Prefix whitespace expansion
-
- For example:
- 192.168.234 local.samba.org
- 192.168 remote.samba.org
- default.samba.org
-
- This is to redirect a DFS client to a host close to it.
-***********************************************************/
-
-static BOOL read_target_host(const char *mapfile, pstring targethost)
-{
- XFILE *f;
- pstring buf;
- char *s, *space = buf;
- BOOL found = False;
-
- f = x_fopen(mapfile, O_RDONLY, 0);
-
- if (f == NULL) {
- DEBUG(0,("can't open IP map %s. Error %s\n",
- mapfile, strerror(errno) ));
- return False;
- }
-
- DEBUG(10, ("Scanning mapfile [%s]\n", mapfile));
-
- while ((s=x_fgets(buf, sizeof(buf), f)) != NULL) {
-
- if ((strlen(buf) > 0) && (buf[strlen(buf)-1] == '\n'))
- buf[strlen(buf)-1] = '\0';
-
- DEBUG(10, ("Scanning line [%s]\n", buf));
-
- space = strchr_m(buf, ' ');
-
- if (space == NULL) {
- DEBUG(0, ("Ignoring invalid line %s\n", buf));
- continue;
- }
-
- *space = '\0';
-
- if (strncmp(client_addr(), buf, strlen(buf)) == 0) {
- found = True;
- break;
- }
- }
-
- x_fclose(f);
-
- if (!found)
- return False;
-
- space += 1;
-
- while (isspace(*space))
- space += 1;
-
- pstrcpy(targethost, space);
- return True;
-}
-
-/**********************************************************
-
- Expand the msdfs target host using read_target_host
- explained above. The syntax used in the msdfs link is
-
- msdfs:@table-filename@/share
-
- Everything between and including the two @-signs is
- replaced by the substitution string found in the table
- described above.
-
-***********************************************************/
-
-static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
-{
- pstring mapfilename;
- char *filename_start = strchr_m(target, '@');
- char *filename_end;
- int filename_len;
- pstring targethost;
- pstring new_target;
-
- if (filename_start == NULL) {
- DEBUG(10, ("No filename start in %s\n", target));
- return False;
- }
-
- filename_end = strchr_m(filename_start+1, '@');
-
- if (filename_end == NULL) {
- DEBUG(10, ("No filename end in %s\n", target));
- return False;
- }
-
- filename_len = PTR_DIFF(filename_end, filename_start+1);
- pstrcpy(mapfilename, filename_start+1);
- mapfilename[filename_len] = '\0';
-
- DEBUG(10, ("Expanding from table [%s]\n", mapfilename));
-
- if (!read_target_host(mapfilename, targethost)) {
- DEBUG(1, ("Could not expand target host from file %s\n",
- mapfilename));
- return False;
- }
-
- standard_sub_conn(conn, mapfilename, sizeof(mapfilename));
-
- DEBUG(10, ("Expanded targethost to %s\n", targethost));
-
- *filename_start = '\0';
- pstrcpy(new_target, target);
- pstrcat(new_target, targethost);
- pstrcat(new_target, filename_end+1);
-
- DEBUG(10, ("New DFS target: %s\n", new_target));
- pstrcpy(target, new_target);
- return True;
-}
-
-static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
- const char *path, char *buf, size_t bufsiz)
-{
- pstring target;
- int result;
-
- result = SMB_VFS_NEXT_READLINK(handle, conn, path, target,
- sizeof(target));
-
- if (result < 0)
- return result;
-
- target[result] = '\0';
-
- if ((strncmp(target, "msdfs:", strlen("msdfs:")) == 0) &&
- (strchr_m(target, '@') != NULL)) {
- if (!expand_msdfs_target(conn, target)) {
- errno = ENOENT;
- return -1;
- }
- }
-
- safe_strcpy(buf, target, bufsiz-1);
- return strlen(buf);
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple expand_msdfs_ops[] = {
- {SMB_VFS_OP(expand_msdfs_readlink), SMB_VFS_OP_READLINK,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_expand_msdfs_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "expand_msdfs",
- expand_msdfs_ops);
-}
diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c
deleted file mode 100644
index 06cddc78e43..00000000000
--- a/source/modules/vfs_extd_audit.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Auditing VFS module for samba. Log selected file operations to syslog
- * facility.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) John H Terpstra, 2003
- * Copyright (C) Stefan (metze) Metzmacher, 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-static int vfs_extd_audit_debug_level = DBGC_VFS;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS vfs_extd_audit_debug_level
-
-/* Function prototypes */
-
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname);
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new);
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
-static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
-
-/* VFS operations */
-
-static vfs_op_tuple audit_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
-
- /* Directory operations */
-
- {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
-
- /* File operations */
-
- {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
-
- /* Finish VFS operations definition */
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-
-static int audit_syslog_facility(vfs_handle_struct *handle)
-{
- /* fix me: let this be configurable by:
- * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog facility",
- * audit_enum_facility,LOG_USER);
- */
- return LOG_USER;
-}
-
-
-static int audit_syslog_priority(vfs_handle_struct *handle)
-{
- /* fix me: let this be configurable by:
- * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog priority",
- * audit_enum_priority,LOG_NOTICE);
- */
- return LOG_NOTICE;
-}
-
-/* Implementation of vfs_ops. Pass everything on to the default
- operation but log event first. */
-
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
-{
- int result;
-
- openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
-
- syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
- svc, user);
- DEBUG(10, ("Connected to service %s as user %s\n",
- svc, user));
-
- result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
-
- return result;
-}
-
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
- syslog(audit_syslog_priority(handle), "disconnected\n");
- DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
-
- return;
-}
-
-static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- DIR *result;
-
- result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
-
- syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: opendir %s %s %s\n",
- fname,
- (result == NULL) ? "failed: " : "",
- (result == NULL) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: mkdir %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
-
- syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: rmdir %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
-
- syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- fname, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
- fname,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- int result;
-
- result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
-
- syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(2, ("vfs_extd_audit: close fd %d %s %s\n",
- fd,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
-{
- int result;
-
- result = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
-
- syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: rename old: %s new: %s %s %s\n",
- old, new,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
-
- syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n",
- path,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
-
- syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n",
- path, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
-
- syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
-
- syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
-NTSTATUS vfs_extd_audit_init(void)
-{
- NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples);
-
- if (!NT_STATUS_IS_OK(ret))
- return ret;
-
- vfs_extd_audit_debug_level = debug_add_class("extd_audit");
- if (vfs_extd_audit_debug_level == -1) {
- vfs_extd_audit_debug_level = DBGC_VFS;
- DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n"));
- } else {
- DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level));
- }
-
- return ret;
-}
diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c
deleted file mode 100644
index 740218dcd41..00000000000
--- a/source/modules/vfs_fake_perms.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Fake Perms VFS module. Implements passthrough operation of all VFS
- * calls to disk functions, except for file permissions, which are now
- * mode 0700 for the current uid/gid.
- *
- * Copyright (C) Tim Potter, 1999-2000
- * Copyright (C) Alexander Bokovoy, 2002
- * Copyright (C) Andrew Bartlett, 2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- int ret = -1;
-
- ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
- if (ret == 0) {
- extern struct current_user current_user;
-
- if (S_ISDIR(sbuf->st_mode)) {
- sbuf->st_mode = S_IFDIR | S_IRWXU;
- } else {
- sbuf->st_mode = S_IRWXU;
- }
- sbuf->st_uid = current_user.uid;
- sbuf->st_gid = current_user.gid;
- }
-
- return ret;
-}
-
-static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
-{
- int ret = -1;
-
- ret = SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf);
- if (ret == 0) {
- extern struct current_user current_user;
-
- if (S_ISDIR(sbuf->st_mode)) {
- sbuf->st_mode = S_IFDIR | S_IRWXU;
- } else {
- sbuf->st_mode = S_IRWXU;
- }
- sbuf->st_uid = current_user.uid;
- sbuf->st_gid = current_user.gid;
- }
- return ret;
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple fake_perms_ops[] = {
- {SMB_VFS_OP(fake_perms_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(fake_perms_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_fake_perms_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "fake_perms", fake_perms_ops);
-}
diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c
deleted file mode 100644
index ae6286e292d..00000000000
--- a/source/modules/vfs_netatalk.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * AppleTalk VFS module for Samba-3.x
- *
- * Copyright (C) Alexei Kotovich, 2002
- * Copyright (C) Stefan (metze) Metzmacher, 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-#define APPLEDOUBLE ".AppleDouble"
-#define ADOUBLEMODE 0777
-
-/* atalk functions */
-
-static int atalk_build_paths(TALLOC_CTX *ctx, const char *path,
- const char *fname, char **adbl_path, char **orig_path,
- SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info);
-
-static int atalk_unlink_file(const char *path);
-
-static int atalk_get_path_ptr(char *path)
-{
- int i = 0;
- int ptr = 0;
-
- for (i = 0; path[i]; i ++) {
- if (path[i] == '/')
- ptr = i;
- /* get out some 'spam';) from win32's file name */
- else if (path[i] == ':') {
- path[i] = '\0';
- break;
- }
- }
-
- return ptr;
-}
-
-static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, const char *fname,
- char **adbl_path, char **orig_path,
- SMB_STRUCT_STAT *adbl_info, SMB_STRUCT_STAT *orig_info)
-{
- int ptr0 = 0;
- int ptr1 = 0;
- char *dname = 0;
- char *name = 0;
-
- if (!ctx || !path || !fname || !adbl_path || !orig_path ||
- !adbl_info || !orig_info)
- return -1;
-#if 0
- DEBUG(3, ("ATALK: PATH: %s[%s]\n", path, fname));
-#endif
- if (strstr(path, APPLEDOUBLE) || strstr(fname, APPLEDOUBLE)) {
- DEBUG(3, ("ATALK: path %s[%s] already contains %s\n", path, fname, APPLEDOUBLE));
- return -1;
- }
-
- if (fname[0] == '.') ptr0 ++;
- if (fname[1] == '/') ptr0 ++;
-
- *orig_path = talloc_asprintf(ctx, "%s/%s", path, &fname[ptr0]);
-
- /* get pointer to last '/' */
- ptr1 = atalk_get_path_ptr(*orig_path);
-
- sys_lstat(*orig_path, orig_info);
-
- if (S_ISDIR(orig_info->st_mode)) {
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
- path, &fname[ptr0], APPLEDOUBLE);
- } else {
- dname = talloc_strdup(ctx, *orig_path);
- dname[ptr1] = '\0';
- name = *orig_path;
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s",
- dname, APPLEDOUBLE, &name[ptr1 + 1]);
- }
-#if 0
- DEBUG(3, ("ATALK: DEBUG:\n%s\n%s\n", *orig_path, *adbl_path));
-#endif
- sys_lstat(*adbl_path, adbl_info);
- return 0;
-}
-
-static int atalk_unlink_file(const char *path)
-{
- int ret = 0;
-
- become_root();
- ret = unlink(path);
- unbecome_root();
-
- return ret;
-}
-
-static void atalk_add_to_list(name_compare_entry **list)
-{
- int i, count = 0;
- name_compare_entry *new_list = 0;
- name_compare_entry *cur_list = 0;
-
- cur_list = *list;
-
- if (cur_list) {
- for (i = 0, count = 0; cur_list[i].name; i ++, count ++) {
- if (strstr(cur_list[i].name, APPLEDOUBLE))
- return;
- }
- }
-
- if (!(new_list = calloc(1,
- (count == 0 ? 1 : count + 1) * sizeof(name_compare_entry))))
- return;
-
- for (i = 0; i < count; i ++) {
- new_list[i].name = strdup(cur_list[i].name);
- new_list[i].is_wild = cur_list[i].is_wild;
- }
-
- new_list[i].name = strdup(APPLEDOUBLE);
- new_list[i].is_wild = False;
-
- free_namearray(*list);
-
- *list = new_list;
- new_list = 0;
- cur_list = 0;
-}
-
-static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
-{
- char *dpath;
- struct dirent *dent = 0;
- DIR *dir;
-
- if (!path) return;
-
- dir = opendir(path);
- if (!dir) return;
-
- while (NULL != (dent = readdir(dir))) {
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- if (!(dpath = talloc_asprintf(ctx, "%s/%s",
- path, dent->d_name)))
- continue;
- atalk_unlink_file(dpath);
- }
-
- closedir(dir);
-}
-
-/* Disk operations */
-
-/* Directory operations */
-
-DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname)
-{
- DIR *ret = 0;
-
- ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
-
- /*
- * when we try to perform delete operation upon file which has fork
- * in ./.AppleDouble and this directory wasn't hidden by Samba,
- * MS Windows explorer causes the error: "Cannot find the specified file"
- * There is some workaround to avoid this situation, i.e. if
- * connection has not .AppleDouble entry in either veto or hide
- * list then it would be nice to add one.
- */
-
- atalk_add_to_list(&conn->hide_list);
- atalk_add_to_list(&conn->veto_list);
-
- return ret;
-}
-
-static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
-{
- BOOL add = False;
- TALLOC_CTX *ctx = 0;
- char *dpath;
-
- if (!conn || !conn->origpath || !path) goto exit_rmdir;
-
- /* due to there is no way to change bDeleteVetoFiles variable
- * from this module, gotta use talloc stuff..
- */
-
- strstr(path, APPLEDOUBLE) ? (add = False) : (add = True);
-
- if (!(ctx = talloc_init("remove_directory")))
- goto exit_rmdir;
-
- if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
- conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
- goto exit_rmdir;
-
- atalk_rrmdir(ctx, dpath);
-
-exit_rmdir:
- talloc_destroy(ctx);
- return SMB_VFS_NEXT_RMDIR(handle, conn, path);
-}
-
-/* File operations */
-
-static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
-
- if (!conn || !old) return ret;
-
- if (!(ctx = talloc_init("rename_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, old, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
- goto exit_rename;
- }
-
- atalk_unlink_file(adbl_path);
-
-exit_rename:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
-{
- int ret = 0, i;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = SMB_VFS_NEXT_UNLINK(handle, conn, path);
-
- if (!conn || !path) return ret;
-
- /* no .AppleDouble sync if veto or hide list is empty,
- * otherwise "Cannot find the specified file" error will be caused
- */
-
- if (!conn->veto_list) return ret;
- if (!conn->hide_list) return ret;
-
- for (i = 0; conn->veto_list[i].name; i ++) {
- if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
- break;
- }
-
- if (!conn->veto_list[i].name) {
- for (i = 0; conn->hide_list[i].name; i ++) {
- if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
- break;
- else {
- DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
- APPLEDOUBLE));
- return ret;
- }
- }
- }
-
- if (!(ctx = talloc_init("unlink_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
- goto exit_unlink;
- }
-
- atalk_unlink_file(adbl_path);
-
-exit_unlink:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
-
- if (!conn || !path) return ret;
-
- if (!(ctx = talloc_init("chmod_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
- goto exit_chmod;
- }
-
- chmod(adbl_path, ADOUBLEMODE);
-
-exit_chmod:
- talloc_destroy(ctx);
- return ret;
-}
-
-static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-{
- int ret = 0;
- char *adbl_path = 0;
- char *orig_path = 0;
- SMB_STRUCT_STAT adbl_info;
- SMB_STRUCT_STAT orig_info;
- TALLOC_CTX *ctx;
-
- ret = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid);
-
- if (!conn || !path) return ret;
-
- if (!(ctx = talloc_init("chown_file")))
- return ret;
-
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
- &adbl_info, &orig_info) != 0)
- return ret;
-
- if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
- goto exit_chown;
- }
-
- chown(adbl_path, uid, gid);
-
-exit_chown:
- talloc_destroy(ctx);
- return ret;
-}
-
-static vfs_op_tuple atalk_ops[] = {
-
- /* Directory operations */
-
- {SMB_VFS_OP(atalk_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(atalk_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {SMB_VFS_OP(atalk_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Finish VFS operations definition */
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_netatalk_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "netatalk", atalk_ops);
-}
diff --git a/source/modules/vfs_readonly.c b/source/modules/vfs_readonly.c
deleted file mode 100644
index ee9e40c2fca..00000000000
--- a/source/modules/vfs_readonly.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- VFS module to perform read-only limitation based on a time period
- Copyright (C) Alexander Bokovoy 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- This work was sponsored by Optifacio Software Services, Inc.
-*/
-
-#include "includes.h"
-#include "getdate.h"
-
-/*
- This module performs a read-only limitation for specified share
- (or all of them if it is loaded in a [global] section) based on period
- definition in smb.conf. You can stack this module multiple times under
- different names to get multiple limit intervals.
-
- The module uses get_date() function from coreutils' date utility to parse
- specified dates according to date(1) rules. Look into info page for date(1)
- to understand the syntax.
-
- The module accepts one parameter:
-
- readonly: period = "begin date","end date"
-
- where "begin date" and "end date" are mandatory and should comply with date(1)
- syntax for date strings.
-
- Example:
-
- readonly: period = "today 14:00","today 15:00"
-
- Default:
-
- readonly: period = "today 0:0:0","tomorrow 0:0:0"
-
- The default covers whole day thus making the share readonly
-
- */
-
-#define MODULE_NAME "readonly"
-static int readonly_connect(vfs_handle_struct *handle,
- connection_struct *conn,
- const char *service,
- const char *user)
-{
- const char *period_def[] = {"today 0:0:0", "tomorrow 0:0:0"};
-
- const char **period = lp_parm_string_list(SNUM(handle->conn),
- (handle->param ? handle->param : MODULE_NAME),
- "period", period_def);
-
- if (period && period[0] && period[1]) {
- time_t current_time = time(NULL);
- time_t begin_period = get_date(period[0], &current_time);
- time_t end_period = get_date(period[1], &current_time);
-
- if ((current_time >= begin_period) && (current_time <= end_period)) {
- conn->read_only = True;
- }
-
- return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
-
- } else {
-
- return 1;
-
- }
-}
-
-
-/* VFS operations structure */
-
-static vfs_op_tuple readonly_op_tuples[] = {
- /* Disk operations */
- {SMB_VFS_OP(readonly_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_readonly_init(void)
-{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE_NAME, readonly_op_tuples);
-}
diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c
deleted file mode 100644
index 1cb1cb327b4..00000000000
--- a/source/modules/vfs_recycle.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Recycle bin VFS module for Samba.
- *
- * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>.
- * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module.
- * Copyright (C) 2002, Alexander Bokovoy - cascaded VFS adoption,
- * Copyright (C) 2002, Juergen Hasch - added some options.
- * Copyright (C) 2002, Simo Sorce
- * Copyright (C) 2002, Stefan (metze) Metzmacher
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#define ALLOC_CHECK(ptr, label) do { if ((ptr) == NULL) { DEBUG(0, ("recycle.bin: out of memory!\n")); errno = ENOMEM; goto label; } } while(0)
-
-static int vfs_recycle_debug_level = DBGC_VFS;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS vfs_recycle_debug_level
-
-static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user);
-static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name);
-
-static vfs_op_tuple recycle_ops[] = {
-
- /* Disk operations */
- {SMB_VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
- {SMB_VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
-{
- DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n",
- service,user));
-
- return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
-}
-
-static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
- DEBUG(10,("recycle_disconnect() connect to service[%s].\n",
- lp_servicename(SNUM(conn))));
-
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
-}
-
-static const char *recycle_repository(vfs_handle_struct *handle)
-{
- const char *tmp_str = NULL;
-
-
- tmp_str = lp_parm_const_string(SNUM(handle->conn), "recycle", "repository",".recycle");
-
- DEBUG(10, ("recycle: repository = %s\n", tmp_str));
-
- return tmp_str;
-}
-
-static BOOL recycle_keep_dir_tree(vfs_handle_struct *handle)
-{
- BOOL ret;
-
- ret = lp_parm_bool(SNUM(handle->conn), "recycle", "keeptree", False);
-
- DEBUG(10, ("recycle_bin: keeptree = %s\n", ret?"True":"False"));
-
- return ret;
-}
-
-static BOOL recycle_versions(vfs_handle_struct *handle)
-{
- BOOL ret;
-
- ret = lp_parm_bool(SNUM(handle->conn), "recycle", "versions", False);
-
- DEBUG(10, ("recycle: versions = %s\n", ret?"True":"False"));
-
- return ret;
-}
-
-static BOOL recycle_touch(vfs_handle_struct *handle)
-{
- BOOL ret;
-
- ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch", False);
-
- DEBUG(10, ("recycle: touch = %s\n", ret?"True":"False"));
-
- return ret;
-}
-
-static const char **recycle_exclude(vfs_handle_struct *handle)
-{
- const char **tmp_lp;
-
- tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude", NULL);
-
- DEBUG(10, ("recycle: exclude = %s ...\n", tmp_lp?*tmp_lp:""));
-
- return tmp_lp;
-}
-
-static const char **recycle_exclude_dir(vfs_handle_struct *handle)
-{
- const char **tmp_lp;
-
- tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude_dir", NULL);
-
- DEBUG(10, ("recycle: exclude_dir = %s ...\n", tmp_lp?*tmp_lp:""));
-
- return tmp_lp;
-}
-
-static const char **recycle_noversions(vfs_handle_struct *handle)
-{
- const char **tmp_lp;
-
- tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "noversions", NULL);
-
- DEBUG(10, ("recycle: noversions = %s\n", tmp_lp?*tmp_lp:""));
-
- return tmp_lp;
-}
-
-static int recycle_maxsize(vfs_handle_struct *handle)
-{
- int maxsize;
-
- maxsize = lp_parm_int(SNUM(handle->conn), "recycle", "maxsize", -1);
-
- DEBUG(10, ("recycle: maxsize = %d\n", maxsize));
-
- return maxsize;
-}
-
-static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname)
-{
- SMB_STRUCT_STAT st;
-
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) {
- if (S_ISDIR(st.st_mode)) {
- return True;
- }
- }
-
- return False;
-}
-
-static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname)
-{
- SMB_STRUCT_STAT st;
-
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) {
- if (S_ISREG(st.st_mode)) {
- return True;
- }
- }
-
- return False;
-}
-
-/**
- * Return file size
- * @param conn connection
- * @param fname file name
- * @return size in bytes
- **/
-static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fname)
-{
- SMB_STRUCT_STAT st;
-
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
- DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
- return (SMB_OFF_T)0;
- }
-
- return(st.st_size);
-}
-
-/**
- * Create directory tree
- * @param conn connection
- * @param dname Directory tree to be created
- * @return Returns True for success
- **/
-static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname)
-{
- int len;
- mode_t mode;
- char *new_dir = NULL;
- char *tmp_str = NULL;
- char *token;
- char *tok_str;
- BOOL ret = False;
-
- mode = S_IRUSR | S_IWUSR | S_IXUSR;
-
- tmp_str = strdup(dname);
- ALLOC_CHECK(tmp_str, done);
- tok_str = tmp_str;
-
- len = strlen(dname)+1;
- new_dir = (char *)malloc(len + 1);
- ALLOC_CHECK(new_dir, done);
- *new_dir = '\0';
-
- /* Create directory tree if neccessary */
- for(token = strtok(tok_str, "/"); token; token = strtok(NULL, "/")) {
- safe_strcat(new_dir, token, len);
- if (recycle_directory_exist(handle, new_dir))
- DEBUG(10, ("recycle: dir %s already exists\n", new_dir));
- else {
- DEBUG(5, ("recycle: creating new dir %s\n", new_dir));
- if (SMB_VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) {
- DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
- ret = False;
- goto done;
- }
- }
- safe_strcat(new_dir, "/", len);
- }
-
- ret = True;
-done:
- SAFE_FREE(tmp_str);
- SAFE_FREE(new_dir);
- return ret;
-}
-
-/**
- * Check if needle is contained exactly in haystack
- * @param haystack list of parameters separated by delimimiter character
- * @param needle string to be matched exactly to haystack
- * @return True if found
- **/
-static BOOL checkparam(const char **haystack_list, const char *needle)
-{
- int i;
-
- if (haystack_list == NULL || haystack_list[0] == NULL ||
- *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') {
- return False;
- }
-
- for(i=0; haystack_list[i] ; i++) {
- if(strequal(haystack_list[i], needle)) {
- return True;
- }
- }
-
- return False;
-}
-
-/**
- * Check if needle is contained in haystack, * and ? patterns are resolved
- * @param haystack list of parameters separated by delimimiter character
- * @param needle string to be matched exectly to haystack including pattern matching
- * @return True if found
- **/
-static BOOL matchparam(const char **haystack_list, const char *needle)
-{
- int i;
-
- if (haystack_list == NULL || haystack_list[0] == NULL ||
- *haystack_list[0] == '\0' || needle == NULL || *needle == '\0') {
- return False;
- }
-
- for(i=0; haystack_list[i] ; i++) {
- if(!unix_wild_match(haystack_list[i], needle)) {
- return True;
- }
- }
-
- return False;
-}
-
-/**
- * Touch access date
- **/
-static void recycle_do_touch(vfs_handle_struct *handle, const char *fname)
-{
- SMB_STRUCT_STAT st;
- struct utimbuf tb;
- time_t currtime;
-
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
- DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
- return;
- }
- currtime = time(&currtime);
- tb.actime = currtime;
- tb.modtime = st.st_mtime;
-
- if (SMB_VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) {
- DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno)));
- }
-}
-
-/**
- * Check if file should be recycled
- **/
-static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name)
-{
- char *path_name = NULL;
- char *temp_name = NULL;
- char *final_name = NULL;
- const char *base;
- char *repository = NULL;
- int i = 1;
- int maxsize;
- SMB_OFF_T file_size; /* space_avail; */
- BOOL exist;
- int rc = -1;
-
- repository = alloc_sub_conn(conn, recycle_repository(handle));
- ALLOC_CHECK(repository, done);
- /* shouldn't we allow absolute path names here? --metze */
- trim_char(repository, '/', '/');
-
- if(!repository || *(repository) == '\0') {
- DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- /* we don't recycle the recycle bin... */
- if (strncmp(file_name, repository, strlen(repository)) == 0) {
- DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n"));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- file_size = recycle_get_file_size(handle, file_name);
- /* it is wrong to purge filenames only because they are empty imho
- * --- simo
- *
- if(fsize == 0) {
- DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name);
- goto done;
- }
- */
-
- /* FIXME: this is wrong, we should check the hole size of the recycle bin is
- * not greater then maxsize, not the size of the single file, also it is better
- * to remove older files
- */
- maxsize = recycle_maxsize(handle);
- if(maxsize > 0 && file_size > maxsize) {
- DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- /* FIXME: this is wrong: moving files with rename does not change the disk space
- * allocation
- *
- space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
- DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
- if(space_avail < file_size) {
- DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
- */
-
- /* extract filename and path */
- base = strrchr(file_name, '/');
- if (base == NULL) {
- base = file_name;
- path_name = strdup("/");
- ALLOC_CHECK(path_name, done);
- }
- else {
- path_name = strdup(file_name);
- ALLOC_CHECK(path_name, done);
- path_name[base - file_name] = '\0';
- base++;
- }
-
- DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */
- DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */
- DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */
-
- if (matchparam(recycle_exclude(handle), base)) {
- DEBUG(3, ("recycle: file %s is excluded \n", base));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- /* FIXME: this check will fail if we have more than one level of directories,
- * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 ....
- * ---simo
- */
- if (checkparam(recycle_exclude_dir(handle), path_name)) {
- DEBUG(3, ("recycle: directory %s is excluded \n", path_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- if (recycle_keep_dir_tree(handle) == True) {
- asprintf(&temp_name, "%s/%s", repository, path_name);
- } else {
- temp_name = strdup(repository);
- }
- ALLOC_CHECK(temp_name, done);
-
- exist = recycle_directory_exist(handle, temp_name);
- if (exist) {
- DEBUG(10, ("recycle: Directory already exists\n"));
- } else {
- DEBUG(10, ("recycle: Creating directory %s\n", temp_name));
- if (recycle_create_dir(handle, temp_name) == False) {
- DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
- }
-
- asprintf(&final_name, "%s/%s", temp_name, base);
- ALLOC_CHECK(final_name, done);
- DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */
-
- /* check if we should delete file from recycle bin */
- if (recycle_file_exist(handle, final_name)) {
- if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) {
- DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name));
- if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) {
- DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno)));
- }
- }
- }
-
- /* rename file we move to recycle bin */
- i = 1;
- while (recycle_file_exist(handle, final_name)) {
- SAFE_FREE(final_name);
- asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base);
- }
-
- DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name));
- rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name);
- if (rc != 0) {
- DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
- goto done;
- }
-
- /* touch access date of moved file */
- if (recycle_touch(handle) == True )
- recycle_do_touch(handle, final_name);
-
-done:
- SAFE_FREE(path_name);
- SAFE_FREE(temp_name);
- SAFE_FREE(final_name);
- SAFE_FREE(repository);
- return rc;
-}
-
-NTSTATUS vfs_recycle_init(void)
-{
- NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops);
-
- if (!NT_STATUS_IS_OK(ret))
- return ret;
-
- vfs_recycle_debug_level = debug_add_class("recycle");
- if (vfs_recycle_debug_level == -1) {
- vfs_recycle_debug_level = DBGC_VFS;
- DEBUG(0, ("vfs_recycle: Couldn't register custom debugging class!\n"));
- } else {
- DEBUG(10, ("vfs_recycle: Debug class number of 'recycle': %d\n", vfs_recycle_debug_level));
- }
-
- return ret;
-}
diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c
deleted file mode 100644
index 7ad7b1f7b14..00000000000
--- a/source/modules/vfs_shadow_copy.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * implementation of an Shadow Copy module
- *
- * Copyright (C) Stefan Metzmacher 2003-2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*
- Please read the VFS module Samba-HowTo-Collection.
- there's a chapter about this module
-
- For this share
- Z:\
-
- the ShadowCopies are in this directories
-
- Z:\@GMT-2003.08.05-12.00.00\
- Z:\@GMT-2003.08.05-12.01.00\
- Z:\@GMT-2003.08.05-12.02.00\
-
- e.g.
-
- Z:\testfile.txt
- Z:\@GMT-2003.08.05-12.02.00\testfile.txt
-
- or:
-
- Z:\testdir\testfile.txt
- Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt
-
-
- Note: Files must differ to be displayed via Windows Explorer!
- Directories are always displayed...
-*/
-
-static int vfs_shadow_copy_debug_level = DBGC_VFS;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS vfs_shadow_copy_debug_level
-
-#define SHADOW_COPY_PREFIX "@GMT-"
-#define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00"
-
-typedef struct {
- int pos;
- int num;
- struct dirent *dirs;
-} shadow_copy_Dir;
-
-static BOOL shadow_copy_match_name(const char *name)
-{
- if (strncmp(SHADOW_COPY_PREFIX,name, sizeof(SHADOW_COPY_PREFIX)-1)==0 &&
- (strlen(SHADOW_COPY_SAMPLE) == strlen(name))) {
- return True;
- }
-
- return False;
-}
-
-static DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
-{
- shadow_copy_Dir *dirp;
- DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname);
-
- if (!p) {
- DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname));
- return NULL;
- }
-
- dirp = (shadow_copy_Dir *)malloc(sizeof(shadow_copy_Dir));
- if (!dirp) {
- DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
- SMB_VFS_NEXT_CLOSEDIR(handle,conn,p);
- return NULL;
- }
-
- ZERO_STRUCTP(dirp);
-
- while (True) {
- struct dirent *d;
- struct dirent *r;
-
-
- d = SMB_VFS_NEXT_READDIR(handle, conn, p);
- if (d == NULL) {
- break;
- }
-
- if (shadow_copy_match_name(d->d_name)) {
- DEBUG(8,("shadow_copy_opendir: hide [%s]\n",d->d_name));
- continue;
- }
-
- DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name));
-
- r = (struct dirent *)Realloc(dirp->dirs,(dirp->num+1)*sizeof(struct dirent));
- if (!r) {
- DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
- break;
- }
-
- dirp->dirs = r;
- dirp->dirs[dirp->num++] = *d;
- }
-
- SMB_VFS_NEXT_CLOSEDIR(handle,conn,p);
- return((DIR *)dirp);
-}
-
-struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
-{
- shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
-
- if (dirp->pos < dirp->num) {
- return &(dirp->dirs[dirp->pos++]);
- }
-
- return NULL;
-}
-
-int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
-{
- shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
-
- SAFE_FREE(dirp);
-
- return 0;
-}
-
-static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath);
-
- shadow_copy_data->num_volumes = 0;
- shadow_copy_data->labels = NULL;
-
- if (!p) {
- DEBUG(0,("shadow_copy_get_shadow_copy_data: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fsp->conn->connectpath));
- return -1;
- }
-
- while (True) {
- SHADOW_COPY_LABEL *tlabels;
- struct dirent *d;
-
- d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p);
- if (d == NULL) {
- break;
- }
-
- /* */
- if (!shadow_copy_match_name(d->d_name)) {
- DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore [%s]\n",d->d_name));
- continue;
- }
-
- DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore [%s]\n",d->d_name));
-
- if (!labels) {
- shadow_copy_data->num_volumes++;
- continue;
- }
-
- tlabels = (SHADOW_COPY_LABEL *)talloc_realloc(shadow_copy_data->mem_ctx,
- shadow_copy_data->labels,
- (shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL));
- if (tlabels == NULL) {
- DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n"));
- SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
- return -1;
- }
-
- snprintf(tlabels[shadow_copy_data->num_volumes++], sizeof(*tlabels), "%s",d->d_name);
-
- shadow_copy_data->labels = tlabels;
- }
-
- SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
- return 0;
-}
-
-/* VFS operations structure */
-
-static vfs_op_tuple shadow_copy_ops[] = {
- {SMB_VFS_OP(shadow_copy_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(shadow_copy_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(shadow_copy_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-NTSTATUS vfs_shadow_copy_init(void)
-{
- NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy", shadow_copy_ops);
-
- if (!NT_STATUS_IS_OK(ret))
- return ret;
-
- vfs_shadow_copy_debug_level = debug_add_class("shadow_copy");
- if (vfs_shadow_copy_debug_level == -1) {
- vfs_shadow_copy_debug_level = DBGC_VFS;
- DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
- "vfs_shadow_copy_init"));
- } else {
- DEBUG(10, ("%s: Debug class number of '%s': %d\n",
- "vfs_shadow_copy_init","shadow_copy",vfs_shadow_copy_debug_level));
- }
-
- return ret;
-}
diff --git a/source/modules/weird.c b/source/modules/weird.c
deleted file mode 100644
index 444853f3831..00000000000
--- a/source/modules/weird.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba module with developer tools
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static struct {
- char from;
- char *to;
- int len;
-} weird_table[] = {
- {'q', "^q^", 3},
- {'Q', "^Q^", 3},
- {0, NULL}
-};
-
-static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- int i;
- int done = 0;
- for (i=0;weird_table[i].from;i++) {
- if (strncmp((*inbuf),
- weird_table[i].to,
- weird_table[i].len) == 0) {
- if (*inbytesleft < weird_table[i].len) {
- DEBUG(0,("ERROR: truncated weird string\n"));
- /* smb_panic("weird_pull"); */
-
- } else {
- (*outbuf)[0] = weird_table[i].from;
- (*outbuf)[1] = 0;
- (*inbytesleft) -= weird_table[i].len;
- (*outbytesleft) -= 2;
- (*inbuf) += weird_table[i].len;
- (*outbuf) += 2;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
- (*outbuf)[0] = (*inbuf)[0];
- (*outbuf)[1] = 0;
- (*inbytesleft) -= 1;
- (*outbytesleft) -= 2;
- (*inbuf) += 1;
- (*outbuf) += 2;
- }
-
- if (*inbytesleft > 0) {
- errno = E2BIG;
- return -1;
- }
-
- return 0;
-}
-
-static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- int ir_count=0;
-
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- int i;
- int done=0;
- for (i=0;weird_table[i].from;i++) {
- if ((*inbuf)[0] == weird_table[i].from &&
- (*inbuf)[1] == 0) {
- if (*outbytesleft < weird_table[i].len) {
- DEBUG(0,("No room for weird character\n"));
- /* smb_panic("weird_push"); */
- } else {
- memcpy(*outbuf, weird_table[i].to,
- weird_table[i].len);
- (*inbytesleft) -= 2;
- (*outbytesleft) -= weird_table[i].len;
- (*inbuf) += 2;
- (*outbuf) += weird_table[i].len;
- done = 1;
- break;
- }
- }
- }
- if (done) continue;
-
- (*outbuf)[0] = (*inbuf)[0];
- if ((*inbuf)[1]) ir_count++;
- (*inbytesleft) -= 2;
- (*outbytesleft) -= 1;
- (*inbuf) += 2;
- (*outbuf) += 1;
- }
-
- if (*inbytesleft == 1) {
- errno = EINVAL;
- return -1;
- }
-
- if (*inbytesleft > 1) {
- errno = E2BIG;
- return -1;
- }
-
- return ir_count;
-}
-
-struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push};
-
-NTSTATUS charset_weird_init(void)
-{
- return smb_register_charset(&weird_functions);
-}
diff --git a/source/msdfs/README b/source/msdfs/README
new file mode 100755
index 00000000000..0e924b31dce
--- /dev/null
+++ b/source/msdfs/README
@@ -0,0 +1,32 @@
+Setting up MS Dfs in Samba
+kalele@veritas.com March 2000
+
+Currently, MS Dfs support is a configure time parameter (--with-msdfs). Can be changed later to always compile it in..
+
+To have a server announce itself as a Dfs server, add a "host msdfs=yes" entry to smb.conf.
+
+To make a share a Dfs root, add a "msdfs root=yes" entry to the share definition
+in the smb.conf file.
+e.g.
+[pub]
+ path = /export/publicsmb
+ msdfs root = yes
+
+To create dfs volumes/junctions in the share, create symbolic links of the
+format msdfs:server1\share1,server2\share2 and so on.
+
+In the above example, create a dfs volume "dfsstorage" in the [pub] share as:
+cd /export/publicsmb
+ln -s msdfs:serverA\\share dfsstorage
+
+Clicking on dfsstorage from a dfs-aware client will show you the contents of
+\\serverA\share
+
+Shares with "msdfs root = no" (which is the default) entries are served as normal
+shares and the client stops talking Dfs with Samba after a tconX.
+
+NOTES:
+* Windows clients need to be rebooted if a non-dfs root is made a dfs root or
+ vice versa. A better option is to introduce a new share and make it the dfs root.
+* Currently there's a restriction that msdfs symlink names should be all
+ lowercase.
diff --git a/source/smbd/msdfs.c b/source/msdfs/msdfs.c
index c66f0477a84..11d2d0b5eba 100644..100755
--- a/source/smbd/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -25,6 +25,8 @@
extern fstring local_machine;
extern uint32 global_client_caps;
+#ifdef WITH_MSDFS
+
/**********************************************************************
Parse the pathname of the form \hostname\service\reqpath
into the dfs_path structure
@@ -40,21 +42,21 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
ZERO_STRUCTP(pdp);
- trim_char(temp,'\\','\\');
+ trim_string(temp,"\\","\\");
DEBUG(10,("temp in parse_dfs_path: .%s. after trimming \\'s\n",temp));
/* now tokenize */
/* parse out hostname */
- p = strchr_m(temp,'\\');
+ p = strchr(temp,'\\');
if(p == NULL)
return False;
*p = '\0';
pstrcpy(pdp->hostname,temp);
- DEBUG(10,("parse_dfs_path: hostname: %s\n",pdp->hostname));
+ DEBUG(10,("hostname: %s\n",pdp->hostname));
/* parse out servicename */
temp = p+1;
- p = strchr_m(temp,'\\');
+ p = strchr(temp,'\\');
if(p == NULL) {
pstrcpy(pdp->servicename,temp);
pdp->reqpath[0] = '\0';
@@ -62,96 +64,34 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
}
*p = '\0';
pstrcpy(pdp->servicename,temp);
- DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename));
+ DEBUG(10,("servicename: %s\n",pdp->servicename));
/* rest is reqpath */
- check_path_syntax(pdp->reqpath, p+1);
-
- DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath));
- return True;
-}
-
-/**********************************************************************
- Parse the pathname of the form /hostname/service/reqpath
- into the dfs_path structure
- **********************************************************************/
-
-static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
-{
- pstring pathname_local;
- char* p,*temp;
-
- pstrcpy(pathname_local,pathname);
- p = temp = pathname_local;
-
- ZERO_STRUCTP(pdp);
-
- trim_char(temp,'/','/');
- DEBUG(10,("temp in parse_processed_dfs_path: .%s. after trimming \\'s\n",temp));
-
- /* now tokenize */
- /* parse out hostname */
- p = strchr_m(temp,'/');
- if(p == NULL)
- return False;
- *p = '\0';
- pstrcpy(pdp->hostname,temp);
- DEBUG(10,("parse_processed_dfs_path: hostname: %s\n",pdp->hostname));
-
- /* parse out servicename */
- temp = p+1;
- p = strchr_m(temp,'/');
- if(p == NULL) {
- pstrcpy(pdp->servicename,temp);
- pdp->reqpath[0] = '\0';
- return True;
+ pstrcpy(pdp->reqpath, p+1);
+ p = pdp->reqpath;
+ while (*p) {
+ if (*p == '\\') *p = '/';
+ p++;
}
- *p = '\0';
- pstrcpy(pdp->servicename,temp);
- DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename));
- /* rest is reqpath */
- check_path_syntax(pdp->reqpath, p+1);
-
- DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath));
+ DEBUG(10,("rest of the path: %s\n",pdp->reqpath));
return True;
}
/********************************************************
Fake up a connection struct for the VFS layer.
- Note this CHANGES CWD !!!! JRA.
*********************************************************/
-static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
+static BOOL create_conn_struct( connection_struct *conn, int snum)
{
+
ZERO_STRUCTP(conn);
conn->service = snum;
- conn->connectpath = path;
- pstring_sub(conn->connectpath , "%S", lp_servicename(snum));
+ conn->connectpath = lp_pathname(snum);
+ pstring_sub(conn->connectpath, "%S", lp_servicename(snum));
- /* needed for smbd_vfs_init() */
-
- if ( (conn->mem_ctx=talloc_init("connection_struct")) == NULL ) {
- DEBUG(0,("talloc_init(connection_struct) failed!\n"));
- return False;
- }
-
if (!smbd_vfs_init(conn)) {
DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
- talloc_destroy( conn->mem_ctx );
- return False;
- }
-
- /*
- * Windows seems to insist on doing trans2getdfsreferral() calls on the IPC$
- * share as the anonymous user. If we try to chdir as that user we will
- * fail.... WTF ? JRA.
- */
-
- if (vfs_ChDir(conn,conn->connectpath) != 0) {
- DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. Error was %s\n",
- conn->connectpath, strerror(errno) ));
- talloc_destroy( conn->mem_ctx );
return False;
}
return True;
@@ -162,7 +102,6 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
Parse the contents of a symlink to verify if it is an msdfs referral
A valid referral is of the form: msdfs:server1\share1,server2\share2
**********************************************************************/
-
static BOOL parse_symlink(char* buf,struct referral** preflist,
int* refcount)
{
@@ -196,21 +135,13 @@ static BOOL parse_symlink(char* buf,struct referral** preflist,
}
for(i=0;i<count;i++) {
- char *p;
-
- /* replace all /'s in the alternate path by a \ */
- for(p = alt_path[i]; *p && ((p = strchr_m(p,'/'))!=NULL); p++) {
+ /* replace / in the alternate path by a \ */
+ char* p = strchr(alt_path[i],'/');
+ if(p)
*p = '\\';
- }
-
- /* Remove leading '\\'s */
- p = alt_path[i];
- while (*p && (*p == '\\')) {
- p++;
- }
pstrcpy(reflist[i].alternate_path, "\\");
- pstrcat(reflist[i].alternate_path, p);
+ pstrcat(reflist[i].alternate_path, alt_path[i]);
reflist[i].proximity = 0;
reflist[i].ttl = REFERRAL_TTL;
DEBUG(10, ("parse_symlink: Created alt path: %s\n", reflist[i].alternate_path));
@@ -225,8 +156,7 @@ static BOOL parse_symlink(char* buf,struct referral** preflist,
/**********************************************************************
Returns true if the unix path is a valid msdfs symlink
**********************************************************************/
-
-BOOL is_msdfs_link(connection_struct* conn, char * path,
+BOOL is_msdfs_link(connection_struct* conn, char* path,
struct referral** reflistp, int* refcnt,
SMB_STRUCT_STAT *sbufp)
{
@@ -237,17 +167,19 @@ BOOL is_msdfs_link(connection_struct* conn, char * path,
if (!path || !conn)
return False;
+ strlower(path);
+
if (sbufp == NULL)
sbufp = &st;
- if (SMB_VFS_LSTAT(conn, path, sbufp) != 0) {
+ if (conn->vfs_ops.lstat(conn,dos_to_unix_static(path), sbufp) != 0) {
DEBUG(5,("is_msdfs_link: %s does not exist.\n",path));
return False;
}
if (S_ISLNK(sbufp->st_mode)) {
/* open the link and read it */
- referral_len = SMB_VFS_READLINK(conn, path, referral,
+ referral_len = conn->vfs_ops.readlink(conn, path, referral,
sizeof(pstring));
if (referral_len == -1) {
DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", path, strerror(errno)));
@@ -275,21 +207,17 @@ they request referrals for dfs roots on a server.
consumedcntp: how much of the dfs path is being redirected. the client
should try the remaining path on the redirected server.
-
*****************************************************************/
-
-static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
+static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
connection_struct* conn,
BOOL findfirst_flag,
struct referral** reflistpp, int* refcntp,
BOOL* self_referralp, int* consumedcntp)
{
- pstring localpath;
+ fstring localpath;
int consumed_level = 1;
char *p;
- BOOL bad_path = False;
- SMB_STRUCT_STAT sbuf;
- pstring reqpath;
+ fstring reqpath;
if (!dp || !conn) {
DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n"));
@@ -304,13 +232,10 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
return False;
}
- DEBUG(10,("resolve_dfs_path: Conn path = %s req_path = %s\n", conn->connectpath, dp->reqpath));
-
- unix_convert(dp->reqpath,conn,0,&bad_path,&sbuf);
- /* JRA... should we strlower the last component here.... ? */
- pstrcpy(localpath, dp->reqpath);
-
/* check if need to redirect */
+ fstrcpy(localpath, conn->connectpath);
+ fstrcat(localpath, "/");
+ fstrcat(localpath, dp->reqpath);
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
if (findfirst_flag) {
DEBUG(6,("resolve_dfs_path (FindFirst) No redirection "
@@ -326,11 +251,13 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
}
/* redirect if any component in the path is a link */
- pstrcpy(reqpath, dp->reqpath);
- p = strrchr_m(reqpath, '/');
+ fstrcpy(reqpath, dp->reqpath);
+ p = strrchr(reqpath, '/');
while (p) {
*p = '\0';
- pstrcpy(localpath, reqpath);
+ fstrcpy(localpath, conn->connectpath);
+ fstrcat(localpath, "/");
+ fstrcat(localpath, reqpath);
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath));
@@ -343,11 +270,10 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
char *q;
pstring buf;
pstrcpy(buf, dfspath);
- trim_char(buf, '\0', '\\');
+ trim_string(buf, NULL, "\\");
for (; consumed_level; consumed_level--) {
- q = strrchr_m(buf, '\\');
- if (q)
- *q = 0;
+ q = strrchr(buf, '\\');
+ if (q) *q = 0;
}
*consumedcntp = strlen(buf);
DEBUG(10, ("resolve_dfs_path: Path consumed: %s (%d)\n", buf, *consumedcntp));
@@ -355,7 +281,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
return True;
}
- p = strrchr_m(reqpath, '/');
+ p = strrchr(reqpath, '/');
consumed_level++;
}
@@ -366,8 +292,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
Decides if a dfs pathname should be redirected or not.
If not, the pathname is converted to a tcon-relative local unix path
*****************************************************************/
-
-BOOL dfs_redirect(pstring pathname, connection_struct* conn,
+BOOL dfs_redirect(char* pathname, connection_struct* conn,
BOOL findfirst_flag)
{
struct dfs_path dp;
@@ -375,16 +300,16 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn,
if (!conn || !pathname)
return False;
- parse_processed_dfs_path(pathname, &dp);
+ parse_dfs_path(pathname, &dp);
/* if dfs pathname for a non-dfs share, convert to tcon-relative
path and return false */
if (!lp_msdfs_root(SNUM(conn))) {
- pstrcpy(pathname, dp.reqpath);
+ fstrcpy(pathname, dp.reqpath);
return False;
}
- if (!strequal(dp.servicename, lp_servicename(SNUM(conn)) ))
+ if (strcasecmp(dp.servicename, lp_servicename(SNUM(conn)) ) != 0)
return False;
if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag,
@@ -395,65 +320,33 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn,
DEBUG(3,("dfs_redirect: Not redirecting %s.\n", pathname));
/* Form non-dfs tcon-relative path */
- pstrcpy(pathname, dp.reqpath);
+ fstrcpy(pathname, dp.reqpath);
DEBUG(3,("dfs_redirect: Path converted to non-dfs path %s\n",
pathname));
return False;
}
-
/* never reached */
-}
-
-/**********************************************************************
- Return a self referral.
-**********************************************************************/
-
-static BOOL self_ref(char *pathname, struct junction_map *jucn,
- int *consumedcntp, BOOL *self_referralp)
-{
- struct referral *ref;
-
- if (self_referralp != NULL)
- *self_referralp = True;
-
- jucn->referral_count = 1;
- if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) {
- DEBUG(0,("self_ref: malloc failed for referral\n"));
- return False;
- }
-
- pstrcpy(ref->alternate_path,pathname);
- ref->proximity = 0;
- ref->ttl = REFERRAL_TTL;
- jucn->referral_list = ref;
- if (consumedcntp)
- *consumedcntp = strlen(pathname);
-
- return True;
+ return False;
}
/**********************************************************************
Gets valid referrals for a dfs path and fills up the
junction_map structure
-**********************************************************************/
-
-BOOL get_referred_path(char *pathname, struct junction_map *jucn,
- int *consumedcntp, BOOL *self_referralp)
+ **********************************************************************/
+BOOL get_referred_path(char *pathname, struct junction_map* jn,
+ int* consumedcntp, BOOL* self_referralp)
{
struct dfs_path dp;
struct connection_struct conns;
struct connection_struct* conn = &conns;
- pstring conn_path;
int snum;
- BOOL ret = False;
+
BOOL self_referral = False;
- if (!pathname || !jucn)
+ if (!pathname || !jn)
return False;
- ZERO_STRUCT(conns);
-
if (self_referralp)
*self_referralp = False;
else
@@ -462,92 +355,65 @@ BOOL get_referred_path(char *pathname, struct junction_map *jucn,
parse_dfs_path(pathname, &dp);
/* Verify hostname in path */
- if (local_machine && (!strequal(local_machine, dp.hostname))) {
- /* Hostname mismatch, check if one of our IP addresses */
- if (!ismyip(*interpret_addr2(dp.hostname))) {
- DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
- dp.hostname, pathname));
- return False;
- }
+ if (local_machine && (strcasecmp(local_machine, dp.hostname) != 0)) {
+
+ /* Hostname mismatch, check if one of our IP addresses */
+ if (!ismyip(*interpret_addr2(dp.hostname))) {
+
+ DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
+ dp.hostname, pathname));
+ return False;
+ }
}
- pstrcpy(jucn->service_name, dp.servicename);
- pstrcpy(jucn->volume_name, dp.reqpath);
+ pstrcpy(jn->service_name, dp.servicename);
+ pstrcpy(jn->volume_name, dp.reqpath);
/* Verify the share is a dfs root */
- snum = lp_servicenumber(jucn->service_name);
+ snum = lp_servicenumber(jn->service_name);
if(snum < 0) {
- if ((snum = find_service(jucn->service_name)) < 0)
+ if ((snum = find_service(jn->service_name)) < 0)
return False;
}
-
- if (!lp_msdfs_root(snum)) {
+
+ if (!create_conn_struct(conn, snum))
+ return False;
+
+ if (!lp_msdfs_root(SNUM(conn))) {
DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n",
dp.servicename, pathname));
- goto out;
- }
-
- /*
- * Self referrals are tested with a anonymous IPC connection and
- * a GET_DFS_REFERRAL call to \\server\share. (which means dp.reqpath[0] points
- * to an empty string). create_conn_struct cd's into the directory and will
- * fail if it cannot (as the anonymous user). Cope with this.
- */
-
- if (dp.reqpath[0] == '\0') {
-
- struct referral* ref;
-
- if (*lp_msdfs_proxy(snum) == '\0')
- return self_ref(pathname, jucn, consumedcntp,
- self_referralp);
-
- jucn->referral_count = 1;
- if ((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) {
- DEBUG(0, ("malloc failed for referral\n"));
- goto out;
- }
-
- pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
- if (dp.reqpath[0] != '\0')
- pstrcat(ref->alternate_path, dp.reqpath);
- ref->proximity = 0;
- ref->ttl = REFERRAL_TTL;
- jucn->referral_list = ref;
- if (consumedcntp)
- *consumedcntp = strlen(pathname);
- ret = True;
- goto out;
- }
-
- pstrcpy(conn_path, lp_pathname(snum));
- if (!create_conn_struct(conn, snum, conn_path))
return False;
+ }
/* If not remote & not a self referral, return False */
if (!resolve_dfs_path(pathname, &dp, conn, False,
- &jucn->referral_list, &jucn->referral_count,
+ &jn->referral_list, &jn->referral_count,
self_referralp, consumedcntp)) {
if (!*self_referralp) {
DEBUG(3,("get_referred_path: No valid referrals for path %s\n", pathname));
- goto out;
+ return False;
}
}
/* if self_referral, fill up the junction map */
if (*self_referralp) {
- if (self_ref(pathname, jucn, consumedcntp, self_referralp) == False) {
- goto out;
+ struct referral* ref;
+ jn->referral_count = 1;
+ if((ref = (struct referral*) malloc(sizeof(struct referral)))
+ == NULL) {
+ DEBUG(0,("malloc failed for referral\n"));
+ return False;
}
+
+ pstrcpy(ref->alternate_path,pathname);
+ ref->proximity = 0;
+ ref->ttl = REFERRAL_TTL;
+ jn->referral_list = ref;
+ if (consumedcntp)
+ *consumedcntp = strlen(pathname);
}
-
- ret = True;
-out:
- if (conn->mem_ctx)
- talloc_destroy( conn->mem_ctx );
-
- return ret;
+ return True;
}
static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
@@ -567,10 +433,9 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
DEBUG(10,("setting up version2 referral\nRequested path:\n"));
- requestedpathlen = rpcstr_push(uni_requestedpath, pathname, -1,
- STR_TERMINATE);
+ requestedpathlen = (dos_struni2((char *)uni_requestedpath,pathname,sizeof(uni_requestedpath)) + 1) * 2;
- dump_data(10, (const char *) uni_requestedpath,requestedpathlen);
+ dump_data(10, (char *) uni_requestedpath,requestedpathlen);
DEBUG(10,("ref count = %u\n",junction->referral_count));
@@ -617,7 +482,7 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
offset = 8;
/* add the referral elements */
for(i=0;i<junction->referral_count;i++) {
- struct referral* ref = &junction->referral_list[i];
+ struct referral* ref = &(junction->referral_list[i]);
int unilen;
SSVAL(pdata,offset,2); /* version 2 */
@@ -633,9 +498,7 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
SSVAL(pdata,offset+16,uni_reqpathoffset1-offset);
SSVAL(pdata,offset+18,uni_reqpathoffset2-offset);
/* copy referred path into current offset */
- unilen = rpcstr_push(pdata+uni_curroffset, ref->alternate_path,
- -1, STR_UNICODE);
-
+ unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,sizeof(uni_requestedpath)) +1)*2;
SSVAL(pdata,offset+20,uni_curroffset-offset);
uni_curroffset += unilen;
@@ -663,7 +526,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
DEBUG(10,("setting up version3 referral\n"));
- reqpathlen = rpcstr_push(uni_reqpath, pathname, -1, STR_TERMINATE);
+ reqpathlen = (dos_struni2((char *) uni_reqpath,pathname,sizeof(uni_reqpath))+1)*2;
dump_data(10, (char *) uni_reqpath,reqpathlen);
@@ -713,8 +576,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
SSVAL(pdata,offset+12,uni_reqpathoffset1-offset);
SSVAL(pdata,offset+14,uni_reqpathoffset2-offset);
/* copy referred path into current offset */
- unilen = rpcstr_push(pdata+uni_curroffset,ref->alternate_path,
- -1, STR_UNICODE | STR_TERMINATE);
+ unilen = (dos_struni2(pdata+uni_curroffset,ref->alternate_path,sizeof(uni_reqpath)) +1)*2;
SSVAL(pdata,offset+16,uni_curroffset-offset);
/* copy 0x10 bytes of 00's in the ServiceSite GUID */
memset(pdata+offset+18,'\0',16);
@@ -729,7 +591,7 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
* Set up the Dfs referral for the dfs pathname
******************************************************************/
-int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_referral_level, char** ppdata)
+int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
{
struct junction_map junction;
int consumedcnt;
@@ -751,14 +613,12 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
pathnamep++;
pstrcpy(buf, pathnamep);
- /* The following call can change cwd. */
- if (!get_referred_path(buf, &junction, &consumedcnt, &self_referral)) {
- vfs_ChDir(orig_conn,orig_conn->connectpath);
+ if (!get_referred_path(buf, &junction, &consumedcnt,
+ &self_referral))
return -1;
- }
- vfs_ChDir(orig_conn,orig_conn->connectpath);
- if (!self_referral) {
+ if (!self_referral)
+ {
pathnamep[consumedcnt] = '\0';
if( DEBUGLVL( 3 ) ) {
@@ -769,7 +629,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
dbgtext(".\n");
}
}
-
+
/* create the referral depeding on version */
DEBUG(10,("max_referral_level :%d\n",max_referral_level));
if(max_referral_level<2 || max_referral_level>3)
@@ -777,18 +637,24 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
switch(max_referral_level) {
case 2:
+ {
reply_size = setup_ver2_dfs_referral(pathnamep, ppdata, &junction,
consumedcnt, self_referral);
SAFE_FREE(junction.referral_list);
break;
+ }
case 3:
+ {
reply_size = setup_ver3_dfs_referral(pathnamep, ppdata, &junction,
consumedcnt, self_referral);
SAFE_FREE(junction.referral_list);
break;
+ }
default:
+ {
DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level));
return -1;
+ }
}
DEBUG(10,("DFS Referral pdata:\n"));
@@ -796,6 +662,11 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
return reply_size;
}
+int dfs_path_error(char* inbuf, char* outbuf)
+{
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+}
+
/**********************************************************************
The following functions are called by the NETDFS RPC pipe functions
**********************************************************************/
@@ -803,14 +674,14 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
/**********************************************************************
Creates a junction structure from a Dfs pathname
**********************************************************************/
-BOOL create_junction(char* pathname, struct junction_map* jucn)
+BOOL create_junction(char* pathname, struct junction_map* jn)
{
struct dfs_path dp;
parse_dfs_path(pathname,&dp);
/* check if path is dfs : validate first token */
- if (local_machine && (!strequal(local_machine,dp.hostname))) {
+ if (local_machine && (strcasecmp(local_machine,dp.hostname)!=0)) {
/* Hostname mismatch, check if one of our IP addresses */
if (!ismyip(*interpret_addr2(dp.hostname))) {
@@ -827,40 +698,38 @@ BOOL create_junction(char* pathname, struct junction_map* jucn)
return False;
}
- pstrcpy(jucn->service_name,dp.servicename);
- pstrcpy(jucn->volume_name,dp.reqpath);
+ pstrcpy(jn->service_name,dp.servicename);
+ pstrcpy(jn->volume_name,dp.reqpath);
return True;
}
/**********************************************************************
Forms a valid Unix pathname from the junction
**********************************************************************/
-
-static BOOL junction_to_local_path(struct junction_map* jucn, char* path,
+static BOOL junction_to_local_path(struct junction_map* jn, char* path,
int max_pathlen, connection_struct *conn)
{
int snum;
- pstring conn_path;
- if(!path || !jucn)
+ if(!path || !jn)
return False;
- snum = lp_servicenumber(jucn->service_name);
+ snum = lp_servicenumber(jn->service_name);
if(snum < 0)
return False;
safe_strcpy(path, lp_pathname(snum), max_pathlen-1);
safe_strcat(path, "/", max_pathlen-1);
- safe_strcat(path, jucn->volume_name, max_pathlen-1);
+ strlower(jn->volume_name);
+ safe_strcat(path, jn->volume_name, max_pathlen-1);
- pstrcpy(conn_path, lp_pathname(snum));
- if (!create_conn_struct(conn, snum, conn_path))
+ if (!create_conn_struct(conn, snum))
return False;
return True;
}
-BOOL create_msdfs_link(struct junction_map *jucn, BOOL exists)
+BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
{
pstring path;
pstring msdfs_link;
@@ -868,17 +737,16 @@ BOOL create_msdfs_link(struct junction_map *jucn, BOOL exists)
connection_struct *conn = &conns;
int i=0;
BOOL insert_comma = False;
- BOOL ret = False;
- if(!junction_to_local_path(jucn, path, sizeof(path), conn))
+ if(!junction_to_local_path(jn, path, sizeof(path), conn))
return False;
/* form the msdfs_link contents */
pstrcpy(msdfs_link, "msdfs:");
- for(i=0; i<jucn->referral_count; i++) {
- char* refpath = jucn->referral_list[i].alternate_path;
+ for(i=0; i<jn->referral_count; i++) {
+ char* refpath = jn->referral_list[i].alternate_path;
- trim_char(refpath, '\\', '\\');
+ trim_string(refpath, "\\", "\\");
if(*refpath == '\0') {
if (i == 0)
insert_comma = False;
@@ -896,41 +764,33 @@ BOOL create_msdfs_link(struct junction_map *jucn, BOOL exists)
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link));
if(exists)
- if(SMB_VFS_UNLINK(conn,path)!=0)
- goto out;
+ if(conn->vfs_ops.unlink(conn,path)!=0)
+ return False;
- if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
+ if(conn->vfs_ops.symlink(conn, msdfs_link, path) < 0) {
DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n",
path, msdfs_link, strerror(errno)));
- goto out;
+ return False;
}
-
-
- ret = True;
-
-out:
- talloc_destroy( conn->mem_ctx );
- return ret;
+ return True;
}
-BOOL remove_msdfs_link(struct junction_map* jucn)
+BOOL remove_msdfs_link(struct junction_map* jn)
{
pstring path;
connection_struct conns;
connection_struct *conn = &conns;
- BOOL ret = False;
-
- if( junction_to_local_path(jucn, path, sizeof(path), conn) ) {
- if( SMB_VFS_UNLINK(conn, path) == 0 )
- ret = True;
- talloc_destroy( conn->mem_ctx );
- }
-
- return ret;
+ if(!junction_to_local_path(jn, path, sizeof(path), conn))
+ return False;
+
+ if(conn->vfs_ops.unlink(conn, path)!=0)
+ return False;
+
+ return True;
}
-static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count)
+static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
{
int cnt = *jn_count;
DIR *dirp;
@@ -939,8 +799,6 @@ static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count)
char* service_name = lp_servicename(snum);
connection_struct conns;
connection_struct *conn = &conns;
- struct referral *ref = NULL;
- BOOL ret = False;
pstrcpy(connect_path,lp_pathname(snum));
@@ -951,69 +809,86 @@ static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count)
* Fake up a connection struct for the VFS layer.
*/
- if (!create_conn_struct(conn, snum, connect_path))
+ if (!create_conn_struct(conn, snum))
return False;
- /* form a junction for the msdfs root - convention
- DO NOT REMOVE THIS: NT clients will not work with us
- if this is not present
- */
- pstrcpy(jucn[cnt].service_name, service_name);
- jucn[cnt].volume_name[0] = '\0';
- jucn[cnt].referral_count = 1;
-
- ref = jucn[cnt].referral_list
- = (struct referral*) malloc(sizeof(struct referral));
- if (jucn[cnt].referral_list == NULL) {
- DEBUG(0, ("Malloc failed!\n"));
- goto out;
- }
+ {
+ /* form a junction for the msdfs root - convention
+ DO NOT REMOVE THIS: NT clients will not work with us
+ if this is not present
+ */
+ struct referral *ref = NULL;
+ pstring alt_path;
+ pstrcpy(jn[cnt].service_name, service_name);
+ jn[cnt].volume_name[0] = '\0';
+ jn[cnt].referral_count = 1;
+
+ slprintf(alt_path,sizeof(alt_path)-1,"\\\\%s\\%s",
+ local_machine, service_name);
+ ref = jn[cnt].referral_list = (struct referral*) malloc(sizeof(struct referral));
+ if (jn[cnt].referral_list == NULL) {
+ DEBUG(0, ("Malloc failed!\n"));
+ return False;
+ }
- ref->proximity = 0;
- ref->ttl = REFERRAL_TTL;
- if (*lp_msdfs_proxy(snum) != '\0') {
- pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
- *jn_count = ++cnt;
- ret = True;
- goto out;
+ pstrcpy(ref->alternate_path, alt_path);
+ ref->proximity = 0;
+ ref->ttl = REFERRAL_TTL;
+ cnt++;
}
-
- slprintf(ref->alternate_path, sizeof(pstring)-1,
- "\\\\%s\\%s", local_machine, service_name);
- cnt++;
-
- /* Now enumerate all dfs links */
- dirp = SMB_VFS_OPENDIR(conn, ".");
+
+ dirp = conn->vfs_ops.opendir(conn, dos_to_unix_static(connect_path));
if(!dirp)
- goto out;
+ return False;
while((dname = vfs_readdirname(conn, dirp)) != NULL) {
- if (is_msdfs_link(conn, dname, &(jucn[cnt].referral_list),
- &(jucn[cnt].referral_count), NULL)) {
- pstrcpy(jucn[cnt].service_name, service_name);
- pstrcpy(jucn[cnt].volume_name, dname);
+ pstring pathreal;
+
+ pstrcpy(pathreal, connect_path);
+ pstrcat(pathreal, "/");
+ pstrcat(pathreal, dname);
+
+ if (is_msdfs_link(conn, pathreal, &(jn[cnt].referral_list),
+ &(jn[cnt].referral_count), NULL)) {
+ pstrcpy(jn[cnt].service_name, service_name);
+ pstrcpy(jn[cnt].volume_name, dname);
cnt++;
}
}
- SMB_VFS_CLOSEDIR(conn,dirp);
+ conn->vfs_ops.closedir(conn,dirp);
*jn_count = cnt;
-out:
- talloc_destroy(conn->mem_ctx);
- return ret;
+ return True;
}
-int enum_msdfs_links(struct junction_map* jucn)
+int enum_msdfs_links(struct junction_map* jn)
{
int i=0;
int jn_count = 0;
if(!lp_host_msdfs())
- return 0;
+ return -1;
- for(i=0;i < lp_numservices();i++) {
+ for(i=0;*lp_servicename(i);i++) {
if(lp_msdfs_root(i))
- form_junctions(i,jucn,&jn_count);
+ form_junctions(i,jn,&jn_count);
}
return jn_count;
}
+
+
+#else
+/* Stub functions if WITH_MSDFS not defined */
+ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
+{
+ return -1;
+}
+
+ BOOL is_msdfs_link(connection_struct* conn, char* path,
+ struct referral** reflistpp, int* refcntp,
+ SMB_STRUCT_STAT *sbufp)
+{
+ return False;
+}
+
+#endif
diff --git a/source/nmbd/asyncdns.c b/source/nmbd/asyncdns.c
index 653cb97fbb0..5ae2eb202da 100644
--- a/source/nmbd/asyncdns.c
+++ b/source/nmbd/asyncdns.c
@@ -1,5 +1,5 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
a async DNS handler
Copyright (C) Andrew Tridgell 1997-1998
@@ -26,26 +26,27 @@
static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
{
- int name_type = question->name_type;
- unstring qname;
-
- pull_ascii_nstring(qname, sizeof(qname), question->name);
+ int name_type = question->name_type;
+ char *qname = question->name;
- if (!addr.s_addr) {
- /* add the fail to WINS cache of names. give it 1 hour in the cache */
- DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
- (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
- return( NULL );
- }
-
- /* add it to our WINS cache of names. give it 2 hours in the cache */
- DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
-
- return( add_name_to_subnet( wins_server_subnet, qname, name_type,
+
+ if (!addr.s_addr) {
+ /* add the fail to WINS cache of names. give it 1 hour in the cache */
+ DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
+ (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
+ return( NULL );
+ }
+
+ /* add it to our WINS cache of names. give it 2 hours in the cache */
+ DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
+
+ return( add_name_to_subnet( wins_server_subnet, qname, name_type,
NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
}
+
+
#ifndef SYNC_DNS
static int fd_in = -1, fd_out = -1;
@@ -69,7 +70,6 @@ static struct packet_struct *dns_current;
return the fd used to gather async dns replies. This is added to the select
loop
****************************************************************************/
-
int asyncdns_fd(void)
{
return fd_in;
@@ -81,7 +81,7 @@ int asyncdns_fd(void)
static void asyncdns_process(void)
{
struct query_record r;
- unstring qname;
+ fstring qname;
DEBUGLEVEL = -1;
@@ -89,7 +89,8 @@ static void asyncdns_process(void)
if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r))
break;
- pull_ascii_nstring( qname, sizeof(qname), r.name.name);
+ fstrcpy(qname, r.name.name);
+
r.result.s_addr = interpret_addr(qname);
if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
@@ -109,7 +110,7 @@ static void asyncdns_process(void)
static void sig_term(int sig)
{
- _exit(0);
+ _exit(0);
}
/***************************************************************************
@@ -119,10 +120,8 @@ static void sig_term(int sig)
void kill_async_dns_child(void)
{
- if (child_pid > 0) {
- kill(child_pid, SIGTERM);
- child_pid = -1;
- }
+ if(child_pid != 0 && child_pid != -1)
+ kill(child_pid, SIGTERM);
}
/***************************************************************************
@@ -223,10 +222,10 @@ void run_dns_queue(void)
if (query_current(&r)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, dns_current, NULL);
- else
- send_wins_name_query_response(0,dns_current,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, dns_current, NULL);
+ else
+ send_wins_name_query_response(0,dns_current,namerec);
in_dns = 0;
}
@@ -244,10 +243,10 @@ void run_dns_queue(void)
if (nmb_name_equal(question, &r.name)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0,p,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ else
+ send_wins_name_query_response(0,p,namerec);
in_dns = 0;
p->locked = False;
@@ -268,8 +267,7 @@ void run_dns_queue(void)
if (dns_queue) {
dns_current = dns_queue;
dns_queue = dns_queue->next;
- if (dns_queue)
- dns_queue->prev = NULL;
+ if (dns_queue) dns_queue->prev = NULL;
dns_current->next = NULL;
if (!write_child(dns_current)) {
@@ -277,12 +275,12 @@ void run_dns_queue(void)
return;
}
}
+
}
/***************************************************************************
queue a DNS query
****************************************************************************/
-
BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
struct name_record **n)
{
@@ -315,14 +313,11 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
/***************************************************************************
we use this when we can't do async DNS lookups
****************************************************************************/
-
BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
struct name_record **n)
{
+ char *qname = question->name;
struct in_addr dns_ip;
- unstring qname;
-
- pull_ascii_nstring(qname, question->name);
DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
@@ -335,19 +330,18 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
BlockSignals(True, SIGTERM);
*n = add_dns_result(question, dns_ip);
- if(*n == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0, p, *n);
+ if(*n == NULL)
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ else
+ send_wins_name_query_response(0, p, *n);
return False;
}
/***************************************************************************
With sync dns there is no child to kill on SIGTERM.
****************************************************************************/
-
void kill_async_dns_child(void)
{
- return;
+ return;
}
#endif
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 880de7f91bf..e95167ff136 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Jeremy Allison 1997-2002
- Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,24 +18,30 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Revision History:
+
+ 14 jan 96: lkcl@pires.co.uk
+ added multiple workgroup domain master support
+
*/
#include "includes.h"
+pstring servicesf = CONFIGFILE;
+
int ClientNMB = -1;
int ClientDGRAM = -1;
int global_nmb_port = -1;
+static pstring host_file;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
+
extern BOOL global_in_nmbd;
/* are we running as a daemon ? */
-static BOOL is_daemon;
-
-/* fork or run in foreground ? */
-static BOOL Fork = True;
-
-/* log to standard output ? */
-static BOOL log_stdout;
+static BOOL is_daemon = False;
/* have we found LanMan clients yet? */
BOOL found_lm_clients = False;
@@ -52,13 +57,13 @@ time_t StartupTime = 0;
static void terminate(void)
{
DEBUG(0,("Got SIGTERM: going down...\n"));
-
+
/* Write out wins.dat file if samba is a WINS server */
wins_write_database(False);
-
- /* Remove all SELF registered names from WINS */
- release_wins_names();
-
+
+ /* Remove all SELF registered names. */
+ release_my_names();
+
/* Announce all server entries as 0 time-to-live, 0 type. */
announce_my_servers_removed();
@@ -69,15 +74,6 @@ static void terminate(void)
}
/**************************************************************************** **
- Handle a SHUTDOWN message from smbcontrol.
- **************************************************************************** */
-
-static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
-{
- terminate();
-}
-
-/**************************************************************************** **
Catch a SIGTERM signal.
**************************************************************************** */
@@ -108,37 +104,37 @@ static void sig_hup(int sig)
static BOOL dump_core(void)
{
- char *p;
- pstring dname;
- pstrcpy( dname, lp_logfile() );
- if ((p=strrchr_m(dname,'/')))
- *p=0;
- pstrcat( dname, "/corefiles" );
- mkdir( dname, 0700 );
- sys_chown( dname, getuid(), getgid() );
- chmod( dname, 0700 );
- if ( chdir(dname) )
- return( False );
- umask( ~(0700) );
+ char *p;
+ pstring dname;
+ pstrcpy( dname, lp_logfile() );
+ if ((p=strrchr(dname,'/')))
+ *p=0;
+ pstrcat( dname, "/corefiles" );
+ mkdir( dname, 0700 );
+ sys_chown( dname, getuid(), getgid() );
+ chmod( dname, 0700 );
+ if ( chdir(dname) )
+ return( False );
+ umask( ~(0700) );
#ifdef HAVE_GETRLIMIT
#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit( RLIMIT_CORE, &rlp );
- rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
- setrlimit( RLIMIT_CORE, &rlp );
- getrlimit( RLIMIT_CORE, &rlp );
- DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
- }
+ {
+ struct rlimit rlp;
+ getrlimit( RLIMIT_CORE, &rlp );
+ rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
+ setrlimit( RLIMIT_CORE, &rlp );
+ getrlimit( RLIMIT_CORE, &rlp );
+ DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
+ }
#endif
#endif
- DEBUG(0,("Dumping core in %s\n",dname));
- abort();
- return( True );
-}
+ DEBUG(0,("Dumping core in %s\n",dname));
+ abort();
+ return( True );
+} /* dump_core */
#endif
/**************************************************************************** **
@@ -148,9 +144,9 @@ static BOOL dump_core(void)
static void fault_continue(void)
{
#if DUMP_CORE
- dump_core();
+ dump_core();
#endif
-}
+} /* fault_continue */
/**************************************************************************** **
Expire old names from the namelist and server list.
@@ -158,32 +154,30 @@ static void fault_continue(void)
static void expire_names_and_servers(time_t t)
{
- static time_t lastrun = 0;
+ static time_t lastrun = 0;
- if ( !lastrun )
- lastrun = t;
- if ( t < (lastrun + 5) )
- return;
- lastrun = t;
-
- /*
- * Expire any timed out names on all the broadcast
- * subnets and those registered with the WINS server.
- * (nmbd_namelistdb.c)
- */
-
- expire_names(t);
-
- /*
- * Go through all the broadcast subnets and for each
- * workgroup known on that subnet remove any expired
- * server names. If a workgroup has an empty serverlist
- * and has itself timed out then remove the workgroup.
- * (nmbd_workgroupdb.c)
- */
-
- expire_workgroups_and_servers(t);
-}
+ if ( !lastrun )
+ lastrun = t;
+ if ( t < (lastrun + 5) )
+ return;
+ lastrun = t;
+
+ /*
+ * Expire any timed out names on all the broadcast
+ * subnets and those registered with the WINS server.
+ * (nmbd_namelistdb.c)
+ */
+ expire_names(t);
+
+ /*
+ * Go through all the broadcast subnets and for each
+ * workgroup known on that subnet remove any expired
+ * server names. If a workgroup has an empty serverlist
+ * and has itself timed out then remove the workgroup.
+ * (nmbd_workgroupdb.c)
+ */
+ expire_workgroups_and_servers(t);
+} /* expire_names_and_servers */
/************************************************************************** **
Reload the list of network interfaces.
@@ -231,8 +225,7 @@ static BOOL reload_interfaces(time_t t)
DEBUG(2,("Found new interface %s\n",
inet_ntoa(iface->ip)));
subrec = make_normal_subnet(iface);
- if (subrec)
- register_my_workgroup_one_subnet(subrec);
+ if (subrec) register_my_workgroup_one_subnet(subrec);
}
}
@@ -272,500 +265,649 @@ static BOOL reload_interfaces(time_t t)
static BOOL reload_nmbd_services(BOOL test)
{
- BOOL ret;
-
- set_remote_machine_name("nmbd", False);
-
- if ( lp_loaded() ) {
- pstring fname;
- pstrcpy( fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
- test = False;
- }
- }
-
- if ( test && !lp_file_list_changed() )
- return(True);
-
- ret = lp_load( dyn_CONFIGFILE, True , False, False);
-
- /* perhaps the config filename is now set */
- if ( !test ) {
- DEBUG( 3, ( "services not loaded\n" ) );
- reload_nmbd_services( True );
- }
-
- return(ret);
-}
+ BOOL ret;
+ extern fstring remote_machine;
+
+ fstrcpy( remote_machine, "nmbd" );
+
+ if ( lp_loaded() )
+ {
+ pstring fname;
+ pstrcpy( fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
+ {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ if ( test && !lp_file_list_changed() )
+ return(True);
+
+ ret = lp_load( servicesf, True , False, False);
+
+ /* perhaps the config filename is now set */
+ if ( !test )
+ {
+ DEBUG( 3, ( "services not loaded\n" ) );
+ reload_nmbd_services( True );
+ }
+
+ /* Do a sanity check for a misconfigured nmbd */
+ if( lp_wins_support() && *lp_wins_server() )
+ {
+ DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
+cannot be set in the smb.conf file. nmbd aborting.\n"));
+ exit(10);
+ }
+
+ return(ret);
+} /* reload_nmbd_services */
/**************************************************************************** **
- * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
- * We use buf here to return BOOL result to process() when reload_interfaces()
- * detects that there are no subnets.
+ The main select loop.
**************************************************************************** */
-static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len)
+static void process(void)
{
- write_browse_list( 0, True );
- dump_all_namelists();
- reload_nmbd_services( True );
- reopen_logs();
-
- if(buf) {
- /* We were called from process() */
- /* If reload_interfaces() returned True */
- /* we need to shutdown if there are no subnets... */
- /* pass this info back to process() */
- *((BOOL*)buf) = reload_interfaces(0);
- }
-}
+ BOOL run_election;
+
+ while( True )
+ {
+ time_t t = time(NULL);
+
+ /* check for internal messages */
+ message_dispatch();
+
+ /*
+ * Check all broadcast subnets to see if
+ * we need to run an election on any of them.
+ * (nmbd_elections.c)
+ */
+ run_election = check_elections();
+
+ /*
+ * Read incoming UDP packets.
+ * (nmbd_packets.c)
+ */
+ if(listen_for_packets(run_election))
+ return;
+
+ /*
+ * Handle termination inband.
+ */
+
+ if (got_sig_term) {
+ got_sig_term = 0;
+ terminate();
+ }
+
+ /*
+ * Process all incoming packets
+ * read above. This calls the success and
+ * failure functions registered when response
+ * packets arrrive, and also deals with request
+ * packets from other sources.
+ * (nmbd_packets.c)
+ */
+ run_packet_queue();
+
+ /*
+ * Run any elections - initiate becoming
+ * a local master browser if we have won.
+ * (nmbd_elections.c)
+ */
+ run_elections(t);
+
+ /*
+ * Send out any broadcast announcements
+ * of our server names. This also announces
+ * the workgroup name if we are a local
+ * master browser.
+ * (nmbd_sendannounce.c)
+ */
+ announce_my_server_names(t);
+
+ /*
+ * Send out any LanMan broadcast announcements
+ * of our server names.
+ * (nmbd_sendannounce.c)
+ */
+ announce_my_lm_server_names(t);
+
+ /*
+ * If we are a local master browser, periodically
+ * announce ourselves to the domain master browser.
+ * This also deals with syncronising the domain master
+ * browser server lists with ourselves as a local
+ * master browser.
+ * (nmbd_sendannounce.c)
+ */
+ announce_myself_to_domain_master_browser(t);
+
+ /*
+ * Fullfill any remote announce requests.
+ * (nmbd_sendannounce.c)
+ */
+ announce_remote(t);
+
+ /*
+ * Fullfill any remote browse sync announce requests.
+ * (nmbd_sendannounce.c)
+ */
+ browse_sync_remote(t);
+
+ /*
+ * Scan the broadcast subnets, and WINS client
+ * namelists and refresh any that need refreshing.
+ * (nmbd_mynames.c)
+ */
+ refresh_my_names(t);
+
+ /*
+ * Scan the subnet namelists and server lists and
+ * expire thos that have timed out.
+ * (nmbd.c)
+ */
+ expire_names_and_servers(t);
+
+ /*
+ * Write out a snapshot of our current browse list into
+ * the browse.dat file. This is used by smbd to service
+ * incoming NetServerEnum calls - used to synchronise
+ * browse lists over subnets.
+ * (nmbd_serverlistdb.c)
+ */
+ write_browse_list(t, False);
+
+ /*
+ * If we are a domain master browser, we have a list of
+ * local master browsers we should synchronise browse
+ * lists with (these are added by an incoming local
+ * master browser announcement packet). Expire any of
+ * these that are no longer current, and pull the server
+ * lists from each of these known local master browsers.
+ * (nmbd_browsesync.c)
+ */
+ dmb_expire_and_sync_browser_lists(t);
+
+ /*
+ * Check that there is a local master browser for our
+ * workgroup for all our broadcast subnets. If one
+ * is not found, start an election (which we ourselves
+ * may or may not participate in, depending on the
+ * setting of the 'local master' parameter.
+ * (nmbd_elections.c)
+ */
+ check_master_browser_exists(t);
+
+ /*
+ * If we are configured as a logon server, attempt to
+ * register the special NetBIOS names to become such
+ * (WORKGROUP<1c> name) on all broadcast subnets and
+ * with the WINS server (if used). If we are configured
+ * to become a domain master browser, attempt to register
+ * the special NetBIOS name (WORKGROUP<1b> name) to
+ * become such.
+ * (nmbd_become_dmb.c)
+ */
+ add_domain_names(t);
+
+ /*
+ * If we are a WINS server, do any timer dependent
+ * processing required.
+ * (nmbd_winsserver.c)
+ */
+ initiate_wins_processing(t);
+
+ /*
+ * If we are a domain master browser, attempt to contact the
+ * WINS server to get a list of all known WORKGROUPS/DOMAINS.
+ * This will only work to a Samba WINS server.
+ * (nmbd_browsesync.c)
+ */
+ if (lp_enhanced_browsing()) {
+ collect_all_workgroup_names_from_wins_server(t);
+ }
+
+ /*
+ * Go through the response record queue and time out or re-transmit
+ * and expired entries.
+ * (nmbd_packets.c)
+ */
+ retransmit_or_expire_response_records(t);
+
+ /*
+ * check to see if any remote browse sync child processes have completed
+ */
+ sync_check_completion();
+
+ /*
+ * regularly sync with any other DMBs we know about
+ */
+ if (lp_enhanced_browsing()) {
+ sync_all_dmbs(t);
+ }
+
+ /*
+ * clear the unexpected packet queue
+ */
+ clear_unexpected(t);
+
+ /*
+ * Reload the services file if we got a sighup.
+ */
+
+ if(reload_after_sighup) {
+ DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
+ write_browse_list( 0, True );
+ dump_all_namelists();
+ reload_nmbd_services( True );
+ reopen_logs();
+ if(reload_interfaces(0))
+ return;
+ reload_after_sighup = 0;
+ }
+
+ /* check for new network interfaces */
+ if(reload_interfaces(t))
+ return;
+ /* free up temp memory */
+ lp_talloc_free();
+ }
+} /* process */
/**************************************************************************** **
- The main select loop.
+ Open the socket communication.
**************************************************************************** */
-static void process(void)
+static BOOL open_sockets(BOOL isdaemon, int port)
{
- BOOL run_election;
- BOOL no_subnets;
-
- while( True ) {
- time_t t = time(NULL);
-
- /* Check for internal messages */
-
- message_dispatch();
-
- /*
- * Check all broadcast subnets to see if
- * we need to run an election on any of them.
- * (nmbd_elections.c)
- */
-
- run_election = check_elections();
-
- /*
- * Read incoming UDP packets.
- * (nmbd_packets.c)
- */
-
- if(listen_for_packets(run_election))
- return;
-
- /*
- * Handle termination inband.
- */
-
- if (got_sig_term) {
- got_sig_term = 0;
- terminate();
- }
-
- /*
- * Process all incoming packets
- * read above. This calls the success and
- * failure functions registered when response
- * packets arrrive, and also deals with request
- * packets from other sources.
- * (nmbd_packets.c)
- */
-
- run_packet_queue();
-
- /*
- * Run any elections - initiate becoming
- * a local master browser if we have won.
- * (nmbd_elections.c)
- */
-
- run_elections(t);
-
- /*
- * Send out any broadcast announcements
- * of our server names. This also announces
- * the workgroup name if we are a local
- * master browser.
- * (nmbd_sendannounce.c)
- */
-
- announce_my_server_names(t);
-
- /*
- * Send out any LanMan broadcast announcements
- * of our server names.
- * (nmbd_sendannounce.c)
- */
-
- announce_my_lm_server_names(t);
-
- /*
- * If we are a local master browser, periodically
- * announce ourselves to the domain master browser.
- * This also deals with syncronising the domain master
- * browser server lists with ourselves as a local
- * master browser.
- * (nmbd_sendannounce.c)
- */
-
- announce_myself_to_domain_master_browser(t);
-
- /*
- * Fullfill any remote announce requests.
- * (nmbd_sendannounce.c)
- */
-
- announce_remote(t);
-
- /*
- * Fullfill any remote browse sync announce requests.
- * (nmbd_sendannounce.c)
- */
-
- browse_sync_remote(t);
-
- /*
- * Scan the broadcast subnets, and WINS client
- * namelists and refresh any that need refreshing.
- * (nmbd_mynames.c)
- */
-
- refresh_my_names(t);
-
- /*
- * Scan the subnet namelists and server lists and
- * expire thos that have timed out.
- * (nmbd.c)
- */
-
- expire_names_and_servers(t);
-
- /*
- * Write out a snapshot of our current browse list into
- * the browse.dat file. This is used by smbd to service
- * incoming NetServerEnum calls - used to synchronise
- * browse lists over subnets.
- * (nmbd_serverlistdb.c)
- */
-
- write_browse_list(t, False);
-
- /*
- * If we are a domain master browser, we have a list of
- * local master browsers we should synchronise browse
- * lists with (these are added by an incoming local
- * master browser announcement packet). Expire any of
- * these that are no longer current, and pull the server
- * lists from each of these known local master browsers.
- * (nmbd_browsesync.c)
- */
+ /* The sockets opened here will be used to receive broadcast
+ packets *only*. Interface specific sockets are opened in
+ make_subnet() in namedbsubnet.c. Thus we bind to the
+ address "0.0.0.0". The parameter 'socket address' is
+ now deprecated.
+ */
+
+ if ( isdaemon )
+ ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()),True);
+ else
+ ClientNMB = 0;
+
+ ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
- dmb_expire_and_sync_browser_lists(t);
+ if ( ClientNMB == -1 )
+ return( False );
- /*
- * Check that there is a local master browser for our
- * workgroup for all our broadcast subnets. If one
- * is not found, start an election (which we ourselves
- * may or may not participate in, depending on the
- * setting of the 'local master' parameter.
- * (nmbd_elections.c)
- */
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
- check_master_browser_exists(t);
+ set_socket_options( ClientNMB, "SO_BROADCAST" );
+ set_socket_options( ClientDGRAM, "SO_BROADCAST" );
- /*
- * If we are configured as a logon server, attempt to
- * register the special NetBIOS names to become such
- * (WORKGROUP<1c> name) on all broadcast subnets and
- * with the WINS server (if used). If we are configured
- * to become a domain master browser, attempt to register
- * the special NetBIOS name (WORKGROUP<1b> name) to
- * become such.
- * (nmbd_become_dmb.c)
- */
+ DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
+ return( True );
+} /* open_sockets */
- add_domain_names(t);
-
- /*
- * If we are a WINS server, do any timer dependent
- * processing required.
- * (nmbd_winsserver.c)
- */
-
- initiate_wins_processing(t);
+/**************************************************************************** **
+ Initialise connect, service and file structs.
+ **************************************************************************** */
- /*
- * If we are a domain master browser, attempt to contact the
- * WINS server to get a list of all known WORKGROUPS/DOMAINS.
- * This will only work to a Samba WINS server.
- * (nmbd_browsesync.c)
- */
+static BOOL init_structs(void)
+{
+ extern fstring local_machine;
+ char *p;
+ const char *ptr;
+ int namecount;
+ int n;
+ int nodup;
+ pstring nbname;
+
+ if (! *global_myname)
+ {
+ fstrcpy( global_myname, myhostname() );
+ p = strchr( global_myname, '.' );
+ if (p)
+ *p = 0;
+ }
+ strupper( global_myname );
+
+ /* Add any NETBIOS name aliases. Ensure that the first entry
+ is equal to global_myname.
+ */
+ /* Work out the max number of netbios aliases that we have */
+ ptr = lp_netbios_aliases();
+ for( namecount=0; next_token(&ptr,nbname,NULL, sizeof(nbname)); namecount++ )
+ ;
+ if ( *global_myname )
+ namecount++;
+
+ /* Allocate space for the netbios aliases */
+ my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
+ if( NULL == my_netbios_names )
+ {
+ DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
+ return( False );
+ }
+
+ /* Use the global_myname string first */
+ namecount=0;
+ if ( *global_myname )
+ my_netbios_names[namecount++] = global_myname;
+
+ ptr = lp_netbios_aliases();
+ while ( next_token( &ptr, nbname, NULL, sizeof(nbname) ) )
+ {
+ strupper( nbname );
+ /* Look for duplicates */
+ nodup=1;
+ for( n=0; n<namecount; n++ )
+ {
+ if( 0 == strcmp( nbname, my_netbios_names[n] ) )
+ nodup=0;
+ }
+ if (nodup)
+ my_netbios_names[namecount++] = strdup( nbname );
+ }
+
+ /* Check the strdups succeeded. */
+ for( n = 0; n < namecount; n++ )
+ if( NULL == my_netbios_names[n] )
+ {
+ DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
+ return False;
+ }
+
+ /* Terminate name list */
+ my_netbios_names[namecount++] = NULL;
+
+ fstrcpy( local_machine, global_myname );
+ trim_string( local_machine, " ", " " );
+ p = strchr( local_machine, ' ' );
+ if (p)
+ *p = 0;
+ strlower( local_machine );
- if (lp_enhanced_browsing())
- collect_all_workgroup_names_from_wins_server(t);
+ DEBUG( 5, ("Netbios name list:-\n") );
+ for( n=0; my_netbios_names[n]; n++ )
+ DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
- /*
- * Go through the response record queue and time out or re-transmit
- * and expired entries.
- * (nmbd_packets.c)
- */
+ return( True );
+} /* init_structs */
- retransmit_or_expire_response_records(t);
+/**************************************************************************** **
+ Usage on the program.
+ **************************************************************************** */
- /*
- * check to see if any remote browse sync child processes have completed
- */
+static void usage(char *pname)
+{
- sync_check_completion();
+ printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
+ printf( " [-n name] [-p port] [-s configuration file]\n" );
+ printf( "\t-D Become a daemon (default)\n" );
+ printf( "\t-a Append to log file (default)\n" );
+ printf( "\t-i Run interactive (not a daemon)\n" );
+ printf( "\t-o Overwrite log file, don't append\n" );
+ printf( "\t-h Print usage\n" );
+ printf( "\t-V Print version\n" );
+ printf( "\t-H hosts file Load a netbios hosts file\n" );
+ printf( "\t-d debuglevel Set the debuglevel\n" );
+ printf( "\t-l log basename. Basename for log/debug files\n" );
+ printf( "\t-n netbiosname. Primary netbios name\n" );
+ printf( "\t-p port Listen on the specified port\n" );
+ printf( "\t-s configuration file Configuration file name\n" );
+ printf( "\n");
+} /* usage */
- /*
- * regularly sync with any other DMBs we know about
- */
- if (lp_enhanced_browsing())
- sync_all_dmbs(t);
+/**************************************************************************** **
+ Main program.
+ **************************************************************************** */
- /*
- * clear the unexpected packet queue
- */
+ int main(int argc,char *argv[])
+{
+ int opt;
+ extern FILE *dbf;
+ extern char *optarg;
+ extern BOOL append_log;
+ extern BOOL AllowDebugChange;
+ BOOL opt_interactive = False;
+ pstring logfile;
- clear_unexpected(t);
+ append_log = True; /* Default, override with '-o' option. */
- /*
- * Reload the services file if we got a sighup.
- */
+ global_nmb_port = NMB_PORT;
+ *host_file = 0;
+ global_in_nmbd = True;
- if(reload_after_sighup) {
- DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
- msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, (void*) &no_subnets, 0);
- if(no_subnets)
- return;
- reload_after_sighup = 0;
- }
+ StartupTime = time(NULL);
- /* check for new network interfaces */
+ sys_srandom(time(NULL) ^ sys_getpid());
- if(reload_interfaces(t))
- return;
+ TimeInit();
- /* free up temp memory */
- lp_talloc_free();
- }
-}
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", LOGFILEBASE);
+ lp_set_logfile(logfile);
-/**************************************************************************** **
- Open the socket communication.
- **************************************************************************** */
+ charset_initialise();
-static BOOL open_sockets(BOOL isdaemon, int port)
-{
- /*
- * The sockets opened here will be used to receive broadcast
- * packets *only*. Interface specific sockets are opened in
- * make_subnet() in namedbsubnet.c. Thus we bind to the
- * address "0.0.0.0". The parameter 'socket address' is
- * now deprecated.
- */
-
- if ( isdaemon )
- ClientNMB = open_socket_in(SOCK_DGRAM, port,
- 0, interpret_addr(lp_socket_address()),
- True);
- else
- ClientNMB = 0;
-
- ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
+#ifdef LMHOSTSFILE
+ pstrcpy( host_file, LMHOSTSFILE );
+#endif
- if ( ClientNMB == -1 )
- return( False );
+ /* this is for people who can't start the program correctly */
+ while (argc > 1 && (*argv[1] != '-'))
+ {
+ argv++;
+ argc--;
+ }
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
+ fault_setup((void (*)(void *))fault_continue );
- set_socket_options( ClientNMB, "SO_BROADCAST" );
- set_socket_options( ClientDGRAM, "SO_BROADCAST" );
+ /* POSIX demands that signals are inherited. If the invoking process has
+ * these signals masked, we will have problems, as we won't recieve them. */
+ BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGUSR1);
+ BlockSignals(False, SIGTERM);
- DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
- return( True );
-}
+ CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
+ CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
-/**************************************************************************** **
- main program
- **************************************************************************** */
- int main(int argc, const char *argv[])
-{
- pstring logfile;
- static BOOL opt_interactive;
- poptContext pc;
- int opt;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
- {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
- {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- {"hosts", 'H', POPT_ARG_STRING, dyn_LMHOSTSFILE, 'H', "Load a netbios hosts file"},
- {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
- POPT_COMMON_SAMBA
- { NULL }
- };
-
- global_nmb_port = NMB_PORT;
-
- pc = poptGetContext("nmbd", argc, argv, long_options, 0);
- while ((opt = poptGetNextOpt(pc)) != -1) ;
- poptFreeContext(pc);
-
- global_in_nmbd = True;
-
- StartupTime = time(NULL);
-
- sys_srandom(time(NULL) ^ sys_getpid());
-
- slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
-
- fault_setup((void (*)(void *))fault_continue );
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't receive them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
- BlockSignals(False, SIGTERM);
-
- CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
- CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
-
#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
+ /* we are never interested in SIGFPE */
+ BlockSignals(True,SIGFPE);
#endif
- /* We no longer use USR2... */
+ /* We no longer use USR2... */
#if defined(SIGUSR2)
- BlockSignals(True, SIGUSR2);
+ BlockSignals(True, SIGUSR2);
#endif
- if ( opt_interactive ) {
- Fork = False;
- log_stdout = True;
- }
-
- if ( log_stdout && Fork ) {
- DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
- exit(1);
- }
-
- setup_logging( argv[0], log_stdout );
-
- reopen_logs();
-
- DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
- DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2004\n" ) );
-
- if ( !reload_nmbd_services(False) )
- return(-1);
-
- if(!init_names())
- return -1;
-
- reload_nmbd_services( True );
-
- if (strequal(lp_workgroup(),"*")) {
- DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
- exit(1);
- }
-
- set_samba_nb_type();
-
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
+ while( EOF !=
+ (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dip:hSH:G:f:" )) )
+ {
+ switch (opt)
+ {
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+ case 'N':
+ case 'B':
+ case 'I':
+ case 'C':
+ case 'G':
+ DEBUG(0,("Obsolete option '%c' used\n",opt));
+ break;
+ case 'H':
+ pstrcpy(host_file,optarg);
+ break;
+ case 'n':
+ pstrcpy(global_myname,optarg);
+ strupper(global_myname);
+ break;
+ case 'l':
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", optarg);
+ lp_set_logfile(logfile);
+ break;
+ case 'a':
+ append_log = True;
+ break;
+ case 'o':
+ append_log = False;
+ break;
+ case 'i':
+ opt_interactive = True;
+ break;
+ case 'D':
+ is_daemon = True;
+ break;
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ AllowDebugChange = False;
+ break;
+ case 'p':
+ global_nmb_port = atoi(optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ break;
+ case 'V':
+ printf( "Version %s\n", VERSION );
+ exit(0);
+ break;
+ default:
+ if( !is_a_socket(0) )
+ {
+ DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
+ usage(argv[0]);
+ exit(0);
+ }
+ break;
+ }
+ }
+
+ setup_logging( argv[0], opt_interactive );
+ reopen_logs();
+
+ DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
+ DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) );
+
+ if ( !reload_nmbd_services(False) )
+ return(-1);
+
+#ifdef WITH_PROFILE
+ if (!profile_setup(False)) {
+ DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
+ return -1;
+ }
+#endif /* WITH_PROFILE */
+
+ codepage_initialise(lp_client_code_page());
+
+ if(!init_structs())
+ return -1;
+
+ reload_nmbd_services( True );
+
+ fstrcpy( global_myworkgroup, lp_workgroup() );
+
+ if (strequal(global_myworkgroup,"*"))
+ {
+ DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
+ exit(1);
+ }
+
+ set_samba_nb_type();
+
+ if (!is_daemon && !is_a_socket(0))
+ {
+ DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+ is_daemon = True;
+ }
- if (is_daemon && !opt_interactive) {
- DEBUG( 2, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
- }
+ if (is_daemon && !opt_interactive)
+ {
+ DEBUG( 2, ( "Becoming a daemon.\n" ) );
+ become_daemon();
+ }
#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (opt_interactive)
- setpgid( (pid_t)0, (pid_t)0 );
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (opt_interactive)
+ setpgid( (pid_t)0, (pid_t)0 );
#endif
#ifndef SYNC_DNS
- /* Setup the async dns. We do it here so it doesn't have all the other
- stuff initialised and thus chewing memory and sockets */
- if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
- start_async_dns();
- }
+ /* Setup the async dns. We do it here so it doesn't have all the other
+ stuff initialised and thus chewing memory and sockets */
+ if(lp_we_are_a_wins_server()) {
+ start_async_dns();
+ }
#endif
- if (!directory_exist(lp_lockdir(), NULL)) {
- mkdir(lp_lockdir(), 0755);
- }
-
- pidfile_create("nmbd");
- message_init();
- message_register(MSG_FORCE_ELECTION, nmbd_message_election);
- message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
- message_register(MSG_SHUTDOWN, nmbd_terminate);
- message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
-
- DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
-
- if ( !open_sockets( is_daemon, global_nmb_port ) ) {
- kill_async_dns_child();
- return 1;
- }
-
- /* Determine all the IP addresses we have. */
- load_interfaces();
-
- /* Create an nmbd subnet record for each of the above. */
- if( False == create_subnets() ) {
- DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* Load in any static local names. */
- load_lmhosts_file(dyn_LMHOSTSFILE);
- DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
-
- /* If we are acting as a WINS server, initialise data structures. */
- if( !initialise_wins() ) {
- DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
- kill_async_dns_child();
- exit(1);
- }
-
- /*
- * Register nmbd primary workgroup and nmbd names on all
- * the broadcast subnets, and on the WINS server (if specified).
- * Also initiate the startup of our primary workgroup (start
- * elections if we are setup as being able to be a local
- * master browser.
- */
-
- if( False == register_my_workgroup_and_names() ) {
- DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
- kill_async_dns_child();
- exit(1);
- }
-
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
- process();
-
- if (dbf)
- x_fclose(dbf);
- kill_async_dns_child();
- return(0);
-}
+ if (!directory_exist(lp_lockdir(), NULL)) {
+ mkdir(lp_lockdir(), 0755);
+ }
+
+ pidfile_create("nmbd");
+ message_init();
+ message_register(MSG_FORCE_ELECTION, nmbd_message_election);
+
+ DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
+
+ if ( !open_sockets( is_daemon, global_nmb_port ) )
+ return 1;
+
+ /* Determine all the IP addresses we have. */
+ load_interfaces();
+
+ /* Create an nmbd subnet record for each of the above. */
+ if( False == create_subnets() )
+ {
+ DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
+ exit(1);
+ }
+
+ /* Load in any static local names. */
+ if ( *host_file )
+ {
+ load_lmhosts_file(host_file);
+ DEBUG(3,("Loaded hosts file\n"));
+ }
+
+ /* If we are acting as a WINS server, initialise data structures. */
+ if( !initialise_wins() )
+ {
+ DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
+ exit(1);
+ }
+
+ /*
+ * Register nmbd primary workgroup and nmbd names on all
+ * the broadcast subnets, and on the WINS server (if specified).
+ * Also initiate the startup of our primary workgroup (start
+ * elections if we are setup as being able to be a local
+ * master browser.
+ */
+
+ if( False == register_my_workgroup_and_names() )
+ {
+ DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
+ exit(1);
+ }
+
+ /* We can only take signals in the select. */
+ BlockSignals( True, SIGTERM );
+
+ process();
+
+ if (dbf)
+ fclose(dbf);
+ return(0);
+} /* main */
diff --git a/source/nmbd/nmbd_become_dmb.c b/source/nmbd/nmbd_become_dmb.c
index fb1fb33a818..7af896e3e03 100644
--- a/source/nmbd/nmbd_become_dmb.c
+++ b/source/nmbd/nmbd_become_dmb.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,11 +24,14 @@
#include "includes.h"
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
extern struct in_addr allones_ip;
extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
-static void become_domain_master_browser_bcast(const char *);
+static void become_domain_master_browser_bcast(char *);
/****************************************************************************
Fail to become a Domain Master Browser on a subnet.
@@ -37,37 +41,36 @@ static void become_domain_master_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- unstring failname;
- struct work_record *work;
- struct server_record *servrec;
-
- pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
- work = find_workgroup_on_subnet(subrec, failname);
- if(!work) {
- DEBUG(0,("become_domain_master_fail: Error - cannot find \
-workgroup %s on subnet %s\n", failname, subrec->subnet_name));
- return;
- }
-
- /* Set the state back to DOMAIN_NONE. */
- work->dom_state = DOMAIN_NONE;
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
+ struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
+ struct server_record *servrec;
+
+ if(!work)
+ {
+ DEBUG(0,("become_domain_master_fail: Error - cannot find \
+workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
+ return;
+ }
+
+ /* Set the state back to DOMAIN_NONE. */
+ work->dom_state = DOMAIN_NONE;
+
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("become_domain_master_fail: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname, work->work_group, subrec->subnet_name));
+ return;
+ }
- /* Update our server status. */
- servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
+ /* Update our server status. */
+ servrec->serv.type &= ~SV_TYPE_DOMAIN_MASTER;
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
+ DEBUG(0,("become_domain_master_fail: Failed to become a domain master browser for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
/****************************************************************************
@@ -80,112 +83,115 @@ static void become_domain_master_stage2(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- unstring regname;
- struct work_record *work;
- struct server_record *servrec;
-
- pull_ascii_nstring(regname, sizeof(regname), registered_name->name);
- work = find_workgroup_on_subnet( subrec, regname);
-
- if(!work) {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", regname, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
+ struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
+ struct server_record *servrec;
+
+ if(!work)
+ {
+ DEBUG(0,("become_domain_master_stage2: Error - cannot find \
+workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("become_domain_master_stage2: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), regname, subrec->subnet_name));
- work->dom_state = DOMAIN_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->dom_state = DOMAIN_MST; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "*****\n\nSamba server %s ", global_myname() );
- dbgtext( "is now a domain master browser for " );
- dbgtext( "workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
-
- if( subrec == unicast_subnet ) {
- struct nmb_name nmbname;
- struct in_addr my_first_ip;
-
- /* Put our name and first IP address into the
- workgroup struct as domain master browser. This
- will stop us syncing with ourself if we are also
- a local master browser. */
-
- make_nmb_name(&nmbname, global_myname(), 0x20);
-
- work->dmb_name = nmbname;
- /* Pick the first interface ip address as the domain master browser ip. */
- my_first_ip = *iface_n_ip(0);
-
- putip((char *)&work->dmb_addr, &my_first_ip);
-
- /* We successfully registered by unicast with the
- WINS server. We now expect to become the domain
- master on the local subnets. If this fails, it's
- probably a 1.9.16p2 to 1.9.16p11 server's fault.
-
- This is a configuration issue that should be addressed
- by the network administrator - you shouldn't have
- several machines configured as a domain master browser
- for the same WINS scope (except if they are 1.9.17 or
- greater, and you know what you're doing.
-
- see docs/DOMAIN.txt.
-
- */
- become_domain_master_browser_bcast(work->work_group);
- } else {
- /*
- * Now we are a domain master on a broadcast subnet, we need to add
- * the WORKGROUP<1b> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. This bug wasn't found for a while
- * as it is strange to have a DMB without using WINS. JRA.
- */
- insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
- }
+ global_myname, registered_name->name, subrec->subnet_name));
+ work->dom_state = DOMAIN_NONE;
+ return;
+ }
+
+ /* Set the state in the workgroup structure. */
+ work->dom_state = DOMAIN_MST; /* Become domain master. */
+
+ /* Update our server status. */
+ servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER);
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "*****\n\nSamba server %s ", global_myname );
+ dbgtext( "is now a domain master browser for " );
+ dbgtext( "workgroup %s ", work->work_group );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
+
+ if( subrec == unicast_subnet )
+ {
+ struct nmb_name nmbname;
+ struct in_addr my_first_ip;
+
+ /* Put our name and first IP address into the
+ workgroup struct as domain master browser. This
+ will stop us syncing with ourself if we are also
+ a local master browser. */
+
+ make_nmb_name(&nmbname, global_myname, 0x20);
+
+ work->dmb_name = nmbname;
+ /* Pick the first interface ip address as the domain master browser ip. */
+ my_first_ip = *iface_n_ip(0);
+
+ putip((char *)&work->dmb_addr, &my_first_ip);
+
+ /* We successfully registered by unicast with the
+ WINS server. We now expect to become the domain
+ master on the local subnets. If this fails, it's
+ probably a 1.9.16p2 to 1.9.16p11 server's fault.
+
+ This is a configuration issue that should be addressed
+ by the network administrator - you shouldn't have
+ several machines configured as a domain master browser
+ for the same WINS scope (except if they are 1.9.17 or
+ greater, and you know what you're doing.
+
+ see docs/DOMAIN.txt.
+
+ */
+ become_domain_master_browser_bcast(work->work_group);
+ }
+ else
+ {
+ /*
+ * Now we are a domain master on a broadcast subnet, we need to add
+ * the WORKGROUP<1b> name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. This bug wasn't found for a while
+ * as it is strange to have a DMB without using WINS. JRA.
+ */
+ insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
+ }
}
/****************************************************************************
Start the name registration process when becoming a Domain Master Browser
on a subnet.
-****************************************************************************/
+ ****************************************************************************/
-static void become_domain_master_stage1(struct subnet_record *subrec, const char *wg_name)
+static void become_domain_master_stage1(struct subnet_record *subrec, char *wg_name)
{
- struct work_record *work;
+ struct work_record *work;
- DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
+ DEBUG(2,("become_domain_master_stage1: Becoming domain master browser for \
workgroup %s on subnet %s\n", wg_name, subrec->subnet_name));
- /* First, find the workgroup on the subnet. */
- if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL) {
- DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
- wg_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
- work->dom_state = DOMAIN_WAIT;
-
- /* WORKGROUP<1b> is the domain master browser name. */
- register_name(subrec, work->work_group,0x1b,samba_nb_type,
- become_domain_master_stage2,
- become_domain_master_fail, NULL);
+ /* First, find the workgroup on the subnet. */
+ if((work = find_workgroup_on_subnet( subrec, wg_name )) == NULL)
+ {
+ DEBUG(0,("become_domain_master_stage1: Error - unable to find workgroup %s on subnet %s.\n",
+ wg_name, subrec->subnet_name));
+ return;
+ }
+
+ DEBUG(3,("become_domain_master_stage1: go to first stage: register <1b> name\n"));
+ work->dom_state = DOMAIN_WAIT;
+
+ /* WORKGROUP<1b> is the domain master browser name. */
+ register_name(subrec, work->work_group,0x1b,samba_nb_type,
+ become_domain_master_stage2,
+ become_domain_master_fail, NULL);
}
/****************************************************************************
@@ -200,35 +206,38 @@ static void become_domain_master_query_success(struct subnet_record *subrec,
struct nmb_name *nmbname, struct in_addr ip,
struct res_rec *rrec)
{
- unstring name;
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
-
- /* If the given ip is not ours, then we can't become a domain
- controler as the name is already registered.
- */
-
- /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
- address or zero ip for this query. Pretend this is ok. */
-
- if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip)) {
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "become_domain_master_query_success():\n" );
- dbgtext( "Our address (%s) ", inet_ntoa(ip) );
- dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
- dbgtext( "(domain master browser name) " );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- dbgtext( "Continuing with domain master code.\n" );
- }
-
- become_domain_master_stage1(subrec, name);
- } else {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "become_domain_master_query_success:\n" );
- dbgtext( "There is already a domain master browser at " );
- dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), name );
- dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
- }
- }
+ /* If the given ip is not ours, then we can't become a domain
+ controler as the name is already registered.
+ */
+
+ /* BUG note. Samba 1.9.16p11 servers seem to return the broadcast
+ address or zero ip for this query. Pretend this is ok. */
+
+ if(ismyip(ip) || ip_equal(allones_ip, ip) || is_zero_ip(ip))
+ {
+ if( DEBUGLVL( 3 ) )
+ {
+ dbgtext( "become_domain_master_query_success():\n" );
+ dbgtext( "Our address (%s) ", inet_ntoa(ip) );
+ dbgtext( "returned in query for name %s ", nmb_namestr(nmbname) );
+ dbgtext( "(domain master browser name) " );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ dbgtext( "Continuing with domain master code.\n" );
+ }
+
+ become_domain_master_stage1(subrec, nmbname->name);
+ }
+ else
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "become_domain_master_query_success:\n" );
+ dbgtext( "There is already a domain master browser at " );
+ dbgtext( "IP %s for workgroup %s ", inet_ntoa(ip), nmbname->name );
+ dbgtext( "registered on subnet %s.\n", subrec->subnet_name );
+ }
+ become_domain_master_stage1(subrec, nmbname->name);
+ }
}
/****************************************************************************
@@ -241,111 +250,115 @@ static void become_domain_master_query_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- unstring name;
-
- /* If the query was unicast, and the error is not NAM_ERR (name didn't exist),
- then this is a failure. Otherwise, not finding the name is what we want. */
-
- if((subrec == unicast_subnet) && (fail_code != NAM_ERR)) {
- DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
+ /* If the query was unicast, and the error is not NAM_ERR (name didn't exist),
+ then this is a failure. Otherwise, not finding the name is what we want. */
+ if((subrec == unicast_subnet) && (fail_code != NAM_ERR))
+ {
+ DEBUG(0,("become_domain_master_query_fail: Error %d returned when \
querying WINS server for name %s.\n",
- fail_code, nmb_namestr(question_name)));
- return;
- }
+ fail_code, nmb_namestr(question_name)));
+ return;
+ }
- /* Otherwise - not having the name allows us to register it. */
- pull_ascii_nstring(name, sizeof(name), question_name->name);
- become_domain_master_stage1(subrec, name);
+ /* Otherwise - not having the name allows us to register it. */
+ become_domain_master_stage1(subrec, question_name->name);
}
/****************************************************************************
Attempt to become a domain master browser on all broadcast subnets.
****************************************************************************/
-static void become_domain_master_browser_bcast(const char *workgroup_name)
+static void become_domain_master_browser_bcast(char *workgroup_name)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
-
- if (work && (work->dom_state == DOMAIN_NONE)) {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
-
- /*
- * Check for our name on the given broadcast subnet first, only initiate
- * further processing if we cannot find it.
- */
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "become_domain_master_browser_bcast:\n" );
- dbgtext( "Attempting to become domain master browser on " );
- dbgtext( "workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name );
- }
-
- /* Send out a query to establish whether there's a
- domain controller on the local subnet. If not,
- we can become a domain controller.
- */
-
- DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
+
+ if (work && (work->dom_state == DOMAIN_NONE))
+ {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,workgroup_name,0x1b);
+
+ /*
+ * Check for our name on the given broadcast subnet first, only initiate
+ * further processing if we cannot find it.
+ */
+
+ if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "become_domain_master_browser_bcast:\n" );
+ dbgtext( "Attempting to become domain master browser on " );
+ dbgtext( "workgroup %s on subnet %s\n",
+ workgroup_name, subrec->subnet_name );
+ }
+
+ /* Send out a query to establish whether there's a
+ domain controller on the local subnet. If not,
+ we can become a domain controller.
+ */
+
+ DEBUG(0,("become_domain_master_browser_bcast: querying subnet %s \
for domain master browser on workgroup %s\n", subrec->subnet_name, workgroup_name));
- query_name(subrec, workgroup_name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
- }
+ query_name(subrec, nmbname.name, nmbname.name_type,
+ become_domain_master_query_success,
+ become_domain_master_query_fail,
+ NULL);
+ }
+ }
+ }
}
/****************************************************************************
Attempt to become a domain master browser by registering with WINS.
****************************************************************************/
-static void become_domain_master_browser_wins(const char *workgroup_name)
+static void become_domain_master_browser_wins(char *workgroup_name)
{
- struct work_record *work;
+ struct work_record *work;
- work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
+ work = find_workgroup_on_subnet(unicast_subnet, workgroup_name);
- if (work && (work->dom_state == DOMAIN_NONE)) {
- struct nmb_name nmbname;
+ if (work && (work->dom_state == DOMAIN_NONE))
+ {
+ struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
+ make_nmb_name(&nmbname,workgroup_name,0x1b);
- /*
- * Check for our name on the unicast subnet first, only initiate
- * further processing if we cannot find it.
- */
+ /*
+ * Check for our name on the unicast subnet first, only initiate
+ * further processing if we cannot find it.
+ */
- if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "become_domain_master_browser_wins:\n" );
- dbgtext( "Attempting to become domain master browser " );
- dbgtext( "on workgroup %s, subnet %s.\n",
- workgroup_name, unicast_subnet->subnet_name );
- }
+ if (find_name_on_subnet(unicast_subnet, &nmbname, FIND_SELF_NAME) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "become_domain_master_browser_wins:\n" );
+ dbgtext( "Attempting to become domain master browser " );
+ dbgtext( "on workgroup %s, subnet %s.\n",
+ workgroup_name, unicast_subnet->subnet_name );
+ }
- /* Send out a query to establish whether there's a
- domain master broswer registered with WINS. If not,
- we can become a domain master browser.
- */
+ /* Send out a query to establish whether there's a
+ domain master broswer registered with WINS. If not,
+ we can become a domain master browser.
+ */
- DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
+ DEBUG(0,("become_domain_master_browser_wins: querying WINS server at IP %s \
for domain master browser name %s on workgroup %s\n",
- inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
-
- query_name(unicast_subnet, workgroup_name, nmbname.name_type,
- become_domain_master_query_success,
- become_domain_master_query_fail,
- NULL);
- }
- }
+ inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
+
+ query_name(unicast_subnet, nmbname.name, nmbname.name_type,
+ become_domain_master_query_success,
+ become_domain_master_query_fail,
+ NULL);
+ }
+ }
}
/****************************************************************************
@@ -355,32 +368,34 @@ for domain master browser name %s on workgroup %s\n",
void add_domain_names(time_t t)
{
- static time_t lastrun = 0;
-
- if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
- return;
-
- lastrun = t;
-
- /* Do the "internet group" - <1c> names. */
- if (lp_domain_logons())
- add_logon_names();
-
- /* Do the domain master names. */
- if(lp_domain_master()) {
- if(we_are_a_wins_client()) {
- /* We register the WORKGROUP<1b> name with the WINS
- server first, and call add_domain_master_bcast()
- only if this is successful.
-
- This results in domain logon services being gracefully provided,
- as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
- 1.9.16p2 to 1.9.16p11 - due to a bug in namelogon.c,
- cannot provide domain master / domain logon services.
- */
- become_domain_master_browser_wins(lp_workgroup());
- } else {
- become_domain_master_browser_bcast(lp_workgroup());
- }
- }
+ static time_t lastrun = 0;
+
+ if ((lastrun != 0) && (t < lastrun + (CHECK_TIME_ADD_DOM_NAMES * 60)))
+ return;
+
+ lastrun = t;
+
+ /* Do the "internet group" - <1c> names. */
+ if (lp_domain_logons())
+ add_logon_names();
+
+ /* Do the domain master names. */
+ if(lp_domain_master())
+ {
+ if(we_are_a_wins_client())
+ {
+ /* We register the WORKGROUP<1b> name with the WINS
+ server first, and call add_domain_master_bcast()
+ only if this is successful.
+
+ This results in domain logon services being gracefully provided,
+ as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
+ 1.9.16p2 to 1.9.16p11 - due to a bug in namelogon.c,
+ cannot provide domain master / domain logon services.
+ */
+ become_domain_master_browser_wins(global_myworkgroup);
+ }
+ else
+ become_domain_master_browser_bcast(global_myworkgroup);
+ }
}
diff --git a/source/nmbd/nmbd_become_lmb.c b/source/nmbd/nmbd_become_lmb.c
index c536deb6f45..7767eff805c 100644
--- a/source/nmbd/nmbd_become_lmb.c
+++ b/source/nmbd/nmbd_become_lmb.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,6 +24,8 @@
#include "includes.h"
+extern pstring global_myname;
+
extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
/*******************************************************************
@@ -33,20 +36,21 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
void insert_permanent_name_into_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_type )
{
- unstring name;
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, name,
- nmbname->name_type, nb_type,
- PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
- } else {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
+ struct name_record *namerec;
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
+ {
+ /* The name needs to be created on the unicast subnet. */
+ (void)add_name_to_subnet( unicast_subnet, nmbname->name,
+ nmbname->name_type, nb_type,
+ PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
+ }
+ else
+ {
+ /* The name already exists on the unicast subnet. Add our local
+ IP for the given broadcast subnet to the name. */
+ add_ip_to_name_record( namerec, subrec->myip);
+ }
}
/*******************************************************************
@@ -56,14 +60,15 @@ void insert_permanent_name_into_unicast( struct subnet_record *subrec,
static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname )
{
- struct name_record *namerec;
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL) {
- /* Remove this broadcast subnet IP address from the name. */
- remove_ip_from_name_record( namerec, subrec->myip);
- if(namerec->data.num_ips == 0)
- remove_name_from_namelist( unicast_subnet, namerec);
- }
+ struct name_record *namerec;
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
+ {
+ /* Remove this broadcast subnet IP address from the name. */
+ remove_ip_from_name_record( namerec, subrec->myip);
+ if(namerec->data.num_ips == 0)
+ remove_name_from_namelist( unicast_subnet, namerec);
+ }
}
/*******************************************************************
@@ -71,58 +76,60 @@ static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
state back to potential browser, or none.
******************************************************************/
-static void reset_workgroup_state( struct subnet_record *subrec, const char *workgroup_name,
+static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
BOOL force_new_election )
{
- struct work_record *work;
- struct server_record *servrec;
- struct nmb_name nmbname;
+ struct work_record *work;
+ struct server_record *servrec;
+ struct nmb_name nmbname;
- if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL) {
- DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
+ if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
+ {
+ DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
subnet %s.\n", workgroup_name, subrec->subnet_name ));
- return;
- }
+ return;
+ }
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname, work->work_group, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- /* Update our server status - remove any master flag and replace
- it with the potential browser flag. */
- servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
- servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
+ /* Update our server status - remove any master flag and replace
+ it with the potential browser flag. */
+ servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
+ servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- /* Reset our election flags. */
- work->ElectionCriterion &= ~0x4;
+ /* Reset our election flags. */
+ work->ElectionCriterion &= ~0x4;
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- /* Forget who the local master browser was for
- this workgroup. */
+ /* Forget who the local master browser was for
+ this workgroup. */
- set_workgroup_local_master_browser_name( work, "");
+ set_workgroup_local_master_browser_name( work, "");
- /*
- * Ensure the IP address of this subnet is not registered as one
- * of the IP addresses of the WORKGROUP<1d> name on the unicast
- * subnet. This undoes what we did below when we became a local
- * master browser.
- */
+ /*
+ * Ensure the IP address of this subnet is not registered as one
+ * of the IP addresses of the WORKGROUP<1d> name on the unicast
+ * subnet. This undoes what we did below when we became a local
+ * master browser.
+ */
- make_nmb_name(&nmbname, work->work_group, 0x1d);
+ make_nmb_name(&nmbname, work->work_group, 0x1d);
- remove_permanent_name_from_unicast( subrec, &nmbname);
+ remove_permanent_name_from_unicast( subrec, &nmbname);
- if(force_new_election)
- work->needelection = True;
+ if(force_new_election)
+ work->needelection = True;
}
/*******************************************************************
@@ -134,25 +141,24 @@ static void unbecome_local_master_success(struct subnet_record *subrec,
struct nmb_name *released_name,
struct in_addr released_ip)
{
- BOOL force_new_election = False;
- unstring relname;
+ BOOL force_new_election = False;
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
+ memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
- DEBUG(3,("unbecome_local_master_success: released name %s.\n",
- nmb_namestr(released_name)));
+ DEBUG(3,("unbecome_local_master_success: released name %s.\n",
+ nmb_namestr(released_name)));
- /* Now reset the workgroup and server state. */
- pull_ascii_nstring(relname, sizeof(relname), released_name->name);
- reset_workgroup_state( subrec, relname, force_new_election );
+ /* Now reset the workgroup and server state. */
+ reset_workgroup_state( subrec, released_name->name, force_new_election );
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", relname );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname );
+ dbgtext( "has stopped being a local master browser " );
+ dbgtext( "for workgroup %s ", released_name->name );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
}
@@ -163,66 +169,67 @@ static void unbecome_local_master_success(struct subnet_record *subrec,
static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct name_record *namerec;
- struct userdata_struct *userdata = rrec->userdata;
- BOOL force_new_election = False;
- unstring failname;
+ struct name_record *namerec;
+ struct userdata_struct *userdata = rrec->userdata;
+ BOOL force_new_election = False;
- memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
+ memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
- DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
+ DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
Removing from namelist anyway.\n", nmb_namestr(fail_name)));
- /* Do it anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
-
- /* Now reset the workgroup and server state. */
- pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
- reset_workgroup_state( subrec, failname, force_new_election );
-
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "has stopped being a local master browser " );
- dbgtext( "for workgroup %s ", failname );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
+ /* Do it anyway. */
+ namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
+ if(namerec)
+ remove_name_from_namelist(subrec, namerec);
+
+ /* Now reset the workgroup and server state. */
+ reset_workgroup_state( subrec, fail_name->name, force_new_election );
+
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname );
+ dbgtext( "has stopped being a local master browser " );
+ dbgtext( "for workgroup %s ", fail_name->name );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
}
/*******************************************************************
Utility function to remove the WORKGROUP<1d> name.
******************************************************************/
-static void release_1d_name( struct subnet_record *subrec, const char *workgroup_name,
+static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
BOOL force_new_election)
{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, workgroup_name, 0x1d);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(BOOL);
-
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
- DEBUG(0,("release_1d_name: malloc fail.\n"));
- return;
- }
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(BOOL);
- memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
-
- release_name(subrec, namerec,
- unbecome_local_master_success,
- unbecome_local_master_fail,
- userdata);
-
- zero_free(userdata, size);
- }
+ struct nmb_name nmbname;
+ struct name_record *namerec;
+
+ make_nmb_name(&nmbname, workgroup_name, 0x1d);
+ if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
+ {
+ struct userdata_struct *userdata;
+ int size = sizeof(struct userdata_struct) + sizeof(BOOL);
+
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
+ {
+ DEBUG(0,("release_1d_name: malloc fail.\n"));
+ return;
+ }
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(BOOL);
+ memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
+
+ release_name(subrec, namerec,
+ unbecome_local_master_success,
+ unbecome_local_master_fail,
+ userdata);
+
+ zero_free(userdata, size);
+ }
}
/*******************************************************************
@@ -234,11 +241,11 @@ static void release_msbrowse_name_success(struct subnet_record *subrec,
struct nmb_name *released_name,
struct in_addr released_ip)
{
- DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
- nmb_namestr(released_name), subrec->subnet_name ));
+ DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
+ nmb_namestr(released_name), subrec->subnet_name ));
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, released_name);
+ /* Remove the permanent MSBROWSE name added into the unicast subnet. */
+ remove_permanent_name_from_unicast( subrec, released_name);
}
/*******************************************************************
@@ -249,18 +256,18 @@ static void release_msbrowse_name_fail( struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
- nmb_namestr(fail_name), subrec->subnet_name ));
+ DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
+ nmb_namestr(fail_name), subrec->subnet_name ));
- /* Release the name anyway. */
- namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
- if(namerec)
- remove_name_from_namelist(subrec, namerec);
+ /* Release the name anyway. */
+ namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
+ if(namerec)
+ remove_name_from_namelist(subrec, namerec);
- /* Remove the permanent MSBROWSE name added into the unicast subnet. */
- remove_permanent_name_from_unicast( subrec, fail_name);
+ /* Remove the permanent MSBROWSE name added into the unicast subnet. */
+ remove_permanent_name_from_unicast( subrec, fail_name);
}
/*******************************************************************
@@ -271,48 +278,50 @@ static void release_msbrowse_name_fail( struct subnet_record *subrec,
void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
BOOL force_new_election)
{
- struct name_record *namerec;
- struct nmb_name nmbname;
+ struct name_record *namerec;
+ struct nmb_name nmbname;
/* Sanity check. */
- DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
+ DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
on subnet %s\n",work->work_group, subrec->subnet_name));
- if(find_server_in_workgroup( work, global_myname()) == NULL) {
- DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
+ if(find_server_in_workgroup( work, global_myname) == NULL)
+ {
+ DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname, work->work_group, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- /* Set the state to unbecoming. */
- work->mst_state = MST_UNBECOMING_MASTER;
-
- /*
- * Release the WORKGROUP<1d> name asap to allow another machine to
- * claim it.
- */
-
- release_1d_name( subrec, work->work_group, force_new_election);
-
- /* Deregister any browser names we may have. */
- make_nmb_name(&nmbname, MSBROWSE, 0x1);
- if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
- release_name(subrec, namerec,
- release_msbrowse_name_success,
- release_msbrowse_name_fail,
- NULL);
- }
-
- /*
- * Ensure we have sent and processed these release packets
- * before returning - we don't want to process any election
- * packets before dealing with the 1d release.
- */
-
- retransmit_or_expire_response_records(time(NULL));
+ /* Set the state to unbecoming. */
+ work->mst_state = MST_UNBECOMING_MASTER;
+
+ /*
+ * Release the WORKGROUP<1d> name asap to allow another machine to
+ * claim it.
+ */
+
+ release_1d_name( subrec, work->work_group, force_new_election);
+
+ /* Deregister any browser names we may have. */
+ make_nmb_name(&nmbname, MSBROWSE, 0x1);
+ if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
+ {
+ release_name(subrec, namerec,
+ release_msbrowse_name_success,
+ release_msbrowse_name_fail,
+ NULL);
+ }
+
+ /*
+ * Ensure we have sent and processed these release packets
+ * before returning - we don't want to process any election
+ * packets before dealing with the 1d release.
+ */
+
+ retransmit_or_expire_response_records(time(NULL));
}
/****************************************************************************
@@ -326,107 +335,104 @@ static void become_local_master_stage2(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- int i = 0;
- struct server_record *sl;
- struct work_record *work;
- struct server_record *servrec;
- unstring regname;
-
- pull_ascii_nstring(regname, sizeof(regname), registered_name->name);
- work = find_workgroup_on_subnet( subrec, regname);
-
- if(!work) {
- DEBUG(0,("become_local_master_stage2: Error - cannot find \
-workgroup %s on subnet %s\n", regname, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
+ int i = 0;
+ struct server_record *sl;
+ struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
+ struct server_record *servrec;
+
+ if(!work)
+ {
+ DEBUG(0,("become_local_master_stage2: Error - cannot find \
+workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), regname, subrec->subnet_name));
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- return;
- }
+ global_myname, registered_name->name, subrec->subnet_name));
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ return;
+ }
- DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
+ DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
on subnet %s\n", work->work_group, subrec->subnet_name));
- work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
-
- /* update our server status */
- servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
- servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /* Add this name to the workgroup as local master browser. */
- set_workgroup_local_master_browser_name( work, global_myname());
-
- /* Count the number of servers we have on our list. If it's
- less than 10 (just a heuristic) request the servers
- to announce themselves.
- */
- for( sl = work->serverlist; sl != NULL; sl = sl->next)
- i++;
-
- if (i < 10) {
- /* Ask all servers on our local net to announce to us. */
- broadcast_announce_request(subrec, work);
- }
-
- /*
- * Now we are a local master on a broadcast subnet, we need to add
- * the WORKGROUP<1d> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We can create this name directly on
- * the unicast subnet as a WINS server always returns true when registering
- * this name, and discards the registration. We use the number of IP
- * addresses registered to this name as a reference count, as we
- * remove this broadcast subnet IP address from it when we stop becoming a local
- * master browser for this broadcast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Reset the announce master browser timer so that we try and tell a domain
- master browser as soon as possible that we are a local master browser. */
- reset_announce_timer();
-
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "*****\n\n" );
- dbgtext( "Samba name server %s ", global_myname() );
- dbgtext( "is now a local master browser " );
- dbgtext( "for workgroup %s ", work->work_group );
- dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
- }
+ work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
+
+ /* update our server status */
+ servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
+ servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ /* Add this name to the workgroup as local master browser. */
+ set_workgroup_local_master_browser_name( work, global_myname);
+
+ /* Count the number of servers we have on our list. If it's
+ less than 10 (just a heuristic) request the servers
+ to announce themselves.
+ */
+ for( sl = work->serverlist; sl != NULL; sl = sl->next)
+ i++;
+
+ if (i < 10)
+ {
+ /* Ask all servers on our local net to announce to us. */
+ broadcast_announce_request(subrec, work);
+ }
+
+ /*
+ * Now we are a local master on a broadcast subnet, we need to add
+ * the WORKGROUP<1d> name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. We can create this name directly on
+ * the unicast subnet as a WINS server always returns true when registering
+ * this name, and discards the registration. We use the number of IP
+ * addresses registered to this name as a reference count, as we
+ * remove this broadcast subnet IP address from it when we stop becoming a local
+ * master browser for this broadcast subnet.
+ */
+
+ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
+
+ /* Reset the announce master browser timer so that we try and tell a domain
+ master browser as soon as possible that we are a local master browser. */
+ reset_announce_timer();
+
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "*****\n\n" );
+ dbgtext( "Samba name server %s ", global_myname );
+ dbgtext( "is now a local master browser " );
+ dbgtext( "for workgroup %s ", work->work_group );
+ dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
+ }
+
}
/****************************************************************************
Failed to register the WORKGROUP<1d> name.
****************************************************************************/
-
static void become_local_master_fail2(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- unstring failname;
- struct work_record *work;
+ struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
- DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
+ DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
- pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
- work = find_workgroup_on_subnet( subrec, failname);
-
- if(!work) {
- DEBUG(0,("become_local_master_fail2: Error - cannot find \
-workgroup %s on subnet %s\n", failname, subrec->subnet_name));
- return;
- }
+ if(!work)
+ {
+ DEBUG(0,("become_local_master_fail2: Error - cannot find \
+workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
+ return;
+ }
- /* Roll back all the way by calling unbecome_local_master_browser(). */
- unbecome_local_master_browser(subrec, work, False);
+ /* Roll back all the way by calling unbecome_local_master_browser(). */
+ unbecome_local_master_browser(subrec, work, False);
}
/****************************************************************************
@@ -439,34 +445,35 @@ static void become_local_master_stage1(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- char *work_name = userdata->data;
- struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
-
- if(!work) {
- DEBUG(0,("become_local_master_stage1: Error - cannot find \
- %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
-
- DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
- work->work_group));
-
- work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
-
- /*
- * We registered the MSBROWSE name on a broadcast subnet, now need to add
- * the MSBROWSE name to the unicast subnet so that we can answer
- * unicast requests sent to this name. We create this name directly on
- * the unicast subnet.
- */
-
- insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
-
- /* Attempt to register the WORKGROUP<1d> name. */
- register_name(subrec, work->work_group,0x1d,samba_nb_type,
- become_local_master_stage2,
- become_local_master_fail2,
- NULL);
+ char *work_name = userdata->data;
+ struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
+
+ if(!work)
+ {
+ DEBUG(0,("become_local_master_stage1: Error - cannot find \
+workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
+ return;
+ }
+
+ DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
+ work->work_group));
+
+ work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
+
+ /*
+ * We registered the MSBROWSE name on a broadcast subnet, now need to add
+ * the MSBROWSE name to the unicast subnet so that we can answer
+ * unicast requests sent to this name. We create this name directly on
+ * the unicast subnet.
+ */
+
+ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
+
+ /* Attempt to register the WORKGROUP<1d> name. */
+ register_name(subrec, work->work_group,0x1d,samba_nb_type,
+ become_local_master_stage2,
+ become_local_master_fail2,
+ NULL);
}
/****************************************************************************
@@ -477,27 +484,29 @@ static void become_local_master_fail1(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- char *work_name = rrec->userdata->data;
- struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
+ char *work_name = rrec->userdata->data;
+ struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
- if(!work) {
- DEBUG(0,("become_local_master_fail1: Error - cannot find \
+ if(!work)
+ {
+ DEBUG(0,("become_local_master_fail1: Error - cannot find \
workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
- return;
- }
+ return;
+ }
- if(find_server_in_workgroup(work, global_myname()) == NULL) {
- DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
+ if(find_server_in_workgroup(work, global_myname) == NULL)
+ {
+ DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname, work->work_group, subrec->subnet_name));
+ return;
+ }
- reset_workgroup_state( subrec, work->work_group, False );
+ reset_workgroup_state( subrec, work->work_group, False );
- DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
+ DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
/******************************************************************
@@ -511,57 +520,61 @@ workgroup %s on subnet %s. Couldn't register name %s.\n",
void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
{
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
-
- /* Sanity check. */
- if (!lp_local_master()) {
- DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
- return;
- }
-
- if(!AM_POTENTIAL_MASTER_BROWSER(work)) {
- DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
- work->mst_state ));
- return;
- }
-
- if(find_server_in_workgroup( work, global_myname()) == NULL) {
- DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
+ struct userdata_struct *userdata;
+ int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
+
+ /* Sanity check. */
+ if (!lp_local_master())
+ {
+ DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
+ return;
+ }
+
+ if(!AM_POTENTIAL_MASTER_BROWSER(work))
+ {
+ DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
+ work->mst_state ));
+ return;
+ }
+
+ if(find_server_in_workgroup( work, global_myname) == NULL)
+ {
+ DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), work->work_group, subrec->subnet_name));
- return;
- }
+ global_myname, work->work_group, subrec->subnet_name));
+ return;
+ }
- DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
+ DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
%s on subnet %s\n", work->work_group, subrec->subnet_name));
- DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
- work->mst_state = MST_BACKUP; /* an election win was successful */
+ DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
+ work->mst_state = MST_BACKUP; /* an election win was successful */
- work->ElectionCriterion |= 0x5;
+ work->ElectionCriterion |= 0x5;
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
- /* Setup the userdata_struct. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
- DEBUG(0,("become_local_master_browser: malloc fail.\n"));
- return;
- }
+ /* Setup the userdata_struct. */
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
+ {
+ DEBUG(0,("become_local_master_browser: malloc fail.\n"));
+ return;
+ }
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = strlen(work->work_group)+1;
+ pstrcpy(userdata->data, work->work_group);
- /* Register the special browser group name. */
- register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
- become_local_master_stage1,
- become_local_master_fail1,
- userdata);
+ /* Register the special browser group name. */
+ register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
+ become_local_master_stage1,
+ become_local_master_fail1,
+ userdata);
- zero_free(userdata, size);
+ zero_free(userdata, size);
}
/***************************************************************
@@ -573,7 +586,7 @@ in workgroup %s on subnet %s\n",
void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname)
{
- DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
+ DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
for workgroup %s.\n", newname, work->work_group ));
#if 0
@@ -590,5 +603,6 @@ local_master_browser_name for workgroup %s to workgroup name.\n",
}
#endif
- unstrcpy(work->local_master_browser_name, newname);
+ StrnCpy(work->local_master_browser_name, newname,
+ sizeof(work->local_master_browser_name)-1);
}
diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c
index c92513fae81..cc1ce6c2ab5 100644
--- a/source/nmbd/nmbd_browserdb.c
+++ b/source/nmbd/nmbd_browserdb.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -37,6 +38,7 @@
ubi_dlNewList( lmb_browserlist );
+
/* -------------------------------------------------------------------------- **
* Functions...
*/
@@ -51,9 +53,9 @@ ubi_dlNewList( lmb_browserlist );
* ************************************************************************** **
*/
static void remove_lmb_browser_entry( struct browse_cache_record *browc )
-{
- safe_free( ubi_dlRemThis( lmb_browserlist, browc ) );
-}
+ {
+ safe_free( (char *)ubi_dlRemThis( lmb_browserlist, browc ) );
+ } /* remove_lmb_browser_entry */
/* ************************************************************************** **
* Update a browser death time.
@@ -64,10 +66,10 @@ static void remove_lmb_browser_entry( struct browse_cache_record *browc )
* ************************************************************************** **
*/
void update_browser_death_time( struct browse_cache_record *browc )
-{
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
-}
+ {
+ /* Allow the new lmb to miss an announce period before we remove it. */
+ browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
+ } /* update_browser_death_time */
/* ************************************************************************** **
* Create a browser entry and add it to the local master browser list.
@@ -80,50 +82,51 @@ void update_browser_death_time( struct browse_cache_record *browc )
*
* ************************************************************************** **
*/
-struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name,
- const char *browser_name,
+struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
+ char *browser_name,
struct in_addr ip )
-{
- struct browse_cache_record *browc;
- time_t now = time( NULL );
+ {
+ struct browse_cache_record *browc;
+ time_t now = time( NULL );
- browc = (struct browse_cache_record *)malloc( sizeof( *browc ) );
+ browc = (struct browse_cache_record *)malloc( sizeof( *browc ) );
- if( NULL == browc ) {
- DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") );
- return( NULL );
- }
+ if( NULL == browc )
+ {
+ DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") );
+ return( NULL );
+ }
- memset( (char *)browc, '\0', sizeof( *browc ) );
+ memset( (char *)browc, '\0', sizeof( *browc ) );
- /* For a new lmb entry we want to sync with it after one minute. This
- will allow it time to send out a local announce and build its
- browse list.
- */
-
- browc->sync_time = now + 60;
-
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
-
- unstrcpy( browc->lmb_name, browser_name);
- unstrcpy( browc->work_group, work_name);
- strupper_m( browc->lmb_name );
- strupper_m( browc->work_group );
+ /* For a new lmb entry we want to sync with it after one minute. This
+ will allow it time to send out a local announce and build its
+ browse list.
+ */
+ browc->sync_time = now + 60;
+
+ /* Allow the new lmb to miss an announce period before we remove it. */
+ browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
+
+ StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 );
+ StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 );
+ strupper( browc->lmb_name );
+ strupper( browc->work_group );
- browc->ip = ip;
+ browc->ip = ip;
- (void)ubi_dlAddTail( lmb_browserlist, browc );
-
- if( DEBUGLVL( 3 ) ) {
- Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
- Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group );
- Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) );
- Debug1( "ttl %d\n", (int)browc->death_time );
- }
+ (void)ubi_dlAddTail( lmb_browserlist, browc );
+
+ if( DEBUGLVL( 3 ) )
+ {
+ Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
+ Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group );
+ Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) );
+ Debug1( "ttl %d\n", (int)browc->death_time );
+ }
- return( browc );
-}
+ return( browc );
+ } /* create_browser_in_lmb_cache */
/* ************************************************************************** **
* Find a browser entry in the local master browser list.
@@ -134,17 +137,18 @@ struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name,
*
* ************************************************************************** **
*/
-struct browse_cache_record *find_browser_in_lmb_cache( const char *browser_name )
-{
- struct browse_cache_record *browc;
+struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name )
+ {
+ struct browse_cache_record *browc;
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc; browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
- if( strequal( browser_name, browc->lmb_name ) )
- break;
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc;
+ browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
+ if( strequal( browser_name, browc->lmb_name ) )
+ break;
- return( browc );
-}
+ return( browc );
+ } /* find_browser_in_lmb_cache */
/* ************************************************************************** **
* Expire timed out browsers in the browserlist.
@@ -156,20 +160,24 @@ struct browse_cache_record *find_browser_in_lmb_cache( const char *browser_name
* ************************************************************************** **
*/
void expire_lmb_browsers( time_t t )
-{
- struct browse_cache_record *browc;
- struct browse_cache_record *nextbrowc;
-
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc; browc = nextbrowc ) {
- nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
-
- if( browc->death_time < t ) {
- if( DEBUGLVL( 3 ) ) {
- Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" );
- Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name );
- }
- remove_lmb_browser_entry( browc );
- }
- }
-}
+ {
+ struct browse_cache_record *browc;
+ struct browse_cache_record *nextbrowc;
+
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc;
+ browc = nextbrowc )
+ {
+ nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
+
+ if( browc->death_time < t )
+ {
+ if( DEBUGLVL( 3 ) )
+ {
+ Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" );
+ Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name );
+ }
+ remove_lmb_browser_entry( browc );
+ }
+ }
+ } /* expire_lmb_browsers */
diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c
index 15827e21bae..b30c9ecbf6b 100644
--- a/source/nmbd/nmbd_browsesync.c
+++ b/source/nmbd/nmbd_browsesync.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +23,10 @@
*/
#include "includes.h"
+#include "smb.h"
+
+extern pstring global_myname;
+extern fstring global_myworkgroup;
/* This is our local master browser list database. */
extern ubi_dlList lmb_browserlist[];
@@ -29,70 +34,74 @@ extern ubi_dlList lmb_browserlist[];
/****************************************************************************
As a domain master browser, do a sync with a local master browser.
**************************************************************************/
-
static void sync_with_lmb(struct browse_cache_record *browc)
{
- struct work_record *work;
-
- if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) ) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Failed to get a workgroup for a local master browser " );
- dbgtext( "cache entry workgroup " );
- dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
- }
- return;
- }
-
- /* We should only be doing this if we are a domain master browser for
- the given workgroup. Ensure this is so. */
+ struct work_record *work;
+
+ if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) )
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "Failed to get a workgroup for a local master browser " );
+ dbgtext( "cache entry workgroup " );
+ dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name );
+ }
+ return;
+ }
- if(!AM_DOMAIN_MASTER_BROWSER(work)) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "We are trying to sync with a local master browser " );
- dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
- dbgtext( "and we are not a domain master browser on this workgroup.\n" );
- dbgtext( "Error!\n" );
- }
- return;
- }
+ /* We should only be doing this if we are a domain master browser for
+ the given workgroup. Ensure this is so. */
+
+ if(!AM_DOMAIN_MASTER_BROWSER(work))
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "We are trying to sync with a local master browser " );
+ dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group );
+ dbgtext( "and we are not a domain master browser on this workgroup.\n" );
+ dbgtext( "Error!\n" );
+ }
+ return;
+ }
- if( DEBUGLVL( 2 ) ) {
- dbgtext( "sync_with_lmb:\n" );
- dbgtext( "Initiating sync with local master browser " );
- dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
- dbgtext( "for workgroup %s\n", browc->work_group );
- }
+ if( DEBUGLVL( 2 ) )
+ {
+ dbgtext( "sync_with_lmb:\n" );
+ dbgtext( "Initiating sync with local master browser " );
+ dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) );
+ dbgtext( "for workgroup %s\n", browc->work_group );
+ }
- sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
+ sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True);
- browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
+ browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60);
}
/****************************************************************************
Sync or expire any local master browsers.
**************************************************************************/
-
void dmb_expire_and_sync_browser_lists(time_t t)
{
- static time_t last_run = 0;
- struct browse_cache_record *browc;
+ static time_t last_run = 0;
+ struct browse_cache_record *browc;
- /* Only do this every 20 seconds. */
- if (t - last_run < 20)
- return;
+ /* Only do this every 20 seconds. */
+ if (t - last_run < 20)
+ return;
- last_run = t;
+ last_run = t;
- expire_lmb_browsers(t);
+ expire_lmb_browsers(t);
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) {
- if (browc->sync_time < t)
- sync_with_lmb(browc);
- }
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc;
+ browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
+ {
+ if (browc->sync_time < t)
+ sync_with_lmb(browc);
+ }
}
/****************************************************************************
@@ -101,43 +110,42 @@ As a local master browser, send an announce packet to the domain master browser.
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
{
- pstring outbuf;
- unstring myname;
- char *p;
-
- if(ismyip(work->dmb_addr)) {
- if( DEBUGLVL( 2 ) ) {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "We are both a domain and a local master browser for " );
- dbgtext( "workgroup %s. ", work->work_group );
- dbgtext( "Do not announce to ourselves.\n" );
- }
- return;
- }
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
-
- unstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- /* The call below does CH_UNIX -> CH_DOS conversion. JRA */
- push_pstring_base(p, myname, outbuf);
-
- p = skip_string(p,1);
+ pstring outbuf;
+ char *p;
+
+ if(ismyip(work->dmb_addr))
+ {
+ if( DEBUGLVL( 2 ) )
+ {
+ dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
+ dbgtext( "We are both a domain and a local master browser for " );
+ dbgtext( "workgroup %s. ", work->work_group );
+ dbgtext( "Do not announce to ourselves.\n" );
+ }
+ return;
+ }
- if( DEBUGLVL( 4 ) ) {
- dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
- dbgtext( "Sending local master announce to " );
- dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
- work->work_group );
- }
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_MasterAnnouncement);
+ p++;
+
+ StrnCpy(p,global_myname,15);
+ strupper(p);
+ p = skip_string(p,1);
+
+ if( DEBUGLVL( 4 ) )
+ {
+ dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
+ dbgtext( "Sending local master announce to " );
+ dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name),
+ work->work_group );
+ }
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, work->dmb_name.name, 0x0,
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname, 0x0, work->dmb_name.name, 0x0,
work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
+
}
/****************************************************************************
@@ -146,19 +154,17 @@ As a local master browser, do a sync with a domain master browser.
static void sync_with_dmb(struct work_record *work)
{
- unstring dmb_name;
-
- if( DEBUGLVL( 2 ) ) {
- dbgtext( "sync_with_dmb:\n" );
- dbgtext( "Initiating sync with domain master browser " );
- dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
- dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
- dbgtext( "for workgroup %s\n", work->work_group );
- }
+ if( DEBUGLVL( 2 ) )
+ {
+ dbgtext( "sync_with_dmb:\n" );
+ dbgtext( "Initiating sync with domain master browser " );
+ dbgtext( "%s ", nmb_namestr(&work->dmb_name) );
+ dbgtext( "at IP %s ", inet_ntoa(work->dmb_addr) );
+ dbgtext( "for workgroup %s\n", work->work_group );
+ }
- pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
- sync_browse_lists(work, dmb_name, work->dmb_name.name_type,
- work->dmb_addr, False, True);
+ sync_browse_lists(work, work->dmb_name.name, work->dmb_name.name_type,
+ work->dmb_addr, False, True);
}
/****************************************************************************
@@ -170,69 +176,78 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
struct res_rec *answers,
struct in_addr from_ip)
{
- struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
-
- if( work == NULL ) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Unable to find workgroup " );
- dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
- }
- return;
- }
+ struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data);
+
+ if( work == NULL )
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Unable to find workgroup " );
+ dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name );
+ }
+ return;
+ }
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Success in node status for workgroup " );
- dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
- }
+ if( DEBUGLVL( 3 ) )
+ {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Success in node status for workgroup " );
+ dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) );
+ }
/* Go through the list of names found at answers->rdata and look for
the first SERVER<0x20> name. */
- if(answers->rdata != NULL) {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
+ if(answers->rdata != NULL)
+ {
+ char *p = answers->rdata;
+ int numnames = CVAL(p, 0);
- p += 1;
+ p += 1;
- while (numnames--) {
- unstring qname;
- uint16 nb_flags;
- int name_type;
+ while (numnames--)
+ {
+ char qname[17];
+ uint16 nb_flags;
+ int name_type;
- pull_ascii_nstring(qname, sizeof(qname), p);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_char(qname,'\0',' ');
+ StrnCpy(qname,p,15);
+ name_type = CVAL(p,15);
+ nb_flags = get_nb_flags(&p[16]);
+ trim_string(qname,NULL," ");
- p += 18;
+ p += 18;
- if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) {
- struct nmb_name nmbname;
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x20))
+ {
+ struct nmb_name nmbname;
- make_nmb_name(&nmbname, qname, name_type);
+ make_nmb_name(&nmbname, qname, name_type);
- /* Copy the dmb name and IP address
- into the workgroup struct. */
+ /* Copy the dmb name and IP address
+ into the workgroup struct. */
- work->dmb_name = nmbname;
- putip((char *)&work->dmb_addr, &from_ip);
+ work->dmb_name = nmbname;
+ putip((char *)&work->dmb_addr, &from_ip);
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
+ /* Do the local master browser announcement to the domain
+ master browser name and IP. */
+ announce_local_master_browser_to_domain_master_browser( work );
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- break;
- }
- }
- } else if( DEBUGLVL( 0 ) ) {
- dbgtext( "domain_master_node_status_success:\n" );
- dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
+ /* Now synchronise lists with the domain master browser. */
+ sync_with_dmb(work);
+ break;
+ }
+ }
+ }
+ else
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "domain_master_node_status_success:\n" );
+ dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " );
+ dbgtext( "%s.\n", inet_ntoa(from_ip) );
+ }
}
/****************************************************************************
@@ -242,15 +257,16 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
static void domain_master_node_status_fail(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct userdata_struct *userdata = rrec->userdata;
-
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "domain_master_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser\n" );
- dbgtext( "for workgroup %s ", userdata ? userdata->data : "NULL" );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot sync browser lists.\n" );
- }
+ struct userdata_struct *userdata = rrec->userdata;
+
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "domain_master_node_status_fail:\n" );
+ dbgtext( "Doing a node status request to the domain master browser\n" );
+ dbgtext( "for workgroup %s ", userdata->data );
+ dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
+ dbgtext( "Cannot sync browser lists.\n" );
+ }
}
/****************************************************************************
@@ -261,99 +277,100 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
struct userdata_struct *userdata_in,
struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
{
- /*
- * Unfortunately, finding the IP address of the Domain Master Browser,
- * as we have here, is not enough. We need to now do a sync to the
- * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
- * respond to the SMBSERVER name. To get this name from IP
- * address we do a Node status request, and look for the first
- * NAME<0x20> in the response, and take that as the server name.
- * We also keep a cache of the Domain Master Browser name for this
- * workgroup in the Workgroup struct, so that if the same IP addess
- * is returned every time, we don't need to do the node status
- * request.
- */
-
- struct work_record *work;
- struct nmb_name nmbname;
- struct userdata_struct *userdata;
- size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
- unstring qname;
-
- pull_ascii_nstring(qname, sizeof(qname), q_name->name);
- if( !(work = find_workgroup_on_subnet(subrec, qname)) ) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "find_domain_master_name_query_success:\n" );
- dbgtext( "Failed to find workgroup %s\n", qname);
- }
- return;
+ /*
+ * Unfortunately, finding the IP address of the Domain Master Browser,
+ * as we have here, is not enough. We need to now do a sync to the
+ * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will
+ * respond to the SMBSERVER name. To get this name from IP
+ * address we do a Node status request, and look for the first
+ * NAME<0x20> in the response, and take that as the server name.
+ * We also keep a cache of the Domain Master Browser name for this
+ * workgroup in the Workgroup struct, so that if the same IP addess
+ * is returned every time, we don't need to do the node status
+ * request.
+ */
+
+ struct work_record *work;
+ struct nmb_name nmbname;
+ struct userdata_struct *userdata;
+ int size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
+
+ if( !(work = find_workgroup_on_subnet(subrec, q_name->name)) )
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "find_domain_master_name_query_success:\n" );
+ dbgtext( "Failed to find workgroup %s\n", q_name->name );
+ }
+ return;
}
/* First check if we already have a dmb for this workgroup. */
- if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
- /* Do the local master browser announcement to the domain
- master browser name and IP. */
- announce_local_master_browser_to_domain_master_browser( work );
-
- /* Now synchronise lists with the domain master browser. */
- sync_with_dmb(work);
- return;
- } else {
- zero_ip(&work->dmb_addr);
- }
-
- /* Now initiate the node status request. */
-
- /* We used to use the name "*",0x0 here, but some Windows
- * servers don't answer that name. However we *know* they
- * have the name workgroup#1b (as we just looked it up).
- * So do the node status request on this name instead.
- * Found at LBL labs. JRA.
- */
+ if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip))
+ {
+ /* Do the local master browser announcement to the domain
+ master browser name and IP. */
+ announce_local_master_browser_to_domain_master_browser( work );
- make_nmb_name(&nmbname,work->work_group,0x1b);
-
- /* Put the workgroup name into the userdata so we know
- what workgroup we're talking to when the reply comes
- back. */
-
- /* Setup the userdata_struct - this is copied so we can use
- a stack variable for this. */
-
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
- DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
- return;
- }
+ /* Now synchronise lists with the domain master browser. */
+ sync_with_dmb(work);
+ return;
+ }
+ else
+ zero_ip(&work->dmb_addr);
+
+ /* Now initiate the node status request. */
+
+ /* We used to use the name "*",0x0 here, but some Windows
+ * servers don't answer that name. However we *know* they
+ * have the name workgroup#1b (as we just looked it up).
+ * So do the node status request on this name instead.
+ * Found at LBL labs. JRA.
+ */
+
+ make_nmb_name(&nmbname,work->work_group,0x1b);
+
+ /* Put the workgroup name into the userdata so we know
+ what workgroup we're talking to when the reply comes
+ back. */
+
+ /* Setup the userdata_struct - this is copied so we can use
+ a stack variable for this. */
+ if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
+ {
+ DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
+ return;
+ }
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = strlen(work->work_group)+1;
- overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = strlen(work->work_group)+1;
+ pstrcpy(userdata->data, work->work_group);
- node_status( subrec, &nmbname, answer_ip,
- domain_master_node_status_success,
- domain_master_node_status_fail,
- userdata);
+ node_status( subrec, &nmbname, answer_ip,
+ domain_master_node_status_success,
+ domain_master_node_status_fail,
+ userdata);
- zero_free(userdata, size);
+ zero_free(userdata, size);
}
/****************************************************************************
Function called when a query for a WORKGROUP<1b> name fails.
****************************************************************************/
-
static void find_domain_master_name_query_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "Unable to find the Domain Master Browser name " );
- dbgtext( "%s for the workgroup %s.\n",
- nmb_namestr(question_name), question_name->name );
- dbgtext( "Unable to sync browse lists in this workgroup.\n" );
- }
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "find_domain_master_name_query_fail:\n" );
+ dbgtext( "Unable to find the Domain Master Browser name " );
+ dbgtext( "%s for the workgroup %s.\n",
+ nmb_namestr(question_name), question_name->name );
+ dbgtext( "Unable to sync browse lists in this workgroup.\n" );
+ }
}
/****************************************************************************
@@ -365,20 +382,27 @@ full domain browse lists from it onto the given subnet.
void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
struct work_record *work)
{
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False) {
- if( DEBUGLVL( 10 ) ) {
- dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
- dbgtext( "Ignoring, as we are not a WINS client.\n" );
- }
- return;
- }
+ struct nmb_name nmbname;
+
+ /* Only do this if we are using a WINS server. */
+ if(we_are_a_wins_client() == False)
+ {
+ if( DEBUGLVL( 10 ) )
+ {
+ dbgtext( "announce_and_sync_with_domain_master_browser:\n" );
+ dbgtext( "Ignoring, as we are not a WINS client.\n" );
+ }
+ return;
+ }
+
+ make_nmb_name(&nmbname,work->work_group,0x1b);
- /* First, query for the WORKGROUP<1b> name from the WINS server. */
- query_name(unicast_subnet, work->work_group, 0x1b,
+ /* First, query for the WORKGROUP<1b> name from the WINS server. */
+ query_name(unicast_subnet, nmbname.name, nmbname.name_type,
find_domain_master_name_query_success,
find_domain_master_name_query_fail,
NULL);
+
}
/****************************************************************************
@@ -398,81 +422,89 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
struct res_rec *answers,
struct in_addr from_ip)
{
- struct work_record *work;
- unstring server_name;
-
- server_name[0] = 0;
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
- }
-
- /*
- * Go through the list of names found at answers->rdata and look for
- * the first WORKGROUP<0x1b> name.
- */
-
- if(answers->rdata != NULL) {
- char *p = answers->rdata;
- int numnames = CVAL(p, 0);
-
- p += 1;
+ struct work_record *work;
+ fstring server_name;
- while (numnames--) {
- unstring qname;
- uint16 nb_flags;
- int name_type;
+ server_name[0] = 0;
- pull_ascii_nstring(qname, sizeof(qname), p);
- name_type = CVAL(p,15);
- nb_flags = get_nb_flags(&p[16]);
- trim_char(qname,'\0',' ');
-
- p += 18;
-
- if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
- server_name[0] == 0) {
- /* this is almost certainly the server netbios name */
- unstrcpy(server_name, qname);
- continue;
- }
+ if( DEBUGLVL( 3 ) )
+ {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) );
+ }
- if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) {
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
- dbgtext( "is a domain master browser for workgroup " );
- dbgtext( "%s. Adding this name.\n", qname );
- }
-
- /*
- * If we don't already know about this workgroup, add it
- * to the workgroup list on the unicast_subnet.
- */
-
- if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) {
- struct nmb_name nmbname;
- /*
- * Add it - with an hour in the cache.
- */
- if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
- return;
-
- /* remember who the master is */
- unstrcpy(work->local_master_browser_name, server_name);
- make_nmb_name(&nmbname, server_name, 0x20);
- work->dmb_name = nmbname;
- work->dmb_addr = from_ip;
- }
- break;
- }
- }
- } else if( DEBUGLVL( 0 ) ) {
- dbgtext( "get_domain_master_name_node_status_success:\n" );
- dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
- dbgtext( "%s.\n", inet_ntoa(from_ip) );
- }
+ /*
+ * Go through the list of names found at answers->rdata and look for
+ * the first WORKGROUP<0x1b> name.
+ */
+
+ if(answers->rdata != NULL)
+ {
+ char *p = answers->rdata;
+ int numnames = CVAL(p, 0);
+
+ p += 1;
+
+ while (numnames--)
+ {
+ char qname[17];
+ uint16 nb_flags;
+ int name_type;
+
+ StrnCpy(qname,p,15);
+ name_type = CVAL(p,15);
+ nb_flags = get_nb_flags(&p[16]);
+ trim_string(qname,NULL," ");
+
+ p += 18;
+
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
+ server_name[0] == 0) {
+ /* this is almost certainly the server netbios name */
+ fstrcpy(server_name, qname);
+ continue;
+ }
+
+ if(!(nb_flags & NB_GROUP) && (name_type == 0x1b))
+ {
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
+ dbgtext( "is a domain master browser for workgroup " );
+ dbgtext( "%s. Adding this name.\n", qname );
+ }
+
+ /*
+ * If we don't already know about this workgroup, add it
+ * to the workgroup list on the unicast_subnet.
+ */
+ if((work = find_workgroup_on_subnet( subrec, qname)) == NULL)
+ {
+ struct nmb_name nmbname;
+ /*
+ * Add it - with an hour in the cache.
+ */
+ if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
+ return;
+
+ /* remember who the master is */
+ fstrcpy(work->local_master_browser_name, server_name);
+ make_nmb_name(&nmbname, server_name, 0x20);
+ work->dmb_name = nmbname;
+ work->dmb_addr = from_ip;
+ }
+ break;
+ }
+ }
+ }
+ else
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "get_domain_master_name_node_status_success:\n" );
+ dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
+ dbgtext( "%s.\n", inet_ntoa(from_ip) );
+ }
}
/****************************************************************************
@@ -482,12 +514,13 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
struct response_record *rrec)
{
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "get_domain_master_name_node_status_fail:\n" );
- dbgtext( "Doing a node status request to the domain master browser " );
- dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
- dbgtext( "Cannot get workgroup name.\n" );
- }
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "get_domain_master_name_node_status_fail:\n" );
+ dbgtext( "Doing a node status request to the domain master browser " );
+ dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
+ dbgtext( "Cannot get workgroup name.\n" );
+ }
}
/****************************************************************************
@@ -498,53 +531,58 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
struct userdata_struct *userdata_in,
struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec)
{
- /*
- * We now have a list of all the domain master browsers for all workgroups
- * that have registered with the WINS server. Now do a node status request
- * to each one and look for the first 1b name in the reply. This will be
- * the workgroup name that we will add to the unicast subnet as a 'non-local'
- * workgroup.
- */
-
- struct nmb_name nmbname;
- struct in_addr send_ip;
- int i;
-
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
- dbgtext( "IP addresses for Domain Master Browsers.\n" );
- }
-
- for(i = 0; i < rrec->rdlength / 6; i++) {
- /* Initiate the node status requests. */
- make_nmb_name(&nmbname, "*", 0);
-
- putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
-
- /*
- * Don't send node status requests to ourself.
- */
-
- if(ismyip( send_ip )) {
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "find_all_domain_master_names_query_succes:\n" );
- dbgtext( "Not sending node status to our own IP " );
- dbgtext( "%s.\n", inet_ntoa(send_ip) );
- }
- continue;
- }
-
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "find_all_domain_master_names_query_success:\n" );
- dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
- }
+ /*
+ * We now have a list of all the domain master browsers for all workgroups
+ * that have registered with the WINS server. Now do a node status request
+ * to each one and look for the first 1b name in the reply. This will be
+ * the workgroup name that we will add to the unicast subnet as a 'non-local'
+ * workgroup.
+ */
+
+ struct nmb_name nmbname;
+ struct in_addr send_ip;
+ int i;
+
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "find_all_domain_master_names_query_succes:\n" );
+ dbgtext( "Got answer from WINS server of %d ", (rrec->rdlength / 6) );
+ dbgtext( "IP addresses for Domain Master Browsers.\n" );
+ }
- node_status( subrec, &nmbname, send_ip,
- get_domain_master_name_node_status_success,
- get_domain_master_name_node_status_fail,
- NULL);
- }
+ for(i = 0; i < rrec->rdlength / 6; i++)
+ {
+ /* Initiate the node status requests. */
+ make_nmb_name(&nmbname, "*", 0);
+
+ putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
+
+ /*
+ * Don't send node status requests to ourself.
+ */
+
+ if(ismyip( send_ip ))
+ {
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "find_all_domain_master_names_query_succes:\n" );
+ dbgtext( "Not sending node status to our own IP " );
+ dbgtext( "%s.\n", inet_ntoa(send_ip) );
+ }
+ continue;
+ }
+
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "find_all_domain_master_names_query_success:\n" );
+ dbgtext( "Sending node status request to IP %s.\n", inet_ntoa(send_ip) );
+ }
+
+ node_status( subrec, &nmbname, send_ip,
+ get_domain_master_name_node_status_success,
+ get_domain_master_name_node_status_fail,
+ NULL);
+ }
}
/****************************************************************************
@@ -554,12 +592,13 @@ static void find_all_domain_master_names_query_fail(struct subnet_record *subrec
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- if( DEBUGLVL( 10 ) ) {
- dbgtext( "find_domain_master_name_query_fail:\n" );
- dbgtext( "WINS server did not reply to a query for name " );
- dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
- dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
- }
+ if( DEBUGLVL( 10 ) )
+ {
+ dbgtext( "find_domain_master_name_query_fail:\n" );
+ dbgtext( "WINS server did not reply to a query for name " );
+ dbgtext( "%s.\nThis means it ", nmb_namestr(question_name) );
+ dbgtext( "is probably not a Samba 1.9.18 or above WINS server.\n" );
+ }
}
/****************************************************************************
@@ -570,39 +609,43 @@ static void find_all_domain_master_names_query_fail(struct subnet_record *subrec
<1b> name in the reply - this is the workgroup name. Add this to the unicast
subnet. This is expensive, so we only do this every 15 minutes.
**************************************************************************/
-
void collect_all_workgroup_names_from_wins_server(time_t t)
{
- static time_t lastrun = 0;
- struct work_record *work;
-
- /* Only do this if we are using a WINS server. */
- if(we_are_a_wins_client() == False)
- return;
-
- /* Check to see if we are a domain master browser on the unicast subnet. */
- if((work = find_workgroup_on_subnet( unicast_subnet, lp_workgroup())) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
- dbgtext( "Cannot find my workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
- }
- return;
- }
+ static time_t lastrun = 0;
+ struct work_record *work;
+ struct nmb_name nmbname;
+
+ /* Only do this if we are using a WINS server. */
+ if(we_are_a_wins_client() == False)
+ return;
+
+ /* Check to see if we are a domain master browser on the unicast subnet. */
+ if((work = find_workgroup_on_subnet( unicast_subnet, global_myworkgroup)) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "collect_all_workgroup_names_from_wins_server:\n" );
+ dbgtext( "Cannot find my workgroup %s ", global_myworkgroup );
+ dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name );
+ }
+ return;
+ }
- if(!AM_DOMAIN_MASTER_BROWSER(work))
- return;
+ if(!AM_DOMAIN_MASTER_BROWSER(work))
+ return;
- if ((lastrun != 0) && (t < lastrun + (15 * 60)))
- return;
+ if ((lastrun != 0) && (t < lastrun + (15 * 60)))
+ return;
- lastrun = t;
+ lastrun = t;
- /* First, query for the *<1b> name from the WINS server. */
- query_name(unicast_subnet, "*", 0x1b,
- find_all_domain_master_names_query_success,
- find_all_domain_master_names_query_fail,
- NULL);
+ make_nmb_name(&nmbname,"*",0x1b);
+
+ /* First, query for the *<1b> name from the WINS server. */
+ query_name(unicast_subnet, nmbname.name, nmbname.name_type,
+ find_all_domain_master_names_query_success,
+ find_all_domain_master_names_query_fail,
+ NULL);
}
@@ -614,7 +657,6 @@ To prevent exponential network traffic with large numbers of workgroups
we use a randomised system where sync probability is inversely proportional
to the number of known workgroups
**************************************************************************/
-
void sync_all_dmbs(time_t t)
{
static time_t lastrun = 0;
@@ -627,9 +669,8 @@ void sync_all_dmbs(time_t t)
/* Check to see if we are a domain master browser on the
unicast subnet. */
- work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup());
- if (!work)
- return;
+ work = find_workgroup_on_subnet(unicast_subnet, global_myworkgroup);
+ if (!work) return;
if (!AM_DOMAIN_MASTER_BROWSER(work))
return;
@@ -639,18 +680,15 @@ void sync_all_dmbs(time_t t)
/* count how many syncs we might need to do */
for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strcmp(lp_workgroup(), work->work_group)) {
+ if (strcmp(global_myworkgroup, work->work_group)) {
count++;
}
}
/* sync with a probability of 1/count */
for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strcmp(lp_workgroup(), work->work_group)) {
- unstring dmb_name;
-
- if (((unsigned)sys_random()) % count != 0)
- continue;
+ if (strcmp(global_myworkgroup, work->work_group)) {
+ if (((unsigned)sys_random()) % count != 0) continue;
lastrun = t;
@@ -662,15 +700,13 @@ void sync_all_dmbs(time_t t)
0x20);
}
- pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
-
DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
- dmb_name, inet_ntoa(work->dmb_addr)));
-
+ work->dmb_name.name,
+ inet_ntoa(work->dmb_addr)));
sync_browse_lists(work,
- dmb_name,
+ work->dmb_name.name,
work->dmb_name.name_type,
work->dmb_addr, False, False);
}
}
-}
+}
diff --git a/source/nmbd/nmbd_elections.c b/source/nmbd/nmbd_elections.c
index 470cf4277b5..1e8579282c0 100644
--- a/source/nmbd/nmbd_elections.c
+++ b/source/nmbd/nmbd_elections.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,42 +24,41 @@
#include "includes.h"
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
/* Election parameters. */
extern time_t StartupTime;
/****************************************************************************
Send an election datagram packet.
**************************************************************************/
-
static void send_election_dgram(struct subnet_record *subrec, const char *workgroup_name,
uint32 criterion, int timeup,const char *server_name)
{
- pstring outbuf;
- unstring srv_name;
- char *p;
-
- DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
- workgroup_name, subrec->subnet_name ));
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_Election); /* Election opcode. */
- p++;
-
- SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
- SIVAL(p,1,criterion);
- SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
- p += 13;
- unstrcpy(srv_name, server_name);
- strupper_m(srv_name);
- /* The following call does UNIX -> DOS charset conversion. */
- pstrcpy_base(p, srv_name, outbuf);
- p = skip_string(p,1);
+ pstring outbuf;
+ char *p;
+
+ DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
+ workgroup_name, subrec->subnet_name ));
+
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_Election); /* Election opcode. */
+ p++;
+
+ SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
+ SIVAL(p,1,criterion);
+ SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
+ p += 13;
+ pstrcpy(p,server_name);
+ strupper(p);
+ p = skip_string(p,1);
- send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- global_myname(), 0,
- workgroup_name, 0x1e,
- subrec->bcast_ip, subrec->myip, DGRAM_PORT);
+ send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ global_myname, 0,
+ workgroup_name, 0x1e,
+ subrec->bcast_ip, subrec->myip, DGRAM_PORT);
}
/*******************************************************************
@@ -70,10 +70,8 @@ static void check_for_master_browser_success(struct subnet_record *subrec,
struct nmb_name *answer_name,
struct in_addr answer_ip, struct res_rec *rrec)
{
- unstring aname;
- pull_ascii_nstring(aname, sizeof(aname), answer_name->name);
- DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
-IP %s (just checking).\n", aname, inet_ntoa(answer_ip) ));
+ DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \
+IP %s (just checking).\n", answer_name->name, inet_ntoa(answer_ip) ));
}
/*******************************************************************
@@ -85,39 +83,41 @@ static void check_for_master_browser_fail( struct subnet_record *subrec,
struct nmb_name *question_name,
int fail_code)
{
- unstring workgroup_name;
- struct work_record *work;
-
- pull_ascii_nstring(workgroup_name,sizeof(workgroup_name),question_name->name);
-
- work = find_workgroup_on_subnet(subrec, workgroup_name);
- if(work == NULL) {
- DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
- workgroup_name, subrec->subnet_name ));
- return;
- }
-
- if (strequal(work->work_group, lp_workgroup())) {
-
- if (lp_local_master()) {
- /* We have discovered that there is no local master
- browser, and we are configured to initiate
- an election that we will participate in.
- */
- DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
- work->work_group, subrec->subnet_name ));
-
- /* Setting this means we will participate when the
- election is run in run_elections(). */
- work->needelection = True;
- } else {
- /* We need to force an election, because we are configured
- not to become the local master, but we still need one,
- having detected that one doesn't exist.
- */
- send_election_dgram(subrec, work->work_group, 0, 0, "");
- }
- }
+ char *workgroup_name = question_name->name;
+ struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name);
+
+ if(work == NULL)
+ {
+ DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n",
+ workgroup_name, subrec->subnet_name ));
+ return;
+ }
+
+ if (strequal(work->work_group, global_myworkgroup))
+ {
+
+ if (lp_local_master())
+ {
+ /* We have discovered that there is no local master
+ browser, and we are configured to initiate
+ an election that we will participate in.
+ */
+ DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n",
+ work->work_group, subrec->subnet_name ));
+
+ /* Setting this means we will participate when the
+ election is run in run_elections(). */
+ work->needelection = True;
+ }
+ else
+ {
+ /* We need to force an election, because we are configured
+ not to become the local master, but we still need one,
+ having detected that one doesn't exist.
+ */
+ send_election_dgram(subrec, work->work_group, 0, 0, "");
+ }
+ }
}
/*******************************************************************
@@ -127,33 +127,36 @@ static void check_for_master_browser_fail( struct subnet_record *subrec,
void check_master_browser_exists(time_t t)
{
- static time_t lastrun=0;
- struct subnet_record *subrec;
- const char *workgroup_name = lp_workgroup();
-
- if (!lastrun)
- lastrun = t;
-
- if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
- return;
-
- lastrun = t;
-
- dump_workgroups(False);
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next) {
- if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) {
- /* Do a name query for the local master browser on this net. */
- query_name( subrec, work->work_group, 0x1d,
- check_for_master_browser_success,
- check_for_master_browser_fail,
- NULL);
- }
- }
- }
+ static time_t lastrun=0;
+ struct subnet_record *subrec;
+ char *workgroup_name = global_myworkgroup;
+
+ if (!lastrun)
+ lastrun = t;
+
+ if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
+ return;
+
+ lastrun = t;
+
+ dump_workgroups(False);
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work;
+
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work))
+ {
+ /* Do a name query for the local master browser on this net. */
+ query_name( subrec, work->work_group, 0x1d,
+ check_for_master_browser_success,
+ check_for_master_browser_fail,
+ NULL);
+ }
+ }
+ }
}
/*******************************************************************
@@ -162,52 +165,56 @@ void check_master_browser_exists(time_t t)
void run_elections(time_t t)
{
- static time_t lastime = 0;
+ static time_t lastime = 0;
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- /* Send election packets once every 2 seconds - note */
- if (lastime && (t - lastime < 2))
- return;
+ /* Send election packets once every 2 seconds - note */
+ if (lastime && (t - lastime < 2))
+ return;
- lastime = t;
+ lastime = t;
- START_PROFILE(run_elections);
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work;
-
- for (work = subrec->workgrouplist; work; work = work->next) {
- if (work->RunningElection) {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
+ START_PROFILE(run_elections);
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work;
+
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ if (work->RunningElection)
+ {
+ /*
+ * We can only run an election for a workgroup if we have
+ * registered the WORKGROUP<1e> name, as that's the name
+ * we must listen to.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, work->work_group, 0x1e);
+ if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
+ DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
+ continue;
+ }
- send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
- t - StartupTime, global_myname());
+ send_election_dgram(subrec, work->work_group, work->ElectionCriterion,
+ t - StartupTime, global_myname);
- if (work->ElectionCount++ >= 4) {
- /* Won election (4 packets were sent out uncontested. */
- DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
-
- work->RunningElection = False;
-
- become_local_master_browser(subrec, work);
- }
- }
- }
- }
- END_PROFILE(run_elections);
+ if (work->ElectionCount++ >= 4)
+ {
+ /* Won election (4 packets were sent out uncontested. */
+ DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+
+ work->RunningElection = False;
+
+ become_local_master_browser(subrec, work);
+ }
+ }
+ }
+ }
+ END_PROFILE(run_elections);
}
/*******************************************************************
@@ -215,42 +222,44 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
******************************************************************/
static BOOL win_election(struct work_record *work, int version,
- uint32 criterion, int timeup, const char *server_name)
+ uint32 criterion, int timeup, char *server_name)
{
- int mytimeup = time(NULL) - StartupTime;
- uint32 mycriterion = work->ElectionCriterion;
-
- /* If local master is false then never win in election broadcasts. */
- if(!lp_local_master()) {
- DEBUG(3,("win_election: Losing election as local master == False\n"));
- return False;
- }
+ int mytimeup = time(NULL) - StartupTime;
+ uint32 mycriterion = work->ElectionCriterion;
+
+ /* If local master is false then never win
+ in election broadcasts. */
+ if(!lp_local_master())
+ {
+ DEBUG(3,("win_election: Losing election as local master == False\n"));
+ return False;
+ }
- DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
- version, ELECTION_VERSION,
- criterion, mycriterion,
- timeup, mytimeup,
- server_name, global_myname()));
-
- if (version > ELECTION_VERSION)
- return(False);
- if (version < ELECTION_VERSION)
- return(True);
+ DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n",
+ version, ELECTION_VERSION,
+ criterion, mycriterion,
+ timeup, mytimeup,
+ server_name, global_myname));
+
+ if (version > ELECTION_VERSION)
+ return(False);
+ if (version < ELECTION_VERSION)
+ return(True);
- if (criterion > mycriterion)
- return(False);
- if (criterion < mycriterion)
- return(True);
-
- if (timeup > mytimeup)
- return(False);
- if (timeup < mytimeup)
- return(True);
-
- if (StrCaseCmp(global_myname(), server_name) > 0)
- return(False);
+ if (criterion > mycriterion)
+ return(False);
+ if (criterion < mycriterion)
+ return(True);
+
+ if (timeup > mytimeup)
+ return(False);
+ if (timeup < mytimeup)
+ return(True);
+
+ if (strcasecmp(global_myname, server_name) > 0)
+ return(False);
- return(True);
+ return(True);
}
/*******************************************************************
@@ -259,63 +268,66 @@ static BOOL win_election(struct work_record *work, int version,
void process_election(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int version = CVAL(buf,0);
- uint32 criterion = IVAL(buf,1);
- int timeup = IVAL(buf,5)/1000;
- unstring server_name;
- struct work_record *work;
- unstring workgroup_name;
-
- pull_ascii_nstring(server_name, sizeof(server_name), buf+13);
- pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
-
- START_PROFILE(election);
- server_name[15] = 0;
-
- DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
- server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
-
- DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
-
- if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) {
- DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
- workgroup_name, subrec->subnet_name ));
- goto done;
- }
-
- if (!strequal(work->work_group, lp_workgroup())) {
- DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int version = CVAL(buf,0);
+ uint32 criterion = IVAL(buf,1);
+ int timeup = IVAL(buf,5)/1000;
+ char *server_name = buf+13;
+ struct work_record *work;
+ char *workgroup_name = dgram->dest_name.name;
+
+ START_PROFILE(election);
+ server_name[15] = 0;
+
+ DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
+ server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name ));
+
+ DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup));
+
+ if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
+ {
+ DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
+ workgroup_name, subrec->subnet_name ));
+ goto done;
+ }
+
+ if (!strequal(work->work_group, global_myworkgroup))
+ {
+ DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
is not my workgroup.\n", work->work_group, subrec->subnet_name ));
- goto done;
- }
-
- if (win_election(work, version,criterion,timeup,server_name)) {
- /* We take precedence over the requesting server. */
- if (!work->RunningElection) {
- /* We weren't running an election - start running one. */
-
- work->needelection = True;
- work->ElectionCount=0;
- }
-
- /* Note that if we were running an election for this workgroup on this
- subnet already, we just ignore the server we take precedence over. */
- } else {
- /* We lost. Stop participating. */
- work->needelection = False;
-
- if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) {
- work->RunningElection = False;
- DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(subrec, work, False);
- }
- }
+ goto done;
+ }
+
+ if (win_election(work, version,criterion,timeup,server_name))
+ {
+ /* We take precedence over the requesting server. */
+ if (!work->RunningElection)
+ {
+ /* We weren't running an election - start running one. */
+
+ work->needelection = True;
+ work->ElectionCount=0;
+ }
+
+ /* Note that if we were running an election for this workgroup on this
+ subnet already, we just ignore the server we take precedence over. */
+ }
+ else
+ {
+ /* We lost. Stop participating. */
+ work->needelection = False;
+
+ if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work))
+ {
+ work->RunningElection = False;
+ DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+ if (AM_LOCAL_MASTER_BROWSER(work))
+ unbecome_local_master_browser(subrec, work, False);
+ }
+ }
done:
-
- END_PROFILE(election);
+ END_PROFILE(election);
}
/****************************************************************************
@@ -327,53 +339,57 @@ done:
BOOL check_elections(void)
{
- struct subnet_record *subrec;
- BOOL run_any_election = False;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next) {
- run_any_election |= work->RunningElection;
-
- /*
- * Start an election if we have any chance of winning.
- * Note this is a change to the previous code, that would
- * only run an election if nmbd was in the potential browser
- * state. We need to run elections in any state if we're told
- * to. JRA.
- */
-
- if (work->needelection && !work->RunningElection && lp_local_master()) {
- /*
- * We can only run an election for a workgroup if we have
- * registered the WORKGROUP<1e> name, as that's the name
- * we must listen to.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, work->work_group, 0x1e);
- if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
- DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
+ struct subnet_record *subrec;
+ BOOL run_any_election = False;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work;
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ run_any_election |= work->RunningElection;
+
+ /*
+ * Start an election if we have any chance of winning.
+ * Note this is a change to the previous code, that would
+ * only run an election if nmbd was in the potential browser
+ * state. We need to run elections in any state if we're told
+ * to. JRA.
+ */
+
+ if (work->needelection && !work->RunningElection && lp_local_master())
+ {
+ /*
+ * We can only run an election for a workgroup if we have
+ * registered the WORKGROUP<1e> name, as that's the name
+ * we must listen to.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, work->work_group, 0x1e);
+ if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
+ DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
- continue;
- }
+ continue;
+ }
+
+ DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
+ work->work_group, subrec->subnet_name ));
+
+ work->ElectionCount = 0;
+ work->RunningElection = True;
+ work->needelection = False;
+ }
+ }
+ }
+ return run_any_election;
+}
- DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n",
- work->work_group, subrec->subnet_name ));
- work->ElectionCount = 0;
- work->RunningElection = True;
- work->needelection = False;
- }
- }
- }
- return run_any_election;
-}
/****************************************************************************
- Process a internal Samba message forcing an election.
+process a internal Samba message forcing an election
***************************************************************************/
-
void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
{
struct subnet_record *subrec;
@@ -381,7 +397,7 @@ void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
struct work_record *work;
for (work = subrec->workgrouplist; work; work = work->next) {
- if (strequal(work->work_group, lp_workgroup())) {
+ if (strequal(work->work_group, global_myworkgroup)) {
work->needelection = True;
work->ElectionCount=0;
work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c
index 53b19471572..d9d1894534d 100644
--- a/source/nmbd/nmbd_incomingdgrams.c
+++ b/source/nmbd/nmbd_incomingdgrams.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -23,6 +24,8 @@
#include "includes.h"
+extern pstring global_myname;
+extern fstring global_myworkgroup;
extern BOOL found_lm_clients;
#if 0
@@ -95,99 +98,102 @@ void tell_become_backup(void)
void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- unstring announce_name;
- uint32 servertype = IVAL(buf,23);
- fstring comment;
- struct work_record *work;
- struct server_record *servrec;
- unstring work_name;
- unstring source_name;
-
- START_PROFILE(host_announce);
-
- pull_ascii_fstring(comment, buf+31);
- comment[42] = 0;
-
- pull_ascii_nstring(announce_name, sizeof(announce_name), buf+5);
- pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ char *announce_name = buf+5;
+ uint32 servertype = IVAL(buf,23);
+ char *comment = buf+31;
+ struct work_record *work;
+ struct server_record *servrec;
+ char *work_name;
+ char *source_name = dgram->source_name.name;
- DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
+ START_PROFILE(host_announce);
+ comment[43] = 0;
+
+ DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
+ nmb_namestr(&dgram->dest_name),announce_name));
- DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype,comment));
+ DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
+ ttl, servertype,comment));
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
- /* A host announcement must be sent to the name WORKGROUP<1d>. */
- if(dgram->dest_name.name_type != 0x1d) {
- DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
+ /* A host announcement must be sent to the name WORKGROUP<1d>. */
+ if(dgram->dest_name.name_type != 0x1d)
+ {
+ DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1d. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x1d;
- }
-
- /* For a host announce the workgroup name is the destination name. */
- pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name.
- */
-
- if(strequal(work_name, global_myname()))
- unstrcpy(work_name,lp_workgroup());
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
-
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0) {
- if (work ==NULL ) {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ /* Change it so it was. */
+ dgram->dest_name.name_type = 0x1d;
+ }
+
+ /* For a host announce the workgroup name is the destination name. */
+ work_name = dgram->dest_name.name;
+
+ /*
+ * Syntax servers version 5.1 send HostAnnounce packets to
+ * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
+ * instead of WORKGROUP<1d> name. So to fix this we check if
+ * the workgroup name is our own name, and if so change it
+ * to be our primary workgroup name.
+ */
+
+ if(strequal(work_name, global_myname))
+ work_name = global_myworkgroup;
+
+ /*
+ * We are being very agressive here in adding a workgroup
+ * name on the basis of a host announcing itself as being
+ * in that workgroup. Maybe we should wait for the workgroup
+ * announce instead ? JRA.
+ */
+
+ work = find_workgroup_on_subnet(subrec, work_name);
+
+ if(servertype != 0)
+ {
+ if (work ==NULL )
+ {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL) {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- } else {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
- } else {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
+ if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
+ {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, announce_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ }
+ else
+ {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl( servrec, ttl);
+ StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ }
+ }
+ else
+ {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(announce_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
+ )
+ {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+ subrec->work_changed = True;
done:
-
- END_PROFILE(host_announce);
+ END_PROFILE(host_announce);
}
/*******************************************************************
@@ -196,55 +202,53 @@ done:
void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- unstring workgroup_announce_name;
- unstring master_name;
- uint32 servertype = IVAL(buf,23);
- struct work_record *work;
- unstring source_name;
- unstring dest_name;
-
- START_PROFILE(workgroup_announce);
-
- pull_ascii_nstring(workgroup_announce_name,sizeof(workgroup_announce_name),buf+5);
- pull_ascii_nstring(master_name,sizeof(master_name),buf+31);
- pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name);
- pull_ascii_nstring(dest_name,sizeof(dest_name),dgram->dest_name.name);
-
- DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ char *workgroup_announce_name = buf+5;
+ uint32 servertype = IVAL(buf,23);
+ char *master_name = buf+31;
+ struct work_record *work;
+ char *source_name = dgram->source_name.name;
+
+ START_PROFILE(workgroup_announce);
+ master_name[43] = 0;
+
+ DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
%s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),workgroup_announce_name));
-
- DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
- ttl, servertype, master_name));
-
- /* Workgroup announcements must only go to the MSBROWSE name. */
- if (!strequal(dest_name, MSBROWSE) || (dgram->dest_name.name_type != 0x1)) {
- DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- goto done;
- }
-
- if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL) {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
- goto done;
- } else {
- /* Update the workgroup death_time. */
- update_workgroup_ttl(work, ttl);
- }
-
- if(*work->local_master_browser_name == '\0') {
- /* Set the master browser name. */
- set_workgroup_local_master_browser_name( work, master_name );
- }
-
- subrec->work_changed = True;
+ nmb_namestr(&dgram->dest_name),workgroup_announce_name));
-done:
+ DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
+ ttl, servertype, master_name));
+
+ /* Workgroup announcements must only go to the MSBROWSE name. */
+ if (!strequal(dgram->dest_name.name, MSBROWSE) || (dgram->dest_name.name_type != 0x1))
+ {
+ DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ goto done;
+ }
- END_PROFILE(workgroup_announce);
+ if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL)
+ {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
+ goto done;
+ }
+ else
+ {
+ /* Update the workgroup death_time. */
+ update_workgroup_ttl(work, ttl);
+ }
+
+ if(*work->local_master_browser_name == '\0')
+ {
+ /* Set the master browser name. */
+ set_workgroup_local_master_browser_name( work, master_name );
+ }
+
+ subrec->work_changed = True;
+done:
+ END_PROFILE(workgroup_announce);
}
/*******************************************************************
@@ -253,110 +257,117 @@ done:
void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int ttl = IVAL(buf,1)/1000;
- unstring server_name;
- uint32 servertype = IVAL(buf,23);
- fstring comment;
- unstring work_name;
- struct work_record *work;
- struct server_record *servrec;
- unstring source_name;
-
- START_PROFILE(local_master_announce);
-
- pull_ascii_nstring(server_name,sizeof(server_name),buf+5);
- pull_ascii_fstring(comment, buf+31);
- comment[42] = 0;
- pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
- pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);
-
- DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int ttl = IVAL(buf,1)/1000;
+ char *server_name = buf+5;
+ uint32 servertype = IVAL(buf,23);
+ char *comment = buf+31;
+ char *work_name;
+ struct work_record *work;
+ struct server_record *servrec;
+ char *source_name = dgram->source_name.name;
+
+ START_PROFILE(local_master_announce);
+ comment[43] = 0;
+
+ DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),server_name));
+ nmb_namestr(&dgram->dest_name),server_name));
- DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
- ttl, servertype, comment));
+ DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
+ ttl, servertype, comment));
- /* A local master announcement must be sent to the name WORKGROUP<1e>. */
- if(dgram->dest_name.name_type != 0x1e) {
- DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
+ /* A local master announcement must be sent to the name WORKGROUP<1e>. */
+ if(dgram->dest_name.name_type != 0x1e)
+ {
+ DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1e. Ignoring packet.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- goto done;
- }
-
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
-
- /* For a local master announce the workgroup name is the destination name. */
-
- if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL) {
- /* Don't bother adding if it's a local master release announce. */
- if(servertype == 0)
- goto done;
-
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- /* If we think we're the local master browser for this workgroup,
- we should never have got this packet. We don't see our own
- packets.
- */
- if(AM_LOCAL_MASTER_BROWSER(work)) {
- DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ goto done;
+ }
+
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+
+ /* For a local master announce the workgroup name is the destination name. */
+ work_name = dgram->dest_name.name;
+
+ if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL)
+ {
+ /* Don't bother adding if it's a local master release announce. */
+ if(servertype == 0)
+ goto done;
+
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
+
+ /* If we think we're the local master browser for this workgroup,
+ we should never have got this packet. We don't see our own
+ packets.
+ */
+ if(AM_LOCAL_MASTER_BROWSER(work))
+ {
+ DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
a local master browser for workgroup %s and we think we are master. Forcing election.\n",
- server_name, inet_ntoa(p->ip), work_name));
+ server_name, inet_ntoa(p->ip), work_name));
- /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
- they have become a local master browser once, they will never
- stop sending local master announcements. To fix this we send
- them a reset browser packet, with level 0x2 on the __SAMBA__
- name that only they should be listening to. */
+ /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
+ they have become a local master browser once, they will never
+ stop sending local master announcements. To fix this we send
+ them a reset browser packet, with level 0x2 on the __SAMBA__
+ name that only they should be listening to. */
- send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);
-
- /* We should demote ourself and force an election. */
-
- unbecome_local_master_browser( subrec, work, True);
-
- /* The actual election requests are handled in nmbd_election.c */
- goto done;
- }
-
- /* Find the server record on this workgroup. If it doesn't exist, add it. */
-
- if(servertype != 0) {
- if((servrec = find_server_in_workgroup( work, server_name))==NULL) {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, server_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- } else {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl(servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
-
- set_workgroup_local_master_browser_name( work, server_name );
- } else {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(server_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, server_name))!=NULL)) {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
-done:
+ send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);
+
+ /* We should demote ourself and force an election. */
+
+ unbecome_local_master_browser( subrec, work, True);
+
+ /* The actual election requests are handled in
+ nmbd_election.c */
+ goto done;
+ }
+
+ /* Find the server record on this workgroup. If it doesn't exist, add it. */
+
+ if(servertype != 0)
+ {
+ if((servrec = find_server_in_workgroup( work, server_name))==NULL)
+ {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, server_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ }
+ else
+ {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl(servrec, ttl);
+ StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ }
- END_PROFILE(local_master_announce);
+ set_workgroup_local_master_browser_name( work, server_name );
+ }
+ else
+ {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(server_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, server_name))!=NULL)
+ )
+ {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+
+ subrec->work_changed = True;
+done:
+ END_PROFILE(local_master_announce);
}
/*******************************************************************
@@ -369,49 +380,50 @@ done:
void process_master_browser_announce(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- unstring local_master_name;
- struct work_record *work;
- struct browse_cache_record *browrec;
-
- START_PROFILE(master_browser_announce);
+ char *local_master_name = buf;
+ struct work_record *work;
+ struct browse_cache_record *browrec;
- pull_ascii_nstring(local_master_name,sizeof(local_master_name),buf);
+ START_PROFILE(master_browser_announce);
+ local_master_name[15] = 0;
- DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
- local_master_name, inet_ntoa(p->ip)));
+ DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
+ local_master_name, inet_ntoa(p->ip)));
- if (!lp_domain_master()) {
- DEBUG(0,("process_master_browser_announce: Not configured as domain \
+ if (!lp_domain_master())
+ {
+ DEBUG(0,("process_master_browser_announce: Not configured as domain \
master - ignoring master announce.\n"));
- goto done;
- }
+ goto done;
+ }
- if((work = find_workgroup_on_subnet(subrec, lp_workgroup())) == NULL) {
- DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), subrec->subnet_name));
- goto done;
- }
-
- if(!AM_DOMAIN_MASTER_BROWSER(work)) {
- DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
-%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip)));
- goto done;
- }
+ if((work = find_workgroup_on_subnet(subrec, global_myworkgroup)) == NULL)
+ {
+ DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
+ global_myworkgroup, subrec->subnet_name));
+ goto done;
+ }
- /* Add this host as a local master browser entry on the browse lists.
- This causes a sync request to be made to it at a later date.
- */
+ if(!AM_DOMAIN_MASTER_BROWSER(work))
+ {
+ DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
+%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip)));
+ goto done;
+ }
- if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL) {
- /* Add it. */
- create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip);
- } else {
- update_browser_death_time(browrec);
- }
+ /* Add this host as a local master browser entry on the browse lists.
+ This causes a sync request to be made to it at a later date.
+ */
+ if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL)
+ {
+ /* Add it. */
+ create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip);
+ }
+ else
+ update_browser_death_time(browrec);
done:
-
- END_PROFILE(master_browser_announce);
+ END_PROFILE(master_browser_announce);
}
/*******************************************************************
@@ -420,117 +432,123 @@ done:
void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- uint32 servertype = IVAL(buf,1);
- int osmajor=CVAL(buf,5); /* major version of node software */
- int osminor=CVAL(buf,6); /* minor version of node software */
- int ttl = SVAL(buf,7);
- unstring announce_name;
- struct work_record *work;
- struct server_record *servrec;
- unstring work_name;
- unstring source_name;
- fstring comment;
- char *s = buf+9;
-
- START_PROFILE(lm_host_announce);
- s = skip_string(s,1);
- pull_ascii(comment, s, sizeof(fstring), 43, STR_TERMINATE);
-
- pull_ascii_nstring(announce_name,sizeof(announce_name),buf+9);
- pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name);
- /* For a LanMan host announce the workgroup name is the destination name. */
- pull_ascii_nstring(work_name,sizeof(work_name),dgram->dest_name.name);
-
- DEBUG(3,("process_lm_host_announce: LM Announcement from %s IP %s to \
-%s for server %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name),announce_name));
-
- DEBUG(5,("process_lm_host_announce: os=(%d,%d) ttl=%d server type=%08x comment=%s\n",
- osmajor, osminor, ttl, servertype,comment));
-
- if ((osmajor < 36) || (osmajor > 38) || (osminor !=0)) {
- DEBUG(5,("process_lm_host_announce: LM Announcement packet does not \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ uint32 servertype = IVAL(buf,1);
+ int osmajor=CVAL(buf,5); /* major version of node software */
+ int osminor=CVAL(buf,6); /* minor version of node software */
+ int ttl = SVAL(buf,7);
+ char *announce_name = buf+9;
+ struct work_record *work;
+ struct server_record *servrec;
+ char *work_name;
+ char *source_name = dgram->source_name.name;
+ pstring comment;
+ char *s = buf+9;
+
+ START_PROFILE(lm_host_announce);
+ s = skip_string(s,1);
+ StrnCpy(comment, s, 43);
+
+ DEBUG(3,("process_lm_host_announce: LM Announcement from %s<%02x> IP %s to \
+%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name),announce_name));
+
+ DEBUG(5,("process_lm_host_announce: os=(%d,%d) ttl=%d server type=%08x comment=%s\n",
+ osmajor, osminor, ttl, servertype,comment));
+
+ if ((osmajor < 36) || (osmajor > 38) || (osminor !=0))
+ {
+ DEBUG(5,("process_lm_host_announce: LM Announcement packet does not \
originate from OS/2 Warp client. Ignoring packet.\n"));
- /* Could have been from a Windows machine (with its LM Announce enabled),
- or a Samba server. Then don't disrupt the current browse list. */
- goto done;
- }
+ /* Could have been from a Windows machine (with its LM Announce enabled),
+ or a Samba server. Then don't disrupt the current browse list. */
+ goto done;
+ }
- /* Filter servertype to remove impossible bits. */
- servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
+ /* Filter servertype to remove impossible bits. */
+ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);
- /* A LanMan host announcement must be sent to the name WORKGROUP<00>. */
- if(dgram->dest_name.name_type != 0x00) {
- DEBUG(2,("process_lm_host_announce: incorrect name type for destination from IP %s \
+ /* A LanMan host announcement must be sent to the name WORKGROUP<00>. */
+ if(dgram->dest_name.name_type != 0x00)
+ {
+ DEBUG(2,("process_lm_host_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x00. Allowing packet anyway.\n",
- inet_ntoa(p->ip), dgram->dest_name.name_type));
- /* Change it so it was. */
- dgram->dest_name.name_type = 0x00;
- }
-
- /*
- * Syntax servers version 5.1 send HostAnnounce packets to
- * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
- * instead of WORKGROUP<1d> name. So to fix this we check if
- * the workgroup name is our own name, and if so change it
- * to be our primary workgroup name. This code is probably
- * not needed in the LanMan announce code, but it won't hurt.
- */
-
- if(strequal(work_name, global_myname()))
- unstrcpy(work_name,lp_workgroup());
-
- /*
- * We are being very agressive here in adding a workgroup
- * name on the basis of a host announcing itself as being
- * in that workgroup. Maybe we should wait for the workgroup
- * announce instead ? JRA.
- */
-
- work = find_workgroup_on_subnet(subrec, work_name);
-
- if(servertype != 0) {
- if (work == NULL) {
- /* We have no record of this workgroup. Add it. */
- if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- goto done;
- }
-
- if((servrec = find_server_in_workgroup( work, announce_name))==NULL) {
- /* If this server is not already in the workgroup, add it. */
- create_server_on_workgroup(work, announce_name,
- servertype|SV_TYPE_LOCAL_LIST_ONLY,
- ttl, comment);
- } else {
- /* Update the record. */
- servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
- update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
- }
- } else {
- /*
- * This server is announcing it is going down. Remove it from the
- * workgroup.
- */
- if(!is_myname(announce_name) && (work != NULL) &&
- ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) {
- remove_server_from_workgroup( work, servrec);
- }
- }
-
- subrec->work_changed = True;
- found_lm_clients = True;
+ inet_ntoa(p->ip), dgram->dest_name.name_type));
+ /* Change it so it was. */
+ dgram->dest_name.name_type = 0x00;
+ }
-done:
+ /* For a LanMan host announce the workgroup name is the destination name. */
+ work_name = dgram->dest_name.name;
+
+ /*
+ * Syntax servers version 5.1 send HostAnnounce packets to
+ * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
+ * instead of WORKGROUP<1d> name. So to fix this we check if
+ * the workgroup name is our own name, and if so change it
+ * to be our primary workgroup name. This code is probably
+ * not needed in the LanMan announce code, but it won't hurt.
+ */
+
+ if(strequal(work_name, global_myname))
+ work_name = global_myworkgroup;
+
+ /*
+ * We are being very agressive here in adding a workgroup
+ * name on the basis of a host announcing itself as being
+ * in that workgroup. Maybe we should wait for the workgroup
+ * announce instead ? JRA.
+ */
+
+ work = find_workgroup_on_subnet(subrec, work_name);
- END_PROFILE(lm_host_announce);
+ if(servertype != 0)
+ {
+ if (work == NULL)
+ {
+ /* We have no record of this workgroup. Add it. */
+ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
+ goto done;
+ }
+
+ if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
+ {
+ /* If this server is not already in the workgroup, add it. */
+ create_server_on_workgroup(work, announce_name,
+ servertype|SV_TYPE_LOCAL_LIST_ONLY,
+ ttl, comment);
+ }
+ else
+ {
+ /* Update the record. */
+ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
+ update_server_ttl( servrec, ttl);
+ StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ }
+ }
+ else
+ {
+ /*
+ * This server is announcing it is going down. Remove it from the
+ * workgroup.
+ */
+ if(!is_myname(announce_name) && (work != NULL) &&
+ ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)
+ )
+ {
+ remove_server_from_workgroup( work, servrec);
+ }
+ }
+
+ subrec->work_changed = True;
+ found_lm_clients = True;
+done:
+ END_PROFILE(lm_host_announce);
}
/****************************************************************************
Send a backup list response.
*****************************************************************************/
-
static void send_backup_list_response(struct subnet_record *subrec,
struct work_record *work,
struct nmb_name *send_to_name,
@@ -538,41 +556,36 @@ static void send_backup_list_response(struct subnet_record *subrec,
uint32 token, struct in_addr sendto_ip,
int port)
{
- char outbuf[1024];
- char *p, *countptr;
- unsigned int count = 0;
- unstring send_to_namestr;
+ char outbuf[1024];
+ char *p, *countptr;
+ unsigned int count = 0;
#if 0
struct server_record *servrec;
#endif
- unstring myname;
- memset(outbuf,'\0',sizeof(outbuf));
+ memset(outbuf,'\0',sizeof(outbuf));
- DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
- work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
+ DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
+ work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
- p = outbuf;
+ p = outbuf;
- SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
- p++;
+ SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
+ p++;
- countptr = p;
- p++;
+ countptr = p;
+ p++;
- SIVAL(p,0,token); /* The sender's unique info. */
- p += 4;
+ SIVAL(p,0,token); /* The sender's unique info. */
+ p += 4;
- /* We always return at least one name - our own. */
- count = 1;
- unstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
+ /* We always return at least one name - our own. */
+ count = 1;
+ StrnCpy(p,global_myname,15);
+ strupper(p);
+ p = skip_string(p,1);
- p = skip_string(p,1);
-
- /* Look for backup browsers in this workgroup. */
+ /* Look for backup browsers in this workgroup. */
#if 0
/* we don't currently send become_backup requests so we should never
@@ -593,14 +606,14 @@ static void send_backup_list_response(struct subnet_record *subrec,
if(count >= (unsigned int)max_number_requested)
break;
- if(strnequal(servrec->serv.name, global_myname(),15))
+ if(strnequal(servrec->serv.name, global_myname,15))
continue;
if(!(servrec->serv.type & SV_TYPE_BACKUP_BROWSER))
continue;
StrnCpy(p, servrec->serv.name, 15);
- strupper_m(p);
+ strupper(p);
count++;
DEBUG(5,("send_backup_list_response: Adding server %s number %d\n",
@@ -610,18 +623,16 @@ static void send_backup_list_response(struct subnet_record *subrec,
}
#endif
- SCVAL(countptr, 0, count);
-
- pull_ascii_nstring(send_to_namestr, sizeof(send_to_namestr), send_to_name->name);
+ SCVAL(countptr, 0, count);
- DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
- send_to_namestr, inet_ntoa(sendto_ip), count));
+ DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
+ send_to_name->name, inet_ntoa(sendto_ip), count));
- send_mailslot(True, BROWSE_MAILSLOT,
- outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0,
- send_to_namestr,0,
- sendto_ip, subrec->myip, port);
+ send_mailslot(True, BROWSE_MAILSLOT,
+ outbuf,PTR_DIFF(p,outbuf),
+ global_myname, 0,
+ send_to_name->name,0,
+ sendto_ip, subrec->myip, port);
}
/*******************************************************************
@@ -637,74 +648,80 @@ static void send_backup_list_response(struct subnet_record *subrec,
void process_get_backup_list_request(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- unsigned char max_number_requested = CVAL(buf,0);
- uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
- int name_type = dgram->dest_name.name_type;
- unstring workgroup_name;
- struct subnet_record *search_subrec = subrec;
-
- START_PROFILE(get_backup_list);
- pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
-
- DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct work_record *work;
+ unsigned char max_number_requested = CVAL(buf,0);
+ uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
+ int name_type = dgram->dest_name.name_type;
+ char *workgroup_name = dgram->dest_name.name;
+ struct subnet_record *search_subrec = subrec;
+
+ START_PROFILE(get_backup_list);
+ DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
- /* We have to be a master browser, or a domain master browser
- for the requested workgroup. That means it must be our
- workgroup. */
-
- if(strequal(workgroup_name, lp_workgroup()) == False) {
- DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL) {
- DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
+ /* We have to be a master browser, or a domain master browser
+ for the requested workgroup. That means it must be our
+ workgroup. */
+
+ if(strequal(workgroup_name, global_myworkgroup) == False)
+ {
+ DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
+
+ if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
+ {
+ DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
subnet %s.\n", workgroup_name, search_subrec->subnet_name));
- goto done;
- }
+ goto done;
+ }
- /*
- * If the packet was sent to WORKGROUP<1b> instead
- * of WORKGROUP<1d> then it was unicast to us a domain master
- * browser. Change search subrec to unicast.
- */
+ /*
+ * If the packet was sent to WORKGROUP<1b> instead
+ * of WORKGROUP<1d> then it was unicast to us a domain master
+ * browser. Change search subrec to unicast.
+ */
- if(name_type == 0x1b) {
- /* We must be a domain master browser in order to
- process this packet. */
+ if(name_type == 0x1b)
+ {
+ /* We must be a domain master browser in order to
+ process this packet. */
- if(!AM_DOMAIN_MASTER_BROWSER(work)) {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
+ if(!AM_DOMAIN_MASTER_BROWSER(work))
+ {
+ DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a domain master browser.\n", workgroup_name));
- goto done;
- }
+ goto done;
+ }
- search_subrec = unicast_subnet;
- } else if (name_type == 0x1d) {
- /* We must be a local master browser in order to process this packet. */
+ search_subrec = unicast_subnet;
+ }
+ else if (name_type == 0x1d)
+ {
+ /* We must be a local master browser in order to
+ process this packet. */
- if(!AM_LOCAL_MASTER_BROWSER(work)) {
- DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
+ if(!AM_LOCAL_MASTER_BROWSER(work))
+ {
+ DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a local master browser.\n", workgroup_name));
- goto done;
- }
- } else {
- DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
- name_type));
- goto done;
- }
-
- send_backup_list_response(subrec, work, &dgram->source_name,
- max_number_requested, token, p->ip, p->port);
+ goto done;
+ }
+ }
+ else
+ {
+ DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
+ name_type));
+ goto done;
+ }
+ send_backup_list_response(subrec, work, &dgram->source_name,
+ max_number_requested, token, p->ip, p->port);
done:
-
- END_PROFILE(get_backup_list);
+ END_PROFILE(get_backup_list);
}
/*******************************************************************
@@ -720,46 +737,48 @@ done:
void process_reset_browser(struct subnet_record *subrec,
struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int state = CVAL(buf,0);
- struct subnet_record *sr;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int state = CVAL(buf,0);
+ struct subnet_record *sr;
- START_PROFILE(reset_browser);
-
- DEBUG(1,("process_reset_browser: received diagnostic browser reset \
+ START_PROFILE(reset_browser);
+ DEBUG(1,("process_reset_browser: received diagnostic browser reset \
request from %s IP %s state=0x%X\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
-
- /* Stop being a local master browser on all our broadcast subnets. */
- if (state & 0x1) {
- for (sr = FIRST_SUBNET; sr; sr = NEXT_SUBNET_EXCLUDING_UNICAST(sr)) {
- struct work_record *work;
- for (work = sr->workgrouplist; work; work = work->next) {
- if (AM_LOCAL_MASTER_BROWSER(work))
- unbecome_local_master_browser(sr, work, True);
- }
- }
- }
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
+
+ /* Stop being a local master browser on all our broadcast subnets. */
+ if (state & 0x1)
+ {
+ for (sr = FIRST_SUBNET; sr; sr = NEXT_SUBNET_EXCLUDING_UNICAST(sr))
+ {
+ struct work_record *work;
+ for (work = sr->workgrouplist; work; work = work->next)
+ {
+ if (AM_LOCAL_MASTER_BROWSER(work))
+ unbecome_local_master_browser(sr, work, True);
+ }
+ }
+ }
- /* Discard our browse lists. */
- if (state & 0x2) {
- /*
- * Calling expire_workgroups_and_servers with a -1
- * time causes all servers not marked with a PERMANENT_TTL
- * on the workgroup lists to be discarded, and all
- * workgroups with empty server lists to be discarded.
- * This means we keep our own server names and workgroup
- * as these have a PERMANENT_TTL.
- */
-
- expire_workgroups_and_servers(-1);
- }
+ /* Discard our browse lists. */
+ if (state & 0x2)
+ {
+ /*
+ * Calling expire_workgroups_and_servers with a -1
+ * time causes all servers not marked with a PERMANENT_TTL
+ * on the workgroup lists to be discarded, and all
+ * workgroups with empty server lists to be discarded.
+ * This means we keep our own server names and workgroup
+ * as these have a PERMANENT_TTL.
+ */
+
+ expire_workgroups_and_servers(-1);
+ }
- /* Request to stop browsing altogether. */
- if (state & 0x4)
- DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
-
- END_PROFILE(reset_browser);
+ /* Request to stop browsing altogether. */
+ if (state & 0x4)
+ DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
+ END_PROFILE(reset_browser);
}
/*******************************************************************
@@ -772,34 +791,33 @@ request from %s IP %s state=0x%X\n",
void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- unstring workgroup_name;
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct work_record *work;
+ char *workgroup_name = dgram->dest_name.name;
- START_PROFILE(announce_request);
-
- pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
- DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
+ START_PROFILE(announce_request);
+ DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False) {
- DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
-
- if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
-
- work->needannounce = True;
-done:
+ /* We only send announcement requests on our workgroup. */
+ if(strequal(workgroup_name, global_myworkgroup) == False)
+ {
+ DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
- END_PROFILE(lm_host_announce);
+ if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
+ {
+ DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
+ workgroup_name));
+ goto done;
+ }
+
+ work->needannounce = True;
+done:
+ END_PROFILE(lm_host_announce);
}
/*******************************************************************
@@ -813,32 +831,30 @@ done:
void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- unstring workgroup_name;
-
- START_PROFILE(lm_announce_request);
-
- pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
- DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
- nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
- nmb_namestr(&dgram->dest_name)));
+ struct dgram_packet *dgram = &p->packet.dgram;
+ char *workgroup_name = dgram->dest_name.name;
- /* We only send announcement requests on our workgroup. */
- if(strequal(workgroup_name, lp_workgroup()) == False) {
- DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
- workgroup_name));
- goto done;
- }
+ START_PROFILE(lm_announce_request);
+ DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
+ nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
+ nmb_namestr(&dgram->dest_name)));
- if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL) {
- DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
- workgroup_name));
- goto done;
- }
+ /* We only send announcement requests on our workgroup. */
+ if(strequal(workgroup_name, global_myworkgroup) == False)
+ {
+ DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
+ workgroup_name));
+ goto done;
+ }
- found_lm_clients = True;
+ if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL)
+ {
+ DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
+ workgroup_name));
+ goto done;
+ }
+ found_lm_clients = True;
done:
-
- END_PROFILE(lm_host_announce);
+ END_PROFILE(lm_host_announce);
}
diff --git a/source/nmbd/nmbd_incomingrequests.c b/source/nmbd/nmbd_incomingrequests.c
index 9214594096c..dbbb7315787 100644
--- a/source/nmbd/nmbd_incomingrequests.c
+++ b/source/nmbd/nmbd_incomingrequests.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,24 +28,26 @@
#include "includes.h"
+extern fstring global_myworkgroup;
+
/****************************************************************************
Send a name release response.
**************************************************************************/
static void send_name_release_response(int rcode, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REL, /* nmbd type code. */
+ NMB_NAME_RELEASE_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/****************************************************************************
@@ -55,74 +58,79 @@ Ignore it if it's not one of our names.
void process_name_release_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr owner_ip;
- struct nmb_name *question = &nmb->question.question_name;
- unstring qname;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec;
- int rcode = 0;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct in_addr owner_ip;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec;
+ int rcode = 0;
- putip((char *)&owner_ip,&nmb->additional->rdata[2]);
+ START_PROFILE(name_release);
+ putip((char *)&owner_ip,&nmb->additional->rdata[2]);
- if(!bcast) {
- /* We should only get broadcast name release packets here.
- Anyone trying to release unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_release_request: unicast name release request \
+ if(!bcast)
+ {
+ /* We should only get broadcast name release packets here.
+ Anyone trying to release unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_release_request: unicast name release request \
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
+ nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
- send_name_release_response(FMT_ERR, p);
- return;
- }
+ send_name_release_response(FMT_ERR, p);
+ goto done;
+ }
- DEBUG(3,("process_name_release_request: Name release on name %s, \
+ DEBUG(3,("process_name_release_request: Name release on name %s, \
subnet %s from owner IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- subrec->subnet_name, inet_ntoa(owner_ip)));
+ nmb_namestr(&nmb->question.question_name),
+ subrec->subnet_name, inet_ntoa(owner_ip)));
- /* If someone is releasing a broadcast group name, just ignore it. */
- if( group && !ismyip(owner_ip) )
- return;
-
- /*
- * Code to work around a bug in FTP OnNet software NBT implementation.
- * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
- * names and *don't set the group bit* !!!!!
- */
-
- pull_ascii_nstring(qname, sizeof(qname), question->name);
- if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) &&
- ((question->name_type == 0x0) || (question->name_type == 0x1e))) {
- DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
+ /* If someone is releasing a broadcast group name, just ignore it. */
+ if( group && !ismyip(owner_ip) )
+ goto done;
+
+ /*
+ * Code to work around a bug in FTP OnNet software NBT implementation.
+ * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
+ * names and *don't set the group bit* !!!!!
+ */
+
+ if( !group && !ismyip(owner_ip) && strequal(question->name, global_myworkgroup) &&
+ ((question->name_type == 0x0) || (question->name_type == 0x1e)))
+ {
+ DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
group release name %s from IP %s on subnet %s with no group bit set.\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
- return;
- }
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /* We only care about someone trying to release one of our names. */
- if( namerec && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) ) {
- rcode = ACT_ERR;
- DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
+ nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
+ goto done;
+ }
+
+ namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
+
+ /* We only care about someone trying to release one of our names. */
+ if( namerec
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME) ) )
+ {
+ rcode = ACT_ERR;
+ DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
on subnet %s being rejected as it is one of our names.\n",
- nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
- }
+ nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
+ }
- if(rcode == 0)
- return;
+ if(rcode == 0)
+ goto done;
- /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
- send_name_release_response(rcode, p);
+ /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
+ send_name_release_response(rcode, p);
+done:
+ END_PROFILE(name_release);
}
/****************************************************************************
@@ -131,18 +139,18 @@ Send a name registration response.
static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REG, /* nmbd type code. */
+ NMB_NAME_REG_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/****************************************************************************
@@ -152,34 +160,41 @@ Process a name refresh request on a broadcast subnet.
void process_name_refresh_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct in_addr from_ip;
+
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ struct in_addr from_ip;
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(!bcast) {
- /* We should only get broadcast name refresh packets here.
- Anyone trying to refresh unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_refresh_request: unicast name registration request \
+ START_PROFILE(name_refresh);
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(!bcast)
+ {
+ /* We should only get broadcast name refresh packets here.
+ Anyone trying to refresh unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_refresh_request: unicast name registration request \
received for name %s from IP %s on subnet %s.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- DEBUG(0,("Error - should be sent to WINS server\n"));
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ DEBUG(0,("Error - should be sent to WINS server\n"));
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
+ send_name_registration_response(FMT_ERR, 0, p);
+ goto done;
+ }
- /* Just log a message. We really don't care about broadcast name refreshes. */
+ /* Just log a message. We really don't care about broadcast name
+ refreshes. */
- DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
+ DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+
+done:
+ END_PROFILE(name_refresh);
}
/****************************************************************************
@@ -189,83 +204,95 @@ Process a name registration request on a broadcast subnet.
void process_name_registration_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = nmb->additional->ttl;
- struct in_addr from_ip;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec = NULL;
+ int ttl = nmb->additional->ttl;
+ struct in_addr from_ip;
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
+ START_PROFILE(name_registration);
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
- if(!bcast) {
- /* We should only get broadcast name registration packets here.
- Anyone trying to register unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_registration_request: unicast name registration request \
+ if(!bcast)
+ {
+ /* We should only get broadcast name registration packets here.
+ Anyone trying to register unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_registration_request: unicast name registration request \
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
+ send_name_registration_response(FMT_ERR, 0, p);
+ goto done;
+ }
- DEBUG(3,("process_name_registration_request: Name registration for name %s \
+ DEBUG(3,("process_name_registration_request: Name registration for name %s \
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- /* See if the name already exists. */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+ /* See if the name already exists. */
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
- /*
- * If the name being registered exists and is a WINS_PROXY_NAME
- * then delete the WINS proxy name entry so we don't reply erroneously
- * later to queries.
- */
-
- if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME)) {
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- if (!group) {
- /* Unique name. */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME)
- || NAME_GROUP(namerec) ) ) {
- /* No-one can register one of Samba's names, nor can they
- register a name that's a group name as a unique name */
-
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- } else if(namerec != NULL) {
- /* Update the namelist record with the new information. */
- namerec->data.ip[0] = from_ip;
- update_name_ttl(namerec, ttl);
-
- DEBUG(3,("process_name_registration_request: Updated name record %s \
+ /*
+ * If the name being registered exists and is a WINS_PROXY_NAME
+ * then delete the WINS proxy name entry so we don't reply erroneously
+ * later to queries.
+ */
+
+ if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
+ {
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ }
+
+ if (!group)
+ {
+ /* Unique name. */
+
+ if( (namerec != NULL)
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME)
+ || NAME_GROUP(namerec) ) )
+ {
+ /* No-one can register one of Samba's names, nor can they
+ register a name that's a group name as a unique name */
+
+ send_name_registration_response(ACT_ERR, 0, p);
+ goto done;
+ }
+ else if(namerec != NULL)
+ {
+ /* Update the namelist record with the new information. */
+ namerec->data.ip[0] = from_ip;
+ update_name_ttl(namerec, ttl);
+
+ DEBUG(3,("process_name_registration_request: Updated name record %s \
with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
- } else {
- /* Group name. */
-
- if( (namerec != NULL)
- && !NAME_GROUP(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) ) {
- /* Disallow group names when we have a unique name. */
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- }
- }
+ goto done;
+ }
+ }
+ else
+ {
+ /* Group name. */
+
+ if( (namerec != NULL)
+ && !NAME_GROUP(namerec)
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME) ) )
+ {
+ /* Disallow group names when we have a unique name. */
+ send_name_registration_response(ACT_ERR, 0, p);
+ goto done;
+ }
+ }
+done:
+ END_PROFILE(name_registration);
}
/****************************************************************************
@@ -275,153 +302,151 @@ We put our own names first, then in alphabetical order.
static int status_compare(char *n1,char *n2)
{
- unstring name1, name2;
- int l1,l2,l3;
-
- memset(name1, '\0', sizeof(name1));
- memset(name2, '\0', sizeof(name2));
- pull_ascii_nstring(name1, sizeof(name1), n1);
- pull_ascii_nstring(name2, sizeof(name2), n2);
- n1 = name1;
- n2 = name2;
-
- /* It's a bit tricky because the names are space padded */
- for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++)
- ;
- for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++)
- ;
- l3 = strlen(global_myname());
-
- if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 &&
- (l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
- return -1;
-
- if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 &&
- (l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
- return 1;
-
- return memcmp(n1,n2,sizeof(name1));
+ extern pstring global_myname;
+ int l1,l2,l3;
+
+ /* It's a bit tricky because the names are space padded */
+ for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
+ for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
+ l3 = strlen(global_myname);
+
+ if ((l1==l3) && strncmp(n1,global_myname,l3) == 0 &&
+ (l2!=l3 || strncmp(n2,global_myname,l3) != 0))
+ return -1;
+
+ if ((l2==l3) && strncmp(n2,global_myname,l3) == 0 &&
+ (l1!=l3 || strncmp(n1,global_myname,l3) != 0))
+ return 1;
+
+ return memcmp(n1,n2,18);
}
+
/****************************************************************************
Process a node status query
****************************************************************************/
void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- unstring qname;
- int ques_type = nmb->question.question_name.name_type;
- char rdata[MAX_DGRAM_SIZE];
- char *countptr, *buf, *bufend, *buf0;
- int names_added,i;
- struct name_record *namerec;
-
- pull_ascii_nstring(qname, sizeof(qname), nmb->question.question_name.name);
-
- DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
-subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name));
-
- if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_SELF_NAME)) == 0) {
- DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char *qname = nmb->question.question_name.name;
+ int ques_type = nmb->question.question_name.name_type;
+ char rdata[MAX_DGRAM_SIZE];
+ char *countptr, *buf, *bufend, *buf0;
+ int names_added,i;
+ struct name_record *namerec;
+
+ START_PROFILE(node_status);
+ DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
+subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
+ subrec->subnet_name));
+
+ if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
+ FIND_SELF_NAME)) == 0)
+ {
+ DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
- inet_ntoa(p->ip), subrec->subnet_name));
+ inet_ntoa(p->ip), subrec->subnet_name));
- return;
- }
+ goto done;
+ }
- /* this is not an exact calculation. the 46 is for the stats buffer
- and the 60 is to leave room for the header etc */
- bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
- countptr = buf = rdata;
- buf += 1;
- buf0 = buf;
-
- names_added = 0;
-
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
-
- while (buf < bufend) {
- if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) {
- int name_type = namerec->name.name_type;
- unstring name;
-
- pull_ascii_nstring(name, sizeof(name), namerec->name.name);
- strupper_m(name);
- if (!strequal(name,"*") &&
- !strequal(name,"__SAMBA__") &&
- (name_type < 0x1b || name_type >= 0x20 ||
- ques_type < 0x1b || ques_type >= 0x20 ||
- strequal(qname, name))) {
- /* Start with the name. */
- size_t len;
- push_ascii_nstring(buf, name);
- len = strlen(buf);
- memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - len - 1);
- buf[MAX_NETBIOSNAME_LEN - 1] = '\0';
-
- /* Put the name type and netbios flags in the buffer. */
-
- buf[15] = name_type;
- set_nb_flags( &buf[16],namerec->data.nb_flags );
- buf[16] |= NB_ACTIVE; /* all our names are active */
-
- buf += 18;
-
- names_added++;
- }
- }
-
- /* Remove duplicate names. */
- if (names_added > 1) {
- qsort( buf0, names_added, 18, QSORT_CAST status_compare );
- }
-
- for( i=1; i < names_added ; i++ ) {
- if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) {
- names_added--;
- if (names_added == i)
- break;
- memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
- i--;
- }
- }
-
- buf = buf0 + 18*names_added;
-
- namerec = (struct name_record *)ubi_trNext( namerec );
-
- if (!namerec) {
- /* End of the subnet specific name list. Now
- add the names on the unicast subnet . */
- struct subnet_record *uni_subrec = unicast_subnet;
-
- if (uni_subrec != subrec) {
- subrec = uni_subrec;
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- }
- }
- if (!namerec)
- break;
-
- }
+ /* this is not an exact calculation. the 46 is for the stats buffer
+ and the 60 is to leave room for the header etc */
+ bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
+ countptr = buf = rdata;
+ buf += 1;
+ buf0 = buf;
+
+ names_added = 0;
+
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+
+ while (buf < bufend)
+ {
+ if( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME) )
+ {
+ int name_type = namerec->name.name_type;
+
+ if (!strequal(namerec->name.name,"*") &&
+ !strequal(namerec->name.name,"__SAMBA__") &&
+ (name_type < 0x1b || name_type >= 0x20 ||
+ ques_type < 0x1b || ques_type >= 0x20 ||
+ strequal(qname, namerec->name.name)))
+ {
+ /* Start with the name. */
+ memset(buf,'\0',18);
+ slprintf(buf, 17, "%-15.15s",namerec->name.name);
+ strupper(buf);
+
+ /* Put the name type and netbios flags in the buffer. */
+ buf[15] = name_type;
+ set_nb_flags( &buf[16],namerec->data.nb_flags );
+ buf[16] |= NB_ACTIVE; /* all our names are active */
+
+ buf += 18;
+
+ names_added++;
+ }
+ }
+
+ /* Remove duplicate names. */
+ if (names_added > 1) {
+ qsort( buf0, names_added, 18, QSORT_CAST status_compare );
+ }
+
+ for( i=1; i < names_added ; i++ )
+ {
+ if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
+ {
+ names_added--;
+ if (names_added == i)
+ break;
+ memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
+ i--;
+ }
+ }
+
+ buf = buf0 + 18*names_added;
+
+ namerec = (struct name_record *)ubi_trNext( namerec );
+
+ if (!namerec)
+ {
+ /* End of the subnet specific name list. Now
+ add the names on the unicast subnet . */
+ struct subnet_record *uni_subrec = unicast_subnet;
+
+ if (uni_subrec != subrec)
+ {
+ subrec = uni_subrec;
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ }
+ }
+ if (!namerec)
+ break;
+
+ }
- SCVAL(countptr,0,names_added);
+ SCVAL(countptr,0,names_added);
- /* We don't send any stats as they could be used to attack
- the protocol. */
- memset(buf,'\0',46);
+ /* We don't send any stats as they could be used to attack
+ the protocol. */
+ memset(buf,'\0',46);
- buf += 46;
+ buf += 46;
- /* Send a NODE STATUS RESPONSE */
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_STATUS, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- PTR_DIFF(buf,rdata)); /* data length. */
+ /* Send a NODE STATUS RESPONSE */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_STATUS, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ PTR_DIFF(buf,rdata)); /* data length. */
+done:
+ END_PROFILE(node_status);
}
@@ -437,151 +462,178 @@ For broadcast name queries:
void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- int name_type = question->name_type;
- BOOL bcast = nmb->header.nm_flags.bcast;
- int ttl=0;
- int rcode = 0;
- char *prdata = NULL;
- char rdata[6];
- BOOL success = False;
- struct name_record *namerec = NULL;
- int reply_data_len = 0;
- int i;
-
- DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
- inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ int name_type = question->name_type;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ int ttl=0;
+ int rcode = 0;
+ char *prdata = NULL;
+ char rdata[6];
+ BOOL success = False;
+ struct name_record *namerec = NULL;
+ int reply_data_len = 0;
+ int i;
+
+ START_PROFILE(name_query);
+ DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
+ inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
- /* Look up the name in the cache - if the request is a broadcast request that
- came from a subnet we don't know about then search all the broadcast subnets
- for a match (as we don't know what interface the request came in on). */
-
- if(subrec == remote_broadcast_subnet)
- namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
- else
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /* Check if it is a name that expired */
- if (namerec &&
- ((namerec->data.death_time != PERMANENT_TTL) &&
- (namerec->data.death_time < p->timestamp))) {
- DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
- namerec = NULL;
- }
-
- if (namerec) {
- /*
- * Always respond to unicast queries.
- * Don't respond to broadcast queries unless the query is for
- * a name we own, a Primary Domain Controller name, or a WINS_PROXY
- * name with type 0 or 0x20. WINS_PROXY names are only ever added
- * into the namelist if we were configured as a WINS proxy.
- */
-
- if (!bcast ||
- (bcast && ((name_type == 0x1b) ||
- (namerec->data.source == SELF_NAME) ||
- (namerec->data.source == PERMANENT_NAME) ||
- ((namerec->data.source == WINS_PROXY_NAME) &&
- ((name_type == 0) || (name_type == 0x20)))))) {
- /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
- or it's a Domain Master type. */
-
- /*
- * If this is a WINS_PROXY_NAME, then ceck that none of the IP
- * addresses we are returning is on the same broadcast subnet
- * as the requesting packet. If it is then don't reply as the
- * actual machine will be replying also and we don't want two
- * replies to a broadcast query.
- */
-
- if (namerec->data.source == WINS_PROXY_NAME) {
- for( i = 0; i < namerec->data.num_ips; i++) {
- if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
- DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n",
- nmb_namestr(&namerec->name), subrec->subnet_name ));
- return;
- }
- }
- }
-
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_ttl();
-
- /* Copy all known ip addresses into the return data. */
- /* Optimise for the common case of one IP address so
- we don't need a malloc. */
-
- if (namerec->data.num_ips == 1) {
- prdata = rdata;
- } else {
- if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
- DEBUG(0,("process_name_query_request: malloc fail !\n"));
- return;
- }
- }
-
- for (i = 0; i < namerec->data.num_ips; i++) {
- set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
- }
-
- sort_query_replies(prdata, i, p->ip);
-
- reply_data_len = namerec->data.num_ips * 6;
- success = True;
- }
- }
-
- /*
- * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
- * set we should initiate a WINS query here. On success we add the resolved name
- * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
- */
-
- if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
- bcast && (subrec != remote_broadcast_subnet)) {
- make_wins_proxy_name_query_request( subrec, p, question );
- return;
- }
-
- if (!success && bcast) {
- if(prdata != rdata)
- SAFE_FREE(prdata);
- return; /* Never reply with a negative response to broadcasts. */
- }
-
- /*
- * Final check. From observation, if a unicast packet is sent
- * to a non-WINS server with the recursion desired bit set
- * then never send a negative response.
- */
-
- if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
- if(prdata != rdata)
- SAFE_FREE(prdata);
- return;
- }
-
- if (success) {
- rcode = 0;
- DEBUG(3,("OK\n"));
- } else {
- rcode = NAM_ERR;
- DEBUG(3,("UNKNOWN\n"));
- }
-
- /* See rfc1002.txt 4.2.13. */
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- prdata, /* data to send. */
- reply_data_len); /* data length. */
-
- if(prdata != rdata)
- SAFE_FREE(prdata);
+ /* Look up the name in the cache - if the request is a broadcast request that
+ came from a subnet we don't know about then search all the broadcast subnets
+ for a match (as we don't know what interface the request came in on). */
+
+ if(subrec == remote_broadcast_subnet)
+ namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
+ else
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+
+ /* Check if it is a name that expired */
+ if( namerec
+ && ( (namerec->data.death_time != PERMANENT_TTL)
+ && (namerec->data.death_time < p->timestamp) ) )
+ {
+ DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
+ namerec = NULL;
+ }
+
+ if (namerec)
+ {
+
+ /*
+ * Always respond to unicast queries.
+ * Don't respond to broadcast queries unless the query is for
+ * a name we own, a Primary Domain Controller name, or a WINS_PROXY
+ * name with type 0 or 0x20. WINS_PROXY names are only ever added
+ * into the namelist if we were configured as a WINS proxy.
+ */
+
+ if( !bcast
+ || ( bcast
+ && ( (name_type == 0x1b)
+ || (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME)
+ || ( (namerec->data.source == WINS_PROXY_NAME)
+ && ( (name_type == 0) || (name_type == 0x20) )
+ )
+ )
+ )
+ )
+ {
+
+ /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
+ or it's a Domain Master type. */
+
+ /*
+ * If this is a WINS_PROXY_NAME, then ceck that none of the IP
+ * addresses we are returning is on the same broadcast subnet
+ * as the requesting packet. If it is then don't reply as the
+ * actual machine will be replying also and we don't want two
+ * replies to a broadcast query.
+ */
+
+ if( namerec->data.source == WINS_PROXY_NAME )
+ {
+ for( i = 0; i < namerec->data.num_ips; i++)
+ {
+ if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))
+ {
+ DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
+on the same subnet (%s) as the requestor. Not replying.\n",
+ nmb_namestr(&namerec->name), subrec->subnet_name ));
+ goto done;
+ }
+ }
+ }
+
+ ttl = (namerec->data.death_time != PERMANENT_TTL) ?
+ namerec->data.death_time - p->timestamp : lp_max_ttl();
+
+ /* Copy all known ip addresses into the return data. */
+ /* Optimise for the common case of one IP address so
+ we don't need a malloc. */
+
+ if( namerec->data.num_ips == 1 )
+ prdata = rdata;
+ else
+ {
+ if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
+ {
+ DEBUG(0,("process_name_query_request: malloc fail !\n"));
+ goto done;
+ }
+ }
+
+ for( i = 0; i < namerec->data.num_ips; i++ )
+ {
+ set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
+ putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+ }
+
+ sort_query_replies(prdata, i, p->ip);
+
+ reply_data_len = namerec->data.num_ips * 6;
+ success = True;
+ }
+ }
+
+ /*
+ * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
+ * set we should initiate a WINS query here. On success we add the resolved name
+ * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
+ */
+
+ if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
+ bcast && (subrec != remote_broadcast_subnet))
+ {
+ make_wins_proxy_name_query_request( subrec, p, question );
+ goto done;
+ }
+
+ if (!success && bcast)
+ {
+ if((prdata != rdata) && (prdata != NULL))
+ SAFE_FREE(prdata);
+ goto done; /* Never reply with a negative response to broadcasts. */
+ }
+
+ /*
+ * Final check. From observation, if a unicast packet is sent
+ * to a non-WINS server with the recursion desired bit set
+ * then never send a negative response.
+ */
+
+ if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
+ {
+ if((prdata != rdata) && (prdata != NULL))
+ SAFE_FREE(prdata);
+ goto done;
+ }
+
+ if (success)
+ {
+ rcode = 0;
+ DEBUG(3,("OK\n"));
+ }
+ else
+ {
+ rcode = NAM_ERR;
+ DEBUG(3,("UNKNOWN\n"));
+ }
+
+ /* See rfc1002.txt 4.2.13. */
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ prdata, /* data to send. */
+ reply_data_len); /* data length. */
+
+ if((prdata != rdata) && (prdata != NULL))
+ SAFE_FREE(prdata);
+done:
+ END_PROFILE(name_query);
}
diff --git a/source/nmbd/nmbd_lmhosts.c b/source/nmbd/nmbd_lmhosts.c
index b14e13f3a47..8eb198020f7 100644
--- a/source/nmbd/nmbd_lmhosts.c
+++ b/source/nmbd/nmbd_lmhosts.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Jeremy Allison 1994-1998
@@ -28,46 +29,50 @@
/****************************************************************************
Load a lmhosts file.
****************************************************************************/
-
void load_lmhosts_file(char *fname)
{
- pstring name;
- int name_type;
- struct in_addr ipaddr;
- XFILE *fp = startlmhosts( fname );
-
- if (!fp) {
- DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
- return;
- }
+ pstring name;
+ int name_type;
+ struct in_addr ipaddr;
+ FILE *fp = startlmhosts( fname );
+
+ if (!fp) {
+ DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
+ fname, strerror(errno)));
+ return;
+ }
- while (getlmhostsent(fp, name, &name_type, &ipaddr) ) {
- struct subnet_record *subrec = NULL;
- enum name_source source = LMHOSTS_NAME;
-
- /* We find a relevent subnet to put this entry on, then add it. */
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
+ while (getlmhostsent(fp, name, &name_type, &ipaddr) )
+ {
+ struct subnet_record *subrec = NULL;
+ enum name_source source = LMHOSTS_NAME;
+
+ /* We find a relevent subnet to put this entry on, then add it. */
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
+ break;
+ }
- /* If none match add the name to the remote_broadcast_subnet. */
- if(subrec == NULL)
- subrec = remote_broadcast_subnet;
-
- if(name_type == -1) {
- /* Add the (0) and (0x20) names directly into the namelist for this subnet. */
- (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- } else {
- /* Add the given name type to the subnet namelist. */
- (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- }
- }
+ /* If none match add the name to the remote_broadcast_subnet. */
+ if(subrec == NULL)
+ subrec = remote_broadcast_subnet;
+
+ if(name_type == -1)
+ {
+ /* Add the (0) and (0x20) names directly into the namelist for this subnet. */
+ (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ }
+ else
+ {
+ /* Add the given name type to the subnet namelist. */
+ (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ }
+ }
- endlmhosts(fp);
+ endlmhosts(fp);
}
/****************************************************************************
@@ -78,16 +83,17 @@ void load_lmhosts_file(char *fname)
BOOL find_name_in_lmhosts(struct nmb_name *nmbname, struct name_record **namerecp)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- *namerecp = NULL;
+ *namerecp = NULL;
- if((namerec = find_name_on_subnet(remote_broadcast_subnet, nmbname, FIND_ANY_NAME))==NULL)
- return False;
+ if((namerec = find_name_on_subnet(remote_broadcast_subnet, nmbname,
+ FIND_ANY_NAME))==NULL)
+ return False;
- if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
- return False;
+ if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
+ return False;
- *namerecp = namerec;
- return True;
+ *namerecp = namerec;
+ return True;
}
diff --git a/source/nmbd/nmbd_logonnames.c b/source/nmbd/nmbd_logonnames.c
index e4264305911..cd8dbf868cb 100644
--- a/source/nmbd/nmbd_logonnames.c
+++ b/source/nmbd/nmbd_logonnames.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,46 +24,47 @@
#include "includes.h"
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
extern struct in_addr allones_ip;
extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
/****************************************************************************
Fail to become a Logon server on a subnet.
-****************************************************************************/
-
+ ****************************************************************************/
static void become_logon_server_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- unstring failname;
- struct work_record *work;
- struct server_record *servrec;
-
- pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
- work = find_workgroup_on_subnet(subrec, failname);
- if(!work) {
- DEBUG(0,("become_logon_server_fail: Error - cannot find \
-workgroup %s on subnet %s\n", failname, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("become_logon_server_fail: Error - cannot find server %s \
+ struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
+ struct server_record *servrec;
+
+ if(!work)
+ {
+ DEBUG(0,("become_logon_server_fail: Error - cannot find \
+workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("become_logon_server_fail: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), failname, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
+ global_myname, fail_name->name, subrec->subnet_name));
+ work->log_state = LOGON_NONE;
+ return;
+ }
- /* Set the state back to LOGON_NONE. */
- work->log_state = LOGON_NONE;
+ /* Set the state back to LOGON_NONE. */
+ work->log_state = LOGON_NONE;
- servrec->serv.type &= ~SV_TYPE_DOMAIN_CTRL;
+ servrec->serv.type &= ~SV_TYPE_DOMAIN_CTRL;
- DEBUG(0,("become_logon_server_fail: Failed to become a domain master for \
+ DEBUG(0,("become_logon_server_fail: Failed to become a domain master for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
@@ -76,51 +78,49 @@ static void become_logon_server_success(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- unstring reg_name;
- struct work_record *work;
- struct server_record *servrec;
-
- pull_ascii_nstring(reg_name, sizeof(reg_name), registered_name->name);
- work = find_workgroup_on_subnet( subrec, reg_name);
- if(!work) {
- DEBUG(0,("become_logon_server_success: Error - cannot find \
-workgroup %s on subnet %s\n", reg_name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
- DEBUG(0,("become_logon_server_success: Error - cannot find server %s \
+ struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
+ struct server_record *servrec;
+
+ if(!work)
+ {
+ DEBUG(0,("become_logon_server_success: Error - cannot find \
+workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
+ {
+ DEBUG(0,("become_logon_server_success: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), reg_name, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->log_state = LOGON_SRV; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER);
- /* To allow Win95 policies to load we need to set type domain
- controller.
- */
- servrec->serv.type |= SV_TYPE_DOMAIN_CTRL;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /*
- * Add the WORKGROUP<1C> name to the UNICAST subnet with the IP address
- * for this subnet so we will respond to queries on this name.
- */
-
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
- insert_permanent_name_into_unicast(subrec, &nmbname, 0x1c);
- }
-
- DEBUG(0,("become_logon_server_success: Samba is now a logon server \
+ global_myname, registered_name->name, subrec->subnet_name));
+ work->log_state = LOGON_NONE;
+ return;
+ }
+
+ /* Set the state in the workgroup structure. */
+ work->log_state = LOGON_SRV; /* Become domain master. */
+
+ /* Update our server status. */
+ servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER);
+ /* To allow Win95 policies to load we need to set type domain
+ controller.
+ */
+ servrec->serv.type |= SV_TYPE_DOMAIN_CTRL;
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ /*
+ * Add the WORKGROUP<1C> name to the UNICAST subnet with the IP address
+ * for this subnet so we will respond to queries on this name.
+ */
+ {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,global_myworkgroup,0x1c);
+ insert_permanent_name_into_unicast(subrec, &nmbname, 0x1c);
+ }
+
+ DEBUG(0,("become_logon_server_success: Samba is now a logon server \
for workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
}
@@ -132,42 +132,45 @@ for workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
static void become_logon_server(struct subnet_record *subrec,
struct work_record *work)
{
- DEBUG(2,("become_logon_server: Atempting to become logon server for workgroup %s \
+ DEBUG(2,("become_logon_server: Atempting to become logon server for workgroup %s \
on subnet %s\n", work->work_group,subrec->subnet_name));
- DEBUG(3,("become_logon_server: go to first stage: register %s<1c> name\n",
- work->work_group));
- work->log_state = LOGON_WAIT;
+ DEBUG(3,("become_logon_server: go to first stage: register %s<1c> name\n",
+ work->work_group));
+ work->log_state = LOGON_WAIT;
- register_name(subrec, work->work_group,0x1c,samba_nb_type|NB_GROUP,
- become_logon_server_success,
- become_logon_server_fail, NULL);
+ register_name(subrec, work->work_group,0x1c,samba_nb_type|NB_GROUP,
+ become_logon_server_success,
+ become_logon_server_fail, NULL);
}
/*****************************************************************************
Add the internet group <1c> logon names by unicast and broadcast.
****************************************************************************/
-
void add_logon_names(void)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if (work && (work->log_state == LOGON_NONE)) {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "add_domain_logon_names:\n" );
- dbgtext( "Attempting to become logon server " );
- dbgtext( "for workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s\n", subrec->subnet_name );
- }
- become_logon_server(subrec, work);
- }
- }
- }
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup);
+
+ if (work && (work->log_state == LOGON_NONE))
+ {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,global_myworkgroup,0x1c);
+
+ if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "add_domain_logon_names:\n" );
+ dbgtext( "Attempting to become logon server " );
+ dbgtext( "for workgroup %s ", global_myworkgroup );
+ dbgtext( "on subnet %s\n", subrec->subnet_name );
+ }
+ become_logon_server(subrec, work);
+ }
+ }
+ }
}
diff --git a/source/nmbd/nmbd_mynames.c b/source/nmbd/nmbd_mynames.c
index 07247d5495e..07745e793a1 100644
--- a/source/nmbd/nmbd_mynames.c
+++ b/source/nmbd/nmbd_mynames.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,25 +24,27 @@
#include "includes.h"
+extern char **my_netbios_names;
+extern fstring global_myworkgroup;
+
extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
/****************************************************************************
Fail funtion when registering my netbios names.
-**************************************************************************/
+ **************************************************************************/
static void my_name_register_failed(struct subnet_record *subrec,
struct response_record *rrec, struct nmb_name *nmbname)
{
- DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
+ DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
+ nmb_namestr(nmbname), subrec->subnet_name));
}
/****************************************************************************
Add my workgroup and my given names to one subnet
Also add the magic Samba names.
-**************************************************************************/
-
+ **************************************************************************/
void register_my_workgroup_one_subnet(struct subnet_record *subrec)
{
int i;
@@ -49,10 +52,10 @@ void register_my_workgroup_one_subnet(struct subnet_record *subrec)
struct work_record *work;
/* Create the workgroup on the subnet. */
- if((work = create_workgroup_on_subnet(subrec, lp_workgroup(),
+ if((work = create_workgroup_on_subnet(subrec, global_myworkgroup,
PERMANENT_TTL)) == NULL) {
DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
-Exiting.\n", lp_workgroup(), subrec->subnet_name));
+Exiting.\n", global_myworkgroup, subrec->subnet_name));
return;
}
@@ -61,14 +64,14 @@ Exiting.\n", lp_workgroup(), subrec->subnet_name));
add_samba_names_to_subnet(subrec);
/* Register all our names including aliases. */
- for (i=0; my_netbios_names(i); i++) {
- register_name(subrec, my_netbios_names(i),0x20,samba_nb_type,
+ for (i=0; my_netbios_names[i]; i++) {
+ register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
NULL,
my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names(i),0x03,samba_nb_type,
+ register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
NULL,
my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names(i),0x00,samba_nb_type,
+ register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
NULL,
my_name_register_failed, NULL);
}
@@ -85,140 +88,164 @@ Exiting.\n", lp_workgroup(), subrec->subnet_name));
static void insert_refresh_name_into_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_type )
{
- struct name_record *namerec;
-
- if (!we_are_a_wins_client()) {
- insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
- return;
- }
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
- unstring name;
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, name,
- nmbname->name_type, nb_type,
- MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
- } else {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
+ struct name_record *namerec;
+
+ if (!we_are_a_wins_client()) {
+ insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
+ return;
+ }
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
+ {
+ /* The name needs to be created on the unicast subnet. */
+ (void)add_name_to_subnet( unicast_subnet, nmbname->name,
+ nmbname->name_type, nb_type,
+ MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
+ }
+ else
+ {
+ /* The name already exists on the unicast subnet. Add our local
+ IP for the given broadcast subnet to the name. */
+ add_ip_to_name_record( namerec, subrec->myip);
+ }
}
/****************************************************************************
Add my workgroup and my given names to the subnet lists.
Also add the magic Samba names.
-**************************************************************************/
+ **************************************************************************/
BOOL register_my_workgroup_and_names(void)
{
- struct subnet_record *subrec;
- int i;
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- register_my_workgroup_one_subnet(subrec);
- }
-
- /* We still need to add the magic Samba
- names and the netbios names to the unicast subnet directly. This is
- to allow unicast node status requests and queries to still work
- in a broadcast only environment. */
-
- add_samba_names_to_subnet(unicast_subnet);
-
- for (i=0; my_netbios_names(i); i++) {
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x20);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x3);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
- }
- }
-
- /*
- * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
- * also for the same reasons.
- */
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x1e);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- }
-
- /*
- * We need to add the Samba names to the remote broadcast subnet,
- * as NT 4.x does directed broadcast requests to the *<0x0> name.
- */
-
- add_samba_names_to_subnet(remote_broadcast_subnet);
-
- return True;
+ struct subnet_record *subrec;
+ int i;
+
+ for(subrec = FIRST_SUBNET;
+ subrec;
+ subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ register_my_workgroup_one_subnet(subrec);
+ }
+
+ /* We still need to add the magic Samba
+ names and the netbios names to the unicast subnet directly. This is
+ to allow unicast node status requests and queries to still work
+ in a broadcast only environment. */
+
+ add_samba_names_to_subnet(unicast_subnet);
+
+ for (i=0; my_netbios_names[i]; i++)
+ {
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ /*
+ * Ensure all the IP addresses are added if we are multihomed.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, my_netbios_names[i],0x20);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+
+ make_nmb_name(&nmbname, my_netbios_names[i],0x3);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+
+ make_nmb_name(&nmbname, my_netbios_names[i],0x0);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+ }
+ }
+
+ /*
+ * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
+ * also for the same reasons.
+ */
+
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ /*
+ * Ensure all the IP addresses are added if we are multihomed.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, global_myworkgroup, 0x0);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
+
+ make_nmb_name(&nmbname, global_myworkgroup, 0x1e);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
+ }
+
+ /*
+ * We need to add the Samba names to the remote broadcast subnet,
+ * as NT 4.x does directed broadcast requests to the *<0x0> name.
+ */
+ add_samba_names_to_subnet(remote_broadcast_subnet);
+
+ return True;
}
/****************************************************************************
Remove all the names we registered.
**************************************************************************/
-void release_wins_names(void)
+void release_my_names(void)
{
- struct subnet_record *subrec = unicast_subnet;
- struct name_record *namerec, *nextnamerec;
-
- for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = nextnamerec) {
- nextnamerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.source == SELF_NAME)
- && !NAME_IS_DEREGISTERING(namerec) )
- release_name( subrec, namerec, standard_success_release,
- NULL, NULL);
- }
+#if 0 /*JRR: do WINS server only, otherwise clients ignore us when we come back up*/
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+#else
+ struct subnet_record *subrec = unicast_subnet;
+#endif
+ {
+ struct name_record *namerec, *nextnamerec;
+
+ for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = nextnamerec)
+ {
+ nextnamerec = (struct name_record *)ubi_trNext( namerec );
+ if( (namerec->data.source == SELF_NAME)
+ && !NAME_IS_DEREGISTERING(namerec) )
+ release_name( subrec, namerec, standard_success_release,
+ NULL, NULL);
+ }
+ }
}
/*******************************************************************
- Refresh our registered names with WINS
-******************************************************************/
+ Refresh our registered names.
+ ******************************************************************/
void refresh_my_names(time_t t)
{
- struct name_record *namerec;
-
- if (wins_srv_count() < 1)
- return;
-
- for (namerec = (struct name_record *)ubi_trFirst(unicast_subnet->namelist);
- namerec;
- namerec = (struct name_record *)ubi_trNext(namerec)) {
- /* Each SELF name has an individual time to be refreshed. */
- if ((namerec->data.source == SELF_NAME) &&
- (namerec->data.refresh_time < t) &&
- (namerec->data.death_time != PERMANENT_TTL)) {
- /* We cheat here and pretend the refresh is going to be
- successful & update the refresh times. This stops
- multiple refresh calls being done. We actually
- deal with refresh failure in the fail_fn.
- */
- if (!is_refresh_already_queued(unicast_subnet, namerec)) {
- wins_refresh_name(namerec);
- }
- namerec->data.death_time = t + lp_max_ttl();
- namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
- }
- }
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ struct name_record *namerec;
+
+ /* B nodes don't send out name refresh requests, see RFC 1001, 15.5.1 */
+ if (subrec != unicast_subnet)
+ continue;
+
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ /* Each SELF name has an individual time to be refreshed. */
+ if( (namerec->data.source == SELF_NAME)
+ && (namerec->data.refresh_time < t)
+ && ( namerec->data.death_time != PERMANENT_TTL) )
+ {
+ /* We cheat here and pretend the refresh is going to be
+ successful & update the refresh times. This stops
+ multiple refresh calls being done. We actually
+ deal with refresh failure in the fail_fn.
+ */
+ if( !is_refresh_already_queued( subrec, namerec) )
+ refresh_name( subrec, namerec, NULL, NULL, NULL );
+ namerec->data.death_time = t + lp_max_ttl();
+ namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
+ }
+ }
+ }
}
diff --git a/source/nmbd/nmbd_namelistdb.c b/source/nmbd/nmbd_namelistdb.c
index bb14ff7641a..b3b36fac05f 100644
--- a/source/nmbd/nmbd_namelistdb.c
+++ b/source/nmbd/nmbd_namelistdb.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,154 +24,159 @@
#include "includes.h"
-uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
+extern char **my_netbios_names;
+uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
-/**************************************************************************
- Set Samba's NetBIOS name type.
-***************************************************************************/
+/* ************************************************************************** **
+ * Set Samba's NetBIOS name type.
+ * ************************************************************************** **
+ */
void set_samba_nb_type(void)
-{
- if( lp_wins_support() || wins_srv_count() )
- samba_nb_type = NB_HFLAG; /* samba is a 'hybrid' node type. */
- else
- samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
-}
-
-/***************************************************************************
- Convert a NetBIOS name to upper case.
-***************************************************************************/
-
+ {
+ if( lp_wins_support() || (*lp_wins_server()) )
+ samba_nb_type = NB_MFLAG; /* samba is a 'hybrid' node type. */
+ else
+ samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
+ } /* set_samba_nb_type */
+
+/* ************************************************************************** **
+ * Convert a NetBIOS name to upper case.
+ * ************************************************************************** **
+ */
static void upcase_name( struct nmb_name *target, struct nmb_name *source )
-{
- int i;
- unstring targ;
- fstring scope;
-
- if( NULL != source )
- memcpy( target, source, sizeof( struct nmb_name ) );
-
- pull_ascii_nstring(targ, sizeof(targ), target->name);
- strupper_m( targ );
- push_ascii_nstring( target->name, targ);
-
- pull_ascii(scope, target->scope, 64, -1, STR_TERMINATE);
- strupper_m( scope );
- push_ascii(target->scope, scope, 64, STR_TERMINATE);
-
- /* fudge... We're using a byte-by-byte compare, so we must be sure that
- * unused space doesn't have garbage in it.
- */
-
- for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
- target->name[i] = '\0';
- for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
- target->scope[i] = '\0';
-}
-
-/**************************************************************************
- Add a new or overwrite an existing namelist entry.
-***************************************************************************/
-
+ {
+ int i;
+
+ if( NULL != source )
+ (void)memcpy( target, source, sizeof( struct nmb_name ) );
+
+ strupper( target->name );
+ strupper( target->scope );
+
+ /* fudge... We're using a byte-by-byte compare, so we must be sure that
+ * unused space doesn't have garbage in it.
+ */
+ for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
+ target->name[i] = '\0';
+ for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
+ target->scope[i] = '\0';
+ } /* upcase_name */
+
+/* ************************************************************************** **
+ * Add a new or overwrite an existing namelist entry.
+ * ************************************************************************** **
+ */
static void update_name_in_namelist( struct subnet_record *subrec,
struct name_record *namerec )
-{
- struct name_record *oldrec = NULL;
-
- ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
- if( oldrec ) {
- SAFE_FREE( oldrec->data.ip );
- SAFE_FREE( oldrec );
- }
-}
-
-/**************************************************************************
- Remove a name from the namelist.
-***************************************************************************/
-
+ {
+ struct name_record *oldrec = NULL;
+
+ (void)ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
+ if( oldrec )
+ {
+ SAFE_FREE( oldrec->data.ip );
+ SAFE_FREE( oldrec );
+ }
+ } /* update_name_in_namelist */
+
+/* ************************************************************************** **
+ * Remove a name from the namelist.
+ * ************************************************************************** **
+ */
void remove_name_from_namelist( struct subnet_record *subrec,
struct name_record *namerec )
-{
- ubi_trRemove( subrec->namelist, namerec );
- SAFE_FREE(namerec->data.ip);
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
- subrec->namelist_changed = True;
-}
+ {
+ (void)ubi_trRemove( subrec->namelist, namerec );
-/**************************************************************************
- Find a name in a subnet.
-**************************************************************************/
+ SAFE_FREE(namerec->data.ip);
+
+ ZERO_STRUCTP(namerec);
+ SAFE_FREE(namerec);
+ subrec->namelist_changed = True;
+ } /* remove_name_from_namelist */
+
+/* ************************************************************************** **
+ * Find a name in a subnet.
+ * ************************************************************************** **
+ */
struct name_record *find_name_on_subnet( struct subnet_record *subrec,
struct nmb_name *nmbname,
BOOL self_only )
-{
- struct nmb_name uc_name[1];
- struct name_record *name_ret;
-
- upcase_name( uc_name, nmbname );
- name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
- if( name_ret ) {
- /* Self names only - these include permanent names. */
- if( self_only && (name_ret->data.source != SELF_NAME) && (name_ret->data.source != PERMANENT_NAME) ) {
- DEBUG( 9, ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
- }
-
- DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
- subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
- return( name_ret );
- }
-
- DEBUG( 9, ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
-}
-
-/**************************************************************************
- Find a name over all known broadcast subnets.
-************************************************************************/
-
+ {
+ struct nmb_name uc_name[1];
+ struct name_record *name_ret;
+
+ upcase_name( uc_name, nmbname );
+ name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
+ if( name_ret )
+ {
+ /* Self names only - these include permanent names. */
+ if( self_only
+ && (name_ret->data.source != SELF_NAME)
+ && (name_ret->data.source != PERMANENT_NAME) )
+ {
+ DEBUG( 9,
+ ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
+ subrec->subnet_name, nmb_namestr(nmbname) ) );
+ return( NULL );
+ }
+ DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
+ subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
+ return( name_ret );
+ }
+ DEBUG( 9,
+ ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
+ subrec->subnet_name, nmb_namestr(nmbname) ) );
+ return( NULL );
+ } /* find_name_on_subnet */
+
+/* ************************************************************************** **
+ * Find a name over all known broadcast subnets.
+ * ************************************************************************** **
+ */
struct name_record *find_name_for_remote_broadcast_subnet(
struct nmb_name *nmbname,
BOOL self_only )
-{
- struct subnet_record *subrec;
- struct name_record *namerec = NULL;
-
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) {
- if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
- break;
- }
-
- return( namerec );
-}
+ {
+ struct subnet_record *subrec;
+ struct name_record *namerec = NULL;
+
+ for( subrec = FIRST_SUBNET;
+ subrec;
+ subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
+ {
+ if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
+ break;
+ }
+
+ return( namerec );
+ } /* find_name_for_remote_broadcast_subnet */
-/**************************************************************************
- Update the ttl of an entry in a subnet name list.
-***************************************************************************/
-
+/* ************************************************************************** **
+ * Update the ttl of an entry in a subnet name list.
+ * ************************************************************************** **
+ */
void update_name_ttl( struct name_record *namerec, int ttl )
{
- time_t time_now = time(NULL);
+ time_t time_now = time(NULL);
- if( namerec->data.death_time != PERMANENT_TTL )
- namerec->data.death_time = time_now + ttl;
+ if( namerec->data.death_time != PERMANENT_TTL )
+ namerec->data.death_time = time_now + ttl;
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
-
- namerec->subnet->namelist_changed = True;
-}
+ namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
-/**************************************************************************
- Add an entry to a subnet name list.
-***********************************************************************/
+ namerec->subnet->namelist_changed = True;
+} /* update_name_ttl */
+/* ************************************************************************** **
+ * Add an entry to a subnet name list.
+ * ************************************************************************** **
+ */
struct name_record *add_name_to_subnet( struct subnet_record *subrec,
- const char *name,
+ const char *name,
int type,
uint16 nb_flags,
int ttl,
@@ -178,66 +184,69 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
int num_ips,
struct in_addr *iplist)
{
- struct name_record *namerec;
- time_t time_now = time(NULL);
+ struct name_record *namerec;
+ time_t time_now = time(NULL);
- namerec = (struct name_record *)malloc( sizeof(*namerec) );
- if( NULL == namerec ) {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
- return( NULL );
- }
+ namerec = (struct name_record *)malloc( sizeof(*namerec) );
+ if( NULL == namerec )
+ {
+ DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
+ return( NULL );
+ }
- memset( (char *)namerec, '\0', sizeof(*namerec) );
- namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr) * num_ips );
- if( NULL == namerec->data.ip ) {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
- return NULL;
- }
+ memset( (char *)namerec, '\0', sizeof(*namerec) );
+ namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr)
+ * num_ips );
+ if( NULL == namerec->data.ip )
+ {
+ DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
- namerec->subnet = subrec;
+ ZERO_STRUCTP(namerec);
+ SAFE_FREE( namerec );
+ return NULL;
+ }
- make_nmb_name(&namerec->name, name, type);
- upcase_name(&namerec->name, NULL );
+ namerec->subnet = subrec;
- /* Enter the name as active. */
- namerec->data.nb_flags = nb_flags | NB_ACTIVE;
- namerec->data.wins_flags = WINS_ACTIVE;
+ make_nmb_name(&namerec->name, name, type);
+ upcase_name(&namerec->name, NULL );
- /* If it's our primary name, flag it as so. */
- if( strequal( my_netbios_names(0), name ) )
- namerec->data.nb_flags |= NB_PERM;
+ /* Enter the name as active. */
+ namerec->data.nb_flags = nb_flags | NB_ACTIVE;
- /* Copy the IPs. */
- namerec->data.num_ips = num_ips;
- memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
+ /* If it's our primary name, flag it as so. */
+ if( strequal( my_netbios_names[0], name ) )
+ namerec->data.nb_flags |= NB_PERM;
- /* Data source. */
- namerec->data.source = source;
+ /* Copy the IPs. */
+ namerec->data.num_ips = num_ips;
+ memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
- /* Setup the death_time and refresh_time. */
- if( ttl == PERMANENT_TTL )
- namerec->data.death_time = PERMANENT_TTL;
- else
- namerec->data.death_time = time_now + ttl;
+ /* Data source. */
+ namerec->data.source = source;
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+ /* Setup the death_time and refresh_time. */
+ if( ttl == PERMANENT_TTL )
+ namerec->data.death_time = PERMANENT_TTL;
+ else
+ namerec->data.death_time = time_now + ttl;
- /* Now add the record to the name list. */
- update_name_in_namelist( subrec, namerec );
+ namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
- DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
+ /* Now add the record to the name list. */
+ update_name_in_namelist( subrec, namerec );
+
+ DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
ttl=%d nb_flags=%2x to subnet %s\n",
- nmb_namestr( &namerec->name ),
- inet_ntoa( *iplist ),
- ttl,
- (unsigned int)nb_flags,
- subrec->subnet_name ) );
+ nmb_namestr( &namerec->name ),
+ inet_ntoa( *iplist ),
+ ttl,
+ (unsigned int)nb_flags,
+ subrec->subnet_name ) );
- subrec->namelist_changed = True;
+ subrec->namelist_changed = True;
- return(namerec);
+ return(namerec);
}
/*******************************************************************
@@ -251,17 +260,14 @@ void standard_success_register(struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_flags, int ttl,
struct in_addr registered_ip)
{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- if( NULL == namerec ) {
- unstring name;
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
- add_name_to_subnet( subrec, name, nmbname->name_type,
- nb_flags, ttl, SELF_NAME, 1, &registered_ip );
- } else {
- update_name_ttl( namerec, ttl );
- }
+ struct name_record *namerec;
+
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
+ if( NULL == namerec )
+ (void)add_name_to_subnet( subrec, nmbname->name, nmbname->name_type,
+ nb_flags, ttl, SELF_NAME, 1, &registered_ip );
+ else
+ update_name_ttl( namerec, ttl );
}
/*******************************************************************
@@ -275,16 +281,17 @@ void standard_fail_register( struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *nmbname )
{
- struct name_record *namerec;
+ struct name_record *namerec;
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
-on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );
+ DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
+on subnet %s\n",
+ nmb_namestr(nmbname), subrec->subnet_name) );
- /* Remove the name from the subnet. */
- if( namerec )
- remove_name_from_namelist(subrec, namerec);
+ /* Remove the name from the subnet. */
+ if( namerec )
+ remove_name_from_namelist(subrec, namerec);
}
/*******************************************************************
@@ -293,13 +300,13 @@ on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );
static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
{
- if( ind != namerec->data.num_ips )
- memmove( (char *)(&namerec->data.ip[ind]),
- (char *)(&namerec->data.ip[ind+1]),
- ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
+ if( ind != namerec->data.num_ips )
+ memmove( (char *)(&namerec->data.ip[ind]),
+ (char *)(&namerec->data.ip[ind+1]),
+ ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
- namerec->data.num_ips--;
- namerec->subnet->namelist_changed = True;
+ namerec->data.num_ips--;
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -308,13 +315,13 @@ static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
{
- int i;
+ int i;
- for(i = 0; i < namerec->data.num_ips; i++)
- if(ip_equal( namerec->data.ip[i], ip))
- return True;
+ for(i = 0; i < namerec->data.num_ips; i++)
+ if(ip_equal( namerec->data.ip[i], ip))
+ return True;
- return False;
+ return False;
}
/*******************************************************************
@@ -323,26 +330,30 @@ BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
{
- struct in_addr *new_list;
+ struct in_addr *new_list;
- /* Don't add one we already have. */
- if( find_ip_in_name_record( namerec, new_ip ) )
- return;
+ /* Don't add one we already have. */
+ if( find_ip_in_name_record( namerec, new_ip ) )
+ return;
- new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1) * sizeof(struct in_addr) );
- if( NULL == new_list ) {
- DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
- return;
- }
-
- memcpy( (char *)new_list, (char *)namerec->data.ip, namerec->data.num_ips * sizeof(struct in_addr) );
- new_list[namerec->data.num_ips] = new_ip;
-
- SAFE_FREE(namerec->data.ip);
- namerec->data.ip = new_list;
- namerec->data.num_ips += 1;
-
- namerec->subnet->namelist_changed = True;
+ new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1)
+ * sizeof(struct in_addr) );
+ if( NULL == new_list )
+ {
+ DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
+ return;
+ }
+
+ memcpy( (char *)new_list,
+ (char *)namerec->data.ip,
+ namerec->data.num_ips * sizeof(struct in_addr) );
+ new_list[namerec->data.num_ips] = new_ip;
+
+ SAFE_FREE(namerec->data.ip);
+ namerec->data.ip = new_list;
+ namerec->data.num_ips += 1;
+
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -352,16 +363,16 @@ void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
void remove_ip_from_name_record( struct name_record *namerec,
struct in_addr remove_ip )
{
- /* Try and find the requested ip address - remove it. */
- int i;
- int orig_num = namerec->data.num_ips;
-
- for(i = 0; i < orig_num; i++) {
- if( ip_equal( remove_ip, namerec->data.ip[i]) ) {
- remove_nth_ip_in_record( namerec, i);
- break;
- }
- }
+ /* Try and find the requested ip address - remove it. */
+ int i;
+ int orig_num = namerec->data.num_ips;
+
+ for(i = 0; i < orig_num; i++)
+ if( ip_equal( remove_ip, namerec->data.ip[i]) )
+ {
+ remove_nth_ip_in_record( namerec, i);
+ break;
+ }
}
/*******************************************************************
@@ -375,67 +386,85 @@ void standard_success_release( struct subnet_record *subrec,
struct nmb_name *nmbname,
struct in_addr released_ip )
{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME );
- if( namerec == NULL ) {
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. Name was not found on subnet.\n", nmb_namestr(nmbname), inet_ntoa(released_ip),
- subrec->subnet_name) );
- return;
- } else {
- int orig_num = namerec->data.num_ips;
-
- remove_ip_from_name_record( namerec, released_ip );
-
- if( namerec->data.num_ips == orig_num )
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. This ip is not known for this name.\n", nmb_namestr(nmbname), inet_ntoa(released_ip), subrec->subnet_name ) );
- }
-
- if( namerec->data.num_ips == 0 )
- remove_name_from_namelist( subrec, namerec );
+ struct name_record *namerec;
+
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME );
+
+ if( namerec == NULL )
+ {
+ DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
+on subnet %s. Name was not found on subnet.\n",
+ nmb_namestr(nmbname),
+ inet_ntoa(released_ip),
+ subrec->subnet_name) );
+ return;
+ }
+ else
+ {
+ int orig_num = namerec->data.num_ips;
+
+ remove_ip_from_name_record( namerec, released_ip );
+
+ if( namerec->data.num_ips == orig_num )
+ DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
+on subnet %s. This ip is not known for this name.\n",
+ nmb_namestr(nmbname),
+ inet_ntoa(released_ip),
+ subrec->subnet_name ) );
+ }
+
+ if( namerec->data.num_ips == 0 )
+ remove_name_from_namelist( subrec, namerec );
}
/*******************************************************************
Expires old names in a subnet namelist.
-******************************************************************/
+ ******************************************************************/
void expire_names_on_subnet(struct subnet_record *subrec, time_t t)
{
- struct name_record *namerec;
- struct name_record *next_namerec;
-
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = next_namerec ) {
- next_namerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
- if( namerec->data.source == SELF_NAME ) {
- DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
-name %s\n", subrec->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- namerec->subnet->namelist_changed = True;
- continue;
- }
-
- DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
- subrec->subnet_name, nmb_namestr(&namerec->name)));
+ struct name_record *namerec;
+ struct name_record *next_namerec;
+
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = next_namerec )
+ {
+ next_namerec = (struct name_record *)ubi_trNext( namerec );
+ if( (namerec->data.death_time != PERMANENT_TTL)
+ && (namerec->data.death_time < t) )
+ {
+ if( namerec->data.source == SELF_NAME )
+ {
+ DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
+name %s\n",
+ subrec->subnet_name, nmb_namestr(&namerec->name) ) );
+ namerec->data.death_time += 300;
+ namerec->subnet->namelist_changed = True;
+ continue;
+ }
+ DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
+ subrec->subnet_name, nmb_namestr(&namerec->name)));
- remove_name_from_namelist( subrec, namerec );
- }
- }
+ remove_name_from_namelist( subrec, namerec );
+ }
+ }
}
/*******************************************************************
Expires old names in all subnet namelists.
-******************************************************************/
+ ******************************************************************/
void expire_names(time_t t)
{
- struct subnet_record *subrec;
-
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) ) {
- expire_names_on_subnet( subrec, t );
- }
+ struct subnet_record *subrec;
+
+ for( subrec = FIRST_SUBNET;
+ subrec;
+ subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
+ {
+ expire_names_on_subnet( subrec, t );
+ }
}
/****************************************************************************
@@ -448,39 +477,46 @@ void expire_names(time_t t)
void add_samba_names_to_subnet( struct subnet_record *subrec )
{
- struct in_addr *iplist = &subrec->myip;
- int num_ips = 1;
-
- /* These names are added permanently (ttl of zero) and will NOT be refreshed. */
-
- if( (subrec == unicast_subnet) || (subrec == wins_server_subnet) || (subrec == remote_broadcast_subnet) ) {
- struct subnet_record *bcast_subrecs;
- int i;
-
- /* Create an IP list containing all our known subnets. */
-
- num_ips = iface_count();
- iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
- if( NULL == iplist ) {
- DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
- return;
- }
-
- for( bcast_subrecs = FIRST_SUBNET, i = 0; bcast_subrecs; bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
- iplist[i] = bcast_subrecs->myip;
- }
-
- add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
-
- if(iplist != &subrec->myip)
- SAFE_FREE(iplist);
+ struct in_addr *iplist = &subrec->myip;
+ int num_ips = 1;
+
+ /* These names are added permanently (ttl of zero) and will NOT be
+ refreshed. */
+
+ if( (subrec == unicast_subnet)
+ || (subrec == wins_server_subnet)
+ || (subrec == remote_broadcast_subnet) )
+ {
+ struct subnet_record *bcast_subrecs;
+ int i;
+ /* Create an IP list containing all our known subnets. */
+
+ num_ips = iface_count();
+ iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
+ if( NULL == iplist )
+ {
+ DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
+ return;
+ }
+
+ for( bcast_subrecs = FIRST_SUBNET, i = 0;
+ bcast_subrecs;
+ bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
+ iplist[i] = bcast_subrecs->myip;
+
+ }
+
+ (void)add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ (void)add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ (void)add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ (void)add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+
+ if(iplist != &subrec->myip)
+ SAFE_FREE(iplist);
}
/****************************************************************************
@@ -488,67 +524,70 @@ void add_samba_names_to_subnet( struct subnet_record *subrec )
into a file. Initiated by SIGHUP - used to debug the state of the namelists.
**************************************************************************/
-static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
+static void dump_subnet_namelist( struct subnet_record *subrec, FILE *fp)
{
- struct name_record *namerec;
- const char *src_type;
- struct tm *tm;
- int i;
-
- x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) ) {
-
- x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
- switch(namerec->data.source) {
- case LMHOSTS_NAME:
- src_type = "LMHOSTS_NAME";
- break;
- case WINS_PROXY_NAME:
- src_type = "WINS_PROXY_NAME";
- break;
- case REGISTER_NAME:
- src_type = "REGISTER_NAME";
- break;
- case SELF_NAME:
- src_type = "SELF_NAME";
- break;
- case DNS_NAME:
- src_type = "DNS_NAME";
- break;
- case DNSFAIL_NAME:
- src_type = "DNSFAIL_NAME";
- break;
- case PERMANENT_NAME:
- src_type = "PERMANENT_NAME";
- break;
- default:
- src_type = "unknown!";
- break;
- }
-
- x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
-
- if(namerec->data.death_time != PERMANENT_TTL) {
- tm = LocalTime(&namerec->data.death_time);
- x_fprintf(fp, "death_time = %s\t", asctime(tm));
- } else {
- x_fprintf(fp, "death_time = PERMANENT\t");
- }
-
- if(namerec->data.refresh_time != PERMANENT_TTL) {
- tm = LocalTime(&namerec->data.refresh_time);
- x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
- } else {
- x_fprintf(fp, "refresh_time = PERMANENT\n");
- }
-
- x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
- for(i = 0; i < namerec->data.num_ips; i++)
- x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
-
- x_fprintf(fp, "\n\n");
- }
+ struct name_record *namerec;
+ const char *src_type;
+ struct tm *tm;
+ int i;
+
+ fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
+ switch(namerec->data.source)
+ {
+ case LMHOSTS_NAME:
+ src_type = "LMHOSTS_NAME";
+ break;
+ case WINS_PROXY_NAME:
+ src_type = "WINS_PROXY_NAME";
+ break;
+ case REGISTER_NAME:
+ src_type = "REGISTER_NAME";
+ break;
+ case SELF_NAME:
+ src_type = "SELF_NAME";
+ break;
+ case DNS_NAME:
+ src_type = "DNS_NAME";
+ break;
+ case DNSFAIL_NAME:
+ src_type = "DNSFAIL_NAME";
+ break;
+ case PERMANENT_NAME:
+ src_type = "PERMANENT_NAME";
+ break;
+ default:
+ src_type = "unknown!";
+ break;
+ }
+ fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
+
+ if(namerec->data.death_time != PERMANENT_TTL)
+ {
+ tm = LocalTime(&namerec->data.death_time);
+ fprintf(fp, "death_time = %s\t", asctime(tm));
+ }
+ else
+ fprintf(fp, "death_time = PERMANENT\t");
+
+ if(namerec->data.refresh_time != PERMANENT_TTL)
+ {
+ tm = LocalTime(&namerec->data.refresh_time);
+ fprintf(fp, "refresh_time = %s\n", asctime(tm));
+ }
+ else
+ fprintf(fp, "refresh_time = PERMANENT\n");
+
+ fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
+ for(i = 0; i < namerec->data.num_ips; i++)
+ fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
+
+ fprintf(fp, "\n\n");
+ }
}
/****************************************************************************
@@ -558,27 +597,30 @@ static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
void dump_all_namelists(void)
{
- XFILE *fp;
- struct subnet_record *subrec;
+ FILE *fp;
+ struct subnet_record *subrec;
- fp = x_fopen(lock_path("namelist.debug"),O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ fp = sys_fopen(lock_path("namelist.debug"),"w");
- if (!fp) {
- DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
- "namelist.debug",strerror(errno)));
- return;
- }
+ if (!fp)
+ {
+ DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
+ "namelist.debug",strerror(errno)));
+ return;
+ }
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
- dump_subnet_namelist( subrec, fp );
+ for( subrec = FIRST_SUBNET;
+ subrec;
+ subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
+ dump_subnet_namelist( subrec, fp );
- if( !we_are_a_wins_client() )
- dump_subnet_namelist( unicast_subnet, fp );
+ if( !we_are_a_wins_client() )
+ dump_subnet_namelist( unicast_subnet, fp );
- if( remote_broadcast_subnet->namelist != NULL )
- dump_subnet_namelist( remote_broadcast_subnet, fp );
+ if( remote_broadcast_subnet->namelist != NULL )
+ dump_subnet_namelist( remote_broadcast_subnet, fp );
- if( wins_server_subnet != NULL )
- dump_subnet_namelist( wins_server_subnet, fp );
- x_fclose( fp );
+ if( wins_server_subnet != NULL )
+ dump_subnet_namelist( wins_server_subnet, fp );
+ fclose( fp );
}
diff --git a/source/nmbd/nmbd_namequery.c b/source/nmbd/nmbd_namequery.c
index 1b07852f111..5c2490e26ee 100644
--- a/source/nmbd/nmbd_namequery.c
+++ b/source/nmbd/nmbd_namequery.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,95 +32,106 @@ static void query_name_response( struct subnet_record *subrec,
struct response_record *rrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL success = False;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct in_addr answer_ip;
-
- zero_ip(&answer_ip);
-
- /* Ensure we don't retry the query but leave the response record cleanup
- to the timeout code. We may get more answer responses in which case
- we should mark the name in conflict.. */
- rrec->repeat_count = 0;
-
- if(rrec->num_msgs == 1) {
- /* This is the first response. */
-
- if(nmb->header.opcode == NMB_WACK_OPCODE) {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more query requests. */
-
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "query_name_response: " );
- dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) );
- dbgtext( "in querying name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+ BOOL success = False;
+ struct nmb_name *question_name =
+ &rrec->packet->packet.nmb.question.question_name;
+ struct in_addr answer_ip;
+
+ zero_ip(&answer_ip);
+
+ /* Ensure we don't retry the query but leave the response record cleanup
+ to the timeout code. We may get more answer responses in which case
+ we should mark the name in conflict.. */
+ rrec->repeat_count = 0;
+
+ if(rrec->num_msgs == 1)
+ {
+ /* This is the first response. */
+
+ if(nmb->header.opcode == NMB_WACK_OPCODE)
+ {
+ /* WINS server is telling us to wait. Pretend we didn't get
+ the response but don't send out any more query requests. */
+
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "query_name_response: " );
+ dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) );
+ dbgtext( "in querying name %s ", nmb_namestr(question_name) );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ }
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- } else if(nmb->header.rcode != 0) {
-
- success = False;
-
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "Error code was %d.\n", nmb->header.rcode );
- }
- } else {
- if (!nmb->answers) {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "IP %s ", inet_ntoa(p->ip) );
- dbgtext( "returned a success response with no answer\n" );
- return;
- }
-
- success = True;
-
- putip((char *)&answer_ip,&nmb->answers->rdata[2]);
-
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) );
- }
-
- /* Interestingly, we could add these names to our namelists, and
- change nmbd to a model that checked its own name cache first,
- before sending out a query. This is a task for another day, though.
- */
- }
- } else if( rrec->num_msgs > 1) {
-
- if( DEBUGLVL( 0 ) ) {
- if (nmb->answers)
- putip( (char *)&answer_ip, &nmb->answers->rdata[2] );
- dbgtext( "query_name_response: " );
- dbgtext( "Multiple (%d) responses ", rrec->num_msgs );
- dbgtext( "received for a query on subnet %s ", subrec->subnet_name );
- dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) );
- dbgtext( "was from IP %s, reporting ", inet_ntoa(p->ip) );
- dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) );
- }
-
- /* We have already called the success or fail function, so we
- don't call again here. Leave the response record around in
- case we get more responses. */
-
- return;
- }
+ rrec->repeat_count = 0;
+ /* How long we should wait for. */
+ rrec->repeat_time = p->timestamp + nmb->answers->ttl;
+ rrec->num_msgs--;
+ return;
+ }
+ else if(nmb->header.rcode != 0)
+ {
+ success = False;
+
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "for name %s. ", nmb_namestr(question_name) );
+ dbgtext( "Error code was %d.\n", nmb->header.rcode );
+ }
+ }
+ else
+ {
+ if (!nmb->answers)
+ {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "returned a success response with no answer\n" );
+ return;
+ }
+
+ success = True;
+
+ putip((char *)&answer_ip,&nmb->answers->rdata[2]);
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "for name %s. ", nmb_namestr(question_name) );
+ dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) );
+ }
+
+ /* Interestingly, we could add these names to our namelists, and
+ change nmbd to a model that checked its own name cache first,
+ before sending out a query. This is a task for another day, though.
+ */
+ }
+ }
+ else if( rrec->num_msgs > 1)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ if (nmb->answers)
+ putip( (char *)&answer_ip, &nmb->answers->rdata[2] );
+ dbgtext( "query_name_response: " );
+ dbgtext( "Multiple (%d) responses ", rrec->num_msgs );
+ dbgtext( "received for a query on subnet %s ", subrec->subnet_name );
+ dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) );
+ dbgtext( "was from IP %s, reporting ", inet_ntoa(p->ip) );
+ dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) );
+ }
+
+ /* We have already called the success or fail function, so we
+ don't call again here. Leave the response record around in
+ case we get more responses. */
+
+ return;
+ }
- if(success && rrec->success_fn)
- (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
- else if( rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
+ if(success && rrec->success_fn)
+ (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
+ else if( rrec->fail_fn)
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
}
@@ -130,30 +142,32 @@ static void query_name_response( struct subnet_record *subrec,
static void query_name_timeout_response(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- /* We can only fail here, never succeed. */
- BOOL failed = True;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
-
- if(rrec->num_msgs != 0) {
- /* We got at least one response, and have called the success/fail
- function already. */
-
- failed = False;
- }
-
- if(failed) {
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "query_name_timeout_response: No response to " );
- dbgtext( "query for name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
-
- if(rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
- }
-
- remove_response_record(subrec, rrec);
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ /* We can only fail here, never succeed. */
+ BOOL failed = True;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
+
+ if(rrec->num_msgs != 0)
+ {
+ /* We got at least one response, and have called the success/fail
+ function already. */
+
+ failed = False;
+ }
+
+ if(failed)
+ {
+ if( DEBUGLVL( 5 ) )
+ {
+ dbgtext( "query_name_timeout_response: No response to " );
+ dbgtext( "query for name %s ", nmb_namestr(question_name) );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ }
+ if(rrec->fail_fn)
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
+ }
+
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -164,83 +178,98 @@ static void query_name_timeout_response(struct subnet_record *subrec,
static BOOL query_local_namelists(struct subnet_record *subrec, struct nmb_name *nmbname,
struct name_record **namerecp)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- *namerecp = NULL;
+ *namerecp = NULL;
- if(find_name_in_lmhosts(nmbname, namerecp))
- return True;
+ if(find_name_in_lmhosts(nmbname, namerecp))
+ return True;
- if((namerec = find_name_on_subnet(subrec, nmbname, FIND_ANY_NAME))==NULL)
- return False;
-
- if( NAME_IS_ACTIVE(namerec) && ( (namerec->data.source == SELF_NAME) || (namerec->data.source == LMHOSTS_NAME) ) ) {
- *namerecp = namerec;
- return True;
- }
- return False;
+ if((namerec = find_name_on_subnet(subrec, nmbname, FIND_ANY_NAME))==NULL)
+ return False;
+
+ if( NAME_IS_ACTIVE(namerec)
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == LMHOSTS_NAME) ) )
+ {
+ *namerecp = namerec;
+ return True;
+ }
+ return False;
}
/****************************************************************************
Try and query for a name.
****************************************************************************/
-BOOL query_name(struct subnet_record *subrec, const char *name, int type,
+BOOL query_name(struct subnet_record *subrec, char *name, int type,
query_name_success_function success_fn,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, name, type);
-
- /*
- * We need to check our local namelists first.
- * It may be an magic name, lmhosts name or just
- * a name we have registered.
- */
-
- if(query_local_namelists(subrec, &nmbname, &namerec) == True) {
- struct res_rec rrec;
- int i;
-
- memset((char *)&rrec, '\0', sizeof(struct res_rec));
-
- /* Fake up the needed res_rec just in case it's used. */
- rrec.rr_name = nmbname;
- rrec.rr_type = RR_TYPE_NB;
- rrec.rr_class = RR_CLASS_IN;
- rrec.ttl = PERMANENT_TTL;
- rrec.rdlength = namerec->data.num_ips * 6;
- if(rrec.rdlength > MAX_DGRAM_SIZE) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "query_name: nmbd internal error - " );
- dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
- dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
- }
- return False;
- }
-
- for( i = 0; i < namerec->data.num_ips; i++) {
- set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
- putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
- }
-
- /* Call the success function directly. */
- if(success_fn)
- (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
- return False;
- }
-
- if(queue_query_name( subrec, query_name_response, query_name_timeout_response, success_fn, fail_fn, userdata, &nmbname) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "query_name: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
+ struct nmb_name nmbname;
+ struct name_record *namerec;
+
+ make_nmb_name(&nmbname, name, type);
+
+ /*
+ * We need to check our local namelists first.
+ * It may be an magic name, lmhosts name or just
+ * a name we have registered.
+ */
+
+ if(query_local_namelists(subrec, &nmbname, &namerec) == True)
+ {
+ struct res_rec rrec;
+ int i;
+
+ memset((char *)&rrec, '\0', sizeof(struct res_rec));
+
+ /* Fake up the needed res_rec just in case it's used. */
+ rrec.rr_name = nmbname;
+ rrec.rr_type = RR_TYPE_NB;
+ rrec.rr_class = RR_CLASS_IN;
+ rrec.ttl = PERMANENT_TTL;
+ rrec.rdlength = namerec->data.num_ips * 6;
+ if(rrec.rdlength > MAX_DGRAM_SIZE)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "query_name: nmbd internal error - " );
+ dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
+ dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
+ }
+ return False;
+ }
+
+ for( i = 0; i < namerec->data.num_ips; i++)
+ {
+ set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
+ putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
+ }
+
+ /* Call the success function directly. */
+ if(success_fn)
+ (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
+ return False;
+ }
+
+ if(queue_query_name( subrec,
+ query_name_response,
+ query_name_timeout_response,
+ success_fn,
+ fail_fn,
+ userdata,
+ &nmbname) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "query_name: Failed to send packet " );
+ dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
+ }
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -248,21 +277,29 @@ BOOL query_name(struct subnet_record *subrec, const char *name, int type,
****************************************************************************/
BOOL query_name_from_wins_server(struct in_addr ip_to,
- const char *name, int type,
+ char *name, int type,
query_name_success_function success_fn,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, name, type);
-
- if(queue_query_name_from_wins_server( ip_to, query_name_response, query_name_timeout_response, success_fn, fail_fn, userdata, &nmbname) == NULL) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "query_name_from_wins_server: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, name, type);
+
+ if(queue_query_name_from_wins_server( ip_to,
+ query_name_response,
+ query_name_timeout_response,
+ success_fn,
+ fail_fn,
+ userdata,
+ &nmbname) == NULL)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "query_name_from_wins_server: Failed to send packet " );
+ dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
+ }
+ return True;
+ }
+ return False;
}
diff --git a/source/nmbd/nmbd_nameregister.c b/source/nmbd/nmbd_nameregister.c
index 4e11881f063..de68265840a 100644
--- a/source/nmbd/nmbd_nameregister.c
+++ b/source/nmbd/nmbd_nameregister.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,9 +24,7 @@
#include "includes.h"
-/* forward declarations */
-static void wins_next_registration(struct response_record *rrec);
-
+extern fstring global_myworkgroup;
/****************************************************************************
Deal with a response packet when registering one of our names.
@@ -34,205 +33,127 @@ static void wins_next_registration(struct response_record *rrec);
static void register_name_response(struct subnet_record *subrec,
struct response_record *rrec, struct packet_struct *p)
{
- /*
- * If we are registering broadcast, then getting a response is an
- * error - we do not have the name. If we are registering unicast,
- * then we expect to get a response.
- */
-
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL bcast = nmb->header.nm_flags.bcast;
- BOOL success = True;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- int ttl = 0;
- uint16 nb_flags = 0;
- struct in_addr register_ip;
- fstring reg_name;
-
- putip(&register_ip,&sent_nmb->additional->rdata[2]);
- fstrcpy(reg_name, inet_ntoa(register_ip));
-
- if (subrec == unicast_subnet) {
- /* we know that this wins server is definately alive - for the moment! */
- wins_srv_alive(rrec->packet->ip, register_ip);
- }
-
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
-
- if(!question_name || !answer_name) {
- DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
- question_name ? "question_name" : "answer_name" ));
- return;
- }
-
- if(!nmb_name_equal(question_name, answer_name)) {
- DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n",
- nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
-
- if(bcast) {
- /*
- * Special hack to cope with old Samba nmbd's.
- * Earlier versions of Samba (up to 1.9.16p11) respond
- * to a broadcast name registration of WORKGROUP<1b> when
- * they should not. Hence, until these versions are gone,
- * we should treat such errors as success for this particular
- * case only. jallison@whistle.com.
- */
-
+ /*
+ * If we are registering broadcast, then getting a response is an
+ * error - we do not have the name. If we are registering unicast,
+ * then we expect to get a response.
+ */
+
+ struct nmb_packet *nmb = &p->packet.nmb;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ BOOL success = True;
+ struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
+ struct nmb_name *answer_name = &nmb->answers->rr_name;
+ int ttl = 0;
+ uint16 nb_flags = 0;
+ struct in_addr registered_ip;
+
+ /* Sanity check. Ensure that the answer name in the incoming packet is the
+ same as the requested name in the outgoing packet. */
+
+ if(!question_name || !answer_name)
+ {
+ DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
+ question_name ? "question_name" : "answer_name" ));
+ return;
+ }
+
+ if(!nmb_name_equal(question_name, answer_name))
+ {
+ DEBUG(0,("register_name_response: Answer name %s differs from question \
+name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
+ return;
+ }
+
+ if(bcast)
+ {
+ /*
+ * Special hack to cope with old Samba nmbd's.
+ * Earlier versions of Samba (up to 1.9.16p11) respond
+ * to a broadcast name registration of WORKGROUP<1b> when
+ * they should not. Hence, until these versions are gone,
+ * we should treat such errors as success for this particular
+ * case only. jallison@whistle.com.
+ */
+
#if 1 /* OLD_SAMBA_SERVER_HACK */
- unstring ans_name;
- pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name);
- if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&
- (answer_name->name_type == 0x1b)) {
- /* Pretend we did not get this. */
- rrec->num_msgs--;
-
- DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n",
- nmb_namestr(answer_name)));
- return;
- }
+ if((nmb->header.rcode == ACT_ERR) && strequal(global_myworkgroup, answer_name->name) &&
+ (answer_name->name_type == 0x1b))
+ {
+ /* Pretend we did not get this. */
+ rrec->num_msgs--;
+
+ DEBUG(5,("register_name_response: Ignoring broadcast response to \
+registration of name %s due to old Samba server bug.\n", nmb_namestr(answer_name)));
+ return;
+ }
#endif /* OLD_SAMBA_SERVER_HACK */
- /* Someone else has the name. Log the problem. */
- DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n",
- nmb_namestr(answer_name),
- reg_name,
- subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
- success = False;
- } else {
- /* Unicast - check to see if the response allows us to have the name. */
- if (nmb->header.opcode == NMB_WACK_OPCODE) {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more register requests. */
-
- DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n",
- inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));
-
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- } else if (nmb->header.rcode != 0) {
- /* Error code - we didn't get the name. */
- success = False;
-
- DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
- subrec==unicast_subnet?"WINS ":"",
- inet_ntoa(p->ip),
- nmb_namestr(answer_name),
- reg_name,
- nmb->header.rcode));
- } else {
- success = True;
- /* Get the data we need to pass to the success function. */
- nb_flags = get_nb_flags(nmb->answers->rdata);
- ttl = nmb->answers->ttl;
-
- /* send off a registration for the next IP, if any */
- wins_next_registration(rrec);
- }
- }
-
- DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
- success ? "success" : "failure",
- subrec==unicast_subnet?"WINS ":"",
- nmb_namestr(answer_name),
- reg_name,
- inet_ntoa(rrec->packet->ip)));
-
- if(success) {
- /* Enter the registered name into the subnet name database before calling
- the success function. */
- standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
- if( rrec->success_fn)
- (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
- } else {
- if( rrec->fail_fn)
- (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
- /* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
- }
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Deal with a timeout of a WINS registration request
-****************************************************************************/
-
-static void wins_registration_timeout(struct subnet_record *subrec,
- struct response_record *rrec)
-{
- struct userdata_struct *userdata = rrec->userdata;
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *nmbname = &sent_nmb->question.question_name;
- struct in_addr register_ip;
- fstring src_addr;
-
- putip(&register_ip,&sent_nmb->additional->rdata[2]);
-
- fstrcpy(src_addr, inet_ntoa(register_ip));
-
- DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n",
- inet_ntoa(rrec->packet->ip), src_addr));
-
- /* mark it temporarily dead for this source address */
- wins_srv_died(rrec->packet->ip, register_ip);
-
- /* if we have some userdata then use that to work out what
- wins server to try next */
- if (userdata) {
- const char *tag = (const char *)userdata->data;
-
- /* try the next wins server in our failover list for
- this tag */
- rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
- }
-
- /* if we have run out of wins servers for this tag then they
- must all have timed out. We treat this as *success*, not
- failure, and go into our standard name refresh mode. This
- copes with all the wins servers being down */
- if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
- uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- int ttl = sent_nmb->additional->ttl;
-
- standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
- if(rrec->success_fn) {
- (*(register_name_success_function)rrec->success_fn)(subrec,
- rrec->userdata,
- nmbname,
- nb_flags,
- ttl,
- register_ip);
- }
-
- /* send off a registration for the next IP, if any */
- wins_next_registration(rrec);
-
- /* don't need to send this packet any more */
- remove_response_record(subrec, rrec);
- return;
- }
-
- /* we will be moving to the next WINS server for this group,
- send it immediately */
- rrec->repeat_count = 2;
- rrec->repeat_time = time(NULL) + 1;
- rrec->in_expiration_processing = False;
-
- DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
- nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));
-
- /* notice that we don't remove the response record. This keeps
- us trying to register with each of our failover wins servers */
+ /* Someone else has the name. Log the problem. */
+ DEBUG(1,("register_name_response: Failed to register \
+name %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n",
+ nmb_namestr(answer_name),
+ subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
+ success = False;
+ }
+ else
+ {
+ /* Unicast - check to see if the response allows us to have the name. */
+ if(nmb->header.rcode != 0)
+ {
+ /* Error code - we didn't get the name. */
+ success = False;
+
+ DEBUG(0,("register_name_response: server at IP %s rejected our \
+name registration of %s with error code %d.\n", inet_ntoa(p->ip),
+ nmb_namestr(answer_name), nmb->header.rcode));
+
+ }
+ else if(nmb->header.opcode == NMB_WACK_OPCODE)
+ {
+ /* WINS server is telling us to wait. Pretend we didn't get
+ the response but don't send out any more register requests. */
+
+ DEBUG(5,("register_name_response: WACK from WINS server %s in registering \
+name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));
+
+ rrec->repeat_count = 0;
+ /* How long we should wait for. */
+ rrec->repeat_time = p->timestamp + nmb->answers->ttl;
+ rrec->num_msgs--;
+ return;
+ }
+ else
+ {
+ success = True;
+ /* Get the data we need to pass to the success function. */
+ nb_flags = get_nb_flags(nmb->answers->rdata);
+ putip((char*)&registered_ip,&nmb->answers->rdata[2]);
+ ttl = nmb->answers->ttl;
+ }
+ }
+
+ DEBUG(5,("register_name_response: %s in registering name %s on subnet %s.\n",
+ success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
+
+ if(success)
+ {
+ /* Enter the registered name into the subnet name database before calling
+ the success function. */
+ standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
+ if( rrec->success_fn)
+ (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
+ }
+ else
+ {
+ if( rrec->fail_fn)
+ (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
+ /* Remove the name. */
+ standard_fail_register( subrec, rrec, question_name);
+ }
+
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -240,298 +161,240 @@ static void wins_registration_timeout(struct subnet_record *subrec,
****************************************************************************/
static void register_name_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
+ struct response_record *rrec)
{
- /*
- * If we are registering unicast, then NOT getting a response is an
- * error - we do not have the name. If we are registering broadcast,
- * then we don't expect to get a response.
- */
-
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- BOOL bcast = sent_nmb->header.nm_flags.bcast;
- BOOL success = False;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
- uint16 nb_flags = 0;
- int ttl = 0;
- struct in_addr registered_ip;
-
- if (bcast) {
- if(rrec->num_msgs == 0) {
- /* Not receiving a message is success for broadcast registration. */
- success = True;
-
- /* Pull the success values from the original request packet. */
- nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- ttl = sent_nmb->additional->ttl;
- putip(&registered_ip,&sent_nmb->additional->rdata[2]);
- }
- } else {
- /* wins timeouts are special */
- wins_registration_timeout(subrec, rrec);
- return;
- }
-
- DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
- success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
- if(success) {
- /* Enter the registered name into the subnet name database before calling
- the success function. */
- standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
- if( rrec->success_fn)
- (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
- } else {
- if( rrec->fail_fn)
- (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
- /* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
- }
-
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
-}
-
-/****************************************************************************
- Initiate one multi-homed name registration packet.
-****************************************************************************/
-
-static void multihomed_register_one(struct nmb_name *nmbname,
- uint16 nb_flags,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct in_addr ip,
- const char *tag)
-{
- struct userdata_struct *userdata;
- struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
- fstring ip_str;
-
- userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
- if (!userdata) {
- DEBUG(0,("Failed to allocate userdata structure!\n"));
- return;
- }
- ZERO_STRUCTP(userdata);
- userdata->userdata_len = strlen(tag) + 1;
- strlcpy(userdata->data, tag, userdata->userdata_len);
-
- fstrcpy(ip_str, inet_ntoa(ip));
-
- DEBUG(6,("Registering name %s IP %s with WINS server %s using tag '%s'\n",
- nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
-
- if (queue_register_multihomed_name(unicast_subnet,
- register_name_response,
- register_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- nmbname,
- nb_flags,
- ip,
- wins_ip) == NULL) {
- DEBUG(0,("multihomed_register_one: Failed to send packet trying to register name %s IP %s\n",
- nmb_namestr(nmbname), inet_ntoa(ip)));
- }
-
- free(userdata);
-}
-
-/****************************************************************************
- We have finished the registration of one IP and need to see if we have
- any more IPs left to register with this group of wins server for this name.
-****************************************************************************/
-
-static void wins_next_registration(struct response_record *rrec)
-{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *nmbname = &sent_nmb->question.question_name;
- uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
- struct userdata_struct *userdata = rrec->userdata;
- const char *tag;
- struct in_addr last_ip;
- struct subnet_record *subrec;
-
- putip(&last_ip,&sent_nmb->additional->rdata[2]);
-
- if (!userdata) {
- /* it wasn't multi-homed */
- return;
- }
-
- tag = (const char *)userdata->data;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if (ip_equal(last_ip, subrec->myip)) {
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
- break;
- }
- }
-
- if (!subrec) {
- /* no more to do! */
- return;
- }
-
- switch (sent_nmb->header.opcode) {
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- multihomed_register_one(nmbname, nb_flags, NULL, NULL, subrec->myip, tag);
- break;
- case NMB_NAME_REFRESH_OPCODE_8:
- queue_wins_refresh(nmbname,
- register_name_response,
- register_name_timeout_response,
- nb_flags, subrec->myip, tag);
- break;
- }
+ /*
+ * If we are registering unicast, then NOT getting a response is an
+ * error - we do not have the name. If we are registering broadcast,
+ * then we don't expect to get a response.
+ */
+
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ BOOL bcast = sent_nmb->header.nm_flags.bcast;
+ BOOL success = False;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
+ uint16 nb_flags = 0;
+ int ttl = 0;
+ struct in_addr registered_ip;
+
+ if(bcast)
+ {
+ if(rrec->num_msgs == 0)
+ {
+ /* Not receiving a message is success for broadcast registration. */
+ success = True;
+
+ /* Pull the success values from the original request packet. */
+ nb_flags = get_nb_flags(sent_nmb->additional->rdata);
+ ttl = sent_nmb->additional->ttl;
+ putip(&registered_ip,&sent_nmb->additional->rdata[2]);
+ }
+ }
+ else
+ {
+ /* Unicast - if no responses then it's an error. */
+ if(rrec->num_msgs == 0)
+ {
+ DEBUG(2,("register_name_timeout_response: WINS server at address %s is not \
+responding.\n", inet_ntoa(rrec->packet->ip)));
+
+ /* Keep trying to contact the WINS server periodically. This allows
+ us to work correctly if the WINS server is down temporarily when
+ we come up. */
+
+ /* Reset the number of attempts to zero and double the interval between
+ retries. Max out at 5 minutes. */
+ rrec->repeat_count = 3;
+ rrec->repeat_interval *= 2;
+ if(rrec->repeat_interval > (5 * 60))
+ rrec->repeat_interval = (5 * 60);
+ rrec->repeat_time = time(NULL) + rrec->repeat_interval;
+ rrec->in_expiration_processing = False;
+
+ DEBUG(5,("register_name_timeout_response: increasing WINS timeout to %d seconds.\n",
+ (int)rrec->repeat_interval));
+ return; /* Don't remove the response record. */
+ }
+ }
+
+ DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
+ success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
+ if(success)
+ {
+ /* Enter the registered name into the subnet name database before calling
+ the success function. */
+ standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
+ if( rrec->success_fn)
+ (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
+ }
+ else
+ {
+ if( rrec->fail_fn)
+ (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
+ /* Remove the name. */
+ standard_fail_register( subrec, rrec, question_name);
+ }
+
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
Try and register one of our names on the unicast subnet - multihomed.
****************************************************************************/
-static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn)
+static BOOL multihomed_register_name( struct nmb_name *nmbname, uint16 nb_flags,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata)
{
- /*
- If we are adding a group name, we just send multiple
- register name packets to the WINS server (this is an
- internet group name.
-
- If we are adding a unique name, We need first to add
- our names to the unicast subnet namelist. This is
- because when a WINS server receives a multihomed
- registration request, the first thing it does is to
- send a name query to the registering machine, to see
- if it has put the name in it's local namelist.
- We need the name there so the query response code in
- nmbd_incomingrequests.c will find it.
-
- We are adding this name prematurely (we don't really
- have it yet), but as this is on the unicast subnet
- only we will get away with this (only the WINS server
- will ever query names from us on this subnet).
- */
- int num_ips=0;
- int i, t;
- struct subnet_record *subrec;
- char **wins_tags;
- struct in_addr *ip_list;
- unstring name;
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
- num_ips++;
-
- if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL) {
- DEBUG(0,("multihomed_register_name: malloc fail !\n"));
- return;
- }
-
- for (subrec = FIRST_SUBNET, i = 0;
- subrec;
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
- ip_list[i] = subrec->myip;
- }
-
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
- add_name_to_subnet(unicast_subnet, name, nmbname->name_type,
- nb_flags, lp_max_ttl(), SELF_NAME,
- num_ips, ip_list);
-
- /* get the list of wins tags - we try to register for each of them */
- wins_tags = wins_srv_tags();
-
- /* Now try and register the name for each wins tag. Note that
- at this point we only register our first IP with each wins
- group. We will register the rest from
- wins_next_registration() when we get the reply for this
- one. That follows the way W2K does things (tridge)
- */
- for (t=0; wins_tags && wins_tags[t]; t++) {
- multihomed_register_one(nmbname, nb_flags,
- success_fn, fail_fn,
- ip_list[0],
- wins_tags[t]);
- }
-
- wins_srv_tags_free(wins_tags);
-
- SAFE_FREE(ip_list);
+ /*
+ If we are adding a group name, we just send multiple
+ register name packets to the WINS server (this is an
+ internet group name.
+
+ If we are adding a unique name, We need first to add
+ our names to the unicast subnet namelist. This is
+ because when a WINS server receives a multihomed
+ registration request, the first thing it does is to
+ send a name query to the registering machine, to see
+ if it has put the name in it's local namelist.
+ We need the name there so the query response code in
+ nmbd_incomingrequests.c will find it.
+
+ We are adding this name prematurely (we don't really
+ have it yet), but as this is on the unicast subnet
+ only we will get away with this (only the WINS server
+ will ever query names from us on this subnet).
+ */
+
+ int num_ips=0;
+ int i;
+ struct in_addr *ip_list = NULL;
+ struct subnet_record *subrec;
+
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
+ num_ips++;
+
+ if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL)
+ {
+ DEBUG(0,("multihomed_register_name: malloc fail !\n"));
+ return True;
+ }
+
+ for( subrec = FIRST_SUBNET, i = 0;
+ subrec;
+ subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ )
+ ip_list[i] = subrec->myip;
+
+ (void)add_name_to_subnet( unicast_subnet, nmbname->name, nmbname->name_type,
+ nb_flags, lp_max_ttl(), SELF_NAME,
+ num_ips, ip_list);
+
+ /* Now try and register the name, num_ips times. On the last time use
+ the given success and fail functions. */
+
+ for( i = 0; i < num_ips; i++)
+ {
+ if(queue_register_multihomed_name( unicast_subnet,
+ register_name_response,
+ register_name_timeout_response,
+ (i == num_ips - 1) ? success_fn : NULL,
+ (i == num_ips - 1) ? fail_fn : NULL,
+ (i == num_ips - 1) ? userdata : NULL,
+ nmbname,
+ nb_flags,
+ ip_list[i]) == NULL)
+ {
+ DEBUG(0,("multihomed_register_name: Failed to send packet trying to \
+register name %s IP %s\n", nmb_namestr(nmbname), inet_ntoa(ip_list[i]) ));
+
+ SAFE_FREE(ip_list);
+ return True;
+ }
+ }
+
+ SAFE_FREE(ip_list);
+
+ return False;
}
/****************************************************************************
Try and register one of our names.
****************************************************************************/
-void register_name(struct subnet_record *subrec,
+BOOL register_name(struct subnet_record *subrec,
const char *name, int type, uint16 nb_flags,
register_name_success_function success_fn,
register_name_fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct nmb_name nmbname;
- nstring nname;
-
- errno = 0;
- push_ascii_nstring(nname, name);
- if (errno == E2BIG) {
- unstring tname;
- pull_ascii_nstring(tname, sizeof(tname), nname);
- DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n",
- name, tname));
- make_nmb_name(&nmbname, tname, type);
- } else {
- make_nmb_name(&nmbname, name, type);
- }
-
- /* Always set the NB_ACTIVE flag on the name we are
- registering. Doesn't make sense without it.
- */
-
- nb_flags |= NB_ACTIVE;
-
- if (subrec == unicast_subnet) {
- /* we now always do multi-homed registration if we are
- registering to a WINS server. This copes much
- better with complex WINS setups */
- multihomed_register_name(&nmbname, nb_flags,
- success_fn, fail_fn);
- return;
- }
-
- if (queue_register_name(subrec,
- register_name_response,
- register_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname,
- nb_flags) == NULL) {
- DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
- nmb_namestr(&nmbname)));
- }
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, name, type);
+
+ /* Always set the NB_ACTIVE flag on the name we are
+ registering. Doesn't make sense without it.
+ */
+
+ nb_flags |= NB_ACTIVE;
+
+ /* If this is the unicast subnet, and we are a multi-homed
+ host, then register a multi-homed name. */
+
+ if( (subrec == unicast_subnet) && we_are_multihomed())
+ return multihomed_register_name(&nmbname, nb_flags,
+ success_fn, fail_fn,
+ userdata);
+
+ if(queue_register_name( subrec,
+ register_name_response,
+ register_name_timeout_response,
+ success_fn,
+ fail_fn,
+ userdata,
+ &nmbname,
+ nb_flags) == NULL)
+ {
+ DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
+ nmb_namestr(&nmbname)));
+ return True;
+ }
+ return False;
}
/****************************************************************************
- Try and refresh one of our names. This is *only* called for WINS refresh
+ Try and refresh one of our names.
****************************************************************************/
-void wins_refresh_name(struct name_record *namerec)
+BOOL refresh_name(struct subnet_record *subrec, struct name_record *namerec,
+ refresh_name_success_function success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata)
{
- int t;
- char **wins_tags;
-
- /* get the list of wins tags - we try to refresh for each of them */
- wins_tags = wins_srv_tags();
-
- for (t=0; wins_tags && wins_tags[t]; t++) {
- queue_wins_refresh(&namerec->name,
- register_name_response,
- register_name_timeout_response,
- namerec->data.nb_flags,
- namerec->data.ip[0], wins_tags[t]);
- }
-
- wins_srv_tags_free(wins_tags);
+ int i;
+
+ /*
+ * Go through and refresh the name for all known ip addresses.
+ * Only call the success/fail function on the last one (it should
+ * only be done once).
+ */
+
+ for( i = 0; i < namerec->data.num_ips; i++)
+ {
+ if(queue_refresh_name( subrec,
+ register_name_response,
+ register_name_timeout_response,
+ (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
+ (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
+ (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
+ namerec,
+ namerec->data.ip[i]) == NULL)
+ {
+ DEBUG(0,("refresh_name: Failed to send packet trying to refresh name %s\n",
+ nmb_namestr(&namerec->name)));
+ return True;
+ }
+ }
+ return False;
}
diff --git a/source/nmbd/nmbd_namerelease.c b/source/nmbd/nmbd_namerelease.c
index 0611ca93234..30a9d165612 100644
--- a/source/nmbd/nmbd_namerelease.c
+++ b/source/nmbd/nmbd_namerelease.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -28,72 +29,85 @@
****************************************************************************/
static void release_name_response(struct subnet_record *subrec,
- struct response_record *rrec, struct packet_struct *p)
+ struct response_record *rrec, struct packet_struct *p)
{
- /*
- * If we are releasing broadcast, then getting a response is an
- * error. If we are releasing unicast, then we expect to get a response.
- */
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL bcast = nmb->header.nm_flags.bcast;
- BOOL success = True;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
- struct in_addr released_ip;
-
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
- if (!nmb_name_equal(question_name, answer_name)) {
- DEBUG(0,("release_name_response: Answer name %s differs from question name %s.\n",
- nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
-
- if (bcast) {
- /* Someone sent a response to a bcast release? ignore it. */
- return;
- }
-
- /* Unicast - check to see if the response allows us to release the name. */
- if (nmb->header.rcode != 0) {
- /* Error code - we were told not to release the name ! What now ! */
- success = False;
-
- DEBUG(0,("release_name_response: WINS server at IP %s rejected our \
-name release of name %s with error code %d.\n",
- inet_ntoa(p->ip),
- nmb_namestr(answer_name), nmb->header.rcode));
- } else if (nmb->header.opcode == NMB_WACK_OPCODE) {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more release requests. */
-
- DEBUG(5,("release_name_response: WACK from WINS server %s in releasing \
-name %s on subnet %s.\n",
- inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));
-
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- }
-
- DEBUG(5,("release_name_response: %s in releasing name %s on subnet %s.\n",
- success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
- if (success) {
- putip((char*)&released_ip ,&nmb->answers->rdata[2]);
-
- if(rrec->success_fn)
- (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
- standard_success_release( subrec, rrec->userdata, answer_name, released_ip);
- } else {
- /* We have no standard_fail_release - maybe we should add one ? */
- if (rrec->fail_fn) {
- (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, answer_name);
- }
- }
-
- remove_response_record(subrec, rrec);
+ /*
+ * If we are releasing broadcast, then getting a response is an
+ * error. If we are releasing unicast, then we expect to get a response.
+ */
+
+ struct nmb_packet *nmb = &p->packet.nmb;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ BOOL success = True;
+ struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
+ struct nmb_name *answer_name = &nmb->answers->rr_name;
+ struct in_addr released_ip;
+
+ /* Sanity check. Ensure that the answer name in the incoming packet is the
+ same as the requested name in the outgoing packet. */
+
+ if(!nmb_name_equal(question_name, answer_name))
+ {
+ DEBUG(0,("release_name_response: Answer name %s differs from question \
+name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
+ return;
+ }
+
+ if(bcast)
+ {
+ /* Someone sent a response. This shouldn't happen/ */
+ DEBUG(1,("release_name_response: A response for releasing name %s was received on a \
+broadcast subnet %s. This should not happen !\n", nmb_namestr(answer_name), subrec->subnet_name));
+ return;
+ }
+ else
+ {
+ /* Unicast - check to see if the response allows us to release the name. */
+ if(nmb->header.rcode != 0)
+ {
+ /* Error code - we were told not to release the name ! What now ! */
+ success = False;
+
+ DEBUG(0,("release_name_response: WINS server at IP %s rejected our \
+name release of name %s with error code %d.\n", inet_ntoa(p->ip),
+ nmb_namestr(answer_name), nmb->header.rcode));
+
+ }
+ else if(nmb->header.opcode == NMB_WACK_OPCODE)
+ {
+ /* WINS server is telling us to wait. Pretend we didn't get
+ the response but don't send out any more release requests. */
+
+ DEBUG(5,("release_name_response: WACK from WINS server %s in releasing \
+name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));
+
+ rrec->repeat_count = 0;
+ /* How long we should wait for. */
+ rrec->repeat_time = p->timestamp + nmb->answers->ttl;
+ rrec->num_msgs--;
+ return;
+ }
+ }
+
+ DEBUG(5,("release_name_response: %s in releasing name %s on subnet %s.\n",
+ success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
+
+ if(success)
+ {
+ putip((char*)&released_ip ,&nmb->answers->rdata[2]);
+
+ if(rrec->success_fn)
+ (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
+ standard_success_release( subrec, rrec->userdata, answer_name, released_ip);
+ }
+ else
+ {
+ /* We have no standard_fail_release - maybe we should add one ? */
+ if(rrec->fail_fn)
+ (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, answer_name);
+ }
+
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -101,122 +115,120 @@ name %s on subnet %s.\n",
****************************************************************************/
static void release_name_timeout_response(struct subnet_record *subrec,
- struct response_record *rrec)
+ struct response_record *rrec)
{
- /* a release is *always* considered to be successful when it
- times out. This doesn't cause problems as if a WINS server
- doesn't respond and someone else wants the name then the
- normal WACK/name query from the WINS server will cope */
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- BOOL bcast = sent_nmb->header.nm_flags.bcast;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
- struct in_addr released_ip;
-
- /* Get the ip address we were trying to release. */
- putip((char*)&released_ip ,&sent_nmb->additional->rdata[2]);
-
- if (!bcast) {
- /* mark the WINS server temporarily dead */
- wins_srv_died(rrec->packet->ip, released_ip);
- }
-
- DEBUG(5,("release_name_timeout_response: success in releasing name %s on subnet %s.\n",
- nmb_namestr(question_name), subrec->subnet_name));
-
- if (rrec->success_fn) {
- (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
- }
-
- standard_success_release( subrec, rrec->userdata, question_name, released_ip);
- remove_response_record(subrec, rrec);
+ /*
+ * If we are releasing unicast, then NOT getting a response is an
+ * error - we could not release the name. If we are releasing broadcast,
+ * then we don't expect to get a response.
+ */
+
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ BOOL bcast = sent_nmb->header.nm_flags.bcast;
+ BOOL success = False;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
+ struct in_addr released_ip;
+
+ if(bcast)
+ {
+ if(rrec->num_msgs == 0)
+ {
+ /* Not receiving a message is success for broadcast release. */
+ success = True;
+
+ /* Get the ip address we were trying to release. */
+ putip((char*)&released_ip ,&sent_nmb->additional->rdata[2]);
+ }
+ }
+ else
+ {
+ /* Unicast - if no responses then it's an error. */
+ if(rrec->num_msgs == 0)
+ {
+ DEBUG(2,("release_name_timeout_response: WINS server at address %s is not \
+responding.\n", inet_ntoa(rrec->packet->ip)));
+
+ /* Keep trying to contact the WINS server periodically. This allows
+ us to work correctly if the WINS server is down temporarily when
+ we want to delete the name. */
+
+ /* Reset the number of attempts to zero and double the interval between
+ retries. Max out at 5 minutes. */
+ rrec->repeat_count = 3;
+ rrec->repeat_interval *= 2;
+ if(rrec->repeat_interval > (5 * 60))
+ rrec->repeat_interval = (5 * 60);
+ rrec->repeat_time = time(NULL) + rrec->repeat_interval;
+
+ DEBUG(5,("release_name_timeout_response: increasing WINS timeout to %d seconds.\n",
+ (int)rrec->repeat_interval));
+ return; /* Don't remove the response record. */
+ }
+ }
+
+ DEBUG(5,("release_name_timeout_response: %s in releasing name %s on subnet %s.\n",
+ success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
+
+ if(success && rrec->success_fn)
+ {
+ if(rrec->success_fn)
+ (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
+ standard_success_release( subrec, rrec->userdata, question_name, released_ip);
+ }
+ else
+ {
+ /* We have no standard_fail_release - maybe we should add one ? */
+ if( rrec->fail_fn)
+ (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
+ }
+
+ remove_response_record(subrec, rrec);
}
-
-/*
- when releasing a name with WINS we need to send the release to each of
- the WINS groups
-*/
-static void wins_release_name(struct name_record *namerec,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata)
-{
- int t, i;
- char **wins_tags;
-
- /* get the list of wins tags - we try to release for each of them */
- wins_tags = wins_srv_tags();
-
- for (t=0;wins_tags && wins_tags[t]; t++) {
- for (i = 0; i < namerec->data.num_ips; i++) {
- struct in_addr wins_ip = wins_srv_ip_tag(wins_tags[t], namerec->data.ip[i]);
-
- BOOL last_one = ((i==namerec->data.num_ips - 1) && !wins_tags[t+1]);
- if (queue_release_name(unicast_subnet,
- release_name_response,
- release_name_timeout_response,
- last_one?success_fn : NULL,
- last_one? fail_fn : NULL,
- last_one? userdata : NULL,
- &namerec->name,
- namerec->data.nb_flags,
- namerec->data.ip[i],
- wins_ip) == NULL) {
- DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
- }
- }
- }
-
- wins_srv_tags_free(wins_tags);
-}
-
-
/****************************************************************************
Try and release one of our names.
****************************************************************************/
-void release_name(struct subnet_record *subrec, struct name_record *namerec,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata)
+BOOL release_name(struct subnet_record *subrec, struct name_record *namerec,
+ release_name_success_function success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata)
{
- int i;
-
- /* Ensure it's a SELF name, and in the ACTIVE state. */
- if ((namerec->data.source != SELF_NAME) || !NAME_IS_ACTIVE(namerec)) {
- DEBUG(0,("release_name: Cannot release name %s from subnet %s. Source was %d \n",
- nmb_namestr(&namerec->name), subrec->subnet_name, namerec->data.source));
- return;
- }
-
- /* Set the name into the deregistering state. */
- namerec->data.nb_flags |= NB_DEREG;
-
- /* wins releases are a bit different */
- if (subrec == unicast_subnet) {
- wins_release_name(namerec, success_fn, fail_fn, userdata);
- return;
- }
-
- /*
- * Go through and release the name for all known ip addresses.
- * Only call the success/fail function on the last one (it should
- * only be done once).
- */
- for (i = 0; i < namerec->data.num_ips; i++) {
- if (queue_release_name(subrec,
- release_name_response,
- release_name_timeout_response,
- (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
- &namerec->name,
- namerec->data.nb_flags,
- namerec->data.ip[i],
- subrec->bcast_ip) == NULL) {
- DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
- }
- }
+ int i;
+
+ /* Ensure it's a SELF name, and in the ACTIVE state. */
+ if((namerec->data.source != SELF_NAME) || !NAME_IS_ACTIVE(namerec))
+ {
+ DEBUG(0,("release_name: Cannot release name %s from subnet %s. Source was %d \n",
+ nmb_namestr(&namerec->name), subrec->subnet_name, namerec->data.source));
+ return True;
+ }
+
+ /* Set the name into the deregistering state. */
+ namerec->data.nb_flags |= NB_DEREG;
+
+ /*
+ * Go through and release the name for all known ip addresses.
+ * Only call the success/fail function on the last one (it should
+ * only be done once).
+ */
+
+ for( i = 0; i < namerec->data.num_ips; i++)
+ {
+ if(queue_release_name( subrec,
+ release_name_response,
+ release_name_timeout_response,
+ (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
+ (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
+ (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
+ &namerec->name,
+ namerec->data.nb_flags,
+ namerec->data.ip[i]) == NULL)
+ {
+ DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
+ nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
+ return True;
+ }
+ }
+ return False;
}
diff --git a/source/nmbd/nmbd_nodestatus.c b/source/nmbd/nmbd_nodestatus.c
index 0ea5d6a8182..eeb532d4109 100644
--- a/source/nmbd/nmbd_nodestatus.c
+++ b/source/nmbd/nmbd_nodestatus.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,52 +27,52 @@
/****************************************************************************
Deal with a successful node status response.
****************************************************************************/
-
static void node_status_response(struct subnet_record *subrec,
struct response_record *rrec, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
+ struct nmb_name *answer_name = &nmb->answers->rr_name;
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
+ /* Sanity check. Ensure that the answer name in the incoming packet is the
+ same as the requested name in the outgoing packet. */
- if(!nmb_name_equal(question_name, answer_name)) {
- DEBUG(0,("node_status_response: Answer name %s differs from question \
+ if(!nmb_name_equal(question_name, answer_name))
+ {
+ DEBUG(0,("node_status_response: Answer name %s differs from question \
name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
+ return;
+ }
- DEBUG(5,("node_status_response: response from name %s on subnet %s.\n",
- nmb_namestr(answer_name), subrec->subnet_name));
+ DEBUG(5,("node_status_response: response from name %s on subnet %s.\n",
+ nmb_namestr(answer_name), subrec->subnet_name));
- /* Just send the whole answer resource record for the success function to parse. */
- if(rrec->success_fn)
- (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
+ /* Just send the whole answer resource record for the success function
+ to parse. */
+ if(rrec->success_fn)
+ (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
Deal with a timeout when requesting a node status.
****************************************************************************/
-
static void node_status_timeout_response(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
- DEBUG(5,("node_status_timeout_response: failed to get node status from name %s on subnet %s\n",
- nmb_namestr(question_name), subrec->subnet_name));
+ DEBUG(5,("node_status_timeout_response: failed to get node status from name %s on subnet %s\n",
+ nmb_namestr(question_name), subrec->subnet_name));
- if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec);
+ if( rrec->fail_fn)
+ (*rrec->fail_fn)(subrec, rrec);
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -82,11 +83,13 @@ BOOL node_status(struct subnet_record *subrec, struct nmb_name *nmbname,
struct in_addr send_ip, node_status_success_function success_fn,
node_status_fail_function fail_fn, struct userdata_struct *userdata)
{
- if(queue_node_status( subrec, node_status_response, node_status_timeout_response,
- success_fn, fail_fn, userdata, nmbname, send_ip)==NULL) {
- DEBUG(0,("node_status: Failed to send packet trying to get node status for \
+ if(queue_node_status( subrec,
+ node_status_response, node_status_timeout_response,
+ success_fn, fail_fn, userdata, nmbname, send_ip)==NULL)
+ {
+ DEBUG(0,("node_status: Failed to send packet trying to get node status for \
name %s, IP address %s\n", nmb_namestr(nmbname), inet_ntoa(send_ip)));
- return True;
- }
- return False;
+ return True;
+ }
+ return False;
}
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index d8b50a1b2e9..e3f2912ae60 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,13 +51,13 @@ Utility function to find the specific fd to send a packet out on.
static int find_subnet_fd_for_address( struct in_addr local_ip )
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->nmb_sock;
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ if(ip_equal(local_ip, subrec->myip))
+ return subrec->nmb_sock;
- return ClientNMB;
+ return ClientNMB;
}
/***************************************************************************
@@ -65,13 +66,13 @@ Utility function to find the specific fd to send a mailslot packet out on.
static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->dgram_sock;
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ if(ip_equal(local_ip, subrec->myip))
+ return subrec->dgram_sock;
- return ClientDGRAM;
+ return ClientDGRAM;
}
/***************************************************************************
@@ -80,13 +81,13 @@ Get/Set problematic nb_flags as network byte order 16 bit int.
uint16 get_nb_flags(char *buf)
{
- return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
+ return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
}
void set_nb_flags(char *buf, uint16 nb_flags)
{
- *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
- *buf = '\0';
+ *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
+ *buf = '\0';
}
/***************************************************************************
@@ -95,34 +96,37 @@ Dumps out the browse packet data.
static void debug_browse_data(char *outbuf, int len)
{
- int i,j;
-
- DEBUG( 4, ( "debug_browse_data():\n" ) );
- for (i = 0; i < len; i+= 16) {
- DEBUGADD( 4, ( "%3x char ", i ) );
-
- for (j = 0; j < 16; j++) {
- unsigned char x;
- if (i+j >= len)
- break;
-
- x = outbuf[i+j];
- if (x < 32 || x > 127)
- x = '.';
+ int i,j;
+
+ DEBUG( 4, ( "debug_browse_data():\n" ) );
+ for (i = 0; i < len; i+= 16)
+ {
+ DEBUGADD( 4, ( "%3x char ", i ) );
+
+ for (j = 0; j < 16; j++)
+ {
+ unsigned char x;
+ if (i+j >= len)
+ break;
+
+ x = outbuf[i+j];
+ if (x < 32 || x > 127)
+ x = '.';
- DEBUGADD( 4, ( "%c", x ) );
- }
+ DEBUGADD( 4, ( "%c", x ) );
+ }
- DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
+ DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
- for (j = 0; j < 16; j++) {
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
- }
+ for (j = 0; j < 16; j++)
+ {
+ if (i+j >= len)
+ break;
+ DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
+ }
- DEBUGADD( 4, ("\n") );
- }
+ DEBUGADD( 4, ("\n") );
+ }
}
/***************************************************************************
@@ -133,11 +137,13 @@ static uint16 name_trn_id=0;
static uint16 generate_name_trn_id(void)
{
- if (!name_trn_id) {
- name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
- }
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- return name_trn_id;
+
+ if (!name_trn_id)
+ {
+ name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
+ }
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+ return name_trn_id;
}
/***************************************************************************
@@ -146,25 +152,28 @@ static uint16 generate_name_trn_id(void)
static BOOL send_netbios_packet(struct packet_struct *p)
{
- BOOL loopback_this_packet = False;
-
- /* Check if we are sending to or from ourselves as a WINS server. */
- if(ismyip(p->ip) && (p->port == global_nmb_port))
- loopback_this_packet = True;
-
- if(loopback_this_packet) {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(p)) == NULL)
- return False;
- queue_packet(lo_packet);
- } else if (!send_packet(p)) {
- DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
- inet_ntoa(p->ip),p->port));
- return False;
- }
+ BOOL loopback_this_packet = False;
+
+ /* Check if we are sending to or from ourselves as a WINS server. */
+ if(ismyip(p->ip) && (p->port == global_nmb_port))
+ loopback_this_packet = True;
+
+ if(loopback_this_packet)
+ {
+ struct packet_struct *lo_packet = NULL;
+ DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(p)) == NULL)
+ return False;
+ queue_packet(lo_packet);
+ }
+ else if (!send_packet(p))
+ {
+ DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
+ inet_ntoa(p->ip),p->port));
+ return False;
+ }
- return True;
+ return True;
}
/***************************************************************************
@@ -180,44 +189,45 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
BOOL bcast, BOOL rec_des,
struct in_addr to_ip)
{
- struct packet_struct *packet = NULL;
- struct nmb_packet *nmb = NULL;
-
- /* Allocate the packet_struct we will return. */
- if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
- DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
- return NULL;
- }
+ struct packet_struct *packet = NULL;
+ struct nmb_packet *nmb = NULL;
+
+ /* Allocate the packet_struct we will return. */
+ if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
+ {
+ DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
+ return NULL;
+ }
- memset((char *)packet,'\0',sizeof(*packet));
+ memset((char *)packet,'\0',sizeof(*packet));
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.name_trn_id = generate_name_trn_id();
- nmb->header.response = False;
- nmb->header.nm_flags.recursion_desired = rec_des;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.nm_flags.bcast = bcast;
+ nmb->header.name_trn_id = generate_name_trn_id();
+ nmb->header.response = False;
+ nmb->header.nm_flags.recursion_desired = rec_des;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = False;
+ nmb->header.nm_flags.bcast = bcast;
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
-
- nmb->question.question_name = *nmbname;
- nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
- nmb->question.question_class = QUESTION_CLASS_IN;
-
- packet->ip = to_ip;
- packet->port = NMB_PORT;
- packet->fd = ClientNMB;
- packet->timestamp = time(NULL);
- packet->packet_type = NMB_PACKET;
- packet->locked = False;
+ nmb->header.rcode = 0;
+ nmb->header.qdcount = 1;
+ nmb->header.ancount = 0;
+ nmb->header.nscount = 0;
+
+ nmb->question.question_name = *nmbname;
+ nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
+ nmb->question.question_class = QUESTION_CLASS_IN;
+
+ packet->ip = to_ip;
+ packet->port = NMB_PORT;
+ packet->fd = ClientNMB;
+ packet->timestamp = time(NULL);
+ packet->packet_type = NMB_PACKET;
+ packet->locked = False;
- return packet; /* Caller must free. */
+ return packet; /* Caller must free. */
}
/***************************************************************************
@@ -228,44 +238,40 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
uint16 nb_flags,
struct in_addr *register_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
- DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
- return False;
- }
-
- memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
-
- nmb->additional->rr_name = nmb->question.question_name;
- nmb->additional->rr_type = RR_TYPE_NB;
- nmb->additional->rr_class = RR_CLASS_IN;
-
- /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
- if (nmb->header.nm_flags.bcast)
- nmb->additional->ttl = PERMANENT_TTL;
- else
- nmb->additional->ttl = lp_max_ttl();
-
- nmb->additional->rdlength = 6;
-
- set_nb_flags(nmb->additional->rdata,nb_flags);
-
- /* Set the address for the name we are registering. */
- putip(&nmb->additional->rdata[2], register_ip);
-
- /*
- it turns out that Jeremys code was correct, we are supposed
- to send registrations from the IP we are registering. The
- trick is what to do on timeouts! When we send on a
- non-routable IP then the reply will timeout, and we should
- treat this as success, not failure. That means we go into
- our standard refresh cycle for that name which copes nicely
- with disconnected networks.
- */
- packet->fd = find_subnet_fd_for_address(*register_ip);
-
- return True;
+ struct nmb_packet *nmb = &packet->packet.nmb;
+
+ if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL)
+ {
+ DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
+ return False;
+ }
+
+ memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
+
+ nmb->additional->rr_name = nmb->question.question_name;
+ nmb->additional->rr_type = RR_TYPE_NB;
+ nmb->additional->rr_class = RR_CLASS_IN;
+
+ /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
+ if (nmb->header.nm_flags.bcast)
+ nmb->additional->ttl = PERMANENT_TTL;
+ else
+ nmb->additional->ttl = lp_max_ttl();
+
+ nmb->additional->rdlength = 6;
+
+ set_nb_flags(nmb->additional->rdata,nb_flags);
+
+ /* Set the address for the name we are registering. */
+ putip(&nmb->additional->rdata[2], register_ip);
+
+ /* Ensure that we send out the file descriptor to give us the
+ the specific source address we are registering as our
+ IP source address. */
+
+ packet->fd = find_subnet_fd_for_address( *register_ip );
+
+ return True;
}
/***************************************************************************
@@ -274,20 +280,20 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
static BOOL initiate_name_query_packet( struct packet_struct *packet)
{
- struct nmb_packet *nmb = NULL;
+ struct nmb_packet *nmb = NULL;
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_desired = True;
- DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -296,20 +302,20 @@ static BOOL initiate_name_query_packet( struct packet_struct *packet)
static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
{
- struct nmb_packet *nmb = NULL;
+ struct nmb_packet *nmb = NULL;
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -319,49 +325,49 @@ static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *p
static BOOL initiate_name_register_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *register_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_REG_OPCODE;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_REG_OPCODE;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_desired = True;
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
Sends out a multihomed name register.
**************************************************************************/
-static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *register_ip)
+static BOOL initiate_multihomed_name_register_packet( struct packet_struct *packet,
+ uint16 nb_flags, struct in_addr *register_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
- fstring second_ip_buf;
+ struct nmb_packet *nmb = &packet->packet.nmb;
+ fstring second_ip_buf;
+
+ fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
- fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
+ nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
+ nmb->header.arcount = 1;
- nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
- nmb->header.arcount = 1;
+ nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_desired = True;
-
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
-
- DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
+ if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
+ return False;
+
+ DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
for name %s IP %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
- BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
+ nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
+ BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -371,21 +377,21 @@ for name %s IP %s (bcast=%s) to IP %s\n",
static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *refresh_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -395,21 +401,21 @@ static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
static BOOL initiate_name_release_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *release_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -418,20 +424,20 @@ static BOOL initiate_name_release_packet( struct packet_struct *packet,
static BOOL initiate_node_status_packet( struct packet_struct *packet )
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
+ nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
- DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/****************************************************************************
@@ -447,12 +453,13 @@ static BOOL initiate_node_status_packet( struct packet_struct *packet )
static BOOL assert_check_subnet(struct subnet_record *subrec)
{
- if( subrec == remote_broadcast_subnet) {
- DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
+ if( subrec == remote_broadcast_subnet)
+ {
+ DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
This is a bug.\n"));
- return True;
- }
- return False;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -468,155 +475,101 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
struct nmb_name *nmbname,
uint16 nb_flags)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
- subrec->bcast_ip)) == NULL)
- return NULL;
-
- if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
-
-/****************************************************************************
- Queue a refresh name packet to the broadcast address of a subnet.
-****************************************************************************/
-
-void queue_wins_refresh(struct nmb_name *nmbname,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- uint16 nb_flags,
- struct in_addr refresh_ip,
- const char *tag)
-{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr wins_ip;
- struct userdata_struct *userdata;
- fstring ip_str;
-
- wins_ip = wins_srv_ip_tag(tag, refresh_ip);
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
- return;
- }
-
- if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- fstrcpy(ip_str, inet_ntoa(refresh_ip));
-
- DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
- nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
-
- userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
- if (!userdata) {
- DEBUG(0,("Failed to allocate userdata structure!\n"));
- return;
- }
- ZERO_STRUCTP(userdata);
- userdata->userdata_len = strlen(tag) + 1;
- strlcpy(userdata->data, tag, userdata->userdata_len);
-
- if ((rrec = make_response_record(unicast_subnet,
- p,
- resp_fn, timeout_fn,
- NULL,
- NULL,
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- free(userdata);
-
- /* we don't want to repeat refresh packets */
- rrec->repeat_count = 0;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ /* note that all name registration requests have RD set (rfc1002 -
+ section 4.2.2 */
+ if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_register_packet( p, nb_flags,
+ iface_ip(subrec->bcast_ip)) == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
-
/****************************************************************************
- Queue a multihomed register name packet to a given WINS server IP
+ Queue a multihomed register name packet to the broadcast address of a subnet.
****************************************************************************/
struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr register_ip,
- struct in_addr wins_ip)
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr register_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
- BOOL ret;
-
- /* Sanity check. */
- if(subrec != unicast_subnet) {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
+ struct packet_struct *p;
+ struct response_record *rrec;
+ BOOL ret;
+
+ /* Sanity check. */
+ if(subrec != unicast_subnet)
+ {
+ DEBUG(0,("queue_register_multihomed_name: should only be done on \
unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
+ return NULL;
+ }
- if(assert_check_subnet(subrec))
- return NULL;
+ if(assert_check_subnet(subrec))
+ return NULL;
- if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
- return NULL;
-
- if (nb_flags & NB_GROUP)
- ret = initiate_name_register_packet( p, nb_flags, &register_ip);
- else
- ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
-
- if (ret == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
+ if(( p = create_and_init_netbios_packet(nmbname, False, True,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if (nb_flags & NB_GROUP)
+ ret = initiate_name_register_packet( p, nb_flags, &register_ip);
+ else
+ ret = initiate_multihomed_name_register_packet( p, nb_flags, &register_ip);
+
+ if(ret == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
- if ((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -624,54 +577,102 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
****************************************************************************/
struct response_record *queue_release_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr release_ip,
- struct in_addr dest_ip)
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ release_name_success_function success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr release_ip)
+{
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_release_packet( p, nb_flags, &release_ip) == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ /*
+ * For a broadcast release packet, only send once.
+ * This will cause us to remove the name asap. JRA.
+ */
+
+ if (subrec != unicast_subnet) {
+ rrec->repeat_count = 0;
+ rrec->repeat_time = 0;
+ }
+
+ return rrec;
+}
+
+/****************************************************************************
+ Queue a refresh name packet to the broadcast address of a subnet.
+****************************************************************************/
+
+struct response_record *queue_refresh_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ refresh_name_success_function success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct name_record *namerec,
+ struct in_addr refresh_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
- return NULL;
-
- if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- /*
- * For a broadcast release packet, only send once.
- * This will cause us to remove the name asap. JRA.
- */
-
- if (subrec != unicast_subnet) {
- rrec->repeat_count = 0;
- rrec->repeat_time = 0;
- }
-
- return rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if(( p = create_and_init_netbios_packet(&namerec->name, (subrec != unicast_subnet), False,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if( !initiate_name_refresh_packet( p, namerec->data.nb_flags, &refresh_ip ) )
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -686,80 +687,61 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
struct userdata_struct *userdata,
struct nmb_name *nmbname)
{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr to_ip;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- to_ip = subrec->bcast_ip;
-
- /* queries to the WINS server turn up here as queries to IP 0.0.0.0
- These need to be handled a bit differently */
- if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
- /* What we really need to do is loop over each of our wins
- * servers and wins server tags here, but that just doesn't
- * fit our architecture at the moment (userdata may already
- * be used when we get here). For now we just query the first
- * active wins server on the first tag.
- */
- char **tags = wins_srv_tags();
- if (!tags) {
- return NULL;
- }
- to_ip = wins_srv_ip_tag(tags[0], to_ip);
- wins_srv_tags_free(tags);
- }
-
- if(( p = create_and_init_netbios_packet(nmbname,
- (subrec != unicast_subnet),
- (subrec == unicast_subnet),
- to_ip)) == NULL)
- return NULL;
-
- if(lp_bind_interfaces_only()) {
- int i;
-
- DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
- for(i = 0; i < iface_count(); i++) {
- struct in_addr *ifip = iface_n_ip(i);
-
- if(ifip == NULL) {
- DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
- continue;
- }
-
- if (ip_equal(*ifip,loopback_ip)) {
- DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
- continue;
- }
-
- DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
- p->fd = find_subnet_fd_for_address( *ifip );
- break;
- }
- }
-
- if(initiate_name_query_packet( p ) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if(( p = create_and_init_netbios_packet(nmbname,
+ (subrec != unicast_subnet),
+ (subrec == unicast_subnet),
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if(lp_bind_interfaces_only()) {
+ int i;
+
+ DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
+ for(i = 0; i < iface_count(); i++) {
+ struct in_addr *ifip = iface_n_ip(i);
+
+ if(ifip == NULL) {
+ DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
+ continue;
+ }
+
+ if (ip_equal(*ifip,loopback_ip)) {
+ DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
+ continue;
+ }
+
+ DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
+ p->fd = find_subnet_fd_for_address( *ifip );
+ break;
+ }
+ }
+
+ if(initiate_name_query_packet( p ) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -774,31 +756,33 @@ struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
struct userdata_struct *userdata,
struct nmb_name *nmbname)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
- return NULL;
-
- if(initiate_name_query_packet_from_wins_server( p ) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_query_packet_from_wins_server( p ) == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -814,41 +798,45 @@ struct response_record *queue_node_status( struct subnet_record *subrec,
struct nmb_name *nmbname,
struct in_addr send_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
- /* Sanity check. */
- if(subrec != unicast_subnet) {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
+ /* Sanity check. */
+ if(subrec != unicast_subnet)
+ {
+ DEBUG(0,("queue_register_multihomed_name: should only be done on \
unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
- return NULL;
-
- if(initiate_node_status_packet(p) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ return NULL;
+ }
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if(( p = create_and_init_netbios_packet(nmbname, False, False,
+ send_ip)) == NULL)
+ return NULL;
+
+ if(initiate_node_status_packet(p) == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -859,145 +847,169 @@ void reply_netbios_packet(struct packet_struct *orig_packet,
int rcode, enum netbios_reply_type_code rcv_code, int opcode,
int ttl, char *data,int len)
{
- struct packet_struct packet;
- struct nmb_packet *nmb = NULL;
- struct res_rec answers;
- struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
- BOOL loopback_this_packet = False;
- const char *packet_type = "unknown";
+ struct packet_struct packet;
+ struct nmb_packet *nmb = NULL;
+ struct res_rec answers;
+ struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
+ BOOL loopback_this_packet = False;
+ const char *packet_type = "unknown";
- /* Check if we are sending to or from ourselves. */
- if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
- loopback_this_packet = True;
+ /* Check if we are sending to or from ourselves. */
+ if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
+ loopback_this_packet = True;
- nmb = &packet.packet.nmb;
-
- /* Do a partial copy of the packet. We clear the locked flag and
- the resource record pointers. */
- packet = *orig_packet; /* Full structure copy. */
- packet.locked = False;
- nmb->answers = NULL;
- nmb->nsrecs = NULL;
- nmb->additional = NULL;
-
- switch (rcv_code) {
- case NMB_STATUS:
- packet_type = "nmb_status";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- case NMB_QUERY:
- packet_type = "nmb_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- case NMB_REG:
- case NMB_REG_REFRESH:
- packet_type = "nmb_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- case NMB_REL:
- packet_type = "nmb_rel";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- case NMB_WAIT_ACK:
- packet_type = "nmb_wack";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- case WINS_REG:
- packet_type = "wins_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- case WINS_QUERY:
- packet_type = "wins_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- default:
- DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
- packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip)));
- return;
- }
-
- DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
-for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
-
- nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
- nmb->header.opcode = opcode;
- nmb->header.response = True;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = True;
+ nmb = &packet.packet.nmb;
+
+ /* Do a partial copy of the packet. We clear the locked flag and
+ the resource record pointers. */
+ packet = *orig_packet; /* Full structure copy. */
+ packet.locked = False;
+ nmb->answers = NULL;
+ nmb->nsrecs = NULL;
+ nmb->additional = NULL;
+
+ switch (rcv_code)
+ {
+ case NMB_STATUS:
+ {
+ packet_type = "nmb_status";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ }
+ case NMB_QUERY:
+ {
+ packet_type = "nmb_query";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ }
+ case NMB_REG:
+ case NMB_REG_REFRESH:
+ {
+ packet_type = "nmb_reg";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ }
+ case NMB_REL:
+ {
+ packet_type = "nmb_rel";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ }
+ case NMB_WAIT_ACK:
+ {
+ packet_type = "nmb_wack";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ }
+ case WINS_REG:
+ {
+ packet_type = "wins_reg";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ }
+ case WINS_QUERY:
+ {
+ packet_type = "wins_query";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ }
+
+ default:
+ {
+ DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
+ packet_type, nmb_namestr(&orig_nmb->question.question_name),
+ inet_ntoa(packet.ip)));
+
+ return;
+ }
+ }
+
+ DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
+for id %hu\n",
+ packet_type, nmb_namestr(&orig_nmb->question.question_name),
+ inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
+
+ nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
+ nmb->header.opcode = opcode;
+ nmb->header.response = True;
+ nmb->header.nm_flags.bcast = False;
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = True;
- nmb->header.rcode = rcode;
- nmb->header.qdcount = 0;
- nmb->header.ancount = 1;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
+ nmb->header.rcode = rcode;
+ nmb->header.qdcount = 0;
+ nmb->header.ancount = 1;
+ nmb->header.nscount = 0;
+ nmb->header.arcount = 0;
- memset((char*)&nmb->question,'\0',sizeof(nmb->question));
+ memset((char*)&nmb->question,'\0',sizeof(nmb->question));
- nmb->answers = &answers;
- memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
+ nmb->answers = &answers;
+ memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
- nmb->answers->rr_name = orig_nmb->question.question_name;
- nmb->answers->rr_type = orig_nmb->question.question_type;
- nmb->answers->rr_class = orig_nmb->question.question_class;
- nmb->answers->ttl = ttl;
+ nmb->answers->rr_name = orig_nmb->question.question_name;
+ nmb->answers->rr_type = orig_nmb->question.question_type;
+ nmb->answers->rr_class = orig_nmb->question.question_class;
+ nmb->answers->ttl = ttl;
- if (data && len) {
- nmb->answers->rdlength = len;
- memcpy(nmb->answers->rdata, data, len);
- }
+ if (data && len)
+ {
+ nmb->answers->rdlength = len;
+ memcpy(nmb->answers->rdata, data, len);
+ }
- packet.packet_type = NMB_PACKET;
- /* Ensure we send out on the same fd that the original
- packet came in on to give the correct source IP address. */
- packet.fd = orig_packet->fd;
- packet.timestamp = time(NULL);
+ packet.packet_type = NMB_PACKET;
+ /* Ensure we send out on the same fd that the original
+ packet came in on to give the correct source IP address. */
+ packet.fd = orig_packet->fd;
+ packet.timestamp = time(NULL);
- debug_nmb_packet(&packet);
+ debug_nmb_packet(&packet);
- if(loopback_this_packet) {
- struct packet_struct *lo_packet;
- DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&packet)) == NULL)
- return;
- queue_packet(lo_packet);
- } else if (!send_packet(&packet)) {
- DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
- inet_ntoa(packet.ip),packet.port));
- }
+ if(loopback_this_packet)
+ {
+ struct packet_struct *lo_packet;
+ DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(&packet)) == NULL)
+ return;
+ queue_packet(lo_packet);
+ }
+ else if (!send_packet(&packet))
+ {
+ DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
+ inet_ntoa(packet.ip),packet.port));
+ }
}
/*******************************************************************
Queue a packet into a packet queue
******************************************************************/
-
static void queue_packet(struct packet_struct *packet)
{
- struct packet_struct *p;
-
- if (!packet_queue) {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
+ struct packet_struct *p;
+
+ if (!packet_queue)
+ {
+ packet->prev = NULL;
+ packet->next = NULL;
+ packet_queue = packet;
+ return;
+ }
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
- ;
+ /* find the bottom */
+ for (p=packet_queue;p->next;p=p->next)
+ ;
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
+ p->next = packet;
+ packet->next = NULL;
+ packet->prev = p;
}
/****************************************************************************
@@ -1006,153 +1018,186 @@ static void queue_packet(struct packet_struct *packet)
static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
{
- struct subnet_record *subrec;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If the subnet record is the remote announce broadcast subnet,
- hack it here to be the first subnet. This is really gross and
- is needed due to people turning on port 137/138 broadcast
- forwarding on their routers. May fire and brimstone rain
- down upon them...
- */
-
- return FIRST_SUBNET;
+ struct subnet_record *subrec;
+
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ return subrec;
+ }
+
+ /* If the subnet record is the remote announce broadcast subnet,
+ hack it here to be the first subnet. This is really gross and
+ is needed due to people turning on port 137/138 broadcast
+ forwarding on their routers. May fire and brimstone rain
+ down upon them...
+ */
+
+ return FIRST_SUBNET;
}
/****************************************************************************
Dispatch a browse frame from port 138 to the correct processing function.
****************************************************************************/
-
static void process_browse_packet(struct packet_struct *p, char *buf,int len)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = CVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
- char scope[64];
- unstring src_name;
-
- /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
- pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
- if (!strequal(scope, global_scope())) {
- DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
- return;
- }
-
- pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
- if (is_myname(src_name)) {
- DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int command = CVAL(buf,0);
+ struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
+ extern pstring global_scope;
+
+ /* Drop the packet if it's a different NetBIOS scope, or
+ the source is from one of our names. */
+
+ if (!strequal(dgram->dest_name.scope, global_scope))
+ {
+ DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
+ return;
+ }
+
+ if (is_myname(dgram->source_name.name))
+ {
+ DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command) {
- case ANN_HostAnnouncement:
- debug_browse_data(buf, len);
- process_host_announce(subrec, p, buf+1);
- break;
- case ANN_DomainAnnouncement:
- debug_browse_data(buf, len);
- process_workgroup_announce(subrec, p, buf+1);
- break;
- case ANN_LocalMasterAnnouncement:
- debug_browse_data(buf, len);
- process_local_master_announce(subrec, p, buf+1);
- break;
- case ANN_AnnouncementRequest:
- debug_browse_data(buf, len);
- process_announce_request(subrec, p, buf+1);
- break;
- case ANN_Election:
- debug_browse_data(buf, len);
- process_election(subrec, p, buf+1);
- break;
- case ANN_GetBackupListReq:
- debug_browse_data(buf, len);
- process_get_backup_list_request(subrec, p, buf+1);
- break;
- case ANN_GetBackupListResp:
- debug_browse_data(buf, len);
- /* We never send ANN_GetBackupListReq so we should never get these. */
- DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
+ return;
+ }
+
+ switch (command)
+ {
+ case ANN_HostAnnouncement:
+ {
+ debug_browse_data(buf, len);
+ process_host_announce(subrec, p, buf+1);
+ break;
+ }
+ case ANN_DomainAnnouncement:
+ {
+ debug_browse_data(buf, len);
+ process_workgroup_announce(subrec, p, buf+1);
+ break;
+ }
+ case ANN_LocalMasterAnnouncement:
+ {
+ debug_browse_data(buf, len);
+ process_local_master_announce(subrec, p, buf+1);
+ break;
+ }
+ case ANN_AnnouncementRequest:
+ {
+ debug_browse_data(buf, len);
+ process_announce_request(subrec, p, buf+1);
+ break;
+ }
+ case ANN_Election:
+ {
+ debug_browse_data(buf, len);
+ process_election(subrec, p, buf+1);
+ break;
+ }
+ case ANN_GetBackupListReq:
+ {
+ debug_browse_data(buf, len);
+ process_get_backup_list_request(subrec, p, buf+1);
+ break;
+ }
+ case ANN_GetBackupListResp:
+ {
+ debug_browse_data(buf, len);
+ /* We never send ANN_GetBackupListReq so we
+ should never get these. */
+ DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
- break;
- case ANN_ResetBrowserState:
- debug_browse_data(buf, len);
- process_reset_browser(subrec, p, buf+1);
- break;
- case ANN_MasterAnnouncement:
- /* Master browser datagrams must be processed on the unicast subnet. */
- subrec = unicast_subnet;
-
- debug_browse_data(buf, len);
- process_master_browser_announce(subrec, p, buf+1);
- break;
- case ANN_BecomeBackup:
- /*
- * We don't currently implement this. Log it just in case.
- */
- debug_browse_data(buf, len);
- DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
-command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- break;
- default:
- debug_browse_data(buf, len);
- DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- break;
- }
+ break;
+ }
+ case ANN_ResetBrowserState:
+ {
+ debug_browse_data(buf, len);
+ process_reset_browser(subrec, p, buf+1);
+ break;
+ }
+ case ANN_MasterAnnouncement:
+ {
+ /* Master browser datagrams must be processed
+ on the unicast subnet. */
+ subrec = unicast_subnet;
+
+ debug_browse_data(buf, len);
+ process_master_browser_announce(subrec, p, buf+1);
+ break;
+ }
+ case ANN_BecomeBackup:
+ {
+ /*
+ * We don't currently implement this. Log it just in case.
+ */
+ debug_browse_data(buf, len);
+ DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
+command ANN_BecomeBackup from %s IP %s to %s\n",
+ subrec->subnet_name, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ break;
+ }
+ default:
+ {
+ debug_browse_data(buf, len);
+ DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
+command code %d from %s IP %s to %s\n",
+ subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ }
+ }
}
/****************************************************************************
Dispatch a LanMan browse frame from port 138 to the correct processing function.
****************************************************************************/
-
static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = SVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
- char scope[64];
- unstring src_name;
-
- /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
-
- pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
- if (!strequal(scope, global_scope())) {
- DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
- return;
- }
-
- pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
- if (is_myname(src_name)) {
- DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int command = SVAL(buf,0);
+ struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
+ extern pstring global_scope;
+
+ /* Drop the packet if it's a different NetBIOS scope, or
+ the source is from one of our names. */
+
+ if (!strequal(dgram->dest_name.scope, global_scope))
+ {
+ DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
+ return;
+ }
+
+ if (is_myname(dgram->source_name.name))
+ {
+ DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command) {
- case ANN_HostAnnouncement:
- debug_browse_data(buf, len);
- process_lm_host_announce(subrec, p, buf+1);
- break;
- case ANN_AnnouncementRequest:
- process_lm_announce_request(subrec, p, buf+1);
- break;
- default:
- DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- break;
- }
+ return;
+ }
+
+ switch (command)
+ {
+ case ANN_HostAnnouncement:
+ {
+ debug_browse_data(buf, len);
+ process_lm_host_announce(subrec, p, buf+1);
+ break;
+ }
+ case ANN_AnnouncementRequest:
+ {
+ process_lm_announce_request(subrec, p, buf+1);
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
+command code %d from %s IP %s to %s\n",
+ subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ }
+ }
}
/****************************************************************************
@@ -1163,94 +1208,104 @@ command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namest
static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
{
- struct subnet_record *subrec = NULL;
+ struct subnet_record *subrec = NULL;
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ break;
+ }
- if(subrec == NULL)
- subrec = unicast_subnet;
+ if(subrec == NULL)
+ subrec = unicast_subnet;
- return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
+ return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
}
/****************************************************************************
Process udp 138 datagrams
****************************************************************************/
-
static void process_dgram(struct packet_struct *p)
{
- char *buf;
- char *buf2;
- int len;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- /* If we aren't listening to the destination name then ignore the packet */
- if (!listening(p,&dgram->dest_name)) {
- unexpected_packet(p);
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
- return;
- }
-
- if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
- unexpected_packet(p);
- /* Don't process error packets etc yet */
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
-an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
- return;
- }
-
- buf = &dgram->data[0];
- buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
-
- if (CVAL(buf,smb_com) != SMBtrans)
- return;
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- if (len <= 0)
- return;
-
- if (buf2 + len > buf + sizeof(dgram->data)) {
- DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
- nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),len));
- len = (buf + sizeof(dgram->data)) - buf;
- }
-
- DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
+ char *buf;
+ char *buf2;
+ int len;
+ struct dgram_packet *dgram = &p->packet.dgram;
+
+ /* If we aren't listening to the destination name then ignore the packet */
+ if (!listening(p,&dgram->dest_name))
+ {
+ unexpected_packet(p);
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
+ return;
+ }
+
+ if (dgram->header.msg_type != 0x10 &&
+ dgram->header.msg_type != 0x11 &&
+ dgram->header.msg_type != 0x12)
+ {
+ unexpected_packet(p);
+ /* Don't process error packets etc yet */
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
+an error packet of type %x\n",
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
+ return;
+ }
+
+ buf = &dgram->data[0];
+ buf -= 4; /* XXXX for the pseudo tcp length -
+ someday I need to get rid of this */
+
+ if (CVAL(buf,smb_com) != SMBtrans)
+ return;
+
+ len = SVAL(buf,smb_vwv11);
+ buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+
+ if (len <= 0)
+ return;
+
+ if (buf2 + len > buf + sizeof(dgram->data)) {
+ DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
-
- /* Datagram packet received for the browser mailslot */
- if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
- process_browse_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the LAN Manager mailslot */
- if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
- process_lanman_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the domain logon mailslot */
- if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
- process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
- return;
- }
-
- /* Datagram packet received for the NT domain logon mailslot */
- if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
- process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
- return;
- }
-
- unexpected_packet(p);
+ inet_ntoa(p->ip), smb_buf(buf),len));
+ len = (buf + sizeof(dgram->data)) - buf;
+ }
+
+ DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
+ nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
+ inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
+
+
+ /* Datagram packet received for the browser mailslot */
+ if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
+ {
+ process_browse_packet(p,buf2,len);
+ return;
+ }
+
+ /* Datagram packet received for the LAN Manager mailslot */
+ if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
+ process_lanman_packet(p,buf2,len);
+ return;
+ }
+
+ /* Datagram packet received for the domain logon mailslot */
+ if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT))
+ {
+ process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
+ return;
+ }
+
+ /* Datagram packet received for the NT domain logon mailslot */
+ if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT))
+ {
+ process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
+ return;
+ }
+
+ unexpected_packet(p);
}
/****************************************************************************
@@ -1259,49 +1314,52 @@ an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip),
static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
-
- switch (nmb->header.opcode) {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if (nmb->header.ancount == 0) {
- DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
- DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.ancount == 0) {
- DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_WACK_OPCODE:
- /* Check WACK response here. */
- if (nmb->header.ancount != 1) {
- DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
+ BOOL ignore = False;
+
+ switch (nmb->header.opcode)
+ {
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ if (nmb->header.ancount == 0)
+ {
+ DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1))
+ {
+ DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
+ ignore = True;
+ }
+ break;
+ case NMB_NAME_RELEASE_OPCODE:
+ if (nmb->header.ancount == 0)
+ {
+ DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
+ ignore = True;
+ }
+ break;
+ case NMB_WACK_OPCODE:
+ /* Check WACK response here. */
+ if (nmb->header.ancount != 1)
+ {
+ DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
+ ignore = True;
+ }
+ break;
+ default:
+ DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
+ nmb->header.opcode));
+ return True;
+ }
+
+ if(ignore)
+ DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
+
+ return ignore;
}
/****************************************************************************
@@ -1310,43 +1368,48 @@ static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
static BOOL validate_nmb_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
-
- switch (nmb->header.opcode) {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
- DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
- (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
- DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
- DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
+ BOOL ignore = False;
+
+ switch (nmb->header.opcode)
+ {
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ if (nmb->header.qdcount==0 || nmb->header.arcount==0)
+ {
+ DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ if ((nmb->header.qdcount == 0) ||
+ ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
+ (nmb->question.question_type != QUESTION_TYPE_NB_STATUS)))
+ {
+ DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_RELEASE_OPCODE:
+ if (nmb->header.qdcount==0 || nmb->header.arcount==0)
+ {
+ DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
+ ignore = True;
+ }
+ break;
+ default:
+ DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
+ nmb->header.opcode));
+ return True;
+ }
+
+ if(ignore)
+ DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
+
+ return ignore;
}
/****************************************************************************
@@ -1356,53 +1419,58 @@ static BOOL validate_nmb_packet( struct nmb_packet *nmb )
static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
struct response_record **pprrec)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct response_record *rrec = NULL;
- struct subnet_record *subrec = NULL;
-
- if(pprrec != NULL)
- *pprrec = NULL;
-
- if(nmb->header.response) {
- /* It's a response packet. Find a record for it or it's an error. */
-
- rrec = find_response_record( &subrec, nmb->header.name_trn_id);
- if(rrec == NULL) {
- DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
- nmb->header.name_trn_id));
- unexpected_packet(p);
- return NULL;
- }
-
- if(subrec == NULL) {
- DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
- nmb->header.name_trn_id));
- return NULL;
- }
-
- if(pprrec != NULL)
- *pprrec = rrec;
- return subrec;
- }
-
- /* Try and see what subnet this packet belongs to. */
-
- /* WINS server ? */
- if(packet_is_for_wins_server(p))
- return wins_server_subnet;
-
- /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
- if(nmb->header.nm_flags.bcast == False)
- return unicast_subnet;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
- return remote_broadcast_subnet;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct response_record *rrec = NULL;
+ struct subnet_record *subrec = NULL;
+
+ if(pprrec != NULL)
+ *pprrec = NULL;
+
+ if(nmb->header.response)
+ {
+ /* It's a response packet. Find a record for it or it's an error. */
+
+ rrec = find_response_record( &subrec, nmb->header.name_trn_id);
+ if(rrec == NULL)
+ {
+ DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
+ nmb->header.name_trn_id));
+ unexpected_packet(p);
+ return NULL;
+ }
+
+ if(subrec == NULL)
+ {
+ DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
+ nmb->header.name_trn_id));
+ return NULL;
+ }
+
+ if(pprrec != NULL)
+ *pprrec = rrec;
+ return subrec;
+ }
+
+ /* Try and see what subnet this packet belongs to. */
+
+ /* WINS server ? */
+ if(packet_is_for_wins_server(p))
+ return wins_server_subnet;
+
+ /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
+ if(nmb->header.nm_flags.bcast == False)
+ return unicast_subnet;
+
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ return subrec;
+ }
+
+ /* If none match it must have been a directed broadcast - assign
+ the remote_broadcast_subnet. */
+ return remote_broadcast_subnet;
}
/****************************************************************************
@@ -1411,71 +1479,79 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
static void process_nmb_request(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
-
- debug_nmb_packet(p);
-
- /* Ensure we have a good packet. */
- if(validate_nmb_packet(nmb))
- return;
-
- /* Allocate a subnet to this packet - if we cannot - fail. */
- if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
- return;
-
- switch (nmb->header.opcode) {
- case NMB_NAME_REG_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_registration_request(subrec, p);
- else
- process_name_registration_request(subrec, p);
- break;
-
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9:
- if(subrec == wins_server_subnet)
- wins_process_name_refresh_request(subrec, p);
- else
- process_name_refresh_request(subrec, p);
- break;
-
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if(subrec == wins_server_subnet) {
- wins_process_multihomed_name_registration_request(subrec, p);
- } else {
- DEBUG(0,("process_nmb_request: Multihomed registration request must be \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct subnet_record *subrec = NULL;
+
+ debug_nmb_packet(p);
+
+ /* Ensure we have a good packet. */
+ if(validate_nmb_packet(nmb))
+ return;
+
+ /* Allocate a subnet to this packet - if we cannot - fail. */
+ if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
+ return;
+
+ switch (nmb->header.opcode)
+ {
+ case NMB_NAME_REG_OPCODE:
+ if(subrec == wins_server_subnet)
+ wins_process_name_registration_request(subrec, p);
+ else
+ process_name_registration_request(subrec, p);
+ break;
+
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9:
+ if(subrec == wins_server_subnet)
+ wins_process_name_refresh_request(subrec, p);
+ else
+ process_name_refresh_request(subrec, p);
+ break;
+
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ if(subrec == wins_server_subnet)
+ wins_process_multihomed_name_registration_request(subrec, p);
+ else
+ {
+ DEBUG(0,("process_nmb_request: Multihomed registration request must be \
directed at a WINS server.\n"));
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- switch (nmb->question.question_type) {
- case QUESTION_TYPE_NB_QUERY:
- if(subrec == wins_server_subnet)
- wins_process_name_query_request(subrec, p);
- else
- process_name_query_request(subrec, p);
- break;
- case QUESTION_TYPE_NB_STATUS:
- if(subrec == wins_server_subnet) {
- DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ switch (nmb->question.question_type)
+ {
+ case QUESTION_TYPE_NB_QUERY:
+ {
+ if(subrec == wins_server_subnet)
+ wins_process_name_query_request(subrec, p);
+ else
+ process_name_query_request(subrec, p);
+ break;
+ }
+ case QUESTION_TYPE_NB_STATUS:
+ {
+ if(subrec == wins_server_subnet)
+ {
+ DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
not allowed.\n"));
- break;
- } else {
- process_node_status_request(subrec, p);
- }
- break;
- }
- break;
+ break;
+ }
+ else
+ process_node_status_request(subrec, p);
+ break;
+ }
+ }
+ break;
- case NMB_NAME_RELEASE_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_release_request(subrec, p);
- else
- process_name_release_request(subrec, p);
- break;
- }
+ case NMB_NAME_RELEASE_OPCODE:
+ if(subrec == wins_server_subnet)
+ wins_process_name_release_request(subrec, p);
+ else
+ process_name_release_request(subrec, p);
+ break;
+ }
}
/****************************************************************************
@@ -1485,61 +1561,65 @@ not allowed.\n"));
static void process_nmb_response(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
- struct response_record *rrec = NULL;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct subnet_record *subrec = NULL;
+ struct response_record *rrec = NULL;
- debug_nmb_packet(p);
+ debug_nmb_packet(p);
- if(validate_nmb_response_packet(nmb))
- return;
+ if(validate_nmb_response_packet(nmb))
+ return;
- if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
- return;
+ if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
+ return;
- if(rrec == NULL) {
- DEBUG(0,("process_nmb_response: response packet received but no response record \
+ if(rrec == NULL)
+ {
+ DEBUG(0,("process_nmb_response: response packet received but no response record \
found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
- return;
- }
+ return;
+ }
- /* Increment the number of responses received for this record. */
- rrec->num_msgs++;
- /* Ensure we don't re-send the request. */
- rrec->repeat_count = 0;
+ /* Increment the number of responses received for this record. */
+ rrec->num_msgs++;
+ /* Ensure we don't re-send the request. */
+ rrec->repeat_count = 0;
- /* Call the response received function for this packet. */
- (*rrec->resp_fn)(subrec, rrec, p);
+ /* Call the response received function for this packet. */
+ (*rrec->resp_fn)(subrec, rrec, p);
}
+
/*******************************************************************
Run elements off the packet queue till its empty
******************************************************************/
void run_packet_queue(void)
{
- struct packet_struct *p;
-
- while ((p = packet_queue)) {
- packet_queue = p->next;
- if (packet_queue)
- packet_queue->prev = NULL;
- p->next = p->prev = NULL;
-
- switch (p->packet_type) {
- case NMB_PACKET:
- if(p->packet.nmb.header.response)
- process_nmb_response(p);
- else
- process_nmb_request(p);
- break;
-
- case DGRAM_PACKET:
- process_dgram(p);
- break;
- }
- free_packet(p);
- }
+ struct packet_struct *p;
+
+ while ((p = packet_queue))
+ {
+ packet_queue = p->next;
+ if (packet_queue)
+ packet_queue->prev = NULL;
+ p->next = p->prev = NULL;
+
+ switch (p->packet_type)
+ {
+ case NMB_PACKET:
+ if(p->packet.nmb.header.response)
+ process_nmb_response(p);
+ else
+ process_nmb_request(p);
+ break;
+
+ case DGRAM_PACKET:
+ process_dgram(p);
+ break;
+ }
+ free_packet(p);
+ }
}
/*******************************************************************
@@ -1552,54 +1632,66 @@ void run_packet_queue(void)
void retransmit_or_expire_response_records(time_t t)
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
- struct response_record *rrec, *nextrrec;
+ for (subrec = FIRST_SUBNET; subrec;
+ subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
+ {
+ struct response_record *rrec, *nextrrec;
- for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
- nextrrec = rrec->next;
+ for (rrec = subrec->responselist; rrec; rrec = nextrrec)
+ {
+ nextrrec = rrec->next;
- if (rrec->repeat_time <= t) {
- if (rrec->repeat_count > 0) {
- /* Resend while we have a non-zero repeat_count. */
- if(!send_packet(rrec->packet)) {
- DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
-to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
- }
- rrec->repeat_time = t + rrec->repeat_interval;
- rrec->repeat_count--;
- } else {
- DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
-on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
-
- /*
- * Check the flag in this record to prevent recursion if we end
- * up in this function again via the timeout function call.
- */
-
- if(!rrec->in_expiration_processing) {
-
- /*
- * Set the recursion protection flag in this record.
- */
-
- rrec->in_expiration_processing = True;
-
- /* Call the timeout function. This will deal with removing the
- timed out packet. */
- if(rrec->timeout_fn) {
- (*rrec->timeout_fn)(subrec, rrec);
- } else {
- /* We must remove the record ourself if there is
- no timeout function. */
- remove_response_record(subrec, rrec);
- }
- } /* !rrec->in_expitation_processing */
- } /* rrec->repeat_count > 0 */
- } /* rrec->repeat_time <= t */
- } /* end for rrec */
- } /* end for subnet */
+ if (rrec->repeat_time <= t)
+ {
+ if (rrec->repeat_count > 0)
+ {
+ /* Resend while we have a non-zero repeat_count. */
+ if(!send_packet(rrec->packet))
+ {
+ DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
+to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
+ subrec->subnet_name));
+ }
+ rrec->repeat_time += rrec->repeat_interval;
+ rrec->repeat_count--;
+ }
+ else
+ {
+ DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
+on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
+ subrec->subnet_name));
+
+ /*
+ * Check the flag in this record to prevent recursion if we end
+ * up in this function again via the timeout function call.
+ */
+
+ if(!rrec->in_expiration_processing)
+ {
+
+ /*
+ * Set the recursion protection flag in this record.
+ */
+
+ rrec->in_expiration_processing = True;
+
+ /* Call the timeout function. This will deal with removing the
+ timed out packet. */
+ if(rrec->timeout_fn)
+ (*rrec->timeout_fn)(subrec, rrec);
+ else
+ {
+ /* We must remove the record ourself if there is
+ no timeout function. */
+ remove_response_record(subrec, rrec);
+ }
+ } /* !rrec->in_expitation_processing */
+ } /* rrec->repeat_count > 0 */
+ } /* rrec->repeat_time <= t */
+ } /* end for rrec */
+ } /* end for subnet */
}
/****************************************************************************
@@ -1609,63 +1701,68 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
{
- int *sock_array = NULL;
- struct subnet_record *subrec = NULL;
- int count = 0;
- int num = 0;
- fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
-
- if(pset == NULL) {
- DEBUG(0,("create_listen_fdset: malloc fail !\n"));
- return True;
- }
-
- /* Check that we can add all the fd's we need. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- count++;
-
- if((count*2) + 2 > FD_SETSIZE) {
- DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
+ int *sock_array = NULL;
+ struct subnet_record *subrec = NULL;
+ int count = 0;
+ int num = 0;
+ fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
+
+ if(pset == NULL)
+ {
+ DEBUG(0,("create_listen_fdset: malloc fail !\n"));
+ return True;
+ }
+
+ /* Check that we can add all the fd's we need. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ count++;
+
+ if((count*2) + 2 > FD_SETSIZE)
+ {
+ DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
only use %d.\n", (count*2) + 2, FD_SETSIZE));
- return True;
- }
-
- if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL) {
- DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
- return True;
- }
-
- FD_ZERO(pset);
-
- /* Add in the broadcast socket on 137. */
- FD_SET(ClientNMB,pset);
- sock_array[num++] = ClientNMB;
-
- /* Add in the 137 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- FD_SET(subrec->nmb_sock,pset);
- sock_array[num++] = subrec->nmb_sock;
- }
-
- /* Add in the broadcast socket on 138. */
- FD_SET(ClientDGRAM,pset);
- sock_array[num++] = ClientDGRAM;
-
- /* Add in the 138 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- FD_SET(subrec->dgram_sock,pset);
- sock_array[num++] = subrec->dgram_sock;
- }
-
- *listen_number = (count*2) + 2;
-
- SAFE_FREE(*ppset);
- SAFE_FREE(*psock_array);
-
- *ppset = pset;
- *psock_array = sock_array;
+ return True;
+ }
+
+ if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
+ {
+ DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
+ return True;
+ }
+
+ FD_ZERO(pset);
+
+ /* Add in the broadcast socket on 137. */
+ FD_SET(ClientNMB,pset);
+ sock_array[num++] = ClientNMB;
+
+ /* Add in the 137 sockets on all the interfaces. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ FD_SET(subrec->nmb_sock,pset);
+ sock_array[num++] = subrec->nmb_sock;
+ }
+
+ /* Add in the broadcast socket on 138. */
+ FD_SET(ClientDGRAM,pset);
+ sock_array[num++] = ClientDGRAM;
+
+ /* Add in the 138 sockets on all the interfaces. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ FD_SET(subrec->dgram_sock,pset);
+ sock_array[num++] = subrec->dgram_sock;
+ }
+
+ *listen_number = (count*2) + 2;
+
+ SAFE_FREE(*ppset);
+ SAFE_FREE(*psock_array);
+
+ *ppset = pset;
+ *psock_array = sock_array;
- return False;
+ return False;
}
/****************************************************************************
@@ -1675,211 +1772,207 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
BOOL listen_for_packets(BOOL run_election)
{
- static fd_set *listen_set = NULL;
- static int listen_number = 0;
- static int *sock_array = NULL;
- int i;
-
- fd_set fds;
- int selrtn;
- struct timeval timeout;
+ static fd_set *listen_set = NULL;
+ static int listen_number = 0;
+ static int *sock_array = NULL;
+ int i;
+
+ fd_set fds;
+ int selrtn;
+ struct timeval timeout;
#ifndef SYNC_DNS
- int dns_fd;
+ int dns_fd;
#endif
- if(listen_set == NULL || rescan_listen_set) {
- if(create_listen_fdset(&listen_set, &sock_array, &listen_number)) {
- DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
- return True;
- }
- rescan_listen_set = False;
- }
+ if(listen_set == NULL || rescan_listen_set)
+ {
+ if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
+ {
+ DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
+ return True;
+ }
+ rescan_listen_set = False;
+ }
- memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
+ memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
#ifndef SYNC_DNS
- dns_fd = asyncdns_fd();
- if (dns_fd != -1) {
- FD_SET(dns_fd, &fds);
- }
+ dns_fd = asyncdns_fd();
+ if (dns_fd != -1) {
+ FD_SET(dns_fd, &fds);
+ }
#endif
- /*
- * During elections and when expecting a netbios response packet we
- * need to send election packets at tighter intervals.
- * Ideally it needs to be the interval (in ms) between time now and
- * the time we are expecting the next netbios packet.
- */
- timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
+ /*
+ * During elections and when expecting a netbios response packet we
+ * need to send election packets at tighter intervals.
+ * Ideally it needs to be the interval (in ms) between time now and
+ * the time we are expecting the next netbios packet.
+ */
+
+ timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
+ timeout.tv_usec = 0;
- /* Prepare for the select - allow certain signals. */
+ /* Prepare for the select - allow certain signals. */
- BlockSignals(False, SIGTERM);
+ BlockSignals(False, SIGTERM);
- selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
+ selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
- /* We can only take signals when we are in the select - block them again here. */
+ /* We can only take signals when we are in the select - block them again here. */
- BlockSignals(True, SIGTERM);
+ BlockSignals(True, SIGTERM);
- if(selrtn == -1) {
- return False;
- }
+ if(selrtn == -1) {
+ return False;
+ }
#ifndef SYNC_DNS
- if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
- run_dns_queue();
- }
+ if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
+ run_dns_queue();
+ }
#endif
- for(i = 0; i < listen_number; i++) {
- if (i < (listen_number/2)) {
- /* Processing a 137 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == global_nmb_port &&
- packet->packet.nmb.header.nm_flags.bcast) {
- DEBUG(7,("discarding own bcast packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } else {
- /* Processing a 138 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
- DEBUG(7,("discarding own dgram packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } /* end processing 138 socket. */
- } /* end for */
- return False;
+ for(i = 0; i < listen_number; i++) {
+ if (i < (listen_number/2)) {
+ /* Processing a 137 socket. */
+ if (FD_ISSET(sock_array[i],&fds)) {
+ struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
+ if (packet) {
+ /*
+ * If we got a packet on the broadcast socket and interfaces
+ * only is set then check it came from one of our local nets.
+ */
+ if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
+ (!is_local_net(packet->ip))) {
+ DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else if (ip_equal(loopback_ip, packet->ip) && packet->port == global_nmb_port) {
+ DEBUG(7,("discarding own packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else {
+ /* Save the file descriptor this packet came in on. */
+ packet->fd = sock_array[i];
+ queue_packet(packet);
+ }
+ }
+ }
+ } else {
+ /* Processing a 138 socket. */
+ if (FD_ISSET(sock_array[i],&fds)) {
+ struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
+ if (packet) {
+ /*
+ * If we got a packet on the broadcast socket and interfaces
+ * only is set then check it came from one of our local nets.
+ */
+ if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
+ (!is_local_net(packet->ip))) {
+ DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else if ((ip_equal(loopback_ip, packet->ip) ||
+ ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
+ DEBUG(7,("discarding own packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else {
+ /* Save the file descriptor this packet came in on. */
+ packet->fd = sock_array[i];
+ queue_packet(packet);
+ }
+ }
+ }
+ } /* end processing 138 socket. */
+ } /* end for */
+ return False;
}
/****************************************************************************
Construct and send a netbios DGRAM.
**************************************************************************/
-
-BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
+BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf,int len,
const char *srcname, int src_type,
const char *dstname, int dest_type,
struct in_addr dest_ip,struct in_addr src_ip,
int dest_port)
{
- BOOL loopback_this_packet = False;
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
-
- memset((char *)&p,'\0',sizeof(p));
-
- if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
- loopback_this_packet = True;
-
- /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
-
- /* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = generate_name_trn_id();
- dgram->header.source_ip = src_ip;
- dgram->header.source_port = DGRAM_PORT;
- dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
- dgram->header.packet_offset = 0;
-
- make_nmb_name(&dgram->source_name,srcname,src_type);
- make_nmb_name(&dgram->dest_name,dstname,dest_type);
-
- ptr = &dgram->data[0];
-
- /* Setup the smb part. */
- ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,strlen(mailslot) + 1 + len,True);
- memcpy(ptr,tmp,4);
-
- SCVAL(ptr,smb_com,SMBtrans);
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
- p2 = skip_string(p2,1);
+ BOOL loopback_this_packet = False;
+ struct packet_struct p;
+ struct dgram_packet *dgram = &p.packet.dgram;
+ char *ptr,*p2;
+ char tmp[4];
+
+ memset((char *)&p,'\0',sizeof(p));
+
+ if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
+ loopback_this_packet = True;
+
+ /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
+
+ /* DIRECT GROUP or UNIQUE datagram. */
+ dgram->header.msg_type = unique ? 0x10 : 0x11;
+ dgram->header.flags.node_type = M_NODE;
+ dgram->header.flags.first = True;
+ dgram->header.flags.more = False;
+ dgram->header.dgm_id = generate_name_trn_id();
+ dgram->header.source_ip = src_ip;
+ dgram->header.source_port = DGRAM_PORT;
+ dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
+ dgram->header.packet_offset = 0;
- if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
- DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
- return False;
- } else {
- memcpy(p2,buf,len);
- p2 += len;
- }
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-
- p.ip = dest_ip;
- p.port = dest_port;
- p.fd = find_subnet_mailslot_fd_for_address( src_ip );
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
- nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
- DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
-
- debug_browse_data(buf, len);
-
- if(loopback_this_packet) {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&p)) == NULL)
- return False;
- queue_packet(lo_packet);
- return True;
- } else {
- return(send_packet(&p));
- }
+ make_nmb_name(&dgram->source_name,srcname,src_type);
+ make_nmb_name(&dgram->dest_name,dstname,dest_type);
+
+ ptr = &dgram->data[0];
+
+ /* Setup the smb part. */
+ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
+ memcpy(tmp,ptr,4);
+ set_message(ptr,17,17 + len,True);
+ memcpy(ptr,tmp,4);
+
+ SCVAL(ptr,smb_com,SMBtrans);
+ SSVAL(ptr,smb_vwv1,len);
+ SSVAL(ptr,smb_vwv11,len);
+ SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
+ SSVAL(ptr,smb_vwv13,3);
+ SSVAL(ptr,smb_vwv14,1);
+ SSVAL(ptr,smb_vwv15,1);
+ SSVAL(ptr,smb_vwv16,2);
+ p2 = smb_buf(ptr);
+ pstrcpy(p2,mailslot);
+ p2 = skip_string(p2,1);
+
+ memcpy(p2,buf,len);
+ p2 += len;
+
+ dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
+
+ p.ip = dest_ip;
+ p.port = dest_port;
+ p.fd = find_subnet_mailslot_fd_for_address( src_ip );
+ p.timestamp = time(NULL);
+ p.packet_type = DGRAM_PACKET;
+
+ DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
+ nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
+ DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
+
+ debug_browse_data(buf, len);
+
+ if(loopback_this_packet)
+ {
+ struct packet_struct *lo_packet = NULL;
+ DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(&p)) == NULL)
+ return False;
+ queue_packet(lo_packet);
+ return True;
+ }
+ else
+ return(send_packet(&p));
}
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index da93224043c..852c43f4b1d 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-2003
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,497 +26,269 @@
#include "includes.h"
-struct sam_database_info {
- uint32 index;
- uint32 serial_lo, serial_hi;
- uint32 date_lo, date_hi;
-};
-
-/****************************************************************************
-Send a message to smbd to do a sam delta sync
-**************************************************************************/
-
-static void send_repl_message(uint32 low_serial)
-{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (!tdb) {
- DEBUG(3, ("send_repl_message(): failed to open connections "
- "database\n"));
- return;
- }
-
- DEBUG(3, ("sending replication message, serial = 0x%04x\n",
- low_serial));
-
- message_send_all(tdb, MSG_SMB_SAM_REPL, &low_serial,
- sizeof(low_serial), False, NULL);
-
- tdb_close(tdb);
-}
+extern pstring global_myname;
+extern fstring global_myworkgroup;
/****************************************************************************
Process a domain logon packet
**************************************************************************/
-void process_logon_packet(struct packet_struct *p, char *buf,int len,
+void process_logon_packet(struct packet_struct *p,char *buf,int len,
const char *mailslot)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- pstring my_name;
- fstring reply_name;
- pstring outbuf;
- int code;
- uint16 token = 0;
- uint32 ntversion = 0;
- uint16 lmnttoken = 0;
- uint16 lm20token = 0;
- uint32 domainsidsize;
- BOOL short_request = False;
- char *getdc;
- char *uniuser; /* Unicode user name. */
- pstring ascuser;
- char *unicomp; /* Unicode computer name. */
-
- memset(outbuf, 0, sizeof(outbuf));
-
- if (!lp_domain_logons()) {
- DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ pstring my_name;
+ fstring reply_name;
+ pstring outbuf;
+ int code;
+ uint16 token = 0;
+ uint32 ntversion = 0;
+ uint16 lmnttoken = 0;
+ uint16 lm20token = 0;
+ uint32 domainsidsize;
+ BOOL short_request = False;
+ char *getdc;
+ char *uniuser; /* Unicode user name. */
+ pstring ascuser;
+ char *unicomp; /* Unicode computer name. */
+
+ START_PROFILE(domain_logon);
+ memset(outbuf, 0, sizeof(outbuf));
+
+ if (!lp_domain_logons())
+ {
+ DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
logons are not enabled.\n", inet_ntoa(p->ip) ));
- return;
- }
-
- pstrcpy(my_name, global_myname());
-
- code = SVAL(buf,0);
- DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
-
- switch (code) {
- case 0:
- {
- fstring mach_str, user_str, getdc_str;
- char *q = buf + 2;
- char *machine = q;
- char *user = skip_string(machine,1);
-
- getdc = skip_string(user,1);
- q = skip_string(getdc,1);
- token = SVAL(q,3);
-
- fstrcpy(reply_name,my_name);
-
- pull_ascii_fstring(mach_str, machine);
- pull_ascii_fstring(user_str, user);
- pull_ascii_fstring(getdc_str, getdc);
-
- DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
- mach_str,inet_ntoa(p->ip),user_str,token));
-
- q = outbuf;
- SSVAL(q, 0, 6);
- q += 2;
-
- fstrcpy(reply_name, "\\\\");
- fstrcat(reply_name, my_name);
- push_ascii_fstring(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
-
- SSVAL(q, 0, token);
- q += 2;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc_str,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- mach_str,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- case QUERYFORPDC:
- {
- fstring mach_str, getdc_str;
- fstring source_name;
- char *q = buf + 2;
- char *machine = q;
-
- if (!lp_domain_master()) {
- /* We're not Primary Domain Controller -- ignore this */
- return;
- }
-
- getdc = skip_string(machine,1);
- q = skip_string(getdc,1);
- q = ALIGN2(q, buf);
-
- /* At this point we can work out if this is a W9X or NT style
- request. Experiments show that the difference is wether the
- packet ends here. For a W9X request we now end with a pair of
- bytes (usually 0xFE 0xFF) whereas with NT we have two further
- strings - the following is a simple way of detecting this */
-
- if (len - PTR_DIFF(q, buf) <= 3) {
- short_request = True;
- } else {
- unicomp = q;
-
- /* A full length (NT style) request */
- q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
-
- if (len - PTR_DIFF(q, buf) > 8) {
- /* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
- int dom_len = CVAL(q, 0);
- q++;
- if (dom_len != 0) {
- q += dom_len + 1;
- }
- q += 16;
- }
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- }
-
- /* Construct reply. */
- q = outbuf;
- SSVAL(q, 0, QUERYFORPDC_R);
- q += 2;
-
- fstrcpy(reply_name,my_name);
- push_ascii_fstring(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
-
- /* PDC and domain name */
- if (!short_request) {
- /* Make a full reply */
- q = ALIGN2(q, outbuf);
-
- q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); /* Domain name*/
- SIVAL(q, 0, 1); /* our nt version */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
- }
-
- /* RJS, 21-Feb-2000, we send a short reply if the request was short */
-
- pull_ascii_fstring(mach_str, machine);
-
- DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, \
-reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
- mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(),
- QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
- (uint32)lm20token ));
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- pull_ascii_fstring(getdc_str, getdc);
- pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
-
- send_mailslot(True, getdc_str,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- source_name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- return;
- }
-
- case SAMLOGON:
-
- {
- fstring getdc_str;
- fstring source_name;
- char *q = buf + 2;
- fstring asccomp;
-
- q += 2;
- unicomp = q;
- uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
- getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
- q = skip_string(getdc,1);
- q += 4; /* Account Control Bits - indicating username type */
- domainsidsize = IVAL(q, 0);
- q += 4;
-
- DEBUG(5,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len));
-
- if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
- q += domainsidsize;
- q = ALIGN4(q, buf);
- }
-
- DEBUG(5,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) ));
-
- if (len - PTR_DIFF(q, buf) > 8) {
+ goto done;
+ }
+
+ pstrcpy(my_name, global_myname);
+ strupper(my_name);
+
+ code = SVAL(buf,0);
+ DEBUG(1,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
+
+ switch (code)
+ {
+ case 0:
+ {
+ char *q = buf + 2;
+ char *machine = q;
+ char *user = skip_string(machine,1);
+
+ getdc = skip_string(user,1);
+ q = skip_string(getdc,1);
+ token = SVAL(q,3);
+
+ fstrcpy(reply_name,my_name);
+
+ DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
+ machine,inet_ntoa(p->ip),user,token));
+
+ q = outbuf;
+ SSVAL(q, 0, 6);
+ q += 2;
+
+ fstrcpy(reply_name, "\\\\");
+ fstrcat(reply_name, my_name);
+ fstrcpy(q, reply_name); q = skip_string(q, 1); /* PDC name */
+
+ SSVAL(q, 0, token);
+ q += 2;
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname, 0x0,
+ machine,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
+
+ case QUERYFORPDC:
+ {
+ char *q = buf + 2;
+ char *machine = q;
+
+ if (!lp_domain_master())
+ {
+ /* We're not Primary Domain Controller -- ignore this */
+ goto done;
+ }
+
+ getdc = skip_string(machine,1);
+ q = skip_string(getdc,1);
+ q = ALIGN2(q, buf);
+
+ /* at this point we can work out if this is a W9X or NT style
+ request. Experiments show that the difference is wether the
+ packet ends here. For a W9X request we now end with a pair of
+ bytes (usually 0xFE 0xFF) whereas with NT we have two further
+ strings - the following is a simple way of detecting this */
+ if (len - PTR_DIFF(q, buf) <= 3) {
+ short_request = True;
+ } else {
+ unicomp = q;
+
+ /* A full length (NT style) request */
+ q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
+
+ if (len - PTR_DIFF(q, buf) > 8) {
/* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
+ get additional data - a length specificed string
+ containing the domain name, then 16 bytes of
+ data (no idea what it is) */
int dom_len = CVAL(q, 0);
q++;
- if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
+ if (dom_len != 0) {
q += dom_len + 1;
}
q += 16;
- }
-
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- q += 8;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
-
- /*
- * we respond regadless of whether the machine is in our password
- * database. If it isn't then we let smbd send an appropriate error.
- * Let's ignore the SID.
- */
- pull_ucs2_pstring(ascuser, uniuser);
- pull_ucs2_fstring(asccomp, unicomp);
- DEBUG(5,("process_logon_packet: SAMLOGON user %s\n", ascuser));
-
- fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
- fstrcat(reply_name, my_name);
-
- DEBUG(5,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
- asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
- SAMLOGON_R ,lmnttoken));
-
- /* Construct reply. */
-
- q = outbuf;
- /* we want the simple version unless we are an ADS PDC..which means */
- /* never, at least for now */
- if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_R);
- }
-
- q += 2;
-
- q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
- q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True);
- }
-#ifdef HAVE_ADS
- else {
- struct uuid domain_guid;
- UUID_FLAT flat_guid;
- pstring domain;
- pstring hostname;
- char *component, *dc, *q1;
- uint8 size;
- char *q_orig = q;
- int str_offset;
-
- get_mydnsdomname(domain);
- get_myname(hostname);
-
- if (SVAL(uniuser, 0) == 0) {
- SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
- } else {
- SIVAL(q, 0, SAMLOGON_AD_R);
- }
- q += 4;
-
- SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
- ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
- q += 4;
-
- /* Push Domain GUID */
- if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
- DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
- return;
- }
-
- smb_uuid_pack(domain_guid, &flat_guid);
- memcpy(q, &flat_guid.info, UUID_FLAT_SIZE);
- q += UUID_FLAT_SIZE;
-
- /* Forest */
- str_offset = q - q_orig;
- dc = domain;
- q1 = q;
- while ((component = strtok(dc, "."))) {
- dc = NULL;
- size = push_ascii(&q[1], component, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
-
- /* Unk0 */
- SCVAL(q, 0, 0);
- q++;
-
- /* Domain */
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- /* Hostname */
- size = push_ascii(&q[1], hostname, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- /* NETBIOS of domain */
- size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Unk1 */
- SCVAL(q, 0, 0);
- q++;
-
- /* NETBIOS of hostname */
- size = push_ascii(&q[1], my_name, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Unk2 */
- SCVAL(q, 0, 0);
- q++;
-
- /* User name */
- if (SVAL(uniuser, 0) != 0) {
- size = push_ascii(&q[1], ascuser, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
-
- q_orig = q;
- /* Site name */
- size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Site name (2) */
- str_offset = q - q_orig;
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- SCVAL(q, 0, PTR_DIFF(q,q1));
- SCVAL(q, 1, 0x10); /* unknown */
-
- SIVAL(q, 0, 0x00000002);
- q += 4; /* unknown */
- SIVAL(q, 0, (iface_ip(p->ip))->s_addr);
- q += 4;
- SIVAL(q, 0, 0x00000000);
- q += 4; /* unknown */
- SIVAL(q, 0, 0x00000000);
- q += 4; /* unknown */
- }
-#endif
-
- /* tell the client what version we are */
- SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
- /* our ntversion */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- pull_ascii_fstring(getdc_str, getdc);
- pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- source_name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- /* Announce change to UAS or SAM. Send by the domain controller when a
- replication event is required. */
-
- case SAM_UAS_CHANGE:
- {
- struct sam_database_info *db_info;
- char *q = buf + 2;
- int i, db_count;
- uint32 low_serial;
-
- /* Header */
-
- low_serial = IVAL(q, 0); q += 4; /* Low serial number */
-
- q += 4; /* Date/time */
- q += 4; /* Pulse */
- q += 4; /* Random */
-
- /* Domain info */
-
- q = skip_string(q, 1); /* PDC name */
- q = skip_string(q, 1); /* Domain name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */
-
- /* Database info */
-
- db_count = SVAL(q, 0); q += 2;
-
- db_info = (struct sam_database_info *)
- malloc(sizeof(struct sam_database_info) * db_count);
-
- if (db_info == NULL) {
- DEBUG(3, ("out of memory allocating info for %d databases\n", db_count));
- return;
- }
-
- for (i = 0; i < db_count; i++) {
- db_info[i].index = IVAL(q, 0);
- db_info[i].serial_lo = IVAL(q, 4);
- db_info[i].serial_hi = IVAL(q, 8);
- db_info[i].date_lo = IVAL(q, 12);
- db_info[i].date_hi = IVAL(q, 16);
- q += 20;
- }
-
- /* Domain SID */
-
-#if 0
- /* We must range check this. */
- q += IVAL(q, 0) + 4; /* 4 byte length plus data */
-
- q += 2; /* Alignment? */
-
- /* Misc other info */
-
- q += 4; /* NT version (0x1) */
- q += 2; /* LMNT token (0xff) */
- q += 2; /* LM20 token (0xff) */
-#endif
-
- SAFE_FREE(db_info); /* Not sure whether we need to do anything useful with these */
-
- /* Send message to smbd */
-
- send_repl_message(low_serial);
- break;
- }
-
- default:
- DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
- return;
- }
+ }
+ ntversion = IVAL(q, 0);
+ lmnttoken = SVAL(q, 4);
+ lm20token = SVAL(q, 6);
+ }
+
+ /* Construct reply. */
+ q = outbuf;
+ SSVAL(q, 0, QUERYFORPDC_R);
+ q += 2;
+
+ fstrcpy(reply_name,my_name);
+ fstrcpy(q, reply_name);
+ q = skip_string(q, 1); /* PDC name */
+
+ /* PDC and domain name */
+ if (!short_request) /* Make a full reply */
+ {
+ q = ALIGN2(q, outbuf);
+
+ q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */
+ q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True); /* Domain name*/
+
+ SIVAL(q, 0, 1); /* our nt version */
+ SSVAL(q, 4, 0xffff); /* our lmnttoken */
+ SSVAL(q, 6, 0xffff); /* our lm20token */
+ q += 8;
+ }
+
+ /* RJS, 21-Feb-2000, we send a short reply if the request was short */
+
+ DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \
+reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
+ machine,inet_ntoa(p->ip), reply_name, global_myworkgroup,
+ QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
+ (uint32)lm20token ));
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname, 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ goto done;
+ }
+
+ case SAMLOGON:
+ {
+ char *q = buf + 2;
+
+ q += 2;
+ unicomp = q;
+ uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
+ getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
+ q = skip_string(getdc,1);
+ q += 4; /* Account Control Bits - indicating username type */
+ domainsidsize = IVAL(q, 0);
+ q += 4;
+
+ DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len));
+
+ if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
+ q += domainsidsize;
+ q = ALIGN4(q, buf);
+ }
+
+ DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) ));
+
+ if (len - PTR_DIFF(q, buf) > 8) {
+ /* with NT5 clients we can sometimes
+ get additional data - a length specificed string
+ containing the domain name, then 16 bytes of
+ data (no idea what it is) */
+ int dom_len = CVAL(q, 0);
+ q++;
+ if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
+ q += dom_len + 1;
+ }
+ q += 16;
+ }
+
+ ntversion = IVAL(q, 0);
+ lmnttoken = SVAL(q, 4);
+ lm20token = SVAL(q, 6);
+ q += 8;
+
+ DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
+
+ /*
+ * we respond regadless of whether the machine is in our password
+ * database. If it isn't then we let smbd send an appropriate error.
+ * Let's ignore the SID.
+ */
+
+ pstrcpy(ascuser, dos_unistr(uniuser));
+ DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
+
+ fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
+ fstrcpy(reply_name+2,my_name);
+
+ DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
+ dos_unistr(unicomp),inet_ntoa(p->ip), ascuser, reply_name, global_myworkgroup,
+ SAMLOGON_R ,lmnttoken));
+
+ /* Construct reply. */
+
+ q = outbuf;
+ if (SVAL(uniuser, 0) == 0) {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ } else {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
+ q += 2;
+
+ q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
+ q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
+ q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
+
+ /* tell the client what version we are */
+ SIVAL(q, 0, 1); /* our ntversion */
+ SSVAL(q, 4, 0xffff); /* our lmnttoken */
+ SSVAL(q, 6, 0xffff); /* our lm20token */
+ q += 8;
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname, 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
+
+ default:
+ {
+ DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
+ goto done;
+ }
+ }
+done:
+ END_PROFILE(domain_logon);
}
diff --git a/source/nmbd/nmbd_responserecordsdb.c b/source/nmbd/nmbd_responserecordsdb.c
index 30c0c129508..63601ff26c4 100644
--- a/source/nmbd/nmbd_responserecordsdb.c
+++ b/source/nmbd/nmbd_responserecordsdb.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios library routines
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -34,26 +35,27 @@ int num_response_packets = 0;
static void add_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct response_record *rrec2;
+ struct response_record *rrec2;
- num_response_packets++; /* count of total number of packets still around */
+ num_response_packets++; /* count of total number of packets still around */
- DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
- rrec->response_id, subrec->subnet_name, num_response_packets));
+ DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
+ rrec->response_id, subrec->subnet_name, num_response_packets));
- if (!subrec->responselist) {
- subrec->responselist = rrec;
- rrec->prev = NULL;
- rrec->next = NULL;
- return;
- }
+ if (!subrec->responselist)
+ {
+ subrec->responselist = rrec;
+ rrec->prev = NULL;
+ rrec->next = NULL;
+ return;
+ }
- for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
- ;
+ for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
+ ;
- rrec2->next = rrec;
- rrec->next = NULL;
- rrec->prev = rrec2;
+ rrec2->next = rrec;
+ rrec->next = NULL;
+ rrec->prev = rrec2;
}
/***************************************************************************
@@ -63,31 +65,32 @@ static void add_response_record(struct subnet_record *subrec,
void remove_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- if (rrec->prev)
- rrec->prev->next = rrec->next;
- if (rrec->next)
- rrec->next->prev = rrec->prev;
-
- if (subrec->responselist == rrec)
- subrec->responselist = rrec->next;
-
- if(rrec->userdata) {
- if(rrec->userdata->free_fn) {
- (*rrec->userdata->free_fn)(rrec->userdata);
- } else {
- ZERO_STRUCTP(rrec->userdata);
- SAFE_FREE(rrec->userdata);
- }
- }
-
- /* Ensure we can delete. */
- rrec->packet->locked = False;
- free_packet(rrec->packet);
-
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
-
- num_response_packets--; /* count of total number of packets still around */
+ if (rrec->prev)
+ rrec->prev->next = rrec->next;
+ if (rrec->next)
+ rrec->next->prev = rrec->prev;
+
+ if (subrec->responselist == rrec)
+ subrec->responselist = rrec->next;
+
+ if(rrec->userdata)
+ {
+ if(rrec->userdata->free_fn) {
+ (*rrec->userdata->free_fn)(rrec->userdata);
+ } else {
+ ZERO_STRUCTP(rrec->userdata);
+ SAFE_FREE(rrec->userdata);
+ }
+ }
+
+ /* Ensure we can delete. */
+ rrec->packet->locked = False;
+ free_packet(rrec->packet);
+
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+
+ num_response_packets--; /* count of total number of packets still around */
}
/****************************************************************************
@@ -95,77 +98,84 @@ void remove_response_record(struct subnet_record *subrec,
**************************************************************************/
struct response_record *make_response_record( struct subnet_record *subrec,
- struct packet_struct *p,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- success_function success_fn,
- fail_function fail_fn,
- struct userdata_struct *userdata)
+ struct packet_struct *p,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ success_function success_fn,
+ fail_function fail_fn,
+ struct userdata_struct *userdata)
{
- struct response_record *rrec;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if (!(rrec = (struct response_record *)malloc(sizeof(*rrec)))) {
- DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
- return NULL;
- }
-
- memset((char *)rrec, '\0', sizeof(*rrec));
-
- rrec->response_id = nmb->header.name_trn_id;
-
- rrec->resp_fn = resp_fn;
- rrec->timeout_fn = timeout_fn;
- rrec->success_fn = success_fn;
- rrec->fail_fn = fail_fn;
-
- rrec->packet = p;
-
- if(userdata) {
- /* Intelligent userdata. */
- if(userdata->copy_fn) {
- if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL) {
- DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- } else {
- /* Primitive userdata, do a memcpy. */
- if((rrec->userdata = (struct userdata_struct *)
- malloc(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL) {
- DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- rrec->userdata->copy_fn = userdata->copy_fn;
- rrec->userdata->free_fn = userdata->free_fn;
- rrec->userdata->userdata_len = userdata->userdata_len;
- memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
- }
- } else {
- rrec->userdata = NULL;
- }
-
- rrec->num_msgs = 0;
-
- if(!nmb->header.nm_flags.bcast)
- rrec->repeat_interval = 5; /* 5 seconds for unicast packets. */
- else
- rrec->repeat_interval = 1; /* XXXX should be in ms */
- rrec->repeat_count = 3; /* 3 retries */
- rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
-
- /* This packet is not being processed. */
- rrec->in_expiration_processing = False;
-
- /* Lock the packet so we won't lose it while it's on the list. */
- p->locked = True;
-
- add_response_record(subrec, rrec);
-
- return rrec;
+ struct response_record *rrec;
+ struct nmb_packet *nmb = &p->packet.nmb;
+
+ if (!(rrec = (struct response_record *)malloc(sizeof(*rrec))))
+ {
+ DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
+ return NULL;
+ }
+
+ memset((char *)rrec, '\0', sizeof(*rrec));
+
+ rrec->response_id = nmb->header.name_trn_id;
+
+ rrec->resp_fn = resp_fn;
+ rrec->timeout_fn = timeout_fn;
+ rrec->success_fn = success_fn;
+ rrec->fail_fn = fail_fn;
+
+ rrec->packet = p;
+
+ if(userdata)
+ {
+ /* Intelligent userdata. */
+ if(userdata->copy_fn)
+ {
+ if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL)
+ {
+ DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+ return NULL;
+ }
+ }
+ else
+ {
+ /* Primitive userdata, do a memcpy. */
+ if((rrec->userdata = (struct userdata_struct *)
+ malloc(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL)
+ {
+ DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+ return NULL;
+ }
+ rrec->userdata->copy_fn = userdata->copy_fn;
+ rrec->userdata->free_fn = userdata->free_fn;
+ rrec->userdata->userdata_len = userdata->userdata_len;
+ memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
+ }
+ }
+ else
+ rrec->userdata = NULL;
+
+ rrec->num_msgs = 0;
+
+ if(!nmb->header.nm_flags.bcast)
+ rrec->repeat_interval = 5; /* 5 seconds for unicast packets. */
+ else
+ rrec->repeat_interval = 1; /* XXXX should be in ms */
+ rrec->repeat_count = 3; /* 3 retries */
+ rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
+
+ /* This packet is not being processed. */
+ rrec->in_expiration_processing = False;
+
+ /* Lock the packet so we won't lose it while it's on the list. */
+ p->locked = True;
+
+ add_response_record(subrec, rrec);
+
+ return rrec;
}
/****************************************************************************
@@ -175,16 +185,18 @@ struct response_record *make_response_record( struct subnet_record *subrec,
static struct response_record *find_response_record_on_subnet(
struct subnet_record *subrec, uint16 id)
{
- struct response_record *rrec = NULL;
-
- for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
- if (rrec->response_id == id) {
- DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
- id, subrec->subnet_name));
- break;
- }
- }
- return rrec;
+ struct response_record *rrec = NULL;
+
+ for (rrec = subrec->responselist; rrec; rrec = rrec->next)
+ {
+ if (rrec->response_id == id)
+ {
+ DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
+ id, subrec->subnet_name));
+ break;
+ }
+ }
+ return rrec;
}
/****************************************************************************
@@ -194,34 +206,37 @@ static struct response_record *find_response_record_on_subnet(
struct response_record *find_response_record(struct subnet_record **ppsubrec,
uint16 id)
{
- struct response_record *rrec = NULL;
-
- for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
- (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec)) {
- if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
- return rrec;
- }
-
- /* There should never be response records on the remote_broadcast subnet.
- Sanity check to ensure this is so. */
- if(remote_broadcast_subnet->responselist != NULL) {
- DEBUG(0,("find_response_record: response record found on subnet %s. This should \
+ struct response_record *rrec = NULL;
+
+ for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
+ (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec))
+ {
+ if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
+ return rrec;
+ }
+
+ /* There should never be response records on the remote_broadcast subnet.
+ Sanity check to ensure this is so. */
+ if(remote_broadcast_subnet->responselist != NULL)
+ {
+ DEBUG(0,("find_response_record: response record found on subnet %s. This should \
never happen !\n", remote_broadcast_subnet->subnet_name));
- }
+ }
- /* Now check the WINS server subnet if it exists. */
- if(wins_server_subnet != NULL) {
- *ppsubrec = wins_server_subnet;
- if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
- return rrec;
- }
+ /* Now check the WINS server subnet if it exists. */
+ if(wins_server_subnet != NULL)
+ {
+ *ppsubrec = wins_server_subnet;
+ if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
+ return rrec;
+ }
- DEBUG(0,("find_response_record: response packet id %hu received with no \
+ DEBUG(0,("find_response_record: response packet id %hu received with no \
matching record.\n", id));
- *ppsubrec = NULL;
+ *ppsubrec = NULL;
- return NULL;
+ return NULL;
}
/****************************************************************************
@@ -230,19 +245,21 @@ matching record.\n", id));
BOOL is_refresh_already_queued(struct subnet_record *subrec, struct name_record *namerec)
{
- struct response_record *rrec = NULL;
+ struct response_record *rrec = NULL;
- for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
- struct packet_struct *p = rrec->packet;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
- (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9)) {
- /* Yes it's a queued refresh - check if the name is correct. */
- if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
- return True;
- }
- }
-
- return False;
-}
+ for (rrec = subrec->responselist; rrec; rrec = rrec->next)
+ {
+ struct packet_struct *p = rrec->packet;
+ struct nmb_packet *nmb = &p->packet.nmb;
+
+ if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
+ (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9))
+ {
+ /* Yes it's a queued refresh - check if the name is correct. */
+ if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
+ return True;
+ }
+ }
+
+ return False;
+}
diff --git a/source/nmbd/nmbd_sendannounce.c b/source/nmbd/nmbd_sendannounce.c
index a74dd99196f..2437e11a9ee 100644
--- a/source/nmbd/nmbd_sendannounce.c
+++ b/source/nmbd/nmbd_sendannounce.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -26,6 +27,9 @@
#include "includes.h"
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
extern int updatecount;
extern BOOL found_lm_clients;
@@ -35,21 +39,21 @@ extern BOOL found_lm_clients;
void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip)
{
- pstring outbuf;
- char *p;
+ pstring outbuf;
+ char *p;
- DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
- reset_type, to_name, to_type, inet_ntoa(to_ip) ));
+ DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
+ reset_type, to_name, to_type, inet_ntoa(to_ip) ));
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_ResetBrowserState);
- p++;
- SCVAL(p,0,reset_type);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_ResetBrowserState);
+ p++;
+ SCVAL(p,0,reset_type);
+ p++;
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, to_name, to_type, to_ip,
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname, 0x0, to_name, to_type, to_ip,
FIRST_SUBNET->myip, DGRAM_PORT);
}
@@ -60,25 +64,27 @@ void send_browser_reset(int reset_type, const char *to_name, int to_type, struct
void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work)
{
- pstring outbuf;
- char *p;
+ pstring outbuf;
+ char *p;
- work->needannounce = True;
+ work->needannounce = True;
- DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
+ DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
to subnet %s\n", work->work_group, subrec->subnet_name));
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_AnnouncementRequest);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_AnnouncementRequest);
+ p++;
- SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
- p++;
- p += push_string(NULL, p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+ SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
+ p++;
+ StrnCpy(p,global_myname,15);
+ strupper(p);
+ p = skip_string(p,1);
- send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
+ send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname, 0x0, work->work_group,0x1e, subrec->bcast_ip,
subrec->myip, DGRAM_PORT);
}
@@ -91,36 +97,36 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
time_t announce_interval,
const char *server_name, int server_type, const char *server_comment)
{
- pstring outbuf;
- unstring upper_server_name;
- char *p;
+ pstring outbuf;
+ char *p;
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf+1;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf+1;
- SCVAL(outbuf,0,announce_type);
+ SCVAL(outbuf,0,announce_type);
- /* Announcement parameters. */
- SCVAL(p,0,updatecount);
- SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
+ /* Announcement parameters. */
+ SCVAL(p,0,updatecount);
+ SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
- safe_strcpy(upper_server_name, server_name, sizeof(upper_server_name)-1);
- strupper_m(upper_server_name);
- push_string(NULL, p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE);
+ StrnCpy(p+5,server_name,15);
+ strupper(p+5);
- SCVAL(p,21,lp_major_announce_version()); /* Major version. */
- SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
+ SCVAL(p,21,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
- SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
- SSVAL(p,27,BROWSER_ELECTION_VERSION);
- SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
+ SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
+ /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
+ SSVAL(p,27,BROWSER_ELECTION_VERSION);
+ SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
- p += 31 + push_string(NULL, p+31, server_comment, -1, STR_ASCII|STR_TERMINATE);
+ pstrcpy(p+31,server_comment);
+ p += 31;
+ p = skip_string(p,1);
- send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
- DGRAM_PORT);
+ send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
+ DGRAM_PORT);
}
/****************************************************************************
@@ -132,23 +138,26 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
time_t announce_interval,
char *server_name, int server_type, char *server_comment)
{
- pstring outbuf;
- char *p=outbuf;
-
- memset(outbuf,'\0',sizeof(outbuf));
-
- SSVAL(p,0,announce_type);
- SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- SCVAL(p,6,lp_major_announce_version()); /* Major version. */
- SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
- SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
-
- p += 10;
- p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
- p += push_string(NULL, p, server_comment, sizeof(pstring)-15, STR_ASCII|STR_UPPER|STR_TERMINATE);
-
- send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
+ pstring outbuf;
+ char *p=outbuf;
+
+ memset(outbuf,'\0',sizeof(outbuf));
+
+ SSVAL(p,0,announce_type);
+ SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
+ SCVAL(p,6,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
+ SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
+
+ p += 10;
+ StrnCpy(p,server_name,15);
+ strupper(p);
+ p = skip_string(p,1);
+ pstrcpy(p,server_comment);
+ p = skip_string(p,1);
+
+ send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
DGRAM_PORT);
}
@@ -159,20 +168,20 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Ensure we don't have the prohibited bit set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
- type, global_myname(), subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_LocalMasterAnnouncement,
- global_myname(), /* From nbt name. */
- work->work_group, 0x1e, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- global_myname(), /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bit set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
+ type, global_myname, subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_LocalMasterAnnouncement,
+ global_myname, /* From nbt name. */
+ work->work_group, 0x1e, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ global_myname, /* Name to announce. */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -181,17 +190,17 @@ static void send_local_master_announcement(struct subnet_record *subrec, struct
static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work)
{
- DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
- subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_DomainAnnouncement,
- global_myname(), /* From nbt name. */
- MSBROWSE, 0x1, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- work->work_group, /* Name to announce. */
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
- global_myname()); /* From name as comment. */
+ DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
+ subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_DomainAnnouncement,
+ global_myname, /* From nbt name. */
+ MSBROWSE, 0x1, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ work->work_group, /* Name to announce. */
+ SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
+ global_myname); /* From name as comment. */
}
/****************************************************************************
@@ -201,20 +210,20 @@ static void send_workgroup_announcement(struct subnet_record *subrec, struct wor
static void send_host_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x1d, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bits set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
+ type, servrec->serv.name, subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_HostAnnouncement,
+ servrec->serv.name, /* From nbt name. */
+ work->work_group, 0x1d, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ servrec->serv.name, /* Name to announce. */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -224,20 +233,20 @@ static void send_host_announcement(struct subnet_record *subrec, struct work_rec
static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec, int lm_interval)
{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
-
- send_lm_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x00, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- lm_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce (fstring not netbios name struct). */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bits set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
+ type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
+
+ send_lm_announcement(subrec, ANN_HostAnnouncement,
+ servrec->serv.name, /* From nbt name. */
+ work->work_group, 0x00, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ lm_interval, /* Time until next announce. */
+ servrec->serv.name, /* Name to announce. */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -247,15 +256,18 @@ static void send_lm_host_announcement(struct subnet_record *subrec, struct work_
static void announce_server(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Only do domain announcements if we are a master and it's
- our primary name we're being asked to announce. */
-
- if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name)) {
- send_local_master_announcement(subrec, work, servrec);
- send_workgroup_announcement(subrec, work);
- } else {
- send_host_announcement(subrec, work, servrec);
- }
+ /* Only do domain announcements if we are a master and it's
+ our primary name we're being asked to announce. */
+
+ if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname,servrec->serv.name))
+ {
+ send_local_master_announcement(subrec, work, servrec);
+ send_workgroup_announcement(subrec, work);
+ }
+ else
+ {
+ send_host_announcement(subrec, work, servrec);
+ }
}
/****************************************************************************
@@ -265,39 +277,43 @@ static void announce_server(struct subnet_record *subrec, struct work_record *wo
void announce_my_server_names(time_t t)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work) {
- struct server_record *servrec;
-
- if (work->needannounce) {
- /* Drop back to a max 3 minute announce. This is to prevent a
- single lost packet from breaking things for too long. */
-
- work->announce_interval = MIN(work->announce_interval,
- CHECK_TIME_MIN_HOST_ANNCE*60);
- work->lastannounce_time = t - (work->announce_interval+1);
- work->needannounce = False;
- }
-
- /* Announce every minute at first then progress to every 12 mins */
- if ((t - work->lastannounce_time) < work->announce_interval)
- continue;
-
- if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
- work->announce_interval += 60;
-
- work->lastannounce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next) {
- if (is_myname(servrec->serv.name))
- announce_server(subrec, work, servrec);
- }
- } /* if work */
- } /* for subrec */
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup);
+
+ if(work)
+ {
+ struct server_record *servrec;
+
+ if (work->needannounce)
+ {
+ /* Drop back to a max 3 minute announce. This is to prevent a
+ single lost packet from breaking things for too long. */
+
+ work->announce_interval = MIN(work->announce_interval,
+ CHECK_TIME_MIN_HOST_ANNCE*60);
+ work->lastannounce_time = t - (work->announce_interval+1);
+ work->needannounce = False;
+ }
+
+ /* Announce every minute at first then progress to every 12 mins */
+ if ((t - work->lastannounce_time) < work->announce_interval)
+ continue;
+
+ if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
+ work->announce_interval += 60;
+
+ work->lastannounce_time = t;
+
+ for (servrec = work->serverlist; servrec; servrec = servrec->next)
+ {
+ if (is_myname(servrec->serv.name))
+ announce_server(subrec, work, servrec);
+ }
+ } /* if work */
+ } /* for subrec */
}
/****************************************************************************
@@ -307,42 +323,47 @@ void announce_my_server_names(time_t t)
void announce_my_lm_server_names(time_t t)
{
- struct subnet_record *subrec;
- static time_t last_lm_announce_time=0;
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
-
- if ((announce_interval <= 0) || (lm_announce <= 0)) {
- /* user absolutely does not want LM announcements to be sent. */
- return;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients)) {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- return;
- }
-
- /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
- been detected. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work) {
- struct server_record *servrec;
-
- if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
- continue;
-
- last_lm_announce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next) {
- if (is_myname(servrec->serv.name))
- /* skipping equivalent of announce_server() */
- send_lm_host_announcement(subrec, work, servrec, announce_interval);
- }
- } /* if work */
- } /* for subrec */
+ struct subnet_record *subrec;
+ static time_t last_lm_announce_time=0;
+ int announce_interval = lp_lm_interval();
+ int lm_announce = lp_lm_announce();
+
+ if ((announce_interval <= 0) || (lm_announce <= 0))
+ {
+ /* user absolutely does not want LM announcements to be sent. */
+ return;
+ }
+
+ if ((lm_announce >= 2) && (!found_lm_clients))
+ {
+ /* has been set to 2 (Auto) but no LM clients detected (yet). */
+ return;
+ }
+
+ /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
+ been detected. */
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup);
+
+ if(work)
+ {
+ struct server_record *servrec;
+
+ if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
+ continue;
+
+ last_lm_announce_time = t;
+
+ for (servrec = work->serverlist; servrec; servrec = servrec->next)
+ {
+ if (is_myname(servrec->serv.name))
+ /* skipping equivalent of announce_server() */
+ send_lm_host_announcement(subrec, work, servrec, announce_interval);
+ }
+ } /* if work */
+ } /* for subrec */
}
/* Announce timer. Moved into global static so it can be reset
@@ -356,7 +377,7 @@ static time_t announce_timer_last=0;
void reset_announce_timer(void)
{
- announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
+ announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
}
/****************************************************************************
@@ -365,40 +386,45 @@ void reset_announce_timer(void)
void announce_myself_to_domain_master_browser(time_t t)
{
- struct subnet_record *subrec;
- struct work_record *work;
-
- if(!we_are_a_wins_client()) {
- DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
- return;
- }
-
- if (!announce_timer_last)
- announce_timer_last = t;
-
- if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60)) {
- DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
- (int)t, (int)announce_timer_last,
- CHECK_TIME_MST_ANNOUNCE * 60 ));
- return;
- }
-
- announce_timer_last = t;
-
- /* Look over all our broadcast subnets to see if any of them
- has the state set as local master browser. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- for (work = subrec->workgrouplist; work; work = work->next) {
- if (AM_LOCAL_MASTER_BROWSER(work)) {
- DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
+ struct subnet_record *subrec;
+ struct work_record *work;
+
+ if(!we_are_a_wins_client())
+ {
+ DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
+ return;
+ }
+
+ if (!announce_timer_last)
+ announce_timer_last = t;
+
+ if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60))
+ {
+ DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
+ (int)t, (int)announce_timer_last,
+ CHECK_TIME_MST_ANNOUNCE * 60 ));
+ return;
+ }
+
+ announce_timer_last = t;
+
+ /* Look over all our broadcast subnets to see if any of them
+ has the state set as local master browser. */
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ if (AM_LOCAL_MASTER_BROWSER(work))
+ {
+ DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
- /* Look in nmbd_browsersync.c for the rest of this code. */
- announce_and_sync_with_domain_master_browser(subrec, work);
- }
- }
- }
+ /* Look in nmbd_browsersync.c for the rest of this code. */
+ announce_and_sync_with_domain_master_browser(subrec, work);
+ }
+ }
+ }
}
/****************************************************************************
@@ -408,43 +434,49 @@ This must *only* be called on shutdown.
void announce_my_servers_removed(void)
{
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next) {
- struct server_record *servrec;
-
- work->announce_interval = 0;
- for (servrec = work->serverlist; servrec; servrec = servrec->next) {
- if (!is_myname(servrec->serv.name))
- continue;
- servrec->serv.type = 0;
- if(AM_LOCAL_MASTER_BROWSER(work))
- send_local_master_announcement(subrec, work, servrec);
- send_host_announcement(subrec, work, servrec);
-
- if ((announce_interval <= 0) || (lm_announce <= 0)) {
- /* user absolutely does not want LM announcements to be sent. */
- continue;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients)) {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- continue;
- }
-
- /*
- * lm announce was set or we have seen lm announcements, so do
- * a lm announcement of host removed.
- */
-
- send_lm_host_announcement(subrec, work, servrec, 0);
- }
- }
- }
+ int announce_interval = lp_lm_interval();
+ int lm_announce = lp_lm_announce();
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work;
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ struct server_record *servrec;
+
+ work->announce_interval = 0;
+ for (servrec = work->serverlist; servrec; servrec = servrec->next)
+ {
+ if (!is_myname(servrec->serv.name))
+ continue;
+ servrec->serv.type = 0;
+ if(AM_LOCAL_MASTER_BROWSER(work))
+ send_local_master_announcement(subrec, work, servrec);
+ send_host_announcement(subrec, work, servrec);
+
+
+ if ((announce_interval <= 0) || (lm_announce <= 0))
+ {
+ /* user absolutely does not want LM announcements to be sent. */
+ continue;
+ }
+
+ if ((lm_announce >= 2) && (!found_lm_clients))
+ {
+ /* has been set to 2 (Auto) but no LM clients detected (yet). */
+ continue;
+ }
+
+ /*
+ * lm announce was set or we have seen lm announcements, so do
+ * a lm announcement of host removed.
+ */
+
+ send_lm_host_announcement(subrec, work, servrec, 0);
+ }
+ }
+ }
}
/****************************************************************************
@@ -455,127 +487,125 @@ void announce_my_servers_removed(void)
void announce_remote(time_t t)
{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- char *comment;
- int stype = lp_default_server_announce();
-
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
-
- last_time = t;
-
- s = lp_remote_announce();
- if (!*s)
- return;
-
- comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
-
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
- /* The entries are of the form a.b.c.d/WORKGROUP with
- WORKGROUP being optional */
- const char *wgroup;
- char *pwgroup;
- int i;
-
- pwgroup = strchr_m(s2,'/');
- if (pwgroup)
- *pwgroup++ = 0;
- if (!pwgroup || !*pwgroup)
- wgroup = lp_workgroup();
- else
- wgroup = pwgroup;
-
- addr = *interpret_addr2(s2);
+ char *s;
+ const char *ptr;
+ static time_t last_time = 0;
+ pstring s2;
+ struct in_addr addr;
+ char *comment;
+ int stype = lp_default_server_announce();
+
+ if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
+ return;
+
+ last_time = t;
+
+ s = lp_remote_announce();
+ if (!*s)
+ return;
+
+ comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
+
+ for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
+ {
+ /* The entries are of the form a.b.c.d/WORKGROUP with
+ WORKGROUP being optional */
+ char *wgroup;
+ int i;
+
+ wgroup = strchr(s2,'/');
+ if (wgroup)
+ *wgroup++ = 0;
+ if (!wgroup || !*wgroup)
+ wgroup = global_myworkgroup;
+
+ addr = *interpret_addr2(s2);
- /* Announce all our names including aliases */
- /* Give the ip address as the address of our first
- broadcast subnet. */
-
- for(i=0; my_netbios_names(i); i++) {
- const char *name = my_netbios_names(i);
-
- DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
- name, inet_ntoa(addr) ));
-
- send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
- name, /* From nbt name. */
- wgroup, 0x1d, /* To nbt name. */
- addr, /* To ip. */
- REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
- name, /* Name to announce. */
- stype, /* Type field. */
- comment);
- }
- }
+ /* Announce all our names including aliases */
+ /* Give the ip address as the address of our first
+ broadcast subnet. */
+
+ for(i=0; my_netbios_names[i]; i++)
+ {
+ char *name = my_netbios_names[i];
+
+ DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
+ name, inet_ntoa(addr) ));
+
+ send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
+ name, /* From nbt name. */
+ wgroup, 0x1d, /* To nbt name. */
+ addr, /* To ip. */
+ REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
+ name, /* Name to announce. */
+ stype, /* Type field. */
+ comment);
+ }
+ }
}
/****************************************************************************
Implement the 'remote browse sync' feature Andrew added.
These are used to put our browse lists into remote browse lists.
-**************************************************************************/
+ **************************************************************************/
void browse_sync_remote(time_t t)
{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- struct work_record *work;
- pstring outbuf;
- char *p;
- unstring myname;
+ char *s;
+ const char *ptr;
+ static time_t last_time = 0;
+ pstring s2;
+ struct in_addr addr;
+ struct work_record *work;
+ pstring outbuf;
+ char *p;
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
+ if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
+ return;
- last_time = t;
-
- s = lp_remote_browse_sync();
- if (!*s)
- return;
-
- /*
- * We only do this if we are the local master browser
- * for our workgroup on the firsst subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {
- DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
+ last_time = t;
+
+ s = lp_remote_browse_sync();
+ if (!*s)
+ return;
+
+ /*
+ * We only do this if we are the local master browser
+ * for our workgroup on the firsst subnet.
+ */
+
+ if((work = find_workgroup_on_subnet(FIRST_SUBNET, global_myworkgroup)) == NULL)
+ {
+ DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
+ global_myworkgroup, FIRST_SUBNET->subnet_name ));
+ return;
+ }
- if(!AM_LOCAL_MASTER_BROWSER(work)) {
- DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
-for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
-
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
-
- unstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
-
- p = skip_string(p,1);
-
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
- /* The entries are of the form a.b.c.d */
- addr = *interpret_addr2(s2);
-
- DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
- global_myname(), inet_ntoa(addr) ));
-
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
- }
+ if(!AM_LOCAL_MASTER_BROWSER(work))
+ {
+ DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
+for workgroup %s on subnet %s.\n", global_myworkgroup, FIRST_SUBNET->subnet_name ));
+ return;
+ }
+
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_MasterAnnouncement);
+ p++;
+
+ StrnCpy(p,global_myname,15);
+ strupper(p);
+ p = skip_string(p,1);
+
+ for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
+ {
+ /* The entries are of the form a.b.c.d */
+ addr = *interpret_addr2(s2);
+
+ DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
+ global_myname, inet_ntoa(addr) ));
+
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname, 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
+ }
}
diff --git a/source/nmbd/nmbd_serverlistdb.c b/source/nmbd/nmbd_serverlistdb.c
index e6fad8319d9..e4bce464a31 100644
--- a/source/nmbd/nmbd_serverlistdb.c
+++ b/source/nmbd/nmbd_serverlistdb.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -22,9 +23,13 @@
*/
#include "includes.h"
+#include "smb.h"
extern int ClientNMB;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
+
int updatecount = 0;
/*******************************************************************
@@ -33,26 +38,28 @@ int updatecount = 0;
void remove_all_servers(struct work_record *work)
{
- struct server_record *servrec;
- struct server_record *nexts;
+ struct server_record *servrec;
+ struct server_record *nexts;
+
+ for (servrec = work->serverlist; servrec; servrec = nexts)
+ {
+ DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
+ nexts = servrec->next;
- for (servrec = work->serverlist; servrec; servrec = nexts) {
- DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
- nexts = servrec->next;
+ if (servrec->prev)
+ servrec->prev->next = servrec->next;
+ if (servrec->next)
+ servrec->next->prev = servrec->prev;
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
+ if (work->serverlist == servrec)
+ work->serverlist = servrec->next;
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
+ ZERO_STRUCTP(servrec);
+ SAFE_FREE(servrec);
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
- }
+ }
- work->subnet->work_changed = True;
+ work->subnet->work_changed = True;
}
/***************************************************************************
@@ -62,37 +69,39 @@ void remove_all_servers(struct work_record *work)
static void add_server_to_workgroup(struct work_record *work,
struct server_record *servrec)
{
- struct server_record *servrec2;
-
- if (!work->serverlist) {
- work->serverlist = servrec;
- servrec->prev = NULL;
- servrec->next = NULL;
- return;
- }
-
- for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
- ;
-
- servrec2->next = servrec;
- servrec->next = NULL;
- servrec->prev = servrec2;
- work->subnet->work_changed = True;
+ struct server_record *servrec2;
+
+ if (!work->serverlist)
+ {
+ work->serverlist = servrec;
+ servrec->prev = NULL;
+ servrec->next = NULL;
+ return;
+ }
+
+ for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
+ ;
+
+ servrec2->next = servrec;
+ servrec->next = NULL;
+ servrec->prev = servrec2;
+ work->subnet->work_changed = True;
}
/****************************************************************************
Find a server in a server list.
**************************************************************************/
-struct server_record *find_server_in_workgroup(struct work_record *work, const char *name)
+struct server_record *find_server_in_workgroup(struct work_record *work, char *name)
{
- struct server_record *ret;
+ struct server_record *ret;
- for (ret = work->serverlist; ret; ret = ret->next) {
- if (strequal(ret->serv.name,name))
- return ret;
- }
- return NULL;
+ for (ret = work->serverlist; ret; ret = ret->next)
+ {
+ if (strequal(ret->serv.name,name))
+ return ret;
+ }
+ return NULL;
}
@@ -102,17 +111,17 @@ struct server_record *find_server_in_workgroup(struct work_record *work, const c
void remove_server_from_workgroup(struct work_record *work, struct server_record *servrec)
{
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
+ if (servrec->prev)
+ servrec->prev->next = servrec->next;
+ if (servrec->next)
+ servrec->next->prev = servrec->prev;
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
+ if (work->serverlist == servrec)
+ work->serverlist = servrec->next;
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
- work->subnet->work_changed = True;
+ ZERO_STRUCTP(servrec);
+ SAFE_FREE(servrec);
+ work->subnet->work_changed = True;
}
/****************************************************************************
@@ -120,47 +129,50 @@ void remove_server_from_workgroup(struct work_record *work, struct server_record
****************************************************************************/
struct server_record *create_server_on_workgroup(struct work_record *work,
- const char *name,int servertype,
- int ttl, const char *comment)
+ char *name,int servertype,
+ int ttl,char *comment)
{
- struct server_record *servrec;
+ struct server_record *servrec;
- if (name[0] == '*') {
- DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n",
- name));
- return (NULL);
- }
+ if (name[0] == '*')
+ {
+ DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n",
+ name));
+ return (NULL);
+ }
- if((servrec = find_server_in_workgroup(work, name)) != NULL) {
- DEBUG(0,("create_server_on_workgroup: Server %s already exists on \
+ if((servrec = find_server_in_workgroup(work, name)) != NULL)
+ {
+ DEBUG(0,("create_server_on_workgroup: Server %s already exists on \
workgroup %s. This is a bug.\n", name, work->work_group));
- return NULL;
- }
+ return NULL;
+ }
- if((servrec = (struct server_record *)malloc(sizeof(*servrec))) == NULL) {
- DEBUG(0,("create_server_entry_on_workgroup: malloc fail !\n"));
- return NULL;
- }
+ if((servrec = (struct server_record *)malloc(sizeof(*servrec))) == NULL)
+ {
+ DEBUG(0,("create_server_entry_on_workgroup: malloc fail !\n"));
+ return NULL;
+ }
- memset((char *)servrec,'\0',sizeof(*servrec));
+ memset((char *)servrec,'\0',sizeof(*servrec));
- servrec->subnet = work->subnet;
+ servrec->subnet = work->subnet;
- fstrcpy(servrec->serv.name,name);
- fstrcpy(servrec->serv.comment,comment);
- strupper_m(servrec->serv.name);
- servrec->serv.type = servertype;
+ StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1);
+ StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ strupper(servrec->serv.name);
+ servrec->serv.type = servertype;
- update_server_ttl(servrec, ttl);
+ update_server_ttl(servrec, ttl);
- add_server_to_workgroup(work, servrec);
+ add_server_to_workgroup(work, servrec);
- DEBUG(3,("create_server_on_workgroup: Created server entry %s of type %x (%s) on \
+ DEBUG(3,("create_server_on_workgroup: Created server entry %s of type %x (%s) on \
workgroup %s.\n", name,servertype,comment, work->work_group));
- work->subnet->work_changed = True;
+ work->subnet->work_changed = True;
- return(servrec);
+ return(servrec);
}
/*******************************************************************
@@ -169,15 +181,15 @@ workgroup %s.\n", name,servertype,comment, work->work_group));
void update_server_ttl(struct server_record *servrec, int ttl)
{
- if(ttl > lp_max_ttl())
- ttl = lp_max_ttl();
+ if(ttl > lp_max_ttl())
+ ttl = lp_max_ttl();
- if(is_myname(servrec->serv.name))
- servrec->death_time = PERMANENT_TTL;
- else
- servrec->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
+ if(is_myname(servrec->serv.name))
+ servrec->death_time = PERMANENT_TTL;
+ else
+ servrec->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
- servrec->subnet->work_changed = True;
+ servrec->subnet->work_changed = True;
}
/*******************************************************************
@@ -188,18 +200,20 @@ void update_server_ttl(struct server_record *servrec, int ttl)
void expire_servers(struct work_record *work, time_t t)
{
- struct server_record *servrec;
- struct server_record *nexts;
+ struct server_record *servrec;
+ struct server_record *nexts;
- for (servrec = work->serverlist; servrec; servrec = nexts) {
- nexts = servrec->next;
-
- if ((servrec->death_time != PERMANENT_TTL) && ((t == -1) || (servrec->death_time < t))) {
- DEBUG(3,("expire_old_servers: Removing timed out server %s\n",servrec->serv.name));
- remove_server_from_workgroup(work, servrec);
- work->subnet->work_changed = True;
- }
- }
+ for (servrec = work->serverlist; servrec; servrec = nexts)
+ {
+ nexts = servrec->next;
+
+ if ((servrec->death_time != PERMANENT_TTL) && ((t == -1) || (servrec->death_time < t)))
+ {
+ DEBUG(3,("expire_old_servers: Removing timed out server %s\n",servrec->serv.name));
+ remove_server_from_workgroup(work, servrec);
+ work->subnet->work_changed = True;
+ }
+ }
}
/*******************************************************************
@@ -212,35 +226,38 @@ static uint32 write_this_server_name( struct subnet_record *subrec,
struct work_record *work,
struct server_record *servrec)
{
- struct subnet_record *ssub;
- struct work_record *iwork;
-
- /* Go through all the subnets we have already seen. */
- for (ssub = FIRST_SUBNET; ssub != subrec; ssub = NEXT_SUBNET_INCLUDING_UNICAST(ssub)) {
- for(iwork = ssub->workgrouplist; iwork; iwork = iwork->next) {
- if(find_server_in_workgroup( iwork, servrec->serv.name) != NULL) {
- /*
- * We have already written out this server record, don't
- * do it again. This gives precedence to servers we have seen
- * on the broadcast subnets over servers that may have been
- * added via a sync on the unicast_subet.
- *
- * The correct way to do this is to have a serverlist file
- * per subnet - this means changes to smbd as well. I may
- * add this at a later date (JRA).
- */
-
- return 0;
- }
- }
- }
-
- return servrec->serv.type;
+ struct subnet_record *ssub;
+ struct work_record *iwork;
+
+ /* Go through all the subnets we have already seen. */
+ for (ssub = FIRST_SUBNET; ssub != subrec; ssub = NEXT_SUBNET_INCLUDING_UNICAST(ssub))
+ {
+ for(iwork = ssub->workgrouplist; iwork; iwork = iwork->next)
+ {
+ if(find_server_in_workgroup( iwork, servrec->serv.name) != NULL)
+ {
+ /*
+ * We have already written out this server record, don't
+ * do it again. This gives precedence to servers we have seen
+ * on the broadcast subnets over servers that may have been
+ * added via a sync on the unicast_subet.
+ *
+ * The correct way to do this is to have a serverlist file
+ * per subnet - this means changes to smbd as well. I may
+ * add this at a later date (JRA).
+ */
+
+ return 0;
+ }
+ }
+ }
+
+ return servrec->serv.type;
}
/*******************************************************************
Decide if we should write out a workgroup record for this workgroup.
- We return zero if we should not. Don't write out lp_workgroup() (we've
+ We return zero if we should not. Don't write out global_myworkgroup (we've
already done it) and also don't write out a second workgroup record
on the unicast subnet that we've already written out on one of the
broadcast subnets.
@@ -249,174 +266,185 @@ static uint32 write_this_server_name( struct subnet_record *subrec,
static uint32 write_this_workgroup_name( struct subnet_record *subrec,
struct work_record *work)
{
- struct subnet_record *ssub;
+ struct subnet_record *ssub;
- if(strequal(lp_workgroup(), work->work_group))
- return 0;
+ if(strequal(global_myworkgroup, work->work_group))
+ return 0;
- /* This is a workgroup we have seen on a broadcast subnet. All
- these have the same type. */
+ /* This is a workgroup we have seen on a broadcast subnet. All
+ these have the same type. */
- if(subrec != unicast_subnet)
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
+ if(subrec != unicast_subnet)
+ return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
- for(ssub = FIRST_SUBNET; ssub; ssub = NEXT_SUBNET_EXCLUDING_UNICAST(ssub)) {
- /* This is the unicast subnet so check if we've already written out
- this subnet when we passed over the broadcast subnets. */
+ for(ssub = FIRST_SUBNET; ssub; ssub = NEXT_SUBNET_EXCLUDING_UNICAST(ssub))
+ {
+ /* This is the unicast subnet so check if we've already written out
+ this subnet when we passed over the broadcast subnets. */
- if(find_workgroup_on_subnet( ssub, work->work_group) != NULL)
- return 0;
- }
+ if(find_workgroup_on_subnet( ssub, work->work_group) != NULL)
+ return 0;
+ }
- /* All workgroups on the unicast subnet (except our own, which we
- have already written out) cannot be local. */
+ /* All workgroups on the unicast subnet (except our own, which we
+ have already written out) cannot be local. */
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT);
+ return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT);
}
/*******************************************************************
Write out the browse.dat file.
******************************************************************/
-void write_browse_list_entry(XFILE *fp, const char *name, uint32 rec_type,
- const char *local_master_browser_name, const char *description)
+void write_browse_list_entry(FILE *fp, fstring name, uint32 rec_type,
+ fstring local_master_browser_name, fstring description)
{
fstring tmp;
slprintf(tmp,sizeof(tmp)-1, "\"%s\"", name);
- x_fprintf(fp, "%-25s ", tmp);
- x_fprintf(fp, "%08x ", rec_type);
+ fprintf(fp, "%-25s ", tmp);
+ fprintf(fp, "%08x ", rec_type);
slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", local_master_browser_name);
- x_fprintf(fp, "%-30s", tmp);
- x_fprintf(fp, "\"%s\"\n", description);
+ fprintf(fp, "%-30s", tmp);
+ fprintf(fp, "\"%s\"\n", description);
}
void write_browse_list(time_t t, BOOL force_write)
{
- struct subnet_record *subrec;
- struct work_record *work;
- struct server_record *servrec;
- pstring fname,fnamenew;
- uint32 stype;
- int i;
- XFILE *fp;
- BOOL list_changed = force_write;
- static time_t lasttime = 0;
+ struct subnet_record *subrec;
+ struct work_record *work;
+ struct server_record *servrec;
+ pstring fname,fnamenew;
+ uint32 stype;
+ int i;
+ FILE *fp;
+ BOOL list_changed = force_write;
+ static time_t lasttime = 0;
- /* Always dump if we're being told to by a signal. */
- if(force_write == False) {
- if (!lasttime)
- lasttime = t;
- if (t - lasttime < 5)
- return;
- }
-
- lasttime = t;
-
- dump_workgroups(force_write);
+ /* Always dump if we're being told to by a signal. */
+ if(force_write == False)
+ {
+ if (!lasttime)
+ lasttime = t;
+ if (t - lasttime < 5)
+ return;
+ }
+
+ lasttime = t;
+
+ dump_workgroups(force_write);
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- if(subrec->work_changed) {
- list_changed = True;
- break;
- }
- }
-
- if(!list_changed)
- return;
-
- updatecount++;
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ if(subrec->work_changed)
+ {
+ list_changed = True;
+ break;
+ }
+ }
+
+ if(!list_changed)
+ return;
+
+ updatecount++;
- pstrcpy(fname,lp_lockdir());
- trim_char(fname,'\0' ,'/');
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
- pstrcpy(fnamenew,fname);
- pstrcat(fnamenew,".");
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,SERVER_LIST);
+ pstrcpy(fnamenew,fname);
+ pstrcat(fnamenew,".");
- fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ fp = sys_fopen(fnamenew,"w");
- if (!fp) {
- DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n",
- fnamenew,strerror(errno)));
- return;
- }
+ if (!fp)
+ {
+ DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n",
+ fnamenew,strerror(errno)));
+ return;
+ }
- /*
- * Write out a record for our workgroup. Use the record from the first
- * subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {
- DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n",
- lp_workgroup()));
- x_fclose(fp);
- return;
- }
-
- write_browse_list_entry(fp, work->work_group,
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
- work->local_master_browser_name, work->work_group);
-
- /*
- * We need to do something special for our own names.
- * This is due to the fact that we may be a local master browser on
- * one of our broadcast subnets, and a domain master on the unicast
- * subnet. We iterate over the subnets and only write out the name
- * once.
- */
-
- for (i=0; my_netbios_names(i); i++) {
- stype = 0;
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- if((work = find_workgroup_on_subnet( subrec, lp_workgroup() )) == NULL)
- continue;
- if((servrec = find_server_in_workgroup( work, my_netbios_names(i))) == NULL)
- continue;
-
- stype |= servrec->serv.type;
- }
-
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, my_netbios_names(i), stype,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_workgroup());
- }
+ /*
+ * Write out a record for our workgroup. Use the record from the first
+ * subnet.
+ */
+
+ if((work = find_workgroup_on_subnet(FIRST_SUBNET, global_myworkgroup)) == NULL)
+ {
+ DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n",
+ global_myworkgroup));
+ fclose(fp);
+ return;
+ }
+
+ write_browse_list_entry(fp, work->work_group, SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
+ work->local_master_browser_name, work->work_group);
+
+ /*
+ * We need to do something special for our own names.
+ * This is due to the fact that we may be a local master browser on
+ * one of our broadcast subnets, and a domain master on the unicast
+ * subnet. We iterate over the subnets and only write out the name
+ * once.
+ */
+
+ for (i=0; my_netbios_names[i]; i++)
+ {
+ stype = 0;
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ if((work = find_workgroup_on_subnet( subrec, global_myworkgroup )) == NULL)
+ continue;
+ if((servrec = find_server_in_workgroup( work, my_netbios_names[i])) == NULL)
+ continue;
+
+ stype |= servrec->serv.type;
+ }
+
+ /* Output server details, plus what workgroup they're in. */
+ write_browse_list_entry(fp, my_netbios_names[i], stype,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
+ global_myworkgroup);
+
+ }
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- subrec->work_changed = False;
-
- for (work = subrec->workgrouplist; work ; work = work->next) {
- /* Write out a workgroup record for a workgroup. */
- uint32 wg_type = write_this_workgroup_name( subrec, work);
-
- if(wg_type) {
- write_browse_list_entry(fp, work->work_group, wg_type,
- work->local_master_browser_name,
- work->work_group);
- }
-
- /* Now write out any server records a workgroup may have. */
-
- for (servrec = work->serverlist; servrec ; servrec = servrec->next) {
- uint32 serv_type;
-
- /* We have already written our names here. */
- if(is_myname(servrec->serv.name))
- continue;
-
- serv_type = write_this_server_name(subrec, work, servrec);
- if(serv_type) {
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, servrec->serv.name, serv_type,
- servrec->serv.comment, work->work_group);
- }
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ subrec->work_changed = False;
+
+ for (work = subrec->workgrouplist; work ; work = work->next)
+ {
+ /* Write out a workgroup record for a workgroup. */
+ uint32 wg_type = write_this_workgroup_name( subrec, work);
+
+ if(wg_type)
+ write_browse_list_entry(fp, work->work_group, wg_type,
+ work->local_master_browser_name,
+ work->work_group);
+
+ /* Now write out any server records a workgroup may have. */
+
+ for (servrec = work->serverlist; servrec ; servrec = servrec->next)
+ {
+ uint32 serv_type;
+
+ /* We have already written our names here. */
+ if(is_myname(servrec->serv.name))
+ continue;
+
+ serv_type = write_this_server_name(subrec, work, servrec);
+
+ /* Output server details, plus what workgroup they're in. */
+ if(serv_type)
+ write_browse_list_entry(fp, servrec->serv.name, serv_type,
+ servrec->serv.comment, work->work_group);
+ }
+ }
+ }
- x_fclose(fp);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("write_browse_list: Wrote browse list into file %s\n",fname));
+ fclose(fp);
+ unlink(fname);
+ chmod(fnamenew,0644);
+ rename(fnamenew,fname);
+ DEBUG(3,("write_browse_list: Wrote browse list into file %s\n",fname));
}
diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c
index 02a91f27606..95f10df09d4 100644
--- a/source/nmbd/nmbd_subnetdb.c
+++ b/source/nmbd/nmbd_subnetdb.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -24,11 +25,15 @@
*/
#include "includes.h"
+#include "smb.h"
extern int ClientNMB;
extern int ClientDGRAM;
extern int global_nmb_port;
+extern fstring myworkgroup;
+extern char **my_netbios_names;
+
/* This is the broadcast subnets database. */
struct subnet_record *subnetlist = NULL;
@@ -63,27 +68,28 @@ static void add_subnet(struct subnet_record *subrec)
* ************************************************************************** **
*/
static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
-{
- struct name_record *NR = (struct name_record *)Node;
+ {
+ struct name_record *NR = (struct name_record *)Node;
- if( DEBUGLVL( 10 ) ) {
- struct nmb_name *Iname = (struct nmb_name *)Item;
+ if( DEBUGLVL( 10 ) )
+ {
+ struct nmb_name *Iname = (struct nmb_name *)Item;
- Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
- Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
- memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
- nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
- }
+ Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
+ Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
+ memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
+ nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
+ }
+
+ return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
+ } /* namelist_entry_compare */
- return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
-}
/****************************************************************************
stop listening on a subnet
we don't free the record as we don't have proper reference counting for it
yet and it may be in use by a response record
****************************************************************************/
-
void close_subnet(struct subnet_record *subrec)
{
DLIST_REMOVE(subnetlist, subrec);
@@ -98,6 +104,8 @@ void close_subnet(struct subnet_record *subrec)
}
}
+
+
/****************************************************************************
Create a subnet entry.
****************************************************************************/
@@ -106,90 +114,102 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
struct in_addr myip, struct in_addr bcast_ip,
struct in_addr mask_ip)
{
- struct subnet_record *subrec = NULL;
- int nmb_sock, dgram_sock;
-
- /* Check if we are creating a non broadcast subnet - if so don't create
- sockets. */
-
- if(type != NORMAL_SUBNET) {
- nmb_sock = -1;
- dgram_sock = -1;
- } else {
- /*
- * Attempt to open the sockets on port 137/138 for this interface
- * and bind them.
- * Fail the subnet creation if this fails.
- */
-
- if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
- if( DEBUGLVL( 0 ) ) {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", global_nmb_port );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
- if( DEBUGLVL( 0 ) ) {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", DGRAM_PORT );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- /* Make sure we can broadcast from these sockets. */
- set_socket_options(nmb_sock,"SO_BROADCAST");
- set_socket_options(dgram_sock,"SO_BROADCAST");
- }
-
- subrec = (struct subnet_record *)malloc(sizeof(*subrec));
- if (!subrec) {
- DEBUG(0,("make_subnet: malloc fail !\n"));
- close(nmb_sock);
- close(dgram_sock);
- return(NULL);
- }
+ struct subnet_record *subrec = NULL;
+ int nmb_sock, dgram_sock;
+
+ /* Check if we are creating a non broadcast subnet - if so don't create
+ sockets.
+ */
+
+ if(type != NORMAL_SUBNET)
+ {
+ nmb_sock = -1;
+ dgram_sock = -1;
+ }
+ else
+ {
+ /*
+ * Attempt to open the sockets on port 137/138 for this interface
+ * and bind them.
+ * Fail the subnet creation if this fails.
+ */
+
+ if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ Debug1( "nmbd_subnetdb:make_subnet()\n" );
+ Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
+ Debug1( "for port %d. ", global_nmb_port );
+ Debug1( "Error was %s\n", strerror(errno) );
+ }
+ return NULL;
+ }
+
+ if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1)
+ {
+ if( DEBUGLVL( 0 ) )
+ {
+ Debug1( "nmbd_subnetdb:make_subnet()\n" );
+ Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
+ Debug1( "for port %d. ", DGRAM_PORT );
+ Debug1( "Error was %s\n", strerror(errno) );
+ }
+ return NULL;
+ }
+
+ /* Make sure we can broadcast from these sockets. */
+ set_socket_options(nmb_sock,"SO_BROADCAST");
+ set_socket_options(dgram_sock,"SO_BROADCAST");
+
+ }
+
+ subrec = (struct subnet_record *)malloc(sizeof(*subrec));
- memset( (char *)subrec, '\0', sizeof(*subrec) );
- (void)ubi_trInitTree( subrec->namelist,
- namelist_entry_compare,
- ubi_trOVERWRITE );
-
- if((subrec->subnet_name = strdup(name)) == NULL) {
- DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
- close(nmb_sock);
- close(dgram_sock);
- ZERO_STRUCTP(subrec);
- SAFE_FREE(subrec);
- return(NULL);
- }
-
- DEBUG(2, ("making subnet name:%s ", name ));
- DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
- DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
+ if (!subrec)
+ {
+ DEBUG(0,("make_subnet: malloc fail !\n"));
+ close(nmb_sock);
+ close(dgram_sock);
+ return(NULL);
+ }
+
+ memset( (char *)subrec, '\0', sizeof(*subrec) );
+ (void)ubi_trInitTree( subrec->namelist,
+ namelist_entry_compare,
+ ubi_trOVERWRITE );
+
+ if((subrec->subnet_name = strdup(name)) == NULL)
+ {
+ DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
+ close(nmb_sock);
+ close(dgram_sock);
+ ZERO_STRUCTP(subrec);
+ SAFE_FREE(subrec);
+ return(NULL);
+ }
+
+ DEBUG(2, ("making subnet name:%s ", name ));
+ DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
+ DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
- subrec->namelist_changed = False;
- subrec->work_changed = False;
+ subrec->namelist_changed = False;
+ subrec->work_changed = False;
- subrec->bcast_ip = bcast_ip;
- subrec->mask_ip = mask_ip;
- subrec->myip = myip;
- subrec->type = type;
- subrec->nmb_sock = nmb_sock;
- subrec->dgram_sock = dgram_sock;
+ subrec->bcast_ip = bcast_ip;
+ subrec->mask_ip = mask_ip;
+ subrec->myip = myip;
+ subrec->type = type;
+ subrec->nmb_sock = nmb_sock;
+ subrec->dgram_sock = dgram_sock;
- return subrec;
+ return subrec;
}
+
/****************************************************************************
Create a normal subnet
**************************************************************************/
-
struct subnet_record *make_normal_subnet(struct interface *iface)
{
struct subnet_record *subrec;
@@ -202,93 +222,121 @@ struct subnet_record *make_normal_subnet(struct interface *iface)
return subrec;
}
+
/****************************************************************************
Create subnet entries.
**************************************************************************/
BOOL create_subnets(void)
{
- int num_interfaces = iface_count();
- int i;
- struct in_addr unicast_ip, ipzero;
- extern struct in_addr loopback_ip;
-
- if(num_interfaces == 0) {
- DEBUG(0,("create_subnets: No local interfaces !\n"));
- DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
- while (iface_count() == 0) {
- sleep(5);
- load_interfaces();
- }
- }
-
- num_interfaces = iface_count();
-
- /*
- * Create subnets from all the local interfaces and thread them onto
- * the linked list.
- */
-
- for (i = 0 ; i < num_interfaces; i++) {
- struct interface *iface = get_interface(i);
-
- /*
- * We don't want to add a loopback interface, in case
- * someone has added 127.0.0.1 for smbd, nmbd needs to
- * ignore it here. JRA.
- */
-
- if (ip_equal(iface->ip, loopback_ip)) {
- DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
- continue;
- }
-
- if (!make_normal_subnet(iface))
- return False;
- }
-
- if (lp_we_are_a_wins_server()) {
- /* Pick the first interface ip address as the WINS server ip. */
- unicast_ip = *iface_n_ip(0);
- } else {
- /* note that we do not set the wins server IP here. We just
- set it at zero and let the wins registration code cope
- with getting the IPs right for each packet */
- zero_ip(&unicast_ip);
- }
-
- /*
- * Create the unicast and remote broadcast subnets.
- * Don't put these onto the linked list.
- * The ip address of the unicast subnet is set to be
- * the WINS server address, if it exists, or ipzero if not.
- */
-
- unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
- unicast_ip, unicast_ip, unicast_ip);
-
- zero_ip(&ipzero);
-
- remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
- REMOTE_BROADCAST_SUBNET,
- ipzero, ipzero, ipzero);
-
- if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
- return False;
-
- /*
- * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
- * the linked list.
- */
-
- if (lp_we_are_a_wins_server()) {
- if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
- WINS_SERVER_SUBNET,
- ipzero, ipzero, ipzero )) == NULL )
- return False;
- }
-
- return True;
+ int num_interfaces = iface_count();
+ int i;
+ struct in_addr unicast_ip, ipzero;
+ extern struct in_addr loopback_ip;
+
+ if(num_interfaces == 0)
+ {
+ DEBUG(0,("create_subnets: No local interfaces !\n"));
+ return False;
+ }
+
+ /*
+ * Create subnets from all the local interfaces and thread them onto
+ * the linked list.
+ */
+
+ for (i = 0 ; i < num_interfaces; i++)
+ {
+ struct interface *iface = get_interface(i);
+
+ /*
+ * We don't want to add a loopback interface, in case
+ * someone has added 127.0.0.1 for smbd, nmbd needs to
+ * ignore it here. JRA.
+ */
+
+ if (ip_equal(iface->ip, loopback_ip)) {
+ DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
+ continue;
+ }
+
+ if (!make_normal_subnet(iface)) return False;
+ }
+
+ /*
+ * If we have been configured to use a WINS server, then try and
+ * get the ip address of it here. If we are the WINS server then
+ * set the unicast subnet address to be the first of our own real
+ * addresses.
+ *
+ * NOTE: I'm not sure of the implications of WINS server failover
+ * on this bit of code. Because of failover, the WINS
+ * server address can change. crh
+ */
+
+ if(*lp_wins_server())
+ {
+ struct in_addr real_wins_ip;
+ real_wins_ip = wins_srv_ip();
+
+ if (!is_zero_ip(real_wins_ip))
+ {
+ unicast_ip = real_wins_ip;
+ }
+ else
+ {
+ /* wins_srv_ip() can return a zero IP if all servers are
+ * either down or incorrectly entered in smb.conf. crh
+ */
+ DEBUG(0,("No 'live' WINS servers found. Check 'wins server' parameter.\n"));
+ return False;
+ }
+ }
+ else if(lp_we_are_a_wins_server())
+ {
+ /* Pick the first interface ip address as the WINS server ip. */
+ unicast_ip = *iface_n_ip(0);
+ }
+ else
+ {
+ /* We should not be using a WINS server at all. Set the
+ ip address of the subnet to be zero. */
+ zero_ip(&unicast_ip);
+ }
+
+ /*
+ * Create the unicast and remote broadcast subnets.
+ * Don't put these onto the linked list.
+ * The ip address of the unicast subnet is set to be
+ * the WINS server address, if it exists, or ipzero if not.
+ */
+
+ unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
+ unicast_ip, unicast_ip, unicast_ip);
+
+ zero_ip(&ipzero);
+
+ remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
+ REMOTE_BROADCAST_SUBNET,
+ ipzero, ipzero, ipzero);
+
+ if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
+ return False;
+
+ /*
+ * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
+ * the linked list.
+ */
+
+ if (lp_we_are_a_wins_server())
+ {
+ if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
+ WINS_SERVER_SUBNET,
+ ipzero, ipzero, ipzero )) == NULL )
+ return False;
+ }
+
+ return True;
}
/*******************************************************************
@@ -297,11 +345,13 @@ Function to tell us if we can use the unicast subnet.
BOOL we_are_a_wins_client(void)
{
- if (wins_srv_count() > 0) {
- return True;
- }
+ static int cache_we_are_a_wins_client = -1;
+
+ if(cache_we_are_a_wins_client == -1)
+ cache_we_are_a_wins_client = (is_zero_ip(unicast_subnet->myip) ?
+ False : True);
- return False;
+ return cache_we_are_a_wins_client;
}
/*******************************************************************
@@ -310,12 +360,12 @@ Access function used by NEXT_SUBNET_INCLUDING_UNICAST
struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec)
{
- if(subrec == unicast_subnet)
- return NULL;
- else if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
+ if(subrec == unicast_subnet)
+ return NULL;
+ else if((subrec->next == NULL) && we_are_a_wins_client())
+ return unicast_subnet;
+ else
+ return subrec->next;
}
/*******************************************************************
@@ -327,18 +377,19 @@ struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec
struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
{
- if(subrec == unicast_subnet) {
- if(wins_server_subnet)
- return wins_server_subnet;
- else
- return NULL;
- }
-
- if(wins_server_subnet && subrec == wins_server_subnet)
- return NULL;
-
- if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
+ if(subrec == unicast_subnet)
+ {
+ if(wins_server_subnet)
+ return wins_server_subnet;
+ else
+ return NULL;
+ }
+
+ if(wins_server_subnet && subrec == wins_server_subnet)
+ return NULL;
+
+ if((subrec->next == NULL) && we_are_a_wins_client())
+ return unicast_subnet;
+ else
+ return subrec->next;
}
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 86f1f760fd2..39c6bff25d3 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -28,11 +29,12 @@
also allows us to have more than 1 sync going at once (tridge) */
#include "includes.h"
+#include "smb.h"
struct sync_record {
struct sync_record *next, *prev;
- unstring workgroup;
- unstring server;
+ fstring workgroup;
+ fstring server;
pstring fname;
struct in_addr ip;
pid_t pid;
@@ -41,17 +43,16 @@ struct sync_record {
/* a linked list of current sync connections */
static struct sync_record *syncs;
-static XFILE *fp;
+static FILE *fp;
/*******************************************************************
This is the NetServerEnum callback.
Note sname and comment are in UNIX codepage format.
******************************************************************/
-
static void callback(const char *sname, uint32 stype,
const char *comment, void *state)
{
- x_fprintf(fp,"\"%s\" %08X \"%s\"\n", sname, stype, comment);
+ fprintf(fp,"\"%s\" %08X \"%s\"\n", sname, stype, comment);
}
/*******************************************************************
@@ -59,7 +60,6 @@ static void callback(const char *sname, uint32 stype,
Log in on the remote server's SMB port to their IPC$ service,
do a NetServerEnum and record the results in fname
******************************************************************/
-
static void sync_child(char *name, int nm_type,
char *workgroup,
struct in_addr ip, BOOL local, BOOL servers,
@@ -80,9 +80,10 @@ static void sync_child(char *name, int nm_type,
}
make_nmb_name(&calling, local_machine, 0x0);
- make_nmb_name(&called , name, nm_type);
+ make_nmb_name(&called , name , nm_type);
- if (!cli_session_request(&cli, &calling, &called)) {
+ if (!cli_session_request(&cli, &calling, &called))
+ {
cli_shutdown(&cli);
return;
}
@@ -104,6 +105,7 @@ static void sync_child(char *name, int nm_type,
/* All the cli_XX functions take UNIX character set. */
fstrcpy(unix_workgroup, cli.server_domain?cli.server_domain:workgroup);
+ dos_to_unix(unix_workgroup);
/* Fetch a workgroup list. */
cli_NetServerEnum(&cli, unix_workgroup,
@@ -113,6 +115,7 @@ static void sync_child(char *name, int nm_type,
/* Now fetch a server list. */
if (servers) {
fstrcpy(unix_workgroup, workgroup);
+ dos_to_unix(unix_workgroup);
cli_NetServerEnum(&cli, unix_workgroup,
local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL,
callback, NULL);
@@ -121,12 +124,12 @@ static void sync_child(char *name, int nm_type,
cli_shutdown(&cli);
}
+
/*******************************************************************
initialise a browse sync with another browse server. Log in on the
remote server's SMB port to their IPC$ service, do a NetServerEnum
and record the results
******************************************************************/
-
void sync_browse_lists(struct work_record *work,
char *name, int nm_type,
struct in_addr ip, BOOL local, BOOL servers)
@@ -148,8 +151,8 @@ done:
ZERO_STRUCTP(s);
- unstrcpy(s->workgroup, work->work_group);
- unstrcpy(s->server, name);
+ fstrcpy(s->workgroup, work->work_group);
+ fstrcpy(s->server, name);
s->ip = ip;
slprintf(s->fname, sizeof(pstring)-1,
@@ -168,7 +171,7 @@ done:
DEBUG(2,("Initiating browse sync for %s to %s(%s)\n",
work->work_group, name, inet_ntoa(ip)));
- fp = x_fopen(s->fname,O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ fp = sys_fopen(s->fname,"w");
if (!fp) {
END_PROFILE(sync_browse_lists);
_exit(1);
@@ -177,15 +180,14 @@ done:
sync_child(name, nm_type, work->work_group, ip, local, servers,
s->fname);
- x_fclose(fp);
+ fclose(fp);
END_PROFILE(sync_browse_lists);
_exit(0);
}
/**********************************************************************
- Handle one line from a completed sync file.
+handle one line from a completed sync file
**********************************************************************/
-
static void complete_one(struct sync_record *s,
char *sname, uint32 stype, char *comment)
{
@@ -206,7 +208,8 @@ static void complete_one(struct sync_record *s,
sname, lp_max_ttl());
if (work) {
/* remember who the master is */
- unstrcpy(work->local_master_browser_name, comment);
+ fstrcpy(work->local_master_browser_name,
+ comment);
}
}
return;
@@ -236,32 +239,33 @@ static void complete_one(struct sync_record *s,
create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment);
}
-/**********************************************************************
- Read the completed sync info.
-**********************************************************************/
+/**********************************************************************
+read the completed sync info
+ **********************************************************************/
static void complete_sync(struct sync_record *s)
{
- XFILE *f;
- unstring server, type_str;
+ FILE *f;
+ fstring server, type_str;
unsigned type;
pstring comment;
pstring line;
const char *ptr;
int count=0;
- f = x_fopen(s->fname,O_RDONLY, 0);
+ f = sys_fopen(s->fname,"r");
- if (!f)
- return;
+ if (!f) return;
- while (!x_feof(f)) {
+ while (!feof(f)) {
- if (!fgets_slash(line,sizeof(pstring),f))
- continue;
+ if (!fgets_slash(line,sizeof(pstring),f)) continue;
ptr = line;
+ /* The line is written in UNIX character set. Convert to DOS codepage. */
+ unix_to_dos(line);
+
if (!next_token(&ptr,server,NULL,sizeof(server)) ||
!next_token(&ptr,type_str,NULL, sizeof(type_str)) ||
!next_token(&ptr,comment,NULL, sizeof(comment))) {
@@ -275,7 +279,7 @@ static void complete_sync(struct sync_record *s)
count++;
}
- x_fclose(f);
+ fclose(f);
unlink(s->fname);
@@ -284,9 +288,8 @@ static void complete_sync(struct sync_record *s)
}
/**********************************************************************
- Check for completion of any of the child processes.
-**********************************************************************/
-
+check for completion of any of the child processes
+ **********************************************************************/
void sync_check_completion(void)
{
struct sync_record *s, *next;
diff --git a/source/nmbd/nmbd_winsproxy.c b/source/nmbd/nmbd_winsproxy.c
index cce168adb2f..84102289587 100644
--- a/source/nmbd/nmbd_winsproxy.c
+++ b/source/nmbd/nmbd_winsproxy.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Jeremy Allison 1994-1998
@@ -30,85 +31,92 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec,
struct userdata_struct *userdata,
struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec)
{
- unstring name;
- struct packet_struct *original_packet;
- struct subnet_record *orig_broadcast_subnet;
- struct name_record *namerec;
- uint16 nb_flags;
- int num_ips;
- int i;
- int ttl = 3600; /* By default one hour in the cache. */
- struct in_addr *iplist;
-
- /* Extract the original packet and the original broadcast subnet from
- the userdata. */
-
- memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
- memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *) );
-
- nb_flags = get_nb_flags( rrec->rdata );
-
- num_ips = rrec->rdlength / 6;
- if(num_ips == 0) {
- DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
+ struct packet_struct *original_packet;
+ struct subnet_record *orig_broadcast_subnet;
+ struct name_record *namerec;
+ uint16 nb_flags;
+ int num_ips;
+ int i;
+ int ttl = 3600; /* By default one hour in the cache. */
+ struct in_addr *iplist;
+
+ /* Extract the original packet and the original broadcast subnet from
+ the userdata. */
+
+ memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
+ memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
+ sizeof(struct packet_struct *) );
+
+ nb_flags = get_nb_flags( rrec->rdata );
+
+ num_ips = rrec->rdlength / 6;
+ if(num_ips == 0)
+ {
+ DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
returned for name %s.\n", nmb_namestr(nmbname) ));
- return;
- }
-
- if(num_ips == 1) {
- iplist = &ip;
- } else {
- if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL) {
- DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
- return;
- }
-
- for(i = 0; i < num_ips; i++)
- putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
- }
-
- /* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
-
- if(rrec == PERMANENT_TTL)
- ttl = lp_max_ttl();
-
- pull_ascii_nstring(name, sizeof(name), nmbname->name);
- namerec = add_name_to_subnet( orig_broadcast_subnet, name,
- nmbname->name_type, nb_flags, ttl,
- WINS_PROXY_NAME, num_ips, iplist );
-
- if(iplist != &ip)
- SAFE_FREE(iplist);
-
- /*
- * Check that none of the IP addresses we are returning is on the
- * same broadcast subnet as the original requesting packet. If it
- * is then don't reply (although we still need to add the name
- * to the cache) as the actual machine will be replying also
- * and we don't want two replies to a broadcast query.
- */
-
- if(namerec && original_packet->packet.nmb.header.nm_flags.bcast) {
- for( i = 0; i < namerec->data.num_ips; i++) {
- if( same_net( namerec->data.ip[i], orig_broadcast_subnet->myip,
- orig_broadcast_subnet->mask_ip ) ) {
- DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
+ return;
+ }
+
+ if(num_ips == 1)
+ iplist = &ip;
+ else
+ {
+ if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL)
+ {
+ DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
+ return;
+ }
+
+ for(i = 0; i < num_ips; i++)
+ putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
+ }
+
+ /* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
+
+ if(rrec == PERMANENT_TTL)
+ ttl = lp_max_ttl();
+
+ namerec = add_name_to_subnet( orig_broadcast_subnet, nmbname->name,
+ nmbname->name_type, nb_flags, ttl,
+ WINS_PROXY_NAME, num_ips, iplist );
+
+ if(iplist != &ip)
+ SAFE_FREE(iplist);
+
+ /*
+ * Check that none of the IP addresses we are returning is on the
+ * same broadcast subnet as the original requesting packet. If it
+ * is then don't reply (although we still need to add the name
+ * to the cache) as the actual machine will be replying also
+ * and we don't want two replies to a broadcast query.
+ */
+
+ if(namerec && original_packet->packet.nmb.header.nm_flags.bcast)
+ {
+ for( i = 0; i < namerec->data.num_ips; i++)
+ {
+ if( same_net( namerec->data.ip[i],
+ orig_broadcast_subnet->myip,
+ orig_broadcast_subnet->mask_ip ) )
+ {
+ DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
proxy name and is also on the same subnet (%s) as the requestor. \
-Not replying.\n", nmb_namestr(&namerec->name), orig_broadcast_subnet->subnet_name ) );
- return;
- }
- }
- }
-
- /* Finally reply to the original name query. */
- reply_netbios_packet(original_packet, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rrec->rdata, /* data to send. */
- rrec->rdlength); /* data length. */
+Not replying.\n",
+ nmb_namestr(&namerec->name),
+ orig_broadcast_subnet->subnet_name ) );
+ return;
+ }
+ }
+ }
+
+ /* Finally reply to the original name query. */
+ reply_netbios_packet(original_packet, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rrec->rdata, /* data to send. */
+ rrec->rdlength); /* data length. */
}
/****************************************************************************
@@ -119,7 +127,7 @@ static void wins_proxy_name_query_request_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
+ DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
of name %s.\n", fail_code, nmb_namestr(question_name) ));
}
@@ -130,35 +138,38 @@ proxy query returns.
static struct userdata_struct *wins_proxy_userdata_copy_fn(struct userdata_struct *userdata)
{
- struct packet_struct *p, *copy_of_p;
- struct userdata_struct *new_userdata = (struct userdata_struct *)malloc( userdata->userdata_len );
+ struct packet_struct *p, *copy_of_p;
+ struct userdata_struct *new_userdata =
+ (struct userdata_struct *)malloc( userdata->userdata_len );
- if(new_userdata == NULL)
- return NULL;
+ if(new_userdata == NULL)
+ return NULL;
- new_userdata->copy_fn = userdata->copy_fn;
- new_userdata->free_fn = userdata->free_fn;
- new_userdata->userdata_len = userdata->userdata_len;
+ new_userdata->copy_fn = userdata->copy_fn;
+ new_userdata->free_fn = userdata->free_fn;
+ new_userdata->userdata_len = userdata->userdata_len;
- /* Copy the subnet_record pointer. */
- memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
+ /* Copy the subnet_record pointer. */
+ memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)], sizeof(struct packet_struct *) );
+ /* Extract the pointer to the packet struct */
+ memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
+ sizeof(struct packet_struct *) );
- /* Do a deep copy of the packet. */
- if((copy_of_p = copy_packet(p)) == NULL) {
- SAFE_FREE(new_userdata);
- return NULL;
- }
+ /* Do a deep copy of the packet. */
+ if((copy_of_p = copy_packet(p)) == NULL)
+ {
+ SAFE_FREE(new_userdata);
+ return NULL;
+ }
- /* Lock the copy. */
- copy_of_p->locked = True;
+ /* Lock the copy. */
+ copy_of_p->locked = True;
- memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)&copy_of_p,
- sizeof(struct packet_struct *) );
+ memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)&copy_of_p,
+ sizeof(struct packet_struct *) );
- return new_userdata;
+ return new_userdata;
}
/****************************************************************************
@@ -168,18 +179,18 @@ proxy query returned.
static void wins_proxy_userdata_free_fn(struct userdata_struct *userdata)
{
- struct packet_struct *p;
+ struct packet_struct *p;
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *));
+ /* Extract the pointer to the packet struct */
+ memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
+ sizeof(struct packet_struct *));
- /* Unlock the packet. */
- p->locked = False;
+ /* Unlock the packet. */
+ p->locked = False;
- free_packet(p);
- ZERO_STRUCTP(userdata);
- SAFE_FREE(userdata);
+ free_packet(p);
+ ZERO_STRUCTP(userdata);
+ SAFE_FREE(userdata);
}
/****************************************************************************
@@ -190,24 +201,22 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec,
struct packet_struct *incoming_packet,
struct nmb_name *question_name)
{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
- sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
- unstring qname;
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
+ sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
- memset(ud, '\0', sizeof(ud));
+ memset(ud, '\0', sizeof(ud));
- userdata->copy_fn = wins_proxy_userdata_copy_fn;
- userdata->free_fn = wins_proxy_userdata_free_fn;
- userdata->userdata_len = sizeof(ud);
- memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
- memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
- sizeof(struct packet_struct *));
-
- /* Now use the unicast subnet to query the name with the WINS server. */
- pull_ascii_nstring(qname, sizeof(qname), question_name->name);
- query_name( unicast_subnet, qname, question_name->name_type,
- wins_proxy_name_query_request_success,
- wins_proxy_name_query_request_fail,
- userdata);
+ userdata->copy_fn = wins_proxy_userdata_copy_fn;
+ userdata->free_fn = wins_proxy_userdata_free_fn;
+ userdata->userdata_len = sizeof(ud);
+ memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
+ memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
+ sizeof(struct packet_struct *));
+
+ /* Now use the unicast subnet to query the name with the WINS server. */
+ query_name( unicast_subnet, question_name->name, question_name->name_type,
+ wins_proxy_name_query_request_success,
+ wins_proxy_name_query_request_fail,
+ userdata);
}
diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c
index 0f0190adb61..72c51b469ad 100644
--- a/source/nmbd/nmbd_winsserver.c
+++ b/source/nmbd/nmbd_winsserver.c
@@ -1,8 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
- Copyright (C) Jeremy Allison 1994-2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,110 +27,30 @@
#define WINS_VERSION 1
/****************************************************************************
- Change the wins owner address in the record.
-*****************************************************************************/
-
-static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
-{
- if (namerec==NULL)
- return;
- namerec->data.wins_ip=wins_ip;
-}
-
-/****************************************************************************
- Create the wins flags based on the nb flags and the input value.
-*****************************************************************************/
-
-static void update_wins_flag(struct name_record *namerec, int flags)
-{
- if (namerec==NULL)
- return;
-
- namerec->data.wins_flags=0x0;
-
- /* if it's a group, it can be a normal or a special one */
- if (namerec->data.nb_flags & NB_GROUP) {
- if (namerec->name.name_type==0x1C)
- namerec->data.wins_flags|=WINS_SGROUP;
- else
- if (namerec->data.num_ips>1)
- namerec->data.wins_flags|=WINS_SGROUP;
- else
- namerec->data.wins_flags|=WINS_NGROUP;
- } else {
- /* can be unique or multi-homed */
- if (namerec->data.num_ips>1)
- namerec->data.wins_flags|=WINS_MHOMED;
- else
- namerec->data.wins_flags|=WINS_UNIQUE;
- }
-
- /* the node type are the same bits */
- namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
-
- /* the static bit is elsewhere */
- if (namerec->data.death_time == PERMANENT_TTL)
- namerec->data.wins_flags|=WINS_STATIC;
-
- /* and add the given bits */
- namerec->data.wins_flags|=flags;
-
- DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
- namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
-}
-
-/****************************************************************************
- Return the general ID value and increase it if requested.
-*****************************************************************************/
-
-static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
-{
- /*
- * it's kept as a static here, to prevent people from messing
- * with the value directly
- */
-
- static SMB_BIG_UINT general_id = 1;
-
- DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
-
- *current_id = general_id;
-
- if (update)
- general_id++;
-}
-
-/****************************************************************************
- Possibly call the WINS hook external program when a WINS change is made.
+possibly call the WINS hook external program when a WINS change is made
*****************************************************************************/
static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
{
pstring command;
- char *cmd = lp_wins_hook();
- char *p, *namestr;
+ const char *cmd = lp_wins_hook();
+ char *p;
int i;
if (!cmd || !*cmd) return;
for (p=namerec->name.name; *p; p++) {
- if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
+ if (!(isalnum((int)*p) || strchr("._-",*p))) {
DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
return;
}
}
- /* Use the name without the nametype (and scope) appended */
-
- namestr = nmb_namestr(&namerec->name);
- if ((p = strchr(namestr, '<')))
- *p = 0;
-
p = command;
p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
cmd,
operation,
- namestr,
+ namerec->name.name,
namerec->name.name_type,
ttl);
@@ -143,63 +64,86 @@ static void wins_hook(const char *operation, struct name_record *namerec, int tt
/****************************************************************************
-Determine if this packet should be allocated to the WINS server.
+hash our interfaces and netbios names settings
*****************************************************************************/
-
-BOOL packet_is_for_wins_server(struct packet_struct *packet)
+static unsigned wins_hash(void)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ int i;
+ unsigned ret = iface_hash();
+ extern char **my_netbios_names;
- /* Only unicast packets go to a WINS server. */
- if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
- return False;
- }
+ for (i=0;my_netbios_names[i];i++)
+ ret ^= str_checksum(my_netbios_names[i]);
+
+ ret ^= str_checksum(lp_workgroup());
- /* Check for node status requests. */
- if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
- return False;
-
- switch(nmb->header.opcode) {
- /*
- * A WINS server issues WACKS, not receives them.
- */
- case NMB_WACK_OPCODE:
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
- return False;
- /*
- * A WINS server only processes registration and
- * release requests, not responses.
- */
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if(nmb->header.response) {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
- return False;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if(nmb->header.response) {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
- return False;
- }
- break;
-
- /*
- * Only process unicast name queries with rd = 1.
- */
- case NMB_NAME_QUERY_OPCODE:
- if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
- return False;
- }
- break;
- }
+ return ret;
+}
+
- return True;
+/****************************************************************************
+Determine if this packet should be allocated to the WINS server.
+*****************************************************************************/
+
+BOOL packet_is_for_wins_server(struct packet_struct *packet)
+{
+ struct nmb_packet *nmb = &packet->packet.nmb;
+
+ /* Only unicast packets go to a WINS server. */
+ if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
+ {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
+ return False;
+ }
+
+ /* Check for node status requests. */
+ if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
+ return False;
+
+ switch(nmb->header.opcode)
+ {
+ /*
+ * A WINS server issues WACKS, not receives them.
+ */
+ case NMB_WACK_OPCODE:
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
+ return False;
+ /*
+ * A WINS server only processes registration and
+ * release requests, not responses.
+ */
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ if(nmb->header.response)
+ {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
+ return False;
+ }
+ break;
+
+ case NMB_NAME_RELEASE_OPCODE:
+ if(nmb->header.response)
+ {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
+ return False;
+ }
+ break;
+
+ /*
+ * Only process unicast name queries with rd = 1.
+ */
+ case NMB_NAME_QUERY_OPCODE:
+ if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
+ {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
+ return False;
+ }
+ break;
+ }
+
+ return True;
}
/****************************************************************************
@@ -208,15 +152,15 @@ Utility function to decide what ttl to give a register/refresh request.
static int get_ttl_from_packet(struct nmb_packet *nmb)
{
- int ttl = nmb->additional->ttl;
+ int ttl = nmb->additional->ttl;
- if(ttl < lp_min_wins_ttl() )
- ttl = lp_min_wins_ttl();
+ if(ttl < lp_min_wins_ttl() )
+ ttl = lp_min_wins_ttl();
- if(ttl > lp_max_wins_ttl() )
- ttl = lp_max_wins_ttl();
+ if(ttl > lp_max_wins_ttl() )
+ ttl = lp_max_wins_ttl();
- return ttl;
+ return ttl;
}
/****************************************************************************
@@ -225,160 +169,178 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
- time_t time_now = time(NULL);
- XFILE *fp;
- pstring line;
-
- if(!lp_we_are_a_wins_server())
- return True;
-
- add_samba_names_to_subnet(wins_server_subnet);
-
- if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
- WINS_LIST, strerror(errno) ));
- return True;
- }
-
- while (!x_feof(fp)) {
- pstring name_str, ip_str, ttl_str, nb_flags_str;
- unsigned int num_ips;
- pstring name;
- struct in_addr *ip_list;
- int type = 0;
- int nb_flags;
- int ttl;
- const char *ptr;
- char *p;
- BOOL got_token;
- BOOL was_ip;
- int i;
- unsigned int hash;
- int version;
-
- /* Read a line from the wins.dat file. Strips whitespace
- from the beginning and end of the line. */
- if (!fgets_slash(line,sizeof(pstring),fp))
- continue;
+ time_t time_now = time(NULL);
+ FILE *fp;
+ pstring line;
+
+ if(!lp_we_are_a_wins_server())
+ return True;
+
+ add_samba_names_to_subnet(wins_server_subnet);
+
+ if((fp = sys_fopen(lock_path(WINS_LIST),"r")) == NULL)
+ {
+ DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
+ WINS_LIST, strerror(errno) ));
+ return True;
+ }
+
+ while (!feof(fp))
+ {
+ pstring name_str, ip_str, ttl_str, nb_flags_str;
+ unsigned int num_ips;
+ pstring name;
+ struct in_addr *ip_list;
+ int type = 0;
+ int nb_flags;
+ int ttl;
+ const char *ptr;
+ char *p;
+ BOOL got_token;
+ BOOL was_ip;
+ int i;
+ unsigned hash;
+ int version;
+
+ /* Read a line from the wins.dat file. Strips whitespace
+ from the beginning and end of the line.
+ */
+ if (!fgets_slash(line,sizeof(pstring),fp))
+ continue;
- if (*line == '#')
- continue;
-
- if (strncmp(line,"VERSION ", 8) == 0) {
- if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
- version != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
- x_fclose(fp);
- return True;
- }
- continue;
- }
-
- ptr = line;
-
- /*
- * Now we handle multiple IP addresses per name we need
- * to iterate over the line twice. The first time to
- * determine how many IP addresses there are, the second
- * time to actually parse them into the ip_list array.
- */
-
- if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
- DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
- continue;
- }
-
- if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
- DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
- continue;
- }
-
- /*
- * Determine the number of IP addresses per line.
- */
- num_ips = 0;
- do {
- got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
- was_ip = False;
-
- if(got_token && strchr(ip_str, '.')) {
- num_ips++;
- was_ip = True;
- }
- } while( got_token && was_ip);
-
- if(num_ips == 0) {
- DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
- continue;
- }
-
- if(!got_token) {
- DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
- continue;
- }
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
- }
+ if (*line == '#')
+ continue;
+
+ if (strncmp(line,"VERSION ", 8) == 0) {
+ if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
+ version != WINS_VERSION ||
+ hash != wins_hash()) {
+ DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
+ fclose(fp);
+ return True;
+ }
+ continue;
+ }
+
+ ptr = line;
+
+ /*
+ * Now we handle multiple IP addresses per name we need
+ * to iterate over the line twice. The first time to
+ * determine how many IP addresses there are, the second
+ * time to actually parse them into the ip_list array.
+ */
+
+ if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
+ {
+ DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
+ continue;
+ }
+
+ if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
+ {
+ DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
+ continue;
+ }
+
+ /*
+ * Determine the number of IP addresses per line.
+ */
+ num_ips = 0;
+ do
+ {
+ got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
+ was_ip = False;
+
+ if(got_token && strchr(ip_str, '.'))
+ {
+ num_ips++;
+ was_ip = True;
+ }
+ } while( got_token && was_ip);
+
+ if(num_ips == 0)
+ {
+ DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
+ continue;
+ }
+
+ if(!got_token)
+ {
+ DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
+ continue;
+ }
+
+ /* Allocate the space for the ip_list. */
+ if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
+ {
+ DEBUG(0,("initialise_wins: Malloc fail !\n"));
+ return False;
+ }
- /* Reset and re-parse the line. */
- ptr = line;
- next_token(&ptr,name_str,NULL,sizeof(name_str));
- next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
- for(i = 0; i < num_ips; i++) {
- next_token(&ptr, ip_str, NULL, sizeof(ip_str));
- ip_list[i] = *interpret_addr2(ip_str);
- }
- next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
-
- /*
- * Deal with SELF or REGISTER name encoding. Default is REGISTER
- * for compatibility with old nmbds.
- */
-
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
- DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
- SAFE_FREE(ip_list);
- continue;
- }
+ /* Reset and re-parse the line. */
+ ptr = line;
+ next_token(&ptr,name_str,NULL,sizeof(name_str));
+ next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
+ for(i = 0; i < num_ips; i++)
+ {
+ next_token(&ptr, ip_str, NULL, sizeof(ip_str));
+ ip_list[i] = *interpret_addr2(ip_str);
+ }
+ next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
+
+ /*
+ * Deal with SELF or REGISTER name encoding. Default is REGISTER
+ * for compatibility with old nmbds.
+ */
+
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
+ {
+ DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
+ SAFE_FREE(ip_list);
+ continue;
+ }
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
- nb_flags_str[strlen(nb_flags_str)-1] = '\0';
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
+ nb_flags_str[strlen(nb_flags_str)-1] = '\0';
- /* Netbios name. # divides the name from the type (hex): netbios#xx */
- pstrcpy(name,name_str);
+ /* Netbios name. # divides the name from the type (hex): netbios#xx */
+ pstrcpy(name,name_str);
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
+ if((p = strchr(name,'#')) != NULL)
+ {
+ *p = 0;
+ sscanf(p+1,"%x",&type);
+ }
- /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
- sscanf(nb_flags_str,"%x",&nb_flags);
- sscanf(ttl_str,"%d",&ttl);
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
+ /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
+ sscanf(nb_flags_str,"%x",&nb_flags);
+ sscanf(ttl_str,"%d",&ttl);
+
+ /* add all entries that have 60 seconds or more to live */
+ if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
+ {
+ if(ttl != PERMANENT_TTL)
+ ttl -= time_now;
- DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list );
- } else {
- DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
+ DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- SAFE_FREE(ip_list);
- }
+ (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
+ ttl, REGISTER_NAME, num_ips, ip_list );
+
+ }
+ else
+ {
+ DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+ }
+
+ SAFE_FREE(ip_list);
+ }
- x_fclose(fp);
- return True;
+ fclose(fp);
+ return True;
}
/****************************************************************************
@@ -387,33 +349,30 @@ Send a WINS WACK (Wait ACKnowledgement) response.
static void send_wins_wack_response(int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char rdata[2];
-
- rdata[0] = rdata[1] = 0;
-
- /* Taken from nmblib.c - we need to send back almost
- identical bytes from the requesting packet header. */
-
- rdata[0] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.nm_flags.authoritative && nmb->header.response)
- rdata[0] |= 0x4;
- if (nmb->header.nm_flags.trunc)
- rdata[0] |= 0x2;
- if (nmb->header.nm_flags.recursion_desired)
- rdata[0] |= 0x1;
- if (nmb->header.nm_flags.recursion_available && nmb->header.response)
- rdata[1] |= 0x80;
- if (nmb->header.nm_flags.bcast)
- rdata[1] |= 0x10;
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_WAIT_ACK, /* nmbd type code. */
- NMB_WACK_OPCODE, /* opcode. */
- ttl, /* ttl. */
- (char *)rdata, /* data to send. */
- 2); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ unsigned char rdata[2];
+
+ rdata[0] = rdata[1] = 0;
+
+ /* Taken from nmblib.c - we need to send back almost
+ identical bytes from the requesting packet header. */
+
+ rdata[0] = (nmb->header.opcode & 0xF) << 3;
+ if (nmb->header.nm_flags.authoritative &&
+ nmb->header.response) rdata[0] |= 0x4;
+ if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
+ if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
+ if (nmb->header.nm_flags.recursion_available &&
+ nmb->header.response) rdata[1] |= 0x80;
+ if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_WAIT_ACK, /* nmbd type code. */
+ NMB_WACK_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ (char *)rdata, /* data to send. */
+ 2); /* data length. */
}
/****************************************************************************
@@ -422,189 +381,134 @@ Send a WINS name registration response.
static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
+
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ WINS_REG, /* nmbd type code. */
+ NMB_NAME_REG_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/***********************************************************************
Deal with a name refresh request to a WINS server.
************************************************************************/
-void wins_process_name_refresh_request( struct subnet_record *subrec,
- struct packet_struct *p )
+void wins_process_name_refresh_request(struct subnet_record *subrec,
+ struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = get_ttl_from_packet(nmb);
- struct in_addr from_ip;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip( (char *)&from_ip, &nmb->additional->rdata[2] );
-
- if(bcast) {
- /*
- * We should only get unicast name refresh packets here.
- * Anyone trying to refresh broadcast should not be going
- * to a WINS server. Log an error here.
- */
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Broadcast name refresh request received " );
- dbgtext( "for name %s ", nmb_namestr(question) );
- dbgtext( "from IP %s ", inet_ntoa(from_ip) );
- dbgtext( "on subnet %s. ", subrec->subnet_name );
- dbgtext( "Error - Broadcasts should not be sent " );
- dbgtext( "to a WINS server\n" );
- }
- return;
- }
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name refresh for name %s IP %s\n",
- nmb_namestr(question), inet_ntoa(from_ip) );
- }
-
- /*
- * See if the name already exists.
- * If not, handle it as a name registration and return.
- */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * If this is a refresh request and the name doesn't exist then
- * treat it like a registration request. This allows us to recover
- * from errors (tridge)
- */
- if(namerec == NULL) {
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name refresh for name %s ",
- nmb_namestr( question ) );
- dbgtext( "and the name does not exist. Treating " );
- dbgtext( "as registration.\n" );
- }
- wins_process_name_registration_request(subrec,p);
- return;
- }
-
- /*
- * if the name is present but not active, simply remove it
- * and treat the refresh request as a registration & return.
- */
- if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
- if( DEBUGLVL( 5 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
- dbgtext( "was not active - removing it.\n" );
- }
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- wins_process_name_registration_request( subrec, p );
- return;
- }
-
- /*
- * Check that the group bits for the refreshing name and the
- * name in our database match. If not, refuse the refresh.
- * [crh: Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
- */
- if( (namerec != NULL) &&
- ( (group && !NAME_GROUP(namerec))
- || (!group && NAME_GROUP(namerec)) ) ) {
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name %s ", nmb_namestr(question) );
- dbgtext( "group bit = %s does not match ",
- group ? "True" : "False" );
- dbgtext( "group bit in WINS for this name.\n" );
- }
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec = NULL;
+ int ttl = get_ttl_from_packet(nmb);
+ struct in_addr from_ip;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast)
+ {
+ /*
+ * We should only get unicast name refresh packets here.
+ * Anyone trying to refresh broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
+received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- /*
- * For a unique name check that the person refreshing the name is
- * one of the registered IP addresses. If not - fail the refresh.
- * Do the same for group names with a type of 0x1c.
- * Just return success for unique 0x1d refreshes. For normal group
- * names update the ttl and return success.
- */
- if( (!group || (group && (question->name_type == 0x1c)))
- && find_ip_in_name_record(namerec, from_ip) ) {
- /*
- * Update the ttl.
- */
- update_name_ttl(namerec, ttl);
-
- /*
- * if the record is a replica:
- * we take ownership and update the version ID.
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- update_wins_owner(namerec, our_fake_ip);
- get_global_id_and_update(&namerec->data.id, True);
- }
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
+IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- } else if((group && (question->name_type == 0x1c))) {
- /*
- * Added by crh for bug #1079.
- * Fix from Bert Driehuis
- */
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name refresh for name %s, ",
- nmb_namestr(question) );
- dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
- dbgtext( "is not yet associated with " );
- dbgtext( "that name. Treating as registration.\n" );
- }
- wins_process_name_registration_request(subrec,p);
- return;
- } else if(group) {
- /*
- * Normal groups are all registered with an IP address of
- * 255.255.255.255 so we can't search for the IP address.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- } else if(!group && (question->name_type == 0x1d)) {
- /*
- * Special name type - just pretend the refresh succeeded.
- */
- send_wins_name_registration_response(0, ttl, p);
- return;
- } else {
- /*
- * Fail the refresh.
- */
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "wins_process_name_refresh_request: " );
- dbgtext( "Name refresh for name %s with IP %s ",
- nmb_namestr(question), inet_ntoa(from_ip) );
- dbgtext( "and is IP is not known to the name.\n" );
- }
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
+ /*
+ * See if the name already exists.
+ */
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ /*
+ * If this is a refresh request and the name doesn't exist then
+ * treat it like a registration request. This allows us to recover
+ * from errors (tridge)
+ */
+
+ if(namerec == NULL)
+ {
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
+the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
+ wins_process_name_registration_request(subrec,p);
+ return;
+ }
+
+ /*
+ * Check that the group bits for the refreshing name and the
+ * name in our database match.
+ */
+
+ if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
+ {
+ DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
+does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * For a unique name check that the person refreshing the name is one of the registered IP
+ * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
+ * Just return success for unique 0x1d refreshes. For normal group names update the ttl
+ * and return success.
+ */
+
+ if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
+ {
+ /*
+ * Update the ttl.
+ */
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+ else if(group)
+ {
+ /*
+ * Normal groups are all registered with an IP address of 255.255.255.255
+ * so we can't search for the IP address.
+ */
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+ else if(!group && (question->name_type == 0x1d))
+ {
+ /*
+ * Special name type - just pretend the refresh succeeded.
+ */
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+ else
+ {
+ /*
+ * Fail the refresh.
+ */
+
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
+is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
}
/***********************************************************************
@@ -623,17 +527,17 @@ static void wins_register_query_success(struct subnet_record *subrec,
struct in_addr ip,
struct res_rec *answers)
{
- struct packet_struct *orig_reg_packet;
+ struct packet_struct *orig_reg_packet;
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
- DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
+ DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -651,37 +555,40 @@ static void wins_register_query_fail(struct subnet_record *subrec,
struct nmb_name *question_name,
int rcode)
{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
- struct name_record *namerec = NULL;
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- /*
- * We want to just add the name, as we now know the original owner
- * didn't want it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this timeout/error response. So we check that
- * the name still exists and is in the same state - if so
- * we remove it and call wins_process_name_registration_request()
- * as we know it will do the right thing now.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec != NULL) && (namerec->data.source == REGISTER_NAME) && ip_equal(rrec->packet->ip, *namerec->data.ip) ) {
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- if(namerec == NULL)
- wins_process_name_registration_request(subrec, orig_reg_packet);
- else
- DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
+ struct userdata_struct *userdata = rrec->userdata;
+ struct packet_struct *orig_reg_packet;
+ struct name_record *namerec = NULL;
+
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+
+ /*
+ * We want to just add the name, as we now know the original owner
+ * didn't want it. But we can't just do that as an arbitary
+ * amount of time may have taken place between the name query
+ * request and this timeout/error response. So we check that
+ * the name still exists and is in the same state - if so
+ * we remove it and call wins_process_name_registration_request()
+ * as we know it will do the right thing now.
+ */
+
+ namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
+
+ if( (namerec != NULL)
+ && (namerec->data.source == REGISTER_NAME)
+ && ip_equal(rrec->packet->ip, *namerec->data.ip) )
+ {
+ remove_name_from_namelist( subrec, namerec);
+ namerec = NULL;
+ }
+
+ if(namerec == NULL)
+ wins_process_name_registration_request(subrec, orig_reg_packet);
+ else
+ DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -744,271 +651,242 @@ querying for name %s in order to replace it and this reply.\n", nmb_namestr(ques
void wins_process_name_registration_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- unstring name;
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast) {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ int ttl = get_ttl_from_packet(nmb);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast)
+ {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
+ DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
- if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
-not active - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
+ /*
+ * See if the name already exists.
+ */
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
- if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
-a dns lookup - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
+ /*
+ * Deal with the case where the name found was a dns entry.
+ * Remove it as we now have a NetBIOS client registering the
+ * name.
+ */
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
- DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
+ if( (namerec != NULL)
+ && ( (namerec->data.source == DNS_NAME)
+ || (namerec->data.source == DNSFAIL_NAME) ) )
+ {
+ DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
+a dns lookup - removing it.\n", nmb_namestr(question) ));
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ }
+
+ /*
+ * Reject if the name exists and is not a REGISTER_NAME.
+ * (ie. Don't allow any static names to be overwritten.
+ */
+
+ if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
+ {
+ DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Special policy decisions based on MS documentation.
- * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
- * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
- */
-
- /*
- * A group name is always added as the local broadcast address, except
- * for group names ending in 0x1c.
- * Group names with type 0x1c are registered with individual IP addresses.
- */
-
- if(registering_group_name && (question->name_type != 0x1c))
- from_ip = *interpret_addr2("255.255.255.255");
-
- /*
- * Ignore all attempts to register a unique 0x1d name, although return success.
- */
-
- if(!registering_group_name && (question->name_type == 0x1d)) {
- DEBUG(3,("wins_process_name_registration_request: Ignoring request \
+ nmb_namestr(question), namerec->data.source ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * Special policy decisions based on MS documentation.
+ * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
+ * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
+ */
+
+ /*
+ * A group name is always added as the local broadcast address, except
+ * for group names ending in 0x1c.
+ * Group names with type 0x1c are registered with individual IP addresses.
+ */
+
+ if(registering_group_name && (question->name_type != 0x1c))
+ from_ip = *interpret_addr2("255.255.255.255");
+
+ /*
+ * Ignore all attempts to register a unique 0x1d name, although return success.
+ */
+
+ if(!registering_group_name && (question->name_type == 0x1d))
+ {
+ DEBUG(3,("wins_process_name_registration_request: Ignoring request \
to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * Next two cases are the 'if statement' mentioned above.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec)) {
- if(registering_group_name) {
- /*
- * If we are adding a group name, the name exists and is also a group entry just add this
- * IP address to it and update the ttl.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
- inet_ntoa(from_ip), nmb_namestr(question) ));
-
- /*
- * Check the ip address is not already in the group.
- */
-
- if(!find_ip_in_name_record(namerec, from_ip)) {
- add_ip_to_name_record(namerec, from_ip);
- /* we need to update the record for replication */
- get_global_id_and_update(&namerec->data.id, True);
-
- /*
- * if the record is a replica, we must change
- * the wins owner to us to make the replication updates
- * it on the other wins servers.
- * And when the partner will receive this record,
- * it will update its own record.
- */
-
- update_wins_owner(namerec, our_fake_ip);
- }
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- } else {
-
- /*
- * If we are adding a unique name, the name exists in the WINS db
- * and is a group name then reject the registration.
- *
- * explanation: groups have a higher priority than unique names.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+
+ /*
+ * Next two cases are the 'if statement' mentioned above.
+ */
+
+ if((namerec != NULL) && NAME_GROUP(namerec))
+ {
+ if(registering_group_name)
+ {
+ /*
+ * If we are adding a group name, the name exists and is also a group entry just add this
+ * IP address to it and update the ttl.
+ */
+
+ DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
+ inet_ntoa(from_ip), nmb_namestr(question) ));
+ /*
+ * Check the ip address is not already in the group.
+ */
+ if(!find_ip_in_name_record(namerec, from_ip))
+ add_ip_to_name_record(namerec, from_ip);
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+ else
+ {
+ /*
+ * If we are adding a unique name, the name exists in the WINS db
+ * and is a group name then reject the registration.
+ */
+
+ DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if ( namerec != NULL )
- pull_ascii_nstring(name, sizeof(name), namerec->name.name);
-
- if( is_myname(name) ) {
- if(!ismyip(from_ip)) {
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+ }
+
+ /*
+ * From here on down we know that if the name exists in the WINS db it is
+ * a unique name, not a group name.
+ */
+
+ /*
+ * If the name exists and is one of our names then check the
+ * registering IP address. If it's not one of ours then automatically
+ * reject without doing the query - we know we will reject it.
+ */
+
+ if((namerec != NULL) && (is_myname(namerec->name.name)) )
+ {
+ if(!ismyip(from_ip))
+ {
+ DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- } else {
- /*
- * It's one of our names and one of our IP's - update the ttl.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
- }
-
- /*
- * If the name exists and it is a unique registration and the registering IP
- * is the same as the (single) already registered IP then just update the ttl.
- *
- * But not if the record is an active replica. IF it's a replica, it means it can be
- * the same client which has moved and not yet expired. So we don't update
- * the ttl in this case and go beyond to do a WACK and query the old client
- */
-
- if( !registering_group_name
- && (namerec != NULL)
- && (namerec->data.num_ips == 1)
- && ip_equal( namerec->data.ip[0], from_ip )
- && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
- update_name_ttl( namerec, ttl );
- send_wins_name_registration_response( 0, ttl, p );
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * Finally if the name exists do a query to the registering machine
- * to see if they still claim to have the name.
- */
-
- if( namerec != NULL ) {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- */
-
- pull_ascii_nstring(name, sizeof(name), question->name);
- query_name_from_wins_server( *namerec->data.ip,
- name,
- question->name_type,
- wins_register_query_success,
- wins_register_query_fail,
- userdata );
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- pull_ascii_nstring(name, sizeof(name), question->name);
- add_name_to_subnet( subrec, name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
-
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
-
- send_wins_name_registration_response(0, ttl, p);
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+ else
+ {
+ /*
+ * It's one of our names and one of our IP's - update the ttl.
+ */
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+ }
+
+ /*
+ * If the name exists and it is a unique registration and the registering IP
+ * is the same as the the (single) already registered IP then just update the ttl.
+ */
+
+ if( !registering_group_name
+ && (namerec != NULL)
+ && (namerec->data.num_ips == 1)
+ && ip_equal( namerec->data.ip[0], from_ip ) )
+ {
+ update_name_ttl( namerec, ttl );
+ send_wins_name_registration_response( 0, ttl, p );
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+
+ /*
+ * Finally if the name exists do a query to the registering machine
+ * to see if they still claim to have the name.
+ */
+
+ if( namerec != NULL )
+ {
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
+
+ /*
+ * First send a WACK to the registering machine.
+ */
+
+ send_wins_wack_response(60, p);
+
+ /*
+ * When the reply comes back we need the original packet.
+ * Lock this so it won't be freed and then put it into
+ * the userdata structure.
+ */
+
+ p->locked = True;
+
+ userdata = (struct userdata_struct *)ud;
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(struct packet_struct *);
+ memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
+
+ /*
+ * Use the new call to send a query directly to an IP address.
+ * This sends the query directly to the IP address, and ensures
+ * the recursion desired flag is not set (you were right Luke :-).
+ * This function should *only* be called from the WINS server
+ * code. JRA.
+ */
+
+ query_name_from_wins_server( *namerec->data.ip,
+ question->name,
+ question->name_type,
+ wins_register_query_success,
+ wins_register_query_fail,
+ userdata );
+ return;
+ }
+
+ /*
+ * Name did not exist - add it.
+ */
+
+ (void)add_name_to_subnet( subrec, question->name, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
+ if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+ wins_hook("add", namerec, ttl);
+ }
+
+ send_wins_name_registration_response(0, ttl, p);
}
/***********************************************************************
@@ -1025,54 +903,50 @@ static void wins_multihomed_register_query_success(struct subnet_record *subrec,
struct in_addr ip,
struct res_rec *answers)
{
- struct packet_struct *orig_reg_packet;
- struct nmb_packet *nmb;
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- int ttl;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- nmb = &orig_reg_packet->packet.nmb;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
- ttl = get_ttl_from_packet(nmb);
-
- /*
- * We want to just add the new IP, as we now know the requesting
- * machine claims to own it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this response. So we check that
- * the name still exists and is in the same state - if so
- * we just add the extra IP and update the ttl.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
- DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
-a subsequent IP address.\n", nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
-
- return;
- }
-
- if(!find_ip_in_name_record(namerec, from_ip))
- add_ip_to_name_record(namerec, from_ip);
-
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, orig_reg_packet);
- wins_hook("add", namerec, ttl);
-
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ struct packet_struct *orig_reg_packet;
+ struct nmb_packet *nmb;
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ int ttl;
+
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+
+ nmb = &orig_reg_packet->packet.nmb;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+ ttl = get_ttl_from_packet(nmb);
+
+ /*
+ * We want to just add the new IP, as we now know the requesting
+ * machine claims to own it. But we can't just do that as an arbitary
+ * amount of time may have taken place between the name query
+ * request and this response. So we check that
+ * the name still exists and is in the same state - if so
+ * we just add the extra IP and update the ttl.
+ */
+
+ namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
+
+ if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
+ {
+ DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
+a subsequent IP addess.\n", nmb_namestr(question_name) ));
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
+
+ return;
+ }
+
+ if(!find_ip_in_name_record(namerec, from_ip))
+ add_ip_to_name_record(namerec, from_ip);
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, orig_reg_packet);
+ wins_hook("add", namerec, ttl);
+
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -1088,18 +962,18 @@ static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
struct nmb_name *question_name,
int rcode)
{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
+ struct userdata_struct *userdata = rrec->userdata;
+ struct packet_struct *orig_reg_packet;
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
- DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
+ DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
- return;
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
+ return;
}
/***********************************************************************
@@ -1110,241 +984,222 @@ query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(
void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
- unstring qname;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast) {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ int ttl = get_ttl_from_packet(nmb);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast)
+ {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- /*
- * Only unique names should be registered multihomed.
- */
+ /*
+ * Only unique names should be registered multihomed.
+ */
- if(group) {
- DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
+ if(group)
+ {
+ DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
+ DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * Deal with policy regarding 0x1d names.
- */
+ /*
+ * Deal with policy regarding 0x1d names.
+ */
- if(question->name_type == 0x1d) {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
+ if(question->name_type == 0x1d)
+ {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
-
- if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
- remove_name_from_namelist(subrec, namerec);
- namerec = NULL;
- }
-
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
-
- if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+
+ /*
+ * See if the name already exists.
+ */
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ /*
+ * Deal with the case where the name found was a dns entry.
+ * Remove it as we now have a NetBIOS client registering the
+ * name.
+ */
+
+ if( (namerec != NULL)
+ && ( (namerec->data.source == DNS_NAME)
+ || (namerec->data.source == DNSFAIL_NAME) ) )
+ {
+ DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
- removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
- DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
+ remove_name_from_namelist( subrec, namerec);
+ namerec = NULL;
+ }
+
+ /*
+ * Reject if the name exists and is not a REGISTER_NAME.
+ * (ie. Don't allow any static names to be overwritten.
+ */
+
+ if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
+ {
+ DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Reject if the name exists and is a GROUP name and is active.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
+ nmb_namestr(question), namerec->data.source ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * Reject if the name exists and is a GROUP name.
+ */
+
+ if((namerec != NULL) && NAME_GROUP(namerec))
+ {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
- if(!ismyip(from_ip)) {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * From here on down we know that if the name exists in the WINS db it is
+ * a unique name, not a group name.
+ */
+
+ /*
+ * If the name exists and is one of our names then check the
+ * registering IP address. If it's not one of ours then automatically
+ * reject without doing the query - we know we will reject it.
+ */
+
+ if((namerec != NULL) && (is_myname(namerec->name.name)) )
+ {
+ if(!ismyip(from_ip))
+ {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- } else {
- /*
- * It's one of our names and one of our IP's. Ensure the IP is in the record and
- * update the ttl. Update the version ID to force replication.
- */
- if(!find_ip_in_name_record(namerec, from_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
-
- add_ip_to_name_record(namerec, from_ip);
- wins_hook("add", namerec, ttl);
- } else {
- wins_hook("refresh", namerec, ttl);
- }
-
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- }
-
- /*
- * If the name exists and is active, check if the IP address is already registered
- * to that name. If so then update the ttl and reply success.
- */
-
- if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
- update_name_ttl(namerec, ttl);
-
- /*
- * If it's a replica, we need to become the wins owner
- * to force the replication
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- }
-
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * If the name exists do a query to the owner
- * to see if they still want the name.
- */
-
- if(namerec != NULL) {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- *
- * Note that this packet is sent to the current owner of the name,
- * not the person who sent the packet
- */
-
- pull_ascii_nstring( qname, sizeof(qname), question->name);
- query_name_from_wins_server( namerec->data.ip[0],
- qname,
- question->name_type,
- wins_multihomed_register_query_success,
- wins_multihomed_register_query_fail,
- userdata );
-
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- pull_ascii_nstring( qname, sizeof(qname), question->name);
- add_name_to_subnet( subrec, qname, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
-
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
-
- send_wins_name_registration_response(0, ttl, p);
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+ else
+ {
+ /*
+ * It's one of our names and one of our IP's. Ensure the IP is in the record and
+ * update the ttl.
+ */
+ if(!find_ip_in_name_record(namerec, from_ip)) {
+ add_ip_to_name_record(namerec, from_ip);
+ wins_hook("add", namerec, ttl);
+ } else {
+ wins_hook("refresh", namerec, ttl);
+ }
+
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+ }
+
+ /*
+ * If the name exists check if the IP address is already registered
+ * to that name. If so then update the ttl and reply success.
+ */
+
+ if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
+ {
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+
+ /*
+ * If the name exists do a query to the owner
+ * to see if they still want the name.
+ */
+
+ if(namerec != NULL)
+ {
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
+
+ /*
+ * First send a WACK to the registering machine.
+ */
+
+ send_wins_wack_response(60, p);
+
+ /*
+ * When the reply comes back we need the original packet.
+ * Lock this so it won't be freed and then put it into
+ * the userdata structure.
+ */
+
+ p->locked = True;
+
+ userdata = (struct userdata_struct *)ud;
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(struct packet_struct *);
+ memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
+
+ /*
+ * Use the new call to send a query directly to an IP address.
+ * This sends the query directly to the IP address, and ensures
+ * the recursion desired flag is not set (you were right Luke :-).
+ * This function should *only* be called from the WINS server
+ * code. JRA.
+ *
+ * Note that this packet is sent to the current owner of the name,
+ * not the person who sent the packet
+ */
+
+ query_name_from_wins_server( namerec->data.ip[0],
+ question->name,
+ question->name_type,
+ wins_multihomed_register_query_success,
+ wins_multihomed_register_query_fail,
+ userdata );
+
+ return;
+ }
+
+ /*
+ * Name did not exist - add it.
+ */
+
+ (void)add_name_to_subnet( subrec, question->name, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
+
+ if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+ wins_hook("add", namerec, ttl);
+ }
+
+ send_wins_name_registration_response(0, ttl, p);
}
/***********************************************************************
@@ -1354,68 +1209,76 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
static void process_wins_dmb_query_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct name_record *namerec = NULL;
- char *prdata;
- int num_ips;
-
- /*
- * Go through all the ACTIVE names in the WINS db looking for those
- * ending in <1b>. Use this to calculate the number of IP
- * addresses we need to return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
- num_ips += namerec->data.num_ips;
- }
-
- if(num_ips == 0) {
- /*
- * There are no 0x1b names registered. Return name query fail.
- */
- send_wins_name_query_response(NAM_ERR, p, NULL);
- return;
- }
-
- if((prdata = (char *)malloc( num_ips * 6 )) == NULL) {
- DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
- return;
- }
-
- /*
- * Go through all the names again in the WINS db looking for those
- * ending in <1b>. Add their IP addresses into the list we will
- * return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
- int i;
- for(i = 0; i < namerec->data.num_ips; i++) {
- set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
- putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
- num_ips++;
- }
- }
- }
-
- /*
- * Send back the reply containing the IP list.
- */
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- lp_min_wins_ttl(), /* ttl. */
- prdata, /* data to send. */
- num_ips*6); /* data length. */
-
- SAFE_FREE(prdata);
+ struct name_record *namerec = NULL;
+ char *prdata;
+ int num_ips;
+
+ /*
+ * Go through all the names in the WINS db looking for those
+ * ending in <1b>. Use this to calculate the number of IP
+ * addresses we need to return.
+ */
+
+ num_ips = 0;
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ if( namerec->name.name_type == 0x1b )
+ num_ips += namerec->data.num_ips;
+ }
+
+ if(num_ips == 0)
+ {
+ /*
+ * There are no 0x1b names registered. Return name query fail.
+ */
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ return;
+ }
+
+ if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
+ {
+ DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
+ return;
+ }
+
+ /*
+ * Go through all the names again in the WINS db looking for those
+ * ending in <1b>. Add their IP addresses into the list we will
+ * return.
+ */
+
+ num_ips = 0;
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ if(namerec->name.name_type == 0x1b)
+ {
+ int i;
+ for(i = 0; i < namerec->data.num_ips; i++)
+ {
+ set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
+ putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
+ num_ips++;
+ }
+ }
+ }
+
+ /*
+ * Send back the reply containing the IP list.
+ */
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ WINS_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ lp_min_wins_ttl(), /* ttl. */
+ prdata, /* data to send. */
+ num_ips*6); /* data length. */
+
+ SAFE_FREE(prdata);
}
/****************************************************************************
@@ -1425,48 +1288,55 @@ Send a WINS name query response.
void send_wins_name_query_response(int rcode, struct packet_struct *p,
struct name_record *namerec)
{
- char rdata[6];
- char *prdata = rdata;
- int reply_data_len = 0;
- int ttl = 0;
- int i;
-
- memset(rdata,'\0',6);
-
- if(rcode == 0) {
- ttl = (namerec->data.death_time != PERMANENT_TTL) ? namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
-
- /* Copy all known ip addresses into the return data. */
- /* Optimise for the common case of one IP address so we don't need a malloc. */
-
- if( namerec->data.num_ips == 1 ) {
- prdata = rdata;
- } else {
- if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
- DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
- return;
- }
- }
-
- for(i = 0; i < namerec->data.num_ips; i++) {
- set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
- }
-
- sort_query_replies(prdata, i, p->ip);
- reply_data_len = namerec->data.num_ips * 6;
- }
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- prdata, /* data to send. */
- reply_data_len); /* data length. */
-
- if(prdata != rdata)
- SAFE_FREE(prdata);
+ char rdata[6];
+ char *prdata = rdata;
+ int reply_data_len = 0;
+ int ttl = 0;
+ int i;
+
+ memset(rdata,'\0',6);
+
+ if(rcode == 0)
+ {
+ ttl = (namerec->data.death_time != PERMANENT_TTL) ?
+ namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
+
+ /* Copy all known ip addresses into the return data. */
+ /* Optimise for the common case of one IP address so
+ we don't need a malloc. */
+
+ if( namerec->data.num_ips == 1 )
+ prdata = rdata;
+ else
+ {
+ if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
+ {
+ DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
+ return;
+ }
+ }
+
+ for(i = 0; i < namerec->data.num_ips; i++)
+ {
+ set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
+ putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+ }
+
+ sort_query_replies(prdata, i, p->ip);
+
+ reply_data_len = namerec->data.num_ips * 6;
+ }
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ WINS_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ prdata, /* data to send. */
+ reply_data_len); /* data length. */
+
+ if((prdata != rdata) && (prdata != NULL))
+ SAFE_FREE(prdata);
}
/***********************************************************************
@@ -1476,87 +1346,82 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
void wins_process_name_query_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- struct name_record *namerec = NULL;
- unstring qname;
-
- DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
- nmb_namestr(question), inet_ntoa(p->ip) ));
-
- /*
- * Special name code. If the queried name is *<1b> then search
- * the entire WINS database and return a list of all the IP addresses
- * registered to any <1b> name. This is to allow domain master browsers
- * to discover other domains that may not have a presence on their subnet.
- */
-
- pull_ascii_nstring(qname, sizeof(qname), question->name);
- if(strequal( qname, "*") && (question->name_type == 0x1b)) {
- process_wins_dmb_query_request( subrec, p);
- return;
- }
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if(namerec != NULL) {
- /*
- * If the name is not anymore in active state then reply not found.
- * it's fair even if we keep it in the cache for days.
- */
- if (!WINS_STATE_ACTIVE(namerec)) {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- /*
- * If it's a DNSFAIL_NAME then reply name not found.
- */
-
- if( namerec->data.source == DNSFAIL_NAME ) {
- DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- /*
- * If the name has expired then reply name not found.
- */
-
- if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
- nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
-
- send_wins_name_query_response(0, p, namerec);
- return;
- }
-
- /*
- * Name not found in WINS - try a dns query if it's a 0x20 name.
- */
-
- if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
- DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
- nmb_namestr(question) ));
-
- queue_dns_query(p, question, &namerec);
- return;
- }
-
- /*
- * Name not found - return error.
- */
-
- send_wins_name_query_response(NAM_ERR, p, NULL);
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ struct name_record *namerec = NULL;
+
+ DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
+ nmb_namestr(question), inet_ntoa(p->ip) ));
+
+ /*
+ * Special name code. If the queried name is *<1b> then search
+ * the entire WINS database and return a list of all the IP addresses
+ * registered to any <1b> name. This is to allow domain master browsers
+ * to discover other domains that may not have a presence on their subnet.
+ */
+
+ if(strequal( question->name, "*") && (question->name_type == 0x1b))
+ {
+ process_wins_dmb_query_request( subrec, p);
+ return;
+ }
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ if(namerec != NULL)
+ {
+ /*
+ * If it's a DNSFAIL_NAME then reply name not found.
+ */
+
+ if( namerec->data.source == DNSFAIL_NAME )
+ {
+ DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
+ nmb_namestr(question) ));
+ send_wins_name_query_response(NAM_ERR, p, namerec);
+ return;
+ }
+
+ /*
+ * If the name has expired then reply name not found.
+ */
+
+ if( (namerec->data.death_time != PERMANENT_TTL)
+ && (namerec->data.death_time < p->timestamp) )
+ {
+ DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
+ nmb_namestr(question) ));
+ send_wins_name_query_response(NAM_ERR, p, namerec);
+ return;
+ }
+
+ DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
+ nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
+
+ send_wins_name_query_response(0, p, namerec);
+ return;
+ }
+
+ /*
+ * Name not found in WINS - try a dns query if it's a 0x20 name.
+ */
+
+ if(lp_dns_proxy() &&
+ ((question->name_type == 0x20) || question->name_type == 0))
+ {
+
+ DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
+ nmb_namestr(question) ));
+
+ queue_dns_query(p, question, &namerec);
+ return;
+ }
+
+ /*
+ * Name not found - return error.
+ */
+
+ send_wins_name_query_response(NAM_ERR, p, NULL);
}
/****************************************************************************
@@ -1565,18 +1430,18 @@ Send a WINS name release response.
static void send_wins_name_release_response(int rcode, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
+
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REL, /* nmbd type code. */
+ NMB_NAME_RELEASE_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/***********************************************************************
@@ -1586,115 +1451,99 @@ static void send_wins_name_release_response(int rcode, struct packet_struct *p)
void wins_process_name_release_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast) {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast)
+ {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
+ DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * Deal with policy regarding 0x1d names.
- */
+ /*
+ * Deal with policy regarding 0x1d names.
+ */
- if(!releasing_group_name && (question->name_type == 0x1d)) {
- DEBUG(3,("wins_process_name_release_request: Ignoring request \
+ if(!releasing_group_name && (question->name_type == 0x1d))
+ {
+ DEBUG(3,("wins_process_name_release_request: Ignoring request \
to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_release_response(0, p);
- return;
- }
+ send_wins_name_release_response(0, p);
+ return;
+ }
- /*
- * See if the name already exists.
- */
+ /*
+ * See if the name already exists.
+ */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check that the sending machine has permission to release this name.
- * If it's a group name not ending in 0x1c then just say yes and let
- * the group time out.
- */
-
- if(releasing_group_name && (question->name_type != 0x1c)) {
- send_wins_name_release_response(0, p);
- return;
- }
-
- /*
- * Check that the releasing node is on the list of IP addresses
- * for this name. Disallow the release if not.
- */
-
- if(!find_ip_in_name_record(namerec, from_ip)) {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ if( (namerec == NULL)
+ || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
+ {
+ send_wins_name_release_response(NAM_ERR, p);
+ return;
+ }
+
+ /*
+ * Check that the sending machine has permission to release this name.
+ * If it's a group name not ending in 0x1c then just say yes and let
+ * the group time out.
+ */
+
+ if(releasing_group_name && (question->name_type != 0x1c))
+ {
+ send_wins_name_release_response(0, p);
+ return;
+ }
+
+ /*
+ * Check that the releasing node is on the list of IP addresses
+ * for this name. Disallow the release if not.
+ */
+
+ if(!find_ip_in_name_record(namerec, from_ip))
+ {
+ DEBUG(3,("wins_process_name_release_request: Refusing request to \
release name %s as IP %s is not one of the known IP's for this name.\n",
- nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip) ));
+ send_wins_name_release_response(NAM_ERR, p);
+ return;
+ }
- /*
- * Check if the record is active. IF it's already released
- * or tombstoned, refuse the release.
- */
-
- if (!WINS_STATE_ACTIVE(namerec)) {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
-release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check if the record is a 0x1c group
- * and has more then one ip
- * remove only this address.
- */
-
- if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
- remove_ip_from_name_record(namerec, from_ip);
- DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
- inet_ntoa(from_ip),nmb_namestr(question)));
- send_wins_name_release_response(0, p);
- return;
- }
+ /*
+ * Release the name and then remove the IP from the known list.
+ */
- /*
- * Send a release response.
- * Flag the name as released and update the ttl
- */
+ send_wins_name_release_response(0, p);
+ remove_ip_from_name_record(namerec, from_ip);
- send_wins_name_release_response(0, p);
-
- namerec->data.wins_flags |= WINS_RELEASED;
- update_name_ttl(namerec, EXTINCTION_INTERVAL);
+ wins_hook("delete", namerec, 0);
+
+ /*
+ * Remove the name entirely if no IP addresses left.
+ */
+ if (namerec->data.num_ips == 0)
+ remove_name_from_namelist(subrec, namerec);
- wins_hook("delete", namerec, 0);
}
/*******************************************************************
@@ -1703,313 +1552,110 @@ release name %s as this record is not active anymore.\n", nmb_namestr(question)
void initiate_wins_processing(time_t t)
{
- static time_t lasttime = 0;
- struct name_record *namerec;
- struct name_record *next_namerec;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- if (!lasttime)
- lasttime = t;
- if (t - lasttime < 20)
- return;
-
- lasttime = t;
-
- if(!lp_we_are_a_wins_server())
- return;
-
- for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = next_namerec ) {
- next_namerec = (struct name_record *)ubi_trNext( namerec );
-
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) ) {
-
- if( namerec->data.source == SELF_NAME ) {
- DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF name %s\n",
- wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- namerec->subnet->namelist_changed = True;
- continue;
- }
-
- /* handle records, samba is the wins owner */
- if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- switch (namerec->data.wins_flags | WINS_STATE_MASK) {
- case WINS_ACTIVE:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_RELEASED;
- namerec->data.death_time = t + EXTINCTION_INTERVAL;
- DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
- break;
- case WINS_RELEASED:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- get_global_id_and_update(&namerec->data.id, True);
- DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
- break;
- case WINS_TOMBSTONED:
- DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
- remove_name_from_namelist( wins_server_subnet, namerec );
- break;
- }
- } else {
- switch (namerec->data.wins_flags | WINS_STATE_MASK) {
- case WINS_ACTIVE:
- /* that's not as MS says it should be */
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
- case WINS_TOMBSTONED:
- DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
- remove_name_from_namelist( wins_server_subnet, namerec );
- break;
- case WINS_RELEASED:
- DEBUG(0,("initiate_wins_processing: %s is in released state and\
-we are not the wins owner !\n", nmb_namestr(&namerec->name)));
- break;
- }
- }
+ static time_t lasttime = 0;
- }
- }
+ if (!lasttime)
+ lasttime = t;
+ if (t - lasttime < 20)
+ return;
- if(wins_server_subnet->namelist_changed)
- wins_write_database(True);
+ lasttime = t;
- wins_server_subnet->namelist_changed = False;
+ if(!lp_we_are_a_wins_server())
+ return;
+
+ expire_names_on_subnet(wins_server_subnet, t);
+
+ if(wins_server_subnet->namelist_changed)
+ wins_write_database(True);
+
+ wins_server_subnet->namelist_changed = False;
}
/*******************************************************************
Write out the current WINS database.
******************************************************************/
-
void wins_write_database(BOOL background)
{
- struct name_record *namerec;
- pstring fname, fnamenew;
+ struct name_record *namerec;
+ pstring fname, fnamenew;
- XFILE *fp;
+ FILE *fp;
- if(!lp_we_are_a_wins_server())
- return;
-
- /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
- if (background) {
- CatchChild();
- if (sys_fork()) {
- return;
- }
- }
-
- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
- if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background) {
- _exit(0);
- }
- return;
- }
-
- DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
-
- x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
+ if(!lp_we_are_a_wins_server())
+ return;
+
+ /* we will do the writing in a child process to ensure that the parent
+ doesn't block while this is done */
+ if (background) {
+ CatchChild();
+ if (sys_fork()) {
+ return;
+ }
+ }
+
+ slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
+ all_string_sub(fname,"//", "/", 0);
+ slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
+
+ if((fp = sys_fopen(fnamenew,"w")) == NULL)
+ {
+ DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
+ if (background) {
+ _exit(0);
+ }
+ return;
+ }
+
+ DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
+
+ fprintf(fp,"VERSION %d %u\n", WINS_VERSION, wins_hash());
- for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
- int i;
- struct tm *tm;
-
- DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
-
- if( namerec->data.death_time != PERMANENT_TTL ) {
- char *ts, *nl;
-
- tm = LocalTime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr( ts, '\n' );
- if( NULL != nl )
- *nl = '\0';
- DEBUGADD(4,("TTL = %s ", ts ));
- } else {
- DEBUGADD(4,("TTL = PERMANENT "));
- }
-
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
- DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
-
- if( namerec->data.source == REGISTER_NAME ) {
- unstring name;
- pull_ascii_nstring(name, sizeof(name), namerec->name.name);
- x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
- (int)namerec->data.death_time);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
- x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
- }
- }
+ for( namerec
+ = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) )
+ {
+ int i;
+ struct tm *tm;
+
+ DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
+
+ if( namerec->data.death_time != PERMANENT_TTL )
+ {
+ char *ts, *nl;
+
+ tm = LocalTime(&namerec->data.death_time);
+ ts = asctime(tm);
+ nl = strrchr( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(4,("TTL = %s ", ts ));
+ }
+ else
+ DEBUGADD(4,("TTL = PERMANENT "));
+
+ for (i = 0; i < namerec->data.num_ips; i++)
+ DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
+
+ if( namerec->data.source == REGISTER_NAME )
+ {
+ fprintf(fp, "\"%s#%02x\" %d ",
+ namerec->name.name,namerec->name.name_type, /* Ignore scope. */
+ (int)namerec->data.death_time);
+
+ for (i = 0; i < namerec->data.num_ips; i++)
+ fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
+ fprintf( fp, "%2xR\n", namerec->data.nb_flags );
+ }
+ }
- x_fclose(fp);
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
- if (background) {
- _exit(0);
- }
-}
-
-/****************************************************************************
- Process a internal Samba message receiving a wins record.
-***************************************************************************/
-
-void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
-{
- WINS_RECORD *record;
- struct name_record *namerec = NULL;
- struct name_record *new_namerec = NULL;
- struct nmb_name question;
- BOOL overwrite=False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
- int i;
-
- if (buf==NULL)
- return;
-
- /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
- record=(WINS_RECORD *)buf;
-
- make_nmb_name(&question, record->name, record->type);
-
- namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
-
- /* record doesn't exist, add it */
- if (namerec == NULL) {
- DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
-
- new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
- if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
- update_wins_flag(new_namerec, record->wins_flags);
- new_namerec->data.id=record->id;
-
- wins_server_subnet->namelist_changed = True;
- }
- }
-
- /* check if we have a conflict */
- if (namerec != NULL) {
- /* both records are UNIQUE */
- if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
-
- /* the database record is a replica */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
- if (ip_equal(namerec->data.wins_ip, record->wins_ip))
- overwrite=True;
- } else
- overwrite=True;
- } else {
- /* we are the wins owner of the database record */
- /* the 2 records have the same IP address */
- if (ip_equal(namerec->data.ip[0], record->ip[0])) {
- if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
- get_global_id_and_update(&namerec->data.id, True);
- else
- overwrite=True;
-
- } else {
- /* the 2 records have different IP address */
- if (namerec->data.wins_flags&WINS_ACTIVE) {
- if (record->wins_flags&WINS_TOMBSTONED)
- get_global_id_and_update(&namerec->data.id, True);
- if (record->wins_flags&WINS_ACTIVE)
- /* send conflict challenge to the replica node */
- ;
- } else
- overwrite=True;
- }
-
- }
- }
-
- /* the replica is a standard group */
- if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
- /* if the database record is unique and active force a name release */
- if (namerec->data.wins_flags&WINS_UNIQUE)
- /* send a release name to the unique node */
- ;
- overwrite=True;
-
- }
-
- /* the replica is a special group */
- if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
- if (namerec->data.wins_flags&WINS_ACTIVE) {
- for (i=0; i<record->num_ips; i++)
- if(!find_ip_in_name_record(namerec, record->ip[i]))
- add_ip_to_name_record(namerec, record->ip[i]);
- } else {
- overwrite=True;
- }
- }
-
- /* the replica is a multihomed host */
-
- /* I'm giving up on multi homed. Too much complex to understand */
-
- if (record->wins_flags&WINS_MHOMED) {
- if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
- if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
- overwrite=True;
- }
- else {
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
- overwrite=True;
-
- if (ip_equal(namerec->data.wins_ip, our_fake_ip))
- if (namerec->data.wins_flags&WINS_UNIQUE)
- get_global_id_and_update(&namerec->data.id, True);
-
- }
-
- if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
- if (namerec->data.wins_flags&WINS_UNIQUE ||
- namerec->data.wins_flags&WINS_MHOMED)
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
- overwrite=True;
-
- }
-
- if (overwrite == False)
- DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
- else {
- DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
-
- /* remove the old record and add a new one */
- remove_name_from_namelist( wins_server_subnet, namerec );
- new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
- if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
- update_wins_flag(new_namerec, record->wins_flags);
- new_namerec->data.id=record->id;
-
- wins_server_subnet->namelist_changed = True;
- }
-
- wins_server_subnet->namelist_changed = True;
- }
-
- }
+ fclose(fp);
+ chmod(fnamenew,0644);
+ unlink(fname);
+ rename(fnamenew,fname);
+ if (background) {
+ _exit(0);
+ }
}
diff --git a/source/nmbd/nmbd_workgroupdb.c b/source/nmbd/nmbd_workgroupdb.c
index 8880cb58bb4..1dddc2cd18c 100644
--- a/source/nmbd/nmbd_workgroupdb.c
+++ b/source/nmbd/nmbd_workgroupdb.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
@@ -22,16 +23,20 @@
*/
#include "includes.h"
+#include "smb.h"
extern int ClientNMB;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+extern char **my_netbios_names;
extern uint16 samba_nb_type;
int workgroup_count = 0; /* unique index key: one for each workgroup */
/****************************************************************************
Add a workgroup into the list.
-**************************************************************************/
+ **************************************************************************/
static void add_workgroup(struct subnet_record *subrec, struct work_record *work)
{
@@ -42,165 +47,164 @@ static void add_workgroup(struct subnet_record *subrec, struct work_record *work
/****************************************************************************
Create an empty workgroup.
-**************************************************************************/
+ **************************************************************************/
static struct work_record *create_workgroup(const char *name, int ttl)
{
- struct work_record *work;
- struct subnet_record *subrec;
- nstring nname;
-
- int t = -1;
+ struct work_record *work;
+ struct subnet_record *subrec;
+ int t = -1;
- if((work = (struct work_record *)malloc(sizeof(*work))) == NULL) {
- DEBUG(0,("create_workgroup: malloc fail !\n"));
- return NULL;
- }
- memset((char *)work, '\0', sizeof(*work));
-
- errno = 0;
- push_ascii_nstring(nname, name);
- if (errno == E2BIG) {
- unstring tname;
- pull_ascii_nstring(tname, sizeof(tname), nname);
- unstrcpy(work->work_group,tname);
- DEBUG(0,("create_workgroup: workgroup name %s is too long. Truncating to %s\n",
- name, tname));
- } else {
- unstrcpy(work->work_group,name);
- }
- work->serverlist = NULL;
+ if((work = (struct work_record *)malloc(sizeof(*work))) == NULL)
+ {
+ DEBUG(0,("create_workgroup: malloc fail !\n"));
+ return NULL;
+ }
+ memset((char *)work, '\0', sizeof(*work));
+
+ StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
+ work->serverlist = NULL;
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->announce_interval = 0;
- work->needelection = False;
- work->needannounce = True;
- work->lastannounce_time = time(NULL);
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- work->dom_state = DOMAIN_NONE;
- work->log_state = LOGON_NONE;
+ work->RunningElection = False;
+ work->ElectionCount = 0;
+ work->announce_interval = 0;
+ work->needelection = False;
+ work->needannounce = True;
+ work->lastannounce_time = time(NULL);
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ work->dom_state = DOMAIN_NONE;
+ work->log_state = LOGON_NONE;
- work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
+ work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
- /* Make sure all token representations of workgroups are unique. */
+ /* Make sure all token representations of workgroups are unique. */
- for (subrec = FIRST_SUBNET; subrec && (t == -1); subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- struct work_record *w;
- for (w = subrec->workgrouplist; w && t == -1; w = w->next) {
- if (strequal(w->work_group, work->work_group))
- t = w->token;
- }
- }
+ for (subrec = FIRST_SUBNET; subrec && (t == -1);
+ subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ struct work_record *w;
+ for (w = subrec->workgrouplist; w && t == -1; w = w->next)
+ {
+ if (strequal(w->work_group, work->work_group))
+ t = w->token;
+ }
+ }
- if (t == -1)
- work->token = ++workgroup_count;
- else
- work->token = t;
+ if (t == -1)
+ work->token = ++workgroup_count;
+ else
+ work->token = t;
- /* No known local master browser as yet. */
- *work->local_master_browser_name = '\0';
-
- /* No known domain master browser as yet. */
- *work->dmb_name.name = '\0';
- zero_ip(&work->dmb_addr);
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master())
- work->ElectionCriterion |= 0x80;
+ /* No known local master browser as yet. */
+ *work->local_master_browser_name = '\0';
+
+ /* No known domain master browser as yet. */
+ *work->dmb_name.name = '\0';
+ zero_ip(&work->dmb_addr);
+
+ /* WfWg uses 01040b01 */
+ /* Win95 uses 01041501 */
+ /* NTAS uses ???????? */
+ work->ElectionCriterion = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8);
+ work->ElectionCriterion |= (lp_os_level() << 24);
+ if (lp_domain_master())
+ work->ElectionCriterion |= 0x80;
- return work;
+ return work;
}
/*******************************************************************
Remove a workgroup.
-******************************************************************/
+ ******************************************************************/
static struct work_record *remove_workgroup_from_subnet(struct subnet_record *subrec,
struct work_record *work)
{
- struct work_record *ret_work = NULL;
+ struct work_record *ret_work = NULL;
- DEBUG(3,("remove_workgroup: Removing workgroup %s\n", work->work_group));
+ DEBUG(3,("remove_workgroup: Removing workgroup %s\n", work->work_group));
- ret_work = work->next;
+ ret_work = work->next;
- remove_all_servers(work);
+ remove_all_servers(work);
- if (!work->serverlist) {
- if (work->prev)
- work->prev->next = work->next;
- if (work->next)
- work->next->prev = work->prev;
+ if (!work->serverlist)
+ {
+ if (work->prev)
+ work->prev->next = work->next;
+ if (work->next)
+ work->next->prev = work->prev;
- if (subrec->workgrouplist == work)
- subrec->workgrouplist = work->next;
+ if (subrec->workgrouplist == work)
+ subrec->workgrouplist = work->next;
- ZERO_STRUCTP(work);
- SAFE_FREE(work);
- }
+ ZERO_STRUCTP(work);
+ free((char *)work);
+ }
- subrec->work_changed = True;
+ subrec->work_changed = True;
- return ret_work;
+ return ret_work;
}
+
/****************************************************************************
Find a workgroup in the workgroup list of a subnet.
-**************************************************************************/
+ **************************************************************************/
struct work_record *find_workgroup_on_subnet(struct subnet_record *subrec,
const char *name)
{
- struct work_record *ret;
+ struct work_record *ret;
- DEBUG(4, ("find_workgroup_on_subnet: workgroup search for %s on subnet %s: ",
- name, subrec->subnet_name));
+ DEBUG(4, ("find_workgroup_on_subnet: workgroup search for %s on subnet %s: ",
+ name, subrec->subnet_name));
- for (ret = subrec->workgrouplist; ret; ret = ret->next) {
- if (strequal(ret->work_group,name)) {
- DEBUGADD(4, ("found.\n"));
- return(ret);
- }
- }
- DEBUGADD(4, ("not found.\n"));
- return NULL;
+ for (ret = subrec->workgrouplist; ret; ret = ret->next)
+ {
+ if (!strcmp(ret->work_group,name))
+ {
+ DEBUGADD(4, ("found.\n"));
+ return(ret);
+ }
+ }
+ DEBUGADD(4, ("not found.\n"));
+ return NULL;
}
/****************************************************************************
Create a workgroup in the workgroup list of the subnet.
-**************************************************************************/
+ **************************************************************************/
struct work_record *create_workgroup_on_subnet(struct subnet_record *subrec,
const char *name, int ttl)
{
- struct work_record *work = NULL;
+ struct work_record *work = NULL;
- DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n",
- name, subrec->subnet_name));
+ DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n",
+ name, subrec->subnet_name));
- if ((work = create_workgroup(name, ttl))) {
- add_workgroup(subrec, work);
- subrec->work_changed = True;
- return(work);
- }
+ if ((work = create_workgroup(name, ttl)))
+ {
+ add_workgroup(subrec, work);
+
+ subrec->work_changed = True;
- return NULL;
+ return(work);
+ }
+
+ return NULL;
}
/****************************************************************************
Update a workgroup ttl.
-**************************************************************************/
+ **************************************************************************/
void update_workgroup_ttl(struct work_record *work, int ttl)
{
- if(work->death_time != PERMANENT_TTL)
- work->death_time = time(NULL)+(ttl*3);
- work->subnet->work_changed = True;
+ if(work->death_time != PERMANENT_TTL)
+ work->death_time = time(NULL)+(ttl*3);
+ work->subnet->work_changed = True;
}
/****************************************************************************
@@ -211,8 +215,8 @@ void update_workgroup_ttl(struct work_record *work, int ttl)
static void fail_register(struct subnet_record *subrec, struct response_record *rrec,
struct nmb_name *nmbname)
{
- DEBUG(0,("fail_register: Failed to register name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
+ DEBUG(0,("fail_register: Failed to register name %s on subnet %s.\n",
+ nmb_namestr(nmbname), subrec->subnet_name));
}
/****************************************************************************
@@ -221,38 +225,50 @@ static void fail_register(struct subnet_record *subrec, struct response_record *
void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_record *work)
{
- int i;
+ int i;
- if(!strequal(lp_workgroup(), work->work_group))
- return;
+ if(!strequal(global_myworkgroup, work->work_group))
+ return;
- /* If this is a broadcast subnet then start elections on it if we are so configured. */
+ /* If this is a broadcast subnet then start elections on it
+ if we are so configured. */
- if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
- (subrec != wins_server_subnet) && lp_preferred_master() && lp_local_master()) {
- DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
+ if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
+ (subrec != wins_server_subnet) && lp_preferred_master() &&
+ lp_local_master())
+ {
+ DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
+ work->needelection = True;
+ work->ElectionCriterion |= (1<<3);
+ }
- /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */
-
- register_name(subrec,lp_workgroup(),0x0,samba_nb_type|NB_GROUP, NULL, fail_register,NULL);
- register_name(subrec,lp_workgroup(),0x1e,samba_nb_type|NB_GROUP, NULL, fail_register,NULL);
+ /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */
- for( i = 0; my_netbios_names(i); i++) {
- const char *name = my_netbios_names(i);
- int stype = lp_default_server_announce() | (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0 );
+ register_name(subrec,global_myworkgroup,0x0,samba_nb_type|NB_GROUP,
+ NULL,
+ fail_register,NULL);
+
+ register_name(subrec,global_myworkgroup,0x1e,samba_nb_type|NB_GROUP,
+ NULL,
+ fail_register,NULL);
+
+ for( i = 0; my_netbios_names[i]; i++)
+ {
+ char *name = my_netbios_names[i];
+ int stype = lp_default_server_announce() | (lp_local_master() ?
+ SV_TYPE_POTENTIAL_BROWSER : 0 );
- if(!strequal(global_myname(), name))
- stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
+ if(!strequal(global_myname, name))
+ stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
+ SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
- create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY, PERMANENT_TTL,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
+ create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY,
+ PERMANENT_TTL,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
on subnet %s\n", name, subrec->subnet_name));
- }
+ }
}
/****************************************************************************
@@ -261,34 +277,43 @@ on subnet %s\n", name, subrec->subnet_name));
void dump_workgroups(BOOL force_write)
{
- struct subnet_record *subrec;
- int debuglevel = force_write ? 0 : 4;
+ struct subnet_record *subrec;
+ int debuglevel = force_write ? 0 : 4;
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- if (subrec->workgrouplist) {
- struct work_record *work;
-
- if( DEBUGLVL( debuglevel ) ) {
- dbgtext( "dump_workgroups()\n " );
- dbgtext( "dump workgroup on subnet %15s: ", subrec->subnet_name );
- dbgtext( "netmask=%15s:\n", inet_ntoa(subrec->mask_ip) );
- }
-
- for (work = subrec->workgrouplist; work; work = work->next) {
- DEBUGADD( debuglevel, ( "\t%s(%d) current master browser = %s\n", work->work_group,
- work->token, *work->local_master_browser_name ? work->local_master_browser_name : "UNKNOWN" ) );
- if (work->serverlist) {
- struct server_record *servrec;
- for (servrec = work->serverlist; servrec; servrec = servrec->next) {
- DEBUGADD( debuglevel, ( "\t\t%s %8x (%s)\n",
- servrec->serv.name,
- servrec->serv.type,
- servrec->serv.comment ) );
- }
- }
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ if (subrec->workgrouplist)
+ {
+ struct work_record *work;
+
+ if( DEBUGLVL( debuglevel ) )
+ {
+ dbgtext( "dump_workgroups()\n " );
+ dbgtext( "dump workgroup on subnet %15s: ", subrec->subnet_name );
+ dbgtext( "netmask=%15s:\n", inet_ntoa(subrec->mask_ip) );
+ }
+
+ for (work = subrec->workgrouplist; work; work = work->next)
+ {
+ DEBUGADD( debuglevel, ( "\t%s(%d) current master browser = %s\n",
+ work->work_group,
+ work->token,
+ *work->local_master_browser_name
+ ? work->local_master_browser_name : "UNKNOWN" ) );
+ if (work->serverlist)
+ {
+ struct server_record *servrec;
+ for (servrec = work->serverlist; servrec; servrec = servrec->next)
+ {
+ DEBUGADD( debuglevel, ( "\t\t%s %8x (%s)\n",
+ servrec->serv.name,
+ servrec->serv.type,
+ servrec->serv.comment ) );
+ }
+ }
+ }
+ }
+ }
}
/****************************************************************************
@@ -298,22 +323,25 @@ void dump_workgroups(BOOL force_write)
void expire_workgroups_and_servers(time_t t)
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
- struct work_record *work;
- struct work_record *nextwork;
-
- for (work = subrec->workgrouplist; work; work = nextwork) {
- nextwork = work->next;
- expire_servers(work, t);
-
- if ((work->serverlist == NULL) && (work->death_time != PERMANENT_TTL) &&
- ((t == -1) || (work->death_time < t))) {
- DEBUG(3,("expire_workgroups_and_servers: Removing timed out workgroup %s\n",
- work->work_group));
- remove_workgroup_from_subnet(subrec, work);
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ {
+ struct work_record *work;
+ struct work_record *nextwork;
+
+ for (work = subrec->workgrouplist; work; work = nextwork)
+ {
+ nextwork = work->next;
+ expire_servers(work, t);
+
+ if ((work->serverlist == NULL) && (work->death_time != PERMANENT_TTL) &&
+ ((t == -1) || (work->death_time < t)))
+ {
+ DEBUG(3,("expire_workgroups_and_servers: Removing timed out workgroup %s\n",
+ work->work_group));
+ remove_workgroup_from_subnet(subrec, work);
+ }
+ }
+ }
}
diff --git a/source/nsswitch/README b/source/nsswitch/README
new file mode 100755
index 00000000000..9f0c581df60
--- /dev/null
+++ b/source/nsswitch/README
@@ -0,0 +1,13 @@
+This extension provides a "wins" module for NSS on glibc2/Linux. This
+allows you to use a WINS entry in /etc/nsswitch.conf for hostname
+resolution, allowing you to resolve netbios names via start unix
+gethostbyname() calls. The end result is that you can use netbios
+names as host names in unix apps.
+
+1) run configure
+2) run "make nsswitch"
+3) cp nsswitch/libnss_wins.so /lib/libnss_wins.so.2
+4) add a wins entry to the hosts line in /etc/nsswitch.conf
+5) use it
+
+tridge@linuxcare.com
diff --git a/source/nsswitch/winbind_nss_irix.h b/source/nsswitch/hp_nss_common.h
index 7878abb981a..5bd5374182e 100644..100755
--- a/source/nsswitch/winbind_nss_irix.h
+++ b/source/nsswitch/hp_nss_common.h
@@ -1,48 +1,51 @@
-/*
+#ifndef _HP_NSS_COMMON_H
+#define _HP_NSS_COMMON_H
+
+/*
Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
+
+ Donated by HP to enable Winbindd to build on HPUX 11.x.
+ Copyright (C) Jeremy Allison 2002.
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
-
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _WINBIND_NSS_IRIX_H
-#define _WINBIND_NSS_IRIX_H
-
-/* following required to prevent warnings of double definition
- * of datum from ns_api.h
+ Boston, MA 02111-1307, USA.
*/
-#ifdef DATUM
-#define _DATUM_DEFINED
+
+#ifdef HAVE_SYNCH_H
+#include <synch.h>
#endif
-
-#include <ns_api.h>
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=NS_SUCCESS,
- NSS_STATUS_NOTFOUND=NS_NOTFOUND,
- NSS_STATUS_UNAVAIL=NS_UNAVAIL,
- NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
-} NSS_STATUS;
-
-#define NSD_MEM_STATIC 0
-#define NSD_MEM_VOLATILE 1
-#define NSD_MEM_DYNAMIC 2
-
-#endif /* _WINBIND_NSS_IRIX_H */
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+typedef enum {
+ NSS_SUCCESS,
+ NSS_NOTFOUND,
+ NSS_UNAVAIL,
+ NSS_TRYAGAIN
+} nss_status_t;
+
+struct nss_backend;
+
+typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
+
+struct nss_backend {
+ nss_backend_op_t *ops;
+ int n_ops;
+};
+typedef struct nss_backend nss_backend_t;
+typedef int nss_dbop_t;
+
+#endif /* _HP_NSS_COMMON_H */
diff --git a/source/nsswitch/winbind_nss_hpux.h b/source/nsswitch/hp_nss_dbdefs.h
index d2a5057bf51..bd24772e339 100644..100755
--- a/source/nsswitch/winbind_nss_hpux.h
+++ b/source/nsswitch/hp_nss_dbdefs.h
@@ -1,3 +1,6 @@
+#ifndef _HP_NSS_DBDEFS_H
+#define _HP_NSS_DBDEFS_H
+
/*
Unix SMB/CIFS implementation.
@@ -20,43 +23,6 @@
Boston, MA 02111-1307, USA.
*/
-#ifndef _WINBIND_NSS_HPUX_H
-#define _WINBIND_NSS_HPUX_H
-
-#include <nsswitch.h>
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#ifdef HAVE_SYNCH_H
-#include <synch.h>
-#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-typedef enum {
- NSS_SUCCESS,
- NSS_NOTFOUND,
- NSS_UNAVAIL,
- NSS_TRYAGAIN
-} nss_status_t;
-
-typedef nss_status_t NSS_STATUS;
-
-struct nss_backend;
-
-typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
-
-struct nss_backend {
- nss_backend_op_t *ops;
- int n_ops;
-};
-typedef struct nss_backend nss_backend_t;
-typedef int nss_dbop_t;
-
#include <errno.h>
#include <netdb.h>
#include <limits.h>
@@ -136,4 +102,4 @@ typedef struct nss_XbyY_args {
nss_status_t status;
} nss_XbyY_args_t;
-#endif /* _WINBIND_NSS_HPUX_H */
+#endif /* _NSS_DBDEFS_H */
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index 123f6703665..4d696d7de73 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -11,6 +11,11 @@
#include "pam_winbind.h"
+/* prototypes from common.c */
+void init_request(struct winbindd_request *req,int rq_type);
+int write_sock(void *buffer, int count);
+int read_reply(struct winbindd_response *response);
+
/* data tokens */
#define MAX_PASSWD_TRIES 3
@@ -40,9 +45,9 @@ static int _pam_parse(int argc, const char **argv)
else if (!strcasecmp(*argv, "use_authtok"))
ctrl |= WINBIND_USE_AUTHTOK_ARG;
else if (!strcasecmp(*argv, "use_first_pass"))
- ctrl |= WINBIND_USE_FIRST_PASS_ARG;
- else if (!strcasecmp(*argv, "try_first_pass"))
ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
+ else if (!strcasecmp(*argv, "try_first_pass"))
+ ctrl |= WINBIND_USE_FIRST_PASS_ARG;
else if (!strcasecmp(*argv, "unknown_ok"))
ctrl |= WINBIND_UNKNOWN_OK_ARG;
else {
@@ -74,7 +79,7 @@ static int converse(pam_handle_t *pamh, int nargs,
}
-static int _make_remark(pam_handle_t * pamh, int type, const char *text)
+int _make_remark(pam_handle_t * pamh, int type, const char *text)
{
int retval = PAM_SUCCESS;
@@ -94,35 +99,28 @@ static int _make_remark(pam_handle_t * pamh, int type, const char *text)
return retval;
}
-static int pam_winbind_request(enum winbindd_cmd req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
+static int winbind_request(enum winbindd_cmd req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
{
-
/* Fill in request and send down pipe */
init_request(request, req_type);
if (write_sock(request, sizeof(*request)) == -1) {
_pam_log(LOG_ERR, "write to socket failed!");
- close_sock();
return PAM_SERVICE_ERR;
}
/* Wait for reply */
if (read_reply(response) == -1) {
_pam_log(LOG_ERR, "read from socket failed!");
- close_sock();
return PAM_SERVICE_ERR;
}
- /* We are done with the socket - close it and avoid mischeif */
- close_sock();
-
/* Copy reply data from socket */
if (response->result != WINBINDD_OK) {
if (response->data.auth.pam_error != PAM_SUCCESS) {
- _pam_log(LOG_ERR, "request failed: %s, PAM error was %d, NT error was %s",
- response->data.auth.error_string,
+ _pam_log(LOG_ERR, "request failed, PAM error was %d, NT error was %s",
response->data.auth.pam_error,
response->data.auth.nt_status_string);
return response->data.auth.pam_error;
@@ -135,33 +133,28 @@ static int pam_winbind_request(enum winbindd_cmd req_type,
return PAM_SUCCESS;
}
-static int pam_winbind_request_log(enum winbindd_cmd req_type,
- struct winbindd_request *request,
- struct winbindd_response *response,
- int ctrl,
- const char *user)
+/* talk to winbindd */
+static int winbind_auth_request(const char *user, const char *pass, int ctrl)
{
+ struct winbindd_request request;
+ struct winbindd_response response;
int retval;
- retval = pam_winbind_request(req_type, request, response);
+ ZERO_STRUCT(request);
+
+ strncpy(request.data.auth.user, user,
+ sizeof(request.data.auth.user)-1);
+
+ strncpy(request.data.auth.pass, pass,
+ sizeof(request.data.auth.pass)-1);
+
+ retval = winbind_request(WINBINDD_PAM_AUTH, &request, &response);
switch (retval) {
case PAM_AUTH_ERR:
/* incorrect password */
_pam_log(LOG_WARNING, "user `%s' denied access (incorrect password)", user);
return retval;
- case PAM_ACCT_EXPIRED:
- /* account expired */
- _pam_log(LOG_WARNING, "user `%s' account expired", user);
- return retval;
- case PAM_AUTHTOK_EXPIRED:
- /* password expired */
- _pam_log(LOG_WARNING, "user `%s' password expired", user);
- return retval;
- case PAM_NEW_AUTHTOK_REQD:
- /* password expired */
- _pam_log(LOG_WARNING, "user `%s' new password required", user);
- return retval;
case PAM_USER_UNKNOWN:
/* the user does not exist */
if (ctrl & WINBIND_DEBUG_ARG)
@@ -172,16 +165,8 @@ static int pam_winbind_request_log(enum winbindd_cmd req_type,
}
return retval;
case PAM_SUCCESS:
- if (req_type == WINBINDD_PAM_AUTH) {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' granted acces", user);
- } else if (req_type == WINBINDD_PAM_CHAUTHTOK) {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' password changed", user);
- } else {
- /* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' OK", user);
- }
+ /* Otherwise, the authentication looked good */
+ _pam_log(LOG_NOTICE, "user '%s' granted acces", user);
return retval;
default:
/* we don't know anything about this return value */
@@ -189,29 +174,12 @@ static int pam_winbind_request_log(enum winbindd_cmd req_type,
retval, user);
return retval;
}
-}
-
-/* talk to winbindd */
-static int winbind_auth_request(const char *user, const char *pass, int ctrl)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
-
- strncpy(request.data.auth.user, user,
- sizeof(request.data.auth.user)-1);
-
- strncpy(request.data.auth.pass, pass,
- sizeof(request.data.auth.pass)-1);
-
-
- return pam_winbind_request_log(WINBINDD_PAM_AUTH, &request, &response, ctrl, user);
+ /* should not be reached */
}
/* talk to winbindd */
static int winbind_chauthtok_request(const char *user, const char *oldpass,
- const char *newpass, int ctrl)
+ const char *newpass)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -237,7 +205,7 @@ static int winbind_chauthtok_request(const char *user, const char *oldpass,
request.data.chauthtok.newpass[0] = '\0';
}
- return pam_winbind_request_log(WINBINDD_PAM_CHAUTHTOK, &request, &response, ctrl, user);
+ return winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response);
}
/*
@@ -265,12 +233,12 @@ static char *_pam_delete(register char *xx)
* obtain a password from the user
*/
-static int _winbind_read_password(pam_handle_t * pamh
- ,unsigned int ctrl
- ,const char *comment
- ,const char *prompt1
- ,const char *prompt2
- ,const char **pass)
+int _winbind_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char **pass)
{
int authtok_flag;
int retval;
@@ -437,7 +405,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
&password);
if (retval != PAM_SUCCESS) {
- _pam_log(LOG_ERR, "Could not retrieve user's password");
+ _pam_log(LOG_ERR, "Could not retrive user's password");
return PAM_AUTHTOK_ERR;
}
@@ -514,29 +482,27 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
/* should not be reached */
return PAM_IGNORE;
}
-PAM_EXTERN
-int pam_sm_open_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
+
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
{
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_open_session handler");
- return PAM_SUCCESS;
+ /* parse arguments */
+ int ctrl = _pam_parse(argc, argv);
+ if (ctrl & WINBIND_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_open_session handler");
+ return PAM_SUCCESS;
}
-PAM_EXTERN
-int pam_sm_close_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
+
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
{
- /* parse arguments */
- int ctrl = _pam_parse(argc, argv);
- if (ctrl & WINBIND_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_close_session handler");
- return PAM_SUCCESS;
+ /* parse arguments */
+ int ctrl = _pam_parse(argc, argv);
+ if (ctrl & WINBIND_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_close_session handler");
+ return PAM_SUCCESS;
}
-
-
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
int argc, const char **argv)
{
@@ -609,7 +575,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
retval = winbind_auth_request(user, pass_old, ctrl);
if (retval != PAM_ACCT_EXPIRED
- && retval != PAM_AUTHTOK_EXPIRED
&& retval != PAM_NEW_AUTHTOK_REQD
&& retval != PAM_SUCCESS) {
pass_old = NULL;
@@ -684,7 +649,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
* rebuild the password database file.
*/
- retval = winbind_chauthtok_request(user, pass_old, pass_new, ctrl);
+ retval = winbind_chauthtok_request(user, pass_old, pass_new);
_pam_overwrite(pass_new);
_pam_overwrite(pass_old);
pass_old = pass_new = NULL;
@@ -704,8 +669,8 @@ struct pam_module _pam_winbind_modstruct = {
pam_sm_authenticate,
pam_sm_setcred,
pam_sm_acct_mgmt,
- pam_sm_open_session,
- pam_sm_close_session,
+ NULL,
+ NULL,
pam_sm_chauthtok
};
diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
index 0afcceb6aa2..9897249e164 100644
--- a/source/nsswitch/pam_winbind.h
+++ b/source/nsswitch/pam_winbind.h
@@ -25,18 +25,15 @@
#define PAM_SM_ACCOUNT
#define PAM_SM_PASSWORD
-#if defined(SUNOS5) || defined(SUNOS4) || defined(HPUX) || defined(FREEBSD)
+#if defined(SUNOS5) || defined(SUNOS4) || defined(HPUX)
/* Solaris always uses dynamic pam modules */
#define PAM_EXTERN extern
#include <security/pam_appl.h>
-#ifndef PAM_AUTHTOK_RECOVER_ERR
#define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
#endif
-#endif
-
#ifdef HAVE_SECURITY_PAM_MODULES_H
#include <security/pam_modules.h>
#endif
@@ -93,4 +90,5 @@ do { \
#define on(x, y) (x & y)
#define off(x, y) (!(x & y))
-#include "winbind_client.h"
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
diff --git a/source/nsswitch/sys_nss.h b/source/nsswitch/sys_nss.h
new file mode 100755
index 00000000000..b4dfc1fa336
--- /dev/null
+++ b/source/nsswitch/sys_nss.h
@@ -0,0 +1,104 @@
+#ifndef _NSSWITCH_SYS_NSS_H
+#define _NSSWITCH_SYS_NSS_H
+/*
+ Unix SMB/CIFS implementation.
+
+ a common place to work out how to define NSS_STATUS on various
+ platforms
+
+ Copyright (C) Tim Potter 2000
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifdef HAVE_NSS_COMMON_H
+
+/* Sun Solaris */
+
+#include <nss_common.h>
+#include <nss_dbdefs.h>
+#include <nsswitch.h>
+
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+
+#elif HAVE_NSS_H
+
+/* GNU */
+
+#include <nss.h>
+
+typedef enum nss_status NSS_STATUS;
+
+#elif HAVE_NS_API_H
+
+/* SGI IRIX */
+
+/* following required to prevent warnings of double definition
+ * of datum from ns_api.h
+*/
+#ifdef DATUM
+#define _DATUM_DEFINED
+#endif
+
+#include <ns_api.h>
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=NS_SUCCESS,
+ NSS_STATUS_NOTFOUND=NS_NOTFOUND,
+ NSS_STATUS_UNAVAIL=NS_UNAVAIL,
+ NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
+} NSS_STATUS;
+
+#define NSD_MEM_STATIC 0
+#define NSD_MEM_VOLATILE 1
+#define NSD_MEM_DYNAMIC 2
+
+#elif defined(HPUX) && defined(HAVE_NSSWITCH_H)
+/* HP-UX 11 */
+
+#include "nsswitch/hp_nss_common.h"
+#include "nsswitch/hp_nss_dbdefs.h"
+#include <nsswitch.h>
+
+#ifndef _HAVE_TYPEDEF_NSS_STATUS
+#define _HAVE_TYPEDEF_NSS_STATUS
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+#endif /* HPUX */
+
+#else /* Nothing's defined. Neither gnu nor sun nor hp */
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=0,
+ NSS_STATUS_NOTFOUND=1,
+ NSS_STATUS_UNAVAIL=2,
+ NSS_STATUS_TRYAGAIN=3
+} NSS_STATUS;
+
+#endif
+
+#endif /* _NSSWITCH_SYS_NSS_H */
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 5d431392450..aeafb4faa93 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -23,17 +23,26 @@
*/
#include "includes.h"
-#include "nsswitch/winbind_nss.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-extern DOM_SID global_sid_NULL; /* NULL sid */
+#include "nsswitch/sys_nss.h"
NSS_STATUS winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
+static BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
+{
+ char *p = strchr(domuser,*lp_winbind_separator());
+
+ if (!p)
+ return False;
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper(domain);
+ return True;
+}
+
/* Call winbindd to convert a name to a sid */
BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
@@ -51,13 +60,17 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- fstrcpy(request.data.name.dom_name, dom_name);
- fstrcpy(request.data.name.name, name);
+ if (dom_name == NULL) {
+ if (!parse_domain_user(name, request.data.name.dom_name, request.data.name.name))
+ return False;
+ } else {
+ fstrcpy(request.data.name.dom_name, dom_name);
+ fstrcpy(request.data.name.name, name);
+ }
if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request,
&response)) == NSS_STATUS_SUCCESS) {
- if (!string_to_sid(sid, response.data.sid.sid))
- return False;
+ string_to_sid(sid, response.data.sid.sid);
*name_type = (enum SID_NAME_USE)response.data.sid.type;
}
@@ -66,7 +79,7 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
/* Call winbindd to convert sid to name */
-BOOL winbind_lookup_sid(const DOM_SID *sid,
+BOOL winbind_lookup_sid(DOM_SID *sid,
fstring dom_name, fstring name,
enum SID_NAME_USE *name_type)
{
@@ -103,7 +116,7 @@ BOOL winbind_lookup_sid(const DOM_SID *sid,
/* Call winbindd to convert SID to uid */
-BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
+BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -159,8 +172,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
/* Copy out result */
if (result == NSS_STATUS_SUCCESS) {
- if (!string_to_sid(sid, response.data.sid.sid))
- return False;
+ string_to_sid(sid, response.data.sid.sid);
} else {
sid_copy(sid, &global_sid_NULL);
}
@@ -170,7 +182,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
/* Call winbindd to convert SID to gid */
-BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
+BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -226,8 +238,7 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
/* Copy out result */
if (result == NSS_STATUS_SUCCESS) {
- if (!string_to_sid(sid, response.data.sid.sid))
- return False;
+ string_to_sid(sid, response.data.sid.sid);
} else {
sid_copy(sid, &global_sid_NULL);
}
@@ -235,30 +246,6 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
return (result == NSS_STATUS_SUCCESS);
}
-BOOL winbind_allocate_rid(uint32 *rid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- int result;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response);
-
- if (result != NSS_STATUS_SUCCESS)
- return False;
-
- /* Copy out result */
- *rid = response.data.rid;
-
- return True;
-}
-
/* Fetch the list of groups a user is a member of from winbindd. This is
used by winbind_getgroups. */
@@ -305,6 +292,11 @@ int winbind_initgroups(char *user, gid_t gid)
return initgroups(user, gid);
}
+ /* We need setgroups for this call to work. */
+#if !defined(HAVE_SETGROUPS)
+ return ENOSYS;
+#endif
+
result = wb_getgroups(user, &groups);
DEBUG(10,("winbind_getgroups: %s: result = %s\n", user,
@@ -339,7 +331,6 @@ int winbind_initgroups(char *user, gid_t gid)
}
/* Set the groups */
-
if (sys_setgroups(ngroups, groups) == -1) {
errno = EPERM;
result = -1;
@@ -367,8 +358,11 @@ int winbind_initgroups(char *user, gid_t gid)
time consuming. If size is zero, list is not modified and the total
number of groups for the user is returned. */
-int winbind_getgroups(const char *user, gid_t **list)
+int winbind_getgroups(const char *user, int size, gid_t *list)
{
+ gid_t *groups = NULL;
+ int result, i;
+
/*
* Don't do the lookup if the name has no separator _and_ we are not in
* 'winbind use default domain' mode.
@@ -379,319 +373,102 @@ int winbind_getgroups(const char *user, gid_t **list)
/* Fetch list of groups */
- return wb_getgroups(user, list);
-}
-
-/**********************************************************************
- simple wrapper function to see if winbindd is alive
-**********************************************************************/
-
-BOOL winbind_ping( void )
-{
- NSS_STATUS result;
+ result = wb_getgroups(user, &groups);
- result = winbindd_request(WINBINDD_PING, NULL, NULL);
+ if (size == 0)
+ goto done;
- return result == NSS_STATUS_SUCCESS;
-}
+ if (result > size) {
+ result = -1;
+ errno = EINVAL; /* This is what getgroups() does */
+ goto done;
+ }
-/**********************************************************************
- Ask winbindd to create a local user
-**********************************************************************/
+ /* Copy list of groups across */
-BOOL winbind_create_user( const char *name, uint32 *rid )
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
- return False;
-
- if ( !name )
- return False;
-
- DEBUG(10,("winbind_create_user: %s\n", name));
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* see if the caller wants a new RID returned */
-
- if ( rid )
- request.flags = WBFLAG_ALLOCATE_RID;
+ for (i = 0; i < result; i++) {
+ list[i] = groups[i];
+ }
- fstrcpy( request.data.acct_mgt.username, name );
- fstrcpy( request.data.acct_mgt.groupname, "" );
-
- result = winbindd_request( WINBINDD_CREATE_USER, &request, &response);
-
- if ( rid )
- *rid = response.data.rid;
-
- return result == NSS_STATUS_SUCCESS;
+ done:
+ SAFE_FREE(groups);
+ return result;
}
-/**********************************************************************
- Ask winbindd to create a local group
-**********************************************************************/
+/* Utility function. Convert a uid_t to a name if possible. */
-BOOL winbind_create_group( const char *name, uint32 *rid )
+BOOL winbind_uidtoname(fstring name, uid_t uid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
- return False;
-
- if ( !name )
- return False;
-
- DEBUG(10,("winbind_create_group: %s\n", name));
+ DOM_SID sid;
+ fstring dom_name;
+ fstring user_name;
+ enum SID_NAME_USE name_type;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* see if the caller wants a new RID returned */
-
- if ( rid )
- request.flags = WBFLAG_ALLOCATE_RID;
-
- fstrcpy( request.data.acct_mgt.groupname, name );
-
-
- result = winbindd_request( WINBINDD_CREATE_GROUP, &request, &response);
-
- if ( rid )
- *rid = response.data.rid;
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/**********************************************************************
- Ask winbindd to add a user to a local group
-**********************************************************************/
-
-BOOL winbind_add_user_to_group( const char *user, const char *group )
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
+ if (!winbind_uid_to_sid(&sid, uid))
return False;
-
- if ( !user || !group )
+ if (!winbind_lookup_sid(&sid, dom_name, user_name, &name_type))
return False;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- DEBUG(10,("winbind_add_user_to_group: user(%s), group(%s) \n",
- user, group));
-
- fstrcpy( request.data.acct_mgt.username, user );
- fstrcpy( request.data.acct_mgt.groupname, group );
-
- result = winbindd_request( WINBINDD_ADD_USER_TO_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/**********************************************************************
- Ask winbindd to remove a user to a local group
-**********************************************************************/
-BOOL winbind_remove_user_from_group( const char *user, const char *group )
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
- return False;
-
- if ( !user || !group )
+ if (name_type != SID_NAME_USER)
return False;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- DEBUG(10,("winbind_remove_user_from_group: user(%s), group(%s) \n",
- user, group));
-
- ZERO_STRUCT(response);
-
- fstrcpy( request.data.acct_mgt.username, user );
- fstrcpy( request.data.acct_mgt.groupname, group );
-
- result = winbindd_request( WINBINDD_REMOVE_USER_FROM_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-/**********************************************************************
- Ask winbindd to set the primary group for a user local user
-**********************************************************************/
+ slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
+ lp_winbind_separator(), user_name);
-BOOL winbind_set_user_primary_group( const char *user, const char *group )
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
- return False;
-
- if ( !user || !group )
- return False;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- DEBUG(10,("winbind_set_user_primary_group: user(%s), group(%s) \n",
- user, group));
-
- fstrcpy( request.data.acct_mgt.username, user );
- fstrcpy( request.data.acct_mgt.groupname, group );
-
- result = winbindd_request( WINBINDD_SET_USER_PRIMARY_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
+ return True;
}
+/* Utility function. Convert a gid_t to a name if possible. */
-/**********************************************************************
- Ask winbindd to remove a user from its lists of accounts
-**********************************************************************/
-
-BOOL winbind_delete_user( const char *user )
+BOOL winbind_gidtoname(fstring name, gid_t gid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
- return False;
-
- if ( !user )
- return False;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- DEBUG(10,("winbind_delete_user: user (%s)\n", user));
-
- fstrcpy( request.data.acct_mgt.username, user );
-
- result = winbindd_request( WINBINDD_DELETE_USER, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/**********************************************************************
- Ask winbindd to remove a group from its lists of accounts
-**********************************************************************/
+ DOM_SID sid;
+ fstring dom_name;
+ fstring group_name;
+ enum SID_NAME_USE name_type;
-BOOL winbind_delete_group( const char *group )
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if ( !lp_winbind_enable_local_accounts() )
+ if (!winbind_gid_to_sid(&sid, gid))
return False;
-
- if ( !group )
+ if (!winbind_lookup_sid(&sid, dom_name, group_name, &name_type))
return False;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- DEBUG(10,("winbind_delete_group: group (%s)\n", group));
-
- fstrcpy( request.data.acct_mgt.groupname, group );
-
- result = winbindd_request( WINBINDD_DELETE_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/***********************************************************************/
-#if 0 /* not needed currently since winbindd_acct was added -- jerry */
-/* Call winbindd to convert SID to uid. Do not allocate */
-
-BOOL winbind_sid_to_uid_query(uid_t *puid, const DOM_SID *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- int result;
- fstring sid_str;
-
- if (!puid)
+ if (name_type != SID_NAME_DOM_GRP)
return False;
- /* Initialise request */
+ slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
+ lp_winbind_separator(), group_name);
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- sid_to_string(sid_str, sid);
- fstrcpy(request.data.sid, sid_str);
-
- request.flags = WBFLAG_QUERY_ONLY;
-
- /* Make request */
-
- result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
-
- /* Copy out result */
-
- if (result == NSS_STATUS_SUCCESS) {
- *puid = response.data.uid;
- }
-
- return (result == NSS_STATUS_SUCCESS);
+ return True;
}
-/* Call winbindd to convert SID to gid. Do not allocate */
+/* Utility function. Convert a name to a uid_t if possible. */
-BOOL winbind_sid_to_gid_query(gid_t *pgid, const DOM_SID *sid)
+BOOL winbind_nametouid(uid_t *puid, const char *name)
{
- struct winbindd_request request;
- struct winbindd_response response;
- int result;
- fstring sid_str;
-
- if (!pgid)
- return False;
+ DOM_SID sid;
+ enum SID_NAME_USE name_type;
- /* Initialise request */
+ if (!winbind_lookup_name(NULL, name, &sid, &name_type))
+ return False;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
+ if (name_type != SID_NAME_USER)
+ return False;
- sid_to_string(sid_str, sid);
- fstrcpy(request.data.sid, sid_str);
-
- request.flags = WBFLAG_QUERY_ONLY;
+ return winbind_sid_to_uid(puid, &sid);
+}
- /* Make request */
+/* Utility function. Convert a name to a gid_t if possible. */
- result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
+BOOL winbind_nametogid(gid_t *pgid, const char *gname)
+{
+ DOM_SID g_sid;
+ enum SID_NAME_USE name_type;
- /* Copy out result */
+ if (!winbind_lookup_name(NULL, gname, &g_sid, &name_type))
+ return False;
- if (result == NSS_STATUS_SUCCESS) {
- *pgid = response.data.gid;
- }
+ if (name_type != SID_NAME_DOM_GRP)
+ return False;
- return (result == NSS_STATUS_SUCCESS);
+ return winbind_sid_to_gid(pgid, &g_sid);
}
-
-#endif /* JERRY */
-
-/***********************************************************************/
-
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 40221b69feb..928b70d8b1b 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -5,8 +5,6 @@
Copyright (C) Tim Potter 2000
Copyright (C) Andrew Tridgell 2000
- Copyright (C) Andrew Bartlett 2002
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -24,11 +22,13 @@
Boston, MA 02111-1307, USA.
*/
-#include "winbind_client.h"
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
/* Global variables. These are effectively the client state information */
int winbindd_fd = -1; /* fd for winbindd socket */
+static char *excluded_domain;
/* Free a response structure */
@@ -40,15 +40,39 @@ void free_response(struct winbindd_response *response)
SAFE_FREE(response->extra_data);
}
+/*
+ smbd needs to be able to exclude lookups for its own domain
+*/
+void winbind_exclude_domain(const char *domain)
+{
+ SAFE_FREE(excluded_domain);
+ excluded_domain = strdup(domain);
+}
+
+
/* Initialise a request structure */
void init_request(struct winbindd_request *request, int request_type)
{
+ static char *domain_env;
+ static BOOL initialised;
+
request->length = sizeof(struct winbindd_request);
request->cmd = (enum winbindd_cmd)request_type;
request->pid = getpid();
+ request->domain[0] = '\0';
+
+ if (!initialised) {
+ initialised = True;
+ domain_env = getenv(WINBINDD_DOMAIN_ENV);
+ }
+ if (domain_env) {
+ strncpy(request->domain, domain_env,
+ sizeof(request->domain) - 1);
+ request->domain[sizeof(request->domain) - 1] = '\0';
+ }
}
/* Initialise a response structure */
@@ -70,77 +94,27 @@ void close_sock(void)
}
}
-/* Make sure socket handle isn't stdin, stdout or stderr */
-#define RECURSION_LIMIT 3
-
-static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */)
-{
- int new_fd;
- if (fd >= 0 && fd <= 2) {
-#ifdef F_DUPFD
- if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) {
- return -1;
- }
- /* Paranoia */
- if (new_fd < 3) {
- close(new_fd);
- return -1;
- }
- close(fd);
- return new_fd;
-#else
- if (limit <= 0)
- return -1;
-
- new_fd = dup(fd);
- if (new_fd == -1)
- return -1;
-
- /* use the program stack to hold our list of FDs to close */
- new_fd = make_nonstd_fd_internals(new_fd, limit - 1);
- close(fd);
- return new_fd;
-#endif
- }
- return fd;
-}
-
-static int make_safe_fd(int fd)
-{
- int result, flags;
- int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT);
- if (new_fd == -1) {
- close(fd);
- return -1;
- }
- /* Socket should be closed on exec() */
-
-#ifdef FD_CLOEXEC
- result = flags = fcntl(new_fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl( new_fd, F_SETFD, flags );
- }
- if (result < 0) {
- close(new_fd);
- return -1;
- }
-#endif
- return new_fd;
-}
-
/* Connect to winbindd socket */
-static int winbind_named_pipe_sock(const char *dir)
+int winbind_open_pipe_sock(void)
{
struct sockaddr_un sunaddr;
+ static pid_t our_pid;
struct stat st;
pstring path;
- int fd;
+
+ if (our_pid != getpid()) {
+ close_sock();
+ our_pid = getpid();
+ }
+
+ if (winbindd_fd != -1) {
+ return winbindd_fd;
+ }
/* Check permissions on unix socket directory */
- if (lstat(dir, &st) == -1) {
+ if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
return -1;
}
@@ -151,13 +125,13 @@ static int winbind_named_pipe_sock(const char *dir)
/* Connect to socket */
- strncpy(path, dir, sizeof(path) - 1);
+ strncpy(path, WINBINDD_SOCKET_DIR, sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
- strncat(path, "/", sizeof(path) - 1 - strlen(path));
+ strncat(path, "/", sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
- strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1 - strlen(path));
+ strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
ZERO_STRUCT(sunaddr);
@@ -181,70 +155,17 @@ static int winbind_named_pipe_sock(const char *dir)
/* Connect to socket */
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return -1;
}
-
- if ((fd = make_safe_fd( fd)) == -1) {
- return fd;
- }
- if (connect(fd, (struct sockaddr *)&sunaddr,
+ if (connect(winbindd_fd, (struct sockaddr *)&sunaddr,
sizeof(sunaddr)) == -1) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-/* Connect to winbindd socket */
-
-int winbind_open_pipe_sock(void)
-{
-#ifdef HAVE_UNIXSOCKET
- static pid_t our_pid;
- struct winbindd_request request;
- struct winbindd_response response;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (our_pid != getpid()) {
- close_sock();
- our_pid = getpid();
- }
-
- if (winbindd_fd != -1) {
- return winbindd_fd;
- }
-
- if ((winbindd_fd = winbind_named_pipe_sock(WINBINDD_SOCKET_DIR)) == -1) {
- return -1;
- }
-
- /* version-check the socket */
-
- if ((winbindd_request(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) {
close_sock();
return -1;
}
-
- /* try and get priv pipe */
-
- if (winbindd_request(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) {
- int fd;
- if ((fd = winbind_named_pipe_sock(response.extra_data)) != -1) {
- close(winbindd_fd);
- winbindd_fd = fd;
- }
- }
-
- SAFE_FREE(response.extra_data);
-
+
return winbindd_fd;
-#else
- return -1;
-#endif /* HAVE_UNIXSOCKET */
}
/* Write data to winbindd socket */
@@ -397,15 +318,17 @@ int read_reply(struct winbindd_response *response)
NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
{
struct winbindd_request lrequest;
- char *env;
- int value;
-
+
/* Check for our tricky environment variable */
- if ( (env = getenv(WINBINDD_DONT_ENV)) != NULL ) {
- value = atoi(env);
- if ( value == 1 )
- return NSS_STATUS_NOTFOUND;
+ if (getenv(WINBINDD_DONT_ENV)) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* smbd may have excluded this domain */
+ if (excluded_domain &&
+ strcasecmp(excluded_domain, request->domain) == 0) {
+ return NSS_STATUS_NOTFOUND;
}
if (!request) {
@@ -460,8 +383,8 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response)
/* Handle simple types of requests */
NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
+ struct winbindd_request *request,
+ struct winbindd_response *response)
{
NSS_STATUS status;
@@ -470,25 +393,3 @@ NSS_STATUS winbindd_request(int req_type,
return(status);
return winbindd_get_response(response);
}
-
-/*************************************************************************
- A couple of simple functions to disable winbindd lookups and re-
- enable them
- ************************************************************************/
-
-/* Use putenv() instead of setenv() in these functions as not all
- environments have the latter. */
-
-BOOL winbind_off( void )
-{
- static char *s = WINBINDD_DONT_ENV "=1";
-
- return putenv(s) != -1;
-}
-
-BOOL winbind_on( void )
-{
- static char *s = WINBINDD_DONT_ENV "=0";
-
- return putenv(s) != -1;
-}
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index ce48e9ae652..025cf6a8e9e 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -3,7 +3,7 @@
Winbind status program.
- Copyright (C) Tim Potter 2000-2003
+ Copyright (C) Tim Potter 2000-2002
Copyright (C) Andrew Bartlett 2002
This program is free software; you can redistribute it and/or modify
@@ -25,10 +25,11 @@
#include "winbindd.h"
#include "debug.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
+/* Prototypes from common.h */
-extern int winbindd_fd;
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
static char winbind_separator(void)
{
@@ -45,7 +46,7 @@ static char winbind_separator(void)
if (winbindd_request(WINBINDD_INFO, NULL, &response) !=
NSS_STATUS_SUCCESS) {
- d_printf("could not obtain winbind separator!\n");
+ printf("could not obtain winbind separator!\n");
/* HACK: (this module should not call lp_ funtions) */
return *lp_winbind_separator();
}
@@ -54,7 +55,7 @@ static char winbind_separator(void)
got_sep = True;
if (!sep) {
- d_printf("winbind separator was NULL!\n");
+ printf("winbind separator was NULL!\n");
/* HACK: (this module should not call lp_ funtions) */
sep = *lp_winbind_separator();
}
@@ -62,7 +63,7 @@ static char winbind_separator(void)
return sep;
}
-static const char *get_winbind_domain(void)
+static char *get_winbind_domain(void)
{
struct winbindd_response response;
static fstring winbind_domain;
@@ -73,7 +74,7 @@ static const char *get_winbind_domain(void)
if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
NSS_STATUS_SUCCESS) {
- d_printf("could not obtain winbind domain name!\n");
+ printf("could not obtain winbind domain name!\n");
/* HACK: (this module should not call lp_ funtions) */
return lp_workgroup();
@@ -103,7 +104,7 @@ static BOOL parse_wbinfo_domain_user(const char *domuser, fstring domain,
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
- strupper_m(domain);
+ strupper(domain);
return True;
}
@@ -129,38 +130,7 @@ static BOOL wbinfo_get_usergroups(char *user)
return False;
for (i = 0; i < response.data.num_entries; i++)
- d_printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
-
- SAFE_FREE(response.extra_data);
-
- return True;
-}
-
-
-/* List group SIDs a user SID is a member of */
-static BOOL wbinfo_get_usersids(char *user_sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- int i;
- const char *s;
-
- ZERO_STRUCT(response);
-
- /* Send request */
- fstrcpy(request.data.sid, user_sid);
-
- result = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response);
-
- if (result != NSS_STATUS_SUCCESS)
- return False;
-
- s = response.extra_data;
- for (i = 0; i < response.data.num_entries; i++) {
- d_printf("%s\n", s);
- s += strlen(s) + 1;
- }
+ printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
SAFE_FREE(response.extra_data);
@@ -237,10 +207,10 @@ static BOOL wbinfo_list_domains(void)
/* Display response */
if (response.extra_data) {
- const char *extra_data = (char *)response.extra_data;
+ const char *extra_data = (const char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
+ printf("%s\n", name);
SAFE_FREE(response.extra_data);
}
@@ -250,20 +220,15 @@ static BOOL wbinfo_list_domains(void)
/* show sequence numbers */
-static BOOL wbinfo_show_sequence(const char *domain)
+static BOOL wbinfo_show_sequence(void)
{
- struct winbindd_request request;
struct winbindd_response response;
ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- if ( domain )
- fstrcpy( request.domain_name, domain );
/* Send request */
- if (winbindd_request(WINBINDD_SHOW_SEQUENCE, &request, &response) !=
+ if (winbindd_request(WINBINDD_SHOW_SEQUENCE, NULL, &response) !=
NSS_STATUS_SUCCESS)
return False;
@@ -271,71 +236,37 @@ static BOOL wbinfo_show_sequence(const char *domain)
if (response.extra_data) {
char *extra_data = (char *)response.extra_data;
- d_printf("%s", extra_data);
+ printf("%s", extra_data);
SAFE_FREE(response.extra_data);
}
return True;
}
-/* Show domain info */
-
-static BOOL wbinfo_domain_info(const char *domain_name)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.domain_name, domain_name);
-
- /* Send request */
-
- if (winbindd_request(WINBINDD_DOMAIN_INFO, &request, &response) !=
- NSS_STATUS_SUCCESS)
- return False;
-
- /* Display response */
-
- d_printf("Name : %s\n", response.data.domain_info.name);
- d_printf("Alt_Name : %s\n", response.data.domain_info.alt_name);
-
- d_printf("SID : %s\n", response.data.domain_info.sid);
-
- d_printf("Active Directory : %s\n",
- response.data.domain_info.active_directory ? "Yes" : "No");
- d_printf("Native : %s\n",
- response.data.domain_info.native_mode ? "Yes" : "No");
-
- d_printf("Primary : %s\n",
- response.data.domain_info.primary ? "Yes" : "No");
-
- d_printf("Sequence : %d\n", response.data.domain_info.sequence_number);
-
- return True;
-}
-
/* Check trust account password */
static BOOL wbinfo_check_secret(void)
{
struct winbindd_response response;
- NSS_STATUS result;
+ BOOL result;
ZERO_STRUCT(response);
- result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
-
- d_printf("checking the trust secret via RPC calls %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+ result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
+ NSS_STATUS_SUCCESS;
- if (result != NSS_STATUS_SUCCESS)
- d_printf("error code was %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status);
-
- return result == NSS_STATUS_SUCCESS;
+ if (result) {
+
+ if (response.data.auth.nt_status == 0)
+ printf("Secret is good\n");
+ else
+ printf("Secret is bad\n0x%08x\n",
+ response.data.auth.nt_status);
+
+ return True;
+ }
+
+ return False;
}
/* Convert uid to sid */
@@ -358,7 +289,7 @@ static BOOL wbinfo_uid_to_sid(uid_t uid)
/* Display response */
- d_printf("%s\n", response.data.sid.sid);
+ printf("%s\n", response.data.sid.sid);
return True;
}
@@ -383,7 +314,7 @@ static BOOL wbinfo_gid_to_sid(gid_t gid)
/* Display response */
- d_printf("%s\n", response.data.sid.sid);
+ printf("%s\n", response.data.sid.sid);
return True;
}
@@ -408,7 +339,7 @@ static BOOL wbinfo_sid_to_uid(char *sid)
/* Display response */
- d_printf("%d\n", (int)response.data.uid);
+ printf("%d\n", (int)response.data.uid);
return True;
}
@@ -431,19 +362,7 @@ static BOOL wbinfo_sid_to_gid(char *sid)
/* Display response */
- d_printf("%d\n", (int)response.data.gid);
-
- return True;
-}
-
-static BOOL wbinfo_allocate_rid(void)
-{
- uint32 rid;
-
- if (!winbind_allocate_rid(&rid))
- return False;
-
- d_printf("New rid: %d\n", rid);
+ printf("%d\n", (int)response.data.gid);
return True;
}
@@ -468,7 +387,7 @@ static BOOL wbinfo_lookupsid(char *sid)
/* Display response */
- d_printf("%s%c%s %d\n", response.data.name.dom_name,
+ printf("%s%c%s %d\n", response.data.name.dom_name,
winbind_separator(), response.data.name.name,
response.data.name.type);
@@ -496,7 +415,7 @@ static BOOL wbinfo_lookupname(char *name)
/* Display response */
- d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type);
+ printf("%s %d\n", response.data.sid.sid, response.data.sid.type);
return True;
}
@@ -529,18 +448,19 @@ static BOOL wbinfo_auth(char *username)
/* Display response */
- d_printf("plaintext password authentication %s\n",
+ printf("plaintext password authentication %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
if (response.data.auth.nt_status)
- d_printf("error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
+ printf("error code was %s (0x%x)\n",
+ response.data.auth.nt_status_string,
+ response.data.auth.nt_status);
return result == NSS_STATUS_SUCCESS;
}
+#ifdef WITH_WINBIND_AUTH_CRAP
+
/* Authenticate a user with a challenge/response */
static BOOL wbinfo_auth_crap(char *username)
@@ -567,24 +487,15 @@ static BOOL wbinfo_auth_crap(char *username)
parse_wbinfo_domain_user(username, name_domain, name_user);
- if (push_utf8_fstring(request.data.auth_crap.user, name_user) == -1) {
- d_printf("unable to create utf8 string for '%s'\n",
- name_user);
- return False;
- }
+ fstrcpy(request.data.auth_crap.user, name_user);
- if (push_utf8_fstring(request.data.auth_crap.domain,
- name_domain) == -1) {
- d_printf("unable to create utf8 string for '%s'\n",
- name_domain);
- return False;
- }
+ fstrcpy(request.data.auth_crap.domain, name_domain);
generate_random_buffer(request.data.auth_crap.chal, 8, False);
- SMBencrypt(pass, request.data.auth_crap.chal,
+ SMBencrypt((uchar *)pass, request.data.auth_crap.chal,
(uchar *)request.data.auth_crap.lm_resp);
- SMBNTencrypt(pass, request.data.auth_crap.chal,
+ SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
(uchar *)request.data.auth_crap.nt_resp);
request.data.auth_crap.lm_resp_len = 24;
@@ -594,320 +505,83 @@ static BOOL wbinfo_auth_crap(char *username)
/* Display response */
- d_printf("challenge/response password authentication %s\n",
+ printf("challenge/response password authentication %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
if (response.data.auth.nt_status)
- d_printf("error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
+ printf("error code was %s (0x%x)\n",
+ response.data.auth.nt_status_string,
+ response.data.auth.nt_status);
return result == NSS_STATUS_SUCCESS;
}
-/* Authenticate a user with a plaintext password and set a token */
-
-static BOOL wbinfo_klog(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *p;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, p + 1);
- *p = '%';
- } else {
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, getpass("Password: "));
- }
-
- request.flags |= WBFLAG_PAM_AFS_TOKEN;
-
- result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
-
- /* Display response */
-
- d_printf("plaintext password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
-
- if (response.data.auth.nt_status)
- d_printf("error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
-
- if (result != NSS_STATUS_SUCCESS)
- return False;
-
- if (response.extra_data == NULL) {
- d_printf("Did not get token data\n");
- return False;
- }
-
- if (!afs_settoken_str((char *)response.extra_data)) {
- d_printf("Could not set token\n");
- return False;
- }
-
- d_printf("Successfully created AFS token\n");
- return True;
-}
-
-/******************************************************************
- create a winbindd user
-******************************************************************/
-
-static BOOL wbinfo_create_user(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.flags = WBFLAG_ALLOCATE_RID;
- fstrcpy(request.data.acct_mgt.username, username);
-
- result = winbindd_request(WINBINDD_CREATE_USER, &request, &response);
-
- if ( result == NSS_STATUS_SUCCESS )
- d_printf("New RID is %d\n", response.data.rid);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/******************************************************************
- remove a winbindd user
-******************************************************************/
-
-static BOOL wbinfo_delete_user(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.acct_mgt.username, username);
-
- result = winbindd_request(WINBINDD_DELETE_USER, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/******************************************************************
- create a winbindd group
-******************************************************************/
-
-static BOOL wbinfo_create_group(char *groupname)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.acct_mgt.groupname, groupname);
-
- result = winbindd_request(WINBINDD_CREATE_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/******************************************************************
- remove a winbindd group
-******************************************************************/
-
-static BOOL wbinfo_delete_group(char *groupname)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.acct_mgt.groupname, groupname);
-
- result = winbindd_request(WINBINDD_DELETE_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/******************************************************************
- parse a string in the form user:group
-******************************************************************/
-
-static BOOL parse_user_group( const char *string, fstring user, fstring group )
-{
- char *p;
-
- if ( !string )
- return False;
-
- if ( !(p = strchr( string, ':' )) )
- return False;
-
- *p = '\0';
- p++;
-
- fstrcpy( user, string );
- fstrcpy( group, p );
-
- return True;
-}
-
-/******************************************************************
- add a user to a winbindd group
-******************************************************************/
-
-static BOOL wbinfo_add_user_to_group(char *string)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if ( !parse_user_group( string, request.data.acct_mgt.username,
- request.data.acct_mgt.groupname))
- {
- d_printf("Can't parse user:group from %s\n", string);
- return False;
- }
-
- result = winbindd_request(WINBINDD_ADD_USER_TO_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/******************************************************************
- remove a user from a winbindd group
-******************************************************************/
-
-static BOOL wbinfo_remove_user_from_group(char *string)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if ( !parse_user_group( string, request.data.acct_mgt.username,
- request.data.acct_mgt.groupname))
- {
- d_printf("Can't parse user:group from %s\n", string);
- return False;
- }
-
- result = winbindd_request(WINBINDD_REMOVE_USER_FROM_GROUP, &request, &response);
-
- return result == NSS_STATUS_SUCCESS;
-}
+#endif /* WITH_WINBIND_AUTH_CRAP */
/* Print domain users */
-static BOOL print_domain_users(const char *domain)
+static BOOL print_domain_users(void)
{
- struct winbindd_request request;
struct winbindd_response response;
const char *extra_data;
fstring name;
/* Send request to winbind daemon */
- ZERO_STRUCT(request);
ZERO_STRUCT(response);
-
- if (domain) {
- /* '.' is the special sign for our own domwin */
- if ( strequal(domain, ".") )
- fstrcpy( request.domain_name, lp_workgroup() );
- else
- fstrcpy( request.domain_name, domain );
- }
- if (winbindd_request(WINBINDD_LIST_USERS, &request, &response) !=
+ if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) !=
NSS_STATUS_SUCCESS)
return False;
/* Look through extra data */
if (!response.extra_data)
- return False;
+ goto done;
extra_data = (const char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
+ printf("%s\n", name);
SAFE_FREE(response.extra_data);
+done:
+ if (response.nt_status)
+ printf("0x%08x\n", response.nt_status);
+
return True;
}
/* Print domain groups */
-static BOOL print_domain_groups(const char *domain)
+static BOOL print_domain_groups(void)
{
- struct winbindd_request request;
struct winbindd_response response;
const char *extra_data;
fstring name;
- ZERO_STRUCT(request);
ZERO_STRUCT(response);
- if (domain) {
- if ( strequal(domain, ".") )
- fstrcpy( request.domain_name, lp_workgroup() );
- else
- fstrcpy( request.domain_name, domain );
- }
-
- if (winbindd_request(WINBINDD_LIST_GROUPS, &request, &response) !=
+ if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) !=
NSS_STATUS_SUCCESS)
return False;
/* Look through extra data */
if (!response.extra_data)
- return False;
+ goto done;
extra_data = (const char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- d_printf("%s\n", name);
+ printf("%s\n", name);
SAFE_FREE(response.extra_data);
+
+done:
+ if (response.nt_status)
+ printf("0x%08x\n", response.nt_status);
return True;
}
@@ -916,195 +590,164 @@ static BOOL print_domain_groups(const char *domain)
static BOOL wbinfo_set_auth_user(char *username)
{
- const char *password;
- char *p;
+ char *password;
fstring user, domain;
/* Separate into user and password */
parse_wbinfo_domain_user(username, domain, user);
- p = strchr(user, '%');
-
- if (p != NULL) {
- *p = 0;
- password = p+1;
- } else {
- char *thepass = getpass("Password: ");
- if (thepass) {
- password = thepass;
- } else
- password = "";
- }
-
- /* Store or remove DOMAIN\username%password in secrets.tdb */
-
- secrets_init();
-
- if (user[0]) {
-
- if (!secrets_store(SECRETS_AUTH_USER, user,
- strlen(user) + 1)) {
- d_fprintf(stderr, "error storing username\n");
- return False;
- }
-
- /* We always have a domain name added by the
- parse_wbinfo_domain_user() function. */
-
- if (!secrets_store(SECRETS_AUTH_DOMAIN, domain,
- strlen(domain) + 1)) {
- d_fprintf(stderr, "error storing domain name\n");
- return False;
- }
-
- } else {
- secrets_delete(SECRETS_AUTH_USER);
- secrets_delete(SECRETS_AUTH_DOMAIN);
- }
-
- if (password[0]) {
-
- if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
- strlen(password) + 1)) {
- d_fprintf(stderr, "error storing password\n");
- return False;
- }
+ password = strchr(user, '%');
+ if (password) {
+ *password = 0;
+ password++;
} else
- secrets_delete(SECRETS_AUTH_PASSWORD);
-
- return True;
-}
+ password = "";
-static void wbinfo_get_auth_user(void)
-{
- char *user, *domain, *password;
-
- /* Lift data from secrets file */
-
- secrets_fetch_ipc_userpass(&user, &domain, &password);
+ /* Store in secrets.tdb */
- if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){
+ secrets_init();
- SAFE_FREE(user);
- SAFE_FREE(domain);
- SAFE_FREE(password);
- d_printf("No authorised user configured\n");
- return;
+ if (!secrets_store(SECRETS_AUTH_USER, user,
+ strlen(user) + 1) ||
+ !secrets_store(SECRETS_AUTH_DOMAIN, domain,
+ strlen(domain) + 1) ||
+ !secrets_store(SECRETS_AUTH_PASSWORD, password,
+ strlen(password) + 1)) {
+ fprintf(stderr, "error storing authenticated user info\n");
+ return False;
}
- /* Pretty print authorised user info */
-
- d_printf("%s%s%s%s%s\n", domain ? domain : "", domain ? lp_winbind_separator(): "",
- user, password ? "%" : "", password ? password : "");
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
- SAFE_FREE(password);
+ return True;
}
static BOOL wbinfo_ping(void)
{
NSS_STATUS result;
-
+
result = winbindd_request(WINBINDD_PING, NULL, NULL);
/* Display response */
- d_printf("Ping to winbindd %s on fd %d\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd);
+ printf("'ping' to winbindd %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
return result == NSS_STATUS_SUCCESS;
}
+/* Print program usage */
+
+static void usage(void)
+{
+ printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
+ "| -[aA] user%%password\n");
+ printf("Version: %s\n", VERSION);
+ printf("\t-u\t\t\tlists all domain users\n");
+ printf("\t-g\t\t\tlists all domain groups\n");
+ printf("\t-n name\t\t\tconverts name to sid\n");
+ printf("\t-s sid\t\t\tconverts sid to name\n");
+ printf("\t-N name\t\t\tconverts NetBIOS name to IP (WINS)\n");
+ printf("\t-I IP\t\t\tconverts IP address to NetBIOS name (WINS)\n");
+ printf("\t-U uid\t\t\tconverts uid to sid\n");
+ printf("\t-G gid\t\t\tconverts gid to sid\n");
+ printf("\t-S sid\t\t\tconverts sid to uid\n");
+ printf("\t-Y sid\t\t\tconverts sid to gid\n");
+ printf("\t-t\t\t\tcheck shared secret\n");
+ printf("\t-m\t\t\tlist trusted domains\n");
+ printf("\t-r user\t\t\tget user groups\n");
+ printf("\t-a user%%password\tauthenticate user\n");
+ printf("\t-A user%%password\tstore user and password used by winbindd (root only)\n");
+ printf("\t-p\t\t\t'ping' winbindd to see if it is alive\n");
+ printf("\t--sequence\t\tshow sequence numbers of all domains\n");
+ printf("\t--set-auth-user DOMAIN\\user%%password\tset password for restrict anonymous\n");
+}
+
/* Main program */
enum {
OPT_SET_AUTH_USER = 1000,
- OPT_GET_AUTH_USER,
- OPT_DOMAIN_NAME,
- OPT_SEQUENCE,
- OPT_USERSIDS
+ OPT_SEQUENCE
};
int main(int argc, char **argv)
{
+ extern pstring global_myname;
int opt;
poptContext pc;
static char *string_arg;
- static char *opt_domain_name;
static int int_arg;
+ BOOL got_command = False;
int result = 1;
struct poptOption long_options[] = {
- POPT_AUTOHELP
/* longName, shortName, argInfo, argPtr, value, descrip,
argDesc */
- { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
- { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
- { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
- { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
- { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
- { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
- { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
- { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
- { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
- { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
- { "allocate-rid", 'A', POPT_ARG_NONE, 0, 'A', "Get a new RID out of idmap" },
- { "create-user", 'c', POPT_ARG_STRING, &string_arg, 'c', "Create a local user account", "name" },
- { "delete-user", 'x', POPT_ARG_STRING, &string_arg, 'x', "Delete a local user account", "name" },
- { "create-group", 'C', POPT_ARG_STRING, &string_arg, 'C', "Create a local group", "name" },
- { "delete-group", 'X', POPT_ARG_STRING, &string_arg, 'X', "Delete a local group", "name" },
- { "add-to-group", 'o', POPT_ARG_STRING, &string_arg, 'o', "Add user to group", "user:group" },
- { "del-from-group", 'O', POPT_ARG_STRING, &string_arg, 'O', "Remove user from group", "user:group" },
- { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
- { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
- { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
- { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
- { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
- { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
- { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
- { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
- { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
- { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
- { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
-#ifdef WITH_FAKE_KASERVER
- { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
-#endif
- POPT_COMMON_VERSION
- POPT_TABLEEND
+ { "help", 'h', POPT_ARG_NONE, 0, 'h' },
+ { "domain-users", 'u', POPT_ARG_NONE, 0, 'u' },
+ { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g' },
+ { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N' },
+ { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I' },
+ { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n' },
+ { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's' },
+ { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U' },
+ { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G' },
+ { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S' },
+ { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y' },
+ { "check-secret", 't', POPT_ARG_NONE, 0, 't' },
+ { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm' },
+ { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE },
+ { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r' },
+ { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a' },
+ { "set-auth-user", 'A', POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER },
+ { "ping", 'p', POPT_ARG_NONE, 0, 'p' },
+ { 0, 0, 0, 0 }
};
/* Samba client initialisation */
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
- dyn_CONFIGFILE, strerror(errno));
- exit(1);
+ if (!*global_myname) {
+ char *p;
+
+ fstrcpy(global_myname, myhostname());
+ p = strchr(global_myname, '.');
+ if (p)
+ *p = 0;
}
- if (!init_names())
- return 1;
+ TimeInit();
- load_interfaces();
+ codepage_initialise(lp_client_code_page());
+ charset_initialise();
- /* Parse options */
+ if (!lp_load(CONFIGFILE, True, False, False)) {
+ fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
+ CONFIGFILE, strerror(errno));
+ exit(1);
+ }
- pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0);
+ load_interfaces();
/* Parse command line options */
if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
+ usage();
return 1;
}
+ /* Parse options */
+
+ pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0);
+
while((opt = poptGetNextOpt(pc)) != -1) {
- /* get the generic configuration parameters like --domain */
+ if (got_command) {
+ fprintf(stderr, "No more than one command may be specified at once.\n");
+ exit(1);
+ }
+ got_command = True;
}
poptFreeContext(pc);
@@ -1114,192 +757,132 @@ int main(int argc, char **argv)
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
+ case 'h':
+ usage();
+ result = 0;
+ goto done;
case 'u':
- if (!print_domain_users(opt_domain_name)) {
- d_printf("Error looking up domain users\n");
+ if (!print_domain_users()) {
+ printf("Error looking up domain users\n");
goto done;
}
break;
case 'g':
- if (!print_domain_groups(opt_domain_name)) {
- d_printf("Error looking up domain groups\n");
+ if (!print_domain_groups()) {
+ printf("Error looking up domain groups\n");
goto done;
}
break;
case 's':
if (!wbinfo_lookupsid(string_arg)) {
- d_printf("Could not lookup sid %s\n", string_arg);
+ printf("Could not lookup sid %s\n", string_arg);
goto done;
}
break;
case 'n':
if (!wbinfo_lookupname(string_arg)) {
- d_printf("Could not lookup name %s\n", string_arg);
+ printf("Could not lookup name %s\n", string_arg);
goto done;
}
break;
case 'N':
if (!wbinfo_wins_byname(string_arg)) {
- d_printf("Could not lookup WINS by name %s\n", string_arg);
+ printf("Could not lookup WINS by name %s\n", string_arg);
goto done;
}
break;
case 'I':
if (!wbinfo_wins_byip(string_arg)) {
- d_printf("Could not lookup WINS by IP %s\n", string_arg);
+ printf("Could not lookup WINS by IP %s\n", string_arg);
goto done;
}
break;
case 'U':
if (!wbinfo_uid_to_sid(int_arg)) {
- d_printf("Could not convert uid %d to sid\n", int_arg);
+ printf("Could not convert uid %d to sid\n", int_arg);
goto done;
}
break;
case 'G':
if (!wbinfo_gid_to_sid(int_arg)) {
- d_printf("Could not convert gid %d to sid\n",
+ printf("Could not convert gid %d to sid\n",
int_arg);
goto done;
}
break;
case 'S':
if (!wbinfo_sid_to_uid(string_arg)) {
- d_printf("Could not convert sid %s to uid\n",
+ printf("Could not convert sid %s to uid\n",
string_arg);
goto done;
}
break;
case 'Y':
if (!wbinfo_sid_to_gid(string_arg)) {
- d_printf("Could not convert sid %s to gid\n",
+ printf("Could not convert sid %s to gid\n",
string_arg);
goto done;
}
break;
- case 'A':
- if (!wbinfo_allocate_rid()) {
- d_printf("Could not allocate a RID\n");
- goto done;
- }
- break;
case 't':
if (!wbinfo_check_secret()) {
- d_printf("Could not check secret\n");
+ printf("Could not check secret\n");
goto done;
}
break;
case 'm':
if (!wbinfo_list_domains()) {
- d_printf("Could not list trusted domains\n");
+ printf("Could not list trusted domains\n");
goto done;
}
break;
case OPT_SEQUENCE:
- if (!wbinfo_show_sequence(opt_domain_name)) {
- d_printf("Could not show sequence numbers\n");
- goto done;
- }
- break;
- case 'D':
- if (!wbinfo_domain_info(string_arg)) {
- d_printf("Could not get domain info\n");
+ if (!wbinfo_show_sequence()) {
+ printf("Could not show sequence numbers\n");
goto done;
}
break;
case 'r':
if (!wbinfo_get_usergroups(string_arg)) {
- d_printf("Could not get groups for user %s\n",
+ printf("Could not get groups for user %s\n",
string_arg);
goto done;
}
break;
- case OPT_USERSIDS:
- if (!wbinfo_get_usersids(string_arg)) {
- d_printf("Could not get group SIDs for user SID %s\n",
- string_arg);
- goto done;
- }
- break;
- case 'a': {
- BOOL got_error = False;
-
- if (!wbinfo_auth(string_arg)) {
- d_printf("Could not authenticate user %s with "
- "plaintext password\n", string_arg);
- got_error = True;
- }
-
- if (!wbinfo_auth_crap(string_arg)) {
- d_printf("Could not authenticate user %s with "
- "challenge/response\n", string_arg);
- got_error = True;
- }
-
- if (got_error)
- goto done;
- break;
- }
- case 'k':
- if (!wbinfo_klog(string_arg)) {
- d_printf("Could not klog user\n");
- goto done;
- }
- break;
- case 'c':
- if ( !wbinfo_create_user(string_arg) ) {
- d_printf("Could not create user account\n");
- goto done;
- }
- break;
- case 'C':
- if ( !wbinfo_create_group(string_arg) ) {
- d_printf("Could not create group\n");
- goto done;
- }
- break;
- case 'o':
- if ( !wbinfo_add_user_to_group(string_arg) ) {
- d_printf("Could not add user to group\n");
- goto done;
- }
- break;
- case 'O':
- if ( !wbinfo_remove_user_from_group(string_arg) ) {
- d_printf("Could not remove user from group\n");
- goto done;
- }
- break;
- case 'x':
- if ( !wbinfo_delete_user(string_arg) ) {
- d_printf("Could not delete user account\n");
- goto done;
- }
- break;
- case 'X':
- if ( !wbinfo_delete_group(string_arg) ) {
- d_printf("Could not delete group\n");
- goto done;
- }
- break;
- case 'p':
- if (!wbinfo_ping()) {
- d_printf("could not ping winbindd!\n");
- goto done;
+ case 'a': {
+ BOOL got_error = False;
+
+ if (!wbinfo_auth(string_arg)) {
+ printf("Could not authenticate user %s with "
+ "plaintext password\n", string_arg);
+ got_error = True;
+ }
+#ifdef WITH_WINBIND_AUTH_CRAP
+ if (!wbinfo_auth_crap(string_arg)) {
+ printf("Could not authenticate user %s with "
+ "challenge/response\n", string_arg);
+ got_error = True;
+ }
+#endif
+ if (got_error)
+ goto done;
+ break;
+ }
+ case 'p': {
+
+ if (!wbinfo_ping()) {
+ printf("could not ping winbindd!\n");
+ goto done;
}
- break;
+ break;
+ }
case OPT_SET_AUTH_USER:
- wbinfo_set_auth_user(string_arg);
- break;
- case OPT_GET_AUTH_USER:
- wbinfo_get_auth_user();
- break;
- /* generic configuration options */
- case OPT_DOMAIN_NAME:
+ if (!(wbinfo_set_auth_user(string_arg)))
+ goto done;
break;
default:
- d_fprintf(stderr, "Invalid option\n");
- poptPrintHelp(pc, stderr, 0);
+ fprintf(stderr, "Invalid option\n");
+ usage();
goto done;
}
}
diff --git a/source/nsswitch/winbind_client.h b/source/nsswitch/winbind_client.h
deleted file mode 100644
index 4de2d57cc7d..00000000000
--- a/source/nsswitch/winbind_client.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "winbind_nss_config.h"
-#include "winbindd_nss.h"
-
-void init_request(struct winbindd_request *req,int rq_type);
-NSS_STATUS winbindd_send_request(int req_type,
- struct winbindd_request *request);
-NSS_STATUS winbindd_get_response(struct winbindd_response *response);
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-int winbind_open_pipe_sock(void);
-int write_sock(void *buffer, int count);
-int read_reply(struct winbindd_response *response);
-void close_sock(void);
-void free_response(struct winbindd_response *response);
-
diff --git a/source/nsswitch/winbind_nss_linux.c b/source/nsswitch/winbind_nss.c
index ae2bcc7ade9..c63dfcfbb93 100644..100755
--- a/source/nsswitch/winbind_nss_linux.c
+++ b/source/nsswitch/winbind_nss.c
@@ -21,11 +21,14 @@
Boston, MA 02111-1307, USA.
*/
-#include "winbind_client.h"
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
-/* Maximum number of users to pass back over the unix domain socket
- per call. This is not a static limit on the total number of users
- or groups returned in total. */
+#ifdef HAVE_NS_API_H
+#undef VOLATILE
+
+#include <ns_daemon.h>
+#endif
#define MAX_GETPWENT_USERS 250
#define MAX_GETGRENT_USERS 250
@@ -34,11 +37,496 @@
extern int winbindd_fd;
+void init_request(struct winbindd_request *req,int rq_type);
+NSS_STATUS winbindd_send_request(int req_type,
+ struct winbindd_request *request);
+NSS_STATUS winbindd_get_response(struct winbindd_response *response);
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+int winbind_open_pipe_sock(void);
+int write_sock(void *buffer, int count);
+int read_reply(struct winbindd_response *response);
+void free_response(struct winbindd_response *response);
+
+#ifdef HAVE_NS_API_H
+/* IRIX version */
+
+static int send_next_request(nsd_file_t *, struct winbindd_request *);
+static int do_list(int state, nsd_file_t *rq);
+
+static nsd_file_t *current_rq = NULL;
+static int current_winbind_xid = 0;
+static int next_winbind_xid = 0;
+
+typedef struct winbind_xid {
+ int xid;
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+ struct winbind_xid *next;
+} winbind_xid_t;
+
+static winbind_xid_t *winbind_xids = (winbind_xid_t *)0;
+
+static int
+winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request)
+{
+ winbind_xid_t *new;
+
+ nsd_logprintf(NSD_LOG_LOW,
+ "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n",
+ xid, rq, request);
+ new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t));
+ if (!new) {
+ nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ new->xid = xid;
+ new->rq = rq;
+ new->request = request;
+ new->next = winbind_xids;
+ winbind_xids = new;
+
+ return NSD_CONTINUE;
+}
+
+/*
+** This routine will look down the xid list and return the request
+** associated with an xid. We remove the record if it is found.
+*/
+nsd_file_t *
+winbind_xid_lookup(int xid, struct winbindd_request **requestp)
+{
+ winbind_xid_t **last, *dx;
+ nsd_file_t *result=0;
+
+ for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid);
+ last = &dx->next, dx = dx->next);
+ if (dx) {
+ *last = dx->next;
+ result = dx->rq;
+ *requestp = dx->request;
+ SAFE_FREE(dx);
+ }
+ nsd_logprintf(NSD_LOG_LOW,
+ "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n",
+ xid, result, dx->request);
+
+ return result;
+}
+
+static int
+winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to)
+{
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n");
+ rq = to->t_file;
+ *rqp = rq;
+ nsd_timeout_remove(rq);
+ request = to->t_clientdata;
+ return(send_next_request(rq, request));
+}
+
+static void
+dequeue_request()
+{
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+
+ /*
+ * Check for queued requests
+ */
+ if (winbind_xids) {
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n",
+ current_winbind_xid);
+ rq = winbind_xid_lookup(current_winbind_xid++, &request);
+ /* cause a timeout on the queued request so we can send it */
+ nsd_timeout_new(rq,1,winbind_startnext_timeout,request);
+ }
+}
+
+static int
+do_request(nsd_file_t *rq, struct winbindd_request *request)
+{
+ if (winbind_xids == NULL) {
+ /*
+ * No outstanding requests.
+ * Send off the request to winbindd
+ */
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n");
+ return(send_next_request(rq, request));
+ } else {
+ /*
+ * Just queue it up for now - previous callout or timout
+ * will start it up
+ */
+ nsd_logprintf(NSD_LOG_MIN,
+ "lookup (winbind): queue request xid = %d\n",
+ next_winbind_xid);
+ return(winbind_xid_new(next_winbind_xid++, rq, request));
+ }
+}
+
+static int
+winbind_callback(nsd_file_t **rqp, int fd)
+{
+ struct winbindd_response response;
+ struct winbindd_pw *pw = &response.data.pw;
+ struct winbindd_gr *gr = &response.data.gr;
+ nsd_file_t *rq;
+ NSS_STATUS status;
+ fstring result;
+ char *members;
+ int i, maxlen;
+
+ dequeue_request();
+
+ nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n");
+
+ rq = current_rq;
+ *rqp = rq;
+
+ nsd_timeout_remove(rq);
+ nsd_callback_remove(fd);
+
+ ZERO_STRUCT(response);
+ status = winbindd_get_response(&response);
+
+ if (status != NSS_STATUS_SUCCESS) {
+ /* free any extra data area in response structure */
+ free_response(&response);
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) returning not found, status = %d\n",
+ status);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+
+ maxlen = sizeof(result) - 1;
+
+ switch ((int)rq->f_cmd_data) {
+ case WINBINDD_WINS_BYNAME:
+ case WINBINDD_WINS_BYIP:
+ snprintf(result,maxlen,"%s\n",response.data.winsresp);
+ break;
+ case WINBINDD_GETPWUID:
+ case WINBINDD_GETPWNAM:
+ snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+ break;
+ case WINBINDD_GETGRNAM:
+ case WINBINDD_GETGRGID:
+ if (gr->num_gr_mem && response.extra_data)
+ members = response.extra_data;
+ else
+ members = "";
+ snprintf(result,maxlen,"%s:%s:%d:%s\n",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
+ break;
+ case WINBINDD_SETGRENT:
+ case WINBINDD_SETPWENT:
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n");
+ free_response(&response);
+ return(do_list(1,rq));
+ case WINBINDD_GETGRENT:
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) - %d GETGRENT responses\n",
+ response.data.num_entries);
+ if (response.data.num_entries) {
+ gr = (struct winbindd_gr *)response.extra_data;
+ if (! gr ) {
+ nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
+ free_response(&response);
+ return NSD_ERROR;
+ }
+ members = (char *)response.extra_data +
+ (response.data.num_entries * sizeof(struct winbindd_gr));
+ for (i = 0; i < response.data.num_entries; i++) {
+ snprintf(result,maxlen,"%s:%s:%d:%s\n",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid,
+ &members[gr->gr_mem_ofs]);
+ nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result);
+ nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
+ gr++;
+ }
+ }
+ i = response.data.num_entries;
+ free_response(&response);
+ if (i < MAX_GETPWENT_USERS)
+ return(do_list(2,rq));
+ else
+ return(do_list(1,rq));
+ case WINBINDD_GETPWENT:
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) - %d GETPWENT responses\n",
+ response.data.num_entries);
+ if (response.data.num_entries) {
+ pw = (struct winbindd_pw *)response.extra_data;
+ if (! pw ) {
+ nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
+ free_response(&response);
+ return NSD_ERROR;
+ }
+ for (i = 0; i < response.data.num_entries; i++) {
+ snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+ nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result);
+ nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
+ pw++;
+ }
+ }
+ i = response.data.num_entries;
+ free_response(&response);
+ if (i < MAX_GETPWENT_USERS)
+ return(do_list(2,rq));
+ else
+ return(do_list(1,rq));
+ case WINBINDD_ENDGRENT:
+ case WINBINDD_ENDPWENT:
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n");
+ nsd_append_element(rq,NS_SUCCESS,"\n",1);
+ free_response(&response);
+ return NSD_NEXT;
+ default:
+ free_response(&response);
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n");
+ return NSD_NEXT;
+ }
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result);
+ /* free any extra data area in response structure */
+ free_response(&response);
+ nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE);
+ return NSD_OK;
+}
+
+static int
+winbind_timeout(nsd_file_t **rqp, nsd_times_t *to)
+{
+ nsd_file_t *rq;
+
+ dequeue_request();
+
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n");
+
+ rq = to->t_file;
+ *rqp = rq;
+
+ /* Remove the callback and timeout */
+ nsd_callback_remove(winbindd_fd);
+ nsd_timeout_remove(rq);
+
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+}
+
+static int
+send_next_request(nsd_file_t *rq, struct winbindd_request *request)
+{
+ NSS_STATUS status;
+ long timeout;
+
+ timeout = 1000;
+
+ nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n",
+ rq->f_cmd_data, timeout);
+ status = winbindd_send_request((int)rq->f_cmd_data,request);
+ SAFE_FREE(request);
+
+ if (status != NSS_STATUS_SUCCESS) {
+ nsd_logprintf(NSD_LOG_MIN,
+ "send_next_request (winbind) error status = %d\n",status);
+ rq->f_status = status;
+ return NSD_NEXT;
+ }
+
+ current_rq = rq;
+
+ /*
+ * Set up callback and timeouts
+ */
+ nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd);
+ nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ);
+ nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0);
+ return NSD_CONTINUE;
+}
+
+int init(void)
+{
+ nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n");
+ return(NSD_OK);
+}
+
+int lookup(nsd_file_t *rq)
+{
+ char *map;
+ char *key;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n");
+ if (! rq)
+ return NSD_ERROR;
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
+ if (! map || ! key) {
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n");
+ rq->f_status = NS_BADREQ;
+ return NSD_ERROR;
+ }
+
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map);
+
+ request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
+ if (! request) {
+ nsd_logprintf(NSD_LOG_RESOURCE,
+ "lookup (winbind): failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ if (strcasecmp(map,"passwd.byuid") == 0) {
+ request->data.uid = atoi(key);
+ rq->f_cmd_data = (void *)WINBINDD_GETPWUID;
+ } else if (strcasecmp(map,"passwd.byname") == 0) {
+ strncpy(request->data.username, key,
+ sizeof(request->data.username) - 1);
+ request->data.username[sizeof(request->data.username) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_GETPWNAM;
+ } else if (strcasecmp(map,"group.byname") == 0) {
+ strncpy(request->data.groupname, key,
+ sizeof(request->data.groupname) - 1);
+ request->data.groupname[sizeof(request->data.groupname) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_GETGRNAM;
+ } else if (strcasecmp(map,"group.bygid") == 0) {
+ request->data.gid = atoi(key);
+ rq->f_cmd_data = (void *)WINBINDD_GETGRGID;
+ } else if (strcasecmp(map,"hosts.byname") == 0) {
+ strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
+ request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME;
+ } else if (strcasecmp(map,"hosts.byaddr") == 0) {
+ strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
+ request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP;
+ } else {
+ /*
+ * Don't understand this map - just return not found
+ */
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+
+ return(do_request(rq, request));
+}
+
+int list(nsd_file_t *rq)
+{
+ char *map;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n");
+ if (! rq)
+ return NSD_ERROR;
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ if (! map ) {
+ nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n");
+ rq->f_status = NS_BADREQ;
+ return NSD_ERROR;
+ }
+
+ nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map);
+
+ return (do_list(0,rq));
+}
+
+static int
+do_list(int state, nsd_file_t *rq)
+{
+ char *map;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state);
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
+ if (! request) {
+ nsd_logprintf(NSD_LOG_RESOURCE,
+ "do_list (winbind): failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ if (strcasecmp(map,"passwd.byname") == 0) {
+ switch (state) {
+ case 0:
+ rq->f_cmd_data = (void *)WINBINDD_SETPWENT;
+ break;
+ case 1:
+ request->data.num_entries = MAX_GETPWENT_USERS;
+ rq->f_cmd_data = (void *)WINBINDD_GETPWENT;
+ break;
+ case 2:
+ rq->f_cmd_data = (void *)WINBINDD_ENDPWENT;
+ break;
+ default:
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+ } else if (strcasecmp(map,"group.byname") == 0) {
+ switch (state) {
+ case 0:
+ rq->f_cmd_data = (void *)WINBINDD_SETGRENT;
+ break;
+ case 1:
+ request->data.num_entries = MAX_GETGRENT_USERS;
+ rq->f_cmd_data = (void *)WINBINDD_GETGRENT;
+ break;
+ case 2:
+ rq->f_cmd_data = (void *)WINBINDD_ENDGRENT;
+ break;
+ default:
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+ } else {
+ /*
+ * Don't understand this map - just return not found
+ */
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+
+ return(do_request(rq, request));
+}
+
+#else
+
/* Allocate some space from the nss static buffer. The buffer and buflen
are the pointers passed in by the C library to the _nss_ntdom_*
functions. */
-static char *get_static(char **buffer, size_t *buflen, size_t len)
+static char *get_static(char **buffer, int *buflen, int len)
{
char *result;
@@ -62,9 +550,9 @@ static char *get_static(char **buffer, size_t *buflen, size_t len)
lib/util_str.c as I really don't want to have to link in any other
objects if I can possibly avoid it. */
-BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
+BOOL next_token(const char **ptr,char *buff,const char *sep, size_t bufsize)
{
- char *s;
+ const char *s;
BOOL quoted;
size_t len=1;
@@ -189,7 +677,7 @@ static NSS_STATUS fill_pwent(struct passwd *result,
the static data passed to us by libc to put strings and stuff in.
Return NSS_STATUS_TRYAGAIN if we run out of memory. */
-static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr,
+static int fill_grent(struct group *result, struct winbindd_gr *gr,
char *gr_mem, char **buffer, size_t *buflen)
{
fstring name;
@@ -257,7 +745,7 @@ static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr,
i = 0;
- while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
+ while(next_token((const char **)&gr_mem, name, ",", sizeof(fstring))) {
/* Allocate space for member */
@@ -379,7 +867,7 @@ _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
}
ret = fill_pwent(result, &pw_cache[ndx_pw_cache],
- &buffer, &buflen);
+ &buffer, (int *)&buflen);
/* Out of memory - try again */
@@ -429,7 +917,7 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
if (ret == NSS_STATUS_SUCCESS) {
ret = fill_pwent(result, &response.data.pw,
- &buffer, &buflen);
+ &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -442,7 +930,7 @@ _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
/* We've been called again */
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
+ ret = fill_pwent(result, &response.data.pw, &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -491,7 +979,7 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
if (ret == NSS_STATUS_SUCCESS) {
ret = fill_pwent(result, &response.data.pw, &buffer,
- &buflen);
+ (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -504,7 +992,7 @@ _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
/* We've been called again */
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
+ ret = fill_pwent(result, &response.data.pw, &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -565,15 +1053,13 @@ _nss_winbind_endgrent(void)
/* Get next entry from ntdom group database */
-static NSS_STATUS
-winbind_getgrent(enum winbindd_cmd cmd,
- struct group *result,
- char *buffer, size_t buflen, int *errnop)
+NSS_STATUS
+_nss_winbind_getgrent_r(struct group *result,
+ char *buffer, size_t buflen, int *errnop)
{
NSS_STATUS ret;
static struct winbindd_request request;
static int called_again;
-
#ifdef DEBUG_NSS
fprintf(stderr, "[%5d]: getgrent\n", getpid());
@@ -597,7 +1083,7 @@ winbind_getgrent(enum winbindd_cmd cmd,
request.data.num_entries = MAX_GETGRENT_USERS;
- ret = winbindd_request(cmd, &request,
+ ret = winbindd_request(WINBINDD_GETGRENT, &request,
&getgrent_response);
if (ret == NSS_STATUS_SUCCESS) {
@@ -630,7 +1116,7 @@ winbind_getgrent(enum winbindd_cmd cmd,
ret = fill_grent(result, &gr_cache[ndx_gr_cache],
((char *)getgrent_response.extra_data)+mem_ofs,
- &buffer, &buflen);
+ &buffer, (int *)&buflen);
/* Out of memory - try again */
@@ -655,21 +1141,6 @@ winbind_getgrent(enum winbindd_cmd cmd,
return ret;
}
-
-NSS_STATUS
-_nss_winbind_getgrent_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop);
-}
-
-NSS_STATUS
-_nss_winbind_getgrlst_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop);
-}
-
/* Return group struct from group name */
NSS_STATUS
@@ -705,7 +1176,7 @@ _nss_winbind_getgrnam_r(const char *name,
if (ret == NSS_STATUS_SUCCESS) {
ret = fill_grent(result, &response.data.gr,
response.extra_data,
- &buffer, &buflen);
+ &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -719,7 +1190,7 @@ _nss_winbind_getgrnam_r(const char *name,
/* We've been called again */
ret = fill_grent(result, &response.data.gr,
- response.extra_data, &buffer, &buflen);
+ response.extra_data, &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -768,7 +1239,7 @@ _nss_winbind_getgrgid_r(gid_t gid,
ret = fill_grent(result, &response.data.gr,
response.extra_data,
- &buffer, &buflen);
+ &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -782,7 +1253,7 @@ _nss_winbind_getgrgid_r(gid_t gid,
/* We've been called again */
ret = fill_grent(result, &response.data.gr,
- response.extra_data, &buffer, &buflen);
+ response.extra_data, &buffer, (int *)&buflen);
if (ret == NSS_STATUS_TRYAGAIN) {
keep_response = True;
@@ -861,289 +1332,4 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
return ret;
}
-
-/* return a list of group SIDs for a user SID */
-NSS_STATUS
-_nss_winbind_getusersids(const char *user_sid, char **group_sids,
- int *num_groups,
- char *buffer, size_t buf_size, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response);
-
- if (ret != NSS_STATUS_SUCCESS) {
- goto done;
- }
-
- if (buf_size < response.length - sizeof(response)) {
- ret = NSS_STATUS_TRYAGAIN;
- errno = *errnop = ERANGE;
- goto done;
- }
-
- *num_groups = response.data.num_entries;
- *group_sids = buffer;
- memcpy(buffer, response.extra_data, response.length - sizeof(response));
- errno = *errnop = 0;
-
- done:
- free_response(&response);
- return ret;
-}
-
-
-/* map a user or group name to a SID string */
-NSS_STATUS
-_nss_winbind_nametosid(const char *name, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- strncpy(request.data.name.name, name,
- sizeof(request.data.name.name) - 1);
- request.data.name.name[sizeof(request.data.name.name) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- free_response(&response);
- return ret;
-}
-
-/* map a sid string to a user or group name */
-NSS_STATUS
-_nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
- static char sep_char;
- unsigned needed;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);
-#endif
-
- /* we need to fetch the separator first time through */
- if (!sep_char) {
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- ret = winbindd_request(WINBINDD_INFO, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- sep_char = response.data.info.winbind_separator;
- free_response(&response);
- }
-
-
- strncpy(request.data.sid, sid,
- sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_LOOKUPSID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- needed =
- strlen(response.data.name.dom_name) +
- strlen(response.data.name.name) + 2;
-
- if (buflen < needed) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- snprintf(buffer, needed, "%s%c%s",
- response.data.name.dom_name,
- sep_char,
- response.data.name.name);
-
- *name = buffer;
- *errnop = errno = 0;
-
-failed:
- free_response(&response);
- return ret;
-}
-
-/* map a sid to a uid */
-NSS_STATUS
-_nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- *uid = response.data.uid;
-
-failed:
- return ret;
-}
-
-/* map a sid to a gid */
-NSS_STATUS
-_nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- *gid = response.data.gid;
-
-failed:
- return ret;
-}
-
-/* map a uid to a SID string */
-NSS_STATUS
-_nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request(WINBINDD_UID_TO_SID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- free_response(&response);
- return ret;
-}
-
-/* map a gid to a SID string */
-NSS_STATUS
-_nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid);
#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.gid = gid;
-
- ret = winbindd_request(WINBINDD_GID_TO_SID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- free_response(&response);
- return ret;
-}
diff --git a/source/nsswitch/winbind_nss.h b/source/nsswitch/winbind_nss.h
deleted file mode 100644
index 5416ae211e3..00000000000
--- a/source/nsswitch/winbind_nss.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- A common place to work out how to define NSS_STATUS on various
- platforms.
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _NSSWITCH_NSS_H
-#define _NSSWITCH_NSS_H
-
-#ifdef HAVE_NSS_COMMON_H
-
-/*
- * Sun Solaris
- */
-
-#include "nsswitch/winbind_nss_solaris.h"
-
-#elif HAVE_NSS_H
-
-/*
- * Linux (glibc)
- */
-
-#include <nss.h>
-typedef enum nss_status NSS_STATUS;
-
-#elif HAVE_NS_API_H
-
-/*
- * SGI IRIX
- */
-
-#include "nsswitch/winbind_nss_irix.h"
-
-#elif defined(HPUX) && defined(HAVE_NSSWITCH_H)
-
-/* HP-UX 11 */
-
-#include "nsswitch/winbind_nss_hpux.h"
-
-#else /* Nothing's defined. Neither gnu nor sun nor hp */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=0,
- NSS_STATUS_NOTFOUND=1,
- NSS_STATUS_UNAVAIL=2,
- NSS_STATUS_TRYAGAIN=3
-} NSS_STATUS;
-
-#endif
-
-#endif /* _NSSWITCH_NSS_H */
diff --git a/source/nsswitch/winbind_nss_aix.c b/source/nsswitch/winbind_nss_aix.c
deleted file mode 100644
index 3e00e54e5c4..00000000000
--- a/source/nsswitch/winbind_nss_aix.c
+++ /dev/null
@@ -1,1019 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- AIX loadable authentication module, providing identification and
- authentication routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Tim Potter 2003
- Copyright (C) Steve Roylance 2003
- Copyright (C) Andrew Tridgell 2003-2004
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/*
-
- To install this module copy nsswitch/WINBIND to /usr/lib/security and add
- "WINBIND" in /usr/lib/security/methods.cfg and /etc/security/user
-
- Note that this module also provides authentication and password
- changing routines, so you do not need to install the winbind PAM
- module.
-
- see
- http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/kernextc/sec_load_mod.htm
- for some information in the interface that this module implements
-
- Many thanks to Julianne Haugh for explaining some of the finer
- details of this interface.
-
- To debug this module use uess_test.c (which you can get from tridge)
- or set "options=debug" in /usr/lib/security/methods.cfg
-
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <usersec.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#include "winbind_client.h"
-
-#define WB_AIX_ENCODED '_'
-
-static int debug_enabled;
-
-
-static void logit(const char *format, ...)
-{
- va_list ap;
- FILE *f;
- if (!debug_enabled) {
- return;
- }
- f = fopen("/tmp/WINBIND_DEBUG.log", "a");
- if (!f) return;
- va_start(ap, format);
- vfprintf(f, format, ap);
- va_end(ap);
- fclose(f);
-}
-
-
-#define HANDLE_ERRORS(ret) do { \
- if ((ret) == NSS_STATUS_NOTFOUND) { \
- errno = ENOENT; \
- return NULL; \
- } else if ((ret) != NSS_STATUS_SUCCESS) { \
- errno = EIO; \
- return NULL; \
- } \
-} while (0)
-
-#define STRCPY_RET(dest, src) \
-do { \
- if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return -1; } \
- strcpy(dest, src); \
-} while (0)
-
-#define STRCPY_RETNULL(dest, src) \
-do { \
- if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return NULL; } \
- strcpy(dest, src); \
-} while (0)
-
-
-/* free a passwd structure */
-static void free_pwd(struct passwd *pwd)
-{
- free(pwd->pw_name);
- free(pwd->pw_passwd);
- free(pwd->pw_gecos);
- free(pwd->pw_dir);
- free(pwd->pw_shell);
- free(pwd);
-}
-
-/* free a group structure */
-static void free_grp(struct group *grp)
-{
- int i;
-
- free(grp->gr_name);
- free(grp->gr_passwd);
-
- if (!grp->gr_mem) {
- free(grp);
- return;
- }
-
- for (i=0; grp->gr_mem[i]; i++) {
- free(grp->gr_mem[i]);
- }
-
- free(grp->gr_mem);
- free(grp);
-}
-
-
-/* replace commas with nulls, and null terminate */
-static void replace_commas(char *s)
-{
- char *p, *p0=s;
- for (p=strchr(s, ','); p; p = strchr(p+1, ',')) {
- *p=0;
- p0 = p+1;
- }
-
- p0[strlen(p0)+1] = 0;
-}
-
-
-/* the decode_*() routines are used to cope with the fact that AIX 5.2
- and below cannot handle user or group names longer than 8
- characters in some interfaces. We use the normalize method to
- provide a mapping to a username that fits, by using the form '_UID'
- or '_GID'.
-
- this only works if you can guarantee that the WB_AIX_ENCODED char
- is not used as the first char of any other username
-*/
-static unsigned decode_id(const char *name)
-{
- unsigned id;
- sscanf(name+1, "%u", &id);
- return id;
-}
-
-static char *decode_user(const char *name)
-{
- struct passwd *pwd;
- unsigned id;
- char *ret;
- static struct passwd *wb_aix_getpwuid(uid_t uid);
-
- sscanf(name+1, "%u", &id);
- pwd = wb_aix_getpwuid(id);
- if (!pwd) {
- return NULL;
- }
- ret = strdup(pwd->pw_name);
-
- free_pwd(pwd);
-
- logit("decoded '%s' -> '%s'\n", name, ret);
-
- return ret;
-}
-
-
-/*
- fill a struct passwd from a winbindd_pw struct, allocating as a single block
-*/
-static struct passwd *fill_pwent(struct winbindd_pw *pw)
-{
- struct passwd *result;
-
- result = calloc(1, sizeof(struct passwd));
- if (!result) {
- errno = ENOMEM;
- return NULL;
- }
-
- result->pw_uid = pw->pw_uid;
- result->pw_gid = pw->pw_gid;
- result->pw_name = strdup(pw->pw_name);
- result->pw_passwd = strdup(pw->pw_passwd);
- result->pw_gecos = strdup(pw->pw_gecos);
- result->pw_dir = strdup(pw->pw_dir);
- result->pw_shell = strdup(pw->pw_shell);
-
- return result;
-}
-
-
-/*
- fill a struct group from a winbindd_pw struct, allocating as a single block
-*/
-static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
-{
- int i;
- struct group *result;
- char *p, *name;
-
- result = calloc(1, sizeof(struct group));
- if (!result) {
- errno = ENOMEM;
- return NULL;
- }
-
- result->gr_gid = gr->gr_gid;
-
- result->gr_name = strdup(gr->gr_name);
- result->gr_passwd = strdup(gr->gr_passwd);
-
- /* Group membership */
- if ((gr->num_gr_mem < 0) || !gr_mem) {
- gr->num_gr_mem = 0;
- }
-
- if (gr->num_gr_mem == 0) {
- /* Group is empty */
- return result;
- }
-
- result->gr_mem = (char **)malloc(sizeof(char *) * (gr->num_gr_mem+1));
- if (!result->gr_mem) {
- errno = ENOMEM;
- return NULL;
- }
-
- /* Start looking at extra data */
- i=0;
- for (name = strtok_r(gr_mem, ",", &p);
- name;
- name = strtok_r(NULL, ",", &p)) {
- if (i == gr->num_gr_mem) {
- break;
- }
- result->gr_mem[i] = strdup(name);
- i++;
- }
-
- /* Terminate list */
- result->gr_mem[i] = NULL;
-
- return result;
-}
-
-
-
-/* take a group id and return a filled struct group */
-static struct group *wb_aix_getgrgid(gid_t gid)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- struct group *grp;
- NSS_STATUS ret;
-
- logit("getgrgid %d\n", gid);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.gid = gid;
-
- ret = winbindd_request(WINBINDD_GETGRGID, &request, &response);
-
- logit("getgrgid ret=%d\n", ret);
-
- HANDLE_ERRORS(ret);
-
- grp = fill_grent(&response.data.gr, response.extra_data);
-
- free_response(&response);
-
- return grp;
-}
-
-/* take a group name and return a filled struct group */
-static struct group *wb_aix_getgrnam(const char *name)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct group *grp;
-
- if (*name == WB_AIX_ENCODED) {
- return wb_aix_getgrgid(decode_id(name));
- }
-
- logit("getgrnam '%s'\n", name);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- STRCPY_RETNULL(request.data.groupname, name);
-
- ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- grp = fill_grent(&response.data.gr, response.extra_data);
-
- free_response(&response);
-
- return grp;
-}
-
-
-/* this call doesn't have to fill in the gr_mem, but we do anyway
- for simplicity */
-static struct group *wb_aix_getgracct(void *id, int type)
-{
- if (type == 1) {
- return wb_aix_getgrnam((char *)id);
- }
- if (type == 0) {
- return wb_aix_getgrgid(*(int *)id);
- }
- errno = EINVAL;
- return NULL;
-}
-
-
-/* take a username and return a string containing a comma-separated
- list of group id numbers to which the user belongs */
-static char *wb_aix_getgrset(char *user)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- int i, idx;
- char *tmpbuf;
- int num_gids;
- gid_t *gid_list;
- char *r_user = user;
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- errno = ENOENT;
- return NULL;
- }
- }
-
- logit("getgrset '%s'\n", r_user);
-
- STRCPY_RETNULL(request.data.username, r_user);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- num_gids = response.data.num_entries;
- gid_list = (gid_t *)response.extra_data;
-
- /* allocate a space large enough to contruct the string */
- tmpbuf = malloc(num_gids*12);
- if (!tmpbuf) {
- return NULL;
- }
-
- for (idx=i=0; i < num_gids-1; i++) {
- idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
- }
- idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
-
- free_response(&response);
-
- return tmpbuf;
-}
-
-
-/* take a uid and return a filled struct passwd */
-static struct passwd *wb_aix_getpwuid(uid_t uid)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct passwd *pwd;
-
- logit("getpwuid '%d'\n", uid);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- pwd = fill_pwent(&response.data.pw);
-
- free_response(&response);
-
- logit("getpwuid gave ptr %p\n", pwd);
-
- return pwd;
-}
-
-
-/* take a username and return a filled struct passwd */
-static struct passwd *wb_aix_getpwnam(const char *name)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct passwd *pwd;
-
- if (*name == WB_AIX_ENCODED) {
- return wb_aix_getpwuid(decode_id(name));
- }
-
- logit("getpwnam '%s'\n", name);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- STRCPY_RETNULL(request.data.username, name);
-
- ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- pwd = fill_pwent(&response.data.pw);
-
- free_response(&response);
-
- logit("getpwnam gave ptr %p\n", pwd);
-
- return pwd;
-}
-
-/*
- list users
-*/
-static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int len;
- char *s;
-
- if (size != 1 || strcmp(attributes[0], S_USERS) != 0) {
- logit("invalid lsuser op\n");
- errno = EINVAL;
- return -1;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- ret = winbindd_request(WINBINDD_LIST_USERS, &request, &response);
- if (ret != 0) {
- errno = EINVAL;
- return -1;
- }
-
- len = strlen(response.extra_data);
-
- s = malloc(len+2);
- if (!s) {
- free_response(&response);
- errno = ENOMEM;
- return -1;
- }
-
- memcpy(s, response.extra_data, len+1);
-
- replace_commas(s);
-
- results[0].attr_un.au_char = s;
- results[0].attr_flag = 0;
-
- free_response(&response);
-
- return 0;
-}
-
-
-/*
- list groups
-*/
-static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int len;
- char *s;
-
- if (size != 1 || strcmp(attributes[0], S_GROUPS) != 0) {
- logit("invalid lsgroup op\n");
- errno = EINVAL;
- return -1;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- ret = winbindd_request(WINBINDD_LIST_GROUPS, &request, &response);
- if (ret != 0) {
- errno = EINVAL;
- return -1;
- }
-
- len = strlen(response.extra_data);
-
- s = malloc(len+2);
- if (!s) {
- free_response(&response);
- errno = ENOMEM;
- return -1;
- }
-
- memcpy(s, response.extra_data, len+1);
-
- replace_commas(s);
-
- results[0].attr_un.au_char = s;
- results[0].attr_flag = 0;
-
- free_response(&response);
-
- return 0;
-}
-
-
-static attrval_t pwd_to_group(struct passwd *pwd)
-{
- attrval_t r;
- struct group *grp = wb_aix_getgrgid(pwd->pw_gid);
-
- if (!grp) {
- r.attr_flag = EINVAL;
- } else {
- r.attr_flag = 0;
- r.attr_un.au_char = strdup(grp->gr_name);
- free_grp(grp);
- }
-
- return r;
-}
-
-static attrval_t pwd_to_groupsids(struct passwd *pwd)
-{
- attrval_t r;
- char *s, *p;
-
- s = wb_aix_getgrset(pwd->pw_name);
- if (!s) {
- r.attr_flag = EINVAL;
- return r;
- }
-
- p = malloc(strlen(s)+2);
- if (!p) {
- r.attr_flag = ENOMEM;
- return r;
- }
-
- strcpy(p, s);
- replace_commas(p);
- free(s);
-
- r.attr_un.au_char = p;
-
- return r;
-}
-
-static attrval_t pwd_to_sid(struct passwd *pwd)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- attrval_t r;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = pwd->pw_uid;
-
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- r.attr_flag = ENOENT;
- } else {
- r.attr_flag = 0;
- r.attr_un.au_char = strdup(response.data.sid.sid);
- }
-
- return r;
-}
-
-static int wb_aix_user_attrib(const char *key, char *attributes[],
- attrval_t results[], int size)
-{
- struct passwd *pwd;
- int i;
-
- pwd = wb_aix_getpwnam(key);
- if (!pwd) {
- errno = ENOENT;
- return -1;
- }
-
- for (i=0;i<size;i++) {
- results[i].attr_flag = 0;
-
- if (strcmp(attributes[i], S_ID) == 0) {
- results[i].attr_un.au_int = pwd->pw_uid;
- } else if (strcmp(attributes[i], S_PWD) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_passwd);
- } else if (strcmp(attributes[i], S_HOME) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_dir);
- } else if (strcmp(attributes[0], S_SHELL) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_shell);
- } else if (strcmp(attributes[0], S_REGISTRY) == 0) {
- results[i].attr_un.au_char = strdup("WINBIND");
- } else if (strcmp(attributes[0], S_GECOS) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_gecos);
- } else if (strcmp(attributes[0], S_PGRP) == 0) {
- results[i] = pwd_to_group(pwd);
- } else if (strcmp(attributes[0], S_GECOS) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_gecos);
- } else if (strcmp(attributes[0], S_GROUPSIDS) == 0) {
- results[i] = pwd_to_groupsids(pwd);
- } else if (strcmp(attributes[0], "SID") == 0) {
- results[i] = pwd_to_sid(pwd);
- } else {
- logit("Unknown user attribute '%s'\n", attributes[i]);
- results[i].attr_flag = EINVAL;
- }
- }
-
- free_pwd(pwd);
-
- return 0;
-}
-
-static int wb_aix_group_attrib(const char *key, char *attributes[],
- attrval_t results[], int size)
-{
- struct group *grp;
- int i;
-
- grp = wb_aix_getgrnam(key);
- if (!grp) {
- errno = ENOENT;
- return -1;
- }
-
- for (i=0;i<size;i++) {
- results[i].attr_flag = 0;
-
- if (strcmp(attributes[i], S_PWD) == 0) {
- results[i].attr_un.au_char = strdup(grp->gr_passwd);
- } else if (strcmp(attributes[i], S_ID) == 0) {
- results[i].attr_un.au_int = grp->gr_gid;
- } else {
- logit("Unknown group attribute '%s'\n", attributes[i]);
- results[i].attr_flag = EINVAL;
- }
- }
-
- free_grp(grp);
-
- return 0;
-}
-
-
-/*
- called for user/group enumerations
-*/
-static int wb_aix_getentry(char *key, char *table, char *attributes[],
- attrval_t results[], int size)
-{
- logit("Got getentry with key='%s' table='%s' size=%d attributes[0]='%s'\n",
- key, table, size, attributes[0]);
-
- if (strcmp(key, "ALL") == 0 &&
- strcmp(table, "user") == 0) {
- return wb_aix_lsuser(attributes, results, size);
- }
-
- if (strcmp(key, "ALL") == 0 &&
- strcmp(table, "group") == 0) {
- return wb_aix_lsgroup(attributes, results, size);
- }
-
- if (strcmp(table, "user") == 0) {
- return wb_aix_user_attrib(key, attributes, results, size);
- }
-
- if (strcmp(table, "group") == 0) {
- return wb_aix_group_attrib(key, attributes, results, size);
- }
-
- logit("Unknown getentry operation key='%s' table='%s'\n", key, table);
-
- errno = ENOSYS;
- return -1;
-}
-
-
-
-/*
- called to start the backend
-*/
-static void *wb_aix_open(const char *name, const char *domain, int mode, char *options)
-{
- if (strstr(options, "debug")) {
- debug_enabled = 1;
- }
- logit("open name='%s' mode=%d domain='%s' options='%s'\n", name, domain,
- mode, options);
- return NULL;
-}
-
-static void wb_aix_close(void *token)
-{
- logit("close\n");
- return;
-}
-
-/*
- return a list of additional attributes supported by the backend
-*/
-static attrlist_t **wb_aix_attrlist(void)
-{
- attrlist_t **ret;
- logit("method attrlist called\n");
- ret = malloc(2*sizeof(attrlist_t *) + sizeof(attrlist_t));
- if (!ret) {
- errno = ENOMEM;
- return NULL;
- }
-
- ret[0] = (attrlist_t *)(ret+2);
-
- /* just one extra attribute - the windows SID */
- ret[0]->al_name = strdup("SID");
- ret[0]->al_flags = AL_USERATTR;
- ret[0]->al_type = SEC_CHAR;
- ret[1] = NULL;
-
- return ret;
-}
-
-
-/*
- turn a long username into a short one. Needed to cope with the 8 char
- username limit in AIX 5.2 and below
-*/
-static int wb_aix_normalize(char *longname, char *shortname)
-{
- struct passwd *pwd;
-
- logit("normalize '%s'\n", longname);
-
- /* automatically cope with AIX 5.3 with longer usernames
- when it comes out */
- if (S_NAMELEN > strlen(longname)) {
- strcpy(shortname, longname);
- return 1;
- }
-
- pwd = wb_aix_getpwnam(longname);
- if (!pwd) {
- errno = ENOENT;
- return 0;
- }
-
- sprintf(shortname, "%c%07u", WB_AIX_ENCODED, pwd->pw_uid);
-
- free_pwd(pwd);
-
- return 1;
-}
-
-
-/*
- authenticate a user
- */
-static int wb_aix_authenticate(char *user, char *pass,
- int *reenter, char **message)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *r_user = user;
-
- logit("authenticate '%s' response='%s'\n", user, pass);
-
- *reenter = 0;
- *message = NULL;
-
- /* Send off request */
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- return AUTH_NOTFOUND;
- }
- }
-
- STRCPY_RET(request.data.auth.user, r_user);
- STRCPY_RET(request.data.auth.pass, pass);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
-
- free_response(&response);
-
- logit("auth result %d for '%s'\n", result, user);
-
- if (result == NSS_STATUS_SUCCESS) {
- errno = 0;
- return AUTH_SUCCESS;
- }
-
- return AUTH_FAILURE;
-}
-
-
-/*
- change a user password
-*/
-static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **message)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *r_user = user;
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- errno = ENOENT;
- return -1;
- }
- }
-
- logit("chpass '%s' old='%s' new='%s'\n", r_user, oldpass, newpass);
-
- *message = NULL;
-
- /* Send off request */
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- STRCPY_RET(request.data.chauthtok.user, r_user);
- STRCPY_RET(request.data.chauthtok.oldpass, oldpass);
- STRCPY_RET(request.data.chauthtok.newpass, newpass);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- result = winbindd_request(WINBINDD_PAM_CHAUTHTOK, &request, &response);
-
- free_response(&response);
-
- if (result == NSS_STATUS_SUCCESS) {
- errno = 0;
- return 0;
- }
-
- errno = EINVAL;
- return -1;
-}
-
-/*
- don't do any password strength testing for now
-*/
-static int wb_aix_passwdrestrictions(char *user, char *newpass, char *oldpass,
- char **message)
-{
- logit("passwdresrictions called for '%s'\n", user);
- return 0;
-}
-
-
-static int wb_aix_passwdexpired(char *user, char **message)
-{
- logit("passwdexpired '%s'\n", user);
- /* we should check the account bits here */
- return 0;
-}
-
-
-/*
- we can't return a crypt() password
-*/
-static char *wb_aix_getpasswd(char *user)
-{
- logit("getpasswd '%s'\n", user);
- errno = ENOSYS;
- return NULL;
-}
-
-/*
- this is called to update things like the last login time. We don't
- currently pass this onto the DC
-*/
-static int wb_aix_putentry(char *key, char *table, char *attributes[],
- attrval_t values[], int size)
-{
- logit("putentry key='%s' table='%s' attrib='%s'\n",
- key, table, size>=1?attributes[0]:"<null>");
- errno = ENOSYS;
- return -1;
-}
-
-static int wb_aix_commit(char *key, char *table)
-{
- logit("commit key='%s' table='%s'\n");
- errno = ENOSYS;
- return -1;
-}
-
-static int wb_aix_getgrusers(char *group, void *result, int type, int *size)
-{
- logit("getgrusers group='%s'\n", group);
- errno = ENOSYS;
- return -1;
-}
-
-
-#define DECL_METHOD(x) \
-int method_ ## x(void) \
-{ \
- logit("UNIMPLEMENTED METHOD '%s'\n", #x); \
- errno = EINVAL; \
- return -1; \
-}
-
-#if LOG_UNIMPLEMENTED_CALLS
-DECL_METHOD(delgroup);
-DECL_METHOD(deluser);
-DECL_METHOD(newgroup);
-DECL_METHOD(newuser);
-DECL_METHOD(putgrent);
-DECL_METHOD(putgrusers);
-DECL_METHOD(putpwent);
-DECL_METHOD(lock);
-DECL_METHOD(unlock);
-DECL_METHOD(getcred);
-DECL_METHOD(setcred);
-DECL_METHOD(deletecred);
-#endif
-
-int wb_aix_init(struct secmethod_table *methods)
-{
- ZERO_STRUCTP(methods);
-
- methods->method_version = SECMETHOD_VERSION_520;
-
- methods->method_getgrgid = wb_aix_getgrgid;
- methods->method_getgrnam = wb_aix_getgrnam;
- methods->method_getgrset = wb_aix_getgrset;
- methods->method_getpwnam = wb_aix_getpwnam;
- methods->method_getpwuid = wb_aix_getpwuid;
- methods->method_getentry = wb_aix_getentry;
- methods->method_open = wb_aix_open;
- methods->method_close = wb_aix_close;
- methods->method_normalize = wb_aix_normalize;
- methods->method_passwdexpired = wb_aix_passwdexpired;
- methods->method_putentry = wb_aix_putentry;
- methods->method_getpasswd = wb_aix_getpasswd;
- methods->method_authenticate = wb_aix_authenticate;
- methods->method_commit = wb_aix_commit;
- methods->method_chpass = wb_aix_chpass;
- methods->method_passwdrestrictions = wb_aix_passwdrestrictions;
- methods->method_getgracct = wb_aix_getgracct;
- methods->method_getgrusers = wb_aix_getgrusers;
- methods->method_attrlist = wb_aix_attrlist;
-
-#if LOG_UNIMPLEMENTED_CALLS
- methods->method_delgroup = method_delgroup;
- methods->method_deluser = method_deluser;
- methods->method_newgroup = method_newgroup;
- methods->method_newuser = method_newuser;
- methods->method_putgrent = method_putgrent;
- methods->method_putgrusers = method_putgrusers;
- methods->method_putpwent = method_putpwent;
- methods->method_lock = method_lock;
- methods->method_unlock = method_unlock;
- methods->method_getcred = method_getcred;
- methods->method_setcred = method_setcred;
- methods->method_deletecred = method_deletecred;
-#endif
-
- return AUTH_SUCCESS;
-}
-
diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h
index 77d1dbe26e0..eac80994fc3 100644
--- a/source/nsswitch/winbind_nss_config.h
+++ b/source/nsswitch/winbind_nss_config.h
@@ -26,9 +26,7 @@
/* Include header files from data in config.h file */
-#ifndef NO_CONFIG_H
#include <config.h>
-#endif
#include <stdio.h>
@@ -64,19 +62,34 @@
#include <string.h>
#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#else
-#ifdef HAVE_SYS_FCNTL_H
-#include <sys/fcntl.h>
-#endif
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
-#include "nsswitch/winbind_nss.h"
+#include "nsswitch/sys_nss.h"
+
+/* Declarations for functions in winbind_nss.c
+ needed in winbind_nss_solaris.c (solaris wrapper to nss) */
+
+NSS_STATUS _nss_winbind_setpwent(void);
+NSS_STATUS _nss_winbind_endpwent(void);
+NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
+ char* buffer, size_t buflen, int* errnop);
+
+NSS_STATUS _nss_winbind_setgrent(void);
+NSS_STATUS _nss_winbind_endgrent(void);
+NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
+ size_t buflen, int* errnop);
+NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
+NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop);
/* I'm trying really hard not to include anything from smb.h with the
result of some silly looking redeclaration of structures. */
diff --git a/source/nsswitch/winbind_nss_freebsd.c b/source/nsswitch/winbind_nss_freebsd.c
deleted file mode 100644
index b73a4ce44f8..00000000000
--- a/source/nsswitch/winbind_nss_freebsd.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- AIX loadable authentication module, providing identification
- routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Aaron Collins 2003
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include "winbind_client.h"
-
-/* Make sure that the module gets registered needed by freebsd 5.1 */
-
-extern enum nss_status _nss_winbind_getgrent_r(struct group *, char *, size_t,
- int *);
-extern enum nss_status _nss_winbind_getgrnam_r(const char *, struct group *,
- char *, size_t, int *);
-extern enum nss_status _nss_winbind_getgrgid_r(gid_t gid, struct group *, char *,
- size_t, int *);
-extern enum nss_status _nss_winbind_setgrent(void);
-extern enum nss_status _nss_winbind_endgrent(void);
-
-extern enum nss_status _nss_winbind_getpwent_r(struct passwd *, char *, size_t,
- int *);
-extern enum nss_status _nss_winbind_getpwnam_r(const char *, struct passwd *,
- char *, size_t, int *);
-extern enum nss_status _nss_winbind_getpwuid_r(gid_t gid, struct passwd *, char *,
- size_t, int *);
-extern enum nss_status _nss_winbind_setpwent(void);
-extern enum nss_status _nss_winbind_endpwent(void);
-
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
-NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
-
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_setpwent);
-NSS_METHOD_PROTOTYPE(__nss_compat_endpwent);
-
-static ns_mtab methods[] = {
-{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r },
-{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_winbind_getgrgid_r },
-{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r },
-{ NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_winbind_setgrent },
-{ NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_winbind_endgrent },
-
-{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r },
-{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r },
-{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_winbind_getpwent_r },
-{ NSDB_PASSWD, "endpwent", __nss_compat_setpwent, _nss_winbind_setpwent },
-{ NSDB_PASSWD, "setpwent", __nss_compat_endpwent, _nss_winbind_endpwent },
-
-};
-
-ns_mtab *
-nss_module_register(const char *source, unsigned int *mtabsize,
- nss_module_unregister_fn *unreg)
-{
- *mtabsize = sizeof(methods)/sizeof(methods[0]);
- *unreg = NULL;
- return (methods);
-}
diff --git a/source/nsswitch/winbind_nss_irix.c b/source/nsswitch/winbind_nss_irix.c
deleted file mode 100644
index 3a9d6c01ab5..00000000000
--- a/source/nsswitch/winbind_nss_irix.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Windows NT Domain nsswitch module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#include "winbind_client.h"
-
-#ifdef HAVE_NS_API_H
-#undef VOLATILE
-#include <ns_daemon.h>
-#endif
-
-/* Maximum number of users to pass back over the unix domain socket
- per call. This is not a static limit on the total number of users
- or groups returned in total. */
-
-#define MAX_GETPWENT_USERS 250
-#define MAX_GETGRENT_USERS 250
-
-/* Prototypes from wb_common.c */
-
-extern int winbindd_fd;
-
-#ifdef HAVE_NS_API_H
-
-/* IRIX version */
-
-static int send_next_request(nsd_file_t *, struct winbindd_request *);
-static int do_list(int state, nsd_file_t *rq);
-
-static nsd_file_t *current_rq = NULL;
-static int current_winbind_xid = 0;
-static int next_winbind_xid = 0;
-
-typedef struct winbind_xid {
- int xid;
- nsd_file_t *rq;
- struct winbindd_request *request;
- struct winbind_xid *next;
-} winbind_xid_t;
-
-static winbind_xid_t *winbind_xids = (winbind_xid_t *)0;
-
-static int
-winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request)
-{
- winbind_xid_t *new;
-
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n",
- xid, rq, request);
- new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t));
- if (!new) {
- nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n");
- return NSD_ERROR;
- }
-
- new->xid = xid;
- new->rq = rq;
- new->request = request;
- new->next = winbind_xids;
- winbind_xids = new;
-
- return NSD_CONTINUE;
-}
-
-/*
-** This routine will look down the xid list and return the request
-** associated with an xid. We remove the record if it is found.
-*/
-nsd_file_t *
-winbind_xid_lookup(int xid, struct winbindd_request **requestp)
-{
- winbind_xid_t **last, *dx;
- nsd_file_t *result=0;
-
- for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid);
- last = &dx->next, dx = dx->next);
- if (dx) {
- *last = dx->next;
- result = dx->rq;
- *requestp = dx->request;
- SAFE_FREE(dx);
- }
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n",
- xid, result, dx->request);
-
- return result;
-}
-
-static int
-winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n");
- rq = to->t_file;
- *rqp = rq;
- nsd_timeout_remove(rq);
- request = to->t_clientdata;
- return(send_next_request(rq, request));
-}
-
-static void
-dequeue_request()
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- /*
- * Check for queued requests
- */
- if (winbind_xids) {
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n",
- current_winbind_xid);
- rq = winbind_xid_lookup(current_winbind_xid++, &request);
- /* cause a timeout on the queued request so we can send it */
- nsd_timeout_new(rq,1,winbind_startnext_timeout,request);
- }
-}
-
-static int
-do_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- if (winbind_xids == NULL) {
- /*
- * No outstanding requests.
- * Send off the request to winbindd
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n");
- return(send_next_request(rq, request));
- } else {
- /*
- * Just queue it up for now - previous callout or timout
- * will start it up
- */
- nsd_logprintf(NSD_LOG_MIN,
- "lookup (winbind): queue request xid = %d\n",
- next_winbind_xid);
- return(winbind_xid_new(next_winbind_xid++, rq, request));
- }
-}
-
-static int
-winbind_callback(nsd_file_t **rqp, int fd)
-{
- struct winbindd_response response;
- struct winbindd_pw *pw = &response.data.pw;
- struct winbindd_gr *gr = &response.data.gr;
- nsd_file_t *rq;
- NSS_STATUS status;
- fstring result;
- char *members;
- int i, maxlen;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n");
-
- rq = current_rq;
- *rqp = rq;
-
- nsd_timeout_remove(rq);
- nsd_callback_remove(fd);
-
- ZERO_STRUCT(response);
- status = winbindd_get_response(&response);
-
- if (status != NSS_STATUS_SUCCESS) {
- /* free any extra data area in response structure */
- free_response(&response);
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) returning not found, status = %d\n",
- status);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- maxlen = sizeof(result) - 1;
-
- switch ((int)rq->f_cmd_data) {
- case WINBINDD_WINS_BYNAME:
- case WINBINDD_WINS_BYIP:
- snprintf(result,maxlen,"%s\n",response.data.winsresp);
- break;
- case WINBINDD_GETPWUID:
- case WINBINDD_GETPWNAM:
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- break;
- case WINBINDD_GETGRNAM:
- case WINBINDD_GETGRGID:
- if (gr->num_gr_mem && response.extra_data)
- members = response.extra_data;
- else
- members = "";
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
- break;
- case WINBINDD_SETGRENT:
- case WINBINDD_SETPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n");
- free_response(&response);
- return(do_list(1,rq));
- case WINBINDD_GETGRENT:
- case WINBINDD_GETGRLST:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETGRENT responses\n",
- response.data.num_entries);
- if (response.data.num_entries) {
- gr = (struct winbindd_gr *)response.extra_data;
- if (! gr ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- free_response(&response);
- return NSD_ERROR;
- }
- members = (char *)response.extra_data +
- (response.data.num_entries * sizeof(struct winbindd_gr));
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid,
- &members[gr->gr_mem_ofs]);
- nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
- gr++;
- }
- }
- i = response.data.num_entries;
- free_response(&response);
- if (i < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- case WINBINDD_GETPWENT:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) - %d GETPWENT responses\n",
- response.data.num_entries);
- if (response.data.num_entries) {
- pw = (struct winbindd_pw *)response.extra_data;
- if (! pw ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- free_response(&response);
- return NSD_ERROR;
- }
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result);
- nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
- pw++;
- }
- }
- i = response.data.num_entries;
- free_response(&response);
- if (i < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- case WINBINDD_ENDGRENT:
- case WINBINDD_ENDPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n");
- nsd_append_element(rq,NS_SUCCESS,"\n",1);
- free_response(&response);
- return NSD_NEXT;
- default:
- free_response(&response);
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n");
- return NSD_NEXT;
- }
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result);
- /* free any extra data area in response structure */
- free_response(&response);
- nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE);
- return NSD_OK;
-}
-
-static int
-winbind_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n");
-
- rq = to->t_file;
- *rqp = rq;
-
- /* Remove the callback and timeout */
- nsd_callback_remove(winbindd_fd);
- nsd_timeout_remove(rq);
-
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
-}
-
-static int
-send_next_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- NSS_STATUS status;
- long timeout;
-
- timeout = 1000;
-
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n",
- rq->f_cmd_data, timeout);
- status = winbindd_send_request((int)rq->f_cmd_data,request);
- SAFE_FREE(request);
-
- if (status != NSS_STATUS_SUCCESS) {
- nsd_logprintf(NSD_LOG_MIN,
- "send_next_request (winbind) error status = %d\n",status);
- rq->f_status = status;
- return NSD_NEXT;
- }
-
- current_rq = rq;
-
- /*
- * Set up callback and timeouts
- */
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd);
- nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ);
- nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0);
- return NSD_CONTINUE;
-}
-
-int init(void)
-{
- nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n");
- return(NSD_OK);
-}
-
-int lookup(nsd_file_t *rq)
-{
- char *map;
- char *key;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
- if (! map || ! key) {
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map);
-
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "lookup (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byuid") == 0) {
- request->data.uid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETPWUID;
- } else if (strcasecmp(map,"passwd.byname") == 0) {
- strncpy(request->data.username, key,
- sizeof(request->data.username) - 1);
- request->data.username[sizeof(request->data.username) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETPWNAM;
- } else if (strcasecmp(map,"group.byname") == 0) {
- strncpy(request->data.groupname, key,
- sizeof(request->data.groupname) - 1);
- request->data.groupname[sizeof(request->data.groupname) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETGRNAM;
- } else if (strcasecmp(map,"group.bygid") == 0) {
- request->data.gid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETGRGID;
- } else if (strcasecmp(map,"hosts.byname") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME;
- } else if (strcasecmp(map,"hosts.byaddr") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP;
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-int list(nsd_file_t *rq)
-{
- char *map;
-
- nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- if (! map ) {
- nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map);
-
- return (do_list(0,rq));
-}
-
-static int
-do_list(int state, nsd_file_t *rq)
-{
- char *map;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state);
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "do_list (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETPWENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETPWENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETPWENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDPWENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else if (strcasecmp(map,"group.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETGRENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETGRENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETGRENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDGRENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-#endif /* HAVE_NS_API_H */
diff --git a/source/nsswitch/winbind_nss_linux.h b/source/nsswitch/winbind_nss_linux.h
deleted file mode 100644
index 1c7e8300373..00000000000
--- a/source/nsswitch/winbind_nss_linux.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _WINBIND_NSS_LINUX_H
-#define _WINBIND_NSS_LINUX_H
-
-#if HAVE_NSS_H
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#endif /* HAVE_NSS_H */
-
-#endif /* _WINBIND_NSS_LINUX_H */
diff --git a/source/nsswitch/winbind_nss_solaris.c b/source/nsswitch/winbind_nss_solaris.c
index 8d307cad5ac..767f1471df0 100644
--- a/source/nsswitch/winbind_nss_solaris.c
+++ b/source/nsswitch/winbind_nss_solaris.c
@@ -31,13 +31,15 @@
#include <string.h>
#include <pwd.h>
#include "includes.h"
+#ifdef HAVE_SYSLOG_H
#include <syslog.h>
-#if !defined(HPUX)
+#endif
+#ifdef HAVE_SYS_SYSLOG_H
#include <sys/syslog.h>
-#endif /*hpux*/
+#endif
#include "winbind_nss_config.h"
-#if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
+#if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
#undef NSS_DEBUG
@@ -256,27 +258,8 @@ _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
static NSS_STATUS
_nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
{
- int errnop;
- struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
-
NSS_DEBUG("_nss_winbind_getgroupsbymember");
-
- _nss_winbind_initgroups_dyn(gmem->username,
- gmem->gid_array[0], /* Primary Group */
- &gmem->numgids,
- &gmem->maxgids,
- &gmem->gid_array,
- gmem->maxgids,
- &errnop);
-
- /*
- * If the maximum number of gids have been found, return
- * SUCCESS so the switch engine will stop searching. Otherwise
- * return NOTFOUND so nsswitch will continue to get groups
- * from the remaining database backends specified in the
- * nsswitch.conf file.
- */
- return (gmem->numgids == gmem->maxgids ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
+ return NSS_STATUS_NOTFOUND;
}
static NSS_STATUS
@@ -316,3 +299,5 @@ _nss_winbind_group_constr (const char* db_name,
}
#endif /* SUN_NSS */
+
+
diff --git a/source/nsswitch/winbind_nss_solaris.h b/source/nsswitch/winbind_nss_solaris.h
deleted file mode 100644
index 567de411aa6..00000000000
--- a/source/nsswitch/winbind_nss_solaris.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-#ifndef _WINBIND_NSS_SOLARIS_H
-#define _WINBIND_NSS_SOLARIS_H
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-/* The solaris winbind is implemented as a wrapper around the linux
- version. */
-
-NSS_STATUS _nss_winbind_setpwent(void);
-NSS_STATUS _nss_winbind_endpwent(void);
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
- char* buffer, size_t buflen, int* errnop);
-
-NSS_STATUS _nss_winbind_setgrent(void);
-NSS_STATUS _nss_winbind_endgrent(void);
-NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-
-#endif /* _WINBIND_NSS_SOLARIS_H */
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 283b2e4a89c..ac43e0e43ed 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -3,9 +3,7 @@
Winbind daemon for ntdom nss module
- Copyright (C) by Tim Potter 2000-2002
- Copyright (C) Andrew Tridgell 2002
- Copyright (C) Jelmer Vernooij 2003
+ Copyright (C) by Tim Potter 2000, 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,37 +20,56 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-BOOL opt_nocache = False;
-BOOL opt_dual_daemon = True;
+/* List of all connected clients */
+
+struct winbindd_cli_state *client_list;
+static int num_clients;
+BOOL opt_nocache;
+
+pstring servicesf = CONFIGFILE;
/* Reload configuration */
-static BOOL reload_services_file(void)
+static BOOL reload_services_file(BOOL test)
{
BOOL ret;
+ pstring logfile;
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
}
}
- reopen_logs();
- ret = lp_load(dyn_CONFIGFILE,False,False,True);
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
+ lp_set_logfile(logfile);
+
+ if (!reopen_logs()) {
+ fprintf(stderr, "Could not open logfile: %s\n", logfile);
+ fprintf(stderr, "Continuing in the hope that that is OK\n");
+ }
+
+ ret = lp_load(servicesf,False,False,True);
+
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
+ lp_set_logfile(logfile);
+
+ if (!reopen_logs()) {
+ fprintf(stderr, "Could not open logfile: %s\n", logfile);
+ fprintf(stderr, "Continuing in the hope that that is OK\n");
+ }
- reopen_logs();
load_interfaces();
return(ret);
}
-
#if DUMP_CORE
/**************************************************************************** **
@@ -112,13 +129,13 @@ static void winbindd_status(void)
/* Print client state information */
- DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
+ DEBUG(0, ("\t%d clients currently active\n", num_clients));
- if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
+ if (DEBUGLEVEL >= 2 && num_clients) {
DEBUG(2, ("\tclient list:\n"));
- for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
- DEBUG(2, ("\t\tpid %lu, sock %d, rbl %d, wbl %d\n",
- (unsigned long)tmp->pid, tmp->sock, tmp->read_buf_len,
+ for(tmp = client_list; tmp; tmp = tmp->next) {
+ DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
+ tmp->pid, tmp->sock, tmp->read_buf_len,
tmp->write_buf_len));
}
}
@@ -129,6 +146,7 @@ static void winbindd_status(void)
static void print_winbindd_status(void)
{
winbindd_status();
+ winbindd_idmap_status();
winbindd_cm_status();
}
@@ -136,17 +154,8 @@ static void print_winbindd_status(void)
static void flush_caches(void)
{
-#if 0
/* Clear cached user and group enumation info */
- if (!opt_dual_daemon) /* Until we have coherent cache flush. */
- wcache_flush_cache();
-#endif
-
- /* We need to invalidate cached user list entries on a SIGHUP
- otherwise cached access denied errors due to restrict anonymous
- hang around until the sequence number changes. */
-
- wcache_invalidate_cache();
+ wcache_flush_cache();
}
/* Handle the signal by unlinking socket and exiting */
@@ -155,10 +164,10 @@ static void terminate(void)
{
pstring path;
- idmap_close();
+ winbindd_idmap_close();
/* Remove socket file */
- pstr_sprintf(path, "%s/%s",
+ snprintf(path, sizeof(path), "%s/%s",
WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
unlink(path);
exit(0);
@@ -188,18 +197,12 @@ static void sighup_handler(int signum)
sys_select_signal();
}
-/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
-static void msg_reload_services(int msg_type, pid_t src, void *buf, size_t len)
-{
- /* Flush various caches */
- flush_caches();
- reload_services_file();
-}
+/* Create winbindd socket */
-/* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
-static void msg_shutdown(int msg_type, pid_t src, void *buf, size_t len)
+static int create_sock(void)
{
- terminate();
+ return create_pipe_sock( WINBINDD_SOCKET_DIR,
+ WINBINDD_SOCKET_NAME, 0755);
}
struct dispatch_table {
@@ -220,7 +223,6 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" },
{ WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" },
- { WINBINDD_GETUSERSIDS, winbindd_getusersids, "GETUSERSIDS" },
/* Group functions */
@@ -229,12 +231,13 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
{ WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
{ WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
- { WINBINDD_GETGRLST, winbindd_getgrent, "GETGRLST" },
/* PAM auth functions */
{ WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },
+#ifdef WITH_WINBIND_AUTH_CRAP
{ WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
+#endif
{ WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
/* Enumeration functions */
@@ -255,7 +258,6 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
{ WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
{ WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
- { WINBINDD_ALLOCATE_RID, winbindd_allocate_rid, "ALLOCATE_RID" },
/* Miscellaneous */
@@ -264,24 +266,12 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_INFO, winbindd_info, "INFO" },
{ WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" },
{ WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
- { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
- { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
- { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir, "WINBINDD_PRIV_PIPE_DIR" },
/* WINS functions */
{ WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
{ WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
-
- /* UNIX account management functions */
- { WINBINDD_CREATE_USER, winbindd_create_user, "CREATE_USER" },
- { WINBINDD_CREATE_GROUP, winbindd_create_group, "CREATE_GROUP" },
- { WINBINDD_ADD_USER_TO_GROUP, winbindd_add_user_to_group, "ADD_USER_TO_GROUP" },
- { WINBINDD_REMOVE_USER_FROM_GROUP, winbindd_remove_user_from_group,"REMOVE_USER_FROM_GROUP"},
- { WINBINDD_SET_USER_PRIMARY_GROUP, winbindd_set_user_primary_group,"SET_USER_PRIMARY_GROUP"},
- { WINBINDD_DELETE_USER, winbindd_delete_user, "DELETE_USER" },
- { WINBINDD_DELETE_GROUP, winbindd_delete_group, "DELETE_GROUP" },
-
+
/* End of list */
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
@@ -307,6 +297,9 @@ static void process_request(struct winbindd_cli_state *state)
if (state->request.cmd == table->cmd) {
DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name ));
state->response.result = table->fn(state);
+ if (state->response.nt_status)
+ DEBUG(10, ("returning extended error 0x%08x\n",
+ state->response.nt_status));
break;
}
}
@@ -322,7 +315,7 @@ static void process_request(struct winbindd_cli_state *state)
/* Process a new connection by adding it to the client connection list */
-static void new_connection(int listen_sock, BOOL privileged)
+static void new_connection(int accept_sock)
{
struct sockaddr_un sunaddr;
struct winbindd_cli_state *state;
@@ -334,7 +327,7 @@ static void new_connection(int listen_sock, BOOL privileged)
len = sizeof(sunaddr);
do {
- sock = accept(listen_sock, (struct sockaddr *)&sunaddr, &len);
+ sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len);
} while (sock == -1 && errno == EINTR);
if (sock == -1)
@@ -353,11 +346,10 @@ static void new_connection(int listen_sock, BOOL privileged)
state->last_access = time(NULL);
- state->privileged = privileged;
-
/* Add to connection list */
- winbindd_add_client(state);
+ DLIST_ADD(client_list, state);
+ num_clients++;
}
/* Remove a client connection from client connection list */
@@ -384,12 +376,12 @@ static void remove_client(struct winbindd_cli_state *state)
/* Remove from list and free */
- winbindd_remove_client(state);
+ DLIST_REMOVE(client_list, state);
SAFE_FREE(state);
+ num_clients--;
}
}
-
/* Shutdown client connection which has been idle for the longest time */
static BOOL remove_idle_client(void)
@@ -398,7 +390,7 @@ static BOOL remove_idle_client(void)
time_t last_access = 0;
int nidle = 0;
- for (state = winbindd_client_list(); state; state = state->next) {
+ for (state = client_list; state; state = state->next) {
if (state->read_buf_len == 0 && state->write_buf_len == 0 &&
!state->getpwent_state && !state->getgrent_state) {
nidle++;
@@ -421,13 +413,10 @@ static BOOL remove_idle_client(void)
/* Process a complete received packet from a client */
-void winbind_process_packet(struct winbindd_cli_state *state)
+static void process_packet(struct winbindd_cli_state *state)
{
/* Process request */
- /* Ensure null termination of entire request */
- state->request.null_term = '\0';
-
state->pid = state->request.pid;
process_request(state);
@@ -436,38 +425,36 @@ void winbind_process_packet(struct winbindd_cli_state *state)
state->read_buf_len = 0;
state->write_buf_len = sizeof(struct winbindd_response);
-
- /* we might need to send it to the dual daemon */
- if (opt_dual_daemon) {
- dual_send_request(state);
- }
}
/* Read some data from a client connection */
-void winbind_client_read(struct winbindd_cli_state *state)
+static void client_read(struct winbindd_cli_state *state)
{
int n;
/* Read data */
- n = sys_read(state->sock, state->read_buf_len +
- (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
-
- DEBUG(10,("client_read: read %d bytes. Need %ld more for a full request.\n", n, (unsigned long)(sizeof(state->request) - n - state->read_buf_len) ));
+ do {
+
+ n = read(state->sock, state->read_buf_len +
+ (char *)&state->request,
+ sizeof(state->request) - state->read_buf_len);
- /* Read failed, kill client */
+ } while (n == -1 && errno == EINTR);
if (n == -1 || n == 0) {
- DEBUG(5,("read failed on sock %d, pid %lu: %s\n",
- state->sock, (unsigned long)state->pid,
+ /* Read failed, kill client */
+ DEBUG(5,("read failed on sock %d, pid %d: %s\n",
+ state->sock, state->pid,
(n == -1) ? strerror(errno) : "EOF"));
state->finished = True;
return;
}
+ DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n, sizeof(state->request) - n - state->read_buf_len ));
+
/* Update client state */
state->read_buf_len += n;
@@ -482,13 +469,6 @@ static void client_write(struct winbindd_cli_state *state)
int num_written;
/* Write some data */
- /*
- * The fancy calculation of data below allows us to handle the
- * case where write (sys_write) does not write all the data we
- * gave it. In that case, we will come back through here again
- * because of the loop above us, and we want to pick up where
- * we left off.
- */
if (!state->write_extra_data) {
@@ -507,7 +487,9 @@ static void client_write(struct winbindd_cli_state *state)
state->write_buf_len;
}
- num_written = sys_write(state->sock, data, state->write_buf_len);
+ do {
+ num_written = write(state->sock, data, state->write_buf_len);
+ } while (num_written == -1 && errno == EINTR);
DEBUG(10,("client_write: wrote %d bytes.\n", num_written ));
@@ -515,8 +497,8 @@ static void client_write(struct winbindd_cli_state *state)
if (num_written == -1 || num_written == 0) {
- DEBUG(3,("write failed on sock %d, pid %lu: %s\n",
- state->sock, (unsigned long)state->pid,
+ DEBUG(3,("write failed on sock %d, pid %d: %s\n",
+ state->sock, state->pid,
(num_written == -1) ? strerror(errno) : "EOF"));
state->finished = True;
@@ -561,29 +543,25 @@ static void client_write(struct winbindd_cli_state *state)
}
}
-/* Process incoming clients on listen_sock. We use a tricky non-blocking,
+/* Process incoming clients on accept_sock. We use a tricky non-blocking,
non-forking, non-threaded model which allows us to handle many
simultaneous connections while remaining impervious to many denial of
service attacks. */
-static void process_loop(void)
+static void process_loop(int accept_sock)
{
/* We'll be doing this a lot */
while (1) {
struct winbindd_cli_state *state;
fd_set r_fds, w_fds;
- int maxfd, listen_sock, listen_priv_sock, selret;
+ int maxfd = accept_sock, selret;
struct timeval timeout;
/* Handle messages */
message_dispatch();
- /* refresh the trusted domain cache */
-
- rescan_trusted_domains();
-
/* Free up temporary memory */
lp_talloc_free();
@@ -591,31 +569,16 @@ static void process_loop(void)
/* Initialise fd lists for select() */
- listen_sock = open_winbindd_socket();
- listen_priv_sock = open_winbindd_priv_socket();
-
- if (listen_sock == -1 || listen_priv_sock == -1) {
- perror("open_winbind_socket");
- exit(1);
- }
-
- maxfd = MAX(listen_sock, listen_priv_sock);
-
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
- FD_SET(listen_sock, &r_fds);
- FD_SET(listen_priv_sock, &r_fds);
+ FD_SET(accept_sock, &r_fds);
timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
timeout.tv_usec = 0;
- if (opt_dual_daemon) {
- maxfd = dual_select_setup(&w_fds, maxfd);
- }
-
/* Set up client readers and writers */
- state = winbindd_client_list();
+ state = client_list;
while (state) {
@@ -663,46 +626,26 @@ static void process_loop(void)
exit(1);
}
- /* Create a new connection if listen_sock readable */
+ /* Create a new connection if accept_sock readable */
if (selret > 0) {
- if (opt_dual_daemon) {
- dual_select(&w_fds);
- }
-
- if (FD_ISSET(listen_sock, &r_fds)) {
- while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
+ if (FD_ISSET(accept_sock, &r_fds)) {
+ while (num_clients > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
if (!remove_idle_client()) {
DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
+ WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
break;
}
}
- /* new, non-privileged connection */
- new_connection(listen_sock, False);
- }
-
- if (FD_ISSET(listen_priv_sock, &r_fds)) {
- while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
- DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
- if (!remove_idle_client()) {
- DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
- break;
- }
- }
- /* new, privileged connection */
- new_connection(listen_priv_sock, True);
- }
-
+ new_connection(accept_sock);
+ }
+
/* Process activity on client connections */
- for (state = winbindd_client_list(); state;
- state = state->next) {
+ for (state = client_list; state; state = state->next) {
/* Data available for reading */
@@ -710,7 +653,7 @@ static void process_loop(void)
/* Read data */
- winbind_client_read(state);
+ client_read(state);
/*
* If we have the start of a
@@ -722,9 +665,8 @@ static void process_loop(void)
if (state->read_buf_len >= sizeof(uint32)
&& *(uint32 *) &state->request != sizeof(state->request)) {
- DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n",
- (unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request)));
- DEBUGADD(0, ("This usually means that you are running old wbinfo, pam_winbind or libnss_winbind clients\n"));
+ DEBUG(0,("process_loop: Invalid request size (%d) sent, should be (%d)\n",
+ *(uint32 *) &state->request, sizeof(state->request)));
remove_client(state);
break;
@@ -735,7 +677,7 @@ static void process_loop(void)
if (state->read_buf_len ==
sizeof(state->request)) {
- winbind_process_packet(state);
+ process_packet(state);
}
}
@@ -757,9 +699,15 @@ static void process_loop(void)
if (do_sighup) {
- DEBUG(3, ("got SIGHUP\n"));
+ /* Flush winbindd cache */
+
+ flush_caches();
+ reload_services_file(True);
+#if 0 /* Notised at present. */
+ namecache_flush();
+#endif
+ winbindd_cm_flush();
- msg_reload_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, NULL, 0);
do_sighup = False;
}
@@ -774,23 +722,27 @@ static void process_loop(void)
struct winbindd_state server_state; /* Server state information */
+
+static void usage(void)
+{
+ printf("Usage: winbindd [options]\n");
+ printf("Version: %s\n", VERSION);
+ printf("\t-i interactive mode\n");
+ printf("\t-n disable cacheing\n");
+ printf("\t-d level set debug level\n");
+ printf("\t-s configfile choose smb.conf location\n");
+ printf("\t-h show this help message\n");
+}
+
int main(int argc, char **argv)
{
+ extern BOOL AllowDebugChange;
+ extern pstring global_myname;
+ extern fstring global_myworkgroup;
+ extern BOOL append_log;
pstring logfile;
- static BOOL interactive = False;
- static BOOL Fork = True;
- static BOOL log_stdout = False;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" },
- { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
- { "single-daemon", 'Y', POPT_ARG_VAL, &opt_dual_daemon, False, "Single daemon mode" },
- { "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
- poptContext pc;
+ int accept_sock;
+ BOOL interactive = False;
int opt;
/* glibc (?) likes to print "User defined signal 1" and exit if a
@@ -799,85 +751,136 @@ int main(int argc, char **argv)
CatchSignal(SIGUSR1, SIG_IGN);
CatchSignal(SIGUSR2, SIG_IGN);
+ TimeInit();
+
+ charset_initialise(); /* For *&#^%'s sake don't remove this */
+
fault_setup((void (*)(void *))fault_quit );
/* Initialise for running in non-root mode */
sec_init();
- set_remote_machine_name("winbindd", False);
-
/* Set environment variable so we don't recursively call ourselves.
This may also be useful interactively. */
- setenv(WINBINDD_DONT_ENV, "1", 1);
+ SETENV(WINBINDD_DONT_ENV, "1", 1);
/* Initialise samba/rpc client stuff */
- pc = poptGetContext("winbindd", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
+ while ((opt = getopt(argc, argv, "id:s:nh")) != EOF) {
switch (opt) {
+
/* Don't become a daemon */
case 'i':
interactive = True;
- log_stdout = True;
- Fork = False;
break;
+
+ /* disable cacheing */
+ case 'n':
+ opt_nocache = True;
+ break;
+
+ /* Run with specified debug level */
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ AllowDebugChange = False;
+ break;
+
+ /* Load a different smb.conf file */
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+
+ case 'h':
+ usage();
+ exit(0);
+
+ default:
+ printf("Unknown option %c\n", (char)opt);
+ exit(1);
}
}
+ /* Append to log file by default as we are a single process daemon
+ program. */
- if (log_stdout && Fork) {
- printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n");
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
+ append_log = True;
- pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE);
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
lp_set_logfile(logfile);
- setup_logging("winbindd", log_stdout);
- reopen_logs();
- DEBUG(1, ("winbindd version %s started.\n", SAMBA_VERSION_STRING) );
- DEBUGADD( 1, ( "Copyright The Samba Team 2000-2004\n" ) );
+ setup_logging("winbindd", interactive);
+ if (!reopen_logs()) {
+ fprintf(stderr, "Could not open logfile: %s\n", logfile);
+ fprintf(stderr, "Continuing in the hope that that is OK\n");
+ }
+
+ DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
+ DEBUGADD( 1, ( "Copyright The Samba Team 2000-2003\n" ) );
- if (!reload_services_file()) {
+ if (!reload_services_file(False)) {
DEBUG(0, ("error opening config file\n"));
exit(1);
}
+ codepage_initialise(lp_client_code_page());
+
/* Setup names. */
- if (!init_names())
- exit(1);
+ if (!*global_myname) {
+ char *p;
+
+ fstrcpy(global_myname, myhostname());
+ p = strchr(global_myname, '.');
+ if (p)
+ *p = 0;
+ }
+
+ fstrcpy(global_myworkgroup, lp_workgroup());
+
+ if (!interactive) {
+ become_daemon();
+ pidfile_create("winbindd");
+ }
- load_interfaces();
+
+#if HAVE_SETPGID
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (interactive)
+ setpgid( (pid_t)0, (pid_t)0);
+#endif
+
+ load_interfaces();
if (!secrets_init()) {
DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
- return False;
+ return 1;
+
}
- /* Enable netbios namecache */
+#if 0 /* Notised at present. */
+ namecache_enable(); /* Enable netbios namecache */
+#endif
- namecache_enable();
+ /* Get list of domains we look up requests for. This includes the
+ domain which we are a member of as well as any trusted
+ domains. */
- /* Check winbindd parameters are valid */
+ init_domain_list();
ZERO_STRUCT(server_state);
- if (!winbindd_param_init())
- return 1;
-
/* Winbind daemon initialisation */
- if (!winbindd_upgrade_idmap())
+ if (!winbindd_param_init())
return 1;
- if (!idmap_init(lp_idmap_backend()))
+ if (!winbindd_idmap_init())
return 1;
/* Unblock all signals we are interested in as they may have been
@@ -901,47 +904,27 @@ int main(int argc, char **argv)
CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
CatchSignal(SIGHUP, sighup_handler);
- if (!interactive)
- become_daemon(Fork);
-
- pidfile_create("winbindd");
-
-#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (interactive)
- setpgid( (pid_t)0, (pid_t)0);
-#endif
-
- if (opt_dual_daemon) {
- do_dual_daemon();
- }
-
/* Initialise messaging system */
if (!message_init()) {
DEBUG(0, ("unable to initialise messaging system\n"));
exit(1);
}
-
- /* React on 'smbcontrol winbindd reload-config' in the same way
- as to SIGHUP signal */
- message_register(MSG_SMB_CONF_UPDATED, msg_reload_services);
- message_register(MSG_SHUTDOWN, msg_shutdown);
-
- poptFreeContext(pc);
- netsamlogon_cache_init(); /* Non-critical */
+ /* Create UNIX domain socket */
- init_domain_list();
+ if ((accept_sock = create_sock()) == -1) {
+ DEBUG(0, ("failed to create socket\n"));
+ return 1;
+ }
/* Loop waiting for requests */
- process_loop();
+ process_loop(accept_sock);
- trustdom_cache_shutdown();
+#if 0
+ uni_group_cache_shutdown();
+#endif
return 0;
}
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index cec73ea805e..4a09cfb244e 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -4,7 +4,6 @@
Winbind daemon for ntdom nss module
Copyright (C) Tim Potter 2000
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -25,13 +24,11 @@
#ifndef _WINBINDD_H
#define _WINBINDD_H
+#include "includes.h"
#include "nterr.h"
#include "winbindd_nss.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
/* Client state structure */
struct winbindd_cli_state {
@@ -42,12 +39,8 @@ struct winbindd_cli_state {
BOOL finished; /* Can delete from list */
BOOL write_extra_data; /* Write extra_data field */
time_t last_access; /* Time of last access (read or write) */
- BOOL privileged; /* Is the client 'privileged' */
-
struct winbindd_request request; /* Request from client */
struct winbindd_response response; /* Respose to client */
- BOOL getpwent_initialized; /* Has getpwent_state been initialized? */
- BOOL getgrent_initialized; /* Has getgrent_state been initialized? */
struct getent_state *getpwent_state; /* State for getpwent() */
struct getent_state *getgrent_state; /* State for getgrent() */
};
@@ -67,8 +60,7 @@ struct getent_state {
struct getpwent_user {
fstring name; /* Account name */
fstring gecos; /* User information */
- DOM_SID user_sid; /* NT user and primary group SIDs */
- DOM_SID group_sid;
+ uint32 user_rid, group_rid; /* NT user and group rids */
};
/* Server state structure */
@@ -86,27 +78,20 @@ extern struct winbindd_state server_state; /* Server information */
typedef struct {
char *acct_name;
char *full_name;
- DOM_SID *user_sid; /* NT user and primary group SIDs */
- DOM_SID *group_sid;
+ uint32 user_rid;
+ uint32 group_rid; /* primary group */
} WINBIND_USERINFO;
/* Structures to hold per domain information */
struct winbindd_domain {
fstring name; /* Domain name */
- fstring alt_name; /* alt Domain name (if any) */
+ fstring full_name; /* full Domain name (realm) */
DOM_SID sid; /* SID for this domain */
- BOOL native_mode; /* is this a win2k domain in native mode ? */
- BOOL active_directory; /* is this a win2k active directory ? */
- BOOL primary; /* is this our primary domain ? */
- BOOL internal; /* BUILTIN and member SAM */
/* Lookup methods for this domain (LDAP or RPC) */
- struct winbindd_methods *methods;
- /* the backend methods are used by the cache layer to find the right
- backend */
- struct winbindd_methods *backend;
+ struct winbindd_methods *methods;
/* Private data for the backends (used for connection cache) */
@@ -136,21 +121,14 @@ struct winbindd_methods {
uint32 *num_entries,
WINBIND_USERINFO **info);
- /* get a list of domain groups */
+ /* get a list of groups */
NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_entries,
struct acct_info **info);
- /* get a list of domain local groups */
- NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info);
-
/* convert one user or group name to a sid */
NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type);
@@ -158,14 +136,14 @@ struct winbindd_methods {
/* convert a sid to a user or group name */
NTSTATUS (*sid_to_name)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ DOM_SID *sid,
char **name,
enum SID_NAME_USE *type);
- /* lookup user info for a given SID */
+ /* lookup user info for a given rid */
NTSTATUS (*query_user)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
+ uint32 user_rid,
WINBIND_USERINFO *user_info);
/* lookup all groups that a user is a member of. The backend
@@ -173,15 +151,14 @@ struct winbindd_methods {
function */
NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids);
+ uint32 user_rid,
+ uint32 *num_groups, uint32 **user_gids);
/* find all members of the group with the specified group_rid */
NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid,
- uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
+ uint32 group_rid, uint32 *num_names,
+ uint32 **rid_mem, char ***names,
uint32 **name_types);
/* return the current global sequence number */
@@ -192,15 +169,11 @@ struct winbindd_methods {
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
- char ***alt_names,
DOM_SID **dom_sids);
/* find the domain sid */
NTSTATUS (*domain_sid)(struct winbindd_domain *domain,
DOM_SID *sid);
-
- /* setup the list of alternate names for the domain, if any */
- NTSTATUS (*alternate_name)(struct winbindd_domain *domain);
};
/* Used to glue a policy handle and cli_state together */
@@ -210,31 +183,26 @@ typedef struct {
POLICY_HND pol;
} CLI_POLICY_HND;
-/* Filled out by IDMAP backends */
-struct winbindd_idmap_methods {
- /* Called when backend is first loaded */
- BOOL (*init)(void);
-
- BOOL (*get_sid_from_uid)(uid_t uid, DOM_SID *sid);
- BOOL (*get_sid_from_gid)(gid_t gid, DOM_SID *sid);
-
- BOOL (*get_uid_from_sid)(DOM_SID *sid, uid_t *uid);
- BOOL (*get_gid_from_sid)(DOM_SID *sid, gid_t *gid);
-
- /* Called when backend is unloaded */
- BOOL (*close)(void);
- /* Called to dump backend status */
- void (*status)(void);
-};
-
-#include "../nsswitch/winbindd_proto.h"
+#include "winbindd_proto.h"
#include "rpc_parse.h"
#include "rpc_client.h"
#define WINBINDD_ESTABLISH_LOOP 30
-#define WINBINDD_RESCAN_FREQ 300
-
#define DOM_SEQUENCE_NONE ((uint32)-1)
+/* SETENV */
+#if HAVE_SETENV
+#define SETENV(name, value, overwrite) setenv(name,value,overwrite)
+#elif HAVE_PUTENV
+#define SETENV(name, value, overwrite) \
+{ \
+ fstring envvar; \
+ slprintf(envvar, sizeof(fstring), "%s=%s", name, value); \
+ putenv(envvar); \
+}
+#else
+#define SETENV(name, value, overwrite) ;
+#endif
+
#endif /* _WINBINDD_H */
diff --git a/source/nsswitch/winbindd_acct.c b/source/nsswitch/winbindd_acct.c
deleted file mode 100644
index e6496695cb6..00000000000
--- a/source/nsswitch/winbindd_acct.c
+++ /dev/null
@@ -1,1223 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind account management functions
-
- Copyright (C) by Gerald (Jerry) Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-#define WBKEY_PASSWD "WBA_PASSWD"
-#define WBKEY_GROUP "WBA_GROUP"
-
-#define NUM_PW_FIELDS 7
-#define NUM_GRP_FIELDS 4
-
-/* Globals */
-
-static TDB_CONTEXT *account_tdb;
-
-extern userdom_struct current_user_info;
-
-struct _check_primary_grp {
- gid_t gid;
- BOOL found;
-};
-
-/**********************************************************************
-**********************************************************************/
-
-static void free_winbindd_gr( WINBINDD_GR *grp )
-{
- int i;
-
- if ( !grp )
- return;
-
- for ( i=0; i<grp->num_gr_mem; i++ )
- SAFE_FREE( grp->gr_mem[i] );
-
- SAFE_FREE( grp->gr_mem );
-
- return;
-}
-
-/*****************************************************************************
- Initialise auto-account database.
-*****************************************************************************/
-
-static BOOL winbindd_accountdb_init(void)
-{
- /* see if we've already opened the tdb */
-
- if ( account_tdb )
- return True;
-
- /* winbindd_idmap.tdb should always be opened by the idmap_init()
- code first */
-
- if ( !(account_tdb = idmap_tdb_handle()) ) {
- DEBUG(0, ("winbindd_accountdb_init: Unable to retreive handle for database\n"));
- return False;
- }
-
- /* yeah! */
-
- return True;
-}
-
-/**********************************************************************
- Convert a string in /etc/passwd format to a struct passwd* entry
-**********************************************************************/
-
-static WINBINDD_PW* string2passwd( char *string )
-{
- static WINBINDD_PW pw;
- char *p, *str;
- char *fields[NUM_PW_FIELDS];
- int i;
-
- if ( !string )
- return NULL;
-
- ZERO_STRUCTP( &pw );
-
- DEBUG(10,("string2passwd: converting \"%s\"\n", string));
-
- ZERO_STRUCT( fields );
-
- for ( i=0, str=string; i<NUM_PW_FIELDS-1; i++ ) {
- if ( !(p = strchr( str, ':' )) ) {
- DEBUG(0,("string2passwd: parsing failure\n"));
- return NULL;
- }
- *p = '\0';
- if ( str )
- fields[i] = str;
- str = p + 1;
- }
- if ( str )
- fields[i] = str;
-
- /* copy fields */
-
- fstrcpy( pw.pw_name, fields[0] );
- fstrcpy( pw.pw_passwd, fields[1] );
- pw.pw_uid = atoi( fields[2] );
- pw.pw_gid = atoi( fields[3] );
- fstrcpy( pw.pw_gecos, fields[4] );
- fstrcpy( pw.pw_dir, fields[5] );
- fstrcpy( pw.pw_shell, fields[6] );
-
-
- /* last minute sanity checks */
-
- if ( pw.pw_uid==0 || pw.pw_gid==0 ) {
- DEBUG(0,("string2passwd: Failure! uid==%lu, gid==%lu\n",
- (unsigned long)pw.pw_uid, (unsigned long)pw.pw_gid));
- return NULL;
- }
-
- DEBUG(10,("string2passwd: Success\n"));
-
- return &pw;
-}
-
-/**********************************************************************
- Convert a struct passwd* to a string formatted for /etc/passwd
-**********************************************************************/
-
-static char* passwd2string( const WINBINDD_PW *pw )
-{
- static pstring string;
- int ret;
-
- if ( !pw || !pw->pw_name )
- return NULL;
-
- DEBUG(10,("passwd2string: converting passwd struct for %s\n",
- pw->pw_name));
-
- ret = pstr_sprintf( string, "%s:%s:%lu:%lu:%s:%s:%s",
- pw->pw_name,
- pw->pw_passwd ? pw->pw_passwd : "x",
- (unsigned long)pw->pw_uid,
- (unsigned long)pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell );
-
- if ( ret < 0 ) {
- DEBUG(0,("passwd2string: pstr_sprintf() failed!\n"));
- return NULL;
- }
-
- return string;
-}
-
-/**********************************************************************
- Convert a string in /etc/group format to a struct group* entry
-**********************************************************************/
-
-static WINBINDD_GR* string2group( char *string )
-{
- static WINBINDD_GR grp;
- char *p, *str;
- char *fields[NUM_GRP_FIELDS];
- int i;
- char **gr_members = NULL;
- int num_gr_members = 0;
-
- if ( !string )
- return NULL;
-
- ZERO_STRUCTP( &grp );
-
- DEBUG(10,("string2group: converting \"%s\"\n", string));
-
- ZERO_STRUCT( fields );
-
- for ( i=0, str=string; i<NUM_GRP_FIELDS-1; i++ ) {
- if ( !(p = strchr( str, ':' )) ) {
- DEBUG(0,("string2group: parsing failure\n"));
- return NULL;
- }
- *p = '\0';
- if ( str )
- fields[i] = str;
- str = p + 1;
- }
-
- /* group members */
-
- if ( *str ) {
- /* we already know we have a non-empty string */
-
- num_gr_members = count_chars(str, ',') + 1;
-
- /* if there was at least one comma, then there
- are n+1 members */
- if ( num_gr_members ) {
- fstring buffer;
-
- gr_members = (char**)smb_xmalloc(sizeof(char*)*(num_gr_members+1));
-
- i = 0;
- while ( next_token(&str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
- gr_members[i++] = smb_xstrdup(buffer);
- }
-
- gr_members[i] = NULL;
- }
- }
-
-
- /* copy fields */
-
- fstrcpy( grp.gr_name, fields[0] );
- fstrcpy( grp.gr_passwd, fields[1] );
- grp.gr_gid = atoi( fields[2] );
-
- grp.num_gr_mem = num_gr_members;
- grp.gr_mem = gr_members;
-
- /* last minute sanity checks */
-
- if ( grp.gr_gid == 0 ) {
- DEBUG(0,("string2group: Failure! gid==%lu\n", (unsigned long)grp.gr_gid));
- SAFE_FREE( gr_members );
- return NULL;
- }
-
- DEBUG(10,("string2group: Success\n"));
-
- return &grp;
-}
-
-/**********************************************************************
- Convert a struct group* to a string formatted for /etc/group
-**********************************************************************/
-
-static char* group2string( const WINBINDD_GR *grp )
-{
- static pstring string;
- int ret;
- char *member, *gr_mem_str;
- int num_members;
- int i, size;
-
- if ( !grp || !grp->gr_name )
- return NULL;
-
- DEBUG(10,("group2string: converting passwd struct for %s\n",
- grp->gr_name));
-
- if ( grp->num_gr_mem ) {
- int idx = 0;
-
- member = grp->gr_mem[0];
- size = 0;
- num_members = 0;
-
- while ( member ) {
- size += strlen(member) + 1;
- num_members++;
- member = grp->gr_mem[num_members];
- }
-
- gr_mem_str = smb_xmalloc(size);
-
- for ( i=0; i<num_members; i++ ) {
- snprintf( &gr_mem_str[idx], size-idx, "%s,", grp->gr_mem[i] );
- idx += strlen(grp->gr_mem[i]) + 1;
- }
- /* add trailing NULL (also removes trailing ',' */
- gr_mem_str[size-1] = '\0';
- }
- else {
- /* no members */
- gr_mem_str = smb_xmalloc(sizeof(fstring));
- fstrcpy( gr_mem_str, "" );
- }
-
- ret = pstr_sprintf( string, "%s:%s:%lu:%s",
- grp->gr_name,
- grp->gr_passwd ? grp->gr_passwd : "*",
- (unsigned long)grp->gr_gid,
- gr_mem_str );
-
- SAFE_FREE( gr_mem_str );
-
- if ( ret < 0 ) {
- DEBUG(0,("group2string: pstr_sprintf() failed!\n"));
- return NULL;
- }
-
- return string;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static char* acct_userkey_byname( const char *name )
-{
- static fstring key;
-
- fstr_sprintf( key, "%s/NAME/%s", WBKEY_PASSWD, name );
-
- return key;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static char* acct_userkey_byuid( uid_t uid )
-{
- static fstring key;
-
- fstr_sprintf( key, "%s/UID/%lu", WBKEY_PASSWD, (unsigned long)uid );
-
- return key;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static char* acct_groupkey_byname( const char *name )
-{
- static fstring key;
-
- fstr_sprintf( key, "%s/NAME/%s", WBKEY_GROUP, name );
-
- return key;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static char* acct_groupkey_bygid( gid_t gid )
-{
- static fstring key;
-
- fstr_sprintf( key, "%s/GID/%lu", WBKEY_GROUP, (unsigned long)gid );
-
- return key;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WINBINDD_PW* wb_getpwnam( const char * name )
-{
- char *keystr;
- TDB_DATA data;
- static WINBINDD_PW *pw;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_getpwnam: Failed to open winbindd account db\n"));
- return NULL;
- }
-
-
- keystr = acct_userkey_byname( name );
-
- data = tdb_fetch_bystring( account_tdb, keystr );
-
- pw = NULL;
-
- if ( data.dptr ) {
- pw = string2passwd( data.dptr );
- SAFE_FREE( data.dptr );
- }
-
- DEBUG(5,("wb_getpwnam: %s user (%s)\n",
- (pw ? "Found" : "Did not find"), name ));
-
- return pw;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WINBINDD_PW* wb_getpwuid( const uid_t uid )
-{
- char *keystr;
- TDB_DATA data;
- static WINBINDD_PW *pw;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_getpwuid: Failed to open winbindd account db\n"));
- return NULL;
- }
-
- data = tdb_fetch_bystring( account_tdb, acct_userkey_byuid(uid) );
- if ( !data.dptr ) {
- DEBUG(4,("wb_getpwuid: failed to locate uid == %lu\n", (unsigned long)uid));
- return NULL;
- }
- keystr = acct_userkey_byname( data.dptr );
-
- SAFE_FREE( data.dptr );
-
- data = tdb_fetch_bystring( account_tdb, keystr );
-
- pw = NULL;
-
- if ( data.dptr ) {
- pw = string2passwd( data.dptr );
- SAFE_FREE( data.dptr );
- }
-
- DEBUG(5,("wb_getpwuid: %s user (uid == %lu)\n",
- (pw ? "Found" : "Did not find"), (unsigned long)uid ));
-
- return pw;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_storepwnam( const WINBINDD_PW *pw )
-{
- char *namekey, *uidkey;
- TDB_DATA data;
- char *str;
- int ret = 0;
- fstring username;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_storepwnam: Failed to open winbindd account db\n"));
- return False;
- }
-
- namekey = acct_userkey_byname( pw->pw_name );
-
- /* lock the main entry first */
-
- if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
- DEBUG(0,("wb_storepwnam: Failed to lock %s\n", namekey));
- return False;
- }
-
- str = passwd2string( pw );
-
- data.dptr = str;
- data.dsize = strlen(str) + 1;
-
- if ( (tdb_store_bystring(account_tdb, namekey, data, TDB_REPLACE)) == -1 ) {
- DEBUG(0,("wb_storepwnam: Failed to store \"%s\"\n", str));
- ret = -1;
- goto done;
- }
-
- /* store the uid index */
-
- uidkey = acct_userkey_byuid(pw->pw_uid);
-
- fstrcpy( username, pw->pw_name );
- data.dptr = username;
- data.dsize = strlen(username) + 1;
-
- if ( (tdb_store_bystring(account_tdb, uidkey, data, TDB_REPLACE)) == -1 ) {
- DEBUG(0,("wb_storepwnam: Failed to store uid key \"%s\"\n", str));
- tdb_delete_bystring(account_tdb, namekey);
- ret = -1;
- goto done;
- }
-
- DEBUG(10,("wb_storepwnam: Success -> \"%s\"\n", str));
-
-done:
- tdb_unlock_bystring( account_tdb, namekey );
-
- return ( ret == 0 );
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WINBINDD_GR* wb_getgrnam( const char * name )
-{
- char *keystr;
- TDB_DATA data;
- static WINBINDD_GR *grp;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_getgrnam: Failed to open winbindd account db\n"));
- return NULL;
- }
-
-
- keystr = acct_groupkey_byname( name );
-
- data = tdb_fetch_bystring( account_tdb, keystr );
-
- grp = NULL;
-
- if ( data.dptr ) {
- grp = string2group( data.dptr );
- SAFE_FREE( data.dptr );
- }
-
- DEBUG(5,("wb_getgrnam: %s group (%s)\n",
- (grp ? "Found" : "Did not find"), name ));
-
- return grp;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WINBINDD_GR* wb_getgrgid( gid_t gid )
-{
- char *keystr;
- TDB_DATA data;
- static WINBINDD_GR *grp;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_getgrgid: Failed to open winbindd account db\n"));
- return NULL;
- }
-
- data = tdb_fetch_bystring( account_tdb, acct_groupkey_bygid(gid) );
- if ( !data.dptr ) {
- DEBUG(4,("wb_getgrgid: failed to locate gid == %lu\n",
- (unsigned long)gid));
- return NULL;
- }
- keystr = acct_groupkey_byname( data.dptr );
-
- SAFE_FREE( data.dptr );
-
- data = tdb_fetch_bystring( account_tdb, keystr );
-
- grp = NULL;
-
- if ( data.dptr ) {
- grp = string2group( data.dptr );
- SAFE_FREE( data.dptr );
- }
-
- DEBUG(5,("wb_getgrgid: %s group (gid == %lu)\n",
- (grp ? "Found" : "Did not find"), (unsigned long)gid ));
-
- return grp;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_storegrnam( const WINBINDD_GR *grp )
-{
- char *namekey, *gidkey;
- TDB_DATA data;
- char *str;
- int ret = 0;
- fstring groupname;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_storepwnam: Failed to open winbindd account db\n"));
- return False;
- }
-
- namekey = acct_groupkey_byname( grp->gr_name );
-
- /* lock the main entry first */
-
- if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
- DEBUG(0,("wb_storegrnam: Failed to lock %s\n", namekey));
- return False;
- }
-
- str = group2string( grp );
-
- data.dptr = str;
- data.dsize = strlen(str) + 1;
-
- if ( (tdb_store_bystring(account_tdb, namekey, data, TDB_REPLACE)) == -1 ) {
- DEBUG(0,("wb_storegrnam: Failed to store \"%s\"\n", str));
- ret = -1;
- goto done;
- }
-
- /* store the gid index */
-
- gidkey = acct_groupkey_bygid(grp->gr_gid);
-
- fstrcpy( groupname, grp->gr_name );
- data.dptr = groupname;
- data.dsize = strlen(groupname) + 1;
-
- if ( (tdb_store_bystring(account_tdb, gidkey, data, TDB_REPLACE)) == -1 ) {
- DEBUG(0,("wb_storegrnam: Failed to store gid key \"%s\"\n", str));
- tdb_delete_bystring(account_tdb, namekey);
- ret = -1;
- goto done;
- }
-
- DEBUG(10,("wb_storegrnam: Success -> \"%s\"\n", str));
-
-done:
- tdb_unlock_bystring( account_tdb, namekey );
-
- return ( ret == 0 );
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_addgrpmember( WINBINDD_GR *grp, const char *user )
-{
- int i;
- char **members;
-
- if ( !grp || !user )
- return False;
-
- for ( i=0; i<grp->num_gr_mem; i++ ) {
- if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 )
- return True;
- }
-
- /* add one new slot and keep an extra for the terminating NULL */
- members = Realloc( grp->gr_mem, (grp->num_gr_mem+2)*sizeof(char*) );
- if ( !members )
- return False;
-
- grp->gr_mem = members;
- grp->gr_mem[grp->num_gr_mem++] = smb_xstrdup(user);
- grp->gr_mem[grp->num_gr_mem] = NULL;
-
- return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_delgrpmember( WINBINDD_GR *grp, const char *user )
-{
- int i;
- BOOL found = False;
-
- if ( !grp || !user )
- return False;
-
- for ( i=0; i<grp->num_gr_mem; i++ ) {
- if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 ) {
- found = True;
- break;
- }
- }
-
- if ( !found )
- return False;
-
- /* still some remaining members */
-
- if ( grp->num_gr_mem > 1 ) {
- SAFE_FREE(grp->gr_mem[i]);
- grp->num_gr_mem--;
- grp->gr_mem[i] = grp->gr_mem[grp->num_gr_mem];
- grp->gr_mem[grp->num_gr_mem] = NULL;
- }
- else { /* last one */
- free_winbindd_gr( grp );
- grp->gr_mem = NULL;
- grp->num_gr_mem = 0;
- }
-
- return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static int cleangroups_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- int len;
- fstring key;
- char *name = (char*)state;
-
- fstr_sprintf( key, "%s/NAME", WBKEY_GROUP );
- len = strlen(key);
-
- /* if this is a group entry then, check the members */
-
- if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
- WINBINDD_GR *grp;
-
- if ( !(grp = string2group( dbuf.dptr )) ) {
- DEBUG(0,("cleangroups_traverse_fn: Failure to parse [%s]\n",
- dbuf.dptr));
- return 0;
- }
-
- /* just try to delete the user and rely on wb_delgrpmember()
- to tell you whether or not the group changed. This is more
- effecient than testing group membership first since the
- checks for deleting a user from a group is essentially the
- same as checking if he/she is a member */
-
- if ( wb_delgrpmember( grp, name ) ) {
- DEBUG(10,("cleanupgroups_traverse_fn: Removed user (%s) from group (%s)\n",
- name, grp->gr_name));
- wb_storegrnam( grp );
- }
-
- free_winbindd_gr( grp );
- }
-
- return 0;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_delete_user( WINBINDD_PW *pw)
-{
- char *namekey;
- char *uidkey;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_delete_user: Failed to open winbindd account db\n"));
- return False;
- }
-
- namekey = acct_userkey_byname( pw->pw_name );
-
- /* lock the main entry first */
-
- if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
- DEBUG(0,("wb_delete_user: Failed to lock %s\n", namekey));
- return False;
- }
-
- /* remove user from all groups */
-
- tdb_traverse(account_tdb, cleangroups_traverse_fn, (void *)pw->pw_name);
-
- /* remove the user */
- uidkey = acct_userkey_byuid( pw->pw_uid );
-
- tdb_delete_bystring( account_tdb, namekey );
- tdb_delete_bystring( account_tdb, uidkey );
-
- tdb_unlock_bystring( account_tdb, namekey );
-
- return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static int isprimarygroup_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
- TDB_DATA dbuf, void *params)
-{
- int len;
- fstring key;
- struct _check_primary_grp *check = (struct _check_primary_grp*)params;
-
- fstr_sprintf( key, "%s/NAME", WBKEY_PASSWD );
- len = strlen(key);
-
- /* if this is a group entry then, check the members */
-
- if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
- WINBINDD_PW *pw;;
-
- if ( !(pw = string2passwd( dbuf.dptr )) ) {
- DEBUG(0,("isprimarygroup_traverse_fn: Failure to parse [%s]\n",
- dbuf.dptr));
- return 0;
- }
-
- if ( check->gid == pw->pw_gid ) {
- check->found = True;
- return 1;
- }
- }
-
- return 0;
-}
-
-
-/**********************************************************************
-**********************************************************************/
-
-static BOOL wb_delete_group( WINBINDD_GR *grp )
-{
- struct _check_primary_grp check;
- char *namekey;
- char *gidkey;
-
- if ( !account_tdb && !winbindd_accountdb_init() ) {
- DEBUG(0,("wb_delete_group: Failed to open winbindd account db\n"));
- return False;
- }
-
- /* lock the main entry first */
-
- namekey = acct_groupkey_byname( grp->gr_name );
- if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
- DEBUG(0,("wb_delete_group: Failed to lock %s\n", namekey));
- return False;
- }
-
- /* is this group the primary group for any user? If
- so deny delete */
-
- check.found = False;
- tdb_traverse(account_tdb, isprimarygroup_traverse_fn, (void *)&check);
-
- if ( check.found ) {
- DEBUG(4,("wb_delete_group: Cannot delete group (%s) since it "
- "is the primary group for some users\n", grp->gr_name));
- return False;
- }
-
- /* We're clear. Delete the group */
-
- DEBUG(5,("wb_delete_group: Removing group (%s)\n", grp->gr_name));
-
- gidkey = acct_groupkey_bygid( grp->gr_gid );
-
- tdb_delete_bystring( account_tdb, namekey );
- tdb_delete_bystring( account_tdb, gidkey );
-
- tdb_unlock_bystring( account_tdb, namekey );
-
- return True;
-}
-
-/**********************************************************************
- Create a new "UNIX" user for the system given a username
-**********************************************************************/
-
-enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state)
-{
- char *user, *group;
- unid_t id;
- WINBINDD_PW pw, *pw_check;
- WINBINDD_GR *wb_grp;
- struct group *unix_grp;
- gid_t primary_gid;
- uint32 flags = state->request.flags;
- uint32 rid;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_create_user: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
- state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
-
- user = state->request.data.acct_mgt.username;
- group = state->request.data.acct_mgt.groupname;
-
- DEBUG(3, ("[%5lu]: create_user: user=>(%s), group=>(%s)\n",
- (unsigned long)state->pid, user, group));
-
- if ( (pw_check=wb_getpwnam(user)) != NULL ) {
- DEBUG(0,("winbindd_create_user: Refusing to create user that already exists (%s)\n",
- user));
- return WINBINDD_ERROR;
- }
-
-
- if ( !*group )
- group = lp_template_primary_group();
-
- /* validate the primary group
- 1) lookup in local tdb first
- 2) call getgrnam() as a last resort */
-
- if ( (wb_grp=wb_getgrnam(group)) != NULL ) {
- primary_gid = wb_grp->gr_gid;
- free_winbindd_gr( wb_grp );
- }
- else if ( (unix_grp=sys_getgrnam(group)) != NULL ) {
- primary_gid = unix_grp->gr_gid;
- }
- else {
- DEBUG(2,("winbindd_create_user: Cannot validate gid for group (%s)\n", group));
- return WINBINDD_ERROR;
- }
-
- /* get a new uid */
-
- if ( !NT_STATUS_IS_OK(idmap_allocate_id( &id, ID_USERID)) ) {
- DEBUG(0,("winbindd_create_user: idmap_allocate_id() failed!\n"));
- return WINBINDD_ERROR;
- }
-
- /* The substitution of %U and %D in the 'template homedir' is done
- by lp_string() calling standard_sub_basic(). */
-
- fstrcpy( current_user_info.smb_name, user );
- sub_set_smb_name( user );
- fstrcpy( current_user_info.domain, get_global_sam_name() );
-
- /* fill in the passwd struct */
-
- fstrcpy( pw.pw_name, user );
- fstrcpy( pw.pw_passwd, "x" );
- fstrcpy( pw.pw_gecos, user);
- fstrcpy( pw.pw_dir, lp_template_homedir() );
- fstrcpy( pw.pw_shell, lp_template_shell() );
-
- pw.pw_uid = id.uid;
- pw.pw_gid = primary_gid;
-
- /* store the new entry */
-
- if ( !wb_storepwnam(&pw) )
- return WINBINDD_ERROR;
-
- /* do we need a new RID? */
-
- if ( flags & WBFLAG_ALLOCATE_RID ) {
- if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, USER_RID_TYPE)) ) {
- DEBUG(0,("winbindd_create_user: RID allocation failure! Cannot create user (%s)\n",
- user));
- wb_delete_user( &pw );
-
- return WINBINDD_ERROR;
- }
-
- state->response.data.rid = rid;
- }
-
- return WINBINDD_OK;
-}
-
-/**********************************************************************
- Create a new "UNIX" group for the system given a username
-**********************************************************************/
-
-enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state)
-{
- char *group;
- unid_t id;
- WINBINDD_GR grp, *grp_check;
- uint32 flags = state->request.flags;
- uint32 rid;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_create_group: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
- group = state->request.data.acct_mgt.groupname;
-
- DEBUG(3, ("[%5lu]: create_group: (%s)\n", (unsigned long)state->pid, group));
-
- if ( (grp_check=wb_getgrnam(group)) != NULL ) {
- DEBUG(0,("winbindd_create_group: Refusing to create group that already exists (%s)\n",
- group));
- return WINBINDD_ERROR;
- }
-
- /* get a new gid */
-
- if ( !NT_STATUS_IS_OK(idmap_allocate_id( &id, ID_GROUPID)) ) {
- DEBUG(0,("winbindd_create_group: idmap_allocate_id() failed!\n"));
- return WINBINDD_ERROR;
- }
-
- /* fill in the group struct */
-
- fstrcpy( grp.gr_name, group );
- fstrcpy( grp.gr_passwd, "*" );
-
- grp.gr_gid = id.gid;
- grp.gr_mem = NULL; /* start with no members */
- grp.num_gr_mem = 0;
-
- if ( !wb_storegrnam(&grp) )
- return WINBINDD_ERROR;
-
- /* do we need a new RID? */
-
- if ( flags & WBFLAG_ALLOCATE_RID ) {
- if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, GROUP_RID_TYPE)) ) {
- DEBUG(0,("winbindd_create_group: RID allocation failure! Cannot create group (%s)\n",
- group));
- wb_delete_group( &grp );
-
- return WINBINDD_ERROR;
- }
-
- state->response.data.rid = rid;
- }
-
- return WINBINDD_OK;
-}
-
-/**********************************************************************
- Add a user to the membership for a group.
-**********************************************************************/
-
-enum winbindd_result winbindd_add_user_to_group(struct winbindd_cli_state *state)
-{
- WINBINDD_PW *pw;
- WINBINDD_GR *grp;
- char *user, *group;
- BOOL ret;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_add_user_to_group: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
- group = state->request.data.acct_mgt.groupname;
- user = state->request.data.acct_mgt.username;
-
- DEBUG(3, ("[%5lu]: add_user_to_group: add %s to %s\n", (unsigned long)state->pid,
- user, group));
-
- /* make sure it is a valid user */
-
- if ( !(pw = wb_getpwnam( user )) ) {
- DEBUG(4,("winbindd_add_user_to_group: Cannot add a non-existent user\n"));
- return WINBINDD_ERROR;
- }
-
- /* make sure it is a valid group */
-
- if ( !(grp = wb_getgrnam( group )) ) {
- DEBUG(4,("winbindd_add_user_to_group: Cannot add a user to a non-extistent group\n"));
- return WINBINDD_ERROR;
- }
-
- if ( !wb_addgrpmember( grp, user ) )
- return WINBINDD_ERROR;
-
- ret = wb_storegrnam(grp);
-
- free_winbindd_gr( grp );
-
- return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
-}
-
-/**********************************************************************
- Remove a user from the membership of a group
-**********************************************************************/
-
-enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state *state)
-{
- WINBINDD_GR *grp;
- char *user, *group;
- BOOL ret;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_remove_user_from_group: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
- group = state->request.data.acct_mgt.groupname;
- user = state->request.data.acct_mgt.username;
-
- DEBUG(3, ("[%5lu]: remove_user_from_group: delete %s from %s\n", (unsigned long)state->pid,
- user, group));
-
- /* don't worry about checking the username since we're removing it anyways */
-
- /* make sure it is a valid group */
-
- if ( !(grp = wb_getgrnam( group )) ) {
- DEBUG(4,("winbindd_remove_user_from_group: Cannot remove a user from a non-extistent group\n"));
- return WINBINDD_ERROR;
- }
-
- if ( !wb_delgrpmember( grp, user ) )
- return WINBINDD_ERROR;
-
- ret = wb_storegrnam(grp);
-
- free_winbindd_gr( grp );
-
- return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
-}
-
-/**********************************************************************
- Set the primary group membership of a user
-**********************************************************************/
-
-enum winbindd_result winbindd_set_user_primary_group(struct winbindd_cli_state *state)
-{
- WINBINDD_PW *pw;
- WINBINDD_GR *grp;
- char *user, *group;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_set_user_primary_group: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
- group = state->request.data.acct_mgt.groupname;
- user = state->request.data.acct_mgt.username;
-
- DEBUG(3, ("[%5lu]: set_user_primary_group: group %s for user %s\n",
- (unsigned long)state->pid, group, user));
-
- /* make sure it is a valid user */
-
- if ( !(pw = wb_getpwnam( user )) ) {
- DEBUG(4,("winbindd_add_user_to_group: Cannot add a non-existent user\n"));
- return WINBINDD_ERROR;
- }
-
- /* make sure it is a valid group */
-
- if ( !(grp = wb_getgrnam( group )) ) {
- DEBUG(4,("winbindd_add_user_to_group: Cannot add a user to a non-extistent group\n"));
- return WINBINDD_ERROR;
- }
-
- pw->pw_gid = grp->gr_gid;
-
- free_winbindd_gr( grp );
-
- return ( wb_storepwnam(pw) ? WINBINDD_OK : WINBINDD_ERROR );
-}
-
-/**********************************************************************
- Delete a user from the winbindd account tdb.
-**********************************************************************/
-
-enum winbindd_result winbindd_delete_user(struct winbindd_cli_state *state)
-{
- WINBINDD_PW *pw;
- char *user;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_delete_user: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
- user = state->request.data.acct_mgt.username;
-
- DEBUG(3, ("[%5lu]: delete_user: %s\n", (unsigned long)state->pid, user));
-
- /* make sure it is a valid user */
-
- if ( !(pw = wb_getpwnam( user )) ) {
- DEBUG(4,("winbindd_delete_user: Cannot delete a non-existent user\n"));
- return WINBINDD_ERROR;
- }
-
- return ( wb_delete_user(pw) ? WINBINDD_OK : WINBINDD_ERROR );
-}
-
-/**********************************************************************
- Delete a group from winbindd's account tdb.
-**********************************************************************/
-
-enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state)
-{
- WINBINDD_GR *grp;
- char *group;
- BOOL ret;
-
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_delete_group: non-privileged access denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* Ensure null termination */
- state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
- group = state->request.data.acct_mgt.groupname;
-
- DEBUG(3, ("[%5lu]: delete_group: %s\n", (unsigned long)state->pid, group));
-
- /* make sure it is a valid group */
-
- if ( !(grp = wb_getgrnam( group )) ) {
- DEBUG(4,("winbindd_delete_group: Cannot delete a non-existent group\n"));
- return WINBINDD_ERROR;
- }
-
- ret = wb_delete_group(grp);
-
- free_winbindd_gr( grp );
-
- return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
-}
-
-
-
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
deleted file mode 100644
index cd8b8e0e246..00000000000
--- a/source/nsswitch/winbindd_ads.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind ADS backend functions
-
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
- Copyright (C) Gerald (Jerry) Carter 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-
-#ifdef HAVE_ADS
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/*
- return our ads connections structure for a domain. We keep the connection
- open to make things faster
-*/
-static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
-{
- ADS_STRUCT *ads;
- ADS_STATUS status;
-
- if (domain->private) {
- ads = (ADS_STRUCT *)domain->private;
-
- /* check for a valid structure */
-
- DEBUG(7, ("Current tickets expire at %d\n, time is now %d\n",
- (uint32) ads->auth.expire, (uint32) time(NULL)));
- if ( ads->config.realm && (ads->auth.expire > time(NULL))) {
- return ads;
- }
- else {
- /* we own this ADS_STRUCT so make sure it goes away */
- ads->is_mine = True;
- ads_destroy( &ads );
- ads_kdestroy("MEMORY:winbind_ccache");
- domain->private = NULL;
- }
- }
-
- /* we don't want this to affect the users ccache */
- setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1);
-
- ads = ads_init(domain->alt_name, domain->name, NULL);
- if (!ads) {
- DEBUG(1,("ads_init for domain %s failed\n", domain->name));
- return NULL;
- }
-
- /* the machine acct password might have change - fetch it every time */
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- SAFE_FREE(ads->auth.realm);
- ads->auth.realm = strdup(lp_realm());
-
- status = ads_connect(ads);
- if (!ADS_ERR_OK(status) || !ads->config.realm) {
- extern struct winbindd_methods msrpc_methods, cache_methods;
- DEBUG(1,("ads_connect for domain %s failed: %s\n",
- domain->name, ads_errstr(status)));
- ads_destroy(&ads);
-
- /* if we get ECONNREFUSED then it might be a NT4
- server, fall back to MSRPC */
- if (status.error_type == ENUM_ADS_ERROR_SYSTEM &&
- status.err.rc == ECONNREFUSED) {
- DEBUG(1,("Trying MSRPC methods\n"));
- if (domain->methods == &cache_methods) {
- domain->backend = &msrpc_methods;
- } else {
- domain->methods = &msrpc_methods;
- }
- }
- return NULL;
- }
-
- /* set the flag that says we don't own the memory even
- though we do so that ads_destroy() won't destroy the
- structure we pass back by reference */
-
- ads->is_mine = False;
-
- domain->private = (void *)ads;
- return ads;
-}
-
-
-/* Query display info for a realm. This is the basic user list fn */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "name", "objectSid", "primaryGroupID",
- "sAMAccountType", NULL};
- int i, count;
- ADS_STATUS rc;
- void *res = NULL;
- void *msg = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- *num_entries = 0;
-
- DEBUG(3,("ads: query_user_list\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- rc = ads_search_retry(ads, &res, "(objectClass=user)", attrs);
- if (!ADS_ERR_OK(rc) || !res) {
- DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(1,("query_user_list: No users found\n"));
- goto done;
- }
-
- (*info) = talloc_zero(mem_ctx, count * sizeof(**info));
- if (!*info) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- i = 0;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- char *name, *gecos;
- DOM_SID sid;
- DOM_SID *sid2;
- DOM_SID *group_sid;
- uint32 group;
- uint32 atype;
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
- ads_atype_map(atype) != SID_NAME_USER) {
- DEBUG(1,("Not a user account? atype=0x%x\n", atype));
- continue;
- }
-
- name = ads_pull_username(ads, mem_ctx, msg);
- gecos = ads_pull_string(ads, mem_ctx, msg, "name");
- if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- continue;
- }
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) {
- DEBUG(1,("No primary group for %s !?\n", name));
- continue;
- }
-
- sid2 = talloc(mem_ctx, sizeof(*sid2));
- if (!sid2) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy(sid2, &sid);
-
- group_sid = rid_to_talloced_sid(domain, mem_ctx, group);
-
- (*info)[i].acct_name = name;
- (*info)[i].full_name = gecos;
- (*info)[i].user_sid = sid2;
- (*info)[i].group_sid = group_sid;
- i++;
- }
-
- (*num_entries) = i;
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries)));
-
-done:
- if (res)
- ads_msgfree(ads, res);
-
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName", "sAMAccountName",
- "name", "objectSid",
- "sAMAccountType", NULL};
- int i, count;
- ADS_STATUS rc;
- void *res = NULL;
- void *msg = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- uint32 group_flags;
-
- *num_entries = 0;
-
- DEBUG(3,("ads: enum_dom_groups\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- rc = ads_search_retry(ads, &res, "(objectCategory=group)", attrs);
- if (!ADS_ERR_OK(rc) || !res) {
- DEBUG(1,("enum_dom_groups ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(1,("enum_dom_groups: No groups found\n"));
- goto done;
- }
-
- (*info) = talloc_zero(mem_ctx, count * sizeof(**info));
- if (!*info) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- i = 0;
-
- group_flags = ATYPE_GLOBAL_GROUP;
-
- /* only grab domain local groups for our domain */
- if ( domain->native_mode && strequal(lp_realm(), domain->alt_name) )
- group_flags |= ATYPE_LOCAL_GROUP;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- char *name, *gecos;
- DOM_SID sid;
- uint32 rid;
- uint32 account_type;
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &account_type) || !(account_type & group_flags) )
- continue;
-
- name = ads_pull_username(ads, mem_ctx, msg);
- gecos = ads_pull_string(ads, mem_ctx, msg, "name");
- if (!ads_pull_sid(ads, msg, "objectSid", &sid)) {
- DEBUG(1,("No sid for %s !?\n", name));
- continue;
- }
-
- if (!sid_peek_check_rid(&domain->sid, &sid, &rid)) {
- DEBUG(1,("No rid for %s !?\n", name));
- continue;
- }
-
- fstrcpy((*info)[i].acct_name, name);
- fstrcpy((*info)[i].acct_desc, gecos);
- (*info)[i].rid = rid;
- i++;
- }
-
- (*num_entries) = i;
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*num_entries)));
-
-done:
- if (res)
- ads_msgfree(ads, res);
-
- return status;
-}
-
-/* list all domain local groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- /*
- * This is a stub function only as we returned the domain
- * local groups in enum_dom_groups() if the domain->native field
- * was true. This is a simple performance optimization when
- * using LDAP.
- *
- * if we ever need to enumerate domain local groups separately,
- * then this the optimization in enum_dom_groups() will need
- * to be split out
- */
- *num_entries = 0;
-
- return NT_STATUS_OK;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- ADS_STRUCT *ads;
-
- DEBUG(3,("ads: name_to_sid\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return ads_name_to_sid(ads, name, sid, type);
-}
-
-/* convert a sid to a user or group name */
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- ADS_STRUCT *ads = NULL;
- DEBUG(3,("ads: sid_to_name\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return ads_sid_to_name(ads, mem_ctx, sid, name, type);
-}
-
-
-/* convert a DN to a name, SID and name type
- this might become a major speed bottleneck if groups have
- lots of users, in which case we could cache the results
-*/
-static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- const char *dn,
- char **name, uint32 *name_type, DOM_SID *sid)
-{
- void *res = NULL;
- const char *attrs[] = {"userPrincipalName", "sAMAccountName",
- "objectSid", "sAMAccountType", NULL};
- ADS_STATUS rc;
- uint32 atype;
- DEBUG(3,("ads: dn_lookup\n"));
-
- rc = ads_search_retry_dn(ads, &res, dn, attrs);
-
- if (!ADS_ERR_OK(rc) || !res) {
- goto failed;
- }
-
- (*name) = ads_pull_username(ads, mem_ctx, res);
-
- if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) {
- goto failed;
- }
- (*name_type) = ads_atype_map(atype);
-
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- goto failed;
- }
-
- if (res)
- ads_msgfree(ads, res);
-
- return True;
-
-failed:
- if (res)
- ads_msgfree(ads, res);
-
- return False;
-}
-
-/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- WINBIND_USERINFO *info)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"userPrincipalName",
- "sAMAccountName",
- "name",
- "primaryGroupID", NULL};
- ADS_STATUS rc;
- int count;
- void *msg = NULL;
- char *ldap_exp;
- char *sidstr;
- uint32 group_rid;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- DOM_SID *sid2;
- fstring sid_string;
-
- DEBUG(3,("ads: query_user\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- sidstr = sid_binstring(sid);
- asprintf(&ldap_exp, "(objectSid=%s)", sidstr);
- rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
- free(ldap_exp);
- free(sidstr);
- if (!ADS_ERR_OK(rc) || !msg) {
- DEBUG(1,("query_user(sid=%s) ads_search: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc)));
- goto done;
- }
-
- count = ads_count_replies(ads, msg);
- if (count != 1) {
- DEBUG(1,("query_user(sid=%s): Not found\n", sid_to_string(sid_string, sid)));
- goto done;
- }
-
- info->acct_name = ads_pull_username(ads, mem_ctx, msg);
- info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
-
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
- DEBUG(1,("No primary group for %s !?\n", sid_to_string(sid_string, sid)));
- goto done;
- }
-
- sid2 = talloc(mem_ctx, sizeof(*sid2));
- if (!sid2) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- sid_copy(sid2, sid);
-
- info->user_sid = sid2;
-
- info->group_sid = rid_to_talloced_sid(domain, mem_ctx, group_rid);
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads query_user gave %s\n", info->acct_name));
-done:
- if (msg)
- ads_msgfree(ads, msg);
-
- return status;
-}
-
-/* Lookup groups a user is a member of - alternate method, for when
- tokenGroups are not available. */
-static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user_dn,
- DOM_SID *primary_group,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- ADS_STATUS rc;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- int count;
- void *res = NULL;
- void *msg = NULL;
- char *ldap_exp;
- ADS_STRUCT *ads;
- const char *group_attrs[] = {"objectSid", NULL};
- char *escaped_dn;
-
- DEBUG(3,("ads: lookup_usergroups_alt\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- /* buggy server, no tokenGroups. Instead lookup what groups this user
- is a member of by DN search on member*/
-
- if (!(ldap_exp = talloc_asprintf(mem_ctx, "(&(member=%s)(objectClass=group))", escaped_dn))) {
- DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
- SAFE_FREE(escaped_dn);
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- SAFE_FREE(escaped_dn);
-
- rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
-
- if (!ADS_ERR_OK(rc) || !res) {
- DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc)));
- return ads_ntstatus(rc);
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- DEBUG(5,("lookup_usergroups: No supp groups found\n"));
-
- status = ads_ntstatus(rc);
- goto done;
- }
-
- (*user_gids) = talloc_zero(mem_ctx, sizeof(**user_gids) * (count + 1));
- (*user_gids)[0] = primary_group;
-
- *num_groups = 1;
-
- for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- DOM_SID group_sid;
-
- if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) {
- DEBUG(1,("No sid for this group ?!?\n"));
- continue;
- }
-
- if (sid_equal(&group_sid, primary_group)) continue;
-
- (*user_gids)[*num_groups] = talloc(mem_ctx, sizeof(***user_gids));
- if (!(*user_gids)[*num_groups]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy((*user_gids)[*num_groups], &group_sid);
-
- (*num_groups)++;
-
- }
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads lookup_usergroups (alt) for dn=%s\n", user_dn));
-done:
- if (res)
- ads_msgfree(ads, res);
-
- return status;
-}
-
-/* Lookup groups a user is a member of. */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"tokenGroups", "primaryGroupID", NULL};
- ADS_STATUS rc;
- int count;
- LDAPMessage *msg = NULL;
- char *user_dn;
- DOM_SID *sids;
- int i;
- DOM_SID *primary_group;
- uint32 primary_group_rid;
- fstring sid_string;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(3,("ads: lookup_usergroups\n"));
- *num_groups = 0;
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- rc = ads_sid_to_dn(ads, mem_ctx, sid, &user_dn);
- if (!ADS_ERR_OK(rc)) {
- status = ads_ntstatus(rc);
- goto done;
- }
-
- rc = ads_search_retry_dn(ads, (void**)&msg, user_dn, attrs);
- if (!ADS_ERR_OK(rc)) {
- status = ads_ntstatus(rc);
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n",
- sid_to_string(sid_string, sid), ads_errstr(rc)));
- goto done;
- }
-
- if (!msg) {
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n",
- sid_to_string(sid_string, sid)));
- status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
- DEBUG(1,("%s: No primary group for sid=%s !?\n",
- domain->name, sid_to_string(sid_string, sid)));
- goto done;
- }
-
- primary_group = rid_to_talloced_sid(domain, mem_ctx, primary_group_rid);
-
- count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
-
- if (msg)
- ads_msgfree(ads, msg);
-
- /* there must always be at least one group in the token,
- unless we are talking to a buggy Win2k server */
- if (count == 0) {
- return lookup_usergroups_alt(domain, mem_ctx, user_dn,
- primary_group,
- num_groups, user_gids);
- }
-
- (*user_gids) = talloc_zero(mem_ctx, sizeof(**user_gids) * (count + 1));
- (*user_gids)[0] = primary_group;
-
- *num_groups = 1;
-
- for (i=0;i<count;i++) {
- if (sid_equal(&sids[i], primary_group)) continue;
-
- (*user_gids)[*num_groups] = talloc(mem_ctx, sizeof(***user_gids));
- if (!(*user_gids)[*num_groups]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- sid_copy((*user_gids)[*num_groups], &sids[i]);
- (*num_groups)++;
- }
-
- status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_usergroups for sid=%s\n", sid_to_string(sid_string, sid)));
-done:
- return status;
-}
-
-/*
- find the members of a group, given a group rid and domain
- */
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- ADS_STATUS rc;
- int count;
- void *res=NULL;
- ADS_STRUCT *ads = NULL;
- char *ldap_exp;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- char *sidstr;
- char **members;
- int i, num_members;
- fstring sid_string;
- BOOL more_values;
- const char **attrs;
- uint32 first_usn;
- uint32 current_usn;
- int num_retries = 0;
-
- DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
- sid_string_static(group_sid)));
-
- *num_names = 0;
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
- }
-
- sidstr = sid_binstring(group_sid);
-
- /* search for all members of the group */
- if (!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)",sidstr))) {
- SAFE_FREE(sidstr);
- DEBUG(1, ("ads: lookup_groupmem: tallloc_asprintf for ldap_exp failed!\n"));
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- SAFE_FREE(sidstr);
-
- members = NULL;
- num_members = 0;
-
- attrs = talloc(mem_ctx, 3 * sizeof(*attrs));
- attrs[1] = talloc_strdup(mem_ctx, "usnChanged");
- attrs[2] = NULL;
-
- do {
- if (num_members == 0)
- attrs[0] = talloc_strdup(mem_ctx, "member");
-
- DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1]));
-
- rc = ads_search_retry(ads, &res, ldap_exp, attrs);
-
- if (!ADS_ERR_OK(rc) || !res) {
- DEBUG(1,("ads: lookup_groupmem ads_search: %s\n",
- ads_errstr(rc)));
- status = ads_ntstatus(rc);
- goto done;
- }
-
- count = ads_count_replies(ads, res);
- if (count == 0)
- break;
-
- if (num_members == 0) {
- if (!ads_pull_uint32(ads, res, "usnChanged", &first_usn)) {
- DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n"));
- goto done;
- }
- }
-
- if (!ads_pull_uint32(ads, res, "usnChanged", &current_usn)) {
- DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n"));
- goto done;
- }
-
- if (first_usn != current_usn) {
- DEBUG(5, ("ads: lookup_groupmem USN on this record changed"
- " - restarting search\n"));
- if (num_retries < 5) {
- num_retries++;
- num_members = 0;
- continue;
- } else {
- DEBUG(5, ("ads: lookup_groupmem USN on this record changed"
- " - restarted search too many times, aborting!\n"));
- status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- }
-
- members = ads_pull_strings_range(ads, mem_ctx, res,
- "member",
- members,
- &attrs[0],
- &num_members,
- &more_values);
-
- if ((members == NULL) || (num_members == 0))
- break;
-
- } while (more_values);
-
- /* now we need to turn a list of members into rids, names and name types
- the problem is that the members are in the form of distinguised names
- */
-
- (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members);
- (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members);
- (*names) = talloc_zero(mem_ctx, sizeof(**names) * num_members);
-
- for (i=0;i<num_members;i++) {
- uint32 name_type;
- char *name;
- DOM_SID sid;
-
- if (dn_lookup(ads, mem_ctx, members[i], &name, &name_type, &sid)) {
- (*names)[*num_names] = name;
- (*name_types)[*num_names] = name_type;
- (*sid_mem)[*num_names] = talloc(mem_ctx, sizeof(***sid_mem));
- if (!(*sid_mem)[*num_names]) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- sid_copy((*sid_mem)[*num_names], &sid);
- (*num_names)++;
- }
- }
-
- status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid)));
-done:
-
- if (res)
- ads_msgfree(ads, res);
-
- return status;
-}
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS rc;
-
- DEBUG(3,("ads: fetch sequence_number for %s\n", domain->name));
-
- *seq = DOM_SEQUENCE_NONE;
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- rc = ads_USN(ads, seq);
-
- if (!ADS_ERR_OK(rc)) {
-
- /* its a dead connection ; don't destroy it
- through since ads_USN() has already done
- that indirectly */
-
- domain->private = NULL;
- }
- return ads_ntstatus(rc);
-}
-
-/* get a list of trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- struct ds_domain_trust *domains = NULL;
- int count = 0;
- int i;
- struct cli_state *cli = NULL;
- /* i think we only need our forest and downlevel trusted domains */
- uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND;
-
- DEBUG(3,("ads: trusted_domains\n"));
-
- *num_domains = 0;
- *alt_names = NULL;
- *names = NULL;
- *dom_sids = NULL;
-
- if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain, PI_NETLOGON, &cli)) ) {
- DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n",
- domain->name, nt_errstr(result)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if ( NT_STATUS_IS_OK(result) )
- result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost,
- flags, &domains, (unsigned int *)&count );
-
- if ( NT_STATUS_IS_OK(result) && count) {
-
- /* Allocate memory for trusted domain names and sids */
-
- if ( !(*names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
- DEBUG(0, ("trusted_domains: out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if ( !(*alt_names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
- DEBUG(0, ("trusted_domains: out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- if ( !(*dom_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * count)) ) {
- DEBUG(0, ("trusted_domains: out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- /* Copy across names and sids */
-
- for (i = 0; i < count; i++) {
- (*names)[i] = domains[i].netbios_domain;
- (*alt_names)[i] = domains[i].dns_domain;
-
- sid_copy(&(*dom_sids)[i], &domains[i].sid);
- }
-
- *num_domains = count;
- }
-
-done:
-
- /* remove connection; This is a special case to the \NETLOGON pipe */
-
- if ( cli )
- cli_shutdown( cli );
-
- return result;
-}
-
-/* find the domain sid for a domain */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
-
- DEBUG(3,("ads: domain_sid\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- rc = ads_domain_sid(ads, sid);
-
- if (!ADS_ERR_OK(rc)) {
-
- /* its a dead connection; don't destroy it though
- since that has already been done indirectly
- by ads_domain_sid() */
-
- domain->private = NULL;
- }
-
- return ads_ntstatus(rc);
-}
-
-
-/* find alternate names list for the domain - for ADS this is the
- netbios name */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- TALLOC_CTX *ctx;
- const char *workgroup;
-
- DEBUG(3,("ads: alternate_name\n"));
-
- ads = ads_cached_connection(domain);
-
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!(ctx = talloc_init("alternate_name"))) {
- return NT_STATUS_NO_MEMORY;
- }
-
- rc = ads_workgroup_name(ads, ctx, &workgroup);
-
- if (ADS_ERR_OK(rc)) {
- fstrcpy(domain->name, workgroup);
- fstrcpy(domain->alt_name, ads->config.realm);
- strupper_m(domain->alt_name);
- strupper_m(domain->name);
- }
-
- talloc_destroy(ctx);
-
- return ads_ntstatus(rc);
-}
-
-/* the ADS backend methods are exposed via this structure */
-struct winbindd_methods ads_methods = {
- True,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};
-
-#endif
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 43a0f9cf395..920b0d388d7 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -4,8 +4,6 @@
Winbind cache backend functions
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Gerald Carter 2003
-
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,13 +20,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
struct winbind_cache {
+ struct winbindd_methods *backend;
TDB_CONTEXT *tdb;
};
@@ -48,22 +43,19 @@ void wcache_flush_cache(void)
{
extern BOOL opt_nocache;
- if (!wcache)
- return;
+ if (!wcache) return;
if (wcache->tdb) {
tdb_close(wcache->tdb);
wcache->tdb = NULL;
}
- if (opt_nocache)
- return;
+ if (opt_nocache) return;
wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
- TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
+ TDB_DEFAULT, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (!wcache->tdb) {
DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
}
- DEBUG(10,("wcache_flush_cache success\n"));
}
void winbindd_check_cache_size(time_t t)
@@ -98,46 +90,24 @@ void winbindd_check_cache_size(time_t t)
/* get the winbind_cache structure */
static struct winbind_cache *get_cache(struct winbindd_domain *domain)
{
+ extern struct winbindd_methods msrpc_methods;
struct winbind_cache *ret = wcache;
- if (!domain->backend) {
- extern struct winbindd_methods msrpc_methods;
- switch (lp_security()) {
-#ifdef HAVE_ADS
- case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
- /* always obey the lp_security parameter for our domain */
- if (domain->primary) {
- domain->backend = &ads_methods;
- break;
- }
-
- /* only use ADS for native modes at the momment.
- The problem is the correct detection of mixed
- mode domains from NT4 BDC's --jerry */
-
- if ( domain->native_mode ) {
- DEBUG(5,("get_cache: Setting ADS methods for domain %s\n",
- domain->name));
- domain->backend = &ads_methods;
- break;
- }
-
- /* fall through */
- }
-#endif
- default:
- DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n",
- domain->name));
- domain->backend = &msrpc_methods;
- }
- }
-
- if (ret)
- return ret;
+ if (ret) return ret;
ret = smb_xmalloc(sizeof(*ret));
ZERO_STRUCTP(ret);
+ switch (lp_security()) {
+#ifdef HAVE_ADS
+ case SEC_ADS: {
+ extern struct winbindd_methods ads_methods;
+ ret->backend = &ads_methods;
+ break;
+ }
+#endif
+ default:
+ ret->backend = &msrpc_methods;
+ }
wcache = ret;
wcache_flush_cache();
@@ -150,12 +120,12 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
*/
static void centry_free(struct cache_entry *centry)
{
- if (!centry)
- return;
+ if (!centry) return;
SAFE_FREE(centry->data);
free(centry);
}
+
/*
pull a uint32 from a cache entry
*/
@@ -219,178 +189,66 @@ static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
return ret;
}
-/* pull a string from a cache entry, using the supplied
- talloc context
-*/
-static DOM_SID *centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
-{
- DOM_SID *sid;
- char *sid_string;
-
- sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid)
- return NULL;
-
- sid_string = centry_string(centry, mem_ctx);
- if (!string_to_sid(sid, sid_string)) {
- return NULL;
- }
- return sid;
-}
-
/* the server is considered down if it can't give us a sequence number */
static BOOL wcache_server_down(struct winbindd_domain *domain)
{
- BOOL ret;
-
- if (!wcache->tdb)
- return False;
-
- ret = (domain->sequence_number == DOM_SEQUENCE_NONE);
-
- if (ret)
- DEBUG(10,("wcache_server_down: server for Domain %s down\n",
- domain->name ));
- return ret;
+ if (!wcache->tdb) return False;
+ return (domain->sequence_number == DOM_SEQUENCE_NONE);
}
-static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
-{
- TDB_DATA data;
- fstring key;
- uint32 time_diff;
-
- if (!wcache->tdb) {
- DEBUG(10,("fetch_cache_seqnum: tdb == NULL\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fstr_sprintf( key, "SEQNUM/%s", domain->name );
-
- data = tdb_fetch_bystring( wcache->tdb, key );
- if ( !data.dptr || data.dsize!=8 ) {
- DEBUG(10,("fetch_cache_seqnum: invalid data size key [%s]\n", key ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- domain->sequence_number = IVAL(data.dptr, 0);
- domain->last_seq_check = IVAL(data.dptr, 4);
-
- /* have we expired? */
-
- time_diff = now - domain->last_seq_check;
- if ( time_diff > lp_winbind_cache_time() ) {
- DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
- domain->name, domain->sequence_number,
- (uint32)domain->last_seq_check));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n",
- domain->name, domain->sequence_number,
- (uint32)domain->last_seq_check));
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain )
-{
- TDB_DATA data, key;
- fstring key_str;
- char buf[8];
-
- if (!wcache->tdb) {
- DEBUG(10,("store_cache_seqnum: tdb == NULL\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fstr_sprintf( key_str, "SEQNUM/%s", domain->name );
- key.dptr = key_str;
- key.dsize = strlen(key_str)+1;
-
- SIVAL(buf, 0, domain->sequence_number);
- SIVAL(buf, 4, domain->last_seq_check);
- data.dptr = buf;
- data.dsize = 8;
-
- if ( tdb_store( wcache->tdb, key, data, TDB_REPLACE) == -1 ) {
- DEBUG(10,("store_cache_seqnum: tdb_store fail key [%s]\n", key_str ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("store_cache_seqnum: success [%s][%u @ %u]\n",
- domain->name, domain->sequence_number,
- (uint32)domain->last_seq_check));
-
- return NT_STATUS_OK;
-}
/*
refresh the domain sequence number. If force is True
then always refresh it, no matter how recently we fetched it
*/
-
static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
{
NTSTATUS status;
unsigned time_diff;
- time_t t = time(NULL);
- unsigned cache_time = lp_winbind_cache_time();
- get_cache( domain );
+ time_diff = time(NULL) - domain->last_seq_check;
-#if 0 /* JERRY -- disable as the default cache time is now 5 minutes */
- /* trying to reconnect is expensive, don't do it too often */
- if (domain->sequence_number == DOM_SEQUENCE_NONE) {
- cache_time *= 8;
+ /* see if we have to refetch the domain sequence number */
+ if (!force && (time_diff < lp_winbind_cache_time())) {
+ return;
}
-#endif
- time_diff = t - domain->last_seq_check;
+ status = wcache->backend->sequence_number(domain, &domain->sequence_number);
- /* see if we have to refetch the domain sequence number */
- if (!force && (time_diff < cache_time)) {
- DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name));
- goto done;
- }
-
- /* try to get the sequence number from the tdb cache first */
- /* this will update the timestamp as well */
+ if (!NT_STATUS_IS_OK(status))
+ DEBUG(10, ("refresh_sequence_number: backend returned 0x%08x\n",
+ NT_STATUS_V(status)));
- status = fetch_cache_seqnum( domain, t );
- if ( NT_STATUS_IS_OK(status) )
- goto done;
+ /* Convert a NT_STATUS_UNSUCCESSFUL error to a
+ NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND. The former is
+ returned when we can't make an initial connection to
+ the domain controller. The latter is returned when we
+ can't fetch the sequence number on an already open
+ connection. */
- status = domain->backend->sequence_number(domain, &domain->sequence_number);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL))
+ status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- if (!NT_STATUS_IS_OK(status)) {
- domain->sequence_number = DOM_SEQUENCE_NONE;
- }
-
domain->last_status = status;
- domain->last_seq_check = time(NULL);
-
- /* save the new sequence number ni the cache */
- store_cache_seqnum( domain );
-done:
- DEBUG(10, ("refresh_sequence_number: %s seq number is now %d\n",
- domain->name, domain->sequence_number));
+ if (!NT_STATUS_IS_OK(status))
+ domain->sequence_number = DOM_SEQUENCE_NONE;
- return;
+ domain->last_seq_check = time(NULL);
+
+ DEBUG(10, ("refresh_sequence_number: seq number is now %d\n",
+ domain->sequence_number));
}
/*
decide if a cache entry has expired
*/
-static BOOL centry_expired(struct winbindd_domain *domain, const char *keystr, struct cache_entry *centry)
+static BOOL centry_expired(struct winbindd_domain *domain, struct cache_entry *centry)
{
/* if the server is OK and our cache entry came from when it was down then
the entry is invalid */
if (domain->sequence_number != DOM_SEQUENCE_NONE &&
centry->sequence_number == DOM_SEQUENCE_NONE) {
- DEBUG(10,("centry_expired: Key %s for domain %s invalid sequence.\n",
- keystr, domain->name ));
return True;
}
@@ -398,14 +256,9 @@ static BOOL centry_expired(struct winbindd_domain *domain, const char *keystr, s
current sequence number then it is OK */
if (wcache_server_down(domain) ||
centry->sequence_number == domain->sequence_number) {
- DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
- keystr, domain->name ));
return False;
}
- DEBUG(10,("centry_expired: Key %s for domain %s expired\n",
- keystr, domain->name ));
-
/* it's expired */
return True;
}
@@ -416,9 +269,6 @@ static BOOL centry_expired(struct winbindd_domain *domain, const char *keystr, s
*/
static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
struct winbindd_domain *domain,
- const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
- struct winbindd_domain *domain,
const char *format, ...)
{
va_list ap;
@@ -436,51 +286,31 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
key.dptr = kstr;
key.dsize = strlen(kstr);
data = tdb_fetch(wcache->tdb, key);
+ free(kstr);
if (!data.dptr) {
/* a cache miss */
- free(kstr);
return NULL;
}
centry = smb_xmalloc(sizeof(*centry));
- centry->data = (unsigned char *)data.dptr;
+ centry->data = (uchar *)data.dptr;
centry->len = data.dsize;
centry->ofs = 0;
if (centry->len < 8) {
/* huh? corrupt cache? */
- DEBUG(10,("wcache_fetch: Corrupt cache for key %s domain %s (len < 8) ?\n",
- kstr, domain->name ));
centry_free(centry);
- free(kstr);
return NULL;
}
centry->status = NT_STATUS(centry_uint32(centry));
centry->sequence_number = centry_uint32(centry);
- if (centry_expired(domain, kstr, centry)) {
- extern BOOL opt_dual_daemon;
-
- DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
- kstr, domain->name ));
-
- if (opt_dual_daemon) {
- extern BOOL background_process;
- background_process = True;
- DEBUG(10,("wcache_fetch: background processing expired entry %s for domain %s\n",
- kstr, domain->name ));
- } else {
- centry_free(centry);
- free(kstr);
- return NULL;
- }
+ if (centry_expired(domain, centry)) {
+ centry_free(centry);
+ return NULL;
}
- DEBUG(10,("wcache_fetch: returning entry %s for domain %s\n",
- kstr, domain->name ));
-
- free(kstr);
return centry;
}
@@ -490,8 +320,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
static void centry_expand(struct cache_entry *centry, uint32 len)
{
uint8 *p;
- if (centry->len - centry->ofs >= len)
- return;
+ if (centry->len - centry->ofs >= len) return;
centry->len *= 2;
p = realloc(centry->data, centry->len);
if (!p) {
@@ -536,20 +365,13 @@ static void centry_put_string(struct cache_entry *centry, const char *s)
len = strlen(s);
/* can't handle more than 254 char strings. Truncating is probably best */
- if (len > 254)
- len = 254;
+ if (len > 254) len = 254;
centry_put_uint8(centry, len);
centry_expand(centry, len);
memcpy(centry->data + centry->ofs, s, len);
centry->ofs += len;
}
-static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
-{
- fstring sid_string;
- centry_put_string(centry, sid_to_string(sid_string, sid));
-}
-
/*
start a centry for output. When finished, call centry_end()
*/
@@ -557,8 +379,7 @@ struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status
{
struct cache_entry *centry;
- if (!wcache->tdb)
- return NULL;
+ if (!wcache->tdb) return NULL;
centry = smb_xmalloc(sizeof(*centry));
@@ -574,7 +395,6 @@ struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status
/*
finish a centry and write it to the tdb
*/
-static void centry_end(struct cache_entry *centry, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
static void centry_end(struct cache_entry *centry, const char *format, ...)
{
va_list ap;
@@ -594,42 +414,47 @@ static void centry_end(struct cache_entry *centry, const char *format, ...)
free(kstr);
}
-static void wcache_save_name_to_sid(struct winbindd_domain *domain,
- NTSTATUS status,
- const char *name, const DOM_SID *sid,
- enum SID_NAME_USE type)
+/* form a sid from the domain plus rid */
+static DOM_SID *form_sid(struct winbindd_domain *domain, uint32 rid)
+{
+ static DOM_SID sid;
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, rid);
+ return &sid;
+}
+
+static void wcache_save_name_to_sid(struct winbindd_domain *domain, NTSTATUS status,
+ const char *name, DOM_SID *sid, enum SID_NAME_USE type)
{
struct cache_entry *centry;
+ uint32 len;
fstring uname;
- fstring sid_string;
centry = centry_start(domain, status);
- if (!centry)
- return;
+ if (!centry) return;
+ len = sid_size(sid);
+ centry_expand(centry, len);
centry_put_uint32(centry, type);
- centry_put_sid(centry, sid);
+ sid_linearize((char *)centry->data + centry->ofs, len, sid);
+ centry->ofs += len;
fstrcpy(uname, name);
- strupper_m(uname);
+ strupper(uname);
centry_end(centry, "NS/%s/%s", domain->name, uname);
- DEBUG(10,("wcache_save_name_to_sid: %s -> %s\n", uname, sid_string));
centry_free(centry);
}
static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
- const DOM_SID *sid, const char *name, enum SID_NAME_USE type)
+ DOM_SID *sid, const char *name, enum SID_NAME_USE type, uint32 rid)
{
struct cache_entry *centry;
- fstring sid_string;
centry = centry_start(domain, status);
- if (!centry)
- return;
+ if (!centry) return;
if (NT_STATUS_IS_OK(status)) {
centry_put_uint32(centry, type);
centry_put_string(centry, name);
}
- centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
- DEBUG(10,("wcache_save_sid_to_name: %s -> %s\n", sid_string, name));
+ centry_end(centry, "SN/%s/%d", domain->name, rid);
centry_free(centry);
}
@@ -637,17 +462,14 @@ static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS sta
static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WINBIND_USERINFO *info)
{
struct cache_entry *centry;
- fstring sid_string;
centry = centry_start(domain, status);
- if (!centry)
- return;
+ if (!centry) return;
centry_put_string(centry, info->acct_name);
centry_put_string(centry, info->full_name);
- centry_put_sid(centry, info->user_sid);
- centry_put_sid(centry, info->group_sid);
- centry_end(centry, "U/%s", sid_to_string(sid_string, info->user_sid));
- DEBUG(10,("wcache_save_user: %s (acct_name %s)\n", sid_string, info->acct_name));
+ centry_put_uint32(centry, info->user_rid);
+ centry_put_uint32(centry, info->group_rid);
+ centry_end(centry, "U/%s/%d", domain->name, info->user_rid);
centry_free(centry);
}
@@ -661,35 +483,38 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i, retry;
+ int i;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
- if (!centry)
- goto do_query;
+ if (!centry) goto do_query;
*num_entries = centry_uint32(centry);
- if (*num_entries == 0)
- goto do_cached;
+ if (*num_entries == 0) goto do_cached;
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info))
- smb_panic("query_user_list out of memory");
+ if (! (*info)) smb_panic("query_user_list out of memory");
for (i=0; i<(*num_entries); i++) {
(*info)[i].acct_name = centry_string(centry, mem_ctx);
(*info)[i].full_name = centry_string(centry, mem_ctx);
- (*info)[i].user_sid = centry_sid(centry, mem_ctx);
- (*info)[i].group_sid = centry_sid(centry, mem_ctx);
+ (*info)[i].user_rid = centry_uint32(centry);
+ (*info)[i].group_rid = centry_uint32(centry);
}
do_cached:
- status = centry->status;
- DEBUG(10,("query_user_list: [Cached] - cached list for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
+ /* If we are returning cached data and the domain controller
+ is down then we don't know whether the data is up to date
+ or not. Return NT_STATUS_MORE_PROCESSING_REQUIRED to
+ indicate this. */
+
+ if (wcache_server_down(domain)) {
+ DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
+ status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ } else
+ status = centry->status;
centry_free(centry);
return status;
@@ -703,52 +528,28 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- /* Put the query_user_list() in a retry loop. There appears to be
- * some bug either with Windows 2000 or Samba's handling of large
- * rpc replies. This manifests itself as sudden disconnection
- * at a random point in the enumeration of a large (60k) user list.
- * The retry loop simply tries the operation again. )-: It's not
- * pretty but an acceptable workaround until we work out what the
- * real problem is. */
-
- retry = 0;
- do {
-
- DEBUG(10,("query_user_list: [Cached] - doing backend query for list for domain %s\n",
- domain->name ));
-
- status = domain->backend->query_user_list(domain, mem_ctx, num_entries, info);
- if (!NT_STATUS_IS_OK(status))
- DEBUG(3, ("query_user_list: returned 0x%08x, retrying\n", NT_STATUS_V(status)));
- if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL)) {
- DEBUG(3, ("query_user_list: flushing connection cache\n"));
- winbindd_cm_flush();
- }
-
- } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
- (retry++ < 5));
+ status = cache->backend->query_user_list(domain, mem_ctx, num_entries, info);
/* and save it */
- refresh_sequence_number(domain, False);
+ refresh_sequence_number(domain, True);
centry = centry_start(domain, status);
- if (!centry)
- goto skip_save;
+ if (!centry) goto skip_save;
centry_put_uint32(centry, *num_entries);
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
centry_put_string(centry, (*info)[i].full_name);
- centry_put_sid(centry, (*info)[i].user_sid);
- centry_put_sid(centry, (*info)[i].group_sid);
- if (domain->backend->consistent) {
+ centry_put_uint32(centry, (*info)[i].user_rid);
+ centry_put_uint32(centry, (*info)[i].group_rid);
+ if (cache->backend->consistent) {
/* when the backend is consistent we can pre-prime some mappings */
wcache_save_name_to_sid(domain, NT_STATUS_OK,
(*info)[i].acct_name,
- (*info)[i].user_sid,
+ form_sid(domain, (*info)[i].user_rid),
SID_NAME_USER);
wcache_save_sid_to_name(domain, NT_STATUS_OK,
- (*info)[i].user_sid,
+ form_sid(domain, (*info)[i].user_rid),
(*info)[i].acct_name,
- SID_NAME_USER);
+ SID_NAME_USER, (*info)[i].user_rid);
wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]);
}
}
@@ -768,96 +569,19 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i;
+ int i;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
- centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
- if (!centry)
- goto do_query;
+ centry = wcache_fetch(cache, domain, "GL/%s", domain->name);
+ if (!centry) goto do_query;
*num_entries = centry_uint32(centry);
- if (*num_entries == 0)
- goto do_cached;
+ if (*num_entries == 0) goto do_cached;
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info))
- smb_panic("enum_dom_groups out of memory");
- for (i=0; i<(*num_entries); i++) {
- fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
- fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
- (*info)[i].rid = centry_uint32(centry);
- }
-
-do_cached:
- status = centry->status;
-
- DEBUG(10,("enum_dom_groups: [Cached] - cached list for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- /* Return status value returned by seq number check */
-
- if (!NT_STATUS_IS_OK(domain->last_status))
- return domain->last_status;
-
- DEBUG(10,("enum_dom_groups: [Cached] - doing backend query for list for domain %s\n",
- domain->name ));
-
- status = domain->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, False);
- centry = centry_start(domain, status);
- if (!centry)
- goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].acct_desc);
- centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/domain", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb)
- goto do_query;
-
- centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
- if (!centry)
- goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0)
- goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info))
- smb_panic("enum_dom_groups out of memory");
+ if (! (*info)) smb_panic("enum_dom_groups out of memory");
for (i=0; i<(*num_entries); i++) {
fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
@@ -872,14 +596,11 @@ do_cached:
indicate this. */
if (wcache_server_down(domain)) {
- DEBUG(10, ("enum_local_groups: returning cached user list and server was down\n"));
+ DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
status = NT_STATUS_MORE_PROCESSING_REQUIRED;
} else
status = centry->status;
- DEBUG(10,("enum_local_groups: [Cached] - cached list for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
@@ -892,32 +613,28 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- DEBUG(10,("enum_local_groups: [Cached] - doing backend query for list for domain %s\n",
- domain->name ));
-
- status = domain->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
+ status = cache->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
/* and save it */
- refresh_sequence_number(domain, False);
+ refresh_sequence_number(domain, True);
centry = centry_start(domain, status);
- if (!centry)
- goto skip_save;
+ if (!centry) goto skip_save;
centry_put_uint32(centry, *num_entries);
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
centry_put_string(centry, (*info)[i].acct_desc);
centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/local", domain->name);
+ }
+ centry_end(centry, "GL/%s", domain->name);
centry_free(centry);
skip_save:
return status;
}
+
/* convert a single name to a sid in a domain */
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type)
@@ -926,50 +643,29 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
struct cache_entry *centry = NULL;
NTSTATUS status;
fstring uname;
- DOM_SID *sid2;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
fstrcpy(uname, name);
- strupper_m(uname);
+ strupper(uname);
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
- if (!centry)
- goto do_query;
- *type = (enum SID_NAME_USE)centry_uint32(centry);
- sid2 = centry_sid(centry, mem_ctx);
- if (!sid2) {
- ZERO_STRUCTP(sid);
- } else {
- sid_copy(sid, sid2);
- }
+ if (!centry) goto do_query;
+ *type = centry_uint32(centry);
+ sid_parse((char *)centry->data + centry->ofs, centry->len - centry->ofs, sid);
status = centry->status;
-
- DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
do_query:
ZERO_STRUCTP(sid);
- /* If the seq number check indicated that there is a problem
- * with this DC, then return that status... except for
- * access_denied. This is special because the dc may be in
- * "restrict anonymous = 1" mode, in which case it will deny
- * most unauthenticated operations, but *will* allow the LSA
- * name-to-sid that we try as a fallback. */
+ /* Return status value returned by seq number check */
- if (!(NT_STATUS_IS_OK(domain->last_status)
- || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
- domain->name ));
-
- status = domain->backend->name_to_sid(domain, mem_ctx, name, sid, type);
+ status = cache->backend->name_to_sid(domain, name, sid, type);
/* and save it */
wcache_save_name_to_sid(domain, status, name, sid, *type);
@@ -984,55 +680,42 @@ do_query:
given */
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ DOM_SID *sid,
char **name,
enum SID_NAME_USE *type)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring sid_string;
+ uint32 rid = 0;
+
+ sid_peek_rid(sid, &rid);
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
- centry = wcache_fetch(cache, domain, "SN/%s", sid_to_string(sid_string, sid));
- if (!centry)
- goto do_query;
+ centry = wcache_fetch(cache, domain, "SN/%s/%d", domain->name, rid);
+ if (!centry) goto do_query;
if (NT_STATUS_IS_OK(centry->status)) {
- *type = (enum SID_NAME_USE)centry_uint32(centry);
+ *type = centry_uint32(centry);
*name = centry_string(centry, mem_ctx);
}
status = centry->status;
-
- DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
do_query:
*name = NULL;
- /* If the seq number check indicated that there is a problem
- * with this DC, then return that status... except for
- * access_denied. This is special because the dc may be in
- * "restrict anonymous = 1" mode, in which case it will deny
- * most unauthenticated operations, but *will* allow the LSA
- * sid-to-name that we try as a fallback. */
+ /* Return status value returned by seq number check */
- if (!(NT_STATUS_IS_OK(domain->last_status)
- || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n",
- domain->name ));
-
- status = domain->backend->sid_to_name(domain, mem_ctx, sid, name, type);
+ status = cache->backend->sid_to_name(domain, mem_ctx, sid, name, type);
/* and save it */
- refresh_sequence_number(domain, False);
- wcache_save_sid_to_name(domain, status, sid, *name, *type);
+ refresh_sequence_number(domain, True);
+ wcache_save_sid_to_name(domain, status, sid, *name, *type, rid);
wcache_save_name_to_sid(domain, status, *name, sid, *type);
return status;
@@ -1042,42 +725,23 @@ do_query:
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
+ uint32 user_rid,
WINBIND_USERINFO *info)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
- centry = wcache_fetch(cache, domain, "U/%s", sid_string_static(user_sid));
-
- /* If we have an access denied cache entry and a cached info3 in the
- samlogon cache then do a query. This will force the rpc back end
- to return the info3 data. */
-
- if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
- netsamlogon_cache_have(user_sid)) {
- DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
- domain->last_status = NT_STATUS_OK;
- centry_free(centry);
- goto do_query;
- }
-
- if (!centry)
- goto do_query;
+ centry = wcache_fetch(cache, domain, "U/%s/%d", domain->name, user_rid);
+ if (!centry) goto do_query;
info->acct_name = centry_string(centry, mem_ctx);
info->full_name = centry_string(centry, mem_ctx);
- info->user_sid = centry_sid(centry, mem_ctx);
- info->group_sid = centry_sid(centry, mem_ctx);
+ info->user_rid = centry_uint32(centry);
+ info->group_rid = centry_uint32(centry);
status = centry->status;
-
- DEBUG(10,("query_user: [Cached] - cached info for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
@@ -1088,14 +752,11 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
-
- DEBUG(10,("sid_to_name: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
- status = domain->backend->query_user(domain, mem_ctx, user_sid, info);
+ status = cache->backend->query_user(domain, mem_ctx, user_rid, info);
/* and save it */
- refresh_sequence_number(domain, False);
+ refresh_sequence_number(domain, True);
wcache_save_user(domain, status, info);
return status;
@@ -1105,53 +766,31 @@ do_query:
/* Lookup groups a user is a member of. */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
+ uint32 user_rid,
+ uint32 *num_groups, uint32 **user_gids)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i;
- fstring sid_string;
+ int i;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
- centry = wcache_fetch(cache, domain, "UG/%s", sid_to_string(sid_string, user_sid));
-
- /* If we have an access denied cache entry and a cached info3 in the
- samlogon cache then do a query. This will force the rpc back end
- to return the info3 data. */
-
- if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
- netsamlogon_cache_have(user_sid)) {
- DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
- domain->last_status = NT_STATUS_OK;
- centry_free(centry);
- goto do_query;
- }
-
- if (!centry)
- goto do_query;
+ centry = wcache_fetch(cache, domain, "UG/%s/%d", domain->name, user_rid);
+ if (!centry) goto do_query;
*num_groups = centry_uint32(centry);
- if (*num_groups == 0)
- goto do_cached;
+ if (*num_groups == 0) goto do_cached;
(*user_gids) = talloc(mem_ctx, sizeof(**user_gids) * (*num_groups));
- if (! (*user_gids))
- smb_panic("lookup_usergroups out of memory");
+ if (! (*user_gids)) smb_panic("lookup_usergroups out of memory");
for (i=0; i<(*num_groups); i++) {
- (*user_gids)[i] = centry_sid(centry, mem_ctx);
+ (*user_gids)[i] = centry_uint32(centry);
}
do_cached:
status = centry->status;
-
- DEBUG(10,("lookup_usergroups: [Cached] - cached info for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
@@ -1164,21 +803,17 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- DEBUG(10,("lookup_usergroups: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
-
- status = domain->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
+ status = cache->backend->lookup_usergroups(domain, mem_ctx, user_rid, num_groups, user_gids);
/* and save it */
- refresh_sequence_number(domain, False);
+ refresh_sequence_number(domain, True);
centry = centry_start(domain, status);
- if (!centry)
- goto skip_save;
+ if (!centry) goto skip_save;
centry_put_uint32(centry, *num_groups);
for (i=0; i<(*num_groups); i++) {
- centry_put_sid(centry, (*user_gids)[i]);
+ centry_put_uint32(centry, (*user_gids)[i]);
}
- centry_end(centry, "UG/%s", sid_to_string(sid_string, user_sid));
+ centry_end(centry, "UG/%s/%d", domain->name, user_rid);
centry_free(centry);
skip_save:
@@ -1188,54 +823,46 @@ skip_save:
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
+ uint32 group_rid, uint32 *num_names,
+ uint32 **rid_mem, char ***names,
uint32 **name_types)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i;
- fstring sid_string;
+ int i;
- if (!cache->tdb)
- goto do_query;
+ if (!cache->tdb) goto do_query;
- centry = wcache_fetch(cache, domain, "GM/%s", sid_to_string(sid_string, group_sid));
- if (!centry)
- goto do_query;
+ centry = wcache_fetch(cache, domain, "GM/%s/%d", domain->name, group_rid);
+ if (!centry) goto do_query;
*num_names = centry_uint32(centry);
- if (*num_names == 0)
- goto do_cached;
+ if (*num_names == 0) goto do_cached;
- (*sid_mem) = talloc(mem_ctx, sizeof(**sid_mem) * (*num_names));
+ (*rid_mem) = talloc(mem_ctx, sizeof(**rid_mem) * (*num_names));
(*names) = talloc(mem_ctx, sizeof(**names) * (*num_names));
(*name_types) = talloc(mem_ctx, sizeof(**name_types) * (*num_names));
- if (! (*sid_mem) || ! (*names) || ! (*name_types)) {
+ if (! (*rid_mem) || ! (*names) || ! (*name_types)) {
smb_panic("lookup_groupmem out of memory");
}
for (i=0; i<(*num_names); i++) {
- (*sid_mem)[i] = centry_sid(centry, mem_ctx);
+ (*rid_mem)[i] = centry_uint32(centry);
(*names)[i] = centry_string(centry, mem_ctx);
(*name_types)[i] = centry_uint32(centry);
}
do_cached:
status = centry->status;
-
- DEBUG(10,("lookup_groupmem: [Cached] - cached info for domain %s status %s\n",
- domain->name, get_friendly_nt_error_msg(status) ));
-
centry_free(centry);
return status;
do_query:
(*num_names) = 0;
- (*sid_mem) = NULL;
+ (*rid_mem) = NULL;
(*names) = NULL;
(*name_types) = NULL;
@@ -1244,24 +871,20 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
- DEBUG(10,("lookup_groupmem: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
-
- status = domain->backend->lookup_groupmem(domain, mem_ctx, group_sid, num_names,
- sid_mem, names, name_types);
+ status = cache->backend->lookup_groupmem(domain, mem_ctx, group_rid, num_names,
+ rid_mem, names, name_types);
/* and save it */
- refresh_sequence_number(domain, False);
+ refresh_sequence_number(domain, True);
centry = centry_start(domain, status);
- if (!centry)
- goto skip_save;
+ if (!centry) goto skip_save;
centry_put_uint32(centry, *num_names);
for (i=0; i<(*num_names); i++) {
- centry_put_sid(centry, (*sid_mem)[i]);
+ centry_put_uint32(centry, (*rid_mem)[i]);
centry_put_string(centry, (*names)[i]);
centry_put_uint32(centry, (*name_types)[i]);
}
- centry_end(centry, "GM/%s", sid_to_string(sid_string, group_sid));
+ centry_end(centry, "GM/%s/%d", domain->name, group_rid);
centry_free(centry);
skip_save:
@@ -1283,81 +906,22 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
- char ***alt_names,
DOM_SID **dom_sids)
{
- get_cache(domain);
-
- DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
+ struct winbind_cache *cache = get_cache(domain);
/* we don't cache this call */
- return domain->backend->trusted_domains(domain, mem_ctx, num_domains,
- names, alt_names, dom_sids);
+ return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
+ names, dom_sids);
}
/* find the domain sid */
static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
{
- get_cache(domain);
-
- DEBUG(10,("domain_sid: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
-
- /* we don't cache this call */
- return domain->backend->domain_sid(domain, sid);
-}
-
-/* find the alternate names for the domain, if any */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- get_cache(domain);
-
- DEBUG(10,("alternate_name: [Cached] - doing backend query for info for domain %s\n",
- domain->name ));
+ struct winbind_cache *cache = get_cache(domain);
/* we don't cache this call */
- return domain->backend->alternate_name(domain);
-}
-
-/* Invalidate cached user and group lists coherently */
-
-static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- if (strncmp(kbuf.dptr, "UL/", 3) == 0 ||
- strncmp(kbuf.dptr, "GL/", 3) == 0)
- tdb_delete(the_tdb, kbuf);
-
- return 0;
-}
-
-/* Invalidate the getpwnam and getgroups entries for a winbindd domain */
-
-void wcache_invalidate_samlogon(struct winbindd_domain *domain,
- NET_USER_INFO_3 *info3)
-{
- struct winbind_cache *cache;
-
- if (!domain)
- return;
-
- cache = get_cache(domain);
- netsamlogon_clear_cached_user(cache->tdb, info3);
-}
-
-void wcache_invalidate_cache(void)
-{
- struct winbindd_domain *domain;
-
- for (domain = domain_list(); domain; domain = domain->next) {
- struct winbind_cache *cache = get_cache(domain);
-
- DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
- "entries for %s\n", domain->name));
- if (cache)
- tdb_traverse(cache->tdb, traverse_fn, NULL);
- }
+ return cache->backend->domain_sid(domain, sid);
}
/* the ADS backend methods are exposed via this structure */
@@ -1365,7 +929,6 @@ struct winbindd_methods cache_methods = {
True,
query_user_list,
enum_dom_groups,
- enum_local_groups,
name_to_sid,
sid_to_name,
query_user,
@@ -1373,6 +936,5 @@ struct winbindd_methods cache_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid,
- alternate_name
+ domain_sid
};
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 56810f221ef..fb406adcf7c 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -4,7 +4,6 @@
Winbind daemon connection manager
Copyright (C) Tim Potter 2001
- Copyright (C) Andrew Bartlett 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -51,17 +50,16 @@
- I'm pretty annoyed by all the make_nmb_name() stuff. It should be
moved down into another function.
+ - There needs to be a utility function in libsmb/namequery.c that does
+ cm_get_dc_name()
+
- Take care when destroying cli_structs as they can be shared between
various sam handles.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
/* Global list of connections. Initially a DLIST but can become a hash
table or whatever later. */
@@ -70,13 +68,107 @@ struct winbindd_cm_conn {
fstring domain;
fstring controller;
fstring pipe_name;
- size_t mutex_ref_count;
struct cli_state *cli;
POLICY_HND pol;
};
static struct winbindd_cm_conn *cm_conns = NULL;
+/* Get a domain controller name */
+
+static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+{
+ struct in_addr *ip_list = NULL, dc_ip, exclude_ip;
+ int count, i;
+
+ zero_ip(&exclude_ip);
+ /* Lookup domain controller name. Try the real PDC first to avoid
+ SAM sync delays */
+ if (get_dc_list(True, domain, &ip_list, &count)) {
+ if (name_status_find(domain, 0x1c, 0x20, ip_list[0], srv_name)) {
+ dc_ip = ip_list[0];
+ goto done;
+ }
+ /* Didn't get name, remember not to talk to this DC. */
+ exclude_ip = ip_list[0];
+ SAFE_FREE(ip_list);
+ }
+
+ if (!get_dc_list(False, domain, &ip_list, &count)) {
+ DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
+ return False;
+ }
+
+ /* Remove the entry we've already failed with (should be the PDC). */
+
+ for (i = 0; i < count; i++) {
+ if (ip_equal( exclude_ip, ip_list[i]))
+ zero_ip(&ip_list[i]);
+ }
+
+ /* Pick a nice close server */
+ /* Look for DC on local net */
+
+ for (i = 0; i < count; i++) {
+ if (is_zero_ip(ip_list[i]))
+ continue;
+
+ if (!is_local_net(ip_list[i]))
+ continue;
+
+ if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+ dc_ip = ip_list[i];
+ goto done;
+ }
+ zero_ip(&ip_list[i]);
+ }
+
+ /*
+ * Secondly try and contact a random PDC/BDC.
+ */
+
+ i = (sys_random() % count);
+
+ if (!is_zero_ip(ip_list[i]) &&
+ name_status_find(domain, 0x1c, 0x20,
+ ip_list[i], srv_name)) {
+ dc_ip = ip_list[i];
+ goto done;
+ }
+ zero_ip(&ip_list[i]); /* Tried and failed. */
+
+ /* Finally return first DC that we can contact */
+
+ for (i = 0; i < count; i++) {
+ if (is_zero_ip(ip_list[i]))
+ continue;
+
+ if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+ dc_ip = ip_list[i];
+ goto done;
+ }
+ }
+
+ SAFE_FREE(ip_list);
+
+ /* No-one to talk to )-: */
+ return False; /* Boo-hoo */
+
+ done:
+ /* We have the netbios name and IP address of a domain controller.
+ Ideally we should sent a SAMLOGON request to determine whether
+ the DC is alive and kicking. If we can catch a dead DC before
+ performing a cli_connect() we can avoid a 30-second timeout. */
+
+ DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
+ inet_ntoa(dc_ip), domain));
+
+ *ip_out = dc_ip;
+
+ SAFE_FREE(ip_list);
+
+ return True;
+}
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
@@ -93,16 +185,11 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
*password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
if (*username && **username) {
-
- if (!*domain || !**domain)
+ if (!*domain || !**domain) {
*domain = smb_xstrdup(lp_workgroup());
+ }
- if (!*password || !**password)
- *password = smb_xstrdup("");
-
- DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
- *domain, *username));
-
+ DEBUG(3, ("IPC$ connections done by user %s\\%s\n", *domain, *username));
} else {
DEBUG(3, ("IPC$ connections done anonymously\n"));
*username = smb_xstrdup("");
@@ -111,213 +198,140 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
}
}
-/*
- setup for schannel on any pipes opened on this connection
-*/
-static NTSTATUS setup_schannel(struct cli_state *cli)
+/* Open a new smb pipe connection to a DC on a given domain. Cache
+ negative creation attempts so we don't try and connect to broken
+ machines too often. */
+
+#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
+
+struct failed_connection_cache {
+ fstring domain_name;
+ fstring controller;
+ time_t lookup_time;
+ NTSTATUS nt_status;
+ struct failed_connection_cache *prev, *next;
+};
+
+static struct failed_connection_cache *failed_connection_cache;
+
+/* Add an entry to the failed conneciton cache */
+
+static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn,
+ NTSTATUS result)
{
- NTSTATUS ret;
- uchar trust_password[16];
- uint32 sec_channel_type;
+ struct failed_connection_cache *fcc;
+
+ SMB_ASSERT(!NT_STATUS_IS_OK(result));
+
+ /* Check we already aren't in the cache */
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password,
- NULL, &sec_channel_type)) {
- return NT_STATUS_UNSUCCESSFUL;
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+ if (strequal(fcc->domain_name, new_conn->domain)) {
+ DEBUG(10, ("domain %s already tried and failed\n",
+ fcc->domain_name));
+ return;
+ }
}
- ret = cli_nt_setup_netsec(cli, sec_channel_type,
- AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN,
- trust_password);
+ /* Create negative lookup cache entry for this domain and controller */
- return ret;
+ if (!(fcc = (struct failed_connection_cache *)
+ malloc(sizeof(struct failed_connection_cache)))) {
+ DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
+ return;
+ }
+
+ ZERO_STRUCTP(fcc);
+
+ fstrcpy(fcc->domain_name, new_conn->domain);
+ fstrcpy(fcc->controller, new_conn->controller);
+ fcc->lookup_time = time(NULL);
+ fcc->nt_status = result;
+
+ DLIST_ADD(failed_connection_cache, fcc);
}
-
+
/* Open a connction to the remote server, cache failures for 30 seconds */
-static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
+static NTSTATUS cm_open_connection(const char *domain,const char *pipe_name,
struct winbindd_cm_conn *new_conn)
{
+ struct failed_connection_cache *fcc;
+ extern pstring global_myname;
NTSTATUS result;
- char *machine_password;
- char *machine_krb5_principal, *ipc_username, *ipc_domain, *ipc_password;
+ char *ipc_username, *ipc_domain, *ipc_password;
struct in_addr dc_ip;
- int i;
- BOOL retry = True;
ZERO_STRUCT(dc_ip);
- fstrcpy(new_conn->domain, domain->name);
+ fstrcpy(new_conn->domain, domain);
+ fstrcpy(new_conn->pipe_name, pipe_name);
- /* connection failure cache has been moved inside of get_dc_name
- so we can deal with half dead DC's --jerry */
+ /* Look for a domain controller for this domain. Negative results
+ are cached so don't bother applying the caching for this
+ function just yet. */
- if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL,
- new_conn->controller, &dc_ip)) {
+ if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(domain->name, "", result);
+ add_failed_connection_entry(new_conn, result);
return result;
}
- /* Initialise SMB connection */
- fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
-
-/* grab stored passwords */
- machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
- SAFE_FREE(machine_password);
- return NT_STATUS_NO_MEMORY;
- }
+ /* Return false if we have tried to look up this domain and netbios
+ name before and failed. */
- cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
-
- for (i = 0; retry && (i < 3); i++) {
- BOOL got_mutex;
- if (!(got_mutex = secrets_named_mutex(new_conn->controller, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
- DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller));
- result = NT_STATUS_POSSIBLE_DEADLOCK;
- continue;
- }
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
- new_conn->cli = NULL;
- result = cli_start_connection(&new_conn->cli, global_myname(),
- new_conn->controller,
- &dc_ip, 0, Undefined,
- CLI_FULL_CONNECTION_USE_KERBEROS,
- &retry);
+ if (!(strequal(domain, fcc->domain_name) &&
+ strequal(new_conn->controller, fcc->controller)))
+ continue; /* Not our domain */
- if (NT_STATUS_IS_OK(result)) {
+ if ((time(NULL) - fcc->lookup_time) >
+ FAILED_CONNECTION_CACHE_TIMEOUT) {
- /* reset the error code */
- result = NT_STATUS_UNSUCCESSFUL;
+ /* Cache entry has expired, delete it */
- /* Krb5 session */
-
- if ((lp_security() == SEC_ADS)
- && (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) {
- ADS_STATUS ads_status;
- new_conn->cli->use_kerberos = True;
- DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n",
- new_conn->controller, global_myname(), machine_krb5_principal));
-
- ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
- machine_password,
- lp_workgroup());
- if (!ADS_ERR_OK(ads_status)) {
- DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status)));
- result = ads_ntstatus(ads_status);
- } else {
- result = NT_STATUS_OK;
- }
- }
- new_conn->cli->use_kerberos = False;
-
- /* only do this is we have a username/password for thr IPC$ connection */
-
- if ( !NT_STATUS_IS_OK(result)
- && new_conn->cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
- && strlen(ipc_username) )
- {
- DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
- new_conn->controller, global_myname(), ipc_domain, ipc_username));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, ipc_username,
- ipc_password, strlen(ipc_password)+1,
- ipc_password, strlen(ipc_password)+1,
- ipc_domain)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* anonymous is all that is left if we get to here */
-
- if (!NT_STATUS_IS_OK(result)) {
-
- DEBUG(5, ("anonymous connection attempt to %s from %s\n",
- new_conn->controller, global_myname()));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, "", NULL, 0, NULL, 0, ""))
- {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed anonymous session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
-
- }
+ DEBUG(10, ("cm_open_connection cache entry expired for %s, %s\n", domain, new_conn->controller));
- if (NT_STATUS_IS_OK(result) && !cli_send_tconX(new_conn->cli, "IPC$", "IPC",
- "", 0)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
- cli_shutdown(new_conn->cli);
- if (NT_STATUS_IS_OK(result)) {
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
- }
+ DLIST_REMOVE(failed_connection_cache, fcc);
+ free(fcc);
- if (NT_STATUS_IS_OK(result)) {
- struct ntuser_creds creds;
- init_creds(&creds, ipc_username, ipc_domain, ipc_password);
- cli_init_creds(new_conn->cli, &creds);
+ break;
}
- if (got_mutex)
- secrets_named_mutex_release(new_conn->controller);
+ /* The timeout hasn't expired yet so return false */
- if (NT_STATUS_IS_OK(result))
- break;
- }
+ DEBUG(10, ("returning negative open_connection_cache entry for %s, %s\n", domain, new_conn->controller));
- /* try and use schannel if possible, but continue anyway if it
- failed. This allows existing setups to continue working,
- while solving the win2003 '100 user' limit for systems that
- are joined properly */
- if (NT_STATUS_IS_OK(result)) {
- NTSTATUS status = setup_schannel(new_conn->cli);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3,("schannel refused - continuing without schannel (%s)\n",
- nt_errstr(status)));
- }
+ result = fcc->nt_status;
+ SMB_ASSERT(!NT_STATUS_IS_OK(result));
+ return result;
}
+ /* Initialise SMB connection */
+
+ cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
+
+ DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
+ new_conn->controller, global_myname, ipc_domain, ipc_username));
+
+ result = cli_full_connection(&(new_conn->cli), global_myname, new_conn->controller,
+ &dc_ip, 0, "IPC$",
+ "IPC", ipc_username, ipc_domain,
+ ipc_password, strlen(ipc_password));
+
SAFE_FREE(ipc_username);
SAFE_FREE(ipc_domain);
SAFE_FREE(ipc_password);
- SAFE_FREE(machine_password);
- SAFE_FREE(machine_krb5_principal);
if (!NT_STATUS_IS_OK(result)) {
- add_failed_connection_entry(domain->name, new_conn->controller, result);
+ add_failed_connection_entry(new_conn, result);
return result;
}
- /* set the domain if empty; needed for schannel connections */
- if ( !*new_conn->cli->domain )
- fstrcpy( new_conn->cli->domain, domain->name );
-
-
- if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
+ if (!cli_nt_session_open (new_conn->cli, pipe_name)) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
- /*
- * only cache a failure if we are not trying to open the
- * **win2k** specific lsarpc UUID. This could be an NT PDC
- * and therefore a failure is normal. This should probably
- * be abstracted to a check for 2k specific pipes and wondering
- * if the PDC is an NT4 box. but since there is only one 2k
- * specific UUID right now, i'm not going to bother. --jerry
- */
- if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(domain->name, new_conn->controller, result);
+ add_failed_connection_entry(new_conn, result);
cli_shutdown(new_conn->cli);
return result;
}
@@ -325,43 +339,26 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
return NT_STATUS_OK;
}
-/************************************************************************
- Wrapper around statuc cm_open_connection to retreive a freshly
- setup cli_state struct
-************************************************************************/
-
-NTSTATUS cm_fresh_connection(struct winbindd_domain *domain, const int pipe_index,
- struct cli_state **cli)
-{
- NTSTATUS result;
- struct winbindd_cm_conn conn;
-
- result = cm_open_connection( domain, pipe_index, &conn );
-
- if ( NT_STATUS_IS_OK(result) )
- *cli = conn.cli;
-
- return result;
-}
-
/* Return true if a connection is still alive */
static BOOL connection_ok(struct winbindd_cm_conn *conn)
{
if (!conn) {
- smb_panic("Invalid parameter passed to connection_ok(): conn was NULL!\n");
+ smb_panic("Invalid paramater passed to conneciton_ok(): conn was NULL!\n");
return False;
}
if (!conn->cli) {
- DEBUG(3, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
+ DEBUG(0, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
conn->controller, conn->domain, conn->pipe_name));
+ smb_panic("connection_ok: conn->cli was null!");
return False;
}
if (!conn->cli->initialised) {
- DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
+ DEBUG(0, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
conn->controller, conn->domain, conn->pipe_name));
+ smb_panic("connection_ok: conn->cli->initialised is False!");
return False;
}
@@ -374,192 +371,52 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn)
return True;
}
-/* Search the cache for a connection. If there is a broken one,
- shut it down properly and return NULL. */
+/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
-static void find_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
- struct winbindd_cm_conn **conn_out)
+static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out)
{
- struct winbindd_cm_conn *conn;
+ struct winbindd_cm_conn *conn, conn_temp;
+ NTSTATUS result;
- for (conn = cm_conns; conn; ) {
- if (strequal(conn->domain, domain->name) &&
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
strequal(conn->pipe_name, pipe_name)) {
if (!connection_ok(conn)) {
- /* Dead connection - remove it. */
- struct winbindd_cm_conn *conn_temp = conn->next;
- if (conn->cli)
+ if (conn->cli) {
cli_shutdown(conn->cli);
+ }
+ conn_temp.next = conn->next;
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
- conn = conn_temp; /* Keep the loop moving */
- continue;
+ conn = &conn_temp; /* Just to keep the loop moving */
} else {
break;
}
}
- conn = conn->next;
- }
-
- *conn_out = conn;
-}
-
-/* Initialize a new connection up to the RPC BIND. */
-
-static NTSTATUS new_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
- struct winbindd_cm_conn **conn_out)
-{
- struct winbindd_cm_conn *conn;
- NTSTATUS result;
-
- if (!(conn = malloc(sizeof(*conn))))
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(conn);
-
- if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) {
- DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
- domain->name, pipe_name, nt_errstr(result)));
- SAFE_FREE(conn);
- return result;
}
- DLIST_ADD(cm_conns, conn);
-
- *conn_out = conn;
- return NT_STATUS_OK;
-}
-
-/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
-
-static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const char *pipe_name,
- struct winbindd_cm_conn **conn_out)
-{
- find_cm_connection(domain, pipe_name, conn_out);
-
- if (*conn_out != NULL)
- return NT_STATUS_OK;
-
- return new_cm_connection(domain, pipe_name, conn_out);
-}
-
-/**********************************************************************************
- We can 'sense' certain things about the DC by it's replies to certain questions.
-
- This tells us if this particular remote server is Active Directory, and if it is
- native mode.
-**********************************************************************************/
-
-void set_dc_type_and_flags( struct winbindd_domain *domain )
-{
- NTSTATUS result;
- struct winbindd_cm_conn conn;
- DS_DOMINFO_CTR ctr;
- TALLOC_CTX *mem_ctx = NULL;
-
- ZERO_STRUCT( conn );
- ZERO_STRUCT( ctr );
-
- domain->native_mode = False;
- domain->active_directory = False;
- if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
- DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
- domain->name, nt_errstr(result)));
- return;
- }
-
- if ( conn.cli ) {
- if ( !NT_STATUS_IS_OK(cli_ds_getprimarydominfo( conn.cli,
- conn.cli->mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr)) ) {
- goto done;
- }
- }
-
- if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING)
- && !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
- domain->native_mode = True;
-
- /* Cheat - shut down the DS pipe, and open LSA */
-
- cli_nt_session_close(conn.cli);
-
- if ( cli_nt_session_open (conn.cli, PI_LSARPC) ) {
- char *domain_name = NULL;
- char *dns_name = NULL;
- DOM_SID *dom_sid = NULL;
-
- mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n", domain->name);
- if (!mem_ctx) {
- DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
- return;
- }
-
- result = cli_lsa_open_policy2(conn.cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &conn.pol);
+ if (!conn) {
+ if (!(conn = (struct winbindd_cm_conn *) malloc(sizeof(struct winbindd_cm_conn))))
+ return NT_STATUS_NO_MEMORY;
- if (NT_STATUS_IS_OK(result)) {
- /* This particular query is exactly what Win2k clients use
- to determine that the DC is active directory */
- result = cli_lsa_query_info_policy2(conn.cli, mem_ctx,
- &conn.pol,
- 12, &domain_name,
- &dns_name, NULL,
- NULL, &dom_sid);
- }
-
- if (NT_STATUS_IS_OK(result)) {
- if (domain_name)
- fstrcpy(domain->name, domain_name);
-
- if (dns_name)
- fstrcpy(domain->alt_name, dns_name);
-
- if (dom_sid)
- sid_copy(&domain->sid, dom_sid);
-
- domain->active_directory = True;
- } else {
-
- result = cli_lsa_open_policy(conn.cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &conn.pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_query_info_policy(conn.cli, mem_ctx,
- &conn.pol, 5, &domain_name,
- &dom_sid);
-
- if (NT_STATUS_IS_OK(result)) {
- if (domain_name)
- fstrcpy(domain->name, domain_name);
-
- if (dom_sid)
- sid_copy(&domain->sid, dom_sid);
- }
+ ZERO_STRUCTP(conn);
+
+ if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, pipe_name, conn))) {
+ DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
+ domain, pipe_name, nt_errstr(result)));
+ SAFE_FREE(conn);
+ return result;
}
+ DLIST_ADD(cm_conns, conn);
}
-done:
-
- /* close the connection; no other calls use this pipe and it is called only
- on reestablishing the domain list --jerry */
-
- if ( conn.cli )
- cli_shutdown( conn.cli );
-
- talloc_destroy(mem_ctx);
-
- return;
+ *conn_out = conn;
+ return NT_STATUS_OK;
}
-
-
/* Return a LSA policy handle on a domain */
-NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
+NTSTATUS cm_get_lsa_handle(char *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -572,7 +429,7 @@ NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
return result;
/* This *shitty* code needs scrapping ! JRA */
-
+
if (policy_handle_is_valid(&conn->pol)) {
hnd.pol = conn->pol;
hnd.cli = conn->cli;
@@ -598,6 +455,7 @@ NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
cli_shutdown(conn->cli);
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
+
return result;
}
}
@@ -612,7 +470,7 @@ NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
/* Return a SAM policy handle on a domain */
-NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
+NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -625,23 +483,23 @@ NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
return result;
/* This *shitty* code needs scrapping ! JRA */
-
+
if (policy_handle_is_valid(&conn->pol)) {
hnd.pol = conn->pol;
hnd.cli = conn->cli;
-
+
*return_hnd = &hnd;
return NT_STATUS_OK;
}
-
+
result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
des_access, &conn->pol);
if (!NT_STATUS_IS_OK(result)) {
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
-
+
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn)))
return result;
@@ -650,11 +508,11 @@ NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
}
if (!NT_STATUS_IS_OK(result)) {
-
+
cli_shutdown(conn->cli);
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
-
+
return result;
}
}
@@ -667,75 +525,277 @@ NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu
return NT_STATUS_OK;
}
-/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
- netlogon pipe as no handle is returned. */
+#if 0 /* This code now *well* out of date */
-NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain,
- const unsigned char *trust_passwd,
- uint32 sec_channel_type,
- BOOL fresh,
- struct cli_state **cli)
+/* Return a SAM domain policy handle on a domain */
+
+CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid)
{
- NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- struct winbindd_cm_conn *conn;
- fstring lock_name;
- BOOL got_mutex;
+ struct winbindd_cm_conn *conn, *basic_conn = NULL;
+ static CLI_POLICY_HND hnd;
+ NTSTATUS result;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- if (!cli)
- return NT_STATUS_INVALID_PARAMETER;
+ /* Look for existing connections */
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM) {
+
+ if (!connection_ok(conn)) {
+ /* Shutdown cli? Free conn? Allow retry of DC? */
+ DLIST_REMOVE(cm_conns, conn);
+ return NULL;
+ }
+
+ goto ok;
+ }
+ }
+
+ /* Create a basic handle to open a domain handle from */
+
+ if (!cm_get_sam_handle(domain))
+ return False;
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_BASIC)
+ basic_conn = conn;
+ }
+
+ if (!(conn = (struct winbindd_cm_conn *)
+ malloc(sizeof(struct winbindd_cm_conn))))
+ return NULL;
+
+ ZERO_STRUCTP(conn);
+
+ fstrcpy(conn->domain, basic_conn->domain);
+ fstrcpy(conn->controller, basic_conn->controller);
+ fstrcpy(conn->pipe_name, basic_conn->pipe_name);
- /* Open an initial conection - keep the mutex. */
+ conn->pipe_data.samr.pipe_type = SAM_PIPE_DOM;
+ conn->cli = basic_conn->cli;
- find_cm_connection(domain, PIPE_NETLOGON, &conn);
+ result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx,
+ &basic_conn->pol, des_access,
+ domain_sid, &conn->pol);
- if ( fresh && (conn != NULL) ) {
- cli_shutdown(conn->cli);
- conn->cli = NULL;
+ if (!NT_STATUS_IS_OK(result))
+ return NULL;
+
+ /* Add to list */
- conn = NULL;
+ DLIST_ADD(cm_conns, conn);
+
+ ok:
+ hnd.pol = conn->pol;
+ hnd.cli = conn->cli;
+
+ return &hnd;
+}
- /* purge connection from cache */
- find_cm_connection(domain, PIPE_NETLOGON, &conn);
- if (conn != NULL) {
- DEBUG(0,("Could not purge connection\n"));
- return NT_STATUS_UNSUCCESSFUL;
+/* Return a SAM policy handle on a domain user */
+
+CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
+ uint32 user_rid)
+{
+ struct winbindd_cm_conn *conn, *basic_conn = NULL;
+ static CLI_POLICY_HND hnd;
+ NTSTATUS result;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+
+ /* Look for existing connections */
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_USER &&
+ conn->pipe_data.samr.rid == user_rid) {
+
+ if (!connection_ok(conn)) {
+ /* Shutdown cli? Free conn? Allow retry of DC? */
+ DLIST_REMOVE(cm_conns, conn);
+ return NULL;
+ }
+
+ goto ok;
}
}
- if (conn != NULL) {
- *cli = conn->cli;
- return NT_STATUS_OK;
+ /* Create a domain handle to open a user handle from */
+
+ if (!cm_get_sam_dom_handle(domain, domain_sid))
+ return NULL;
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
+ basic_conn = conn;
}
+
+ if (!basic_conn) {
+ DEBUG(0, ("No domain sam handle was created!\n"));
+ return NULL;
+ }
+
+ if (!(conn = (struct winbindd_cm_conn *)
+ malloc(sizeof(struct winbindd_cm_conn))))
+ return NULL;
+
+ ZERO_STRUCTP(conn);
+
+ fstrcpy(conn->domain, basic_conn->domain);
+ fstrcpy(conn->controller, basic_conn->controller);
+ fstrcpy(conn->pipe_name, basic_conn->pipe_name);
+
+ conn->pipe_data.samr.pipe_type = SAM_PIPE_USER;
+ conn->cli = basic_conn->cli;
+ conn->pipe_data.samr.rid = user_rid;
- result = new_cm_connection(domain, PIPE_NETLOGON, &conn);
+ result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx,
+ &basic_conn->pol, des_access, user_rid,
+ &conn->pol);
if (!NT_STATUS_IS_OK(result))
- return result;
-
- fstr_sprintf(lock_name, "NETLOGON\\%s", conn->controller);
+ return NULL;
+
+ /* Add to list */
+
+ DLIST_ADD(cm_conns, conn);
+
+ ok:
+ hnd.pol = conn->pol;
+ hnd.cli = conn->cli;
+
+ return &hnd;
+}
+
+/* Return a SAM policy handle on a domain group */
+
+CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
+ uint32 group_rid)
+{
+ struct winbindd_cm_conn *conn, *basic_conn = NULL;
+ static CLI_POLICY_HND hnd;
+ NTSTATUS result;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+
+ /* Look for existing connections */
- if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
- DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_GROUP &&
+ conn->pipe_data.samr.rid == group_rid) {
+
+ if (!connection_ok(conn)) {
+ /* Shutdown cli? Free conn? Allow retry of DC? */
+ DLIST_REMOVE(cm_conns, conn);
+ return NULL;
+ }
+
+ goto ok;
+ }
+ }
+
+ /* Create a domain handle to open a user handle from */
+
+ if (!cm_get_sam_dom_handle(domain, domain_sid))
+ return NULL;
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_SAMR) &&
+ conn->pipe_data.samr.pipe_type == SAM_PIPE_DOM)
+ basic_conn = conn;
}
- if ( sec_channel_type == SEC_CHAN_DOMAIN )
- fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup());
-
- /* This must be the remote domain (not ours) for schannel */
+ if (!basic_conn) {
+ DEBUG(0, ("No domain sam handle was created!\n"));
+ return NULL;
+ }
- fstrcpy( conn->cli->domain, domain->name);
+ if (!(conn = (struct winbindd_cm_conn *)
+ malloc(sizeof(struct winbindd_cm_conn))))
+ return NULL;
- result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
+ ZERO_STRUCTP(conn);
+
+ fstrcpy(conn->domain, basic_conn->domain);
+ fstrcpy(conn->controller, basic_conn->controller);
+ fstrcpy(conn->pipe_name, basic_conn->pipe_name);
- if (got_mutex)
- secrets_named_mutex_release(lock_name);
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_shutdown(conn->cli);
- DLIST_REMOVE(cm_conns, conn);
- SAFE_FREE(conn);
+ conn->pipe_data.samr.pipe_type = SAM_PIPE_GROUP;
+ conn->cli = basic_conn->cli;
+ conn->pipe_data.samr.rid = group_rid;
+
+ result = cli_samr_open_group(conn->cli, conn->cli->mem_ctx,
+ &basic_conn->pol, des_access, group_rid,
+ &conn->pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ return NULL;
+
+ /* Add to list */
+
+ DLIST_ADD(cm_conns, conn);
+
+ ok:
+ hnd.pol = conn->pol;
+ hnd.cli = conn->cli;
+
+ return &hnd;
+}
+
+#endif
+
+/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
+ netlogon pipe as no handle is returned. */
+
+NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
+ struct cli_state **cli)
+{
+ NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ struct winbindd_cm_conn *conn;
+
+ if (!cli) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Open an initial conection */
+
+ if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn))) {
return result;
}
+
+ result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("error connecting to domain password server: %s\n",
+ nt_errstr(result)));
+
+ /* Hit the cache code again. This cleans out the old connection and gets a new one */
+ if (conn->cli->fd == -1) {
+ if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn))) {
+ return result;
+ }
+
+ /* Try again */
+ result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
+ }
+
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(conn->cli);
+ DLIST_REMOVE(cm_conns, conn);
+ SAFE_FREE(conn);
+ return result;
+ }
+ }
*cli = conn->cli;
@@ -782,15 +842,13 @@ void winbindd_cm_flush(void)
{
struct winbindd_cm_conn *conn, tmp;
- /* Flush connection cache */
-
for (conn = cm_conns; conn; conn = conn->next) {
if (!connection_ok(conn))
continue;
DEBUG(10, ("Closing connection to %s on %s\n",
- conn->pipe_name, conn->controller));
+ conn->pipe_name, conn->controller));
if (conn->cli)
cli_shutdown(conn->cli);
@@ -801,8 +859,4 @@ void winbindd_cm_flush(void)
SAFE_FREE(conn);
conn = &tmp;
}
-
- /* Flush failed connection cache */
-
- flush_negative_conn_cache();
}
diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c
deleted file mode 100644
index a9796afa367..00000000000
--- a/source/nsswitch/winbindd_dual.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind background daemon
-
- Copyright (C) Andrew Tridgell 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- the idea of the optional dual daemon mode is ot prevent slow domain
- responses from clagging up the rest of the system. When in dual
- daemon mode winbindd always responds to requests from cache if the
- request is in cache, and if the cached answer is stale then it asks
- the "dual daemon" to update the cache for that request
-
- */
-
-#include "includes.h"
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-extern BOOL opt_dual_daemon;
-BOOL background_process = False;
-int dual_daemon_pipe = -1;
-
-
-/* a list of requests ready to be sent to the dual daemon */
-struct dual_list {
- struct dual_list *next;
- char *data;
- int length;
- int offset;
-};
-
-static struct dual_list *dual_list;
-static struct dual_list *dual_list_end;
-
-/*
- setup a select() including the dual daemon pipe
- */
-int dual_select_setup(fd_set *fds, int maxfd)
-{
- if (dual_daemon_pipe == -1 ||
- !dual_list) {
- return maxfd;
- }
-
- FD_SET(dual_daemon_pipe, fds);
- if (dual_daemon_pipe > maxfd) {
- maxfd = dual_daemon_pipe;
- }
- return maxfd;
-}
-
-
-/*
- a hook called from the main winbindd select() loop to handle writes
- to the dual daemon pipe
-*/
-void dual_select(fd_set *fds)
-{
- int n;
-
- if (dual_daemon_pipe == -1 ||
- !dual_list ||
- !FD_ISSET(dual_daemon_pipe, fds)) {
- return;
- }
-
- n = sys_write(dual_daemon_pipe,
- &dual_list->data[dual_list->offset],
- dual_list->length - dual_list->offset);
-
- if (n <= 0) {
- /* the pipe is dead! fall back to normal operation */
- dual_daemon_pipe = -1;
- return;
- }
-
- dual_list->offset += n;
-
- if (dual_list->offset == dual_list->length) {
- struct dual_list *next;
- next = dual_list->next;
- free(dual_list->data);
- free(dual_list);
- dual_list = next;
- if (!dual_list) {
- dual_list_end = NULL;
- }
- }
-}
-
-/*
- send a request to the background daemon
- this is called for stale cached entries
-*/
-void dual_send_request(struct winbindd_cli_state *state)
-{
- struct dual_list *list;
-
- if (!background_process) return;
-
- list = malloc(sizeof(*list));
- if (!list) return;
-
- list->next = NULL;
- list->data = memdup(&state->request, sizeof(state->request));
- list->length = sizeof(state->request);
- list->offset = 0;
-
- if (!dual_list_end) {
- dual_list = list;
- dual_list_end = list;
- } else {
- dual_list_end->next = list;
- dual_list_end = list;
- }
-
- background_process = False;
-}
-
-
-/*
-the main dual daemon
-*/
-void do_dual_daemon(void)
-{
- int fdpair[2];
- struct winbindd_cli_state state;
-
- if (pipe(fdpair) != 0) {
- return;
- }
-
- ZERO_STRUCT(state);
- state.pid = getpid();
-
- dual_daemon_pipe = fdpair[1];
- state.sock = fdpair[0];
-
- if (fork() != 0) {
- close(fdpair[0]);
- return;
- }
- close(fdpair[1]);
-
- /* tdb needs special fork handling */
- if (tdb_reopen_all() == -1) {
- DEBUG(0,("tdb_reopen_all failed.\n"));
- _exit(0);
- }
-
- dual_daemon_pipe = -1;
- opt_dual_daemon = False;
-
- while (1) {
- /* free up any talloc memory */
- lp_talloc_free();
- main_loop_talloc_free();
-
- /* fetch a request from the main daemon */
- winbind_client_read(&state);
-
- if (state.finished) {
- /* we lost contact with our parent */
- exit(0);
- }
-
- /* process full rquests */
- if (state.read_buf_len == sizeof(state.request)) {
- DEBUG(4,("dual daemon request %d\n", (int)state.request.cmd));
-
- /* special handling for the stateful requests */
- switch (state.request.cmd) {
- case WINBINDD_GETPWENT:
- winbindd_setpwent(&state);
- break;
-
- case WINBINDD_GETGRENT:
- case WINBINDD_GETGRLST:
- winbindd_setgrent(&state);
- break;
- default:
- break;
- }
-
- winbind_process_packet(&state);
- SAFE_FREE(state.response.extra_data);
-
- free_getent_state(state.getpwent_state);
- free_getent_state(state.getgrent_state);
- state.getpwent_state = NULL;
- state.getgrent_state = NULL;
- }
- }
-}
-
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index e8cad897662..68c94659ad2 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -5,7 +5,6 @@
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
- Copyright (C) Gerald (Jerry) Carter 2003.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,42 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-extern BOOL opt_nocache;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/*********************************************************************
-*********************************************************************/
-
-static int gr_mem_buffer( char **buffer, char **members, int num_members )
-{
- int i;
- int len = 0;
- int idx = 0;
-
- if ( num_members == 0 ) {
- *buffer = NULL;
- return 0;
- }
-
- for ( i=0; i<num_members; i++ )
- len += strlen(members[i])+1;
-
- *buffer = (char*)smb_xmalloc(len);
- for ( i=0; i<num_members; i++ ) {
- snprintf( &(*buffer)[idx], len-idx, "%s,", members[i]);
- idx += strlen(members[i])+1;
- }
- /* terminate with NULL */
- (*buffer)[len-1] = '\0';
-
- return len;
-}
-
/***************************************************************
Empty static struct for negative caching.
****************************************************************/
@@ -81,56 +46,43 @@ static BOOL fill_grent(struct winbindd_gr *gr, const char *dom_name,
return True;
}
-/* Fill in the group membership field of a NT group given by group_sid */
+/* Fill in the group membership field of a NT group given by group_rid */
static BOOL fill_grent_mem(struct winbindd_domain *domain,
- DOM_SID *group_sid,
+ uint32 group_rid,
enum SID_NAME_USE group_name_type,
int *num_gr_mem, char **gr_mem, int *gr_mem_len)
{
- DOM_SID **sid_mem = NULL;
- uint32 num_names = 0;
+ uint32 *rid_mem = NULL, num_names = 0;
uint32 *name_types = NULL;
- unsigned int buf_len, buf_ndx, i;
+ int buf_len, buf_ndx, i;
char **names = NULL, *buf;
BOOL result = False;
TALLOC_CTX *mem_ctx;
NTSTATUS status;
- fstring sid_string;
- if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name)))
+ if (!(mem_ctx = talloc_init_named("fill_grent_mem(%s)", domain->name)))
return False;
/* Initialise group membership information */
- DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid)));
+ DEBUG(10, ("group %s rid 0x%x\n", domain ? domain->name : "NULL",
+ group_rid));
*num_gr_mem = 0;
-
- /* HACK ALERT!! This whole routine does not cope with group members
- * from more than one domain, ie aliases. Thus we have to work it out
- * ourselves in a special routine. */
-
- if (domain->internal)
- return fill_passdb_alias_grmem(domain, group_sid,
- num_gr_mem,
- gr_mem, gr_mem_len);
- if ( !((group_name_type==SID_NAME_DOM_GRP) ||
- ((group_name_type==SID_NAME_ALIAS) && domain->primary)) )
- {
- DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n",
- sid_to_string(sid_string, group_sid), domain->name,
- group_name_type));
+ if (group_name_type != SID_NAME_DOM_GRP) {
+ DEBUG(1, ("rid %d in domain %s isn't a " "domain group\n",
+ group_rid, domain->name));
goto done;
}
/* Lookup group members */
- status = domain->methods->lookup_groupmem(domain, mem_ctx, group_sid, &num_names,
- &sid_mem, &names, &name_types);
+ status = domain->methods->lookup_groupmem(domain, mem_ctx, group_rid, &num_names,
+ &rid_mem, &names, &name_types);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("could not lookup membership for group rid %s in domain %s (error: %s)\n",
- sid_to_string(sid_string, group_sid), domain->name, nt_errstr(status)));
+ DEBUG(1, ("could not lookup membership for group rid %d in domain %s\n",
+ group_rid, domain->name));
goto done;
}
@@ -139,7 +91,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
if (DEBUGLEVEL >= 10) {
for (i = 0; i < num_names; i++)
- DEBUG(10, ("\t%20s %s %d\n", names[i], sid_to_string(sid_string, sid_mem[i]),
+ DEBUG(10, ("\t%20s %x %d\n", names[i], rid_mem[i],
name_types[i]));
}
@@ -163,13 +115,18 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
occur in Universal groups on a Windows 2000 native mode
server. */
- /* make sure to allow machine accounts */
-
- if (name_types[i] != SID_NAME_USER && name_types[i] != SID_NAME_COMPUTER) {
+ if (name_types[i] != SID_NAME_USER) {
DEBUG(3, ("name %s isn't a domain user\n", the_name));
continue;
}
+ /* Don't bother with machine accounts */
+
+ if (the_name[strlen(the_name) - 1] == '$') {
+ DEBUG(10, ("%s is machine account\n", the_name));
+ continue;
+ }
+
/* Append domain name */
fill_domain_username(name, domain->name, the_name);
@@ -228,18 +185,15 @@ done:
enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
{
DOM_SID group_sid;
- WINBINDD_GR *grp;
struct winbindd_domain *domain;
enum SID_NAME_USE name_type;
+ uint32 group_rid;
fstring name_domain, name_group;
char *tmp, *gr_mem;
- int gr_mem_len;
gid_t gid;
+ int gr_mem_len;
- /* Ensure null termination */
- state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
-
- DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
state->request.data.groupname));
/* Parse domain and groupname */
@@ -247,48 +201,16 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
memset(name_group, 0, sizeof(fstring));
tmp = state->request.data.groupname;
-
- parse_domain_user(tmp, name_domain, name_group);
-
- /* if no domain or our local domain, then do a local tdb search */
-
- if ( (!*name_domain || strequal(name_domain, get_global_sam_name())) &&
- ((grp = wb_getgrnam(name_group)) != NULL) ) {
-
- char *buffer = NULL;
-
- memcpy( &state->response.data.gr, grp, sizeof(WINBINDD_GR) );
-
- gr_mem_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem );
-
- state->response.data.gr.gr_mem_ofs = 0;
- state->response.length += gr_mem_len;
- state->response.extra_data = buffer; /* give the memory away */
-
- return WINBINDD_OK;
- }
-
- /* if no domain or our local domain and no local tdb group, default to
- * our local domain for aliases */
-
- if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) {
- fstrcpy(name_domain, get_global_sam_name());
- }
+ if (!parse_domain_user(tmp, name_domain, name_group))
+ return WINBINDD_ERROR;
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(3, ("could not get domain sid for domain %s\n",
+ DEBUG(0, ("could not get domain sid for domain %s\n",
name_domain));
return WINBINDD_ERROR;
}
- /* should we deal with users for our domain? */
-
- if ( lp_winbind_trusted_domains_only() && domain->primary) {
- DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n",
- name_domain, name_group));
- return WINBINDD_ERROR;
- }
/* Get rid and name type from name */
@@ -299,23 +221,23 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- if ( !((name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) && domain->primary) ||
- ((name_type==SID_NAME_ALIAS) && domain->internal)) )
- {
+ if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
name_group, name_type));
return WINBINDD_ERROR;
}
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid, 0))) {
+ /* Fill in group structure */
+ sid_peek_rid(&group_sid, &group_rid);
+
+ if (!winbindd_idmap_get_gid_from_sid(&group_sid, &gid)) {
DEBUG(1, ("error converting unix gid to sid\n"));
return WINBINDD_ERROR;
}
if (!fill_grent(&state->response.data.gr, name_domain,
name_group, gid) ||
- !fill_grent_mem(domain, &group_sid, name_type,
+ !fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr.num_gr_mem,
&gr_mem, &gr_mem_len)) {
return WINBINDD_ERROR;
@@ -336,16 +258,16 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
- WINBINDD_GR *grp;
DOM_SID group_sid;
enum SID_NAME_USE name_type;
fstring dom_name;
fstring group_name;
+ uint32 group_rid;
int gr_mem_len;
char *gr_mem;
- DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.gid));
+ DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
+ state->request.data.gid));
/* Bug out if the gid isn't in the winbind range */
@@ -353,56 +275,37 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
(state->request.data.gid > server_state.gid_high))
return WINBINDD_ERROR;
- /* alway try local tdb lookup first */
- if ( ( grp=wb_getgrgid(state->request.data.gid)) != NULL ) {
- char *buffer = NULL;
-
- memcpy( &state->response.data.gr, grp, sizeof(WINBINDD_GR) );
-
- gr_mem_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem );
-
- state->response.data.gr.gr_mem_ofs = 0;
- state->response.length += gr_mem_len;
- state->response.extra_data = buffer; /* give away the memory */
-
- return WINBINDD_OK;
- }
-
/* Get rid from gid */
- if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid))) {
- DEBUG(1, ("could not convert gid %lu to rid\n",
- (unsigned long)state->request.data.gid));
- return WINBINDD_ERROR;
- }
- /* Get name from sid */
-
- if (!winbindd_lookup_name_by_sid(&group_sid, dom_name, group_name, &name_type)) {
- DEBUG(1, ("could not lookup sid\n"));
+ if (!winbindd_idmap_get_rid_from_gid(state->request.data.gid,
+ &group_rid, &domain)) {
+ DEBUG(1, ("could not convert gid %d to rid\n",
+ state->request.data.gid));
return WINBINDD_ERROR;
}
- /* Fill in group structure */
+ /* Get sid from gid */
- domain = find_domain_from_sid(&group_sid);
+ sid_copy(&group_sid, &domain->sid);
+ sid_append_rid(&group_sid, group_rid);
- if (!domain) {
- DEBUG(1,("Can't find domain from sid\n"));
+ if (!winbindd_lookup_name_by_sid(&group_sid, dom_name, group_name, &name_type)) {
+ DEBUG(1, ("could not lookup sid\n"));
return WINBINDD_ERROR;
}
- if ( !((name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) && domain->primary) ||
- ((name_type==SID_NAME_ALIAS) && domain->internal)) )
- {
+ if (!((name_type == SID_NAME_ALIAS) ||
+ (name_type == SID_NAME_DOM_GRP))) {
DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
group_name, name_type));
return WINBINDD_ERROR;
}
+ /* Fill in group structure */
+
if (!fill_grent(&state->response.data.gr, dom_name, group_name,
state->request.data.gid) ||
- !fill_grent_mem(domain, &group_sid, name_type,
+ !fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr.num_gr_mem,
&gr_mem, &gr_mem_len))
return WINBINDD_ERROR;
@@ -427,7 +330,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
- DEBUG(3, ("[%5lu]: setgrent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: setgrent\n", state->pid));
/* Check user has enabled this */
@@ -446,23 +349,18 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
for (domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
- /* don't add our domaina if we are a PDC or if we
- are a member of a Samba domain */
-
- if ( (IS_DC || lp_winbind_trusted_domains_only())
- && domain->primary )
- {
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
continue;
- }
-
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL) {
- DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n"));
+ malloc(sizeof(struct getent_state))) == NULL)
return WINBINDD_ERROR;
- }
ZERO_STRUCTP(domain_state);
@@ -473,8 +371,6 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
DLIST_ADD(state->getgrent_state, domain_state);
}
- state->getgrent_initialized = True;
-
return WINBINDD_OK;
}
@@ -482,10 +378,9 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5lu]: endgrent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: endgrent\n", state->pid));
free_getent_state(state->getgrent_state);
- state->getgrent_initialized = False;
state->getgrent_state = NULL;
return WINBINDD_OK;
@@ -498,24 +393,19 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
#define MAX_FETCH_SAM_ENTRIES 100
-static BOOL get_sam_group_entries(struct getent_state *ent)
+static BOOL get_sam_group_entries(struct getent_state *ent, NTSTATUS *status)
{
- NTSTATUS status;
uint32 num_entries;
- struct acct_info *name_list = NULL, *tmp_name_list = NULL;
+ struct acct_info *name_list = NULL;
TALLOC_CTX *mem_ctx;
BOOL result = False;
struct acct_info *sam_grp_entries = NULL;
struct winbindd_domain *domain;
+ NTSTATUS nt_status;
- if (ent->got_sam_entries)
+ if (!(mem_ctx = talloc_init_named("get_sam_group_entries(%s)",
+ ent->domain_name)))
return False;
-
- if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)",
- ent->domain_name))) {
- DEBUG(1, ("get_sam_group_entries: could not create talloc context!\n"));
- return False;
- }
/* Free any existing group info */
@@ -532,75 +422,33 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
goto done;
}
- /* always get the domain global groups */
-
- status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
+ nt_status = domain->methods->enum_dom_groups(
+ domain, mem_ctx, &num_entries, &sam_grp_entries);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s\n", nt_errstr(status)));
- result = False;
- goto done;
- }
+ if (status && !NT_STATUS_IS_OK(nt_status))
+ *status = nt_status;
/* Copy entries into return buffer */
if (num_entries) {
- if ( !(name_list = malloc(sizeof(struct acct_info) * num_entries)) ) {
- DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n",
- num_entries));
- result = False;
- goto done;
- }
- memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) );
+ name_list = malloc(sizeof(struct acct_info) * num_entries);
+ memcpy(name_list, sam_grp_entries,
+ num_entries * sizeof(struct acct_info));
}
ent->num_sam_entries = num_entries;
-
- /* get the domain local groups if we are a member of a native win2k domain
- and are not using LDAP to get the groups */
-
- if ( ( lp_security() != SEC_ADS && domain->native_mode
- && domain->primary) || domain->internal )
- {
- DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
-
- status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
-
- if ( !NT_STATUS_IS_OK(status) ) {
- DEBUG(3,("get_sam_group_entries: Failed to enumerate domain local groups!\n"));
- num_entries = 0;
- }
- else
- DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries));
-
- /* Copy entries into return buffer */
-
- if ( num_entries ) {
- if ( !(tmp_name_list = Realloc( name_list, sizeof(struct acct_info) * (ent->num_sam_entries+num_entries))) )
- {
- DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n",
- num_entries));
- result = False;
- SAFE_FREE( name_list );
- goto done;
- }
-
- name_list = tmp_name_list;
-
- memcpy( &name_list[ent->num_sam_entries], sam_grp_entries,
- num_entries * sizeof(struct acct_info) );
- }
-
- ent->num_sam_entries += num_entries;
- }
-
/* Fill in remaining fields */
ent->sam_entries = name_list;
ent->sam_entry_index = 0;
- result = (ent->num_sam_entries > 0);
+ /* Return false if we got an error or no sam entries, true otherwise */
+
+ if (!NT_STATUS_IS_OK(nt_status))
+ result = False;
+ else
+ result = (ent->num_sam_entries > 0);
done:
talloc_destroy(mem_ctx);
@@ -619,7 +467,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0;
char *new_extra_data, *gr_mem_list = NULL;
- DEBUG(3, ("[%5lu]: getgrent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: getgrent\n", state->pid));
/* Check user has enabled this */
@@ -636,9 +484,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
group_list = (struct winbindd_gr *)state->response.extra_data;
- if (!state->getgrent_initialized)
- winbindd_setgrent(state);
-
if (!(ent = state->getgrent_state))
return WINBINDD_ERROR;
@@ -651,9 +496,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
gid_t group_gid;
int gr_mem_len;
char *gr_mem, *new_gr_mem_list;
- DOM_SID group_sid;
- struct winbindd_domain *domain;
-
+
/* Do we need to fetch another chunk of groups? */
tryagain:
@@ -662,10 +505,22 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
ent->sam_entry_index, ent->num_sam_entries));
if (ent->num_sam_entries == ent->sam_entry_index) {
+ struct getent_state *next_ent;
+
+ /* is this the beginning ( == 0 ) or the end ? */
+
+ if ( ent->sam_entry_index > 0 ) {
+ DEBUG(10, ("end of getgrent: freeing state info for domain %s\n", ent->domain_name));
+ SAFE_FREE(ent->sam_entries);
+ next_ent = ent->next;
+ DLIST_REMOVE(state->getgrent_state, ent);
+ SAFE_FREE(ent);
+ ent = next_ent;
+ }
- while(ent && !get_sam_group_entries(ent)) {
- struct getent_state *next_ent;
+ /* find the next domain's group entries */
+ while(ent && !get_sam_group_entries(ent, NULL)) {
DEBUG(10, ("freeing state info for domain %s\n", ent->domain_name));
/* Free state information for this domain */
@@ -687,29 +542,22 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
name_list = ent->sam_entries;
- if (!(domain =
- find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("No such domain %s in winbindd_getgrent\n", ent->domain_name));
- result = False;
- goto done;
- }
-
/* Lookup group info */
- sid_copy(&group_sid, &domain->sid);
- sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
-
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &group_gid, 0))) {
+ if (!winbindd_idmap_get_gid_from_rid(
+ ent->domain_name,
+ name_list[ent->sam_entry_index].rid,
+ &group_gid)) {
DEBUG(1, ("could not look up gid for group %s\n",
name_list[ent->sam_entry_index].acct_name));
-
+
ent->sam_entry_index++;
goto tryagain;
}
- DEBUG(10, ("got gid %lu for group %lu\n", (unsigned long)group_gid,
- (unsigned long)name_list[ent->sam_entry_index].rid));
+ DEBUG(10, ("got gid %d for group %x\n", group_gid,
+ name_list[ent->sam_entry_index].rid));
/* Fill in group entry */
@@ -724,24 +572,23 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Fill in group membership entry */
if (result) {
- DOM_SID member_sid;
- group_list[group_list_ndx].num_gr_mem = 0;
- gr_mem = NULL;
- gr_mem_len = 0;
-
- /* Get group membership */
- if (state->request.cmd == WINBINDD_GETGRLST) {
- result = True;
- } else {
- sid_copy(&member_sid, &domain->sid);
- sid_append_rid(&member_sid, name_list[ent->sam_entry_index].rid);
- result = fill_grent_mem(
- domain,
- &member_sid,
- SID_NAME_DOM_GRP,
- &group_list[group_list_ndx].num_gr_mem,
- &gr_mem, &gr_mem_len);
+ struct winbindd_domain *domain;
+
+ if (!(domain =
+ find_domain_from_name(ent->domain_name))) {
+ DEBUG(3, ("No such domain %s in winbindd_getgrent\n", ent->domain_name));
+ result = False;
+ goto done;
}
+
+ /* Get group membership */
+
+ result = fill_grent_mem(
+ domain,
+ name_list[ent->sam_entry_index].rid,
+ SID_NAME_DOM_GRP,
+ &group_list[group_list_ndx].num_gr_mem,
+ &gr_mem, &gr_mem_len);
}
if (result) {
@@ -838,37 +685,39 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
{
uint32 total_entries = 0;
struct winbindd_domain *domain;
- const char *which_domain;
char *extra_data = NULL;
char *ted = NULL;
- unsigned int extra_data_len = 0, i;
+ int extra_data_len = 0, i;
- DEBUG(3, ("[%5lu]: list groups\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: list groups\n", state->pid));
- /* Ensure null termination */
- state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
- which_domain = state->request.domain_name;
-
/* Enumerate over trusted domains */
for (domain = domain_list(); domain; domain = domain->next) {
struct getent_state groups;
+ NTSTATUS status;
- /* if we have a domain name restricting the request and this
- one in the list doesn't match, then just bypass the remainder
- of the loop */
-
- if ( *which_domain && !strequal(which_domain, domain->name) )
- continue;
-
ZERO_STRUCT(groups);
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
+ continue;
+
/* Get list of sam groups */
-
+
+ ZERO_STRUCT(groups);
fstrcpy(groups.domain_name, domain->name);
- get_sam_group_entries(&groups);
-
+ if (!get_sam_group_entries(&groups, &status)) {
+ if (!NT_STATUS_IS_OK(status))
+ state->response.nt_status = NT_STATUS_V(status);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
+ continue;
+ }
+
if (groups.num_sam_entries == 0) {
/* this domain is empty or in an error state */
continue;
@@ -876,10 +725,12 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
/* keep track the of the total number of groups seen so
far over all domains */
+
total_entries += groups.num_sam_entries;
/* Allocate some memory for extra data. Note that we limit
account names to sizeof(fstring) = 128 characters. */
+
ted = Realloc(extra_data, sizeof(fstring) * total_entries);
if (!ted) {
@@ -903,7 +754,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
extra_data[extra_data_len++] = ',';
}
- SAFE_FREE(groups.sam_entries);
+ free(groups.sam_entries);
}
/* Assign extra_data fields in response structure */
@@ -919,112 +770,44 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
-static void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num)
-{
- int i;
-
- if ((*num) >= groups_max())
- return;
-
- for (i=0; i<*num; i++) {
- if ((*gids)[i] == gid)
- return;
- }
-
- *gids = Realloc(*gids, (*num+1) * sizeof(gid_t));
-
- if (*gids == NULL)
- return;
-
- (*gids)[*num] = gid;
- *num += 1;
-}
-
-static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
-{
- gid_t gid;
- DOM_SID *aliases;
- int j, num_aliases;
-
- DEBUG(10, ("Adding gids from SID: %s\n", sid_string_static(sid)));
-
- if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0)))
- add_gid_to_array_unique(gid, gids, num);
-
- /* Don't expand aliases if not explicitly activated -- for now */
- /* we don't support windows local nested groups if we are a DC.
- refer to to sid_to_gid() in the smbd server code to see why
- -- jerry */
-
- if (!lp_winbind_nested_groups() || IS_DC)
- return;
-
- /* Add nested group memberships */
-
- if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
- return;
-
- for (j=0; j<num_aliases; j++) {
-
- if (!NT_STATUS_IS_OK(sid_to_gid(&aliases[j], &gid)))
- continue;
-
- add_gid_to_array_unique(gid, gids, num);
- }
- SAFE_FREE(aliases);
-}
-
/* Get user supplementary groups. This is much quicker than trying to
- invert the groups database. We merge the groups from the gids and
- other_sids info3 fields as trusted domain, universal group
- memberships, and nested groups (win2k native mode only) are not
- returned by the getgroups RPC call but are present in the info3. */
+ invert the groups database. */
enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
{
fstring name_domain, name_user;
- DOM_SID user_sid, group_sid;
+ DOM_SID user_sid;
enum SID_NAME_USE name_type;
- uint32 num_groups = 0;
- uint32 num_gids = 0;
+ uint32 user_rid, num_groups, num_gids;
NTSTATUS status;
- DOM_SID **user_grpsids;
+ uint32 *user_gids;
struct winbindd_domain *domain;
enum winbindd_result result = WINBINDD_ERROR;
- gid_t *gid_list = NULL;
- unsigned int i;
+ gid_t *gid_list;
+ int i;
TALLOC_CTX *mem_ctx;
- NET_USER_INFO_3 *info3 = NULL;
- /* Ensure null termination */
- state->request.data.username[sizeof(state->request.data.username)-1]='\0';
-
- DEBUG(3, ("[%5lu]: getgroups %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
state->request.data.username));
- if (!(mem_ctx = talloc_init("winbindd_getgroups(%s)",
+ if (!(mem_ctx = talloc_init_named("winbindd_getgroups(%s)",
state->request.data.username)))
return WINBINDD_ERROR;
/* Parse domain and username */
- parse_domain_user(state->request.data.username,
- name_domain, name_user);
-
+ if (!parse_domain_user(state->request.data.username, name_domain,
+ name_user))
+ goto done;
+
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(7, ("could not find domain entry for domain %s\n",
+ DEBUG(0, ("could not find domain entry for domain %s\n",
name_domain));
goto done;
}
- if ( domain->primary && lp_winbind_trusted_domains_only()) {
- DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getgroups() for %s\\%s.\n",
- name_domain, name_user));
- return WINBINDD_ERROR;
- }
-
/* Get rid and name type from name. The following costs 1 packet */
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid,
@@ -1033,101 +816,38 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
goto done;
}
- if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) {
+ if (name_type != SID_NAME_USER) {
DEBUG(1, ("name '%s' is not a user name: %d\n",
name_user, name_type));
goto done;
}
- add_gids_from_sid(&user_sid, &gid_list, &num_gids);
-
- /* Treat the info3 cache as authoritative as the
- lookup_usergroups() function may return cached data. */
-
- if ( !opt_nocache && (info3 = netsamlogon_cache_get(mem_ctx, &user_sid))) {
-
- DEBUG(10, ("winbindd_getgroups: info3 has %d groups, %d other sids\n",
- info3->num_groups2, info3->num_other_sids));
+ sid_split_rid(&user_sid, &user_rid);
- num_groups = info3->num_other_sids + info3->num_groups2;
-
- /* Go through each other sid and convert it to a gid */
-
- for (i = 0; i < info3->num_other_sids; i++) {
- fstring name;
- fstring dom_name;
- enum SID_NAME_USE sid_type;
+ status = domain->methods->lookup_usergroups(domain, mem_ctx, user_rid, &num_groups, &user_gids);
+ if (!NT_STATUS_IS_OK(status)) goto done;
- /* Is this sid known to us? It can either be
- a trusted domain sid or a foreign sid. */
+ /* Copy data back to client */
- if (!winbindd_lookup_name_by_sid( &info3->other_sids[i].sid,
- dom_name, name, &sid_type))
- {
- DEBUG(10, ("winbindd_getgroups: could not lookup name for %s\n",
- sid_string_static(&info3->other_sids[i].sid)));
- continue;
- }
+ num_gids = 0;
+ gid_list = malloc(sizeof(gid_t) * num_groups);
- /* Check it is a domain group or an alias (domain local group)
- in a win2k native mode domain. */
-
- if ( !((sid_type==SID_NAME_DOM_GRP) ||
- ((sid_type==SID_NAME_ALIAS) && domain->primary)) )
- {
- DEBUG(10, ("winbindd_getgroups: sid type %d "
- "for %s is not a domain group\n",
- sid_type,
- sid_string_static(
- &info3->other_sids[i].sid)));
- continue;
- }
+ if (state->response.extra_data)
+ goto done;
- add_gids_from_sid(&info3->other_sids[i].sid,
- &gid_list, &num_gids);
+ for (i = 0; i < num_groups; i++) {
+ if (!winbindd_idmap_get_gid_from_rid(domain->name,
+ user_gids[i],
+ &gid_list[num_gids])) {
- if (gid_list == NULL)
- goto done;
+ DEBUG(1, ("unable to convert group rid %d to gid\n",
+ user_gids[i]));
+ continue;
}
-
- for (i = 0; i < info3->num_groups2; i++) {
-
- /* create the group SID */
- sid_copy( &group_sid, &domain->sid );
- sid_append_rid( &group_sid, info3->gids[i].g_rid );
-
- add_gids_from_sid(&group_sid, &gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
- }
-
- SAFE_FREE(info3);
-
- } else {
- status = domain->methods->lookup_usergroups(domain, mem_ctx,
- &user_sid, &num_groups,
- &user_grpsids);
- if (!NT_STATUS_IS_OK(status))
- goto done;
-
- if (state->response.extra_data)
- goto done;
-
- for (i = 0; i < num_groups; i++) {
- add_gids_from_sid(user_grpsids[i],
- &gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
- }
+ num_gids++;
}
- remove_duplicate_gids( &num_gids, gid_list );
-
- /* Send data back to client */
-
state->response.data.num_entries = num_gids;
state->response.extra_data = gid_list;
state->response.length += num_gids * sizeof(gid_t);
@@ -1140,88 +860,3 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
return result;
}
-
-
-/* Get user supplementary sids. This is equivalent to the
- winbindd_getgroups() function but it involves a SID->SIDs mapping
- rather than a NAME->SID->SIDS->GIDS mapping, which means we avoid
- idmap. This call is designed to be used with applications that need
- to do ACL evaluation themselves. Note that the cached info3 data is
- not used
-
- this function assumes that the SID that comes in is a user SID. If
- you pass in another type of SID then you may get unpredictable
- results.
-*/
-enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state)
-{
- DOM_SID user_sid;
- NTSTATUS status;
- DOM_SID **user_grpsids;
- struct winbindd_domain *domain;
- enum winbindd_result result = WINBINDD_ERROR;
- unsigned int i;
- TALLOC_CTX *mem_ctx;
- char *ret = NULL;
- uint32 num_groups;
- unsigned ofs, ret_size = 0;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- if (!string_to_sid(&user_sid, state->request.data.sid)) {
- DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
- return WINBINDD_ERROR;
- }
-
- if (!(mem_ctx = talloc_init("winbindd_getusersids(%s)",
- state->request.data.username))) {
- return WINBINDD_ERROR;
- }
-
- /* Get info for the domain */
- if ((domain = find_domain_from_sid(&user_sid)) == NULL) {
- DEBUG(0,("could not find domain entry for sid %s\n",
- sid_string_static(&user_sid)));
- goto done;
- }
-
- status = domain->methods->lookup_usergroups(domain, mem_ctx,
- &user_sid, &num_groups,
- &user_grpsids);
- if (!NT_STATUS_IS_OK(status))
- goto done;
-
- if (num_groups == 0) {
- goto no_groups;
- }
-
- /* work out the response size */
- for (i = 0; i < num_groups; i++) {
- const char *s = sid_string_static(user_grpsids[i]);
- ret_size += strlen(s) + 1;
- }
-
- /* build the reply */
- ret = malloc(ret_size);
- if (!ret) goto done;
- ofs = 0;
- for (i = 0; i < num_groups; i++) {
- const char *s = sid_string_static(user_grpsids[i]);
- safe_strcpy(ret + ofs, s, ret_size - ofs - 1);
- ofs += strlen(ret+ofs) + 1;
- }
-
-no_groups:
- /* Send data back to client */
- state->response.data.num_entries = num_groups;
- state->response.extra_data = ret;
- state->response.length += ret_size;
- result = WINBINDD_OK;
-
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
diff --git a/source/nsswitch/winbindd_idmap.c b/source/nsswitch/winbindd_idmap.c
new file mode 100755
index 00000000000..0594f616801
--- /dev/null
+++ b/source/nsswitch/winbindd_idmap.c
@@ -0,0 +1,526 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind daemon - user related function
+
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "winbindd.h"
+
+/* High water mark keys */
+
+#define HWM_GROUP "GROUP HWM"
+#define HWM_USER "USER HWM"
+
+/* idmap version determines auto-conversion */
+#define IDMAP_VERSION 2
+
+/* Globals */
+
+static TDB_CONTEXT *idmap_tdb;
+
+/* Allocate either a user or group id from the pool */
+
+static BOOL allocate_id(uid_t *id, BOOL isgroup)
+{
+ int hwm;
+
+ /* Get current high water mark */
+
+ if ((hwm = tdb_fetch_int32(idmap_tdb,
+ isgroup ? HWM_GROUP : HWM_USER)) == -1) {
+ return False;
+ }
+
+ /* Return next available uid in list */
+
+ if ((isgroup && (hwm > server_state.gid_high)) ||
+ (!isgroup && (hwm > server_state.uid_high))) {
+ DEBUG(0, ("winbind %sid range full!\n", isgroup ? "g" : "u"));
+ return False;
+ }
+
+ if (id) {
+ *id = hwm;
+ }
+
+ hwm++;
+
+ /* Store new high water mark */
+
+ tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm);
+
+ return True;
+}
+
+/* Get an id from a rid */
+static BOOL get_id_from_sid(DOM_SID *sid, uid_t *id, BOOL isgroup)
+{
+ TDB_DATA data, key;
+ fstring keystr;
+ BOOL result = False;
+
+ /* Check if sid is present in database */
+ sid_to_string(keystr, sid);
+
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
+
+ data = tdb_fetch(idmap_tdb, key);
+
+ if (data.dptr) {
+ fstring scanstr;
+ int the_id;
+
+ /* Parse and return existing uid */
+ fstrcpy(scanstr, isgroup ? "GID" : "UID");
+ fstrcat(scanstr, " %d");
+
+ if (sscanf(data.dptr, scanstr, &the_id) == 1) {
+ /* Store uid */
+ if (id) {
+ *id = the_id;
+ }
+
+ result = True;
+ }
+
+ SAFE_FREE(data.dptr);
+ } else {
+
+ /* Allocate a new id for this sid */
+
+ if (id && allocate_id(id, isgroup)) {
+ fstring keystr2;
+
+ /* Store new id */
+
+ slprintf(keystr2, sizeof(keystr2), "%s %d", isgroup ? "GID" : "UID", *id);
+
+ data.dptr = keystr2;
+ data.dsize = strlen(keystr2) + 1;
+
+ tdb_store(idmap_tdb, key, data, TDB_REPLACE);
+ tdb_store(idmap_tdb, data, key, TDB_REPLACE);
+
+ result = True;
+ }
+ }
+
+ return result;
+}
+
+/* Get a uid from a user sid */
+BOOL winbindd_idmap_get_uid_from_sid(DOM_SID *sid, uid_t *uid)
+{
+ return get_id_from_sid(sid, uid, False);
+}
+
+/* Get a gid from a group sid */
+BOOL winbindd_idmap_get_gid_from_sid(DOM_SID *sid, gid_t *gid)
+{
+ return get_id_from_sid(sid, gid, True);
+}
+
+/* Get a uid from a user rid */
+BOOL winbindd_idmap_get_uid_from_rid(const char *dom_name, uint32 rid, uid_t *uid)
+{
+ struct winbindd_domain *domain;
+ DOM_SID sid;
+
+ if (!(domain = find_domain_from_name(dom_name))) {
+ return False;
+ }
+
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, rid);
+
+ return get_id_from_sid(&sid, uid, False);
+}
+
+/* Get a gid from a group rid */
+BOOL winbindd_idmap_get_gid_from_rid(const char *dom_name, uint32 rid, gid_t *gid)
+{
+ struct winbindd_domain *domain;
+ DOM_SID sid;
+
+ if (!(domain = find_domain_from_name(dom_name))) {
+ return False;
+ }
+
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, rid);
+
+ return get_id_from_sid(&sid, gid, True);
+}
+
+
+BOOL get_sid_from_id(int id, DOM_SID *sid, BOOL isgroup)
+{
+ TDB_DATA key, data;
+ fstring keystr;
+ BOOL result = False;
+
+ slprintf(keystr, sizeof(keystr), "%s %d", isgroup ? "GID" : "UID", id);
+
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
+
+ data = tdb_fetch(idmap_tdb, key);
+
+ if (data.dptr) {
+ result = string_to_sid(sid, data.dptr);
+ SAFE_FREE(data.dptr);
+ }
+
+ return result;
+}
+
+/* Get a sid from a uid */
+BOOL winbindd_idmap_get_sid_from_uid(uid_t uid, DOM_SID *sid)
+{
+ return get_sid_from_id((int)uid, sid, False);
+}
+
+/* Get a sid from a gid */
+BOOL winbindd_idmap_get_sid_from_gid(gid_t gid, DOM_SID *sid)
+{
+ return get_sid_from_id((int)gid, sid, True);
+}
+
+/* Get a user rid from a uid */
+BOOL winbindd_idmap_get_rid_from_uid(uid_t uid, uint32 *user_rid,
+ struct winbindd_domain **domain)
+{
+ DOM_SID sid;
+
+ if (!get_sid_from_id((int)uid, &sid, False)) {
+ return False;
+ }
+
+ *domain = find_domain_from_sid(&sid);
+ if (! *domain) return False;
+
+ sid_split_rid(&sid, user_rid);
+
+ return True;
+}
+
+/* Get a group rid from a gid */
+
+BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid,
+ struct winbindd_domain **domain)
+{
+ DOM_SID sid;
+
+ if (!get_sid_from_id((int)gid, &sid, True)) {
+ return False;
+ }
+
+ *domain = find_domain_from_sid(&sid);
+ if (! *domain) return False;
+
+ sid_split_rid(&sid, group_rid);
+
+ return True;
+}
+
+/* convert one record to the new format */
+static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *ignored)
+{
+ struct winbindd_domain *domain;
+ char *p;
+ DOM_SID sid;
+ uint32 rid;
+ fstring keystr;
+ fstring dom_name;
+ TDB_DATA key2;
+
+ p = strchr(key.dptr, '/');
+ if (!p)
+ return 0;
+
+ *p = 0;
+ fstrcpy(dom_name, key.dptr);
+ *p++ = '/';
+
+ domain = find_domain_from_name(dom_name);
+ if (!domain) {
+ /* We must delete the old record. */
+ DEBUG(0,("winbindd: convert_fn : Unable to find domain %s\n", dom_name ));
+ DEBUG(0,("winbindd: convert_fn : deleting record %s\n", key.dptr ));
+ tdb_delete(idmap_tdb, key);
+ return 0;
+ }
+
+ rid = atoi(p);
+
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, rid);
+
+ sid_to_string(keystr, &sid);
+ key2.dptr = keystr;
+ key2.dsize = strlen(keystr) + 1;
+
+ if (tdb_store(idmap_tdb, key2, data, TDB_INSERT) != 0) {
+ /* not good! */
+ DEBUG(0,("winbindd: convert_fn : Unable to update record %s\n", key2.dptr ));
+ DEBUG(0,("winbindd: convert_fn : conversion failed - idmap corrupt ?\n"));
+ return -1;
+ }
+
+ if (tdb_store(idmap_tdb, data, key2, TDB_REPLACE) != 0) {
+ /* not good! */
+ DEBUG(0,("winbindd: convert_fn : Unable to update record %s\n", data.dptr ));
+ DEBUG(0,("winbindd: convert_fn : conversion failed - idmap corrupt ?\n"));
+ return -1;
+ }
+
+ tdb_delete(idmap_tdb, key);
+
+ return 0;
+}
+
+#if 0
+/*****************************************************************************
+ Make a backup copy of the old idmap just to be safe.... JRA.
+*****************************************************************************/
+
+static BOOL backup_old_idmap(const char *idmap_name)
+{
+ pstring new_name;
+ int outfd = -1;
+ SMB_OFF_T size;
+ struct stat st;
+
+ pstrcpy(new_name, idmap_name);
+ pstrcat(new_name, ".bak");
+
+ DEBUG(10,("backup_old_idmap: backing up %s to %s before upgrade.\n",
+ idmap_name, new_name ));
+
+ if (tdb_lockall(idmap_tdb) == -1) {
+ DEBUG(10,("backup_old_idmap: failed to lock %s. Error %s\n",
+ idmap_name, tdb_errorstr(idmap_tdb) ));
+ return False;
+ }
+ if ((outfd = open(new_name, O_CREAT|O_EXCL|O_RDWR, 0600)) == -1) {
+ DEBUG(10,("backup_old_idmap: failed to open %s. Error %s\n",
+ new_name, strerror(errno) ));
+ goto fail;
+ }
+
+ if (fstat(idmap_tdb->fd, &st) == -1) {
+ DEBUG(10,("backup_old_idmap: failed to fstat %s. Error %s\n",
+ idmap_name, strerror(errno) ));
+ goto fail;
+ }
+
+ size = (SMB_OFF_T)st.st_size;
+
+ if (transfer_file(idmap_tdb->fd, outfd, size) != size ) {
+ DEBUG(10,("backup_old_idmap: failed to copy %s. Error %s\n",
+ idmap_name, strerror(errno) ));
+ goto fail;
+ }
+
+ if (close(outfd) == -1) {
+ DEBUG(10,("backup_old_idmap: failed to close %s. Error %s\n",
+ idmap_name, strerror(errno) ));
+ outfd = -1;
+ goto fail;
+ }
+ tdb_unlockall(idmap_tdb);
+ return True;
+
+fail:
+
+ if (outfd != -1)
+ close(outfd);
+ tdb_unlockall(idmap_tdb);
+ return False;
+}
+#endif
+
+/*****************************************************************************
+ Convert the idmap database from an older version.
+*****************************************************************************/
+
+static BOOL idmap_convert(const char *idmap_name)
+{
+ int32 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
+ BOOL bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
+
+ if (vers == IDMAP_VERSION)
+ return True;
+
+#if 0
+ /* Make a backup copy before doing anything else.... */
+ if (!backup_old_idmap(idmap_name))
+ return False;
+#endif
+
+ if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
+ /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
+ /*
+ * high and low records were created on a
+ * big endian machine and will need byte-reversing.
+ */
+
+ int32 wm;
+
+ wm = tdb_fetch_int32(idmap_tdb, HWM_USER);
+
+ if (wm != -1) {
+ wm = IREV(wm);
+ } else
+ wm = server_state.uid_low;
+
+ if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n"));
+ return False;
+ }
+
+ wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);
+ if (wm != -1) {
+ wm = IREV(wm);
+ } else
+ wm = server_state.gid_low;
+
+ if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));
+ return False;
+ }
+ }
+
+ /* the old format stored as DOMAIN/rid - now we store the SID direct */
+ tdb_traverse(idmap_tdb, convert_fn, NULL);
+
+ if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/*****************************************************************************
+ Initialise idmap database.
+*****************************************************************************/
+
+BOOL winbindd_idmap_init(void)
+{
+ /* Open tdb cache */
+
+ if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
+ TDB_DEFAULT, O_RDWR | O_CREAT, 0600))) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n"));
+ return False;
+ }
+
+ /* possibly convert from an earlier version */
+ if (!idmap_convert(lock_path("winbindd_idmap.tdb"))) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n"));
+ return False;
+ }
+
+ /* Create high water marks for group and user id */
+
+ if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) {
+ if (tdb_store_int32(idmap_tdb, HWM_USER, server_state.uid_low) == -1) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to initialise user hwm in idmap database\n"));
+ return False;
+ }
+ }
+
+ if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) {
+ if (tdb_store_int32(idmap_tdb, HWM_GROUP, server_state.gid_low) == -1) {
+ DEBUG(0, ("winbindd_idmap_init: Unable to initialise group hwm in idmap database\n"));
+ return False;
+ }
+ }
+
+ return True;
+}
+
+BOOL winbindd_idmap_close(void)
+{
+ if (idmap_tdb)
+ return (tdb_close(idmap_tdb) == 0);
+ return True;
+}
+
+/* Dump status information to log file. Display different stuff based on
+ the debug level:
+
+ Debug Level Information Displayed
+ =================================================================
+ 0 Percentage of [ug]id range allocated
+ 0 High water marks (next allocated ids)
+*/
+
+#define DUMP_INFO 0
+
+void winbindd_idmap_status(void)
+{
+ int user_hwm, group_hwm;
+
+ DEBUG(0, ("winbindd idmap status:\n"));
+
+ /* Get current high water marks */
+
+ if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {
+ DEBUG(DUMP_INFO, ("\tCould not get userid high water mark!\n"));
+ }
+
+ if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {
+ DEBUG(DUMP_INFO, ("\tCould not get groupid high water mark!\n"));
+ }
+
+ /* Display next ids to allocate */
+
+ if (user_hwm != -1) {
+ DEBUG(DUMP_INFO, ("\tNext userid to allocate is %d\n", user_hwm));
+ }
+
+ if (group_hwm != -1) {
+ DEBUG(DUMP_INFO, ("\tNext groupid to allocate is %d\n", group_hwm));
+ }
+
+ /* Display percentage of id range already allocated. */
+
+ if (user_hwm != -1) {
+ int num_users = user_hwm - server_state.uid_low;
+ int total_users = server_state.uid_high - server_state.uid_low;
+
+ DEBUG(DUMP_INFO, ("\tUser id range is %d%% full (%d of %d)\n",
+ num_users * 100 / total_users, num_users,
+ total_users));
+ }
+
+ if (group_hwm != -1) {
+ int num_groups = group_hwm - server_state.gid_low;
+ int total_groups = server_state.gid_high - server_state.gid_low;
+
+ DEBUG(DUMP_INFO, ("\tGroup id range is %d%% full (%d of %d)\n",
+ num_groups * 100 / total_groups, num_groups,
+ total_groups));
+ }
+
+ /* Display complete mapping of users and groups to rids */
+}
diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c
index 18478992f3e..ec7b21dac8c 100644
--- a/source/nsswitch/winbindd_misc.c
+++ b/source/nsswitch/winbindd_misc.c
@@ -21,11 +21,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
+extern pstring global_myname;
/* Check the machine account password is valid */
@@ -35,34 +33,23 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
uchar trust_passwd[16];
int num_retries = 0;
struct cli_state *cli;
- uint32 sec_channel_type;
- struct winbindd_domain *contact_domain;
-
- DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: check machine account\n", state->pid));
/* Get trust account password */
again:
if (!secrets_fetch_trust_account_password(
- lp_workgroup(), trust_passwd, NULL, &sec_channel_type)) {
+ lp_workgroup(), trust_passwd, NULL)) {
result = NT_STATUS_INTERNAL_ERROR;
+ DEBUG(3, ("could not retrieve trust account pw for %s\n", lp_workgroup()));
goto done;
}
-
- contact_domain = find_our_domain();
- if (!contact_domain) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- DEBUG(1, ("Cannot find our own domain!\n"));
- goto done;
- }
-
/* This call does a cli_nt_setup_creds() which implicitly checks
the trust account password. */
+
/* Don't shut this down - it belongs to the connection cache code */
-
- result = cm_get_netlogon_cli(contact_domain,
- trust_passwd, sec_channel_type, True, &cli);
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
@@ -90,14 +77,11 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
done:
state->response.data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
- state->response.data.auth.pam_error = nt_status_to_pam(result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
- state->response.data.auth.nt_status_string));
+ fstrcpy(state->response.data.auth.nt_status_string, get_nt_error_msg(result));
+ fstrcpy(state->response.data.auth.error_string, get_nt_error_msg(result));
+ /*state->response.data.auth.pam_error = nt_status_to_pam(result);*/
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+ return WINBINDD_OK;
}
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
@@ -107,23 +91,19 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
int total_entries = 0, extra_data_len = 0;
char *ted, *extra_data = NULL;
- DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: list trusted domains\n", state->pid));
/* We need to refresh the trusted domain list as the domains may
have changed since we last looked. There may be a sequence
number or something we should use but I haven't found it yet. */
- if (!init_domain_list()) {
- DEBUG(1, ("winbindd_list_trusted_domains: could not "
- "refresh trusted domain list\n"));
- return WINBINDD_ERROR;
- }
+ init_domain_list();
for(domain = domain_list(); domain; domain = domain->next) {
/* Skip own domain */
- if (domain->primary) continue;
+ if (strequal(domain->name, lp_workgroup())) continue;
/* Add domain to list */
@@ -160,13 +140,8 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
char *extra_data = NULL;
- const char *which_domain;
-
- DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
- /* Ensure null termination */
- state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
- which_domain = state->request.domain_name;
+ DEBUG(3, ("[%5d]: show sequence\n", state->pid));
extra_data = strdup("");
@@ -175,13 +150,6 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
for (domain = domain_list(); domain; domain = domain->next) {
char *s;
- /* if we have a domain name restricting the request and this
- one in the list doesn't match, then just bypass the remainder
- of the loop */
-
- if ( *which_domain && !strequal(which_domain, domain->name) )
- continue;
-
domain->methods->sequence_number(domain, &domain->sequence_number);
if (DOM_SEQUENCE_NONE == (unsigned)domain->sequence_number) {
@@ -202,40 +170,10 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
-enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
-
- DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)state->pid,
- state->request.domain_name));
-
- domain = find_domain_from_name(state->request.domain_name);
-
- if (domain == NULL) {
- DEBUG(3, ("Did not find domain [%s]\n",
- state->request.domain_name));
- return WINBINDD_ERROR;
- }
-
- fstrcpy(state->response.data.domain_info.name, domain->name);
- fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name);
- fstrcpy(state->response.data.domain_info.sid,
- sid_string_static(&domain->sid));
-
- state->response.data.domain_info.native_mode = domain->native_mode;
- state->response.data.domain_info.active_directory = domain->active_directory;
- state->response.data.domain_info.primary = domain->primary;
-
- state->response.data.domain_info.sequence_number =
- domain->sequence_number;
-
- return WINBINDD_OK;
-}
-
enum winbindd_result winbindd_ping(struct winbindd_cli_state
*state)
{
- DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: ping\n", state->pid));
return WINBINDD_OK;
}
@@ -245,10 +183,10 @@ enum winbindd_result winbindd_ping(struct winbindd_cli_state
enum winbindd_result winbindd_info(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: request misc info\n", state->pid));
state->response.data.info.winbind_separator = *lp_winbind_separator();
- fstrcpy(state->response.data.info.samba_version, SAMBA_VERSION_STRING);
+ fstrcpy(state->response.data.info.samba_version, VERSION);
return WINBINDD_OK;
}
@@ -258,7 +196,7 @@ enum winbindd_result winbindd_info(struct winbindd_cli_state *state)
enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: request interface version\n", state->pid));
state->response.data.interface_version = WINBIND_INTERFACE_VERSION;
@@ -270,38 +208,9 @@ enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state
enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: request domain name\n", state->pid));
fstrcpy(state->response.data.domain_name, lp_workgroup());
return WINBINDD_OK;
}
-
-/* What's my name again? */
-
-enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid));
-
- fstrcpy(state->response.data.netbios_name, global_myname());
-
- return WINBINDD_OK;
-}
-
-/* Where can I find the privilaged pipe? */
-
-enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
-{
-
- DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid));
-
- state->response.extra_data = strdup(get_winbind_priv_pipe_dir());
- if (!state->response.extra_data)
- return WINBINDD_ERROR;
-
- /* must add one to length to copy the 0 for string termination */
- state->response.length += strlen((char *)state->response.extra_data) + 1;
-
- return WINBINDD_OK;
-}
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index 6a457f38004..28a32ee1911 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -30,13 +30,13 @@
#define WINBINDD_SOCKET_NAME "pipe" /* Name of PF_UNIX socket */
#define WINBINDD_SOCKET_DIR "/tmp/.winbindd" /* Name of PF_UNIX dir */
-#define WINBINDD_PRIV_SOCKET_SUBDIR "winbindd_privileged" /* name of subdirectory of lp_lockdir() to hold the 'privileged' pipe */
+
#define WINBINDD_DOMAIN_ENV "WINBINDD_DOMAIN" /* Environment variables */
#define WINBINDD_DONT_ENV "_NO_WINBINDD"
/* Update this when you change the interface. */
-#define WINBIND_INTERFACE_VERSION 10
+#define WINBIND_INTERFACE_VERSION 4
/* Socket commands */
@@ -84,7 +84,6 @@ enum winbindd_cmd {
WINBINDD_SID_TO_GID,
WINBINDD_UID_TO_SID,
WINBINDD_GID_TO_SID,
- WINBINDD_ALLOCATE_RID,
/* Miscellaneous other stuff */
@@ -93,9 +92,6 @@ enum winbindd_cmd {
WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */
- WINBINDD_DOMAIN_INFO, /* Most of what we know from
- struct winbindd_domain */
-
WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */
/* WINS commands */
@@ -103,71 +99,17 @@ enum winbindd_cmd {
WINBINDD_WINS_BYIP,
WINBINDD_WINS_BYNAME,
- /* account management commands */
-
- WINBINDD_CREATE_USER,
- WINBINDD_CREATE_GROUP,
- WINBINDD_ADD_USER_TO_GROUP,
- WINBINDD_REMOVE_USER_FROM_GROUP,
- WINBINDD_SET_USER_PRIMARY_GROUP,
- WINBINDD_DELETE_USER,
- WINBINDD_DELETE_GROUP,
-
- /* this is like GETGRENT but gives an empty group list */
- WINBINDD_GETGRLST,
-
- WINBINDD_NETBIOS_NAME, /* The netbios name of the server */
-
- /* find the location of our privileged pipe */
- WINBINDD_PRIV_PIPE_DIR,
-
- /* return a list of group sids for a user sid */
- WINBINDD_GETUSERSIDS,
-
/* Placeholder for end of cmd list */
+
WINBINDD_NUM_CMDS
};
-typedef struct winbindd_pw {
- fstring pw_name;
- fstring pw_passwd;
- uid_t pw_uid;
- gid_t pw_gid;
- fstring pw_gecos;
- fstring pw_dir;
- fstring pw_shell;
-} WINBINDD_PW;
-
-
-typedef struct winbindd_gr {
- fstring gr_name;
- fstring gr_passwd;
- gid_t gr_gid;
- int num_gr_mem;
- int gr_mem_ofs; /* offset to group membership */
- char **gr_mem;
-} WINBINDD_GR;
-
-
-#define WBFLAG_PAM_INFO3_NDR 0x0001
-#define WBFLAG_PAM_INFO3_TEXT 0x0002
-#define WBFLAG_PAM_USER_SESSION_KEY 0x0004
-#define WBFLAG_PAM_LMKEY 0x0008
-#define WBFLAG_PAM_CONTACT_TRUSTDOM 0x0010
-#define WBFLAG_QUERY_ONLY 0x0020
-#define WBFLAG_ALLOCATE_RID 0x0040
-#define WBFLAG_PAM_UNIX_NAME 0x0080
-#define WBFLAG_PAM_AFS_TOKEN 0x0100
-#define WBFLAG_PAM_NT_STATUS_SQUASH 0x0200
-
/* Winbind request structure */
struct winbindd_request {
uint32 length;
enum winbindd_cmd cmd; /* Winbindd command to execute */
pid_t pid; /* pid of calling process */
- uint32 flags; /* flags relavant to a given request */
- fstring domain_name; /* name of domain for which the request applies */
union {
fstring winsreq; /* WINS request */
@@ -181,7 +123,6 @@ struct winbindd_request {
character is. */
fstring user;
fstring pass;
- fstring required_membership_sid;
} auth; /* pam_winbind auth module */
struct {
unsigned char chal[8];
@@ -191,8 +132,6 @@ struct winbindd_request {
uint16 lm_resp_len;
fstring nt_resp;
uint16 nt_resp_len;
- fstring workstation;
- fstring required_membership_sid;
} auth_crap;
struct {
fstring user;
@@ -205,12 +144,8 @@ struct winbindd_request {
fstring name;
} name;
uint32 num_entries; /* getpwent, getgrent */
- struct {
- fstring username;
- fstring groupname;
- } acct_mgt;
} data;
- char null_term;
+ fstring domain; /* {set,get,end}{pw,gr}ent() */
};
/* Response values */
@@ -238,11 +173,25 @@ struct winbindd_response {
/* getpwnam, getpwuid */
- struct winbindd_pw pw;
+ struct winbindd_pw {
+ fstring pw_name;
+ fstring pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ fstring pw_gecos;
+ fstring pw_dir;
+ fstring pw_shell;
+ } pw;
/* getgrnam, getgrgid */
- struct winbindd_gr gr;
+ struct winbindd_gr {
+ fstring gr_name;
+ fstring gr_passwd;
+ gid_t gr_gid;
+ int num_gr_mem;
+ int gr_mem_ofs; /* offset to group membership */
+ } gr;
uint32 num_entries; /* getpwent, getgrent */
struct winbindd_sid {
@@ -261,28 +210,17 @@ struct winbindd_response {
fstring samba_version;
} info;
fstring domain_name;
- fstring netbios_name;
struct auth_reply {
uint32 nt_status;
fstring nt_status_string;
fstring error_string;
int pam_error;
- char user_session_key[16];
- char first_8_lm_hash[8];
} auth;
- uint32 rid; /* create user or group or allocate rid */
- struct {
- fstring name;
- fstring alt_name;
- fstring sid;
- BOOL native_mode;
- BOOL active_directory;
- BOOL primary;
- uint32 sequence_number;
- } domain_info;
} data;
+ uint32 nt_status; /* Extended error information */
+
/* Variable length return data */
void *extra_data; /* getgrnam, getgrgid, getgrent */
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index c1840b60533..c02ce81bbd3 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon - pam auth funcions
@@ -22,162 +22,31 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
- struct winbindd_cli_state *state,
- NET_USER_INFO_3 *info3)
-{
- prs_struct ps;
- uint32 size;
- if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!net_io_user_info3("", info3, &ps, 1, 3)) {
- prs_mem_free(&ps);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- size = prs_data_size(&ps);
- state->response.extra_data = malloc(size);
- if (!state->response.extra_data) {
- prs_mem_free(&ps);
- return NT_STATUS_NO_MEMORY;
- }
- prs_copy_all_data_out(state->response.extra_data, &ps);
- state->response.length += size;
- prs_mem_free(&ps);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
- NET_USER_INFO_3 *info3,
- const char *group_sid)
-{
- DOM_SID required_membership_sid;
- DOM_SID *all_sids;
- size_t num_all_sids = (2 + info3->num_groups2 + info3->num_other_sids);
- size_t i, j = 0;
-
- /* Parse the 'required group' SID */
-
- if (!group_sid || !group_sid[0]) {
- /* NO sid supplied, all users may access */
- return NT_STATUS_OK;
- }
-
- if (!string_to_sid(&required_membership_sid, group_sid)) {
- DEBUG(0, ("check_info3_in_group: could not parse %s as a SID!",
- group_sid));
-
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- all_sids = talloc(mem_ctx, sizeof(DOM_SID) * num_all_sids);
- if (!all_sids)
- return NT_STATUS_NO_MEMORY;
-
- /* and create (by appending rids) the 'domain' sids */
-
- sid_copy(&all_sids[0], &(info3->dom_sid.sid));
-
- if (!sid_append_rid(&all_sids[0], info3->user_rid)) {
- DEBUG(3,("could not append user's primary RID 0x%x\n",
- info3->user_rid));
-
- return NT_STATUS_INVALID_PARAMETER;
- }
- j++;
-
- sid_copy(&all_sids[1], &(info3->dom_sid.sid));
-
- if (!sid_append_rid(&all_sids[1], info3->group_rid)) {
- DEBUG(3,("could not append additional group rid 0x%x\n",
- info3->group_rid));
-
- return NT_STATUS_INVALID_PARAMETER;
- }
- j++;
-
- for (i = 0; i < info3->num_groups2; i++) {
-
- sid_copy(&all_sids[j], &(info3->dom_sid.sid));
-
- if (!sid_append_rid(&all_sids[j], info3->gids[j].g_rid)) {
- DEBUG(3,("could not append additional group rid 0x%x\n",
- info3->gids[j].g_rid));
-
- return NT_STATUS_INVALID_PARAMETER;
- }
- j++;
- }
-
- /* Copy 'other' sids. We need to do sid filtering here to
- prevent possible elevation of privileges. See:
-
- http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
- */
-
- for (i = 0; i < info3->num_other_sids; j++) {
- sid_copy(&all_sids[info3->num_groups2 + i + 2],
- &info3->other_sids[j].sid);
- j++;
- }
-
- for (i = 0; i < j; i++) {
- fstring sid1, sid2;
- DEBUG(10, ("User has SID: %s\n",
- sid_to_string(sid1, &all_sids[i])));
- if (sid_equal(&required_membership_sid, &all_sids[i])) {
- DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n",
- sid_to_string(sid1, &required_membership_sid), sid_to_string(sid2, &all_sids[i])));
- return NT_STATUS_OK;
- }
- }
-
- /* Do not distinguish this error from a wrong username/pw */
-
- return NT_STATUS_LOGON_FAILURE;
-}
-
-/**********************************************************************
- Authenticate a user with a clear text password
-**********************************************************************/
+/* Return a password structure from a username. */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
NTSTATUS result;
fstring name_domain, name_user;
+ int passlen;
unsigned char trust_passwd[16];
time_t last_change_time;
- uint32 sec_channel_type;
+ uint32 smb_uid_low;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
uchar chal[8];
TALLOC_CTX *mem_ctx = NULL;
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
- DOM_CRED ret_creds;
- int attempts = 0;
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
- struct winbindd_domain *contact_domain;
- BOOL retry;
-
- /* Ensure null termination */
- state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
- /* Ensure null termination */
- state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';
+ extern pstring global_myname;
- DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
state->request.data.auth.user));
- if (!(mem_ctx = talloc_init("winbind pam auth for %s", state->request.data.auth.user))) {
+ if (!(mem_ctx = talloc_init_named("winbind pam auth for %s", state->request.data.auth.user))) {
DEBUG(0, ("winbindd_pam_auth: could not talloc_init()!\n"));
result = NT_STATUS_NO_MEMORY;
goto done;
@@ -185,127 +54,65 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
/* Parse domain and username */
- parse_domain_user(state->request.data.auth.user, name_domain, name_user);
-
- /* do password magic */
-
- generate_random_buffer(chal, 8, False);
- SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
-
- SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
-
- lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
- nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
-
- /* what domain should we contact? */
-
- if ( IS_DC ) {
- if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth.user, name_domain, name_user, name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- } else {
- if (is_myname(name_domain)) {
- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- if (!(contact_domain = find_our_domain())) {
- DEBUG(1, ("Authentication for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
- state->request.data.auth.user, name_domain, name_user));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
- }
-
- if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ if (!parse_domain_user(state->request.data.auth.user, name_domain,
+ name_user)) {
+ DEBUG(5,("no domain separator (%s) in username (%s) - failing auth\n", lp_winbind_separator(), state->request.data.auth.user));
+ result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
- /* check authentication loop */
-
- do {
- ZERO_STRUCT(info3);
- ZERO_STRUCT(ret_creds);
- retry = False;
-
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd,
- sec_channel_type, False, &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
- goto done;
- }
-
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- &ret_creds,
- name_user, name_domain,
- global_myname(), chal,
- lm_resp, nt_resp,
- &info3);
- attempts += 1;
+ passlen = strlen(state->request.data.auth.pass);
- /* We have to try a second time as cm_get_netlogon_cli
- might not yet have noticed that the DC has killed
- our connection. */
-
- if ( cli->fd == -1 ) {
- retry = True;
- continue;
- }
+ {
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
- /* if we get access denied, a possible cuase was that we had and open
- connection to the DC, but someone changed our machine account password
- out from underneath us using 'net rpc changetrustpw' */
-
- if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) {
- DEBUG(3,("winbindd_pam_auth: sam_logon returned ACCESS_DENIED. Maybe the trust account "
- "password was changed and we didn't know it. Killing connections to domain %s\n",
- name_domain));
- winbindd_cm_flush();
- retry = True;
- cli = NULL;
- }
+ generate_random_buffer(chal, 8, False);
+ SMBencrypt( (const uchar *)state->request.data.auth.pass, chal, local_lm_response);
- } while ( (attempts < 2) && retry );
+ SMBNTencrypt((const uchar *)state->request.data.auth.pass, chal, local_nt_response);
- if (cli != NULL) {
- /* We might have come out of the loop above with cli == NULL,
- so don't dereference that. */
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
+ lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
+ nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
}
- if (NT_STATUS_IS_OK(result)) {
- netsamlogon_cache_store( cli->mem_ctx, &info3 );
- wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
+ /*
+ * Get the machine account password for our primary domain
+ */
+
+ if (!secrets_fetch_trust_account_password(
+ lp_workgroup(), trust_passwd, &last_change_time)) {
+ DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
+ "password for domain %s\n", lp_workgroup()));
+ result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ goto done;
+ }
- /* Check if the user is in the right group */
+ /* We really don't care what LUID we give the user. */
- if (!NT_STATUS_IS_OK(result = check_info3_in_group(mem_ctx, &info3, state->request.data.auth.required_membership_sid))) {
- DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
- state->request.data.auth.user,
- state->request.data.auth.required_membership_sid));
- }
- }
+ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
-done:
- /* give us a more useful (more correct?) error code */
- if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
- result = NT_STATUS_NO_LOGON_SERVERS;
- }
+ ZERO_STRUCT(info3);
+ /* Don't shut this down - it belongs to the connection cache code */
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
+ goto done;
+ }
+
+ result = cli_netlogon_sam_network_logon(cli, mem_ctx,
+ name_user, name_domain,
+ global_myname, chal,
+ lm_resp, nt_resp,
+ &info3);
+
+done:
+
state->response.data.auth.nt_status = NT_STATUS_V(result);
fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
-
- /* we might have given a more useful error above */
- if (!*state->response.data.auth.error_string)
- fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
state->response.data.auth.pam_error = nt_status_to_pam(result);
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
@@ -313,302 +120,97 @@ done:
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
- if ( NT_STATUS_IS_OK(result) &&
- (state->request.flags & WBFLAG_PAM_AFS_TOKEN) ) {
-
- char *afsname = strdup(lp_afs_username_map());
- char *cell;
-
- if (afsname == NULL) goto no_token;
-
- afsname = realloc_string_sub(afsname, "%D", name_domain);
- afsname = realloc_string_sub(afsname, "%u", name_user);
- afsname = realloc_string_sub(afsname, "%U", name_user);
-
- if (afsname == NULL) goto no_token;
-
- strlower_m(afsname);
-
- cell = strchr(afsname, '@');
-
- if (cell == NULL) goto no_token;
-
- *cell = '\0';
- cell += 1;
-
- /* Append an AFS token string */
- state->response.extra_data =
- afs_createtoken_str(afsname, cell);
-
- if (state->response.extra_data != NULL)
- state->response.length +=
- strlen(state->response.extra_data)+1;
-
- no_token:
- SAFE_FREE(afsname);
- }
-
if (mem_ctx)
talloc_destroy(mem_ctx);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
-
-/**********************************************************************
- Challenge Response Authentication Protocol
-**********************************************************************/
+
+#ifdef WITH_WINBIND_AUTH_CRAP
+/* Challenge Response Authentication Protocol */
enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
{
NTSTATUS result;
unsigned char trust_passwd[16];
time_t last_change_time;
- uint32 sec_channel_type;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
- char *name_user = NULL;
- const char *name_domain = NULL;
- const char *workstation;
- struct winbindd_domain *contact_domain;
- DOM_CRED ret_creds;
- int attempts = 0;
- BOOL retry;
+ const char *domain = NULL;
DATA_BLOB lm_resp, nt_resp;
- if (!state->privileged) {
- char *error_string = NULL;
- DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access denied. !\n"));
- DEBUGADD(2, ("winbindd_pam_auth_crap: Ensure permissions on %s are set correctly.\n",
- get_winbind_priv_pipe_dir()));
- /* send a better message than ACCESS_DENIED */
- asprintf(&error_string, "winbind client not authorized to use winbindd_pam_auth_crap. Ensure permissions on %s are set correctly.",
- get_winbind_priv_pipe_dir());
- push_utf8_fstring(state->response.data.auth.error_string, error_string);
- SAFE_FREE(error_string);
- result = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
+ extern pstring global_myname;
- /* Ensure null termination */
- state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]=0;
- state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]=0;
+ DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
+ state->request.data.auth_crap.domain, state->request.data.auth_crap.user));
- if (!(mem_ctx = talloc_init("winbind pam auth crap for (utf8) %s", state->request.data.auth_crap.user))) {
+ if (!(mem_ctx = talloc_init_named("winbind pam auth crap for %s", state->request.data.auth_crap.user))) {
DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
result = NT_STATUS_NO_MEMORY;
goto done;
}
- if (pull_utf8_talloc(mem_ctx, &name_user, state->request.data.auth_crap.user) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
if (*state->request.data.auth_crap.domain) {
- char *dom = NULL;
- if (pull_utf8_talloc(mem_ctx, &dom, state->request.data.auth_crap.domain) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- name_domain = dom;
+ domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
} else if (lp_winbind_use_default_domain()) {
- name_domain = lp_workgroup();
+ domain = talloc_strdup(mem_ctx, lp_workgroup());
} else {
- DEBUG(5,("no domain specified with username (%s) - failing auth\n",
- name_user));
- result = NT_STATUS_NO_SUCH_USER;
+ DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth_crap.user));
+ result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
- DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
- name_domain, name_user));
-
- if (*state->request.data.auth_crap.workstation) {
- char *wrk = NULL;
- if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- workstation = wrk;
- } else {
- workstation = global_myname();
- }
-
- if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
- || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
- DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
- state->request.data.auth_crap.lm_resp_len,
- state->request.data.auth_crap.nt_resp_len));
- result = NT_STATUS_INVALID_PARAMETER;
+ if (!domain) {
+ DEBUG(0,("winbindd_pam_auth_crap: talloc_strdup failed!\n"));
+ result = NT_STATUS_NO_MEMORY;
goto done;
}
lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
-
- /* what domain should we contact? */
-
- if ( IS_DC ) {
- if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth_crap.user, name_domain, name_user, name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- } else {
- if (is_myname(name_domain)) {
- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- if (!(contact_domain = find_our_domain())) {
- DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
- state->request.data.auth_crap.user, name_domain, name_user));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
- }
-
- if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) {
+ /*
+ * Get the machine account password for our primary domain
+ */
+
+ if (!secrets_fetch_trust_account_password(
+ lp_workgroup(), trust_passwd, &last_change_time)) {
+ DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
+ "password for domain %s\n", lp_workgroup()));
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
goto done;
}
- do {
- ZERO_STRUCT(info3);
- ZERO_STRUCT(ret_creds);
- retry = False;
-
- /* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, False, &cli);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
- nt_errstr(result)));
- goto done;
- }
-
- result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- &ret_creds,
- name_user, name_domain,
- workstation,
- state->request.data.auth_crap.chal,
- lm_resp, nt_resp,
- &info3);
-
- attempts += 1;
-
- /* We have to try a second time as cm_get_netlogon_cli
- might not yet have noticed that the DC has killed
- our connection. */
-
- if ( cli->fd == -1 ) {
- retry = True;
- continue;
- }
-
- /* if we get access denied, a possible cause was that we had and open
- connection to the DC, but someone changed our machine account password
- out from underneath us using 'net rpc changetrustpw' */
-
- if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) {
- DEBUG(3,("winbindd_pam_auth_crap: sam_logon returned ACCESS_DENIED. Maybe the trust account "
- "password was changed and we didn't know it. Killing connections to domain %s\n",
- contact_domain->name));
- winbindd_cm_flush();
- retry = True;
- cli = NULL;
- }
-
- } while ( (attempts < 2) && retry );
+ ZERO_STRUCT(info3);
- if (cli != NULL) {
- /* We might have come out of the loop above with cli == NULL,
- so don't dereference that. */
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
- }
+ /* Don't shut this down - it belongs to the connection cache code */
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
- if (NT_STATUS_IS_OK(result)) {
- netsamlogon_cache_store( cli->mem_ctx, &info3 );
- wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
-
- if (!NT_STATUS_IS_OK(result = check_info3_in_group(mem_ctx, &info3, state->request.data.auth_crap.required_membership_sid))) {
- DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
- state->request.data.auth_crap.user,
- state->request.data.auth_crap.required_membership_sid));
- goto done;
- }
-
- if (state->request.flags & WBFLAG_PAM_INFO3_NDR) {
- result = append_info3_as_ndr(mem_ctx, state, &info3);
- } else if (state->request.flags & WBFLAG_PAM_UNIX_NAME) {
- /* ntlm_auth should return the unix username, per
- 'winbind use default domain' settings and the like */
-
- fstring username_out;
- const char *nt_username, *nt_domain;
- if (!(nt_username = unistr2_tdup(mem_ctx, &(info3.uni_user_name)))) {
- /* If the server didn't give us one, just use the one we sent them */
- nt_username = name_user;
- }
-
- if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3.uni_logon_dom)))) {
- /* If the server didn't give us one, just use the one we sent them */
- nt_domain = name_domain;
- }
-
- fill_domain_username(username_out, nt_domain, nt_username);
-
- DEBUG(5, ("Setting unix username to [%s]\n", username_out));
-
- /* this interface is in UTF8 */
- if (push_utf8_allocate((char **)&state->response.extra_data, username_out) == -1) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
- state->response.length += strlen(state->response.extra_data)+1;
- }
-
- if (state->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
- memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, sizeof(state->response.data.auth.user_session_key) /* 16 */);
- }
- if (state->request.flags & WBFLAG_PAM_LMKEY) {
- memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
- }
- }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe (%s)\n", nt_errstr(result)));
+ goto done;
+ }
+ result = cli_netlogon_sam_network_logon(cli, mem_ctx,
+ state->request.data.auth_crap.user, domain,
+ global_myname, state->request.data.auth_crap.chal,
+ lm_resp, nt_resp,
+ &info3);
+
done:
- /* give us a more useful (more correct?) error code */
- if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
- result = NT_STATUS_NO_LOGON_SERVERS;
- }
- if (state->request.flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
- result = nt_status_squash(result);
- }
-
state->response.data.auth.nt_status = NT_STATUS_V(result);
- push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
-
- /* we might have given a more useful error above */
- if (!*state->response.data.auth.error_string)
- push_utf8_fstring(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
- name_domain,
- name_user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ state->request.data.auth_crap.domain,
+ state->request.data.auth_crap.user,
+ state->response.data.auth.nt_status_string,
+ state->response.data.auth.pam_error));
if (mem_ctx)
talloc_destroy(mem_ctx);
@@ -616,6 +218,8 @@ done:
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+#endif /* WITH_WINBIND_AUTH_CRAP */
+
/* Change a user password */
enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
@@ -624,30 +228,18 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
char *oldpass, *newpass;
fstring domain, user;
CLI_POLICY_HND *hnd;
- TALLOC_CTX *mem_ctx;
- struct winbindd_domain *contact_domain;
- DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
state->request.data.chauthtok.user));
- if (!(mem_ctx = talloc_init("winbind password change for (utf8) %s",
- state->request.data.chauthtok.user))) {
- DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
/* Setup crap */
if (state == NULL)
return WINBINDD_ERROR;
- parse_domain_user(state->request.data.chauthtok.user, domain, user);
-
- if (!(contact_domain = find_domain_from_name(domain))) {
- DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
- state->request.data.chauthtok.user, domain, user, domain));
- result = NT_STATUS_NO_SUCH_USER;
+ if (!parse_domain_user(state->request.data.chauthtok.user, domain,
+ user)) {
+ result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
@@ -658,12 +250,17 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
/* Get sam handle */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(contact_domain, &hnd)) ) {
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) {
DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
goto done;
}
- result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, user, newpass, oldpass);
+ if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) {
+ DEBUG(1, ("password change failed for user %s/%s\n", domain,
+ user));
+ result = NT_STATUS_WRONG_PASSWORD;
+ } else
+ result = NT_STATUS_OK;
done:
state->response.data.auth.nt_status = NT_STATUS_V(result);
@@ -671,15 +268,5 @@ done:
fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
- domain,
- user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c
deleted file mode 100644
index 36f5297efeb..00000000000
--- a/source/nsswitch/winbindd_passdb.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind rpc backend functions
-
- Copyright (C) Tim Potter 2000-2001,2003
- Copyright (C) Simo Sorce 2003
- Copyright (C) Volker Lendecke 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-static void
-add_member(const char *domain, const char *user,
- char **members, int *num_members)
-{
- fstring name;
-
- fill_domain_username(name, domain, user);
- safe_strcat(name, ",", sizeof(name)-1);
- string_append(members, name);
- *num_members += 1;
-}
-
-/**********************************************************************
- Add member users resulting from sid. Expand if it is a domain group.
-**********************************************************************/
-
-static void
-add_expanded_sid(const DOM_SID *sid, char **members, int *num_members)
-{
- DOM_SID dom_sid;
- uint32 rid;
- struct winbindd_domain *domain;
- int i;
-
- char *name = NULL;
- enum SID_NAME_USE type;
-
- uint32 num_names;
- DOM_SID **sid_mem;
- char **names;
- uint32 *types;
-
- NTSTATUS result;
-
- TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid");
-
- if (mem_ctx == NULL) {
- DEBUG(1, ("talloc_init failed\n"));
- return;
- }
-
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &rid);
-
- domain = find_domain_from_sid(&dom_sid);
-
- if (domain == NULL) {
- DEBUG(3, ("Could not find domain for sid %s\n",
- sid_string_static(sid)));
- goto done;
- }
-
- result = domain->methods->sid_to_name(domain, mem_ctx, sid,
- &name, &type);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("sid_to_name failed for sid %s\n",
- sid_string_static(sid)));
- goto done;
- }
-
- DEBUG(10, ("Found name %s, type %d\n", name, type));
-
- if (type == SID_NAME_USER) {
- add_member(domain->name, name, members, num_members);
- goto done;
- }
-
- if (type != SID_NAME_DOM_GRP) {
- DEBUG(10, ("Alias member %s neither user nor group, ignore\n",
- name));
- goto done;
- }
-
- /* Expand the domain group */
-
- result = domain->methods->lookup_groupmem(domain, mem_ctx,
- sid, &num_names,
- &sid_mem, &names,
- &types);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10, ("Could not lookup group members for %s: %s\n",
- name, nt_errstr(result)));
- goto done;
- }
-
- for (i=0; i<num_names; i++) {
- DEBUG(10, ("Adding group member SID %s\n",
- sid_string_static(sid_mem[i])));
-
- if (types[i] != SID_NAME_USER) {
- DEBUG(1, ("Hmmm. Member %s of group %s is no user. "
- "Ignoring.\n", names[i], name));
- continue;
- }
-
- add_member(domain->name, names[i], members, num_members);
- }
-
- done:
- talloc_destroy(mem_ctx);
- return;
-}
-
-BOOL fill_passdb_alias_grmem(struct winbindd_domain *domain,
- DOM_SID *group_sid,
- int *num_gr_mem, char **gr_mem, int *gr_mem_len)
-{
- DOM_SID *members;
- int i, num_members;
-
- *num_gr_mem = 0;
- *gr_mem = NULL;
- *gr_mem_len = 0;
-
- if (!pdb_enum_aliasmem(group_sid, &members, &num_members))
- return True;
-
- for (i=0; i<num_members; i++) {
- add_expanded_sid(&members[i], gr_mem, num_gr_mem);
- }
-
- SAFE_FREE(members);
-
- if (*gr_mem != NULL) {
- int len;
-
- /* We have at least one member, strip off the last "," */
- len = strlen(*gr_mem);
- (*gr_mem)[len-1] = '\0';
- *gr_mem_len = len;
- }
-
- return True;
-}
-
-/* Query display info for a domain. This returns enough information plus a
- bit extra to give an overview of domain users for the User Manager
- application. */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- /* We don't have users */
- *num_entries = 0;
- *info = NULL;
- return NT_STATUS_OK;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- /* We don't have domain groups */
- *num_entries = 0;
- *info = NULL;
- return NT_STATUS_OK;
-}
-
-/* List all domain groups */
-
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct acct_info *talloced_info;
-
- /* Hmm. One billion aliases should be enough for a start */
-
- if (!pdb_enum_aliases(&domain->sid, 0, 1000000000,
- num_entries, info)) {
- /* Nothing to report, just exit. */
- return NT_STATUS_OK;
- }
-
- talloced_info = (struct acct_info *)
- talloc_memdup(mem_ctx, *info,
- *num_entries * sizeof(struct acct_info));
-
- SAFE_FREE(*info);
- *info = talloced_info;
-
- return NT_STATUS_OK;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- DEBUG(10, ("Finding name %s\n", name));
-
- if (!pdb_find_alias(name, sid))
- return NT_STATUS_NONE_MAPPED;
-
- *type = SID_NAME_ALIAS;
- return NT_STATUS_OK;
-}
-
-/*
- convert a domain SID to a user or group name
-*/
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- struct acct_info info;
-
- DEBUG(10, ("Converting SID %s\n", sid_string_static(sid)));
-
- if (!pdb_get_aliasinfo(sid, &info))
- return NT_STATUS_NONE_MAPPED;
-
- *name = talloc_strdup(mem_ctx, info.acct_name);
- *type = SID_NAME_ALIAS;
-
- return NT_STATUS_OK;
-}
-
-/* Lookup user information from a rid or username. */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- WINBIND_USERINFO *user_info)
-{
- return NT_STATUS_NO_SUCH_USER;
-}
-
-/* Lookup groups a user is a member of. I wish Unix had a call like this! */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- return NT_STATUS_NO_SUCH_USER;
-}
-
-
-/* Lookup group membership given a rid. */
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- return NT_STATUS_OK;
-}
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- *seq = 1;
- return NT_STATUS_OK;
-}
-
-/* get a list of trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- return NT_STATUS_OK;
-}
-
-/* find the domain sid for a domain */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- sid_copy(sid, &domain->sid);
- return NT_STATUS_OK;
-}
-
-/* find alternate names list for the domain
- * should we look for netbios aliases??
- SSS */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- DEBUG(3,("pdb: alternate_name\n"));
-
- return NT_STATUS_OK;
-}
-
-
-/* the rpc backend methods are exposed via this structure */
-struct winbindd_methods passdb_methods = {
- False,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 25d5f64df67..93df063b6d6 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -3,7 +3,7 @@
Winbind rpc backend functions
- Copyright (C) Tim Potter 2000-2001,2003
+ Copyright (C) Tim Potter 2000-2001
Copyright (C) Andrew Tridgell 2001
This program is free software; you can redistribute it and/or modify
@@ -21,12 +21,25 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
+/*******************************************************************
+ Duplicate a UNISTR2 string into a UNIX codepage null terminated char*
+ using a talloc context
+********************************************************************/
+static char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
+{
+ char *s;
+ int maxlen = (str->uni_str_len+1)*4;
+ if (!str->buffer)
+ return NULL;
+ s = (char *)talloc(ctx, maxlen); /* convervative */
+ if (!s)
+ return NULL;
+ unistr2_to_unix(s, str, maxlen);
+ return s;
+}
/* Query display info for a domain. This returns enough information plus a
bit extra to give an overview of domain users for the User Manager
@@ -37,14 +50,12 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
WINBIND_USERINFO **info)
{
CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- unsigned int i, start_idx, retry;
- uint32 loop_count;
-
- DEBUG(3,("rpc: query_user_list\n"));
+ int i, loop_count = 0;
+ int retry;
*num_entries = 0;
*info = NULL;
@@ -53,71 +64,66 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
do {
/* Get sam handle */
- if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
- return result;
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ goto done;
/* Get domain handle */
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
-
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ des_access, &domain->sid, &dom_pol);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
goto done;
got_dom_pol = True;
- i = start_idx = 0;
- loop_count = 0;
-
+ i = 0;
do {
- TALLOC_CTX *ctx2;
- uint32 num_dom_users, j;
- uint32 max_entries, max_size;
SAM_DISPINFO_CTR ctr;
SAM_DISPINFO_1 info1;
+ uint32 count = 0, start=i, max_entries, max_size;
+ int j;
+ TALLOC_CTX *ctx2;
- ZERO_STRUCT( ctr );
- ZERO_STRUCT( info1 );
ctr.sam.info1 = &info1;
-
- if (!(ctx2 = talloc_init("winbindd enum_users"))) {
+
+ ctx2 = talloc_init_named("winbindd dispinfo");
+ if (!ctx2) {
result = NT_STATUS_NO_MEMORY;
goto done;
- }
-
- /* this next bit is copied from net_user_list_internal() */
-
- get_query_dispinfo_params( loop_count, &max_entries, &max_size );
+ }
+
+ get_query_dispinfo_params(
+ loop_count, &max_entries, &max_size);
- result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, &dom_pol,
- &start_idx, 1, &num_dom_users, max_entries, max_size, &ctr);
+ /* Query display info level 1 */
+ result = cli_samr_query_dispinfo(
+ hnd->cli, ctx2, &dom_pol, &start, 1, &count,
+ max_entries, max_size, &ctr);
loop_count++;
- *num_entries += num_dom_users;
+ if (!NT_STATUS_IS_OK(result) &&
+ !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break;
- *info = talloc_realloc( mem_ctx, *info,
- (*num_entries) * sizeof(WINBIND_USERINFO));
+ (*num_entries) += count;
+ /* now map the result into the WINBIND_USERINFO structure */
+ (*info) = talloc_realloc(mem_ctx, *info,
+ (*num_entries)*sizeof(WINBIND_USERINFO));
if (!(*info)) {
result = NT_STATUS_NO_MEMORY;
talloc_destroy(ctx2);
goto done;
}
- for (j = 0; j < num_dom_users; i++, j++) {
- fstring username, fullname;
- uint32 rid = ctr.sam.info1->sam[j].rid_user;
-
- unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
- unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
-
- (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
- (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
- (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, rid );
-
+ for (j=0;j<count;i++, j++) {
+ /* unistr2_tdup converts to UNIX charset. */
+ (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_acct_name);
+ (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_full_name);
+ (*info)[i].user_rid = info1.sam[j].rid_user;
/* For the moment we set the primary group for
every user to be the Domain Users group.
There are serious problems with determining
@@ -125,13 +131,10 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
This should really be made into a 'winbind
force group' smb.conf parameter or
something like that. */
-
- (*info)[i].group_sid = rid_to_talloced_sid(domain,
- mem_ctx, DOMAIN_GROUP_RID_USERS);
+ (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS;
}
talloc_destroy(ctx2);
-
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
done:
@@ -142,77 +145,9 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
return result;
}
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- CLI_POLICY_HND *hnd;
- POLICY_HND dom_pol;
- NTSTATUS status;
- uint32 start = 0;
- int retry;
- NTSTATUS result;
-
- *num_entries = 0;
- *info = NULL;
-
- DEBUG(3,("rpc: enum_dom_groups\n"));
-
- retry = 0;
- do {
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
- return result;
-
- status = cli_samr_open_domain(hnd->cli, mem_ctx,
- &hnd->pol, des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- do {
- struct acct_info *info2 = NULL;
- uint32 count = 0;
- TALLOC_CTX *mem_ctx2;
-
- mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
-
- /* start is updated by this call. */
- status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
- &start,
- 0xFFFF, /* buffer size? */
- &info2, &count);
-
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
- talloc_destroy(mem_ctx2);
- break;
- }
-
- (*info) = talloc_realloc(mem_ctx, *info,
- sizeof(**info) * ((*num_entries) + count));
- if (! *info) {
- talloc_destroy(mem_ctx2);
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
- return NT_STATUS_NO_MEMORY;
- }
-
- memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
- (*num_entries) += count;
- talloc_destroy(mem_ctx2);
- } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
-
- cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-
- return status;
-}
-
/* List all domain groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
+static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_entries,
struct acct_info **info)
@@ -221,6 +156,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
CLI_POLICY_HND *hnd;
POLICY_HND dom_pol;
NTSTATUS result;
+ uint32 start = 0;
int retry;
*num_entries = 0;
@@ -228,29 +164,31 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
retry = 0;
do {
- if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
return result;
- result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ result = cli_samr_open_domain(hnd->cli, mem_ctx,
+ &hnd->pol, des_access, &domain->sid, &dom_pol);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
- if ( !NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result))
return result;
do {
struct acct_info *info2 = NULL;
- uint32 count = 0, start = *num_entries;
+ uint32 count = 0;
TALLOC_CTX *mem_ctx2;
- mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
+ mem_ctx2 = talloc_init_named("enum_dom_groups[rpc]");
+
+ /* This call updates 'start' */
+ result = cli_samr_enum_dom_groups(
+ hnd->cli, mem_ctx2, &dom_pol, &start,
+ 0xFFFF, /* buffer size? */ &info2, &count);
- result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
- &start, 0xFFFF, &info2, &count);
-
- if ( !NT_STATUS_IS_OK(result)
- && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
- {
+ if (!NT_STATUS_IS_OK(result) &&
+ !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
talloc_destroy(mem_ctx2);
break;
}
@@ -275,11 +213,11 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
/* convert a single name to a sid in a domain */
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type)
{
+ TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
NTSTATUS result;
DOM_SID *sids = NULL;
@@ -287,25 +225,28 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
const char *full_name;
int retry;
- DEBUG(3,("rpc: name_to_sid name=%s\n", name));
-
+ if (!(mem_ctx = talloc_init_named("name_to_sid[rpc] for [%s]\\[%s]", domain->name, name))) {
+ DEBUG(0, ("talloc_init failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
if (!full_name) {
DEBUG(0, ("talloc_asprintf failed!\n"));
+ talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
- DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
-
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) {
- return result;
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
+ talloc_destroy(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
}
result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
- &full_name, &sids, &types);
+ &full_name, &sids, &types);
} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
hnd && hnd->cli && hnd->cli->fd == -1);
@@ -313,9 +254,10 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
if (NT_STATUS_IS_OK(result)) {
sid_copy(sid, &sids[0]);
- *type = (enum SID_NAME_USE)types[0];
+ *type = types[0];
}
+ talloc_destroy(mem_ctx);
return result;
}
@@ -324,7 +266,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
*/
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ DOM_SID *sid,
char **name,
enum SID_NAME_USE *type)
{
@@ -334,27 +276,24 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
uint32 *types;
NTSTATUS result;
int retry;
-
- DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
- domain->name ));
-
+
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
- return result;
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
+ return NT_STATUS_UNSUCCESSFUL;
result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
- 1, sid, &domains, &names, &types);
+ 1, sid, &domains, &names, &types);
} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
hnd && hnd->cli && hnd->cli->fd == -1);
if (NT_STATUS_IS_OK(result)) {
- *type = (enum SID_NAME_USE)types[0];
+ *type = types[0];
*name = names[0];
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
/* Paranoia */
- if (!strequal(domain->name, domains[0])) {
+ if (strcasecmp(domain->name, domains[0]) != 0) {
DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -366,57 +305,26 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
/* Lookup user information from a rid or username. */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
+ uint32 user_rid,
WINBIND_USERINFO *user_info)
{
- CLI_POLICY_HND *hnd = NULL;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
POLICY_HND dom_pol, user_pol;
BOOL got_dom_pol = False, got_user_pol = False;
SAM_USERINFO_CTR *ctr;
int retry;
- fstring sid_string;
- uint32 user_rid;
- NET_USER_INFO_3 *user;
- DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
- if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
- goto done;
- }
-
- /* try netsamlogon cache first */
-
- if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
- {
-
- DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
- sid_string_static(user_sid)));
-
- user_info->user_sid = rid_to_talloced_sid( domain, mem_ctx, user_rid );
- user_info->group_sid = rid_to_talloced_sid( domain, mem_ctx, user->group_rid );
-
- user_info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
- user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
-
- SAFE_FREE(user);
-
- return NT_STATUS_OK;
- }
-
- /* no cache; hit the wire */
-
retry = 0;
do {
- /* Get sam handle; if we fail here there is no hope */
-
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
+ /* Get sam handle */
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
-
- /* Get domain handle */
+ /* Get domain handle */
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sid, &dom_pol);
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sid, &dom_pol);
} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
hnd && hnd->cli && hnd->cli->fd == -1);
@@ -444,8 +352,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
cli_samr_close(hnd->cli, mem_ctx, &user_pol);
got_user_pol = False;
- user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
- user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
+ user_info->user_rid = user_rid;
+ user_info->group_rid = ctr->info.id21->group_rid;
user_info->acct_name = unistr2_tdup(mem_ctx,
&ctr->info.id21->uni_user_name);
user_info->full_name = unistr2_tdup(mem_ctx,
@@ -465,59 +373,31 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
/* Lookup groups a user is a member of. I wish Unix had a call like this! */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_grpsids)
+ uint32 user_rid,
+ uint32 *num_groups, uint32 **user_gids)
{
CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result;
POLICY_HND dom_pol, user_pol;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
BOOL got_dom_pol = False, got_user_pol = False;
DOM_GID *user_groups;
- unsigned int i;
- unsigned int retry;
- fstring sid_string;
- uint32 user_rid;
- NET_USER_INFO_3 *user;
-
- DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
+ int i;
+ int retry;
*num_groups = 0;
- *user_grpsids = NULL;
+ *user_gids = NULL;
- /* so lets see if we have a cached user_info_3 */
-
- if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
- {
- DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
- sid_string_static(user_sid)));
-
- *num_groups = user->num_groups;
-
- (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
- for (i=0;i<(*num_groups);i++) {
- (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user->gids[i].g_rid);
- }
-
- SAFE_FREE(user);
-
- return NT_STATUS_OK;
- }
-
- /* no cache; hit the wire */
-
retry = 0;
do {
- /* Get sam handle; if we fail here there is no hope */
-
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
+ /* Get sam handle */
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
/* Get domain handle */
-
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
- des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ des_access, &domain->sid, &dom_pol);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
@@ -525,11 +405,6 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
got_dom_pol = True;
-
- if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
- goto done;
- }
-
/* Get user handle */
result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
des_access, user_rid, &user_pol);
@@ -546,14 +421,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
goto done;
- (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
- if (!(*user_grpsids)) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
+ (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
for (i=0;i<(*num_groups);i++) {
- (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
+ (*user_gids)[i] = user_groups[i].g_rid;
}
done:
@@ -571,41 +441,31 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
+ uint32 group_rid, uint32 *num_names,
+ uint32 **rid_mem, char ***names,
uint32 **name_types)
{
- CLI_POLICY_HND *hnd = NULL;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
uint32 i, total_names = 0;
POLICY_HND dom_pol, group_pol;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
BOOL got_dom_pol = False, got_group_pol = False;
- uint32 *rid_mem = NULL;
- uint32 group_rid;
int retry;
- unsigned int j;
- fstring sid_string;
-
- DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
-
- if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
- goto done;
- }
*num_names = 0;
retry = 0;
do {
/* Get sam handle */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
/* Get domain handle */
-
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -626,19 +486,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
group. */
result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
- &group_pol, num_names, &rid_mem,
+ &group_pol, num_names, rid_mem,
name_types);
if (!NT_STATUS_IS_OK(result))
goto done;
- if (!*num_names) {
- names = NULL;
- name_types = NULL;
- sid_mem = NULL;
- goto done;
- }
-
/* Step #2: Convert list of rids into list of usernames. Do this
in bunches of ~1000 to avoid crashing NT4. It looks like there
is a buffer overflow or something like that lurking around
@@ -648,16 +501,6 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
*names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
*name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
- *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
-
- for (j=0;j<(*num_names);j++) {
- (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
- }
-
- if (*num_names>0 && (!*names || !*name_types)) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
@@ -670,16 +513,13 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
&dom_pol, 1000, /* flags */
num_lookup_rids,
- &rid_mem[i],
+ &(*rid_mem)[i],
&tmp_num_names,
&tmp_names, &tmp_types);
- /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
- the one returned from 2k) */
-
- if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
+ if (!NT_STATUS_IS_OK(result))
goto done;
-
+
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on. */
@@ -688,15 +528,13 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
tmp_num_names);
-
+
total_names += tmp_num_names;
}
*num_names = total_names;
- result = NT_STATUS_OK;
-
-done:
+ done:
if (got_group_pol)
cli_samr_close(hnd->cli, mem_ctx, &group_pol);
@@ -706,8 +544,9 @@ done:
return result;
}
-#ifdef HAVE_LDAP
+/* find the sequence number for a domain */
+#ifdef WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK
#include <ldap.h>
static SIG_ATOMIC_T gotalarm;
@@ -740,7 +579,7 @@ static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int t
return ldp;
}
-static int get_ldap_seq(const char *server, int port, uint32 *seq)
+int get_ldap_seq(const char *server, uint32 *seq)
{
int ret = -1;
struct timeval to;
@@ -756,9 +595,15 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
* doesn't seem to apply to doing an open as well. JRA.
*/
- if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
+ if ((ldp = ldap_open_with_timeout(server, LDAP_PORT, 10)) == NULL)
return -1;
+#if 0
+ /* As per tridge comment this doesn't seem to be needed. JRA */
+ if ((err = ldap_simple_bind_s(ldp, NULL, NULL)) != 0)
+ goto done;
+#endif
+
/* Timeout if no response within 20 seconds. */
to.tv_sec = 10;
to.tv_usec = 0;
@@ -786,58 +631,8 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
ldap_unbind(ldp);
return ret;
}
+#endif /* WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK */
-/**********************************************************************
- Get the sequence number for a Windows AD native mode domain using
- LDAP queries
-**********************************************************************/
-
-static int get_ldap_sequence_number( const char* domain, uint32 *seq)
-{
- int ret = -1;
- int i, port = LDAP_PORT;
- struct ip_service *ip_list = NULL;
- int count;
-
- if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
- DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
- return False;
- }
-
- /* Finally return first DC that we can contact */
-
- for (i = 0; i < count; i++) {
- fstring ipstr;
-
- /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
- port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
-
- fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
-
- if (is_zero_ip(ip_list[i].ip))
- continue;
-
- if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
- goto done;
-
- /* add to failed connection cache */
- add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
- }
-
-done:
- if ( ret == 0 ) {
- DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
- domain, inet_ntoa(ip_list[i].ip), port));
- }
-
- SAFE_FREE(ip_list);
-
- return ret;
-}
-
-#endif /* HAVE_LDAP */
-
-/* find the sequence number for a domain */
static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
{
TALLOC_CTX *mem_ctx;
@@ -845,44 +640,42 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
SAM_UNK_CTR ctr;
uint16 switch_value = 2;
NTSTATUS result;
+ uint32 seqnum = DOM_SEQUENCE_NONE;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
int retry;
- DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
-
*seq = DOM_SEQUENCE_NONE;
- if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
+ if (!(mem_ctx = talloc_init_named("sequence_number[rpc]")))
return NT_STATUS_NO_MEMORY;
retry = 0;
do {
-#ifdef HAVE_LDAP
- if ( domain->native_mode )
- {
- DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
-
- if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
- result = NT_STATUS_OK;
- DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
- domain->name, *seq));
- goto done;
- }
-
- DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
- domain->name ));
- }
-#endif /* HAVE_LDAP */
- /* Get sam handle */
- if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
+ /* Get sam handle */
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
+#ifdef WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK
+ if (get_ldap_seq( inet_ntoa(hnd->cli->dest_ip), seq) == 0) {
+ result = NT_STATUS_OK;
+ seqnum = *seq;
+ DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
+ domain->name, (unsigned)seqnum ));
+ goto done;
+ }
+
+ DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number (%u) for domain %s\n",
+ (unsigned)seqnum, domain->name ));
+
+#endif /* WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK */
+
/* Get domain handle */
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -895,11 +688,14 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
switch_value, &ctr);
if (NT_STATUS_IS_OK(result)) {
- *seq = ctr.info.inf2.seq_num;
- DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
+ seqnum = ctr.info.inf2.seq_num;
+ seqnum += ctr.info.inf2.num_domain_usrs;
+ seqnum += ctr.info.inf2.num_domain_grps;
+ seqnum += ctr.info.inf2.num_local_grps;
+ DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
} else {
DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
- (unsigned)*seq, domain->name ));
+ (unsigned)seqnum, domain->name ));
}
done:
@@ -909,6 +705,8 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
talloc_destroy(mem_ctx);
+ *seq = seqnum;
+
return result;
}
@@ -917,29 +715,25 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
- char ***alt_names,
DOM_SID **dom_sids)
{
CLI_POLICY_HND *hnd;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result;
uint32 enum_ctx = 0;
int retry;
- DEBUG(3,("rpc: trusted_domains\n"));
-
*num_domains = 0;
- *alt_names = NULL;
retry = 0;
do {
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
goto done;
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
- &hnd->pol, &enum_ctx,
- num_domains, names, dom_sids);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
+ &hnd->pol, &enum_ctx, num_domains,
+ names, dom_sids);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
done:
return result;
}
@@ -947,54 +741,36 @@ done:
/* find the domain sid for a domain */
static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result;
TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
- char *level5_dom;
- DOM_SID *alloc_sid;
+ fstring level5_dom;
int retry;
- DEBUG(3,("rpc: domain_sid\n"));
-
- if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
+ if (!(mem_ctx = talloc_init_named("domain_sid[rpc]")))
return NT_STATUS_NO_MEMORY;
retry = 0;
do {
/* Get lsa handle */
- if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
goto done;
result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
- &hnd->pol, 0x05, &level5_dom, &alloc_sid);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
-
- if (NT_STATUS_IS_OK(result)) {
- if (alloc_sid) {
- sid_copy(sid, alloc_sid);
- } else {
- result = NT_STATUS_NO_MEMORY;
- }
- }
+ &hnd->pol, 0x05, level5_dom, sid);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
done:
talloc_destroy(mem_ctx);
return result;
}
-/* find alternate names list for the domain - none for rpc */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- return NT_STATUS_OK;
-}
-
-
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods msrpc_methods = {
False,
query_user_list,
enum_dom_groups,
- enum_local_groups,
name_to_sid,
sid_to_name,
query_user,
@@ -1002,6 +778,5 @@ struct winbindd_methods msrpc_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid,
- alternate_name
+ domain_sid
};
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index d4206558c5e..a41bf759160 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -20,25 +20,21 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
+#include "sids.h"
/* Convert a string */
enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
{
+ extern DOM_SID global_sid_Builtin;
enum SID_NAME_USE type;
- DOM_SID sid;
+ DOM_SID sid, tmp_sid;
+ uint32 rid;
fstring name;
fstring dom_name;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
state->request.data.sid));
/* Lookup sid from PDC using lsa_lookup_sids() */
@@ -48,6 +44,15 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ /* Don't look up BUILTIN sids */
+
+ sid_copy(&tmp_sid, &sid);
+ sid_split_rid(&tmp_sid, &rid);
+
+ if (sid_equal(&tmp_sid, &global_sid_Builtin)) {
+ return WINBINDD_ERROR;
+ }
+
/* Lookup the sid */
if (!winbindd_lookup_name_by_sid(&sid, dom_name, name, &type)) {
@@ -62,10 +67,8 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
+/* Convert a sid to a string */
-/**
- * Look up the SID for a qualified name.
- **/
enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
{
enum SID_NAME_USE type;
@@ -73,27 +76,14 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
char *name_domain, *name_user;
DOM_SID sid;
struct winbindd_domain *domain;
- char *p;
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
-
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
-
- /* cope with the name being a fully qualified name */
- p = strstr(state->request.data.name.name, lp_winbind_separator());
- if (p) {
- *p = 0;
- name_domain = state->request.data.name.name;
- name_user = p+1;
- } else {
- name_domain = state->request.data.name.dom_name;
- name_user = state->request.data.name.name;
- }
- DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
- name_domain, lp_winbind_separator(), name_user));
+ DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
+ state->request.data.name.dom_name,
+ lp_winbind_separator(),
+ state->request.data.name.name));
+
+ name_domain = state->request.data.name.dom_name;
+ name_user = state->request.data.name.name;
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(0, ("could not find domain entry for domain %s\n",
@@ -119,85 +109,21 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- uint32 flags = 0x0;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
state->request.data.sid));
+ /* Split sid into domain sid and user rid */
if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.sid));
return WINBINDD_ERROR;
}
-
- /* This gets a little tricky. If we assume that usernames are syncd between
- /etc/passwd and the windows domain (such as a member of a Samba domain),
- the we need to get the uid from the OS and not alocate one ourselves */
-
- if ( lp_winbind_trusted_domains_only() ) {
- struct winbindd_domain *domain = NULL;
- DOM_SID sid2;
- uint32 rid;
-
- domain = find_our_domain();
- if ( !domain ) {
- DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
- return WINBINDD_ERROR;
- }
-
- sid_copy( &sid2, &sid );
- sid_split_rid( &sid2, &rid );
-
- if ( sid_equal( &sid2, &domain->sid ) ) {
-
- fstring domain_name;
- fstring user;
- enum SID_NAME_USE type;
- struct passwd *pw = NULL;
- unid_t id;
-
- /* ok...here's we know that we are dealing with our
- own domain (the one to which we are joined). And
- we know that there must be a UNIX account for this user.
- So we lookup the sid and the call getpwnam().*/
-
-
- /* But first check and see if we don't already have a mapping */
-
- flags = ID_QUERY_ONLY;
- if ( NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) )
- return WINBINDD_OK;
-
- /* now fall back to the hard way */
-
- if ( !winbindd_lookup_name_by_sid(&sid, domain_name, user, &type) )
- return WINBINDD_ERROR;
-
- if ( !(pw = getpwnam(user)) ) {
- DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
- "set but this user [%s] doesn't exist!\n", user));
- return WINBINDD_ERROR;
- }
-
- state->response.data.uid = pw->pw_uid;
-
- id.uid = pw->pw_uid;
- idmap_set_mapping( &sid, id, ID_USERID );
-
- return WINBINDD_OK;
- }
- }
-
- if ( state->request.flags & WBFLAG_QUERY_ONLY )
- flags = ID_QUERY_ONLY;
-
/* Find uid for this sid and return it */
-
- if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) {
- DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid));
+ if (!winbindd_idmap_get_uid_from_sid(&sid, &state->response.data.uid)) {
+ DEBUG(1, ("Could not get uid for sid %s\n",
+ state->request.data.sid));
return WINBINDD_ERROR;
}
@@ -210,83 +136,20 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- uint32 flags = 0x0;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
- DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
state->request.data.sid));
if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("Could not cvt string to sid %s\n", state->request.data.sid));
+ DEBUG(1, ("Could not cvt string to sid %s\n",
+ state->request.data.sid));
return WINBINDD_ERROR;
}
- /* This gets a little tricky. If we assume that usernames are syncd between
- /etc/passwd and the windows domain (such as a member of a Samba domain),
- the we need to get the uid from the OS and not alocate one ourselves */
-
- if ( lp_winbind_trusted_domains_only() ) {
- struct winbindd_domain *domain = NULL;
- DOM_SID sid2;
- uint32 rid;
- unid_t id;
-
- domain = find_our_domain();
- if ( !domain ) {
- DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
- return WINBINDD_ERROR;
- }
-
- sid_copy( &sid2, &sid );
- sid_split_rid( &sid2, &rid );
-
- if ( sid_equal( &sid2, &domain->sid ) ) {
-
- fstring domain_name;
- fstring group;
- enum SID_NAME_USE type;
- struct group *grp = NULL;
-
- /* ok...here's we know that we are dealing with our
- own domain (the one to which we are joined). And
- we know that there must be a UNIX account for this group.
- So we lookup the sid and the call getpwnam().*/
-
- /* But first check and see if we don't already have a mapping */
-
- flags = ID_QUERY_ONLY;
- if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) )
- return WINBINDD_OK;
-
- /* now fall back to the hard way */
-
- if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) )
- return WINBINDD_ERROR;
-
- if ( !(grp = getgrnam(group)) ) {
- DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
- "set but this group [%s] doesn't exist!\n", group));
- return WINBINDD_ERROR;
- }
-
- state->response.data.gid = grp->gr_gid;
-
- id.gid = grp->gr_gid;
- idmap_set_mapping( &sid, id, ID_GROUPID );
-
- return WINBINDD_OK;
- }
-
- }
-
- if ( state->request.flags & WBFLAG_QUERY_ONLY )
- flags = ID_QUERY_ONLY;
-
/* Find gid for this sid and return it */
- if ( !NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) {
- DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid));
+ if (!winbindd_idmap_get_gid_from_sid(&sid, &state->response.data.gid)) {
+ DEBUG(1, ("Could not get gid for sid %s\n",
+ state->request.data.sid));
return WINBINDD_ERROR;
}
@@ -299,65 +162,23 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.uid));
-
- if ( (state->request.data.uid < server_state.uid_low )
- || (state->request.data.uid > server_state.uid_high) )
- {
- struct passwd *pw = NULL;
- enum SID_NAME_USE type;
- unid_t id;
- struct winbindd_domain *domain;
-
- /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
-
- /* if we don't trust /etc/password then when can't know
- anything about this uid */
-
- if ( !lp_winbind_trusted_domains_only() )
- return WINBINDD_ERROR;
-
-
- /* look for an idmap entry first */
-
- if ( NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid)) )
- goto done;
-
- /* if users exist in /etc/passwd, we should try to
- use that uid. Get the username and the lookup the SID */
-
- if ( !(pw = getpwuid(state->request.data.uid)) )
- return WINBINDD_ERROR;
-
- if ( !(domain = find_our_domain()) ) {
- DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
- return WINBINDD_ERROR;
- }
-
- if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) )
- return WINBINDD_ERROR;
-
- if ( type != SID_NAME_USER )
- return WINBINDD_ERROR;
-
- /* don't fail if we can't store it */
-
- id.uid = pw->pw_uid;
- idmap_set_mapping( &sid, id, ID_USERID );
-
- goto done;
+ /* Bug out if the uid isn't in the winbind range */
+
+ if ((state->request.data.uid < server_state.uid_low ) ||
+ (state->request.data.uid > server_state.uid_high)) {
+ return WINBINDD_ERROR;
}
+ DEBUG(3, ("[%5d]: uid to sid %d\n", state->pid,
+ state->request.data.uid));
+
/* Lookup rid for this uid */
-
- if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) {
- DEBUG(1, ("Could not convert uid %lu to rid\n",
- (unsigned long)state->request.data.uid));
+ if (!winbindd_idmap_get_sid_from_uid(state->request.data.uid, &sid)) {
+ DEBUG(1, ("Could not convert uid %d to rid\n",
+ state->request.data.uid));
return WINBINDD_ERROR;
}
-done:
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_USER;
@@ -370,87 +191,26 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.gid));
-
- if ( (state->request.data.gid < server_state.gid_low)
- || (state->request.data.gid > server_state.gid_high) )
- {
- struct group *grp = NULL;
- enum SID_NAME_USE type;
- unid_t id;
- struct winbindd_domain *domain;
-
- /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
-
- /* if we don't trust /etc/group then when can't know
- anything about this gid */
-
- if ( !lp_winbind_trusted_domains_only() )
- return WINBINDD_ERROR;
-
- /* look for an idmap entry first */
-
- if ( NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid)) )
- goto done;
-
- /* if users exist in /etc/group, we should try to
- use that gid. Get the username and the lookup the SID */
-
- if ( !(grp = getgrgid(state->request.data.gid)) )
- return WINBINDD_ERROR;
-
- if ( !(domain = find_our_domain()) ) {
- DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
- return WINBINDD_ERROR;
- }
-
- if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) )
- return WINBINDD_ERROR;
-
- if ( type!=SID_NAME_DOM_GRP && type!=SID_NAME_ALIAS )
- return WINBINDD_ERROR;
-
- /* don't fail if we can't store it */
-
- id.gid = grp->gr_gid;
- idmap_set_mapping( &sid, id, ID_GROUPID );
-
- goto done;
+ /* Bug out if the gid isn't in the winbind range */
+
+ if ((state->request.data.gid < server_state.gid_low) ||
+ (state->request.data.gid > server_state.gid_high)) {
+ return WINBINDD_ERROR;
}
+ DEBUG(3, ("[%5d]: gid to sid %d\n", state->pid,
+ state->request.data.gid));
+
/* Lookup sid for this uid */
-
- if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) {
- DEBUG(1, ("Could not convert gid %lu to sid\n",
- (unsigned long)state->request.data.gid));
+ if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &sid)) {
+ DEBUG(1, ("Could not convert gid %d to sid\n",
+ state->request.data.gid));
return WINBINDD_ERROR;
}
-done:
/* Construct sid and return it */
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_DOM_GRP;
return WINBINDD_OK;
}
-
-enum winbindd_result winbindd_allocate_rid(struct winbindd_cli_state *state)
-{
- if ( !state->privileged ) {
- DEBUG(2, ("winbindd_allocate_rid: non-privileged access "
- "denied!\n"));
- return WINBINDD_ERROR;
- }
-
- /* We tell idmap to always allocate a user RID. There might be a good
- * reason to keep RID allocation for users to even and groups to
- * odd. This needs discussion I think. For now only allocate user
- * rids. */
-
- if (!NT_STATUS_IS_OK(idmap_allocate_rid(&state->response.data.rid,
- USER_RID_TYPE)))
- return WINBINDD_ERROR;
-
- return WINBINDD_OK;
-}
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index 18782641fcc..fb5394ea142 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -3,9 +3,8 @@
Winbind daemon - user related functions
- Copyright (C) Tim Potter 2000
+ Copyright (C) Tim Potter 2000,2002
Copyright (C) Jeremy Allison 2001.
- Copyright (C) Gerald (Jerry) Carter 2003.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,39 +21,34 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-extern userdom_struct current_user_info;
-
/* Fill a pwent structure with information we have obtained */
static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
- DOM_SID *user_sid, DOM_SID *group_sid,
+ uint32 user_rid, uint32 group_rid,
char *full_name, struct winbindd_pw *pw)
{
+ extern userdom_struct current_user_info;
fstring output_username;
- char *homedir;
- char *shell;
- fstring sid_string;
+ pstring homedir;
if (!pw || !dom_name || !user_name)
return False;
/* Resolve the uid number */
-
- if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &(pw->pw_uid), 0))) {
- DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid)));
+
+ if (!winbindd_idmap_get_uid_from_rid(dom_name, user_rid,
+ &pw->pw_uid)) {
+ DEBUG(1, ("error getting user id for rid %d\n", user_rid));
return False;
}
/* Resolve the gid number */
-
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &(pw->pw_gid), 0))) {
- DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid)));
+
+ if (!winbindd_idmap_get_gid_from_rid(dom_name, group_rid,
+ &pw->pw_gid)) {
+ DEBUG(1, ("error getting group id for rid %d\n", group_rid));
return False;
}
@@ -73,32 +67,24 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
shell. */
/* The substitution of %U and %D in the 'template homedir' is done
- by alloc_sub_specified() below. */
+ by lp_string() calling standard_sub_basic(). */
+ fstrcpy(current_user_info.smb_name, user_name);
+ sub_set_smb_name(user_name);
fstrcpy(current_user_info.domain, dom_name);
- homedir = alloc_sub_specified(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
-
- if (!homedir)
- return False;
+ pstrcpy(homedir, lp_template_homedir());
safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
- SAFE_FREE(homedir);
-
- shell = alloc_sub_specified(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
-
- if (!shell)
- return False;
-
- safe_strcpy(pw->pw_shell, shell,
+ safe_strcpy(pw->pw_shell, lp_template_shell(),
sizeof(pw->pw_shell) - 1);
/* Password - set to "x" as we can't generate anything useful here.
Authentication can be done using the pam_winbind module. */
safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1);
-
+
return True;
}
@@ -106,8 +92,8 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
{
+ uint32 user_rid;
WINBIND_USERINFO user_info;
- WINBINDD_PW *pw;
DOM_SID user_sid;
NTSTATUS status;
fstring name_domain, name_user;
@@ -115,42 +101,20 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
struct winbindd_domain *domain;
TALLOC_CTX *mem_ctx;
- /* Ensure null termination */
- state->request.data.username[sizeof(state->request.data.username)-1]='\0';
-
- DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
state->request.data.username));
/* Parse domain and username */
- parse_domain_user(state->request.data.username,
- name_domain, name_user);
-
- /* if this is our local domain (or no domain), the do a local tdb search */
-
- if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) {
- if ( !(pw = wb_getpwnam(name_user)) ) {
- DEBUG(5,("winbindd_getpwnam: lookup for %s\\%s failed\n",
- name_domain, name_user));
- return WINBINDD_ERROR;
- }
- memcpy( &state->response.data.pw, pw, sizeof(WINBINDD_PW) );
- return WINBINDD_OK;
- }
-
- /* should we deal with users for our domain? */
+ if (!parse_domain_user(state->request.data.username, name_domain,
+ name_user))
+ return WINBINDD_ERROR;
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(5, ("no such domain: %s\n", name_domain));
return WINBINDD_ERROR;
}
- if ( domain->primary && lp_winbind_trusted_domains_only()) {
- DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
- name_domain, name_user));
- return WINBINDD_ERROR;
- }
-
/* Get rid and name type from name */
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, &name_type)) {
@@ -158,21 +122,25 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) {
+ if (name_type != SID_NAME_USER) {
DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
name_type));
return WINBINDD_ERROR;
}
- /* Get some user info. */
+ /* Get some user info. Split the user rid from the sid obtained
+ from the winbind_lookup_by_name() call and use it in a
+ winbind_lookup_userinfo() */
- if (!(mem_ctx = talloc_init("winbindd_getpwnam([%s]\\[%s])",
+ if (!(mem_ctx = talloc_init_named("winbindd_getpwnam([%s]\\[%s])",
name_domain, name_user))) {
DEBUG(1, ("out of memory\n"));
return WINBINDD_ERROR;
}
- status = domain->methods->query_user(domain, mem_ctx, &user_sid,
+ sid_split_rid(&user_sid, &user_rid);
+
+ status = domain->methods->query_user(domain, mem_ctx, user_rid,
&user_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -184,7 +152,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
/* Now take all this information and fill in a passwd structure */
if (!winbindd_fill_pwent(name_domain, name_user,
- user_info.user_sid, user_info.group_sid,
+ user_rid, user_info.group_rid,
user_info.full_name,
&state->response.data.pw)) {
talloc_destroy(mem_ctx);
@@ -202,14 +170,14 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
{
DOM_SID user_sid;
struct winbindd_domain *domain;
- WINBINDD_PW *pw;
+ uint32 user_rid;
fstring dom_name;
fstring user_name;
enum SID_NAME_USE name_type;
WINBIND_USERINFO user_info;
+ gid_t gid;
TALLOC_CTX *mem_ctx;
NTSTATUS status;
- gid_t gid;
/* Bug out if the uid isn't in the winbind range */
@@ -217,26 +185,23 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
(state->request.data.uid > server_state.uid_high))
return WINBINDD_ERROR;
- DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.uid));
-
- /* always try local tdb first */
-
- if ( (pw = wb_getpwuid(state->request.data.uid)) != NULL ) {
- memcpy( &state->response.data.pw, pw, sizeof(WINBINDD_PW) );
- return WINBINDD_OK;
- }
+ DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
+ state->request.data.uid));
/* Get rid from uid */
- if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&user_sid, state->request.data.uid))) {
- DEBUG(1, ("could not convert uid %lu to SID\n",
- (unsigned long)state->request.data.uid));
+ if (!winbindd_idmap_get_rid_from_uid(state->request.data.uid,
+ &user_rid, &domain)) {
+ DEBUG(1, ("could not convert uid %d to rid\n",
+ state->request.data.uid));
return WINBINDD_ERROR;
}
/* Get name and name type from rid */
+ sid_copy(&user_sid, &domain->sid);
+ sid_append_rid(&user_sid, user_rid);
+
if (!winbindd_lookup_name_by_sid(&user_sid, dom_name, user_name, &name_type)) {
fstring temp;
@@ -245,23 +210,16 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- domain = find_domain_from_sid(&user_sid);
-
- if (!domain) {
- DEBUG(1,("Can't find domain from sid\n"));
- return WINBINDD_ERROR;
- }
-
/* Get some user info */
- if (!(mem_ctx = talloc_init("winbind_getpwuid(%lu)",
- (unsigned long)state->request.data.uid))) {
+ if (!(mem_ctx = talloc_init_named("winbind_getpwuid(%d)",
+ state->request.data.uid))) {
DEBUG(1, ("out of memory\n"));
return WINBINDD_ERROR;
}
- status = domain->methods->query_user(domain, mem_ctx, &user_sid,
+ status = domain->methods->query_user(domain, mem_ctx, user_rid,
&user_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -271,9 +229,9 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- /* Check group has a gid number */
+ /* Resolve gid number */
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_info.group_sid, &gid, 0))) {
+ if (!winbindd_idmap_get_gid_from_rid(domain->name, user_info.group_rid, &gid)) {
DEBUG(1, ("error getting group id for user %s\n", user_name));
talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
@@ -281,8 +239,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
/* Fill in password structure */
- if (!winbindd_fill_pwent(domain->name, user_name, user_info.user_sid,
- user_info.group_sid,
+ if (!winbindd_fill_pwent(domain->name, user_name, user_rid, user_info.group_rid,
user_info.full_name, &state->response.data.pw)) {
talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
@@ -303,7 +260,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
- DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: setpwent\n", state->pid));
/* Check user has enabled this */
@@ -316,35 +273,22 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
free_getent_state(state->getpwent_state);
state->getpwent_state = NULL;
}
-
-#if 0 /* JERRY */
- /* add any local users we have */
-
- if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL )
- return WINBINDD_ERROR;
-
- ZERO_STRUCTP(domain_state);
-
- /* Add to list of open domains */
-
- DLIST_ADD(state->getpwent_state, domain_state);
-#endif
/* Create sam pipes for each domain we know about */
for(domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
-
- /* don't add our domaina if we are a PDC or if we
- are a member of a Samba domain */
-
- if ( (IS_DC || lp_winbind_trusted_domains_only())
- && strequal(domain->name, lp_workgroup()) )
- {
+ /*
+ * Skip domains other than WINBINDD_DOMAIN environment
+ * variable.
+ */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain,
+ domain->name))
continue;
- }
-
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
@@ -360,8 +304,6 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
DLIST_ADD(state->getpwent_state, domain_state);
}
- state->getpwent_initialized = True;
-
return WINBINDD_OK;
}
@@ -369,10 +311,9 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: endpwent\n", state->pid));
free_getent_state(state->getpwent_state);
- state->getpwent_initialized = False;
state->getpwent_state = NULL;
return WINBINDD_OK;
@@ -395,13 +336,13 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
TALLOC_CTX *mem_ctx;
struct winbindd_domain *domain;
struct winbindd_methods *methods;
- unsigned int i;
+ int i;
if (ent->num_sam_entries)
return False;
- if (!(mem_ctx = talloc_init("get_sam_user_entries(%s)",
- ent->domain_name)))
+ if (!(mem_ctx = talloc_init_named("get_sam_user_entries(%s)",
+ ent->domain_name)))
return False;
if (!(domain = find_domain_from_name(ent->domain_name))) {
@@ -456,8 +397,8 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
}
/* User and group ids */
- sid_copy(&name_list[ent->num_sam_entries+i].user_sid, info[i].user_sid);
- sid_copy(&name_list[ent->num_sam_entries+i].group_sid, info[i].group_sid);
+ name_list[ent->num_sam_entries+i].user_rid = info[i].user_rid;
+ name_list[ent->num_sam_entries+i].group_rid = info[i].group_rid;
}
ent->num_sam_entries += num_entries;
@@ -485,7 +426,7 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
struct winbindd_pw *user_list;
int num_users, user_list_ndx = 0, i;
- DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: getpwent\n", state->pid));
/* Check user has enabled this */
@@ -504,9 +445,6 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
sizeof(struct winbindd_pw));
user_list = (struct winbindd_pw *)state->response.extra_data;
-
- if (!state->getpwent_initialized)
- winbindd_setpwent(state);
if (!(ent = state->getpwent_state))
return WINBINDD_ERROR;
@@ -520,9 +458,30 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
/* Do we need to fetch another chunk of users? */
if (ent->num_sam_entries == ent->sam_entry_index) {
+ struct getent_state *next_ent;
+
+ /* is this the beginning ( == 0 ) or the end ? */
+
+ /*
+ * for some reason this check is not needed here, but is
+ * in winbindd_getgrent(). I'm putting it in but ifdef'd
+ * out for posterity --jerry
+ */
+#if 0 /* NOT NEEDED APPARENTLY */
+
+ if ( ent->sam_entry_index > 0 ) {
+ DEBUG(10, ("end of getpwent: freeing state info for domain %s\n", ent->domain_name));
+ SAFE_FREE(ent->sam_entries);
+ next_ent = ent->next;
+ DLIST_REMOVE(state->getgrent_state, ent);
+ SAFE_FREE(ent);
+ ent = next_ent;
+ }
+#endif /* NOT NEEDED APPARENTLY */
+
+ /* find the next domain's group entries */
while(ent && !get_sam_user_entries(ent)) {
- struct getent_state *next_ent;
/* Free state information for this domain */
@@ -543,13 +502,22 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
name_list = ent->sam_entries;
+ /* Skip machine accounts */
+
+ if (name_list[ent->sam_entry_index].
+ name[strlen(name_list[ent->sam_entry_index].name) - 1]
+ == '$') {
+ ent->sam_entry_index++;
+ continue;
+ }
+
/* Lookup user info */
result = winbindd_fill_pwent(
ent->domain_name,
name_list[ent->sam_entry_index].name,
- &name_list[ent->sam_entry_index].user_sid,
- &name_list[ent->sam_entry_index].group_sid,
+ name_list[ent->sam_entry_index].user_rid,
+ name_list[ent->sam_entry_index].group_rid,
name_list[ent->sam_entry_index].gecos,
&user_list[user_list_ndx]);
@@ -580,46 +548,57 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
WINBIND_USERINFO *info;
- const char *which_domain;
uint32 num_entries = 0, total_entries = 0;
char *ted, *extra_data = NULL;
int extra_data_len = 0;
TALLOC_CTX *mem_ctx;
enum winbindd_result rv = WINBINDD_ERROR;
- DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid));
+ DEBUG(3, ("[%5d]: list users\n", state->pid));
- if (!(mem_ctx = talloc_init("winbindd_list_users")))
+ if (!(mem_ctx = talloc_init_named("winbindd_list_users")))
return WINBINDD_ERROR;
- /* Ensure null termination */
- state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
- which_domain = state->request.domain_name;
-
/* Enumerate over trusted domains */
for (domain = domain_list(); domain; domain = domain->next) {
NTSTATUS status;
struct winbindd_methods *methods;
- unsigned int i;
-
- /* if we have a domain name restricting the request and this
- one in the list doesn't match, then just bypass the remainder
- of the loop */
-
- if ( *which_domain && !strequal(which_domain, domain->name) )
+ int i;
+
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
continue;
-
+
methods = domain->methods;
/* Query display info */
- status = methods->query_user_list(domain, mem_ctx,
- &num_entries, &info);
+
+ status = methods->query_user_list(
+ domain, mem_ctx, &num_entries, &info);
+
+ /* If an error occured on this domain, set the extended error
+ info and continue to the next domain. If we receive
+ NT_STATUS_MORE_PROCESSING_REQUIRED then cached data was
+ returned but we couldn't contact the DC for the sequence
+ number. */
+
+ if (!NT_STATUS_IS_OK(status)) {
+ state->response.nt_status = NT_STATUS_V(status);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
+ continue;
+ }
+
+ /* No entries for this domain */
if (num_entries == 0)
continue;
/* Allocate some memory for extra data */
+
total_entries += num_entries;
ted = Realloc(extra_data, sizeof(fstring) * total_entries);
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 7e3fd99dac2..78ea7d16dbb 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -21,11 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
+#include "sids.h"
/**
* @file winbindd_util.c
@@ -49,21 +46,12 @@ static const fstring name_deadbeef = "<deadbeef>";
static struct winbindd_domain *_domain_list;
-/**
- When was the last scan of trusted domains done?
-
- 0 == not ever
-*/
-
-static time_t last_trustdom_scan;
-
struct winbindd_domain *domain_list(void)
{
/* Initialise list */
- if (!_domain_list)
- if (!init_domain_list())
- return NULL;
+ if (!_domain_list)
+ init_domain_list();
return _domain_list;
}
@@ -83,282 +71,108 @@ void free_domain_list(void)
}
}
-static BOOL is_internal_domain(const DOM_SID *sid)
-{
- DOM_SID tmp_sid;
-
- if (sid_equal(sid, get_global_sam_sid()))
- return True;
-
- string_to_sid(&tmp_sid, "S-1-5-32");
- if (sid_equal(sid, &tmp_sid))
- return True;
-
- return False;
-}
-
-
/* Add a trusted domain to our list of domains */
-static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
- struct winbindd_methods *methods,
- DOM_SID *sid)
+
+static struct winbindd_domain *add_trusted_domain(char *domain_name,
+ struct winbindd_methods *methods)
{
struct winbindd_domain *domain;
- const char *alternative_name = NULL;
- static const DOM_SID null_sid;
-
- /* ignore alt_name if we are not in an AD domain */
-
- if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
- alternative_name = alt_name;
- }
/* We can't call domain_list() as this function is called from
init_domain_list() and we'll get stuck in a loop. */
+
for (domain = _domain_list; domain; domain = domain->next) {
- if (strequal(domain_name, domain->name) ||
- strequal(domain_name, domain->alt_name)) {
+ if (strcmp(domain_name, domain->name) == 0) {
+ DEBUG(3, ("domain %s already in domain list\n",
+ domain_name));
return domain;
}
- if (alternative_name && *alternative_name) {
- if (strequal(alternative_name, domain->name) ||
- strequal(alternative_name, domain->alt_name)) {
- return domain;
- }
- }
- if (sid) {
- if (sid_equal(sid, &null_sid) ) {
-
- } else if (sid_equal(sid, &domain->sid)) {
- return domain;
- }
- }
}
/* Create new domain entry */
- if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL)
+ if ((domain = (struct winbindd_domain *)
+ malloc(sizeof(*domain))) == NULL)
return NULL;
/* Fill in fields */
ZERO_STRUCTP(domain);
- /* prioritise the short name */
- if (strchr_m(domain_name, '.') && alternative_name && *alternative_name) {
- fstrcpy(domain->name, alternative_name);
- fstrcpy(domain->alt_name, domain_name);
- } else {
- fstrcpy(domain->name, domain_name);
- if (alternative_name) {
- fstrcpy(domain->alt_name, alternative_name);
- }
- }
-
- domain->methods = methods;
- domain->backend = NULL;
- domain->internal = is_internal_domain(sid);
+ fstrcpy(domain->name, domain_name);
+ domain->methods = methods;
domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
- if (sid) {
- sid_copy(&domain->sid, sid);
- }
-
- /* set flags about native_mode, active_directory */
-
- if (!domain->internal)
- set_dc_type_and_flags( domain );
-
- DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name,
- domain->active_directory ? "ADS" : "NT4",
- domain->native_mode ? "native mode" :
- ((domain->active_directory && !domain->native_mode) ? "mixed mode" : "")));
/* Link to domain list */
- DLIST_ADD(_domain_list, domain);
- DEBUG(1,("Added domain %s %s %s\n",
- domain->name, domain->alt_name,
- &domain->sid?sid_string_static(&domain->sid):""));
+ DLIST_ADD(_domain_list, domain);
return domain;
}
-/********************************************************************
- rescan our domains looking for new trusted domains
-********************************************************************/
+/* Look up global info for the winbind daemon */
-static void add_trusted_domains( struct winbindd_domain *domain )
+BOOL init_domain_list(void)
{
- TALLOC_CTX *mem_ctx;
NTSTATUS result;
- time_t t;
+ TALLOC_CTX *mem_ctx;
+ extern struct winbindd_methods cache_methods;
+ struct winbindd_domain *domain;
+ DOM_SID *dom_sids;
char **names;
- char **alt_names;
int num_domains = 0;
- DOM_SID *dom_sids, null_sid;
- int i;
- struct winbindd_domain *new_domain;
- /* trusted domains might be disabled */
- if (!lp_allow_trusted_domains()) {
- return;
- }
-
- DEBUG(5, ("scanning trusted domain list\n"));
+ if (!(mem_ctx = talloc_init_named("init_domain_list")))
+ return False;
- if (!(mem_ctx = talloc_init("init_domain_list")))
- return;
-
- ZERO_STRUCTP(&null_sid);
+ /* Free existing list */
- t = time(NULL);
-
- /* ask the DC what domains it trusts */
-
- result = domain->methods->trusted_domains(domain, mem_ctx, (unsigned int *)&num_domains,
- &names, &alt_names, &dom_sids);
-
- if ( NT_STATUS_IS_OK(result) ) {
+ free_domain_list();
- /* Add each domain to the trusted domain list */
-
- for(i = 0; i < num_domains; i++) {
- DEBUG(10,("Found domain %s\n", names[i]));
- add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
- domain->methods, &dom_sids[i]);
-
- /* if the SID was empty, we better set it now */
-
- if ( sid_equal(&dom_sids[i], &null_sid) ) {
-
- new_domain = find_domain_from_name(names[i]);
-
- /* this should never happen */
- if ( !new_domain ) {
- DEBUG(0,("rescan_trust_domains: can't find the domain I just added! [%s]\n",
- names[i]));
- break;
- }
-
- /* call the cache method; which will operate on the winbindd_domain \
- passed in and choose either rpc or ads as appropriate */
-
- result = domain->methods->domain_sid( new_domain, &new_domain->sid );
-
- if ( NT_STATUS_IS_OK(result) )
- sid_copy( &dom_sids[i], &new_domain->sid );
- }
-
- /* store trusted domain in the cache */
- trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL,
- &dom_sids[i], t + WINBINDD_RESCAN_FREQ);
- }
- }
+ /* Add ourselves as the first entry */
- talloc_destroy(mem_ctx);
-}
+ domain = add_trusted_domain(lp_workgroup(), &cache_methods);
-/********************************************************************
- Periodically we need to refresh the trusted domain cache for smbd
-********************************************************************/
+ /* Now we *must* get the domain sid for our primary domain. Go into
+ a holding pattern until that is available */
-void rescan_trusted_domains( void )
-{
- time_t now = time(NULL);
- struct winbindd_domain *mydomain = NULL;
-
- /* see if the time has come... */
-
- if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
- return;
-
- if ( (mydomain = find_our_domain()) == NULL ) {
- DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n"));
- return;
+ result = cache_methods.domain_sid(domain, &domain->sid);
+ while (!NT_STATUS_IS_OK(result)) {
+ sleep(10);
+ DEBUG(1,("Retrying startup domain sid fetch for %s\n",
+ domain->name));
+ result = cache_methods.domain_sid(domain, &domain->sid);
}
-
- /* this will only add new domains we didn't already know about */
-
- add_trusted_domains( mydomain );
+
+ DEBUG(1,("Added domain %s (%s)\n",
+ domain->name,
+ sid_string_static(&domain->sid)));
- last_trustdom_scan = now;
-
- return;
-}
+ DEBUG(1, ("getting trusted domain list\n"));
-/* Look up global info for the winbind daemon */
-BOOL init_domain_list(void)
-{
- extern struct winbindd_methods cache_methods;
- struct winbindd_domain *domain;
-
- /* Free existing list */
- free_domain_list();
+ result = cache_methods.trusted_domains(domain, mem_ctx, (uint *)&num_domains,
+ &names, &dom_sids);
- /* Add ourselves as the first entry. */
-
- domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL);
-
- domain->primary = True;
-
- /* get any alternate name for the primary domain */
-
- cache_methods.alternate_name(domain);
-
- /* now we have the correct netbios (short) domain name */
-
- if ( *domain->name )
- set_global_myworkgroup( domain->name );
-
- if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) {
- DEBUG(1, ("Could not fetch sid for our domain %s\n",
- domain->name));
- return False;
+ /* Add each domain to the trusted domain list */
+ if (NT_STATUS_IS_OK(result)) {
+ int i;
+ for(i = 0; i < num_domains; i++) {
+ domain = add_trusted_domain(names[i], &cache_methods);
+ if (!domain) continue;
+ sid_copy(&domain->sid, &dom_sids[i]);
+ DEBUG(1,("Added domain %s (%s)\n",
+ domain->name,
+ sid_string_static(&domain->sid)));
+ }
}
- /* do an initial scan for trusted domains */
- add_trusted_domains(domain);
-
- /* Don't expand aliases if not explicitly activated -- for now */
- /* we don't support windows local nested groups if we are a DC.
- refer to to sid_to_gid() in the smbd server code to see why
- -- jerry */
-
-
- if (lp_winbind_nested_groups() || IS_DC) {
-
- /* Add our local SAM domains */
- DOM_SID sid;
- extern struct winbindd_methods passdb_methods;
- struct winbindd_domain *dom;
-
- string_to_sid(&sid, "S-1-5-32");
-
- dom = add_trusted_domain("BUILTIN", NULL, &passdb_methods,
- &sid);
-
- dom = add_trusted_domain(get_global_sam_name(), NULL,
- &passdb_methods,
- get_global_sam_sid());
- }
-
- /* avoid rescanning this right away */
- last_trustdom_scan = time(NULL);
+ talloc_destroy(mem_ctx);
return True;
}
-/**
- * Given a domain name, return the struct winbindd domain info for it
- *
- * @note Do *not* pass lp_workgroup() to this function. domain_list
- * may modify it's value, and free that pointer. Instead, our local
- * domain may be found by calling find_our_domain().
- * directly.
- *
- *
- * @return The domain structure for the named domain, if it is working.
- */
+/* Given a domain name, return the struct winbindd domain info for it
+ if it is actually working. */
struct winbindd_domain *find_domain_from_name(const char *domain_name)
{
@@ -368,9 +182,8 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
for (domain = domain_list(); domain != NULL; domain = domain->next) {
if (strequal(domain_name, domain->name) ||
- (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) {
+ strequal(domain_name, domain->full_name))
return domain;
- }
}
/* Not found */
@@ -380,7 +193,7 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
/* Given a domain sid, return the struct winbindd domain info for it */
-struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
{
struct winbindd_domain *domain;
@@ -396,24 +209,6 @@ struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
return NULL;
}
-/* Given a domain sid, return the struct winbindd domain info for it */
-
-struct winbindd_domain *find_our_domain(void)
-{
- struct winbindd_domain *domain;
-
- /* Search through list */
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- if (domain->primary)
- return domain;
- }
-
- /* Not found */
-
- return NULL;
-}
-
/* Lookup a sid in a domain from a name */
BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
@@ -421,16 +216,14 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
enum SID_NAME_USE *type)
{
NTSTATUS result;
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name);
- if (!mem_ctx)
- return False;
- /* Lookup name */
- result = domain->methods->name_to_sid(domain, mem_ctx, name, sid, type);
+ /* Don't bother with machine accounts */
+
+ if (name[strlen(name) - 1] == '$')
+ return False;
- talloc_destroy(mem_ctx);
+ /* Lookup name */
+ result = domain->methods->name_to_sid(domain, name, sid, type);
/* Return rid and type if lookup successful */
if (!NT_STATUS_IS_OK(result)) {
@@ -444,10 +237,14 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
* @brief Lookup a name in a domain from a sid.
*
* @param sid Security ID you want to look up.
+ *
* @param name On success, set to the name corresponding to @p sid.
+ *
* @param dom_name On success, set to the 'domain name' corresponding to @p sid.
+ *
* @param type On success, contains the type of name: alias, group or
* user.
+ *
* @retval True if the name exists, in which case @p name and @p type
* are set, otherwise False.
**/
@@ -471,7 +268,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
/* Lookup name */
- if (!(mem_ctx = talloc_init("winbindd_lookup_name_by_sid")))
+ if (!(mem_ctx = talloc_init_named("winbindd_lookup_name_by_sid")))
return False;
result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type);
@@ -516,21 +313,19 @@ void free_getent_state(struct getent_state *state)
}
}
-/* Parse winbindd related parameters */
+/* Initialise trusted domain info */
BOOL winbindd_param_init(void)
{
/* Parse winbind uid and winbind_gid parameters */
- if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) {
- DEBUG(0, ("winbindd: idmap uid range missing or invalid\n"));
- DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
+ if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
+ DEBUG(0, ("winbind uid range missing or invalid\n"));
return False;
}
- if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) {
- DEBUG(0, ("winbindd: idmap gid range missing or invalid\n"));
- DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
+ if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
+ DEBUG(0, ("winbind gid range missing or invalid\n"));
return False;
}
@@ -552,43 +347,25 @@ BOOL check_domain_env(char *domain_env, char *domain)
return False;
}
-/* Is this a domain which we may assume no DOMAIN\ prefix? */
-
-static BOOL assume_domain(const char *domain) {
- if ((lp_winbind_use_default_domain()
- || lp_winbind_trusted_domains_only()) &&
- strequal(lp_workgroup(), domain))
- return True;
-
- if (strequal(get_global_sam_name(), domain))
- return True;
-
- return False;
-}
-
/* Parse a string of the form DOMAIN/user into a domain and a user */
+extern fstring global_myworkgroup;
BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
{
char *p = strchr(domuser,*lp_winbind_separator());
- if ( !p ) {
+ if (!(p || lp_winbind_use_default_domain()))
+ return False;
+
+ if(!p && lp_winbind_use_default_domain()) {
fstrcpy(user, domuser);
-
- if ( assume_domain(lp_workgroup())) {
- fstrcpy(domain, lp_workgroup());
- } else {
- fstrcpy( domain, get_global_sam_name() );
- }
- }
- else {
+ fstrcpy(domain, global_myworkgroup);
+ } else {
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
}
-
- strupper_m(domain);
-
+ strupper(domain);
return True;
}
@@ -597,17 +374,13 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
'winbind separator' options.
This means:
- omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
- lp_workgroup()
-
- If we are a PDC or BDC, and this is for our domain, do likewise.
-
- Also, if omit DOMAIN if 'winbind trusted domains only = true', as the
- username is then unqualified in unix
+ global_myworkgroup
*/
void fill_domain_username(fstring name, const char *domain, const char *user)
{
- if (assume_domain(domain)) {
+ if(lp_winbind_use_default_domain() &&
+ !strcmp(global_myworkgroup, domain)) {
strlcpy(name, user, sizeof(fstring));
} else {
slprintf(name, sizeof(fstring) - 1, "%s%s%s",
@@ -615,385 +388,3 @@ void fill_domain_username(fstring name, const char *domain, const char *user)
user);
}
}
-
-/*
- * Winbindd socket accessor functions
- */
-
-char *get_winbind_priv_pipe_dir(void)
-{
- return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
-}
-
-/* Open the winbindd socket */
-
-static int _winbindd_socket = -1;
-static int _winbindd_priv_socket = -1;
-
-int open_winbindd_socket(void)
-{
- if (_winbindd_socket == -1) {
- _winbindd_socket = create_pipe_sock(
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);
- DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
- _winbindd_socket));
- }
-
- return _winbindd_socket;
-}
-
-int open_winbindd_priv_socket(void)
-{
- if (_winbindd_priv_socket == -1) {
- _winbindd_priv_socket = create_pipe_sock(
- get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
- DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
- _winbindd_priv_socket));
- }
-
- return _winbindd_priv_socket;
-}
-
-/* Close the winbindd socket */
-
-void close_winbindd_socket(void)
-{
- if (_winbindd_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_socket));
- close(_winbindd_socket);
- _winbindd_socket = -1;
- }
- if (_winbindd_priv_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_priv_socket));
- close(_winbindd_priv_socket);
- _winbindd_priv_socket = -1;
- }
-}
-
-/*
- * Client list accessor functions
- */
-
-static struct winbindd_cli_state *_client_list;
-static int _num_clients;
-
-/* Return list of all connected clients */
-
-struct winbindd_cli_state *winbindd_client_list(void)
-{
- return _client_list;
-}
-
-/* Add a connection to the list */
-
-void winbindd_add_client(struct winbindd_cli_state *cli)
-{
- DLIST_ADD(_client_list, cli);
- _num_clients++;
-}
-
-/* Remove a client from the list */
-
-void winbindd_remove_client(struct winbindd_cli_state *cli)
-{
- DLIST_REMOVE(_client_list, cli);
- _num_clients--;
-}
-
-/* Close all open clients */
-
-void winbindd_kill_all_clients(void)
-{
- struct winbindd_cli_state *cl = winbindd_client_list();
-
- DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
-
- while (cl) {
- struct winbindd_cli_state *next;
-
- next = cl->next;
- winbindd_remove_client(cl);
- cl = next;
- }
-}
-
-/* Return number of open clients */
-
-int winbindd_num_clients(void)
-{
- return _num_clients;
-}
-
-/* Help with RID -> SID conversion */
-
-DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 rid)
-{
- DOM_SID *sid;
- sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid) {
- smb_panic("rid_to_to_talloced_sid: talloc for DOM_SID failed!\n");
- }
- sid_copy(sid, &domain->sid);
- sid_append_rid(sid, rid);
- return sid;
-}
-
-/*****************************************************************************
- For idmap conversion: convert one record to new format
- Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid
- instead of the SID.
-*****************************************************************************/
-static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct winbindd_domain *domain;
- char *p;
- DOM_SID sid;
- uint32 rid;
- fstring keystr;
- fstring dom_name;
- TDB_DATA key2;
- BOOL *failed = (BOOL *)state;
-
- DEBUG(10,("Converting %s\n", key.dptr));
-
- p = strchr(key.dptr, '/');
- if (!p)
- return 0;
-
- *p = 0;
- fstrcpy(dom_name, key.dptr);
- *p++ = '/';
-
- domain = find_domain_from_name(dom_name);
- if (domain == NULL) {
- /* We must delete the old record. */
- DEBUG(0,("Unable to find domain %s\n", dom_name ));
- DEBUG(0,("deleting record %s\n", key.dptr ));
-
- if (tdb_delete(tdb, key) != 0) {
- DEBUG(0, ("Unable to delete record %s\n", key.dptr));
- *failed = True;
- return -1;
- }
-
- return 0;
- }
-
- rid = atoi(p);
-
- sid_copy(&sid, &domain->sid);
- sid_append_rid(&sid, rid);
-
- sid_to_string(keystr, &sid);
- key2.dptr = keystr;
- key2.dsize = strlen(keystr) + 1;
-
- if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) {
- DEBUG(0,("Unable to add record %s\n", key2.dptr ));
- *failed = True;
- return -1;
- }
-
- if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) {
- DEBUG(0,("Unable to update record %s\n", data.dptr ));
- *failed = True;
- return -1;
- }
-
- if (tdb_delete(tdb, key) != 0) {
- DEBUG(0,("Unable to delete record %s\n", key.dptr ));
- *failed = True;
- return -1;
- }
-
- return 0;
-}
-
-/* These definitions are from sam/idmap_tdb.c. Replicated here just
- out of laziness.... :-( */
-
-/* High water mark keys */
-#define HWM_GROUP "GROUP HWM"
-#define HWM_USER "USER HWM"
-
-/* idmap version determines auto-conversion */
-#define IDMAP_VERSION 2
-
-
-/*****************************************************************************
- Convert the idmap database from an older version.
-*****************************************************************************/
-
-static BOOL idmap_convert(const char *idmap_name)
-{
- int32 vers;
- BOOL bigendianheader;
- BOOL failed = False;
- TDB_CONTEXT *idmap_tdb;
-
- if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
- TDB_DEFAULT, O_RDWR,
- 0600))) {
- DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
- return False;
- }
-
- bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
-
- vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
-
- if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
- /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
- /*
- * high and low records were created on a
- * big endian machine and will need byte-reversing.
- */
-
- int32 wm;
-
- wm = tdb_fetch_int32(idmap_tdb, HWM_USER);
-
- if (wm != -1) {
- wm = IREV(wm);
- } else {
- wm = server_state.uid_low;
- }
-
- if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {
- DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n"));
- tdb_close(idmap_tdb);
- return False;
- }
-
- wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);
- if (wm != -1) {
- wm = IREV(wm);
- } else {
- wm = server_state.gid_low;
- }
-
- if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {
- DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));
- tdb_close(idmap_tdb);
- return False;
- }
- }
-
- /* the old format stored as DOMAIN/rid - now we store the SID direct */
- tdb_traverse(idmap_tdb, convert_fn, &failed);
-
- if (failed) {
- DEBUG(0, ("Problem during conversion\n"));
- tdb_close(idmap_tdb);
- return False;
- }
-
- if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
- DEBUG(0, ("idmap_convert: Unable to dtore idmap version in databse\n"));
- tdb_close(idmap_tdb);
- return False;
- }
-
- tdb_close(idmap_tdb);
- return True;
-}
-
-/*****************************************************************************
- Convert the idmap database from an older version if necessary
-*****************************************************************************/
-
-BOOL winbindd_upgrade_idmap(void)
-{
- pstring idmap_name;
- pstring backup_name;
- SMB_STRUCT_STAT stbuf;
- TDB_CONTEXT *idmap_tdb;
-
- pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb"));
-
- if (!file_exist(idmap_name, &stbuf)) {
- /* nothing to convert return */
- return True;
- }
-
- if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
- TDB_DEFAULT, O_RDWR,
- 0600))) {
- DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
- return False;
- }
-
- if (tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION") == IDMAP_VERSION) {
- /* nothing to convert return */
- tdb_close(idmap_tdb);
- return True;
- }
-
- /* backup_tdb expects the tdb not to be open */
- tdb_close(idmap_tdb);
-
- DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
-
- pstrcpy(backup_name, idmap_name);
- pstrcat(backup_name, ".bak");
-
- if (backup_tdb(idmap_name, backup_name) != 0) {
- DEBUG(0, ("Could not backup idmap database\n"));
- return False;
- }
-
- return idmap_convert(idmap_name);
-}
-
-/*******************************************************************
- wrapper around retrieving the trust account password
-*******************************************************************/
-
-BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
- time_t *pass_last_set_time, uint32 *channel)
-{
- DOM_SID sid;
- char *pwd;
-
- /* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
- {
- if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- pass_last_set_time) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for trusted domain %s\n", domain));
- return False;
- }
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
-
- return True;
- }
- else /* just get the account for our domain (covers
- ROLE_DOMAIN_MEMBER as well */
- {
- /* get the machine trust account for our domain */
-
- if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
- pass_last_set_time, channel) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for my domain %s\n", domain));
- return False;
- }
-
- return True;
- }
-
- /* Failure */
-}
-
diff --git a/source/nsswitch/winbindd_wins.c b/source/nsswitch/winbindd_wins.c
index a1eef159c0a..79f88ed6c2c 100644
--- a/source/nsswitch/winbindd_wins.c
+++ b/source/nsswitch/winbindd_wins.c
@@ -21,12 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "winbindd.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
/* Use our own create socket code so we don't recurse.... */
static int wins_lookup_open_socket_in(void)
@@ -87,31 +83,26 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd;
- struct ip_service *ret = NULL;
- struct in_addr *return_ip;
- int j, i, flags = 0;
+ struct in_addr *ret = NULL;
+ struct in_addr p;
+ int j, flags;
*count = 0;
- /* always try with wins first */
- if (resolve_wins(name,0x20,&ret,count)) {
- if ( count == 0 )
- return NULL;
- if ( (return_ip = (struct in_addr *)malloc((*count)*sizeof(struct in_addr))) == NULL ) {
- free( ret );
- return NULL;
- }
+ fd = wins_lookup_open_socket_in();
+ if (fd == -1)
+ return NULL;
- /* copy the IP addresses */
- for ( i=0; i<(*count); i++ )
- return_ip[i] = ret[i].ip;
-
- return return_ip;
+ p = wins_srv_ip();
+ if( !is_zero_ip(p) ) {
+ ret = name_query(fd,name,0x20,False,True, p, count, &flags);
+ goto out;
}
- fd = wins_lookup_open_socket_in();
- if (fd == -1) {
- return NULL;
+ if (lp_wins_support()) {
+ /* we are our own WINS server */
+ ret = name_query(fd,name,0x20,False,True, *interpret_addr2("127.0.0.1"), count, &flags);
+ goto out;
}
/* uggh, we have to broadcast to each interface in turn */
@@ -119,12 +110,14 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
j >= 0;
j--) {
struct in_addr *bcast = iface_n_bcast(j);
- return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (return_ip) break;
+ ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags);
+ if (ret) break;
}
+ out:
+
close(fd);
- return return_ip;
+ return ret;
}
/* Get hostname from IP */
@@ -135,10 +128,7 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
int i, count, maxlen, size;
struct node_status *status;
- /* Ensure null termination */
- state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
-
- DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
state->request.data.winsreq));
*response = '\0';
@@ -150,8 +140,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
- fstrcat(response,state->request.data.winsreq);
- fstrcat(response,"\t");
+ safe_strcat(response,state->request.data.winsreq,maxlen);
+ safe_strcat(response,"\t",maxlen);
for (i = 0; i < count; i++) {
/* ignore group names */
if (status[i].flags & 0x80) continue;
@@ -161,8 +151,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
- fstrcat(response, status[i].name);
- fstrcat(response, " ");
+ safe_strcat(response, status[i].name, maxlen);
+ safe_strcat(response, " ", maxlen);
}
}
/* make last character a newline */
@@ -182,10 +172,7 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
fstring response;
char * addr;
- /* Ensure null termination */
- state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
-
- DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
state->request.data.winsreq));
*response = '\0';
@@ -201,21 +188,18 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
}
if (i != 0) {
/* Clear out the newline character */
- /* But only if there is something in there,
- otherwise we clobber something in the stack */
- if (strlen(response))
- response[strlen(response)-1] = ' ';
+ response[strlen(response)-1] = ' ';
}
- fstrcat(response,addr);
- fstrcat(response,"\t");
+ safe_strcat(response,addr,maxlen);
+ safe_strcat(response,"\t",maxlen);
}
size = strlen(state->request.data.winsreq) + strlen(response);
if (size > maxlen) {
SAFE_FREE(ip_list);
return WINBINDD_ERROR;
}
- fstrcat(response,state->request.data.winsreq);
- fstrcat(response,"\n");
+ safe_strcat(response,state->request.data.winsreq,maxlen);
+ safe_strcat(response,"\n",maxlen);
SAFE_FREE(ip_list);
} else
return WINBINDD_ERROR;
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index 9580dad677c..d74b006bb92 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -80,77 +80,85 @@ static void nss_wins_init(void)
DEBUGLEVEL = 0;
AllowDebugChange = False;
+ /* needed for lp_xx() functions */
+ charset_initialise();
+
TimeInit();
setup_logging("nss_wins",False);
- lp_load(dyn_CONFIGFILE,True,False,False);
+ lp_load(CONFIGFILE,True,False,False);
load_interfaces();
+ codepage_initialise(lp_client_code_page());
}
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
+static struct node_status *lookup_byaddr_backend(char *addr, int *count)
{
- int fd = -1;
- struct ip_service *address = NULL;
- struct in_addr *ret;
- int j, flags = 0;
+ int fd;
+ struct in_addr ip;
+ struct nmb_name nname;
+ struct node_status *status;
if (!initialised) {
nss_wins_init();
}
- *count = 0;
-
- /* always try with wins first */
- if (resolve_wins(name,0x00,&address,count)) {
- if ( (ret = (struct in_addr *)malloc(sizeof(struct in_addr))) == NULL ) {
- free( address );
- return NULL;
- }
- *ret = address[0].ip;
- free( address );
- return ret;
- }
-
fd = wins_lookup_open_socket_in();
- if (fd == -1) {
+ if (fd == -1)
return NULL;
- }
- /* uggh, we have to broadcast to each interface in turn */
- for (j=iface_count() - 1;j >= 0;j--) {
- struct in_addr *bcast = iface_n_bcast(j);
- ret = name_query(fd,name,0x00,True,True,*bcast,count, &flags, NULL);
- if (ret) break;
- }
+ make_nmb_name(&nname, "*", 0);
+ ip = *interpret_addr2(addr);
+ status = node_status_query(fd,&nname,ip, count);
close(fd);
- return ret;
+ return status;
}
-#ifdef HAVE_NS_API_H
-
-static struct node_status *lookup_byaddr_backend(char *addr, int *count)
+static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd;
- struct in_addr ip;
- struct nmb_name nname;
- struct node_status *status;
+ struct in_addr *ret = NULL;
+ struct in_addr p;
+ int j, flags;
if (!initialised) {
nss_wins_init();
}
+ *count = 0;
+
fd = wins_lookup_open_socket_in();
if (fd == -1)
return NULL;
- make_nmb_name(&nname, "*", 0);
- ip = *interpret_addr2(addr);
- status = node_status_query(fd,&nname,ip, count);
+ p = wins_srv_ip();
+ if( !is_zero_ip(p) ) {
+ ret = name_query(fd,name,0x20,False,True, p, count, &flags);
+ goto out;
+ }
+
+ if (lp_wins_support()) {
+ /* we are our own WINS server */
+ ret = name_query(fd,name,0x20,False,True, *interpret_addr2("127.0.0.1"), count, &flags);
+ goto out;
+ }
+
+ /* uggh, we have to broadcast to each interface in turn */
+ for (j=iface_count() - 1;
+ j >= 0;
+ j--) {
+ struct in_addr *bcast = iface_n_bcast(j);
+ ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags);
+ if (ret) break;
+ }
+
+ out:
close(fd);
- return status;
+ return ret;
}
+
+#ifdef HAVE_NS_API_H
/* IRIX version */
int init(void)
@@ -194,7 +202,7 @@ int lookup(nsd_file_t *rq)
* response needs to be a string of the following format
* ip_address[ ip_address]*\tname[ alias]*
*/
- if (StrCaseCmp(map,"hosts.byaddr") == 0) {
+ if (strcasecmp(map,"hosts.byaddr") == 0) {
if ( status = lookup_byaddr_backend(key, &count)) {
size = strlen(key) + 1;
if (size > len) {
@@ -222,7 +230,7 @@ int lookup(nsd_file_t *rq)
response[strlen(response)-1] = '\n';
free(status);
}
- } else if (StrCaseCmp(map,"hosts.byname") == 0) {
+ } else if (strcasecmp(map,"hosts.byname") == 0) {
if (ip_list = lookup_byname_backend(key, &count)) {
for (i = count; i ; i--) {
addr = inet_ntoa(ip_list[i-1]);
@@ -260,120 +268,72 @@ int lookup(nsd_file_t *rq)
}
#else
-
-/* Allocate some space from the nss static buffer. The buffer and buflen
- are the pointers passed in by the C library to the _nss_*_*
- functions. */
-
-static char *get_static(char **buffer, size_t *buflen, int len)
-{
- char *result;
-
- /* Error check. We return false if things aren't set up right, or
- there isn't enough buffer space left. */
-
- if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
- return NULL;
- }
-
- /* Return an index into the static buffer */
-
- result = *buffer;
- *buffer += len;
- *buflen -= len;
-
- return result;
-}
-
/****************************************************************************
gethostbyname() - we ignore any domain portion of the name and only
handle names that are at most 15 characters long
**************************************************************************/
NSS_STATUS
-_nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop)
+_nss_wins_gethostbyname_r(const char *name, struct hostent *he,
+ char *buffer, size_t buflen, int *errnop,
+ int *h_errnop)
{
+ char **host_addresses;
struct in_addr *ip_list;
int i, count;
- fstring name;
- size_t namelen;
+ size_t namelen = strlen(name) + 1;
memset(he, '\0', sizeof(*he));
- fstrcpy(name, hostname);
-
- /* Do lookup */
ip_list = lookup_byname_backend(name, &count);
-
- if (!ip_list)
+ if (!ip_list) {
return NSS_STATUS_NOTFOUND;
-
- /* Copy h_name */
-
- namelen = strlen(name) + 1;
-
- if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL)
- return NSS_STATUS_TRYAGAIN;
-
- memcpy(he->h_name, name, namelen);
-
- /* Copy h_addr_list, align to pointer boundary first */
-
- if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if (get_static(&buffer, &buflen, i) == NULL)
- return NSS_STATUS_TRYAGAIN;
-
- if ((he->h_addr_list = (char **)get_static(
- &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL)
- return NSS_STATUS_TRYAGAIN;
-
- for (i = 0; i < count; i++) {
- if ((he->h_addr_list[i] = get_static(&buffer, &buflen,
- INADDRSZ)) == NULL)
- return NSS_STATUS_TRYAGAIN;
- memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ);
}
- he->h_addr_list[count] = NULL;
-
- if (ip_list)
- free(ip_list);
+ if (buflen < namelen + (2*count+1)*INADDRSZ) {
+ /* no ENOMEM error type?! */
+ return NSS_STATUS_NOTFOUND;
+ }
- /* Set h_addr_type and h_length */
+ host_addresses = (char **)buffer;
+ he->h_addr_list = host_addresses;
+ host_addresses[count] = NULL;
+ buffer += (count + 1) * INADDRSZ;
+ buflen += (count + 1) * INADDRSZ;
he->h_addrtype = AF_INET;
he->h_length = INADDRSZ;
- /* Set h_aliases */
-
- if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if (get_static(&buffer, &buflen, i) == NULL)
- return NSS_STATUS_TRYAGAIN;
+ for (i=0;i<count;i++) {
+ memcpy(buffer, &ip_list[i].s_addr, INADDRSZ);
+ *host_addresses = buffer;
+ buffer += INADDRSZ;
+ buflen -= INADDRSZ;
+ host_addresses++;
+ }
- if ((he->h_aliases = (char **)get_static(
- &buffer, &buflen, sizeof(char *))) == NULL)
- return NSS_STATUS_TRYAGAIN;
+ if (ip_list)
+ free(ip_list);
- he->h_aliases[0] = NULL;
+ memcpy(buffer, name, namelen);
+ he->h_name = buffer;
return NSS_STATUS_SUCCESS;
}
-
NSS_STATUS
_nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop)
+ char *buffer, size_t buflen, int *errnop,
+ int *h_errnop)
{
if(af!=AF_INET) {
*h_errnop = NO_DATA;
+ *errnop = EAFNOSUPPORT;
return NSS_STATUS_UNAVAIL;
}
- return _nss_wins_gethostbyname_r(
- name, he, buffer, buflen, h_errnop);
+ return _nss_wins_gethostbyname_r(name,he,buffer,buflen,errnop,h_errnop);
}
+
+
+
#endif
diff --git a/source/pam_smbpass/README b/source/pam_smbpass/README
index 6cdb76f9c3f..cf208a99140 100644
--- a/source/pam_smbpass/README
+++ b/source/pam_smbpass/README
@@ -11,7 +11,13 @@ For more information on PAM, see http://ftp.kernel.org/pub/linux/libs/pam/
This module authenticates a local smbpasswd user database. If you require
support for authenticating against a remote SMB server, or if you're
concerned about the presence of suid root binaries on your system, it is
-recommended that you use pam_winbind instead.
+recommended that you use one of the other two following modules
+
+ pam_smb - http://www.csn.ul.ie/~airlied/pam_smb/
+ authenticates against any remote SMB server
+
+ pam_ntdom - ftp://ftp.samba.org/pub/samba/pam_ntdom/
+ authenticates against an NT or Samba domain controller
Options recognized by this module are as follows:
diff --git a/source/pam_smbpass/general.h b/source/pam_smbpass/general.h
index 4f13d601313..4de9d369631 100644
--- a/source/pam_smbpass/general.h
+++ b/source/pam_smbpass/general.h
@@ -11,12 +11,15 @@
#include <stdio.h>
#include <stdlib.h>
-#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
/*
* here is the string to inform the user that the new passwords they
* typed were not the same.
@@ -121,10 +124,3 @@ struct _pam_failed_auth {
char *agent; /* attempt from user with name */
int count; /* number of failures so far */
};
-
-/*
- * General use functions go here
- */
-
-/* from support.c */
-int make_remark(pam_handle_t *, unsigned int, int, const char *);
diff --git a/source/pam_smbpass/pam_smb_acct.c b/source/pam_smbpass/pam_smb_acct.c
index 2ea7eea7d87..22f8e756581 100644
--- a/source/pam_smbpass/pam_smb_acct.c
+++ b/source/pam_smbpass/pam_smb_acct.c
@@ -33,7 +33,6 @@
#include "support.h"
-
/*
* pam_sm_acct_mgmt() verifies whether or not the account is disabled.
*
@@ -47,11 +46,13 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
const char *name;
SAM_ACCOUNT *sampass = NULL;
- void (*oldsig_handler)(int);
+
extern BOOL in_client;
/* Samba initialization. */
setup_logging( "pam_smbpass", False );
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl( flags, argc, argv );
@@ -69,12 +70,8 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
}
- /* Getting into places that might use LDAP -- protect the app
- from a SIGPIPE it's not expecting */
- oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_AUTHINFO_UNAVAIL;
}
@@ -82,10 +79,8 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
pdb_init_sam(&sampass);
pdb_getsampwnam(sampass, name );
- if (!sampass) {
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ if (!sampass)
return PAM_USER_UNKNOWN;
- }
if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
if (on( SMB_DEBUG, ctrl )) {
@@ -96,13 +91,11 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
, "Your account has been disabled; "
"please see your system administrator." );
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_ACCT_EXPIRED;
}
/* TODO: support for expired passwords. */
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_SUCCESS;
}
diff --git a/source/pam_smbpass/pam_smb_auth.c b/source/pam_smbpass/pam_smb_auth.c
index d0dca6fa920..6a3e6e56598 100644
--- a/source/pam_smbpass/pam_smb_auth.c
+++ b/source/pam_smbpass/pam_smb_auth.c
@@ -36,8 +36,6 @@
#define AUTH_RETURN \
do { \
- /* Restore application signal handler */ \
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); \
if(ret_data) { \
*ret_data = retval; \
pam_set_data( pamh, "smb_setcred_return" \
@@ -49,6 +47,8 @@ do { \
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
const char *name, SAM_ACCOUNT *sampass, BOOL exist);
+int make_remark(pam_handle_t *, unsigned int, int, const char *);
+
/*
* pam_sm_authenticate() authenticates users against the samba password file.
@@ -67,7 +67,6 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
SAM_ACCOUNT *sampass = NULL;
extern BOOL in_client;
const char *name;
- void (*oldsig_handler)(int);
BOOL found;
/* Points to memory managed by the PAM library. Do not free. */
@@ -76,6 +75,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
/* Samba initialization. */
setup_logging("pam_smbpass",False);
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl(flags, argc, argv);
@@ -96,10 +97,6 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", name );
}
- /* Getting into places that might use LDAP -- protect the app
- from a SIGPIPE it's not expecting */
- oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
-
if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
retval = PAM_AUTHINFO_UNAVAIL;
@@ -112,14 +109,14 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (on( SMB_MIGRATE, ctrl )) {
retval = _smb_add_user(pamh, ctrl, name, sampass, found);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
AUTH_RETURN;
}
if (!found) {
_log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
retval = PAM_USER_UNKNOWN;
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
sampass = NULL;
AUTH_RETURN;
}
@@ -127,7 +124,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
/* if this user does not have a password... */
if (_smb_blankpasswd( ctrl, sampass )) {
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
retval = PAM_SUCCESS;
AUTH_RETURN;
}
@@ -138,14 +135,14 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS ) {
_log_err(LOG_CRIT, "auth: no password provided for [%s]"
, name);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
AUTH_RETURN;
}
/* verify the password of this user */
retval = _smb_verify_password( pamh, sampass, p, ctrl );
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
p = NULL;
AUTH_RETURN;
}
@@ -179,7 +176,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
{
pstring err_str;
pstring msg_str;
- const char *pass = NULL;
+ char *pass = NULL;
int retval;
err_str[0] = '\0';
@@ -198,7 +195,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
/* Add the user to the db if they aren't already there. */
if (!exist) {
- retval = local_password_change( name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD,
+ retval = local_password_change( name, LOCAL_ADD_USER,
pass, err_str,
sizeof(err_str),
msg_str, sizeof(msg_str) );
@@ -217,10 +214,10 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
return PAM_IGNORE;
}
else {
- /* mimick 'update encrypted' as long as the 'no pw req' flag is not set */
- if ( pdb_get_acct_ctrl(sampass) & ~ACB_PWNOTREQ )
+ /* Change the user's password IFF it's null. */
+ if ((pdb_get_lanman_passwd(sampass) == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
{
- retval = local_password_change( name, LOCAL_SET_PASSWORD, pass, err_str, sizeof(err_str),
+ retval = local_password_change( name, 0, pass, err_str, sizeof(err_str),
msg_str, sizeof(msg_str) );
if (!retval && *err_str)
{
diff --git a/source/pam_smbpass/pam_smb_passwd.c b/source/pam_smbpass/pam_smb_passwd.c
index bef587a916c..4cdf5c3e9b0 100644
--- a/source/pam_smbpass/pam_smb_passwd.c
+++ b/source/pam_smbpass/pam_smb_passwd.c
@@ -1,22 +1,18 @@
-/*
- Unix SMB/CIFS implementation.
- Use PAM to update user passwords in the local SAM
- Copyright (C) Steve Langasek 1998-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
+/* Unix NT password database implementation, version 0.7.5.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
*/
/* indicate the following groups are defined */
@@ -24,13 +20,12 @@
#include "includes.h"
-/* This is only used in the Sun implementation. FIXME: we really
- want a define here that distinguishes between the Solaris PAM
- and others (including FreeBSD). */
-
#ifndef LINUX
+
+/* This is only used in the Sun implementation. */
#include <security/pam_appl.h>
-#endif
+
+#endif /* LINUX */
#include <security/pam_modules.h>
@@ -38,36 +33,36 @@
#include "support.h"
-int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new )
+int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, char *pass_new )
{
- int retval;
- pstring err_str;
- pstring msg_str;
-
- err_str[0] = '\0';
- msg_str[0] = '\0';
-
- retval = local_password_change( user, LOCAL_SET_PASSWORD, pass_new,
- err_str, sizeof(err_str),
- msg_str, sizeof(msg_str) );
-
- if (!retval) {
- if (*err_str) {
- err_str[PSTRING_LEN-1] = '\0';
- make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
- }
-
- /* FIXME: what value is appropriate here? */
- retval = PAM_AUTHTOK_ERR;
- } else {
- if (*msg_str) {
- msg_str[PSTRING_LEN-1] = '\0';
- make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
- }
- retval = PAM_SUCCESS;
- }
+ int retval;
+ pstring err_str;
+ pstring msg_str;
+
+ err_str[0] = '\0';
+ msg_str[0] = '\0';
+
+ retval = local_password_change( user, 0, pass_new, err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str) );
+
+ if (!retval) {
+ if (*err_str) {
+ err_str[PSTRING_LEN-1] = '\0';
+ make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
+ }
+
+ /* FIXME: what value is appropriate here? */
+ retval = PAM_AUTHTOK_ERR;
+ } else {
+ if (*msg_str) {
+ msg_str[PSTRING_LEN-1] = '\0';
+ make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
+ }
+ retval = PAM_SUCCESS;
+ }
+
+ return retval;
- return retval;
}
@@ -97,15 +92,13 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
extern BOOL in_client;
SAM_ACCOUNT *sampass = NULL;
- void (*oldsig_handler)(int);
const char *user;
- char *pass_old;
- char *pass_new;
-
- NTSTATUS nt_status;
+ char *pass_old, *pass_new;
/* Samba initialization. */
setup_logging( "pam_smbpass", False );
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl(flags, argc, argv);
@@ -126,25 +119,17 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", user );
}
- /* Getting into places that might use LDAP -- protect the app
- from a SIGPIPE it's not expecting */
- oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
-
if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_AUTHINFO_UNAVAIL;
}
/* obtain user record */
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
- return nt_status_to_pam(nt_status);
- }
+ pdb_init_sam(&sampass);
+ pdb_getsampwnam(sampass,user);
- if (!pdb_getsampwnam(sampass,user)) {
+ if (sampass == NULL) {
_log_err( LOG_ALERT, "Failed to find entry for user %s.", user );
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
return PAM_USER_UNKNOWN;
}
@@ -158,8 +143,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (_smb_blankpasswd( ctrl, sampass )) {
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return PAM_SUCCESS;
}
@@ -172,8 +156,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
Announce = (char *) malloc(sizeof(greeting)+strlen(user));
if (Announce == NULL) {
_log_err(LOG_CRIT, "password: out of memory");
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return PAM_BUF_ERR;
}
strncpy( Announce, greeting, sizeof(greeting) );
@@ -188,8 +171,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
_log_err( LOG_NOTICE
, "password - (old) token not obtained" );
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
}
@@ -203,12 +185,20 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
pass_old = NULL;
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
} else if (flags & PAM_UPDATE_AUTHTOK) {
+#if 0
+ /* We used to return when this flag was set, but that breaks
+ password synchronization when /other/ tokens are expired. For
+ now, we change the password whenever we're asked. SRL */
+ if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) {
+ pdb_free_sam(sampass);
+ return PAM_SUCCESS;
+ }
+#endif
/*
* obtain the proposed password
*/
@@ -233,8 +223,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
_log_err( LOG_NOTICE, "password: user not authenticated" );
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
}
@@ -261,8 +250,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
, "password: new password not obtained" );
}
pass_old = NULL; /* tidy up */
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
}
@@ -281,8 +269,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
_log_err(LOG_NOTICE, "new password not acceptable");
pass_new = pass_old = NULL; /* tidy up */
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
}
@@ -295,25 +282,18 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = smb_update_db(pamh, ctrl, user, pass_new);
if (retval == PAM_SUCCESS) {
- uid_t uid;
-
/* password updated */
- if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &uid))) {
- _log_err( LOG_NOTICE, "Unable to get uid for user %s",
- pdb_get_username(sampass));
- _log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)",
- user, uidtoname(getuid()), getuid());
- } else {
- _log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)",
- user, uid, uidtoname(getuid()), getuid());
- }
- } else {
- _log_err( LOG_ERR, "password change failed for user %s", user);
- }
+ _log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)"
+ , user, pdb_get_uid(sampass), uidtoname( getuid() )
+ , getuid() );
+ } else {
+ _log_err( LOG_ERR, "password change failed for user %s"
+ , user );
+ }
pass_old = pass_new = NULL;
if (sampass) {
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
sampass = NULL;
}
@@ -325,12 +305,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
if (sampass) {
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
sampass = NULL;
}
- pdb_free_sam(&sampass);
- CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+ pdb_free_sam(sampass);
return retval;
}
diff --git a/source/pam_smbpass/support.c b/source/pam_smbpass/support.c
index 8a0432c8550..332b54f23b7 100644
--- a/source/pam_smbpass/support.c
+++ b/source/pam_smbpass/support.c
@@ -1,135 +1,136 @@
- /* Unix NT password database implementation, version 0.6.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
+/* Unix NT password database implementation, version 0.6.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
- #include "includes.h"
- #include "general.h"
+#include "includes.h"
+#include "general.h"
- #include "support.h"
+#include "support.h"
- #define _pam_overwrite(x) \
- do { \
- register char *__xx__; \
- if ((__xx__=(x))) \
- while (*__xx__) \
- *__xx__++ = '\0'; \
- } while (0)
+#define _pam_overwrite(x) \
+do { \
+ register char *__xx__; \
+ if ((__xx__=(x))) \
+ while (*__xx__) \
+ *__xx__++ = '\0'; \
+} while (0)
- /*
- * Don't just free it, forget it too.
- */
+/*
+ * Don't just free it, forget it too.
+ */
- #define _pam_drop(X) \
- do { \
- if (X) { \
- free(X); \
- X=NULL; \
- } \
- } while (0)
-
- #define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
- do { \
- int reply_i; \
- \
- for (reply_i=0; reply_i<replies; ++reply_i) { \
- if (reply[reply_i].resp) { \
- _pam_overwrite(reply[reply_i].resp); \
- free(reply[reply_i].resp); \
- } \
- } \
- if (reply) \
- free(reply); \
- } while (0)
-
-
- int converse(pam_handle_t *, int, int, struct pam_message **,
- struct pam_response **);
- int make_remark(pam_handle_t *, unsigned int, int, const char *);
- void _cleanup(pam_handle_t *, void *, int);
- char *_pam_delete(register char *);
-
- /* default configuration file location */
-
- char *servicesf = dyn_CONFIGFILE;
-
- /* syslogging function for errors and other information */
-
- void _log_err( int err, const char *format, ... )
- {
- va_list args;
-
- va_start( args, format );
- openlog( "PAM_smbpass", LOG_CONS | LOG_PID, LOG_AUTH );
- vsyslog( err, format, args );
- va_end( args );
- closelog();
- }
+#define _pam_drop(X) \
+do { \
+ if (X) { \
+ free(X); \
+ X=NULL; \
+ } \
+} while (0)
+
+#define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
+do { \
+ int reply_i; \
+ \
+ for (reply_i=0; reply_i<replies; ++reply_i) { \
+ if (reply[reply_i].resp) { \
+ _pam_overwrite(reply[reply_i].resp); \
+ free(reply[reply_i].resp); \
+ } \
+ } \
+ if (reply) \
+ free(reply); \
+} while (0)
+
+
+int converse(pam_handle_t *, int, int, struct pam_message **,
+ struct pam_response **);
+int make_remark(pam_handle_t *, unsigned int, int, const char *);
+void _cleanup(pam_handle_t *, void *, int);
+char *_pam_delete(register char *);
+
+/* default configuration file location */
+
+pstring servicesf = CONFIGFILE;
+
+/* syslogging function for errors and other information */
+
+void _log_err( int err, const char *format, ... )
+{
+ va_list args;
- /* this is a front-end for module-application conversations */
+ va_start( args, format );
+ openlog( "PAM_smbpass", LOG_CONS | LOG_PID, LOG_AUTH );
+ vsyslog( err, format, args );
+ va_end( args );
+ closelog();
+}
- int converse( pam_handle_t * pamh, int ctrl, int nargs
- , struct pam_message **message
- , struct pam_response **response )
- {
- int retval;
- struct pam_conv *conv;
+/* this is a front-end for module-application conversations */
+
+int converse( pam_handle_t * pamh, int ctrl, int nargs
+ , struct pam_message **message
+ , struct pam_response **response )
+{
+ int retval;
+ struct pam_conv *conv;
- retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
- if (retval == PAM_SUCCESS) {
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS) {
- retval = conv->conv(nargs, (const struct pam_message **) message
- ,response, conv->appdata_ptr);
+ retval = conv->conv(nargs, (const struct pam_message **) message
+ ,response, conv->appdata_ptr);
- if (retval != PAM_SUCCESS && on(SMB_DEBUG, ctrl)) {
- _log_err(LOG_DEBUG, "conversation failure [%s]"
- ,pam_strerror(pamh, retval));
- }
- } else {
- _log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
+ if (retval != PAM_SUCCESS && on(SMB_DEBUG, ctrl)) {
+ _log_err(LOG_DEBUG, "conversation failure [%s]"
,pam_strerror(pamh, retval));
}
-
- return retval; /* propagate error status */
+ } else {
+ _log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
+ ,pam_strerror(pamh, retval));
}
- int make_remark( pam_handle_t * pamh, unsigned int ctrl
- , int type, const char *text )
- {
- if (off(SMB__QUIET, ctrl)) {
- struct pam_message *pmsg[1], msg[1];
- struct pam_response *resp;
+ return retval; /* propagate error status */
+}
- pmsg[0] = &msg[0];
- msg[0].msg = text;
- msg[0].msg_style = type;
- resp = NULL;
+int make_remark( pam_handle_t * pamh, unsigned int ctrl
+ , int type, const char *text )
+{
+ if (off(SMB__QUIET, ctrl)) {
+ struct pam_message *pmsg[1], msg[1];
+ struct pam_response *resp;
- return converse(pamh, ctrl, 1, pmsg, &resp);
- }
- return PAM_SUCCESS;
+ pmsg[0] = &msg[0];
+ msg[0].msg = text;
+ msg[0].msg_style = type;
+ resp = NULL;
+
+ return converse(pamh, ctrl, 1, pmsg, &resp);
}
+ return PAM_SUCCESS;
+}
- /* set the control flags for the SMB module. */
+/* set the control flags for the SMB module. */
int set_ctrl( int flags, int argc, const char **argv )
{
int i = 0;
- const char *service_file = dyn_CONFIGFILE;
+ static pstring servicesf = CONFIGFILE;
+ const char *service_file = servicesf;
unsigned int ctrl;
ctrl = SMB_DEFAULTS; /* the default selection of options */
@@ -308,6 +309,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err )
int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
const char *p, unsigned int ctrl )
{
+ uchar hash_pass[16];
uchar lm_pw[16];
uchar nt_pw[16];
int retval = PAM_AUTH_ERR;
@@ -338,8 +340,11 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
const char *service;
pam_get_item( pamh, PAM_SERVICE, (const void **)&service );
- _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s",
- uidtoname(getuid()), service ? service : "**unknown**", name);
+ _log_err( LOG_NOTICE
+ , "failed auth request by %s for service %s as %s(%d)"
+ , uidtoname( getuid() )
+ , service ? service : "**unknown**", name
+ , pdb_get_uid(sampass) );
return PAM_AUTH_ERR;
}
}
@@ -351,6 +356,25 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
strncpy( data_name, FAIL_PREFIX, sizeof(FAIL_PREFIX) );
strncpy( data_name + sizeof(FAIL_PREFIX) - 1, name, strlen( name ) + 1 );
+ /* First we check whether we've been given the password in already
+ encrypted form. */
+ if (strlen( p ) == 16 || (strlen( p ) == 32
+ && pdb_gethexpwd( p, (char *) hash_pass ))) {
+
+ if (!memcmp( hash_pass, pdb_get_lanman_passwd(sampass), 16 )
+ || (pdb_get_nt_passwd(sampass)
+ && !memcmp( hash_pass, pdb_get_nt_passwd(sampass), 16 )))
+ {
+ retval = PAM_SUCCESS;
+ if (data_name) { /* reset failures */
+ pam_set_data( pamh, data_name, NULL, _cleanup_failures );
+ }
+ _pam_delete( data_name );
+ memset( hash_pass, '\0', 16 );
+ return retval;
+ }
+ }
+
/*
* The password we were given wasn't an encrypted password, or it
* didn't match the one we have. We encrypt the password now and try
@@ -393,34 +417,32 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
retval = PAM_MAXTRIES;
}
} else {
- _log_err(LOG_NOTICE,
- "failed auth request by %s for service %s as %s",
- uidtoname(getuid()),
- service ? service : "**unknown**", name);
+ _log_err( LOG_NOTICE
+ , "failed auth request by %s for service %s as %s(%d)"
+ , uidtoname( getuid() )
+ , service ? service : "**unknown**", name
+ , pdb_get_uid(sampass) );
new->count = 1;
}
- if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &(new->id)))) {
- _log_err(LOG_NOTICE,
- "failed auth request by %s for service %s as %s",
- uidtoname(getuid()),
- service ? service : "**unknown**", name);
- }
new->user = smbpXstrDup( name );
+ new->id = pdb_get_uid(sampass);
new->agent = smbpXstrDup( uidtoname( getuid() ) );
pam_set_data( pamh, data_name, new, _cleanup_failures );
} else {
_log_err( LOG_CRIT, "no memory for failure recorder" );
- _log_err(LOG_NOTICE,
- "failed auth request by %s for service %s as %s(%d)",
- uidtoname(getuid()),
- service ? service : "**unknown**", name);
+ _log_err( LOG_NOTICE
+ , "failed auth request by %s for service %s as %s(%d)"
+ , uidtoname( getuid() )
+ , service ? service : "**unknown**", name
+ , pdb_get_uid(sampass) );
}
} else {
- _log_err(LOG_NOTICE,
- "failed auth request by %s for service %s as %s(%d)",
- uidtoname(getuid()),
- service ? service : "**unknown**", name);
+ _log_err( LOG_NOTICE
+ , "failed auth request by %s for service %s as %s(%d)"
+ , uidtoname( getuid() )
+ , service ? service : "**unknown**", name
+ , pdb_get_uid(sampass) );
retval = PAM_AUTH_ERR;
}
}
@@ -464,8 +486,8 @@ int _smb_blankpasswd( unsigned int ctrl, SAM_ACCOUNT *sampass )
*/
int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
- const char *comment, const char *prompt1,
- const char *prompt2, const char *data_name, char **pass )
+ char *comment, char *prompt1,
+ char *prompt2, char *data_name, char **pass )
{
int authtok_flag;
int retval;
diff --git a/source/pam_smbpass/support.h b/source/pam_smbpass/support.h
index a13a2d0aeb9..d2fe26bd048 100644
--- a/source/pam_smbpass/support.h
+++ b/source/pam_smbpass/support.h
@@ -43,8 +43,10 @@ extern int _smb_blankpasswd(unsigned int, SAM_ACCOUNT *);
/* obtain a password from the user */
-extern int _smb_read_password( pam_handle_t *, unsigned int, const char*,
- const char *, const char *, const char *, char **);
+extern int _smb_read_password( pam_handle_t *, unsigned int, char*,
+ char *, char *, char *, char **);
extern int _pam_smb_approve_pass(pam_handle_t *, unsigned int, const char *,
const char *);
+
+extern pstring servicesf;
diff --git a/source/param/config_ldap.c b/source/param/config_ldap.c
deleted file mode 100644
index fe4693fb583..00000000000
--- a/source/param/config_ldap.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- ModConfig LDAP backend
-
- Copyright (C) Simo Sorce 2003
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
- Copyright (C) Gerald Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_CONFIG
-*/
-
-#include <lber.h>
-#include <ldap.h>
-
-#include "smbldap.h"
-
-#define LDAP_OBJ_SAMBA_CONFIG "sambaConfig"
-#define LDAP_OBJ_SAMBA_SHARE "sambaShare"
-#define LDAP_OBJ_SAMBA_OPTION "sambaConfigOption"
-
-#define LDAP_ATTR_LIST_END 0
-#define LDAP_ATTR_BOOL 1
-#define LDAP_ATTR_INTEGER 2
-#define LDAP_ATTR_STRING 3
-#define LDAP_ATTR_LIST 4
-#define LDAP_ATTR_NAME 5
-
-
-struct ldap_config_state {
- struct smbldap_state *smbldap_state;
- TALLOC_CTX *mem_ctx;
-};
-
-ATTRIB_MAP_ENTRY option_attr_list[] = {
- { LDAP_ATTR_NAME, "sambaOptionName" },
- { LDAP_ATTR_LIST, "sambaListOption" },
- { LDAP_ATTR_STRING, "sambaStringOption" },
- { LDAP_ATTR_INTEGER, "sambaIntegerOption" },
- { LDAP_ATTR_BOOL, "sambaBoolOption" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-static struct ldap_config_state ldap_state;
-static char *config_base_dn;
-
-static NTSTATUS ldap_config_close(void);
-
-/*
-TODO:
- search each section
- start with global, then with others
- for each section parse all options
-*/
-
-static NTSTATUS parse_section(
- const char *dn,
- BOOL (*pfunc)(const char *, const char *))
-{
- TALLOC_CTX *mem_ctx;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring filter;
- pstring option_name;
- pstring option_value;
- char **attr_list = NULL;
- int rc;
- int count;
-
- mem_ctx = talloc_init("parse_section");
-
- /* search for the options */
- pstr_sprintf(filter, "objectClass=%s",
- LDAP_OBJ_SAMBA_OPTION);
-
- DEBUG(0, ("Searching for:[%s]\n", filter));
-
- attr_list = get_attr_list(option_attr_list);
- rc = smbldap_search(ldap_state.smbldap_state,
- dn, LDAP_SCOPE_ONELEVEL,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("parse_section: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
- goto done;
- }
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
- while (entry) {
- int o;
-
- if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "sambaOptionName", option_name)) {
- goto done;
- }
-
- option_value[0] = '\0';
- for (o = 1; option_attr_list[o].name != NULL; o++) {
- if (smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, option_attr_list[o].name, option_value)) {
- break;
- }
- }
- if (option_value[0] != '\0') {
- if (!pfunc(option_name, option_value)) {
- goto done;
- }
- } else {
- DEBUG(0,("parse_section: Missing value for option: %s\n", option_name));
- goto done;
- }
-
- entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry);
- }
-
- ret = NT_STATUS_OK;
-
-done:
- talloc_destroy(mem_ctx);
- free_attr_list(attr_list);
- if (result) ldap_msgfree(result);
-
- return ret;
-}
-
-/*****************************************************************************
- load configuration from ldap
-*****************************************************************************/
-
-static NTSTATUS ldap_config_load(
- BOOL (*sfunc)(const char *),
- BOOL (*pfunc)(const char *, const char *))
-{
- TALLOC_CTX *mem_ctx;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring filter;
- pstring attr_text;
- char *config_dn = NULL;
- char *temp;
- int rc;
- int count;
- const char *config_attr_list[] = {"description", NULL};
- const char *share_attr_list[] = {"sambaShareName", "description", NULL};
- char **share_dn;
- char **share_name;
-
- mem_ctx = talloc_init("ldap_config_load");
-
- /* search for the base config dn */
- pstr_sprintf(filter, "objectClass=%s",
- LDAP_OBJ_SAMBA_CONFIG);
-
- DEBUG(0, ("Searching for:[%s]\n", filter));
-
- rc = smbldap_search(ldap_state.smbldap_state,
- config_base_dn, LDAP_SCOPE_SUBTREE,
- filter, config_attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
- goto done;
- }
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- if (count != 1) {
- DEBUG(0,("ldap_config_load: single %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
- goto done;
- }
-
- if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result))) {
- goto done;
- }
- config_dn = talloc_strdup(mem_ctx, temp);
- SAFE_FREE(temp);
- if (!config_dn) {
- goto done;
- }
-
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "description", attr_text)) {
- DEBUG(0, ("ldap_config_load: no description field in %s object\n", LDAP_OBJ_SAMBA_CONFIG));
- }
-
- if (result) ldap_msgfree(result);
-/* TODO: finish up the last section, see loadparm's lp_load()*/
-
- /* retrive the section list */
- pstr_sprintf(filter, "objectClass=%s",
- LDAP_OBJ_SAMBA_SHARE);
-
- DEBUG(0, ("Searching for:[%s]\n", filter));
-
- rc = smbldap_search(ldap_state.smbldap_state,
- config_dn, LDAP_SCOPE_SUBTREE,
- filter, share_attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
- goto done;
- }
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- DEBUG(0, ("config_ldap: Found %d shares\n", count));
- if (count) {
- int i;
-
- share_dn = talloc(mem_ctx, (count + 1) * sizeof(char *));
- share_name = talloc(mem_ctx, (count) * sizeof(char *));
- if (!share_dn || !share_name) {
- DEBUG(0,("config_ldap: Out of memory!\n"));
- goto done;
- }
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
- i = 0;
- while (entry) {
- if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, entry))) {
- goto done;
- }
- if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "sambaShareName", attr_text)) {
- goto done;
- }
- share_dn[i] = talloc_strdup(mem_ctx, temp);
- share_name[i] = talloc_strdup(mem_ctx, attr_text);
- if (!share_dn[i] || !share_name[i]) {
- DEBUG(0,("config_ldap: Out of memory!\n"));
- goto done;
- }
-
- DEBUG(0, ("config_ldap: Found share [%s] (%s)\n", attr_text, temp));
- SAFE_FREE(temp);
-
- entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry);
- i++;
- if (entry && (count == i)) {
- DEBUG(0, ("Error too many entryes in ldap result\n"));
- goto done;
- }
- }
- share_dn[i] = NULL;
- }
-
- /* parse global section*/
- if (!sfunc("global")) {
- goto done;
- }
- if (!NT_STATUS_IS_OK(parse_section(config_dn, pfunc))) {
- goto done;
- } else { /* parse shares */
- int i;
-
- for (i = 0; share_dn[i] != NULL; i++) {
- if (!sfunc(share_name[i])) {
- goto done;
- }
- if (!NT_STATUS_IS_OK(parse_section(share_dn[i], pfunc))) {
- goto done;
- }
- }
- }
-
-done:
- talloc_destroy(mem_ctx);
- if (result) ldap_msgfree(result);
-
- return ret;
-}
-
-/*****************************************************************************
- Initialise config_ldap module
-*****************************************************************************/
-
-static NTSTATUS ldap_config_init(char *params)
-{
- NTSTATUS nt_status;
- const char *location;
- const char *basedn;
-
- ldap_state.mem_ctx = talloc_init("config_ldap");
- if (!ldap_state.mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- /* we assume only location is passed through an inline parameter
- * other options go via parametrical options */
- if (params) {
- location = params;
- } else {
- location = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "url", "ldap://localhost");
- }
- DEBUG(0,("config_ldap: location=%s\n", location));
- basedn = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "basedn", NULL);
- if (basedn) config_base_dn = smb_xstrdup(basedn);
-
- if (!NT_STATUS_IS_OK(nt_status =
- smbldap_init(ldap_state.mem_ctx, location,
- &ldap_state.smbldap_state))) {
- talloc_destroy(ldap_state.mem_ctx);
- DEBUG(0,("config_ldap: smbldap_init failed!\n"));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-/*****************************************************************************
- End the LDAP session
-*****************************************************************************/
-
-static NTSTATUS ldap_config_close(void)
-{
-
- smbldap_free_struct(&(ldap_state).smbldap_state);
- talloc_destroy(ldap_state.mem_ctx);
-
- DEBUG(5,("The connection to the LDAP server was closed\n"));
- /* maybe free the results here --metze */
-
- return NT_STATUS_OK;
-}
-
-static struct config_functions functions = {
- ldap_config_init,
- ldap_config_load,
- ldap_config_close
-};
-
-NTSTATUS config_ldap_init(void)
-{
- return smb_register_config(SAMBA_CONFIG_INTERFACE_VERSION, "ldap", &functions);
-}
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 2f57e171d22..6e0d54ced48 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -1,14 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Parameter loading functions
Copyright (C) Karl Auer 1993-1998
Largely re-written by Andrew Tridgell, September 1994
-
- Copyright (C) Simo Sorce 2001
- Copyright (C) Alexander Bokovoy 2002
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -53,11 +49,30 @@
#include "includes.h"
+/* Set default coding system for KANJI if none specified in Makefile. */
+/*
+ * We treat KANJI specially due to historical precedent (it was the
+ * first non-english codepage added to Samba). With the new dynamic
+ * codepage support this is not needed anymore.
+ *
+ * The define 'KANJI' is being overloaded to mean 'use kanji codepage
+ * by default' and also 'this is the filename-to-disk conversion
+ * method to use'. This really should be removed and all control
+ * over this left in the smb.conf parameters 'client codepage'
+ * and 'coding system'.
+ */
+#ifndef KANJI
+#define KANJI "sbcs"
+#endif /* KANJI */
+
BOOL in_client = False; /* Not in the client by default */
BOOL bLoaded = False;
-extern userdom_struct current_user_info;
+extern int DEBUGLEVEL_CLASS[DBGC_LAST];
extern pstring user_socket_options;
+extern pstring global_myname;
+pstring global_scope = "";
+
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
@@ -82,24 +97,11 @@ extern int extra_time_offset;
static BOOL defaults_saved = False;
-typedef struct _param_opt_struct param_opt_struct;
-struct _param_opt_struct {
- param_opt_struct *prev, *next;
- char *key;
- char *value;
- char **list;
-};
-
/*
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct
{
- char *szConfigBackend;
- char *smb_ports;
- char *dos_charset;
- char *unix_charset;
- char *display_charset;
char *szPrintcapname;
char *szEnumPortsCommand;
char *szAddPrinterCommand;
@@ -110,8 +112,6 @@ typedef struct
char *szRootdir;
char *szDefaultService;
char *szDfree;
- char *szGetQuota;
- char *szSetQuota;
char *szMsgCommand;
char *szHostsEquiv;
char *szServerString;
@@ -120,73 +120,64 @@ typedef struct
char *szPasswdChat;
char *szLogFile;
char *szConfigFile;
+#ifdef WITH_TDB_SAM
+ char *szTDBPasswdFile;
+#else
char *szSMBPasswdFile;
- char *szPrivateDir;
- char **szPassdbBackend;
- char *szGumsBackend;
- char **szPreloadModules;
+#endif
char *szPasswordServer;
char *szSocketOptions;
- char *szRealm;
- char *szAfsUsernameMap;
+ char *szValidChars;
+ char *szWorkGroup;
+ char *szDomainAdminGroup;
+ char *szDomainGuestGroup;
+ char *szDomainHostsallow;
+ char *szDomainHostsdeny;
char *szUsernameMap;
+#ifdef USING_GROUPNAME_MAP
+ char *szGroupnameMap;
+#endif /* USING_GROUPNAME_MAP */
+ char *szCharacterSet;
+ char *szCodePageDir;
char *szLogonScript;
char *szLogonPath;
char *szLogonDrive;
char *szLogonHome;
- char **szWINSservers;
- char **szInterfaces;
+ char *szWINSserver;
+ char *szCodingSystem;
+ char *szInterfaces;
char *szRemoteAnnounce;
char *szRemoteBrowseSync;
char *szSocketAddress;
char *szNISHomeMapName;
char *szAnnounceVersion; /* This is initialised in init_globals */
- char *szWorkgroup;
- char *szNetbiosName;
- char **szNetbiosAliases;
- char *szNetbiosScope;
+ char *szNetbiosAliases;
char *szDomainOtherSIDs;
char *szNameResolveOrder;
char *szPanicAction;
char *szAddUserScript;
char *szDelUserScript;
- char *szAddGroupScript;
- char *szDelGroupScript;
- char *szAddUserToGroupScript;
- char *szDelUserFromGroupScript;
- char *szSetPrimaryGroupScript;
- char *szAddMachineScript;
- char *szShutdownScript;
- char *szAbortShutdownScript;
char *szWINSHook;
- char *szWINSPartners;
+#ifdef WITH_UTMP
char *szUtmpDir;
char *szWtmpDir;
BOOL bUtmp;
- char *szIdmapUID;
- char *szIdmapGID;
- BOOL bEnableRidAlgorithm;
- int AlgorithmicRidBase;
- char *szTemplatePrimaryGroup;
+#endif
+ char *szSourceEnv;
+ char *szWinbindUID;
+ char *szWinbindGID;
char *szTemplateHomedir;
char *szTemplateShell;
char *szWinbindSeparator;
- BOOL bWinbindEnableLocalAccounts;
BOOL bWinbindEnumUsers;
BOOL bWinbindEnumGroups;
BOOL bWinbindUseDefaultDomain;
- BOOL bWinbindTrustedDomainsOnly;
- BOOL bWinbindNestedGroups;
- char *szWinbindBackend;
- char *szIdmapBackend;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
- char *szGuestaccount;
char *szManglingMethod;
- int mangle_prefix;
int max_log_size;
- char *szLogLevel;
+ int mangled_stack;
int max_xmit;
int max_mux;
int max_open_files;
@@ -196,8 +187,6 @@ typedef struct
int maxprotocol;
int minprotocol;
int security;
- char **AuthMethods;
- BOOL paranoid_server_security;
int maxdisksize;
int lpqcachetime;
int iMaxSmbdProcesses;
@@ -209,33 +198,49 @@ typedef struct
int max_ttl;
int max_wins_ttl;
int min_wins_ttl;
+ int ReadSize;
int lm_announce;
int lm_interval;
+ int client_code_page;
int announce_as; /* This is initialised in init_globals */
int machine_password_timeout;
int change_notify_timeout;
+ int stat_cache_size;
int map_to_guest;
int min_passwd_length;
int oplock_break_wait_time;
int winbind_cache_time;
int iLockSpinCount;
int iLockSpinTime;
- char *szLdapMachineSuffix;
- char *szLdapUserSuffix;
- char *szLdapIdmapSuffix;
- char *szLdapGroupSuffix;
-#ifdef WITH_LDAP_SAMCONFIG
+#ifdef WITH_LDAP_SAM
int ldap_port;
- char *szLdapServer;
-#endif
int ldap_ssl;
+ char *szLdapServer;
char *szLdapSuffix;
char *szLdapFilter;
char *szLdapAdminDn;
+#endif /* WITH_LDAP */
+
+#ifdef WITH_SSL
+ int sslVersion;
+ char *sslHostsRequire;
+ char *sslHostsResign;
+ char *sslCaCertDir;
+ char *sslCaCertFile;
+ char *sslServerCert;
+ char *sslServerPrivKey;
+ char *sslClientCert;
+ char *sslClientPrivKey;
+ char *sslCiphers;
+ char *sslEgdSocket;
+ char *sslEntropyFile;
+ int sslEntropyBytes;
+ BOOL sslEnabled;
+ BOOL sslReqClientCert;
+ BOOL sslReqServerCert;
+ BOOL sslCompatibility;
+#endif /* WITH_SSL */
char *szAclCompat;
- int ldap_passwd_sync;
- int ldap_replication_sleep;
- BOOL ldap_delete_dn;
BOOL bMsAddPrinterWizard;
BOOL bDNSproxy;
BOOL bWINSsupport;
@@ -246,16 +251,18 @@ typedef struct
BOOL bDomainLogons;
BOOL bEncryptPasswords;
BOOL bUpdateEncrypt;
- int clientSchannel;
- int serverSchannel;
+ BOOL bStripDot;
BOOL bNullPasswords;
BOOL bObeyPamRestrictions;
BOOL bLoadPrinters;
+ BOOL bUseRhosts;
BOOL bLargeReadwrite;
BOOL bReadRaw;
BOOL bWriteRaw;
+ BOOL bReadPrediction;
BOOL bReadbmpx;
BOOL bSyslogOnly;
+ BOOL bAdminLog;
BOOL bBrowseList;
BOOL bNISHomeMap;
BOOL bTimeServer;
@@ -263,7 +270,6 @@ typedef struct
BOOL bPamPasswordChange;
BOOL bUnixPasswdSync;
BOOL bPasswdChatDebug;
- int iPasswdChatTimeout;
BOOL bTimestampLogs;
BOOL bNTSmbSupport;
BOOL bNTPipeSupport;
@@ -271,32 +277,23 @@ typedef struct
BOOL bStatCache;
BOOL bKernelOplocks;
BOOL bAllowTrustedDomains;
+ BOOL bRestrictAnonymous;
BOOL bLanmanAuth;
- BOOL bNTLMAuth;
- BOOL bUseSpnego;
- BOOL bClientLanManAuth;
- BOOL bClientNTLMv2Auth;
- BOOL bClientPlaintextAuth;
- BOOL bClientUseSpnego;
BOOL bDebugHiresTimestamp;
BOOL bDebugPid;
BOOL bDebugUid;
BOOL bHostMSDfs;
+ BOOL bHideLocalUsers;
BOOL bUseMmap;
- BOOL bHostnameLookups;
BOOL bUnixExtensions;
- BOOL bDisableNetbios;
- BOOL bKernelChangeNotify;
- int restrict_anonymous;
int name_cache_timeout;
- int client_signing;
- int server_signing;
- param_opt_struct *param_opt;
}
global;
static global Globals;
+
+
/*
* This structure describes a single service.
*/
@@ -307,16 +304,16 @@ typedef struct
char *szService;
char *szPath;
char *szUsername;
- char **szInvalidUsers;
- char **szValidUsers;
- char **szAdminUsers;
+ char *szGuestaccount;
+ char *szInvalidUsers;
+ char *szValidUsers;
+ char *szAdminUsers;
char *szCopy;
char *szInclude;
char *szPreExec;
char *szPostExec;
char *szRootPreExec;
char *szRootPostExec;
- char *szCupsOptions;
char *szPrintcommand;
char *szLpqcommand;
char *szLprmcommand;
@@ -325,9 +322,12 @@ typedef struct
char *szQueuepausecommand;
char *szQueueresumecommand;
char *szPrintername;
+ char *szPrinterDriver;
+ char *szPrinterDriverLocation;
+ char *szDriverFile;
char *szDontdescend;
- char **szHostsallow;
- char **szHostsdeny;
+ char *szHostsallow;
+ char *szHostsdeny;
char *szMagicScript;
char *szMagicOutput;
char *szMangledMap;
@@ -337,16 +337,15 @@ typedef struct
char *comment;
char *force_user;
char *force_group;
- char **readlist;
- char **writelist;
- char **printer_admin;
+ char *readlist;
+ char *writelist;
+ char *printer_admin;
char *volume;
char *fstype;
- char **szVfsObjects;
- char *szMSDfsProxy;
+ char *szVfsObjectFile;
+ char *szVfsOptions;
int iMinPrintSpace;
int iMaxPrintJobs;
- int iMaxReportedPrintJobs;
int iWriteCacheSize;
int iCreate_mask;
int iCreate_force_mode;
@@ -362,15 +361,16 @@ typedef struct
int iOplockContentionLimit;
int iCSCPolicy;
int iBlock_size;
+ BOOL bAlternatePerm;
BOOL bPreexecClose;
BOOL bRootpreexecClose;
BOOL bCaseSensitive;
BOOL bCasePreserve;
BOOL bShortCasePreserve;
+ BOOL bCaseMangle;
+ BOOL status;
BOOL bHideDotFiles;
- BOOL bHideSpecialFiles;
BOOL bHideUnReadable;
- BOOL bHideUnWriteableFiles;
BOOL bBrowseable;
BOOL bAvailable;
BOOL bRead_only;
@@ -378,10 +378,10 @@ typedef struct
BOOL bGuest_only;
BOOL bGuest_ok;
BOOL bPrint_ok;
+ BOOL bPostscript;
BOOL bMap_system;
BOOL bMap_hidden;
BOOL bMap_archive;
- BOOL bStoreDosAttributes;
BOOL bLocking;
BOOL bStrictLocking;
BOOL bPosixLocking;
@@ -411,12 +411,11 @@ typedef struct
BOOL bUseClientDriver;
BOOL bDefaultDevmode;
BOOL bNTAclSupport;
+ BOOL bForceUnknownAclUser;
+#ifdef WITH_SENDFILE
BOOL bUseSendfile;
+#endif
BOOL bProfileAcls;
- BOOL bMap_acl_inherit;
- BOOL bAfs_Share;
- BOOL bEASupport;
- param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
}
@@ -430,6 +429,7 @@ static service sDefault = {
NULL, /* szService */
NULL, /* szPath */
NULL, /* szUsername */
+ NULL, /* szGuestAccount - this is set in init_globals() */
NULL, /* szInvalidUsers */
NULL, /* szValidUsers */
NULL, /* szAdminUsers */
@@ -439,7 +439,6 @@ static service sDefault = {
NULL, /* szPostExec */
NULL, /* szRootPreExec */
NULL, /* szRootPostExec */
- NULL, /* szCupsOptions */
NULL, /* szPrintcommand */
NULL, /* szLpqcommand */
NULL, /* szLprmcommand */
@@ -448,6 +447,9 @@ static service sDefault = {
NULL, /* szQueuepausecommand */
NULL, /* szQueueresumecommand */
NULL, /* szPrintername */
+ NULL, /* szPrinterDriver - this is set in init_globals() */
+ NULL, /* szPrinterDriverLocation */
+ NULL, /* szDriverFile */
NULL, /* szDontdescend */
NULL, /* szHostsallow */
NULL, /* szHostsdeny */
@@ -465,11 +467,10 @@ static service sDefault = {
NULL, /* printer admin */
NULL, /* volume */
NULL, /* fstype */
- NULL, /* vfs objects */
- NULL, /* szMSDfsProxy */
+ NULL, /* vfs object */
+ NULL, /* vfs options */
0, /* iMinPrintSpace */
1000, /* iMaxPrintJobs */
- 0, /* iMaxReportedPrintJobs */
0, /* iWriteCacheSize */
0744, /* iCreate_mask */
0000, /* iCreate_force_mode */
@@ -484,16 +485,17 @@ static service sDefault = {
DEFAULT_PRINTING, /* iPrinting */
2, /* iOplockContentionLimit */
0, /* iCSCPolicy */
- 1024, /* iBlock_size */
+ 1024, /* iBlock_size */
+ False, /* bAlternatePerm */
False, /* bPreexecClose */
False, /* bRootpreexecClose */
False, /* case sensitive */
True, /* case preserve */
True, /* short case preserve */
+ False, /* case mangle */
+ True, /* status */
True, /* bHideDotFiles */
- False, /* bHideSpecialFiles */
False, /* bHideUnReadable */
- False, /* bHideUnWriteableFiles */
True, /* bBrowseable */
True, /* bAvailable */
True, /* bRead_only */
@@ -501,12 +503,12 @@ static service sDefault = {
False, /* bGuest_only */
False, /* bGuest_ok */
False, /* bPrint_ok */
+ False, /* bPostscript */
False, /* bMap_system */
False, /* bMap_hidden */
True, /* bMap_archive */
- False, /* bStoreDosAttributes */
True, /* bLocking */
- True, /* bStrictLocking */
+ False, /* bStrictLocking */
True, /* bPosixLocking */
True, /* bShareModes */
True, /* bOpLocks */
@@ -534,13 +536,11 @@ static service sDefault = {
False, /* bUseClientDriver */
False, /* bDefaultDevmode */
True, /* bNTAclSupport */
- False, /* bUseSendfile */
+ False, /* bForceUnknownAclUser */
+#ifdef WITH_SENDFILE
+ False, /* bUseSendfile */
+#endif
False, /* bProfileAcls */
- False, /* bMap_acl_inherit */
- False, /* bAfs_Share */
- False, /* bEASupport */
-
- NULL, /* Parametric options */
"" /* dummy */
};
@@ -557,24 +557,25 @@ static int default_server_announce;
#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
/* prototypes for the special type handlers */
-static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
-static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
+static BOOL handle_valid_chars(const char *pszParmValue, char **ptr);
+static BOOL handle_include(const char *pszParmValue, char **ptr);
+static BOOL handle_copy(const char *pszParmValue, char **ptr);
+static BOOL handle_character_set(const char *pszParmValue, char **ptr);
+static BOOL handle_coding_system(const char *pszParmValue, char **ptr);
+static BOOL handle_client_code_page(const char *pszParmValue, char **ptr);
+static BOOL handle_vfs_object(const char *pszParmValue, char **ptr);
+static BOOL handle_source_env(const char *pszParmValue, char **ptr);
+static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
+static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
+static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
+static BOOL handle_wins_server_list(const char *pszParmValue, char **ptr);
+static BOOL handle_debug_list(const char *pszParmValue, char **ptr );
+static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
-static void set_allowed_client_auth(void);
-static const struct enum_list enum_protocol[] = {
+static struct enum_list enum_protocol[] = {
{PROTOCOL_NT1, "NT1"},
{PROTOCOL_LANMAN2, "LANMAN2"},
{PROTOCOL_LANMAN1, "LANMAN1"},
@@ -584,18 +585,15 @@ static const struct enum_list enum_protocol[] = {
{-1, NULL}
};
-static const struct enum_list enum_security[] = {
+static struct enum_list enum_security[] = {
{SEC_SHARE, "SHARE"},
{SEC_USER, "USER"},
{SEC_SERVER, "SERVER"},
{SEC_DOMAIN, "DOMAIN"},
-#ifdef HAVE_ADS
- {SEC_ADS, "ADS"},
-#endif
{-1, NULL}
};
-static const struct enum_list enum_printing[] = {
+static struct enum_list enum_printing[] = {
{PRINT_SYSV, "sysv"},
{PRINT_AIX, "aix"},
{PRINT_HPUX, "hpux"},
@@ -603,6 +601,7 @@ static const struct enum_list enum_printing[] = {
{PRINT_QNX, "qnx"},
{PRINT_PLP, "plp"},
{PRINT_LPRNG, "lprng"},
+ {PRINT_SOFTQ, "softq"},
{PRINT_CUPS, "cups"},
{PRINT_LPRNT, "nt"},
{PRINT_LPROS2, "os2"},
@@ -613,35 +612,21 @@ static const struct enum_list enum_printing[] = {
{-1, NULL}
};
-static const struct enum_list enum_ldap_ssl[] = {
-#ifdef WITH_LDAP_SAMCONFIG
+#ifdef WITH_LDAP_SAM
+static struct enum_list enum_ldap_ssl[] = {
{LDAP_SSL_ON, "Yes"},
{LDAP_SSL_ON, "yes"},
{LDAP_SSL_ON, "on"},
{LDAP_SSL_ON, "On"},
-#endif
{LDAP_SSL_OFF, "no"},
{LDAP_SSL_OFF, "No"},
{LDAP_SSL_OFF, "off"},
{LDAP_SSL_OFF, "Off"},
{LDAP_SSL_START_TLS, "start tls"},
- {LDAP_SSL_START_TLS, "Start_tls"},
- {-1, NULL}
-};
-
-static const struct enum_list enum_ldap_passwd_sync[] = {
- {LDAP_PASSWD_SYNC_OFF, "no"},
- {LDAP_PASSWD_SYNC_OFF, "No"},
- {LDAP_PASSWD_SYNC_OFF, "off"},
- {LDAP_PASSWD_SYNC_OFF, "Off"},
- {LDAP_PASSWD_SYNC_ON, "Yes"},
- {LDAP_PASSWD_SYNC_ON, "yes"},
- {LDAP_PASSWD_SYNC_ON, "on"},
- {LDAP_PASSWD_SYNC_ON, "On"},
- {LDAP_PASSWD_SYNC_ONLY, "Only"},
- {LDAP_PASSWD_SYNC_ONLY, "only"},
+ {LDAP_SSL_START_TLS, "start_tls"},
{-1, NULL}
};
+#endif
/* Types of machine we can announce as. */
#define ANNOUNCE_AS_NT_SERVER 1
@@ -649,7 +634,7 @@ static const struct enum_list enum_ldap_passwd_sync[] = {
#define ANNOUNCE_AS_WFW 3
#define ANNOUNCE_AS_NT_WORKSTATION 4
-static const struct enum_list enum_announce_as[] = {
+static struct enum_list enum_announce_as[] = {
{ANNOUNCE_AS_NT_SERVER, "NT"},
{ANNOUNCE_AS_NT_SERVER, "NT Server"},
{ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
@@ -658,13 +643,13 @@ static const struct enum_list enum_announce_as[] = {
{-1, NULL}
};
-static const struct enum_list enum_case[] = {
+static struct enum_list enum_case[] = {
{CASE_LOWER, "lower"},
{CASE_UPPER, "upper"},
{-1, NULL}
};
-static const struct enum_list enum_bool_auto[] = {
+static struct enum_list enum_bool_auto[] = {
{False, "No"},
{False, "False"},
{False, "0"},
@@ -681,36 +666,14 @@ static const struct enum_list enum_bool_auto[] = {
#define CSC_POLICY_PROGRAMS 2
#define CSC_POLICY_DISABLE 3
-static const struct enum_list enum_csc_policy[] = {
+static struct enum_list enum_csc_policy[] = {
{CSC_POLICY_MANUAL, "manual"},
{CSC_POLICY_DOCUMENTS, "documents"},
{CSC_POLICY_PROGRAMS, "programs"},
{CSC_POLICY_DISABLE, "disable"},
- {-1, NULL}
+ {-1,NULL}
};
-/* SMB signing types. */
-static const struct enum_list enum_smb_signing_vals[] = {
- {False, "No"},
- {False, "False"},
- {False, "0"},
- {False, "Off"},
- {False, "disabled"},
- {True, "Yes"},
- {True, "True"},
- {True, "1"},
- {True, "On"},
- {True, "enabled"},
- {Auto, "auto"},
- {Required, "required"},
- {Required, "mandatory"},
- {Required, "force"},
- {Required, "forced"},
- {Required, "enforced"},
- {-1, NULL}
-};
-
-
/*
Do you want session setups at user level security with a invalid
password to be rejected or allowed in as guest? WinNT rejects them
@@ -732,548 +695,549 @@ static const struct enum_list enum_smb_signing_vals[] = {
level security.
*/
-static const struct enum_list enum_map_to_guest[] = {
+static struct enum_list enum_map_to_guest[] = {
{NEVER_MAP_TO_GUEST, "Never"},
{MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
{MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
{-1, NULL}
};
-/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
- *
- * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
- * screen in SWAT. This is used to exclude parameters as well as to squash all
- * parameters that have been duplicated by pseudonyms.
- *
- * NOTE: To display a parameter in BASIC view set FLAG_BASIC
- * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
- * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
- * respective views.
- *
- * NOTE2: Handling of duplicated (synonym) paramters:
- * Only the first occurance of a parameter should be enabled by FLAG_BASIC
- * and/or FLAG_ADVANCED. All duplicates following the first mention should be
- * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
- * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
- */
+#ifdef WITH_SSL
+static struct enum_list enum_ssl_version[] = {
+ {SMB_SSL_V2, "ssl2"},
+ {SMB_SSL_V3, "ssl3"},
+ {SMB_SSL_V23, "ssl2or3"},
+ {SMB_SSL_TLS1, "tls1"},
+ {-1, NULL}
+};
+#endif
+/* note that we do not initialise the defaults union - it is not allowed in ANSI C */
static struct parm_struct parm_table[] = {
- {N_("Base Options"), P_SEP, P_SEPARATOR},
-
- {"config backend", P_STRING, P_GLOBAL, &Globals.szConfigBackend, NULL, NULL, FLAG_ADVANCED},
- {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
- {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
- {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
- {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
- {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
-#ifdef WITH_ADS
- {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"Base Options", P_SEP, P_SEPARATOR},
+
+ {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
+ {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page, NULL, 0},
+ {"code page directory", P_STRING, P_GLOBAL, &Globals.szCodePageDir, NULL, NULL, 0},
+ {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_DOS_STRING},
+ {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_DOS_STRING},
+ {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING},
+ {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING | FLAG_WIZARD},
+ {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC | FLAG_DOS_STRING | FLAG_WIZARD},
+ {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING},
+ {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING},
+ {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING},
+ {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_WIZARD},
+ {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_WIZARD},
+
+ {"Security Options", P_SEP, P_SEPARATOR},
+
+ {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_WIZARD},
+ {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_WIZARD},
+ {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
+ {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0},
+ {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL | FLAG_DEPRECATED},
+ {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
+ {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
+ {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
+ {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0},
+ {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
+ {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, 0},
+ {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_WIZARD},
+#ifdef WITH_TDB_SAM
+ {"tdb passwd file", P_STRING, P_GLOBAL, &Globals.szTDBPasswdFile, NULL, NULL, 0},
+#else
+ {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
#endif
- {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
- {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
- {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
- {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
-
- {N_("Security Options"), P_SEP, P_SEPARATOR},
-
- {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
- {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
- {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
- {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
- {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
- {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
- {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
- {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
- {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
- {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
- {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
- {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
- {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
- {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
- {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
- {"gums backend", P_STRING, P_GLOBAL, &Globals.szGumsBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
- {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
- {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
- {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
- {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
- {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
-
- {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
- {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
- {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
- {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
- {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
- {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
- {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
- {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
- {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
- {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
- {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
- {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
- {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
- {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
- {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
-
- {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
- {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
-
- {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT},
- {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
-
- {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
- {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
- {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
- {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
-
- {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
- {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
- {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
- {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
-
- {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
-
- {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
- {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
- {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
- {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
-
- {N_("Logging Options"), P_SEP, P_SEPARATOR},
-
- {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
- {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
- {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
- {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
- {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
-
- {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
- {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
- {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
- {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
- {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
- {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Protocol Options"), P_SEP, P_SEPARATOR},
-
- {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
- {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
- {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
- {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
- {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
- {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
- {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
- {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
- {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
-
- {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
- {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
- {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
-
- {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
- {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
- {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
- {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
-
- {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
- {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
- {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
- {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
- {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
- {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
- {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
- {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
- {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
- {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Tuning Options"), P_SEP, P_SEPARATOR},
-
- {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
- {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
- {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
- {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
- {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
-
- {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
- {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
- {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
- {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
- {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
- {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
-
- {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
- {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
- {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
- {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
-
- {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Printing Options"), P_SEP, P_SEPARATOR},
-
- {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
- {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
- {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
- {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
-
- {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
- {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
- {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
- {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
- {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
-
- {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
- {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
- {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
-
- {N_("Filename Handling"), P_SEP, P_SEPARATOR},
- {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
- {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
-
- {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
- {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
- {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
- {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
- {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
- {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
- {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
- {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
-
- {N_("Domain Options"), P_SEP, P_SEPARATOR},
-
- {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
-
- {N_("Logon Options"), P_SEP, P_SEPARATOR},
-
- {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
- {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
- {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
- {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
- {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
- {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
- {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
- {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
- {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
- {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
-
- {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
- {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
- {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
- {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
- {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Browse Options"), P_SEP, P_SEPARATOR},
-
- {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
- {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
- {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
- {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
- {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
- {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
- {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
- {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
- {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
- {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
-
- {N_("WINS Options"), P_SEP, P_SEPARATOR},
-
- {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
- {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
-
- {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
- {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
- {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
-
- {N_("Locking Options"), P_SEP, P_SEPARATOR},
-
- {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
- {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
- {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
-
- {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
- {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
-
- {N_("Ldap Options"), P_SEP, P_SEPARATOR},
-
-#ifdef WITH_LDAP_SAMCONFIG
- {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED},
- {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED},
+ {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
+ {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
+ {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
+
+ {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, 0},
+ {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
+ {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
+ {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
+ {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
+ {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
+ {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
+ {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
+ {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0},
+ {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, 0},
+ {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
+
+ {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
+ {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
+
+ {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_GLOBAL},
+ {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"printer admin", P_STRING, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
+ {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
+ {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
+ {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
+
+ {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE},
+ {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
+ {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
+ {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
+
+ {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
+ {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
+ {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"force unknown acl user", P_OCTAL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
+ {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
+ {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
+ {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
+ {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
+
+ {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
+ {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
+
+ {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
+ {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
+ {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
+ {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
+ {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
+
+#ifdef WITH_SSL
+ {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
+ {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0},
+
+ {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0},
+ {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0},
+ {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0},
+ {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0},
+ {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslServerCert, NULL, NULL, 0},
+ {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslServerPrivKey, NULL, NULL, 0},
+ {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0},
+ {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0},
+ {"ssl egd socket", P_STRING, P_GLOBAL, &Globals.sslEgdSocket, NULL, NULL, 0},
+ {"ssl entropy file", P_STRING, P_GLOBAL, &Globals.sslEntropyFile, NULL, NULL, 0},
+ {"ssl entropy bytes", P_INTEGER, P_GLOBAL, &Globals.sslEntropyBytes, NULL, NULL, 0},
+ {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0},
+ {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0},
+ {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0},
+ {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
+ {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0},
+#endif /* WITH_SSL */
+
+ {"Logging Options", P_SEP, P_SEPARATOR},
+
+ {"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0},
+ {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0},
+ {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0},
+ {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
+ {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
+ {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
+
+ {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
+ {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
+ {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
+ {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0},
+ {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0},
+ {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0},
+
+ {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_PRINT | FLAG_DEPRECATED},
+
+ {"Protocol Options", P_SEP, P_SEPARATOR},
+
+ {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
+ {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0},
+ {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
+ {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, 0},
+ {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
+ {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
+ {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
+
+ {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
+ {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
+ {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
+ {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE },
+ {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, 0 },
+ {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE },
+ {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
+ {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
+ {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
+ {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
+
+ {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
+ {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
+ {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
+ {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
+ {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
+ {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, 0},
+
+ {"Tuning Options", P_SEP, P_SEPARATOR},
+
+ {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
+ {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
+ {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
+ {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
+
+ {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
+ {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, 0},
+ {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
+ {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
+ {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
+ {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
+ {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, 0},
+ {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
+
+ {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
+ {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
+ {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
+ {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
+ {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
+ {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, 0},
+#ifdef WITH_SENDFILE
+ {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
#endif
- {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
- {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
- {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
- {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
- {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
- {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED},
- {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
- {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
- {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
- {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
- {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
- {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
- {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
- {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
-
- {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
- {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
- {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
- {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
- {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
- {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
+ {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
+
+ {"Printing Options", P_SEP, P_SEPARATOR},
+
+ {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
+ {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
+ {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
+ {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT},
+ {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
+ {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
+ {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
+ {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT | FLAG_DEPRECATED},
+ {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
+ {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+
+ {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, 0},
+ {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0},
+ {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0},
+ {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, 0},
+ {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0},
+
+ {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT|FLAG_DOS_STRING},
+ {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_DOS_STRING},
+ {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
+ {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
+ {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT | FLAG_DEPRECATED},
+ {"printer driver file", P_STRING, P_LOCAL, &sDefault.szDriverFile, NULL, NULL, FLAG_PRINT | FLAG_DEPRECATED},
+ {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL | FLAG_DEPRECATED},
+
+ {"Filename Handling", P_SEP, P_SEPARATOR},
+ {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_DEPRECATED },
+ {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, 0},
+
+ {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
+ {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
+ {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
+ {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
+ {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
+ {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
+ {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
+ {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
+
+ {"Domain Options", P_SEP, P_SEPARATOR},
+
+ {"domain admin group", P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
+ {"domain guest group", P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
+#ifdef USING_GROUPNAME_MAP
+
+ {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
+#endif /* USING_GROUPNAME_MAP */
+
+ {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
+
+ {"Logon Options", P_SEP, P_SEPARATOR},
+
+ {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0},
+ {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0},
+ {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_DOS_STRING},
+ {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_DOS_STRING},
+ {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
+ {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_DOS_STRING},
+ {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
+
+ {"Browse Options", P_SEP, P_SEPARATOR},
+
+ {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
+ {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0},
+ {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
+ {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC},
+ {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
+ {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
+ {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC},
+ {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
+ {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
+ {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
+ {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL},
+
+ {"WINS Options", P_SEP, P_SEPARATOR},
+ {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
+ {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
+
+ {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, handle_wins_server_list, NULL, FLAG_BASIC | FLAG_WIZARD},
+ {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_WIZARD},
+ {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0},
+
+ {"Locking Options", P_SEP, P_SEPARATOR},
+
+ {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
+ {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
+ {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
+ {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
+ {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
+
+ {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
+ {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+
+#ifdef WITH_LDAP_SAM
+ {"Ldap Options", P_SEP, P_SEPARATOR},
+
+ {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
+ {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
+ {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
+ {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
+ {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, 0},
+ {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, 0},
+#endif /* WITH_LDAP_SAM */
+
+ {"Miscellaneous Options", P_SEP, P_SEPARATOR},
+ {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, 0},
+ {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, 0},
+ {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, 0},
+
+ {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
+ {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING},
+ {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING},
+ {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
+ {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, 0},
#ifdef WITH_UTMP
- {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
- {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
- {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
+ {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
+ {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0},
+ {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, 0},
#endif
+
+ {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DOS_STRING},
+ {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DOS_STRING},
+ {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
+ {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
+ {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
+ {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
+ {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0},
+ {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
+ {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
+ {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
+ {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
+ {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
+
+ {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
+ {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
+ {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
+ {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
+
+ {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
+ {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
+ {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
+ {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
+ {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
+ {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT},
+ {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE | FLAG_DOS_STRING},
+ {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
+ {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
+ {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, 0},
+ {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
+ {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
+ {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
+ {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+
+ {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
+ {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL,
+ NULL, 0},
+
+ {"VFS module options", P_SEP, P_SEPARATOR},
+
+ {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE},
+ {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
+
+#ifdef WITH_MSDFS
+ {"MSDfs options", P_SEP, P_SEPARATOR},
+
+ {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
+ {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, 0},
+#endif
+
+ {"Winbind options", P_SEP, P_SEPARATOR},
- {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
- {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
- {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
- {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED},
- {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
- {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
- {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
- {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
- {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
- {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
- {"afs username map", P_USTRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
- {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
- {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
- {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
-
- {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
- {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
- {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
-
- {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
- {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
-
- {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
-
- {N_("VFS module options"), P_SEP, P_SEPARATOR},
-
- {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
-
-
- {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
- {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
-
- {N_("Winbind options"), P_SEP, P_SEPARATOR},
-
- {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
- {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
- {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
- {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
- {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
- {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE},
- {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED},
- {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
- {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
- {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
- {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
- {"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED},
- {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
- {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
- {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
- {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
- {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
-
- {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
+ {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, 0},
+ {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, 0},
+ {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, 0},
+ {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, 0},
+ {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, 0},
+ {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0},
+ {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, 0},
+ {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, 0},
+ {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, 0},
+
+ {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
+
/***************************************************************************
- Initialise the sDefault parameter structure for the printer values.
+Initialise the sDefault parameter structure for the printer values.
***************************************************************************/
-
-static void init_printer_values(service *pService)
+static void init_printer_values(void)
{
+ string_set(&sDefault.szPrinterDriver, "");
+ string_set(&sDefault.szDriverFile, DRIVERFILE);
+
/* choose defaults depending on the type of printing */
- switch (pService->iPrinting) {
+ switch (sDefault.iPrinting)
+ {
case PRINT_BSD:
case PRINT_AIX:
case PRINT_LPRNT:
case PRINT_LPROS2:
- string_set(&pService->szLpqcommand, "lpq -P'%p'");
- string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
- string_set(&pService->szPrintcommand,
- "lpr -r -P'%p' %s");
+ string_set(&sDefault.szLpqcommand, "lpq -P%p");
+ string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
+ string_set(&sDefault.szPrintcommand,
+ "lpr -r -P%p %s");
break;
case PRINT_LPRNG:
case PRINT_PLP:
- string_set(&pService->szLpqcommand, "lpq -P'%p'");
- string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
- string_set(&pService->szPrintcommand,
- "lpr -r -P'%p' %s");
- string_set(&pService->szQueuepausecommand,
- "lpc stop '%p'");
- string_set(&pService->szQueueresumecommand,
- "lpc start '%p'");
- string_set(&pService->szLppausecommand,
- "lpc hold '%p' %j");
- string_set(&pService->szLpresumecommand,
- "lpc release '%p' %j");
+ string_set(&sDefault.szLpqcommand, "lpq -P%p");
+ string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
+ string_set(&sDefault.szPrintcommand,
+ "lpr -r -P%p %s");
+ string_set(&sDefault.szQueuepausecommand,
+ "lpc stop %p");
+ string_set(&sDefault.szQueueresumecommand,
+ "lpc start %p");
+ string_set(&sDefault.szLppausecommand,
+ "lpc hold %p %j");
+ string_set(&sDefault.szLpresumecommand,
+ "lpc release %p %j");
break;
case PRINT_CUPS:
#ifdef HAVE_CUPS
- string_set(&pService->szLpqcommand, "");
- string_set(&pService->szLprmcommand, "");
- string_set(&pService->szPrintcommand, "");
- string_set(&pService->szLppausecommand, "");
- string_set(&pService->szLpresumecommand, "");
- string_set(&pService->szQueuepausecommand, "");
- string_set(&pService->szQueueresumecommand, "");
-
- string_set(&Globals.szPrintcapname, "cups");
+ string_set(&sDefault.szLpqcommand, "");
+ string_set(&sDefault.szLprmcommand, "");
+ string_set(&sDefault.szPrintcommand, "");
+ string_set(&sDefault.szLppausecommand, "");
+ string_set(&sDefault.szLpresumecommand, "");
+ string_set(&sDefault.szQueuepausecommand, "");
+ string_set(&sDefault.szQueueresumecommand, "");
+
+ string_set(&Globals.szPrintcapname, "cups");
#else
- string_set(&pService->szLpqcommand,
- "/usr/bin/lpstat -o '%p'");
- string_set(&pService->szLprmcommand,
- "/usr/bin/cancel '%p-%j'");
- string_set(&pService->szPrintcommand,
- "/usr/bin/lp -d '%p' %s; rm %s");
- string_set(&pService->szLppausecommand,
- "lp -i '%p-%j' -H hold");
- string_set(&pService->szLpresumecommand,
- "lp -i '%p-%j' -H resume");
- string_set(&pService->szQueuepausecommand,
- "/usr/bin/disable '%p'");
- string_set(&pService->szQueueresumecommand,
- "/usr/bin/enable '%p'");
+ string_set(&sDefault.szLpqcommand,
+ "/usr/bin/lpstat -o %p");
+ string_set(&sDefault.szLprmcommand,
+ "/usr/bin/cancel %p-%j");
+ string_set(&sDefault.szPrintcommand,
+ "/usr/bin/lp -d %p %s; rm %s");
+ string_set(&sDefault.szLppausecommand,
+ "lp -i %p-%j -H hold");
+ string_set(&sDefault.szLpresumecommand,
+ "lp -i %p-%j -H resume");
+ string_set(&sDefault.szQueuepausecommand,
+ "/usr/bin/disable %p");
+ string_set(&sDefault.szQueueresumecommand,
+ "/usr/bin/enable %p");
string_set(&Globals.szPrintcapname, "lpstat");
#endif /* HAVE_CUPS */
break;
case PRINT_SYSV:
case PRINT_HPUX:
- string_set(&pService->szLpqcommand, "lpstat -o%p");
- string_set(&pService->szLprmcommand, "cancel %p-%j");
- string_set(&pService->szPrintcommand,
+ string_set(&sDefault.szLpqcommand, "lpstat -o%p");
+ string_set(&sDefault.szLprmcommand, "cancel %p-%j");
+ string_set(&sDefault.szPrintcommand,
"lp -c -d%p %s; rm %s");
- string_set(&pService->szQueuepausecommand,
+ string_set(&sDefault.szQueuepausecommand,
"disable %p");
- string_set(&pService->szQueueresumecommand,
+ string_set(&sDefault.szQueueresumecommand,
"enable %p");
#ifndef HPUX
- string_set(&pService->szLppausecommand,
+ string_set(&sDefault.szLppausecommand,
"lp -i %p-%j -H hold");
- string_set(&pService->szLpresumecommand,
+ string_set(&sDefault.szLpresumecommand,
"lp -i %p-%j -H resume");
-#endif /* HPUX */
+#endif /* SYSV */
break;
case PRINT_QNX:
- string_set(&pService->szLpqcommand, "lpq -P%p");
- string_set(&pService->szLprmcommand, "lprm -P%p %j");
- string_set(&pService->szPrintcommand, "lp -r -P%p %s");
+ string_set(&sDefault.szLpqcommand, "lpq -P%p");
+ string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
+ string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
break;
+ case PRINT_SOFTQ:
+ string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
+ string_set(&sDefault.szLprmcommand,
+ "qstat -s -j%j -c");
+ string_set(&sDefault.szPrintcommand,
+ "lp -d%p -s %s; rm %s");
+ string_set(&sDefault.szLppausecommand,
+ "qstat -s -j%j -h");
+ string_set(&sDefault.szLpresumecommand,
+ "qstat -s -j%j -r");
+ break;
#ifdef DEVELOPER
case PRINT_TEST:
case PRINT_VLP:
- string_set(&pService->szPrintcommand, "vlp print %p %s");
- string_set(&pService->szLpqcommand, "vlp lpq %p");
- string_set(&pService->szLprmcommand, "vlp lprm %p %j");
- string_set(&pService->szLppausecommand, "vlp lppause %p %j");
- string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
- string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
- string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
+ string_set(&sDefault.szPrintcommand, "vlp print %p %s");
+ string_set(&sDefault.szLpqcommand, "vlp lpq %p");
+ string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
+ string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
+ string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
+ string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
+ string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
break;
#endif /* DEVELOPER */
@@ -1281,15 +1245,15 @@ static void init_printer_values(service *pService)
}
/***************************************************************************
- Initialise the global parameter structure.
+Initialise the global parameter structure.
***************************************************************************/
-
static void init_globals(void)
{
static BOOL done_init = False;
pstring s;
- if (!done_init) {
+ if (!done_init)
+ {
int i;
memset((void *)&Globals, '\0', sizeof(Globals));
@@ -1299,57 +1263,43 @@ static void init_globals(void)
parm_table[i].ptr)
string_set(parm_table[i].ptr, "");
+ string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
string_set(&sDefault.fstype, FSTYPE_STRING);
+ init_printer_values();
+
done_init = True;
}
DEBUG(3, ("Initialising global parameters\n"));
- string_set(&Globals.szConfigBackend, NULL);
-
- string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
- string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
-
- /* use the new 'hash2' method by default, with a prefix of 1 */
- string_set(&Globals.szManglingMethod, "hash2");
- Globals.mangle_prefix = 1;
-
- string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
-
- /* using UTF8 by default allows us to support all chars */
- string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
-
-#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
- /* If the system supports nl_langinfo(), try to grab the value
- from the user's locale */
- string_set(&Globals.display_charset, "LOCALE");
+#ifdef WITH_TDB_SAM
+ string_set(&Globals.szTDBPasswdFile, TDB_PASSWD_FILE);
#else
- string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
+ string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
#endif
- /* Use codepage 850 as a default for the dos character set */
- string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
+ /* use the old 'hash' method by default */
+ string_set(&Globals.szManglingMethod, "hash");
/*
* Allow the default PASSWD_CHAT to be overridden in local.h.
*/
string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
-
- set_global_myname(myhostname());
- string_set(&Globals.szNetbiosName,global_myname());
-
- set_global_myworkgroup(WORKGROUP);
- string_set(&Globals.szWorkgroup, lp_workgroup());
-
- string_set(&Globals.szPasswdProgram, "");
+ string_set(&Globals.szWorkGroup, WORKGROUP);
+ string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
- string_set(&Globals.szPidDir, dyn_PIDDIR);
- string_set(&Globals.szLockDir, dyn_LOCKDIR);
+ string_set(&Globals.szLockDir, LOCKDIR);
+ string_set(&Globals.szPidDir, PIDDIR);
+#ifdef WITH_UTMP
+ string_set(&Globals.szUtmpDir, "");
+ string_set(&Globals.szWtmpDir, "");
+ Globals.bUtmp = False;
+#endif
string_set(&Globals.szSocketAddress, "0.0.0.0");
pstrcpy(s, "Samba ");
- pstrcat(s, SAMBA_VERSION_STRING);
+ pstrcat(s, VERSION);
string_set(&Globals.szServerString, s);
slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
DEFAULT_MINOR_VERSION);
@@ -1362,12 +1312,12 @@ static void init_globals(void)
string_set(&Globals.szLogonHome, "\\\\%N\\%U");
string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
- string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
- string_set(&Globals.szPasswordServer, "*");
-
- Globals.AlgorithmicRidBase = BASE_RID;
+ string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
+ string_set(&Globals.szCodePageDir, CODEPAGEDIR);
Globals.bLoadPrinters = True;
+ Globals.bUseRhosts = False;
+ Globals.mangled_stack = 50;
/* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
@@ -1385,20 +1335,19 @@ static void init_globals(void)
Globals.maxprotocol = PROTOCOL_NT1;
Globals.minprotocol = PROTOCOL_CORE;
Globals.security = SEC_USER;
- Globals.paranoid_server_security = True;
- Globals.bEncryptPasswords = True;
+ Globals.bEncryptPasswords = False;
Globals.bUpdateEncrypt = False;
- Globals.clientSchannel = Auto;
- Globals.serverSchannel = Auto;
Globals.bReadRaw = True;
Globals.bWriteRaw = True;
+ Globals.bReadPrediction = False;
Globals.bReadbmpx = False;
Globals.bNullPasswords = False;
Globals.bObeyPamRestrictions = False;
+ Globals.bStripDot = False;
Globals.syslog = 1;
Globals.bSyslogOnly = False;
+ Globals.bAdminLog = False;
Globals.bTimestampLogs = True;
- string_set(&Globals.szLogLevel, "0");
Globals.bDebugHiresTimestamp = False;
Globals.bDebugPid = False;
Globals.bDebugUid = False;
@@ -1407,9 +1356,10 @@ static void init_globals(void)
Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
Globals.change_notify_timeout = 60; /* 1 minute default. */
- Globals.bKernelChangeNotify = True; /* On if we have it. */
+ Globals.ReadSize = 16 * 1024;
Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
Globals.lm_interval = 60;
+ Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
Globals.bNISHomeMap = False;
@@ -1419,62 +1369,59 @@ static void init_globals(void)
string_set(&Globals.szNISHomeMapName, "auto.home");
#endif
#endif
+ Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
Globals.bTimeServer = False;
Globals.bBindInterfacesOnly = False;
Globals.bUnixPasswdSync = False;
Globals.bPamPasswordChange = False;
Globals.bPasswdChatDebug = False;
- Globals.iPasswdChatTimeout = 2; /* 2 second default. */
+ Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
- Globals.bNTStatusSupport = True; /* Use NT status by default. */
Globals.bStatCache = True; /* use stat cache by default */
- Globals.restrict_anonymous = 0;
- Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
- Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
+ Globals.bNTStatusSupport = True; /* Use NT status by default. */
+ Globals.bRestrictAnonymous = False;
Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
- Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
- Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
- /* Note, that we will use NTLM2 session security (which is different), if it is available */
-
Globals.map_to_guest = 0; /* By Default, "Never" */
Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = True;
- Globals.iLockSpinCount = 3; /* Try 3 times. */
+ Globals.iLockSpinCount = 3; /* Try 2 times. */
Globals.iLockSpinTime = 10; /* usec. */
#ifdef MMAP_BLACKLIST
Globals.bUseMmap = False;
#else
Globals.bUseMmap = True;
#endif
- Globals.bUnixExtensions = True;
-
- /* hostname lookups can be very expensive and are broken on
- a large number of sites (tridge) */
- Globals.bHostnameLookups = False;
-
-#ifdef WITH_LDAP_SAMCONFIG
+ Globals.bUnixExtensions = False;
+
+#ifdef WITH_SSL
+ Globals.sslVersion = SMB_SSL_V23;
+ string_set(&Globals.sslHostsRequire, "");
+ string_set(&Globals.sslHostsResign, "");
+ string_set(&Globals.sslCaCertDir, "");
+ string_set(&Globals.sslCaCertFile, "");
+ string_set(&Globals.sslServerCert, "");
+ string_set(&Globals.sslServerPrivKey, "");
+ string_set(&Globals.sslClientCert, "");
+ string_set(&Globals.sslClientPrivKey, "");
+ string_set(&Globals.sslCiphers, "");
+ string_set(&Globals.sslEgdSocket, "");
+ string_set(&Globals.sslEntropyFile, "");
+ Globals.sslEntropyBytes = 256;
+ Globals.sslEnabled = False;
+ Globals.sslReqClientCert = False;
+ Globals.sslReqServerCert = False;
+ Globals.sslCompatibility = False;
+#endif /* WITH_SSL */
+
+#ifdef WITH_LDAP_SAM
string_set(&Globals.szLdapServer, "localhost");
- Globals.ldap_port = 636;
- Globals.szPassdbBackend = str_list_make("ldapsam_compat", NULL);
-#else
- Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
-#endif /* WITH_LDAP_SAMCONFIG */
- string_set(&Globals.szGumsBackend, "tdbsam2");
-
string_set(&Globals.szLdapSuffix, "");
- string_set(&Globals.szLdapFilter, "(uid=%u)");
- string_set(&Globals.szLdapMachineSuffix, "");
- string_set(&Globals.szLdapUserSuffix, "");
- string_set(&Globals.szLdapGroupSuffix, "");
- string_set(&Globals.szLdapIdmapSuffix, "");
-
+ string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
string_set(&Globals.szLdapAdminDn, "");
+ Globals.ldap_port = 636;
Globals.ldap_ssl = LDAP_SSL_ON;
- Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
- Globals.ldap_delete_dn = False;
- Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
-
+#endif /* WITH_LDAP_SAM */
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -1506,37 +1453,31 @@ static void init_globals(void)
string_set(&Globals.szTemplateShell, "/bin/false");
string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
- string_set(&Globals.szTemplatePrimaryGroup, "nobody");
string_set(&Globals.szWinbindSeparator, "\\");
string_set(&Globals.szAclCompat, "");
+ Globals.winbind_cache_time = 15;
- Globals.winbind_cache_time = 300; /* 5 minutes */
- Globals.bWinbindEnableLocalAccounts = True;
Globals.bWinbindEnumUsers = True;
Globals.bWinbindEnumGroups = True;
Globals.bWinbindUseDefaultDomain = False;
- Globals.bWinbindTrustedDomainsOnly = False;
- Globals.bWinbindNestedGroups = False;
-
- Globals.bEnableRidAlgorithm = True;
- Globals.name_cache_timeout = 660; /* In seconds */
+ Globals.bHostMSDfs = False;
- Globals.bUseSpnego = True;
- Globals.bClientUseSpnego = True;
+ Globals.name_cache_timeout = 660; /* In seconds */
- Globals.client_signing = Auto;
- Globals.server_signing = False;
+ /*
+ * This must be done last as it checks the value in
+ * client_code_page.
+ */
- string_set(&Globals.smb_ports, SMB_PORTS);
+ interpret_coding_system(KANJI);
}
static TALLOC_CTX *lp_talloc;
/******************************************************************* a
- Free up temporary memory - called from the main loop.
+free up temporary memory - called from the main loop
********************************************************************/
-
void lp_talloc_free(void)
{
if (!lp_talloc)
@@ -1546,40 +1487,35 @@ void lp_talloc_free(void)
}
/*******************************************************************
- Convenience routine to grab string parameters into temporary memory
- and run standard_sub_basic on them. The buffers can be written to by
- callers without affecting the source string.
+convenience routine to grab string parameters into temporary memory
+and run standard_sub_basic on them. The buffers can be written to by
+callers without affecting the source string.
********************************************************************/
-
static char *lp_string(const char *s)
{
- char *ret, *tmpstr;
+ size_t len = s ? strlen(s) : 0;
+ char *ret;
- /* The follow debug is useful for tracking down memory problems
- especially if you have an inner loop that is calling a lp_*()
- function that returns a string. Perhaps this debug should be
- present all the time? */
+ if (!lp_talloc)
+ lp_talloc = talloc_init();
-#if 0
- DEBUG(10, ("lp_string(%s)\n", s));
-#endif
+ ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
- if (!lp_talloc)
- lp_talloc = talloc_init("lp_talloc");
+ if (!ret)
+ return NULL;
- tmpstr = alloc_sub_basic(current_user_info.smb_name, s);
- if (trim_char(tmpstr, '\"', '\"')) {
- if (strchr(tmpstr,'\"') != NULL) {
- SAFE_FREE(tmpstr);
- tmpstr = alloc_sub_basic(current_user_info.smb_name,s);
- }
- }
- ret = talloc_strdup(lp_talloc, tmpstr);
- SAFE_FREE(tmpstr);
-
+ if (!s)
+ *ret = 0;
+ else
+ StrnCpy(ret, s, len);
+
+ trim_string(ret, "\"", "\"");
+
+ standard_sub_basic(ret, len + 100);
return (ret);
}
+
/*
In this section all the functions that are used to access the
parameters from the rest of the program are defined
@@ -1587,10 +1523,6 @@ static char *lp_string(const char *s)
#define FN_GLOBAL_STRING(fn_name,ptr) \
char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
-#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
- const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
-#define FN_GLOBAL_LIST(fn_name,ptr) \
- const char **fn_name(void) {return(*(const char ***)(ptr));}
#define FN_GLOBAL_BOOL(fn_name,ptr) \
BOOL fn_name(void) {return(*(BOOL *)(ptr));}
#define FN_GLOBAL_CHAR(fn_name,ptr) \
@@ -1601,9 +1533,7 @@ static char *lp_string(const char *s)
#define FN_LOCAL_STRING(fn_name,val) \
char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
#define FN_LOCAL_CONST_STRING(fn_name,val) \
- const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
-#define FN_LOCAL_LIST(fn_name,val) \
- const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
+ const char *fn_name(int i) {return(const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
#define FN_LOCAL_BOOL(fn_name,val) \
BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
#define FN_LOCAL_CHAR(fn_name,val) \
@@ -1611,15 +1541,13 @@ static char *lp_string(const char *s)
#define FN_LOCAL_INTEGER(fn_name,val) \
int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
-FN_GLOBAL_STRING(lp_config_backend, &Globals.szConfigBackend)
-FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
-FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
-FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
-FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
+#ifdef WITH_TDB_SAM
+FN_GLOBAL_STRING(lp_tdb_passwd_file, &Globals.szTDBPasswdFile)
+#else
FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
-FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
+#endif
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
@@ -1628,91 +1556,86 @@ FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
-FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
-FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
+#ifdef WITH_UTMP
FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
+#endif
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
+FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
-FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
-FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
-FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
-FN_GLOBAL_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
+FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
-FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
-FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
-FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
-FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
+#ifdef USING_GROUPNAME_MAP
+FN_GLOBAL_STRING(lp_groupname_map, &Globals.szGroupnameMap)
+#endif /* USING_GROUPNAME_MAP */
+FN_GLOBAL_STRING(lp_logon_script, &Globals.szLogonScript)
+FN_GLOBAL_STRING(lp_logon_path, &Globals.szLogonPath)
+FN_GLOBAL_STRING(lp_logon_drive, &Globals.szLogonDrive)
+FN_GLOBAL_STRING(lp_logon_home, &Globals.szLogonHome)
FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
-FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
-FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
+FN_GLOBAL_STRING(lp_wins_server, &Globals.szWINSserver)
+FN_GLOBAL_STRING(lp_interfaces, &Globals.szInterfaces)
FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
-FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
-FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
-FN_GLOBAL_STRING(lp_gums_backend, &Globals.szGumsBackend)
-FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
+FN_GLOBAL_STRING(lp_netbios_aliases, &Globals.szNetbiosAliases)
FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
-
-FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
-FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
-FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
-FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
-FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
-FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
-
-FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
-
-FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
-FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
-
FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
-FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
-FN_GLOBAL_STRING(lp_template_primary_group, &Globals.szTemplatePrimaryGroup)
-FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
-FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
-FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
+FN_GLOBAL_STRING(lp_domain_admin_group, &Globals.szDomainAdminGroup)
+FN_GLOBAL_STRING(lp_domain_guest_group, &Globals.szDomainGuestGroup)
+FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
+FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
+FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
-FN_GLOBAL_BOOL(lp_winbind_enable_local_accounts, &Globals.bWinbindEnableLocalAccounts)
FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
-FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
-FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
-
-
-FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
-FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
-
-#ifdef WITH_LDAP_SAMCONFIG
+FN_GLOBAL_STRING(lp_codepagedir,&Globals.szCodePageDir)
+#ifdef WITH_LDAP_SAM
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
-FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
-#endif
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
+FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
-FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
-FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
-FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
+#endif /* WITH_LDAP_SAM */
FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
+FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
+
+#ifdef WITH_SSL
+FN_GLOBAL_INTEGER(lp_ssl_version, &Globals.sslVersion)
+FN_GLOBAL_STRING(lp_ssl_hosts, &Globals.sslHostsRequire)
+FN_GLOBAL_STRING(lp_ssl_hosts_resign, &Globals.sslHostsResign)
+FN_GLOBAL_STRING(lp_ssl_cacertdir, &Globals.sslCaCertDir)
+FN_GLOBAL_STRING(lp_ssl_cacertfile, &Globals.sslCaCertFile)
+FN_GLOBAL_STRING(lp_ssl_server_cert, &Globals.sslServerCert)
+FN_GLOBAL_STRING(lp_ssl_server_privkey, &Globals.sslServerPrivKey)
+FN_GLOBAL_STRING(lp_ssl_client_cert, &Globals.sslClientCert)
+FN_GLOBAL_STRING(lp_ssl_client_privkey, &Globals.sslClientPrivKey)
+FN_GLOBAL_STRING(lp_ssl_ciphers, &Globals.sslCiphers)
+FN_GLOBAL_STRING(lp_ssl_egdsocket, &Globals.sslEgdSocket)
+FN_GLOBAL_STRING(lp_ssl_entropyfile, &Globals.sslEntropyFile)
+FN_GLOBAL_INTEGER(lp_ssl_entropybytes, &Globals.sslEntropyBytes)
+FN_GLOBAL_BOOL(lp_ssl_enabled, &Globals.sslEnabled)
+FN_GLOBAL_BOOL(lp_ssl_reqClientCert, &Globals.sslReqClientCert)
+FN_GLOBAL_BOOL(lp_ssl_reqServerCert, &Globals.sslReqServerCert)
+FN_GLOBAL_BOOL(lp_ssl_compatibility, &Globals.sslCompatibility)
+#endif /* WITH_SSL */
-FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
@@ -1721,17 +1644,19 @@ FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
+FN_GLOBAL_BOOL(lp_use_rhosts, &Globals.bUseRhosts)
+FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
+FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
-FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
-FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
+FN_GLOBAL_BOOL(lp_admin_log, &Globals.bAdminLog)
FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
@@ -1743,26 +1668,18 @@ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
-FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
+FN_GLOBAL_BOOL(lp_nt_smb_support, &Globals.bNTSmbSupport)
FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
-FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
+FN_GLOBAL_BOOL(lp_restrict_anonymous, &Globals.bRestrictAnonymous)
FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
-FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
-FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
-FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
-FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
-FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
-FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
-FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
-FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
@@ -1773,27 +1690,30 @@ FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
+FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
FN_GLOBAL_INTEGER(lp_security, &Globals.security)
-FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
-FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
+FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
+FN_GLOBAL_INTEGER(lp_client_code_page, &Globals.client_code_page)
static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
+FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
+FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
FN_LOCAL_STRING(lp_preexec, szPreExec)
FN_LOCAL_STRING(lp_postexec, szPostExec)
FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
@@ -1803,10 +1723,10 @@ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
FN_LOCAL_STRING(lp_pathname, szPath)
FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
FN_LOCAL_STRING(lp_username, szUsername)
-FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
-FN_LOCAL_LIST(lp_valid_users, szValidUsers)
-FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
-FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
+FN_LOCAL_STRING(lp_guestaccount, szGuestaccount)
+FN_LOCAL_STRING(lp_invalid_users, szInvalidUsers)
+FN_LOCAL_STRING(lp_valid_users, szValidUsers)
+FN_LOCAL_STRING(lp_admin_users, szAdminUsers)
FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
@@ -1815,24 +1735,27 @@ FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
static FN_LOCAL_STRING(_lp_printername, szPrintername)
-FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
-FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
+FN_LOCAL_STRING(lp_driverfile, szDriverFile)
+FN_LOCAL_STRING(lp_printerdriver, szPrinterDriver)
+FN_LOCAL_STRING(lp_hostsallow, szHostsallow)
+FN_LOCAL_STRING(lp_hostsdeny, szHostsdeny)
FN_LOCAL_STRING(lp_magicscript, szMagicScript)
FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_force_user, force_user)
FN_LOCAL_STRING(lp_force_group, force_group)
-FN_LOCAL_LIST(lp_readlist, readlist)
-FN_LOCAL_LIST(lp_writelist, writelist)
-FN_LOCAL_LIST(lp_printer_admin, printer_admin)
+FN_LOCAL_STRING(lp_readlist, readlist)
+FN_LOCAL_STRING(lp_writelist, writelist)
+FN_LOCAL_STRING(lp_printer_admin, printer_admin)
FN_LOCAL_STRING(lp_fstype, fstype)
-FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
-FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
+FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
+FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
static FN_LOCAL_STRING(lp_volume, volume)
FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
FN_LOCAL_STRING(lp_hide_files, szHideFiles)
FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
+FN_LOCAL_STRING(lp_driverlocation, szPrinterDriverLocation)
FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
@@ -1840,23 +1763,23 @@ FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
+FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
+FN_LOCAL_BOOL(lp_status, status)
FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
-FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
-FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
FN_LOCAL_BOOL(lp_browseable, bBrowseable)
FN_LOCAL_BOOL(lp_readonly, bRead_only)
FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
+FN_LOCAL_BOOL(lp_postscript, bPostscript)
FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
-FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
FN_LOCAL_BOOL(lp_locking, bLocking)
FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
-FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_share_modes, bShareModes)
+FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
@@ -1880,11 +1803,11 @@ FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
-FN_LOCAL_BOOL(lp_ea_support, bEASupport)
-FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
+FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
+#ifdef WITH_SENDFILE
+FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
+#endif
FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
-FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
-FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
@@ -1897,354 +1820,85 @@ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
FN_LOCAL_INTEGER(lp_printing, iPrinting)
-FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
-FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
-FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
-FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
-FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
+FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
/* local prototypes */
static int map_parameter(const char *pszParmName);
static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
static int getservicebyname(const char *pszServiceName,
- service * pserviceDest);
+ service * pserviceDest);
static void copy_service(service * pserviceDest,
- service * pserviceSource, BOOL *pcopymapDest);
+ service * pserviceSource, BOOL *pcopymapDest);
static BOOL service_ok(int iService);
-static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
-static BOOL do_section(const char *pszSectionName);
+static BOOL do_parameter(char *pszParmName, char *pszParmValue);
+static BOOL do_section(char *pszSectionName);
static void init_copymap(service * pservice);
-/* This is a helper function for parametrical options support. */
-/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
-/* Actual parametrical functions are quite simple */
-static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
-{
- BOOL global_section = False;
- char* param_key;
- param_opt_struct *data;
-
- if (snum >= iNumServices) return NULL;
-
- if (snum < 0) {
- data = Globals.param_opt;
- global_section = True;
- } else {
- data = ServicePtrs[snum]->param_opt;
- }
-
- asprintf(&param_key, "%s:%s", type, option);
- if (!param_key) {
- DEBUG(0,("asprintf failed!\n"));
- return NULL;
- }
-
- while (data) {
- if (strcmp(data->key, param_key) == 0) {
- string_free(&param_key);
- return data;
- }
- data = data->next;
- }
-
- if (!global_section) {
- /* Try to fetch the same option but from globals */
- /* but only if we are not already working with Globals */
- data = Globals.param_opt;
- while (data) {
- if (strcmp(data->key, param_key) == 0) {
- string_free(&param_key);
- return data;
- }
- data = data->next;
- }
- }
-
- string_free(&param_key);
-
- return NULL;
-}
-
-
-/*******************************************************************
-convenience routine to return int parameters.
-********************************************************************/
-static int lp_int(const char *s)
-{
-
- if (!s) {
- DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
- return (-1);
- }
-
- return atoi(s);
-}
-
-/*******************************************************************
-convenience routine to return unsigned long parameters.
-********************************************************************/
-static int lp_ulong(const char *s)
-{
-
- if (!s) {
- DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
- return (-1);
- }
-
- return strtoul(s, NULL, 10);
-}
-
-/*******************************************************************
-convenience routine to return boolean parameters.
-********************************************************************/
-static BOOL lp_bool(const char *s)
-{
- BOOL ret = False;
-
- if (!s) {
- DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
- return False;
- }
-
- if (!set_boolean(&ret,s)) {
- DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
- return False;
- }
-
- return ret;
-}
-
-/*******************************************************************
-convenience routine to return enum parameters.
-********************************************************************/
-static int lp_enum(const char *s,const struct enum_list *_enum)
-{
- int i;
-
- if (!s || !_enum) {
- DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
- return (-1);
- }
-
- for (i=0; _enum[i].name; i++) {
- if (strequal(_enum[i].name,s))
- return _enum[i].value;
- }
-
- DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
- return (-1);
-}
-
-
-/* DO NOT USE lp_parm_string ANYMORE!!!!
- * use lp_parm_const_string or lp_parm_talloc_string
- *
- * lp_parm_string is only used to let old modules find this symbol
- */
-#undef lp_parm_string
- char *lp_parm_string(const char *servicename, const char *type, const char *option)
-{
- return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-/* the returned value is talloced in lp_talloc */
-char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data == NULL||data->value==NULL) {
- if (def) {
- return lp_string(def);
- } else {
- return NULL;
- }
- }
-
- return lp_string(data->value);
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data == NULL||data->value==NULL)
- return def;
-
- return data->value;
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-
-const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data == NULL||data->value==NULL)
- return (const char **)def;
-
- if (data->list==NULL) {
- data->list = str_list_make(data->value, NULL);
- }
-
- return (const char **)data->list;
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-
-int lp_parm_int(int snum, const char *type, const char *option, int def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data && data->value && *data->value)
- return lp_int(data->value);
-
- return def;
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-
-unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data && data->value && *data->value)
- return lp_ulong(data->value);
-
- return def;
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-
-BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data && data->value && *data->value)
- return lp_bool(data->value);
-
- return def;
-}
-
-/* Return parametric option from a given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-
-int lp_parm_enum(int snum, const char *type, const char *option,
- const struct enum_list *_enum, int def)
-{
- param_opt_struct *data = get_parametrics(snum, type, option);
-
- if (data && data->value && *data->value && _enum)
- return lp_enum(data->value, _enum);
-
- return def;
-}
-
/***************************************************************************
- Initialise a service to the defaults.
+initialise a service to the defaults
***************************************************************************/
-
static void init_service(service * pservice)
{
memset((char *)pservice, '\0', sizeof(service));
copy_service(pservice, &sDefault, NULL);
}
+
/***************************************************************************
- Free the dynamically allocated parts of a service struct.
+free the dynamically allocated parts of a service struct
***************************************************************************/
-
-static void free_service(service *pservice)
+static void free_service(service * pservice)
{
int i;
- param_opt_struct *data, *pdata;
if (!pservice)
return;
if (pservice->szService)
- DEBUG(5, ("free_service: Freeing service %s\n",
+ DEBUG(5,
+ ("free_service: Freeing service %s\n",
pservice->szService));
string_free(&pservice->szService);
SAFE_FREE(pservice->copymap);
- for (i = 0; parm_table[i].label; i++) {
+ for (i = 0; parm_table[i].label; i++)
if ((parm_table[i].type == P_STRING ||
parm_table[i].type == P_USTRING) &&
parm_table[i].class == P_LOCAL)
string_free((char **)
(((char *)pservice) +
PTR_DIFF(parm_table[i].ptr, &sDefault)));
- else if (parm_table[i].type == P_LIST &&
- parm_table[i].class == P_LOCAL)
- str_list_free((char ***)
- (((char *)pservice) +
- PTR_DIFF(parm_table[i].ptr, &sDefault)));
- }
-
- data = pservice->param_opt;
- if (data)
- DEBUG(5,("Freeing parametrics:\n"));
- while (data) {
- DEBUG(5,("[%s = %s]\n", data->key, data->value));
- string_free(&data->key);
- string_free(&data->value);
- str_list_free(&data->list);
- pdata = data->next;
- SAFE_FREE(data);
- data = pdata;
- }
ZERO_STRUCTP(pservice);
}
/***************************************************************************
- Add a new service to the services array initialising it with the given
- service.
+add a new service to the services array initialising it with the given
+service. name must be in DOS codepage.
***************************************************************************/
-
-static int add_a_service(const service *pservice, const char *name)
+static int add_a_service(service * pservice, const char *name)
{
int i;
service tservice;
int num_to_alloc = iNumServices + 1;
- param_opt_struct *data, *pdata;
tservice = *pservice;
/* it might already exist */
- if (name) {
+
+ if (name)
+ {
i = getservicebyname(name, NULL);
- if (i >= 0) {
- /* Clean all parametric options for service */
- /* They will be added during parsing again */
- data = ServicePtrs[i]->param_opt;
- while (data) {
- string_free(&data->key);
- string_free(&data->value);
- str_list_free(&data->list);
- pdata = data->next;
- SAFE_FREE(data);
- data = pdata;
- }
- ServicePtrs[i]->param_opt = NULL;
+ if (i >= 0)
return (i);
- }
}
/* find an invalid one */
@@ -2253,29 +1907,43 @@ static int add_a_service(const service *pservice, const char *name)
break;
/* if not, then create one */
- if (i == iNumServices) {
+ if (i == iNumServices)
+ {
service **tsp;
-
+
+#ifdef __INSURE__
+ service **oldservices = iNumServices ? malloc(sizeof(service *) * iNumServices) : NULL;
+
+ if (iNumServices)
+ memcpy(oldservices, ServicePtrs, sizeof(service *) * iNumServices);
+#endif
+
tsp = (service **) Realloc(ServicePtrs,
- sizeof(service *) *
- num_to_alloc);
-
+ sizeof(service *) *
+ num_to_alloc);
+
if (!tsp) {
DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
return (-1);
- }
- else {
+ } else {
ServicePtrs = tsp;
ServicePtrs[iNumServices] =
(service *) malloc(sizeof(service));
+ }
+
+#ifdef __INSURE__
+ if (iNumServices && (memcmp(oldservices, ServicePtrs, sizeof(service *) * iNumServices) != 0)) {
+ smb_panic("add_a_service: Realloc corrupted ptrs...\n");
}
- if (!ServicePtrs[iNumServices]) {
- DEBUG(0,("add_a_service: out of memory!\n"));
+ safe_free(oldservices);
+#endif
+
+ if (!ServicePtrs[iNumServices])
return (-1);
- }
iNumServices++;
- } else
+ }
+ else
free_service(ServicePtrs[i]);
ServicePtrs[i]->valid = True;
@@ -2283,62 +1951,54 @@ static int add_a_service(const service *pservice, const char *name)
init_service(ServicePtrs[i]);
copy_service(ServicePtrs[i], &tservice, NULL);
if (name)
+ {
string_set(&ServicePtrs[i]->szService, name);
+ }
return (i);
}
/***************************************************************************
- Add a new home service, with the specified home directory, defaults coming
- from service ifrom.
+add a new home service, with the specified home directory, defaults coming
+from service ifrom. homename must be in DOS codepage.
***************************************************************************/
-
-BOOL lp_add_home(const char *pszHomename, int iDefaultService,
- const char *user, const char *pszHomedir)
+BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
{
int i;
- pstring newHomedir;
-
+
i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
if (i < 0)
return (False);
- if (!(*(ServicePtrs[iDefaultService]->szPath))
- || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
- pstrcpy(newHomedir, pszHomedir);
- string_set(&ServicePtrs[i]->szPath, newHomedir);
- }
-
- if (!(*(ServicePtrs[i]->comment))) {
+ if (!(*(ServicePtrs[i]->szPath))
+ || strequal(ServicePtrs[i]->szPath, lp_pathname(-1)))
+ string_set(&ServicePtrs[i]->szPath, pszHomedir);
+ if (!(*(ServicePtrs[i]->comment)))
+ {
pstring comment;
slprintf(comment, sizeof(comment) - 1,
- "Home directory of %s", user);
+ "Home directory of %s", pszHomename);
string_set(&ServicePtrs[i]->comment, comment);
}
- /* set the browseable flag from the gloabl default */
-
- ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
+ DEBUG(3,
+ ("adding home directory %s at %s\n", pszHomename, pszHomedir));
- DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
- user, newHomedir));
-
return (True);
}
/***************************************************************************
- Add a new service, based on an old one.
+add a new service, based on an old one. pszService must be in DOS codepage.
***************************************************************************/
-
-int lp_add_service(const char *pszService, int iDefaultService)
+int lp_add_service(char *pszService, int iDefaultService)
{
return (add_a_service(ServicePtrs[iDefaultService], pszService));
}
+
/***************************************************************************
- Add the IPC service.
+add the IPC service
***************************************************************************/
-
static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
{
pstring comment;
@@ -2354,6 +2014,7 @@ static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
string_set(&ServicePtrs[i]->szUsername, "");
string_set(&ServicePtrs[i]->comment, comment);
string_set(&ServicePtrs[i]->fstype, "IPC");
+ ServicePtrs[i]->status = False;
ServicePtrs[i]->iMaxConnections = 0;
ServicePtrs[i]->bAvailable = True;
ServicePtrs[i]->bRead_only = True;
@@ -2362,16 +2023,17 @@ static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
ServicePtrs[i]->bPrint_ok = False;
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
- DEBUG(3, ("adding IPC service\n"));
+ DEBUG(3, ("adding IPC service %s\n", ipc_name));
return (True);
}
+
/***************************************************************************
- Add a new printer service, with defaults coming from service iFrom.
+add a new printer service, with defaults coming from service iFrom.
+printername must be in DOS codepage.
***************************************************************************/
-
-BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
+BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
{
const char *comment = "From Printcap";
int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
@@ -2388,28 +2050,22 @@ BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
string_set(&ServicePtrs[i]->comment, comment);
- /* set the browseable flag from the gloabl default */
- ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
-
/* Printers cannot be read_only. */
ServicePtrs[i]->bRead_only = False;
- /* No share modes on printer services. */
- ServicePtrs[i]->bShareModes = False;
/* No oplocks on printer services. */
ServicePtrs[i]->bOpLocks = False;
/* Printer services must be printable. */
ServicePtrs[i]->bPrint_ok = True;
-
+
DEBUG(3, ("adding printer service %s\n", pszPrintername));
return (True);
}
/***************************************************************************
- Map a parameter's string representation to something we can use.
- Returns False if the parameter string is not recognised, else TRUE.
+Map a parameter's string representation to something we can use.
+Returns False if the parameter string is not recognised, else TRUE.
***************************************************************************/
-
static int map_parameter(const char *pszParmName)
{
int iIndex;
@@ -2421,21 +2077,16 @@ static int map_parameter(const char *pszParmName)
if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
return (iIndex);
- /* Warn only if it isn't parametric option */
- if (strchr(pszParmName, ':') == NULL)
- DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
- /* We do return 'fail' for parametric options as well because they are
- stored in different storage
- */
+ DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
return (-1);
}
+
/***************************************************************************
- Set a boolean variable from the text value stored in the passed string.
- Returns True in success, False if the passed string does not correctly
- represent a boolean.
+Set a boolean variable from the text value stored in the passed string.
+Returns True in success, False if the passed string does not correctly
+represent a boolean.
***************************************************************************/
-
static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
{
BOOL bRetval;
@@ -2445,11 +2096,13 @@ static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
strwicmp(pszParmValue, "true") == 0 ||
strwicmp(pszParmValue, "1") == 0)
*pb = True;
- else if (strwicmp(pszParmValue, "no") == 0 ||
+ else
+ if (strwicmp(pszParmValue, "no") == 0 ||
strwicmp(pszParmValue, "False") == 0 ||
strwicmp(pszParmValue, "0") == 0)
*pb = False;
- else {
+ else
+ {
DEBUG(0,
("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
pszParmValue));
@@ -2461,14 +2114,14 @@ static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
/***************************************************************************
Find a service by name. Otherwise works like get_service.
***************************************************************************/
-
static int getservicebyname(const char *pszServiceName, service * pserviceDest)
{
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
if (VALID(iService) &&
- strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
+ strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0)
+ {
if (pserviceDest != NULL)
copy_service(pserviceDest, ServicePtrs[iService], NULL);
break;
@@ -2477,21 +2130,23 @@ static int getservicebyname(const char *pszServiceName, service * pserviceDest)
return (iService);
}
+
+
/***************************************************************************
- Copy a service structure to another.
- If pcopymapDest is NULL then copy all fields
-***************************************************************************/
+Copy a service structure to another
-static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
+If pcopymapDest is NULL then copy all fields
+***************************************************************************/
+static void copy_service(service * pserviceDest,
+ service * pserviceSource, BOOL *pcopymapDest)
{
int i;
BOOL bcopyall = (pcopymapDest == NULL);
- param_opt_struct *data, *pdata, *paramo;
- BOOL not_added;
for (i = 0; parm_table[i].label; i++)
if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
- (bcopyall || pcopymapDest[i])) {
+ (bcopyall || pcopymapDest[i]))
+ {
void *def_ptr = parm_table[i].ptr;
void *src_ptr =
((char *)pserviceSource) + PTR_DIFF(def_ptr,
@@ -2500,7 +2155,8 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
((char *)pserviceDest) + PTR_DIFF(def_ptr,
&sDefault);
- switch (parm_table[i].type) {
+ switch (parm_table[i].type)
+ {
case P_BOOL:
case P_BOOLREV:
*(BOOL *)dest_ptr = *(BOOL *)src_ptr;
@@ -2524,63 +2180,36 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
case P_USTRING:
string_set(dest_ptr,
*(char **)src_ptr);
- strupper_m(*(char **)dest_ptr);
- break;
- case P_LIST:
- str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
+ strupper(*(char **)dest_ptr);
break;
default:
break;
}
}
- if (bcopyall) {
+ if (bcopyall)
+ {
init_copymap(pserviceDest);
if (pserviceSource->copymap)
memcpy((void *)pserviceDest->copymap,
(void *)pserviceSource->copymap,
sizeof(BOOL) * NUMPARAMETERS);
}
-
- data = pserviceSource->param_opt;
- while (data) {
- not_added = True;
- pdata = pserviceDest->param_opt;
- /* Traverse destination */
- while (pdata) {
- /* If we already have same option, override it */
- if (strcmp(pdata->key, data->key) == 0) {
- string_free(&pdata->value);
- str_list_free(&data->list);
- pdata->value = strdup(data->value);
- not_added = False;
- break;
- }
- pdata = pdata->next;
- }
- if (not_added) {
- paramo = smb_xmalloc(sizeof(param_opt_struct));
- paramo->key = strdup(data->key);
- paramo->value = strdup(data->value);
- paramo->list = NULL;
- DLIST_ADD(pserviceDest->param_opt, paramo);
- }
- data = data->next;
- }
}
/***************************************************************************
Check a service for consistency. Return False if the service is in any way
incomplete or faulty, else True.
***************************************************************************/
-
static BOOL service_ok(int iService)
{
BOOL bRetval;
bRetval = True;
- if (ServicePtrs[iService]->szService[0] == '\0') {
- DEBUG(0, ("The following message indicates an internal error:\n"));
+ if (ServicePtrs[iService]->szService[0] == '\0')
+ {
+ DEBUG(0,
+ ("The following message indicates an internal error:\n"));
DEBUG(0, ("No service name in service entry.\n"));
bRetval = False;
}
@@ -2589,7 +2218,8 @@ static BOOL service_ok(int iService)
/* I can't see why you'd want a non-printable printer service... */
if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
if (!ServicePtrs[iService]->bPrint_ok) {
- DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
+ DEBUG(0,
+ ("WARNING: [%s] service MUST be printable!\n",
ServicePtrs[iService]->szService));
ServicePtrs[iService]->bPrint_ok = True;
}
@@ -2599,8 +2229,10 @@ static BOOL service_ok(int iService)
}
if (ServicePtrs[iService]->szPath[0] == '\0' &&
- strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
- DEBUG(0, ("No path in service %s - using %s\n",
+ strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0)
+ {
+ DEBUG(0,
+ ("No path in service %s - using %s\n",
ServicePtrs[iService]->szService, tmpdir()));
string_set(&ServicePtrs[iService]->szPath, tmpdir());
}
@@ -2613,7 +2245,8 @@ static BOOL service_ok(int iService)
return (bRetval);
}
-static struct file_lists {
+static struct file_lists
+{
struct file_lists *next;
char *name;
char *subfname;
@@ -2621,20 +2254,19 @@ static struct file_lists {
} *file_lists = NULL;
/*******************************************************************
- Keep a linked list of all config files so we know when one has changed
- it's date and needs to be reloaded.
+keep a linked list of all config files so we know when one has changed
+it's date and needs to be reloaded
********************************************************************/
-
static void add_to_file_list(const char *fname, const char *subfname)
{
struct file_lists *f = file_lists;
-
+
while (f) {
if (f->name && !strcmp(f->name, fname))
break;
f = f->next;
}
-
+
if (!f) {
f = (struct file_lists *)malloc(sizeof(file_lists[0]));
if (!f)
@@ -2654,45 +2286,33 @@ static void add_to_file_list(const char *fname, const char *subfname)
f->modtime = file_modtime(subfname);
} else {
time_t t = file_modtime(subfname);
- if (t)
+ if (t)
f->modtime = t;
- }
+ }
}
/*******************************************************************
- Check if a config file has changed date.
+check if a config file has changed date
********************************************************************/
-
BOOL lp_file_list_changed(void)
{
struct file_lists *f = file_lists;
- char *username;
-
- DEBUG(6, ("lp_file_list_changed()\n"));
-
- /* get the username for substituion -- preference to the current_user_info */
- if ( strlen( current_user_info.smb_name ) != 0 )
- username = current_user_info.smb_name;
- else
- username = sub_get_smb_name();
-
-
+ DEBUG(6, ("lp_file_list_changed()\n"));
+
while (f) {
pstring n2;
time_t mod_time;
-
+
pstrcpy(n2, f->name);
- standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
-
+ standard_sub_basic(n2,sizeof(n2));
+
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
- f->name, n2, ctime(&f->modtime)));
-
+ f->name, n2, ctime(&f->modtime)));
+
mod_time = file_modtime(n2);
-
+
if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
- DEBUGADD(6,
- ("file %s modified: %s\n", n2,
- ctime(&mod_time)));
+ DEBUGADD(6, ("file %s modified: %s\n", n2, ctime(&mod_time)));
f->modtime = mod_time;
SAFE_FREE(f->subfname);
f->subfname = strdup(n2);
@@ -2709,69 +2329,219 @@ BOOL lp_file_list_changed(void)
Note: We must *NOT* use string_set() here as ptr points to global_myname.
***************************************************************************/
-static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
{
- BOOL ret;
pstring netbios_name;
pstrcpy(netbios_name, pszParmValue);
- standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
+ standard_sub_basic(netbios_name,sizeof(netbios_name));
+ strupper(netbios_name);
- ret = set_global_myname(netbios_name);
- string_set(&Globals.szNetbiosName,global_myname());
-
- DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
- global_myname()));
+ /*
+ * Convert from UNIX to DOS string - the UNIX to DOS converter
+ * isn't called on the special handlers.
+ */
+ unix_to_dos(netbios_name);
+ pstrcpy(global_myname, netbios_name);
- return ret;
+ DEBUG(4,
+ ("handle_netbios_name: set global_myname to: %s\n",
+ global_myname));
+
+ return (True);
}
-static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
+/***************************************************************************
+ Do the work of sourcing in environment variable/value pairs.
+***************************************************************************/
+
+static BOOL source_env(char **lines)
{
- if (strcmp(*ptr, pszParmValue) != 0) {
- string_set(ptr, pszParmValue);
- init_iconv();
+ char *varval;
+ size_t len;
+ int i;
+ char *p;
+
+ for (i = 0; lines[i]; i++)
+ {
+ char *line = lines[i];
+
+ if ((len = strlen(line)) == 0)
+ continue;
+
+ if (line[len - 1] == '\n')
+ line[--len] = '\0';
+
+ if ((varval = malloc(len + 1)) == NULL)
+ {
+ DEBUG(0, ("source_env: Not enough memory!\n"));
+ return (False);
+ }
+
+ DEBUG(4, ("source_env: Adding to environment: %s\n", line));
+ strncpy(varval, line, len);
+ varval[len] = '\0';
+
+ p = strchr(line, (int)'=');
+ if (p == NULL)
+ {
+ DEBUG(4, ("source_env: missing '=': %s\n", line));
+ continue;
+ }
+
+ if (putenv(varval))
+ {
+ DEBUG(0,
+ ("source_env: Failed to put environment variable %s\n",
+ varval));
+ continue;
+ }
+
+ *p = '\0';
+ p++;
+ DEBUG(4,
+ ("source_env: getting var %s = %s\n", line,
+ getenv(line)));
+ }
+
+ DEBUG(4, ("source_env: returning successfully\n"));
+ return (True);
+}
+
+/***************************************************************************
+ Handle the source environment operation
+***************************************************************************/
+
+static BOOL handle_source_env(const char *pszParmValue, char **ptr)
+{
+ pstring fname;
+ char *p = fname;
+ BOOL result;
+ char **lines;
+
+ pstrcpy(fname, pszParmValue);
+
+ standard_sub_basic(fname,sizeof(fname));
+
+ string_set(ptr, pszParmValue);
+
+ DEBUG(4, ("handle_source_env: checking env type\n"));
+
+ /*
+ * Filename starting with '|' means popen and read from stdin.
+ */
+
+ if (*p == '|')
+ {
+ lines = file_lines_pload(p + 1, NULL, True);
+ }
+ else
+ {
+ lines = file_lines_load(fname, NULL, True);
+ }
+
+ if (!lines)
+ {
+ DEBUG(0,
+ ("handle_source_env: Failed to open file %s, Error was %s\n",
+ fname, strerror(errno)));
+ return (False);
}
+
+ result = source_env(lines);
+ file_lines_free(lines);
+
+ return (result);
+}
+
+/***************************************************************************
+ handle the interpretation of the vfs object parameter
+ *************************************************************************/
+static BOOL handle_vfs_object(const char *pszParmValue, char **ptr)
+{
+ /* Set string value */
+
+ string_set(ptr, pszParmValue);
+
+ /* Do any other initialisation required for vfs. Note that
+ anything done here may have linking repercussions in nmbd. */
+
return True;
}
-static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
+/***************************************************************************
+ handle the interpretation of the coding system parameter
+ *************************************************************************/
+static BOOL handle_coding_system(const char *pszParmValue, char **ptr)
{
- BOOL ret;
-
- ret = set_global_myworkgroup(pszParmValue);
- string_set(&Globals.szWorkgroup,lp_workgroup());
-
- return ret;
+ string_set(ptr, pszParmValue);
+ interpret_coding_system(pszParmValue);
+ return (True);
}
-static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
+/***************************************************************************
+ Handle the interpretation of the character set system parameter.
+***************************************************************************/
+
+static char *saved_character_set = NULL;
+
+static BOOL handle_character_set(const char *pszParmValue, char **ptr)
{
- BOOL ret;
-
- ret = set_global_scope(pszParmValue);
- string_set(&Globals.szNetbiosScope,global_scope());
+ /* A dependency here is that the parameter client code page should be
+ set before this is called.
+ */
+ string_set(ptr, pszParmValue);
+ strupper(*ptr);
+ saved_character_set = strdup(*ptr);
+ interpret_character_set(*ptr, lp_client_code_page());
+ return (True);
+}
- return ret;
+/***************************************************************************
+ Handle the interpretation of the client code page parameter.
+ We handle this separately so that we can reset the character set
+ parameter in case this came before 'client code page' in the smb.conf.
+***************************************************************************/
+
+static BOOL handle_client_code_page(const char *pszParmValue, char **ptr)
+{
+ Globals.client_code_page = atoi(pszParmValue);
+ if (saved_character_set != NULL)
+ interpret_character_set(saved_character_set,
+ lp_client_code_page());
+ codepage_initialise(lp_client_code_page());
+ return (True);
}
-static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
+/***************************************************************************
+handle the valid chars lines
+***************************************************************************/
+
+static BOOL handle_valid_chars(const char *pszParmValue, char **ptr)
{
- Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
- return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
+ string_set(ptr, pszParmValue);
+
+ /* A dependency here is that the parameter client code page must be
+ set before this is called - as calling codepage_initialise()
+ would overwrite the valid char lines.
+ */
+ codepage_initialise(lp_client_code_page());
+
+ add_char_string(pszParmValue);
+ return (True);
}
/***************************************************************************
- Handle the include operation.
+handle the include operation
***************************************************************************/
-static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_include(const char *pszParmValue, char **ptr)
{
pstring fname;
pstrcpy(fname, pszParmValue);
- standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
+ standard_sub_basic(fname,sizeof(fname));
add_to_file_list(pszParmValue, fname);
@@ -2785,11 +2555,11 @@ static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
return (False);
}
+
/***************************************************************************
- Handle the interpretation of the copy parameter.
+handle the interpretation of the copy parameter
***************************************************************************/
-
-static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_copy(const char *pszParmValue, char **ptr)
{
BOOL bRetval;
int iTemp;
@@ -2803,17 +2573,26 @@ static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
DEBUG(3, ("Copying service from service %s\n", pszParmValue));
- if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
- if (iTemp == iServiceIndex) {
- DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
- } else {
+ if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
+ {
+ if (iTemp == iServiceIndex)
+ {
+ DEBUG(0,
+ ("Can't copy service %s - unable to copy self!\n",
+ pszParmValue));
+ }
+ else
+ {
copy_service(ServicePtrs[iServiceIndex],
&serviceTemp,
ServicePtrs[iServiceIndex]->copymap);
bRetval = True;
}
- } else {
- DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
+ }
+ else
+ {
+ DEBUG(0, ("Unable to copy service - source not found: %s\n",
+ pszParmValue));
bRetval = False;
}
@@ -2822,57 +2601,57 @@ static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
}
/***************************************************************************
- Handle idmap/non unix account uid and gid allocation parameters. The format of these
+ Handle winbind uid and gid allocation parameters. The format of these
parameters is:
[global]
- idmap uid = 1000-1999
- idmap gid = 700-899
+ winbind uid = 1000-1999
+ winbind gid = 700-899
We only do simple parsing checks here. The strings are parsed into useful
- structures in the idmap daemon code.
+ structures in the winbind daemon code.
***************************************************************************/
-/* Some lp_ routines to return idmap [ug]id information */
+/* Some lp_ routines to return winbind [ug]id information */
-static uid_t idmap_uid_low, idmap_uid_high;
-static gid_t idmap_gid_low, idmap_gid_high;
+static uid_t winbind_uid_low, winbind_uid_high;
+static gid_t winbind_gid_low, winbind_gid_high;
-BOOL lp_idmap_uid(uid_t *low, uid_t *high)
+BOOL lp_winbind_uid(uid_t *low, uid_t *high)
{
- if (idmap_uid_low == 0 || idmap_uid_high == 0)
+ if (winbind_uid_low == 0 || winbind_uid_high == 0)
return False;
if (low)
- *low = idmap_uid_low;
+ *low = winbind_uid_low;
if (high)
- *high = idmap_uid_high;
+ *high = winbind_uid_high;
return True;
}
-BOOL lp_idmap_gid(gid_t *low, gid_t *high)
+BOOL lp_winbind_gid(gid_t *low, gid_t *high)
{
- if (idmap_gid_low == 0 || idmap_gid_high == 0)
+ if (winbind_gid_low == 0 || winbind_gid_high == 0)
return False;
if (low)
- *low = idmap_gid_low;
+ *low = winbind_gid_low;
if (high)
- *high = idmap_gid_high;
+ *high = winbind_gid_high;
return True;
}
-/* Do some simple checks on "idmap [ug]id" parameter values */
+/* Do some simple checks on "winbind [ug]id" parameter values */
-static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
{
- uint32 low, high;
+ unsigned int low, high;
if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
return False;
@@ -2881,15 +2660,15 @@ static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
string_set(ptr, pszParmValue);
- idmap_uid_low = low;
- idmap_uid_high = high;
+ winbind_uid_low = (uid_t)low;
+ winbind_uid_high = (uid_t)high;
return True;
}
-static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
{
- uint32 low, high;
+ unsigned int low, high;
if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
return False;
@@ -2898,82 +2677,39 @@ static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
string_set(ptr, pszParmValue);
- idmap_gid_low = low;
- idmap_gid_high = high;
+ winbind_gid_low = (gid_t)low;
+ winbind_gid_high = (gid_t)high;
return True;
}
/***************************************************************************
- Handle the DEBUG level list.
+ Handle the WINS SERVER list.
***************************************************************************/
-static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
+static BOOL handle_wins_server_list(const char *pszParmValue, char **ptr )
{
- pstring pszParmValue;
+ if( !wins_srv_load_list( pszParmValue ) )
+ return( False ); /* Parse failed. */
- pstrcpy(pszParmValue, pszParmValueIn);
- string_set(ptr, pszParmValueIn);
- return debug_parse_levels( pszParmValue );
+ string_set( ptr, pszParmValue );
+ return( True );
}
/***************************************************************************
- Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
+ Handle the DEBUG level list.
***************************************************************************/
-static char* append_ldap_suffix( const char *str )
+static BOOL handle_debug_list(const char *pszParmValueIn, char **ptr )
{
- char *suffix_string;
-
-
- if (!lp_talloc)
- lp_talloc = talloc_init("lp_talloc");
-
- suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
- if ( !suffix_string ) {
- DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
- return NULL;
- }
-
- return suffix_string;
-}
-
-char *lp_ldap_machine_suffix(void)
-{
- if (Globals.szLdapMachineSuffix[0])
- return append_ldap_suffix(Globals.szLdapMachineSuffix);
-
- return lp_string(Globals.szLdapSuffix);
-}
-
-char *lp_ldap_user_suffix(void)
-{
- if (Globals.szLdapUserSuffix[0])
- return append_ldap_suffix(Globals.szLdapUserSuffix);
-
- return lp_string(Globals.szLdapSuffix);
-}
-
-char *lp_ldap_group_suffix(void)
-{
- if (Globals.szLdapGroupSuffix[0])
- return append_ldap_suffix(Globals.szLdapGroupSuffix);
-
- return lp_string(Globals.szLdapSuffix);
-}
-
-char *lp_ldap_idmap_suffix(void)
-{
- if (Globals.szLdapIdmapSuffix[0])
- return append_ldap_suffix(Globals.szLdapIdmapSuffix);
+ pstring pszParmValue;
- return lp_string(Globals.szLdapSuffix);
+ pstrcpy(pszParmValue, pszParmValueIn);
+ return debug_parse_levels( pszParmValue );
}
-/***************************************************************************
-***************************************************************************/
-static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **ptr)
+static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
{
if (strequal(pszParmValue, "auto"))
string_set(ptr, "");
@@ -2983,53 +2719,9 @@ static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **
string_set(ptr, "win2k");
else
return False;
-
return True;
}
-/****************************************************************************
- set the value for a P_ENUM
- ***************************************************************************/
-
-static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
- int *ptr )
-{
- int i;
-
- for (i = 0; parm->enum_list[i].name; i++)
- {
- if ( strequal(pszParmValue, parm->enum_list[i].name))
- {
- *ptr = parm->enum_list[i].value;
- break;
- }
- }
-}
-
-/***************************************************************************
-***************************************************************************/
-
-static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
-{
- static int parm_num = -1;
- service *s;
-
- if ( parm_num == -1 )
- parm_num = map_parameter( "printing" );
-
- lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
-
- if ( snum < 0 )
- s = &sDefault;
- else
- s = ServicePtrs[snum];
-
- init_printer_values( s );
-
- return True;
-}
-
-
/***************************************************************************
Initialise a copymap.
***************************************************************************/
@@ -3048,87 +2740,52 @@ static void init_copymap(service * pservice)
pservice->copymap[i] = True;
}
+
/***************************************************************************
- Return the local pointer to a parameter given the service number and the
- pointer into the default structure.
+ return the local pointer to a parameter given the service number and the
+ pointer into the default structure
***************************************************************************/
-
void *lp_local_ptr(int snum, void *ptr)
{
return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
}
/***************************************************************************
- Process a parameter for a particular service number. If snum < 0
- then assume we are in the globals.
+Process a parameter for a particular service number. If snum < 0
+then assume we are in the globals
***************************************************************************/
-
BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
{
- int parmnum, i, slen;
+ int parmnum, i;
void *parm_ptr = NULL; /* where we are going to store the result */
void *def_ptr = NULL;
- pstring param_key;
- char *sep;
- param_opt_struct *paramo, *data;
- BOOL not_added;
parmnum = map_parameter(pszParmName);
- if (parmnum < 0) {
- if ((sep=strchr(pszParmName, ':')) != NULL) {
- *sep = '\0';
- ZERO_STRUCT(param_key);
- pstr_sprintf(param_key, "%s:", pszParmName);
- slen = strlen(param_key);
- pstrcat(param_key, sep+1);
- trim_char(param_key+slen, ' ', ' ');
- not_added = True;
- data = (snum < 0) ? Globals.param_opt :
- ServicePtrs[snum]->param_opt;
- /* Traverse destination */
- while (data) {
- /* If we already have same option, override it */
- if (strcmp(data->key, param_key) == 0) {
- string_free(&data->value);
- str_list_free(&data->list);
- data->value = strdup(pszParmValue);
- not_added = False;
- break;
- }
- data = data->next;
- }
- if (not_added) {
- paramo = smb_xmalloc(sizeof(param_opt_struct));
- paramo->key = strdup(param_key);
- paramo->value = strdup(pszParmValue);
- paramo->list = NULL;
- if (snum < 0) {
- DLIST_ADD(Globals.param_opt, paramo);
- } else {
- DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
- }
- }
-
- *sep = ':';
- return (True);
- }
- DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
+ if (parmnum < 0)
+ {
+ DEBUG(0,
+ ("Ignoring unknown parameter \"%s\"\n", pszParmName));
return (True);
}
- if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
- DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
+ if (parm_table[parmnum].flags & FLAG_DEPRECATED)
+ {
+ DEBUG(0, ("WARNING: The \"%s\"option is deprecated\n",
pszParmName));
}
def_ptr = parm_table[parmnum].ptr;
/* we might point at a service, the default service or a global */
- if (snum < 0) {
+ if (snum < 0)
+ {
parm_ptr = def_ptr;
- } else {
- if (parm_table[parmnum].class == P_GLOBAL) {
+ }
+ else
+ {
+ if (parm_table[parmnum].class == P_GLOBAL)
+ {
DEBUG(0,
("Global parameter %s found in service section!\n",
pszParmName));
@@ -3139,7 +2796,8 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
&sDefault);
}
- if (snum >= 0) {
+ if (snum >= 0)
+ {
if (!ServicePtrs[snum]->copymap)
init_copymap(ServicePtrs[snum]);
@@ -3151,8 +2809,9 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
}
/* if it is a special case then go ahead */
- if (parm_table[parmnum].special) {
- parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
+ if (parm_table[parmnum].special)
+ {
+ parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
return (True);
}
@@ -3180,44 +2839,59 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
sscanf(pszParmValue, "%o", (int *)parm_ptr);
break;
- case P_LIST:
- str_list_free(parm_ptr);
- *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
- break;
-
case P_STRING:
string_set(parm_ptr, pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos(*(char **)parm_ptr);
break;
case P_USTRING:
string_set(parm_ptr, pszParmValue);
- strupper_m(*(char **)parm_ptr);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos(*(char **)parm_ptr);
+ strupper(*(char **)parm_ptr);
break;
case P_GSTRING:
pstrcpy((char *)parm_ptr, pszParmValue);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos((char *)parm_ptr);
break;
case P_UGSTRING:
pstrcpy((char *)parm_ptr, pszParmValue);
- strupper_m((char *)parm_ptr);
+ if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+ unix_to_dos((char *)parm_ptr);
+ strupper((char *)parm_ptr);
break;
case P_ENUM:
- lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
+ for (i = 0; parm_table[parmnum].enum_list[i].name;
+ i++)
+ {
+ if (strequal
+ (pszParmValue,
+ parm_table[parmnum].enum_list[i].name))
+ {
+ *(int *)parm_ptr =
+ parm_table[parmnum].
+ enum_list[i].value;
+ break;
+ }
+ }
break;
case P_SEP:
break;
}
+
return (True);
}
/***************************************************************************
- Process a parameter.
+Process a parameter.
***************************************************************************/
-
-static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
+static BOOL do_parameter(char *pszParmName, char *pszParmValue)
{
if (!bInGlobalSection && bGlobalOnly)
return (True);
@@ -3228,18 +2902,20 @@ static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
pszParmName, pszParmValue));
}
+
/***************************************************************************
- Print a parameter of the specified type.
+print a parameter of the specified type
***************************************************************************/
-
-static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
+static void print_parameter(struct parm_struct *p, void *ptr, FILE * f, char *(*dos_to_ext)(const char *))
{
int i;
switch (p->type)
{
case P_ENUM:
- for (i = 0; p->enum_list[i].name; i++) {
- if (*(int *)ptr == p->enum_list[i].value) {
+ for (i = 0; p->enum_list[i].name; i++)
+ {
+ if (*(int *)ptr == p->enum_list[i].value)
+ {
fprintf(f, "%s",
p->enum_list[i].name);
break;
@@ -3257,6 +2933,12 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
case P_INTEGER:
fprintf(f, "%d", *(int *)ptr);
+ if (strequal(p->label,"log level")) {
+ for (i = 1; i < DBGC_LAST; i ++) {
+ if (((int *)ptr)[i])
+ fprintf(f, ",%s:%d",debug_classname_from_index(i),((int *)ptr)[i]);
+ }
+ }
break;
case P_CHAR:
@@ -3267,31 +2949,23 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
fprintf(f, "%s", octal_string(*(int *)ptr));
break;
- case P_LIST:
- if ((char ***)ptr && *(char ***)ptr) {
- char **list = *(char ***)ptr;
-
- for (; *list; list++) {
- /* surround strings with whitespace in single quotes */
- if ( strchr_m( *list, ' ' ) )
- fprintf(f, "\'%s\'%s", *list, ((*(list+1))?", ":""));
- else
- fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
- }
- }
- break;
-
case P_GSTRING:
case P_UGSTRING:
if ((char *)ptr) {
- fprintf(f, "%s", (char *)ptr);
+ if (p->flags & FLAG_DOS_STRING)
+ fprintf(f, "%s", dos_to_ext((const char *)ptr));
+ else
+ fprintf(f, "%s", (char *)ptr);
}
break;
case P_STRING:
case P_USTRING:
if (*(char **)ptr) {
- fprintf(f, "%s", *(char **)ptr);
+ if(p->flags & FLAG_DOS_STRING)
+ fprintf(f,"%s",dos_to_ext((const char *)*(const char **)ptr));
+ else
+ fprintf(f, "%s", *(char **)ptr);
}
break;
case P_SEP:
@@ -3299,13 +2973,14 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
}
}
+
/***************************************************************************
- Check if two parameters are equal.
+check if two parameters are equal
***************************************************************************/
-
static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
{
- switch (type) {
+ switch (type)
+ {
case P_BOOL:
case P_BOOLREV:
return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
@@ -3317,9 +2992,6 @@ static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
case P_CHAR:
return (*((char *)ptr1) == *((char *)ptr2));
-
- case P_LIST:
- return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
case P_GSTRING:
case P_UGSTRING:
@@ -3357,12 +3029,11 @@ void init_locals(void)
}
/***************************************************************************
- Process a new section (service). At this stage all sections are services.
- Later we'll have special sections that permit server parameters to be set.
- Returns True on success, False on failure.
+Process a new section (service). At this stage all sections are services.
+Later we'll have special sections that permit server parameters to be set.
+Returns True on success, False on failure. SectionName must be in DOS codepage.
***************************************************************************/
-
-static BOOL do_section(const char *pszSectionName)
+static BOOL do_section(char *pszSectionName)
{
BOOL bRetval;
BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
@@ -3377,7 +3048,8 @@ static BOOL do_section(const char *pszSectionName)
bInGlobalSection = isglobal;
/* check for multiple global sections */
- if (bInGlobalSection) {
+ if (bInGlobalSection)
+ {
DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
return (True);
}
@@ -3392,13 +3064,15 @@ static BOOL do_section(const char *pszSectionName)
bRetval = service_ok(iServiceIndex);
/* if all is still well, move to the next record in the services array */
- if (bRetval) {
+ if (bRetval)
+ {
/* We put this here to avoid an odd message order if messages are */
/* issued by the post-processing of a previous section. */
DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
- < 0) {
+ < 0)
+ {
DEBUG(0, ("Failed to add a new service\n"));
return (False);
}
@@ -3409,17 +3083,14 @@ static BOOL do_section(const char *pszSectionName)
/***************************************************************************
- Determine if a partcular base parameter is currentl set to the default value.
+determine if a partcular base parameter is currently set to the default value.
***************************************************************************/
-
static BOOL is_default(int i)
{
if (!defaults_saved)
return False;
- switch (parm_table[i].type) {
- case P_LIST:
- return str_list_compare (parm_table[i].def.lvalue,
- *(char ***)parm_table[i].ptr);
+ switch (parm_table[i].type)
+ {
case P_STRING:
case P_USTRING:
return strequal(parm_table[i].def.svalue,
@@ -3446,41 +3117,31 @@ static BOOL is_default(int i)
return False;
}
+
/***************************************************************************
Display the contents of the global structure.
***************************************************************************/
-
-static void dump_globals(FILE *f)
+static void dump_globals(FILE *f, char *(*dos_to_ext)(const char *))
{
int i;
- param_opt_struct *data;
-
fprintf(f, "# Global parameters\n[global]\n");
for (i = 0; parm_table[i].label; i++)
if (parm_table[i].class == P_GLOBAL &&
parm_table[i].ptr &&
- (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
+ (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
+ {
if (defaults_saved && is_default(i))
continue;
fprintf(f, "\t%s = ", parm_table[i].label);
- print_parameter(&parm_table[i], parm_table[i].ptr, f);
+ print_parameter(&parm_table[i], parm_table[i].ptr, f, dos_to_ext);
fprintf(f, "\n");
- }
- if (Globals.param_opt != NULL) {
- data = Globals.param_opt;
- while(data) {
- fprintf(f, "\t%s = %s\n", data->key, data->value);
- data = data->next;
}
- }
-
}
/***************************************************************************
- Return True if a local parameter is currently set to the global default.
+return True if a local parameter is currently set to the global default
***************************************************************************/
-
BOOL lp_is_default(int snum, struct parm_struct *parm)
{
int pdiff = PTR_DIFF(parm->ptr, &sDefault);
@@ -3490,32 +3151,31 @@ BOOL lp_is_default(int snum, struct parm_struct *parm)
((char *)&sDefault) + pdiff);
}
+
/***************************************************************************
- Display the contents of a single services record.
+Display the contents of a single services record.
***************************************************************************/
-
-static void dump_a_service(service * pService, FILE * f)
+static void dump_a_service(service * pService, FILE * f, char *(*dos_to_ext)(const char *))
{
int i;
- param_opt_struct *data;
-
if (pService != &sDefault)
fprintf(f, "\n[%s]\n", pService->szService);
- for (i = 0; parm_table[i].label; i++) {
-
+ for (i = 0; parm_table[i].label; i++)
if (parm_table[i].class == P_LOCAL &&
parm_table[i].ptr &&
(*parm_table[i].label != '-') &&
- (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
+ (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
{
-
int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
- if (pService == &sDefault) {
+ if (pService == &sDefault)
+ {
if (defaults_saved && is_default(i))
continue;
- } else {
+ }
+ else
+ {
if (equal_parameter(parm_table[i].type,
((char *)pService) +
pdiff,
@@ -3526,31 +3186,24 @@ static void dump_a_service(service * pService, FILE * f)
fprintf(f, "\t%s = ", parm_table[i].label);
print_parameter(&parm_table[i],
- ((char *)pService) + pdiff, f);
+ ((char *)pService) + pdiff, f, dos_to_ext);
fprintf(f, "\n");
}
-
- if (pService->param_opt != NULL) {
- data = pService->param_opt;
- while(data) {
- fprintf(f, "\t%s = %s\n", data->key, data->value);
- data = data->next;
- }
- }
- }
}
/***************************************************************************
- Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
- Return NULL when out of parameters.
-***************************************************************************/
+return info about the next service in a service. snum==-1 gives the globals
+return NULL when out of parameters
+***************************************************************************/
struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
{
- if (snum < 0) {
+ if (snum == -1)
+ {
/* do the globals */
- for (; parm_table[*i].label; (*i)++) {
+ for (; parm_table[*i].label; (*i)++)
+ {
if (parm_table[*i].class == P_SEPARATOR)
return &parm_table[(*i)++];
@@ -3565,10 +3218,13 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
return &parm_table[(*i)++];
}
- } else {
+ }
+ else
+ {
service *pService = ServicePtrs[snum];
- for (; parm_table[*i].label; (*i)++) {
+ for (; parm_table[*i].label; (*i)++)
+ {
if (parm_table[*i].class == P_SEPARATOR)
return &parm_table[(*i)++];
@@ -3602,7 +3258,7 @@ struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
#if 0
/***************************************************************************
- Display the contents of a single copy structure.
+Display the contents of a single copy structure.
***************************************************************************/
static void dump_copy_map(BOOL *pcopymap)
{
@@ -3651,13 +3307,13 @@ static void lp_add_auto_services(char *str)
homes = lp_servicenumber(HOMES_NAME);
for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
- char *home = get_user_home_dir(p);
+ char *home = get_user_service_home_dir(p);
if (lp_servicenumber(p) >= 0)
continue;
if (home && homes >= 0)
- lp_add_home(p, homes, p, home);
+ lp_add_home(p, homes, home);
}
SAFE_FREE(s);
}
@@ -3675,82 +3331,75 @@ void lp_add_one_printer(char *name, char *comment)
lp_add_printer(name, printers);
if ((i = lp_servicenumber(name)) >= 0) {
string_set(&ServicePtrs[i]->comment, comment);
+ unix_to_dos(ServicePtrs[i]->comment);
ServicePtrs[i]->autoloaded = True;
}
}
}
/***************************************************************************
- Have we loaded a services file yet?
+have we loaded a services file yet?
***************************************************************************/
-
BOOL lp_loaded(void)
{
return (bLoaded);
}
/***************************************************************************
- Unload unused services.
+unload unused services
***************************************************************************/
-
void lp_killunused(BOOL (*snumused) (int))
{
int i;
- for (i = 0; i < iNumServices; i++) {
+ for (i = 0; i < iNumServices; i++)
+ {
if (!VALID(i))
continue;
- if (!snumused || !snumused(i)) {
+ if (!snumused || !snumused(i))
+ {
ServicePtrs[i]->valid = False;
free_service(ServicePtrs[i]);
}
}
}
+
/***************************************************************************
- Unload a service.
+unload a service
***************************************************************************/
-
void lp_killservice(int iServiceIn)
{
- if (VALID(iServiceIn)) {
+ if (VALID(iServiceIn))
+ {
ServicePtrs[iServiceIn]->valid = False;
free_service(ServicePtrs[iServiceIn]);
}
}
/***************************************************************************
- Save the curent values of all global and sDefault parameters into the
- defaults union. This allows swat and testparm to show only the
- changed (ie. non-default) parameters.
+save the curent values of all global and sDefault parameters into the
+defaults union. This allows swat and testparm to show only the
+changed (ie. non-default) parameters.
***************************************************************************/
-
static void lp_save_defaults(void)
{
int i;
- for (i = 0; parm_table[i].label; i++) {
+ for (i = 0; parm_table[i].label; i++)
+ {
if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
continue;
- switch (parm_table[i].type) {
- case P_LIST:
- str_list_copy(&(parm_table[i].def.lvalue),
- *(const char ***)parm_table[i].ptr);
- break;
+ switch (parm_table[i].type)
+ {
case P_STRING:
case P_USTRING:
- if (parm_table[i].ptr) {
- parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
- } else {
- parm_table[i].def.svalue = NULL;
- }
+ parm_table[i].def.svalue =
+ strdup(*(char **)parm_table[i].ptr);
break;
case P_GSTRING:
case P_UGSTRING:
- if (parm_table[i].ptr) {
- parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
- } else {
- parm_table[i].def.svalue = NULL;
- }
+ parm_table[i].def.svalue =
+ strdup((char *)parm_table[i].ptr);
break;
case P_BOOL:
case P_BOOLREV:
@@ -3777,7 +3426,6 @@ static void lp_save_defaults(void)
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
-
static void set_server_role(void)
{
server_role = ROLE_STANDALONE;
@@ -3786,107 +3434,55 @@ static void set_server_role(void)
case SEC_SHARE:
if (lp_domain_logons())
DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
+ DEBUG(10,("set_server_role: ROLE_STANDALONE\n"));
break;
case SEC_SERVER:
- if (lp_domain_logons())
- DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
- server_role = ROLE_DOMAIN_MEMBER;
- break;
case SEC_DOMAIN:
if (lp_domain_logons()) {
- DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
server_role = ROLE_DOMAIN_BDC;
+ DEBUG(10,("set_server_role: ROLE_DOMAIN_BDC\n"));
break;
}
server_role = ROLE_DOMAIN_MEMBER;
+ DEBUG(10,("set_server_role: ROLE_DOMAIN_MEMBER\n"));
break;
- case SEC_ADS:
+ case SEC_USER:
if (lp_domain_logons()) {
server_role = ROLE_DOMAIN_PDC;
+ DEBUG(10,("set_server_role: ROLE_DOMAIN_PDC\n"));
break;
}
- server_role = ROLE_DOMAIN_MEMBER;
- break;
- case SEC_USER:
- if (lp_domain_logons()) {
-
- if (Globals.bDomainMaster) /* auto or yes */
- server_role = ROLE_DOMAIN_PDC;
- else
- server_role = ROLE_DOMAIN_BDC;
- }
+ DEBUG(10,("set_server_role: ROLE_STANDALONE\n"));
break;
default:
DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
+ DEBUG(10,("set_server_role: ROLE_STANDALONE\n"));
break;
}
-
- DEBUG(10, ("set_server_role: role = "));
-
- switch(server_role) {
- case ROLE_STANDALONE:
- DEBUGADD(10, ("ROLE_STANDALONE\n"));
- break;
- case ROLE_DOMAIN_MEMBER:
- DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
- break;
- case ROLE_DOMAIN_BDC:
- DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
- break;
- case ROLE_DOMAIN_PDC:
- DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
- break;
- }
}
-/***********************************************************
- If we should send plaintext/LANMAN passwords in the clinet
-************************************************************/
-static void set_allowed_client_auth(void)
-{
- if (Globals.bClientNTLMv2Auth) {
- Globals.bClientLanManAuth = False;
- }
- if (!Globals.bClientLanManAuth) {
- Globals.bClientPlaintextAuth = False;
- }
-}
/***************************************************************************
- Load the services array from the services file. Return True on success,
- False on failure.
+Load the services array from the services file. Return True on success,
+False on failure.
***************************************************************************/
-
BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
BOOL add_ipc)
{
pstring n2;
BOOL bRetval;
- param_opt_struct *data, *pdata;
- char *username;
pstrcpy(n2, pszFname);
-
- /* get the username for substituion -- preference to the current_user_info */
-
- if ( strlen( current_user_info.smb_name ) != 0 )
- username = current_user_info.smb_name;
- else
- username = sub_get_smb_name();
-
- standard_sub_basic( username, n2,sizeof(n2) );
+ standard_sub_basic(n2,sizeof(n2));
add_to_file_list(pszFname, n2);
bRetval = False;
- DEBUG(3, ("lp_load: refreshing parameters\n"));
-
bInGlobalSection = True;
bGlobalOnly = global_only;
init_globals();
- debug_init();
if (save_defaults)
{
@@ -3894,19 +3490,9 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
lp_save_defaults();
}
- if (Globals.param_opt != NULL) {
- data = Globals.param_opt;
- while (data) {
- string_free(&data->key);
- string_free(&data->value);
- str_list_free(&data->list);
- pdata = data->next;
- SAFE_FREE(data);
- data = pdata;
- }
- Globals.param_opt = NULL;
- }
-
+ pstrcpy(n2, pszFname);
+ standard_sub_basic(n2,sizeof(n2));
+
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, do_section, do_parameter);
@@ -3917,53 +3503,43 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
if (iServiceIndex >= 0)
bRetval = service_ok(iServiceIndex);
- if (*(lp_config_backend())) {
- modconf_init(lp_config_backend());
- modconf_load(do_section, do_parameter);
- }
-
lp_add_auto_services(lp_auto_services());
if (add_ipc) {
- /* When 'restrict anonymous = 2' guest connections to ipc$
- are denied */
- lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
+ lp_add_ipc("IPC$", True);
lp_add_ipc("ADMIN$", False);
}
set_server_role();
set_default_server_announce_type();
- set_allowed_client_auth();
bLoaded = True;
/* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
/* if bWINSsupport is true and we are in the client */
- if (in_client && Globals.bWINSsupport) {
- lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
- }
- init_iconv();
-#if 0 /* JERRY */
- init_printer_values(&sDefault);
-#endif
+ if (in_client && Globals.bWINSsupport)
+ {
+
+ string_set(&Globals.szWINSserver, "127.0.0.1");
+
+ }
return (bRetval);
}
+
/***************************************************************************
- Reset the max number of services.
+reset the max number of services
***************************************************************************/
-
void lp_resetnumservices(void)
{
iNumServices = 0;
}
/***************************************************************************
- Return the max number of services.
+return the max number of services
***************************************************************************/
-
int lp_numservices(void)
{
return (iNumServices);
@@ -3972,73 +3548,72 @@ int lp_numservices(void)
/***************************************************************************
Display the contents of the services array in human-readable form.
***************************************************************************/
-
-void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
+void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint, char *(*dos_to_ext)(const char *))
{
int iService;
if (show_defaults)
+ {
defaults_saved = False;
+ }
- dump_globals(f);
+ dump_globals(f, dos_to_ext);
- dump_a_service(&sDefault, f);
+ dump_a_service(&sDefault, f, dos_to_ext);
for (iService = 0; iService < maxtoprint; iService++)
- lp_dump_one(f, show_defaults, iService);
+ lp_dump_one(f, show_defaults, iService, dos_to_ext);
}
/***************************************************************************
Display the contents of one service in human-readable form.
***************************************************************************/
-
-void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
+void lp_dump_one(FILE * f, BOOL show_defaults, int snum, char *(*dos_to_ext)(const char *))
{
- if (VALID(snum)) {
+ if (VALID(snum))
+ {
if (ServicePtrs[snum]->szService[0] == '\0')
return;
- dump_a_service(ServicePtrs[snum], f);
+ dump_a_service(ServicePtrs[snum], f, dos_to_ext);
}
}
+
/***************************************************************************
Return the number of the service with the given name, or -1 if it doesn't
exist. Note that this is a DIFFERENT ANIMAL from the internal function
getservicebyname()! This works ONLY if all services have been loaded, and
does not copy the found service.
***************************************************************************/
-
int lp_servicenumber(const char *pszServiceName)
{
int iService;
- fstring serviceName;
-
- if (!pszServiceName)
- return GLOBAL_SECTION_SNUM;
-
- for (iService = iNumServices - 1; iService >= 0; iService--) {
- if (VALID(iService) && ServicePtrs[iService]->szService) {
+ fstring serviceName;
+
+
+ for (iService = iNumServices - 1; iService >= 0; iService--)
+ {
+ if (VALID(iService) && ServicePtrs[iService]->szService)
+ {
/*
- * The substitution here is used to support %U is
+ * The substitution here is used to support %U is
* service names
*/
fstrcpy(serviceName, ServicePtrs[iService]->szService);
- standard_sub_basic(current_user_info.smb_name, serviceName,sizeof(serviceName));
+ standard_sub_basic(serviceName,sizeof(serviceName));
if (strequal(serviceName, pszServiceName))
break;
}
}
- if (iService < 0) {
+ if (iService < 0)
DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
- return GLOBAL_SECTION_SNUM;
- }
return (iService);
}
/*******************************************************************
- A useful volume label function.
+ A useful volume label function. Returns a string in DOS codepage.
********************************************************************/
char *volume_label(int snum)
@@ -4053,56 +3628,75 @@ char *volume_label(int snum)
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
-
static void set_default_server_announce_type(void)
{
default_server_announce = 0;
default_server_announce |= SV_TYPE_WORKSTATION;
default_server_announce |= SV_TYPE_SERVER;
default_server_announce |= SV_TYPE_SERVER_UNIX;
-
- /* note that the flag should be set only if we have a
- printer service but nmbd doesn't actually load the
- services so we can't tell --jerry */
-
default_server_announce |= SV_TYPE_PRINTQ_SERVER;
- switch (lp_announce_as()) {
+ switch (lp_announce_as())
+ {
case ANNOUNCE_AS_NT_SERVER:
+ {
default_server_announce |= SV_TYPE_SERVER_NT;
/* fall through... */
+ }
case ANNOUNCE_AS_NT_WORKSTATION:
+ {
default_server_announce |= SV_TYPE_NT;
break;
+ }
case ANNOUNCE_AS_WIN95:
+ {
default_server_announce |= SV_TYPE_WIN95_PLUS;
break;
+ }
case ANNOUNCE_AS_WFW:
+ {
default_server_announce |= SV_TYPE_WFW;
break;
+ }
default:
+ {
break;
+ }
}
- switch (lp_server_role()) {
+ switch (lp_server_role())
+ {
case ROLE_DOMAIN_MEMBER:
+ {
default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
break;
+ }
case ROLE_DOMAIN_PDC:
+ {
default_server_announce |= SV_TYPE_DOMAIN_CTRL;
break;
+ }
case ROLE_DOMAIN_BDC:
+ {
default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
break;
+ }
case ROLE_STANDALONE:
default:
+ {
break;
+ }
}
+
if (lp_time_server())
+ {
default_server_announce |= SV_TYPE_TIME_SOURCE;
+ }
if (lp_host_msdfs())
+ {
default_server_announce |= SV_TYPE_DFS_SERVER;
+ }
}
/***********************************************************
@@ -4121,7 +3715,9 @@ int lp_server_role(void)
BOOL lp_domain_master(void)
{
if (Globals.bDomainMaster == Auto)
+ {
return (lp_server_role() == ROLE_DOMAIN_PDC);
+ }
return Globals.bDomainMaster;
}
@@ -4133,31 +3729,35 @@ BOOL lp_domain_master(void)
BOOL lp_preferred_master(void)
{
if (Globals.bPreferredMaster == Auto)
+ {
return (lp_local_master() && lp_domain_master());
+ }
return Globals.bPreferredMaster;
}
+
+
/*******************************************************************
- Remove a service.
+remove a service
********************************************************************/
-
void lp_remove_service(int snum)
{
ServicePtrs[snum]->valid = False;
}
/*******************************************************************
- Copy a service.
+copy a service. new_name must be in dos codepage
********************************************************************/
-
-void lp_copy_service(int snum, const char *new_name)
+void lp_copy_service(int snum, char *new_name)
{
+ char *oldname = lp_servicename(snum);
do_section(new_name);
- if (snum >= 0) {
+ if (snum >= 0)
+ {
snum = lp_servicenumber(new_name);
if (snum >= 0)
- lp_do_parameter(snum, "copy", lp_servicename(snum));
+ lp_do_parameter(snum, "copy", oldname);
}
}
@@ -4165,7 +3765,6 @@ void lp_copy_service(int snum, const char *new_name)
/*******************************************************************
Get the default server type we will announce as via nmbd.
********************************************************************/
-
int lp_default_server_announce(void)
{
return default_server_announce;
@@ -4174,7 +3773,6 @@ int lp_default_server_announce(void)
/*******************************************************************
Split the announce version into major and minor numbers.
********************************************************************/
-
int lp_major_announce_version(void)
{
static BOOL got_major = False;
@@ -4189,7 +3787,7 @@ int lp_major_announce_version(void)
if ((vers = lp_announce_version()) == NULL)
return major_version;
- if ((p = strchr_m(vers, '.')) == 0)
+ if ((p = strchr(vers, '.')) == 0)
return major_version;
*p = '\0';
@@ -4211,7 +3809,7 @@ int lp_minor_announce_version(void)
if ((vers = lp_announce_version()) == NULL)
return minor_version;
- if ((p = strchr_m(vers, '.')) == 0)
+ if ((p = strchr(vers, '.')) == 0)
return minor_version;
p++;
@@ -4223,28 +3821,39 @@ int lp_minor_announce_version(void)
Set the global name resolution order (used in smbclient).
************************************************************/
-void lp_set_name_resolve_order(const char *new_order)
+void lp_set_name_resolve_order(char *new_order)
{
- string_set(&Globals.szNameResolveOrder, new_order);
+ Globals.szNameResolveOrder = new_order;
}
-const char *lp_printername(int snum)
+char *lp_printername(int snum)
{
- const char *ret = _lp_printername(snum);
+ char *ret = _lp_printername(snum);
if (ret == NULL || (ret != NULL && *ret == '\0'))
- ret = lp_const_servicename(snum);
+ ret = lp_servicename(snum);
return ret;
}
+/***********************************************************
+ Return a pointer to the private directory (containing
+ smbpasswd etc.).
+************************************************************/
-/****************************************************************
- Compatibility fn. for 2.2.2 code.....
-*****************************************************************/
-
-void get_private_directory(pstring privdir)
+void get_private_directory(pstring priv_dir)
{
- pstrcpy (privdir, lp_private_dir());
+ char *p;
+
+ *priv_dir = 0;
+
+#ifdef WITH_TDB_SAM
+ pstrcpy(priv_dir, lp_tdb_passwd_file());
+#else
+ pstrcpy(priv_dir, lp_smb_passwd_file());
+#endif
+
+ p = strrchr(priv_dir, '/');
+ if (p) *p = 0;
}
/***********************************************************
@@ -4253,12 +3862,13 @@ void get_private_directory(pstring privdir)
void lp_set_logfile(const char *name)
{
+ extern pstring debugf;
string_set(&Globals.szLogFile, name);
pstrcpy(debugf, name);
}
/*******************************************************************
- Return the NetBIOS called name, or my IP - but never global_myname().
+ Return the NetBIOS called name.
********************************************************************/
const char *get_called_name(void)
@@ -4266,11 +3876,22 @@ const char *get_called_name(void)
extern fstring local_machine;
static fstring called_name;
- if (!*local_machine) {
- fstrcpy(called_name, get_my_primary_ip());
- DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
- called_name));
- return called_name;
+ if (! *local_machine)
+ return global_myname;
+
+ /*
+ * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
+ * arrggg!!! but we've already rewritten the client's
+ * netbios name at this point...
+ */
+
+ if (*local_machine) {
+ if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) {
+ fstrcpy(called_name, get_my_primary_ip());
+ DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
+ called_name));
+ return called_name;
+ }
}
return local_machine;
@@ -4288,12 +3909,3 @@ int lp_maxprintjobs(int snum)
return maxjobs;
}
-
-/*******************************************************************
- Ensure we don't use sendfile if server smb signing is active.
-********************************************************************/
-
-BOOL lp_use_sendfile(int snum)
-{
- return (_lp_use_sendfile(snum) && !srv_is_signing_active());
-}
diff --git a/source/param/modconf.c b/source/param/modconf.c
deleted file mode 100644
index a9ab6f9b4a2..00000000000
--- a/source/param/modconf.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Configuration Modules Support
- Copyright (C) Simo Sorce 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-struct modconf_struct {
- char *name;
- struct config_functions *fns;
-};
-
-static struct modconf_struct module;
-
-NTSTATUS smb_register_config(int version, const char *name, struct config_functions *fns)
-{
- if ((version != SAMBA_CONFIG_INTERFACE_VERSION)) {
- DEBUG(0, ("smb_register_config: Failed to register config module.\n"
- "The module has been compiled with a different interface version (%d).\n"
- "The supported version is: %d\n",
- version, SAMBA_CONFIG_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !name[0]) {
- DEBUG(0,("smb_register_config: Name missing!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- module.name = smb_xstrdup(name);
- module.fns = fns;
- DEBUG(5, ("smb_register_config: Successfully registeres config backend '%s'\n", name));
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- * Init the configuration module
- *********************************************************************/
-
-BOOL modconf_init(const char *config_backend)
-{
- NTSTATUS ret;
- BOOL bret = False;
- char *name;
- char *params;
-
- /* nothing to do */
- if (!config_backend)
- return True;
-
- name = smb_xstrdup(config_backend);
- if ((params = strchr(name, ':')) != NULL ) {
- *params = '\0';
- params++;
- }
-
- ret = smb_probe_module("config", name);
-
- if (NT_STATUS_IS_OK(ret) && NT_STATUS_IS_OK(module.fns->init(params)))
- bret = True;
-
- SAFE_FREE(name);
- return bret;
-}
-
-BOOL modconf_load(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *))
-{
- if (module.fns) {
- if (NT_STATUS_IS_OK(module.fns->load(sfunc, pfunc))) {
- return True;
- }
- }
- return False;
-}
-
-NTSTATUS modconf_close(void)
-{
- return module.fns->close();
-}
diff --git a/source/param/params.c b/source/param/params.c
index 892e5476cc0..495dd7cf71a 100644
--- a/source/param/params.c
+++ b/source/param/params.c
@@ -191,17 +191,31 @@ static int EatComment( myFILE *InFile )
*
*****************************************************************************/
-static int Continuation(char *line, int pos )
+static int Continuation( char *line, int pos )
{
- pos--;
- while( (pos >= 0) && isspace((int)line[pos]))
- pos--;
-
- return (((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
+ int pos2 = 0;
+
+ pos--;
+ while( (pos >= 0) && isspace((int)line[pos]) )
+ pos--;
+
+ /* we should recognize if `\` is part of a multibyte character or not. */
+ while(pos2 <= pos) {
+ size_t skip = 0;
+ skip = get_character_len(line[pos2]);
+ if (skip) {
+ pos2 += skip;
+ } else if (pos == pos2) {
+ return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
+ } else {
+ pos2++;
+ }
+ }
+ return (-1);
}
-static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *) )
+static BOOL Section( myFILE *InFile, BOOL (*sfunc)(char *) )
/* ------------------------------------------------------------------------ **
* Scan a section name, and pass the name to function sfunc().
*
@@ -237,7 +251,7 @@ static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *) )
if( i > (bSize - 2) )
{
char *tb;
-
+
tb = Realloc( bufr, bSize +BUFR_INC );
if( NULL == tb )
{
@@ -258,7 +272,7 @@ static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *) )
DEBUG(0, ("%s Empty section name in configuration file.\n", func ));
return( False );
}
- if( !sfunc(bufr) ) /* Got a valid name. Deal with it. */
+ if( !sfunc( unix_to_dos(bufr) ) ) /* Got a valid name. Deal with it. */
return( False );
(void)EatComment( InFile ); /* Finish off the line. */
return( True );
@@ -297,7 +311,7 @@ static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *) )
return( False );
} /* Section */
-static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *), int c )
+static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(char *, char *), int c )
/* ------------------------------------------------------------------------ **
* Scan a parameter name and value, and pass these two fields to pfunc().
*
@@ -334,7 +348,7 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *)
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
{
char *tb;
-
+
tb = Realloc( bufr, bSize + BUFR_INC );
if( NULL == tb )
{
@@ -401,16 +415,13 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *)
if( i > (bSize - 2) ) /* Make sure there's enough room. */
{
- char *tb;
-
- tb = Realloc( bufr, bSize + BUFR_INC );
- if( NULL == tb )
+ bSize += BUFR_INC;
+ bufr = Realloc( bufr, bSize );
+ if( NULL == bufr )
{
DEBUG(0, ("%s Memory re-allocation failure.", func) );
return( False );
}
- bufr = tb;
- bSize += BUFR_INC;
}
switch( c )
@@ -445,8 +456,8 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *)
} /* Parameter */
static BOOL Parse( myFILE *InFile,
- BOOL (*sfunc)(const char *),
- BOOL (*pfunc)(const char *, const char *) )
+ BOOL (*sfunc)(char *),
+ BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
* Scan & parse the input.
*
@@ -505,7 +516,7 @@ static BOOL Parse( myFILE *InFile,
return( True );
} /* Parse */
-static myFILE *OpenConfFile( const char *FileName )
+static myFILE *OpenConfFile( char *FileName )
/* ------------------------------------------------------------------------ **
* Open a configuration file.
*
@@ -538,9 +549,9 @@ static myFILE *OpenConfFile( const char *FileName )
return( ret );
} /* OpenConfFile */
-BOOL pm_process( const char *FileName,
- BOOL (*sfunc)(const char *),
- BOOL (*pfunc)(const char *, const char *) )
+BOOL pm_process( char *FileName,
+ BOOL (*sfunc)(char *),
+ BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
* Process the named parameter file.
*
diff --git a/source/parsing.doc b/source/parsing.doc
new file mode 100755
index 00000000000..d26a64ae4e8
--- /dev/null
+++ b/source/parsing.doc
@@ -0,0 +1,363 @@
+Chris Hertel, Samba Team
+November 1997
+
+This is a quick overview of the lexical analysis, syntax, and semantics
+of the smb.conf file.
+
+Lexical Analysis:
+
+ Basically, the file is processed on a line by line basis. There are
+ four types of lines that are recognized by the lexical analyzer
+ (params.c):
+
+ Blank lines - Lines containing only whitespace.
+ Comment lines - Lines beginning with either a semi-colon or a
+ pound sign (';' or '#').
+ Section header lines - Lines beginning with an open square bracket
+ ('[').
+ Parameter lines - Lines beginning with any other character.
+ (The default line type.)
+
+ The first two are handled exclusively by the lexical analyzer, which
+ ignores them. The latter two line types are scanned for
+
+ - Section names
+ - Parameter names
+ - Parameter values
+
+ These are the only tokens passed to the parameter loader
+ (loadparm.c). Parameter names and values are divided from one
+ another by an equal sign: '='.
+
+
+ Handling of Whitespace:
+
+ Whitespace is defined as all characters recognized by the isspace()
+ function (see ctype(3C)) except for the newline character ('\n')
+ The newline is excluded because it identifies the end of the line.
+
+ - The lexical analyzer scans past white space at the beginning of a
+ line.
+
+ - Section and parameter names may contain internal white space. All
+ whitespace within a name is compressed to a single space character.
+
+ - Internal whitespace within a parameter value is kept verbatim with
+ the exception of carriage return characters ('\r'), all of which
+ are removed.
+
+ - Leading and trailing whitespace is removed from names and values.
+
+
+ Handling of Line Continuation:
+
+ Long section header and parameter lines may be extended across
+ multiple lines by use of the backslash character ('\\'). Line
+ continuation is ignored for blank and comment lines.
+
+ If the last (non-whitespace) character within a section header or on
+ a parameter line is a backslash, then the next line will be
+ (logically) concatonated with the current line by the lexical
+ analyzer. For example:
+
+ param name = parameter value string \
+ with line continuation.
+
+ Would be read as
+
+ param name = parameter value string with line continuation.
+
+ Note that there are five spaces following the word 'string',
+ representing the one space between 'string' and '\\' in the top
+ line, plus the four preceeding the word 'with' in the second line.
+ (Yes, I'm counting the indentation.)
+
+ Line continuation characters are ignored on blank lines and at the end
+ of comments. They are *only* recognized within section and parameter
+ lines.
+
+
+ Line Continuation Quirks:
+
+ Note the following example:
+
+ param name = parameter value string \
+ \
+ with line continuation.
+
+ The middle line is *not* parsed as a blank line because it is first
+ concatonated with the top line. The result is
+
+ param name = parameter value string with line continuation.
+
+ The same is true for comment lines.
+
+ param name = parameter value string \
+ ; comment \
+ with a comment.
+
+ This becomes:
+
+ param name = parameter value string ; comment with a comment.
+
+ On a section header line, the closing bracket (']') is considered a
+ terminating character, and the rest of the line is ignored. The lines
+
+ [ section name ] garbage \
+ param name = value
+
+ are read as
+
+ [section name]
+ param name = value
+
+
+
+Syntax:
+
+ The syntax of the smb.conf file is as follows:
+
+ <file> :== { <section> } EOF
+
+ <section> :== <section header> { <parameter line> }
+
+ <section header> :== '[' NAME ']'
+
+ <parameter line> :== NAME '=' VALUE NL
+
+
+ Basically, this means that
+
+ - a file is made up of zero or more sections, and is terminated by
+ an EOF (we knew that).
+
+ - A section is made up of a section header followed by zero or more
+ parameter lines.
+
+ - A section header is identified by an opening bracket and
+ terminated by the closing bracket. The enclosed NAME identifies
+ the section.
+
+ - A parameter line is divided into a NAME and a VALUE. The *first*
+ equal sign on the line separates the NAME from the VALUE. The
+ VALUE is terminated by a newline character (NL = '\n').
+
+
+About params.c:
+
+ The parsing of the config file is a bit unusual if you are used to
+ lex, yacc, bison, etc. Both lexical analysis (scanning) and parsing
+ are performed by params.c. Values are loaded via callbacks to
+ loadparm.c.
+
+--------------------------------------------------------------------------
+
+ Samba DEBUG
+
+Chris Hertel, Samba Team
+July, 1998
+
+ Here's the scoop on the update to the DEBUG() system.
+
+ First, my goals are:
+ * Backward compatibility (ie., I don't want to break any Samba code
+ that already works).
+ * Debug output should be timestamped and easy to read (format-wise).
+ * Debug output should be parsable by software.
+ * There should be convenient tools for composing debug messages.
+
+ NOTE: the Debug functionality has been moved from util.c to the new
+ debug.c module.
+
+New Output Syntax
+
+ The syntax of a debugging log file is represented as:
+ <debugfile> :== { <debugmsg> }
+
+ <debugmsg> :== <debughdr> '\n' <debugtext>
+
+ <debughdr> :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')'
+
+ <debugtext> :== { <debugline> }
+
+ <debugline> :== TEXT '\n'
+
+ TEXT is a string of characters excluding the newline character.
+ LEVEL is the DEBUG level of the message (an integer in the range
+ 0..10).
+ TIME is a timestamp.
+ FILE is the name of the file from which the debug message was
+ generated.
+ FUNCTION is the function from which the debug message was generated.
+ LINE is the line number of the debug statement that generated the
+ message.
+
+ Basically, what that all means is:
+ * A debugging log file is made up of debug messages.
+ * Each debug message is made up of a header and text. The header is
+ separated from the text by a newline.
+ * The header begins with the timestamp and debug level of the
+ message enclosed in brackets. The filename, function, and line
+ number at which the message was generated follow. The filename is
+ terminated by a colon, and the function name is terminated by the
+ parenthesis which contain the line number. Depending upon the
+ compiler, the function name may be missing (it is generated by the
+ __FUNCTION__ macro, which is not universally implemented, dangit).
+ * The message text is made up of zero or more lines, each terminated
+ by a newline.
+
+ Here's some example output:
+
+ [1998/08/03 12:55:25, 1] nmbd.c:(659)
+ Netbios nameserver version 1.9.19-prealpha started.
+ Copyright Andrew Tridgell 1994-1997
+ [1998/08/03 12:55:25, 3] loadparm.c:(763)
+ Initializing global parameters
+
+ Note that in the above example the function names are not listed on
+ the header line. That's because the example above was generated on an
+ SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro.
+
+The DEBUG() Macro
+
+ Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
+ The first is the message level, the second is the body of a function
+ call to the Debug1() function.
+
+ That's confusing.
+
+ Here's an example which may help a bit. If you would write
+
+ printf( "This is a %s message.\n", "debug" );
+
+ to send the output to stdout, then you would write
+
+ DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
+
+ to send the output to the debug file. All of the normal printf()
+ formatting escapes work.
+
+ Note that in the above example the DEBUG message level is set to 0.
+ Messages at level 0 always print. Basically, if the message level is
+ less than or equal to the global value DEBUGLEVEL, then the DEBUG
+ statement is processed.
+
+ The output of the above example would be something like:
+
+ [1998/07/30 16:00:51, 0] file.c:function(128)
+ This is a debug message.
+
+ Each call to DEBUG() creates a new header *unless* the output produced
+ by the previous call to DEBUG() did not end with a '\n'. Output to the
+ debug file is passed through a formatting buffer which is flushed
+ every time a newline is encountered. If the buffer is not empty when
+ DEBUG() is called, the new input is simply appended.
+
+ ...but that's really just a Kludge. It was put in place because
+ DEBUG() has been used to write partial lines. Here's a simple (dumb)
+ example of the kind of thing I'm talking about:
+
+ DEBUG( 0, ("The test returned " ) );
+ if( test() )
+ DEBUG(0, ("True") );
+ else
+ DEBUG(0, ("False") );
+ DEBUG(0, (".\n") );
+
+ Without the format buffer, the output (assuming test() returned true)
+ would look like this:
+
+ [1998/07/30 16:00:51, 0] file.c:function(256)
+ The test returned
+ [1998/07/30 16:00:51, 0] file.c:function(258)
+ True
+ [1998/07/30 16:00:51, 0] file.c:function(261)
+ .
+
+ Which isn't much use. The format buffer kludge fixes this problem.
+
+The DEBUGADD() Macro
+
+ In addition to the kludgey solution to the broken line problem
+ described above, there is a clean solution. The DEBUGADD() macro never
+ generates a header. It will append new text to the current debug
+ message even if the format buffer is empty. The syntax of the
+ DEBUGADD() macro is the same as that of the DEBUG() macro.
+
+ DEBUG( 0, ("This is the first line.\n" ) );
+ DEBUGADD( 0, ("This is the second line.\nThis is the third line.\n" ) );
+
+ Produces
+ [1998/07/30 16:00:51, 0] file.c:function(512)
+ This is the first line.
+ This is the second line.
+ This is the third line.
+
+The DEBUGLVL() Macro
+
+ One of the problems with the DEBUG() macro was that DEBUG() lines
+ tended to get a bit long. Consider this example from
+ nmbd_sendannounce.c:
+
+ DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
+ type, global_myname, subrec->subnet_name, work->work_group));
+
+ One solution to this is to break it down using DEBUG() and DEBUGADD(),
+ as follows:
+
+ DEBUG( 3, ( "send_local_master_announcement: " ) );
+ DEBUGADD( 3, ( "type %x for name %s ", type, global_myname ) );
+ DEBUGADD( 3, ( "on subnet %s ", subrec->subnet_name ) );
+ DEBUGADD( 3, ( "for workgroup %s\n", work->work_group ) );
+
+ A similar, but arguably nicer approach is to use the DEBUGLVL() macro.
+ This macro returns True if the message level is less than or equal to
+ the global DEBUGLEVEL value, so:
+
+ if( DEBUGLVL( 3 ) )
+ {
+ dbgtext( "send_local_master_announcement: " );
+ dbgtext( "type %x for name %s ", type, global_myname );
+ dbgtext( "on subnet %s ", subrec->subnet_name );
+ dbgtext( "for workgroup %s\n", work->work_group );
+ }
+
+ (The dbgtext() function is explained below.)
+
+ There are a few advantages to this scheme:
+ * The test is performed only once.
+ * You can allocate variables off of the stack that will only be used
+ within the DEBUGLVL() block.
+ * Processing that is only relevant to debug output can be contained
+ within the DEBUGLVL() block.
+
+New Functions
+
+ dbgtext()
+ This function prints debug message text to the debug file (and
+ possibly to syslog) via the format buffer. The function uses a
+ variable argument list just like printf() or Debug1(). The
+ input is printed into a buffer using the vslprintf() function,
+ and then passed to format_debug_text().
+
+ If you use DEBUGLVL() you will probably print the body of the
+ message using dbgtext().
+
+ dbghdr()
+ This is the function that writes a debug message header.
+ Headers are not processed via the format buffer. Also note that
+ if the format buffer is not empty, a call to dbghdr() will not
+ produce any output. See the comments in dbghdr() for more info.
+
+ It is not likely that this function will be called directly. It
+ is used by DEBUG() and DEBUGADD().
+
+ format_debug_text()
+ This is a static function in debug.c. It stores the output text
+ for the body of the message in a buffer until it encounters a
+ newline. When the newline character is found, the buffer is
+ written to the debug file via the Debug1() function, and the
+ buffer is reset. This allows us to add the indentation at the
+ beginning of each line of the message body, and also ensures
+ that the output is written a line at a time (which cleans up
+ syslog output).
diff --git a/source/passdb/login_cache.c b/source/passdb/login_cache.c
deleted file mode 100644
index fc05122ccaf..00000000000
--- a/source/passdb/login_cache.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAM_ACCOUNT local cache for
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2004.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-#define LOGIN_CACHE_FILE "login_cache.tdb"
-
-#define SAM_CACHE_FORMAT "dwwd"
-
-static TDB_CONTEXT *cache;
-
-BOOL login_cache_init(void)
-{
- char* cache_fname = NULL;
-
- /* skip file open if it's already opened */
- if (cache) return True;
-
- asprintf(&cache_fname, "%s/%s", lp_lockdir(), LOGIN_CACHE_FILE);
- if (cache_fname)
- DEBUG(5, ("Opening cache file at %s\n", cache_fname));
- else {
- DEBUG(0, ("Filename allocation failed.\n"));
- return False;
- }
-
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0644);
-
- if (!cache)
- DEBUG(5, ("Attempt to open %s failed.\n", cache_fname));
-
- SAFE_FREE(cache_fname);
-
- return (cache ? True : False);
-}
-
-BOOL login_cache_shutdown(void)
-{
- /* tdb_close routine returns -1 on error */
- if (!cache) return False;
- DEBUG(5, ("Closing cache file\n"));
- return tdb_close(cache) != -1;
-}
-
-/* if we can't read the cache, oh well, no need to return anything */
-LOGIN_CACHE * login_cache_read(SAM_ACCOUNT *sampass)
-{
- TDB_DATA keybuf, databuf;
- LOGIN_CACHE *entry;
-
- if (!login_cache_init())
- return NULL;
-
- keybuf.dptr = strdup(pdb_get_nt_username(sampass));
- if (!keybuf.dptr || !strlen(keybuf.dptr)) {
- SAFE_FREE(keybuf.dptr);
- return NULL;
- }
- keybuf.dsize = strlen(keybuf.dptr) + 1;
-
- DEBUG(7, ("Looking up login cache for user %s\n",
- keybuf.dptr));
- databuf = tdb_fetch(cache, keybuf);
- SAFE_FREE(keybuf.dptr);
-
- if (!(entry = malloc(sizeof(LOGIN_CACHE)))) {
- DEBUG(1, ("Unable to allocate cache entry buffer!\n"));
- SAFE_FREE(databuf.dptr);
- return NULL;
- }
-
- if (tdb_unpack (databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT,
- &entry->entry_timestamp, &entry->acct_ctrl,
- &entry->bad_password_count,
- &entry->bad_password_time) == -1) {
- DEBUG(7, ("No cache entry found\n"));
- SAFE_FREE(databuf.dptr);
- return NULL;
- }
-
- DEBUG(5, ("Found login cache entry: timestamp %12u, flags 0x%x, count %d, time %12u\n",
- (unsigned int)entry->entry_timestamp, entry->acct_ctrl,
- entry->bad_password_count, (unsigned int)entry->bad_password_time));
- return entry;
-}
-
-BOOL login_cache_write(const SAM_ACCOUNT *sampass, LOGIN_CACHE entry)
-{
-
- TDB_DATA keybuf, databuf;
- BOOL ret;
-
- if (!login_cache_init())
- return False;
-
- keybuf.dptr = strdup(pdb_get_nt_username(sampass));
- if (!keybuf.dptr || !strlen(keybuf.dptr)) {
- SAFE_FREE(keybuf.dptr);
- return False;
- }
- keybuf.dsize = strlen(keybuf.dptr) + 1;
-
- entry.entry_timestamp = time(NULL);
-
- databuf.dsize =
- tdb_pack(NULL, 0, SAM_CACHE_FORMAT,
- entry.entry_timestamp,
- entry.acct_ctrl,
- entry.bad_password_count,
- entry.bad_password_time);
- databuf.dptr = malloc(databuf.dsize);
- if (!databuf.dptr) {
- SAFE_FREE(keybuf.dptr);
- return False;
- }
-
- if (tdb_pack(databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT,
- entry.entry_timestamp,
- entry.acct_ctrl,
- entry.bad_password_count,
- entry.bad_password_time)
- != databuf.dsize) {
- SAFE_FREE(keybuf.dptr);
- SAFE_FREE(databuf.dptr);
- return False;
- }
-
- ret = tdb_store(cache, keybuf, databuf, 0);
- SAFE_FREE(keybuf.dptr);
- SAFE_FREE(databuf.dptr);
- return ret == 0;
-}
-
-BOOL login_cache_delentry(const SAM_ACCOUNT *sampass)
-{
- int ret;
- TDB_DATA keybuf;
-
- if (!login_cache_init())
- return False;
-
- keybuf.dptr = strdup(pdb_get_nt_username(sampass));
- if (!keybuf.dptr || !strlen(keybuf.dptr)) {
- SAFE_FREE(keybuf.dptr);
- return False;
- }
- keybuf.dsize = strlen(keybuf.dptr) + 1;
- DEBUG(9, ("About to delete entry for %s\n", keybuf.dptr));
- ret = tdb_delete(cache, keybuf);
- DEBUG(9, ("tdb_delete returned %d\n", ret));
-
- SAFE_FREE(keybuf.dptr);
- return ret == 0;
-}
-
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
deleted file mode 100644
index a365cba0082..00000000000
--- a/source/passdb/lookup_sid.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- uid/user handling
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Gerald (Jerry) Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*****************************************************************
- *THE CANONICAL* convert name to SID function.
- Tries local lookup first - for local domains - then uses winbind.
-*****************************************************************/
-
-BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
-{
- fstring sid;
- BOOL local_lookup = False;
-
- *name_type = SID_NAME_UNKNOWN;
-
- /* If we are looking up a domain user, make sure it is
- for the local machine only */
-
- if (strequal(domain, get_global_sam_name())) {
- if (local_lookup_name(name, psid, name_type)) {
- DEBUG(10,
- ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
- domain, name, sid_to_string(sid,psid),
- sid_type_lookup(*name_type), (unsigned int)*name_type));
- return True;
- }
- } else {
- /* Remote */
- if (winbind_lookup_name(domain, name, psid, name_type)) {
-
- DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
- domain, name, sid_to_string(sid, psid),
- (unsigned int)*name_type));
- return True;
- }
- }
-
- DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
- local_lookup ? "local" : "winbind", domain, name));
-
- return False;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert SID to name function.
- Tries local lookup first - for local sids, then tries winbind.
-*****************************************************************/
-
-BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
-{
- if (!name_type)
- return False;
-
- *name_type = SID_NAME_UNKNOWN;
-
- /* Check if this is our own sid. This should perhaps be done by
- winbind? For the moment handle it here. */
-
- if (sid->num_auths == 5) {
- DOM_SID tmp_sid;
- uint32 rid;
-
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
-
- if (sid_equal(get_global_sam_sid(), &tmp_sid)) {
-
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- local_lookup_sid(sid, name, name_type);
- }
- }
-
- if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
- fstring sid_str;
- DOM_SID tmp_sid;
- uint32 rid;
-
- DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
-
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- lookup_known_rid(&tmp_sid, rid, name, name_type);
- }
- return True;
-}
-
-BOOL sid_to_local_user_name(const DOM_SID *sid, fstring username)
-{
- fstring dom_name;
- fstring name;
- enum SID_NAME_USE type;
-
- if (!sid_check_is_in_our_domain(sid))
- return False;
-
- if (!lookup_sid(sid, dom_name, name, &type))
- return False;
-
- if (type != SID_NAME_USER)
- return False;
-
- fstrcpy(username, name);
- return True;
-}
-
-BOOL sid_to_local_dom_grp_name(const DOM_SID *sid, fstring groupname)
-{
- fstring dom_name;
- fstring name;
- enum SID_NAME_USE type;
-
- if (!sid_check_is_in_our_domain(sid))
- return False;
-
- if (!lookup_sid(sid, dom_name, name, &type))
- return False;
-
- if (type != SID_NAME_DOM_GRP)
- return False;
-
- fstrcpy(groupname, name);
- return True;
-}
-
-
-/*****************************************************************
- Id mapping cache. This is to avoid Winbind mappings already
- seen by smbd to be queried too frequently, keeping winbindd
- busy, and blocking smbd while winbindd is busy with other
- stuff. Written by Michael Steffens <michael.steffens@hp.com>,
- modified to use linked lists by jra.
-*****************************************************************/
-
-#define MAX_UID_SID_CACHE_SIZE 100
-#define TURNOVER_UID_SID_CACHE_SIZE 10
-#define MAX_GID_SID_CACHE_SIZE 100
-#define TURNOVER_GID_SID_CACHE_SIZE 10
-
-static size_t n_uid_sid_cache = 0;
-static size_t n_gid_sid_cache = 0;
-
-static struct uid_sid_cache {
- struct uid_sid_cache *next, *prev;
- uid_t uid;
- DOM_SID sid;
- enum SID_NAME_USE sidtype;
-} *uid_sid_cache_head;
-
-static struct gid_sid_cache {
- struct gid_sid_cache *next, *prev;
- gid_t gid;
- DOM_SID sid;
- enum SID_NAME_USE sidtype;
-} *gid_sid_cache_head;
-
-/*****************************************************************
- Find a SID given a uid.
-*****************************************************************/
-
-static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
-{
- struct uid_sid_cache *pc;
-
- for (pc = uid_sid_cache_head; pc; pc = pc->next) {
- if (pc->uid == uid) {
- fstring sid;
- *psid = pc->sid;
- DEBUG(3,("fetch sid from uid cache %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid)));
- DLIST_PROMOTE(uid_sid_cache_head, pc);
- return True;
- }
- }
- return False;
-}
-
-/*****************************************************************
- Find a uid given a SID.
-*****************************************************************/
-
-static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
-{
- struct uid_sid_cache *pc;
-
- for (pc = uid_sid_cache_head; pc; pc = pc->next) {
- if (sid_compare(&pc->sid, psid) == 0) {
- fstring sid;
- *puid = pc->uid;
- DEBUG(3,("fetch uid from cache %u -> %s\n",
- (unsigned int)*puid, sid_to_string(sid, psid)));
- DLIST_PROMOTE(uid_sid_cache_head, pc);
- return True;
- }
- }
- return False;
-}
-
-/*****************************************************************
- Store uid to SID mapping in cache.
-*****************************************************************/
-
-static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
-{
- struct uid_sid_cache *pc;
-
- if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
- /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
- struct uid_sid_cache *pc_next;
- size_t i;
-
- for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
- ;
- for(; pc; pc = pc_next) {
- pc_next = pc->next;
- DLIST_REMOVE(uid_sid_cache_head,pc);
- SAFE_FREE(pc);
- n_uid_sid_cache--;
- }
- }
-
- pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache));
- if (!pc)
- return;
- pc->uid = uid;
- sid_copy(&pc->sid, psid);
- DLIST_ADD(uid_sid_cache_head, pc);
- n_uid_sid_cache++;
-}
-
-/*****************************************************************
- Find a SID given a gid.
-*****************************************************************/
-
-static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
-{
- struct gid_sid_cache *pc;
-
- for (pc = gid_sid_cache_head; pc; pc = pc->next) {
- if (pc->gid == gid) {
- fstring sid;
- *psid = pc->sid;
- DEBUG(3,("fetch sid from gid cache %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid, psid)));
- DLIST_PROMOTE(gid_sid_cache_head, pc);
- return True;
- }
- }
- return False;
-}
-
-/*****************************************************************
- Find a gid given a SID.
-*****************************************************************/
-
-static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
-{
- struct gid_sid_cache *pc;
-
- for (pc = gid_sid_cache_head; pc; pc = pc->next) {
- if (sid_compare(&pc->sid, psid) == 0) {
- fstring sid;
- *pgid = pc->gid;
- DEBUG(3,("fetch uid from cache %u -> %s\n",
- (unsigned int)*pgid, sid_to_string(sid, psid)));
- DLIST_PROMOTE(gid_sid_cache_head, pc);
- return True;
- }
- }
- return False;
-}
-
-/*****************************************************************
- Store gid to SID mapping in cache.
-*****************************************************************/
-
-static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
-{
- struct gid_sid_cache *pc;
-
- if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
- /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
- struct gid_sid_cache *pc_next;
- size_t i;
-
- for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
- ;
- for(; pc; pc = pc_next) {
- pc_next = pc->next;
- DLIST_REMOVE(gid_sid_cache_head,pc);
- SAFE_FREE(pc);
- n_gid_sid_cache--;
- }
- }
-
- pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache));
- if (!pc)
- return;
- pc->gid = gid;
- sid_copy(&pc->sid, psid);
- DLIST_ADD(gid_sid_cache_head, pc);
- n_gid_sid_cache++;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert uid_t to SID function.
-*****************************************************************/
-
-NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
-{
- fstring sid;
- uid_t low, high;
-
- ZERO_STRUCTP(psid);
-
- if (fetch_sid_from_uid_cache(psid, uid))
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
-
- /* DC's never use winbindd to resolve users outside the
- defined idmap range */
-
- if ( lp_server_role()==ROLE_DOMAIN_MEMBER
- || (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) )
- {
- if (winbind_uid_to_sid(psid, uid)) {
-
- DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid)));
-
- if (psid)
- store_uid_sid_cache(psid, uid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
- }
-
- if (!local_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
-
- store_uid_sid_cache(psid, uid);
- return NT_STATUS_OK;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert gid_t to SID function.
-*****************************************************************/
-
-NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
-{
- fstring sid;
- gid_t low, high;
-
- ZERO_STRUCTP(psid);
-
- if (fetch_sid_from_gid_cache(psid, gid))
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
-
- /* DC's never use winbindd to resolve groups outside the
- defined idmap range */
-
- if ( lp_server_role()==ROLE_DOMAIN_MEMBER
- || (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) )
- {
- if (winbind_gid_to_sid(psid, gid)) {
-
- DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid, psid)));
-
- if (psid)
- store_gid_sid_cache(psid, gid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
- }
-
- if (!local_gid_to_sid(psid, gid)) {
- DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
-
- store_gid_sid_cache(psid, gid);
- return NT_STATUS_OK;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert SID to uid function.
-*****************************************************************/
-
-NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
-{
- fstring dom_name, name, sid_str;
- enum SID_NAME_USE name_type;
-
- if (fetch_uid_from_cache(puid, psid))
- return NT_STATUS_OK;
-
- /* if this is our SID then go straight to a local lookup */
-
- if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) {
- DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n",
- sid_string_static(psid) ));
-
- if ( local_sid_to_uid(puid, psid, &name_type) )
- goto success;
-
- DEBUG(10,("sid_to_uid: local lookup failed\n"));
-
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* If it is not our local domain, only hope is winbindd */
-
- if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
- DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
- sid_string_static(psid) ));
-
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* If winbindd does know the SID, ensure this is a user */
-
- if (name_type != SID_NAME_USER) {
- DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n",
- (unsigned int)name_type ));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* get the uid. Has to work or else we are dead in the water */
-
- if ( !winbind_sid_to_uid(puid, psid) ) {
- DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
- sid_to_string(sid_str, psid) ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-success:
- DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
- (unsigned int)*puid ));
-
- store_uid_sid_cache(psid, *puid);
-
- return NT_STATUS_OK;
-}
-/*****************************************************************
- *THE CANONICAL* convert SID to gid function.
- Group mapping is used for gids that maps to Wellknown SIDs
-*****************************************************************/
-
-NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
-{
- fstring dom_name, name, sid_str;
- enum SID_NAME_USE name_type;
-
- if (fetch_gid_from_cache(pgid, psid))
- return NT_STATUS_OK;
-
- /*
- * First we must look up the name and decide if this is a group sid.
- * Group mapping can deal with foreign SIDs
- */
-
- if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
- sid_to_string(sid_str, psid) ));
-
- if ( local_sid_to_gid(pgid, psid, &name_type) )
- goto success;
-
- DEBUG(10,("sid_to_gid: no one knows this SID\n"));
-
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* winbindd knows it; Ensure this is a group sid */
-
- if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS)
- && (name_type != SID_NAME_WKN_GRP))
- {
- DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
- (unsigned int)name_type ));
-
- /* winbindd is running and knows about this SID. Just the wrong type.
- Don't fallback to a local lookup here */
-
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* winbindd knows it and it is a type of group; sid_to_gid must succeed
- or we are dead in the water */
-
- if ( !winbind_sid_to_gid(pgid, psid) ) {
- DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n",
- sid_to_string(sid_str, psid) ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-success:
- DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
- (unsigned int)*pgid ));
-
- store_gid_sid_cache(psid, *pgid);
-
- return NT_STATUS_OK;
-}
-
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index 47b9e2d487e..d83fe2adc03 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Password and authentication handling
Copyright (C) Jeremy Allison 1996-2002
Copyright (C) Andrew Tridgell 2002
Copyright (C) Gerald (Jerry) Carter 2000
- Copyright (C) Stefan (metze) Metzmacher 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,43 +23,39 @@
#include "includes.h"
-/* NOTE! the global_sam_sid is the SID of our local SAM. This is only
- equal to the domain SID when we are a DC, otherwise its our
- workstation SID */
-static DOM_SID *global_sam_sid=NULL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
/****************************************************************************
- Read a SID from a file. This is for compatibility with the old MACHINE.SID
- style of SID storage
+ Read the machine SID from a file.
****************************************************************************/
-static BOOL read_sid_from_file(const char *fname, DOM_SID *sid)
+
+static BOOL read_sid_from_file(char *fname, DOM_SID *sid)
{
char **lines;
int numlines;
BOOL ret;
- lines = file_lines_load(fname, &numlines);
-
+ lines = file_lines_load(fname, &numlines, False);
+
if (!lines || numlines < 1) {
- if (lines) file_lines_free(lines);
+ if (lines)
+ file_lines_free(lines);
return False;
}
-
+
ret = string_to_sid(sid, lines[0]);
+ if (!ret)
+ DEBUG(0,("read_sid_from_file: Failed to convert machine SID. (%s)\n", lines[0]));
file_lines_free(lines);
return ret;
}
-/*
- generate a random sid - used to build our own sid if we don't have one
-*/
+/****************************************************************************
+ Generate a random sid - used to build our own sid if we don't have one.
+****************************************************************************/
+
static void generate_random_sid(DOM_SID *sid)
{
int i;
- uchar raw_sid_data[12];
+ unsigned char raw_sid_data[12];
memset((char *)sid, '\0', sizeof(*sid));
sid->sid_rev_num = 1;
@@ -73,19 +69,19 @@ static void generate_random_sid(DOM_SID *sid)
}
/****************************************************************************
- Generate the global machine sid.
+ Generate the global machine sid. Look for the MACHINE.SID file first, if
+ not found then look in smb.conf and use it to create the MACHINE.SID file.
+ Note this function will be replaced soon. JRA.
****************************************************************************/
-static DOM_SID *pdb_generate_sam_sid(void)
+BOOL pdb_generate_sam_sid(void)
{
- DOM_SID domain_sid;
char *fname = NULL;
+ extern pstring global_myname;
+ extern fstring global_myworkgroup;
BOOL is_dc = False;
- DOM_SID *sam_sid;
-
- if(!(sam_sid=(DOM_SID *)malloc(sizeof(DOM_SID))))
- return NULL;
-
+ pstring priv_dir;
+
generate_wellknown_sids();
switch (lp_server_role()) {
@@ -98,116 +94,81 @@ static DOM_SID *pdb_generate_sam_sid(void)
break;
}
- if (is_dc) {
- if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
- sid_copy(sam_sid, &domain_sid);
- return sam_sid;
- }
- }
-
- if (secrets_fetch_domain_sid(global_myname(), sam_sid)) {
+ if (secrets_fetch_domain_sid(global_myname, &global_sam_sid)) {
+ DOM_SID domain_sid;
/* We got our sid. If not a pdc/bdc, we're done. */
if (!is_dc)
- return sam_sid;
+ return True;
- if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
+ if (!secrets_fetch_domain_sid(global_myworkgroup, &domain_sid)) {
/* No domain sid and we're a pdc/bdc. Store it */
- if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc.\n"));
- SAFE_FREE(sam_sid);
- return NULL;
+ return False;
}
- return sam_sid;
+ return True;
}
- if (!sid_equal(&domain_sid, sam_sid)) {
+ if (!sid_equal(&domain_sid, &global_sam_sid)) {
- /* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */
+ /* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */
DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n"));
- if (!secrets_store_domain_sid(global_myname(), &domain_sid)) {
- DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID for local sid as PDC/BDC.\n"));
- SAFE_FREE(sam_sid);
- return NULL;
+ if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
+ DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n"));
+ return False;
}
- return sam_sid;
+ return True;
}
- return sam_sid;
-
+ return True;
}
/* check for an old MACHINE.SID file for backwards compatibility */
- asprintf(&fname, "%s/MACHINE.SID", lp_private_dir());
+ get_private_directory(priv_dir);
+ asprintf(&fname, "%s/MACHINE.SID", priv_dir);
- if (read_sid_from_file(fname, sam_sid)) {
+ if (read_sid_from_file(fname, &global_sam_sid)) {
/* remember it for future reference and unlink the old MACHINE.SID */
- if (!secrets_store_domain_sid(global_myname(), sam_sid)) {
+ if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store SID from file.\n"));
SAFE_FREE(fname);
- SAFE_FREE(sam_sid);
- return NULL;
+ return False;
}
unlink(fname);
if (is_dc) {
- if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file.\n"));
SAFE_FREE(fname);
- SAFE_FREE(sam_sid);
- return NULL;
+ return False;
}
}
- /* Stored the old sid from MACHINE.SID successfully.*/
+ /* Stored the old sid from MACHINE.SID successfully.
+ Patch from Stefan "metze" Metzmacher <metze@metzemix.de>*/
SAFE_FREE(fname);
- return sam_sid;
+ return True;
}
SAFE_FREE(fname);
/* we don't have the SID in secrets.tdb, we will need to
- generate one and save it */
- generate_random_sid(sam_sid);
-
- if (!secrets_store_domain_sid(global_myname(), sam_sid)) {
+ generate one and save it */
+ generate_random_sid(&global_sam_sid);
+ DEBUG(10, ("Generated random SID ...\n"));
+ if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store generated machine SID.\n"));
- SAFE_FREE(sam_sid);
- return NULL;
+ return False;
}
if (is_dc) {
- if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID.\n"));
- SAFE_FREE(sam_sid);
- return NULL;
+ return False;
}
}
- return sam_sid;
-}
-
-/* return our global_sam_sid */
-DOM_SID *get_global_sam_sid(void)
-{
- if (global_sam_sid != NULL)
- return global_sam_sid;
-
- /* memory for global_sam_sid is allocated in
- pdb_generate_sam_sid() as needed */
-
- if (!(global_sam_sid = pdb_generate_sam_sid())) {
- smb_panic("Could not generate a machine SID\n");
- }
-
- return global_sam_sid;
-}
-
-/**
- * Force get_global_sam_sid to requery the backends
- */
-void reset_global_sam_sid(void)
-{
- SAFE_FREE(global_sam_sid);
+ return True;
}
diff --git a/source/passdb/pampass.c b/source/passdb/pampass.c
new file mode 100755
index 00000000000..018eae3a07e
--- /dev/null
+++ b/source/passdb/pampass.c
@@ -0,0 +1,892 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.2.
+ PAM Password checking
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) John H Terpsta 1999-2001
+ Copyright (C) Andrew Bartlett 2001
+ Copyright (C) Jeremy Allison 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * This module provides PAM based functions for validation of
+ * username/password pairs, account managment, session and access control.
+ * Note: SMB password checking is done in smbpass.c
+ */
+
+#include "includes.h"
+
+#ifdef WITH_PAM
+
+/*******************************************************************
+ * Handle PAM authentication
+ * - Access, Authentication, Session, Password
+ * Note: See PAM Documentation and refer to local system PAM implementation
+ * which determines what actions/limitations/allowances become affected.
+ *********************************************************************/
+
+#include <security/pam_appl.h>
+
+/*
+ * Structure used to communicate between the conversation function
+ * and the server_login/change password functions.
+ */
+
+struct smb_pam_userdata {
+ const char *PAM_username;
+ const char *PAM_password;
+ const char *PAM_newpassword;
+};
+
+typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr);
+
+/*
+ * Macros to help make life easy
+ */
+#define COPY_STRING(s) (s) ? strdup(s) : NULL
+
+/*******************************************************************
+ PAM error handler.
+ *********************************************************************/
+
+static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl)
+{
+
+ if( pam_error != PAM_SUCCESS) {
+ DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n",
+ msg, pam_strerror(pamh, pam_error)));
+
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+ This function is a sanity check, to make sure that we NEVER report
+ failure as sucess.
+*********************************************************************/
+
+static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
+ char *msg, int dbglvl,
+ NTSTATUS *nt_status)
+{
+ if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
+ return True;
+
+ if (NT_STATUS_IS_OK(*nt_status)) {
+ /* Complain LOUDLY */
+ DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
+error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
+ *nt_status = NT_STATUS_LOGON_FAILURE;
+ }
+ return False;
+}
+
+/*
+ * PAM conversation function
+ * Here we assume (for now, at least) that echo on means login name, and
+ * echo off means password.
+ */
+
+static int smb_pam_conv(int num_msg,
+ const struct pam_message **msg,
+ struct pam_response **resp,
+ void *appdata_ptr)
+{
+ int replies = 0;
+ struct pam_response *reply = NULL;
+ struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr;
+
+ *resp = NULL;
+
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ /*
+ * Apparantly HPUX has a buggy PAM that doesn't support the
+ * appdata_ptr. Fail if this is the case. JRA.
+ */
+
+ if (udp == NULL) {
+ DEBUG(0,("smb_pam_conv: PAM on this system is broken - appdata_ptr == NULL !\n"));
+ return PAM_CONV_ERR;
+ }
+
+ reply = malloc(sizeof(struct pam_response) * num_msg);
+ if (!reply)
+ return PAM_CONV_ERR;
+
+ memset(reply, '\0', sizeof(struct pam_response) * num_msg);
+
+ for (replies = 0; replies < num_msg; replies++) {
+ switch (msg[replies]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(udp->PAM_username);
+ /* PAM frees resp */
+ break;
+
+ case PAM_PROMPT_ECHO_OFF:
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(udp->PAM_password);
+ /* PAM frees resp */
+ break;
+
+ case PAM_TEXT_INFO:
+ /* fall through */
+
+ case PAM_ERROR_MSG:
+ /* ignore it... */
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = NULL;
+ break;
+
+ default:
+ /* Must be an error of some sort... */
+ SAFE_FREE(reply);
+ return PAM_CONV_ERR;
+ }
+ }
+ if (reply)
+ *resp = reply;
+ return PAM_SUCCESS;
+}
+
+/*
+ * PAM password change conversation function
+ * Here we assume (for now, at least) that echo on means login name, and
+ * echo off means password.
+ */
+
+static void special_char_sub(char *buf)
+{
+ all_string_sub(buf, "\\n", "", 0);
+ all_string_sub(buf, "\\r", "", 0);
+ all_string_sub(buf, "\\s", " ", 0);
+ all_string_sub(buf, "\\t", "\t", 0);
+}
+
+static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass)
+{
+ pstring_sub(buf, "%u", username);
+ all_string_sub(buf, "%o", oldpass, sizeof(fstring));
+ all_string_sub(buf, "%n", newpass, sizeof(fstring));
+}
+
+
+struct chat_struct {
+ struct chat_struct *next, *prev;
+ fstring prompt;
+ fstring reply;
+};
+
+/**************************************************************
+ Create a linked list containing chat data.
+***************************************************************/
+
+static struct chat_struct *make_pw_chat(char *p)
+{
+ fstring prompt;
+ fstring reply;
+ struct chat_struct *list = NULL;
+ struct chat_struct *t;
+ struct chat_struct *tmp;
+
+ while (1) {
+ t = (struct chat_struct *)malloc(sizeof(*t));
+ if (!t) {
+ DEBUG(0,("make_pw_chat: malloc failed!\n"));
+ return NULL;
+ }
+
+ ZERO_STRUCTP(t);
+
+ DLIST_ADD_END(list, t, tmp);
+
+ if (!next_token(&p, prompt, NULL, sizeof(fstring)))
+ break;
+
+ if (strequal(prompt,"."))
+ fstrcpy(prompt,"*");
+
+ special_char_sub(prompt);
+ fstrcpy(t->prompt, prompt);
+ strlower(t->prompt);
+ trim_string(t->prompt, " ", " ");
+
+ if (!next_token(&p, reply, NULL, sizeof(fstring)))
+ break;
+
+ if (strequal(reply,"."))
+ fstrcpy(reply,"");
+
+ special_char_sub(reply);
+ fstrcpy(t->reply, reply);
+ strlower(t->reply);
+ trim_string(t->reply, " ", " ");
+
+ }
+ return list;
+}
+
+static void free_pw_chat(struct chat_struct *list)
+{
+ while (list) {
+ struct chat_struct *old_head = list;
+ DLIST_REMOVE(list, list);
+ SAFE_FREE(old_head);
+ }
+}
+
+static int smb_pam_passchange_conv(int num_msg,
+ const struct pam_message **msg,
+ struct pam_response **resp,
+ void *appdata_ptr)
+{
+ int replies = 0;
+ struct pam_response *reply = NULL;
+ fstring current_prompt;
+ fstring current_reply;
+ struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr;
+ struct chat_struct *pw_chat= make_pw_chat(lp_passwd_chat());
+ struct chat_struct *t;
+ BOOL found;
+ *resp = NULL;
+
+ DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg));
+
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ if (pw_chat == NULL)
+ return PAM_CONV_ERR;
+
+ /*
+ * Apparantly HPUX has a buggy PAM that doesn't support the
+ * appdata_ptr. Fail if this is the case. JRA.
+ */
+
+ if (udp == NULL) {
+ DEBUG(0,("smb_pam_passchange_conv: PAM on this system is broken - appdata_ptr == NULL !\n"));
+ free_pw_chat(pw_chat);
+ return PAM_CONV_ERR;
+ }
+
+ reply = malloc(sizeof(struct pam_response) * num_msg);
+ if (!reply) {
+ DEBUG(0,("smb_pam_passchange_conv: malloc for reply failed!\n"));
+ free_pw_chat(pw_chat);
+ return PAM_CONV_ERR;
+ }
+
+ for (replies = 0; replies < num_msg; replies++) {
+ found = False;
+ DEBUG(10,("smb_pam_passchange_conv: Processing message %d\n", replies));
+ switch (msg[replies]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg));
+ fstrcpy(current_prompt, msg[replies]->msg);
+ trim_string(current_prompt, " ", " ");
+ for (t=pw_chat; t; t=t->next) {
+
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: trying to match |%s| to |%s|\n",
+ t->prompt, current_prompt ));
+
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
+ fstrcpy(current_reply, t->reply);
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply));
+ pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actualy sent: %s\n", current_reply));
+#endif
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(current_reply);
+ found = True;
+ break;
+ }
+ }
+ /* PAM frees resp */
+ if (!found) {
+ DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
+ free_pw_chat(pw_chat);
+ SAFE_FREE(reply);
+ return PAM_CONV_ERR;
+ }
+ break;
+
+ case PAM_PROMPT_ECHO_OFF:
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg));
+ fstrcpy(current_prompt, msg[replies]->msg);
+ trim_string(current_prompt, " ", " ");
+ for (t=pw_chat; t; t=t->next) {
+
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: trying to match |%s| to |%s|\n",
+ t->prompt, current_prompt ));
+
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
+ fstrcpy(current_reply, t->reply);
+ DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply));
+ pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(current_reply);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply));
+#endif
+ found = True;
+ break;
+ }
+ }
+ /* PAM frees resp */
+
+ if (!found) {
+ DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
+ free_pw_chat(pw_chat);
+ SAFE_FREE(reply);
+ return PAM_CONV_ERR;
+ }
+ break;
+
+ case PAM_TEXT_INFO:
+ /* fall through */
+
+ case PAM_ERROR_MSG:
+ /* ignore it... */
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = NULL;
+ break;
+
+ default:
+ /* Must be an error of some sort... */
+ free_pw_chat(pw_chat);
+ SAFE_FREE(reply);
+ return PAM_CONV_ERR;
+ }
+ }
+
+ free_pw_chat(pw_chat);
+ if (reply)
+ *resp = reply;
+ return PAM_SUCCESS;
+}
+
+/***************************************************************************
+ Free up a malloced pam_conv struct.
+****************************************************************************/
+
+static void smb_free_pam_conv(struct pam_conv *pconv)
+{
+ if (pconv)
+ SAFE_FREE(pconv->appdata_ptr);
+
+ SAFE_FREE(pconv);
+}
+
+/***************************************************************************
+ Allocate a pam_conv struct.
+****************************************************************************/
+
+static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, const char *user,
+ const char *passwd, const char *newpass)
+{
+ struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv));
+ struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata));
+
+ if (pconv == NULL || udp == NULL) {
+ SAFE_FREE(pconv);
+ SAFE_FREE(udp);
+ return NULL;
+ }
+
+ udp->PAM_username = user;
+ udp->PAM_password = passwd;
+ udp->PAM_newpassword = newpass;
+
+ pconv->conv = smb_pam_conv_fnptr;
+ pconv->appdata_ptr = (void *)udp;
+ return pconv;
+}
+
+/*
+ * PAM Closing out cleanup handler
+ */
+
+static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr)
+{
+ int pam_error;
+
+ smb_free_pam_conv(smb_pam_conv_ptr);
+
+ if( pamh != NULL ) {
+ pam_error = pam_end(pamh, 0);
+ if(smb_pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) {
+ DEBUG(4, ("smb_pam_end: PAM: PAM_END OK.\n"));
+ return True;
+ }
+ }
+ DEBUG(2,("smb_pam_end: PAM: not initialised"));
+ return False;
+}
+
+/*
+ * Start PAM authentication for specified account
+ */
+
+static BOOL smb_pam_start(pam_handle_t **pamh, const char *user, const char *rhost, struct pam_conv *pconv)
+{
+ int pam_error;
+ const char *our_rhost;
+
+ *pamh = (pam_handle_t *)NULL;
+
+ DEBUG(4,("smb_pam_start: PAM: Init user: %s\n", user));
+
+ pam_error = pam_start("samba", user, pconv, pamh);
+ if( !smb_pam_error_handler(*pamh, pam_error, "Init Failed", 0)) {
+ *pamh = (pam_handle_t *)NULL;
+ return False;
+ }
+
+ if (rhost == NULL) {
+ our_rhost = client_name();
+ if (strequal(rhost,"UNKNOWN"))
+ our_rhost = client_addr();
+ } else {
+ our_rhost = rhost;
+ }
+
+#ifdef PAM_RHOST
+ DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", our_rhost));
+ pam_error = pam_set_item(*pamh, PAM_RHOST, our_rhost);
+ if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) {
+ smb_pam_end(*pamh, pconv);
+ *pamh = (pam_handle_t *)NULL;
+ return False;
+ }
+#endif
+#ifdef PAM_TTY
+ DEBUG(4,("smb_pam_start: PAM: setting tty\n"));
+ pam_error = pam_set_item(*pamh, PAM_TTY, "samba");
+ if (!smb_pam_error_handler(*pamh, pam_error, "set tty failed", 0)) {
+ smb_pam_end(*pamh, pconv);
+ *pamh = (pam_handle_t *)NULL;
+ return False;
+ }
+#endif
+ DEBUG(4,("smb_pam_start: PAM: Init passed for user: %s\n", user));
+ return True;
+}
+
+/*
+ * PAM Authentication Handler
+ */
+static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user)
+{
+ int pam_error;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+ /*
+ * To enable debugging set in /etc/pam.d/samba:
+ * auth required /lib/security/pam_pwdb.so nullok shadow audit
+ */
+
+ DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user));
+ pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK);
+ switch( pam_error ){
+ case PAM_AUTH_ERR:
+ DEBUG(2, ("smb_pam_auth: PAM: Athentication Error for user %s\n", user));
+ nt_status = NT_STATUS_WRONG_PASSWORD;
+ break;
+ case PAM_CRED_INSUFFICIENT:
+ DEBUG(2, ("smb_pam_auth: PAM: Insufficient Credentials for user %s\n", user));
+ nt_status = NT_STATUS_INSUFFICIENT_LOGON_INFO;
+ break;
+ case PAM_AUTHINFO_UNAVAIL:
+ DEBUG(2, ("smb_pam_auth: PAM: Authentication Information Unavailable for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ break;
+ case PAM_USER_UNKNOWN:
+ DEBUG(2, ("smb_pam_auth: PAM: Username %s NOT known to Authentication system\n", user));
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ break;
+ case PAM_MAXTRIES:
+ DEBUG(2, ("smb_pam_auth: PAM: One or more authentication modules reports user limit for user %s exceeeded\n", user));
+ nt_status = NT_STATUS_REMOTE_SESSION_LIMIT;
+ break;
+ case PAM_ABORT:
+ DEBUG(0, ("smb_pam_auth: PAM: One or more PAM modules failed to load for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ break;
+ case PAM_SUCCESS:
+ DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user));
+ nt_status = NT_STATUS_OK;
+ break;
+ default:
+ DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ break;
+ }
+
+ smb_pam_nt_status_error_handler(pamh, pam_error, "Authentication Failure", 2, &nt_status);
+ return nt_status;
+}
+
+/*
+ * PAM Account Handler
+ */
+static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user)
+{
+ int pam_error;
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
+
+ DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user));
+ pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */
+ switch( pam_error ) {
+ case PAM_AUTHTOK_EXPIRED:
+ DEBUG(2, ("smb_pam_account: PAM: User %s is valid but password is expired\n", user));
+ nt_status = NT_STATUS_PASSWORD_EXPIRED;
+ break;
+ case PAM_ACCT_EXPIRED:
+ DEBUG(2, ("smb_pam_account: PAM: User %s no longer permitted to access system\n", user));
+ nt_status = NT_STATUS_ACCOUNT_EXPIRED;
+ break;
+ case PAM_AUTH_ERR:
+ DEBUG(2, ("smb_pam_account: PAM: There was an authentication error for user %s\n", user));
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ break;
+ case PAM_PERM_DENIED:
+ DEBUG(0, ("smb_pam_account: PAM: User %s is NOT permitted to access system at this time\n", user));
+ nt_status = NT_STATUS_ACCOUNT_RESTRICTION;
+ break;
+ case PAM_USER_UNKNOWN:
+ DEBUG(0, ("smb_pam_account: PAM: User \"%s\" is NOT known to account management\n", user));
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ break;
+ case PAM_SUCCESS:
+ DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user));
+ nt_status = NT_STATUS_OK;
+ break;
+ default:
+ nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ DEBUG(0, ("smb_pam_account: PAM: UNKNOWN PAM ERROR (%d) during Account Management for User: %s\n", pam_error, user));
+ break;
+ }
+
+ smb_pam_nt_status_error_handler(pamh, pam_error, "Account Check Failed", 2, &nt_status);
+ return nt_status;
+}
+
+/*
+ * PAM Credential Setting
+ */
+
+static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user)
+{
+ int pam_error;
+ NTSTATUS nt_status = NT_STATUS_NO_TOKEN;
+
+ /*
+ * This will allow samba to aquire a kerberos token. And, when
+ * exporting an AFS cell, be able to /write/ to this cell.
+ */
+
+ DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user));
+ pam_error = pam_setcred(pamh, (PAM_ESTABLISH_CRED|PAM_SILENT));
+ switch( pam_error ) {
+ case PAM_CRED_UNAVAIL:
+ DEBUG(0, ("smb_pam_setcred: PAM: Credentials not found for user:%s\n", user ));
+ nt_status = NT_STATUS_NO_TOKEN;
+ break;
+ case PAM_CRED_EXPIRED:
+ DEBUG(0, ("smb_pam_setcred: PAM: Credentials for user: \"%s\" EXPIRED!\n", user ));
+ nt_status = NT_STATUS_PASSWORD_EXPIRED;
+ break;
+ case PAM_USER_UNKNOWN:
+ DEBUG(0, ("smb_pam_setcred: PAM: User: \"%s\" is NOT known so can not set credentials!\n", user ));
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ break;
+ case PAM_CRED_ERR:
+ DEBUG(0, ("smb_pam_setcred: PAM: Unknown setcredentials error - unable to set credentials for %s\n", user ));
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ break;
+ case PAM_SUCCESS:
+ DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user));
+ nt_status = NT_STATUS_OK;
+ break;
+ default:
+ DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user));
+ nt_status = NT_STATUS_NO_TOKEN;
+ break;
+ }
+
+ smb_pam_nt_status_error_handler(pamh, pam_error, "Set Credential Failure", 2, &nt_status);
+ return nt_status;
+}
+
+/*
+ * PAM Internal Session Handler
+ */
+static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag)
+{
+ int pam_error;
+
+#ifdef PAM_TTY
+ DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty));
+ pam_error = pam_set_item(pamh, PAM_TTY, tty);
+ if (!smb_pam_error_handler(pamh, pam_error, "set tty failed", 0))
+ return False;
+#endif
+
+ if (flag) {
+ pam_error = pam_open_session(pamh, PAM_SILENT);
+ if (!smb_pam_error_handler(pamh, pam_error, "session setup failed", 0))
+ return False;
+ } else {
+ pam_setcred(pamh, (PAM_DELETE_CRED|PAM_SILENT)); /* We don't care if this fails */
+ pam_error = pam_close_session(pamh, PAM_SILENT); /* This will probably pick up the error anyway */
+ if (!smb_pam_error_handler(pamh, pam_error, "session close failed", 0))
+ return False;
+ }
+ return (True);
+}
+
+/*
+ * Internal PAM Password Changer.
+ */
+
+static BOOL smb_pam_chauthtok(pam_handle_t *pamh, const char * user)
+{
+ int pam_error;
+
+ DEBUG(4,("smb_pam_chauthtok: PAM: Password Change for User: %s\n", user));
+
+ pam_error = pam_chauthtok(pamh, PAM_SILENT); /* Change Password */
+
+ switch( pam_error ) {
+ case PAM_AUTHTOK_ERR:
+ DEBUG(2, ("PAM: unable to obtain the new authentication token - is password to weak?\n"));
+ break;
+
+ /* This doesn't seem to be defined on Solaris. JRA */
+#ifdef PAM_AUTHTOK_RECOVER_ERR
+ case PAM_AUTHTOK_RECOVER_ERR:
+ DEBUG(2, ("PAM: unable to obtain the old authentication token - was the old password wrong?.\n"));
+ break;
+#endif
+
+ case PAM_AUTHTOK_LOCK_BUSY:
+ DEBUG(2, ("PAM: unable to change the authentication token since it is currently locked.\n"));
+ break;
+ case PAM_AUTHTOK_DISABLE_AGING:
+ DEBUG(2, ("PAM: Authentication token aging has been disabled.\n"));
+ break;
+ case PAM_PERM_DENIED:
+ DEBUG(0, ("PAM: Permission denied.\n"));
+ break;
+ case PAM_TRY_AGAIN:
+ DEBUG(0, ("PAM: Could not update all authentication token(s). No authentication tokens were updated.\n"));
+ break;
+ case PAM_USER_UNKNOWN:
+ DEBUG(0, ("PAM: User not known to PAM\n"));
+ break;
+ case PAM_SUCCESS:
+ DEBUG(4, ("PAM: Account OK for User: %s\n", user));
+ break;
+ default:
+ DEBUG(0, ("PAM: UNKNOWN PAM ERROR (%d) for User: %s\n", pam_error, user));
+ }
+
+ if(!smb_pam_error_handler(pamh, pam_error, "Password Change Failed", 2)) {
+ return False;
+ }
+
+ /* If this point is reached, the password has changed. */
+ return True;
+}
+
+/*
+ * PAM Externally accessible Session handler
+ */
+
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
+{
+ pam_handle_t *pamh = NULL;
+ struct pam_conv *pconv = NULL;
+
+ /* Ignore PAM if told to. */
+
+ if (!lp_obey_pam_restrictions())
+ return True;
+
+ if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
+ return False;
+
+ if (!smb_pam_start(&pamh, user, rhost, pconv))
+ return False;
+
+ if (!smb_internal_pam_session(pamh, user, tty, True)) {
+ smb_pam_end(pamh, pconv);
+ return False;
+ }
+
+ return smb_pam_end(pamh, pconv);
+}
+
+/*
+ * PAM Externally accessible Session handler
+ */
+
+BOOL smb_pam_close_session(char *user, char *tty, char *rhost)
+{
+ pam_handle_t *pamh = NULL;
+ struct pam_conv *pconv = NULL;
+
+ /* Ignore PAM if told to. */
+
+ if (!lp_obey_pam_restrictions())
+ return True;
+
+ if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
+ return False;
+
+ if (!smb_pam_start(&pamh, user, rhost, pconv))
+ return False;
+
+ if (!smb_internal_pam_session(pamh, user, tty, False)) {
+ smb_pam_end(pamh, pconv);
+ return False;
+ }
+
+ return smb_pam_end(pamh, pconv);
+}
+
+/*
+ * PAM Externally accessible Account handler
+ */
+
+NTSTATUS smb_pam_accountcheck(const char * user)
+{
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ pam_handle_t *pamh = NULL;
+ struct pam_conv *pconv = NULL;
+
+ /* Ignore PAM if told to. */
+
+ if (!lp_obey_pam_restrictions())
+ return NT_STATUS_OK;
+
+ if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ if (!smb_pam_start(&pamh, user, NULL, pconv))
+ return NT_STATUS_ACCOUNT_DISABLED;
+
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user)))
+ DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
+
+ smb_pam_end(pamh, pconv);
+ return nt_status;
+}
+
+/*
+ * PAM Password Validation Suite
+ */
+
+NTSTATUS smb_pam_passcheck(char * user, char * password)
+{
+ pam_handle_t *pamh = NULL;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ struct pam_conv *pconv = NULL;
+
+ /*
+ * Note we can't ignore PAM here as this is the only
+ * way of doing auths on plaintext passwords when
+ * compiled --with-pam.
+ */
+
+ if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, password, NULL)) == NULL)
+ return NT_STATUS_LOGON_FAILURE;
+
+ if (!smb_pam_start(&pamh, user, NULL, pconv))
+ return NT_STATUS_LOGON_FAILURE;
+
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_auth(pamh, user))) {
+ DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
+ smb_pam_end(pamh, pconv);
+ return nt_status;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user))) {
+ DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
+ smb_pam_end(pamh, pconv);
+ return nt_status;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_setcred(pamh, user))) {
+ DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
+ smb_pam_end(pamh, pconv);
+ return nt_status;
+ }
+
+ smb_pam_end(pamh, pconv);
+ return nt_status;
+}
+
+/*
+ * PAM Password Change Suite
+ */
+
+BOOL smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword)
+{
+ /* Appropriate quantities of root should be obtained BEFORE calling this function */
+ struct pam_conv *pconv = NULL;
+ pam_handle_t *pamh = NULL;
+
+ if ((pconv = smb_setup_pam_conv(smb_pam_passchange_conv, user, oldpassword, newpassword)) == NULL)
+ return False;
+
+ if(!smb_pam_start(&pamh, user, NULL, pconv))
+ return False;
+
+ if (!smb_pam_chauthtok(pamh, user)) {
+ DEBUG(0, ("smb_pam_passchange: PAM: Password Change Failed for user %s!\n", user));
+ smb_pam_end(pamh, pconv);
+ return False;
+ }
+
+ return smb_pam_end(pamh, pconv);
+}
+
+#else
+
+/* If PAM not used, no PAM restrictions on accounts. */
+NTSTATUS smb_pam_accountcheck(const char * user)
+{
+ return NT_STATUS_OK;
+}
+
+/* If PAM not used, also no PAM restrictions on sessions. */
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
+{
+ return True;
+}
+
+/* If PAM not used, also no PAM restrictions on sessions. */
+BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
+{
+ return True;
+}
+#endif /* WITH_PAM */
diff --git a/source/passdb/pass_check.c b/source/passdb/pass_check.c
new file mode 100755
index 00000000000..2437aa0d53e
--- /dev/null
+++ b/source/passdb/pass_check.c
@@ -0,0 +1,865 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password checking
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* this module is for checking a username/password against a system
+ password database. The SMB encrypted password support is elsewhere */
+
+#include "includes.h"
+
+/* these are kept here to keep the string_combinations function simple */
+static fstring this_user;
+static fstring this_salt;
+static fstring this_crypted;
+
+#ifdef WITH_AFS
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
+/*******************************************************************
+check on AFS authentication
+********************************************************************/
+static BOOL afs_auth(char *user, char *password)
+{
+ long password_expires = 0;
+ char *reason;
+
+ /* For versions of AFS prior to 3.3, this routine has few arguments, */
+ /* but since I can't find the old documentation... :-) */
+ setpag();
+ if (ka_UserAuthenticateGeneral
+ (KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, user, (char *)0, /* instance */
+ (char *)0, /* cell */
+ password, 0, /* lifetime, default */
+ &password_expires, /*days 'til it expires */
+ 0, /* spare 2 */
+ &reason) == 0)
+ {
+ return (True);
+ }
+ DEBUG(1,
+ ("AFS authentication for \"%s\" failed (%s)\n", user, reason));
+ return (False);
+}
+#endif
+
+
+#ifdef WITH_DFS
+
+#include <dce/dce_error.h>
+#include <dce/sec_login.h>
+
+/*****************************************************************
+ This new version of the DFS_AUTH code was donated by Karsten Muuss
+ <muuss@or.uni-bonn.de>. It fixes the following problems with the
+ old code :
+
+ - Server credentials may expire
+ - Client credential cache files have wrong owner
+ - purge_context() function is called with invalid argument
+
+ This new code was modified to ensure that on exit the uid/gid is
+ still root, and the original directory is restored. JRA.
+******************************************************************/
+
+sec_login_handle_t my_dce_sec_context;
+int dcelogin_atmost_once = 0;
+
+/*******************************************************************
+check on a DCE/DFS authentication
+********************************************************************/
+static BOOL dfs_auth(char *user, char *password)
+{
+ error_status_t err;
+ int err2;
+ int prterr;
+ signed32 expire_time, current_time;
+ boolean32 password_reset;
+ struct passwd *pw;
+ sec_passwd_rec_t passwd_rec;
+ sec_login_auth_src_t auth_src = sec_login_auth_src_network;
+ unsigned char dce_errstr[dce_c_error_string_len];
+ gid_t egid;
+
+ if (dcelogin_atmost_once)
+ return (False);
+
+#ifdef HAVE_CRYPT
+ /*
+ * We only go for a DCE login context if the given password
+ * matches that stored in the local password file..
+ * Assumes local passwd file is kept in sync w/ DCE RGY!
+ */
+
+ if (strcmp((char *)crypt(password, this_salt), this_crypted))
+ {
+ return (False);
+ }
+#endif
+
+ sec_login_get_current_context(&my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ sec_login_certify_identity(my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ time(&current_time);
+
+ if (expire_time < (current_time + 60))
+ {
+ struct passwd *pw;
+ sec_passwd_rec_t *key;
+
+ sec_login_get_pwent(my_dce_sec_context,
+ (sec_login_passwd_t *) & pw, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ sec_login_refresh_identity(my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't refresh identity. %s\n",
+ dce_errstr));
+
+ return (False);
+ }
+
+ sec_key_mgmt_get_key(rpc_c_authn_dce_secret, NULL,
+ (unsigned char *)pw->pw_name,
+ sec_c_key_version_none,
+ (void **)&key, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get key for %s. %s\n",
+ pw->pw_name, dce_errstr));
+
+ return (False);
+ }
+
+ sec_login_valid_and_cert_ident(my_dce_sec_context, key,
+ &password_reset, &auth_src,
+ &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0,
+ ("DCE can't validate and certify identity for %s. %s\n",
+ pw->pw_name, dce_errstr));
+ }
+
+ sec_key_mgmt_free_key(key, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't free key.\n", dce_errstr));
+ }
+ }
+
+ if (sec_login_setup_identity((unsigned char *)user,
+ sec_login_no_flags,
+ &my_dce_sec_context, &err) == 0)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",
+ user, dce_errstr));
+ return (False);
+ }
+
+ sec_login_get_pwent(my_dce_sec_context,
+ (sec_login_passwd_t *) & pw, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ sec_login_purge_context(&my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't purge context. %s\n", dce_errstr));
+
+ return (False);
+ }
+
+ /*
+ * NB. I'd like to change these to call something like change_to_user()
+ * instead but currently we don't have a connection
+ * context to become the correct user. This is already
+ * fairly platform specific code however, so I think
+ * this should be ok. I have added code to go
+ * back to being root on error though. JRA.
+ */
+
+ egid = getegid();
+
+ set_effective_gid(pw->pw_gid);
+ set_effective_uid(pw->pw_uid);
+
+ if (sec_login_setup_identity((unsigned char *)user,
+ sec_login_no_flags,
+ &my_dce_sec_context, &err) == 0)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",
+ user, dce_errstr));
+ goto err;
+ }
+
+ sec_login_get_pwent(my_dce_sec_context,
+ (sec_login_passwd_t *) & pw, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
+ goto err;
+ }
+
+ passwd_rec.version_number = sec_passwd_c_version_none;
+ passwd_rec.pepper = NULL;
+ passwd_rec.key.key_type = sec_passwd_plain;
+ passwd_rec.key.tagged_union.plain = (idl_char *) password;
+
+ sec_login_validate_identity(my_dce_sec_context,
+ &passwd_rec, &password_reset,
+ &auth_src, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0,
+ ("DCE Identity Validation failed for principal %s: %s\n",
+ user, dce_errstr));
+ goto err;
+ }
+
+ sec_login_certify_identity(my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE certify identity failed: %s\n", dce_errstr));
+ goto err;
+ }
+
+ if (auth_src != sec_login_auth_src_network)
+ {
+ DEBUG(0, ("DCE context has no network credentials.\n"));
+ }
+
+ sec_login_set_context(my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0,
+ ("DCE login failed for principal %s, cant set context: %s\n",
+ user, dce_errstr));
+
+ sec_login_purge_context(&my_dce_sec_context, &err);
+ goto err;
+ }
+
+ sec_login_get_pwent(my_dce_sec_context,
+ (sec_login_passwd_t *) & pw, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
+ goto err;
+ }
+
+ DEBUG(0, ("DCE login succeeded for principal %s on pid %d\n",
+ user, sys_getpid()));
+
+ DEBUG(3, ("DCE principal: %s\n"
+ " uid: %d\n"
+ " gid: %d\n",
+ pw->pw_name, pw->pw_uid, pw->pw_gid));
+ DEBUG(3, (" info: %s\n"
+ " dir: %s\n"
+ " shell: %s\n",
+ pw->pw_gecos, pw->pw_dir, pw->pw_shell));
+
+ sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));
+ goto err;
+ }
+
+ set_effective_uid(0);
+ set_effective_gid(0);
+
+ DEBUG(0,
+ ("DCE context expires: %s", asctime(localtime(&expire_time))));
+
+ dcelogin_atmost_once = 1;
+ return (True);
+
+ err:
+
+ /* Go back to root, JRA. */
+ set_effective_uid(0);
+ set_effective_gid(egid);
+ return (False);
+}
+
+void dfs_unlogin(void)
+{
+ error_status_t err;
+ int err2;
+ unsigned char dce_errstr[dce_c_error_string_len];
+
+ sec_login_purge_context(&my_dce_sec_context, &err);
+ if (err != error_status_ok)
+ {
+ dce_error_inq_text(err, dce_errstr, &err2);
+ DEBUG(0,
+ ("DCE purge login context failed for server instance %d: %s\n",
+ sys_getpid(), dce_errstr));
+ }
+}
+#endif
+
+#ifdef KRB5_AUTH
+
+#include <krb5.h>
+
+/*******************************************************************
+check on Kerberos authentication
+********************************************************************/
+static BOOL krb5_auth(char *user, char *password)
+{
+ krb5_data tgtname = {
+ 0,
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME
+ };
+ krb5_context kcontext;
+ krb5_principal kprinc;
+ krb5_principal server;
+ krb5_creds kcreds;
+ int options = 0;
+ krb5_address **addrs = (krb5_address **) 0;
+ krb5_preauthtype *preauth = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_timestamp now;
+ krb5_ccache ccache = NULL;
+ int retval;
+ char *name;
+
+ if (retval = krb5_init_context(&kcontext))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_timeofday(kcontext, &now))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_cc_default(kcontext, &ccache))
+ {
+ return (False);
+ }
+
+ if (retval = krb5_parse_name(kcontext, user, &kprinc))
+ {
+ return (False);
+ }
+
+ ZERO_STRUCT(kcreds);
+
+ kcreds.client = kprinc;
+
+ if ((retval = krb5_build_principal_ext(kcontext, &server,
+ krb5_princ_realm(kcontext,
+ kprinc)->
+ length,
+ krb5_princ_realm(kcontext,
+ kprinc)->data,
+ tgtname.length, tgtname.data,
+ krb5_princ_realm(kcontext,
+ kprinc)->
+ length,
+ krb5_princ_realm(kcontext,
+ kprinc)->data,
+ 0)))
+ {
+ return (False);
+ }
+
+ kcreds.server = server;
+
+ retval = krb5_get_in_tkt_with_password(kcontext,
+ options,
+ addrs,
+ NULL,
+ preauth,
+ password, 0, &kcreds, 0);
+
+ if (retval)
+ {
+ return (False);
+ }
+
+ return (True);
+}
+#endif /* KRB5_AUTH */
+
+#ifdef KRB4_AUTH
+#include <krb.h>
+
+/*******************************************************************
+check on Kerberos authentication
+********************************************************************/
+static BOOL krb4_auth(char *user, char *password)
+{
+ char realm[REALM_SZ];
+ char tkfile[MAXPATHLEN];
+
+ if (krb_get_lrealm(realm, 1) != KSUCCESS)
+ {
+ (void)safe_strcpy(realm, KRB_REALM, sizeof(realm) - 1);
+ }
+
+ (void)slprintf(tkfile, sizeof(tkfile) - 1, "/tmp/samba_tkt_%d",
+ (int)sys_getpid());
+
+ krb_set_tkt_string(tkfile);
+ if (krb_verify_user(user, "", realm, password, 0, "rmcd") == KSUCCESS)
+ {
+ unlink(tkfile);
+ return 1;
+ }
+ unlink(tkfile);
+ return 0;
+}
+#endif /* KRB4_AUTH */
+
+#ifdef LINUX_BIGCRYPT
+/****************************************************************************
+an enhanced crypt for Linux to handle password longer than 8 characters
+****************************************************************************/
+static int linux_bigcrypt(char *password, char *salt1, char *crypted)
+{
+#define LINUX_PASSWORD_SEG_CHARS 8
+ char salt[3];
+ int i;
+
+ StrnCpy(salt, salt1, 2);
+ crypted += 2;
+
+ for (i = strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) {
+ char *p = crypt(password, salt) + 2;
+ if (strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0)
+ return (0);
+ password += LINUX_PASSWORD_SEG_CHARS;
+ crypted += strlen(p);
+ }
+
+ return (1);
+}
+#endif
+
+#ifdef OSF1_ENH_SEC
+/****************************************************************************
+an enhanced crypt for OSF1
+****************************************************************************/
+static char *osf1_bigcrypt(char *password, char *salt1)
+{
+ static char result[AUTH_MAX_PASSWD_LENGTH] = "";
+ char *p1;
+ char *p2 = password;
+ char salt[3];
+ int i;
+ int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS;
+ if (strlen(password) % AUTH_CLEARTEXT_SEG_CHARS)
+ parts++;
+
+ StrnCpy(salt, salt1, 2);
+ StrnCpy(result, salt1, 2);
+ result[2] = '\0';
+
+ for (i = 0; i < parts; i++) {
+ p1 = crypt(p2, salt);
+ strncat(result, p1 + 2,
+ AUTH_MAX_PASSWD_LENGTH - strlen(p1 + 2) - 1);
+ StrnCpy(salt, &result[2 + i * AUTH_CIPHERTEXT_SEG_CHARS], 2);
+ p2 += AUTH_CLEARTEXT_SEG_CHARS;
+ }
+
+ return (result);
+}
+#endif
+
+
+/****************************************************************************
+apply a function to upper/lower case combinations
+of a string and return true if one of them returns true.
+try all combinations with N uppercase letters.
+offset is the first char to try and change (start with 0)
+it assumes the string starts lowercased
+****************************************************************************/
+static BOOL string_combinations2(char *s, int offset, BOOL (*fn) (char *),
+ int N)
+{
+ int len = strlen(s);
+ int i;
+
+#ifdef PASSWORD_LENGTH
+ len = MIN(len, PASSWORD_LENGTH);
+#endif
+
+ if (N <= 0 || offset >= len)
+ return (fn(s));
+
+ for (i = offset; i < (len - (N - 1)); i++) {
+ char c = s[i];
+ if (!islower(c))
+ continue;
+ s[i] = toupper(c);
+ if (string_combinations2(s, i + 1, fn, N - 1))
+ return (True);
+ s[i] = c;
+ }
+ return (False);
+}
+
+/****************************************************************************
+apply a function to upper/lower case combinations
+of a string and return true if one of them returns true.
+try all combinations with up to N uppercase letters.
+offset is the first char to try and change (start with 0)
+it assumes the string starts lowercased
+****************************************************************************/
+static BOOL string_combinations(char *s, BOOL (*fn) (char *), int N)
+{
+ int n;
+ for (n = 1; n <= N; n++)
+ if (string_combinations2(s, 0, fn, n))
+ return (True);
+ return (False);
+}
+
+
+/****************************************************************************
+core of password checking routine
+****************************************************************************/
+static BOOL password_check(char *password)
+{
+
+#ifdef WITH_PAM
+ return (NT_STATUS_IS_OK(smb_pam_passcheck(this_user, password)));
+#endif /* WITH_PAM */
+
+#ifdef WITH_AFS
+ if (afs_auth(this_user, password))
+ return (True);
+#endif /* WITH_AFS */
+
+#ifdef WITH_DFS
+ if (dfs_auth(this_user, password))
+ return (True);
+#endif /* WITH_DFS */
+
+#ifdef KRB5_AUTH
+ if (krb5_auth(this_user, password))
+ return (True);
+#endif /* KRB5_AUTH */
+
+#ifdef KRB4_AUTH
+ if (krb4_auth(this_user, password))
+ return (True);
+#endif /* KRB4_AUTH */
+
+#ifdef OSF1_ENH_SEC
+ {
+ BOOL ret =
+ (strcmp
+ (osf1_bigcrypt(password, this_salt),
+ this_crypted) == 0);
+ if (!ret) {
+ DEBUG(2,
+ ("OSF1_ENH_SEC failed. Trying normal crypt.\n"));
+ ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+ }
+ return ret;
+ }
+#endif /* OSF1_ENH_SEC */
+
+#ifdef ULTRIX_AUTH
+ return (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
+#endif /* ULTRIX_AUTH */
+
+#ifdef LINUX_BIGCRYPT
+ return (linux_bigcrypt(password, this_salt, this_crypted));
+#endif /* LINUX_BIGCRYPT */
+
+#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
+
+ /*
+ * Some systems have bigcrypt in the C library but might not
+ * actually use it for the password hashes (HPUX 10.20) is
+ * a noteable example. So we try bigcrypt first, followed
+ * by crypt.
+ */
+
+ if (strcmp(bigcrypt(password, this_salt), this_crypted) == 0)
+ return True;
+ else
+ return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+
+#ifdef HAVE_BIGCRYPT
+ return (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
+#endif /* HAVE_BIGCRYPT */
+
+#ifndef HAVE_CRYPT
+ DEBUG(1, ("Warning - no crypt available\n"));
+ return (False);
+#else /* HAVE_CRYPT */
+ return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+#endif /* HAVE_CRYPT */
+#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+}
+
+
+
+/****************************************************************************
+check if a username/password is OK
+the function pointer fn() points to a function to call when a successful
+match is found and is used to update the encrypted password file
+return True on correct match, False otherwise
+****************************************************************************/
+
+BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
+ BOOL (*fn) (char *, char *))
+{
+ pstring pass2;
+ int level = lp_passwordlevel();
+ struct passwd *pass = NULL;
+
+ if (password)
+ password[pwlen] = 0;
+
+#if DEBUG_PASSWORD
+ DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password));
+#endif
+
+ if (!password)
+ return (False);
+
+ if (((!*password) || (!pwlen)) && !lp_null_passwords())
+ return (False);
+
+ if (pwd && !user) {
+ pass = (struct passwd *)pwd;
+ user = pass->pw_name;
+ } else {
+ pass = Get_Pwnam(user, True);
+ }
+
+#ifdef WITH_PAM
+
+ /*
+ * If we're using PAM we want to short-circuit all the
+ * checks below and dive straight into the PAM code.
+ */
+
+ fstrcpy(this_user, user);
+
+ DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen));
+
+#else /* Not using PAM */
+
+ DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen));
+
+ if (!pass) {
+ DEBUG(3, ("Couldn't find user %s\n", user));
+ return (False);
+ }
+
+#ifdef HAVE_GETSPNAM
+ {
+ struct spwd *spass;
+
+ /* many shadow systems require you to be root to get
+ the password, in most cases this should already be
+ the case when this function is called, except
+ perhaps for IPC password changing requests */
+
+ spass = getspnam(pass->pw_name);
+ if (spass && spass->sp_pwdp)
+ pstrcpy(pass->pw_passwd, spass->sp_pwdp);
+ }
+#elif defined(IA_UINFO)
+ {
+ /* Need to get password with SVR4.2's ia_ functions
+ instead of get{sp,pw}ent functions. Required by
+ UnixWare 2.x, tested on version
+ 2.1. (tangent@cyberport.com) */
+ uinfo_t uinfo;
+ if (ia_openinfo(pass->pw_name, &uinfo) != -1)
+ ia_get_logpwd(uinfo, &(pass->pw_passwd));
+ }
+#endif
+
+#ifdef HAVE_GETPRPWNAM
+ {
+ struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
+ if (pr_pw && pr_pw->ufld.fd_encrypt)
+ pstrcpy(pass->pw_passwd, pr_pw->ufld.fd_encrypt);
+ }
+#endif
+
+#ifdef OSF1_ENH_SEC
+ {
+ struct pr_passwd *mypasswd;
+ DEBUG(5, ("Checking password for user %s in OSF1_ENH_SEC\n",
+ user));
+ mypasswd = getprpwnam(user);
+ if (mypasswd) {
+ fstrcpy(pass->pw_name, mypasswd->ufld.fd_name);
+ fstrcpy(pass->pw_passwd, mypasswd->ufld.fd_encrypt);
+ } else {
+ DEBUG(5,
+ ("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
+ user));
+ }
+ }
+#endif
+
+#ifdef ULTRIX_AUTH
+ {
+ AUTHORIZATION *ap = getauthuid(pass->pw_uid);
+ if (ap) {
+ fstrcpy(pass->pw_passwd, ap->a_password);
+ endauthent();
+ }
+ }
+#endif
+
+ /* extract relevant info */
+ fstrcpy(this_user, pass->pw_name);
+ fstrcpy(this_salt, pass->pw_passwd);
+
+#if defined(HAVE_TRUNCATED_SALT)
+ /* crypt on some platforms (HPUX in particular)
+ won't work with more than 2 salt characters. */
+ this_salt[2] = 0;
+#endif
+
+ fstrcpy(this_crypted, pass->pw_passwd);
+
+ if (!*this_crypted) {
+ if (!lp_null_passwords()) {
+ DEBUG(2, ("Disallowing %s with null password\n",
+ this_user));
+ return (False);
+ }
+ if (!*password) {
+ DEBUG(3,
+ ("Allowing access to %s with null password\n",
+ this_user));
+ return (True);
+ }
+ }
+
+#endif /* WITH_PAM */
+
+ /* try it as it came to us */
+ if (password_check(password)) {
+ if (fn)
+ fn(user, password);
+ return (True);
+ }
+
+ /* if the password was given to us with mixed case then we don't
+ need to proceed as we know it hasn't been case modified by the
+ client */
+ if (strhasupper(password) && strhaslower(password)) {
+ return (False);
+ }
+
+ /* make a copy of it */
+ StrnCpy(pass2, password, sizeof(pstring) - 1);
+
+ /* try all lowercase if it's currently all uppercase */
+ if (strhasupper(password)) {
+ strlower(password);
+ if (password_check(password)) {
+ if (fn)
+ fn(user, password);
+ return (True);
+ }
+ }
+
+ /* give up? */
+ if (level < 1) {
+ /* restore it */
+ fstrcpy(password, pass2);
+ return (False);
+ }
+
+ /* last chance - all combinations of up to level chars upper! */
+ strlower(password);
+
+ if (string_combinations(password, password_check, level)) {
+ if (fn)
+ fn(user, password);
+ return (True);
+ }
+
+ /* restore it */
+ fstrcpy(password, pass2);
+
+ return (False);
+}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index e2e84436029..cf98f78ee28 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -1,11 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Password and authentication handling
Copyright (C) Jeremy Allison 1996-2001
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
- Copyright (C) Andrew Bartlett 2001-2002
- Copyright (C) Simo Sorce 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,296 +23,103 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
+/*
+ * This is set on startup - it defines the SID for this
+ * machine, and therefore the SAM database for which it is
+ * responsible.
+ */
-/******************************************************************
- get the default domain/netbios name to be used when
- testing authentication. For example, if you connect
- to a Windows member server using a bogus domain name, the
- Windows box will map the BOGUS\user to DOMAIN\user. A
- standalone box will map to WKS\user.
-******************************************************************/
+extern DOM_SID global_sam_sid;
-const char *get_default_sam_name(void)
-{
- /* standalone servers can only use the local netbios name */
- if ( lp_server_role() == ROLE_STANDALONE )
- return global_myname();
-
- /* Windows domain members default to the DOMAIN
- name when not specified */
- return lp_workgroup();
-}
-
-/************************************************************
- Fill the SAM_ACCOUNT with default values.
- ***********************************************************/
-
-void pdb_fill_default_sam(SAM_ACCOUNT *user)
-{
- ZERO_STRUCT(user->private); /* Don't touch the talloc context */
-
- /* no initial methods */
- user->methods = NULL;
-
- /* Don't change these timestamp settings without a good reason.
- They are important for NT member server compatibility. */
-
- user->private.logon_time = (time_t)0;
- user->private.pass_last_set_time = (time_t)0;
- user->private.pass_can_change_time = (time_t)0;
- user->private.logoff_time =
- user->private.kickoff_time =
- user->private.pass_must_change_time = get_time_t_max();
- user->private.fields_present = 0x00ffffff;
- user->private.logon_divs = 168; /* hours per week */
- user->private.hours_len = 21; /* 21 times 8 bits = 168 */
- memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
- user->private.bad_password_count = 0;
- user->private.logon_count = 0;
- user->private.unknown_6 = 0x000004ec; /* don't know */
-
- /* Some parts of samba strlen their pdb_get...() returns,
- so this keeps the interface unchanged for now. */
-
- user->private.username = "";
- user->private.domain = "";
- user->private.nt_username = "";
- user->private.full_name = "";
- user->private.home_dir = "";
- user->private.logon_script = "";
- user->private.profile_path = "";
- user->private.acct_desc = "";
- user->private.workstations = "";
- user->private.unknown_str = "";
- user->private.munged_dial = "";
-
- user->private.plaintext_pw = NULL;
-
- /*
- Unless we know otherwise have a Account Control Bit
- value of 'normal user'. This helps User Manager, which
- asks for a filtered list of users.
- */
-
- user->private.acct_ctrl = ACB_NORMAL;
-}
-
-static void destroy_pdb_talloc(SAM_ACCOUNT **user)
-{
- if (*user) {
- data_blob_clear_free(&((*user)->private.lm_pw));
- data_blob_clear_free(&((*user)->private.nt_pw));
-
- if((*user)->private.plaintext_pw!=NULL)
- memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw));
- talloc_destroy((*user)->mem_ctx);
- *user = NULL;
- }
-}
-
-
-/**********************************************************************
- Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
-***********************************************************************/
+struct passdb_ops *pdb_ops;
-NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
-{
- if (*user != NULL) {
- DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
-#if 0
- smb_panic("non-NULL pointer passed to pdb_init_sam\n");
+#if 0 /* JERRY */
+static void* pdb_handle = NULL;
#endif
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!mem_ctx) {
- DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- *user=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(SAM_ACCOUNT));
-
- if (*user==NULL) {
- DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- (*user)->mem_ctx = mem_ctx;
- (*user)->free_fn = NULL;
+/***************************************************************
+ Initialize the password db operations.
+***************************************************************/
- pdb_fill_default_sam(*user);
+BOOL initialize_password_db(BOOL reload)
+{
+ /*
+ * This function is unfinished right now, so just
+ * ignore the details and always return True. It
+ * is here only as a placeholder --jerry
+ */
+ return True;
- return NT_STATUS_OK;
}
-
/*************************************************************
- Allocates memory and initialises a struct sam_passwd.
- ************************************************************/
+ Initialises a struct sam_disp_info.
+ **************************************************************/
-NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
+static void pdb_init_dispinfo(struct sam_disp_info *user)
{
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
-
- mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
-
- if (!mem_ctx) {
- DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
- talloc_destroy(mem_ctx);
- return nt_status;
- }
-
- (*user)->free_fn = destroy_pdb_talloc;
-
- return NT_STATUS_OK;
+ if (user == NULL)
+ return;
+ ZERO_STRUCTP(user);
}
-/**************************************************************************
- * This function will take care of all the steps needed to correctly
- * allocate and set the user SID, please do use this function to create new
- * users, messing with SIDs is not good.
- *
- * account_data must be provided initialized, pwd may be null.
- * SSS
- ***************************************************************************/
-static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
-{
- const char *guest_account = lp_guestaccount();
- GROUP_MAP map;
- BOOL ret;
-
- if (!account_data || !pwd) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* this is a hack this thing should not be set
- this way --SSS */
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- } else {
- /* Ensure this *must* be set right */
- if (strcmp(pwd->pw_name, guest_account) == 0) {
- if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- return NT_STATUS_OK;
- }
- }
+/************************************************************
+ Fill the SAM_ACCOUNT with default values.
+ ***********************************************************/
- if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
- DEBUG(0,("Can't set User SID from RID!\n"));
- return NT_STATUS_INVALID_PARAMETER;
+static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user)
+{
+ if (user == NULL) {
+ DEBUG(0,("pdb_fill_default_sam: SAM_ACCOUNT was NULL\n"));
+ return False;
}
- /* call the mapping code here */
- become_root();
- ret = pdb_getgrgid(&map, pwd->pw_gid);
- unbecome_root();
+ ZERO_STRUCTP(user);
- if( ret ) {
- if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
- DEBUG(0,("Can't set Group SID!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- else {
- if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
- DEBUG(0,("Can't set Group SID\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
+ user->init_flag = FLAG_SAM_UNINIT;
+ user->uid = user->gid = -1;
+ user->logon_time = (time_t)0;
+ user->pass_last_set_time = (time_t)0;
+ user->pass_can_change_time = (time_t)0;
+ user->logoff_time =
+ user->kickoff_time =
+ user->pass_must_change_time = get_time_t_max(); /* Password never expires. */
+
+ user->unknown_3 = 0x00ffffff; /* don't know */
+ user->logon_divs = 168; /* hours per week */
+ user->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+ user->unknown_5 = 0x00000000; /* don't know */
+ user->unknown_6 = 0x000004ec; /* don't know */
+ return True;
+}
- return NT_STATUS_OK;
-}
/*************************************************************
- Initialises a struct sam_passwd with sane values.
+ Alloc memory and initialises a struct sam_passwd.
************************************************************/
-NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
+BOOL pdb_init_sam(SAM_ACCOUNT **user)
{
- NTSTATUS ret;
-
- if (!pwd) {
- return NT_STATUS_UNSUCCESSFUL;
+ if (*user != NULL) {
+ DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n"));
+#if 0
+ smb_panic("NULL pointer passed to pdb_init_sam\n");
+#endif
+ return False;
}
-
- pdb_fill_default_sam(sam_account);
-
- pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
- pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
-
- pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
-
- pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
- /* When we get a proper uid -> SID and SID -> uid allocation
- mechinism, we should call it here.
-
- We can't just set this to 0 or allow it only to be filled
- in when added to the backend, because the user's SID
- may already be in security descriptors etc.
-
- -- abartlet 11-May-02
- */
-
- ret = pdb_set_sam_sids(sam_account, pwd);
- if (!NT_STATUS_IS_OK(ret)) return ret;
-
- /* check if this is a user account or a machine account */
- if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
- {
- pdb_set_profile_path(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_path(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
-
- pdb_set_homedir(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_home(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
-
- pdb_set_dir_drive(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_drive(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
-
- pdb_set_logon_script(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_script(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
- if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
- DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
- if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
- DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ *user=(SAM_ACCOUNT *)malloc(sizeof(SAM_ACCOUNT));
+
+ if (*user==NULL) {
+ DEBUG(0,("pdb_init_sam: error while allocating memory\n"));
+ return False;
}
- return NT_STATUS_OK;
+
+ pdb_fill_default_sam(*user);
+
+ return True;
}
@@ -321,135 +127,121 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
Initialises a struct sam_passwd with sane values.
************************************************************/
-NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd)
{
- NTSTATUS nt_status;
-
if (!pwd) {
new_sam_acct = NULL;
- return NT_STATUS_INVALID_PARAMETER;
+ return False;
}
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
+ if (!pdb_init_sam(new_sam_acct)) {
new_sam_acct = NULL;
- return nt_status;
+ return False;
}
- if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
- pdb_free_sam(new_sam_acct);
- new_sam_acct = NULL;
- return nt_status;
- }
- return NT_STATUS_OK;
+ pdb_set_username(*new_sam_acct, pwd->pw_name);
+ pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
+ pdb_set_uid(*new_sam_acct, pwd->pw_uid);
+ pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+ pdb_set_profile_path(*new_sam_acct, lp_logon_path(), False);
+ pdb_set_homedir(*new_sam_acct, lp_logon_home(), False);
+ pdb_set_dir_drive(*new_sam_acct, lp_logon_drive(), False);
+ pdb_set_logon_script(*new_sam_acct, lp_logon_script(), False);
+ return True;
}
-/*************************************************************
- Initialises a SAM_ACCOUNT ready to add a new account, based
- on the UNIX user. Pass in a RID if you have one
- ************************************************************/
+/************************************************************
+ Free the NT/LM hashes only.
+ ***********************************************************/
-NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
- uint32 rid)
+static BOOL pdb_free_sam_contents(SAM_ACCOUNT *user)
{
- NTSTATUS nt_status = NT_STATUS_NO_MEMORY;
- struct passwd *pwd;
- BOOL ret;
-
- pwd = Get_Pwnam(username);
-
- if (!pwd)
- return NT_STATUS_NO_SUCH_USER;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
- *new_sam_acct = NULL;
- return nt_status;
- }
-
- /* see if we need to generate a new rid using the 2.2 algorithm */
- if ( rid == 0 && lp_enable_rid_algorithm() ) {
- DEBUG(10,("pdb_init_sam_new: no RID specified. Generating one via old algorithm\n"));
- rid = fallback_pdb_uid_to_user_rid(pwd->pw_uid);
+ if (user == NULL) {
+ DEBUG(0,("pdb_free_sam_contents: SAM_ACCOUNT was NULL\n"));
+#if 0
+ smb_panic("NULL pointer passed to pdb_free_sam\n");
+#endif
+ return False;
}
-
- /* set the new SID */
-
- ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
-
- return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
-}
-
-
-/**
- * Free the contets of the SAM_ACCOUNT, but not the structure.
- *
- * Also wipes the LM and NT hashes and plaintext password from
- * memory.
- *
- * @param user SAM_ACCOUNT to free members of.
- **/
-
-static void pdb_free_sam_contents(SAM_ACCOUNT *user)
-{
-
- /* Kill off sensitive data. Free()ed by the
- talloc mechinism */
- data_blob_clear_free(&(user->private.lm_pw));
- data_blob_clear_free(&(user->private.nt_pw));
- if (user->private.plaintext_pw!=NULL)
- memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw));
+ /* As we start mallocing more strings this is where
+ we should free them. */
- if (user->private.backend_private_data && user->private.backend_private_data_free_fn) {
- user->private.backend_private_data_free_fn(&user->private.backend_private_data);
- }
+ SAFE_FREE(user->nt_pw);
+ SAFE_FREE(user->lm_pw);
+
+ return True;
}
/************************************************************
Reset the SAM_ACCOUNT and free the NT/LM hashes.
+ - note: they are not zero'ed out however.
***********************************************************/
-NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
+BOOL pdb_reset_sam(SAM_ACCOUNT *user)
{
if (user == NULL) {
DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_free_sam\n");
-#endif
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
- pdb_free_sam_contents(user);
+ if (!pdb_free_sam_contents(user)) {
+ return False;
+ }
- pdb_fill_default_sam(user);
+ if (!pdb_fill_default_sam(user)) {
+ return False;
+ }
- return NT_STATUS_OK;
+ return True;
}
/************************************************************
- Free the SAM_ACCOUNT and the member pointers.
+ Free the SAM_ACCOUNT and the NT/LM hashes.
***********************************************************/
-NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
+BOOL pdb_free_sam(SAM_ACCOUNT *user)
{
- if (*user == NULL) {
+ if (user == NULL) {
DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
#if 0
smb_panic("NULL pointer passed to pdb_free_sam\n");
#endif
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
- pdb_free_sam_contents(*user);
-
- if ((*user)->free_fn) {
- (*user)->free_fn(user);
+ if (!pdb_free_sam_contents(user)) {
+ return False;
}
- return NT_STATUS_OK;
+ SAFE_FREE(user);
+
+ return True;
+}
+
+
+/*************************************************************************
+ Routine to return the next entry in the sam passwd list.
+ *************************************************************************/
+
+struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
+{
+ static struct sam_disp_info disp_info;
+
+ if (user == NULL)
+ return NULL;
+
+ pdb_init_dispinfo(&disp_info);
+
+ disp_info.smb_name = user->username;
+ disp_info.full_name = user->full_name;
+ disp_info.user_rid = user->user_rid;
+
+ return &disp_info;
}
/**********************************************************
@@ -461,11 +253,8 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
{
static fstring acct_str;
-
size_t i = 0;
- SMB_ASSERT(length <= sizeof(acct_str));
-
acct_str[i++] = '[';
if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
@@ -536,7 +325,7 @@ uint16 pdb_decode_acct_ctrl(const char *p)
Routine to set 32 hex password characters from a 16 byte array.
**************************************************************/
-void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
+void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
{
if (pwd != NULL) {
int i;
@@ -555,11 +344,11 @@ void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
into a 16 byte array.
**************************************************************/
-BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
+BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
{
int i;
unsigned char lonybble, hinybble;
- const char *hexchars = "0123456789ABCDEF";
+ const char *hexchars = "0123456789ABCDEF";
char *p1, *p2;
if (!p)
@@ -583,70 +372,66 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
return (True);
}
-int algorithmic_rid_base(void)
-{
- static int rid_offset = 0;
+/*******************************************************************
+ Group and User RID username mapping function
+ ********************************************************************/
- if (rid_offset != 0)
- return rid_offset;
+BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
+{
+ struct passwd *pw = Get_Pwnam(user_name, False);
- rid_offset = lp_algorithmic_rid_base();
+ if (u_rid == NULL || g_rid == NULL || user_name == NULL)
+ return False;
- if (rid_offset < BASE_RID) {
- /* Try to prevent admin foot-shooting, we can't put algorithmic
- rids below 1000, that's the 'well known RIDs' on NT */
- DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
- rid_offset = BASE_RID;
- }
- if (rid_offset & 1) {
- DEBUG(0, ("algorithmic rid base must be even\n"));
- rid_offset += 1;
+ if (!pw) {
+ DEBUG(1,("Username %s is invalid on this system\n", user_name));
+ return False;
}
- return rid_offset;
+
+ /* turn the unix UID into a Domain RID. this is what the posix
+ sub-system does (adds 1000 to the uid) */
+ *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
+
+ /* absolutely no idea what to do about the unix GID to Domain RID mapping */
+ *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
+
+ return True;
}
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/
-uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
+uid_t pdb_user_rid_to_uid(uint32 user_rid)
{
- int rid_offset = algorithmic_rid_base();
- return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
+ return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
}
/*******************************************************************
- converts UNIX uid to an NT User RID.
+ Converts NT user RID to a UNIX gid.
********************************************************************/
-uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
+gid_t pdb_user_rid_to_gid(uint32 user_rid)
{
- int rid_offset = algorithmic_rid_base();
- return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
+ return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
}
/*******************************************************************
- Converts NT group RID to a UNIX gid.
+ converts UNIX uid to an NT User RID.
********************************************************************/
-gid_t pdb_group_rid_to_gid(uint32 group_rid)
+uint32 pdb_uid_to_user_rid(uid_t uid)
{
- int rid_offset = algorithmic_rid_base();
- return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
+ return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
}
/*******************************************************************
converts NT Group RID to a UNIX uid.
-
- warning: you must not call that function only
- you must do a call to the group mapping first.
- there is not anymore a direct link between the gid and the rid.
********************************************************************/
uint32 pdb_gid_to_group_rid(gid_t gid)
{
- int rid_offset = algorithmic_rid_base();
- return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
+ return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
}
/*******************************************************************
@@ -655,25 +440,19 @@ uint32 pdb_gid_to_group_rid(gid_t gid)
static BOOL pdb_rid_is_well_known(uint32 rid)
{
- /* Not using rid_offset here, because this is the actual
- NT fixed value (1000) */
-
- return (rid < BASE_RID);
+ return (rid < 1000);
}
/*******************************************************************
Decides if a RID is a user or group RID.
********************************************************************/
-BOOL fallback_pdb_rid_is_user(uint32 rid)
+BOOL pdb_rid_is_user(uint32 rid)
{
/* lkcl i understand that NT attaches an enumeration to a RID
* such that it can be identified as either a user, group etc
* type. there are 5 such categories, and they are documented.
*/
- /* However, they are not in the RID, just somthing you can query
- seperatly. Sorry luke :-) */
-
if(pdb_rid_is_well_known(rid)) {
/*
* The only well known user RIDs are DOMAIN_USER_RID_ADMIN
@@ -691,144 +470,127 @@ BOOL fallback_pdb_rid_is_user(uint32 rid)
Convert a rid into a name. Used in the lookup SID rpc.
********************************************************************/
-BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
+BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
{
- uint32 rid;
- SAM_ACCOUNT *sam_account = NULL;
- GROUP_MAP map;
- BOOL ret;
+ BOOL is_user = pdb_rid_is_user(rid);
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
- DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
- sid_string_static(&map.sid)));
- return False;
- }
*psid_name_use = SID_NAME_UNKNOWN;
-
- DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
-
- if (rid == DOMAIN_USER_RID_ADMIN) {
- const char **admin_list = lp_admin_users(-1);
- *psid_name_use = SID_NAME_USER;
- if (admin_list) {
- const char *p = *admin_list;
+
+ DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
+ "group", (unsigned int)rid));
+
+ if(is_user) {
+ if(rid == DOMAIN_USER_RID_ADMIN) {
+ const char *p = lp_admin_users(-1);
+ *psid_name_use = SID_NAME_USER;
if(!next_token(&p, name, NULL, sizeof(fstring)))
fstrcpy(name, "Administrator");
+ } else if (rid == DOMAIN_USER_RID_GUEST) {
+ const char *p = lp_guestaccount(-1);
+ *psid_name_use = SID_NAME_USER;
+ if(!next_token(&p, name, NULL, sizeof(fstring)))
+ fstrcpy(name, "Guest");
} else {
- fstrcpy(name, "Administrator");
- }
- return True;
- }
-
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
- return False;
- }
-
- /* see if the passdb can help us with the name of the user */
+ uid_t uid;
+ struct passwd *pass;
+
+ /*
+ * Don't try to convert the rid to a name if
+ * running in appliance mode
+ */
+ if (lp_hide_local_users())
+ return False;
+
+ uid = pdb_user_rid_to_uid(rid);
+ pass = sys_getpwuid(uid);
- /* BEING ROOT BLLOCK */
- become_root();
- if (pdb_getsampwsid(sam_account, sid)) {
- unbecome_root(); /* -----> EXIT BECOME_ROOT() */
- fstrcpy(name, pdb_get_username(sam_account));
- *psid_name_use = SID_NAME_USER;
+ *psid_name_use = SID_NAME_USER;
- pdb_free_sam(&sam_account);
-
- return True;
- }
- pdb_free_sam(&sam_account);
-
- ret = pdb_getgrsid(&map, *sid);
- unbecome_root();
- /* END BECOME_ROOT BLOCK */
-
- if ( ret ) {
- if (map.gid!=(gid_t)-1) {
- DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
- } else {
- DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
- }
+ DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
+ pass ? "succeeded" : "failed" ));
- fstrcpy(name, map.nt_name);
- *psid_name_use = map.sid_name_use;
- return True;
- }
+ if(!pass) {
+ slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
+ return True;
+ }
- if (fallback_pdb_rid_is_user(rid)) {
- uid_t uid;
- struct passwd *pw = NULL;
+ fstrcpy(name, pass->pw_name);
- DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
+ DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
+ (unsigned int)rid ));
+ }
- uid = fallback_pdb_user_rid_to_uid(rid);
- pw = sys_getpwuid( uid );
-
- DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
- pw ? "succeeded" : "failed" ));
-
- if ( !pw )
- fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
- else
- fstrcpy( name, pw->pw_name );
-
- DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
- (unsigned int)rid ));
-
- *psid_name_use = SID_NAME_USER;
-
- return ( pw != NULL );
} else {
gid_t gid;
struct group *gr;
-
- DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
- gid = pdb_group_rid_to_gid(rid);
- gr = getgrgid(gid);
-
- DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
- gr ? "succeeded" : "failed" ));
-
- if( !gr )
- fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
- else
- fstrcpy( name, gr->gr_name);
-
- DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
- (unsigned int)rid ));
-
- /* assume fallback groups aer domain global groups */
+ /*
+ * Don't try to convert the rid to a name if running
+ * in appliance mode
+ */
- *psid_name_use = SID_NAME_DOM_GRP;
+ if (lp_hide_local_users())
+ return False;
- return ( gr != NULL );
+ gid = pdb_user_rid_to_gid(rid);
+ gr = getgrgid(gid);
+
+ *psid_name_use = SID_NAME_ALIAS;
+
+ DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
+ gr ? "succeeded" : "failed" ));
+
+ if(!gr) {
+ switch (rid) {
+ case DOMAIN_GROUP_RID_ADMINS:
+ fstrcpy(name, "Domain Admins");
+ return True;
+ case DOMAIN_GROUP_RID_USERS:
+ fstrcpy(name, "Domain Users");
+ return True;
+ case DOMAIN_GROUP_RID_GUESTS:
+ fstrcpy(name, "Domain Guests");
+ return True;
+ case BUILTIN_ALIAS_RID_USERS:
+ fstrcpy(name, "Users");
+ return True;
+ }
+ slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
+ return True;
+ }
+
+ fstrcpy( name, gr->gr_name);
+
+ DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
+ (unsigned int)rid ));
}
+
+ return True;
}
/*******************************************************************
Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
-BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
+BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
{
extern DOM_SID global_sid_World_Domain;
+ struct passwd *pass = NULL;
DOM_SID local_sid;
fstring user;
- SAM_ACCOUNT *sam_account = NULL;
- struct group *grp;
- GROUP_MAP map;
-
+ fstring domain;
+
*psid_name_use = SID_NAME_UNKNOWN;
/*
- * user may be quoted a const string, and map_username and
- * friends can modify it. Make a modifiable copy. JRA.
+ * domain and user may be quoted const strings, and map_username and
+ * friends can modify them. Make a modifiable copy. JRA.
*/
+ fstrcpy(domain, c_domain);
fstrcpy(user, c_user);
- sid_copy(&local_sid, get_global_sam_sid());
+ sid_copy(&local_sid, &global_sam_sid);
/*
* Special case for MACHINE\Everyone. Map to the world_sid.
@@ -841,73 +603,272 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
return True;
}
- (void)map_username(user);
-
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
+ /*
+ * Don't lookup local unix users if running in appliance mode
+ */
+ if (lp_hide_local_users())
return False;
- }
-
- /* BEGIN ROOT BLOCK */
-
- become_root();
- if (pdb_getsampwnam(sam_account, user)) {
- unbecome_root();
- sid_copy(psid, pdb_get_user_sid(sam_account));
- *psid_name_use = SID_NAME_USER;
-
- pdb_free_sam(&sam_account);
- return True;
- }
- pdb_free_sam(&sam_account);
-
- /*
- * Maybe it was a group ?
- */
+ (void)map_username(user);
- /* check if it's a mapped group */
- if (pdb_getgrnam(&map, user)) {
- /* yes it's a mapped group */
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
+ if((pass = Get_Pwnam(user, False))) {
+ sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
+ *psid_name_use = SID_NAME_USER;
} else {
- /* it's not a mapped group */
- grp = getgrnam(user);
- if(!grp) {
- unbecome_root(); /* ---> exit form block */
- return False;
- }
-
- /*
- *check if it's mapped, if it is reply it doesn't exist
- *
- * that's to prevent this case:
- *
- * unix group ug is mapped to nt group ng
- * someone does a lookup on ug
- * we must not reply as it doesn't "exist" anymore
- * for NT. For NT only ng exists.
- * JFM, 30/11/2001
+ /*
+ * Maybe it was a group ?
*/
-
- if (pdb_getgrgid(&map, grp->gr_gid)){
- unbecome_root(); /* ---> exit form block */
+ struct group *grp = getgrnam(user);
+
+ if(!grp)
return False;
- }
-
+
sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
*psid_name_use = SID_NAME_ALIAS;
}
- unbecome_root();
- /* END ROOT BLOCK */
sid_copy( psid, &local_sid);
return True;
}
+/****************************************************************************
+ Convert a uid to SID - locally.
+****************************************************************************/
+
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+ extern DOM_SID global_sam_sid;
+
+ sid_copy(psid, &global_sam_sid);
+ sid_append_rid(psid, pdb_uid_to_user_rid(uid));
+
+ return psid;
+}
+
+/****************************************************************************
+ Convert a SID to uid - locally.
+****************************************************************************/
+
+BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
+{
+ extern DOM_SID global_sam_sid;
+
+ DOM_SID dom_sid;
+ uint32 rid;
+ fstring str;
+ struct passwd *pass;
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ sid_copy(&dom_sid, psid);
+ sid_split_rid(&dom_sid, &rid);
+
+ if (!pdb_rid_is_user(rid))
+ return False;
+
+ /*
+ * We can only convert to a uid if this is our local
+ * Domain SID (ie. we are the controling authority).
+ */
+ if (!sid_equal(&global_sam_sid, &dom_sid))
+ return False;
+
+ *puid = pdb_user_rid_to_uid(rid);
+
+ /*
+ * Ensure this uid really does exist.
+ */
+ if(!(pass = sys_getpwuid(*puid)))
+ return False;
+
+ DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
+ (unsigned int)*puid, pass->pw_name ));
+
+ *name_type = SID_NAME_USER;
+ return True;
+}
+
+/****************************************************************************
+ Convert a gid to SID - locally.
+****************************************************************************/
+
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ extern DOM_SID global_sam_sid;
+
+ sid_copy(psid, &global_sam_sid);
+ sid_append_rid(psid, pdb_gid_to_group_rid(gid));
+
+ return psid;
+}
+
+/****************************************************************************
+ Convert a SID to gid - locally.
+****************************************************************************/
+
+BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
+{
+ extern DOM_SID global_sam_sid;
+ DOM_SID dom_sid;
+ uint32 rid;
+ fstring str;
+ struct group *grp;
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ sid_copy(&dom_sid, psid);
+ sid_split_rid(&dom_sid, &rid);
+
+ /*
+ * We can only convert to a gid if this is our local
+ * Domain SID (ie. we are the controling authority).
+ */
+
+ if (!sid_equal(&global_sam_sid, &dom_sid))
+ return False;
+
+ if (pdb_rid_is_user(rid))
+ return False;
+
+ *pgid = pdb_user_rid_to_gid(rid);
+
+ /*
+ * Ensure this gid really does exist.
+ */
+
+ if(!(grp = getgrgid(*pgid)))
+ return False;
+
+ *name_type = SID_NAME_ALIAS;
+
+ DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid),
+ (unsigned int)*pgid, grp->gr_name ));
+
+ return True;
+}
+
+static void select_name(pstring string, const UNISTR2 *from)
+{
+ if (from->buffer != 0)
+ unistr2_to_dos(string, from, sizeof(pstring));
+}
+
+/*************************************************************
+ Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
+ **************************************************************/
+
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
+{
+
+ if (from == NULL || to == NULL)
+ return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(to->username , &from->uni_user_name );
+ select_name(to->full_name , &from->uni_full_name );
+ select_name(to->home_dir , &from->uni_home_dir );
+ select_name(to->dir_drive , &from->uni_dir_drive );
+ select_name(to->logon_script, &from->uni_logon_script);
+ select_name(to->profile_path, &from->uni_profile_path);
+ select_name(to->acct_desc , &from->uni_acct_desc );
+ select_name(to->workstations, &from->uni_workstations);
+ select_name(to->unknown_str , &from->uni_unknown_str );
+ select_name(to->munged_dial , &from->uni_munged_dial );
+
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+/*************************************************************
+ Copies a sam passwd.
+ **************************************************************/
+
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
+{
+ if (from == NULL || to == NULL)
+ return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(to->username , &from->uni_user_name );
+ select_name(to->full_name , &from->uni_full_name );
+ select_name(to->home_dir , &from->uni_home_dir );
+ select_name(to->dir_drive , &from->uni_dir_drive );
+ select_name(to->logon_script, &from->uni_logon_script);
+ select_name(to->profile_path, &from->uni_profile_path);
+ select_name(to->acct_desc , &from->uni_acct_desc );
+ select_name(to->workstations, &from->uni_workstations);
+ select_name(to->unknown_str , &from->uni_unknown_str );
+ select_name(to->munged_dial , &from->uni_munged_dial );
+
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ /* FIXME!! Do we need to copy the passwords here as well?
+ I don't know. Need to figure this out --jerry */
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+#if 0 /* JERRY */
+/*************************************************************
+ Copies a SAM_ACCOUNT.
+ FIXME!!!! This is broken as SAM_ACCOUNT contains two
+ pointers. --jerry
+ **************************************************************/
+
+void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
+{
+ if (!from || !to)
+ return;
+
+ memcpy(to, from, sizeof(SAM_ACCOUNT));
+
+
+}
+#endif
+
/*************************************************************
Change a password entry in the local smbpasswd file.
+
+ FIXME!! The function needs to be abstracted into the
+ passdb interface or something. It is currently being called
+ by _api_samr_create_user() in rpc_server/srv_samr.c
+
+ --jerry
+
+ FIXME ! The new password is in UNIX character set. Must be
+ changed to DOS codepage before hashing.
*************************************************************/
BOOL local_password_change(const char *user_name, int local_flags,
@@ -915,56 +876,84 @@ BOOL local_password_change(const char *user_name, int local_flags,
char *err_str, size_t err_str_len,
char *msg_str, size_t msg_str_len)
{
+ struct passwd *pwd = NULL;
SAM_ACCOUNT *sam_pass=NULL;
- uint16 other_acb;
*err_str = '\0';
*msg_str = '\0';
+ if (local_flags & LOCAL_ADD_USER) {
+
+ /*
+ * Check for a local account - if we're adding only.
+ */
+
+ if(!(pwd = sys_getpwnam(user_name))) {
+ slprintf(err_str, err_str_len - 1, "User %s does not \
+exist in system password file (usually /etc/passwd). Cannot add \
+account without a valid local system user.\n", user_name);
+ return False;
+ }
+ }
+
/* Get the smb passwd entry for this user */
pdb_init_sam(&sam_pass);
-
- become_root();
+ if(local_flags & LOCAL_DELETE_USER) {
+ if (!pdb_delete_sam_account(user_name)) {
+ slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return True;
+ }
if(!pdb_getsampwnam(sam_pass, user_name)) {
- unbecome_root();
- pdb_free_sam(&sam_pass);
+ pdb_free_sam(sam_pass);
- if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
- /* Might not exist in /etc/passwd. Use rid algorithm here */
- if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
- slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s.\n", user_name);
- return False;
- }
- } else {
+ if(!(local_flags & LOCAL_ADD_USER)) {
slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
return False;
}
- } else {
- unbecome_root();
- /* the entry already existed */
- local_flags &= ~LOCAL_ADD_USER;
- }
- /* the 'other' acb bits not being changed here */
- other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
- if (local_flags & LOCAL_TRUST_ACCOUNT) {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
- slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
+ sam_pass = NULL;
+ if (!pdb_init_sam_pw(&sam_pass, sys_getpwnam(user_name))) {
return False;
}
- } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
- slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+
+ /* Set account flags. Note that the default is non-expiring accounts */
+ pdb_set_acct_ctrl(sam_pass,(local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL|ACB_PWNOEXP);
+
+ if (local_flags & LOCAL_DISABLE_USER)
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
+
+ if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
+ } else {
+ /* set the passwords here. if we get to here it means
+ we have a valid, active account */
+ if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
}
- } else {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
- slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
+
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sam_pass, time(NULL));
+
+ if (pdb_add_sam_account(sam_pass)) {
+ slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return True;
+ } else {
+ slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
return False;
}
+ } else {
+ /* the entry already existed */
+ local_flags &= ~LOCAL_ADD_USER;
+ slprintf(msg_str, msg_str_len-1, "Password changed for user %s.\n", user_name );
}
/*
@@ -972,27 +961,28 @@ BOOL local_password_change(const char *user_name, int local_flags,
* and the valid last change time.
*/
- if (local_flags & LOCAL_DISABLE_USER) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
- slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
+ if(local_flags & LOCAL_DISABLE_USER) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
} else if (local_flags & LOCAL_ENABLE_USER) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
- slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
+ if(pdb_get_lanman_passwd(sam_pass) == NULL) {
+ if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ }
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
+ } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
+ /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+ if (!pdb_set_lanman_passwd (sam_pass, NULL)) {
+ pdb_free_sam(sam_pass);
return False;
}
- }
-
- if (local_flags & LOCAL_SET_NO_PASSWORD) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
- slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
+ if (!pdb_set_nt_passwd(sam_pass, NULL)) {
+ pdb_free_sam(sam_pass);
return False;
}
- } else if (local_flags & LOCAL_SET_PASSWORD) {
+ } else {
/*
* If we're dealing with setting a completely empty user account
* ie. One with a password of 'XXXX', but not set disabled (like
@@ -1002,1385 +992,773 @@ BOOL local_password_change(const char *user_name, int local_flags,
* and the decision hasn't really been made to disable them (ie.
* don't create them disabled). JRA.
*/
- if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
- slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
- }
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
- slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
-
+ if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED))
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ));
if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
- slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ pdb_free_sam(sam_pass);
+ return False;
}
- }
-
- if (local_flags & LOCAL_ADD_USER) {
- if (pdb_add_sam_account(sam_pass)) {
- slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return True;
- } else {
- slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
- } else if (local_flags & LOCAL_DELETE_USER) {
- if (!pdb_delete_sam_account(sam_pass)) {
- slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
- slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
- } else {
- if(!pdb_update_sam_account(sam_pass)) {
- slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
- }
- if(local_flags & LOCAL_DISABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
- else if (local_flags & LOCAL_ENABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
- else if (local_flags & LOCAL_SET_NO_PASSWORD)
- slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
}
+
+ if(!pdb_update_sam_account(sam_pass, True)) {
+ slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ if(local_flags & LOCAL_DISABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_ENABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_SET_NO_PASSWORD)
+ slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
- pdb_free_sam(&sam_pass);
+ pdb_free_sam(sam_pass);
return True;
}
-/****************************************************************************
- Convert a uid to SID - algorithmic.
-****************************************************************************/
+/*********************************************************************
+ Collection of get...() functions for SAM_ACCOUNT_INFO.
+ ********************************************************************/
-DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
+uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
{
- if ( !lp_enable_rid_algorithm() )
- return NULL;
+ if (sampass)
+ return (sampass->acct_ctrl);
+ else
+ return (ACB_DISABLED);
+}
- DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
- sid_copy( psid, get_global_sam_sid() );
- sid_append_rid( psid, fallback_pdb_uid_to_user_rid(uid) );
- DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
- (unsigned int)uid, sid_string_static(psid) ));
+time_t pdb_get_logon_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logon_time);
+ else
+ return (0);
+}
- return psid;
+time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logoff_time);
+ else
+ return (-1);
}
-/****************************************************************************
- Convert a uid to SID - locally.
-****************************************************************************/
+time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->kickoff_time);
+ else
+ return (-1);
+}
-DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
+time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass)
{
- SAM_ACCOUNT *sampw = NULL;
- struct passwd *unix_pw;
- BOOL ret;
-
- unix_pw = sys_getpwuid( uid );
+ if (sampass)
+ return (sampass->pass_last_set_time);
+ else
+ return (-1);
+}
- if ( !unix_pw ) {
- DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
- return algorithmic_uid_to_sid( psid, uid);
- }
-
- if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
- DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
- return NULL;
- }
-
- become_root();
- ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
- unbecome_root();
-
- if ( ret )
- sid_copy( psid, pdb_get_user_sid(sampw) );
- else {
- DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
- unix_pw->pw_name, (unsigned long)uid));
+time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->pass_can_change_time);
+ else
+ return (-1);
+}
- return algorithmic_uid_to_sid( psid, uid);
- }
+time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->pass_must_change_time);
+ else
+ return (-1);
+}
- DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
- (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
-
- return psid;
+uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logon_divs);
+ else
+ return (-1);
}
-/****************************************************************************
- Convert a SID to uid - locally.
-****************************************************************************/
+uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->hours_len);
+ else
+ return (-1);
+}
-BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
+uint8* pdb_get_hours (SAM_ACCOUNT *sampass)
{
- SAM_ACCOUNT *sampw = NULL;
- struct passwd *unix_pw;
- const char *user_name;
+ if (sampass)
+ return (sampass->hours);
+ else
+ return (NULL);
+}
- *name_type = SID_NAME_UNKNOWN;
+uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->nt_pw);
+ else
+ return (NULL);
+}
- /*
- * We can only convert to a uid if this is our local
- * Domain SID (ie. we are the controling authority).
- */
- if (!sid_check_is_in_our_domain(psid) ) {
- DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
- return False;
- }
+uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->lm_pw);
+ else
+ return (NULL);
+}
- /* lookup the user account */
-
- if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
- DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
- return False;
- }
-
- become_root();
- if ( !pdb_getsampwsid(sampw, psid) ) {
- unbecome_root();
- DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
- sid_string_static(psid)));
- return False;
- }
- unbecome_root();
-
- user_name = pdb_get_username(sampw);
+uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->user_rid);
+ else
+ return (-1);
+}
- unix_pw = sys_getpwnam( user_name );
+uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->group_rid);
+ else
+ return (-1);
+}
- if ( !unix_pw ) {
- DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
- user_name));
- pdb_free_sam( &sampw );
- return False;
- }
-
- *puid = unix_pw->pw_uid;
-
- DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
- (unsigned int)*puid, user_name ));
+uid_t pdb_get_uid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->uid);
+ else
+ return ((uid_t)-1);
+}
- *name_type = SID_NAME_USER;
-
- return True;
+gid_t pdb_get_gid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->gid);
+ else
+ return ((gid_t)-1);
}
-/****************************************************************************
- Convert a gid to SID - locally.
-****************************************************************************/
+char* pdb_get_username (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->username);
+ else
+ return (NULL);
+}
-DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
+char* pdb_get_domain (SAM_ACCOUNT *sampass)
{
- GROUP_MAP group;
- BOOL ret;
-
- /* we don't need to disable winbindd since the gid is stored in
- the GROUP_MAP object */
-
- /* done as root since ldap backend requires root to open a connection */
-
- become_root();
- ret = pdb_getgrgid( &group, gid );
- unbecome_root();
-
- if ( !ret ) {
+ if (sampass)
+ return (sampass->domain);
+ else
+ return (NULL);
+}
- /* fallback to rid mapping if enabled */
+char* pdb_get_nt_username (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->nt_username);
+ else
+ return (NULL);
+}
- if ( lp_enable_rid_algorithm() ) {
- sid_copy(psid, get_global_sam_sid());
- sid_append_rid(psid, pdb_gid_to_group_rid(gid));
+char* pdb_get_fullname (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->full_name);
+ else
+ return (NULL);
+}
- DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
- (unsigned int)gid, sid_string_static(psid)));
-
- return psid;
- }
- else
- return NULL;
- }
-
- sid_copy( psid, &group.sid );
-
- DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
- (unsigned int)gid, sid_string_static(psid)));
-
- return psid;
+char* pdb_get_homedir (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->home_dir);
+ else
+ return (NULL);
}
-/****************************************************************************
- Convert a SID to gid - locally.
-****************************************************************************/
+char* pdb_get_dirdrive (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->dir_drive);
+ else
+ return (NULL);
+}
-BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
+char* pdb_get_logon_script (SAM_ACCOUNT *sampass)
{
- uint32 rid;
- GROUP_MAP group;
- BOOL ret;
+ if (sampass)
+ return (sampass->logon_script);
+ else
+ return (NULL);
+}
- *name_type = SID_NAME_UNKNOWN;
+char* pdb_get_profile_path (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->profile_path);
+ else
+ return (NULL);
+}
- /* This call can enumerate group mappings for foreign sids as well.
- So don't check for a match against our domain SID */
+char* pdb_get_acct_desc (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->acct_desc);
+ else
+ return (NULL);
+}
- /* we don't need to disable winbindd since the gid is stored in
- the GROUP_MAP object */
-
- become_root();
- ret = pdb_getgrsid(&group, *psid);
- unbecome_root();
-
- if ( !ret ) {
+char* pdb_get_workstations (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->workstations);
+ else
+ return (NULL);
+}
- /* fallback to rid mapping if enabled */
+char* pdb_get_munged_dial (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->munged_dial);
+ else
+ return (NULL);
+}
- if ( lp_enable_rid_algorithm() ) {
+uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_3);
+ else
+ return (-1);
+}
- if (!sid_check_is_in_our_domain(psid) ) {
- DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
- return False;
- }
+uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_5);
+ else
+ return (-1);
+}
- if (!sid_peek_rid(psid, &rid)) {
- DEBUG(10,("local_sid_to_uid: invalid SID!\n"));
- return False;
- }
+uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_6);
+ else
+ return (-1);
+}
- DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
+/*********************************************************************
+ Collection of set...() functions for SAM_ACCOUNT_INFO.
+ ********************************************************************/
- if (fallback_pdb_rid_is_user(rid)) {
- DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
- return False;
- } else {
- *pgid = pdb_group_rid_to_gid(rid);
- DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
- return True;
- }
- }
-
+BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
+{
+ if (!sampass)
return False;
+
+ if (sampass) {
+ sampass->acct_ctrl = flags;
+ return True;
}
+
+ return False;
+}
- *pgid = group.gid;
-
- DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
- (unsigned int)*pgid));
+BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+ sampass->logon_time = mytime;
return True;
}
-/**********************************************************************
- Marshall/unmarshall SAM_ACCOUNT structs.
- *********************************************************************/
-
-#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
-#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
+BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
-/**********************************************************************
- Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
- *********************************************************************/
+ sampass->logoff_time = mytime;
+ return True;
+}
-BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime)
{
- return(init_sam_from_buffer_v1(sampass, buf, buflen));
-}
+ if (!sampass)
+ return False;
-/**********************************************************************
- Intialize a BYTE buffer from a SAM_ACCOUNT struct
- *********************************************************************/
+ sampass->kickoff_time = mytime;
+ return True;
+}
-uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
+BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime)
{
- return(init_buffer_from_sam_v1(buf, sampass, size_only));
-}
+ if (!sampass)
+ return False;
+ sampass->pass_can_change_time = mytime;
+ return True;
+}
-BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime)
{
+ if (!sampass)
+ return False;
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
- char *username;
- char *domain;
- char *nt_username;
- char *dir_drive;
- char *unknown_str;
- char *munged_dial;
- char *fullname;
- char *homedir;
- char *logon_script;
- char *profile_path;
- char *acct_desc;
- char *workstations;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
- uint16 acct_ctrl, logon_divs;
- uint16 bad_password_count, logon_count;
- uint8 *hours;
- static uint8 *lm_pw_ptr, *nt_pw_ptr;
- uint32 len = 0;
- uint32 lm_pw_len, nt_pw_len, hourslen;
- BOOL ret = True;
-
- if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
+ sampass->pass_must_change_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
return False;
- }
-
- /* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
- &logon_time,
- &logoff_time,
- &kickoff_time,
- &pass_last_set_time,
- &pass_can_change_time,
- &pass_must_change_time,
- &username_len, &username,
- &domain_len, &domain,
- &nt_username_len, &nt_username,
- &fullname_len, &fullname,
- &homedir_len, &homedir,
- &dir_drive_len, &dir_drive,
- &logon_script_len, &logon_script,
- &profile_path_len, &profile_path,
- &acct_desc_len, &acct_desc,
- &workstations_len, &workstations,
- &unknown_str_len, &unknown_str,
- &munged_dial_len, &munged_dial,
- &user_rid,
- &group_rid,
- &lm_pw_len, &lm_pw_ptr,
- &nt_pw_len, &nt_pw_ptr,
- &acct_ctrl,
- &remove_me, /* remove on the next TDB_FORMAT upgarde */
- &logon_divs,
- &hours_len,
- &hourslen, &hours,
- &bad_password_count,
- &logon_count,
- &unknown_6);
-
- if (len == (uint32) -1) {
- ret = False;
- goto done;
- }
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+ sampass->pass_last_set_time = mytime;
+ return True;
+}
- pdb_set_username(sampass, username, PDB_SET);
- pdb_set_domain(sampass, domain, PDB_SET);
- pdb_set_nt_username(sampass, nt_username, PDB_SET);
- pdb_set_fullname(sampass, fullname, PDB_SET);
+BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
+{
+ if (!sampass)
+ return False;
- if (homedir) {
- pdb_set_homedir(sampass, homedir, PDB_SET);
- }
- else {
- pdb_set_homedir(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
- PDB_DEFAULT);
- }
+ sampass->hours_len = len;
+ return True;
+}
- if (dir_drive)
- pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- else {
- pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT);
- }
+BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours)
+{
+ if (!sampass)
+ return False;
- if (logon_script)
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
- else {
- pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
- PDB_DEFAULT);
- }
+ sampass->logon_divs = hours;
+ return True;
+}
+
+BOOL pdb_set_init_flag (SAM_ACCOUNT *sampass, uint32 flag)
+{
+ if (!sampass)
+ return False;
- if (profile_path) {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
- } else {
- pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
- PDB_DEFAULT);
- }
+ sampass->init_flag |= flag;
- pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
- pdb_set_workstations(sampass, workstations, PDB_SET);
- pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+ return True;
+}
- if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
+BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
+{
+ if (!sampass)
+ return False;
- if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
+ sampass->uid = uid;
+ sampass->init_flag |= FLAG_SAM_UID;
- pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- pdb_set_hours_len(sampass, hours_len, PDB_SET);
- pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
- pdb_set_logon_count(sampass, logon_count, PDB_SET);
- pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
- pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
- pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
- pdb_set_hours(sampass, hours, PDB_SET);
-
-done:
-
- SAFE_FREE(username);
- SAFE_FREE(domain);
- SAFE_FREE(nt_username);
- SAFE_FREE(fullname);
- SAFE_FREE(homedir);
- SAFE_FREE(dir_drive);
- SAFE_FREE(logon_script);
- SAFE_FREE(profile_path);
- SAFE_FREE(acct_desc);
- SAFE_FREE(workstations);
- SAFE_FREE(munged_dial);
- SAFE_FREE(unknown_str);
- SAFE_FREE(hours);
-
- return ret;
-}
-
-
-uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
-{
- size_t len, buflen;
-
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
-
- uint32 user_rid, group_rid;
-
- const char *username;
- const char *domain;
- const char *nt_username;
- const char *dir_drive;
- const char *unknown_str;
- const char *munged_dial;
- const char *fullname;
- const char *homedir;
- const char *logon_script;
- const char *profile_path;
- const char *acct_desc;
- const char *workstations;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- const uint8 *lm_pw;
- const uint8 *nt_pw;
- uint32 lm_pw_len = 16;
- uint32 nt_pw_len = 16;
-
- /* do we have a valid SAM_ACCOUNT pointer? */
- if (sampass == NULL) {
- DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
- return -1;
- }
-
- *buf = NULL;
- buflen = 0;
-
- logon_time = (uint32)pdb_get_logon_time(sampass);
- logoff_time = (uint32)pdb_get_logoff_time(sampass);
- kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
- pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
- pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
- pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
-
- user_rid = pdb_get_user_rid(sampass);
- group_rid = pdb_get_group_rid(sampass);
-
- username = pdb_get_username(sampass);
- if (username)
- username_len = strlen(username) +1;
- else
- username_len = 0;
+ return True;
+}
- domain = pdb_get_domain(sampass);
- if (domain)
- domain_len = strlen(domain) +1;
- else
- domain_len = 0;
+BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
+{
+ if (!sampass)
+ return False;
- nt_username = pdb_get_nt_username(sampass);
- if (nt_username)
- nt_username_len = strlen(nt_username) +1;
- else
- nt_username_len = 0;
+ sampass->gid = gid;
+ sampass->init_flag |= FLAG_SAM_GID;
- fullname = pdb_get_fullname(sampass);
- if (fullname)
- fullname_len = strlen(fullname) +1;
- else
- fullname_len = 0;
+ return True;
+}
- /*
- * Only updates fields which have been set (not defaults from smb.conf)
- */
+BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
+{
+ if (!sampass)
+ return False;
- if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE))
- dir_drive = pdb_get_dir_drive(sampass);
- else
- dir_drive = NULL;
- if (dir_drive)
- dir_drive_len = strlen(dir_drive) +1;
- else
- dir_drive_len = 0;
+ sampass->user_rid = rid;
+ return True;
+}
- if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME))
- homedir = pdb_get_homedir(sampass);
- else
- homedir = NULL;
- if (homedir)
- homedir_len = strlen(homedir) +1;
- else
- homedir_len = 0;
+BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
+{
+ if (!sampass)
+ return False;
- if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT))
- logon_script = pdb_get_logon_script(sampass);
- else
- logon_script = NULL;
- if (logon_script)
- logon_script_len = strlen(logon_script) +1;
- else
- logon_script_len = 0;
+ sampass->group_rid = grid;
+ return True;
+}
- if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE))
- profile_path = pdb_get_profile_path(sampass);
- else
- profile_path = NULL;
- if (profile_path)
- profile_path_len = strlen(profile_path) +1;
- else
- profile_path_len = 0;
-
- lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw)
- lm_pw_len = 0;
-
- nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw)
- nt_pw_len = 0;
-
- acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc)
- acct_desc_len = strlen(acct_desc) +1;
- else
- acct_desc_len = 0;
+/*********************************************************************
+ Set the user's UNIX name.
+ ********************************************************************/
- workstations = pdb_get_workstations(sampass);
- if (workstations)
- workstations_len = strlen(workstations) +1;
- else
- workstations_len = 0;
+BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
+{
+ if (!sampass)
+ return False;
+ *sampass->username = '\0';
+ if (!username)
+ return False;
- unknown_str = NULL;
- unknown_str_len = 0;
+ StrnCpy (sampass->username, username, sizeof(sampass->username)-1);
- munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial)
- munged_dial_len = strlen(munged_dial) +1;
- else
- munged_dial_len = 0;
-
- /* one time to get the size needed */
- len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V0,
- logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0, /* was: fileds_present, to be removed on format change */
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- if (size_only)
- return buflen;
-
- /* malloc the space needed */
- if ( (*buf=(uint8*)malloc(len)) == NULL) {
- DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
- return (-1);
- }
-
- /* now for the real call to tdb_pack() */
- buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V0,
- logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0, /* was: fileds_present, to be removed on format change */
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- /* check to make sure we got it correct */
- if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
- (unsigned long)buflen, (unsigned long)len));
- /* error */
- SAFE_FREE (*buf);
- return (-1);
- }
+ return True;
+}
- return (buflen);
-}
-
-
-BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
-{
-
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
- char *username;
- char *domain;
- char *nt_username;
- char *dir_drive;
- char *unknown_str;
- char *munged_dial;
- char *fullname;
- char *homedir;
- char *logon_script;
- char *profile_path;
- char *acct_desc;
- char *workstations;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
- uint16 acct_ctrl, logon_divs;
- uint16 bad_password_count, logon_count;
- uint8 *hours;
- static uint8 *lm_pw_ptr, *nt_pw_ptr;
- uint32 len = 0;
- uint32 lm_pw_len, nt_pw_len, hourslen;
- BOOL ret = True;
-
- if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
+/*********************************************************************
+ Set the domain name.
+ ********************************************************************/
+
+BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
+{
+ if (!sampass)
+ return False;
+ *sampass->domain = '\0';
+ if (!domain)
return False;
- }
-
- /* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
- &logon_time,
- &logoff_time,
- &kickoff_time,
- &bad_password_time,
- &pass_last_set_time,
- &pass_can_change_time,
- &pass_must_change_time,
- &username_len, &username,
- &domain_len, &domain,
- &nt_username_len, &nt_username,
- &fullname_len, &fullname,
- &homedir_len, &homedir,
- &dir_drive_len, &dir_drive,
- &logon_script_len, &logon_script,
- &profile_path_len, &profile_path,
- &acct_desc_len, &acct_desc,
- &workstations_len, &workstations,
- &unknown_str_len, &unknown_str,
- &munged_dial_len, &munged_dial,
- &user_rid,
- &group_rid,
- &lm_pw_len, &lm_pw_ptr,
- &nt_pw_len, &nt_pw_ptr,
- &acct_ctrl,
- &remove_me,
- &logon_divs,
- &hours_len,
- &hourslen, &hours,
- &bad_password_count,
- &logon_count,
- &unknown_6);
-
- if (len == (uint32) -1) {
- ret = False;
- goto done;
- }
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
-
- pdb_set_username(sampass, username, PDB_SET);
- pdb_set_domain(sampass, domain, PDB_SET);
- pdb_set_nt_username(sampass, nt_username, PDB_SET);
- pdb_set_fullname(sampass, fullname, PDB_SET);
-
- if (homedir) {
- pdb_set_homedir(sampass, homedir, PDB_SET);
- }
- else {
- pdb_set_homedir(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
- PDB_DEFAULT);
- }
+ StrnCpy (sampass->domain, domain, sizeof(sampass->domain)-1);
- if (dir_drive)
- pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- else {
- pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT);
- }
+ return True;
+}
- if (logon_script)
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
- else {
- pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
- PDB_DEFAULT);
- }
-
- if (profile_path) {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
- } else {
- pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
- PDB_DEFAULT);
- }
+/*********************************************************************
+ Set the user's NT name.
+ ********************************************************************/
- pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
- pdb_set_workstations(sampass, workstations, PDB_SET);
- pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
+{
+ if (!sampass)
+ return False;
+ *sampass->nt_username = '\0';
+ if (!nt_username)
+ return False;
- if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
+ StrnCpy (sampass->nt_username, nt_username, sizeof(sampass->nt_username) -1);
- if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
+ return True;
+}
- pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- pdb_set_hours_len(sampass, hours_len, PDB_SET);
- pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
- pdb_set_logon_count(sampass, logon_count, PDB_SET);
- pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
- pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
- pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
- pdb_set_hours(sampass, hours, PDB_SET);
-
-done:
-
- SAFE_FREE(lm_pw_ptr);
- SAFE_FREE(nt_pw_ptr);
- SAFE_FREE(username);
- SAFE_FREE(domain);
- SAFE_FREE(nt_username);
- SAFE_FREE(fullname);
- SAFE_FREE(homedir);
- SAFE_FREE(dir_drive);
- SAFE_FREE(logon_script);
- SAFE_FREE(profile_path);
- SAFE_FREE(acct_desc);
- SAFE_FREE(workstations);
- SAFE_FREE(munged_dial);
- SAFE_FREE(unknown_str);
- SAFE_FREE(hours);
-
- return ret;
-}
-
-
-uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
-{
- size_t len, buflen;
-
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
-
- uint32 user_rid, group_rid;
-
- const char *username;
- const char *domain;
- const char *nt_username;
- const char *dir_drive;
- const char *unknown_str;
- const char *munged_dial;
- const char *fullname;
- const char *homedir;
- const char *logon_script;
- const char *profile_path;
- const char *acct_desc;
- const char *workstations;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- const uint8 *lm_pw;
- const uint8 *nt_pw;
- uint32 lm_pw_len = 16;
- uint32 nt_pw_len = 16;
-
- /* do we have a valid SAM_ACCOUNT pointer? */
- if (sampass == NULL) {
- DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
- return -1;
- }
-
- *buf = NULL;
- buflen = 0;
-
- logon_time = (uint32)pdb_get_logon_time(sampass);
- logoff_time = (uint32)pdb_get_logoff_time(sampass);
- kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
- bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
- pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
- pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
- pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
-
- user_rid = pdb_get_user_rid(sampass);
- group_rid = pdb_get_group_rid(sampass);
-
- username = pdb_get_username(sampass);
- if (username)
- username_len = strlen(username) +1;
- else
- username_len = 0;
+/*********************************************************************
+ Set the user's full name.
+ ********************************************************************/
- domain = pdb_get_domain(sampass);
- if (domain)
- domain_len = strlen(domain) +1;
- else
- domain_len = 0;
+BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
+{
+ if (!sampass)
+ return False;
+ *sampass->full_name = '\0';
+ if (!fullname)
+ return False;
- nt_username = pdb_get_nt_username(sampass);
- if (nt_username)
- nt_username_len = strlen(nt_username) +1;
- else
- nt_username_len = 0;
+ StrnCpy (sampass->full_name, fullname, sizeof(sampass->full_name)-1);
- fullname = pdb_get_fullname(sampass);
- if (fullname)
- fullname_len = strlen(fullname) +1;
- else
- fullname_len = 0;
+ return True;
+}
- /*
- * Only updates fields which have been set (not defaults from smb.conf)
- */
+/*********************************************************************
+ Set the user's logon script.
+ ********************************************************************/
- if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE))
- dir_drive = pdb_get_dir_drive(sampass);
- else
- dir_drive = NULL;
- if (dir_drive)
- dir_drive_len = strlen(dir_drive) +1;
- else
- dir_drive_len = 0;
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script, BOOL store)
+{
+ if (!sampass)
+ return False;
+ *sampass->logon_script = '\0';
+ if (!logon_script)
+ return False;
- if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME))
- homedir = pdb_get_homedir(sampass);
- else
- homedir = NULL;
- if (homedir)
- homedir_len = strlen(homedir) +1;
- else
- homedir_len = 0;
+ StrnCpy (sampass->logon_script, logon_script, sizeof(sampass->logon_script)-1);
- if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT))
- logon_script = pdb_get_logon_script(sampass);
- else
- logon_script = NULL;
- if (logon_script)
- logon_script_len = strlen(logon_script) +1;
- else
- logon_script_len = 0;
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT);
- if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE))
- profile_path = pdb_get_profile_path(sampass);
- else
- profile_path = NULL;
- if (profile_path)
- profile_path_len = strlen(profile_path) +1;
- else
- profile_path_len = 0;
+ return True;
+}
+
+/*********************************************************************
+ Set the user's profile path.
+ ********************************************************************/
+
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path, BOOL store)
+{
+ if (!sampass)
+ return False;
+ *sampass->profile_path = '\0';
+ if (!profile_path)
+ return False;
- lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw)
- lm_pw_len = 0;
+ StrnCpy (sampass->profile_path, profile_path, sizeof(sampass->profile_path)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_PROFILE);
- nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw)
- nt_pw_len = 0;
-
- acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc)
- acct_desc_len = strlen(acct_desc) +1;
- else
- acct_desc_len = 0;
+ return True;
+}
- workstations = pdb_get_workstations(sampass);
- if (workstations)
- workstations_len = strlen(workstations) +1;
- else
- workstations_len = 0;
+/*********************************************************************
+ Set the user's directory drive.
+ ********************************************************************/
- unknown_str = NULL;
- unknown_str_len = 0;
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive, BOOL store)
+{
+ if (!sampass)
+ return False;
+ *sampass->dir_drive = '\0';
+ if (!dir_drive)
+ return False;
- munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial)
- munged_dial_len = strlen(munged_dial) +1;
- else
- munged_dial_len = 0;
-
- /* one time to get the size needed */
- len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V1,
- logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0,
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- if (size_only)
- return buflen;
-
- /* malloc the space needed */
- if ( (*buf=(uint8*)malloc(len)) == NULL) {
- DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
- return (-1);
- }
+ StrnCpy (sampass->dir_drive, dir_drive, sizeof(sampass->dir_drive)-1);
- /* now for the real call to tdb_pack() */
- buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V1,
- logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0,
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- /* check to make sure we got it correct */
- if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
- (unsigned long)buflen, (unsigned long)len));
- /* error */
- SAFE_FREE (*buf);
- return (-1);
- }
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_DRIVE);
- return (buflen);
+ return True;
}
+/*********************************************************************
+ Set the user's home directory.
+ ********************************************************************/
-/**********************************************************************
-**********************************************************************/
-
-static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir, BOOL store)
{
- uid_t u_low, u_high;
- gid_t g_low, g_high;
-
- if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
+ if (!sampass)
+ return False;
+ *sampass->home_dir = '\0';
+ if (!homedir)
return False;
- }
-
- *low = (u_low < g_low) ? u_low : g_low;
- *high = (u_high < g_high) ? u_high : g_high;
+ StrnCpy (sampass->home_dir, homedir, sizeof(sampass->home_dir)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_SMBHOME);
+
return True;
}
-/******************************************************************
- Get the the non-algorithmic RID range if idmap range are defined
-******************************************************************/
+/*********************************************************************
+ Set the user's account description.
+ ********************************************************************/
-BOOL get_free_rid_range(uint32 *low, uint32 *high)
+BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
{
- uint32 id_low, id_high;
+ if (!sampass)
+ return False;
+ *sampass->acct_desc = '\0';
+ if (!acct_desc)
+ return False;
+
+ StrnCpy (sampass->acct_desc, acct_desc, sizeof(sampass->acct_desc)-1);
- if (!lp_enable_rid_algorithm()) {
- *low = BASE_RID;
- *high = (uint32)-1;
- }
+ return True;
+}
- if (!get_free_ugid_range(&id_low, &id_high)) {
+/*********************************************************************
+ Set the user's workstation allowed list.
+ ********************************************************************/
+
+BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
+{
+ if (!sampass)
+ return False;
+ *sampass->workstations = '\0';
+ if (!workstations)
return False;
- }
- *low = fallback_pdb_uid_to_user_rid(id_low);
- if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
- *high = (uint32)-1;
- } else {
- *high = fallback_pdb_uid_to_user_rid(id_high);
- }
+ StrnCpy (sampass->workstations, workstations, sizeof(sampass->workstations)-1);
return True;
}
/*********************************************************************
- Update the bad password count checking the AP_RESET_COUNT_TIME
-*********************************************************************/
+ Set the user's dial string.
+ ********************************************************************/
-BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
+BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
{
- time_t LastBadPassword;
- uint16 BadPasswordCount;
- uint32 resettime;
-
- if (!sampass) return False;
-
- BadPasswordCount = pdb_get_bad_password_count(sampass);
- if (!BadPasswordCount) {
- DEBUG(9, ("No bad password attempts.\n"));
- return True;
- }
-
- if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
- DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
+ if (!sampass)
+ return False;
+ *sampass->munged_dial = '\0';
+ if (!munged_dial)
return False;
- }
-
- /* First, check if there is a reset time to compare */
- if ((resettime == (uint32) -1) || (resettime == 0)) {
- DEBUG(9, ("No reset time, can't reset bad pw count\n"));
- return True;
- }
- LastBadPassword = pdb_get_bad_password_time(sampass);
- DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
- (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
- if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
- pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
- pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
- if (updated) *updated = True;
- }
+ StrnCpy (sampass->munged_dial, munged_dial, sizeof(sampass->munged_dial)-1);
return True;
}
/*********************************************************************
- Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
-*********************************************************************/
+ Set the user's NT hash.
+ ********************************************************************/
-BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
+BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
{
- uint32 duration;
- time_t LastBadPassword;
+ if (!sampass)
+ return False;
+
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sampass, time(NULL));
- if (!sampass) return False;
-
- if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
- DEBUG(9, ("Account not autolocked, no check needed\n"));
+ if (!pwd) {
+ /* Allow setting to NULL */
+ SAFE_FREE(sampass->nt_pw);
return True;
}
- if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
- DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
+ if (sampass->nt_pw!=NULL)
+ DEBUG(4,("pdb_set_nt_passwd: NT hash non NULL overwritting ?\n"));
+ else
+ sampass->nt_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
+
+ if (sampass->nt_pw==NULL)
return False;
- }
- /* First, check if there is a duration to compare */
- if ((duration == (uint32) -1) || (duration == 0)) {
- DEBUG(9, ("No reset duration, can't reset autolock\n"));
- return True;
- }
-
- LastBadPassword = pdb_get_bad_password_time(sampass);
- DEBUG(7, ("LastBadPassword=%d, duration=%d, current time =%d.\n",
- (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
- if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
- pdb_set_acct_ctrl(sampass,
- pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
- PDB_CHANGED);
- pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
- pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
- if (updated) *updated = True;
- }
-
+ memcpy (sampass->nt_pw, pwd, 16);
+
return True;
}
/*********************************************************************
- Increment the bad_password_count
-*********************************************************************/
+ Set the user's LM hash.
+ ********************************************************************/
-BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
{
- uint32 account_policy_lockout;
- BOOL autolock_updated = False, badpw_updated = False;
-
if (!sampass)
return False;
- /* Retrieve the account lockout policy */
- if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
- &account_policy_lockout)) {
- DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
- return False;
- }
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sampass, time(NULL));
- /* If there is no policy, we don't need to continue checking */
- if (!account_policy_lockout) {
- DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
+ if (!pwd) {
+ /* Allow setting to NULL */
+ SAFE_FREE(sampass->lm_pw);
return True;
}
-
- /* Check if the autolock needs to be cleared */
- if (!pdb_update_autolock_flag(sampass, &autolock_updated))
+
+ if (sampass->lm_pw!=NULL)
+ DEBUG(4,("pdb_set_lanman_passwd: LM hash non NULL overwritting ?\n"));
+ else
+ sampass->lm_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
+
+ if (sampass->lm_pw==NULL)
return False;
- /* Check if the badpw count needs to be reset */
- if (!pdb_update_bad_password_count(sampass, &badpw_updated))
- return False;
+ memcpy (sampass->lm_pw, pwd, 16);
- /*
- Ok, now we can assume that any resetting that needs to be
- done has been done, and just get on with incrementing
- and autolocking if necessary
- */
+ return True;
+}
- pdb_set_bad_password_count(sampass,
- pdb_get_bad_password_count(sampass)+1,
- PDB_CHANGED);
- pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
+/*********************************************************************
+ Set the user's PLAINTEXT password. Used as an interface to the above.
+ NB. The plaintext is in UNIX character set. Must be converted to DOS
+ codepage.
+ ********************************************************************/
+BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
+{
+ uchar new_lanman_p16[16];
+ uchar new_nt_p16[16];
+ fstring dos_plaintext;
- if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
- return True;
+ if (!sampass || !plaintext)
+ return False;
+
+ fstrcpy(dos_plaintext, unix_to_dos_static(plaintext));
+
+ nt_lm_owf_gen (dos_plaintext, new_nt_p16, new_lanman_p16);
- if (!pdb_set_acct_ctrl(sampass,
- pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
- PDB_CHANGED)) {
- DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
+ if (!pdb_set_nt_passwd (sampass, new_nt_p16))
+ return False;
+
+ if (!pdb_set_lanman_passwd (sampass, new_lanman_p16))
return False;
- }
return True;
}
+BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn)
+{
+ if (!sampass)
+ return False;
-/**
- * Allocate and initialise buffer from SAM_TRUST_PASSWD
- *
- * @param trust trust structure's pointer address
- * @return nt status code
- **/
+ sampass->unknown_3 = unkn;
+ return True;
+}
-size_t pdb_init_buffer_from_trustpw(TALLOC_CTX *mem_ctx, char** buf, const SAM_TRUST_PASSWD *trust)
+BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn)
{
- size_t len, buflen;
+ if (!sampass)
+ return False;
- if (!mem_ctx || !trust)
- return 0;
+ sampass->unknown_5 = unkn;
+ return True;
+}
- /* flags must be defined (ie. not null) */
- if (!pdb_get_tp_flags(trust)) {
- return 0;
- }
+BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn)
+{
+ if (!sampass)
+ return False;
- /* calculate length of the storage buffer */
- len = tdb_trustpw_pack(trust, NULL, 0);
+ sampass->unknown_6 = unkn;
+ return True;
+}
- *buf = (char*)talloc(mem_ctx, len);
- if (!(*buf)) {
- return 0;
- }
+BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
+{
+ if (!sampass)
+ return False;
- /* pack the structure in allocated buffer */
- buflen = tdb_trustpw_pack(trust, *buf, len);
-
- if (buflen != len) {
- return 0;
+ if (!hours) {
+ memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
+ return True;
}
+
+ memcpy (sampass->hours, hours, MAX_HOURS_LEN);
- return buflen;
+ return True;
}
+/***************************************************************************
+ Search by uid. Wrapper around pdb_getsampwnam()
+ **************************************************************************/
-/**
- * Allocate and initialise buffer from SAM_TRUST_PASSWD
- *
- * @param trust trust structure's pointer address (it's up to caller
- * to free an allocated structure)
- * @param buf
- * @param buf_len
- * @return nt status code
- **/
-
-BOOL pdb_init_trustpw_from_buffer(SAM_TRUST_PASSWD *trust, const char** buf, size_t buf_len)
+BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
{
- if (!trust || !buf)
+ struct passwd *pw;
+ fstring name;
+
+ if (user==NULL) {
+ DEBUG(0,("pdb_getsampwuid: SAM_ACCOUNT is NULL.\n"));
+ return False;
+ }
+
+ /*
+ * Never trust the uid in the passdb. Lookup the username first
+ * and then lokup the user by name in the sam.
+ */
+
+ if ((pw=sys_getpwuid(uid)) == NULL) {
+ DEBUG(0,("pdb_getsampwuid: getpwuid(%u) return NULL. User does not exist in Unix accounts!\n",
+ (unsigned int)uid));
return False;
+ }
- tdb_trustpw_unpack(trust, *buf, buf_len);
- return True;
+ fstrcpy (name, pw->pw_name);
+
+ return pdb_getsampwnam (user, name);
+
}
+
diff --git a/source/passdb/passgrp.c b/source/passdb/passgrp.c
new file mode 100755
index 00000000000..fe5b181e33c
--- /dev/null
+++ b/source/passdb/passgrp.c
@@ -0,0 +1,218 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ * NOTE. All these functions are abstracted into a structure
+ * that points to the correct function for the selected database. JRA.
+ *
+ * the API does NOT fill in the gaps if you set an API function
+ * to NULL: it will deliberately attempt to call the NULL function.
+ *
+ */
+
+static struct passgrp_ops *pwgrp_ops;
+
+/***************************************************************
+ Initialise the passgrp operations.
+***************************************************************/
+
+BOOL initialise_passgrp_db(void)
+{
+ if (pwgrp_ops)
+ {
+ return True;
+ }
+
+#ifdef WITH_NISPLUS
+ pwgrp_ops = nisplus_initialise_password_grp();
+#elif defined(WITH_LDAP)
+ pwgrp_ops = ldap_initialize_password_grp();
+#else
+ pwgrp_ops = file_initialise_password_grp();
+#endif
+
+ return (pwgrp_ops != NULL);
+}
+
+/*
+ * Functions that return/manipulate a struct smb_passwd.
+ */
+
+/************************************************************************
+ Utility function to search smb passwd by rid.
+*************************************************************************/
+
+struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ return iterate_getsmbgrpuid(pwdb_user_rid_to_uid(user_rid),
+ grps, num_grps, alss, num_alss);
+}
+
+/************************************************************************
+ Utility function to search smb passwd by uid. use this if your database
+ does not have search facilities.
+*************************************************************************/
+
+struct smb_passwd *iterate_getsmbgrpuid(uid_t smb_userid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ struct smb_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
+
+ /* Open the smb password database - not for update. */
+ fp = startsmbgrpent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open smb passgrp database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->smb_userid != smb_userid)
+ ;
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
+ }
+
+ endsmbgrpent(fp);
+ return pwd;
+}
+
+/************************************************************************
+ Utility function to search smb passwd by name. use this if your database
+ does not have search facilities.
+*************************************************************************/
+
+struct smb_passwd *iterate_getsmbgrpnam(char *name,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ struct smb_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by name: %s\n", name));
+
+ /* Open the passgrp file - not for update. */
+ fp = startsmbgrpent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open smb passgrp database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && !strequal(pwd->smb_name, name))
+ ;
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by name: %s\n", name));
+ }
+
+ endsmbgrpent(fp);
+ return pwd;
+}
+
+/***************************************************************
+ Start to enumerate the smb or sam passwd list. Returns a void pointer
+ to ensure no modification outside this module.
+
+ Note that currently it is being assumed that a pointer returned
+ from this function may be used to enumerate struct sam_passwd
+ entries as well as struct smb_passwd entries. This may need
+ to change. JRA.
+
+****************************************************************/
+
+void *startsmbgrpent(BOOL update)
+{
+ return pwgrp_ops->startsmbgrpent(update);
+}
+
+/***************************************************************
+ End enumeration of the smb or sam passwd list.
+
+ Note that currently it is being assumed that a pointer returned
+ from this function may be used to enumerate struct sam_passwd
+ entries as well as struct smb_passwd entries. This may need
+ to change. JRA.
+
+****************************************************************/
+
+void endsmbgrpent(void *vp)
+{
+ pwgrp_ops->endsmbgrpent(vp);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smb passwd list.
+ *************************************************************************/
+
+struct smb_passwd *getsmbgrpent(void *vp,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ return pwgrp_ops->getsmbgrpent(vp, grps, num_grps, alss, num_alss);
+}
+
+/************************************************************************
+ Routine to search smb passwd by name.
+*************************************************************************/
+
+struct smb_passwd *getsmbgrpnam(char *name,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ return pwgrp_ops->getsmbgrpnam(name, grps, num_grps, alss, num_alss);
+}
+
+/************************************************************************
+ Routine to search smb passwd by user rid.
+*************************************************************************/
+
+struct smb_passwd *getsmbgrprid(uint32 user_rid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ return pwgrp_ops->getsmbgrprid(user_rid, grps, num_grps, alss, num_alss);
+}
+
+/************************************************************************
+ Routine to search smb passwd by uid.
+*************************************************************************/
+
+struct smb_passwd *getsmbgrpuid(uid_t smb_userid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss)
+{
+ return pwgrp_ops->getsmbgrpuid(smb_userid, grps, num_grps, alss, num_alss);
+}
+
diff --git a/source/passdb/pdb_compat.c b/source/passdb/pdb_compat.c
deleted file mode 100644
index abd572a7c14..00000000000
--- a/source/passdb/pdb_compat.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAM_ACCOUNT access routines
- Copyright (C) Jeremy Allison 1996-2001
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Gerald (Jerry) Carter 2000-2001
- Copyright (C) Andrew Bartlett 2001-2002
- Copyright (C) Stefan (metze) Metzmacher 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
-{
- uint32 u_rid;
-
- if (sampass)
- if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_user_sid(sampass),&u_rid))
- return u_rid;
-
- return (0);
-}
-
-uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
-{
- uint32 g_rid;
-
- if (sampass)
- if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_group_sid(sampass),&g_rid))
- return g_rid;
- return (0);
-}
-
-BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid, enum pdb_value_state flag)
-{
- DOM_SID u_sid;
- const DOM_SID *global_sam_sid;
-
- if (!sampass)
- return False;
-
- if (!(global_sam_sid = get_global_sam_sid())) {
- DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
- return False;
- }
-
- sid_copy(&u_sid, global_sam_sid);
-
- if (!sid_append_rid(&u_sid, rid))
- return False;
-
- if (!pdb_set_user_sid(sampass, &u_sid, flag))
- return False;
-
- DEBUG(10, ("pdb_set_user_sid_from_rid:\n\tsetting user sid %s from rid %d\n",
- sid_string_static(&u_sid),rid));
-
- return True;
-}
-
-BOOL pdb_set_group_sid_from_rid (SAM_ACCOUNT *sampass, uint32 grid, enum pdb_value_state flag)
-{
- DOM_SID g_sid;
- const DOM_SID *global_sam_sid;
-
- if (!sampass)
- return False;
-
- if (!(global_sam_sid = get_global_sam_sid())) {
- DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n"));
- return False;
- }
-
- sid_copy(&g_sid, global_sam_sid);
-
- if (!sid_append_rid(&g_sid, grid))
- return False;
-
- if (!pdb_set_group_sid(sampass, &g_sid, flag))
- return False;
-
- DEBUG(10, ("pdb_set_group_sid_from_rid:\n\tsetting group sid %s from rid %d\n",
- sid_string_static(&g_sid), grid));
-
- return True;
-}
-
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
deleted file mode 100644
index 1440a2238da..00000000000
--- a/source/passdb/pdb_get_set.c
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAM_ACCOUNT access routines
- Copyright (C) Jeremy Allison 1996-2001
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Gerald (Jerry) Carter 2000-2001
- Copyright (C) Andrew Bartlett 2001-2002
- Copyright (C) Stefan (metze) Metzmacher 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-/**
- * @todo Redefine this to NULL, but this changes the API because
- * much of samba assumes that the pdb_get...() funtions
- * return pstrings. (ie not null-pointers).
- * See also pdb_fill_default_sam().
- */
-
-#define PDB_NOT_QUITE_NULL ""
-
-/*********************************************************************
- Collection of get...() functions for SAM_ACCOUNT.
- ********************************************************************/
-
-uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.acct_ctrl);
- else
- return (ACB_DISABLED);
-}
-
-time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.logon_time);
- else
- return (0);
-}
-
-time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.logoff_time);
- else
- return (-1);
-}
-
-time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.kickoff_time);
- else
- return (-1);
-}
-
-time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.bad_password_time);
- else
- return (-1);
-}
-
-time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.pass_last_set_time);
- else
- return (-1);
-}
-
-time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.pass_can_change_time);
- else
- return (-1);
-}
-
-time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.pass_must_change_time);
- else
- return (-1);
-}
-
-uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.logon_divs);
- else
- return (-1);
-}
-
-uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.hours_len);
- else
- return (-1);
-}
-
-const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.hours);
- else
- return (NULL);
-}
-
-const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass)
-{
- if (sampass) {
- SMB_ASSERT((!sampass->private.nt_pw.data)
- || sampass->private.nt_pw.length == NT_HASH_LEN);
- return ((uint8*)sampass->private.nt_pw.data);
- }
- else
- return (NULL);
-}
-
-const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
-{
- if (sampass) {
- SMB_ASSERT((!sampass->private.lm_pw.data)
- || sampass->private.lm_pw.length == LM_HASH_LEN);
- return ((uint8*)sampass->private.lm_pw.data);
- }
- else
- return (NULL);
-}
-
-/* Return the plaintext password if known. Most of the time
- it isn't, so don't assume anything magic about this function.
-
- Used to pass the plaintext to passdb backends that might
- want to store more than just the NTLM hashes.
-*/
-const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
-{
- if (sampass) {
- return (sampass->private.plaintext_pw);
- }
- else
- return (NULL);
-}
-const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return &sampass->private.user_sid;
- else
- return (NULL);
-}
-
-const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return &sampass->private.group_sid;
- else
- return (NULL);
-}
-
-/**
- * Get flags showing what is initalised in the SAM_ACCOUNT
- * @param sampass the SAM_ACCOUNT in question
- * @return the flags indicating the members initialised in the struct.
- **/
-
-enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element)
-{
- enum pdb_value_state ret = PDB_DEFAULT;
-
- if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags)
- return ret;
-
- if (bitmap_query(sampass->private.set_flags, element)) {
- DEBUG(11, ("element %d: SET\n", element));
- ret = PDB_SET;
- }
-
- if (bitmap_query(sampass->private.change_flags, element)) {
- DEBUG(11, ("element %d: CHANGED\n", element));
- ret = PDB_CHANGED;
- }
-
- if (ret == PDB_DEFAULT) {
- DEBUG(11, ("element %d: DEFAULT\n", element));
- }
-
- return ret;
-}
-
-const char* pdb_get_username (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.username);
- else
- return (NULL);
-}
-
-const char* pdb_get_domain (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.domain);
- else
- return (NULL);
-}
-
-const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.nt_username);
- else
- return (NULL);
-}
-
-const char* pdb_get_fullname (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.full_name);
- else
- return (NULL);
-}
-
-const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.home_dir);
- else
- return (NULL);
-}
-
-const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.unix_home_dir);
- else
- return (NULL);
-}
-
-const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.dir_drive);
- else
- return (NULL);
-}
-
-const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.logon_script);
- else
- return (NULL);
-}
-
-const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.profile_path);
- else
- return (NULL);
-}
-
-const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.acct_desc);
- else
- return (NULL);
-}
-
-const char* pdb_get_workstations (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.workstations);
- else
- return (NULL);
-}
-
-const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.unknown_str);
- else
- return (NULL);
-}
-
-const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.munged_dial);
- else
- return (NULL);
-}
-
-uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.bad_password_count);
- else
- return 0;
-}
-
-uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.logon_count);
- else
- return 0;
-}
-
-uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.unknown_6);
- else
- return (-1);
-}
-
-void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods)
-{
- if (sampass && my_methods == sampass->private.backend_private_methods)
- return sampass->private.backend_private_data;
- else
- return NULL;
-}
-
-/*********************************************************************
- Collection of set...() functions for SAM_ACCOUNT.
- ********************************************************************/
-
-BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.acct_ctrl = acct_ctrl;
-
- return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
-}
-
-BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.logon_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
-}
-
-BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.logoff_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
-}
-
-BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.kickoff_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
-}
-
-BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime,
- enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.bad_password_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
-}
-
-BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.pass_can_change_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
-}
-
-BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.pass_must_change_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
-}
-
-BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.pass_last_set_time = mytime;
-
- return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
-}
-
-BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.hours_len = len;
-
- return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
-}
-
-BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.logon_divs = hours;
-
- return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
-}
-
-/**
- * Set flags showing what is initalised in the SAM_ACCOUNT
- * @param sampass the SAM_ACCOUNT in question
- * @param flag The *new* flag to be set. Old flags preserved
- * this flag is only added.
- **/
-
-BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
-{
- if (!sampass || !sampass->mem_ctx)
- return False;
-
- if (!sampass->private.set_flags) {
- if ((sampass->private.set_flags =
- bitmap_talloc(sampass->mem_ctx,
- PDB_COUNT))==NULL) {
- DEBUG(0,("bitmap_talloc failed\n"));
- return False;
- }
- }
- if (!sampass->private.change_flags) {
- if ((sampass->private.change_flags =
- bitmap_talloc(sampass->mem_ctx,
- PDB_COUNT))==NULL) {
- DEBUG(0,("bitmap_talloc failed\n"));
- return False;
- }
- }
-
- switch(value_flag) {
- case PDB_CHANGED:
- if (!bitmap_set(sampass->private.change_flags, element)) {
- DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
- return False;
- }
- if (!bitmap_set(sampass->private.set_flags, element)) {
- DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
- return False;
- }
- DEBUG(11, ("element %d -> now CHANGED\n", element));
- break;
- case PDB_SET:
- if (!bitmap_clear(sampass->private.change_flags, element)) {
- DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
- return False;
- }
- if (!bitmap_set(sampass->private.set_flags, element)) {
- DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
- return False;
- }
- DEBUG(10, ("element %d -> now SET\n", element));
- break;
- case PDB_DEFAULT:
- default:
- if (!bitmap_clear(sampass->private.change_flags, element)) {
- DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
- return False;
- }
- if (!bitmap_clear(sampass->private.set_flags, element)) {
- DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
- return False;
- }
- DEBUG(11, ("element %d -> now DEFAULT\n", element));
- break;
- }
-
- return True;
-}
-
-BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
-{
- if (!sampass || !u_sid)
- return False;
-
- sid_copy(&sampass->private.user_sid, u_sid);
-
- DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
- sid_string_static(&sampass->private.user_sid)));
-
- return pdb_set_init_flags(sampass, PDB_USERSID, flag);
-}
-
-BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag)
-{
- DOM_SID new_sid;
-
- if (!sampass || !u_sid)
- return False;
-
- DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
- u_sid));
-
- if (!string_to_sid(&new_sid, u_sid)) {
- DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
- return False;
- }
-
- if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
- DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
- return False;
- }
-
- return True;
-}
-
-BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
-{
- if (!sampass || !g_sid)
- return False;
-
- sid_copy(&sampass->private.group_sid, g_sid);
-
- DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
- sid_string_static(&sampass->private.group_sid)));
-
- return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
-}
-
-BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag)
-{
- DOM_SID new_sid;
- if (!sampass || !g_sid)
- return False;
-
- DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
- g_sid));
-
- if (!string_to_sid(&new_sid, g_sid)) {
- DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
- return False;
- }
-
- if (!pdb_set_group_sid(sampass, &new_sid, flag)) {
- DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
- return False;
- }
- return True;
-}
-
-/*********************************************************************
- Set the user's UNIX name.
- ********************************************************************/
-
-BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (username) {
- DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
- (sampass->private.username)?(sampass->private.username):"NULL"));
-
- sampass->private.username = talloc_strdup(sampass->mem_ctx, username);
-
- if (!sampass->private.username) {
- DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.username = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
-}
-
-/*********************************************************************
- Set the domain name.
- ********************************************************************/
-
-BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (domain) {
- DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
- (sampass->private.domain)?(sampass->private.domain):"NULL"));
-
- sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain);
-
- if (!sampass->private.domain) {
- DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.domain = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
-}
-
-/*********************************************************************
- Set the user's NT name.
- ********************************************************************/
-
-BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (nt_username) {
- DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
- (sampass->private.nt_username)?(sampass->private.nt_username):"NULL"));
-
- sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username);
-
- if (!sampass->private.nt_username) {
- DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.nt_username = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
-}
-
-/*********************************************************************
- Set the user's full name.
- ********************************************************************/
-
-BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (full_name) {
- DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
- (sampass->private.full_name)?(sampass->private.full_name):"NULL"));
-
- sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name);
-
- if (!sampass->private.full_name) {
- DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.full_name = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
-}
-
-/*********************************************************************
- Set the user's logon script.
- ********************************************************************/
-
-BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (logon_script) {
- DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
- (sampass->private.logon_script)?(sampass->private.logon_script):"NULL"));
-
- sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
-
- if (!sampass->private.logon_script) {
- DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.logon_script = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
-}
-
-/*********************************************************************
- Set the user's profile path.
- ********************************************************************/
-
-BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (profile_path) {
- DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
- (sampass->private.profile_path)?(sampass->private.profile_path):"NULL"));
-
- sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
-
- if (!sampass->private.profile_path) {
- DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.profile_path = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
-}
-
-/*********************************************************************
- Set the user's directory drive.
- ********************************************************************/
-
-BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (dir_drive) {
- DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
- (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL"));
-
- sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
-
- if (!sampass->private.dir_drive) {
- DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.dir_drive = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
-}
-
-/*********************************************************************
- Set the user's home directory.
- ********************************************************************/
-
-BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (home_dir) {
- DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
- (sampass->private.home_dir)?(sampass->private.home_dir):"NULL"));
-
- sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
-
- if (!sampass->private.home_dir) {
- DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.home_dir = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
-}
-
-/*********************************************************************
- Set the user's unix home directory.
- ********************************************************************/
-
-BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (unix_home_dir) {
- DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
- (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
-
- sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx,
- unix_home_dir);
-
- if (!sampass->private.unix_home_dir) {
- DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag);
-}
-
-/*********************************************************************
- Set the user's account description.
- ********************************************************************/
-
-BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (acct_desc) {
- sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
-
- if (!sampass->private.acct_desc) {
- DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.acct_desc = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
-}
-
-/*********************************************************************
- Set the user's workstation allowed list.
- ********************************************************************/
-
-BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (workstations) {
- DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
- (sampass->private.workstations)?(sampass->private.workstations):"NULL"));
-
- sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations);
-
- if (!sampass->private.workstations) {
- DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.workstations = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
-}
-
-/*********************************************************************
- Set the user's 'unknown_str', whatever the heck this actually is...
- ********************************************************************/
-
-BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (unknown_str) {
- sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
-
- if (!sampass->private.unknown_str) {
- DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.unknown_str = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
-}
-
-/*********************************************************************
- Set the user's dial string.
- ********************************************************************/
-
-BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (munged_dial) {
- sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
-
- if (!sampass->private.munged_dial) {
- DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.munged_dial = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
-}
-
-/*********************************************************************
- Set the user's NT hash.
- ********************************************************************/
-
-BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- data_blob_clear_free(&sampass->private.nt_pw);
-
- if (pwd) {
- sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN);
- } else {
- sampass->private.nt_pw = data_blob(NULL, 0);
- }
-
- return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
-}
-
-/*********************************************************************
- Set the user's LM hash.
- ********************************************************************/
-
-BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- data_blob_clear_free(&sampass->private.lm_pw);
-
- if (pwd) {
- sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN);
- } else {
- sampass->private.lm_pw = data_blob(NULL, 0);
- }
-
- return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
-}
-
-/*********************************************************************
- Set the user's plaintext password only (base procedure, see helper
- below)
- ********************************************************************/
-
-BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (password) {
- if (sampass->private.plaintext_pw!=NULL)
- memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1);
-
- sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password);
-
- if (!sampass->private.plaintext_pw) {
- DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private.plaintext_pw = NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
-}
-
-BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.bad_password_count = bad_password_count;
-
- return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
-}
-
-BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.logon_count = logon_count;
-
- return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
-}
-
-BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.unknown_6 = unkn;
-
- return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
-}
-
-BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (!hours) {
- memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN);
- return True;
- }
-
- memcpy (sampass->private.hours, hours, MAX_HOURS_LEN);
-
- return pdb_set_init_flags(sampass, PDB_HOURS, flag);
-}
-
-BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
- void (*free_fn)(void **),
- const struct pdb_methods *my_methods,
- enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
- sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
- }
-
- sampass->private.backend_private_data = private_data;
- sampass->private.backend_private_data_free_fn = free_fn;
- sampass->private.backend_private_methods = my_methods;
-
- return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
-}
-
-
-/* Helpful interfaces to the above */
-
-/*********************************************************************
- Sets the last changed times and must change times for a normal
- password change.
- ********************************************************************/
-
-BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
-{
- uint32 expire;
- uint32 min_age;
-
- if (!sampass)
- return False;
-
- if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
- return False;
-
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
- || (expire==(uint32)-1) || (expire == 0)) {
- if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
- return False;
- } else {
- if (!pdb_set_pass_must_change_time (sampass,
- pdb_get_pass_last_set_time(sampass)
- + expire, PDB_CHANGED))
- return False;
- }
-
- if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age)
- || (min_age==(uint32)-1)) {
- if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
- return False;
- } else {
- if (!pdb_set_pass_can_change_time (sampass,
- pdb_get_pass_last_set_time(sampass)
- + min_age, PDB_CHANGED))
- return False;
- }
- return True;
-}
-
-/*********************************************************************
- Set the user's PLAINTEXT password. Used as an interface to the above.
- Also sets the last change time to NOW.
- ********************************************************************/
-
-BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
-{
- uchar new_lanman_p16[16];
- uchar new_nt_p16[16];
-
- if (!sampass || !plaintext)
- return False;
-
- /* Calculate the MD4 hash (NT compatible) of the password */
- E_md4hash(plaintext, new_nt_p16);
-
- if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
- return False;
-
- if (!E_deshash(plaintext, new_lanman_p16)) {
- /* E_deshash returns false for 'long' passwords (> 14
- DOS chars). This allows us to match Win2k, which
- does not store a LM hash for these passwords (which
- would reduce the effective password length to 14 */
-
- if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
- return False;
- } else {
- if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
- return False;
- }
-
- if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
- return False;
-
- if (!pdb_set_pass_changed_now (sampass))
- return False;
-
- return True;
-}
-
-/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
-uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass)
-{
- /* value set to all for testing */
- return 0x00ffffff;
-}
-
-
-/*
- * Get/set functions for SAM_TRUST_PASSWD.
- */
-
-const uint16 pdb_get_tp_flags(const SAM_TRUST_PASSWD *trust)
-{
- if (!trust)
- return -1;
-
- return trust->private.flags;
-}
-
-const smb_ucs2_t* pdb_get_tp_domain_name(const SAM_TRUST_PASSWD *trust)
-{
- smb_ucs2_t name[32];
-
- if (!trust)
- return NULL;
-
- /* ensure null-termination of unicode domain name */
- strncpy_w(name, trust->private.uni_name, 32);
- name[trust->private.uni_name_len] = 0;
-
- return strdup_w(name);
-}
-
-const char* pdb_get_tp_pass(const SAM_TRUST_PASSWD *trust)
-{
- if (!trust)
- return NULL;
-
- return trust->private.pass;
-}
-
-
-time_t pdb_get_tp_mod_time(const SAM_TRUST_PASSWD *trust)
-{
- if (!trust)
- return -1;
-
- return trust->private.mod_time;
-}
-
-const DOM_SID* pdb_get_tp_domain_sid(const SAM_TRUST_PASSWD *trust)
-{
- if (!trust)
- return NULL;
-
- return &trust->private.domain_sid;
-}
-
-
-BOOL pdb_set_tp_domain_name(SAM_TRUST_PASSWD *trust, const smb_ucs2_t *dom_name)
-{
- if (!trust || !dom_name)
- return False;
-
- trust->private.uni_name_len = strnlen_w(dom_name, 32);
- strncpy_w(trust->private.uni_name, dom_name, trust->private.uni_name_len);
-
- return True;
-}
-
-BOOL pdb_set_tp_flags(SAM_TRUST_PASSWD *trust, uint16 t_flags)
-{
- if (!trust)
- return False;
-
- trust->private.flags = t_flags;
- return True;
-}
-
-BOOL pdb_set_tp_pass(SAM_TRUST_PASSWD *trust, const char *pass)
-{
- if (!trust || !pass)
- return False;
-
- strncpy(trust->private.pass, pass, sizeof(trust->private.pass));
- return True;
-}
-
-BOOL pdb_set_tp_mod_time(SAM_TRUST_PASSWD *trust, time_t mod_time)
-{
- if (!trust)
- return False;
-
- trust->private.mod_time = mod_time;
- return True;
-}
-
-BOOL pdb_set_tp_domain_sid(SAM_TRUST_PASSWD *trust, const DOM_SID *sid)
-{
- if (!trust || !sid)
- return False;
-
- sid_copy(&trust->private.domain_sid, sid);
- return True;
-}
diff --git a/source/passdb/pdb_guest.c b/source/passdb/pdb_guest.c
deleted file mode 100644
index 8c1d4c7b0fe..00000000000
--- a/source/passdb/pdb_guest.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 'Guest' password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- * Copyright (C) Andrew Bartlett 2003
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *sam_account, const char *sname)
-{
- const char *guest_account = lp_guestaccount();
-
- if (!sam_account || !sname) {
- DEBUG(0,("invalid name specified"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!methods) {
- DEBUG(0,("invalid methods\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (!strequal(guest_account, sname)) {
- return NT_STATUS_NO_SUCH_USER;
- }
-
- pdb_fill_default_sam(sam_account);
-
- if (!pdb_set_username(sam_account, guest_account, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_fullname(sam_account, guest_account, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_domain(sam_account, get_global_sam_name(), PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- return NT_STATUS_OK;
-}
-
-
-/***************************************************************************
- Search by rid
- **************************************************************************/
-
-static NTSTATUS guestsam_getsampwrid (struct pdb_methods *methods,
- SAM_ACCOUNT *sam_account, uint32 rid)
-{
- if (rid != DOMAIN_USER_RID_GUEST) {
- return NT_STATUS_NO_SUCH_USER;
- }
-
- if (!sam_account) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return guestsam_getsampwnam (methods, sam_account, lp_guestaccount());
-}
-
-static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
-{
- uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return NT_STATUS_NO_SUCH_USER;
-
- return guestsam_getsampwrid(my_methods, user, rid);
-}
-
-
-/***************************************************************************
- Updates a SAM_ACCOUNT
-
- This isn't a particulary practical option for pdb_guest. We certainly don't
- want to twidde the filesystem, so what should we do?
-
- Current plan is to transparently add the account. It should appear
- as if the pdb_guest version was modified, but its actually stored somehwere.
- ****************************************************************************/
-
-static NTSTATUS guestsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
-#if 1 /* JERRY */
-
- /* apparently thr build farm relies upon this heavior :-( */
-
- return methods->parent->pdb_add_sam_account(methods->parent, newpwd);
-#else
- /* I don't think we should allow any modification of
- the guest account as SID will could messed up with
- the smbpasswd backend --jerry */
-
- return NT_STATUS_NOT_IMPLEMENTED;
-#endif
-}
-
-NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_context specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "guestsam";
-
- (*pdb_method)->getsampwnam = guestsam_getsampwnam;
- (*pdb_method)->getsampwsid = guestsam_getsampwsid;
- (*pdb_method)->update_sam_account = guestsam_update_sam_account;
-
- /* we should do no group mapping here */
- (*pdb_method)->getgrsid = pdb_nop_getgrsid;
- (*pdb_method)->getgrgid = pdb_nop_getgrgid;
- (*pdb_method)->getgrnam = pdb_nop_getgrnam;
- (*pdb_method)->add_group_mapping_entry = pdb_nop_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = pdb_nop_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = pdb_nop_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = pdb_nop_enum_group_mapping;
-
- /* we do not handle groups in guest backend */
-/* FIXME
- (*pdb_method)->get_group_info_by_sid = pdb_nop_get_group_info_by_sid;
- (*pdb_method)->get_group_list = pdb_nop_get_group_list;
- (*pdb_method)->get_group_sids = pdb_nop_get_group_sids;
- (*pdb_method)->add_group = pdb_nop_add_group;
- (*pdb_method)->update_group = pdb_nop_update_group;
- (*pdb_method)->delete_group = pdb_nop_delete_group;
- (*pdb_method)->add_sid_to_group = pdb_nop_add_sid_to_group;
- (*pdb_method)->remove_sid_from_group = pdb_nop_remove_sid_from_group;
- (*pdb_method)->get_group_info_by_name = pdb_nop_get_group_info_by_name;
- (*pdb_method)->get_group_info_by_nt_name = pdb_nop_get_group_info_by_nt_name;
- (*pdb_method)->get_group_uids = pdb_nop_get_group_uids;
-*/
-
-
- /* There's not very much to initialise here */
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_guest_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "guest", pdb_init_guestsam);
-}
-
diff --git a/source/passdb/pdb_gums.c b/source/passdb/pdb_gums.c
deleted file mode 100644
index f34d3a94b5a..00000000000
--- a/source/passdb/pdb_gums.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * GUMS password backend for samba
- * Copyright (C) Simo Sorce 2003-2004
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
-#define BOOL_SET_OR_FAIL(func, label) do { if (!func) { DEBUG(0, ("%s: Setting sam object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
-
-struct gums_gw_data {
- GUMS_FUNCTIONS *fns;
- void *handle;
-};
-
-static NTSTATUS gums_object_to_sam_account(SAM_ACCOUNT *sa, GUMS_OBJECT *go)
-{
- NTSTATUS ret;
- NTTIME nt_time;
- DATA_BLOB pwd;
-
- if (!go || !sa)
- return NT_STATUS_INVALID_PARAMETER;
-/*
- if (!NT_STATUS_IS_OK(ret = pdb_init_sam(sa))) {
- DEBUG(0, ("gums_object_to_sam_account: error occurred while creating sam_account object!\n"));
- goto error;
- }
-*/
- if (gums_get_object_type(go) != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- BOOL_SET_OR_FAIL(pdb_set_acct_ctrl(sa, gums_get_user_acct_ctrl(go), PDB_SET), error);
-
- /* domain */
- /* unix_homedir ? */
-
- nt_time = gums_get_user_logon_time(go);
- BOOL_SET_OR_FAIL(pdb_set_logon_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- nt_time = gums_get_user_logoff_time(go);
- BOOL_SET_OR_FAIL(pdb_set_logoff_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- nt_time = gums_get_user_kickoff_time(go);
- BOOL_SET_OR_FAIL(pdb_set_kickoff_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- nt_time = gums_get_user_pass_last_set_time(go);
- BOOL_SET_OR_FAIL(pdb_set_pass_last_set_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- nt_time = gums_get_user_pass_can_change_time(go);
- BOOL_SET_OR_FAIL(pdb_set_pass_can_change_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- nt_time = gums_get_user_pass_must_change_time(go);
- BOOL_SET_OR_FAIL(pdb_set_pass_must_change_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_hours_len(sa, gums_get_user_hours_len(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_logon_divs(sa, gums_get_user_logon_divs(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_user_sid(sa, gums_get_object_sid(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_group_sid(sa, gums_get_user_pri_group(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_username(sa, gums_get_object_name(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_nt_username(sa, gums_get_object_name(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_fullname(sa, gums_get_user_fullname(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_logon_script(sa, gums_get_user_logon_script(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_profile_path(sa, gums_get_user_profile_path(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_dir_drive(sa, gums_get_user_dir_drive(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_homedir(sa, gums_get_user_homedir(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_acct_desc(sa, gums_get_object_description(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_workstations(sa, gums_get_user_workstations(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_unknown_str(sa, gums_get_user_unknown_str(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_munged_dial(sa, gums_get_user_munged_dial(go), PDB_SET), error);
-
- pwd = gums_get_user_nt_pwd(go);
- if (!pdb_set_nt_passwd(sa, pwd.data, PDB_SET)) {
- DEBUG(5, ("gums_object_to_sam_account: unable to set nt password"));
- data_blob_clear_free(&pwd);
- ret = NT_STATUS_UNSUCCESSFUL;
- goto error;
- }
- data_blob_clear_free(&pwd);
- pwd = gums_get_user_lm_pwd(go);
- if (!pdb_set_lanman_passwd(sa, pwd.data, PDB_SET)) {
- DEBUG(5, ("gums_object_to_sam_account: unable to set lanman password"));
- data_blob_clear_free(&pwd);
- ret = NT_STATUS_UNSUCCESSFUL;
- goto error;
- }
- data_blob_clear_free(&pwd);
-
- BOOL_SET_OR_FAIL(pdb_set_bad_password_count(sa, gums_get_user_bad_password_count(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_unknown_6(sa, gums_get_user_unknown_6(go), PDB_SET), error);
- BOOL_SET_OR_FAIL(pdb_set_hours(sa, gums_get_user_hours(go), PDB_SET), error);
-
- return NT_STATUS_OK;
-
-error:
- if (sa && (sa->free_fn)) {
- sa->free_fn(&sa);
- }
-
- return ret;
-}
-
-static NTSTATUS sam_account_to_gums_object(GUMS_OBJECT *go, SAM_ACCOUNT *sa)
-{
- NTSTATUS ret;
- NTTIME nt_time;
- DATA_BLOB pwd;
-
- if (!go || !sa)
- return NT_STATUS_INVALID_PARAMETER;
-
-/*
- ret = gums_create_object(go, GUMS_OBJ_NORMAL_USER);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("sam_account_to_gums_object: error occurred while creating gums object!\n"));
- goto error;
- }
-*/
-
- /* sec_desc */
-
- SET_OR_FAIL(gums_set_object_name(go, pdb_get_username(sa)), error);
-
- SET_OR_FAIL(gums_set_object_sid(go, pdb_get_user_sid(sa)), error);
- SET_OR_FAIL(gums_set_user_pri_group(go, pdb_get_group_sid(sa)), error);
-
- if (pdb_get_acct_desc(sa))
- SET_OR_FAIL(gums_set_object_description(go, pdb_get_acct_desc(sa)), error);
- if (pdb_get_fullname(sa))
- SET_OR_FAIL(gums_set_user_fullname(go, pdb_get_fullname(sa)), error);
- if (pdb_get_homedir(sa))
- SET_OR_FAIL(gums_set_user_homedir(go, pdb_get_homedir(sa)), error);
- if (pdb_get_dir_drive(sa))
- SET_OR_FAIL(gums_set_user_dir_drive(go, pdb_get_dir_drive(sa)), error);
- if (pdb_get_logon_script(sa))
- SET_OR_FAIL(gums_set_user_logon_script(go, pdb_get_logon_script(sa)), error);
- if (pdb_get_profile_path(sa))
- SET_OR_FAIL(gums_set_user_profile_path(go, pdb_get_profile_path(sa)), error);
- if (pdb_get_workstations(sa))
- SET_OR_FAIL(gums_set_user_workstations(go, pdb_get_workstations(sa)), error);
- if (pdb_get_unknown_str(sa))
- SET_OR_FAIL(gums_set_user_unknown_str(go, pdb_get_unknown_str(sa)), error);
- if (pdb_get_munged_dial(sa))
- SET_OR_FAIL(gums_set_user_munged_dial(go, pdb_get_munged_dial(sa)), error);
- SET_OR_FAIL(gums_set_user_logon_divs(go, pdb_get_logon_divs(sa)), error);
- if (pdb_get_hours(sa))
- SET_OR_FAIL(gums_set_user_hours(go, pdb_get_hours_len(sa), pdb_get_hours(sa)), error);
- SET_OR_FAIL(gums_set_user_bad_password_count(go, pdb_get_bad_password_count(sa)), error);
- SET_OR_FAIL(gums_set_user_unknown_6(go, pdb_get_unknown_6(sa)), error);
-
- unix_to_nt_time(&nt_time, pdb_get_logon_time(sa));
- SET_OR_FAIL(gums_set_user_logon_time(go, nt_time), error);
- unix_to_nt_time(&nt_time, pdb_get_logoff_time(sa));
- SET_OR_FAIL(gums_set_user_logoff_time(go, nt_time), error);
- unix_to_nt_time(&nt_time, pdb_get_kickoff_time(sa));
- SET_OR_FAIL(gums_set_user_kickoff_time(go, nt_time), error);
- unix_to_nt_time(&nt_time, pdb_get_pass_last_set_time(sa));
- SET_OR_FAIL(gums_set_user_pass_last_set_time(go, nt_time), error);
- unix_to_nt_time(&nt_time, pdb_get_pass_can_change_time(sa));
- SET_OR_FAIL(gums_set_user_pass_can_change_time(go, nt_time), error);
- unix_to_nt_time(&nt_time, pdb_get_pass_must_change_time(sa));
- SET_OR_FAIL(gums_set_user_pass_must_change_time(go, nt_time), error);
-
- pwd = data_blob(pdb_get_nt_passwd(sa), NT_HASH_LEN);
- ret = gums_set_user_nt_pwd(go, pwd);
- data_blob_clear_free(&pwd);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(5, ("sam_account_to_gums_object: failed to set nt password!\n"));
- goto error;
- }
- pwd = data_blob(pdb_get_lanman_passwd(sa), LM_HASH_LEN);
- ret = gums_set_user_lm_pwd(go, pwd);
- data_blob_clear_free(&pwd);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(5, ("sam_account_to_gums_object: failed to set lanman password!\n"));
- goto error;
- }
-
- SET_OR_FAIL(gums_set_user_acct_ctrl(go, pdb_get_acct_ctrl(sa)), error);
-
- return NT_STATUS_OK;
-
-error:
- gums_reset_object(go);
- return ret;
-}
-
-static NTSTATUS gums_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- return ggwd->fns->enumerate_objects_start(&(ggwd->handle), NULL, GUMS_OBJ_NORMAL_USER);
-}
-
-static NTSTATUS gums_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *account)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->enumerate_objects_get_next(&go, ggwd->handle))) {
- return ret;
- }
-
- ret = gums_object_to_sam_account(account, go);
-
- gums_destroy_object(&go);
- return ret;
-}
-
-static void gums_endsampwent(struct pdb_methods *methods)
-{
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- ggwd->fns->enumerate_objects_stop(ggwd->handle);
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS gums_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *account, const char *name)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!account || !name)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_name(&go, global_myname(), name, GUMS_OBJ_NORMAL_USER))) {
- DEBUG(10, ("gums_getsampwnam: unable to find account with name %s", name));
- return ret;
- }
-
- ret = gums_object_to_sam_account(account, go);
-
- gums_destroy_object(&go);
- return ret;
-}
-
-/***************************************************************************
- Search by SID
- **************************************************************************/
-
-static NTSTATUS gums_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT *account, const DOM_SID *sid)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!account || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_sid(&go, sid, GUMS_OBJ_NORMAL_USER))) {
- DEBUG(10, ("gums_getsampwsid: unable to find account with sid %s", sid_string_static(sid)));
- return ret;
- }
-
- ret = gums_object_to_sam_account(account, go);
-
- gums_destroy_object(&go);
- return ret;
-}
-
-/***************************************************************************
- Search by rid
- **************************************************************************/
-
-#if 0
-
-static NTSTATUS gums_getsampwrid (struct pdb_methods *methods,
- SAM_ACCOUNT *account, uint32 rid)
-{
- DOM_SID sid;
-
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- gums_getsampwsid(methods, account, &sid);
-
- return NT_STATUS_OK;
-}
-
-#endif
-
-/***************************************************************************
- Updates a SAM_ACCOUNT
-
- This isn't a particulary practical option for pdb_guest. We certainly don't
- want to twidde the filesystem, so what should we do?
-
- Current plan is to transparently add the account. It should appear
- as if the pdb_guest version was modified, but its actually stored somehwere.
- ****************************************************************************/
-
-static NTSTATUS gums_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!account)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_NORMAL_USER))) {
- DEBUG(0, ("gums_add_sam_account: error occurred while creating gums object!\n"));
- return ret;
- }
-
- if (!NT_STATUS_IS_OK(ret = sam_account_to_gums_object(go, account))) {
- DEBUG(0, ("gums_add_sam_account: error occurred while converting object!\n"));
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->set_object(go))) {
- DEBUG(0, ("gums_add_sam_account: unable to store account!\n"));
- goto done;
- }
-
-done:
- gums_destroy_object(&go);
- return ret;
-}
-
-static NTSTATUS gums_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!account)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_sid(&go, pdb_get_user_sid(account), GUMS_OBJ_NORMAL_USER))) {
- DEBUG(0, ("gums_update_sam_account: update on invalid account!\n"));
- return ret;
- }
-
- if (!NT_STATUS_IS_OK(ret = sam_account_to_gums_object(go, account))) {
- DEBUG(0, ("gums_update_sam_account: error occurred while converting object!\n"));
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->set_object(go))) {
- DEBUG(0, ("gums_update_sam_account: unable to store account!\n"));
- goto done;
- }
-
-done:
- gums_destroy_object(&go);
- return ret;
-}
-
-static NTSTATUS gums_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
-{
- NTSTATUS ret;
- struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
-
- if (!account)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = ggwd->fns->delete_object(pdb_get_user_sid(account)))) {
- DEBUG(0, ("gums_add_sam_account: unable to store account!\n"));
- }
-
- return ret;
-}
-
-
-static void free_gw_private_data(void **vp)
-{
- struct gums_gw_data *ggwd = (struct gums_gw_data *)vp;
- ggwd->fns->free_private_data(&(ggwd->fns->private_data));
- ggwd->fns = NULL;
- ggwd->handle = NULL;
- SAFE_FREE(vp);
-}
-
-NTSTATUS pdb_init_gums_gateway(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS ret;
- struct gums_gw_data *ggwd;
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_context specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(ret = gums_setup_backend(lp_gums_backend()))) {
- DEBUG(0, ("pdb_init_gums_gateway: initialization error!\n"));
- return ret;
- }
-
- ggwd = (struct gums_gw_data *)malloc(sizeof(struct gums_gw_data));
- if (!ggwd)
- return NT_STATUS_NO_MEMORY;
- memset(ggwd, 0, sizeof(struct gums_gw_data));
-
- if (!NT_STATUS_IS_OK(ret = get_gums_fns(&(ggwd->fns)))) {
- goto error;
- }
-
- if (!NT_STATUS_IS_OK(ret = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- goto error;
- }
-
- (*pdb_method)->name = "gums_gateway";
-
- (*pdb_method)->setsampwent = gums_setsampwent;
- (*pdb_method)->getsampwent = gums_getsampwent;
- (*pdb_method)->endsampwent = gums_endsampwent;
- (*pdb_method)->getsampwnam = gums_getsampwnam;
- (*pdb_method)->getsampwsid = gums_getsampwsid;
- (*pdb_method)->add_sam_account = gums_add_sam_account;
- (*pdb_method)->update_sam_account = gums_update_sam_account;
- (*pdb_method)->delete_sam_account = gums_delete_sam_account;
-
- /* we should do no group mapping here */
-/* (*pdb_method)->getgrsid = gums_getgrsid;
- (*pdb_method)->getgrgid = gums_getgrgid;
- (*pdb_method)->getgrnam = gums_getgrnam;
- (*pdb_method)->add_group_mapping_entry = gums_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = gums_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = gums_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = gums_enum_group_mapping;*/
-
- /* we do not handle groups in guest backend */
-/* FIXME
- (*pdb_method)->get_group_info_by_sid = gums_get_group_info_by_sid;
- (*pdb_method)->get_group_list = gums_get_group_list;
- (*pdb_method)->get_group_sids = gums_get_group_sids;
- (*pdb_method)->add_group = gums_add_group;
- (*pdb_method)->update_group = gums_update_group;
- (*pdb_method)->delete_group = gums_delete_group;
- (*pdb_method)->add_sid_to_group = gums_add_sid_to_group;
- (*pdb_method)->remove_sid_from_group = gums_remove_sid_from_group;
- (*pdb_method)->get_group_info_by_name = gums_get_group_info_by_name;
- (*pdb_method)->get_group_info_by_nt_name = gums_get_group_info_by_nt_name;
- (*pdb_method)->get_group_uids = gums_get_group_uids;
-*/
-
- (*pdb_method)->private_data = ggwd;
- (*pdb_method)->free_private_data = free_gw_private_data;
-
- return NT_STATUS_OK;
-
-error:
- SAFE_FREE(ggwd);
- return ret;
-}
-
-NTSTATUS pdb_gums_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "gums", pdb_init_gums_gateway);
-}
-
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
deleted file mode 100644
index 4156b1643cc..00000000000
--- a/source/passdb/pdb_interface.c
+++ /dev/null
@@ -1,1722 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Jelmer Vernooij 2002
- Copyright (C) SImo Sorce 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-static struct pdb_init_function_entry *backends = NULL;
-
-static void lazy_initialize_passdb(void)
-{
- static BOOL initialized = False;
- if(initialized)return;
- static_init_pdb;
- initialized = True;
-}
-
-static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
-
-/*******************************************************************
- Clean up uninitialised passwords. The only way to tell
- that these values are not 'real' is that they do not
- have a valid last set time. Instead, the value is fixed at 0.
- Therefore we use that as the key for 'is this a valid password'.
- However, it is perfectly valid to have a 'default' last change
- time, such LDAP with a missing attribute would produce.
-********************************************************************/
-
-static void pdb_force_pw_initialization(SAM_ACCOUNT *pass)
-{
- const char *lm_pwd, *nt_pwd;
-
- /* only reset a password if the last set time has been
- explicitly been set to zero. A default last set time
- is ignored */
-
- if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT)
- && (pdb_get_pass_last_set_time(pass) == 0) )
- {
-
- if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT)
- {
- lm_pwd = pdb_get_lanman_passwd(pass);
- if (lm_pwd)
- pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED);
- }
- if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT)
- {
- nt_pwd = pdb_get_nt_passwd(pass);
- if (nt_pwd)
- pdb_set_nt_passwd(pass, NULL, PDB_CHANGED);
- }
- }
-
- return;
-}
-
-NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init)
-{
- struct pdb_init_function_entry *entry = backends;
-
- if(version != PASSDB_INTERFACE_VERSION) {
- DEBUG(0,("Can't register passdb backend!\n"
- "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, "
- "while this version of samba uses version %d\n",
- version,PASSDB_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !init) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5,("Attempting to register passdb backend %s\n", name));
-
- /* Check for duplicates */
- if (pdb_find_backend_entry(name)) {
- DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct pdb_init_function_entry));
- entry->name = smb_xstrdup(name);
- entry->init = init;
-
- DLIST_ADD(backends, entry);
- DEBUG(5,("Successfully added passdb backend '%s'\n", name));
- return NT_STATUS_OK;
-}
-
-static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
-{
- struct pdb_init_function_entry *entry = backends;
-
- while(entry) {
- if (strcmp(entry->name, name)==0) return entry;
- entry = entry->next;
- }
-
- return NULL;
-}
-
-static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- context->pwent_methods = context->pdb_methods;
-
- if (!context->pwent_methods) {
- /* No passdbs at all */
- return ret;
- }
-
- while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) {
- context->pwent_methods = context->pwent_methods->next;
- if (context->pwent_methods == NULL)
- return NT_STATUS_UNSUCCESSFUL;
- }
- return ret;
-}
-
-static void context_endsampwent(struct pdb_context *context)
-{
- if ((!context)){
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return;
- }
-
- if (context->pwent_methods && context->pwent_methods->endsampwent)
- context->pwent_methods->endsampwent(context->pwent_methods);
-
- /* So we won't get strange data when calling getsampwent now */
- context->pwent_methods = NULL;
-}
-
-static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pwent_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- /* Loop until we find something useful */
- while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) {
-
- context->pwent_methods->endsampwent(context->pwent_methods);
-
- context->pwent_methods = context->pwent_methods->next;
-
- /* All methods are checked now. There are no more entries */
- if (context->pwent_methods == NULL)
- return ret;
-
- context->pwent_methods->setsampwent(context->pwent_methods, False);
- }
- user->methods = context->pwent_methods;
- pdb_force_pw_initialization(user);
- return ret;
-}
-
-static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) {
- pdb_force_pw_initialization(sam_acct);
- sam_acct->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- curmethods = context->pdb_methods;
-
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) {
- pdb_force_pw_initialization(sam_acct);
- sam_acct->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- /** @todo This is where a 're-read on add' should be done */
- /* We now add a new account to the first database listed.
- * Should we? */
-
- return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
-}
-
-static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- if (!sam_acct || !sam_acct->methods){
- DEBUG(0, ("invalid sam_acct specified\n"));
- return ret;
- }
-
- /** @todo This is where a 're-read on update' should be done */
-
- return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
-}
-
-static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *pdb_selected;
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- if (!sam_acct->methods){
- pdb_selected = context->pdb_methods;
- /* There's no passdb backend specified for this account.
- * Try to delete it in every passdb available
- * Needed to delete accounts in smbpasswd that are not
- * in /etc/passwd.
- */
- while (pdb_selected){
- if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) {
- return ret;
- }
- pdb_selected = pdb_selected->next;
- }
- return ret;
- }
-
- if (!sam_acct->methods->delete_sam_account){
- DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
- return ret;
- }
-
- return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
-}
-
-static NTSTATUS context_getgrsid(struct pdb_context *context,
- GROUP_MAP *map, DOM_SID sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrsid(curmethods, map, sid);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_getgrgid(struct pdb_context *context,
- GROUP_MAP *map, gid_t gid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrgid(curmethods, map, gid);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_getgrnam(struct pdb_context *context,
- GROUP_MAP *map, const char *name)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrnam(curmethods, map, name);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_add_group_mapping_entry(struct pdb_context *context,
- GROUP_MAP *map)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->add_group_mapping_entry(context->pdb_methods,
- map);
-}
-
-static NTSTATUS context_update_group_mapping_entry(struct pdb_context *context,
- GROUP_MAP *map)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->
- pdb_methods->update_group_mapping_entry(context->pdb_methods, map);
-}
-
-static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context,
- DOM_SID sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->
- pdb_methods->delete_group_mapping_entry(context->pdb_methods, sid);
-}
-
-static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->enum_group_mapping(context->pdb_methods,
- sid_name_use, rmap,
- num_entries, unix_only);
-}
-
-static NTSTATUS context_find_alias(struct pdb_context *context,
- const char *name, DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->find_alias(context->pdb_methods,
- name, sid);
-}
-
-static NTSTATUS context_create_alias(struct pdb_context *context,
- const char *name, uint32 *rid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->create_alias(context->pdb_methods,
- name, rid);
-}
-
-static NTSTATUS context_delete_alias(struct pdb_context *context,
- const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->delete_alias(context->pdb_methods, sid);
-}
-
-static NTSTATUS context_enum_aliases(struct pdb_context *context,
- const DOM_SID *sid,
- uint32 start_idx, uint32 max_entries,
- uint32 *num_aliases,
- struct acct_info **info)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->enum_aliases(context->pdb_methods,
- sid, start_idx, max_entries,
- num_aliases, info);
-}
-
-static NTSTATUS context_get_aliasinfo(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->get_aliasinfo(context->pdb_methods,
- sid, info);
-}
-
-static NTSTATUS context_set_aliasinfo(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->set_aliasinfo(context->pdb_methods,
- sid, info);
-}
-
-static NTSTATUS context_add_aliasmem(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->add_aliasmem(context->pdb_methods,
- alias, member);
-}
-
-static NTSTATUS context_del_aliasmem(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->del_aliasmem(context->pdb_methods,
- alias, member);
-}
-
-static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
- const DOM_SID *alias, DOM_SID **members,
- int *num)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->enum_aliasmem(context->pdb_methods,
- alias, members, num);
-}
-
-static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->
- enum_alias_memberships(context->pdb_methods, sid, aliases,
- num);
-}
-
-static NTSTATUS context_settrustpwent(struct pdb_context *context)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->settrustpwent(cur_methods);
- if (NT_STATUS_IS_OK(ret)) {
- context->pdb_methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static void context_endtrustpwent(struct pdb_context *context)
-{
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return;
- }
-
- cur_methods = context->pdb_methods;
-
- cur_methods->endtrustpwent(cur_methods);
- context->pdb_methods = cur_methods;
- return;
-}
-
-static NTSTATUS context_gettrustpwent(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->gettrustpwent(cur_methods, trust);
- if (!NT_STATUS_IS_ERR(ret)) {
- /* prevent from segfaulting when gettrustpwent
- was called just to rewind enumeration */
- if (trust) trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_gettrustpwnam(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust,
- const char *name)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->gettrustpwnam(cur_methods, trust, name);
- if (NT_STATUS_IS_OK(ret)) {
- trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_gettrustpwsid(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust,
- const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->gettrustpwsid(cur_methods, trust, sid);
- if (NT_STATUS_IS_OK(ret)) {
- trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_add_trust_passwd(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->add_trust_passwd(cur_methods, trust);
- if (NT_STATUS_IS_OK(ret)) {
- trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_update_trust_passwd(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->update_trust_passwd(cur_methods, trust);
- if (NT_STATUS_IS_OK(ret)) {
- trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_delete_trust_passwd(struct pdb_context *context,
- SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct pdb_methods *cur_methods;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- cur_methods = context->pdb_methods;
-
- while (cur_methods) {
- ret = cur_methods->delete_trust_passwd(cur_methods, trust);
- if (NT_STATUS_IS_OK(ret)) {
- trust->methods = cur_methods;
- return ret;
- }
- cur_methods = cur_methods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_lsa_create_account(struct pdb_context *context, const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->lsa_create_account(curmethods, sid))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_lsa_enumerate_accounts(struct pdb_context *context, DOM_SID **sid_list, int *sid_count)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->lsa_enumerate_accounts(curmethods, sid_list, sid_count))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_add_privilege_to_sid(struct pdb_context *context, const char *priv_name, const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->add_privilege_to_sid(curmethods, priv_name, sid))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_remove_privilege_from_sid(struct pdb_context *context, const char *priv_name, const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->remove_privilege_from_sid(curmethods, priv_name, sid))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_get_privilege_set(struct pdb_context *context, DOM_SID *sid_list, int num_sids, PRIVILEGE_SET *privset)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->get_privilege_set(curmethods, sid_list, num_sids, privset))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-static NTSTATUS context_get_privilege_entry(struct pdb_context *context, const char *privname, DOM_SID **sid_list, int *sid_count)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->get_privilege_entry(curmethods, privname, sid_list, sid_count))) {
- return ret;
- }
- curmethods = curmethods->next;
- }
-
- return ret;
-}
-
-/******************************************************************
- Free and cleanup a pdb context, any associated data and anything
- that the attached modules might have associated.
- *******************************************************************/
-
-static void free_pdb_context(struct pdb_context **context)
-{
- struct pdb_methods *pdb_selected = (*context)->pdb_methods;
-
- while (pdb_selected){
- if(pdb_selected->free_private_data)
- pdb_selected->free_private_data(&(pdb_selected->private_data));
- pdb_selected = pdb_selected->next;
- }
-
- talloc_destroy((*context)->mem_ctx);
- *context = NULL;
-}
-
-/******************************************************************
- Make a pdb_methods from scratch
- *******************************************************************/
-
-static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
-{
- char *module_name = smb_xstrdup(selected);
- char *module_location = NULL, *p;
- struct pdb_init_function_entry *entry;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- lazy_initialize_passdb();
-
- p = strchr(module_name, ':');
-
- if (p) {
- *p = 0;
- module_location = p+1;
- trim_char(module_location, ' ', ' ');
- }
-
- trim_char(module_name, ' ', ' ');
-
-
- DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
-
- entry = pdb_find_backend_entry(module_name);
-
- /* Try to find a module that contains this module */
- if (!entry) {
- DEBUG(2,("No builtin backend found, trying to load plugin\n"));
- if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
- DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* No such backend found */
- if(!entry) {
- DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5,("Found pdb backend %s\n", module_name));
- nt_status = entry->init(context, methods, module_location);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5,("pdb backend %s has a valid init\n", selected));
- } else {
- DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
- }
- SAFE_FREE(module_name);
- return nt_status;
-}
-
-/******************************************************************
- Make a pdb_context from scratch.
- *******************************************************************/
-
-static NTSTATUS make_pdb_context(struct pdb_context **context)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("pdb_context internal allocation context");
-
- if (!mem_ctx) {
- DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- *context = talloc(mem_ctx, sizeof(**context));
- if (!*context) {
- DEBUG(0, ("make_pdb_context: talloc failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*context);
-
- (*context)->mem_ctx = mem_ctx;
-
- (*context)->pdb_setsampwent = context_setsampwent;
- (*context)->pdb_endsampwent = context_endsampwent;
- (*context)->pdb_getsampwent = context_getsampwent;
- (*context)->pdb_getsampwnam = context_getsampwnam;
- (*context)->pdb_getsampwsid = context_getsampwsid;
- (*context)->pdb_add_sam_account = context_add_sam_account;
- (*context)->pdb_update_sam_account = context_update_sam_account;
- (*context)->pdb_delete_sam_account = context_delete_sam_account;
- (*context)->pdb_getgrsid = context_getgrsid;
- (*context)->pdb_getgrgid = context_getgrgid;
- (*context)->pdb_getgrnam = context_getgrnam;
- (*context)->pdb_add_group_mapping_entry = context_add_group_mapping_entry;
- (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
- (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
- (*context)->pdb_enum_group_mapping = context_enum_group_mapping;
- (*context)->pdb_find_alias = context_find_alias;
- (*context)->pdb_create_alias = context_create_alias;
- (*context)->pdb_delete_alias = context_delete_alias;
- (*context)->pdb_enum_aliases = context_enum_aliases;
- (*context)->pdb_get_aliasinfo = context_get_aliasinfo;
- (*context)->pdb_set_aliasinfo = context_set_aliasinfo;
- (*context)->pdb_add_aliasmem = context_add_aliasmem;
- (*context)->pdb_del_aliasmem = context_del_aliasmem;
- (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
- (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
- (*context)->pdb_settrustpwent = context_settrustpwent;
- (*context)->pdb_endtrustpwent = context_endtrustpwent;
- (*context)->pdb_gettrustpwent = context_gettrustpwent;
- (*context)->pdb_gettrustpwnam = context_gettrustpwnam;
- (*context)->pdb_gettrustpwsid = context_gettrustpwsid;
- (*context)->pdb_add_trust_passwd = context_add_trust_passwd;
- (*context)->pdb_update_trust_passwd = context_update_trust_passwd;
- (*context)->pdb_delete_trust_passwd = context_delete_trust_passwd;
- (*context)->pdb_lsa_create_account = context_lsa_create_account;
- (*context)->pdb_lsa_enumerate_accounts = context_lsa_enumerate_accounts;
- (*context)->pdb_add_privilege_to_sid = context_add_privilege_to_sid;
- (*context)->pdb_remove_privilege_from_sid = context_remove_privilege_from_sid;
- (*context)->pdb_get_privilege_set = context_get_privilege_set;
- (*context)->pdb_get_privilege_entry = context_get_privilege_entry;
-
- (*context)->free_fn = free_pdb_context;
-
- return NT_STATUS_OK;
-}
-
-
-/******************************************************************
- Make a pdb_context, given an array of strings
- *******************************************************************/
-
-NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **selected)
-{
- int i = 0;
- struct pdb_methods *curmethods, *tmpmethods;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- BOOL have_guest = False;
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
- return nt_status;
- }
-
- if (!selected) {
- DEBUG(0, ("ERROR: empty passdb backend list!\n"));
- return nt_status;
- }
-
- while (selected[i]){
- if (strcmp(selected[i], "guest") == 0) {
- have_guest = True;
- }
- /* Try to initialise pdb */
- DEBUG(5,("Trying to load: %s\n", selected[i]));
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
- DEBUG(1, ("Loading %s failed!\n", selected[i]));
- free_pdb_context(context);
- return nt_status;
- }
- curmethods->parent = *context;
- DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
- i++;
- }
-
- if (have_guest)
- return NT_STATUS_OK;
-
- if ( (lp_guestaccount() == NULL) ||
- (*lp_guestaccount() == '\0') ) {
- /* We explicitly don't want guest access. No idea what
- else that breaks, but be it that way. */
- return NT_STATUS_OK;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods,
- *context,
- "guest"))) {
- DEBUG(1, ("Loading guest module failed!\n"));
- free_pdb_context(context);
- return nt_status;
- }
-
- curmethods->parent = *context;
- DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************
- Make a pdb_context, given a text string.
- *******************************************************************/
-
-NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
-{
- NTSTATUS ret;
- char **newsel = str_list_make(selected, NULL);
- ret = make_pdb_context_list(context, (const char **)newsel);
- str_list_free(&newsel);
- return ret;
-}
-
-/******************************************************************
- Return an already initialised pdb_context, to facilitate backward
- compatibility (see functions below).
-*******************************************************************/
-
-static struct pdb_context *pdb_get_static_context(BOOL reload)
-{
- static struct pdb_context *pdb_context = NULL;
-
- if ((pdb_context) && (reload)) {
- pdb_context->free_fn(&pdb_context);
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
- return NULL;
- }
- }
-
- if (!pdb_context) {
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
- return NULL;
- }
- }
-
- return pdb_context;
-}
-
-/******************************************************************
- Backward compatibility functions for the original passdb interface
-*******************************************************************/
-
-BOOL pdb_setsampwent(BOOL update)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update));
-}
-
-void pdb_endsampwent(void)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return;
- }
-
- pdb_context->pdb_endsampwent(pdb_context);
-}
-
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
-}
-
-BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username));
-}
-
-BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
-}
-
-BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
- const char *lm_pw, *nt_pw;
- uint16 acb_flags;
-
- if (!pdb_context) {
- return False;
- }
-
- /* disable acccounts with no passwords (that has not
- been allowed by the ACB_PWNOTREQ bit */
-
- lm_pw = pdb_get_lanman_passwd( sam_acct );
- nt_pw = pdb_get_nt_passwd( sam_acct );
- acb_flags = pdb_get_acct_ctrl( sam_acct );
- if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
- acb_flags |= ACB_DISABLED;
- pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct));
-}
-
-BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
- const char *lm_pw, *nt_pw;
- uint16 acb_flags;
-
- if (!pdb_context) {
- return False;
- }
-
- /* disable acccounts with no passwords (that has not
- been allowed by the ACB_PWNOTREQ bit */
-
- lm_pw = pdb_get_lanman_passwd( sam_acct );
- nt_pw = pdb_get_nt_passwd( sam_acct );
- acb_flags = pdb_get_acct_ctrl( sam_acct );
- if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
- acb_flags |= ACB_DISABLED;
- pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
-}
-
-BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
-}
-
-BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrsid(pdb_context, map, sid));
-}
-
-BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrgid(pdb_context, map, gid));
-}
-
-BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrnam(pdb_context, map, name));
-}
-
-BOOL pdb_add_group_mapping_entry(GROUP_MAP *map)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_add_group_mapping_entry(pdb_context, map));
-}
-
-BOOL pdb_update_group_mapping_entry(GROUP_MAP *map)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_update_group_mapping_entry(pdb_context, map));
-}
-
-BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_delete_group_mapping_entry(pdb_context, sid));
-}
-
-BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
- int *num_entries, BOOL unix_only)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_group_mapping(pdb_context, sid_name_use,
- rmap, num_entries, unix_only));
-}
-
-BOOL pdb_find_alias(const char *name, DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_find_alias(pdb_context,
- name, sid));
-}
-
-NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- return pdb_context->pdb_create_alias(pdb_context, name, rid);
-}
-
-BOOL pdb_delete_alias(const DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_delete_alias(pdb_context,
- sid));
-
-}
-
-BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries,
- uint32 *num_aliases, struct acct_info **info)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid,
- start_idx,
- max_entries,
- num_aliases,
- info));
-}
-
-BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_get_aliasinfo(pdb_context, sid,
- info));
-}
-
-BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->pdb_set_aliasinfo(pdb_context, sid,
- info));
-}
-
-BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_add_aliasmem(pdb_context, alias, member));
-}
-
-BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_del_aliasmem(pdb_context, alias, member));
-}
-
-BOOL pdb_enum_aliasmem(const DOM_SID *alias,
- DOM_SID **members, int *num_members)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_aliasmem(pdb_context, alias,
- members, num_members));
-}
-
-BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
- DOM_SID **aliases, int *num)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
-
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_alias_memberships(pdb_context, sid,
- aliases, num));
-}
-
-NTSTATUS pdb_lsa_create_account(DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return pdb_context->pdb_lsa_create_account(pdb_context, sid);
-}
-
-NTSTATUS pdb_lsa_enumerate_accounts(DOM_SID **sid, int *sid_count)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_NO_MORE_ENTRIES;
- }
-
- return pdb_context->pdb_lsa_enumerate_accounts(pdb_context, sid, sid_count);
-}
-
-NTSTATUS pdb_add_privilege_to_sid(char *priv_name, DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return pdb_context->pdb_add_privilege_to_sid(pdb_context, priv_name, sid);
-}
-
-NTSTATUS pdb_remove_privilege_from_sid(char *priv_name, DOM_SID *sid)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return pdb_context->pdb_remove_privilege_from_sid(pdb_context, priv_name, sid);
-}
-
-NTSTATUS pdb_get_privilege_set(DOM_SID *sid_list, int num_sids, PRIVILEGE_SET *privset)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_OK;
- }
-
- return pdb_context->pdb_get_privilege_set(pdb_context, sid_list, num_sids, privset);
-}
-
-NTSTATUS pdb_get_privilege_entry(const char *privname, DOM_SID **sid_list, int *sid_count)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return pdb_context->pdb_get_privilege_entry(pdb_context, privname, sid_list, sid_count);
-}
-
-/***************************************************************
- Initialize the static context (at smbd startup etc).
-
- If uninitialised, context will auto-init on first use.
- ***************************************************************/
-
-BOOL initialize_password_db(BOOL reload)
-{
- return (pdb_get_static_context(reload) != NULL);
-}
-
-
-/***************************************************************************
- Default implementations of some functions.
- ****************************************************************************/
-
-static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
-{
- return NT_STATUS_NO_SUCH_USER;
-}
-
-static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
-{
- return NT_STATUS_NO_SUCH_USER;
-}
-
-static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
- DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static void pdb_default_endsampwent(struct pdb_methods *methods)
-{
- return; /* NT_STATUS_NOT_IMPLEMENTED; */
-}
-
-static NTSTATUS pdb_default_settrustpwent(struct pdb_methods *methods)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static void pdb_default_endtrustpwent(struct pdb_methods *methods)
-{
- return;
-}
-
-static NTSTATUS pdb_default_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust,
- const char* name)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust,
- const DOM_SID* sid)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_add_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_lsa_create_account(struct pdb_methods *methods, const DOM_SID *sid)
-{
- return NT_STATUS_OK;
-}
-
-static NTSTATUS pdb_default_lsa_enumerate_accounts(struct pdb_methods *methods, DOM_SID **sid_list, int *sid_count)
-{
- return NT_STATUS_NO_MORE_ENTRIES;
-}
-
-static NTSTATUS pdb_default_add_privilege_to_sid(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_remove_privilege_from_sid(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-static NTSTATUS pdb_default_get_privilege_set(struct pdb_methods *methods, DOM_SID *sid_list, int num_sids, PRIVILEGE_SET *privset)
-{
- /* by default return the empty privilege set as otherwise login will
- * be denied if a backend does not support privilege sets */
- return NT_STATUS_OK;
-}
-
-static NTSTATUS pdb_default_get_privilege_entry(struct pdb_methods *methods, const char *privname, DOM_SID **sid_list, int *sid_count)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-
-NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
-{
- *methods = talloc(mem_ctx, sizeof(struct pdb_methods));
-
- if (!*methods) {
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*methods);
-
- (*methods)->setsampwent = pdb_default_setsampwent;
- (*methods)->endsampwent = pdb_default_endsampwent;
- (*methods)->getsampwent = pdb_default_getsampwent;
- (*methods)->getsampwnam = pdb_default_getsampwnam;
- (*methods)->getsampwsid = pdb_default_getsampwsid;
- (*methods)->add_sam_account = pdb_default_add_sam_account;
- (*methods)->update_sam_account = pdb_default_update_sam_account;
- (*methods)->delete_sam_account = pdb_default_delete_sam_account;
-
- (*methods)->getgrsid = pdb_default_getgrsid;
- (*methods)->getgrgid = pdb_default_getgrgid;
- (*methods)->getgrnam = pdb_default_getgrnam;
- (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
- (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
- (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
- (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
- (*methods)->find_alias = pdb_default_find_alias;
- (*methods)->create_alias = pdb_default_create_alias;
- (*methods)->delete_alias = pdb_default_delete_alias;
- (*methods)->enum_aliases = pdb_default_enum_aliases;
- (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
- (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
- (*methods)->add_aliasmem = pdb_default_add_aliasmem;
- (*methods)->del_aliasmem = pdb_default_del_aliasmem;
- (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
- (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
-
- (*methods)->settrustpwent = pdb_default_settrustpwent;
- (*methods)->endtrustpwent = pdb_default_endtrustpwent;
- (*methods)->gettrustpwent = pdb_default_gettrustpwent;
- (*methods)->gettrustpwnam = pdb_default_gettrustpwnam;
- (*methods)->gettrustpwsid = pdb_default_gettrustpwsid;
- (*methods)->add_trust_passwd = pdb_default_add_trust_passwd;
- (*methods)->update_trust_passwd = pdb_default_update_trust_passwd;
- (*methods)->delete_trust_passwd = pdb_default_delete_trust_passwd;
-
- (*methods)->lsa_create_account = pdb_default_lsa_create_account;
- (*methods)->lsa_enumerate_accounts = pdb_default_lsa_enumerate_accounts;
- (*methods)->add_privilege_to_sid = pdb_default_add_privilege_to_sid;
- (*methods)->remove_privilege_from_sid = pdb_default_remove_privilege_from_sid;
- (*methods)->get_privilege_set = pdb_default_get_privilege_set;
- (*methods)->get_privilege_entry = pdb_default_get_privilege_entry;
-
- return NT_STATUS_OK;
-}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 6cf109bc65c..ebcca0fac6e 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1,13 +1,11 @@
/*
- Unix SMB/CIFS mplementation.
+ Unix SMB/Netbios implementation.
+ Version 2.9.
LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
- Copyright (C) Gerald Carter 2001-2003
- Copyright (C) Shahms King 2001
- Copyright (C) Andrew Bartlett 2002-2003
- Copyright (C) Stefan (metze) Metzmacher 2002-2003
- Copyright (C) Simo Sorce 2003
-
+ Copyright (C) Gerald Carter 2001
+ Copyright (C) Shahms King 2001
+ Copyright (C) Jean François Micouleau 1998
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +22,9 @@
*/
+#include "includes.h"
+
+#ifdef WITH_LDAP_SAM
/* TODO:
* persistent connections: if using NSS LDAP, many connections are made
* however, using only one within Samba would be nice
@@ -44,389 +45,492 @@
* and/or winbind
*/
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
#include <lber.h>
#include <ldap.h>
-/*
- * Work around versions of the LDAP client libs that don't have the OIDs
- * defined, or have them defined under the old name.
- * This functionality is really a factor of the server, not the client
- *
- */
-
-#if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
-#define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
-#elif !defined(LDAP_EXOP_MODIFY_PASSWD)
-#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
+#ifndef LDAP_OPT_SUCCESS
+#define LDAP_OPT_SUCCESS LDAP_SUCCESS
#endif
-#if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
-#elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
+#ifndef SAM_ACCOUNT
+#define SAM_ACCOUNT struct sam_passwd
#endif
-#if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
-#elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
-#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
-#endif
+struct ldap_enum_info {
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ int index;
+};
+static struct ldap_enum_info global_ldap_ent;
+static pstring ldap_secret;
-#ifndef SAM_ACCOUNT
-#define SAM_ACCOUNT struct sam_passwd
-#endif
-#define MODIFY_TIMESTAMP_STRING "modifyTimestamp"
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
-#include "smbldap.h"
+/*
+ * attributes needed from sambaAccount
+ *
+ * objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+ * DESC 'Samba Auxilary Account'
+ * MUST ( uid $ rid )
+ * MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+ * logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+ * displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+ * description $ userWorkstations $ primaryGroupID $ domain ))
+ */
-struct ldapsam_privates {
- struct smbldap_state *smbldap_state;
+char* attribs[] = {
+ "uid",
+ "rid",
+ "cn",
+ "lmPassword",
+ "ntPassword",
+ "pwdLastSet",
+ "logonTime",
+ "logoffTime",
+ "kickoffTime",
+ "pwdCanChange",
+ "pwdMustChange",
+ "acctFlags",
+ "displayName",
+ "smbHome",
+ "homeDrive",
+ "scriptPath",
+ "profilePath",
+ "description",
+ "userWorkstations",
+ "primaryGroupID",
+ "domain",
+ NULL
+};
- /* Former statics */
- LDAPMessage *result;
- LDAPMessage *entry;
- int index;
+
+/*******************************************************************
+ open a connection to the ldap server.
+******************************************************************/
+static BOOL ldap_open_connection (LDAP ** ldap_struct)
+{
+ int port;
+ int version;
+#ifdef HAVE_LDAP_START_TLS_S
+ int tls, rc;
+#endif
+ uid_t uid = geteuid();
+ struct passwd* pass;
- const char *domain_name;
- DOM_SID domain_sid;
+ DEBUG(5,("ldap_open_connection: starting...\n"));
+ /*
+ * using sys_getpwnam() here since I'm assuming that the
+ * ldapsam is only used on a standalone server or PDC.
+ * winbind not in the picture....
+ */
- /* configuration items */
- int schema_ver;
-};
+ if ( (pass=sys_getpwuid(uid)) == NULL ) {
+ DEBUG(0,("ldap_open_connection: Can't determine user of running process!\n"));
+ return False;
+ }
-/**********************************************************************
- Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
- **********************************************************************/
-
-static void private_data_free_fn(void **result)
-{
- ldap_msgfree(*result);
- *result = NULL;
-}
+ /* check that the user is in the domain admin group for connecting */
-/**********************************************************************
- Get the attribute name given a user schame version.
- **********************************************************************/
-
-static const char* get_userattr_key2string( int schema_ver, int key )
-{
- switch ( schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- return get_attr_key2string( attrib_map_v22, key );
+ if ( (uid != 0) && !user_in_list(pass->pw_name, lp_domain_admin_group()) ) {
+ DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root or a member of domain admin group..\n"));
+ return False;
+ }
+
+ port = lp_ldap_port();
+
+ /* remap default port is no SSL */
+ if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (lp_ldap_port() == 636) ) {
+ port = 389;
+ }
+
+ DEBUG(10,("Initializing connection to %s on port %d\n",
+ lp_ldap_server(), port ));
+
+ if ((*ldap_struct = ldap_init(lp_ldap_server(), port)) == NULL) {
+ DEBUG(0, ("The LDAP server is not responding !\n"));
+ return False;
+ }
+
+ /* Connect to older servers using SSL and V2 rather than Start TLS */
+ if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+ {
+ if (version != LDAP_VERSION3)
+ {
+ version = LDAP_VERSION3;
+ ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+ }
+ }
+
+ switch (lp_ldap_ssl())
+ {
+ case LDAP_SSL_START_TLS:
+#ifdef HAVE_LDAP_START_TLS_S
+ if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
+ &version) == LDAP_OPT_SUCCESS)
+ {
+ if (version < LDAP_VERSION3)
+ {
+ version = LDAP_VERSION3;
+ ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
+ &version);
+ }
+ }
+ if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
+ {
+ DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
+ ldap_err2string(rc)));
+ return False;
+ }
+ DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
+#else
+ DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
+ return False;
+#endif
+ break;
+
+ case LDAP_SSL_ON:
+#ifdef LDAP_OPT_X_TLS
+ tls = LDAP_OPT_X_TLS_HARD;
+ if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("Failed to setup a TLS session\n"));
+ }
- case SCHEMAVER_SAMBASAMACCOUNT:
- return get_attr_key2string( attrib_map_v30, key );
+ DEBUG(0,("LDAPS option set...!\n"));
+#else
+ DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
+ return False;
+#endif
+ break;
+ case LDAP_SSL_OFF:
default:
- DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
+ /*
+ * No special needs to setup options prior to the LDAP
+ * bind (which should be called next via ldap_connect_system()
+ */
break;
}
- return NULL;
+
+ DEBUG(2, ("ldap_open_connection: connection opened\n"));
+ return True;
}
-/**********************************************************************
- Return the list of attribute names given a user schema version.
-**********************************************************************/
-static char** get_userattr_list( int schema_ver )
+/*******************************************************************
+ ldap rebind proc to rebind w/ the admin dn when following referrals
+*******************************************************************/
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 3
+static int rebindproc_with_state (LDAP *ldap_struct,
+ LDAP_CONST char *url,
+ ber_tag_t request,
+ ber_int_t msgid, void *arg)
+# else /* LDAP_SET_REBIND_PROC_ARGS == 2 */
+static int rebindproc (LDAP *ldap_struct,
+ LDAP_CONST char *url,
+ ber_tag_t request,
+ ber_int_t msgid)
+# endif /* LDAP_SET_REBIND_PROC_ARGS */
{
- switch ( schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- return get_attr_list( attrib_map_v22 );
-
- case SCHEMAVER_SAMBASAMACCOUNT:
- return get_attr_list( attrib_map_v30 );
- default:
- DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
- break;
+
+ int rc = 0;
+
+ DEBUG(2,("ldap_connect_system: Rebinding as \"%s\", API: %d, PROC_ARGS: %d\n",
+ lp_ldap_admin_dn(), LDAP_API_VERSION, LDAP_SET_REBIND_PROC_ARGS));
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ if ( ( rc = ldap_simple_bind_s( ldap_struct, lp_ldap_admin_dn(), ldap_secret ) ) == LDAP_SUCCESS )
+ {
+ DEBUG( 2, ( "Rebind successful\n" ) );
}
-
- return NULL;
+ else {
+ DEBUG( 2, ( "Rebind failed: %s\n", ldap_err2string( rc ) ) );
+ }
+ return rc;
+}
+#else /* other Vendor or LDAP_API_VERSION */
+# if LDAP_SET_REBIND_PROC_ARGS ==3
+static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
+ int *methodp, int freeit, void *arg)
+
+# else /* LDAP_SET_REBIND_PROC_ARGS == 2 */
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
+# endif
+{
+
+ if (freeit) {
+ SAFE_FREE(*whop);
+ memset(*credp, '\0', strlen(*credp));
+ SAFE_FREE(*credp);
+ } else {
+ *whop = strdup(lp_ldap_admin_dn());
+ if (!*whop) {
+ return LDAP_NO_MEMORY;
+ }
+ DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", *whop));
+
+ *credp = strdup(ldap_secret);
+ if (!*credp) {
+ SAFE_FREE(*whop);
+ return LDAP_NO_MEMORY;
+ }
+ *methodp = LDAP_AUTH_SIMPLE;
+ }
+ return LDAP_SUCCESS;
}
+#endif
+
+
/*******************************************************************
- Generate the LDAP search filter for the objectclass based on the
- version of the schema we are using.
+ connect to the ldap server under system privilege.
******************************************************************/
-
-static const char* get_objclass_filter( int schema_ver )
+static BOOL ldap_connect_system(LDAP * ldap_struct)
{
- static fstring objclass_filter;
-
- switch( schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
- break;
- case SCHEMAVER_SAMBASAMACCOUNT:
- fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
- break;
- default:
- DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
- break;
+ int rc;
+ static BOOL got_pw = False;
+
+ /* get the password if we don't have it already */
+ if (!got_pw && !(got_pw=fetch_ldap_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring))))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
+ lp_ldap_admin_dn()));
+ return False;
+ }
+
+ /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
+ (OpenLDAP) doesnt' seem to support it */
+
+ DEBUG(0,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
+ lp_ldap_admin_dn()));
+
+#if LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc(ldap_struct, rebindproc);
+#else /* LDAP_SET_REBIND_PROC_ARGS == 3 */
+ ldap_set_rebind_proc(ldap_struct, rebindproc_with_state, NULL);
+#endif
+
+ if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
+ ldap_secret)) != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
+ return False;
}
- return objclass_filter;
+ DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+ return True;
}
/*******************************************************************
- Run the search by name.
+ run the search by name.
******************************************************************/
-
-static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state,
- const char *user,
- LDAPMessage ** result, char **attr)
+static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMessage ** result)
{
- pstring filter;
- char *escape_user = escape_ldap_string_alloc(user);
+ int scope = LDAP_SCOPE_SUBTREE;
+ int rc;
+
+ DEBUG(2, ("ldap_search_one_user: searching for:[%s]\n", filter));
- if (!escape_user) {
- return LDAP_NO_MEMORY;
+ rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, (char*)filter, attribs, 0, result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_search_one_user: Problem during the LDAP search: %s\n",
+ ldap_err2string (rc)));
+ DEBUG(3,("ldap_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
+ filter));
}
+
+ return rc;
+}
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+static int ldap_search_one_user_by_name (LDAP * ldap_struct, const char *user,
+ LDAPMessage ** result)
+{
+ pstring filter;
+
/*
* in the filter expression, replace %u with the real name
* so in ldap filter, %u MUST exist :-)
*/
- pstr_sprintf(filter, "(&%s%s)", lp_ldap_filter(),
- get_objclass_filter(ldap_state->schema_ver));
+ pstrcpy(filter, lp_ldap_filter());
/*
* have to use this here because $ is filtered out
- * in pstring_sub
+ * in pstring_sub
*/
-
-
- all_string_sub(filter, "%u", escape_user, sizeof(pstring));
- SAFE_FREE(escape_user);
+ all_string_sub(filter, "%u", user, sizeof(pstring));
- return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
+ return ldap_search_one_user(ldap_struct, filter, result);
}
/*******************************************************************
- Run the search by rid.
+ run the search by uid.
******************************************************************/
-
-static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
- uint32 rid, LDAPMessage ** result,
- char **attr)
+static int ldap_search_one_user_by_uid(LDAP * ldap_struct, int uid,
+ LDAPMessage ** result)
{
+ struct passwd *user;
pstring filter;
- int rc;
- pstr_sprintf(filter, "(&(rid=%i)%s)", rid,
- get_objclass_filter(ldap_state->schema_ver));
+ /* Get the username from the system and look that up in the LDAP */
- rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
+ if ((user = sys_getpwuid(uid)) == NULL) {
+ DEBUG(3,("ldap_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
+ return LDAP_NO_SUCH_OBJECT;
+ }
- return rc;
+ pstrcpy(filter, lp_ldap_filter());
+
+ all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
+
+ return ldap_search_one_user(ldap_struct, filter, result);
}
/*******************************************************************
- Run the search by SID.
+ run the search by rid.
******************************************************************/
-
-static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
- const DOM_SID *sid, LDAPMessage ** result,
- char **attr)
+static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid,
+ LDAPMessage ** result)
{
pstring filter;
int rc;
- fstring sid_string;
- pstr_sprintf(filter, "(&(%s=%s)%s)",
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- sid_to_string(sid_string, sid),
- get_objclass_filter(ldap_state->schema_ver));
-
- rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
+ /* check if the user rid exsists, if not, try searching on the uid */
+
+ snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
+ rc = ldap_search_one_user(ldap_struct, filter, result);
+ if (rc != LDAP_SUCCESS)
+ rc = ldap_search_one_user_by_uid(ldap_struct,
+ pdb_user_rid_to_uid(rid), result);
+
return rc;
}
/*******************************************************************
- Delete complete object or objectclass and attrs from
- object found in search_result depending on lp_ldap_delete_dn
+ search an attribute and return the first value found.
+ the string in 'value' is unchanged if the attribute does not exist
******************************************************************/
-static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
- LDAPMessage *result,
- const char *objectclass,
- char **attrs)
+static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
+ char *attribute, char *value)
{
- int rc;
- LDAPMessage *entry = NULL;
- LDAPMod **mods = NULL;
- char *name, *dn;
- BerElement *ptr = NULL;
-
- rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (rc != 1) {
- DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (lp_ldap_delete_dn()) {
- NTSTATUS ret = NT_STATUS_OK;
- rc = smbldap_delete(ldap_state->smbldap_state, dn);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn));
- ret = NT_STATUS_UNSUCCESSFUL;
- }
- SAFE_FREE(dn);
- return ret;
- }
-
- /* Ok, delete only the SAM attributes */
-
- for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
- name != NULL;
- name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr)) {
- char **attrib;
-
- /* We are only allowed to delete the attributes that
- really exist. */
-
- for (attrib = attrs; *attrib != NULL; attrib++) {
- if (StrCaseCmp(*attrib, name) == 0) {
- DEBUG(10, ("ldapsam_delete_entry: deleting attribute %s\n", name));
- smbldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
- }
- }
+ char **values;
- ldap_memfree(name);
- }
-
- if (ptr != NULL) {
- ber_free(ptr, 0);
+ if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
+ DEBUG (2, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
+ return False;
}
-
- smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- ldap_mods_free(mods, True);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
+ pstrcpy(value, values[0]);
+ ldap_value_free(values);
+ DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
- DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
- dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- SAFE_FREE(dn);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- SAFE_FREE(dn);
- return NT_STATUS_OK;
+ return True;
}
-
-/* New Interface is being implemented here */
-#if 0 /* JERRY - not uesed anymore */
+/************************************************************************
+ Routine to manage the LDAPMod structure array
+ manage memory used by the array, by each struct, and values
+************************************************************************/
-/**********************************************************************
-Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
-*********************************************************************/
-static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
- SAM_ACCOUNT * sampass,
- LDAPMessage * entry,
- gid_t *gid)
+static void make_a_mod (LDAPMod *** modlist, int modop, char *attribute, char *value)
{
- pstring homedir;
- pstring temp;
- char **ldap_values;
- char **values;
+ LDAPMod **mods;
+ int i;
+ int j;
- if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
- DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
- return False;
- }
+ mods = *modlist;
- for (values=ldap_values;*values;values++) {
- if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
- break;
+ if (attribute == NULL || *attribute == '\0')
+ return;
+
+ if (value == NULL || *value == '\0')
+ return;
+
+ if (mods == NULL)
+ {
+ mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
+ if (mods == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
}
+ mods[0] = NULL;
}
-
- if (!*values) { /*end of array, no posixAccount */
- DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
- ldap_value_free(ldap_values);
- return False;
+
+ for (i = 0; mods[i] != NULL; ++i) {
+ if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
+ break;
}
- ldap_value_free(ldap_values);
- if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
+ if (mods[i] == NULL)
{
- return False;
+ mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
+ }
+ mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
+ if (mods[i] == NULL)
+ {
+ DEBUG(0, ("make_a_mod: out of memory!\n"));
+ return;
+ }
+ mods[i]->mod_op = modop;
+ mods[i]->mod_values = NULL;
+ mods[i]->mod_type = strdup(attribute);
+ mods[i + 1] = NULL;
}
-
- if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
+
+ if (value != NULL)
{
- return False;
+ j = 0;
+ if (mods[i]->mod_values != NULL) {
+ for (; mods[i]->mod_values[j] != NULL; j++);
+ }
+ mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
+ (j + 2) * sizeof (char *));
+
+ if (mods[i]->mod_values == NULL) {
+ DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
+ return;
+ }
+ mods[i]->mod_values[j] = strdup(value);
+ mods[i]->mod_values[j + 1] = NULL;
}
-
- *gid = (gid_t)atol(temp);
-
- pdb_set_unix_homedir(sampass, homedir, PDB_SET);
-
- DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
-
- return True;
+ *modlist = mods;
}
-#endif
-
-static time_t ldapsam_get_entry_timestamp(
- struct ldapsam_privates *ldap_state,
- LDAPMessage * entry)
-{
- pstring temp;
- struct tm tm;
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct,
- entry, MODIFY_TIMESTAMP_STRING, temp))
- return (time_t) 0;
-
- strptime(temp, "%Y%m%d%H%M%SZ", &tm);
- tzset();
- return timegm(&tm);
-}
+/* New Interface is being implemented here */
/**********************************************************************
- Initialize SAM_ACCOUNT from an LDAP query.
- (Based on init_sam_from_buffer in pdb_tdb.c)
+Initialize SAM_ACCOUNT from an LDAP query
+(Based on init_sam_from_buffer in pdb_tdb.c)
*********************************************************************/
-
-static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
- SAM_ACCOUNT * sampass,
- LDAPMessage * entry)
+static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
+ LDAP * ldap_struct, LDAPMessage * entry)
{
- time_t logon_time,
+ time_t logon_time,
logoff_time,
kickoff_time,
pass_last_set_time,
pass_can_change_time,
- pass_must_change_time,
- ldap_entry_time,
- bad_password_time;
+ pass_must_change_time;
pstring username,
domain,
nt_username,
@@ -436,19 +540,20 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
logon_script,
profile_path,
acct_desc,
+ munged_dial,
workstations;
- char munged_dial[2048];
- uint32 user_rid;
- uint8 smblmpwd[LM_HASH_LEN],
- smbntpwd[NT_HASH_LEN];
- uint16 acct_ctrl = 0,
+ struct passwd *sys_user;
+ uint32 user_rid,
+ group_rid;
+ uint8 smblmpwd[16],
+ smbntpwd[16];
+ uint16 acct_ctrl,
logon_divs;
- uint16 bad_password_count = 0,
- logon_count = 0;
- uint32 hours_len;
+ uint32 hours_len;
uint8 hours[MAX_HOURS_LEN];
- pstring temp;
- LOGIN_CACHE *cache_entry = NULL;
+ pstring temp;
+ gid_t gid = getegid();
+
/*
* do a little initialization
@@ -466,339 +571,177 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
workstations[0] = '\0';
- if (sampass == NULL || ldap_state == NULL || entry == NULL) {
- DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
- return False;
- }
-
- if (ldap_state->smbldap_state->ldap_struct == NULL) {
- DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
- return False;
- }
+ get_single_attribute(ldap_struct, entry, "uid", username);
+ DEBUG(2, ("Entry found for user: %s\n", username));
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
- DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
- return False;
- }
-
- DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
-
- pstrcpy(nt_username, username);
-
- pstrcpy(domain, ldap_state->domain_name);
+ pstrcpy(samlogon_user, username);
- pdb_set_username(sampass, username, PDB_SET);
+ pstrcpy(nt_username, username);
- pdb_set_domain(sampass, domain, PDB_DEFAULT);
- pdb_set_nt_username(sampass, nt_username, PDB_SET);
+ pstrcpy(domain, lp_workgroup());
- /* deal with different attributes between the schema first */
+ pass_last_set_time = TIME_T_MAX;
+ logon_time = TIME_T_MAX;
+ logoff_time = TIME_T_MAX;
+ kickoff_time = TIME_T_MAX;
+ pass_can_change_time = TIME_T_MAX;
+ pass_must_change_time = TIME_T_MAX;
- if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
- pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
- }
-
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) {
- pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
- } else {
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- }
- } else {
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
- user_rid = (uint32)atol(temp);
- pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- }
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) {
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- } else {
- uint32 group_rid;
-
- group_rid = (uint32)atol(temp);
-
- /* for some reason, we often have 0 as a primary group RID.
- Make sure that we treat this just as a 'default' value */
-
- if ( group_rid > 0 )
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- else
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- }
- }
- if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
- DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
- username));
- return False;
- }
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "pwdLastSet", temp))
pass_last_set_time = (time_t) atol(temp);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "logonTime", temp))
logon_time = (time_t) atol(temp);
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "logoffTime", temp))
logoff_time = (time_t) atol(temp);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "kickoffTime", temp))
kickoff_time = (time_t) atol(temp);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "pwdCanChange", temp))
pass_can_change_time = (time_t) atol(temp);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {
- /* leave as default */
- } else {
+ if (get_single_attribute(ldap_struct, entry, "pwdMustChange", temp))
pass_must_change_time = (time_t) atol(temp);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- }
/* recommend that 'gecos' and 'displayName' should refer to the same
* attribute OID. userFullName depreciated, only used by Samba
* primary rules of LDAP: don't make a new attribute when one is already defined
* that fits your needs; using cn then displayName rather than 'userFullName'
*/
+
+ sam_logon_in_ssb = True;
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
- /* leave as default */
- } else {
- pdb_set_fullname(sampass, fullname, PDB_SET);
- }
- } else {
- pdb_set_fullname(sampass, fullname, PDB_SET);
+ if (!get_single_attribute(ldap_struct, entry, "cn", fullname)) {
+ get_single_attribute(ldap_struct, entry, "displayName", fullname);
}
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
- {
- pdb_set_dir_drive( sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT );
- } else {
- pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- }
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
- {
- pdb_set_homedir( sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
- PDB_DEFAULT );
- } else {
- pdb_set_homedir(sampass, homedir, PDB_SET);
+ if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
+ pstrcpy(dir_drive, lp_logon_drive());
+ standard_sub_advanced(-1, username, "", gid, dir_drive, sizeof(dir_drive));
+ DEBUG(5,("homeDrive fell back to %s\n",dir_drive));
+ pdb_set_dir_drive(sampass, dir_drive, False);
}
+ else
+ pdb_set_dir_drive(sampass, dir_drive, True);
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
- {
- pdb_set_logon_script( sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
- PDB_DEFAULT );
- } else {
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
+ pstrcpy(homedir, lp_logon_home());
+ standard_sub_advanced(-1, username, "", gid, homedir, sizeof(homedir));
+ DEBUG(5,("smbHome fell back to %s\n",homedir));
+ pdb_set_homedir(sampass, homedir, False);
}
+ else
+ pdb_set_homedir(sampass, homedir, True);
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
- {
- pdb_set_profile_path( sampass,
- talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
- PDB_DEFAULT );
- } else {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
+ if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
+ pstrcpy(logon_script, lp_logon_script());
+ standard_sub_advanced(-1, username, "", gid, logon_script, sizeof(logon_script));
+ DEBUG(5,("scriptPath fell back to %s\n",logon_script));
+ pdb_set_logon_script(sampass, logon_script, False);
}
+ else
+ pdb_set_logon_script(sampass, logon_script, True);
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
- {
- /* leave as default */
- } else {
- pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
+ if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
+ pstrcpy(profile_path, lp_logon_path());
+ standard_sub_advanced(-1, username, "", gid, profile_path, sizeof(profile_path));
+ DEBUG(5,("profilePath fell back to %s\n",profile_path));
+ pdb_set_profile_path(sampass, profile_path, False);
}
+ else
+ pdb_set_profile_path(sampass, profile_path, True);
+
+ sam_logon_in_ssb = False;
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
- /* leave as default */;
- } else {
- pdb_set_workstations(sampass, workstations, PDB_SET);
- }
+ get_single_attribute(ldap_struct, entry, "description", acct_desc);
+ get_single_attribute(ldap_struct, entry, "userWorkstations", workstations);
+ get_single_attribute(ldap_struct, entry, "rid", temp);
+ user_rid = (uint32)atol(temp);
+ get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
+ group_rid = (uint32)atol(temp);
- if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) {
- /* leave as default */;
- } else {
- pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+
+ /* These values MAY be in LDAP, but they can also be retrieved through
+ * sys_getpw*() which is how we're doing it
+ */
+ sys_user = sys_getpwnam(username);
+ if (sys_user == NULL) {
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
+ return False;
}
-
+
+
/* FIXME: hours stuff should be cleaner */
logon_divs = 168;
hours_len = 21;
memset(hours, 0xff, hours_len);
- if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
- /* leave as default */
- } else {
- pdb_gethexpwd(temp, smblmpwd);
- memset((char *)temp, '\0', strlen(temp)+1);
- if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
- return False;
- ZERO_STRUCT(smblmpwd);
- }
+ get_single_attribute (ldap_struct, entry, "lmPassword", temp);
+ pdb_gethexpwd(temp, smblmpwd);
+ memset((char *)temp, '\0', sizeof(temp));
+ get_single_attribute (ldap_struct, entry, "ntPassword", temp);
+ pdb_gethexpwd(temp, smbntpwd);
+ memset((char *)temp, '\0', sizeof(temp));
+ get_single_attribute (ldap_struct, entry, "acctFlags", temp);
+ acct_ctrl = pdb_decode_acct_ctrl(temp);
- if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
- /* leave as default */
- } else {
- pdb_gethexpwd(temp, smbntpwd);
- memset((char *)temp, '\0', strlen(temp)+1);
- if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
- return False;
- ZERO_STRUCT(smbntpwd);
- }
-
- if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
+ if (acct_ctrl == 0)
acct_ctrl |= ACB_NORMAL;
- } else {
- acct_ctrl = pdb_decode_acct_ctrl(temp);
- if (acct_ctrl == 0)
- acct_ctrl |= ACB_NORMAL;
- pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
- }
+ pdb_set_acct_ctrl(sampass, acct_ctrl);
+ pdb_set_logon_time(sampass, logon_time);
+ pdb_set_logoff_time(sampass, logoff_time);
+ pdb_set_kickoff_time(sampass, kickoff_time);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time);
- pdb_set_hours_len(sampass, hours_len, PDB_SET);
- pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+ pdb_set_hours_len(sampass, hours_len);
+ pdb_set_logon_divs(sampass, logon_divs);
-/* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
- /* leave as default */
- } else {
- bad_password_count = (uint32) atol(temp);
- pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
- }
+ pdb_set_uid(sampass, sys_user->pw_uid);
+ pdb_set_gid(sampass, sys_user->pw_gid);
+ pdb_set_user_rid(sampass, user_rid);
+ pdb_set_group_rid(sampass, group_rid);
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) {
- /* leave as default */
- } else {
- bad_password_time = (time_t) atol(temp);
- pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
- }
+ pdb_set_username(sampass, username);
+ pdb_set_domain(sampass, domain);
+ pdb_set_nt_username(sampass, nt_username);
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
- /* leave as default */
- } else {
- logon_count = (uint32) atol(temp);
- pdb_set_logon_count(sampass, logon_count, PDB_SET);
- }
-
- /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
-
- pdb_set_hours(sampass, hours, PDB_SET);
-
- /* check the timestamp of the cache vs ldap entry */
- if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
- entry)))
- return True;
+ pdb_set_fullname(sampass, fullname);
- /* see if we have newer updates */
- if (!(cache_entry = login_cache_read(sampass))) {
- DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
- (unsigned int)pdb_get_bad_password_count(sampass),
- (unsigned int)pdb_get_bad_password_time(sampass)));
- return True;
- }
+ pdb_set_acct_desc(sampass, acct_desc);
+ pdb_set_workstations(sampass, workstations);
+ pdb_set_munged_dial(sampass, munged_dial);
+
+ if (!pdb_set_nt_passwd(sampass, smbntpwd))
+ return False;
+ if (!pdb_set_lanman_passwd(sampass, smblmpwd))
+ return False;
- DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
- (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp,
- (unsigned int)cache_entry->bad_password_time));
+ /* pdb_set_unknown_3(sampass, unknown3); */
+ /* pdb_set_unknown_5(sampass, unknown5); */
+ /* pdb_set_unknown_6(sampass, unknown6); */
- if (ldap_entry_time > cache_entry->entry_timestamp) {
- /* cache is older than directory , so
- we need to delete the entry but allow the
- fields to be written out */
- login_cache_delentry(sampass);
- } else {
- /* read cache in */
- pdb_set_acct_ctrl(sampass,
- pdb_get_acct_ctrl(sampass) |
- (cache_entry->acct_ctrl & ACB_AUTOLOCK),
- PDB_SET);
- pdb_set_bad_password_count(sampass,
- cache_entry->bad_password_count,
- PDB_SET);
- pdb_set_bad_password_time(sampass,
- cache_entry->bad_password_time,
- PDB_SET);
- }
+ pdb_set_hours(sampass, hours);
- SAFE_FREE(cache_entry);
return True;
}
/**********************************************************************
- Initialize SAM_ACCOUNT from an LDAP query.
- (Based on init_buffer_from_sam in pdb_tdb.c)
+Initialize SAM_ACCOUNT from an LDAP query
+(Based on init_buffer_from_sam in pdb_tdb.c)
*********************************************************************/
-
-static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
- LDAPMessage *existing,
- LDAPMod *** mods, SAM_ACCOUNT * sampass,
- BOOL (*need_update)(const SAM_ACCOUNT *,
- enum pdb_elements))
+static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT * sampass)
{
pstring temp;
- uint32 rid;
-
- if (mods == NULL || sampass == NULL) {
- DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
- return False;
- }
*mods = NULL;
@@ -806,2565 +749,468 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
* took out adding "objectclass: sambaAccount"
* do this on a per-mod basis
*/
- if (need_update(sampass, PDB_USERNAME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- "uid", pdb_get_username(sampass));
-
- DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
-
- /* only update the RID if we actually need to */
- if (need_update(sampass, PDB_USERSID)) {
- fstring sid_string;
- fstring dom_sid_string;
- const DOM_SID *user_sid = pdb_get_user_sid(sampass);
-
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
- DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
- sid_to_string(sid_string, user_sid),
- sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
- return False;
- }
- slprintf(temp, sizeof(temp) - 1, "%i", rid);
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
- temp);
- break;
-
- case SCHEMAVER_SAMBASAMACCOUNT:
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- sid_to_string(sid_string, user_sid));
- break;
-
- default:
- DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
- break;
- }
- }
-
- /* we don't need to store the primary group RID - so leaving it
- 'free' to hang off the unix primary group makes life easier */
-
- if (need_update(sampass, PDB_GROUPSID)) {
- fstring sid_string;
- fstring dom_sid_string;
- const DOM_SID *group_sid = pdb_get_group_sid(sampass);
-
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
- DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
- sid_to_string(sid_string, group_sid),
- sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
- return False;
- }
-
- slprintf(temp, sizeof(temp) - 1, "%i", rid);
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver,
- LDAP_ATTR_PRIMARY_GROUP_RID), temp);
- break;
-
- case SCHEMAVER_SAMBASAMACCOUNT:
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver,
- LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
- break;
-
- default:
- DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
- break;
- }
-
- }
-
- /* displayName, cn, and gecos should all be the same
- * most easily accomplished by giving them the same OID
- * gecos isn't set here b/c it should be handled by the
- * add-user script
- * We change displayName only and fall back to cn if
- * it does not exist.
- */
- if (need_update(sampass, PDB_FULLNAME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
- pdb_get_fullname(sampass));
- if (need_update(sampass, PDB_ACCTDESC))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
- pdb_get_acct_desc(sampass));
+ make_a_mod(mods, ldap_state, "uid", pdb_get_username(sampass));
+ DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
- if (need_update(sampass, PDB_WORKSTATIONS))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
- pdb_get_workstations(sampass));
-
- if (need_update(sampass, PDB_MUNGEDDIAL))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
- pdb_get_munged_dial(sampass));
-
- if (need_update(sampass, PDB_SMBHOME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
- pdb_get_homedir(sampass));
-
- if (need_update(sampass, PDB_DRIVE))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
- pdb_get_dir_drive(sampass));
-
- if (need_update(sampass, PDB_LOGONSCRIPT))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
- pdb_get_logon_script(sampass));
-
- if (need_update(sampass, PDB_PROFILE))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
- pdb_get_profile_path(sampass));
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
+ make_a_mod(mods, ldap_state, "pwdLastSet", temp);
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
- if (need_update(sampass, PDB_LOGONTIME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
+ make_a_mod(mods, ldap_state, "logonTime", temp);
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
- if (need_update(sampass, PDB_LOGOFFTIME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
+ make_a_mod(mods, ldap_state, "logoffTime", temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
- if (need_update(sampass, PDB_KICKOFFTIME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
+ make_a_mod(mods, ldap_state, "kickoffTime", temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
- if (need_update(sampass, PDB_CANCHANGETIME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
+ make_a_mod(mods, ldap_state, "pwdCanChange", temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
- if (need_update(sampass, PDB_MUSTCHANGETIME))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
-
-
- if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
- || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
-
- if (need_update(sampass, PDB_LMPASSWD)) {
- const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
- if (lm_pw) {
- pdb_sethexpwd(temp, lm_pw,
- pdb_get_acct_ctrl(sampass));
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
- temp);
- } else {
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
- NULL);
- }
- }
- if (need_update(sampass, PDB_NTPASSWD)) {
- const uchar *nt_pw = pdb_get_nt_passwd(sampass);
- if (nt_pw) {
- pdb_sethexpwd(temp, nt_pw,
- pdb_get_acct_ctrl(sampass));
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
- temp);
- } else {
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
- NULL);
- }
- }
-
- if (need_update(sampass, PDB_PASSLASTSET)) {
- slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
- temp);
- }
- }
-
- /* FIXME: Hours stuff goes in LDAP */
-
- if (need_update(sampass, PDB_ACCTCTRL))
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
- pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
-
- /* password lockout cache:
- - If we are now autolocking or clearing, we write to ldap
- - If we are clearing, we delete the cache entry
- - If the count is > 0, we update the cache
-
- This even means when autolocking, we cache, just in case the
- update doesn't work, and we have to cache the autolock flag */
-
- if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* &&
- need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
- uint16 badcount = pdb_get_bad_password_count(sampass);
- time_t badtime = pdb_get_bad_password_time(sampass);
- uint32 pol;
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &pol);
-
- DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
- (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
-
- if ((badcount >= pol) || (badcount == 0)) {
- DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
- (unsigned int)badcount, (unsigned int)badtime));
- slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount);
- smbldap_make_mod(
- ldap_state->smbldap_state->ldap_struct,
- existing, mods,
- get_userattr_key2string(
- ldap_state->schema_ver,
- LDAP_ATTR_BAD_PASSWORD_COUNT),
- temp);
-
- slprintf (temp, sizeof (temp) - 1, "%li", badtime);
- smbldap_make_mod(
- ldap_state->smbldap_state->ldap_struct,
- existing, mods,
- get_userattr_key2string(
- ldap_state->schema_ver,
- LDAP_ATTR_BAD_PASSWORD_TIME),
- temp);
- }
- if (badcount == 0) {
- DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
- login_cache_delentry(sampass);
- } else {
- LOGIN_CACHE cache_entry ={time(NULL),
- pdb_get_acct_ctrl(sampass),
- badcount, badtime};
- DEBUG(7, ("Updating bad password count and time in login cache\n"));
- login_cache_write(sampass, cache_entry);
- }
- }
-
- return True;
-}
-
-/**********************************************************************
- Connect to LDAP server for password enumeration.
-*********************************************************************/
-
-static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- int rc;
- pstring filter;
- char **attr_list;
-
- pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(),
- get_objclass_filter(ldap_state->schema_ver));
- all_string_sub(filter, "%u", "*", sizeof(pstring));
-
- attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
- attr_list, &ldap_state->result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
- ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- ldap_state->result)));
-
- ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- ldap_state->result);
- ldap_state->index = 0;
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- End enumeration of the LDAP password list.
-*********************************************************************/
-
-static void ldapsam_endsampwent(struct pdb_methods *my_methods)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- if (ldap_state->result) {
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- }
-}
+ make_a_mod(mods, ldap_state, "pwdMustChange", temp);
-/**********************************************************************
-Get the next entry in the LDAP password database.
-*********************************************************************/
+ /* displayName, cn, and gecos should all be the same
+ * most easily accomplished by giving them the same OID
+ * gecos isn't set here b/c it should be handled by the
+ * add-user script
+ */
-static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- BOOL bret = False;
+ make_a_mod(mods, ldap_state, "displayName", pdb_get_fullname(sampass));
+ make_a_mod(mods, ldap_state, "cn", pdb_get_fullname(sampass));
+ make_a_mod(mods, ldap_state, "description", pdb_get_acct_desc(sampass));
+ make_a_mod(mods, ldap_state, "userWorkstations", pdb_get_workstations(sampass));
- while (!bret) {
- if (!ldap_state->entry)
- return ret;
+ /*
+ * Only updates fields which have been set (not defaults from smb.conf)
+ */
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME))
+ make_a_mod(mods, ldap_state, "smbHome", pdb_get_homedir(sampass));
- ldap_state->index++;
- bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
+ if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
+ make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass));
- ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- ldap_state->entry);
- }
+ if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
+ make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass));
- return NT_STATUS_OK;
-}
+ if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE))
+ make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass));
+
-/**********************************************************************
-Get SAM_ACCOUNT entry from LDAP by username.
-*********************************************************************/
+ if ( !pdb_get_user_rid(sampass))
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_uid_to_user_rid(pdb_get_uid(sampass)));
+ else
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_user_rid(sampass));
+ make_a_mod(mods, ldap_state, "rid", temp);
-static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
- char ** attr_list;
- int rc;
-
- attr_list = get_userattr_list( ldap_state->schema_ver );
- rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
- free_attr_list( attr_list );
+ if ( !pdb_get_group_rid(sampass))
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_gid_to_group_rid(pdb_get_gid(sampass)));
+ else
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_group_rid(sampass));
+ make_a_mod(mods, ldap_state, "primaryGroupID", temp);
- if ( rc != LDAP_SUCCESS )
- return NT_STATUS_NO_SUCH_USER;
+ /* FIXME: Hours stuff goes in LDAP */
+ pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
+ make_a_mod (mods, ldap_state, "lmPassword", temp);
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
+ pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
+ make_a_mod (mods, ldap_state, "ntPassword", temp);
- if (count < 1) {
- DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- } else if (count > 1) {
- DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- if (entry) {
- if (!init_sam_from_ldap(ldap_state, user, entry)) {
- DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- }
- pdb_set_backend_private_data(user, result,
- private_data_free_fn,
- my_methods, PDB_CHANGED);
- ret = NT_STATUS_OK;
- } else {
- ldap_msgfree(result);
- }
- return ret;
-}
+ make_a_mod (mods, ldap_state, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
+ NEW_PW_FORMAT_SPACE_PADDED_LEN));
-static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
- const DOM_SID *sid, LDAPMessage **result)
-{
- int rc = -1;
- char ** attr_list;
- uint32 rid;
-
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBASAMACCOUNT:
- attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
- free_attr_list( attr_list );
-
- if ( rc != LDAP_SUCCESS )
- return rc;
- break;
-
- case SCHEMAVER_SAMBAACCOUNT:
- if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
- return rc;
- }
-
- attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
- free_attr_list( attr_list );
-
- if ( rc != LDAP_SUCCESS )
- return rc;
- break;
- }
- return rc;
+ return True;
}
/**********************************************************************
- Get SAM_ACCOUNT entry from LDAP by SID.
+Connect to LDAP server for password enumeration
*********************************************************************/
-
-static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+BOOL pdb_setsampwent(BOOL update)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
int rc;
- fstring sid_string;
-
- rc = ldapsam_get_ldap_user_by_sid(ldap_state,
- sid, &result);
- if (rc != LDAP_SUCCESS)
- return NT_STATUS_NO_SUCH_USER;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (count < 1) {
- DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
- count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- } else if (count > 1) {
- DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
- count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- if (!entry) {
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- if (!init_sam_from_ldap(ldap_state, user, entry)) {
- DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- pdb_set_backend_private_data(user, result,
- private_data_free_fn,
- my_methods, PDB_CHANGED);
- return NT_STATUS_OK;
-}
-
-/********************************************************************
- Do the actual modification - also change a plaintext passord if
- it it set.
-**********************************************************************/
-
-static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
- SAM_ACCOUNT *newpwd, char *dn,
- LDAPMod **mods, int ldap_op,
- BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements))
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- int rc;
-
- if (!my_methods || !newpwd || !dn) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!mods) {
- DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
- /* may be password change below however */
- } else {
- switch(ldap_op) {
- case LDAP_MOD_ADD:
- smbldap_set_mod(&mods, LDAP_MOD_ADD,
- "objectclass",
- LDAP_OBJ_ACCOUNT);
- rc = smbldap_add(ldap_state->smbldap_state,
- dn, mods);
- break;
- case LDAP_MOD_REPLACE:
- rc = smbldap_modify(ldap_state->smbldap_state,
- dn ,mods);
- break;
- default:
- DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
- ldap_op));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (rc!=LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
- ldap_op == LDAP_MOD_ADD ? "add" : "modify",
- dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
- (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
- need_update(newpwd, PDB_PLAINTEXT_PW) &&
- (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
- BerElement *ber;
- struct berval *bv;
- char *retoid;
- struct berval *retdata;
- char *utf8_password;
- char *utf8_dn;
-
- if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
- DEBUG(0,("ber_alloc_t returns NULL\n"));
- SAFE_FREE(utf8_password);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ pstring filter;
- ber_printf (ber, "{");
- ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
- ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
- ber_printf (ber, "N}");
-
- if ((rc = ber_flatten (ber, &bv))<0) {
- DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
- ber_free(ber,1);
- SAFE_FREE(utf8_dn);
- SAFE_FREE(utf8_password);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- SAFE_FREE(utf8_dn);
- SAFE_FREE(utf8_password);
- ber_free(ber, 1);
-
- if ((rc = smbldap_extended_operation(ldap_state->smbldap_state,
- LDAP_EXOP_MODIFY_PASSWD,
- bv, NULL, NULL, &retoid,
- &retdata)) != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
- pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- ber_bvfree(bv);
- return NT_STATUS_UNSUCCESSFUL;
- } else {
- DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
-#endif
- ber_bvfree(retdata);
- ber_memfree(retoid);
- }
- ber_bvfree(bv);
+ if (!ldap_open_connection(&global_ldap_ent.ldap_struct))
+ {
+ return False;
}
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Delete entry from LDAP for username.
-*********************************************************************/
-
-static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- const char *sname;
- int rc;
- LDAPMessage *result = NULL;
- NTSTATUS ret;
- char **attr_list;
- fstring objclass;
-
- if (!sam_acct) {
- DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ if (!ldap_connect_system(global_ldap_ent.ldap_struct))
+ {
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ return False;
}
- sname = pdb_get_username(sam_acct);
-
- DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname));
+ pstrcpy(filter, lp_ldap_filter());
+ all_string_sub(filter, "%u", "*", sizeof(pstring));
- attr_list= get_userattr_list( ldap_state->schema_ver );
- rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
+ rc = ldap_search_s(global_ldap_ent.ldap_struct, lp_ldap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attribs, 0,
+ &global_ldap_ent.result);
- if (rc != LDAP_SUCCESS) {
- free_attr_list( attr_list );
- return NT_STATUS_NO_SUCH_USER;
- }
-
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBASAMACCOUNT:
- fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
- break;
-
- case SCHEMAVER_SAMBAACCOUNT:
- fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
- break;
- default:
- fstrcpy( objclass, "UNKNOWN" );
- DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
- break;
+ if (rc != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
+ DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
+ ldap_msgfree(global_ldap_ent.result);
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ global_ldap_ent.ldap_struct = NULL;
+ global_ldap_ent.result = NULL;
+ return False;
}
- ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
- ldap_msgfree(result);
- free_attr_list( attr_list );
-
- return ret;
-}
+ DEBUG(2, ("pdb_setsampwent: %d entries in the base!\n",
+ ldap_count_entries(global_ldap_ent.ldap_struct,
+ global_ldap_ent.result)));
-/**********************************************************************
- Helper function to determine for update_sam_account whether
- we need LDAP modification.
-*********************************************************************/
+ global_ldap_ent.entry = ldap_first_entry(global_ldap_ent.ldap_struct,
+ global_ldap_ent.result);
+ global_ldap_ent.index = -1;
-static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
- enum pdb_elements element)
-{
- return IS_SAM_CHANGED(sampass, element);
+ return True;
}
/**********************************************************************
- Update SAM_ACCOUNT.
+End enumeration of the LDAP password list
*********************************************************************/
-
-static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+void pdb_endsampwent(void)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- int rc = 0;
- char *dn;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- LDAPMod **mods = NULL;
- char **attr_list;
-
- result = pdb_get_backend_private_data(newpwd, my_methods);
- if (!result) {
- attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
- free_attr_list( attr_list );
- if (rc != LDAP_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
- DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
-
- if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
- element_is_changed)) {
- DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
- SAFE_FREE(dn);
- if (mods != NULL)
- ldap_mods_free(mods,True);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (mods == NULL) {
- DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
- pdb_get_username(newpwd)));
- SAFE_FREE(dn);
- return NT_STATUS_OK;
- }
-
- ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
- ldap_mods_free(mods,True);
- SAFE_FREE(dn);
-
- if (!NT_STATUS_IS_OK(ret)) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
- pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
- return ret;
+ if (global_ldap_ent.ldap_struct && global_ldap_ent.result)
+ {
+ ldap_msgfree(global_ldap_ent.result);
+ ldap_unbind(global_ldap_ent.ldap_struct);
+ global_ldap_ent.ldap_struct = NULL;
+ global_ldap_ent.result = NULL;
}
-
- DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
- pdb_get_username(newpwd)));
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Helper function to determine for update_sam_account whether
- we need LDAP modification.
- *********************************************************************/
-
-static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
- enum pdb_elements element)
-{
- return (IS_SAM_SET(sampass, element) ||
- IS_SAM_CHANGED(sampass, element));
}
/**********************************************************************
- Add SAM_ACCOUNT to LDAP.
+Get the next entry in the LDAP password database
*********************************************************************/
-
-static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+BOOL pdb_getsampwent(SAM_ACCOUNT * user)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- int rc;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring dn;
- LDAPMod **mods = NULL;
- int ldap_op = LDAP_MOD_REPLACE;
- uint32 num_result;
- char **attr_list;
- char *escape_user;
- const char *username = pdb_get_username(newpwd);
- const DOM_SID *sid = pdb_get_user_sid(newpwd);
- pstring filter;
- fstring sid_string;
-
- if (!username || !*username) {
- DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* free this list after the second search or in case we exit on failure */
- attr_list = get_userattr_list(ldap_state->schema_ver);
-
- rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
-
- if (rc != LDAP_SUCCESS) {
- free_attr_list( attr_list );
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
- DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
- username));
- ldap_msgfree(result);
- free_attr_list( attr_list );
- return NT_STATUS_UNSUCCESSFUL;
- }
- ldap_msgfree(result);
- result = NULL;
-
- if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
- rc = ldapsam_get_ldap_user_by_sid(ldap_state,
- sid, &result);
- if (rc == LDAP_SUCCESS) {
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
- DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
- sid_to_string(sid_string, sid)));
- free_attr_list( attr_list );
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
- ldap_msgfree(result);
- }
- }
-
- /* does the entry already exist but without a samba attributes?
- we need to return the samba attributes here */
-
- escape_user = escape_ldap_string_alloc( username );
- pstrcpy( filter, lp_ldap_filter() );
- all_string_sub( filter, "%u", escape_user, sizeof(filter) );
- SAFE_FREE( escape_user );
-
- rc = smbldap_search_suffix(ldap_state->smbldap_state,
- filter, attr_list, &result);
- if ( rc != LDAP_SUCCESS ) {
- free_attr_list( attr_list );
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (num_result > 1) {
- DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
- free_attr_list( attr_list );
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Check if we need to update an existing entry */
- if (num_result == 1) {
- char *tmp;
-
- DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
- ldap_op = LDAP_MOD_REPLACE;
- entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
- tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
- if (!tmp) {
- free_attr_list( attr_list );
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
- slprintf (dn, sizeof (dn) - 1, "%s", tmp);
- SAFE_FREE(tmp);
-
- } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
-
- /* There might be a SID for this account already - say an idmap entry */
-
- pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- sid_to_string(sid_string, sid),
- LDAP_OBJ_IDMAP_ENTRY,
- LDAP_OBJ_SID_ENTRY);
-
- /* free old result before doing a new search */
- if (result != NULL) {
- ldap_msgfree(result);
- result = NULL;
- }
- rc = smbldap_search_suffix(ldap_state->smbldap_state,
- filter, attr_list, &result);
-
- if ( rc != LDAP_SUCCESS ) {
- free_attr_list( attr_list );
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (num_result > 1) {
- DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
- free_attr_list( attr_list );
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Check if we need to update an existing entry */
- if (num_result == 1) {
- char *tmp;
-
- DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
- ldap_op = LDAP_MOD_REPLACE;
- entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
- tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
- if (!tmp) {
- free_attr_list( attr_list );
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
- slprintf (dn, sizeof (dn) - 1, "%s", tmp);
- SAFE_FREE(tmp);
- }
- }
-
- free_attr_list( attr_list );
-
- if (num_result == 0) {
- /* Check if we need to add an entry */
- DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
- ldap_op = LDAP_MOD_ADD;
- if (username[strlen(username)-1] == '$') {
- slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
- } else {
- slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
- }
- }
-
- if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
- element_is_set_or_changed)) {
- DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
- ldap_msgfree(result);
- if (mods != NULL)
- ldap_mods_free(mods,True);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ldap_msgfree(result);
-
- if (mods == NULL) {
- DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
- return NT_STATUS_UNSUCCESSFUL;
- }
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBAACCOUNT:
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
- break;
- case SCHEMAVER_SAMBASAMACCOUNT:
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
- break;
- default:
- DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
- break;
- }
+ if (!global_ldap_ent.entry)
+ return False;
- ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
- pdb_get_username(newpwd),dn));
- ldap_mods_free(mods, True);
- return ret;
+ global_ldap_ent.index++;
+ if (global_ldap_ent.index > 0)
+ {
+ global_ldap_ent.entry = ldap_next_entry(global_ldap_ent.ldap_struct, global_ldap_ent.entry);
}
- DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
- ldap_mods_free(mods, True);
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
- const char *filter,
- LDAPMessage ** result)
-{
- int scope = LDAP_SCOPE_SUBTREE;
- int rc;
- char **attr_list;
-
- attr_list = get_attr_list(groupmap_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state,
- lp_ldap_group_suffix (), scope,
- filter, attr_list, 0, result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_search_one_group: "
- "Problem during the LDAP search: LDAP error: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
- DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
- lp_ldap_group_suffix(), filter));
- SAFE_FREE(ld_error);
+ if (global_ldap_ent.entry != NULL)
+ {
+ return init_sam_from_ldap(user, global_ldap_ent.ldap_struct,
+ global_ldap_ent.entry);
}
-
- return rc;
+ return False;
}
/**********************************************************************
- *********************************************************************/
-
-static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
- GROUP_MAP *map, LDAPMessage *entry)
+Get SAM_ACCOUNT entry from LDAP by username
+*********************************************************************/
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
{
- pstring temp;
-
- if (ldap_state == NULL || map == NULL || entry == NULL ||
- ldap_state->smbldap_state->ldap_struct == NULL) {
- DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
- return False;
- }
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
- DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
- return False;
- }
- DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
-
- map->gid = (gid_t)atol(temp);
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
- DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
- return False;
- }
-
- if (!string_to_sid(&map->sid, temp)) {
- DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
+ if (!ldap_open_connection(&ldap_struct))
return False;
- }
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
- DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
+ if (!ldap_connect_system(ldap_struct))
+ {
+ ldap_unbind(ldap_struct);
return False;
}
- map->sid_name_use = (enum SID_NAME_USE)atol(temp);
-
- if ((map->sid_name_use < SID_NAME_USER) ||
- (map->sid_name_use > SID_NAME_UNKNOWN)) {
- DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
+ if (ldap_search_one_user_by_name(ldap_struct, sname, &result) != LDAP_SUCCESS)
+ {
+ ldap_unbind(ldap_struct);
return False;
}
+ if (ldap_count_entries(ldap_struct, result) < 1)
+ {
+ pstring filter;
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
- temp[0] = '\0';
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
- {
- DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
-for gidNumber(%lu)\n",(unsigned long)map->gid));
- return False;
- }
- }
- fstrcpy(map->nt_name, temp);
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
- temp[0] = '\0';
- }
- fstrcpy(map->comment, temp);
-
- return True;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static BOOL init_ldap_from_group(LDAP *ldap_struct,
- LDAPMessage *existing,
- LDAPMod ***mods,
- const GROUP_MAP *map)
-{
- pstring tmp;
-
- if (mods == NULL || map == NULL) {
- DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
+ pstrcpy(filter, lp_ldap_filter());
+ standard_sub_advanced(-1, sname, "", -1, filter, sizeof(filter));
+ DEBUG(0,("LDAP search \"%s\" returned %d entries.\n", filter,
+ ldap_count_entries(ldap_struct, result)));
+ ldap_unbind(ldap_struct);
return False;
}
-
- *mods = NULL;
-
- sid_to_string(tmp, &map->sid);
-
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
- pstr_sprintf(tmp, "%i", map->sid_name_use);
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
-
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
-
- return True;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
- const char *filter,
- GROUP_MAP *map)
-{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
-
- if (ldapsam_search_one_group(ldap_state, filter, &result)
- != LDAP_SUCCESS) {
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (count < 1) {
- DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- if (count > 1) {
- DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
- filter, count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
-
- if (!entry) {
+ entry = ldap_first_entry(ldap_struct, result);
+ if (entry)
+ {
+ init_sam_from_ldap(user, ldap_struct, entry);
ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ ldap_unbind(ldap_struct);
+ return True;
}
-
- if (!init_group_from_ldap(ldap_state, map, entry)) {
- DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
- filter));
+ else
+ {
ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- ldap_msgfree(result);
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid)
-{
- pstring filter;
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_GROUPMAP,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
- sid_string_static(&sid));
-
- return ldapsam_getgroup(methods, filter, map);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid)
-{
- pstring filter;
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
- LDAP_OBJ_GROUPMAP,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- (unsigned long)gid);
-
- return ldapsam_getgroup(methods, filter, map);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- const char *name)
-{
- pstring filter;
- char *escape_name = escape_ldap_string_alloc(name);
-
- if (!escape_name) {
- return NT_STATUS_NO_MEMORY;
+ ldap_unbind(ldap_struct);
+ return False;
}
-
- pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
- LDAP_OBJ_GROUPMAP,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
-
- SAFE_FREE(escape_name);
-
- return ldapsam_getgroup(methods, filter, map);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
- gid_t gid,
- LDAPMessage **result)
-{
- pstring filter;
-
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s)(objectclass=%s))(%s=%lu))",
- LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY, LDAP_OBJ_GROUPMAP,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- (unsigned long)gid);
-
- return ldapsam_search_one_group(ldap_state, filter, result);
}
/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
+Get SAM_ACCOUNT entry from LDAP by rid
+*********************************************************************/
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
- LDAPMessage *result = NULL;
- LDAPMod **mods = NULL;
- int count;
-
- char *tmp;
- pstring dn;
+ LDAP *ldap_struct;
+ LDAPMessage *result;
LDAPMessage *entry;
- GROUP_MAP dummy;
-
- int rc;
-
- if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
- map->gid))) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
- if (rc != LDAP_SUCCESS) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if ( count == 0 ) {
- /* There's no posixGroup account, let's try to find an
- * appropriate idmap entry for aliases */
-
- pstring suffix;
- pstring filter;
- char **attr_list;
-
- ldap_msgfree(result);
+ if (!ldap_open_connection(&ldap_struct))
+ return False;
- pstrcpy( suffix, lp_ldap_idmap_suffix() );
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
- map->gid);
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state->smbldap_state, suffix,
- LDAP_SCOPE_SUBTREE, filter, attr_list,
- 0, &result);
-
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("Failure looking up entry (%s)\n",
- ldap_err2string(rc) ));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ if (!ldap_connect_system(ldap_struct))
+ {
+ ldap_unbind(ldap_struct);
+ return False;
}
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
- if ( count == 0 ) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ if (ldap_search_one_user_by_rid(ldap_struct, rid, &result) !=
+ LDAP_SUCCESS)
+ {
+ ldap_unbind(ldap_struct);
+ return False;
}
- if (count > 1) {
- DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
- (unsigned long)map->gid));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ if (ldap_count_entries(ldap_struct, result) < 1)
+ {
+ DEBUG(0,
+ ("We don't find this rid [%i] count=%d\n", rid,
+ ldap_count_entries(ldap_struct, result)));
+ ldap_unbind(ldap_struct);
+ return False;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!tmp) {
+ entry = ldap_first_entry(ldap_struct, result);
+ if (entry)
+ {
+ init_sam_from_ldap(user, ldap_struct, entry);
ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ ldap_unbind(ldap_struct);
+ return True;
}
- pstrcpy(dn, tmp);
- SAFE_FREE(tmp);
-
- if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
- result, &mods, map)) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
- ldap_mods_free(mods, True);
+ else
+ {
ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ldap_msgfree(result);
-
- if (mods == NULL) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
-
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- ldap_mods_free(mods, True);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid,
- ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
- return NT_STATUS_UNSUCCESSFUL;
+ ldap_unbind(ldap_struct);
+ return False;
}
-
- DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_OK;
}
/**********************************************************************
- *********************************************************************/
+Delete entry from LDAP for username
+*********************************************************************/
-static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
+BOOL pdb_delete_sam_account(const char *sname)
{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
int rc;
- char *dn = NULL;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- LDAPMod **mods = NULL;
-
- rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
-
- if (rc != LDAP_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
- DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
-
- if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
- result, &mods, map)) {
- DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
- ldap_msgfree(result);
- if (mods != NULL)
- ldap_mods_free(mods,True);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ char *dn;
+ LDAP *ldap_struct;
+ LDAPMessage *entry;
+ LDAPMessage *result;
- if (mods == NULL) {
- DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
- ldap_msgfree(result);
- return NT_STATUS_OK;
- }
+ /* Ensure we have euid as root - else deny this. */
+ if (!ldap_open_connection (&ldap_struct))
+ return False;
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
+
+ if (!ldap_connect_system (ldap_struct)) {
+ ldap_unbind (ldap_struct);
+ DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
+ return False;
}
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- SAFE_FREE(dn);
-
- ldap_mods_free(mods, True);
- ldap_msgfree(result);
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
- ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
- return NT_STATUS_UNSUCCESSFUL;
+ rc = ldap_search_one_user_by_name (ldap_struct, sname, &result);
+ if (ldap_count_entries (ldap_struct, result) == 0) {
+ DEBUG (0, ("User doesn't exit!\n"));
+ ldap_msgfree (result);
+ ldap_unbind (ldap_struct);
+ return False;
}
- DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
- DOM_SID sid)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
- pstring sidstring, filter;
- LDAPMessage *result = NULL;
- int rc;
- NTSTATUS ret;
- char **attr_list;
-
- sid_to_string(sidstring, &sid);
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
+ entry = ldap_first_entry (ldap_struct, result);
+ dn = ldap_get_dn (ldap_struct, entry);
- rc = ldapsam_search_one_group(ldap_state, filter, &result);
+ rc = ldap_delete_s (ldap_struct, dn);
+ ldap_memfree (dn);
if (rc != LDAP_SUCCESS) {
- return NT_STATUS_NO_SUCH_GROUP;
+ char *ld_error;
+ ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
+ sname, ldap_err2string (rc), ld_error));
+ free (ld_error);
+ ldap_unbind (ldap_struct);
+ return False;
}
- attr_list = get_attr_list( groupmap_attr_list_to_delete );
- ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
- free_attr_list ( attr_list );
-
- ldap_msgfree(result);
-
- return ret;
+ DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
+ ldap_unbind (ldap_struct);
+ return True;
}
/**********************************************************************
- *********************************************************************/
+Update SAM_ACCOUNT
+*********************************************************************/
-static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- fstring filter;
int rc;
- char **attr_list;
-
- pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
- attr_list = get_attr_list( groupmap_attr_list );
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
- ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- ldap_state->result)));
-
- ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
- ldap_state->index = 0;
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
-{
- ldapsam_endsampwent(my_methods);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
- GROUP_MAP *map)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- BOOL bret = False;
-
- while (!bret) {
- if (!ldap_state->entry)
- return ret;
-
- ldap_state->index++;
- bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
-
- ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- ldap_state->entry);
- }
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only)
-{
- GROUP_MAP map;
- GROUP_MAP *mapt;
- int entries = 0;
-
- *num_entries = 0;
- *rmap = NULL;
-
- if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
- DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
- if (sid_name_use != SID_NAME_UNKNOWN &&
- sid_name_use != map.sid_name_use) {
- DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
- continue;
- }
- if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
- DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map.nt_name));
- continue;
- }
-
- mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
- if (!mapt) {
- DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
- SAFE_FREE(*rmap);
- return NT_STATUS_UNSUCCESSFUL;
- }
- else
- (*rmap) = mapt;
-
- mapt[entries] = map;
-
- entries += 1;
-
- }
- ldapsam_endsamgrent(methods);
-
- *num_entries = entries;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias,
- const DOM_SID *member,
- int modop)
-{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
char *dn;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
- LDAPMod **mods = NULL;
- int rc;
-
- pstring filter;
-
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_GROUP_SID),
- sid_string_static(alias));
-
- if (ldapsam_search_one_group(ldap_state, filter,
- &result) != LDAP_SUCCESS)
- return NT_STATUS_NO_SUCH_ALIAS;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- result);
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ LDAPMod **mods;
- if (count < 1) {
- DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_ALIAS;
- }
+ if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+ return False;
- if (count > 1) {
- DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
- "count=%d\n", filter, count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_ALIAS;
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */ {
+ ldap_unbind(ldap_struct);
+ return False;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- result);
+ rc = ldap_search_one_user_by_name(ldap_struct,
+ pdb_get_username(newpwd), &result);
- if (!entry) {
+ if (ldap_count_entries(ldap_struct, result) == 0) {
+ DEBUG(0, ("No user to modify!\n"));
ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ ldap_unbind(ldap_struct);
+ return False;
}
- smbldap_set_mod(&mods, modop,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_SID_LIST),
- sid_string_static(member));
+ init_ldap_from_sam(&mods, LDAP_MOD_REPLACE, newpwd);
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+ entry = ldap_first_entry(ldap_struct, result);
+ dn = ldap_get_dn(ldap_struct, entry);
- ldap_mods_free(mods, True);
- ldap_msgfree(result);
+ rc = ldap_modify_s(ldap_struct, dn, mods);
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct,
- LDAP_OPT_ERROR_STRING,&ld_error);
-
- DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify attributes "
- "for %s, error: %s (%s)\n", dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- SAFE_FREE(dn);
- return NT_STATUS_UNSUCCESSFUL;
+ char *ld_error;
+ ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING,
+ &ld_error);
+ DEBUG(0,
+ ("failed to modify user with uid = %s with: %s\n\t%s\n",
+ pdb_get_username(newpwd), ldap_err2string(rc),
+ ld_error));
+ free(ld_error);
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return False;
}
- SAFE_FREE(dn);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias,
- const DOM_SID *member)
-{
- return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
+ DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
+ pdb_get_username(newpwd)));
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return True;
}
-static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias,
- const DOM_SID *member)
-{
- return ldapsam_modify_aliasmem(methods, alias, member,
- LDAP_MOD_DELETE);
-}
+/**********************************************************************
+Add SAM_ACCOUNT to LDAP
+*********************************************************************/
-static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias, DOM_SID **members,
- int *num_members)
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
- char **values;
- int i;
- pstring filter;
-
- *members = NULL;
- *num_members = 0;
-
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_GROUP_SID),
- sid_string_static(alias));
-
- if (ldapsam_search_one_group(ldap_state, filter,
- &result) != LDAP_SUCCESS)
- return NT_STATUS_NO_SUCH_ALIAS;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- result);
-
- if (count < 1) {
- DEBUG(4, ("ldapsam_add_aliasmem: Did not find alias\n"));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_ALIAS;
- }
-
- if (count > 1) {
- DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
- "count=%d\n", filter, count));
- ldap_msgfree(result);
- return NT_STATUS_NO_SUCH_ALIAS;
- }
+ int rc;
+ pstring filter;
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ pstring dn;
+ LDAPMod **mods;
+ int ldap_op;
+ uint32 num_result;
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- result);
+ if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+ return False;
- if (!entry) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */ {
+ ldap_unbind(ldap_struct);
+ return False;
}
- values = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
- entry,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_SID_LIST));
+ rc = ldap_search_one_user_by_name (ldap_struct, pdb_get_username(newpwd), &result);
- if (values == NULL) {
+ if (ldap_count_entries(ldap_struct, result) != 0) {
+ DEBUG(0,("User already in the base, with samba properties\n"));
ldap_msgfree(result);
- return NT_STATUS_OK;
- }
-
- count = ldap_count_values(values);
-
- for (i=0; i<count; i++) {
- DOM_SID member;
-
- if (!string_to_sid(&member, values[i]))
- continue;
-
- add_sid_to_array(&member, members, num_members);
- }
-
- ldap_value_free(values);
- ldap_msgfree(result);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num)
-{
- struct ldapsam_privates *ldap_state =
- (struct ldapsam_privates *)methods->private_data;
-
- fstring sid_string;
- const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
-
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- int count;
- int rc;
- pstring filter;
-
- sid_to_string(sid_string, sid);
- pstr_sprintf(filter, "(&(|(objectclass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_SID_LIST), sid_string);
-
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
-
- if (rc != LDAP_SUCCESS)
- return NT_STATUS_UNSUCCESSFUL;
-
- *aliases = NULL;
- *num = 0;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- result);
-
- if (count < 1) {
- ldap_msgfree(result);
- return NT_STATUS_OK;
- }
-
-
- for (entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- result);
- entry != NULL;
- entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- entry))
- {
- DOM_SID alias;
- char **vals;
- vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
- entry, LDAP_ATTRIBUTE_SID);
-
- if (vals == NULL)
- continue;
-
- if (vals[0] == NULL) {
- ldap_value_free(vals);
- continue;
- }
-
- if (!string_to_sid(&alias, vals[0])) {
- ldap_value_free(vals);
- continue;
- }
-
- add_sid_to_array(&alias, aliases, num);
- ldap_value_free(vals);
+ ldap_unbind(ldap_struct);
+ return False;
}
-
ldap_msgfree(result);
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Privileges related functions
- *********************************************************************/
-
-static NTSTATUS ldapsam_lsa_create_account(struct pdb_methods *my_methods, const DOM_SID *sid)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMod **mods = NULL;
- fstring sid_str;
- fstring filter;
- char **attr_list, *dn;
- int rc;
- if ((sid == NULL) || (!sid_to_string(sid_str, sid))) {
- DEBUG(3, ("ldapsam_lsa_create_account: Invalid SID\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
+ slprintf (filter, sizeof (filter) - 1, "uid=%s", pdb_get_username(newpwd));
+ rc = ldap_search_one_user(ldap_struct, filter, &result);
+ num_result = ldap_count_entries(ldap_struct, result);
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_PRIVILEGE, LDAP_ATTRIBUTE_SID, sid_str);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_lsa_create_account: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_lsa_create_account: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- goto done;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) {
- /* if the sid does not exist
- * and it is not in our local domain then
- * quit otherwise create it */
-
- if (sid_check_is_in_our_domain(sid)) {
-
- ldap_msgfree(ldap_state->result);
- pstr_sprintf(filter, "%s=%s", LDAP_ATTRIBUTE_SID, sid_str);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_lsa_create_account: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_lsa_create_account: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- goto done;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 1) {
- /* entry found */
- ret = NT_STATUS_OK;
- } else {
- /* no way */
- ret = NT_STATUS_UNSUCCESSFUL;
- }
- goto done;
-
- }
-
- /* if not store a new sid entry there */
-
- DEBUG(3, ("SID not found on ldap tree, creating a new entry\n"));
- if (asprintf(&dn, "%s=%s,%s", get_attr_key2string( privilege_attr_list, LDAP_ATTR_SID), sid_str, lp_ldap_idmap_suffix()) < 0) {
- DEBUG(0, ("ldapsam_lsa_create_account: Out of memory\n"));
- goto done;
- }
-
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_PRIVILEGE);
-
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SID_ENTRY);
-
- rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
-
- /* free used structures */
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
-
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,
- ("ldapsam_lsa_create_account:"
- "Failed to create the lsa account dn= %s with: %s\n\t%s\n",
- dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown")
- );
-
- SAFE_FREE(ld_error);
- goto done;
- }
-
- ret = NT_STATUS_OK;
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return ret;
-}
-
-static NTSTATUS ldapsam_lsa_enumerate_accounts(struct pdb_methods *my_methods, DOM_SID **sid_list, int *sid_count)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *entry = NULL;
- fstring filter;
- char **attr_list;
- int rc;
-
- *sid_list = NULL;
- *sid_count = 0;
-
- pstr_sprintf(filter, "(|(objectclass=%s)(objectclass=%s))", LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_GROUPMAP);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_lsa_enumerate_accounts: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_lsa_enumerate_accounts: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- goto done;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) {
- ret = NT_STATUS_NO_MORE_ENTRIES;
- goto done;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
-
- do {
- DOM_SID tmpsid;
- pstring sid_string;
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_string)) {
- DEBUG(3, ("ldapsam_lsa_enumerate_accounts: No sambaSID when searching for sambaSID !?\n"));
- ret = NT_STATUS_NO_MORE_ENTRIES;
- goto done;
- }
-
- /* add the discovered sid */
-
- if (!string_to_sid(&tmpsid, sid_string)) {
- DEBUG(3, ("Could not convert SID\n"));
- continue;
- }
-
- add_sid_to_array(&tmpsid, sid_list, sid_count);
-
- if (sid_list == NULL) {
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- } while((entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry)) != NULL);
-
-
- ret = NT_STATUS_OK;
-
-done:
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return ret;
-}
-
-static NTSTATUS ldapsam_modify_privilege_list_for_sid(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid, int ldap_op)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *entry = NULL;
- LDAPMod **mods = NULL;
- fstring sid_str;
- fstring filter;
- char **attr_list, *dn;
- int rc;
-
- if ((sid == NULL) || (!sid_to_string(sid_str, sid))) {
- DEBUG(3, ("ldapsam_modify_privilege_list_for_sid: Invalid SID\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ if (num_result > 1) {
+ DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
+ return False;
}
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_PRIVILEGE, LDAP_ATTRIBUTE_SID, sid_str);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_modify_privilege_list_for_sid: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_modify_privilege_list_for_sid: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- goto done;
+ /* Check if we need to update an existing entry */
+ if (num_result == 1) {
+ char *tmp;
+ LDAPMessage *entry;
+
+ DEBUG(3,("User exists without samba properties: adding them\n"));
+ ldap_op = LDAP_MOD_REPLACE;
+ entry = ldap_first_entry (ldap_struct, result);
+ tmp = ldap_get_dn (ldap_struct, entry);
+ slprintf (dn, sizeof (dn) - 1, "%s", tmp);
+ ldap_memfree (tmp);
+ } else {
+ /* Check if we need to add an entry */
+ DEBUG(3,("Adding new user\n"));
+ ldap_op = LDAP_MOD_ADD;
+ slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", pdb_get_username(newpwd), lp_ldap_suffix ());
}
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) {
- /* if the sid does not exist and we are adding
- * and it is not in our local domain then
- * create it */
-
- if (ldap_op != LDAP_MOD_ADD) {
- /* nothing to do */
- goto done;
- }
-
- if (sid_check_is_in_our_domain(sid)) {
-
- ldap_msgfree(ldap_state->result);
- pstr_sprintf(filter, "%s=%s", LDAP_ATTRIBUTE_SID, sid_str);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_modify_privilege_list_for_sid: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_modify_privilege_list_for_sid: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- goto done;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) != 1) {
- goto done;
- }
-
- /* entry found */
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
-
- /* retrieve the dn */
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- DEBUG(3, ("ldapsam_modify_privilege_list_for_sid: Unable to get the dn ?!\n"));
- goto done;
- }
-
- /* prepare the modification */
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_PRIVILEGE);
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaPrivilegeList", privname);
-
- /* modify the privilege */
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
-
- /* free used structures */
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
-
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,
- ("ldapsam_modify_privilege_list_for_sid:"
- "Failed to %s privilege (%s) for dn= %s with: %s\n\t%s\n",
- "add", privname,
- dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown")
- );
- SAFE_FREE(ld_error);
- goto done;
- }
-
- ret = NT_STATUS_OK;
- goto done;
- }
-
- /* if not store a new sid entry there */
-
- DEBUG(3, ("SID not found on ldap tree, creating a new entry\n"));
- if (asprintf(&dn, "%s=%s,%s", get_attr_key2string( privilege_attr_list, LDAP_ATTR_SID), sid_str, lp_ldap_idmap_suffix()) < 0) {
- DEBUG(0, ("ldapsam_modify_privilege_list_for_sid: Out of memory\n"));
- goto done;
- }
-
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_PRIVILEGE);
-
- smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaPrivilegeList", privname);
-
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SID_ENTRY);
-
- rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
-
- /* free used structures */
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
-
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,
- ("ldapsam_modify_privilege_list_for_sid:"
- "Failed to add privilege (%s) dn= %s with: %s\n\t%s\n",
- privname,
- dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown")
- );
-
- SAFE_FREE(ld_error);
- goto done;
- }
-
- ret = NT_STATUS_OK;
- goto done;
- }
+ ldap_msgfree(result);
- /* entry found */
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
+ init_ldap_from_sam(&mods, ldap_op, newpwd);
+ make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
- /* retrieve the dn */
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- DEBUG(3, ("ldapsam_modify_privilege_list_for_sid: Unable to get the dn ?!\n"));
- goto done;
+ if (ldap_op == LDAP_MOD_REPLACE) {
+ rc = ldap_modify_s(ldap_struct, dn, mods);
+ } else {
+ make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
+ rc = ldap_add_s(ldap_struct, dn, mods);
}
- /* prepare the modification */
- smbldap_set_mod(&mods, ldap_op, "sambaPrivilegeList", privname);
-
- /* modify the privilege */
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
-
- /* free used structures */
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
-
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
-
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(1,
- ("ldapsam_modify_privilege_list_for_sid:"
- "Failed to %s privilege (%s) for dn= %s with: %s\n\t%s\n",
- (ldap_op == LDAP_MOD_ADD) ? "add" : "remove",
- privname,
- dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown")
- );
- SAFE_FREE(ld_error);
- goto done;
+ char *ld_error;
+
+ ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(0,("failed to modify user with uid = %s with: %s\n\t%s\n",
+ pdb_get_username(newpwd), ldap_err2string (rc), ld_error));
+ free(ld_error);
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return False;
}
-
- ret = NT_STATUS_OK;
-
-done:
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return ret;
-}
-
-static NTSTATUS ldapsam_add_privilege_to_sid(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid)
-{
- return ldapsam_modify_privilege_list_for_sid(my_methods, privname, sid, LDAP_MOD_ADD);
-}
-
-static NTSTATUS ldapsam_remove_privilege_from_sid(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid)
-
-{
- return ldapsam_modify_privilege_list_for_sid(my_methods, privname, sid, LDAP_MOD_DELETE);
-}
-
-static NTSTATUS ldapsam_get_privilege_set(struct pdb_methods *my_methods, DOM_SID *user_sids, int num_sids, PRIVILEGE_SET *privset)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *entry = NULL;
- fstring sid_str;
- fstring filter;
- char **attr_list;
- int rc, i, j;
-
- for (i = 0; i < num_sids; i++) {
- char **values = NULL;
-
- sid_to_string(sid_str, &user_sids[i]);
- pstr_sprintf(filter, "(&(objectclass=%s)(%s=%s))", LDAP_OBJ_PRIVILEGE, LDAP_ATTRIBUTE_SID, sid_str);
- attr_list = get_attr_list(privilege_attr_list);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &ldap_state->result);
- free_attr_list(attr_list);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_get_privilege_set: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_get_privilege_set: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- continue;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) {
- DEBUG(3, ("ldapsam_get_privilege_set: No privileges in ldap tree\n"));
- ret = NT_STATUS_OK;
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- continue;
- }
-
- DEBUG(2, ("ldapsam_get_privilege_set: %d entries in the base!\n",
- ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result)));
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
-
-
- if ((values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_PRIVILEGE_LIST)) == NULL) {
- DEBUG(10, ("ldapsam_get_privilege_set: Privilege List not found skipping SID\n"));
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- continue;
- }
-
- j = 0;
- while (values[j] != 0) {
- add_privilege_by_name(privset, values[j]);
- j++;
- }
-
- ldap_value_free(values);
- values = NULL;
-
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- }
-
- ret = NT_STATUS_OK;
-
- return ret;
-}
-
-static NTSTATUS ldapsam_get_privilege_entry(struct pdb_methods *my_methods, const char *privname, DOM_SID **sid_list, int *sid_count)
-{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- LDAPMessage *entry = NULL;
- fstring filter;
- int rc;
-
- *sid_list = NULL;
- pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivilegeList=%s))", LDAP_OBJ_PRIVILEGE, privname);
- rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- NULL, 0, &ldap_state->result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_get_privilege_entry: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_get_privilege_entry: Query was: %s, %s\n", lp_ldap_suffix(), filter));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) {
- DEBUG(3, ("ldapsam_get_privilege_entry: No such privilege [%s] in ldap tree\n", privname));
- goto done;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
-
- do {
- DOM_SID tmpsid;
- pstring sid_string;
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_string)) {
- DEBUG(3, ("ldapsam_get_privilege_entry: No sid for (%s) in ldap tree !?\n", privname));
- goto done;
- }
-
- /* add the discovered sid */
-
- if (!string_to_sid(&tmpsid, sid_string)) {
- DEBUG(3, ("Could not convert SID\n"));
- } else {
-
- add_sid_to_array(&tmpsid, sid_list, sid_count);
-
- if (sid_list == NULL) {
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
- }
-
- } while ((entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry)) != NULL);
-
- ret = NT_STATUS_OK;
-done:
- ldap_msgfree(ldap_state->result);
- ldap_state->result = NULL;
- return ret;
-}
-
-
-static NTSTATUS ldapsam_settrustpwent(struct pdb_methods *methods)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const char *name)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_add_trust_passwd(struct pdb_methods* methods, SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-static NTSTATUS ldapsam_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
- return nt_status;
-}
-
-
-/**********************************************************************
- Housekeeping
- *********************************************************************/
-
-static void free_private_data(void **vp)
-{
- struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
-
- smbldap_free_struct(&(*ldap_state)->smbldap_state);
-
- if ((*ldap_state)->result != NULL) {
- ldap_msgfree((*ldap_state)->result);
- (*ldap_state)->result = NULL;
- }
-
- *ldap_state = NULL;
-
- /* No need to free any further, as it is talloc()ed */
-}
-
-/**********************************************************************
- Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
- *********************************************************************/
-
-static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- struct ldapsam_privates *ldap_state;
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "ldapsam";
-
- (*pdb_method)->setsampwent = ldapsam_setsampwent;
- (*pdb_method)->endsampwent = ldapsam_endsampwent;
- (*pdb_method)->getsampwent = ldapsam_getsampwent;
- (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
- (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
- (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
- (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
- (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
-
- (*pdb_method)->getgrsid = ldapsam_getgrsid;
- (*pdb_method)->getgrgid = ldapsam_getgrgid;
- (*pdb_method)->getgrnam = ldapsam_getgrnam;
- (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
-
- (*pdb_method)->lsa_create_account = ldapsam_lsa_create_account;
- (*pdb_method)->lsa_enumerate_accounts = ldapsam_lsa_enumerate_accounts;
- (*pdb_method)->add_privilege_to_sid = ldapsam_add_privilege_to_sid;
- (*pdb_method)->remove_privilege_from_sid = ldapsam_remove_privilege_from_sid;
- (*pdb_method)->get_privilege_set = ldapsam_get_privilege_set;
- (*pdb_method)->get_privilege_entry = ldapsam_get_privilege_entry;
-
- (*pdb_method)->settrustpwent = ldapsam_settrustpwent;
- (*pdb_method)->gettrustpwent = ldapsam_gettrustpwent;
- (*pdb_method)->gettrustpwnam = ldapsam_gettrustpwnam;
- (*pdb_method)->gettrustpwsid = ldapsam_gettrustpwsid;
- (*pdb_method)->add_trust_passwd = ldapsam_add_trust_passwd;
- (*pdb_method)->update_trust_passwd = ldapsam_update_trust_passwd;
- (*pdb_method)->delete_trust_passwd = ldapsam_delete_trust_passwd;
-
- /* TODO: Setup private data and free */
-
- ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state));
- if (!ldap_state) {
- DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!NT_STATUS_IS_OK(nt_status =
- smbldap_init(pdb_context->mem_ctx, location,
- &ldap_state->smbldap_state)));
-
- ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
- if (!ldap_state->domain_name) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*pdb_method)->private_data = ldap_state;
-
- (*pdb_method)->free_private_data = free_private_data;
-
- return NT_STATUS_OK;
+ DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
+ ldap_mods_free(mods, 1);
+ ldap_unbind(ldap_struct);
+ return True;
}
-/**********************************************************************
- Initialise the 'compat' mode for pdb_ldap
- *********************************************************************/
-
-static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+#else
+void dummy_function(void);
+void
+dummy_function (void)
{
- NTSTATUS nt_status;
- struct ldapsam_privates *ldap_state;
-
-#ifdef WITH_LDAP_SAMCONFIG
- if (!location) {
- int ldap_port = lp_ldap_port();
-
- /* remap default port if not using SSL (ie clear or TLS) */
- if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
- ldap_port = 389;
- }
-
- location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
- if (!location) {
- return NT_STATUS_NO_MEMORY;
- }
- }
+} /* stop some compilers complaining */
#endif
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "ldapsam_compat";
-
- ldap_state = (*pdb_method)->private_data;
- ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
-
- sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Initialise the normal mode for pdb_ldap
- *********************************************************************/
-
-static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
- struct ldapsam_privates *ldap_state;
- uint32 alg_rid_base;
- pstring alg_rid_base_string;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- DOM_SID ldap_domain_sid;
- DOM_SID secrets_domain_sid;
- pstring domain_sid_string;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "ldapsam";
-
- (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
- (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
- (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
- (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
-
- ldap_state = (*pdb_method)->private_data;
- ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
-
- /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
-
- nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result,
- ldap_state->domain_name, True);
-
- if ( !NT_STATUS_IS_OK(nt_status) ) {
- DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
- DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
-and will risk BDCs having inconsistant SIDs\n"));
- sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
- return NT_STATUS_OK;
- }
-
- /* Given that the above might fail, everything below this must be optional */
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- if (!entry) {
- DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- domain_sid_string)) {
- BOOL found_sid;
- if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
- DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string));
- return NT_STATUS_INVALID_PARAMETER;
- }
- found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid);
- if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) {
- fstring new_sid_str, old_sid_str;
- DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
- ldap_state->domain_name,
- sid_to_string(old_sid_str, &secrets_domain_sid),
- sid_to_string(new_sid_str, &ldap_domain_sid)));
-
- /* reset secrets.tdb sid */
- secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid);
- DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str, get_global_sam_sid())));
- }
- sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
- }
-
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ALGORITHMIC_RID_BASE),
- alg_rid_base_string)) {
- alg_rid_base = (uint32)atol(alg_rid_base_string);
- if (alg_rid_base != algorithmic_rid_base()) {
- DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
- "database was initialised. Aborting. \n"));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- ldap_msgfree(result);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_ldap_init(void)
-{
- NTSTATUS nt_status;
- if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
- return nt_status;
-
- if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
- return nt_status;
-
- return NT_STATUS_OK;
-}
diff --git a/source/passdb/pdb_mysql.c b/source/passdb/pdb_mysql.c
deleted file mode 100644
index deed27dbe49..00000000000
--- a/source/passdb/pdb_mysql.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * MySQL password backend for samba
- * Copyright (C) Jelmer Vernooij 2002-2004
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include <mysql/mysql.h>
-
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "3306"
-#define CONFIG_DB_DEFAULT "samba"
-
-static int mysqlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS mysqlsam_debug_level
-
-typedef struct pdb_mysql_data {
- MYSQL *handle;
- MYSQL_RES *pwent;
- const char *location;
-} pdb_mysql_data;
-
-#define SET_DATA(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return NT_STATUS_INVALID_PARAMETER; \
- } \
- data = (struct pdb_mysql_data *)methods->private_data; \
- if(!data || !(data->handle)){ \
- DEBUG(0, ("invalid handle!\n")); \
- return NT_STATUS_INVALID_HANDLE; \
- } \
-}
-
-#define config_value( data, name, default_value ) \
- lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value )
-
-static long xatol(const char *d)
-{
- if(!d) return 0;
- return atol(d);
-}
-
-static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
-{
- MYSQL_ROW row;
- pstring temp;
- unsigned int num_fields;
- DOM_SID sid;
-
- num_fields = mysql_num_fields(r);
- row = mysql_fetch_row(r);
- if (!row)
- return NT_STATUS_INVALID_PARAMETER;
-
- pdb_set_logon_time(u, xatol(row[0]), PDB_SET);
- pdb_set_logoff_time(u, xatol(row[1]), PDB_SET);
- pdb_set_kickoff_time(u, xatol(row[2]), PDB_SET);
- pdb_set_pass_last_set_time(u, xatol(row[3]), PDB_SET);
- pdb_set_pass_can_change_time(u, xatol(row[4]), PDB_SET);
- pdb_set_pass_must_change_time(u, xatol(row[5]), PDB_SET);
- pdb_set_username(u, row[6], PDB_SET);
- pdb_set_domain(u, row[7], PDB_SET);
- pdb_set_nt_username(u, row[8], PDB_SET);
- pdb_set_fullname(u, row[9], PDB_SET);
- pdb_set_homedir(u, row[10], PDB_SET);
- pdb_set_dir_drive(u, row[11], PDB_SET);
- pdb_set_logon_script(u, row[12], PDB_SET);
- pdb_set_profile_path(u, row[13], PDB_SET);
- pdb_set_acct_desc(u, row[14], PDB_SET);
- pdb_set_workstations(u, row[15], PDB_SET);
- pdb_set_unknown_str(u, row[16], PDB_SET);
- pdb_set_munged_dial(u, row[17], PDB_SET);
-
- if(!row[18] || !string_to_sid(&sid, row[18])) {
- DEBUG(0,("No user SID retrieved from database!\n"));
- } else {
- pdb_set_user_sid(u, &sid, PDB_SET);
- }
-
- if(row[19]) {
- string_to_sid(&sid, row[19]);
- pdb_set_group_sid(u, &sid, PDB_SET);
- }
-
- if (pdb_gethexpwd(row[20], temp))
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- if (pdb_gethexpwd(row[21], temp))
- pdb_set_nt_passwd(u, temp, PDB_SET);
-
- /* Only use plaintext password storage when lanman and nt are
- * NOT used */
- if (!row[20] || !row[21])
- pdb_set_plaintext_passwd(u, row[22]);
-
- pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET);
- pdb_set_logon_divs(u, xatol(row[25]), PDB_SET);
- pdb_set_hours_len(u, xatol(row[26]), PDB_SET);
- pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET);
- pdb_set_logon_count(u, xatol(row[28]), PDB_SET);
- pdb_set_unknown_6(u, xatol(row[29]), PDB_SET);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
- char *query;
- int ret;
-
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- query = sql_account_query_select(data->location, update, SQL_SEARCH_NONE, NULL);
-
- ret = mysql_query(data->handle, query);
- SAFE_FREE(query);
-
- if (ret) {
- DEBUG(0,
- ("Error executing MySQL query %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- data->pwent = mysql_store_result(data->handle);
-
- if (data->pwent == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5,
- ("mysqlsam_setsampwent succeeded(%llu results)!\n",
- mysql_num_rows(data->pwent)));
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void mysqlsam_endsampwent(struct pdb_methods *methods)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
-
- if (data == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return;
- }
-
- if (data->pwent != NULL)
- mysql_free_result(data->pwent);
-
- data->pwent = NULL;
-
- DEBUG(5, ("mysql_endsampwent called\n"));
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS mysqlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (data->pwent == NULL) {
- DEBUG(0, ("invalid pwent\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return row_to_sam_account(data->pwent, user);
-}
-
-static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOUNT * user,
- enum sql_search_field field, const char *sname)
-{
- char *esc_sname;
- char *query;
- NTSTATUS ret;
- MYSQL_RES *res;
- int mysql_ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
-
- SET_DATA(data, methods);
-
- esc_sname = malloc(strlen(sname) * 2 + 1);
- if (!esc_sname) {
- return NT_STATUS_NO_MEMORY;
- }
-
- tmp_sname = smb_xstrdup(sname);
-
- /* Escape sname */
- mysql_real_escape_string(data->handle, esc_sname, tmp_sname,
- strlen(tmp_sname));
-
- SAFE_FREE(tmp_sname);
-
- if (user == NULL) {
- DEBUG(0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- SAFE_FREE(esc_sname);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- query = sql_account_query_select(data->location, True, field, esc_sname);
-
- SAFE_FREE(esc_sname);
-
- DEBUG(5, ("Executing query %s\n", query));
-
- mysql_ret = mysql_query(data->handle, query);
-
- SAFE_FREE(query);
-
- if (mysql_ret) {
- DEBUG(0,
- ("Error while executing MySQL query %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- res = mysql_store_result(data->handle);
- if (res == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = row_to_sam_account(res, user);
- mysql_free_result(res);
-
- return ret;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS mysqlsam_getsampwnam(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const char *sname)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (!sname) {
- DEBUG(0, ("invalid name specified"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return mysqlsam_select_by_field(methods, user,
- SQL_SEARCH_USER_NAME, sname);
-}
-
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS mysqlsam_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const DOM_SID * sid)
-{
- struct pdb_mysql_data *data;
- fstring sid_str;
-
- SET_DATA(data, methods);
-
- sid_to_string(sid_str, sid);
-
- return mysqlsam_select_by_field(methods, user, SQL_SEARCH_USER_SID, sid_str);
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS mysqlsam_delete_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * sam_pass)
-{
- const char *sname = pdb_get_username(sam_pass);
- char *esc;
- char *query;
- int ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
-
- SET_DATA(data, methods);
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- if (!sname) {
- DEBUG(0, ("invalid name specified\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Escape sname */
- esc = malloc(strlen(sname) * 2 + 1);
- if (!esc) {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- tmp_sname = smb_xstrdup(sname);
-
- mysql_real_escape_string(data->handle, esc, tmp_sname,
- strlen(tmp_sname));
-
- SAFE_FREE(tmp_sname);
-
- query = sql_account_query_delete(data->location, esc);
-
- SAFE_FREE(esc);
-
- ret = mysql_query(data->handle, query);
-
- SAFE_FREE(query);
-
- if (ret) {
- DEBUG(0,
- ("Error while executing query: %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("User '%s' deleted\n", sname));
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_replace_sam_account(struct pdb_methods *methods,
- const SAM_ACCOUNT * newpwd, char isupdate)
-{
- struct pdb_mysql_data *data;
- char *query;
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
-
- if (data == NULL || data->handle == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- query = sql_account_query_update(data->location, newpwd, isupdate);
-
- /* Execute the query */
- if (mysql_query(data->handle, query)) {
- DEBUG(0,
- ("Error executing %s, %s\n", query,
- mysql_error(data->handle)));
- return NT_STATUS_INVALID_PARAMETER;
- }
- SAFE_FREE(query);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 0);
-}
-
-static NTSTATUS mysqlsam_update_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 1);
-}
-
-static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_methods ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- struct pdb_mysql_data *data;
-
- mysqlsam_debug_level = debug_add_class("mysqlsam");
- if (mysqlsam_debug_level == -1) {
- mysqlsam_debug_level = DBGC_ALL;
- DEBUG(0,
- ("mysqlsam: Couldn't register custom debugging class!\n"));
- }
-
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "mysqlsam";
-
- (*pdb_method)->setsampwent = mysqlsam_setsampwent;
- (*pdb_method)->endsampwent = mysqlsam_endsampwent;
- (*pdb_method)->getsampwent = mysqlsam_getsampwent;
- (*pdb_method)->getsampwnam = mysqlsam_getsampwnam;
- (*pdb_method)->getsampwsid = mysqlsam_getsampwsid;
- (*pdb_method)->add_sam_account = mysqlsam_add_sam_account;
- (*pdb_method)->update_sam_account = mysqlsam_update_sam_account;
- (*pdb_method)->delete_sam_account = mysqlsam_delete_sam_account;
-
- data = talloc(pdb_context->mem_ctx, sizeof(struct pdb_mysql_data));
- (*pdb_method)->private_data = data;
- data->handle = NULL;
- data->pwent = NULL;
-
- if (!location) {
- DEBUG(0, ("No identifier specified. Check the Samba HOWTO Collection for details\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data->location = smb_xstrdup(location);
-
- DEBUG(1,
- ("Connecting to database server, host: %s, user: %s, password: %s, database: %s, port: %ld\n",
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value(data, "mysql port", CONFIG_PORT_DEFAULT))));
-
- /* Do the mysql initialization */
- data->handle = mysql_init(NULL);
- if (!data->handle) {
- DEBUG(0, ("Failed to connect to server\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if(!sql_account_config_valid(data->location)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Process correct entry in $HOME/.my.conf */
- if (!mysql_real_connect(data->handle,
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value (data, "mysql port", CONFIG_PORT_DEFAULT)),
- NULL, 0)) {
- DEBUG(0,
- ("Failed to connect to mysql database: error: %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("Connected to mysql db\n"));
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_mysql_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "mysql", mysqlsam_init);
-}
diff --git a/source/passdb/pdb_nisplus.c b/source/passdb/pdb_nisplus.c
new file mode 100755
index 00000000000..9a929e6c452
--- /dev/null
+++ b/source/passdb/pdb_nisplus.c
@@ -0,0 +1,1374 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ * Copyright (C) Benny Holmgren 1998 <bigfoot@astrakan.hgs.se>
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998.
+ * Copyright (C) Toomas Soome <tsoome@ut.ee> 2001
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NISPLUS_SAM
+
+#ifdef BROKEN_NISPLUS_INCLUDE_FILES
+
+/*
+ * The following lines are needed due to buggy include files
+ * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
+ * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
+ * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
+ * an enum in /usr/include/rpcsvc/nis.h.
+ */
+
+#if defined(GROUP)
+#undef GROUP
+#endif
+
+#if defined(GROUP_OBJ)
+#undef GROUP_OBJ
+#endif
+
+#endif
+
+#include <rpcsvc/nis.h>
+
+extern int DEBUGLEVEL;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
+
+struct nisp_enum_info
+{
+ nis_result *result;
+ int enum_entry;
+};
+
+static struct nisp_enum_info global_nisp_ent;
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+
+ the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
+
+ name=S,nogw=r
+ uid=S,nogw=r
+ user_rid=S,nogw=r
+ smb_grpid=,nw+r
+ group_rid=,nw+r
+ acb=,nw+r
+
+ lmpwd=C,nw=,g=r,o=rm
+ ntpwd=C,nw=,g=r,o=rm
+
+ logon_t=,nw+r
+ logoff_t=,nw+r
+ kick_t=,nw+r
+ pwdlset_t=,nw+r
+ pwdlchg_t=,nw+r
+ pwdmchg_t=,nw+r
+
+ full_name=,nw+r
+ home_dir=,nw+r
+ dir_drive=,nw+r
+ logon_script=,nw+r
+ profile_path=,nw+r
+ acct_desc=,nw+r
+ workstations=,nw+r
+
+ hours=,nw+r
+
+****************************************************************/
+
+#define NPF_NAME 0
+#define NPF_UID 1
+#define NPF_USER_RID 2
+#define NPF_SMB_GRPID 3
+#define NPF_GROUP_RID 4
+#define NPF_ACB 5
+#define NPF_LMPWD 6
+#define NPF_NTPWD 7
+#define NPF_LOGON_T 8
+#define NPF_LOGOFF_T 9
+#define NPF_KICK_T 10
+#define NPF_PWDLSET_T 11
+#define NPF_PWDCCHG_T 12
+#define NPF_PWDMCHG_T 13
+#define NPF_FULL_NAME 14
+#define NPF_HOME_DIR 15
+#define NPF_DIR_DRIVE 16
+#define NPF_LOGON_SCRIPT 17
+#define NPF_PROFILE_PATH 18
+#define NPF_ACCT_DESC 19
+#define NPF_WORKSTATIONS 20
+#define NPF_HOURS 21
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+/***************************************************************
+ make_nisname_from_user_rid
+ ****************************************************************/
+static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
+{
+ static pstring nisname;
+
+ slprintf(nisname, sizeof(nisname)-1, "[user_rid=%d],%s", rid, pfile);
+
+ return nisname;
+}
+
+/***************************************************************
+ make_nisname_from_name
+ ****************************************************************/
+static char *make_nisname_from_name(char *user_name, char *pfile)
+{
+ static pstring nisname;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", user_name, pfile);
+
+ return nisname;
+}
+
+/***************************************************************
+ smb_passwd_table
+
+ * if only plain table in is in pfile, org_dir will be concated.
+ * so, at first we will clear path prefix from pfile, and
+ * then we will use pfiletmp as playground to put together full
+ * nisname string.
+ * such approach will make it possible to specify samba private dir
+ * AND still use NIS+ table. as all domain related data is normally
+ * stored in org_dir.DOMAIN, this should be ok to do.
+ ****************************************************************/
+static char *smb_passwd_table(){
+ char *sp, *p = lp_smb_passwd_file();
+#if 1
+ static pstring pfiletmp;
+#endif
+
+ /* if lp_smb_passwd_file() returns anything wierd, pass it on */
+ if (!p || !*p) return p;
+ sp = strrchr( p, '/' );
+ if (sp) p=sp+1;
+
+#if 1
+ /* append org_dir ONLY if plain table name is used.
+ why we do append it is because NIS_PATH env may not be set,
+ should we check if it's set?
+ do not append if lp_smb_passwd_file() returns an empty string
+ */
+ if (!strchr(p, '.')){
+ slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.org_dir", p);
+ return pfiletmp;
+ }
+#endif
+ return p;
+
+}
+
+/*************************************************************************
+ gets a NIS+ attribute
+ *************************************************************************/
+static void get_single_attribute(nis_object *new_obj, int col,
+ char *val, int len)
+{
+ int entry_len;
+
+ if (new_obj == NULL || val == NULL) return;
+
+ entry_len = ENTRY_LEN(new_obj, col);
+ if (len > entry_len)
+ {
+ len = entry_len;
+ }
+
+ safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
+}
+
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ object.
+ ************************************************************************/
+static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
+{
+ char *ptr;
+ pstring full_name; /* this must be translated to dos code page */
+ pstring acct_desc; /* this must be translated to dos code page */
+ pstring home_dir; /* set default value from smb.conf for user */
+ pstring home_drive; /* set default value from smb.conf for user */
+ pstring logon_script; /* set default value from smb.conf for user */
+ pstring profile_path; /* set default value from smb.conf for user */
+ pstring hours;
+ int hours_len;
+ unsigned char smbpwd[16];
+ unsigned char smbntpwd[16];
+
+
+ /*
+ * time values. note: this code assumes 32bit time_t!
+ */
+
+ pdb_set_logon_time(pw_buf, (time_t)0);
+ ptr = ENTRY_VAL(obj, NPF_LOGON_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_logoff_time(pw_buf, get_time_t_max());
+ ptr = ENTRY_VAL(obj, NPF_LOGOFF_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_kickoff_time(pw_buf, get_time_t_max());
+ ptr = ENTRY_VAL(obj, NPF_KICK_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_last_set_time(pw_buf, (time_t)0);
+ ptr = ENTRY_VAL(obj, NPF_PWDLSET_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_can_change_time(pw_buf, (time_t)0);
+ ptr = ENTRY_VAL(obj, NPF_PWDCCHG_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ pdb_set_pass_must_change_time(pw_buf, get_time_t_max()); /* Password never expires. */
+ ptr = ENTRY_VAL(obj, NPF_PWDMCHG_T);
+ if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) {
+ int i;
+ ptr += 4;
+ for(i = 0; i < 8; i++) {
+ if(ptr[i] == '\0' || !isxdigit(ptr[i]))
+ break;
+ }
+ if(i == 8) {
+ pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
+ }
+ }
+
+ /* string values */
+ pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
+ pdb_set_domain(pw_buf, lp_workgroup());
+ /* pdb_set_nt_username() -- cant set it here... */
+
+ get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
+ unix_to_dos(full_name);
+ pdb_set_fullname(pw_buf, full_name);
+
+ pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
+ NPF_ACB)));
+
+ get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
+ unix_to_dos(acct_desc);
+ pdb_set_acct_desc(pw_buf, acct_desc);
+
+ pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
+ pdb_set_munged_dial(pw_buf, NULL);
+
+/* Might want to consult sys_getpwnam for the following two.
+ for now, use same default as pdb_fill-default_sam */
+
+ ptr = ENTRY_VAL(obj, NPF_UID);
+ pdb_set_uid(pw_buf, ptr ? atoi(ptr) : -1);
+
+ ptr = ENTRY_VAL(obj, NPF_SMB_GRPID);
+ pdb_set_gid(pw_buf, ptr ? atoi(ptr) : -1);
+
+
+ ptr = ENTRY_VAL(obj, NPF_USER_RID);
+ pdb_set_user_rid(pw_buf, ptr ? atoi(ptr) :
+ pdb_uid_to_user_rid(pdb_get_uid(pw_buf)));
+
+ ptr = ENTRY_VAL(obj, NPF_GROUP_RID);
+ pdb_set_group_rid(pw_buf, ptr ? atoi(ptr) :
+ pdb_gid_to_group_rid(pdb_get_gid(pw_buf)));
+
+
+ /* values, must exist for user */
+ if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
+ /* FIXME!! This doesn't belong here.
+ Should be set in net_sam_logon()
+ --jerry */
+ pstrcpy(samlogon_user, pdb_get_username(pw_buf));
+
+ get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
+ if( !(home_dir && *home_dir) ) {
+ pstrcpy(home_dir, lp_logon_home());
+ pdb_set_homedir(pw_buf, home_dir, False);
+ }
+ else
+ pdb_set_homedir(pw_buf, home_dir, True);
+
+ get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
+ if( !(home_drive && *home_drive) ) {
+ pstrcpy(home_drive, lp_logon_drive());
+ pdb_set_dir_drive(pw_buf, home_drive, False);
+ }
+ else
+ pdb_set_dir_drive(pw_buf, home_drive, True);
+
+ get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
+ sizeof(pstring));
+ if( !(logon_script && *logon_script) ) {
+ pstrcpy(logon_script, lp_logon_script());
+ pdb_set_logon_script(pw_buf, logon_script, False);
+ }
+ else
+ pdb_set_logon_script(pw_buf, logon_script, True);
+
+ get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
+ if( !(profile_path && *profile_path) ) {
+ pstrcpy(profile_path, lp_logon_path());
+ pdb_set_profile_path(pw_buf, profile_path, False);
+ }
+ else
+ pdb_set_profile_path(pw_buf, profile_path, True);
+
+ }
+ else
+ {
+ /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+ pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
+ }
+
+ /* Check the lanman password column. */
+ ptr = ENTRY_VAL(obj, NPF_LMPWD);
+ if (!pdb_set_lanman_passwd(pw_buf, NULL))
+ return False;
+
+ if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
+ pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
+ } else {
+ if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
+ DEBUG(0, ("malformed LM pwd entry: %s.\n",
+ pdb_get_username(pw_buf)));
+ return False;
+ }
+ if (!pdb_set_lanman_passwd(pw_buf, smbpwd))
+ return False;
+ }
+
+ /* Check the NT password column. */
+ ptr = ENTRY_VAL(obj, NPF_NTPWD);
+ if (!pdb_set_nt_passwd(pw_buf, NULL))
+ return False;
+
+ if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
+ strncasecmp(ptr, "NO PASSWORD", 11)) {
+ if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
+ DEBUG(0, ("malformed NT pwd entry:\
+ uid = %d.\n",
+ pdb_get_uid(pw_buf)));
+ return False;
+ }
+ if (!pdb_set_nt_passwd(pw_buf, smbntpwd))
+ return False;
+ }
+
+ pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
+ pdb_set_logon_divs(pw_buf, 168); /* hours per week */
+
+ if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
+ memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
+ } else {
+ hours_len = 21; /* 21 times 8 bits = 168 */
+ /* available at all hours */
+ memset(hours, 0xff, hours_len);
+ }
+ pdb_set_hours_len(pw_buf, hours_len);
+ pdb_set_hours(pw_buf, (uchar *)hours);
+
+ pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
+ pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
+
+ return True;
+}
+
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ result.
+ ************************************************************************/
+static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, nis_result *result)
+{
+ if (pw_buf == NULL || result == NULL) return False;
+
+ if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
+ {
+ DEBUG(0, ("NIS+ lookup failure: %s\n",
+ nis_sperrno(result->status)));
+ return False;
+ }
+
+ /* User not found. */
+ if (NIS_RES_NUMOBJ(result) <= 0)
+ {
+ DEBUG(10, ("user not found in NIS+\n"));
+ return False;
+ }
+
+ if (NIS_RES_NUMOBJ(result) > 1)
+ {
+ DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
+ }
+
+ /* Grab the first hit. */
+ return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
+}
+
+/*************************************************************************
+ sets a NIS+ attribute
+ *************************************************************************/
+static void set_single_attribute(nis_object *new_obj, int col,
+ char *val, int len, int flags)
+{
+ if (new_obj == NULL) return;
+
+ ENTRY_VAL(new_obj, col) = val;
+ ENTRY_LEN(new_obj, col) = len+1;
+
+ if (flags != 0)
+ {
+ new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
+ }
+}
+
+/***************************************************************
+ copy or modify nis object. this object is used to add or update
+ nisplus table entry.
+ ****************************************************************/
+static BOOL init_nisp_from_sam(nis_object *obj, SAM_ACCOUNT *sampass,
+ nis_object *old)
+{
+ /*
+ * Fill nis_object for entry add or update.
+ * if we are updateing, we have to find out differences and set
+ * EN_MODIFIED flag. also set need_to_modify to trigger
+ * nis_modify_entry() call in pdb_update_sam_account().
+ *
+ * TODO:
+ * get data from SAM
+ * if (modify) get data from nis_object, compare and store if
+ * different + set EN_MODIFIED and need_to_modify
+ * else
+ * store
+ */
+ BOOL need_to_modify = False;
+ char *name; /* from SAM */
+ /* these must be static or allocate and free entry columns! */
+ static fstring uid; /* from SAM */
+ static fstring user_rid; /* from SAM */
+ static fstring gid; /* from SAM */
+ static fstring group_rid; /* from SAM */
+ char *acb; /* from SAM */
+ static fstring smb_passwd; /* from SAM */
+ static fstring smb_nt_passwd; /* from SAM */
+ static fstring logon_t; /* from SAM */
+ static fstring logoff_t; /* from SAM */
+ static fstring kickoff_t; /* from SAM */
+ static fstring pwdlset_t; /* from SAM */
+ static fstring pwdlchg_t; /* from SAM */
+ static fstring pwdmchg_t; /* from SAM */
+ static fstring full_name; /* from SAM */
+ static fstring acct_desc; /* from SAM */
+ static char empty[1]; /* just an empty string */
+
+
+ name = pdb_get_username(sampass);
+ slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
+ slprintf(user_rid, sizeof(user_rid)-1, "%u",
+ pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
+ pdb_uid_to_user_rid(pdb_get_uid(sampass)));
+ slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
+ slprintf(group_rid, sizeof(group_rid)-1, "%u",
+ pdb_get_group_rid(sampass)? pdb_get_group_rid(sampass):
+ pdb_gid_to_group_rid(pdb_get_gid(sampass)));
+ acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
+ NEW_PW_FORMAT_SPACE_PADDED_LEN);
+ pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
+ pdb_get_acct_ctrl(sampass));
+ pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
+ pdb_get_acct_ctrl(sampass));
+ slprintf(logon_t, 13, "LNT-%08X",
+ (uint32)pdb_get_logon_time(sampass));
+ slprintf(logoff_t, 13, "LOT-%08X",
+ (uint32)pdb_get_logoff_time(sampass));
+ slprintf(kickoff_t, 13, "KOT-%08X",
+ (uint32)pdb_get_kickoff_time(sampass));
+ slprintf(pwdlset_t, 13, "LCT-%08X",
+ (uint32)pdb_get_pass_last_set_time(sampass));
+ slprintf(pwdlchg_t, 13, "CCT-%08X",
+ (uint32)pdb_get_pass_can_change_time(sampass));
+ slprintf(pwdmchg_t, 13, "MCT-%08X",
+ (uint32)pdb_get_pass_must_change_time(sampass));
+ safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
+ dos_to_unix(full_name);
+ safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
+ dos_to_unix(acct_desc);
+
+ if( old ) {
+ /* name */
+ if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
+ {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_NAME, name, strlen(name),
+ EN_MODIFIED);
+ }
+
+
+ /* uid */
+ if(pdb_get_uid(sampass) != -1) {
+ if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
+ {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_UID, uid,
+ strlen(uid), EN_MODIFIED);
+ }
+ }
+
+ /* user_rid */
+ if (pdb_get_user_rid(sampass)) {
+ if(!ENTRY_VAL(old, NPF_USER_RID) ||
+ strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_USER_RID, user_rid,
+ strlen(user_rid), EN_MODIFIED);
+ }
+ }
+
+ /* smb_grpid */
+ if (pdb_get_gid(sampass) != -1) {
+ if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
+ strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_SMB_GRPID, gid,
+ strlen(gid), EN_MODIFIED);
+ }
+ }
+
+ /* group_rid */
+ if (pdb_get_group_rid(sampass)) {
+ if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
+ strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_GROUP_RID, group_rid,
+ strlen(group_rid), EN_MODIFIED);
+ }
+ }
+
+ /* acb */
+ if (!ENTRY_VAL(old, NPF_ACB) ||
+ strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
+ }
+
+ /* lmpwd */
+ if(!ENTRY_VAL(old, NPF_LMPWD) ||
+ strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LMPWD, smb_passwd,
+ strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
+ }
+
+ /* ntpwd */
+ if(!ENTRY_VAL(old, NPF_NTPWD) ||
+ strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
+ strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
+ }
+
+ /* logon_t */
+ if( pdb_get_logon_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_LOGON_T) ||
+ strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGON_T, logon_t,
+ strlen(logon_t), EN_MODIFIED);
+ }
+
+ /* logoff_t */
+ if( pdb_get_logoff_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
+ strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
+ strlen(logoff_t), EN_MODIFIED);
+ }
+
+ /* kick_t */
+ if( pdb_get_kickoff_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_KICK_T) ||
+ strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_KICK_T, kickoff_t,
+ strlen(kickoff_t), EN_MODIFIED);
+ }
+
+ /* pwdlset_t */
+ if( pdb_get_pass_last_set_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
+ strlen(pwdlset_t), EN_MODIFIED);
+ }
+
+ /* pwdlchg_t */
+ if( pdb_get_pass_can_change_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
+ strlen(pwdlchg_t), EN_MODIFIED);
+ }
+
+ /* pwdmchg_t */
+ if( pdb_get_pass_must_change_time(sampass) &&
+ (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
+ strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
+ strlen(pwdmchg_t), EN_MODIFIED);
+ }
+
+ /* full_name */
+ /* must support set, unset and change */
+ if ( (pdb_get_fullname(sampass) &&
+ !ENTRY_VAL(old, NPF_FULL_NAME)) ||
+ (ENTRY_VAL(old, NPF_FULL_NAME) &&
+ !pdb_get_fullname(sampass)) ||
+ (ENTRY_VAL(old, NPF_FULL_NAME) &&
+ pdb_get_fullname(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_FULL_NAME, full_name,
+ strlen(full_name), EN_MODIFIED);
+ }
+
+ /* home_dir */
+ /* must support set, unset and change */
+ if( (pdb_get_homedir(sampass) &&
+ !ENTRY_VAL(old, NPF_HOME_DIR)) ||
+ (ENTRY_VAL(old, NPF_HOME_DIR) &&
+ !pdb_get_homedir(sampass)) ||
+ (ENTRY_VAL(old, NPF_HOME_DIR) &&
+ pdb_get_homedir(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
+ pdb_get_homedir(sampass)))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
+ strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
+ }
+
+ /* dir_drive */
+ /* must support set, unset and change */
+ if( (pdb_get_dirdrive(sampass) &&
+ !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
+ (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
+ !pdb_get_dirdrive(sampass)) ||
+ (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
+ pdb_get_dirdrive(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
+ pdb_get_dirdrive(sampass)))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
+ strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
+ }
+
+ /* logon_script */
+ /* must support set, unset and change */
+ if( (pdb_get_logon_script(sampass) &&
+ !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
+ (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ !pdb_get_logon_script(sampass)) ||
+ ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ pdb_get_logon_script(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
+ pdb_get_logon_script(sampass))))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_LOGON_SCRIPT,
+ pdb_get_logon_script(sampass),
+ strlen(pdb_get_logon_script(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* profile_path */
+ /* must support set, unset and change */
+ if( (pdb_get_profile_path(sampass) &&
+ !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
+ (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
+ !pdb_get_profile_path(sampass)) ||
+ (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
+ pdb_get_profile_path(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
+ pdb_get_profile_path(sampass) ) )) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_PROFILE_PATH,
+ pdb_get_profile_path(sampass),
+ strlen(pdb_get_profile_path(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* acct_desc */
+ /* must support set, unset and change */
+ if( (pdb_get_acct_desc(sampass) &&
+ !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
+ (ENTRY_VAL(old, NPF_ACCT_DESC) &&
+ !pdb_get_acct_desc(sampass)) ||
+ (ENTRY_VAL(old, NPF_ACCT_DESC) &&
+ pdb_get_acct_desc(sampass) &&
+ strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
+ strlen(acct_desc), EN_MODIFIED);
+ }
+
+ /* workstations */
+ /* must support set, unset and change */
+ if ( (pdb_get_workstations(sampass) &&
+ !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
+ (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
+ !pdb_get_workstations(sampass)) ||
+ (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
+ pdb_get_workstations(sampass)) &&
+ strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
+ pdb_get_workstations(sampass))) {
+ need_to_modify = True;
+ set_single_attribute(obj, NPF_WORKSTATIONS,
+ pdb_get_workstations(sampass),
+ strlen(pdb_get_workstations(sampass)),
+ EN_MODIFIED);
+ }
+
+ /* hours */
+ if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
+ memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
+ ENTRY_LEN(old, NPF_HOURS))) {
+ need_to_modify = True;
+ /* set_single_attribute will add 1 for len ... */
+ set_single_attribute(obj, NPF_HOURS, (char *)pdb_get_hours(sampass),
+ pdb_get_hours_len(sampass)-1, EN_MODIFIED);
+ }
+ } else {
+ char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
+
+ *empty = '\0'; /* empty string */
+
+ set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
+ set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
+ set_single_attribute(obj, NPF_USER_RID, user_rid,
+ strlen(user_rid), 0);
+ set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
+ set_single_attribute(obj, NPF_GROUP_RID, group_rid,
+ strlen(group_rid), 0);
+ set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
+ set_single_attribute(obj, NPF_LMPWD, smb_passwd,
+ strlen(smb_passwd), EN_CRYPT);
+ set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
+ strlen(smb_nt_passwd), EN_CRYPT);
+ set_single_attribute(obj, NPF_LOGON_T, logon_t,
+ strlen(logon_t), 0);
+ set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
+ strlen(logoff_t), 0);
+ set_single_attribute(obj, NPF_KICK_T, kickoff_t,
+ strlen(kickoff_t),0);
+ set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
+ strlen(pwdlset_t), 0);
+ set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
+ strlen(pwdlchg_t), 0);
+ set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
+ strlen(pwdmchg_t), 0);
+ set_single_attribute(obj, NPF_FULL_NAME ,
+ full_name, strlen(full_name), 0);
+
+ if(!(homedir = pdb_get_homedir(sampass)))
+ homedir = empty;
+
+ set_single_attribute(obj, NPF_HOME_DIR,
+ homedir, strlen(homedir), 0);
+
+ if(!(dirdrive = pdb_get_dirdrive(sampass)))
+ dirdrive = empty;
+
+ set_single_attribute(obj, NPF_DIR_DRIVE,
+ dirdrive, strlen(dirdrive), 0);
+
+ if(!(logon_script = pdb_get_logon_script(sampass)))
+ logon_script = empty;
+
+ set_single_attribute(obj, NPF_LOGON_SCRIPT,
+ logon_script, strlen(logon_script), 0);
+
+ if(!(profile_path = pdb_get_profile_path(sampass)))
+ profile_path = empty;
+
+ set_single_attribute(obj, NPF_PROFILE_PATH,
+ profile_path, strlen(profile_path), 0);
+
+ set_single_attribute(obj, NPF_ACCT_DESC,
+ acct_desc, strlen(acct_desc), 0);
+
+ if(!(workstations = pdb_get_workstations(sampass)))
+ workstations = empty;
+
+ set_single_attribute(obj, NPF_WORKSTATIONS,
+ workstations, strlen(workstations), 0);
+
+ /* set_single_attribute will add 1 for len ... */
+ set_single_attribute(obj, NPF_HOURS,
+ (char *)pdb_get_hours(sampass),
+ pdb_get_hours_len(sampass)-1, 0);
+ }
+
+ return need_to_modify;
+}
+
+/***************************************************************
+ calls nis_list, returns results.
+ ****************************************************************/
+static nis_result *nisp_get_nis_list(char *nis_name, unsigned int flags)
+{
+ nis_result *result;
+ int i;
+
+ if( ! flags)
+ flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
+
+ for(i = 0; i<2;i++ ) {
+ alarm(60); /* hopefully ok for long searches */
+ result = nis_list(nis_name, flags,NULL,NULL);
+
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
+
+ if (gotalarm)
+ {
+ DEBUG(0,("NIS+ lookup time out\n"));
+ nis_freeresult(result);
+ return NULL;
+ }
+ if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
+ /* nis replicas are not in sync perhaps?
+ * this can happen, if account was just added.
+ */
+ DEBUG(10,("will try master only\n"));
+ nis_freeresult(result);
+ flags |= MASTER_ONLY;
+ } else
+ break;
+ }
+ return result;
+}
+
+/***************************************************************
+ Start to enumerate the nisplus passwd list.
+ ****************************************************************/
+BOOL pdb_setsampwent(BOOL update)
+{
+ char *pfile = smb_passwd_table();
+
+ pdb_endsampwent(); /* just in case */
+ global_nisp_ent.result = nisp_get_nis_list( pfile, 0 );
+ global_nisp_ent.enum_entry = 0;
+ return global_nisp_ent.result != NULL ? True : False;
+}
+
+/***************************************************************
+ End enumeration of the nisplus passwd list.
+****************************************************************/
+void pdb_endsampwent(void)
+{
+ if( global_nisp_ent.result )
+ nis_freeresult(global_nisp_ent.result);
+ global_nisp_ent.result = NULL;
+ global_nisp_ent.enum_entry = 0;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the nisplus passwd list.
+ *************************************************************************/
+BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+{
+ int enum_entry = (int)(global_nisp_ent.enum_entry);
+ nis_result *result = global_nisp_ent.result;
+
+ if (user==NULL) {
+ DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
+ return False;
+ }
+
+ if (result == NULL ||
+ enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
+ {
+ return False;
+ }
+
+ if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
+ {
+ DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
+ return False;
+ }
+ (int)(global_nisp_ent.enum_entry)++;
+ return True;
+}
+
+/*************************************************************************
+ Routine to search the nisplus passwd file for an entry matching the username
+ *************************************************************************/
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
+{
+ /* Static buffers we will return. */
+ nis_result *result = NULL;
+ pstring nisname;
+ BOOL ret;
+ char *pfile = smb_passwd_table();
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("No SMB password file set\n"));
+ return False;
+ }
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
+ DEBUG(10, ("search by nisname: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+}
+
+/*************************************************************************
+ Routine to search the nisplus passwd file for an entry matching the username
+ *************************************************************************/
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
+{
+ nis_result *result;
+ char *nisname;
+ BOOL ret;
+ char *pfile = smb_passwd_table();
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ nisname = make_nisname_from_user_rid(rid, pfile);
+
+ DEBUG(10, ("search by rid: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+}
+
+/*************************************************************************
+ Routine to remove entry from the nisplus smbpasswd table
+ *************************************************************************/
+BOOL pdb_delete_sam_account(const char *sname)
+{
+ char *pfile = smb_passwd_table();
+ pstring nisname;
+ nis_result *result, *delresult;
+ nis_object *obj;
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
+ obj->zo_domain);
+
+ DEBUG(10, ("removing name: %s\n", nisname));
+ delresult = nis_remove_entry(nisname, obj,
+ MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+
+ nis_freeresult(result);
+
+ if(delresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(delresult->status)));
+ nis_freeresult(delresult);
+ return False;
+ }
+ nis_freeresult(delresult);
+ return True;
+}
+
+/************************************************************************
+ Routine to add an entry to the nisplus passwd file.
+*************************************************************************/
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
+{
+ int local_user = 0;
+ char *pfile = smb_passwd_table();
+ pstring pfiletmp;
+ char *nisname;
+ nis_result *result = NULL, *tblresult = NULL;
+ nis_object new_obj, *obj;
+ entry_col *ecol;
+ int ta_maxcol;
+
+ /*
+ * 1. find user domain.
+ * a. try nis search in passwd.org_dir - if found use domain from result.
+ * b. try getpwnam. this may be needed if user is defined
+ * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
+ * if found, use host default domain.
+ * c. exit with False - no such user.
+ *
+ * 2. add user
+ * a. find smbpasswd table
+ * search pfile in user domain if not found, try host default
+ * domain.
+ * b. smbpasswd domain is found, fill data and add entry.
+ *
+ */
+
+
+ /*
+ * Check if user is already there.
+ */
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+
+ if(pdb_get_username(newpwd) != NULL) {
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ pfiletmp);
+ } else {
+ return False;
+ }
+
+ if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+ if (result->status != NIS_SUCCESS &&
+ result->status != NIS_NOTFOUND) {
+ DEBUG(3, ( "nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+ return False;
+ }
+
+ if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
+ {
+ DEBUG(3, ("User already exists in NIS+ password db: %s\n",
+ pfile));
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(result); /* no such user, free results */
+
+ /*
+ * check for user in unix password database. we need this to get
+ * domain, where smbpasswd entry should be stored.
+ */
+
+#if 1 /* passwd and smbpasswd users should be in the same domain */
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ "passwd.org_dir");
+
+ result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP);
+
+ if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
+ {
+ DEBUG(3, ("nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+
+ if (!sys_getpwnam(pdb_get_username(newpwd))) {
+ /* no such user in system! */
+ return False;
+ }
+ /*
+ * user is defined, but not in passwd.org_dir.
+ */
+ local_user = 1;
+ } else {
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ nis_freeresult(result); /* not needed any more */
+
+ tblresult = nis_lookup(pfiletmp,
+ MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ }
+
+ if (local_user || tblresult->status != NIS_SUCCESS)
+ {
+ /*
+ * no user domain or
+ * smbpasswd table not found in user domain, fallback to
+ * default domain.
+ */
+ if (!local_user) /* free previous failed search result */
+ nis_freeresult(tblresult);
+#endif
+ tblresult = nis_lookup(pfile, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ if (tblresult->status != NIS_SUCCESS)
+ {
+ /* still nothing. bail out */
+ nis_freeresult(tblresult);
+ DEBUG(3, ( "nis_lookup failure: %s\n",
+ nis_sperrno(tblresult->status)));
+ return False;
+ }
+ obj = NIS_RES_OBJECT(tblresult);
+ /* we need full name for nis_add_entry() */
+ slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.%s", obj->zo_name,
+ obj->zo_domain);
+#if 1 /* matching } from previous #if */
+ }
+#endif
+
+ memset((char *)&new_obj, 0, sizeof (new_obj));
+ /* fill entry headers */
+ /* we do not free these. */
+ new_obj.zo_name = obj->zo_name;
+ new_obj.zo_owner = obj->zo_owner;
+ new_obj.zo_group = obj->zo_group;
+ new_obj.zo_domain = obj->zo_domain;
+ /* uints */
+ new_obj.zo_access = obj->zo_access;
+ new_obj.zo_ttl = obj->zo_ttl;
+
+ new_obj.zo_data.zo_type = ENTRY_OBJ;
+ new_obj.EN_data.en_type = obj->TA_data.ta_type;
+
+ ta_maxcol = obj->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(tblresult);
+ return False;
+ }
+
+ memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ init_nisp_from_sam(&new_obj, newpwd, NULL);
+
+ DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
+ result = nis_add_entry(pfiletmp, &new_obj, 0);
+
+ free(ecol); /* free allocated entry space */
+
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(3, ( "NIS+ table update failed: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+
+ return True;
+}
+
+/************************************************************************
+ Routine to modify the nisplus passwd entry.
+************************************************************************/
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
+{
+ nis_result *result, *addresult;
+ nis_object *obj;
+ nis_object new_obj;
+ entry_col *ecol;
+ int ta_maxcol;
+ char *pfile = smb_passwd_table();
+ pstring nisname;
+ int i;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s",
+ pdb_get_username(newpwd), pfile);
+
+ DEBUG(10, ("search by name: %s\n", nisname));
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ DEBUG(6,("entry found in %s\n", obj->zo_domain));
+
+ /* we must create new stub object with EN_MODIFIED flag.
+ this is because obj from result is going to be freed and
+ we do not want to break it or cause memory leaks or corruption.
+ */
+
+ memmove((char *)&new_obj, obj, sizeof (new_obj));
+ ta_maxcol = obj->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
+ ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
+ pdb_get_username(newpwd), obj->zo_name, obj->zo_domain);
+
+ DEBUG(10, ("NIS+ table update: %s\n", nisname));
+ addresult =
+ nis_modify_entry(nisname, &new_obj,
+ MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
+
+ if(addresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(addresult->status)));
+ nis_freeresult(addresult);
+ nis_freeresult(result);
+ free(ecol);
+ return False;
+ }
+
+ DEBUG(6,("password changed\n"));
+ nis_freeresult(addresult);
+ } else {
+ DEBUG(6,("nothing to change!\n"));
+ }
+
+ free(ecol);
+ nis_freeresult(result);
+
+ return True;
+}
+
+#else
+ void nisplus_dummy_function(void);
+ void nisplus_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* WITH_NISPLUSSAM */
+
diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c
deleted file mode 100644
index 1731c720a21..00000000000
--- a/source/passdb/pdb_pgsql.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * PostgresSQL password backend for samba
- * Copyright (C) Hamish Friedlander 2003
- * Copyright (C) Jelmer Vernooij 2004
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include <libpq-fe.h>
-
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "5432"
-#define CONFIG_DB_DEFAULT "samba"
-
-/* handles for doing db transactions */
-typedef struct pdb_pgsql_data {
- PGconn *handle ;
- PGresult *pwent ;
- long currow ;
-
- const char *location ;
-} pdb_pgsql_data ;
-
-#define SET_DATA(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return NT_STATUS_INVALID_PARAMETER; \
- } \
- data = (struct pdb_pgsql_data *)methods->private_data; \
- if(!data || !(data->handle)){ \
- DEBUG(0, ("invalid handle!\n")); \
- return NT_STATUS_INVALID_HANDLE; \
- } \
-}
-
-#define SET_DATA_QUIET(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return ; \
- } \
- data = (struct pdb_pgsql_data *)methods->private_data; \
- if(!data || !(data->handle)){ \
- DEBUG(0, ("invalid handle!\n")); \
- return ; \
- } \
-}
-
-
-#define config_value( data, name, default_value ) \
- lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value )
-
-static long PQgetlong( PGresult *r, long row, long col )
-{
- if ( PQgetisnull( r, row, col ) ) return 0 ;
-
- return atol( PQgetvalue( r, row, col ) ) ;
-}
-
-static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
-{
- pstring temp ;
- DOM_SID sid ;
-
- if ( row >= PQntuples( r ) ) return NT_STATUS_INVALID_PARAMETER ;
-
- pdb_set_logon_time ( u, PQgetlong ( r, row, 0 ), PDB_SET ) ;
- pdb_set_logoff_time ( u, PQgetlong ( r, row, 1 ), PDB_SET ) ;
- pdb_set_kickoff_time ( u, PQgetlong ( r, row, 2 ), PDB_SET ) ;
- pdb_set_pass_last_set_time ( u, PQgetlong ( r, row, 3 ), PDB_SET ) ;
- pdb_set_pass_can_change_time ( u, PQgetlong ( r, row, 4 ), PDB_SET ) ;
- pdb_set_pass_must_change_time( u, PQgetlong ( r, row, 5 ), PDB_SET ) ;
- pdb_set_username ( u, PQgetvalue( r, row, 6 ), PDB_SET ) ;
- pdb_set_domain ( u, PQgetvalue( r, row, 7 ), PDB_SET ) ;
- pdb_set_nt_username ( u, PQgetvalue( r, row, 8 ), PDB_SET ) ;
- pdb_set_fullname ( u, PQgetvalue( r, row, 9 ), PDB_SET ) ;
- pdb_set_homedir ( u, PQgetvalue( r, row, 10 ), PDB_SET ) ;
- pdb_set_dir_drive ( u, PQgetvalue( r, row, 11 ), PDB_SET ) ;
- pdb_set_logon_script ( u, PQgetvalue( r, row, 12 ), PDB_SET ) ;
- pdb_set_profile_path ( u, PQgetvalue( r, row, 13 ), PDB_SET ) ;
- pdb_set_acct_desc ( u, PQgetvalue( r, row, 14 ), PDB_SET ) ;
- pdb_set_workstations ( u, PQgetvalue( r, row, 15 ), PDB_SET ) ;
- pdb_set_unknown_str ( u, PQgetvalue( r, row, 16 ), PDB_SET ) ;
- pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ;
-
- pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ;
- pdb_set_logon_divs ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
- pdb_set_hours_len ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ;
- pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
- pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ;
-
- if ( !PQgetisnull( r, row, 18 ) ) string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ;
- pdb_set_user_sid ( u, &sid, PDB_SET ) ;
- if ( !PQgetisnull( r, row, 19 ) ) string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ;
- pdb_set_group_sid( u, &sid, PDB_SET ) ;
-
- if ( pdb_gethexpwd( PQgetvalue( r, row, 20 ), temp ), PDB_SET ) pdb_set_lanman_passwd( u, temp, PDB_SET ) ;
- if ( pdb_gethexpwd( PQgetvalue( r, row, 21 ), temp ), PDB_SET ) pdb_set_nt_passwd ( u, temp, PDB_SET ) ;
-
- /* Only use plaintext password storage when lanman and nt are NOT used */
- if ( PQgetisnull( r, row, 20 ) || PQgetisnull( r, row, 21 ) ) pdb_set_plaintext_passwd( u, PQgetvalue( r, row, 22 ) ) ;
-
- return NT_STATUS_OK ;
-}
-
-static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- struct pdb_pgsql_data *data ;
- char *query ;
- NTSTATUS retval ;
-
- SET_DATA( data, methods ) ;
-
- query = sql_account_query_select(data->location, update, SQL_SEARCH_NONE, NULL);
-
- /* Do it */
- DEBUG( 5, ("Executing query %s\n", query) ) ;
- data->pwent = PQexec( data->handle, query ) ;
- data->currow = 0 ;
-
- /* Result? */
- if ( data->pwent == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( data->pwent ) != PGRES_TUPLES_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( data->pwent ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%llu results)!\n", PQntuples(data->pwent)) ) ;
- retval = NT_STATUS_OK ;
- }
-
- SAFE_FREE(query);
- return retval ;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void pgsqlsam_endsampwent(struct pdb_methods *methods)
-{
- struct pdb_pgsql_data *data ;
-
- SET_DATA_QUIET( data, methods ) ;
-
- if (data->pwent != NULL)
- {
- PQclear( data->pwent ) ;
- }
-
- data->pwent = NULL ;
- data->currow = 0 ;
-
- DEBUG( 5, ("pgsql_endsampwent called\n") ) ;
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwent( struct pdb_methods *methods, SAM_ACCOUNT *user )
-{
- struct pdb_pgsql_data *data;
- NTSTATUS retval ;
-
- SET_DATA( data, methods ) ;
-
- if ( data->pwent == NULL )
- {
- DEBUG( 0, ("invalid pwent\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- retval = row_to_sam_account( data->pwent, data->currow, user ) ;
- data->currow++ ;
-
- return retval ;
-}
-
-static NTSTATUS pgsqlsam_select_by_field ( struct pdb_methods *methods, SAM_ACCOUNT *user, enum sql_search_field field, const char *sname )
-{
- struct pdb_pgsql_data *data ;
-
- char *esc ;
- char *query ;
-
- PGresult *result ;
- NTSTATUS retval ;
-
- SET_DATA(data, methods);
-
- if ( user == NULL )
- {
- DEBUG( 0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG( 5, ("pgsqlsam_select_by_field: getting data where %d = %s(nonescaped)\n", field, sname) ) ;
-
- /* Escape sname */
- esc = malloc(strlen(sname) * 2 + 1);
- if ( !esc )
- {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- //tmp_sname = smb_xstrdup(sname);
- PQescapeString( esc, sname, strlen(sname) ) ;
-
- query = sql_account_query_select(data->location, True, field, esc);
-
- /* Do it */
- DEBUG( 5, ("Executing query %s\n", query) ) ;
- result = PQexec( data->handle, query ) ;
-
- /* Result? */
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- retval = row_to_sam_account( result, 0, user ) ;
- }
-
- SAFE_FREE( esc ) ;
- SAFE_FREE( query ) ;
-
- PQclear( result ) ;
-
- return retval ;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwnam ( struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname )
-{
- struct pdb_pgsql_data *data;
-
- SET_DATA(data, methods);
-
- if ( !sname )
- {
- DEBUG( 0, ("invalid name specified") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_NAME, sname ) ;
-}
-
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwsid ( struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid )
-{
- struct pdb_pgsql_data *data;
- fstring sid_str;
-
- SET_DATA( data, methods ) ;
-
- sid_to_string( sid_str, sid ) ;
-
- return pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_SID, sid_str ) ;
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS pgsqlsam_delete_sam_account( struct pdb_methods *methods, SAM_ACCOUNT *sam_pass )
-{
- struct pdb_pgsql_data *data ;
-
- const char *sname = pdb_get_username( sam_pass ) ;
- char *esc ;
- char *query ;
-
- PGresult *result ;
- NTSTATUS retval ;
-
- SET_DATA(data, methods);
-
- if ( !sname )
- {
- DEBUG( 0, ("invalid name specified\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- /* Escape sname */
- esc = malloc(strlen(sname) * 2 + 1);
- if ( !esc )
- {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- PQescapeString( esc, sname, strlen(sname) ) ;
-
- query = sql_account_query_delete(data->location, esc);
-
- /* Do it */
- result = PQexec( data->handle, query ) ;
-
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( result ) != PGRES_COMMAND_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- DEBUG( 5, ("User '%s' deleted\n", sname) ) ;
- retval = NT_STATUS_OK ;
- }
-
- SAFE_FREE( esc ) ;
- SAFE_FREE( query ) ;
-
- return retval ;
-}
-
-static NTSTATUS pgsqlsam_replace_sam_account( struct pdb_methods *methods, const SAM_ACCOUNT *newpwd, char isupdate )
-{
- struct pdb_pgsql_data *data ;
- char *query;
- PGresult *result ;
-
- if ( !methods )
- {
- DEBUG( 0, ("invalid methods!\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- data = (struct pdb_pgsql_data *) methods->private_data ;
-
- if ( data == NULL || data->handle == NULL )
- {
- DEBUG( 0, ("invalid handle!\n") ) ;
- return NT_STATUS_INVALID_HANDLE ;
- }
-
- query = sql_account_query_update(data->location, newpwd, isupdate);
-
- result = PQexec( data->handle, query ) ;
-
-
- /* Execute the query */
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
- else if ( PQresultStatus( result ) != PGRES_COMMAND_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
- SAFE_FREE(query);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS pgsqlsam_add_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd )
-{
- return pgsqlsam_replace_sam_account( methods, newpwd, 0 ) ;
-}
-
-static NTSTATUS pgsqlsam_update_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd )
-{
- return pgsqlsam_replace_sam_account( methods, newpwd, 1 ) ;
-}
-
-static NTSTATUS pgsqlsam_init ( struct pdb_context *pdb_context, struct pdb_methods **pdb_method, const char *location )
-{
- NTSTATUS nt_status ;
- struct pdb_pgsql_data *data ;
-
- if ( !pdb_context )
- {
- DEBUG( 0, ("invalid pdb_methods specified\n") ) ;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "pgsqlsam" ;
-
- (*pdb_method)->setsampwent = pgsqlsam_setsampwent ;
- (*pdb_method)->endsampwent = pgsqlsam_endsampwent ;
- (*pdb_method)->getsampwent = pgsqlsam_getsampwent ;
- (*pdb_method)->getsampwnam = pgsqlsam_getsampwnam ;
- (*pdb_method)->getsampwsid = pgsqlsam_getsampwsid ;
- (*pdb_method)->add_sam_account = pgsqlsam_add_sam_account ;
- (*pdb_method)->update_sam_account = pgsqlsam_update_sam_account ;
- (*pdb_method)->delete_sam_account = pgsqlsam_delete_sam_account ;
-
- data = talloc( pdb_context->mem_ctx, sizeof( struct pdb_pgsql_data ) ) ;
- (*pdb_method)->private_data = data ;
- data->handle = NULL ;
- data->pwent = NULL ;
-
- if ( !location )
- {
- DEBUG( 0, ("No identifier specified. Check the Samba HOWTO Collection for details\n") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data->location = smb_xstrdup( location ) ;
-
- if(!sql_account_config_valid(data->location)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG
- (
- 1,
- (
- "Connecting to database server, host: %s, user: %s, password: XXXXXX, database: %s, port: %s\n",
- config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT ),
- config_value( data, "pgsql user" , CONFIG_USER_DEFAULT ),
- config_value( data, "pgsql database", CONFIG_DB_DEFAULT ),
- config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT )
- )
- ) ;
-
- /* Do the pgsql initialization */
- data->handle = PQsetdbLogin(
- config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT ),
- config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT ),
- NULL,
- NULL,
- config_value( data, "pgsql database", CONFIG_DB_DEFAULT ),
- config_value( data, "pgsql user" , CONFIG_USER_DEFAULT ),
- config_value( data, "pgsql password", CONFIG_PASS_DEFAULT )
- ) ;
-
- if ( PQstatus( data->handle ) != CONNECTION_OK )
- {
- DEBUG( 0, ("Failed to connect to pgsql database: error: %s\n", PQerrorMessage( data->handle )) ) ;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG( 5, ("Connected to pgsql database\n") ) ;
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_pgsql_init(void)
-{
- return smb_register_passdb( PASSDB_INTERFACE_VERSION, "pgsql", pgsqlsam_init ) ;
-}
diff --git a/source/passdb/pdb_plugin.c b/source/passdb/pdb_plugin.c
deleted file mode 100644
index 027cd0b5d33..00000000000
--- a/source/passdb/pdb_plugin.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Loadable passdb module interface.
- Copyright (C) Jelmer Vernooij 2002
- Copyright (C) Andrew Bartlett 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- void * dl_handle;
- char *plugin_location, *plugin_name, *p;
- pdb_init_function plugin_init;
- int (*plugin_version)(void);
-
- if (location == NULL) {
- DEBUG(0, ("The plugin module needs an argument!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- plugin_name = smb_xstrdup(location);
- p = strchr(plugin_name, ':');
- if (p) {
- *p = 0;
- plugin_location = p+1;
- trim_char(plugin_location, ' ', ' ');
- } else {
- plugin_location = NULL;
- }
- trim_char(plugin_name, ' ', ' ');
-
- DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name));
- dl_handle = sys_dlopen(plugin_name, RTLD_NOW );
- if (!dl_handle) {
- DEBUG(0, ("Failed to load sam plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror()));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- plugin_version = sys_dlsym(dl_handle, "pdb_version");
- if (!plugin_version) {
- sys_dlclose(dl_handle);
- DEBUG(0, ("Failed to find function 'pdb_version' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror()));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (plugin_version() != PASSDB_INTERFACE_VERSION) {
- sys_dlclose(dl_handle);
- DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n",
- plugin_version(),PASSDB_INTERFACE_VERSION));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- plugin_init = sys_dlsym(dl_handle, "pdb_init");
- if (!plugin_init) {
- sys_dlclose(dl_handle);
- DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror()));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("Starting sam plugin %s with location %s\n", plugin_name, plugin_location));
- return plugin_init(pdb_context, pdb_method, plugin_location);
-}
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 562d50f89e3..bc6cad405da 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1,10 +1,9 @@
/*
- * Unix SMB/CIFS implementation.
- * SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1998
- * Modified by Jeremy Allison 1995.
- * Modified by Gerald (Jerry) Carter 2000-2001,2003
- * Modified by Andrew Bartlett 2002.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Modified by Jeremy Allison 1995.
+ * Modified by Gerald (Jerry) Carter 2000-2001
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
@@ -23,8 +22,8 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
+#ifdef WITH_SMBPASSWD_SAM
+
/*
smb_passwd is analogous to sam_passwd used everywhere
@@ -34,33 +33,26 @@
struct smb_passwd
{
- uint32 smb_userid; /* this is actually the unix uid_t */
- const char *smb_name; /* username string */
+ uid_t smb_userid; /* this is actually the unix uid_t */
+ char *smb_name; /* username string */
- const unsigned char *smb_passwd; /* Null if no password */
- const unsigned char *smb_nt_passwd; /* Null if no password */
+ unsigned char *smb_passwd; /* Null if no password */
+ unsigned char *smb_nt_passwd; /* Null if no password */
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
time_t pass_last_set_time; /* password last set time */
};
-struct smbpasswd_privates
-{
- /* used for maintain locks on the smbpasswd file */
- int pw_file_lock_depth;
-
- /* Global File pointer */
- FILE *pw_file;
-
- /* formerly static variables */
- struct smb_passwd pw_buf;
- pstring user_name;
- unsigned char smbpwd[16];
- unsigned char smbntpwd[16];
-
- /* retrive-once info */
- const char *smbpasswd_file;
-};
+
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
+extern struct passdb_ops pdb_ops;
+
+
+/* used for maintain locks on the smbpasswd file */
+static int pw_file_lock_depth;
+static void *global_vp;
+
enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
@@ -94,10 +86,6 @@ static BOOL pw_file_unlock(int fd, int *plock_depth)
{
BOOL ret=True;
- if (fd == 0 || *plock_depth == 0) {
- return True;
- }
-
if(*plock_depth == 1)
ret = do_file_lock(fd, 5, F_UNLCK);
@@ -131,7 +119,7 @@ static void pdb_init_smb(struct smb_passwd *user)
been granted to prevent race conditions. JRA.
****************************************************************/
-static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
+static void *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
{
FILE *fp = NULL;
const char *open_mode = NULL;
@@ -179,25 +167,8 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int
DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
if((fp = sys_fopen(pfile, open_mode)) == NULL) {
-
- /*
- * If smbpasswd file doesn't exist, then create new one. This helps to avoid
- * confusing error msg when adding user account first time.
- */
- if (errno == ENOENT) {
- if ((fp = sys_fopen(pfile, "a+")) != NULL) {
- DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. File successfully created.\n", pfile));
-
- } else {
- DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. Couldn't create new one. Error was: %s",
- pfile, strerror(errno)));
- return NULL;
- }
-
- } else {
- DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was: %s\n", pfile, strerror(errno)));
- return NULL;
- }
+ DEBUG(2, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
+ return NULL;
}
if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) {
@@ -274,34 +245,35 @@ Error was %s\n.", pfile, strerror(errno) ));
}
/* We have a lock on the file. */
- return fp;
+ return (void *)fp;
}
/***************************************************************
End enumeration of the smbpasswd list.
****************************************************************/
-static void endsmbfilepwent(FILE *fp, int *lock_depth)
+static void endsmbfilepwent(void *vp, int *lock_depth)
{
- if (!fp) {
- return;
- }
+ FILE *fp = (FILE *)vp;
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
+ if (!fp)
+ return;
+ pw_file_unlock(fileno(fp), lock_depth);
+ fclose(fp);
+ DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
}
/*************************************************************************
Routine to return the next entry in the smbpasswd list.
*************************************************************************/
-static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_state, FILE *fp)
+static struct smb_passwd *getsmbfilepwent(void *vp)
{
/* Static buffers we will return. */
- struct smb_passwd *pw_buf = &smbpasswd_state->pw_buf;
- char *user_name = smbpasswd_state->user_name;
- unsigned char *smbpwd = smbpasswd_state->smbpwd;
- unsigned char *smbntpwd = smbpasswd_state->smbntpwd;
+ static struct smb_passwd pw_buf;
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ FILE *fp = (FILE *)vp;
char linebuf[256];
unsigned char c;
unsigned char *p;
@@ -313,9 +285,9 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
return NULL;
}
- pdb_init_smb(pw_buf);
+ pdb_init_smb(&pw_buf);
- pw_buf->acct_ctrl = ACB_NORMAL;
+ pw_buf.acct_ctrl = ACB_NORMAL;
/*
* Scan the file, a line at a time and check if the name matches.
@@ -371,7 +343,7 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
DEBUG(6, ("getsmbfilepwent: skipping comment or blank line\n"));
continue;
}
- p = (unsigned char *) strchr_m(linebuf, ':');
+ p = (unsigned char *) strchr(linebuf, ':');
if (p == NULL) {
DEBUG(0, ("getsmbfilepwent: malformed password entry (no :)\n"));
continue;
@@ -380,8 +352,6 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
* As 256 is shorter than a pstring we don't need to check
* length here - if this ever changes....
*/
- SMB_ASSERT(sizeof(pstring) > sizeof(linebuf));
-
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
@@ -409,8 +379,8 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
continue;
}
- pw_buf->smb_name = user_name;
- pw_buf->smb_userid = uidval;
+ pw_buf.smb_name = user_name;
+ pw_buf.smb_userid = uidval;
/*
* Now get the password value - this should be 32 hex digits
@@ -421,6 +391,15 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
/* Skip the ':' */
p++;
+ if (*p == '*' || *p == 'X') {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
+ pw_buf.smb_nt_passwd = NULL;
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_DISABLED;
+ return &pw_buf;
+ }
+
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
continue;
@@ -431,34 +410,29 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
continue;
}
- if (strnequal((char *) p, "NO PASSWORD", 11)) {
- pw_buf->smb_passwd = NULL;
- pw_buf->acct_ctrl |= ACB_PWNOTREQ;
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_PWNOTREQ;
} else {
- if (*p == '*' || *p == 'X') {
- /* NULL LM password */
- pw_buf->smb_passwd = NULL;
- DEBUG(10, ("getsmbfilepwent: LM password for user %s invalidated\n", user_name));
- } else if (pdb_gethexpwd((char *)p, smbpwd)) {
- pw_buf->smb_passwd = smbpwd;
- } else {
- pw_buf->smb_passwd = NULL;
- DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
- }
+ if (!pdb_gethexpwd((char *)p, smbpwd)) {
+ DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
+ continue;
+ }
+ pw_buf.smb_passwd = smbpwd;
}
/*
* Now check if the NT compatible password is
* available.
*/
- pw_buf->smb_nt_passwd = NULL;
+ pw_buf.smb_nt_passwd = NULL;
p += 33; /* Move to the first character of the line after
the lanman password. */
if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
if (*p != '*' && *p != 'X') {
if(pdb_gethexpwd((char *)p,smbntpwd))
- pw_buf->smb_nt_passwd = smbntpwd;
+ pw_buf.smb_nt_passwd = smbntpwd;
}
p += 33; /* Move to the first character of the line after
the NT password. */
@@ -469,12 +443,12 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
if (*p == '[')
{
- unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
- pw_buf->acct_ctrl = pdb_decode_acct_ctrl((char*)p);
+ unsigned char *end_p = (unsigned char *)strchr((char *)p, ']');
+ pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
/* Must have some account type set. */
- if(pw_buf->acct_ctrl == 0)
- pw_buf->acct_ctrl = ACB_NORMAL;
+ if(pw_buf.acct_ctrl == 0)
+ pw_buf.acct_ctrl = ACB_NORMAL;
/* Now try and get the last change time. */
if(end_p)
@@ -494,7 +468,7 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
* read into a time_t as the seconds since
* 1970 that the password was last changed.
*/
- pw_buf->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
+ pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
}
}
}
@@ -505,13 +479,13 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
* password file as 'normal accounts'. If this changes
* we will have to fix this code. JRA.
*/
- if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
- pw_buf->acct_ctrl &= ~ACB_NORMAL;
- pw_buf->acct_ctrl |= ACB_WSTRUST;
+ if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
+ pw_buf.acct_ctrl &= ~ACB_NORMAL;
+ pw_buf.acct_ctrl |= ACB_WSTRUST;
}
}
- return pw_buf;
+ return &pw_buf;
}
DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
@@ -522,11 +496,12 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
Create a new smbpasswd entry - malloced space returned.
*************************************************************************/
-static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
+static char *format_new_smbpasswd_entry(struct smb_passwd *newpwd)
{
int new_entry_length;
char *new_entry;
char *p;
+ int i;
new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
@@ -536,16 +511,38 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
}
slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
+ p = &new_entry[strlen(new_entry)];
- p = new_entry+strlen(new_entry);
+ if(newpwd->smb_passwd != NULL) {
+ for( i = 0; i < 16; i++) {
+ slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
+ }
+ } else {
+ i=0;
+ if(newpwd->acct_ctrl & ACB_PWNOTREQ)
+ safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ else
+ safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ }
- pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl);
+ p += 32;
- p+=strlen(p); *p = ':'; p++;
+ *p++ = ':';
- pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
+ if(newpwd->smb_nt_passwd != NULL) {
+ for( i = 0; i < 16; i++) {
+ slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
+ }
+ } else {
+ if(newpwd->acct_ctrl & ACB_PWNOTREQ)
+ safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ else
+ safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ }
- p+=strlen(p); *p = ':'; p++;
+ p += 32;
+
+ *p++ = ':';
/* Add the account encoding and the last change time. */
slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
@@ -559,9 +556,9 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
Routine to add an entry to the smbpasswd file.
*************************************************************************/
-static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd)
+static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
{
- const char *pfile = smbpasswd_state->smbpasswd_file;
+ char *pfile = lp_smb_passwd_file();
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
int wr_len;
@@ -569,14 +566,13 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
size_t new_entry_length;
char *new_entry;
SMB_OFF_T offpos;
- uint32 max_found_uid = 0;
-
+
/* Open the smbpassword file - for update. */
- fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth));
+ fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth);
if (fp == NULL && errno == ENOENT) {
/* Try again - create. */
- fp = startsmbfilepwent(pfile, PWF_CREATE, &(smbpasswd_state->pw_file_lock_depth));
+ fp = startsmbfilepwent(pfile, PWF_CREATE, &pw_file_lock_depth);
}
if (fp == NULL) {
@@ -588,20 +584,15 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
* Scan the file, a line at a time and check if the name matches.
*/
- while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL)
+ while ((pwd = getsmbfilepwent(fp)) != NULL)
{
if (strequal(newpwd->smb_name, pwd->smb_name))
{
DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
return False;
}
-
- /* Look for a free uid for use in non-unix accounts */
- if (pwd->smb_userid > max_found_uid) {
- max_found_uid = pwd->smb_userid;
- }
- }
+ }
/* Ok - entry doesn't exist. We can add it */
@@ -616,7 +607,7 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
{
DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
return False;
}
@@ -624,7 +615,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
{
DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
return False;
}
@@ -648,13 +639,13 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
newpwd->smb_name, strerror(errno)));
}
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
free(new_entry);
return False;
}
free(new_entry);
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
return True;
}
@@ -667,10 +658,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
override = True, override XXXXXXXX'd out password or NO PASS
************************************************************************/
-static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
+static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
{
/* Static buffers we will return. */
- pstring user_name;
+ static pstring user_name;
char linebuf[256];
char readbuf[1024];
@@ -681,7 +672,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
size_t linebuf_len = 0;
FILE *fp;
int lockfd;
- const char *pfile = smbpasswd_state->smbpasswd_file;
+ char *pfile = lp_smb_passwd_file();
BOOL found_entry = False;
BOOL got_pass_last_set_time = False;
@@ -708,7 +699,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
lockfd = fileno(fp);
- if (!pw_file_lock(lockfd, F_WRLCK, 5, &(smbpasswd_state->pw_file_lock_depth))) {
+ if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return False;
@@ -728,7 +719,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
fgets(linebuf, sizeof(linebuf), fp);
if (ferror(fp)) {
- pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -777,7 +768,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
continue;
}
- p = (unsigned char *) strchr_m(linebuf, ':');
+ p = (unsigned char *) strchr(linebuf, ':');
if (p == NULL) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no :)\n"));
@@ -788,9 +779,6 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
* As 256 is shorter than a pstring we don't need to check
* length here - if this ever changes....
*/
-
- SMB_ASSERT(sizeof(user_name) > sizeof(linebuf));
-
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
if (strequal(user_name, pwd->smb_name)) {
@@ -800,11 +788,8 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
}
if (!found_entry) {
- pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
-
- DEBUG(2, ("Cannot update entry for user %s, as they don't exist in the smbpasswd file!\n",
- pwd->smb_name));
return False;
}
@@ -815,7 +800,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
if (!isdigit(*p)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n"));
- pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -824,7 +809,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
p++;
if (*p != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n"));
- pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -839,16 +824,30 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/* Record exact password position */
pwd_seekpos += PTR_DIFF(p, linebuf);
+ if (!override && (*p == '*' || *p == 'X')) {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for user %s\n", user_name));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
+ if (!override && (*p == '*' || *p == 'X')) {
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -859,14 +858,14 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
the lanman password. */
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -878,6 +877,16 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
p += 33; /* Move to the first character of the line after
the NT password. */
+ /*
+ * If both NT and lanman passwords are provided - reset password
+ * not required flag.
+ */
+
+ if(pwd->smb_passwd != NULL || pwd->smb_nt_passwd != NULL) {
+ /* Reqiure password in the future (should ACB_DISABLED also be reset?) */
+ pwd->acct_ctrl &= ~(ACB_PWNOTREQ);
+ }
+
if (*p == '[') {
i = 0;
@@ -896,9 +905,15 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
*/
fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
} else {
- DEBUG(0,("mod_smbfilepwd_entry: Using old smbpasswd format. This is no longer supported.!\n"));
- DEBUG(0,("mod_smbfilepwd_entry: No changes made, failing.!\n"));
- return False;
+ /*
+ * If using the old format and the ACB_DISABLED or
+ * ACB_PWNOTREQ are set then set the lanman and NT passwords to NULL
+ * here as we have no space to encode the change.
+ */
+ if(pwd->acct_ctrl & (ACB_DISABLED|ACB_PWNOTREQ)) {
+ pwd->smb_passwd = NULL;
+ pwd->smb_nt_passwd = NULL;
+ }
}
/* Go past the ']' */
@@ -931,18 +946,38 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/* Entry is correctly formed. */
/* Create the 32 byte representation of the new p16 */
- pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl);
+ if(pwd->smb_passwd != NULL) {
+ for (i = 0; i < 16; i++) {
+ slprintf(&ascii_p16[i*2], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_passwd[i]);
+ }
+ } else {
+ if(pwd->acct_ctrl & ACB_PWNOTREQ)
+ fstrcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+ else
+ fstrcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ }
/* Add on the NT md4 hash */
ascii_p16[32] = ':';
wr_len = 66;
- pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl);
+ if (pwd->smb_nt_passwd != NULL) {
+ for (i = 0; i < 16; i++) {
+ slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]);
+ }
+ } else {
+ if(pwd->acct_ctrl & ACB_PWNOTREQ)
+ fstrcpy(&ascii_p16[33], "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+ else
+ fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ }
ascii_p16[65] = ':';
ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */
/* Add on the account info bits and the time of last
password change. */
+ pwd->pass_last_set_time = time(NULL);
+
if(got_pass_last_set_time) {
slprintf(&ascii_p16[strlen(ascii_p16)],
sizeof(ascii_p16)-(strlen(ascii_p16)+1),
@@ -958,7 +993,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
if(wr_len > sizeof(linebuf)) {
DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
@@ -976,7 +1011,7 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -984,33 +1019,33 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/* Sanity check - ensure the areas we are writing are framed by ':' */
if (read(fd, linebuf, wr_len+1) != wr_len+1) {
DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if (write(fd, ascii_p16, wr_len) != wr_len) {
DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
- pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return True;
}
@@ -1019,9 +1054,9 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
Routine to delete an entry in the smbpasswd file by name.
*************************************************************************/
-static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
+static BOOL del_smbfilepwd_entry(const char *name)
{
- const char *pfile = smbpasswd_state->smbpasswd_file;
+ char *pfile = lp_smb_passwd_file();
pstring pfile2;
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
@@ -1036,7 +1071,7 @@ static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
* it.
*/
- if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth))) == NULL) {
+ if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth)) == NULL) {
DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
return False;
}
@@ -1046,7 +1081,7 @@ static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
*/
if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {
DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
return False;
}
@@ -1054,12 +1089,12 @@ static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
* Scan the file, a line at a time and check if the name matches.
*/
- while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
+ while ((pwd = getsmbfilepwent(fp)) != NULL) {
char *new_entry;
size_t new_entry_length;
if (strequal(name, pwd->smb_name)) {
- DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
+ DEBUG(10, ("del_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
continue;
}
@@ -1072,7 +1107,7 @@ static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
endsmbfilepwent(fp_write, &pfile2_lockdepth);
return False;
}
@@ -1084,7 +1119,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
endsmbfilepwent(fp_write, &pfile2_lockdepth);
free(new_entry);
return False;
@@ -1100,7 +1135,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
if(fflush(fp_write) != 0)
{
DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
endsmbfilepwent(fp_write,&pfile2_lockdepth);
return False;
}
@@ -1113,7 +1148,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
}
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
endsmbfilepwent(fp_write,&pfile2_lockdepth);
return True;
}
@@ -1123,36 +1158,15 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
We will not allocate any new memory. The smb_passwd struct
should only stay around as long as the SAM_ACCOUNT does.
********************************************************************/
-static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
+static BOOL build_smb_pass (struct smb_passwd *smb_pw, SAM_ACCOUNT *sampass)
{
- uint32 rid;
-
if (sampass == NULL)
return False;
- ZERO_STRUCTP(smb_pw);
- if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
- rid = pdb_get_user_rid(sampass);
-
- /* If the user specified a RID, make sure its able to be both stored and retreived */
- if (rid == DOMAIN_USER_RID_GUEST) {
- struct passwd *passwd = getpwnam_alloc(lp_guestaccount());
- if (!passwd) {
- DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));
- return False;
- }
- smb_pw->smb_userid=passwd->pw_uid;
- passwd_free(&passwd);
-
- } else if (fallback_pdb_rid_is_user(rid)) {
- smb_pw->smb_userid=fallback_pdb_user_rid_to_uid(rid);
- } else {
- DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
- return False;
- }
- }
+ ZERO_STRUCTP(smb_pw);
- smb_pw->smb_name=(const char*)pdb_get_username(sampass);
+ smb_pw->smb_userid=pdb_get_uid(sampass);
+ smb_pw->smb_name=pdb_get_username(sampass);
smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);
smb_pw->smb_nt_passwd=pdb_get_nt_passwd(sampass);
@@ -1166,8 +1180,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
/*********************************************************************
Create a SAM_ACCOUNT from a smb_passwd struct
********************************************************************/
-static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
- SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
@@ -1175,109 +1188,149 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
DEBUG(5,("build_sam_account: SAM_ACCOUNT is NULL\n"));
return False;
}
+
+ /* Verify in system password file...
+ FIXME!!! This is where we should look up an internal
+ mapping of allocated uid for machine accounts as well
+ --jerry */
+ pwfile = sys_getpwnam(pw_buf->smb_name);
+ if (pwfile == NULL) {
+ DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s not in unix passwd database!\n", pw_buf->smb_name));
+ return False;
+ }
- /* verify the user account exists */
-
- if ( !(pwfile = getpwnam_alloc(pw_buf->smb_name)) ) {
- DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid "
- "%u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
+ /* FIXME!! This doesn't belong here. Should be set in net_sam_logon()
+ --jerry */
+ pstrcpy(samlogon_user, pw_buf->smb_name);
+
+ pdb_set_uid (sam_pass, pwfile->pw_uid);
+ pdb_set_gid (sam_pass, pwfile->pw_gid);
+ pdb_set_fullname(sam_pass, pwfile->pw_gecos);
+
+ pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
+
+ /* should check the group mapping here instead of static mappig. JFM */
+ pdb_set_group_rid(sam_pass, pdb_gid_to_group_rid(pwfile->pw_gid));
+
+ pdb_set_username (sam_pass, pw_buf->smb_name);
+ if (!pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd)) {
+ if (pw_buf->smb_nt_passwd)
return False;
}
+ if (!pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd)) {
+ if (pw_buf->smb_passwd)
+ return False;
+ }
+ pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl);
+ pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time);
+ pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time);
+ pdb_set_domain (sam_pass, lp_workgroup());
- if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile)))
- return False;
-
- passwd_free(&pwfile);
+ pdb_set_dir_drive (sam_pass, lp_logon_drive(), False);
- /* set remaining fields */
+ /* FIXME!! What should this be set to? New smb.conf parameter maybe?
+ max password age? For now, we'll use the current time + 21 days.
+ --jerry */
+ pdb_set_pass_must_change_time (sam_pass, time(NULL)+1814400);
+
+ /* check if this is a user account or a machine account */
+ if (samlogon_user[strlen(samlogon_user)-1] != '$')
+ {
+ pstring str;
+ gid_t gid = getegid();
- pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET);
- pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET);
- pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET);
- pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
- pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
+ sam_logon_in_ssb = True;
+
+ pstrcpy(str, lp_logon_script());
+ standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str,sizeof(str));
+ pdb_set_logon_script(sam_pass, str, False);
+
+ pstrcpy(str, lp_logon_path());
+ standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str,sizeof(str));
+ pdb_set_profile_path(sam_pass, str, False);
+
+ pstrcpy(str, lp_logon_home());
+ standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str,sizeof(str));
+ pdb_set_homedir(sam_pass, str, False);
+
+ sam_logon_in_ssb = False;
+ } else {
+ /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+ pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS);
+ }
return True;
}
-
/*****************************************************************
Functions to be implemented by the new passdb API
****************************************************************/
-static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
+BOOL pdb_setsampwent (BOOL update)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
-
- smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
- update ? PWF_UPDATE : PWF_READ,
- &(smbpasswd_state->pw_file_lock_depth));
+ global_vp = startsmbfilepwent(lp_smb_passwd_file(),
+ update ? PWF_UPDATE : PWF_READ,
+ &pw_file_lock_depth);
/* did we fail? Should we try to create it? */
- if (!smbpasswd_state->pw_file && update && errno == ENOENT)
+ if (!global_vp && update && errno == ENOENT)
{
FILE *fp;
/* slprintf(msg_str,msg_str_len-1,
- "smbpasswd file did not exist - attempting to create it.\n"); */
+ "smbpasswd file did not exist - attempting to create it.\n"); */
DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
- fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
+ fp = sys_fopen(lp_smb_passwd_file(), "w");
if (fp)
{
fprintf(fp, "# Samba SMB password file\n");
fclose(fp);
}
- smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
- update ? PWF_UPDATE : PWF_READ,
- &(smbpasswd_state->pw_file_lock_depth));
+ global_vp = startsmbfilepwent(lp_smb_passwd_file(),
+ update ? PWF_UPDATE : PWF_READ,
+ &pw_file_lock_depth);
}
- if (smbpasswd_state->pw_file != NULL)
- return NT_STATUS_OK;
- else
- return NT_STATUS_UNSUCCESSFUL;
+ return (global_vp != NULL);
}
-static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
+void pdb_endsampwent (void)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
- endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(global_vp, &pw_file_lock_depth);
}
/*****************************************************************
****************************************************************/
-static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+BOOL pdb_getsampwent(SAM_ACCOUNT *user)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *pw_buf=NULL;
BOOL done = False;
DEBUG(5,("pdb_getsampwent\n"));
if (user==NULL) {
- DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
+ DEBUG(5,("pdb_getsampwent: user is NULL\n"));
#if 0
- smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");
+ smb_panic("NULL pointer passed to pdb_getsampwent\n");
#endif
- return nt_status;
+ return False;
}
while (!done)
{
/* do we have an entry? */
- pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
+ pw_buf = getsmbfilepwent(global_vp);
if (pw_buf == NULL)
- return nt_status;
+ return False;
/* build the SAM_ACCOUNT entry from the smb_passwd struct.
We loop in case the user in the pdb does not exist in
the local system password file */
- if (build_sam_account(smbpasswd_state, user, pw_buf))
+ if (build_sam_account(user, pw_buf))
done = True;
}
- DEBUG(5,("getsampwent (smbpasswd): done\n"));
+ DEBUG(5,("pdb_getsampwent:done\n"));
/* success */
- return NT_STATUS_OK;
+ return True;
}
@@ -1286,232 +1339,152 @@ static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUN
call getpwnam() for unix account information until we have found
the correct entry
***************************************************************/
-static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods,
- SAM_ACCOUNT *sam_acct, const char *username)
+BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
+ char *domain = NULL;
+ char *user = NULL;
+ fstring name;
- DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
+ DEBUG(10, ("pdb_getsampwnam: search by name: %s\n", username));
+
+
+ /* break the username from the domain if we have
+ been given a string in the form 'DOMAIN\user' */
+ fstrcpy (name, username);
+ if ((user=strchr(name, '\\')) != NULL) {
+ domain = name;
+ *user = '\0';
+ user++;
+ }
+
+ /* if a domain was specified and it wasn't ours
+ then there is no chance of matching */
+ if ( domain && !StrCaseCmp(domain, lp_workgroup()) )
+ return False;
/* startsmbfilepwent() is used here as we don't want to lookup
the UNIX account in the local system password file until
we have a match. */
- fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
+ fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
if (fp == NULL) {
- DEBUG(0, ("Unable to open passdb database.\n"));
- return nt_status;
+ DEBUG(0, ("unable to open passdb database.\n"));
+ return False;
}
- while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
+ /* if we have a domain name, then we should map it to a UNIX
+ username first */
+ if ( domain )
+ map_username(user);
+
+ while ( ((smb_pw=getsmbfilepwent(fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
/* do nothing....another loop */ ;
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
- return nt_status;
+ return False;
- DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
+ DEBUG(10, ("pdb_getsampwnam: found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n"));
+ DEBUG(10,("pdb_getsampwnam:SAM_ACCOUNT is NULL\n"));
#if 0
smb_panic("NULL pointer passed to pdb_getsampwnam\n");
#endif
- return nt_status;
+ return False;
}
/* now build the SAM_ACCOUNT */
- if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
- return nt_status;
+ if (!build_sam_account(sam_acct, smb_pw))
+ return False;
/* success */
- return NT_STATUS_OK;
+ return True;
}
-static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+
+BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
- fstring sid_str;
- uint32 rid;
-
- DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid)));
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return NT_STATUS_UNSUCCESSFUL;
-
- /* More special case 'guest account' hacks... */
- if (rid == DOMAIN_USER_RID_GUEST) {
- const char *guest_account = lp_guestaccount();
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("Guest account not specfied!\n"));
- return nt_status;
- }
- return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account);
- }
+ DEBUG(10, ("pdb_getsampwrid: search by rid: %d\n", rid));
/* Open the sam password file - not for update. */
- fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
+ fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
if (fp == NULL) {
- DEBUG(0, ("Unable to open passdb database.\n"));
- return nt_status;
+ DEBUG(0, ("unable to open passdb database.\n"));
+ return False;
}
- while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (fallback_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
+ while ( ((smb_pw=getsmbfilepwent(fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
/* do nothing */ ;
- endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ endsmbfilepwent(fp, &pw_file_lock_depth);
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
- return nt_status;
+ return False;
- DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
+ DEBUG(10, ("pdb_getsampwrid: found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n"));
+ DEBUG(10,("pdb_getsampwrid:SAM_ACCOUNT is NULL\n"));
#if 0
smb_panic("NULL pointer passed to pdb_getsampwrid\n");
#endif
- return nt_status;
+ return False;
}
/* now build the SAM_ACCOUNT */
- if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
- return nt_status;
-
- /* build_sam_account might change the SID on us, if the name was for the guest account */
- if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) {
- fstring sid_string1, sid_string2;
- DEBUG(1, ("looking for user with sid %s instead returned %s for account %s!?!\n",
- sid_to_string(sid_string1, sid), sid_to_string(sid_string2, pdb_get_user_sid(sam_acct)), pdb_get_username(sam_acct)));
- return NT_STATUS_NO_SUCH_USER;
- }
+ if (!build_sam_account (sam_acct, smb_pw))
+ return False;
/* success */
- return NT_STATUS_OK;
+ return True;
}
-static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+BOOL pdb_add_sam_account(SAM_ACCOUNT *sampass)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
- if (!build_smb_pass(&smb_pw, sampass)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
+ build_smb_pass(&smb_pw, sampass);
/* add the entry */
- if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
+ if(!add_smbfilepwd_entry(&smb_pw))
+ return False;
- return NT_STATUS_OK;
+ return True;
}
-static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+BOOL pdb_update_sam_account(SAM_ACCOUNT *sampass, BOOL override)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
- if (!build_smb_pass(&smb_pw, sampass)) {
- DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ build_smb_pass(&smb_pw, sampass);
/* update the entry */
- if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
- DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
-{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
-
- const char *username = pdb_get_username(sampass);
-
- if (del_smbfilepwd_entry(smbpasswd_state, username))
- return NT_STATUS_OK;
-
- return NT_STATUS_UNSUCCESSFUL;
+ if(!mod_smbfilepwd_entry(&smb_pw, override))
+ return False;
+
+ return True;
}
-static void free_private_data(void **vp)
+BOOL pdb_delete_sam_account (const char* username)
{
- struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;
-
- endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth));
-
- *privates = NULL;
- /* No need to free any further, as it is talloc()ed */
+ return del_smbfilepwd_entry(username);
}
-static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
- struct smbpasswd_privates *privates;
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "smbpasswd";
-
- (*pdb_method)->setsampwent = smbpasswd_setsampwent;
- (*pdb_method)->endsampwent = smbpasswd_endsampwent;
- (*pdb_method)->getsampwent = smbpasswd_getsampwent;
- (*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
- (*pdb_method)->getsampwsid = smbpasswd_getsampwsid;
- (*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
- (*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
- (*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
-
- /* Setup private data and free function */
-
- privates = talloc_zero(pdb_context->mem_ctx, sizeof(struct smbpasswd_privates));
-
- if (!privates) {
- DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- /* Store some config details */
-
- if (location) {
- privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
- privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file());
- }
-
- if (!privates->smbpasswd_file) {
- DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- (*pdb_method)->private_data = privates;
-
- (*pdb_method)->free_private_data = free_private_data;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_smbpasswd_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);
-}
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void smbpass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* WTH_SMBPASSWD_SAM*/
diff --git a/source/passdb/pdb_sql.c b/source/passdb/pdb_sql.c
deleted file mode 100644
index ffb8313a970..00000000000
--- a/source/passdb/pdb_sql.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Common PDB SQL backend functions
- * Copyright (C) Jelmer Vernooij 2003-2004
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#define CONFIG_TABLE_DEFAULT "user"
-#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
-#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
-#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
-#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
-#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
-#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
-#define CONFIG_USERNAME_DEFAULT "username"
-#define CONFIG_DOMAIN_DEFAULT "domain"
-#define CONFIG_NT_USERNAME_DEFAULT "nt_username"
-#define CONFIG_FULLNAME_DEFAULT "nt_fullname"
-#define CONFIG_HOME_DIR_DEFAULT "home_dir"
-#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive"
-#define CONFIG_LOGON_SCRIPT_DEFAULT "logon_script"
-#define CONFIG_PROFILE_PATH_DEFAULT "profile_path"
-#define CONFIG_ACCT_DESC_DEFAULT "acct_desc"
-#define CONFIG_WORKSTATIONS_DEFAULT "workstations"
-#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str"
-#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial"
-#define CONFIG_USER_SID_DEFAULT "user_sid"
-#define CONFIG_GROUP_SID_DEFAULT "group_sid"
-#define CONFIG_LM_PW_DEFAULT "lm_pw"
-#define CONFIG_NT_PW_DEFAULT "nt_pw"
-#define CONFIG_PLAIN_PW_DEFAULT "NULL"
-#define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl"
-#define CONFIG_LOGON_DIVS_DEFAULT "logon_divs"
-#define CONFIG_HOURS_LEN_DEFAULT "hours_len"
-#define CONFIG_BAD_PASSWORD_COUNT_DEFAULT "bad_password_count"
-#define CONFIG_LOGON_COUNT_DEFAULT "logon_count"
-#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6"
-
-/* Used to construct insert and update queries */
-
-typedef struct pdb_sql_query {
- char update;
- TALLOC_CTX *mem_ctx;
- char *part1;
- char *part2;
-} pdb_sql_query;
-
-static void pdb_sql_int_field(struct pdb_sql_query *q, const char *name, int value)
-{
- if (!name || strchr(name, '\''))
- return; /* This field shouldn't be set by us */
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1,
- "%s = %d,", name, value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->mem_ctx, q->part2, "%d,", value);
- }
-}
-
-char *sql_escape_string(const char *unesc)
-{
- char *esc = malloc(strlen(unesc) * 2 + 3);
- size_t pos_unesc = 0, pos_esc = 0;
-
- for(pos_unesc = 0; unesc[pos_unesc]; pos_unesc++) {
- switch(unesc[pos_unesc]) {
- case '\\':
- case '\'':
- case '"':
- esc[pos_esc] = '\\'; pos_esc++;
- default:
- esc[pos_esc] = unesc[pos_unesc]; pos_esc++;
- break;
- }
- }
-
- esc[pos_esc] = '\0';
-
- return esc;
-}
-
-static NTSTATUS pdb_sql_string_field(struct pdb_sql_query *q,
- const char *name, const char *value)
-{
- char *esc_value;
-
- if (!name || !value || !strcmp(value, "") || strchr(name, '\''))
- return NT_STATUS_INVALID_PARAMETER; /* This field shouldn't be set by module */
-
- esc_value = sql_escape_string(value);
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1,
- "%s = '%s',", name, esc_value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->mem_ctx, q->part2, "'%s',",
- esc_value);
- }
-
- SAFE_FREE(esc_value);
-
- return NT_STATUS_OK;
-}
-
-#define config_value(data,name,default_value) \
- lp_parm_const_string(GLOBAL_SECTION_SNUM, data, name, default_value)
-
-static const char * config_value_write(const char *location, const char *name, const char *default_value)
-{
- char const *v = NULL;
- char const *swrite = NULL;
-
- v = lp_parm_const_string(GLOBAL_SECTION_SNUM, location, name, default_value);
-
- if (!v)
- return NULL;
-
- swrite = strrchr(v, ':');
-
- /* Default to the same field as read field */
- if (!swrite)
- return v;
-
- swrite++;
-
- /* If the field is 0 chars long, we shouldn't write to it */
- if (!strlen(swrite) || !strcmp(swrite, "NULL"))
- return NULL;
-
- /* Otherwise, use the additionally specified */
- return swrite;
-}
-
-static const char * config_value_read(const char *location, const char *name, const char *default_value)
-{
- char *v = NULL;
- char *swrite;
-
- v = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, location, name, default_value);
-
- if (!v)
- return "NULL";
-
- swrite = strrchr(v, ':');
-
- /* If no write is specified, there are no problems */
- if (!swrite) {
- if (strlen(v) == 0)
- return "NULL";
- return (const char *)v;
- }
-
- /* Otherwise, we have to cut the ':write_part' */
- *swrite = '\0';
- if (strlen(v) == 0)
- return "NULL";
-
- return (const char *)v;
-}
-
-char *sql_account_query_select(const char *data, BOOL update, enum sql_search_field field, const char *value)
-{
- const char *field_string;
- char *query;
-
- switch(field) {
- case SQL_SEARCH_NONE:
- field_string = "'1'";
- value = "1";
- break;
-
- case SQL_SEARCH_USER_SID:
- field_string = config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT);
- break;
-
- case SQL_SEARCH_USER_NAME:
- field_string = config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT);
- break;
- }
-
- asprintf(&query,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'",
- config_value_read(data, "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- config_value_read(data, "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- config_value_read(data, "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- config_value_read(data, "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- config_value_read(data, "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- config_value_read(data, "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT),
- config_value_read(data, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- config_value_read(data, "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- config_value_read(data, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- config_value_read(data, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- config_value_read(data, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- config_value_read(data, "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- config_value_read(data, "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- config_value_read(data, "acct desc column",
- CONFIG_ACCT_DESC_DEFAULT),
- config_value_read(data, "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- config_value_read(data, "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- config_value_read(data, "munged dial column",
- CONFIG_MUNGED_DIAL_DEFAULT),
- config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- config_value_read(data, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- config_value_read(data, "lanman pass column",
- CONFIG_LM_PW_DEFAULT),
- config_value_read(data, "nt pass column",
- CONFIG_NT_PW_DEFAULT),
- config_value_read(data, "plain pass column",
- CONFIG_PLAIN_PW_DEFAULT),
- config_value_read(data, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- config_value_read(data, "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- config_value_read(data, "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- config_value_read(data, "bad password count column",
- CONFIG_BAD_PASSWORD_COUNT_DEFAULT),
- config_value_read(data, "logon count column",
- CONFIG_LOGON_COUNT_DEFAULT),
- config_value_read(data, "unknown 6 column",
- CONFIG_UNKNOWN_6_DEFAULT),
- config_value(data, "table", CONFIG_TABLE_DEFAULT),
- field_string, value
- );
- return query;
-}
-
-char *sql_account_query_delete(const char *data, const char *esc)
-{
- char *query;
-
- asprintf(&query, "DELETE FROM %s WHERE %s = '%s'",
- config_value(data, "table", CONFIG_TABLE_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT), esc);
- return query;
-}
-
-char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd, char isupdate)
-{
- char *ret;
- pstring temp;
- pdb_sql_query query;
- fstring sid_str;
-
- query.update = isupdate;
-
- /* I know this is somewhat overkill but only the talloc
- * functions have asprint_append and the 'normal' asprintf
- * is a GNU extension */
- query.mem_ctx = talloc_init("sql_query_update");
- query.part2 = talloc_asprintf(query.mem_ctx, "%s", "");
- if (query.update) {
- query.part1 =
- talloc_asprintf(query.mem_ctx, "UPDATE %s SET ",
- config_value(location, "table",
- CONFIG_TABLE_DEFAULT));
- } else {
- query.part1 =
- talloc_asprintf(query.mem_ctx, "INSERT INTO %s (",
- config_value(location, "table",
- CONFIG_TABLE_DEFAULT));
- }
-
- pdb_sql_int_field(&query,
- config_value_write(location, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- pdb_get_acct_ctrl(newpwd));
-
- if (pdb_get_init_flags(newpwd, PDB_LOGONTIME) != PDB_DEFAULT) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- pdb_get_logon_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_LOGOFFTIME) != PDB_DEFAULT) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- pdb_get_logoff_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_KICKOFFTIME) != PDB_DEFAULT) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- pdb_get_kickoff_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_CANCHANGETIME) != PDB_DEFAULT) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- pdb_get_pass_can_change_time(newpwd));
- }
-
- if (pdb_get_init_flags(newpwd, PDB_MUSTCHANGETIME) != PDB_DEFAULT) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- pdb_get_pass_must_change_time(newpwd));
- }
-
- if (pdb_get_pass_last_set_time(newpwd)) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- pdb_get_pass_last_set_time(newpwd));
- }
-
- if (pdb_get_hours_len(newpwd)) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- pdb_get_hours_len(newpwd));
- }
-
- if (pdb_get_logon_divs(newpwd)) {
- pdb_sql_int_field(&query,
- config_value_write(location,
- "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- pdb_get_logon_divs(newpwd));
- }
-
- pdb_sql_string_field(&query,
- config_value_write(location, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_user_sid(newpwd)));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_group_sid(newpwd)));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "username column",
- CONFIG_USERNAME_DEFAULT),
- pdb_get_username(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- pdb_get_domain(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location,
- "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- pdb_get_nt_username(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- pdb_get_fullname(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location,
- "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- pdb_get_logon_script(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location,
- "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- pdb_get_profile_path(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- pdb_get_dir_drive(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- pdb_get_homedir(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location,
- "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- pdb_get_workstations(newpwd));
-
- pdb_sql_string_field(&query,
- config_value_write(location,
- "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- pdb_get_workstations(newpwd));
-
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_sql_string_field(&query,
- config_value_write(location,
- "lanman pass column",
- CONFIG_LM_PW_DEFAULT), temp);
-
- pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_sql_string_field(&query,
- config_value_write(location, "nt pass column",
- CONFIG_NT_PW_DEFAULT), temp);
-
- if (query.update) {
- query.part1[strlen(query.part1) - 1] = '\0';
- query.part1 =
- talloc_asprintf_append(query.mem_ctx, query.part1,
- " WHERE %s = '%s'",
- config_value_read(location,
- "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str, pdb_get_user_sid (newpwd)));
- } else {
- query.part2[strlen(query.part2) - 1] = ')';
- query.part1[strlen(query.part1) - 1] = ')';
- query.part1 =
- talloc_asprintf_append(query.mem_ctx, query.part1,
- " VALUES (%s", query.part2);
- }
-
- ret = strdup(query.part1);
- talloc_destroy(query.mem_ctx);
- return ret;
-}
-
-BOOL sql_account_config_valid(const char *data)
-{
- const char *sid_column, *username_column;
-
- sid_column = config_value_read(data, "user sid column", CONFIG_USER_SID_DEFAULT);
- username_column = config_value_read(data, "username column", CONFIG_USERNAME_DEFAULT);
-
- if(!strcmp(sid_column,"NULL") || !strcmp(username_column, "NULL")) {
- DEBUG(0,("Please specify both a valid 'user sid column' and a valid 'username column' in smb.conf\n"));
- return False;
- }
-
- return True;
-}
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 29063be523b..7902ad235bb 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -1,12 +1,9 @@
/*
- * Unix SMB/CIFS implementation.
- * SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Simo Sorce 2000-2003
- * Copyright (C) Gerald Carter 2000
- * Copyright (C) Jeremy Allison 2001
- * Copyright (C) Andrew Bartlett 2002
- * Copyright (C) Rafal Szczesniak 2004
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Simo Sorce 2000
+ * Copyright (C) Gerald Carter 2000
+ * Copyright (C) Jeremy Allison 2001
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
@@ -25,306 +22,454 @@
#include "includes.h"
-#if 0 /* when made a module use this */
+#ifdef WITH_TDB_SAM
-static int tdbsam_debug_level = DBGC_ALL;
-#undef DBGC_CLASS
-#define DBGC_CLASS tdbsam_debug_level
-
-#else
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-#endif
-
-#define TDBSAM_VERSION 1 /* Most recent TDBSAM version */
-#define TDBSAM_VERSION_STRING "INFO/version"
+#define PDB_VERSION "20010830"
#define PASSDB_FILE_NAME "passdb.tdb"
+#define TDB_FORMAT_STRING "ddddddBBBBBBBBBBBBddBBwdwdBdd"
#define USERPREFIX "USER_"
#define RIDPREFIX "RID_"
-#define PRIVPREFIX "PRIV_"
-#define TRUSTPW_PREFIX "TRUSTPW_"
-#define tdbsamver_t int32
-
-struct tdbsam_privates {
- TDB_CONTEXT *passwd_tdb;
- /* retrive-once info */
- const char *tdbsam_location;
-};
+extern int DEBUGLEVEL;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
-struct pwent_list {
- struct pwent_list *prev, *next;
- TDB_DATA key;
+struct tdb_enum_info {
+ TDB_CONTEXT *passwd_tdb;
+ TDB_DATA key;
};
-static struct pwent_list *tdbsam_pwent_list;
-
-static TDB_LIST_NODE *tp_key_list;
-
-
-/**
- * Convert old TDBSAM to the latest version.
- * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted.
- * This file must be opened with read/write access.
- * @param from Current version of the TDBSAM file.
- * @return True if the conversion has been successful, false otherwise.
- **/
-
-static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
-{
- const char * vstring = TDBSAM_VERSION_STRING;
- SAM_ACCOUNT *user = NULL;
- const char *prefix = USERPREFIX;
- TDB_DATA data, key, old_key;
- uint8 *buf = NULL;
- BOOL ret;
- if (pdb_tdb == NULL) {
- DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n"));
+static struct tdb_enum_info global_tdb_ent;
+/*static SAM_ACCOUNT global_sam_pass;*/
+
+/**********************************************************************
+ Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
+ *********************************************************************/
+
+static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+{
+
+ /* times are stored as 32bit integer
+ take care on system with 64bit wide time_t
+ --SSS */
+ uint32 logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ char *username;
+ char *domain;
+ char *nt_username;
+ char *dir_drive;
+ char *unknown_str;
+ char *munged_dial;
+ char *fullname;
+ char *homedir;
+ char *logon_script;
+ char *profile_path;
+ char *acct_desc;
+ char *workstations;
+ uint32 username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32 /* uid, gid,*/ user_rid, group_rid, unknown_3, hours_len, unknown_5, unknown_6;
+ uint16 acct_ctrl, logon_divs;
+ uint8 *hours;
+ static uint8 *lm_pw_ptr, *nt_pw_ptr;
+ uint32 len = 0;
+ uint32 lmpwlen, ntpwlen, hourslen;
+ BOOL ret = True;
+ BOOL setflag;
+ struct passwd *pw;
+ uid_t uid;
+ gid_t gid;
+
+ pstring phomedir;
+ pstring pdir_drive;
+ pstring plogon_script;
+ pstring pprofile_path;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
return False;
}
-
- /* handle a Samba upgrade */
- tdb_lock_bystring(pdb_tdb, vstring, 0);
- if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
- DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n"));
- return False;
+ /* unpack the buffer into variables */
+ len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
+ &logon_time,
+ &logoff_time,
+ &kickoff_time,
+ &pass_last_set_time,
+ &pass_can_change_time,
+ &pass_must_change_time,
+ &username_len, &username,
+ &domain_len, &domain,
+ &nt_username_len, &nt_username,
+ &fullname_len, &fullname,
+ &homedir_len, &homedir,
+ &dir_drive_len, &dir_drive,
+ &logon_script_len, &logon_script,
+ &profile_path_len, &profile_path,
+ &acct_desc_len, &acct_desc,
+ &workstations_len, &workstations,
+ &unknown_str_len, &unknown_str,
+ &munged_dial_len, &munged_dial,
+ &user_rid,
+ &group_rid,
+ &lmpwlen, &lm_pw_ptr,
+ &ntpwlen, &nt_pw_ptr,
+ &acct_ctrl,
+ &unknown_3,
+ &logon_divs,
+ &hours_len,
+ &hourslen, &hours,
+ &unknown_5,
+ &unknown_6);
+
+ if (len == -1) {
+ ret = False;
+ goto done;
}
- /* Enumerate all records and convert them */
- key = tdb_firstkey(pdb_tdb);
-
- while (key.dptr) {
-
- /* skip all non-USER entries (eg. RIDs) */
- while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
- old_key = key;
- /* increment to next in line */
- key = tdb_nextkey(pdb_tdb, key);
- SAFE_FREE(old_key.dptr);
- }
-
- if (key.dptr) {
-
- /* read from tdbsam */
- data = tdb_fetch(pdb_tdb, key);
- if (!data.dptr) {
- DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
- return False;
- }
-
- if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) {
- DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n"));
- SAFE_FREE(data.dptr);
- return False;
- }
-
- /* unpack the buffer from the former format */
- DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
- switch (from) {
- case 0:
- ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize);
- break;
- case 1:
- ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
- break;
- default:
- /* unknown tdbsam version */
- ret = False;
- }
- if (!ret) {
- DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
- SAFE_FREE(data.dptr);
- return False;
- }
-
- /* pack from the buffer into the new format */
- DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
- if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) {
- DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n"));
- SAFE_FREE(data.dptr);
- return False;
- }
- data.dptr = (char *)buf;
-
- /* Store the buffer inside the TDBSAM */
- if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) {
- DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr));
- SAFE_FREE(data.dptr);
- return False;
- }
-
- SAFE_FREE(data.dptr);
-
- /* increment to next in line */
- old_key = key;
- key = tdb_nextkey(pdb_tdb, key);
- SAFE_FREE(old_key.dptr);
- }
-
+ /* validate the account and fill in UNIX uid and gid. Standard
+ * getpwnam() is used instead of Get_Pwnam() as we do not need
+ * to try case permutations
+ */
+ if (!username || !(pw=getpwnam(username))) {
+ DEBUG(0,("tdb_sam: getpwnam(%s) return NULL. User does not exist!\n",
+ username?username:"NULL"));
+ ret = False;
+ goto done;
}
- pdb_free_sam(&user);
-
- /* upgrade finished */
- tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION);
- tdb_unlock_bystring(pdb_tdb, vstring);
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ pdb_set_uid(sampass, uid);
+ pdb_set_gid(sampass, gid);
+
+ pdb_set_logon_time(sampass, logon_time);
+ pdb_set_logoff_time(sampass, logoff_time);
+ pdb_set_kickoff_time(sampass, kickoff_time);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time);
+
+ pdb_set_username (sampass, username_len?username:NULL);
+ pdb_set_domain (sampass, domain_len?domain:NULL);
+ pdb_set_nt_username (sampass, nt_username_len?nt_username:NULL);
+ pdb_set_fullname (sampass, fullname_len?fullname:NULL);
+
+ if (homedir) setflag = True;
+ else {
+ setflag = False;
+ pstrcpy(phomedir, lp_logon_home());
+ standard_sub_advanced(-1, username, "", gid, phomedir, sizeof(phomedir));
+ DEBUG(5,("Home directory set back to %s\n", phomedir));
+ }
+ pdb_set_homedir(sampass, phomedir, setflag);
+
+ if (dir_drive) setflag = True;
+ else {
+ setflag = False;
+ pstrcpy(pdir_drive, lp_logon_drive());
+ standard_sub_advanced(-1, username, "", gid, pdir_drive, sizeof(pdir_drive));
+ DEBUG(5,("Home directory set back to %s\n", pdir_drive));
+ }
+ pdb_set_dir_drive(sampass, pdir_drive, setflag);
+
+ if (logon_script) setflag = True;
+ else {
+ setflag = False;
+ pstrcpy(plogon_script, lp_logon_script());
+ standard_sub_advanced(-1, username, "", gid, plogon_script, sizeof(plogon_script));
+ DEBUG(5,("Home directory set back to %s\n", plogon_script));
+ }
+ pdb_set_logon_script(sampass, plogon_script, setflag);
+
+ if (profile_path) setflag = True;
+ else {
+ setflag = False;
+ pstrcpy(pprofile_path, lp_logon_path());
+ standard_sub_advanced(-1, username, "", gid, pprofile_path, sizeof(pprofile_path));
+ DEBUG(5,("Home directory set back to %s\n", pprofile_path));
+ }
+ pdb_set_profile_path(sampass, pprofile_path, setflag);
+
+ pdb_set_acct_desc (sampass, acct_desc);
+ pdb_set_workstations (sampass, workstations);
+ pdb_set_munged_dial (sampass, munged_dial);
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
- return(True);
-}
+ /*pdb_set_uid(sampass, uid);
+ pdb_set_gid(sampass, gid);*/
+ pdb_set_user_rid(sampass, user_rid);
+ pdb_set_group_rid(sampass, group_rid);
+ pdb_set_unknown_3(sampass, unknown_3);
+ pdb_set_hours_len(sampass, hours_len);
+ pdb_set_unknown_5(sampass, unknown_5);
+ pdb_set_unknown_6(sampass, unknown_6);
+ pdb_set_acct_ctrl(sampass, acct_ctrl);
+ pdb_set_logon_divs(sampass, logon_divs);
+ pdb_set_hours(sampass, hours);
-/**
- * Open the TDB passwd database, check version and convert it if needed.
- * @param name filename of the tdbsam file.
- * @param open_flags file access mode.
- * @return a TDB_CONTEXT handle on the tdbsam file.
- **/
+done:
-static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags)
-{
- TDB_CONTEXT *pdb_tdb;
- tdbsamver_t version;
-
- /* Try to open tdb passwd */
- if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT,
- open_flags, 0600))) {
- DEBUG(0, ("Unable to open/create TDB passwd\n"));
- return NULL;
- }
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
- /* Check the version */
- version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb,
- TDBSAM_VERSION_STRING);
- if (version == -1)
- version = 0; /* Version not found, assume version 0 */
-
- /* Compare the version */
- if (version > TDBSAM_VERSION) {
- /* Version more recent than the latest known */
- DEBUG(0, ("TDBSAM version unknown: %d\n", version));
- tdb_close(pdb_tdb);
- pdb_tdb = NULL;
- }
- else if (version < TDBSAM_VERSION) {
- /* Older version, must be converted */
- DEBUG(1, ("TDBSAM version too old (%d), trying to convert it.\n", version));
-
- /* Reopen the pdb file with read-write access if needed */
- if (!(open_flags & O_RDWR)) {
- DEBUG(10, ("tdbsam_tdbopen: TDB file opened with read only access, reopen it with read-write access.\n"));
- tdb_close(pdb_tdb);
- pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, (open_flags & 07777770) | O_RDWR, 0600);
- }
-
- /* Convert */
- if (!tdbsam_convert(pdb_tdb, version)){
- DEBUG(0, ("tdbsam_tdbopen: Error when trying to convert tdbsam: %s\n",name));
- tdb_close(pdb_tdb);
- pdb_tdb = NULL;
- } else {
- DEBUG(1, ("TDBSAM converted successfully.\n"));
- }
-
- /* Reopen the pdb file as it must be */
- if (!(open_flags & O_RDWR)) {
- tdb_close(pdb_tdb);
- pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600);
- }
- }
-
- return pdb_tdb;
+ return ret;
}
-/*****************************************************************************
- Utility functions to close the tdb sam database
- ****************************************************************************/
-
-static void tdbsam_tdbclose ( struct tdbsam_privates *state )
-{
- if ( !state )
- return;
-
- if ( state->passwd_tdb ) {
- tdb_close( state->passwd_tdb );
- state->passwd_tdb = NULL;
+/**********************************************************************
+ Intialize a BYTE buffer from a SAM_ACCOUNT struct
+ *********************************************************************/
+static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
+{
+ size_t len, buflen;
+
+ /* times are stored as 32bit integer
+ take care on system with 64bit wide time_t
+ --SSS */
+ uint32 logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ char *username;
+ char *domain;
+ char *nt_username;
+ char *dir_drive;
+ char *unknown_str;
+ char *munged_dial;
+ char *fullname;
+ char *homedir;
+ char *logon_script;
+ char *profile_path;
+ char *acct_desc;
+ char *workstations;
+ uint32 username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ const uint8 *lm_pw;
+ const uint8 *nt_pw;
+ uint32 lm_pw_len = 16;
+ uint32 nt_pw_len = 16;
+
+ /* do we have a valid SAM_ACCOUNT pointer? */
+ if (sampass == NULL) {
+ DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
+ return -1;
}
-
- return;
-}
+ *buf = NULL;
+ buflen = 0;
+
+ logon_time = (uint32)pdb_get_logon_time(sampass);
+ logoff_time = (uint32)pdb_get_logoff_time(sampass);
+ kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
+ pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
+ pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
+ pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
+
+
+ username = pdb_get_username(sampass);
+ if (username) username_len = strlen(username) +1;
+ else username_len = 0;
+
+ domain = pdb_get_domain(sampass);
+ if (domain) domain_len = strlen(domain) +1;
+ else domain_len = 0;
+
+ nt_username = pdb_get_nt_username(sampass);
+ if (nt_username) nt_username_len = strlen(nt_username) +1;
+ else nt_username_len = 0;
+
+ fullname = pdb_get_fullname(sampass);
+ if (fullname) fullname_len = strlen(fullname) +1;
+ else fullname_len = 0;
+
+ /*
+ * Only updates fields which have been set (not defaults from smb.conf)
+ */
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) dir_drive = pdb_get_dirdrive(sampass);
+ else dir_drive = NULL;
+ if (dir_drive) dir_drive_len = strlen(dir_drive) +1;
+ else dir_drive_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME)) homedir = pdb_get_homedir(sampass);
+ else homedir = NULL;
+ if (homedir) homedir_len = strlen(homedir) +1;
+ else homedir_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT)) logon_script = pdb_get_logon_script(sampass);
+ else logon_script = NULL;
+ if (logon_script) logon_script_len = strlen(logon_script) +1;
+ else logon_script_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE)) profile_path = pdb_get_profile_path(sampass);
+ else profile_path = NULL;
+ if (profile_path) profile_path_len = strlen(profile_path) +1;
+ else profile_path_len = 0;
+
+ lm_pw = pdb_get_lanman_passwd(sampass);
+ if (!lm_pw) lm_pw_len = 0;
+
+ nt_pw = pdb_get_nt_passwd(sampass);
+ if (!nt_pw) nt_pw_len = 0;
+
+ acct_desc = pdb_get_acct_desc(sampass);
+ if (acct_desc) acct_desc_len = strlen(acct_desc) +1;
+ else acct_desc_len = 0;
-/****************************************************************************
- creates a list of user keys
-****************************************************************************/
+ workstations = pdb_get_workstations(sampass);
+ if (workstations) workstations_len = strlen(workstations) +1;
+ else workstations_len = 0;
-static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- const char *prefix = USERPREFIX;
- int prefixlen = strlen (prefix);
- struct pwent_list *ptr;
-
- if ( strncmp(key.dptr, prefix, prefixlen) == 0 ) {
- if ( !(ptr=(struct pwent_list*)malloc(sizeof(struct pwent_list))) ) {
- DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
-
- /* just return 0 and let the traversal continue */
- return 0;
- }
- ZERO_STRUCTP(ptr);
-
- /* save a copy of the key */
-
- ptr->key.dptr = memdup( key.dptr, key.dsize );
- ptr->key.dsize = key.dsize;
+ unknown_str = NULL;
+ unknown_str_len = 0;
+
+ munged_dial = pdb_get_munged_dial(sampass);
+ if (munged_dial) munged_dial_len = strlen(munged_dial) +1;
+ else munged_dial_len = 0;
- DLIST_ADD( tdbsam_pwent_list, ptr );
-
- }
-
-
- return 0;
+ /* one time to get the size needed */
+ len = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
+ logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time,
+ username_len, username,
+ domain_len, domain,
+ nt_username_len, nt_username,
+ fullname_len, fullname,
+ homedir_len, homedir,
+ dir_drive_len, dir_drive,
+ logon_script_len, logon_script,
+ profile_path_len, profile_path,
+ acct_desc_len, acct_desc,
+ workstations_len, workstations,
+ unknown_str_len, unknown_str,
+ munged_dial_len, munged_dial,
+ pdb_get_user_rid(sampass),
+ pdb_get_group_rid(sampass),
+ lm_pw_len, lm_pw,
+ nt_pw_len, nt_pw,
+ pdb_get_acct_ctrl(sampass),
+ pdb_get_unknown3(sampass),
+ pdb_get_logon_divs(sampass),
+ pdb_get_hours_len(sampass),
+ MAX_HOURS_LEN, pdb_get_hours(sampass),
+ pdb_get_unknown5(sampass),
+ pdb_get_unknown6(sampass));
+
+
+ /* malloc the space needed */
+ if ( (*buf=(uint8*)malloc(len)) == NULL) {
+ DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
+ return (-1);
+ }
+
+ /* now for the real call to tdb_pack() */
+ buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING,
+ logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time,
+ username_len, username,
+ domain_len, domain,
+ nt_username_len, nt_username,
+ fullname_len, fullname,
+ homedir_len, homedir,
+ dir_drive_len, dir_drive,
+ logon_script_len, logon_script,
+ profile_path_len, profile_path,
+ acct_desc_len, acct_desc,
+ workstations_len, workstations,
+ unknown_str_len, unknown_str,
+ munged_dial_len, munged_dial,
+ pdb_get_user_rid(sampass),
+ pdb_get_group_rid(sampass),
+ lm_pw_len, lm_pw,
+ nt_pw_len, nt_pw,
+ pdb_get_acct_ctrl(sampass),
+ pdb_get_unknown3(sampass),
+ pdb_get_logon_divs(sampass),
+ pdb_get_hours_len(sampass),
+ MAX_HOURS_LEN, pdb_get_hours(sampass),
+ pdb_get_unknown5(sampass),
+ pdb_get_unknown6(sampass));
+
+
+ /* check to make sure we got it correct */
+ if (buflen != len) {
+ /* error */
+ SAFE_FREE (*buf);
+ return (-1);
+ }
+
+ return (buflen);
}
/***************************************************************
Open the TDB passwd database for SAM account enumeration.
- Save a list of user keys for iteration.
****************************************************************/
-static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+BOOL pdb_setsampwent(BOOL update)
{
- uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY;
+ pstring tdbfile;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
+ get_private_directory(tdbfile);
+ pstrcat(tdbfile, "/");
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
- if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, flags )) )
- return NT_STATUS_UNSUCCESSFUL;
-
- tdb_traverse( tdb_state->passwd_tdb, tdbsam_traverse_setpwent, NULL );
+ /* Open tdb passwd */
+ if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
+ {
+ DEBUG(0, ("Unable to open/create TDB passwd\n"));
+ return False;
+ }
- return NT_STATUS_OK;
-}
+ global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb);
+ return True;
+}
/***************************************************************
End enumeration of the TDB passwd list.
****************************************************************/
-static void tdbsam_endsampwent(struct pdb_methods *my_methods)
+void pdb_endsampwent(void)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- struct pwent_list *ptr, *ptr_next;
-
- tdbsam_tdbclose( tdb_state );
-
- /* clear out any remaining entries in the list */
-
- for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) {
- ptr_next = ptr->next;
- DLIST_REMOVE( tdbsam_pwent_list, ptr );
- SAFE_FREE( ptr->key.dptr);
- SAFE_FREE( ptr );
+ if (global_tdb_ent.passwd_tdb) {
+ tdb_close(global_tdb_ent.passwd_tdb);
+ global_tdb_ent.passwd_tdb = NULL;
}
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
@@ -334,103 +479,89 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods)
Get one SAM_ACCOUNT from the TDB (next in line)
*****************************************************************/
-static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+BOOL pdb_getsampwent(SAM_ACCOUNT *user)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_DATA data;
- struct pwent_list *pkey;
-
- if ( !user ) {
- DEBUG(0,("tdbsam_getsampwent: SAM_ACCOUNT is NULL.\n"));
- return nt_status;
- }
+ TDB_DATA data;
+ struct passwd *pw;
+ uid_t uid;
+ gid_t gid;
+ char *prefix = USERPREFIX;
+ int prefixlen = strlen (prefix);
- if ( !tdbsam_pwent_list ) {
- DEBUG(4,("tdbsam_getsampwent: end of list\n"));
- tdbsam_tdbclose( tdb_state );
- return nt_status;
- }
-
- if ( !tdb_state->passwd_tdb ) {
- if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY)) )
- return nt_status;
+ if (user==NULL) {
+ DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n"));
+ return False;
}
- /* pull the next entry */
-
- pkey = tdbsam_pwent_list;
- DLIST_REMOVE( tdbsam_pwent_list, pkey );
-
- data = tdb_fetch(tdb_state->passwd_tdb, pkey->key);
+ /* skip all non-USER entries (eg. RIDS) */
+ while ((global_tdb_ent.key.dsize != 0) && (strncmp(global_tdb_ent.key.dptr, prefix, prefixlen)))
+ /* increment to next in line */
+ global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
- SAFE_FREE( pkey->key.dptr);
- SAFE_FREE( pkey);
-
+ /* do we have an valid interation pointer? */
+ if(global_tdb_ent.passwd_tdb == NULL) {
+ DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
+ return False;
+ }
+
+ data = tdb_fetch(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
if (!data.dptr) {
- DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
- return nt_status;
+ DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
+ return False;
}
- if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
+ /* unpack the buffer */
+ if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
+ SAFE_FREE(data.dptr);
+ return False;
}
+ SAFE_FREE(data.dptr);
- SAFE_FREE( data.dptr );
-
+ /* increment to next in line */
+ global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
- return NT_STATUS_OK;
+ return True;
}
/******************************************************************
Lookup a name in the SAM TDB
******************************************************************/
-static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
+BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
+ struct passwd *pw;
+ pstring tdbfile;
fstring name;
+ uid_t uid;
+ gid_t gid;
- if ( !user ) {
+
+ if (user==NULL) {
DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- return nt_status;
+ return False;
}
/* Data is stored in all lower-case */
fstrcpy(name, sname);
- strlower_m(name);
+ strlower(name);
+ get_private_directory(tdbfile);
+ pstrcat(tdbfile, "/");
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
+
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) {
-
- if (errno == ENOENT) {
- /*
- * TDB file doesn't exist, so try to create new one. This is useful to avoid
- * confusing error msg when adding user account first time
- */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_CREAT ))) {
- DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n",
- tdb_state->tdbsam_location));
- } else {
- DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) does not exist. Couldn't create new one. Error was: %s\n",
- tdb_state->tdbsam_location, strerror(errno)));
- }
-
- /* requested user isn't there anyway */
- nt_status = NT_STATUS_NO_SUCH_USER;
- return nt_status;
- }
- DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
- return nt_status;
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+ DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
+ return False;
}
/* get the record */
@@ -438,102 +569,99 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
if (!data.dptr) {
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
tdb_close(pwd_tdb);
- return nt_status;
+ return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
tdb_close(pwd_tdb);
- return nt_status;
+ return False;
}
SAFE_FREE(data.dptr);
/* no further use for database, close it now */
tdb_close(pwd_tdb);
- return NT_STATUS_OK;
+ return True;
}
/***************************************************************************
Search by rid
**************************************************************************/
-static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
+BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
+ pstring tdbfile;
fstring name;
if (user==NULL) {
DEBUG(0,("pdb_getsampwrid: SAM_ACCOUNT is NULL.\n"));
- return nt_status;
+ return False;
}
+ get_private_directory(tdbfile);
+ pstrcat(tdbfile, "/");
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
+
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
- return nt_status;
+ return False;
}
/* get the record */
data = tdb_fetch (pwd_tdb, key);
if (!data.dptr) {
- DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
+ DEBUG(5,("pdb_getsampwrid (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
- return nt_status;
+ return False;
}
-
- fstrcpy(name, data.dptr);
+ fstrcpy (name, data.dptr);
SAFE_FREE(data.dptr);
tdb_close (pwd_tdb);
- return tdbsam_getsampwnam (my_methods, user, name);
-}
-
-static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
-{
- uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return NT_STATUS_UNSUCCESSFUL;
- return tdbsam_getsampwrid(my_methods, user, rid);
+ return pdb_getsampwnam (user, name);
}
/***************************************************************************
Delete a SAM_ACCOUNT
****************************************************************************/
-static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass)
+BOOL pdb_delete_sam_account(const char *sname)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
+ SAM_ACCOUNT *sam_pass = NULL;
TDB_CONTEXT *pwd_tdb;
- TDB_DATA key;
+ TDB_DATA key, data;
fstring keystr;
+ pstring tdbfile;
uint32 rid;
fstring name;
- fstrcpy(name, pdb_get_username(sam_pass));
- strlower_m(name);
+ fstrcpy(name, sname);
+ strlower(name);
+ get_private_directory(tdbfile);
+ pstrcat(tdbfile, "/");
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
+
/* open the TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR))) {
+ if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600))) {
DEBUG(0, ("Unable to open TDB passwd!"));
- return nt_status;
+ return False;
}
/* set the search key */
@@ -541,14 +669,39 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
+ /* get the record */
+ data = tdb_fetch (pwd_tdb, key);
+ if (!data.dptr) {
+ DEBUG(5,("pdb_delete_sam_account (TDB): error fetching database.\n"));
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ tdb_close (pwd_tdb);
+ return False;
+ }
+
+ /* unpack the buffer */
+ if (!pdb_init_sam (&sam_pass)) {
+ tdb_close (pwd_tdb);
+ return False;
+ }
+
+ if (!init_sam_from_buffer (sam_pass, data.dptr, data.dsize)) {
+ DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
+ tdb_close (pwd_tdb);
+ SAFE_FREE(data.dptr);
+ return False;
+ }
+ SAFE_FREE(data.dptr);
+
rid = pdb_get_user_rid(sam_pass);
+ pdb_free_sam (sam_pass);
+
/* it's outaa here! 8^) */
if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
- return nt_status;
+ return False;
}
/* delete also the RID key */
@@ -563,92 +716,86 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC
DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
- return nt_status;
+ return False;
}
tdb_close(pwd_tdb);
- return NT_STATUS_OK;
+ return True;
}
/***************************************************************************
Update the TDB SAM
****************************************************************************/
-static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb = NULL;
TDB_DATA key, data;
uint8 *buf = NULL;
fstring keystr;
+ pstring tdbfile;
fstring name;
BOOL ret = True;
- uint32 user_rid;
-
- /* invalidate the existing TDB iterator if it is open */
-
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
+ get_private_directory(tdbfile);
+ pstrcat(tdbfile, "/");
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
- if (!pwd_tdb) {
- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
- return False;
- }
-
- if (!pdb_get_group_rid(newpwd)) {
- DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",
- pdb_get_username(newpwd)));
- ret = False;
- goto done;
- }
-
- if ( !(user_rid = pdb_get_user_rid(newpwd)) ) {
- DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd)));
- ret = False;
- goto done;
- }
+ if ( (!newpwd->uid) || (!newpwd->gid) )
+ DEBUG (0,("tdb_update_sam: Storing a SAM_ACCOUNT for [%s] with uid %d and gid %d!\n",
+ newpwd->username, newpwd->uid, newpwd->gid));
+
+ /* if we don't have a RID, then generate one */
+ if (!newpwd->user_rid)
+ pdb_set_user_rid (newpwd, pdb_uid_to_user_rid (newpwd->uid));
+ if (!newpwd->group_rid)
+ pdb_set_group_rid (newpwd, pdb_gid_to_group_rid (newpwd->gid));
/* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
- if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) {
+ if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1) {
DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
ret = False;
goto done;
}
- data.dptr = (char *)buf;
+ data.dptr = buf;
- fstrcpy(name, pdb_get_username(newpwd));
- strlower_m(name);
+ fstrcpy(name,pdb_get_username(newpwd));
+ strlower(name);
- DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid));
-
/* setup the USER index key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
+ key.dsize = strlen (keystr) + 1;
+
+ /* invalidate the existing TDB iterator if it is open */
+ if (global_tdb_ent.passwd_tdb) {
+ tdb_close(global_tdb_ent.passwd_tdb);
+ global_tdb_ent.passwd_tdb = NULL;
+ }
+
+ /* open the account TDB passwd*/
+ pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
+ if (!pwd_tdb)
+ {
+ DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
+ return False;
+ }
/* add the account */
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
- DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
+ DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
ret = False;
goto done;
}
/* setup RID data */
- data.dsize = strlen(name) + 1;
+ data.dsize = sizeof(fstring);
data.dptr = name;
/* setup the RID index key */
- slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid);
+ slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
@@ -656,7 +803,6 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify TDB passwd !"));
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
ret = False;
goto done;
}
@@ -673,1012 +819,21 @@ done:
Modifies an existing SAM_ACCOUNT
****************************************************************************/
-static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
+BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override)
{
- if (tdb_update_sam(my_methods, newpwd, TDB_MODIFY))
- return NT_STATUS_OK;
- else
- return NT_STATUS_UNSUCCESSFUL;
+ return (tdb_update_sam(newpwd, override, TDB_MODIFY));
}
/***************************************************************************
Adds an existing SAM_ACCOUNT
****************************************************************************/
-static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
-{
- if (tdb_update_sam(my_methods, newpwd, TDB_INSERT))
- return NT_STATUS_OK;
- else
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-static void free_private_data(void **vp)
-{
- struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp;
- tdbsam_tdbclose(*tdb_state);
- *tdb_state = NULL;
-
- /* No need to free any further, as it is talloc()ed */
-}
-
-
-/**
- * Start trust passwords enumeration.
- * Function performs a search for properly prefixed objects.
- *
- * @param methods methods belonging in pdb context (module)
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_settrustpwent(struct pdb_methods *methods)
-{
- TDB_CONTEXT *secrets_tdb = secrets_open();
- char* trustpw_pattern;
-
- if (!methods)
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!secrets_tdb) {
- DEBUG(1, ("pdb_settrustpwent: couldn't open secrets.tdb file.\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(7, ("pdb_settrustpwent: opening trust passwords database.\n"));
- asprintf(&trustpw_pattern, "%s*", TRUSTPW_PREFIX);
- tp_key_list = tdb_search_keys(secrets_tdb, trustpw_pattern);
-
- SAFE_FREE(trustpw_pattern);
- return NT_STATUS_OK;
-}
-
-
-static void tdbsam_endtrustpwent(struct pdb_methods *methods)
-{
- tdb_search_list_free(tp_key_list);
- tp_key_list = NULL;
- DEBUG(7, ("pdb_endtrustpwent: closing trust passwords database.\n"));
-}
-
-
-/**
- * Enumerate across trust passwords (machine and interdomain nt/ads)
- *
- * @param methods methods belonging in pdb context (module)
- * @param trust trust password structure
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TDB_LIST_NODE *tp_key;
- TDB_DATA tp_data;
- TDB_CONTEXT *secrets_tdb = secrets_open();
-
- if (!secrets_tdb) {
- DEBUG(0, ("pdb_gettrustpwent: couldn't open secrets.tdb file!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- tp_key = tp_key_list;
- if (!tp_key || !tp_key->node_key.dptr) {
- DEBUG(7, ("pdb_gettrustpwent: end of search keys list.\n"));
- return NT_STATUS_NO_MORE_ENTRIES;
- }
-
- DLIST_REMOVE(tp_key_list, tp_key);
-
- tp_data = tdb_fetch(secrets_tdb, tp_key->node_key);
- SAFE_FREE(tp_key->node_key.dptr);
- SAFE_FREE(tp_key);
-
- if (!tp_data.dptr) {
- DEBUG(5, ("pdb_gettrustpwent: no database entry found. Deleted password ?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!pdb_init_trustpw_from_buffer(trust, (const char**)&tp_data.dptr,
- tp_data.dsize)) {
- DEBUG(0, ("pdb_gettrustpwent: Bad SAM_TRUST_PASSWD entry returned from TDB!\n"));
- }
-
- nt_status = STATUS_MORE_ENTRIES;
-
- SAFE_FREE(tp_data.dptr);
- return nt_status;
-}
-
-
-/**
- * Get trust password by trusted party name
- *
- * @param methods methods belonging to pdb context (module)
- * @param trust trust password structure
- * @param sid trusted party name
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust,
- const char *name)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char domain_name[32];
- size_t domain_name_len = sizeof(domain_name);
- size_t uni_name_len;
-
- if (!methods) return nt_status;
-
- if (!trust) {
- DEBUG(0, ("pdb_gettrustpwnam: SAM_TRUST_PASSWD is NULL\n"));
- return nt_status;
- }
-
- if (!name) {
- DEBUG(0, ("pdb_gettrustpwnam: char *name is NULL\n"));
- return nt_status;
- }
-
- nt_status = methods->settrustpwent(methods);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
-
- DEBUG(7, ("pdb_gettrustpwnam: Searching for trust password %s", name));
- do {
- /* get trust password (next in turn) */
- nt_status = methods->gettrustpwent(methods, trust);
-
- /* convert unicode name and do case insensitive compare source
- string length is given as byte length, even though it not
- necessarily corresponds to the actual unicode string length */
- pull_ucs2(NULL, domain_name, trust->private.uni_name, domain_name_len,
- sizeof(trust->private.uni_name), 0);
- uni_name_len = trust->private.uni_name_len;
- domain_name[uni_name_len > 32 ? 32 : uni_name_len] = 0;
-
- DEBUG(10, ("Trust password: %s\n", domain_name));
- if (!StrnCaseCmp(domain_name, name, sizeof(domain_name))) {
- DEBUG(7, ("pdb_gettrustpwnam: Trust password %s found!\n", domain_name));
- return NT_STATUS_OK;
- }
-
- } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
-
- DEBUG(7, ("pdb_gettrustpwnam: Trust password not found"));
- methods->endtrustpwent(methods);
- return nt_status;
-}
-
-
-/**
- * Get trust password by trusted party sid
- *
- * @param methods methods belonging to pdb context (module)
- * @param trust trust password structure
- * @param sid trusted party sid
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust,
- const DOM_SID *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- if (!methods) return nt_status;
-
- if (!trust) {
- DEBUG(0, ("pdb_gettrustpwsid: SAM_TRUST_PASSWD is NULL\n"));
- return nt_status;
- }
-
- if (!sid) {
- DEBUG(0, ("pdb_gettrustpwsid: DOM_SID is NULL\n"));
- return nt_status;
- }
-
- nt_status = methods->settrustpwent(methods);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
-
- DEBUG(7, ("pdb_gettrustpwsid: Searching for trust password %s\n", sid_string_static(sid)));
- do {
- nt_status = tdbsam_gettrustpwent(methods, trust);
-
- DEBUG(10, ("Trust password: %s\n", sid_string_static(&trust->private.domain_sid)));
- if (sid_equal(&trust->private.domain_sid, sid)) {
- DEBUG(7, ("pdb_gettrustpwsid: Trust password %s found!\n",
- sid_string_static(&trust->private.domain_sid)));
- return NT_STATUS_OK;
- }
-
- } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
-
- DEBUG(7, ("pdb_gettrustpwsid: Trust password not found"));
- methods->endtrustpwent(methods);
- return nt_status;
-}
-
-
-static NTSTATUS tdb_update_trustpw(const SAM_TRUST_PASSWD *pass, int tdb_flag)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *mem_ctx;
- TDB_CONTEXT *secrets_tdb;
- TDB_DATA key, data;
-
- char* domain = NULL, *tp_key = NULL;
- char** buffer;
- size_t buffer_len;
-
- secrets_tdb = secrets_open();
- if (!secrets_tdb) {
- DEBUG(1, ("tdb_update_trustpw: couldn't open secrets.tdb file!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- mem_ctx = talloc_init("tdbsam_add_trust_passwd: storing new trust password");
- if (!mem_ctx) {
- DEBUG(0, ("tdb_update_trustpw: couldn't create talloc context. Out of memory ?\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- /* convert unicode name to char* and create the key for tdb record */
- pull_ucs2_talloc(mem_ctx, &domain, pass->private.uni_name);
- if (!domain) {
- DEBUG(0, ("tdb_update_trustpw: couldn't allocate talloc memory. Out of memory?\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- tp_key = talloc_asprintf(mem_ctx, "%s%s", TRUSTPW_PREFIX, domain);
- if (!tp_key) {
- DEBUG(0, ("tdb_update_trustpw: couldn't allocate talloc memory. Out of memory?\n"));
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* prepare storage record */
- buffer_len = pdb_init_buffer_from_trustpw(mem_ctx, buffer, pass);
-
- key.dptr = tp_key;
- key.dsize = strlen(tp_key);
- data.dptr = *buffer;
- data.dsize = buffer_len;
-
- /* write the packed structure in secrets.tdb */
- if (tdb_store(secrets_tdb, key, data, tdb_flag) != TDB_SUCCESS) {
- DEBUG(1, ("tdb_update_trustpw: couldn't write SAM_TRUST_PASSWD structure in secrets.tdb!\n"));
- talloc_destroy(mem_ctx);
- return nt_status;
- }
-
- DEBUG(7, ("tdb_update_trustpw: SAM_TRUST_PASSWD structure stored successfully.\n"));
- nt_status = NT_STATUS_OK;
- talloc_destroy(mem_ctx);
- return nt_status;
-}
-
-
-/**
- * Add new trust password.
- *
- * @param methods methods belonging in pdb context (module)
- * @param trust trust password structure
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_add_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD *trust)
-{
- DEBUG(7, ("pdb_add_trust_passwd: adding new trust password\n"));
- return tdb_update_trustpw(trust, TDB_INSERT);
-}
-
-
-/**
- * Update trust password.
- *
- * @param methods methods belonging in pdb context (module)
- * @param trust trust password structure
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
+BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd)
{
- DEBUG(7, ("pdb_update_trust_passwd: updating trust password\n"));
- return tdb_update_trustpw(trust, TDB_MODIFY);
+ return (tdb_update_sam(newpwd, True, TDB_INSERT));
}
-
-/**
- * Delete trust password.
- *
- * @param methods methods belonging in pdb context (module)
- * @param trust trust password structure
- *
- * @return nt status of performed operation
- **/
-
-static NTSTATUS tdbsam_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int status;
- TALLOC_CTX *mem_ctx = NULL;
- TDB_CONTEXT *secrets_tdb = NULL;
- TDB_DATA domain_key;
- char *domain = NULL;
- struct trust_passwd_data t;
-
- if (!methods) return nt_status;
-
- if (!trust) {
- DEBUG(0, ("pdb_delete_trust_passwd: SAM_TRUST_PASSWD is NULL\n"));
- return nt_status;
- }
- t = trust->private;
-
- secrets_tdb = secrets_open();
- if (!secrets_tdb) {
- DEBUG(1, ("pdb_delete_trust_passwd: couldn't open secrets.tdb file!\n"));
- return nt_status;
- }
-
- mem_ctx = talloc_init("tdbsam_delete_trust_passwd: deleting trust password");
- if (!mem_ctx) {
- DEBUG(0, ("pdb_delete_trust_passwd: couln't create talloc context. Out of memory ?\n"));
- return nt_status;
- }
-
- /* convert unicode name to char* and make sure it's null-terminated */
- pull_ucs2_talloc(mem_ctx, &domain, t.uni_name);
- if (!domain) {
- DEBUG(0, ("pdb_delete_trust_passwd: couldn't allocate talloc memory. Out of memory?\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- domain_key.dptr = talloc_asprintf(mem_ctx, "%s%s", TRUSTPW_PREFIX, domain);
- domain_key.dsize = strlen(TRUSTPW_PREFIX) + t.uni_name_len;
- if (!domain_key.dptr) {
- DEBUG(0, ("pdb_delete_trust_passwd: couldn't allocate talloc memory. Out of memory?\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- status = tdb_delete(secrets_tdb, domain_key);
- if (status) {
- DEBUG(0, ("pdb_delete_trust_passwd: couldn't delete %s record from secrets.tdb!\n",
- domain_key.dptr));
- } else {
- DEBUG(0, ("pdb_delete_trust_passwd: trust password %s successfully deleted\n",
- domain));
- }
-
- talloc_destroy(mem_ctx);
- return status ? NT_STATUS_UNSUCCESSFUL : NT_STATUS_OK;
-}
-
-
-static NTSTATUS tdbsam_lsa_create_account(struct pdb_methods *my_methods, const DOM_SID *sid)
-{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb = NULL;
- TDB_DATA key, data;
- fstring keystr;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- fstring sid_str;
-
- /* invalidate the existing TDB iterator if it is open */
-
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
-
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
-
- if (!pwd_tdb) {
- DEBUG(0, ("tdb_lsa_create_account: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* setup the PRIV index key */
- sid_to_string(sid_str, sid);
-
- slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, sid_str);
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- /* get the record */
- data = tdb_fetch (pwd_tdb, key);
-
- /* check if the privilege already exist in the database */
- if (data.dptr != NULL) {
- ret = NT_STATUS_OK;
- goto done;
- }
-
- data.dptr = strdup("");
- data.dsize = 1;
-
- /* add the account */
- if (tdb_store(pwd_tdb, key, data, TDB_INSERT) != TDB_SUCCESS) {
- DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
- DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- /* cleanup */
- tdb_close (pwd_tdb);
-
- return (ret);
-}
-
-/***************************************************************************
- Add privilege to sid
-****************************************************************************/
-
-static NTSTATUS tdbsam_add_privilege_to_sid(struct pdb_methods *my_methods, const char *priv_name, const DOM_SID *sid)
-{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb = NULL;
- TDB_DATA key, data;
- fstring keystr;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- fstring sid_str;
- char *priv_list = NULL, *s = NULL;
- size_t str_size;
- int priv_name_len = strlen(priv_name);
- int flag;
-
- /* invalidate the existing TDB iterator if it is open */
-
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
-
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
-
- if (!pwd_tdb) {
- DEBUG(0, ("tdb_add_privilege_to_sid: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* setup the PRIV index key */
- sid_to_string(sid_str, sid);
-
- slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, sid_str);
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- /* check if the privilege already exist in the database */
-
- /* get the record */
- data = tdb_fetch (pwd_tdb, key);
-
- if (data.dptr) {
- char *p;
-
- /* check the list is not empty */
- if (*(data.dptr)) {
- priv_list = strdup(data.dptr);
- if (!priv_list) {
- DEBUG(0, ("tdbsam_add_privilege_to_sid: Out of Memory!\n"));
- goto done;
- }
- }
-
- /* check the privilege is not yet there */
- p = data.dptr;
-
- do {
- p += (p == data.dptr)?0:1;
- if ((StrnCaseCmp(p, priv_name, priv_name_len)) == 0) {
- ret = NT_STATUS_OK;
- SAFE_FREE(priv_list);
- SAFE_FREE(data.dptr);
- goto done;
- }
-
- } while ((p = strchr(p, ',')) != NULL);
-
- SAFE_FREE(data.dptr);
-
- flag = TDB_MODIFY;
- } else {
- /* if sid does not exist create one */
- flag = TDB_INSERT;
- }
-
- /* add the given privilege */
- if (priv_list) {
- int priv_list_len = strlen(priv_list);
- str_size = priv_list_len + priv_name_len + 2;
- s = realloc(priv_list, str_size);
- if (!s) {
- DEBUG(0, ("tdbsam_add_privilege_to_sid: Out of Memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
- priv_list = s;
- s = &priv_list[priv_list_len];
- snprintf(s, priv_name_len + 2, ",%s", priv_name);
-
- } else {
- priv_list = strdup(priv_name);
- if (!priv_list) {
- DEBUG(0, ("tdbsam_add_sid_to_privilege: Out of Memory!\n"));
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- }
-
- /* copy the PRIVILEGE struct into a BYTE buffer for storage */
- data.dsize = strlen(priv_list) + 1;
- data.dptr = priv_list;
-
- /* add the account */
- if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
- DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
- DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- /* cleanup */
- tdb_close (pwd_tdb);
- SAFE_FREE(priv_list);
-
- return (ret);
-}
-
-/***************************************************************************
- Reomve privilege from sid
-****************************************************************************/
-
-static NTSTATUS tdbsam_remove_privilege_from_sid(struct pdb_methods *my_methods, const char *priv_name, const DOM_SID *sid)
-{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb = NULL;
- TDB_DATA key, data;
- fstring keystr;
- fstring name;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- fstring sid_str;
- char *priv_list = NULL, *p = NULL;
- int priv_name_len = strlen(priv_name);
-
- /* invalidate the existing TDB iterator if it is open */
-
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
-
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
-
- if (!pwd_tdb) {
- DEBUG(0, ("tdbsam_remove_sid_from_privilege: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* setup the PRIV index key */
- sid_to_string(sid_str, sid);
-
- fstrcpy(name, priv_name);
- strlower_m(name);
-
- slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, sid_str);
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- /* check if the privilege already exist in the database */
-
- /* get the record */
- data = tdb_fetch (pwd_tdb, key);
-
- /* if privilege does not exist, just leave */
- if (!data.dptr) {
- ret = NT_STATUS_OK;
- goto done;
- }
-
- priv_list = strdup(data.dptr);
- SAFE_FREE(data.dptr);
- if (!priv_list) {
- DEBUG(0, ("tdbsam_remove_sid_from_privilege: Out of Memory!\n"));
- goto done;
- }
-
- /* remove the given privilege */
- p = priv_list;
-
- do {
- p += (p == priv_list)?0:1;
- if ((StrnCaseCmp(p, priv_name, priv_name_len)) == 0) {
- break;
- }
-
- } while ((p = strchr(p, ',')) != NULL);
-
- if (p) {
- char *s;
- s = strchr(p, ',');
- if (s) {
- size_t l = strlen(priv_list) + 1 - (p - priv_list);
- memmove(p, ++s, l);
- } else {
- if (p != priv_list)
- p--;
- *p = '\0';
- }
- } else {
- /* sid not found */
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* copy the PRIVILEGE struct into a BYTE buffer for storage */
- data.dsize = strlen(priv_list) + 1;
- data.dptr = priv_list;
-
- /* add the account */
- if (tdb_store(pwd_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) {
- DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
- DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- /* cleanup */
- tdb_close (pwd_tdb);
- SAFE_FREE(priv_list);
-
- return (ret);
-}
-
-/***************************************************************************
- get the privilege list for the given list of sids
-****************************************************************************/
-
-struct priv_traverse_1 {
- char **sid_list;
- PRIVILEGE_SET *privset;
-};
-
-static int tdbsam_traverse_sids(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct priv_traverse_1 *pt = (struct priv_traverse_1 *)state;
- int prefixlen = strlen(PRIVPREFIX);
-
- /* check we have a PRIV_+SID entry */
- if (strncmp(key.dptr, PRIVPREFIX, prefixlen) == 0) {
-
- fstring sid_str;
- int i;
- /* add to privilege_set if any of the sid in the token
- * contain the privilege */
-
- fstrcpy(sid_str, &key.dptr[strlen(PRIVPREFIX)]);
-
- for (i = 0; pt->sid_list[i] != NULL; i++) {
- int len;
-
- len = MAX(strlen(sid_str), strlen(pt->sid_list[i]));
- if (strncmp(sid_str, pt->sid_list[i], len) == 0) {
- char *c, *s;
-
- s = data.dptr;
- if (*s != '\0') {
-
- DEBUG(10, ("sid [%s] found in users sid list\n", pt->sid_list[i]));
- DEBUG(10, ("adding privileges [%s] to the users privilege list\n", data.dptr));
-
- while ((c = strchr(s, ',')) != NULL) {
- *c = '\0';
-
- add_privilege_by_name(pt->privset, s);
- s = c + 1;
- }
- add_privilege_by_name(pt->privset, s);
- }
- }
- }
- }
-
- return 0;
-}
-
-/***************************************************************************
- get the privilege list for the given list of sids
-****************************************************************************/
-
-struct priv_traverse_2 {
- const char *privname;
- DOM_SID **sid_list;
- int *sid_count;
- NTSTATUS status;
-};
-
-static int tdbsam_traverse_single_privilege(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct priv_traverse_2 *pt = (struct priv_traverse_2 *)state;
- int prefixlen = strlen(PRIVPREFIX);
- int privname_len = strlen(pt->privname);
-
- if (*(data.dptr) == 0) return 0;
-
- /* check we have a PRIV_+SID entry */
- if (strncmp(key.dptr, PRIVPREFIX, prefixlen) == 0) {
-
- fstring sid_str;
- char *p;
- BOOL found = False;
- /* add to privilege_set if any of the sid in the token
- * contain the privilege */
-
- fstrcpy(sid_str, &key.dptr[strlen(PRIVPREFIX)]);
-
- p = data.dptr;
-
- do {
- p += (p == data.dptr)?0:1;
- if ((StrnCaseCmp(p, pt->privname, privname_len)) == 0) {
- found = True;
- break;
- }
-
- } while ((p = strchr(p, ',')) != NULL);
-
- if (found) {
- /* add the discovered sid */
- DOM_SID tmpsid;
-
- if (!string_to_sid(&tmpsid, sid_str)) {
- DEBUG(3, ("Could not convert SID\n"));
- return 0;
- }
-
- add_sid_to_array(&tmpsid, pt->sid_list, pt->sid_count);
-
- if (pt->sid_list == NULL) {
- pt->status = NT_STATUS_NO_MEMORY;
- return 1;
- }
-
- pt->status = NT_STATUS_OK;
- }
- }
-
- return 0;
-}
-
-static int tdbsam_traverse_accounts(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct priv_traverse_2 *pt = (struct priv_traverse_2 *)state;
- int prefixlen = strlen(PRIVPREFIX);
-
- if (*(data.dptr) == 0) return 0;
-
- /* check we have a PRIV_+SID entry */
- if (strncmp(key.dptr, PRIVPREFIX, prefixlen) == 0) {
-
- fstring sid_str;
- /* add to privilege_set if any of the sid in the token
- * contain the privilege */
-
- fstrcpy(sid_str, &key.dptr[strlen(PRIVPREFIX)]);
-
- /* add the discovered sid */
- DOM_SID tmpsid;
-
- if (!string_to_sid(&tmpsid, sid_str)) {
- DEBUG(3, ("Could not convert SID\n"));
- return 0;
- }
-
- add_sid_to_array(&tmpsid, pt->sid_list, pt->sid_count);
-
- if (pt->sid_list == NULL) {
- pt->status = NT_STATUS_NO_MEMORY;
- return 1;
- }
-
- pt->status = NT_STATUS_OK;
- }
-
- return 0;
-}
-
-static NTSTATUS tdbsam_get_privilege_set(struct pdb_methods *my_methods, DOM_SID *user_sids, int num_sids, PRIVILEGE_SET *privset)
-{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- TDB_CONTEXT *pwd_tdb = NULL;
- struct priv_traverse_1 pt;
- fstring sid_str;
- char **sid_list;
- int i;
-
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY )))
- return NT_STATUS_UNSUCCESSFUL;
-
- sid_list = (char **)malloc(sizeof(char *) * (num_sids + 1));
- for (i = 0; i < num_sids; i++) {
- sid_to_string(sid_str, &user_sids[i]);
- sid_list[i] = strdup(sid_str);
- if ( ! sid_list[i]) {
- ret = NT_STATUS_NO_MEMORY;
- goto done;
- }
- }
- sid_list[i] = NULL;
-
- pt.sid_list = sid_list;
- pt.privset = privset;
- tdb_traverse(pwd_tdb, tdbsam_traverse_sids, &pt);
-
- ret = NT_STATUS_OK;
-
-done:
- i = 0;
- while (sid_list[i]) {
- free(sid_list[i]);
- i++;
- }
- free(sid_list);
-
- tdb_close(pwd_tdb);
-
- return ret;
-}
-
-static NTSTATUS tdbsam_get_privilege_entry(struct pdb_methods *my_methods, const char *privname, DOM_SID **sid_list, int *sid_count)
-{
- TDB_CONTEXT *pwd_tdb = NULL;
- struct priv_traverse_2 pt;
-
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
-
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY)))
- return NT_STATUS_UNSUCCESSFUL;
-
- pt.status = NT_STATUS_UNSUCCESSFUL;
- pt.sid_list = sid_list;
- pt.sid_count = sid_count;
- pt.privname = privname;
-
- tdb_traverse(pwd_tdb, tdbsam_traverse_single_privilege, &pt);
-
- if (!NT_STATUS_IS_OK(pt.status)) {
- SAFE_FREE(*sid_list);
- *sid_list = NULL;
- *sid_count = 0;
- }
-
- tdb_close(pwd_tdb);
- return pt.status;
-}
-
-static NTSTATUS tdbsam_lsa_enumerate_accounts(struct pdb_methods *my_methods, DOM_SID **sid_list, int *sid_count)
-{
- TDB_CONTEXT *pwd_tdb = NULL;
- struct priv_traverse_2 pt;
-
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
-
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY)))
- return NT_STATUS_UNSUCCESSFUL;
- pt.status = NT_STATUS_NO_MORE_ENTRIES;
- pt.sid_list = sid_list;
- pt.sid_count = sid_count;
- pt.privname = NULL;
-
- tdb_traverse(pwd_tdb, tdbsam_traverse_accounts, &pt);
-
- if (!NT_STATUS_IS_OK(pt.status)) {
- SAFE_FREE(*sid_list);
- *sid_list = NULL;
- *sid_count = 0;
- }
-
- tdb_close(pwd_tdb);
- return pt.status;
-}
-
-
-/**
- * Init tdbsam backend
- *
- * @param pdb_context initialised passdb context
- * @param pdb_method backend methods structure to be filled with function pointers
- * @param location the backend tdb file location
- *
- * @return nt_status code
- **/
-
-static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
- struct tdbsam_privates *tdb_state;
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "tdbsam";
-
- (*pdb_method)->setsampwent = tdbsam_setsampwent;
- (*pdb_method)->endsampwent = tdbsam_endsampwent;
- (*pdb_method)->getsampwent = tdbsam_getsampwent;
- (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
- (*pdb_method)->getsampwsid = tdbsam_getsampwsid;
- (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
- (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
- (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
- (*pdb_method)->settrustpwent = tdbsam_settrustpwent;
- (*pdb_method)->endtrustpwent = tdbsam_endtrustpwent;
- (*pdb_method)->gettrustpwent = tdbsam_gettrustpwent;
- (*pdb_method)->gettrustpwnam = tdbsam_gettrustpwnam;
- (*pdb_method)->gettrustpwsid = tdbsam_gettrustpwsid;
- (*pdb_method)->add_trust_passwd = tdbsam_add_trust_passwd;
- (*pdb_method)->update_trust_passwd = tdbsam_update_trust_passwd;
- (*pdb_method)->delete_trust_passwd = tdbsam_delete_trust_passwd;
- (*pdb_method)->lsa_create_account = tdbsam_lsa_create_account;
- (*pdb_method)->lsa_enumerate_accounts = tdbsam_lsa_enumerate_accounts;
- (*pdb_method)->add_privilege_to_sid = tdbsam_add_privilege_to_sid;
- (*pdb_method)->remove_privilege_from_sid = tdbsam_remove_privilege_from_sid;
- (*pdb_method)->get_privilege_set = tdbsam_get_privilege_set;
- (*pdb_method)->get_privilege_entry = tdbsam_get_privilege_entry;
-
- tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates));
-
- if (!tdb_state) {
- DEBUG(0, ("talloc() failed for tdbsam private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (location) {
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
- pstring tdbfile;
- get_private_directory(tdbfile);
- pstrcat(tdbfile, "/");
- pstrcat(tdbfile, PASSDB_FILE_NAME);
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile);
- }
-
- (*pdb_method)->private_data = tdb_state;
-
- (*pdb_method)->free_private_data = free_private_data;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_tdbsam_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
-}
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void samtdb_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* WITH_TDB_SAM */
diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c
deleted file mode 100644
index 2738ad40e2a..00000000000
--- a/source/passdb/pdb_xml.c
+++ /dev/null
@@ -1,563 +0,0 @@
-
-/*
- * XML password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- * Some parts based on the libxml gjobread example by Daniel Veillard
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* FIXME:
- * - Support stdin input by using '-'
- * - Be faster. Don't rewrite the whole file when adding a user, but store it in the memory and save it when exiting. Requires changes to samba source.
- * - Gives the ability to read/write to standard input/output
- * - Do locking!
- * - Better names!
- */
-
-
-#define XML_URL "http://samba.org/~jelmer/sambapdb.dtd"
-
-#include "includes.h"
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-
-static int xmlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS xmlsam_debug_level
-
-static char * iota(int a) {
- static char tmp[10];
-
- snprintf(tmp, 9, "%d", a);
- return tmp;
-}
-
-static BOOL parsePass(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- pstring temp;
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (strcmp(cur->name, "crypt"))
- DEBUG(0, ("Unknown element %s\n", cur->name));
- else {
- if (!strcmp(xmlGetProp(cur, "type"), "nt")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_nt_passwd(u, temp, PDB_SET);
- else if (!strcmp(xmlGetProp(cur, "type"), "lanman")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- else
- DEBUG(0,
- ("Unknown crypt type: %s\n",
- xmlGetProp(cur, "type")));
- }
- cur = cur->next;
- }
- return True;
-}
-
-static BOOL parseUser(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- char *tmp;
- DOM_SID sid;
-
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_user_sid(u, &sid, PDB_SET);
- }
- pdb_set_username(u, xmlGetProp(cur, "name"), PDB_SET);
- /* We don't care what the top level element name is */
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if ((!strcmp(cur->name, "group")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_group_sid(u, &sid, PDB_SET);
- }
- }
-
- else if ((!strcmp(cur->name, "domain")) && (cur->ns == ns))
- pdb_set_domain(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "fullname") && cur->ns == ns)
- pdb_set_fullname(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "nt_username") && cur->ns == ns)
- pdb_set_nt_username(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_script") && cur->ns == ns)
- pdb_set_logon_script(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "profile_path") && cur->ns == ns)
- pdb_set_profile_path(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_time") && cur->ns == ns)
- pdb_set_logon_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "logoff_time") && cur->ns == ns)
- pdb_set_logoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "kickoff_time") && cur->ns == ns)
- pdb_set_kickoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "logon_divs") && cur->ns == ns)
- pdb_set_logon_divs(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "hours_len") && cur->ns == ns)
- pdb_set_hours_len(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "bad_password_count") && cur->ns == ns)
- pdb_set_bad_password_count(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_count") && cur->ns == ns)
- pdb_set_logon_count(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_6") && cur->ns == ns)
- pdb_set_unknown_6(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "homedir") && cur->ns == ns)
- pdb_set_homedir(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_str") && cur->ns == ns)
- pdb_set_unknown_str(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "dir_drive") && cur->ns == ns)
- pdb_set_dir_drive(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "munged_dial") && cur->ns == ns)
- pdb_set_munged_dial(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_desc") && cur->ns == ns)
- pdb_set_acct_desc(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_ctrl") && cur->ns == ns)
- pdb_set_acct_ctrl(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "workstations") && cur->ns == ns)
- pdb_set_workstations(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if ((!strcmp(cur->name, "password")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "last_set");
- if (tmp)
- pdb_set_pass_last_set_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "must_change");
- if (tmp)
- pdb_set_pass_must_change_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "can_change");
- if (tmp)
- pdb_set_pass_can_change_time(u, atol(tmp), PDB_SET);
- parsePass(doc, ns, cur, u);
- }
-
- else
- DEBUG(0, ("Unknown element %s\n", cur->name));
- cur = cur->next;
- }
-
- return True;
-}
-
-typedef struct pdb_xml {
- char *location;
- char written;
- xmlDocPtr doc;
- xmlNodePtr users;
- xmlNodePtr pwent;
- xmlNsPtr ns;
-} pdb_xml;
-
-static xmlNodePtr parseSambaXMLFile(struct pdb_xml *data)
-{
- xmlNodePtr cur;
-
- data->doc = xmlParseFile(data->location);
- if (data->doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement(data->doc);
- if (!cur) {
- DEBUG(0, ("empty document\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->ns = xmlSearchNsByHref(data->doc, cur, XML_URL);
- if (!data->ns) {
- DEBUG(0,
- ("document of the wrong type, samba user namespace not found\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- if (strcmp(cur->name, "samba")) {
- DEBUG(0, ("document of the wrong type, root node != samba"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
-
- cur = cur->xmlChildrenNode;
- while (cur && xmlIsBlankNode(cur)) {
- cur = cur->next;
- }
- if (!cur)
- return NULL;
- if ((strcmp(cur->name, "users")) || (cur->ns != data->ns)) {
- DEBUG(0, ("document of the wrong type, was '%s', users expected",
- cur->name));
- DEBUG(0, ("xmlDocDump follows\n"));
- xmlDocDump(stderr, data->doc);
- DEBUG(0, ("xmlDocDump finished\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->users = cur;
- cur = cur->xmlChildrenNode;
- return cur;
-}
-
-static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data->pwent = parseSambaXMLFile(data);
- if (!data->pwent)
- return NT_STATUS_UNSUCCESSFUL;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void xmlsam_endsampwent(struct pdb_methods *methods)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return;
- }
-
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return;
- }
-
- xmlFreeDoc(data->doc);
- data->doc = NULL;
- data->pwent = NULL;
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS xmlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- while (data->pwent) {
- if ((!strcmp(data->pwent->name, "user")) &&
- (data->pwent->ns == data->ns)) {
-
- parseUser(data->doc, data->ns, data->pwent, user);
- data->pwent = data->pwent->next;
- return NT_STATUS_OK;
- }
- data->pwent = data->pwent->next;
- }
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/***************************************************************************
- Adds an existing SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * u)
-{
- pstring temp;
- fstring sid_str;
- xmlNodePtr cur, user, pass, root;
- pdb_xml *data;
-
- DEBUG(10, ("xmlsam_add_sam_account called!\n"));
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Create a new document if we can't open the current one */
- if (!parseSambaXMLFile(data)) {
- DEBUG(0, ("Can't load current XML file, creating a new one\n"));
- data->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- root = xmlNewDocNode(data->doc, NULL, "samba", NULL);
- cur = xmlDocSetRootElement(data->doc, root);
- data->ns = xmlNewNs(root, XML_URL, "samba");
- data->users = xmlNewChild(root, data->ns, "users", NULL);
- }
-
- user = xmlNewChild(data->users, data->ns, "user", NULL);
- xmlNewProp(user, "sid",
- sid_to_string(sid_str, pdb_get_user_sid(u)));
-
- if (pdb_get_username(u) && strcmp(pdb_get_username(u), ""))
- xmlNewProp(user, "name", pdb_get_username(u));
-
- cur = xmlNewChild(user, data->ns, "group", NULL);
-
- xmlNewProp(cur, "sid",
- sid_to_string(sid_str, pdb_get_group_sid(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGONTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "logon_time",
- iota(pdb_get_logon_time(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGOFFTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "logoff_time",
- iota(pdb_get_logoff_time(u)));
-
- if (pdb_get_init_flags(u, PDB_KICKOFFTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "kickoff_time",
- iota(pdb_get_kickoff_time(u)));
-
- if (pdb_get_domain(u) && strcmp(pdb_get_domain(u), ""))
- xmlNewChild(user, data->ns, "domain", pdb_get_domain(u));
-
- if (pdb_get_nt_username(u) && strcmp(pdb_get_nt_username(u), ""))
- xmlNewChild(user, data->ns, "nt_username", pdb_get_nt_username(u));
-
- if (pdb_get_fullname(u) && strcmp(pdb_get_fullname(u), ""))
- xmlNewChild(user, data->ns, "fullname", pdb_get_fullname(u));
-
- if (pdb_get_homedir(u) && strcmp(pdb_get_homedir(u), ""))
- xmlNewChild(user, data->ns, "homedir", pdb_get_homedir(u));
-
- if (pdb_get_dir_drive(u) && strcmp(pdb_get_dir_drive(u), ""))
- xmlNewChild(user, data->ns, "dir_drive", pdb_get_dir_drive(u));
-
- if (pdb_get_logon_script(u) && strcmp(pdb_get_logon_script(u), ""))
- xmlNewChild(user, data->ns, "logon_script",
- pdb_get_logon_script(u));
-
- if (pdb_get_profile_path(u) && strcmp(pdb_get_profile_path(u), ""))
- xmlNewChild(user, data->ns, "profile_path",
- pdb_get_profile_path(u));
-
- if (pdb_get_acct_desc(u) && strcmp(pdb_get_acct_desc(u), ""))
- xmlNewChild(user, data->ns, "acct_desc", pdb_get_acct_desc(u));
-
- if (pdb_get_workstations(u) && strcmp(pdb_get_workstations(u), ""))
- xmlNewChild(user, data->ns, "workstations",
- pdb_get_workstations(u));
-
- if (pdb_get_unknown_str(u) && strcmp(pdb_get_unknown_str(u), ""))
- xmlNewChild(user, data->ns, "unknown_str", pdb_get_unknown_str(u));
-
- if (pdb_get_munged_dial(u) && strcmp(pdb_get_munged_dial(u), ""))
- xmlNewChild(user, data->ns, "munged_dial", pdb_get_munged_dial(u));
-
-
- /* Password stuff */
- pass = xmlNewChild(user, data->ns, "password", NULL);
- if (pdb_get_pass_last_set_time(u))
- xmlNewProp(pass, "last_set", iota(pdb_get_pass_last_set_time(u)));
- if (pdb_get_init_flags(u, PDB_CANCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "can_change",
- iota(pdb_get_pass_can_change_time(u)));
-
- if (pdb_get_init_flags(u, PDB_MUSTCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "must_change",
- iota(pdb_get_pass_must_change_time(u)));
-
-
- if (pdb_get_lanman_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(u),
- pdb_get_acct_ctrl(u));
- cur = xmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "lanman");
- }
-
- if (pdb_get_nt_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_nt_passwd(u), pdb_get_acct_ctrl(u));
- cur = xmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "nt");
- }
-
- xmlNewChild(user, data->ns, "acct_ctrl", iota(pdb_get_acct_ctrl(u)));
-
- if (pdb_get_logon_divs(u))
- xmlNewChild(user, data->ns, "logon_divs",
- iota(pdb_get_logon_divs(u)));
-
- if (pdb_get_hours_len(u))
- xmlNewChild(user, data->ns, "hours_len",
- iota(pdb_get_hours_len(u)));
-
- xmlNewChild(user, data->ns, "bad_password_count", iota(pdb_get_bad_password_count(u)));
- xmlNewChild(user, data->ns, "logon_count", iota(pdb_get_logon_count(u)));
- xmlNewChild(user, data->ns, "unknown_6", iota(pdb_get_unknown_6(u)));
- xmlSaveFile(data->location, data->doc);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- pdb_xml *data;
-
- xmlsam_debug_level = debug_add_class("xmlsam");
- if (xmlsam_debug_level == -1) {
- xmlsam_debug_level = DBGC_ALL;
- DEBUG(0, ("xmlsam: Couldn't register custom debugging class!\n"));
- }
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "xmlsam";
-
- (*pdb_method)->setsampwent = xmlsam_setsampwent;
- (*pdb_method)->endsampwent = xmlsam_endsampwent;
- (*pdb_method)->getsampwent = xmlsam_getsampwent;
- (*pdb_method)->add_sam_account = xmlsam_add_sam_account;
- (*pdb_method)->getsampwnam = NULL;
- (*pdb_method)->getsampwsid = NULL;
- (*pdb_method)->update_sam_account = NULL;
- (*pdb_method)->delete_sam_account = NULL;
- (*pdb_method)->get_group_info_by_sid = NULL;
- (*pdb_method)->get_group_list = NULL;
- (*pdb_method)->get_group_sids = NULL;
- (*pdb_method)->add_group = NULL;
- (*pdb_method)->update_group = NULL;
- (*pdb_method)->delete_group = NULL;
- (*pdb_method)->add_sid_to_group = NULL;
- (*pdb_method)->remove_sid_from_group = NULL;
- (*pdb_method)->get_group_info_by_name = NULL;
- (*pdb_method)->get_group_info_by_nt_name = NULL;
- (*pdb_method)->get_group_uids = NULL;
-
- data = talloc(pdb_context->mem_ctx, sizeof(pdb_xml));
- data->location = talloc_strdup(pdb_context->mem_ctx, (location ? location : "passdb.xml"));
- data->pwent = NULL;
- data->written = 0;
- (*pdb_method)->private_data = data;
-
- LIBXML_TEST_VERSION xmlKeepBlanksDefault(0);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_xml_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "xml", xmlsam_init);
-}
diff --git a/source/passdb/privileges.c b/source/passdb/privileges.c
deleted file mode 100644
index 624817e32e0..00000000000
--- a/source/passdb/privileges.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- *
- * default privileges backend for passdb
- *
- * Copyright (C) Andrew Tridgell 2003
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/*
- this is a local implementation of a privileges backend, with
- privileges stored in a tdb. Most passdb implementations will
- probably use this backend, although some (such as pdb_ldap) will
- store the privileges in another manner.
-
- The basic principle is that the backend should store a list of SIDs
- associated with each right, where a right is a string name such as
- 'SeTakeOwnershipPrivilege'. The SIDs can be of any type, and do not
- need to belong to the local domain.
-
- The way this is used is that certain places in the code which
- require access control will ask the privileges backend 'does this
- user have the following privilege'. The 'user' will be a NT_TOKEN,
- which is essentially just a list of SIDs. If any of those SIDs are
- listed in the list of SIDs for that privilege then the answer will
- be 'yes'. That will usually mean that the user gets unconditional
- access to that functionality, regradless of any ACLs. In this way
- privileges act in a similar fashion to unix setuid bits.
-*/
-
-/*
- The terms 'right' and 'privilege' are used interchangably in this
- file. This follows MSDN convention where the LSA calls are calls on
- 'rights', which really means privileges. My apologies for the
- confusion.
-*/
-
-
-/* 15 seconds seems like an ample time for timeouts on the privileges db */
-#define LOCK_TIMEOUT 15
-
-
-/* the tdb handle for the privileges database */
-static TDB_CONTEXT *tdb;
-
-
-/* initialise the privilege database */
-BOOL privilege_init(void)
-{
- tdb = tdb_open_log(lock_path("privilege.tdb"), 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open privilege database\n"));
- return False;
- }
-
- return True;
-}
-
-/*
- lock the record for a particular privilege (write lock)
-*/
-static NTSTATUS privilege_lock_right(const char *right)
-{
- if (tdb_lock_bystring(tdb, right, LOCK_TIMEOUT) != 0) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-
-/*
- unlock the record for a particular privilege (write lock)
-*/
-static void privilege_unlock_right(const char *right)
-{
- tdb_unlock_bystring(tdb, right);
-}
-
-
-/*
- return a list of SIDs that have a particular right
-*/
-NTSTATUS privilege_enum_account_with_right(const char *right,
- uint32 *count,
- DOM_SID **sids)
-{
- TDB_DATA data;
- char *p;
- int i;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- data = tdb_fetch_bystring(tdb, right);
- if (!data.dptr) {
- *count = 0;
- *sids = NULL;
- return NT_STATUS_OK;
- }
-
- /* count them */
- for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
- p += strlen(p) + 1;
- }
- *count = i;
-
- /* allocate and parse */
- *sids = malloc(sizeof(DOM_SID) * *count);
- if (! *sids) {
- return NT_STATUS_NO_MEMORY;
- }
- for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
- if (!string_to_sid(&(*sids)[i], p)) {
- free(data.dptr);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- p += strlen(p) + 1;
- }
-
- free(data.dptr);
-
- return NT_STATUS_OK;
-}
-
-/*
- set what accounts have a given right - this is an internal interface
-*/
-static NTSTATUS privilege_set_accounts_with_right(const char *right,
- uint32 count,
- DOM_SID *sids)
-{
- TDB_DATA data;
- char *p;
- int i;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- /* allocate the maximum size that we might use */
- data.dptr = malloc(count * ((MAXSUBAUTHS*11) + 30));
- if (!data.dptr) {
- return NT_STATUS_NO_MEMORY;
- }
-
- p = data.dptr;
-
- for (i=0;i<count;i++) {
- sid_to_string(p, &sids[i]);
- p += strlen(p) + 1;
- }
-
- data.dsize = PTR_DIFF(p, data.dptr);
-
- if (tdb_store_bystring(tdb, right, data, TDB_REPLACE) != 0) {
- free(data.dptr);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- free(data.dptr);
- return NT_STATUS_OK;
-}
-
-
-/*
- add a SID to the list of SIDs for a right
-*/
-NTSTATUS privilege_add_account_right(const char *right,
- DOM_SID *sid)
-{
- NTSTATUS status;
- DOM_SID *current_sids;
- uint32 current_count;
- int i;
-
- status = privilege_lock_right(right);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = privilege_enum_account_with_right(right, &current_count, &current_sids);
- if (!NT_STATUS_IS_OK(status)) {
- privilege_unlock_right(right);
- return status;
- }
-
- /* maybe that SID is already listed? this is not an error */
- for (i=0;i<current_count;i++) {
- if (sid_equal(&current_sids[i], sid)) {
- privilege_unlock_right(right);
- free(current_sids);
- return NT_STATUS_OK;
- }
- }
-
- /* add it in */
- current_sids = Realloc(current_sids, sizeof(current_sids[0]) * (current_count+1));
- if (!current_sids) {
- privilege_unlock_right(right);
- return NT_STATUS_NO_MEMORY;
- }
-
- sid_copy(&current_sids[current_count], sid);
- current_count++;
-
- status = privilege_set_accounts_with_right(right, current_count, current_sids);
-
- free(current_sids);
- privilege_unlock_right(right);
-
- return status;
-}
-
-
-/*
- remove a SID from the list of SIDs for a right
-*/
-NTSTATUS privilege_remove_account_right(const char *right,
- DOM_SID *sid)
-{
- NTSTATUS status;
- DOM_SID *current_sids;
- uint32 current_count;
- int i;
-
- status = privilege_lock_right(right);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = privilege_enum_account_with_right(right, &current_count, &current_sids);
- if (!NT_STATUS_IS_OK(status)) {
- privilege_unlock_right(right);
- return status;
- }
-
- for (i=0;i<current_count;i++) {
- if (sid_equal(&current_sids[i], sid)) {
- /* found it - so remove it */
- if (current_count-i > 1) {
- memmove(&current_sids[i], &current_sids[i+1],
- sizeof(current_sids[0]) * ((current_count-i)-1));
- }
- current_count--;
- status = privilege_set_accounts_with_right(right,
- current_count,
- current_sids);
- free(current_sids);
- privilege_unlock_right(right);
- return status;
- }
- }
-
- /* removing a right that you don't have is not an error */
-
- safe_free(current_sids);
- privilege_unlock_right(right);
- return NT_STATUS_OK;
-}
-
-
-/*
- an internal function for checking if a SID has a right
-*/
-static BOOL privilege_sid_has_right(DOM_SID *sid, const char *right)
-{
- NTSTATUS status;
- uint32 count;
- DOM_SID *sids;
- int i;
-
- status = privilege_enum_account_with_right(right, &count, &sids);
- if (!NT_STATUS_IS_OK(status)) {
- return False;
- }
- for (i=0;i<count;i++) {
- if (sid_equal(sid, &sids[i])) {
- free(sids);
- return True;
- }
- }
-
- safe_free(sids);
- return False;
-}
-
-/*
- list the rights for an account. This involves traversing the database
-*/
-NTSTATUS privilege_enum_account_rights(DOM_SID *sid,
- uint32 *count,
- char ***rights)
-{
- TDB_DATA key, nextkey;
- char *right;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- *rights = NULL;
- *count = 0;
-
- for (key = tdb_firstkey(tdb); key.dptr; key = nextkey) {
- nextkey = tdb_nextkey(tdb, key);
-
- right = key.dptr;
-
- if (privilege_sid_has_right(sid, right)) {
- (*rights) = (char **)Realloc(*rights,sizeof(char *) * ((*count)+1));
- if (! *rights) {
- safe_free(nextkey.dptr);
- free(key.dptr);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*rights)[*count] = strdup(right);
- (*count)++;
- }
-
- free(key.dptr);
- }
-
- return NT_STATUS_OK;
-}
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 73bcbdf343b..241965e143d 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
- Copyright (C) Andrew Tridgell 1992-2001
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Rafal Szczesniak 2002
- Copyright (C) Tim Potter 2001
+ Unix SMB/Netbios implementation.
+ Version 3.0.
+ Samba registry functions
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,9 +24,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
static TDB_CONTEXT *tdb;
/* open up the secrets database */
@@ -38,7 +34,8 @@ BOOL secrets_init(void)
if (tdb)
return True;
- pstrcpy(fname, lp_private_dir());
+ get_private_directory(fname);
+
pstrcat(fname,"/secrets.tdb");
tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
@@ -50,38 +47,16 @@ BOOL secrets_init(void)
return True;
}
-/* Another incarnation of secrets_init that returns the opened
- tdb context to the caller. Used by tdbsam api to access trust
- passwords */
-
-TDB_CONTEXT* secrets_open(void)
-{
- pstring fname;
-
- if (tdb)
- return tdb;
-
- pstrcpy(fname, lp_private_dir());
- pstrcat(fname,"/secrets.tdb");
-
- tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open %s\n", fname));
- return NULL;
- }
- return tdb;
-}
-
/* read a entry from the secrets database - the caller must free the result
if size is non-null then the size of the entry is put in there
*/
void *secrets_fetch(const char *key, size_t *size)
{
TDB_DATA kbuf, dbuf;
- secrets_init();
+
if (!tdb)
- return NULL;
- kbuf.dptr = (char *)key;
+ return False;
+ kbuf.dptr = key;
kbuf.dsize = strlen(key);
dbuf = tdb_fetch(tdb, kbuf);
if (size)
@@ -94,43 +69,35 @@ void *secrets_fetch(const char *key, size_t *size)
BOOL secrets_store(const char *key, const void *data, size_t size)
{
TDB_DATA kbuf, dbuf;
- secrets_init();
if (!tdb)
return False;
- kbuf.dptr = (char *)key;
+ kbuf.dptr = key;
kbuf.dsize = strlen(key);
- dbuf.dptr = (char *)data;
+ dbuf.dptr = data;
dbuf.dsize = size;
return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
}
-/* delete a secrets database entry
+/* delete a secets database entry
*/
BOOL secrets_delete(const char *key)
{
TDB_DATA kbuf;
- secrets_init();
if (!tdb)
return False;
- kbuf.dptr = (char *)key;
+ kbuf.dptr = key;
kbuf.dsize = strlen(key);
return tdb_delete(tdb, kbuf) == 0;
}
-BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
+BOOL secrets_store_domain_sid(const char *domain, DOM_SID *sid)
{
fstring key;
- BOOL ret;
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
- strupper_m(key);
- ret = secrets_store(key, sid, sizeof(DOM_SID));
-
- /* Force a re-query, in case we modified our domain */
- if (ret)
- reset_global_sam_sid();
- return ret;
+ strupper(key);
+ return secrets_store(key, sid, sizeof(DOM_SID));
}
BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
@@ -140,7 +107,10 @@ BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
size_t size;
slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
- strupper_m(key);
+ strupper(key);
+
+ dos_to_unix(key); /* Convert key to unix-codepage */
+
dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
if (dyn_sid == NULL)
@@ -157,79 +127,22 @@ BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
return True;
}
-BOOL secrets_store_domain_guid(const char *domain, struct uuid *guid)
-{
- fstring key;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
- strupper_m(key);
- return secrets_store(key, guid, sizeof(struct uuid));
-}
-
-BOOL secrets_fetch_domain_guid(const char *domain, struct uuid *guid)
-{
- struct uuid *dyn_guid;
- fstring key;
- size_t size;
- struct uuid new_guid;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
- strupper_m(key);
- dyn_guid = (struct uuid *)secrets_fetch(key, &size);
-
- if ((!dyn_guid) && (lp_server_role() == ROLE_DOMAIN_PDC)) {
- smb_uuid_generate_random(&new_guid);
- if (!secrets_store_domain_guid(domain, &new_guid))
- return False;
- dyn_guid = (struct uuid *)secrets_fetch(key, &size);
- if (dyn_guid == NULL)
- return False;
- }
-
- if (size != sizeof(struct uuid))
- {
- DEBUG(1,("UUID size %d is wrong!\n", (int)size));
- SAFE_FREE(dyn_guid);
- return False;
- }
-
- *guid = *dyn_guid;
- SAFE_FREE(dyn_guid);
- return True;
-}
+/************************************************************************
+form a key for fetching a domain trust password
+************************************************************************/
-/**
- * Form a key for fetching the machine trust account password
- *
- * @param domain domain name
- *
- * @return stored password's key
- **/
const char *trust_keystr(const char *domain)
{
static fstring keystr;
+ fstring dos_domain;
- slprintf(keystr,sizeof(keystr)-1,"%s/%s",
- SECRETS_MACHINE_ACCT_PASS, domain);
- strupper_m(keystr);
-
- return keystr;
-}
+ fstrcpy(dos_domain, domain);
+ unix_to_dos(dos_domain);
-/**
- * Form a key for fetching a trusted domain password
- *
- * @param domain trusted domain name
- *
- * @return stored password's key
- **/
-const char *trustdom_keystr(const char *domain)
-{
- static pstring keystr;
+ slprintf(keystr,sizeof(keystr)-1,"%s/%s",
+ SECRETS_MACHINE_ACCT_PASS, dos_domain);
- pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
- strupper_m(keystr);
-
+ strupper(keystr);
return keystr;
}
@@ -250,252 +163,43 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
}
/************************************************************************
- Routine to get the default secure channel type for trust accounts
-************************************************************************/
-
-uint32 get_default_sec_channel(void)
-{
- if (lp_server_role() == ROLE_DOMAIN_BDC ||
- lp_server_role() == ROLE_DOMAIN_PDC) {
- return SEC_CHAN_BDC;
- } else {
- return SEC_CHAN_WKSTA;
- }
-}
-
-/************************************************************************
Routine to get the trust account password for a domain.
The user of this function must have locked the trust password file using
- secrets_lock_trust_account_password().
+ the above call.
************************************************************************/
BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
- time_t *pass_last_set_time,
- uint32 *channel)
+ time_t *pass_last_set_time)
{
struct machine_acct_pass *pass;
- char *plaintext;
size_t size;
- plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
- channel);
- if (plaintext) {
- DEBUG(4,("Using cleartext machine password\n"));
- E_md4hash(plaintext, ret_pwd);
- SAFE_FREE(plaintext);
- return True;
- }
-
- if (!(pass = secrets_fetch(trust_keystr(domain), &size))) {
- DEBUG(5, ("secrets_fetch failed!\n"));
- return False;
- }
-
- if (size != sizeof(*pass)) {
- DEBUG(0, ("secrets were of incorrect size!\n"));
+ if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
+ size != sizeof(*pass))
return False;
- }
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
memcpy(ret_pwd, pass->hash, 16);
SAFE_FREE(pass);
-
- if (channel)
- *channel = get_default_sec_channel();
-
return True;
}
/************************************************************************
- Routine to get account password to trusted domain
+ Routine to set the trust account password for a domain.
************************************************************************/
-BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
- DOM_SID *sid, time_t *pass_last_set_time)
+BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
{
- struct trusted_dom_pass pass;
- size_t size;
-
- /* unpacking structures */
- char* pass_buf;
- int pass_len = 0;
-
- ZERO_STRUCT(pass);
-
- /* fetching trusted domain password structure */
- if (!(pass_buf = secrets_fetch(trustdom_keystr(domain), &size))) {
- DEBUG(5, ("secrets_fetch failed!\n"));
- return False;
- }
-
- /* unpack trusted domain password */
- pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
- SAFE_FREE(pass_buf);
-
- if (pass_len != size) {
- DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
- return False;
- }
-
- /* the trust's password */
- if (pwd) {
- *pwd = strdup(pass.pass);
- if (!*pwd) {
- return False;
- }
- }
+ struct machine_acct_pass pass;
- /* last change time */
- if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
-
- /* domain sid */
- sid_copy(sid, &pass.domain_sid);
-
- return True;
-}
-
-
-/**
- * Routine to store the password for trusted domain
- *
- * @param domain remote domain name
- * @param pwd plain text password of trust relationship
- * @param sid remote domain sid
- *
- * @return true if succeeded
- **/
-
-BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_dom_name,
- size_t uni_name_len, const char* pwd,
- DOM_SID sid)
-{
- /* packing structures */
- pstring pass_buf;
- int pass_len = 0;
- int pass_buf_len = sizeof(pass_buf);
-
- struct trusted_dom_pass pass;
- ZERO_STRUCT(pass);
-
- /* unicode domain name and its length */
- if (!uni_dom_name)
- return False;
-
- strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
- pass.uni_name_len = uni_name_len;
-
- /* last change time */
pass.mod_time = time(NULL);
+ memcpy(pass.hash, new_pwd, 16);
- /* password of the trust */
- pass.pass_len = strlen(pwd);
- fstrcpy(pass.pass, pwd);
-
- /* domain sid */
- sid_copy(&pass.domain_sid, &sid);
-
- pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
-
- return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
+ return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
}
/************************************************************************
- Routine to set the plaintext machine account password for a realm
-the password is assumed to be a null terminated ascii string
-************************************************************************/
-
-BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
-{
- char *key = NULL;
- BOOL ret;
- uint32 last_change_time;
- uint32 sec_channel_type;
-
- asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
- if (!key)
- return False;
- strupper_m(key);
-
- ret = secrets_store(key, pass, strlen(pass)+1);
- SAFE_FREE(key);
-
- if (!ret)
- return ret;
-
- asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
- if (!key)
- return False;
- strupper_m(key);
-
- SIVAL(&last_change_time, 0, time(NULL));
- ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
- SAFE_FREE(key);
-
- asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
- if (!key)
- return False;
- strupper_m(key);
-
- SIVAL(&sec_channel_type, 0, sec_channel);
- ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
- SAFE_FREE(key);
-
- return ret;
-}
-
-
-/************************************************************************
- Routine to fetch the plaintext machine account password for a realm
-the password is assumed to be a null terminated ascii string
-************************************************************************/
-char *secrets_fetch_machine_password(const char *domain,
- time_t *pass_last_set_time,
- uint32 *channel)
-{
- char *key = NULL;
- char *ret;
- asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
- strupper_m(key);
- ret = (char *)secrets_fetch(key, NULL);
- SAFE_FREE(key);
-
- if (pass_last_set_time) {
- size_t size;
- uint32 *last_set_time;
- asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
- strupper_m(key);
- last_set_time = secrets_fetch(key, &size);
- if (last_set_time) {
- *pass_last_set_time = IVAL(last_set_time,0);
- SAFE_FREE(last_set_time);
- } else {
- *pass_last_set_time = 0;
- }
- SAFE_FREE(key);
- }
-
- if (channel) {
- size_t size;
- uint32 *channel_type;
- asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
- strupper_m(key);
- channel_type = secrets_fetch(key, &size);
- if (channel_type) {
- *channel = IVAL(channel_type,0);
- SAFE_FREE(channel_type);
- } else {
- *channel = get_default_sec_channel();
- }
- SAFE_FREE(key);
- }
-
- return ret;
-}
-
-
-
-/************************************************************************
- Routine to delete the machine trust account password file for a domain.
+ Routine to delete the trust account password file for a domain.
************************************************************************/
BOOL trust_password_delete(const char *domain)
@@ -503,16 +207,6 @@ BOOL trust_password_delete(const char *domain)
return secrets_delete(trust_keystr(domain));
}
-/************************************************************************
- Routine to delete the password for trusted domain
-************************************************************************/
-
-BOOL trusted_domain_password_delete(const char *domain)
-{
- return secrets_delete(trustdom_keystr(domain));
-}
-
-
/*******************************************************************
Reset the 'done' variables so after a client process is created
from a fork call these calls will be re-done. This should be
@@ -523,15 +217,13 @@ void reset_globals_after_fork(void)
{
unsigned char dummy;
- secrets_init();
-
/*
* Increment the global seed value to ensure every smbd starts
* with a new random seed.
*/
if (tdb) {
- uint32 initial_val = sys_getpid();
+ int32 initial_val = sys_getpid();
tdb_change_int32_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1);
set_rand_reseed_data((unsigned char *)&initial_val, sizeof(initial_val));
}
@@ -544,166 +236,54 @@ void reset_globals_after_fork(void)
generate_random_buffer( &dummy, 1, True);
}
-BOOL secrets_store_ldap_pw(const char* dn, char* pw)
+BOOL secrets_store_ldap_pw(const char* dn, const char* pw)
{
- char *key = NULL;
- BOOL ret;
+ fstring key;
+ char *p;
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
- DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
- return False;
- }
-
- ret = secrets_store(key, pw, strlen(pw)+1);
+ pstrcpy(key, dn);
+ for (p=key; *p; p++)
+ if (*p == ',') *p = '/';
- SAFE_FREE(key);
- return ret;
+ return secrets_store(key, pw, strlen(pw));
}
-
-/**
- * Get trusted domains info from secrets.tdb.
- *
- * The linked list is allocated on the supplied talloc context, caller gets to destroy
- * when done.
- *
- * @param ctx Allocation context
- * @param enum_ctx Starting index, eg. we can start fetching at third
- * or sixth trusted domain entry. Zero is the first index.
- * Value it is set to is the enum context for the next enumeration.
- * @param num_domains Number of domain entries to fetch at one call
- * @param domains Pointer to array of trusted domain structs to be filled up
- *
- * @return nt status code of rpc response
- **/
-
-NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains,
- int *num_domains, TRUSTDOM ***domains)
+BOOL fetch_ldap_pw(const char *dn, char* pw, int len)
{
- TDB_LIST_NODE *keys, *k;
- TRUSTDOM *dom = NULL;
- char *pattern;
- unsigned int start_idx;
- uint32 idx = 0;
- size_t size, packed_size = 0;
- fstring dom_name;
- char *packed_pass;
- struct trusted_dom_pass *pass = talloc_zero(ctx, sizeof(struct trusted_dom_pass));
- NTSTATUS status;
-
- if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
+ fstring key;
+ char *p;
+ void *data = NULL;
+ size_t size;
+
+ pstrcpy(key, dn);
+ for (p=key; *p; p++)
+ if (*p == ',') *p = '/';
- if (!pass) {
- DEBUG(0, ("talloc_zero failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ data=secrets_fetch(key, &size);
+ if (!size) {
+ DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
+ return False;
}
-
- *num_domains = 0;
- start_idx = *enum_ctx;
-
- /* generate searching pattern */
- if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) {
- DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
- return NT_STATUS_NO_MEMORY;
+
+ if (size > len-1)
+ {
+ DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
+ return False;
}
- DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n",
- max_num_domains, *enum_ctx));
-
- *domains = talloc_zero(ctx, sizeof(**domains)*max_num_domains);
-
- /* fetching trusted domains' data and collecting them in a list */
- keys = tdb_search_keys(tdb, pattern);
-
- /*
- * if there's no keys returned ie. no trusted domain,
- * return "no more entries" code
- */
- status = NT_STATUS_NO_MORE_ENTRIES;
-
- /* searching for keys in secrets db -- way to go ... */
- for (k = keys; k; k = k->next) {
- char *secrets_key;
-
- /* important: ensure null-termination of the key string */
- secrets_key = strndup(k->node_key.dptr, k->node_key.dsize);
- if (!secrets_key) {
- DEBUG(0, ("strndup failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- packed_pass = secrets_fetch(secrets_key, &size);
- packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
- /* packed representation isn't needed anymore */
- SAFE_FREE(packed_pass);
-
- if (size != packed_size) {
- DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
- continue;
- }
-
- pull_ucs2_fstring(dom_name, pass->uni_name);
- DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
- idx, dom_name, sid_string_static(&pass->domain_sid)));
-
- SAFE_FREE(secrets_key);
-
- if (idx >= start_idx && idx < start_idx + max_num_domains) {
- dom = talloc_zero(ctx, sizeof(*dom));
- if (!dom) {
- /* free returned tdb record */
- return NT_STATUS_NO_MEMORY;
- }
-
- /* copy domain sid */
- SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid));
- memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
-
- /* copy unicode domain name */
- dom->name = talloc_strdup_w(ctx, pass->uni_name);
-
- (*domains)[idx - start_idx] = dom;
-
- DEBUG(18, ("Secret record is in required range.\n \
- start_idx = %d, max_num_domains = %d. Added to returned array.\n",
- start_idx, max_num_domains));
-
- *enum_ctx = idx + 1;
- (*num_domains)++;
-
- /* set proper status code to return */
- if (k->next) {
- /* there are yet some entries to enumerate */
- status = STATUS_MORE_ENTRIES;
- } else {
- /* this is the last entry in the whole enumeration */
- status = NT_STATUS_OK;
- }
- } else {
- DEBUG(18, ("Secret is outside the required range.\n \
- start_idx = %d, max_num_domains = %d. Not added to returned array\n",
- start_idx, max_num_domains));
- }
-
- idx++;
- }
+ memcpy(pw, data, size);
+ pw[size] = '\0';
- DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
-
- /* free the results of searching the keys */
- tdb_search_list_free(keys);
-
- return status;
+ return True;
}
-/*******************************************************************************
- Lock the secrets tdb based on a string - this is used as a primitive form of mutex
- between smbd instances.
-*******************************************************************************/
-
+/*
+ lock the secrets tdb based on a string - this is used as a primitive form of mutex
+ between smbd instances.
+*/
BOOL secrets_named_mutex(const char *name, unsigned int timeout)
{
- int ret = 0;
+ int ret;
if (!message_init())
return False;
@@ -715,132 +295,11 @@ BOOL secrets_named_mutex(const char *name, unsigned int timeout)
return (ret == 0);
}
-/*******************************************************************************
- Unlock a named mutex.
-*******************************************************************************/
-
+/*
+ unlock a named mutex
+*/
void secrets_named_mutex_release(const char *name)
{
tdb_unlock_bystring(tdb, name);
DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
}
-
-/*********************************************************
- Check to see if we must talk to the PDC to avoid sam
- sync delays
- ********************************************************/
-
-BOOL must_use_pdc( const char *domain )
-{
- time_t now = time(NULL);
- time_t last_change_time;
- unsigned char passwd[16];
-
- if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) )
- return False;
-
- /*
- * If the time the machine password has changed
- * was less than about 15 minutes then we need to contact
- * the PDC only, as we cannot be sure domain replication
- * has yet taken place. Bug found by Gerald (way to go
- * Gerald !). JRA.
- */
-
- if ( now - last_change_time < SAM_SYNC_WINDOW )
- return True;
-
- return False;
-
-}
-
-/*******************************************************************************
- Store a complete AFS keyfile into secrets.tdb.
-*******************************************************************************/
-
-BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
-{
- fstring key;
-
- if ((cell == NULL) || (keyfile == NULL))
- return False;
-
- if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
- return False;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
- return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
-}
-
-/*******************************************************************************
- Fetch the current (highest) AFS key from secrets.tdb
-*******************************************************************************/
-BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
-{
- fstring key;
- struct afs_keyfile *keyfile;
- size_t size;
- uint32 i;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
-
- keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
-
- if (keyfile == NULL)
- return False;
-
- if (size != sizeof(struct afs_keyfile)) {
- SAFE_FREE(keyfile);
- return False;
- }
-
- i = ntohl(keyfile->nkeys);
-
- if (i > SECRETS_AFS_MAXKEYS) {
- SAFE_FREE(keyfile);
- return False;
- }
-
- *result = keyfile->entry[i-1];
-
- result->kvno = ntohl(result->kvno);
-
- return True;
-}
-
-/******************************************************************************
- When kerberos is not available, choose between anonymous or
- authenticated connections.
-
- We need to use an authenticated connection if DCs have the
- RestrictAnonymous registry entry set > 0, or the "Additional
- restrictions for anonymous connections" set in the win2k Local
- Security Policy.
-
- Caller to free() result in domain, username, password
-*******************************************************************************/
-void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
-{
- *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
- *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
- *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
-
- if (*username && **username) {
-
- if (!*domain || !**domain)
- *domain = smb_xstrdup(lp_workgroup());
-
- if (!*password || !**password)
- *password = smb_xstrdup("");
-
- DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
- *domain, *username));
-
- } else {
- DEBUG(3, ("IPC$ connections done anonymously\n"));
- *username = smb_xstrdup("");
- *domain = smb_xstrdup("");
- *password = smb_xstrdup("");
- }
-}
-
diff --git a/source/passdb/smbpassfile.c b/source/passdb/smbpassfile.c
new file mode 100755
index 00000000000..d931478839d
--- /dev/null
+++ b/source/passdb/smbpassfile.c
@@ -0,0 +1,295 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * This file also contains migration code to move from an old
+ * trust account password file stored in the file :
+ * ${SAMBA_HOME}/private/{domain}.{netbiosname}.mac
+ * into a record stored in the tdb ${SAMBA_HOME}/private/secrets.tdb
+ * database. JRA.
+ */
+
+#include "includes.h"
+
+extern pstring global_myname;
+
+
+static int mach_passwd_lock_depth;
+static FILE *mach_passwd_fp;
+
+/***************************************************************
+ Lock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
+static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
+{
+ if (fd < 0)
+ return False;
+
+ if(*plock_depth == 0) {
+ if (!do_file_lock(fd, secs, type)) {
+ DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
+ strerror(errno)));
+ return False;
+ }
+ }
+
+ (*plock_depth)++;
+
+ return True;
+}
+
+/***************************************************************
+ Unlock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
+static BOOL pw_file_unlock(int fd, int *plock_depth)
+{
+ BOOL ret=True;
+
+ if(*plock_depth == 1)
+ ret = do_file_lock(fd, 5, F_UNLCK);
+
+ if (*plock_depth > 0)
+ (*plock_depth)--;
+
+ if(!ret)
+ DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
+ strerror(errno)));
+ return ret;
+}
+
+/************************************************************************
+ Routine to get the name for an old trust account file.
+************************************************************************/
+
+static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
+{
+ unsigned int mac_file_len;
+
+ /* strip the filename to the last '/' */
+ get_private_directory(mac_file);
+ pstrcat(mac_file, "/");
+
+ mac_file_len = strlen(mac_file);
+
+ if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0) {
+ DEBUG(0,("trust_password_lock: path %s too long to add trust details.\n",
+ mac_file));
+ return;
+ }
+
+ pstrcat(mac_file, domain);
+ pstrcat(mac_file, ".");
+ pstrcat(mac_file, name);
+ pstrcat(mac_file, ".mac");
+}
+
+/************************************************************************
+ Routine to lock the old trust account password file for a domain.
+ As this is a function to migrate to the new secrets.tdb, we never
+ create the file here, only open it.
+************************************************************************/
+
+static BOOL trust_password_file_lock(char *domain, char *name)
+{
+ pstring mac_file;
+
+ if(mach_passwd_lock_depth == 0) {
+ int fd;
+
+ get_trust_account_file_name( domain, name, mac_file);
+
+ if ((fd = sys_open(mac_file, O_RDWR, 0)) == -1)
+ return False;
+
+ if((mach_passwd_fp = fdopen(fd, "w+b")) == NULL) {
+ DEBUG(0,("trust_password_lock: cannot open file %s - Error was %s.\n",
+ mac_file, strerror(errno) ));
+ return False;
+ }
+
+ if(!pw_file_lock(fileno(mach_passwd_fp), F_WRLCK, 60, &mach_passwd_lock_depth)) {
+ DEBUG(0,("trust_password_lock: cannot lock file %s\n", mac_file));
+ fclose(mach_passwd_fp);
+ return False;
+ }
+
+ }
+
+ return True;
+}
+
+/************************************************************************
+ Routine to unlock the old trust account password file for a domain.
+************************************************************************/
+
+static BOOL trust_password_file_unlock(void)
+{
+ BOOL ret = pw_file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
+ if(mach_passwd_lock_depth == 0)
+ fclose(mach_passwd_fp);
+ return ret;
+}
+
+/************************************************************************
+ Routine to delete the old trust account password file for a domain.
+ Note that this file must be locked as it is truncated before the
+ delete. This is to ensure it only gets deleted by one smbd.
+************************************************************************/
+
+static BOOL trust_password_file_delete( char *domain, char *name )
+{
+ pstring mac_file;
+ int ret;
+
+ get_trust_account_file_name( domain, name, mac_file);
+ if(sys_ftruncate(fileno(mach_passwd_fp),(SMB_OFF_T)0) == -1) {
+ DEBUG(0,("trust_password_file_delete: Failed to truncate file %s (%s)\n",
+ mac_file, strerror(errno) ));
+ }
+ ret = unlink( mac_file );
+ return (ret != -1);
+}
+
+/************************************************************************
+ Routine to get the old trust account password for a domain - to convert
+ to the new secrets.tdb entry.
+ The user of this function must have locked the trust password file.
+************************************************************************/
+
+static BOOL get_trust_account_password_from_file( unsigned char *ret_pwd, time_t *pass_last_set_time)
+{
+ char linebuf[256];
+ char *p;
+ int i;
+ SMB_STRUCT_STAT st;
+ linebuf[0] = '\0';
+
+ *pass_last_set_time = (time_t)0;
+ memset(ret_pwd, '\0', 16);
+
+ if(sys_fstat(fileno(mach_passwd_fp), &st) == -1) {
+ DEBUG(0,("get_trust_account_password: Failed to stat file. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * If size is zero, another smbd has migrated this file
+ * to the secrets.tdb file, and we are in a race condition.
+ * Just ignore the file.
+ */
+
+ if (st.st_size == 0)
+ return False;
+
+ if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
+ DEBUG(0,("get_trust_account_password: Failed to seek to start of file. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ fgets(linebuf, sizeof(linebuf), mach_passwd_fp);
+ if(ferror(mach_passwd_fp)) {
+ DEBUG(0,("get_trust_account_password: Failed to read password. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ if(linebuf[strlen(linebuf)-1] == '\n')
+ linebuf[strlen(linebuf)-1] = '\0';
+
+ /*
+ * The length of the line read
+ * must be 45 bytes ( <---XXXX 32 bytes-->:TLC-12345678
+ */
+
+ if(strlen(linebuf) != 45) {
+ DEBUG(0,("get_trust_account_password: Malformed trust password file (wrong length \
+- was %d, should be 45).\n", (int)strlen(linebuf)));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+
+ /*
+ * Get the hex password.
+ */
+
+ if (!pdb_gethexpwd((char *)linebuf, ret_pwd) || linebuf[32] != ':' ||
+ strncmp(&linebuf[33], "TLC-", 4)) {
+ DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+
+ /*
+ * Get the last changed time.
+ */
+ p = &linebuf[37];
+
+ for(i = 0; i < 8; i++) {
+ if(p[i] == '\0' || !isxdigit((int)p[i])) {
+ DEBUG(0,("get_trust_account_password: Malformed trust password file (no timestamp).\n"));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+ }
+
+ /*
+ * p points at 8 characters of hex digits -
+ * read into a time_t as the seconds since
+ * 1970 that the password was last changed.
+ */
+
+ *pass_last_set_time = (time_t)strtol(p, NULL, 16);
+
+ return True;
+}
+
+/************************************************************************
+ Migrate an old DOMAIN.MACINE.mac password file to the tdb secrets db.
+************************************************************************/
+
+BOOL migrate_from_old_password_file(char *domain)
+{
+ struct machine_acct_pass pass;
+
+ if (!trust_password_file_lock(domain, global_myname))
+ return True;
+
+ if (!get_trust_account_password_from_file( pass.hash, &pass.mod_time)) {
+ trust_password_file_unlock();
+ return False;
+ }
+
+ if (!secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass)))
+ return False;
+
+ trust_password_file_delete(domain, global_myname);
+ trust_password_file_unlock();
+
+ return True;
+}
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
deleted file mode 100644
index bb3a0ea98cb..00000000000
--- a/source/passdb/util_sam_sid.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
- Copyright (C) Jeremy Allison 1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define MAX_SID_NAMES 7
-
-typedef struct _known_sid_users {
- uint32 rid;
- enum SID_NAME_USE sid_name_use;
- const char *known_user_name;
-} known_sid_users;
-
-static struct sid_name_map_info
-{
- DOM_SID *sid;
- const char *name;
- const known_sid_users *known_users;
-} sid_name_map[MAX_SID_NAMES];
-
-extern DOM_SID global_sid_Builtin; /* Local well-known domain */
-extern DOM_SID global_sid_World_Domain; /* Everyone domain */
-extern DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
-extern DOM_SID global_sid_NT_Authority; /* NT Authority */
-
-
-static BOOL sid_name_map_initialized = False;
-/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
-
-static const known_sid_users everyone_users[] = {
- { 0, SID_NAME_WKN_GRP, "Everyone" },
- {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users creator_owner_users[] = {
- { 0, SID_NAME_WKN_GRP, "Creator Owner" },
- { 1, SID_NAME_WKN_GRP, "Creator Group" },
- {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users nt_authority_users[] = {
- { 1, SID_NAME_ALIAS, "Dialup" },
- { 2, SID_NAME_ALIAS, "Network"},
- { 3, SID_NAME_ALIAS, "Batch"},
- { 4, SID_NAME_ALIAS, "Interactive"},
- { 6, SID_NAME_ALIAS, "Service"},
- { 7, SID_NAME_ALIAS, "AnonymousLogon"},
- { 8, SID_NAME_ALIAS, "Proxy"},
- { 9, SID_NAME_ALIAS, "ServerLogon"},
- { 11, SID_NAME_ALIAS, "Authenticated Users"},
- { 18, SID_NAME_ALIAS, "SYSTEM"},
- { 0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users builtin_groups[] = {
- { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
- { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
- { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
- { BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" },
- { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
- { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
- { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
- { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
- { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
- { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
- { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
- { 0, (enum SID_NAME_USE)0, NULL}};
-
-/**************************************************************************
- Quick init function.
-*************************************************************************/
-
-static void init_sid_name_map (void)
-{
- int i = 0;
-
- if (sid_name_map_initialized) return;
-
- generate_wellknown_sids();
-
- if ((lp_security() == SEC_USER) && lp_domain_logons()) {
- sid_name_map[i].sid = get_global_sam_sid();
- /* This is not lp_workgroup() for good reason:
- it must stay around longer than the lp_*()
- strings do */
- sid_name_map[i].name = strdup(lp_workgroup());
- sid_name_map[i].known_users = NULL;
- i++;
- sid_name_map[i].sid = get_global_sam_sid();
- sid_name_map[i].name = strdup(global_myname());
- sid_name_map[i].known_users = NULL;
- i++;
- } else {
- sid_name_map[i].sid = get_global_sam_sid();
- sid_name_map[i].name = strdup(global_myname());
- sid_name_map[i].known_users = NULL;
- i++;
- }
-
- sid_name_map[i].sid = &global_sid_Builtin;
- sid_name_map[i].name = "BUILTIN";
- sid_name_map[i].known_users = &builtin_groups[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_World_Domain;
- sid_name_map[i].name = "";
- sid_name_map[i].known_users = &everyone_users[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_Creator_Owner_Domain;
- sid_name_map[i].name = "";
- sid_name_map[i].known_users = &creator_owner_users[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_NT_Authority;
- sid_name_map[i].name = "NT Authority";
- sid_name_map[i].known_users = &nt_authority_users[0];
- i++;
-
- /* End of array. */
- sid_name_map[i].sid = NULL;
- sid_name_map[i].name = NULL;
- sid_name_map[i].known_users = NULL;
-
- sid_name_map_initialized = True;
-
- return;
-}
-
-/**************************************************************************
- Turns a domain SID into a name, returned in the nt_domain argument.
-***************************************************************************/
-
-BOOL map_domain_sid_to_name(DOM_SID *sid, fstring nt_domain)
-{
- fstring sid_str;
- int i = 0;
-
- sid_to_string(sid_str, sid);
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
- DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
-
- if (nt_domain == NULL)
- return False;
-
- while (sid_name_map[i].sid != NULL) {
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str));
- if (sid_equal(sid_name_map[i].sid, sid)) {
- fstrcpy(nt_domain, sid_name_map[i].name);
- DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain));
- return True;
- }
- i++;
- }
-
- DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str));
-
- return False;
-}
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
-{
- int i = 0;
- struct sid_name_map_info *psnm;
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
- for(i = 0; sid_name_map[i].sid != NULL; i++) {
- psnm = &sid_name_map[i];
- if(sid_equal(psnm->sid, sid)) {
- int j;
- for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) {
- if(rid == psnm->known_users[j].rid) {
- DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n",
- (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name ));
- fstrcpy( name, psnm->known_users[j].known_user_name);
- *psid_name_use = psnm->known_users[j].sid_name_use;
- return True;
- }
- }
- }
- }
-
- return False;
-}
-
-/**************************************************************************
- Turns a domain name into a SID.
- *** side-effect: if the domain name is NULL, it is set to our domain ***
-***************************************************************************/
-
-BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain)
-{
- int i = 0;
-
- if (nt_domain == NULL) {
- DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n"));
- sid_copy(sid, get_global_sam_sid());
- return True;
- }
-
- if (nt_domain[0] == 0) {
- fstrcpy(nt_domain, global_myname());
- DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain));
- sid_copy(sid, get_global_sam_sid());
- return True;
- }
-
- DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain));
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
- while (sid_name_map[i].name != NULL) {
- DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name));
- if (strequal(sid_name_map[i].name, nt_domain)) {
- fstring sid_str;
- sid_copy(sid, sid_name_map[i].sid);
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str));
- return True;
- }
- i++;
- }
-
- DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain));
- return False;
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_domain(const DOM_SID *sid)
-{
- return sid_equal(sid, get_global_sam_sid());
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
-{
- DOM_SID dom_sid;
- uint32 rid;
-
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &rid);
-
- return sid_equal(&dom_sid, get_global_sam_sid());
-}
-
-/**************************************************************************
- Try and map a name to one of the well known SIDs.
-***************************************************************************/
-
-BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
-{
- int i, j;
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
- for (i=0; sid_name_map[i].sid != NULL; i++) {
- const known_sid_users *users = sid_name_map[i].known_users;
-
- if (users == NULL)
- continue;
-
- for (j=0; users[j].known_user_name != NULL; j++) {
- if ( strequal(users[j].known_user_name, name) ) {
- sid_copy(sid, sid_name_map[i].sid);
- sid_append_rid(sid, users[j].rid);
- *use = users[j].sid_name_use;
- return True;
- }
- }
- }
-
- return False;
-}
-
-void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
-{
- DOM_SID *list;
-
- list = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID));
-
- if (list == NULL) {
- DEBUG(0, ("Realloc failed in add_sid_to_array!!\n"));
- free(*sids);
- *sids = NULL;
- return;
- }
-
- *sids = list;
-
- sid_copy(&((*sids)[*num]), sid);
- *num += 1;
-
- return;
-}
-
-void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num)
-{
- int i;
-
- for (i=0; i<*num; i++) {
- if (sid_compare(sid, &(*sids)[i]) == 0)
- return;
- }
-
- add_sid_to_array(sid, sids, num);
-}
diff --git a/source/po/de.msg b/source/po/de.msg
deleted file mode 100644
index b1b84a21b67..00000000000
--- a/source/po/de.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# German messages for international release of SWAT.
-# Copyright (C) 2001 Andreas Moroder
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat\n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2000-02-08 14:45+0100\n"
-"Last-Translator: Andreas Moroder\n"
-"Language-Team: (Samba Team) <samba-technical@samba.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr "ERRORE: Kann %s nicht öffnen"
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Hilfe"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Setze Standardwerte"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "Verbunden als <b>%s</b>"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Home"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Globals"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Freigaben"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Drucker"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Status"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Zeige Konfiguration"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Passwortverwaltung"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Aktuelle Konfiguration"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Basis Ansicht"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Erweiterte Ansicht"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Ändere Passwort"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Aktuelle Konfiguration"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Normale Ansich"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Komplette Ansicht"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "Kommentar"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Drucker Parameter"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr ""
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "Domänen master"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "Domänen master"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "nicht hinabsteigen"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Globale Variablen"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Speichere Änderungen"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Setze Werte zurück"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Parameter der Freigabe"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Wähle Freigabe"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Lösche Freigabe"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Erstelle Freigabe"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "Änderung des Passworts im Demo modus nicht aktiv"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " \"Benutzername\" muss angegeben werden "
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " \"Altes Passwort\" muß angegeben werden "
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " \"Remote Maschine\" muß angegeben werden "
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Neues/Bestätige Passwort\" muß angegeben werden "
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " Das bestätigte Passwort stimmt nicht mit dem neuen Passwort überein"
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " Das Passwort für '%s' wurde geändert."
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " Das Passwort für '%s' wurde nicht geändert."
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Verwaltung des Server Passwortes"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr "Benutzername"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr "Altes Passwort"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr "Neues Passwort"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr "Bestätige neues Passwort"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Ändere Passwort"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Füge Benutzer hinzu"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Lösche Benutzer"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Desaktiviere Benutzer"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Aktiviere Benutzer"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Client/Server Passwort Verwaltung"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr "Remote Maschine"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Drucker Parameter"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Wichtige Hinweise:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Mit [*] gekennzeichnete Druckername in der Druckerauswahlliste"
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "wurde automatisch geladen von :"
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Printcap Name"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Der Versuch diese Drucker von SWAT aus zu löschen wird keine Auswirkung haben."
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Wähle Drucker"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Lösche Drucker"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Ersteller Drucker"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr ""
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr ""
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr ""
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Server Status"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Automatische Aktualisierung"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Aktualisierungsintervall: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Stop Aktualisierung"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "Version:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "aktiv"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "inaktiv"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Stopp smbd"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Start smbd"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Neustart smbd"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Stopp nmbd"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Start nmbd"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Neustart nmbd"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Stopp winbindd"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Start winbindd"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Neustart winbindd"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Neustart Alle"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Start Alle"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Aktive Verbindungen"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr ""
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "IP Adresse"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Datum"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Kill"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Aktive Freigaben"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Freigabe"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "Benutzer"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Gruppe"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Offene Dateien"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr ""
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Basisoptionen"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Sicherheitsoptionen"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Log Optionen"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Protokoll Optionen"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Optimierungsoptionen"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Druckoptionen"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Verwaltung Dateinamen"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Domänen Optionen"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Login optionen"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Browsing Optionen"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "WINS Optionen"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Locking Optionen"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "LDAP Optionen"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Verschiedene Optionen"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "VFS Optionen"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Winbind Optionen"
diff --git a/source/po/en.msg b/source/po/en.msg
deleted file mode 100644
index 6a1fcb55bac..00000000000
--- a/source/po/en.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# English messages for international release of SWAT.
-# Copyright (C) 2003 TAKAHASHI Motonobu <monyo@samba.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2000-02-08 12:48+09:00\n"
-"Last-Translator: TAKAHASHI Motonobu <monyo@samba.org>\n"
-"Language-Team: (Samba Team) <samba-technical@samba.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=US-ASCII\n"
-"Content-Transfer-Encoding: \n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr ""
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr ""
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr ""
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr ""
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr ""
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr ""
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr ""
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr ""
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr ""
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr ""
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr ""
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr ""
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr ""
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr ""
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr ""
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr ""
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr ""
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr ""
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr ""
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr ""
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr ""
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr ""
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr ""
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr ""
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr ""
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr ""
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr ""
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr ""
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr ""
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr ""
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr ""
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr ""
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr ""
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr ""
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr ""
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr ""
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr ""
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr ""
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr ""
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr ""
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr ""
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr ""
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr ""
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr ""
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr ""
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr ""
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr ""
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr ""
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr ""
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr ""
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr ""
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr ""
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr ""
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr ""
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr ""
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr ""
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr ""
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr ""
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr ""
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr ""
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr ""
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr ""
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr ""
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr ""
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr ""
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr ""
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr ""
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr ""
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr ""
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr ""
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr ""
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr ""
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr ""
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr ""
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr ""
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr ""
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr ""
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr ""
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr ""
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr ""
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr ""
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr ""
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr ""
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr ""
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr ""
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr ""
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr ""
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr ""
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr ""
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr ""
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr ""
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr ""
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr ""
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr ""
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr ""
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr ""
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr ""
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr ""
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr ""
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr ""
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr ""
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr ""
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr ""
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr ""
diff --git a/source/po/fr.msg b/source/po/fr.msg
deleted file mode 100644
index 134f1d6390b..00000000000
--- a/source/po/fr.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# French messages for international release of SWAT.
-# Copyright (C) 2001 François Le Lay <fanch@tuxfamily.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2000-02-08 14:45+0100\n"
-"Last-Translator: François Le Lay <fanch@tuxfamily.org>\n"
-"Language-Team: (Samba Team) <samba-technical@samba.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
-"Content-Transfer-Encoding: \n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr ""
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Aide"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Définir par défaut"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "Connecté en tant que <b>%s</b>"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Home"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Paramètres Généraux"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Partages"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Imprimantes"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Statut"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Voir Configuration"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Gestion des mots de passe"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Configuration Actuelle"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Vue Basique"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Vue Détaillée"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Modifier le mot de passe"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Configuration Actuelle"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Vue Normale"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Vue Complète"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "commentaire"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Paramètres Imprimantes"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr ""
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "master de domaine"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "master de domaine"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "ne pas descendre"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Variables Globales"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Sauver les modifications"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Réinitialiser Valeurs"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Paramètres de partage"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Choisir un partage"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Supprimer un partage"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Créer un partage"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "changement de mot de passe en mode démo rejeté"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " Le champ \"Nom d'utilisateur\" doit être spécifié"
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " Le champ \"Ancien mot de passe\" doît être spécifié"
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " Le champ \"Machine Distante\" doît être spécifié"
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr "Les champs \"Nouveau mot de passe\" et \"Confirmation du nouveau mot de passe\" doivent être spécifiés \n"
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " Echec de la confirmation du nouveau mot de passe"
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " Le mot de passe de '%s' a été modifié. "
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " Le mot de passe de '%s' n'a PAS été modifié. \n"
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Gestion des mots de passe serveur"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr " Nom d'utilisateur : "
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr " Ancien mot de passe : "
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr " Nouveau mot de passe : "
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr " Confirmation du nouveau mot de passe : "
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Modifier le mot de passe"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Nouvel Utilisateur"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Supprimer Utilisateur"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Désactiver Utilisateur"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Activer Utilisateur"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Gestion des mots de passe Client/Serveur"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr " Machine distante : "
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Paramètres Imprimantes"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Note Importante:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Les Noms d'imprimantes marqués du signe [*] dans le menu déroulant Choisir Imprimante"
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "désignent des imprimantes automatiquement chargées depuis le "
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Nom Printcap"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Essayer de supprimer ces imprimantes depuis SWAT n'aura aucun effet."
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Choisir Imprimante"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Supprimer Imprimante"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Créer Imprimante"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr ""
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr ""
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr ""
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Statut du Serveur"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Rafraîchissement Automatique"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Intervalle de rafraîchissement: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Stopper Rafraîchissement"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "version:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "actif"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "non actif"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Stopper smbd"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Lancer smbd"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Relancer smbd"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Stopper nmbd"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Lancer nmbd"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Relancer nmbd"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Stopper nmbd"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Lancer nmbd"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Relancer nmbd"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Relancer nmbd"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Lancer nmbd"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Connections Actives"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr ""
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "adresse IP"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Date"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Terminer"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Partages Actifs"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Partager"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "Utilisateur"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Groupe"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Fichiers Ouverts"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr "Fichier"
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Options de base"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Options de Sécurité"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Options de Logging"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Options de Protocole"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Options de réglage"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Options d'impression"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Gestion des noms de fichier"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Options de Domaine"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Options de Logon"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Options de Navigation"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "Options WINS"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Options de Verrouillage"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "Options Ldap"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Options Diverses"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "Options VFS"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Options Winbind"
diff --git a/source/po/it.msg b/source/po/it.msg
deleted file mode 100644
index be447a84d47..00000000000
--- a/source/po/it.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# Italian messages for international release of SWAT.
-# Copyright (C) 2001 Simo Sorce <idra@samba.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2000-02-08 14:45+0100\n"
-"Last-Translator: Simo Sorce <idra@samba.org>\n"
-"Language-Team: (Samba Team) <samba-technical@samba.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-1\n"
-"Content-Transfer-Encoding: \n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr ""
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Aiuto"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Imposta Default"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "Connesso come <b>%s</b><p>\n"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Home"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Globali"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Condivisioni"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Stampanti"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Stato"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Visualizza Configurazione"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Gestione Password"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Configurazione Attuale"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Vista Semplice"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Vista Avanzata"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Cambia Password"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Configurazione Attuale"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Vista Normale"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Vista Completa"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "commento"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Parametri Stampante"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr ""
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "master dominio"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "master dominio"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "non discendere"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Variabili Globali"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Salva Modifiche"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Resetta Valori"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Parametri Condivisioni"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Scegli Condivisione"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Cancella Condivisione"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Crea Condivisione"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "cambio password in modalita' demo rigettata"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " \"Nome Utente\" deve essere specificato "
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " \"Vecchia Password\" deve essere specificato "
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " \"Macchina Remota\" deve essere specificato "
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Nuova/Conferma Password\" devono essere specificati "
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " la password di conferma non e' uguale alla nuova password "
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " La password per '%s' e' stata cambiata."
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " La password per '%s' non e' stata cambianta."
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Gestione Password del Server"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr " Nome Utente"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr " Vecchia Password"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr " Nuova Password"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr " Conferma nuova Password"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Cambia Password"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Aggiungi Nuovo Utente"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Cancella Utente"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Disabilita Utente"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Abilita Utente"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Gestione Password Client/Server"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr " Macchina Remota"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Parametri Stampante"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Nota Importante:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "nomi di stampante marcati con [*] nel riquadro a scomparsa Scegli Stampante"
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "sono stampanti caricate automaticamente da "
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Nome Printcap"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Il tentativo di cancellare queste stampanti da sWAT non avara' effetto.\n"
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Scegli Stampante"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Cancella Stampante"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Crea Stampante"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr ""
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr ""
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr ""
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Stato del Server"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Rinfresco Automatico"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Intervallo Rinfresco: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Ferma Rinfresco"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "versione:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "attivo"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "non attivo"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Ferma smbd"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Lancia smbd"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Rilancia smbd"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Ferma nmbd"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Lancia nmbd"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Rilancia nmbd"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Ferma nmbd"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Lancia nmbd"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Rilancia nmbd"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Rilancia nmbd"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Lancia nmbd"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Connessioni Attive"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr ""
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "indirizzo IP"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Data"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Termina"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Condivisioni Attive"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Condivisione"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "Utente"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Gruppo"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "File Aperti"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr ""
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Opzioni Basilari"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Opzioni di Sicurezza"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Opzioni di Log"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Opzioni Protocollo"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Opzioni Tuning"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Opzioni di Stampa"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Gestione Nomi File"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Opzioni Dominio"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Opzioni di Logon"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Opzioni Browsing"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "opzioni WINS"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Opzioni Locking"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "Opzioni Ldap"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Opzioni Generiche"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "Opzioni VFS"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Opzioni Winbind"
diff --git a/source/po/ja.msg b/source/po/ja.msg
deleted file mode 100644
index affb2764141..00000000000
--- a/source/po/ja.msg
+++ /dev/null
@@ -1,595 +0,0 @@
-# Japanese messages for international release of SWAT.
-# Copyright (C) 2003 TAKAHASHI Motonobu <monyo@samba.org>
-# Copyright (C) 2000 Ryo Kawahara <rkawa@lbe.co.jp>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n-swat\n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2003-09-23 04:38+900\n"
-"Last-Translator: TAKAHASHI Motonobu <monyo@samba.org>\n"
-"Language-Team: Samba Users Group Japan <sugj-tech@samba.gr.jp>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CP932\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr "%s ‚ðƒI[ƒvƒ“‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "ƒwƒ‹ƒv"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "ƒfƒtƒHƒ‹ƒg’l"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr "%s ‚ð‘‚«ž‚Ý—p‚ɃI[ƒvƒ“‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr "%s ‚ðÄ“Ç‚Ýž‚Ý‚Å‚«‚Ü‚¹‚ñ\n"
-
-# msgid "Logged in as <b>%s</b><p>\n"
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "<b>%s</b>‚Æ‚µ‚ăƒOƒCƒ“"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "ƒz[ƒ€"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "ƒOƒ[ƒoƒ‹"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "ƒtƒ@ƒCƒ‹‹¤—L"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "ˆóü‹¤—L"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr "ƒEƒBƒU[ƒh"
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "ƒT[ƒo‚Ìó‘Ô"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Œ»Ý‚ÌÝ’è"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "ƒpƒXƒ[ƒhŠÇ—"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Œ»Ý‚Ì•\Ž¦ƒ‚[ƒh"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "•W€•\Ž¦"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Úו\Ž¦"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "•\Ž¦ƒ‚[ƒh‚Ì•ÏX"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Œ»Ý‚ÌÝ’è"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "•W€•\Ž¦"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Š®‘S•\Ž¦"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr "ƒEƒBƒU[ƒh‚É‚æ‚éƒpƒ‰ƒ[ƒ^•ÒWƒy[ƒW"
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr "smb.conf ƒtƒ@ƒCƒ‹‚ª‘‚«Š·‚¦‚ç‚ê‚Ü‚µ‚½B"
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr "Samba Ý’èƒEƒBƒU[ƒh"
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr "usmb.conf ‚Ì‘Š·vƒ{ƒ^ƒ“‚ð‰Ÿ‚·‚Æ smb.conf ƒtƒ@ƒCƒ‹’†‚Ì‚·‚ׂẴfƒtƒHƒ‹ƒg’l‚âƒRƒƒ“ƒg‚Í휂³‚ê‚Ü‚·B"
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr "ucommitvƒ{ƒ^ƒ“‚ð‰Ÿ‚µ‚½ê‡‚É‚à“¯—l‚Ì•ÏX‚ªs‚È‚í‚ê‚Ü‚·B"
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr "smb.conf ‚Ì‘Š·"
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "Ý’è‚𔽉f"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Šeƒpƒ‰ƒ[ƒ^‚Ì•ÒW"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr "ƒT[ƒoƒ^ƒCƒv"
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr "ƒXƒ^ƒ“ƒhƒAƒƒ“"
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "ƒhƒƒCƒ“ƒƒ“ƒo"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "ƒhƒƒCƒ“ƒRƒ“ƒgƒ[ƒ‰"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr "’Êí‚ÌŒ`Ž®‚Å‚Í‚È‚¢ - V‚µ‚¢ƒ‚[ƒh‚ð‘I‘ð‚Ì‚±‚Æ"
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr "WINS"
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "Žg‚í‚È‚¢"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr "ƒT[ƒo‚Æ‚µ‚Ä\¬"
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr "•Ê‚Ì WINS ƒT[ƒo‚̃Nƒ‰ƒCƒAƒ“ƒg‚Æ‚µ‚Ä\¬"
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr "•Ê‚Ì WINS ƒT[ƒo"
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr "ƒGƒ‰[: wins server ‚Æ wins support ‚Ì—¼ƒpƒ‰ƒ[ƒ^‚ª smb.conf ‚ÅŽw’肳‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr "‚¢‚¸‚ê‚©‚Ì WINS ƒ‚[ƒh‚ð‘I‘ð‚µ‚Ä‚­‚¾‚³‚¢B"
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr "ƒz[ƒ€ƒfƒBƒŒƒNƒgƒŠ‚ÌŒöŠJ"
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr "ã‹L‚ÌÝ’èƒIƒvƒVƒ‡ƒ“‚É‚æ‚èA•¡”‚̃pƒ‰ƒ[ƒ^‚ª“¯Šú‚µ‚Äݒ肳‚ê‚邽‚ßA Samba ‚̉^—p‚ðv‘¬‚ÉŠJŽn‚·‚éã‚Å‚Ì•‚¯‚Æ‚È‚é‚Å‚µ‚傤B"
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Global ƒpƒ‰ƒ[ƒ^"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "•ÏX‚𔽉f"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "•ÏX‚ðŽæÁ"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "ƒtƒ@ƒCƒ‹‹¤—L ƒpƒ‰ƒ[ƒ^"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "ƒtƒ@ƒCƒ‹‹¤—L‚Ì‘I‘ð"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "ƒtƒ@ƒCƒ‹‹¤—L‚Ìíœ"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "ƒtƒ@ƒCƒ‹‹¤—L‚Ìì¬"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "ƒfƒ‚Eƒ‚[ƒh‚ł̃pƒXƒ[ƒh•ÏX‚Í‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr "ƒpƒXƒ[ƒhEƒf[ƒ^ƒx[ƒX‚ªŒ©‚‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr "uƒ†[ƒU–¼v—“‚É“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr "u‹ŒƒpƒXƒ[ƒhv—“‚É“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr "uƒŠƒ‚[ƒgƒ}ƒVƒ“v—“‚É“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr "uVƒpƒXƒ[ƒhv—“‚ÆuVƒpƒXƒ[ƒh‚ÌÄ“ü—Ív—“‚É“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr "uVƒpƒXƒ[ƒh‚ÌÄ“ü—Ív—“‚Ì“ü—Í“à—e‚ªuVƒpƒXƒ[ƒhv—“‚Ì“ü—͂ƈê’v‚µ‚Ä‚¢‚Ü‚¹‚ñB"
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " %s ‚̃pƒXƒ[ƒh‚Í•ÏX‚³‚ê‚Ü‚µ‚½B"
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " '%s' ‚̃pƒXƒ[ƒh‚Í•ÏX‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½B"
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "ƒ[ƒJƒ‹ƒ}ƒVƒ“‚̃pƒXƒ[ƒhŠÇ—"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr "ƒ†[ƒU–¼"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr "‹ŒƒpƒXƒ[ƒh"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr "VƒpƒXƒ[ƒh"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr "VƒpƒXƒ[ƒh‚ÌÄ“ü—Í"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "ƒpƒXƒ[ƒh•ÏX"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "V‹Kƒ†[ƒU’ljÁ"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "ƒ†[ƒU‚Ìíœ"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "ƒ†[ƒU‚Ì–³Œø‰»"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "ƒ†[ƒU‚Ì—LŒø‰»"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "ƒŠƒ‚[ƒgƒ}ƒVƒ“‚̃pƒXƒ[ƒhŠÇ—"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr "ƒŠƒ‚[ƒgƒ}ƒVƒ“"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "ˆóü‹¤—L ƒpƒ‰ƒ[ƒ^"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "*’"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "–¼‘O‚Ì擪‚É [*] ‚ª‚‚¢‚½ƒvƒŠƒ“ƒ^"
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "‚Í"
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "printcap name ƒpƒ‰ƒ[ƒ^"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "‚©‚玩“®Ý’肳‚ꂽ‚à‚Ì‚Å‚·‚©‚çA휂·‚邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñB"
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "ˆóü‹¤—L‚Ì‘I‘ð"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "ˆóü‹¤—L‚Ìíœ"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "ˆóü‹¤—L‚Ìì¬"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr "ŽQÆ‚Ì‚Ý "
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr "XV‚Ì‚Ý "
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr "ŽQÆ/XV "
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "ƒT[ƒo‚Ìó‘Ô"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Ž©“®XV‚ÌŠJŽn"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "XVŠÔŠu: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Ž©“®XV‚Ì’âŽ~"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "ƒo[ƒWƒ‡ƒ“"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "ŽÀs’†"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "’âŽ~’†"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "smbd ‚Ì’âŽ~"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "smbd ‚Ì‹N“®"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "smbd ‚ÌÄ‹N“®"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "nmbd ‚Ì’âŽ~"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "nmbd ‚Ì‹N“®"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "nmbd ‚ÌÄ‹N“®"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "winbindd ‚Ì’âŽ~"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "winbindd ‚Ì‹N“®"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "winbindd ‚ÌÄ‹N“®"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr "‚·‚ׂĒâŽ~"
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "‚·‚ׂÄÄ‹N“®"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "‚·‚ׂċN“®"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Ú‘±’†‚̃Nƒ‰ƒCƒAƒ“ƒg"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr "ƒNƒ‰ƒCƒAƒ“ƒg"
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "IPƒAƒhƒŒƒX"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "“ú•t"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Ø’f"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Ú‘±’†‚Ì‹¤—L"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "‹¤—L–¼"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "ƒ†[ƒU"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "ƒOƒ‹[ƒv"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Žg—p’†‚̃tƒ@ƒCƒ‹"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr "”r‘¼ƒ‚[ƒh"
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr "ŽQÆ/XV"
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr "ƒtƒ@ƒCƒ‹–¼"
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr "ƒNƒ‰ƒCƒAƒ“ƒg–¼‚ð擪‚É•\Ž¦"
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr "PID‚ð擪‚É•\Ž¦"
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Šî–{ ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "ƒZƒLƒ…ƒŠƒeƒB ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "ƒƒMƒ“ƒO ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "ƒvƒƒgƒRƒ‹ ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "ƒ`ƒ…[ƒjƒ“ƒO ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "ˆóü ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "ƒtƒ@ƒCƒ‹–¼‚̎戵"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "ƒhƒƒCƒ“ ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "ƒƒOƒIƒ“ ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "ƒuƒ‰ƒEƒWƒ“ƒO ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "WINS ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "ƒƒbƒLƒ“ƒO ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "LDAP ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "‚»‚Ì‘¼‚̃IƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "VFS ƒIƒvƒVƒ‡ƒ“"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Winbind ƒIƒvƒVƒ‡ƒ“"
diff --git a/source/po/nl.msg b/source/po/nl.msg
deleted file mode 100644
index 8d7b050ce90..00000000000
--- a/source/po/nl.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# Dutch messages for international release of SWAT.
-# Copyright (C) 2003 Jelmer Vernooij <jelmer@samba.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2000-02-08 12:48+09:00\n"
-"Last-Translator: Jelmer Vernooij <jelmer@samba.org>\n"
-"Language-Team: (Samba Team) <samba-technical@samba.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=US-ASCII\n"
-"Content-Transfer-Encoding: \n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr "FOUT: Kan %s niet openen"
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Help"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Stel Standaard In"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr "kon %s niet openen voor schrijven"
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr "Kan %s niet herladen"
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "Ingelogd als <b>%s</b>"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Home"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Algemene Instellingen"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Gedeelde Bronnen"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Printers"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr "Wizard"
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Status"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Bekijk Configuratie"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Wachtwoord Beheer"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Huidige weergave is"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Basis"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Geadvanceerd"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Verander Weergave In"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Huidige Configuratie"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Normale Weergave"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Volledige Weergave"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr "Wizard Instellingen Veranderen Pagina"
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr "N.B.: het smb.conf bestand is gelezen en herschreven"
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr "Samba Configuratie Wizard"
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr "De \"Herschrijf smb.conf bestand\" knop zal alle standaardwaardes en alle commentaar verwijderen."
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr "Hetzelfde zal gebeuren als u de \"toepassen\" knop gebruikt."
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr "Herschrijf smb.conf bestand"
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "Toepassen"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Bewerk Configuratie Waardes"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr "Server Type"
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr "Stand Alone"
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "Domein Lid"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "Domein Controller"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr "Ongebruikelijk Type in smb.conf - Selecteer een nieuwe modus"
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr "Configureer WINS Als"
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "Niet gebruikt"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr "Server voor client gebruik"
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr "Client van een andere WINS server"
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr "Naam of IP-adres WINS Server"
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr "Fout: WINS Server Modus en WINS Ondersteuning beiden ingesteld in smb.conf"
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr "Selecteer hierboven de gewenste WINS modus."
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr "Stel Home Directories Open"
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr "The configuratie hierboven zal meerdere variabelen veranderen en zal over het algemeen zorgen voor snelle installatie van Samba."
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Algemene Instellingen"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Pas Veranderingen Toe"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Beginwaarden"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Instellingen Gedeelde Bronnen"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Kies Bron"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Verwijder Bron"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Maak Bron"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "wachtwoord veranderen in demo modus geweigerd"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr "Kan wachtwoord database vectors niet opzetten."
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " \"Gebruikersnaam\" moet opgegeven worden "
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " \"Oude wachtwoord\" moet opgegeven worden "
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " \"Server Naam of IP\" moet opgegeven worden "
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Nieuw, en bevestiging Wachtwoorden\" moeten opgegeven worden "
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " Bevestigingswachtwoord was anders dan nieuwe wachtwoord "
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " Het wachtwoord voor '%s' is veranderd."
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " Het wachtwoord voor '%s' is niet veranderd."
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Server Wachtwoord Beheer"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr "Gebuikersnaam"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr "Oud Wachtwoord"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr "Nieuw Wachtwoord"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr "Bevestiging Nieuw Wachtwoord"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Verander Wachtwoord"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Voeg Gebruiker Toe"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Verwijder Gebruiker"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Maak gebruiker inactief"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Maak gebruiker actief"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Client/Server Wachtwoord Beheer"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr "Naam of IP Server"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Printer Instellingen"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Belangrijk:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Printer namen gemarkeerd met [*] in het Kies Printer veld "
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "zijn automatisch geladen uit "
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Printcap Naam"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Proberen deze printers te verwijderen vanuit SWAT zal geen effect hebben."
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Kies Printer"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Verwijder Printer"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Maak Printer"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr "RDONLY"
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr "WRONLY"
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr "RDWR"
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Server Status"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Automatisch Verversen"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Ververs Interval:"
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Stop met Verversen"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "versie:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr "smbd:"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "draaiend"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "niet draaiend"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Stop smbd"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Start smbd"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Herstart smbd"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr "nmbd:"
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Stop nmbd"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Start nmbd"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Herstart nmbd"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr "winbindd:"
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Stop winbindd"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Start winbindd"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Herstart winbindd"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr "Stop Alles"
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Herstart Alles"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Start Alles"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Actieve Verbindingen"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr "PID"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr "Client"
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "IP adres"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Datum"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Kill"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Actieve Bronnen"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Bron"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "Gebruiker"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Groep"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Geopende Bestanden"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr "Gedeeld"
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr "Lees/Schrijf"
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr "Oplock"
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr "Bestand"
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr "Toon Client in kolom 1"
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr "Toon PID in kolom 1"
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Basis Opties"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Veiligheidsopties"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Log Opties"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Protocol Opties"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Fijntune Opties"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Printer Opties"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Bestandsnaam Afhandeling"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Domein Opties"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Logon Opties"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Verken Opties"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "WINS Opties"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Locking Opties"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "LDAP Opties"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Verscheidene Opties"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "VFS module opties"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Winbind opties"
diff --git a/source/po/pl.msg b/source/po/pl.msg
deleted file mode 100644
index a7e56453bfc..00000000000
--- a/source/po/pl.msg
+++ /dev/null
@@ -1,593 +0,0 @@
-# Polish messages for international release of SWAT.
-# Copyright (C) 2001 Rafal Szczesniak <mimir@spin.ict.pwr.wroc.pl>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2001-08-15 22:45+02:00\n"
-"Last-Translator: Rafal Szczesniak <mimir@spin.ict.pwr.wroc.pl>\n"
-"Language-Team: pl\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=iso-8859-2\n"
-"Content-Transfer-Encoding: \n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr ""
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Pomoc"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Ustaw domy¶lnie"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "Zalogowany jako <b>%s</b><p>\n"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Strona domowa"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Ustawienia globalne"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Wspó³udzia³y"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Drukarki"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Status"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Przejrzyj Konfiguracjê"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Zarz±dzanie Has³ami"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Bie¿±ca Konfiguracja"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Widok Podstawowy"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Widok Zaawansowany"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Zmieñ Has³o"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Bie¿±ca Konfiguracja"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Normalny Widok"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Pe³ny Widok"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "Potwierd¼ Zmiany"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Parametry Drukarki"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr "Uruchom nmbd"
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr ""
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr ""
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr ""
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Zmienne Globalne"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Potwierd¼ Zmiany"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Zresetuj Warto¶ci"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Parametry Wspó³udzia³u"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Wybierz Wspó³udzia³"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Usuñ Wspó³udzia³"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Utwórz Wspó³udzia³"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "zmiana has³a w trybie demo odrzucona\n"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " Musisz podaæ \"Nazwê U¿ytkownika\" \n"
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " Musisz podaæ \"Stare Has³o\" \n"
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " Musisz podaæ \"Zdaln± Maszynê\" \n"
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " Musisz podaæ \"Nowe Has³o, i ponownie wpisane Nowe Has³o\" \n"
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " Ponownie wpisane has³o nie pasuje do nowego has³a\n"
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " Has³o dla '%s' zosta³o zmienione. \n"
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " Has³o dla '%s' NIE zosta³o zmienione. \n"
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Zarz±dzanie Has³ami na Serwerze"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr " Nazwa U¿ytkownika"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr " Stare Has³o"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr " Nowe Has³o"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr " Ponownie wpisz Nowe Has³o"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Zmieñ Has³o"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Dodaj Nowego U¿ytkownika"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Usuñ U¿ytkownika"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Zablokuj U¿ytkownika"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Odblokuj U¿ytkownika"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Zarz±dzanie Has³ami Klient/Serwer"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr " Zdalna Maszyna"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Parametry Drukarki"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Wa¿na Informacja:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Nazwy Drukarek zaznaczone [*] w rozwijanym polu Wybierz Drukarkê "
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "s± drukarkami automatycznie ³adowanymi z "
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Nazwa Printcap"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Próby usuniêcia tych drukarek ze SWAT nie przynios± efektu.\n"
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Wybierz Drukarkê"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Usuñ Drukarkê"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Utwórz Drukarkê"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr ""
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr ""
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr ""
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Status Serwera"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Automatyczne Od¶wie¿anie"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Interwa³ Od¶wie¿ania: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Zatrzymaj Od¶wie¿anie"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "wersja:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr ""
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "dzia³a"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "nie dzia³a"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Zatrzymaj smbd"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Uruchom smbd"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Zrestartuj smbd"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr ""
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Zatrzymaj nmbd"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Uruchom nmbd"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Zrestartuj nmbd"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr ""
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Zatrzymaj nmbd"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Uruchom nmbd"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Zrestartuj nmbd"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Zrestartuj nmbd"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Uruchom nmbd"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Aktywne Po³±czenia"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr ""
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr "Klient"
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "adres IP"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Data"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Zatrzymaj"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Aktywne Wspó³udzia³y"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Wspó³udzia³"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "U¿ytkownik"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Grupa"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Otwarte Pliki"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr "Wspó³dzielenie"
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr ""
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr "Plik"
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Bazowe Opcje"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Opcje Zabezpieczeñ"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Opcje Blokowania"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Opcje Protoko³u"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Opcje Dostrajaj±ce"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Opcje Drukowania"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Obs³uga Nazw Plików"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Opcje Domeny"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Opcje Logowania"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Opcje Przegl±dania"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "Opcje WINS"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Opcje Blokowania"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "Opcje Ldap"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Pozosta³e Opcje"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "Opcje WINS"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Opcje Drukowania"
diff --git a/source/po/tr.msg b/source/po/tr.msg
deleted file mode 100644
index 8ef551da46a..00000000000
--- a/source/po/tr.msg
+++ /dev/null
@@ -1,594 +0,0 @@
-# Turkish messages for international release of SWAT.
-# Copyright (C) 2001 Deniz Akkus Kanca <deniz@arayan.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: i18n_swat \n"
-"POT-Creation-Date: 2003-10-06 05:30+0900\n"
-"PO-Revision-Date: 2001-09-20 22:51EEST\n"
-"Last-Translator: Deniz Akkus Kanca <deniz@arayan.com>\n"
-"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-9\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 0.9.1\n"
-
-#: ../web/swat.c:117
-#, c-format
-msgid "ERROR: Can't open %s"
-msgstr ""
-
-#: ../web/swat.c:200
-msgid "Help"
-msgstr "Yardým"
-
-#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
-msgid "Set Default"
-msgstr "Öntanýmlýya Ayarla"
-
-#: ../web/swat.c:408
-#, c-format
-msgid "failed to open %s for writing"
-msgstr ""
-
-#: ../web/swat.c:431
-#, c-format
-msgid "Can't reload %s"
-msgstr ""
-
-#: ../web/swat.c:501
-#, c-format
-msgid "Logged in as <b>%s</b>"
-msgstr "<b>%s</b> kimliði ile oturum açýlmýþ"
-
-#: ../web/swat.c:505
-msgid "Home"
-msgstr "Ev"
-
-#: ../web/swat.c:507
-msgid "Globals"
-msgstr "Evrenseller"
-
-#: ../web/swat.c:508
-msgid "Shares"
-msgstr "Paylaþýmlar"
-
-#: ../web/swat.c:509
-msgid "Printers"
-msgstr "Yazýcýlar"
-
-#: ../web/swat.c:510
-msgid "Wizard"
-msgstr ""
-
-#: ../web/swat.c:513
-msgid "Status"
-msgstr "Durum"
-
-#: ../web/swat.c:514
-msgid "View Config"
-msgstr "Ayarlara Gözat"
-
-#: ../web/swat.c:516
-msgid "Password Management"
-msgstr "Þifre Yönetimi"
-
-#: ../web/swat.c:526
-msgid "Current View Is"
-msgstr "Þimdiki Ayarlar"
-
-#: ../web/swat.c:527 ../web/swat.c:530
-msgid "Basic"
-msgstr "Temel Görünüm"
-
-#: ../web/swat.c:528 ../web/swat.c:531
-msgid "Advanced"
-msgstr "Geliþmiþ Görünüm"
-
-#: ../web/swat.c:529
-msgid "Change View To"
-msgstr "Þifre Deðiþtir"
-
-#: ../web/swat.c:554
-msgid "Current Config"
-msgstr "Þimdiki Ayarlar"
-
-#: ../web/swat.c:558
-msgid "Normal View"
-msgstr "Normal Görünüm"
-
-#: ../web/swat.c:560
-msgid "Full View"
-msgstr "Tam Görünüm"
-
-#. Here we first set and commit all the parameters that were selected
-#. in the previous screen.
-#: ../web/swat.c:579
-msgid "Wizard Parameter Edit Page"
-msgstr ""
-
-#: ../web/swat.c:608
-msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
-
-#. Here we go ...
-#: ../web/swat.c:716
-msgid "Samba Configuration Wizard"
-msgstr ""
-
-#: ../web/swat.c:720
-msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
-
-#: ../web/swat.c:721
-msgid "The same will happen if you press the commit button."
-msgstr ""
-
-#: ../web/swat.c:724
-msgid "Rewrite smb.conf file"
-msgstr ""
-
-#: ../web/swat.c:725
-msgid "Commit"
-msgstr "açýklama"
-
-#: ../web/swat.c:726
-msgid "Edit Parameter Values"
-msgstr "Yazýcý Bilgileri"
-
-#: ../web/swat.c:732
-msgid "Server Type"
-msgstr ""
-
-#: ../web/swat.c:733
-msgid "Stand Alone"
-msgstr "Nmbd'yi çalýþtýr"
-
-#: ../web/swat.c:734
-msgid "Domain Member"
-msgstr "alan sunucusu"
-
-#: ../web/swat.c:735
-msgid "Domain Controller"
-msgstr "alan sunucusu"
-
-#: ../web/swat.c:738
-msgid "Unusual Type in smb.conf - Please Select New Mode"
-msgstr ""
-
-#: ../web/swat.c:740
-msgid "Configure WINS As"
-msgstr ""
-
-#: ../web/swat.c:741
-msgid "Not Used"
-msgstr "dont descend"
-
-#: ../web/swat.c:742
-msgid "Server for client use"
-msgstr ""
-
-#: ../web/swat.c:743
-msgid "Client of another WINS server"
-msgstr ""
-
-#: ../web/swat.c:745
-msgid "Remote WINS Server"
-msgstr ""
-
-#: ../web/swat.c:756
-msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
-
-#: ../web/swat.c:757
-msgid "Please Select desired WINS mode above."
-msgstr ""
-
-#: ../web/swat.c:759
-msgid "Expose Home Directories"
-msgstr ""
-
-#: ../web/swat.c:774
-msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
-
-#: ../web/swat.c:787
-msgid "Global Parameters"
-msgstr "Genel Deðiþkenler"
-
-#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
-msgid "Commit Changes"
-msgstr "Deðiþiklikleri Kaydet"
-
-#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
-msgid "Reset Values"
-msgstr "Deðerleri Ýlk Haline Getir"
-
-#: ../web/swat.c:844
-msgid "Share Parameters"
-msgstr "Paylaþým Parametreleri"
-
-#: ../web/swat.c:887
-msgid "Choose Share"
-msgstr "Paylaþým Seçin"
-
-#: ../web/swat.c:901
-msgid "Delete Share"
-msgstr "Paylaþým Kaldýr"
-
-#: ../web/swat.c:908
-msgid "Create Share"
-msgstr "Paylaþým Oluþtur"
-
-#: ../web/swat.c:944
-msgid "password change in demo mode rejected"
-msgstr "demo kipinde þifre deðiþikliði kabul edilmedi\n"
-
-#: ../web/swat.c:957
-msgid "Can't setup password database vectors."
-msgstr ""
-
-#: ../web/swat.c:983
-msgid " Must specify \"User Name\" "
-msgstr " \"Kullanýcý Adý\" belirtilmeli \n"
-
-#: ../web/swat.c:999
-msgid " Must specify \"Old Password\" "
-msgstr " \"Eski Þifre\" belirtilmeli \n"
-
-#: ../web/swat.c:1005
-msgid " Must specify \"Remote Machine\" "
-msgstr " \"Uzak Makina\" belirtilmeli \n"
-
-#: ../web/swat.c:1012
-msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Yeni ve Tekrar Girilmiþ Þifreler\" belirtilmeli \n"
-
-#: ../web/swat.c:1018
-msgid " Re-typed password didn't match new password "
-msgstr " Tekrar girilen þifre yeni þifre ile eþleþmedi\n"
-
-#: ../web/swat.c:1048
-#, c-format
-msgid " The passwd for '%s' has been changed."
-msgstr " '%s' için þifre deðiþtirildi."
-
-#: ../web/swat.c:1051
-#, c-format
-msgid " The passwd for '%s' has NOT been changed."
-msgstr " '%s' için þifre DEÐÝÞTÝRÝLMEDÝ."
-
-#: ../web/swat.c:1076
-msgid "Server Password Management"
-msgstr "Sunucu Þifre Yönetimi"
-
-#.
-#. * Create all the dialog boxes for data collection
-#.
-#: ../web/swat.c:1085 ../web/swat.c:1132
-msgid "User Name"
-msgstr " Kullanýcý Adý"
-
-#: ../web/swat.c:1088 ../web/swat.c:1134
-msgid "Old Password"
-msgstr " Eski Þifre"
-
-#: ../web/swat.c:1091 ../web/swat.c:1136
-msgid "New Password"
-msgstr " Yeni Þifre"
-
-#: ../web/swat.c:1093 ../web/swat.c:1138
-msgid "Re-type New Password"
-msgstr " Yeni Þifre Tekrarý"
-
-#: ../web/swat.c:1101 ../web/swat.c:1149
-msgid "Change Password"
-msgstr "Þifre Deðiþtir"
-
-#: ../web/swat.c:1104
-msgid "Add New User"
-msgstr "Kull. Ekle"
-
-#: ../web/swat.c:1106
-msgid "Delete User"
-msgstr "Kull. Sil"
-
-#: ../web/swat.c:1108
-msgid "Disable User"
-msgstr "Kull. Etkisizleþtir"
-
-#: ../web/swat.c:1110
-msgid "Enable User"
-msgstr "Kull. Etkinleþtir"
-
-#: ../web/swat.c:1123
-msgid "Client/Server Password Management"
-msgstr "Ýstemci/Sunucu Þifre Yönetimi"
-
-#: ../web/swat.c:1140
-msgid "Remote Machine"
-msgstr " Uzak Makina"
-
-#: ../web/swat.c:1179
-msgid "Printer Parameters"
-msgstr "Yazýcý Bilgileri"
-
-#: ../web/swat.c:1181
-msgid "Important Note:"
-msgstr "Önemli Not:"
-
-#: ../web/swat.c:1182
-msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Yazýcý Seç kutusunda [*] ile iþaretlenmiþ yazýcý isimleri "
-
-#: ../web/swat.c:1183
-msgid "are autoloaded printers from "
-msgstr "otomatik yüklenen yazýcýlar "
-
-#: ../web/swat.c:1184
-msgid "Printcap Name"
-msgstr "Printcap Adý"
-
-#: ../web/swat.c:1185
-msgid "Attempting to delete these printers from SWAT will have no effect."
-msgstr "Bu yazýcýlarý SWAT'dan silmek etkisiz olacaktýr.\n"
-
-#: ../web/swat.c:1231
-msgid "Choose Printer"
-msgstr "Yazýcý Seç"
-
-#: ../web/swat.c:1250
-msgid "Delete Printer"
-msgstr "Yazýcý Sil"
-
-#: ../web/swat.c:1257
-msgid "Create Printer"
-msgstr "Yazýcý Oluþtur"
-
-#: ../web/statuspage.c:123
-msgid "RDONLY "
-msgstr "SALTOKUNUR "
-
-#: ../web/statuspage.c:124
-msgid "WRONLY "
-msgstr "SALTYAZILIR "
-
-#: ../web/statuspage.c:125
-msgid "RDWR "
-msgstr "O/Y "
-
-#: ../web/statuspage.c:309
-msgid "Server Status"
-msgstr "Sunucu Durumu"
-
-#: ../web/statuspage.c:314
-msgid "Auto Refresh"
-msgstr "Oto Tazele"
-
-#: ../web/statuspage.c:315 ../web/statuspage.c:320
-msgid "Refresh Interval: "
-msgstr "Tazeleme Aralýðý: "
-
-#: ../web/statuspage.c:319
-msgid "Stop Refreshing"
-msgstr "Tazelemeyi Durdur"
-
-#: ../web/statuspage.c:334
-msgid "version:"
-msgstr "sürüm:"
-
-#: ../web/statuspage.c:337
-msgid "smbd:"
-msgstr "smbd:"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "running"
-msgstr "çalýþýyor"
-
-#: ../web/statuspage.c:337 ../web/statuspage.c:350 ../web/statuspage.c:364
-msgid "not running"
-msgstr "çalýþmýyor"
-
-#: ../web/statuspage.c:341
-msgid "Stop smbd"
-msgstr "Smbd'yi durdur"
-
-#: ../web/statuspage.c:343
-msgid "Start smbd"
-msgstr "Smbd'yi çalýþtýr"
-
-#: ../web/statuspage.c:345
-msgid "Restart smbd"
-msgstr "Smbd'yi yeniden çalýþtýr"
-
-#: ../web/statuspage.c:350
-msgid "nmbd:"
-msgstr "nmbd:"
-
-#: ../web/statuspage.c:354
-msgid "Stop nmbd"
-msgstr "Nmbd'yi durdur"
-
-#: ../web/statuspage.c:356
-msgid "Start nmbd"
-msgstr "Nmbd'yi çalýþtýr"
-
-#: ../web/statuspage.c:358
-msgid "Restart nmbd"
-msgstr "Nmbd'yi yeniden çalýþtýr"
-
-#: ../web/statuspage.c:364
-msgid "winbindd:"
-msgstr "winbind uid"
-
-#: ../web/statuspage.c:368
-msgid "Stop winbindd"
-msgstr "Nmbd'yi durdur"
-
-#: ../web/statuspage.c:370
-msgid "Start winbindd"
-msgstr "Nmbd'yi çalýþtýr"
-
-#: ../web/statuspage.c:372
-msgid "Restart winbindd"
-msgstr "Nmbd'yi yeniden çalýþtýr"
-
-#. stop, restart all
-#: ../web/statuspage.c:381
-msgid "Stop All"
-msgstr ""
-
-#: ../web/statuspage.c:382
-msgid "Restart All"
-msgstr "Nmbd'yi yeniden çalýþtýr"
-
-#. start all
-#: ../web/statuspage.c:386
-msgid "Start All"
-msgstr "Nmbd'yi çalýþtýr"
-
-#: ../web/statuspage.c:393
-msgid "Active Connections"
-msgstr "Aktif Baðlantýlar"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "PID"
-msgstr "PID"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408
-msgid "Client"
-msgstr "Ýstemci"
-
-#: ../web/statuspage.c:395
-msgid "IP address"
-msgstr "IP numarasý"
-
-#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
-msgid "Date"
-msgstr "Tarih"
-
-#: ../web/statuspage.c:397
-msgid "Kill"
-msgstr "Kapat"
-
-#: ../web/statuspage.c:405
-msgid "Active Shares"
-msgstr "Aktif Paylaþýmlar"
-
-#: ../web/statuspage.c:408
-msgid "Share"
-msgstr "Paylaþým"
-
-#: ../web/statuspage.c:408
-msgid "User"
-msgstr "Kullanýcý"
-
-#: ../web/statuspage.c:408
-msgid "Group"
-msgstr "Grup"
-
-#: ../web/statuspage.c:414
-msgid "Open Files"
-msgstr "Açýk Dosyalar"
-
-#: ../web/statuspage.c:416
-msgid "Sharing"
-msgstr "Paylaþýlýyor"
-
-#: ../web/statuspage.c:416
-msgid "R/W"
-msgstr "O/Y"
-
-#: ../web/statuspage.c:416
-msgid "Oplock"
-msgstr "Oplock"
-
-#: ../web/statuspage.c:416
-msgid "File"
-msgstr "Dosya"
-
-#: ../web/statuspage.c:425
-msgid "Show Client in col 1"
-msgstr ""
-
-#: ../web/statuspage.c:426
-msgid "Show PID in col 1"
-msgstr ""
-
-#: ../param/loadparm.c:755
-msgid "Base Options"
-msgstr "Temel Seçenekler"
-
-#: ../param/loadparm.c:775
-msgid "Security Options"
-msgstr "Güvenlik Seçenekleri"
-
-#: ../param/loadparm.c:859
-msgid "Logging Options"
-msgstr "Günlük Kaydý Seçenekleri"
-
-#: ../param/loadparm.c:874
-msgid "Protocol Options"
-msgstr "Protokol Seçenekleri"
-
-#: ../param/loadparm.c:911
-msgid "Tuning Options"
-msgstr "Ayar Seçenekleri"
-
-#: ../param/loadparm.c:940
-msgid "Printing Options"
-msgstr "Yazdýrma Seçenekleri"
-
-#: ../param/loadparm.c:970
-msgid "Filename Handling"
-msgstr "Dosyaadý Ýþlenmesi"
-
-#: ../param/loadparm.c:996
-msgid "Domain Options"
-msgstr "Alan Seçenekleri"
-
-#: ../param/loadparm.c:1000
-msgid "Logon Options"
-msgstr "Sistem Giriþ Seçenekleri"
-
-#: ../param/loadparm.c:1019
-msgid "Browse Options"
-msgstr "Gözatma Seçenekleri"
-
-#: ../param/loadparm.c:1033
-msgid "WINS Options"
-msgstr "WINS Seçenekleri"
-
-#: ../param/loadparm.c:1043
-msgid "Locking Options"
-msgstr "Kilitleme Seçenekleri"
-
-#: ../param/loadparm.c:1061
-msgid "Ldap Options"
-msgstr "Ldap Seçenekleri"
-
-#: ../param/loadparm.c:1078
-msgid "Miscellaneous Options"
-msgstr "Diðer Seçenekler"
-
-#: ../param/loadparm.c:1138
-msgid "VFS module options"
-msgstr "VFS Seçenekleri"
-
-#: ../param/loadparm.c:1148
-msgid "Winbind options"
-msgstr "Winbind seçenekleri"
diff --git a/source/printing/load.c b/source/printing/load.c
index cd90cbb6f33..ae76229d773 100644
--- a/source/printing/load.c
+++ b/source/printing/load.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
load printer lists
Copyright (C) Andrew Tridgell 1992-2000
@@ -38,7 +39,7 @@ auto-load some homes and printer services
***************************************************************************/
static void add_auto_printers(void)
{
- const char *p;
+ char *p;
int printers;
char *str = strdup(lp_auto_services());
@@ -47,9 +48,9 @@ static void add_auto_printers(void)
printers = lp_servicenumber(PRINTERS_NAME);
if (printers < 0) {
- SAFE_FREE(str);
- return;
- }
+ SAFE_FREE(str);
+ return;
+ }
for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
if (lp_servicenumber(p) >= 0) continue;
diff --git a/source/printing/lpq_parse.c b/source/printing/lpq_parse.c
index b7e41964f1b..ccebe6bce19 100644
--- a/source/printing/lpq_parse.c
+++ b/source/printing/lpq_parse.c
@@ -1,7 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
lpq parsing routines
Copyright (C) Andrew Tridgell 2000
+ Copyright (C) 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,6 +22,7 @@
#include "includes.h"
+
static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
@@ -126,7 +129,6 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
}
#endif /* OSF1 */
- /* FIXME: Use next_token rather than strtok! */
tok[0] = strtok(line2," \t");
count++;
@@ -152,11 +154,11 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
int i;
for (i = (FILETOK + 1); i < TOTALTOK; i++) {
- /* FIXME: Using fstrcat rather than other means is a bit
- * inefficient; this might be a problem for enormous queues with
- * many fields. */
- fstrcat(buf->fs_file, " ");
- fstrcat(buf->fs_file, tok[i]);
+ /* FIXME: Using fstrcat rather than other means is a bit
+ * inefficient; this might be a problem for enormous queues with
+ * many fields. */
+ fstrcat(buf->fs_file, " ");
+ fstrcat(buf->fs_file, tok[i]);
}
/* Ensure null termination. */
fstrterminate(buf->fs_file);
@@ -272,7 +274,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
* for the current user on the taskbar. Plop in a null.
*/
- if ((ptr = strchr_m(buf->fs_user,'@')) != NULL) {
+ if ((ptr = strchr(buf->fs_user,'@')) != NULL) {
*ptr = '\0';
}
@@ -316,7 +318,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
const char *cline = line;
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
+ pstring_sub(line,"standard input","STDIN");
all_string_sub(line,"(","\"",0);
all_string_sub(line,")","\"",0);
@@ -334,13 +336,13 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False);
buf->size = atoi(tok[4]) * 1024;
/* if the fname contains a space then use STDIN */
- if (strchr_m(tok[2],' '))
+ if (strchr(tok[2],' '))
fstrcpy(tok[2],"STDIN");
/* only take the last part of the filename */
{
fstring tmp;
- char *p = strrchr_m(tok[2],'/');
+ char *p = strrchr(tok[2],'/');
if (p)
{
fstrcpy(tmp,p+1);
@@ -353,8 +355,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[3]);
- fstrcpy(buf->fs_file,tok[2]);
+ fstrcpy(buf->fs_user, tok[3]);
+ fstrcpy(buf->fs_file, tok[2]);
}
else
{
@@ -368,13 +370,13 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False);
buf->size = atoi(tok[8]) * 1024;
/* if the fname contains a space then use STDIN */
- if (strchr_m(tok[4],' '))
+ if (strchr(tok[4],' '))
fstrcpy(tok[4],"STDIN");
/* only take the last part of the filename */
{
fstring tmp;
- char *p = strrchr_m(tok[4],'/');
+ char *p = strrchr(tok[4],'/');
if (p)
{
fstrcpy(tmp,p+1);
@@ -387,8 +389,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
buf->priority = 0;
buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[5]);
- fstrcpy(buf->fs_file,tok[4]);
+ fstrcpy(buf->fs_user, tok[5]);
+ fstrcpy(buf->fs_file, tok[4]);
}
@@ -406,7 +408,7 @@ ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
ljplus-2154 user priority 0 Jan 19 08:14 from client
(standard input) 7551 bytes
****************************************************************************/
-static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
+static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
{
/* must read two lines to process, therefore keep some values static */
static BOOL header_line_ok=False, base_prio_reset=False;
@@ -418,6 +420,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
/* to store minimum priority to print, lpstat command should be invoked
with -p option first, to work */
static int base_prio;
+
int count;
char htab = '\011';
const char *cline = line;
@@ -433,7 +436,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
}
if (!header_line_ok) return (False); /* incorrect header line */
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
+ pstring_sub(line,"standard input","STDIN");
all_string_sub(line,"(","\"",0);
all_string_sub(line,")","\"",0);
@@ -445,7 +448,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
if (!isdigit((int)*tok[1])) return(False);
/* if the fname contains a space then use STDIN */
- if (strchr_m(tok[0],' '))
+ if (strchr(tok[0],' '))
fstrcpy(tok[0],"STDIN");
buf->size = atoi(tok[1]);
@@ -456,7 +459,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
buf->job = jobid;
buf->status = jobstat;
buf->priority = jobprio;
- fstrcpy(buf->fs_user,jobuser);
+ fstrcpy(buf->fs_user, jobuser);
return(True);
}
@@ -471,7 +474,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
else if (base_prio) base_prio_reset=False;
/* handle the dash in the job id */
- string_sub(line,"-"," ",0);
+ pstring_sub(line,"-"," ");
for (count=0; count<12 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
@@ -482,7 +485,7 @@ static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
/* the 2nd, 5th & 7th column must be integer */
if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
jobid = atoi(tok[1]);
- fstrcpy(jobuser,tok[2]);
+ fstrcpy(jobuser, tok[2]);
jobprio = atoi(tok[4]);
/* process time */
@@ -520,7 +523,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
int count=0;
char *p;
const char *cline = line;
-
+
/*
* Handle the dash in the job id, but make sure that we skip over
* the printer name in case we have a dash in that.
@@ -557,7 +560,7 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
return(False);
/* if the user contains a ! then trim the first part of it */
- if ((p=strchr_m(tok[2],'!'))) {
+ if ((p=strchr(tok[2],'!'))) {
fstring tmp;
fstrcpy(tmp,p+1);
fstrcpy(tok[2],tmp);
@@ -573,8 +576,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
buf->status = LPQ_QUEUED;
buf->priority = 0;
buf->time = EntryTime(tok, 4, count, 7);
- fstrcpy(buf->fs_user,tok[2]);
- fstrcpy(buf->fs_file,tok[2]);
+ fstrcpy(buf->fs_user, tok[2]);
+ fstrcpy(buf->fs_file, tok[2]);
return(True);
}
@@ -597,16 +600,16 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
DEBUG(4,("antes [%s]\n", line));
/* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN",0);
+ pstring_sub(line,"standard input","STDIN");
DEBUG(4,("despues [%s]\n", line));
all_string_sub(line,"-- ","\"",0);
all_string_sub(line," --","\"",0);
DEBUG(4,("despues 1 [%s]\n", line));
- string_sub(line,"[job #","",0);
- string_sub(line,"]","",0);
+ pstring_sub(line,"[job #","");
+ pstring_sub(line,"]","");
DEBUG(4,("despues 2 [%s]\n", line));
-
+
for (count=0; count<7 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
/* we must get 7 tokens */
@@ -619,7 +622,7 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
/* only take the last part of the filename */
{
fstring tmp;
- char *p = strrchr_m(tok[6],'/');
+ char *p = strrchr(tok[6],'/');
if (p)
{
fstrcpy(tmp,p+1);
@@ -659,7 +662,7 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
const char *cline = line;
/* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN",0);
+ pstring_sub(line,"stdin","STDIN");
all_string_sub(line,"(","\"",0);
all_string_sub(line,")","\"",0);
@@ -678,13 +681,13 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
return(False);
/* if the fname contains a space then use STDIN */
- if (strchr_m(tok[6],' '))
+ if (strchr(tok[6],' '))
fstrcpy(tok[6],"STDIN");
/* only take the last part of the filename */
{
fstring tmp;
- char *p = strrchr_m(tok[6],'/');
+ char *p = strrchr(tok[6],'/');
if (p)
{
fstrcpy(tmp,p+1);
@@ -696,9 +699,9 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
buf->job = atoi(tok[4]);
buf->size = atoi(tok[7]);
- if (strchr_m(tok[7],'K'))
+ if (strchr(tok[7],'K'))
buf->size *= 1024;
- if (strchr_m(tok[7],'M'))
+ if (strchr(tok[7],'M'))
buf->size *= 1024*1024;
buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
@@ -709,6 +712,86 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
return(True);
}
+/****************************************************************************
+parse a qstat line
+
+here is an example of "qstat -l -d qms" output under softq
+
+Queue qms: 2 jobs; daemon active (313); enabled; accepting;
+ job-ID submission-time pri size owner title
+205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps
+206086:> 98/03/12 17:24:40 0 659 chris -
+206087: 98/03/12 17:24:45 0 4876 chris -
+Total: 21268 bytes in queue
+
+
+****************************************************************************/
+static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
+{
+ fstring tok[10];
+ int count=0;
+ const char *cline = line;
+
+ /* mung all the ":"s to spaces*/
+ pstring_sub(line,":"," ");
+
+ for (count=0; count<10 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
+
+ /* we must get 9 tokens */
+ if (count < 9)
+ return(False);
+
+ /* the 1st and 7th columns must be integer */
+ if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False);
+ /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
+ * integer, else it's the 6th and 7th that must be
+ */
+ if (*tok[1] == 'H' || *tok[1] == '>')
+ {
+ if (!isdigit((int)*tok[7]))
+ return(False);
+ buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
+ count = 1;
+ }
+ else
+ {
+ if (!isdigit((int)*tok[5]))
+ return(False);
+ buf->status = LPQ_QUEUED;
+ count = 0;
+ }
+
+
+ buf->job = atoi(tok[0]);
+ buf->size = atoi(tok[count+6]);
+ buf->priority = atoi(tok[count+5]);
+ fstrcpy(buf->fs_user,tok[count+7]);
+ fstrcpy(buf->fs_file,tok[count+8]);
+ buf->time = time(NULL); /* default case: take current time */
+ {
+ time_t jobtime;
+ struct tm *t;
+
+ t = localtime(&buf->time);
+ t->tm_mday = atoi(tok[count+2]+6);
+ t->tm_mon = atoi(tok[count+2]+3);
+ switch (*tok[count+2])
+ {
+ case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
+ default: t->tm_year = atoi(tok[count+2]); break;
+ }
+
+ t->tm_hour = atoi(tok[count+3]);
+ t->tm_min = atoi(tok[count+4]);
+ t->tm_sec = atoi(tok[count+5]);
+ jobtime = mktime(t);
+ if (jobtime != (time_t)-1)
+ buf->time = jobtime;
+ }
+
+ return(True);
+}
+
/*******************************************************************
parse lpq on an NT system
@@ -755,8 +838,8 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
return(False);
/* Just want the first word in the owner field - the username */
- if (strchr_m(parse_line.owner, ' '))
- *(strchr_m(parse_line.owner, ' ')) = '\0';
+ if (strchr(parse_line.owner, ' '))
+ *(strchr(parse_line.owner, ' ')) = '\0';
else
parse_line.space1 = '\0';
@@ -766,14 +849,14 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
/* Make sure the status is valid */
parse_line.space2 = '\0';
- trim_char(parse_line.status, '\0', ' ');
+ trim_string(parse_line.status, NULL, " ");
if (!strequal(parse_line.status, LPRNT_PRINTING) &&
!strequal(parse_line.status, LPRNT_PAUSED) &&
!strequal(parse_line.status, LPRNT_WAITING))
return(False);
parse_line.space3 = '\0';
- trim_char(parse_line.jobname, '\0', ' ');
+ trim_string(parse_line.jobname, NULL, " ");
buf->job = atoi(parse_line.jobid);
buf->priority = 0;
@@ -837,7 +920,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
/* Get the job name */
parse_line.space2[0] = '\0';
- trim_char(parse_line.jobname, '\0', ' ');
+ trim_string(parse_line.jobname, NULL, " ");
fstrcpy(buf->fs_file, parse_line.jobname);
buf->priority = 0;
@@ -850,7 +933,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
/* Make sure we have a valid status */
parse_line.space4[0] = '\0';
- trim_char(parse_line.status, '\0', ' ');
+ trim_string(parse_line.status, NULL, " ");
if (!strequal(parse_line.status, LPROS2_PRINTING) &&
!strequal(parse_line.status, LPROS2_PAUSED) &&
!strequal(parse_line.status, LPROS2_WAITING))
@@ -880,7 +963,7 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
{
int toknum = 0;
fstring tok;
- const char *cline = line;
+ const char *cline = line;
/* First line is printer status */
@@ -920,7 +1003,6 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
/****************************************************************************
parse a lpq line. Choose printing style
****************************************************************************/
-
BOOL parse_lpq_entry(int snum,char *line,
print_queue_struct *buf,
print_status_struct *status,BOOL first)
@@ -947,6 +1029,9 @@ BOOL parse_lpq_entry(int snum,char *line,
case PRINT_PLP:
ret = parse_lpq_plp(line,buf,first);
break;
+ case PRINT_SOFTQ:
+ ret = parse_lpq_softq(line,buf,first);
+ break;
case PRINT_LPRNT:
ret = parse_lpq_nt(line,buf,first);
break;
@@ -966,7 +1051,7 @@ BOOL parse_lpq_entry(int snum,char *line,
/* We don't want the newline in the status message. */
{
- char *p = strchr_m(line,'\n');
+ char *p = strchr(line,'\n');
if (p) *p = 0;
}
@@ -984,29 +1069,29 @@ BOOL parse_lpq_entry(int snum,char *line,
printer status line:
handle them so that most severe condition is shown */
int i;
- strlower_m(line);
+ strlower(line);
switch (status->status) {
case LPSTAT_OK:
for (i=0; stat0_strings[i]; i++)
- if (strstr_m(line,stat0_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_OK;
- return ret;
+ if (strstr(line,stat0_strings[i])) {
+ StrnCpy(status->message,line,sizeof(status->message)-1);
+ status->status=LPSTAT_OK;
+ return ret;
}
case LPSTAT_STOPPED:
for (i=0; stat1_strings[i]; i++)
- if (strstr_m(line,stat1_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_STOPPED;
- return ret;
+ if (strstr(line,stat1_strings[i])) {
+ StrnCpy(status->message,line,sizeof(status->message)-1);
+ status->status=LPSTAT_STOPPED;
+ return ret;
}
case LPSTAT_ERROR:
for (i=0; stat2_strings[i]; i++)
- if (strstr_m(line,stat2_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_ERROR;
- return ret;
+ if (strstr(line,stat2_strings[i])) {
+ StrnCpy(status->message,line,sizeof(status->message)-1);
+ status->status=LPSTAT_ERROR;
+ return ret;
}
break;
}
diff --git a/source/printing/notify.c b/source/printing/notify.c
deleted file mode 100644
index 7750239630c..00000000000
--- a/source/printing/notify.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Tim Potter, 2002
- Copyright (C) Gerald Carter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-static TALLOC_CTX *send_ctx;
-
-static unsigned int num_messages;
-
-static struct notify_queue {
- struct notify_queue *next, *prev;
- struct spoolss_notify_msg *msg;
- struct timeval tv;
- char *buf;
- size_t buflen;
-} *notify_queue_head = NULL;
-
-
-static BOOL create_send_ctx(void)
-{
- if (!send_ctx)
- send_ctx = talloc_init("print notify queue");
-
- if (!send_ctx)
- return False;
-
- return True;
-}
-
-/****************************************************************************
- Turn a queue name into a snum.
-****************************************************************************/
-
-int print_queue_snum(const char *qname)
-{
- int snum = lp_servicenumber(qname);
- if (snum == -1 || !lp_print_ok(snum))
- return -1;
- return snum;
-}
-
-/*******************************************************************
- Used to decide if we need a short select timeout.
-*******************************************************************/
-
-BOOL print_notify_messages_pending(void)
-{
- return (notify_queue_head != NULL);
-}
-
-/*******************************************************************
- Flatten data into a message.
-*******************************************************************/
-
-static BOOL flatten_message(struct notify_queue *q)
-{
- struct spoolss_notify_msg *msg = q->msg;
- char *buf = NULL;
- size_t buflen = 0, len;
-
-again:
- len = 0;
-
- /* Pack header */
-
- len += tdb_pack(buf + len, buflen - len, "f", msg->printer);
-
- len += tdb_pack(buf + len, buflen - len, "ddddddd",
- (uint32)q->tv.tv_sec, (uint32)q->tv.tv_usec,
- msg->type, msg->field, msg->id, msg->len, msg->flags);
-
- /* Pack data */
-
- if (msg->len == 0)
- len += tdb_pack(buf + len, buflen - len, "dd",
- msg->notify.value[0], msg->notify.value[1]);
- else
- len += tdb_pack(buf + len, buflen - len, "B",
- msg->len, msg->notify.data);
-
- if (buflen != len) {
- buf = talloc_realloc(send_ctx, buf, len);
- if (!buf)
- return False;
- buflen = len;
- goto again;
- }
-
- q->buf = buf;
- q->buflen = buflen;
-
- return True;
-}
-
-/*******************************************************************
- Send the batched messages - on a per-printer basis.
-*******************************************************************/
-
-static void print_notify_send_messages_to_printer(const char *printer, unsigned int timeout)
-{
- char *buf;
- struct notify_queue *pq, *pq_next;
- size_t msg_count = 0, offset = 0;
- size_t num_pids = 0;
- size_t i;
- pid_t *pid_list = NULL;
-
- /* Count the space needed to send the messages. */
- for (pq = notify_queue_head; pq; pq = pq->next) {
- if (strequal(printer, pq->msg->printer)) {
- if (!flatten_message(pq)) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- num_messages = 0;
- return;
- }
- offset += (pq->buflen + 4);
- msg_count++;
- }
- }
- offset += 4; /* For count. */
-
- buf = talloc(send_ctx, offset);
- if (!buf) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- num_messages = 0;
- return;
- }
-
- offset = 0;
- SIVAL(buf,offset,msg_count);
- offset += 4;
- for (pq = notify_queue_head; pq; pq = pq_next) {
- pq_next = pq->next;
-
- if (strequal(printer, pq->msg->printer)) {
- SIVAL(buf,offset,pq->buflen);
- offset += 4;
- memcpy(buf + offset, pq->buf, pq->buflen);
- offset += pq->buflen;
-
- /* Remove from list. */
- DLIST_REMOVE(notify_queue_head, pq);
- }
- }
-
- DEBUG(5, ("print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s\n",
- (unsigned long)msg_count, msg_count != 1 ? "s" : "", printer));
-
- /*
- * Get the list of PID's to send to.
- */
-
- if (!print_notify_pid_list(printer, send_ctx, &num_pids, &pid_list))
- return;
-
- for (i = 0; i < num_pids; i++) {
- unsigned int q_len = messages_pending_for_pid(pid_list[i]);
- if (q_len > 1000) {
- DEBUG(5, ("print_notify_send_messages_to_printer: discarding notify to printer %s as queue length = %u\n",
- printer, q_len ));
- continue;
- }
- message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
- }
-}
-
-/*******************************************************************
- Actually send the batched messages.
-*******************************************************************/
-
-void print_notify_send_messages(unsigned int timeout)
-{
- if (!print_notify_messages_pending())
- return;
-
- if (!create_send_ctx())
- return;
-
- while (print_notify_messages_pending())
- print_notify_send_messages_to_printer(notify_queue_head->msg->printer, timeout);
-
- talloc_destroy_pool(send_ctx);
- num_messages = 0;
-}
-
-/**********************************************************************
- deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
- *********************************************************************/
-
-static BOOL copy_notify2_msg( SPOOLSS_NOTIFY_MSG *to, SPOOLSS_NOTIFY_MSG *from )
-{
-
- if ( !to || !from )
- return False;
-
- memcpy( to, from, sizeof(SPOOLSS_NOTIFY_MSG) );
-
- if ( from->len ) {
- to->notify.data = talloc_memdup(send_ctx, from->notify.data, from->len );
- if ( !to->notify.data ) {
- DEBUG(0,("copy_notify2_msg: talloc_memdup() of size [%d] failed!\n", from->len ));
- return False;
- }
- }
-
-
- return True;
-}
-
-/*******************************************************************
- Batch up print notify messages.
-*******************************************************************/
-
-static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
-{
- struct notify_queue *pnqueue, *tmp_ptr;
-
- /*
- * Ensure we only have one job total_bytes and job total_pages for
- * each job. There is no point in sending multiple messages that match
- * as they will just cause flickering updates in the client.
- */
-
- if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE) &&
- (msg->field == JOB_NOTIFY_TOTAL_BYTES || msg->field == JOB_NOTIFY_TOTAL_PAGES)) {
-
- for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) {
- if (tmp_ptr->msg->type == msg->type &&
- tmp_ptr->msg->field == msg->field &&
- tmp_ptr->msg->id == msg->id &&
- tmp_ptr->msg->flags == msg->flags &&
- strequal(tmp_ptr->msg->printer, msg->printer)) {
-
- DEBUG(5, ("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for printer %s \
-in notify_queue\n", msg->type, msg->field, msg->printer));
-
- tmp_ptr->msg = msg;
- return;
- }
- }
- }
-
- /* Store the message on the pending queue. */
-
- pnqueue = talloc(send_ctx, sizeof(*pnqueue));
- if (!pnqueue) {
- DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n"));
- return;
- }
-
- /* allocate a new msg structure and copy the fields */
-
- if ( !(pnqueue->msg = (SPOOLSS_NOTIFY_MSG*)talloc(send_ctx, sizeof(SPOOLSS_NOTIFY_MSG))) ) {
- DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%lu] failed!\n",
- (unsigned long)sizeof(SPOOLSS_NOTIFY_MSG)));
- return;
- }
- copy_notify2_msg(pnqueue->msg, msg);
- gettimeofday(&pnqueue->tv, NULL);
- pnqueue->buf = NULL;
- pnqueue->buflen = 0;
-
- DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
-to notify_queue_head\n", msg->type, msg->field, msg->printer));
-
- /*
- * Note we add to the end of the list to ensure
- * the messages are sent in the order they were received. JRA.
- */
-
- DLIST_ADD_END(notify_queue_head, pnqueue, tmp_ptr);
- num_messages++;
-}
-
-static void send_notify_field_values(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 value1,
- uint32 value2, uint32 flags)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->notify.value[0] = value1;
- msg->notify.value[1] = value2;
- msg->flags = flags;
-
- send_spoolss_notify2_msg(msg);
-}
-
-static void send_notify_field_buffer(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 len,
- char *buffer)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->len = len;
- msg->notify.data = buffer;
-
- send_spoolss_notify2_msg(msg);
-}
-
-/* Send a message that the printer status has changed */
-
-void notify_printer_status_byname(const char *printer_name, uint32 status)
-{
- /* Printer status stored in value1 */
-
- send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE,
- PRINTER_NOTIFY_STATUS, 0,
- status, 0, 0);
-}
-
-void notify_printer_status(int snum, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- if (printer_name)
- notify_printer_status_byname(printer_name, status);
-}
-
-void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status,
- uint32 flags)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_STATUS, jobid,
- status, 0, flags);
-}
-
-void notify_job_status(int snum, uint32 jobid, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- notify_job_status_byname(printer_name, jobid, status, 0);
-}
-
-void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_BYTES, jobid,
- size, 0, 0);
-}
-
-void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_PAGES, jobid,
- pages, 0, 0);
-}
-
-void notify_job_username(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_name(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
- jobid, sizeof(submitted), (char *)&submitted);
-}
-
-void notify_printer_driver(int snum, char *driver_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
- snum, strlen(driver_name) + 1, driver_name);
-}
-
-void notify_printer_comment(int snum, char *comment)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
- snum, strlen(comment) + 1, comment);
-}
-
-void notify_printer_sharename(int snum, char *share_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
- snum, strlen(share_name) + 1, share_name);
-}
-
-void notify_printer_port(int snum, char *port_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
- snum, strlen(port_name) + 1, port_name);
-}
-
-void notify_printer_location(int snum, char *location)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
- snum, strlen(location) + 1, location);
-}
-
-void notify_printer_byname( const char *printername, uint32 change, char *value )
-{
- int snum = print_queue_snum(printername);
- int type = PRINTER_NOTIFY_TYPE;
-
- if ( snum == -1 )
- return;
-
- send_notify_field_buffer( printername, type, change, snum, strlen(value)+1, value );
-}
-
-
-/****************************************************************************
- Return a malloced list of pid_t's that are interested in getting update
- messages on this print queue. Used in printing/notify to send the messages.
-****************************************************************************/
-
-BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
-{
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- TDB_DATA data;
- BOOL ret = True;
- size_t i, num_pids, offset;
- pid_t *pid_list;
-
- *p_num_pids = 0;
- *pp_pid_list = NULL;
-
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
-
- if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- if (!data.dptr) {
- ret = True;
- goto done;
- }
-
- num_pids = data.dsize / 8;
-
- if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
- ret = False;
- goto done;
- }
-
- for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
- pid_list[i] = (pid_t)IVAL(data.dptr, offset);
-
- *pp_pid_list = pid_list;
- *p_num_pids = num_pids;
-
- ret = True;
-
- done:
-
- tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index ef709069e94..52a7386010c 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -3,7 +3,6 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Jean François Micouleau 1998-2000.
- * Copyright (C) Gerald Carter 2002-2003.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -77,7 +76,7 @@ STANDARD_MAPPING printserver_std_mapping = {
forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
array index). Letter is always first, so (for the current code) additions
always put things in the correct order. */
-static const nt_forms_struct default_forms[] = {
+static nt_forms_struct default_forms[] = {
{"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
@@ -198,28 +197,6 @@ static const nt_forms_struct default_forms[] = {
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
-struct table_node {
- const char *long_archi;
- const char *short_archi;
- int version;
-};
-
-#define SPL_ARCH_WIN40 "WIN40"
-#define SPL_ARCH_W32X86 "W32X86"
-#define SPL_ARCH_W32MIPS "W32MIPS"
-#define SPL_ARCH_W32ALPHA "W32ALPHA"
-#define SPL_ARCH_W32PPC "W32PPC"
-
-static const struct table_node archi_table[]= {
-
- {"Windows 4.0", SPL_ARCH_WIN40, 0 },
- {"Windows NT x86", SPL_ARCH_W32X86, 2 },
- {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
- {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
- {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
- {NULL, "", -1 }
-};
-
static BOOL upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
@@ -234,12 +211,10 @@ static BOOL upgrade_to_version_3(void)
if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving form\n"));
if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
@@ -248,12 +223,10 @@ static BOOL upgrade_to_version_3(void)
if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving printer\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
@@ -262,12 +235,10 @@ static BOOL upgrade_to_version_3(void)
if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
@@ -280,7 +251,7 @@ static BOOL upgrade_to_version_3(void)
}
/****************************************************************************
- Open the NT printing tdbs. Done once before fork().
+ Open the NT printing tdb.
****************************************************************************/
BOOL nt_printing_init(void)
@@ -291,8 +262,6 @@ BOOL nt_printing_init(void)
if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
return True;
- if (tdb_drivers)
- tdb_close(tdb_drivers);
tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_drivers) {
DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
@@ -300,8 +269,6 @@ BOOL nt_printing_init(void)
return False;
}
- if (tdb_printers)
- tdb_close(tdb_printers);
tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_printers) {
DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
@@ -309,8 +276,6 @@ BOOL nt_printing_init(void)
return False;
}
- if (tdb_forms)
- tdb_close(tdb_forms);
tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_forms) {
DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
@@ -321,7 +286,7 @@ BOOL nt_printing_init(void)
local_pid = sys_getpid();
/* handle a Samba upgrade */
- tdb_lock_bystring(tdb_drivers, vstring, 0);
+ tdb_lock_bystring(tdb_drivers, vstring,0);
{
int32 vers_id;
@@ -349,38 +314,16 @@ BOOL nt_printing_init(void)
update_c_setprinter(True);
- /*
+ /*
* register callback to handle updating printers as new
- * drivers are installed
- */
-
- message_register( MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer );
-
- /*
- * register callback to handle updating printer data
- * when a driver is initialized
+ * drivers are installed
*/
-
- message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
-
+ message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer);
return True;
}
/*******************************************************************
- Function to allow filename parsing "the old way".
-********************************************************************/
-
-static BOOL driver_unix_convert(char *name,connection_struct *conn,
- char *saved_last_component, BOOL *bad_path, SMB_STRUCT_STAT *pst)
-{
- unix_format(name);
- unix_clean_name(name);
- trim_string(name,"/","/");
- return unix_convert(name, conn, saved_last_component, bad_path, pst);
-}
-
-/*******************************************************************
tdb traversal function for counting printers.
********************************************************************/
@@ -409,7 +352,7 @@ uint32 update_c_setprinter(BOOL initialize)
int32 c_setprinter;
int32 printer_count = 0;
- tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER, 0);
+ tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER,0);
/* Traverse the tdb, counting the printers */
tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
@@ -464,7 +407,7 @@ BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
{
int i,count;
fstring form_name;
- unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
+ unistr2_to_dos(form_name, uni_formname, sizeof(form_name)-1);
DEBUGADD(6,("Looking for builtin form %s \n", form_name));
count = sizeof(default_forms) / sizeof(default_forms[0]);
for (i=0;i<count;i++) {
@@ -492,29 +435,25 @@ int get_ntforms(nt_forms_struct **list)
for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
- {
- if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
- continue;
+ newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+ if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
dbuf = tdb_fetch(tdb_forms, kbuf);
- if (!dbuf.dptr)
- continue;
+ if (!dbuf.dptr) continue;
fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
&i, &form.flag, &form.width, &form.length, &form.left,
&form.top, &form.right, &form.bottom);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize)
- continue;
+ if (ret != dbuf.dsize) continue;
tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
if (!tl) {
DEBUG(0,("get_ntforms: Realloc fail.\n"));
return 0;
}
- *list = tl;
+ *list = tl;
(*list)[n] = form;
n++;
}
@@ -541,6 +480,7 @@ int write_ntforms(nt_forms_struct **list, int number)
(*list)[i].bottom);
if (len > sizeof(buf)) break;
slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dsize = strlen(key)+1;
kbuf.dptr = key;
dbuf.dsize = len;
@@ -569,7 +509,7 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
update=False;
- unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
+ unistr2_to_dos(form_name, &form->name, sizeof(form_name)-1);
for (n=0; n<*count; n++) {
if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
@@ -584,7 +524,7 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
return False;
}
*list = tl;
- unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
+ unistr2_to_dos((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
(*count)++;
}
@@ -600,9 +540,8 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
}
/****************************************************************************
- Delete a named form struct.
+ delete a named form struct
****************************************************************************/
-
BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
{
pstring key;
@@ -612,7 +551,7 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
*ret = WERR_OK;
- unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
+ unistr2_to_dos(form_name, del_name, sizeof(form_name)-1);
for (n=0; n<*count; n++) {
if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
@@ -628,6 +567,7 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
}
slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dsize = strlen(key)+1;
kbuf.dptr = key;
if (tdb_delete(tdb_forms, kbuf) != 0) {
@@ -639,17 +579,17 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
}
/****************************************************************************
- Update a form struct.
+update a form struct
****************************************************************************/
-
void update_a_form(nt_forms_struct **list, const FORM *form, int count)
{
int n=0;
fstring form_name;
- unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
+ unistr2_to_dos(form_name, &(form->name), sizeof(form_name)-1);
DEBUG(106, ("[%s]\n", form_name));
- for (n=0; n<count; n++) {
+ for (n=0; n<count; n++)
+ {
DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
break;
@@ -667,26 +607,25 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count)
}
/****************************************************************************
- Get the nt drivers list.
- Traverse the database and look-up the matching names.
+get the nt drivers list
+
+traverse the database and look-up the matching names
****************************************************************************/
-int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
+int get_ntdrivers(fstring **list, char *architecture, uint32 version)
{
int total=0;
- const char *short_archi;
+ fstring short_archi;
fstring *fl;
pstring key;
TDB_DATA kbuf, newkey;
- short_archi = get_short_archi(architecture);
+ get_short_archi(short_archi, architecture);
slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
- continue;
+ if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
@@ -705,29 +644,50 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
function to do the mapping between the long architecture name and
the short one.
****************************************************************************/
-const char *get_short_archi(const char *long_archi)
+
+BOOL get_short_archi(char *short_archi, const char *long_archi)
{
- int i=-1;
+ struct table {
+ const char *long_archi;
+ const char *short_archi;
+ };
+
+ struct table archi_table[]=
+ {
+ {"Windows 4.0", "WIN40" },
+ {"Windows NT x86", "W32X86" },
+ {"Windows NT R4000", "W32MIPS" },
+ {"Windows NT Alpha_AXP", "W32ALPHA" },
+ {"Windows NT PowerPC", "W32PPC" },
+ {NULL, "" }
+ };
+
+ int i=-1;
- DEBUG(107,("Getting architecture dependant directory\n"));
- do {
- i++;
- } while ( (archi_table[i].long_archi!=NULL ) &&
- StrCaseCmp(long_archi, archi_table[i].long_archi) );
+ DEBUG(107,("Getting architecture dependant directory\n"));
- if (archi_table[i].long_archi==NULL) {
- DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
- return NULL;
- }
+ if (long_archi == NULL) {
+ DEBUGADD(107,("Bad long_archi param.!\n"));
+ return False;
+ }
- /* this might be client code - but shouldn't this be an fstrcpy etc? */
+ do {
+ i++;
+ } while ( (archi_table[i].long_archi!=NULL ) &&
+ StrCaseCmp(long_archi, archi_table[i].long_archi) );
+ if (archi_table[i].long_archi==NULL) {
+ DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
+ return False;
+ }
- DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
+ StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
- return archi_table[i].short_archi;
+ DEBUGADD(108,("index: [%d]\n", i));
+ DEBUGADD(108,("long architecture: [%s]\n", long_archi));
+ DEBUGADD(108,("short architecture: [%s]\n", short_archi));
+
+ return True;
}
/****************************************************************************
@@ -741,7 +701,7 @@ const char *get_short_archi(const char *long_archi)
static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
{
int i;
- char *buf = NULL;
+ char *buf;
ssize_t byte_count;
if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
@@ -752,8 +712,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
/* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
+ DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
+ fname, byte_count));
goto no_version_info;
}
@@ -765,7 +725,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (SMB_VFS_LSEEK(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+ if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
fname, errno));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
@@ -773,16 +733,16 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
+ DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
+ fname, byte_count));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
goto no_version_info;
}
/* The header may be a PE (Portable Executable) or an NE (New Executable) */
if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
- unsigned int num_sections;
- unsigned int section_table_bytes;
+ int num_sections;
+ int section_table_bytes;
if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
@@ -796,9 +756,6 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
/* get the section table */
num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
- if (section_table_bytes == 0)
- goto error_exit;
-
SAFE_FREE(buf);
if ((buf=malloc(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
@@ -807,8 +764,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
+ fname, byte_count));
goto error_exit;
}
@@ -817,11 +774,8 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
- unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
- unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
-
- if (section_bytes == 0)
- goto error_exit;
+ int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
+ int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
SAFE_FREE(buf);
if ((buf=malloc(section_bytes)) == NULL) {
@@ -831,21 +785,18 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
}
/* Seek to the start of the .rsrc section info */
- if (SMB_VFS_LSEEK(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+ if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
fname, errno));
goto error_exit;
}
if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
+ fname, byte_count));
goto error_exit;
}
- if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
- goto error_exit;
-
for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
/* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
@@ -927,7 +878,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
* twice, as it is simpler to read the code. */
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
/* Compute skip alignment to next long address */
- int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
+ int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
sizeof(VS_SIGNATURE)) & 3;
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
@@ -971,8 +922,8 @@ is no previous version, the new one is newer (obviously). If either file is
missing the version info structure, compare the creation date (on Unix use
the modification date). Otherwise chose the numerically larger version number.
****************************************************************************/
-
-static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
+static int file_version_is_newer(connection_struct *conn, fstring new_file,
+ fstring old_file)
{
BOOL use_version = True;
pstring filepath;
@@ -1000,12 +951,12 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
/* Get file version info (if available) for previous file (if it exists) */
pstrcpy(filepath, old_file);
- driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
fsp = open_file_shared(conn, filepath, &stat_buf,
SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
+ 0, 0, &access_mode, &action);
if (!fsp) {
/* Old file not found, so by definition new file is in fact newer */
DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
@@ -1020,21 +971,21 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
old_file));
use_version = False;
- if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
- old_create_time = st.st_mtime;
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
+ if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ old_create_time = st.st_mtime;
+ DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
close_file(fsp, True);
/* Get file version info (if available) for new file */
pstrcpy(filepath, new_file);
- driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
fsp = open_file_shared(conn, filepath, &stat_buf,
SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
+ 0, 0, &access_mode, &action);
if (!fsp) {
/* New file not found, this shouldn't occur if the caller did its job */
DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
@@ -1049,10 +1000,10 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
new_file));
use_version = False;
- if (SMB_VFS_FSTAT(fsp, fsp->fd, &st) == -1) goto error_exit;
- new_create_time = st.st_mtime;
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
+ if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ new_create_time = st.st_mtime;
+ DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
close_file(fsp, True);
@@ -1090,19 +1041,22 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
+static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
struct current_user *user, WERROR *perr)
{
int cversion;
int access_mode;
int action;
- NTSTATUS nt_status;
- pstring driverpath;
- DATA_BLOB null_pw;
- fstring res_type;
+ pstring driverpath;
+ fstring user_name;
+ fstring null_pw;
+ fstring dev;
+ fstring sharename;
files_struct *fsp = NULL;
BOOL bad_path;
+ int ecode;
SMB_STRUCT_STAT st;
+ struct passwd *pass;
connection_struct *conn;
ZERO_STRUCT(st);
@@ -1116,26 +1070,39 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
return 0;
}
+ become_root();
+ pass = sys_getpwuid(user->uid);
+ if(pass == NULL) {
+ DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
+ (unsigned int)user->uid ));
+ unbecome_root();
+ *perr = WERR_ACCESS_DENIED;
+ return -1;
+ }
+
/*
* Connect to the print$ share under the same account as the user connected
* to the rpc pipe. Note we must still be root to do this.
*/
+ fstrcpy(user_name, pass->pw_name );
+ DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user->uid, user_name));
+
/* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob(NULL, 0);
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
+ *null_pw = '\0';
+ fstrcpy(dev, "A:");
+ fstrcpy(sharename, "print$");
+ conn = make_connection(sharename, user_name, null_pw, 0, dev, user->vuid, &ecode);
unbecome_root();
if (conn == NULL) {
DEBUG(0,("get_correct_cversion: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ *perr = W_ERROR(ecode);
return -1;
}
/* We are temporarily becoming the connection user. */
- if (!become_user(conn, user->vuid)) {
+ if (!become_user(conn, conn->vuid)) {
DEBUG(0,("get_correct_cversion: Can't become user!\n"));
*perr = WERR_ACCESS_DENIED;
return -1;
@@ -1145,12 +1112,12 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
* deriver the cversion. */
slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
- driver_unix_convert(driverpath,conn,NULL,&bad_path,&st);
+ unix_convert(driverpath,conn,NULL,&bad_path,&st);
fsp = open_file_shared(conn, driverpath, &st,
SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
+ 0, 0, &access_mode, &action);
if (!fsp) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
driverpath, errno));
@@ -1216,7 +1183,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
struct current_user *user)
{
- const char *architecture;
+ fstring architecture;
fstring new_name;
char *p;
int i;
@@ -1256,7 +1223,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
}
}
- architecture = get_short_archi(driver->environment);
+ get_short_archi(architecture, driver->environment);
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
@@ -1278,9 +1245,10 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
+static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
+ struct current_user *user)
{
- const char *architecture;
+ fstring architecture;
fstring new_name;
char *p;
int i;
@@ -1320,7 +1288,7 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
}
}
- architecture = get_short_archi(driver->environment);
+ get_short_archi(architecture, driver->environment);
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
@@ -1333,7 +1301,8 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
* NT 4: cversion=2
* NT2K: cversion=3
*/
- if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
+ if ((driver->version = get_correct_cversion(architecture,
+ driver->driverpath, user, &err)) == -1)
return err;
return WERR_OK;
@@ -1406,18 +1375,19 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
- const char *architecture;
+ fstring architecture;
pstring new_dir;
pstring old_name;
pstring new_name;
- DATA_BLOB null_pw;
+ fstring user_name;
+ fstring null_pw;
+ fstring dev;
+ fstring sharename;
connection_struct *conn;
- NTSTATUS nt_status;
pstring inbuf;
pstring outbuf;
- fstring res_type;
- BOOL bad_path;
- SMB_STRUCT_STAT st;
+ struct passwd *pass;
+ int ecode;
int ver = 0;
int i;
@@ -1435,22 +1405,35 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
return False;
}
- architecture = get_short_archi(driver->environment);
+ get_short_archi(architecture, driver->environment);
+
+ become_root();
+ pass = sys_getpwuid(user->uid);
+ if(pass == NULL) {
+ DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
+ (unsigned int)user->uid ));
+ unbecome_root();
+ return False;
+ }
/*
* Connect to the print$ share under the same account as the user connected to the rpc pipe.
* Note we must be root to do this.
*/
- null_pw = data_blob(NULL, 0);
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
+ fstrcpy(user_name, pass->pw_name );
+ DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
+
+ /* Null password is ok - we are already an authenticated user... */
+ *null_pw = '\0';
+ fstrcpy(dev, "A:");
+ fstrcpy(sharename, "print$");
+ conn = make_connection(sharename, user_name, null_pw, 0, dev, user->vuid, &ecode);
unbecome_root();
if (conn == NULL) {
DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ *perr = W_ERROR(ecode);
return False;
}
@@ -1459,7 +1442,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
*/
if (!become_user(conn, conn->vuid)) {
- DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
+ DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
return False;
}
@@ -1469,7 +1452,6 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
*/
DEBUG(5,("Creating first directory\n"));
slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
- driver_unix_convert(new_dir, conn, NULL, &bad_path, &st);
mkdir_internal(conn, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
@@ -1496,8 +1478,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- status = rename_internals(conn, new_name, old_name, 0, True);
+ status = rename_internals(conn, new_name, old_name, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
@@ -1505,10 +1486,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unlink_internals(conn, 0, new_name);
ver = -1;
}
- } else {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- unlink_internals(conn, 0, new_name);
}
+ else
+ unlink_internals(conn, 0, new_name);
}
if (driver->datafile && strlen(driver->datafile)) {
@@ -1517,8 +1497,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- status = rename_internals(conn, new_name, old_name, 0, True);
+ status = rename_internals(conn, new_name, old_name, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
@@ -1526,10 +1505,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unlink_internals(conn, 0, new_name);
ver = -1;
}
- } else {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- unlink_internals(conn, 0, new_name);
}
+ else
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1540,8 +1518,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- status = rename_internals(conn, new_name, old_name, 0, True);
+ status = rename_internals(conn, new_name, old_name, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
@@ -1549,10 +1526,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unlink_internals(conn, 0, new_name);
ver = -1;
}
- } else {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- unlink_internals(conn, 0, new_name);
}
+ else
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1564,8 +1540,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- status = rename_internals(conn, new_name, old_name, 0, True);
+ status = rename_internals(conn, new_name, old_name, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
@@ -1573,10 +1548,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unlink_internals(conn, 0, new_name);
ver = -1;
}
- } else {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- unlink_internals(conn, 0, new_name);
}
+ else
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1597,8 +1571,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- status = rename_internals(conn, new_name, old_name, 0, True);
+ status = rename_internals(conn, new_name, old_name, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
@@ -1606,10 +1579,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unlink_internals(conn, 0, new_name);
ver = -1;
}
- } else {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- unlink_internals(conn, 0, new_name);
}
+ else
+ unlink_internals(conn, 0, new_name);
}
NextDriver: ;
}
@@ -1626,15 +1598,15 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
int len, buflen;
- const char *architecture;
+ fstring architecture;
pstring directory;
- fstring temp_name;
+ pstring temp_name;
pstring key;
char *buf;
int i, ret;
TDB_DATA kbuf, dbuf;
- architecture = get_short_archi(driver->environment);
+ get_short_archi(architecture, driver->environment);
/* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
* \\server is added in the rpc server layer.
@@ -1677,6 +1649,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
}
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
+ dos_to_unix(key); /* Convert key to unix-codepage */
DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
@@ -1757,13 +1730,13 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *driver, const char *arch)
+static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const fstring in_prt, const fstring in_arch)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
ZERO_STRUCT(info);
- fstrcpy(info.name, driver);
+ fstrcpy(info.name, in_prt);
fstrcpy(info.defaultdatatype, "RAW");
fstrcpy(info.driverpath, "");
@@ -1784,27 +1757,22 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
+static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const fstring in_prt, const fstring in_arch, uint32 version)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA kbuf, dbuf;
- const char *architecture;
+ fstring architecture;
int len = 0;
int i;
pstring key;
ZERO_STRUCT(driver);
- architecture = get_short_archi(arch);
-
- /* Windows 4.0 (i.e. win9x) should always use a version of 0 */
-
- if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 )
- version = 0;
+ get_short_archi(architecture, in_arch);
- DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
+ DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername);
+ slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -1840,16 +1808,15 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
&driver.dependentfiles[i]);
i++;
}
-
if (driver.dependentfiles != NULL)
fstrcpy(driver.dependentfiles[i], "");
SAFE_FREE(dbuf.dptr);
if (len != dbuf.dsize) {
- SAFE_FREE(driver.dependentfiles);
+ SAFE_FREE(driver.dependentfiles);
- return get_a_printer_driver_3_default(info_ptr, drivername, arch);
+ return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
}
*info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
@@ -1858,6 +1825,67 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
}
/****************************************************************************
+****************************************************************************/
+uint32 get_a_printer_driver_9x_compatible(pstring line, const fstring model)
+{
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
+ TDB_DATA kbuf;
+ pstring key;
+ int i;
+ line[0] = '\0';
+
+ slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
+ DEBUG(10,("driver key: [%s]\n", key));
+
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key)+1;
+ if (!tdb_exists(tdb_drivers, kbuf))
+ return False;
+
+ ZERO_STRUCT(info3);
+ get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
+
+ DEBUGADD(10,("info3->name [%s]\n", info3->name));
+ DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
+ DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
+ DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
+ DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
+ for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
+ DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
+ }
+ DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
+ DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
+ DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
+
+ /*pstrcat(line, info3->name); pstrcat(line, ":");*/
+ trim_string(info3->driverpath, "\\print$\\WIN40\\0\\", 0);
+ pstrcat(line, info3->driverpath);
+ pstrcat(line, ":");
+ trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
+ pstrcat(line, info3->datafile);
+ pstrcat(line, ":");
+ trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
+ pstrcat(line, info3->helpfile);
+ pstrcat(line, ":");
+ trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
+ pstrcat(line, info3->monitorname);
+ pstrcat(line, ":");
+ pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
+ pstrcat(line, ":");
+
+ for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
+ if (i)
+ pstrcat(line, ","); /* don't end in a "," */
+ trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
+ pstrcat(line, info3->dependentfiles[i]);
+ }
+
+ SAFE_FREE(info3);
+
+ return True;
+}
+
+/****************************************************************************
Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
@@ -1867,7 +1895,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
int i;
- DEBUG(20,("Dumping printer driver at level [%d]\n", level));
+ DEBUG(106,("Dumping printer driver at level [%d]\n", level));
switch (level)
{
@@ -1878,19 +1906,19 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
else {
info3=driver.info_3;
- DEBUGADD(20,("version:[%d]\n", info3->cversion));
- DEBUGADD(20,("name:[%s]\n", info3->name));
- DEBUGADD(20,("environment:[%s]\n", info3->environment));
- DEBUGADD(20,("driverpath:[%s]\n", info3->driverpath));
- DEBUGADD(20,("datafile:[%s]\n", info3->datafile));
- DEBUGADD(20,("configfile:[%s]\n", info3->configfile));
- DEBUGADD(20,("helpfile:[%s]\n", info3->helpfile));
- DEBUGADD(20,("monitorname:[%s]\n", info3->monitorname));
- DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
+ DEBUGADD(106,("version:[%d]\n", info3->cversion));
+ DEBUGADD(106,("name:[%s]\n", info3->name));
+ DEBUGADD(106,("environment:[%s]\n", info3->environment));
+ DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
+ DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
+ DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
+ DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
+ DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
+ DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
for (i=0; info3->dependentfiles &&
*info3->dependentfiles[i]; i++) {
- DEBUGADD(20,("dependentfile:[%s]\n",
+ DEBUGADD(106,("dependentfile:[%s]\n",
info3->dependentfiles[i]));
}
result=0;
@@ -1898,7 +1926,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
break;
}
default:
- DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
+ DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
result=1;
break;
}
@@ -1908,14 +1936,13 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
/****************************************************************************
****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
+static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
{
int len = 0;
len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
- if (!nt_devmode)
- return len;
+ if (!nt_devmode) return len;
len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
nt_devmode->devicename,
@@ -1969,50 +1996,22 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
}
/****************************************************************************
- Pack all values in all printer keys
- ***************************************************************************/
-
-static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
+****************************************************************************/
+static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
{
- int len = 0;
- int i, j;
- REGISTRY_VALUE *val;
- REGVAL_CTR *val_ctr;
- pstring path;
- int num_values;
-
- if ( !data )
- return 0;
+ int len = 0;
- /* loop over all keys */
-
- for ( i=0; i<data->num_keys; i++ ) {
- val_ctr = &data->keys[i].values;
- num_values = regval_ctr_numvals( val_ctr );
-
- /* loop over all values */
-
- for ( j=0; j<num_values; j++ ) {
- /* pathname should be stored as <key>\<value> */
-
- val = regval_ctr_specific_value( val_ctr, j );
- pstrcpy( path, data->keys[i].name );
- pstrcat( path, "\\" );
- pstrcat( path, regval_name(val) );
-
- len += tdb_pack(buf+len, buflen-len, "pPdB",
- val,
- path,
- regval_type(val),
- regval_size(val),
- regval_data_p(val) );
- }
-
+ while (param != NULL) {
+ len += tdb_pack(buf+len, buflen-len, "pfdB",
+ param,
+ param->value,
+ param->type,
+ param->data_len,
+ param->data);
+ param=param->next;
}
- /* terminator */
-
- len += tdb_pack(buf+len, buflen-len, "p", NULL);
+ len += tdb_pack(buf+len, buflen-len, "p", param);
return len;
}
@@ -2029,6 +2028,7 @@ uint32 del_a_printer(char *sharename)
TDB_DATA kbuf;
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
@@ -2038,7 +2038,7 @@ uint32 del_a_printer(char *sharename)
}
/* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, const char* sharename);
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
/****************************************************************************
****************************************************************************/
@@ -2061,7 +2061,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
if (info->servername[0]!='\0') {
trim_string(info->printername, info->servername, NULL);
- trim_char(info->printername, '\\', '\0');
+ trim_string(info->printername, "\\", NULL);
info->servername[0]='\0';
}
@@ -2106,7 +2106,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
len += pack_devicemode(info->devmode, buf+len, buflen-len);
- len += pack_values( &info->data, buf+len, buflen-len );
+ len += pack_specifics(info->specific, buf+len, buflen-len);
if (buflen != len) {
char *tb;
@@ -2124,6 +2124,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -2146,13 +2147,96 @@ done:
/****************************************************************************
+****************************************************************************/
+void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
+{
+ NT_PRINTER_PARAM *current;
+
+ DEBUG(108,("add_a_specific_param\n"));
+
+ (*param)->next=NULL;
+
+ if (info_2->specific == NULL)
+ {
+ info_2->specific=*param;
+ }
+ else
+ {
+ current=info_2->specific;
+ while (current->next != NULL) {
+ current=current->next;
+ }
+ current->next=*param;
+ }
+
+ *param = NULL;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
+{
+ NT_PRINTER_PARAM *current;
+ NT_PRINTER_PARAM *previous;
+
+ current=info_2->specific;
+ previous=current;
+
+ if (current==NULL) return (False);
+
+ if ( !strcmp(current->value, param->value) &&
+ (strlen(current->value)==strlen(param->value)) ) {
+ DEBUG(109,("deleting first value\n"));
+ info_2->specific=current->next;
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
+ DEBUG(109,("deleted first value\n"));
+ return (True);
+ }
+
+ current=previous->next;
+
+ while ( current!=NULL ) {
+ if (!strcmp(current->value, param->value) &&
+ strlen(current->value)==strlen(param->value) ) {
+ DEBUG(109,("deleting current value\n"));
+ previous->next=current->next;
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
+ DEBUG(109,("deleted current value\n"));
+ return(True);
+ }
+
+ previous=previous->next;
+ current=current->next;
+ }
+ return (False);
+}
+
+/****************************************************************************
+ Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
+****************************************************************************/
+void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
+{
+ NT_PRINTER_PARAM *param = *param_ptr;
+
+ if(param == NULL)
+ return;
+
+ DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
+
+ SAFE_FREE(param->data);
+ SAFE_FREE(*param_ptr);
+}
+
+/****************************************************************************
Malloc and return an NT devicemode.
****************************************************************************/
NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
{
- char adevice[MAXDEVICENAME];
+ char adevice[MAXDEVICENAME+1];
NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
if (nt_devmode == NULL) {
@@ -2216,9 +2300,6 @@ NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
{
NT_DEVICEMODE *new_nt_devicemode = NULL;
- if ( !nt_devicemode )
- return NULL;
-
if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
return NULL;
@@ -2249,7 +2330,7 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
- SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(nt_devmode->private);
SAFE_FREE(*devmode_ptr);
}
@@ -2259,39 +2340,34 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
{
NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
- NT_PRINTER_DATA *data;
- int i;
+ NT_PRINTER_PARAM *param_ptr;
- if ( !info )
+ if(info == NULL)
return;
DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
free_nt_devicemode(&info->devmode);
- /* clean up all registry keys */
-
- data = &info->data;
- for ( i=0; i<data->num_keys; i++ ) {
- SAFE_FREE( data->keys[i].name );
- regval_ctr_destroy( &data->keys[i].values );
+ for(param_ptr = info->specific; param_ptr; ) {
+ NT_PRINTER_PARAM *tofree = param_ptr;
+
+ param_ptr = param_ptr->next;
+ free_nt_printer_param(&tofree);
}
- SAFE_FREE( data->keys );
- /* finally the top level structure */
-
- SAFE_FREE( *info_ptr );
+ SAFE_FREE(*info_ptr);
}
/****************************************************************************
****************************************************************************/
-int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
+static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
{
int len = 0;
int extra_len = 0;
NT_DEVICEMODE devmode;
-
+
ZERO_STRUCT(devmode);
len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
@@ -2360,759 +2436,32 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
}
/****************************************************************************
- Allocate and initialize a new slot.
-***************************************************************************/
-
-static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
- NT_PRINTER_KEY *d;
- int key_index;
-
- if ( !data || !name )
- return -1;
-
- /* allocate another slot in the NT_PRINTER_KEY array */
-
- d = Realloc( data->keys, sizeof(NT_PRINTER_KEY)*(data->num_keys+1) );
- if ( d )
- data->keys = d;
-
- key_index = data->num_keys;
-
- /* initialze new key */
-
- data->num_keys++;
- data->keys[key_index].name = strdup( name );
-
- ZERO_STRUCTP( &data->keys[key_index].values );
-
- regval_ctr_init( &data->keys[key_index].values );
-
- DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-
- return key_index;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-
-int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
-{
- int key_index = -1;
- int i;
-
- if ( !data || !name )
- return -1;
-
- DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
-
- /* loop over all existing keys */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( strequal(data->keys[i].name, name) ) {
- DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
- key_index = i;
- break;
-
- }
- }
-
- return key_index;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
-{
- int i, j;
- int key_len;
- int num_subkeys = 0;
- char *p;
- fstring *ptr, *subkeys_ptr = NULL;
- fstring subkeyname;
-
- if ( !data )
- return 0;
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
- /* match sure it is a subkey and not the key itself */
-
- key_len = strlen( key );
- if ( strlen(data->keys[i].name) == key_len )
- continue;
-
- /* get subkey path */
-
- p = data->keys[i].name + key_len;
- if ( *p == '\\' )
- p++;
- fstrcpy( subkeyname, p );
- if ( (p = strchr( subkeyname, '\\' )) )
- *p = '\0';
-
- /* don't add a key more than once */
-
- for ( j=0; j<num_subkeys; j++ ) {
- if ( strequal( subkeys_ptr[j], subkeyname ) )
- break;
- }
-
- if ( j != num_subkeys )
- continue;
-
- /* found a match, so allocate space and copy the name */
-
- if ( !(ptr = Realloc( subkeys_ptr, (num_subkeys+2)*sizeof(fstring))) ) {
- DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
- num_subkeys+1));
- SAFE_FREE( subkeys );
- return 0;
- }
-
- subkeys_ptr = ptr;
- fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
- num_subkeys++;
- }
-
- }
-
- /* tag of the end */
-
- if (num_subkeys)
- fstrcpy(subkeys_ptr[num_subkeys], "" );
-
- *subkeys = subkeys_ptr;
-
- return num_subkeys;
-}
-
-#ifdef HAVE_ADS
-static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
- const char *sz)
-{
- smb_ucs2_t conv_str[1024];
- size_t str_size;
-
- regval_ctr_delvalue(ctr, val_name);
- str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
- STR_TERMINATE | STR_NOALIGN);
- regval_ctr_addvalue(ctr, val_name, REG_SZ,
- (char *) conv_str, str_size);
-}
-
-static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
- uint32 dword)
-{
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_DWORD,
- (char *) &dword, sizeof(dword));
-}
-
-static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
- BOOL b)
-{
- uint8 bin_bool = (b ? 1 : 0);
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_BINARY,
- (char *) &bin_bool, sizeof(bin_bool));
-}
-
-static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
- const char *multi_sz)
-{
- smb_ucs2_t *conv_strs = NULL;
- size_t str_size;
-
- /* a multi-sz has to have a null string terminator, i.e., the last
- string must be followed by two nulls */
- str_size = (strlen(multi_sz) + 2) * sizeof(smb_ucs2_t);
- conv_strs = calloc(str_size, 1);
-
- push_ucs2(NULL, conv_strs, multi_sz, str_size,
- STR_TERMINATE | STR_NOALIGN);
-
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
- (char *) conv_strs, str_size);
- safe_free(conv_strs);
-
-}
-
-/****************************************************************************
- * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
- *
- * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
- * @return BOOL indicating success or failure
- ***************************************************************************/
-
-static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
-{
- REGVAL_CTR *ctr = NULL;
- fstring longname;
- char *allocated_string = NULL;
- const char *ascii_str;
- int i;
-
- if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = &info2->data.keys[i].values;
-
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
- map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
-
- get_mydnsfullname(longname);
- map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
-
- asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
- map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
- SAFE_FREE(allocated_string);
-
- map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
- map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
- map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
- map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
- map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
- map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
- map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
- map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
-
- map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
- (info2->attributes &
- PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
-
- switch (info2->attributes & 0x3) {
- case 0:
- ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
- break;
- case 1:
- ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
- break;
- case 2:
- ascii_str = SPOOL_REGVAL_PRINTDIRECT;
- break;
- default:
- ascii_str = "unknown";
- }
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
-
- return True;
-}
-
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
- struct uuid guid)
-{
- int i;
- REGVAL_CTR *ctr=NULL;
-
- /* find the DsSpooler key */
- if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = &info2->data.keys[i].values;
-
- regval_ctr_delvalue(ctr, "objectGUID");
- regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
- (char *) &guid, sizeof(struct uuid));
-}
-
-static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
-{
- ADS_STATUS ads_rc;
- TALLOC_CTX *ctx = talloc_init("publish_it");
- ADS_MODLIST mods = ads_init_mods(ctx);
- char *prt_dn = NULL, *srv_dn, *srv_cn_0;
- char *srv_dn_utf8, **srv_cn_utf8;
- void *res = NULL;
- ADS_STRUCT *ads;
- const char *attrs[] = {"objectGUID", NULL};
- struct uuid guid;
- WERROR win_rc = WERR_OK;
-
- ZERO_STRUCT(guid);
- /* set the DsSpooler info and attributes */
- if (!(map_nt_printer_info2_to_dsspooler(printer->info_2)))
- return WERR_NOMEM;
- printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- /* Build the ads mods */
- get_local_printer_publishing_data(ctx, &mods,
- &printer->info_2->data);
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
- printer->info_2->sharename);
-
- /* initial ads structure */
-
- ads = ads_init(NULL, NULL, NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- return WERR_SERVER_UNAVAILABLE;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
-
- /* figure out where to publish */
- ads_find_machine_acct(ads, &res, global_myname());
-
- /* We use ldap_get_dn here as we need the answer
- * in utf8 to call ldap_explode_dn(). JRA. */
-
- srv_dn_utf8 = ldap_get_dn(ads->ld, res);
- if (!srv_dn_utf8) {
- ads_destroy(&ads);
- return WERR_SERVER_UNAVAILABLE;
- }
- ads_msgfree(ads, res);
- srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
- if (!srv_cn_utf8) {
- ldap_memfree(srv_dn_utf8);
- ads_destroy(&ads);
- return WERR_SERVER_UNAVAILABLE;
- }
- /* Now convert to CH_UNIX. */
- if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) {
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
- ads_destroy(&ads);
- return WERR_SERVER_UNAVAILABLE;
- }
- if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
- ads_destroy(&ads);
- SAFE_FREE(srv_dn);
- return WERR_SERVER_UNAVAILABLE;
- }
-
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
-
- asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_0,
- printer->info_2->sharename, srv_dn);
-
- SAFE_FREE(srv_dn);
- SAFE_FREE(srv_cn_0);
-
- /* publish it */
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
-
- /* retreive the guid and store it locally */
- if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
- ads_memfree(ads, prt_dn);
- ads_pull_guid(ads, res, &guid);
- ads_msgfree(ads, res);
- store_printer_guid(printer->info_2, guid);
- win_rc = mod_a_printer(*printer, 2);
- }
-
- safe_free(prt_dn);
- ads_destroy(&ads);
-
- return WERR_OK;
-}
-
-WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
-{
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads;
- void *res;
- char *prt_dn = NULL;
- WERROR win_rc;
-
- printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- ads = ads_init(NULL, NULL, NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- return WERR_SERVER_UNAVAILABLE;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
-
- /* remove the printer from the directory */
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer->info_2->sharename, global_myname());
- if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
- prt_dn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
- ads_rc = ads_del_dn(ads, prt_dn);
- ads_memfree(ads, prt_dn);
- }
-
- ads_destroy(&ads);
- return WERR_OK;
-}
-
-/****************************************************************************
- * Publish a printer in the directory
- *
- * @param snum describing printer service
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR win_rc;
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- return win_rc;
-
- switch(action) {
- case SPOOL_DS_PUBLISH:
- case SPOOL_DS_UPDATE:
- win_rc = publish_it(printer);
- break;
- case SPOOL_DS_UNPUBLISH:
- win_rc = unpublish_it(printer);
- break;
- default:
- win_rc = WERR_NOT_SUPPORTED;
- }
-
-
- free_a_printer(&printer, 2);
- return win_rc;
-}
-
-BOOL is_printer_published(Printer_entry *print_hnd, int snum,
- struct uuid *guid)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- REGVAL_CTR *ctr;
- REGISTRY_VALUE *guid_val;
- WERROR win_rc;
- int i;
-
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- return False;
-
- if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- return False;
-
- if ((i = lookup_printerkey(&printer->info_2->data,
- SPOOL_DSSPOOLER_KEY)) < 0)
- return False;
-
- if (!(ctr = &printer->info_2->data.keys[i].values)) {
- return False;
- }
-
- if (!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
- return False;
- }
-
- if (regval_size(guid_val) == sizeof(struct uuid))
- memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
-
- return True;
-}
-
-#else
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- return WERR_OK;
-}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum,
- struct uuid *guid)
-{
- return False;
-}
-#endif
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
-{
- NT_PRINTER_DATA *data;
- int i;
- int removed_keys = 0;
- int empty_slot;
-
- data = &p2->data;
- empty_slot = data->num_keys;
-
- if ( !key )
- return WERR_INVALID_PARAM;
-
- /* remove all keys */
-
- if ( !strlen(key) ) {
- for ( i=0; i<data->num_keys; i++ ) {
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
- data->keys[i].name));
-
- SAFE_FREE( data->keys[i].name );
- regval_ctr_destroy( &data->keys[i].values );
- }
-
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
- p2->printername ));
-
- SAFE_FREE( data->keys );
- ZERO_STRUCTP( data );
-
- return WERR_OK;
- }
-
- /* remove a specific key (and all subkeys) */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
- data->keys[i].name));
-
- SAFE_FREE( data->keys[i].name );
- regval_ctr_destroy( &data->keys[i].values );
-
- /* mark the slot as empty */
-
- ZERO_STRUCTP( &data->keys[i] );
- }
- }
-
- /* find the first empty slot */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( !data->keys[i].name ) {
- empty_slot = i;
- removed_keys++;
- break;
- }
- }
-
- if ( i == data->num_keys )
- /* nothing was removed */
- return WERR_INVALID_PARAM;
-
- /* move everything down */
-
- for ( i=empty_slot+1; i<data->num_keys; i++ ) {
- if ( data->keys[i].name ) {
- memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
- ZERO_STRUCTP( &data->keys[i] );
- empty_slot++;
- removed_keys++;
- }
- }
-
- /* update count */
-
- data->num_keys -= removed_keys;
-
- /* sanity check to see if anything is left */
-
- if ( !data->num_keys ) {
- DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
-
- SAFE_FREE( data->keys );
- ZERO_STRUCTP( data );
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
- WERROR result = WERR_OK;
- int key_index;
-
- /* we must have names on non-zero length */
-
- if ( !key || !*key|| !value || !*value )
- return WERR_INVALID_NAME;
-
- /* find the printer key first */
-
- key_index = lookup_printerkey( &p2->data, key );
- if ( key_index == -1 )
- return WERR_OK;
-
- /* make sure the value exists so we can return the correct error code */
-
- if ( !regval_ctr_getvalue( &p2->data.keys[key_index].values, value ) )
- return WERR_BADFILE;
-
- regval_ctr_delvalue( &p2->data.keys[key_index].values, value );
-
- DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
- key, value ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
- uint32 type, uint8 *data, int real_len )
-{
- WERROR result = WERR_OK;
- int key_index;
-
- /* we must have names on non-zero length */
-
- if ( !key || !*key|| !value || !*value )
- return WERR_INVALID_NAME;
-
- /* find the printer key first */
-
- key_index = lookup_printerkey( &p2->data, key );
- if ( key_index == -1 )
- key_index = add_new_printer_key( &p2->data, key );
-
- if ( key_index == -1 )
- return WERR_NOMEM;
-
- regval_ctr_addvalue( &p2->data.keys[key_index].values, value,
- type, (const char *)data, real_len );
-
- DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
- key, value, type, real_len ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
+****************************************************************************/
+static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
{
- int key_index;
-
- if ( (key_index = lookup_printerkey( &p2->data, key )) == -1 )
- return NULL;
-
- DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
- key, value ));
-
- return regval_ctr_getvalue( &p2->data.keys[key_index].values, value );
-}
+ int len = 0;
+ NT_PRINTER_PARAM param, *p;
-/****************************************************************************
- Unpack a list of registry values frem the TDB
- ***************************************************************************/
-
-static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
-{
- int len = 0;
- uint32 type;
- pstring string, valuename, keyname;
- char *str;
- int size;
- uint8 *data_p;
- REGISTRY_VALUE *regval_p;
- int key_index;
-
- /* add the "PrinterDriverData" key first for performance reasons */
-
- add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
+ *list = NULL;
- /* loop and unpack the rest of the registry values */
-
- while ( True ) {
-
- /* check to see if there are any more registry values */
-
- len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
- if ( !regval_p )
- break;
+ while (1) {
+ len += tdb_unpack(buf+len, buflen-len, "p", &p);
+ if (!p) break;
- /* unpack the next regval */
-
len += tdb_unpack(buf+len, buflen-len, "fdB",
- string,
- &type,
- &size,
- &data_p);
-
- /*
- * break of the keyname from the value name.
- * Should only be one '\' in the string returned.
- */
-
- str = strrchr( string, '\\');
-
- /* Put in "PrinterDriverData" is no key specified */
-
- if ( !str ) {
- pstrcpy( keyname, SPOOL_PRINTERDATA_KEY );
- pstrcpy( valuename, string );
- }
- else {
- *str = '\0';
- pstrcpy( keyname, string );
- pstrcpy( valuename, str+1 );
- }
-
- /* see if we need a new key */
-
- if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
- key_index = add_new_printer_key( printer_data, keyname );
-
- if ( key_index == -1 ) {
- DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
- keyname));
- break;
- }
-
- /* add the new value */
-
- regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
-
- SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
+ param.value,
+ &param.type,
+ &param.data_len,
+ &param.data);
+ param.next = *list;
+ *list = memdup(&param, sizeof(param));
- DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
+ DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
}
return len;
}
-/****************************************************************************
- ***************************************************************************/
-
static void map_to_os2_driver(fstring drivername)
{
static BOOL initialised=False;
@@ -3139,7 +2488,7 @@ static void map_to_os2_driver(fstring drivername)
return;
}
- lines = file_lines_load(mapfile, &numlines);
+ lines = file_lines_load(mapfile, &numlines, True);
if (numlines == 0) {
DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
return;
@@ -3195,9 +2544,9 @@ static void map_to_os2_driver(fstring drivername)
}
/****************************************************************************
- Get a default printer info 2 struct.
+get a default printer info 2 struct
****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
{
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
@@ -3211,6 +2560,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const
get_called_name(), sharename);
fstrcpy(info.sharename, sharename);
fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
+ fstrcpy(info.drivername, lp_printerdriver(snum));
/* by setting the driver name to an empty string, a local NT admin
can now run the **local** APW to install a local printer driver
@@ -3228,7 +2578,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const
fstrcpy(info.printprocessor, "winprint");
fstrcpy(info.datatype, "RAW");
- info.attributes = PRINTER_ATTRIBUTE_SAMBA;
+ info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; /* attributes */
info.starttime = 0; /* Minutes since 12:00am GMT */
info.untiltime = 0; /* Minutes since 12:00am GMT */
@@ -3276,18 +2626,18 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
{
pstring key;
NT_PRINTER_INFO_LEVEL_2 info;
int len = 0;
TDB_DATA kbuf, dbuf;
fstring printername;
- char adevice[MAXDEVICENAME];
ZERO_STRUCT(info);
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -3321,14 +2671,14 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sh
info.parameters);
/* Samba has to have shared raw drivers. */
- info.attributes = PRINTER_ATTRIBUTE_SAMBA;
+ info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK);
/* Restore the stripped strings. */
slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
info.printername);
fstrcpy(info.printername, printername);
-
+
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
@@ -3339,21 +2689,17 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sh
* See comments in get_a_printer_2_default()
*/
- if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode) {
+ if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
+ {
DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
printername));
info.devmode = construct_nt_devicemode(printername);
}
- safe_strcpy(adevice, info.printername, sizeof(adevice)-1);
- if (info.devmode) {
- fstrcpy(info.devmode->devicename, adevice);
- }
-
- len += unpack_values( &info.data, dbuf.dptr+len, dbuf.dsize-len );
+ len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
/* This will get the current RPC talloc context, but we should be
- passing this as a parameter... fixme... JRA ! */
+ passing this as a parameter... fixme... JRA ! */
nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
@@ -3372,7 +2718,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sh
}
/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
+debugging function, dump at level 6 the struct in the logs
****************************************************************************/
static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
@@ -3381,7 +2727,8 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
DEBUG(106,("Dumping printer at level [%d]\n", level));
- switch (level) {
+ switch (level)
+ {
case 2:
{
if (printer.info_2 == NULL)
@@ -3427,6 +2774,26 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
}
/****************************************************************************
+ Get the parameters we can substitute in an NT print job.
+****************************************************************************/
+
+void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+
+ **printername = **sharename = **portname = '\0';
+
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ return;
+
+ fstrcpy(*printername, printer->info_2->printername);
+ fstrcpy(*sharename, printer->info_2->sharename);
+ fstrcpy(*portname, printer->info_2->portname);
+
+ free_a_printer(&printer, 2);
+}
+
+/****************************************************************************
Update the changeid time.
This is SO NASTY as some drivers need this to change, others need it
static. This value will change every second, and I must hope that this
@@ -3469,15 +2836,8 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
dump_a_printer(printer, level);
- /*
- * invalidate cache for all open handles to this printer.
- * cache for a given handle will be updated on the next
- * get_a_printer()
- */
-
- invalidate_printer_hnd_cache( printer.info_2->sharename );
-
- switch (level) {
+ switch (level)
+ {
case 2:
{
/*
@@ -3512,7 +2872,6 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
*/
result=update_a_printer_2(printer.info_2);
-
break;
}
default:
@@ -3527,25 +2886,29 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
Initialize printer devmode & data with previously saved driver init values.
****************************************************************************/
-static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
+static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
{
int len = 0;
pstring key;
TDB_DATA kbuf, dbuf;
+ NT_PRINTER_PARAM *current;
NT_PRINTER_INFO_LEVEL_2 info;
-
- ZERO_STRUCT(info);
-
/*
- * Delete any printer data 'values' already set. When called for driver
+ * Delete any printer data 'specifics' already set. When called for driver
* replace, there will generally be some, but during an add printer, there
* should not be any (if there are delete them).
*/
-
- delete_all_printer_data( info_ptr, "" );
-
+ while ( (current=info_ptr->specific) != NULL ) {
+ info_ptr->specific=current->next;
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
+ }
+
+ ZERO_STRUCT(info);
+
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -3559,47 +2922,70 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
free_nt_devicemode(&info_ptr->devmode);
return False;
}
-
+
/*
* Get the saved DEVMODE..
*/
-
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
* The saved DEVMODE contains the devicename from the printer used during
* the initialization save. Change it to reflect the new printer.
*/
-
- if ( info.devmode ) {
- ZERO_STRUCT(info.devmode->devicename);
- fstrcpy(info.devmode->devicename, info_ptr->printername);
- }
+ ZERO_STRUCT(info.devmode->devicename);
+ fstrcpy(info.devmode->devicename, info_ptr->printername);
+
/*
* NT/2k does not change out the entire DeviceMode of a printer
* when changing the driver. Only the driverextra, private, &
* driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
*
- * Later examination revealed that Windows NT/2k does reset the
+ * Later e4xamination revealed that Windows NT/2k does reset the
* the printer's device mode, bit **only** when you change a
* property of the device mode such as the page orientation.
* --jerry
*/
+#if 1 /* JERRY */
- /* Bind the saved DEVMODE to the new the printer */
-
+ /*
+ * Bind the saved DEVMODE to the new the printer.
+ */
free_nt_devicemode(&info_ptr->devmode);
info_ptr->devmode = info.devmode;
+#else
+ /* copy the entire devmode if we currently don't have one */
- DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
- info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
+ if (!info_ptr->devmode) {
+ DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
+ info_ptr->devmode = info.devmode;
+ }
+ else {
+ /* only set the necessary fields */
- /* Add the printer data 'values' to the new printer */
-
- len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
+ DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
+ info.devmode->driverversion, info.devmode->driverextra));
+
+ info_ptr->devmode->driverversion = info.devmode->driverversion;
+
+ SAFE_FREE(info_ptr->devmode->private);
+ info_ptr->devmode->private = NULL;
+
+ if (info.devmode->driverversion)
+ info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
+
+ free_nt_devicemode(&info.devmode);
+ }
+#endif
+
+ DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
+ info_ptr->printername, info_ptr->drivername));
+
+ /*
+ * Add the printer data 'specifics' to the new printer
+ */
+ len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
SAFE_FREE(dbuf.dptr);
@@ -3617,7 +3003,8 @@ BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
BOOL result = False;
- switch (level) {
+ switch (level)
+ {
case 2:
result = set_driver_init_2(printer->info_2);
break;
@@ -3646,6 +3033,7 @@ BOOL del_driver_init(char *drivername)
}
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -3656,7 +3044,7 @@ BOOL del_driver_init(char *drivername)
}
/****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry
+ Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
in the tdb. Note: this is different from the driver entry and the printer
entry. There should be a single driver init entry for each driver regardless
of whether it was installed from NT or 2K. Technically, they should be
@@ -3677,7 +3065,7 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
len = 0;
len += pack_devicemode(info->devmode, buf+len, buflen-len);
- len += pack_values( &info->data, buf+len, buflen-len );
+ len += pack_specifics(info->specific, buf+len, buflen-len);
if (buflen != len) {
char *tb;
@@ -3688,13 +3076,13 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
ret = -1;
goto done;
}
- else
- buf = tb;
+ else buf = tb;
buflen = len;
goto again;
}
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
+ dos_to_unix(key); /* Convert key to unix-codepage */
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
@@ -3709,14 +3097,14 @@ done:
SAFE_FREE(buf);
- DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
+ DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
info->sharename, info->drivername));
return ret;
}
/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and values) for a printer
+ Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
****************************************************************************/
uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
@@ -3725,12 +3113,15 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
dump_a_printer(printer, level);
- switch (level) {
+ switch (level)
+ {
case 2:
- result = update_driver_init_2(printer.info_2);
+ {
+ result=update_driver_init_2(printer.info_2);
break;
+ }
default:
- result = 1;
+ result=1;
break;
}
@@ -3743,7 +3134,7 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
got to keep the endians happy :).
****************************************************************************/
-static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
+static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
{
BOOL result = False;
prs_struct ps;
@@ -3752,8 +3143,8 @@ static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uin
ZERO_STRUCT(devmode);
prs_init(&ps, 0, ctx, UNMARSHALL);
- ps.data_p = (char *)data;
- ps.buffer_size = data_len;
+ ps.data_p = (char *)param->data;
+ ps.buffer_size = param->data_len;
if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
result = convert_devicemode("", &devmode, &nt_devmode);
@@ -3785,7 +3176,7 @@ static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uin
about it and you will realize why. JRR 010720
****************************************************************************/
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
+static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
{
WERROR status = WERR_OK;
TALLOC_CTX *ctx = NULL;
@@ -3795,29 +3186,28 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
/*
* When the DEVMODE is already set on the printer, don't try to unpack it.
*/
- DEBUG(8,("save_driver_init_2: Enter...\n"));
-
- if ( !printer->info_2->devmode && data_len ) {
+
+ if (!printer->info_2->devmode && param->data_len) {
/*
* Set devmode on printer info, so entire printer initialization can be
* saved to tdb.
*/
- if ((ctx = talloc_init("save_driver_init_2")) == NULL)
+ if ((ctx = talloc_init()) == NULL)
return WERR_NOMEM;
if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
status = WERR_NOMEM;
goto done;
}
-
+
ZERO_STRUCTP(nt_devmode);
/*
* The DEVMODE is held in the 'data' component of the param in raw binary.
* Convert it to to a devmode structure
*/
- if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
+ if (!convert_driver_init(param, ctx, nt_devmode)) {
DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
status = WERR_INVALID_PARAM;
goto done;
@@ -3832,7 +3222,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
*
*/
- if ( update_driver_init(*printer, 2) != 0 ) {
+ if (update_driver_init(*printer, 2)!=0) {
DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
status = WERR_NOMEM;
goto done;
@@ -3849,10 +3239,15 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
printer->info_2->printername));
}
+#if 0 /* JERRY */
+ srv_spoolss_sendnotify(p, handle);
+#endif
+
done:
talloc_destroy(ctx);
- free_nt_devicemode( &nt_devmode );
-
+ if (nt_devmode)
+ SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(nt_devmode);
printer->info_2->devmode = tmp_devmode;
return status;
@@ -3862,16 +3257,19 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
Update the driver init info (DEVMODE and specifics) for a printer
****************************************************************************/
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
+WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
{
WERROR status = WERR_OK;
- switch (level) {
+ switch (level)
+ {
case 2:
- status = save_driver_init_2( printer, data, data_len );
+ {
+ status=save_driver_init_2(printer, param);
break;
+ }
default:
- status = WERR_UNKNOWN_LEVEL;
+ status=WERR_UNKNOWN_LEVEL;
break;
}
@@ -3879,87 +3277,10 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
}
/****************************************************************************
- Deep copy a NT_PRINTER_DATA
-****************************************************************************/
-
-static NTSTATUS copy_printer_data( NT_PRINTER_DATA *dst, NT_PRINTER_DATA *src )
-{
- int i, j, num_vals, new_key_index;
- REGVAL_CTR *src_key, *dst_key;
-
- if ( !dst || !src )
- return NT_STATUS_NO_MEMORY;
-
- for ( i=0; i<src->num_keys; i++ ) {
-
- /* create a new instance of the printerkey in the destination
- printer_data object */
-
- new_key_index = add_new_printer_key( dst, src->keys[i].name );
- dst_key = &dst->keys[new_key_index].values;
-
- src_key = &src->keys[i].values;
- num_vals = regval_ctr_numvals( src_key );
-
- /* dup the printer entire printer key */
-
- for ( j=0; j<num_vals; j++ ) {
- regval_ctr_copyvalue( dst_key, regval_ctr_specific_value(src_key, j) );
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Deep copy a NT_PRINTER_INFO_LEVEL_2 structure using malloc()'d memeory
- Caller must free.
-****************************************************************************/
-
-NT_PRINTER_INFO_LEVEL_2* dup_printer_2( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 *printer )
-{
- NT_PRINTER_INFO_LEVEL_2 *copy;
-
- if ( !printer )
- return NULL;
-
- if ( !(copy = (NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2))) )
- return NULL;
-
- memcpy( copy, printer, sizeof(NT_PRINTER_INFO_LEVEL_2) );
-
- /* malloc()'d members copied here */
-
- copy->devmode = dup_nt_devicemode( printer->devmode );
-
- ZERO_STRUCT( copy->data );
- copy_printer_data( &copy->data, &printer->data );
-
- /* this is talloc()'d; very ugly that we have a structure that
- is half malloc()'d and half talloc()'d but that is the way
- that the PRINTER_INFO stuff is written right now. --jerry */
-
- copy->secdesc_buf = dup_sec_desc_buf( ctx, printer->secdesc_buf );
-
- return copy;
-}
-
-/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
-
- Previously the code had a memory allocation problem because it always
- used the TALLOC_CTX from the Printer_entry*. This context lasts
- as a long as the original handle is open. So if the client made a lot
- of getprinter[data]() calls, the memory usage would climb. Now we use
- a short lived TALLOC_CTX for printer_info_2 objects returned. We
- still use the Printer_entry->ctx for maintaining the cache copy though
- since that object must live as long as the handle by definition.
- --jerry
-
****************************************************************************/
-WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
- const char *sharename)
+WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
{
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
@@ -3968,82 +3289,24 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
- switch (level) {
+ switch (level)
+ {
case 2:
+ {
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
DEBUG(0,("get_a_printer: malloc fail.\n"));
return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
-
- /*
- * check for cache first. A Printer handle cannot changed
- * to another printer object so we only check that the printer
- * is actually for a printer and that the printer_info pointer
- * is valid
- */
- if ( print_hnd
- && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)
- && print_hnd->printer_info )
- {
- /* get_talloc_ctx() works here because we need a short
- lived talloc context */
-
- if ( !(printer->info_2 = dup_printer_2(get_talloc_ctx(), print_hnd->printer_info->info_2)) )
- {
- DEBUG(0,("get_a_printer: unable to copy cached printer info!\n"));
-
- SAFE_FREE(printer);
- return WERR_NOMEM;
- }
-
- DEBUG(10,("get_a_printer: using cached copy of printer_info_2\n"));
-
- *pp_printer = printer;
- result = WERR_OK;
-
- break;
- }
-
- /* no cache for this handle; see if we can match one from another handle.
- Make sure to use a short lived talloc ctx */
-
- if ( print_hnd )
- result = find_printer_in_print_hnd_cache(get_talloc_ctx(), &printer->info_2, sharename);
-
- /* fail to disk if we don't have it with any open handle */
-
- if ( !print_hnd || !W_ERROR_IS_OK(result) )
- result = get_a_printer_2(&printer->info_2, sharename);
-
- /* we have a new printer now. Save it with this handle */
-
- if ( W_ERROR_IS_OK(result) ) {
+ result=get_a_printer_2(&printer->info_2, sharename);
+ if (W_ERROR_IS_OK(result)) {
dump_a_printer(*printer, level);
-
- /* save a copy in cache */
- if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {
- if ( !print_hnd->printer_info )
- print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL));
-
- if ( print_hnd->printer_info ) {
- /* make sure to use the handle's talloc ctx here since
- the printer_2 object must last until the handle is closed */
-
- print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2);
-
- /* don't fail the lookup just because the cache update failed */
- if ( !print_hnd->printer_info->info_2 )
- DEBUG(0,("get_a_printer: unable to copy new printer info!\n"));
- }
- }
- *pp_printer = printer;
- }
- else
+ *pp_printer = printer;
+ } else {
SAFE_FREE(printer);
-
+ }
break;
-
+ }
default:
result=WERR_UNKNOWN_LEVEL;
break;
@@ -4068,15 +3331,21 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
if (printer == NULL)
return 0;
- switch (level) {
+ switch (level)
+ {
case 2:
- if (printer->info_2 != NULL) {
+ {
+ if (printer->info_2 != NULL)
+ {
free_nt_printer_info_level_2(&printer->info_2);
result=0;
- } else
+ }
+ else
+ {
result=4;
+ }
break;
-
+ }
default:
result=1;
break;
@@ -4094,15 +3363,19 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
DEBUG(104,("adding a printer at level [%d]\n", level));
dump_a_printer_driver(driver, level);
- switch (level) {
+ switch (level)
+ {
case 3:
+ {
result=add_a_printer_driver_3(driver.info_3);
break;
+ }
case 6:
+ {
result=add_a_printer_driver_6(driver.info_6);
break;
-
+ }
default:
result=1;
break;
@@ -4112,13 +3385,13 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
}
/****************************************************************************
****************************************************************************/
-
WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
- fstring drivername, const char *architecture, uint32 version)
+ fstring drivername, const fstring architecture, uint32 version)
{
WERROR result;
- switch (level) {
+ switch (level)
+ {
case 3:
/* Sometime we just want any version of the driver */
@@ -4131,7 +3404,8 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
result = get_a_printer_driver_3( &driver->info_3,
drivername, architecture, 2 );
}
- } else {
+ }
+ else {
result = get_a_printer_driver_3(&driver->info_3, drivername,
architecture, version);
}
@@ -4154,7 +3428,8 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
{
uint32 result;
- switch (level) {
+ switch (level)
+ {
case 3:
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
@@ -4165,7 +3440,9 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
ZERO_STRUCTP(info3);
SAFE_FREE(info3);
result=0;
- } else {
+ }
+ else
+ {
result=4;
}
break;
@@ -4173,14 +3450,17 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
case 6:
{
NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
- if (driver.info_6 != NULL) {
+ if (driver.info_6 != NULL)
+ {
info6=driver.info_6;
SAFE_FREE(info6->dependentfiles);
SAFE_FREE(info6->previousnames);
ZERO_STRUCTP(info6);
SAFE_FREE(info6);
result=0;
- } else {
+ }
+ else
+ {
result=4;
}
break;
@@ -4211,11 +3491,12 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
/* loop through the printers.tdb and check for the drivername */
- for (snum=0; snum<n_services; snum++) {
+ for (snum=0; snum<n_services; snum++)
+ {
if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
continue;
- if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
+ if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
continue;
if ( !StrCaseCmp(info_3->name, printer->info_2->drivername) ) {
@@ -4233,299 +3514,6 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
return False;
}
-
-/**********************************************************************
- Check to see if a ogiven file is in use by *info
- *********************************************************************/
-
-static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
-{
- int i = 0;
-
- if ( !info )
- return False;
-
- if ( strequal(file, info->driverpath) )
- return True;
-
- if ( strequal(file, info->datafile) )
- return True;
-
- if ( strequal(file, info->configfile) )
- return True;
-
- if ( strequal(file, info->helpfile) )
- return True;
-
- /* see of there are any dependent files to examine */
-
- if ( !info->dependentfiles )
- return False;
-
- while ( *info->dependentfiles[i] ) {
- if ( strequal(file, info->dependentfiles[i]) )
- return True;
- i++;
- }
-
- return False;
-
-}
-
-/**********************************************************************
- Utility function to remove the dependent file pointed to by the
- input parameter from the list
- *********************************************************************/
-
-static void trim_dependent_file( fstring files[], int idx )
-{
-
- /* bump everything down a slot */
-
- while( *files[idx+1] ) {
- fstrcpy( files[idx], files[idx+1] );
- idx++;
- }
-
- *files[idx] = '\0';
-
- return;
-}
-
-/**********************************************************************
- Check if any of the files used by src are also used by drv
- *********************************************************************/
-
-static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
-{
- BOOL in_use = False;
- int i = 0;
-
- if ( !src || !drv )
- return False;
-
- /* check each file. Remove it from the src structure if it overlaps */
-
- if ( drv_file_in_use(src->driverpath, drv) ) {
- in_use = True;
- DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath));
- fstrcpy( src->driverpath, "" );
- }
-
- if ( drv_file_in_use(src->datafile, drv) ) {
- in_use = True;
- DEBUG(10,("Removing datafile [%s] from list\n", src->datafile));
- fstrcpy( src->datafile, "" );
- }
-
- if ( drv_file_in_use(src->configfile, drv) ) {
- in_use = True;
- DEBUG(10,("Removing configfile [%s] from list\n", src->configfile));
- fstrcpy( src->configfile, "" );
- }
-
- if ( drv_file_in_use(src->helpfile, drv) ) {
- in_use = True;
- DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile));
- fstrcpy( src->helpfile, "" );
- }
-
- /* are there any dependentfiles to examine? */
-
- if ( !src->dependentfiles )
- return in_use;
-
- while ( *src->dependentfiles[i] ) {
- if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
- in_use = True;
- DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i]));
- trim_dependent_file( src->dependentfiles, i );
- } else
- i++;
- }
-
- return in_use;
-}
-
-/****************************************************************************
- Determine whether or not a particular driver files are currently being
- used by any other driver.
-
- Return value is True if any files were in use by other drivers
- and False otherwise.
-
- Upon return, *info has been modified to only contain the driver files
- which are not in use
-****************************************************************************/
-
-BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
-{
- int i;
- int ndrivers;
- uint32 version;
- fstring *list = NULL;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
-
- if ( !info )
- return False;
-
- version = info->cversion;
-
- /* loop over all driver versions */
-
- DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
-
- /* get the list of drivers */
-
- list = NULL;
- ndrivers = get_ntdrivers(&list, info->environment, version);
-
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
- ndrivers, info->environment, version));
-
- /* check each driver for overlap in files */
-
- for (i=0; i<ndrivers; i++) {
- DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
-
- ZERO_STRUCT(driver);
-
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
- SAFE_FREE(list);
- return True;
- }
-
- /* check if d2 uses any files from d1 */
- /* only if this is a different driver than the one being deleted */
-
- if ( !strequal(info->name, driver.info_3->name) ) {
- if ( trim_overlap_drv_files(info, driver.info_3) ) {
- free_a_printer_driver(driver, 3);
- SAFE_FREE( list );
- return True;
- }
- }
-
- free_a_printer_driver(driver, 3);
- }
-
- SAFE_FREE(list);
-
- DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
-
- driver.info_3 = info;
-
- if ( DEBUGLEVEL >= 20 )
- dump_a_printer_driver( driver, 3 );
-
- return False;
-}
-
-/****************************************************************************
- Actually delete the driver files. Make sure that
- printer_driver_files_in_use() return False before calling
- this.
-****************************************************************************/
-
-static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
-{
- int i = 0;
- char *s;
- connection_struct *conn;
- DATA_BLOB null_pw;
- NTSTATUS nt_status;
- fstring res_type;
- BOOL bad_path;
- SMB_STRUCT_STAT st;
-
- if ( !info_3 )
- return False;
-
- DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
-
- /*
- * Connect to the print$ share under the same account as the
- * user connected to the rpc pipe. Note we must be root to
- * do this.
- */
-
- null_pw = data_blob( NULL, 0 );
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
- unbecome_root();
-
- if ( !conn ) {
- DEBUG(0,("delete_driver_files: Unable to connect\n"));
- return False;
- }
-
- /* Save who we are - we are temporarily becoming the connection user. */
-
- if ( !become_user(conn, conn->vuid) ) {
- DEBUG(0,("delete_driver_files: Can't become user!\n"));
- return False;
- }
-
- /* now delete the files; must strip the '\print$' string from
- fron of path */
-
- if ( *info_3->driverpath ) {
- if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
- driver_unix_convert(s, conn, NULL, &bad_path, &st);
- DEBUG(10,("deleting driverfile [%s]\n", s));
- unlink_internals(conn, 0, s);
- }
- }
-
- if ( *info_3->configfile ) {
- if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
- driver_unix_convert(s, conn, NULL, &bad_path, &st);
- DEBUG(10,("deleting configfile [%s]\n", s));
- unlink_internals(conn, 0, s);
- }
- }
-
- if ( *info_3->datafile ) {
- if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
- driver_unix_convert(s, conn, NULL, &bad_path, &st);
- DEBUG(10,("deleting datafile [%s]\n", s));
- unlink_internals(conn, 0, s);
- }
- }
-
- if ( *info_3->helpfile ) {
- if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
- driver_unix_convert(s, conn, NULL, &bad_path, &st);
- DEBUG(10,("deleting helpfile [%s]\n", s));
- unlink_internals(conn, 0, s);
- }
- }
-
- /* check if we are done removing files */
-
- if ( info_3->dependentfiles ) {
- while ( *info_3->dependentfiles[i] ) {
- char *file;
-
- /* bypass the "\print$" portion of the path */
-
- if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
- DEBUG(10,("deleting dependent file [%s]\n", file));
- unlink_internals(conn, 0, file );
- }
-
- i++;
- }
- }
-
- unbecome_user();
-
- return True;
-}
-
/****************************************************************************
Remove a printer driver from the TDB. This assumes that the the driver was
previously looked up.
@@ -4535,13 +3523,13 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
uint32 version, BOOL delete_files )
{
pstring key;
- const char *arch;
+ fstring arch;
TDB_DATA kbuf, dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
- arch = get_short_archi(info_3->environment);
+ get_short_archi(arch, info_3->environment);
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
arch, version, info_3->name);
@@ -4553,7 +3541,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
-
+
/* check if the driver actually exists for this environment */
dbuf = tdb_fetch( tdb_drivers, kbuf );
@@ -4571,6 +3559,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
return WERR_ACCESS_DENIED;
}
+#if 0 /* JERRY - no used in Samba 2.2.x */
/*
* now delete any associated files if delete_files == True
* even if this part failes, we return succes because the
@@ -4578,19 +3567,95 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
*/
if ( delete_files )
- delete_driver_files( info_3, user );
-
-
+ delete_driver_files( i, user );
+
+#endif
+
DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
return WERR_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
+ fstring value, uint8 **data, uint32 *type, uint32 *len)
+{
+ /* right now that's enough ! */
+ NT_PRINTER_PARAM *param;
+ int i=0;
+
+ param=printer.info_2->specific;
+
+ while (param != NULL && i < param_index) {
+ param=param->next;
+ i++;
+ }
+
+ if (param == NULL)
+ return False;
+
+ /* exited because it exist */
+ *type=param->type;
+ StrnCpy(value, param->value, sizeof(fstring)-1);
+ *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
+ if(*data == NULL)
+ return False;
+ ZERO_STRUCTP(*data);
+ memcpy(*data, param->data, param->data_len);
+ *len=param->data_len;
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
+ fstring value, uint8 **data, uint32 *type, uint32 *len)
+{
+ /* right now that's enough ! */
+ NT_PRINTER_PARAM *param;
+
+ DEBUG(10, ("get_specific_param\n"));
+
+ param=printer.info_2->specific;
+
+ while (param != NULL)
+ {
+#if 1 /* JRA - I think this should be case insensitive.... */
+ if ( strequal(value, param->value)
+#else
+ if ( !strcmp(value, param->value)
+#endif
+ && strlen(value)==strlen(param->value))
+ break;
+
+ param=param->next;
}
+ if (param != NULL)
+ {
+ DEBUGADD(10, ("get_specific_param: found one param\n"));
+ /* exited because it exist */
+ *type=param->type;
+
+ *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
+ if(*data == NULL)
+ return False;
+ memcpy(*data, param->data, param->data_len);
+ *len=param->data_len;
+
+ DEBUGADD(10, ("get_specific_param: exit true\n"));
+ return (True);
+ }
+ DEBUGADD(10, ("get_specific_param: exit false\n"));
+ return (False);
+}
+
/****************************************************************************
Store a security desc for a printer.
****************************************************************************/
-WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
+WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL;
SEC_DESC_BUF *old_secdesc_ctr = NULL;
@@ -4599,7 +3664,7 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
fstring key;
WERROR status;
- mem_ctx = talloc_init("nt_printing_setsec");
+ mem_ctx = talloc_init();
if (mem_ctx == NULL)
return WERR_NOMEM;
@@ -4636,7 +3701,7 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
/* Make a deep copy of the security descriptor */
- psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision, secdesc_ctr->sec->type,
+ psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
owner_sid, group_sid,
sacl,
dacl,
@@ -4685,6 +3750,7 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
{
+ extern DOM_SID global_sam_sid;
SEC_ACE ace[3];
SEC_ACCESS sa;
SEC_ACL *psa = NULL;
@@ -4692,7 +3758,9 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
SEC_DESC *psd = NULL;
DOM_SID owner_sid;
size_t sd_size;
-
+ enum SID_NAME_USE name_type;
+ fstring dos_domain;
+
/* Create an ACE where Everyone is allowed to print */
init_sec_access(&sa, PRINTER_ACE_PRINT);
@@ -4702,16 +3770,25 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
/* Make the security descriptor owned by the Administrators group
on the PDC of the domain. */
- if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
+ /* Note that for hysterical raisins, the argument to
+ secrets_fetch_domain_sid() must be in dos codepage format.
+ Aargh! */
+
+ fstrcpy(dos_domain, lp_workgroup());
+ unix_to_dos(dos_domain);
+
+ if (secrets_fetch_domain_sid(dos_domain, &owner_sid)) {
sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
} else {
- /* Backup plan - make printer owned by admins.
- This should emulate a lanman printer as security
- settings can't be changed. */
+ /* Backup plan - make printer owned by admins or root.
+ This should emulate a lanman printer as security
+ settings can't be changed. */
- sid_copy(&owner_sid, get_global_sam_sid());
- sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
+ if (!lookup_name("root", &owner_sid, &name_type)) {
+ sid_copy(&owner_sid, &global_sam_sid);
+ sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
+ }
}
init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
@@ -4729,7 +3806,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
NT5 machine. */
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
- psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ psd = make_sec_desc(ctx, SEC_DESC_REVISION,
&owner_sid, NULL,
NULL, psa, &sd_size);
}
@@ -4751,13 +3828,13 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
Get a security desc for a printer.
****************************************************************************/
-BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF **secdesc_ctr)
+BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
{
prs_struct ps;
fstring key;
char *temp;
- if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) {
+ if ((temp = strchr(printername + 2, '\\'))) {
printername = temp + 1;
}
@@ -4779,7 +3856,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF *
prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
sizeof(SEC_DESC_BUF), ctx, MARSHALL);
- if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1))
+ if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
tdb_prs_store(tdb_printers, key, &ps);
prs_mem_free(&ps);
@@ -4793,10 +3870,12 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF *
if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
DOM_SID owner_sid;
+ enum SID_NAME_USE name_type;
/* Change sd owner to workgroup administrator */
- if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
+ if (winbind_lookup_name(NULL, lp_workgroup(), &owner_sid,
+ &name_type)) {
SEC_DESC_BUF *new_secdesc_ctr = NULL;
SEC_DESC *psd = NULL;
size_t size;
@@ -4805,7 +3884,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF *
sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
- psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision, (*secdesc_ctr)->sec->type,
+ psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
&owner_sid,
(*secdesc_ctr)->sec->grp_sid,
(*secdesc_ctr)->sec->sacl,
@@ -4920,7 +3999,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
uint32 access_granted;
NTSTATUS status;
BOOL result;
- const char *pname;
+ char *pname;
TALLOC_CTX *mem_ctx = NULL;
extern struct current_user current_user;
@@ -4932,7 +4011,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
/* Always allow root or printer admins to do anything */
if (user->uid == 0 ||
- user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
+ user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
return True;
}
@@ -4947,7 +4026,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
/* Get printer security descriptor */
- if(!(mem_ctx = talloc_init("print_access_check"))) {
+ if(!(mem_ctx = talloc_init())) {
errno = ENOMEM;
return False;
}
@@ -5001,7 +4080,7 @@ BOOL print_time_access_check(int snum)
struct tm *t;
uint32 mins;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
@@ -5020,3 +4099,77 @@ BOOL print_time_access_check(int snum)
return ok;
}
+
+#if 0 /* JERRY - not used */
+/****************************************************************************
+ Attempt to write a default device.
+*****************************************************************************/
+
+WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ WERROR result;
+
+ /*
+ * Don't bother if no default devicemode was sent.
+ */
+
+ if (printer_default->devmode_cont.devmode == NULL)
+ return WERR_OK;
+
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) return result;
+
+ /*
+ * Just ignore it if we already have a devmode.
+ */
+#if 0
+ if (printer->info_2->devmode != NULL)
+ goto done;
+#endif
+ /*
+ * We don't have a devicemode and we're trying to write
+ * one. Check we have the access needed.
+ */
+ DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
+
+ if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
+ PRINTER_ACCESS_ADMINISTER) {
+ DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
+
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
+ lp_servicename(snum) ));
+ result = WERR_ACCESS_DENIED;
+ /*result = NT_STATUS_NO_PROBLEMO;*/
+ goto done;
+ }
+
+ DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
+
+ /*
+ * Convert the on the wire devicemode format to the internal one.
+ */
+
+ if (!convert_devicemode(printer->info_2->printername,
+ printer_default->devmode_cont.devmode,
+ &printer->info_2->devmode)) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ /*
+ * Finally write back to the tdb.
+ */
+
+ result = mod_a_printer(*printer, 2);
+
+ done:
+
+ free_a_printer(&printer, 2);
+ return result;
+}
+#endif /* JERRY */
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index a5fb53a320d..c8387bf79c8 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
printcap parsing
Copyright (C) Karl Auer 1993-1998
@@ -62,6 +63,8 @@
#include "includes.h"
+#include "smb.h"
+
#ifdef AIX
/* ******************************************
Extend for AIX system and qconfig file
@@ -94,14 +97,14 @@ static int strlocate(char *xpLine,char *xpS)
static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
{
int iEtat;
- XFILE *pfile;
+ FILE *pfile;
char *line,*p;
pstring name,comment;
line = NULL;
*name = 0;
*comment = 0;
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
+ if ((pfile = sys_fopen(psz, "r")) == NULL)
{
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
return;
@@ -117,7 +120,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
{
case 0: /* locate an entry */
if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr_m(line,':')))
+ if ((p=strchr(line,':')))
{
*p = '\0';
p = strtok(line,":");
@@ -155,7 +158,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
break;
}
}
- x_fclose(pfile);
+ fclose(pfile);
}
/* Scan qconfig file and locate de printername */
@@ -163,7 +166,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
static BOOL ScanQconfig(char *psz,char *pszPrintername)
{
int iLg,iEtat;
- XFILE *pfile;
+ FILE *pfile;
char *pName;
char *line;
@@ -176,7 +179,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
return(False);
}
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
+ if ((pfile = sys_fopen(psz, "r")) == NULL)
{
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
SAFE_FREE(pName);
@@ -206,9 +209,9 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
{
/* name is found without stanza device */
/* probably a good printer ??? */
- free (line);
+ SAFE_FREE (line);
SAFE_FREE(pName);
- x_fclose(pfile);
+ fclose(pfile);
return(True);
}
@@ -220,16 +223,16 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
else if (strlocate(line,"device"))
{
/* it's a good virtual printer */
- free (line);
+ SAFE_FREE (line);
SAFE_FREE(pName);
- x_fclose(pfile);
+ fclose(pfile);
return(True);
}
break;
}
}
- free (pName);
- x_fclose(pfile);
+ SAFE_FREE (pName);
+ fclose(pfile);
return(False);
}
#endif /* AIX */
@@ -239,14 +242,18 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
Scan printcap file pszPrintcapname for a printer called pszPrintername.
Return True if found, else False. Returns False on error, too, after logging
the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
+passed as NULL, the configuration will be queried for the name. pszPrintername
+must be in DOS codepage.
+The xxx_printername_ok functions need fixing to understand they are being
+given a DOS codepage. FIXME !! JRA.
***************************************************************************/
-BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
+
+BOOL pcap_printername_ok(char *pszPrintername, const char *pszPrintcapname)
{
char *line=NULL;
const char *psz;
char *p,*q;
- XFILE *pfile;
+ FILE *pfile;
if (pszPrintername == NULL || pszPrintername[0] == '\0')
{
@@ -277,7 +284,7 @@ BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname
return(ScanQconfig(psz,pszPrintername));
#endif
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
+ if ((pfile = sys_fopen(psz, "r")) == NULL)
{
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
return(False);
@@ -288,27 +295,31 @@ BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname
if (*line == '#' || *line == 0)
continue;
+ unix_to_dos(line);
+
/* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
+ p = strchr(line,':');
if (p) *p = 0;
/* now just check if the name is in the list */
/* NOTE: I avoid strtok as the fn calling this one may be using it */
for (p=line; p; p=q)
{
- if ((q = strchr_m(p,'|'))) *q++ = 0;
+ if ((q = strchr(p,'|'))) *q++ = 0;
if (strequal(p,pszPrintername))
{
+ /* normalise the case */
+ pstrcpy(pszPrintername,p);
SAFE_FREE(line);
- x_fclose(pfile);
+ fclose(pfile);
return(True);
}
p = q;
}
}
- x_fclose(pfile);
+ fclose(pfile);
return(False);
}
@@ -325,7 +336,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
char *line;
char *psz;
char *p,*q;
- XFILE *pfile;
+ FILE *pfile;
/* only go looking if no printcap name supplied */
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
@@ -356,7 +367,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
}
#endif
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
+ if ((pfile = sys_fopen(psz, "r")) == NULL)
{
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
return;
@@ -368,9 +379,11 @@ void pcap_printer_fn(void (*fn)(char *, char *))
continue;
/* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
+ p = strchr(line,':');
if (p) *p = 0;
+ unix_to_dos(line);
+
/* now find the most likely printer name and comment
this is pure guesswork, but it's better than nothing */
*name = 0;
@@ -378,13 +391,13 @@ void pcap_printer_fn(void (*fn)(char *, char *))
for (p=line; p; p=q)
{
BOOL has_punctuation;
- if ((q = strchr_m(p,'|'))) *q++ = 0;
+ if ((q = strchr(p,'|'))) *q++ = 0;
- has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
+ has_punctuation = (strchr(p,' ') || strchr(p,'\t') || strchr(p,'(') || strchr(p,')'));
if (strlen(p)>strlen(comment) && has_punctuation)
{
- pstrcpy(comment,p);
+ StrnCpy(comment,p,sizeof(comment)-1);
continue;
}
@@ -395,11 +408,11 @@ void pcap_printer_fn(void (*fn)(char *, char *))
continue;
}
- if (!strchr_m(comment,' ') &&
+ if (!strchr(comment,' ') &&
strlen(p) > strlen(comment))
{
- pstrcpy(comment,p);
- continue;
+ StrnCpy(comment,p,sizeof(comment)-1);
+ continue;
}
}
@@ -409,5 +422,5 @@ void pcap_printer_fn(void (*fn)(char *, char *))
if (*name)
fn(name,comment);
}
- x_fclose(pfile);
+ fclose(pfile);
}
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index 9a48296543d..c2839375566 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -18,7 +18,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "printing.h"
#ifdef HAVE_CUPS
@@ -333,7 +332,7 @@ int cups_printername_ok(const char *name)
if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
{
- DEBUG(3,("Unable to connect to CUPS server %s - %s\n",
+ DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cupsServer(), strerror(errno)));
return (0);
}
@@ -375,7 +374,7 @@ int cups_printername_ok(const char *name)
if ((response = cupsDoRequest(http, request, "/")) == NULL)
{
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
+ DEBUG(0,("Unable to get printer status for %s - %s\n", name,
ippErrorString(cupsLastError())));
httpClose(http);
return (0);
@@ -385,7 +384,7 @@ int cups_printername_ok(const char *name)
if (response->request.status.status_code >= IPP_OK_CONFLICT)
{
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
+ DEBUG(0,("Unable to get printer status for %s - %s\n", name,
ippErrorString(response->request.status.status_code)));
ippDelete(response);
return (0);
@@ -681,10 +680,7 @@ cups_job_submit(int snum, struct printjob *pjob)
*response; /* IPP Response */
cups_lang_t *language; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char *clientname; /* hostname of client for job-originating-host attribute */
- pstring new_jobname;
- int num_options = 0;
- cups_option_t *options;
+
DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
@@ -738,31 +734,12 @@ cups_job_submit(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, pjob->user);
- clientname = client_name();
- if (strcmp(clientname, "UNKNOWN") == 0) {
- clientname = client_addr();
- }
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"job-originating-host-name", NULL,
- clientname);
-
- pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX,
- (unsigned int)pjob->smbjob, pjob->jobname);
+ get_remote_machine_name());
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- new_jobname);
-
- /*
- * add any options defined in smb.conf
- */
-
- num_options = 0;
- options = NULL;
- num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options);
-
- if ( num_options )
- cupsEncodeOptions(request, num_options, options);
+ pjob->jobname);
/*
* Do the request and get back a response...
@@ -795,6 +772,7 @@ cups_job_submit(int snum, struct printjob *pjob)
return (ret);
}
+
/*
* 'cups_queue_get()' - Get all the jobs in the print queue.
*/
diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c
index 9e0ea85bb9a..2a6b11ebc4e 100644
--- a/source/printing/print_generic.c
+++ b/source/printing/print_generic.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
printing command routines
Copyright (C) Andrew Tridgell 1992-2000
@@ -18,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "printing.h"
@@ -56,7 +56,7 @@ static int print_run_command(int snum,char *command, int *outfd, ...)
{
pstring syscmd;
- char *arg;
+ char *p, *arg;
int ret;
va_list ap;
va_start(ap, outfd);
@@ -76,9 +76,13 @@ static int print_run_command(int snum,char *command, int *outfd, ...)
}
va_end(ap);
- pstring_sub(syscmd, "%p", PRINTERNAME(snum));
+ p = PRINTERNAME(snum);
+
+ pstring_sub(syscmd, "%p", p);
standard_sub_snum(snum,syscmd,sizeof(syscmd));
+ /* Convert script args to unix-codepage */
+ dos_to_unix(syscmd);
ret = smbrun(syscmd,outfd);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -154,7 +158,7 @@ static int generic_job_submit(int snum, struct printjob *pjob)
return 0;
pstrcpy(print_directory, pjob->filename);
- p = strrchr_m(print_directory,'/');
+ p = strrchr(print_directory,'/');
if (!p)
return 0;
*p++ = 0;
@@ -165,17 +169,17 @@ static int generic_job_submit(int snum, struct printjob *pjob)
pstrcpy(jobname, pjob->jobname);
pstring_sub(jobname, "'", "_");
slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
- slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
+ slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size);
/* send it to the system spooler */
ret = print_run_command(snum,
- lp_printcommand(snum), NULL,
- "%s", p,
- "%J", jobname,
- "%f", p,
- "%z", job_size,
- "%c", job_page_count,
- NULL);
+ lp_printcommand(snum), NULL,
+ "%s", p,
+ "%J", jobname,
+ "%f", p,
+ "%z", job_size,
+ "%c", job_page_count,
+ NULL);
chdir(wd);
@@ -194,7 +198,9 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru
print_queue_struct *queue = NULL;
fstring printer_name;
+ /* Convert printer name (i.e. share name) to unix-codepage */
fstrcpy(printer_name, lp_servicename(snum));
+ dos_to_unix(printer_name);
print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
@@ -205,7 +211,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru
}
numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
+ qlines = fd_lines_load(fd, &numlines, True);
close(fd);
/* turn the lpq output into a series of job structures */
@@ -215,7 +221,6 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru
queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
if (queue) {
- memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
for (i=0; i<numlines; i++) {
/* parse the line */
if (parse_lpq_entry(snum,qlines[i],
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 07b157bcd95..36446a3da7c 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -33,6 +33,7 @@
#include "includes.h"
+#include "smb.h"
#ifdef SYSV
@@ -47,7 +48,7 @@ static void populate_printers(void)
char **lines;
int i;
- lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
+ lines = file_lines_pload("/usr/bin/lpstat -v", NULL, False);
if (!lines) return;
for (i=0;lines[i];i++) {
@@ -56,8 +57,8 @@ static void populate_printers(void)
char *buf = lines[i];
/* eat "system/device for " */
- if (((tmp = strchr_m(buf, ' ')) == NULL) ||
- ((tmp = strchr_m(++tmp, ' ')) == NULL))
+ if (((tmp = strchr(buf, ' ')) == NULL) ||
+ ((tmp = strchr(++tmp, ' ')) == NULL))
continue;
/*
@@ -65,7 +66,7 @@ static void populate_printers(void)
*/
if(!strncmp("for ",++tmp,4)) {
- tmp=strchr_m(tmp, ' ');
+ tmp=strchr(tmp, ' ');
tmp++;
}
@@ -84,7 +85,7 @@ static void populate_printers(void)
name = tmp;
/* truncate the ": ..." */
- if ((tmp = strchr_m(name, ':')) != NULL)
+ if ((tmp = strchr(name, ':')) != NULL)
*tmp = '\0';
/* add it to the cache */
@@ -117,7 +118,7 @@ void sysv_printer_fn(void (*fn)(char *, char *))
if (printers == NULL)
populate_printers();
for (tmp = printers; tmp != NULL; tmp = tmp->next)
- (fn)(tmp->name, "");
+ (fn)(unix_to_dos_static(tmp->name), "");
}
@@ -125,7 +126,7 @@ void sysv_printer_fn(void (*fn)(char *, char *))
* provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
* systems.
*/
-int sysv_printername_ok(const char *name)
+int sysv_printername_ok(char *name)
{
printer_t *tmp;
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index 0b6d4fdbe1c..4f9b649185d 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
printing backend routines for smbd - using files_struct rather
than only snum
Copyright (C) Andrew Tridgell 1992-2000
@@ -46,23 +47,15 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
fstrcat(name, p);
}
- jobid = print_job_start(&current_user, SNUM(conn), name, NULL);
+ jobid = print_job_start(&current_user, SNUM(conn), name);
if (jobid == -1) {
file_free(fsp);
return NULL;
}
- /* Convert to RAP id. */
- fsp->rap_print_jobid = pjobid_to_rap(SNUM(conn), jobid);
- if (fsp->rap_print_jobid == 0) {
- /* We need to delete the entry in the tdb. */
- pjob_delete(SNUM(conn), jobid);
- file_free(fsp);
- return NULL;
- }
-
/* setup a full fsp */
- fsp->fd = print_job_fd(SNUM(conn),jobid);
+ fsp->print_jobid = jobid;
+ fsp->fd = print_job_fd(jobid);
GetTimeOfDay(&fsp->open_time);
fsp->vuid = current_user.vuid;
fsp->size = 0;
@@ -77,10 +70,11 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
fsp->directory_delete_on_close = False;
- string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
+ fsp->conn = conn;
+ string_set(&fsp->fsp_name,print_job_fname(jobid));
fsp->wbmpx_ptr = NULL;
fsp->wcp = NULL;
- SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf);
+ conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
fsp->mode = sbuf.st_mode;
fsp->inode = sbuf.st_ino;
fsp->dev = sbuf.st_dev;
@@ -95,9 +89,6 @@ print a file - called on closing the file
****************************************************************************/
void print_fsp_end(files_struct *fsp, BOOL normal_close)
{
- uint32 jobid;
- int snum;
-
if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
/*
* Truncate the job. print_job_end will take
@@ -106,15 +97,9 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
sys_ftruncate(fsp->fd, 0);
}
+ print_job_end(fsp->print_jobid, normal_close);
+
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
}
-
- if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
- DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
- (unsigned int)fsp->rap_print_jobid ));
- return;
- }
-
- print_job_end(SNUM(fsp->conn),jobid, normal_close);
}
diff --git a/source/printing/printing.c b/source/printing/printing.c
index e4ef1f52d0e..c5d2564a850 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -3,7 +3,6 @@
Version 3.0
printing backend routines
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,11 +19,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
#include "printing.h"
/* Current printer interface */
-static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
+struct printif *current_printif = &generic_printif;
/*
the printing backend revolves around a tdb database that stores the
@@ -40,213 +38,56 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
jobids are assigned when a job starts spooling.
*/
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
-
-static TDB_CONTEXT *rap_tdb;
-static uint16 next_rap_jobid;
-
-uint16 pjobid_to_rap(int snum, uint32 jobid)
-{
- uint16 rap_jobid;
- TDB_DATA data, key;
- char jinfo[8];
-
- DEBUG(10,("pjobid_to_rap: called.\n"));
-
- if (!rap_tdb) {
- /* Create the in-memory tdb. */
- rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
- if (!rap_tdb)
- return 0;
- }
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == sizeof(uint16)) {
- rap_jobid = SVAL(data.dptr, 0);
- SAFE_FREE(data.dptr);
- DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
- }
- SAFE_FREE(data.dptr);
- /* Not found - create and store mapping. */
- rap_jobid = ++next_rap_jobid;
- if (rap_jobid == 0)
- rap_jobid = ++next_rap_jobid;
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_store(rap_tdb, key, data, TDB_REPLACE);
- tdb_store(rap_tdb, data, key, TDB_REPLACE);
-
- DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
-}
-
-BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
-{
- TDB_DATA data, key;
-
- DEBUG(10,("rap_to_pjobid called.\n"));
-
- if (!rap_tdb)
- return False;
-
- key.dptr = (char *)&rap_jobid;
- key.dsize = sizeof(rap_jobid);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == 8) {
- *psnum = IVAL(data.dptr,0);
- *pjobid = IVAL(data.dptr,4);
- DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
- (unsigned int)*pjobid,
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return True;
- }
-
- DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return False;
-}
-
-static void rap_jobid_delete(int snum, uint32 jobid)
-{
- TDB_DATA key, data;
- uint16 rap_jobid;
- char jinfo[8];
-
- DEBUG(10,("rap_jobid_delete: called.\n"));
-
- if (!rap_tdb)
- return;
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (!data.dptr || (data.dsize != sizeof(uint16))) {
- DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
- (unsigned int)jobid ));
- SAFE_FREE(data.dptr);
- return;
- }
-
- DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
- (unsigned int)jobid ));
-
- rap_jobid = SVAL(data.dptr, 0);
- SAFE_FREE(data.dptr);
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_delete(rap_tdb, key);
- tdb_delete(rap_tdb, data);
-}
-
+/* the open printing.tdb database */
+static TDB_CONTEXT *tdb;
static pid_t local_pid;
static int get_queue_status(int, print_status_struct *);
/****************************************************************************
- Initialise the printing backend. Called once at startup before the fork().
+ Initialise the printing backend. Called once at startup.
+ Does not survive a fork
****************************************************************************/
BOOL print_backend_init(void)
{
const char *sversion = "INFO/version";
- pstring printing_path;
- int services = lp_numservices();
- int snum;
- if (local_pid == sys_getpid())
+ if (tdb && local_pid == sys_getpid())
return True;
-
- unlink(lock_path("printing.tdb"));
- pstrcpy(printing_path,lock_path("printing"));
- mkdir(printing_path,0755);
-
+ tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb) {
+ DEBUG(0,("print_backend_init: Failed to open printing backend database %s.\n",
+ lock_path("printing.tdb") ));
+ return False;
+ }
local_pid = sys_getpid();
/* handle a Samba upgrade */
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
-
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (!pdb)
- continue;
- if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
- DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- return False;
- }
- if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
- }
- tdb_unlock_bystring(pdb->tdb, sversion);
- release_print_db(pdb);
+ tdb_lock_bystring(tdb, sversion, 0);
+ if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) {
+ tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
+ tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION);
}
+ tdb_unlock_bystring(tdb, sversion);
- close_all_print_db(); /* Don't leave any open. */
+ /* select the appropriate printing interface... */
+#ifdef HAVE_CUPS
+ if (strcmp(lp_printcapname(), "cups") == 0)
+ current_printif = &cups_printif;
+#endif /* HAVE_CUPS */
/* do NT print initialization... */
return nt_printing_init();
}
/****************************************************************************
- Shut down printing backend. Called once at shutdown to close the tdb.
-****************************************************************************/
-
-void printing_end(void)
-{
- close_all_print_db(); /* Don't leave any open. */
-}
-
-/****************************************************************************
- Retrieve the set of printing functions for a given service. This allows
- us to set the printer function table based on the value of the 'printing'
- service parameter.
-
- Use the generic interface as the default and only use cups interface only
- when asked for (and only when supported)
-****************************************************************************/
-
-static struct printif *get_printer_fns( int snum )
-{
- struct printif *printer_fns = &generic_printif;
-
-#ifdef HAVE_CUPS
- if ( lp_printing(snum) == PRINT_CUPS ) {
- printer_fns = &cups_printif;
- }
-#endif /* HAVE_CUPS */
-
- return printer_fns;
-}
-
-/****************************************************************************
Useful function to generate a tdb key.
****************************************************************************/
-static TDB_DATA print_key(uint32 jobid)
+static TDB_DATA print_key(int jobid)
{
- static uint32 j;
+ static int j;
TDB_DATA ret;
j = jobid;
@@ -255,383 +96,73 @@ static TDB_DATA print_key(uint32 jobid)
return ret;
}
-/***********************************************************************
- unpack a pjob from a tdb buffer
-***********************************************************************/
-
-int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
-{
- int len = 0;
- int used;
- uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
- uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
-
- if ( !buf || !pjob )
- return -1;
-
- len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
- &pjpid,
- &pjsysjob,
- &pjfd,
- &pjstarttime,
- &pjstatus,
- &pjsize,
- &pjpage_count,
- &pjspooled,
- &pjsmbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- if ( len == -1 )
- return -1;
-
- if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
- return -1;
-
- len += used;
-
- pjob->pid = pjpid;
- pjob->sysjob = pjsysjob;
- pjob->fd = pjfd;
- pjob->starttime = pjstarttime;
- pjob->status = pjstatus;
- pjob->size = pjsize;
- pjob->page_count = pjpage_count;
- pjob->spooled = pjspooled;
- pjob->smbjob = pjsmbjob;
-
- return len;
-
-}
-
/****************************************************************************
Useful function to find a print job in the database.
****************************************************************************/
-static struct printjob *print_job_find(int snum, uint32 jobid)
+static struct printjob *print_job_find(int jobid)
{
- static struct printjob pjob;
- TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
+ static struct printjob pjob;
+ TDB_DATA ret;
- if (!pdb)
+ ret = tdb_fetch(tdb, print_key(jobid));
+ if (!ret.dptr || ret.dsize != sizeof(pjob))
return NULL;
- ret = tdb_fetch(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
-
- if (!ret.dptr)
- return NULL;
-
- if ( pjob.nt_devmode )
- free_nt_devicemode( &pjob.nt_devmode );
-
- ZERO_STRUCT( pjob );
-
- if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
- SAFE_FREE(ret.dptr);
- return NULL;
- }
-
- SAFE_FREE(ret.dptr);
+ memcpy(&pjob, ret.dptr, sizeof(pjob));
+ SAFE_FREE(ret.dptr);
+ unix_to_dos(pjob.queuename);
return &pjob;
}
-/* Convert a unix jobid to a smb jobid */
-
-static uint32 sysjob_to_jobid_value;
-
-static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state)
-{
- struct printjob *pjob;
- int *sysjob = (int *)state;
-
- if (!data.dptr || data.dsize == 0)
- return 0;
-
- pjob = (struct printjob *)data.dptr;
- if (key.dsize != sizeof(uint32))
- return 0;
-
- if (*sysjob == pjob->sysjob) {
- uint32 *jobid = (uint32 *)key.dptr;
-
- sysjob_to_jobid_value = *jobid;
- return 1;
- }
-
- return 0;
-}
-
-/****************************************************************************
- This is a *horribly expensive call as we have to iterate through all the
- current printer tdb's. Don't do this often ! JRA.
-****************************************************************************/
-
-uint32 sysjob_to_jobid(int unix_jobid)
-{
- int services = lp_numservices();
- int snum;
-
- sysjob_to_jobid_value = (uint32)-1;
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (pdb)
- tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
- release_print_db(pdb);
- if (sysjob_to_jobid_value != (uint32)-1)
- return sysjob_to_jobid_value;
- }
- return (uint32)-1;
-}
-
-/****************************************************************************
- Send notifications based on what has changed after a pjob_store.
-****************************************************************************/
-
-static struct {
- uint32 lpq_status;
- uint32 spoolss_status;
-} lpq_to_spoolss_status_map[] = {
- { LPQ_QUEUED, JOB_STATUS_QUEUED },
- { LPQ_PAUSED, JOB_STATUS_PAUSED },
- { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
- { LPQ_PRINTING, JOB_STATUS_PRINTING },
- { LPQ_DELETING, JOB_STATUS_DELETING },
- { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
- { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
- { LPQ_PRINTED, JOB_STATUS_PRINTED },
- { LPQ_DELETED, JOB_STATUS_DELETED },
- { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
- { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
- { -1, 0 }
-};
-
-/* Convert a lpq status value stored in printing.tdb into the
- appropriate win32 API constant. */
-
-static uint32 map_to_spoolss_status(uint32 lpq_status)
-{
- int i = 0;
-
- while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
- if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
- return lpq_to_spoolss_status_map[i].spoolss_status;
- i++;
- }
-
- return 0;
-}
-
-static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
- struct printjob *new_data)
-{
- BOOL new_job = False;
-
- if (!old_data)
- new_job = True;
-
- /* Notify the job name first */
-
- if (new_job || !strequal(old_data->jobname, new_data->jobname))
- notify_job_name(snum, jobid, new_data->jobname);
-
- /* Job attributes that can't be changed. We only send
- notification for these on a new job. */
-
- if (new_job) {
- notify_job_submitted(snum, jobid, new_data->starttime);
- notify_job_username(snum, jobid, new_data->user);
- }
-
- /* Job attributes of a new job or attributes that can be
- modified. */
-
- if (new_job || old_data->status != new_data->status)
- notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
-
- if (new_job || old_data->size != new_data->size)
- notify_job_total_bytes(snum, jobid, new_data->size);
-
- if (new_job || old_data->page_count != new_data->page_count)
- notify_job_total_pages(snum, jobid, new_data->page_count);
-}
-
/****************************************************************************
Store a job structure back to the database.
****************************************************************************/
-static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
+static BOOL print_job_store(int jobid, struct printjob *pjob)
{
- TDB_DATA old_data, new_data;
- BOOL ret = False;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- char *buf = NULL;
- int len, newlen, buflen;
-
-
- if (!pdb)
- return False;
-
- /* Get old data */
-
- old_data = tdb_fetch(pdb->tdb, print_key(jobid));
-
- /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
-
- newlen = 0;
-
- do {
- len = 0;
- buflen = newlen;
- len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
- (uint32)pjob->pid,
- (uint32)pjob->sysjob,
- (uint32)pjob->fd,
- (uint32)pjob->starttime,
- (uint32)pjob->status,
- (uint32)pjob->size,
- (uint32)pjob->page_count,
- (uint32)pjob->spooled,
- (uint32)pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
-
- if (buflen != len) {
- char *tb;
-
- tb = (char *)Realloc(buf, len);
- if (!tb) {
- DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
- goto done;
- }
- else
- buf = tb;
- newlen = len;
- }
- } while ( buflen != len );
-
-
- /* Store new data */
-
- new_data.dptr = buf;
- new_data.dsize = len;
- ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
-
- release_print_db(pdb);
-
- /* Send notify updates for what has changed */
-
- if ( ret ) {
- struct printjob old_pjob;
-
- if ( old_data.dsize )
- {
- if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
- {
- pjob_store_notify( snum, jobid, &old_pjob , pjob );
- free_nt_devicemode( &old_pjob.nt_devmode );
- }
- }
- else {
- /* new job */
- pjob_store_notify( snum, jobid, NULL, pjob );
- }
- }
-
-done:
- SAFE_FREE( old_data.dptr );
- SAFE_FREE( buf );
+ TDB_DATA d;
+ BOOL ret;
+ dos_to_unix(pjob->queuename);
+ d.dptr = (void *)pjob;
+ d.dsize = sizeof(*pjob);
+ ret = (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
+ unix_to_dos(pjob->queuename);
return ret;
}
/****************************************************************************
- Remove a job structure from the database.
-****************************************************************************/
-
-void pjob_delete(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- uint32 job_status = 0;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
- if (!pdb)
- return;
-
- if (!pjob) {
- DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
- (unsigned int)jobid));
- release_print_db(pdb);
- return;
- }
-
- /* Send a notification that a job has been deleted */
-
- job_status = map_to_spoolss_status(pjob->status);
-
- /* We must cycle through JOB_STATUS_DELETING and
- JOB_STATUS_DELETED for the port monitor to delete the job
- properly. */
-
- job_status |= JOB_STATUS_DELETING;
- notify_job_status(snum, jobid, job_status);
-
- job_status |= JOB_STATUS_DELETED;
- notify_job_status(snum, jobid, job_status);
-
- /* Remove from printing.tdb */
-
- tdb_delete(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- rap_jobid_delete(snum, jobid);
-}
-
-/****************************************************************************
Parse a file name from the system spooler to generate a jobid.
****************************************************************************/
-static uint32 print_parse_jobid(char *fname)
+static int print_parse_jobid(char *fname)
{
int jobid;
if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
- return (uint32)-1;
+ return -1;
fname += strlen(PRINT_SPOOL_PREFIX);
jobid = atoi(fname);
if (jobid <= 0)
- return (uint32)-1;
+ return -1;
- return (uint32)jobid;
+ return jobid;
}
/****************************************************************************
List a unix job in the print database.
****************************************************************************/
-static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
+static void print_unix_job(int snum, print_queue_struct *q)
{
+ int jobid = q->job + UNIX_JOB_START;
struct printjob pj, *old_pj;
- if (jobid == (uint32)-1)
- jobid = q->job + UNIX_JOB_START;
-
/* Preserve the timestamp on an existing unix print job */
- old_pj = print_job_find(snum, jobid);
+ old_pj = print_job_find(jobid);
ZERO_STRUCT(pj);
@@ -642,18 +173,13 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
pj.status = q->status;
pj.size = q->size;
pj.spooled = True;
- fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
- if (jobid < UNIX_JOB_START) {
- pj.smbjob = True;
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
- } else {
- pj.smbjob = False;
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
- }
- fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
- fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
+ pj.smbjob = False;
+ fstrcpy(pj.filename, "");
+ fstrcpy(pj.jobname, q->fs_file);
+ fstrcpy(pj.user, q->fs_user);
+ fstrcpy(pj.queuename, lp_servicename(snum));
- pjob_store(snum, jobid, &pj);
+ print_job_store(jobid, &pj);
}
@@ -671,20 +197,17 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
{
struct traverse_struct *ts = (struct traverse_struct *)state;
struct printjob pjob;
- uint32 jobid;
- int i = 0;
+ int i, jobid;
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- jobid = IVAL(key.dptr, 0);
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
+ if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int))
return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
+ memcpy(&jobid, key.dptr, sizeof(jobid));
+ memcpy(&pjob, data.dptr, sizeof(pjob));
+ unix_to_dos(pjob.queuename);
if (ts->snum != lp_servicenumber(pjob.queuename)) {
- /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
+ /* this isn't for the queue we are looking at */
+ ts->total_jobs++;
return 0;
}
@@ -692,19 +215,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
/* remove a unix job if it isn't in the system queue any more */
for (i=0;i<ts->qcount;i++) {
- uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
- if (jobid == u_jobid)
+ if (jobid == ts->queue[i].job + UNIX_JOB_START)
break;
}
- if (i == ts->qcount) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
- (unsigned int)jobid ));
- pjob_delete(ts->snum, jobid);
- return 0;
- }
-
- /* need to continue the the bottom of the function to
- save the correct attributes */
+ if (i == ts->qcount)
+ tdb_delete(tdb, key);
+ else
+ ts->total_jobs++;
+ return 0;
}
/* maybe it hasn't been spooled yet */
@@ -712,23 +230,17 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
/* if a job is not spooled and the process doesn't
exist then kill it. This cleans up after smbd
deaths */
- if (!process_exists(pjob.pid)) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
- (unsigned int)jobid, (unsigned int)pjob.pid ));
- pjob_delete(ts->snum, jobid);
- } else
+ if (!process_exists(pjob.pid))
+ tdb_delete(tdb, key);
+ else
ts->total_jobs++;
return 0;
}
- /* this check only makes sense for jobs submitted from Windows clients */
-
- if ( pjob.smbjob ) {
- for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
- if (jobid == curr_jobid)
- break;
- }
+ for (i=0;i<ts->qcount;i++) {
+ int qid = print_parse_jobid(ts->queue[i].fs_file);
+ if (jobid == qid)
+ break;
}
/* The job isn't in the system queue - we have to assume it has
@@ -743,30 +255,13 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
is currently traversing the printing tdb and deleting jobs.
Don't delete the job if it was submitted after the lpq_time. */
- if (pjob.starttime < ts->lpq_time) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
- (unsigned int)jobid,
- (unsigned int)pjob.starttime,
- (unsigned int)ts->lpq_time ));
- pjob_delete(ts->snum, jobid);
- } else
+ if (pjob.starttime < ts->lpq_time)
+ tdb_delete(t, key);
+ else
ts->total_jobs++;
- return 0;
}
-
- /* Save the pjob attributes we will store. */
- /* FIXME!!! This is the only place where queue->job
- represents the SMB jobid --jerry */
- ts->queue[i].job = jobid;
- ts->queue[i].size = pjob.size;
- ts->queue[i].page_count = pjob.page_count;
- ts->queue[i].status = pjob.status;
- ts->queue[i].priority = 1;
- ts->queue[i].time = pjob.starttime;
- fstrcpy(ts->queue[i].fs_user, pjob.user);
- fstrcpy(ts->queue[i].fs_file, pjob.jobname);
-
- ts->total_jobs++;
+ else
+ ts->total_jobs++;
return 0;
}
@@ -778,14 +273,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
static void print_cache_flush(int snum)
{
fstring key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return;
- slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
- tdb_store_int32(pdb->tdb, key, -1);
- release_print_db(pdb);
+ slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
+ dos_to_unix(key); /* Convert key to unix-codepage */
+ tdb_store_int32(tdb, key, -1);
}
/****************************************************************************
@@ -797,22 +287,16 @@ static pid_t get_updating_pid(fstring printer_name)
fstring keystr;
TDB_DATA data, key;
pid_t updating_pid;
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
- if (!pdb)
- return (pid_t)-1;
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
key.dptr = keystr;
key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- release_print_db(pdb);
- if (!data.dptr || data.dsize != sizeof(pid_t)) {
- SAFE_FREE(data.dptr);
+ data = tdb_fetch(tdb, key);
+ if (!data.dptr || data.dsize != sizeof(pid_t))
return (pid_t)-1;
- }
- updating_pid = IVAL(data.dptr, 0);
+ memcpy(&updating_pid, data.dptr, sizeof(pid_t));
SAFE_FREE(data.dptr);
if (process_exists(updating_pid))
@@ -823,152 +307,53 @@ static pid_t get_updating_pid(fstring printer_name)
/****************************************************************************
Set the fact that we're doing the update, or have finished doing the update
- in the tdb.
+ in th tdb.
****************************************************************************/
-static void set_updating_pid(const fstring printer_name, BOOL delete)
+static void set_updating_pid(fstring printer_name, BOOL delete)
{
fstring keystr;
TDB_DATA key;
TDB_DATA data;
pid_t updating_pid = sys_getpid();
- uint8 buffer[4];
-
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
-
- if (!pdb)
- return;
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
key.dptr = keystr;
key.dsize = strlen(keystr);
if (delete) {
- tdb_delete(pdb->tdb, key);
- release_print_db(pdb);
+ tdb_delete(tdb, key);
return;
}
- SIVAL( buffer, 0, updating_pid);
- data.dptr = (void *)buffer;
- data.dsize = 4; /* we always assume this is a 4 byte value */
-
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Sort print jobs by submittal time.
-****************************************************************************/
-
-static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
-{
- /* Silly cases */
+ data.dptr = (void *)&updating_pid;
+ data.dsize = sizeof(pid_t);
- if (!j1 && !j2)
- return 0;
- if (!j1)
- return -1;
- if (!j2)
- return 1;
-
- /* Sort on job start time */
-
- if (j1->time == j2->time)
- return 0;
- return (j1->time > j2->time) ? 1 : -1;
+ tdb_store(tdb, key, data, TDB_REPLACE);
}
/****************************************************************************
- Store the sorted queue representation for later portmon retrieval.
+ Send a message saying the queue changed.
****************************************************************************/
-static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
+static void send_queue_message(const char *printer_name, uint32 high, uint32 low)
{
- TDB_DATA data, key;
- int max_reported_jobs = lp_max_reported_jobs(pts->snum);
- print_queue_struct *queue = pts->queue;
- size_t len;
- size_t i;
- uint qcount;
-
- if (max_reported_jobs && (max_reported_jobs < pts->qcount))
- pts->qcount = max_reported_jobs;
- qcount = pts->qcount;
-
- /* Work out the size. */
- data.dsize = 0;
- data.dsize += tdb_pack(NULL, 0, "d", qcount);
-
- for (i = 0; i < pts->qcount; i++) {
- data.dsize += tdb_pack(NULL, 0, "ddddddff",
- (uint32)queue[i].job,
- (uint32)queue[i].size,
- (uint32)queue[i].page_count,
- (uint32)queue[i].status,
- (uint32)queue[i].priority,
- (uint32)queue[i].time,
- queue[i].fs_user,
- queue[i].fs_file);
- }
-
- if ((data.dptr = malloc(data.dsize)) == NULL)
- return;
-
- len = 0;
- len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
- for (i = 0; i < pts->qcount; i++) {
- len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
- (uint32)queue[i].job,
- (uint32)queue[i].size,
- (uint32)queue[i].page_count,
- (uint32)queue[i].status,
- (uint32)queue[i].priority,
- (uint32)queue[i].time,
- queue[i].fs_user,
- queue[i].fs_file);
- }
-
- key.dptr = "INFO/linear_queue_array";
- key.dsize = strlen(key.dptr);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
- SAFE_FREE(data.dptr);
- return;
-}
-
-static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
-{
- TDB_DATA data, key;
-
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
- ZERO_STRUCT(data);
-
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- }
-
- return data;
-}
+ char msg[sizeof(PRINTER_MESSAGE_INFO)];
+ PRINTER_MESSAGE_INFO info;
-static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
-{
- unsigned int i;
- unsigned int job_count = data.dsize / 4;
+ ZERO_STRUCT(info);
- for (i = 0; i < job_count; i++) {
- uint32 ch_jobid;
+ info.low = low;
+ info.high = high;
+ info.flags = 0;
+ fstrcpy(info.printer_name, printer_name);
+ memcpy( msg, &info, sizeof(PRINTER_MESSAGE_INFO));
- ch_jobid = IVAL(data.dptr, i*4);
- if (ch_jobid == jobid)
- remove_from_jobs_changed(snum, jobid);
- }
+ message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO), False, NULL);
}
/****************************************************************************
- Update the internal database from the system print queue for a queue.
+update the internal database from the system print queue for a queue
****************************************************************************/
static void print_queue_update(int snum)
@@ -981,32 +366,26 @@ static void print_queue_update(int snum)
struct traverse_struct tstruct;
fstring keystr, printer_name, cachestr;
TDB_DATA data, key;
- TDB_DATA jcdata;
- struct tdb_print_db *pdb;
- struct printif *current_printif = get_printer_fns( snum );
-
- fstrcpy(printer_name, lp_const_servicename(snum));
- pdb = get_print_db_byname(printer_name);
- if (!pdb)
- return;
+ /* Convert printer name (i.e. share name) to unix-codepage for all of the
+ * following tdb key generation */
+ fstrcpy(printer_name, lp_servicename(snum));
+ dos_to_unix(printer_name);
+
/*
* Check to see if someone else is doing this update.
* This is essentially a mutex on the update.
*/
- if (get_updating_pid(printer_name) != -1) {
- release_print_db(pdb);
+ if (get_updating_pid(printer_name) != -1)
return;
- }
/* Lock the queue for the database update */
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
/* Only wait 10 seconds for this. */
- if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
- release_print_db(pdb);
+ if (tdb_lock_bystring(tdb, keystr, 10) == -1) {
+ DEBUG(0,("print_queue_update: Failed to lock printing database\n" ));
return;
}
@@ -1020,8 +399,7 @@ static void print_queue_update(int snum)
/*
* Someone else is doing the update, exit.
*/
- tdb_unlock_bystring(pdb->tdb, keystr);
- release_print_db(pdb);
+ tdb_unlock_bystring(tdb, keystr);
return;
}
@@ -1037,7 +415,7 @@ static void print_queue_update(int snum)
* the update.
*/
- tdb_unlock_bystring(pdb->tdb, keystr);
+ tdb_unlock_bystring(tdb, keystr);
/*
* Update the cache time FIRST ! Stops others even
@@ -1046,7 +424,7 @@ static void print_queue_update(int snum)
*/
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
+ tdb_store_int32(tdb, cachestr, (int)time(NULL));
/* get the current queue using the appropriate interface */
ZERO_STRUCT(status);
@@ -1056,12 +434,6 @@ static void print_queue_update(int snum)
DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
"s" : "", printer_name));
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
-
- qsort(queue, qcount, sizeof(print_queue_struct),
- QSORT_CAST(printjob_comp));
-
/*
any job in the internal database that is marked as spooled
and doesn't exist in the system queue is considered finished
@@ -1072,35 +444,30 @@ static void print_queue_update(int snum)
fill in any system job numbers as we go
*/
-
- jcdata = get_jobs_changed_data(pdb);
-
for (i=0; i<qcount; i++) {
- uint32 jobid = print_parse_jobid(queue[i].fs_file);
+ int jobid = print_parse_jobid(queue[i].fs_file);
- if (jobid == (uint32)-1) {
+ if (jobid == -1) {
/* assume its a unix print job */
- print_unix_job(snum, &queue[i], jobid);
+ print_unix_job(snum, &queue[i]);
continue;
}
/* we have an active SMB print job - update its status */
- pjob = print_job_find(snum, jobid);
+ pjob = print_job_find(jobid);
if (!pjob) {
/* err, somethings wrong. Probably smbd was restarted
with jobs in the queue. All we can do is treat them
like unix jobs. Pity. */
- print_unix_job(snum, &queue[i], jobid);
+ print_unix_job(snum, &queue[i]);
continue;
}
pjob->sysjob = queue[i].job;
pjob->status = queue[i].status;
- pjob_store(snum, jobid, pjob);
- check_job_changed(snum, jcdata, jobid);
- }
- SAFE_FREE(jcdata.dptr);
+ print_job_store(jobid, pjob);
+ }
/* now delete any queued entries that don't appear in the
system queue */
@@ -1110,22 +477,23 @@ static void print_queue_update(int snum)
tstruct.total_jobs = 0;
tstruct.lpq_time = time(NULL);
- tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
-
- /* Store the linearised queue, max jobs only. */
- store_queue_struct(pdb, &tstruct);
+ tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
- SAFE_FREE(tstruct.queue);
+ safe_free(tstruct.queue);
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
- printer_name, tstruct.total_jobs ));
+ tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs);
- tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
+ /*
+ * Get the old print status. We will use this to compare the
+ * number of jobs. If they have changed we need to send a
+ * "changed" message to the smbds.
+ */
- get_queue_status(snum, &old_status);
- if (old_status.qcount != qcount)
+ if( qcount != get_queue_status(snum, &old_status)) {
DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
- old_status.qcount, qcount, printer_name ));
+ old_status.qcount, qcount, printer_name ));
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
+ }
/* store the new queue status structure */
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
@@ -1135,7 +503,7 @@ static void print_queue_update(int snum)
status.qcount = qcount;
data.dptr = (void *)&status;
data.dsize = sizeof(status);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
+ tdb_store(tdb, key, data, TDB_REPLACE);
/*
* Update the cache time again. We want to do this call
@@ -1143,217 +511,43 @@ static void print_queue_update(int snum)
*/
slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
+ tdb_store_int32(tdb, keystr, (int32)time(NULL));
/* Delete our pid from the db. */
set_updating_pid(printer_name, True);
- release_print_db(pdb);
}
/****************************************************************************
- Create/Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-BOOL print_notify_register_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- BOOL ret = False;
- size_t i;
-
- /* if (snum == -1), then the change notify request was
- on a print server handle and we need to register on
- all print queus */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if (lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_register_pid(idx);
- }
-
- return True;
- }
- else /* register for a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Add ourselves and increase the refcount. */
-
- for (i = 0; i < data.dsize; i += 8) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
- SIVAL(data.dptr, i+4, new_refcount);
- break;
- }
- }
-
- if (i == data.dsize) {
- /* We weren't in the list. Realloc. */
- data.dptr = Realloc(data.dptr, data.dsize + 8);
- if (!data.dptr) {
- DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
- printername));
- goto done;
- }
- data.dsize += 8;
- SIVAL(data.dptr,data.dsize - 8,mypid);
- SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
- }
-
- /* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
+ Check if a jobid is valid. It is valid if it exists in the database.
****************************************************************************/
-BOOL print_notify_deregister_pid(int snum)
+BOOL print_job_exists(int jobid)
{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- size_t i;
- BOOL ret = False;
-
- /* if ( snum == -1 ), we are deregister a print server handle
- which means to deregister on all print queues */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if ( lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_deregister_pid(idx);
- }
-
- return True;
- }
- else /* deregister a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock \
-printer %s database\n", printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Reduce refcount. Remove ourselves if zero. */
-
- for (i = 0; i < data.dsize; ) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 refcount = IVAL(data.dptr, i+4);
-
- refcount--;
-
- if (refcount == 0) {
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- continue;
- }
- SIVAL(data.dptr, i+4, refcount);
- }
-
- i += 8;
- }
-
- if (data.dsize == 0)
- SAFE_FREE(data.dptr);
-
- /* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
+ return tdb_exists(tdb, print_key(jobid));
}
/****************************************************************************
- Check if a jobid is valid. It is valid if it exists in the database.
+ Work out which service a jobid is for.
+ Note that we have to look up by queue name to ensure that it works for
+ other than the process that started the job.
****************************************************************************/
-BOOL print_job_exists(int snum, uint32 jobid)
+int print_job_snum(int jobid)
{
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- BOOL ret;
+ struct printjob *pjob = print_job_find(jobid);
+ if (!pjob)
+ return -1;
- if (!pdb)
- return False;
- ret = tdb_exists(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- return ret;
+ return find_service(pjob->queuename);
}
/****************************************************************************
Give the fd used for a jobid.
****************************************************************************/
-int print_job_fd(int snum, uint32 jobid)
+int print_job_fd(int jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
if (!pjob)
return -1;
/* don't allow another process to get this info - it is meaningless */
@@ -1368,36 +562,19 @@ int print_job_fd(int snum, uint32 jobid)
has not been spooled.
****************************************************************************/
-char *print_job_fname(int snum, uint32 jobid)
+char *print_job_fname(int jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
if (!pjob || pjob->spooled || pjob->pid != local_pid)
return NULL;
return pjob->filename;
}
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
-
- if ( !pjob )
- return NULL;
-
- return pjob->nt_devmode;
-}
-
/****************************************************************************
Set the place in the queue for a job.
****************************************************************************/
-BOOL print_job_set_place(int snum, uint32 jobid, int place)
+BOOL print_job_set_place(int jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
return False;
@@ -1407,81 +584,24 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place)
Set the name of a job. Only possible for owner.
****************************************************************************/
-BOOL print_job_set_name(int snum, uint32 jobid, char *name)
+BOOL print_job_set_name(int jobid, char *name)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
if (!pjob || pjob->pid != local_pid)
return False;
fstrcpy(pjob->jobname, name);
- return pjob_store(snum, jobid, pjob);
-}
-
-/***************************************************************************
- Remove a jobid from the 'jobs changed' list.
-***************************************************************************/
-
-static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
-{
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- TDB_DATA data, key;
- size_t job_count, i;
- BOOL ret = False;
- BOOL gotlock = False;
-
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
- ZERO_STRUCT(data);
-
- if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
- goto out;
-
- gotlock = True;
-
- data = tdb_fetch(pdb->tdb, key);
-
- if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
- goto out;
-
- job_count = data.dsize / 4;
- for (i = 0; i < job_count; i++) {
- uint32 ch_jobid;
-
- ch_jobid = IVAL(data.dptr, i*4);
- if (ch_jobid == jobid) {
- if (i < job_count -1 )
- memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
- data.dsize -= 4;
- if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
- goto out;
- break;
- }
- }
-
- ret = True;
- out:
-
- if (gotlock)
- tdb_chainunlock(pdb->tdb, key);
- SAFE_FREE(data.dptr);
- release_print_db(pdb);
- if (ret)
- DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
- else
- DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
- return ret;
+ return print_job_store(jobid, pjob);
}
/****************************************************************************
Delete a print job - don't update queue.
****************************************************************************/
-static BOOL print_job_delete1(int snum, uint32 jobid)
+static BOOL print_job_delete1(int jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int result = 0;
- struct printif *current_printif = get_printer_fns( snum );
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, result = 0;
if (!pjob)
return False;
@@ -1493,37 +613,32 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
if (pjob->status == LPQ_DELETING)
return True;
+ snum = print_job_snum(jobid);
+ if (snum == -1) {
+ DEBUG(5,("print_job_delete1: unknown service number for jobid %d\n", jobid));
+ return False;
+ }
+
/* Hrm - we need to be able to cope with deleting a job before it
has reached the spooler. */
if (pjob->sysjob == -1) {
- DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
+ DEBUG(5, ("attempt to delete job %d not seen by lpr\n", jobid));
}
/* Set the tdb entry to be deleting. */
pjob->status = LPQ_DELETING;
- pjob_store(snum, jobid, pjob);
+ print_job_store(jobid, pjob);
if (pjob->spooled && pjob->sysjob != -1)
result = (*(current_printif->job_delete))(snum, pjob);
- else
- remove_from_jobs_changed(snum, jobid);
- /* Delete the tdb entry if the delete succeeded or the job hasn't
+ /* Delete the tdb entry if the delete suceeded or the job hasn't
been spooled. */
if (result == 0) {
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int njobs = 1;
-
- if (!pdb)
- return False;
- pjob_delete(snum, jobid);
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
- release_print_db(pdb);
+ tdb_delete(tdb, print_key(jobid));
}
return (result == 0);
@@ -1533,18 +648,20 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
Return true if the current user owns the print job.
****************************************************************************/
-static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
+static BOOL is_owner(struct current_user *user, int jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
user_struct *vuser;
if (!pjob || !user)
return False;
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- return strequal(pjob->user, vuser->user.smb_name);
+ return strequal(pjob->user,
+ unix_to_dos_static(vuser->user.smb_name));
} else {
- return strequal(pjob->user, uidtoname(user->uid));
+ return strequal(pjob->user,
+ unix_to_dos_static(uidtoname(user->uid)));
}
}
@@ -1552,14 +669,18 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
Delete a print job.
****************************************************************************/
-BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
{
- BOOL owner, deleted;
- char *fname;
+ int snum = print_job_snum(jobid);
+ char *printer_name;
+ BOOL owner;
- *errcode = WERR_OK;
-
- owner = is_owner(user, snum, jobid);
+ if (snum == -1) {
+ DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid));
+ return False;
+ }
+
+ owner = is_owner(user, jobid);
/* Check access against security descriptor or whether the user
owns their job. */
@@ -1568,80 +689,51 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("delete denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
return False;
}
- /*
- * get the spooled filename of the print job
- * if this works, then the file has not been spooled
- * to the underlying print system. Just delete the
- * spool file & return.
- */
-
- if ( (fname = print_job_fname( snum, jobid )) != NULL )
- {
- /* remove the spool file */
- DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
- if ( unlink( fname ) == -1 ) {
- *errcode = map_werror_from_unix(errno);
- return False;
- }
-
- return True;
- }
-
- if (!print_job_delete1(snum, jobid)) {
- *errcode = WERR_ACCESS_DENIED;
+ if (!print_job_delete1(jobid))
return False;
- }
/* force update the database and say the delete failed if the
job still exists */
print_queue_update(snum);
-
- deleted = !print_job_exists(snum, jobid);
- if ( !deleted )
- *errcode = WERR_ACCESS_DENIED;
- return deleted;
+ /* Send a printer notify message */
+
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
+
+ return !print_job_exists(jobid);
}
/****************************************************************************
Pause a job.
****************************************************************************/
-BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret = -1;
- struct printif *current_printif = get_printer_fns( snum );
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, ret = -1;
+ char *printer_name;
- if (!pjob || !user)
+ if (!pjob || !user)
return False;
- if (!pjob->spooled || pjob->sysjob == -1)
+ if (!pjob->spooled || pjob->sysjob == -1)
return False;
- if (!is_owner(user, snum, jobid) &&
+ snum = print_job_snum(jobid);
+ if (snum == -1) {
+ DEBUG(5,("print_job_pause: unknown service number for jobid %d\n", jobid));
+ return False;
+ }
+
+ if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
*errcode = WERR_ACCESS_DENIED;
return False;
}
@@ -1659,7 +751,9 @@ pause, or resume print job. User name: %s. Printer name: %s.",
/* Send a printer notify message */
- notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
/* how do we tell if this succeeded? */
@@ -1670,11 +764,11 @@ pause, or resume print job. User name: %s. Printer name: %s.",
Resume a job.
****************************************************************************/
-BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
- struct printif *current_printif = get_printer_fns( snum );
+ struct printjob *pjob = print_job_find(jobid);
+ char *printer_name;
+ int snum, ret;
if (!pjob || !user)
return False;
@@ -1682,17 +776,16 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR
if (!pjob->spooled || pjob->sysjob == -1)
return False;
- if (!is_owner(user, snum, jobid) &&
+ snum = print_job_snum(jobid);
+ if (snum == -1) {
+ DEBUG(5,("print_job_resume: unknown service number for jobid %d\n", jobid));
+ return False;
+ }
+
+ if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
return False;
}
@@ -1708,7 +801,9 @@ pause, or resume print job. User name: %s. Printer name: %s.",
/* Send a printer notify message */
- notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
return True;
}
@@ -1717,10 +812,10 @@ pause, or resume print job. User name: %s. Printer name: %s.",
Write to a print file.
****************************************************************************/
-int print_job_write(int snum, uint32 jobid, const char *buf, int size)
+int print_job_write(int jobid, const char *buf, int size)
{
int return_code;
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
if (!pjob)
return -1;
@@ -1731,7 +826,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
return_code = write(pjob->fd, buf, size);
if (return_code>0) {
pjob->size += size;
- pjob_store(snum, jobid, pjob);
+ print_job_store(jobid, pjob);
}
return return_code;
}
@@ -1744,14 +839,10 @@ static BOOL print_cache_expired(int snum)
{
fstring key;
time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
+ slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
+ dos_to_unix(key); /* Convert key to unix-codepage */
+ last_qscan_time = (time_t)tdb_fetch_int32(tdb, key);
/*
* Invalidate the queue for 3 reasons.
@@ -1766,12 +857,10 @@ static BOOL print_cache_expired(int snum)
if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
+(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum),
(int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
return True;
}
- release_print_db(pdb);
return False;
}
@@ -1783,30 +872,20 @@ static int get_queue_status(int snum, print_status_struct *status)
{
fstring keystr;
TDB_DATA data, key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int len;
-
- if (!pdb)
- return 0;
- if (status) {
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(print_status_struct))
- /* this memcpy is ok since the status struct was
- not packed before storing it in the tdb */
- memcpy(status, data.dptr, sizeof(print_status_struct));
- SAFE_FREE(data.dptr);
+ ZERO_STRUCTP(status);
+ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
+ dos_to_unix(keystr); /* Convert key to unix-codepage */
+ key.dptr = keystr;
+ key.dsize = strlen(keystr);
+ data = tdb_fetch(tdb, key);
+ if (data.dptr) {
+ if (data.dsize == sizeof(print_status_struct)) {
+ memcpy(status, data.dptr, sizeof(print_status_struct));
}
+ SAFE_FREE(data.dptr);
}
- len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
- release_print_db(pdb);
- return (len == -1 ? 0 : len);
+ return status->qcount;
}
/****************************************************************************
@@ -1825,126 +904,53 @@ int print_queue_length(int snum, print_status_struct *pstatus)
/* also fetch the queue status */
memset(&status, 0, sizeof(status));
len = get_queue_status(snum, &status);
-
if (pstatus)
*pstatus = status;
-
return len;
}
-/***************************************************************************
- Allocate a jobid. Hold the lock for as short a time as possible.
-***************************************************************************/
-
-static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
-{
- int i;
- uint32 jobid;
-
- *pjobid = (uint32)-1;
-
- for (i = 0; i < 3; i++) {
- /* Lock the database - only wait 20 seconds. */
- if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
- DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
- return False;
- }
-
- if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
- if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
- DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
- printername ));
- return False;
- }
- jobid = 0;
- }
-
- jobid = NEXT_JOBID(jobid);
-
- if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
- DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
- return False;
- }
-
- /* We've finished with the INFO/nextjob lock. */
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
-
- if (!print_job_exists(snum, jobid))
- break;
- }
-
- if (i > 2) {
- DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
- printername ));
- /* Probably full... */
- errno = ENOSPC;
- return False;
- }
-
- /* Store a dummy placeholder. */
- {
- TDB_DATA dum;
- dum.dptr = NULL;
- dum.dsize = 0;
- if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
- DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
- jobid ));
- return False;
- }
- }
-
- *pjobid = jobid;
- return True;
-}
-
-/***************************************************************************
- Append a jobid to the 'jobs changed' list.
-***************************************************************************/
+/****************************************************************************
+ Determine the number of jobs in all queues.
+****************************************************************************/
-static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
+static int get_total_jobs(int snum)
{
- TDB_DATA data, key;
-
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
- data.dptr = (char *)&jobid;
- data.dsize = 4;
+ int total_jobs;
- DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
+ /* make sure the database is up to date */
+ if (print_cache_expired(snum))
+ print_queue_update(snum);
- return (tdb_append(pdb->tdb, key, data) == 0);
+ total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs");
+ if (total_jobs >0)
+ return total_jobs;
+ else
+ return 0;
}
/***************************************************************************
Start spooling a job - return the jobid.
***************************************************************************/
-uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
+int print_job_start(struct current_user *user, int snum, char *jobname)
{
- uint32 jobid;
+ int jobid;
char *path;
struct printjob pjob;
+ int next_jobid;
user_struct *vuser;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int njobs;
+ int njobs = 0;
errno = 0;
- if (!pdb)
- return (uint32)-1;
-
if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
- release_print_db(pdb);
- return (uint32)-1;
+ return -1;
}
if (!print_time_access_check(snum)) {
DEBUG(3, ("print_job_start: job start denied by time check\n"));
- release_print_db(pdb);
- return (uint32)-1;
+ return -1;
}
path = lp_pathname(snum);
@@ -1955,39 +961,36 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
if (sys_fsusage(path, &dspace, &dsize) == 0 &&
dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
DEBUG(3, ("print_job_start: disk space check failed.\n"));
- release_print_db(pdb);
errno = ENOSPC;
- return (uint32)-1;
+ return -1;
}
}
/* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
- DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
+ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
+ DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) ));
errno = ENOENT;
- return (uint32)-1;
+ return -1;
}
/* Insure the maximum queue size is not violated */
- if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
- DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
- printername, njobs, lp_maxprintjobs(snum) ));
- release_print_db(pdb);
+ if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
+ DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
+ njobs, lp_maxprintjobs(snum) ));
errno = ENOSPC;
- return (uint32)-1;
+ return -1;
}
- DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
- printername, njobs, lp_maxprintjobs(snum) ));
-
- if (!allocate_print_jobid(pdb, snum, printername, &jobid))
- goto fail;
+ /* Insure the maximum print jobs in the system is not violated */
+ if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
+ DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
+ njobs, lp_totalprintjobs() ));
+ errno = ENOSPC;
+ return -1;
+ }
/* create the database entry */
-
ZERO_STRUCT(pjob);
-
pjob.pid = local_pid;
pjob.sysjob = -1;
pjob.fd = -1;
@@ -1996,21 +999,43 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
pjob.size = 0;
pjob.spooled = False;
pjob.smbjob = True;
- pjob.nt_devmode = nt_devmode;
-
+
fstrcpy(pjob.jobname, jobname);
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- fstrcpy(pjob.user, vuser->user.smb_name);
+ fstrcpy(pjob.user, unix_to_dos_static(vuser->user.smb_name));
} else {
- fstrcpy(pjob.user, uidtoname(user->uid));
+ fstrcpy(pjob.user, unix_to_dos_static(uidtoname(user->uid)));
+ }
+
+ fstrcpy(pjob.queuename, lp_servicename(snum));
+
+ /* Lock the database - only wait 20 seconds. */
+ if (tdb_lock_bystring(tdb, "INFO/nextjob", 20) == -1) {
+ DEBUG(0,("print_job_start: failed to lock printing database.\n"));
+ return -1;
+ }
+
+ next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob");
+ if (next_jobid == -1)
+ next_jobid = 1;
+
+ for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
+ if (!print_job_exists(jobid))
+ break;
+ }
+ if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
+ DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n",
+ jobid, next_jobid ));
+ jobid = -1;
+ goto fail;
}
- fstrcpy(pjob.queuename, lp_const_servicename(snum));
+ tdb_store_int32(tdb, "INFO/nextjob", jobid);
/* we have a job entry - now create the spool file */
- slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
- path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
+ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
+ path, PRINT_SPOOL_PREFIX, jobid);
pjob.fd = smb_mkstemp(pjob.filename);
if (pjob.fd == -1) {
@@ -2026,35 +1051,41 @@ to open spool file %s.\n", pjob.filename));
goto fail;
}
- pjob_store(snum, jobid, &pjob);
+ print_job_store(jobid, &pjob);
- /* Update the 'jobs changed' entry used by print_queue_status. */
- add_to_jobs_changed(pdb, jobid);
+ tdb_unlock_bystring(tdb, "INFO/nextjob");
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
-
- release_print_db(pdb);
+ /*
+ * If the printer is marked as postscript output a leading
+ * file identifier to ensure the file is treated as a raw
+ * postscript file.
+ * This has a similar effect as CtrlD=0 in WIN.INI file.
+ * tim@fsg.com 09/06/94
+ */
+ if (lp_postscript(snum)) {
+ print_job_write(jobid, "%!\n",3);
+ }
return jobid;
fail:
- if (jobid != -1)
- pjob_delete(snum, jobid);
+ if (jobid != -1) {
+ tdb_delete(tdb, print_key(jobid));
+ }
- release_print_db(pdb);
+ tdb_unlock_bystring(tdb, "INFO/nextjob");
DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
- return (uint32)-1;
+ return -1;
}
/****************************************************************************
Update the number of pages spooled to jobid
****************************************************************************/
-void print_job_endpage(int snum, uint32 jobid)
+void print_job_endpage(int jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
if (!pjob)
return;
/* don't allow another process to get this info - it is meaningless */
@@ -2062,7 +1093,7 @@ void print_job_endpage(int snum, uint32 jobid)
return;
pjob->page_count++;
- pjob_store(snum, jobid, pjob);
+ print_job_store(jobid, pjob);
}
/****************************************************************************
@@ -2071,12 +1102,11 @@ void print_job_endpage(int snum, uint32 jobid)
error.
****************************************************************************/
-BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
+BOOL print_job_end(int jobid, BOOL normal_close)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, ret;
SMB_STRUCT_STAT sbuf;
- struct printif *current_printif = get_printer_fns( snum );
if (!pjob)
return False;
@@ -2084,6 +1114,12 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
if (pjob->spooled || pjob->pid != local_pid)
return False;
+ snum = print_job_snum(jobid);
+ if (snum == -1) {
+ DEBUG(5,("print_job_end: unknown service number for jobid %d\n", jobid));
+ return False;
+ }
+
if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
@@ -2100,7 +1136,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
goto fail;
}
- /* Technically, this is not quite right. If the printer has a separator
+ /* Technically, this is not quit right. If the printer has a separator
* page turned on, the NT spooler prints the separator page even if the
* print job is 0 bytes. 010215 JRR */
if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
@@ -2108,12 +1144,10 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
pjob->filename, pjob->size ? "deleted" : "zero length" ));
unlink(pjob->filename);
- pjob_delete(snum, jobid);
+ tdb_delete(tdb, print_key(jobid));
return True;
}
- pjob->smbjob = jobid;
-
ret = (*(current_printif->job_submit))(snum, pjob);
if (ret)
@@ -2123,7 +1157,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
pjob->spooled = True;
pjob->status = LPQ_QUEUED;
- pjob_store(snum, jobid, pjob);
+ print_job_store(jobid, pjob);
/* make sure the database is up to date */
if (print_cache_expired(snum))
@@ -2136,177 +1170,131 @@ fail:
/* The print job was not succesfully started. Cleanup */
/* Still need to add proper error return propagation! 010122:JRR */
unlink(pjob->filename);
- pjob_delete(snum, jobid);
- remove_from_jobs_changed(snum, jobid);
+ tdb_delete(tdb, print_key(jobid));
return False;
}
/****************************************************************************
- Get a snapshot of jobs in the system without traversing.
+ Utility fn to enumerate the print queue.
****************************************************************************/
-static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
+static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
- TDB_DATA data, key, cgdata;
- print_queue_struct *queue = NULL;
- uint32 qcount = 0;
- uint32 extra_count = 0;
- int total_count = 0;
- size_t len = 0;
- uint32 i;
- int max_reported_jobs = lp_max_reported_jobs(snum);
- BOOL ret = False;
+ struct traverse_struct *ts = (struct traverse_struct *)state;
+ struct printjob pjob;
+ int i, jobid;
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- *pcount = 0;
- *ppqueue = NULL;
+ if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int))
+ return 0;
+ memcpy(&jobid, key.dptr, sizeof(jobid));
+ memcpy(&pjob, data.dptr, sizeof(pjob));
+ unix_to_dos(pjob.queuename);
- ZERO_STRUCT(data);
- ZERO_STRUCT(cgdata);
- key.dptr = "INFO/linear_queue_array";
- key.dsize = strlen(key.dptr);
+ /* maybe it isn't for this queue */
+ if (ts->snum != lp_servicenumber(pjob.queuename))
+ return 0;
- /* Get the stored queue data. */
- data = tdb_fetch(pdb->tdb, key);
-
- if (data.dptr && data.dsize >= sizeof(qcount))
- len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
-
- /* Get the changed jobs list. */
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
+ if (ts->qcount >= ts->maxcount)
+ return 0;
- cgdata = tdb_fetch(pdb->tdb, key);
- if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
- extra_count = cgdata.dsize/4;
+ i = ts->qcount;
+
+ ts->queue[i].job = jobid;
+ ts->queue[i].size = pjob.size;
+ ts->queue[i].page_count = pjob.page_count;
+ ts->queue[i].status = pjob.status;
+ ts->queue[i].priority = 1;
+ ts->queue[i].time = pjob.starttime;
+ fstrcpy(ts->queue[i].fs_user, pjob.user);
+ fstrcpy(ts->queue[i].fs_file, pjob.jobname);
- DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
+ ts->qcount++;
- /* Allocate the queue size. */
- if (qcount == 0 && extra_count == 0)
- goto out;
-
- if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
- goto out;
-
- /* Retrieve the linearised queue data. */
-
- for( i = 0; i < qcount; i++) {
- uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
- len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
- &qjob,
- &qsize,
- &qpage_count,
- &qstatus,
- &qpriority,
- &qtime,
- queue[i].fs_user,
- queue[i].fs_file);
- queue[i].job = qjob;
- queue[i].size = qsize;
- queue[i].page_count = qpage_count;
- queue[i].status = qstatus;
- queue[i].priority = qpriority;
- queue[i].time = qtime;
- }
+ return 0;
+}
- total_count = qcount;
+struct traverse_count_struct {
+ int snum, count;
+};
- /* Add in the changed jobids. */
- for( i = 0; i < extra_count; i++) {
- uint32 jobid;
- struct printjob *pjob;
+/****************************************************************************
+ Utility fn to count the number of entries in the print queue.
+****************************************************************************/
- jobid = IVAL(cgdata.dptr, i*4);
- DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
- pjob = print_job_find(snum, jobid);
- if (!pjob) {
- DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
- remove_from_jobs_changed(snum, jobid);
- continue;
- }
+static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
+{
+ struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
+ struct printjob pjob;
+ int jobid;
- queue[total_count].job = jobid;
- queue[total_count].size = pjob->size;
- queue[total_count].page_count = pjob->page_count;
- queue[total_count].status = pjob->status;
- queue[total_count].priority = 1;
- queue[total_count].time = pjob->starttime;
- fstrcpy(queue[total_count].fs_user, pjob->user);
- fstrcpy(queue[total_count].fs_file, pjob->jobname);
- total_count++;
- }
+ if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int))
+ return 0;
+ memcpy(&jobid, key.dptr, sizeof(jobid));
+ memcpy(&pjob, data.dptr, sizeof(pjob));
+ unix_to_dos(pjob.queuename);
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
+ /* maybe it isn't for this queue */
+ if (ts->snum != lp_servicenumber(pjob.queuename))
+ return 0;
- qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
+ ts->count++;
- DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
+ return 0;
+}
- if (max_reported_jobs && total_count > max_reported_jobs)
- total_count = max_reported_jobs;
+/****************************************************************************
+ Sort print jobs by submittal time.
+****************************************************************************/
- *ppqueue = queue;
- *pcount = total_count;
+static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
+{
+ /* Silly cases */
- ret = True;
+ if (!j1 && !j2)
+ return 0;
+ if (!j1)
+ return -1;
+ if (!j2)
+ return 1;
- out:
+ /* Sort on job start time */
- SAFE_FREE(data.dptr);
- SAFE_FREE(cgdata.dptr);
- return ret;
+ if (j1->time == j2->time)
+ return 0;
+ return (j1->time > j2->time) ? 1 : -1;
}
/****************************************************************************
Get a printer queue listing.
- set queue = NULL and status = NULL if you just want to update the cache
****************************************************************************/
int print_queue_status(int snum,
- print_queue_struct **ppqueue,
+ print_queue_struct **queue,
print_status_struct *status)
{
+ struct traverse_struct tstruct;
+ struct traverse_count_struct tsc;
fstring keystr;
TDB_DATA data, key;
- const char *printername;
- struct tdb_print_db *pdb;
- int count = 0;
/* make sure the database is up to date */
-
if (print_cache_expired(snum))
print_queue_update(snum);
- /* return if we are done */
- if ( !ppqueue || !status )
- return 0;
-
- *ppqueue = NULL;
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return 0;
-
+ *queue = NULL;
+
/*
* Fetch the queue status. We must do this first, as there may
* be no jobs in the queue.
*/
-
ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
+ slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
+ dos_to_unix(keystr); /* Convert key to unix-codepage */
key.dptr = keystr;
key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch(tdb, key);
if (data.dptr) {
if (data.dsize == sizeof(*status)) {
- /* this memcpy is ok since the status struct was
- not packed before storing it in the tdb */
memcpy(status, data.dptr, sizeof(*status));
}
SAFE_FREE(data.dptr);
@@ -2316,14 +1304,50 @@ int print_queue_status(int snum,
* Now, fetch the print queue information. We first count the number
* of entries, and then only retrieve the queue if necessary.
*/
+ tsc.count = 0;
+ tsc.snum = snum;
+
+ tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
- if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
- release_print_db(pdb);
+ if (tsc.count == 0)
return 0;
- }
- release_print_db(pdb);
- return count;
+ /* Allocate the queue size. */
+ if ((tstruct.queue = (print_queue_struct *)
+ malloc(sizeof(print_queue_struct)*tsc.count)) == NULL)
+ return 0;
+
+ /*
+ * Fill in the queue.
+ * We need maxcount as the queue size may have changed between
+ * the two calls to tdb_traverse.
+ */
+ tstruct.qcount = 0;
+ tstruct.maxcount = tsc.count;
+ tstruct.snum = snum;
+
+ tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
+
+ /* Sort the queue by submission time otherwise they are displayed
+ in hash order. */
+
+ qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
+ QSORT_CAST(printjob_comp));
+
+ *queue = tstruct.queue;
+ return tstruct.qcount;
+}
+
+/****************************************************************************
+ Turn a queue name into a snum.
+****************************************************************************/
+
+int print_queue_snum(char *qname)
+{
+ int snum = lp_servicenumber(qname);
+ if (snum == -1 || !lp_print_ok(snum))
+ return -1;
+ return snum;
}
/****************************************************************************
@@ -2332,8 +1356,8 @@ int print_queue_status(int snum,
BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
{
+ char *printer_name;
int ret;
- struct printif *current_printif = get_printer_fns( snum );
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
*errcode = WERR_ACCESS_DENIED;
@@ -2352,7 +1376,9 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
/* Send a printer notify message */
- notify_printer_status(snum, PRINTER_STATUS_PAUSED);
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
return True;
}
@@ -2363,8 +1389,8 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
{
+ char *printer_name;
int ret;
- struct printif *current_printif = get_printer_fns( snum );
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
*errcode = WERR_ACCESS_DENIED;
@@ -2379,12 +1405,13 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
}
/* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
+ if (print_cache_expired(snum)) print_queue_update(snum);
/* Send a printer notify message */
- notify_printer_status(snum, PRINTER_STATUS_OK);
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
return True;
}
@@ -2397,6 +1424,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
{
print_queue_struct *queue;
print_status_struct status;
+ char *printer_name;
int njobs, i;
BOOL can_job_admin;
@@ -2407,14 +1435,20 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
njobs = print_queue_status(snum, &queue, &status);
for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, snum, queue[i].job);
+ BOOL owner = is_owner(user, queue[i].job);
if (owner || can_job_admin) {
- print_job_delete1(snum, queue[i].job);
+ print_job_delete1(queue[i].job);
}
}
- SAFE_FREE(queue);
+ safe_free(queue);
+
+ /* Send a printer notify message */
+
+ printer_name = PRINTERNAME(snum);
+
+ send_queue_message(printer_name, 0, PRINTER_CHANGE_JOB);
return True;
}
diff --git a/source/printing/printing_db.c b/source/printing/printing_db.c
deleted file mode 100644
index d402aa366f4..00000000000
--- a/source/printing/printing_db.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-static struct tdb_print_db *print_db_head;
-
-/****************************************************************************
- Function to find or create the printer specific job tdb given a printername.
- Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
-****************************************************************************/
-
-struct tdb_print_db *get_print_db_byname(const char *printername)
-{
- struct tdb_print_db *p = NULL, *last_entry = NULL;
- int num_open = 0;
- pstring printdb_path;
- BOOL done_become_root = False;
-
- for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
- /* Ensure the list terminates... JRA. */
- SMB_ASSERT(p->next != print_db_head);
-
- if (p->tdb && strequal(p->printer_name, printername)) {
- DLIST_PROMOTE(print_db_head, p);
- p->ref_count++;
- return p;
- }
- num_open++;
- last_entry = p;
- }
-
- /* Not found. */
- if (num_open >= MAX_PRINT_DBS_OPEN) {
- /* Try and recycle the last entry. */
- DLIST_PROMOTE(print_db_head, last_entry);
-
- for (p = print_db_head; p; p = p->next) {
- if (p->ref_count)
- continue;
- if (p->tdb) {
- if (tdb_close(print_db_head->tdb)) {
- DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
- print_db_head->printer_name ));
- return NULL;
- }
- }
- p->tdb = NULL;
- p->ref_count = 0;
- memset(p->printer_name, '\0', sizeof(p->printer_name));
- break;
- }
- if (p) {
- DLIST_PROMOTE(print_db_head, p);
- p = print_db_head;
- }
- }
-
- if (!p) {
- /* Create one. */
- p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
- if (!p) {
- DEBUG(0,("get_print_db: malloc fail !\n"));
- return NULL;
- }
- ZERO_STRUCTP(p);
- DLIST_ADD(print_db_head, p);
- }
-
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, printername);
- pstrcat(printdb_path, ".tdb");
-
- if (geteuid() != 0) {
- become_root();
- done_become_root = True;
- }
-
- p->tdb = tdb_open_ex(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT,
- 0600, smbd_tdb_log);
-
- if (done_become_root)
- unbecome_root();
-
- if (!p->tdb) {
- DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
- printdb_path ));
- DLIST_REMOVE(print_db_head, p);
- SAFE_FREE(p);
- return NULL;
- }
- fstrcpy(p->printer_name, printername);
- p->ref_count++;
- return p;
-}
-
-/***************************************************************************
- Remove a reference count.
-****************************************************************************/
-
-void release_print_db( struct tdb_print_db *pdb)
-{
- pdb->ref_count--;
- SMB_ASSERT(pdb->ref_count >= 0);
-}
-
-/***************************************************************************
- Close all open print db entries.
-****************************************************************************/
-
-void close_all_print_db(void)
-{
- struct tdb_print_db *p = NULL, *next_p = NULL;
-
- for (p = print_db_head; p; p = next_p) {
- next_p = p->next;
-
- if (p->tdb)
- tdb_close(p->tdb);
- DLIST_REMOVE(print_db_head, p);
- ZERO_STRUCTP(p);
- SAFE_FREE(p);
- }
-}
-
-
-/****************************************************************************
- Fetch and clean the pid_t record list for all pids interested in notify
- messages. data needs freeing on exit.
-****************************************************************************/
-
-TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
-{
- TDB_DATA data;
- size_t i;
-
- ZERO_STRUCT(data);
-
- data = tdb_fetch_bystring( tdb, NOTIFY_PID_LIST_KEY );
-
- if (!data.dptr) {
- ZERO_STRUCT(data);
- return data;
- }
-
- if (data.dsize % 8) {
- DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
- tdb_delete_bystring(tdb, NOTIFY_PID_LIST_KEY );
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- return data;
- }
-
- if (!cleanlist)
- return data;
-
- /*
- * Weed out all dead entries.
- */
-
- for( i = 0; i < data.dsize; i += 8) {
- pid_t pid = (pid_t)IVAL(data.dptr, i);
-
- if (pid == sys_getpid())
- continue;
-
- /* Entry is dead if process doesn't exist or refcount is zero. */
-
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
-
- /* Refcount == zero is a logic error and should never happen. */
- if (IVAL(data.dptr, i + 4) == 0) {
- DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
- (unsigned int)pid, printer_name ));
- }
-
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- }
- }
-
- return data;
-}
-
-
diff --git a/source/profile/profile.c b/source/profile/profile.c
index 689f67da997..cde3bb35a56 100644
--- a/source/profile/profile.c
+++ b/source/profile/profile.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
store smbd profiling information in shared memory
Copyright (C) Andrew Tridgell 1999
@@ -23,12 +24,10 @@
#ifdef WITH_PROFILE
#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
-#endif /* WITH_PROFILE */
-
-#ifdef WITH_PROFILE
static int shm_id;
static BOOL read_only;
-#endif
+
+#endif /* WITH_PROFILE */
struct profile_header *profile_h;
struct profile_stats *profile_p;
@@ -71,7 +70,7 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len)
DEBUG(1,("INFO: Profiling values cleared from pid %d\n", (int)src));
break;
}
-#else /* WITH_PROFILE */
+#else /* ndef WITH_PROFILE */
DEBUG(1,("INFO: Profiling support unavailable in this build.\n"));
#endif /* WITH_PROFILE */
}
@@ -95,6 +94,7 @@ void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len)
/*******************************************************************
open the profiling shared memory area
******************************************************************/
+
#ifdef WITH_PROFILE
BOOL profile_setup(BOOL rdonly)
{
@@ -136,10 +136,12 @@ BOOL profile_setup(BOOL rdonly)
return False;
}
- if (shm_ds.shm_perm.cuid != sec_initial_uid() || shm_ds.shm_perm.cgid != sec_initial_gid()) {
- DEBUG(0,("ERROR: we did not create the shmem (owned by another user)\n"));
+#if 0
+ if (shm_ds.shm_perm.cuid != 0 || shm_ds.shm_perm.cgid != 0) {
+ DEBUG(0,("ERROR: root did not create the shmem\n"));
return False;
}
+#endif
if (shm_ds.shm_segsz != sizeof(*profile_h)) {
DEBUG(0,("WARNING: profile size is %d (expected %d). Deleting\n",
diff --git a/source/python/README b/source/python/README
deleted file mode 100644
index 04f794215ab..00000000000
--- a/source/python/README
+++ /dev/null
@@ -1,28 +0,0 @@
-This directory contains Python bindings to allow you to access various
-aspects of Samba. At the moment their status is "experimental" and
-they are not built by default.
-
-In order to be able to compile samba-python you need to have python
-and the python-dev packages installed.
-
-Python libraries are always built for a particular version of Python
-(2.2, 2.1, etc), and libraries built for one version will not be seen
-by another. By default Samba's libraries are built for whatever is
-installed as "python" on your $PATH, but you can override this using
-the --with-python option. For example
-
- $ ./configure --with-python=python2.2
-
-To build:
-
-$ autoconf
-$ ./configure
-$ make python_ext
-
-Now, you can install the modules:
-
-$ cp build/lib.*/*.so /usr/lib/python2.1/lib-dynload/
-
-(the directory /usr/lib/python2.1 may vary, depending on your installation)
-
-Samba-python should work now!
diff --git a/source/python/examples/spoolss/changeid.py b/source/python/examples/spoolss/changeid.py
deleted file mode 100755
index 85fe0efe8a4..00000000000
--- a/source/python/examples/spoolss/changeid.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-#
-# Display the changeid for a list of printers given on the command line
-#
-# Sample usage:
-#
-# changeid.py '\\win2kdc1\magpie'
-#
-
-import sys
-from samba import spoolss
-
-if len(sys.argv) == 1:
- print "Usage: changeid.py <printername>"
- sys.exit(1)
-
-for printer in sys.argv[1:]:
-
- # Open printer handle
-
- try:
- hnd = spoolss.openprinter(printer)
- except:
- print "error opening printer %s" % printer
- sys.exit(1)
-
- # Fetch and display changeid
-
- info = hnd.getprinter(level = 0)
- print info["change_id"]
-
- # Clean up
-
- spoolss.closeprinter(hnd)
diff --git a/source/python/examples/spoolss/enumprinters.py b/source/python/examples/spoolss/enumprinters.py
deleted file mode 100755
index 478c46bc24c..00000000000
--- a/source/python/examples/spoolss/enumprinters.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-#
-# Display information on all printers on a print server. Defaults to
-# printer info level 1.
-#
-# Example: enumprinters.py win2kdc1
-#
-
-import sys
-from samba import spoolss
-
-if len(sys.argv) < 2 or len(sys.argv) > 3:
- print "Usage: enumprinters.py <servername> [infolevel]"
- sys.exit(1)
-
-printserver = sys.argv[1]
-
-level = 1
-if len(sys.argv) == 3:
- level = int(sys.argv[2])
-
-# Get list of printers
-
-try:
- printer_list = spoolss.enumprinters("\\\\%s" % printserver)
-except:
- print "error enumerating printers on %s" % printserver
- sys.exit(1)
-
-# Display basic info
-
-for printer in printer_list:
- h = spoolss.openprinter("\\\\%s\\%s" % (printserver, printer))
- info = h.getprinter(level = level)
- print "Printer info %d for %s: %s" % (level, printer, info)
- print
diff --git a/source/python/examples/spoolss/psec.py b/source/python/examples/spoolss/psec.py
deleted file mode 100755
index 498a0ef1744..00000000000
--- a/source/python/examples/spoolss/psec.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python
-#
-# Get or set the security descriptor on a printer
-#
-
-import sys, re, string
-from samba import spoolss
-
-if len(sys.argv) != 3:
- print "Usage: psec.py getsec|setsec printername"
- sys.exit(1)
-
-op = sys.argv[1]
-printername = sys.argv[2]
-
-# Display security descriptor
-
-if op == "getsec":
-
- try:
- hnd = spoolss.openprinter(printername)
- except:
- print "error opening printer %s" % printername
- sys.exit(1)
-
- secdesc = hnd.getprinter(level = 3)["security_descriptor"]
-
- print secdesc["owner_sid"]
- print secdesc["group_sid"]
-
- for acl in secdesc["dacl"]["ace_list"]:
- print "%d %d 0x%08x %s" % (acl["type"], acl["flags"],
- acl["mask"], acl["trustee"])
-
- spoolss.closeprinter(hnd)
-
- sys.exit(0)
-
-# Set security descriptor
-
-if op == "setsec":
-
- # Open printer
-
- try:
- hnd = spoolss.openprinter(printername,
- creds = {"domain": "NPSD-TEST2",
- "username": "Administrator",
- "password": "penguin"})
- except:
- print "error opening printer %s" % printername
- sys.exit(1)
-
- # Read lines from standard input and build security descriptor
-
- lines = sys.stdin.readlines()
-
- secdesc = {}
-
- secdesc["owner_sid"] = lines[0]
- secdesc["group_sid"] = lines[1]
-
- secdesc["revision"] = 1
- secdesc["dacl"] = {}
- secdesc["dacl"]["revision"] = 2
- secdesc["dacl"]["ace_list"] = []
-
- for acl in lines[2:]:
- match = re.match("(\d+) (\d+) (0[xX][\dA-Fa-f]+) (\S+)", acl)
- secdesc["dacl"]["ace_list"].append(
- {"type": int(match.group(1)), "flags": int(match.group(2)),
- "mask": string.atoi(match.group(3), 0), "trustee": match.group(4)})
-
- # Build info3 structure
-
- info3 = {}
-
- info3["flags"] = 0x8004 # self-relative, dacl present
- info3["level"] = 3
- info3["security_descriptor"] = secdesc
-
- hnd.setprinter(info3)
-
- spoolss.closeprinter(hnd)
- sys.exit(0)
-
-print "invalid operation %s" % op
-sys.exit(1)
diff --git a/source/python/examples/tdbpack/oldtdbutil.py b/source/python/examples/tdbpack/oldtdbutil.py
deleted file mode 100644
index ac435b8bacf..00000000000
--- a/source/python/examples/tdbpack/oldtdbutil.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python
-#############################################################
-# tdbutil
-#
-# Purpose:
-# Contains functions that are used to pack and unpack data
-# from Samba's tdb databases. Samba sometimes represents complex
-# data structures as a single value in a database. These functions
-# allow other python scripts to package data types into a single python
-# string and unpackage them.
-#
-#
-# XXXXX: This code is no longer used; it's just here for testing
-# compatibility with the new (much faster) C implementation.
-#
-##############################################################
-import string
-
-def pack(format,list):
- retstring = ''
- listind = 0
-
- # Cycle through format entries
- for type in format:
- # Null Terminated String
- if (type == 'f' or type == 'P'):
- retstring = retstring + list[listind] + "\000"
- # 4 Byte Number
- if (type == 'd'):
- retstring = retstring + PackNum(list[listind],4)
- # 2 Byte Number
- if (type == 'w'):
- retstring = retstring + PackNum(list[listind],2)
- # Pointer Value
- if (type == 'p'):
- if (list[listind]):
- retstring = retstring + PackNum(1,4)
- else:
- retstring = retstring + PackNum(0,4)
- # Buffer and Length
- if (type == 'B'):
- # length
- length = list[listind]
- retstring = retstring + PackNum(length,4)
- length = int(length)
- listind = listind + 1
- # buffer
- retstring = retstring + list[listind][:length]
-
- listind = listind + 1
-
- return retstring
-
-def unpack(format,buffer):
- retlist = []
- bufind = 0
-
- lasttype = ""
- for type in format:
- # Pointer Value
- if (type == 'p'):
- newvalue = UnpackNum(buffer[bufind:bufind+4])
- bufind = bufind + 4
- if (newvalue):
- newvalue = 1L
- else:
- newvalue = 0L
- retlist.append(newvalue)
- # Previous character till end of data
- elif (type == '$'):
- if (lasttype == 'f'):
- while (bufind < len(buffer)):
- newstring = ''
- while (buffer[bufind] != '\000'):
- newstring = newstring + buffer[bufind]
- bufind = bufind + 1
- bufind = bufind + 1
- retlist.append(newstring)
- # Null Terminated String
- elif (type == 'f' or type == 'P'):
- newstring = ''
- while (buffer[bufind] != '\000'):
- newstring = newstring + buffer[bufind]
- bufind = bufind + 1
- bufind = bufind + 1
- retlist.append(newstring)
- # 4 Byte Number
- elif (type == 'd'):
- newvalue = UnpackNum(buffer[bufind:bufind+4])
- bufind = bufind + 4
- retlist.append(newvalue)
- # 2 Byte Number
- elif (type == 'w'):
- newvalue = UnpackNum(buffer[bufind:bufind+2])
- bufind = bufind + 2
- retlist.append(newvalue)
- # Length and Buffer
- elif (type == 'B'):
- # Length
- length = UnpackNum(buffer[bufind:bufind+4])
- bufind = bufind + 4
- retlist.append(length)
- length = int(length)
- # Buffer
- retlist.append(buffer[bufind:bufind+length])
- bufind = bufind + length
-
- lasttype = type
-
- return ((retlist,buffer[bufind:]))
-
-def PackNum(myint,size):
- retstring = ''
- size = size * 2
- hint = hex(myint)[2:]
-
- # Check for long notation
- if (hint[-1:] == 'L'):
- hint = hint[:-1]
-
- addon = size - len(hint)
- for i in range(0,addon):
- hint = '0' + hint
-
- while (size > 0):
- val = string.atoi(hint[size-2:size],16)
- retstring = retstring + chr(val)
- size = size - 2
-
- return retstring
-
-def UnpackNum(buffer):
- size = len(buffer)
- mystring = ''
-
- for i in range(size-1,-1,-1):
- val = hex(ord(buffer[i]))[2:]
- if (len(val) == 1):
- val = '0' + val
- mystring = mystring + val
- if (len(mystring) > 4):
- return string.atol(mystring,16)
- else:
- return string.atoi(mystring,16)
diff --git a/source/python/examples/tdbpack/tdbtimetrial.py b/source/python/examples/tdbpack/tdbtimetrial.py
deleted file mode 100755
index be6404899d8..00000000000
--- a/source/python/examples/tdbpack/tdbtimetrial.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#! /usr/bin/python2.2
-
-def run_trial():
- # import tdbutil
- from samba.tdbpack import pack
-
- for i in xrange(500000):
- pack("ddffd", (10, 2, "mbp", "martin", 0))
- #s = "\n\0\0\0" + "\x02\0\0\0" + "mbp\0" + "martin\0" + "\0\0\0\0"
-
-if __name__ == '__main__':
- run_trial()
diff --git a/source/python/examples/tdbpack/test_tdbpack.py b/source/python/examples/tdbpack/test_tdbpack.py
deleted file mode 100755
index 837600f789e..00000000000
--- a/source/python/examples/tdbpack/test_tdbpack.py
+++ /dev/null
@@ -1,253 +0,0 @@
-#! /usr/bin/env python2.2
-
-__doc__ = """test case for samba.tdbpack functions
-
-tdbpack provides a means of pickling values into binary formats
-compatible with that used by the samba tdbpack()/tdbunpack()
-functions.
-
-Numbers are always stored in little-endian format; strings are stored
-in either DOS or Unix codepage as appropriate.
-
-The format for any particular element is encoded as a short ASCII
-string, with one character per field."""
-
-# Copyright (C) 2002 Hewlett-Packard.
-
-__author__ = 'Martin Pool <mbp@sourcefrog.net>'
-
-import unittest
-import oldtdbutil
-import samba.tdbpack
-
-both_unpackers = (samba.tdbpack.unpack, oldtdbutil.unpack)
-both_packers = (samba.tdbpack.pack, oldtdbutil.pack)
-
-
-
-# # ('B', [10, 'hello'], '\x0a\0\0\0hello'),
-# ('BB', [11, 'hello\0world', 3, 'now'],
-# '\x0b\0\0\0hello\0world\x03\0\0\0now'),
-# ('pd', [1, 10], '\x01\0\0\0\x0a\0\0\0'),
-# ('BBB', [5, 'hello', 0, '', 5, 'world'],
-# '\x05\0\0\0hello\0\0\0\0\x05\0\0\0world'),
-
- # strings are sequences in Python, there's no getting away
- # from it
-# ('ffff', 'evil', 'e\0v\0i\0l\0'),
-# ('BBBB', 'evil',
-# '\x01\0\0\0e'
-# '\x01\0\0\0v'
-# '\x01\0\0\0i'
-# '\x01\0\0\0l'),
-
-# ('', [], ''),
-
-# # exercise some long strings
-# ('PP', ['hello' * 255, 'world' * 255],
-# 'hello' * 255 + '\0' + 'world' * 255 + '\0'),
-# ('PP', ['hello' * 40000, 'world' * 50000],
-# 'hello' * 40000 + '\0' + 'world' * 50000 + '\0'),
-# ('B', [(5*51), 'hello' * 51], '\xff\0\0\0' + 'hello' * 51),
-# ('BB', [(5 * 40000), 'hello' * 40000,
-# (5 * 50000), 'world' * 50000],
-# '\x40\x0d\x03\0' + 'hello' * 40000 + '\x90\xd0\x03\x00' + 'world' * 50000),
-
-
-class PackTests(unittest.TestCase):
- symm_cases = [
- ('w', [42], '\x2a\0'),
- ('www', [42, 2, 69], '\x2a\0\x02\0\x45\0'),
- ('wd', [42, 256], '\x2a\0\0\x01\0\0'),
- ('w', [0], '\0\0'),
- ('w', [255], '\xff\0'),
- ('w', [256], '\0\x01'),
- ('w', [0xdead], '\xad\xde'),
- ('w', [0xffff], '\xff\xff'),
- ('p', [0], '\0\0\0\0'),
- ('p', [1], '\x01\0\0\0'),
- ('d', [0x01020304], '\x04\x03\x02\x01'),
- ('d', [0x7fffffff], '\xff\xff\xff\x7f'),
- ('d', [0x80000000L], '\x00\x00\x00\x80'),
- ('d', [0x80000069L], '\x69\x00\x00\x80'),
- ('d', [0xffffffffL], '\xff\xff\xff\xff'),
- ('d', [0xffffff00L], '\x00\xff\xff\xff'),
- ('ddd', [1, 10, 50], '\x01\0\0\0\x0a\0\0\0\x32\0\0\0'),
- ('ff', ['hello', 'world'], 'hello\0world\0'),
- ('fP', ['hello', 'world'], 'hello\0world\0'),
- ('PP', ['hello', 'world'], 'hello\0world\0'),
- ('B', [0, ''], '\0\0\0\0'),
-# old implementation is wierd when string is not the right length
-# ('B', [2, 'hello'], '\x0a\0\0\0hello'),
- ('B', [5, 'hello'], '\x05\0\0\0hello'),
- ]
-
- def test_symmetric(self):
- """Cookbook of symmetric pack/unpack tests
- """
- for packer in [samba.tdbpack.pack]: # both_packers:
- for unpacker in both_unpackers:
- for format, values, expected in self.symm_cases:
- out_packed = packer(format, values)
- self.assertEquals(out_packed, expected)
- out, rest = unpacker(format, expected)
- self.assertEquals(rest, '')
- self.assertEquals(list(values), list(out))
-
- def test_large(self):
- """Test large pack/unpack strings"""
- large_cases = [('w' * 1000, xrange(1000)), ]
- for packer in both_packers:
- for unpacker in both_unpackers:
- for format, values in large_cases:
- packed = packer(format, values)
- out, rest = unpacker(format, packed)
- self.assertEquals(rest, '')
- self.assertEquals(list(values), list(out))
-
-
- def test_pack(self):
- """Cookbook of expected pack values
-
- These can't be used for the symmetric test because the unpacked value is
- not "canonical".
- """
- cases = [('w', (42,), '\x2a\0'),
- ]
-
- for packer in both_packers:
- for format, values, expected in cases:
- self.assertEquals(packer(format, values), expected)
-
- def test_unpack_extra(self):
- # Test leftover data
- for unpacker in both_unpackers:
- for format, values, packed in self.symm_cases:
- out, rest = unpacker(format, packed + 'hello sailor!')
- self.assertEquals(rest, 'hello sailor!')
- self.assertEquals(list(values), list(out))
-
-
- def test_pack_extra(self):
- """Leftover values when packing"""
- cases = [
- ('d', [10, 20], [10]),
- ('d', [10, 'hello'], [10]),
- ('ff', ['hello', 'world', 'sailor'], ['hello', 'world']),
- ]
- for unpacker in both_unpackers:
- for packer in both_packers:
- for format, values, chopped in cases:
- bin = packer(format, values)
- out, rest = unpacker(format, bin)
- self.assertEquals(list(out), list(chopped))
- self.assertEquals(rest, '')
-
-
- def test_unpack(self):
- """Cookbook of tricky unpack tests"""
- cases = [
- # Apparently I couldn't think of any tests that weren't
- # symmetric :-/
- ]
- for unpacker in both_unpackers:
- for format, values, expected in cases:
- out, rest = unpacker(format, expected)
- self.assertEquals(rest, '')
- self.assertEquals(list(values), list(out))
-
-
- def test_pack_failures(self):
- """Expected errors for incorrect packing"""
- cases = [('w', []),
-# ('w', ()),
-# ('w', {}),
- ('ww', [2]),
- ('w', 2),
-# ('w', None),
- ('wwwwwwwwwwww', []),
-# ('w', [0x60A15EC5L]),
-# ('w', [None]),
- ('d', []),
- ('p', []),
- ('f', [2]),
- ('P', [None]),
- ('P', ()),
- ('f', [hex]),
- ('fw', ['hello']),
-# ('f', [u'hello']),
- ('B', [2]),
- (None, [2, 3, 4]),
- (ord('f'), [20]),
- # old code doesn't distinguish string from seq-of-char
-# (['w', 'w'], [2, 2]),
- # old code just ignores invalid characters
-# ('Q', [2]),
-# ('fQ', ['2', 3]),
-# ('fQ', ['2']),
- (2, [2]),
- # old code doesn't typecheck format
-# ({}, {})
- ]
- for packer in both_packers:
- for format, values in cases:
- try:
- packer(format, values)
- except StandardError:
- pass
- else:
- raise AssertionError("didn't get exception: format %s, values %s, packer %s"
- % (`format`, `values`, `packer`))
-
-
- def test_unpack_failures(self):
- """Expected errors for incorrect unpacking"""
- cases = [
-# This ought to be illegal, but the old code doesn't prohibit it
-# ('$', '', ValueError),
-# ('Q', '', ValueError),
-# ('Q$', '', ValueError),
- ('f', '', IndexError),
- ('d', '', IndexError),
-# This is an illegal packing, but the old code doesn't trap
-# ('d', '2', IndexError),
-# ('d', '22', IndexError),
-# ('d', '222', IndexError),
-# ('p', '\x01\0', IndexError),
-# ('w', '2', IndexError),
-# ('B', '\xff\0\0\0hello', IndexError),
-# ('B', '\xff\0', IndexError),
- ('w', '', IndexError),
- ('f', 'hello', IndexError),
- ('f', '', IndexError),
-# ('B', '\x01\0\0\0', IndexError),
-# ('B', '\x05\0\0\0hell', IndexError),
- ('B', '\xff\xff\xff\xff', ValueError),
-# ('B', 'foobar', IndexError),
-# ('BB', '\x01\0\0\0a\x01', IndexError),
- ]
-
- for unpacker in both_unpackers:
- for format, values, throwable_class in cases:
- try:
- unpacker(format, values)
- except StandardError:
- pass
- else:
- raise AssertionError("didn't get exception: format %s, values %s, unpacker %s"
- % (`format`, `values`, `unpacker`))
-
- def test_unpack_repeated(self):
- cases = [(('df$',
- '\x00\x00\x00\x00HP C LaserJet 4500-PS\x00Windows 4.0\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.HLP\x00\x00RAW\x00\\print$\\WIN40\\0\\readme.wri\x00\\print$\\WIN40\\0\\pscript.drv\x00\\print$\\WIN40\\0\\pscript.hlp\x00'),
- ([0L, 'HP C LaserJet 4500-PS', 'Windows 4.0', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.HLP', '', 'RAW', '\\print$\\WIN40\\0\\readme.wri', '\\print$\\WIN40\\0\\pscript.drv', '\\print$\\WIN40\\0\\pscript.hlp'], ''))]
- for unpacker in both_unpackers:
- for input, expected in cases:
- result = apply(unpacker, input)
- if result != expected:
- raise AssertionError("%s:\n input: %s\n output: %s\n expected: %s" % (`unpacker`, `input`, `result`, `expected`))
-
-
-if __name__ == '__main__':
- unittest.main()
-
diff --git a/source/python/gprinterdata b/source/python/gprinterdata
deleted file mode 100755
index cd062076c0b..00000000000
--- a/source/python/gprinterdata
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from gtkdictbrowser import GtkDictBrowser, hex_string
-import gtk
-from samba import spoolss
-import string
-import printerdata
-
-# Initialise printerdata dictionary
-
-if len(sys.argv) < 2 or len(sys.argv) > 3:
- print "Usage: gprinterdata [--ex] <printer>"
- print "where <printer> is a UNC printer name."
- sys.exit(1)
-
-try:
- host = string.replace(sys.argv[len(sys.argv) - 1], "/", "\\")
- if sys.argv[1] == "--ex":
- t = printerdata.printerdata_ex(host)
- else:
- t = printerdata.printerdata(host)
-except:
- print "gprinterdata: error opening %s" % sys.argv[len(sys.argv) - 1]
- sys.exit(1)
-
-# Create interface
-
-db = GtkDictBrowser(t)
-db.register_get_value_text_fn("", hex_string)
-db.build_ui('gprinterdata')
-
-# Override Python's handling of ctrl-c so we can break out of the
-# gui from the command line.
-
-import signal
-signal.signal(signal.SIGINT, signal.SIG_DFL)
-
-gtk.mainloop()
diff --git a/source/python/gtdbtool b/source/python/gtdbtool
deleted file mode 100755
index 129f4fe0e2e..00000000000
--- a/source/python/gtdbtool
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from gtkdictbrowser import GtkDictBrowser
-import gtk
-from samba import tdb
-import string
-
-# Open handle on tdb
-
-if len(sys.argv) != 2:
- print "Usage: gdbtool <tdbfile>"
- sys.exit(1)
-
-try:
- t = tdb.open(sys.argv[1])
-except tdb.error, t:
- print "gtdbtool: error opening %s: %s" % (sys.argv[1], t)
- sys.exit(1)
-
-# Create interface
-
-db = GtkDictBrowser(t)
-
-def display_key_x00(key):
- """Remove \x00 from all keys as they mucks up GTK."""
- return string.replace(key, "\x00", "")
-
-db.register_get_key_text_fn(display_key_x00)
-
-db.build_ui('gtdbtool')
-
-# Override Python's handling of ctrl-c so we can break out of the
-# gui from the command line.
-
-import signal
-signal.signal(signal.SIGINT, signal.SIG_DFL)
-
-gtk.mainloop()
diff --git a/source/python/gtkdictbrowser.py b/source/python/gtkdictbrowser.py
deleted file mode 100755
index dd8bed8f478..00000000000
--- a/source/python/gtkdictbrowser.py
+++ /dev/null
@@ -1,272 +0,0 @@
-#!/usr/bin/python
-#
-# Browse a Python dictionary in a two pane graphical interface written
-# in GTK.
-#
-# The GtkDictBrowser class is supposed to be generic enough to allow
-# applications to override enough methods and produce a
-# domain-specific browser provided the information is presented as a
-# Python dictionary.
-#
-# Possible applications:
-#
-# - Windows registry browser
-# - SPOOLSS printerdata browser
-# - tdb file browser
-#
-
-from gtk import *
-import string, re
-
-class GtkDictBrowser:
-
- def __init__(self, dict):
- self.dict = dict
-
- # This variable stores a list of (regexp, function) used to
- # convert the raw value data to a displayable string.
-
- self.get_value_text_fns = []
- self.get_key_text = lambda x: x
-
- # We can filter the list of keys displayed using a regex
-
- self.filter_regex = ""
-
- # Create and configure user interface widgets. A string argument is
- # used to set the window title.
-
- def build_ui(self, title):
- win = GtkWindow()
- win.set_title(title)
-
- win.connect("destroy", mainquit)
-
- hpaned = GtkHPaned()
- win.add(hpaned)
- hpaned.set_border_width(5)
- hpaned.show()
-
- vbox = GtkVBox()
- hpaned.add1(vbox)
- vbox.show()
-
- scrolled_win = GtkScrolledWindow()
- scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
- vbox.pack_start(scrolled_win)
- scrolled_win.show()
-
- hbox = GtkHBox()
- vbox.pack_end(hbox, expand = 0, padding = 5)
- hbox.show()
-
- label = GtkLabel("Filter:")
- hbox.pack_start(label, expand = 0, padding = 5)
- label.show()
-
- self.entry = GtkEntry()
- hbox.pack_end(self.entry, padding = 5)
- self.entry.show()
-
- self.entry.connect("activate", self.filter_activated)
-
- self.list = GtkList()
- self.list.set_selection_mode(SELECTION_MULTIPLE)
- self.list.set_selection_mode(SELECTION_BROWSE)
- scrolled_win.add_with_viewport(self.list)
- self.list.show()
-
- self.list.connect("select_child", self.key_selected)
-
- scrolled_win = GtkScrolledWindow()
- scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
- hpaned.add2(scrolled_win)
- scrolled_win.set_usize(500,400)
- scrolled_win.show()
-
- self.text = GtkText()
- self.text.set_editable(FALSE)
- scrolled_win.add_with_viewport(self.text)
- self.text.show()
-
- self.text.connect("event", self.event_handler)
-
- self.menu = GtkMenu()
- self.menu.show()
-
- self.font = load_font("fixed")
-
- self.update_keylist()
-
- win.show()
-
- # Add a key to the left hand side of the user interface
-
- def add_key(self, key):
- display_key = self.get_key_text(key)
- list_item = GtkListItem(display_key)
- list_item.set_data("raw_key", key) # Store raw key in item data
- self.list.add(list_item)
- list_item.show()
-
- # Event handler registered by build_ui()
-
- def event_handler(self, event, menu):
- return FALSE
-
- # Set the text to appear in the right hand side of the user interface
-
- def set_value_text(self, item):
-
- # Clear old old value in text window
-
- self.text.delete_text(0, self.text.get_length())
-
- if type(item) == str:
-
- # The text widget has trouble inserting text containing NULL
- # characters.
-
- item = string.replace(item, "\x00", ".")
-
- self.text.insert(self.font, None, None, item)
-
- else:
-
- # A non-text item
-
- self.text.insert(self.font, None, None, repr(item))
-
- # This function is called when a key is selected in the left hand side
- # of the user interface.
-
- def key_selected(self, list, list_item):
- key = list_item.children()[0].get()
-
- # Look for a match in the value display function list
-
- text = self.dict[list_item.get_data("raw_key")]
-
- for entry in self.get_value_text_fns:
- if re.match(entry[0], key):
- text = entry[1](text)
- break
-
- self.set_value_text(text)
-
- # Refresh the key list by removing all items and re-inserting them.
- # Items are only inserted if they pass through the filter regexp.
-
- def update_keylist(self):
- self.list.remove_items(self.list.children())
- self.set_value_text("")
- for k in self.dict.keys():
- if re.match(self.filter_regex, k):
- self.add_key(k)
-
- # Invoked when the user hits return in the filter text entry widget.
-
- def filter_activated(self, entry):
- self.filter_regex = entry.get_text()
- self.update_keylist()
-
- # Register a key display function
-
- def register_get_key_text_fn(self, fn):
- self.get_key_text = fn
-
- # Register a value display function
-
- def register_get_value_text_fn(self, regexp, fn):
- self.get_value_text_fns.append((regexp, fn))
-
-#
-# A utility function to convert a string to the standard hex + ascii format.
-# To display all values in hex do:
-# register_get_value_text_fn("", gtkdictbrowser.hex_string)
-#
-
-def hex_string(data):
- """Return a hex dump of a string as a string.
-
- The output produced is in the standard 16 characters per line hex +
- ascii format:
-
- 00000000: 40 00 00 00 00 00 00 00 40 00 00 00 01 00 04 80 @....... @.......
- 00000010: 01 01 00 00 00 00 00 01 00 00 00 00 ........ ....
- """
-
- pos = 0 # Position in data
- line = 0 # Line of data
-
- hex = "" # Hex display
- ascii = "" # ASCII display
-
- result = ""
-
- while pos < len(data):
-
- # Start with header
-
- if pos % 16 == 0:
- hex = "%08x: " % (line * 16)
- ascii = ""
-
- # Add character
-
- hex = hex + "%02x " % (ord(data[pos]))
-
- if ord(data[pos]) < 32 or ord(data[pos]) > 176:
- ascii = ascii + '.'
- else:
- ascii = ascii + data[pos]
-
- pos = pos + 1
-
- # Add separator if half way
-
- if pos % 16 == 8:
- hex = hex + " "
- ascii = ascii + " "
-
- # End of line
-
- if pos % 16 == 0:
- result = result + "%s %s\n" % (hex, ascii)
- line = line + 1
-
- # Leftover bits
-
- if pos % 16 != 0:
-
- # Pad hex string
-
- for i in range(0, (16 - (pos % 16))):
- hex = hex + " "
-
- # Half way separator
-
- if (pos % 16) < 8:
- hex = hex + " "
-
- result = result + "%s %s\n" % (hex, ascii)
-
- return result
-
-# For testing purposes, create a fixed dictionary to browse with
-
-if __name__ == "__main__":
-
- dict = {"chicken": "ham", "spam": "fun", "subdict": {"a": "b", "c": "d"}}
-
- db = GtkDictBrowser(dict)
-
- db.build_ui("GtkDictBrowser")
-
- # Override Python's handling of ctrl-c so we can break out of the
- # gui from the command line.
-
- import signal
- signal.signal(signal.SIGINT, signal.SIG_DFL)
-
- mainloop()
diff --git a/source/python/py_common.c b/source/python/py_common.c
deleted file mode 100644
index 02d22bbdab5..00000000000
--- a/source/python/py_common.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_common.h"
-
-/* Return a tuple of (error code, error string) from a WERROR */
-
-PyObject *py_werror_tuple(WERROR werror)
-{
- return Py_BuildValue("[is]", W_ERROR_V(werror),
- dos_errstr(werror));
-}
-
-/* Return a tuple of (error code, error string) from a WERROR */
-
-PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
-{
- return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
- nt_errstr(ntstatus));
-}
-
-/* Initialise samba client routines */
-
-static BOOL initialised;
-
-void py_samba_init(void)
-{
- if (initialised)
- return;
-
- /* Load configuration file */
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False))
- fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
-
- /* Misc other stuff */
-
- load_interfaces();
- init_names();
-
- initialised = True;
-}
-
-/* Debuglevel routines */
-
-PyObject *get_debuglevel(PyObject *self, PyObject *args)
-{
- PyObject *debuglevel;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- debuglevel = PyInt_FromLong(DEBUGLEVEL);
-
- return debuglevel;
-}
-
-PyObject *set_debuglevel(PyObject *self, PyObject *args)
-{
- int debuglevel;
-
- if (!PyArg_ParseTuple(args, "i", &debuglevel))
- return NULL;
-
- DEBUGLEVEL = debuglevel;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Initialise logging */
-
-PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
-{
- BOOL interactive = False;
- char *logfilename = NULL;
- static char *kwlist[] = {"interactive", "logfilename", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "|is", kwlist, &interactive, &logfilename))
- return NULL;
-
- if (interactive && logfilename) {
- PyErr_SetString(PyExc_RuntimeError,
- "can't be interactive and set log file name");
- return NULL;
- }
-
- if (interactive)
- setup_logging("spoolss", True);
-
- if (logfilename) {
- lp_set_logfile(logfilename);
- setup_logging(logfilename, False);
- reopen_logs();
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Parse credentials from a python dictionary. The dictionary can
- only have the keys "username", "domain" and "password". Return
- True for valid credentials in which case the username, domain and
- password are set to pointers to their values from the dicationary.
- If returns False, the errstr is set to point at some mallocated
- memory describing the error. */
-
-BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
- char **password, char **errstr)
-{
- /* Initialise anonymous credentials */
-
- *username = "";
- *domain = "";
- *password = "";
-
- if (creds && PyDict_Size(creds) > 0) {
- PyObject *username_obj, *password_obj, *domain_obj;
- PyObject *key, *value;
- int i;
-
- /* Check for presence of required fields */
-
- username_obj = PyDict_GetItemString(creds, "username");
- domain_obj = PyDict_GetItemString(creds, "domain");
- password_obj = PyDict_GetItemString(creds, "password");
-
- if (!username_obj) {
- *errstr = strdup("no username field in credential");
- return False;
- }
-
- if (!domain_obj) {
- *errstr = strdup("no domain field in credential");
- return False;
- }
-
- if (!password_obj) {
- *errstr = strdup("no password field in credential");
- return False;
- }
-
- /* Check type of required fields */
-
- if (!PyString_Check(username_obj)) {
- *errstr = strdup("username field is not string type");
- return False;
- }
-
- if (!PyString_Check(domain_obj)) {
- *errstr = strdup("domain field is not string type");
- return False;
- }
-
- if (!PyString_Check(password_obj)) {
- *errstr = strdup("password field is not string type");
- return False;
- }
-
- /* Look for any extra fields */
-
- i = 0;
-
- while (PyDict_Next(creds, &i, &key, &value)) {
- if (strcmp(PyString_AsString(key), "domain") != 0 &&
- strcmp(PyString_AsString(key), "username") != 0 &&
- strcmp(PyString_AsString(key), "password") != 0) {
- asprintf(errstr,
- "creds contain extra field '%s'",
- PyString_AsString(key));
- return False;
- }
- }
-
- /* Assign values */
-
- *username = PyString_AsString(username_obj);
- *domain = PyString_AsString(domain_obj);
- *password = PyString_AsString(password_obj);
- }
-
- *errstr = NULL;
-
- return True;
-}
-
-/* Return a cli_state to a RPC pipe on the given server. Use the
- credentials passed if not NULL. If an error occurs errstr is set to a
- string describing the error and NULL is returned. If set, errstr must
- be freed by calling free(). */
-
-struct cli_state *open_pipe_creds(char *server, PyObject *creds,
- int pipe_idx, char **errstr)
-{
- char *username, *password, *domain;
- struct cli_state *cli;
- NTSTATUS result;
-
- /* Extract credentials from the python dictionary */
-
- if (!py_parse_creds(creds, &username, &domain, &password, errstr))
- return NULL;
-
- /* Now try to connect */
-
- result = cli_full_connection(
- &cli, NULL, server, NULL, 0, "IPC$", "IPC",
- username, domain, password, 0, Undefined, NULL);
-
- if (!NT_STATUS_IS_OK(result)) {
- *errstr = strdup("error connecting to IPC$ pipe");
- return NULL;
- }
-
- if (!cli_nt_session_open(cli, pipe_idx)) {
- cli_shutdown(cli);
- asprintf(errstr, "error opening pipe index %d", pipe_idx);
- return NULL;
- }
-
- *errstr = NULL;
-
- return cli;
-}
-
-/* Return true if a dictionary contains a "level" key with an integer
- value. Set the value if so. */
-
-BOOL get_level_value(PyObject *dict, uint32 *level)
-{
- PyObject *obj;
-
- if (!(obj = PyDict_GetItemString(dict, "level")) ||
- !PyInt_Check(obj))
- return False;
-
- if (level)
- *level = PyInt_AsLong(obj);
-
- return True;
-}
diff --git a/source/python/py_common.h b/source/python/py_common.h
deleted file mode 100644
index 2bbd148ff4b..00000000000
--- a/source/python/py_common.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_COMMON_H
-#define _PY_COMMON_H
-
-#include "includes.h"
-
-/* This symbol is used in both includes.h and Python.h which causes an
- annoying compiler warning. */
-
-#ifdef HAVE_FSTAT
-#undef HAVE_FSTAT
-#endif
-
-#include "Python.h"
-
-/* Return a cli_state struct opened on the specified pipe. If credentials
- are passed use them. */
-
-typedef struct cli_state *(cli_pipe_fn)(
- struct cli_state *cli, char *system_name,
- struct ntuser_creds *creds);
-
-/* The following definitions come from python/py_common.c */
-
-PyObject *py_werror_tuple(WERROR werror);
-PyObject *py_ntstatus_tuple(NTSTATUS ntstatus);
-void py_samba_init(void);
-PyObject *get_debuglevel(PyObject *self, PyObject *args);
-PyObject *set_debuglevel(PyObject *self, PyObject *args);
-PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw);
-BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
- char **password, char **errstr);
-struct cli_state *open_pipe_creds(char *server, PyObject *creds,
- int pipe_idx, char **errstr);
-BOOL get_level_value(PyObject *dict, uint32 *level);
-
-/* The following definitions come from python/py_ntsec.c */
-
-BOOL py_from_SID(PyObject **obj, DOM_SID *sid);
-BOOL py_to_SID(DOM_SID *sid, PyObject *obj);
-BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace);
-BOOL py_to_ACE(SEC_ACE *ace, PyObject *dict);
-BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl);
-BOOL py_to_ACL(SEC_ACL *acl, PyObject *dict, TALLOC_CTX *mem_ctx);
-BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd);
-BOOL py_to_SECDESC(SEC_DESC **sd, PyObject *dict, TALLOC_CTX *mem_ctx);
-
-#endif /* _PY_COMMON_H */
diff --git a/source/python/py_conv.c b/source/python/py_conv.c
deleted file mode 100644
index d0a2d78aabd..00000000000
--- a/source/python/py_conv.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "py_conv.h"
-
-/* Helper for rpcstr_pull() function */
-
-static void fstr_pull(fstring str, UNISTR *uni)
-{
- rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
-}
-
-static void fstr_pull2(fstring str, UNISTR2 *uni)
-{
- rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
-}
-
-/* Convert a structure to a Python dict */
-
-PyObject *from_struct(void *s, struct pyconv *conv)
-{
- PyObject *obj, *item;
- int i;
-
- obj = PyDict_New();
-
- for (i = 0; conv[i].name; i++) {
- switch (conv[i].type) {
- case PY_UNISTR: {
- UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
- fstring str = "";
-
- if (u->buffer)
- fstr_pull(str, u);
-
- item = PyString_FromString(str);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_UNISTR2: {
- UNISTR2 *u = (UNISTR2 *)((char *)s + conv[i].offset);
- fstring str = "";
-
- if (u->buffer)
- fstr_pull2(str, u);
-
- item = PyString_FromString(str);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_UINT32: {
- uint32 *u = (uint32 *)((char *)s + conv[i].offset);
-
- item = PyInt_FromLong(*u);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_UINT16: {
- uint16 *u = (uint16 *)((char *)s + conv[i].offset);
-
- item = PyInt_FromLong(*u);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_STRING: {
- char *str = (char *)s + conv[i].offset;
-
- item = PyString_FromString(str);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_UID: {
- uid_t *uid = (uid_t *)((char *)s + conv[i].offset);
-
- item = PyInt_FromLong(*uid);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- case PY_GID: {
- gid_t *gid = (gid_t *)((char *)s + conv[i].offset);
-
- item = PyInt_FromLong(*gid);
- PyDict_SetItemString(obj, conv[i].name, item);
-
- break;
- }
- default:
-
- break;
- }
- }
-
- return obj;
-}
-
-/* Convert a Python dict to a structure */
-
-BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv)
-{
- PyObject *visited, *key, *value;
- BOOL result = False;
- int i;
-
- visited = PyDict_New();
-
- for (i = 0; conv[i].name; i++) {
- PyObject *obj;
-
- obj = PyDict_GetItemString(dict, conv[i].name);
-
- if (!obj)
- goto done;
-
- switch (conv[i].type) {
- case PY_UNISTR: {
- UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
- char *str = "";
-
- if (!PyString_Check(obj))
- goto done;
-
- str = PyString_AsString(obj);
- init_unistr(u, str);
-
- break;
- }
- case PY_UINT32: {
- uint32 *u = (uint32 *)((char *)s + conv[i].offset);
-
- if (!PyInt_Check(obj))
- goto done;
-
- *u = PyInt_AsLong(obj);
-
- break;
- }
- case PY_UINT16: {
- uint16 *u = (uint16 *)((char *)s + conv[i].offset);
-
- if (!PyInt_Check(obj))
- goto done;
-
- *u = PyInt_AsLong(obj);
- break;
- }
- default:
- break;
- }
-
- /* Mark as visited */
-
- PyDict_SetItemString(visited, conv[i].name,
- PyInt_FromLong(1));
- }
-
- /* Iterate over each item in the input dictionary and see if it was
- visited. If it wasn't then the user has added some extra crap
- to the dictionary. */
-
- i = 0;
-
- while (PyDict_Next(dict, &i, &key, &value)) {
- if (!PyDict_GetItem(visited, key))
- goto done;
- }
-
- result = True;
-
-done:
- /* We must decrement the reference count here or the visited
- dictionary will not be freed. */
-
- Py_DECREF(visited);
-
- return result;
-}
-
-/* Convert a NULL terminated list of NULL terminated unicode strings
- to a list of (char *) strings */
-
-PyObject *from_unistr_list(uint16 *dependentfiles)
-{
- PyObject *list;
- int offset = 0;
-
- list = PyList_New(0);
-
- while (*(dependentfiles + offset) != 0) {
- fstring name;
- int len;
-
- len = rpcstr_pull(name, dependentfiles + offset,
- sizeof(fstring), -1, STR_TERMINATE);
-
- offset += len / 2;
- PyList_Append(list, PyString_FromString(name));
- }
-
- return list;
-}
diff --git a/source/python/py_conv.h b/source/python/py_conv.h
deleted file mode 100644
index 798661c3a0e..00000000000
--- a/source/python/py_conv.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_CONV_H
-#define _PY_CONV_H
-
-#include "python/py_common.h"
-
-enum pyconv_types { PY_UNISTR, PY_UNISTR2, PY_UINT32, PY_UINT16, PY_STRING,
- PY_UID, PY_GID };
-
-struct pyconv {
- char *name; /* Name of member */
- enum pyconv_types type; /* Type */
- size_t offset; /* Offset into structure */
-};
-
-PyObject *from_struct(void *s, struct pyconv *conv);
-BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv);
-PyObject *from_unistr_list(uint16 *dependentfiles);
-
-/* Another version of offsetof (-: */
-
-#undef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
-#endif /* _PY_CONV_H */
diff --git a/source/python/py_lsa.c b/source/python/py_lsa.c
deleted file mode 100644
index 07191be8682..00000000000
--- a/source/python/py_lsa.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_lsa.h"
-
-PyObject *new_lsa_policy_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- lsa_policy_hnd_object *o;
-
- o = PyObject_New(lsa_policy_hnd_object, &lsa_policy_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-/*
- * Exceptions raised by this module
- */
-
-PyObject *lsa_error; /* This indicates a non-RPC related error
- such as name lookup failure */
-
-PyObject *lsa_ntstatus; /* This exception is raised when a RPC call
- returns a status code other than
- NT_STATUS_OK */
-
-/*
- * Open/close lsa handles
- */
-
-static PyObject *lsa_open_policy(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- static char *kwlist[] = { "servername", "creds", "access", NULL };
- char *server, *errstr;
- PyObject *creds = NULL, *result = NULL;
- uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
- struct cli_state *cli = NULL;
- NTSTATUS ntstatus;
- TALLOC_CTX *mem_ctx = NULL;
- POLICY_HND hnd;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|Oi", kwlist, &server, &creds, &desired_access))
- return NULL;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (!(cli = open_pipe_creds(server, creds, PI_LSARPC, &errstr))) {
- PyErr_SetString(lsa_error, errstr);
- free(errstr);
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("lsa_open_policy"))) {
- PyErr_SetString(lsa_error, "unable to init talloc context\n");
- goto done;
- }
-
- ntstatus = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED, &hnd);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- result = new_lsa_policy_hnd_object(cli, mem_ctx, &hnd);
-
-done:
- if (!result) {
- if (cli)
- cli_shutdown(cli);
-
- talloc_destroy(mem_ctx);
- }
-
- return result;
-}
-
-static PyObject *lsa_close(PyObject *self, PyObject *args, PyObject *kw)
-{
- PyObject *po;
- lsa_policy_hnd_object *hnd;
- NTSTATUS result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTuple(args, "O!", &lsa_policy_hnd_type, &po))
- return NULL;
-
- hnd = (lsa_policy_hnd_object *)po;
-
- /* Call rpc function */
-
- result = cli_lsa_close(hnd->cli, hnd->mem_ctx, &hnd->pol);
-
- /* Cleanup samba stuff */
-
- cli_shutdown(hnd->cli);
- talloc_destroy(hnd->mem_ctx);
-
- /* Return value */
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
-{
- PyObject *py_names, *result = NULL;
- NTSTATUS ntstatus;
- lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
- int num_names, i;
- const char **names;
- DOM_SID *sids;
- TALLOC_CTX *mem_ctx = NULL;
- uint32 *name_types;
-
- if (!PyArg_ParseTuple(args, "O", &py_names))
- return NULL;
-
- if (!PyList_Check(py_names) && !PyString_Check(py_names)) {
- PyErr_SetString(PyExc_TypeError, "must be list or string");
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("lsa_lookup_names"))) {
- PyErr_SetString(lsa_error, "unable to init talloc context\n");
- goto done;
- }
-
- if (PyList_Check(py_names)) {
-
- /* Convert list to char ** array */
-
- num_names = PyList_Size(py_names);
- names = (const char **)talloc(mem_ctx, num_names * sizeof(char *));
-
- for (i = 0; i < num_names; i++) {
- PyObject *obj = PyList_GetItem(py_names, i);
-
- names[i] = talloc_strdup(mem_ctx, PyString_AsString(obj));
- }
-
- } else {
-
- /* Just a single element */
-
- num_names = 1;
- names = (const char **)talloc(mem_ctx, sizeof(char *));
-
- names[0] = PyString_AsString(py_names);
- }
-
- ntstatus = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol,
- num_names, names, &sids, &name_types);
-
- if (!NT_STATUS_IS_OK(ntstatus) && NT_STATUS_V(ntstatus) != 0x107) {
- PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- result = PyList_New(num_names);
-
- for (i = 0; i < num_names; i++) {
- PyObject *sid_obj, *obj;
-
- py_from_SID(&sid_obj, &sids[i]);
-
- obj = Py_BuildValue("(Ni)", sid_obj, name_types[i]);
-
- PyList_SetItem(result, i, obj);
- }
-
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- PyObject *py_sids, *result = NULL;
- NTSTATUS ntstatus;
- int num_sids, i;
- char **domains, **names;
- uint32 *types;
- lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
- TALLOC_CTX *mem_ctx = NULL;
- DOM_SID *sids;
-
- if (!PyArg_ParseTuple(args, "O", &py_sids))
- return NULL;
-
- if (!PyList_Check(py_sids) && !PyString_Check(py_sids)) {
- PyErr_SetString(PyExc_TypeError, "must be list or string");
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("lsa_lookup_sids"))) {
- PyErr_SetString(lsa_error, "unable to init talloc context\n");
- goto done;
- }
-
- if (PyList_Check(py_sids)) {
-
- /* Convert dictionary to char ** array */
-
- num_sids = PyList_Size(py_sids);
- sids = (DOM_SID *)talloc(mem_ctx, num_sids * sizeof(DOM_SID));
-
- memset(sids, 0, num_sids * sizeof(DOM_SID));
-
- for (i = 0; i < num_sids; i++) {
- PyObject *obj = PyList_GetItem(py_sids, i);
-
- if (!string_to_sid(&sids[i], PyString_AsString(obj))) {
- PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
- goto done;
- }
- }
-
- } else {
-
- /* Just a single element */
-
- num_sids = 1;
- sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID));
-
- if (!string_to_sid(&sids[0], PyString_AsString(py_sids))) {
- PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
- goto done;
- }
- }
-
- ntstatus = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
- num_sids, sids, &domains, &names,
- &types);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- result = PyList_New(num_sids);
-
- for (i = 0; i < num_sids; i++) {
- PyObject *obj;
-
- obj = Py_BuildValue("{sssssi}", "username", names[i],
- "domain", domains[i], "name_type",
- types[i]);
-
- PyList_SetItem(result, i, obj);
- }
-
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-static PyObject *lsa_enum_trust_dom(PyObject *self, PyObject *args)
-{
- lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
- NTSTATUS ntstatus;
- uint32 enum_ctx = 0, num_domains, i;
- char **domain_names;
- DOM_SID *domain_sids;
- PyObject *result;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- ntstatus = cli_lsa_enum_trust_dom(
- hnd->cli, hnd->mem_ctx, &hnd->pol, &enum_ctx,
- &num_domains, &domain_names, &domain_sids);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- return NULL;
- }
-
- result = PyList_New(num_domains);
-
- for (i = 0; i < num_domains; i++) {
- fstring sid_str;
-
- sid_to_string(sid_str, &domain_sids[i]);
- PyList_SetItem(
- result, i,
- Py_BuildValue("(ss)", domain_names[i], sid_str));
- }
-
- return result;
-}
-
-/*
- * Method dispatch tables
- */
-
-static PyMethodDef lsa_hnd_methods[] = {
-
- /* SIDs<->names */
-
- { "lookup_sids", (PyCFunction)lsa_lookup_sids,
- METH_VARARGS | METH_KEYWORDS,
- "Convert sids to names." },
-
- { "lookup_names", (PyCFunction)lsa_lookup_names,
- METH_VARARGS | METH_KEYWORDS,
- "Convert names to sids." },
-
- /* Trusted domains */
-
- { "enum_trusted_domains", (PyCFunction)lsa_enum_trust_dom,
- METH_VARARGS,
- "Enumerate trusted domains." },
-
- { NULL }
-};
-
-static void py_lsa_policy_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyObject *py_lsa_policy_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(lsa_hnd_methods, self, attrname);
-}
-
-PyTypeObject lsa_policy_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "LSA Policy Handle",
- sizeof(lsa_policy_hnd_object),
- 0,
- py_lsa_policy_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_lsa_policy_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-static PyMethodDef lsa_methods[] = {
-
- /* Open/close lsa handles */
-
- { "open_policy", (PyCFunction)lsa_open_policy,
- METH_VARARGS | METH_KEYWORDS,
- "Open a policy handle" },
-
- { "close", (PyCFunction)lsa_close,
- METH_VARARGS,
- "Close a policy handle" },
-
- /* Other stuff - this should really go into a samba config module
- but for the moment let's leave it here. */
-
- { "setup_logging", (PyCFunction)py_setup_logging,
- METH_VARARGS | METH_KEYWORDS,
- "Set up debug logging.\n"
-"\n"
-"Initialises Samba's debug logging system. One argument is expected which\n"
-"is a boolean specifying whether debugging is interactive and sent to stdout\n"
-"or logged to a file.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> lsa.setup_logging(interactive = 1)" },
-
- { "get_debuglevel", (PyCFunction)get_debuglevel,
- METH_VARARGS,
- "Set the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> lsa.get_debuglevel()\n"
-"0" },
-
- { "set_debuglevel", (PyCFunction)set_debuglevel,
- METH_VARARGS,
- "Get the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> lsa.set_debuglevel(10)" },
-
- { NULL }
-};
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
- { NULL }
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/*
- * Module initialisation
- */
-
-void initlsa(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("lsa", lsa_methods);
- dict = PyModule_GetDict(module);
-
- lsa_error = PyErr_NewException("lsa.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", lsa_error);
-
- lsa_ntstatus = PyErr_NewException("lsa.ntstatus", NULL, NULL);
- PyDict_SetItemString(dict, "ntstatus", lsa_ntstatus);
-
- /* Initialise policy handle object */
-
- lsa_policy_hnd_type.ob_type = &PyType_Type;
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Do samba initialisation */
-
- py_samba_init();
-
- setup_logging("lsa", True);
- DEBUGLEVEL = 10;
-}
diff --git a/source/python/py_lsa.h b/source/python/py_lsa.h
deleted file mode 100644
index 99f3de50b1f..00000000000
--- a/source/python/py_lsa.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_LSA_H
-#define _PY_LSA_H
-
-#include "python/py_common.h"
-
-/* LSA policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND pol;
-} lsa_policy_hnd_object;
-
-/* Exceptions raised by this module */
-
-extern PyTypeObject lsa_policy_hnd_type;
-
-extern PyObject *lsa_error;
-
-#endif /* _PY_LSA_H */
diff --git a/source/python/py_ntsec.c b/source/python/py_ntsec.c
deleted file mode 100644
index 5ce5e8fc1be..00000000000
--- a/source/python/py_ntsec.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_common.h"
-
-/* Convert a SID to a Python dict */
-
-BOOL py_from_SID(PyObject **obj, DOM_SID *sid)
-{
- fstring sidstr;
-
- if (!sid) {
- Py_INCREF(Py_None);
- *obj = Py_None;
- return True;
- }
-
- if (!sid_to_string(sidstr, sid))
- return False;
-
- *obj = PyString_FromString(sidstr);
-
- return True;
-}
-
-BOOL py_to_SID(DOM_SID *sid, PyObject *obj)
-{
- if (!PyString_Check(obj))
- return False;
-
- return string_to_sid(sid, PyString_AsString(obj));
-}
-
-BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace)
-{
- PyObject *obj;
-
- if (!ace) {
- Py_INCREF(Py_None);
- *dict = Py_None;
- return True;
- }
-
- *dict = Py_BuildValue("{sisisi}", "type", ace->type,
- "flags", ace->flags,
- "mask", ace->info.mask);
-
- if (py_from_SID(&obj, &ace->trustee)) {
- PyDict_SetItemString(*dict, "trustee", obj);
- Py_DECREF(obj);
- }
-
- return True;
-}
-
-BOOL py_to_ACE(SEC_ACE *ace, PyObject *dict)
-{
- PyObject *obj;
- uint8 ace_type, ace_flags;
- DOM_SID trustee;
- SEC_ACCESS sec_access;
-
- if (!PyDict_Check(dict))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "type")) ||
- !PyInt_Check(obj))
- return False;
-
- ace_type = PyInt_AsLong(obj);
-
- if (!(obj = PyDict_GetItemString(dict, "flags")) ||
- !PyInt_Check(obj))
- return False;
-
- ace_flags = PyInt_AsLong(obj);
-
- if (!(obj = PyDict_GetItemString(dict, "trustee")) ||
- !PyString_Check(obj))
- return False;
-
- if (!py_to_SID(&trustee, obj))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "mask")) ||
- !PyInt_Check(obj))
- return False;
-
- sec_access.mask = PyInt_AsLong(obj);
-
- init_sec_ace(ace, &trustee, ace_type, sec_access, ace_flags);
-
- /* Fill in size field */
-
- ace->size = SEC_ACE_HEADER_SIZE + sid_size(&trustee);
-
- return True;
-}
-
-BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl)
-{
- PyObject *ace_list;
- int i;
-
- if (!acl) {
- Py_INCREF(Py_None);
- *dict = Py_None;
- return True;
- }
-
- ace_list = PyList_New(acl->num_aces);
-
- for (i = 0; i < acl->num_aces; i++) {
- PyObject *obj;
-
- if (py_from_ACE(&obj, &acl->ace[i]))
- PyList_SetItem(ace_list, i, obj);
- }
-
- *dict = Py_BuildValue("{sisN}", "revision", acl->revision,
- "ace_list", ace_list);
-
- return True;
-}
-
-BOOL py_to_ACL(SEC_ACL *acl, PyObject *dict, TALLOC_CTX *mem_ctx)
-{
- PyObject *obj;
- uint32 i;
-
- if (!(obj = PyDict_GetItemString(dict, "revision")) ||
- !PyInt_Check(obj))
- return False;
-
- acl->revision = PyInt_AsLong(obj);
-
- if (!(obj = PyDict_GetItemString(dict, "ace_list")) ||
- !PyList_Check(obj))
- return False;
-
- acl->num_aces = PyList_Size(obj);
-
- acl->ace = talloc(mem_ctx, acl->num_aces * sizeof(SEC_ACE));
- acl->size = SEC_ACL_HEADER_SIZE;
-
- for (i = 0; i < acl->num_aces; i++) {
- PyObject *py_ace = PyList_GetItem(obj, i);
-
- if (!py_to_ACE(&acl->ace[i], py_ace))
- return False;
-
- acl->size += acl->ace[i].size;
- }
-
- return True;
-}
-
-BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd)
-{
- PyObject *obj;
-
- *dict = PyDict_New();
-
- obj = PyInt_FromLong(sd->revision);
- PyDict_SetItemString(*dict, "revision", obj);
- Py_DECREF(obj);
-
- if (py_from_SID(&obj, sd->owner_sid)) {
- PyDict_SetItemString(*dict, "owner_sid", obj);
- Py_DECREF(obj);
- }
-
- if (py_from_SID(&obj, sd->grp_sid)) {
- PyDict_SetItemString(*dict, "group_sid", obj);
- Py_DECREF(obj);
- }
-
- if (py_from_ACL(&obj, sd->dacl)) {
- PyDict_SetItemString(*dict, "dacl", obj);
- Py_DECREF(obj);
- }
-
- if (py_from_ACL(&obj, sd->sacl)) {
- PyDict_SetItemString(*dict, "sacl", obj);
- Py_DECREF(obj);
- }
-
- return True;
-}
-
-BOOL py_to_SECDESC(SEC_DESC **sd, PyObject *dict, TALLOC_CTX *mem_ctx)
-{
- PyObject *obj;
- uint16 revision;
- DOM_SID owner_sid, group_sid;
- SEC_ACL sacl, dacl;
- BOOL got_dacl = False, got_sacl = False;
- BOOL got_owner_sid = False, got_group_sid = False;
-
- ZERO_STRUCT(dacl); ZERO_STRUCT(sacl);
- ZERO_STRUCT(owner_sid); ZERO_STRUCT(group_sid);
-
- if (!(obj = PyDict_GetItemString(dict, "revision")))
- return False;
-
- revision = PyInt_AsLong(obj);
-
- if ((obj = PyDict_GetItemString(dict, "owner_sid"))) {
-
- if (obj != Py_None) {
-
- if (!py_to_SID(&owner_sid, obj))
- return False;
-
- got_owner_sid = True;
- }
- }
-
- if ((obj = PyDict_GetItemString(dict, "group_sid"))) {
-
- if (obj != Py_None) {
-
- if (!py_to_SID(&group_sid, obj))
- return False;
-
- got_group_sid = True;
- }
- }
-
- if ((obj = PyDict_GetItemString(dict, "dacl"))) {
-
- if (obj != Py_None) {
-
- if (!py_to_ACL(&dacl, obj, mem_ctx))
- return False;
-
- got_dacl = True;
- }
- }
-
- if ((obj = PyDict_GetItemString(dict, "sacl"))) {
-
- if (obj != Py_None) {
-
- if (!py_to_ACL(&sacl, obj, mem_ctx))
- return False;
-
- got_sacl = True;
- }
- }
-
-#if 0 /* For new secdesc code */
- *sd = make_sec_desc(mem_ctx, revision,
- got_owner_sid ? &owner_sid : NULL,
- got_group_sid ? &group_sid : NULL,
- got_sacl ? &sacl : NULL,
- got_dacl ? &dacl : NULL);
-#else
- {
- size_t sd_size;
-
- *sd = make_sec_desc(mem_ctx, revision, SEC_DESC_SELF_RELATIVE,
- got_owner_sid ? &owner_sid : NULL,
- got_group_sid ? &group_sid : NULL,
- got_sacl ? &sacl : NULL,
- got_dacl ? &dacl : NULL, &sd_size);
- }
-#endif
-
- return True;
-}
diff --git a/source/python/py_samr.c b/source/python/py_samr.c
deleted file mode 100644
index 57acd74bedb..00000000000
--- a/source/python/py_samr.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_samr.h"
-
-/*
- * Exceptions raised by this module
- */
-
-PyObject *samr_error; /* This indicates a non-RPC related error
- such as name lookup failure */
-
-PyObject *samr_ntstatus; /* This exception is raised when a RPC call
- returns a status code other than
- NT_STATUS_OK */
-
-/* SAMR group handle object */
-
-static void py_samr_group_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyMethodDef samr_group_methods[] = {
- { NULL }
-};
-
-static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(samr_group_methods, self, attrname);
-}
-
-PyTypeObject samr_group_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SAMR Group Handle",
- sizeof(samr_group_hnd_object),
- 0,
- py_samr_group_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_samr_group_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- samr_group_hnd_object *o;
-
- o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-/* Alias handle object */
-
-static void py_samr_alias_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyMethodDef samr_alias_methods[] = {
- { NULL }
-};
-
-static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(samr_alias_methods, self, attrname);
-}
-
-PyTypeObject samr_alias_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SAMR Alias Handle",
- sizeof(samr_alias_hnd_object),
- 0,
- py_samr_alias_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_samr_alias_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- samr_alias_hnd_object *o;
-
- o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-/* SAMR user handle object */
-
-static void py_samr_user_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyObject *samr_set_user_info2(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
- static char *kwlist[] = { "dict", NULL };
- PyObject *info, *result = NULL;
- SAM_USERINFO_CTR ctr;
- TALLOC_CTX *mem_ctx;
- uchar sess_key[16];
- NTSTATUS ntstatus;
- int level;
- union {
- SAM_USER_INFO_10 id10;
- SAM_USER_INFO_21 id21;
- } pinfo;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &info))
- return NULL;
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(samr_error, "invalid info level");
- return NULL;
- }
-
- ZERO_STRUCT(ctr);
-
- ctr.switch_value = level;
-
- switch(level) {
- case 0x10:
- ctr.info.id10 = &pinfo.id10;
-
- if (!py_to_SAM_USER_INFO_10(ctr.info.id10, info)) {
- PyErr_SetString(
- samr_error, "error converting user info");
- goto done;
- }
-
- break;
- case 21:
- ctr.info.id21 = &pinfo.id21;
-
- if (!py_to_SAM_USER_INFO_21(ctr.info.id21, info)) {
- PyErr_SetString(
- samr_error, "error converting user info");
- goto done;
- }
-
- break;
- default:
- PyErr_SetString(samr_error, "unsupported info level");
- goto done;
- }
-
- /* Call RPC function */
-
- if (!(mem_ctx = talloc_init("samr_set_user_info2"))) {
- PyErr_SetString(
- samr_error, "unable to init talloc context\n");
- goto done;
- }
-
- ntstatus = cli_samr_set_userinfo2(
- user_hnd->cli, mem_ctx, &user_hnd->user_pol, level,
- sess_key, &ctr);
-
- talloc_destroy(mem_ctx);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- Py_INCREF(Py_None);
- result = Py_None;
-
-done:
- return result;
-}
-
-static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
- static char *kwlist[] = { NULL };
- NTSTATUS ntstatus;
- TALLOC_CTX *mem_ctx;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "", kwlist))
- return NULL;
-
- if (!(mem_ctx = talloc_init("samr_delete_dom_user"))) {
- PyErr_SetString(samr_error, "unable to init talloc context");
- return NULL;
- }
-
- ntstatus = cli_samr_delete_dom_user(
- user_hnd->cli, mem_ctx, &user_hnd->user_pol);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- Py_INCREF(Py_None);
- result = Py_None;
-
-done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-static PyMethodDef samr_user_methods[] = {
- { "delete_domain_user", (PyCFunction)samr_delete_dom_user,
- METH_VARARGS | METH_KEYWORDS,
- "Delete domain user." },
- { "set_user_info2", (PyCFunction)samr_set_user_info2,
- METH_VARARGS | METH_KEYWORDS,
- "Set user info 2" },
- { NULL }
-};
-
-static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(samr_user_methods, self, attrname);
-}
-
-PyTypeObject samr_user_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SAMR User Handle",
- sizeof(samr_user_hnd_object),
- 0,
- py_samr_user_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_samr_user_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- samr_user_hnd_object *o;
-
- o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-/* SAMR connect handle object */
-
-static void py_samr_connect_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-PyObject *new_samr_domain_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- samr_domain_hnd_object *o;
-
- o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
-{
- samr_connect_hnd_object *connect_hnd = (samr_connect_hnd_object *)self;
- static char *kwlist[] = { "sid", "access", NULL };
- uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
- char *sid_str;
- DOM_SID sid;
- TALLOC_CTX *mem_ctx = NULL;
- POLICY_HND domain_pol;
- NTSTATUS ntstatus;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|i", kwlist, &sid_str, &desired_access))
- return NULL;
-
- if (!string_to_sid(&sid, sid_str)) {
- PyErr_SetString(PyExc_TypeError, "string is not a sid");
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("samr_open_domain"))) {
- PyErr_SetString(samr_error, "unable to init talloc context");
- return NULL;
- }
-
- ntstatus = cli_samr_open_domain(
- connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
- desired_access, &sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- result = new_samr_domain_hnd_object(
- connect_hnd->cli, mem_ctx, &domain_pol);
-
-done:
- if (!result) {
- if (mem_ctx)
- talloc_destroy(mem_ctx);
- }
-
- return result;
-}
-
-static PyMethodDef samr_connect_methods[] = {
- { "open_domain", (PyCFunction)samr_open_domain,
- METH_VARARGS | METH_KEYWORDS,
- "Open a handle on a domain" },
-
- { NULL }
-};
-
-static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(samr_connect_methods, self, attrname);
-}
-
-PyTypeObject samr_connect_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SAMR Connect Handle",
- sizeof(samr_connect_hnd_object),
- 0,
- py_samr_connect_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_samr_connect_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-PyObject *new_samr_connect_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- samr_connect_hnd_object *o;
-
- o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
-
-/* SAMR domain handle object */
-
-static void py_samr_domain_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
- static char *kwlist[] = { NULL };
- TALLOC_CTX *mem_ctx;
-/* uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
- uint32 start_idx, size, num_dom_groups;
- struct acct_info *dom_groups;
- NTSTATUS result;
- PyObject *py_result = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
- PyErr_SetString(samr_error, "unable to init talloc context");
- return NULL;
- }
-
- start_idx = 0;
- size = 0xffff;
-
- do {
- result = cli_samr_enum_dom_groups(
- domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
- &start_idx, size, &dom_groups, &num_dom_groups);
-
- if (NT_STATUS_IS_OK(result) ||
- NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
- py_from_acct_info(&py_result, dom_groups,
- num_dom_groups);
- }
-
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
-
- return py_result;
-}
-
-static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
- static char *kwlist[] = { "account_name", "acb_info", NULL };
- char *account_name;
- NTSTATUS ntstatus;
- uint32 unknown = 0xe005000b; /* Access mask? */
- uint32 user_rid;
- PyObject *result = NULL;
- TALLOC_CTX *mem_ctx;
- uint16 acb_info = ACB_NORMAL;
- POLICY_HND user_pol;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|i", kwlist, &account_name, &acb_info))
- return NULL;
-
- if (!(mem_ctx = talloc_init("samr_create_dom_user"))) {
- PyErr_SetString(samr_error, "unable to init talloc context");
- return NULL;
- }
-
- ntstatus = cli_samr_create_dom_user(
- domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
- account_name, acb_info, unknown, &user_pol, &user_rid);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
- talloc_destroy(mem_ctx);
- goto done;
- }
-
- result = new_samr_user_hnd_object(
- domain_hnd->cli, mem_ctx, &user_pol);
-
-done:
-
- return result;
-}
-
-static PyMethodDef samr_domain_methods[] = {
- { "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
- METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
- { "create_domain_user", (PyCFunction)samr_create_dom_user,
- METH_VARARGS | METH_KEYWORDS, "Create domain user" },
- { NULL }
-};
-
-static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(samr_domain_methods, self, attrname);
-}
-
-PyTypeObject samr_domain_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SAMR Domain Handle",
- sizeof(samr_domain_hnd_object),
- 0,
- py_samr_domain_hnd_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_samr_domain_hnd_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] = { "server", "creds", "access", NULL };
- uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
- char *server, *errstr;
- struct cli_state *cli = NULL;
- POLICY_HND hnd;
- TALLOC_CTX *mem_ctx = NULL;
- PyObject *result = NULL, *creds = NULL;
- NTSTATUS ntstatus;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|Oi", kwlist, &server, &creds,
- &desired_access))
- return NULL;
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
- PyErr_SetString(samr_error, errstr);
- free(errstr);
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("samr_connect"))) {
- PyErr_SetString(samr_ntstatus,
- "unable to init talloc context\n");
- goto done;
- }
-
- ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd);
-
- if (!NT_STATUS_IS_OK(ntstatus)) {
- cli_shutdown(cli);
- PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
- goto done;
- }
-
- result = new_samr_connect_hnd_object(cli, mem_ctx, &hnd);
-
-done:
- if (!result) {
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
- }
-
- return result;
-}
-
-/*
- * Module initialisation
- */
-
-static PyMethodDef samr_methods[] = {
-
- /* Open/close samr connect handles */
-
- { "connect", (PyCFunction)samr_connect,
- METH_VARARGS | METH_KEYWORDS,
- "Open a connect handle" },
-
- { NULL }
-};
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
-
- /* Account control bits */
-
- { "ACB_DISABLED", 0x0001 },
- { "ACB_HOMDIRREQ", 0x0002 },
- { "ACB_PWNOTREQ", 0x0004 },
- { "ACB_TEMPDUP", 0x0008 },
- { "ACB_NORMAL", 0x0010 },
- { "ACB_MNS", 0x0020 },
- { "ACB_DOMTRUST", 0x0040 },
- { "ACB_WSTRUST", 0x0080 },
- { "ACB_SVRTRUST", 0x0100 },
- { "ACB_PWNOEXP", 0x0200 },
- { "ACB_AUTOLOCK", 0x0400 },
-
- { NULL }
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-void initsamr(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("samr", samr_methods);
- dict = PyModule_GetDict(module);
-
- samr_error = PyErr_NewException("samr.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", samr_error);
-
- samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
- PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
-
- /* Initialise policy handle object */
-
- samr_connect_hnd_type.ob_type = &PyType_Type;
- samr_domain_hnd_type.ob_type = &PyType_Type;
- samr_user_hnd_type.ob_type = &PyType_Type;
- samr_group_hnd_type.ob_type = &PyType_Type;
- samr_alias_hnd_type.ob_type = &PyType_Type;
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Do samba initialisation */
-
- py_samba_init();
-
- setup_logging("samr", True);
- DEBUGLEVEL = 10;
-}
diff --git a/source/python/py_samr.h b/source/python/py_samr.h
deleted file mode 100644
index 4d2b0675b47..00000000000
--- a/source/python/py_samr.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_SAMR_H
-#define _PY_SAMR_H
-
-#include "python/py_common.h"
-
-/* SAMR connect policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND connect_pol;
-} samr_connect_hnd_object;
-
-/* SAMR domain policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND domain_pol;
-} samr_domain_hnd_object;
-
-/* SAMR user policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND user_pol;
-} samr_user_hnd_object;
-
-/* SAMR group policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND group_pol;
-} samr_group_hnd_object;
-
-/* SAMR alias policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND alias_pol;
-} samr_alias_hnd_object;
-
-extern PyTypeObject samr_connect_hnd_type, samr_domain_hnd_type,
- samr_user_hnd_type, samr_group_hnd_type, samr_alias_hnd_type;
-
-/* Exceptions raised by this module */
-
-extern PyObject *samr_error;
-
-/* The following definitions are from py_samr_conv.c */
-
-BOOL py_from_acct_info(PyObject **array, struct acct_info *info, int num_accts);
-BOOL py_from_SAM_USER_INFO_10(PyObject **dict, SAM_USER_INFO_10 *info);
-BOOL py_to_SAM_USER_INFO_10(SAM_USER_INFO_10 *info, PyObject *dict);
-BOOL py_from_SAM_USER_INFO_21(PyObject **dict, SAM_USER_INFO_21 *info);
-BOOL py_to_SAM_USER_INFO_21(SAM_USER_INFO_21 *info, PyObject *dict);
-
-#endif /* _PY_SAMR_H */
diff --git a/source/python/py_samr_conv.c b/source/python/py_samr_conv.c
deleted file mode 100644
index 7523ee7dfcb..00000000000
--- a/source/python/py_samr_conv.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_samr.h"
-#include "python/py_conv.h"
-
-/*
- * Convert between SAM_USER_INFO_10 and Python
- */
-
-struct pyconv py_SAM_USER_INFO_10[] = {
- { "acb_info", PY_UINT32, offsetof(SAM_USER_INFO_10, acb_info) },
- { NULL }
-};
-
-BOOL py_from_SAM_USER_INFO_10(PyObject **dict, SAM_USER_INFO_10 *info)
-{
- *dict = from_struct(info, py_SAM_USER_INFO_10);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(0x10));
- return True;
-}
-
-BOOL py_to_SAM_USER_INFO_10(SAM_USER_INFO_10 *info, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- if (!to_struct(info, dict_copy, py_SAM_USER_INFO_10))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-/*
- * Convert between SAM_USER_INFO_21 and Python
- */
-
-struct pyconv py_SAM_USER_INFO_21[] = {
- { NULL }
-};
-
-BOOL py_from_SAM_USER_INFO_21(PyObject **dict, SAM_USER_INFO_21 *info)
-{
- *dict = from_struct(info, py_SAM_USER_INFO_21);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(21));
- return True;
-}
-
-BOOL py_to_SAM_USER_INFO_21(SAM_USER_INFO_21 *info, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- if (!to_struct(info, dict_copy, py_SAM_USER_INFO_21))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-/*
- * Convert between acct_info and Python
- */
-
-BOOL py_from_acct_info(PyObject **array, struct acct_info *info, int num_accts)
-{
- int i;
-
- *array = PyList_New(num_accts);
-
- for (i = 0; i < num_accts; i++) {
- PyObject *obj;
-
- obj = PyDict_New();
-
- PyDict_SetItemString(
- obj, "name", PyString_FromString(info[i].acct_name));
-
- PyDict_SetItemString(
- obj, "description",
- PyString_FromString(info[i].acct_desc));
-
- PyDict_SetItemString(obj, "rid", PyInt_FromLong(info[i].rid));
-
- PyList_SetItem(*array, i, obj);
- }
-
- return True;
-}
-
-BOOL py_to_acct_info(PRINTER_INFO_3 *info, PyObject *dict,
- TALLOC_CTX *mem_ctx)
-{
- return False;
-}
diff --git a/source/python/py_smb.c b/source/python/py_smb.c
deleted file mode 100644
index e5e65061965..00000000000
--- a/source/python/py_smb.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_smb.h"
-
-/* Create a new cli_state python object */
-
-PyObject *new_cli_state_object(struct cli_state *cli)
-{
- cli_state_object *o;
-
- o = PyObject_New(cli_state_object, &cli_state_type);
-
- o->cli = cli;
-
- return (PyObject*)o;
-}
-
-static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] = { "server", NULL };
- struct cli_state *cli;
- char *server;
- struct in_addr ip;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server))
- return NULL;
-
- if (!(cli = cli_initialise(NULL)))
- return NULL;
-
- ZERO_STRUCT(ip);
-
- if (!cli_connect(cli, server, &ip))
- return NULL;
-
- return new_cli_state_object(cli);
-}
-
-static PyObject *py_smb_session_request(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "called", "calling", NULL };
- char *calling_name = NULL, *called_name;
- struct nmb_name calling, called;
- BOOL result;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name,
- &calling_name))
- return NULL;
-
- if (!calling_name)
- calling_name = global_myname();
-
- make_nmb_name(&calling, calling_name, 0x00);
- make_nmb_name(&called, called_name, 0x20);
-
- result = cli_session_request(cli->cli, &calling, &called);
-
- return Py_BuildValue("i", result);
-}
-
-static PyObject *py_smb_negprot(PyObject *self, PyObject *args, PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { NULL };
- BOOL result;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- result = cli_negprot(cli->cli);
-
- return Py_BuildValue("i", result);
-}
-
-static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "creds", NULL };
- PyObject *creds;
- char *username, *domain, *password, *errstr;
- BOOL result;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
- return NULL;
-
- if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
- free(errstr);
- return NULL;
- }
-
- result = cli_session_setup(
- cli->cli, username, password, strlen(password) + 1,
- password, strlen(password) + 1, domain);
-
- if (cli_is_error(cli->cli)) {
- PyErr_SetString(PyExc_RuntimeError, "session setup failed");
- return NULL;
- }
-
- return Py_BuildValue("i", result);
-}
-
-static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "service", NULL };
- char *service;
- BOOL result;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &service))
- return NULL;
-
- result = cli_send_tconX(
- cli->cli, service, strequal(service, "IPC$") ? "IPC" :
- "?????", "", 1);
-
- if (cli_is_error(cli->cli)) {
- PyErr_SetString(PyExc_RuntimeError, "tconx failed");
- return NULL;
- }
-
- return Py_BuildValue("i", result);
-}
-
-static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "filename", "desired_access",
- "file_attributes", "share_access",
- "create_disposition", NULL };
- char *filename;
- uint32 desired_access, file_attributes = 0,
- share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
- create_disposition = FILE_EXISTS_OPEN, create_options = 0;
- int result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "si|iii", kwlist, &filename, &desired_access,
- &file_attributes, &share_access, &create_disposition,
- &create_options))
- return NULL;
-
- result = cli_nt_create_full(
- cli->cli, filename, 0, desired_access, file_attributes,
- share_access, create_disposition, create_options, 0);
-
- if (cli_is_error(cli->cli)) {
- PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed");
- return NULL;
- }
-
- /* Return FID */
-
- return PyInt_FromLong(result);
-}
-
-static PyObject *py_smb_close(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "fnum", NULL };
- BOOL result;
- int fnum;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "i", kwlist, &fnum))
- return NULL;
-
- result = cli_close(cli->cli, fnum);
-
- return PyInt_FromLong(result);
-}
-
-static PyObject *py_smb_unlink(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "filename", NULL };
- char *filename;
- BOOL result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s", kwlist, &filename))
- return NULL;
-
- result = cli_unlink(cli->cli, filename);
-
- return PyInt_FromLong(result);
-}
-
-static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "fnum", NULL };
- PyObject *result = NULL;
- SEC_DESC *secdesc = NULL;
- int fnum;
- TALLOC_CTX *mem_ctx = NULL;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "i", kwlist, &fnum))
- return NULL;
-
- mem_ctx = talloc_init("py_smb_query_secdesc");
-
- secdesc = cli_query_secdesc(cli->cli, fnum, mem_ctx);
-
- if (cli_is_error(cli->cli)) {
- PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
- goto done;
- }
-
- if (!secdesc) {
- Py_INCREF(Py_None);
- result = Py_None;
- goto done;
- }
-
- if (!py_from_SECDESC(&result, secdesc)) {
- PyErr_SetString(
- PyExc_TypeError,
- "Invalid security descriptor returned");
- goto done;
- }
-
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-
-}
-
-static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- cli_state_object *cli = (cli_state_object *)self;
- static char *kwlist[] = { "fnum", "security_descriptor", NULL };
- PyObject *result = NULL;
- PyObject *py_secdesc;
- SEC_DESC *secdesc;
- TALLOC_CTX *mem_ctx = NULL;
- int fnum;
- BOOL err;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "iO", kwlist, &fnum, &py_secdesc))
- return NULL;
-
- mem_ctx = talloc_init("py_smb_set_secdesc");
-
- if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
- PyErr_SetString(PyExc_TypeError,
- "Invalid security descriptor");
- goto done;
- }
-
- err = cli_set_secdesc(cli->cli, fnum, secdesc);
-
- if (cli_is_error(cli->cli)) {
- PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
- goto done;
- }
-
- result = PyInt_FromLong(err);
- done:
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-static PyMethodDef smb_hnd_methods[] = {
-
- /* Session and connection handling */
-
- { "session_request", (PyCFunction)py_smb_session_request,
- METH_VARARGS | METH_KEYWORDS, "Request a session" },
-
- { "negprot", (PyCFunction)py_smb_negprot,
- METH_VARARGS | METH_KEYWORDS, "Protocol negotiation" },
-
- { "session_setup", (PyCFunction)py_smb_session_setup,
- METH_VARARGS | METH_KEYWORDS, "Session setup" },
-
- { "tconx", (PyCFunction)py_smb_tconx,
- METH_VARARGS | METH_KEYWORDS, "Tree connect" },
-
- /* File operations */
-
- { "nt_create_andx", (PyCFunction)py_smb_nt_create_andx,
- METH_VARARGS | METH_KEYWORDS, "NT Create&X" },
-
- { "close", (PyCFunction)py_smb_close,
- METH_VARARGS | METH_KEYWORDS, "Close" },
-
- { "unlink", (PyCFunction)py_smb_unlink,
- METH_VARARGS | METH_KEYWORDS, "Unlink" },
-
- /* Security descriptors */
-
- { "query_secdesc", (PyCFunction)py_smb_query_secdesc,
- METH_VARARGS | METH_KEYWORDS, "Query security descriptor" },
-
- { "set_secdesc", (PyCFunction)py_smb_set_secdesc,
- METH_VARARGS | METH_KEYWORDS, "Set security descriptor" },
-
- { NULL }
-};
-
-/*
- * Method dispatch tables
- */
-
-static PyMethodDef smb_methods[] = {
-
- { "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS,
- "Connect to a host" },
-
- /* Other stuff - this should really go into a samba config module
- but for the moment let's leave it here. */
-
- { "setup_logging", (PyCFunction)py_setup_logging,
- METH_VARARGS | METH_KEYWORDS,
- "Set up debug logging.\n"
-"\n"
-"Initialises Samba's debug logging system. One argument is expected which\n"
-"is a boolean specifying whether debugging is interactive and sent to stdout\n"
-"or logged to a file.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> smb.setup_logging(interactive = 1)" },
-
- { "get_debuglevel", (PyCFunction)get_debuglevel,
- METH_VARARGS,
- "Set the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> smb.get_debuglevel()\n"
-"0" },
-
- { "set_debuglevel", (PyCFunction)set_debuglevel,
- METH_VARARGS,
- "Get the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> smb.set_debuglevel(10)" },
-
- { NULL }
-};
-
-static void py_cli_state_dealloc(PyObject* self)
-{
- cli_state_object *cli = (cli_state_object *)self;
-
- if (cli->cli)
- cli_shutdown(cli->cli);
-
- PyObject_Del(self);
-}
-
-static PyObject *py_cli_state_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(smb_hnd_methods, self, attrname);
-}
-
-PyTypeObject cli_state_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "SMB client connection",
- sizeof(cli_state_object),
- 0,
- py_cli_state_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- py_cli_state_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
-
-/*
- * Module initialisation
- */
-
-void initsmb(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("smb", smb_methods);
- dict = PyModule_GetDict(module);
-
- /* Initialise policy handle object */
-
- cli_state_type.ob_type = &PyType_Type;
-
- /* Do samba initialisation */
-
- py_samba_init();
-
- setup_logging("smb", True);
- DEBUGLEVEL = 3;
-}
diff --git a/source/python/py_smb.h b/source/python/py_smb.h
deleted file mode 100644
index 31bcf4aab2e..00000000000
--- a/source/python/py_smb.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_SMB_H
-#define _PY_SMB_H
-
-#include "python/py_common.h"
-
-/* cli_state handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
-} cli_state_object;
-
-/* Exceptions raised by this module */
-
-extern PyTypeObject cli_state_type;
-
-extern PyObject *smb_ntstatus;
-
-#endif /* _PY_SMB_H */
diff --git a/source/python/py_spoolss.c b/source/python/py_spoolss.c
deleted file mode 100644
index b8df5cbf113..00000000000
--- a/source/python/py_spoolss.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Exceptions this module can raise */
-
-PyObject *spoolss_error, *spoolss_werror;
-
-/*
- * Method dispatch table
- */
-
-static PyMethodDef spoolss_methods[] = {
-
- /* Open/close printer handles */
-
- { "openprinter", (PyCFunction)spoolss_openprinter, METH_VARARGS | METH_KEYWORDS,
- "Open a printer by name in UNC format.\n"
-"\n"
-"Optionally a dictionary of (domain, username, password) may be given in\n"
-"which case they are used when opening the RPC pipe. An access mask may\n"
-"also be given which defaults to MAXIMUM_ALLOWED_ACCESS.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> hnd = spoolss.openprinter(\"\\\\\\\\NPSD-PDC2\\\\meanie\")"},
-
- { "closeprinter", spoolss_closeprinter, METH_VARARGS,
- "Close a printer handle opened with openprinter or addprinter.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> spoolss.closeprinter(hnd)"},
-
- { "addprinterex", (PyCFunction)spoolss_addprinterex, METH_VARARGS,
- "addprinterex()"},
-
- /* Server enumeratation functions */
-
- { "enumprinters", (PyCFunction)spoolss_enumprinters,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printers on a print server.\n"
-"\n"
-"Return a list of printers on a print server. The credentials, info level\n"
-"and flags may be specified as keyword arguments.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> print spoolss.enumprinters(\"\\\\\\\\npsd-pdc2\")\n"
-"[{'comment': 'i am a comment', 'printer_name': 'meanie', 'flags': 8388608, \n"
-" 'description': 'meanie,Generic / Text Only,i am a location'}, \n"
-" {'comment': '', 'printer_name': 'fileprint', 'flags': 8388608, \n"
-" 'description': 'fileprint,Generic / Text Only,'}]"},
-
- { "enumports", (PyCFunction)spoolss_enumports,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate ports on a print server.\n"
-"\n"
-"Return a list of ports on a print server.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> print spoolss.enumports(\"\\\\\\\\npsd-pdc2\")\n"
-"[{'name': 'LPT1:'}, {'name': 'LPT2:'}, {'name': 'COM1:'}, \n"
-"{'name': 'COM2:'}, {'name': 'FILE:'}, {'name': '\\\\nautilus1\\zpekt3r'}]"},
-
- { "enumprinterdrivers", (PyCFunction)spoolss_enumprinterdrivers,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printer drivers on a print server.\n"
-"\n"
-"Return a list of printer drivers."},
-
- /* Miscellaneous other commands */
-
- { "getprinterdriverdir", (PyCFunction)spoolss_getprinterdriverdir,
- METH_VARARGS | METH_KEYWORDS,
- "Return printer driver directory.\n"
-"\n"
-"Return the printer driver directory for a given architecture. The\n"
-"architecture defaults to \"Windows NT x86\"."},
-
- /* Other stuff - this should really go into a samba config module
- but for the moment let's leave it here. */
-
- { "setup_logging", (PyCFunction)py_setup_logging,
- METH_VARARGS | METH_KEYWORDS,
- "Set up debug logging.\n"
-"\n"
-"Initialises Samba's debug logging system. One argument is expected which\n"
-"is a boolean specifying whether debugging is interactive and sent to stdout\n"
-"or logged to a file.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> spoolss.setup_logging(interactive = 1)" },
-
- { "get_debuglevel", (PyCFunction)get_debuglevel,
- METH_VARARGS,
- "Set the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> spoolss.get_debuglevel()\n"
-"0" },
-
- { "set_debuglevel", (PyCFunction)set_debuglevel,
- METH_VARARGS,
- "Get the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> spoolss.set_debuglevel(10)" },
-
- /* Printer driver routines */
-
- { "addprinterdriver", (PyCFunction)spoolss_addprinterdriver,
- METH_VARARGS | METH_KEYWORDS,
- "Add a printer driver." },
-
- { "addprinterdriverex", (PyCFunction)spoolss_addprinterdriverex,
- METH_VARARGS | METH_KEYWORDS,
- "Add a printer driver." },
-
- { "deleteprinterdriver", (PyCFunction)spoolss_deleteprinterdriver,
- METH_VARARGS | METH_KEYWORDS,
- "Delete a printer driver." },
-
- { "deleteprinterdriverex", (PyCFunction)spoolss_deleteprinterdriverex,
- METH_VARARGS | METH_KEYWORDS,
- "Delete a printer driver." },
-
- { NULL }
-};
-
-/* Methods attached to a spoolss handle object */
-
-static PyMethodDef spoolss_hnd_methods[] = {
-
- /* Printer info */
-
- { "getprinter", (PyCFunction)spoolss_hnd_getprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Get printer information.\n"
-"\n"
-"Return a dictionary of print information. The info level defaults to 1.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> hnd.getprinter()\n"
-"{'comment': 'i am a comment', 'printer_name': '\\\\NPSD-PDC2\\meanie',\n"
-" 'description': '\\\\NPSD-PDC2\\meanie,Generic / Text Only,i am a location',\n"
-" 'flags': 8388608}"},
-
- { "setprinter", (PyCFunction)spoolss_hnd_setprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Set printer information."},
-
- /* Printer drivers */
-
- { "getprinterdriver", (PyCFunction)spoolss_hnd_getprinterdriver,
- METH_VARARGS | METH_KEYWORDS,
- "Return printer driver information.\n"
-"\n"
-"Return a dictionary of printer driver information for the printer driver\n"
-"bound to this printer."},
-
- /* Forms */
-
- { "enumforms", (PyCFunction)spoolss_hnd_enumforms,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate supported forms.\n"
-"\n"
-"Return a list of forms supported by this printer or print server."},
-
- { "setform", (PyCFunction)spoolss_hnd_setform,
- METH_VARARGS | METH_KEYWORDS,
- "Set form data.\n"
-"\n"
-"Set the form given by the dictionary argument."},
-
- { "addform", (PyCFunction)spoolss_hnd_addform,
- METH_VARARGS | METH_KEYWORDS,
- "Add a new form." },
-
- { "getform", (PyCFunction)spoolss_hnd_getform,
- METH_VARARGS | METH_KEYWORDS,
- "Get form properties." },
-
- { "deleteform", (PyCFunction)spoolss_hnd_deleteform,
- METH_VARARGS | METH_KEYWORDS,
- "Delete a form." },
-
- /* Job related methods */
-
- { "enumjobs", (PyCFunction)spoolss_hnd_enumjobs,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate jobs." },
-
- { "setjob", (PyCFunction)spoolss_hnd_setjob,
- METH_VARARGS | METH_KEYWORDS,
- "Set job information." },
-
- { "getjob", (PyCFunction)spoolss_hnd_getjob,
- METH_VARARGS | METH_KEYWORDS,
- "Get job information." },
-
- { "startpageprinter", (PyCFunction)spoolss_hnd_startpageprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Notify spooler that a page is about to be printed." },
-
- { "endpageprinter", (PyCFunction)spoolss_hnd_endpageprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Notify spooler that a page is about to be printed." },
-
- { "startdocprinter", (PyCFunction)spoolss_hnd_startdocprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Notify spooler that a document is about to be printed." },
-
- { "enddocprinter", (PyCFunction)spoolss_hnd_enddocprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Notify spooler that a document is about to be printed." },
-
- { "writeprinter", (PyCFunction)spoolss_hnd_writeprinter,
- METH_VARARGS | METH_KEYWORDS,
- "Write job data to a printer." },
-
- { "addjob", (PyCFunction)spoolss_hnd_addjob,
- METH_VARARGS | METH_KEYWORDS,
- "Add a job to the list of print jobs." },
-
- /* Printer data */
-
- { "getprinterdata", (PyCFunction)spoolss_hnd_getprinterdata,
- METH_VARARGS | METH_KEYWORDS,
- "Get printer data." },
-
- { "setprinterdata", (PyCFunction)spoolss_hnd_setprinterdata,
- METH_VARARGS | METH_KEYWORDS,
- "Set printer data." },
-
- { "enumprinterdata", (PyCFunction)spoolss_hnd_enumprinterdata,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printer data." },
-
- { "deleteprinterdata", (PyCFunction)spoolss_hnd_deleteprinterdata,
- METH_VARARGS | METH_KEYWORDS,
- "Delete printer data." },
-
- { "getprinterdataex", (PyCFunction)spoolss_hnd_getprinterdataex,
- METH_VARARGS | METH_KEYWORDS,
- "Get printer data." },
-
- { "setprinterdataex", (PyCFunction)spoolss_hnd_setprinterdataex,
- METH_VARARGS | METH_KEYWORDS,
- "Set printer data." },
-
- { "enumprinterdataex", (PyCFunction)spoolss_hnd_enumprinterdataex,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printer data." },
-
- { "deleteprinterdataex", (PyCFunction)spoolss_hnd_deleteprinterdataex,
- METH_VARARGS | METH_KEYWORDS,
- "Delete printer data." },
-
- { "enumprinterkey", (PyCFunction)spoolss_hnd_enumprinterkey,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printer key." },
-
-#if 0
- /* Not implemented */
-
- { "deleteprinterkey", (PyCFunction)spoolss_hnd_deleteprinterkey,
- METH_VARARGS | METH_KEYWORDS,
- "Delete printer key." },
-#endif
-
- { NULL }
-
-};
-
-static void py_policy_hnd_dealloc(PyObject* self)
-{
- spoolss_policy_hnd_object *hnd;
-
- /* Close down policy handle and free talloc context */
-
- hnd = (spoolss_policy_hnd_object*)self;
-
- cli_shutdown(hnd->cli);
- talloc_destroy(hnd->mem_ctx);
-
- PyObject_Del(self);
-}
-
-static PyObject *py_policy_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(spoolss_hnd_methods, self, attrname);
-}
-
-static char spoolss_type_doc[] =
-"Python wrapper for Windows NT SPOOLSS rpc pipe.";
-
-PyTypeObject spoolss_policy_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "spoolss.hnd",
- sizeof(spoolss_policy_hnd_object),
- 0,
- py_policy_hnd_dealloc, /* tp_dealloc*/
- 0, /* tp_print*/
- py_policy_hnd_getattr, /* tp_getattr*/
- 0, /* tp_setattr*/
- 0, /* tp_compare*/
- 0, /* tp_repr*/
- 0, /* tp_as_number*/
- 0, /* tp_as_sequence*/
- 0, /* tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- spoolss_type_doc, /* tp_doc */
-};
-
-/* Initialise constants */
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
-
- /* Access permissions */
-
- { "MAXIMUM_ALLOWED_ACCESS", MAXIMUM_ALLOWED_ACCESS },
- { "SERVER_ALL_ACCESS", SERVER_ALL_ACCESS },
- { "SERVER_READ", SERVER_READ },
- { "SERVER_WRITE", SERVER_WRITE },
- { "SERVER_EXECUTE", SERVER_EXECUTE },
- { "SERVER_ACCESS_ADMINISTER", SERVER_ACCESS_ADMINISTER },
- { "SERVER_ACCESS_ENUMERATE", SERVER_ACCESS_ENUMERATE },
- { "PRINTER_ALL_ACCESS", PRINTER_ALL_ACCESS },
- { "PRINTER_READ", PRINTER_READ },
- { "PRINTER_WRITE", PRINTER_WRITE },
- { "PRINTER_EXECUTE", PRINTER_EXECUTE },
- { "PRINTER_ACCESS_ADMINISTER", PRINTER_ACCESS_ADMINISTER },
- { "PRINTER_ACCESS_USE", PRINTER_ACCESS_USE },
- { "JOB_ACCESS_ADMINISTER", JOB_ACCESS_ADMINISTER },
- { "JOB_ALL_ACCESS", JOB_ALL_ACCESS },
- { "JOB_READ", JOB_READ },
- { "JOB_WRITE", JOB_WRITE },
- { "JOB_EXECUTE", JOB_EXECUTE },
- { "STANDARD_RIGHTS_ALL_ACCESS", STANDARD_RIGHTS_ALL_ACCESS },
- { "STANDARD_RIGHTS_EXECUTE_ACCESS", STANDARD_RIGHTS_EXECUTE_ACCESS },
- { "STANDARD_RIGHTS_READ_ACCESS", STANDARD_RIGHTS_READ_ACCESS },
- { "STANDARD_RIGHTS_REQUIRED_ACCESS", STANDARD_RIGHTS_REQUIRED_ACCESS },
- { "STANDARD_RIGHTS_WRITE_ACCESS", STANDARD_RIGHTS_WRITE_ACCESS },
-
- /* Printer enumeration flags */
-
- { "PRINTER_ENUM_DEFAULT", PRINTER_ENUM_DEFAULT },
- { "PRINTER_ENUM_LOCAL", PRINTER_ENUM_LOCAL },
- { "PRINTER_ENUM_CONNECTIONS", PRINTER_ENUM_CONNECTIONS },
- { "PRINTER_ENUM_FAVORITE", PRINTER_ENUM_FAVORITE },
- { "PRINTER_ENUM_NAME", PRINTER_ENUM_NAME },
- { "PRINTER_ENUM_REMOTE", PRINTER_ENUM_REMOTE },
- { "PRINTER_ENUM_SHARED", PRINTER_ENUM_SHARED },
- { "PRINTER_ENUM_NETWORK", PRINTER_ENUM_NETWORK },
-
- /* Form types */
-
- { "FORM_USER", FORM_USER },
- { "FORM_BUILTIN", FORM_BUILTIN },
- { "FORM_PRINTER", FORM_PRINTER },
-
- /* WERRORs */
-
- { "WERR_OK", 0 },
- { "WERR_BADFILE", 2 },
- { "WERR_ACCESS_DENIED", 5 },
- { "WERR_BADFID", 6 },
- { "WERR_BADFUNC", 1 },
- { "WERR_INSUFFICIENT_BUFFER", 122 },
- { "WERR_NO_SUCH_SHARE", 67 },
- { "WERR_ALREADY_EXISTS", 80 },
- { "WERR_INVALID_PARAM", 87 },
- { "WERR_NOT_SUPPORTED", 50 },
- { "WERR_BAD_PASSWORD", 86 },
- { "WERR_NOMEM", 8 },
- { "WERR_INVALID_NAME", 123 },
- { "WERR_UNKNOWN_LEVEL", 124 },
- { "WERR_OBJECT_PATH_INVALID", 161 },
- { "WERR_NO_MORE_ITEMS", 259 },
- { "WERR_MORE_DATA", 234 },
- { "WERR_UNKNOWN_PRINTER_DRIVER", 1797 },
- { "WERR_INVALID_PRINTER_NAME", 1801 },
- { "WERR_PRINTER_ALREADY_EXISTS", 1802 },
- { "WERR_INVALID_DATATYPE", 1804 },
- { "WERR_INVALID_ENVIRONMENT", 1805 },
- { "WERR_INVALID_FORM_NAME", 1902 },
- { "WERR_INVALID_FORM_SIZE", 1903 },
- { "WERR_BUF_TOO_SMALL", 2123 },
- { "WERR_JOB_NOT_FOUND", 2151 },
- { "WERR_DEST_NOT_FOUND", 2152 },
- { "WERR_NOT_LOCAL_DOMAIN", 2320 },
- { "WERR_PRINTER_DRIVER_IN_USE", 3001 },
- { "WERR_STATUS_MORE_ENTRIES ", 0x0105 },
-
- /* Job control constants */
-
- { "JOB_CONTROL_PAUSE", JOB_CONTROL_PAUSE },
- { "JOB_CONTROL_RESUME", JOB_CONTROL_RESUME },
- { "JOB_CONTROL_CANCEL", JOB_CONTROL_CANCEL },
- { "JOB_CONTROL_RESTART", JOB_CONTROL_RESTART },
- { "JOB_CONTROL_DELETE", JOB_CONTROL_DELETE },
-
- { NULL },
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/* Module initialisation */
-
-void initspoolss(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("spoolss", spoolss_methods);
- dict = PyModule_GetDict(module);
-
- /* Exceptions we can raise */
-
- spoolss_error = PyErr_NewException("spoolss.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", spoolss_error);
-
- spoolss_werror = PyErr_NewException("spoolss.werror", NULL, NULL);
- PyDict_SetItemString(dict, "werror", spoolss_werror);
-
- /* Initialise policy handle object */
-
- spoolss_policy_hnd_type.ob_type = &PyType_Type;
-
- PyDict_SetItemString(dict, "spoolss.hnd",
- (PyObject *)&spoolss_policy_hnd_type);
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Do samba initialisation */
-
- py_samba_init();
-}
diff --git a/source/python/py_spoolss.h b/source/python/py_spoolss.h
deleted file mode 100644
index 34b48190cd1..00000000000
--- a/source/python/py_spoolss.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_SPOOLSS_H
-#define _PY_SPOOLSS_H
-
-#include "python/py_common.h"
-
-/* Spoolss policy handle object */
-
-typedef struct {
- PyObject_HEAD
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- POLICY_HND pol;
-} spoolss_policy_hnd_object;
-
-/* Exceptions raised by this module */
-
-extern PyTypeObject spoolss_policy_hnd_type;
-
-extern PyObject *spoolss_error, *spoolss_werror;
-
-/* The following definitions come from python/py_spoolss_common.c */
-
-PyObject *new_spoolss_policy_hnd_object(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, POLICY_HND *pol);
-
-/* The following definitions come from python/py_spoolss_drivers.c */
-
-PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
- PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_drivers_conv.c */
-
-BOOL py_from_DRIVER_INFO_1(PyObject **dict, DRIVER_INFO_1 *info);
-BOOL py_to_DRIVER_INFO_1(DRIVER_INFO_1 *info, PyObject *dict);
-BOOL py_from_DRIVER_INFO_2(PyObject **dict, DRIVER_INFO_2 *info);
-BOOL py_to_DRIVER_INFO_2(DRIVER_INFO_2 *info, PyObject *dict);
-BOOL py_from_DRIVER_INFO_3(PyObject **dict, DRIVER_INFO_3 *info);
-BOOL py_to_DRIVER_INFO_3(DRIVER_INFO_3 *info, PyObject *dict);
-BOOL py_from_DRIVER_INFO_6(PyObject **dict, DRIVER_INFO_6 *info);
-BOOL py_to_DRIVER_INFO_6(DRIVER_INFO_6 *info, PyObject *dict);
-BOOL py_from_DRIVER_DIRECTORY_1(PyObject **dict, DRIVER_DIRECTORY_1 *info);
-BOOL py_to_DRIVER_DIRECTORY_1(DRIVER_DIRECTORY_1 *info, PyObject *dict);
-
-/* The following definitions come from python/py_spoolss_forms.c */
-
-PyObject *spoolss_hnd_addform(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_getform(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_setform(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_deleteform(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_enumforms(PyObject *self, PyObject *args, PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_forms_conv.c */
-
-BOOL py_from_FORM_1(PyObject **dict, FORM_1 *form);
-BOOL py_to_FORM(FORM *form, PyObject *dict);
-
-/* The following definitions come from python/py_spoolss_jobs.c */
-
-PyObject *spoolss_hnd_enumjobs(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_setjob(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_getjob(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_startpageprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_endpageprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_startdocprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_enddocprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_writeprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_addjob(PyObject *self, PyObject *args, PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_jobs_conv.c */
-
-BOOL py_from_JOB_INFO_1(PyObject **dict, JOB_INFO_1 *info);
-BOOL py_to_JOB_INFO_1(JOB_INFO_1 *info, PyObject *dict);
-BOOL py_from_JOB_INFO_2(PyObject **dict, JOB_INFO_2 *info);
-BOOL py_to_JOB_INFO_2(JOB_INFO_2 *info, PyObject *dict);
-BOOL py_from_DOC_INFO_1(PyObject **dict, DOC_INFO_1 *info);
-BOOL py_to_DOC_INFO_1(DOC_INFO_1 *info, PyObject *dict);
-
-/* The following definitions come from python/py_spoolss_ports.c */
-
-PyObject *spoolss_enumports(PyObject *self, PyObject *args, PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_ports_conv.c */
-
-BOOL py_from_PORT_INFO_1(PyObject **dict, PORT_INFO_1 *info);
-BOOL py_to_PORT_INFO_1(PORT_INFO_1 *info, PyObject *dict);
-BOOL py_from_PORT_INFO_2(PyObject **dict, PORT_INFO_2 *info);
-BOOL py_to_PORT_INFO_2(PORT_INFO_2 *info, PyObject *dict);
-
-/* The following definitions come from python/py_spoolss_printerdata.c */
-
-PyObject *spoolss_hnd_getprinterdata(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_setprinterdata(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_enumprinterdata(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_deleteprinterdata(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_getprinterdataex(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_setprinterdataex(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_enumprinterdataex(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_deleteprinterdataex(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_enumprinterkey(PyObject *self, PyObject *args,
- PyObject *kw);
-PyObject *spoolss_hnd_deleteprinterkey(PyObject *self, PyObject *args,
- PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_printers.c */
-
-PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_closeprinter(PyObject *self, PyObject *args);
-PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw);
-PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw);
-
-/* The following definitions come from python/py_spoolss_printers_conv.c */
-
-BOOL py_from_DEVICEMODE(PyObject **dict, DEVICEMODE *devmode);
-BOOL py_to_DEVICEMODE(DEVICEMODE *devmode, PyObject *dict);
-BOOL py_from_PRINTER_INFO_0(PyObject **dict, PRINTER_INFO_0 *info);
-BOOL py_to_PRINTER_INFO_0(PRINTER_INFO_0 *info, PyObject *dict);
-BOOL py_from_PRINTER_INFO_1(PyObject **dict, PRINTER_INFO_1 *info);
-BOOL py_to_PRINTER_INFO_1(PRINTER_INFO_1 *info, PyObject *dict);
-BOOL py_from_PRINTER_INFO_2(PyObject **dict, PRINTER_INFO_2 *info);
-BOOL py_to_PRINTER_INFO_2(PRINTER_INFO_2 *info, PyObject *dict,
- TALLOC_CTX *mem_ctx);
-BOOL py_from_PRINTER_INFO_3(PyObject **dict, PRINTER_INFO_3 *info);
-BOOL py_to_PRINTER_INFO_3(PRINTER_INFO_3 *info, PyObject *dict,
- TALLOC_CTX *mem_ctx);
-
-#endif /* _PY_SPOOLSS_H */
diff --git a/source/python/py_spoolss_common.c b/source/python/py_spoolss_common.c
deleted file mode 100644
index f34d2ac6c7e..00000000000
--- a/source/python/py_spoolss_common.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-PyObject *new_spoolss_policy_hnd_object(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, POLICY_HND *pol)
-{
- spoolss_policy_hnd_object *o;
-
- o = PyObject_New(spoolss_policy_hnd_object, &spoolss_policy_hnd_type);
-
- o->cli = cli;
- o->mem_ctx = mem_ctx;
- memcpy(&o->pol, pol, sizeof(POLICY_HND));
-
- return (PyObject*)o;
-}
diff --git a/source/python/py_spoolss_drivers.c b/source/python/py_spoolss_drivers.c
deleted file mode 100644
index 12190519ecc..00000000000
--- a/source/python/py_spoolss_drivers.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Enumerate printer drivers */
-
-PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- WERROR werror;
- PyObject *result = NULL, *creds = NULL;
- PRINTER_DRIVER_CTR ctr;
- int level = 1, i;
- uint32 needed, num_drivers;
- char *arch = "Windows NT x86", *server, *errstr;
- static char *kwlist[] = {"server", "level", "creds", "arch", NULL};
- struct cli_state *cli = NULL;
- TALLOC_CTX *mem_ctx = NULL;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|iOs", kwlist, &server, &level, &creds,
- &arch))
- return NULL;
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- /* Call rpc function */
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_enumprinterdrivers"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- goto done;
- }
-
- werror = cli_spoolss_enumprinterdrivers(
- cli, mem_ctx, 0, &needed, level, arch,
- &num_drivers, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enumprinterdrivers(
- cli, mem_ctx, needed, NULL, level, arch,
- &num_drivers, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- /* Return value */
-
- switch (level) {
- case 1:
- result = PyDict_New();
-
- for (i = 0; i < num_drivers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.info1[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- case 2:
- result = PyDict_New();
-
- for(i = 0; i < num_drivers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.info2[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- case 3:
- result = PyDict_New();
-
- for(i = 0; i < num_drivers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.info3[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- case 6:
- result = PyDict_New();
-
- for(i = 0; i < num_drivers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.info6[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_DRIVER_INFO_6(&value, &ctr.info6[i]);
-
- PyList_SetItem(result, i, value);
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unknown info level");
- goto done;
- }
-
- done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/* Fetch printer driver */
-
-PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *result = Py_None;
- PRINTER_DRIVER_CTR ctr;
- int level = 1;
- uint32 needed;
- char *arch = "Windows NT x86";
- int version = 2;
- static char *kwlist[] = {"level", "arch", NULL};
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "|is", kwlist, &level, &arch))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getprinterdriver(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
- version, arch, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinterdriver(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, version, arch, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- /* Return value */
-
- switch (level) {
- case 1:
- py_from_DRIVER_INFO_1(&result, ctr.info1);
- break;
- case 2:
- py_from_DRIVER_INFO_2(&result, ctr.info2);
- break;
- case 3:
- py_from_DRIVER_INFO_3(&result, ctr.info3);
- break;
- case 6:
- py_from_DRIVER_INFO_6(&result, ctr.info6);
- break;
- default:
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- Py_INCREF(result);
- return result;
-}
-
-/* Fetch printer driver directory */
-
-PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- WERROR werror;
- PyObject *result = NULL, *creds = NULL;
- DRIVER_DIRECTORY_CTR ctr;
- uint32 needed, level = 1;
- char *arch = "Windows NT x86", *server, *errstr;
- static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
- struct cli_state *cli = NULL;
- TALLOC_CTX *mem_ctx = NULL;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|isO", kwlist, &server, &level,
- &arch, &creds))
- return NULL;
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- /* Call rpc function */
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_getprinterdriverdir"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- goto done;
- }
-
- werror = cli_spoolss_getprinterdriverdir(
- cli, mem_ctx, 0, &needed, level, arch, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinterdriverdir(
- cli, mem_ctx, needed, NULL, level, arch, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- /* Return value */
-
- switch (level) {
- case 1:
- py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
- break;
- default:
- PyErr_SetString(spoolss_error, "unknown info level");
- goto done;
- }
-
- done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- static char *kwlist[] = { "server", "info", "creds", NULL };
- char *server, *errstr;
- uint32 level;
- PyObject *info, *result = NULL, *creds = NULL;
- WERROR werror;
- TALLOC_CTX *mem_ctx = NULL;
- struct cli_state *cli = NULL;
- PRINTER_DRIVER_CTR ctr;
- union {
- DRIVER_INFO_3 driver_3;
- } dinfo;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "sO!|O", kwlist, &server, &PyDict_Type,
- &info, &creds))
- return NULL;
-
- if (server[0] == '\\' || server[1] == '\\')
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_addprinterdriver"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(spoolss_error, "invalid info level");
- goto done;
- }
-
- if (level != 3) {
- PyErr_SetString(spoolss_error, "unsupported info level");
- goto done;
- }
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(dinfo);
-
- switch(level) {
- case 3:
- ctr.info3 = &dinfo.driver_3;
-
- if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info)) {
- PyErr_SetString(spoolss_error,
- "error converting to driver info 3");
- goto done;
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unsupported info level");
- goto done;
- }
-
- werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- Py_INCREF(Py_None);
- result = Py_None;
-
-done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-
-}
-
-PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- /* Not supported by Samba server */
-
- PyErr_SetString(spoolss_error, "Not implemented");
- return NULL;
-}
-
-PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- PyErr_SetString(spoolss_error, "Not implemented");
- return NULL;
-}
-
-PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- PyErr_SetString(spoolss_error, "Not implemented");
- return NULL;
-}
diff --git a/source/python/py_spoolss_drivers_conv.c b/source/python/py_spoolss_drivers_conv.c
deleted file mode 100644
index 9bc84080529..00000000000
--- a/source/python/py_spoolss_drivers_conv.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-/* Structure/hash conversions */
-
-struct pyconv py_DRIVER_INFO_1[] = {
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_1, name) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_2[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_2, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_2, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_2, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_2, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_2, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_2, configfile) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_3[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_3, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_3, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_3, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_3, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_3, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_3, configfile) },
- { "help_file", PY_UNISTR, offsetof(DRIVER_INFO_3, helpfile) },
- { "monitor_name", PY_UNISTR, offsetof(DRIVER_INFO_3, monitorname) },
- { "default_datatype", PY_UNISTR, offsetof(DRIVER_INFO_3, defaultdatatype) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_6[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_6, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_6, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_6, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_6, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_6, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_6, configfile) },
- { "help_file", PY_UNISTR, offsetof(DRIVER_INFO_6, helpfile) },
- { "monitor_name", PY_UNISTR, offsetof(DRIVER_INFO_6, monitorname) },
- { "default_datatype", PY_UNISTR, offsetof(DRIVER_INFO_6, defaultdatatype) },
- /* driver_date */
- { "padding", PY_UINT32, offsetof(DRIVER_INFO_6, padding) },
- { "driver_version_low", PY_UINT32, offsetof(DRIVER_INFO_6, driver_version_low) },
- { "driver_version_high", PY_UINT32, offsetof(DRIVER_INFO_6, driver_version_high) },
- { "mfg_name", PY_UNISTR, offsetof(DRIVER_INFO_6, mfgname) },
- { "oem_url", PY_UNISTR, offsetof(DRIVER_INFO_6, oem_url) },
- { "hardware_id", PY_UNISTR, offsetof(DRIVER_INFO_6, hardware_id) },
- { "provider", PY_UNISTR, offsetof(DRIVER_INFO_6, provider) },
-
- { NULL }
-};
-
-struct pyconv py_DRIVER_DIRECTORY_1[] = {
- { "name", PY_UNISTR, offsetof(DRIVER_DIRECTORY_1, name) },
- { NULL }
-};
-
-static uint16 *to_dependentfiles(PyObject *dict)
-{
- return (uint16 *)"abcd\0";
-}
-
-BOOL py_from_DRIVER_INFO_1(PyObject **dict, DRIVER_INFO_1 *info)
-{
- *dict = from_struct(info, py_DRIVER_INFO_1);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(1));
-
- return True;
-}
-
-BOOL py_to_DRIVER_INFO_1(DRIVER_INFO_1 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_DRIVER_INFO_2(PyObject **dict, DRIVER_INFO_2 *info)
-{
- *dict = from_struct(info, py_DRIVER_INFO_2);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(2));
-
- return True;
-}
-
-BOOL py_to_DRIVER_INFO_2(DRIVER_INFO_2 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_DRIVER_INFO_3(PyObject **dict, DRIVER_INFO_3 *info)
-{
- *dict = from_struct(info, py_DRIVER_INFO_3);
-
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(3));
-
- PyDict_SetItemString(
- *dict, "dependent_files",
- from_unistr_list(info->dependentfiles));
-
- return True;
-}
-
-BOOL py_to_DRIVER_INFO_3(DRIVER_INFO_3 *info, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "dependent_files")) ||
- !PyList_Check(obj))
- goto done;
-
- info->dependentfiles = to_dependentfiles(obj);
-
- PyDict_DelItemString(dict_copy, "dependent_files");
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- if (!to_struct(info, dict_copy, py_DRIVER_INFO_3))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-BOOL py_from_DRIVER_INFO_6(PyObject **dict, DRIVER_INFO_6 *info)
-{
- *dict = from_struct(info, py_DRIVER_INFO_6);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(6));
- PyDict_SetItemString(
- *dict, "dependent_files",
- from_unistr_list(info->dependentfiles));
- return True;
-}
-
-BOOL py_to_DRIVER_INFO_6(DRIVER_INFO_6 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_DRIVER_DIRECTORY_1(PyObject **dict, DRIVER_DIRECTORY_1 *info)
-{
- *dict = from_struct(info, py_DRIVER_DIRECTORY_1);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(1));
- return True;
-}
-
-BOOL py_to_DRIVER_DIRECTORY_1(DRIVER_DIRECTORY_1 *info, PyObject *dict)
-{
- return False;
-}
diff --git a/source/python/py_spoolss_forms.c b/source/python/py_spoolss_forms.c
deleted file mode 100644
index 66a6540e074..00000000000
--- a/source/python/py_spoolss_forms.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Add a form */
-
-PyObject *spoolss_hnd_addform(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *info;
- FORM form;
- int level;
- static char *kwlist[] = {"form", NULL};
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &info))
- return NULL;
-
- /* Call rpc function */
-
- if (!py_to_FORM(&form, info)) {
- PyErr_SetString(spoolss_error, "invalid form");
- return NULL;
- }
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(spoolss_error, "invalid info level");
- return NULL;
- }
-
- if (level != 1) {
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- switch (level) {
- case 1: {
- PyObject *obj = PyDict_GetItemString(info, "name");
- char *form_name = PyString_AsString(obj);
-
- init_unistr2(&form.name, form_name, UNI_STR_TERMINATE);
- break;
- }
- default:
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- werror = cli_spoolss_addform(hnd->cli, hnd->mem_ctx, &hnd->pol,
- level, &form);
-
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Get form properties */
-
-PyObject *spoolss_hnd_getform(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *result;
- char *form_name;
- int level = 1;
- static char *kwlist[] = {"form_name", "level", NULL};
- uint32 needed;
- FORM_1 form;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|i", kwlist, &form_name, &level))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getform(hnd->cli, hnd->mem_ctx, 0, &needed,
- &hnd->pol, form_name, level, &form);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getform(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- form_name, 1, &form);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- result = Py_None;
-
- switch(level) {
- case 1:
- py_from_FORM_1(&result, &form);
- break;
- }
-
- Py_INCREF(result);
- return result;
-}
-
-/* Set form properties */
-
-PyObject *spoolss_hnd_setform(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *info, *form_name;
- int level;
- static char *kwlist[] = { "form", NULL};
- FORM form;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &info))
- return NULL;
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(spoolss_error, "invalid info level");
- return NULL;
- }
-
- if (level != 1) {
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- /* Call rpc function */
-
- if (!py_to_FORM(&form, info)) {
- PyErr_SetString(spoolss_error, "invalid form");
- return NULL;
- }
-
- form_name = PyDict_GetItemString(info, "name");
-
- werror = cli_spoolss_setform(
- hnd->cli, hnd->mem_ctx, &hnd->pol, level,
- PyString_AsString(form_name), &form);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Delete a form */
-
-PyObject *spoolss_hnd_deleteform(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = {"form_name", NULL};
- char *form_name;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s", kwlist, &form_name))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_deleteform(
- hnd->cli, hnd->mem_ctx, &hnd->pol, form_name);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Enumerate forms */
-
-PyObject *spoolss_hnd_enumforms(PyObject *self, PyObject *args, PyObject *kw)
-{
- PyObject *result;
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- uint32 level = 1, num_forms, needed, i;
- static char *kwlist[] = {"level", NULL};
- FORM_1 *forms;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "|i", kwlist, &level))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_enumforms(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
- &num_forms, &forms);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enumforms(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol, level,
- &num_forms, &forms);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- switch(level) {
- case 1:
- result = PyDict_New();
-
- for (i = 0; i < num_forms; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, forms[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_FORM_1(&value, &forms[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(1));
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unknown info level");
- return NULL;
- }
-
- return result;
-}
diff --git a/source/python/py_spoolss_forms_conv.c b/source/python/py_spoolss_forms_conv.c
deleted file mode 100644
index ede729cad33..00000000000
--- a/source/python/py_spoolss_forms_conv.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-struct pyconv py_FORM[] = {
- { "flags", PY_UINT32, offsetof(FORM, flags) },
- { "width", PY_UINT32, offsetof(FORM, size_x) },
- { "length", PY_UINT32, offsetof(FORM, size_y) },
- { "top", PY_UINT32, offsetof(FORM, top) },
- { "left", PY_UINT32, offsetof(FORM, left) },
- { "right", PY_UINT32, offsetof(FORM, right) },
- { "bottom", PY_UINT32, offsetof(FORM, bottom) },
- { NULL }
-};
-
-struct pyconv py_FORM_1[] = {
- { "flags", PY_UINT32, offsetof(FORM_1, flag) },
- { "width", PY_UINT32, offsetof(FORM_1, width) },
- { "length", PY_UINT32, offsetof(FORM_1, length) },
- { "top", PY_UINT32, offsetof(FORM_1, top) },
- { "left", PY_UINT32, offsetof(FORM_1, left) },
- { "right", PY_UINT32, offsetof(FORM_1, right) },
- { "bottom", PY_UINT32, offsetof(FORM_1, bottom) },
- { "name", PY_UNISTR, offsetof(FORM_1, name) },
- { NULL }
-};
-
-BOOL py_from_FORM_1(PyObject **dict, FORM_1 *form)
-{
- *dict = from_struct(form, py_FORM_1);
-
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(1));
-
- return True;
-}
-
-BOOL py_to_FORM(FORM *form, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- char *name;
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "name")) ||
- !PyString_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "name");
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- if (!to_struct(form, dict_copy, py_FORM))
- goto done;
-
- /* Careful! We can't call PyString_AsString(obj) then delete
- obj and still expect to have our pointer pointing somewhere
- useful. */
-
- obj = PyDict_GetItemString(dict, "name");
- name = PyString_AsString(obj);
-
- init_unistr2(&form->name, name, UNI_STR_TERMINATE);
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
diff --git a/source/python/py_spoolss_jobs.c b/source/python/py_spoolss_jobs.c
deleted file mode 100644
index 59754bd36dd..00000000000
--- a/source/python/py_spoolss_jobs.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Enumerate jobs */
-
-PyObject *spoolss_hnd_enumjobs(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *result;
- int level = 1;
- uint32 i, needed, num_jobs;
- static char *kwlist[] = {"level", NULL};
- JOB_INFO_CTR ctr;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_enumjobs(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, 0,
- 1000, &num_jobs, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enumjobs(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, 0, 1000, &num_jobs, &ctr);
-
- /* Return value */
-
- result = Py_None;
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- result = PyList_New(num_jobs);
-
- switch (level) {
- case 1:
- for (i = 0; i < num_jobs; i++) {
- PyObject *value;
-
- py_from_JOB_INFO_1(&value, &ctr.job.job_info_1[i]);
-
- PyList_SetItem(result, i, value);
- }
-
- break;
- case 2:
- for(i = 0; i < num_jobs; i++) {
- PyObject *value;
-
- py_from_JOB_INFO_2(&value, &ctr.job.job_info_2[i]);
-
- PyList_SetItem(result, i, value);
- }
-
- break;
- }
-
- done:
- Py_INCREF(result);
- return result;
-}
-
-/* Set job command */
-
-PyObject *spoolss_hnd_setjob(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- uint32 level = 0, command, jobid;
- static char *kwlist[] = {"jobid", "command", "level", NULL};
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "ii|i", kwlist, &jobid, &command, &level))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_setjob(hnd->cli, hnd->mem_ctx, &hnd->pol,
- jobid, level, command);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Get job */
-
-PyObject *spoolss_hnd_getjob(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *result;
- uint32 level = 1, jobid, needed;
- static char *kwlist[] = {"jobid", "level", NULL};
- JOB_INFO_CTR ctr;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "i|i", kwlist, &jobid, &level))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getjob(hnd->cli, hnd->mem_ctx, 0, &needed,
- &hnd->pol, jobid, level, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getjob(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- jobid, level, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- switch(level) {
- case 1:
- py_from_JOB_INFO_1(&result, &ctr.job.job_info_1[0]);
- break;
- case 2:
- py_from_JOB_INFO_2(&result, &ctr.job.job_info_2[0]);
- break;
- }
-
- return result;
-}
-
-/* Start page printer. This notifies the spooler that a page is about to be
- printed on the specified printer. */
-
-PyObject *spoolss_hnd_startpageprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = { NULL };
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_startpageprinter(
- hnd->cli, hnd->mem_ctx, &hnd->pol);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* End page printer. This notifies the spooler that a page has finished
- being printed on the specified printer. */
-
-PyObject *spoolss_hnd_endpageprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = { NULL };
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_endpageprinter(
- hnd->cli, hnd->mem_ctx, &hnd->pol);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Start doc printer. This notifies the spooler that a document is about to be
- printed on the specified printer. */
-
-PyObject *spoolss_hnd_startdocprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = { "document_info", NULL };
- PyObject *info, *obj;
- uint32 level, jobid;
- char *document_name = NULL, *output_file = NULL, *data_type = NULL;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &info))
- return NULL;
-
- /* Check document_info parameter */
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(spoolss_error, "invalid info level");
- return NULL;
- }
-
- if (level != 1) {
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- if ((obj = PyDict_GetItemString(info, "document_name"))) {
-
- if (!PyString_Check(obj) && obj != Py_None) {
- PyErr_SetString(spoolss_error,
- "document_name not a string");
- return NULL;
- }
-
- if (PyString_Check(obj))
- document_name = PyString_AsString(obj);
-
- } else {
- PyErr_SetString(spoolss_error, "no document_name present");
- return NULL;
- }
-
- if ((obj = PyDict_GetItemString(info, "output_file"))) {
-
- if (!PyString_Check(obj) && obj != Py_None) {
- PyErr_SetString(spoolss_error,
- "output_file not a string");
- return NULL;
- }
-
- if (PyString_Check(obj))
- output_file = PyString_AsString(obj);
-
- } else {
- PyErr_SetString(spoolss_error, "no output_file present");
- return NULL;
- }
-
- if ((obj = PyDict_GetItemString(info, "data_type"))) {
-
- if (!PyString_Check(obj) && obj != Py_None) {
- PyErr_SetString(spoolss_error,
- "data_type not a string");
- return NULL;
- }
-
- if (PyString_Check(obj))
- data_type = PyString_AsString(obj);
-
- } else {
- PyErr_SetString(spoolss_error, "no data_type present");
- return NULL;
- }
-
- /* Call rpc function */
-
- werror = cli_spoolss_startdocprinter(
- hnd->cli, hnd->mem_ctx, &hnd->pol, document_name,
- output_file, data_type, &jobid);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- /* The return value is zero for an error (where does the status
- code come from now??) and the return value is the jobid
- allocated for the new job. */
-
- return Py_BuildValue("i", jobid);
-}
-
-/* End doc printer. This notifies the spooler that a document has finished
- being printed on the specified printer. */
-
-PyObject *spoolss_hnd_enddocprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = { NULL };
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_enddocprinter(hnd->cli, hnd->mem_ctx, &hnd->pol);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Write data to a printer */
-
-PyObject *spoolss_hnd_writeprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- static char *kwlist[] = { "data", NULL };
- PyObject *data;
- uint32 num_written;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyString_Type, &data))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_writeprinter(
- hnd->cli, hnd->mem_ctx, &hnd->pol, PyString_Size(data),
- PyString_AsString(data), &num_written);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *spoolss_hnd_addjob(PyObject *self, PyObject *args, PyObject *kw)
-{
- PyErr_SetString(spoolss_error, "Not implemented");
- return NULL;
-}
diff --git a/source/python/py_spoolss_jobs_conv.c b/source/python/py_spoolss_jobs_conv.c
deleted file mode 100644
index cb04ec6713c..00000000000
--- a/source/python/py_spoolss_jobs_conv.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-struct pyconv py_JOB_INFO_1[] = {
- { "jobid", PY_UINT32, offsetof(JOB_INFO_1, jobid) },
- { "printer_name", PY_UNISTR, offsetof(JOB_INFO_1, printername) },
- { "server_name", PY_UNISTR, offsetof(JOB_INFO_1, machinename) },
- { "user_name", PY_UNISTR, offsetof(JOB_INFO_1, username) },
- { "document_name", PY_UNISTR, offsetof(JOB_INFO_1, document) },
- { "data_type", PY_UNISTR, offsetof(JOB_INFO_1, datatype) },
- { "text_status", PY_UNISTR, offsetof(JOB_INFO_1, text_status) },
- { "status", PY_UINT32, offsetof(JOB_INFO_1, status) },
- { "priority", PY_UINT32, offsetof(JOB_INFO_1, priority) },
- { "position", PY_UINT32, offsetof(JOB_INFO_1, position) },
- { "total_pages", PY_UINT32, offsetof(JOB_INFO_1, totalpages) },
- { "pages_printed", PY_UINT32, offsetof(JOB_INFO_1, pagesprinted) },
- { NULL }
-};
-
-struct pyconv py_JOB_INFO_2[] = {
- { "jobid", PY_UINT32, offsetof(JOB_INFO_2, jobid) },
- { "printer_name", PY_UNISTR, offsetof(JOB_INFO_2, printername) },
- { "server_name", PY_UNISTR, offsetof(JOB_INFO_2, machinename) },
- { "user_name", PY_UNISTR, offsetof(JOB_INFO_2, username) },
- { "document_name", PY_UNISTR, offsetof(JOB_INFO_2, document) },
- { "notify_name", PY_UNISTR, offsetof(JOB_INFO_2, notifyname) },
- { "data_type", PY_UNISTR, offsetof(JOB_INFO_2, datatype) },
- { "print_processor", PY_UNISTR, offsetof(JOB_INFO_2, printprocessor) },
- { "parameters", PY_UNISTR, offsetof(JOB_INFO_2, parameters) },
- { "driver_name", PY_UNISTR, offsetof(JOB_INFO_2, drivername) },
- { "text_status", PY_UNISTR, offsetof(JOB_INFO_2, text_status) },
- { "status", PY_UINT32, offsetof(JOB_INFO_2, status) },
- { "priority", PY_UINT32, offsetof(JOB_INFO_2, priority) },
- { "position", PY_UINT32, offsetof(JOB_INFO_2, position) },
- { "start_time", PY_UINT32, offsetof(JOB_INFO_2, starttime) },
- { "until_time", PY_UINT32, offsetof(JOB_INFO_2, untiltime) },
- { "total_pages", PY_UINT32, offsetof(JOB_INFO_2, totalpages) },
- { "size", PY_UINT32, offsetof(JOB_INFO_2, size) },
- { "time_elapsed", PY_UINT32, offsetof(JOB_INFO_2, timeelapsed) },
- { "pages_printed", PY_UINT32, offsetof(JOB_INFO_2, pagesprinted) },
- { NULL }
-};
-
-struct pyconv py_DOC_INFO_1[] = {
- { "document_name", PY_UNISTR, offsetof(DOC_INFO_1, docname) },
- { "output_file", PY_UNISTR, offsetof(DOC_INFO_1, outputfile) },
- { "data_type", PY_UNISTR, offsetof(DOC_INFO_1, datatype) },
- { NULL }
-};
-
-BOOL py_from_JOB_INFO_1(PyObject **dict, JOB_INFO_1 *info)
-{
- *dict = from_struct(info, py_JOB_INFO_1);
- return True;
-}
-
-BOOL py_to_JOB_INFO_1(JOB_INFO_1 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_JOB_INFO_2(PyObject **dict, JOB_INFO_2 *info)
-{
- *dict = from_struct(info, py_JOB_INFO_2);
- return True;
-}
-
-BOOL py_to_JOB_INFO_2(JOB_INFO_2 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_DOC_INFO_1(PyObject **dict, DOC_INFO_1 *info)
-{
- *dict = from_struct(info, py_DOC_INFO_1);
- return True;
-}
-
-BOOL py_to_DOC_INFO_1(DOC_INFO_1 *info, PyObject *dict)
-{
- return to_struct(info, dict, py_DOC_INFO_1);
-}
diff --git a/source/python/py_spoolss_ports.c b/source/python/py_spoolss_ports.c
deleted file mode 100644
index ddc8868f0f5..00000000000
--- a/source/python/py_spoolss_ports.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Enumerate ports */
-
-PyObject *spoolss_enumports(PyObject *self, PyObject *args, PyObject *kw)
-{
- WERROR werror;
- PyObject *result = NULL, *creds = NULL;
- uint32 level = 1;
- uint32 i, needed, num_ports;
- static char *kwlist[] = {"server", "level", "creds", NULL};
- TALLOC_CTX *mem_ctx = NULL;
- struct cli_state *cli = NULL;
- char *server, *errstr;
- PORT_INFO_CTR ctr;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|iO", kwlist, &server, &level, &creds))
- return NULL;
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_enumports"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- goto done;
- }
-
- /* Call rpc function */
-
- werror = cli_spoolss_enum_ports(
- cli, mem_ctx, 0, &needed, level, &num_ports, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enum_ports(
- cli, mem_ctx, needed, NULL, level,
- &num_ports, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- /* Return value */
-
- switch (level) {
- case 1:
- result = PyDict_New();
-
- for (i = 0; i < num_ports; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.port.info_1[i].port_name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_PORT_INFO_1(&value, &ctr.port.info_1[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(1));
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- case 2:
- result = PyDict_New();
-
- for(i = 0; i < num_ports; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, ctr.port.info_2[i].port_name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_PORT_INFO_2(&value, &ctr.port.info_2[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(2));
-
- PyDict_SetItemString(result, name, value);
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unknown info level");
- goto done;
- }
-
- done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
diff --git a/source/python/py_spoolss_ports_conv.c b/source/python/py_spoolss_ports_conv.c
deleted file mode 100644
index 3f6d94bf7e7..00000000000
--- a/source/python/py_spoolss_ports_conv.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-struct pyconv py_PORT_INFO_1[] = {
- { "name", PY_UNISTR, offsetof(PORT_INFO_1, port_name) },
- { NULL }
-};
-
-struct pyconv py_PORT_INFO_2[] = {
- { "name", PY_UNISTR, offsetof(PORT_INFO_2, port_name) },
- { "monitor_name", PY_UNISTR, offsetof(PORT_INFO_2, monitor_name) },
- { "description", PY_UNISTR, offsetof(PORT_INFO_2, description) },
- { "reserved", PY_UINT32, offsetof(PORT_INFO_2, reserved) },
- { "type", PY_UINT32, offsetof(PORT_INFO_2, port_type) },
- { NULL }
-};
-
-BOOL py_from_PORT_INFO_1(PyObject **dict, PORT_INFO_1 *info)
-{
- *dict = from_struct(info, py_PORT_INFO_1);
- return True;
-}
-
-BOOL py_to_PORT_INFO_1(PORT_INFO_1 *info, PyObject *dict)
-{
- return False;
-}
-
-BOOL py_from_PORT_INFO_2(PyObject **dict, PORT_INFO_2 *info)
-{
- *dict = from_struct(info, py_PORT_INFO_2);
- return True;
-}
-
-BOOL py_to_PORT_INFO_2(PORT_INFO_2 *info, PyObject *dict)
-{
- return False;
-}
diff --git a/source/python/py_spoolss_printerdata.c b/source/python/py_spoolss_printerdata.c
deleted file mode 100644
index f165475b080..00000000000
--- a/source/python/py_spoolss_printerdata.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-static BOOL py_from_printerdata(PyObject **dict, char *key, char *value,
- uint16 data_type, uint8 *data,
- uint32 data_size)
-{
- *dict = PyDict_New();
-
- PyDict_SetItemString(*dict, "key", Py_BuildValue("s", key ? key : ""));
- PyDict_SetItemString(*dict, "value", Py_BuildValue("s", value));
- PyDict_SetItemString(*dict, "type", Py_BuildValue("i", data_type));
-
- PyDict_SetItemString(*dict, "data",
- Py_BuildValue("s#", data, data_size));
-
- return True;
-}
-
-static BOOL py_to_printerdata(char **key, char **value, uint16 *data_type,
- uint8 **data, uint32 *data_size,
- PyObject *dict)
-{
- PyObject *obj;
-
- if ((obj = PyDict_GetItemString(dict, "key"))) {
-
- if (!PyString_Check(obj)) {
- PyErr_SetString(spoolss_error,
- "key not a string");
- return False;
- }
-
- if (key) {
- *key = PyString_AsString(obj);
-
- if (!key[0])
- *key = NULL;
- }
- } else
- *key = NULL;
-
- if ((obj = PyDict_GetItemString(dict, "value"))) {
-
- if (!PyString_Check(obj)) {
- PyErr_SetString(spoolss_error,
- "value not a string");
- return False;
- }
-
- *value = PyString_AsString(obj);
- } else {
- PyErr_SetString(spoolss_error, "no value present");
- return False;
- }
-
- if ((obj = PyDict_GetItemString(dict, "type"))) {
-
- if (!PyInt_Check(obj)) {
- PyErr_SetString(spoolss_error,
- "type not an integer");
- return False;
- }
-
- *data_type = PyInt_AsLong(obj);
- } else {
- PyErr_SetString(spoolss_error, "no type present");
- return False;
- }
-
- if ((obj = PyDict_GetItemString(dict, "data"))) {
-
- if (!PyString_Check(obj)) {
- PyErr_SetString(spoolss_error,
- "data not a string");
- return False;
- }
-
- *data = PyString_AsString(obj);
- *data_size = PyString_Size(obj);
- } else {
- PyErr_SetString(spoolss_error, "no data present");
- return False;
- }
-
- return True;
-}
-
-PyObject *spoolss_hnd_getprinterdata(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "value", NULL };
- char *valuename;
- WERROR werror;
- uint32 needed;
- PyObject *result;
- REGISTRY_VALUE value;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &valuename))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getprinterdata(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, valuename,
- &value);
-
- if (W_ERROR_V(werror) == ERRmoredata)
- werror = cli_spoolss_getprinterdata(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- valuename, &value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- py_from_printerdata(
- &result, NULL, valuename, value.type, value.data_p,
- value.size);
-
- return result;
-}
-
-PyObject *spoolss_hnd_setprinterdata(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "data", NULL };
- PyObject *py_data;
- char *valuename;
- WERROR werror;
- REGISTRY_VALUE value;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &py_data))
- return NULL;
-
- if (!py_to_printerdata(
- NULL, &valuename, &value.type, &value.data_p,
- &value.size, py_data))
- return NULL;
-
- fstrcpy(value.valuename, valuename);
-
- /* Call rpc function */
-
- werror = cli_spoolss_setprinterdata(
- hnd->cli, hnd->mem_ctx, &hnd->pol, &value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *spoolss_hnd_enumprinterdata(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { NULL };
- uint32 data_needed, value_needed, ndx = 0;
- WERROR werror;
- PyObject *result;
- REGISTRY_VALUE value;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
- return NULL;
-
- /* Get max buffer sizes for value and data */
-
- werror = cli_spoolss_enumprinterdata(
- hnd->cli, hnd->mem_ctx, &hnd->pol, ndx, 0, 0,
- &value_needed, &data_needed, NULL);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- /* Iterate over all printerdata */
-
- result = PyDict_New();
-
- while (W_ERROR_IS_OK(werror)) {
- PyObject *obj;
-
- werror = cli_spoolss_enumprinterdata(
- hnd->cli, hnd->mem_ctx, &hnd->pol, ndx,
- value_needed, data_needed, NULL, NULL, &value);
-
- if (py_from_printerdata(
- &obj, NULL, value.valuename, value.type,
- value.data_p, value.size))
- PyDict_SetItemString(result, value.valuename, obj);
-
- ndx++;
- }
-
- return result;
-}
-
-PyObject *spoolss_hnd_deleteprinterdata(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "value", NULL };
- char *value;
- WERROR werror;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &value))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_deleteprinterdata(
- hnd->cli, hnd->mem_ctx, &hnd->pol, value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *spoolss_hnd_getprinterdataex(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "key", "value", NULL };
- char *key, *valuename;
- WERROR werror;
- uint32 needed;
- PyObject *result;
- REGISTRY_VALUE value;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "ss", kwlist, &key, &valuename))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getprinterdataex(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, key,
- valuename, &value);
-
- if (W_ERROR_V(werror) == ERRmoredata)
- werror = cli_spoolss_getprinterdataex(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol, key,
- valuename, &value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- py_from_printerdata(
- &result, key, valuename, value.type, value.data_p, value.size);
-
- return result;
-}
-
-PyObject *spoolss_hnd_setprinterdataex(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "data", NULL };
- PyObject *py_data;
- char *keyname, *valuename;
- WERROR werror;
- REGISTRY_VALUE value;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &py_data))
- return NULL;
-
- if (!py_to_printerdata(
- &keyname, &valuename, &value.type, &value.data_p, &value.size, py_data))
- return NULL;
-
- fstrcpy(value.valuename, valuename);
-
- /* Call rpc function */
-
- werror = cli_spoolss_setprinterdataex(
- hnd->cli, hnd->mem_ctx, &hnd->pol, keyname, &value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *spoolss_hnd_enumprinterdataex(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "key", NULL };
- uint32 needed, i;
- char *key;
- WERROR werror;
- PyObject *result;
- REGVAL_CTR ctr;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &key))
- return NULL;
-
- /* Get max buffer sizes for value and data */
-
- werror = cli_spoolss_enumprinterdataex(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, key, &ctr);
-
- if (W_ERROR_V(werror) == ERRmoredata)
- werror = cli_spoolss_enumprinterdataex(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol, key,
- &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- /* Iterate over all printerdata */
-
- result = PyDict_New();
-
- for (i = 0; i < regval_ctr_numvals(&ctr); i++) {
- REGISTRY_VALUE *value;
- PyObject *item;
-
- item = PyDict_New();
- value = regval_ctr_specific_value(&ctr, i);
-
- if (py_from_printerdata(
- &item, key, value->valuename, value->type,
- value->data_p, value->size))
- PyDict_SetItemString(result, value->valuename, item);
- }
-
- return result;
-}
-
-PyObject *spoolss_hnd_deleteprinterdataex(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "key", "value", NULL };
- char *key, *value;
- WERROR werror;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "ss", kwlist, &key, &value))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_deleteprinterdataex(
- hnd->cli, hnd->mem_ctx, &hnd->pol, key, value);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *spoolss_hnd_enumprinterkey(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "key", NULL };
- char *keyname;
- WERROR werror;
- uint32 needed, keylist_len;
- uint16 *keylist;
- PyObject *result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &keyname))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_enumprinterkey(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol,
- keyname, &keylist, &keylist_len);
-
- if (W_ERROR_V(werror) == ERRmoredata)
- werror = cli_spoolss_enumprinterkey(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- keyname, &keylist, &keylist_len);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- result = from_unistr_list(keylist);
-
- return result;
-}
-
-#if 0
-
-PyObject *spoolss_hnd_deleteprinterkey(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- static char *kwlist[] = { "key", NULL };
- char *keyname;
- WERROR werror;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &keyname))
- return NULL;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#endif
diff --git a/source/python/py_spoolss_printers.c b/source/python/py_spoolss_printers.c
deleted file mode 100644
index d011681acc2..00000000000
--- a/source/python/py_spoolss_printers.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-
-/* Open a printer */
-
-PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- char *unc_name, *server, *errstr;
- TALLOC_CTX *mem_ctx = NULL;
- POLICY_HND hnd;
- WERROR werror;
- PyObject *result = NULL, *creds = NULL;
- static char *kwlist[] = { "printername", "creds", "access", NULL };
- uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
- struct cli_state *cli;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|Oi", kwlist, &unc_name, &creds,
- &desired_access))
- return NULL;
-
- if (unc_name[0] != '\\' || unc_name[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server = strdup(unc_name + 2);
-
- if (strchr(server, '\\')) {
- char *c = strchr(server, '\\');
- *c = 0;
- }
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
- PyErr_SetString(spoolss_error,
- "unable to init talloc context\n");
- goto done;
- }
-
- werror = cli_spoolss_open_printer_ex(
- cli, mem_ctx, unc_name, "", desired_access, server,
- "", &hnd);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
-
- done:
- if (!result) {
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
- }
-
- SAFE_FREE(server);
-
- return result;
-}
-
-/* Close a printer */
-
-PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
-{
- PyObject *po;
- spoolss_policy_hnd_object *hnd;
- WERROR result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
- return NULL;
-
- hnd = (spoolss_policy_hnd_object *)po;
-
- /* Call rpc function */
-
- result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
-
- /* Return value */
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Fetch printer information */
-
-PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *result = NULL;
- PRINTER_INFO_CTR ctr;
- int level = 1;
- uint32 needed;
- static char *kwlist[] = {"level", NULL};
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
- return NULL;
-
- ZERO_STRUCT(ctr);
-
- /* Call rpc function */
-
- werror = cli_spoolss_getprinter(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinter(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, &ctr);
-
- /* Return value */
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- result = Py_None;
-
- switch (level) {
-
- case 0:
- py_from_PRINTER_INFO_0(&result, ctr.printers_0);
- break;
-
- case 1:
- py_from_PRINTER_INFO_1(&result, ctr.printers_1);
- break;
-
- case 2:
- py_from_PRINTER_INFO_2(&result, ctr.printers_2);
- break;
-
- case 3:
- py_from_PRINTER_INFO_3(&result, ctr.printers_3);
- break;
- }
-
- Py_INCREF(result);
- return result;
-}
-
-/* Set printer information */
-
-PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
-{
- spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
- WERROR werror;
- PyObject *info;
- PRINTER_INFO_CTR ctr;
- uint32 level;
- static char *kwlist[] = {"dict", NULL};
- union {
- PRINTER_INFO_1 printers_1;
- PRINTER_INFO_2 printers_2;
- PRINTER_INFO_3 printers_3;
- } pinfo;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &info))
- return NULL;
-
- if (!get_level_value(info, &level)) {
- PyErr_SetString(spoolss_error, "invalid info level");
- return NULL;
- }
-
- if (level < 1 && level > 3) {
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- /* Fill in printer info */
-
- ZERO_STRUCT(ctr);
-
- switch (level) {
- case 1:
- ctr.printers_1 = &pinfo.printers_1;
-
- if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
- PyErr_SetString(spoolss_error,
- "error converting printer to info 1");
- return NULL;
- }
-
- break;
- case 2:
- ctr.printers_2 = &pinfo.printers_2;
-
- if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
- hnd->mem_ctx)){
- PyErr_SetString(spoolss_error,
- "error converting printer to info 2");
- return NULL;
- }
-
- break;
- case 3:
- ctr.printers_3 = &pinfo.printers_3;
-
- if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
- hnd->mem_ctx)) {
- PyErr_SetString(spoolss_error,
- "error converting to printer info 3");
- return NULL;
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unsupported info level");
- return NULL;
- }
-
- /* Call rpc function */
-
- werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
- level, &ctr, 0);
-
- /* Return value */
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Enumerate printers */
-
-PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
-{
- WERROR werror;
- PyObject *result = NULL, *creds = NULL;
- PRINTER_INFO_CTR ctr;
- int level = 1, flags = PRINTER_ENUM_LOCAL, i;
- uint32 needed, num_printers;
- static char *kwlist[] = {"server", "name", "level", "flags",
- "creds", NULL};
- TALLOC_CTX *mem_ctx = NULL;
- struct cli_state *cli = NULL;
- char *server, *errstr, *name = NULL;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|siiO", kwlist, &server, &name, &level,
- &flags, &creds))
- return NULL;
-
- if (server[0] != '\\' || server[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server += 2;
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- goto done;
- }
-
- /* This RPC is weird. By setting the server name to different
- values we can get different behaviour. If however the server
- name is not specified, we default it to being the full server
- name as this is probably what the caller intended. To pass a
- NULL name, pass a value of "" */
-
- if (!name)
- name = server;
- else {
- if (!name[0])
- name = NULL;
- }
-
- /* Call rpc function */
-
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, 0, &needed, name, flags, level,
- &num_printers, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, needed, NULL, name, flags,
- level, &num_printers, &ctr);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- goto done;
- }
-
- /* Return value */
-
- switch (level) {
- case 0:
- result = PyDict_New();
-
- for (i = 0; i < num_printers; i++) {
- PyObject *value;
- fstring s;
-
- rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(0));
-
- PyDict_SetItemString(result, s, value);
- }
-
- break;
- case 1:
- result = PyDict_New();
-
- for(i = 0; i < num_printers; i++) {
- PyObject *value;
- fstring s;
-
- rpcstr_pull(s, ctr.printers_1[i].name.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(1));
-
- PyDict_SetItemString(result, s, value);
- }
-
- break;
- case 2:
- result = PyDict_New();
-
- for(i = 0; i < num_printers; i++) {
- PyObject *value;
- fstring s;
-
- rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
- sizeof(fstring), -1, STR_TERMINATE);
-
- py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(2));
-
- PyDict_SetItemString(result, s, value);
- }
-
- break;
- default:
- PyErr_SetString(spoolss_error, "unknown info level");
- goto done;
- }
-
-done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/* Add a printer */
-
-PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] = { "server", "printername", "info", "creds",
- NULL};
- char *printername, *server, *errstr;
- PyObject *info, *result = NULL, *creds = NULL;
- struct cli_state *cli = NULL;
- TALLOC_CTX *mem_ctx = NULL;
- PRINTER_INFO_CTR ctr;
- PRINTER_INFO_2 info2;
- WERROR werror;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "ssO!|O!", kwlist, &server, &printername,
- &PyDict_Type, &info, &PyDict_Type, &creds))
- return NULL;
-
- if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- goto done;
- }
-
- if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
- PyErr_SetString(spoolss_error,
- "error converting to printer info 2");
- goto done;
- }
-
- ctr.printers_2 = &info2;
-
- werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr);
-
- Py_INCREF(Py_None);
- result = Py_None;
-
-done:
- if (cli)
- cli_shutdown(cli);
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
diff --git a/source/python/py_spoolss_printers_conv.c b/source/python/py_spoolss_printers_conv.c
deleted file mode 100644
index f7b2f516df5..00000000000
--- a/source/python/py_spoolss_printers_conv.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_spoolss.h"
-#include "python/py_conv.h"
-
-struct pyconv py_PRINTER_INFO_0[] = {
- { "name", PY_UNISTR, offsetof(PRINTER_INFO_0, printername) },
- { "server_name", PY_UNISTR, offsetof(PRINTER_INFO_0, servername) },
-
- { "cjobs", PY_UINT32, offsetof(PRINTER_INFO_0, cjobs) },
- { "total_jobs", PY_UINT32, offsetof(PRINTER_INFO_0, total_jobs) },
- { "total_bytes", PY_UINT32, offsetof(PRINTER_INFO_0, total_bytes) },
-
- { "year", PY_UINT16, offsetof(PRINTER_INFO_0, year) },
- { "month", PY_UINT16, offsetof(PRINTER_INFO_0, month) },
- { "day_of_week", PY_UINT16, offsetof(PRINTER_INFO_0, dayofweek) },
- { "day", PY_UINT16, offsetof(PRINTER_INFO_0, day) },
- { "hour", PY_UINT16, offsetof(PRINTER_INFO_0, hour) },
- { "minute", PY_UINT16, offsetof(PRINTER_INFO_0, minute) },
- { "second", PY_UINT16, offsetof(PRINTER_INFO_0, second) },
- { "milliseconds", PY_UINT16, offsetof(PRINTER_INFO_0, milliseconds) },
-
- { "global_counter", PY_UINT32, offsetof(PRINTER_INFO_0, global_counter) },
- { "total_pages", PY_UINT32, offsetof(PRINTER_INFO_0, total_pages) },
-
- { "major_version", PY_UINT16, offsetof(PRINTER_INFO_0, major_version) },
- { "build_version", PY_UINT16, offsetof(PRINTER_INFO_0, build_version) },
-
- { "unknown7", PY_UINT32, offsetof(PRINTER_INFO_0, unknown7) },
- { "unknown8", PY_UINT32, offsetof(PRINTER_INFO_0, unknown8) },
- { "unknown9", PY_UINT32, offsetof(PRINTER_INFO_0, unknown9) },
- { "session_counter", PY_UINT32, offsetof(PRINTER_INFO_0, session_counter)},
- { "unknown11", PY_UINT32, offsetof(PRINTER_INFO_0, unknown11) },
- { "printer_errors", PY_UINT32, offsetof(PRINTER_INFO_0, printer_errors) },
- { "unknown13", PY_UINT32, offsetof(PRINTER_INFO_0, unknown13) },
- { "unknown14", PY_UINT32, offsetof(PRINTER_INFO_0, unknown14) },
- { "unknown15", PY_UINT32, offsetof(PRINTER_INFO_0, unknown15) },
- { "unknown16", PY_UINT32, offsetof(PRINTER_INFO_0, unknown16) },
- { "change_id", PY_UINT32, offsetof(PRINTER_INFO_0, change_id) },
- { "unknown18", PY_UINT32, offsetof(PRINTER_INFO_0, unknown18) },
- { "status", PY_UINT32, offsetof(PRINTER_INFO_0, status) },
- { "unknown20", PY_UINT32, offsetof(PRINTER_INFO_0, unknown20) },
- { "c_setprinter", PY_UINT32, offsetof(PRINTER_INFO_0, c_setprinter) },
- { "unknown22", PY_UINT32, offsetof(PRINTER_INFO_0, unknown22) },
- { "unknown23", PY_UINT32, offsetof(PRINTER_INFO_0, unknown23) },
- { "unknown24", PY_UINT32, offsetof(PRINTER_INFO_0, unknown24) },
- { "unknown25", PY_UINT32, offsetof(PRINTER_INFO_0, unknown25) },
- { "unknown26", PY_UINT32, offsetof(PRINTER_INFO_0, unknown26) },
- { "unknown27", PY_UINT32, offsetof(PRINTER_INFO_0, unknown27) },
- { "unknown28", PY_UINT32, offsetof(PRINTER_INFO_0, unknown28) },
- { "unknown29", PY_UINT32, offsetof(PRINTER_INFO_0, unknown29) },
-
- { NULL }
-};
-
-struct pyconv py_PRINTER_INFO_1[] = {
- { "name", PY_UNISTR, offsetof(PRINTER_INFO_1, name) },
- { "description", PY_UNISTR, offsetof(PRINTER_INFO_1, description) },
- { "comment", PY_UNISTR, offsetof(PRINTER_INFO_1, comment) },
- { "flags", PY_UINT32, offsetof(PRINTER_INFO_1, flags) },
- { NULL }
-};
-
-struct pyconv py_PRINTER_INFO_2[] = {
- { "server_name", PY_UNISTR, offsetof(PRINTER_INFO_2, servername) },
- { "name", PY_UNISTR, offsetof(PRINTER_INFO_2, printername) },
- { "share_name", PY_UNISTR, offsetof(PRINTER_INFO_2, sharename) },
- { "port_name", PY_UNISTR, offsetof(PRINTER_INFO_2, portname) },
- { "driver_name", PY_UNISTR, offsetof(PRINTER_INFO_2, drivername) },
- { "comment", PY_UNISTR, offsetof(PRINTER_INFO_2, comment) },
- { "location", PY_UNISTR, offsetof(PRINTER_INFO_2, location) },
- { "datatype", PY_UNISTR, offsetof(PRINTER_INFO_2, datatype) },
- { "sepfile", PY_UNISTR, offsetof(PRINTER_INFO_2, sepfile) },
- { "print_processor", PY_UNISTR, offsetof(PRINTER_INFO_2, printprocessor) },
- { "parameters", PY_UNISTR, offsetof(PRINTER_INFO_2, parameters) },
- { "attributes", PY_UINT32, offsetof(PRINTER_INFO_2, attributes) },
- { "default_priority", PY_UINT32, offsetof(PRINTER_INFO_2, defaultpriority) },
- { "priority", PY_UINT32, offsetof(PRINTER_INFO_2, priority) },
- { "start_time", PY_UINT32, offsetof(PRINTER_INFO_2, starttime) },
- { "until_time", PY_UINT32, offsetof(PRINTER_INFO_2, untiltime) },
- { "status", PY_UINT32, offsetof(PRINTER_INFO_2, status) },
- { "cjobs", PY_UINT32, offsetof(PRINTER_INFO_2, cjobs) },
- { "average_ppm", PY_UINT32, offsetof(PRINTER_INFO_2, averageppm) },
- { NULL }
-};
-
-struct pyconv py_PRINTER_INFO_3[] = {
- { "flags", PY_UINT32, offsetof(PRINTER_INFO_3, flags) },
- { NULL }
-};
-
-struct pyconv py_DEVICEMODE[] = {
- { "device_name", PY_UNISTR, offsetof(DEVICEMODE, devicename) },
- { "spec_version", PY_UINT16, offsetof(DEVICEMODE, specversion) },
- { "driver_version", PY_UINT16, offsetof(DEVICEMODE, driverversion) },
- { "size", PY_UINT16, offsetof(DEVICEMODE, size) },
- { "fields", PY_UINT16, offsetof(DEVICEMODE, fields) },
- { "orientation", PY_UINT16, offsetof(DEVICEMODE, orientation) },
- { "paper_size", PY_UINT16, offsetof(DEVICEMODE, papersize) },
- { "paper_width", PY_UINT16, offsetof(DEVICEMODE, paperwidth) },
- { "paper_length", PY_UINT16, offsetof(DEVICEMODE, paperlength) },
- { "scale", PY_UINT16, offsetof(DEVICEMODE, scale) },
- { "copies", PY_UINT16, offsetof(DEVICEMODE, copies) },
- { "default_source", PY_UINT16, offsetof(DEVICEMODE, defaultsource) },
- { "print_quality", PY_UINT16, offsetof(DEVICEMODE, printquality) },
- { "color", PY_UINT16, offsetof(DEVICEMODE, color) },
- { "duplex", PY_UINT16, offsetof(DEVICEMODE, duplex) },
- { "y_resolution", PY_UINT16, offsetof(DEVICEMODE, yresolution) },
- { "tt_option", PY_UINT16, offsetof(DEVICEMODE, ttoption) },
- { "collate", PY_UINT16, offsetof(DEVICEMODE, collate) },
- { "form_name", PY_UNISTR, offsetof(DEVICEMODE, formname) },
- { "log_pixels", PY_UINT16, offsetof(DEVICEMODE, logpixels) },
- { "bits_per_pel", PY_UINT32, offsetof(DEVICEMODE, bitsperpel) },
- { "pels_width", PY_UINT32, offsetof(DEVICEMODE, pelswidth) },
- { "pels_height", PY_UINT32, offsetof(DEVICEMODE, pelsheight) },
- { "display_flags", PY_UINT32, offsetof(DEVICEMODE, displayflags) },
- { "display_frequency", PY_UINT32, offsetof(DEVICEMODE, displayfrequency) },
- { "icm_method", PY_UINT32, offsetof(DEVICEMODE, icmmethod) },
- { "icm_intent", PY_UINT32, offsetof(DEVICEMODE, icmintent) },
- { "media_type", PY_UINT32, offsetof(DEVICEMODE, mediatype) },
- { "dither_type", PY_UINT32, offsetof(DEVICEMODE, dithertype) },
- { "reserved1", PY_UINT32, offsetof(DEVICEMODE, reserved1) },
- { "reserved2", PY_UINT32, offsetof(DEVICEMODE, reserved2) },
- { "panning_width", PY_UINT32, offsetof(DEVICEMODE, panningwidth) },
- { "panning_height", PY_UINT32, offsetof(DEVICEMODE, panningheight) },
- { NULL }
-};
-
-/*
- * Convert between DEVICEMODE and Python
- */
-
-BOOL py_from_DEVICEMODE(PyObject **dict, DEVICEMODE *devmode)
-{
- *dict = from_struct(devmode, py_DEVICEMODE);
-
- PyDict_SetItemString(*dict, "private",
- PyString_FromStringAndSize(
- devmode->private, devmode->driverextra));
-
- return True;
-}
-
-BOOL py_to_DEVICEMODE(DEVICEMODE *devmode, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "private")))
- goto done;
-
- if (!PyString_Check(obj))
- goto done;
-
- devmode->private = PyString_AsString(obj);
- devmode->driverextra = PyString_Size(obj);
-
- PyDict_DelItemString(dict_copy, "private");
-
- if (!to_struct(devmode, dict_copy, py_DEVICEMODE))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-/*
- * Convert between PRINTER_INFO_0 and Python
- */
-
-BOOL py_from_PRINTER_INFO_0(PyObject **dict, PRINTER_INFO_0 *info)
-{
- *dict = from_struct(info, py_PRINTER_INFO_0);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(0));
- return True;
-}
-
-BOOL py_to_PRINTER_INFO_0(PRINTER_INFO_0 *info, PyObject *dict)
-{
- return False;
-}
-
-/*
- * Convert between PRINTER_INFO_1 and Python
- */
-
-BOOL py_from_PRINTER_INFO_1(PyObject **dict, PRINTER_INFO_1 *info)
-{
- *dict = from_struct(info, py_PRINTER_INFO_1);
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(1));
- return True;
-}
-
-BOOL py_to_PRINTER_INFO_1(PRINTER_INFO_1 *info, PyObject *dict)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- if (!to_struct(info, dict_copy, py_PRINTER_INFO_1))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-/*
- * Convert between PRINTER_INFO_2 and Python
- */
-
-BOOL py_from_PRINTER_INFO_2(PyObject **dict, PRINTER_INFO_2 *info)
-{
- PyObject *obj;
-
- *dict = from_struct(info, py_PRINTER_INFO_2);
-
- /* The security descriptor could be NULL */
-
- if (info->secdesc) {
- if (py_from_SECDESC(&obj, info->secdesc))
- PyDict_SetItemString(*dict, "security_descriptor", obj);
- }
-
- /* Bong! The devmode could be NULL */
-
- if (info->devmode)
- py_from_DEVICEMODE(&obj, info->devmode);
- else
- obj = PyDict_New();
-
- PyDict_SetItemString(*dict, "device_mode", obj);
-
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(2));
-
- return True;
-}
-
-BOOL py_to_PRINTER_INFO_2(PRINTER_INFO_2 *info, PyObject *dict,
- TALLOC_CTX *mem_ctx)
-{
- PyObject *obj, *dict_copy = PyDict_Copy(dict);
- BOOL result = False;
-
- /* Convert security descriptor - may be NULL */
-
- info->secdesc = NULL;
-
- if ((obj = PyDict_GetItemString(dict_copy, "security_descriptor"))) {
-
- if (!PyDict_Check(obj))
- goto done;
-
- if (!py_to_SECDESC(&info->secdesc, obj, mem_ctx))
- goto done;
-
- PyDict_DelItemString(dict_copy, "security_descriptor");
- }
-
- /* Convert device mode */
-
- if (!(obj = PyDict_GetItemString(dict_copy, "device_mode"))
- || !PyDict_Check(obj))
- goto done;
-
- info->devmode = talloc(mem_ctx, sizeof(DEVICEMODE));
-
- if (!py_to_DEVICEMODE(info->devmode, obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "device_mode");
-
- /* Check info level */
-
- if (!(obj = PyDict_GetItemString(dict_copy, "level")) ||
- !PyInt_Check(obj))
- goto done;
-
- PyDict_DelItemString(dict_copy, "level");
-
- /* Convert remaining elements of dictionary */
-
- if (!to_struct(info, dict_copy, py_PRINTER_INFO_2))
- goto done;
-
- result = True;
-
-done:
- Py_DECREF(dict_copy);
- return result;
-}
-
-/*
- * Convert between PRINTER_INFO_1 and Python
- */
-
-BOOL py_from_PRINTER_INFO_3(PyObject **dict, PRINTER_INFO_3 *info)
-{
- PyObject *obj;
-
- *dict = from_struct(info, py_PRINTER_INFO_3);
-
- if (py_from_SECDESC(&obj, info->secdesc))
- PyDict_SetItemString(*dict, "security_descriptor", obj);
-
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(3));
-
- return True;
-}
-
-BOOL py_to_PRINTER_INFO_3(PRINTER_INFO_3 *info, PyObject *dict,
- TALLOC_CTX *mem_ctx)
-{
- PyObject *obj;
-
- if (!to_struct(info, dict, py_PRINTER_INFO_3))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "security_descriptor")))
- return False;
-
- if (!py_to_SECDESC(&info->secdesc, obj, mem_ctx))
- return False;
-
- return True;
-}
diff --git a/source/python/py_srvsvc.c b/source/python/py_srvsvc.c
deleted file mode 100644
index 3e5a42be234..00000000000
--- a/source/python/py_srvsvc.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_srvsvc.h"
-
-/* Exceptions this module can raise */
-
-PyObject *srvsvc_error, *srvsvc_werror;
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
- { "SV_TYPE_WORKSTATION", SV_TYPE_WORKSTATION },
- { "SV_TYPE_SERVER", SV_TYPE_SERVER },
- { "SV_TYPE_SQLSERVER", SV_TYPE_SQLSERVER },
- { "SV_TYPE_DOMAIN_CTRL", SV_TYPE_DOMAIN_CTRL },
- { "SV_TYPE_DOMAIN_BAKCTRL", SV_TYPE_DOMAIN_BAKCTRL },
- { "SV_TYPE_TIME_SOURCE", SV_TYPE_TIME_SOURCE },
- { "SV_TYPE_AFP", SV_TYPE_AFP },
- { "SV_TYPE_NOVELL", SV_TYPE_NOVELL },
- { "SV_TYPE_DOMAIN_MEMBER", SV_TYPE_DOMAIN_MEMBER },
- { "SV_TYPE_PRINTQ_SERVER", SV_TYPE_PRINTQ_SERVER },
- { "SV_TYPE_DIALIN_SERVER", SV_TYPE_DIALIN_SERVER },
- { "SV_TYPE_SERVER_UNIX", SV_TYPE_SERVER_UNIX },
- { "SV_TYPE_NT", SV_TYPE_NT },
- { "SV_TYPE_WFW", SV_TYPE_WFW },
- { "SV_TYPE_SERVER_MFPN", SV_TYPE_SERVER_MFPN },
- { "SV_TYPE_SERVER_NT", SV_TYPE_SERVER_NT },
- { "SV_TYPE_POTENTIAL_BROWSER", SV_TYPE_POTENTIAL_BROWSER },
- { "SV_TYPE_BACKUP_BROWSER", SV_TYPE_BACKUP_BROWSER },
- { "SV_TYPE_MASTER_BROWSER", SV_TYPE_MASTER_BROWSER },
- { "SV_TYPE_DOMAIN_MASTER", SV_TYPE_DOMAIN_MASTER },
- { "SV_TYPE_SERVER_OSF", SV_TYPE_SERVER_OSF },
- { "SV_TYPE_SERVER_VMS", SV_TYPE_SERVER_VMS },
- { "SV_TYPE_WIN95_PLUS", SV_TYPE_WIN95_PLUS },
- { "SV_TYPE_DFS_SERVER", SV_TYPE_DFS_SERVER },
- { "SV_TYPE_ALTERNATE_XPORT", SV_TYPE_ALTERNATE_XPORT },
- { "SV_TYPE_LOCAL_LIST_ONLY", SV_TYPE_LOCAL_LIST_ONLY },
- { "SV_TYPE_DOMAIN_ENUM", SV_TYPE_DOMAIN_ENUM },
- { NULL },
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/* NetServerGetInfo */
-
-PyObject *srvsvc_netservergetinfo(PyObject *self, PyObject *args,
- PyObject *kw)
-{
- static char *kwlist[] = { "server", "level", "creds", NULL };
- char *unc_name, *server, *errstr;
- PyObject *creds = NULL, *result = NULL;
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx = NULL;
- uint32 level;
- SRV_INFO_CTR ctr;
- WERROR status;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "si|O", kwlist, &unc_name, &level, &creds))
- return NULL;
-
- if (unc_name[0] != '\\' || unc_name[1] != '\\') {
- PyErr_SetString(PyExc_ValueError, "UNC name required");
- return NULL;
- }
-
- server = strdup(unc_name + 2);
-
- if (strchr(server, '\\')) {
- char *c = strchr(server, '\\');
- *c = 0;
- }
-
- if (creds && creds != Py_None && !PyDict_Check(creds)) {
- PyErr_SetString(PyExc_TypeError,
- "credentials must be dictionary or None");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PI_SRVSVC, &errstr))) {
- PyErr_SetString(srvsvc_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init("srvsvc_netservergetinfo"))) {
- PyErr_SetString(srvsvc_error,
- "unable to init talloc context\n");
- goto done;
- }
-
- ZERO_STRUCT(ctr);
-
- status = cli_srvsvc_net_srv_get_info(cli, mem_ctx, level, &ctr);
-
- if (!NT_STATUS_IS_OK(status)) {
- PyErr_SetObject(srvsvc_error, py_werror_tuple(status));
- goto done;
- }
-
- if (level != ctr.switch_value) {
- PyErr_SetString(srvsvc_error, "container level value wrong");
- goto done;
- }
-
- switch(level) {
- case 101:
- py_from_SRV_INFO_101(&result, &ctr.srv.sv101);
- break;
- }
-
- Py_INCREF(result);
-
-done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/*
- * Module initialisation
- */
-
-static PyMethodDef srvsvc_methods[] = {
- { "netservergetinfo", (PyCFunction)srvsvc_netservergetinfo,
- METH_VARARGS | METH_KEYWORDS,
- "Retrieve information about a particular server." },
-
- { "setup_logging", (PyCFunction)py_setup_logging,
- METH_VARARGS | METH_KEYWORDS,
- "Set up debug logging.\n"
-"\n"
-"Initialises Samba's debug logging system. One argument is expected which\n"
-"is a boolean specifying whether debugging is interactive and sent to stdout\n"
-"or logged to a file.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> srvsvc.setup_logging(interactive = 1)" },
-
- { "get_debuglevel", (PyCFunction)get_debuglevel,
- METH_VARARGS,
- "Set the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> srvsvc.get_debuglevel()\n"
-"0" },
-
- { "set_debuglevel", (PyCFunction)set_debuglevel,
- METH_VARARGS,
- "Get the current debug level.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> srvsvc.set_debuglevel(10)" },
-
- { NULL }
-};
-
-void initsrvsvc(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("srvsvc", srvsvc_methods);
- dict = PyModule_GetDict(module);
-
- /* Exceptions we can raise */
-
- srvsvc_error = PyErr_NewException("srvsvc.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", srvsvc_error);
-
- srvsvc_werror = PyErr_NewException("srvsvc.werror", NULL, NULL);
- PyDict_SetItemString(dict, "werror", srvsvc_werror);
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Do samba initialisation */
-
- py_samba_init();
-}
diff --git a/source/python/py_srvsvc.h b/source/python/py_srvsvc.h
deleted file mode 100644
index c5e71cb90f5..00000000000
--- a/source/python/py_srvsvc.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_SRVSVC_H
-#define _PY_SRVSVC_H
-
-#include "python/py_common.h"
-
-/* The following definitions come from python/py_srvsv.c */
-
-BOOL py_from_SRV_INFO_101(PyObject **dict, SRV_INFO_101 *info);
-
-#endif /* _PY_SRVSVC_H */
diff --git a/source/python/py_srvsvc_conv.c b/source/python/py_srvsvc_conv.c
deleted file mode 100644
index 86c3761d0f4..00000000000
--- a/source/python/py_srvsvc_conv.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_srvsvc.h"
-#include "python/py_conv.h"
-
-static struct pyconv py_SRV_INFO_101[] = {
- { "platform_id", PY_UINT32, offsetof(SRV_INFO_101, platform_id) },
- { "major_version", PY_UINT32, offsetof(SRV_INFO_101, ver_major) },
- { "minor_version", PY_UINT32, offsetof(SRV_INFO_101, ver_minor) },
- { "server_type", PY_UINT32, offsetof(SRV_INFO_101, srv_type) },
- { "name", PY_UNISTR2, offsetof(SRV_INFO_101, uni_name) },
- { "comment", PY_UNISTR2, offsetof(SRV_INFO_101, uni_comment) },
- { NULL }
-};
-
-BOOL py_from_SRV_INFO_101(PyObject **dict, SRV_INFO_101 *info)
-{
- *dict = from_struct(info, py_SRV_INFO_101);
-
- PyDict_SetItemString(*dict, "level", PyInt_FromLong(101));
-
- return True;
-}
diff --git a/source/python/py_tdb.c b/source/python/py_tdb.c
deleted file mode 100644
index 6796469759b..00000000000
--- a/source/python/py_tdb.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- Python wrappers for TDB module
-
- Copyright (C) Tim Potter, 2002-2003
-
- ** NOTE! The following LGPL license applies to the tdb python
- ** scripting library. This does NOT imply that all of Samba is
- ** released under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "includes.h"
-
-/* This symbol is used in both includes.h and Python.h which causes an
- annoying compiler warning. */
-
-#ifdef HAVE_FSTAT
-#undef HAVE_FSTAT
-#endif
-
-#include "Python.h"
-
-/* Tdb exception */
-
-PyObject *py_tdb_error;
-
-/* tdb handle object */
-
-typedef struct {
- PyObject_HEAD
- TDB_CONTEXT *tdb;
-} tdb_hnd_object;
-
-PyTypeObject tdb_hnd_type;
-
-PyObject *new_tdb_hnd_object(TDB_CONTEXT *tdb)
-{
- tdb_hnd_object *obj;
-
- obj = PyObject_New(tdb_hnd_object, &tdb_hnd_type);
- obj->tdb = tdb;
-
- return (PyObject *)obj;
-}
-
-PyObject *py_tdb_close(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj;
-
- if (!PyArg_ParseTuple(args, "O!", &tdb_hnd_type, &obj))
- return NULL;
-
- if (tdb_close(obj->tdb) == -1) {
- obj->tdb = NULL;
- PyErr_SetString(py_tdb_error, strerror(errno));
- return NULL;
- }
-
- obj->tdb = NULL;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject *py_tdb_open(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] = { "name", "hash_size", "tdb_flags",
- "open_flags", "mode", NULL };
- char *name;
- int hash_size = 0, flags = TDB_DEFAULT, open_flags = -1, open_mode = 0600;
- TDB_CONTEXT *tdb;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|iiii", kwlist, &name, &hash_size, &flags,
- &open_flags, &open_mode))
- return NULL;
-
- /* Default open_flags to read/write */
-
- if (open_flags == -1) {
- if (access(name, W_OK) == -1)
- open_flags = O_RDONLY;
- else
- open_flags = O_RDWR;
- }
-
- if (!(tdb = tdb_open(name, hash_size, flags, open_flags, open_mode))) {
- PyErr_SetString(py_tdb_error, strerror(errno));
- return NULL;
- }
-
- return new_tdb_hnd_object(tdb);
-}
-
-/*
- * Allow a tdb to act as a python mapping (dictionary)
- */
-
-static int tdb_traverse_count(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
- void *state)
-{
- /* Do nothing - tdb_traverse will return the number of records
- traversed. */
-
- return 0;
-}
-
-static int tdb_hnd_length(tdb_hnd_object *obj)
-{
- int result;
-
- result = tdb_traverse(obj->tdb, tdb_traverse_count, NULL);
-
- return result;
-}
-
-static PyObject *tdb_hnd_subscript(tdb_hnd_object *obj, PyObject *key)
-{
- TDB_DATA drec, krec;
- PyObject *result;
-
- if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize))
- return NULL;
-
- drec = tdb_fetch(obj->tdb, krec);
-
- if (!drec.dptr) {
- PyErr_SetString(PyExc_KeyError,
- PyString_AsString(key));
- return NULL;
- }
-
- result = PyString_FromStringAndSize(drec.dptr, drec.dsize);
- free(drec.dptr);
-
- return result;
-}
-
-static int tdb_ass_subscript(tdb_hnd_object *obj, PyObject *key, PyObject *value)
-{
- TDB_DATA krec, drec;
-
- if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize)) {
- PyErr_SetString(PyExc_TypeError,
- "tdb mappings have string indices only");
- return -1;
- }
-
- if (!obj->tdb) {
- PyErr_SetString(
- py_tdb_error, "tdb object has been closed");
- return -1;
- }
-
- if (!value) {
-
- /* Delete value */
-
- if (tdb_delete(obj->tdb, krec) == -1) {
- PyErr_SetString(PyExc_KeyError,
- PyString_AsString(value));
- return -1;
- }
-
- } else {
-
- /* Set value */
-
- if (!PyArg_Parse(value, "s#", &drec.dptr, &drec.dsize)) {
- PyErr_SetString(PyExc_TypeError,
- "tdb mappings have string elements only");
- return -1;
- }
-
- errno = 0;
-
- if (tdb_store(obj->tdb, krec, drec, 0) < 0 ) {
- if (errno != 0)
- PyErr_SetFromErrno(py_tdb_error);
- else
- PyErr_SetString(
- py_tdb_error,
- (char *)tdb_errorstr(obj->tdb));
-
- return -1;
- }
- }
-
- return 0;
-}
-
-static PyMappingMethods tdb_mapping = {
- (inquiry) tdb_hnd_length,
- (binaryfunc) tdb_hnd_subscript,
- (objobjargproc) tdb_ass_subscript
-};
-
-/*
- * Utility methods
- */
-
-/* Return non-zero if a given key exists in the tdb */
-
-PyObject *py_tdb_hnd_has_key(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- TDB_DATA key;
-
- if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
- return NULL;
-
- if (!obj->tdb) {
- PyErr_SetString(
- py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- return PyInt_FromLong(tdb_exists(obj->tdb, key));
-}
-
-/* Return a list of keys in the tdb */
-
-static int tdb_traverse_keys(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
- void *state)
-{
- PyObject *key_list = (PyObject *)state;
-
- PyList_Append(key_list,
- PyString_FromStringAndSize(key.dptr, key.dsize));
-
- return 0;
-}
-
-PyObject *py_tdb_hnd_keys(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- PyObject *key_list = PyList_New(0);
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (tdb_traverse(obj->tdb, tdb_traverse_keys, key_list) == -1) {
- PyErr_SetString(py_tdb_error, "error traversing tdb");
- Py_DECREF(key_list);
- return NULL;
- }
-
- return key_list;
-}
-
-PyObject *py_tdb_hnd_first_key(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- TDB_DATA key;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- key = tdb_firstkey(obj->tdb);
-
- return Py_BuildValue("s#", key.dptr, key.dsize);
-}
-
-PyObject *py_tdb_hnd_next_key(PyObject *self, PyObject *py_oldkey)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- TDB_DATA key, oldkey;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_Parse(py_oldkey, "s#", &oldkey.dptr, &oldkey.dsize))
- return NULL;
-
- key = tdb_nextkey(obj->tdb, oldkey);
-
- return Py_BuildValue("s#", key.dptr, key.dsize);
-}
-
-/*
- * Locking routines
- */
-
-PyObject *py_tdb_hnd_lock_all(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- int result;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- result = tdb_lockall(obj->tdb);
-
- return PyInt_FromLong(result != -1);
-}
-
-PyObject *py_tdb_hnd_unlock_all(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- tdb_unlockall(obj->tdb);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* Return an array of keys from a python object which must be a string or a
- list of strings. */
-
-static BOOL make_lock_list(PyObject *py_keys, TDB_DATA **keys, int *num_keys)
-{
- /* Are we a list or a string? */
-
- if (!PyList_Check(py_keys) && !PyString_Check(py_keys)) {
- PyErr_SetString(PyExc_TypeError, "arg must be list of string");
- return False;
- }
-
- if (PyList_Check(py_keys)) {
- int i;
-
- /* Turn python list into array of keys */
-
- *num_keys = PyList_Size(py_keys);
- *keys = (TDB_DATA *)malloc(sizeof(TDB_DATA) * (*num_keys));
-
- for (i = 0; i < *num_keys; i++) {
- PyObject *key = PyList_GetItem(py_keys, i);
-
- if (!PyString_Check(key)) {
- PyErr_SetString(
- PyExc_TypeError,
- "list elements must be strings");
- return False;
- }
-
- PyArg_Parse(key, "s#", &(*keys)[i].dptr,
- &(*keys)[i].dsize);
- }
-
- } else {
-
- /* Turn python string into a single key */
-
- *keys = (TDB_DATA *)malloc(sizeof(TDB_DATA));
- *num_keys = 1;
- PyArg_Parse(py_keys, "s#", &(*keys)->dptr, &(*keys)->dsize);
- }
-
- return True;
-}
-
-PyObject *py_tdb_hnd_lock(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- PyObject *py_keys;
- TDB_DATA *keys;
- int num_keys, result;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "O", &py_keys))
- return NULL;
-
- if (!make_lock_list(py_keys, &keys, &num_keys))
- return NULL;
-
- result = tdb_lockkeys(obj->tdb, num_keys, keys);
-
- free(keys);
-
- return PyInt_FromLong(result != -1);
-}
-
-PyObject *py_tdb_hnd_unlock(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- tdb_unlockkeys(obj->tdb);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
- * tdb traversal
- */
-
-struct traverse_info {
- PyObject *callback;
- PyObject *state;
-};
-
-static int tdb_traverse_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
- void *state)
-{
- struct traverse_info *info = state;
- PyObject *arglist, *py_result;
- int result;
-
- arglist = Py_BuildValue("(s#s#O)", key.dptr, key.dsize, value.dptr,
- value.dsize, info->state);
-
- py_result = PyEval_CallObject(info->callback, arglist);
-
- Py_DECREF(arglist);
-
- if (!PyInt_Check(py_result)) {
- result = 1; /* Hmm - non-integer object returned by callback */
- goto done;
- }
-
- result = PyInt_AsLong(py_result);
-
-done:
- Py_DECREF(py_result);
- return result;
-}
-
-PyObject *py_tdb_hnd_traverse(PyObject *self, PyObject *args, PyObject *kw)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- static char *kwlist[] = { "traverse_fn", "state", NULL };
- PyObject *state = Py_None, *callback;
- struct traverse_info info;
- int result;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O|O", kwlist, &callback, &state))
- return NULL;
-
- if (!PyCallable_Check(callback)) {
- PyErr_SetString(PyExc_TypeError, "parameter must be callable");
- return NULL;
- }
-
- Py_INCREF(callback);
- Py_INCREF(state);
-
- info.callback = callback;
- info.state = state;
-
- result = tdb_traverse(obj->tdb, tdb_traverse_traverse, &info);
-
- Py_DECREF(callback);
- Py_DECREF(state);
-
- return PyInt_FromLong(result);
-}
-
-PyObject *py_tdb_hnd_chainlock(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- TDB_DATA key;
- int result;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
- return NULL;
-
- result = tdb_chainlock(obj->tdb, key);
-
- return PyInt_FromLong(result != -1);
-}
-
-PyObject *py_tdb_hnd_chainunlock(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- TDB_DATA key;
- int result;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
- return NULL;
-
- result = tdb_chainunlock(obj->tdb, key);
-
- return PyInt_FromLong(result != -1);
-}
-
-PyObject *py_tdb_hnd_lock_bystring(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- int result, timeout = 30;
- char *s;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "s|i", &s, &timeout))
- return NULL;
-
- result = tdb_lock_bystring(obj->tdb, s, timeout);
-
- return PyInt_FromLong(result != -1);
-}
-
-PyObject *py_tdb_hnd_unlock_bystring(PyObject *self, PyObject *args)
-{
- tdb_hnd_object *obj = (tdb_hnd_object *)self;
- char *s;
-
- if (!obj->tdb) {
- PyErr_SetString(py_tdb_error, "tdb object has been closed");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "s", &s))
- return NULL;
-
- tdb_unlock_bystring(obj->tdb, s);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
- * Method dispatch table for this module
- */
-
-static PyMethodDef tdb_methods[] = {
- { "open", (PyCFunction)py_tdb_open, METH_VARARGS | METH_KEYWORDS },
- { "close", (PyCFunction)py_tdb_close, METH_VARARGS },
- { NULL }
-};
-
-/*
- * Methods on a tdb object
- */
-
-static PyMethodDef tdb_hnd_methods[] = {
- { "keys", (PyCFunction)py_tdb_hnd_keys, METH_VARARGS },
- { "has_key", (PyCFunction)py_tdb_hnd_has_key, METH_VARARGS },
- { "first_key", (PyCFunction)py_tdb_hnd_first_key, METH_VARARGS },
- { "next_key", (PyCFunction)py_tdb_hnd_next_key, METH_VARARGS },
- { "lock_all", (PyCFunction)py_tdb_hnd_lock_all, METH_VARARGS },
- { "unlock_all", (PyCFunction)py_tdb_hnd_unlock_all, METH_VARARGS },
- { "lock", (PyCFunction)py_tdb_hnd_lock, METH_VARARGS },
- { "unlock", (PyCFunction)py_tdb_hnd_unlock, METH_VARARGS },
- { "traverse", (PyCFunction)py_tdb_hnd_traverse, METH_VARARGS | METH_KEYWORDS },
- { "chainlock", (PyCFunction)py_tdb_hnd_chainlock, METH_VARARGS | METH_KEYWORDS },
- { "chainunlock", (PyCFunction)py_tdb_hnd_chainunlock, METH_VARARGS | METH_KEYWORDS },
- { "lock_bystring", (PyCFunction)py_tdb_hnd_lock_bystring, METH_VARARGS | METH_KEYWORDS },
- { "unlock_bystring", (PyCFunction)py_tdb_hnd_unlock_bystring, METH_VARARGS | METH_KEYWORDS },
- { NULL }
-};
-
-/* Deallocate a tdb handle object */
-
-static void tdb_hnd_dealloc(PyObject* self)
-{
- tdb_hnd_object *hnd = (tdb_hnd_object *)self;
-
- if (hnd->tdb) {
- tdb_close(hnd->tdb);
- hnd->tdb = NULL;
- }
-}
-
-/* Return tdb handle attributes */
-
-static PyObject *tdb_hnd_getattr(PyObject *self, char *attrname)
-{
- return Py_FindMethod(tdb_hnd_methods, self, attrname);
-}
-
-static char tdb_hnd_type_doc[] =
-"Python wrapper for tdb.";
-
-PyTypeObject tdb_hnd_type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "tdb",
- sizeof(tdb_hnd_object),
- 0,
- tdb_hnd_dealloc, /* tp_dealloc*/
- 0, /* tp_print*/
- tdb_hnd_getattr, /* tp_getattr*/
- 0, /* tp_setattr*/
- 0, /* tp_compare*/
- 0, /* tp_repr*/
- 0, /* tp_as_number*/
- 0, /* tp_as_sequence*/
- &tdb_mapping, /* tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- tdb_hnd_type_doc, /* tp_doc */
-};
-
-/* Constants */
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
-
- /* Flags for tdb_open() */
-
- { "TDB_DEFAULT", TDB_DEFAULT },
- { "TDB_CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST },
- { "TDB_INTERNAL", TDB_INTERNAL },
- { "TDB_NOLOCK", TDB_NOLOCK },
- { "TDB_NOMMAP", TDB_NOMMAP },
- { "TDB_CONVERT", TDB_CONVERT },
- { "TDB_BIGENDIAN", TDB_BIGENDIAN },
-
- { NULL },
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/* Module initialisation */
-
-void inittdb(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("tdb", tdb_methods);
- dict = PyModule_GetDict(module);
-
- py_tdb_error = PyErr_NewException("tdb.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", py_tdb_error);
-
- /* Initialise policy handle object */
-
- tdb_hnd_type.ob_type = &PyType_Type;
-
- PyDict_SetItemString(dict, "tdb.hnd",
- (PyObject *)&tdb_hnd_type);
-
- /* Initialise constants */
-
- const_init(dict);
-}
diff --git a/source/python/py_tdb.h b/source/python/py_tdb.h
deleted file mode 100644
index 5134d2ff968..00000000000
--- a/source/python/py_tdb.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- ** NOTE! The following LGPL license applies to the tdb python
- ** scripting library. This does NOT imply that all of Samba is
- ** released under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef _PY_TDB_H
-#define _PY_TDB_H
-
-#include "python/py_common.h"
-
-#endif /* _PY_TDB_H */
diff --git a/source/python/py_tdbpack.c b/source/python/py_tdbpack.c
deleted file mode 100644
index 4fa97af8a3c..00000000000
--- a/source/python/py_tdbpack.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/* -*- c-file-style: "python"; indent-tabs-mode: nil; -*-
-
- Python wrapper for Samba tdb pack/unpack functions
- Copyright (C) Martin Pool 2002, 2003
-
-
- NOTE PYTHON STYLE GUIDE
- http://www.python.org/peps/pep-0007.html
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "Python.h"
-
-/* This symbol is used in both config.h and Python.h which causes an
- annoying compiler warning. */
-
-#ifdef HAVE_FSTAT
-#undef HAVE_FSTAT
-#endif
-
-/* This module is supposed to be standalone, however for portability
- it would be good to use the FUNCTION_MACRO preprocessor define. */
-
-#include "include/config.h"
-
-#ifdef HAVE_FUNCTION_MACRO
-#define FUNCTION_MACRO (__FUNCTION__)
-#else
-#define FUNCTION_MACRO (__FILE__)
-#endif
-
-static PyObject * pytdbpack_number(char ch, PyObject *val_iter, PyObject *packed_list);
-static PyObject * pytdbpack_str(char ch,
- PyObject *val_iter, PyObject *packed_list,
- const char *encoding);
-static PyObject * pytdbpack_buffer(PyObject *val_iter, PyObject *packed_list);
-
-static PyObject *pytdbunpack_item(char, char **pbuf, int *plen, PyObject *);
-
-static PyObject *pytdbpack_data(const char *format_str,
- PyObject *val_seq,
- PyObject *val_list);
-
-static PyObject *
-pytdbunpack_string(char **pbuf, int *plen, const char *encoding);
-
-static void pack_le_uint32(unsigned long val_long, unsigned char *pbuf);
-
-
-static PyObject *pytdbpack_bad_type(char ch,
- const char *expected,
- PyObject *val_obj);
-
-static const char * pytdbpack_docstring =
-"Convert between Python values and Samba binary encodings.\n"
-"\n"
-"This module is conceptually similar to the standard 'struct' module, but it\n"
-"uses both a different binary format and a different description string.\n"
-"\n"
-"Samba's encoding is based on that used inside DCE-RPC and SMB: a\n"
-"little-endian, unpadded, non-self-describing binary format. It is intended\n"
-"that these functions be as similar as possible to the routines in Samba's\n"
-"tdb/tdbutil module, with appropriate adjustments for Python datatypes.\n"
-"\n"
-"Python strings are used to specify the format of data to be packed or\n"
-"unpacked.\n"
-"\n"
-"String encodings are implied by the database format: they may be either DOS\n"
-"codepage (currently hardcoded to 850), or Unix codepage (currently hardcoded\n"
-"to be the same as the default Python encoding).\n"
-"\n"
-"tdbpack format strings:\n"
-"\n"
-" 'f': NUL-terminated string in codepage iso8859-1\n"
-" \n"
-" 'P': same as 'f'\n"
-"\n"
-" 'F': NUL-terminated string in iso-8859-1\n"
-"\n"
-" 'd': 4 byte little-endian unsigned number\n"
-"\n"
-" 'w': 2 byte little-endian unsigned number\n"
-"\n"
-" 'P': \"Pointer\" value -- in the subset of DCERPC used by Samba, this is\n"
-" really just an \"exists\" or \"does not exist\" flag. The boolean\n"
-" value of the Python object is used.\n"
-" \n"
-" 'B': 4-byte LE length, followed by that many bytes of binary data.\n"
-" Corresponds to a Python integer giving the length, followed by a byte\n"
-" string of the appropriate length.\n"
-"\n"
-" '$': Special flag indicating that the preceding format code should be\n"
-" repeated while data remains. This is only supported for unpacking.\n"
-"\n"
-" Every code corresponds to a single Python object, except 'B' which\n"
-" corresponds to two values (length and contents), and '$', which produces\n"
-" however many make sense.\n";
-
-static char const pytdbpack_doc[] =
-"pack(format, values) -> buffer\n"
-"Pack Python objects into Samba binary format according to format string.\n"
-"\n"
-"arguments:\n"
-" format -- string of tdbpack format characters\n"
-" values -- sequence of value objects corresponding 1:1 to format characters\n"
-"\n"
-"returns:\n"
-" buffer -- string containing packed data\n"
-"\n"
-"raises:\n"
-" IndexError -- if there are too few values for the format\n"
-" ValueError -- if any of the format characters is illegal\n"
-" TypeError -- if the format is not a string, or values is not a sequence,\n"
-" or any of the values is of the wrong type for the corresponding\n"
-" format character\n"
-"\n"
-"notes:\n"
-" For historical reasons, it is not an error to pass more values than are consumed\n"
-" by the format.\n";
-
-
-static char const pytdbunpack_doc[] =
-"unpack(format, buffer) -> (values, rest)\n"
-"Unpack Samba binary data according to format string.\n"
-"\n"
-"arguments:\n"
-" format -- string of tdbpack characters\n"
-" buffer -- string of packed binary data\n"
-"\n"
-"returns:\n"
-" 2-tuple of:\n"
-" values -- sequence of values corresponding 1:1 to format characters\n"
-" rest -- string containing data that was not decoded, or '' if the\n"
-" whole string was consumed\n"
-"\n"
-"raises:\n"
-" IndexError -- if there is insufficient data in the buffer for the\n"
-" format (or if the data is corrupt and contains a variable-length\n"
-" field extending past the end)\n"
-" ValueError -- if any of the format characters is illegal\n"
-"\n"
-"notes:\n"
-" Because unconsumed data is returned, you can feed it back in to the\n"
-" unpacker to extract further fields. Alternatively, if you wish to modify\n"
-" some fields near the start of the data, you may be able to save time by\n"
-" only unpacking and repacking the necessary part.\n";
-
-
-const char *pytdb_dos_encoding = "cp850";
-
-/* NULL, meaning that the Samba default encoding *must* be the same as the
- Python default encoding. */
-const char *pytdb_unix_encoding = NULL;
-
-
-/*
- * Pack objects to bytes.
- *
- * All objects are first individually encoded onto a list, and then the list
- * of strings is concatenated. This is faster than concatenating strings,
- * and reasonably simple to code.
- */
-static PyObject *
-pytdbpack(PyObject *self,
- PyObject *args)
-{
- char *format_str;
- PyObject *val_seq, *val_iter = NULL,
- *packed_list = NULL, *packed_str = NULL,
- *empty_str = NULL;
-
- /* TODO: Test passing wrong types or too many arguments */
- if (!PyArg_ParseTuple(args, "sO", &format_str, &val_seq))
- return NULL;
-
- if (!(val_iter = PyObject_GetIter(val_seq)))
- goto out;
-
- /* Create list to hold strings until we're done, then join them all. */
- if (!(packed_list = PyList_New(0)))
- goto out;
-
- if (!pytdbpack_data(format_str, val_iter, packed_list))
- goto out;
-
- /* this function is not officially documented but it works */
- if (!(empty_str = PyString_InternFromString("")))
- goto out;
-
- packed_str = _PyString_Join(empty_str, packed_list);
-
- out:
- Py_XDECREF(empty_str);
- Py_XDECREF(val_iter);
- Py_XDECREF(packed_list);
-
- return packed_str;
-}
-
-
-/*
- Pack data according to FORMAT_STR from the elements of VAL_SEQ into
- PACKED_BUF.
-
- The string has already been checked out, so we know that VAL_SEQ is large
- enough to hold the packed data, and that there are enough value items.
- (However, their types may not have been thoroughly checked yet.)
-
- In addition, val_seq is a Python Fast sequence.
-
- Returns NULL for error (with exception set), or None.
-*/
-PyObject *
-pytdbpack_data(const char *format_str,
- PyObject *val_iter,
- PyObject *packed_list)
-{
- int format_i, val_i = 0;
-
- for (format_i = 0, val_i = 0; format_str[format_i]; format_i++) {
- char ch = format_str[format_i];
-
- switch (ch) {
- /* dispatch to the appropriate packer for this type,
- which should pull things off the iterator, and
- append them to the packed_list */
- case 'w':
- case 'd':
- case 'p':
- if (!(packed_list = pytdbpack_number(ch, val_iter, packed_list)))
- return NULL;
- break;
-
- case 'f':
- case 'P':
- if (!(packed_list = pytdbpack_str(ch, val_iter, packed_list, pytdb_unix_encoding)))
- return NULL;
- break;
-
- case 'B':
- if (!(packed_list = pytdbpack_buffer(val_iter, packed_list)))
- return NULL;
- break;
-
- default:
- PyErr_Format(PyExc_ValueError,
- "%s: format character '%c' is not supported",
- FUNCTION_MACRO, ch);
- return NULL;
- }
- }
-
- return packed_list;
-}
-
-
-static PyObject *
-pytdbpack_number(char ch, PyObject *val_iter, PyObject *packed_list)
-{
- unsigned long val_long;
- PyObject *val_obj = NULL, *long_obj = NULL, *result_obj = NULL;
- PyObject *new_list = NULL;
- unsigned char pack_buf[4];
-
- if (!(val_obj = PyIter_Next(val_iter)))
- goto out;
-
- if (!(long_obj = PyNumber_Long(val_obj))) {
- pytdbpack_bad_type(ch, "Number", val_obj);
- goto out;
- }
-
- val_long = PyLong_AsUnsignedLong(long_obj);
- pack_le_uint32(val_long, pack_buf);
-
- /* pack as 32-bit; if just packing a 'w' 16-bit word then only take
- the first two bytes. */
-
- if (!(result_obj = PyString_FromStringAndSize(pack_buf, ch == 'w' ? 2 : 4)))
- goto out;
-
- if (PyList_Append(packed_list, result_obj) != -1)
- new_list = packed_list;
-
- out:
- Py_XDECREF(val_obj);
- Py_XDECREF(long_obj);
- Py_XDECREF(result_obj);
-
- return new_list;
-}
-
-
-/*
- * Take one string from the iterator val_iter, convert it to 8-bit, and return
- * it.
- *
- * If the input is neither a string nor Unicode, an exception is raised.
- *
- * If the input is Unicode, then it is converted to the appropriate encoding.
- *
- * If the input is a String, and encoding is not null, then it is converted to
- * Unicode using the default decoding method, and then converted to the
- * encoding. If the encoding is NULL, then the string is written out as-is --
- * this is used when the default Python encoding is the same as the Samba
- * encoding.
- *
- * I hope this approach avoids being too fragile w.r.t. being passed either
- * Unicode or String objects.
- */
-static PyObject *
-pytdbpack_str(char ch,
- PyObject *val_iter, PyObject *packed_list, const char *encoding)
-{
- PyObject *val_obj = NULL;
- PyObject *unicode_obj = NULL;
- PyObject *coded_str = NULL;
- PyObject *nul_str = NULL;
- PyObject *new_list = NULL;
-
- if (!(val_obj = PyIter_Next(val_iter)))
- goto out;
-
- if (PyUnicode_Check(val_obj)) {
- if (!(coded_str = PyUnicode_AsEncodedString(val_obj, encoding, NULL)))
- goto out;
- }
- else if (PyString_Check(val_obj) && !encoding) {
- /* For efficiency, we assume that the Python interpreter has
- the same default string encoding as Samba's native string
- encoding. On the PSA, both are always 8859-1. */
- coded_str = val_obj;
- Py_INCREF(coded_str);
- }
- else if (PyString_Check(val_obj)) {
- /* String, but needs to be converted */
- if (!(unicode_obj = PyString_AsDecodedObject(val_obj, NULL, NULL)))
- goto out;
- if (!(coded_str = PyUnicode_AsEncodedString(unicode_obj, encoding, NULL)))
- goto out;
- }
- else {
- pytdbpack_bad_type(ch, "String or Unicode", val_obj);
- goto out;
- }
-
- if (!nul_str)
- /* this is constant and often-used; hold it forever */
- if (!(nul_str = PyString_FromStringAndSize("", 1)))
- goto out;
-
- if ((PyList_Append(packed_list, coded_str) != -1)
- && (PyList_Append(packed_list, nul_str) != -1))
- new_list = packed_list;
-
- out:
- Py_XDECREF(val_obj);
- Py_XDECREF(unicode_obj);
- Py_XDECREF(coded_str);
-
- return new_list;
-}
-
-
-/*
- * Pack (LENGTH, BUFFER) pair onto the list.
- *
- * The buffer must already be a String, not Unicode, because it contains 8-bit
- * untranslated data. In some cases it will actually be UTF_16_LE data.
- */
-static PyObject *
-pytdbpack_buffer(PyObject *val_iter, PyObject *packed_list)
-{
- PyObject *val_obj;
- PyObject *new_list = NULL;
-
- /* pull off integer and stick onto list */
- if (!(packed_list = pytdbpack_number('d', val_iter, packed_list)))
- return NULL;
-
- /* this assumes that the string is the right length; the old code did
- the same. */
- if (!(val_obj = PyIter_Next(val_iter)))
- return NULL;
-
- if (!PyString_Check(val_obj)) {
- pytdbpack_bad_type('B', "String", val_obj);
- goto out;
- }
-
- if (PyList_Append(packed_list, val_obj) != -1)
- new_list = packed_list;
-
- out:
- Py_XDECREF(val_obj);
- return new_list;
-}
-
-
-static PyObject *pytdbpack_bad_type(char ch,
- const char *expected,
- PyObject *val_obj)
-{
- PyObject *r = PyObject_Repr(val_obj);
- if (!r)
- return NULL;
- PyErr_Format(PyExc_TypeError,
- "tdbpack: format '%c' requires %s, not %s",
- ch, expected, PyString_AS_STRING(r));
- Py_DECREF(r);
- return val_obj;
-}
-
-
-/*
- XXX: glib and Samba have quicker macro for doing the endianness conversions,
- but I don't know of one in plain libc, and it's probably not a big deal. I
- realize this is kind of dumb because we'll almost always be on x86, but
- being safe is important.
-*/
-static void pack_le_uint32(unsigned long val_long, unsigned char *pbuf)
-{
- pbuf[0] = val_long & 0xff;
- pbuf[1] = (val_long >> 8) & 0xff;
- pbuf[2] = (val_long >> 16) & 0xff;
- pbuf[3] = (val_long >> 24) & 0xff;
-}
-
-
-static void pack_bytes(long len, const char *from,
- unsigned char **pbuf)
-{
- memcpy(*pbuf, from, len);
- (*pbuf) += len;
-}
-
-
-
-static PyObject *
-pytdbunpack(PyObject *self,
- PyObject *args)
-{
- char *format_str, *packed_str, *ppacked;
- PyObject *val_list = NULL, *ret_tuple = NULL;
- PyObject *rest_string = NULL;
- int format_len, packed_len;
- char last_format = '#'; /* invalid */
- int i;
-
- /* get arguments */
- if (!PyArg_ParseTuple(args, "ss#", &format_str, &packed_str, &packed_len))
- return NULL;
-
- format_len = strlen(format_str);
-
- /* Allocate list to hold results. Initially empty, and we append
- results as we go along. */
- val_list = PyList_New(0);
- if (!val_list)
- goto failed;
- ret_tuple = PyTuple_New(2);
- if (!ret_tuple)
- goto failed;
-
- /* For every object, unpack. */
- for (ppacked = packed_str, i = 0; i < format_len && format_str[i] != '$'; i++) {
- last_format = format_str[i];
- /* packed_len is reduced in place */
- if (!pytdbunpack_item(format_str[i], &ppacked, &packed_len, val_list))
- goto failed;
- }
-
- /* If the last character was '$', keep going until out of space */
- if (format_str[i] == '$') {
- if (i == 0) {
- PyErr_Format(PyExc_ValueError,
- "%s: '$' may not be first character in format",
- FUNCTION_MACRO);
- return NULL;
- }
- while (packed_len > 0)
- if (!pytdbunpack_item(last_format, &ppacked, &packed_len, val_list))
- goto failed;
- }
-
- /* save leftovers for next time */
- rest_string = PyString_FromStringAndSize(ppacked, packed_len);
- if (!rest_string)
- goto failed;
-
- /* return (values, rest) tuple; give up references to them */
- PyTuple_SET_ITEM(ret_tuple, 0, val_list);
- val_list = NULL;
- PyTuple_SET_ITEM(ret_tuple, 1, rest_string);
- val_list = NULL;
- return ret_tuple;
-
- failed:
- /* handle failure: deallocate anything. XDECREF forms handle NULL
- pointers for objects that haven't been allocated yet. */
- Py_XDECREF(val_list);
- Py_XDECREF(ret_tuple);
- Py_XDECREF(rest_string);
- return NULL;
-}
-
-
-static void
-pytdbunpack_err_too_short(void)
-{
- PyErr_Format(PyExc_IndexError,
- "%s: data too short for unpack format", FUNCTION_MACRO);
-}
-
-
-static PyObject *
-pytdbunpack_uint32(char **pbuf, int *plen)
-{
- unsigned long v;
- unsigned char *b;
-
- if (*plen < 4) {
- pytdbunpack_err_too_short();
- return NULL;
- }
-
- b = *pbuf;
- v = b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
-
- (*pbuf) += 4;
- (*plen) -= 4;
-
- return PyLong_FromUnsignedLong(v);
-}
-
-
-static PyObject *pytdbunpack_int16(char **pbuf, int *plen)
-{
- long v;
- unsigned char *b;
-
- if (*plen < 2) {
- pytdbunpack_err_too_short();
- return NULL;
- }
-
- b = *pbuf;
- v = b[0] | b[1]<<8;
-
- (*pbuf) += 2;
- (*plen) -= 2;
-
- return PyInt_FromLong(v);
-}
-
-
-static PyObject *
-pytdbunpack_string(char **pbuf, int *plen, const char *encoding)
-{
- int len;
- char *nul_ptr, *start;
-
- start = *pbuf;
-
- nul_ptr = memchr(start, '\0', *plen);
- if (!nul_ptr) {
- pytdbunpack_err_too_short();
- return NULL;
- }
-
- len = nul_ptr - start;
-
- *pbuf += len + 1; /* skip \0 */
- *plen -= len + 1;
-
- return PyString_Decode(start, len, encoding, NULL);
-}
-
-
-static PyObject *
-pytdbunpack_buffer(char **pbuf, int *plen, PyObject *val_list)
-{
- /* first get 32-bit len */
- long slen;
- unsigned char *b;
- unsigned char *start;
- PyObject *str_obj = NULL, *len_obj = NULL;
-
- if (*plen < 4) {
- pytdbunpack_err_too_short();
- return NULL;
- }
-
- b = *pbuf;
- slen = b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
-
- if (slen < 0) { /* surely you jest */
- PyErr_Format(PyExc_ValueError,
- "%s: buffer seems to have negative length", FUNCTION_MACRO);
- return NULL;
- }
-
- (*pbuf) += 4;
- (*plen) -= 4;
- start = *pbuf;
-
- if (*plen < slen) {
- PyErr_Format(PyExc_IndexError,
- "%s: not enough data to unpack buffer: "
- "need %d bytes, have %d", FUNCTION_MACRO,
- (int) slen, *plen);
- return NULL;
- }
-
- (*pbuf) += slen;
- (*plen) -= slen;
-
- if (!(len_obj = PyInt_FromLong(slen)))
- goto failed;
-
- if (PyList_Append(val_list, len_obj) == -1)
- goto failed;
-
- if (!(str_obj = PyString_FromStringAndSize(start, slen)))
- goto failed;
-
- if (PyList_Append(val_list, str_obj) == -1)
- goto failed;
-
- Py_DECREF(len_obj);
- Py_DECREF(str_obj);
-
- return val_list;
-
- failed:
- Py_XDECREF(len_obj); /* handles NULL */
- Py_XDECREF(str_obj);
- return NULL;
-}
-
-
-/* Unpack a single field from packed data, according to format character CH.
- Remaining data is at *PBUF, of *PLEN.
-
- *PBUF is advanced, and *PLEN reduced to reflect the amount of data that has
- been consumed.
-
- Returns a reference to None, or NULL for failure.
-*/
-static PyObject *pytdbunpack_item(char ch,
- char **pbuf,
- int *plen,
- PyObject *val_list)
-{
- PyObject *unpacked;
-
- if (ch == 'w') { /* 16-bit int */
- unpacked = pytdbunpack_int16(pbuf, plen);
- }
- else if (ch == 'd' || ch == 'p') { /* 32-bit int */
- /* pointers can just come through as integers */
- unpacked = pytdbunpack_uint32(pbuf, plen);
- }
- else if (ch == 'f' || ch == 'P') { /* nul-term string */
- unpacked = pytdbunpack_string(pbuf, plen, pytdb_unix_encoding);
- }
- else if (ch == 'B') { /* length, buffer */
- return pytdbunpack_buffer(pbuf, plen, val_list);
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%s: format character '%c' is not supported",
- FUNCTION_MACRO, ch);
-
- return NULL;
- }
-
- /* otherwise OK */
- if (!unpacked)
- return NULL;
-
- if (PyList_Append(val_list, unpacked) == -1)
- val_list = NULL;
-
- /* PyList_Append takes a new reference to the inserted object.
- Therefore, we no longer need the original reference. */
- Py_DECREF(unpacked);
-
- return val_list;
-}
-
-
-
-
-
-
-static PyMethodDef pytdbpack_methods[] = {
- { "pack", pytdbpack, METH_VARARGS, (char *) pytdbpack_doc },
- { "unpack", pytdbunpack, METH_VARARGS, (char *) pytdbunpack_doc },
-};
-
-DL_EXPORT(void)
-inittdbpack(void)
-{
- Py_InitModule3("tdbpack", pytdbpack_methods,
- (char *) pytdbpack_docstring);
-}
diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c
deleted file mode 100644
index 130f78d7e12..00000000000
--- a/source/python/py_winbind.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Python wrapper for winbind client functions.
-
- Copyright (C) Tim Potter 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "py_winbind.h"
-
-/*
- * Exceptions raised by this module
- */
-
-PyObject *winbind_error; /* A winbind call returned WINBINDD_ERROR */
-
-/* Prototypes from common.h */
-
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-/*
- * Name <-> SID conversion
- */
-
-/* Convert a name to a sid */
-
-static PyObject *py_name_to_sid(PyObject *self, PyObject *args)
-
-{
- struct winbindd_request request;
- struct winbindd_response response;
- PyObject *result;
- char *name, *p;
- const char *sep;
-
- if (!PyArg_ParseTuple(args, "s", &name))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- sep = lp_winbind_separator();
-
- if ((p = strchr(name, sep[0]))) {
- *p = 0;
- fstrcpy(request.data.name.dom_name, name);
- fstrcpy(request.data.name.name, p + 1);
- } else {
- fstrcpy(request.data.name.dom_name, lp_workgroup());
- fstrcpy(request.data.name.name, name);
- }
-
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- result = PyString_FromString(response.data.sid.sid);
-
- return result;
-}
-
-/* Convert a sid to a name */
-
-static PyObject *py_sid_to_name(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- PyObject *result;
- char *sid, *name;
-
- if (!PyArg_ParseTuple(args, "s", &sid))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- asprintf(&name, "%s%s%s", response.data.name.dom_name,
- lp_winbind_separator(), response.data.name.name);
-
- result = PyString_FromString(name);
-
- free(name);
-
- return result;
-}
-
-/*
- * Enumerate users/groups
- */
-
-/* Enumerate domain users */
-
-static PyObject *py_enum_domain_users(PyObject *self, PyObject *args)
-{
- struct winbindd_response response;
- PyObject *result;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- result = PyList_New(0);
-
- if (response.extra_data) {
- const char *extra_data = response.extra_data;
- fstring name;
-
- while (next_token(&extra_data, name, ",", sizeof(fstring)))
- PyList_Append(result, PyString_FromString(name));
- }
-
- return result;
-}
-
-/* Enumerate domain groups */
-
-static PyObject *py_enum_domain_groups(PyObject *self, PyObject *args)
-{
- struct winbindd_response response;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- result = PyList_New(0);
-
- if (response.extra_data) {
- const char *extra_data = response.extra_data;
- fstring name;
-
- while (next_token(&extra_data, name, ",", sizeof(fstring)))
- PyList_Append(result, PyString_FromString(name));
- }
-
- return result;
-}
-
-/*
- * Miscellaneous domain related
- */
-
-/* Enumerate domain groups */
-
-static PyObject *py_enum_trust_dom(PyObject *self, PyObject *args)
-{
- struct winbindd_response response;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- result = PyList_New(0);
-
- if (response.extra_data) {
- const char *extra_data = response.extra_data;
- fstring name;
-
- while (next_token(&extra_data, name, ",", sizeof(fstring)))
- PyList_Append(result, PyString_FromString(name));
- }
-
- return result;
-}
-
-/* Check machine account password */
-
-static PyObject *py_check_secret(PyObject *self, PyObject *args)
-{
- struct winbindd_response response;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- ZERO_STRUCT(response);
-
- if (winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.num_entries);
-}
-
-/*
- * Return a dictionary consisting of all the winbind related smb.conf
- * parameters. This is stored in the module object.
- */
-
-static PyObject *py_config_dict(void)
-{
- PyObject *result;
- uid_t ulow, uhi;
- gid_t glow, ghi;
-
- if (!(result = PyDict_New()))
- return NULL;
-
- /* Various string parameters */
-
- PyDict_SetItemString(result, "workgroup",
- PyString_FromString(lp_workgroup()));
-
- PyDict_SetItemString(result, "separator",
- PyString_FromString(lp_winbind_separator()));
-
- PyDict_SetItemString(result, "template_homedir",
- PyString_FromString(lp_template_homedir()));
-
- PyDict_SetItemString(result, "template_shell",
- PyString_FromString(lp_template_shell()));
-
- /* idmap uid/gid range */
-
- if (lp_idmap_uid(&ulow, &uhi)) {
- PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow));
- PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi));
- }
-
- if (lp_idmap_gid(&glow, &ghi)) {
- PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow));
- PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi));
- }
-
- return result;
-}
-
-/*
- * ID mapping
- */
-
-/* Convert a uid to a SID */
-
-static PyObject *py_uid_to_sid(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- int id;
-
- if (!PyArg_ParseTuple(args, "i", &id))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = id;
-
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyString_FromString(response.data.sid.sid);
-}
-
-/* Convert a gid to a SID */
-
-static PyObject *py_gid_to_sid(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- int id;
-
- if (!PyArg_ParseTuple(args, "i", &id))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.gid = id;
-
- if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyString_FromString(response.data.sid.sid);
-}
-
-/* Convert a sid to a uid */
-
-static PyObject *py_sid_to_uid(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- char *sid;
-
- if (!PyArg_ParseTuple(args, "s", &sid))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.uid);
-}
-
-/* Convert a sid to a gid */
-
-static PyObject *py_sid_to_gid(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- char *sid;
-
- if (!PyArg_ParseTuple(args, "s", &sid))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.sid, sid);
-
- if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.gid);
-}
-
-/*
- * PAM authentication functions
- */
-
-/* Plaintext authentication */
-
-static PyObject *py_auth_plaintext(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- char *username, *password;
-
- if (!PyArg_ParseTuple(args, "ss", &username, &password))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, password);
-
- if (winbindd_request(WINBINDD_PAM_AUTH, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.auth.nt_status);
-}
-
-/* Challenge/response authentication */
-
-static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] =
- {"username", "password", "use_lm_hash", "use_nt_hash", NULL };
- struct winbindd_request request;
- struct winbindd_response response;
- char *username, *password;
- int use_lm_hash = 1, use_nt_hash = 1;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "ss|ii", kwlist, &username, &password,
- &use_lm_hash, &use_nt_hash))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
- PyErr_SetString(winbind_error, "unable to create utf8 string");
- return NULL;
- }
-
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
-
- if (use_lm_hash) {
- SMBencrypt((uchar *)password, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.lm_resp);
- request.data.auth_crap.lm_resp_len = 24;
- }
-
- if (use_nt_hash) {
- SMBNTencrypt((uchar *)password, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.nt_resp);
- request.data.auth_crap.nt_resp_len = 24;
- }
-
- if (winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.auth.nt_status);
-}
-
-#if 0 /* Include when auth_smbd merged to HEAD */
-
-/* Challenge/response authentication, with secret */
-
-static PyObject *py_auth_smbd(PyObject *self, PyObject *args, PyObject *kw)
-{
- static char *kwlist[] =
- {"username", "password", "use_lm_hash", "use_nt_hash", NULL };
- struct winbindd_request request;
- struct winbindd_response response;
- char *username, *password;
- int use_lm_hash = 1, use_nt_hash = 1;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "ss|ii", kwlist, &username, &password,
- &use_lm_hash, &use_nt_hash))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
- PyErr_SetString("unable to create utf8 string");
- return NULL;
- }
-
- generate_random_buffer(request.data.smbd_auth_crap.chal, 8, False);
-
- if (use_lm_hash) {
- SMBencrypt((uchar *)password,
- request.data.smbd_auth_crap.chal,
- (uchar *)request.data.smbd_auth_crap.lm_resp);
- request.data.smbd_auth_crap.lm_resp_len = 24;
- }
-
- if (use_nt_hash) {
- SMBNTencrypt((uchar *)password,
- request.data.smbd_auth_crap.chal,
- (uchar *)request.data.smbd_auth_crap.nt_resp);
- request.data.smbd_auth_crap.nt_resp_len = 24;
- }
-
- if (!secrets_fetch_trust_account_password(
- lp_workgroup(), request.data.smbd_auth_crap.proof, NULL)) {
- PyErr_SetString(
- winbind_error, "unable to fetch domain secret");
- return NULL;
- }
-
-
-
- if (winbindd_request(WINBINDD_SMBD_AUTH_CRAP, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- return PyInt_FromLong(response.data.auth.nt_status);
-}
-
-#endif /* 0 */
-
-/* Get user info from name */
-
-static PyObject *py_getpwnam(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- char *username;
- PyObject *result;
-
- if (!PyArg_ParseTuple(args, "s", &username))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.username, username);
-
- if (winbindd_request(WINBINDD_GETPWNAM, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- if (!py_from_winbind_passwd(&result, &response)) {
- result = Py_None;
- Py_INCREF(result);
- }
-
- return result;
-}
-
-/* Get user info from uid */
-
-static PyObject *py_getpwuid(PyObject *self, PyObject *args)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- uid_t uid;
- PyObject *result;
-
- if (!PyArg_ParseTuple(args, "i", &uid))
- return NULL;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = uid;
-
- if (winbindd_request(WINBINDD_GETPWUID, &request, &response)
- != NSS_STATUS_SUCCESS) {
- PyErr_SetString(winbind_error, "lookup failed");
- return NULL;
- }
-
- if (!py_from_winbind_passwd(&result, &response)) {
- result = Py_None;
- Py_INCREF(result);
- }
-
- return result;
-}
-
-/*
- * Method dispatch table
- */
-
-static PyMethodDef winbind_methods[] = {
-
- { "getpwnam", (PyCFunction)py_getpwnam, METH_VARARGS, "getpwnam(3)" },
- { "getpwuid", (PyCFunction)py_getpwuid, METH_VARARGS, "getpwuid(3)" },
-
- /* Name <-> SID conversion */
-
- { "name_to_sid", (PyCFunction)py_name_to_sid, METH_VARARGS,
- "name_to_sid(s) -> string\n"
-"\n"
-"Return the SID for a name.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.name_to_sid('FOO/Administrator')\n"
-"'S-1-5-21-406022937-1377575209-526660263-500' " },
-
- { "sid_to_name", (PyCFunction)py_sid_to_name, METH_VARARGS,
- "sid_to_name(s) -> string\n"
-"\n"
-"Return the name for a SID.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> import winbind\n"
-">>> winbind.sid_to_name('S-1-5-21-406022937-1377575209-526660263-500')\n"
-"'FOO/Administrator' " },
-
- /* Enumerate users/groups */
-
- { "enum_domain_users", (PyCFunction)py_enum_domain_users, METH_VARARGS,
- "enum_domain_users() -> list of strings\n"
-"\n"
-"Return a list of domain users.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.enum_domain_users()\n"
-"['FOO/Administrator', 'FOO/anna', 'FOO/Anne Elk', 'FOO/build', \n"
-"'FOO/foo', 'FOO/foo2', 'FOO/foo3', 'FOO/Guest', 'FOO/user1', \n"
-"'FOO/whoops-ptang'] " },
-
- { "enum_domain_groups", (PyCFunction)py_enum_domain_groups,
- METH_VARARGS,
- "enum_domain_groups() -> list of strings\n"
-"\n"
-"Return a list of domain groups.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.enum_domain_groups()\n"
-"['FOO/cows', 'FOO/Domain Admins', 'FOO/Domain Guests', \n"
-"'FOO/Domain Users'] " },
-
- /* ID mapping */
-
- { "uid_to_sid", (PyCFunction)py_uid_to_sid, METH_VARARGS,
- "uid_to_sid(int) -> string\n"
-"\n"
-"Return the SID for a UNIX uid.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.uid_to_sid(10000) \n"
-"'S-1-5-21-406022937-1377575209-526660263-500' " },
-
- { "gid_to_sid", (PyCFunction)py_gid_to_sid, METH_VARARGS,
- "gid_to_sid(int) -> string\n"
-"\n"
-"Return the UNIX gid for a SID.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.gid_to_sid(10001)\n"
-"'S-1-5-21-406022937-1377575209-526660263-512' " },
-
- { "sid_to_uid", (PyCFunction)py_sid_to_uid, METH_VARARGS,
- "sid_to_uid(string) -> int\n"
-"\n"
-"Return the UNIX uid for a SID.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.sid_to_uid('S-1-5-21-406022937-1377575209-526660263-500')\n"
-"10000 " },
-
- { "sid_to_gid", (PyCFunction)py_sid_to_gid, METH_VARARGS,
- "sid_to_gid(string) -> int\n"
-"\n"
-"Return the UNIX gid corresponding to a SID.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.sid_to_gid('S-1-5-21-406022937-1377575209-526660263-512')\n"
-"10001 " },
-
- /* Miscellaneous */
-
- { "check_secret", (PyCFunction)py_check_secret, METH_VARARGS,
- "check_secret() -> int\n"
-"\n"
-"Check the machine trust account password. The NT status is returned\n"
-"with zero indicating success. " },
-
- { "enum_trust_dom", (PyCFunction)py_enum_trust_dom, METH_VARARGS,
- "enum_trust_dom() -> list of strings\n"
-"\n"
-"Return a list of trusted domains. The domain the server is a member \n"
-"of is not included.\n"
-"\n"
-"Example:\n"
-"\n"
-">>> winbind.enum_trust_dom()\n"
-"['NPSD-TEST2', 'SP2NDOM'] " },
-
- /* PAM authorisation functions */
-
- { "auth_plaintext", (PyCFunction)py_auth_plaintext, METH_VARARGS,
- "auth_plaintext(s, s) -> int\n"
-"\n"
-"Authenticate a username and password using plaintext authentication.\n"
-"The NT status code is returned with zero indicating success." },
-
- { "auth_crap", (PyCFunction)py_auth_crap, METH_VARARGS,
- "auth_crap(s, s) -> int\n"
-"\n"
-"Authenticate a username and password using the challenge/response\n"
-"protocol. The NT status code is returned with zero indicating\n"
-"success." },
-
-#if 0 /* Include when smbd_auth merged to HEAD */
-
- { "auth_smbd", (PyCFunction)py_auth_crap, METH_VARARGS,
- "auth_smbd(s, s) -> int\n"
-"\n"
-"Authenticate a username and password using the challenge/response\n"
-"protocol but using the domain secret to prove we are root. The NT \n"
-"status code is returned with zero indicating success." },
-
-#endif
-
- { NULL }
-};
-
-static struct const_vals {
- char *name;
- uint32 value;
- char *docstring;
-} module_const_vals[] = {
-
- /* Well known RIDs */
-
- { "DOMAIN_USER_RID_ADMIN", DOMAIN_USER_RID_ADMIN,
- "Well-known RID for Administrator user" },
-
- { "DOMAIN_USER_RID_GUEST", DOMAIN_USER_RID_GUEST,
- "Well-known RID for Guest user" },
-
- { "DOMAIN_GROUP_RID_ADMINS", DOMAIN_GROUP_RID_ADMINS,
- "Well-known RID for Domain Admins group" },
-
- { "DOMAIN_GROUP_RID_USERS", DOMAIN_GROUP_RID_USERS,
- "Well-known RID for Domain Users group" },
-
- { "DOMAIN_GROUP_RID_GUESTS", DOMAIN_GROUP_RID_GUESTS,
- "Well-known RID for Domain Guests group" },
-
- { NULL }
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/*
- * Module initialisation
- */
-
-static char winbind_module__doc__[] =
-"A python extension to winbind client functions.";
-
-void initwinbind(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule3("winbind", winbind_methods,
- winbind_module__doc__);
-
- dict = PyModule_GetDict(module);
-
- winbind_error = PyErr_NewException("winbind.error", NULL, NULL);
- PyDict_SetItemString(dict, "error", winbind_error);
-
- /* Do samba initialisation */
-
- py_samba_init();
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Insert configuration dictionary */
-
- PyDict_SetItemString(dict, "config", py_config_dict());
-}
diff --git a/source/python/py_winbind.h b/source/python/py_winbind.h
deleted file mode 100644
index 10927ea6c8f..00000000000
--- a/source/python/py_winbind.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _PY_WINBIND_H
-#define _PY_WINBIND_H
-
-#include "python/py_common.h"
-
-/* The following definitions are from py_winbind_conv.c */
-
-BOOL py_from_winbind_passwd(PyObject **dict, struct winbindd_response *response);
-
-#endif /* _PY_WINBIND_H */
diff --git a/source/python/py_winbind_conv.c b/source/python/py_winbind_conv.c
deleted file mode 100644
index 6e2eab59414..00000000000
--- a/source/python/py_winbind_conv.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_common.h"
-#include "python/py_conv.h"
-
-/* Convert a struct passwd to a dictionary */
-
-static struct pyconv py_passwd[] = {
- { "pw_name", PY_STRING, offsetof(struct winbindd_response, data.pw.pw_name) },
- { "pw_passwd", PY_STRING, offsetof(struct winbindd_response, data.pw.pw_passwd) },
- { "pw_uid", PY_UID, offsetof(struct winbindd_response, data.pw.pw_uid) },
- { "pw_guid", PY_GID, offsetof(struct winbindd_response, data.pw.pw_gid) },
- { "pw_gecos", PY_STRING, offsetof(struct winbindd_response, data.pw.pw_gecos) },
- { "pw_dir", PY_STRING, offsetof(struct winbindd_response, data.pw.pw_dir) },
- { "pw_shell", PY_STRING, offsetof(struct winbindd_response, data.pw.pw_shell) },
- { NULL}
-};
-
-BOOL py_from_winbind_passwd(PyObject **dict, struct winbindd_response *response)
-{
- *dict = from_struct(response, py_passwd);
- return True;
-}
diff --git a/source/python/py_winreg.c b/source/python/py_winreg.c
deleted file mode 100644
index ce27f5c533b..00000000000
--- a/source/python/py_winreg.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "python/py_winreg.h"
-
-static struct const_vals {
- char *name;
- uint32 value;
-} module_const_vals[] = {
-
- /* Registry value types */
-
- { "REG_NONE", REG_NONE },
- { "REG_SZ", REG_SZ },
- { "REG_EXPAND_SZ", REG_EXPAND_SZ },
- { "REG_BINARY", REG_BINARY },
- { "REG_DWORD", REG_DWORD },
- { "REG_DWORD_LE", REG_DWORD_LE },
- { "REG_DWORD_BE", REG_DWORD_BE },
- { "REG_LINK", REG_LINK },
- { "REG_MULTI_SZ", REG_MULTI_SZ },
- { "REG_RESOURCE_LIST", REG_RESOURCE_LIST },
- { "REG_FULL_RESOURCE_DESCRIPTOR", REG_FULL_RESOURCE_DESCRIPTOR },
- { "REG_RESOURCE_REQUIREMENTS_LIST", REG_RESOURCE_REQUIREMENTS_LIST },
-
- { NULL },
-};
-
-static void const_init(PyObject *dict)
-{
- struct const_vals *tmp;
- PyObject *obj;
-
- for (tmp = module_const_vals; tmp->name; tmp++) {
- obj = PyInt_FromLong(tmp->value);
- PyDict_SetItemString(dict, tmp->name, obj);
- Py_DECREF(obj);
- }
-}
-
-/*
- * Module initialisation
- */
-
-static PyMethodDef winreg_methods[] = {
- { NULL }
-};
-
-void initwinreg(void)
-{
- PyObject *module, *dict;
-
- /* Initialise module */
-
- module = Py_InitModule("winreg", winreg_methods);
- dict = PyModule_GetDict(module);
-
- /* Initialise constants */
-
- const_init(dict);
-
- /* Do samba initialisation */
-
- py_samba_init();
-}
diff --git a/source/python/samba/__init__.py b/source/python/samba/__init__.py
deleted file mode 100644
index c818ca3e044..00000000000
--- a/source/python/samba/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-"""samba
-
-Various Python modules for interfacing to Samba.
-
-Try using help() to examine their documentation.
-"""
-
diff --git a/source/python/samba/printerdata.py b/source/python/samba/printerdata.py
deleted file mode 100644
index 0b53a3dfb52..00000000000
--- a/source/python/samba/printerdata.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-
-#
-# A python module that maps printerdata to a dictionary. We define
-# two classes. The printerdata class maps to Get/Set/Enum/DeletePrinterData
-# and the printerdata_ex class maps to Get/Set/Enum/DeletePrinterDataEx
-#
-
-#
-# TODO:
-#
-# - Implement __delitem__
-#
-
-from samba import spoolss
-
-class printerdata:
- def __init__(self, host, creds = {}, access = 0x02000000):
- # For read access, use MAXIMUM_ALLOWED_ACCESS = 0x02000000
- # For write access, use PRINTER_ACCESS_ADMINISTER = 0x00000004
- self.hnd = spoolss.openprinter(host, creds = creds, access = access)
-
- def keys(self):
- return self.hnd.enumprinterdata().keys()
-
- def __getitem__(self, key):
- return self.hnd.getprinterdata(key)['data']
-
- def __setitem__(self, key, value):
- # Store as REG_BINARY for now
- self.hnd.setprinterdata({"key": "", "value": key, "type": 3,
- "data": value})
-
-class printerdata_ex:
- def __init__(self, host, creds = {}, access = 0x02000000):
- # For read access, use MAXIMUM_ALLOWED_ACCESS = 0x02000000
- # For write access, use PRINTER_ACCESS_ADMINISTER = 0x00000004
- self.host = host
- self.top_level_keys = ["PrinterDriverData", "DsSpooler", "DsDriver",
- "DsUser"]
- self.creds = creds
- self.access = access
-
- def keys(self):
- return self.top_level_keys
-
- def has_key(self, key):
- for k in self.top_level_keys:
- if k == key:
- return 1
- return 0
-
- class printerdata_ex_subkey:
- def __init__(self, host, key, creds, access):
- self.hnd = spoolss.openprinter(host, creds, access)
- self.key = key
-
- def keys(self):
- return self.hnd.enumprinterdataex(self.key).keys()
-
- def __getitem__(self, key):
- return self.hnd.getprinterdataex(self.key, key)['data']
-
- def __getitem__(self, key):
- return self.printerdata_ex_subkey(self.host, key, creds, access)
diff --git a/source/python/setup.py b/source/python/setup.py
deleted file mode 100755
index 4a4f6ad3f81..00000000000
--- a/source/python/setup.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# -*- mode: python -*-
-#
-# Unix SMB/CIFS implementation.
-# Module packaging setup for Samba python extensions
-#
-# Copyright (C) Tim Potter, 2002-2003
-# Copyright (C) Martin Pool, 2002
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-from distutils.core import setup
-from distutils.extension import Extension
-
-import sys, string, os
-
-# The Makefile passes in environment variable $PYTHON_OBJ as being the
-# list of Samba objects. This kind of goes against the distutils.cmd
-# method of adding setup commands and will also confuse people who are
-# familiar with the python Distutils module.
-
-samba_objs = os.environ.get("PYTHON_OBJS", "")
-
-samba_cflags = os.environ.get("PYTHON_CFLAGS", "")
-
-samba_srcdir = os.environ.get("SRCDIR", "")
-
-# These variables are filled in by configure
-
-samba_libs = os.environ.get("LIBS", "")
-
-obj_list = string.split(samba_objs)
-
-# Unfortunately the samba_libs variable contains both shared libraries
-# and linker flags. The python distutils doesn't like this so we have
-# to split $samba_libs into a flags component and a library component.
-
-libraries = []
-library_dirs = []
-
-for lib in string.split(samba_libs):
- if lib[0:2] == "-l":
- libraries.append(lib[2:])
- continue
- if lib[0:2] == "-L":
- library_dirs.append(lib[2:])
- continue
- if lib[0:2] == "-W":
- # Skip linker flags
- continue
- print "Unknown entry '%s' in $LIBS variable passed to setup.py" % lib
- sys.exit(1)
-
-flags_list = string.split(samba_cflags)
-
-# Invoke distutils.setup
-
-setup(
-
- # Overview information
-
- name = "Samba Python Extensions",
- version = "0.1",
- author = "Tim Potter",
- author_email = "tpot@samba.org",
- license = "GPL",
-
- # Get the "samba" directory of Python source. At the moment this
- # just contains the __init__ file that makes it work as a
- # subpackage. This is needed even though everything else is an
- # extension module.
- package_dir = {"samba": os.path.join(samba_srcdir, "python", "samba")},
- packages = ["samba"],
-
- # Module list
- ext_package = "samba",
- ext_modules = [
-
- # SPOOLSS pipe module
-
- Extension(name = "spoolss",
- sources = [samba_srcdir + "python/py_spoolss.c",
- samba_srcdir + "python/py_common.c",
- samba_srcdir + "python/py_conv.c",
- samba_srcdir + "python/py_ntsec.c",
- samba_srcdir + "python/py_spoolss_common.c",
- samba_srcdir + "python/py_spoolss_forms.c",
- samba_srcdir + "python/py_spoolss_forms_conv.c",
- samba_srcdir + "python/py_spoolss_drivers.c",
- samba_srcdir + "python/py_spoolss_drivers_conv.c",
- samba_srcdir + "python/py_spoolss_printers.c",
- samba_srcdir + "python/py_spoolss_printers_conv.c",
- samba_srcdir + "python/py_spoolss_printerdata.c",
- samba_srcdir + "python/py_spoolss_ports.c",
- samba_srcdir + "python/py_spoolss_ports_conv.c",
- samba_srcdir + "python/py_spoolss_jobs.c",
- samba_srcdir + "python/py_spoolss_jobs_conv.c",
- ],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # LSA pipe module
-
- Extension(name = "lsa",
- sources = [samba_srcdir + "python/py_lsa.c",
- samba_srcdir + "python/py_common.c",
- samba_srcdir + "python/py_ntsec.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # SAMR pipe module
-
- Extension(name = "samr",
- sources = [samba_srcdir + "python/py_samr.c",
- samba_srcdir + "python/py_conv.c",
- samba_srcdir + "python/py_samr_conv.c",
- samba_srcdir + "python/py_common.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # winbind client module
-
- Extension(name = "winbind",
- sources = [samba_srcdir + "python/py_winbind.c",
- samba_srcdir + "python/py_winbind_conv.c",
- samba_srcdir + "python/py_conv.c",
- samba_srcdir + "python/py_common.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # WINREG pipe module
-
- Extension(name = "winreg",
- sources = [samba_srcdir + "python/py_winreg.c",
- samba_srcdir + "python/py_common.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # SRVSVC pipe module
-
- Extension(name = "srvsvc",
- sources = [samba_srcdir + "python/py_srvsvc.c",
- samba_srcdir + "python/py_conv.c",
- samba_srcdir + "python/py_srvsvc_conv.c",
- samba_srcdir + "python/py_common.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # tdb module
-
- Extension(name = "tdb",
- sources = [samba_srcdir + "python/py_tdb.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # libsmb module
-
- Extension(name = "smb",
- sources = [samba_srcdir + "python/py_smb.c",
- samba_srcdir + "python/py_common.c",
- samba_srcdir + "python/py_ntsec.c"],
- libraries = libraries,
- library_dirs = ["/usr/kerberos/lib"] + library_dirs,
- extra_compile_args = flags_list,
- extra_objects = obj_list),
-
- # tdbpack/unpack extensions. Does not actually link to any Samba
- # code, although it implements a compatible data format.
-
- Extension(name = "tdbpack",
- sources = [os.path.join(samba_srcdir, "python", "py_tdbpack.c")],
- extra_compile_args = ["-I."])
- ],
-)
diff --git a/source/registry/reg_cachehook.c b/source/registry/reg_cachehook.c
deleted file mode 100644
index 547eed392d8..00000000000
--- a/source/registry/reg_cachehook.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry hook cache tree */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-static SORTED_TREE *cache_tree;
-extern REGISTRY_OPS regdb_ops; /* these are the default */
-static REGISTRY_HOOK default_hook = { KEY_TREE_ROOT, &regdb_ops };
-
-/**********************************************************************
- Initialize the cache tree
- *********************************************************************/
-
-BOOL reghook_cache_init( void )
-{
- cache_tree = sorted_tree_init( &default_hook, NULL, NULL );
-
- return ( cache_tree == NULL );
-}
-
-/**********************************************************************
- Add a new REGISTRY_HOOK to the cache. Note that the keyname
- is not in the exact format that a SORTED_TREE expects.
- *********************************************************************/
-
-BOOL reghook_cache_add( REGISTRY_HOOK *hook )
-{
- pstring key;
-
- if ( !hook )
- return False;
-
- pstrcpy( key, "\\");
- pstrcat( key, hook->keyname );
-
- pstring_sub( key, "\\", "/" );
-
- DEBUG(10,("reghook_cache_add: Adding key [%s]\n", key));
-
- return sorted_tree_add( cache_tree, key, hook );
-}
-
-/**********************************************************************
- Initialize the cache tree
- *********************************************************************/
-
-REGISTRY_HOOK* reghook_cache_find( char *keyname )
-{
- char *key;
- int len;
- REGISTRY_HOOK *hook;
-
- if ( !keyname )
- return NULL;
-
- /* prepend the string with a '\' character */
-
- len = strlen( keyname );
- if ( !(key = malloc( len + 2 )) ) {
- DEBUG(0,("reghook_cache_find: malloc failed for string [%s] !?!?!\n",
- keyname));
- return NULL;
- }
-
- *key = '\\';
- strncpy( key+1, keyname, len+1);
-
- /* swap to a form understood by the SORTED_TREE */
-
- string_sub( key, "\\", "/", 0 );
-
- DEBUG(10,("reghook_cache_find: Searching for keyname [%s]\n", key));
-
- hook = sorted_tree_find( cache_tree, key ) ;
-
- SAFE_FREE( key );
-
- return hook;
-}
-
-/**********************************************************************
- Initialize the cache tree
- *********************************************************************/
-
-void reghook_dump_cache( int debuglevel )
-{
- DEBUG(debuglevel,("reghook_dump_cache: Starting cache dump now...\n"));
-
- sorted_tree_print_keys( cache_tree, debuglevel );
-}
diff --git a/source/registry/reg_db.c b/source/registry/reg_db.c
deleted file mode 100644
index cd5ec18f021..00000000000
--- a/source/registry/reg_db.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of internal registry database functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-static TDB_CONTEXT *tdb_reg;
-
-
-/***********************************************************************
- Open the registry data in the tdb
- ***********************************************************************/
-
-static BOOL init_registry_data( void )
-{
- pstring keyname;
- REGSUBKEY_CTR subkeys;
-
- ZERO_STRUCTP( &subkeys );
-
- /* HKEY_LOCAL_MACHINE */
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- regsubkey_ctr_addkey( &subkeys, "SYSTEM" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM" );
- regsubkey_ctr_addkey( &subkeys, "CurrentControlSet" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet" );
- regsubkey_ctr_addkey( &subkeys, "Control" );
- regsubkey_ctr_addkey( &subkeys, "Services" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
- regsubkey_ctr_addkey( &subkeys, "Print" );
- regsubkey_ctr_addkey( &subkeys, "ProductOptions" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services" );
- regsubkey_ctr_addkey( &subkeys, "Netlogon" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Netlogon" );
- regsubkey_ctr_addkey( &subkeys, "Parameters" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
- regsubkey_ctr_destroy( &subkeys );
-
- pstrcpy( keyname, KEY_HKLM );
- pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Netlogon/Parameters" );
- if ( !regdb_store_reg_keys( keyname, &subkeys ))
- return False;
-
- /* HKEY_USER */
-
- pstrcpy( keyname, KEY_HKU );
- if ( !regdb_store_reg_keys( keyname, &subkeys ) )
- return False;
-
- /* HKEY_CLASSES_ROOT*/
-
- pstrcpy( keyname, KEY_HKCR );
- if ( !regdb_store_reg_keys( keyname, &subkeys ) )
- return False;
-
- return True;
-}
-
-/***********************************************************************
- Open the registry database
- ***********************************************************************/
-
-BOOL init_registry_db( void )
-{
- static pid_t local_pid;
-
- if (tdb_reg && local_pid == sys_getpid())
- return True;
-
- /*
- * try to open first without creating so we can determine
- * if we need to init the data in the registry
- */
-
- tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
- if ( !tdb_reg )
- {
- tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if ( !tdb_reg ) {
- DEBUG(0,("init_registry: Failed to open registry %s (%s)\n",
- lock_path("registry.tdb"), strerror(errno) ));
- return False;
- }
-
- DEBUG(10,("init_registry: Successfully created registry tdb\n"));
-
- /* create the registry here */
- if ( !init_registry_data() ) {
- DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
- return False;
- }
- }
-
- local_pid = sys_getpid();
-
- return True;
-}
-
-
-
-/***********************************************************************
- Add subkey strings to the registry tdb under a defined key
- fmt is the same format as tdb_pack except this function only supports
- fstrings
-
- The full path to the registry key is used as database after the
- \'s are converted to /'s. Key string is also normalized to UPPER
- case.
- ***********************************************************************/
-
-BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr )
-{
- TDB_DATA kbuf, dbuf;
- char *buffer, *tmpbuf;
- int i = 0;
- uint32 len, buflen;
- BOOL ret = True;
- uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
-
- if ( !keyname )
- return False;
-
- strupper_m( keyname );
-
- /* allocate some initial memory */
-
- buffer = malloc(sizeof(pstring));
- buflen = sizeof(pstring);
- len = 0;
-
- /* store the number of subkeys */
-
- len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
-
- /* pack all the strings */
-
- for (i=0; i<num_subkeys; i++) {
- len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
- if ( len > buflen ) {
- /* allocate some extra space */
- if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) {
- DEBUG(0,("regdb_store_reg_keys: Failed to realloc memory of size [%d]\n", len*2));
- ret = False;
- goto done;
- }
- buffer = tmpbuf;
- buflen = len*2;
-
- len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
- }
- }
-
- /* finally write out the data */
-
- kbuf.dptr = keyname;
- kbuf.dsize = strlen(keyname)+1;
- dbuf.dptr = buffer;
- dbuf.dsize = len;
- if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
- ret = False;
- goto done;
- }
-
-done:
- SAFE_FREE( buffer );
-
- return ret;
-}
-
-/***********************************************************************
- Retrieve an array of strings containing subkeys. Memory should be
- released by the caller. The subkeys are stored in a catenated string
- of null terminated character strings
- ***********************************************************************/
-
-int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
-{
- pstring path;
- uint32 num_items;
- TDB_DATA dbuf;
- char *buf;
- uint32 buflen, len;
- int i;
- fstring subkeyname;
-
- DEBUG(10,("regdb_fetch_reg_keys: Enter key => [%s]\n", key ? key : "NULL"));
-
- pstrcpy( path, key );
-
- /* convert to key format */
- pstring_sub( path, "\\", "/" );
- strupper_m( path );
-
- dbuf = tdb_fetch_bystring( tdb_reg, path );
-
- buf = dbuf.dptr;
- buflen = dbuf.dsize;
-
- if ( !buf ) {
- DEBUG(5,("regdb_fetch_reg_keys: tdb lookup failed to locate key [%s]\n", key));
- return -1;
- }
-
- len = tdb_unpack( buf, buflen, "d", &num_items);
-
- for (i=0; i<num_items; i++) {
- len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
- regsubkey_ctr_addkey( ctr, subkeyname );
- }
-
- SAFE_FREE( dbuf.dptr );
-
- DEBUG(10,("regdb_fetch_reg_keys: Exit [%d] items\n", num_items));
-
- return num_items;
-}
-
-
-/***********************************************************************
- Retrieve an array of strings containing subkeys. Memory should be
- released by the caller. The subkeys are stored in a catenated string
- of null terminated character strings
- ***********************************************************************/
-
-int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
-{
- return 0;
-}
-
-/***********************************************************************
- Stub function since we do not currently support storing registry
- values in the registry.tdb
- ***********************************************************************/
-
-BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val )
-{
- return False;
-}
-
-
-/*
- * Table of function pointers for default access
- */
-
-REGISTRY_OPS regdb_ops = {
- regdb_fetch_reg_keys,
- regdb_fetch_reg_values,
- regdb_store_reg_keys,
- regdb_store_reg_values
-};
-
-
diff --git a/source/registry/reg_frontend.c b/source/registry/reg_frontend.c
deleted file mode 100644
index a9dfb52f011..00000000000
--- a/source/registry/reg_frontend.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry frontend view functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-extern REGISTRY_OPS printing_ops;
-extern REGISTRY_OPS regdb_ops; /* these are the default */
-
-/* array of REGISTRY_HOOK's which are read into a tree for easy access */
-
-
-REGISTRY_HOOK reg_hooks[] = {
- { KEY_PRINTING, &printing_ops },
- { NULL, NULL }
-};
-
-
-/***********************************************************************
- Open the registry database and initialize the REGISTRY_HOOK cache
- ***********************************************************************/
-
-BOOL init_registry( void )
-{
- int i;
-
- if ( !init_registry_db() ) {
- DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
- return False;
- }
-
- /* build the cache tree of registry hooks */
-
- reghook_cache_init();
-
- for ( i=0; reg_hooks[i].keyname; i++ ) {
- if ( !reghook_cache_add(&reg_hooks[i]) )
- return False;
- }
-
- if ( DEBUGLEVEL >= 20 )
- reghook_dump_cache(20);
-
- return True;
-}
-
-
-
-
-/***********************************************************************
- High level wrapper function for storing registry subkeys
- ***********************************************************************/
-
-BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
-{
- if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
- return key->hook->ops->store_subkeys_fn( key->name, subkeys );
- else
- return False;
-
-}
-
-/***********************************************************************
- High level wrapper function for storing registry values
- ***********************************************************************/
-
-BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
- return key->hook->ops->store_values_fn( key->name, val );
- else
- return False;
-}
-
-
-/***********************************************************************
- High level wrapper function for enumerating registry subkeys
- Initialize the TALLOC_CTX if necessary
- ***********************************************************************/
-
-int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
-{
- int result = -1;
-
- if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
- result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
-
- return result;
-}
-
-/***********************************************************************
- retreive a specific subkey specified by index. Caller is
- responsible for freeing memory
- ***********************************************************************/
-
-BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
-{
- static REGSUBKEY_CTR ctr;
- static pstring save_path;
- static BOOL ctr_init = False;
- char *s;
-
- *subkey = NULL;
-
- /* simple caching for performance; very basic heuristic */
-
- if ( !ctr_init ) {
- DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
- ZERO_STRUCTP( &ctr );
- regsubkey_ctr_init( &ctr );
-
- pstrcpy( save_path, key->name );
-
- if ( fetch_reg_keys( key, &ctr) == -1 )
- return False;
-
- ctr_init = True;
- }
- /* clear the cache when key_index == 0 or the path has changed */
- else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
-
- DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
-
- regsubkey_ctr_destroy( &ctr );
- regsubkey_ctr_init( &ctr );
-
- pstrcpy( save_path, key->name );
-
- if ( fetch_reg_keys( key, &ctr) == -1 )
- return False;
- }
-
- if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
- return False;
-
- *subkey = strdup( s );
-
- return True;
-}
-
-
-/***********************************************************************
- High level wrapper function for enumerating registry values
- Initialize the TALLOC_CTX if necessary
- ***********************************************************************/
-
-int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- int result = -1;
-
- if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
- result = key->hook->ops->value_fn( key->name, val );
-
- return result;
-}
-
-
-/***********************************************************************
- retreive a specific subkey specified by index. Caller is
- responsible for freeing memory
- ***********************************************************************/
-
-BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
-{
- static REGVAL_CTR ctr;
- static pstring save_path;
- static BOOL ctr_init = False;
- REGISTRY_VALUE *v;
-
- *val = NULL;
-
- /* simple caching for performance; very basic heuristic */
-
- if ( !ctr_init ) {
- DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
-
- ZERO_STRUCTP( &ctr );
- regval_ctr_init( &ctr );
-
- pstrcpy( save_path, key->name );
-
- if ( fetch_reg_values( key, &ctr) == -1 )
- return False;
-
- ctr_init = True;
- }
- /* clear the cache when val_index == 0 or the path has changed */
- else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
-
- DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
-
- regval_ctr_destroy( &ctr );
- regval_ctr_init( &ctr );
-
- pstrcpy( save_path, key->name );
-
- if ( fetch_reg_values( key, &ctr) == -1 )
- return False;
- }
-
- if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
- return False;
-
- *val = dup_registry_value( v );
-
- return True;
-}
-
-/***********************************************************************
- Utility function for splitting the base path of a registry path off
- by setting base and new_path to the apprapriate offsets withing the
- path.
-
- WARNING!! Does modify the original string!
- ***********************************************************************/
-
-BOOL reg_split_path( char *path, char **base, char **new_path )
-{
- char *p;
-
- *new_path = *base = NULL;
-
- if ( !path)
- return False;
-
- *base = path;
-
- p = strchr( path, '\\' );
-
- if ( p ) {
- *p = '\0';
- *new_path = p+1;
- }
-
- return True;
-}
-
-
-
diff --git a/source/registry/reg_objects.c b/source/registry/reg_objects.c
deleted file mode 100644
index 9cfeb7faa97..00000000000
--- a/source/registry/reg_objects.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry frontend view functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-
-/***********************************************************************
- Init the talloc context held by a REGSUBKEY_CTR structure
- **********************************************************************/
-
-void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
-{
- if ( !ctr->ctx )
- ctr->ctx = talloc_init("regsubkey_ctr_init for ctr %p", ctr);
-}
-
-/***********************************************************************
- Add a new key to the array
- **********************************************************************/
-
-int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
-{
- uint32 len;
- char **pp;
-
- if ( keyname )
- {
- len = strlen( keyname );
-
- /* allocate a space for the char* in the array */
-
- if ( ctr->subkeys == 0 )
- ctr->subkeys = talloc( ctr->ctx, sizeof(char*) );
- else {
- pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) );
- if ( pp )
- ctr->subkeys = pp;
- }
-
- /* allocate the string and save it in the array */
-
- ctr->subkeys[ctr->num_subkeys] = talloc( ctr->ctx, len+1 );
- strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 );
- ctr->num_subkeys++;
- }
-
- return ctr->num_subkeys;
-}
-
-/***********************************************************************
- How many keys does the container hold ?
- **********************************************************************/
-
-int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
-{
- return ctr->num_subkeys;
-}
-
-/***********************************************************************
- Retreive a specific key string
- **********************************************************************/
-
-char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
-{
- if ( ! (key_index < ctr->num_subkeys) )
- return NULL;
-
- return ctr->subkeys[key_index];
-}
-
-/***********************************************************************
- free memory held by a REGSUBKEY_CTR structure
- **********************************************************************/
-
-void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
-{
- if ( ctr ) {
- talloc_destroy( ctr->ctx );
- ZERO_STRUCTP( ctr );
- }
-}
-
-
-/*
- * Utility functions for REGVAL_CTR
- */
-
-/***********************************************************************
- Init the talloc context held by a REGSUBKEY_CTR structure
- **********************************************************************/
-
-void regval_ctr_init( REGVAL_CTR *ctr )
-{
- if ( !ctr->ctx )
- ctr->ctx = talloc_init("regval_ctr_init for ctr %p", ctr);
-}
-
-/***********************************************************************
- How many keys does the container hold ?
- **********************************************************************/
-
-int regval_ctr_numvals( REGVAL_CTR *ctr )
-{
- return ctr->num_values;
-}
-
-/***********************************************************************
- allocate memory for and duplicate a REGISTRY_VALUE.
- This is malloc'd memory so the caller should free it when done
- **********************************************************************/
-
-REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
-{
- REGISTRY_VALUE *copy = NULL;
-
- if ( !val )
- return NULL;
-
- if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
- DEBUG(0,("dup_registry_value: malloc() failed!\n"));
- return NULL;
- }
-
- /* copy all the non-pointer initial data */
-
- memcpy( copy, val, sizeof(REGISTRY_VALUE) );
- if ( val->data_p )
- {
- if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
- DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
- val->size));
- SAFE_FREE( copy );
- }
- }
-
- return copy;
-}
-
-/**********************************************************************
- free the memory allocated to a REGISTRY_VALUE
- *********************************************************************/
-
-void free_registry_value( REGISTRY_VALUE *val )
-{
- if ( !val )
- return;
-
- SAFE_FREE( val->data_p );
- SAFE_FREE( val );
-
- return;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-uint8* regval_data_p( REGISTRY_VALUE *val )
-{
- return val->data_p;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-int regval_size( REGISTRY_VALUE *val )
-{
- return val->size;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-char* regval_name( REGISTRY_VALUE *val )
-{
- return val->valuename;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-uint32 regval_type( REGISTRY_VALUE *val )
-{
- return val->type;
-}
-
-/***********************************************************************
- Retreive a pointer to a specific value. Caller shoud dup the structure
- since this memory may go away with a regval_ctr_destroy()
- **********************************************************************/
-
-REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
-{
- if ( !(idx < ctr->num_values) )
- return NULL;
-
- return ctr->values[idx];
-}
-
-/***********************************************************************
- Retrive the TALLOC_CTX associated with a REGISTRY_VALUE
- **********************************************************************/
-
-TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
-{
- if ( !val )
- return NULL;
-
- return val->ctx;
-}
-
-/***********************************************************************
- Add a new registry value to the array
- **********************************************************************/
-
-int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type,
- const char *data_p, size_t size )
-{
- REGISTRY_VALUE **ppreg;
-
- if ( name )
- {
- /* allocate a slot in the array of pointers */
-
- if ( ctr->num_values == 0 )
- ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
- else {
- ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
- if ( ppreg )
- ctr->values = ppreg;
- }
-
- /* allocate a new value and store the pointer in the arrya */
-
- ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
-
- /* init the value */
-
- fstrcpy( ctr->values[ctr->num_values]->valuename, name );
- ctr->values[ctr->num_values]->type = type;
- ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, data_p, size );
- ctr->values[ctr->num_values]->size = size;
- ctr->num_values++;
- }
-
- return ctr->num_values;
-}
-
-/***********************************************************************
- Add a new registry value to the array
- **********************************************************************/
-
-int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
-{
- REGISTRY_VALUE **ppreg;
-
- if ( val )
- {
- /* allocate a slot in the array of pointers */
-
- if ( ctr->num_values == 0 )
- ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
- else {
- ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
- if ( ppreg )
- ctr->values = ppreg;
- }
-
- /* allocate a new value and store the pointer in the arrya */
-
- ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
-
- /* init the value */
-
- fstrcpy( ctr->values[ctr->num_values]->valuename, val->valuename );
- ctr->values[ctr->num_values]->type = val->type;
- ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, val->data_p, val->size );
- ctr->values[ctr->num_values]->size = val->size;
- ctr->num_values++;
- }
-
- return ctr->num_values;
-}
-
-/***********************************************************************
- Delete a single value from the registry container.
- No need to free memory since it is talloc'd.
- **********************************************************************/
-
-int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
-{
- int i;
-
- /* search for the value */
- if (!(ctr->num_values))
- return 0;
-
- for ( i=0; i<ctr->num_values; i++ ) {
- if ( strcmp( ctr->values[i]->valuename, name ) == 0)
- break;
- }
-
- /* just return if we don't find it */
-
- if ( i == ctr->num_values )
- return ctr->num_values;
-
- /* just shift everything down one */
-
- for ( /* use previous i */; i<(ctr->num_values-1); i++ )
- memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
-
- /* paranoia */
-
- ZERO_STRUCTP( ctr->values[i] );
-
- ctr->num_values--;
-
- return ctr->num_values;
-}
-
-/***********************************************************************
- Delete a single value from the registry container.
- No need to free memory since it is talloc'd.
- **********************************************************************/
-
-REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
-{
- int i;
-
- /* search for the value */
-
- for ( i=0; i<ctr->num_values; i++ ) {
- if ( strequal( ctr->values[i]->valuename, name ) )
- return ctr->values[i];
- }
-
- return NULL;
-}
-
-/***********************************************************************
- free memory held by a REGVAL_CTR structure
- **********************************************************************/
-
-void regval_ctr_destroy( REGVAL_CTR *ctr )
-{
- if ( ctr ) {
- talloc_destroy( ctr->ctx );
- ZERO_STRUCTP( ctr );
- }
-}
-
-
diff --git a/source/registry/reg_printing.c b/source/registry/reg_printing.c
deleted file mode 100644
index e50a5f4d4fd..00000000000
--- a/source/registry/reg_printing.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry virtual views for printing information */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-#define MAX_TOP_LEVEL_KEYS 3
-
-/* some symbolic indexes into the top_level_keys */
-
-#define KEY_INDEX_ENVIR 0
-#define KEY_INDEX_FORMS 1
-#define KEY_INDEX_PRINTER 2
-
-static const char *top_level_keys[MAX_TOP_LEVEL_KEYS] = {
- "Environments",
- "Forms",
- "Printers"
-};
-
-
-/**********************************************************************
- It is safe to assume that every registry path passed into on of
- the exported functions here begins with KEY_PRINTING else
- these functions would have never been called. This is a small utility
- function to strip the beginning of the path and make a copy that the
- caller can modify. Note that the caller is responsible for releasing
- the memory allocated here.
- **********************************************************************/
-
-static char* trim_reg_path( char *path )
-{
- char *p;
- uint16 key_len = strlen(KEY_PRINTING);
-
- /*
- * sanity check...this really should never be True.
- * It is only here to prevent us from accessing outside
- * the path buffer in the extreme case.
- */
-
- if ( strlen(path) < key_len ) {
- DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
- DEBUG(0,("trim_reg_path: KEY_PRINTING => [%s]!\n", KEY_PRINTING));
- return NULL;
- }
-
-
- p = path + strlen( KEY_PRINTING );
-
- if ( *p == '\\' )
- p++;
-
- if ( *p )
- return strdup(p);
- else
- return NULL;
-}
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Environments
- *********************************************************************/
-
-static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys )
-{
- const char *environments[] = {
- "Windows 4.0",
- "Windows NT x86",
- "Windows NT R4000",
- "Windows NT Alpha_AXP",
- "Windows NT PowerPC",
- NULL };
- fstring *drivers = NULL;
- int i, env_index, num_drivers;
- BOOL valid_env = False;
- char *base, *new_path;
- char *keystr;
- char *key2 = NULL;
- int num_subkeys = -1;
-
- DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" ));
-
- /* listed architectures of installed drivers */
-
- if ( !key )
- {
- /* Windows 9x drivers */
-
- if ( get_ntdrivers( &drivers, environments[0], 0 ) )
- regsubkey_ctr_addkey( subkeys, environments[0] );
- SAFE_FREE( drivers );
-
- /* Windows NT/2k intel drivers */
-
- if ( get_ntdrivers( &drivers, environments[1], 2 )
- || get_ntdrivers( &drivers, environments[1], 3 ) )
- {
- regsubkey_ctr_addkey( subkeys, environments[1] );
- }
- SAFE_FREE( drivers );
-
- /* Windows NT 4.0; non-intel drivers */
- for ( i=2; environments[i]; i++ ) {
- if ( get_ntdrivers( &drivers, environments[i], 2 ) )
- regsubkey_ctr_addkey( subkeys, environments[i] );
-
- }
- SAFE_FREE( drivers );
-
- num_subkeys = regsubkey_ctr_numkeys( subkeys );
- goto done;
- }
-
- /* we are dealing with a subkey of "Environments */
-
- key2 = strdup( key );
- keystr = key2;
- reg_split_path( keystr, &base, &new_path );
-
- /* sanity check */
-
- for ( env_index=0; environments[env_index]; env_index++ ) {
- if ( StrCaseCmp( environments[env_index], base ) == 0 ) {
- valid_env = True;
- break;
- }
- }
-
- if ( !valid_env )
- return -1;
-
- /* enumerate driver versions; environment is environments[env_index] */
-
- if ( !new_path ) {
- switch ( env_index ) {
- case 0: /* Win9x */
- if ( get_ntdrivers( &drivers, environments[0], 0 ) ) {
- regsubkey_ctr_addkey( subkeys, "0" );
- SAFE_FREE( drivers );
- }
- break;
- case 1: /* Windows NT/2k - intel */
- if ( get_ntdrivers( &drivers, environments[1], 2 ) ) {
- regsubkey_ctr_addkey( subkeys, "2" );
- SAFE_FREE( drivers );
- }
- if ( get_ntdrivers( &drivers, environments[1], 3 ) ) {
- regsubkey_ctr_addkey( subkeys, "3" );
- SAFE_FREE( drivers );
- }
- break;
- default: /* Windows NT - nonintel */
- if ( get_ntdrivers( &drivers, environments[env_index], 2 ) ) {
- regsubkey_ctr_addkey( subkeys, "2" );
- SAFE_FREE( drivers );
- }
-
- }
-
- num_subkeys = regsubkey_ctr_numkeys( subkeys );
- goto done;
- }
-
- /* we finally get to enumerate the drivers */
-
- keystr = new_path;
- reg_split_path( keystr, &base, &new_path );
-
- if ( !new_path ) {
- num_drivers = get_ntdrivers( &drivers, environments[env_index], atoi(base) );
- for ( i=0; i<num_drivers; i++ )
- regsubkey_ctr_addkey( subkeys, drivers[i] );
-
- num_subkeys = regsubkey_ctr_numkeys( subkeys );
- goto done;
- }
-
-done:
- SAFE_FREE( key2 );
-
- return num_subkeys;
-}
-
-/***********************************************************************
- simple function to prune a pathname down to the basename of a file
- **********************************************************************/
-
-static char* dos_basename ( char *path )
-{
- char *p;
-
- p = strrchr( path, '\\' );
- if ( p )
- p++;
- else
- p = path;
-
- return p;
-}
-
-/**********************************************************************
- handle enumeration of values below
- KEY_PRINTING\Environments\<arch>\<version>\<drivername>
- *********************************************************************/
-
-static int print_subpath_values_environments( char *key, REGVAL_CTR *val )
-{
- char *keystr;
- char *key2 = NULL;
- char *base, *new_path;
- fstring env;
- fstring driver;
- int version;
- NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr;
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
- WERROR w_result;
- char *buffer = NULL;
- char *buffer2 = NULL;
- int buffer_size = 0;
- int i, length;
- char *filename;
- UNISTR2 data;;
-
- DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL"));
-
- if ( !key )
- return 0;
-
- /*
- * The only key below KEY_PRINTING\Environments that
- * posseses values is each specific printer driver
- * First get the arch, version, & driver name
- */
-
- /* env */
-
- key2 = strdup( key );
- keystr = key2;
- reg_split_path( keystr, &base, &new_path );
- if ( !base || !new_path )
- return 0;
- fstrcpy( env, base );
-
- /* version */
-
- keystr = new_path;
- reg_split_path( keystr, &base, &new_path );
- if ( !base || !new_path )
- return 0;
- version = atoi( base );
-
- /* printer driver name */
-
- keystr = new_path;
- reg_split_path( keystr, &base, &new_path );
- /* new_path should be NULL here since this must be the last key */
- if ( !base || new_path )
- return 0;
- fstrcpy( driver, base );
-
- w_result = get_a_printer_driver( &driver_ctr, 3, driver, env, version );
-
- if ( !W_ERROR_IS_OK(w_result) )
- return -1;
-
- /* build the values out of the driver information */
- info3 = driver_ctr.info_3;
-
- filename = dos_basename( info3->driverpath );
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- filename = dos_basename( info3->configfile );
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Configuration File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- filename = dos_basename( info3->datafile );
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Data File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- filename = dos_basename( info3->helpfile );
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Help File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Data Type", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- regval_ctr_addvalue( val, "Version", REG_DWORD, (char*)&info3->cversion, sizeof(info3->cversion) );
-
- if ( info3->dependentfiles ) {
- /* place the list of dependent files in a single
- character buffer, separating each file name by
- a NULL */
-
- for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
- /* strip the path to only the file's base name */
-
- filename = dos_basename( info3->dependentfiles[i] );
-
- length = strlen(filename);
-
- buffer2 = Realloc( buffer, buffer_size + (length + 1)*sizeof(uint16) );
- if ( !buffer2 )
- break;
- buffer = buffer2;
-
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- buffer_size += (length + 1)*sizeof(uint16);
- }
-
- /* terminated by double NULL. Add the final one here */
-
- buffer2 = Realloc( buffer, buffer_size + 2 );
- if ( !buffer2 ) {
- SAFE_FREE( buffer );
- buffer_size = 0;
- } else {
- buffer = buffer2;
- buffer[buffer_size++] = '\0';
- buffer[buffer_size++] = '\0';
- }
- }
-
- regval_ctr_addvalue( val, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size );
-
- free_a_printer_driver( driver_ctr, 3 );
-
- SAFE_FREE( key2 );
- SAFE_FREE( buffer );
-
- DEBUG(8,("print_subpath_values_environments: Exit\n"));
-
- return regval_ctr_numvals( val );
-}
-
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Forms
- Really just a stub function, but left here in case it needs to
- be expanded later on
- *********************************************************************/
-
-static int print_subpath_forms( char *key, REGSUBKEY_CTR *subkeys )
-{
- DEBUG(10,("print_subpath_forms: key=>[%s]\n", key ? key : "NULL" ));
-
- /* there are no subkeys */
-
- if ( key )
- return -1;
-
- return 0;
-}
-
-/**********************************************************************
- handle enumeration of values below KEY_PRINTING\Forms
- *********************************************************************/
-
-static int print_subpath_values_forms( char *key, REGVAL_CTR *val )
-{
- int num_values = 0;
- uint32 data[8];
- int form_index = 1;
-
- DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
-
- /* handle ..\Forms\ */
-
- if ( !key )
- {
- nt_forms_struct *forms_list = NULL;
- nt_forms_struct *form = NULL;
- int i;
-
- if ( (num_values = get_ntforms( &forms_list )) == 0 )
- return 0;
-
- DEBUG(10,("print_subpath_values_forms: [%d] user defined forms returned\n",
- num_values));
-
- /* handle user defined forms */
-
- for ( i=0; i<num_values; i++ )
- {
- form = &forms_list[i];
-
- data[0] = form->width;
- data[1] = form->length;
- data[2] = form->left;
- data[3] = form->top;
- data[4] = form->right;
- data[5] = form->bottom;
- data[6] = form_index++;
- data[7] = form->flag;
-
- regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) );
-
- }
-
- SAFE_FREE( forms_list );
- forms_list = NULL;
-
- /* handle built-on forms */
-
- if ( (num_values = get_builtin_ntforms( &forms_list )) == 0 )
- return 0;
-
- DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
- num_values));
-
- for ( i=0; i<num_values; i++ )
- {
- form = &forms_list[i];
-
- data[0] = form->width;
- data[1] = form->length;
- data[2] = form->left;
- data[3] = form->top;
- data[4] = form->right;
- data[5] = form->bottom;
- data[6] = form_index++;
- data[7] = form->flag;
-
- regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) );
- }
-
- SAFE_FREE( forms_list );
- }
-
- return num_values;
-}
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Printers
- *********************************************************************/
-
-static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
-{
- int n_services = lp_numservices();
- int snum;
- fstring sname;
- int i;
- int num_subkeys = 0;
- char *keystr, *key2 = NULL;
- char *base, *new_path;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- fstring *subkey_names = NULL;
-
- DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
-
- if ( !key )
- {
- /* enumerate all printers */
-
- for (snum=0; snum<n_services; snum++) {
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
- continue;
-
- fstrcpy( sname, lp_servicename(snum) );
-
- regsubkey_ctr_addkey( subkeys, sname );
- }
-
- num_subkeys = regsubkey_ctr_numkeys( subkeys );
- goto done;
- }
-
- /* get information for a specific printer */
-
- key2 = strdup( key );
- keystr = key2;
- reg_split_path( keystr, &base, &new_path );
-
- if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
- goto done;
-
- num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names );
-
- for ( i=0; i<num_subkeys; i++ )
- regsubkey_ctr_addkey( subkeys, subkey_names[i] );
-
- free_a_printer( &printer, 2 );
-
- /* no other subkeys below here */
-
-done:
- SAFE_FREE( key2 );
- SAFE_FREE( subkey_names );
-
- return num_subkeys;
-}
-
-/**********************************************************************
- handle enumeration of values below KEY_PRINTING\Printers
- *********************************************************************/
-
-static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
-{
- int num_values = 0;
- char *keystr, *key2 = NULL;
- char *base, *new_path;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- NT_PRINTER_INFO_LEVEL_2 *info2;
- DEVICEMODE *devmode;
- prs_struct prs;
- uint32 offset;
- int snum;
- fstring printername;
- NT_PRINTER_DATA *p_data;
- int i, key_index;
- UNISTR2 data;
-
- /*
- * Theres are tw cases to deal with here
- * (1) enumeration of printer_info_2 values
- * (2) enumeration of the PrinterDriverData subney
- */
-
- if ( !key ) {
- /* top level key has no values */
- goto done;
- }
-
- key2 = strdup( key );
- keystr = key2;
- reg_split_path( keystr, &base, &new_path );
-
- fstrcpy( printername, base );
-
- if ( !new_path )
- {
- /* we are dealing with the printer itself */
-
- if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
- goto done;
-
- info2 = printer->info_2;
-
-
- regval_ctr_addvalue( val, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) );
- regval_ctr_addvalue( val, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) );
- regval_ctr_addvalue( val, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) );
- regval_ctr_addvalue( val, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
- regval_ctr_addvalue( val, "Status", REG_DWORD, (char*)&info2->status, sizeof(info2->status) );
- regval_ctr_addvalue( val, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) );
- regval_ctr_addvalue( val, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) );
- regval_ctr_addvalue( val, "cjobs", REG_DWORD, (char*)&info2->cjobs, sizeof(info2->cjobs) );
- regval_ctr_addvalue( val, "AveragePPM", REG_DWORD, (char*)&info2->averageppm, sizeof(info2->averageppm) );
-
- init_unistr2( &data, info2->printername, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Comment", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->servername, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Server", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Share", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
- init_unistr2( &data, "winprint", UNI_STR_TERMINATE);
- regval_ctr_addvalue( val, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-
- /* use a prs_struct for converting the devmode and security
- descriptor to REG_BIARY */
-
- prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(val), MARSHALL);
-
- /* stream the device mode */
-
- snum = lp_servicenumber(info2->sharename);
- if ( (devmode = construct_dev_mode( snum )) != NULL )
- {
- if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
-
- offset = prs_offset( &prs );
-
- regval_ctr_addvalue( val, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
- }
-
-
- }
-
- prs_mem_clear( &prs );
- prs_set_offset( &prs, 0 );
-
- if ( info2->secdesc_buf && info2->secdesc_buf->len )
- {
- if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) {
-
- offset = prs_offset( &prs );
-
- regval_ctr_addvalue( val, "Security", REG_BINARY, prs_data_p(&prs), offset );
- }
- }
-
- prs_mem_free( &prs );
-
- num_values = regval_ctr_numvals( val );
-
- goto done;
-
- }
-
- /* now enumerate the key */
-
- if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
- goto done;
-
- /* iterate over all printer data and fill the regval container */
-
- p_data = &printer->info_2->data;
- if ( (key_index = lookup_printerkey( p_data, new_path )) == -1 ) {
- DEBUG(10,("print_subpath_values_printer: Unknown keyname [%s]\n", new_path));
- goto done;
- }
-
- num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
-
- for ( i=0; i<num_values; i++ )
- regval_ctr_copyvalue( val, regval_ctr_specific_value(&p_data->keys[key_index].values, i) );
-
-
-done:
- if ( printer )
- free_a_printer( &printer, 2 );
-
- SAFE_FREE( key2 );
-
- return num_values;
-}
-
-/**********************************************************************
- Routine to handle enumeration of subkeys and values
- below KEY_PRINTING (depending on whether or not subkeys/val are
- valid pointers.
- *********************************************************************/
-
-static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CTR *val )
-{
- int result = 0;
- char *p, *base;
- int i;
-
- DEBUG(10,("handle_printing_subpath: key=>[%s]\n", key ));
-
- /*
- * break off the first part of the path
- * topmost base **must** be one of the strings
- * in top_level_keys[]
- */
-
- reg_split_path( key, &base, &p);
-
- for ( i=0; i<MAX_TOP_LEVEL_KEYS; i++ ) {
- if ( StrCaseCmp( top_level_keys[i], base ) == 0 )
- break;
- }
-
- DEBUG(10,("handle_printing_subpath: base=>[%s], i==[%d]\n", base, i));
-
- if ( !(i < MAX_TOP_LEVEL_KEYS) )
- return -1;
-
- /* Call routine to handle each top level key */
- switch ( i )
- {
- case KEY_INDEX_ENVIR:
- if ( subkeys )
- print_subpath_environments( p, subkeys );
- if ( val )
- print_subpath_values_environments( p, val );
- break;
-
- case KEY_INDEX_FORMS:
- if ( subkeys )
- print_subpath_forms( p, subkeys );
- if ( val )
- print_subpath_values_forms( p, val );
- break;
-
- case KEY_INDEX_PRINTER:
- if ( subkeys )
- print_subpath_printers( p, subkeys );
- if ( val )
- print_subpath_values_printers( p, val );
- break;
-
- /* default case for top level key that has no handler */
-
- default:
- break;
- }
-
-
-
- return result;
-
-}
-/**********************************************************************
- Enumerate registry subkey names given a registry path.
- Caller is responsible for freeing memory to **subkeys
- *********************************************************************/
-
-int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
-{
- char *path;
- BOOL top_level = False;
- int num_subkeys = 0;
-
- DEBUG(10,("printing_subkey_info: key=>[%s]\n", key));
-
- path = trim_reg_path( key );
-
- /* check to see if we are dealing with the top level key */
-
- if ( !path )
- top_level = True;
-
- if ( top_level ) {
- for ( num_subkeys=0; num_subkeys<MAX_TOP_LEVEL_KEYS; num_subkeys++ )
- regsubkey_ctr_addkey( subkey_ctr, top_level_keys[num_subkeys] );
- }
- else
- num_subkeys = handle_printing_subpath( path, subkey_ctr, NULL );
-
- SAFE_FREE( path );
-
- return num_subkeys;
-}
-
-/**********************************************************************
- Enumerate registry values given a registry path.
- Caller is responsible for freeing memory
- *********************************************************************/
-
-int printing_value_info( char *key, REGVAL_CTR *val )
-{
- char *path;
- BOOL top_level = False;
- int num_values = 0;
-
- DEBUG(10,("printing_value_info: key=>[%s]\n", key));
-
- path = trim_reg_path( key );
-
- /* check to see if we are dealing with the top level key */
-
- if ( !path )
- top_level = True;
-
- /* fill in values from the getprinterdata_printer_server() */
- if ( top_level )
- num_values = 0;
- else
- num_values = handle_printing_subpath( path, NULL, val );
-
-
- return num_values;
-}
-
-/**********************************************************************
- Stub function which always returns failure since we don't want
- people storing printing information directly via regostry calls
- (for now at least)
- *********************************************************************/
-
-BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
-{
- return False;
-}
-
-/**********************************************************************
- Stub function which always returns failure since we don't want
- people storing printing information directly via regostry calls
- (for now at least)
- *********************************************************************/
-
-BOOL printing_store_value( char *key, REGVAL_CTR *val )
-{
- return False;
-}
-
-/*
- * Table of function pointers for accessing printing data
- */
-
-REGISTRY_OPS printing_ops = {
- printing_subkey_info,
- printing_value_info,
- printing_store_subkey,
- printing_store_value
-};
-
-
diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c
deleted file mode 100644
index 09e63a47147..00000000000
--- a/source/rpc_client/cli_ds.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
- Copyright (C) Gerald Carter 2002,
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* implementations of client side DsXXX() functions */
-
-/********************************************************************
- Get information about the server and directory services
-********************************************************************/
-
-NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint16 level, DS_DOMINFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- DS_Q_GETPRIMDOMINFO q;
- DS_R_GETPRIMDOMINFO r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- q.level = level;
-
- if (!ds_io_q_getprimdominfo("", &qbuf, 0, &q)
- || !rpc_api_pipe_req(cli, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!ds_io_r_getprimdominfo("", &rbuf, 0, &r)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Return basic info - if we are requesting at info != 1 then
- there could be trouble. */
-
- result = r.status;
-
- if ( r.ptr && ctr ) {
- ctr->basic = talloc(mem_ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC));
- if (!ctr->basic)
- goto done;
- memcpy(ctr->basic, r.info.basic, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC));
- }
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/********************************************************************
- Enumerate trusted domains in an AD forest
-********************************************************************/
-
-NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *server, uint32 flags,
- struct ds_domain_trust **trusts, uint32 *num_domains)
-{
- prs_struct qbuf, rbuf;
- DS_Q_ENUM_DOM_TRUSTS q;
- DS_R_ENUM_DOM_TRUSTS r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- init_q_ds_enum_domain_trusts( &q, server, flags );
-
- if (!ds_io_q_enum_domain_trusts("", &qbuf, 0, &q)
- || !rpc_api_pipe_req(cli, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!ds_io_r_enum_domain_trusts("", &rbuf, 0, &r)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
-
- if ( NT_STATUS_IS_OK(result) ) {
- int i;
-
- *num_domains = r.num_domains;
- *trusts = (struct ds_domain_trust*)talloc(mem_ctx, r.num_domains*sizeof(**trusts));
-
- for ( i=0; i< *num_domains; i++ ) {
- (*trusts)[i].flags = r.domains.trusts[i].flags;
- (*trusts)[i].parent_index = r.domains.trusts[i].parent_index;
- (*trusts)[i].trust_type = r.domains.trusts[i].trust_type;
- (*trusts)[i].trust_attributes = r.domains.trusts[i].trust_attributes;
- (*trusts)[i].guid = r.domains.trusts[i].guid;
-
- if (r.domains.trusts[i].sid_ptr) {
- sid_copy(&(*trusts)[i].sid, &r.domains.trusts[i].sid.sid);
- } else {
- ZERO_STRUCT((*trusts)[i].sid);
- }
-
- if (r.domains.trusts[i].netbios_ptr) {
- (*trusts)[i].netbios_domain = unistr2_tdup( mem_ctx, &r.domains.trusts[i].netbios_domain );
- } else {
- (*trusts)[i].netbios_domain = NULL;
- }
-
- if (r.domains.trusts[i].dns_ptr) {
- (*trusts)[i].dns_domain = unistr2_tdup( mem_ctx, &r.domains.trusts[i].dns_domain );
- } else {
- (*trusts)[i].dns_domain = NULL;
- }
- }
- }
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-
diff --git a/source/rpc_client/cli_echo.c b/source/rpc_client/cli_echo.c
deleted file mode 100644
index 03a4ab36ee0..00000000000
--- a/source/rpc_client/cli_echo.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- RPC pipe client
-
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 request, uint32 *response)
-{
- prs_struct qbuf, rbuf;
- ECHO_Q_ADD_ONE q;
- ECHO_R_ADD_ONE r;
- BOOL result = False;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_echo_q_add_one(&q, request);
-
- if (!echo_io_q_add_one("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_ADD_ONE, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!echo_io_r_add_one("", &r, &rbuf, 0))
- goto done;
-
- if (response)
- *response = r.response;
-
- result = True;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 size, char *in_data, char **out_data)
-{
- prs_struct qbuf, rbuf;
- ECHO_Q_ECHO_DATA q;
- ECHO_R_ECHO_DATA r;
- BOOL result = False;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_echo_q_echo_data(&q, size, in_data);
-
- if (!echo_io_q_echo_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_DATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!echo_io_r_echo_data("", &r, &rbuf, 0))
- goto done;
-
- result = True;
-
- if (out_data) {
- *out_data = talloc(mem_ctx, size);
- memcpy(*out_data, r.data, size);
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 size, char *in_data)
-{
- prs_struct qbuf, rbuf;
- ECHO_Q_SINK_DATA q;
- ECHO_R_SINK_DATA r;
- BOOL result = False;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_echo_q_sink_data(&q, size, in_data);
-
- if (!echo_io_q_sink_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_SINK_DATA, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!echo_io_r_sink_data("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = True;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 size, char **out_data)
-{
- prs_struct qbuf, rbuf;
- ECHO_Q_SOURCE_DATA q;
- ECHO_R_SOURCE_DATA r;
- BOOL result = False;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_echo_q_source_data(&q, size);
-
- if (!echo_io_q_source_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_SOURCE_DATA, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!echo_io_r_source_data("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = True;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
diff --git a/source/rpc_client/cli_epmapper.c b/source/rpc_client/cli_epmapper.c
deleted file mode 100644
index 66362f16209..00000000000
--- a/source/rpc_client/cli_epmapper.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-NTSTATUS cli_epm_map(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- EPM_HANDLE *handle, EPM_TOWER **tower,
- EPM_HANDLE *entry_handle, uint32 *num_towers)
-{
- prs_struct qbuf, rbuf;
- EPM_Q_MAP q;
- EPM_R_MAP r;
- BOOL result = False;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_epm_q_map(mem_ctx, &q, *tower, *num_towers);
-
- if (!epm_io_q_map("map_query", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, EPM_MAP_PIPE_NAME, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!epm_io_r_map("map_reply", &r, &rbuf, 0))
- goto done;
-
- result = True;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
diff --git a/source/rpc_client/cli_login.c b/source/rpc_client/cli_login.c
new file mode 100755
index 00000000000..e5abca941be
--- /dev/null
+++ b/source/rpc_client/cli_login.c
@@ -0,0 +1,206 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Jeremy Allison 1999.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern fstring global_myworkgroup;
+extern pstring global_myname;
+
+/****************************************************************************
+Initialize domain session credentials.
+****************************************************************************/
+
+NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
+{
+ NTSTATUS result;
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+
+ UTIME zerotime;
+
+ /******************* Request Challenge ********************/
+
+ generate_random_buffer( clnt_chal.data, 8, False);
+
+ /* Send a client challenge; receive a server challenge */
+ if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal)) {
+ DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /**************** Long-term Session key **************/
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, (uchar *)mach_pwd, cli->sess_key);
+ memset((char *)cli->sess_key+8, '\0', 8);
+
+ /******************* Authenticate 2 ********************/
+
+ /* Calculate auth-2 credentials */
+ zerotime.time = 0;
+ cred_create(cli->sess_key, &clnt_chal, zerotime, &(cli->clnt_cred.challenge));
+
+ /*
+ * Send client auth-2 challenge.
+ * Receive an auth-2 challenge response and check it.
+ */
+
+ result = cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, &srv_chal);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
+ return result;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Set machine password.
+ ****************************************************************************/
+
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
+{
+ unsigned char processed_new_pwd[16];
+
+ DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__));
+
+#ifdef DEBUG_PASSWORD
+ dump_data(6, (char *)new_hashof_mach_pwd, 16);
+#endif
+
+ /* Process the new password. */
+ cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1);
+
+ /* Send client srv_pwset challenge */
+ return cli_net_srv_pwset(cli, processed_new_pwd);
+}
+
+/****************************************************************************
+NT login - interactive.
+*NEVER* use this code. This method of doing a logon (sending the cleartext
+password equivalents, protected by the session key) is inherently insecure
+given the current design of the NT Domain system. JRA.
+ ****************************************************************************/
+
+NTSTATUS cli_nt_login_interactive(struct cli_state *cli, char *unix_domain, char *unix_username,
+ uint32 smb_userid_low, char *unix_password,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+{
+ fstring dos_password, dos_username, dos_domain;
+ uchar lm_owf_user_pwd[16];
+ uchar nt_owf_user_pwd[16];
+ NTSTATUS ret;
+
+ DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+
+ fstrcpy(dos_password, unix_password);
+ unix_to_dos(dos_password);
+ fstrcpy(dos_username, unix_username);
+ unix_to_dos(dos_username);
+ fstrcpy(dos_domain, unix_domain);
+ unix_to_dos(dos_domain);
+
+ nt_lm_owf_gen(dos_password, nt_owf_user_pwd, lm_owf_user_pwd);
+
+#ifdef DEBUG_PASSWORD
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, (char *)lm_owf_user_pwd, 16);
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, (char *)nt_owf_user_pwd, 16);
+
+#endif
+
+ DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+
+ /* indicate an "interactive" login */
+ ctr->switch_value = INTERACTIVE_LOGON_TYPE;
+
+ /* Create the structure needed for SAM logon. */
+ init_id_info1(&ctr->auth.id1, dos_domain, 0,
+ smb_userid_low, 0,
+ dos_username, cli->clnt_name_slash,
+ (char *)cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+
+ /* Ensure we overwrite all the plaintext password equivalents. */
+ memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
+ memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
+
+ /* Send client sam-logon request - update credentials on success. */
+ ret = cli_net_sam_logon(cli, ctr, user_info3);
+
+ memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
+ memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
+
+ return ret;
+}
+
+/****************************************************************************
+NT login - network.
+*ALWAYS* use this call to validate a user as it does not expose plaintext
+password equivalents over the network. JRA.
+****************************************************************************/
+
+NTSTATUS cli_nt_login_network(struct cli_state *cli, char *unix_domain, char *unix_username,
+ uint32 smb_userid_low, const char lm_chal[8],
+ const char *lm_chal_resp, const char *nt_chal_resp,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+{
+ fstring dos_wksta_name, dos_username, dos_domain;
+ DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
+ /* indicate a "network" login */
+ ctr->switch_value = NET_LOGON_TYPE;
+
+ fstrcpy(dos_wksta_name, cli->clnt_name_slash);
+ unix_to_dos(dos_wksta_name);
+
+ fstrcpy(dos_username, unix_username);
+ unix_to_dos(dos_username);
+
+ fstrcpy(dos_domain, unix_domain);
+ unix_to_dos(dos_domain);
+
+ /* Create the structure needed for SAM logon. */
+ init_id_info2(&ctr->auth.id2, dos_domain, 0, smb_userid_low, 0,
+ dos_username, dos_wksta_name,
+ (const uchar *)lm_chal, (const uchar *)lm_chal_resp, lm_chal_resp ? 24 : 0,
+ (const uchar *)nt_chal_resp, nt_chal_resp ? 24 : 0 );
+
+ /* Send client sam-logon request - update credentials on success. */
+ return cli_net_sam_logon(cli, ctr, user_info3);
+}
+
+/****************************************************************************
+NT Logoff.
+****************************************************************************/
+
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
+{
+ DEBUG(5,("cli_nt_logoff: %d\n", __LINE__));
+
+ /* Send client sam-logoff request - update credentials on success. */
+ return cli_net_sam_logoff(cli, ctr);
+}
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index f6d88a19501..df77080425a 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -1,802 +1,541 @@
/*
- Unix SMB/CIFS implementation.
- NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Tim Potter 2001
- Copyright (C) Paul Ashton 1997.
- Copyright (C) Jeremy Allison 1998.
- Copyright (C) Andrew Bartlett 2001.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
#include "includes.h"
-/* LSA Request Challenge. Sends our challenge to server, then gets
- server response. These are used to generate the credentials. */
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
+/****************************************************************************
+Generate the next creds to use.
+****************************************************************************/
-NTSTATUS cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
- DOM_CHAL *srv_chal)
+static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
{
- prs_struct qbuf, rbuf;
- NET_Q_REQ_CHAL q;
- NET_R_REQ_CHAL r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_REQCHAL */
-
- DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
- global_myname(), cli->desthost, credstr(clnt_chal->data)));
-
- /* store the parameters */
- init_q_req_chal(&q, cli->srv_name_slash, global_myname(), clnt_chal);
-
- /* Marshall data and send request */
-
- if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarhall response */
-
- if (!net_io_r_req_chal("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = r.status;
-
- /* Return result */
-
- if (NT_STATUS_IS_OK(result)) {
- memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data));
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ /*
+ * Create the new client credentials.
+ */
+
+ cli->clnt_cred.timestamp.time = time(NULL);
+
+ memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
+
+ /* Calculate the new credentials. */
+ cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
+ new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
+
}
+#if UNUSED_CODE
/****************************************************************************
-LSA Authenticate 2
-
-Send the client credential, receive back a server credential.
-Ensure that the server credential returned matches the session key
-encrypt of the server challenge originally received. JRA.
+do a LSA Logon Control2
****************************************************************************/
-
-NTSTATUS cli_net_auth2(struct cli_state *cli,
- uint16 sec_chan,
- uint32 *neg_flags, DOM_CHAL *srv_chal)
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, NTSTATUS status_level)
{
- prs_struct qbuf, rbuf;
- NET_Q_AUTH_2 q;
- NET_R_AUTH_2 r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_AUTH2 */
-
- DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname(),
- credstr(cli->clnt_cred.challenge.data), *neg_flags));
-
- /* store the parameters */
- init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct,
- sec_chan, global_myname(), &cli->clnt_cred.challenge,
- *neg_flags);
-
- /* turn parameters into data stream */
-
- if (!net_io_q_auth_2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_auth_2("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = r.status;
-
- if (NT_STATUS_IS_OK(result)) {
- UTIME zerotime;
-
- /*
- * Check the returned value using the initial
- * server received challenge.
- */
-
- zerotime.time = 0;
- if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal,
- zerotime) == 0) {
-
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- result = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
- *neg_flags = r.srv_flgs.neg_flags;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_LOGON_CTRL2 q_l;
+ BOOL ok = False;
+
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
+
+ DEBUG(4,("do_net_logon_ctrl2 from %s status level:%x\n",
+ global_myname, status_level));
+
+ /* store the parameters */
+ init_q_logon_ctrl2(&q_l, unix_to_dos_static(cli->srv_name_slash),
+ status_level);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_logon_ctrl2("", &q_l, &buf, 0)) {
+ DEBUG(0,("cli_net_logon_ctrl2: Error : failed to marshall NET_Q_LOGON_CTRL2 struct.\n"));
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf))
+ {
+ NET_R_LOGON_CTRL2 r_l;
+
+ /*
+ * Unmarshall the return buffer.
+ */
+ ok = net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
+
+ if (ok && r_l.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("do_net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status)));
+ cli->nt_error = r_l.status;
+ ok = False;
+ }
+ }
+
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+
+ return ok;
}
+#endif
/****************************************************************************
-LSA Authenticate 3
+LSA Authenticate 2
Send the client credential, receive back a server credential.
Ensure that the server credential returned matches the session key
encrypt of the server challenge originally received. JRA.
****************************************************************************/
-NTSTATUS cli_net_auth3(struct cli_state *cli,
- uint16 sec_chan,
- uint32 *neg_flags, DOM_CHAL *srv_chal)
+NTSTATUS cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal)
{
- prs_struct qbuf, rbuf;
- NET_Q_AUTH_3 q;
- NET_R_AUTH_3 r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_AUTH2 */
-
- DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname(),
- credstr(cli->clnt_cred.challenge.data), *neg_flags));
-
- /* store the parameters */
- init_q_auth_3(&q, cli->srv_name_slash, cli->mach_acct,
- sec_chan, global_myname(), &cli->clnt_cred.challenge,
- *neg_flags);
-
- /* turn parameters into data stream */
-
- if (!net_io_q_auth_3("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_AUTH3, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_auth_3("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = r.status;
-
- if (NT_STATUS_IS_OK(result)) {
- UTIME zerotime;
-
- /*
- * Check the returned value using the initial
- * server received challenge.
- */
-
- zerotime.time = 0;
- if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal,
- zerotime) == 0) {
-
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_auth3: server %s replied with bad credential (bad machine \
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_AUTH_2 q_a;
+ BOOL ok = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_AUTH2 */
+
+ DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
+ cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
+ credstr(cli->clnt_cred.challenge.data), neg_flags));
+
+ /* store the parameters */
+ init_q_auth_2(&q_a, unix_to_dos_static(cli->srv_name_slash), cli->mach_acct,
+ sec_chan, global_myname, &cli->clnt_cred.challenge, neg_flags);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_auth_2("", &q_a, &buf, 0)) {
+ DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n"));
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return result;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf))
+ {
+ NET_R_AUTH_2 r_a;
+
+ ok = net_io_r_auth_2("", &r_a, &rbuf, 0);
+ result = r_a.status;
+
+ if (ok && !NT_STATUS_IS_OK(result))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(result)));
+ ok = False;
+ }
+
+ if (ok)
+ {
+ /*
+ * Check the returned value using the initial
+ * server received challenge.
+ */
+ UTIME zerotime;
+
+ zerotime.time = 0;
+ if(cred_assert( &r_a.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
password ?).\n", cli->desthost ));
- result = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
- *neg_flags = r.srv_flgs.neg_flags;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ ok = False;
+ }
+ }
+
+#if 0
+ /*
+ * Try commenting this out to see if this makes the connect
+ * work for a NT 3.51 PDC. JRA.
+ */
+
+ if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
+ {
+ /* report different neg_flags */
+ DEBUG(0,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n",
+ q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
+ ok = False;
+ }
+#endif
+
+ }
+
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+
+ return result;
}
-/* Initialize domain session credentials */
+/****************************************************************************
+LSA Request Challenge. Sends our challenge to server, then gets
+server response. These are used to generate the credentials.
+****************************************************************************/
-NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
- uint16 sec_chan,
- const unsigned char mach_pwd[16], uint32 *neg_flags, int level)
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
{
- DOM_CHAL clnt_chal;
- DOM_CHAL srv_chal;
- UTIME zerotime;
- NTSTATUS result;
-
- /******************* Request Challenge ********************/
-
- generate_random_buffer(clnt_chal.data, 8, False);
-
- /* send a client challenge; receive a server challenge */
- result = cli_net_req_chal(cli, &clnt_chal, &srv_chal);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
- return result;
- }
-
- /**************** Long-term Session key **************/
-
- /* calculate the session key */
- cred_session_key(&clnt_chal, &srv_chal, mach_pwd,
- cli->sess_key);
- memset((char *)cli->sess_key+8, '\0', 8);
-
- /******************* Authenticate 2/3 ********************/
-
- /* calculate auth-2/3 credentials */
- zerotime.time = 0;
- cred_create(cli->sess_key, &clnt_chal, zerotime, &cli->clnt_cred.challenge);
-
- /*
- * Send client auth-2/3 challenge.
- * Receive an auth-2/3 challenge response and check it.
- */
- switch (level) {
- case 2:
- result = cli_net_auth2(cli, sec_chan, neg_flags, &srv_chal);
- break;
- case 3:
- result = cli_net_auth3(cli, sec_chan, neg_flags, &srv_chal);
- break;
- default:
- DEBUG(1,("cli_nt_setup_creds: unsupported auth level: %d\n", level));
- break;
- }
-
- if (!NT_STATUS_IS_OK(result))
- DEBUG(3,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result)));
-
- return result;
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_REQ_CHAL q_c;
+ BOOL valid_chal = False;
+
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_REQCHAL */
+
+ DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
+ cli->desthost, global_myname, credstr(clnt_chal->data)));
+
+ /* store the parameters */
+ init_q_req_chal(&q_c, unix_to_dos_static(cli->srv_name_slash),
+ global_myname, clnt_chal);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_req_chal("", &q_c, &buf, 0)) {
+ DEBUG(0,("cli_net_req_chal: Error : failed to marshall NET_Q_REQ_CHAL struct.\n"));
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf))
+ {
+ NET_R_REQ_CHAL r_c;
+ BOOL ok;
+
+ ok = net_io_r_req_chal("", &r_c, &rbuf, 0);
+
+ if (ok && !NT_STATUS_IS_OK(r_c.status))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
+ ok = False;
+ }
+
+ if (ok)
+ {
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
+ valid_chal = True;
+ }
+ }
+
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+
+ return valid_chal;
}
-/* Logon Control 2 */
+/***************************************************************************
+LSA Server Password Set.
+****************************************************************************/
-NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 query_level)
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
{
- prs_struct qbuf, rbuf;
- NET_Q_LOGON_CTRL2 q;
- NET_R_LOGON_CTRL2 r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level);
-
- /* Marshall data and send request */
-
- if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
+ prs_struct rbuf;
+ prs_struct buf;
+ DOM_CRED new_clnt_cred;
+ NET_Q_SRV_PWSET q_s;
+ BOOL ok = False;
+ uint16 sec_chan_type = 2;
+
+ gen_next_creds( cli, &new_clnt_cred);
+
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_SRV_PWSET */
+
+ DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
+ cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
+ credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
+
+ /* store the parameters */
+ init_q_srv_pwset(&q_s, unix_to_dos_static(cli->srv_name_slash),
+ cli->mach_acct, sec_chan_type, global_myname,
+ &new_clnt_cred, (char *)hashed_mach_pwd);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
+ {
+ NET_R_SRV_PWSET r_s;
+
+ ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
+
+ if (ok && !NT_STATUS_IS_OK(r_s.status))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
+ ok = False;
+ }
+
+ /* Update the credentials. */
+ if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
+ {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+ ok = False;
+ }
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
- return result;
+ return ok;
}
-/* GetDCName */
+/***************************************************************************
+ LSA SAM Logon internal - interactive or network. Does level 2 or 3 but always
+ returns level 3.
+****************************************************************************/
-NTSTATUS cli_netlogon_getdcname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *domainname, fstring dcname)
+static NTSTATUS cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3,
+ uint16 validation_level)
{
- prs_struct qbuf, rbuf;
- NET_Q_GETDCNAME q;
- NET_R_GETDCNAME r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED new_clnt_cred;
+ DOM_CRED dummy_rtn_creds;
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_SAM_LOGON q_s;
+ NET_R_SAM_LOGON r_s;
+ NTSTATUS retval = NT_STATUS_OK;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ gen_next_creds( cli, &new_clnt_cred);
- /* Initialise parse structures */
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ /* create and send a MSRPC command with api NET_SAMLOGON */
- /* Initialise input parameters */
+ DEBUG(4,("cli_net_sam_logon_internal: srv:%s mc:%s clnt %s %x ll: %d\n",
+ cli->srv_name_slash, global_myname,
+ credstr(new_clnt_cred.challenge.data), cli->clnt_cred.timestamp.time,
+ ctr->switch_value));
- init_net_q_getdcname(&q, cli->srv_name_slash, domainname);
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
+ dummy_rtn_creds.timestamp.time = time(NULL);
- /* Marshall data and send request */
+ /* store the parameters */
+ q_s.validation_level = validation_level;
+ init_sam_info(&q_s.sam_id, unix_to_dos_static(cli->srv_name_slash),
+ global_myname, &new_clnt_cred, &dummy_rtn_creds,
+ ctr->switch_value, ctr);
- if (!net_io_q_getdcname("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_GETDCNAME, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ /* turn parameters into data stream */
+ if(!net_io_q_sam_logon("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_net_sam_logon_internal: Error : failed to marshall NET_Q_SAM_LOGON struct.\n"));
+ retval = NT_STATUS_NO_MEMORY;
+ goto out;
}
- /* Unmarshall response */
-
- if (!net_io_r_getdcname("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf)) {
+ DEBUG(0,("cli_net_sam_logon_internal: Error rpc_api_pipe_req failed.\n"));
+ retval = NT_STATUS_UNSUCCESSFUL;
+ goto out;
}
- result = r.status;
-
- if (NT_STATUS_IS_OK(result))
- rpcstr_pull_unistr2_fstring(dcname, &r.uni_dcname);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
+ r_s.user = user_info3;
-/****************************************************************************
-Generate the next creds to use.
-****************************************************************************/
+ if(!net_io_r_sam_logon("", &r_s, &rbuf, 0)) {
+ DEBUG(0,("cli_net_sam_logon_internal: Error : failed to unmarshal NET_R_SAM_LOGON struct.\n"));
+ retval = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ retval = r_s.status;
-static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
-{
/*
- * Create the new client credentials.
+ * Don't treat NT_STATUS_INVALID_INFO_CLASS as an error - we will re-issue
+ * the call.
*/
- cli->clnt_cred.timestamp.time = time(NULL);
-
- memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
-
- /* Calculate the new credentials. */
- cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
- new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
-}
-
-/* Sam synchronisation */
-
-NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds,
- uint32 database_id, uint32 next_rid, uint32 *num_deltas,
- SAM_DELTA_HDR **hdr_deltas,
- SAM_DELTA_CTR **deltas)
-{
- prs_struct qbuf, rbuf;
- NET_Q_SAM_SYNC q;
- NET_R_SAM_SYNC r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED clnt_creds;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- gen_next_creds(cli, &clnt_creds);
-
- init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2,
- &clnt_creds, ret_creds, database_id, next_rid);
-
- /* Marshall data and send request */
-
- if (!net_io_q_sam_sync("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ if (NT_STATUS_V(retval) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
+ goto out;
}
- /* Return results */
+ if (!NT_STATUS_IS_OK(retval)) {
+ /* report error code */
+ DEBUG(0,("cli_net_sam_logon_internal: %s\n", get_nt_error_msg(r_s.status)));
+ goto out;
+ }
+
+ /* Update the credentials. */
+ if (!clnt_deal_with_creds(cli->sess_key, &cli->clnt_cred, &r_s.srv_creds)) {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_sam_logon_internal: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+ retval = NT_STATUS_WRONG_PASSWORD;
+ }
- result = r.status;
- *num_deltas = r.num_deltas2;
- *hdr_deltas = r.hdr_deltas;
- *deltas = r.deltas;
+ if (r_s.switch_value != validation_level) {
+ /* report different switch_value */
+ DEBUG(0,("cli_net_sam_logon: switch_value of %x expected %x\n", (unsigned int)validation_level,
+ (unsigned int)r_s.switch_value));
+ retval = NT_STATUS_INVALID_PARAMETER;
+ }
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
+ out:
- done:
- prs_mem_free(&qbuf);
+ prs_mem_free(&buf);
prs_mem_free(&rbuf);
- return result;
+ return retval;
}
-/* Sam synchronisation */
+/***************************************************************************
+LSA SAM Logon - interactive or network.
+****************************************************************************/
-NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 database_id, UINT64_S seqnum,
- uint32 *num_deltas,
- SAM_DELTA_HDR **hdr_deltas,
- SAM_DELTA_CTR **deltas)
+NTSTATUS cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
{
- prs_struct qbuf, rbuf;
- NET_Q_SAM_DELTAS q;
- NET_R_SAM_DELTAS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED clnt_creds;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
+ uint16 validation_level=3;
+ NTSTATUS result;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
- /* Initialise input parameters */
+ if (NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("cli_net_sam_logon: Success \n"));
+ } else if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
+ DEBUG(10,("cli_net_sam_logon: STATUS INVALID INFO CLASS \n"));
- gen_next_creds(cli, &clnt_creds);
+ validation_level=2;
- init_net_q_sam_deltas(&q, cli->srv_name_slash,
- cli->clnt_name_slash + 2, &clnt_creds,
- database_id, seqnum);
+ /*
+ * Since this is the second time we call this function, don't care
+ * for the error. If its error, return False.
+ */
- /* Marshall data and send request */
-
- if (!net_io_q_sam_deltas("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
}
- /* Unmarshall response */
-
- if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Return results */
-
- result = r.status;
- *num_deltas = r.num_deltas2;
- *hdr_deltas = r.hdr_deltas;
- *deltas = r.deltas;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-/* Logon domain user */
-
-NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- DOM_CRED *ret_creds,
- const char *username, const char *password,
- int logon_type)
-{
- prs_struct qbuf, rbuf;
- NET_Q_SAM_LOGON q;
- NET_R_SAM_LOGON r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED clnt_creds, dummy_rtn_creds;
- NET_ID_INFO_CTR ctr;
- NET_USER_INFO_3 user;
- int validation_level = 3;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
- ZERO_STRUCT(dummy_rtn_creds);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- gen_next_creds(cli, &clnt_creds);
-
- q.validation_level = validation_level;
-
- if (ret_creds == NULL)
- ret_creds = &dummy_rtn_creds;
-
- ctr.switch_value = logon_type;
-
- switch (logon_type) {
- case INTERACTIVE_LOGON_TYPE: {
- unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
-
- nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
-
- init_id_info1(&ctr.auth.id1, lp_workgroup(),
- 0, /* param_ctrl */
- 0xdead, 0xbeef, /* LUID? */
- username, cli->clnt_name_slash,
- (const char *)cli->sess_key, lm_owf_user_pwd,
- nt_owf_user_pwd);
-
- break;
- }
- case NET_LOGON_TYPE: {
- uint8 chal[8];
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
-
- generate_random_buffer(chal, 8, False);
-
- SMBencrypt(password, chal, local_lm_response);
- SMBNTencrypt(password, chal, local_nt_response);
-
- init_id_info2(&ctr.auth.id2, lp_workgroup(),
- 0, /* param_ctrl */
- 0xdead, 0xbeef, /* LUID? */
- username, cli->clnt_name_slash, chal,
- local_lm_response, 24, local_nt_response, 24);
- break;
- }
- default:
- DEBUG(0, ("switch value %d not supported\n",
- ctr.switch_value));
- goto done;
- }
-
- init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
- &clnt_creds, ret_creds, logon_type,
- &ctr);
-
- /* Marshall data and send request */
-
- if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- r.user = &user;
-
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- goto done;
- }
-
- /* Return results */
-
- result = r.status;
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-
-/**
- * Logon domain user with an 'network' SAM logon
- *
- * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
- **/
-
-NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- DOM_CRED *ret_creds,
- const char *username, const char *domain, const char *workstation,
- const uint8 chal[8],
- DATA_BLOB lm_response, DATA_BLOB nt_response,
- NET_USER_INFO_3 *info3)
+/***************************************************************************
+LSA SAM Logoff.
+This currently doesnt work correctly as the domain controller
+returns NT_STATUS_INVALID_INFO_CLASS - we obviously need to
+send a different info level. Right now though, I'm not sure
+what that needs to be (I need to see one on the wire before
+I can be sure). JRA.
+****************************************************************************/
+BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
{
- prs_struct qbuf, rbuf;
- NET_Q_SAM_LOGON q;
- NET_R_SAM_LOGON r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED clnt_creds, dummy_rtn_creds;
- NET_ID_INFO_CTR ctr;
- int validation_level = 3;
- char *workstation_name_slash;
- uint8 netlogon_sess_key[16];
- static uint8 zeros[16];
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
- ZERO_STRUCT(dummy_rtn_creds);
-
- workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
-
- if (!workstation_name_slash) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ DOM_CRED new_clnt_cred;
+ DOM_CRED dummy_rtn_creds;
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_SAM_LOGOFF q_s;
+ BOOL ok = False;
- /* Initialise parse structures */
+ gen_next_creds( cli, &new_clnt_cred);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
- /* Initialise input parameters */
+ /* create and send a MSRPC command with api NET_SAMLOGOFF */
- gen_next_creds(cli, &clnt_creds);
+ DEBUG(4,("cli_net_sam_logoff: srv:%s mc:%s clnt %s %x ll: %d\n",
+ cli->srv_name_slash, global_myname,
+ credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time,
+ ctr->switch_value));
- q.validation_level = validation_level;
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
- if (ret_creds == NULL)
- ret_creds = &dummy_rtn_creds;
+ init_sam_info(&q_s.sam_id, unix_to_dos_static(cli->srv_name_slash),
+ global_myname, &new_clnt_cred, &dummy_rtn_creds,
+ ctr->switch_value, ctr);
- ctr.switch_value = NET_LOGON_TYPE;
+ /* turn parameters into data stream */
+ if(!net_io_q_sam_logoff("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_net_sam_logoff: Error : failed to marshall NET_Q_SAM_LOGOFF struct.\n"));
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
- init_id_info2(&ctr.auth.id2, domain,
- 0, /* param_ctrl */
- 0xdead, 0xbeef, /* LUID? */
- username, workstation_name_slash, (const uchar*)chal,
- lm_response.data, lm_response.length, nt_response.data, nt_response.length);
-
- init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
- &clnt_creds, ret_creds, NET_LOGON_TYPE,
- &ctr);
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
+ {
+ NET_R_SAM_LOGOFF r_s;
- /* Marshall data and send request */
-
- if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- r.user = info3;
-
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- goto done;
- }
-
- ZERO_STRUCT(netlogon_sess_key);
- memcpy(netlogon_sess_key, cli->sess_key, 8);
-
- if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
- SamOEMhash(info3->user_sess_key, netlogon_sess_key, 16);
- } else {
- memset(info3->user_sess_key, '\0', 16);
- }
-
- if (memcmp(zeros, info3->padding, 16) != 0) {
- SamOEMhash(info3->padding, netlogon_sess_key, 16);
- } else {
- memset(info3->padding, '\0', 16);
- }
-
- /* Return results */
-
- result = r.status;
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/***************************************************************************
-LSA Server Password Set.
-****************************************************************************/
-
-NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *machine_name, uint8 hashed_mach_pwd[16])
-{
- prs_struct rbuf;
- prs_struct qbuf;
- DOM_CRED new_clnt_cred;
- NET_Q_SRV_PWSET q_s;
- uint16 sec_chan_type = 2;
- NTSTATUS nt_status;
-
- gen_next_creds( cli, &new_clnt_cred);
-
- prs_init(&qbuf , 1024, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan_type, machine_name,
- credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
-
- /* store the parameters */
- init_q_srv_pwset(&q_s, cli->srv_name_slash, (const char *)cli->sess_key,
- cli->mach_acct, sec_chan_type, machine_name,
- &new_clnt_cred, hashed_mach_pwd);
-
- /* turn parameters into data stream */
- if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) {
- DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf))
- {
- NET_R_SRV_PWSET r_s;
-
- if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0);
- nt_status = r_s.status;
-
- if (!NT_STATUS_IS_OK(r_s.status))
- {
- /* report error code */
- DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status)));
- goto done;
- }
-
- /* Update the credentials. */
- if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
- {
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+ if (ok && !NT_STATUS_IS_OK(r_s.status))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
+ ok = False;
+ }
+
+ /* Update the credentials. */
+ if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
+ {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \
password ?).\n", cli->desthost ));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
- }
+ ok = False;
+ }
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return nt_status;
-}
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return ok;
+}
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index df0d37a4631..782119f0643 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1998.
* Copyright (C) Jeremy Allison 1999.
- * Copyright (C) Andrew Bartlett 2003.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,29 +24,9 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_CLI
-
extern struct pipe_id_info pipe_names[];
-
-/* convert pipe auth flags into the RPC auth type and level */
-
-void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level)
-{
- *auth_type = 0;
- *auth_level = 0;
- if (pipe_auth_flags & AUTH_PIPE_SEAL) {
- *auth_level = RPC_PIPE_AUTH_SEAL_LEVEL;
- } else if (pipe_auth_flags & AUTH_PIPE_SIGN) {
- *auth_level = RPC_PIPE_AUTH_SIGN_LEVEL;
- }
-
- if (pipe_auth_flags & AUTH_PIPE_NETSEC) {
- *auth_type = NETSEC_AUTH_TYPE;
- } else if (pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- *auth_type = NTLMSSP_AUTH_TYPE;
- }
-}
+extern fstring global_myworkgroup;
+extern pstring global_myname;
/********************************************************************
Rpc pipe call id.
@@ -100,13 +80,13 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re
DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
num_read, stream_offset, data_to_read));
- if (cli_is_dos_error(cli)) {
- cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRDOS && ecode != ERRmoredata) {
+ if (cli_is_dos_error(cli)) {
+ cli_dos_error(cli, &eclass, &ecode);
+ if (eclass != ERRDOS && ecode != ERRmoredata) {
DEBUG(0,("rpc_read: Error %d/%u in cli_read\n",
eclass, (unsigned int)ecode));
- return False;
- }
+ return False;
+ }
}
data_to_read -= num_read;
@@ -152,6 +132,32 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
return (rhdr->pkt_type != RPC_FAULT);
}
+static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 len)
+{
+ unsigned char *hash = cli->ntlmssp_hash;
+ unsigned char index_i = hash[256];
+ unsigned char index_j = hash[257];
+ int ind;
+
+ for( ind = 0; ind < len; ind++) {
+ unsigned char tc;
+ unsigned char t;
+
+ index_i++;
+ index_j += hash[index_i];
+
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
+
+ t = hash[index_i] + hash[index_j];
+ data[ind] = data[ind] ^ hash[t];
+ }
+
+ hash[256] = index_i;
+ hash[257] = index_j;
+}
+
/****************************************************************************
Verify data on an rpc pipe.
The VERIFY & SEAL code is only executed on packets that look like this :
@@ -168,11 +174,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
Never on bind requests/responses.
****************************************************************************/
-static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
- uint32 fragment_start, int len, int auth_len, uint8 pkt_type,
- int *pauth_padding_len)
+static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len)
{
-
/*
* The following is that length of the data we must sign or seal.
* This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
@@ -184,183 +187,118 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
/*
* The start of the data to sign/seal is just after the RPC headers.
*/
- char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
+ char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
- RPC_HDR_AUTH rhdr_auth;
+ BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0);
- char *dp = prs_data_p(rdata) + fragment_start + len -
- RPC_HDR_AUTH_LEN - auth_len;
- prs_struct auth_verf;
+ DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
+ len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
- *pauth_padding_len = 0;
-
- if (auth_len == 0) {
- if (cli->pipe_auth_flags == 0) {
- /* move along, nothing to see here */
- return True;
- }
-
- DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n"));
- return False;
- }
-
- DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n",
- pkt_type, len, auth_len,
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL)));
+ /*
+ * Unseal any sealed data in the PDU, not including the
+ * 8 byte auth_header or the auth_data.
+ */
- if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
- DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
- return False;
+ if (auth_seal) {
+ DEBUG(10,("rpc_auth_pipe: unseal\n"));
+ dump_data(100, reply_data, data_len);
+ NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
+ dump_data(100, reply_data, data_len);
}
- DEBUG(10,("rpc_auth_pipe: packet:\n"));
- dump_data(100, dp, auth_len);
-
- prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* The endinness must be preserved. JRA. */
- prs_set_endian_data( &auth_verf, rdata->bigendian_data);
-
- /* Point this new parse struct at the auth section of the main
- parse struct - rather than copying it. Avoids needing to
- free it on every error
- */
- prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */);
- prs_set_offset(&auth_verf, 0);
+ if (auth_verify || auth_seal) {
+ RPC_HDR_AUTH rhdr_auth;
+ prs_struct auth_req;
+ char data[RPC_HDR_AUTH_LEN];
+ /*
+ * We set dp to be the end of the packet, minus the auth_len
+ * and the length of the header that preceeds the auth_data.
+ */
+ char *dp = prs_data_p(rdata) + len - auth_len - RPC_HDR_AUTH_LEN;
- {
- int auth_type;
- int auth_level;
- if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
- DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n"));
+ if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+ DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
return False;
}
- /* Let the caller know how much padding at the end of the data */
- *pauth_padding_len = rhdr_auth.padding;
-
- /* Check it's the type of reply we were expecting to decode */
-
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
- if (rhdr_auth.auth_type != auth_type) {
- DEBUG(0, ("BAD auth type %d (should be %d)\n",
- rhdr_auth.auth_type, auth_type));
- return False;
- }
+ memcpy(data, dp, sizeof(data));
- if (rhdr_auth.auth_level != auth_level) {
- DEBUG(0, ("BAD auth level %d (should be %d)\n",
- rhdr_auth.auth_level, auth_level));
- return False;
- }
- }
+ prs_init(&auth_req , 0, cli->mem_ctx, UNMARSHALL);
- if (pkt_type == RPC_BINDACK) {
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- /* copy the next auth_len bytes into a buffer for
- later use */
+ /* The endianness must be preserved... JRA. */
- DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
- BOOL store_ok;
+ prs_set_endian_data(&auth_req, rdata->bigendian_data);
- /* save the reply away, for use a little later */
- prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
+ prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False);
- store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state,
- ntlmssp_verf)));
-
- data_blob_free(&ntlmssp_verf);
- return store_ok;
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- /* nothing to do here - we don't seem to be able to
- validate the bindack based on VL's comments */
- return True;
- }
- }
-
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- NTSTATUS nt_status;
- DATA_BLOB sig;
- if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) ||
- (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) {
- if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) {
- DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len));
- return False;
- }
- sig = data_blob(NULL, auth_len);
- prs_copy_data_out((char *)sig.data, &auth_verf, auth_len);
- }
-
/*
- * Unseal any sealed data in the PDU, not including the
- * 8 byte auth_header or the auth_data.
+ * Unmarshall the 8 byte auth_header that comes before the
+ * auth data.
*/
- /*
- * Now unseal and check the auth verifier in the auth_data at
- * the end of the packet.
- */
-
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
- if (data_len < 0) {
- DEBUG(1, ("Can't unseal - data_len < 0!!\n"));
- return False;
- }
- nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state,
- (unsigned char *)reply_data, data_len,
- &sig);
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state,
- (const unsigned char *)reply_data, data_len,
- &sig);
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0)) {
+ DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_HDR_AUTH failed.\n"));
+ return False;
}
- data_blob_free(&sig);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("rpc_auth_pipe: could not validate "
- "incoming NTLMSSP packet!\n"));
+ if (!rpc_hdr_auth_chk(&rhdr_auth)) {
+ DEBUG(0,("rpc_auth_pipe: rpc_hdr_auth_chk failed.\n"));
return False;
}
}
- if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- RPC_AUTH_NETSEC_CHK chk;
+ /*
+ * Now unseal and check the auth verifier in the auth_data at
+ * then end of the packet. The 4 bytes skipped in the unseal
+ * seem to be a buffer pointer preceeding the sealed data.
+ */
- if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
- DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
- return False;
- }
+ if (auth_verify) {
+ RPC_AUTH_NTLMSSP_CHK chk;
+ uint32 crc32;
+ prs_struct auth_verf;
+ char data[RPC_AUTH_NTLMSSP_CHK_LEN];
+ char *dp = prs_data_p(rdata) + len - auth_len;
- if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign",
- &chk, &auth_verf, 0)) {
- DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
- "RPC_AUTH_NETSECK_CHK failed\n"));
+ if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+ DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
return False;
}
- if (!netsec_decode(&cli->auth_info,
- cli->pipe_auth_flags,
- SENDER_IS_ACCEPTOR,
- &chk, reply_data, data_len)) {
- DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
+ DEBUG(10,("rpc_auth_pipe: verify\n"));
+ dump_data(100, dp, auth_len);
+ NTLMSSPcalc_ap(cli, (uchar*)(dp+4), auth_len - 4);
+
+ memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN);
+ dump_data(100, data, auth_len);
+
+ prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* The endinness must be preserved. JRA. */
+ prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+
+ prs_give_memory(&auth_verf, data, RPC_AUTH_NTLMSSP_CHK_LEN, False);
+
+ if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0)) {
+ DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_AUTH_NTLMSSP_CHK failed.\n"));
return False;
}
- cli->auth_info.seq_num++;
+ crc32 = crc32_calc_buffer(reply_data, data_len);
+ if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) {
+ DEBUG(0,("rpc_auth_pipe: rpc_auth_ntlmssp_chk failed.\n"));
+ return False;
+ }
+ cli->ntlmssp_seq_num++;
}
return True;
}
/****************************************************************************
- Send data on an rpc pipe via trans, which *must* be the last fragment.
+ Send data on an rpc pipe, which *must* be in one fragment.
receive response data from an rpc pipe, which may be large...
Read the first fragment: unfortunately have to use SMBtrans for the first
@@ -379,12 +317,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
+------------+-----------------+-------------+---------------+-------------+
Where the presence of the AUTH_HDR and AUTH are dependent on the
- signing & sealing being negotiated.
+ signing & sealing being neogitated.
****************************************************************************/
-static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata,
- uint8 expected_pkt_type)
+static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, prs_struct *rdata)
{
uint32 len;
char *rparam = NULL;
@@ -398,16 +335,14 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
char *prdata = NULL;
uint32 rdata_len = 0;
uint32 current_offset = 0;
- uint32 fragment_start = 0;
- uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024;
- int auth_padding_len = 0;
/* Create setup parameters - must be in native byte order. */
- setup[0] = TRANSACT_DCERPCCMD;
+ setup[0] = cmd;
setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */
- DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum));
+ DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd,
+ (int)cli->nt_pipe_fnum));
/* Send the RPC request and receive a response. For short RPC
calls (about 1024 bytes or so) the RPC request and response
@@ -417,7 +352,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
if (!cli_api_pipe(cli, "\\PIPE\\",
setup, 2, 0, /* Setup, length, max */
NULL, 0, 0, /* Params, length, max */
- pdata, data_len, max_data, /* data, length, max */
+ pdata, data_len, data_len, /* data, length, max */
&rparam, &rparam_len, /* return params, len */
&prdata, &rdata_len)) /* return data, len */
{
@@ -430,8 +365,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
SAFE_FREE(rparam);
if (prdata == NULL) {
- DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n",
- (int)cli->nt_pipe_fnum));
+ DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n",
+ (int)cmd, (int)cli->nt_pipe_fnum));
return False;
}
@@ -458,12 +393,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
}
}
- if (rhdr.pkt_type == RPC_BINDNACK) {
- DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum));
- prs_mem_free(rdata);
- return False;
- }
-
if (rhdr.pkt_type == RPC_RESPONSE) {
RPC_HDR_RESP rhdr_resp;
if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
@@ -473,12 +402,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
}
}
- if (rhdr.pkt_type != expected_pkt_type) {
- DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type));
- prs_mem_free(rdata);
- return False;
- }
-
DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
(unsigned int)len, (unsigned int)rdata_len ));
@@ -501,20 +424,16 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
* Now we have a complete PDU, check the auth struct if any was sent.
*/
- if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
- rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
- prs_mem_free(rdata);
- return False;
- }
-
if (rhdr.auth_len != 0) {
+ if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+ return False;
/*
* Drop the auth footers from the current offset.
* We need this if there are more fragments.
* The auth footers consist of the auth_data and the
* preceeding 8 byte auth_header.
*/
- current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
+ current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
}
/*
@@ -538,7 +457,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
prs_struct hps;
uint8 eclass;
uint32 ecode;
-
+
/*
* First read the header of the next PDU.
*/
@@ -547,12 +466,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
+
if (cli_is_dos_error(cli)) {
- cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRDOS && ecode != ERRmoredata) {
- DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
- return False;
- }
+ cli_dos_error(cli, &eclass, &ecode);
+ if (eclass != ERRDOS && ecode != ERRmoredata) {
+ DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
+ return False;
+ }
}
DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
@@ -591,33 +511,23 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
* Now read the rest of the PDU.
*/
- if (!rpc_read(cli, rdata, len, &current_offset)) {
- prs_mem_free(rdata);
+ if (!rpc_read(cli, rdata, len, &current_offset))
return False;
- }
-
- fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
/*
* Verify any authentication footer.
*/
-
- if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
- rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
- prs_mem_free(rdata);
- return False;
- }
-
if (rhdr.auth_len != 0 ) {
-
+ if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+ return False;
/*
* Drop the auth footers from the current offset.
* The auth footers consist of the auth_data and the
* preceeding 8 byte auth_header.
* We need this if there are more fragments.
*/
- current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
+ current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
}
}
@@ -633,105 +543,68 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
********************************************************************/
-static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
- uint32 rpc_call_id,
- RPC_IFACE *abstract, RPC_IFACE *transfer,
- const char *my_name, const char *domain)
+static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id,
+ RPC_IFACE *abstract, RPC_IFACE *transfer,
+ char *my_name, char *domain, uint32 neg_flags)
{
RPC_HDR hdr;
RPC_HDR_RB hdr_rb;
- RPC_HDR_AUTH hdr_auth;
+ char buffer[4096];
+ prs_struct auth_info;
int auth_len = 0;
- int auth_type, auth_level;
- size_t saved_hdr_offset = 0;
- prs_struct auth_info;
- prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */
- prs_get_mem_context(rpc_out), MARSHALL);
+ prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL);
+
+ if (do_auth) {
+ RPC_HDR_AUTH hdr_auth;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
- if (cli->pipe_auth_flags) {
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
-
/*
* Create the auth structs we will marshall.
*/
-
- init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1);
-
+
+ init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00, 1);
+ init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_NEGOTIATE);
+ init_rpc_auth_ntlmssp_neg(&ntlmssp_neg, neg_flags, my_name, domain);
+
/*
- * Now marshall the data into the temporary parse_struct.
+ * Use the 4k buffer to store the auth info.
*/
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
- }
- saved_hdr_offset = prs_offset(&auth_info);
- }
-
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- NTSTATUS nt_status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB request;
+ prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
- DEBUG(5, ("Processing NTLMSSP Negotiate\n"));
- nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
- null_blob,
- &request);
+ /*
+ * Now marshall the data into the temporary parse_struct.
+ */
- if (!NT_STATUS_EQUAL(nt_status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- prs_mem_free(&auth_info);
- return nt_status;
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
+ DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
+ return False;
}
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = request.length;
- prs_copy_data_in(&auth_info, (char *)request.data, request.length);
-
- DEBUG(5, ("NTLMSSP Negotiate:\n"));
- dump_data(5, (const char *)request.data, request.length);
-
- data_blob_free(&request);
-
- } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- RPC_AUTH_NETSEC_NEG netsec_neg;
-
- /* Use lp_workgroup() if domain not specified */
-
- if (!domain || !domain[0]) {
- DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n"));
- domain = lp_workgroup();
+ if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
+ DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_VERIFIER.\n"));
+ return False;
}
- init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);
-
- /*
- * Now marshall the data into the temporary parse_struct.
- */
-
- if(!smb_io_rpc_auth_netsec_neg("netsec_neg",
- &netsec_neg, &auth_info, 0)) {
- DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
+ if(!smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_info, 0)) {
+ DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_NTLMSSP_NEG.\n"));
+ return False;
}
/* Auth len in the rpc header doesn't include auth_header. */
- auth_len = prs_offset(&auth_info) - saved_hdr_offset;
+ auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN;
}
- /* Create the request RPC_HDR */
- init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id,
+ /* create the request RPC_HDR */
+ init_rpc_hdr(&hdr, RPC_BIND, RPC_FLG_FIRST | RPC_FLG_LAST, rpc_call_id,
RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
auth_len);
if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
/* create the bind request RPC_HDR_RB */
@@ -741,23 +614,21 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
/* Marshall the bind request data */
if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
/*
* Grow the outgoing buffer to store any auth info.
*/
- if(auth_len != 0) {
+ if(hdr.auth_len != 0) {
if(!prs_append_prs_data( rpc_out, &auth_info)) {
DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
}
- prs_mem_free(&auth_info);
- return NT_STATUS_OK;
+
+ return True;
}
/*******************************************************************
@@ -767,63 +638,90 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
the authentication handshake.
********************************************************************/
-static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
- uint32 rpc_call_id,
- prs_struct *rpc_out)
+static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs,
+ uint32 rpc_call_id,
+ prs_struct *rpc_out)
{
- NTSTATUS nt_status;
+ unsigned char lm_owf[24];
+ unsigned char nt_owf[24];
RPC_HDR hdr;
RPC_HDR_AUTHA hdr_autha;
- DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0);
- DATA_BLOB ntlmssp_reply;
- int auth_type, auth_level;
-
- /* The response is picked up from the internal cache,
- where it was placed by the rpc_auth_pipe() code */
- nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
- ntlmssp_null_response,
- &ntlmssp_reply);
-
- if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- return nt_status;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ char buffer[4096];
+ prs_struct auth_info;
+
+ /*
+ * Marshall the variable length data into a temporary parse
+ * struct, pointing into a 4k local buffer.
+ */
+ prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL);
+
+ /*
+ * Use the 4k buffer to store the auth info.
+ */
+
+ prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
+
+ /*
+ * Create the variable length auth_data.
+ */
+
+ init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH);
+
+ pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
+
+ init_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
+ lm_owf, nt_owf,
+ domain, user_name, my_name,
+ ntlmssp_cli_flgs);
+
+ /*
+ * Marshall the variable length auth_data into a temp parse_struct.
+ */
+
+ if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
+ DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_VERIFIER.\n"));
+ return False;
+ }
+
+ if(!smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, &auth_info, 0)) {
+ DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_NTLMSSP_RESP.\n"));
+ return False;
}
/* Create the request RPC_HDR */
init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
- RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + ntlmssp_reply.length,
- ntlmssp_reply.length );
-
+ RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + prs_offset(&auth_info),
+ prs_offset(&auth_info) );
+
/* Marshall it. */
if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
-
/* Create the request RPC_HDR_AUTHA */
init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN,
- auth_type, auth_level, 0x00);
+ NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00);
if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
/*
* Append the auth data to the outgoing buffer.
*/
- if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) {
+ if(!prs_append_prs_data(rpc_out, &auth_info)) {
DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
+ return False;
}
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_OK;
+ return True;
}
@@ -831,18 +729,17 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
Creates a DCE/RPC request.
********************************************************************/
-static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len, uint8 flags, uint32 oldid, uint32 data_left)
+static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len)
{
uint32 alloc_hint;
RPC_HDR hdr;
RPC_HDR_REQ hdr_req;
- uint32 callid = oldid ? oldid : get_rpc_call_id();
DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len));
/* create the rpc header RPC_HDR */
- init_rpc_hdr(&hdr, RPC_REQUEST, flags,
- callid, data_len, auth_len);
+ init_rpc_hdr(&hdr, RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
+ get_rpc_call_id(), data_len, auth_len);
/*
* The alloc hint should be the amount of data, not including
@@ -862,237 +759,136 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len
/* stream-time... */
if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0))
- return 0;
+ return False;
if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0))
- return 0;
+ return False;
if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN)
- return 0;
-
- return callid;
-}
-
-/*******************************************************************
- Puts an auth header into an rpc request.
- ********************************************************************/
-
-static BOOL create_auth_hdr(prs_struct *outgoing_packet,
- int auth_type,
- int auth_level, int padding)
-{
- RPC_HDR_AUTH hdr_auth;
-
- init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level,
- padding, 1);
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth,
- outgoing_packet, 0)) {
- DEBUG(0,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n"));
return False;
- }
+
return True;
}
-/**
- * Send a request on an RPC pipe and get a response.
- *
- * @param data NDR contents of the request to be sent.
- * @param rdata Unparsed NDR response data.
-**/
+
+/****************************************************************************
+ Send a request on an rpc pipe.
+ ****************************************************************************/
BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
prs_struct *data, prs_struct *rdata)
{
- uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent;
- NTSTATUS nt_status;
- BOOL ret = False;
- uint32 callid = 0;
- fstring dump_name;
-
- auth_len = 0;
- real_auth_len = 0;
- auth_hdr_len = 0;
-
- if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
- }
- if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- auth_len = RPC_AUTH_NETSEC_CHK_LEN;
- }
- auth_hdr_len = RPC_HDR_AUTH_LEN;
- }
+ prs_struct outgoing_packet;
+ uint32 data_len;
+ uint32 auth_len;
+ BOOL ret;
+ BOOL auth_verify;
+ BOOL auth_seal;
+ uint32 crc32 = 0;
+ char *pdata_out = NULL;
+
+ auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0);
/*
- * calc how much actual data we can send in a PDU fragment
+ * The auth_len doesn't include the RPC_HDR_AUTH_LEN.
*/
- max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- auth_hdr_len - auth_len - 8;
-
- for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) {
- prs_struct outgoing_packet;
- prs_struct sec_blob;
- uint32 data_len, send_size;
- uint8 flags = 0;
- uint32 auth_padding = 0;
- DATA_BLOB sign_blob;
- /*
- * how much will we send this time
- */
- send_size = MIN(data_left, max_data);
+ auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0);
- if (!prs_init(&sec_blob, send_size, /* will need at least this much */
- cli->mem_ctx, MARSHALL)) {
- DEBUG(0,("Could not malloc %u bytes",
- send_size+auth_padding));
- return False;
- }
+ /*
+ * PDU len is header, plus request header, plus data, plus
+ * auth_header_len (if present), plus auth_len (if present).
+ * NB. The auth stuff should be aligned on an 8 byte boundary
+ * to be totally DCE/RPC spec complient. For now we cheat and
+ * hope that the data structs defined are a multiple of 8 bytes.
+ */
- if(!prs_append_some_prs_data(&sec_blob, data,
- data_sent, send_size)) {
- DEBUG(0,("Failed to append data to netsec blob\n"));
- prs_mem_free(&sec_blob);
- return False;
- }
+ if((prs_offset(data) % 8) != 0) {
+ DEBUG(5,("rpc_api_pipe_req: Outgoing data not a multiple of 8 bytes....\n"));
+ }
- /*
- * NT expects the data that is sealed to be 8-byte
- * aligned. The padding must be encrypted as well and
- * taken into account when generating the
- * authentication verifier. The amount of padding must
- * be stored in the auth header.
- */
+ data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(data) +
+ (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len;
- if (cli->pipe_auth_flags) {
- size_t data_and_padding_size;
- int auth_type;
- int auth_level;
- prs_align_uint64(&sec_blob);
+ /*
+ * Malloc a parse struct to hold it (and enough for alignments).
+ */
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
+ if(!prs_init(&outgoing_packet, data_len + 8, cli->mem_ctx, MARSHALL)) {
+ DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
+ return False;
+ }
- data_and_padding_size = prs_offset(&sec_blob);
- auth_padding = data_and_padding_size - send_size;
+ pdata_out = prs_data_p(&outgoing_packet);
+
+ /*
+ * Write out the RPC header and the request header.
+ */
- /* insert the auth header */
-
- if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) {
- prs_mem_free(&sec_blob);
- return False;
- }
-
- /* create an NTLMSSP signature */
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- /*
- * Seal the outgoing data if requested.
- */
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
-
- nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state,
- (unsigned char*)prs_data_p(&sec_blob),
- data_and_padding_size,
- &sign_blob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- prs_mem_free(&sec_blob);
- return False;
- }
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-
- nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state,
- (unsigned char*)prs_data_p(&sec_blob),
- data_and_padding_size, &sign_blob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- prs_mem_free(&sec_blob);
- return False;
- }
- }
-
-
- /* write auth footer onto the packet */
- real_auth_len = sign_blob.length;
-
- prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length);
- data_blob_free(&sign_blob);
+ if(!create_rpc_request(&outgoing_packet, op_num, data_len, auth_len)) {
+ DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
+ prs_mem_free(&outgoing_packet);
+ return False;
+ }
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- size_t parse_offset_marker;
- RPC_AUTH_NETSEC_CHK verf;
- DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
-
- netsec_encode(&cli->auth_info,
- cli->pipe_auth_flags,
- SENDER_IS_INITIATOR,
- &verf,
- prs_data_p(&sec_blob),
- data_and_padding_size);
-
- cli->auth_info.seq_num++;
-
- /* write auth footer onto the packet */
-
- parse_offset_marker = prs_offset(&sec_blob);
- if (!smb_io_rpc_auth_netsec_chk("", &verf,
- &sec_blob, 0)) {
- prs_mem_free(&sec_blob);
- return False;
- }
- real_auth_len = prs_offset(&sec_blob) - parse_offset_marker;
- }
- }
+ /*
+ * Seal the outgoing data if requested.
+ */
- data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(&sec_blob);
+ if (auth_seal) {
+ crc32 = crc32_calc_buffer(prs_data_p(data), prs_offset(data));
+ NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data), prs_offset(data));
+ }
- /*
- * Malloc parse struct to hold it (and enough for alignments).
- */
- if(!prs_init(&outgoing_packet, data_len + 8,
- cli->mem_ctx, MARSHALL)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
- return False;
- }
+ /*
+ * Now copy the data into the outgoing packet.
+ */
- if (data_left == prs_offset(data))
- flags |= RPC_FLG_FIRST;
+ if(!prs_append_prs_data( &outgoing_packet, data)) {
+ DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n"));
+ prs_mem_free(&outgoing_packet);
+ return False;
+ }
- if (data_left <= max_data)
- flags |= RPC_FLG_LAST;
- /*
- * Write out the RPC header and the request header.
- */
- if(!(callid = create_rpc_request(&outgoing_packet, op_num,
- data_len, real_auth_len, flags,
- callid, data_left))) {
- DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
+ /*
+ * Add a trailing auth_verifier if needed.
+ */
+
+ if (auth_seal || auth_verify) {
+ RPC_HDR_AUTH hdr_auth;
+
+ init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE,
+ NTLMSSP_AUTH_LEVEL, 0x08, (auth_verify ? 1 : 0));
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &outgoing_packet, 0)) {
+ DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_HDR_AUTH.\n"));
prs_mem_free(&outgoing_packet);
- prs_mem_free(&sec_blob);
return False;
}
+ }
- prs_append_prs_data(&outgoing_packet, &sec_blob);
- prs_mem_free(&sec_blob);
+ /*
+ * Finally the auth data itself.
+ */
- DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len,
- prs_offset(&outgoing_packet)));
-
- if (flags & RPC_FLG_LAST)
- ret = rpc_api_pipe(cli, &outgoing_packet,
- rdata, RPC_RESPONSE);
- else {
- cli_write(cli, cli->nt_pipe_fnum, 0x0008,
- prs_data_p(&outgoing_packet),
- data_sent, data_len);
+ if (auth_verify) {
+ RPC_AUTH_NTLMSSP_CHK chk;
+ uint32 current_offset = prs_offset(&outgoing_packet);
+
+ init_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
+ if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &outgoing_packet, 0)) {
+ DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n"));
+ prs_mem_free(&outgoing_packet);
+ return False;
}
- prs_mem_free(&outgoing_packet);
- data_sent += send_size;
- data_left -= send_size;
+ NTLMSSPcalc_ap(cli, (unsigned char*)&pdata_out[current_offset+4], RPC_AUTH_NTLMSSP_CHK_LEN - 4);
}
- /* Also capture received data */
- slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s",
- cli_pipe_get_name(cli));
- prs_dump(dump_name, op_num, rdata);
+
+ DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet)));
+
+ ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata);
+
+ prs_mem_free(&outgoing_packet);
return ret;
}
@@ -1145,46 +941,29 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name,
check the rpc bind acknowledge response
****************************************************************************/
-int get_pipe_index( const char *pipe_name )
+static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
{
int pipe_idx = 0;
while (pipe_names[pipe_idx].client_pipe != NULL) {
- if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
- return pipe_idx;
+ if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) {
+ DEBUG(5,("Bind Abstract Syntax: "));
+ dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax),
+ sizeof(pipe_names[pipe_idx].abstr_syntax));
+ DEBUG(5,("Bind Transfer Syntax: "));
+ dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
+ sizeof(pipe_names[pipe_idx].trans_syntax));
+
+ /* copy the required syntaxes out so we can do the right bind */
+ *transfer = pipe_names[pipe_idx].trans_syntax;
+ *abstract = pipe_names[pipe_idx].abstr_syntax;
+
+ return True;
+ }
pipe_idx++;
};
- return -1;
-}
-
-
-/****************************************************************************
- check the rpc bind acknowledge response
-****************************************************************************/
-
-const char* get_pipe_name_from_index( const int pipe_index )
-{
-
- if ( (pipe_index < 0) || (pipe_index >= PI_MAX_PIPES) )
- return NULL;
-
- return pipe_names[pipe_index].client_pipe;
-}
-
-/****************************************************************************
- Check to see if this pipe index points to one of
- the pipes only supported by Win2k
- ****************************************************************************/
-
-BOOL is_win2k_pipe( const int pipe_idx )
-{
- switch ( pipe_idx )
- {
- case PI_LSARPC_DS:
- return True;
- }
-
+ DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
return False;
}
@@ -1192,59 +971,36 @@ BOOL is_win2k_pipe( const int pipe_idx )
check the rpc bind acknowledge response
****************************************************************************/
-static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
-{
- if ( pipe_idx >= PI_MAX_PIPES ) {
- DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n",
- pipe_idx));
- return False;
- }
-
- DEBUG(5,("Bind Abstract Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax),
- sizeof(pipe_names[pipe_idx].abstr_syntax));
- DEBUG(5,("Bind Transfer Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
- sizeof(pipe_names[pipe_idx].trans_syntax));
-
- /* copy the required syntaxes out so we can do the right bind */
-
- *transfer = pipe_names[pipe_idx].trans_syntax;
- *abstract = pipe_names[pipe_idx].abstr_syntax;
-
- return True;
-}
-
-/****************************************************************************
- check the rpc bind acknowledge response
-****************************************************************************/
-
-static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
+static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, RPC_IFACE *transfer)
{
-# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
- if ( hdr_ba->addr.len <= 0)
- return False;
-
- if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
- !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
- {
- DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
- pipe_names[i].server_pipe ,hdr_ba->addr.str));
- return False;
+ int i = 0;
+
+ while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) {
+ if ((strequal(pipe_name, pipe_names[i].client_pipe ))) {
+ if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) {
+ DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
+ pipe_names[i].server_pipe ));
+ break;
+ } else {
+ DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
+ pipe_names[i].server_pipe ,
+ hdr_ba->addr.str));
+ break;
+ }
+ } else {
+ i++;
+ }
}
-
- DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe ));
- if (pipe_names[pipe_idx].server_pipe == NULL) {
+ if (pipe_names[i].server_pipe == NULL) {
DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
return False;
}
-#endif /* JERRY */
/* check the transfer syntax */
if ((hdr_ba->transfer.version != transfer->version) ||
(memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
- DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
+ DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
return False;
}
@@ -1264,25 +1020,84 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id)
{
+ RPC_HDR_AUTH rhdr_auth;
+ RPC_AUTH_VERIFIER rhdr_verf;
+ RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
+ char buffer[MAX_PDU_FRAG_LEN];
prs_struct rpc_out;
ssize_t ret;
- prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */
- cli->mem_ctx, MARSHALL);
+ unsigned char p24[24];
+ unsigned char lm_owf[24];
+ unsigned char lm_hash[16];
- if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
- &rpc_out))) {
+ if(!smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0)) {
+ DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_HDR_AUTH.\n"));
return False;
}
+ if(!smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0)) {
+ DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_VERIFIER.\n"));
+ return False;
+ }
+ if(!smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, rdata, 0)) {
+ DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_NTLMSSP_CHAL.\n"));
+ return False;
+ }
+
+ cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
+
+ pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
+
+ prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL);
+
+ prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
+
+ create_rpc_bind_resp(&cli->pwd, cli->domain,
+ cli->user_name, global_myname,
+ cli->ntlmssp_cli_flgs, rpc_call_id,
+ &rpc_out);
+
+ pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
+ pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
+
+ NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
+
+ {
+ unsigned char j = 0;
+ int ind;
+ unsigned char k2[8];
+
+ memcpy(k2, p24, 5);
+ k2[5] = 0xe5;
+ k2[6] = 0x38;
+ k2[7] = 0xb0;
+
+ for (ind = 0; ind < 256; ind++)
+ cli->ntlmssp_hash[ind] = (unsigned char)ind;
+
+ for( ind = 0; ind < 256; ind++) {
+ unsigned char tc;
+
+ j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
+
+ tc = cli->ntlmssp_hash[ind];
+ cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
+ cli->ntlmssp_hash[j] = tc;
+ }
+
+ cli->ntlmssp_hash[256] = 0;
+ cli->ntlmssp_hash[257] = 0;
+ }
+
+ memset((char *)lm_hash, '\0', sizeof(lm_hash));
if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out),
0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
- prs_mem_free(&rpc_out);
return False;
}
- prs_mem_free(&rpc_out);
+ cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
return True;
}
@@ -1290,21 +1105,19 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
Do an rpc bind.
****************************************************************************/
-static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name)
+BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name)
{
RPC_IFACE abstract;
RPC_IFACE transfer;
prs_struct rpc_out;
prs_struct rdata;
+ BOOL do_auth = (cli->ntlmssp_cli_flgs != 0);
uint32 rpc_call_id;
char buffer[MAX_PDU_FRAG_LEN];
- if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) )
- return False;
-
- DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe));
+ DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
- if (!valid_pipe_name(pipe_idx, &abstract, &transfer))
+ if (!valid_pipe_name(pipe_name, &abstract, &transfer))
return False;
prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL);
@@ -1317,65 +1130,16 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
rpc_call_id = get_rpc_call_id();
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- NTSTATUS nt_status;
- fstring password;
-
- DEBUG(5, ("NTLMSSP authenticated pipe selected\n"));
-
- nt_status = ntlmssp_client_start(&cli->ntlmssp_pipe_state);
-
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
-
- /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */
-
- cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
-
- nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state,
- cli->user_name);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
-
- nt_status = ntlmssp_set_domain(cli->ntlmssp_pipe_state,
- cli->domain);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
-
- if (cli->pwd.null_pwd) {
- nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state,
- NULL);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
- } else {
- pwd_get_cleartext(&cli->pwd, password);
- nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state,
- password);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
- }
-
- if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
-
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
- cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
- }
- } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- cli->auth_info.seq_num = 0;
- }
-
/* Marshall the outgoing data. */
- create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
+ create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id,
&abstract, &transfer,
- global_myname(), cli->domain);
+ global_myname, cli->domain, cli->ntlmssp_cli_flgs);
/* Initialize the incoming data struct. */
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* send data on \PIPE\. receive a response */
- if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) {
+ if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) {
RPC_HDR_BA hdr_ba;
DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));
@@ -1386,8 +1150,8 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
return False;
}
- if(!check_bind_response(&hdr_ba, pipe_idx, &transfer)) {
- DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
+ if(!check_bind_response(&hdr_ba, pipe_name, &transfer)) {
+ DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n"));
prs_mem_free(&rdata);
return False;
}
@@ -1401,251 +1165,97 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
* handshake.
*/
- if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP)
- && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
+ if (do_auth && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
prs_mem_free(&rdata);
return False;
}
- prs_mem_free(&rdata);
- return True;
}
- return False;
+ prs_mem_free(&rdata);
+ return True;
}
/****************************************************************************
+ Set ntlmssp negotiation flags.
+ ****************************************************************************/
+
+void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
+{
+ cli->ntlmssp_cli_flgs = ntlmssp_flgs;
+}
+
+
+/****************************************************************************
Open a session.
****************************************************************************/
-BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name)
{
int fnum;
- /* At the moment we can't have more than one pipe open over
- a cli connection. )-: */
-
SMB_ASSERT(cli->nt_pipe_fnum == 0);
-
- /* The pipe index must fall within our array */
-
- SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
if (cli->capabilities & CAP_NT_SMBS) {
- if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -1) {
+ if ((fnum = cli_nt_create(cli, &pipe_name[5], DESIRED_ACCESS_PIPE)) == -1) {
DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
- &pipe_names[pipe_idx].client_pipe[5], cli->desthost, cli_errstr(cli)));
+ &pipe_name[5], cli->desthost, cli_errstr(cli)));
return False;
}
cli->nt_pipe_fnum = (uint16)fnum;
} else {
- if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
- DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
- pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli)));
+ if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
+ DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
+ pipe_name, cli->desthost, cli_errstr(cli)));
return False;
}
cli->nt_pipe_fnum = (uint16)fnum;
/**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(cli, pipe_names[pipe_idx].client_pipe, 0x4300)) {
+ if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) {
DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
cli_errstr(cli)));
cli_close(cli, cli->nt_pipe_fnum);
- cli->nt_pipe_fnum = 0;
return False;
}
}
/******************* bind request on pipe *****************/
- if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) {
- DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n",
- get_pipe_name_from_index(pipe_idx)));
+ if (!rpc_pipe_bind(cli, pipe_name, global_myname)) {
+ DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
+ cli_errstr(cli)));
cli_close(cli, cli->nt_pipe_fnum);
- cli->nt_pipe_fnum = 0;
return False;
}
- cli->pipe_idx = pipe_idx;
-
/*
* Setup the remote server name prefixed by \ and the machine account name.
*/
fstrcpy(cli->srv_name_slash, "\\\\");
fstrcat(cli->srv_name_slash, cli->desthost);
- strupper_m(cli->srv_name_slash);
+ strupper(cli->srv_name_slash);
fstrcpy(cli->clnt_name_slash, "\\\\");
- fstrcat(cli->clnt_name_slash, global_myname());
- strupper_m(cli->clnt_name_slash);
+ fstrcat(cli->clnt_name_slash, global_myname);
+ strupper(cli->clnt_name_slash);
- fstrcpy(cli->mach_acct, global_myname());
+ fstrcpy(cli->mach_acct, global_myname);
fstrcat(cli->mach_acct, "$");
- strupper_m(cli->mach_acct);
-
- /* Remember which pipe we're talking to */
- fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe);
+ strupper(cli->mach_acct);
return True;
}
-
/****************************************************************************
- Open a session to the NETLOGON pipe using schannel.
-
- (Assumes that the netlogon pipe is already open)
- ****************************************************************************/
-
-NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
- const uchar trust_password[16])
-{
- NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
- int fnum;
-
- cli_nt_netlogon_netsec_session_close(cli);
-
- if (lp_client_schannel() != False)
- neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- result = cli_nt_setup_creds(cli, sec_chan, trust_password,
- &neg_flags, 2);
-
- if (!NT_STATUS_IS_OK(result)) {
- cli_nt_session_close(cli);
- return result;
- }
-
- if ((lp_client_schannel() == True) &&
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
-
- DEBUG(3, ("Server did not offer schannel\n"));
- cli_nt_session_close(cli);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if ((lp_client_schannel() == False) ||
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
- return NT_STATUS_OK;
-
- /* keep the existing connection to NETLOGON open */
-
- }
-
- /* Server offered schannel, so try it. */
-
- memcpy(cli->auth_info.sess_key, cli->sess_key,
- sizeof(cli->auth_info.sess_key));
-
- cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
-
- cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
-
- if (cli->capabilities & CAP_NT_SMBS) {
-
- /* The secure channel connection must be opened on the same
- session (TCP connection) as the one the challenge was
- requested from. */
- if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN,
- DESIRED_ACCESS_PIPE)) == -1) {
- DEBUG(0,("cli_nt_create failed to %s machine %s. "
- "Error was %s\n",
- PIPE_NETLOGON, cli->desthost,
- cli_errstr(cli)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- cli->nt_pipe_fnum = (uint16)fnum;
- } else {
- if ((fnum = cli_open(cli, PIPE_NETLOGON,
- O_CREAT|O_RDWR, DENY_NONE)) == -1) {
- DEBUG(0,("cli_open failed on pipe %s to machine %s. "
- "Error was %s\n",
- PIPE_NETLOGON, cli->desthost,
- cli_errstr(cli)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- cli->nt_pipe_fnum = (uint16)fnum;
-
- /**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) {
- DEBUG(0,("Pipe hnd state failed. Error was %s\n",
- cli_errstr(cli)));
- cli_close(cli, cli->nt_pipe_fnum);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
- DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
- cli_close(cli, cli->nt_pipe_fnum);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
-}
-
+close the session
+****************************************************************************/
-NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags,
- const uchar trust_password[16])
+void cli_nt_session_close(struct cli_state *cli)
{
- NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
- cli->pipe_auth_flags = 0;
-
- if (lp_client_schannel() == False) {
- return NT_STATUS_OK;
- }
-
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(PI_NETLOGON)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (lp_client_schannel() != False)
- neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- result = cli_nt_setup_creds(cli, sec_chan, trust_password,
- &neg_flags, 2);
-
- if (!(neg_flags & NETLOGON_NEG_SCHANNEL)
- && lp_client_schannel() == True) {
- DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
- result = NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- ZERO_STRUCT(cli->auth_info.sess_key);
- ZERO_STRUCT(cli->sess_key);
- cli->pipe_auth_flags = 0;
- cli_nt_session_close(cli);
- return result;
- }
-
- memcpy(cli->auth_info.sess_key, cli->sess_key,
- sizeof(cli->auth_info.sess_key));
-
- cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+ cli_close(cli, cli->nt_pipe_fnum);
cli->nt_pipe_fnum = 0;
-
- /* doing schannel, not per-user auth */
- cli->pipe_auth_flags = auth_flags;
-
- return NT_STATUS_OK;
-}
-
-const char *cli_pipe_get_name(struct cli_state *cli)
-{
- return cli->pipe_name;
}
-
-
diff --git a/source/rpc_client/cli_shutdown.c b/source/rpc_client/cli_shutdown.c
deleted file mode 100644
index 0bf6e90ad27..00000000000
--- a/source/rpc_client/cli_shutdown.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC Pipe client
-
- Copyright (C) Andrew Tridgell 1992-1998,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- Copyright (C) Paul Ashton 1997-1998.
- Copyright (C) Jeremy Allison 1999,
- Copyright (C) Simo Sorce 2001,
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* Shutdown a server */
-
-NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
- const char *msg, uint32 timeout, BOOL do_reboot,
- BOOL force)
-{
- prs_struct qbuf;
- prs_struct rbuf;
- SHUTDOWN_Q_INIT q_s;
- SHUTDOWN_R_INIT r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
-
- ZERO_STRUCT (q_s);
- ZERO_STRUCT (r_s);
-
- prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_shutdown_q_init(&q_s, msg, timeout, do_reboot, force);
-
- if (!shutdown_io_q_init("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SHUTDOWN_INIT, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if(shutdown_io_r_init("", &r_s, &rbuf, 0))
- result = r_s.status;
-
-done:
- prs_mem_free(&rbuf);
- prs_mem_free(&qbuf);
-
- return result;
-}
-
-
-/* Abort a server shutdown */
-
-NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
-{
- prs_struct rbuf;
- prs_struct qbuf;
- SHUTDOWN_Q_ABORT q_s;
- SHUTDOWN_R_ABORT r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- ZERO_STRUCT (q_s);
- ZERO_STRUCT (r_s);
-
- prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_shutdown_q_abort(&q_s);
-
- if (!shutdown_io_q_abort("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SHUTDOWN_ABORT, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (shutdown_io_r_abort("", &r_s, &rbuf, 0))
- result = r_s.status;
-
-done:
- prs_mem_free(&rbuf);
- prs_mem_free(&qbuf );
-
- return result;
-}
diff --git a/source/rpc_client/cli_spoolss_notify.c b/source/rpc_client/cli_spoolss_notify.c
index f4eda332bb1..a6ce3341b78 100644
--- a/source/rpc_client/cli_spoolss_notify.c
+++ b/source/rpc_client/cli_spoolss_notify.c
@@ -1,119 +1,261 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Gerald Carter 2001-2002,
- Copyright (C) Tim Potter 2000-2002,
- Copyright (C) Andrew Tridgell 1994-2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- Copyright (C) Jean-Francois Micouleau 1999-2000.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Jean Francois Micouleau 1998-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
#include "includes.h"
+#if 0
+#include "rpc_parse.h"
+#include "nterr.h"
+#endif
+extern pstring global_myname;
+
+struct msg_info_table {
+ uint32 msg;
+ uint32 field;
+ const char *name;
+ void (*construct_fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
+ print_queue_struct *queue,
+ NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
+};
+
+struct msg_info_table msg_table[] = {
+{ PRINTER_MESSAGE_DRIVER, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_MESSAGE_DRIVER", spoolss_notify_driver_name },
+{ PRINTER_MESSAGE_ATTRIBUTES, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_MESSAGE_ATTRIBUTES", spoolss_notify_attributes },
+{ PRINTER_MESSAGE_COMMENT, PRINTER_NOTIFY_COMMENT, "PRINTER_MESSAGE_COMMENT", spoolss_notify_comment },
+{ PRINTER_MESSAGE_LOCATION, PRINTER_NOTIFY_LOCATION, "PRINTER_MESSAGE_LOCATION", spoolss_notify_location },
+{ PRINTER_MESSAGE_PRINTERNAME, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_MESSAGE_PRINTERNAME", spoolss_notify_printer_name },
+{ PRINTER_MESSAGE_SHARENAME, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_MESSAGE_SHARENAME", spoolss_notify_share_name },
+{ PRINTER_MESSAGE_PORT, PRINTER_NOTIFY_PORT_NAME, "PRINTER_MESSAGE_PORT", spoolss_notify_port_name },
+{ PRINTER_MESSAGE_CJOBS, PRINTER_NOTIFY_CJOBS, "PRINTER_MESSAGE_CJOBS", spoolss_notify_cjobs },
+{ PRINTER_MESSAGE_SEPFILE, PRINTER_NOTIFY_SEPFILE, "PRINTER_MESSAGE_SEPFILE", spoolss_notify_sepfile },
+{ PRINTER_MESSAGE_PARAMS, PRINTER_NOTIFY_PARAMETERS, "PRINTER_MESSAGE_PARAMETERS", spoolss_notify_parameters },
+{ PRINTER_MESSAGE_DATATYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_MESSAGE_DATATYPE", spoolss_notify_datatype },
+{ PRINTER_MESSAGE_NULL, 0x0, "", NULL },
+};
+
+/*********************************************************
+ Disconnect from the client machine.
+**********************************************************/
+BOOL spoolss_disconnect_from_client( struct cli_state *cli)
+{
+ cli_nt_session_close(cli);
+ cli_ulogoff(cli);
+ cli_shutdown(cli);
+
+ return True;
+}
+
+
+/*********************************************************
+ Connect to the client machine.
+**********************************************************/
+
+BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine)
+{
+ ZERO_STRUCTP(cli);
+ if(cli_initialise(cli) == NULL) {
+ DEBUG(0,("connect_to_client: unable to initialize client connection.\n"));
+ return False;
+ }
+
+ if(!resolve_name( remote_machine, &cli->dest_ip, 0x20)) {
+ DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (ismyip(cli->dest_ip)) {
+ DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (!cli_connect(cli, remote_machine, &cli->dest_ip)) {
+ DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (!attempt_netbios_session_request(cli, global_myname, remote_machine, &cli->dest_ip)) {
+ DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n",
+ remote_machine));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ cli->protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(cli)) {
+ DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (cli->protocol != PROTOCOL_NT1) {
+ DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(cli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+ DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
+ cli_shutdown(cli);
+ return False;
+ }
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
+ if(cli_nt_session_open(cli, PIPE_SPOOLSS) == False) {
+ DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli)));
+ cli_nt_session_close(cli);
+ cli_ulogoff(cli);
+ cli_shutdown(cli);
+ return False;
+ }
+
+ return True;
+}
/*
* SPOOLSS Client RPC's used by servers as the notification
- * back channel.
+ * back channel
*/
-/* Send a ReplyOpenPrinter request. This rpc is made by the printer
- server to the printer client in response to a rffpcnex request.
- The rrfpcnex request names a printer and a handle (the printerlocal
- value) and this rpc establishes a back-channel over which printer
- notifications are performed. */
+ /***************************************************************************
+ do a reply open printer
+****************************************************************************/
WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *printer, uint32 printerlocal, uint32 type,
- POLICY_HND *handle)
+ char *printer, uint32 localprinter, uint32 type,
+ POLICY_HND *handle)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_REPLYOPENPRINTER q;
- SPOOL_R_REPLYOPENPRINTER r;
WERROR result = W_ERROR(ERRgeneral);
- /* Initialise input parameters */
+ prs_struct rbuf;
+ prs_struct buf;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ SPOOL_Q_REPLYOPENPRINTER q_s;
+ SPOOL_R_REPLYOPENPRINTER r_s;
- make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type);
+ prs_init(&buf, 1024, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL );
- /* Marshall data and send request */
+ /* create and send a MSRPC command with api SPOOLSS_REPLYOPENPRINTER */
+
+ /* store the parameters */
+ make_spoolss_q_replyopenprinter(&q_s, printer, localprinter, type);
- if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
+ /* turn parameters into data stream */
+ if(!spoolss_io_q_replyopenprinter("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to marshall SPOOL_Q_REPLYOPENPRINTER struct.\n"));
+ goto done;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYOPENPRINTER, &buf, &rbuf))
goto done;
- /* Unmarshall response */
-
- if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
+ /* turn data stream into parameters*/
+ if(!spoolss_io_r_replyopenprinter("", &r_s, &rbuf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to unmarshall SPOOL_R_REPLYOPENPRINTER struct.\n"));
goto done;
-
- /* Return result */
-
- memcpy(handle, &r.handle, sizeof(r.handle));
- result = r.status;
+ }
+
+ memcpy(handle, &r_s.handle, sizeof(r_s.handle));
+ result = r_s.status;
done:
- prs_mem_free(&qbuf);
+ prs_mem_free(&buf);
prs_mem_free(&rbuf);
return result;
}
-/* Close a back-channel notification connection */
+/***************************************************************************
+ do a reply open printer
+****************************************************************************/
WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle)
+ POLICY_HND *handle)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_REPLYCLOSEPRINTER q;
- SPOOL_R_REPLYCLOSEPRINTER r;
WERROR result = W_ERROR(ERRgeneral);
+ prs_struct rbuf;
+ prs_struct buf;
- /* Initialise input parameters */
+ SPOOL_Q_REPLYCLOSEPRINTER q_s;
+ SPOOL_R_REPLYCLOSEPRINTER r_s;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&buf, 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL );
+
+ /* create and send a MSRPC command with api */
+
+ /* store the parameters */
+ make_spoolss_q_reply_closeprinter(&q_s, handle);
- make_spoolss_q_reply_closeprinter(&q, handle);
+ /* turn parameters into data stream */
+ if(!spoolss_io_q_replycloseprinter("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_Q_REPLY_CLOSEPRINTER struct.\n"));
+ goto done;
+ }
- /* Marshall data and send request */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYCLOSEPRINTER, &buf, &rbuf))
+ goto done;
- if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
+ /* turn data stream into parameters*/
+ if(!spoolss_io_r_replycloseprinter("", &r_s, &rbuf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_R_REPLY_CLOSEPRINTER struct.\n"));
goto done;
+ }
- /* Unmarshall response */
-
- if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return result */
- result = r.status;
+ result = r_s.status;
done:
- prs_mem_free(&qbuf);
+ prs_mem_free(&buf);
prs_mem_free(&rbuf);
return result;
}
+
/*********************************************************************
This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change
notification event when the registration **did not** use
@@ -121,34 +263,44 @@ done:
Also see cli_spolss_reply_rrpcn()
*********************************************************************/
-WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 condition, uint32 change_id)
+WERROR cli_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 condition, uint32 changd_id)
{
prs_struct qbuf, rbuf;
SPOOL_Q_ROUTERREPLYPRINTER q;
SPOOL_R_ROUTERREPLYPRINTER r;
WERROR result = W_ERROR(ERRgeneral);
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+
/* Initialise input parameters */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id);
- /* Marshall data and send request */
+ /* write the request */
+ make_spoolss_q_routerreplyprinter(&q, pol, condition, changd_id);
- if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
+ /* Marshall data and send request */
+ if (!spoolss_io_q_routerreplyprinter ("", &q, &qbuf, 0)) {
+ DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to marshall SPOOL_Q_ROUTERREPLYPRINTER!\n"));
goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
+ }
+
+
+ if (!rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
goto done;
+ /* Unmarshall response */
+ if (!spoolss_io_r_routerreplyprinter ("", &r, &rbuf, 0)) {
+ DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to unmarshall SPOOL_R_ROUTERREPLYPRINTER!\n"));
+ goto done;
+ }
+
/* Return output parameters */
-
result = r.status;
done:
@@ -158,115 +310,139 @@ done:
return result;
}
+
+/**********************************************************************************
+ Build the SPOOL_NOTIFY_INFO_DATA entries based upon the flags which have been set
+ *********************************************************************************/
+
+static int build_notify_data (TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, uint32 flags,
+ SPOOL_NOTIFY_INFO_DATA **notify_data)
+{
+ SPOOL_NOTIFY_INFO_DATA *data;
+ uint32 idx = 0;
+ int i = 0;
+
+ while ((msg_table[i].msg != PRINTER_MESSAGE_NULL) && flags)
+ {
+ if (flags & msg_table[i].msg)
+ {
+ DEBUG(10,("build_notify_data: %s set on [%s][%d]\n", msg_table[i].name,
+ printer->info_2->printername, idx));
+ if ((data=Realloc(*notify_data, (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ DEBUG(0,("build_notify_data: Realloc() failed with size [%d]!\n",
+ (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA)));
+ return -1;
+ }
+ *notify_data = data;
+
+ /* clear memory */
+ memset(*notify_data+idx, 0x0, sizeof(SPOOL_NOTIFY_INFO_DATA));
+
+ /*
+ * 'id' (last param here) is undefined when type == PRINTER_NOTIFY_TYPE
+ * See PRINTER_NOTIFY_INFO_DATA entries in MSDN
+ * --jerry
+ */
+ construct_info_data(*notify_data+idx, PRINTER_NOTIFY_TYPE, msg_table[i].field, 0x00);
+
+ msg_table[i].construct_fn(-1, *notify_data+idx, NULL, printer, ctx);
+ idx++;
+ }
+
+ i++;
+ }
+
+ return idx;
+}
+
/*********************************************************************
- This SPOOLSS_REPLY_RRPCN function is used to send a change
+ This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change
notification event when the registration **did** use
SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor
Also see cli_spoolss_routereplyprinter()
*********************************************************************/
-WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 notify_data_len,
- SPOOL_NOTIFY_INFO_DATA *notify_data,
- uint32 change_low, uint32 change_high)
+WERROR cli_spoolss_reply_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, PRINTER_MESSAGE_INFO *info,
+ NT_PRINTER_INFO_LEVEL *printer)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_REPLY_RRPCN q;
- SPOOL_R_REPLY_RRPCN r;
- WERROR result = W_ERROR(ERRgeneral);
+ prs_struct rbuf;
+ prs_struct buf;
+
SPOOL_NOTIFY_INFO notify_info;
+ SPOOL_NOTIFY_INFO_DATA *notify_data = NULL;
+ uint32 data_len;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ WERROR result = W_ERROR(ERRgeneral);
- /* Initialise parse structures */
+ SPOOL_Q_REPLY_RRPCN q_s;
+ SPOOL_R_REPLY_RRPCN r_s;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (!info) {
+ DEBUG(5,("cli_spoolss_reply_rrpcn: NULL printer message info pointer!\n"));
+ goto done;
+ }
+
+ prs_init(&buf, 1024, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL );
ZERO_STRUCT(notify_info);
- /* Initialise input parameters */
-
+ /*
+ * See comments in _spoolss_setprinter() about PRINTER_CHANGE_XXX
+ * events. --jerry
+ */
+ DEBUG(10,("cli_spoolss_reply_rrpcn: PRINTER_MESSAGE flags = 0x%8x\n", info->flags));
+
+ data_len = build_notify_data(mem_ctx, printer, info->flags, &notify_data);
+ if (info->flags && (data_len == -1)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Failed to build SPOOL_NOTIFY_INFO_DATA [flags == 0x%x] for printer [%s]\n",
+ info->flags, info->printer_name));
+ result = WERR_NOMEM;
+ goto done;
+ }
notify_info.version = 0x2;
notify_info.flags = 0x00020000; /* ?? */
- notify_info.count = notify_data_len;
+ notify_info.count = data_len;
notify_info.data = notify_data;
/* create and send a MSRPC command with api */
/* store the parameters */
- make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high,
- &notify_info);
-
- /* Marshall data and send request */
+ make_spoolss_q_reply_rrpcn(&q_s, handle, info->low, info->high, &notify_info);
- if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf))
+ /* turn parameters into data stream */
+ if(!spoolss_io_q_reply_rrpcn("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to marshall SPOOL_Q_REPLY_RRPCN struct.\n"));
goto done;
+ }
- /* Unmarshall response */
-
- if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &buf, &rbuf))
goto done;
- if (r.unknown0 == 0x00080000)
- DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
- else if ( r.unknown0 != 0x0 )
- DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0));
-
- result = r.status;
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/*********************************************************************
- *********************************************************************/
-
-WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 flags, uint32 options,
- const char *localmachine, uint32 printerlocal,
- SPOOL_NOTIFY_OPTION *option)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_RFFPCNEX q;
- SPOOL_R_RFFPCNEX r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- make_spoolss_q_rffpcnex(
- &q, pol, flags, options, localmachine, printerlocal,
- option);
-
- /* Marshall data and send request */
-
- if(!spoolss_io_q_rffpcnex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
+ /* turn data stream into parameters*/
+ if(!spoolss_io_r_reply_rrpcn("", &r_s, &rbuf, 0)) {
+ DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to unmarshall SPOOL_R_REPLY_RRPCN struct.\n"));
goto done;
+ }
- /* Unmarshall response */
-
- if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0))
- goto done;
+ if (r_s.unknown0 == 0x00080000) {
+ DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
+ }
- result = r.status;
+ result = r_s.status;
done:
- prs_mem_free(&qbuf);
+ prs_mem_free(&buf);
prs_mem_free(&rbuf);
-
+ /*
+ * The memory allocated in this array is talloc'd so we only need
+ * free the array here. JRA.
+ */
+ SAFE_FREE(notify_data);
+
return result;
}
+
diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c
deleted file mode 100644
index 555703cf4d8..00000000000
--- a/source/rpc_client/cli_srvsvc.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Tim Potter 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 switch_value, SRV_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_SRV_GET_INFO q;
- SRV_R_NET_SRV_GET_INFO r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- r.ctr = ctr;
-
- if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
- int preferred_len, ENUM_HND *hnd)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_SHARE_ENUM q;
- SRV_R_NET_SHARE_ENUM r;
- WERROR result = W_ERROR(ERRgeneral);
- int i;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_share_enum(
- &q, cli->srv_name_slash, info_level, preferred_len, hnd);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_enum("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* Oh yuck yuck yuck - we have to copy all the info out of the
- SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a
- prs_mem_free() it will all be invalidated. The various share
- info structures suck badly too. This really is gross. */
-
- ZERO_STRUCTP(ctr);
-
- if (!r.ctr.num_entries)
- goto done;
-
- ctr->info_level = info_level;
- ctr->num_entries = r.ctr.num_entries;
-
- switch(info_level) {
- case 1:
- ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc(
- mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries);
-
- memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
-
- for (i = 0; i < ctr->num_entries; i++) {
- SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
- char *s;
-
- /* Copy pointer crap */
-
- memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1,
- sizeof(SH_INFO_1));
-
- /* Duplicate strings */
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
- if (s)
- init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
- if (s)
- init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
-
- }
-
- break;
- case 2:
- ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc(
- mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries);
-
- memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
-
- for (i = 0; i < ctr->num_entries; i++) {
- SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
- char *s;
-
- /* Copy pointer crap */
-
- memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2,
- sizeof(SH_INFO_2));
-
- /* Duplicate strings */
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname);
- if (s)
- init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark);
- if (s)
- init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path);
- if (s)
- init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
-
- s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd);
- if (s)
- init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
- }
- break;
- }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *sharename)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_SHARE_DEL q;
- SRV_R_NET_SHARE_DEL r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *netname, uint32 type,
- const char *remark, uint32 perms,
- uint32 max_uses, uint32 num_uses,
- const char *path, const char *passwd)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_SHARE_ADD q;
- SRV_R_NET_SHARE_ADD r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
- perms, max_uses, num_uses, path, passwd);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_add("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *server, TIME_OF_DAY_INFO *tod)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_REMOTE_TOD q;
- SRV_R_NET_REMOTE_TOD r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_remote_tod(&q, cli->srv_name_slash);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- r.tod = tod;
-
- if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 file_level, const char *user_name,
- SRV_FILE_INFO_CTR *ctr, int preferred_len,
- ENUM_HND *hnd)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_FILE_ENUM q;
- SRV_R_NET_FILE_ENUM r;
- WERROR result = W_ERROR(ERRgeneral);
- int i;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name,
- file_level, ctr, preferred_len, hnd);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_file_enum("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* copy the data over to the ctr */
-
- ZERO_STRUCTP(ctr);
-
- ctr->switch_value = file_level;
-
- ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries;
-
- switch(file_level) {
- case 3:
- ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc(
- mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
-
- memset(ctr->file.info3, 0,
- sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
-
- for (i = 0; i < r.ctr.num_entries; i++) {
- SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i];
- char *s;
-
- /* Copy pointer crap */
-
- memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3,
- sizeof(FILE_INFO_3));
-
- /* Duplicate strings */
-
- s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name);
- if (s)
- init_unistr2(&info3->info_3_str.uni_path_name, s, UNI_STR_TERMINATE);
-
- s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name);
- if (s)
- init_unistr2(&info3->info_3_str.uni_user_name, s, UNI_STR_TERMINATE);
-
- }
-
- break;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 file_id)
-{
- prs_struct qbuf, rbuf;
- SRV_Q_NET_FILE_CLOSE q;
- SRV_R_NET_FILE_CLOSE r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
- init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_file_close("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
- return result;
-}
diff --git a/source/rpc_client/cli_trust.c b/source/rpc_client/cli_trust.c
new file mode 100755
index 00000000000..662c8443968
--- /dev/null
+++ b/source/rpc_client/cli_trust.c
@@ -0,0 +1,250 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+extern pstring global_myname;
+
+/*********************************************************
+ Change the domain password on the PDC.
+**********************************************************/
+
+static BOOL modify_trust_password( char *domain, char *remote_machine,
+ unsigned char orig_trust_passwd_hash[16],
+ unsigned char new_trust_passwd_hash[16])
+{
+ struct cli_state cli;
+ NTSTATUS result;
+ DOM_SID domain_sid;
+
+ /*
+ * Ensure we have the domain SID for this domain.
+ */
+
+ if (!secrets_fetch_domain_sid(domain, &domain_sid)) {
+ DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n"));
+ return False;
+ }
+
+ ZERO_STRUCT(cli);
+ if(cli_initialise(&cli) == NULL) {
+ DEBUG(0,("modify_trust_password: unable to initialize client connection.\n"));
+ return False;
+ }
+
+ if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
+ DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (ismyip(cli.dest_ip)) {
+ DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
+to ourselves.\n", remote_machine));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS session request.\n",
+ remote_machine ));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (cli.protocol != PROTOCOL_NT1) {
+ DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n",
+ remote_machine));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (!(cli.sec_mode & 1)) {
+ DEBUG(0,("modify_trust_password: machine %s isn't in user level security mode\n",
+ remote_machine));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
+ if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
+ DEBUG(0,("modify_trust_password: unable to open the domain client session to \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+ cli_nt_session_close(&cli);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ result = cli_nt_setup_creds(&cli, orig_trust_passwd_hash);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
+%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result)));
+ cli_nt_session_close(&cli);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) {
+ DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
+%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine,
+ cli_errstr(&cli)));
+ cli_close(&cli, cli.nt_pipe_fnum);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ cli_nt_session_close(&cli);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
+
+ return True;
+}
+
+/************************************************************************
+ Change the trust account password for a domain.
+ The user of this function must have locked the trust password file for
+ update.
+************************************************************************/
+
+BOOL change_trust_account_password( char *domain, const char *remote_machine_list)
+{
+ fstring remote_machine;
+ unsigned char old_trust_passwd_hash[16];
+ unsigned char new_trust_passwd_hash[16];
+ time_t lct;
+ BOOL res = False;
+
+ if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
+ DEBUG(0,("change_trust_account_password: unable to read the machine \
+account password for domain %s.\n", domain));
+ return False;
+ }
+
+ /*
+ * Create the new (random) password.
+ */
+ generate_random_buffer( new_trust_passwd_hash, 16, True);
+
+ while(remote_machine_list &&
+ next_token(&remote_machine_list, remote_machine,
+ LIST_SEP, sizeof(remote_machine))) {
+ strupper(remote_machine);
+ if(strequal(remote_machine, "*")) {
+
+ /*
+ * We have been asked to dynamcially determine the IP addresses of the PDC.
+ */
+
+ struct in_addr *ip_list = NULL;
+ int count = 0;
+ int i;
+
+ /* Use the PDC *only* for this. */
+ if(!get_dc_list(True, domain, &ip_list, &count))
+ continue;
+
+ /*
+ * Try and connect to the PDC/BDC list in turn as an IP
+ * address used as a string.
+ */
+
+ for(i = 0; i < count; i++) {
+ fstring dc_name;
+ if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name))
+ continue;
+ if((res = modify_trust_password( domain, dc_name,
+ old_trust_passwd_hash, new_trust_passwd_hash)))
+ break;
+ }
+
+ SAFE_FREE(ip_list);
+
+ } else {
+ res = modify_trust_password( domain, remote_machine,
+ old_trust_passwd_hash, new_trust_passwd_hash);
+ }
+
+ if(res) {
+ DEBUG(0,("%s : change_trust_account_password: Changed password for \
+domain %s.\n", timestring(False), domain));
+ /*
+ * Return the result of trying to write the new password
+ * back into the trust account file.
+ */
+ res = secrets_store_trust_account_password(domain, new_trust_passwd_hash);
+ memset(new_trust_passwd_hash, 0, 16);
+ memset(old_trust_passwd_hash, 0, 16);
+ return res;
+ }
+ }
+
+ memset(new_trust_passwd_hash, 0, 16);
+ memset(old_trust_passwd_hash, 0, 16);
+
+ DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
+domain %s.\n", timestring(False), domain));
+ return False;
+}
diff --git a/source/rpc_client/cli_wkssvc.c b/source/rpc_client/cli_wkssvc.c
deleted file mode 100644
index 97b948bf628..00000000000
--- a/source/rpc_client/cli_wkssvc.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Tim Potter 2001
- Copytight (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/**
- * WksQueryInfo rpc call (like query for server's capabilities)
- *
- * @param initialised client structure with \PIPE\wkssvc opened
- * @param mem_ctx memory context assigned to this rpc binding
- * @param wks100 WksQueryInfo structure
- *
- * @return NTSTATUS of rpc call
- */
-
-NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- WKS_INFO_100 *wks100)
-{
- prs_struct buf;
- prs_struct rbuf;
- WKS_Q_QUERY_INFO q_o;
- WKS_R_QUERY_INFO r_o;
-
- if (cli == NULL || wks100 == NULL)
- return NT_STATUS_UNSUCCESSFUL;
-
- /* init rpc parse structures */
- prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- DEBUG(4, ("WksQueryInfo\n"));
-
- /* init query structure with rpc call arguments */
- init_wks_q_query_info(&q_o, cli->desthost, 100);
-
- /* marshall data */
- if (!wks_io_q_query_info("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* actual rpc call over \PIPE\wkssvc */
- if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- prs_mem_free(&buf);
-
- r_o.wks100 = wks100;
-
- /* get call results from response buffer */
- if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* check returnet status code */
- if (NT_STATUS_IS_ERR(r_o.status)) {
- /* report the error */
- DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status)));
- prs_mem_free(&rbuf);
- return r_o.status;
- }
-
- /* do clean up */
- prs_mem_free(&rbuf);
-
- return NT_STATUS_OK;
-}
-
diff --git a/source/rpc_parse/parse_dfs.c b/source/rpc_parse/parse_dfs.c
index 0d0ce557b22..dc6cbca1c77 100644
--- a/source/rpc_parse/parse_dfs.c
+++ b/source/rpc_parse/parse_dfs.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* MSDfs RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
@@ -25,9 +26,6 @@
#include "nterr.h"
#include "rpc_parse.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
/*******************************************************************
Make a DFS_Q_DFS_QUERY structure
*******************************************************************/
@@ -80,9 +78,9 @@ BOOL init_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, const char *entrypath,
const char *servername, const char *sharename)
{
DEBUG(5,("init_dfs_q_dfs_remove\n"));
- init_unistr2(&q_d->DfsEntryPath, entrypath, UNI_STR_TERMINATE);
- init_unistr2(&q_d->ServerName, servername, UNI_STR_TERMINATE);
- init_unistr2(&q_d->ShareName, sharename, UNI_STR_TERMINATE);
+ init_unistr2(&q_d->DfsEntryPath, entrypath, strlen(entrypath)+1);
+ init_unistr2(&q_d->ServerName, servername, strlen(servername)+1);
+ init_unistr2(&q_d->ShareName, sharename, strlen(sharename)+1);
q_d->ptr_ServerName = q_d->ptr_ShareName = 1;
return True;
}
@@ -149,17 +147,16 @@ BOOL dfs_io_r_dfs_remove(const char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps
Make a DFS_Q_DFS_ADD structure
*******************************************************************/
-BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, const char *entrypath,
- const char *servername, const char *sharename,
- const char *comment, uint32 flags)
+BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, const char *entrypath, const char *servername,
+ const char *sharename, const char *comment, uint32 flags)
{
DEBUG(5,("init_dfs_q_dfs_add\n"));
q_d->ptr_DfsEntryPath = q_d->ptr_ServerName = q_d->ptr_ShareName = 1;
- init_unistr2(&q_d->DfsEntryPath, entrypath, UNI_STR_TERMINATE);
- init_unistr2(&q_d->ServerName, servername, UNI_STR_TERMINATE);
- init_unistr2(&q_d->ShareName, sharename, UNI_STR_TERMINATE);
+ init_unistr2(&q_d->DfsEntryPath, entrypath, strlen(entrypath)+1);
+ init_unistr2(&q_d->ServerName, servername, strlen(servername)+1);
+ init_unistr2(&q_d->ShareName, sharename, strlen(sharename)+1);
if(comment != NULL) {
- init_unistr2(&q_d->Comment, comment,UNI_STR_TERMINATE);
+ init_unistr2(&q_d->Comment, comment, strlen(comment)+1);
q_d->ptr_Comment = 1;
} else {
q_d->ptr_Comment = 0;
@@ -237,9 +234,9 @@ BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, const char *entrypath,
uint32 info_level)
{
DEBUG(5,("init_dfs_q2_get_info\n"));
- init_unistr2(&q_d->uni_path, entrypath, UNI_STR_TERMINATE);
- init_unistr2(&q_d->uni_server, servername, UNI_STR_TERMINATE);
- init_unistr2(&q_d->uni_share, sharename, UNI_STR_TERMINATE);
+ init_unistr2(&q_d->uni_path, entrypath, strlen(entrypath)+1);
+ init_unistr2(&q_d->uni_server, servername, strlen(servername)+1);
+ init_unistr2(&q_d->uni_share, sharename, strlen(sharename)+1);
q_d->level = info_level;
q_d->ptr_server = q_d->ptr_share = 1;
return True;
@@ -249,7 +246,7 @@ BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, const char *entrypath,
Read/write a DFS_Q_GET_INFO structure
************************************************************/
-BOOL dfs_io_q_dfs_get_info(const char *desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct* ps, int depth)
+BOOL dfs_io_q_dfs_get_info(const char* desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct* ps, int depth)
{
if(q_i == NULL)
return False;
@@ -289,7 +286,7 @@ BOOL dfs_io_q_dfs_get_info(const char *desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct
Read/write a DFS_R_GET_INFO structure
************************************************************/
-BOOL dfs_io_r_dfs_get_info(const char *desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps, int depth)
+BOOL dfs_io_r_dfs_get_info(const char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps, int depth)
{
if(r_i == NULL)
return False;
diff --git a/source/rpc_parse/parse_ds.c b/source/rpc_parse/parse_ds.c
deleted file mode 100644
index 8d894b6c6ad..00000000000
--- a/source/rpc_parse/parse_ds.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
-
- * Copyright (C) Gerald Carter 2002-2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/************************************************************************
-************************************************************************/
-
-static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic)
-{
- DSROLE_PRIMARY_DOMAIN_INFO_BASIC *p = *basic;
-
- if ( UNMARSHALLING(ps) )
- p = *basic = (DSROLE_PRIMARY_DOMAIN_INFO_BASIC *)prs_alloc_mem(ps, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC));
-
- if ( !p )
- return False;
-
- if ( !prs_uint16("machine_role", ps, depth, &p->machine_role) )
- return False;
- if ( !prs_uint16("unknown", ps, depth, &p->unknown) )
- return False;
-
- if ( !prs_uint32("flags", ps, depth, &p->flags) )
- return False;
-
- if ( !prs_uint32("netbios_ptr", ps, depth, &p->netbios_ptr) )
- return False;
- if ( !prs_uint32("dnsname_ptr", ps, depth, &p->dnsname_ptr) )
- return False;
- if ( !prs_uint32("forestname_ptr", ps, depth, &p->forestname_ptr) )
- return False;
-
- if ( !smb_io_uuid("domain_guid", &p->domain_guid, ps, depth) )
- return False;
-
- if ( !smb_io_unistr2( "netbios_domain", &p->netbios_domain, p->netbios_ptr, ps, depth) )
- return False;
- if ( !prs_align(ps) )
- return False;
-
- if ( !smb_io_unistr2( "dns_domain", &p->dns_domain, p->dnsname_ptr, ps, depth) )
- return False;
- if ( !prs_align(ps) )
- return False;
-
- if ( !smb_io_unistr2( "forest_domain", &p->forest_domain, p->forestname_ptr, ps, depth) )
- return False;
- if ( !prs_align(ps) )
- return False;
-
-
- return True;
-
-}
-
-/************************************************************************
-************************************************************************/
-
-BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_GETPRIMDOMINFO *q_u)
-{
- prs_debug(ps, depth, desc, "ds_io_q_getprimdominfo");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if ( !prs_uint16( "level", ps, depth, &q_u->level ) )
- return False;
-
- return True;
-}
-
-/************************************************************************
-************************************************************************/
-
-BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_GETPRIMDOMINFO *r_u)
-{
- prs_debug(ps, depth, desc, "ds_io_r_getprimdominfo");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if ( !prs_uint32( "ptr", ps, depth, &r_u->ptr ) )
- return False;
-
- if ( r_u->ptr )
- {
- if ( !prs_uint16( "level", ps, depth, &r_u->level ) )
- return False;
-
- if ( !prs_uint16( "unknown0", ps, depth, &r_u->unknown0 ) )
- return False;
-
- switch ( r_u->level )
- {
- case DsRolePrimaryDomainInfoBasic:
- if ( !ds_io_dominfobasic( "dominfobasic", ps, depth, &r_u->info.basic ) )
- return False;
- break;
- default:
- return False;
- }
- }
-
- if ( !prs_align(ps) )
- return False;
-
- if ( !prs_ntstatus("status", ps, depth, &r_u->status ) )
- return False;
-
- return True;
-}
-
-/************************************************************************
- initialize a DS_ENUM_DOM_TRUSTS structure
-************************************************************************/
-
-BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server,
- uint32 flags )
-{
- q->flags = flags;
-
- if ( server && *server )
- q->server_ptr = 1;
- else
- q->server_ptr = 0;
-
- init_unistr2( &q->server, server, UNI_STR_TERMINATE);
-
- return True;
-}
-
-/************************************************************************
-************************************************************************/
-
-static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS *trust)
-{
- prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr");
- depth++;
-
- if ( !prs_uint32( "netbios_ptr", ps, depth, &trust->netbios_ptr ) )
- return False;
-
- if ( !prs_uint32( "dns_ptr", ps, depth, &trust->dns_ptr ) )
- return False;
-
- if ( !prs_uint32( "flags", ps, depth, &trust->flags ) )
- return False;
-
- if ( !prs_uint32( "parent_index", ps, depth, &trust->parent_index ) )
- return False;
-
- if ( !prs_uint32( "trust_type", ps, depth, &trust->trust_type ) )
- return False;
-
- if ( !prs_uint32( "trust_attributes", ps, depth, &trust->trust_attributes ) )
- return False;
-
- if ( !prs_uint32( "sid_ptr", ps, depth, &trust->sid_ptr ) )
- return False;
-
- if ( !smb_io_uuid("guid", &trust->guid, ps, depth) )
- return False;
-
- return True;
-}
-
-/************************************************************************
-************************************************************************/
-
-static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS_CTR *ctr)
-{
- int i;
-
- prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr");
- depth++;
-
- if ( !prs_uint32( "ptr", ps, depth, &ctr->ptr ) )
- return False;
-
- if ( !prs_uint32( "max_count", ps, depth, &ctr->max_count ) )
- return False;
-
- /* are we done? */
-
- if ( ctr->max_count == 0 )
- return True;
-
- /* allocate the domain trusts array are parse it */
-
- ctr->trusts = (DS_DOMAIN_TRUSTS*)talloc(ps->mem_ctx, sizeof(DS_DOMAIN_TRUSTS)*ctr->max_count);
-
- if ( !ctr->trusts )
- return False;
-
- /* this stinks; the static portion o fthe structure is read here and then
- we need another loop to read the UNISTR2's and SID's */
-
- for ( i=0; i<ctr->max_count;i++ ) {
- if ( !ds_io_domain_trusts("domain_trusts", ps, depth, &ctr->trusts[i] ) )
- return False;
- }
-
- for ( i=0; i<ctr->max_count; i++ ) {
-
- if ( !smb_io_unistr2("netbios_domain", &ctr->trusts[i].netbios_domain, ctr->trusts[i].netbios_ptr, ps, depth) )
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if ( !smb_io_unistr2("dns_domain", &ctr->trusts[i].dns_domain, ctr->trusts[i].dns_ptr, ps, depth) )
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if ( ctr->trusts[i].sid_ptr ) {
- if ( !smb_io_dom_sid2("sid", &ctr->trusts[i].sid, ps, depth ) )
- return False;
- }
- }
-
- return True;
-}
-
-/************************************************************************
- initialize a DS_ENUM_DOM_TRUSTS request
-************************************************************************/
-
-BOOL ds_io_q_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_Q_ENUM_DOM_TRUSTS *q_u)
-{
- prs_debug(ps, depth, desc, "ds_io_q_enum_domain_trusts");
- depth++;
-
- if ( !prs_align(ps) )
- return False;
-
- if ( !prs_uint32( "server_ptr", ps, depth, &q_u->server_ptr ) )
- return False;
-
- if ( !smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth) )
- return False;
-
- if ( !prs_align(ps) )
- return False;
-
- if ( !prs_uint32( "flags", ps, depth, &q_u->flags ) )
- return False;
-
- return True;
-}
-
-/************************************************************************
-************************************************************************/
-
-BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_R_ENUM_DOM_TRUSTS *r_u)
-{
- prs_debug(ps, depth, desc, "ds_io_r_enum_domain_trusts");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if ( !prs_uint32( "num_domains", ps, depth, &r_u->num_domains ) )
- return False;
-
- if ( r_u->num_domains ) {
- if ( !ds_io_dom_trusts_ctr("domains", ps, depth, &r_u->domains ) )
- return False;
- }
-
- if(!prs_align(ps))
- return False;
-
- if ( !prs_ntstatus("status", ps, depth, &r_u->status ) )
- return False;
-
- return True;
-}
-
-
diff --git a/source/rpc_parse/parse_echo.c b/source/rpc_parse/parse_echo.c
deleted file mode 100644
index 4b1ff1f4d54..00000000000
--- a/source/rpc_parse/parse_echo.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- *
- * RPC Pipe client / server routines
- *
- * Copyright (C) Tim Potter 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "nterr.h"
-#include "rpc_parse.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-void init_echo_q_add_one(ECHO_Q_ADD_ONE *q_d, uint32 request)
-{
- q_d->request = request;
-}
-
-BOOL echo_io_q_add_one(const char *desc, ECHO_Q_ADD_ONE *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("request", ps, 0, &q_d->request))
- return False;
-
- return True;
-}
-
-BOOL echo_io_r_add_one(const char *desc, ECHO_R_ADD_ONE *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("response", ps, 0, &q_d->response))
- return False;
-
- return True;
-}
-
-
-void init_echo_q_echo_data(ECHO_Q_ECHO_DATA *q_d, uint32 size, char *data)
-{
- q_d->size = size;
- q_d->data = data;
-}
-
-BOOL echo_io_q_echo_data(const char *desc, ECHO_Q_ECHO_DATA *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("size", ps, depth, &q_d->size))
- return False;
-
- if (!prs_uint32("size", ps, depth, &q_d->size))
- return False;
-
- if (UNMARSHALLING(ps)) {
- q_d->data = prs_alloc_mem(ps, q_d->size);
-
- if (!q_d->data)
- return False;
- }
-
- if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
- return False;
-
- return True;
-}
-
-BOOL echo_io_r_echo_data(const char *desc, ECHO_R_ECHO_DATA *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("size", ps, 0, &q_d->size))
- return False;
-
- if (UNMARSHALLING(ps)) {
- q_d->data = prs_alloc_mem(ps, q_d->size);
-
- if (!q_d->data)
- return False;
- }
-
- if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
- return False;
-
- return True;
-}
-
-void init_echo_q_sink_data(ECHO_Q_SINK_DATA *q_d, uint32 size, char *data)
-{
- q_d->size = size;
- q_d->data = data;
-}
-
-BOOL echo_io_q_sink_data(const char *desc, ECHO_Q_SINK_DATA *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("size", ps, depth, &q_d->size))
- return False;
-
- if (!prs_uint32("size", ps, depth, &q_d->size))
- return False;
-
- if (UNMARSHALLING(ps)) {
- q_d->data = prs_alloc_mem(ps, q_d->size);
-
- if (!q_d->data)
- return False;
- }
-
- if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
- return False;
-
- return True;
-}
-
-BOOL echo_io_r_sink_data(const char *desc, ECHO_R_SINK_DATA *q_d,
- prs_struct *ps, int depth)
-{
- return True;
-}
-
-void init_echo_q_source_data(ECHO_Q_SOURCE_DATA *q_d, uint32 size)
-{
- q_d->size = size;
-}
-
-BOOL echo_io_q_source_data(const char *desc, ECHO_Q_SOURCE_DATA *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("size", ps, depth, &q_d->size))
- return False;
-
- return True;
-}
-
-BOOL echo_io_r_source_data(const char *desc, ECHO_R_SOURCE_DATA *q_d,
- prs_struct *ps, int depth)
-{
- if (!prs_uint32("size", ps, 0, &q_d->size))
- return False;
-
- if (UNMARSHALLING(ps)) {
- q_d->data = prs_alloc_mem(ps, q_d->size);
-
- if (!q_d->data)
- return False;
- }
-
- if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
- return False;
-
- return True;
-}
diff --git a/source/rpc_parse/parse_epmapper.c b/source/rpc_parse/parse_epmapper.c
deleted file mode 100644
index bc2cd175034..00000000000
--- a/source/rpc_parse/parse_epmapper.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba end point mapper functions
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-static uint32 internal_referent_id = 0;
-
-
-/*******************************************************************
- Reads or writes a handle.
-********************************************************************/
-BOOL epm_io_handle(const char *desc, EPM_HANDLE *handle, prs_struct *ps,
- int depth)
-{
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint8s(False, "data", ps, depth, handle->data,
- sizeof(handle->data)))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure.
-********************************************************************/
-NTSTATUS init_epm_floor(EPM_FLOOR *efloor, uint8 protocol)
-{
- /* handle lhs */
- efloor->lhs.protocol = protocol;
- efloor->lhs.length = sizeof(efloor->lhs.protocol);
-
- switch(efloor->lhs.protocol) {
- case EPM_FLOOR_UUID:
- efloor->lhs.length += sizeof(efloor->lhs.uuid.uuid);
- efloor->lhs.length += sizeof(efloor->lhs.uuid.version);
- break;
- default:
- break;
- }
-
- /* handle rhs */
- switch(efloor->lhs.protocol) {
- case EPM_FLOOR_RPC:
- case EPM_FLOOR_UUID:
- efloor->rhs.length = sizeof(efloor->rhs.unknown);
- break;
- case EPM_FLOOR_TCP:
- efloor->rhs.length = sizeof(efloor->rhs.tcp.port);
- break;
- case EPM_FLOOR_IP:
- efloor->rhs.length = sizeof(efloor->rhs.ip.addr);
- break;
- case EPM_FLOOR_NMPIPES:
- case EPM_FLOOR_LRPC:
- case EPM_FLOOR_NETBIOS:
- efloor->rhs.length = strlen(efloor->rhs.string) + 1;
- break;
- default:
- break;
- }
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure with a UUID
-********************************************************************/
-NTSTATUS init_epm_floor_uuid(EPM_FLOOR *efloor,
- const struct uuid uuid, uint16 version)
-{
- memcpy(&efloor->lhs.uuid.uuid, &uuid, sizeof(uuid));
- efloor->lhs.uuid.version = version;
- efloor->rhs.unknown = 0;
- return init_epm_floor(efloor, EPM_FLOOR_UUID);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for RPC
-********************************************************************/
-NTSTATUS init_epm_floor_rpc(EPM_FLOOR *efloor)
-{
- efloor->rhs.unknown = 0;
- return init_epm_floor(efloor, EPM_FLOOR_RPC);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for TCP
-********************************************************************/
-NTSTATUS init_epm_floor_tcp(EPM_FLOOR *efloor, uint16 port)
-{
- efloor->rhs.tcp.port = htons(port);
- return init_epm_floor(efloor, EPM_FLOOR_TCP);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for IP
-********************************************************************/
-NTSTATUS init_epm_floor_ip(EPM_FLOOR *efloor, uint8 addr[4])
-{
- memcpy(&efloor->rhs.ip.addr, addr, sizeof(addr));
- return init_epm_floor(efloor, EPM_FLOOR_IP);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for named pipe
-********************************************************************/
-NTSTATUS init_epm_floor_np(EPM_FLOOR *efloor, const char *pipe_name)
-{
- safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1);
- return init_epm_floor(efloor, EPM_FLOOR_NMPIPES);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for named pipe
-********************************************************************/
-NTSTATUS init_epm_floor_lrpc(EPM_FLOOR *efloor, const char *pipe_name)
-{
- safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1);
- return init_epm_floor(efloor, EPM_FLOOR_LRPC);
-}
-
-/*******************************************************************
- inits an EPM_FLOOR structure for named pipe
-********************************************************************/
-NTSTATUS init_epm_floor_nb(EPM_FLOOR *efloor, char *host_name)
-{
- safe_strcpy(efloor->rhs.string, host_name, sizeof(efloor->rhs.string)-1);
- return init_epm_floor(efloor, EPM_FLOOR_NETBIOS);
-}
-
-/*******************************************************************
- reads and writes EPM_FLOOR.
-********************************************************************/
-BOOL epm_io_floor(const char *desc, EPM_FLOOR *efloor,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "epm_io_floor");
- depth++;
-
- if (!prs_uint16("lhs_length", ps, depth, &efloor->lhs.length))
- return False;
- if (!prs_uint8("protocol", ps, depth, &efloor->lhs.protocol))
- return False;
-
- switch (efloor->lhs.protocol) {
- case EPM_FLOOR_UUID:
- if (!smb_io_uuid("uuid", &efloor->lhs.uuid.uuid, ps, depth))
- return False;
- if (!prs_uint16("version", ps, depth,
- &efloor->lhs.uuid.version))
- return False;
- break;
- }
-
- if (!prs_uint16("rhs_length", ps, depth, &efloor->rhs.length))
- return False;
-
- switch (efloor->lhs.protocol) {
- case EPM_FLOOR_UUID:
- case EPM_FLOOR_RPC:
- if (!prs_uint16("unknown", ps, depth, &efloor->rhs.unknown))
- return False;
- break;
- case EPM_FLOOR_TCP:
- if (!prs_uint16("tcp_port", ps, depth, &efloor->rhs.tcp.port))
- return False;
- break;
- case EPM_FLOOR_IP:
- if (!prs_uint8s(False, "ip_addr", ps, depth,
- efloor->rhs.ip.addr,
- sizeof(efloor->rhs.ip.addr)))
- return False;
- break;
- case EPM_FLOOR_NMPIPES:
- case EPM_FLOOR_LRPC:
- case EPM_FLOOR_NETBIOS:
- if (!prs_uint8s(False, "string", ps, depth,
- efloor->rhs.string,
- efloor->rhs.length))
- return False;
- break;
- default:
- break;
- }
-
- return True;
-}
-
-/*******************************************************************
- Inits a EPM_TOWER structure.
-********************************************************************/
-NTSTATUS init_epm_tower(TALLOC_CTX *ctx, EPM_TOWER *tower,
- const EPM_FLOOR *floors, int num_floors)
-{
- int size = 0;
- int i;
-
- DEBUG(5, ("init_epm_tower\n"));
-
- size += sizeof(uint16); /* number of floors is in tower length */
- for (i = 0; i < num_floors; i++) {
- size += (sizeof(uint16) * 2);
- size += floors[i].lhs.length;
- size += floors[i].rhs.length;
- }
-
- tower->max_length = tower->length = size;
- tower->num_floors = num_floors;
- tower->floors = talloc(ctx, sizeof(EPM_FLOOR) * num_floors);
- if (!tower->floors) {
- return NT_STATUS_NO_MEMORY;
- }
- memcpy(tower->floors, floors, sizeof(EPM_FLOOR) * num_floors);
- tower->unknown = 0x7e;
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Reads or writes an EPM_TOWER structure.
-********************************************************************/
-BOOL epm_io_tower(const char *desc, EPM_TOWER *tower,
- prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "epm_io_tower");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("max_length", ps, depth, &tower->max_length))
- return False;
- if (!prs_uint32("length", ps, depth, &tower->length))
- return False;
- if (!prs_uint16("num_floors", ps, depth, &tower->num_floors))
- return False;
-
- if (UNMARSHALLING(ps)) {
- tower->floors = talloc(ps->mem_ctx,
- sizeof(EPM_FLOOR) * tower->num_floors);
- if (!tower->floors)
- return False;
- }
-
- for (i = 0; i < tower->num_floors; i++) {
- if (!epm_io_floor("floor", tower->floors + i, ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Initialize an EPM_TOWER_ARRAY structure
-********************************************************************/
-NTSTATUS init_epm_tower_array(TALLOC_CTX *ctx, EPM_TOWER_ARRAY *array,
- const EPM_TOWER *towers, int num_towers)
-{
- int i;
-
- array->max_count = num_towers;
- array->offset = 0;
- array->count = num_towers;
- array->tower_ref_ids = talloc(ctx, sizeof(uint32) * num_towers);
- if (!array->tower_ref_ids) {
- return NT_STATUS_NO_MEMORY;
- }
- for (i=0;i<num_towers;i++)
- array->tower_ref_ids[i] = ++internal_referent_id;
-
- array->towers = talloc(ctx, sizeof(EPM_TOWER) * num_towers);
- if (!array->towers) {
- return NT_STATUS_NO_MEMORY;
- }
- memcpy(array->towers, towers, sizeof(EPM_TOWER) * num_towers);
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Reads or writes an EPM_TOWER_ARRAY structure.
-********************************************************************/
-BOOL epm_io_tower_array(const char *desc, EPM_TOWER_ARRAY *array,
- prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "epm_io_tower_array");
- depth++;
-
- if (!prs_uint32("max_count", ps, depth, &array->max_count))
- return False;
- if (!prs_uint32("offset", ps, depth, &array->offset))
- return False;
- if (!prs_uint32("count", ps, depth, &array->count))
- return False;
-
-
- if (UNMARSHALLING(ps)) {
- array->tower_ref_ids = talloc(ps->mem_ctx,
- sizeof(uint32) * array->count);
- if (!array->tower_ref_ids) {
- return False;
- }
- }
- for (i=0; i < array->count; i++) {
- if (!prs_uint32("ref_id", ps, depth, &array->tower_ref_ids[i])) {
- return False;
- } else {
- if (array->tower_ref_ids[i] > internal_referent_id) {
- internal_referent_id = array->tower_ref_ids[i];
- }
- }
- }
-
-
-
- if (!prs_set_offset(ps, prs_offset(ps) + array->offset))
- return False;
-
- if (UNMARSHALLING(ps)) {
- array->towers = talloc(ps->mem_ctx,
- sizeof(EPM_TOWER) * array->count);
- if (!array->towers) {
- return False;
- }
- }
-
- for (i = 0; i < array->count; i++) {
- if (!epm_io_tower("tower", &array->towers[i], ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Initialize EPM_R_MAP structure
-******************************************************************/
-NTSTATUS init_epm_r_map(TALLOC_CTX *ctx, EPM_R_MAP *r_map,
- const EPM_HANDLE *handle, const EPM_TOWER_ARRAY *array,
- int num_elements, uint32 status)
-{
- memcpy(&r_map->handle, handle, sizeof(*handle));
- r_map->num_results = num_elements;
- r_map->results = talloc(ctx, sizeof(EPM_TOWER_ARRAY) * num_elements);
- if (!r_map->results) {
- return NT_STATUS_NO_MEMORY;
- }
- memcpy(r_map->results, array, sizeof(EPM_TOWER_ARRAY) * num_elements);
- r_map->status = status;
- return NT_STATUS_OK;
-}
-
-/*************************************************************************
- Inits a EPM_Q_MAP structure.
-**************************************************************************
-* We attempt to hide the ugliness of the wire format by taking a EPM_TOWER
-* array with a defined size
-**************************************************************************/
-NTSTATUS init_epm_q_map(TALLOC_CTX *ctx, EPM_Q_MAP *q_map,
- const EPM_TOWER *towers, int num_towers)
-{
- static uint32 handle = 1;
-
- ZERO_STRUCTP(q_map);
-
- DEBUG(5, ("init_epm_q_map\n"));
- q_map->handle.data[0] = (handle >> 0) & 0xFF;
- q_map->handle.data[1] = (handle >> 8) & 0xFF;
- q_map->handle.data[2] = (handle >> 16) & 0xFF;
- q_map->handle.data[3] = (handle >> 24) & 0xFF;
-
- q_map->tower = talloc(ctx, sizeof(EPM_TOWER) * (num_towers + 1));
- if (!q_map->tower) {
- return NT_STATUS_NO_MEMORY;
- }
-
- memcpy(q_map->tower, towers, sizeof(EPM_TOWER) * num_towers);
-
- ZERO_STRUCT(q_map->tower[num_towers]);
-
- /* For now let's not take more than 4 towers per result */
- q_map->max_towers = num_towers * 4;
-
- q_map->tower_ref_id = ++internal_referent_id;
-
- handle++;
-
- return NT_STATUS_OK;
-}
-
-/*****************************************************************
- epm_io_q_map - read or write EPM_Q_MAP structure
-******************************************************************/
-BOOL epm_io_q_map(const char *desc, EPM_Q_MAP *io_map, prs_struct *ps,
- int depth)
-{
- prs_debug(ps, depth, desc, "epm_io_q_map");
- depth++;
-
- if (!epm_io_handle("handle", &io_map->handle, ps, depth))
- return False;
-
- if (!prs_uint32("referent_id", ps, 0, &io_map->tower_ref_id))
- return False;
- if (io_map->tower_ref_id > internal_referent_id)
- internal_referent_id = io_map->tower_ref_id;
-
- /* HACK: We need a more elegant way of doing this */
- if (UNMARSHALLING(ps)) {
- io_map->tower = talloc(ps->mem_ctx, sizeof(EPM_TOWER));
- if (!io_map->tower)
- return False;
- }
- if (!epm_io_tower("tower", io_map->tower, ps, depth))
- return False;
- if (!epm_io_handle("term_handle", &io_map->term_handle, ps, depth))
- return False;
-
- if (!prs_uint32("max_towers", ps, 0, &io_map->max_towers))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- epm_io_r_map - Read/Write EPM_R_MAP structure
-******************************************************************/
-BOOL epm_io_r_map(const char *desc, EPM_R_MAP *io_map,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "epm_io_r_map");
- depth++;
-
- if (!epm_io_handle("handle", &io_map->handle, ps, depth))
- return False;
- if (!prs_uint32("num_results", ps, depth, &io_map->num_results))
- return False;
-
- if (UNMARSHALLING(ps)) {
- io_map->results = talloc(ps->mem_ctx,
- sizeof(EPM_TOWER_ARRAY) *
- io_map->num_results);
- if (!io_map->results)
- return False;
- }
- if (!epm_io_tower_array("results", io_map->results, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("status", ps, depth, &io_map->status))
- return False;
-
- return True;
-}
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index 50fd3beb48e..bce5c1c1964 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -3,9 +3,7 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Andrew Bartlett 2002,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
+ * Copyright (C) Paul Ashton 1997.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,9 +22,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
static BOOL lsa_io_trans_names(const char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth);
/*******************************************************************
@@ -36,9 +31,14 @@ static BOOL lsa_io_trans_names(const char *desc, LSA_TRANS_NAME_ENUM *trn, prs_s
void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
uint16 sid_name_use, const char *name, uint32 idx)
{
+ int len_name = strlen(name);
+
+ if(len_name == 0)
+ len_name = 1;
+
trn->sid_name_use = sid_name_use;
- init_unistr2(uni_name, name, UNI_FLAGS_NONE);
- init_uni_hdr(&trn->hdr_name, uni_name);
+ init_uni_hdr(&trn->hdr_name, len_name);
+ init_unistr2(uni_name, name, len_name);
trn->domain_idx = idx;
}
@@ -75,7 +75,7 @@ static BOOL lsa_io_trans_name(const char *desc, LSA_TRANS_NAME *trn, prs_struct
static BOOL lsa_io_dom_r_ref(const char *desc, DOM_R_REF *r_r, prs_struct *ps,
int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "lsa_io_dom_r_ref");
depth++;
@@ -188,7 +188,7 @@ static BOOL lsa_io_sec_qos(const char *desc, LSA_SEC_QOS *qos, prs_struct *ps,
Inits an LSA_OBJ_ATTR structure.
********************************************************************/
-static void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
+void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
{
DEBUG(5, ("init_lsa_obj_attr\n"));
@@ -341,7 +341,8 @@ void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name,
r_q->des_access = desired_access;
- init_unistr2(&r_q->uni_server_name, server_name, UNI_STR_TERMINATE);
+ init_unistr2(&r_q->uni_server_name, server_name,
+ strlen(server_name) + 1);
init_lsa_obj_attr(&r_q->attr, attributes, qos);
}
@@ -522,52 +523,40 @@ BOOL lsa_io_q_enum_trust_dom(const char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
Inits an LSA_R_ENUM_TRUST_DOM structure.
********************************************************************/
-void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
- uint32 req_num_domains, uint32 num_domains, TRUSTDOM **td)
+void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
+ const char *domain_name, DOM_SID *domain_sid,
+ NTSTATUS status)
{
- unsigned int i;
-
DEBUG(5, ("init_r_enum_trust_dom\n"));
r_e->enum_context = enum_context;
- r_e->num_domains = num_domains;
- r_e->ptr_enum_domains = 0;
- r_e->num_domains2 = num_domains;
- if (num_domains != 0) {
-
- /*
- * allocating empty arrays of unicode headers, strings
- * and sids of enumerated trusted domains
- */
- if (!(r_e->hdr_domain_name = (UNIHDR2 *)talloc(ctx,sizeof(UNIHDR2) * num_domains))) {
- r_e->status = NT_STATUS_NO_MEMORY;
- return;
- }
+ if (NT_STATUS_IS_OK(status)) {
+ int len_domain_name = strlen(domain_name) + 1;
- if (!(r_e->uni_domain_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2) * num_domains))) {
- r_e->status = NT_STATUS_NO_MEMORY;
+ r_e->num_domains = 1;
+ r_e->ptr_enum_domains = 1;
+ r_e->num_domains2 = 1;
+
+ if (!(r_e->hdr_domain_name = (UNIHDR2 *)talloc(ctx,sizeof(UNIHDR2))))
return;
- }
- if (!(r_e->domain_sid = (DOM_SID2 *)talloc(ctx,sizeof(DOM_SID2) * num_domains))) {
- r_e->status = NT_STATUS_NO_MEMORY;
+ if (!(r_e->uni_domain_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2))))
+ return;
+
+ if (!(r_e->domain_sid = (DOM_SID2 *)talloc(ctx,sizeof(DOM_SID2))))
return;
- }
-
- for (i = 0; i < num_domains; i++) {
-
- /* don't know what actually is this for */
- r_e->ptr_enum_domains = 1;
-
- init_dom_sid2(&r_e->domain_sid[i], &(td[i])->sid);
-
- init_unistr2_w(ctx, &r_e->uni_domain_name[i], (td[i])->name);
- init_uni_hdr2(&r_e->hdr_domain_name[i], &r_e->uni_domain_name[i]);
-
- };
- }
+ init_uni_hdr2(&r_e->hdr_domain_name[0], len_domain_name);
+ init_unistr2 (&r_e->uni_domain_name[0], domain_name,
+ len_domain_name);
+ init_dom_sid2(&r_e->domain_sid[0], domain_sid);
+ } else {
+ r_e->num_domains = 0;
+ r_e->ptr_enum_domains = 0;
+ }
+
+ r_e->status = status;
}
/*******************************************************************
@@ -614,7 +603,7 @@ BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
for (i = 0; i < num_domains; i++) {
if(!smb_io_unistr2 ("", &r_e->uni_domain_name[i],
- r_e->hdr_domain_name[i].buffer,
+ r_e->hdr_domain_name[i].buffer,
ps, depth))
return False;
if(!smb_io_dom_sid2("", &r_e->domain_sid[i], ps,
@@ -724,7 +713,7 @@ static BOOL lsa_io_dom_query_3(const char *desc, DOM_QUERY_3 *d_q, prs_struct *p
Reads or writes a dom query structure.
********************************************************************/
-static BOOL lsa_io_dom_query_5(const char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth)
+BOOL lsa_io_dom_query_5(const char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth)
{
return lsa_io_dom_query("", d_q, ps, depth);
}
@@ -803,8 +792,8 @@ BOOL lsa_io_r_query(const char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps,
Inits a LSA_SID_ENUM structure.
********************************************************************/
-static void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
- int num_entries, const DOM_SID *sids)
+void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
+ int num_entries, DOM_SID *sids)
{
int i;
@@ -845,7 +834,7 @@ static void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
static BOOL lsa_io_sid_enum(const char *desc, LSA_SID_ENUM *sen, prs_struct *ps,
int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "lsa_io_sid_enum");
depth++;
@@ -913,10 +902,10 @@ static BOOL lsa_io_sid_enum(const char *desc, LSA_SID_ENUM *sen, prs_struct *ps,
********************************************************************/
void init_q_lookup_sids(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_SIDS *q_l,
- POLICY_HND *hnd, int num_sids, const DOM_SID *sids,
+ POLICY_HND *hnd, int num_sids, DOM_SID *sids,
uint16 level)
{
- DEBUG(5, ("init_q_lookup_sids\n"));
+ DEBUG(5, ("init_r_enum_trust_dom\n"));
ZERO_STRUCTP(q_l);
@@ -961,7 +950,7 @@ BOOL lsa_io_q_lookup_sids(const char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *
static BOOL lsa_io_trans_names(const char *desc, LSA_TRANS_NAME_ENUM *trn,
prs_struct *ps, int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "lsa_io_trans_names");
depth++;
@@ -1057,7 +1046,7 @@ makes a structure.
void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l,
POLICY_HND *hnd, int num_names, const char **names)
{
- unsigned int i;
+ int i;
DEBUG(5, ("init_q_lookup_names\n"));
@@ -1081,8 +1070,11 @@ void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l,
}
for (i = 0; i < num_names; i++) {
- init_unistr2(&q_l->uni_name[i], names[i], UNI_FLAGS_NONE);
- init_uni_hdr(&q_l->hdr_name[i], &q_l->uni_name[i]);
+ int len;
+ len = strlen(unix_to_dos_static(names[i]));
+
+ init_uni_hdr(&q_l->hdr_name[i], len);
+ init_unistr2(&q_l->uni_name[i], unix_to_dos_static(names[i]), len);
}
}
@@ -1093,7 +1085,7 @@ reads or writes a structure.
BOOL lsa_io_q_lookup_names(const char *desc, LSA_Q_LOOKUP_NAMES *q_r,
prs_struct *ps, int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "lsa_io_q_lookup_names");
depth++;
@@ -1157,7 +1149,7 @@ reads or writes a structure.
BOOL lsa_io_r_lookup_names(const char *desc, LSA_R_LOOKUP_NAMES *r_r,
prs_struct *ps, int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "lsa_io_r_lookup_names");
depth++;
@@ -1427,10 +1419,15 @@ BOOL lsa_io_r_enum_privs(const char *desc, LSA_R_ENUM_PRIVS *r_q, prs_struct *ps
void init_lsa_priv_get_dispname(LSA_Q_PRIV_GET_DISPNAME *trn, POLICY_HND *hnd, const char *name, uint16 lang_id, uint16 lang_id_sys)
{
+ int len_name = strlen(name);
+
+ if(len_name == 0)
+ len_name = 1;
+
memcpy(&trn->pol, hnd, sizeof(trn->pol));
- init_unistr2(&trn->name, name, UNI_FLAGS_NONE);
- init_uni_hdr(&trn->hdr_name, &trn->name);
+ init_uni_hdr(&trn->hdr_name, len_name);
+ init_unistr2(&trn->name, name, len_name);
trn->lang_id = lang_id;
trn->lang_id_sys = lang_id_sys;
}
@@ -1505,9 +1502,6 @@ BOOL lsa_io_r_priv_get_dispname(const char *desc, LSA_R_PRIV_GET_DISPNAME *r_q,
return True;
}
-/*
- initialise a LSA_Q_ENUM_ACCOUNTS structure
-*/
void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length)
{
memcpy(&trn->pol, hnd, sizeof(trn->pol));
@@ -1538,7 +1532,6 @@ BOOL lsa_io_q_enum_accounts(const char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_stru
return True;
}
-
/*******************************************************************
Inits an LSA_R_ENUM_PRIVS structure.
********************************************************************/
@@ -1662,61 +1655,6 @@ BOOL lsa_io_r_unk_get_connuser(const char *desc, LSA_R_UNK_GET_CONNUSER *r_c, pr
return True;
}
-void init_lsa_q_create_account(LSA_Q_CREATEACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access)
-{
- memcpy(&trn->pol, hnd, sizeof(trn->pol));
-
- init_dom_sid2(&trn->sid, sid);
- trn->access = desired_access;
-}
-
-
-/*******************************************************************
- Reads or writes an LSA_Q_CREATEACCOUNT structure.
-********************************************************************/
-
-BOOL lsa_io_q_create_account(const char *desc, LSA_Q_CREATEACCOUNT *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_q_create_account");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("sid", &r_c->sid, ps, depth)) /* domain SID */
- return False;
-
- if(!prs_uint32("access", ps, depth, &r_c->access))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes an LSA_R_CREATEACCOUNT structure.
-********************************************************************/
-
-BOOL lsa_io_r_create_account(const char *desc, LSA_R_CREATEACCOUNT *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_open_account");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
-
-
void init_lsa_q_open_account(LSA_Q_OPENACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access)
{
memcpy(&trn->pol, hnd, sizeof(trn->pol));
@@ -1799,7 +1737,7 @@ BOOL lsa_io_q_enum_privsaccount(const char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, p
Reads or writes an LUID structure.
********************************************************************/
-static BOOL lsa_io_luid(const char *desc, LUID *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_luid(const char *desc, LUID *r_c, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_luid");
depth++;
@@ -1820,7 +1758,7 @@ static BOOL lsa_io_luid(const char *desc, LUID *r_c, prs_struct *ps, int depth)
Reads or writes an LUID_ATTR structure.
********************************************************************/
-static BOOL lsa_io_luid_attr(const char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_luid_attr(const char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_luid_attr");
depth++;
@@ -1841,7 +1779,7 @@ static BOOL lsa_io_luid_attr(const char *desc, LUID_ATTR *r_c, prs_struct *ps, i
Reads or writes an PRIVILEGE_SET structure.
********************************************************************/
-static BOOL lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth)
{
uint32 i;
@@ -1864,24 +1802,14 @@ static BOOL lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *r_c, prs_struc
return True;
}
-NTSTATUS init_lsa_r_enum_privsaccount(TALLOC_CTX *mem_ctx, LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control)
+void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control)
{
- NTSTATUS ret = NT_STATUS_OK;
-
- r_u->ptr = 1;
- r_u->count = count;
-
- if (!NT_STATUS_IS_OK(ret = init_priv_with_ctx(mem_ctx, &(r_u->set))))
- return ret;
-
- r_u->set->count = count;
-
- if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(r_u->set->mem_ctx, &(r_u->set->set), set, count)))
- return ret;
-
- DEBUG(10,("init_lsa_r_enum_privsaccount: %d privileges\n", r_u->count));
-
- return ret;
+ r_u->ptr=1;
+ r_u->count=count;
+ r_u->set.set=set;
+ r_u->set.count=count;
+ r_u->set.control=control;
+ DEBUG(10,("init_lsa_r_enum_privsaccount: %d %d privileges\n", r_u->count, r_u->set.count));
}
/*******************************************************************
@@ -1905,16 +1833,13 @@ BOOL lsa_io_r_enum_privsaccount(const char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, p
/* malloc memory if unmarshalling here */
- if (UNMARSHALLING(ps) && r_c->count != 0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
- return False;
-
- if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
+ if (UNMARSHALLING(ps) && r_c->count!=0) {
+ if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
}
@@ -2008,9 +1933,14 @@ BOOL lsa_io_r_setsystemaccount(const char *desc, LSA_R_SETSYSTEMACCOUNT *r_c, p
void init_lsa_q_lookupprivvalue(LSA_Q_LOOKUPPRIVVALUE *trn, POLICY_HND *hnd, const char *name)
{
+ int len_name = strlen(name);
memcpy(&trn->pol, hnd, sizeof(trn->pol));
- init_unistr2(&trn->uni2_right, name, UNI_FLAGS_NONE);
- init_uni_hdr(&trn->hdr_right, &trn->uni2_right);
+
+ if(len_name == 0)
+ len_name = 1;
+
+ init_uni_hdr(&trn->hdr_right, len_name);
+ init_unistr2(&trn->uni2_right, name, len_name);
}
/*******************************************************************
@@ -2076,14 +2006,11 @@ BOOL lsa_io_q_addprivs(const char *desc, LSA_Q_ADDPRIVS *r_c, prs_struct *ps, in
return False;
if (UNMARSHALLING(ps) && r_c->count!=0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
- return False;
-
- if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps, sizeof(LUID_ATTR) * r_c->count)))
+ if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
return True;
@@ -2138,14 +2065,11 @@ BOOL lsa_io_q_removeprivs(const char *desc, LSA_Q_REMOVEPRIVS *r_c, prs_struct *
return False;
if (UNMARSHALLING(ps) && r_c->count!=0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
- return False;
-
- if (!(r_c->set->set = (LUID_ATTR *)prs_alloc_mem(ps, sizeof(LUID_ATTR) * r_c->count)))
+ if (!(r_c->set.set = (LUID_ATTR *)prs_alloc_mem(ps,sizeof(LUID_ATTR) * r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
}
@@ -2177,298 +2101,3 @@ BOOL policy_handle_is_valid(const POLICY_HND *hnd)
ZERO_STRUCT(zero_pol);
return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True );
}
-
-/*******************************************************************
- Reads or writes an LSA_DNS_DOM_INFO structure.
-********************************************************************/
-
-BOOL lsa_io_dns_dom_info(const char *desc, LSA_DNS_DOM_INFO *info,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_dns_dom_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth))
- return False;
- if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth))
- return False;
- if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if ( !smb_io_uuid("dom_guid", &info->dom_guid, ps, depth) )
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid))
- return False;
-
- if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name,
- info->hdr_nb_dom_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name,
- info->hdr_dns_dom_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("forest", &info->uni_forest_name,
- info->hdr_forest_name.buffer, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
- return False;
-
- return True;
-
-}
-
-/*******************************************************************
- Inits an LSA_Q_QUERY_INFO2 structure.
-********************************************************************/
-
-void init_q_query2(LSA_Q_QUERY_INFO2 *q_q, POLICY_HND *hnd, uint16 info_class)
-{
- DEBUG(5, ("init_q_query2\n"));
-
- memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
-
- q_q->info_class = info_class;
-}
-
-/*******************************************************************
- Reads or writes an LSA_Q_QUERY_DNSDOMINFO structure.
-********************************************************************/
-
-BOOL lsa_io_q_query_info2(const char *desc, LSA_Q_QUERY_INFO2 *q_c,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_q_query_info2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("pol", &q_c->pol, ps, depth))
- return False;
-
- if(!prs_uint16("info_class", ps, depth, &q_c->info_class))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes an LSA_R_QUERY_DNSDOMINFO structure.
-********************************************************************/
-
-BOOL lsa_io_r_query_info2(const char *desc, LSA_R_QUERY_INFO2 *r_c,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_query_info2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
- return False;
- if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
- return False;
- switch(r_c->info_class) {
- case 0x000c:
- if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
- ps, depth))
- return False;
- break;
- default:
- DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
- r_c->info_class));
- return False;
- }
-
- if(!prs_align(ps))
- return False;
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
- Inits an LSA_Q_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-void init_q_enum_acct_rights(LSA_Q_ENUM_ACCT_RIGHTS *q_q,
- POLICY_HND *hnd,
- uint32 count,
- DOM_SID *sid)
-{
- DEBUG(5, ("init_q_enum_acct_rights\n"));
-
- q_q->pol = *hnd;
- init_dom_sid2(&q_q->sid, sid);
-}
-
-/*******************************************************************
-reads or writes a LSA_Q_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_q_enum_acct_rights(const char *desc, LSA_Q_ENUM_ACCT_RIGHTS *q_q, prs_struct *ps, int depth)
-{
-
- if (q_q == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "lsa_io_q_enum_acct_rights");
- depth++;
-
- if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
-reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_enum_acct_rights");
- depth++;
-
- if(!prs_uint32("count ", ps, depth, &r_c->count))
- return False;
-
- if(!smb_io_unistr2_array("rights", &r_c->rights, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
- Inits an LSA_Q_ADD_ACCT_RIGHTS structure.
-********************************************************************/
-void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q,
- POLICY_HND *hnd,
- DOM_SID *sid,
- uint32 count,
- const char **rights)
-{
- DEBUG(5, ("init_q_add_acct_rights\n"));
-
- q_q->pol = *hnd;
- init_dom_sid2(&q_q->sid, sid);
- init_unistr2_array(&q_q->rights, count, rights);
- q_q->count = 5;
-}
-
-
-/*******************************************************************
-reads or writes a LSA_Q_ADD_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *q_q, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_q_add_acct_rights");
- depth++;
-
- if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth))
- return False;
-
- if(!prs_uint32("count", ps, depth, &q_q->rights.count))
- return False;
-
- if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_r_add_acct_rights(const char *desc, LSA_R_ADD_ACCT_RIGHTS *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_add_acct_rights");
- depth++;
-
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
- Inits an LSA_Q_REMOVE_ACCT_RIGHTS structure.
-********************************************************************/
-void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q,
- POLICY_HND *hnd,
- DOM_SID *sid,
- uint32 removeall,
- uint32 count,
- const char **rights)
-{
- DEBUG(5, ("init_q_remove_acct_rights\n"));
-
- q_q->pol = *hnd;
- init_dom_sid2(&q_q->sid, sid);
- q_q->removeall = removeall;
- init_unistr2_array(&q_q->rights, count, rights);
- q_q->count = 5;
-}
-
-
-/*******************************************************************
-reads or writes a LSA_Q_REMOVE_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_q_remove_acct_rights");
- depth++;
-
- if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth))
- return False;
-
- if(!prs_uint32("removeall", ps, depth, &q_q->removeall))
- return False;
-
- if(!prs_uint32("count", ps, depth, &q_q->rights.count))
- return False;
-
- if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure.
-********************************************************************/
-BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *r_c, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "lsa_io_r_remove_acct_rights");
- depth++;
-
- if(!prs_ntstatus("status", ps, depth, &r_c->status))
- return False;
-
- return True;
-}
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index cea31c88a80..e1cd3eb5122 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -14,16 +15,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ e
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
+#include "includes.h"
/****************************************************************************
A temporary TALLOC context for things like unistrs, that is valid for
@@ -32,7 +31,7 @@
static TALLOC_CTX *current_rpc_talloc = NULL;
-static TALLOC_CTX *get_current_rpc_talloc(void)
+TALLOC_CTX *get_current_rpc_talloc(void)
{
return current_rpc_talloc;
}
@@ -63,7 +62,7 @@ void main_loop_talloc_free(void)
TALLOC_CTX *main_loop_talloc_get(void)
{
if (!main_loop_talloc) {
- main_loop_talloc = talloc_init("main loop talloc (mainly parse_misc)");
+ main_loop_talloc = talloc_init();
if (!main_loop_talloc)
smb_panic("main_loop_talloc: malloc fail\n");
}
@@ -214,9 +213,11 @@ BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "smb_io_dom_sid");
depth++;
+ if(!prs_align(ps))
+ return False;
+
if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
return False;
-
if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths))
return False;
@@ -251,7 +252,8 @@ void init_dom_sid(DOM_SID *sid, const char *str_sid)
int identauth;
char *p;
- if (str_sid == NULL) {
+ if (str_sid == NULL)
+ {
DEBUG(4,("netlogon domain SID: none\n"));
sid->sid_rev_num = 0;
sid->num_auths = 0;
@@ -323,34 +325,6 @@ BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
}
/*******************************************************************
- Reads or writes a struct uuid
-********************************************************************/
-
-BOOL smb_io_uuid(const char *desc, struct uuid *uuid,
- prs_struct *ps, int depth)
-{
- if (uuid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_uuid");
- depth++;
-
- if(!prs_uint32 ("data ", ps, depth, &uuid->time_low))
- return False;
- if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid))
- return False;
- if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version))
- return False;
-
- if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq)))
- return False;
- if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node)))
- return False;
-
- return True;
-}
-
-/*******************************************************************
creates a STRHDR structure.
********************************************************************/
@@ -389,11 +363,11 @@ BOOL smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth)
Inits a UNIHDR structure.
********************************************************************/
-void init_uni_hdr(UNIHDR *hdr, UNISTR2 *str2)
+void init_uni_hdr(UNIHDR *hdr, int len)
{
- hdr->uni_str_len = 2 * (str2->uni_str_len);
- hdr->uni_max_len = 2 * (str2->uni_max_len);
- hdr->buffer = (str2->uni_str_len != 0) ? 1 : 0;
+ hdr->uni_str_len = 2 * len;
+ hdr->uni_max_len = 2 * len;
+ hdr->buffer = len != 0 ? 1 : 0;
}
/*******************************************************************
@@ -510,10 +484,10 @@ BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
creates a UNIHDR2 structure.
********************************************************************/
-void init_uni_hdr2(UNIHDR2 *hdr, UNISTR2 *str2)
+void init_uni_hdr2(UNIHDR2 *hdr, int len)
{
- init_uni_hdr(&hdr->unihdr, str2);
- hdr->buffer = (str2->uni_str_len > 0) ? 1 : 0;
+ init_uni_hdr(&hdr->unihdr, len);
+ hdr->buffer = (len > 0) ? 1 : 0;
}
/*******************************************************************
@@ -563,7 +537,8 @@ void init_unistr(UNISTR *str, const char *buf)
if (str->buffer == NULL)
smb_panic("init_unistr: malloc fail\n");
- rpcstr_push(str->buffer, buf, len, STR_TERMINATE);
+ /* store the string (null-terminated copy) */
+ dos_struni2((char *)str->buffer, buf, len);
}
/*******************************************************************
@@ -594,7 +569,7 @@ static void create_buffer3(BUFFER3 *str, size_t len)
if (len < MAX_BUFFERLEN)
len = MAX_BUFFERLEN;
- str->buffer = talloc_zero(get_talloc_ctx(), len);
+ str->buffer = talloc_zero(get_talloc_ctx(), len);
if (str->buffer == NULL)
smb_panic("create_buffer3: talloc fail\n");
@@ -620,25 +595,25 @@ void init_buffer3_uint32(BUFFER3 *str, uint32 val)
Inits a BUFFER3 structure.
********************************************************************/
-void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
+void init_buffer3_str(BUFFER3 *str, char *buf, int len)
{
ZERO_STRUCTP(str);
/* set up string lengths. */
str->buf_max_len = len * 2;
- str->buf_len = len * 2;
+ str->buf_len = len * 2;
create_buffer3(str, str->buf_max_len);
- rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
-
+ /* store the string (null-terminated 8 bit chars into 16 bit chars) */
+ dos_struni2((char *)str->buffer, buf, str->buf_max_len);
}
/*******************************************************************
Inits a BUFFER3 structure from a hex string.
********************************************************************/
-void init_buffer3_hex(BUFFER3 *str, const char *buf)
+void init_buffer3_hex(BUFFER3 *str, char *buf)
{
ZERO_STRUCTP(str);
create_buffer3(str, strlen(buf));
@@ -725,13 +700,13 @@ BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
Inits a BUFFER2 structure.
********************************************************************/
-void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
+void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
{
ZERO_STRUCTP(str);
/* max buffer size (allocated size) */
str->buf_max_len = len;
- str->offset = 0;
+ str->undoc = 0;
str->buf_len = buf != NULL ? len : 0;
if (buf != NULL) {
@@ -765,7 +740,7 @@ BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *
if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
return False;
- if(!prs_uint32("offset ", ps, depth, &buf2->offset))
+ if(!prs_uint32("undoc ", ps, depth, &buf2->undoc))
return False;
if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
return False;
@@ -793,11 +768,14 @@ creates a UNISTR2 structure: sets up the buffer, too
void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
{
if (buf != NULL) {
+
*ptr = 1;
- init_unistr2(str, buf, UNI_STR_TERMINATE);
+ init_unistr2(str, buf, strlen(buf)+1);
+
} else {
+
*ptr = 0;
- init_unistr2(str, NULL, UNI_FLAGS_NONE);
+ init_unistr2(str, "", 0);
}
}
@@ -808,8 +786,10 @@ void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
{
+
+ /* set up string lengths. add one if string is not null-terminated */
str->uni_max_len = from->uni_max_len;
- str->offset = from->offset;
+ str->undoc = from->undoc;
str->uni_str_len = from->uni_str_len;
if (from->buffer == NULL)
@@ -826,7 +806,8 @@ void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
len *= sizeof(uint16);
str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
- if ((str->buffer == NULL) && (len > 0 )) {
+ if ((str->buffer == NULL) && (len > 0 ))
+ {
smb_panic("copy_unistr2: talloc fail\n");
return;
}
@@ -846,7 +827,7 @@ void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
/* set up string lengths. */
str->str_max_len = max_len;
- str->offset = 0;
+ str->undoc = 0;
str->str_str_len = str_len;
/* store the string */
@@ -857,7 +838,7 @@ void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
if (str->buffer == NULL)
smb_panic("init_string2: malloc fail\n");
memcpy(str->buffer, buf, str_len);
- }
+ }
}
/*******************************************************************
@@ -882,7 +863,7 @@ BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *
if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
return False;
- if(!prs_uint32("offset ", ps, depth, &str2->offset))
+ if(!prs_uint32("undoc ", ps, depth, &str2->undoc))
return False;
if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
return False;
@@ -904,98 +885,46 @@ BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *
}
/*******************************************************************
- Inits a UNISTR2 structure.
+ Inits a UNISTR2 structure. len is in bytes.
********************************************************************/
-void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
+void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
{
- size_t len = 0;
- uint32 num_chars = 0;
+ ZERO_STRUCTP(str);
- if (buf) {
- /* We always null terminate the copy. */
- len = strlen(buf) + 1;
- }
+ /* set up string lengths. */
+ str->uni_max_len = (uint32)len;
+ str->undoc = 0;
+ str->uni_str_len = (uint32)len;
if (len < MAX_UNISTRLEN)
len = MAX_UNISTRLEN;
len *= sizeof(uint16);
str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
- if ((str->buffer == NULL) && (len > 0)) {
+ if ((str->buffer == NULL) && (len > 0))
+ {
smb_panic("init_unistr2: malloc fail\n");
return;
}
/*
- * The UNISTR2 must be initialized !!!
- * jfm, 7/7/2001.
- */
- if (buf) {
- rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
- num_chars = strlen_w(str->buffer);
- if (flags == STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
- num_chars++;
- }
- }
-
- str->uni_max_len = num_chars;
- str->offset = 0;
- str->uni_str_len = num_chars;
- if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
- str->uni_max_len++;
-}
-
-/**
- * Inits a UNISTR2 structure.
- * @param ctx talloc context to allocate string on
- * @param str pointer to string to create
- * @param buf UCS2 null-terminated buffer to init from
-*/
-
-void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
-{
- uint32 len = strlen_w(buf);
- uint32 max_len = len;
- uint32 alloc_len;
-
- ZERO_STRUCTP(str);
-
- /* set up string lengths. */
- str->uni_max_len = len;
- str->offset = 0;
- str->uni_str_len = len;
-
- if (max_len < MAX_UNISTRLEN)
- max_len = MAX_UNISTRLEN;
-
- alloc_len = (max_len + 1) * sizeof(uint16);
-
- str->buffer = (uint16 *)talloc_zero(ctx, alloc_len);
- if ((str->buffer == NULL) && (alloc_len > 0)) {
- smb_panic("init_unistr2_w: malloc fail\n");
- return;
- }
-
- /*
* don't move this test above ! The UNISTR2 must be initialized !!!
* jfm, 7/7/2001.
*/
if (buf==NULL)
return;
-
- /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
- long as the buffer above is talloc()ed correctly then this
- is the correct thing to do */
- strncpy_w(str->buffer, buf, len + 1);
+
+ /* store the string (null-terminated 8 bit chars into 16 bit chars) */
+ dos_struni2((char *)str->buffer, buf, len);
}
/*******************************************************************
Inits a UNISTR2 structure from a UNISTR
********************************************************************/
-
-void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
+void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from)
{
+
uint32 i;
/* the destination UNISTR2 should never be NULL.
@@ -1017,7 +946,7 @@ void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
/* set up string lengths; uni_max_len is set to i+1
because we need to account for the final NULL termination */
to->uni_max_len = i;
- to->offset = 0;
+ to->undoc = 0;
to->uni_str_len = i;
/* allocate the space and copy the string buffer */
@@ -1025,33 +954,10 @@ void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
if (to->buffer == NULL)
smb_panic("init_unistr2_from_unistr: malloc fail\n");
memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
+
return;
}
-/*******************************************************************
- Inits a UNISTR2 structure from a DATA_BLOB.
- The length of the data_blob must count the bytes of the buffer.
- Copies the blob data.
-********************************************************************/
-
-void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob)
-{
- /* Allocs the unistring */
- init_unistr2(str, NULL, UNI_FLAGS_NONE);
-
- /* Sets the values */
- str->uni_str_len = blob->length / sizeof(uint16);
- str->uni_max_len = str->uni_str_len;
- str->offset = 0;
- if (blob->length) {
- str->buffer = (uint16 *) memdup(blob->data, blob->length);
- } else {
- str->buffer = NULL;
- }
- if ((str->buffer == NULL) && (blob->length > 0)) {
- smb_panic("init_unistr2_from_datablob: malloc fail\n");
- }
-}
/*******************************************************************
Reads or writes a UNISTR2 structure.
@@ -1075,7 +981,7 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *
if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
return False;
- if(!prs_uint32("offset ", ps, depth, &uni2->offset))
+ if(!prs_uint32("undoc ", ps, depth, &uni2->undoc))
return False;
if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
return False;
@@ -1096,85 +1002,6 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *
return True;
}
-
-/*
- initialise a UNISTR_ARRAY from a char**
-*/
-BOOL init_unistr2_array(UNISTR2_ARRAY *array,
- uint32 count, const char **strings)
-{
- unsigned int i;
-
- array->count = count;
- array->ref_id = count?1:0;
- if (array->count == 0) {
- return True;
- }
-
- array->strings = (UNISTR2_ARRAY_EL *)talloc_zero(get_talloc_ctx(), count * sizeof(UNISTR2_ARRAY_EL));
- if (!array->strings) {
- return False;
- }
-
- for (i=0;i<count;i++) {
- init_unistr2(&array->strings[i].string, strings[i], UNI_FLAGS_NONE);
- array->strings[i].size = array->strings[i].string.uni_max_len*2;
- array->strings[i].length = array->strings[i].size;
- array->strings[i].ref_id = 1;
- }
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a UNISTR2_ARRAY structure.
-********************************************************************/
-BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps, int depth)
-{
- unsigned int i;
-
- prs_debug(ps, depth, desc, "smb_io_unistr2_array");
- depth++;
-
- if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
- return False;
-
- if (! array->ref_id) {
- return True;
- }
-
- if(!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (array->count == 0) {
- return True;
- }
-
- if (UNMARSHALLING(ps)) {
- array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0]));
- }
- if (! array->strings) {
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if(!prs_uint16("length", ps, depth, &array->strings[i].length))
- return False;
- if(!prs_uint16("size", ps, depth, &array->strings[i].size))
- return False;
- if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth))
- return False;
- }
-
- return True;
-}
-
-
/*******************************************************************
Inits a DOM_RID2 structure.
********************************************************************/
@@ -1270,22 +1097,22 @@ void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
Inits a DOM_CLNT_SRV structure.
********************************************************************/
-static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
+static void init_clnt_srv(DOM_CLNT_SRV *log, const char *logon_srv, const char *comp_name)
{
DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
if (logon_srv != NULL) {
- logcln->undoc_buffer = 1;
- init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
+ log->undoc_buffer = 1;
+ init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
} else {
- logcln->undoc_buffer = 0;
+ log->undoc_buffer = 0;
}
if (comp_name != NULL) {
- logcln->undoc_buffer2 = 1;
- init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
+ log->undoc_buffer2 = 1;
+ init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
} else {
- logcln->undoc_buffer2 = 0;
+ log->undoc_buffer2 = 0;
}
}
@@ -1293,9 +1120,9 @@ static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const cha
Inits or writes a DOM_CLNT_SRV structure.
********************************************************************/
-static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
+static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
{
- if (logcln == NULL)
+ if (log == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_clnt_srv");
@@ -1304,22 +1131,22 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
+ if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
return False;
- if (logcln->undoc_buffer != 0) {
- if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
+ if (log->undoc_buffer != 0) {
+ if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
+ if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
return False;
- if (logcln->undoc_buffer2 != 0) {
- if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
+ if (log->undoc_buffer2 != 0) {
+ if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
return False;
}
@@ -1330,28 +1157,28 @@ static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *
Inits a DOM_LOG_INFO structure.
********************************************************************/
-void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
+void init_log_info(DOM_LOG_INFO *log, const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name)
{
DEBUG(5,("make_log_info %d\n", __LINE__));
- loginfo->undoc_buffer = 1;
+ log->undoc_buffer = 1;
- init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
- init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
+ init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
+ init_unistr2(&log->uni_acct_name, acct_name, strlen(acct_name)+1);
- loginfo->sec_chan = sec_chan;
+ log->sec_chan = sec_chan;
- init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
+ init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
}
/*******************************************************************
Reads or writes a DOM_LOG_INFO structure.
********************************************************************/
-BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
+BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
{
- if (loginfo == NULL)
+ if (log == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_log_info");
@@ -1360,18 +1187,18 @@ BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, in
if(!prs_align(ps))
return False;
- if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
+ if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
return False;
- if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
return False;
- if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
return False;
- if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
+ if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
return False;
- if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
+ if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
return False;
return True;
@@ -1388,6 +1215,9 @@ BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "smb_io_chal");
depth++;
+
+ if(!prs_align(ps))
+ return False;
if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
return False;
@@ -1425,15 +1255,15 @@ BOOL smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
const char *logon_srv, const char *comp_name,
- const DOM_CRED *clnt_cred)
+ DOM_CRED *clnt_cred)
{
DEBUG(5,("make_clnt_info: %d\n", __LINE__));
- init_clnt_srv(&clnt->login, logon_srv, comp_name);
+ init_clnt_srv(&(clnt->login), logon_srv, comp_name);
if (clnt_cred != NULL) {
clnt->ptr_cred = 1;
- memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
+ memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
} else {
clnt->ptr_cred = 0;
}
@@ -1475,7 +1305,7 @@ BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, i
void init_clnt_info(DOM_CLNT_INFO *clnt,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name,
- const DOM_CRED *cred)
+ DOM_CRED *cred)
{
DEBUG(5,("make_clnt_info\n"));
@@ -1510,21 +1340,21 @@ BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, in
Inits a DOM_LOGON_ID structure.
********************************************************************/
-void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
+void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
{
DEBUG(5,("make_logon_id: %d\n", __LINE__));
- logonid->low = log_id_low;
- logonid->high = log_id_high;
+ log->low = log_id_low;
+ log->high = log_id_high;
}
/*******************************************************************
Reads or writes a DOM_LOGON_ID structure.
********************************************************************/
-BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
+BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
{
- if (logonid == NULL)
+ if (log == NULL)
return False;
prs_debug(ps, depth, desc, "smb_io_logon_id");
@@ -1533,9 +1363,9 @@ BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, in
if(!prs_align(ps))
return False;
- if(!prs_uint32("low ", ps, depth, &logonid->low ))
+ if(!prs_uint32("low ", ps, depth, &log->low ))
return False;
- if(!prs_uint32("high", ps, depth, &logonid->high))
+ if(!prs_uint32("high", ps, depth, &log->high))
return False;
return True;
@@ -1545,7 +1375,7 @@ BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, in
Inits an OWF_INFO structure.
********************************************************************/
-void init_owf_info(OWF_INFO *hash, const uint8 data[16])
+void init_owf_info(OWF_INFO *hash, uint8 data[16])
{
DEBUG(5,("init_owf_info: %d\n", __LINE__));
@@ -1658,7 +1488,8 @@ void init_unistr3(UNISTR3 *str, const char *buf)
if (str->str.buffer == NULL)
smb_panic("init_unistr3: malloc fail\n");
- rpcstr_push((char *)str->str.buffer, buf, len, STR_TERMINATE);
+ /* store the string (null-terminated copy) */
+ dos_struni2((char *)str->str.buffer, buf, len);
}
/*******************************************************************
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index a98738b51f0..ba81fee7e93 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jean François Micouleau 2002.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -23,9 +23,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -136,15 +133,16 @@ static BOOL net_io_netinfo_1(const char *desc, NETLOGON_INFO_1 *info, prs_struct
static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
uint32 tc_status, const char *trusted_dc_name)
{
+ int len_dc_name = strlen(trusted_dc_name);
info->flags = flags;
info->pdc_status = pdc_status;
info->ptr_trusted_dc_name = 1;
info->tc_status = tc_status;
if (trusted_dc_name != NULL)
- init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, UNI_STR_TERMINATE);
+ init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, len_dc_name+1);
else
- init_unistr2(&info->uni_trusted_dc_name, "", UNI_STR_TERMINATE);
+ init_unistr2(&info->uni_trusted_dc_name, "", 1);
}
/*******************************************************************
@@ -229,7 +227,7 @@ void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name,
q_l->query_level = query_level;
q_l->switch_value = 0x01;
- init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
}
/*******************************************************************
@@ -359,7 +357,7 @@ void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name,
q_l->function_code = 0x01; /* ??? */
q_l->query_level = query_level;
- init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
}
/*******************************************************************
@@ -425,97 +423,13 @@ BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps
}
/*******************************************************************
- Inits an NET_R_GETDCNAME structure.
-********************************************************************/
-void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server,
- const char *domainname)
-{
- DEBUG(5,("init_r_getdcname\n"));
-
- r_t->ptr_logon_server = (logon_server != NULL);
- init_unistr2(&r_t->uni_logon_server, logon_server, UNI_STR_TERMINATE);
- r_t->ptr_domainname = (domainname != NULL);
- init_unistr2(&r_t->uni_domainname, domainname, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes an NET_Q_GETDCNAME structure.
-********************************************************************/
-
-BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps,
- int depth)
-{
- if (r_t == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "net_io_q_getdcname");
- depth++;
-
- if (!prs_uint32("ptr_logon_server", ps, depth, &r_t->ptr_logon_server))
- return False;
-
- if (!smb_io_unistr2("logon_server", &r_t->uni_logon_server,
- r_t->ptr_logon_server, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("ptr_domainname", ps, depth, &r_t->ptr_domainname))
- return False;
-
- if (!smb_io_unistr2("domainname", &r_t->uni_domainname,
- r_t->ptr_domainname, ps, depth))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
- Inits an NET_R_GETDCNAME structure.
-********************************************************************/
-void init_net_r_getdcname(NET_R_GETDCNAME *r_t, const char *dcname)
-{
- DEBUG(5,("init_r_getdcname\n"));
-
- init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes an NET_R_GETDCNAME structure.
-********************************************************************/
-
-BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps,
- int depth)
-{
- if (r_t == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "net_io_r_getdcname");
- depth++;
-
- if (!prs_uint32("ptr_dcname", ps, depth, &r_t->ptr_dcname))
- return False;
-
- if (!smb_io_unistr2("dcname", &r_t->uni_dcname,
- r_t->ptr_dcname, ps, depth))
- return False;
-
- if (!prs_ntstatus("status", ps, depth, &r_t->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Inits an NET_R_TRUST_DOM_LIST structure.
********************************************************************/
void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
uint32 num_doms, const char *dom_name)
{
- unsigned int i = 0;
+ int i = 0;
DEBUG(5,("init_r_trust_dom\n"));
@@ -529,10 +443,10 @@ void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
for (i = 0; i < num_doms; i++) {
fstring domain_name;
fstrcpy(domain_name, dom_name);
- strupper_m(domain_name);
- init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, UNI_STR_TERMINATE);
+ strupper(domain_name);
+ init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
/* the use of UNISTR2 here is non-standard. */
- r_t->uni_trust_dom_name[i].offset = 0x1;
+ r_t->uni_trust_dom_name[i].undoc = 0x1;
}
r_t->status = NT_STATUS_OK;
@@ -615,15 +529,15 @@ BOOL net_io_q_trust_dom(const char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct
********************************************************************/
void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
- const char *logon_srv, const char *logon_clnt,
- DOM_CHAL *clnt_chal)
+ const char *logon_srv, const char *logon_clnt,
+ DOM_CHAL *clnt_chal)
{
DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
q_c->undoc_buffer = 1; /* don't know what this buffer is */
- init_unistr2(&q_c->uni_logon_srv, logon_srv , UNI_STR_TERMINATE);
- init_unistr2(&q_c->uni_logon_clnt, logon_clnt, UNI_STR_TERMINATE);
+ init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
+ init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
@@ -636,6 +550,8 @@ void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
BOOL net_io_q_req_chal(const char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
{
+ int old_align;
+
if (q_c == NULL)
return False;
@@ -653,8 +569,15 @@ BOOL net_io_q_req_chal(const char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, i
if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
return False;
- if(!smb_io_chal("", &q_c->clnt_chal, ps, depth))
+ old_align = ps->align;
+ ps->align = 0;
+ /* client challenge is _not_ aligned after the unicode strings */
+ if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
+ /* client challenge */
+ ps->align = old_align;
return False;
+ }
+ ps->align = old_align;
return True;
}
@@ -690,6 +613,7 @@ BOOL net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, in
BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
{
+ int old_align;
if (q_a == NULL)
return False;
@@ -701,8 +625,15 @@ BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
return False;
- if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
+ /* client challenge is _not_ aligned */
+ old_align = ps->align;
+ ps->align = 0;
+ if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
+ /* client-calculated credentials */
+ ps->align = old_align;
return False;
+ }
+ ps->align = old_align;
return True;
}
@@ -754,6 +685,7 @@ void init_q_auth_2(NET_Q_AUTH_2 *q_a,
BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
{
+ int old_align;
if (q_a == NULL)
return False;
@@ -765,8 +697,15 @@ BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int de
if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
return False;
- if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
+ /* client challenge is _not_ aligned */
+ old_align = ps->align;
+ ps->align = 0;
+ if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
+ /* client-calculated credentials */
+ ps->align = old_align;
return False;
+ }
+ ps->align = old_align;
if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
return False;
@@ -799,92 +738,15 @@ BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int de
return True;
}
-/*******************************************************************
- Inits a NET_Q_AUTH_3 struct.
-********************************************************************/
-
-void init_q_auth_3(NET_Q_AUTH_3 *q_a,
- const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
- DOM_CHAL *clnt_chal, uint32 clnt_flgs)
-{
- DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
-
- init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
- memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
- q_a->clnt_flgs.neg_flags = clnt_flgs;
-
- DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-BOOL net_io_q_auth_3(const char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth)
-{
- if (q_a == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "net_io_q_auth_3");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
- return False;
- if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
- return False;
- if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-BOOL net_io_r_auth_3(const char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth)
-{
- if (r_a == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "net_io_r_auth_3");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */
- return False;
- if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth))
- return False;
- if (!prs_uint32("unknown", ps, depth, &r_a->unknown))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_a->status))
- return False;
-
- return True;
-}
-
/*******************************************************************
Inits a NET_Q_SRV_PWSET.
********************************************************************/
-void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
- const char *logon_srv, const char *sess_key, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- DOM_CRED *cred, uchar hashed_mach_pwd[16])
+void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name, DOM_CRED *cred, char nt_cypher[16])
{
- unsigned char nt_cypher[16];
-
DEBUG(5,("init_q_srv_pwset\n"));
-
- /* Process the new password. */
- cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1);
init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
@@ -956,12 +818,10 @@ static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsi
int number;
DOM_SID2 *sids;
- /* Count the number of valid SIDs. */
- for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
- DOM_SID tmpsid;
- if (string_to_sid(&tmpsid, s2))
- count++;
- }
+ /* Count the number of SIDs. */
+ for (count = 0, ptr = sids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2)); count++)
+ ;
/* Now allocate space for them. */
*ppsids = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
@@ -970,13 +830,11 @@ static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsi
sids = *ppsids;
- for (number = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
+ for (number = 0, ptr = sids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2)); number++) {
DOM_SID tmpsid;
- if (string_to_sid(&tmpsid, s2)) {
- /* count only valid sids */
- init_dom_sid2(&sids[number], &tmpsid);
- number++;
- }
+ string_to_sid(&tmpsid, s2);
+ init_dom_sid2(&sids[number], &tmpsid);
}
}
@@ -993,6 +851,10 @@ void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
const char *sess_key,
unsigned char lm_cypher[16], unsigned char nt_cypher[16])
{
+ int len_domain_name = strlen(domain_name);
+ int len_user_name = strlen(user_name );
+ int len_wksta_name = strlen(wksta_name );
+
unsigned char lm_owf[16];
unsigned char nt_owf[16];
@@ -1000,9 +862,13 @@ void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
id->ptr_id_info1 = 1;
+ init_uni_hdr(&id->hdr_domain_name, len_domain_name);
+
id->param_ctrl = param_ctrl;
init_logon_id(&id->logon_id, log_id_low, log_id_high);
+ init_uni_hdr(&id->hdr_user_name, len_user_name);
+ init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
if (lm_cypher && nt_cypher) {
unsigned char key[16];
@@ -1037,12 +903,9 @@ void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
init_owf_info(&id->lm_owf, lm_cypher);
init_owf_info(&id->nt_owf, nt_cypher);
- init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
- init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
- init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
+ init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
+ init_unistr2(&id->uni_user_name, user_name, len_user_name);
+ init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
}
/*******************************************************************
@@ -1116,9 +979,12 @@ void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
uint32 log_id_low, uint32 log_id_high,
const char *user_name, const char *wksta_name,
const uchar lm_challenge[8],
- const uchar * lm_chal_resp, size_t lm_chal_resp_len,
- const uchar * nt_chal_resp, size_t nt_chal_resp_len)
+ const uchar * lm_chal_resp, int lm_chal_resp_len,
+ const uchar * nt_chal_resp, int nt_chal_resp_len)
{
+ int len_domain_name = strlen(domain_name);
+ int len_user_name = strlen(user_name );
+ int len_wksta_name = strlen(wksta_name );
unsigned char lm_owf[24];
unsigned char nt_owf[128];
@@ -1126,10 +992,14 @@ void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
id->ptr_id_info2 = 1;
+ init_uni_hdr(&id->hdr_domain_name, len_domain_name);
id->param_ctrl = param_ctrl;
init_logon_id(&id->logon_id, log_id_low, log_id_high);
+ init_uni_hdr(&id->hdr_user_name, len_user_name);
+ init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
+
if (nt_chal_resp) {
/* oops. can only send what-ever-it-is direct */
memcpy(nt_owf, nt_chal_resp, MIN(sizeof(nt_owf), nt_chal_resp_len));
@@ -1145,12 +1015,9 @@ void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
- init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
- init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
- init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
- init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
+ init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
+ init_unistr2(&id->uni_user_name, user_name, len_user_name);
+ init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
@@ -1223,8 +1090,7 @@ static BOOL net_io_id_info2(const char *desc, NET_ID_INFO_2 *id, prs_struct *ps
********************************************************************/
void init_sam_info(DOM_SAM_INFO *sam,
- const char *logon_srv, const char *comp_name,
- DOM_CRED *clnt_cred,
+ const char *logon_srv, const char *comp_name, DOM_CRED *clnt_cred,
DOM_CRED *rtn_cred, uint16 logon_level,
NET_ID_INFO_CTR *ctr)
{
@@ -1321,59 +1187,58 @@ static BOOL smb_io_sam_info(const char *desc, DOM_SAM_INFO *sam, prs_struct *ps,
}
/*************************************************************************
- Inits a NET_USER_INFO_3 structure.
-
- This is a network logon reply packet, and contains much information about
- the user. This information is passed as a (very long) paramater list
- to avoid having to link in the PASSDB code to every program that deals
- with this file.
+ Init
*************************************************************************/
-void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
- uint32 user_rid,
- uint32 group_rid,
-
- const char* user_name,
- const char* full_name,
- const char* home_dir,
- const char* dir_drive,
- const char* logon_script,
- const char* profile_path,
-
- time_t unix_logon_time,
- time_t unix_logoff_time,
- time_t unix_kickoff_time,
- time_t unix_pass_last_set_time,
- time_t unix_pass_can_change_time,
- time_t unix_pass_must_change_time,
-
+void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
uint16 logon_count, uint16 bad_pw_count,
- uint32 num_groups, const DOM_GID *gids,
- uint32 user_flgs, uchar nt_session_key[16],
- uchar lm_session_key[16],
+ uint32 num_groups, DOM_GID *gids,
+ uint32 user_flgs, uchar *sess_key,
const char *logon_srv, const char *logon_dom,
- const DOM_SID *dom_sid, const char *other_sids)
+ DOM_SID *dom_sid, const char *other_sids)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
- unsigned int i;
+ int i;
int num_other_sids = 0;
NTTIME logon_time, logoff_time, kickoff_time,
pass_last_set_time, pass_can_change_time,
pass_must_change_time;
+ int len_user_name, len_full_name, len_home_dir,
+ len_dir_drive, len_logon_script, len_profile_path;
+
+ const char* user_name = pdb_get_username(sampw);
+ const char* full_name = pdb_get_fullname(sampw);
+ const char* home_dir = pdb_get_homedir(sampw);
+ const char* dir_drive = pdb_get_dirdrive(sampw);
+ const char* logon_script = pdb_get_logon_script(sampw);
+ const char* profile_path = pdb_get_profile_path(sampw);
+
+ int len_logon_srv = strlen(logon_srv);
+ int len_logon_dom = strlen(logon_dom);
+
+ len_user_name = strlen(user_name );
+ len_full_name = strlen(full_name );
+ len_home_dir = strlen(home_dir );
+ len_dir_drive = strlen(dir_drive );
+ len_logon_script = strlen(logon_script);
+ len_profile_path = strlen(profile_path);
+
+
ZERO_STRUCTP(usr);
usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
+
/* Create NTTIME structs */
- unix_to_nt_time (&logon_time, unix_logon_time);
- unix_to_nt_time (&logoff_time, unix_logoff_time);
- unix_to_nt_time (&kickoff_time, unix_kickoff_time);
- unix_to_nt_time (&pass_last_set_time, unix_pass_last_set_time);
- unix_to_nt_time (&pass_can_change_time, unix_pass_can_change_time);
- unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time);
+ unix_to_nt_time (&logon_time, pdb_get_logon_time(sampw));
+ unix_to_nt_time (&logoff_time, TIME_T_MAX);
+ unix_to_nt_time (&kickoff_time, TIME_T_MAX);
+ unix_to_nt_time (&pass_last_set_time, pdb_get_pass_last_set_time(sampw));
+ unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(sampw));
+ unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(sampw));
usr->logon_time = logon_time;
usr->logoff_time = logoff_time;
@@ -1382,61 +1247,64 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
usr->pass_can_change_time = pass_can_change_time;
usr->pass_must_change_time = pass_must_change_time;
+ init_uni_hdr(&usr->hdr_user_name, len_user_name);
+ init_uni_hdr(&usr->hdr_full_name, len_full_name);
+ init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+ init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+ init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+ init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+
usr->logon_count = logon_count;
usr->bad_pw_count = bad_pw_count;
- usr->user_rid = user_rid;
- usr->group_rid = group_rid;
- usr->num_groups = num_groups;
+ usr->user_rid = pdb_get_user_rid(sampw);
+ usr->group_rid = pdb_get_group_rid(sampw);
+ usr->num_groups = num_groups+1;
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
- if (nt_session_key != NULL)
- memcpy(usr->user_sess_key, nt_session_key, sizeof(usr->user_sess_key));
+ if (sess_key != NULL)
+ memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
else
memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
+ init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
+ init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
+
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
memset((char *)usr->padding, '\0', sizeof(usr->padding));
-#if 0 /* JRATEST - exchange auth test. */
- if (lm_session_key != NULL)
- memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key));
-#endif
-
num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
usr->num_other_sids = num_other_sids;
usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0;
- init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
- init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
- init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
- init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
- init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
- init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
-
- usr->num_groups2 = num_groups;
-
- usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups));
- if (usr->gids == NULL && num_groups>0)
+ init_unistr2(&usr->uni_user_name, user_name, len_user_name);
+ init_unistr2(&usr->uni_full_name, full_name, len_full_name);
+ init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
+ init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
+ init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
+ init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
+
+ /* always have at least one group == the user's primary group */
+ usr->num_groups2 = num_groups+1;
+
+ usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups+1));
+ if (usr->gids == NULL)
return;
+ /* primary group **MUST** go first. NT4's winmsd.exe will give
+ "The Network statistics are currently not available. 9-5"
+ What the heck is this? -- jerry */
+ usr->gids[0].g_rid = usr->group_rid;
+ usr->gids[0].attr = 0x07;
for (i = 0; i < num_groups; i++)
- usr->gids[i] = gids[i];
+ usr->gids[i+1] = gids[i];
- init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv);
- init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom);
+ init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
+ init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
init_dom_sid2(&usr->dom_sid, dom_sid);
/* "other" sids are set up above */
@@ -1450,15 +1318,14 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
Jacobsen at HP. JRA.
********************************************************************/
-BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
- int depth, uint16 validation_level)
+static BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
{
- unsigned int i;
+ int i;
if (usr == NULL)
return False;
- prs_debug(ps, depth, desc, "net_io_user_info3");
+ prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
depth++;
if (UNMARSHALLING(ps))
@@ -1486,17 +1353,17 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
return False;
- if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
return False;
- if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
return False;
- if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
return False;
- if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
return False;
- if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
return False;
- if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
return False;
if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count)) /* logon count */
@@ -1515,12 +1382,12 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!prs_uint32("user_flgs ", ps, depth, &usr->user_flgs)) /* user flags */
return False;
- if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */
+ if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
return False;
- if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
return False;
- if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
+ if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
return False;
if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
@@ -1540,17 +1407,17 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
}
}
- if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
return False;
- if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
return False;
- if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
return False;
- if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
return False;
- if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
return False;
- if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
return False;
if(!prs_align(ps))
@@ -1569,9 +1436,9 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
return False;
}
- if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
return False;
- if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
+ if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
return False;
if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */
@@ -1625,9 +1492,6 @@ BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps,
if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
return False;
- if(!prs_align_uint16(ps))
- return False;
-
if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
return False;
@@ -1729,14 +1593,13 @@ BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps
makes a NET_Q_SAM_SYNC structure.
********************************************************************/
BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
- const char *cli_name, DOM_CRED *cli_creds,
- DOM_CRED *ret_creds, uint32 database_id,
- uint32 next_rid)
+ const char *cli_name, DOM_CRED * cli_creds,
+ DOM_CRED *ret_creds, uint32 database_id)
{
DEBUG(5, ("init_q_sam_sync\n"));
- init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
- init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
+ init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
if (cli_creds)
memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
@@ -1744,11 +1607,11 @@ BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
if (cli_creds)
memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
else
- memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
+ memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
q_s->database_id = database_id;
q_s->restart_state = 0;
- q_s->sync_context = next_rid;
+ q_s->sync_context = 0;
q_s->max_size = 0xffff;
return True;
@@ -1819,7 +1682,7 @@ static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
+static BOOL net_io_sam_delta_stamp(const char *desc, SAM_DELTA_STAMP *info,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
@@ -2195,12 +2058,12 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
if (!prs_uint32("pwd_len", ps, depth, &len))
return False;
old_offset = ps->data_offset;
- if (len > 0)
+ if (len == 0x44)
{
if (ps->io)
{
/* reading */
- if (!prs_hash1(ps, ps->data_offset, sess_key, len))
+ if (!prs_hash1(ps, ps->data_offset, sess_key))
return False;
}
if (!net_io_sam_passwd_info("pass", &info->pass,
@@ -2210,7 +2073,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
if (!ps->io)
{
/* writing */
- if (!prs_hash1(ps, old_offset, sess_key, len))
+ if (!prs_hash1(ps, old_offset, sess_key))
return False;
}
}
@@ -2343,12 +2206,9 @@ static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
info->hdr_sec_desc.buffer, ps, depth))
return False;
-
- if (info->hdr_als_desc.buffer != 0) {
- if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
- info->hdr_als_name.buffer, ps, depth))
- return False;
- }
+ if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
+ info->hdr_als_name.buffer, ps, depth))
+ return False;
return True;
}
@@ -2371,12 +2231,12 @@ static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * inf
if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
return False;
- if (ps->data_offset + 16 > ps->buffer_size)
- return False;
- ps->data_offset += 16;
-
if (info->ptr_members != 0)
{
+ if (ps->data_offset + 16 > ps->buffer_size)
+ return False;
+ ps->data_offset += 16;
+
if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
return False;
if (info->num_sids != info->num_members)
@@ -2429,326 +2289,6 @@ static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * inf
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
- prs_struct *ps, int depth)
-{
- unsigned int i;
- prs_debug(ps, depth, desc, "net_io_sam_policy_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
- return False;
- if (!prs_uint64("audit_retention_period", ps, depth,
- &info->audit_retention_period))
- return False;
- if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
- return False;
- if (!prs_uint32("num_events", ps, depth, &info->num_events))
- return False;
- if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
- return False;
-
- if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
- return False;
-
- if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
- return False;
-
- if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
- return False;
- if (!prs_uint32("non_paged_pool_limit", ps, depth,
- &info->non_paged_pool_limit))
- return False;
- if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
- return False;
- if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
- return False;
- if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
- return False;
- if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
- return False;
- if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
- return False;
- if (!smb_io_time("create_time", &info->create_time, ps, depth))
- return False;
- if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
- return False;
-
- for (i=0; i<4; i++) {
- UNIHDR dummy;
- if (!smb_io_unihdr("dummy", &dummy, ps, depth))
- return False;
- }
-
- for (i=0; i<4; i++) {
- uint32 reserved;
- if (!prs_uint32("reserved", ps, depth, &reserved))
- return False;
- }
-
- if (!prs_uint32("num_event_audit_options", ps, depth,
- &info->num_event_audit_options))
- return False;
-
- for (i=0; i<info->num_event_audit_options; i++)
- if (!prs_uint32("event_audit_option", ps, depth,
- &info->event_audit_option))
- return False;
-
- if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
- return False;
-
- if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
- info->hdr_sec_desc.buffer, ps, depth))
-
- return False;
-
- return True;
-}
-
-#if 0
-
-/* This function is pretty broken - see bug #334 */
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
- prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
- return False;
-
- if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
- return False;
-
- if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
- return False;
-
- if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
- return False;
-
- if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
- return False;
- if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
- return False;
- if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
- return False;
-
- if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
- return False;
- if(!prs_uint32("ptr", ps, depth, &info->ptr))
- return False;
-
- for (i=0; i<12; i++)
- if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
- return False;
-
- if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
- return False;
-
- return True;
-}
-
-#endif
-
-#if 0
-
-/* This function doesn't work - see bug #334 */
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
- prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "net_io_sam_secret_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
- return False;
-
- if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
- return False;
-
- if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("count1", ps, depth, &info->count1))
- return False;
- if(!prs_uint32("count2", ps, depth, &info->count2))
- return False;
- if(!prs_uint32("ptr", ps, depth, &info->ptr))
- return False;
-
-
- if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
- return False;
- if(!prs_uint32("count3", ps, depth, &info->count3))
- return False;
- if(!prs_uint32("count4", ps, depth, &info->count4))
- return False;
- if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
- return False;
- if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
- return False;
- if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
- return False;
-
-
- if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
- return False;
- if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
- return False;
- for(i=0; i<12; i++)
- if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
- return False;
-
- if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
- return False;
- if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
- return False;
- if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
- return False;
-
- if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
- return False;
-
- if(!prs_uint32("key_len", ps, depth, &info->key_len))
- return False;
- if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
- return False;
- if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
- return False;
-
- if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
- return False;
-
-
- if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
- return False;
-
- if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
- return False;
-
-
- return True;
-}
-
-#endif
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
- prs_struct *ps, int depth)
-{
- unsigned int i;
-
- prs_debug(ps, depth, desc, "net_io_sam_privs_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
- return False;
-
- if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
- return False;
- if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
- return False;
-
- if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
- return False;
- if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
- return False;
-
- if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
- return False;
- if (!prs_uint32("non_paged_pool_limit", ps, depth,
- &info->non_paged_pool_limit))
- return False;
- if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
- return False;
- if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
- return False;
- if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
- return False;
- if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
- return False;
- if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
- return False;
- if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
- return False;
-
- for (i=0; i<4; i++) {
- UNIHDR dummy;
- if (!smb_io_unihdr("dummy", &dummy, ps, depth))
- return False;
- }
-
- for (i=0; i<4; i++) {
- uint32 reserved;
- if (!prs_uint32("reserved", ps, depth, &reserved))
- return False;
- }
-
- if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
- return False;
-
- info->attributes = talloc(ps->mem_ctx, sizeof(uint32) * info->attribute_count);
-
- for (i=0; i<info->attribute_count; i++)
- if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
- return False;
-
- if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
- return False;
-
- info->hdr_privslist = talloc(ps->mem_ctx, sizeof(UNIHDR) * info->privlist_count);
- info->uni_privslist = talloc(ps->mem_ctx, sizeof(UNISTR2) * info->privlist_count);
-
- for (i=0; i<info->privlist_count; i++)
- if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
- return False;
-
- for (i=0; i<info->privlist_count; i++)
- if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
- return False;
-
- if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
- info->hdr_sec_desc.buffer, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
SAM_DELTA_CTR * delta, uint16 type,
prs_struct *ps, int depth)
@@ -2756,69 +2296,70 @@ static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
depth++;
- switch (type) {
+ switch (type)
+ {
/* Seen in sam deltas */
- case SAM_DELTA_MODIFIED_COUNT:
- if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
+
+ case SAM_DELTA_SAM_STAMP:
+ {
+ if (!net_io_sam_delta_stamp("", &delta->stamp,
+ ps, depth))
return False;
break;
+ }
case SAM_DELTA_DOMAIN_INFO:
- if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
+ {
+ if (!net_io_sam_domain_info("", &delta->domain_info,
+ ps, depth))
return False;
break;
-
+ }
case SAM_DELTA_GROUP_INFO:
- if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
+ {
+ if (!net_io_sam_group_info("", &delta->group_info,
+ ps, depth))
return False;
break;
-
+ }
case SAM_DELTA_ACCOUNT_INFO:
- if (!net_io_sam_account_info("", sess_key, &delta->account_info, ps, depth))
+ {
+ if (!net_io_sam_account_info("", sess_key,
+ &delta->account_info,
+ ps, depth))
return False;
break;
-
+ }
case SAM_DELTA_GROUP_MEM:
- if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
+ {
+ if (!net_io_sam_group_mem_info("",
+ &delta->grp_mem_info,
+ ps, depth))
return False;
break;
-
+ }
case SAM_DELTA_ALIAS_INFO:
- if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
- return False;
- break;
-
- case SAM_DELTA_POLICY_INFO:
- if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
+ {
+ if (!net_io_sam_alias_info("", &delta->alias_info,
+ ps, depth))
return False;
break;
-
+ }
case SAM_DELTA_ALIAS_MEM:
- if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
- return False;
- break;
-
- case SAM_DELTA_PRIVS_INFO:
- if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
+ {
+ if (!net_io_sam_alias_mem_info("",
+ &delta->als_mem_info,
+ ps, depth))
return False;
break;
-
- /* These guys are implemented but broken */
-
- case SAM_DELTA_TRUST_DOMS:
- case SAM_DELTA_SECRET_INFO:
- break;
-
- /* These guys are not implemented yet */
-
- case SAM_DELTA_RENAME_GROUP:
- case SAM_DELTA_RENAME_USER:
- case SAM_DELTA_RENAME_ALIAS:
- case SAM_DELTA_DELETE_GROUP:
- case SAM_DELTA_DELETE_USER:
+ }
default:
- DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
+ {
+ DEBUG(0,
+ ("Replication error: Unknown delta type 0x%x\n",
+ type));
break;
+ }
}
return True;
@@ -2923,8 +2464,8 @@ BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name,
{
DEBUG(5, ("init_net_q_sam_deltas\n"));
- init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
- init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
+ init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
@@ -2972,7 +2513,7 @@ reads or writes a structure.
BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
{
- unsigned int i;
+ int i;
prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
depth++;
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 0e5a25fe8c2..d8a26d7bf1e 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba memory buffer functions
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Jeremy Allison 1999
- Copyright (C) Andrew Bartlett 2003.
+ Copyright (C) Jeremy Allison 1999.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,32 +23,10 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/**
- * Dump a prs to a file: from the current location through to the end.
- **/
-void prs_dump(char *name, int v, prs_struct *ps)
-{
- prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size);
-}
-
-
-/**
- * Dump from the start of the prs to the current location.
- **/
-void prs_dump_before(char *name, int v, prs_struct *ps)
-{
- prs_dump_region(name, v, ps, 0, ps->data_offset);
-}
-
-
-/**
- * Dump everything from the start of the prs up to the current location.
- **/
-void prs_dump_region(char *name, int v, prs_struct *ps,
- int from_off, int to_off)
+/*******************************************************************
+dump a prs to a file
+ ********************************************************************/
+void prs_dump(const char *name, int v, prs_struct *ps)
{
int fd, i;
pstring fname;
@@ -63,7 +41,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps,
if (fd != -1 || errno != EEXIST) break;
}
if (fd != -1) {
- write(fd, ps->data_p + from_off, to_off - from_off);
+ write(fd, ps->data_p + ps->data_offset, ps->buffer_size - ps->data_offset);
close(fd);
DEBUG(0,("created %s\n", fname));
}
@@ -117,6 +95,25 @@ BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
}
/*******************************************************************
+ read from a socket into memory.
+ ********************************************************************/
+BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout)
+{
+ BOOL ok;
+ size_t prev_size = ps->buffer_size;
+ if (!prs_grow(ps, len))
+ return False;
+
+ if (timeout > 0) {
+ ok = (read_with_timeout(fd, &ps->data_p[prev_size],
+ len, len,timeout) == len);
+ } else {
+ ok = (read_data(fd, &ps->data_p[prev_size], len) == len);
+ }
+ return ok;
+}
+
+/*******************************************************************
Delete the memory in a parse structure - if we own it.
********************************************************************/
@@ -135,8 +132,7 @@ void prs_mem_free(prs_struct *ps)
void prs_mem_clear(prs_struct *ps)
{
- if (ps->buffer_size)
- memset(ps->data_p, '\0', (size_t)ps->buffer_size);
+ memset(ps->data_p, '\0', (size_t)ps->buffer_size);
}
/*******************************************************************
@@ -145,13 +141,11 @@ void prs_mem_clear(prs_struct *ps)
char *prs_alloc_mem(prs_struct *ps, size_t size)
{
- char *ret = NULL;
+ char *ret = talloc(ps->mem_ctx, size);
+
+ if (ret)
+ memset(ret, '\0', size);
- if (size) {
- ret = talloc(ps->mem_ctx, size);
- if (ret)
- memset(ret, '\0', size);
- }
return ret;
}
@@ -312,7 +306,7 @@ BOOL prs_force_grow(prs_struct *ps, uint32 extra_space)
/*******************************************************************
Get the data pointer (external interface).
-********************************************************************/
+ ********************************************************************/
char *prs_data_p(prs_struct *ps)
{
@@ -361,13 +355,10 @@ BOOL prs_set_offset(prs_struct *ps, uint32 offset)
BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
{
- if (prs_offset(src) == 0)
- return True;
-
if(!prs_grow(dst, prs_offset(src)))
return False;
- memcpy(&dst->data_p[dst->data_offset], src->data_p, (size_t)prs_offset(src));
+ memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)prs_offset(src));
dst->data_offset += prs_offset(src);
return True;
@@ -385,7 +376,7 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin
if(!prs_grow(dst, len))
return False;
- memcpy(&dst->data_p[dst->data_offset], src->data_p + start, (size_t)len);
+ memcpy(&dst->data_p[dst->data_offset], prs_data_p(src)+start, (size_t)len);
dst->data_offset += len;
return True;
@@ -395,11 +386,8 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin
Append the data from a buffer into a parse_struct.
********************************************************************/
-BOOL prs_copy_data_in(prs_struct *dst, char *src, uint32 len)
+BOOL prs_append_data(prs_struct *dst, char *src, uint32 len)
{
- if (len == 0)
- return True;
-
if(!prs_grow(dst, len))
return False;
@@ -410,39 +398,6 @@ BOOL prs_copy_data_in(prs_struct *dst, char *src, uint32 len)
}
/*******************************************************************
- Copy some data from a parse_struct into a buffer.
- ********************************************************************/
-
-BOOL prs_copy_data_out(char *dst, prs_struct *src, uint32 len)
-{
- if (len == 0)
- return True;
-
- if(!prs_mem_get(src, len))
- return False;
-
- memcpy(dst, &src->data_p[src->data_offset], (size_t)len);
- src->data_offset += len;
-
- return True;
-}
-
-/*******************************************************************
- Copy all the data from a parse_struct into a buffer.
- ********************************************************************/
-
-BOOL prs_copy_all_data_out(char *dst, prs_struct *src)
-{
- uint32 len = prs_offset(src);
-
- if (!len)
- return True;
-
- prs_set_offset(src, 0);
- return prs_copy_data_out(dst, src, len);
-}
-
-/*******************************************************************
Set the data as X-endian (external interface).
********************************************************************/
@@ -474,7 +429,7 @@ BOOL prs_align(prs_struct *ps)
/******************************************************************
Align on a 2 byte boundary
*****************************************************************/
-
+
BOOL prs_align_uint16(prs_struct *ps)
{
BOOL ret;
@@ -483,14 +438,13 @@ BOOL prs_align_uint16(prs_struct *ps)
ps->align = 2;
ret = prs_align(ps);
ps->align = old_align;
-
return ret;
}
/******************************************************************
Align on a 8 byte boundary
*****************************************************************/
-
+
BOOL prs_align_uint64(prs_struct *ps)
{
BOOL ret;
@@ -499,7 +453,6 @@ BOOL prs_align_uint64(prs_struct *ps)
ps->align = 8;
ret = prs_align(ps);
ps->align = old_align;
-
return ret;
}
@@ -662,7 +615,7 @@ BOOL prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
}
DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
- nt_errstr(*status)));
+ get_nt_error_msg(*status)));
ps->data_offset += sizeof(uint32);
@@ -917,11 +870,9 @@ BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
return False;
if (UNMARSHALLING(ps)) {
- if ( str->buf_len ) {
- str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
- if ( str->buffer == NULL )
- return False;
- }
+ str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
+ if (str->buffer == NULL)
+ return False;
}
p = (char *)str->buffer;
@@ -939,7 +890,7 @@ BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str)
{
- unsigned int i;
+ int i;
char *q = prs_mem_get(ps, str->str_max_len);
if (q == NULL)
return False;
@@ -1036,7 +987,7 @@ BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps,
BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
{
- unsigned int len = 0;
+ int len = 0;
unsigned char *p = (unsigned char *)str->buffer;
uint8 *start;
char *q;
@@ -1085,14 +1036,12 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
len++;
- DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
- print_asc(5, (unsigned char*)start, 2*len);
- DEBUG(5, ("\n"));
+ dump_data(5+depth, (char *)start, len * 2);
}
else { /* unmarshalling */
uint32 alloc_len = 0;
- q = ps->data_p + prs_offset(ps);
+ q = prs_data_p(ps) + prs_offset(ps);
/*
* Work out how much space we need and talloc it.
@@ -1140,10 +1089,6 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
/* NULL terminate the UNISTR */
str->buffer[len++] = '\0';
}
-
- DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
- print_asc(5, (unsigned char*)str->buffer, 2*len);
- DEBUG(5, ("\n"));
}
/* set the offset in the prs_struct; 'len' points to the
@@ -1160,16 +1105,10 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
not include the null-termination character.
********************************************************************/
-BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size)
+BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size)
{
char *q;
int i;
- int len;
-
- if (UNMARSHALLING(ps))
- len = strlen(&ps->data_p[ps->data_offset]);
- else
- len = strlen(str);
len = MIN(len, (max_buf_size-1));
@@ -1291,7 +1230,7 @@ int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps)
TDB_DATA kbuf, dbuf;
kbuf.dptr = keystr;
kbuf.dsize = strlen(keystr)+1;
- dbuf.dptr = ps->data_p;
+ dbuf.dptr = prs_data_p(ps);
dbuf.dsize = prs_offset(ps);
return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
}
@@ -1304,9 +1243,9 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
kbuf.dsize = strlen(keystr)+1;
dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- return -1;
+ if (!dbuf.dptr) return -1;
+ ZERO_STRUCTP(ps);
prs_init(ps, 0, mem_ctx, UNMARSHALL);
prs_give_memory(ps, dbuf.dptr, dbuf.dsize, True);
@@ -1316,309 +1255,23 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
/*******************************************************************
hash a stream.
********************************************************************/
-BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
+BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
{
char *q;
- q = ps->data_p;
+ q = prs_data_p(ps);
q = &q[offset];
#ifdef DEBUG_PASSWORD
DEBUG(100, ("prs_hash1\n"));
dump_data(100, sess_key, 16);
- dump_data(100, q, len);
+ dump_data(100, q, 68);
#endif
- SamOEMhash((uchar *) q, sess_key, len);
+ SamOEMhash((uchar *) q, sess_key, 68);
#ifdef DEBUG_PASSWORD
- dump_data(100, q, len);
+ dump_data(100, q, 68);
#endif
return True;
}
-
-
-/*******************************************************************
- Create a digest over the entire packet (including the data), and
- MD5 it with the session key.
- ********************************************************************/
-static void netsec_digest(struct netsec_auth_struct *a,
- int auth_flags,
- RPC_AUTH_NETSEC_CHK * verf,
- char *data, size_t data_len,
- uchar digest_final[16])
-{
- uchar whole_packet_digest[16];
- static uchar zeros[4];
- struct MD5Context ctx3;
-
- /* verfiy the signature on the packet by MD5 over various bits */
- MD5Init(&ctx3);
- /* use our sequence number, which ensures the packet is not
- out of order */
- MD5Update(&ctx3, zeros, sizeof(zeros));
- MD5Update(&ctx3, verf->sig, sizeof(verf->sig));
- if (auth_flags & AUTH_PIPE_SEAL) {
- MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder));
- }
- MD5Update(&ctx3, (const unsigned char *)data, data_len);
- MD5Final(whole_packet_digest, &ctx3);
- dump_data_pw("whole_packet_digest:\n", whole_packet_digest, sizeof(whole_packet_digest));
-
- /* MD5 this result and the session key, to prove that
- only a valid client could had produced this */
- hmac_md5(a->sess_key, whole_packet_digest, sizeof(whole_packet_digest), digest_final);
-}
-
-/*******************************************************************
- Calculate the key with which to encode the data payload
- ********************************************************************/
-static void netsec_get_sealing_key(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
- uchar sealing_key[16])
-{
- static uchar zeros[4];
- uchar digest2[16];
- uchar sess_kf0[16];
- int i;
-
- for (i = 0; i < sizeof(sess_kf0); i++) {
- sess_kf0[i] = a->sess_key[i] ^ 0xf0;
- }
-
- dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
-
- /* MD5 of sess_kf0 and 4 zero bytes */
- hmac_md5(sess_kf0, zeros, 0x4, digest2);
- dump_data_pw("digest2:\n", digest2, sizeof(digest2));
-
- /* MD5 of the above result, plus 8 bytes of sequence number */
- hmac_md5(digest2, verf->seq_num, sizeof(verf->seq_num), sealing_key);
- dump_data_pw("sealing_key:\n", sealing_key, 16);
-}
-
-/*******************************************************************
- Encode or Decode the sequence number (which is symmetric)
- ********************************************************************/
-static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf)
-{
- static uchar zeros[4];
- uchar sequence_key[16];
- uchar digest1[16];
-
- hmac_md5(a->sess_key, zeros, sizeof(zeros), digest1);
- dump_data_pw("(sequence key) digest1:\n", digest1, sizeof(digest1));
-
- hmac_md5(digest1, verf->packet_digest, 8, sequence_key);
-
- dump_data_pw("sequence_key:\n", sequence_key, sizeof(sequence_key));
-
- dump_data_pw("seq_num (before):\n", verf->seq_num, sizeof(verf->seq_num));
- SamOEMhash(verf->seq_num, sequence_key, 8);
- dump_data_pw("seq_num (after):\n", verf->seq_num, sizeof(verf->seq_num));
-}
-
-/*******************************************************************
-creates an RPC_AUTH_NETSEC_CHK structure.
-********************************************************************/
-static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
- const uchar sig[8],
- const uchar packet_digest[8],
- const uchar seq_num[8], const uchar confounder[8])
-{
- if (chk == NULL)
- return False;
-
- memcpy(chk->sig, sig, sizeof(chk->sig));
- memcpy(chk->packet_digest, packet_digest, sizeof(chk->packet_digest));
- memcpy(chk->seq_num, seq_num, sizeof(chk->seq_num));
- memcpy(chk->confounder, confounder, sizeof(chk->confounder));
-
- return True;
-}
-
-
-/*******************************************************************
- Encode a blob of data using the netsec (schannel) alogrithm, also produceing
- a checksum over the original data. We currently only support
- signing and sealing togeather - the signing-only code is close, but not
- quite compatible with what MS does.
- ********************************************************************/
-void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf,
- char *data, size_t data_len)
-{
- uchar digest_final[16];
- uchar confounder[8];
- uchar seq_num[8];
- static const uchar nullbytes[8];
-
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
-
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
-
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
- }
-
- /* fill the 'confounder' with random data */
- generate_random_buffer(confounder, sizeof(confounder), False);
-
- dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
-
- RSIVAL(seq_num, 0, a->seq_num);
-
- switch (direction) {
- case SENDER_IS_INITIATOR:
- SIVAL(seq_num, 4, 0x80);
- break;
- case SENDER_IS_ACCEPTOR:
- SIVAL(seq_num, 4, 0x0);
- break;
- }
-
- dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num));
-
- init_rpc_auth_netsec_chk(verf, netsec_sig, nullbytes,
- seq_num, confounder);
-
- /* produce a digest of the packet to prove it's legit (before we seal it) */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
- memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest));
-
- if (auth_flags & AUTH_PIPE_SEAL) {
- uchar sealing_key[16];
-
- /* get the key to encode the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
-
- /* encode the verification data */
- dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder));
- SamOEMhash(verf->confounder, sealing_key, 8);
-
- dump_data_pw("verf->confounder_enc:\n", verf->confounder, sizeof(verf->confounder));
-
- /* encode the packet payload */
- dump_data_pw("data:\n", (const unsigned char *)data, data_len);
- SamOEMhash((unsigned char *)data, sealing_key, data_len);
- dump_data_pw("data_enc:\n", (const unsigned char *)data, data_len);
- }
-
- /* encode the sequence number (key based on packet digest) */
- /* needs to be done after the sealing, as the original version
- is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
-
- return;
-}
-
-/*******************************************************************
- Decode a blob of data using the netsec (schannel) alogrithm, also verifiying
- a checksum over the original data. We currently can verify signed messages,
- as well as decode sealed messages
- ********************************************************************/
-
-BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
-{
- uchar digest_final[16];
-
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
-
- uchar seq_num[8];
-
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
-
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
- }
-
- /* Create the expected sequence number for comparison */
- RSIVAL(seq_num, 0, a->seq_num);
-
- switch (direction) {
- case SENDER_IS_INITIATOR:
- SIVAL(seq_num, 4, 0x80);
- break;
- case SENDER_IS_ACCEPTOR:
- SIVAL(seq_num, 4, 0x0);
- break;
- }
-
- DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
- dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
-
- dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num));
-
- /* extract the sequence number (key based on supplied packet digest) */
- /* needs to be done before the sealing, as the original version
- is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
-
- if (memcmp(verf->seq_num, seq_num, sizeof(seq_num))) {
- /* don't even bother with the below if the sequence number is out */
- /* The sequence number is MD5'ed with a key based on the whole-packet
- digest, as supplied by the client. We check that it's a valid
- checksum after the decode, below
- */
- DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n"));
- dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num));
- DEBUG(2, ("should be:\n"));
- dump_data(2, (const char*)seq_num, sizeof(seq_num));
-
- return False;
- }
-
- if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) {
- /* Validate that the other end sent the expected header */
- DEBUG(2, ("netsec_decode: FAILED: packet header:\n"));
- dump_data(2, (const char*)verf->sig, sizeof(verf->sig));
- DEBUG(2, ("should be:\n"));
- dump_data(2, (const char*)netsec_sig, sizeof(netsec_sig));
- return False;
- }
-
- if (auth_flags & AUTH_PIPE_SEAL) {
- uchar sealing_key[16];
-
- /* get the key to extract the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
-
- /* extract the verification data */
- dump_data_pw("verf->confounder:\n", verf->confounder,
- sizeof(verf->confounder));
- SamOEMhash(verf->confounder, sealing_key, 8);
-
- dump_data_pw("verf->confounder_dec:\n", verf->confounder,
- sizeof(verf->confounder));
-
- /* extract the packet payload */
- dump_data_pw("data :\n", (const unsigned char *)data, data_len);
- SamOEMhash((unsigned char *)data, sealing_key, data_len);
- dump_data_pw("datadec:\n", (const unsigned char *)data, data_len);
- }
-
- /* digest includes 'data' after unsealing */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
-
- dump_data_pw("Calculated digest:\n", digest_final,
- sizeof(digest_final));
- dump_data_pw("verf->packet_digest:\n", verf->packet_digest,
- sizeof(verf->packet_digest));
-
- /* compare - if the client got the same result as us, then
- it must know the session key */
- return (memcmp(digest_final, verf->packet_digest,
- sizeof(verf->packet_digest)) == 0);
-}
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index 69c0dfc7548..78acbe688e7 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -1,12 +1,12 @@
-/*
- * Unix SMB/CIFS implementation.
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Marc Jacobsen 1999.
* Copyright (C) Simo Sorce 2000.
- * Copyright (C) Gerald Carter 2002.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,26 +25,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/*******************************************************************
- Fill in a BUFFER2 for the data given a REGISTRY_VALUE
- *******************************************************************/
-
-static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
-{
- uint32 real_size = 0;
-
- if ( !buf2 || !val )
- return 0;
-
- real_size = regval_size(val);
- init_buffer2( buf2, (unsigned char*)regval_data_p(val), real_size );
-
- return real_size;
-}
-
/*******************************************************************
Inits a structure.
********************************************************************/
@@ -147,11 +127,11 @@ BOOL reg_io_q_open_hklm(const char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
if (r_q->ptr != 0)
{
if (!prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0)))
- return False;
+ return False;
if (!prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)))
- return False;
+ return False;
if (!prs_uint32("access_mask", ps, depth, &(r_q->access_mask)))
- return False;
+ return False;
}
return True;
@@ -183,8 +163,6 @@ BOOL reg_io_r_open_hklm(const char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
}
-
-
/*******************************************************************
Inits a structure.
********************************************************************/
@@ -278,18 +256,21 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DES
********************************************************************/
void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *name, char *class, SEC_ACCESS *sam_access,
+ const char *name, const char *class, SEC_ACCESS *sam_access,
SEC_DESC_BUF *sec_buf)
{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
+ int len_class = class != NULL ? strlen(class) + 1: 0;
+
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+ init_uni_hdr(&q_c->hdr_name, len_name);
+ init_unistr2(&q_c->uni_name, name, len_name);
- init_unistr2(&q_c->uni_class, class, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_class, &q_c->uni_class);
+ init_uni_hdr(&q_c->hdr_class, len_class);
+ init_unistr2(&q_c->uni_class, class, len_class);
q_c->reserved = 0x00000000;
memcpy(&q_c->sam_access, sam_access, sizeof(q_c->sam_access));
@@ -392,14 +373,15 @@ BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *p
********************************************************************/
void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
- char *name)
+ const char *name)
{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+ init_uni_hdr(&q_c->hdr_name, len_name);
+ init_unistr2(&q_c->uni_name, name, len_name);
}
/*******************************************************************
@@ -457,14 +439,15 @@ BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct
********************************************************************/
void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
- char *name)
+ const char *name)
{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+ init_uni_hdr(&q_c->hdr_name, len_name);
+ init_unistr2(&q_c->uni_name, name, len_name);
}
/*******************************************************************
@@ -520,12 +503,14 @@ BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *p
Inits a structure.
********************************************************************/
-void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, UNISTR2 *uni2)
+void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
+ uint32 max_class_len)
{
ZERO_STRUCTP(q_o);
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
- init_uni_hdr(&q_o->hdr_class, uni2);
+ init_uni_hdr(&q_o->hdr_class, max_class_len);
+ q_o->uni_class.uni_max_len = max_class_len;
}
/*******************************************************************
@@ -584,7 +569,7 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
return False;
if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen))
return False;
- if(!prs_uint32("reserved ", ps, depth, &r_r->reserved))
+ if(!prs_uint32("mak_subkeysize", ps, depth, &r_r->max_subkeysize))
return False;
if(!prs_uint32("num_values ", ps, depth, &r_r->num_values))
return False;
@@ -596,7 +581,7 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
return False;
if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
return False;
-
+
if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
@@ -607,27 +592,26 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
Inits a structure.
********************************************************************/
-void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
+void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
{
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
}
-
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_unknown_1a(const char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_unk_1a(const char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth)
{
if (r_q == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_q_unknown_1a");
+ prs_debug(ps, depth, desc, "reg_io_q_unk_1a");
depth++;
if(!prs_align(ps))
return False;
-
+
if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
return False;
@@ -638,17 +622,17 @@ BOOL reg_io_q_unknown_1a(const char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *p
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_unknown_1a(const char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_unk_1a(const char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
{
if (r_r == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_r_unknown_1a");
+ prs_debug(ps, depth, desc, "reg_io_r_unk_1a");
depth++;
if(!prs_align(ps))
return False;
-
+
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
return False;
if(!prs_ntstatus("status" , ps, depth, &r_r->status))
@@ -657,68 +641,17 @@ BOOL reg_io_r_unknown_1a(const char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *p
return True;
}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL reg_io_q_save_key(const char *desc, REG_Q_SAVE_KEY *r_q, prs_struct *ps, int depth)
-{
- if (r_q == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "reg_io_q_save_key");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
-
- if(!smb_io_unihdr ("hdr_file", &r_q->hdr_file, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_file", &r_q->uni_file, r_q->hdr_file.buffer, ps, depth))
- return False;
-
- if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL reg_io_r_save_key(const char *desc, REG_R_SAVE_KEY *r_r, prs_struct *ps, int depth)
-{
- if (r_r == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "reg_io_r_save_key");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_ntstatus("status" , ps, depth, &r_r->status))
- return False;
-
- return True;
-}
-
/*******************************************************************
Inits a structure.
********************************************************************/
void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
- uint16 unknown_0, uint32 access_mask)
+ uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
q_o->unknown_1 = 0x0; /* random - changes */
- q_o->access_mask = access_mask;
+ q_o->level = level;
}
/*******************************************************************
@@ -739,11 +672,11 @@ BOOL reg_io_q_open_hku(const char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, i
if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
return False;
if (r_q->ptr != 0) {
- if(!prs_uint16("unknown_0 ", ps, depth, &r_q->unknown_0))
+ if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
return False;
- if(!prs_uint16("unknown_1 ", ps, depth, &r_q->unknown_1))
+ if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
return False;
- if(!prs_uint32("access_mask ", ps, depth, &r_q->access_mask))
+ if(!prs_uint32("level ", ps, depth, &r_q->level))
return False;
}
@@ -794,7 +727,7 @@ BOOL reg_io_q_close(const char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int dep
if (q_u == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_q_close");
+ prs_debug(ps, depth, desc, "reg_io_q_unknown_1");
depth++;
if(!prs_align(ps))
@@ -817,7 +750,7 @@ BOOL reg_io_r_close(const char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int dep
if (r_u == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_r_close");
+ prs_debug(ps, depth, desc, "reg_io_r_unknown_1");
depth++;
if(!prs_align(ps))
@@ -1003,13 +936,15 @@ makes a structure.
BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name)
{
+ int len_type = val_name != NULL ? strlen(val_name) + 1 : 0;
+
if (q_i == NULL)
return False;
q_i->pol = *pol;
- init_unistr2(&q_i->uni_type, val_name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_i->hdr_type, &q_i->uni_type);
+ init_uni_hdr(&(q_i->hdr_type), len_type);
+ init_unistr2(&(q_i->uni_type), val_name, len_type);
q_i->ptr_reserved = 1;
q_i->ptr_buf = 1;
@@ -1088,77 +1023,33 @@ BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth
/*******************************************************************
Inits a structure.
- New version to replace older init_reg_r_info()
-********************************************************************/
-
-BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- REGISTRY_VALUE *val, NTSTATUS status)
-{
- uint32 buf_len = 0;
- BUFFER2 buf2;
-
- if(r_r == NULL)
- return False;
-
- if ( !val )
- return False;
-
- r_r->ptr_type = 1;
- r_r->type = val->type;
-
- /* if include_keyval is not set, don't send the key value, just
- the buflen data. probably used by NT5 to allocate buffer space - SK */
-
- if ( include_keyval ) {
- r_r->ptr_uni_val = 1;
- buf_len = reg_init_buffer2( &r_r->uni_val, val );
-
- }
- else {
- /* dummy buffer used so we can get the size */
- r_r->ptr_uni_val = 0;
- buf_len = reg_init_buffer2( &buf2, val );
- }
-
- r_r->ptr_max_len = 1;
- r_r->buf_max_len = buf_len;
-
- r_r->ptr_len = 1;
- r_r->buf_len = buf_len;
-
- r_r->status = status;
-
- return True;
-}
-
-/*******************************************************************
- Inits a structure.
********************************************************************/
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
BUFFER2* buf, uint32 type, NTSTATUS status)
{
- if(r_r == NULL)
- return False;
-
- r_r->ptr_type = 1;
- r_r->type = type;
+ if(r_r == NULL)
+ return False;
- /* if include_keyval is not set, don't send the key value, just
- the buflen data. probably used by NT5 to allocate buffer space - SK */
+
+ r_r->ptr_type = 1;
+ r_r->type = type;
- r_r->ptr_uni_val = include_keyval ? 1:0;
- r_r->uni_val = *buf;
+ /* if include_keyval is not set, don't send the key value, just
+ the buflen data. probably used by NT5 to allocate buffer space - SK */
+ r_r->ptr_uni_val = include_keyval ? 1:0;
+ r_r->uni_val = buf;
- r_r->ptr_max_len = 1;
- r_r->buf_max_len = r_r->uni_val.buf_max_len;
+ r_r->ptr_max_len = 1;
+ r_r->buf_max_len = r_r->uni_val->buf_max_len;
- r_r->ptr_len = 1;
- r_r->buf_len = r_r->uni_val.buf_len;
+ r_r->ptr_len = 1;
+ r_r->buf_len = r_r->uni_val->buf_len;
- r_r->status = status;
+ r_r->status = status;
- return True;
+ return True;
+
}
/*******************************************************************
@@ -1188,7 +1079,7 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
return False;
if(r_r->ptr_uni_val != 0) {
- if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
+ if(!smb_io_buffer2("uni_val", r_r->uni_val, r_r->ptr_uni_val, ps, depth))
return False;
}
@@ -1221,7 +1112,7 @@ makes a structure.
********************************************************************/
void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
- uint32 val_idx, UNISTR2 *uni2,
+ uint32 val_idx, uint32 max_val_len,
uint32 max_buf_len)
{
ZERO_STRUCTP(q_i);
@@ -1229,7 +1120,8 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
memcpy(&q_i->pol, pol, sizeof(q_i->pol));
q_i->val_index = val_idx;
- init_uni_hdr(&q_i->hdr_name, uni2);
+ init_uni_hdr(&q_i->hdr_name, max_val_len);
+ q_i->uni_name.uni_max_len = max_val_len;
q_i->ptr_type = 1;
q_i->type = 0x0;
@@ -1245,46 +1137,6 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
}
/*******************************************************************
-makes a structure.
-********************************************************************/
-
-void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
-{
- uint32 real_size;
-
- DEBUG(8,("init_reg_r_enum_val: Enter\n"));
-
- ZERO_STRUCTP(r_u);
-
- /* value name */
-
- DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
-
- init_unistr2( &r_u->uni_name, val->valuename, UNI_STR_TERMINATE);
- init_uni_hdr( &r_u->hdr_name, &r_u->uni_name);
-
- /* type */
-
- r_u->ptr_type = 1;
- r_u->type = val->type;
-
- /* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
-
- r_u->ptr_value = 1;
- real_size = reg_init_buffer2( &r_u->buf_value, val );
-
- /* lengths */
-
- r_u->ptr1 = 1;
- r_u->len_value1 = real_size;
-
- r_u->ptr2 = 1;
- r_u->len_value2 = real_size;
-
- DEBUG(8,("init_reg_r_enum_val: Exit\n"));
-}
-
-/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -1304,7 +1156,6 @@ BOOL reg_io_q_enum_val(const char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps,
if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
return False;
-
if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
return False;
if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
@@ -1375,7 +1226,7 @@ BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps,
if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
return False;
- if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
+ if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
return False;
if(!prs_align(ps))
return False;
@@ -1405,15 +1256,17 @@ makes a structure.
********************************************************************/
void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
- char *val_name, uint32 type,
+ const char *val_name, uint32 type,
BUFFER3 *val)
{
+ int val_len = strlen(val_name) + 1;
+
ZERO_STRUCTP(q_i);
memcpy(&q_i->pol, pol, sizeof(q_i->pol));
- init_unistr2(&q_i->uni_name, val_name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_i->hdr_name, &q_i->uni_name);
+ init_uni_hdr(&q_i->hdr_name, val_len);
+ init_unistr2(&q_i->uni_name, val_name, val_len);
q_i->type = type;
q_i->buf_value = val;
@@ -1499,29 +1352,6 @@ void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
}
/*******************************************************************
-makes a reply structure.
-********************************************************************/
-
-void init_reg_r_enum_key(REG_R_ENUM_KEY *r_u, char *subkey, uint32 unknown_1,
- uint32 unknown_2)
-{
- if ( !r_u )
- return;
-
- r_u->unknown_1 = unknown_1;
- r_u->unknown_2 = unknown_2;
- r_u->unknown_3 = 0x0;
-
- r_u->key_name_len = (strlen(subkey)+1) * 2;
- if (r_u->key_name_len)
- r_u->ptr1 = 0x1;
- init_unistr3( &r_u->key_name, subkey );
-
- r_u->ptr2 = 0x1;
- r_u->ptr3 = 0x1;
-}
-
-/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -1636,15 +1466,17 @@ makes a structure.
********************************************************************/
void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
- char *key_name, uint32 access_desired)
+ const char *key_name, uint32 unk)
{
+ int len_name = strlen(key_name)+1;
+
memcpy(&r_q->pol, pol, sizeof(r_q->pol));
- init_unistr2(&r_q->uni_name, key_name, UNI_STR_TERMINATE);
- init_uni_hdr(&r_q->hdr_name, &r_q->uni_name);
+ init_uni_hdr(&r_q->hdr_name, len_name);
+ init_unistr2(&r_q->uni_name, key_name, len_name);
r_q->unknown_0 = 0x00000000;
- r_q->access_desired = access_desired;
+ r_q->unknown_1 = unk;
}
/*******************************************************************
@@ -1672,9 +1504,9 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *p
if(!prs_align(ps))
return False;
- if(!prs_uint32("unknown_0 ", ps, depth, &r_q->unknown_0))
+ if(!prs_uint32("unknown_0", ps, depth, &r_q->unknown_0))
return False;
- if(!prs_uint32("access_desired ", ps, depth, &r_q->access_desired))
+ if(!prs_uint32("unknown_1", ps, depth, &r_q->unknown_1))
return False;
return True;
@@ -1687,11 +1519,7 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *p
void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
POLICY_HND *pol, NTSTATUS status)
{
- if (NT_STATUS_IS_OK(status)) {
- memcpy(&r_r->pol, pol, sizeof(r_r->pol));
- } else {
- ZERO_STRUCT(r_r->pol);
- }
+ memcpy(&r_r->pol, pol, sizeof(r_r->pol));
r_r->status = status;
}
@@ -1722,27 +1550,27 @@ BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *p
/*******************************************************************
Inits a structure.
********************************************************************/
-
-void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s, const char *msg,
- uint32 timeout, BOOL do_reboot, BOOL force)
+void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s,
+ const char *msg, uint32 timeout, uint16 flags)
{
+ int msg_len;
+ msg_len = strlen(msg);
+
q_s->ptr_0 = 1;
q_s->ptr_1 = 1;
q_s->ptr_2 = 1;
- init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
- init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+ init_uni_hdr(&(q_s->hdr_msg), msg_len);
+ init_unistr2(&(q_s->uni_msg), msg, msg_len);
q_s->timeout = timeout;
+ q_s->flags = flags;
- q_s->reboot = do_reboot ? 1 : 0;
- q_s->force = force ? 1 : 0;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
int depth)
{
@@ -1771,9 +1599,7 @@ BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
return False;
- if (!prs_uint8("force ", ps, depth, &(q_s->force)))
- return False;
- if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
+ if (!prs_uint16("flags ", ps, depth, &(q_s->flags)))
return False;
return True;
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index 696f258e5de..46a57daaaf7 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -1,5 +1,7 @@
+
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -21,10 +23,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
+#include "includes.h"
/*******************************************************************
interface/version dce/rpc pipe identification
@@ -34,9 +34,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x8a885d04, 0x1ceb, 0x11c9, \
- { 0x9f, 0xe8 }, \
- { 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
+ { 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 } \
}, 0x02 \
}
@@ -44,9 +43,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x8a885d04, 0x1ceb, 0x11c9, \
- { 0x9f, 0xe8 }, \
- { 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
+ { 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 } \
}, 0x02 \
}
@@ -54,9 +52,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x6bffd098, 0xa112, 0x3610, \
- { 0x98, 0x33 }, \
- { 0x46, 0xc3, \
- 0xf8, 0x7e, 0x34, 0x5a } \
+ { 0x98, 0x33, 0x46, 0xc3, \
+ 0xf8, 0x7e, 0x34, 0x5a } \
}, 0x01 \
}
@@ -64,9 +61,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x4b324fc8, 0x1670, 0x01d3, \
- { 0x12, 0x78 }, \
- { 0x5a, 0x47, \
- 0xbf, 0x6e, 0xe1, 0x88 } \
+ { 0x12, 0x78, 0x5a, 0x47, \
+ 0xbf, 0x6e, 0xe1, 0x88 } \
}, 0x03 \
}
@@ -74,19 +70,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x12345778, 0x1234, 0xabcd, \
- { 0xef, 0x00 }, \
- { 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
- }, 0x00 \
-}
-
-#define SYNT_LSARPC_V0_DS \
-{ \
- { \
- 0x3919286a, 0xb10c, 0x11d0, \
- { 0x9b, 0xa8 }, \
- { 0x00, 0xc0, \
- 0x4f, 0xd9, 0x2e, 0xf5 } \
+ { 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab } \
}, 0x00 \
}
@@ -94,9 +79,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x12345778, 0x1234, 0xabcd, \
- { 0xef, 0x00 }, \
- { 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xac } \
+ { 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xac } \
}, 0x01 \
}
@@ -104,9 +88,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x12345678, 0x1234, 0xabcd, \
- { 0xef, 0x00 }, \
- { 0x01, 0x23, \
- 0x45, 0x67, 0xcf, 0xfb } \
+ { 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0xcf, 0xfb } \
}, 0x01 \
}
@@ -114,9 +97,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x338cd001, 0x2244, 0x31f1, \
- { 0xaa, 0xaa }, \
- { 0x90, 0x00, \
- 0x38, 0x00, 0x10, 0x03 } \
+ { 0xaa, 0xaa, 0x90, 0x00, \
+ 0x38, 0x00, 0x10, 0x03 } \
}, 0x01 \
}
@@ -124,9 +106,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x12345678, 0x1234, 0xabcd, \
- { 0xef, 0x00 }, \
- { 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
+ { 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab } \
}, 0x01 \
}
@@ -134,9 +115,8 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x0, 0x0, 0x0, \
- { 0x00, 0x00 }, \
- { 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00 } \
+ { 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00 } \
}, 0x00 \
}
@@ -144,63 +124,23 @@ interface/version dce/rpc pipe identification
{ \
{ \
0x4fc742e0, 0x4a10, 0x11cf, \
- { 0x82, 0x73 }, \
- { 0x00, 0xaa, \
+ { 0x82, 0x73, 0x00, 0xaa, \
0x00, 0x4a, 0xe6, 0x73 } \
}, 0x03 \
}
-#define SYNT_ECHO_V1 \
-{ \
- { \
- 0x60a15ec5, 0x4de8, 0x11d7, \
- { 0xa6, 0x37 }, \
- { 0x00, 0x50, \
- 0x56, 0xa2, 0x01, 0x82 } \
- }, 0x01 \
-}
-
-#define SYNT_SHUTDOWN_V1 \
-{ \
- { \
- 0x894de0c0, 0x0d55, 0x11d3, \
- { 0xa3, 0x22 }, \
- { 0x00, 0xc0, \
- 0x4f, 0xa3, 0x21, 0xa1 } \
- }, 0x01 \
-}
-
-#define SYNT_EPM_V3 \
-{ \
- { \
- 0xe1af8308, 0x5d1f, 0x11c9, \
- { 0x91, 0xa4 }, \
- { 0x08, 0x00, \
- 0x2b, 0x14, 0xa0, 0xfa } \
- }, 0x03 \
-}
-
-/*
- * IMPORTANT!! If you update this structure, make sure to
- * update the index #defines in smb.h.
- */
-
-const struct pipe_id_info pipe_names [] =
+struct pipe_id_info pipe_names [] =
{
- /* client pipe , abstract syntax , server pipe , transfer syntax */
- { PIPE_LSARPC , SYNT_LSARPC_V0 , PIPE_LSASS , TRANS_SYNT_V2 },
- { PIPE_LSARPC , SYNT_LSARPC_V0_DS , PIPE_LSASS , TRANS_SYNT_V2 },
- { PIPE_SAMR , SYNT_SAMR_V1 , PIPE_LSASS , TRANS_SYNT_V2 },
- { PIPE_NETLOGON, SYNT_NETLOGON_V1 , PIPE_LSASS , TRANS_SYNT_V2 },
- { PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 },
- { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
- { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
- { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
- { PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 },
- { PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 },
- { PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1 , PIPE_SHUTDOWN , TRANS_SYNT_V2 },
- { PIPE_EPM , SYNT_EPM_V3 , PIPE_EPM , TRANS_SYNT_V2 },
- { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
+ /* client pipe , abstract syntax , server pipe , transfer syntax */
+ { PIPE_LSARPC , SYNT_LSARPC_V0 , PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_SAMR , SYNT_SAMR_V1 , PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_NETLOGON, SYNT_NETLOGON_V1, PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
+ { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
+ { PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 },
+ { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
/*******************************************************************
@@ -289,13 +229,19 @@ static BOOL smb_io_rpc_iface(const char *desc, RPC_IFACE *ifc, prs_struct *ps, i
prs_debug(ps, depth, desc, "smb_io_rpc_iface");
depth++;
- if (!prs_align(ps))
+ if(!prs_align(ps))
return False;
- if (!smb_io_uuid( "uuid", &ifc->uuid, ps, depth))
+ if(!prs_uint32 ("data ", ps, depth, &ifc->uuid.time_low))
+ return False;
+ if(!prs_uint16 ("data ", ps, depth, &ifc->uuid.time_mid))
+ return False;
+ if(!prs_uint16 ("data ", ps, depth, &ifc->uuid.time_hi_and_version))
return False;
- if(!prs_uint32 ("version", ps, depth, &ifc->version))
+ if(!prs_uint8s (False, "data ", ps, depth, ifc->uuid.remaining, sizeof(ifc->uuid.remaining)))
+ return False;
+ if(!prs_uint32 ( "version", ps, depth, &ifc->version))
return False;
return True;
@@ -632,20 +578,29 @@ BOOL smb_io_rpc_hdr_autha(const char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps,
}
/*******************************************************************
+ Checks an RPC_HDR_AUTH structure.
+********************************************************************/
+
+BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai)
+{
+ return (rai->auth_type == NTLMSSP_AUTH_TYPE && rai->auth_level == NTLMSSP_AUTH_LEVEL);
+}
+
+/*******************************************************************
Inits an RPC_HDR_AUTH structure.
********************************************************************/
void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
uint8 auth_type, uint8 auth_level,
- uint8 padding,
+ uint8 stub_type_len,
uint32 ptr)
{
rai->auth_type = auth_type; /* nt lm ssp 0x0a */
rai->auth_level = auth_level; /* 0x06 */
- rai->padding = padding;
- rai->reserved = 0;
+ rai->stub_type_len = stub_type_len; /* 0x00 */
+ rai->padding = 0; /* padding 0x00 */
- rai->auth_context = ptr; /* non-zero pointer to something */
+ rai->unknown = ptr; /* non-zero pointer to something */
}
/*******************************************************************
@@ -667,11 +622,12 @@ BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, in
return False;
if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
return False;
- if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
+ if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
return False;
- if(!prs_uint8 ("reserved ", ps, depth, &rai->reserved))
+ if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
return False;
- if(!prs_uint32("auth_context ", ps, depth, &rai->auth_context))
+
+ if(!prs_uint32("unknown ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
return False;
return True;
@@ -711,7 +667,7 @@ BOOL smb_io_rpc_auth_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_stru
depth++;
/* "NTLMSSP" */
- if(!prs_string("signature", ps, depth, rav->signature,
+ if(!prs_string("signature", ps, depth, rav->signature, strlen("NTLMSSP"),
sizeof(rav->signature)))
return False;
if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type)) /* NTLMSSP_MESSAGE_TYPE */
@@ -721,34 +677,12 @@ BOOL smb_io_rpc_auth_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_stru
}
/*******************************************************************
- This parses an RPC_AUTH_VERIFIER for NETLOGON schannel. I think
- assuming "NTLMSSP" in sm_io_rpc_auth_verifier is somewhat wrong.
- I have to look at that later...
-********************************************************************/
-
-BOOL smb_io_rpc_netsec_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
-{
- if (rav == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
- depth++;
-
- if(!prs_string("signature", ps, depth, rav->signature, sizeof(rav->signature)))
- return False;
- if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Inits an RPC_AUTH_NTLMSSP_NEG structure.
********************************************************************/
void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
uint32 neg_flgs,
- const char *myname, const char *domain)
+ fstring myname, fstring domain)
{
int len_myname = strlen(myname);
int len_domain = strlen(domain);
@@ -940,9 +874,9 @@ void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
memcpy(rsp->nt_resp, nt_resp, 24);
if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- rpcstr_push(rsp->domain, domain, sizeof(rsp->domain), 0);
- rpcstr_push(rsp->user, user, sizeof(rsp->user), 0);
- rpcstr_push(rsp->wks, wks, sizeof(rsp->wks), 0);
+ dos_struni2(rsp->domain, domain, sizeof(rsp->domain));
+ dos_struni2(rsp->user, user, sizeof(rsp->user));
+ dos_struni2(rsp->wks, wks, sizeof(rsp->wks));
} else {
fstrcpy(rsp->domain, domain);
fstrcpy(rsp->user, user);
@@ -1108,10 +1042,9 @@ BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_nu
chk->seq_num != seq_num)
{
DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
- chk->crc32, chk->ver, chk->seq_num));
-
- DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
crc32, NTLMSSP_SIGN_VERSION, seq_num));
+ DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
+ chk->crc32, chk->ver, chk->seq_num));
return False;
}
return True;
@@ -1156,64 +1089,3 @@ BOOL smb_io_rpc_auth_ntlmssp_chk(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, pr
return True;
}
-
-/*******************************************************************
-creates an RPC_AUTH_NETSEC_NEG structure.
-********************************************************************/
-void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
- const char *domain, const char *myname)
-{
- neg->type1 = 0;
- neg->type2 = 0x3;
- fstrcpy(neg->domain, domain);
- fstrcpy(neg->myname, myname);
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NETSEC_NEG structure.
-********************************************************************/
-
-BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg,
- prs_struct *ps, int depth)
-{
- if (neg == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_neg");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("type1", ps, depth, &neg->type1))
- return False;
- if(!prs_uint32("type2", ps, depth, &neg->type2))
- return False;
- if(!prs_string("domain ", ps, depth, neg->domain, sizeof(neg->domain)))
- return False;
- if(!prs_string("myname ", ps, depth, neg->myname, sizeof(neg->myname)))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an RPC_AUTH_NETSEC_CHK structure.
-********************************************************************/
-BOOL smb_io_rpc_auth_netsec_chk(const char *desc, RPC_AUTH_NETSEC_CHK * chk,
- prs_struct *ps, int depth)
-{
- if (chk == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk");
- depth++;
-
- prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig));
- prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num));
- prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest));
- prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder));
-
- return True;
-}
-
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 85eedc7baab..3db903b5d79 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -1,13 +1,13 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* Copyright (C) Paul Ashton 1997-2000,
* Copyright (C) Elrond 2000,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
+ * Copyright (C) Jeremy Allison 2001
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,9 +28,6 @@
#include "rpc_parse.h"
#include "nterr.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
/*******************************************************************
inits a SAMR_Q_CLOSE_HND structure.
********************************************************************/
@@ -91,14 +88,16 @@ inits a SAMR_Q_LOOKUP_DOMAIN structure.
********************************************************************/
void init_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
- POLICY_HND *pol, char *dom_name)
+ POLICY_HND *pol, const char *dom_name)
{
+ int len_name = strlen(dom_name);
+
DEBUG(5, ("init_samr_q_lookup_domain\n"));
q_u->connect_pol = *pol;
- init_unistr2(&q_u->uni_domain, dom_name, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_domain, &q_u->uni_domain);
+ init_uni_hdr(&q_u->hdr_domain, len_name);
+ init_unistr2(&q_u->uni_domain, dom_name, len_name);
}
/*******************************************************************
@@ -181,9 +180,9 @@ BOOL samr_io_r_lookup_domain(const char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
reads or writes a structure.
********************************************************************/
-void init_samr_q_remove_sid_foreign_domain(SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid)
+void init_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u, POLICY_HND *dom_pol, DOM_SID *sid)
{
- DEBUG(5, ("samr_init_samr_q_remove_sid_foreign_domain\n"));
+ DEBUG(5, ("samr_init_samr_q_unknown_2d\n"));
q_u->dom_pol = *dom_pol;
init_dom_sid2(&q_u->sid, sid);
@@ -193,13 +192,13 @@ void init_samr_q_remove_sid_foreign_domain(SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_
reads or writes a structure.
********************************************************************/
-BOOL samr_io_q_remove_sid_foreign_domain(const char *desc, SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u,
+BOOL samr_io_q_unknown_2d(const char *desc, SAMR_Q_UNKNOWN_2D * q_u,
prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
- prs_debug(ps, depth, desc, "samr_io_q_remove_sid_foreign_domain");
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_2d");
depth++;
if(!prs_align(ps))
@@ -221,13 +220,13 @@ BOOL samr_io_q_remove_sid_foreign_domain(const char *desc, SAMR_Q_REMOVE_SID_FOR
reads or writes a structure.
********************************************************************/
-BOOL samr_io_r_remove_sid_foreign_domain(const char *desc, SAMR_R_REMOVE_SID_FOREIGN_DOMAIN * r_u,
+BOOL samr_io_r_unknown_2d(const char *desc, SAMR_R_UNKNOWN_2D * r_u,
prs_struct *ps, int depth)
{
if (r_u == NULL)
return False;
- prs_debug(ps, depth, desc, "samr_io_r_remove_sid_foreign_domain");
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_2d");
depth++;
if(!prs_align(ps))
@@ -389,36 +388,6 @@ BOOL samr_io_r_get_usrdom_pwinfo(const char *desc, SAMR_R_GET_USRDOM_PWINFO * r_
return True;
}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL samr_io_q_set_sec_obj(const char *desc, SAMR_Q_SET_SEC_OBJ * q_u,
- prs_struct *ps, int depth)
-{
- if (q_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_q_set_sec_obj");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
-
- if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
- return False;
-
- if(!sec_io_desc_buf("sec_desc", &q_u->buf, ps, depth))
- return False;
-
- return True;
-}
-
-
/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -628,11 +597,13 @@ static BOOL sam_io_unk_info12(const char *desc, SAM_UNK_INFO_12 * u_12,
/*******************************************************************
inits a structure.
********************************************************************/
-
void init_unk_info5(SAM_UNK_INFO_5 * u_5,const char *server)
{
- init_unistr2(&u_5->uni_server, server, UNI_FLAGS_NONE);
- init_uni_hdr(&u_5->hdr_server, &u_5->uni_server);
+ int len_server = strlen(server);
+
+ init_uni_hdr(&u_5->hdr_server, len_server);
+
+ init_unistr2(&u_5->uni_server, server, len_server);
}
/*******************************************************************
@@ -660,16 +631,20 @@ static BOOL sam_io_unk_info5(const char *desc, SAM_UNK_INFO_5 * u_5,
/*******************************************************************
inits a structure.
********************************************************************/
-
void init_unk_info2(SAM_UNK_INFO_2 * u_2,
const char *domain, const char *server,
uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias)
{
+ int len_domain = strlen(domain);
+ int len_server = strlen(server);
+
u_2->unknown_0 = 0x00000000;
u_2->unknown_1 = 0x80000000;
u_2->unknown_2 = 0x00000000;
u_2->ptr_0 = 1;
+ init_uni_hdr(&u_2->hdr_domain, len_domain);
+ init_uni_hdr(&u_2->hdr_server, len_server);
u_2->seq_num = seq_num;
u_2->unknown_3 = 0x00000000;
@@ -683,10 +658,8 @@ void init_unk_info2(SAM_UNK_INFO_2 * u_2,
memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
- init_unistr2(&u_2->uni_domain, domain, UNI_FLAGS_NONE);
- init_uni_hdr(&u_2->hdr_domain, &u_2->uni_domain);
- init_unistr2(&u_2->uni_server, server, UNI_FLAGS_NONE);
- init_uni_hdr(&u_2->hdr_server, &u_2->uni_server);
+ init_unistr2(&u_2->uni_domain, domain, len_domain);
+ init_unistr2(&u_2->uni_server, server, len_server);
}
/*******************************************************************
@@ -738,14 +711,8 @@ static BOOL sam_io_unk_info2(const char *desc, SAM_UNK_INFO_2 * u_2,
if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps))
return False;
- if (u_2->ptr_0) {
- /* this was originally marked as 'padding'. It isn't
- padding, it is some sort of optional 12 byte
- structure. When it is present it contains zeros
- !? */
- if(!prs_uint8s(False, "unknown", ps, depth, u_2->padding,sizeof(u_2->padding)))
- return False;
- }
+ if(!prs_uint8s(False, "padding", ps, depth, u_2->padding,sizeof(u_2->padding)))
+ return False;
if(!smb_io_unistr2("uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth))
return False;
@@ -896,28 +863,6 @@ BOOL samr_io_r_query_dom_info(const char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
}
/*******************************************************************
-reads or writes a SAMR_R_SET_SEC_OBJ structure.
-********************************************************************/
-
-BOOL samr_io_r_set_sec_obj(const char *desc, SAMR_R_SET_SEC_OBJ * r_u,
- prs_struct *ps, int depth)
-{
- if (r_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_r_set_sec_obj");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
reads or writes a SAMR_R_QUERY_SEC_OBJ structure.
********************************************************************/
@@ -978,9 +923,9 @@ static BOOL sam_io_sam_str1(const char *desc, SAM_STR1 * sam, uint32 acct_buf,
inits a SAM_ENTRY1 structure.
********************************************************************/
-static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
- UNISTR2 *sam_name, UNISTR2 *sam_full,
- UNISTR2 *sam_desc, uint32 rid_user,
+static void init_sam_entry1(SAM_ENTRY1 * sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_full,
+ uint32 len_sam_desc, uint32 rid_user,
uint16 acb_info)
{
DEBUG(5, ("init_sam_entry1\n"));
@@ -991,9 +936,9 @@ static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
sam->rid_user = rid_user;
sam->acb_info = acb_info;
- init_uni_hdr(&sam->hdr_acct_name, sam_name);
- init_uni_hdr(&sam->hdr_user_name, sam_full);
- init_uni_hdr(&sam->hdr_user_desc, sam_desc);
+ init_uni_hdr(&sam->hdr_acct_name, len_sam_name);
+ init_uni_hdr(&sam->hdr_user_name, len_sam_full);
+ init_uni_hdr(&sam->hdr_user_desc, len_sam_desc);
}
/*******************************************************************
@@ -1061,7 +1006,7 @@ static BOOL sam_io_sam_str2(const char *desc, SAM_STR2 * sam, uint32 acct_buf,
inits a SAM_ENTRY2 structure.
********************************************************************/
static void init_sam_entry2(SAM_ENTRY2 * sam, uint32 user_idx,
- UNISTR2 *sam_name, UNISTR2 *sam_desc,
+ uint32 len_sam_name, uint32 len_sam_desc,
uint32 rid_user, uint16 acb_info)
{
DEBUG(5, ("init_sam_entry2\n"));
@@ -1070,8 +1015,8 @@ static void init_sam_entry2(SAM_ENTRY2 * sam, uint32 user_idx,
sam->rid_user = rid_user;
sam->acb_info = acb_info;
- init_uni_hdr(&sam->hdr_srv_name, sam_name);
- init_uni_hdr(&sam->hdr_srv_desc, sam_desc);
+ init_uni_hdr(&sam->hdr_srv_name, len_sam_name);
+ init_uni_hdr(&sam->hdr_srv_desc, len_sam_desc);
}
/*******************************************************************
@@ -1138,7 +1083,7 @@ inits a SAM_ENTRY3 structure.
********************************************************************/
static void init_sam_entry3(SAM_ENTRY3 * sam, uint32 grp_idx,
- UNISTR2 *grp_name, UNISTR2 *grp_desc,
+ uint32 len_grp_name, uint32 len_grp_desc,
uint32 rid_grp)
{
DEBUG(5, ("init_sam_entry3\n"));
@@ -1147,8 +1092,8 @@ static void init_sam_entry3(SAM_ENTRY3 * sam, uint32 grp_idx,
sam->rid_grp = rid_grp;
sam->attr = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
- init_uni_hdr(&sam->hdr_grp_name, grp_name);
- init_uni_hdr(&sam->hdr_grp_desc, grp_desc);
+ init_uni_hdr(&sam->hdr_grp_name, len_grp_name);
+ init_uni_hdr(&sam->hdr_grp_desc, len_grp_desc);
}
/*******************************************************************
@@ -1262,12 +1207,12 @@ static BOOL sam_io_sam_entry5(const char *desc, SAM_ENTRY5 * sam,
inits a SAM_ENTRY structure.
********************************************************************/
-void init_sam_entry(SAM_ENTRY *sam, UNISTR2 *uni2, uint32 rid)
+void init_sam_entry(SAM_ENTRY * sam, uint32 len_sam_name, uint32 rid)
{
- DEBUG(10, ("init_sam_entry: %d\n", rid));
+ DEBUG(10, ("init_sam_entry: %d %d\n", len_sam_name, rid));
sam->rid = rid;
- init_uni_hdr(&sam->hdr_name, uni2);
+ init_uni_hdr(&sam->hdr_name, len_sam_name);
}
/*******************************************************************
@@ -1493,9 +1438,9 @@ inits a SAM_DISPINFO_1 structure.
********************************************************************/
NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
- uint32 start_idx, SAM_ACCOUNT *disp_user_info,
- DOM_SID *domain_sid)
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
+ uint32 len_sam_name, len_sam_full, len_sam_desc;
uint32 i;
SAM_ACCOUNT *pwd = NULL;
@@ -1518,49 +1463,25 @@ NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_en
ZERO_STRUCTP(sam->str);
for (i = 0; i < num_entries ; i++) {
- const char *username;
- const char *fullname;
- const char *acct_desc;
- uint32 user_rid;
- const DOM_SID *user_sid;
- fstring user_sid_string, domain_sid_string;
-
DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
- pwd=&disp_user_info[i+start_idx];
-
- username = pdb_get_username(pwd);
- fullname = pdb_get_fullname(pwd);
- acct_desc = pdb_get_acct_desc(pwd);
-
- if (!username)
- username = "";
-
- if (!fullname)
- fullname = "";
+ pwd=disp_user_info[i+start_idx].sam;
- if (!acct_desc)
- acct_desc = "";
-
- user_sid = pdb_get_user_sid(pwd);
-
- if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
- DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with "
- "the domain sid %s. Failing operation.\n",
- username,
- sid_to_string(user_sid_string, user_sid),
- sid_to_string(domain_sid_string, domain_sid)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- init_unistr2(&sam->str[i].uni_acct_name, pdb_get_username(pwd), UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_full_name, pdb_get_fullname(pwd), UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_acct_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
+ len_sam_name = strlen(unix_to_dos_static(pdb_get_username(pwd)));
+ len_sam_full = strlen(unix_to_dos_static(pdb_get_fullname(pwd)));
+ len_sam_desc = strlen(unix_to_dos_static(pdb_get_acct_desc(pwd)));
init_sam_entry1(&sam->sam[i], start_idx + i + 1,
- &sam->str[i].uni_acct_name, &sam->str[i].uni_full_name, &sam->str[i].uni_acct_desc,
- user_rid, pdb_get_acct_ctrl(pwd));
-
+ len_sam_name, len_sam_full, len_sam_desc,
+ pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
+
+ ZERO_STRUCTP(&sam->str[i].uni_acct_name);
+ ZERO_STRUCTP(&sam->str[i].uni_full_name);
+ ZERO_STRUCTP(&sam->str[i].uni_acct_desc);
+
+ init_unistr2(&sam->str[i].uni_acct_name, unix_to_dos_static(pdb_get_username(pwd)), len_sam_name);
+ init_unistr2(&sam->str[i].uni_full_name, unix_to_dos_static(pdb_get_fullname(pwd)), len_sam_full);
+ init_unistr2(&sam->str[i].uni_acct_desc, unix_to_dos_static(pdb_get_acct_desc(pwd)), len_sam_desc);
}
return NT_STATUS_OK;
@@ -1620,9 +1541,9 @@ inits a SAM_DISPINFO_2 structure.
********************************************************************/
NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
- uint32 start_idx, SAM_ACCOUNT *disp_user_info,
- DOM_SID *domain_sid )
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
+ uint32 len_sam_name, len_sam_desc;
uint32 i;
SAM_ACCOUNT *pwd = NULL;
@@ -1643,34 +1564,21 @@ NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_en
ZERO_STRUCTP(sam->str);
for (i = 0; i < num_entries; i++) {
- uint32 user_rid;
- const DOM_SID *user_sid;
- const char *username;
- const char *acct_desc;
- fstring user_sid_string, domain_sid_string;
-
DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
- pwd=&disp_user_info[i+start_idx];
-
- username = pdb_get_username(pwd);
- acct_desc = pdb_get_acct_desc(pwd);
- user_sid = pdb_get_user_sid(pwd);
-
- if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
- DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with "
- "the domain sid %s. Failing operation.\n",
- username,
- sid_to_string(user_sid_string, user_sid),
- sid_to_string(domain_sid_string, domain_sid)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
+ pwd=disp_user_info[i+start_idx].sam;
+ len_sam_name = strlen(unix_to_dos_static(pdb_get_username(pwd)));
+ len_sam_desc = strlen(unix_to_dos_static(pdb_get_acct_desc(pwd)));
+
init_sam_entry2(&sam->sam[i], start_idx + i + 1,
- &sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
- user_rid, pdb_get_acct_ctrl(pwd));
+ len_sam_name, len_sam_desc,
+ pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
+
+ ZERO_STRUCTP(&sam->str[i].uni_srv_name);
+ ZERO_STRUCTP(&sam->str[i].uni_srv_desc);
+
+ init_unistr2(&sam->str[i].uni_srv_name, unix_to_dos_static(pdb_get_username(pwd)), len_sam_name);
+ init_unistr2(&sam->str[i].uni_srv_desc, unix_to_dos_static(pdb_get_acct_desc(pwd)), len_sam_desc);
}
return NT_STATUS_OK;
@@ -1732,8 +1640,9 @@ inits a SAM_DISPINFO_3 structure.
********************************************************************/
NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
- uint32 start_idx, DOMAIN_GRP *disp_group_info)
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info)
{
+ uint32 len_sam_name, len_sam_desc;
uint32 i;
ZERO_STRUCTP(sam);
@@ -1753,15 +1662,17 @@ NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_en
ZERO_STRUCTP(sam->str);
for (i = 0; i < num_entries; i++) {
- DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
+ DOMAIN_GRP *grp = disp_group_info[i+start_idx].grp;
DEBUG(11, ("init_sam_dispinfo_3: entry: %d\n",i));
- init_unistr2(&sam->str[i].uni_grp_name, grp->name, UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_grp_desc, grp->comment, UNI_FLAGS_NONE);
+ len_sam_name = strlen(grp->name);
+ len_sam_desc = strlen(grp->comment);
- init_sam_entry3(&sam->sam[i], start_idx + i + 1, &sam->str[i].uni_grp_name,
- &sam->str[i].uni_grp_desc, grp->rid);
+ init_sam_entry3(&sam->sam[i], start_idx + i + 1, len_sam_name, len_sam_desc, grp->rid);
+
+ init_unistr2(&sam->str[i].uni_grp_name, grp->name, len_sam_name);
+ init_unistr2(&sam->str[i].uni_grp_desc, grp->comment, len_sam_desc);
}
return NT_STATUS_OK;
@@ -1823,7 +1734,7 @@ inits a SAM_DISPINFO_4 structure.
********************************************************************/
NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
- uint32 start_idx, SAM_ACCOUNT *disp_user_info)
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
uint32 len_sam_name;
uint32 i;
@@ -1847,13 +1758,14 @@ NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_en
for (i = 0; i < num_entries; i++) {
DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
- pwd=&disp_user_info[i+start_idx];
+ pwd=disp_user_info[i+start_idx].sam;
- len_sam_name = strlen(pdb_get_username(pwd));
+ len_sam_name = strlen(unix_to_dos_static(pdb_get_username(pwd)));
init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
- init_string2(&sam->str[i].acct_name, pdb_get_username(pwd), len_sam_name+1, len_sam_name);
+ init_string2(&sam->str[i].acct_name, unix_to_dos_static(pdb_get_username(pwd)),
+ len_sam_name+1, len_sam_name);
}
return NT_STATUS_OK;
@@ -1914,7 +1826,7 @@ inits a SAM_DISPINFO_5 structure.
********************************************************************/
NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
- uint32 start_idx, DOMAIN_GRP *disp_group_info)
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info)
{
uint32 len_sam_name;
uint32 i;
@@ -1936,7 +1848,7 @@ NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_en
ZERO_STRUCTP(sam->str);
for (i = 0; i < num_entries; i++) {
- DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
+ DOMAIN_GRP *grp = disp_group_info[i+start_idx].grp;
DEBUG(11, ("init_sam_dispinfo_5: entry: %d\n",i));
@@ -2183,18 +2095,23 @@ inits a GROUP_INFO1 structure.
********************************************************************/
void init_samr_group_info1(GROUP_INFO1 * gr1,
- char *acct_name, char *acct_desc,
+ const char *acct_name, const char *acct_desc,
uint32 num_members)
{
+ int desc_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ int acct_len = acct_name != NULL ? strlen(acct_name) : 0;
+
DEBUG(5, ("init_samr_group_info1\n"));
+ init_uni_hdr(&gr1->hdr_acct_name, acct_len);
+
gr1->unknown_1 = 0x3;
gr1->num_members = num_members;
- init_unistr2(&gr1->uni_acct_name, acct_name, UNI_FLAGS_NONE);
- init_uni_hdr(&gr1->hdr_acct_name, &gr1->uni_acct_name);
- init_unistr2(&gr1->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&gr1->hdr_acct_desc, &gr1->uni_acct_desc);
+ init_uni_hdr(&gr1->hdr_acct_desc, desc_len);
+
+ init_unistr2(&gr1->uni_acct_name, acct_name, acct_len);
+ init_unistr2(&gr1->uni_acct_desc, acct_desc, desc_len);
}
/*******************************************************************
@@ -2273,11 +2190,12 @@ inits a GROUP_INFO4 structure.
void init_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc)
{
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+
DEBUG(5, ("init_samr_group_info4\n"));
- gr4->level = 4;
- init_unistr2(&gr4->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&gr4->hdr_acct_desc, &gr4->uni_acct_desc);
+ init_uni_hdr(&gr4->hdr_acct_desc, acct_len);
+ init_unistr2(&gr4->uni_acct_desc, acct_desc, acct_len);
}
/*******************************************************************
@@ -2293,8 +2211,9 @@ BOOL samr_io_group_info4(const char *desc, GROUP_INFO4 * gr4,
prs_debug(ps, depth, desc, "samr_io_group_info4");
depth++;
- if(!prs_uint16("hdr_level", ps, depth, &gr4->level))
+ if(!prs_align(ps))
return False;
+
if(!smb_io_unihdr("hdr_acct_desc", &gr4->hdr_acct_desc, ps, depth))
return False;
if(!smb_io_unistr2("uni_acct_desc", &gr4->uni_acct_desc,
@@ -2352,12 +2271,14 @@ void init_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
POLICY_HND *pol, const char *acct_desc,
uint32 access_mask)
{
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+
DEBUG(5, ("init_samr_q_create_dom_group\n"));
q_e->pol = *pol;
- init_unistr2(&q_e->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&q_e->hdr_acct_desc, &q_e->uni_acct_desc);
+ init_uni_hdr(&q_e->hdr_acct_desc, acct_len);
+ init_unistr2(&q_e->uni_acct_desc, acct_desc, acct_len);
q_e->access_mask = access_mask;
}
@@ -3467,17 +3388,20 @@ BOOL samr_io_r_enum_dom_aliases(const char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
inits a ALIAS_INFO1 structure.
********************************************************************/
-void init_samr_alias_info1(ALIAS_INFO1 * al1, char *acct_name, uint32 num_member, char *acct_desc)
+void init_samr_alias_info1(ALIAS_INFO1 * al1, const char *acct_name, uint32 num_member, const char *acct_desc)
{
+ int acct_len_name = acct_name != NULL ? strlen(acct_name) : 0;
+ int acct_len_desc = acct_desc != NULL ? strlen(acct_desc) : 0;
+
DEBUG(5, ("init_samr_alias_info1\n"));
- init_unistr2(&al1->uni_acct_name, acct_name, UNI_FLAGS_NONE);
- init_uni_hdr(&al1->hdr_acct_name, &al1->uni_acct_name);
+ init_uni_hdr(&al1->hdr_acct_name, acct_len_name);
+ init_unistr2(&al1->uni_acct_name, acct_name, acct_len_name);
al1->num_member=num_member;
- init_unistr2(&al1->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&al1->hdr_acct_desc, &al1->uni_acct_name);
+ init_uni_hdr(&al1->hdr_acct_desc, acct_len_desc);
+ init_unistr2(&al1->uni_acct_desc, acct_desc, acct_len_desc);
}
/*******************************************************************
@@ -3523,10 +3447,12 @@ inits a ALIAS_INFO3 structure.
void init_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc)
{
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+
DEBUG(5, ("init_samr_alias_info3\n"));
- init_unistr2(&al3->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&al3->hdr_acct_desc, &al3->uni_acct_desc);
+ init_uni_hdr(&al3->hdr_acct_desc, acct_len);
+ init_unistr2(&al3->uni_acct_desc, acct_desc, acct_len);
}
/*******************************************************************
@@ -4234,14 +4160,16 @@ inits a SAMR_Q_CREATE_DOM_ALIAS structure.
void init_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
POLICY_HND *hnd, const char *acct_desc)
{
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+
DEBUG(5, ("init_samr_q_create_dom_alias\n"));
q_u->dom_pol = *hnd;
- init_unistr2(&q_u->uni_acct_desc, acct_desc, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_acct_desc, &q_u->uni_acct_desc);
+ init_uni_hdr(&q_u->hdr_acct_desc, acct_len);
+ init_unistr2(&q_u->uni_acct_desc, acct_desc, acct_len);
- q_u->access_mask = MAXIMUM_ALLOWED_ACCESS;
+ q_u->access_mask = 0x001f000f;
}
/*******************************************************************
@@ -4557,6 +4485,7 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
prs_struct *ps, int depth)
{
uint32 i;
+ uint32 ptr_sid[MAX_LOOKUP_SIDS];
if (r_u == NULL)
return False;
@@ -4572,31 +4501,28 @@ BOOL samr_io_r_query_aliasmem(const char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
if(!prs_uint32("ptr", ps, depth, &r_u->ptr))
return False;
- if (r_u->ptr != 0 && r_u->num_sids != 0) {
- uint32 *ptr_sid = NULL;
-
- if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1))
- return False;
+ if (r_u->ptr != 0) {
+ SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids);
- ptr_sid = talloc(ps->mem_ctx, sizeof(uint32) * r_u->num_sids1);
- if (!ptr_sid) {
- return False;
- }
-
- for (i = 0; i < r_u->num_sids1; i++) {
- ptr_sid[i] = 1;
- if(!prs_uint32("ptr_sid", ps, depth, &ptr_sid[i]))
+ if (r_u->num_sids != 0) {
+ if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1))
return False;
- }
-
- if (UNMARSHALLING(ps)) {
- r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2));
- }
-
- for (i = 0; i < r_u->num_sids1; i++) {
- if (ptr_sid[i] != 0) {
- if(!smb_io_dom_sid2("sid", &r_u->sid[i], ps, depth))
- return False;
+
+ for (i = 0; i < r_u->num_sids1; i++) {
+ ptr_sid[i] = 1;
+ if(!prs_uint32("", ps, depth, &ptr_sid[i]))
+ return False;
+ }
+
+ if (UNMARSHALLING(ps)) {
+ r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2));
+ }
+
+ for (i = 0; i < r_u->num_sids1; i++) {
+ if (ptr_sid[i] != 0) {
+ if(!smb_io_dom_sid2("", &r_u->sid[i], ps, depth))
+ return False;
+ }
}
}
}
@@ -4635,8 +4561,9 @@ NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
return NT_STATUS_NO_MEMORY;
for (i = 0; i < num_names; i++) {
- init_unistr2(&q_u->uni_name[i], name[i], UNI_FLAGS_NONE); /* unicode string for machine account */
- init_uni_hdr(&q_u->hdr_name[i], &q_u->uni_name[i]); /* unicode header for user_name */
+ int len_name = name[i] != NULL ? strlen(name[i]) : 0;
+ init_uni_hdr(&q_u->hdr_name[i], len_name); /* unicode header for user_name */
+ init_unistr2(&q_u->uni_name[i], name[i], len_name); /* unicode string for machine account */
}
return NT_STATUS_OK;
@@ -4972,12 +4899,15 @@ void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
const char *name,
uint32 acb_info, uint32 access_mask)
{
+ int len_name;
+ len_name = strlen(name);
+
DEBUG(5, ("samr_init_samr_q_create_user\n"));
q_u->domain_pol = *pol;
- init_unistr2(&q_u->uni_name, name, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_name, &q_u->uni_name);
+ init_uni_hdr(&q_u->hdr_name, len_name);
+ init_unistr2(&q_u->uni_name, name, len_name);
q_u->acb_info = acb_info;
q_u->access_mask = access_mask;
@@ -5036,7 +4966,7 @@ BOOL samr_io_r_create_user(const char *desc, SAMR_R_CREATE_USER * r_u,
if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
return False;
- if(!prs_uint32("access_granted", ps, depth, &r_u->access_granted))
+ if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
return False;
if(!prs_uint32("user_rid ", ps, depth, &r_u->user_rid))
return False;
@@ -5197,14 +5127,19 @@ inits a SAM_USER_INFO_11 structure.
void init_sam_user_info11(SAM_USER_INFO_11 * usr,
NTTIME * expiry,
- char *mach_acct,
+ const char *mach_acct,
uint32 rid_user, uint32 rid_group, uint16 acct_ctrl)
{
+ int len_mach_acct;
+
DEBUG(5, ("init_sam_user_info11\n"));
- memcpy(&usr->expiry, expiry, sizeof(usr->expiry)); /* expiry time or something? */
+ len_mach_acct = strlen(mach_acct);
+
+ memcpy(&(usr->expiry), expiry, sizeof(usr->expiry)); /* expiry time or something? */
ZERO_STRUCT(usr->padding_1); /* 0 - padding 24 bytes */
+ init_uni_hdr(&usr->hdr_mach_acct, len_mach_acct); /* unicode header for machine account */
usr->padding_2 = 0; /* 0 - padding 4 bytes */
usr->ptr_1 = 1; /* pointer */
@@ -5229,8 +5164,7 @@ void init_sam_user_info11(SAM_USER_INFO_11 * usr,
ZERO_STRUCT(usr->padding_7); /* 0 - padding 16 bytes */
usr->padding_8 = 0; /* 0 - padding 4 bytes */
- init_unistr2(&usr->uni_mach_acct, mach_acct, UNI_FLAGS_NONE); /* unicode string for machine account */
- init_uni_hdr(&usr->hdr_mach_acct, &usr->uni_mach_acct); /* unicode header for machine account */
+ init_unistr2(&usr->uni_mach_acct, mach_acct, len_mach_acct); /* unicode string for machine account */
}
/*******************************************************************
@@ -5315,6 +5249,11 @@ static BOOL sam_io_user_info11(const char *desc, SAM_USER_INFO_11 * usr,
/*************************************************************************
init_sam_user_infoa
+
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
+ unknown_6 = 0x0000 04ec
+
*************************************************************************/
void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len)
@@ -5357,6 +5296,8 @@ static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr,
/*************************************************************************
init_sam_user_info23
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
@@ -5380,13 +5321,23 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid,
uint32 acb_info,
- uint32 fields_present,
+ uint32 unknown_3,
uint16 logon_divs,
LOGON_HRS * hrs,
- uint16 bad_password_count,
- uint16 logon_count,
+ uint32 unknown_5,
char newpass[516], uint32 unknown_6)
{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
usr->logon_time = *logon_time; /* all zeros */
usr->logoff_time = *logoff_time; /* all zeros */
usr->kickoff_time = *kickoff_time; /* all zeros */
@@ -5394,60 +5345,44 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
usr->pass_can_change_time = *pass_can_change_time; /* all zeros */
usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
+ init_uni_hdr(&usr->hdr_user_name, len_user_name); /* NULL */
+ init_uni_hdr(&usr->hdr_full_name, len_full_name);
+ init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+ init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+ init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+ init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+ init_uni_hdr(&usr->hdr_acct_desc, len_description);
+ init_uni_hdr(&usr->hdr_workstations, len_workstations);
+ init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+
ZERO_STRUCT(usr->nt_pwd);
ZERO_STRUCT(usr->lm_pwd);
usr->user_rid = user_rid; /* 0x0000 0000 */
usr->group_rid = group_rid;
usr->acb_info = acb_info;
- usr->fields_present = fields_present; /* 09f8 27fa */
+ usr->unknown_3 = unknown_3; /* 09f8 27fa */
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
- if (nt_time_is_zero(pass_must_change_time)) {
- usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
- } else {
- usr->passmustchange=0;
- }
-
ZERO_STRUCT(usr->padding1);
- ZERO_STRUCT(usr->padding2);
- usr->bad_password_count = bad_password_count;
- usr->logon_count = logon_count;
+ usr->unknown_5 = unknown_5; /* 0x0001 0000 */
memcpy(usr->pass, newpass, sizeof(usr->pass));
copy_unistr2(&usr->uni_user_name, user_name);
- init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
-
copy_unistr2(&usr->uni_full_name, full_name);
- init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
-
copy_unistr2(&usr->uni_home_dir, home_dir);
- init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
-
copy_unistr2(&usr->uni_dir_drive, dir_drive);
- init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
-
copy_unistr2(&usr->uni_logon_script, log_scr);
- init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
-
copy_unistr2(&usr->uni_profile_path, prof_path);
- init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
-
copy_unistr2(&usr->uni_acct_desc, desc);
- init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
-
copy_unistr2(&usr->uni_workstations, wkstas);
- init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
-
copy_unistr2(&usr->uni_unknown_str, unk_str);
- init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
-
copy_unistr2(&usr->uni_munged_dial, mung_dial);
- init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
@@ -5458,6 +5393,8 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
/*************************************************************************
init_sam_user_info23
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
@@ -5468,18 +5405,27 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
NTTIME * pass_last_set_time, /* all zeros */
NTTIME * pass_can_change_time, /* all zeros */
NTTIME * pass_must_change_time, /* all zeros */
- char *user_name, /* NULL */
- char *full_name,
- char *home_dir, char *dir_drive, char *log_scr,
- char *prof_path, const char *desc, char *wkstas,
- char *unk_str, char *mung_dial, uint32 user_rid, /* 0x0000 0000 */
+ const char *user_name, /* NULL */
+ const char *full_name,
+ const char *home_dir, const char *dir_drive, const char *log_scr,
+ const char *prof_path, const char *desc, const char *wkstas,
+ const char *unk_str, const char *mung_dial, uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid, uint32 acb_info,
- uint32 fields_present, uint16 logon_divs,
- LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count,
+ uint32 unknown_3, uint16 logon_divs,
+ LOGON_HRS * hrs, uint32 unknown_5,
char newpass[516], uint32 unknown_6)
{
- DATA_BLOB blob = base64_decode_data_blob(mung_dial);
-
+ int len_user_name = user_name != NULL ? strlen(user_name) : 0;
+ int len_full_name = full_name != NULL ? strlen(full_name) : 0;
+ int len_home_dir = home_dir != NULL ? strlen(home_dir) : 0;
+ int len_dir_drive = dir_drive != NULL ? strlen(dir_drive) : 0;
+ int len_logon_script = log_scr != NULL ? strlen(log_scr) : 0;
+ int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
+ int len_description = desc != NULL ? strlen(desc) : 0;
+ int len_workstations = wkstas != NULL ? strlen(wkstas) : 0;
+ int len_unknown_str = unk_str != NULL ? strlen(unk_str) : 0;
+ int len_munged_dial = mung_dial != NULL ? strlen(mung_dial) : 0;
+
usr->logon_time = *logon_time; /* all zeros */
usr->logoff_time = *logoff_time; /* all zeros */
usr->kickoff_time = *kickoff_time; /* all zeros */
@@ -5487,63 +5433,45 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
usr->pass_can_change_time = *pass_can_change_time; /* all zeros */
usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
+ init_uni_hdr(&usr->hdr_user_name, len_user_name); /* NULL */
+ init_uni_hdr(&usr->hdr_full_name, len_full_name);
+ init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+ init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+ init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+ init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+ init_uni_hdr(&usr->hdr_acct_desc, len_description);
+ init_uni_hdr(&usr->hdr_workstations, len_workstations);
+ init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+
ZERO_STRUCT(usr->nt_pwd);
ZERO_STRUCT(usr->lm_pwd);
usr->user_rid = user_rid; /* 0x0000 0000 */
usr->group_rid = group_rid;
usr->acb_info = acb_info;
- usr->fields_present = fields_present; /* 09f8 27fa */
+ usr->unknown_3 = unknown_3; /* 09f8 27fa */
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
- if (nt_time_is_zero(pass_must_change_time)) {
- usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
- } else {
- usr->passmustchange=0;
- }
-
ZERO_STRUCT(usr->padding1);
- ZERO_STRUCT(usr->padding2);
- usr->bad_password_count = bad_password_count;
- usr->logon_count = logon_count;
+ usr->unknown_5 = unknown_5; /* 0x0001 0000 */
memcpy(usr->pass, newpass, sizeof(usr->pass));
- init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
-
- init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
-
- init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
-
- init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
-
- init_unistr2(&usr->uni_logon_script, log_scr, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
-
- init_unistr2(&usr->uni_profile_path, prof_path, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
-
- init_unistr2(&usr->uni_acct_desc, desc, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
-
- init_unistr2(&usr->uni_workstations, wkstas, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
-
- init_unistr2(&usr->uni_unknown_str, unk_str, UNI_FLAGS_NONE);
- init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
+ init_unistr2(&usr->uni_user_name, user_name, len_user_name); /* NULL */
+ init_unistr2(&usr->uni_full_name, full_name, len_full_name);
+ init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
+ init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
+ init_unistr2(&usr->uni_logon_script, log_scr, len_logon_script);
+ init_unistr2(&usr->uni_profile_path, prof_path, len_profile_path);
+ init_unistr2(&usr->uni_acct_desc, desc, len_description);
+ init_unistr2(&usr->uni_workstations, wkstas, len_workstations);
+ init_unistr2(&usr->uni_unknown_str, unk_str, len_unknown_str);
+ init_unistr2(&usr->uni_munged_dial, mung_dial, len_munged_dial);
- init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
- init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
-
- data_blob_free(&blob);
-
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
@@ -5612,7 +5540,7 @@ static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr,
if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info))
return False;
- if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
+ if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3))
return False;
if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */
return False;
@@ -5620,20 +5548,11 @@ static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr,
return False;
if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
return False;
-
- if(!prs_uint16("bad_password_count ", ps, depth, &usr->bad_password_count))
- return False;
- if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count))
- return False;
-
if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
return False;
- if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
- return False;
- if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
+ if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
return False;
-
if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
return False;
@@ -5809,6 +5728,8 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
/*************************************************************************
init_sam_user_info21W
+ unknown_3 = 0x00ff ffff
+ unknown_5 = 0x0002 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
@@ -5835,13 +5756,22 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
uint32 user_rid,
uint32 group_rid,
uint32 acb_info,
- uint32 fields_present,
+ uint32 unknown_3,
uint16 logon_divs,
LOGON_HRS * hrs,
- uint16 bad_password_count,
- uint16 logon_count,
- uint32 unknown_6)
-{
+ uint32 unknown_5, uint32 unknown_6)
+{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
usr->logon_time = *logon_time;
usr->logoff_time = *logoff_time;
usr->kickoff_time = *kickoff_time;
@@ -5849,57 +5779,41 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
usr->pass_can_change_time = *pass_can_change_time;
usr->pass_must_change_time = *pass_must_change_time;
+ init_uni_hdr(&usr->hdr_user_name, len_user_name);
+ init_uni_hdr(&usr->hdr_full_name, len_full_name);
+ init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+ init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+ init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+ init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+ init_uni_hdr(&usr->hdr_acct_desc, len_description);
+ init_uni_hdr(&usr->hdr_workstations, len_workstations);
+ init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+
memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
usr->user_rid = user_rid;
usr->group_rid = group_rid;
usr->acb_info = acb_info;
- usr->fields_present = fields_present; /* 0x00ff ffff */
+ usr->unknown_3 = unknown_3; /* 0x00ff ffff */
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
- usr->bad_password_count = bad_password_count;
- usr->logon_count = logon_count;
-
- if (nt_time_is_zero(pass_must_change_time)) {
- usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
- } else {
- usr->passmustchange=0;
- }
+ usr->unknown_5 = unknown_5; /* 0x0002 0000 */
ZERO_STRUCT(usr->padding1);
- ZERO_STRUCT(usr->padding2);
copy_unistr2(&usr->uni_user_name, user_name);
- init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
-
copy_unistr2(&usr->uni_full_name, full_name);
- init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
-
copy_unistr2(&usr->uni_home_dir, home_dir);
- init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
-
copy_unistr2(&usr->uni_dir_drive, dir_drive);
- init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
-
copy_unistr2(&usr->uni_logon_script, log_scr);
- init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
-
copy_unistr2(&usr->uni_profile_path, prof_path);
- init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
-
copy_unistr2(&usr->uni_acct_desc, desc);
- init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
-
copy_unistr2(&usr->uni_workstations, wkstas);
- init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
-
copy_unistr2(&usr->uni_unknown_str, unk_str);
- init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
-
copy_unistr2(&usr->uni_munged_dial, mung_dial);
- init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
@@ -5910,38 +5824,44 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
/*************************************************************************
init_sam_user_info21
+ unknown_3 = 0x00ff ffff
+ unknown_5 = 0x0002 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
-NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *domain_sid)
+void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw)
{
NTTIME logon_time, logoff_time, kickoff_time,
pass_last_set_time, pass_can_change_time,
pass_must_change_time;
+
+ int len_user_name, len_full_name, len_home_dir,
+ len_dir_drive, len_logon_script, len_profile_path,
+ len_description, len_workstations, len_unknown_str,
+ len_munged_dial;
const char* user_name = pdb_get_username(pw);
const char* full_name = pdb_get_fullname(pw);
const char* home_dir = pdb_get_homedir(pw);
- const char* dir_drive = pdb_get_dir_drive(pw);
+ const char* dir_drive = pdb_get_dirdrive(pw);
const char* logon_script = pdb_get_logon_script(pw);
const char* profile_path = pdb_get_profile_path(pw);
const char* description = pdb_get_acct_desc(pw);
const char* workstations = pdb_get_workstations(pw);
const char* munged_dial = pdb_get_munged_dial(pw);
- DATA_BLOB munged_dial_blob;
- uint32 user_rid;
- const DOM_SID *user_sid;
+ len_user_name = user_name != NULL ? strlen(unix_to_dos_static(user_name))+1 : 0;
+ len_full_name = full_name != NULL ? strlen(unix_to_dos_static(full_name))+1 : 0;
+ len_home_dir = home_dir != NULL ? strlen(unix_to_dos_static(home_dir))+1 : 0;
+ len_dir_drive = dir_drive != NULL ? strlen(unix_to_dos_static(dir_drive))+1 : 0;
+ len_logon_script = logon_script != NULL ? strlen(unix_to_dos_static(logon_script))+1 : 0;
+ len_profile_path = profile_path != NULL ? strlen(unix_to_dos_static(profile_path))+1 : 0;
+ len_description = description != NULL ? strlen(unix_to_dos_static(description))+1 : 0;
+ len_workstations = workstations != NULL ? strlen(unix_to_dos_static(workstations))+1 : 0;
+ len_unknown_str = 0;
+ len_munged_dial = munged_dial != NULL ? strlen(unix_to_dos_static(munged_dial))+1 : 0;
- uint32 group_rid;
- const DOM_SID *group_sid;
-
- if (munged_dial) {
- munged_dial_blob = base64_decode_data_blob(munged_dial);
- } else {
- munged_dial_blob = data_blob(NULL, 0);
- }
/* Create NTTIME structs */
unix_to_nt_time (&logon_time, pdb_get_logon_time(pw));
@@ -5959,98 +5879,43 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
usr->pass_can_change_time = pass_can_change_time;
usr->pass_must_change_time = pass_must_change_time;
+ init_uni_hdr(&usr->hdr_user_name, len_user_name);
+ init_uni_hdr(&usr->hdr_full_name, len_full_name);
+ init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+ init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+ init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+ init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+ init_uni_hdr(&usr->hdr_acct_desc, len_description);
+ init_uni_hdr(&usr->hdr_workstations, len_workstations);
+ init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+
ZERO_STRUCT(usr->nt_pwd);
ZERO_STRUCT(usr->lm_pwd);
- user_sid = pdb_get_user_sid(pw);
-
- if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
- fstring user_sid_string;
- fstring domain_sid_string;
- DEBUG(0, ("init_sam_user_info_21A: User %s has SID %s, \nwhich conflicts with "
- "the domain sid %s. Failing operation.\n",
- user_name,
- sid_to_string(user_sid_string, user_sid),
- sid_to_string(domain_sid_string, domain_sid)));
- data_blob_free(&munged_dial_blob);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- group_sid = pdb_get_group_sid(pw);
-
- if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
- fstring group_sid_string;
- fstring domain_sid_string;
- DEBUG(0, ("init_sam_user_info_21A: User %s has Primary Group SID %s, \n"
- "which conflicts with the domain sid %s. Failing operation.\n",
- user_name,
- sid_to_string(group_sid_string, group_sid),
- sid_to_string(domain_sid_string, domain_sid)));
- data_blob_free(&munged_dial_blob);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- usr->user_rid = user_rid;
- usr->group_rid = group_rid;
+ usr->user_rid = pdb_get_user_rid(pw);
+ usr->group_rid = pdb_get_group_rid(pw);
usr->acb_info = pdb_get_acct_ctrl(pw);
-
- /*
- Look at a user on a real NT4 PDC with usrmgr, press
- 'ok'. Then you will see that fields_present is set to
- 0x08f827fa. Look at the user immediately after that again,
- and you will see that 0x00fffff is returned. This solves
- the problem that you get access denied after having looked
- at the user.
- -- Volker
- */
- usr->fields_present = pdb_build_fields_present(pw);
+ usr->unknown_3 = pdb_get_unknown3(pw);
usr->logon_divs = pdb_get_logon_divs(pw);
usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0;
- usr->bad_password_count = pdb_get_bad_password_count(pw);
- usr->logon_count = pdb_get_logon_count(pw);
-
- if (pdb_get_pass_must_change_time(pw) == 0) {
- usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
- } else {
- usr->passmustchange=0;
- }
+ usr->unknown_5 = pdb_get_unknown5(pw); /* 0x0002 0000 */
ZERO_STRUCT(usr->padding1);
- ZERO_STRUCT(usr->padding2);
-
- init_unistr2(&usr->uni_user_name, user_name, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
-
- init_unistr2(&usr->uni_full_name, full_name, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
-
- init_unistr2(&usr->uni_home_dir, home_dir, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
- init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
-
- init_unistr2(&usr->uni_logon_script, logon_script, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
-
- init_unistr2(&usr->uni_profile_path, profile_path, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
-
- init_unistr2(&usr->uni_acct_desc, description, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_acct_desc, &usr->uni_acct_desc);
-
- init_unistr2(&usr->uni_workstations, workstations, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_workstations, &usr->uni_workstations);
-
- init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE);
- init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
-
- init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
- init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
- data_blob_free(&munged_dial_blob);
-
- usr->unknown_6 = pdb_get_unknown_6(pw);
+ init_unistr2(&usr->uni_user_name, unix_to_dos_static(user_name), len_user_name);
+ init_unistr2(&usr->uni_full_name, unix_to_dos_static(full_name), len_full_name);
+ init_unistr2(&usr->uni_home_dir, unix_to_dos_static(home_dir), len_home_dir);
+ init_unistr2(&usr->uni_dir_drive, unix_to_dos_static(dir_drive), len_dir_drive);
+ init_unistr2(&usr->uni_logon_script, unix_to_dos_static(logon_script), len_logon_script);
+ init_unistr2(&usr->uni_profile_path, unix_to_dos_static(profile_path), len_profile_path);
+ init_unistr2(&usr->uni_acct_desc, unix_to_dos_static(description), len_description);
+ init_unistr2(&usr->uni_workstations, unix_to_dos_static(workstations), len_workstations);
+ init_unistr2(&usr->uni_unknown_str, NULL, len_unknown_str);
+ init_unistr2(&usr->uni_munged_dial, unix_to_dos_static(munged_dial), len_munged_dial);
+
+ usr->unknown_6 = pdb_get_unknown6(pw);
usr->padding4 = 0;
if (pdb_get_hours(pw)) {
@@ -6058,8 +5923,6 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN);
} else
memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs));
-
- return NT_STATUS_OK;
}
/*******************************************************************
@@ -6124,7 +5987,7 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info))
return False;
- if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
+ if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3))
return False;
if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */
return False;
@@ -6132,18 +5995,11 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
return False;
if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
return False;
-
- if(!prs_uint16("bad_password_count ", ps, depth, &usr->bad_password_count))
- return False;
- if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count))
+ if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
return False;
if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
return False;
- if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
- return False;
- if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
- return False;
/* here begins pointed-to data */
@@ -6188,12 +6044,13 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw)
{
- const char *munged_dial = pdb_get_munged_dial(pw);
- DATA_BLOB blob = base64_decode_data_blob(munged_dial);
-
- init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
- init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
- data_blob_free(&blob);
+ int len_munged_dial;
+ const char* munged_dial = pdb_get_munged_dial(pw);
+
+ len_munged_dial = munged_dial != NULL ? strlen(unix_to_dos_static(munged_dial))+1 : 0;
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+ init_unistr2(&usr->uni_munged_dial, unix_to_dos_static(munged_dial), len_munged_dial);
+
}
/*******************************************************************
@@ -6293,8 +6150,8 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
inits a SAM_USERINFO_CTR structure.
********************************************************************/
-static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key,
- uint16 switch_value, void *info)
+void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
+ uint16 switch_value, void *info)
{
DEBUG(5, ("init_samr_userinfo_ctr\n"));
@@ -6303,13 +6160,13 @@ static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key,
switch (switch_value) {
case 0x18:
- SamOEMhashBlob(ctr->info.id24->pass, 516, sess_key);
- dump_data(100, (char *)sess_key->data, sess_key->length);
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
+ dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id24->pass, 516);
break;
case 0x17:
- SamOEMhashBlob(ctr->info.id23->pass, 516, sess_key);
- dump_data(100, (char *)sess_key->data, sess_key->length);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
+ dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id23->pass, 516);
break;
default:
@@ -6494,7 +6351,7 @@ inits a SAMR_Q_SET_USERINFO structure.
********************************************************************/
void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
- POLICY_HND *hnd, DATA_BLOB *sess_key,
+ POLICY_HND *hnd, unsigned char sess_key[16],
uint16 switch_value, void *info)
{
DEBUG(5, ("init_samr_q_set_userinfo\n"));
@@ -6568,7 +6425,7 @@ inits a SAMR_Q_SET_USERINFO2 structure.
********************************************************************/
void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
- POLICY_HND *hnd, DATA_BLOB *sess_key,
+ POLICY_HND *hnd, unsigned char sess_key[16],
uint16 switch_value, SAM_USERINFO_CTR * ctr)
{
DEBUG(5, ("init_samr_q_set_userinfo2\n"));
@@ -6582,9 +6439,9 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
switch (switch_value) {
case 0x12:
- SamOEMhashBlob(ctr->info.id12->lm_pwd, 16, sess_key);
- SamOEMhashBlob(ctr->info.id12->nt_pwd, 16, sess_key);
- dump_data(100, (char *)sess_key->data, sess_key->length);
+ SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16);
+ SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16);
+ dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id12->lm_pwd, 16);
dump_data(100, (char *)ctr->info.id12->nt_pwd, 16);
break;
@@ -6656,13 +6513,15 @@ inits a SAMR_Q_CONNECT structure.
********************************************************************/
void init_samr_q_connect(SAMR_Q_CONNECT * q_u,
- char *srv_name, uint32 access_mask)
+ const char *srv_name, uint32 access_mask)
{
+ int len_srv_name = strlen(srv_name);
+
DEBUG(5, ("init_samr_q_connect\n"));
/* make PDC server name \\server */
- q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
- init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
+ q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
+ init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name + 1);
/* example values: 0x0000 0002 */
q_u->access_mask = access_mask;
@@ -6723,82 +6582,6 @@ BOOL samr_io_r_connect(const char *desc, SAMR_R_CONNECT * r_u,
}
/*******************************************************************
-inits a SAMR_Q_CONNECT4 structure.
-********************************************************************/
-
-void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
- char *srv_name, uint32 access_mask)
-{
- DEBUG(5, ("init_samr_q_connect\n"));
-
- /* make PDC server name \\server */
- q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
- init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
-
- /* Only value we've seen, possibly an address type ? */
- q_u->unk_0 = 2;
-
- /* example values: 0x0000 0002 */
- q_u->access_mask = access_mask;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL samr_io_q_connect4(const char *desc, SAMR_Q_CONNECT4 * q_u,
- prs_struct *ps, int depth)
-{
- if (q_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_q_connect4");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("unk_0", ps, depth, &q_u->unk_0))
- return False;
- if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL samr_io_r_connect4(const char *desc, SAMR_R_CONNECT4 * r_u,
- prs_struct *ps, int depth)
-{
- if (r_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_r_connect4");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
inits a SAMR_Q_CONNECT_ANON structure.
********************************************************************/
@@ -6870,13 +6653,15 @@ inits a SAMR_Q_GET_DOM_PWINFO structure.
********************************************************************/
void init_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
- char *srv_name)
+ const char *srv_name)
{
+ int len_srv_name = strlen(srv_name);
+
DEBUG(5, ("init_samr_q_get_dom_pwinfo\n"));
q_u->ptr = 1;
- init_unistr2(&q_u->uni_srv_name, srv_name, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_srv_name, &q_u->uni_srv_name);
+ init_uni_hdr(&q_u->hdr_srv_name, len_srv_name);
+ init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name);
}
/*******************************************************************
@@ -6923,17 +6708,17 @@ BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
if(!prs_align(ps))
return False;
- /*
- * We need 16 bytes here according to tests. Don't know
+ /*
+ * we need 16 bytes herre according to tests. Don't know
* what they are, but the length is important for the singing
- */
+ */
- if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0))
- return False;
- if(!prs_align(ps))
+ if(!prs_uint32("unk_0", ps, depth, &r_u->unk_0))
return False;
if(!prs_uint32("unk_1", ps, depth, &r_u->unk_1))
return False;
+ if(!prs_uint32("unk_2", ps, depth, &r_u->unk_2))
+ return False;
if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
@@ -6945,7 +6730,7 @@ BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
make a SAMR_ENC_PASSWD structure.
********************************************************************/
-void init_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512])
+void init_enc_passwd(SAMR_ENC_PASSWD * pwd, char pass[512])
{
ZERO_STRUCTP(pwd);
@@ -6988,7 +6773,7 @@ BOOL samr_io_enc_passwd(const char *desc, SAMR_ENC_PASSWD * pwd,
inits a SAMR_ENC_HASH structure.
********************************************************************/
-void init_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16])
+void init_enc_hash(SAMR_ENC_HASH * hsh, uchar hash[16])
{
ZERO_STRUCTP(hsh);
@@ -7032,19 +6817,21 @@ inits a SAMR_R_GET_DOM_PWINFO structure.
void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
const char *dest_host, const char *user_name,
- const char nt_newpass[516],
- const uchar nt_oldhash[16],
- const char lm_newpass[516],
- const uchar lm_oldhash[16])
+ char nt_newpass[516],
+ uchar nt_oldhash[16],
+ char lm_newpass[516],
+ uchar lm_oldhash[16])
{
+ int len_dest_host = strlen(dest_host);
+ int len_user_name = strlen(user_name);
+
DEBUG(5, ("init_samr_q_chgpasswd_user\n"));
q_u->ptr_0 = 1;
- init_unistr2(&q_u->uni_dest_host, dest_host, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_dest_host, &q_u->uni_dest_host);
-
- init_unistr2(&q_u->uni_user_name, user_name, UNI_FLAGS_NONE);
- init_uni_hdr(&q_u->hdr_user_name, &q_u->uni_user_name);
+ init_uni_hdr(&q_u->hdr_dest_host, len_dest_host);
+ init_unistr2(&q_u->uni_dest_host, dest_host, len_dest_host);
+ init_uni_hdr(&q_u->hdr_user_name, len_user_name);
+ init_unistr2(&q_u->uni_user_name, user_name, len_user_name);
init_enc_passwd(&q_u->nt_newpass, nt_newpass);
init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index a78627650ad..e3518e4aa18 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -3,7 +3,7 @@
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
+ * Copyright (C) Jeremy R. Allison 1995-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998.
*
@@ -24,8 +24,16 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
+#define SD_HEADER_SIZE 0x14
+
+/*******************************************************************
+ Sets up a SEC_ACCESS structure.
+********************************************************************/
+
+void init_sec_access(SEC_ACCESS *t, uint32 mask)
+{
+ t->mask = mask;
+}
/*******************************************************************
Reads or writes a SEC_ACCESS structure.
@@ -39,12 +47,28 @@ BOOL sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "sec_io_access");
depth++;
- if(!prs_uint32("mask", ps, depth, &t->mask))
+ if(!prs_uint32("mask", ps, depth, &(t->mask)))
return False;
return True;
}
+
+/*******************************************************************
+ Sets up a SEC_ACE structure.
+********************************************************************/
+
+void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+{
+ t->type = type;
+ t->flags = flag;
+ t->size = sid_size(sid) + 8;
+ t->info = mask;
+
+ ZERO_STRUCTP(&t->trustee);
+ sid_copy(&t->trustee, sid);
+}
+
/*******************************************************************
Reads or writes a SEC_ACE structure.
********************************************************************/
@@ -74,29 +98,61 @@ BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
if(!sec_io_access("info ", &psa->info, ps, depth))
return False;
- /* check whether object access is present */
- if (!sec_ace_object(psa->type)) {
- if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
- return False;
- } else {
- if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
- return False;
+ if(!smb_io_dom_sid("sid ", &psa->trustee , ps, depth))
+ return False;
- if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
- if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
- return False;
+ if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
+ return False;
- if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
- if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
- return False;
+ return True;
+}
- if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
- return False;
+/*******************************************************************
+ Create a SEC_ACL structure.
+********************************************************************/
+
+SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list)
+{
+ SEC_ACL *dst;
+ int i;
+
+ if((dst = (SEC_ACL *)talloc_zero(ctx,sizeof(SEC_ACL))) == NULL)
+ return NULL;
+
+ dst->revision = revision;
+ dst->num_aces = num_aces;
+ dst->size = 8;
+
+ /* Now we need to return a non-NULL address for the ace list even
+ if the number of aces required is zero. This is because there
+ is a distinct difference between a NULL ace and an ace with zero
+ entries in it. This is achieved by checking that num_aces is a
+ positive number. */
+
+ if ((num_aces) &&
+ ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
+ == NULL)) {
+ return NULL;
+ }
+
+ for (i = 0; i < num_aces; i++) {
+ dst->ace[i] = ace_list[i]; /* Structure copy. */
+ dst->size += ace_list[i].size;
}
- if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
- return False;
- return True;
+ return dst;
+}
+
+/*******************************************************************
+ Duplicate a SEC_ACL structure.
+********************************************************************/
+
+SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
+{
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_acl(ctx, src->revision, src->num_aces, src->ace);
}
/*******************************************************************
@@ -108,7 +164,7 @@ BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
{
- unsigned int i;
+ int i;
uint32 old_offset;
uint32 offset_acl_size;
SEC_ACL *psa;
@@ -172,6 +228,364 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
}
/*******************************************************************
+ Works out the linearization size of a SEC_DESC.
+********************************************************************/
+
+size_t sec_desc_size(SEC_DESC *psd)
+{
+ size_t offset;
+
+ if (!psd) return 0;
+
+ offset = SD_HEADER_SIZE;
+
+ /* don't align */
+
+ if (psd->owner_sid != NULL)
+ offset += sid_size(psd->owner_sid);
+
+ if (psd->grp_sid != NULL)
+ offset += sid_size(psd->grp_sid);
+
+ if (psd->sacl != NULL)
+ offset += psd->sacl->size;
+
+ if (psd->dacl != NULL)
+ offset += psd->dacl->size;
+
+ return offset;
+}
+
+/*******************************************************************
+ Compares two SEC_ACE structures
+********************************************************************/
+
+BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
+{
+ /* Trivial case */
+
+ if (!s1 && !s2) return True;
+
+ /* Check top level stuff */
+
+ if (s1->type != s2->type || s1->flags != s2->flags ||
+ s1->info.mask != s2->info.mask) {
+ return False;
+ }
+
+ /* Check SID */
+
+ if (!sid_equal(&s1->trustee, &s2->trustee)) {
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Compares two SEC_ACL structures
+********************************************************************/
+
+BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
+{
+ int i, j;
+
+ /* Trivial cases */
+
+ if (!s1 && !s2) return True;
+ if (!s1 || !s2) return False;
+
+ /* Check top level stuff */
+
+ if (s1->revision != s2->revision) {
+ DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ if (s1->num_aces != s2->num_aces) {
+ DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ /* The ACEs could be in any order so check each ACE in s1 against
+ each ACE in s2. */
+
+ for (i = 0; i < s1->num_aces; i++) {
+ BOOL found = False;
+
+ for (j = 0; j < s2->num_aces; j++) {
+ if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) {
+ found = True;
+ break;
+ }
+ }
+
+ if (!found) return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Compares two SEC_DESC structures
+********************************************************************/
+
+BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
+{
+ /* Trivial case */
+
+ if (!s1 && !s2) {
+ goto done;
+ }
+
+ /* Check top level stuff */
+
+ if (s1->revision != s2->revision) {
+ DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
+ s1->revision, s2->revision));
+ return False;
+ }
+
+ if (s1->type!= s2->type) {
+ DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
+ s1->type, s2->type));
+ return False;
+ }
+
+ /* Check owner and group */
+
+ if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
+ fstring str1, str2;
+
+ sid_to_string(str1, s1->owner_sid);
+ sid_to_string(str2, s2->owner_sid);
+
+ DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
+ str1, str2));
+ return False;
+ }
+
+ if (!sid_equal(s1->grp_sid, s2->grp_sid)) {
+ fstring str1, str2;
+
+ sid_to_string(str1, s1->grp_sid);
+ sid_to_string(str2, s2->grp_sid);
+
+ DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
+ str1, str2));
+ return False;
+ }
+
+ /* Check ACLs present in one but not the other */
+
+ if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
+ (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
+ DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
+ return False;
+ }
+
+ /* Sigh - we have to do it the hard way by iterating over all
+ the ACEs in the ACLs */
+
+ if (!sec_acl_equal(s1->dacl, s2->dacl) ||
+ !sec_acl_equal(s1->sacl, s2->sacl)) {
+ DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
+ return False;
+ }
+
+ done:
+ DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
+ return True;
+}
+
+/*******************************************************************
+ Merge part of security descriptor old_sec in to the empty sections of
+ security descriptor new_sec.
+********************************************************************/
+
+SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
+{
+ DOM_SID *owner_sid, *group_sid;
+ SEC_DESC_BUF *return_sdb;
+ SEC_ACL *dacl, *sacl;
+ SEC_DESC *psd = NULL;
+ uint16 secdesc_type;
+ size_t secdesc_size;
+
+ /* Copy over owner and group sids. There seems to be no flag for
+ this so just check the pointer values. */
+
+ owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid :
+ old_sdb->sec->owner_sid;
+
+ group_sid = new_sdb->sec->grp_sid ? new_sdb->sec->grp_sid :
+ old_sdb->sec->grp_sid;
+
+ secdesc_type = new_sdb->sec->type;
+
+ /* Ignore changes to the system ACL. This has the effect of making
+ changes through the security tab audit button not sticking.
+ Perhaps in future Samba could implement these settings somehow. */
+
+ sacl = NULL;
+ secdesc_type &= ~SEC_DESC_SACL_PRESENT;
+
+ /* Copy across discretionary ACL */
+
+ if (secdesc_type & SEC_DESC_DACL_PRESENT) {
+ dacl = new_sdb->sec->dacl;
+ } else {
+ dacl = old_sdb->sec->dacl;
+ }
+
+ /* Create new security descriptor from bits */
+
+ psd = make_sec_desc(ctx, new_sdb->sec->revision,
+ owner_sid, group_sid, sacl, dacl, &secdesc_size);
+
+ return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
+
+ return(return_sdb);
+}
+
+/*******************************************************************
+ Tallocs a duplicate SID.
+********************************************************************/
+
+static DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
+{
+ DOM_SID *dst;
+
+ if(!src)
+ return NULL;
+
+ if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
+ sid_copy( dst, src);
+ }
+
+ return dst;
+}
+
+/*******************************************************************
+ Creates a SEC_DESC structure
+********************************************************************/
+
+SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
+{
+ SEC_DESC *dst;
+ uint32 offset;
+
+ *sd_size = 0;
+
+ if(( dst = (SEC_DESC *)talloc_zero(ctx, sizeof(SEC_DESC))) == NULL)
+ return NULL;
+
+ dst->revision = revision;
+ dst->type = SEC_DESC_SELF_RELATIVE;
+
+ if (sacl) dst->type |= SEC_DESC_SACL_PRESENT;
+ if (dacl) dst->type |= SEC_DESC_DACL_PRESENT;
+
+ dst->off_owner_sid = 0;
+ dst->off_grp_sid = 0;
+ dst->off_sacl = 0;
+ dst->off_dacl = 0;
+
+ if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL))
+ goto error_exit;
+
+ if(grp_sid && ((dst->grp_sid = sid_dup_talloc(ctx,grp_sid)) == NULL))
+ goto error_exit;
+
+ if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL))
+ goto error_exit;
+
+ if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL))
+ goto error_exit;
+
+ offset = 0;
+
+ /*
+ * Work out the linearization sizes.
+ */
+
+ if (dst->owner_sid != NULL) {
+
+ if (offset == 0)
+ offset = SD_HEADER_SIZE;
+
+ dst->off_owner_sid = offset;
+ offset += sid_size(dst->owner_sid);
+ }
+
+ if (dst->grp_sid != NULL) {
+
+ if (offset == 0)
+ offset = SD_HEADER_SIZE;
+
+ dst->off_grp_sid = offset;
+ offset += sid_size(dst->grp_sid);
+ }
+
+ if (dst->sacl != NULL) {
+
+ if (offset == 0)
+ offset = SD_HEADER_SIZE;
+
+ dst->off_sacl = offset;
+ offset += dst->sacl->size;
+ }
+
+ if (dst->dacl != NULL) {
+
+ if (offset == 0)
+ offset = SD_HEADER_SIZE;
+
+ dst->off_dacl = offset;
+ offset += dst->dacl->size;
+ }
+
+ *sd_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset);
+ return dst;
+
+error_exit:
+
+ *sd_size = 0;
+ return NULL;
+}
+
+/*******************************************************************
+ Duplicate a SEC_DESC structure.
+********************************************************************/
+
+SEC_DESC *dup_sec_desc( TALLOC_CTX *ctx, SEC_DESC *src)
+{
+ size_t dummy;
+
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_desc( ctx, src->revision,
+ src->owner_sid, src->grp_sid, src->sacl,
+ src->dacl, &dummy);
+}
+
+/*******************************************************************
+ Creates a SEC_DESC structure with typical defaults.
+********************************************************************/
+
+SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *dacl, size_t *sd_size)
+{
+ return make_sec_desc(ctx, SEC_DESC_REVISION,
+ owner_sid, grp_sid, NULL, dacl, sd_size);
+}
+
+/*******************************************************************
Reads or writes a SEC_DESC structure.
If reading and the *ppsd = NULL, allocates the structure.
********************************************************************/
@@ -181,7 +595,6 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
uint32 old_offset;
uint32 max_offset = 0; /* after we're done, move offset to end */
uint32 tmp_offset = 0;
-
SEC_DESC *psd;
if (ppsd == NULL)
@@ -202,7 +615,7 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "sec_io_desc");
depth++;
-
+
#if 0
/*
* if alignment is needed, should be done by the the
@@ -238,7 +651,7 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if (psd->off_owner_sid != 0) {
- tmp_offset = prs_offset(ps);
+ tmp_offset = ps->data_offset;
if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
return False;
@@ -259,7 +672,7 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if (psd->off_grp_sid != 0) {
- tmp_offset = prs_offset(ps);
+ tmp_offset = ps->data_offset;
if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
return False;
@@ -271,15 +684,15 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
return False;
-
- max_offset = MAX(max_offset, prs_offset(ps));
+ max_offset = MAX(max_offset, prs_offset(ps));
+
if (!prs_set_offset(ps,tmp_offset))
return False;
}
if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
- tmp_offset = prs_offset(ps);
+ tmp_offset = ps->data_offset;
if(!prs_set_offset(ps, old_offset + psd->off_sacl))
return False;
if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
@@ -289,9 +702,8 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
return False;
}
-
if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
- tmp_offset = prs_offset(ps);
+ tmp_offset = ps->data_offset;
if(!prs_set_offset(ps, old_offset + psd->off_dacl))
return False;
if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
@@ -307,6 +719,42 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
}
/*******************************************************************
+ Creates a SEC_DESC_BUF structure.
+********************************************************************/
+
+SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
+{
+ SEC_DESC_BUF *dst;
+
+ if((dst = (SEC_DESC_BUF *)talloc_zero(ctx, sizeof(SEC_DESC_BUF))) == NULL)
+ return NULL;
+
+ /* max buffer size (allocated size) */
+ dst->max_len = (uint32)len;
+ dst->len = (uint32)len;
+
+ if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) {
+ return NULL;
+ }
+
+ dst->ptr = 0x1;
+
+ return dst;
+}
+
+/*******************************************************************
+ Duplicates a SEC_DESC_BUF structure.
+********************************************************************/
+
+SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
+{
+ if(src == NULL)
+ return NULL;
+
+ return make_sec_desc_buf( ctx, src->len, src->sec);
+}
+
+/*******************************************************************
Reads or writes a SEC_DESC_BUF structure.
********************************************************************/
diff --git a/source/rpc_parse/parse_shutdown.c b/source/rpc_parse/parse_shutdown.c
deleted file mode 100644
index ad2d6e1a028..00000000000
--- a/source/rpc_parse/parse_shutdown.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/*******************************************************************
-Inits a structure.
-********************************************************************/
-
-void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
- uint32 timeout, BOOL do_reboot, BOOL force)
-{
- q_s->ptr_server = 1;
- q_s->server = 1;
- q_s->ptr_msg = 1;
-
- init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
- init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
-
- q_s->timeout = timeout;
-
- q_s->reboot = do_reboot ? 1 : 0;
- q_s->force = force ? 1 : 0;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL shutdown_io_q_init(const char *desc, SHUTDOWN_Q_INIT *q_s, prs_struct *ps,
- int depth)
-{
- if (q_s == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "shutdown_io_q_init");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
- return False;
- if (!prs_uint16("server", ps, depth, &(q_s->server)))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("ptr_msg", ps, depth, &(q_s->ptr_msg)))
- return False;
-
- if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
- return False;
- if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
- return False;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
- return False;
- if (!prs_uint8("force ", ps, depth, &(q_s->force)))
- return False;
- if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
- int depth)
-{
- if (r_s == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "shutdown_io_r_init");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_ntstatus("status", ps, depth, &r_s->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-Inits a structure.
-********************************************************************/
-void init_shutdown_q_abort(SHUTDOWN_Q_ABORT *q_s)
-{
-
- q_s->ptr_server = 0;
-
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL shutdown_io_q_abort(const char *desc, SHUTDOWN_Q_ABORT *q_s,
- prs_struct *ps, int depth)
-{
- if (q_s == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "shutdown_io_q_abort");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
- return False;
- if (q_s->ptr_server != 0)
- if (!prs_uint16("server", ps, depth, &(q_s->server)))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL shutdown_io_r_abort(const char *desc, SHUTDOWN_R_ABORT *r_s,
- prs_struct *ps, int depth)
-{
- if (r_s == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "shutdown_io_r_abort");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_ntstatus("status", ps, depth, &r_s->status))
- return False;
-
- return True;
-}
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index ae087c7f774..3700b2fded9 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -24,9 +24,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
/*******************************************************************
return the length of a UNISTR string.
********************************************************************/
@@ -48,7 +45,7 @@ static uint32 str_len_uni(UNISTR *source)
This should be moved in a more generic lib.
********************************************************************/
-BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
+static BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
{
if(!prs_uint16("year", ps, depth, &systime->year))
return False;
@@ -322,74 +319,55 @@ reads or writes an NOTIFY INFO DATA structure.
static BOOL smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
{
- uint32 useless_ptr=0x0FF0ADDE;
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 how_many_words;
+ BOOL isvalue;
+ uint32 x;
+
prs_debug(ps, depth, desc, "smb_io_notify_info_data");
depth++;
+ how_many_words=data->size;
+ if (how_many_words==POINTER) {
+ how_many_words=TWO_VALUE;
+ }
+
+ isvalue=data->enc_type;
+
if(!prs_align(ps))
return False;
if(!prs_uint16("type", ps, depth, &data->type))
return False;
if(!prs_uint16("field", ps, depth, &data->field))
return False;
+ /*prs_align(ps);*/
- if(!prs_uint32("how many words", ps, depth, &data->size))
+ if(!prs_uint32("how many words", ps, depth, &how_many_words))
return False;
if(!prs_uint32("id", ps, depth, &data->id))
return False;
- if(!prs_uint32("how many words", ps, depth, &data->size))
+ if(!prs_uint32("how many words", ps, depth, &how_many_words))
return False;
- switch (data->enc_type) {
- /* One and two value data has two uint32 values */
-
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
+ /*prs_align(ps);*/
+ if (isvalue==True) {
if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
return False;
if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
return False;
- break;
-
- /* Pointers and strings have a string length and a
- pointer. For a string the length is expressed as
- the number of uint16 characters plus a trailing
- \0\0. */
-
- case NOTIFY_POINTER:
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
- return False;
- if(!prs_uint32("pointer", ps, depth, &useless_ptr))
- return False;
-
- break;
-
- case NOTIFY_STRING:
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
+ /*prs_align(ps);*/
+ } else {
+ /* it's a string */
+ /* length in ascii including \0 */
+ x=2*(data->notify_data.data.length+1);
+ if(!prs_uint32("string length", ps, depth, &x ))
return False;
-
if(!prs_uint32("pointer", ps, depth, &useless_ptr))
return False;
-
- break;
-
- case NOTIFY_SECDESC:
- if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
- return False;
- if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
- return False;
-
- break;
-
- default:
- DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
- data->enc_type));
- break;
+ /*prs_align(ps);*/
}
return True;
@@ -402,86 +380,22 @@ reads or writes an NOTIFY INFO DATA structure.
BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
prs_struct *ps, int depth)
{
+ uint32 x;
+ BOOL isvalue;
+
prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
depth++;
if(!prs_align(ps))
return False;
- switch(data->enc_type) {
-
- /* No data for values */
-
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
-
- break;
-
- /* Strings start with a length in uint16s */
-
- case NOTIFY_STRING:
-
- if (UNMARSHALLING(ps)) {
- data->notify_data.data.string =
- (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
-
- if (!data->notify_data.data.string)
- return False;
- }
-
- if (MARSHALLING(ps))
- data->notify_data.data.length /= 2;
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
- return False;
-
- if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
- data->notify_data.data.length))
- return False;
-
- if (MARSHALLING(ps))
- data->notify_data.data.length *= 2;
-
- break;
-
- case NOTIFY_POINTER:
-
- if (UNMARSHALLING(ps)) {
- data->notify_data.data.string =
- (uint16 *)prs_alloc_mem(ps, data->notify_data.data.length);
-
- if (!data->notify_data.data.string)
- return False;
- }
-
- if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
- return False;
-
- break;
-
- case NOTIFY_SECDESC:
- if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
- return False;
- if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
- return False;
- break;
+ isvalue=data->enc_type;
- default:
- DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
- data->enc_type));
- break;
- }
-
-#if 0
if (isvalue==False) {
-
/* length of string in unicode include \0 */
x=data->notify_data.data.length+1;
-
- if (data->field != 16)
if(!prs_uint32("string length", ps, depth, &x ))
return False;
-
if (MARSHALLING(ps)) {
/* These are already in little endian format. Don't byte swap. */
if (x == 1) {
@@ -495,10 +409,6 @@ BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *da
if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
return False;
} else {
-
- if (data->field == 16)
- x /= 2;
-
if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
return False;
}
@@ -514,9 +424,6 @@ BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *da
return False;
}
}
-
-#endif
-
#if 0 /* JERRY */
/* Win2k does not seem to put this parse align here */
if(!prs_align(ps))
@@ -615,10 +522,6 @@ static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struc
if (!prs_align(ps))
return False;
-
- /* From looking at many captures in ethereal, it looks like
- the level and ptr fields should be transposed. -tpot */
-
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
@@ -645,7 +548,7 @@ static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struc
BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
- int available_space; /* size of the device mode left to parse */
+ uint32 available_space; /* size of the device mode left to parse */
/* only important on unmarshalling */
int i = 0;
@@ -663,7 +566,7 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
{ "panningheight", NULL }
};
- /* assign at run time to keep non-gcc compilers happy */
+ /* assign at run time to keep non-gcc vompilers happy */
opt_fields[0].field = &devmode->icmmethod;
opt_fields[1].field = &devmode->icmintent;
@@ -688,17 +591,15 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
return False;
if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
- return False;
+ return False;
/* Sanity Check - look for unknown specversions, but don't fail if we see one.
Let the size determine that */
switch (devmode->specversion) {
- /* list of observed spec version's */
case 0x0320:
case 0x0400:
case 0x0401:
- case 0x040d:
break;
default:
@@ -781,15 +682,15 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
return False;
}
-
+
/*
* Conditional parsing. Assume that the DeviceMode has been
* zero'd by the caller.
*/
-
- while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
+
+ while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
{
- DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
+ DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
return False;
available_space -= sizeof(uint32);
@@ -798,7 +699,7 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
/* Sanity Check - we should no available space at this point unless
MS changes the device mode structure */
-
+
if (available_space) {
DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
@@ -806,7 +707,7 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
return False;
}
-
+
if (devmode->driverextra!=0) {
if (UNMARSHALLING(ps)) {
@@ -916,12 +817,12 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
{
DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
q_u->printername_ptr = (printername!=NULL)?1:0;
- init_unistr2(&q_u->printername, printername, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->printername, printername, strlen(printername)+1);
q_u->printer_default.datatype_ptr = 0;
/*
q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
- init_unistr2(&q_u->printer_default.datatype, datatype, UNI_FLAGS_NONE);
+ init_unistr2(&q_u->printer_default.datatype, datatype, strlen(datatype));
*/
q_u->printer_default.devmode_cont.size=0;
q_u->printer_default.devmode_cont.devmode_ptr=0;
@@ -937,8 +838,8 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
q_u->user_ctr.user1.major=2;
q_u->user_ctr.user1.minor=0;
q_u->user_ctr.user1.processor=0;
- init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
- init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
+ init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
return True;
}
@@ -963,7 +864,7 @@ BOOL make_spoolss_q_addprinterex(
ZERO_STRUCTP(q_u);
q_u->server_name_ptr = (srv_name!=NULL)?1:0;
- init_unistr2(&q_u->server_name, srv_name, UNI_FLAGS_NONE);
+ init_unistr2(&q_u->server_name, srv_name, strlen(srv_name));
q_u->level = level;
@@ -991,8 +892,8 @@ BOOL make_spoolss_q_addprinterex(
q_u->user_ctr.user1.major=2;
q_u->user_ctr.user1.minor=0;
q_u->user_ctr.user1.processor=0;
- init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
- init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
+ init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
q_u->user_ctr.user1.client_name.uni_str_len + 2;
@@ -1101,11 +1002,11 @@ BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_
return False;
if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
- return False;
+ return False;
if (!prs_werror("status code", ps, depth, &(r_u->status)))
return False;
-
+
return True;
}
@@ -1136,12 +1037,12 @@ BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u
if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
return False;
-
+
if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
return False;
if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
return False;
-
+
return True;
}
@@ -1187,48 +1088,29 @@ BOOL make_spoolss_q_deleteprinterdriver(
/* these must be NULL terminated or else NT4 will
complain about invalid parameters --jerry */
- init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
- init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
- init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->server, server, strlen(server)+1);
+ init_unistr2(&q_u->arch, arch, strlen(arch)+1);
+ init_unistr2(&q_u->driver, driver, strlen(driver)+1);
+
return True;
}
+
/*******************************************************************
* make a structure.
********************************************************************/
BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
- const POLICY_HND *handle,
- const char *valuename, uint32 size)
+ const POLICY_HND *handle,
+ UNISTR2 *valuename, uint32 size)
{
if (q_u == NULL) return False;
DEBUG(5,("make_spoolss_q_getprinterdata\n"));
q_u->handle = *handle;
- init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
- q_u->size = size;
-
- return True;
-}
-
-/*******************************************************************
- * make a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
- const POLICY_HND *handle,
- const char *keyname,
- const char *valuename, uint32 size)
-{
- if (q_u == NULL) return False;
-
- DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
-
- q_u->handle = *handle;
- init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
- init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
+ copy_unistr2(&q_u->valuename, valuename);
q_u->size = size;
return True;
@@ -1304,48 +1186,6 @@ BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA
}
/*******************************************************************
- * read a structure.
- * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
- ********************************************************************/
-
-BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
-{
- if (q_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
-
- if (!smb_io_unistr2("keyname ", &q_u->keyname, True, ps, depth))
- return False;
- if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- * write a structure.
- * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
- ********************************************************************/
-
-BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
- depth++;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
* write a structure.
* called from spoolss_r_getprinterdata (srv_spoolss.c)
********************************************************************/
@@ -1366,12 +1206,12 @@ BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u,
return False;
if (UNMARSHALLING(ps) && r_u->size) {
- r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
+ r_u->data = prs_alloc_mem(ps, r_u->size);
if(!r_u->data)
return False;
}
- if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
+ if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
return False;
if (!prs_align(ps))
@@ -1532,64 +1372,6 @@ BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRI
}
-/*******************************************************************
- * read a structure.
- * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
- * called from spoolss_deleteprinterdriver (cli_spoolss.c)
- ********************************************************************/
-
-BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
-{
- if (q_u == NULL) return False;
-
- prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
- return False;
- if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
- return False;
- if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
- return False;
- if(!prs_uint32("version ", ps, depth, &q_u->version))
- return False;
-
-
- return True;
-}
-
-
-/*******************************************************************
- * write a structure.
- ********************************************************************/
-BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
-{
- if (r_u == NULL) return False;
-
- prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-
/*******************************************************************
* read a structure.
@@ -2100,9 +1882,6 @@ static BOOL smb_io_relstr(const char *desc, NEW_BUFFER *buffer, int depth, UNIST
if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
return False;
- if (buffer->string_at_end == 0)
- return True;
-
old_offset = prs_offset(ps);
if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
return False;
@@ -2510,7 +2289,7 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
prs_struct *ps=&buffer->prs;
uint32 dm_offset, sd_offset, current_offset;
uint32 dummy_value = 0, has_secdesc = 0;
-
+
prs_debug(ps, depth, desc, "smb_io_printer_info_2");
depth++;
@@ -2535,7 +2314,7 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
dm_offset = prs_offset(ps);
if (!prs_uint32("devmode", ps, depth, &dummy_value))
return False;
-
+
if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
return False;
if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
@@ -2549,7 +2328,6 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
sd_offset = prs_offset(ps);
if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
return False;
-
/* save current location so we can pick back up here */
current_offset = prs_offset(ps);
@@ -2561,13 +2339,13 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
return False;
/* parse the sec_desc */
- if (info->secdesc) {
+ if (has_secdesc) {
if (!prs_set_offset(ps, sd_offset))
return False;
if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
return False;
}
-
+
/* pick up where we left off */
if (!prs_set_offset(ps, current_offset))
return False;
@@ -2662,26 +2440,6 @@ BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5
}
/*******************************************************************
- Parse a PRINTER_INFO_7 structure.
-********************************************************************/
-
-BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
-{
- prs_struct *ps=&buffer->prs;
-
- prs_debug(ps, depth, desc, "smb_io_printer_info_7");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (!smb_io_relstr("guid", buffer, depth, &info->guid))
- return False;
- if (!prs_uint32("action", ps, depth, &info->action))
- return False;
- return True;
-}
-
-/*******************************************************************
Parse a PORT_INFO_1 structure.
********************************************************************/
@@ -3357,7 +3115,7 @@ return the size required by a struct in the stream
uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
{
- uint32 size=0;
+ uint32 size=0;
size += 4;
@@ -3394,7 +3152,7 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
* it is easier to maintain the calculation here and
* not place the burden on the caller to remember. --jerry
*/
- if ((size % 4) != 0)
+ if ((size % 4) != 0)
size += 4 - (size % 4);
return size;
@@ -3448,19 +3206,6 @@ uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
-{
- uint32 size=0;
-
- size+=size_of_relative_string( &info->guid );
- size+=size_of_uint32( &info->action );
- return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
{
int size=0;
@@ -3879,7 +3624,7 @@ BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2
BOOL make_spoolss_q_enumprinters(
SPOOL_Q_ENUMPRINTERS *q_u,
uint32 flags,
- char *servername,
+ fstring servername,
uint32 level,
NEW_BUFFER *buffer,
uint32 offered
@@ -4197,7 +3942,7 @@ BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_stru
if (!prs_uint32("size", ps, depth + 1, &dummy))
return False;
if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
- False;
+ False;
}
if(!prs_uint32("command", ps, depth, &q_u->command))
@@ -4862,24 +4607,6 @@ BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2
return True;
}
-BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
- return False;
- if(!prs_uint32("action", ps, depth, &il->action))
- return False;
-
- if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
- return False;
- return True;
-}
-
/*******************************************************************
********************************************************************/
@@ -4945,13 +4672,6 @@ BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il,
return False;
break;
}
- case 7:
- if (UNMARSHALLING(ps))
- if ((il->info_7=(SPOOL_PRINTER_INFO_LEVEL_7 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_7))) == NULL)
- return False;
- if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
- return False;
- break;
}
return True;
@@ -5156,9 +4876,9 @@ BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER
if(!prs_uint32("cversion ", ps, depth, &il->version))
return False;
if(!prs_uint32("name ", ps, depth, &il->name_ptr))
- return False;
+ return False;
if(!prs_uint32("environment ", ps, depth, &il->environment_ptr))
- return False;
+ return False;
if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr))
return False;
if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr))
@@ -5287,7 +5007,7 @@ static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
*ar = NULL;
while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
- rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
+ unistr_to_dos(f, src, sizeof(f)-1);
src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
if (!tar)
@@ -5315,7 +5035,7 @@ BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int dep
{
if (buffer==NULL) return False;
- buffer->offset=0;
+ buffer->undoc=0;
buffer->uni_str_len=buffer->uni_max_len;
if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
@@ -5372,7 +5092,7 @@ BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
q_u->server_name_ptr = (srv_name!=NULL)?1:0;
- init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->server_name, srv_name, strlen(srv_name)+1);
q_u->level = level;
@@ -5384,7 +5104,7 @@ BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
case 3 :
make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
break;
-
+
default:
DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
break;
@@ -5394,7 +5114,7 @@ BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
}
BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
+ SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
DRIVER_INFO_3 *info3)
{
uint32 len = 0;
@@ -5518,53 +5238,6 @@ BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q
}
/*******************************************************************
- fill in the prs_struct for a ADDPRINTERDRIVER request PDU
- ********************************************************************/
-
-BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
- return False;
- if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("info_level", ps, depth, &q_u->level))
- return False;
-
- if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
- depth++;
-
- if(!prs_werror("status", ps, depth, &q_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
********************************************************************/
BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
@@ -5586,14 +5259,14 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
d->cversion=uni->cversion;
- unistr2_to_ascii(d->name, &uni->name, sizeof(d->name)-1);
- unistr2_to_ascii(d->environment, &uni->environment, sizeof(d->environment)-1);
- unistr2_to_ascii(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
- unistr2_to_ascii(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
- unistr2_to_ascii(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
- unistr2_to_ascii(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
- unistr2_to_ascii(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
- unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
+ unistr2_to_dos(d->name, &uni->name, sizeof(d->name)-1);
+ unistr2_to_dos(d->environment, &uni->environment, sizeof(d->environment)-1);
+ unistr2_to_dos(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
+ unistr2_to_dos(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
+ unistr2_to_dos(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
+ unistr2_to_dos(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
+ unistr2_to_dos(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
+ unistr2_to_dos(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
DEBUGADD(8,( "version: %d\n", d->cversion));
DEBUGADD(8,( "name: %s\n", d->name));
@@ -5633,14 +5306,14 @@ BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
d->version=uni->version;
- unistr2_to_ascii(d->name, &uni->name, sizeof(d->name)-1);
- unistr2_to_ascii(d->environment, &uni->environment, sizeof(d->environment)-1);
- unistr2_to_ascii(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
- unistr2_to_ascii(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
- unistr2_to_ascii(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
- unistr2_to_ascii(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
- unistr2_to_ascii(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
- unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
+ unistr2_to_dos(d->name, &uni->name, sizeof(d->name)-1);
+ unistr2_to_dos(d->environment, &uni->environment, sizeof(d->environment)-1);
+ unistr2_to_dos(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
+ unistr2_to_dos(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
+ unistr2_to_dos(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
+ unistr2_to_dos(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
+ unistr2_to_dos(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
+ unistr2_to_dos(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
DEBUGADD(8,( "version: %d\n", d->version));
DEBUGADD(8,( "name: %s\n", d->name));
@@ -5685,7 +5358,6 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
* addprinter(ex) so we can do one time stuff here.
*/
(*asc)->setuptime=time_unix;
-
}
DEBUGADD(8,("start converting\n"));
@@ -5699,17 +5371,17 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
d->status=uni->status;
d->cjobs=uni->cjobs;
- unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
- unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
- unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
- unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
- unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
- unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
- unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
- unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
- unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
- unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
- unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
+ unistr2_to_dos(d->servername, &uni->servername, sizeof(d->servername)-1);
+ unistr2_to_dos(d->printername, &uni->printername, sizeof(d->printername)-1);
+ unistr2_to_dos(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
+ unistr2_to_dos(d->portname, &uni->portname, sizeof(d->portname)-1);
+ unistr2_to_dos(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
+ unistr2_to_dos(d->comment, &uni->comment, sizeof(d->comment)-1);
+ unistr2_to_dos(d->location, &uni->location, sizeof(d->location)-1);
+ unistr2_to_dos(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
+ unistr2_to_dos(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
+ unistr2_to_dos(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
+ unistr2_to_dos(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
return True;
}
@@ -6154,50 +5826,22 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
/*******************************************************************
********************************************************************/
-
-BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
- const POLICY_HND *hnd, const char *key,
- uint32 size)
+BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
+ char* value, char* data)
{
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
- init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
- q_u->size = size;
+ UNISTR2 tmp;
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
- char* value, uint32 data_type, char* data, uint32 data_size)
-{
memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
- q_u->type = data_type;
- init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
+ q_u->type = REG_SZ;
+ init_unistr2(&q_u->value, value, strlen(value)+1);
- q_u->max_len = q_u->real_len = data_size;
- q_u->data = (unsigned char *)data;
+ init_unistr2(&tmp, data, strlen(data)+1);
+ q_u->max_len = q_u->real_len = tmp.uni_max_len*2;
+ q_u->data = talloc(ctx, q_u->real_len);
+ memcpy(q_u->data, tmp.buffer, q_u->real_len);
return True;
}
-
-/*******************************************************************
-********************************************************************/
-BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
- char *key, char* value, uint32 data_type, char* data,
- uint32 data_size)
-{
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
- q_u->type = data_type;
- init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
- init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
-
- q_u->max_len = q_u->real_len = data_size;
- q_u->data = (unsigned char *)data;
-
- return True;
-}
-
/*******************************************************************
********************************************************************/
@@ -6280,7 +5924,7 @@ BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_
if (q_u->datatype_ptr) {
if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
- return False;
+ return False;
}
if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
@@ -6307,6 +5951,42 @@ BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_
/*******************************************************************
********************************************************************/
+BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
+ uint32 type, const uint8 *data, uint32 len)
+{
+ DEBUG(5,("converting a specific param struct\n"));
+
+ if (*param == NULL)
+ {
+ *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
+ if(*param == NULL)
+ return False;
+ memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
+ DEBUGADD(6,("Allocated a new PARAM struct\n"));
+ }
+ unistr2_to_dos((*param)->value, value, sizeof((*param)->value)-1);
+ (*param)->type = type;
+
+ /* le champ data n'est pas NULL termine */
+ /* on stocke donc la longueur */
+
+ (*param)->data_len=len;
+
+ if (len) {
+ (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
+ if((*param)->data == NULL)
+ return False;
+ memcpy((*param)->data, data, len);
+ }
+
+ DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
+ dump_data(10, (char *)(*param)->data, (*param)->data_len);
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
{
@@ -6566,11 +6246,6 @@ void free_printer_info_5(PRINTER_INFO_5 *printer)
SAFE_FREE(printer);
}
-void free_printer_info_7(PRINTER_INFO_7 *printer)
-{
- SAFE_FREE(printer);
-}
-
void free_job_info_2(JOB_INFO_2 *job)
{
if (job!=NULL)
@@ -6587,7 +6262,7 @@ BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u,
if (q_u == NULL)
return False;
- init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->string, string, strlen(string)+1);
q_u->printer=printer;
q_u->type=type;
@@ -6855,7 +6530,7 @@ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
q_u->unknown0=0x0;
q_u->unknown1=0x0;
- q_u->info_ptr=0x0FF0ADDE;
+ q_u->info_ptr=0xaddee11e;
q_u->info.version=2;
@@ -6869,8 +6544,8 @@ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
q_u->info.data = info->data;
}
else {
- q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
- q_u->info.count=0;
+ q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
+ q_u->info.count=0;
}
return True;
@@ -6988,7 +6663,7 @@ BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r
return False;
if (UNMARSHALLING(ps) && r_u->size) {
- r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
+ r_u->data = prs_alloc_mem(ps, r_u->size);
if(!r_u->data)
return False;
}
@@ -7080,21 +6755,6 @@ BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r
return True;
}
-/*******************************************************************
- * read a structure.
- ********************************************************************/
-BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u,
- POLICY_HND *hnd, const char *key,
- uint32 size)
-{
- DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
-
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
- init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
- q_u->size = size;
-
- return True;
-}
/*******************************************************************
* read a structure.
@@ -7149,59 +6809,6 @@ BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u,
return True;
}
-/*******************************************************************
- * read a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u,
- POLICY_HND *hnd, char *keyname)
-{
- DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
-
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
- init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
-
- return True;
-}
-
-/*******************************************************************
- * read a structure.
- ********************************************************************/
-
-BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
-
- if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- * write a structure.
- ********************************************************************/
-
-BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
/*******************************************************************
* read a structure.
@@ -7294,16 +6901,15 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps,
if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
return False;
- if ( ctr->values[i].data_len ) {
- if ( UNMARSHALLING(ps) ) {
- ctr->values[i].data = (uint8 *)prs_alloc_mem(
- ps, ctr->values[i].data_len);
- if (!ctr->values[i].data)
- return False;
- }
- if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
+ if (UNMARSHALLING(ps)) {
+ ctr->values[i].data = (uint8 *)prs_alloc_mem(
+ ps, ctr->values[i].data_len);
+ if (!ctr->values[i].data)
return False;
}
+
+ if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
+ return False;
if ( !prs_align_uint16(ps) )
return False;
@@ -7382,8 +6988,8 @@ BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTOR
{
DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
- init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
- init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->name, name, strlen(name)+1);
+ init_unistr2(&q_u->environment, environment, strlen(environment)+1);
q_u->level = level;
@@ -7503,13 +7109,13 @@ BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle,
********************************************************************/
BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle,
- int level, const char *form_name, FORM *form)
+ int level, char *form_name, FORM *form)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
q_u->level = level;
q_u->level2 = level;
memcpy(&q_u->form, form, sizeof(FORM));
- init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->name, form_name, strlen(form_name) + 1);
return True;
}
@@ -7518,11 +7124,10 @@ BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle,
* init a structure.
********************************************************************/
-BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle,
- const char *form)
+BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, char *form)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->name, form, strlen(form) + 1);
return True;
}
@@ -7531,12 +7136,12 @@ BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle,
********************************************************************/
BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
- const char *formname, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ char *formname, uint32 level, NEW_BUFFER *buffer,
+ uint32 offered)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
q_u->level = level;
- init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
+ init_unistr2(&q_u->formname, formname, strlen(formname) + 1);
q_u->buffer=buffer;
q_u->offered=offered;
@@ -7558,184 +7163,3 @@ BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
return True;
}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
- uint32 jobid, uint32 level, uint32 command)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- q_u->jobid = jobid;
- q_u->level = level;
-
- /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
- the server side code has it marked as unused. */
-
- q_u->command = command;
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
- uint32 jobid, uint32 level, NEW_BUFFER *buffer,
- uint32 offered)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- q_u->jobid = jobid;
- q_u->level = level;
- q_u->buffer = buffer;
- q_u->offered = offered;
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u,
- POLICY_HND *handle)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u,
- POLICY_HND *handle)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u,
- POLICY_HND *handle, uint32 level,
- char *docname, char *outputfile,
- char *datatype)
-{
- DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
-
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- ctr->level = level;
-
- switch (level) {
- case 1:
- ctr->docinfo.switch_value = level;
-
- ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
- ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
- ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
-
- init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
- init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
- init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
-
- break;
- case 2:
- /* DOC_INFO_2 is only used by Windows 9x and since it
- doesn't do printing over RPC we don't have to worry
- about it. */
- default:
- DEBUG(3, ("unsupported info level %d\n", level));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u,
- POLICY_HND *handle)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u,
- POLICY_HND *handle, uint32 data_size,
- char *data)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- q_u->buffer_size = q_u->buffer_size2 = data_size;
- q_u->buffer = (unsigned char *)data;
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
- POLICY_HND *handle, char *valuename)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u,
- POLICY_HND *handle, char *key,
- char *value)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
- init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
- uint32 flags, uint32 options, const char *localmachine,
- uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- q_u->flags = flags;
- q_u->options = options;
-
- q_u->localmachine_ptr = 1;
-
- init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
-
- q_u->printerlocal = printerlocal;
-
- if (option)
- q_u->option_ptr = 1;
-
- q_u->option = option;
-
- return True;
-}
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 6349fc16325..ea30438fdb3 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -1,12 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jeremy Allison 1999,
- * Copyright (C) Nigel Williams 2001,
- * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2002.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,73 +24,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/*******************************************************************
- Inits a SH_INFO_0_STR structure
-********************************************************************/
-
-void init_srv_share_info0_str(SH_INFO_0_STR *sh0, const char *net_name)
-{
- DEBUG(5,("init_srv_share_info0_str\n"));
-
- init_unistr2(&sh0->uni_netname, net_name, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info0_str(const char *desc, SH_INFO_0_STR *sh0, prs_struct *ps, int depth)
-{
- if (sh0 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info0_str");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(sh0->ptrs->ptr_netname)
- if(!smb_io_unistr2("", &sh0->uni_netname, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- makes a SH_INFO_0 structure
-********************************************************************/
-
-void init_srv_share_info0(SH_INFO_0 *sh0, const char *net_name)
-{
- DEBUG(5,("init_srv_share_info0: %s\n", net_name));
-
- sh0->ptr_netname = (net_name != NULL) ? 1 : 0;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info0(const char *desc, SH_INFO_0 *sh0, prs_struct *ps, int depth)
-{
- if (sh0 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info0");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_netname", ps, depth, &sh0->ptr_netname))
- return False;
-
- return True;
-}
-
/*******************************************************************
Inits a SH_INFO_1_STR structure
********************************************************************/
@@ -100,8 +32,8 @@ void init_srv_share_info1_str(SH_INFO_1_STR *sh1, const char *net_name, const ch
{
DEBUG(5,("init_srv_share_info1_str\n"));
- init_unistr2(&sh1->uni_netname, net_name, UNI_STR_TERMINATE);
- init_unistr2(&sh1->uni_remark, remark, UNI_STR_TERMINATE);
+ init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
+ init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
}
/*******************************************************************
@@ -112,24 +44,20 @@ static BOOL srv_io_share_info1_str(const char *desc, SH_INFO_1_STR *sh1, prs_str
{
if (sh1 == NULL)
return False;
-
+
prs_debug(ps, depth, desc, "srv_io_share_info1_str");
depth++;
-
+
if(!prs_align(ps))
return False;
+ if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
+ return False;
- if(sh1->ptrs->ptr_netname)
- if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
- return False;
-
if(!prs_align(ps))
return False;
-
- if(sh1->ptrs->ptr_remark)
- if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
- return False;
-
+ if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
+ return False;
+
return True;
}
@@ -140,7 +68,7 @@ static BOOL srv_io_share_info1_str(const char *desc, SH_INFO_1_STR *sh1, prs_str
void init_srv_share_info1(SH_INFO_1 *sh1, const char *net_name, uint32 type, const char *remark)
{
DEBUG(5,("init_srv_share_info1: %s %8x %s\n", net_name, type, remark));
-
+
sh1->ptr_netname = (net_name != NULL) ? 1 : 0;
sh1->type = type;
sh1->ptr_remark = (remark != NULL) ? 1 : 0;
@@ -181,10 +109,10 @@ void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
{
DEBUG(5,("init_srv_share_info2_str\n"));
- init_unistr2(&sh2->uni_netname, net_name, UNI_STR_TERMINATE);
- init_unistr2(&sh2->uni_remark, remark, UNI_STR_TERMINATE);
- init_unistr2(&sh2->uni_path, path, UNI_STR_TERMINATE);
- init_unistr2(&sh2->uni_passwd, passwd, UNI_STR_TERMINATE);
+ init_unistr2(&sh2->uni_netname, net_name, strlen(net_name)+1);
+ init_unistr2(&sh2->uni_remark, remark, strlen(remark)+1);
+ init_unistr2(&sh2->uni_path, path, strlen(path)+1);
+ init_unistr2(&sh2->uni_passwd, passwd, strlen(passwd)+1);
}
/*******************************************************************
@@ -204,7 +132,6 @@ static BOOL srv_io_share_info2_str(const char *desc, SH_INFO_2 *sh, SH_INFO_2_ST
if(!prs_align(ps))
return False;
-
if (sh->ptr_netname)
if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth))
return False;
@@ -241,6 +168,7 @@ void init_srv_share_info2(SH_INFO_2 *sh2,
sh2->perms = perms;
sh2->max_uses = max_uses;
sh2->num_uses = num_uses;
+ sh2->type = type;
sh2->ptr_path = (path != NULL) ? 1 : 0;
sh2->ptr_passwd = (passwd != NULL) ? 1 : 0;
}
@@ -281,19 +209,6 @@ static BOOL srv_io_share_info2(const char *desc, SH_INFO_2 *sh2, prs_struct *ps,
}
/*******************************************************************
- Inits a SH_INFO_501_STR structure
-********************************************************************/
-
-void init_srv_share_info501_str(SH_INFO_501_STR *sh501,
- const char *net_name, const char *remark)
-{
- DEBUG(5,("init_srv_share_info501_str\n"));
-
- init_unistr2(&sh501->uni_netname, net_name, UNI_STR_TERMINATE);
- init_unistr2(&sh501->uni_remark, remark, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
Inits a SH_INFO_2 structure
*******************************************************************/
@@ -337,6 +252,18 @@ static BOOL srv_io_share_info501(const char *desc, SH_INFO_501 *sh501, prs_struc
return True;
}
+/********************************************************************
+ Inits a SH_INFO_501_STR structure
+********************************************************************/
+
+void init_srv_share_info501_str(SH_INFO_501_STR *sh501, const char *net_name, const char *remark)
+{
+ DEBUG(5,("init_srv_share_info501_str\n"));
+
+ init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1);
+ init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1);
+}
+
/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -381,9 +308,9 @@ void init_srv_share_info502(SH_INFO_502 *sh502,
sh502->perms = perms;
sh502->max_uses = max_uses;
sh502->num_uses = num_uses;
+ sh502->type = type;
sh502->ptr_path = (path != NULL) ? 1 : 0;
sh502->ptr_passwd = (passwd != NULL) ? 1 : 0;
- sh502->reserved = 0; /* actual size within rpc */
sh502->sd_size = (uint32)sd_size;
sh502->ptr_sd = (psd != NULL) ? 1 : 0;
}
@@ -419,7 +346,7 @@ static BOOL srv_io_share_info502(const char *desc, SH_INFO_502 *sh502, prs_struc
return False;
if(!prs_uint32("ptr_passwd ", ps, depth, &sh502->ptr_passwd))
return False;
- if(!prs_uint32_pre("reserved ", ps, depth, &sh502->reserved, &sh502->reserved_offset))
+ if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size))
return False;
if(!prs_uint32("ptr_sd ", ps, depth, &sh502->ptr_sd))
return False;
@@ -432,18 +359,26 @@ static BOOL srv_io_share_info502(const char *desc, SH_INFO_502 *sh502, prs_struc
********************************************************************/
void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
+ SH_INFO_502 *ptrs,
const char *net_name, const char *remark,
const char *path, const char *passwd, SEC_DESC *psd, size_t sd_size)
{
DEBUG(5,("init_srv_share_info502_str\n"));
- init_unistr2(&sh502str->uni_netname, net_name, UNI_STR_TERMINATE);
- init_unistr2(&sh502str->uni_remark, remark, UNI_STR_TERMINATE);
- init_unistr2(&sh502str->uni_path, path, UNI_STR_TERMINATE);
- init_unistr2(&sh502str->uni_passwd, passwd, UNI_STR_TERMINATE);
- sh502str->sd = psd;
- sh502str->reserved = 0;
- sh502str->sd_size = sd_size;
+ sh502str->ptrs = ptrs;
+
+ if(sh502str->ptrs->ptr_netname)
+ init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1);
+ if(sh502str->ptrs->ptr_remark)
+ init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1);
+ if(sh502str->ptrs->ptr_path)
+ init_unistr2(&sh502str->uni_path, path, strlen(path)+1);
+ if(sh502str->ptrs->ptr_passwd)
+ init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1);
+ if(sh502str->ptrs->ptr_sd) {
+ sh502str->sd = psd;
+ sh502str->sd_size = sd_size;
+ }
}
/*******************************************************************
@@ -494,111 +429,21 @@ static BOOL srv_io_share_info502_str(const char *desc, SH_INFO_502_STR *sh502, p
return False;
if(sh502->ptrs->ptr_sd) {
- uint32 old_offset;
- uint32 reserved_offset;
-
- if(!prs_uint32_pre("reserved ", ps, depth, &sh502->reserved, &reserved_offset))
+ if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size))
return False;
-
- old_offset = prs_offset(ps);
-
if (!sec_io_desc(desc, &sh502->sd, ps, depth))
return False;
-
- if(UNMARSHALLING(ps)) {
-
- sh502->ptrs->sd_size = sh502->sd_size = sec_desc_size(sh502->sd);
-
- prs_set_offset(ps, old_offset + sh502->reserved);
- }
-
- prs_align(ps);
-
- if(MARSHALLING(ps)) {
-
- sh502->ptrs->reserved = sh502->reserved = prs_offset(ps) - old_offset;
- }
-
- if(!prs_uint32_post("reserved ", ps, depth,
- &sh502->reserved, reserved_offset, sh502->reserved))
- return False;
- if(!prs_uint32_post("reserved ", ps, depth,
- &sh502->ptrs->reserved, sh502->ptrs->reserved_offset, sh502->ptrs->reserved))
- return False;
}
return True;
}
/*******************************************************************
- Inits a SH_INFO_1004_STR structure
-********************************************************************/
-
-void init_srv_share_info1004_str(SH_INFO_1004_STR *sh1004, const char *remark)
-{
- DEBUG(5,("init_srv_share_info1004_str\n"));
-
- init_unistr2(&sh1004->uni_remark, remark, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1004_str(const char *desc, SH_INFO_1004_STR *sh1004, prs_struct *ps, int depth)
-{
- if (sh1004 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info1004_str");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(sh1004->ptrs->ptr_remark)
- if(!smb_io_unistr2("", &sh1004->uni_remark, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- makes a SH_INFO_1004 structure
-********************************************************************/
-
-void init_srv_share_info1004(SH_INFO_1004 *sh1004, const char *remark)
-{
- DEBUG(5,("init_srv_share_info1004: %s\n", remark));
-
- sh1004->ptr_remark = (remark != NULL) ? 1 : 0;
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
-static BOOL srv_io_share_info1004(const char *desc, SH_INFO_1004 *sh1004, prs_struct *ps, int depth)
-{
- if (sh1004 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info1004");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_remark", ps, depth, &sh1004->ptr_remark))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1005(const char* desc, SRV_SHARE_INFO_1005* sh1005, prs_struct* ps, int depth)
+static BOOL srv_io_share_info1005(const char* desc, SRV_SHARE_INFO_1005* sh1005,
+ prs_struct* ps, int depth)
{
if(sh1005 == NULL)
return False;
@@ -609,8 +454,7 @@ static BOOL srv_io_share_info1005(const char* desc, SRV_SHARE_INFO_1005* sh1005,
if(!prs_align(ps))
return False;
- if(!prs_uint32("share_info_flags", ps, depth,
- &sh1005->share_info_flags))
+ if(!prs_uint32("misc_flags", ps, depth, &sh1005->misc_flags))
return False;
return True;
@@ -620,94 +464,6 @@ static BOOL srv_io_share_info1005(const char* desc, SRV_SHARE_INFO_1005* sh1005,
Reads or writes a structure.
********************************************************************/
-static BOOL srv_io_share_info1006(const char* desc, SRV_SHARE_INFO_1006* sh1006, prs_struct* ps, int depth)
-{
- if(sh1006 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info1006");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("max uses ", ps, depth, &sh1006->max_uses))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a SH_INFO_1007_STR structure
-********************************************************************/
-
-void init_srv_share_info1007_str(SH_INFO_1007_STR *sh1007, const char *alternate_directory_name)
-{
- DEBUG(5,("init_srv_share_info1007_str\n"));
-
- init_unistr2(&sh1007->uni_AlternateDirectoryName, alternate_directory_name, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1007_str(const char *desc, SH_INFO_1007_STR *sh1007, prs_struct *ps, int depth)
-{
- if (sh1007 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info1007_str");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(sh1007->ptrs->ptr_AlternateDirectoryName)
- if(!smb_io_unistr2("", &sh1007->uni_AlternateDirectoryName, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- makes a SH_INFO_1007 structure
-********************************************************************/
-
-void init_srv_share_info1007(SH_INFO_1007 *sh1007, uint32 flags, const char *alternate_directory_name)
-{
- DEBUG(5,("init_srv_share_info1007: %s\n", alternate_directory_name));
-
- sh1007->flags = flags;
- sh1007->ptr_AlternateDirectoryName = (alternate_directory_name != NULL) ? 1 : 0;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1007(const char *desc, SH_INFO_1007 *sh1007, prs_struct *ps, int depth)
-{
- if (sh1007 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_share_info1007");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("flags ", ps, depth, &sh1007->flags))
- return False;
- if(!prs_uint32("ptr_Alter..", ps, depth, &sh1007->ptr_AlternateDirectoryName))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
static BOOL srv_io_share_info1501(const char* desc, SRV_SHARE_INFO_1501* sh1501,
prs_struct* ps, int depth)
{
@@ -748,6 +504,9 @@ static BOOL srv_io_srv_share_ctr(const char *desc, SRV_SHARE_INFO_CTR *ctr, prs_
if(!prs_uint32("info_level", ps, depth, &ctr->info_level))
return False;
+ if (ctr->info_level == 0)
+ return True;
+
if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
return False;
if(!prs_uint32("ptr_share_info", ps, depth, &ctr->ptr_share_info))
@@ -775,33 +534,6 @@ static BOOL srv_io_srv_share_ctr(const char *desc, SRV_SHARE_INFO_CTR *ctr, prs_
return False;
switch (ctr->switch_value) {
-
- case 0:
- {
- SRV_SHARE_INFO_0 *info0 = ctr->share.info0;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info0 = (SRV_SHARE_INFO_0 *)prs_alloc_mem(ps, num_entries * sizeof(SRV_SHARE_INFO_0))))
- return False;
- ctr->share.info0 = info0;
- }
-
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info0("", &info0[i].info_0, ps, depth))
- return False;
- }
-
- for (i = 0; i < num_entries; i++) {
- info0[i].info_0_str.ptrs = &info0[i].info_0;
- if(!srv_io_share_info0_str("", &info0[i].info_0_str, ps, depth))
- return False;
- }
-
- break;
- }
-
case 1:
{
SRV_SHARE_INFO_1 *info1 = ctr->share.info1;
@@ -820,7 +552,6 @@ static BOOL srv_io_srv_share_ctr(const char *desc, SRV_SHARE_INFO_CTR *ctr, prs_
}
for (i = 0; i < num_entries; i++) {
- info1[i].info_1_str.ptrs = &info1[i].info_1;
if(!srv_io_share_info1_str("", &info1[i].info_1_str, ps, depth))
return False;
}
@@ -894,123 +625,11 @@ static BOOL srv_io_srv_share_ctr(const char *desc, SRV_SHARE_INFO_CTR *ctr, prs_
for (i = 0; i < num_entries; i++) {
if(!srv_io_share_info502("", &info502[i].info_502, ps, depth))
return False;
- }
-
- for (i = 0; i < num_entries; i++) {
- info502[i].info_502_str.ptrs = &info502[i].info_502;
- if(!srv_io_share_info502_str("", &info502[i].info_502_str, ps, depth))
- return False;
- }
-
- break;
- }
-
- case 1004:
- {
- SRV_SHARE_INFO_1004 *info1004 = ctr->share.info1004;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info1004 = (SRV_SHARE_INFO_1004 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1004))))
- return False;
- ctr->share.info1004 = info1004;
- }
-
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1004("", &info1004[i].info_1004, ps, depth))
- return False;
- }
-
- for (i = 0; i < num_entries; i++) {
- info1004[i].info_1004_str.ptrs = &info1004[i].info_1004;
- if(!srv_io_share_info1004_str("", &info1004[i].info_1004_str, ps, depth))
- return False;
- }
-
- break;
- }
-
- case 1005:
- {
- SRV_SHARE_INFO_1005 *info1005 = ctr->share.info1005;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info1005 = (SRV_SHARE_INFO_1005 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1005))))
- return False;
- ctr->share.info1005 = info1005;
- }
-
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1005("", &info1005[i], ps, depth))
- return False;
- }
-
- break;
- }
-
- case 1006:
- {
- SRV_SHARE_INFO_1006 *info1006 = ctr->share.info1006;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info1006 = (SRV_SHARE_INFO_1006 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1006))))
- return False;
- ctr->share.info1006 = info1006;
- }
-
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1006("", &info1006[i], ps, depth))
- return False;
- }
-
- break;
- }
-
- case 1007:
- {
- SRV_SHARE_INFO_1007 *info1007 = ctr->share.info1007;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info1007 = (SRV_SHARE_INFO_1007 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1007))))
- return False;
- ctr->share.info1007 = info1007;
}
for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1007("", &info1007[i].info_1007, ps, depth))
- return False;
- }
-
- for (i = 0; i < num_entries; i++) {
- info1007[i].info_1007_str.ptrs = &info1007[i].info_1007;
- if(!srv_io_share_info1007_str("", &info1007[i].info_1007_str, ps, depth))
- return False;
- }
-
- break;
- }
-
- case 1501:
- {
- SRV_SHARE_INFO_1501 *info1501 = ctr->share.info1501;
- int num_entries = ctr->num_entries;
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (!(info1501 = (SRV_SHARE_INFO_1501 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1501))))
- return False;
- ctr->share.info1501 = info1501;
- }
-
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1501("", &info1501[i], ps, depth))
+ info502[i].info_502_str.ptrs = &info502[i].info_502;
+ if(!srv_io_share_info502_str("", &info502[i].info_502_str, ps, depth))
return False;
}
@@ -1040,10 +659,7 @@ void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
q_n->ctr.info_level = q_n->ctr.switch_value = info_level;
- q_n->ctr.ptr_share_info = 1;
- q_n->ctr.num_entries = 0;
- q_n->ctr.ptr_entries = 0;
- q_n->ctr.num_entries2 = 0;
+ q_n->ctr.ptr_share_info = 0;
q_n->preferred_len = preferred_len;
memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
@@ -1104,36 +720,15 @@ BOOL srv_io_r_net_share_enum(const char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_st
if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
return False;
-
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
-
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
}
/*******************************************************************
- initialises a structure.
-********************************************************************/
-
-BOOL init_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n, const char *srv_name, const char *share_name, uint32 info_level)
-{
-
- uint32 ptr_share_name;
-
- DEBUG(5,("init_srv_q_net_share_get_info\n"));
-
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
- init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name, share_name);
-
- q_n->info_level = info_level;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -1188,24 +783,10 @@ static BOOL srv_io_srv_share_info(const char *desc, prs_struct *ps, int depth, S
if (r_n->ptr_share_ctr != 0) {
switch (r_n->switch_value) {
- case 0:
- if(!srv_io_share_info0("", &r_n->share.info0.info_0, ps, depth))
- return False;
-
- /* allow access to pointers in the str part. */
- r_n->share.info0.info_0_str.ptrs = &r_n->share.info0.info_0;
-
- if(!srv_io_share_info0_str("", &r_n->share.info0.info_0_str, ps, depth))
- return False;
-
- break;
case 1:
if(!srv_io_share_info1("", &r_n->share.info1.info_1, ps, depth))
return False;
- /* allow access to pointers in the str part. */
- r_n->share.info1.info_1_str.ptrs = &r_n->share.info1.info_1;
-
if(!srv_io_share_info1_str("", &r_n->share.info1.info_1_str, ps, depth))
return False;
@@ -1229,40 +810,16 @@ static BOOL srv_io_srv_share_info(const char *desc, prs_struct *ps, int depth, S
if(!srv_io_share_info502("", &r_n->share.info502.info_502, ps, depth))
return False;
- /* allow access to pointers in the str part. */
+ /*allow access to pointers in the str part. */
r_n->share.info502.info_502_str.ptrs = &r_n->share.info502.info_502;
if(!srv_io_share_info502_str("", &r_n->share.info502.info_502_str, ps, depth))
return False;
break;
- case 1004:
- if(!srv_io_share_info1004("", &r_n->share.info1004.info_1004, ps, depth))
- return False;
-
- /* allow access to pointers in the str part. */
- r_n->share.info1004.info_1004_str.ptrs = &r_n->share.info1004.info_1004;
-
- if(!srv_io_share_info1004_str("", &r_n->share.info1004.info_1004_str, ps, depth))
- return False;
- break;
case 1005:
if(!srv_io_share_info1005("", &r_n->share.info1005, ps, depth))
return False;
break;
- case 1006:
- if(!srv_io_share_info1006("", &r_n->share.info1006, ps, depth))
- return False;
- break;
- case 1007:
- if(!srv_io_share_info1007("", &r_n->share.info1007.info_1007, ps, depth))
- return False;
-
- /* allow access to pointers in the str part. */
- r_n->share.info1007.info_1007_str.ptrs = &r_n->share.info1007.info_1007;
-
- if(!srv_io_share_info1007_str("", &r_n->share.info1007.info_1007_str, ps, depth))
- return False;
- break;
case 1501:
if (!srv_io_share_info1501("", &r_n->share.info1501, ps, depth))
return False;
@@ -1304,34 +861,6 @@ BOOL srv_io_r_net_share_get_info(const char *desc, SRV_R_NET_SHARE_GET_INFO *r_n
}
/*******************************************************************
- intialises a structure.
-********************************************************************/
-
-BOOL init_srv_q_net_share_set_info(SRV_Q_NET_SHARE_SET_INFO *q_n,
- const char *srv_name,
- const char *share_name,
- uint32 info_level,
- const SRV_SHARE_INFO *info)
-{
-
- uint32 ptr_share_name;
-
- DEBUG(5,("init_srv_q_net_share_set_info\n"));
-
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
- init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name, share_name);
-
- q_n->info_level = info_level;
-
- q_n->info = *info;
-
- q_n->ptr_parm_error = 1;
- q_n->parm_error = 0;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -1366,15 +895,6 @@ BOOL srv_io_q_net_share_set_info(const char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n
if(!srv_io_srv_share_info("info ", ps, depth, &q_n->info))
return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("ptr_parm_error", ps, depth, &q_n->ptr_parm_error))
- return False;
- if(q_n->ptr_parm_error!=0) {
- if(!prs_uint32("parm_error", ps, depth, &q_n->parm_error))
- return False;
- }
-
return True;
}
@@ -1382,9 +902,9 @@ BOOL srv_io_q_net_share_set_info(const char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n
Reads or writes a structure.
********************************************************************/
-BOOL srv_io_r_net_share_set_info(const char *desc, SRV_R_NET_SHARE_SET_INFO *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_set_info(const char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
+ if (q_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_r_net_share_set_info");
@@ -1393,22 +913,14 @@ BOOL srv_io_r_net_share_set_info(const char *desc, SRV_R_NET_SHARE_SET_INFO *r_n
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_parm_error ", ps, depth, &r_n->ptr_parm_error))
+ if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value))
return False;
-
- if(r_n->ptr_parm_error) {
-
- if(!prs_uint32("parm_error ", ps, depth, &r_n->parm_error))
- return False;
- }
-
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &q_n->status))
return False;
return True;
}
-
/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -1441,44 +953,16 @@ BOOL srv_io_q_net_share_add(const char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_stru
if(!srv_io_srv_share_info("info ", ps, depth, &q_n->info))
return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_err_index", ps, depth, &q_n->ptr_err_index))
- return False;
- if (q_n->ptr_err_index)
- if (!prs_uint32("err_index", ps, depth, &q_n->err_index))
- return False;
-
return True;
}
-void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, const char *srvname,
- const char *netname, uint32 type, const char *remark,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- const char *path, const char *passwd)
-{
- q->ptr_srv_name = 1;
- init_unistr2(&q->uni_srv_name, srvname, UNI_STR_TERMINATE);
- q->info.switch_value = q->info_level = 2;
-
- q->info.ptr_share_ctr = 1;
- init_srv_share_info2(&q->info.share.info2.info_2, netname, type,
- remark, perms, max_uses, num_uses, path, passwd);
- init_srv_share_info2_str(&q->info.share.info2.info_2_str, netname,
- remark, path, passwd);
- q->ptr_err_index = 1;
- q->err_index = 0;
-}
-
-
/*******************************************************************
Reads or writes a structure.
********************************************************************/
-BOOL srv_io_r_net_share_add(const char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_add(const char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
+ if (q_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_r_net_share_add");
@@ -1487,34 +971,15 @@ BOOL srv_io_r_net_share_add(const char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_stru
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_parm_error", ps, depth, &r_n->ptr_parm_error))
+ if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value))
return False;
-
- if(r_n->ptr_parm_error) {
-
- if(!prs_uint32("parm_error", ps, depth, &r_n->parm_error))
- return False;
- }
-
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &q_n->status))
return False;
return True;
}
/*******************************************************************
- initialises a structure.
-********************************************************************/
-
-void init_srv_q_net_share_del(SRV_Q_NET_SHARE_DEL *del, const char *srvname,
- const char *sharename)
-{
- del->ptr_srv_name = 1;
- init_unistr2(&del->uni_srv_name, srvname, UNI_STR_TERMINATE);
- init_unistr2(&del->uni_share_name, sharename, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -1537,11 +1002,6 @@ BOOL srv_io_q_net_share_del(const char *desc, SRV_Q_NET_SHARE_DEL *q_n, prs_stru
if(!smb_io_unistr2("", &q_n->uni_share_name, True, ps, depth))
return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("reserved", ps, depth, &q_n->reserved))
- return False;
-
return True;
}
@@ -1560,7 +1020,7 @@ BOOL srv_io_r_net_share_del(const char *desc, SRV_R_NET_SHARE_DEL *q_n, prs_stru
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &q_n->status))
+ if(!prs_werror("status ", ps, depth, &q_n->status))
return False;
return True;
@@ -1574,7 +1034,7 @@ void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, const char *name)
{
DEBUG(5,("init_srv_sess_info0_str\n"));
- init_unistr2(&ss0->uni_name, name, UNI_STR_TERMINATE);
+ init_unistr2(&ss0->uni_name, name, strlen(name)+1);
}
/*******************************************************************
@@ -1651,8 +1111,8 @@ static BOOL srv_io_srv_sess_info_0(const char *desc, SRV_SESS_INFO_0 *ss0, prs_s
return False;
if (ss0->ptr_sess_info != 0) {
- uint32 i;
- uint32 num_entries = ss0->num_entries_read;
+ int i;
+ int num_entries = ss0->num_entries_read;
if (num_entries > MAX_SESS_ENTRIES) {
num_entries = MAX_SESS_ENTRIES; /* report this! */
@@ -1688,8 +1148,8 @@ void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, const char *name, const char
{
DEBUG(5,("init_srv_sess_info1_str\n"));
- init_unistr2(&ss1->uni_name, name, UNI_STR_TERMINATE);
- init_unistr2(&ss1->uni_user, user, UNI_STR_TERMINATE);
+ init_unistr2(&ss1->uni_name, name, strlen(name)+1);
+ init_unistr2(&ss1->uni_user, name, strlen(user)+1);
}
/*******************************************************************
@@ -1788,8 +1248,8 @@ static BOOL srv_io_srv_sess_info_1(const char *desc, SRV_SESS_INFO_1 *ss1, prs_s
return False;
if (ss1->ptr_sess_info != 0) {
- uint32 i;
- uint32 num_entries = ss1->num_entries_read;
+ int i;
+ int num_entries = ss1->num_entries_read;
if (num_entries > MAX_SESS_ENTRIES) {
num_entries = MAX_SESS_ENTRIES; /* report this! */
@@ -1870,10 +1330,10 @@ static BOOL srv_io_srv_sess_ctr(const char *desc, SRV_SESS_INFO_CTR **pp_ctr, pr
********************************************************************/
void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
- const char *srv_name, const char *qual_name,
- const char *user_name, uint32 sess_level,
- SRV_SESS_INFO_CTR *ctr, uint32 preferred_len,
- ENUM_HND *hnd)
+ const char *srv_name, const char *qual_name,
+ uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
{
q_n->ctr = ctr;
@@ -1881,7 +1341,6 @@ void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
- init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name);
q_n->sess_level = sess_level;
q_n->preferred_len = preferred_len;
@@ -1919,18 +1378,11 @@ BOOL srv_io_q_net_sess_enum(const char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_stru
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
if(!prs_uint32("sess_level", ps, depth, &q_n->sess_level))
return False;
- if (q_n->sess_level != (uint32)-1) {
+ if (q_n->sess_level != -1) {
if(!srv_io_srv_sess_ctr("sess_ctr", &q_n->ctr, ps, depth))
return False;
}
@@ -1962,7 +1414,7 @@ BOOL srv_io_r_net_sess_enum(const char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_stru
if(!prs_uint32("sess_level", ps, depth, &r_n->sess_level))
return False;
- if (r_n->sess_level != (uint32)-1) {
+ if (r_n->sess_level != -1) {
if(!srv_io_srv_sess_ctr("sess_ctr", &r_n->ctr, ps, depth))
return False;
}
@@ -1971,7 +1423,7 @@ BOOL srv_io_r_net_sess_enum(const char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_stru
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2060,8 +1512,8 @@ void init_srv_conn_info1_str(CONN_INFO_1_STR *ss1, const char *usr_name, const c
{
DEBUG(5,("init_srv_conn_info1_str\n"));
- init_unistr2(&ss1->uni_usr_name, usr_name, UNI_STR_TERMINATE);
- init_unistr2(&ss1->uni_net_name, net_name, UNI_STR_TERMINATE);
+ init_unistr2(&ss1->uni_usr_name, usr_name, strlen(usr_name)+1);
+ init_unistr2(&ss1->uni_net_name, net_name, strlen(net_name)+1);
}
/*******************************************************************
@@ -2295,7 +1747,7 @@ BOOL srv_io_q_net_conn_enum(const char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_stru
if(!prs_uint32("conn_level", ps, depth, &q_n->conn_level))
return False;
- if (q_n->conn_level != (uint32)-1) {
+ if (q_n->conn_level != -1) {
if(!srv_io_srv_conn_ctr("conn_ctr", &q_n->ctr, ps, depth))
return False;
}
@@ -2327,7 +1779,7 @@ BOOL srv_io_r_net_conn_enum(const char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_str
if(!prs_uint32("conn_level", ps, depth, &r_n->conn_level))
return False;
- if (r_n->conn_level != (uint32)-1) {
+ if (r_n->conn_level != -1) {
if(!srv_io_srv_conn_ctr("conn_ctr", &r_n->ctr, ps, depth))
return False;
}
@@ -2336,7 +1788,7 @@ BOOL srv_io_r_net_conn_enum(const char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_str
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2350,8 +1802,8 @@ void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, const char *user_name, const
{
DEBUG(5,("init_srv_file_info3_str\n"));
- init_unistr2(&fi3->uni_path_name, path_name, UNI_STR_TERMINATE);
- init_unistr2(&fi3->uni_user_name, user_name, UNI_STR_TERMINATE);
+ init_unistr2(&fi3->uni_path_name, path_name, strlen(path_name)+1);
+ init_unistr2(&fi3->uni_user_name, user_name, strlen(user_name)+1);
}
/*******************************************************************
@@ -2382,8 +1834,8 @@ static BOOL srv_io_file_info3_str(const char *desc, FILE_INFO_3_STR *sh1, prs_st
********************************************************************/
void init_srv_file_info3(FILE_INFO_3 *fl3,
- uint32 id, uint32 perms, uint32 num_locks,
- const char *path_name, const char *user_name)
+ uint32 id, uint32 perms, uint32 num_locks,
+ const char *path_name, const char *user_name)
{
DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name));
@@ -2428,67 +1880,91 @@ static BOOL srv_io_file_info3(const char *desc, FILE_INFO_3 *fl3, prs_struct *ps
Reads or writes a structure.
********************************************************************/
-static BOOL srv_io_srv_file_ctr(const char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL srv_io_srv_file_info_3(const char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
{
- if (ctr == NULL)
+ if (fl3 == NULL)
return False;
- prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
+ prs_debug(ps, depth, desc, "srv_io_file_3_fl3");
depth++;
- if (UNMARSHALLING(ps)) {
- memset(ctr, '\0', sizeof(SRV_FILE_INFO_CTR));
- }
-
if(!prs_align(ps))
return False;
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if (ctr->switch_value != 3) {
- DEBUG(5,("%s File info %d level not supported\n",
- tab_depth(depth), ctr->switch_value));
- }
- if(!prs_uint32("ptr_file_info", ps, depth, &ctr->ptr_file_info))
+ if(!prs_uint32("num_entries_read", ps, depth, &fl3->num_entries_read))
return False;
- if(!prs_uint32("num_entries", ps, depth, &ctr->num_entries))
- return False;
- if(!prs_uint32("ptr_entries", ps, depth, &ctr->ptr_entries))
- return False;
- if (ctr->ptr_entries == 0)
- return True;
- if(!prs_uint32("num_entries2", ps, depth,
- &ctr->num_entries2))
+ if(!prs_uint32("ptr_file_fl3", ps, depth, &fl3->ptr_file_info))
return False;
- switch (ctr->switch_value) {
- case 3: {
- SRV_FILE_INFO_3 *info3 = ctr->file.info3;
- int num_entries = ctr->num_entries;
+ if (fl3->ptr_file_info != 0) {
int i;
+ int num_entries = fl3->num_entries_read;
- if (UNMARSHALLING(ps)) {
- if (!(info3 = (SRV_FILE_INFO_3 *)prs_alloc_mem(ps, num_entries * sizeof(SRV_FILE_INFO_3))))
- return False;
- ctr->file.info3 = info3;
+ if (num_entries > MAX_FILE_ENTRIES) {
+ num_entries = MAX_FILE_ENTRIES; /* report this! */
}
+ if(!prs_uint32("num_entries_read2", ps, depth, &fl3->num_entries_read2))
+ return False;
+
for (i = 0; i < num_entries; i++) {
- if(!srv_io_file_info3("", &ctr->file.info3[i].info_3, ps, depth))
+ if(!srv_io_file_info3("", &fl3->info_3[i], ps, depth))
return False;
}
+
for (i = 0; i < num_entries; i++) {
- if(!srv_io_file_info3_str("", &ctr->file.info3[i].info_3_str, ps, depth))
+ if(!srv_io_file_info3_str("", &fl3->info_3_str[i], ps, depth))
return False;
}
- break;
+
+ if(!prs_align(ps))
+ return False;
}
- default:
- DEBUG(5,("%s no file info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_srv_file_ctr(const char *desc, SRV_FILE_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
+{
+ SRV_FILE_INFO_CTR *ctr = *pp_ctr;
+
+ if (UNMARSHALLING(ps)) {
+ ctr = *pp_ctr = (SRV_FILE_INFO_CTR *)prs_alloc_mem(ps, sizeof(SRV_FILE_INFO_CTR));
+ if (ctr == NULL)
+ return False;
+ }
+
+ if (ctr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+ return False;
+ if(!prs_uint32("ptr_file_ctr", ps, depth, &ctr->ptr_file_ctr))
+ return False;
+
+ if (ctr->ptr_file_ctr != 0) {
+ switch (ctr->switch_value) {
+ case 3:
+ if(!srv_io_srv_file_info_3("", &ctr->file.info3, ps, depth))
+ return False;
+ break;
+ default:
+ DEBUG(5,("%s no file info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
}
-
+
return True;
}
@@ -2497,23 +1973,20 @@ static BOOL srv_io_srv_file_ctr(const char *desc, SRV_FILE_INFO_CTR *ctr, prs_st
********************************************************************/
void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
- const char *srv_name, const char *qual_name,
- const char *user_name,
- uint32 file_level, SRV_FILE_INFO_CTR *ctr,
- uint32 preferred_len,
- ENUM_HND *hnd)
+ const char *srv_name, const char *qual_name,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
{
DEBUG(5,("init_q_net_file_enum\n"));
+ q_n->ctr = ctr;
+
init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
- init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name);
- q_n->file_level = q_n->ctr.switch_value = file_level;
+ q_n->file_level = file_level;
q_n->preferred_len = preferred_len;
- q_n->ctr.ptr_file_info = 1;
- q_n->ctr.num_entries = 0;
- q_n->ctr.num_entries2 = 0;
memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
}
@@ -2549,17 +2022,10 @@ BOOL srv_io_q_net_file_enum(const char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_stru
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
if(!prs_uint32("file_level", ps, depth, &q_n->file_level))
return False;
- if (q_n->file_level != (uint32)-1) {
+ if (q_n->file_level != -1) {
if(!srv_io_srv_file_ctr("file_ctr", &q_n->ctr, ps, depth))
return False;
}
@@ -2600,75 +2066,13 @@ BOOL srv_io_r_net_file_enum(const char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_stru
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
}
/*******************************************************************
- Initialize a net file close request
-********************************************************************/
-void init_srv_q_net_file_close(SRV_Q_NET_FILE_CLOSE *q_n, const char *server,
- uint32 file_id)
-{
- q_n->ptr_srv_name = 1;
- init_unistr2(&q_n->uni_srv_name, server, UNI_STR_TERMINATE);
- q_n->file_id = file_id;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-BOOL srv_io_q_net_file_close(const char *desc, SRV_Q_NET_FILE_CLOSE *q_n,
- prs_struct *ps, int depth)
-{
- if (q_n == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_q_net_file_close");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("file_id", ps, depth, &q_n->file_id))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-BOOL srv_io_r_net_file_close(const char *desc, SRV_R_NET_FILE_CLOSE *q_n,
- prs_struct *ps, int depth)
-{
- if (q_n == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "srv_io_r_net_file_close");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_werror("status", ps, depth, &q_n->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Inits a SRV_INFO_100 structure.
********************************************************************/
@@ -2789,7 +2193,7 @@ void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, const char *name
sv102->disc = disc;
sv102->hidden = hidden;
sv102->announce = announce;
- sv102->ann_delta = ann_delta;
+ sv102->ann_delta =ann_delta;
sv102->licenses = licenses;
init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path);
}
@@ -3034,7 +2438,7 @@ BOOL srv_io_r_net_srv_get_info(const char *desc, SRV_R_NET_SRV_GET_INFO *r_n, pr
if(!srv_io_info_ctr("ctr", r_n->ctr, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -3053,10 +2457,10 @@ BOOL srv_io_r_net_srv_set_info(const char *desc, SRV_R_NET_SRV_SET_INFO *r_n,
if(!prs_align(ps))
return False;
- if(!prs_uint32("switch value ", ps, depth, &r_n->switch_value))
+ if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -3175,38 +2579,13 @@ BOOL srv_io_r_net_remote_tod(const char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_st
if(!srv_io_time_of_day_info("tod", r_n->tod, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_n->status))
+ if(!prs_werror("status ", ps, depth, &r_n->status))
return False;
return True;
}
/*******************************************************************
- initialises a structure.
- ********************************************************************/
-
-BOOL init_srv_q_net_disk_enum(SRV_Q_NET_DISK_ENUM *q_n,
- const char *srv_name,
- uint32 preferred_len,
- ENUM_HND *enum_hnd
- )
-{
-
-
- DEBUG(5,("init_srv_q_net_srv_disk_enum\n"));
-
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
-
- q_n->disk_enum_ctr.level = 0;
- q_n->disk_enum_ctr.disk_info_ptr = 0;
-
- q_n->preferred_len = preferred_len;
- memcpy(&q_n->enum_hnd, enum_hnd, sizeof(*enum_hnd));
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -3256,9 +2635,7 @@ BOOL srv_io_q_net_disk_enum(const char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_stru
BOOL srv_io_r_net_disk_enum(const char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth)
{
-
- unsigned int i;
- uint32 entries_read, entries_read2, entries_read3;
+ int i;
if (r_n == NULL)
return False;
@@ -3266,35 +2643,22 @@ BOOL srv_io_r_net_disk_enum(const char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_stru
prs_debug(ps, depth, desc, "srv_io_r_net_disk_enum");
depth++;
- entries_read = entries_read2 = entries_read3 = r_n->disk_enum_ctr.entries_read;
-
if(!prs_align(ps))
return False;
- if(!prs_uint32("entries_read", ps, depth, &entries_read))
+ if(!prs_uint32("entries_read", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
if(!prs_uint32("ptr_disk_info", ps, depth, &r_n->disk_enum_ctr.disk_info_ptr))
return False;
/*this may be max, unknown, actual?*/
- if(!prs_uint32("max_elements", ps, depth, &entries_read2))
+ if(!prs_uint32("max_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.unknown))
return False;
- if(!prs_uint32("actual_elements", ps, depth, &entries_read3))
- return False;
-
- r_n->disk_enum_ctr.entries_read = entries_read3;
-
- if(UNMARSHALLING(ps)) {
-
- DISK_INFO *dinfo;
-
- if(!(dinfo = (DISK_INFO *)prs_alloc_mem(ps, sizeof(*dinfo) * entries_read3)))
+ if(!prs_uint32("actual_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
- r_n->disk_enum_ctr.disk_info = dinfo;
- }
for(i=0; i < r_n->disk_enum_ctr.entries_read; i++) {
@@ -3321,25 +2685,6 @@ BOOL srv_io_r_net_disk_enum(const char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_stru
}
/*******************************************************************
- initialises a structure.
- ********************************************************************/
-
-BOOL init_srv_q_net_name_validate(SRV_Q_NET_NAME_VALIDATE *q_n, const char *srv_name, const char *share_name, int type)
-{
- uint32 ptr_share_name;
-
- DEBUG(5,("init_srv_q_net_name_validate\n"));
-
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
- init_buf_unistr2(&q_n->uni_name, &ptr_share_name, share_name);
-
- q_n->type = type;
- q_n->flags = 0;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -3563,13 +2908,3 @@ BOOL srv_io_r_net_file_set_secdesc(const char *desc, SRV_R_NET_FILE_SET_SECDESC
return True;
}
-
-/*******************************************************************
- Inits a structure
-********************************************************************/
-
-void init_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_u, const char *server)
-{
- q_u->ptr_srv_name = 1;
- init_unistr2(&q_u->uni_srv_name, server, UNI_STR_TERMINATE);
-}
diff --git a/source/rpc_parse/parse_wks.c b/source/rpc_parse/parse_wks.c
index b6de058652b..a9f2643e964 100644
--- a/source/rpc_parse/parse_wks.c
+++ b/source/rpc_parse/parse_wks.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -22,15 +23,12 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
/*******************************************************************
Init
********************************************************************/
void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
- char *server, uint16 switch_value)
+ const char *server, uint16 switch_value)
{
DEBUG(5,("init_wks_q_query_info\n"));
@@ -74,7 +72,7 @@ BOOL wks_io_q_query_info(const char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps
void init_wks_info_100(WKS_INFO_100 *inf,
uint32 platform_id, uint32 ver_major, uint32 ver_minor,
- char *my_name, char *domain_name)
+ const char *my_name, const char *domain_name)
{
DEBUG(5,("Init WKS_INFO_100: %d\n", __LINE__));
diff --git a/source/rpc_server/srv_dfs.c b/source/rpc_server/srv_dfs.c
index 6c35917e618..6b48a46b466 100644
--- a/source/rpc_server/srv_dfs.c
+++ b/source/rpc_server/srv_dfs.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines for Dfs
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Shirish Kalele 2000,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Shirish Kalele 2000.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,8 +29,9 @@
#define MAX_MSDFS_JUNCTIONS 256
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+extern pstring global_myname;
+
+#ifdef WITH_MSDFS
/**********************************************************************
api_dfs_exist
@@ -157,23 +158,28 @@ static BOOL api_dfs_enum(pipes_struct *p)
/*******************************************************************
\pipe\netdfs commands
********************************************************************/
-static struct api_struct api_netdfs_cmds[] =
+
+struct api_struct api_netdfs_cmds[] =
{
- {"DFS_EXIST", DFS_EXIST, api_dfs_exist },
- {"DFS_ADD", DFS_ADD, api_dfs_add },
- {"DFS_REMOVE", DFS_REMOVE, api_dfs_remove },
- {"DFS_GET_INFO", DFS_GET_INFO, api_dfs_get_info },
- {"DFS_ENUM", DFS_ENUM, api_dfs_enum }
+ {"DFS_EXIST", DFS_EXIST, api_dfs_exist },
+ {"DFS_ADD", DFS_ADD, api_dfs_add },
+ {"DFS_REMOVE", DFS_REMOVE, api_dfs_remove },
+ {"DFS_GET_INFO", DFS_GET_INFO, api_dfs_get_info },
+ {"DFS_ENUM", DFS_ENUM, api_dfs_enum },
+ {NULL, 0, NULL }
};
-void netdfs_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_netdfs_cmds;
- *n_fns = sizeof(api_netdfs_cmds) / sizeof(struct api_struct);
-}
+/*******************************************************************
+receives a netdfs pipe and responds.
+********************************************************************/
-NTSTATUS rpc_dfs_init(void)
+BOOL api_netdfs_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "netdfs", "netdfs", api_netdfs_cmds,
- sizeof(api_netdfs_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_netdfs_rpc", api_netdfs_cmds);
}
+
+#else
+
+ void dfs_dummy(void) {;} /* So some compilers don't complain. */
+
+#endif
diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c
index a3b06bb6e10..f3f495afcf7 100644
--- a/source/rpc_server/srv_dfs_nt.c
+++ b/source/rpc_server/srv_dfs_nt.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines for Dfs
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -21,15 +22,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* This is the implementation of the dfs pipe. */
+/*
+ * This is the implementation of the dfs pipe.
+ */
#include "includes.h"
#include "nterr.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+extern pstring global_myname;
#define MAX_MSDFS_JUNCTIONS 256
+#ifdef WITH_MSDFS
/* This function does not return a WERROR or NTSTATUS code but rather 1 if
dfs exists, or 0 otherwise. */
@@ -44,334 +47,331 @@ uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u)
WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
{
- struct current_user user;
- struct junction_map jn;
- struct referral* old_referral_list = NULL;
- BOOL exists = False;
-
- pstring dfspath, servername, sharename;
- pstring altpath;
-
- get_current_user(&user,p);
-
- if (user.uid != 0) {
- DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
- return WERR_ACCESS_DENIED;
- }
-
- unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
- unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1);
- unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1);
-
- DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n",
- dfspath, servername, sharename));
-
- pstrcpy(altpath, servername);
- pstrcat(altpath, "\\");
- pstrcat(altpath, sharename);
-
- /* The following call can change the cwd. */
- if(get_referred_path(dfspath, &jn, NULL, NULL)) {
- exists = True;
- jn.referral_count += 1;
- old_referral_list = jn.referral_list;
- } else {
- jn.referral_count = 1;
- }
-
- vfs_ChDir(p->conn,p->conn->connectpath);
-
- jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count
- * sizeof(struct referral));
-
- if(jn.referral_list == NULL) {
- DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
- return WERR_DFS_INTERNAL_ERROR;
- }
-
- if(old_referral_list) {
- memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1);
- SAFE_FREE(old_referral_list);
- }
+ struct current_user user;
+ struct junction_map jn;
+ struct referral* old_referral_list = NULL;
+ BOOL exists = False;
+
+ pstring dfspath, servername, sharename;
+ pstring altpath;
+
+ get_current_user(&user,p);
+
+ if (user.uid != 0) {
+ DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
+ unistr2_to_dos(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
+ unistr2_to_dos(servername, &q_u->ServerName, sizeof(servername)-1);
+ unistr2_to_dos(sharename, &q_u->ShareName, sizeof(sharename)-1);
+
+ DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n",
+ dfspath, servername, sharename));
+
+ pstrcpy(altpath, servername);
+ pstrcat(altpath, "\\");
+ pstrcat(altpath, sharename);
+
+ if(get_referred_path(dfspath, &jn, NULL, NULL))
+ {
+ exists = True;
+ jn.referral_count += 1;
+ old_referral_list = jn.referral_list;
+ }
+ else
+ jn.referral_count = 1;
+
+ jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count
+ * sizeof(struct referral));
+
+ if(jn.referral_list == NULL)
+ {
+ DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
+ return WERR_DFS_INTERNAL_ERROR;
+ }
+
+ if(old_referral_list)
+ {
+ memcpy(jn.referral_list, old_referral_list,
+ sizeof(struct referral)*jn.referral_count-1);
+ SAFE_FREE(old_referral_list);
+ }
- jn.referral_list[jn.referral_count-1].proximity = 0;
- jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL;
+ jn.referral_list[jn.referral_count-1].proximity = 0;
+ jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL;
- pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
+ pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
- if(!create_msdfs_link(&jn, exists)) {
- vfs_ChDir(p->conn,p->conn->connectpath);
- return WERR_DFS_CANT_CREATE_JUNCT;
- }
- vfs_ChDir(p->conn,p->conn->connectpath);
+ if(!create_msdfs_link(&jn, exists))
+ return WERR_DFS_CANT_CREATE_JUNCT;
- return WERR_OK;
+ return WERR_OK;
}
WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
DFS_R_DFS_REMOVE *r_u)
{
- struct current_user user;
- struct junction_map jn;
- BOOL found = False;
-
- pstring dfspath, servername, sharename;
- pstring altpath;
-
- get_current_user(&user,p);
-
- if (user.uid != 0) {
- DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
- return WERR_ACCESS_DENIED;
+ struct current_user user;
+ struct junction_map jn;
+ BOOL found = False;
+
+ pstring dfspath, servername, sharename;
+ pstring altpath;
+
+ get_current_user(&user,p);
+
+ if (user.uid != 0) {
+ DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
+ unistr2_to_dos(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
+ if(q_u->ptr_ServerName)
+ unistr2_to_dos(servername, &q_u->ServerName, sizeof(servername)-1);
+
+ if(q_u->ptr_ShareName)
+ unistr2_to_dos(sharename, &q_u->ShareName, sizeof(sharename)-1);
+
+ if(q_u->ptr_ServerName && q_u->ptr_ShareName)
+ {
+ pstrcpy(altpath, servername);
+ pstrcat(altpath, "\\");
+ pstrcat(altpath, sharename);
+ strlower(altpath);
+ }
+
+ DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
+ dfspath, servername, sharename));
+
+ if(!get_referred_path(dfspath, &jn, NULL, NULL))
+ return WERR_DFS_NO_SUCH_VOL;
+
+ /* if no server-share pair given, remove the msdfs link completely */
+ if(!q_u->ptr_ServerName && !q_u->ptr_ShareName)
+ {
+ if(!remove_msdfs_link(&jn))
+ return WERR_DFS_NO_SUCH_VOL;
+ }
+ else
+ {
+ int i=0;
+ /* compare each referral in the list with the one to remove */
+ DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
+ for(i=0;i<jn.referral_count;i++)
+ {
+ pstring refpath;
+ pstrcpy(refpath,jn.referral_list[i].alternate_path);
+ trim_string(refpath, "\\", "\\");
+ DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath));
+ if(strequal(refpath, altpath))
+ {
+ *(jn.referral_list[i].alternate_path)='\0';
+ DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
+ refpath));
+ found = True;
+ }
}
-
- unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
- if(q_u->ptr_ServerName) {
- unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1);
- }
-
- if(q_u->ptr_ShareName) {
- unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1);
- }
-
- if(q_u->ptr_ServerName && q_u->ptr_ShareName) {
- pstrcpy(altpath, servername);
- pstrcat(altpath, "\\");
- pstrcat(altpath, sharename);
- strlower_m(altpath);
- }
-
- DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
- dfspath, servername, sharename));
-
- if(!get_referred_path(dfspath, &jn, NULL, NULL)) {
- return WERR_DFS_NO_SUCH_VOL;
+ if(!found)
+ return WERR_DFS_NO_SUCH_SHARE;
+
+ /* Only one referral, remove it */
+ if(jn.referral_count == 1)
+ {
+ if(!remove_msdfs_link(&jn))
+ return WERR_DFS_NO_SUCH_VOL;
}
-
- /* if no server-share pair given, remove the msdfs link completely */
- if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) {
- if(!remove_msdfs_link(&jn)) {
- vfs_ChDir(p->conn,p->conn->connectpath);
- return WERR_DFS_NO_SUCH_VOL;
- }
- vfs_ChDir(p->conn,p->conn->connectpath);
- } else {
- int i=0;
- /* compare each referral in the list with the one to remove */
- DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
- for(i=0;i<jn.referral_count;i++) {
- pstring refpath;
- pstrcpy(refpath,jn.referral_list[i].alternate_path);
- trim_char(refpath, '\\', '\\');
- DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath));
- if(strequal(refpath, altpath)) {
- *(jn.referral_list[i].alternate_path)='\0';
- DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
- refpath));
- found = True;
- }
- }
-
- if(!found) {
- return WERR_DFS_NO_SUCH_SHARE;
- }
-
- /* Only one referral, remove it */
- if(jn.referral_count == 1) {
- if(!remove_msdfs_link(&jn)) {
- vfs_ChDir(p->conn,p->conn->connectpath);
- return WERR_DFS_NO_SUCH_VOL;
- }
- } else {
- if(!create_msdfs_link(&jn, True)) {
- vfs_ChDir(p->conn,p->conn->connectpath);
- return WERR_DFS_CANT_CREATE_JUNCT;
- }
- }
- vfs_ChDir(p->conn,p->conn->connectpath);
+ else
+ {
+ if(!create_msdfs_link(&jn, True))
+ return WERR_DFS_CANT_CREATE_JUNCT;
}
+ }
- return WERR_OK;
+ return WERR_OK;
}
static BOOL init_reply_dfs_info_1(struct junction_map* j, DFS_INFO_1* dfs1, int num_j)
{
- int i=0;
- for(i=0;i<num_j;i++) {
- pstring str;
- dfs1[i].ptr_entrypath = 1;
- slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
- j[i].service_name, j[i].volume_name);
- DEBUG(5,("init_reply_dfs_info_1: %d) initing entrypath: %s\n",i,str));
- init_unistr2(&dfs1[i].entrypath,str,UNI_STR_TERMINATE);
- }
- return True;
+ int i=0;
+ for(i=0;i<num_j;i++)
+ {
+ pstring str;
+ dfs1[i].ptr_entrypath = 1;
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname,
+ j[i].service_name, j[i].volume_name);
+ DEBUG(5,("init_reply_dfs_info_1: %d) initing entrypath: %s\n",i,str));
+ init_unistr2(&dfs1[i].entrypath,str,strlen(str)+1);
+ }
+ return True;
}
static BOOL init_reply_dfs_info_2(struct junction_map* j, DFS_INFO_2* dfs2, int num_j)
{
- int i=0;
- for(i=0;i<num_j;i++) {
- pstring str;
- dfs2[i].ptr_entrypath = 1;
- slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
- j[i].service_name, j[i].volume_name);
- init_unistr2(&dfs2[i].entrypath, str, UNI_STR_TERMINATE);
- dfs2[i].ptr_comment = 0;
- dfs2[i].state = 1; /* set up state of dfs junction as OK */
- dfs2[i].num_storages = j[i].referral_count;
- }
- return True;
+ int i=0;
+ for(i=0;i<num_j;i++)
+ {
+ pstring str;
+ dfs2[i].ptr_entrypath = 1;
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname,
+ j[i].service_name, j[i].volume_name);
+ init_unistr2(&dfs2[i].entrypath, str, strlen(str)+1);
+ dfs2[i].ptr_comment = 0;
+ dfs2[i].state = 1; /* set up state of dfs junction as OK */
+ dfs2[i].num_storages = j[i].referral_count;
+ }
+ return True;
}
static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_INFO_3* dfs3, int num_j)
{
- int i=0,ii=0;
- for(i=0;i<num_j;i++) {
- pstring str;
- dfs3[i].ptr_entrypath = 1;
- if (j[i].volume_name[0] == '\0')
- slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
- global_myname(), j[i].service_name);
- else
- slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
- j[i].service_name, j[i].volume_name);
-
- init_unistr2(&dfs3[i].entrypath, str, UNI_STR_TERMINATE);
- dfs3[i].ptr_comment = 1;
- init_unistr2(&dfs3[i].comment, "", UNI_STR_TERMINATE);
- dfs3[i].state = 1;
- dfs3[i].num_storages = dfs3[i].num_storage_infos = j[i].referral_count;
- dfs3[i].ptr_storages = 1;
+ int i=0,ii=0;
+ for(i=0;i<num_j;i++)
+ {
+ pstring str;
+ dfs3[i].ptr_entrypath = 1;
+ if (j[i].volume_name[0] == '\0')
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
+ global_myname, j[i].service_name);
+ else
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname,
+ j[i].service_name, j[i].volume_name);
+
+ init_unistr2(&dfs3[i].entrypath, str, strlen(str)+1);
+ dfs3[i].ptr_comment = 1;
+ init_unistr2(&dfs3[i].comment, "", 1);
+ dfs3[i].state = 1;
+ dfs3[i].num_storages = dfs3[i].num_storage_infos = j[i].referral_count;
+ dfs3[i].ptr_storages = 1;
- /* also enumerate the storages */
- dfs3[i].storages = (DFS_STORAGE_INFO*) talloc(ctx, j[i].referral_count *
- sizeof(DFS_STORAGE_INFO));
- if (!dfs3[i].storages)
- return False;
-
- memset(dfs3[i].storages, '\0', j[i].referral_count * sizeof(DFS_STORAGE_INFO));
-
- for(ii=0;ii<j[i].referral_count;ii++) {
- char* p;
- pstring path;
- DFS_STORAGE_INFO* stor = &(dfs3[i].storages[ii]);
- struct referral* ref = &(j[i].referral_list[ii]);
+ /* also enumerate the storages */
+ dfs3[i].storages = (DFS_STORAGE_INFO*) talloc(ctx, j[i].referral_count *
+ sizeof(DFS_STORAGE_INFO));
+ if (!dfs3[i].storages)
+ return False;
+
+ memset(dfs3[i].storages, '\0', j[i].referral_count * sizeof(DFS_STORAGE_INFO));
+
+ for(ii=0;ii<j[i].referral_count;ii++)
+ {
+ char* p;
+ pstring path;
+ DFS_STORAGE_INFO* stor = &(dfs3[i].storages[ii]);
+ struct referral* ref = &(j[i].referral_list[ii]);
- pstrcpy(path, ref->alternate_path);
- trim_char(path,'\\','\0');
- p = strrchr_m(path,'\\');
- if(p==NULL) {
- DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path));
- continue;
- }
- *p = '\0';
- DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1));
- stor->state = 2; /* set all storages as ONLINE */
- init_unistr2(&stor->servername, path, UNI_STR_TERMINATE);
- init_unistr2(&stor->sharename, p+1, UNI_STR_TERMINATE);
- stor->ptr_servername = stor->ptr_sharename = 1;
- }
+ pstrcpy(path, ref->alternate_path);
+ trim_string(path,"\\","");
+ p = strrchr(path,'\\');
+ if(p==NULL)
+ {
+ DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path));
+ continue;
+ }
+ *p = '\0';
+ DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1));
+ stor->state = 2; /* set all storages as ONLINE */
+ init_unistr2(&stor->servername, path, strlen(path)+1);
+ init_unistr2(&stor->sharename, p+1, strlen(p+1)+1);
+ stor->ptr_servername = stor->ptr_sharename = 1;
}
- return True;
+ }
+ return True;
}
static WERROR init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level,
DFS_INFO_CTR* ctr, struct junction_map* jn,
int num_jn)
{
- /* do the levels */
- switch(level) {
- case 1:
- {
- DFS_INFO_1* dfs1;
- dfs1 = (DFS_INFO_1*) talloc(ctx, num_jn * sizeof(DFS_INFO_1));
- if (!dfs1)
- return WERR_NOMEM;
- init_reply_dfs_info_1(jn, dfs1, num_jn);
- ctr->dfs.info1 = dfs1;
- break;
- }
- case 2:
- {
- DFS_INFO_2* dfs2;
- dfs2 = (DFS_INFO_2*) talloc(ctx, num_jn * sizeof(DFS_INFO_2));
- if (!dfs2)
- return WERR_NOMEM;
- init_reply_dfs_info_2(jn, dfs2, num_jn);
- ctr->dfs.info2 = dfs2;
- break;
- }
- case 3:
- {
- DFS_INFO_3* dfs3;
- dfs3 = (DFS_INFO_3*) talloc(ctx, num_jn * sizeof(DFS_INFO_3));
- if (!dfs3)
- return WERR_NOMEM;
- init_reply_dfs_info_3(ctx, jn, dfs3, num_jn);
- ctr->dfs.info3 = dfs3;
- break;
- }
+ /* do the levels */
+ switch(level)
+ {
+ case 1:
+ {
+ DFS_INFO_1* dfs1;
+ dfs1 = (DFS_INFO_1*) talloc(ctx, num_jn * sizeof(DFS_INFO_1));
+ if (!dfs1)
+ return WERR_NOMEM;
+ init_reply_dfs_info_1(jn, dfs1, num_jn);
+ ctr->dfs.info1 = dfs1;
+ break;
+ }
+ case 2:
+ {
+ DFS_INFO_2* dfs2;
+ dfs2 = (DFS_INFO_2*) talloc(ctx, num_jn * sizeof(DFS_INFO_2));
+ if (!dfs2)
+ return WERR_NOMEM;
+ init_reply_dfs_info_2(jn, dfs2, num_jn);
+ ctr->dfs.info2 = dfs2;
+ break;
+ }
+ case 3:
+ {
+ DFS_INFO_3* dfs3;
+ dfs3 = (DFS_INFO_3*) talloc(ctx, num_jn * sizeof(DFS_INFO_3));
+ if (!dfs3)
+ return WERR_NOMEM;
+ init_reply_dfs_info_3(ctx, jn, dfs3, num_jn);
+ ctr->dfs.info3 = dfs3;
+ break;
+ }
default:
return WERR_INVALID_PARAM;
- }
- return WERR_OK;
+ }
+ return WERR_OK;
}
WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
{
- uint32 level = q_u->level;
- struct junction_map jn[MAX_MSDFS_JUNCTIONS];
- int num_jn = 0;
-
- num_jn = enum_msdfs_links(jn);
- vfs_ChDir(p->conn,p->conn->connectpath);
-
- DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
-
- r_u->ptr_buffer = level;
- r_u->level = r_u->level2 = level;
- r_u->ptr_num_entries = r_u->ptr_num_entries2 = 1;
- r_u->num_entries = r_u->num_entries2 = num_jn;
- r_u->reshnd.ptr_hnd = 1;
- r_u->reshnd.handle = num_jn;
+ uint32 level = q_u->level;
+ struct junction_map jn[MAX_MSDFS_JUNCTIONS];
+ int num_jn = 0;
+
+ num_jn = enum_msdfs_links(jn);
- r_u->ctr = (DFS_INFO_CTR*)talloc(p->mem_ctx, sizeof(DFS_INFO_CTR));
- if (!r_u->ctr)
- return WERR_NOMEM;
- ZERO_STRUCTP(r_u->ctr);
- r_u->ctr->switch_value = level;
- r_u->ctr->num_entries = num_jn;
- r_u->ctr->ptr_dfs_ctr = 1;
+ DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
+
+ r_u->ptr_buffer = level;
+ r_u->level = r_u->level2 = level;
+ r_u->ptr_num_entries = r_u->ptr_num_entries2 = 1;
+ r_u->num_entries = r_u->num_entries2 = num_jn;
+ r_u->reshnd.ptr_hnd = 1;
+ r_u->reshnd.handle = num_jn;
- r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, r_u->ctr, jn, num_jn);
+ r_u->ctr = (DFS_INFO_CTR*)talloc(p->mem_ctx, sizeof(DFS_INFO_CTR));
+ if (!r_u->ctr)
+ return WERR_NOMEM;
+ ZERO_STRUCTP(r_u->ctr);
+ r_u->ctr->switch_value = level;
+ r_u->ctr->num_entries = num_jn;
+ r_u->ctr->ptr_dfs_ctr = 1;
+
+ r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, r_u->ctr, jn, num_jn);
- return r_u->status;
+ return r_u->status;
}
WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
DFS_R_DFS_GET_INFO *r_u)
{
- UNISTR2* uni_path = &q_u->uni_path;
- uint32 level = q_u->level;
- int consumedcnt = sizeof(pstring);
- pstring path;
- struct junction_map jn;
-
- unistr2_to_ascii(path, uni_path, sizeof(path)-1);
- if(!create_junction(path, &jn))
- return WERR_DFS_NO_SUCH_SERVER;
+ UNISTR2* uni_path = &q_u->uni_path;
+ uint32 level = q_u->level;
+ pstring path;
+ struct junction_map jn;
+
+ unistr2_to_dos(path, uni_path, sizeof(path)-1);
+ if(!create_junction(path, &jn))
+ return WERR_DFS_NO_SUCH_SERVER;
- /* The following call can change the cwd. */
- if(!get_referred_path(path, &jn, &consumedcnt, NULL) || consumedcnt < strlen(path)) {
- vfs_ChDir(p->conn,p->conn->connectpath);
- return WERR_DFS_NO_SUCH_VOL;
- }
+ if(!get_referred_path(path, &jn, NULL, NULL))
+ return WERR_DFS_NO_SUCH_VOL;
- vfs_ChDir(p->conn,p->conn->connectpath);
- r_u->level = level;
- r_u->ptr_ctr = 1;
- r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1);
+ r_u->level = level;
+ r_u->ptr_ctr = 1;
+ r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1);
- return r_u->status;
+ return r_u->status;
}
+#else
+ void dfs_dummy1(void) {;} /* So some compilers don't complain. */
+#endif
diff --git a/source/rpc_server/srv_echo.c b/source/rpc_server/srv_echo.c
deleted file mode 100644
index c6cfde07c15..00000000000
--- a/source/rpc_server/srv_echo.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines for rpcecho
- * Copyright (C) Tim Potter 2003.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* This is the interface to the rpcecho pipe. */
-
-#include "includes.h"
-#include "nterr.h"
-
-#ifdef DEVELOPER
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-static BOOL api_add_one(pipes_struct *p)
-{
- ECHO_Q_ADD_ONE q_u;
- ECHO_R_ADD_ONE r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!echo_io_q_add_one("", &q_u, data, 0))
- return False;
-
- _echo_add_one(p, &q_u, &r_u);
-
- if(!echo_io_r_add_one("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-static BOOL api_echo_data(pipes_struct *p)
-{
- ECHO_Q_ECHO_DATA q_u;
- ECHO_R_ECHO_DATA r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!echo_io_q_echo_data("", &q_u, data, 0))
- return False;
-
- _echo_data(p, &q_u, &r_u);
-
- if(!echo_io_r_echo_data("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-static BOOL api_source_data(pipes_struct *p)
-{
- ECHO_Q_SOURCE_DATA q_u;
- ECHO_R_SOURCE_DATA r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!echo_io_q_source_data("", &q_u, data, 0))
- return False;
-
- _source_data(p, &q_u, &r_u);
-
- if(!echo_io_r_source_data("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-static BOOL api_sink_data(pipes_struct *p)
-{
- ECHO_Q_SINK_DATA q_u;
- ECHO_R_SINK_DATA r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!echo_io_q_sink_data("", &q_u, data, 0))
- return False;
-
- _sink_data(p, &q_u, &r_u);
-
- if(!echo_io_r_sink_data("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-\pipe\rpcecho commands
-********************************************************************/
-
-struct api_struct api_echo_cmds[] = {
- {"ADD_ONE", ECHO_ADD_ONE, api_add_one },
- {"ECHO_DATA", ECHO_DATA, api_echo_data },
- {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
- {"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
-};
-
-
-void echo_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_echo_cmds;
- *n_fns = sizeof(api_echo_cmds) / sizeof(struct api_struct);
-}
-
-NTSTATUS rpc_echo_init(void)
-{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
- "rpcecho", "rpcecho", api_echo_cmds,
- sizeof(api_echo_cmds) / sizeof(struct api_struct));
-}
-
-#else /* DEVELOPER */
-
-NTSTATUS rpc_echo_init(void)
-{
- return NT_STATUS_OK;
-}
-#endif /* DEVELOPER */
diff --git a/source/rpc_server/srv_echo_nt.c b/source/rpc_server/srv_echo_nt.c
deleted file mode 100644
index ddb76b3a21e..00000000000
--- a/source/rpc_server/srv_echo_nt.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines for rpcecho
- * Copyright (C) Tim Potter 2003.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* This is the interface to the rpcecho pipe. */
-
-#include "includes.h"
-#include "nterr.h"
-
-#ifdef DEVELOPER
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/* Add one to the input and return it */
-
-void _echo_add_one(pipes_struct *p, ECHO_Q_ADD_ONE *q_u, ECHO_R_ADD_ONE *r_u)
-{
- DEBUG(10, ("_echo_add_one\n"));
-
- r_u->response = q_u->request + 1;
-}
-
-/* Echo back an array of data */
-
-void _echo_data(pipes_struct *p, ECHO_Q_ECHO_DATA *q_u,
- ECHO_R_ECHO_DATA *r_u)
-{
- DEBUG(10, ("_echo_data\n"));
-
- r_u->data = talloc(p->mem_ctx, q_u->size);
- r_u->size = q_u->size;
- memcpy(r_u->data, q_u->data, q_u->size);
-}
-
-/* Sink an array of data */
-
-void _sink_data(pipes_struct *p, ECHO_Q_SINK_DATA *q_u,
- ECHO_R_SINK_DATA *r_u)
-{
- DEBUG(10, ("_sink_data\n"));
-
- /* My that was some yummy data! */
-}
-
-/* Source an array of data */
-
-void _source_data(pipes_struct *p, ECHO_Q_SOURCE_DATA *q_u,
- ECHO_R_SOURCE_DATA *r_u)
-{
- uint32 i;
-
- DEBUG(10, ("_source_data\n"));
-
- r_u->data = talloc(p->mem_ctx, q_u->size);
- r_u->size = q_u->size;
-
- for (i = 0; i < r_u->size; i++)
- r_u->data[i] = i & 0xff;
-}
-
-#endif /* DEVELOPER */
diff --git a/source/rpc_server/srv_epmapper.c b/source/rpc_server/srv_epmapper.c
deleted file mode 100644
index 70de092850b..00000000000
--- a/source/rpc_server/srv_epmapper.c
+++ /dev/null
@@ -1,88 +0,0 @@
-
-/*
- Unix SMB/CIFS implementation.
- Samba end point mapper utility and mapping functions
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*****************************************************************
- api_handle_map_req - handles standard epm mapping request
-******************************************************************/
-static BOOL api_handle_map_req(pipes_struct * p)
-{
-
- EPM_Q_MAP q_in;
- EPM_R_MAP q_out;
-
- prs_struct *in_data = &p->in_data.data;
- prs_struct *ret_data = &p->out_data.rdata;
-
- ZERO_STRUCT(q_in);
- ZERO_STRUCT(q_out);
-
- /* process input request and parse packet */
-
- if (!epm_io_q_map("", &q_in, in_data, 0)) {
- DEBUG(0,
- ("api_handle_map_request: unable to unmarshall EPMD_MAP\n"));
- return False;
- }
-
- _epm_map(p, &q_in, &q_out);
-
- if (!epm_io_r_map("", &q_out, ret_data, 0)) {
- DEBUG(0,
- ("api_handle_map_req: unable to marshall EPMD_MAP\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************/
-/* \pipe\epmapper commands */
-/*******************************************************************/
-/* opnum is 3 on map request */
-
-struct api_struct api_epmapper_cmds[] = {
- {"MAP_PIPE_NAME", EPM_MAP_PIPE_NAME, api_handle_map_req},
-};
-
-/*******************************************************************/
-/* */
-/*******************************************************************/
-
-void epm_get_pipe_fns(struct api_struct **funcs, int *n_funcs)
-{
- *funcs = api_epmapper_cmds;
- *n_funcs = sizeof(api_epmapper_cmds) / sizeof(struct api_struct);
-}
-
-/*******************************************************************/
-/* */
-/*******************************************************************/
-
-NTSTATUS rpc_epmapper_init(void)
-{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
- EPM_PIPE_NM, EPM_PIPE_NM,
- api_epmapper_cmds,
- sizeof(api_epmapper_cmds) /
- sizeof(struct api_struct));
-}
diff --git a/source/rpc_server/srv_epmapper_nt.c b/source/rpc_server/srv_epmapper_nt.c
deleted file mode 100644
index e82484af4af..00000000000
--- a/source/rpc_server/srv_epmapper_nt.c
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/*
- Unix SMB/CIFS implementation.
- Samba end point mapper utility and mapping functions
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*******************************************************************/
-/* _epm_map - fill out mapping on input and output structs */
-/*******************************************************************/
-void _epm_map(pipes_struct *ps, const EPM_Q_MAP *q_u, EPM_R_MAP *r_u)
-{
- int i;
- uint8 target_address[] = { 9, 53, 95, 27 };
- EPM_FLOOR *floors = talloc(ps->mem_ctx, sizeof(EPM_FLOOR) *
- q_u->tower->num_floors);
- EPM_TOWER *towers = talloc(ps->mem_ctx,
- sizeof(EPM_TOWER) * MAX_TOWERS);
- EPM_TOWER_ARRAY array;
-
- if (!floors || !towers) {
- DEBUG(0, ("_epm_map: talloc failed!\n"));
- return;
- }
-
- for (i = 0; i < q_u->tower->num_floors; i++) {
- switch (q_u->tower->floors[i].lhs.protocol) {
- case EPM_FLOOR_UUID:
- init_epm_floor_uuid(&floors[i],
- q_u->tower->floors[i].
- lhs.uuid.uuid,
- q_u->tower->floors[i].
- lhs.uuid.version);
- break;
- case EPM_FLOOR_RPC:
- init_epm_floor_rpc(&floors[i]);
- break;
- case EPM_FLOOR_TCP:
- /* for now map all requests to port 135 */
- init_epm_floor_tcp(&floors[i], 135);
- break;
- case EPM_FLOOR_IP:
- init_epm_floor_ip(&floors[i], target_address);
- break;
- }
- }
-
- init_epm_tower(ps->mem_ctx, &towers[0], floors, 5);
- init_epm_tower_array(ps->mem_ctx, &array, towers, 1);
- init_epm_r_map(ps->mem_ctx, r_u, &q_u->term_handle, &array, 1, 0);
-
- return;
-
-}
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 63e74ec8911..ec7fb8f5e1a 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/***************************************************************************
api_lsa_open_policy2
***************************************************************************/
@@ -109,10 +106,8 @@ static BOOL api_lsa_enum_trust_dom(pipes_struct *p)
if(!lsa_io_q_enum_trust_dom("", &q_u, data, 0))
return False;
- /* get required trusted domains information */
r_u.status = _lsa_enum_trust_dom(p, &q_u, &r_u);
- /* prepare the response */
if(!lsa_io_r_enum_trust_dom("", &r_u, rdata, 0))
return False;
@@ -331,6 +326,7 @@ static BOOL api_lsa_priv_get_dispname(pipes_struct *p)
return True;
}
+#if 0
/***************************************************************************
api_lsa_open_secret.
***************************************************************************/
@@ -360,6 +356,7 @@ static BOOL api_lsa_enum_accounts(pipes_struct *p)
return True;
}
+#endif
/***************************************************************************
api_lsa_UNK_GET_CONNUSER
@@ -393,37 +390,6 @@ static BOOL api_lsa_unk_get_connuser(pipes_struct *p)
}
/***************************************************************************
- api_lsa_create_user
- ***************************************************************************/
-
-static BOOL api_lsa_create_account(pipes_struct *p)
-{
- LSA_Q_CREATEACCOUNT q_u;
- LSA_R_CREATEACCOUNT r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_create_account("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_create_account: failed to unmarshall LSA_Q_CREATEACCOUNT.\n"));
- return False;
- }
-
- r_u.status = _lsa_create_account(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_create_account("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_create_account: Failed to marshall LSA_R_CREATEACCOUNT.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
api_lsa_open_user
***************************************************************************/
@@ -454,6 +420,7 @@ static BOOL api_lsa_open_account(pipes_struct *p)
return True;
}
+#if 0
/***************************************************************************
api_lsa_get_privs
***************************************************************************/
@@ -474,7 +441,7 @@ static BOOL api_lsa_enum_privsaccount(pipes_struct *p)
return False;
}
- r_u.status = _lsa_enum_privsaccount(p, rdata, &q_u, &r_u);
+ r_u.status = _lsa_enum_privsaccount(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) {
@@ -484,6 +451,7 @@ static BOOL api_lsa_enum_privsaccount(pipes_struct *p)
return True;
}
+#endif
/***************************************************************************
api_lsa_getsystemaccount
@@ -518,217 +486,37 @@ static BOOL api_lsa_getsystemaccount(pipes_struct *p)
/***************************************************************************
- api_lsa_setsystemaccount
- ***************************************************************************/
-
-static BOOL api_lsa_setsystemaccount(pipes_struct *p)
-{
- LSA_Q_SETSYSTEMACCOUNT q_u;
- LSA_R_SETSYSTEMACCOUNT r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_setsystemaccount("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_setsystemaccount: failed to unmarshall LSA_Q_SETSYSTEMACCOUNT.\n"));
- return False;
- }
-
- r_u.status = _lsa_setsystemaccount(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_setsystemaccount("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_setsystemaccount: Failed to marshall LSA_R_SETSYSTEMACCOUNT.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_addprivs
- ***************************************************************************/
-
-static BOOL api_lsa_addprivs(pipes_struct *p)
-{
- LSA_Q_ADDPRIVS q_u;
- LSA_R_ADDPRIVS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_addprivs("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_addprivs: failed to unmarshall LSA_Q_ADDPRIVS.\n"));
- return False;
- }
-
- r_u.status = _lsa_addprivs(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_addprivs("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_addprivs: Failed to marshall LSA_R_ADDPRIVS.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_removeprivs
- ***************************************************************************/
-
-static BOOL api_lsa_removeprivs(pipes_struct *p)
-{
- LSA_Q_REMOVEPRIVS q_u;
- LSA_R_REMOVEPRIVS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_removeprivs("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_removeprivs: failed to unmarshall LSA_Q_REMOVEPRIVS.\n"));
- return False;
- }
-
- r_u.status = _lsa_removeprivs(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_removeprivs("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_removeprivs: Failed to marshall LSA_R_REMOVEPRIVS.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_query_secobj
- ***************************************************************************/
-
-static BOOL api_lsa_query_secobj(pipes_struct *p)
-{
- LSA_Q_QUERY_SEC_OBJ q_u;
- LSA_R_QUERY_SEC_OBJ r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_query_sec_obj("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_query_secobj: failed to unmarshall LSA_Q_QUERY_SEC_OBJ.\n"));
- return False;
- }
-
- r_u.status = _lsa_query_secobj(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_query_sec_obj("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_query_secobj: Failed to marshall LSA_R_QUERY_SEC_OBJ.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_query_dnsdomainfo
- ***************************************************************************/
-
-static BOOL api_lsa_query_info2(pipes_struct *p)
-{
- LSA_Q_QUERY_INFO2 q_u;
- LSA_R_QUERY_INFO2 r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!lsa_io_q_query_info2("", &q_u, data, 0)) {
- DEBUG(0,("api_lsa_query_info2: failed to unmarshall LSA_Q_QUERY_INFO2.\n"));
- return False;
- }
-
- r_u.status = _lsa_query_info2(p, &q_u, &r_u);
-
- if (!lsa_io_r_query_info2("", &r_u, rdata, 0)) {
- DEBUG(0,("api_lsa_query_info2: failed to marshall LSA_R_QUERY_INFO2.\n"));
- return False;
- }
-
- return True;
-}
-
-
-/***************************************************************************
\PIPE\ntlsa commands
***************************************************************************/
-
+
static struct api_struct api_lsa_cmds[] =
{
- { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
- { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
- { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
- { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
- { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
- { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
- { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
- { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
- { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
+ { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
+ { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
+ { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
+ { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
+ { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
+ { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
+ { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
+ { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
+ { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
{ "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
- { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
- { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser },
- { "LSA_CREATEACCOUNT" , LSA_CREATEACCOUNT , api_lsa_create_account },
- { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
+#if 0
+ { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
+#endif
+ { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser},
+ { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
+#if 0
{ "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
- { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount },
- { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount },
- { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
- { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
- { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
- /* be careful of the adding of new RPC's. See commentrs below about
- ADS DC capabilities */
- { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 }
+#endif
+ { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount},
+ { NULL , 0 , NULL }
};
-static int count_fns(void)
-{
- int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
-
- /*
- * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
- * these calls are always last and that you decrement by the amount of calls
- * to disable.
- */
- if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
- funcs -= 1;
- }
-
- return funcs;
-}
-void lsa_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_lsa_cmds;
- *n_fns = count_fns();
-}
-
-
-NTSTATUS rpc_lsa_init(void)
+/***************************************************************************
+ api_ntLsarpcTNP
+ ***************************************************************************/
+BOOL api_ntlsa_rpc(pipes_struct *p)
{
- int funcs = count_fns();
-
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
- funcs);
+ return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds);
}
diff --git a/source/rpc_server/srv_lsa_ds.c b/source/rpc_server/srv_lsa_ds.c
deleted file mode 100644
index 1e75175c2cd..00000000000
--- a/source/rpc_server/srv_lsa_ds.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2003
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* This is the interface for the registry functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-#if 0 /* disabled */
-/*******************************************************************
- api_reg_open_entry
- ********************************************************************/
-
-static BOOL api_dsrole_get_primary_dominfo(pipes_struct *p)
-{
- DS_Q_GETPRIMDOMINFO q_u;
- DS_R_GETPRIMDOMINFO r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the request */
- if ( !ds_io_q_getprimdominfo("", data, 0, &q_u) )
- return False;
-
- /* construct reply. */
- r_u.status = _dsrole_get_primary_dominfo( p, &q_u, &r_u );
-
- if ( !ds_io_r_getprimdominfo("", rdata, 0, &r_u) )
- return False;
-
- return True;
-}
-#endif
-
-/*******************************************************************
- stub functions for unimplemented RPC
-*******************************************************************/
-
-static BOOL api_dsrole_stub( pipes_struct *p )
-{
- DEBUG(0,("api_dsrole_stub: Hmmm....didn't know this RPC existed...\n"));
-
- return False;
-}
-
-
-/*******************************************************************
- array of \PIPE\lsass (new windows 2000 UUID) operations
-********************************************************************/
-static struct api_struct api_lsa_ds_cmds[] = {
- { "DS_NOP", DS_NOP, api_dsrole_stub }
-
-#if 0 /* disabled due to breakage with viewing domain users and groups
- on a Samba PDC from win2k clients --jerry CIFS 2003 */
- { "DS_GETPRIMDOMINFO", DS_GETPRIMDOMINFO, api_dsrole_get_primary_dominfo }
-#endif
-
-};
-
-void lsa_ds_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_lsa_ds_cmds;
- *n_fns = sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct);
-}
-
-
-NTSTATUS rpc_lsa_ds_init(void)
-{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsa_ds", "lsa_ds", api_lsa_ds_cmds,
- sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct));
-}
diff --git a/source/rpc_server/srv_lsa_ds_nt.c b/source/rpc_server/srv_lsa_ds_nt.c
deleted file mode 100644
index f6e8eed9a97..00000000000
--- a/source/rpc_server/srv_lsa_ds_nt.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 2001.
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/********************************************************************
- Fill in a DS_DOMINFO_CTR structure
- ********************************************************************/
-
-static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **info)
-{
- DSROLE_PRIMARY_DOMAIN_INFO_BASIC *basic;
- const char *netbios_domain;
- fstring dnsdomain;
-
- DEBUG(10,("fill_dsrole_dominfo_basic: enter\n"));
-
- if ( !(basic = talloc_zero(ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC))) ) {
- DEBUG(0,("fill_dsrole_dominfo_basic: FATAL error! talloc_xero() failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- switch ( lp_server_role() ) {
- case ROLE_STANDALONE:
- basic->machine_role = DSROLE_STANDALONE_SRV;
- break;
- case ROLE_DOMAIN_MEMBER:
- basic->machine_role = DSROLE_DOMAIN_MEMBER_SRV;
- break;
- case ROLE_DOMAIN_BDC:
- basic->machine_role = DSROLE_BDC;
- basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
- if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
- basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
- get_mydnsdomname(dnsdomain);
- strlower_m(dnsdomain);
- break;
- case ROLE_DOMAIN_PDC:
- basic->machine_role = DSROLE_PDC;
- basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
- if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
- basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
- get_mydnsdomname(dnsdomain);
- strlower_m(dnsdomain);
- break;
- }
-
- basic->unknown = 0x6173; /* seen on the wire; maybe padding */
-
- /* always set netbios name */
-
- basic->netbios_ptr = 1;
- netbios_domain = get_global_sam_name();
- init_unistr2( &basic->netbios_domain, netbios_domain, UNI_FLAGS_NONE);
-
- basic->dnsname_ptr = 1;
- init_unistr2( &basic->dns_domain, dnsdomain, UNI_FLAGS_NONE);
- basic->forestname_ptr = 1;
- init_unistr2( &basic->forest_domain, dnsdomain, UNI_FLAGS_NONE);
-
-
- /* fill in some additional fields if we are a member of an AD domain */
-
- if ( lp_security() == SEC_ADS ) {
- /* TODO */
- ;;
- }
-
- *info = basic;
-
- return NT_STATUS_OK;
-}
-
-/********************************************************************
- Implement the DsroleGetPrimaryDomainInfo() call
- ********************************************************************/
-
-NTSTATUS _dsrole_get_primary_dominfo(pipes_struct *p, DS_Q_GETPRIMDOMINFO *q_u, DS_R_GETPRIMDOMINFO *r_u)
-{
- NTSTATUS result = NT_STATUS_OK;
- uint32 level = q_u->level;
-
- switch ( level ) {
-
- case DsRolePrimaryDomainInfoBasic:
- r_u->level = DsRolePrimaryDomainInfoBasic;
- r_u->ptr = 1;
- result = fill_dsrole_dominfo_basic( p->mem_ctx, &r_u->info.basic );
- break;
-
- default:
- DEBUG(0,("_dsrole_get_primary_dominfo: Unsupported info level [%d]!\n",
- level));
- result = NT_STATUS_INVALID_LEVEL;
- }
-
- return result;
-}
-
-
-
diff --git a/source/rpc_server/srv_lsa_hnd.c b/source/rpc_server/srv_lsa_hnd.c
index 2ec62e2c57a..59bbc5263fa 100644
--- a/source/rpc_server/srv_lsa_hnd.c
+++ b/source/rpc_server/srv_lsa_hnd.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -22,9 +23,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/* This is the max handles across all instances of a pipe name. */
#ifndef MAX_OPEN_POLS
#define MAX_OPEN_POLS 1024
@@ -47,12 +45,12 @@ static BOOL is_samr_lsa_pipe(const char *pipe_name)
BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
{
- pipes_struct *plist = get_first_internal_pipe();
+ pipes_struct *plist = get_first_pipe();
struct handle_list *hl = NULL;
- for (plist = get_first_internal_pipe(); plist; plist = get_next_internal_pipe(plist)) {
+ for (plist = get_first_pipe(); plist; plist = get_next_pipe(plist)) {
if (strequal( plist->name, pipe_name) ||
- (is_samr_lsa_pipe(plist->name) && is_samr_lsa_pipe(pipe_name))) {
+ (is_samr_lsa_pipe(plist->name) && is_samr_lsa_pipe(pipe_name))) {
if (!plist->pipe_handles) {
pstring msg;
slprintf(msg, sizeof(msg)-1, "init_pipe_handles: NULL pipe_handle pointer in pipe %s",
@@ -89,8 +87,8 @@ BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
p->pipe_handles = hl;
- DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
- (unsigned long)p->pipe_handles->pipe_ref_count, pipe_name ));
+ DEBUG(10,("init_pipe_handles: pipe_handles ref count = %u for pipe %s\n",
+ p->pipe_handles->pipe_ref_count, pipe_name ));
return True;
}
@@ -171,7 +169,6 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *h
dump_data(4, (char *)hnd, sizeof(*hnd));
p->bad_handle_fault_state = True;
-
return NULL;
}
@@ -232,34 +229,7 @@ void close_policy_by_pipe(pipes_struct *p)
p->pipe_handles->count = 0;
SAFE_FREE(p->pipe_handles);
+ p->pipe_handles = NULL;
DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name ));
}
}
-
-/*******************************************************************
-Shall we allow access to this rpc? Currently this function
-implements the 'restrict anonymous' setting by denying access to
-anonymous users if the restrict anonymous level is > 0. Further work
-will be checking a security descriptor to determine whether a user
-token has enough access to access the pipe.
-********************************************************************/
-
-BOOL pipe_access_check(pipes_struct *p)
-{
- /* Don't let anonymous users access this RPC if restrict
- anonymous > 0 */
-
- if (lp_restrict_anonymous() > 0) {
- user_struct *user = get_valid_user_struct(p->vuid);
-
- if (!user) {
- DEBUG(3, ("invalid vuid %d\n", p->vuid));
- return False;
- }
-
- if (user->guest)
- return False;
- }
-
- return True;
-}
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 71ac05e7389..c216b6ddf89 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -1,13 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Rafal Szczesniak 2002,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
- * Copyright (C) Simo Sorce 2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,21 +26,21 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+extern DOM_SID global_sam_sid;
+extern fstring global_myworkgroup;
+extern pstring global_myname;
-extern PRIVS privs[];
-
-struct lsa_info {
- DOM_SID sid;
- uint32 access;
+static PRIVS privs[] = {
+ {SE_PRIV_NONE, "no_privs", "No privilege"},
+ {SE_PRIV_ADD_USERS, "add_users", "add users"},
+ {SE_PRIV_ADD_MACHINES, "add_computers", "add computers to domain"},
+ {SE_PRIV_PRINT_OPERATOR, "print_op", "printer operator"},
+ {SE_PRIV_ALL, "all_privs", "all privileges"}
};
-struct generic_mapping lsa_generic_mapping = {
- POLICY_READ,
- POLICY_WRITE,
- POLICY_EXECUTE,
- POLICY_ALL_ACCESS
+struct lsa_info {
+ DOM_SID sid;
+ uint32 access;
};
/*******************************************************************
@@ -60,14 +58,9 @@ static void free_lsa_info(void *ptr)
Init dom_query
***************************************************************************/
-static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid)
+static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
{
- d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */
- d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */
-
- /* this string is supposed to be non-null terminated. */
- /* But the maxlen in this UNISTR2 must include the terminating null. */
- init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL);
+ int domlen = (dom_name != NULL) ? strlen(dom_name) : 0;
/*
* I'm not sure why this really odd combination of length
@@ -77,15 +70,14 @@ static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_si
* a domain with both odd and even length names... JRA.
*/
- /*
- * IMPORTANT NOTE !!!!
- * The two fields below probably are reversed in meaning, ie.
- * the first field is probably the str_len, the second the max
- * len. Both are measured in bytes anyway.
- */
+ d_q->uni_dom_str_len = domlen ? ((domlen + 1) * 2) : 0;
+ d_q->uni_dom_max_len = domlen * 2;
+ d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
+ d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
- d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2;
- d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2;
+ /* this string is supposed to be character short */
+ init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
+ d_q->uni_domain_name.uni_max_len++;
if (dom_sid != NULL)
init_dom_sid2(&d_q->dom_sid, dom_sid);
@@ -98,11 +90,12 @@ static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_si
static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
{
int num = 0;
+ int len;
if (dom_name != NULL) {
for (num = 0; num < ref->num_ref_doms_1; num++) {
fstring domname;
- rpcstr_pull(domname, &ref->ref_dom[num].uni_dom_name, sizeof(domname), -1, 0);
+ fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
if (strequal(domname, dom_name))
return num;
}
@@ -120,11 +113,14 @@ static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
ref->max_entries = MAX_REF_DOMAINS;
ref->num_ref_doms_2 = num+1;
- ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
+ len = (dom_name != NULL) ? strlen(dom_name) : 0;
+ if(dom_name != NULL && len == 0)
+ len = 1;
- init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
- init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
+ init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
+ ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
+ init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
return num;
@@ -144,8 +140,6 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
- become_root(); /* lookup_name can require root privs */
-
for (i = 0; i < num_entries; i++) {
BOOL status = False;
DOM_SID sid;
@@ -157,44 +151,32 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
/* Split name into domain and user component */
- unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
+ pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
+ dos_to_unix(full_name); /* full name should be in unix charset. */
split_domain_name(full_name, dom_name, user);
/* Lookup name */
DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
- status = lookup_name(dom_name, user, &sid, &name_type);
-
- if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) {
- DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
- fstrcpy(dom_name, lp_workgroup());
- status = lookup_name(dom_name, user, &sid, &name_type);
- }
-
- if (name_type == SID_NAME_WKN_GRP) {
- /* BUILTIN aliases are still aliases :-) */
- name_type = SID_NAME_ALIAS;
- }
+ status = lookup_name(full_name, &sid, &name_type);
DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
"not found"));
- if (status && name_type != SID_NAME_UNKNOWN) {
+ if (status) {
sid_split_rid(&sid, &rid);
dom_idx = init_dom_ref(ref, dom_name, &sid);
(*mapped_count)++;
} else {
dom_idx = -1;
- rid = 0;
+ rid = 0xffffffff;
name_type = SID_NAME_UNKNOWN;
}
init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
total++;
}
-
- unbecome_root();
}
/***************************************************************************
@@ -214,6 +196,11 @@ static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
r_l->dom_rid = rid2;
r_l->mapped_count = mapped_count;
+
+ if (mapped_count == 0)
+ r_l->status = NT_STATUS_NONE_MAPPED;
+ else
+ r_l->status = NT_STATUS_OK;
}
/***************************************************************************
@@ -244,8 +231,6 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
}
}
- become_root(); /* Need root to get to passdb to for local sids */
-
for (i = 0; i < num_entries; i++) {
BOOL status = False;
DOM_SID find_sid = sid[i].sid;
@@ -259,6 +244,9 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
/* Lookup sid from winbindd */
+ memset(dom_name, '\0', sizeof(dom_name));
+ memset(name, '\0', sizeof(name));
+
status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" :
@@ -266,32 +254,31 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
if (!status) {
sid_name_use = SID_NAME_UNKNOWN;
- memset(dom_name, '\0', sizeof(dom_name));
- sid_to_string(name, &find_sid);
- dom_idx = -1;
-
- DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
- "referenced list.\n", name ));
- } else {
- (*mapped_count)++;
- /* Store domain sid in ref array */
- if (find_sid.num_auths == 5) {
- sid_split_rid(&find_sid, &rid);
- }
- dom_idx = init_dom_ref(ref, dom_name, &find_sid);
+ }
- DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
- "referenced list.\n", dom_name, name ));
+ /* Store domain sid in ref array */
+ if (find_sid.num_auths == 5) {
+ sid_split_rid(&find_sid, &rid);
}
+ /* unistr routines take dos codepage strings */
+
+ unix_to_dos(dom_name);
+ unix_to_dos(name);
+
+ dom_idx = init_dom_ref(ref, dom_name, &find_sid);
+
+ DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
+ "referenced list.\n", dom_name, name ));
+
+ (*mapped_count)++;
+
init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
sid_name_use, name, dom_idx);
total++;
}
- unbecome_root();
-
trn->num_entries = total;
trn->ptr_trans_names = 1;
trn->num_entries2 = total;
@@ -309,80 +296,11 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
r_l->dom_ref = ref;
r_l->names = names;
r_l->mapped_count = mapped_count;
-}
-
-static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
-{
- extern DOM_SID global_sid_World;
- extern DOM_SID global_sid_Builtin;
- DOM_SID local_adm_sid;
- DOM_SID adm_sid;
-
- SEC_ACE ace[3];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- init_sec_access(&mask, POLICY_EXECUTE);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- sid_copy(&adm_sid, get_global_sam_sid());
- sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
- init_sec_access(&mask, POLICY_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- sid_copy(&local_adm_sid, &global_sid_Builtin);
- sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
- init_sec_access(&mask, POLICY_ALL_ACCESS);
- init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Init_dns_dom_info.
-***************************************************************************/
-
-static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
- const char *dns_name, const char *forest_name,
- struct uuid *dom_guid, DOM_SID *dom_sid)
-{
- if (nb_name && *nb_name) {
- init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
- init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
- r_l->hdr_nb_dom_name.uni_max_len += 2;
- r_l->uni_nb_dom_name.uni_max_len += 1;
- }
-
- if (dns_name && *dns_name) {
- init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
- init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
- r_l->hdr_dns_dom_name.uni_max_len += 2;
- r_l->uni_dns_dom_name.uni_max_len += 1;
- }
-
- if (forest_name && *forest_name) {
- init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
- init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
- r_l->hdr_forest_name.uni_max_len += 2;
- r_l->uni_forest_name.uni_max_len += 1;
- }
- /* how do we init the guid ? probably should write an init fn */
- if (dom_guid) {
- memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid));
- }
-
- if (dom_sid) {
- r_l->ptr_dom_sid = 1;
- init_dom_sid2(&r_l->dom_sid, dom_sid);
- }
+ if (mapped_count == 0)
+ r_l->status = NT_STATUS_NONE_MAPPED;
+ else
+ r_l->status = NT_STATUS_OK;
}
/***************************************************************************
@@ -391,44 +309,10 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
{
- struct lsa_info *info;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- uint32 des_access=q_u->des_access;
- uint32 acc_granted;
- NTSTATUS status;
-
-
- /* map the generic bits to the lsa policy ones */
- se_map_generic(&des_access, &lsa_generic_mapping);
-
- /* get the generic lsa policy SD until we store it */
- lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
-
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
- if (geteuid() != 0) {
- return status;
- }
- DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
- acc_granted, des_access));
- DEBUGADD(4,("but overwritten by euid == 0\n"));
- }
-
- /* This is needed for lsa_open_account and rpcclient .... :-) */
-
- if (geteuid() == 0)
- acc_granted = POLICY_ALL_ACCESS;
-
- /* associate the domain SID with the (unique) handle. */
- if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
- sid_copy(&info->sid,get_global_sam_sid());
- info->access = acc_granted;
+ /* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* set up the LSA QUERY INFO response */
- if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, &r_u->pol, NULL, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return NT_STATUS_OK;
@@ -440,40 +324,10 @@ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL
NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
{
- struct lsa_info *info;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- uint32 des_access=q_u->des_access;
- uint32 acc_granted;
- NTSTATUS status;
-
-
- /* map the generic bits to the lsa policy ones */
- se_map_generic(&des_access, &lsa_generic_mapping);
-
- /* get the generic lsa policy SD until we store it */
- lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
-
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
- if (geteuid() != 0) {
- return status;
- }
- DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
- acc_granted, des_access));
- DEBUGADD(4,("but overwritten by euid == 0\n"));
- acc_granted = des_access;
- }
-
- /* associate the domain SID with the (unique) handle. */
- if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
- sid_copy(&info->sid,get_global_sam_sid());
- info->access = acc_granted;
+ /* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* set up the LSA QUERY INFO response */
- if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, &r_u->pol, NULL, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return NT_STATUS_OK;
@@ -481,44 +335,20 @@ NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *
/***************************************************************************
_lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
- ufff, done :) mimir
***************************************************************************/
NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u)
{
- struct lsa_info *info;
- uint32 enum_context = q_u->enum_context;
-
- /*
- * preferred length is set to 5 as a "our" preferred length
- * nt sets this parameter to 2
- * update (20.08.2002): it's not preferred length, but preferred size!
- * it needs further investigation how to optimally choose this value
- */
- uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10;
- TRUSTDOM **trust_doms;
- uint32 num_domains;
- NTSTATUS nt_status;
+ uint32 enum_context = 0;
+ char *dom_name = NULL;
+ DOM_SID *dom_sid = NULL;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
- if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms);
-
- if (!NT_STATUS_IS_OK(nt_status) &&
- !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) &&
- !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
- return nt_status;
- } else {
- r_u->status = nt_status;
- }
-
- /* set up the lsa_enum_trust_dom response */
- init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms);
+ /* set up the LSA QUERY INFO response */
+ init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, dom_name, dom_sid,
+ dom_name != NULL ? NT_STATUS_OK : NT_STATUS_NO_MORE_ENTRIES);
return r_u->status;
}
@@ -529,57 +359,57 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
{
- struct lsa_info *handle;
LSA_INFO_UNION *info = &r_u->dom;
DOM_SID domain_sid;
- const char *name;
+ fstring dos_domain;
+ fstring dos_myname;
+ char *name = NULL;
DOM_SID *sid = NULL;
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
+ fstrcpy(dos_myname, global_myname);
+ unix_to_dos(dos_myname);
+
+ fstrcpy(dos_domain, global_myworkgroup);
+ unix_to_dos(dos_domain);
+
switch (q_u->info_class) {
case 0x02:
{
- unsigned int i;
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- /* fake info: We audit everything. ;) */
- info->id2.auditing_enabled = 1;
- info->id2.count1 = 7;
- info->id2.count2 = 7;
- if ((info->id2.auditsettings = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL)
- return NT_STATUS_NO_MEMORY;
- for (i = 0; i < 7; i++)
- info->id2.auditsettings[i] = 3;
- break;
+ unsigned int i;
+ /* fake info: We audit everything. ;) */
+ info->id2.auditing_enabled = 1;
+ info->id2.count1 = 7;
+ info->id2.count2 = 7;
+ if ((info->id2.auditsettings = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL)
+ return NT_STATUS_NO_MEMORY;
+ for (i = 0; i < 7; i++)
+ info->id2.auditsettings[i] = 3;
+ break;
}
case 0x03:
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
/* Request PolicyPrimaryDomainInformation. */
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
- name = get_global_sam_name();
- sid = get_global_sam_sid();
+ name = dos_domain;
+ sid = &global_sam_sid;
break;
case ROLE_DOMAIN_MEMBER:
- name = lp_workgroup();
+ name = dos_domain;
/* We need to return the Domain SID here. */
- if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
+ if (secrets_fetch_domain_sid(dos_domain,
+ &domain_sid))
sid = &domain_sid;
else
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
break;
case ROLE_STANDALONE:
- name = lp_workgroup();
+ name = dos_domain;
sid = NULL;
break;
default:
@@ -588,20 +418,27 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF
init_dom_query(&r_u->dom.id3, name, sid);
break;
case 0x05:
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
/* Request PolicyAccountDomainInformation. */
- name = get_global_sam_name();
- sid = get_global_sam_sid();
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ name = dos_domain;
+ sid = &global_sam_sid;
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ name = dos_myname;
+ sid = &global_sam_sid;
+ break;
+ case ROLE_STANDALONE:
+ name = dos_myname;
+ sid = &global_sam_sid;
+ break;
+ default:
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
init_dom_query(&r_u->dom.id5, name, sid);
break;
case 0x06:
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
switch (lp_server_role()) {
case ROLE_DOMAIN_BDC:
/*
@@ -639,44 +476,23 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF
NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u)
{
- struct lsa_info *handle;
DOM_SID2 *sid = q_u->sids.sid;
int num_entries = q_u->sids.num_entries;
DOM_R_REF *ref = NULL;
LSA_TRANS_NAME_ENUM *names = NULL;
uint32 mapped_count = 0;
- if (num_entries > MAX_LOOKUP_SIDS) {
- num_entries = MAX_LOOKUP_SIDS;
- DEBUG(5,("_lsa_lookup_sids: truncating SID lookup list to %d\n", num_entries));
- }
-
ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF));
names = (LSA_TRANS_NAME_ENUM *)talloc_zero(p->mem_ctx, sizeof(LSA_TRANS_NAME_ENUM));
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
r_u->status = NT_STATUS_INVALID_HANDLE;
- goto done;
- }
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_LOOKUP_NAMES)) {
- r_u->status = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
- if (!ref || !names)
- return NT_STATUS_NO_MEMORY;
-
-done:
+ if ((!ref || !names) && NT_STATUS_IS_OK(r_u->status))
+ r_u->status = NT_STATUS_NO_MEMORY;
/* set up the LSA Lookup SIDs response */
init_lsa_trans_names(p->mem_ctx, ref, names, num_entries, sid, &mapped_count);
- if (mapped_count == 0)
- r_u->status = NT_STATUS_NONE_MAPPED;
- else if (mapped_count != num_entries)
- r_u->status = STATUS_SOME_UNMAPPED;
- else
- r_u->status = NT_STATUS_OK;
init_reply_lookup_sids(r_u, ref, names, mapped_count);
return r_u->status;
@@ -688,45 +504,23 @@ lsa_reply_lookup_names
NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
{
- struct lsa_info *handle;
UNISTR2 *names = q_u->uni_name;
int num_entries = q_u->num_entries;
DOM_R_REF *ref;
DOM_RID2 *rids;
uint32 mapped_count = 0;
- if (num_entries > MAX_LOOKUP_SIDS) {
- num_entries = MAX_LOOKUP_SIDS;
- DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
- }
-
ref = (DOM_R_REF *)talloc_zero(p->mem_ctx, sizeof(DOM_R_REF));
- rids = (DOM_RID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_RID2)*num_entries);
+ rids = (DOM_RID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_RID2)*MAX_LOOKUP_SIDS);
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
r_u->status = NT_STATUS_INVALID_HANDLE;
- goto done;
- }
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_LOOKUP_NAMES)) {
- r_u->status = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
-
- if (!ref || !rids)
- return NT_STATUS_NO_MEMORY;
-
-done:
+ if ((!ref || !rids) && NT_STATUS_IS_OK(r_u->status))
+ r_u->status = NT_STATUS_NO_MEMORY;
/* set up the LSA Lookup RIDs response */
init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
- if (mapped_count == 0)
- r_u->status = NT_STATUS_NONE_MAPPED;
- else if (mapped_count != num_entries)
- r_u->status = STATUS_SOME_UNMAPPED;
- else
- r_u->status = NT_STATUS_OK;
init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
return r_u->status;
@@ -760,51 +554,31 @@ _lsa_enum_privs.
NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
{
- struct lsa_info *handle;
uint32 i;
- uint32 enum_context = q_u->enum_context;
+ uint32 enum_context=q_u->enum_context;
LSA_PRIV_ENTRY *entry;
- LSA_PRIV_ENTRY *entries = NULL;
-
- if (enum_context >= PRIV_ALL_INDEX-1)
- return NT_STATUS_NO_MORE_ENTRIES;
+ LSA_PRIV_ENTRY *entries;
- entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX + 1));
- if (entries == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ if (enum_context >= PRIV_ALL_INDEX)
+ return NT_STATUS_UNABLE_TO_FREE_VM;
- /*
- * I don't know if it's the right one. not documented.
- */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
+ entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX-enum_context));
+ if (entries==NULL)
+ return NT_STATUS_NO_MEMORY;
entry = entries;
-
- DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context, PRIV_ALL_INDEX));
-
- for (i = 0; i < PRIV_ALL_INDEX - 1; i++, entry++) {
- if( i < enum_context) {
- init_unistr2(&entry->name, NULL, UNI_FLAGS_NONE);
- init_uni_hdr(&entry->hdr_name, &entry->name);
- entry->luid_low = 0;
- entry->luid_high = 0;
- } else {
- init_unistr2(&entry->name, privs[i].priv, UNI_FLAGS_NONE);
- init_uni_hdr(&entry->hdr_name, &entry->name);
- entry->luid_low = privs[i].se_priv;
- entry->luid_high = 0;
- }
+ for (i = 0; i < PRIV_ALL_INDEX-enum_context; i++, entry++) {
+ init_uni_hdr(&entry->hdr_name, strlen(privs[i+1-enum_context].priv));
+ init_unistr2(&entry->name, privs[i+1-enum_context].priv, strlen(privs[i+1-enum_context].priv) );
+ entry->luid_low = privs[i+1-enum_context].se_priv;
+ entry->luid_high = 1;
}
- enum_context = PRIV_ALL_INDEX - 1;
- init_lsa_r_enum_privs(r_u, enum_context, PRIV_ALL_INDEX - 1, entries);
+ init_lsa_r_enum_privs(r_u, i+enum_context, PRIV_ALL_INDEX-enum_context, entries);
return NT_STATUS_OK;
}
@@ -815,192 +589,79 @@ _lsa_priv_get_dispname.
NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
{
- struct lsa_info *handle;
fstring name_asc;
- int i = 0;
-
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
- return NT_STATUS_INVALID_HANDLE;
-
- /* check if the user have enough rights */
-
- /*
- * I don't know if it's the right one. not documented.
- */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
-
- DEBUG(10,("_lsa_priv_get_dispname: %s\n", name_asc));
-
- while (privs[i].se_priv != SE_ALL_PRIVS && StrCaseCmp(name_asc, privs[i].priv))
- i++;
-
- if (privs[i].se_priv != SE_ALL_PRIVS) {
- DEBUG(10,(": %s\n", privs[i].description));
- init_unistr2(&r_u->desc, privs[i].description, UNI_FLAGS_NONE);
- init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
-
- r_u->ptr_info = 0xdeadbeef;
- r_u->lang_id = q_u->lang_id;
- return NT_STATUS_OK;
- } else {
- DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
- r_u->ptr_info = 0;
- return NT_STATUS_NO_SUCH_PRIVILEGE;
- }
-}
-
-/***************************************************************************
-_lsa_enum_accounts.
- ***************************************************************************/
-
-NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
-{
- struct lsa_info *handle;
- DOM_SID *sid_list;
- int i, j, num_entries;
- LSA_SID_ENUM *sids=&r_u->sids;
- NTSTATUS ret;
+ fstring desc_asc;
+ int i;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- sid_list = NULL;
- num_entries = 0;
-
- /* The only way we can currently find out all the SIDs that have been
- privileged is to scan all privileges */
-
- if (!NT_STATUS_IS_OK(ret = pdb_lsa_enumerate_accounts(&sid_list, &num_entries))) {
- return ret;
- }
-
- if (q_u->enum_context >= num_entries)
- return NT_STATUS_NO_MORE_ENTRIES;
-
- sids->ptr_sid = (uint32 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(uint32));
- sids->sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(DOM_SID2));
+ unistr2_to_dos(name_asc, &q_u->name, sizeof(name_asc));
- if (sids->ptr_sid==NULL || sids->sid==NULL) {
- SAFE_FREE(sid_list);
- return NT_STATUS_NO_MEMORY;
- }
+ DEBUG(0,("_lsa_priv_get_dispname: %s", name_asc));
- for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
- init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
- (*sids).ptr_sid[j] = 1;
+ for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) {
+ if ( strcmp(name_asc, privs[i].priv)) {
+
+ fstrcpy(desc_asc, privs[i].description);
+
+ }
}
+ DEBUG(0,(": %s\n", desc_asc));
- SAFE_FREE(sid_list);
+ init_uni_hdr(&r_u->hdr_desc, strlen(desc_asc));
+ init_unistr2(&r_u->desc, desc_asc, strlen(desc_asc) );
- init_lsa_r_enum_accounts(r_u, num_entries);
+ r_u->ptr_info=0xdeadbeef;
+ r_u->lang_id=q_u->lang_id;
return NT_STATUS_OK;
}
-
NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
{
- fstring username, domname;
- user_struct *vuser = get_valid_user_struct(p->vuid);
+ fstring username, domname;
+ int ulen, dlen;
+ user_struct *vuser = get_valid_user_struct(p->vuid);
- if (vuser == NULL)
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ if (vuser == NULL)
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- fstrcpy(username, vuser->user.smb_name);
- fstrcpy(domname, vuser->user.domain);
+ fstrcpy(username, vuser->user.smb_name);
+ fstrcpy(domname, vuser->user.domain);
- r_u->ptr_user_name = 1;
- init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
- init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
-
- r_u->unk1 = 1;
+ ulen = strlen(username) + 1;
+ dlen = strlen(domname) + 1;
- r_u->ptr_dom_name = 1;
- init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE);
- init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
+ init_uni_hdr(&r_u->hdr_user_name, ulen);
+ r_u->ptr_user_name = 1;
+ init_unistr2(&r_u->uni2_user_name, username, ulen);
- r_u->status = NT_STATUS_OK;
+ r_u->unk1 = 1;
- return r_u->status;
-}
-
-/***************************************************************************
- Lsa Create Account
- ***************************************************************************/
-
-NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
-{
- struct lsa_info *handle;
- struct lsa_info *info;
- NTSTATUS ret;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
- return NT_STATUS_INVALID_HANDLE;
-
- /* check if the user have enough rights */
+ init_uni_hdr(&r_u->hdr_dom_name, dlen);
+ r_u->ptr_dom_name = 1;
+ init_unistr2(&r_u->uni2_dom_name, domname, dlen);
- /*
- * I don't know if it's the right one. not documented.
- * but guessed with rpcclient.
- */
- if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- /* associate the user/group SID with the (unique) handle. */
- if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
- info->sid = q_u->sid.sid;
- info->access = q_u->access;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- if (!NT_STATUS_IS_OK(ret = pdb_lsa_create_account(&info->sid)))
- return ret;
-
- return NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
+
+ return r_u->status;
}
-
/***************************************************************************
- Lsa Open Account
+
***************************************************************************/
NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
{
- struct lsa_info *handle;
struct lsa_info *info;
- fstring name, dom_name;
- enum SID_NAME_USE type;
+
+ r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
-
- /*
- * I don't know if it's the right one. not documented.
- * but guessed with rpcclient.
- */
- if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- /* TODO: Fis the parsing routine before reenabling this check! */
- #if 0
- if (!lookup_sid(&handle->sid, dom_name, name, &type))
- return NT_STATUS_ACCESS_DENIED;
- #endif
/* associate the user/group SID with the (unique) handle. */
if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -1013,40 +674,7 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- For a given SID, enumerate all the privilege this account has.
- ***************************************************************************/
-
-NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
-{
- struct lsa_info *info=NULL;
- PRIVILEGE_SET *priv;
- NTSTATUS ret;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- init_privilege(&priv);
-
- become_root();
-
- if (!NT_STATUS_IS_OK(ret = pdb_get_privilege_set(&info->sid, 1, priv))) {
- /* This is probably wrong... */
- unbecome_root();
- return ret;
- }
- unbecome_root();
-
- DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", priv->count));
-
- init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, priv->set, priv->count, 0);
- destroy_privilege(&priv);
-
- return NT_STATUS_OK;
+ return r_u->status;
}
/***************************************************************************
@@ -1055,231 +683,13 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
{
- struct lsa_info *info=NULL;
r_u->status = NT_STATUS_OK;
- fstring name, dom_name;
- enum SID_NAME_USE type;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!lookup_sid(&info->sid, dom_name, name, &type))
- return NT_STATUS_ACCESS_DENIED;
-
- /*
- 0x01 -> Log on locally
- 0x02 -> Access this computer from network
- 0x04 -> Log on as a batch job
- 0x10 -> Log on as a service
-
- they can be ORed together
- */
-
- r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
-
- return r_u->status;
-}
-
-/***************************************************************************
- update the systemaccount information
- ***************************************************************************/
-
-NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
-{
- struct lsa_info *info=NULL;
- GROUP_MAP map;
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!pdb_getgrsid(&map, info->sid))
- return NT_STATUS_NO_SUCH_GROUP;
-
- if(!pdb_update_group_mapping_entry(&map))
- return NT_STATUS_NO_SUCH_GROUP;
-
- return r_u->status;
-}
-
-/***************************************************************************
- For a given SID, add some privileges.
- ***************************************************************************/
-
-NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
-{
- struct lsa_info *info = NULL;
- int i = 0;
- PRIVILEGE_SET *set = NULL;
- NTSTATUS ret;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- set = q_u->set;
-
- for (i = 0; i < set->count; i++) {
- fstring privname;
-
- /* if the privilege exist */
- if (luid_to_privilege_name(&(set->set[i].luid), privname)) {
- /* then add it */
- DEBUG(10, ("_lsa_addprivs: Adding privilege [%s]\n", privname));
- if (!NT_STATUS_IS_OK(ret = pdb_add_privilege_to_sid(privname, &info->sid)))
- return ret;
- }
- }
-
- r_u->status = NT_STATUS_OK;
-
- return r_u->status;
-}
-
-/***************************************************************************
- For a given SID, remove some privileges.
- ***************************************************************************/
-
-NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
-{
- struct lsa_info *info = NULL;
- int i = 0;
- PRIVILEGE_SET *set = NULL;
- NTSTATUS ret;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- set = q_u->set;
-
- for (i = 0; i < set->count; i++) {
- fstring privname;
-
- /* if the privilege exist */
- if (luid_to_privilege_name(&(set->set[i].luid), privname)) {
- /* then remove it */
- DEBUG(10, ("_lsa_removeprivs: Removing privilege [%s]\n", privname));
- if (!NT_STATUS_IS_OK(ret = pdb_remove_privilege_from_sid(privname, &info->sid)))
- return ret;
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- For a given SID, remove some privileges.
- ***************************************************************************/
-
-NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
-{
- struct lsa_info *handle=NULL;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- NTSTATUS status;
-
- r_u->status = NT_STATUS_OK;
-
- /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
- return NT_STATUS_INVALID_HANDLE;
-
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
-
- switch (q_u->sec_info) {
- case 1:
- /* SD contains only the owner */
-
- status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!NT_STATUS_IS_OK(status))
- return NT_STATUS_NO_MEMORY;
-
-
- if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- case 4:
- /* SD contains only the ACL */
-
- status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!NT_STATUS_IS_OK(status))
- return NT_STATUS_NO_MEMORY;
-
- if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
- }
-
- r_u->ptr=1;
-
- return r_u->status;
-}
-
-
-NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
-{
- struct lsa_info *handle;
- const char *nb_name;
- char *dns_name = NULL;
- char *forest_name = NULL;
- DOM_SID *sid = NULL;
- struct uuid guid;
- fstring dnsdomname;
-
- ZERO_STRUCT(guid);
- r_u->status = NT_STATUS_OK;
-
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- switch (q_u->info_class) {
- case 0x0c:
- /* check if the user have enough rights */
- if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
- return NT_STATUS_ACCESS_DENIED;
-
- /* Request PolicyPrimaryDomainInformation. */
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- nb_name = get_global_sam_name();
- /* ugly temp hack for these next two */
-
- /* This should be a 'netbios domain -> DNS domain' mapping */
- dnsdomname[0] = '\0';
- get_mydnsdomname(dnsdomname);
- strlower_m(dnsdomname);
-
- dns_name = dnsdomname;
- forest_name = dnsdomname;
-
- sid = get_global_sam_sid();
- secrets_fetch_domain_guid(lp_workgroup(), &guid);
- break;
- default:
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
- init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
- forest_name,&guid,sid);
- break;
- default:
- DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
- r_u->status = NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
-
- if (NT_STATUS_IS_OK(r_u->status)) {
- r_u->ptr = 0x1;
- r_u->info_class = q_u->info_class;
- }
+ r_u->access=3;
return r_u->status;
}
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index f06a2002e3c..06e2f75ead4 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jeremy Allison 1998-2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*************************************************************************
api_net_req_chal:
*************************************************************************/
@@ -317,69 +314,28 @@ static BOOL api_net_logon_ctrl(pipes_struct *p)
return True;
}
-/*************************************************************************
- api_ds_enum_dom_trusts:
- *************************************************************************/
-
-#if 0 /* JERRY */
-static BOOL api_ds_enum_dom_trusts(pipes_struct *p)
-{
- DS_Q_ENUM_DOM_TRUSTS q_u;
- DS_R_ENUM_DOM_TRUSTS r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- DEBUG(6,("api_ds_enum_dom_trusts\n"));
-
- if ( !ds_io_q_enum_domain_trusts("", data, 0, &q_u) ) {
- DEBUG(0,("api_ds_enum_domain_trusts: Failed to unmarshall DS_Q_ENUM_DOM_TRUSTS.\n"));
- return False;
- }
-
- r_u.status = _ds_enum_dom_trusts(p, &q_u, &r_u);
-
- if ( !ds_io_r_enum_domain_trusts("", rdata, 0, &r_u) ) {
- DEBUG(0,("api_ds_enum_domain_trusts: Failed to marshall DS_R_ENUM_DOM_TRUSTS.\n"));
- return False;
- }
-
- DEBUG(6,("api_ds_enum_dom_trusts\n"));
-
- return True;
-}
-#endif /* JERRY */
-
/*******************************************************************
array of \PIPE\NETLOGON operations
********************************************************************/
static struct api_struct api_net_cmds [] =
- {
- { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
- { "NET_AUTH" , NET_AUTH , api_net_auth },
- { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
- { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
- { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
- { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
- { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
- { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
- { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl },
-#if 0 /* JERRY */
- { "DS_ENUM_DOM_TRUSTS", DS_ENUM_DOM_TRUSTS, api_ds_enum_dom_trusts }
-#endif /* JERRY */
- };
-
-void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns )
{
- *fns = api_net_cmds;
- *n_fns = sizeof(api_net_cmds) / sizeof(struct api_struct);
-}
+ { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
+ { "NET_AUTH" , NET_AUTH , api_net_auth },
+ { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
+ { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
+ { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
+ { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
+ { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
+ { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
+ { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
-NTSTATUS rpc_net_init(void)
+BOOL api_netlog_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "NETLOGON", "lsass", api_net_cmds,
- sizeof(api_net_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds);
}
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index be8eda82c90..e61288f079b 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -1,11 +1,12 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 1998-2001.
- * Copyright (C) Andrew Bartlett 2001.
+ * Copyirht (C) Andrew Bartlett 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,8 +27,10 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+extern BOOL sam_logon_in_ssb;
+extern pstring samlogon_user;
+extern pstring global_myname;
+extern DOM_SID global_sam_sid;
/*************************************************************************
init_net_r_req_chal:
@@ -72,40 +75,17 @@ NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u,
return r_u->status;
}
-/****************************************************************************
-Send a message to smbd to do a sam synchronisation
-**************************************************************************/
-static void send_sync_message(void)
-{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (!tdb) {
- DEBUG(3, ("send_sync_message(): failed to open connections "
- "database\n"));
- return;
- }
-
- DEBUG(3, ("sending sam synchronisation message\n"));
-
- message_send_all(tdb, MSG_SMB_SAM_SYNC, NULL, 0, False, NULL);
-
- tdb_close(tdb);
-}
-
/*************************************************************************
net_reply_logon_ctrl2:
*************************************************************************/
NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u)
{
- uint32 flags = 0x0;
- uint32 pdc_connection_status = 0x0;
- uint32 logon_attempts = 0x0;
- uint32 tc_status = ERROR_NO_LOGON_SERVERS;
- const char *trusted_domain = "test_domain";
+ uint32 flags = 0x0;
+ uint32 pdc_connection_status = 0x0;
+ uint32 logon_attempts = 0x0;
+ uint32 tc_status = ERROR_NO_LOGON_SERVERS;
+ const char *trusted_domain = "test_domain";
DEBUG(0, ("*** net long ctrl2 %d, %d, %d\n",
q_u->function_code, q_u->query_level, q_u->switch_value));
@@ -115,11 +95,8 @@ NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_C
/* set up the Logon Control2 response */
init_net_r_logon_ctrl2(r_u, q_u->query_level,
- flags, pdc_connection_status, logon_attempts,
- tc_status, trusted_domain);
-
- if (lp_server_role() == ROLE_DOMAIN_BDC)
- send_sync_message();
+ flags, pdc_connection_status, logon_attempts,
+ tc_status, trusted_domain);
DEBUG(6,("_net_logon_ctrl2: %d\n", __LINE__));
@@ -150,7 +127,7 @@ NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_T
***********************************************************************************/
static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
- DOM_CRED *srv_cred, NTSTATUS status)
+ DOM_CRED *srv_cred, NTSTATUS status)
{
DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
@@ -167,9 +144,8 @@ static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
static BOOL get_md4pw(char *md4pw, char *mach_acct)
{
SAM_ACCOUNT *sampass = NULL;
- const uint8 *pass;
+ uint8 *pass;
BOOL ret;
- uint32 acct_ctrl;
#if 0
/*
@@ -188,37 +164,30 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
return False;
}
#endif /* 0 */
-
- if(!NT_STATUS_IS_OK(pdb_init_sam(&sampass)))
+ if(!pdb_init_sam(&sampass))
return False;
/* JRA. This is ok as it is only used for generating the challenge. */
become_root();
ret=pdb_getsampwnam(sampass, mach_acct);
unbecome_root();
-
+
if (ret==False) {
DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return False;
}
- acct_ctrl = pdb_get_acct_ctrl(sampass);
- if (!(acct_ctrl & ACB_DISABLED) &&
- ((acct_ctrl & ACB_DOMTRUST) ||
- (acct_ctrl & ACB_WSTRUST) ||
- (acct_ctrl & ACB_SVRTRUST)) &&
- ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
+ if (!(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) && ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
memcpy(md4pw, pass, 16);
dump_data(5, md4pw, 16);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return True;
}
DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return False;
-
}
/*************************************************************************
@@ -228,25 +197,46 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
{
NTSTATUS status = NT_STATUS_OK;
+ fstring mach_acct;
+
+ if (!get_valid_user_struct(p->vuid))
+ return NT_STATUS_NO_SUCH_USER;
- rpcstr_pull(p->dc.remote_machine,q_u->uni_logon_clnt.buffer,sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0);
+ fstrcpy(mach_acct, dos_unistrn2(q_u->uni_logon_clnt.buffer,
+ q_u->uni_logon_clnt.uni_str_len));
- /* create a server challenge for the client */
- /* Set these to random values. */
- generate_random_buffer(p->dc.srv_chal.data, 8, False);
-
- memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
+ strlower(mach_acct);
+ fstrcat(mach_acct, "$");
+
+ if (get_md4pw((char *)p->dc.md4pw, mach_acct)) {
+ /* copy the client credentials */
+ memcpy(p->dc.clnt_chal.data , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+ memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+
+ /* create a server challenge for the client */
+ /* Set these to random values. */
+ generate_random_buffer(p->dc.srv_chal.data, 8, False);
+
+ memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
- memcpy(p->dc.clnt_chal.data , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+ memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
- memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
+ /* from client / server challenges and md4 password, generate sess key */
+ cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
+ (uchar *)p->dc.md4pw, p->dc.sess_key);
+
+ /* Save the machine account name. */
+ fstrcpy(p->dc.mach_acct, mach_acct);
+
+ } else {
+ /* lkclXXXX take a guess at a good error message to return :-) */
+ status = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
+ }
- p->dc.challenge_sent = True;
/* set up the LSA REQUEST CHALLENGE response */
init_net_r_req_chal(r_u, &p->dc.srv_chal, status);
-
- return status;
+
+ return r_u->status;
}
/*************************************************************************
@@ -268,41 +258,26 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
NTSTATUS status = NT_STATUS_OK;
DOM_CHAL srv_cred;
UTIME srv_time;
- fstring mach_acct;
+
+ if (!get_valid_user_struct(p->vuid))
+ return NT_STATUS_NO_SUCH_USER;
srv_time.time = 0;
- rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
+ /* check that the client credentials are valid */
+ if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
- if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
+ /* create server challenge for inclusion in the reply */
+ cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
- /* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
- p->dc.md4pw, p->dc.sess_key);
-
- /* check that the client credentials are valid */
- if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
-
- /* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-
- /* Save the machine account name. */
- fstrcpy(p->dc.mach_acct, mach_acct);
-
- p->dc.authenticated = True;
-
- } else {
- status = NT_STATUS_ACCESS_DENIED;
- }
+ /* copy the received client credentials for use next time */
+ memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+ memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
} else {
status = NT_STATUS_ACCESS_DENIED;
}
-
- /* set up the LSA AUTH response */
+
+ /* set up the LSA AUTH 2 response */
init_net_r_auth(r_u, &srv_cred, status);
return r_u->status;
@@ -330,61 +305,30 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
DOM_CHAL srv_cred;
UTIME srv_time;
NEG_FLAGS srv_flgs;
- fstring mach_acct;
- srv_time.time = 0;
+ if (!get_valid_user_struct(p->vuid))
+ return NT_STATUS_NO_SUCH_USER;
- if ( (lp_server_schannel() == True) &&
- ((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) {
+ srv_time.time = 0;
- /* schannel must be used, but client did not offer it. */
- status = NT_STATUS_ACCESS_DENIED;
- }
+ /* check that the client credentials are valid */
+ if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
- rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
+ /* create server challenge for inclusion in the reply */
+ cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
- if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
-
- /* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
- p->dc.md4pw, p->dc.sess_key);
-
- /* check that the client credentials are valid */
- if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
-
- /* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-
- /* Save the machine account name. */
- fstrcpy(p->dc.mach_acct, mach_acct);
-
- p->dc.authenticated = True;
-
- } else {
- status = NT_STATUS_ACCESS_DENIED;
- }
+ /* copy the received client credentials for use next time */
+ memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+ memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
} else {
status = NT_STATUS_ACCESS_DENIED;
}
-
- srv_flgs.neg_flags = 0x000001ff;
- if (lp_server_schannel() != False) {
- srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL;
- }
+ srv_flgs.neg_flags = 0x000001ff;
/* set up the LSA AUTH 2 response */
init_net_r_auth_2(r_u, &srv_cred, &srv_flgs, status);
- if (NT_STATUS_IS_OK(status)) {
- extern struct dcinfo last_dcinfo;
- last_dcinfo = p->dc;
- }
-
return r_u->status;
}
@@ -394,51 +338,53 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
{
- NTSTATUS status = NT_STATUS_ACCESS_DENIED;
+ NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
DOM_CRED srv_cred;
- pstring workstation;
+ pstring mach_acct;
SAM_ACCOUNT *sampass=NULL;
- BOOL ret = False;
+ BOOL ret=False;
unsigned char pwd[16];
int i;
- uint32 acct_ctrl;
+
+ if (!get_valid_user_struct(p->vuid))
+ return NT_STATUS_NO_SUCH_USER;
/* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred)))
+ if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred))
return NT_STATUS_INVALID_HANDLE;
memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
- rpcstr_pull(workstation,q_u->clnt_id.login.uni_comp_name.buffer,
- sizeof(workstation),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0);
+ pstrcpy(mach_acct, dos_unistrn2(q_u->clnt_id.login.uni_acct_name.buffer,
+ q_u->clnt_id.login.uni_acct_name.uni_str_len));
+
+ DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+
+ /*
+ * Check the machine account name we're changing is the same
+ * as the one we've authenticated from. This prevents arbitrary
+ * machines changing other machine account passwords.
+ */
+
+ if (!strequal(mach_acct, p->dc.mach_acct)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
- DEBUG(3,("Server Password Set by Wksta:[%s] on account [%s]\n", workstation, p->dc.mach_acct));
-
pdb_init_sam(&sampass);
become_root();
- ret=pdb_getsampwnam(sampass, p->dc.mach_acct);
+ ret=pdb_getsampwnam(sampass, mach_acct);
unbecome_root();
/* Ensure the account exists and is a machine account. */
-
- acct_ctrl = pdb_get_acct_ctrl(sampass);
- if (!(ret
- && (acct_ctrl & ACB_WSTRUST ||
- acct_ctrl & ACB_SVRTRUST ||
- acct_ctrl & ACB_DOMTRUST))) {
- pdb_free_sam(&sampass);
+ if (ret==False || !(pdb_get_acct_ctrl(sampass) & ACB_WSTRUST)) {
+ pdb_free_sam(sampass);
return NT_STATUS_NO_SUCH_USER;
}
-
- if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
- pdb_free_sam(&sampass);
- return NT_STATUS_ACCOUNT_DISABLED;
- }
-
+
DEBUG(100,("Server password set : new given value was :\n"));
for(i = 0; i < 16; i++)
DEBUG(100,("%02X ", q_u->pwd[i]));
@@ -447,33 +393,27 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);
/* lies! nt and lm passwords are _not_ the same: don't care */
- if (!pdb_set_lanman_passwd (sampass, pwd, PDB_CHANGED)) {
- pdb_free_sam(&sampass);
+ if (!pdb_set_lanman_passwd (sampass, pwd)) {
+ pdb_free_sam(sampass);
return NT_STATUS_NO_MEMORY;
}
-
- if (!pdb_set_nt_passwd (sampass, pwd, PDB_CHANGED)) {
- pdb_free_sam(&sampass);
+ if (!pdb_set_nt_passwd(sampass, pwd)) {
+ pdb_free_sam(sampass);
return NT_STATUS_NO_MEMORY;
}
-
- if (!pdb_set_pass_changed_now (sampass)) {
- pdb_free_sam(&sampass);
- /* Not quite sure what this one qualifies as, but this will do */
- return NT_STATUS_UNSUCCESSFUL;
- }
+ pdb_set_acct_ctrl (sampass, ACB_WSTRUST);
become_root();
- ret = pdb_update_sam_account (sampass);
+ ret = pdb_update_sam_account (sampass,False);
unbecome_root();
-
+
if (ret)
status = NT_STATUS_OK;
/* set up the LSA Server Password Set response */
init_net_r_srv_pwset(r_u, &srv_cred, status);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return r_u->status;
}
@@ -490,8 +430,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
return NT_STATUS_NO_SUCH_USER;
/* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred,
- &q_u->sam_id.client.cred, &srv_cred)))
+ if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred,
+ &q_u->sam_id.client.cred, &srv_cred))
return NT_STATUS_INVALID_HANDLE;
memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
@@ -505,6 +445,118 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
return r_u->status;
}
+/*************************************************************************
+ net_login_interactive:
+ *************************************************************************/
+
+static NTSTATUS net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
+{
+ uint8 *stored_nt_pwd, *stored_lanman_pwd;
+ char nt_pwd[16];
+ char lm_pwd[16];
+ unsigned char key[16];
+
+ memset(key, 0, 16);
+ memcpy(key, p->dc.sess_key, 8);
+
+ memcpy(lm_pwd, id1->lm_owf.data, 16);
+ memcpy(nt_pwd, id1->nt_owf.data, 16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("key:"));
+ dump_data(100, (char *)key, 16);
+
+ DEBUG(100,("lm owf password:"));
+ dump_data(100, lm_pwd, 16);
+
+ DEBUG(100,("nt owf password:"));
+ dump_data(100, nt_pwd, 16);
+#endif
+
+ SamOEMhash((uchar *)lm_pwd, key, 16);
+ SamOEMhash((uchar *)nt_pwd, key, 16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("decrypt of lm owf password:"));
+ dump_data(100, lm_pwd, 16);
+
+ DEBUG(100,("decrypt of nt owf password:"));
+ dump_data(100, nt_pwd, 16);
+#endif
+
+ /* JRA. Check the NT password first if it exists - this is a higher quality
+ password, if it exists and it doesn't match - fail. */
+
+ stored_nt_pwd = pdb_get_nt_passwd(sampass);
+
+ if (stored_nt_pwd) {
+ if (memcmp(stored_nt_pwd, nt_pwd, 16) != 0) {
+ DEBUG(10,("net_login_interactive: NT password for user %s doesn't match.\n",
+ sampass->username));
+ return NT_STATUS_WRONG_PASSWORD;
+ } else
+ return NT_STATUS_OK;
+ }
+
+ stored_lanman_pwd = pdb_get_lanman_passwd(sampass);
+
+ if (stored_lanman_pwd && lp_lanman_auth()) {
+ if (memcmp(stored_lanman_pwd, lm_pwd, 16) != 0) {
+ DEBUG(10,("net_login_interactive: lanman password for user %s doesn't match.\n",
+ sampass->username));
+ return NT_STATUS_WRONG_PASSWORD;
+ } else
+ return NT_STATUS_OK;
+ }
+
+ return NT_STATUS_WRONG_PASSWORD;
+}
+
+/*************************************************************************
+ _net_login_network:
+ *************************************************************************/
+
+static NTSTATUS net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
+{
+ uint8 *nt_pwd, *lanman_pwd;
+
+ DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
+ id2->hdr_lm_chal_resp.str_str_len,
+ id2->hdr_nt_chal_resp.str_str_len));
+
+ /* JRA. Check the NT password first if it exists - this is a higher quality
+ password, if it exists and it doesn't match - fail. */
+
+ nt_pwd = pdb_get_nt_passwd(sampass);
+ lanman_pwd = pdb_get_lanman_passwd(sampass);
+
+ if (id2->hdr_nt_chal_resp.str_str_len == 24 && nt_pwd != NULL) {
+ if(smb_password_check((char *)id2->nt_chal_resp.buffer, nt_pwd, id2->lm_chal))
+ return NT_STATUS_OK;
+ else
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ /* lkclXXXX this is not a good place to put disabling of LM hashes in.
+ if that is to be done, first move this entire function into a
+ library routine that calls the two smb_password_check() functions.
+ if disabling LM hashes (which nt can do for security reasons) then
+ an attempt should be made to disable them everywhere (which nt does
+ not do, for various security-hole reasons).
+ */
+
+ if (lp_lanman_auth() && id2->hdr_lm_chal_resp.str_str_len == 24 &&
+ smb_password_check((char *)id2->lm_chal_resp.buffer,
+ lanman_pwd, id2->lm_chal))
+ {
+ return NT_STATUS_OK;
+ }
+
+
+ /* oops! neither password check succeeded */
+
+ return NT_STATUS_WRONG_PASSWORD;
+}
/*************************************************************************
_net_sam_logon
@@ -514,22 +566,16 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
{
NTSTATUS status = NT_STATUS_OK;
NET_USER_INFO_3 *usr_info = NULL;
- NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr;
DOM_CRED srv_cred;
+ SAM_ACCOUNT *sampass = NULL;
UNISTR2 *uni_samlogon_user = NULL;
- UNISTR2 *uni_samlogon_domain = NULL;
- UNISTR2 *uni_samlogon_workstation = NULL;
- fstring nt_username, nt_domain, nt_workstation;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
- extern userdom_struct current_user_info;
- SAM_ACCOUNT *sampw;
- struct auth_context *auth_context = NULL;
-
+ fstring nt_username;
+ BOOL ret;
+ uint16 acct_ctrl;
+
usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
if (!usr_info)
return NT_STATUS_NO_MEMORY;
-
ZERO_STRUCTP(usr_info);
/* store the user information, if there is any. */
@@ -540,20 +586,12 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
if (!get_valid_user_struct(p->vuid))
return NT_STATUS_NO_SUCH_USER;
-
-
- if ( (lp_server_schannel() == True) && (!p->netsec_auth_validated) ) {
- /* 'server schannel = yes' should enforce use of
- schannel, the client did offer it in auth2, but
- obviously did not use it. */
- return NT_STATUS_ACCESS_DENIED;
- }
-
+
/* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
+ if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred))
return NT_STATUS_INVALID_HANDLE;
-
- memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
+ else
+ memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
r_u->buffer_creds = 1; /* yes, we have valid server credentials */
memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
@@ -562,17 +600,12 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
switch (q_u->sam_id.logon_level) {
case INTERACTIVE_LOGON_TYPE:
- uni_samlogon_user = &ctr->auth.id1.uni_user_name;
- uni_samlogon_domain = &ctr->auth.id1.uni_domain_name;
-
- uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name;
+ uni_samlogon_user = &q_u->sam_id.ctr->auth.id1.uni_user_name;
DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
break;
case NET_LOGON_TYPE:
- uni_samlogon_user = &ctr->auth.id2.uni_user_name;
- uni_samlogon_domain = &ctr->auth.id2.uni_domain_name;
- uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name;
+ uni_samlogon_user = &q_u->sam_id.ctr->auth.id2.uni_user_name;
DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
break;
@@ -581,215 +614,116 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
return NT_STATUS_INVALID_INFO_CLASS;
} /* end switch */
- rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0);
- rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0);
- rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0);
+ /* check username exists */
- DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username,
- nt_workstation, nt_domain));
-
- fstrcpy(current_user_info.smb_name, nt_username);
- sub_set_smb_name(nt_username);
-
- DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));
+ pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer, uni_samlogon_user->uni_str_len));
- status = NT_STATUS_OK;
-
- switch (ctr->switch_value) {
- case NET_LOGON_TYPE:
- {
- const char *wksname = nt_workstation;
-
- if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
- return status;
- }
+ DEBUG(3,("User:[%s]\n", nt_username));
+
+ /*
+ * Convert to a UNIX username.
+ */
- /* For a network logon, the workstation name comes in with two
- * backslashes in the front. Strip them if they are there. */
-
- if (*wksname == '\\') wksname++;
- if (*wksname == '\\') wksname++;
-
- /* Standard challenge/response authenticaion */
- if (!make_user_info_netlogon_network(&user_info,
- nt_username, nt_domain,
- wksname,
- ctr->auth.id2.lm_chal_resp.buffer,
- ctr->auth.id2.lm_chal_resp.str_str_len,
- ctr->auth.id2.nt_chal_resp.buffer,
- ctr->auth.id2.nt_chal_resp.str_str_len)) {
- status = NT_STATUS_NO_MEMORY;
- }
- break;
- }
- case INTERACTIVE_LOGON_TYPE:
- /* 'Interactive' autheticaion, supplies the password in its
- MD4 form, encrypted with the session key. We will
- convert this to chellange/responce for the auth
- subsystem to chew on */
+ map_username(nt_username);
+
+ /* get the account information */
+ pdb_init_sam(&sampass);
+ become_root();
+ ret = pdb_getsampwnam(sampass, nt_username);
+ unbecome_root();
+
+ if (!ret)
{
- const uint8 *chal;
-
- if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
- return status;
- }
-
- chal = auth_context->get_ntlm_challenge(auth_context);
-
- if (!make_user_info_netlogon_interactive(&user_info,
- nt_username, nt_domain,
- nt_workstation, chal,
- ctr->auth.id1.lm_owf.data,
- ctr->auth.id1.nt_owf.data,
- p->dc.sess_key)) {
- status = NT_STATUS_NO_MEMORY;
- }
- break;
+ pdb_free_sam(sampass);
+ return NT_STATUS_NO_SUCH_USER;
}
- default:
- DEBUG(2,("SAM Logon: unsupported switch value\n"));
- return NT_STATUS_INVALID_INFO_CLASS;
- } /* end switch */
- if ( NT_STATUS_IS_OK(status) ) {
- status = auth_context->check_ntlm_password(auth_context,
- user_info, &server_info);
- }
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
- (auth_context->free)(&auth_context);
- free_user_info(&user_info);
-
- DEBUG(5, ("_net_sam_logon: check_password returned status %s\n",
- nt_errstr(status)));
+ /* Validate password - if required. */
+
+ if (!(acct_ctrl & ACB_PWNOTREQ)) {
+ switch (q_u->sam_id.logon_level) {
+ case INTERACTIVE_LOGON_TYPE:
+ /* interactive login. */
+ status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, sampass, p);
+ break;
+ case NET_LOGON_TYPE:
+ /* network login. lm challenge and 24 byte responses */
+ status = net_login_network(&q_u->sam_id.ctr->auth.id2, sampass);
+ break;
+ }
+ }
- /* Check account and password */
-
if (!NT_STATUS_IS_OK(status)) {
- free_server_info(&server_info);
+ pdb_free_sam(sampass);
return status;
}
- if (server_info->guest) {
- /* We don't like guest domain logons... */
- DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST denied.\n"));
- free_server_info(&server_info);
- return NT_STATUS_LOGON_FAILURE;
+#ifdef WITH_PAM
+ become_root();
+ status = smb_pam_accountcheck(pdb_get_username(sampass));
+ unbecome_root();
+ if (!NT_STATUS_IS_OK(status)) {
+ pdb_free_sam(sampass);
+ return status;
}
+#endif
- /* This is the point at which, if the login was successful, that
- the SAM Local Security Authority should record that the user is
- logged in to the domain. */
+ if (acct_ctrl & ACB_DISABLED) {
+ pdb_free_sam(sampass);
+ return NT_STATUS_ACCOUNT_DISABLED;
+ }
+
+ /* lkclXXXX this is the point at which, if the login was
+ successful, that the SAM Local Security Authority should
+ record that the user is logged in to the domain.
+ */
{
DOM_GID *gids = NULL;
- const DOM_SID *user_sid = NULL;
- const DOM_SID *group_sid = NULL;
- DOM_SID domain_sid;
- uint32 user_rid, group_rid;
-
int num_gids = 0;
pstring my_name;
- fstring user_sid_string;
- fstring group_sid_string;
- uchar user_session_key[16];
- uchar lm_session_key[16];
- uchar netlogon_sess_key[16];
-
- sampw = server_info->sam_account;
-
+ pstring my_workgroup;
+ pstring domain_groups;
+
/* set up pointer indicating user/password failed to be found */
usr_info->ptr_user_info = 0;
-
- user_sid = pdb_get_user_sid(sampw);
- group_sid = pdb_get_group_sid(sampw);
-
- sid_copy(&domain_sid, user_sid);
- sid_split_rid(&domain_sid, &user_rid);
-
- if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
- DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid %s\n but group sid %s.\nThe conflicting domain portions are not supported for NETLOGON calls\n",
- pdb_get_domain(sampw), pdb_get_username(sampw),
- sid_to_string(user_sid_string, user_sid),
- sid_to_string(group_sid_string, group_sid)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pstrcpy(my_name, global_myname());
-
- if (!NT_STATUS_IS_OK(status
- = nt_token_to_group_list(p->mem_ctx,
- &domain_sid,
- server_info->ptok,
- &num_gids,
- &gids))) {
- return status;
- }
-
- ZERO_STRUCT(netlogon_sess_key);
- memcpy(netlogon_sess_key, p->dc.sess_key, 8);
- if (server_info->user_session_key.length) {
- memcpy(user_session_key, server_info->user_session_key.data,
- MIN(sizeof(user_session_key), server_info->user_session_key.length));
- SamOEMhash(user_session_key, netlogon_sess_key, 16);
- }
- if (server_info->lm_session_key.length) {
- memcpy(lm_session_key, server_info->lm_session_key.data,
- MIN(sizeof(lm_session_key), server_info->lm_session_key.length));
- SamOEMhash(lm_session_key, netlogon_sess_key, 16);
- }
- ZERO_STRUCT(netlogon_sess_key);
-
- init_net_user_info3(p->mem_ctx, usr_info,
- user_rid,
- group_rid,
- pdb_get_username(sampw),
- pdb_get_fullname(sampw),
- pdb_get_homedir(sampw),
- pdb_get_dir_drive(sampw),
- pdb_get_logon_script(sampw),
- pdb_get_profile_path(sampw),
- pdb_get_logon_time(sampw),
- get_time_t_max(),
- get_time_t_max(),
- pdb_get_pass_last_set_time(sampw),
- pdb_get_pass_can_change_time(sampw),
- pdb_get_pass_must_change_time(sampw),
-
- 0, /* logon_count */
- 0, /* bad_pw_count */
- num_gids, /* uint32 num_groups */
- gids , /* DOM_GID *gids */
- 0x20 , /* uint32 user_flgs (?) */
- server_info->user_session_key.length ? user_session_key : NULL,
- server_info->lm_session_key.length ? lm_session_key : NULL,
- my_name , /* char *logon_srv */
- pdb_get_domain(sampw),
- &domain_sid, /* DOM_SID *dom_sid */
- /* Should be users domain sid, not servers - for trusted domains */
-
- NULL); /* char *other_sids */
- ZERO_STRUCT(user_session_key);
- ZERO_STRUCT(lm_session_key);
+
+ pstrcpy(my_workgroup, lp_workgroup());
+ pstrcpy(my_name, global_myname);
+ strupper(my_name);
+
+ /*
+ * This is the point at which we get the group
+ * database - we should be getting the gid_t list
+ * from /etc/group and then turning the uids into
+ * rids and then into machine sids for this user.
+ * JRA.
+ */
+
+ get_domain_user_groups(domain_groups, nt_username);
+
+ /*
+ * make_dom_gids allocates the gids array. JRA.
+ */
+ gids = NULL;
+ num_gids = make_dom_gids(p->mem_ctx, domain_groups, &gids);
+
+ init_net_user_info3(p->mem_ctx, usr_info, sampass,
+ 0, /* logon_count */
+ 0, /* bad_pw_count */
+ num_gids, /* uint32 num_groups */
+ gids , /* DOM_GID *gids */
+ 0x20 , /* uint32 user_flgs (?) */
+ NULL, /* char sess_key[16] */
+ my_name , /* char *logon_srv */
+ my_workgroup, /* char *logon_dom */
+ &global_sam_sid, /* DOM_SID *dom_sid */
+ NULL); /* char *other_sids */
+
}
- free_server_info(&server_info);
- return status;
-}
-
-/*************************************************************************
- _ds_enum_dom_trusts
- *************************************************************************/
-#if 0 /* JERRY -- not correct */
-NTSTATUS _ds_enum_dom_trusts(pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
- DS_R_ENUM_DOM_TRUSTS *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
-
- /* TODO: According to MSDN, the can only be executed against a
- DC or domain member running Windows 2000 or later. Need
- to test against a standalone 2k server and see what it
- does. A windows 2000 DC includes its own domain in the
- list. --jerry */
+ pdb_free_sam(sampass);
return status;
}
-#endif /* JERRY */
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index 2589a47ca1e..e3a5528bcf7 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998,
- * Copyright (C) Jeremy Allison 1999,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Paul Ashton 1997-1998.
+ * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,16 +40,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/*************************************************************
- HACK Alert!
- We need to transfer the session key from one rpc bind to the
- next. This is the way the netlogon schannel works.
-**************************************************************/
-struct dcinfo last_dcinfo;
-
static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
unsigned char *hash = p->ntlmssp_hash;
@@ -87,11 +77,12 @@ BOOL create_next_pdu(pipes_struct *p)
RPC_HDR_RESP hdr_resp;
BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
- uint32 ss_padding_len = 0;
uint32 data_len;
uint32 data_space_available;
uint32 data_len_left;
prs_struct outgoing_pdu;
+ char *data;
+ char *data_from;
uint32 data_pos;
/*
@@ -110,22 +101,18 @@ BOOL create_next_pdu(pipes_struct *p)
p->hdr.pkt_type = RPC_RESPONSE;
/* Set up rpc header flags. */
- if (p->out_data.data_sent_length == 0) {
+ if (p->out_data.data_sent_length == 0)
p->hdr.flags = RPC_FLG_FIRST;
- } else {
+ else
p->hdr.flags = 0;
- }
/*
* Work out how much we can fit in a single PDU.
*/
data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
- if(p->ntlmssp_auth_validated) {
+ if(p->ntlmssp_auth_validated)
data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
- } else if(p->netsec_auth_validated) {
- data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN);
- }
/*
* The amount we send is the minimum of the available
@@ -153,38 +140,26 @@ BOOL create_next_pdu(pipes_struct *p)
hdr_resp.alloc_hint = data_len_left;
/*
- * Work out if this PDU will be the last.
- */
-
- if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
- p->hdr.flags |= RPC_FLG_LAST;
- if ((auth_seal || auth_verify) && (data_len_left % 8)) {
- ss_padding_len = 8 - (data_len_left % 8);
- DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n",
- ss_padding_len ));
- }
- }
-
- /*
* Set up the header lengths.
*/
if (p->ntlmssp_auth_validated) {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
- data_len + ss_padding_len +
- RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
+ RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
- } else if (p->netsec_auth_validated) {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
- data_len + ss_padding_len +
- RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN;
- p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN;
} else {
p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
p->hdr.auth_len = 0;
}
/*
+ * Work out if this PDU will be the last.
+ */
+
+ if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata))
+ p->hdr.flags |= RPC_FLG_LAST;
+
+ /*
* Init the parse struct to point at the outgoing
* data.
*/
@@ -209,51 +184,36 @@ BOOL create_next_pdu(pipes_struct *p)
data_pos = prs_offset(&outgoing_pdu);
/* Copy the data into the PDU. */
+ data_from = prs_data_p(&p->out_data.rdata) + p->out_data.data_sent_length;
- if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
+ if(!prs_append_data(&outgoing_pdu, data_from, data_len)) {
DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
prs_mem_free(&outgoing_pdu);
return False;
}
- /* Copy the sign/seal padding data. */
- if (ss_padding_len) {
- char pad[8];
- memset(pad, '\0', 8);
- if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
- DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
- prs_mem_free(&outgoing_pdu);
- return False;
- }
- }
+ /*
+ * Set data to point to where we copied the data into.
+ */
- if (p->ntlmssp_auth_validated) {
- /*
- * NTLMSSP processing. Mutually exclusive with Schannel.
- */
+ data = prs_data_p(&outgoing_pdu) + data_pos;
+
+ if (p->hdr.auth_len > 0) {
uint32 crc32 = 0;
- char *data;
DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len));
-
- /*
- * Set data to point to where we copied the data into.
- */
-
- data = prs_data_p(&outgoing_pdu) + data_pos;
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len));
if (auth_seal) {
- crc32 = crc32_calc_buffer(data, data_len + ss_padding_len);
- NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len);
+ crc32 = crc32_calc_buffer(data, data_len);
+ NTLMSSPcalc_p(p, (uchar*)data, data_len);
}
if (auth_seal || auth_verify) {
RPC_HDR_AUTH auth_info;
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE,
- auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL,
- (auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0));
+ init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL,
+ (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
prs_mem_free(&outgoing_pdu);
@@ -276,42 +236,6 @@ BOOL create_next_pdu(pipes_struct *p)
}
NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
}
- } else if (p->netsec_auth_validated) {
- /*
- * Schannel processing. Mutually exclusive with NTLMSSP.
- */
- int auth_type, auth_level;
- char *data;
- RPC_HDR_AUTH auth_info;
-
- RPC_AUTH_NETSEC_CHK verf;
- prs_struct rverf;
- prs_struct rauth;
-
- data = prs_data_p(&outgoing_pdu) + data_pos;
- /* Check it's the type of reply we were expecting to decode */
-
- get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level);
- init_rpc_hdr_auth(&auth_info, auth_type, auth_level,
- ss_padding_len, 1);
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
- prs_mem_free(&outgoing_pdu);
- return False;
- }
-
- prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
- prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
-
- netsec_encode(&p->netsec_auth,
- p->netsec_auth.auth_flags,
- SENDER_IS_ACCEPTOR,
- &verf, data, data_len + ss_padding_len);
-
- smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0);
-
- p->netsec_auth.seq_num++;
}
/*
@@ -337,19 +261,16 @@ BOOL create_next_pdu(pipes_struct *p)
static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
{
uchar lm_owf[24];
- uchar nt_owf[128];
- int nt_pw_len;
- int lm_pw_len;
+ uchar nt_owf[24];
fstring user_name;
+ fstring pipe_user_name;
fstring domain;
fstring wks;
-
- NTSTATUS nt_status;
-
- struct auth_context *auth_context = NULL;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
-
+ BOOL guest_user = False;
+ SAM_ACCOUNT *sampass = NULL;
+ uchar null_smb_passwd[16];
+ uchar *smb_passwd_ptr = NULL;
+
DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
memset(p->user_name, '\0', sizeof(p->user_name));
@@ -360,38 +281,37 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
/* Set up for non-authenticated user. */
delete_nt_token(&p->pipe_user.nt_user_token);
p->pipe_user.ngroups = 0;
- SAFE_FREE( p->pipe_user.groups);
+ safe_free( p->pipe_user.groups);
/*
* Setup an empty password for a guest user.
*/
+ memset(null_smb_passwd,0,16);
+
/*
* We always negotiate UNICODE.
*/
if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
- rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
- rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
+ fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2));
+ fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2));
+ fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2));
} else {
- pull_ascii_fstring(user_name, ntlmssp_resp->user);
- pull_ascii_fstring(domain, ntlmssp_resp->domain);
- pull_ascii_fstring(wks, ntlmssp_resp->wks);
+ fstrcpy(user_name, ntlmssp_resp->user);
+ fstrcpy(domain, ntlmssp_resp->domain);
+ fstrcpy(wks, ntlmssp_resp->wks);
}
DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
- nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
- lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);
-
memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
- memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);
+ memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
#ifdef DEBUG_PASSWORD
DEBUG(100,("lm, nt owfs, chal\n"));
dump_data(100, (char *)lm_owf, sizeof(lm_owf));
- dump_data(100, (char *)nt_owf, nt_pw_len);
+ dump_data(100, (char *)nt_owf, sizeof(nt_owf));
dump_data(100, (char *)p->challenge, 8);
#endif
@@ -399,7 +319,25 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
* Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
*/
- if (*user_name) {
+ if((strlen(user_name) == 0) &&
+ (ntlmssp_resp->hdr_nt_resp.str_str_len==0))
+ {
+ guest_user = True;
+
+ fstrcpy(pipe_user_name, lp_guestaccount(-1));
+ DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name));
+
+ smb_passwd_ptr = null_smb_passwd;
+
+ } else {
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ fstrcpy(pipe_user_name, user_name);
+ (void)map_username(pipe_user_name);
/*
* Do the length checking only if user is not NULL.
@@ -417,44 +355,78 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
return False;
}
-
- make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
- if (!make_user_info_netlogon_network(&user_info,
- user_name, domain, wks,
- lm_owf, lm_pw_len,
- nt_owf, nt_pw_len)) {
- DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n"));
- return False;
+ if(!guest_user) {
+
+ become_root();
+
+ if(!(p->ntlmssp_auth_validated = pass_check_smb(pipe_user_name, domain,
+ (uchar*)p->challenge, lm_owf, nt_owf, NULL))) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
+failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name ));
+ unbecome_root();
+ return False;
+ }
+
+ pdb_init_sam(&sampass);
+
+ if(!pdb_getsampwnam(sampass, pipe_user_name)) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
+ pipe_user_name));
+ pdb_free_sam(sampass);
+ unbecome_root();
+ return False;
+ }
+
+ unbecome_root();
+
+ /* Quit if the account was disabled. */
+ if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) {
+ DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ if(!pdb_get_nt_passwd(sampass)) {
+ DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ smb_passwd_ptr = pdb_get_lanman_passwd(sampass);
+
+ /*
+ * Store the UNIX credential data (uid/gid pair) in the pipe structure.
+ */
+
+ p->pipe_user.uid = pdb_get_uid(sampass);
+ p->pipe_user.gid = pdb_get_gid(sampass);
}
-
- nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
-
- (auth_context->free)(&auth_context);
- free_user_info(&user_info);
-
- p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
-
- if (!p->ntlmssp_auth_validated) {
- DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
-failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
- free_server_info(&server_info);
- return False;
+ else {
+ struct passwd *pw;
+
+ /* setup the guest credentials; assuming that the guest
+ account does not have to exist in the smbpasswd file */
+
+ if ( (pw = sys_getpwnam(pipe_user_name)) == NULL ) {
+ DEBUG(0,("api_pipe_ntlmssp_verify: Invalid guest account [%s]. getpwnam() failed!\n",
+ pipe_user_name));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ p->pipe_user.uid = pw->pw_uid;
+ p->pipe_user.gid = pw->pw_gid;
+
}
/*
* Set up the sign/seal data.
*/
- if (server_info->lm_session_key.length != 16) {
- DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
-succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n",
- domain, user_name, wks, p->name, server_info->lm_session_key.length));
- free_server_info(&server_info);
- return False;
- } else {
+ {
uchar p24[24];
- NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24);
+ NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
{
unsigned char j = 0;
int ind;
@@ -482,50 +454,27 @@ succeeded authentication on named pipe %s, but session key was of incorrect leng
p->ntlmssp_hash[256] = 0;
p->ntlmssp_hash[257] = 0;
}
-
- dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
- sizeof(p->ntlmssp_hash));
-
/* NTLMSSPhash(p->ntlmssp_hash, p24); */
p->ntlmssp_seq_num = 0;
}
fstrcpy(p->user_name, user_name);
- fstrcpy(p->pipe_user_name, server_info->unix_name);
+ fstrcpy(p->pipe_user_name, pipe_user_name);
fstrcpy(p->domain, domain);
fstrcpy(p->wks, wks);
- /*
- * Store the UNIX credential data (uid/gid pair) in the pipe structure.
- */
-
- p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length);
-
- p->pipe_user.uid = server_info->uid;
- p->pipe_user.gid = server_info->gid;
-
- p->pipe_user.ngroups = server_info->n_groups;
- if (p->pipe_user.ngroups) {
- if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) {
- DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
- free_server_info(&server_info);
- return False;
- }
- }
+ /* Set up pipe user group membership. */
+ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid);
+ get_current_groups( p->pipe_user.gid, &p->pipe_user.ngroups, &p->pipe_user.groups);
- if (server_info->ptok)
- p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok);
- else {
- DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
- p->pipe_user.nt_user_token = NULL;
- free_server_info(&server_info);
- return False;
- }
+ /* Create an NT_USER_TOKEN struct for this user. */
+ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid,
+ p->pipe_user.ngroups, p->pipe_user.groups,
+ guest_user, NULL);
p->ntlmssp_auth_validated = True;
-
- free_server_info(&server_info);
+ pdb_free_sam(sampass);
return True;
}
@@ -533,19 +482,27 @@ succeeded authentication on named pipe %s, but session key was of incorrect leng
The switch table for the pipe names and the functions to handle them.
*******************************************************************/
-struct rpc_table
+struct api_cmd
{
- struct
- {
- const char *clnt;
- const char *srv;
- } pipe;
- struct api_struct *cmds;
- int n_cmds;
+ const char * pipe_clnt_name;
+ const char * pipe_srv_name;
+ BOOL (*fn) (pipes_struct *);
};
-static struct rpc_table *rpc_lookup;
-static int rpc_lookup_size;
+static struct api_cmd api_fd_commands[] =
+{
+ { "lsarpc", "lsass", api_ntlsa_rpc },
+ { "samr", "lsass", api_samr_rpc },
+ { "srvsvc", "ntsvcs", api_srvsvc_rpc },
+ { "wkssvc", "ntsvcs", api_wkssvc_rpc },
+ { "NETLOGON", "lsass", api_netlog_rpc },
+ { "winreg", "winreg", api_reg_rpc },
+ { "spoolss", "spoolss", api_spoolss_rpc },
+#ifdef WITH_MSDFS
+ { "netdfs", "netdfs" , api_netdfs_rpc },
+#endif
+ { NULL, NULL, NULL }
+};
/*******************************************************************
This is the client reply to our challenge for an authenticated
@@ -574,7 +531,7 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
return False;
}
- if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) {
+ if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) {
DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
(int)autha_info.auth_type, (int)autha_info.auth_level ));
return False;
@@ -744,111 +701,36 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
Used to reject unknown binds from Win2k.
*******************************************************************/
-BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
- RPC_IFACE* transfer, uint32 context_id)
+BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
+ RPC_IFACE* transfer)
{
extern struct pipe_id_info pipe_names[];
- char *pipe_name = p->name;
int i=0;
fstring pname;
-
fstrcpy(pname,"\\PIPE\\");
fstrcat(pname,pipe_name);
- DEBUG(3,("check_bind_req for %s\n", pname));
-
- /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
-
- for ( i=0; pipe_names[i].client_pipe; i++ )
- {
- if ( strequal(pipe_names[i].client_pipe, pname)
- && (abstract->version == pipe_names[i].abstr_syntax.version)
- && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0)
- && (transfer->version == pipe_names[i].trans_syntax.version)
- && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) )
- {
- struct api_struct *fns = NULL;
- int n_fns = 0;
- PIPE_RPC_FNS *context_fns;
-
- if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) {
- DEBUG(0,("check_bind_req: malloc() failed!\n"));
- return False;
- }
-
- /* save the RPC function table associated with this bind */
-
- get_pipe_fns(i, &fns, &n_fns);
-
- context_fns->cmds = fns;
- context_fns->n_cmds = n_fns;
- context_fns->context_id = context_id;
-
- /* add to the list of open contexts */
-
- DLIST_ADD( p->contexts, context_fns );
-
+ for(i=0;pipe_names[i].client_pipe; i++) {
+ if(strequal(pipe_names[i].client_pipe, pname))
break;
- }
}
if(pipe_names[i].client_pipe == NULL)
return False;
- return True;
-}
-
-/*******************************************************************
- Register commands to an RPC pipe
-*******************************************************************/
-NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
-{
- struct rpc_table *rpc_entry;
-
- if (!clnt || !srv || !cmds) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (version != SMB_RPC_INTERFACE_VERSION) {
- DEBUG(0,("Can't register rpc commands!\n"
- "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
- ", while this version of samba uses version %d!\n",
- version,SMB_RPC_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ /* check the abstract interface */
+ if((abstract->version != pipe_names[i].abstr_syntax.version) ||
+ (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid,
+ sizeof(RPC_UUID)) != 0))
+ return False;
- /* TODO:
- *
- * we still need to make sure that don't register the same commands twice!!!
- *
- * --metze
- */
+ /* check the transfer interface */
+ if((transfer->version != pipe_names[i].trans_syntax.version) ||
+ (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid,
+ sizeof(RPC_UUID)) != 0))
+ return False;
- /* We use a temporary variable because this call can fail and
- rpc_lookup will still be valid afterwards. It could then succeed if
- called again later */
- rpc_entry = realloc(rpc_lookup,
- ++rpc_lookup_size*sizeof(struct rpc_table));
- if (NULL == rpc_entry) {
- rpc_lookup_size--;
- DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
- return NT_STATUS_NO_MEMORY;
- } else {
- rpc_lookup = rpc_entry;
- }
-
- rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
- ZERO_STRUCTP(rpc_entry);
- rpc_entry->pipe.clnt = strdup(clnt);
- rpc_entry->pipe.srv = strdup(srv);
- rpc_entry->cmds = realloc(rpc_entry->cmds,
- (rpc_entry->n_cmds + size) *
- sizeof(struct api_struct));
- memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds,
- size * sizeof(struct api_struct));
- rpc_entry->n_cmds += size;
-
- return NT_STATUS_OK;
+ return True;
}
/*******************************************************************
@@ -870,7 +752,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
enum RPC_PKT_TYPE reply_pkt_type;
p->ntlmssp_auth_requested = False;
- p->netsec_auth_validated = False;
DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
@@ -879,38 +760,23 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
* that this is a pipe name we support.
*/
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
- DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
- break;
- }
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL) {
+ DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ api_fd_commands[i].pipe_clnt_name,
+ api_fd_commands[i].pipe_srv_name));
+ fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
+ break;
+ }
}
- if (i == rpc_lookup_size) {
- if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
- DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
- p->name ));
- if(!setup_bind_nak(p))
- return False;
- return True;
- }
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
- DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
- break;
- }
- }
-
- if (i == rpc_lookup_size) {
- DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
+ if (api_fd_commands[i].fn == NULL) {
+ DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
+ p->name ));
+ if(!setup_bind_nak(p))
return False;
- }
+ return True;
}
/* decode the bind request */
@@ -936,62 +802,39 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
return False;
}
- if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) {
-
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to "
- "unmarshall RPC_HDR_AUTH struct.\n"));
- return False;
- }
-
- if(!strequal(auth_verifier.signature, "NTLMSSP")) {
- DEBUG(0,("api_pipe_bind_req: "
- "auth_verifier.signature != NTLMSSP\n"));
- return False;
- }
-
- if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
- DEBUG(0,("api_pipe_bind_req: "
- "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
- auth_verifier.msg_type));
- return False;
- }
-
- if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: "
- "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
- return False;
- }
-
- p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
- p->ntlmssp_auth_requested = True;
-
- } else if (auth_info.auth_type == NETSEC_AUTH_TYPE) {
-
- RPC_AUTH_NETSEC_NEG neg;
- struct netsec_auth_struct *a = &(p->netsec_auth);
-
- if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: "
- "Could not unmarshal SCHANNEL auth neg\n"));
- return False;
- }
+ /*
+ * We only support NTLMSSP_AUTH_TYPE requests.
+ */
- p->netsec_auth_validated = True;
+ if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) {
+ DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
+ auth_info.auth_type ));
+ return False;
+ }
- memset(a->sess_key, 0, sizeof(a->sess_key));
- memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
+ if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+ return False;
+ }
- a->seq_num = 0;
+ if(!strequal(auth_verifier.signature, "NTLMSSP")) {
+ DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n"));
+ return False;
+ }
- DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
- neg.domain, neg.myname));
+ if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
+ DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
+ auth_verifier.msg_type));
+ return False;
+ }
- } else {
- DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
- auth_info.auth_type ));
+ if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
return False;
}
+
+ p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
+ p->ntlmssp_auth_requested = True;
}
switch(p->hdr.pkt_type) {
@@ -1057,8 +900,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
unknown to NT4)
Needed when adding entries to a DACL from NT5 - SK */
- if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id ))
- {
+ if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) {
init_rpc_hdr_ba(&hdr_ba,
MAX_PDU_FRAG_LEN,
MAX_PDU_FRAG_LEN,
@@ -1097,7 +939,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
/*** Authentication info ***/
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1);
+ init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1);
if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
goto err_exit;
@@ -1123,38 +965,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
}
- if (p->netsec_auth_validated) {
- RPC_AUTH_VERIFIER auth_verifier;
- uint32 flags;
-
- /* The client opens a second RPC NETLOGON pipe without
- doing a auth2. The credentials for the schannel are
- re-used from the auth2 the client did before. */
- p->dc = last_dcinfo;
-
- init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, auth_info.auth_level, RPC_HDR_AUTH_LEN, 1);
- if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
- goto err_exit;
- }
-
- /*** NETSEC verifier ***/
-
- init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
- if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
- goto err_exit;
- }
-
- prs_align(&out_auth);
-
- flags = 5;
- if(!prs_uint32("flags ", &out_auth, 0, &flags))
- goto err_exit;
-
- auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
- }
-
/*
* Create the header, now we know the length.
*/
@@ -1182,8 +992,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
goto err_exit;
}
- if((p->ntlmssp_auth_requested|p->netsec_auth_validated) &&
- !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+ if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
goto err_exit;
}
@@ -1253,14 +1062,7 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
* has already been consumed.
*/
char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN;
- dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
- sizeof(p->ntlmssp_hash));
-
- dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n",
- (const unsigned char *)data, data_len);
NTLMSSPcalc_p(p, (uchar*)data, data_len);
- dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n",
- (const unsigned char *)data, data_len);
crc32 = crc32_calc_buffer(data, data_len);
}
@@ -1323,98 +1125,6 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
}
/****************************************************************************
- Deal with schannel processing on an RPC request.
-****************************************************************************/
-BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
-{
- /*
- * We always negotiate the following two bits....
- */
- int data_len;
- int auth_len;
- uint32 old_offset;
- RPC_HDR_AUTH auth_info;
- RPC_AUTH_NETSEC_CHK netsec_chk;
-
-
- auth_len = p->hdr.auth_len;
-
- if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
- DEBUG(0,("Incorrect auth_len %d.\n", auth_len ));
- return False;
- }
-
- /*
- * The following is that length of the data we must verify or unseal.
- * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
- * preceeding the auth_data.
- */
-
- data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- RPC_HDR_AUTH_LEN - auth_len;
-
- DEBUG(5,("data %d auth %d\n", data_len, auth_len));
-
- old_offset = prs_offset(rpc_in);
-
- if(!prs_set_offset(rpc_in, old_offset + data_len)) {
- DEBUG(0,("cannot move offset to %u.\n",
- (unsigned int)old_offset + data_len ));
- return False;
- }
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
- DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n"));
- return False;
- }
-
- if (auth_info.auth_type != NETSEC_AUTH_TYPE) {
- DEBUG(0,("Invalid auth info %d on schannel\n",
- auth_info.auth_type));
- return False;
- }
-
- if (auth_info.auth_level == RPC_PIPE_AUTH_SEAL_LEVEL) {
- p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL;
- } else if (auth_info.auth_level == RPC_PIPE_AUTH_SIGN_LEVEL) {
- p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN;
- } else {
- DEBUG(0,("Invalid auth level %d on schannel\n",
- auth_info.auth_level));
- return False;
- }
-
- if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) {
- DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n"));
- return False;
- }
-
- if (!netsec_decode(&p->netsec_auth,
- p->netsec_auth.auth_flags,
- SENDER_IS_INITIATOR,
- &netsec_chk,
- prs_data_p(rpc_in)+old_offset, data_len)) {
- DEBUG(0,("failed to decode PDU\n"));
- return False;
- }
-
- /*
- * Return the current pointer to the data offset.
- */
-
- if(!prs_set_offset(rpc_in, old_offset)) {
- DEBUG(0,("failed to set offset back to %u\n",
- (unsigned int)old_offset ));
- return False;
- }
-
- /* The sequence number gets incremented on both send and receive. */
- p->netsec_auth.seq_num++;
-
- return True;
-}
-
-/****************************************************************************
Return a user struct for a pipe user.
****************************************************************************/
@@ -1431,48 +1141,6 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
}
/****************************************************************************
- Find the set of RPC functions associated with this context_id
-****************************************************************************/
-
-static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
-{
- PIPE_RPC_FNS *fns = NULL;
- PIPE_RPC_FNS *tmp = NULL;
-
- if ( !list ) {
- DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
- return NULL;
- }
-
- for (tmp=list; tmp; tmp=tmp->next ) {
- if ( tmp->context_id == context_id )
- break;
- }
-
- fns = tmp;
-
- return fns;
-}
-
-/****************************************************************************
- memory cleanup
-****************************************************************************/
-
-void free_pipe_rpc_context( PIPE_RPC_FNS *list )
-{
- PIPE_RPC_FNS *tmp = list;
- PIPE_RPC_FNS *tmp2;
-
- while (tmp) {
- tmp2 = tmp->next;
- SAFE_FREE(tmp);
- tmp = tmp2;
- }
-
- return;
-}
-
-/****************************************************************************
Find the correct RPC function to call for this request.
If the pipe is authenticated then become the correct UNIX user
before doing the call.
@@ -1480,9 +1148,9 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list )
BOOL api_pipe_request(pipes_struct *p)
{
+ int i = 0;
BOOL ret = False;
- PIPE_RPC_FNS *pipe_fns;
-
+
if (p->ntlmssp_auth_validated) {
if(!become_authenticated_pipe_user(p)) {
@@ -1491,23 +1159,17 @@ BOOL api_pipe_request(pipes_struct *p)
}
}
- DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
-
- /* get the set of RPC functions for this context */
-
- pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);
-
- if ( pipe_fns ) {
- set_current_rpc_talloc(p->mem_ctx);
- ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
- set_current_rpc_talloc(NULL);
- }
- else {
- DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
- p->hdr_req.context_id, p->name));
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL) {
+ DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+ set_current_rpc_talloc(p->mem_ctx);
+ ret = api_fd_commands[i].fn(p);
+ set_current_rpc_talloc(NULL);
+ }
}
- if(p->ntlmssp_auth_validated)
+ if (p->ntlmssp_auth_validated)
unbecome_authenticated_pipe_user();
return ret;
@@ -1518,7 +1180,7 @@ BOOL api_pipe_request(pipes_struct *p)
********************************************************************/
BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
- const struct api_struct *api_rpc_cmds, int n_cmds)
+ struct api_struct *api_rpc_cmds)
{
int fn_num;
fstring name;
@@ -1530,14 +1192,14 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
slprintf(name, sizeof(name)-1, "in_%s", rpc_name);
prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
- for (fn_num = 0; fn_num < n_cmds; fn_num++) {
+ for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
- DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));
+ DEBUG(3,("api_rpcTNP: pipe %u rpc command: %s\n", (unsigned int)p->pnum, api_rpc_cmds[fn_num].name));
break;
}
}
- if (fn_num == n_cmds) {
+ if (api_rpc_cmds[fn_num].name == NULL) {
/*
* For an unknown RPC just return a fault PDU but
* return True to allow RPC's on the pipe to continue
@@ -1550,8 +1212,6 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
offset1 = prs_offset(&p->out_data.rdata);
- DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
- fn_num, api_rpc_cmds[fn_num].fn));
/* do the actual command */
if(!api_rpc_cmds[fn_num].fn(p)) {
DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
@@ -1577,15 +1237,17 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
/* Check for buffer underflow in rpc parsing */
if ((DEBUGLEVEL >= 10) &&
- (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {
- size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);
+ (p->in_data.data.data_offset != p->in_data.data.buffer_size)) {
+ int data_len = p->in_data.data.buffer_size -
+ p->in_data.data.data_offset;
char *data;
data = malloc(data_len);
DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
if (data) {
- prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len);
+ prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data,
+ data_len);
SAFE_FREE(data);
}
@@ -1593,59 +1255,3 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
return True;
}
-
-/*******************************************************************
-*******************************************************************/
-
-void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
-{
- struct api_struct *cmds = NULL;
- int n_cmds = 0;
-
- switch ( idx ) {
- case PI_LSARPC:
- lsa_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_LSARPC_DS:
- lsa_ds_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_SAMR:
- samr_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_NETLOGON:
- netlog_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_SRVSVC:
- srvsvc_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_WKSSVC:
- wkssvc_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_WINREG:
- reg_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_SPOOLSS:
- spoolss_get_pipe_fns( &cmds, &n_cmds );
- break;
- case PI_NETDFS:
- netdfs_get_pipe_fns( &cmds, &n_cmds );
- break;
-#ifdef DEVELOPER
- case PI_ECHO:
- echo_get_pipe_fns( &cmds, &n_cmds );
- break;
-#endif
- case PI_EPM:
- epm_get_pipe_fns( &cmds, &n_cmds );
- break;
- default:
- DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));
- }
-
- *fns = cmds;
- *n_fns = n_cmds;
-
- return;
-}
-
-
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 9659f90d890..c5cad313cbf 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
@@ -20,15 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
-static smb_np_struct *chain_p;
+static pipes_struct *chain_p;
static int pipes_open;
/*
@@ -37,62 +37,28 @@ static int pipes_open;
* writers. This gets around a combination of bugs in the spooler
* and the HP 8500 PCL driver that causes a spooler spin. JRA.
*
- * bumped up from 20 -> 64 after viewing traffic from WordPerfect
+ * bumped up from 20 -> 64 after viewing traffic from WordPerfect
* 2002 running on NT 4.- SP6
- * bumped up from 64 -> 256 after viewing traffic from con2prt
- * for lots of printers on a WinNT 4.x SP6 box.
*/
-
+
#ifndef MAX_OPEN_SPOOLSS_PIPES
#define MAX_OPEN_SPOOLSS_PIPES 256
#endif
static int current_spoolss_pipes_open;
-static smb_np_struct *Pipes;
-static pipes_struct *InternalPipes;
+static pipes_struct *Pipes;
static struct bitmap *bmap;
-/* TODO
- * the following prototypes are declared here to avoid
- * code being moved about too much for a patch to be
- * disrupted / less obvious.
- *
- * these functions, and associated functions that they
- * call, should be moved behind a .so module-loading
- * system _anyway_. so that's the next step...
- */
-
-static ssize_t read_from_internal_pipe(void *np_conn, char *data, size_t n,
- BOOL *is_data_outstanding);
-static ssize_t write_to_internal_pipe(void *np_conn, char *data, size_t n);
-static BOOL close_internal_rpc_pipe_hnd(void *np_conn);
-static void *make_internal_rpc_pipe_p(char *pipe_name,
- connection_struct *conn, uint16 vuid);
-
/****************************************************************************
Pipe iterator functions.
****************************************************************************/
-smb_np_struct *get_first_pipe(void)
+pipes_struct *get_first_pipe(void)
{
return Pipes;
}
-smb_np_struct *get_next_pipe(smb_np_struct *p)
-{
- return p->next;
-}
-
-/****************************************************************************
- Internal Pipe iterator functions.
-****************************************************************************/
-
-pipes_struct *get_first_internal_pipe(void)
-{
- return InternalPipes;
-}
-
-pipes_struct *get_next_internal_pipe(pipes_struct *p)
+pipes_struct *get_next_pipe(pipes_struct *p)
{
return p->next;
}
@@ -115,7 +81,6 @@ void set_pipe_handle_offset(int max_open_files)
/****************************************************************************
Reset pipe chain handle number.
****************************************************************************/
-
void reset_chain_p(void)
{
chain_p = NULL;
@@ -166,11 +131,11 @@ static BOOL pipe_init_outgoing_data(pipes_struct *p)
Find first available pipe slot.
****************************************************************************/
-smb_np_struct *open_rpc_pipe_p(char *pipe_name,
+pipes_struct *open_rpc_pipe_p(char *pipe_name,
connection_struct *conn, uint16 vuid)
{
int i;
- smb_np_struct *p, *p_it;
+ pipes_struct *p;
static int next_pipe;
BOOL is_spoolss_pipe = False;
@@ -179,7 +144,7 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
if (strstr(pipe_name, "spoolss"))
is_spoolss_pipe = True;
-
+
if (is_spoolss_pipe && current_spoolss_pipes_open >= MAX_OPEN_SPOOLSS_PIPES) {
DEBUG(10,("open_rpc_pipe_p: spooler bug workaround. Denying open on pipe %s\n",
pipe_name ));
@@ -204,96 +169,14 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
for (p = Pipes; p; p = p->next)
DEBUG(5,("open_rpc_pipe_p: name %s pnum=%x\n", p->name, p->pnum));
- p = (smb_np_struct *)malloc(sizeof(*p));
-
- if (!p) {
- DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
- return NULL;
- }
-
- ZERO_STRUCTP(p);
-
- /* add a dso mechanism instead of this, here */
-
- p->namedpipe_create = make_internal_rpc_pipe_p;
- p->namedpipe_read = read_from_internal_pipe;
- p->namedpipe_write = write_to_internal_pipe;
- p->namedpipe_close = close_internal_rpc_pipe_hnd;
-
- p->np_state = p->namedpipe_create(pipe_name, conn, vuid);
-
- if (p->np_state == NULL) {
- DEBUG(0,("open_rpc_pipe_p: make_internal_rpc_pipe_p failed.\n"));
- SAFE_FREE(p);
- return NULL;
- }
-
- DLIST_ADD(Pipes, p);
-
- /*
- * Initialize the incoming RPC data buffer with one PDU worth of memory.
- * We cheat here and say we're marshalling, as we intend to add incoming
- * data directly into the prs_struct and we want it to auto grow. We will
- * change the type to UNMARSALLING before processing the stream.
- */
-
- bitmap_set(bmap, i);
- i += pipe_handle_offset;
-
- pipes_open++;
-
- p->pnum = i;
-
- p->open = True;
- p->device_state = 0;
- p->priority = 0;
- p->conn = conn;
- p->vuid = vuid;
-
- p->max_trans_reply = 0;
-
- fstrcpy(p->name, pipe_name);
-
- DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
- pipe_name, i, pipes_open));
-
- chain_p = p;
-
- /* Iterate over p_it as a temp variable, to display all open pipes */
- for (p_it = Pipes; p_it; p_it = p_it->next)
- DEBUG(5,("open pipes: name %s pnum=%x\n", p_it->name, p_it->pnum));
-
- return chain_p;
-}
-
-/****************************************************************************
- Make an internal namedpipes structure
-****************************************************************************/
-
-static void *make_internal_rpc_pipe_p(char *pipe_name,
- connection_struct *conn, uint16 vuid)
-{
- pipes_struct *p;
- user_struct *vuser = get_valid_user_struct(vuid);
-
- DEBUG(4,("Create pipe requested %s\n", pipe_name));
-
- if (!vuser && vuid != UID_FIELD_INVALID) {
- DEBUG(0,("ERROR! vuid %d did not map to a valid vuser struct!\n", vuid));
- return NULL;
- }
-
p = (pipes_struct *)malloc(sizeof(*p));
if (!p)
- {
- DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
return NULL;
- }
ZERO_STRUCTP(p);
- if ((p->mem_ctx = talloc_init("pipe %s %p", pipe_name, p)) == NULL) {
+ if ((p->mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
SAFE_FREE(p);
return NULL;
@@ -306,6 +189,9 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
return NULL;
}
+
+ DLIST_ADD(Pipes, p);
+
/*
* Initialize the incoming RPC data buffer with one PDU worth of memory.
* We cheat here and say we're marshalling, as we intend to add incoming
@@ -318,15 +204,21 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
return NULL;
}
- DLIST_ADD(InternalPipes, p);
+ bitmap_set(bmap, i);
+ i += pipe_handle_offset;
- p->conn = conn;
+ pipes_open++;
- /* Ensure the connection isn't idled whilst this pipe is open. */
- p->conn->num_files_open++;
+ p->pnum = i;
+ p->open = True;
+ p->device_state = 0;
+ p->priority = 0;
+ p->conn = conn;
p->vuid = vuid;
+ p->max_trans_reply = 0;
+
p->ntlmssp_chal_flags = 0;
p->ntlmssp_auth_validated = False;
p->ntlmssp_auth_requested = False;
@@ -335,19 +227,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
p->fault_state = False;
p->endian = RPC_LITTLE_ENDIAN;
- ZERO_STRUCT(p->pipe_user);
-
- p->pipe_user.uid = (uid_t)-1;
- p->pipe_user.gid = (gid_t)-1;
-
- /* Store the session key and NT_TOKEN */
- if (vuser) {
- p->session_key = data_blob(vuser->session_key.data, vuser->session_key.length);
- p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token);
- init_privilege(&p->pipe_user.privs);
- dup_priv_set(p->pipe_user.privs, vuser->privs);
- }
-
/*
* Initialize the incoming RPC struct.
*/
@@ -368,12 +247,31 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
*/
prs_init(&p->out_data.rdata, 0, p->mem_ctx, MARSHALL);
+ ZERO_STRUCT(p->pipe_user);
+
+ p->pipe_user.uid = (uid_t)-1;
+ p->pipe_user.gid = (gid_t)-1;
+
fstrcpy(p->name, pipe_name);
- DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
- pipe_name, pipes_open));
+ DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
+ pipe_name, i, pipes_open));
+
+ chain_p = p;
+
+ /* OVERWRITE p as a temp variable, to display all open pipes */
+ for (p = Pipes; p; p = p->next)
+ DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+
+ if (is_spoolss_pipe)
+ current_spoolss_pipes_open++;
+
+ /*
+ * The connection can be idled whilst this pipe is open
+ * if there are no handles open. JRA.
+ */
- return (void*)p;
+ return chain_p;
}
/****************************************************************************
@@ -386,8 +284,8 @@ static void set_incoming_fault(pipes_struct *p)
p->in_data.pdu_needed_len = 0;
p->in_data.pdu_received_len = 0;
p->fault_state = True;
- DEBUG(10,("set_incoming_fault: Setting fault state on pipe %s : vuid = 0x%x\n",
- p->name, p->vuid ));
+ DEBUG(10,("set_incoming_fault: Setting fault state on pipe %s : pnum = 0x%x\n",
+ p->name, p->pnum ));
}
/****************************************************************************
@@ -543,10 +441,10 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
void free_pipe_context(pipes_struct *p)
{
if (p->mem_ctx) {
- DEBUG(3,("free_pipe_context: destroying talloc pool of size %lu\n", (unsigned long)talloc_pool_size(p->mem_ctx) ));
+ DEBUG(3,("free_pipe_context: destroying talloc pool of size %u\n", talloc_pool_size(p->mem_ctx) ));
talloc_destroy_pool(p->mem_ctx);
} else {
- p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
+ p->mem_ctx = talloc_init();
if (p->mem_ctx == NULL)
p->fault_state = True;
}
@@ -596,27 +494,20 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
* Authentication _was_ requested and it already failed.
*/
- DEBUG(0,("process_request_pdu: RPC request received on pipe %s "
- "where authentication failed. Denying the request.\n",
- p->name));
+ DEBUG(0,("process_request_pdu: RPC request received on pipe %s where \
+authentication failed. Denying the request.\n", p->name));
set_incoming_fault(p);
- return False;
- }
-
- if (p->netsec_auth_validated && !api_pipe_netsec_process(p, rpc_in_p)) {
- DEBUG(0,("process_request_pdu: failed to do schannel processing.\n"));
- set_incoming_fault(p);
- return False;
- }
+ return False;
+ }
/*
- * Check the data length doesn't go over the 15Mb limit.
+ * Check the data length doesn't go over the 40Mb limit.
* increased after observing a bug in the Windows NT 4.0 SP6a
* spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
* will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
*/
- if(prs_offset(&p->in_data.data) + data_len > 15*1024*1024) {
+ if(prs_offset(&p->in_data.data) + data_len > 40*1024*1024) {
DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
(unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
set_incoming_fault(p);
@@ -627,11 +518,16 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
* Append the data portion into the buffer and return.
*/
- if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) {
- DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
- (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
- set_incoming_fault(p);
- return False;
+ {
+ char *data_from = prs_data_p(rpc_in_p) + prs_offset(rpc_in_p);
+
+ if(!prs_append_data(&p->in_data.data, data_from, data_len)) {
+ DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
+ (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
+ set_incoming_fault(p);
+ return False;
+ }
+
}
if(p->hdr.flags & RPC_FLG_LAST) {
@@ -774,7 +670,6 @@ static ssize_t process_complete_pdu(pipes_struct *p)
static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
{
size_t data_to_copy = MIN(n, MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
- size_t old_pdu_received_len = p->in_data.pdu_received_len;
DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
(unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
@@ -834,11 +729,10 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
/*
* Do we have a complete PDU ?
- * (return the nym of bytes handled in the call)
*/
if(p->in_data.pdu_received_len == p->in_data.pdu_needed_len)
- return process_complete_pdu(p) - old_pdu_received_len;
+ return process_complete_pdu(p);
DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
(unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
@@ -851,8 +745,10 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
Accepts incoming data on an rpc pipe.
****************************************************************************/
-ssize_t write_to_pipe(smb_np_struct *p, char *data, size_t n)
+ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
{
+ size_t data_left = n;
+
DEBUG(6,("write_to_pipe: %x", p->pnum));
DEBUG(6,(" name: %s open: %s len: %d\n",
@@ -860,18 +756,6 @@ ssize_t write_to_pipe(smb_np_struct *p, char *data, size_t n)
dump_data(50, data, n);
- return p->namedpipe_write(p->np_state, data, n);
-}
-
-/****************************************************************************
- Accepts incoming data on an internal rpc pipe.
-****************************************************************************/
-
-static ssize_t write_to_internal_pipe(void *np_conn, char *data, size_t n)
-{
- pipes_struct *p = (pipes_struct*)np_conn;
- size_t data_left = n;
-
while(data_left) {
ssize_t data_used;
@@ -902,42 +786,18 @@ static ssize_t write_to_internal_pipe(void *np_conn, char *data, size_t n)
have been prepared into arrays of headers + data stream sections.
****************************************************************************/
-ssize_t read_from_pipe(smb_np_struct *p, char *data, size_t n,
- BOOL *is_data_outstanding)
-{
- if (!p || !p->open) {
- DEBUG(0,("read_from_pipe: pipe not open\n"));
- return -1;
- }
-
- DEBUG(6,("read_from_pipe: %x", p->pnum));
-
- return p->namedpipe_read(p->np_state, data, n, is_data_outstanding);
-}
-
-/****************************************************************************
- Replies to a request to read data from a pipe.
-
- Headers are interspersed with the data at PDU intervals. By the time
- this function is called, the start of the data could possibly have been
- read by an SMBtrans (file_offset != 0).
-
- Calling create_rpc_reply() here is a hack. The data should already
- have been prepared into arrays of headers + data stream sections.
-****************************************************************************/
-
-static ssize_t read_from_internal_pipe(void *np_conn, char *data, size_t n,
- BOOL *is_data_outstanding)
+ssize_t read_from_pipe(pipes_struct *p, char *data, size_t n)
{
- pipes_struct *p = (pipes_struct*)np_conn;
uint32 pdu_remaining = 0;
ssize_t data_returned = 0;
- if (!p) {
+ if (!p || !p->open) {
DEBUG(0,("read_from_pipe: pipe not open\n"));
return -1;
}
+ DEBUG(6,("read_from_pipe: %x", p->pnum));
+
DEBUG(6,(" name: %s len: %u\n", p->name, (unsigned int)n));
/*
@@ -946,13 +806,13 @@ static ssize_t read_from_internal_pipe(void *np_conn, char *data, size_t n,
*/
/*
- * This condition should result in the connection being closed.
+ * This condition should result in the connection being closed.
* Netapp filers seem to set it to 0xffff which results in domain
* authentications failing. Just ignore it so things work.
*/
if(n > MAX_PDU_FRAG_LEN) {
- DEBUG(5,("read_from_pipe: too large read (%u) requested on \
+ DEBUG(5,("read_from_pipe: too large read (%u) requested on \
pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, MAX_PDU_FRAG_LEN ));
}
@@ -1012,7 +872,6 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
out:
- (*is_data_outstanding) = p->out_data.current_pdu_len > n;
return data_returned;
}
@@ -1020,7 +879,7 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
Wait device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
-BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
+BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
{
if (p == NULL)
return False;
@@ -1044,7 +903,7 @@ BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
Set device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
-BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state)
+BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
{
if (p == NULL)
return False;
@@ -1068,68 +927,41 @@ BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state)
Close an rpc pipe.
****************************************************************************/
-BOOL close_rpc_pipe_hnd(smb_np_struct *p)
+BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
{
if (!p) {
DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
return False;
}
- p->namedpipe_close(p->np_state);
-
- bitmap_clear(bmap, p->pnum - pipe_handle_offset);
-
- pipes_open--;
-
- DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
- p->name, p->pnum, pipes_open));
-
- DLIST_REMOVE(Pipes, p);
-
- ZERO_STRUCTP(p);
-
- SAFE_FREE(p);
-
- return True;
-}
-
-/****************************************************************************
- Close an rpc pipe.
-****************************************************************************/
-
-static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
-{
- pipes_struct *p = (pipes_struct *)np_conn;
- if (!p) {
- DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
- return False;
- }
+ if (strstr(p->name, "spoolss"))
+ current_spoolss_pipes_open--;
prs_mem_free(&p->out_data.rdata);
prs_mem_free(&p->in_data.data);
if (p->mem_ctx)
talloc_destroy(p->mem_ctx);
-
- free_pipe_rpc_context( p->contexts );
/* Free the handles database. */
close_policy_by_pipe(p);
- if (p->session_key.data != NULL)
- data_blob_free(&p->session_key);
+ bitmap_clear(bmap, p->pnum - pipe_handle_offset);
- delete_nt_token(&p->pipe_user.nt_user_token);
- SAFE_FREE(p->pipe_user.groups);
+ pipes_open--;
+
+ DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
+ p->name, p->pnum, pipes_open));
- DLIST_REMOVE(InternalPipes, p);
+ DLIST_REMOVE(Pipes, p);
- p->conn->num_files_open--;
+ delete_nt_token(&p->pipe_user.nt_user_token);
+ safe_free(p->pipe_user.groups);
ZERO_STRUCTP(p);
SAFE_FREE(p);
-
+
return True;
}
@@ -1137,7 +969,7 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
Find an rpc pipe given a pipe handle in a buffer and an offset.
****************************************************************************/
-smb_np_struct *get_rpc_pipe_p(char *buf, int where)
+pipes_struct *get_rpc_pipe_p(char *buf, int where)
{
int pnum = SVAL(buf,where);
@@ -1151,9 +983,9 @@ smb_np_struct *get_rpc_pipe_p(char *buf, int where)
Find an rpc pipe given a pipe handle.
****************************************************************************/
-smb_np_struct *get_rpc_pipe(int pnum)
+pipes_struct *get_rpc_pipe(int pnum)
{
- smb_np_struct *p;
+ pipes_struct *p;
DEBUG(4,("search for pipe pnum=%x\n", pnum));
diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c
index b780be0aff3..d9fa93206ac 100644
--- a/source/rpc_server/srv_reg.c
+++ b/source/rpc_server/srv_reg.c
@@ -1,13 +1,12 @@
-/*
- * Unix SMB/CIFS implementation.
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Marc Jacobsen 2000,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Gerald Carter 2002,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Marc Jacobsen 2000.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,9 +27,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*******************************************************************
api_reg_close
********************************************************************/
@@ -58,10 +54,10 @@ static BOOL api_reg_close(pipes_struct *p)
}
/*******************************************************************
- api_reg_open_khlm
+ api_reg_open
********************************************************************/
-static BOOL api_reg_open_hklm(pipes_struct *p)
+static BOOL api_reg_open(pipes_struct *p)
{
REG_Q_OPEN_HKLM q_u;
REG_R_OPEN_HKLM r_u;
@@ -75,7 +71,7 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
if(!reg_io_q_open_hklm("", &q_u, data, 0))
return False;
- r_u.status = _reg_open_hklm(p, &q_u, &r_u);
+ r_u.status = _reg_open(p, &q_u, &r_u);
if(!reg_io_r_open_hklm("", &r_u, rdata, 0))
return False;
@@ -84,59 +80,6 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
}
/*******************************************************************
- api_reg_open_khu
- ********************************************************************/
-
-static BOOL api_reg_open_hku(pipes_struct *p)
-{
- REG_Q_OPEN_HKU q_u;
- REG_R_OPEN_HKU r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the reg open */
- if(!reg_io_q_open_hku("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_open_hku(p, &q_u, &r_u);
-
- if(!reg_io_r_open_hku("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- api_reg_open_khcr
- ********************************************************************/
-
-static BOOL api_reg_open_hkcr(pipes_struct *p)
-{
- REG_Q_OPEN_HKCR q_u;
- REG_R_OPEN_HKCR r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the reg open */
- if(!reg_io_q_open_hkcr("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_open_hkcr(p, &q_u, &r_u);
-
- if(!reg_io_r_open_hkcr("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
api_reg_open_entry
********************************************************************/
@@ -189,6 +132,7 @@ static BOOL api_reg_info(pipes_struct *p)
return True;
}
+#if 0
/*******************************************************************
api_reg_shutdown
********************************************************************/
@@ -240,163 +184,29 @@ static BOOL api_reg_abort_shutdown(pipes_struct *p)
return True;
}
-
-
-/*******************************************************************
- api_reg_query_key
- ********************************************************************/
-
-static BOOL api_reg_query_key(pipes_struct *p)
-{
- REG_Q_QUERY_KEY q_u;
- REG_R_QUERY_KEY r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!reg_io_q_query_key("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_query_key(p, &q_u, &r_u);
-
- if(!reg_io_r_query_key("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- api_reg_unknown_1a
- ********************************************************************/
-
-static BOOL api_reg_unknown_1a(pipes_struct *p)
-{
- REG_Q_UNKNOWN_1A q_u;
- REG_R_UNKNOWN_1A r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!reg_io_q_unknown_1a("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_unknown_1a(p, &q_u, &r_u);
-
- if(!reg_io_r_unknown_1a("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- api_reg_enum_key
- ********************************************************************/
-
-static BOOL api_reg_enum_key(pipes_struct *p)
-{
- REG_Q_ENUM_KEY q_u;
- REG_R_ENUM_KEY r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!reg_io_q_enum_key("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_enum_key(p, &q_u, &r_u);
-
- if(!reg_io_r_enum_key("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- api_reg_enum_value
- ********************************************************************/
-
-static BOOL api_reg_enum_value(pipes_struct *p)
-{
- REG_Q_ENUM_VALUE q_u;
- REG_R_ENUM_VALUE r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!reg_io_q_enum_val("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_enum_value(p, &q_u, &r_u);
-
- if(!reg_io_r_enum_val("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- api_reg_save_key
- ********************************************************************/
-
-static BOOL api_reg_save_key(pipes_struct *p)
-{
- REG_Q_SAVE_KEY q_u;
- REG_R_SAVE_KEY r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!reg_io_q_save_key("", &q_u, data, 0))
- return False;
-
- r_u.status = _reg_save_key(p, &q_u, &r_u);
-
- if(!reg_io_r_save_key("", &r_u, rdata, 0))
- return False;
-
- return True;
-}
+#endif
/*******************************************************************
array of \PIPE\reg operations
********************************************************************/
-
static struct api_struct api_reg_cmds[] =
{
- { "REG_CLOSE" , REG_CLOSE , api_reg_close },
- { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
- { "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
- { "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
- { "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
- { "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },
- { "REG_ENUM_VALUE" , REG_ENUM_VALUE , api_reg_enum_value },
- { "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key },
- { "REG_INFO" , REG_INFO , api_reg_info },
- { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },
- { "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown },
- { "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a },
- { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }
+ { "REG_CLOSE" , REG_CLOSE , api_reg_close },
+ { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
+ { "REG_OPEN" , REG_OPEN_HKLM , api_reg_open },
+ { "REG_INFO" , REG_INFO , api_reg_info },
+#if 0
+ { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },
+ { "REG_ABORT_SHUTDOWN", REG_ABORT_SHUTDOWN, api_reg_abort_shutdown },
+#endif
+ { NULL, 0 , NULL }
};
-void reg_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_reg_cmds;
- *n_fns = sizeof(api_reg_cmds) / sizeof(struct api_struct);
-}
-
-NTSTATUS rpc_reg_init(void)
-{
+/*******************************************************************
+ receives a reg pipe and responds.
+ ********************************************************************/
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "winreg", "winreg", api_reg_cmds,
- sizeof(api_reg_cmds) / sizeof(struct api_struct));
+BOOL api_reg_rpc(pipes_struct *p)
+{
+ return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds);
}
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index a4e3638be60..cc071757b5e 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -1,11 +1,12 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 2001.
- * Copyright (C) Gerald Carter 2002.
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Hewlett-Packard Company 1999.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,254 +27,21 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-#define REGSTR_PRODUCTTYPE "ProductType"
-#define REG_PT_WINNT "WinNT"
-#define REG_PT_LANMANNT "LanmanNT"
-#define REG_PT_SERVERNT "ServerNT"
-
-#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
-((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
-
-
-static REGISTRY_KEY *regkeys_list;
-
-
-/******************************************************************
- free() function for REGISTRY_KEY
- *****************************************************************/
-
-static void free_regkey_info(void *ptr)
+struct reg_info
{
- REGISTRY_KEY *info = (REGISTRY_KEY*)ptr;
-
- DLIST_REMOVE(regkeys_list, info);
-
- SAFE_FREE(info);
-}
+ /* for use by \PIPE\winreg */
+ fstring name; /* name of registry key */
+};
-/******************************************************************
- Find a registry key handle and return a REGISTRY_KEY
- *****************************************************************/
-
-static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
+static void free_reg_info(void *ptr)
{
- REGISTRY_KEY *regkey = NULL;
-
- if(!find_policy_by_hnd(p,hnd,(void **)&regkey)) {
- DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
- return NULL;
- }
-
- return regkey;
-}
+ struct reg_info *info = (struct reg_info *)ptr;
-
-/*******************************************************************
- Function for open a new registry handle and creating a handle
- Note that P should be valid & hnd should already have space
-
- When we open a key, we store the full path to the key as
- HK[LM|U]\<key>\<key>\...
- *******************************************************************/
-
-static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent,
- const char *subkeyname, uint32 access_granted )
-{
- REGISTRY_KEY *regkey = NULL;
- NTSTATUS result = NT_STATUS_OK;
- REGSUBKEY_CTR subkeys;
- pstring subkeyname2;
- int subkey_len;
-
- DEBUG(7,("open_registry_key: name = [%s][%s]\n",
- parent ? parent->name : "NULL", subkeyname));
-
- /* strip any trailing '\'s */
- pstrcpy( subkeyname2, subkeyname );
- subkey_len = strlen ( subkeyname2 );
- if ( subkey_len && subkeyname2[subkey_len-1] == '\\' )
- subkeyname2[subkey_len-1] = '\0';
-
- if ((regkey=(REGISTRY_KEY*)malloc(sizeof(REGISTRY_KEY))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP( regkey );
-
- /*
- * very crazy, but regedit.exe on Win2k will attempt to call
- * REG_OPEN_ENTRY with a keyname of "". We should return a new
- * (second) handle here on the key->name. regedt32.exe does
- * not do this stupidity. --jerry
- */
-
- if ( !subkey_len ) {
- pstrcpy( regkey->name, parent->name );
- }
- else {
- pstrcpy( regkey->name, "" );
- if ( parent ) {
- pstrcat( regkey->name, parent->name );
- pstrcat( regkey->name, "\\" );
- }
- pstrcat( regkey->name, subkeyname2 );
- }
-
- /* Look up the table of registry I/O operations */
-
- if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) {
- DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
- regkey->name ));
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* check if the path really exists; failed is indicated by -1 */
- /* if the subkey count failed, bail out */
-
- ZERO_STRUCTP( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
-
- if ( fetch_reg_keys( regkey, &subkeys ) == -1 ) {
-
- /* don't really know what to return here */
- result = NT_STATUS_NO_SUCH_FILE;
- }
- else {
- /*
- * This would previously return NT_STATUS_TOO_MANY_SECRETS
- * that doesn't sound quite right to me --jerry
- */
-
- if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) )
- result = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- /* clean up */
-
- regsubkey_ctr_destroy( &subkeys );
-
- if ( ! NT_STATUS_IS_OK(result) )
- SAFE_FREE( regkey );
- else
- DLIST_ADD( regkeys_list, regkey );
-
-
- DEBUG(7,("open_registry_key: exit\n"));
-
- return result;
+ SAFE_FREE(info);
}
/*******************************************************************
- Function for open a new registry handle and creating a handle
- Note that P should be valid & hnd should already have space
- *******************************************************************/
-
-static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
-{
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd(p, hnd);
-
- if ( !regkey ) {
- DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
- return False;
- }
-
- close_policy_hnd(p, hnd);
-
- return True;
-}
-
-/********************************************************************
- retrieve information about the subkeys
- *******************************************************************/
-
-static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen )
-{
- int num_subkeys, i;
- uint32 max_len;
- REGSUBKEY_CTR subkeys;
- uint32 len;
-
- if ( !key )
- return False;
-
- ZERO_STRUCTP( &subkeys );
-
- regsubkey_ctr_init( &subkeys );
-
- if ( fetch_reg_keys( key, &subkeys ) == -1 )
- return False;
-
- /* find the longest string */
-
- max_len = 0;
- num_subkeys = regsubkey_ctr_numkeys( &subkeys );
-
- for ( i=0; i<num_subkeys; i++ ) {
- len = strlen( regsubkey_ctr_specific_key(&subkeys, i) );
- max_len = MAX(max_len, len);
- }
-
- *maxnum = num_subkeys;
- *maxlen = max_len*2;
-
- regsubkey_ctr_destroy( &subkeys );
-
- return True;
-}
-
-/********************************************************************
- retrieve information about the values. We don't store values
- here. The registry tdb is intended to be a frontend to oether
- Samba tdb's (such as ntdrivers.tdb).
- *******************************************************************/
-
-static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
- uint32 *maxlen, uint32 *maxsize )
-{
- REGVAL_CTR values;
- REGISTRY_VALUE *val;
- uint32 sizemax, lenmax;
- int i, num_values;
-
- if ( !key )
- return False;
-
-
- ZERO_STRUCTP( &values );
-
- regval_ctr_init( &values );
-
- if ( fetch_reg_values( key, &values ) == -1 )
- return False;
-
- lenmax = sizemax = 0;
- num_values = regval_ctr_numvals( &values );
-
- val = regval_ctr_specific_value( &values, 0 );
-
- for ( i=0; i<num_values && val; i++ )
- {
- lenmax = MAX(lenmax, strlen(val->valuename)+1 );
- sizemax = MAX(sizemax, val->size );
-
- val = regval_ctr_specific_value( &values, i );
- }
-
- *maxnum = num_values;
- *maxlen = lenmax;
- *maxsize = sizemax;
-
- regval_ctr_destroy( &values );
-
- return True;
-}
-
-
-/********************************************************************
- reg_close
+ reg_reply_unknown_1
********************************************************************/
NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
@@ -282,34 +50,22 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
ZERO_STRUCT(r_u->pol);
/* close the policy handle */
- if (!close_registry_key(p, &q_u->pol))
+ if (!close_policy_hnd(p, &q_u->pol))
return NT_STATUS_OBJECT_NAME_INVALID;
return NT_STATUS_OK;
}
/*******************************************************************
+ reg_reply_open
********************************************************************/
-NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
-{
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 );
-}
-
-/*******************************************************************
- ********************************************************************/
-
-NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
+NTSTATUS _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
{
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
-}
-
-/*******************************************************************
- ********************************************************************/
+ if (!create_policy_hnd(p, &r_u->pol, free_reg_info, NULL))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
-{
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 );
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -320,21 +76,34 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
{
POLICY_HND pol;
fstring name;
- REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->pol);
- NTSTATUS result;
+ struct reg_info *info = NULL;
- DEBUG(5,("reg_open_entry: Enter\n"));
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
- if ( !key )
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
-
- result = open_registry_key( p, &pol, key, name, 0x0 );
-
- init_reg_r_open_entry( r_u, &pol, result );
+ fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));
- DEBUG(5,("reg_open_entry: Exit\n"));
+ DEBUG(5,("reg_open_entry: %s\n", name));
+
+ /* lkcl XXXX do a check on the name, here */
+ if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") &&
+ !strequal(name, "System\\CurrentControlSet\\services\\Netlogon\\parameters\\"))
+ return NT_STATUS_ACCESS_DENIED;
+
+ if ((info = (struct reg_info *)malloc(sizeof(struct reg_info))) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ ZERO_STRUCTP(info);
+ fstrcpy(info->name, name);
+
+ if (!create_policy_hnd(p, &pol, free_reg_info, (void *)info))
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+
+ init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK);
+
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
return r_u->status;
}
@@ -345,320 +114,64 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
- NTSTATUS status = NT_STATUS_NO_SUCH_FILE;
- fstring name;
- const char *value_ascii = "";
- fstring value;
- int value_length;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
- REGISTRY_VALUE *val = NULL;
- REGVAL_CTR regvals;
- int i;
-
- DEBUG(5,("_reg_info: Enter\n"));
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
-
- rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
-
- DEBUG(5,("reg_info: looking up value: [%s]\n", name));
-
- ZERO_STRUCTP( &regvals );
-
- regval_ctr_init( &regvals );
-
- /* couple of hard coded registry values */
-
- if ( strequal(name, "RefusePasswordChange") ) {
- if ( (val = (REGISTRY_VALUE*)malloc(sizeof(REGISTRY_VALUE))) == NULL ) {
- DEBUG(0,("_reg_info: malloc() failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
- ZERO_STRUCTP( val );
-
- goto out;
- }
+ NTSTATUS status = NT_STATUS_OK;
+ const char *key = NULL;
+ uint32 type=0x1; /* key type: REG_SZ */
- if ( strequal(name, REGSTR_PRODUCTTYPE) ) {
- /* This makes the server look like a member server to clients */
- /* which tells clients that we have our own local user and */
- /* group databases and helps with ACL support. */
-
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- value_ascii = REG_PT_LANMANNT;
- break;
- case ROLE_STANDALONE:
- value_ascii = REG_PT_SERVERNT;
- break;
- case ROLE_DOMAIN_MEMBER:
- value_ascii = REG_PT_WINNT;
- break;
- }
- value_length = push_ucs2(value, value, value_ascii,
- sizeof(value),
- STR_TERMINATE|STR_NOALIGN);
- regval_ctr_addvalue(&regvals, REGSTR_PRODUCTTYPE, REG_SZ,
- value, value_length);
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 0 ) );
-
- status = NT_STATUS_OK;
-
- goto out;
- }
+ UNISTR2 *uni_key = NULL;
+ BUFFER2 *buf = NULL;
+ fstring name;
- /* else fall back to actually looking up the value */
-
- for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
- {
- DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
- if ( StrCaseCmp( val->valuename, name ) == 0 ) {
- DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
- status = NT_STATUS_OK;
- break;
- }
-
- free_registry_value( val );
- }
+ DEBUG(5,("_reg_info: %d\n", __LINE__));
-
-out:
- new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
-
- regval_ctr_destroy( &regvals );
- free_registry_value( val );
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
- DEBUG(5,("_reg_info: Exit\n"));
+ fstrcpy(name, dos_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len));
- return status;
-}
+ DEBUG(5,("reg_info: checking key: %s\n", name));
+ uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2));
+ buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2));
-/*****************************************************************************
- Implementation of REG_QUERY_KEY
- ****************************************************************************/
-
-NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
-
- DEBUG(5,("_reg_query_key: Enter\n"));
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) )
- return NT_STATUS_ACCESS_DENIED;
-
- if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) )
- return NT_STATUS_ACCESS_DENIED;
+ if (!uni_key || !buf)
+ return NT_STATUS_NO_MEMORY;
+ if ( strequal(name, "RefusePasswordChange") ) {
+ type=0xF770;
+ status = NT_STATUS_NO_SUCH_FILE;
+ init_unistr2(uni_key, "", 0);
+ init_buffer2(buf, (uint8*) uni_key->buffer, uni_key->uni_str_len*2);
- r_u->sec_desc = 0x00000078; /* size for key's sec_desc */
-
- /* Win9x set this to 0x0 since it does not keep timestamps.
- Doing the same here for simplicity --jerry */
-
- ZERO_STRUCT(r_u->mod_time);
-
- DEBUG(5,("_reg_query_key: Exit\n"));
-
- return status;
-}
-
-
-/*****************************************************************************
- Implementation of REG_UNKNOWN_1A
- ****************************************************************************/
-
-NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
-
- DEBUG(5,("_reg_unknown_1a: Enter\n"));
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- r_u->unknown = 0x00000005; /* seems to be consistent...no idea what it means */
-
- DEBUG(5,("_reg_unknown_1a: Exit\n"));
-
- return status;
-}
-
-
-/*****************************************************************************
- Implementation of REG_ENUM_KEY
- ****************************************************************************/
-
-NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
- char *subkey = NULL;
-
-
- DEBUG(5,("_reg_enum_key: Enter\n"));
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name));
-
- if ( !fetch_reg_keys_specific( regkey, &subkey, q_u->key_index ) )
- {
- status = NT_STATUS_NO_MORE_ENTRIES;
- goto done;
- }
-
- DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n", subkey));
-
- /* subkey has the string name now */
-
- init_reg_r_enum_key( r_u, subkey, q_u->unknown_1, q_u->unknown_2 );
-
- DEBUG(5,("_reg_enum_key: Exit\n"));
-
-done:
- SAFE_FREE( subkey );
- return status;
-}
+ buf->buf_max_len=4;
-/*****************************************************************************
- Implementation of REG_ENUM_VALUE
- ****************************************************************************/
-
-NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
- REGISTRY_VALUE *val;
-
-
- DEBUG(5,("_reg_enum_value: Enter\n"));
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
-
- if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
- {
- status = NT_STATUS_NO_MORE_ENTRIES;
- goto done;
+ goto out;
}
-
- DEBUG(10,("_reg_enum_value: retrieved value named [%s]\n", val->valuename));
-
- /* subkey has the string name now */
-
- init_reg_r_enum_val( r_u, val );
-
-
- DEBUG(5,("_reg_enum_value: Exit\n"));
-
-done:
- free_registry_value( val );
-
- return status;
-}
-
-/*******************************************************************
- reg_shutdwon
- ********************************************************************/
-
-#define SHUTDOWN_R_STRING "-r"
-#define SHUTDOWN_F_STRING "-f"
-
-
-NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- pstring shutdown_script;
- UNISTR2 unimsg = q_u->uni_msg;
- pstring message;
- pstring chkmsg;
- fstring timeout;
- fstring r;
- fstring f;
-
- /* message */
- rpcstr_pull (message, unimsg.buffer, sizeof(message), unimsg.uni_str_len*2,0);
- /* security check */
- alpha_strcpy (chkmsg, message, NULL, sizeof(message));
- /* timeout */
- fstr_sprintf(timeout, "%d", q_u->timeout);
- /* reboot */
- fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
- /* force */
- fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
-
- pstrcpy(shutdown_script, lp_shutdown_script());
-
- if(*shutdown_script) {
- int shutdown_ret;
- all_string_sub(shutdown_script, "%m", chkmsg, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%t", timeout, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%r", r, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%f", f, sizeof(shutdown_script));
- shutdown_ret = smbrun(shutdown_script,NULL);
- DEBUG(3,("_reg_shutdown: Running the command `%s' gave %d\n",shutdown_script,shutdown_ret));
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ key = "LanmanNT";
+ break;
+ case ROLE_STANDALONE:
+ key = "ServerNT";
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ key = "WinNT";
+ break;
}
- return status;
-}
-
-/*******************************************************************
- reg_abort_shutdwon
- ********************************************************************/
-
-NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
-{
- NTSTATUS status = NT_STATUS_OK;
- pstring abort_shutdown_script;
+ /* This makes the server look like a member server to clients */
+ /* which tells clients that we have our own local user and */
+ /* group databases and helps with ACL support. */
- pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
+ init_unistr2(uni_key, key, strlen(key)+1);
+ init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2);
+
+ out:
+ init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status);
- if(*abort_shutdown_script) {
- int abort_shutdown_ret;
- abort_shutdown_ret = smbrun(abort_shutdown_script,NULL);
- DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",abort_shutdown_script,abort_shutdown_ret));
- }
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
return status;
}
-
-/*******************************************************************
- REG_SAVE_KEY (0x14)
- ********************************************************************/
-
-NTSTATUS _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u)
-{
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
-
- DEBUG(5,("_reg_save_key: Enter\n"));
-
- /*
- * basically this is a no op function which just gverifies
- * that the client gave us a valid registry key handle
- */
-
- if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(8,("_reg_save_key: berifying backup of key [%s]\n", regkey->name));
-
-
- return NT_STATUS_OK;
-}
-
-
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index 971f5ed40ce..0d2e4a81e66 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -1,12 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Marc Jacobsen 1999,
- * Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Marc Jacobsen 1999.
*
* Split into interface and implementation modules by,
*
@@ -33,9 +32,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*******************************************************************
api_samr_close_hnd
********************************************************************/
@@ -112,52 +108,18 @@ static BOOL api_samr_get_usrdom_pwinfo(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_get_usrdom_pwinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_get_usrdom_pwinfo: unable to unmarshall SAMR_Q_GET_USRDOM_PWINFO.\n"));
+ if(!samr_io_q_get_usrdom_pwinfo("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_get_usrdom_pwinfo(p, &q_u, &r_u);
- if(!samr_io_r_get_usrdom_pwinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_get_usrdom_pwinfo: unable to marshall SAMR_R_GET_USRDOM_PWINFO.\n"));
+ if(!samr_io_r_get_usrdom_pwinfo("", &r_u, rdata, 0))
return False;
- }
return True;
}
/*******************************************************************
- api_samr_set_sec_obj
- ********************************************************************/
-
-static BOOL api_samr_set_sec_obj(pipes_struct *p)
-{
- SAMR_Q_SET_SEC_OBJ q_u;
- SAMR_R_SET_SEC_OBJ r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!samr_io_q_set_sec_obj("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_set_sec_obj: unable to unmarshall SAMR_Q_SET_SEC_OBJ.\n"));
- return False;
- }
-
- r_u.status = _samr_set_sec_obj(p, &q_u, &r_u);
-
- if(!samr_io_r_set_sec_obj("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_set_sec_obj: unable to marshall SAMR_R_SET_SEC_OBJ.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
api_samr_query_sec_obj
********************************************************************/
@@ -172,17 +134,13 @@ static BOOL api_samr_query_sec_obj(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_query_sec_obj("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_sec_obj: unable to unmarshall SAMR_Q_QUERY_SEC_OBJ.\n"));
+ if(!samr_io_q_query_sec_obj("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_sec_obj(p, &q_u, &r_u);
- if(!samr_io_r_query_sec_obj("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_sec_obj: unable to marshall SAMR_R_QUERY_SEC_OBJ.\n"));
+ if(!samr_io_r_query_sec_obj("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -202,18 +160,14 @@ static BOOL api_samr_enum_dom_users(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open */
- if(!samr_io_q_enum_dom_users("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_enum_dom_users: unable to unmarshall SAMR_Q_ENUM_DOM_USERS.\n"));
+ if(!samr_io_q_enum_dom_users("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_enum_dom_users(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_enum_dom_users("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_enum_dom_users: unable to marshall SAMR_R_ENUM_DOM_USERS.\n"));
+ if(!samr_io_r_enum_dom_users("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -233,18 +187,14 @@ static BOOL api_samr_enum_dom_groups(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open */
- if(!samr_io_q_enum_dom_groups("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_enum_dom_groups: unable to unmarshall SAMR_Q_ENUM_DOM_GROUPS.\n"));
+ if(!samr_io_q_enum_dom_groups("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_enum_dom_groups(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_enum_dom_groups("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_enum_dom_groups: unable to marshall SAMR_R_ENUM_DOM_GROUPS.\n"));
+ if(!samr_io_r_enum_dom_groups("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -264,18 +214,14 @@ static BOOL api_samr_enum_dom_aliases(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open */
- if(!samr_io_q_enum_dom_aliases("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_enum_dom_aliases: unable to unmarshall SAMR_Q_ENUM_DOM_ALIASES.\n"));
+ if(!samr_io_q_enum_dom_aliases("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_enum_dom_aliases(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_enum_dom_aliases("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_enum_dom_aliases: unable to marshall SAMR_R_ENUM_DOM_ALIASES.\n"));
+ if(!samr_io_r_enum_dom_aliases("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -294,18 +240,14 @@ static BOOL api_samr_query_dispinfo(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_query_dispinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_dispinfo: unable to unmarshall SAMR_Q_QUERY_DISPINFO.\n"));
+ if(!samr_io_q_query_dispinfo("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_dispinfo(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_query_dispinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_dispinfo: unable to marshall SAMR_R_QUERY_DISPINFO.\n"));
+ if(!samr_io_r_query_dispinfo("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -325,18 +267,14 @@ static BOOL api_samr_query_aliasinfo(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open */
- if(!samr_io_q_query_aliasinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_aliasinfo: unable to unmarshall SAMR_Q_QUERY_ALIASINFO.\n"));
+ if(!samr_io_q_query_aliasinfo("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_aliasinfo(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_query_aliasinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_aliasinfo: unable to marshall SAMR_R_QUERY_ALIASINFO.\n"));
+ if(!samr_io_r_query_aliasinfo("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -356,18 +294,14 @@ static BOOL api_samr_lookup_names(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr lookup names */
- if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_lookup_names: unable to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
+ if(!samr_io_q_lookup_names("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_lookup_names(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_lookup_names: unable to marshall SAMR_R_LOOKUP_NAMES.\n"));
+ if(!samr_io_r_lookup_names("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -386,7 +320,7 @@ static BOOL api_samr_chgpasswd_user(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- /* change password request */
+ /* unknown 38 command */
if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
DEBUG(0,("api_samr_chgpasswd_user: Failed to unmarshall SAMR_Q_CHGPASSWD_USER.\n"));
return False;
@@ -418,18 +352,14 @@ static BOOL api_samr_lookup_rids(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr lookup names */
- if(!samr_io_q_lookup_rids("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_lookup_rids: unable to unmarshall SAMR_Q_LOOKUP_RIDS.\n"));
+ if(!samr_io_q_lookup_rids("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_lookup_rids(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_lookup_rids("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_lookup_rids: unable to marshall SAMR_R_LOOKUP_RIDS.\n"));
+ if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -448,18 +378,17 @@ static BOOL api_samr_open_user(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_open_user("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_open_user: unable to unmarshall SAMR_Q_OPEN_USER.\n"));
+ /* grab the samr unknown 22 */
+ if(!samr_io_q_open_user("", &q_u, data, 0))
return False;
- }
- r_u.status = _samr_open_user(p, &q_u, &r_u);
+ r_u.status = _api_samr_open_user(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_open_user("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_open_user: unable to marshall SAMR_R_OPEN_USER.\n"));
+ if(!samr_io_r_open_user("", &r_u, rdata, 0))
return False;
- }
+
+ DEBUG(5,("samr_open_user: %d\n", __LINE__));
return True;
}
@@ -478,18 +407,15 @@ static BOOL api_samr_query_userinfo(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_query_userinfo("", &q_u, data, 0)){
- DEBUG(0,("api_samr_query_userinfo: unable to unmarshall SAMR_Q_QUERY_USERINFO.\n"));
+ /* grab the samr unknown 24 */
+ if(!samr_io_q_query_userinfo("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_userinfo(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_query_userinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_userinfo: unable to marshall SAMR_R_QUERY_USERINFO.\n"));
+ if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -508,16 +434,14 @@ static BOOL api_samr_query_usergroups(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_query_usergroups("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_usergroups: unable to unmarshall SAMR_Q_QUERY_USERGROUPS.\n"));
+ /* grab the samr unknown 32 */
+ if(!samr_io_q_query_usergroups("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_usergroups(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_usergroups: unable to marshall SAMR_R_QUERY_USERGROUPS.\n"));
return False;
}
@@ -538,18 +462,17 @@ static BOOL api_samr_query_dom_info(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!samr_io_q_query_dom_info("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_dom_info: unable to unmarshall SAMR_Q_QUERY_DOMAIN_INFO.\n"));
+ /* grab the samr unknown 8 command */
+ if(!samr_io_q_query_dom_info("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_query_dom_info(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_query_dom_info("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_dom_info: unable to marshall SAMR_R_QUERY_DOMAIN_INFO.\n"));
+ if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
return False;
- }
+
+ DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
return True;
}
@@ -575,7 +498,7 @@ static BOOL api_samr_create_user(pipes_struct *p)
return False;
}
- r_u.status=_samr_create_user(p, &q_u, &r_u);
+ r_u.status=_api_samr_create_user(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_create_user("", &r_u, rdata, 0)) {
@@ -601,18 +524,14 @@ static BOOL api_samr_connect_anon(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open policy */
- if(!samr_io_q_connect_anon("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_connect_anon: unable to unmarshall SAMR_Q_CONNECT_ANON.\n"));
+ if(!samr_io_q_connect_anon("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_connect_anon(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_connect_anon("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_connect_anon: unable to marshall SAMR_R_CONNECT_ANON.\n"));
+ if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -632,49 +551,14 @@ static BOOL api_samr_connect(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the samr open policy */
- if(!samr_io_q_connect("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_connect: unable to unmarshall SAMR_Q_CONNECT.\n"));
+ if(!samr_io_q_connect("", &q_u, data, 0))
return False;
- }
r_u.status = _samr_connect(p, &q_u, &r_u);
/* store the response in the SMB stream */
- if(!samr_io_r_connect("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_connect: unable to marshall SAMR_R_CONNECT.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- api_samr_connect4
- ********************************************************************/
-
-static BOOL api_samr_connect4(pipes_struct *p)
-{
- SAMR_Q_CONNECT4 q_u;
- SAMR_R_CONNECT4 r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the samr open policy */
- if(!samr_io_q_connect4("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_connect4: unable to unmarshall SAMR_Q_CONNECT4.\n"));
- return False;
- }
-
- r_u.status = _samr_connect4(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!samr_io_r_connect4("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_connect4: unable to marshall SAMR_R_CONNECT4.\n"));
+ if(!samr_io_r_connect("", &r_u, rdata, 0))
return False;
- }
return True;
}
@@ -757,7 +641,7 @@ static BOOL api_samr_open_alias(pipes_struct *p)
return False;
}
- r_u.status=_samr_open_alias(p, &q_u, &r_u);
+ r_u.status=_api_samr_open_alias(p, &q_u, &r_u);
/* store the response in the SMB stream */
if(!samr_io_r_open_alias("", &r_u, rdata, 0)) {
@@ -878,14 +762,12 @@ static BOOL api_samr_query_aliasmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_query_aliasmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_aliasmem: unable to unmarshall SAMR_Q_QUERY_ALIASMEM.\n"));
return False;
}
r_u.status = _samr_query_aliasmem(p, &q_u, &r_u);
if (!samr_io_r_query_aliasmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_aliasmem: unable to marshall SAMR_R_QUERY_ALIASMEM.\n"));
return False;
}
@@ -908,14 +790,12 @@ static BOOL api_samr_query_groupmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_query_groupmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_groupmem: unable to unmarshall SAMR_Q_QUERY_GROUPMEM.\n"));
return False;
}
r_u.status = _samr_query_groupmem(p, &q_u, &r_u);
if (!samr_io_r_query_groupmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_groupmem: unable to marshall SAMR_R_QUERY_GROUPMEM.\n"));
return False;
}
@@ -938,14 +818,12 @@ static BOOL api_samr_add_aliasmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_add_aliasmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_add_aliasmem: unable to unmarshall SAMR_Q_ADD_ALIASMEM.\n"));
return False;
}
r_u.status = _samr_add_aliasmem(p, &q_u, &r_u);
if (!samr_io_r_add_aliasmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_add_aliasmem: unable to marshall SAMR_R_ADD_ALIASMEM.\n"));
return False;
}
@@ -968,14 +846,12 @@ static BOOL api_samr_del_aliasmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_del_aliasmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_del_aliasmem: unable to unmarshall SAMR_Q_DEL_ALIASMEM.\n"));
return False;
}
r_u.status = _samr_del_aliasmem(p, &q_u, &r_u);
if (!samr_io_r_del_aliasmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_del_aliasmem: unable to marshall SAMR_R_DEL_ALIASMEM.\n"));
return False;
}
@@ -998,14 +874,12 @@ static BOOL api_samr_add_groupmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_add_groupmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_add_groupmem: unable to unmarshall SAMR_Q_ADD_GROUPMEM.\n"));
return False;
}
r_u.status = _samr_add_groupmem(p, &q_u, &r_u);
if (!samr_io_r_add_groupmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_add_groupmem: unable to marshall SAMR_R_ADD_GROUPMEM.\n"));
return False;
}
@@ -1028,14 +902,12 @@ static BOOL api_samr_del_groupmem(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_del_groupmem("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_del_groupmem: unable to unmarshall SAMR_Q_DEL_GROUPMEM.\n"));
return False;
}
r_u.status = _samr_del_groupmem(p, &q_u, &r_u);
if (!samr_io_r_del_groupmem("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_del_groupmem: unable to marshall SAMR_R_DEL_GROUPMEM.\n"));
return False;
}
@@ -1058,14 +930,12 @@ static BOOL api_samr_delete_dom_user(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_delete_dom_user("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_delete_dom_user: unable to unmarshall SAMR_Q_DELETE_DOM_USER.\n"));
return False;
}
r_u.status = _samr_delete_dom_user(p, &q_u, &r_u);
if (!samr_io_r_delete_dom_user("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_delete_dom_user: unable to marshall SAMR_R_DELETE_DOM_USER.\n"));
return False;
}
@@ -1088,14 +958,12 @@ static BOOL api_samr_delete_dom_group(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_delete_dom_group("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_delete_dom_group: unable to unmarshall SAMR_Q_DELETE_DOM_GROUP.\n"));
return False;
}
r_u.status = _samr_delete_dom_group(p, &q_u, &r_u);
if (!samr_io_r_delete_dom_group("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_delete_dom_group: unable to marshall SAMR_R_DELETE_DOM_GROUP.\n"));
return False;
}
@@ -1118,14 +986,12 @@ static BOOL api_samr_delete_dom_alias(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_delete_dom_alias("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_delete_dom_alias: unable to unmarshall SAMR_Q_DELETE_DOM_ALIAS.\n"));
return False;
}
r_u.status = _samr_delete_dom_alias(p, &q_u, &r_u);
if (!samr_io_r_delete_dom_alias("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_delete_dom_alias: unable to marshall SAMR_R_DELETE_DOM_ALIAS.\n"));
return False;
}
@@ -1148,14 +1014,12 @@ static BOOL api_samr_create_dom_group(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_create_dom_group("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_create_dom_group: unable to unmarshall SAMR_Q_CREATE_DOM_GROUP.\n"));
return False;
}
r_u.status = _samr_create_dom_group(p, &q_u, &r_u);
if (!samr_io_r_create_dom_group("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_create_dom_group: unable to marshall SAMR_R_CREATE_DOM_GROUP.\n"));
return False;
}
@@ -1178,14 +1042,12 @@ static BOOL api_samr_create_dom_alias(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_create_dom_alias("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_create_dom_alias: unable to unmarshall SAMR_Q_CREATE_DOM_ALIAS.\n"));
return False;
}
r_u.status = _samr_create_dom_alias(p, &q_u, &r_u);
if (!samr_io_r_create_dom_alias("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_create_dom_alias: unable to marshall SAMR_R_CREATE_DOM_ALIAS.\n"));
return False;
}
@@ -1208,14 +1070,12 @@ static BOOL api_samr_query_groupinfo(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_query_groupinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_query_groupinfo: unable to unmarshall SAMR_Q_QUERY_GROUPINFO.\n"));
return False;
}
r_u.status = _samr_query_groupinfo(p, &q_u, &r_u);
if (!samr_io_r_query_groupinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_query_groupinfo: unable to marshall SAMR_R_QUERY_GROUPINFO.\n"));
return False;
}
@@ -1238,44 +1098,12 @@ static BOOL api_samr_set_groupinfo(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_set_groupinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_set_groupinfo: unable to unmarshall SAMR_Q_SET_GROUPINFO.\n"));
return False;
}
r_u.status = _samr_set_groupinfo(p, &q_u, &r_u);
if (!samr_io_r_set_groupinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_set_groupinfo: unable to marshall SAMR_R_SET_GROUPINFO.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- api_samr_set_aliasinfo
- ********************************************************************/
-
-static BOOL api_samr_set_aliasinfo(pipes_struct *p)
-{
- SAMR_Q_SET_ALIASINFO q_u;
- SAMR_R_SET_ALIASINFO r_u;
-
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if (!samr_io_q_set_aliasinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_set_aliasinfo: unable to unmarshall SAMR_Q_SET_ALIASINFO.\n"));
- return False;
- }
-
- r_u.status = _samr_set_aliasinfo(p, &q_u, &r_u);
-
- if (!samr_io_r_set_aliasinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_set_aliasinfo: unable to marshall SAMR_R_SET_ALIASINFO.\n"));
return False;
}
@@ -1298,14 +1126,12 @@ static BOOL api_samr_get_dom_pwinfo(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_get_dom_pwinfo("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_get_dom_pwinfo: unable to unmarshall SAMR_Q_GET_DOM_PWINFO.\n"));
return False;
}
r_u.status = _samr_get_dom_pwinfo(p, &q_u, &r_u);
if (!samr_io_r_get_dom_pwinfo("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_get_dom_pwinfo: unable to marshall SAMR_R_GET_DOM_PWINFO.\n"));
return False;
}
@@ -1328,14 +1154,12 @@ static BOOL api_samr_open_group(pipes_struct *p)
ZERO_STRUCT(r_u);
if (!samr_io_q_open_group("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_open_group: unable to unmarshall SAMR_Q_OPEN_GROUP.\n"));
return False;
}
r_u.status = _samr_open_group(p, &q_u, &r_u);
if (!samr_io_r_open_group("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_open_group: unable to marshall SAMR_R_OPEN_GROUP.\n"));
return False;
}
@@ -1343,13 +1167,13 @@ static BOOL api_samr_open_group(pipes_struct *p)
}
/*******************************************************************
- api_samr_remove_sid_foreign_domain
+ api_samr_unknown_2d
********************************************************************/
-static BOOL api_samr_remove_sid_foreign_domain(pipes_struct *p)
+static BOOL api_samr_unknown_2d(pipes_struct *p)
{
- SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q_u;
- SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r_u;
+ SAMR_Q_UNKNOWN_2D q_u;
+ SAMR_R_UNKNOWN_2D r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
@@ -1357,76 +1181,13 @@ static BOOL api_samr_remove_sid_foreign_domain(pipes_struct *p)
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!samr_io_q_remove_sid_foreign_domain("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN.\n"));
+ if (!samr_io_q_unknown_2d("", &q_u, data, 0)) {
return False;
}
- r_u.status = _samr_remove_sid_foreign_domain(p, &q_u, &r_u);
+ r_u.status = _samr_unknown_2d(p, &q_u, &r_u);
- if (!samr_io_r_remove_sid_foreign_domain("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to marshall SAMR_R_REMOVE_SID_FOREIGN_DOMAIN.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- api_samr_query_dom_info
- ********************************************************************/
-
-static BOOL api_samr_unknown_2e(pipes_struct *p)
-{
- SAMR_Q_UNKNOWN_2E q_u;
- SAMR_R_UNKNOWN_2E r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the samr unknown 8 command */
- if(!samr_io_q_unknown_2e("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_unknown_2e: unable to unmarshall SAMR_Q_UNKNOWN_2E.\n"));
- return False;
- }
-
- r_u.status = _samr_unknown_2e(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!samr_io_r_samr_unknown_2e("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_unknown_2e: unable to marshall SAMR_R_UNKNOWN_2E.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- api_samr_set_dom_info
- ********************************************************************/
-
-static BOOL api_samr_set_dom_info(pipes_struct *p)
-{
- SAMR_Q_SET_DOMAIN_INFO q_u;
- SAMR_R_SET_DOMAIN_INFO r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!samr_io_q_set_domain_info("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_set_dom_info: unable to unmarshall SAMR_Q_SET_DOMAIN_INFO.\n"));
- return False;
- }
-
- r_u.status = _samr_set_dom_info(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!samr_io_r_set_domain_info("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_set_dom_info: unable to marshall SAMR_R_SET_DOMAIN_INFO.\n"));
+ if (!samr_io_r_unknown_2d("", &r_u, rdata, 0)) {
return False;
}
@@ -1439,70 +1200,92 @@ static BOOL api_samr_set_dom_info(pipes_struct *p)
static struct api_struct api_samr_cmds [] =
{
- {"SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
- {"SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
- {"SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
- {"SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
- {"SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
-
- {"SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
- {"SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
- {"SAMR_QUERY_USERALIASES" , SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
- {"SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem },
- {"SAMR_QUERY_GROUPMEM" , SAMR_QUERY_GROUPMEM , api_samr_query_groupmem },
- {"SAMR_ADD_ALIASMEM" , SAMR_ADD_ALIASMEM , api_samr_add_aliasmem },
- {"SAMR_DEL_ALIASMEM" , SAMR_DEL_ALIASMEM , api_samr_del_aliasmem },
- {"SAMR_ADD_GROUPMEM" , SAMR_ADD_GROUPMEM , api_samr_add_groupmem },
- {"SAMR_DEL_GROUPMEM" , SAMR_DEL_GROUPMEM , api_samr_del_groupmem },
-
- {"SAMR_DELETE_DOM_USER" , SAMR_DELETE_DOM_USER , api_samr_delete_dom_user },
- {"SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
- {"SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
- {"SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
- {"SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
- {"SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
- {"SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
- {"SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
- {"SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
- {"SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
-
- {"SAMR_QUERY_DOMAIN_INFO" , SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
- {"SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
- {"SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
- {"SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo },
- {"SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
-
- {"SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
- {"SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
- {"SAMR_SET_GROUPINFO" , SAMR_SET_GROUPINFO , api_samr_set_groupinfo },
- {"SAMR_SET_ALIASINFO" , SAMR_SET_ALIASINFO , api_samr_set_aliasinfo },
- {"SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
- {"SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
- {"SAMR_GET_DOM_PWINFO" , SAMR_GET_DOM_PWINFO , api_samr_get_dom_pwinfo },
- {"SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
- {"SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
- {"SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
- {"SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
- {"SAMR_REMOVE_SID_FOREIGN_DOMAIN" , SAMR_REMOVE_SID_FOREIGN_DOMAIN , api_samr_remove_sid_foreign_domain },
- {"SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
-
- {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj },
- {"SAMR_SET_SEC_OBJECT" , SAMR_SET_SEC_OBJECT , api_samr_set_sec_obj },
- {"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
- {"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e },
- {"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info },
- {"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 }
+ {"SAMR_CLOSE_HND", SAMR_CLOSE_HND, api_samr_close_hnd},
+ {"SAMR_CONNECT", SAMR_CONNECT, api_samr_connect},
+ {"SAMR_CONNECT_ANON", SAMR_CONNECT_ANON, api_samr_connect_anon},
+ {"SAMR_ENUM_DOMAINS", SAMR_ENUM_DOMAINS, api_samr_enum_domains},
+ {"SAMR_ENUM_DOM_USERS", SAMR_ENUM_DOM_USERS, api_samr_enum_dom_users},
+
+ {"SAMR_ENUM_DOM_GROUPS", SAMR_ENUM_DOM_GROUPS, api_samr_enum_dom_groups},
+ {"SAMR_ENUM_DOM_ALIASES", SAMR_ENUM_DOM_ALIASES, api_samr_enum_dom_aliases},
+ {"SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
+ {"SAMR_QUERY_ALIASMEM", SAMR_QUERY_ALIASMEM, api_samr_query_aliasmem},
+ {"SAMR_QUERY_GROUPMEM", SAMR_QUERY_GROUPMEM, api_samr_query_groupmem},
+ {"SAMR_ADD_ALIASMEM", SAMR_ADD_ALIASMEM, api_samr_add_aliasmem},
+ {"SAMR_DEL_ALIASMEM", SAMR_DEL_ALIASMEM, api_samr_del_aliasmem},
+ {"SAMR_ADD_GROUPMEM", SAMR_ADD_GROUPMEM, api_samr_add_groupmem},
+ {"SAMR_DEL_GROUPMEM", SAMR_DEL_GROUPMEM, api_samr_del_groupmem},
+
+ {"SAMR_DELETE_DOM_USER", SAMR_DELETE_DOM_USER, api_samr_delete_dom_user},
+ {"SAMR_DELETE_DOM_GROUP", SAMR_DELETE_DOM_GROUP, api_samr_delete_dom_group},
+ {"SAMR_DELETE_DOM_ALIAS", SAMR_DELETE_DOM_ALIAS, api_samr_delete_dom_alias},
+ {"SAMR_CREATE_DOM_GROUP", SAMR_CREATE_DOM_GROUP, api_samr_create_dom_group},
+ {"SAMR_CREATE_DOM_ALIAS", SAMR_CREATE_DOM_ALIAS, api_samr_create_dom_alias},
+ {"SAMR_LOOKUP_NAMES", SAMR_LOOKUP_NAMES, api_samr_lookup_names},
+ {"SAMR_OPEN_USER", SAMR_OPEN_USER, api_samr_open_user},
+ {"SAMR_QUERY_USERINFO", SAMR_QUERY_USERINFO, api_samr_query_userinfo},
+ {"SAMR_SET_USERINFO", SAMR_SET_USERINFO, api_samr_set_userinfo},
+ {"SAMR_SET_USERINFO2", SAMR_SET_USERINFO2, api_samr_set_userinfo2},
+
+ {"SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info},
+ {"SAMR_QUERY_USERGROUPS", SAMR_QUERY_USERGROUPS, api_samr_query_usergroups},
+ {"SAMR_QUERY_DISPINFO", SAMR_QUERY_DISPINFO, api_samr_query_dispinfo},
+ {"SAMR_QUERY_DISPINFO3", SAMR_QUERY_DISPINFO3, api_samr_query_dispinfo},
+ {"SAMR_QUERY_DISPINFO4", SAMR_QUERY_DISPINFO4, api_samr_query_dispinfo},
+
+ {"SAMR_QUERY_ALIASINFO", SAMR_QUERY_ALIASINFO, api_samr_query_aliasinfo},
+ {"SAMR_QUERY_GROUPINFO", SAMR_QUERY_GROUPINFO, api_samr_query_groupinfo},
+ {"SAMR_SET_GROUPINFO", SAMR_SET_GROUPINFO, api_samr_set_groupinfo},
+ {"SAMR_CREATE_USER", SAMR_CREATE_USER, api_samr_create_user},
+ {"SAMR_LOOKUP_RIDS", SAMR_LOOKUP_RIDS, api_samr_lookup_rids},
+ {"SAMR_GET_DOM_PWINFO", SAMR_GET_DOM_PWINFO, api_samr_get_dom_pwinfo},
+ {"SAMR_CHGPASSWD_USER", SAMR_CHGPASSWD_USER, api_samr_chgpasswd_user},
+ {"SAMR_OPEN_ALIAS", SAMR_OPEN_ALIAS, api_samr_open_alias},
+ {"SAMR_OPEN_GROUP", SAMR_OPEN_GROUP, api_samr_open_group},
+ {"SAMR_OPEN_DOMAIN", SAMR_OPEN_DOMAIN, api_samr_open_domain},
+ {"SAMR_UNKNOWN_2D", SAMR_UNKNOWN_2D, api_samr_unknown_2d},
+ {"SAMR_LOOKUP_DOMAIN", SAMR_LOOKUP_DOMAIN, api_samr_lookup_domain},
+
+ {"SAMR_QUERY_SEC_OBJECT", SAMR_QUERY_SEC_OBJECT, api_samr_query_sec_obj},
+ {"SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
+ {NULL, 0, NULL}
+
+#if 0
+
+ { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
+ { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
+ { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
+ { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
+ { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
+ { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
+ { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
+ { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
+ { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
+ { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
+ { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
+ { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
+ { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
+ { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
+ { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
+ { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
+ { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
+ { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
+ { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
+ { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
+ { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj },
+ { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
+ { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
+ { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
+ { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
+ { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
+ { NULL , 0 , NULL }
+#endif
};
-void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_samr_cmds;
- *n_fns = sizeof(api_samr_cmds) / sizeof(struct api_struct);
-}
-
-
-NTSTATUS rpc_samr_init(void)
+/*******************************************************************
+ receives a samr pipe and responds.
+ ********************************************************************/
+BOOL api_samr_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "samr", "lsass", api_samr_cmds,
- sizeof(api_samr_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index e0d7ef57da1..2ce5ed74274 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -1,15 +1,13 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Marc Jacobsen 1999,
- * Copyright (C) Jeremy Allison 2001-2002,
- * Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
- * Copyright (C) Gerald (Jerry) Carter 2003,
- * Copyright (C) Simo Sorce 2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Marc Jacobsen 1999.
+ * Copyright (C) Jeremy Allison 2001-2002.
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,143 +30,50 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
+extern fstring global_myworkgroup;
+extern pstring global_myname;
+extern DOM_SID global_sam_sid;
extern DOM_SID global_sid_Builtin;
extern rid_name domain_group_rids[];
extern rid_name domain_alias_rids[];
extern rid_name builtin_alias_rids[];
-extern PRIVS privs[];
-
typedef struct _disp_info {
BOOL user_dbloaded;
uint32 num_user_account;
- SAM_ACCOUNT *disp_user_info;
+ DISP_USER_INFO *disp_user_info;
BOOL group_dbloaded;
uint32 num_group_account;
- DOMAIN_GRP *disp_group_info;
+ DISP_GROUP_INFO *disp_group_info;
} DISP_INFO;
struct samr_info {
/* for use by the \PIPE\samr policy */
DOM_SID sid;
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
- uint32 acc_granted;
- uint16 acb_mask;
- BOOL all_machines;
DISP_INFO disp_info;
-
- TALLOC_CTX *mem_ctx;
};
-struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
-struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
-struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
-struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
-struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
-
-static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
-
-/*******************************************************************
- Checks if access to an object should be granted, and returns that
- level of access for further checks.
-********************************************************************/
-
-NTSTATUS access_check_samr_object(SEC_DESC *psd, pipes_struct *p, uint32 des_access,
- uint32 *acc_granted, uint32 *priv_list, const char *debug)
-{
- NTSTATUS status = NT_STATUS_ACCESS_DENIED;
- NT_USER_TOKEN *nt_user_token = p->pipe_user.nt_user_token;
- int i;
-
- if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
- *acc_granted = des_access;
- if (geteuid() == sec_initial_uid()) {
- DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
- debug, des_access));
- DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
- return NT_STATUS_OK;
- }
- if (priv_list != NULL) {
- for (i = 0; priv_list[i] != SE_NONE; i++) {
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), priv_list[i]))) {
- DEBUG(3, ("%s: User should be denied access but was overridden by %s\n", debug, privs[priv_list[i]].priv));
- return NT_STATUS_OK;
- }
- }
- }
-
- DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n", debug, des_access));
- }
- return status;
-}
-
-/*******************************************************************
- Checks if access to a function can be granted
-********************************************************************/
-
-NTSTATUS access_check_samr_function(pipes_struct *p, uint32 acc_granted, uint32 acc_required, uint32 *priv_list, const char *debug)
-{
- int i;
-
- DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
- debug, acc_granted, acc_required));
- if ((acc_granted & acc_required) != acc_required) {
- if (geteuid() == sec_initial_uid()) {
- DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
- debug, acc_granted, acc_required));
- DEBUGADD(4,("but overwritten by euid == 0\n"));
- return NT_STATUS_OK;
- }
- if (priv_list != NULL) {
- for (i = 0; priv_list[i] != SE_NONE; i++) {
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), priv_list[i]))) {
- DEBUG(3, ("%s: User should be denied access but was overridden by %s\n", debug, privs[priv_list[i]].priv));
- return NT_STATUS_OK;
- }
- }
- }
-
- DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
- debug, acc_granted, acc_required));
- return NT_STATUS_ACCESS_DENIED;
- }
- return NT_STATUS_OK;
-}
-
-
/*******************************************************************
Create a samr_info struct.
-********************************************************************/
+ ********************************************************************/
static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
{
struct samr_info *info;
fstring sid_str;
- TALLOC_CTX *mem_ctx;
-
- if (psid) {
- sid_to_string(sid_str, psid);
- } else {
- fstrcpy(sid_str,"(NULL)");
- }
-
- mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
- if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
+ if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
return NULL;
ZERO_STRUCTP(info);
- DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
if (psid) {
+ DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
sid_copy( &info->sid, psid);
} else {
DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
}
- info->mem_ctx = mem_ctx;
return info;
}
@@ -176,18 +81,27 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
Function to free the per handle data.
********************************************************************/
-static void free_samr_users(struct samr_info *info)
+static void free_samr_db(struct samr_info *info)
{
int i;
+ if (info->disp_info.group_dbloaded) {
+ for (i=0; i<info->disp_info.num_group_account; i++)
+ SAFE_FREE(info->disp_info.disp_group_info[i].grp);
+
+ SAFE_FREE(info->disp_info.disp_group_info);
+ }
+
if (info->disp_info.user_dbloaded){
- for (i=0; i<info->disp_info.num_user_account; i++) {
- SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
- /* Not really a free, actually a 'clear' */
- pdb_free_sam(&sam);
- }
+ for (i=0; i<info->disp_info.num_user_account; i++)
+ pdb_free_sam(info->disp_info.disp_user_info[i].sam);
+
+ SAFE_FREE(info->disp_info.disp_user_info);
}
+
info->disp_info.user_dbloaded=False;
+ info->disp_info.group_dbloaded=False;
+ info->disp_info.num_group_account=0;
info->disp_info.num_user_account=0;
}
@@ -195,89 +109,74 @@ static void free_samr_users(struct samr_info *info)
Function to free the per handle data.
********************************************************************/
-static void free_samr_db(struct samr_info *info)
-{
- /* Groups are talloced */
-
- free_samr_users(info);
-
- info->disp_info.group_dbloaded=False;
- info->disp_info.num_group_account=0;
-}
-
static void free_samr_info(void *ptr)
{
struct samr_info *info=(struct samr_info *) ptr;
free_samr_db(info);
- talloc_destroy(info->mem_ctx);
+ SAFE_FREE(info);
}
/*******************************************************************
Ensure password info is never given out. Paranioa... JRA.
********************************************************************/
+static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
+{
+ int i;
+
+ if (!pass)
+ return;
+
+ for (i = 0; i < num_entries; i++) {
+ memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
+ memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
+ }
+}
+
static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
{
-
if (!sam_pass)
return;
- /* These now zero out the old password */
-
- pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
- pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
+ if (sam_pass->lm_pw)
+ memset(sam_pass->lm_pw, '\0', 16);
+ if (sam_pass->nt_pw)
+ memset(sam_pass->nt_pw, '\0', 16);
}
-
-static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
+static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
{
SAM_ACCOUNT *pwd = NULL;
- SAM_ACCOUNT *pwd_array = NULL;
- NTSTATUS nt_status = NT_STATUS_OK;
- TALLOC_CTX *mem_ctx = info->mem_ctx;
+ DISP_USER_INFO *pwd_array = NULL;
DEBUG(10,("load_sampwd_entries\n"));
/* if the snapshoot is already loaded, return */
- if ((info->disp_info.user_dbloaded==True)
- && (info->acb_mask == acb_mask)
- && (info->all_machines == all_machines)) {
+ if (info->disp_info.user_dbloaded==True) {
DEBUG(10,("load_sampwd_entries: already in memory\n"));
return NT_STATUS_OK;
}
- free_samr_users(info);
-
if (!pdb_setsampwent(False)) {
DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
return NT_STATUS_ACCESS_DENIED;
}
- for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
- && pdb_getsampwent(pwd) == True; pwd=NULL) {
+ for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) {
- if (all_machines) {
- if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
- || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
- DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
- pdb_free_sam(&pwd);
- continue;
- }
- } else {
- if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
- pdb_free_sam(&pwd);
- DEBUG(5,(" acb_mask %x reject\n", acb_mask));
- continue;
- }
+ if (acb_mask != 0 && !(pwd->acct_ctrl & acb_mask)) {
+ pdb_free_sam(pwd);
+ DEBUG(5,(" acb_mask %x reject\n", acb_mask));
+ continue;
}
/* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
- pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
- (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
+ pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info,
+ (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
if (pwd_array==NULL)
return NT_STATUS_NO_MEMORY;
@@ -285,8 +184,8 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOO
info->disp_info.disp_user_info=pwd_array;
}
- /* Copy the SAM_ACCOUNT into the array */
- info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
+ /* link the SAM_ACCOUNT to the array */
+ info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
@@ -297,23 +196,61 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOO
/* the snapshoot is in memory, we're ready to enumerate fast */
- info->acb_mask = acb_mask;
- info->all_machines = all_machines;
info->disp_info.user_dbloaded=True;
- DEBUG(10,("load_sampwd_entries: done\n"));
+ DEBUG(12,("load_sampwd_entries: done\n"));
- return nt_status;
+ return NT_STATUS_OK;
+}
+
+/*
+ * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
+ * Return a malloced map so we can free it.
+ */
+
+static int setup_fake_group_map(GROUP_MAP **ret_map)
+{
+ static GROUP_MAP static_map[2];
+ static BOOL group_map_init;
+ extern DOM_SID global_sam_sid;
+
+ *ret_map = (GROUP_MAP *)malloc(sizeof(GROUP_MAP)*2);
+ if (!ret_map)
+ return 2;
+
+ if (group_map_init) {
+ memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
+ return sizeof(static_map)/sizeof(GROUP_MAP);
+ }
+
+ group_map_init = True;
+
+ static_map[0].gid = (gid_t)-1;
+ sid_copy(&static_map[0].sid, &global_sam_sid);
+ sid_append_rid(&static_map[0].sid, DOMAIN_GROUP_RID_ADMINS);
+ static_map[0].sid_name_use = SID_NAME_DOM_GRP;
+ fstrcpy(static_map[0].nt_name, "Domain Admins");
+ fstrcpy(static_map[0].comment, "Administrators for the domain");
+ static_map[0].privilege = 0;
+
+ static_map[1].gid = (gid_t)-1;
+ sid_copy(&static_map[1].sid, &global_sam_sid);
+ sid_append_rid(&static_map[1].sid, DOMAIN_GROUP_RID_USERS);
+ static_map[1].sid_name_use = SID_NAME_DOM_GRP;
+ fstrcpy(static_map[1].nt_name, "Domain Users");
+ fstrcpy(static_map[1].comment, "Users in the domain");
+ static_map[1].privilege = 0;
+
+ memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
+ return sizeof(static_map)/sizeof(GROUP_MAP);
}
static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
{
- GROUP_MAP *map=NULL;
- DOMAIN_GRP *grp_array = NULL;
+ GROUP_MAP *map;
+ DISP_GROUP_INFO *grp_array = NULL;
uint32 group_entries = 0;
uint32 i;
- TALLOC_CTX *mem_ctx = info->mem_ctx;
- BOOL ret;
DEBUG(10,("load_group_domain_entries\n"));
@@ -322,41 +259,31 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
DEBUG(10,("load_group_domain_entries: already in memory\n"));
return NT_STATUS_OK;
}
-
- if (sid_equal(sid, &global_sid_Builtin)) {
- /* No domain groups for now in the BUILTIN domain */
- info->disp_info.num_group_account=0;
- info->disp_info.disp_group_info=NULL;
- info->disp_info.group_dbloaded=True;
- return NT_STATUS_OK;
- }
- become_root();
- ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
- unbecome_root();
-
- if ( !ret ) {
- DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
+ /*
+ * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
+ */
+
+ group_entries = setup_fake_group_map(&map);
info->disp_info.num_group_account=group_entries;
- grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
+ grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
+
if (group_entries!=0 && grp_array==NULL) {
- DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
- SAFE_FREE(map);
return NT_STATUS_NO_MEMORY;
}
info->disp_info.disp_group_info=grp_array;
for (i=0; i<group_entries; i++) {
- fstrcpy(grp_array[i].name, map[i].nt_name);
- fstrcpy(grp_array[i].comment, map[i].comment);
- sid_split_rid(&map[i].sid, &grp_array[i].rid);
- grp_array[i].attr=SID_NAME_DOM_GRP;
+
+ grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP));
+
+ fstrcpy(grp_array[i].grp->name, map[i].nt_name);
+ fstrcpy(grp_array[i].grp->comment, map[i].comment);
+ sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
+ grp_array[i].grp->attr=SID_NAME_DOM_GRP;
}
SAFE_FREE(map);
@@ -365,11 +292,88 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
info->disp_info.group_dbloaded=True;
- DEBUG(10,("load_group_domain_entries: done\n"));
+ DEBUG(12,("load_group_domain_entries: done\n"));
return NT_STATUS_OK;
}
+/*******************************************************************
+ This next function should be replaced with something that
+ dynamically returns the correct user info..... JRA.
+ ********************************************************************/
+
+static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
+ int *total_entries, int *num_entries,
+ int max_num_entries, uint16 acb_mask)
+{
+ SAM_ACCOUNT *pwd = NULL;
+ BOOL not_finished = True;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (pw_buf == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ pdb_init_sam(&pwd);
+
+ if (!pdb_setsampwent(False)) {
+ DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
+ pdb_free_sam(pwd);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ while (((not_finished = pdb_getsampwent(pwd)) != False)
+ && (*num_entries) < max_num_entries)
+ {
+ int user_name_len;
+
+ if (start_idx > 0) {
+
+ pdb_reset_sam(pwd);
+
+ /* skip the requested number of entries.
+ not very efficient, but hey... */
+ start_idx--;
+ continue;
+ }
+
+ user_name_len = strlen(pdb_get_username(pwd))+1;
+ init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
+ init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
+ pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+
+ /* Now check if the NT compatible password is available. */
+ if (pdb_get_nt_passwd(pwd))
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
+
+ pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
+
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
+ (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
+
+ if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ } else {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ }
+
+ (*total_entries)++;
+
+ pdb_reset_sam(pwd);
+
+ }
+
+ pdb_endsampwent();
+ pdb_free_sam(pwd);
+
+ if (not_finished)
+ return STATUS_MORE_ENTRIES;
+ else
+ return NT_STATUS_OK;
+}
/*******************************************************************
_samr_close_hnd
@@ -394,38 +398,17 @@ NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HN
NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
{
- struct samr_info *info;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->flags;
- size_t sd_size;
- NTSTATUS status;
- uint32 priv_list[3] = {SE_MACHINE_ACCOUNT, SE_NONE};
+ struct samr_info *info;
r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(p, info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, priv_list, "_samr_open_domain"))) {
- return status;
- }
-
- /*check if access can be granted as requested by client. */
- samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access,&dom_generic_mapping);
-
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- priv_list, "_samr_open_domain"))) {
- return status;
- }
-
/* associate the domain SID with the (unique) handle. */
if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
return NT_STATUS_NO_MEMORY;
- info->acc_granted = acc_granted;
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
@@ -436,6 +419,16 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
return r_u->status;
}
+static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
+{
+ if (!info) {
+ DEBUG(3,("Error getting policy\n"));
+ return 0xffffffff;
+ }
+
+ return info->sid.sub_auths[info->sid.num_auths-1];
+}
+
/*******************************************************************
_samr_get_usrdom_pwinfo
********************************************************************/
@@ -447,69 +440,29 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u,
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
+ if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
return NT_STATUS_INVALID_HANDLE;
+ }
- if (!sid_check_is_in_our_domain(&info->sid))
+ /* find the user's rid */
+ if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
- /*
- * NT sometimes return NT_STATUS_ACCESS_DENIED
- * I don't know yet why.
- */
-
return r_u->status;
}
/*******************************************************************
- samr_make_dom_obj_sd
- ********************************************************************/
-
-static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
-{
- extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
-
- SEC_ACE ace[3];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
samr_make_usr_obj_sd
********************************************************************/
-static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
+static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
{
+ extern DOM_SID global_sid_Builtin;
extern DOM_SID global_sid_World;
DOM_SID adm_sid;
DOM_SID act_sid;
@@ -518,6 +471,8 @@ static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
SEC_ACCESS mask;
SEC_ACL *psa = NULL;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
sid_copy(&adm_sid, &global_sid_Builtin);
sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
@@ -525,107 +480,29 @@ static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
sid_copy(&act_sid, &global_sid_Builtin);
sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
+ init_sec_access(&mask, 0x2035b);
init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
+ init_sec_access(&mask, 0xf07ff);
init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- /*extended access for the user*/
- init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
+ init_sec_access(&mask,0x20044);
init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
+ if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
return NT_STATUS_NO_MEMORY;
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
+ if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- samr_make_grp_obj_sd
- ********************************************************************/
-
-static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
-{
- extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
-
- SEC_ACE ace[3];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
+ if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
return NT_STATUS_NO_MEMORY;
return NT_STATUS_OK;
}
-/*******************************************************************
- samr_make_ali_obj_sd
- ********************************************************************/
-
-static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
-{
- extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
-
- SEC_ACE ace[3];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
-
-static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
+static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
{
struct samr_info *info = NULL;
@@ -637,75 +514,25 @@ static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *s
return False;
*sid = info->sid;
- *acc_granted = info->acc_granted;
return True;
}
/*******************************************************************
- _samr_set_sec_obj
- ********************************************************************/
-
-NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
-{
- DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-
-/*******************************************************************
_samr_query_sec_obj
********************************************************************/
NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
{
DOM_SID pol_sid;
- fstring str_sid;
- SEC_DESC * psd = NULL;
- size_t sd_size;
- uint32 acc_granted;
r_u->status = NT_STATUS_OK;
/* Get the SID. */
- if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
-
- DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
-
- /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
-
- /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
- if (pol_sid.sid_rev_num == 0)
- {
- DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
- r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
- }
- else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
-
- {
- DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
- r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
- }
- else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
- {
- /* TODO: Builtin probably needs a different SD with restricted write access*/
- DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
- r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
- }
- else if (sid_check_is_in_our_domain(&pol_sid) ||
- sid_check_is_in_builtin(&pol_sid))
- {
- /* TODO: different SDs have to be generated for aliases groups and users.
- Currently all three get a default user SD */
- DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
- r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
- }
- else return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
+ return NT_STATUS_INVALID_HANDLE;
- if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
+ r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
if (NT_STATUS_IS_OK(r_u->status))
r_u->ptr = 1;
@@ -717,121 +544,66 @@ NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_
makes a SAM_ENTRY / UNISTR2* structure from a user list.
********************************************************************/
-static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
- uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
- DOM_SID *domain_sid)
+static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
+ uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
{
uint32 i;
SAM_ENTRY *sam;
UNISTR2 *uni_name;
- SAM_ACCOUNT *pwd = NULL;
- UNISTR2 uni_temp_name;
- const char *temp_name;
- const DOM_SID *user_sid;
- uint32 user_rid;
- fstring user_sid_string;
- fstring domain_sid_string;
-
+
*sam_pp = NULL;
*uni_name_pp = NULL;
- if (num_entries == 0)
- return NT_STATUS_OK;
+ if (num_sam_entries == 0)
+ return;
- sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
+ sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
- uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
+ uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
if (sam == NULL || uni_name == NULL) {
- DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
+ return;
}
- for (i = 0; i < num_entries; i++) {
- pwd = &disp_user_info[i+start_idx];
- temp_name = pdb_get_username(pwd);
- init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
- user_sid = pdb_get_user_sid(pwd);
-
- if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
- DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
- "the domain sid %s. Failing operation.\n",
- temp_name,
- sid_to_string(user_sid_string, user_sid),
- sid_to_string(domain_sid_string, domain_sid)));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ for (i = 0; i < num_sam_entries; i++) {
+ int len = pass[i].uni_user_name.uni_str_len;
- init_sam_entry(&sam[i], &uni_temp_name, user_rid);
- copy_unistr2(&uni_name[i], &uni_temp_name);
+ init_sam_entry(&sam[i], len, pass[i].user_rid);
+ copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
}
*sam_pp = sam;
*uni_name_pp = uni_name;
- return NT_STATUS_OK;
}
/*******************************************************************
samr_reply_enum_dom_users
********************************************************************/
-NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
- SAMR_R_ENUM_DOM_USERS *r_u)
+NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
{
- struct samr_info *info = NULL;
- uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
- int num_account;
- uint32 enum_context=q_u->start_idx;
- uint32 max_size=q_u->max_size;
- uint32 temp_size;
- enum remote_arch_types ra_type = get_remote_arch();
- int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
- uint32 max_entries = max_sam_entries;
- DOM_SID domain_sid;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries = 0;
+ int total_entries = 0;
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- domain_sid = info->sid;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, info->acc_granted,
- SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, NULL,
- "_samr_enum_dom_users"))) {
- return r_u->status;
- }
-
DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
become_root();
- r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
+ r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
+ MAX_SAM_ENTRIES, q_u->acb_mask);
unbecome_root();
-
- if (!NT_STATUS_IS_OK(r_u->status))
- return r_u->status;
-
- num_account = info->disp_info.num_user_account;
- if (enum_context > num_account) {
- DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
- return NT_STATUS_OK;
- }
-
- /* verify we won't overflow */
- if (max_entries > num_account-enum_context) {
- max_entries = num_account-enum_context;
- DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
- }
+ if (NT_STATUS_IS_ERR(r_u->status))
+ return r_u->status;
- /* calculate the size and limit on the number of entries we will return */
- temp_size=max_entries*struct_size;
-
- if (temp_size>max_size) {
- max_entries=MIN((max_size/struct_size),max_entries);;
- DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
- }
+ samr_clear_passwd_fields(pass, num_entries);
/*
* Note from JRA. total_entries is not being used here. Currently if there is a
@@ -846,20 +618,9 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
* value (again I think this is wrong).
*/
- r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
- max_entries, enum_context,
- info->disp_info.disp_user_info,
- &domain_sid);
-
- if (!NT_STATUS_IS_OK(r_u->status))
- return r_u->status;
-
- if (enum_context+max_entries < num_account)
- r_u->status = STATUS_MORE_ENTRIES;
+ make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
- DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
-
- init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
+ init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
@@ -896,8 +657,10 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
/*
* JRA. I think this should include the null. TNG does not.
*/
- init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
- init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
+ int len = strlen(unix_to_dos_static(grp[i].name))+1;
+
+ init_sam_entry(&sam[i], len, grp[i].rid);
+ init_unistr2(&uni_name[i], unix_to_dos_static(grp[i].name), len);
}
*sam_pp = sam;
@@ -906,125 +669,160 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
/*******************************************************************
Get the group entries - similar to get_sampwd_entries().
- ******************************************************************/
+ ********************************************************************/
-static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
- DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
- uint32 *p_num_entries, uint32 max_entries )
+static NTSTATUS get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
+ uint32 *p_num_entries, uint32 max_entries)
{
- GROUP_MAP *map=NULL;
- int i;
- uint32 group_entries = 0;
+ fstring sid_str;
+ fstring sam_sid_str;
uint32 num_entries = 0;
+ sid_to_string(sid_str, sid);
+ sid_to_string(sam_sid_str, &global_sam_sid);
+
*p_num_entries = 0;
- /* access checks for the users were performed higher up. become/unbecome_root()
- needed for some passdb backends to enumerate groups */
-
- become_root();
- pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
- ENUM_ONLY_MAPPED);
- unbecome_root();
-
- num_entries=group_entries-start_idx;
+ /* well-known aliases */
+ if (strequal(sid_str, "S-1-5-32")) {
+ const char *alias_name;
+ while (!lp_hide_local_users() &&
+ num_entries < max_entries &&
+ ((alias_name = builtin_alias_rids[num_entries].name) != NULL)) {
- /* limit the number of entries */
- if (num_entries>max_entries) {
- DEBUG(5,("Limiting to %d entries\n", max_entries));
- num_entries=max_entries;
- }
+ fstrcpy(d_grp[num_entries].name, alias_name);
+ d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid;
- *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
- if (num_entries!=0 && *d_grp==NULL){
- SAFE_FREE(map);
- return NT_STATUS_NO_MEMORY;
- }
-
- for (i=0; i<num_entries; i++) {
- fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
- fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
- sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
- (*d_grp)[i].attr=SID_NAME_DOM_GRP;
- }
+ num_entries++;
+ }
+ } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) {
+ fstring name;
+ char *sep;
+ struct sys_grent *glist;
+ struct sys_grent *grp;
+
+ sep = lp_winbind_separator();
+
+ /* local aliases */
+ /* we return the UNIX groups here. This seems to be the right */
+ /* thing to do, since NT member servers return their local */
+ /* groups in the same situation. */
+
+ /* use getgrent_list() to retrieve the list of groups to avoid
+ * problems with getgrent possible infinite loop by internal
+ * libc grent structures overwrites by called functions */
+ grp = glist = getgrent_list();
+ if (grp == NULL)
+ return NT_STATUS_NO_MEMORY;
- SAFE_FREE(map);
+ for (;(num_entries < max_entries) && (grp != NULL); grp = grp->next) {
+ int i;
+ uint32 trid;
- *p_num_entries = num_entries;
+ fstrcpy(name,grp->gr_name);
+ DEBUG(10,("get_group_alias_entries: got group %s\n", name ));
+
+ /* Don't return winbind groups as they are not local! */
+
+ if (strchr(name, *sep) != NULL) {
+ DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name ));
+ continue;
+ }
+
+ /* Don't return user private groups... */
+ if (Get_Pwnam(name, False) != 0) {
+ DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name ));
+ continue;
+ }
+
+ trid = pdb_gid_to_group_rid(grp->gr_gid);
+ for( i = 0; i < num_entries; i++)
+ if ( d_grp[i].rid == trid )
+ break;
+
+ if ( i < num_entries )
+ continue; /* rid was there, dup! */
+
+ /* JRA - added this for large group db enumeration... */
+
+ if (start_idx > 0) {
+ /* skip the requested number of entries.
+ not very efficient, but hey...
+ */
+ start_idx--;
+ continue;
+ }
+
+ fstrcpy(d_grp[num_entries].name, name);
+ d_grp[num_entries].rid = trid;
+ num_entries++;
+ }
+
+ grent_free(glist);
+ }
- DEBUG(10,("get_group_domain_entries: returning %d entries\n",
- *p_num_entries));
+ *p_num_entries = num_entries;
+ if (num_entries >= max_entries)
+ return STATUS_MORE_ENTRIES;
return NT_STATUS_OK;
}
/*******************************************************************
- Wrapper for enumerating local groups
- ******************************************************************/
+ Get the group entries - similar to get_sampwd_entries().
+ ********************************************************************/
-static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
- const DOM_SID *sid, uint32 start_idx,
- uint32 *p_num_entries, uint32 max_entries )
+static NTSTATUS get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
+ uint32 *p_num_entries, uint32 max_entries)
{
- struct acct_info *info;
- int i;
- BOOL res;
+ fstring sid_str;
+ fstring sam_sid_str;
+ uint32 num_entries = 0;
+ fstring name="Domain Admins";
+ fstring comment="Just to make it work !";
- become_root();
- res = pdb_enum_aliases(sid, start_idx, max_entries,
- p_num_entries, &info);
- unbecome_root();
+ sid_to_string(sid_str, sid);
+ sid_to_string(sam_sid_str, &global_sam_sid);
- if (!res)
- return NT_STATUS_ACCESS_DENIED;
+ *p_num_entries = 0;
- if (*p_num_entries == 0)
- return NT_STATUS_OK;
+ fstrcpy(d_grp[0].name, name);
+ fstrcpy(d_grp[0].comment, comment);
+ d_grp[0].rid = DOMAIN_GROUP_RID_ADMINS;
+ d_grp[0].attr=SID_NAME_DOM_GRP;
- *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries));
+ fstrcpy(d_grp[1].name, "Domain Users");
+ fstrcpy(d_grp[1].comment, "Just to make it work !");
+ d_grp[1].rid = DOMAIN_GROUP_RID_USERS;
+ d_grp[1].attr=SID_NAME_DOM_GRP;
- if (*d_grp == NULL) {
- SAFE_FREE(info);
- return NT_STATUS_NO_MEMORY;
- }
+ num_entries = 2;
- for (i=0; i<*p_num_entries; i++) {
- fstrcpy((*d_grp)[i].name, info[i].acct_name);
- fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
- (*d_grp)[i].rid = info[i].rid;
- (*d_grp)[i].attr = SID_NAME_ALIAS;
- }
+ *p_num_entries = num_entries;
- SAFE_FREE(info);
return NT_STATUS_OK;
}
/*******************************************************************
samr_reply_enum_dom_groups
+ Only reply with one group - domain admins. This must be fixed for
+ a real PDC. JRA.
********************************************************************/
NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
{
- DOMAIN_GRP *grp=NULL;
+ DOMAIN_GRP grp[2];
uint32 num_entries;
DOM_SID sid;
- uint32 acc_granted;
r_u->status = NT_STATUS_OK;
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, NULL, "_samr_enum_dom_groups"))) {
- return r_u->status;
- }
DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
- /* the domain group array is being allocated in the function below */
- if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
- return r_u->status;
- }
+ get_group_domain_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
@@ -1042,33 +840,26 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
{
- DOMAIN_GRP *grp=NULL;
+ DOMAIN_GRP grp[MAX_SAM_ENTRIES];
uint32 num_entries = 0;
fstring sid_str;
DOM_SID sid;
- NTSTATUS status;
- uint32 acc_granted;
r_u->status = NT_STATUS_OK;
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, NULL, "_samr_enum_dom_aliases"))) {
- return r_u->status;
- }
-
sid_to_string(sid_str, &sid);
DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
- status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
- &num_entries, MAX_SAM_ENTRIES);
- if (!NT_STATUS_IS_OK(status)) return status;
+ r_u->status = get_group_alias_entries(grp, &sid, q_u->start_idx,
+ &num_entries, MAX_SAM_ENTRIES);
+ if (NT_STATUS_IS_ERR(r_u->status))
+ return r_u->status;
make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
- /*safe_free(grp);*/
-
init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
@@ -1079,12 +870,11 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S
/*******************************************************************
samr_reply_query_dispinfo
********************************************************************/
-
-NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
- SAMR_R_QUERY_DISPINFO *r_u)
+NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
{
struct samr_info *info = NULL;
uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
+ uint16 acb_mask;
uint32 max_entries=q_u->max_entries;
uint32 enum_context=q_u->start_idx;
@@ -1095,8 +885,9 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
NTSTATUS disp_ret;
uint32 num_account = 0;
enum remote_arch_types ra_type = get_remote_arch();
- int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
- DOM_SID domain_sid;
+ int max_sam_entries;
+
+ max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
r_u->status = NT_STATUS_OK;
@@ -1105,8 +896,6 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- domain_sid = info->sid;
-
/*
* calculate how many entries we will return.
* based on
@@ -1136,27 +925,21 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
*/
/* Get what we need from the password database */
+
+ if (q_u->switch_level==2)
+ acb_mask = ACB_WSTRUST;
+ else
+ acb_mask = ACB_NORMAL;
+
+ /* Get what we need from the password database */
switch (q_u->switch_level) {
case 0x1:
- /* When playing with usrmgr, this is necessary
- if you want immediate refresh after editing
- a user. I would like to do this after the
- setuserinfo2, but we do not have access to
- the domain handle in that call, only to the
- user handle. Where else does this hurt?
- -- Volker
- */
-#if 0
- /* We cannot do this here - it kills performace. JRA. */
- free_samr_users(info);
-#endif
case 0x2:
case 0x4:
become_root();
- /* Level 2 is for all machines, otherwise only 'normal' users */
- r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
+ r_u->status=load_sampwd_entries(info, acb_mask);
unbecome_root();
- if (!NT_STATUS_IS_OK(r_u->status)) {
+ if (NT_STATUS_IS_ERR(r_u->status)) {
DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
return r_u->status;
}
@@ -1165,7 +948,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
case 0x3:
case 0x5:
r_u->status = load_group_domain_entries(info, &info->sid);
- if (!NT_STATUS_IS_OK(r_u->status))
+ if (NT_STATUS_IS_ERR(r_u->status))
return r_u->status;
num_account = info->disp_info.num_group_account;
break;
@@ -1182,7 +965,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
if (enum_context > num_account) {
DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
- return NT_STATUS_NO_MORE_ENTRIES;
+ return NT_STATUS_OK;
}
/* verify we won't overflow */
@@ -1195,7 +978,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
temp_size=max_entries*struct_size;
if (temp_size>max_size) {
- max_entries=MIN((max_size/struct_size),max_entries);;
+ max_entries=MIN((max_size/struct_size),max_entries);
DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
}
@@ -1211,9 +994,8 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
- info->disp_info.disp_user_info, &domain_sid);
- if (!NT_STATUS_IS_OK(disp_ret))
+ disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x2:
@@ -1221,9 +1003,8 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
- info->disp_info.disp_user_info, &domain_sid);
- if (!NT_STATUS_IS_OK(disp_ret))
+ disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x3:
@@ -1232,7 +1013,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
return NT_STATUS_NO_MEMORY;
}
disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
- if (!NT_STATUS_IS_OK(disp_ret))
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x4:
@@ -1241,7 +1022,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
return NT_STATUS_NO_MEMORY;
}
disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
- if (!NT_STATUS_IS_OK(disp_ret))
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x5:
@@ -1250,7 +1031,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
return NT_STATUS_NO_MEMORY;
}
disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
- if (!NT_STATUS_IS_OK(disp_ret))
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
@@ -1279,40 +1060,32 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
{
- DOM_SID sid;
- struct acct_info info;
- uint32 acc_granted;
- BOOL ret;
+ fstring alias_desc = "Local Unix group";
+ fstring alias="";
+ enum SID_NAME_USE type;
+ uint32 alias_rid;
+ struct samr_info *info = NULL;
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, NULL, "_samr_query_aliasinfo"))) {
- return r_u->status;
- }
- become_root();
- ret = pdb_get_aliasinfo(&sid, &info);
- unbecome_root();
-
- if ( !ret )
+ alias_rid = get_lsa_policy_samr_rid(info);
+ if(alias_rid == 0xffffffff)
+ return NT_STATUS_NO_SUCH_ALIAS;
+
+ if(!local_lookup_rid(alias_rid, alias, &type))
return NT_STATUS_NO_SUCH_ALIAS;
switch (q_u->switch_level) {
- case 1:
- r_u->ptr = 1;
- r_u->ctr.switch_value1 = 1;
- init_samr_alias_info1(&r_u->ctr.alias.info1,
- info.acct_name, 1, info.acct_desc);
- break;
case 3:
r_u->ptr = 1;
r_u->ctr.switch_value1 = 3;
- init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
+ init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
break;
default:
return NT_STATUS_INVALID_INFO_CLASS;
@@ -1397,7 +1170,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
int num_rids = q_u->num_names2;
DOM_SID pol_sid;
fstring sid_str;
- uint32 acc_granted;
r_u->status = NT_STATUS_OK;
@@ -1406,14 +1178,10 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
ZERO_ARRAY(rid);
ZERO_ARRAY(type);
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
return r_u->status;
}
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, 0, NULL, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
- return r_u->status;
- }
if (num_rids > MAX_SAM_ENTRIES) {
num_rids = MAX_SAM_ENTRIES;
@@ -1421,45 +1189,39 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
}
DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
-
+
for (i = 0; i < num_rids; i++) {
fstring name;
- DOM_SID sid;
- int ret;
+ DOM_SID sid;
- r_u->status = NT_STATUS_NONE_MAPPED;
+ r_u->status = NT_STATUS_NONE_MAPPED;
- rid [i] = 0xffffffff;
- type[i] = SID_NAME_UNKNOWN;
+ rid [i] = 0xffffffff;
+ type[i] = SID_NAME_UNKNOWN;
- ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
+ fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
- /*
+ /*
* we are only looking for a name
* the SID we get back can be outside
* the scope of the pol_sid
- *
+ *
* in clear: it prevents to reply to domain\group: yes
* when only builtin\group exists.
*
* a cleaner code is to add the sid of the domain we're looking in
* to the local_lookup_name function.
*/
-
- if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
- sid_split_rid(&sid, &local_rid);
-
+
+ if(local_lookup_name(global_myname, name, &sid, &local_type)) {
+ sid_split_rid(&sid, &local_rid);
+
if (sid_equal(&sid, &pol_sid)) {
rid[i]=local_rid;
-
- /* Windows does not return WKN_GRP here, even
- * on lookups in builtin */
- type[i] = (local_type == SID_NAME_WKN_GRP) ?
- SID_NAME_ALIAS : local_type;
-
- r_u->status = NT_STATUS_OK;
+ type[i]=local_type;
+ r_u->status = NT_STATUS_OK;
}
- }
+ }
}
init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
@@ -1475,17 +1237,17 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
{
- fstring user_name;
- fstring wks;
+ fstring user_name;
+ fstring wks;
- DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
+ DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
- rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
+ fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
+ fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
- DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+ DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
/*
* Pass the user through the NT -> unix user mapping
@@ -1495,18 +1257,19 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
(void)map_username(user_name);
/*
- * UNIX username case mangling not required, pass_oem_change
- * is case insensitive.
+ * Do any UNIX username case mangling.
*/
+ (void)Get_Pwnam( user_name, True);
- r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
- q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
+ if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
+ q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
+ r_u->status = NT_STATUS_WRONG_PASSWORD;
- init_samr_r_chgpasswd_user(r_u, r_u->status);
+ init_samr_r_chgpasswd_user(r_u, r_u->status);
- DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
+ DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
- return r_u->status;
+ return r_u->status;
}
/*******************************************************************
@@ -1517,8 +1280,8 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
{
uint32 i;
- UNIHDR *hdr_name=NULL;
- UNISTR2 *uni_name=NULL;
+ UNIHDR *hdr_name = NULL;
+ UNISTR2 *uni_name = NULL;
*pp_uni_name = NULL;
*pp_hdr_name = NULL;
@@ -1534,9 +1297,10 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
}
for (i = 0; i < num_names; i++) {
- DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
- init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
- init_uni_hdr(&hdr_name[i], &uni_name[i]);
+ int len = names[i] != NULL ? strlen(names[i]) : 0;
+ DEBUG(10, ("names[%d]:%s\n", i, names[i]));
+ init_uni_hdr(&hdr_name[i], len);
+ init_unistr2(&uni_name[i], names[i], len);
}
*pp_uni_name = uni_name;
@@ -1558,14 +1322,13 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
DOM_SID pol_sid;
int num_rids = q_u->num_rids1;
int i;
- uint32 acc_granted;
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
return NT_STATUS_INVALID_HANDLE;
if (num_rids > MAX_SAM_ENTRIES) {
@@ -1576,11 +1339,9 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
if (num_rids) {
if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
return NT_STATUS_NO_MEMORY;
- }
-
- r_u->status = NT_STATUS_NONE_MAPPED;
+ }
- become_root(); /* lookup_sid can require root privs */
+ r_u->status = NT_STATUS_NONE_MAPPED;
for (i = 0; i < num_rids; i++) {
fstring tmpname;
@@ -1591,7 +1352,7 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
group_attrs[i] = SID_NAME_UNKNOWN;
*group_names[i] = '\0';
- if (sid_equal(&pol_sid, get_global_sam_sid())) {
+ if (sid_equal(&pol_sid, &global_sam_sid)) {
sid_copy(&sid, &pol_sid);
sid_append_rid(&sid, q_u->rid[i]);
@@ -1599,13 +1360,10 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
r_u->status = NT_STATUS_OK;
group_attrs[i] = (uint32)type;
fstrcpy(group_names[i],tmpname);
- DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
}
}
}
- unbecome_root();
-
if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
return NT_STATUS_NO_MEMORY;
@@ -1617,67 +1375,51 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
}
/*******************************************************************
- _samr_open_user. Safe - gives out no passwd info.
+ _api_samr_open_user. Safe - gives out no passwd info.
********************************************************************/
-NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
+NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
{
SAM_ACCOUNT *sampass=NULL;
DOM_SID sid;
POLICY_HND domain_pol = q_u->domain_pol;
+ uint32 user_rid = q_u->user_rid;
POLICY_HND *user_pol = &r_u->user_pol;
struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- size_t sd_size;
BOOL ret;
- NTSTATUS nt_status;
- uint32 priv_list[3] = {SE_MACHINE_ACCOUNT, SE_ADD_USERS, SE_NONE};
r_u->status = NT_STATUS_OK;
- /* find the domain policy handle and get domain SID / access bits in the domain policy. */
- if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
+ /* find the domain policy handle. */
+ if (!find_policy_by_hnd(p, &domain_pol, NULL))
return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, priv_list, "_samr_open_user"))) {
- return nt_status;
- }
- nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- /* append the user's RID to it */
- if (!sid_append_rid(&sid, q_u->user_rid))
- return NT_STATUS_NO_SUCH_USER;
-
- /* check if access can be granted as requested by client. */
- samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
- se_map_generic(&des_access, &usr_generic_mapping);
- if (!NT_STATUS_IS_OK(nt_status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- priv_list, "_samr_open_user"))) {
- return nt_status;
- }
+ pdb_init_sam(&sampass);
become_root();
- ret=pdb_getsampwsid(sampass, &sid);
+ ret=pdb_getsampwrid(sampass, user_rid);
unbecome_root();
- /* check that the SID exists in our domain. */
+ /* check that the RID exists in our domain. */
if (ret == False) {
+ pdb_free_sam(sampass);
return NT_STATUS_NO_SUCH_USER;
}
- pdb_free_sam(&sampass);
+ samr_clear_sam_passwd(sampass);
+ pdb_free_sam(sampass);
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, user_rid))
+ return NT_STATUS_NO_SUCH_USER;
- /* associate the user's SID and access bits with the new handle. */
+ /* associate the user's SID with the new handle. */
if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
- info->acc_granted = acc_granted;
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
@@ -1690,25 +1432,26 @@ NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USE
get_user_info_10. Safe. Only gives out acb bits.
*************************************************************************/
-static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
+static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
{
SAM_ACCOUNT *smbpass=NULL;
BOOL ret;
- NTSTATUS nt_status;
- nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
}
+ pdb_init_sam(&smbpass);
+
become_root();
- ret = pdb_getsampwsid(smbpass, user_sid);
+ ret = pdb_getsampwrid(smbpass, user_rid);
unbecome_root();
if (ret==False) {
- DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
- return NT_STATUS_NO_SUCH_USER;
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(smbpass);
+ return False;
}
DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
@@ -1716,22 +1459,22 @@ static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DO
ZERO_STRUCTP(id10);
init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
- pdb_free_sam(&smbpass);
+ samr_clear_sam_passwd(smbpass);
+ pdb_free_sam(smbpass);
- return NT_STATUS_OK;
+ return True;
}
/*************************************************************************
get_user_info_12. OK - this is the killer as it gives out password info.
Ensure that this is only allowed on an encrypted connection with a root
- user. JRA.
+ user. JRA.
*************************************************************************/
-static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
+static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
{
SAM_ACCOUNT *smbpass=NULL;
BOOL ret;
- NTSTATUS nt_status;
if (!p->ntlmssp_auth_validated)
return NT_STATUS_ACCESS_DENIED;
@@ -1742,54 +1485,56 @@ static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_
/*
* Do *NOT* do become_root()/unbecome_root() here ! JRA.
*/
+ pdb_init_sam(&smbpass);
- nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- ret = pdb_getsampwsid(smbpass, user_sid);
+ ret = pdb_getsampwrid(smbpass, user_rid);
if (ret == False) {
- DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
- pdb_free_sam(&smbpass);
+ DEBUG(4, ("User 0x%x not found\n", user_rid));
+ pdb_free_sam(smbpass);
return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
}
DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
- pdb_free_sam(&smbpass);
+ pdb_free_sam(smbpass);
return NT_STATUS_ACCOUNT_DISABLED;
}
ZERO_STRUCTP(id12);
init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
- pdb_free_sam(&smbpass);
+ pdb_free_sam(smbpass);
return NT_STATUS_OK;
}
+#if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
/*************************************************************************
get_user_info_20
*************************************************************************/
-static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
+static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
{
SAM_ACCOUNT *sampass=NULL;
BOOL ret;
- pdb_init_sam_talloc(mem_ctx, &sampass);
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
+
+ pdb_init_sam(&sampass);
become_root();
- ret = pdb_getsampwsid(sampass, user_sid);
+ ret = pdb_getsampwrid(sampass, user_rid);
unbecome_root();
if (ret == False) {
- DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
- return NT_STATUS_NO_SUCH_USER;
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(sampass);
+ return False;
}
samr_clear_sam_passwd(sampass);
@@ -1799,34 +1544,36 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DO
ZERO_STRUCTP(id20);
init_sam_user_info20A(id20, sampass);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
- return NT_STATUS_OK;
+ return True;
}
+#endif
/*************************************************************************
get_user_info_21
*************************************************************************/
-static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
- DOM_SID *user_sid, DOM_SID *domain_sid)
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
{
SAM_ACCOUNT *sampass=NULL;
BOOL ret;
- NTSTATUS nt_status;
- nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
}
+ pdb_init_sam(&sampass);
+
become_root();
- ret = pdb_getsampwsid(sampass, user_sid);
+ ret = pdb_getsampwrid(sampass, user_rid);
unbecome_root();
if (ret == False) {
- DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
- return NT_STATUS_NO_SUCH_USER;
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(sampass);
+ return False;
}
samr_clear_sam_passwd(sampass);
@@ -1834,11 +1581,11 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
ZERO_STRUCTP(id21);
- nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
+ init_sam_user_info21A(id21, sampass);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
- return NT_STATUS_OK;
+ return True;
}
/*******************************************************************
@@ -1848,24 +1595,20 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
{
SAM_USERINFO_CTR *ctr;
+ uint32 rid = 0;
struct samr_info *info = NULL;
- DOM_SID domain_sid;
- uint32 rid;
-
+
r_u->status=NT_STATUS_OK;
/* search for the handle */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- domain_sid = info->sid;
-
- sid_split_rid(&domain_sid, &rid);
-
- if (!sid_check_is_in_our_domain(&info->sid))
+ /* find the user's rid */
+ if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
+ DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
if (!ctr)
@@ -1882,8 +1625,8 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
if (ctr->info.id10 == NULL)
return NT_STATUS_NO_MEMORY;
- if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
- return r_u->status;
+ if (!get_user_info_10(ctr->info.id10, rid))
+ return NT_STATUS_NO_SUCH_USER;
break;
#if 0
@@ -1901,7 +1644,6 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
(*ctr->
info.
id11));
- ZERO_STRUCTP(ctr->info.id11);
init_sam_user_info11(ctr->info.id11, &expire,
"BROOKFIELDS$", /* name */
0x03ef, /* user rid */
@@ -1917,25 +1659,24 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
if (ctr->info.id12 == NULL)
return NT_STATUS_NO_MEMORY;
- if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
+ if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
return r_u->status;
break;
-
+
case 20:
ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
if (ctr->info.id20 == NULL)
return NT_STATUS_NO_MEMORY;
- if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
- return r_u->status;
+ if (!get_user_info_20(ctr->info.id20, rid))
+ return NT_STATUS_NO_SUCH_USER;
break;
case 21:
ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
if (ctr->info.id21 == NULL)
return NT_STATUS_NO_MEMORY;
- if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
- &info->sid, &domain_sid)))
- return r_u->status;
+ if (!get_user_info_21(ctr->info.id21, rid))
+ return NT_STATUS_NO_SUCH_USER;
break;
default:
@@ -1945,7 +1686,7 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
init_samr_r_query_userinfo(r_u, ctr, r_u->status);
DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
-
+
return r_u->status;
}
@@ -1956,62 +1697,49 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
- DOM_SID sid;
DOM_GID *gids = NULL;
int num_groups = 0;
- uint32 acc_granted;
+ pstring groups;
+ uint32 rid;
+ struct samr_info *info = NULL;
BOOL ret;
- /*
- * from the SID in the request:
- * we should send back the list of DOMAIN GROUPS
- * the user is a member of
- *
- * and only the DOMAIN GROUPS
- * no ALIASES !!! neither aliases of the domain
- * nor aliases of the builtin SID
- *
- * JFM, 12/2/2001
- */
-
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_USER_GET_GROUPS, NULL, "_samr_query_usergroups"))) {
- return r_u->status;
- }
- if (!sid_check_is_in_our_domain(&sid))
+ /* find the user's rid */
+ if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
return NT_STATUS_OBJECT_TYPE_MISMATCH;
pdb_init_sam(&sam_pass);
-
+
become_root();
- ret = pdb_getsampwsid(sam_pass, &sid);
+ ret = pdb_getsampwrid(sam_pass, rid);
unbecome_root();
if (ret == False) {
- pdb_free_sam(&sam_pass);
+ samr_clear_sam_passwd(sam_pass);
+ pdb_free_sam(sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
-
- if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
+
+ get_domain_user_groups(groups, pdb_get_username(sam_pass));
+ gids = NULL;
+ num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
+
/* construct the response. lkclXXXX: gids are not copied! */
init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
-
+
DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
- pdb_free_sam(&sam_pass);
-
+ samr_clear_sam_passwd(sam_pass);
+ pdb_free_sam(sam_pass);
+
return r_u->status;
}
@@ -2034,8 +1762,6 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
time_t u_logout;
NTTIME nt_logout;
- uint32 account_policy_temp;
-
uint32 num_users=0, num_groups=0, num_aliases=0;
if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
@@ -2044,31 +1770,22 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
ZERO_STRUCTP(ctr);
r_u->status = NT_STATUS_OK;
-
+
DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
-
+
/* find the policy handle. open a policy on it. */
if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
-
+
switch (q_u->switch_value) {
case 0x01:
-
- account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
- min_pass_len = account_policy_temp;
+ /* Use defaults until we merge with HEAD db. JRA */
+ min_pass_len = MINPASSWDLENGTH; /* 5 chars minimum */
+ pass_hist = 0; /* don't keep any old password */
+ flag = 0; /* don't force user to logon */
+ u_expire = MAX_PASSWORD_AGE; /* 21 days */
+ u_min_age = 0; /* 0 days */
- account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
- pass_hist = account_policy_temp;
-
- account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
- flag = account_policy_temp;
-
- account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
- u_expire = account_policy_temp;
-
- account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
- u_min_age = account_policy_temp;
-
unix_to_nt_time_abs(&nt_expire, u_expire);
unix_to_nt_time_abs(&nt_min_age, u_min_age);
@@ -2077,17 +1794,17 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
break;
case 0x02:
become_root();
- r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
+ r_u->status=load_sampwd_entries(info, ACB_NORMAL);
unbecome_root();
- if (!NT_STATUS_IS_OK(r_u->status)) {
+ if (NT_STATUS_IS_ERR(r_u->status)) {
DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
return r_u->status;
}
num_users=info->disp_info.num_user_account;
free_samr_db(info);
- r_u->status=load_group_domain_entries(info, get_global_sam_sid());
- if (!NT_STATUS_IS_OK(r_u->status)) {
+ r_u->status=load_group_domain_entries(info, &global_sam_sid);
+ if (NT_STATUS_IS_ERR(r_u->status)) {
DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
return r_u->status;
}
@@ -2095,17 +1812,17 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
free_samr_db(info);
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
+ init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
num_users, num_groups, num_aliases);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
+ /* Use defaults until we merge with HEAD db. JRA */
+ u_logout = -1; /* don't force logout */
unix_to_nt_time_abs(&nt_logout, u_logout);
-
init_unk_info3(&ctr->info.inf3, nt_logout);
break;
case 0x05:
- init_unk_info5(&ctr->info.inf5, global_myname());
+ init_unk_info5(&ctr->info.inf5, global_myname);
break;
case 0x06:
init_unk_info6(&ctr->info.inf6);
@@ -2114,15 +1831,11 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
init_unk_info7(&ctr->info.inf7);
break;
case 0x0c:
- account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
- u_lock_duration = account_policy_temp * 60;
-
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
- u_reset_time = account_policy_temp * 60;
-
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
- lockout = account_policy_temp;
-
+ /* Use defaults until we merge with HEAD db. JRA */
+ u_lock_duration = 0; /* lockout for 0 minutes */
+ u_reset_time = 0; /* reset immediatly */
+ lockout = 0; /* don't lockout */
+
unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
@@ -2130,25 +1843,28 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
break;
default:
return NT_STATUS_INVALID_INFO_CLASS;
- }
-
+ }
+
init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
-
+
DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
-
+
return r_u->status;
}
/*******************************************************************
- _samr_create_user
+ _api_samr_create_user
Create an account, can be either a normal user or a machine.
This funcion will need to be updated for bdc/domain trusts.
********************************************************************/
-NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
+NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
- fstring account;
+ fstring mach_acct;
+ pstring err_str;
+ pstring msg_str;
+ int local_flags=0;
DOM_SID sid;
pstring add_script;
POLICY_HND dom_pol = q_u->domain_pol;
@@ -2157,51 +1873,33 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
POLICY_HND *user_pol = &r_u->user_pol;
struct samr_info *info = NULL;
BOOL ret;
- NTSTATUS nt_status;
- struct passwd *pw;
- uint32 acc_granted;
- SEC_DESC *psd;
- size_t sd_size;
- uint32 new_rid = 0;
- /* check this, when giving away 'add computer to domain' privs */
- uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
- uint32 priv_list[3] = {SE_MACHINE_ACCOUNT, SE_ADD_USERS, SE_NONE};
- /* Get the domain SID stored in the domain policy */
- if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
+ /* find the policy handle. open a policy on it. */
+ if (!find_policy_by_hnd(p, &dom_pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, priv_list, "_samr_create_user"))) {
- return nt_status;
- }
-
- if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
- /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
- this parameter is not an account type */
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* find the account: tell the caller if it exists.
+ /* find the machine account: tell the caller if it exists.
lkclXXXX i have *no* idea if this is a problem or not
or even if you are supposed to construct a different
reply if the account already exists...
*/
- rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
- strlower_m(account);
+ fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
+ strlower(mach_acct);
pdb_init_sam(&sam_pass);
become_root();
- ret = pdb_getsampwnam(sam_pass, account);
+ ret = pdb_getsampwnam(sam_pass, mach_acct);
unbecome_root();
if (ret == True) {
- /* this account exists: say so */
- pdb_free_sam(&sam_pass);
+ /* machine account exists: say so */
+ pdb_free_sam(sam_pass);
return NT_STATUS_USER_EXISTS;
}
- pdb_free_sam(&sam_pass);
+ local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
+ local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
/*
* NB. VERY IMPORTANT ! This call must be done as the current pipe user,
@@ -2219,136 +1917,60 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
*
* So we go the easy way, only check after if the account exists.
* JFM (2/3/2001), to clear any possible bad understanding (-:
- *
- * We now have seperate script paramaters for adding users/machines so we
- * now have some sainity-checking to match.
*/
+
+ pstrcpy(add_script, lp_adduser_script());
+
+ if(*add_script)
+ smb_create_user(mach_acct, NULL);
- DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
-
- /*
- * we used to have code here that made sure the acb_info flags
- * matched with the users named (e.g. an account flags as a machine
- * trust account ended in '$'). It has been ifdef'd out for a long
- * time, so I replaced it with this comment. --jerry
- */
+ /* add the user in the smbpasswd file or the Samba authority database */
+ if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
+ DEBUG(0, ("%s\n", err_str));
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_ACCESS_DENIED;
+ }
- /* the passdb lookup has failed; check to see if we need to run the
- add user/machine script */
-
- /*
- * we can't check both the ending $ and the acb_info.
- *
- * UserManager creates trust accounts (ending in $,
- * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
- * JFM, 11/29/2001
- */
- if (account[strlen(account)-1] == '$') {
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_MACHINE_ACCOUNT)) || geteuid() == 0) {
- DEBUG(3, ("user [%s] has been granted Add Machines privilege!\n", p->user_name));
- become_root();
- pstrcpy(add_script, lp_addmachine_script());
- } else {
- DEBUG(3, ("user [%s] doesn't have Add Machines privilege!\n", p->user_name));
- return NT_STATUS_ACCESS_DENIED;
- }
- } else {
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_ADD_USERS)) || geteuid() == 0) {
- DEBUG(3, ("user [%s] has been granted Add Users privilege!\n", p->user_name));
- become_root();
- pstrcpy(add_script, lp_adduser_script());
- } else {
- DEBUG(3, ("user [%s] doesn't have Add Users privilege!\n", p->user_name));
- return NT_STATUS_ACCESS_DENIED;
- }
+ become_root();
+ ret = pdb_getsampwnam(sam_pass, mach_acct);
+ unbecome_root();
+ if (ret == False) {
+ /* account doesn't exist: say so */
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_ACCESS_DENIED;
}
-
- pw = Get_Pwnam(account);
-
- /*********************************************************************
- * HEADS UP! If we have to create a new user account, we have to get
- * a new RID from somewhere. This used to be done by the passdb
- * backend. It has been moved into idmap now. Since idmap is now
- * wrapped up behind winbind, this means you have to run winbindd if you
- * want new accounts to get a new RID when "enable rid algorithm = no".
- * Tough. We now have a uniform way of allocating RIDs regardless
- * of what ever passdb backend people may use.
- * --jerry (2003-07-10)
- *********************************************************************/
-
- if ( !pw ) {
-
- if (add_script[0] != '\0') {
- int add_ret;
- all_string_sub(add_script, "%u", account, sizeof(account));
- add_ret = smbrun(add_script,NULL);
- }
- else /* no add user script -- ask winbindd to do it */
- {
- DEBUG(0, ("_samr_create_user: lp_adduser_script() = %s add_script = %s\n", lp_adduser_script(), add_script));
- if (!winbind_create_user(account, &new_rid)) {
- DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
- account));
- }
- }
-
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_INVALID_HANDLE;
}
-
- /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
- if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
- goto done;
-
- pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
-
- if (!pdb_add_sam_account(sam_pass)) {
- pdb_free_sam(&sam_pass);
- DEBUG(0, ("could not add user/computer %s to passdb !?\n",
- account));
- nt_status = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
-
- /* Get the user's SID */
- sid_copy(&sid, pdb_get_user_sid(sam_pass));
-
- samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
- se_map_generic(&des_access, &usr_generic_mapping);
- if (!NT_STATUS_IS_OK(nt_status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- priv_list, "_samr_create_user"))) {
- goto done;
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_NO_SUCH_USER;
}
/* associate the user's SID with the new handle. */
+
if ((info = get_samr_info_by_sid(&sid)) == NULL) {
- pdb_free_sam(&sam_pass);
- nt_status = NT_STATUS_NO_MEMORY;
- goto done;
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(info);
- info->sid = sid;
- info->acc_granted = acc_granted;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
- pdb_free_sam(&sam_pass);
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- goto done;
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- r_u->user_rid=pdb_get_user_rid(sam_pass);
-
- r_u->access_granted = acc_granted;
-
- pdb_free_sam(&sam_pass);
+ r_u->user_rid=sam_pass->user_rid;
+ r_u->unknown_0 = 0x000703ff;
- nt_status = NT_STATUS_OK;
+ pdb_free_sam(sam_pass);
-done:
- unbecome_root();
- return nt_status;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -2358,15 +1980,6 @@ done:
NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
{
struct samr_info *info = NULL;
- uint32 des_access = q_u->access_mask;
-
- /* Access check */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_connect_anon\n"));
- r_u->status = NT_STATUS_ACCESS_DENIED;
- return r_u->status;
- }
/* set up the SAMR connect_anon response */
@@ -2376,13 +1989,6 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO
if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
- /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
- was observed from a win98 client trying to enumerate users (when configured
- user level access control on shares) --jerry */
-
- se_map_generic( &des_access, &sam_generic_mapping );
- info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
-
info->status = q_u->unknown_0;
/* get a (unique) handle. open a policy on it. */
@@ -2399,88 +2005,15 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO
NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
{
struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- size_t sd_size;
- NTSTATUS nt_status;
-
-
- DEBUG(5,("_samr_connect: %d\n", __LINE__));
-
- /* Access check */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_connect\n"));
- r_u->status = NT_STATUS_ACCESS_DENIED;
- return r_u->status;
- }
-
- samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access, &sam_generic_mapping);
- if (!NT_STATUS_IS_OK(nt_status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- NULL, "_samr_connect"))) {
- return nt_status;
- }
-
- r_u->status = NT_STATUS_OK;
-
- /* associate the user's SID and access granted with the new handle. */
- if ((info = get_samr_info_by_sid(NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
- info->status = q_u->access_mask;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
DEBUG(5,("_samr_connect: %d\n", __LINE__));
- return r_u->status;
-}
-
-/*******************************************************************
- samr_connect4
- ********************************************************************/
-
-NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
-{
- struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- size_t sd_size;
- NTSTATUS nt_status;
-
-
- DEBUG(5,("_samr_connect4: %d\n", __LINE__));
-
- /* Access check */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_connect4\n"));
- r_u->status = NT_STATUS_ACCESS_DENIED;
- return r_u->status;
- }
-
- samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access, &sam_generic_mapping);
- if (!NT_STATUS_IS_OK(nt_status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- NULL, "_samr_connect"))) {
- return nt_status;
- }
-
r_u->status = NT_STATUS_OK;
- /* associate the user's SID and access granted with the new handle. */
+ /* associate the user's SID with the new handle. */
if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
- info->acc_granted = acc_granted;
info->status = q_u->access_mask;
/* get a (unique) handle. open a policy on it. */
@@ -2498,22 +2031,15 @@ NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *
NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
{
- struct samr_info *info;
fstring domain_name;
DOM_SID sid;
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
+ if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, info->acc_granted,
- SA_RIGHT_SAM_ENUM_DOMAINS, NULL, "_samr_lookup_domain")))
- {
- return r_u->status;
- }
-
- rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
+ fstrcpy(domain_name, dos_unistrn2( q_u->uni_domain.buffer, q_u->uni_domain.uni_str_len));
ZERO_STRUCT(sid);
@@ -2554,8 +2080,10 @@ static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
return False;
for (i = 0; i < num_sam_entries; i++) {
- init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
- init_sam_entry(&sam[i], &uni_name[i], 0);
+ int len = doms[i] != NULL ? strlen(doms[i]) : 0;
+
+ init_sam_entry(&sam[i], len, 0);
+ init_unistr2(&uni_name[i], doms[i], len);
}
*pp_sam = sam;
@@ -2570,24 +2098,23 @@ static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
{
- struct samr_info *info;
uint32 num_entries = 2;
fstring dom[2];
- const char *name;
+ char *name;
r_u->status = NT_STATUS_OK;
-
- if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, NULL, "_samr_enum_domains"))) {
- return r_u->status;
- }
- name = get_global_sam_name();
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ name = global_myworkgroup;
+ break;
+ default:
+ name = global_myname;
+ }
fstrcpy(dom[0],name);
- strupper_m(dom[0]);
+ strupper(dom[0]);
fstrcpy(dom[1],"Builtin");
if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
@@ -2602,41 +2129,27 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN
api_samr_open_alias
********************************************************************/
-NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
+NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
{
DOM_SID sid;
POLICY_HND domain_pol = q_u->dom_pol;
uint32 alias_rid = q_u->rid_alias;
POLICY_HND *alias_pol = &r_u->pol;
- struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- size_t sd_size;
- NTSTATUS status;
+ struct samr_info *info = NULL;
r_u->status = NT_STATUS_OK;
- /* find the domain policy and get the SID / access bits stored in the domain policy */
- if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
+ /* get the domain policy. */
+ if (!find_policy_by_hnd(p, &domain_pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, NULL, "_samr_open_alias"))) {
- return status;
- }
/* append the alias' RID to it */
- if (!sid_append_rid(&sid, alias_rid))
+ if(!sid_append_rid(&sid, alias_rid))
return NT_STATUS_NO_SUCH_USER;
-
- /*check if access can be granted as requested by client. */
- samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access,&ali_generic_mapping);
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- NULL, "_samr_open_alias"))) {
- return status;
- }
/*
* we should check if the rid really exist !!!
@@ -2646,8 +2159,6 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
/* associate the user's SID with the new handle. */
if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
@@ -2660,38 +2171,37 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
set_user_info_10
********************************************************************/
-static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
+static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
{
SAM_ACCOUNT *pwd =NULL;
BOOL ret;
pdb_init_sam(&pwd);
- ret = pdb_getsampwsid(pwd, sid);
+ ret = pdb_getsampwrid(pwd, rid);
if(ret==False) {
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return False;
}
if (id10 == NULL) {
DEBUG(5, ("set_user_info_10: NULL id10\n"));
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return False;
}
-
- /* FIX ME: check if the value is really changed --metze */
- if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
- pdb_free_sam(&pwd);
+
+ if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
+ pdb_free_sam(pwd);
return False;
}
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
return False;
}
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return True;
}
@@ -2700,120 +2210,49 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
set_user_info_12
********************************************************************/
-static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
+static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
pdb_init_sam(&pwd);
- if(!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
+ if(!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
return False;
}
if (id12 == NULL) {
DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return False;
}
- if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
- pdb_free_sam(&pwd);
+ if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
+ pdb_free_sam(pwd);
return False;
}
- if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
- pdb_free_sam(&pwd);
+ if (!pdb_set_nt_passwd(pwd, id12->nt_pwd)) {
+ pdb_free_sam(pwd);
return False;
}
- if (!pdb_set_pass_changed_now (pwd)) {
- pdb_free_sam(&pwd);
- return False;
- }
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
return False;
}
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return True;
}
/*******************************************************************
- The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
- ********************************************************************/
-static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
-{
- struct group *grp;
- gid_t gid;
-
- if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
- &gid))) {
- DEBUG(2,("Could not get gid for primary group of "
- "user %s\n", pdb_get_username(sampass)));
- return False;
- }
-
- grp = getgrgid(gid);
-
- if (grp == NULL) {
- DEBUG(2,("Could not find primary group %lu for "
- "user %s\n", (unsigned long)gid,
- pdb_get_username(sampass)));
- return False;
- }
-
- if (smb_set_primary_group(grp->gr_name,
- pdb_get_username(sampass)) != 0) {
- DEBUG(2,("Could not set primary group for user %s to "
- "%s\n",
- pdb_get_username(sampass), grp->gr_name));
- return False;
- }
-
- return True;
-}
-
-
-/*******************************************************************
- set_user_info_20
- ********************************************************************/
-
-static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
-{
- SAM_ACCOUNT *pwd = NULL;
-
- if (id20 == NULL) {
- DEBUG(5, ("set_user_info_20: NULL id20\n"));
- return False;
- }
-
- pdb_init_sam(&pwd);
-
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
- copy_id20_to_sam_passwd(pwd, id20);
-
- /* write the change out */
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
- pdb_free_sam(&pwd);
-
- return True;
-}
-/*******************************************************************
set_user_info_21
********************************************************************/
-static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
+static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
+ BOOL result = True;
if (id21 == NULL) {
DEBUG(5, ("set_user_info_21: NULL id21\n"));
@@ -2822,11 +2261,12 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
pdb_init_sam(&pwd);
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
+ if (!pdb_getsampwrid(pwd, rid)) {
+ result = False;
+ goto done;
}
+ /* we make a copy so that we can modify stuff */
copy_id21_to_sam_passwd(pwd, id21);
/*
@@ -2836,30 +2276,30 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
* id21. I don't know if they need to be set. --jerry
*/
- if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
- set_unix_primary_group(pwd);
-
/* write the change out */
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
- return False;
+ if(!pdb_update_sam_account(pwd, True)) {
+ result = False;
+ goto done;
}
- pdb_free_sam(&pwd);
-
- return True;
+done:
+ pdb_free_sam(pwd);
+ return result;
}
/*******************************************************************
set_user_info_23
********************************************************************/
-static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
+static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
- pstring plaintext_buf;
+ uint8 nt_hash[16];
+ uint8 lm_hash[16];
+ pstring buf;
uint32 len;
uint16 acct_ctrl;
+ BOOL result = True;
if (id23 == NULL) {
DEBUG(5, ("set_user_info_23: NULL id23\n"));
@@ -2868,129 +2308,118 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
pdb_init_sam(&pwd);
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
+ if (!pdb_getsampwrid(pwd, rid)) {
+ result = False;
+ goto done;
}
- DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
- pdb_get_username(pwd)));
-
acct_ctrl = pdb_get_acct_ctrl(pwd);
-
- if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
- pdb_free_sam(&pwd);
- return False;
+
+ copy_id23_to_sam_passwd(pwd, id23);
+
+ if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
+ result = False;
+ goto done;
}
- if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
- pdb_free_sam(&pwd);
- return False;
+ if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
+ result = False;
+ goto done;
+ }
+ if (!pdb_set_nt_passwd(pwd, nt_hash)) {
+ result = False;
+ goto done;
}
-
- copy_id23_to_sam_passwd(pwd, id23);
/* if it's a trust account, don't update /etc/passwd */
- if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
- ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
- ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
- DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
+ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
+ ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
+ ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
+ DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
} else {
/* update the UNIX password */
- if (lp_unix_password_sync() ) {
- struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
- if (!passwd) {
- DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
+ if (lp_unix_password_sync() )
+ if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
+ result = False;
+ goto done;
}
-
- if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
- pdb_free_sam(&pwd);
- return False;
- }
- }
}
- ZERO_STRUCT(plaintext_buf);
+ memset(buf, 0, sizeof(buf));
- if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
- set_unix_primary_group(pwd);
-
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
- return False;
+ if(!pdb_update_sam_account(pwd, True)) {
+ result = False;
+ goto done;
}
- pdb_free_sam(&pwd);
-
- return True;
+done:
+ pdb_free_sam(pwd);
+ return result;
}
/*******************************************************************
set_user_info_pw
********************************************************************/
-static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
+static BOOL set_user_info_pw(char *pass, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
+ uchar nt_hash[16];
+ uchar lm_hash[16];
uint32 len;
- pstring plaintext_buf;
+ pstring buf;
uint16 acct_ctrl;
pdb_init_sam(&pwd);
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
+ if (!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
return False;
}
- DEBUG(5, ("Attempting administrator password change for user %s\n",
- pdb_get_username(pwd)));
-
acct_ctrl = pdb_get_acct_ctrl(pwd);
- ZERO_STRUCT(plaintext_buf);
+ memset(buf, 0, sizeof(buf));
- if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
- pdb_free_sam(&pwd);
+ if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
+ pdb_free_sam(pwd);
return False;
}
- if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
- pdb_free_sam(&pwd);
+ if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
+ if (!pdb_set_nt_passwd(pwd, nt_hash)) {
+ pdb_free_sam(pwd);
return False;
}
/* if it's a trust account, don't update /etc/passwd */
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
- ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
- ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
- DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
+ ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
+ ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
+ DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
} else {
/* update the UNIX password */
- if (lp_unix_password_sync()) {
- struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
- if (!passwd) {
- DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
- }
-
- if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
- pdb_free_sam(&pwd);
+ if (lp_unix_password_sync())
+ if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
+ pdb_free_sam(pwd);
return False;
}
- }
}
- ZERO_STRUCT(plaintext_buf);
+ memset(buf, 0, sizeof(buf));
- DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
+ DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
/* update the SAMBA password */
- if(!pdb_update_sam_account(pwd)) {
- pdb_free_sam(&pwd);
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
return False;
}
- pdb_free_sam(&pwd);
+ pdb_free_sam(pwd);
return True;
}
@@ -3001,83 +2430,78 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
{
+ uint32 rid = 0x0;
DOM_SID sid;
+ struct current_user user;
+ SAM_ACCOUNT *sam_pass=NULL;
+ unsigned char sess_key[16];
POLICY_HND *pol = &q_u->pol;
uint16 switch_value = q_u->switch_value;
SAM_USERINFO_CTR *ctr = q_u->ctr;
- uint32 acc_granted;
- uint32 acc_required;
- uint32 priv_list[3] = {SE_MACHINE_ACCOUNT, SE_ADD_USERS, SE_NONE};
- BOOL priv_to_root = False;
+ BOOL ret;
DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
r_u->status = NT_STATUS_OK;
- /* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, acc_required, priv_list, "_samr_set_userinfo"))) {
- return r_u->status;
+ if (p->ntlmssp_auth_validated) {
+ memcpy(&user, &p->pipe_user, sizeof(user));
+ } else {
+ extern struct current_user current_user;
+ memcpy(&user, &current_user, sizeof(user));
}
- if (geteuid() != sec_initial_uid()) {
- SAM_ACCOUNT *pwd = NULL;
-
- pdb_init_sam(&pwd);
-
- become_root();
- if (!pdb_getsampwsid(pwd, &sid)) {
- unbecome_root();
- pdb_free_sam(&pwd);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_ADD_USERS))) {
- priv_to_root = True;
+ /* find the policy handle. open a policy on it. */
+ if (!get_lsa_policy_samr_sid(p, pol, &sid))
+ return NT_STATUS_INVALID_HANDLE;
- } else if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_MACHINE_ACCOUNT))) {
- if (pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) {
- priv_to_root = True;
- }
- } else {
- unbecome_root();
- return NT_STATUS_ACCESS_DENIED;
- }
- }
+ sid_split_rid(&sid, &rid);
- DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
+ DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
if (ctr == NULL) {
DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
- if (priv_to_root) unbecome_root();
return NT_STATUS_INVALID_INFO_CLASS;
}
+
+ pdb_init_sam(&sam_pass);
+
+ /*
+ * We need the NT hash of the user who is changing the user's password.
+ * This NT hash is used to generate a "user session key"
+ * This "user session key" is in turn used to encrypt/decrypt the user's password.
+ */
+
+ become_root();
+ ret = pdb_getsampwuid(sam_pass, user.uid);
+ unbecome_root();
+ if(ret == False) {
+ DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memset(sess_key, '\0', 16);
+ mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
+
+ pdb_free_sam(sam_pass);
+ sam_pass = NULL;
+
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch (switch_value) {
case 0x12:
- if (!set_user_info_12(ctr->info.id12, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_12(ctr->info.id12, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
case 24:
- if (!p->session_key.length) {
- if (priv_to_root) unbecome_root();
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
- SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
dump_data(100, (char *)ctr->info.id24->pass, 516);
- if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
case 25:
@@ -3090,41 +2514,29 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
* info level and W2K SP2 drops down to level 23... JRA.
*/
- if (!p->session_key.length) {
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
- SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
+ SamOEMhash(ctr->info.id25->pass, sess_key, 532);
dump_data(100, (char *)ctr->info.id25->pass, 532);
- if (!set_user_info_pw(ctr->info.id25->pass, &sid))
+ if (!set_user_info_pw(ctr->info.id25->pass, rid))
return NT_STATUS_ACCESS_DENIED;
break;
#endif
- if (priv_to_root) unbecome_root();
return NT_STATUS_INVALID_INFO_CLASS;
case 23:
- if (!p->session_key.length) {
- if (priv_to_root) unbecome_root();
- return NT_STATUS_NO_USER_SESSION_KEY;
- }
- SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
dump_data(100, (char *)ctr->info.id23->pass, 516);
- if (!set_user_info_23(ctr->info.id23, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_23(ctr->info.id23, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
default:
- if (priv_to_root) unbecome_root();
return NT_STATUS_INVALID_INFO_CLASS;
}
- if (priv_to_root) unbecome_root();
return r_u->status;
}
@@ -3135,57 +2547,25 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
{
DOM_SID sid;
+ uint32 rid = 0x0;
SAM_USERINFO_CTR *ctr = q_u->ctr;
POLICY_HND *pol = &q_u->pol;
uint16 switch_value = q_u->switch_value;
- uint32 acc_granted;
- uint32 acc_required;
- uint32 priv_list[3] = {SE_MACHINE_ACCOUNT, SE_ADD_USERS, SE_NONE};
- BOOL priv_to_root = False;
DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
+ if (!get_lsa_policy_samr_sid(p, pol, &sid))
return NT_STATUS_INVALID_HANDLE;
-
- acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, acc_required, priv_list, "_samr_set_userinfo2"))) {
- return r_u->status;
- }
-
- if (geteuid() != sec_initial_uid()) {
- SAM_ACCOUNT *pwd = NULL;
-
- pdb_init_sam(&pwd);
- become_root();
- if (!pdb_getsampwsid(pwd, &sid)) {
- unbecome_root();
- pdb_free_sam(&pwd);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_ADD_USERS))) {
- priv_to_root = True;
-
- } else if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_MACHINE_ACCOUNT))) {
- if (pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) {
- priv_to_root = True;
- }
- } else {
- unbecome_root();
- return NT_STATUS_ACCESS_DENIED;
- }
- }
+ sid_split_rid(&sid, &rid);
- DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
+ DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
if (ctr == NULL) {
DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
- if (priv_to_root) unbecome_root();
return NT_STATUS_INVALID_INFO_CLASS;
}
@@ -3194,36 +2574,22 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch (switch_value) {
case 21:
- if (!set_user_info_21(ctr->info.id21, &sid)) {
- if (priv_to_root) unbecome_root();
- return NT_STATUS_ACCESS_DENIED;
- }
- break;
- case 20:
- if (!set_user_info_20(ctr->info.id20, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_21(ctr->info.id21, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
case 16:
- if (!set_user_info_10(ctr->info.id10, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_10(ctr->info.id10, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
case 18:
/* Used by AS/U JRA. */
- if (!set_user_info_12(ctr->info.id12, &sid)) {
- if (priv_to_root) unbecome_root();
+ if (!set_user_info_12(ctr->info.id12, rid))
return NT_STATUS_ACCESS_DENIED;
- }
break;
default:
- if (priv_to_root) unbecome_root();
return NT_STATUS_INVALID_INFO_CLASS;
}
- if (priv_to_root) unbecome_root();
return r_u->status;
}
@@ -3233,89 +2599,22 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
- int num_groups = 0, tmp_num_groups=0;
- uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
- struct samr_info *info = NULL;
- int i,j;
-
- NTSTATUS ntstatus1;
- NTSTATUS ntstatus2;
-
- /* until i see a real useraliases query, we fack one up */
-
- /* I have seen one, JFM 2/12/2001 */
- /*
- * Explanation of what this call does:
- * for all the SID given in the request:
- * return a list of alias (local groups)
- * that have those SID as members.
- *
- * and that's the alias in the domain specified
- * in the policy_handle
- *
- * if the policy handle is on an incorrect sid
- * for example a user's sid
- * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
- */
-
- r_u->status = NT_STATUS_OK;
-
- DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- ntstatus1 = access_check_samr_function(p, info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, NULL, "_samr_query_useraliases");
- ntstatus2 = access_check_samr_function(p, info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, NULL, "_samr_query_useraliases");
-
- if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
- if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
- !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
- return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
- }
- }
-
- if (!sid_check_is_domain(&info->sid) &&
- !sid_check_is_builtin(&info->sid))
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
-
- for (i=0; i<q_u->num_sids1; i++) {
-
- r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
-
- /*
- * if there is an error, we just continue as
- * it can be an unfound user or group
- */
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
- continue;
- }
-
- if (tmp_num_groups==0) {
- DEBUG(10,("_samr_query_useraliases: no groups found\n"));
- continue;
- }
+ uint32 *rid=NULL;
+ int num_rids;
- new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
- if (new_rids==NULL) {
- DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
+ num_rids = 1;
+ rid=(uint32 *)talloc_zero(p->mem_ctx, num_rids*sizeof(uint32));
+ if (rid == NULL)
+ return NT_STATUS_NO_MEMORY;
- for (j=0; j<tmp_num_groups; j++)
- rids[j+num_groups]=tmp_rids[j];
-
- safe_free(tmp_rids);
-
- num_groups+=tmp_num_groups;
- }
-
- init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
+ /* until i see a real useraliases query, we fack one up */
+
+ rid[0] = BUILTIN_ALIAS_RID_USERS;
+
+ init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_OK);
+
return NT_STATUS_OK;
+
}
/*********************************************************************
@@ -3324,196 +2623,18 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
{
- int i;
-
- int num_sids = 0;
- DOM_SID2 *sid;
- DOM_SID *sids=NULL;
-
- DOM_SID alias_sid;
-
- uint32 acc_granted;
-
- /* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status =
- access_check_samr_function(p, acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, NULL, "_samr_query_aliasmem"))) {
- return r_u->status;
- }
-
- DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
-
- if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
- if (num_sids!=0 && sid == NULL) {
- SAFE_FREE(sids);
- return NT_STATUS_NO_MEMORY;
- }
-
- for (i = 0; i < num_sids; i++) {
- init_dom_sid2(&sid[i], &sids[i]);
- }
-
- init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
-
- SAFE_FREE(sids);
-
- return NT_STATUS_OK;
-}
-
-static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
-{
- int i;
-
- if ((*num) >= groups_max())
- return;
-
- for (i=0; i<*num; i++) {
- if ((*uids)[i] == uid)
- return;
- }
-
- *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
-
- if (*uids == NULL)
- return;
-
- (*uids)[*num] = uid;
- *num += 1;
+ DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
-
-static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
-{
- struct group *grp;
- char **gr;
- struct sys_pwent *userlist, *user;
-
- *uids = NULL;
- *num = 0;
-
- /* We only look at our own sam, so don't care about imported stuff */
-
- winbind_off();
-
- if ((grp = getgrgid(gid)) == NULL) {
- winbind_on();
- return False;
- }
-
- /* Primary group members */
-
- userlist = getpwent_list();
-
- for (user = userlist; user != NULL; user = user->next) {
- if (user->pw_gid != gid)
- continue;
- add_uid_to_array_unique(user->pw_uid, uids, num);
- }
-
- pwent_free(userlist);
-
- /* Secondary group members */
-
- gr = grp->gr_mem;
- while ((*gr != NULL) && ((*gr)[0] != '\0')) {
- struct passwd *pw = getpwnam(*gr);
-
- if (pw == NULL)
- continue;
-
- add_uid_to_array_unique(pw->pw_uid, uids, num);
-
- gr += 1;
- }
-
- winbind_on();
-
- return True;
-}
-
/*********************************************************************
_samr_query_groupmem
*********************************************************************/
NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
{
- int final_num_rids, i;
- DOM_SID group_sid;
- fstring group_sid_str;
- uid_t *uids;
- int num;
- gid_t gid;
-
- uint32 *rid=NULL;
- uint32 *attr=NULL;
-
- uint32 acc_granted;
-
- /* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, NULL, "_samr_query_groupmem"))) {
- return r_u->status;
- }
-
- sid_to_string(group_sid_str, &group_sid);
- DEBUG(10, ("sid is %s\n", group_sid_str));
-
- if (!sid_check_is_in_our_domain(&group_sid)) {
- DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- DEBUG(10, ("lookup on Domain SID\n"));
-
- if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
- return NT_STATUS_NO_SUCH_GROUP;
-
- if(!get_memberuids(gid, &uids, &num))
- return NT_STATUS_NO_SUCH_GROUP;
-
- rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
- attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
-
- if (num!=0 && (rid==NULL || attr==NULL))
- return NT_STATUS_NO_MEMORY;
-
- final_num_rids = 0;
-
- for (i=0; i<num; i++) {
- DOM_SID sid;
-
- if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
- DEBUG(1, ("Could not map member uid to SID\n"));
- continue;
- }
-
- if (!sid_check_is_in_our_domain(&sid)) {
- DEBUG(1, ("Inconsistent SAM -- group member uid not "
- "in our domain\n"));
- continue;
- }
-
- sid_peek_rid(&sid, &rid[final_num_rids]);
-
- /* Hmm. In a trace I got the constant 7 here from NT. */
- attr[final_num_rids] = SID_NAME_USER;
-
- final_num_rids += 1;
- }
-
- SAFE_FREE(uids);
-
- init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
- NT_STATUS_OK);
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3522,23 +2643,8 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_
NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
{
- DOM_SID alias_sid;
- uint32 acc_granted;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, NULL, "_samr_add_aliasmem"))) {
- return r_u->status;
- }
-
- DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
-
- if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3547,24 +2653,8 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
{
- DOM_SID alias_sid;
- uint32 acc_granted;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, NULL, "_samr_del_aliasmem"))) {
- return r_u->status;
- }
-
- DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
- sid_string_static(&alias_sid)));
-
- if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3573,54 +2663,8 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
{
- DOM_SID group_sid;
- DOM_SID user_sid;
- fstring grp_name;
- fstring usr_name;
- uint32 acc_granted;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, NULL, "_samr_add_groupmem"))) {
- return r_u->status;
- }
-
- if (!sid_to_local_dom_grp_name(&group_sid, grp_name)) {
- DEBUG(1, ("Could not find group for SID %s\n",
- sid_string_static(&group_sid)));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- sid_copy(&user_sid, get_global_sam_sid());
- sid_append_rid(&user_sid, q_u->rid);
-
- if (!sid_to_local_user_name(&user_sid, usr_name)) {
- DEBUG(1, ("Could not find user for SID %s\n",
- sid_string_static(&user_sid)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- /* if the user is already in the group */
- if(user_in_unix_group_list(usr_name, grp_name)) {
- return NT_STATUS_MEMBER_IN_GROUP;
- }
-
- /*
- * ok, the group exist, the user exist, the user is not in the group,
- *
- * we can (finally) add it to the group !
- */
-
- smb_add_user_group(grp_name, usr_name);
-
- /* check if the user has been added then ... */
- if(!user_in_unix_group_list(usr_name, grp_name)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3629,87 +2673,8 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
{
- DOM_SID group_sid;
- DOM_SID user_sid;
- fstring grp_name;
- fstring usr_name;
- uint32 acc_granted;
-
- /*
- * delete the group member named q_u->rid
- * who is a member of the sid associated with the handle
- * the rid is a user's rid as the group is a domain group.
- */
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, NULL, "_samr_del_groupmem"))) {
- return r_u->status;
- }
-
- if (!sid_to_local_dom_grp_name(&group_sid, grp_name)) {
- DEBUG(1, ("Could not find group for SID %s\n",
- sid_string_static(&group_sid)));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- sid_copy(&user_sid, get_global_sam_sid());
- sid_append_rid(&user_sid, q_u->rid);
-
- if (!sid_to_local_user_name(&user_sid, usr_name)) {
- DEBUG(1, ("Could not find user for SID %s\n",
- sid_string_static(&user_sid)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- /* if the user is not in the group */
- if (!user_in_unix_group_list(usr_name, grp_name)) {
- return NT_STATUS_MEMBER_NOT_IN_GROUP;
- }
-
- smb_delete_user_group(grp_name, usr_name);
-
- /* check if the user has been removed then ... */
- if(user_in_unix_group_list(usr_name, grp_name)) {
- /* don't know what to reply else */
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_OK;
-
-}
-
-/****************************************************************************
- Delete a UNIX user on demand.
-****************************************************************************/
-
-static int smb_delete_user(const char *unix_user)
-{
- pstring del_script;
- int ret;
-
- /* try winbindd first since it is impossible to determine where
- a user came from via NSS. Try the delete user script if this fails
- meaning the user did not exist in winbindd's list of accounts */
-
- if ( winbind_delete_user( unix_user ) ) {
- DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
- return 0;
- }
-
-
- /* fall back to 'delete user script' */
-
- pstrcpy(del_script, lp_deluser_script());
- if (! *del_script)
- return -1;
- all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
- ret = smbrun(del_script,NULL);
- DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
-
- return ret;
+ DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3718,53 +2683,8 @@ static int smb_delete_user(const char *unix_user)
NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
{
- DOM_SID user_sid;
- SAM_ACCOUNT *sam_pass=NULL;
- uint32 acc_granted;
-
- DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, STD_RIGHT_DELETE_ACCESS, NULL, "_samr_delete_dom_user"))) {
- return r_u->status;
- }
-
- if (!sid_check_is_in_our_domain(&user_sid))
- return NT_STATUS_CANNOT_DELETE;
-
- /* check if the user exists before trying to delete */
- pdb_init_sam(&sam_pass);
- if(!pdb_getsampwsid(sam_pass, &user_sid)) {
- DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
- sid_string_static(&user_sid)));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- /* delete the unix side */
- /*
- * note: we don't check if the delete really happened
- * as the script is not necessary present
- * and maybe the sysadmin doesn't want to delete the unix side
- */
- smb_delete_user(pdb_get_username(sam_pass));
-
- /* and delete the samba side */
- if (!pdb_delete_sam_account(sam_pass)) {
- DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_CANNOT_DELETE;
- }
-
- pdb_free_sam(&sam_pass);
-
- if (!close_policy_hnd(p, &q_u->user_pol))
- return NT_STATUS_OBJECT_NAME_INVALID;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3773,38 +2693,8 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
{
- DOM_SID group_sid;
- fstring grp_name;
- struct group *grp;
- uint32 acc_granted;
-
- DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, STD_RIGHT_DELETE_ACCESS, NULL, "_samr_delete_dom_group"))) {
- return r_u->status;
- }
-
- if (!sid_to_local_dom_grp_name(&group_sid, grp_name)) {
- DEBUG(1, ("Could not find group for SID %s\n",
- sid_string_static(&group_sid)));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- /* we can delete the UNIX group */
- smb_delete_group(grp_name);
-
- /* check if the group has been successfully deleted */
- if ( (grp=getgrnam(grp_name)) != NULL)
- return NT_STATUS_ACCESS_DENIED;
-
- if (!close_policy_hnd(p, &q_u->group_pol))
- return NT_STATUS_OBJECT_NAME_INVALID;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3813,34 +2703,8 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
{
- DOM_SID alias_sid;
- uint32 acc_granted;
-
- DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, STD_RIGHT_DELETE_ACCESS, NULL, "_samr_delete_dom_alias"))) {
- return r_u->status;
- }
-
- DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
-
- if (!sid_check_is_in_our_domain(&alias_sid))
- return NT_STATUS_NO_SUCH_ALIAS;
-
- DEBUG(10, ("lookup on Local SID\n"));
-
- /* Have passdb delete the alias */
- if (!pdb_delete_alias(&alias_sid))
- return NT_STATUS_ACCESS_DENIED;
-
- if (!close_policy_hnd(p, &q_u->alias_pol))
- return NT_STATUS_OBJECT_NAME_INVALID;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3849,60 +2713,8 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
{
- DOM_SID dom_sid;
- DOM_SID info_sid;
- fstring name;
- fstring sid_string;
- struct group *grp;
- struct samr_info *info;
- uint32 acc_granted;
- gid_t gid;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, NULL, "_samr_create_dom_group"))) {
- return r_u->status;
- }
-
- if (!sid_equal(&dom_sid, get_global_sam_sid()))
- return NT_STATUS_ACCESS_DENIED;
-
- /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
-
- unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
-
- /* check if group already exist */
- if ((grp=getgrnam(name)) != NULL)
- return NT_STATUS_GROUP_EXISTS;
-
- /* we can create the UNIX group */
- if (smb_create_group(name, &gid) != 0)
- return NT_STATUS_ACCESS_DENIED;
-
- /* check if the group has been successfully created */
- if ((grp=getgrgid(gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
-
- r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
-
- /* add the group to the mapping table */
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, r_u->rid);
- sid_to_string(sid_string, &info_sid);
-
- if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
- return NT_STATUS_ACCESS_DENIED;
-
- if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -3911,201 +2723,28 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
{
- DOM_SID dom_sid;
- DOM_SID info_sid;
- fstring name;
- struct group *grp;
- struct samr_info *info;
- uint32 acc_granted;
- gid_t gid;
- NTSTATUS result;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, NULL, "_samr_create_alias"))) {
- return r_u->status;
- }
-
- if (!sid_equal(&dom_sid, get_global_sam_sid()))
- return NT_STATUS_ACCESS_DENIED;
-
- /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
-
- unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
-
- /* Have passdb create the alias */
- result = pdb_create_alias(name, &r_u->rid);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, r_u->rid);
-
- if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
- return NT_STATUS_ACCESS_DENIED;
-
- /* check if the group has been successfully created */
- if ((grp=getgrgid(gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
-
- if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_query_groupinfo
-
-sends the name/comment pair of a domain group
-level 1 send also the number of users of that group
*********************************************************************/
NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
{
- DOM_SID group_sid;
- gid_t gid;
- uid_t *uids;
- int num=0;
- GROUP_INFO_CTR *ctr;
- uint32 acc_granted;
- struct acct_info info;
-
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, NULL, "_samr_query_groupinfo"))) {
- return r_u->status;
- }
-
- if (!pdb_get_dom_grp_info(&group_sid, &info))
- return NT_STATUS_NO_SUCH_GROUP;
-
- if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
- return NT_STATUS_INVALID_HANDLE;
-
- ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
- if (ctr==NULL)
- return NT_STATUS_NO_MEMORY;
-
- switch (q_u->switch_level) {
- case 1:
- ctr->switch_value1 = 1;
- if(!get_memberuids(gid, &uids, &num))
- return NT_STATUS_NO_SUCH_GROUP;
- SAFE_FREE(uids);
- init_samr_group_info1(&ctr->group.info1,
- info.acct_name, info.acct_desc,
- num);
- break;
- case 3:
- ctr->switch_value1 = 3;
- init_samr_group_info3(&ctr->group.info3);
- break;
- case 4:
- ctr->switch_value1 = 4;
- init_samr_group_info4(&ctr->group.info4,
- info.acct_desc);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_set_groupinfo
-
- update a domain group's comment.
*********************************************************************/
NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
{
- DOM_SID group_sid;
- GROUP_INFO_CTR *ctr;
- uint32 acc_granted;
- struct acct_info info;
-
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_GROUP_SET_INFO, NULL, "_samr_set_groupinfo"))) {
- return r_u->status;
- }
-
- if (!pdb_get_dom_grp_info(&group_sid, &info))
- return NT_STATUS_INVALID_HANDLE;
-
- ctr=q_u->ctr;
-
- switch (ctr->switch_value1) {
- case 1:
- unistr2_to_ascii(info.acct_desc,
- &(ctr->group.info1.uni_acct_desc),
- sizeof(info.acct_desc)-1);
- break;
- case 4:
- unistr2_to_ascii(info.acct_desc,
- &(ctr->group.info4.uni_acct_desc),
- sizeof(info.acct_desc)-1);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- if (!pdb_set_dom_grp_info(&group_sid, &info))
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_OK;
-}
-
-/*********************************************************************
- _samr_set_aliasinfo
-
- update an alias's comment.
-*********************************************************************/
-
-NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
-{
- DOM_SID group_sid;
- struct acct_info info;
- ALIAS_INFO_CTR *ctr;
- uint32 acc_granted;
-
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(p, acc_granted, SA_RIGHT_ALIAS_SET_INFO, NULL, "_samr_set_aliasinfo"))) {
- return r_u->status;
- }
-
- ctr=&q_u->ctr;
-
- switch (ctr->switch_value1) {
- case 3:
- unistr2_to_ascii(info.acct_desc,
- &(ctr->alias.info3.uni_acct_desc),
- sizeof(info.acct_desc)-1);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- if(!pdb_set_aliasinfo(&group_sid, &info)) {
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
@@ -4114,18 +2753,7 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_
NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
{
- /* Perform access check. Since this rpc does not require a
- policy handle it will not be caught by the access checks on
- SAMR_CONNECT or SAMR_CONNECT_ANON. */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
- r_u->status = NT_STATUS_ACCESS_DENIED;
- return r_u->status;
- }
-
/* Actually, returning zeros here works quite well :-). */
-
return NT_STATUS_OK;
}
@@ -4135,353 +2763,16 @@ NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_
NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
{
- DOM_SID sid;
- DOM_SID info_sid;
- fstring grp_name;
- struct samr_info *info;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- size_t sd_size;
- NTSTATUS status;
- fstring sid_string;
-
- if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(p, acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, NULL, "_samr_open_group"))) {
- return status;
- }
-
- /*check if access can be granted as requested by client. */
- samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access,&grp_generic_mapping);
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p, des_access, &acc_granted,
- NULL, "_samr_open_group"))) {
- return status;
- }
-
-
- /* this should not be hard-coded like this */
- if (!sid_equal(&sid, get_global_sam_sid()))
- return NT_STATUS_ACCESS_DENIED;
-
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, q_u->rid_group);
- sid_to_string(sid_string, &info_sid);
-
- if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
-
- DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
-
- if (!sid_to_local_dom_grp_name(&info->sid, grp_name))
- return NT_STATUS_NO_SUCH_GROUP;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
- _samr_remove_sid_foreign_domain
+ _samr_unknown_2d
*********************************************************************/
-NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
- SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
- SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
-{
- DOM_SID delete_sid, alias_sid;
- SAM_ACCOUNT *sam_pass=NULL;
- uint32 acc_granted;
- GROUP_MAP map;
- BOOL is_user = False;
- NTSTATUS result;
- enum SID_NAME_USE type = SID_NAME_UNKNOWN;
-
- sid_copy( &delete_sid, &q_u->sid.sid );
-
- DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
- sid_string_static(&delete_sid)));
-
- /* Find the policy handle. Open a policy on it. */
-
- if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
- return NT_STATUS_INVALID_HANDLE;
-
- result = access_check_samr_function(p, acc_granted, STD_RIGHT_DELETE_ACCESS,
- NULL, "_samr_remove_sid_foreign_domain");
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
- sid_string_static(&alias_sid)));
-
- /* make sure we can handle this */
-
- if ( sid_check_is_domain(&alias_sid) )
- type = SID_NAME_DOM_GRP;
- else if ( sid_check_is_builtin(&alias_sid) )
- type = SID_NAME_ALIAS;
-
- if ( type == SID_NAME_UNKNOWN ) {
- DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
- return NT_STATUS_OK;
- }
-
- /* check if the user exists before trying to delete */
-
- pdb_init_sam(&sam_pass);
-
- if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
- is_user = True;
- } else {
- /* maybe it is a group */
- if( !pdb_getgrsid(&map, delete_sid) ) {
- DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
- sid_string_static(&delete_sid)));
- result = NT_STATUS_INVALID_SID;
- goto done;
- }
- }
-
- /* we can only delete a user from a group since we don't have
- nested groups anyways. So in the latter case, just say OK */
-
- if ( is_user ) {
- GROUP_MAP *mappings = NULL;
- int num_groups, i;
- struct group *grp2;
-
- if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
-
- /* interate over the groups */
- for ( i=0; i<num_groups; i++ ) {
-
- grp2 = getgrgid(mappings[i].gid);
-
- if ( !grp2 ) {
- DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
- continue;
- }
-
- if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
- continue;
-
- smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
-
- if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
- /* should we fail here ? */
- DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
- pdb_get_username(sam_pass), grp2->gr_name ));
- continue;
- }
-
- DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
- pdb_get_username(sam_pass), grp2->gr_name ));
- }
-
- SAFE_FREE(mappings);
- }
- }
-
- result = NT_STATUS_OK;
-done:
-
- pdb_free_sam(&sam_pass);
-
- return result;
-}
-
-/*******************************************************************
- _samr_unknown_2e
- ********************************************************************/
-
-NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
-{
- struct samr_info *info = NULL;
- SAM_UNK_CTR *ctr;
- uint32 min_pass_len,pass_hist,flag;
- time_t u_expire, u_min_age;
- NTTIME nt_expire, nt_min_age;
-
- time_t u_lock_duration, u_reset_time;
- NTTIME nt_lock_duration, nt_reset_time;
- uint32 lockout;
-
- time_t u_logout;
- NTTIME nt_logout;
-
- uint32 num_users=0, num_groups=0, num_aliases=0;
-
- uint32 account_policy_temp;
-
- if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(ctr);
-
- r_u->status = NT_STATUS_OK;
-
- DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- switch (q_u->switch_value) {
- case 0x01:
- account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
- min_pass_len = account_policy_temp;
-
- account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
- pass_hist = account_policy_temp;
-
- account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
- flag = account_policy_temp;
-
- account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
- u_expire = account_policy_temp;
-
- account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
- u_min_age = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_expire, u_expire);
- unix_to_nt_time_abs(&nt_min_age, u_min_age);
-
- init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
- flag, nt_expire, nt_min_age);
- break;
- case 0x02:
- become_root();
- r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
- unbecome_root();
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
- return r_u->status;
- }
- num_users=info->disp_info.num_user_account;
- free_samr_db(info);
-
- r_u->status=load_group_domain_entries(info, get_global_sam_sid());
- if (NT_STATUS_IS_ERR(r_u->status)) {
- DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
- return r_u->status;
- }
- num_groups=info->disp_info.num_group_account;
- free_samr_db(info);
-
- /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
- num_users, num_groups, num_aliases);
- break;
- case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
- u_logout = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_logout, u_logout);
-
- init_unk_info3(&ctr->info.inf3, nt_logout);
- break;
- case 0x05:
- init_unk_info5(&ctr->info.inf5, global_myname());
- break;
- case 0x06:
- init_unk_info6(&ctr->info.inf6);
- break;
- case 0x07:
- init_unk_info7(&ctr->info.inf7);
- break;
- case 0x0c:
- account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
- u_lock_duration = account_policy_temp * 60;
-
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
- u_reset_time = account_policy_temp * 60;
-
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
- lockout = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
- unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
-
- init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
-
- DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
-
- return r_u->status;
-}
-
-/*******************************************************************
- _samr_
- ********************************************************************/
-
-NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
+NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
{
- time_t u_expire, u_min_age;
- time_t u_logout;
- time_t u_lock_duration, u_reset_time;
-
- r_u->status = NT_STATUS_OK;
-
- DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
-
- switch (q_u->switch_value) {
- case 0x01:
- u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
- u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
-
- account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
- account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
- account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
- account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
- account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
- break;
- case 0x02:
- break;
- case 0x03:
- u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
- account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
- break;
- case 0x05:
- break;
- case 0x06:
- break;
- case 0x07:
- break;
- case 0x0c:
- u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
- u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
-
- account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
- account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
- account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
-
- DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
-
- return r_u->status;
+ DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c
deleted file mode 100644
index ae0fe84e029..00000000000
--- a/source/rpc_server/srv_samr_util.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAMR Pipe utility functions.
-
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Gerald (Jerry) Carter 2000-2001
- Copyright (C) Andrew Bartlett 2001-2002
- Copyright (C) Stefan (metze) Metzmacher 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-#define STRING_CHANGED (old_string && !new_string) ||\
- (!old_string && new_string) ||\
- (old_string && new_string && (strcmp(old_string, new_string) != 0))
-
-#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
- (!(s1) && (s2)) ||\
- ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
-
-/*************************************************************
- Copies a SAM_USER_INFO_20 to a SAM_ACCOUNT
-**************************************************************/
-
-void copy_id20_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_20 *from)
-{
- const char *old_string;
- char *new_string;
- DATA_BLOB mung;
-
- if (from == NULL || to == NULL)
- return;
-
- if (from->hdr_munged_dial.buffer) {
- old_string = pdb_get_munged_dial(to);
- mung.length = from->hdr_munged_dial.uni_str_len;
- mung.data = (uint8 *) from->uni_munged_dial.buffer;
- new_string = base64_encode_data_blob(mung);
- DEBUG(10,("INFO_20 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED_NC(old_string,new_string))
- pdb_set_munged_dial(to , new_string, PDB_CHANGED);
-
- SAFE_FREE(new_string);
- }
-}
-
-/*************************************************************
- Copies a SAM_USER_INFO_21 to a SAM_ACCOUNT
-**************************************************************/
-
-void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
-{
- time_t unix_time, stored_time;
- const char *old_string, *new_string;
- DATA_BLOB mung;
-
- if (from == NULL || to == NULL)
- return;
-
- if (from->fields_present & ACCT_LAST_LOGON) {
- unix_time=nt_time_to_unix(&from->logon_time);
- stored_time = pdb_get_logon_time(to);
- DEBUG(10,("INFO_21 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_logon_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_LAST_LOGOFF) {
- unix_time=nt_time_to_unix(&from->logoff_time);
- stored_time = pdb_get_logoff_time(to);
- DEBUG(10,("INFO_21 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_EXPIRY) {
- unix_time=nt_time_to_unix(&from->kickoff_time);
- stored_time = pdb_get_kickoff_time(to);
- DEBUG(10,("INFO_21 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_can_change_time);
- stored_time = pdb_get_pass_can_change_time(to);
- DEBUG(10,("INFO_21 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_last_set_time);
- stored_time = pdb_get_pass_last_set_time(to);
- DEBUG(10,("INFO_21 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_must_change_time);
- stored_time=pdb_get_pass_must_change_time(to);
- DEBUG(10,("INFO_21 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_USERNAME) &&
- (from->hdr_user_name.buffer)) {
- old_string = pdb_get_username(to);
- new_string = unistr2_static(&from->uni_user_name);
- DEBUG(10,("INFO_21 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_username(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_FULL_NAME) &&
- (from->hdr_full_name.buffer)) {
- old_string = pdb_get_fullname(to);
- new_string = unistr2_static(&from->uni_full_name);
- DEBUG(10,("INFO_21 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_fullname(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_HOME_DIR) &&
- (from->hdr_home_dir.buffer)) {
- old_string = pdb_get_homedir(to);
- new_string = unistr2_static(&from->uni_home_dir);
- DEBUG(10,("INFO_21 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_homedir(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_HOME_DRIVE) &&
- (from->hdr_dir_drive.buffer)) {
- old_string = pdb_get_dir_drive(to);
- new_string = unistr2_static(&from->uni_dir_drive);
- DEBUG(10,("INFO_21 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_dir_drive(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_LOGON_SCRIPT) &&
- (from->hdr_logon_script.buffer)) {
- old_string = pdb_get_logon_script(to);
- new_string = unistr2_static(&from->uni_logon_script);
- DEBUG(10,("INFO_21 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_logon_script(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_PROFILE) &&
- (from->hdr_profile_path.buffer)) {
- old_string = pdb_get_profile_path(to);
- new_string = unistr2_static(&from->uni_profile_path);
- DEBUG(10,("INFO_21 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_profile_path(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_DESCRIPTION) &&
- (from->hdr_acct_desc.buffer)) {
- old_string = pdb_get_acct_desc(to);
- new_string = unistr2_static(&from->uni_acct_desc);
- DEBUG(10,("INFO_21 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_acct_desc(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_WORKSTATIONS) &&
- (from->hdr_workstations.buffer)) {
- old_string = pdb_get_workstations(to);
- new_string = unistr2_static(&from->uni_workstations);
- DEBUG(10,("INFO_21 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_workstations(to , new_string, PDB_CHANGED);
- }
-
- /* is this right? */
- if ((from->fields_present & ACCT_ADMIN_DESC) &&
- (from->hdr_unknown_str.buffer)) {
- old_string = pdb_get_unknown_str(to);
- new_string = unistr2_static(&from->uni_unknown_str);
- DEBUG(10,("INFO_21 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_unknown_str(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_CALLBACK) &&
- (from->hdr_munged_dial.buffer)) {
- char *newstr;
- old_string = pdb_get_munged_dial(to);
- mung.length = from->hdr_munged_dial.uni_str_len;
- mung.data = (uint8 *) from->uni_munged_dial.buffer;
- newstr = base64_encode_data_blob(mung);
- DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr));
- if (STRING_CHANGED_NC(old_string,newstr))
- pdb_set_munged_dial(to , newstr, PDB_CHANGED);
-
- SAFE_FREE(newstr);
- }
-
- if (from->fields_present & ACCT_RID) {
- if (from->user_rid == 0) {
- DEBUG(10, ("INFO_21: Asked to set User RID to 0 !? Skipping change!\n"));
- } else if (from->user_rid != pdb_get_user_rid(to)) {
- DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
- }
- }
-
- if (from->fields_present & ACCT_PRIMARY_GID) {
- if (from->group_rid == 0) {
- DEBUG(10, ("INFO_21: Asked to set Group RID to 0 !? Skipping change!\n"));
- } else if (from->group_rid != pdb_get_group_rid(to)) {
- DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
- pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_FLAGS) {
- DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
- if (from->acb_info != pdb_get_acct_ctrl(to)) {
- pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_LOGON_HOURS) {
- DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
- if (from->logon_divs != pdb_get_logon_divs(to)) {
- pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
- }
-
- DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
- if (from->logon_hrs.len != pdb_get_hours_len(to)) {
- pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
- }
-
- DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
- /* Fix me: only update if it changes --metze */
- pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
-
- /* This is max logon hours */
- DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
- if (from->unknown_6 != pdb_get_unknown_6(to)) {
- pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_BAD_PWD_COUNT) {
- DEBUG(10,("INFO_21 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
- if (from->bad_password_count != pdb_get_bad_password_count(to)) {
- pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_NUM_LOGONS) {
- DEBUG(10,("INFO_21 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
- if (from->logon_count != pdb_get_logon_count(to)) {
- pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
- }
- }
-
- DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
- if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
- pdb_set_pass_must_change_time(to,0, PDB_CHANGED);
- } else {
- uint32 expire;
- time_t new_time;
- if (pdb_get_pass_must_change_time(to) == 0) {
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
- || expire == (uint32)-1) {
- new_time = get_time_t_max();
- } else {
- time_t old_time = pdb_get_pass_last_set_time(to);
- new_time = old_time + expire;
- if ((new_time) < time(0)) {
- new_time = time(0) + expire;
- }
- }
- if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
- DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
- }
- }
- }
-
- DEBUG(10,("INFO_21 PADDING_2: %02X\n",from->padding2));
-
- DEBUG(10,("INFO_21 PADDING_4: %08X\n",from->padding4));
-}
-
-
-/*************************************************************
- Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
-**************************************************************/
-
-void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
-{
- time_t unix_time, stored_time;
- const char *old_string, *new_string;
- DATA_BLOB mung;
-
- if (from == NULL || to == NULL)
- return;
-
- if (from->fields_present & ACCT_LAST_LOGON) {
- unix_time=nt_time_to_unix(&from->logon_time);
- stored_time = pdb_get_logon_time(to);
- DEBUG(10,("INFO_23 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_logon_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_LAST_LOGOFF) {
- unix_time=nt_time_to_unix(&from->logoff_time);
- stored_time = pdb_get_logoff_time(to);
- DEBUG(10,("INFO_23 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_EXPIRY) {
- unix_time=nt_time_to_unix(&from->kickoff_time);
- stored_time = pdb_get_kickoff_time(to);
- DEBUG(10,("INFO_23 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_can_change_time);
- stored_time = pdb_get_pass_can_change_time(to);
- DEBUG(10,("INFO_23 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_last_set_time);
- stored_time = pdb_get_pass_last_set_time(to);
- DEBUG(10,("INFO_23 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
- }
-
- if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
- unix_time=nt_time_to_unix(&from->pass_must_change_time);
- stored_time=pdb_get_pass_must_change_time(to);
- DEBUG(10,("INFO_23 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
- if (stored_time != unix_time)
- pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
- }
-
- /* Backend should check this for sanity */
- if ((from->fields_present & ACCT_USERNAME) &&
- (from->hdr_user_name.buffer)) {
- old_string = pdb_get_username(to);
- new_string = unistr2_static(&from->uni_user_name);
- DEBUG(10,("INFO_23 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_username(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_FULL_NAME) &&
- (from->hdr_full_name.buffer)) {
- old_string = pdb_get_fullname(to);
- new_string = unistr2_static(&from->uni_full_name);
- DEBUG(10,("INFO_23 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_fullname(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_HOME_DIR) &&
- (from->hdr_home_dir.buffer)) {
- old_string = pdb_get_homedir(to);
- new_string = unistr2_static(&from->uni_home_dir);
- DEBUG(10,("INFO_23 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_homedir(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_HOME_DRIVE) &&
- (from->hdr_dir_drive.buffer)) {
- old_string = pdb_get_dir_drive(to);
- new_string = unistr2_static(&from->uni_dir_drive);
- DEBUG(10,("INFO_23 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_dir_drive(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_LOGON_SCRIPT) &&
- (from->hdr_logon_script.buffer)) {
- old_string = pdb_get_logon_script(to);
- new_string = unistr2_static(&from->uni_logon_script);
- DEBUG(10,("INFO_23 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_logon_script(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_PROFILE) &&
- (from->hdr_profile_path.buffer)) {
- old_string = pdb_get_profile_path(to);
- new_string = unistr2_static(&from->uni_profile_path);
- DEBUG(10,("INFO_23 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_profile_path(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_DESCRIPTION) &&
- (from->hdr_acct_desc.buffer)) {
- old_string = pdb_get_acct_desc(to);
- new_string = unistr2_static(&from->uni_acct_desc);
- DEBUG(10,("INFO_23 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
- if (STRING_CHANGED)
- pdb_set_acct_desc(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_WORKSTATIONS) &&
- (from->hdr_workstations.buffer)) {
- old_string = pdb_get_workstations(to);
- new_string = unistr2_static(&from->uni_workstations);
- DEBUG(10,("INFO_23 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_workstations(to , new_string, PDB_CHANGED);
- }
-
- /* is this right? */
- if ((from->fields_present & ACCT_ADMIN_DESC) &&
- (from->hdr_unknown_str.buffer)) {
- old_string = pdb_get_unknown_str(to);
- new_string = unistr2_static(&from->uni_unknown_str);
- DEBUG(10,("INFO_23 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
- if (STRING_CHANGED)
- pdb_set_unknown_str(to , new_string, PDB_CHANGED);
- }
-
- if ((from->fields_present & ACCT_CALLBACK) &&
- (from->hdr_munged_dial.buffer)) {
- char *newstr;
- old_string = pdb_get_munged_dial(to);
- mung.length = from->hdr_munged_dial.uni_str_len;
- mung.data = (uint8 *) from->uni_munged_dial.buffer;
- newstr = base64_encode_data_blob(mung);
- DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr));
- if (STRING_CHANGED_NC(old_string, newstr))
- pdb_set_munged_dial(to , newstr, PDB_CHANGED);
-
- SAFE_FREE(newstr);
- }
-
- if (from->fields_present & ACCT_RID) {
- if (from->user_rid == 0) {
- DEBUG(10, ("INFO_23: Asked to set User RID to 0 !? Skipping change!\n"));
- } else if (from->user_rid != pdb_get_user_rid(to)) {
- DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
- }
- }
-
- if (from->fields_present & ACCT_PRIMARY_GID) {
- if (from->group_rid == 0) {
- DEBUG(10, ("INFO_23: Asked to set Group RID to 0 !? Skipping change!\n"));
- } else if (from->group_rid != pdb_get_group_rid(to)) {
- DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
- pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_FLAGS) {
- DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
- if (from->acb_info != pdb_get_acct_ctrl(to)) {
- pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_LOGON_HOURS) {
- DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
- if (from->logon_divs != pdb_get_logon_divs(to)) {
- pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
- }
-
- DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
- if (from->logon_hrs.len != pdb_get_hours_len(to)) {
- pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
- }
-
- DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
- /* Fix me: only update if it changes --metze */
- pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
-
- /* This is max logon hours */
- DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
- if (from->unknown_6 != pdb_get_unknown_6(to)) {
- pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_BAD_PWD_COUNT) {
- DEBUG(10,("INFO_23 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
- if (from->bad_password_count != pdb_get_bad_password_count(to)) {
- pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
- }
- }
-
- if (from->fields_present & ACCT_NUM_LOGONS) {
- DEBUG(10,("INFO_23 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
- if (from->logon_count != pdb_get_logon_count(to)) {
- pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
- }
- }
-
- DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
- if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
- pdb_set_pass_must_change_time(to,0, PDB_CHANGED);
- } else {
- uint32 expire;
- time_t new_time;
- if (pdb_get_pass_must_change_time(to) == 0) {
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
- || expire == (uint32)-1) {
- new_time = get_time_t_max();
- } else {
- time_t old_time = pdb_get_pass_last_set_time(to);
- new_time = old_time + expire;
- if ((new_time) < time(0)) {
- new_time = time(0) + expire;
- }
- }
- if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
- DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
- }
- }
- }
-
- DEBUG(10,("INFO_23 PADDING_2: %02X\n",from->padding2));
-
- DEBUG(10,("INFO_23 PADDING_4: %08X\n",from->padding4));
-}
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index f846813a40b..f9789a286cf 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -3,10 +3,8 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- * Copyright (C) Jean François Micouleau 1998-2000,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Gerald Carter 2001-2002,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Jean François Micouleau 1998-2000.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,9 +23,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/********************************************************************
* api_spoolss_open_printer_ex (rarely seen - older call)
********************************************************************/
@@ -141,7 +136,7 @@ static BOOL api_spoolss_deleteprinterdata(pipes_struct *p)
return False;
}
- r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u );
+ r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u);
if (!spoolss_io_r_deleteprinterdata("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_deleteprinterdata: unable to marshall SPOOL_R_DELETEPRINTERDATA.\n"));
@@ -1026,7 +1021,7 @@ static BOOL api_spoolss_reset_printer(pipes_struct *p)
}
r_u.status = _spoolss_resetprinter(p, &q_u, &r_u);
-
+
if(!spoolss_io_r_resetprinter("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_RESETPRINTER.\n"));
return False;
@@ -1404,184 +1399,12 @@ static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
return True;
}
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_deleteprinterdataex(pipes_struct *p)
-{
- SPOOL_Q_DELETEPRINTERDATAEX q_u;
- SPOOL_R_DELETEPRINTERDATAEX r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_deleteprinterdataex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_deleteprinterdataex: unable to unmarshall SPOOL_Q_DELETEPRINTERDATAEX.\n"));
- return False;
- }
-
- r_u.status = _spoolss_deleteprinterdataex(p, &q_u, &r_u);
-
- if(!spoolss_io_r_deleteprinterdataex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_deleteprinterdataex: unable to marshall SPOOL_R_DELETEPRINTERDATAEX.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_deleteprinterkey(pipes_struct *p)
-{
- SPOOL_Q_DELETEPRINTERKEY q_u;
- SPOOL_R_DELETEPRINTERKEY r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_deleteprinterkey("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_deleteprinterkey: unable to unmarshall SPOOL_Q_DELETEPRINTERKEY.\n"));
- return False;
- }
-
- r_u.status = _spoolss_deleteprinterkey(p, &q_u, &r_u);
-
- if(!spoolss_io_r_deleteprinterkey("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_deleteprinterkey: unable to marshall SPOOL_R_DELETEPRINTERKEY.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_addprinterdriverex(pipes_struct *p)
-{
- SPOOL_Q_ADDPRINTERDRIVEREX q_u;
- SPOOL_R_ADDPRINTERDRIVEREX r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_addprinterdriverex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_addprinterdriverex: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVEREX.\n"));
- return False;
- }
-
- r_u.status = _spoolss_addprinterdriverex(p, &q_u, &r_u);
-
- if(!spoolss_io_r_addprinterdriverex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_addprinterdriverex: unable to marshall SPOOL_R_ADDPRINTERDRIVEREX.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_deleteprinterdriverex(pipes_struct *p)
-{
- SPOOL_Q_DELETEPRINTERDRIVEREX q_u;
- SPOOL_R_DELETEPRINTERDRIVEREX r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_deleteprinterdriverex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_deleteprinterdriverex: unable to unmarshall SPOOL_Q_DELETEPRINTERDRIVEREX.\n"));
- return False;
- }
-
- r_u.status = _spoolss_deleteprinterdriverex(p, &q_u, &r_u);
-
- if(!spoolss_io_r_deleteprinterdriverex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_deleteprinterdriverex: unable to marshall SPOOL_R_DELETEPRINTERDRIVEREX.\n"));
- return False;
- }
-
- return True;
-}
-
-#if 0
-
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_replyopenprinter(pipes_struct *p)
-{
- SPOOL_Q_REPLYOPENPRINTER q_u;
- SPOOL_R_REPLYOPENPRINTER r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_replyopenprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_replyopenprinter: unable to unmarshall SPOOL_Q_REPLYOPENPRINTER.\n"));
- return False;
- }
-
- r_u.status = _spoolss_replyopenprinter(p, &q_u, &r_u);
-
- if(!spoolss_io_r_replyopenprinter("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_replyopenprinter: unable to marshall SPOOL_R_REPLYOPENPRINTER.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static BOOL api_spoolss_replycloseprinter(pipes_struct *p)
-{
- SPOOL_Q_REPLYCLOSEPRINTER q_u;
- SPOOL_R_REPLYCLOSEPRINTER r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_replycloseprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_replycloseprinter: unable to unmarshall SPOOL_Q_REPLYCLOSEPRINTER.\n"));
- return False;
- }
-
- r_u.status = _spoolss_replycloseprinter(p, &q_u, &r_u);
-
- if(!spoolss_io_r_replycloseprinter("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_replycloseprinter: unable to marshall SPOOL_R_REPLYCLOSEPRINTER.\n"));
- return False;
- }
-
- return True;
-}
-
-#endif
-
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
- struct api_struct api_spoolss_cmds[] =
- {
+struct api_struct api_spoolss_cmds[] =
+{
{"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer },
{"SPOOLSS_OPENPRINTEREX", SPOOLSS_OPENPRINTEREX, api_spoolss_open_printer_ex },
{"SPOOLSS_GETPRINTERDATA", SPOOLSS_GETPRINTERDATA, api_spoolss_getprinterdata },
@@ -1626,27 +1449,16 @@ static BOOL api_spoolss_replycloseprinter(pipes_struct *p)
{"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes },
{"SPOOLSS_GETPRINTERDATAEX", SPOOLSS_GETPRINTERDATAEX, api_spoolss_getprinterdataex },
{"SPOOLSS_SETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex },
- {"SPOOLSS_DELETEPRINTERDATAEX", SPOOLSS_DELETEPRINTERDATAEX, api_spoolss_deleteprinterdataex },
- {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex },
{"SPOOLSS_ENUMPRINTERKEY", SPOOLSS_ENUMPRINTERKEY, api_spoolss_enumprinterkey },
- {"SPOOLSS_DELETEPRINTERKEY", SPOOLSS_DELETEPRINTERKEY, api_spoolss_deleteprinterkey },
+ {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex },
{"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory},
- {"SPOOLSS_ADDPRINTERDRIVEREX", SPOOLSS_ADDPRINTERDRIVEREX, api_spoolss_addprinterdriverex },
- {"SPOOLSS_DELETEPRINTERDRIVEREX", SPOOLSS_DELETEPRINTERDRIVEREX, api_spoolss_deleteprinterdriverex },
-#if 0
- {"SPOOLSS_REPLYOPENPRINTER", SPOOLSS_REPLYOPENPRINTER, api_spoolss_replyopenprinter },
- {"SPOOLSS_REPLYCLOSEPRINTER", SPOOLSS_REPLYCLOSEPRINTER, api_spoolss_replycloseprinter }
-#endif
- };
-
-void spoolss_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_spoolss_cmds;
- *n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct);
-}
+ { NULL, 0, NULL }
+};
-NTSTATUS rpc_spoolss_init(void)
+/*******************************************************************
+receives a spoolss pipe and responds.
+********************************************************************/
+BOOL api_spoolss_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss", api_spoolss_cmds,
- sizeof(api_spoolss_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_spoolss_rpc", api_spoolss_cmds);
}
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index edd62fa8f62..661b9d310ad 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -28,39 +28,63 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
#ifndef MAX_OPEN_PRINTER_EXS
#define MAX_OPEN_PRINTER_EXS 50
#endif
#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
-
+#define PRINTER_HANDLE_IS_PRINTER 0
+#define PRINTER_HANDLE_IS_PRINTSERVER 1
/* Table to map the driver version */
/* to OS */
-static const char * drv_ver_to_os[] = {
+const char * drv_ver_to_os[] = {
"WIN9X", /* driver version/cversion 0 */
"", /* unused ? */
"WINNT", /* driver version/cversion 2 */
"WIN2K", /* driver version/cversion 3 */
};
-static const char *get_drv_ver_to_os(int ver)
-{
- if (ver < 0 || ver > 3)
- return "";
- return drv_ver_to_os[ver];
-}
-
struct table_node {
const char *long_archi;
const char *short_archi;
int version;
};
+
+/* structure to store the printer handles */
+/* and a reference to what it's pointing to */
+/* and the notify info asked about */
+/* that's the central struct */
+typedef struct _Printer{
+ struct _Printer *prev, *next;
+ BOOL document_started;
+ BOOL page_started;
+ int jobid; /* jobid in printing backend */
+ BOOL printer_type;
+ union {
+ fstring handlename;
+ fstring printerservername;
+ } dev;
+ uint32 type;
+ uint32 access_granted;
+ struct {
+ uint32 flags;
+ uint32 options;
+ fstring localmachine;
+ uint32 printerlocal;
+ SPOOL_NOTIFY_OPTION *option;
+ POLICY_HND client_hnd;
+ uint32 client_connected;
+ uint32 change;
+ } notify;
+ struct {
+ fstring machine;
+ fstring user;
+ } client;
+} Printer_entry;
+
static Printer_entry *printers_list;
typedef struct _counter_printer_0 {
@@ -73,7 +97,7 @@ typedef struct _counter_printer_0 {
static ubi_dlList counter_list;
-static struct cli_state notify_cli; /* print notify back-channel */
+static struct cli_state cli;
static uint32 smb_connections=0;
@@ -146,25 +170,17 @@ static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
Disconnect from the client
****************************************************************************/
-static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
+static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
{
WERROR result;
- /*
- * Tell the specific printing tdb we no longer want messages for this printer
- * by deregistering our PID.
- */
-
- if (!print_notify_deregister_pid(snum))
- DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
-
/* weird if the test succeds !!! */
if (smb_connections==0) {
DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
return;
}
- result = cli_spoolss_reply_close_printer(&notify_cli, notify_cli.mem_ctx, handle);
+ result = cli_spoolss_reply_close_printer(&cli, cli.mem_ctx, handle);
if (!W_ERROR_IS_OK(result))
DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
@@ -172,15 +188,10 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
/* if it's the last connection, deconnect the IPC$ share */
if (smb_connections==1) {
- cli_nt_session_close(&notify_cli);
- cli_ulogoff(&notify_cli);
- cli_shutdown(&notify_cli);
- message_deregister(MSG_PRINTER_NOTIFY2);
-
- /* Tell the connections db we're no longer interested in
- * printer notify messages. */
+ if(!spoolss_disconnect_from_client(&cli))
+ return;
- register_message_flags( False, FLAG_MSG_PRINTING );
+ message_deregister(MSG_PRINTER_NOTIFY);
}
smb_connections--;
@@ -194,19 +205,8 @@ static void free_printer_entry(void *ptr)
{
Printer_entry *Printer = (Printer_entry *)ptr;
- if (Printer->notify.client_connected==True) {
- int snum = -1;
-
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
- snum = -1;
- srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
- } else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) {
- snum = print_queue_snum(Printer->dev.handlename);
- if (snum != -1)
- srv_spoolss_replycloseprinter(snum,
- &Printer->notify.client_hnd);
- }
- }
+ if (Printer->notify.client_connected==True)
+ srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
Printer->notify.flags=0;
Printer->notify.options=0;
@@ -215,11 +215,6 @@ static void free_printer_entry(void *ptr)
free_spool_notify_option(&Printer->notify.option);
Printer->notify.option=NULL;
Printer->notify.client_connected=False;
-
- free_nt_devicemode( &Printer->nt_devmode );
- free_a_printer( &Printer->printer_info, 2 );
-
- talloc_destroy( Printer->ctx );
/* Remove from the internal list. */
DLIST_REMOVE(printers_list, Printer);
@@ -231,7 +226,7 @@ static void free_printer_entry(void *ptr)
Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
****************************************************************************/
-static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
+SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
{
SPOOL_NOTIFY_OPTION *new_sp = NULL;
@@ -273,56 +268,6 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
}
/****************************************************************************
- look for a printer object cached on an open printer handle
-****************************************************************************/
-
-WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2,
- const char *printername )
-{
- Printer_entry *p;
-
- DEBUG(10,("find_printer_in_print_hnd_cache: printer [%s]\n", printername));
-
- for ( p=printers_list; p; p=p->next )
- {
- if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
- && p->printer_info
- && StrCaseCmp(p->dev.handlename, printername) == 0 )
- {
- DEBUG(10,("Found printer\n"));
- *info2 = dup_printer_2( ctx, p->printer_info->info_2 );
- if ( *info2 )
- return WERR_OK;
- }
- }
-
- return WERR_INVALID_PRINTER_NAME;
-}
-
-/****************************************************************************
- destroy any cached printer_info_2 structures on open handles
-****************************************************************************/
-
-void invalidate_printer_hnd_cache( char *printername )
-{
- Printer_entry *p;
-
- DEBUG(10,("invalidate_printer_hnd_cache: printer [%s]\n", printername));
-
- for ( p=printers_list; p; p=p->next )
- {
- if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
- && StrCaseCmp(p->dev.handlename, printername)==0)
- {
- DEBUG(10,("invalidating printer_info cache for handl:\n"));
- free_a_printer( &p->printer_info, 2 );
- p->printer_info = NULL;
- }
- }
-
- return;
-}
-/****************************************************************************
Close printer index by handle.
****************************************************************************/
@@ -387,10 +332,12 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
char *cmd = lp_deleteprinter_cmd();
pstring command;
int ret;
+ int i;
/* Printer->dev.handlename equals portname equals sharename */
slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
Printer->dev.handlename);
+ dos_to_unix(command); /* Convert printername to unix-codepage */
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, NULL);
@@ -405,7 +352,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
/* go ahead and re-read the services immediately */
reload_services( False );
- if ( lp_servicenumber( Printer->dev.handlename ) < 0 )
+ if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) < 0 )
return WERR_ACCESS_DENIED;
}
@@ -452,7 +399,7 @@ static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename
}
/* it's a print server */
- if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
+ if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr(handlename+2, '\\')) {
DEBUGADD(4,("Printer is a print server\n"));
Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
}
@@ -477,7 +424,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
fstring sname;
BOOL found=False;
- DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
+ DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
ZERO_STRUCT(Printer->dev.printerservername);
@@ -489,14 +436,14 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
return False;
if (*handlename=='\\') {
- aprinter=strchr_m(handlename+2, '\\');
+ aprinter=strchr(handlename+2, '\\');
aprinter++;
}
else {
aprinter=handlename;
}
- DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
+ DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
/*
* The original code allowed smbd to store a printer name that
@@ -556,17 +503,11 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
SAFE_FREE(new_printer);
return False;
}
-
+
/* Add to the internal list. */
DLIST_ADD(printers_list, new_printer);
-
+
new_printer->notify.option=NULL;
-
- if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) {
- DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
- close_printer_handle(p, hnd);
- return False;
- }
if (!set_printer_hnd_printertype(new_printer, name)) {
close_printer_handle(p, hnd);
@@ -619,574 +560,231 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
return True;
}
-
/***************************************************************************
- check to see if the client motify handle is monitoring the notification
- given by (notify_type, notify_field).
+ Always give preference Printer_entry.notify.option over
+ Printer_entry.notify.flags. Return True if we should send notification
+ events using SPOOLSS_RRPCN. False means that we should use
+ SPOOLSS_ROUTERREPLYPRINTER.
**************************************************************************/
-
-static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type,
- uint16 notify_field)
-{
- return True;
-}
-
-static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
- uint16 notify_field)
+static BOOL valid_notify_options(Printer_entry *printer)
{
- SPOOL_NOTIFY_OPTION *option = p->notify.option;
- uint32 i, j;
-
- /*
- * Flags should always be zero when the change notify
- * is registered by the client's spooler. A user Win32 app
- * might use the flags though instead of the NOTIFY_OPTION_INFO
- * --jerry
- */
-
- if (p->notify.flags)
- return is_monitoring_event_flags(
- p->notify.flags, notify_type, notify_field);
-
- for (i = 0; i < option->count; i++) {
-
- /* Check match for notify_type */
-
- if (option->ctr.type[i].type != notify_type)
- continue;
-
- /* Check match for field */
+ if (printer->notify.option == NULL)
+ return False;
- for (j = 0; j < option->ctr.type[i].count; j++) {
- if (option->ctr.type[i].fields[j] == notify_field) {
- return True;
- }
- }
- }
-
- DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
- (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ?
- p->dev.handlename : p->dev.printerservername,
- notify_type, notify_field));
-
- return False;
-}
-
-/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
-
-static void notify_one_value(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
-{
- data->notify_data.value[0] = msg->notify.value[0];
- data->notify_data.value[1] = 0;
-}
-
-static void notify_string(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
-{
- UNISTR2 unistr;
-
- /* The length of the message includes the trailing \0 */
-
- init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
-
- data->notify_data.data.length = msg->len * 2;
- data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2);
-
- if (!data->notify_data.data.string) {
- data->notify_data.data.length = 0;
- return;
- }
-
- memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
-}
-
-static void notify_system_time(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
- TALLOC_CTX *mem_ctx)
-{
- SYSTEMTIME systime;
- prs_struct ps;
-
- if (msg->len != sizeof(time_t)) {
- DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
- msg->len));
- return;
- }
-
- if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- DEBUG(5, ("notify_system_time: prs_init() failed\n"));
- return;
- }
-
- if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
- DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
- return;
- }
-
- if (!spoolss_io_system_time("", &ps, 0, &systime))
- return;
-
- data->notify_data.data.length = prs_offset(&ps);
- data->notify_data.data.string = talloc(mem_ctx, prs_offset(&ps));
-
- prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
-
- prs_mem_free(&ps);
+ return True;
}
-struct notify2_message_table {
- const char *name;
- void (*fn)(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
-};
-
-static struct notify2_message_table printer_notify_table[] = {
- /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
- /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
- /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
- /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
- /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
- /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
- /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
- /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
- /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
- /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
- /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
- /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
- /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
- /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
- /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
- /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
- /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
- /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
- /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
-};
-
-static struct notify2_message_table job_notify_table[] = {
- /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
- /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
- /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
- /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
- /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
- /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
- /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
- /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
- /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
- /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
- /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
- /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
- /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
- /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
- /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
- /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
- /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
- /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
- /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
- /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
- /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
- /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
- /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
- /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
-};
-
-
-/***********************************************************************
- Allocate talloc context for container object
- **********************************************************************/
+/***************************************************************************
+ Simple check to see if the client motify handle is set to watch for events
+ represented by 'flags'
-static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
-{
- if ( !ctr )
- return;
-
- ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
-
- return;
-}
-
-/***********************************************************************
- release all allocated memory and zero out structure
- **********************************************************************/
+ FIXME!!!! only a stub right now --jerry
+ **************************************************************************/
-static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
+static BOOL is_client_monitoring_event(Printer_entry *p, uint32 flags)
{
- if ( !ctr )
- return;
- if ( ctr->ctx )
- talloc_destroy(ctr->ctx);
-
- ZERO_STRUCTP(ctr);
-
- return;
+ return True;
}
-/***********************************************************************
- **********************************************************************/
+/***************************************************************************
+ Server wrapper for cli_spoolss_routerreplyprinter() since the client
+ function can only send a single change notification at a time.
-static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
-{
- if ( !ctr )
- return NULL;
-
- return ctr->ctx;
-}
-
-/***********************************************************************
- **********************************************************************/
+ FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER)
+ --jerry
+ **************************************************************************/
-static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
+static WERROR srv_spoolss_routerreplyprinter (struct cli_state *reply_cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, PRINTER_MESSAGE_INFO *info,
+ NT_PRINTER_INFO_LEVEL *printer)
{
- if ( !ctr || !ctr->msg_groups )
- return NULL;
+ WERROR result;
+ uint32 condition = 0x0;
- if ( idx >= ctr->num_groups )
- return NULL;
-
- return &ctr->msg_groups[idx];
-
-}
+ if (info->flags & PRINTER_MESSAGE_DRIVER)
+ condition = PRINTER_CHANGE_SET_PRINTER_DRIVER;
+
+ result = cli_spoolss_routerreplyprinter(reply_cli, mem_ctx, pol, condition,
+ printer->info_2->changeid);
-/***********************************************************************
- How many groups of change messages do we have ?
- **********************************************************************/
-
-static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
-{
- if ( !ctr )
- return 0;
-
- return ctr->num_groups;
+ return result;
}
/***********************************************************************
- Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
+ Wrapper around the decision of which RPC use to in the change
+ notification
**********************************************************************/
-static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
+static WERROR srv_spoolss_send_event_to_client(Printer_entry* Printer,
+ struct cli_state *send_cli, PRINTER_MESSAGE_INFO *msg,
+ NT_PRINTER_INFO_LEVEL *info)
{
- SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
- SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
- SPOOLSS_NOTIFY_MSG *msg_list = NULL;
- int i, new_slot;
-
- if ( !ctr || !msg )
- return 0;
-
- /* loop over all groups looking for a matching printer name */
-
- for ( i=0; i<ctr->num_groups; i++ ) {
- if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
- break;
- }
-
- /* add a new group? */
+ WERROR result;
- if ( i == ctr->num_groups ) {
- ctr->num_groups++;
-
- if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) {
- DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
- return 0;
- }
- ctr->msg_groups = groups;
+ if (valid_notify_options(Printer)) {
+ /* This is a single call that can send information about multiple changes */
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ msg->flags |= PRINTER_MESSAGE_ATTRIBUTES;
- /* clear the new entry and set the printer name */
-
- ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
- fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
+ result = cli_spoolss_reply_rrpcn(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
}
-
- /* add the change messages; 'i' is the correct index now regardless */
-
- msg_grp = &ctr->msg_groups[i];
-
- msg_grp->num_msgs++;
-
- if ( !(msg_list = talloc_realloc( ctr->ctx, msg_grp->msgs, sizeof(SPOOLSS_NOTIFY_MSG)*msg_grp->num_msgs )) ) {
- DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
- return 0;
+ else {
+ /* This requires that the server send an individual event notification for each change */
+ result = srv_spoolss_routerreplyprinter(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd,
+ msg, info);
}
- msg_grp->msgs = msg_list;
-
- new_slot = msg_grp->num_msgs-1;
- memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
-
- /* need to allocate own copy of data */
- if ( msg->len != 0 )
- msg_grp->msgs[new_slot].notify.data = talloc_memdup( ctr->ctx, msg->notify.data, msg->len );
-
- return ctr->num_groups;
+ return result;
}
+
/***********************************************************************
Send a change notication message on all handles which have a call
back registered
**********************************************************************/
-static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
+static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg)
{
- Printer_entry *p;
- TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
- SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
- SPOOLSS_NOTIFY_MSG *messages;
- int sending_msg_count;
-
- if ( !msg_group ) {
- DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
- return;
- }
-
- messages = msg_group->msgs;
+ Printer_entry *find_printer;
+ WERROR result;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
- if ( !messages ) {
- DEBUG(5,("send_notify2_changes() called with no messages!\n"));
+ if (!msg) {
+ DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n"));
return;
}
- DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
-
- /* loop over all printers */
-
- for (p = printers_list; p; p = p->next) {
- SPOOL_NOTIFY_INFO_DATA *data;
- uint32 data_len = 0;
- uint32 id;
- int i;
-
- /* Is there notification on this handle? */
-
- if ( !p->notify.client_connected )
- continue;
-
- DEBUG(10,("Client connected! [%s]\n", p->dev.handlename));
+ for(find_printer = printers_list; find_printer; find_printer = find_printer->next) {
- /* For this printer? Print servers always receive
- notifications. */
-
- if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) &&
- ( !strequal(msg_group->printername, p->dev.handlename) ) )
- continue;
+ /*
+ * If the entry has a connected client we send the message. There should
+ * only be one of these normally when dealing with the NT/2k spooler.
+ * However, iterate over all to make sure we deal with user applications
+ * in addition to spooler service.
+ *
+ * While we are only maintaining a single connection to the client,
+ * the FindFirstPrinterChangeNotification() call is made on a printer
+ * handle, so "client_connected" represents the whether or not the
+ * client asked for change notication on this handle.
+ *
+ * --jerry
+ */
- DEBUG(10,("Our printer\n"));
-
- /* allocate the max entries possible */
-
- data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
- ZERO_STRUCTP(data);
+ if (find_printer->notify.client_connected==True) {
- /* build the array of change notifications */
-
- sending_msg_count = 0;
-
- for ( i=0; i<msg_group->num_msgs; i++ ) {
- SPOOLSS_NOTIFY_MSG *msg = &messages[i];
-
- /* Are we monitoring this event? */
+ msg->low = find_printer->notify.change;
- if (!is_monitoring_event(p, msg->type, msg->field))
- continue;
+ /* does the client care about what changed? */
- sending_msg_count++;
-
+ if (msg->flags && !is_client_monitoring_event(find_printer, msg->flags)) {
+ DEBUG(10,("send_spoolss_event_notification: Client [%s] not monitoring these events\n",
+ find_printer->client.machine));
+ continue;
+ }
- DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
- msg->type, msg->field, p->dev.handlename));
-
- /*
- * if the is a printer notification handle and not a job notification
- * type, then set the id to 0. Other wise just use what was specified
- * in the message.
- *
- * When registering change notification on a print server handle
- * we always need to send back the id (snum) matching the printer
- * for which the change took place. For change notify registered
- * on a printer handle, this does not matter and the id should be 0.
- *
- * --jerry
- */
-
- if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
- id = 0;
+ if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername ));
else
- id = msg->id;
+ DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename));
+ /*
+ * if handle is a printer, only send if the printer_name matches.
+ * ...else if handle is a printerserver, send to all
+ */
- /* Convert unix jobid to smb jobid */
+ if (*msg->printer_name && (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
+ && !strequal(msg->printer_name, find_printer->dev.handlename))
+ {
+ DEBUG(10,("send_spoolss_event_notification: ignoring message sent to %s [%s]\n",
+ msg->printer_name, find_printer->dev.handlename ));
+ continue;
+ }
- if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
- id = sysjob_to_jobid(msg->id);
- if (id == -1) {
- DEBUG(3, ("no such unix jobid %d\n", msg->id));
- goto done;
+ /* lookup the printer if we have a name if we don't already have a
+ valid NT_PRINTER_INFO_LEVEL structure. And yes I'm assuming we
+ will always have a non-empty msg.printer_name */
+
+ if (!printer || !printer->info_2 || strcmp(msg->printer_name, printer->info_2->printername))
+ {
+
+ if (printer) {
+ free_a_printer(&printer, 2);
+ printer = NULL;
}
+
+ result = get_a_printer(&printer, 2, msg->printer_name);
+ if (!W_ERROR_IS_OK(result))
+ continue;
}
- construct_info_data( &data[data_len], msg->type, msg->field, id );
+ /* issue the client call */
- switch(msg->type) {
- case PRINTER_NOTIFY_TYPE:
- if ( printer_notify_table[msg->field].fn )
- printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
- break;
+ result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer);
- case JOB_NOTIFY_TYPE:
- if ( job_notify_table[msg->field].fn )
- job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
- break;
-
- default:
- DEBUG(5, ("Unknown notification type %d\n", msg->type));
- goto done;
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(5,("send_spoolss_event_notification: Event notification failed [%s]\n",
+ dos_errstr(result)));
}
-
- data_len++;
- }
-
- if ( sending_msg_count ) {
- cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd,
- data_len, data, p->notify.change, 0 );
}
}
-
-done:
- DEBUG(8,("send_notify2_changes: Exit...\n"));
+
return;
}
+/***************************************************************************
+ Receive the notify message and decode the message. Do not send
+ notification if we sent this originally as that would result in
+ duplicates.
+****************************************************************************/
-/***********************************************************************
- **********************************************************************/
-
-static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
+static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
{
-
- uint32 tv_sec, tv_usec;
- size_t offset = 0;
-
- /* Unpack message */
-
- offset += tdb_unpack((char *)buf + offset, len - offset, "f",
- msg->printer);
+ PRINTER_MESSAGE_INFO msg;
- offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd",
- &tv_sec, &tv_usec,
- &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
-
- if (msg->len == 0)
- tdb_unpack((char *)buf + offset, len - offset, "dd",
- &msg->notify.value[0], &msg->notify.value[1]);
- else
- tdb_unpack((char *)buf + offset, len - offset, "B",
- &msg->len, &msg->notify.data);
-
- DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
- msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
-
- tv->tv_sec = tv_sec;
- tv->tv_usec = tv_usec;
-
- if (msg->len == 0)
- DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
- msg->notify.value[1]));
- else
- dump_data(3, msg->notify.data, msg->len);
-
- return True;
-}
-
-/********************************************************************
- Receive a notify2 message list
- ********************************************************************/
-
-static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, size_t len)
-{
- size_t msg_count, i;
- char *buf = (char *)msg;
- char *msg_ptr;
- size_t msg_len;
- SPOOLSS_NOTIFY_MSG notify;
- SPOOLSS_NOTIFY_MSG_CTR messages;
- int num_groups;
-
- if (len < 4) {
- DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
+ if (len < sizeof(msg)) {
+ DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
return;
}
-
- msg_count = IVAL(buf, 0);
- msg_ptr = buf + 4;
-
- DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
- if (msg_count == 0) {
- DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
- return;
- }
+ memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO));
+
+ DEBUG(10,("srv_spoolss_receive_message: Got message printer change [queue = %s] low=0x%x high=0x%x flags=0x%x\n",
+ msg.printer_name, (unsigned int)msg.low, (unsigned int)msg.high, msg.flags ));
- /* initialize the container */
+ /* Iterate the printer list */
- ZERO_STRUCT( messages );
- notify_msg_ctr_init( &messages );
+ send_spoolss_event_notification(&msg);
- /*
- * build message groups for each printer identified
- * in a change_notify msg. Remember that a PCN message
- * includes the handle returned for the srv_spoolss_replyopenprinter()
- * call. Therefore messages are grouped according to printer handle.
- */
-
- for ( i=0; i<msg_count; i++ ) {
- struct timeval msg_tv;
-
- if (msg_ptr + 4 - buf > len) {
- DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
- return;
- }
+}
- msg_len = IVAL(msg_ptr,0);
- msg_ptr += 4;
+/***************************************************************************
+ Send a notify event.
+****************************************************************************/
- if (msg_ptr + msg_len - buf > len) {
- DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
- return;
- }
-
- /* unpack messages */
-
- ZERO_STRUCT( notify );
- notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
- msg_ptr += msg_len;
-
- /* add to correct list in container */
-
- notify_msg_ctr_addmsg( &messages, &notify );
-
- /* free memory that might have been allocated by notify2_unpack_msg() */
-
- if ( notify.len != 0 )
- SAFE_FREE( notify.notify.data );
- }
-
- /* process each group of messages */
+static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags)
+{
+ char msg[sizeof(PRINTER_MESSAGE_INFO)];
+ PRINTER_MESSAGE_INFO info;
- num_groups = notify_msg_ctr_numgroups( &messages );
- for ( i=0; i<num_groups; i++ )
- send_notify2_changes( &messages, i );
+ ZERO_STRUCT(info);
+
+ info.low = low;
+ info.high = high;
+ info.flags = flags;
+ fstrcpy(info.printer_name, printer_name);
+ memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO));
- /* cleanup */
-
- DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
+ DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x [%s], flags=0x%x\n",
+ low, high, printer_name, flags));
- notify_msg_ctr_destroy( &messages );
+ message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO),
+ False, NULL);
- return;
-}
+ return True;
+}
/********************************************************************
Send a message to ourself about new driver being installed
@@ -1211,7 +809,7 @@ static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
/**********************************************************************
callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
- over all printers, upgrading ones as necessary
+ over all printers, upgrading ones as neessary
**********************************************************************/
void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
@@ -1234,7 +832,7 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
- result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result))
continue;
@@ -1259,112 +857,6 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
}
/********************************************************************
- Update the cache for all printq's with a registered client
- connection
- ********************************************************************/
-
-void update_monitored_printq_cache( void )
-{
- Printer_entry *printer = printers_list;
- int snum;
-
- /* loop through all printers and update the cache where
- client_connected == True */
- while ( printer )
- {
- if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER)
- && printer->notify.client_connected )
- {
- snum = print_queue_snum(printer->dev.handlename);
- print_queue_status( snum, NULL, NULL );
- }
-
- printer = printer->next;
- }
-
- return;
-}
-/********************************************************************
- Send a message to ourself about new driver being installed
- so we can upgrade the information for each printer bound to this
- driver
- ********************************************************************/
-
-static BOOL srv_spoolss_reset_printerdata(char* drivername)
-{
- int len = strlen(drivername);
-
- if (!len)
- return False;
-
- DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
- drivername));
-
- message_send_pid(sys_getpid(), MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
-
- return True;
-}
-
-/**********************************************************************
- callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
- over all printers, resetting printer data as neessary
- **********************************************************************/
-
-void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len)
-{
- fstring drivername;
- int snum;
- int n_services = lp_numservices();
-
- len = MIN( len, sizeof(drivername)-1 );
- strncpy( drivername, buf, len );
-
- DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
-
- /* Iterate the printer list */
-
- for ( snum=0; snum<n_services; snum++ )
- {
- if ( lp_snum_ok(snum) && lp_print_ok(snum) )
- {
- WERROR result;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
- if ( !W_ERROR_IS_OK(result) )
- continue;
-
- /*
- * if the printer is bound to the driver,
- * then reset to the new driver initdata
- */
-
- if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
- {
- DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
-
- if ( !set_driver_init(printer, 2) ) {
- DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
- printer->info_2->printername, printer->info_2->drivername));
- }
-
- result = mod_a_printer( *printer, 2 );
- if ( !W_ERROR_IS_OK(result) ) {
- DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
- get_dos_error_msg(result)));
- }
- }
-
- free_a_printer( &printer, 2 );
- }
- }
-
- /* all done */
-
- return;
-}
-
-/********************************************************************
Copy routines used by convert_to_openprinterex()
*******************************************************************/
@@ -1546,9 +1038,11 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R
WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
{
- UNISTR2 *printername = NULL;
- PRINTER_DEFAULT *printer_default = &q_u->printer_default;
- POLICY_HND *handle = &r_u->handle;
+ UNISTR2 *printername = NULL;
+ PRINTER_DEFAULT *printer_default = &q_u->printer_default;
+/* uint32 user_switch = q_u->user_switch; - notused */
+/* SPOOL_USER_CTR user_ctr = q_u->user_ctr; - notused */
+ POLICY_HND *handle = &r_u->handle;
fstring name;
int snum;
@@ -1563,7 +1057,7 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
- unistr2_to_ascii(name, printername, sizeof(name)-1);
+ unistr2_to_dos(name, printername, sizeof(name)-1);
DEBUGADD(3,("checking name: %s\n",name));
@@ -1636,7 +1130,7 @@ Can't find printer handle we created for printer %s\n", name ));
/* if the user is not root and not a printer admin, then fail */
if ( user.uid != 0
- && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
+ && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum)) )
{
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1685,7 +1179,7 @@ Can't find printer handle we created for printer %s\n", name ));
/* check smb.conf parameters and the the sec_desc */
- if (!user_ok(uidtoname(user.uid), snum, user.groups, user.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
+ if (!user_ok(uidtoname(user.uid), snum) || !print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1704,32 +1198,9 @@ Can't find printer handle we created for printer %s\n", name ));
DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
-
}
- Printer->access_granted = printer_default->access_required;
-
- /*
- * If the client sent a devmode in the OpenPrinter() call, then
- * save it here in case we get a job submission on this handle
- */
-
- if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
- && q_u->printer_default.devmode_cont.devmode_ptr )
- {
- convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode,
- &Printer->nt_devmode );
- }
-
- /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
- optimization in Windows 2000 clients --jerry */
-
- if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
- && (RA_WIN2K == get_remote_arch()) )
- {
- DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
- sys_usleep( 500000 );
- }
+ Printer->access_granted = printer_default->access_required;
return WERR_OK;
}
@@ -1792,8 +1263,8 @@ BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
return False;
}
- rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
- rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
+ unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
+ unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
nt_devmode->specversion=devmode->specversion;
nt_devmode->driverversion=devmode->driverversion;
@@ -1853,18 +1324,14 @@ BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
{
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- int snum;
-
+
if (!Printer) {
DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
Printer->document_started=False;
- print_job_end(snum, Printer->jobid,True);
+ print_job_end(Printer->jobid,True);
/* error codes unhandled so far ... */
return WERR_OK;
@@ -1916,6 +1383,10 @@ WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL
update_c_setprinter(False);
+ if (W_ERROR_IS_OK(result)) {
+ srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0);
+ }
+
return result;
}
@@ -1948,9 +1419,21 @@ static int get_version_id (char * arch)
/********************************************************************
* _spoolss_deleteprinterdriver
+ *
+ * We currently delete the driver for the architecture only.
+ * This can leave the driver for other archtectures. However,
+ * since every printer associates a "Windows NT x86" driver name
+ * and we cannot delete that one while it is in use, **and** since
+ * it is impossible to assign a driver to a Samba printer without
+ * having the "Windows NT x86" driver installed,...
+ *
+ * ....we should not get into trouble here.
+ *
+ * --jerry
********************************************************************/
-WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
+WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+ SPOOL_R_DELETEPRINTERDRIVER *r_u)
{
fstring driver;
fstring arch;
@@ -1960,11 +1443,12 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
struct current_user user;
WERROR status;
WERROR status_win2k = WERR_ACCESS_DENIED;
-
+
+ unistr2_to_dos(driver, &q_u->driver, sizeof(driver)-1 );
+ unistr2_to_dos(arch, &q_u->arch, sizeof(arch)-1 );
get_current_user(&user, p);
- unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
- unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
+ unistr2_to_dos(arch, &q_u->arch, sizeof(arch)-1 );
/* check that we have a valid driver name first */
@@ -1997,7 +1481,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
status = WERR_PRINTER_DRIVER_IN_USE;
goto done;
}
-
+
if ( version == 2 )
{
if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
@@ -2007,7 +1491,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False );
free_a_printer_driver( info_win2k, 3 );
-
+
/* this should not have failed---if it did, report to client */
if ( !W_ERROR_IS_OK(status_win2k) )
goto done;
@@ -2023,303 +1507,77 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
done:
free_a_printer_driver( info, 3 );
-
- return status;
-}
-
-/********************************************************************
- * spoolss_deleteprinterdriverex
- ********************************************************************/
-
-WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u)
-{
- fstring driver;
- fstring arch;
- NT_PRINTER_DRIVER_INFO_LEVEL info;
- NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
- int version;
- uint32 flags = q_u->delete_flags;
- BOOL delete_files;
- struct current_user user;
- WERROR status;
- WERROR status_win2k = WERR_ACCESS_DENIED;
-
- get_current_user(&user, p);
-
- unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
- unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
-
- /* check that we have a valid driver name first */
- if ((version=get_version_id(arch)) == -1) {
- /* this is what NT returns */
- return WERR_INVALID_ENVIRONMENT;
- }
-
- if ( flags & DPD_DELETE_SPECIFIC_VERSION )
- version = q_u->version;
-
- ZERO_STRUCT(info);
- ZERO_STRUCT(info_win2k);
-
- status = get_a_printer_driver(&info, 3, driver, arch, version);
-
- if ( !W_ERROR_IS_OK(status) )
- {
- /*
- * if the client asked for a specific version,
- * or this is something other than Windows NT x86,
- * then we've failed
- */
-
- if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
- goto done;
-
- /* try for Win2k driver if "Windows NT x86" */
-
- version = 3;
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
- status = WERR_UNKNOWN_PRINTER_DRIVER;
- goto done;
- }
- }
-
- if ( printer_driver_in_use(info.info_3) ) {
- status = WERR_PRINTER_DRIVER_IN_USE;
- goto done;
- }
-
- /*
- * we have a couple of cases to consider.
- * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
- * then the delete should fail if **any** files overlap with
- * other drivers
- * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
- * non-overlapping files
- * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
- * is set, the do not delete any files
- * Refer to MSDN docs on DeletePrinterDriverEx() for details.
- */
-
- delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
-
- /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
-
- if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
- /* no idea of the correct error here */
- status = WERR_ACCESS_DENIED;
- goto done;
- }
-
-
- /* also check for W32X86/3 if necessary; maybe we already have? */
-
- if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
- if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
- {
-
- if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
- /* no idea of the correct error here */
- free_a_printer_driver( info_win2k, 3 );
- status = WERR_ACCESS_DENIED;
- goto done;
- }
-
- /* if we get to here, we now have 2 driver info structures to remove */
- /* remove the Win2k driver first*/
-
- status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files);
- free_a_printer_driver( info_win2k, 3 );
-
- /* this should not have failed---if it did, report to client */
-
- if ( !W_ERROR_IS_OK(status_win2k) )
- goto done;
- }
- }
-
- status = delete_printer_driver(info.info_3, &user, version, delete_files);
-
- if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
- status = WERR_OK;
-done:
- free_a_printer_driver( info, 3 );
return status;
}
-
-/****************************************************************************
- Internal routine for retreiving printerdata
- ***************************************************************************/
-
-static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
- const char *key, const char *value, uint32 *type, uint8 **data,
- uint32 *needed, uint32 in_size )
-{
- REGISTRY_VALUE *val;
- int size, data_len;
-
- if ( !(val = get_printer_data( printer->info_2, key, value)) )
- return WERR_BADFILE;
-
- *type = regval_type( val );
-
- DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
-
- size = regval_size( val );
-
- /* copy the min(in_size, len) */
-
- if ( in_size ) {
- data_len = (size > in_size) ? in_size : size*sizeof(uint8);
-
- /* special case for 0 length values */
- if ( data_len ) {
- if ( (*data = (uint8 *)talloc_memdup(ctx, regval_data_p(val), data_len)) == NULL )
- return WERR_NOMEM;
- }
- else {
- if ( (*data = (uint8 *)talloc_zero(ctx, in_size)) == NULL )
- return WERR_NOMEM;
- }
- }
- else
- *data = NULL;
-
- *needed = size;
-
- DEBUG(5,("get_printer_dataex: copy done\n"));
-
- return WERR_OK;
-}
-
-/****************************************************************************
- Internal routine for removing printerdata
- ***************************************************************************/
-
-static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
-{
- return delete_printer_data( printer->info_2, key, value );
-}
-
-/****************************************************************************
- Internal routine for storing printerdata
- ***************************************************************************/
-
-static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
- uint32 type, uint8 *data, int real_len )
-{
- delete_printer_data( printer->info_2, key, value );
-
- return add_printer_data( printer->info_2, key, value, type, data, real_len );
-}
-
/********************************************************************
GetPrinterData on a printer server Handle.
********************************************************************/
-static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
+static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
{
int i;
DEBUG(8,("getprinterdata_printer_server:%s\n", value));
- if (!StrCaseCmp(value, "W3SvcInstalled")) {
+ if (!strcmp(value, "W3SvcInstalled")) {
*type = 0x4;
if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
- *needed = 0x4;
- return WERR_OK;
+ return False;
+ *needed = 0x4;
+ return True;
}
- if (!StrCaseCmp(value, "BeepEnabled")) {
+ if (!strcmp(value, "BeepEnabled")) {
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
+ return False;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
- return WERR_OK;
+ return True;
}
- if (!StrCaseCmp(value, "EventLog")) {
+ if (!strcmp(value, "EventLog")) {
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
+ return False;
/* formally was 0x1b */
SIVAL(*data, 0, 0x0);
*needed = 0x4;
- return WERR_OK;
+ return True;
}
- if (!StrCaseCmp(value, "NetPopup")) {
+ if (!strcmp(value, "NetPopup")) {
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
+ return False;
SIVAL(*data, 0, 0x00);
*needed = 0x4;
- return WERR_OK;
- }
-
- if (!StrCaseCmp(value, "MajorVersion")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
-
- /* Windows NT 4.0 seems to not allow uploading of drivers
- to a server that reports 0x3 as the MajorVersion.
- need to investigate more how Win2k gets around this .
- -- jerry */
-
- if ( RA_WINNT == get_remote_arch() )
- SIVAL(*data, 0, 2);
- else
- SIVAL(*data, 0, 3);
-
- *needed = 0x4;
- return WERR_OK;
+ return True;
}
- if (!StrCaseCmp(value, "MinorVersion")) {
+ if (!strcmp(value, "MajorVersion")) {
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
- SIVAL(*data, 0, 0);
+ return False;
+#ifndef EMULATE_WIN2K_HACK /* JERRY */
+ SIVAL(*data, 0, 2);
+#else
+ SIVAL(*data, 0, 3);
+#endif
*needed = 0x4;
- return WERR_OK;
- }
-
- /* REG_BINARY
- * uint32 size = 0x114
- * uint32 major = 5
- * uint32 minor = [0|1]
- * uint32 build = [2195|2600]
- * extra unicode string = e.g. "Service Pack 3"
- */
- if (!StrCaseCmp(value, "OSVersion")) {
- *type = 0x3;
- *needed = 0x114;
-
- if((*data = (uint8 *)talloc(ctx, (*needed)*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
- ZERO_STRUCTP( *data );
-
- SIVAL(*data, 0, *needed); /* size */
- SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
- SIVAL(*data, 8, 0);
- SIVAL(*data, 12, 2195); /* build */
-
- /* leave extra string empty */
-
- return WERR_OK;
+ return True;
}
+ if (!strcmp(value, "DefaultSpoolDirectory")) {
+ fstring string;
- if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
- const char *string="C:\\PRINTERS";
+ fstrcpy(string, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
*type = 0x1;
*needed = 2*(strlen(string)+1);
if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
- return WERR_NOMEM;
+ return False;
memset(*data, 0, (*needed > in_size) ? *needed:in_size);
/* it's done by hand ready to go on the wire */
@@ -2327,52 +1585,82 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
(*data)[2*i]=string[i];
(*data)[2*i+1]='\0';
}
- return WERR_OK;
+ return True;
}
- if (!StrCaseCmp(value, "Architecture")) {
- const char *string="Windows NT x86";
+ if (!strcmp(value, "Architecture")) {
+ pstring string="Windows NT x86";
*type = 0x1;
*needed = 2*(strlen(string)+1);
if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
- return WERR_NOMEM;
+ return False;
memset(*data, 0, (*needed > in_size) ? *needed:in_size);
for (i=0; i<strlen(string); i++) {
(*data)[2*i]=string[i];
(*data)[2*i+1]='\0';
}
- return WERR_OK;
+ return True;
}
+
+ return False;
+}
- if (!StrCaseCmp(value, "DsPresent")) {
- *type = 0x4;
- if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
- return WERR_NOMEM;
- SIVAL(*data, 0, 0x01);
- *needed = 0x4;
- return WERR_OK;
+/********************************************************************
+ GetPrinterData on a printer Handle.
+********************************************************************/
+
+static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND *handle,
+ fstring value, uint32 *type,
+ uint8 **data, uint32 *needed, uint32 in_size )
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int snum=0;
+ uint8 *idata=NULL;
+ uint32 len;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+
+ DEBUG(5,("getprinterdata_printer\n"));
+
+ if (!Printer) {
+ DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return False;
}
- if (!StrCaseCmp(value, "DNSMachineName")) {
- pstring hostname;
-
- if (!get_mydnsfullname(hostname))
- return WERR_BADFILE;
- *type = 0x1;
- *needed = 2*(strlen(hostname)+1);
- if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
- return WERR_NOMEM;
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
- for (i=0; i<strlen(hostname); i++) {
- (*data)[2*i]=hostname[i];
- (*data)[2*i+1]='\0';
- }
- return WERR_OK;
+ if(!get_printer_snum(p, handle, &snum))
+ return False;
+
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ return False;
+
+ if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
+ free_a_printer(&printer, 2);
+ return False;
}
+ free_a_printer(&printer, 2);
- return WERR_BADFILE;
-}
+ DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
+
+ if (in_size) {
+ if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
+ return False;
+ }
+
+ memset(*data, 0, in_size *sizeof(uint8));
+ /* copy the min(in_size, len) */
+ memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
+ } else {
+ *data = NULL;
+ }
+
+ *needed = len;
+
+ DEBUG(5,("getprinterdata_printer:copy done\n"));
+
+ SAFE_FREE(idata);
+
+ return True;
+}
/********************************************************************
* spoolss_getprinterdata
@@ -2380,18 +1668,17 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *valuename = &q_u->valuename;
- uint32 in_size = q_u->size;
- uint32 *type = &r_u->type;
- uint32 *out_size = &r_u->size;
- uint8 **data = &r_u->data;
- uint32 *needed = &r_u->needed;
- WERROR status;
- fstring value;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum = 0;
+ POLICY_HND *handle = &q_u->handle;
+ UNISTR2 *valuename = &q_u->valuename;
+ uint32 in_size = q_u->size;
+ uint32 *type = &r_u->type;
+ uint32 *out_size = &r_u->size;
+ uint8 **data = &r_u->data;
+ uint32 *needed = &r_u->needed;
+
+ fstring value;
+ BOOL found=False;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
/*
* Reminder: when it's a string, the length is in BYTES
@@ -2400,222 +1687,80 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
* JFM, 4/19/1999
*/
- *out_size = in_size;
+ *out_size=in_size;
/* in case of problem, return some default values */
-
- *needed = 0;
- *type = 0;
+ *needed=0;
+ *type=0;
DEBUG(4,("_spoolss_getprinterdata\n"));
- if ( !Printer ) {
+ if (!Printer) {
+ if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- status = WERR_BADFID;
- goto done;
+ return WERR_BADFID;
}
- unistr2_to_ascii(value, valuename, sizeof(value)-1);
+ unistr2_to_dos(value, valuename, sizeof(value)-1);
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER )
- status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
else
- {
- if ( !get_printer_snum(p,handle, &snum) ) {
- status = WERR_BADFID;
- goto done;
- }
-
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(status) )
- goto done;
-
- /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
-
- if ( strequal(value, "ChangeId") ) {
- *type = REG_DWORD;
- *needed = sizeof(uint32);
- if ( (*data = (uint8*)talloc(p->mem_ctx, sizeof(uint32))) == NULL) {
- status = WERR_NOMEM;
- goto done;
- }
- SIVAL( *data, 0, printer->info_2->changeid );
- status = WERR_OK;
- }
- else
- status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
- }
+ found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
- if (*needed > *out_size)
- status = WERR_MORE_DATA;
-
-done:
- if ( !W_ERROR_IS_OK(status) )
- {
- DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
-
+ if (found==False) {
+ DEBUG(5, ("value not found, allocating %d\n", *out_size));
/* reply this param doesn't exist */
-
- if ( *out_size ) {
- if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) {
- if ( printer )
- free_a_printer( &printer, 2 );
+ if (*out_size) {
+ if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
return WERR_NOMEM;
- }
- }
- else {
+ } else {
*data = NULL;
}
- }
-
- /* cleanup & exit */
-
- if ( printer )
- free_a_printer( &printer, 2 );
-
- return status;
-}
-/*********************************************************
- Connect to the client machine.
-**********************************************************/
+ /* error depends on handle type */
-static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
- struct in_addr *client_ip, const char *remote_machine)
-{
- ZERO_STRUCTP(the_cli);
-
- if(cli_initialise(the_cli) == NULL) {
- DEBUG(0,("spoolss_connect_to_client: unable to initialize client connection.\n"));
- return False;
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ return WERR_INVALID_PARAM;
+ else
+ return WERR_BADFILE;
}
- if ( is_zero_ip(*client_ip) ) {
- if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) {
- DEBUG(0,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (ismyip(the_cli->dest_ip)) {
- DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
- }
- else {
- the_cli->dest_ip.s_addr = client_ip->s_addr;
- DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
- inet_ntoa(*client_ip) ));
- }
-
- if (!cli_connect(the_cli, remote_machine, &the_cli->dest_ip)) {
- DEBUG(0,("spoolss_connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!attempt_netbios_session_request(the_cli, global_myname(), remote_machine, &the_cli->dest_ip)) {
- DEBUG(0,("spoolss_connect_to_client: machine %s rejected the NetBIOS session request.\n",
- remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- the_cli->protocol = PROTOCOL_NT1;
- cli_setup_signing_state(the_cli, lp_client_signing());
-
- if (!cli_negprot(the_cli)) {
- DEBUG(0,("spoolss_connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (the_cli->protocol != PROTOCOL_NT1) {
- DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(the_cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("spoolss_connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!(the_cli->sec_mode & 1)) {
- DEBUG(0,("spoolss_connect_to_client: machine %s isn't in user level security mode\n", remote_machine));
- cli_shutdown(the_cli);
- return False;
- }
-
- if (!cli_send_tconX(the_cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("spoolss_connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
- cli_shutdown(the_cli);
- return False;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- if(cli_nt_session_open(the_cli, PI_SPOOLSS) == False) {
- DEBUG(0,("spoolss_connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli)));
- cli_nt_session_close(the_cli);
- cli_ulogoff(the_cli);
- cli_shutdown(the_cli);
- return False;
- }
-
- return True;
+ if (*needed > *out_size)
+ return WERR_MORE_DATA;
+ else
+ return WERR_OK;
}
/***************************************************************************
Connect to the client.
****************************************************************************/
-static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
- uint32 localprinter, uint32 type,
- POLICY_HND *handle, struct in_addr *client_ip)
+static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
{
WERROR result;
/*
* If it's the first connection, contact the client
- * and connect to the IPC$ share anonymously
+ * and connect to the IPC$ share anonumously
*/
if (smb_connections==0) {
fstring unix_printer;
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
+ dos_to_unix(unix_printer);
- ZERO_STRUCT(notify_cli);
-
- if(!spoolss_connect_to_client(&notify_cli, client_ip, unix_printer))
+ if(!spoolss_connect_to_client(&cli, unix_printer))
return False;
- message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
- /* Tell the connections db we're now interested in printer
- * notify messages. */
- register_message_flags( True, FLAG_MSG_PRINTING );
- }
-
- /*
- * Tell the specific printing tdb we want messages for this printer
- * by registering our PID.
- */
+ message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
- if (!print_notify_register_pid(snum))
- DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
+ }
smb_connections++;
- result = cli_spoolss_reply_open_printer(&notify_cli, notify_cli.mem_ctx, printer, localprinter,
+ result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter,
type, handle);
if (!W_ERROR_IS_OK(result))
@@ -2643,9 +1788,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
uint32 options = q_u->options;
UNISTR2 *localmachine = &q_u->localmachine;
uint32 printerlocal = q_u->printerlocal;
- int snum = -1;
SPOOL_NOTIFY_OPTION *option = q_u->option;
- struct in_addr client_ip;
/* store the notify value in the printer struct */
@@ -2665,25 +1808,15 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
Printer->notify.option=dup_spool_notify_option(option);
- unistr2_to_ascii(Printer->notify.localmachine, localmachine,
- sizeof(Printer->notify.localmachine)-1);
-
- /* Connect to the client machine and send a ReplyOpenPrinter */
+ unistr2_to_dos(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
- snum = -1;
- else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) &&
- !get_printer_snum(p, handle, &snum) )
- return WERR_BADFID;
-
- client_ip.s_addr = inet_addr(p->conn->client_address);
-
- if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
+ /* connect to the client machine and send a ReplyOpenPrinter */
+ if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
Printer->notify.printerlocal, 1,
- &Printer->notify.client_hnd, &client_ip))
- return WERR_SERVER_UNAVAILABLE;
-
- Printer->notify.client_connected=True;
+ &Printer->notify.client_hnd))
+ {
+ Printer->notify.client_connected=True;
+ }
return WERR_OK;
}
@@ -2703,9 +1836,9 @@ void spoolss_notify_server_name(int snum,
slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
- len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, temp_name, sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2738,9 +1871,9 @@ void spoolss_notify_printer_name(int snum,
p++;
}
- len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, p, sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2764,9 +1897,10 @@ void spoolss_notify_share_name(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, lp_servicename(snum),
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2792,9 +1926,10 @@ void spoolss_notify_port_name(int snum,
/* even if it's strange, that's consistant in all the code */
- len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->portname,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2819,9 +1954,10 @@ void spoolss_notify_driver_name(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->drivername,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2846,11 +1982,13 @@ void spoolss_notify_comment(int snum,
uint32 len;
if (*printer->info_2->comment == '\0')
- len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, lp_comment(snum),
+ sizeof(temp) - 2, True);
else
- len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->comment,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2875,9 +2013,10 @@ void spoolss_notify_location(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->location,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2914,9 +2053,10 @@ void spoolss_notify_sepfile(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->sepfile,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2941,9 +2081,10 @@ void spoolss_notify_print_processor(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->printprocessor,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2968,9 +2109,10 @@ void spoolss_notify_parameters(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->parameters,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2995,9 +2137,10 @@ void spoolss_notify_datatype(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, printer->info_2->datatype,
+ sizeof(pstring) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -3020,8 +2163,8 @@ static void spoolss_notify_security_desc(int snum,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.sd.size = printer->info_2->secdesc_buf->len;
- data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sec ) ;
+ data->notify_data.data.length=0;
+ data->notify_data.data.string = NULL;
}
/*******************************************************************
@@ -3155,9 +2298,10 @@ static void spoolss_notify_username(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, queue->fs_user,
+ sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -3195,9 +2339,10 @@ static void spoolss_notify_job_name(int snum,
pstring temp;
uint32 len;
- len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, queue->fs_file, sizeof(temp) - 2,
+ True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -3245,9 +2390,9 @@ static void spoolss_notify_job_status_string(int snum,
}
#endif /* NO LONGER NEEDED. */
- len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
+ len = (uint32)dos_PutUniCode(temp, p, sizeof(temp) - 2, True);
- data->notify_data.data.length = len;
+ data->notify_data.data.length = len / 2 - 1;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -3371,6 +2516,8 @@ static void spoolss_notify_submitted_time(int snum,
SSVAL(p, 14, st.milliseconds);
}
+#define END 65535
+
struct s_notify_info_data_table
{
uint16 type;
@@ -3386,57 +2533,59 @@ struct s_notify_info_data_table
whether the notification data is a pointer to a variable sized
buffer, a one value uint32 or a two value uint32. */
-static const struct s_notify_info_data_table notify_info_data_table[] =
-{
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
+struct s_notify_info_data_table notify_info_data_table[] =
+{
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, spoolss_notify_total_pages },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, spoolss_notify_pages_printed },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL },
+{ END, END, "", END, NULL }
};
/*******************************************************************
@@ -3447,52 +2596,43 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
{
int i=0;
- for (i = 0; i < sizeof(notify_info_data_table); i++)
+ while (notify_info_data_table[i].type != END)
{
- if ( (notify_info_data_table[i].type == type)
- && (notify_info_data_table[i].field == field) )
+ if ( (notify_info_data_table[i].type == type ) &&
+ (notify_info_data_table[i].field == field ) )
{
- switch(notify_info_data_table[i].size)
- {
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
- return 1;
- case NOTIFY_STRING:
- return 2;
-
- /* The only pointer notify data I have seen on
- the wire is the submitted time and this has
- the notify size set to 4. -tpot */
-
- case NOTIFY_POINTER:
- return 4;
-
- case NOTIFY_SECDESC:
- return 5;
- }
+ return (notify_info_data_table[i].size);
}
+ i++;
}
-
- DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
-
- return 0;
+ return (65535);
}
/*******************************************************************
Return the type of notify_info_data.
********************************************************************/
-static int type_of_notify_info_data(uint16 type, uint16 field)
+static BOOL type_of_notify_info_data(uint16 type, uint16 field)
{
int i=0;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field)
- return notify_info_data_table[i].size;
+ while (notify_info_data_table[i].type != END)
+ {
+ if ( (notify_info_data_table[i].type == type ) &&
+ (notify_info_data_table[i].field == field ) )
+ {
+ if (notify_info_data_table[i].size == POINTER)
+ {
+ return (False);
+ }
+ else
+ {
+ return (True);
+ }
+ }
+ i++;
}
-
- return False;
+ return (False);
}
/****************************************************************************
@@ -3500,18 +2640,21 @@ static int type_of_notify_info_data(uint16 type, uint16 field)
static int search_notify(uint16 type, uint16 field, int *value)
{
- int i;
+ int j;
+ BOOL found;
- for (i = 0; i < sizeof(notify_info_data_table); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field &&
- notify_info_data_table[i].fn != NULL) {
- *value = i;
- return True;
- }
+ for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
+ {
+ if ( (notify_info_data_table[j].type == type ) &&
+ (notify_info_data_table[j].field == field ) )
+ found=True;
}
-
- return False;
+ *value=--j;
+
+ if ( found && (notify_info_data_table[j].fn != NULL) )
+ return True;
+ else
+ return False;
}
/****************************************************************************
@@ -3522,12 +2665,9 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
info_data->type = type;
info_data->field = field;
info_data->reserved = 0;
-
+ info_data->id = id;
info_data->size = size_of_notify_info_data(type, field);
info_data->enc_type = type_of_notify_info_data(type, field);
-
- info_data->id = id;
-
}
@@ -3537,7 +2677,7 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
*
********************************************************************/
-static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
+static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
snum, SPOOL_NOTIFY_OPTION_TYPE
*option_type, uint32 id,
TALLOC_CTX *mem_ctx)
@@ -3556,12 +2696,11 @@ static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
(option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
option_type->count, lp_servicename(snum)));
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
for(field_num=0; field_num<option_type->count; field_num++) {
field = option_type->fields[field_num];
-
DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
if (!search_notify(type, field, &j) )
@@ -3570,10 +2709,10 @@ static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
return False;
- } else
- info->data = tid;
+ }
+ else info->data = tid;
- current_data = &info->data[info->count];
+ current_data=&info->data[info->count];
construct_info_data(current_data, type, field, id);
@@ -3678,6 +2817,7 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
int n_services=lp_numservices();
int i;
+ uint32 id;
SPOOL_NOTIFY_OPTION *option;
SPOOL_NOTIFY_OPTION_TYPE *option_type;
@@ -3687,6 +2827,7 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
return WERR_BADFID;
option=Printer->notify.option;
+ id=1;
info->version=2;
info->data=NULL;
info->count=0;
@@ -3698,17 +2839,16 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
continue;
for (snum=0; snum<n_services; snum++)
- {
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
- }
+ if (construct_notify_printer_info
+ (info, snum, option_type, id, mem_ctx))
+ id++;
}
-#if 0
/*
* Debugging information, don't delete.
*/
-
+ /*
DEBUG(1,("dumping the NOTIFY_INFO\n"));
DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
@@ -3718,7 +2858,7 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
i, info->data[i].type, info->data[i].field, info->data[i].reserved,
info->data[i].id, info->data[i].size, info->data[i].enc_type));
}
-#endif
+ */
return WERR_OK;
}
@@ -3760,7 +2900,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
switch ( option_type->type ) {
case PRINTER_NOTIFY_TYPE:
- if(construct_notify_printer_info(Printer, info, snum,
+ if(construct_notify_printer_info(info, snum,
option_type, id,
mem_ctx))
id--;
@@ -3771,7 +2911,8 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
count = print_queue_status(snum, &queue, &status);
- if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2,
+ lp_servicename(snum))))
goto done;
for (j=0; j<count; j++) {
@@ -3815,6 +2956,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */
SPOOL_NOTIFY_INFO *info = &r_u->info;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
@@ -3832,21 +2974,14 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
DEBUG(4,("Printer type %x\n",Printer->printer_type));
/*
- * We are now using the change value, and
+ * same thing for option->flags
* I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
* I don't have a global notification system, I'm sending back all the
* informations even when _NOTHING_ has changed.
*/
- /* We need to keep track of the change value to send back in
- RRPCN replies otherwise our updates are ignored. */
-
- Printer->notify.fnpcn = True;
-
- if (Printer->notify.client_connected) {
- DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
+ if (Printer->notify.client_connected)
Printer->notify.change = q_u->change;
- }
/* just ignore the SPOOL_NOTIFY_OPTION */
@@ -3860,9 +2995,7 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
break;
}
- Printer->notify.fnpcn = False;
-
-done:
+ done:
return result;
}
@@ -3871,7 +3004,7 @@ done:
* fill a printer_info_0 struct
********************************************************************/
-static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
+static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
{
pstring chaine;
int count;
@@ -3882,7 +3015,7 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
time_t setuptime;
print_status_struct status;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
count = print_queue_length(snum, &status);
@@ -3941,11 +3074,13 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
printer->global_counter = global_counter;
printer->total_pages = 0;
-
- /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
+#ifndef EMULATE_WIN2K_HACK /* JERRY */
+ printer->major_version = 0x0004; /* NT 4 */
+ printer->build_version = 0x0565; /* build 1381 */
+#else
printer->major_version = 0x0005; /* NT 5 */
printer->build_version = 0x0893; /* build 2195 */
-
+#endif
printer->unknown7 = 0x1;
printer->unknown8 = 0x0;
printer->unknown9 = 0x0;
@@ -3978,13 +3113,13 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
* construct_printer_info_1
* fill a printer_info_1 struct
********************************************************************/
-static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
+static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum)
{
pstring chaine;
pstring chaine2;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
printer->flags=flags;
@@ -4023,20 +3158,45 @@ static void free_dev_mode(DEVICEMODE *dev)
SAFE_FREE(dev);
}
-
/****************************************************************************
- Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
- should be valid upon entry
+ Create a DEVMODE struct. Returns malloced memory.
****************************************************************************/
-static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
+static DEVICEMODE *construct_dev_mode(int snum)
{
- if ( !devmode || !ntdevmode )
- return False;
-
- init_unistr(&devmode->devicename, ntdevmode->devicename);
+ char adevice[32];
+ char aform[32];
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ NT_DEVICEMODE *ntdevmode = NULL;
+ DEVICEMODE *devmode = NULL;
- init_unistr(&devmode->formname, ntdevmode->formname);
+ DEBUG(7,("construct_dev_mode\n"));
+
+ DEBUGADD(8,("getting printer characteristics\n"));
+
+ if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
+ DEBUG(2,("construct_dev_mode: malloc fail.\n"));
+ return NULL;
+ }
+
+ ZERO_STRUCTP(devmode);
+
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ goto fail;
+
+ if (printer->info_2->devmode)
+ ntdevmode = dup_nt_devicemode(printer->info_2->devmode);
+
+ if (ntdevmode == NULL)
+ goto fail;
+
+ DEBUGADD(8,("loading DEVICEMODE\n"));
+
+ slprintf(adevice, sizeof(adevice)-1, printer->info_2->printername);
+ init_unistr(&devmode->devicename, adevice);
+
+ slprintf(aform, sizeof(aform)-1, ntdevmode->formname);
+ init_unistr(&devmode->formname, aform);
devmode->specversion = ntdevmode->specversion;
devmode->driverversion = ntdevmode->driverversion;
@@ -4064,51 +3224,23 @@ static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
if (ntdevmode->private != NULL) {
if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
- return False;
+ goto fail;
}
-
- return True;
-}
-
-/****************************************************************************
- Create a DEVMODE struct. Returns malloced memory.
-****************************************************************************/
-
-DEVICEMODE *construct_dev_mode(int snum)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- DEVICEMODE *devmode = NULL;
-
- DEBUG(7,("construct_dev_mode\n"));
-
- DEBUGADD(8,("getting printer characteristics\n"));
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
- return NULL;
-
- if ( !printer->info_2->devmode ) {
- DEBUG(5, ("BONG! There was no device mode!\n"));
- goto done;
- }
-
- if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
- DEBUG(2,("construct_dev_mode: malloc fail.\n"));
- goto done;
- }
+ free_nt_devicemode(&ntdevmode);
+ free_a_printer(&printer,2);
- ZERO_STRUCTP(devmode);
-
- DEBUGADD(8,("loading DEVICEMODE\n"));
+ return devmode;
- if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
- free_dev_mode( devmode );
- devmode = NULL;
- }
+ fail:
-done:
- free_a_printer(&printer,2);
+ if (ntdevmode)
+ free_nt_devicemode(&ntdevmode);
+ if (printer)
+ free_a_printer(&printer,2);
+ free_dev_mode(devmode);
- return devmode;
+ return NULL;
}
/********************************************************************
@@ -4116,14 +3248,14 @@ done:
* fill a printer_info_2 struct
********************************************************************/
-static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum)
{
int count;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
print_status_struct status;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
count = print_queue_length(snum, &status);
@@ -4179,12 +3311,12 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *p
* fill a printer_info_3 struct
********************************************************************/
-static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
+static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
{
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
PRINTER_INFO_3 *printer = NULL;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
*pp_printer = NULL;
@@ -4234,11 +3366,11 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **
* fill a printer_info_4 struct
********************************************************************/
-static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
+static BOOL construct_printer_info_4(PRINTER_INFO_4 *printer, int snum)
{
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
@@ -4254,48 +3386,20 @@ static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *p
* fill a printer_info_5 struct
********************************************************************/
-static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum)
{
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
- init_unistr(&printer->printername, ntprinter->info_2->printername);
- init_unistr(&printer->portname, ntprinter->info_2->portname);
+ init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
+ init_unistr(&printer->portname, ntprinter->info_2->portname); /* portname */
printer->attributes = ntprinter->info_2->attributes;
-
- /* these two are not used by NT+ according to MSDN */
-
- printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
- printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
+ printer->device_not_selected_timeout = 0x3a98;
+ printer->transmission_retry_timeout = 0xafc8;
free_a_printer(&ntprinter, 2);
-
- return True;
-}
-
-/********************************************************************
- * construct_printer_info_7
- * fill a printer_info_7 struct
- ********************************************************************/
-
-static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
-{
- char *guid_str = NULL;
- UUID_FLAT guid;
-
- if (is_printer_published(print_hnd, snum, &guid)) {
- asprintf(&guid_str, "{%s}",
- smb_uuid_string_static(smb_uuid_unpack_static(guid)));
- strupper_m(guid_str);
- init_unistr(&printer->guid, guid_str);
- printer->action = SPOOL_DS_PUBLISH;
- } else {
- init_unistr(&printer->guid, "");
- printer->action = SPOOL_DS_UNPUBLISH;
- }
-
return True;
}
@@ -4317,7 +3421,7 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
- if (construct_printer_info_1(NULL, flags, &current_prt, snum)) {
+ if (construct_printer_info_1(flags, &current_prt, snum)) {
if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
SAFE_FREE(printers);
@@ -4486,7 +3590,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
- if (construct_printer_info_2(NULL, &current_prt, snum)) {
+ if (construct_printer_info_2(&current_prt, snum)) {
if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
SAFE_FREE(printers);
@@ -4637,8 +3741,8 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
* Level 5: same as Level 2
*/
- unistr2_to_ascii(name, servername, sizeof(name)-1);
- strupper_m(name);
+ unistr2_to_dos(name, servername, sizeof(name)-1);
+ strupper(name);
switch (level) {
case 1:
@@ -4657,14 +3761,14 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_0 *printer=NULL;
if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
return WERR_NOMEM;
- construct_printer_info_0(print_hnd, printer, snum);
+ construct_printer_info_0(printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_0(printer);
@@ -4690,14 +3794,14 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_1 *printer=NULL;
if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
return WERR_NOMEM;
- construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
+ construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_1(printer);
@@ -4723,14 +3827,14 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_2 *printer=NULL;
if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
return WERR_NOMEM;
- construct_printer_info_2(print_hnd, printer, snum);
+ construct_printer_info_2(printer, snum);
/* check the required size. */
*needed += spoolss_size_printer_info_2(printer);
@@ -4759,11 +3863,11 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_3 *printer=NULL;
- if (!construct_printer_info_3(print_hnd, &printer, snum))
+ if (!construct_printer_info_3(&printer, snum))
return WERR_NOMEM;
/* check the required size. */
@@ -4790,14 +3894,14 @@ static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_4 *printer=NULL;
if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL)
return WERR_NOMEM;
- if (!construct_printer_info_4(print_hnd, printer, snum))
+ if (!construct_printer_info_4(printer, snum))
return WERR_NOMEM;
/* check the required size. */
@@ -4824,14 +3928,14 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_5 *printer=NULL;
if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL)
return WERR_NOMEM;
- if (!construct_printer_info_5(print_hnd, printer, snum))
+ if (!construct_printer_info_5(printer, snum))
return WERR_NOMEM;
/* check the required size. */
@@ -4855,37 +3959,6 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER
return WERR_OK;
}
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_7 *printer=NULL;
-
- if((printer=(PRINTER_INFO_7*)malloc(sizeof(PRINTER_INFO_7)))==NULL)
- return WERR_NOMEM;
-
- if (!construct_printer_info_7(print_hnd, printer, snum))
- return WERR_NOMEM;
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_7(printer);
-
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_7(printer);
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- /* fill the buffer with the structures */
- smb_io_printer_info_7("", buffer, printer, 0);
-
- /* clear memory */
- free_printer_info_7(printer);
-
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
-}
-
/****************************************************************************
****************************************************************************/
@@ -4896,7 +3969,6 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
int snum;
@@ -4911,19 +3983,17 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
switch (level) {
case 0:
- return getprinter_level_0(Printer, snum, buffer, offered, needed);
+ return getprinter_level_0(snum, buffer, offered, needed);
case 1:
- return getprinter_level_1(Printer, snum, buffer, offered, needed);
+ return getprinter_level_1(snum, buffer, offered, needed);
case 2:
- return getprinter_level_2(Printer, snum, buffer, offered, needed);
+ return getprinter_level_2(snum, buffer, offered, needed);
case 3:
- return getprinter_level_3(Printer, snum, buffer, offered, needed);
+ return getprinter_level_3(snum, buffer, offered, needed);
case 4:
- return getprinter_level_4(Printer, snum, buffer, offered, needed);
+ return getprinter_level_4(snum, buffer, offered, needed);
case 5:
- return getprinter_level_5(Printer, snum, buffer, offered, needed);
- case 7:
- return getprinter_level_7(Printer, snum, buffer, offered, needed);
+ return getprinter_level_5(snum, buffer, offered, needed);
}
return WERR_UNKNOWN_LEVEL;
}
@@ -4948,7 +4018,7 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst
ZERO_STRUCT(driver);
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return WERR_INVALID_PRINTER_NAME;
if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
@@ -5008,7 +4078,7 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst
ZERO_STRUCT(printer);
ZERO_STRUCT(driver);
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return WERR_INVALID_PRINTER_NAME;
if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
@@ -5027,7 +4097,7 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst
* convert an array of ascii string to a UNICODE string
********************************************************************/
-static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
+static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
{
int i=0;
int j=0;
@@ -5038,54 +4108,30 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
DEBUG(6,("init_unistr_array\n"));
*uni_array=NULL;
- while (True)
- {
- if ( !char_array )
+ while (1) {
+ if (char_array == NULL)
v = "";
- else
- {
+ else {
v = char_array[i];
- if (!v)
- v = ""; /* hack to handle null lists */
+ if (!v) v = ""; /* hack to handle null lists */
}
-
- /* hack to allow this to be used in places other than when generating
- the list of dependent files */
-
- if ( servername )
- slprintf( line, sizeof(line)-1, "\\\\%s%s", servername, v );
- else
- pstrcpy( line, v );
-
- DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
-
- /* add one extra unit16 for the second terminating NULL */
-
- if ( (tuary=Realloc(*uni_array, (j+1+strlen(line)+2)*sizeof(uint16))) == NULL ) {
+ if (strlen(v) == 0) break;
+ slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
+ DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
+ if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
DEBUG(2,("init_unistr_array: Realloc error\n" ));
- return 0;
+ return;
} else
*uni_array = tuary;
-
- if ( !strlen(v) )
- break;
-
- j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
+ j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
i++;
}
if (*uni_array) {
- /* special case for ""; we need to add both NULL's here */
- if (!j)
- (*uni_array)[j++]=0x0000;
(*uni_array)[j]=0x0000;
}
DEBUGADD(6,("last one:done\n"));
-
- /* return size of array in uint16's */
-
- return j+1;
}
/********************************************************************
@@ -5104,29 +4150,29 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
init_unistr( &info->name, driver.info_3->name );
init_unistr( &info->architecture, driver.info_3->environment );
- if (strlen(driver.info_3->driverpath)) {
- slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
- init_unistr( &info->driverpath, temp );
- } else
- init_unistr( &info->driverpath, "" );
+ if (strlen(driver.info_3->driverpath)) {
+ slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
+ init_unistr( &info->driverpath, temp );
+ } else
+ init_unistr( &info->driverpath, "" );
- if (strlen(driver.info_3->datafile)) {
- slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
- init_unistr( &info->datafile, temp );
- } else
- init_unistr( &info->datafile, "" );
+ if (strlen(driver.info_3->datafile)) {
+ slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+ init_unistr( &info->datafile, temp );
+ } else
+ init_unistr( &info->datafile, "" );
- if (strlen(driver.info_3->configfile)) {
- slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
- init_unistr( &info->configfile, temp );
- } else
- init_unistr( &info->configfile, "" );
+ if (strlen(driver.info_3->configfile)) {
+ slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+ init_unistr( &info->configfile, temp );
+ } else
+ init_unistr( &info->configfile, "" );
- if (strlen(driver.info_3->helpfile)) {
- slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
- init_unistr( &info->helpfile, temp );
- } else
- init_unistr( &info->helpfile, "" );
+ if (strlen(driver.info_3->helpfile)) {
+ slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+ init_unistr( &info->helpfile, temp );
+ } else
+ init_unistr( &info->helpfile, "" );
init_unistr( &info->monitorname, driver.info_3->monitorname );
init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
@@ -5147,7 +4193,7 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst
WERROR status;
ZERO_STRUCT(driver);
- status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
+ status=get_a_printer(&printer, 2, lp_servicename(snum) );
DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
if (!W_ERROR_IS_OK(status))
return WERR_INVALID_PRINTER_NAME;
@@ -5239,8 +4285,8 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
init_unistr( &info->monitorname, driver.info_3->monitorname );
init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
- info->dependentfiles = NULL;
- init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
+ info->dependentfiles=NULL;
+ init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
info->previousdrivernames=NULL;
init_unistr_array(&info->previousdrivernames, &nullstr, servername);
@@ -5263,28 +4309,21 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
* fill a printer_info_6 struct
********************************************************************/
-static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
- fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- WERROR status;
-
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ NT_PRINTER_DRIVER_INFO_LEVEL driver;
+ WERROR status;
ZERO_STRUCT(driver);
- status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
-
+ status=get_a_printer(&printer, 2, lp_servicename(snum) );
DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
-
if (!W_ERROR_IS_OK(status))
return WERR_INVALID_PRINTER_NAME;
- status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
-
+ status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
-
- if (!W_ERROR_IS_OK(status))
- {
+ if (!W_ERROR_IS_OK(status)) {
/*
* Is this a W2k client ?
*/
@@ -5307,7 +4346,6 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
fill_printer_driver_info_6(info, driver, servername);
free_a_printer(&printer,2);
- free_a_printer_driver(driver, 3);
return WERR_OK;
}
@@ -5480,6 +4518,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
UNISTR2 *uni_arch = &q_u->architecture;
uint32 level = q_u->level;
uint32 clientmajorversion = q_u->clientmajorversion;
+/* uint32 clientminorversion = q_u->clientminorversion; - notused. */
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
@@ -5496,12 +4535,12 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
DEBUG(4,("_spoolss_getprinterdriver2\n"));
- *needed = 0;
- *servermajorversion = 0;
- *serverminorversion = 0;
+ *needed=0;
+ *servermajorversion=0;
+ *serverminorversion=0;
- fstrcpy(servername, get_called_name());
- unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
+ pstrcpy(servername, get_called_name());
+ unistr2_to_dos(architecture, uni_arch, sizeof(architecture)-1);
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
@@ -5544,7 +4583,6 @@ WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u,
WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
- int snum;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
@@ -5553,11 +4591,8 @@ WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO
return WERR_BADFID;
}
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
Printer->page_started=False;
- print_job_endpage(snum, Printer->jobid);
+ print_job_endpage(Printer->jobid);
return WERR_OK;
}
@@ -5571,6 +4606,7 @@ WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO
WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* uint32 level = q_u->doc_info_container.level; - notused. */
DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
uint32 *jobid = &r_u->jobid;
@@ -5594,10 +4630,14 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
* in EMF format.
*
* So I add checks like in NT Server ...
+ *
+ * lkclXXXX jean-francois, i love this kind of thing. oh, well,
+ * there's a bug in NT client-side code, so we'll fix it in the
+ * server-side code. *nnnnnggggh!*
*/
if (info_1->p_datatype != 0) {
- unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
+ unistr2_to_dos(datatype, &info_1->datatype, sizeof(datatype));
if (strcmp(datatype, "RAW") != 0) {
(*jobid)=0;
return WERR_INVALID_DATATYPE;
@@ -5609,9 +4649,9 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
return WERR_BADFID;
}
- unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
+ unistr2_to_dos(jobname, &info_1->docname, sizeof(jobname));
- Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode);
+ Printer->jobid = print_job_start(&user, snum, jobname);
/* An error occured in print_job_start() so return an appropriate
NT error code. */
@@ -5648,7 +4688,7 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
uint32 buffer_size = q_u->buffer_size;
uint8 *buffer = q_u->buffer;
uint32 *buffer_written = &q_u->buffer_size2;
- int snum;
+
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
@@ -5657,17 +4697,8 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
return WERR_BADFID;
}
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
+ (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
- (*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size);
- if (*buffer_written == -1) {
- r_u->buffer_written = 0;
- if (errno == ENOSPC)
- return WERR_NO_SPOOL_SPACE;
- else
- return WERR_ACCESS_DENIED;
- }
r_u->buffer_written = q_u->buffer_size2;
@@ -5724,31 +4755,13 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command,
/********************************************************************
* api_spoolss_abortprinter
- * From MSDN: "Deletes printer's spool file if printer is configured
- * for spooling"
********************************************************************/
WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- int snum;
- struct current_user user;
- WERROR errcode = WERR_OK;
-
- if (!Printer) {
- DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle)));
- return WERR_BADFID;
- }
-
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
- get_current_user( &user, p );
-
- print_job_delete( &user, snum, Printer->jobid, &errcode );
-
- return errcode;
+ POLICY_HND *handle = &q_u->handle;
+
+ return control_printer(handle, PRINTER_CONTROL_PURGE, p);
}
/********************************************************************
@@ -5862,8 +4875,7 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
fstrcpy(info->sharename, lp_servicename(snum));
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
get_called_name(), info->sharename);
- info->attributes = PRINTER_ATTRIBUTE_SAMBA;
-
+ info->attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;
return True;
}
@@ -5873,22 +4885,29 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
{
- extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
char **qlines;
pstring command;
+ pstring driverlocation;
int numlines;
int ret;
int fd;
fstring remote_machine = "%m";
- standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
+ /* build driver path... only 9X architecture is needed for legacy reasons */
+ slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
+ get_called_name());
+ /* change \ to \\ for the shell */
+ all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
+ standard_sub_basic(remote_machine,sizeof(remote_machine));
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
cmd, printer->info_2->printername, printer->info_2->sharename,
printer->info_2->portname, printer->info_2->drivername,
- printer->info_2->location, printer->info_2->comment, remote_machine);
+ printer->info_2->location, driverlocation, remote_machine);
+ /* Convert script args to unix-codepage */
+ dos_to_unix(command);
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, &fd);
DEBUGADD(10,("returned [%d]\n", ret));
@@ -5901,7 +4920,7 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
numlines = 0;
/* Get lines and convert them back to dos-codepage */
- qlines = fd_lines_load(fd, &numlines);
+ qlines = fd_lines_load(fd, &numlines, True);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
@@ -5921,6 +4940,254 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
return True;
}
+#if 0 /* JERRY */
+
+/* Return true if two devicemodes are equal */
+
+#define DEVMODE_CHECK_INT(field) \
+ if (d1->field != d2->field) { \
+ DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
+ d1->field, d2->field)); \
+ return False; \
+ }
+
+/************************************************************************
+ Handy, but currently unused functions
+ ***********************************************************************/
+
+static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
+{
+ if (!d1 && !d2) goto equal; /* if both are NULL they are equal */
+
+ if (!d1 ^ !d2) {
+ DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
+ return False; /* if either is exclusively NULL are not equal */
+ }
+
+ if (!strequal(d1->devicename, d2->devicename)) {
+ DEBUG(10, ("nt_devicemode_equal(): device not equal (%s != %s)\n", d1->devicename, d2->devicename));
+ return False;
+ }
+
+ if (!strequal(d1->formname, d2->formname)) {
+ DEBUG(10, ("nt_devicemode_equal(): formname not equal (%s != %s)\n", d1->formname, d2->formname));
+ return False;
+ }
+
+ DEVMODE_CHECK_INT(specversion);
+ DEVMODE_CHECK_INT(driverversion);
+ DEVMODE_CHECK_INT(driverextra);
+ DEVMODE_CHECK_INT(orientation);
+ DEVMODE_CHECK_INT(papersize);
+ DEVMODE_CHECK_INT(paperlength);
+ DEVMODE_CHECK_INT(paperwidth);
+ DEVMODE_CHECK_INT(scale);
+ DEVMODE_CHECK_INT(copies);
+ DEVMODE_CHECK_INT(defaultsource);
+ DEVMODE_CHECK_INT(printquality);
+ DEVMODE_CHECK_INT(color);
+ DEVMODE_CHECK_INT(duplex);
+ DEVMODE_CHECK_INT(yresolution);
+ DEVMODE_CHECK_INT(ttoption);
+ DEVMODE_CHECK_INT(collate);
+ DEVMODE_CHECK_INT(logpixels);
+
+ DEVMODE_CHECK_INT(fields);
+ DEVMODE_CHECK_INT(bitsperpel);
+ DEVMODE_CHECK_INT(pelswidth);
+ DEVMODE_CHECK_INT(pelsheight);
+ DEVMODE_CHECK_INT(displayflags);
+ DEVMODE_CHECK_INT(displayfrequency);
+ DEVMODE_CHECK_INT(icmmethod);
+ DEVMODE_CHECK_INT(icmintent);
+ DEVMODE_CHECK_INT(mediatype);
+ DEVMODE_CHECK_INT(dithertype);
+ DEVMODE_CHECK_INT(reserved1);
+ DEVMODE_CHECK_INT(reserved2);
+ DEVMODE_CHECK_INT(panningwidth);
+ DEVMODE_CHECK_INT(panningheight);
+
+ /* compare the private data if it exists */
+ if (!d1->driverextra && !d2->driverextra) goto equal;
+
+
+ DEVMODE_CHECK_INT(driverextra);
+
+ if (memcmp(d1->private, d2->private, d1->driverextra)) {
+ DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
+ return False;
+ }
+
+ equal:
+ DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
+ return True;
+}
+
+/* Return true if two NT_PRINTER_PARAM structures are equal */
+
+static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
+ NT_PRINTER_PARAM *p2)
+{
+ if (!p1 && !p2) goto equal;
+
+ if ((!p1 && p2) || (p1 && !p2)) {
+ DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
+ return False;
+ }
+
+ /* Compare lists of printer parameters */
+
+ while (p1) {
+ BOOL found = False;
+ NT_PRINTER_PARAM *q = p1;
+
+ /* Find the parameter in the second structure */
+
+ while(q) {
+
+ if (strequal(p1->value, q->value)) {
+
+ if (p1->type != q->type) {
+ DEBUG(10, ("nt_printer_param_equal():"
+ "types for %s differ (%d != %d)\n",
+ p1->value, p1->type,
+ q->type));
+ break;
+ }
+
+ if (p1->data_len != q->data_len) {
+ DEBUG(10, ("nt_printer_param_equal():"
+ "len for %s differs (%d != %d)\n",
+ p1->value, p1->data_len,
+ q->data_len));
+ break;
+ }
+
+ if (memcmp(p1->data, q->data, p1->data_len) == 0) {
+ found = True;
+ } else {
+ DEBUG(10, ("nt_printer_param_equal():"
+ "data for %s differs\n", p1->value));
+ }
+
+ break;
+ }
+
+ q = q->next;
+ }
+
+ if (!found) {
+ DEBUG(10, ("nt_printer_param_equal(): param %s "
+ "does not exist\n", p1->value));
+ return False;
+ }
+
+ p1 = p1->next;
+ }
+
+ equal:
+
+ DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
+ return True;
+}
+
+/********************************************************************
+ * Called by update_printer when trying to work out whether to
+ * actually update printer info.
+ ********************************************************************/
+
+#define PI_CHECK_INT(field) \
+ if (pi1->field != pi2->field) { \
+ DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
+ pi1->field, pi2->field)); \
+ return False; \
+ }
+
+#define PI_CHECK_STR(field) \
+ if (!strequal(pi1->field, pi2->field)) { \
+ DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
+ pi1->field, pi2->field)); \
+ return False; \
+ }
+
+static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
+ NT_PRINTER_INFO_LEVEL *p2)
+{
+ NT_PRINTER_INFO_LEVEL_2 *pi1, *pi2;
+
+ /* Trivial conditions */
+
+ if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
+ goto equal;
+ }
+
+ if ((!p1 && p2) || (p1 && !p2) ||
+ (!p1->info_2 && p2->info_2) ||
+ (p1->info_2 && !p2->info_2)) {
+ DEBUG(10, ("nt_printer_info_level_equal(): info levels "
+ "differ\n"));
+ return False;
+ }
+
+ /* Compare two nt_printer_info_level structures. Don't compare
+ status or cjobs as they seem to have something to do with the
+ printer queue. */
+
+ pi1 = p1->info_2;
+ pi2 = p2->info_2;
+
+ /* Don't check the attributes as we stomp on the value in
+ check_printer_ok() anyway. */
+
+#if 0
+ PI_CHECK_INT(attributes);
+#endif
+
+ PI_CHECK_INT(priority);
+ PI_CHECK_INT(default_priority);
+ PI_CHECK_INT(starttime);
+ PI_CHECK_INT(untiltime);
+ PI_CHECK_INT(averageppm);
+
+ /* Yuck - don't check the printername or servername as the
+ mod_a_printer() code plays games with them. You can't
+ change the printername or the sharename through this interface
+ in Samba. */
+
+ PI_CHECK_STR(sharename);
+ PI_CHECK_STR(portname);
+ PI_CHECK_STR(drivername);
+ PI_CHECK_STR(comment);
+ PI_CHECK_STR(location);
+
+ if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
+ return False;
+ }
+
+ PI_CHECK_STR(sepfile);
+ PI_CHECK_STR(printprocessor);
+ PI_CHECK_STR(datatype);
+ PI_CHECK_STR(parameters);
+
+ if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
+ return False;
+ }
+
+ if (!sec_desc_equal(pi1->secdesc_buf->sec, pi2->secdesc_buf->sec)) {
+ return False;
+ }
+
+ PI_CHECK_INT(changeid);
+ PI_CHECK_INT(c_setprinter);
+ PI_CHECK_INT(setuptime);
+
+ equal:
+ DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
+ return True;
+}
+
+#endif
+
/********************************************************************
* Called by spoolss_api_setprinter
* when updating a printer description.
@@ -5933,14 +5200,22 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
int snum;
NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ PRINTER_MESSAGE_INFO msg;
WERROR result;
- UNISTR2 buffer;
- fstring asc_buffer;
DEBUG(8,("update_printer\n"));
+ ZERO_STRUCT(msg);
+
result = WERR_OK;
+ if (level!=2) {
+ DEBUG(0,("update_printer: Send a mail to samba@samba.org\n"));
+ DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
+ result = WERR_UNKNOWN_LEVEL;
+ goto done;
+ }
+
if (!Printer) {
result = WERR_BADFID;
goto done;
@@ -5951,8 +5226,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
goto done;
}
- if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
- (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ||
+ (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) {
result = WERR_BADFID;
goto done;
}
@@ -5980,6 +5255,13 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
result = WERR_NOMEM;
goto done;
}
+
+ /*
+ * make sure we actually reload the services after
+ * this as smb.conf could have a new section in it
+ * .... shouldn't .... but could
+ */
+ reload_services(False);
}
/* Do sanity check on the requested changes for Samba */
@@ -5989,8 +5271,21 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
goto done;
}
- /* FIXME!!! If the driver has changed we really should verify that
- it is installed before doing much else --jerry */
+#if 0 /* JERRY */
+
+ /*
+ * Another one of those historical misunderstandings...
+ * This is reminisent of a similar call we had in _spoolss_setprinterdata()
+ * I'm leaving it here as a reminder. --jerry
+ */
+
+ if (nt_printer_info_level_equal(printer, old_printer)) {
+ DEBUG(3, ("update_printer: printer info has not changed\n"));
+ result = WERR_OK;
+ goto done;
+ }
+
+#endif
/* Check calling user has permission to update printer description */
@@ -6001,103 +5296,70 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
}
/* Call addprinter hook */
- /* Check changes to see if this is really needed */
-
- if ( *lp_addprinter_cmd()
- && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
- || !strequal(printer->info_2->comment, old_printer->info_2->comment)
- || !strequal(printer->info_2->portname, old_printer->info_2->portname)
- || !strequal(printer->info_2->location, old_printer->info_2->location)) )
- {
+
+ if (*lp_addprinter_cmd()) {
if ( !add_printer_hook(printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
-
- /*
- * make sure we actually reload the services after
- * this as smb.conf could have a new section in it
- * .... shouldn't .... but could
- */
- reload_services(False);
}
/*
- * When a *new* driver is bound to a printer, the drivername is used to
- * lookup previously saved driver initialization info, which is then
- * bound to the printer, simulating what happens in the Windows arch.
+ * Set the DRIVER_INIT info in the tdb; trigger on magic value for the
+ * DEVMODE.displayfrequency, which is not used for printer drivers. This
+ * requires Win32 client code (see other notes elsewhere in the code).
*/
- if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
- {
- if (!set_driver_init(printer, 2))
- {
- DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
- printer->info_2->drivername));
+ if (printer->info_2->devmode &&
+ printer->info_2->devmode->displayfrequency == MAGIC_DISPLAY_FREQUENCY) {
+
+ DEBUG(10,("update_printer: Save printer driver init data\n"));
+ printer->info_2->devmode->displayfrequency = 0;
+
+ if (update_driver_init(*printer, 2)!=0) {
+ DEBUG(10,("update_printer: error updating printer driver init DEVMODE\n"));
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
+ } else {
+ /*
+ * When a *new* driver is bound to a printer, the drivername is used to
+ * lookup previously saved driver initialization info, which is then
+ * bound to the printer, simulating what happens in the Windows arch.
+ */
+ if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
+ if (!set_driver_init(printer, 2)) {
+ DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
+ printer->info_2->drivername));
+ }
+ msg.flags |= PRINTER_MESSAGE_DRIVER;
}
-
- DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
- printer->info_2->drivername));
-
- notify_printer_driver(snum, printer->info_2->drivername);
}
- /*
- * flag which changes actually occured. This is a small subset of
- * all the possible changes. We also have to update things in the
- * DsSpooler key.
- */
-
- if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
- init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+ /* Update printer info */
+ result = mod_a_printer(*printer, 2);
- notify_printer_comment(snum, printer->info_2->comment);
- }
+ /* flag which changes actually occured. This is a small subset of
+ all the possible changes */
- if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
- init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+ if (!strequal(printer->info_2->comment, old_printer->info_2->comment))
+ msg.flags |= PRINTER_MESSAGE_COMMENT;
- notify_printer_sharename(snum, printer->info_2->sharename);
- }
+ if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename))
+ msg.flags |= PRINTER_MESSAGE_SHARENAME;
- if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
- init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+ if (!strequal(printer->info_2->portname, old_printer->info_2->portname))
+ msg.flags |= PRINTER_MESSAGE_PORT;
- notify_printer_port(snum, printer->info_2->portname);
- }
+ if (!strequal(printer->info_2->location, old_printer->info_2->location))
+ msg.flags |= PRINTER_MESSAGE_LOCATION;
- if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
- init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+ msg.low = PRINTER_CHANGE_ADD_PRINTER;
+ fstrcpy(msg.printer_name, printer->info_2->printername);
- notify_printer_location(snum, printer->info_2->location);
+ /* only send a notify if something changed */
+ if (msg.flags) {
+ srv_spoolss_sendnotify(msg.printer_name, 0, PRINTER_CHANGE_ADD_PRINTER, msg.flags);
}
-
- /* here we need to update some more DsSpooler keys */
- /* uNCName, serverName, shortServerName */
-
- init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
-
- slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
- global_myname(), printer->info_2->sharename );
- init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
- set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
- REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
-
- /* Update printer info */
- result = mod_a_printer(*printer, 2);
done:
free_a_printer(&printer, 2);
@@ -6109,31 +5371,6 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
- const SPOOL_PRINTER_INFO_LEVEL *info)
-{
-#ifdef HAVE_ADS
- SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
- int snum;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
-
- DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
-
- if (!Printer)
- return WERR_BADFID;
-
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
- nt_printer_publish(Printer, snum, info7->action);
-
- return WERR_OK;
-#else
- return WERR_UNKNOWN_LEVEL;
-#endif
-}
-/****************************************************************************
-****************************************************************************/
WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
{
@@ -6160,8 +5397,6 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
case 3:
return update_printer_sec(handle, level, info, p,
secdesc_ctr);
- case 7:
- return publish_or_unpublish_printer(p, handle, info);
default:
return WERR_UNKNOWN_LEVEL;
}
@@ -6173,6 +5408,7 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
{
POLICY_HND *handle = &q_u->handle;
+
Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
if (!Printer) {
@@ -6180,17 +5416,8 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
return WERR_BADFID;
}
- if (Printer->notify.client_connected==True) {
- int snum = -1;
-
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
- snum = -1;
- else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) &&
- !get_printer_snum(p, handle, &snum) )
- return WERR_BADFID;
-
- srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
- }
+ if (Printer->notify.client_connected==True)
+ srv_spoolss_replycloseprinter(&Printer->notify.client_hnd);
Printer->notify.flags=0;
Printer->notify.options=0;
@@ -6361,7 +5588,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
goto done;
}
- result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+ result = get_a_printer(&ntprinter, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result)) {
*returned = 0;
goto done;
@@ -6417,12 +5644,13 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* uint32 firstjob = q_u->firstjob; - notused. */
+/* uint32 numofjobs = q_u->numofjobs; - notused. */
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
- WERROR wret;
int snum;
print_status_struct prt_status;
@@ -6450,11 +5678,9 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
switch (level) {
case 1:
- wret = enumjobs_level1(queue, snum, buffer, offered, needed, returned);
- return wret;
+ return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
case 2:
- wret = enumjobs_level2(queue, snum, buffer, offered, needed, returned);
- return wret;
+ return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
default:
SAFE_FREE(queue);
*returned=0;
@@ -6477,6 +5703,8 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
{
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
+/* uint32 level = q_u->level; - notused. */
+/* JOB_INFO *ctr = &q_u->ctr; - notused. */
uint32 command = q_u->command;
struct current_user user;
@@ -6487,7 +5715,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
return WERR_BADFID;
}
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
return WERR_INVALID_PRINTER_NAME;
}
@@ -6496,18 +5724,18 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
switch (command) {
case JOB_CONTROL_CANCEL:
case JOB_CONTROL_DELETE:
- if (print_job_delete(&user, snum, jobid, &errcode)) {
+ if (print_job_delete(&user, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
case JOB_CONTROL_PAUSE:
- if (print_job_pause(&user, snum, jobid, &errcode)) {
+ if (print_job_pause(&user, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
case JOB_CONTROL_RESTART:
case JOB_CONTROL_RESUME:
- if (print_job_resume(&user, snum, jobid, &errcode)) {
+ if (print_job_resume(&user, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
@@ -6534,7 +5762,9 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6613,7 +5843,9 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6693,7 +5925,9 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
*returned=0;
- for (version=0; version<DRIVER_MAX_VERSION; version++) {
+#define MAX_VERSION 4
+
+ for (version=0; version<MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6766,6 +6000,7 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
UNISTR2 *environment = &q_u->environment;
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
@@ -6786,7 +6021,7 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
*needed=0;
*returned=0;
- unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
+ unistr2_to_dos(architecture, environment, sizeof(architecture)-1);
switch (level) {
case 1:
@@ -6822,6 +6057,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
{
+/* POLICY_HND *handle = &q_u->handle; - notused. */
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
@@ -6922,6 +6158,7 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
{
+/* POLICY_HND *handle = &q_u->handle; - notused. */
uint32 level = q_u->level;
UNISTR2 *uni_formname = &q_u->formname;
NEW_BUFFER *buffer = NULL;
@@ -6940,7 +6177,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
buffer = r_u->buffer;
- unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
+ unistr2_to_dos(form_name, uni_formname, sizeof(form_name)-1);
DEBUG(4,("_spoolss_getform\n"));
DEBUGADD(5,("Offered buffer size [%d]\n", offered));
@@ -7018,6 +6255,7 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
init_unistr(&port->port_name, name);
init_unistr(&port->monitor_name, "Local Monitor");
init_unistr(&port->description, "Local Port");
+#define PORT_TYPE_WRITE 1
port->port_type=PORT_TYPE_WRITE;
port->reserved=0x0;
}
@@ -7052,7 +6290,7 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
}
numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
+ qlines = fd_lines_load(fd, &numlines,True);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
@@ -7151,7 +6389,7 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
}
numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
+ qlines = fd_lines_load(fd, &numlines,True);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
@@ -7216,6 +6454,7 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
@@ -7276,9 +6515,6 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
free_a_printer(&printer, 2);
return WERR_PRINTER_ALREADY_EXISTS;
}
-
- /* FIXME!!! smbd should check to see if the driver is installed before
- trying to add a printer like this --jerry */
if (*lp_addprinter_cmd() ) {
if ( !add_printer_hook(printer) ) {
@@ -7318,11 +6554,8 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
*/
if (!devmode)
- {
set_driver_init(printer, 2);
- }
- else
- {
+ else {
/* A valid devmode was included, convert and link it
*/
DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
@@ -7332,6 +6565,8 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
return WERR_NOMEM;
}
+ set_driver_init(printer, 2);
+
/* write the ASCII on disk */
err = mod_a_printer(*printer, 2);
if (!W_ERROR_IS_OK(err)) {
@@ -7347,6 +6582,9 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
}
update_c_setprinter(False);
+
+ srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0);
+
free_a_printer(&printer,2);
return WERR_OK;
@@ -7385,6 +6623,7 @@ WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_
WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
{
+/* UNISTR2 *server_name = &q_u->server_name; - notused. */
uint32 level = q_u->level;
SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
WERROR err = WERR_OK;
@@ -7395,7 +6634,7 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
ZERO_STRUCT(driver);
- get_current_user(&user, p);
+ get_current_user(&user, p);
if (!convert_printer_driver_info(info, &driver, level)) {
err = WERR_NOMEM;
@@ -7422,14 +6661,14 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
/* BEGIN_ADMIN_LOG */
switch(level) {
case 3:
- fstrcpy(driver_name, driver.info_3->name ? driver.info_3->name : "");
sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver_name, get_drv_ver_to_os(driver.info_3->cversion),uidtoname(user.uid));
+ driver.info_3->name,drv_ver_to_os[driver.info_3->cversion],uidtoname(user.uid));
+ fstrcpy(driver_name, driver.info_3->name);
break;
case 6:
- fstrcpy(driver_name, driver.info_6->name ? driver.info_6->name : "");
sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
- driver_name, get_drv_ver_to_os(driver.info_6->version),uidtoname(user.uid));
+ driver.info_6->name,drv_ver_to_os[driver.info_6->version],uidtoname(user.uid));
+ fstrcpy(driver_name, driver.info_6->name);
break;
}
/* END_ADMIN_LOG */
@@ -7515,35 +6754,6 @@ done:
return err;
}
-/********************************************************************
- * spoolss_addprinterdriverex
- ********************************************************************/
-
-WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
-{
- SPOOL_Q_ADDPRINTERDRIVER q_u_local;
- SPOOL_R_ADDPRINTERDRIVER r_u_local;
-
- /*
- * we only support the semantics of AddPrinterDriver()
- * i.e. only copy files that are newer than existing ones
- */
-
- if ( q_u->copy_flags != APD_COPY_NEW_FILES )
- return WERR_ACCESS_DENIED;
-
- ZERO_STRUCT(q_u_local);
- ZERO_STRUCT(r_u_local);
-
- /* just pass the information off to _spoolss_addprinterdriver() */
- q_u_local.server_name_ptr = q_u->server_name_ptr;
- copy_unistr2(&q_u_local.server_name, &q_u->server_name);
- q_u_local.level = q_u->level;
- memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
-
- return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
-}
-
/****************************************************************************
****************************************************************************/
@@ -7559,12 +6769,12 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
{
pstring path;
pstring long_archi;
- const char *short_archi;
+ pstring short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
- unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
+ unistr2_to_dos(long_archi, uni_environment, sizeof(long_archi)-1);
- if (!(short_archi = get_short_archi(long_archi)))
+ if (get_short_archi(short_archi, long_archi)==False)
return WERR_INVALID_ENVIRONMENT;
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
@@ -7627,37 +6837,38 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
- uint32 idx = q_u->index;
- uint32 in_value_len = q_u->valuesize;
- uint32 in_data_len = q_u->datasize;
+ uint32 idx = q_u->index;
+ uint32 in_value_len = q_u->valuesize;
+ uint32 in_data_len = q_u->datasize;
uint32 *out_max_value_len = &r_u->valuesize;
- uint16 **out_value = &r_u->value;
- uint32 *out_value_len = &r_u->realvaluesize;
- uint32 *out_type = &r_u->type;
+ uint16 **out_value = &r_u->value;
+ uint32 *out_value_len = &r_u->realvaluesize;
+ uint32 *out_type = &r_u->type;
uint32 *out_max_data_len = &r_u->datasize;
- uint8 **data_out = &r_u->data;
- uint32 *out_data_len = &r_u->realdatasize;
+ uint8 **data_out = &r_u->data;
+ uint32 *out_data_len = &r_u->realdatasize;
NT_PRINTER_INFO_LEVEL *printer = NULL;
- uint32 biggest_valuesize;
- uint32 biggest_datasize;
- uint32 data_len;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- int snum;
- WERROR result;
- REGISTRY_VALUE *val = NULL;
- NT_PRINTER_DATA *p_data;
- int i, key_index, num_values;
- int name_length;
+ fstring value;
- ZERO_STRUCT( printer );
+ uint32 param_index;
+ uint32 biggest_valuesize;
+ uint32 biggest_datasize;
+ uint32 data_len;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum;
+ uint8 *data=NULL;
+ uint32 type;
+ WERROR result;
+
+ ZERO_STRUCT(printer);
- *out_type = 0;
+ *out_type=0;
- *out_max_data_len = 0;
- *data_out = NULL;
- *out_data_len = 0;
+ *out_max_data_len=0;
+ *data_out=NULL;
+ *out_data_len=0;
DEBUG(5,("spoolss_enumprinterdata\n"));
@@ -7669,136 +6880,106 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
- result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result))
return result;
-
- p_data = &printer->info_2->data;
- key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
-
- result = WERR_OK;
/*
* The NT machine wants to know the biggest size of value and data
*
* cf: MSDN EnumPrinterData remark section
*/
-
- if ( !in_value_len && !in_data_len && (key_index != -1) )
- {
+ if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- biggest_valuesize = 0;
- biggest_datasize = 0;
-
- num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
+ SAFE_FREE(data);
+
+ param_index=0;
+ biggest_valuesize=0;
+ biggest_datasize=0;
- for ( i=0; i<num_values; i++ )
- {
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
-
- name_length = strlen(val->valuename);
- if ( strlen(val->valuename) > biggest_valuesize )
- biggest_valuesize = name_length;
-
- if ( val->size > biggest_datasize )
- biggest_datasize = val->size;
-
- DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
- biggest_datasize));
+ while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len)) {
+ if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
+ if (data_len > biggest_datasize) biggest_datasize=data_len;
+
+ DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
+
+ SAFE_FREE(data);
+ param_index++;
}
- /* the value is an UNICODE string but real_value_size is the length
- in bytes including the trailing 0 */
-
- *out_value_len = 2 * (1+biggest_valuesize);
- *out_data_len = biggest_datasize;
+ /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
+ *out_value_len=2*(1+biggest_valuesize);
+ *out_data_len=biggest_datasize;
DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
- goto done;
+ free_a_printer(&printer, 2);
+ return WERR_OK;
}
/*
* the value len is wrong in NT sp3
* that's the number of bytes not the number of unicode chars
*/
-
- if ( key_index != -1 )
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx );
- if ( !val )
- {
+ if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
+
+ SAFE_FREE(data);
+ free_a_printer(&printer, 2);
/* out_value should default to "" or else NT4 has
problems unmarshalling the response */
*out_max_value_len=(in_value_len/sizeof(uint16));
-
if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
- {
- result = WERR_NOMEM;
- goto done;
- }
+ return WERR_NOMEM;
- *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
+ *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, "", in_value_len, True);
/* the data is counted in bytes */
-
*out_max_data_len = in_data_len;
- *out_data_len = in_data_len;
-
- /* only allocate when given a non-zero data_len */
-
- if ( in_data_len && ((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
- {
- result = WERR_NOMEM;
- goto done;
- }
+ *out_data_len = in_data_len;
+ if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
- result = WERR_NO_MORE_ITEMS;
+ return WERR_NO_MORE_ITEMS;
}
- else
- {
- /*
- * the value is:
- * - counted in bytes in the request
- * - counted in UNICODE chars in the max reply
- * - counted in bytes in the real size
- *
- * take a pause *before* coding not *during* coding
- */
+
+ free_a_printer(&printer, 2);
+
+ /*
+ * the value is:
+ * - counted in bytes in the request
+ * - counted in UNICODE chars in the max reply
+ * - counted in bytes in the real size
+ *
+ * take a pause *before* coding not *during* coding
+ */
- /* name */
- *out_max_value_len=(in_value_len/sizeof(uint16));
- if ( (*out_value = (uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
- {
- result = WERR_NOMEM;
- goto done;
- }
+ *out_max_value_len=(in_value_len/sizeof(uint16));
+ if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
+ SAFE_FREE(data);
+ return WERR_NOMEM;
+ }
- *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), in_value_len, 0);
+ *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
- /* type */
-
- *out_type = regval_type( val );
-
- /* data - counted in bytes */
+ *out_type=type;
- *out_max_data_len = in_data_len;
- if ( (*data_out = (uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
- {
- result = WERR_NOMEM;
- goto done;
- }
- data_len = (size_t)regval_size(val);
- memcpy( *data_out, regval_data_p(val), data_len );
- *out_data_len = data_len;
+ /* the data is counted in bytes */
+ *out_max_data_len=in_data_len;
+ if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
+ SAFE_FREE(data);
+ return WERR_NOMEM;
}
+
+ memcpy(*data_out, data, (size_t)data_len);
+ *out_data_len=data_len;
-done:
- free_a_printer(&printer, 2);
- return result;
+ SAFE_FREE(data);
+
+ return WERR_OK;
}
/****************************************************************************
@@ -7806,17 +6987,19 @@ done:
WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->value;
- uint32 type = q_u->type;
- uint8 *data = q_u->data;
- uint32 real_len = q_u->real_len;
+ POLICY_HND *handle = &q_u->handle;
+ UNISTR2 *value = &q_u->value;
+ uint32 type = q_u->type;
+/* uint32 max_len = q_u->max_len; - notused. */
+ uint8 *data = q_u->data;
+ uint32 real_len = q_u->real_len;
+/* uint32 numeric_data = q_u->numeric_data; - notused. */
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- fstring valuename;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ NT_PRINTER_PARAM *param = NULL, old_param;
+ int snum=0;
+ WERROR status = WERR_OK;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
DEBUG(5,("spoolss_setprinterdata\n"));
@@ -7825,14 +7008,11 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
return WERR_BADFID;
}
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
- DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
- return WERR_INVALID_PARAM;
- }
-
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
+ ZERO_STRUCT(old_param);
+
/*
* Access check : NT returns "access denied" if you make a
* SetPrinterData call without the necessary privildge.
@@ -7841,41 +7021,46 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
* when connecting to a printer --jerry
*/
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
- {
+ if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
status = WERR_ACCESS_DENIED;
goto done;
}
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ /* Check if we are making any changes or not. Return true if
+ nothing is actually changing. This is not needed anymore but
+ has been left in as an optimization to keep from from
+ writing to disk as often --jerry */
+
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
return status;
- unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
+ convert_specific_param(&param, value , type, data, real_len);
+
+ unlink_specific_param_if_exist(printer->info_2, param);
/*
* When client side code sets a magic printer data key, detect it and save
* the current printer data and the magic key's data (its the DEVMODE) for
* future printer/driver initializations.
*/
- if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
- {
- /* Set devmode and printer initialization info */
- status = save_driver_init( printer, 2, data, real_len );
-
- srv_spoolss_reset_printerdata( printer->info_2->drivername );
+ if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
+ /*
+ * Set devmode and printer initialization info
+ */
+ status = save_driver_init(printer, 2, param);
}
- else
- {
- status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
- type, data, real_len );
- if ( W_ERROR_IS_OK(status) )
- status = mod_a_printer(*printer, 2);
+ else {
+ add_a_specific_param(printer->info_2, &param);
+ status = mod_a_printer(*printer, 2);
}
-done:
+ done:
free_a_printer(&printer, 2);
+ if (param)
+ free_nt_printer_param(&param);
+ SAFE_FREE(old_param.data);
return status;
}
@@ -7885,9 +7070,9 @@ done:
WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- int snum;
+ POLICY_HND *handle = &q_u->handle;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+ int snum;
DEBUG(5,("_spoolss_resetprinter\n"));
@@ -7911,19 +7096,16 @@ WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R
}
-/****************************************************************************
-****************************************************************************/
-
WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->valuename;
+ POLICY_HND *handle = &q_u->handle;
+ UNISTR2 *value = &q_u->valuename;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- pstring valuename;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ NT_PRINTER_PARAM param;
+ int snum=0;
+ WERROR status = WERR_OK;
+ Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
DEBUG(5,("spoolss_deleteprinterdata\n"));
@@ -7940,19 +7122,19 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
return WERR_ACCESS_DENIED;
}
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
return status;
- unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
+ ZERO_STRUCTP(&param);
+ unistr2_to_dos(param.value, value, sizeof(param.value)-1);
- status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
-
- if ( W_ERROR_IS_OK(status) )
- mod_a_printer( *printer, 2 );
+ if(!unlink_specific_param_if_exist(printer->info_2, &param))
+ status = WERR_INVALID_PARAM;
+ else
+ status = mod_a_printer(*printer, 2);
free_a_printer(&printer, 2);
-
return status;
}
@@ -7962,6 +7144,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
int snum;
@@ -7987,7 +7170,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
goto done;
}
@@ -8058,7 +7241,7 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
goto done;
}
@@ -8102,6 +7285,8 @@ done:
WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
+/* UNISTR2 *uni_name = &q_u->name; - notused. */
+/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
int snum;
@@ -8126,7 +7311,7 @@ WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(status))
goto done;
}
@@ -8200,10 +7385,12 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
+/* UNISTR2 *environment = &q_u->environment; - notused. */
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
+ uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
@@ -8267,6 +7454,8 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
+/* UNISTR2 *processor = &q_u->processor; - notused. */
uint32 level = q_u->level;
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
@@ -8361,10 +7550,11 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
{
+/* UNISTR2 *name = &q_u->name; - notused. */
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
- uint32 *needed = &r_u->needed;
+ uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
@@ -8396,7 +7586,7 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
int i=0;
BOOL found=False;
@@ -8405,21 +7595,25 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, ui
info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
if (info_1 == NULL) {
+ SAFE_FREE(queue);
return WERR_NOMEM;
}
- for (i=0; i<count && found==False; i++) {
- if ((*queue)[i].job==(int)jobid)
+ for (i=0; i<count && found==False; i++) {
+ if (queue[i].job==(int)jobid)
found=True;
}
if (found==False) {
+ SAFE_FREE(queue);
SAFE_FREE(info_1);
/* NT treats not found as bad param... yet another bad choice */
return WERR_INVALID_PARAM;
}
- fill_job_info_1(info_1, &((*queue)[i-1]), i, snum);
+ fill_job_info_1(info_1, &(queue[i-1]), i, snum);
+
+ SAFE_FREE(queue);
*needed += spoolss_size_job_info_1(info_1);
@@ -8441,15 +7635,14 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, ui
/****************************************************************************
****************************************************************************/
-static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
- int i = 0;
- BOOL found = False;
- JOB_INFO_2 *info_2;
+ int i=0;
+ BOOL found=False;
+ JOB_INFO_2 *info_2;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- WERROR ret;
- DEVICEMODE *devmode = NULL;
- NT_DEVICEMODE *nt_devmode = NULL;
+ WERROR ret;
+ DEVICEMODE *devmode = NULL;
info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
@@ -8460,40 +7653,27 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, ui
goto done;
}
- for ( i=0; i<count && found==False; i++ )
- {
- if ((*queue)[i].job == (int)jobid)
- found = True;
+ for (i=0; i<count && found==False; i++) {
+ if (queue[i].job==(int)jobid)
+ found=True;
}
- if ( !found )
- {
+ if (found==False) {
/* NT treats not found as bad param... yet another bad
choice */
ret = WERR_INVALID_PARAM;
goto done;
}
- ret = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+ ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(ret))
goto done;
+
+ /* not a failure condition if devmode == NULL */
- /*
- * if the print job does not have a DEVMODE associated with it,
- * just use the one for the printer. A NULL devicemode is not
- * a failure condition
- */
-
- if ( !(nt_devmode=print_job_devmode( snum, jobid )) )
- devmode = construct_dev_mode(snum);
- else {
- if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) != NULL) {
- ZERO_STRUCTP( devmode );
- convert_nt_devicemode( devmode, nt_devmode );
- }
- }
-
- fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
+ construct_dev_mode(snum);
+
+ fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter, devmode);
*needed += spoolss_size_job_info_2(info_2);
@@ -8514,6 +7694,7 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, ui
done:
/* Cleanup allocated memory */
+ SAFE_FREE(queue);
free_job_info_2(info_2); /* Also frees devmode */
SAFE_FREE(info_2);
free_a_printer(&ntprinter, 2);
@@ -8532,11 +7713,10 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
- WERROR wstatus = WERR_OK;
int snum;
int count;
- print_queue_struct *queue = NULL;
+ print_queue_struct *queue=NULL;
print_status_struct prt_status;
/* that's an [in out] buffer */
@@ -8545,7 +7725,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
DEBUG(5,("spoolss_getjob\n"));
- *needed = 0;
+ *needed=0;
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
@@ -8555,29 +7735,19 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
count, prt_status.status, prt_status.message));
- switch ( level ) {
+ switch (level) {
case 1:
- wstatus = getjob_level_1(&queue, count, snum, jobid,
- buffer, offered, needed);
- break;
+ return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
case 2:
- wstatus = getjob_level_2(&queue, count, snum, jobid,
- buffer, offered, needed);
- break;
+ return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
default:
- wstatus = WERR_UNKNOWN_LEVEL;
- break;
+ SAFE_FREE(queue);
+ return WERR_UNKNOWN_LEVEL;
}
-
- SAFE_FREE(queue);
- return wstatus;
}
/********************************************************************
- spoolss_getprinterdataex
-
- From MSDN documentation of GetPrinterDataEx: pass request
- to GetPrinterData if key is "PrinterDriverData".
+ * spoolss_getprinterdataex
********************************************************************/
WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
@@ -8588,363 +7758,178 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
uint32 *out_size = &r_u->size;
uint8 **data = &r_u->data;
uint32 *needed = &r_u->needed;
- fstring keyname, valuename;
-
+
+ fstring key, value;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
-
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum = 0;
- WERROR status = WERR_OK;
+ BOOL found = False;
DEBUG(4,("_spoolss_getprinterdataex\n"));
- unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname) - 1);
- unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename) - 1);
-
- DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
- keyname, valuename));
+ unistr2_to_dos(key, &q_u->keyname, sizeof(key) - 1);
+ unistr2_to_dos(value, &q_u->valuename, sizeof(value) - 1);
/* in case of problem, return some default values */
-
- *needed = 0;
- *type = 0;
- *out_size = in_size;
+ *needed=0;
+ *type=0;
+ *out_size=0;
+
if (!Printer) {
- DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- status = WERR_BADFID;
- goto done;
+ if((*data=(uint8 *)talloc_zero(p->mem_ctx, 4*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
+ DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
+
/* Is the handle to a printer or to the server? */
- if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
- DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
- status = WERR_INVALID_PARAM;
- goto done;
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ {
+ DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
+ return WERR_INVALID_PARAM;
}
-
- if ( !get_printer_snum(p,handle, &snum) )
- return WERR_BADFID;
-
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if ( !W_ERROR_IS_OK(status) )
- goto done;
+ else
+ {
+ /*
+ * From MSDN documentation of GetPrinterDataEx: pass request
+ * to GetPrinterData if key is "PrinterDriverData". This is
+ * the only key we really support. Other keys to implement:
+ * (a) DsDriver
+ * (b) DsSpooler
+ * (c) PnPData
+ */
+
+ if (strcmp(key, "PrinterDriverData") != 0)
+ return WERR_BADFILE;
- /* check to see if the keyname is valid */
- if ( !strlen(keyname) ) {
- status = WERR_INVALID_PARAM;
- goto done;
- }
-
- if ( lookup_printerkey( &printer->info_2->data, keyname ) == -1 ) {
- DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
- free_a_printer( &printer, 2 );
- status = WERR_BADFILE;
- goto done;
+ DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
+ found = getprinterdata_printer(p, p->mem_ctx, handle, value,
+ type, data, needed, in_size);
+
}
-
- /* When given a new keyname, we should just create it */
-
- status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
-
- if (*needed > *out_size)
- status = WERR_MORE_DATA;
-
-done:
- if ( !W_ERROR_IS_OK(status) )
- {
- DEBUG(5, ("error: allocating %d\n", *out_size));
+
+ if (!found) {
+ DEBUG(5, ("value not found, allocating %d\n", *out_size));
/* reply this param doesn't exist */
-
- if ( *out_size )
- {
- if( (*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
- status = WERR_NOMEM;
- goto done;
- }
- }
- else {
+ if (*out_size) {
+ if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
+ } else {
*data = NULL;
- }
+ }
+
+ return WERR_INVALID_PARAM;
}
- if ( printer )
- free_a_printer( &printer, 2 );
-
- return status;
+ if (*needed > *out_size)
+ return WERR_MORE_DATA;
+ else
+ return WERR_OK;
}
/********************************************************************
- * spoolss_setprinterdataex
+ * spoolss_setprinterdata
********************************************************************/
WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 type = q_u->type;
- uint8 *data = q_u->data;
- uint32 real_len = q_u->real_len;
+ SPOOL_Q_SETPRINTERDATA q_u_local;
+ SPOOL_R_SETPRINTERDATA r_u_local;
+ fstring key;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum = 0;
- WERROR status = WERR_OK;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- fstring valuename;
- fstring keyname;
- char *oid_string;
-
DEBUG(4,("_spoolss_setprinterdataex\n"));
/* From MSDN documentation of SetPrinterDataEx: pass request to
SetPrinterData if key is "PrinterDriverData" */
- if (!Printer) {
- DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- return WERR_BADFID;
- }
-
- if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
- DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
- return WERR_INVALID_PARAM;
- }
-
- if ( !get_printer_snum(p,handle, &snum) )
- return WERR_BADFID;
-
- /*
- * Access check : NT returns "access denied" if you make a
- * SetPrinterData call without the necessary privildge.
- * we were originally returning OK if nothing changed
- * which made Win2k issue **a lot** of SetPrinterData
- * when connecting to a printer --jerry
- */
-
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
- {
- DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
- return WERR_ACCESS_DENIED;
- }
-
- status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
+ unistr2_to_dos(key, &q_u->key, sizeof(key) - 1);
- unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename) - 1);
- unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname) - 1);
-
- /* check for OID in valuename */
-
- if ( (oid_string = strchr( valuename, ',' )) != NULL )
- {
- *oid_string = '\0';
- oid_string++;
- }
-
- /* save the registry data */
-
- status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
-
- if ( W_ERROR_IS_OK(status) )
- {
- /* save the OID if one was specified */
- if ( oid_string ) {
- fstrcat( keyname, "\\" );
- fstrcat( keyname, SPOOL_OID_KEY );
+ if (strcmp(key, "PrinterDriverData") != 0)
+ return WERR_INVALID_PARAM;
- /*
- * I'm not checking the status here on purpose. Don't know
- * if this is right, but I'm returning the status from the
- * previous set_printer_dataex() call. I have no idea if
- * this is right. --jerry
- */
-
- set_printer_dataex( printer, keyname, valuename,
- REG_SZ, (void*)oid_string, strlen(oid_string)+1 );
- }
-
- status = mod_a_printer(*printer, 2);
- }
+ ZERO_STRUCT(q_u_local);
+ ZERO_STRUCT(r_u_local);
+
+ /* make a copy to call _spoolss_setprinterdata() */
+
+ memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
+ copy_unistr2(&q_u_local.value, &q_u->value);
+ q_u_local.type = q_u->type;
+ q_u_local.max_len = q_u->max_len;
+ q_u_local.data = q_u->data;
+ q_u_local.real_len = q_u->real_len;
+ q_u_local.numeric_data = q_u->numeric_data;
- free_a_printer(&printer, 2);
-
- return status;
-}
-
-
-/********************************************************************
- * spoolss_deleteprinterdataex
- ********************************************************************/
-
-WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u)
-{
- POLICY_HND *handle = &q_u->handle;
- UNISTR2 *value = &q_u->valuename;
- UNISTR2 *key = &q_u->keyname;
-
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- WERROR status = WERR_OK;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- pstring valuename, keyname;
-
- DEBUG(5,("spoolss_deleteprinterdataex\n"));
-
- if (!Printer) {
- DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- return WERR_BADFID;
- }
-
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
- DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
- return WERR_ACCESS_DENIED;
- }
-
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
-
- unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
- unistr2_to_ascii( keyname, key, sizeof(keyname)-1 );
-
- status = delete_printer_dataex( printer, keyname, valuename );
-
- if ( W_ERROR_IS_OK(status) )
- mod_a_printer( *printer, 2 );
-
- free_a_printer(&printer, 2);
-
- return status;
+ return _spoolss_setprinterdata(p, &q_u_local, &r_u_local);
}
/********************************************************************
* spoolss_enumprinterkey
********************************************************************/
+/* constants for EnumPrinterKey() */
+#define ENUMERATED_KEY_SIZE 19
WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
{
- fstring key;
- fstring *keynames = NULL;
- uint16 *enumkeys = NULL;
- int num_keys;
- int printerkey_len;
- POLICY_HND *handle = &q_u->handle;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- NT_PRINTER_DATA *data;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum = 0;
- WERROR status = WERR_BADFILE;
-
-
- DEBUG(4,("_spoolss_enumprinterkey\n"));
-
- if (!Printer) {
- DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- return WERR_BADFID;
- }
+ fstring key;
+ uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
+ fstring PrinterKey;
+ UNISTR2 uni_keys;
+ int enum_key_len;
- if ( !get_printer_snum(p,handle, &snum) )
- return WERR_BADFID;
-
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
-
- /* get the list of subkey names */
-
- unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
- data = &printer->info_2->data;
+ DEBUG(4,("_spoolss_enumprinterkey\n"));
- num_keys = get_printer_subkeys( data, key, &keynames );
+ unistr2_to_dos(key, &q_u->key, sizeof(key) - 1);
- if ( num_keys == -1 ) {
- status = WERR_BADFILE;
- goto done;
- }
+ ZERO_STRUCTP(PrinterKey);
+ fstrcpy( PrinterKey, "PrinterDriverData" );
- printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
+ /* add space for 2 terminating NULLs */
- r_u->needed = printerkey_len*2;
+ enum_key_len = strlen( PrinterKey ) + 2;
- if ( q_u->size < r_u->needed ) {
- status = WERR_MORE_DATA;
- goto done;
- }
- if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
- status = WERR_NOMEM;
- goto done;
- }
-
- status = WERR_OK;
-
- if ( q_u->size < r_u->needed )
- status = WERR_MORE_DATA;
-
-done:
- free_a_printer( &printer, 2 );
- SAFE_FREE( keynames );
+ /*
+ * we only support enumating all keys (key == "")
+ * Of course, the only key we support is the "PrinterDriverData"
+ * key
+ */
+ if (strlen(key) == 0)
+ {
+ r_u->needed = enum_key_len*2;
+ if (q_u->size < r_u->needed)
+ return WERR_MORE_DATA;
- return status;
-}
-
-/********************************************************************
- * spoolss_deleteprinterkey
- ********************************************************************/
+ init_unistr2( &uni_keys, PrinterKey, enum_key_len );
-WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u)
-{
- POLICY_HND *handle = &q_u->handle;
- Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
- fstring key;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- WERROR status;
-
- DEBUG(5,("spoolss_deleteprinterkey\n"));
-
- if (!Printer) {
- DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
- return WERR_BADFID;
+ if ( !make_spoolss_buffer5(p->mem_ctx, &r_u->keys, enum_key_len, uni_keys.buffer) )
+ return WERR_BADFILE;
+
+ return WERR_OK;
}
-
- /* if keyname == NULL, return error */
- if ( !q_u->keyname.buffer )
- return WERR_INVALID_PARAM;
-
- if (!get_printer_snum(p, handle, &snum))
- return WERR_BADFID;
-
- if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
- DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
- return WERR_ACCESS_DENIED;
+ /* The "PrinterDriverData" key should have no subkeys */
+ if (strcmp(key, PrinterKey) == 0)
+ {
+ r_u-> needed = 2;
+ if (q_u->size < r_u->needed)
+ return WERR_MORE_DATA;
+ enumkeys[0] = 0x0;
+ if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, enumkeys))
+ return WERR_BADFILE;
+
+ return WERR_OK;
}
-
- status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
- return status;
-
- /* delete the key and all subneys */
- unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
-
- status = delete_all_printer_data( printer->info_2, key );
- if ( W_ERROR_IS_OK(status) )
- status = mod_a_printer(*printer, 2);
-
- free_a_printer( &printer, 2 );
-
- return status;
+ /* The return value for an unknown key is documented in MSDN
+ EnumPrinterKey description */
+ return WERR_BADFILE;
}
-
/********************************************************************
* spoolss_enumprinterdataex
********************************************************************/
@@ -8957,119 +7942,100 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
needed;
NT_PRINTER_INFO_LEVEL *printer = NULL;
PRINTER_ENUM_VALUES *enum_values = NULL;
- NT_PRINTER_DATA *p_data;
- fstring key;
+ fstring key, value;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
int snum;
+ uint32 param_index,
+ data_len,
+ type;
WERROR result;
- int key_index;
- int i;
- REGISTRY_VALUE *val;
- char *value_name;
- int data_len;
+ uint8 *data=NULL;
DEBUG(4,("_spoolss_enumprinterdataex\n"));
if (!Printer) {
- DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
- /*
- * first check for a keyname of NULL or "". Win2k seems to send
- * this a lot and we should send back WERR_INVALID_PARAM
- * no need to spend time looking up the printer in this case.
- * --jerry
+
+ /*
+ * The only key we support is "PrinterDriverData". This should return
+ > an array of all the key/value pairs returned by EnumPrinterDataSee
+ * _spoolss_getprinterdataex() for details --jerry
*/
-
- unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
- if ( !strlen(key) ) {
- result = WERR_INVALID_PARAM;
- goto done;
+
+ unistr2_to_dos(key, &q_u->key, sizeof(key) - 1);
+ if (strcmp(key, "PrinterDriverData") != 0)
+ {
+ DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
+ return WERR_INVALID_PARAM;
}
- /* get the printer off of disk */
-
+
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
ZERO_STRUCT(printer);
- result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(result))
return result;
+
- /* now look for a match on the key name */
-
- p_data = &printer->info_2->data;
-
- unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
- if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
- {
- DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
- result = WERR_INVALID_PARAM;
- goto done;
- }
-
+ /*
+ * loop through all params and build the array to pass
+ * back to the client
+ */
result = WERR_OK;
- needed = 0;
-
- /* allocate the memory for the array of pointers -- if necessary */
+ param_index = 0;
+ needed = 0;
+ num_entries = 0;
- num_entries = regval_ctr_numvals( &p_data->keys[key_index].values );
- if ( num_entries )
+ while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len))
{
- if ( (enum_values=talloc(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL )
+ PRINTER_ENUM_VALUES *ptr;
+
+ DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries, value));
+
+ if ((ptr=talloc_realloc(p->mem_ctx, enum_values, (num_entries+1) * sizeof(PRINTER_ENUM_VALUES))) == NULL)
{
- DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
- (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
+ DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
result = WERR_NOMEM;
goto done;
}
-
- memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
- }
-
- /*
- * loop through all params and build the array to pass
- * back to the client
- */
-
- for ( i=0; i<num_entries; i++ )
- {
- /* lookup the registry value */
+ enum_values = ptr;
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
- DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
+ ZERO_STRUCTP( &enum_values[num_entries] );
/* copy the data */
- value_name = regval_name( val );
- init_unistr( &enum_values[i].valuename, value_name );
- enum_values[i].value_len = (strlen(value_name)+1) * 2;
- enum_values[i].type = regval_type( val );
+ init_unistr(&enum_values[num_entries].valuename, value);
+ enum_values[num_entries].value_len = (strlen(value)+1) * 2;
+ enum_values[num_entries].type = type;
- data_len = regval_size( val );
- if ( data_len ) {
- if ( !(enum_values[i].data = talloc_memdup(p->mem_ctx, regval_data_p(val), data_len)) )
- {
- DEBUG(0,("talloc_memdup failed to allocate memory [data_len=%d] for data!\n",
- data_len ));
+ if ( data_len )
+ {
+ if ( !(enum_values[num_entries].data = talloc_zero(p->mem_ctx, data_len)) ) {
+ DEBUG(0,("talloc_realloc failed to allocate more memory [data_len=%d] for data!\n", data_len ));
result = WERR_NOMEM;
goto done;
}
+ memcpy(enum_values[num_entries].data, data, data_len);
}
- enum_values[i].data_len = data_len;
+
+ enum_values[num_entries].data_len = data_len;
/* keep track of the size of the array in bytes */
- needed += spoolss_size_printer_enum_values(&enum_values[i]);
+ needed += spoolss_size_printer_enum_values(&enum_values[num_entries]);
+
+ num_entries++;
+ param_index++;
}
- /* housekeeping information in the reply */
-
- r_u->needed = needed;
- r_u->returned = num_entries;
+ r_u->needed = needed;
+ r_u->returned = num_entries;
if (needed > in_size) {
result = WERR_MORE_DATA;
@@ -9085,7 +8051,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
done:
- if ( printer )
free_a_printer(&printer, 2);
return result;
@@ -9107,11 +8072,12 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
{
pstring path;
pstring long_archi;
+ pstring short_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
- unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
+ unistr2_to_dos(long_archi, environment, sizeof(long_archi)-1);
- if (!get_short_archi(long_archi))
+ if (get_short_archi(short_archi, long_archi)==False)
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
@@ -9166,23 +8132,3 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
return result;
}
-#if 0
-
-WERROR _spoolss_replyopenprinter(pipes_struct *p, SPOOL_Q_REPLYOPENPRINTER *q_u,
- SPOOL_R_REPLYOPENPRINTER *r_u)
-{
- DEBUG(5,("_spoolss_replyopenprinter\n"));
-
- DEBUG(10, ("replyopenprinter for localprinter %d\n", q_u->printer));
-
- return WERR_OK;
-}
-
-WERROR _spoolss_replycloseprinter(pipes_struct *p, SPOOL_Q_REPLYCLOSEPRINTER *q_u,
- SPOOL_R_REPLYCLOSEPRINTER *r_u)
-{
- DEBUG(5,("_spoolss_replycloseprinter\n"));
- return WERR_OK;
-}
-
-#endif
diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c
index 9d85088e568..35bacc3458d 100644
--- a/source/rpc_server/srv_srvsvc.c
+++ b/source/rpc_server/srv_srvsvc.c
@@ -1,11 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Jeremy Allison 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*******************************************************************
api_srv_net_srv_get_info
********************************************************************/
@@ -346,36 +343,6 @@ static BOOL api_srv_net_share_del(pipes_struct *p)
}
/*******************************************************************
- RPC to delete share information.
-********************************************************************/
-
-static BOOL api_srv_net_share_del_sticky(pipes_struct *p)
-{
- SRV_Q_NET_SHARE_DEL q_u;
- SRV_R_NET_SHARE_DEL r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* Unmarshall the net server del info. */
- if(!srv_io_q_net_share_del("", &q_u, data, 0)) {
- DEBUG(0,("api_srv_net_share_del_sticky: Failed to unmarshall SRV_Q_NET_SHARE_DEL.\n"));
- return False;
- }
-
- r_u.status = _srv_net_share_del_sticky(p, &q_u, &r_u);
-
- if(!srv_io_r_net_share_del("", &r_u, rdata, 0)) {
- DEBUG(0,("api_srv_net_share_del_sticky: Failed to marshall SRV_R_NET_SHARE_DEL.\n"));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
api_srv_net_remote_tod
********************************************************************/
@@ -526,36 +493,31 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p)
\PIPE\srvsvc commands
********************************************************************/
-static struct api_struct api_srv_cmds[] =
+struct api_struct api_srv_cmds[] =
{
- { "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum },
- { "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum },
- { "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all },
- { "SRV_NET_SHARE_ENUM" , SRV_NET_SHARE_ENUM , api_srv_net_share_enum },
- { "SRV_NET_SHARE_ADD" , SRV_NET_SHARE_ADD , api_srv_net_share_add },
- { "SRV_NET_SHARE_DEL" , SRV_NET_SHARE_DEL , api_srv_net_share_del },
- { "SRV_NET_SHARE_DEL_STICKY" , SRV_NET_SHARE_DEL_STICKY , api_srv_net_share_del_sticky },
- { "SRV_NET_SHARE_GET_INFO" , SRV_NET_SHARE_GET_INFO , api_srv_net_share_get_info },
- { "SRV_NET_SHARE_SET_INFO" , SRV_NET_SHARE_SET_INFO , api_srv_net_share_set_info },
- { "SRV_NET_FILE_ENUM" , SRV_NET_FILE_ENUM , api_srv_net_file_enum },
- { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info },
- { "SRV_NET_SRV_SET_INFO" , SRV_NET_SRV_SET_INFO , api_srv_net_srv_set_info },
- { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
- { "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum },
- { "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate },
- { "SRV_NET_FILE_QUERY_SECDESC", SRV_NET_FILE_QUERY_SECDESC, api_srv_net_file_query_secdesc },
- { "SRV_NET_FILE_SET_SECDESC" , SRV_NET_FILE_SET_SECDESC , api_srv_net_file_set_secdesc }
+ { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
+ { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
+ { "SRV_NETSHAREENUM_ALL" , SRV_NETSHAREENUM_ALL , api_srv_net_share_enum_all },
+ { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
+ { "SRV_NET_SHARE_ADD" , SRV_NET_SHARE_ADD , api_srv_net_share_add },
+ { "SRV_NET_SHARE_DEL" , SRV_NET_SHARE_DEL , api_srv_net_share_del },
+ { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info },
+ { "SRV_NET_SHARE_SET_INFO", SRV_NET_SHARE_SET_INFO, api_srv_net_share_set_info },
+ { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
+ { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info },
+ { "SRV_NET_SRV_SET_INFO" , SRV_NET_SRV_SET_INFO , api_srv_net_srv_set_info },
+ { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
+ { "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum },
+ { "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate},
+ { "SRV_NETFILEQUERYSECDESC",SRV_NETFILEQUERYSECDESC,api_srv_net_file_query_secdesc},
+ { "SRV_NETFILESETSECDESC" , SRV_NETFILESETSECDESC , api_srv_net_file_set_secdesc},
+ { NULL , 0 , NULL }
};
-void srvsvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_srv_cmds;
- *n_fns = sizeof(api_srv_cmds) / sizeof(struct api_struct);
-}
-
-
-NTSTATUS rpc_srv_init(void)
+/*******************************************************************
+receives a srvsvc pipe and responds.
+********************************************************************/
+BOOL api_srvsvc_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "srvsvc", "ntsvcs", api_srv_cmds,
- sizeof(api_srv_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds);
}
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index 9d56e1b3858..33b6076afd2 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -1,9 +1,11 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 2001.
- * Copyright (C) Nigel Williams 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,43 +26,7 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/*******************************************************************
- Utility function to get the 'type' of a share from an snum.
- ********************************************************************/
-static uint32 get_share_type(int snum)
-{
- char *net_name = lp_servicename(snum);
- int len_net_name = strlen(net_name);
-
- /* work out the share type */
- uint32 type = STYPE_DISKTREE;
-
- if (lp_print_ok(snum))
- type = STYPE_PRINTQ;
- if (strequal(lp_fstype(snum), "IPC"))
- type = STYPE_IPC;
- if (net_name[len_net_name] == '$')
- type |= STYPE_HIDDEN;
-
- return type;
-}
-
-/*******************************************************************
- Fill in a share info level 0 structure.
- ********************************************************************/
-
-static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
-{
- pstring net_name;
-
- pstrcpy(net_name, lp_servicename(snum));
-
- init_srv_share_info0(&sh0->info_0, net_name);
- init_srv_share_info0_str(&sh0->info_0_str, net_name);
-}
+extern pstring global_myname;
/*******************************************************************
Fill in a share info level 1 structure.
@@ -68,13 +34,27 @@ static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int sn
static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
{
+ int len_net_name;
+ pstring net_name;
pstring remark;
+ uint32 type;
- char *net_name = lp_servicename(snum);
+ pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark,sizeof(remark));
+ standard_sub_conn(p->conn, remark, sizeof(remark));
+ len_net_name = strlen(net_name);
+
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
- init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
+ init_srv_share_info1(&sh1->info_1, net_name, type, remark);
init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
}
@@ -84,13 +64,16 @@ static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int sn
static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
{
+ int len_net_name;
+ pstring net_name;
pstring remark;
pstring path;
pstring passwd;
+ uint32 type;
- char *net_name = lp_servicename(snum);
+ pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark,sizeof(remark));
+ standard_sub_conn(p->conn, remark, sizeof(remark));
pstrcpy(path, "C:");
pstrcat(path, lp_pathname(snum));
@@ -102,8 +85,19 @@ static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int sn
string_replace(path, '/', '\\');
pstrcpy(passwd, "");
+ len_net_name = strlen(net_name);
- init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
+
+ init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
}
@@ -143,7 +137,7 @@ BOOL share_info_db_init(void)
local_pid = sys_getpid();
/* handle a Samba upgrade */
- tdb_lock_bystring(share_tdb, vstring, 0);
+ tdb_lock_bystring(share_tdb, vstring,0);
/* Cope with byte-reversed older versions of the db. */
vers_id = tdb_fetch_int32(share_tdb, vstring);
@@ -184,7 +178,7 @@ static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *
init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
- psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize);
+ psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
}
if (!psd) {
@@ -237,7 +231,7 @@ static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC
fstring key;
BOOL ret = False;
- mem_ctx = talloc_init("set_share_security");
+ mem_ctx = talloc_init();
if (mem_ctx == NULL)
return False;
@@ -257,7 +251,7 @@ static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC
/* Free malloc'ed memory */
-out:
+ out:
prs_mem_free(&ps);
if (mem_ctx)
@@ -317,7 +311,7 @@ void map_generic_share_sd_bits(SEC_DESC *psd)
Can this user access with share with the required permissions ?
********************************************************************/
-BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
+BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access)
{
uint32 granted;
NTSTATUS status;
@@ -325,9 +319,10 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u
SEC_DESC *psd = NULL;
size_t sd_size;
NT_USER_TOKEN *token = NULL;
+ user_struct *vuser = get_valid_user_struct(vuid);
BOOL ret = True;
- mem_ctx = talloc_init("share_access_check");
+ mem_ctx = talloc_init();
if (mem_ctx == NULL)
return False;
@@ -336,14 +331,14 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u
if (!psd)
goto out;
- if (conn->nt_user_token)
- token = conn->nt_user_token;
- else
+ if (vuser)
token = vuser->nt_user_token;
+ else
+ token = conn->nt_user_token;
ret = se_access_check(psd, token, desired_access, &granted, &status);
-out:
+ out:
talloc_destroy(mem_ctx);
@@ -357,15 +352,27 @@ out:
static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
{
int len_net_name;
+ pstring net_name;
pstring remark;
+ uint32 type;
- char *net_name = lp_servicename(snum);
+ pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark, sizeof(remark));
+ standard_sub_conn(p->conn, remark,sizeof(remark));
len_net_name = strlen(net_name);
- init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
+
+ init_srv_share_info501(&sh501->info_501, net_name, type, remark, (lp_csc_policy(snum) << 4));
init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
}
@@ -380,6 +387,7 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
pstring remark;
pstring path;
pstring passwd;
+ uint32 type;
SEC_DESC *sd;
size_t sd_size;
TALLOC_CTX *ctx = p->mem_ctx;
@@ -403,93 +411,49 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
pstrcpy(passwd, "");
len_net_name = strlen(net_name);
- sd = get_share_security(ctx, snum, &sd_size);
-
- init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
- init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
-}
-
-/***************************************************************************
- Fill in a share info level 1004 structure.
- ***************************************************************************/
-
-static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
-{
- pstring remark;
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
- pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark, sizeof(remark));
+ sd = get_share_security(ctx, snum, &sd_size);
- ZERO_STRUCTP(sh1004);
-
- init_srv_share_info1004(&sh1004->info_1004, remark);
- init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
+ init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
+ init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
}
/***************************************************************************
Fill in a share info level 1005 structure.
***************************************************************************/
-static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
+static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
{
- sh1005->share_info_flags = 0;
+ sh1005->misc_flags = 0;
+#ifdef WITH_MSDFS
if(lp_host_msdfs() && lp_msdfs_root(snum))
- sh1005->share_info_flags |=
- SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
- sh1005->share_info_flags |=
- lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
-}
-/***************************************************************************
- Fill in a share info level 1006 structure.
- ***************************************************************************/
-
-static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
-{
- sh1006->max_uses = -1;
-}
-
-/***************************************************************************
- Fill in a share info level 1007 structure.
- ***************************************************************************/
-
-static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
-{
- pstring alternate_directory_name = "";
- uint32 flags = 0;
-
- ZERO_STRUCTP(sh1007);
-
- init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
- init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
-}
-
-/*******************************************************************
- Fill in a share info level 1501 structure.
- ********************************************************************/
-
-static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
-{
- SEC_DESC *sd;
- size_t sd_size;
- TALLOC_CTX *ctx = p->mem_ctx;
-
- ZERO_STRUCTP(sh1501);
-
- sd = get_share_security(ctx, snum, &sd_size);
+ sh1005->misc_flags = 3;
+#endif
+
+ sh1005->misc_flags |= (lp_csc_policy(snum) << 4);
- sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
}
/*******************************************************************
True if it ends in '$'.
********************************************************************/
-static BOOL is_hidden_share(int snum)
+static BOOL is_admin_share(int snum)
{
- const char *net_name = lp_servicename(snum);
+ pstring net_name;
- return (net_name[strlen(net_name) - 1] == '$') ? True : False;
+ pstrcpy(net_name, lp_servicename(snum));
+ return (net_name[strlen(net_name)] == '$') ? True : False;
}
/*******************************************************************
@@ -513,7 +477,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
/* Count the number of entries. */
for (snum = 0; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
num_entries++;
}
@@ -525,24 +489,6 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
return True;
switch (info_level) {
- case 0:
- {
- SRV_SHARE_INFO_0 *info0;
- int i = 0;
-
- info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_0(p, &info0[i++], snum);
- }
- }
-
- ctr->share.info0 = info0;
- break;
-
- }
-
case 1:
{
SRV_SHARE_INFO_1 *info1;
@@ -551,7 +497,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
init_srv_share_info_1(p, &info1[i++], snum);
}
}
@@ -568,7 +514,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
init_srv_share_info_2(p, &info2[i++], snum);
}
}
@@ -585,7 +531,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
init_srv_share_info_501(p, &info501[i++], snum);
}
}
@@ -602,7 +548,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
init_srv_share_info_502(p, &info502[i++], snum);
}
}
@@ -611,92 +557,6 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
break;
}
- /* here for completeness but not currently used with enum (1004 - 1501)*/
-
- case 1004:
- {
- SRV_SHARE_INFO_1004 *info1004;
- int i = 0;
-
- info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_1004(p, &info1004[i++], snum);
- }
- }
-
- ctr->share.info1004 = info1004;
- break;
- }
-
- case 1005:
- {
- SRV_SHARE_INFO_1005 *info1005;
- int i = 0;
-
- info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_1005(p, &info1005[i++], snum);
- }
- }
-
- ctr->share.info1005 = info1005;
- break;
- }
-
- case 1006:
- {
- SRV_SHARE_INFO_1006 *info1006;
- int i = 0;
-
- info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_1006(p, &info1006[i++], snum);
- }
- }
-
- ctr->share.info1006 = info1006;
- break;
- }
-
- case 1007:
- {
- SRV_SHARE_INFO_1007 *info1007;
- int i = 0;
-
- info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_1007(p, &info1007[i++], snum);
- }
- }
-
- ctr->share.info1007 = info1007;
- break;
- }
-
- case 1501:
- {
- SRV_SHARE_INFO_1501 *info1501;
- int i = 0;
-
- info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
- init_srv_share_info_1501(p, &info1501[i++], snum);
- }
- }
-
- ctr->share.info1501 = info1501;
- break;
- }
default:
DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
return False;
@@ -742,9 +602,6 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I
if (snum >= 0) {
switch (info_level) {
- case 0:
- init_srv_share_info_0(p, &r_n->info.share.info0, snum);
- break;
case 1:
init_srv_share_info_1(p, &r_n->info.share.info1, snum);
break;
@@ -757,24 +614,8 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I
case 502:
init_srv_share_info_502(p, &r_n->info.share.info502, snum);
break;
-
- /* here for completeness */
- case 1004:
- init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
- break;
case 1005:
- init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
- break;
-
- /* here for completeness 1006 - 1501 */
- case 1006:
- init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
- break;
- case 1007:
- init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
- break;
- case 1501:
- init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
+ init_srv_share_info_1005(&r_n->info.share.info1005, snum);
break;
default:
DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
@@ -793,7 +634,7 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I
fill in a sess info level 1 structure.
********************************************************************/
-static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
+static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, const char *name)
{
init_srv_sess_info0(se0, name);
init_srv_sess_info0_str(str0, name);
@@ -805,13 +646,11 @@ static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *
static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
{
- struct sessionid *session_list;
uint32 num_entries = 0;
- (*stot) = list_sessions(&session_list);
+ (*stot) = 1;
if (ss0 == NULL) {
(*snum) = 0;
- SAFE_FREE(session_list);
return;
}
@@ -820,7 +659,7 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
if (snum) {
for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
init_srv_sess_0_info(&ss0->info_0[num_entries],
- &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
+ &ss0->info_0_str[num_entries], "MACHINE");
/* move on to creating next session */
/* move on to creating next sess */
@@ -840,7 +679,6 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
ss0->ptr_sess_info = 0;
ss0->num_entries_read2 = 0;
}
- SAFE_FREE(session_list);
}
/*******************************************************************
@@ -848,7 +686,7 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
********************************************************************/
static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
- char *name, char *user,
+ const char *name, const char *user,
uint32 num_opens,
uint32 open_time, uint32 idle_time,
uint32 usr_flgs)
@@ -863,13 +701,11 @@ static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
{
- struct sessionid *session_list;
uint32 num_entries = 0;
- (*stot) = list_sessions(&session_list);
+ (*stot) = 1;
if (ss1 == NULL) {
(*snum) = 0;
- SAFE_FREE(session_list);
return;
}
@@ -878,10 +714,8 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
if (snum) {
for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
init_srv_sess_1_info(&ss1->info_1[num_entries],
- &ss1->info_1_str[num_entries],
- session_list[*snum].remote_machine,
- session_list[*snum].username,
- 1, 10, 5, 0);
+ &ss1->info_1_str[num_entries],
+ "MACHINE", "dummy_user", 1, 10, 5, 0);
/* move on to creating next session */
/* move on to creating next sess */
@@ -1116,44 +950,73 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
}
/*******************************************************************
+ fill in a file info level 3 structure.
+ ********************************************************************/
+
+static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
+ uint32 fnum, uint32 perms, uint32 num_locks,
+ const char *path_name, const char *user_name)
+{
+ init_srv_file_info3(fl3 , fnum, perms, num_locks, path_name, user_name);
+ init_srv_file_info3_str(str3, path_name, user_name);
+}
+
+/*******************************************************************
+ fill in a file info level 3 structure.
+ ********************************************************************/
+
+static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
+{
+ uint32 num_entries = 0;
+ (*ftot) = 1;
+
+ if (fl3 == NULL) {
+ (*fnum) = 0;
+ return;
+ }
+
+ DEBUG(5,("init_srv_file_3_fl3\n"));
+
+ for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++) {
+ init_srv_file_3_info(&fl3->info_3[num_entries],
+ &fl3->info_3_str[num_entries],
+ (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
+
+ /* move on to creating next file */
+ num_entries++;
+ }
+
+ fl3->num_entries_read = num_entries;
+ fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
+ fl3->num_entries_read2 = num_entries;
+
+ if ((*fnum) >= (*ftot)) {
+ (*fnum) = 0;
+ }
+}
+
+/*******************************************************************
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd,
- uint32 *total_entries)
+static WERROR init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
WERROR status = WERR_OK;
- TALLOC_CTX *ctx = p->mem_ctx;
DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
- *total_entries = 1; /* dummy entries only, for */
ctr->switch_value = switch_value;
- ctr->num_entries = *total_entries - *resume_hnd;
- ctr->num_entries2 = ctr->num_entries;
switch (switch_value) {
- case 3: {
- int i;
- if (*total_entries > 0) {
- ctr->ptr_entries = 1;
- ctr->file.info3 = talloc(ctx, ctr->num_entries *
- sizeof(SRV_FILE_INFO_3));
- }
- for (i=0 ;i<ctr->num_entries;i++) {
- init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
- init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
-
- }
- ctr->ptr_file_info = 1;
- *resume_hnd = 0;
+ case 3:
+ init_srv_file_info_3(&ctr->file.info3, resume_hnd, total_entries);
+ ctr->ptr_file_ctr = 1;
break;
- }
default:
DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
(*resume_hnd = 0);
(*total_entries) = 0;
- ctr->ptr_entries = 0;
+ ctr->ptr_file_ctr = 0;
status = WERR_UNKNOWN_LEVEL;
break;
}
@@ -1165,7 +1028,7 @@ static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
+static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
uint32 resume_hnd, int file_level, int switch_value)
{
DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
@@ -1174,7 +1037,7 @@ static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
if (file_level == 0)
r_n->status = WERR_UNKNOWN_LEVEL;
else
- r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
+ r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
if (!W_ERROR_IS_OK(r_n->status))
resume_hnd = 0;
@@ -1198,21 +1061,11 @@ WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R
DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
- return WERR_ACCESS_DENIED;
- }
-
switch (q_u->switch_value) {
-
- /* Technically level 102 should only be available to
- Administrators but there isn't anything super-secret
- here, as most of it is made up. */
-
case 102:
init_srv_info_102(&ctr->srv.sv102,
- 500, global_myname(),
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
+ 500, global_myname,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
lp_major_announce_version(), lp_minor_announce_version(),
lp_default_server_announce(),
0xffffffff, /* users */
@@ -1225,13 +1078,13 @@ WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R
break;
case 101:
init_srv_info_101(&ctr->srv.sv101,
- 500, global_myname(),
+ 500, global_myname,
lp_major_announce_version(), lp_minor_announce_version(),
lp_default_server_announce(),
string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
break;
case 100:
- init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
+ init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
break;
default:
status = WERR_UNKNOWN_LEVEL;
@@ -1271,13 +1124,19 @@ net file enum
WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
{
+ r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR));
+ if (!r_u->ctr)
+ return WERR_NOMEM;
+
+ ZERO_STRUCTP(r_u->ctr);
+
DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
/* set up the */
- init_srv_r_net_file_enum(p, r_u,
+ init_srv_r_net_file_enum(r_u,
get_enum_hnd(&q_u->enum_hnd),
q_u->file_level,
- q_u->ctr.switch_value);
+ q_u->ctr->switch_value);
DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
@@ -1342,11 +1201,6 @@ WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R
{
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
- return WERR_ACCESS_DENIED;
- }
-
/* Create the list of shares for the response. */
init_srv_r_net_share_enum(p, r_u,
q_u->ctr.info_level,
@@ -1365,15 +1219,10 @@ WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET
{
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to srv_net_share_enum\n"));
- return WERR_ACCESS_DENIED;
- }
-
/* Create the list of shares for the response. */
init_srv_r_net_share_enum(p, r_u,
- q_u->ctr.info_level,
- get_enum_hnd(&q_u->enum_hnd), False);
+ q_u->ctr.info_level,
+ get_enum_hnd(&q_u->enum_hnd), False);
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
@@ -1391,7 +1240,7 @@ WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
/* Create the list of shares for the response. */
- unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->uni_share_name, sizeof(share_name));
init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
@@ -1405,7 +1254,10 @@ WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
static char *valid_share_pathname(char *dos_pathname)
{
+ pstring saved_pathname;
+ pstring unix_pathname;
char *ptr;
+ int ret;
/* Convert any '\' paths to '/' */
unix_format(dos_pathname);
@@ -1420,29 +1272,21 @@ static char *valid_share_pathname(char *dos_pathname)
if (*ptr != '/')
return NULL;
- return ptr;
-}
-
-static BOOL exist_share_pathname(char *unix_pathname)
-{
- pstring saved_pathname;
- int ret;
-
/* Can we cd to it ? */
/* First save our current directory. */
if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
return False;
+ pstrcpy(unix_pathname, ptr);
+
ret = chdir(unix_pathname);
/* We *MUST* be able to chdir back. Abort if we can't. */
if (chdir(saved_pathname) == -1)
smb_panic("valid_share_pathname: Unable to restore current directory.\n");
- if (ret == -1) return False;
-
- return True;
+ return (ret != -1) ? ptr : NULL;
}
/*******************************************************************
@@ -1459,14 +1303,14 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
int type;
int snum;
int ret;
- char *path;
+ char *ptr;
SEC_DESC *psd = NULL;
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
- unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->uni_share_name, sizeof(share_name));
- r_u->parm_error = 0;
+ r_u->switch_value = 0;
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
return WERR_ACCESS_DENIED;
@@ -1483,62 +1327,30 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ if (user.uid != 0)
return WERR_ACCESS_DENIED;
switch (q_u->info_level) {
case 1:
- pstrcpy(pathname, lp_pathname(snum));
- unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
- type = q_u->info.share.info2.info_2.type;
- psd = NULL;
- break;
+ /* Not enough info in a level 1 to do anything. */
+ return WERR_ACCESS_DENIED;
case 2:
- unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
- unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
+ unistr2_to_dos(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
+ unistr2_to_dos(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
type = q_u->info.share.info2.info_2.type;
psd = NULL;
break;
-#if 0
- /* not supported on set but here for completeness */
- case 501:
- unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
- type = q_u->info.share.info501.info_501.type;
- psd = NULL;
- break;
-#endif
case 502:
- unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
- unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
+ unistr2_to_dos(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
+ unistr2_to_dos(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
type = q_u->info.share.info502.info_502.type;
psd = q_u->info.share.info502.info_502_str.sd;
map_generic_share_sd_bits(psd);
break;
- case 1004:
- pstrcpy(pathname, lp_pathname(snum));
- unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
- type = STYPE_DISKTREE;
- break;
case 1005:
- /* XP re-sets the csc policy even if it wasn't changed by the
- user, so we must compare it to see if it's what is set in
- smb.conf, so that we can contine other ops like setting
- ACLs on a share */
- if (((q_u->info.share.info1005.share_info_flags &
- SHARE_1005_CSC_POLICY_MASK) >>
- SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
- return WERR_OK;
- else {
- DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
- return WERR_ACCESS_DENIED;
- }
- break;
- case 1006:
- case 1007:
return WERR_ACCESS_DENIED;
- break;
case 1501:
- pstrcpy(pathname, lp_pathname(snum));
+ fstrcpy(pathname, lp_pathname(snum));
fstrcpy(comment, lp_comment(snum));
psd = q_u->info.share.info1501.sdb->sec;
map_generic_share_sd_bits(psd);
@@ -1554,12 +1366,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(path = valid_share_pathname( pathname )))
+ if (!(ptr = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(path, '"', ' ');
+ string_replace(ptr, '"', ' ');
string_replace(comment, '"', ' ');
DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
@@ -1567,12 +1379,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* Only call modify function if something changed. */
- if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
+ if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
if (!lp_change_share_cmd() || !*lp_change_share_cmd())
return WERR_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
+ lp_change_share_cmd(), CONFIGFILE, share_name, ptr, comment);
DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
@@ -1580,12 +1392,6 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
return WERR_ACCESS_DENIED;
}
- /* Check if the new share pathname exist, if not return an error */
- if (!exist_share_pathname(path)) {
- DEBUG(1, ("_srv_net_share_set_info: change share command was ok but path (%s) has not been created!\n", path));
- return WERR_OBJECT_PATH_INVALID;
- }
-
/* Tell everyone we updated smb.conf. */
message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
@@ -1626,17 +1432,17 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
int type;
int snum;
int ret;
- char *path;
+ char *ptr;
SEC_DESC *psd = NULL;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
- r_u->parm_error = 0;
+ r_u->switch_value = 0;
get_current_user(&user,p);
- if (user.uid != sec_initial_uid()) {
- DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
+ if (user.uid != 0) {
+ DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
@@ -1646,39 +1452,24 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
}
switch (q_u->info_level) {
- case 0:
- /* No path. Not enough info in a level 0 to do anything. */
- return WERR_ACCESS_DENIED;
case 1:
/* Not enough info in a level 1 to do anything. */
return WERR_ACCESS_DENIED;
case 2:
- unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
- unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
- unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
+ unistr2_to_dos(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
+ unistr2_to_dos(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
type = q_u->info.share.info2.info_2.type;
break;
- case 501:
- /* No path. Not enough info in a level 501 to do anything. */
- return WERR_ACCESS_DENIED;
case 502:
- unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
- unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
- unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
+ unistr2_to_dos(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
+ unistr2_to_dos(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
type = q_u->info.share.info502.info_502.type;
psd = q_u->info.share.info502.info_502_str.sd;
map_generic_share_sd_bits(psd);
break;
-
- /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
-
- case 1004:
case 1005:
- case 1006:
- case 1007:
- return WERR_ACCESS_DENIED;
- break;
- case 1501:
/* DFS only level. */
return WERR_ACCESS_DENIED;
default:
@@ -1700,16 +1491,16 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(path = valid_share_pathname( pathname )))
+ if (!(ptr = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(path, '"', ' ');
+ string_replace(ptr, '"', ' ');
string_replace(comment, '"', ' ');
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
+ lp_add_share_cmd(), CONFIGFILE, share_name, ptr, comment);
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
@@ -1717,33 +1508,10 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
return WERR_ACCESS_DENIED;
}
- /* Check if the new share pathname exist, if not try to delete the
- * share and return an error */
- if (!exist_share_pathname(path)) {
- DEBUG(1, ("_srv_net_share_add: add share command was ok but path (%s) has not been created!\n", path));
- DEBUG(1, ("_srv_net_share_add: trying to rollback and delete the share\n"));
-
- if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
- DEBUG(1, ("_srv_net_share_add: Error! delete share command is not defined! Please check share (%s) in the config file\n", share_name));
- return WERR_OBJECT_PATH_INVALID;
- }
-
- slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
- lp_delete_share_cmd(), dyn_CONFIGFILE, share_name);
-
- DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
- DEBUG(1, ("_srv_net_share_add: Error! delete share command failed! Please check share (%s) in the config file\n", share_name));
- }
-
- return WERR_OBJECT_PATH_INVALID;
- }
-
if (psd) {
- if (!set_share_security(p->mem_ctx, share_name, psd)) {
- DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
- }
+ if (!set_share_security(p->mem_ctx, share_name, psd))
+ DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
+ share_name ));
}
/* Tell everyone we updated smb.conf. */
@@ -1775,7 +1543,7 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
- unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->uni_share_name, sizeof(share_name));
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
return WERR_ACCESS_DENIED;
@@ -1791,14 +1559,14 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ if (user.uid != 0)
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
return WERR_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
- lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
+ lp_delete_share_cmd(), CONFIGFILE, lp_servicename(snum));
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
@@ -1817,13 +1585,6 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
return WERR_OK;
}
-WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
-{
- DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
-
- return _srv_net_share_del(p, q_u, r_u);
-}
-
/*******************************************************************
time of day
********************************************************************/
@@ -1877,7 +1638,8 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
{
SEC_DESC *psd = NULL;
size_t sd_size;
- DATA_BLOB null_pw;
+ fstring null_pw;
+ fstring dev;
pstring filename;
pstring qualname;
files_struct *fsp = NULL;
@@ -1885,8 +1647,9 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
BOOL bad_path;
int access_mode;
int action;
- NTSTATUS nt_status;
+ int ecode;
struct current_user user;
+ fstring user_name;
connection_struct *conn = NULL;
BOOL became_user = False;
@@ -1894,20 +1657,22 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
r_u->status = WERR_OK;
- unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
+ unistr2_to_dos(qualname, &q_u->uni_qual_name, sizeof(qualname));
/* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob(NULL, 0);
+ *null_pw = '\0';
+ fstrcpy(dev, "A:");
get_current_user(&user, p);
+ fstrcpy(user_name, uidtoname(user.uid));
become_root();
- conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
+ conn = make_connection(qualname, user_name, null_pw, 0, dev, user.vuid, &ecode);
unbecome_root();
if (conn == NULL) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
- r_u->status = ntstatus_to_werror(nt_status);
+ r_u->status = W_ERROR(ecode);
goto error_exit;
}
@@ -1916,18 +1681,18 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
r_u->status = WERR_ACCESS_DENIED;
goto error_exit;
}
- became_user = True;
+ became_user = True;
- unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
+ unistr2_to_dos(filename, &q_u->uni_file_name, sizeof(filename));
unix_convert(filename, conn, NULL, &bad_path, &st);
fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
if (!fsp) {
/* Perhaps it is a directory */
if (errno == EISDIR)
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
if (!fsp) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
@@ -1936,7 +1701,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
}
}
- sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
+ sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
if (sd_size == 0) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
@@ -1957,7 +1722,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
close_cnum(conn, user.vuid);
return r_u->status;
-error_exit:
+ error_exit:
if(fsp) {
close_file(fsp, True);
@@ -1982,14 +1747,16 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
BOOL ret;
pstring filename;
pstring qualname;
- DATA_BLOB null_pw;
+ fstring null_pw;
+ fstring dev;
files_struct *fsp = NULL;
SMB_STRUCT_STAT st;
BOOL bad_path;
int access_mode;
int action;
- NTSTATUS nt_status;
+ int ecode;
struct current_user user;
+ fstring user_name;
connection_struct *conn = NULL;
BOOL became_user = False;
@@ -1997,20 +1764,22 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
r_u->status = WERR_OK;
- unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
+ unistr2_to_dos(qualname, &q_u->uni_qual_name, sizeof(qualname));
/* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob(NULL, 0);
+ *null_pw = '\0';
+ fstrcpy(dev, "A:");
get_current_user(&user, p);
+ fstrcpy(user_name, uidtoname(user.uid));
become_root();
- conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
+ conn = make_connection(qualname, user_name, null_pw, 0, dev, user.vuid, &ecode);
unbecome_root();
if (conn == NULL) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
- r_u->status = ntstatus_to_werror(nt_status);
+ r_u->status = W_ERROR(ecode);
goto error_exit;
}
@@ -2021,17 +1790,17 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
}
became_user = True;
- unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
+ unistr2_to_dos(filename, &q_u->uni_file_name, sizeof(filename));
unix_convert(filename, conn, NULL, &bad_path, &st);
fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
if (!fsp) {
/* Perhaps it is a directory */
if (errno == EISDIR)
fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
if (!fsp) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
@@ -2040,7 +1809,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
}
}
- ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
+ ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
if (ret == False) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
@@ -2053,7 +1822,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
close_cnum(conn, user.vuid);
return r_u->status;
-error_exit:
+ error_exit:
if(fsp) {
close_file(fsp, True);
@@ -2076,7 +1845,7 @@ error_exit:
"Nigel Williams" <nigel@veritas.com>.
***********************************************************************************/
-static const char *server_disks[] = {"C:"};
+const char *server_disks[] = {"C:"};
static uint32 get_server_disk_count(void)
{
@@ -2118,7 +1887,6 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
{
uint32 i;
const char *disk_name;
- TALLOC_CTX *ctx = p->mem_ctx;
uint32 resume=get_enum_hnd(&q_u->enum_hnd);
r_u->status=WERR_OK;
@@ -2127,18 +1895,6 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
r_u->disk_enum_ctr.unknown = 0;
- {
- DISK_INFO *dinfo;
-
- int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
-
- if(!(dinfo = talloc(ctx, dinfo_size))) {
- return WERR_NOMEM;
- }
-
- r_u->disk_enum_ctr.disk_info = dinfo;
- }
-
r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
/*allow one DISK_INFO for null terminator*/
@@ -2152,7 +1908,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
}
- /* add a terminating null string. Is this there if there is more data to come? */
+ /*add a terminating null string. Is this there if there is more data to come?*/
r_u->disk_enum_ctr.entries_read++;
@@ -2177,7 +1933,7 @@ WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
/*check if share name is ok*/
/*also check if we already have a share with this name*/
- unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
+ unistr2_to_dos(share_name, &q_u->uni_name, sizeof(share_name));
snum = find_service(share_name);
/* Share already exists. */
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 5bb8db4e062..44c35d3d588 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
@@ -38,9 +39,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*
* A list of the rids of well known BUILTIN and Domain users
* and groups.
@@ -78,340 +76,124 @@ rid_name domain_group_rids[] =
{ 0 , NULL }
};
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid)
-{
- SAM_ACCOUNT *sam_pass=NULL;
- int i, cur_rid=0;
- gid_t gid;
- gid_t *groups = NULL;
- int num_groups;
- GROUP_MAP map;
- DOM_SID tmp_sid;
- fstring user_name;
- fstring str_domsid, str_qsid;
- uint32 rid,grid;
- uint32 *rids=NULL, *new_rids=NULL;
- gid_t winbind_gid_low, winbind_gid_high;
- BOOL ret;
- BOOL winbind_groups_exist;
-
- /*
- * this code is far from perfect.
- * first it enumerates the full /etc/group and that can be slow.
- * second, it works only with users' SIDs
- * whereas the day we support nested groups, it will have to
- * support both users's SIDs and domain groups' SIDs
- *
- * having our own ldap backend would be so much faster !
- * we're far from that, but hope one day ;-) JFM.
- */
-
- *prids=NULL;
- *numgroups=0;
-
- winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
-
-
- DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n",
- sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid)));
-
- pdb_init_sam(&sam_pass);
- become_root();
- ret = pdb_getsampwsid(sam_pass, q_sid);
- unbecome_root();
- if (ret == False) {
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- fstrcpy(user_name, pdb_get_username(sam_pass));
- grid=pdb_get_group_rid(sam_pass);
- if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- become_root();
- /* on some systems this must run as root */
- num_groups = getgroups_user(user_name, &groups);
- unbecome_root();
- if (num_groups == -1) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: getgroups_user failed\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
+#define LSA_MAX_GROUPS 96
- for (i=0;i<num_groups;i++) {
-
- become_root();
- ret = get_group_from_gid(groups[i], &map);
- unbecome_root();
-
- if ( !ret ) {
- DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
- continue;
- }
-
- /* if it's not an alias, continue */
- if (map.sid_name_use != SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- continue;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- continue;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name));
- continue;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name));
- continue;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- free(groups);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
- break;
- }
-
- if(num_groups)
- free(groups);
-
- /* now check for the user's gid (the primary group rid) */
- for (i=0; i<cur_rid && grid!=rids[i]; i++)
- ;
-
- /* the user's gid is already there */
- if (i!=cur_rid) {
- DEBUG(10,("get_alias_user_groups: user is already in the list. good.\n"));
- goto done;
- }
-
- DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name));
-
- if(!get_group_from_gid(gid, &map)) {
- DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your "
- "/etc/passwd and /etc/group files\n", user_name));
- goto done;
- }
-
- /* the primary group isn't an alias */
- if (map.sid_name_use!=SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- goto done;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- goto done;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name ));
- goto done;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name ));
- goto done;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
-
-done:
- *prids=rids;
- *numgroups=cur_rid;
- pdb_free_sam(&sam_pass);
-
- return NT_STATUS_OK;
+int make_dom_gids(TALLOC_CTX *ctx, char *gids_str, DOM_GID **ppgids)
+{
+ const char *ptr;
+ pstring s2;
+ int count;
+ DOM_GID *gids;
+
+ *ppgids = NULL;
+
+ DEBUG(4,("make_dom_gids: %s\n", gids_str));
+
+ if (gids_str == NULL || *gids_str == 0)
+ return 0;
+
+ for (count = 0, ptr = gids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2));
+ count++)
+ ;
+
+ gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * count );
+ if(!gids)
+ {
+ DEBUG(0,("make_dom_gids: talloc fail !\n"));
+ return 0;
+ }
+
+ for (count = 0, ptr = gids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2)) &&
+ count < LSA_MAX_GROUPS;
+ count++)
+ {
+ /* the entries are of the form GID/ATTR, ATTR being optional.*/
+ const char *attr = NULL;
+ char *pattr = NULL;
+ uint32 rid = 0;
+ int i;
+
+ pattr = strchr(s2,'/');
+ if (pattr)
+ *pattr++ = 0;
+
+ attr = pattr;
+ if (!attr || !*attr)
+ attr = "7"; /* default value for attribute is 7 */
+
+ /* look up the RID string and see if we can turn it into a rid number */
+ for (i = 0; builtin_alias_rids[i].name != NULL; i++)
+ {
+ if (strequal(builtin_alias_rids[i].name, s2))
+ {
+ rid = builtin_alias_rids[i].rid;
+ break;
+ }
+ }
+
+ if (rid == 0)
+ rid = atoi(s2);
+
+ if (rid == 0)
+ {
+ DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n", s2, attr));
+ count--;
+ }
+ else
+ {
+ gids[count].g_rid = rid;
+ gids[count].attr = atoi(attr);
+
+ DEBUG(5,("group id: %d attr: %d\n", gids[count].g_rid, gids[count].attr));
+ }
+ }
+
+ *ppgids = gids;
+ return count;
}
/*******************************************************************
gets a domain user's groups
********************************************************************/
-BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass)
+void get_domain_user_groups(char *domain_groups, char *user)
{
- GROUP_MAP *map=NULL;
- int i, num, num_entries, cur_gid=0;
- struct group *grp;
- DOM_GID *gids;
- fstring user_name;
- uint32 grid;
- uint32 tmp_rid;
- BOOL ret;
-
- *numgroups= 0;
-
- fstrcpy(user_name, pdb_get_username(sam_pass));
- grid=pdb_get_group_rid(sam_pass);
+ pstring tmp;
- DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name));
-
- /* we must wrap this is become/unbecome root for ldap backends */
-
- become_root();
- /* first get the list of the domain groups */
- ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
-
- unbecome_root();
-
- /* end wrapper for group enumeration */
-
-
- if ( !ret )
- return False;
-
- DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries));
-
-
- /*
- * alloc memory. In the worse case, we alloc memory for nothing.
- * but I prefer to alloc for nothing
- * than reallocing everytime.
- */
- gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries);
-
- /* for each group, check if the user is a member of. Only include groups
- from this domain */
-
- for(i=0; i<num_entries; i++) {
-
- if ( !sid_check_is_in_our_domain(&map[i].sid) ) {
- DEBUG(10,("get_domain_user_groups: skipping check of %s since it is not in our domain\n",
- map[i].nt_name));
- continue;
- }
-
- if ((grp=getgrgid(map[i].gid)) == NULL) {
- /* very weird !!! */
- DEBUG(5,("get_domain_user_groups: gid %d doesn't exist anymore !\n", (int)map[i].gid));
- continue;
- }
+ if (domain_groups == NULL || user == NULL) return;
- for(num=0; grp->gr_mem[num]!=NULL; num++) {
- if(strcmp(grp->gr_mem[num], user_name)==0) {
- /* we found the user, add the group to the list */
- sid_peek_rid(&map[i].sid, &(gids[cur_gid].g_rid));
- gids[cur_gid].attr=7;
- DEBUG(10,("get_domain_user_groups: user found in group %s\n", map[i].nt_name));
- cur_gid++;
- break;
- }
- }
- }
+#if 0 /* removed by --jerry */
+ /* any additional groups this user is in. e.g power users */
+ pstrcpy(domain_groups, lp_domain_groups());
+#else
+ *domain_groups = '\0';
+#endif
- /* we have checked the groups */
- /* we must now check the gid of the user or the primary group rid, that's the same */
- for (i=0; i<cur_gid && grid!=gids[i].g_rid; i++)
- ;
-
- /* the user's gid is already there */
- if (i!=cur_gid) {
- /*
- * the primary group of the user but be the first one in the list
- * don't ask ! JFM.
- */
- gids[i].g_rid=gids[0].g_rid;
- gids[0].g_rid=grid;
- goto done;
- }
+ /* can only be a user or a guest. cannot be guest _and_ admin */
+ if (user_in_list(user, lp_domain_guest_group()))
+ {
+ slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
+ pstrcat(domain_groups, tmp);
- for(i=0; i<num_entries; i++) {
- sid_peek_rid(&map[i].sid, &tmp_rid);
- if (tmp_rid==grid) {
- /*
- * the primary group of the user but be the first one in the list
- * don't ask ! JFM.
- */
- gids[cur_gid].g_rid=gids[0].g_rid;
- gids[0].g_rid=tmp_rid;
- gids[cur_gid].attr=7;
- DEBUG(10,("get_domain_user_groups: primary gid of user found in group %s\n", map[i].nt_name));
- cur_gid++;
- goto done; /* leave the loop early */
- }
+ DEBUG(3,("domain guest group access %s granted\n", tmp));
}
+ else
+ {
+ slprintf(tmp, sizeof(tmp) -1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
+ pstrcat(domain_groups, tmp);
- DEBUG(0,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", user_name));
- DEBUGADD(0,("get_domain_user_groups: You should fix it, NT doesn't like that\n"));
-
-
- done:
- *pgids=gids;
- *numgroups=cur_gid;
- SAFE_FREE(map);
-
- return True;
-}
-
-/*******************************************************************
- gets a domain user's groups from their already-calculated NT_USER_TOKEN
- ********************************************************************/
-NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
- const NT_USER_TOKEN *nt_token,
- int *numgroups, DOM_GID **pgids)
-{
- DOM_GID *gids;
- int i;
-
- gids = (DOM_GID *)talloc(mem_ctx, sizeof(*gids) * nt_token->num_sids);
-
- if (!gids) {
- return NT_STATUS_NO_MEMORY;
- }
+ DEBUG(3,("domain group access %s granted\n", tmp));
- *numgroups=0;
+ if (user_in_list(user, lp_domain_admin_group()))
+ {
+ slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
+ pstrcat(domain_groups, tmp);
- for (i=PRIMARY_GROUP_SID_INDEX; i < nt_token->num_sids; i++) {
- if (sid_compare_domain(domain_sid, &nt_token->user_sids[i])==0) {
- sid_peek_rid(&nt_token->user_sids[i], &(gids[*numgroups].g_rid));
- gids[*numgroups].attr=7;
- (*numgroups)++;
+ DEBUG(3,("domain admin group access %s granted\n", tmp));
}
}
- *pgids = gids;
- return NT_STATUS_OK;
}
/*******************************************************************
@@ -466,8 +248,6 @@ NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
return NT_STATUS_NONE_MAPPED;
}
-
-#if 0 /*Nobody uses this function just now*/
/*******************************************************************
Look up a local user rid and return a name and type.
********************************************************************/
@@ -503,17 +283,15 @@ NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
if (ret == True) {
fstrcpy(user_name, pdb_get_username(sampwd) );
DEBUG(5,(" = %s\n", user_name));
- pdb_free_sam(&sampwd);
+ pdb_free_sam(sampwd);
return NT_STATUS_OK;
}
DEBUG(5,(" none mapped\n"));
- pdb_free_sam(&sampwd);
+ pdb_free_sam(sampwd);
return NT_STATUS_NONE_MAPPED;
}
-#endif
-
/*******************************************************************
Look up a local (domain) group name and return a rid
********************************************************************/
@@ -536,7 +314,7 @@ NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid)
/*******************************************************************
Look up a local (BUILTIN) alias name and return a rid
********************************************************************/
-NTSTATUS local_lookup_alias_rid(const char *alias_name, uint32 *rid)
+NTSTATUS local_lookup_alias_rid(char *alias_name, uint32 *rid)
{
const char *als_name;
int i = -1; /* start do loop at -1 */
@@ -571,10 +349,10 @@ NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid)
if (ret == True) {
(*rid) = pdb_get_user_rid(sampass);
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return NT_STATUS_OK;
}
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return NT_STATUS_NONE_MAPPED;
}
diff --git a/source/rpc_server/srv_wkssvc.c b/source/rpc_server/srv_wkssvc.c
index b5c1af34d9d..3661824da17 100644
--- a/source/rpc_server/srv_wkssvc.c
+++ b/source/rpc_server/srv_wkssvc.c
@@ -1,10 +1,10 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Copyright (C) Paul Ashton 1997.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,9 +25,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
/*******************************************************************
api_wks_query_info
********************************************************************/
@@ -59,20 +56,16 @@ static BOOL api_wks_query_info(pipes_struct *p)
/*******************************************************************
\PIPE\wkssvc commands
********************************************************************/
-
-static struct api_struct api_wks_cmds[] =
+struct api_struct api_wks_cmds[] =
{
- { "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info }
+ { "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info },
+ { NULL , 0 , NULL }
};
-void wkssvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
- *fns = api_wks_cmds;
- *n_fns = sizeof(api_wks_cmds) / sizeof(struct api_struct);
-}
-
-NTSTATUS rpc_wks_init(void)
+/*******************************************************************
+ receives a wkssvc pipe and responds.
+ ********************************************************************/
+BOOL api_wkssvc_rpc(pipes_struct *p)
{
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "wkssvc", "ntsvcs", api_wks_cmds,
- sizeof(api_wks_cmds) / sizeof(struct api_struct));
+ return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds);
}
diff --git a/source/rpc_server/srv_wkssvc_nt.c b/source/rpc_server/srv_wkssvc_nt.c
index 25fa029237d..ea3b48887df 100644
--- a/source/rpc_server/srv_wkssvc_nt.c
+++ b/source/rpc_server/srv_wkssvc_nt.c
@@ -1,5 +1,6 @@
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
@@ -25,8 +26,7 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+extern pstring global_myname;
/*******************************************************************
create_wks_info_100
@@ -39,17 +39,17 @@ static void create_wks_info_100(WKS_INFO_100 *inf)
DEBUG(5,("create_wks_info_100: %d\n", __LINE__));
- pstrcpy (my_name, global_myname());
- strupper_m(my_name);
+ pstrcpy (my_name, global_myname);
+ strupper(my_name);
pstrcpy (domain, lp_workgroup());
- strupper_m(domain);
+ strupper(domain);
init_wks_info_100(inf,
0x000001f4, /* platform id info */
lp_major_announce_version(),
lp_minor_announce_version(),
- my_name, domain);
+ my_name, unix_to_dos_static(domain));
}
/*******************************************************************
diff --git a/source/rpcclient/cmd_dfs.c b/source/rpcclient/cmd_dfs.c
index 44e97f9881e..1d90c6a96d6 100644
--- a/source/rpcclient/cmd_dfs.c
+++ b/source/rpcclient/cmd_dfs.c
@@ -25,7 +25,7 @@
/* Check DFS is supported by the remote server */
static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
BOOL dfs_exists;
NTSTATUS result;
@@ -44,10 +44,10 @@ static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
static NTSTATUS cmd_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result;
- const char *entrypath, *servername, *sharename, *comment;
+ char *entrypath, *servername, *sharename, *comment;
uint32 flags = 0;
if (argc != 5) {
@@ -68,10 +68,10 @@ static NTSTATUS cmd_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
static NTSTATUS cmd_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result;
- const char *entrypath, *servername, *sharename;
+ char *entrypath, *servername, *sharename;
if (argc != 4) {
printf("Usage: %s entrypath servername sharename\n", argv[0]);
@@ -94,7 +94,7 @@ static void display_dfs_info_1(DFS_INFO_1 *info1)
{
fstring temp;
- unistr2_to_ascii(temp, &info1->entrypath, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &info1->entrypath, sizeof(temp) - 1);
printf("entrypath: %s\n", temp);
}
@@ -104,10 +104,10 @@ static void display_dfs_info_2(DFS_INFO_2 *info2)
{
fstring temp;
- unistr2_to_ascii(temp, &info2->entrypath, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &info2->entrypath, sizeof(temp) - 1);
printf("entrypath: %s\n", temp);
- unistr2_to_ascii(temp, &info2->comment, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &info2->comment, sizeof(temp) - 1);
printf("\tcomment: %s\n", temp);
printf("\tstate: %d\n", info2->state);
@@ -121,10 +121,10 @@ static void display_dfs_info_3(DFS_INFO_3 *info3)
fstring temp;
int i;
- unistr2_to_ascii(temp, &info3->entrypath, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &info3->entrypath, sizeof(temp) - 1);
printf("entrypath: %s\n", temp);
- unistr2_to_ascii(temp, &info3->comment, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &info3->comment, sizeof(temp) - 1);
printf("\tcomment: %s\n", temp);
printf("\tstate: %d\n", info3->state);
@@ -133,10 +133,10 @@ static void display_dfs_info_3(DFS_INFO_3 *info3)
for (i = 0; i < info3->num_storages; i++) {
DFS_STORAGE_INFO *dsi = &info3->storages[i];
- unistr2_to_ascii(temp, &dsi->servername, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &dsi->servername, sizeof(temp) - 1);
printf("\t\tstorage[%d] servername: %s\n", i, temp);
- unistr2_to_ascii(temp, &dsi->sharename, sizeof(temp) - 1);
+ unistr2_to_unix(temp, &dsi->sharename, sizeof(temp) - 1);
printf("\t\tstorage[%d] sharename: %s\n", i, temp);
}
}
@@ -169,7 +169,7 @@ static void display_dfs_info_ctr(DFS_INFO_CTR *ctr)
/* Enumerate dfs shares */
static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
DFS_INFO_CTR ctr;
NTSTATUS result;
@@ -192,10 +192,10 @@ static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
static NTSTATUS cmd_dfs_getinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result;
- const char *entrypath, *servername, *sharename;
+ char *entrypath, *servername, *sharename;
uint32 info_level = 1;
DFS_INFO_CTR ctr;
@@ -227,11 +227,11 @@ struct cmd_set dfs_commands[] = {
{ "DFS" },
- { "dfsexist", RPC_RTYPE_NTSTATUS, cmd_dfs_exist, NULL, PI_NETDFS, "Query DFS support", "" },
- { "dfsadd", RPC_RTYPE_NTSTATUS, cmd_dfs_add, NULL, PI_NETDFS, "Add a DFS share", "" },
- { "dfsremove", RPC_RTYPE_NTSTATUS, cmd_dfs_remove, NULL, PI_NETDFS, "Remove a DFS share", "" },
- { "dfsgetinfo",RPC_RTYPE_NTSTATUS, cmd_dfs_getinfo, NULL, PI_NETDFS, "Query DFS share info", "" },
- { "dfsenum", RPC_RTYPE_NTSTATUS, cmd_dfs_enum, NULL, PI_NETDFS, "Enumerate dfs shares", "" },
+ { "dfsexist", cmd_dfs_exist, PIPE_NETDFS, "Query DFS support", "" },
+ { "dfsadd", cmd_dfs_add, PIPE_NETDFS, "Add a DFS share", "" },
+ { "dfsremove", cmd_dfs_remove, PIPE_NETDFS, "Remove a DFS share", "" },
+ { "dfsgetinfo", cmd_dfs_getinfo, PIPE_NETDFS, "Query DFS share info", "" },
+ { "dfsenum", cmd_dfs_enum, PIPE_NETDFS, "Enumerate dfs shares", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_ds.c b/source/rpcclient/cmd_ds.c
deleted file mode 100644
index c5b12ed1503..00000000000
--- a/source/rpcclient/cmd_ds.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Gerald Carter 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "rpcclient.h"
-
-/* Look up domain related information on a remote host */
-
-static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- NTSTATUS result;
- DS_DOMINFO_CTR ctr;
-
- result = cli_ds_getprimarydominfo( cli, mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr );
- if ( NT_STATUS_IS_OK(result) )
- {
- printf ("Machine Role = [%d]\n", ctr.basic->machine_role);
-
- if ( ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING ) {
- printf( "Directory Service is running.\n");
- printf( "Domain is in %s mode.\n", (ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) ? "mixed" : "native" );
- }
- else
- printf( "Directory Service not running on server\n");
- }
-
- return result;
-}
-
-static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- NTSTATUS result;
- uint32 flags = 0x1;
- struct ds_domain_trust *trusts = NULL;
- unsigned int num_domains = 0;
-
- result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags,
- &trusts, &num_domains );
-
- printf( "%d domains returned\n", num_domains );
-
- SAFE_FREE( trusts );
-
- return result;
-}
-
-/* List of commands exported by this module */
-
-struct cmd_set ds_commands[] = {
-
- { "LSARPC-DS" },
-
- { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" },
- { "dsenumdomtrusts", RPC_RTYPE_NTSTATUS, cmd_ds_enum_domain_trusts, NULL, PI_NETLOGON, "Enumerate all trusted domains in an AD forest", "" },
-
- { NULL }
-};
diff --git a/source/rpcclient/cmd_echo.c b/source/rpcclient/cmd_echo.c
deleted file mode 100644
index fa4e6916633..00000000000
--- a/source/rpcclient/cmd_echo.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "rpcclient.h"
-
-static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- uint32 request = 1, response;
- NTSTATUS result;
-
- if (argc > 2) {
- printf("Usage: %s [num]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- if (argc == 2)
- request = atoi(argv[1]);
-
- result = cli_echo_add_one(cli, mem_ctx, request, &response);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- printf("%d + 1 = %d\n", request, response);
-
-done:
- return result;
-}
-
-static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- uint32 size, i;
- NTSTATUS result;
- char *in_data = NULL, *out_data = NULL;
-
- if (argc != 2) {
- printf("Usage: %s num\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- size = atoi(argv[1]);
- in_data = malloc(size);
-
- for (i = 0; i < size; i++)
- in_data[i] = i & 0xff;
-
- result = cli_echo_data(cli, mem_ctx, size, in_data, &out_data);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- for (i = 0; i < size; i++) {
- if (in_data[i] != out_data[i]) {
- printf("mismatch at offset %d, %d != %d\n",
- i, in_data[i], out_data[i]);
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
-done:
- SAFE_FREE(in_data);
-
- return result;
-}
-
-static NTSTATUS cmd_echo_source_data(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- uint32 size, i;
- NTSTATUS result;
- char *out_data = NULL;
-
- if (argc != 2) {
- printf("Usage: %s num\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- size = atoi(argv[1]);
-
- result = cli_echo_source_data(cli, mem_ctx, size, &out_data);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- for (i = 0; i < size; i++) {
- if (out_data && out_data[i] != (i & 0xff)) {
- printf("mismatch at offset %d, %d != %d\n",
- i, out_data[i], i & 0xff);
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
-done:
- return result;
-}
-
-static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- uint32 size, i;
- NTSTATUS result;
- char *in_data = NULL;
-
- if (argc != 2) {
- printf("Usage: %s num\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- size = atoi(argv[1]);
- in_data = malloc(size);
-
- for (i = 0; i < size; i++)
- in_data[i] = i & 0xff;
-
- result = cli_echo_sink_data(cli, mem_ctx, size, in_data);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
-done:
- SAFE_FREE(in_data);
-
- return result;
-}
-
-/* List of commands exported by this module */
-
-struct cmd_set echo_commands[] = {
-
- { "ECHO" },
-
- { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, "Add one to a number", "" },
- { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, "Echo data", "" },
- { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, "Sink data", "" },
- { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, "Source data", "" },
- { NULL }
-};
diff --git a/source/rpcclient/cmd_epmapper.c b/source/rpcclient/cmd_epmapper.c
deleted file mode 100644
index 4998286194c..00000000000
--- a/source/rpcclient/cmd_epmapper.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "rpcclient.h"
-
-
-static NTSTATUS cmd_epm_map(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- EPM_HANDLE handle, entry_handle;
- EPM_TOWER *towers;
- EPM_FLOOR floors[5];
- uint8 addr[4] = {0,0,0,0};
- uint32 numtowers;
- /* need to allow all this stuff to be passed in, but
- for now, it demonstrates the call */
- struct uuid if_uuid = {0xe3514235, 0x4b06, 0x11d1, \
- { 0xab, 0x04 }, \
- { 0x00, 0xc0, \
- 0x4f, 0xc2, 0xdc, 0xd2 } },
- syn_uuid = {0x8a885d04, 0x1ceb, 0x11c9, \
- { 0x9f, 0xe8 }, \
- { 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } };
-
- NTSTATUS result;
-
- ZERO_STRUCT(handle);
- numtowers = 1;
- init_epm_floor_uuid(&floors[0], if_uuid, 4);
- init_epm_floor_uuid(&floors[1], syn_uuid, 2);
- init_epm_floor_rpc(&floors[2]);
-
- /* sample for netbios named pipe query
- init_epm_floor_np(&floors[3], "\\PIPE\\lsass");
- init_epm_floor_nb(&floors[4], "\\\\psflinux");
- */
- init_epm_floor_tcp(&floors[3], 135);
- init_epm_floor_ip(&floors[4], addr);
- towers = talloc(mem_ctx, sizeof(EPM_TOWER));
- init_epm_tower(mem_ctx, towers, floors, 5);
-
- result = cli_epm_map(cli, mem_ctx, &handle, &towers, &entry_handle, &numtowers);
-
- return result;
-}
-
-struct cmd_set epm_commands[] = {
-
- { "EPMAPPER" },
-
- { "map", RPC_RTYPE_NTSTATUS, cmd_epm_map, NULL, PI_EPM, "map endpoint", "" },
- { NULL }
-};
-
-
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 5a646a10460..17180e237f7 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -1,9 +1,8 @@
-/*
+/*
Unix SMB/CIFS implementation.
RPC pipe client
- Copyright (C) Tim Potter 2000
- Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Tim Potter 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,58 +22,16 @@
#include "includes.h"
#include "rpcclient.h"
-
-/* useful function to allow entering a name instead of a SID and
- * looking it up automatically */
-static NTSTATUS name_to_sid(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid, const char *name)
-{
- POLICY_HND pol;
- uint32 *sid_types;
- NTSTATUS result;
- DOM_SID *sids;
-
- /* maybe its a raw SID */
- if (strncmp(name, "S-", 2) == 0 &&
- string_to_sid(sid, name)) {
- return NT_STATUS_OK;
- }
-
- result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- cli_lsa_close(cli, mem_ctx, &pol);
-
- *sid = sids[0];
-
-done:
- return result;
-}
-
-
/* Look up domain related information on a remote host */
static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_SID *dom_sid;
- struct uuid *dom_guid;
- fstring sid_str;
- char *domain_name = NULL;
- char *dns_name = NULL;
- char *forest_name = NULL;
-
+ DOM_SID dom_sid;
+ fstring sid_str, domain_name;
uint32 info_class = 3;
if (argc > 2) {
@@ -85,51 +42,28 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
if (argc == 2)
info_class = atoi(argv[1]);
- /* Lookup info policy */
- switch (info_class) {
- case 12:
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
- result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol,
- info_class, &domain_name,
- &dns_name, &forest_name,
- &dom_guid, &dom_sid);
- break;
- default:
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
- if (!NT_STATUS_IS_OK(result))
- goto done;
- result = cli_lsa_query_info_policy(cli, mem_ctx, &pol,
- info_class, &domain_name,
- &dom_sid);
- }
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Lookup info policy */
+
+ result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
+ domain_name, &dom_sid);
if (!NT_STATUS_IS_OK(result))
goto done;
-
- sid_to_string(sid_str, dom_sid);
- if (domain_name)
+ sid_to_string(sid_str, &dom_sid);
+
+ if (domain_name[0])
printf("domain %s has sid %s\n", domain_name, sid_str);
else
printf("could not query info for level %d\n", info_class);
- if (dns_name)
- printf("domain dns name is %s\n", dns_name);
- if (forest_name)
- printf("forest name is %s\n", forest_name);
-
- if (info_class == 12) {
- printf("domain GUID is ");
- smb_uuid_string_static(*dom_guid);
- }
done:
return result;
}
@@ -138,7 +72,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -158,11 +92,11 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
- (const char**)(argv + 1), &sids, &types);
+ result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
+ (const char**)(argv + 1), &sids, &types);
- if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
- NT_STATUS_V(STATUS_SOME_UNMAPPED))
+ if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
+ NT_STATUS_V(STATUS_SOME_UNMAPPED))
goto done;
result = NT_STATUS_OK;
@@ -171,9 +105,10 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
for (i = 0; i < (argc - 1); i++) {
fstring sid_str;
+
sid_to_string(sid_str, &sids[i]);
- printf("%s %s (%s: %d)\n", argv[i + 1], sid_str,
- sid_type_lookup(types[i]), types[i]);
+ printf("%s %s (%d)\n", argv[i + 1], sid_str,
+ types[i]);
}
done:
@@ -183,7 +118,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
/* Resolve a list of SIDs to a list of names */
static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -214,19 +149,16 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- for (i = 0; i < argc - 1; i++)
- if (!string_to_sid(&sids[i], argv[i + 1])) {
- result = NT_STATUS_INVALID_SID;
- goto done;
- }
+ for (i = 0; i < argc - 1; i++)
+ string_to_sid(&sids[i], argv[i + 1]);
/* Lookup the SIDs */
- result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
- &domains, &names, &types);
+ result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
+ &domains, &names, &types);
- if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
- NT_STATUS_V(STATUS_SOME_UNMAPPED))
+ if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
+ NT_STATUS_V(STATUS_SOME_UNMAPPED))
goto done;
result = NT_STATUS_OK;
@@ -237,9 +169,9 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
fstring sid_str;
sid_to_string(sid_str, &sids[i]);
- printf("%s %s\\%s (%d)\n", sid_str,
- domains[i] ? domains[i] : "*unknown*",
- names[i] ? names[i] : "*unknown*", types[i]);
+ printf("%s %s\\%s (%d)\n", sid_str,
+ domains[i] ? domains[i] : "*unknown*",
+ names[i] ? names[i] : "*unknown*", types[i]);
}
done:
@@ -250,29 +182,23 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID *domain_sids;
char **domain_names;
-
- /* defaults, but may be changed using params */
uint32 enum_ctx = 0;
- uint32 num_domains = 0;
+ uint32 num_domains;
int i;
- if (argc > 2) {
- printf("Usage: %s [enum context (0)]\n", argv[0]);
+ if (argc != 1) {
+ printf("Usage: %s\n", argv[0]);
return NT_STATUS_OK;
}
- if (argc == 2 && argv[1]) {
- enum_ctx = atoi(argv[2]);
- }
-
result = cli_lsa_open_policy(cli, mem_ctx, True,
- POLICY_VIEW_LOCAL_INFORMATION,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
@@ -281,14 +207,14 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
/* Lookup list of trusted domains */
result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
- &num_domains,
- &domain_names, &domain_sids);
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- goto done;
-
- /* Print results: list of names and sids returned in this response. */
+ &num_domains, &domain_names,
+ &domain_sids);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Print results */
+
for (i = 0; i < num_domains; i++) {
fstring sid_str;
@@ -304,8 +230,8 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
/* Enumerates privileges */
static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -358,7 +284,7 @@ static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -395,8 +321,8 @@ static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
/* Enumerate the LSA SIDS */
static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -445,53 +371,11 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
return result;
}
-/* Create a new account */
-
-static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- POLICY_HND dom_pol;
- POLICY_HND user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 des_access = 0x000f000f;
-
- DOM_SID sid;
-
- if (argc != 2 ) {
- printf("Usage: %s SID\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &dom_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_create_account(cli, mem_ctx, &dom_pol, &sid, des_access, &user_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- printf("Account for SID %s successfully created\n\n", argv[1]);
- result = NT_STATUS_OK;
-
- done:
- return result;
-}
-
-
/* Enumerate the privileges of an SID */
static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND dom_pol;
POLICY_HND user_pol;
@@ -508,9 +392,7 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
+ string_to_sid(&sid, argv[1]);
result = cli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
@@ -541,135 +423,11 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
return result;
}
-
-/* Enumerate the privileges of an SID via LsaEnumerateAccountRights */
-
-static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- POLICY_HND dom_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DOM_SID sid;
- uint32 count;
- char **rights;
-
- int i;
-
- if (argc != 2 ) {
- printf("Usage: %s SID\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &dom_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, sid, &count, &rights);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- printf("found %d privileges for SID %s\n", count, sid_string_static(&sid));
-
- for (i = 0; i < count; i++) {
- printf("\t%s\n", rights[i]);
- }
-
- done:
- return result;
-}
-
-
-/* add some privileges to a SID via LsaAddAccountRights */
-
-static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- POLICY_HND dom_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DOM_SID sid;
-
- if (argc < 3 ) {
- printf("Usage: %s SID [rights...]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &dom_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
- argc-2, argv+2);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- done:
- return result;
-}
-
-
-/* remove some privileges to a SID via LsaRemoveAccountRights */
-
-static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- POLICY_HND dom_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- DOM_SID sid;
-
- if (argc < 3 ) {
- printf("Usage: %s SID [rights...]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &dom_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
- False, argc-2, argv+2);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- done:
- return result;
-}
-
-
/* Get a privilege value given its name */
static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -704,7 +462,7 @@ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -736,27 +494,22 @@ static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
return result;
}
-
/* List of commands exported by this module */
struct cmd_set lsarpc_commands[] = {
{ "LSARPC" },
- { "lsaquery", RPC_RTYPE_NTSTATUS, cmd_lsa_query_info_policy, NULL, PI_LSARPC, "Query info policy", "" },
- { "lookupsids", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_sids, NULL, PI_LSARPC, "Convert SIDs to names", "" },
- { "lookupnames", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names, NULL, PI_LSARPC, "Convert names to SIDs", "" },
- { "enumtrust", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_trust_dom, NULL, PI_LSARPC, "Enumerate trusted domains", "Usage: [preferred max number] [enum context (0)]" },
- { "enumprivs", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege, NULL, PI_LSARPC, "Enumerate privileges", "" },
- { "getdispname", RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname, NULL, PI_LSARPC, "Get the privilege name", "" },
- { "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, "Enumerate the LSA SIDS", "" },
- { "lsacreateaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_create_account, NULL, PI_LSARPC, "Create a new lsa account", "" },
- { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID", "" },
- { "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, "Enumerate the rights of an SID", "" },
- { "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, "Add rights to an account", "" },
- { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" },
- { "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookupprivvalue, NULL, PI_LSARPC, "Get a privilege value given its name", "" },
- { "lsaquerysecobj", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj, NULL, PI_LSARPC, "Query LSA security object", "" },
+ { "lsaquery", cmd_lsa_query_info_policy, PIPE_LSARPC, "Query info policy", "" },
+ { "lookupsids", cmd_lsa_lookup_sids, PIPE_LSARPC, "Convert SIDs to names", "" },
+ { "lookupnames", cmd_lsa_lookup_names, PIPE_LSARPC, "Convert names to SIDs", "" },
+ { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "" },
+ { "enumprivs", cmd_lsa_enum_privilege, PIPE_LSARPC, "Enumerate privileges", "" },
+ { "getdispname", cmd_lsa_get_dispname, PIPE_LSARPC, "Get the privilege name", "" },
+ { "lsaenumsid", cmd_lsa_enum_sids, PIPE_LSARPC, "Enumerate the LSA SIDS", "" },
+ { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PIPE_LSARPC, "Enumerate the privileges of an SID", "" },
+ { "lsalookupprivvalue", cmd_lsa_lookupprivvalue, PIPE_LSARPC, "Get a privilege value given its name", "" },
+ { "lsaquerysecobj", cmd_lsa_query_secobj, PIPE_LSARPC, "Query LSA security object", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 9e281fefce4..c9ab4393ba2 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -24,7 +24,7 @@
static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
uint32 query_level = 1;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -45,34 +45,9 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
return result;
}
-static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- fstring dcname;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s domainname\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = cli_netlogon_getdcname(cli, mem_ctx, argv[1], dcname);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- /* Display results */
-
- printf("%s\n", dcname);
-
- done:
- return result;
-}
-
static NTSTATUS cmd_netlogon_logon_ctrl(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
#if 0
uint32 query_level = 1;
@@ -107,25 +82,25 @@ static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
for (i = 0; i < num_deltas; i++) {
switch (hdr_deltas[i].type) {
case SAM_DELTA_DOMAIN_INFO:
- unistr2_to_ascii(name,
+ unistr2_to_unix(name,
&deltas[i].domain_info.uni_dom_name,
sizeof(name) - 1);
printf("Domain: %s\n", name);
break;
case SAM_DELTA_GROUP_INFO:
- unistr2_to_ascii(name,
+ unistr2_to_unix(name,
&deltas[i].group_info.uni_grp_name,
sizeof(name) - 1);
printf("Group: %s\n", name);
break;
case SAM_DELTA_ACCOUNT_INFO:
- unistr2_to_ascii(name,
+ unistr2_to_unix(name,
&deltas[i].account_info.uni_acct_name,
sizeof(name) - 1);
printf("Account: %s\n", name);
break;
case SAM_DELTA_ALIAS_INFO:
- unistr2_to_ascii(name,
+ unistr2_to_unix(name,
&deltas[i].alias_info.uni_als_name,
sizeof(name) - 1);
printf("Alias: %s\n", name);
@@ -150,10 +125,11 @@ static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
group->rids[j], group->attribs[j]);
break;
}
- case SAM_DELTA_MODIFIED_COUNT: {
- SAM_DELTA_MOD_COUNT *mc = &deltas[i].mod_count;
+ case SAM_DELTA_SAM_STAMP: {
+ SAM_DELTA_STAMP *stamp = &deltas[i].stamp;
- printf("sam sequence update: 0x%04x\n", mc->seqnum);
+ printf("sam sequence update: 0x%04x\n",
+ stamp->seqnum);
break;
}
default:
@@ -168,9 +144,10 @@ static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ unsigned char trust_passwd[16];
uint32 database_id = 0, num_deltas;
SAM_DELTA_HDR *hdr_deltas;
SAM_DELTA_CTR *deltas;
@@ -184,13 +161,33 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
if (argc == 2)
database_id = atoi(argv[1]);
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ return result;
+ }
+
+ /* Initialise session credentials */
+
+ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
+ NULL)) {
+ fprintf(stderr, "could not fetch trust account password\n");
+ goto done;
+ }
+
+ result = cli_nt_setup_creds(cli, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
+ }
+
/* on first call the returnAuthenticator is empty */
memset(&ret_creds, 0, sizeof(ret_creds));
/* Synchronise sam database */
result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, database_id,
- 0, &num_deltas, &hdr_deltas, &deltas);
+ &num_deltas, &hdr_deltas, &deltas);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -207,9 +204,10 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ unsigned char trust_passwd[16];
uint32 database_id, num_deltas, tmp;
SAM_DELTA_HDR *hdr_deltas;
SAM_DELTA_CTR *deltas;
@@ -226,6 +224,28 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
seqnum.low = tmp & 0xffff;
seqnum.high = 0;
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ goto done;
+ }
+
+ /* Initialise session credentials */
+
+ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
+ NULL)) {
+ fprintf(stderr, "could not fetch trust account password\n");
+ goto done;
+ }
+
+ result = cli_nt_setup_creds(cli, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
+ }
+
+ /* Synchronise sam database */
+
result = cli_netlogon_sam_deltas(cli, mem_ctx, database_id,
seqnum, &num_deltas,
&hdr_deltas, &deltas);
@@ -245,21 +265,18 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
+ unsigned char trust_passwd[16];
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
int logon_type = NET_LOGON_TYPE;
- const char *username, *password;
- uint32 neg_flags = 0x000001ff;
- int auth_level = 2;
- DOM_CRED ret_creds;
+ char *username, *password;
/* Check arguments */
- if (argc < 3 || argc > 6) {
+ if (argc < 3 || argc > 4) {
fprintf(stderr, "Usage: samlogon <username> <password> "
- "[logon_type] [neg flags] [auth level (2 or 3)]\n"
- "neg flags being 0x000001ff or 0x6007ffff\n");
+ "[logon_type]\n");
return NT_STATUS_OK;
}
@@ -269,55 +286,30 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
if (argc == 4)
sscanf(argv[3], "%i", &logon_type);
- if (argc == 5)
- sscanf(argv[4], "%i", &neg_flags);
-
- if (argc == 6)
- sscanf(argv[5], "%i", &auth_level);
+ /* Authenticate ourselves with the domain controller */
- /* Perform the sam logon */
-
- ZERO_STRUCT(ret_creds);
-
- result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
-
- result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ return result;
+ }
- if (!NT_STATUS_IS_OK(result))
+ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
+ NULL)) {
+ fprintf(stderr, "could not fetch trust account password\n");
goto done;
+ }
- done:
- return result;
-}
-
-/* Change the trust account password */
-
-static NTSTATUS cmd_netlogon_change_trust_pw(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED ret_creds;
-
- /* Check arguments */
+ result = cli_nt_setup_creds(cli, trust_passwd);
- if (argc > 1) {
- fprintf(stderr, "Usage: change_trust_pw");
- return NT_STATUS_OK;
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
}
/* Perform the sam logon */
- ZERO_STRUCT(ret_creds);
-
- result = trust_pw_find_change_and_store_it(cli, mem_ctx,
- lp_workgroup());
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
+ result = cli_netlogon_sam_logon(cli, mem_ctx, username, password,
+ logon_type);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -326,20 +318,17 @@ static NTSTATUS cmd_netlogon_change_trust_pw(struct cli_state *cli,
return result;
}
-
/* List of commands exported by this module */
struct cmd_set netlogon_commands[] = {
{ "NETLOGON" },
- { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, "Logon Control 2", "" },
- { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, "Get trusted DC name", "" },
- { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, "Logon Control", "" },
- { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, "Sam Synchronisation", "" },
- { "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, "Query Sam Deltas", "" },
- { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon, NULL, PI_NETLOGON, "Sam Logon", "" },
- { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw, NULL, PI_NETLOGON, "Change Trust Account Password", "" },
+ { "logonctrl2", cmd_netlogon_logon_ctrl2, PIPE_NETLOGON, "Logon Control 2", "" },
+ { "logonctrl", cmd_netlogon_logon_ctrl, PIPE_NETLOGON, "Logon Control", "" },
+ { "samsync", cmd_netlogon_sam_sync, PIPE_NETLOGON, "Sam Synchronisation", "" },
+ { "samdeltas", cmd_netlogon_sam_deltas, PIPE_NETLOGON, "Query Sam Deltas", "" },
+ { "samlogon", cmd_netlogon_sam_logon, PIPE_NETLOGON, "Sam Logon", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_reg.c b/source/rpcclient/cmd_reg.c
index bf85d217160..5ffaeb38610 100644
--- a/source/rpcclient/cmd_reg.c
+++ b/source/rpcclient/cmd_reg.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NT Domain Authentication SMB / MSRPC client
Copyright (C) Andrew Tridgell 1994-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
@@ -88,7 +89,7 @@ static void cmd_reg_enum(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
@@ -247,7 +248,7 @@ static void cmd_reg_query_key(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
@@ -410,7 +411,7 @@ static void cmd_reg_create_val(struct client_info *info)
dump_data(10, (char *)value.buffer, value.buf_len);
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, keyname, parent_name,
@@ -489,7 +490,7 @@ static void cmd_reg_delete_val(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, keyname, parent_name,
@@ -564,7 +565,7 @@ static void cmd_reg_delete_key(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, parent_name, key_name,
@@ -653,7 +654,7 @@ static void cmd_reg_create_key(struct client_info *info)
sam_access.mask = SEC_RIGHTS_READ;
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, parent_key, parent_name,
@@ -732,7 +733,7 @@ static void cmd_reg_test_key_sec(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
@@ -827,7 +828,7 @@ static void cmd_reg_get_key_sec(struct client_info *info)
}
/* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
/* open registry receive a policy handle */
res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
@@ -895,13 +896,14 @@ static void cmd_reg_get_key_sec(struct client_info *info)
nt registry shutdown
****************************************************************************/
static NTSTATUS cmd_reg_shutdown(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
+ extern char *optarg;
+ extern int optind;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring msg;
uint32 timeout = 20;
- BOOL force = False;
- BOOL reboot = False;
+ uint16 flgs = 0;
int opt;
*msg = 0;
@@ -909,33 +911,37 @@ static NTSTATUS cmd_reg_shutdown(struct cli_state *cli, TALLOC_CTX *mem_ctx,
while ((opt = getopt(argc, argv, "m:t:rf")) != EOF)
{
- /*fprintf (stderr, "[%s]\n", argv[argc-1]);*/
+ fprintf (stderr, "[%s]\n", argv[argc-1]);
switch (opt)
{
case 'm':
- fstrcpy(msg, optarg);
- /*fprintf (stderr, "[%s|%s]\n", optarg, msg);*/
+ {
+ safe_strcpy(msg, optarg, sizeof(msg)-1);
+ fprintf (stderr, "[%s|%s]\n", optarg, msg);
break;
-
+ }
case 't':
+ {
timeout = atoi(optarg);
- /*fprintf (stderr, "[%s|%d]\n", optarg, timeout);*/
- break;
-
+ fprintf (stderr, "[%s|%d]\n", optarg, timeout);
+ break;
+ }
case 'r':
- reboot = True;
- break;
-
+ {
+ flgs |= 0x100;
+ break;
+ }
case 'f':
- force = True;
+ {
+ flgs |= 0x001;
break;
-
+ }
}
}
/* create an entry */
- result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, reboot, force);
+ result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, flgs);
if (NT_STATUS_IS_OK(result))
DEBUG(5,("cmd_reg_shutdown: query succeeded\n"));
@@ -950,7 +956,7 @@ abort a shutdown
****************************************************************************/
static NTSTATUS cmd_reg_abort_shutdown(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -970,11 +976,11 @@ struct cmd_set reg_commands[] = {
{ "REG" },
- { "shutdown", RPC_RTYPE_NTSTATUS, cmd_reg_shutdown, NULL, PI_WINREG, "Remote Shutdown",
- "syntax: shutdown [-m message] [-t timeout] [-r] [-h] [-f] (-r == reboot, -h == halt, -f == force)" },
+ { "shutdown", cmd_reg_shutdown, PIPE_WINREG, "Remote Shutdown",
+ "[-m message] [-t timeout] [-r] [-f] (-r == reboot, -f == force)" },
- { "abortshutdown", RPC_RTYPE_NTSTATUS, cmd_reg_abort_shutdown, NULL, PI_WINREG, "Abort Shutdown",
- "syntax: abortshutdown" },
+ { "abortshutdown", cmd_reg_abort_shutdown, PIPE_WINREG, "Abort Shutdown",
+ "" },
/*
{ "regenum", cmd_reg_enum, "Registry Enumeration",
"<keyname>" },
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 6ab08e1991b..b86b364637b 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -34,34 +34,34 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
{
fstring temp;
- unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_user_name, sizeof(temp)-1);
printf("\tUser Name :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_full_name, sizeof(temp)-1);
printf("\tFull Name :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_home_dir, sizeof(temp)-1);
printf("\tHome Drive :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_dir_drive, sizeof(temp)-1);
printf("\tDir Drive :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_profile_path, sizeof(temp)-1);
printf("\tProfile Path:\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_logon_script, sizeof(temp)-1);
printf("\tLogon Script:\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_acct_desc, sizeof(temp)-1);
printf("\tDescription :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_workstations, sizeof(temp)-1);
printf("\tWorkstations:\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_unknown_str, sizeof(temp)-1);
printf("\tUnknown Str :\t%s\n", temp);
- unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
+ unistr2_to_unix(temp, &usr->uni_munged_dial, sizeof(temp)-1);
printf("\tRemote Dial :\t%s\n", temp);
printf("\tLogon Time :\t%s\n",
@@ -79,14 +79,13 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
printf("\tunknown_2[0..31]...\n"); /* user passwords? */
- printf("\tuser_rid :\t0x%x\n" , usr->user_rid ); /* User ID */
- printf("\tgroup_rid:\t0x%x\n" , usr->group_rid); /* Group ID */
- printf("\tacb_info :\t0x%04x\n", usr->acb_info ); /* Account Control Info */
+ printf("\tuser_rid :\t%x\n" , usr->user_rid ); /* User ID */
+ printf("\tgroup_rid:\t%x\n" , usr->group_rid); /* Group ID */
+ printf("\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */
- printf("\tfields_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */
+ printf("\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */
printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
- printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count);
- printf("\tlogon_count:\t0x%08x\n", usr->logon_count);
+ printf("\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */
printf("\tpadding1[0..7]...\n");
@@ -126,7 +125,7 @@ static const char *display_time(NTTIME nttime)
mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
- fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
+ snprintf(string, sizeof(string)-1, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
return (string);
}
@@ -147,10 +146,10 @@ static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
{
fstring name;
- unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1);
+ unistr2_to_unix(name, &info2->uni_domain, sizeof(name) - 1);
printf("Domain:\t%s\n", name);
- unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
+ unistr2_to_unix(name, &info2->uni_server, sizeof(name) - 1);
printf("Server:\t%s\n", name);
printf("Total Users:\t%d\n", info2->num_domain_usrs);
@@ -175,14 +174,14 @@ static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
printf("index: 0x%x ", e1->user_idx);
printf("RID: 0x%x ", e1->rid_user);
printf("acb: 0x%x ", e1->acb_info);
-
- unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
+
+ unistr2_to_unix(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
printf("Account: %s\t", tmp);
- unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s1->uni_full_name, sizeof(tmp)-1);
printf("Name: %s\t", tmp);
- unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
printf("Desc: %s\n", tmp);
}
@@ -194,10 +193,10 @@ static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
printf("RID: 0x%x ", e2->rid_user);
printf("acb: 0x%x ", e2->acb_info);
- unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
printf("Account: %s\t", tmp);
- unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
printf("Name: %s\n", tmp);
}
@@ -210,10 +209,10 @@ static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
printf("RID: 0x%x ", e3->rid_grp);
printf("attr: 0x%x ", e3->attr);
- unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
printf("Account: %s\t", tmp);
- unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
+ unistr2_to_unix(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
printf("Name: %s\n", tmp);
}
@@ -244,56 +243,32 @@ static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
}
-/****************************************************************************
- Try samr_connect4 first, then samr_conenct if it fails
- ****************************************************************************/
-static NTSTATUS try_samr_connects(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- result = cli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- result = cli_samr_connect(cli, mem_ctx, access_mask,
- connect_pol);
- }
- return result;
-}
-
/**********************************************************************
* Query user information
*/
static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 info_level = 21;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
SAM_USERINFO_CTR *user_ctr;
fstring server;
uint32 user_rid;
- if ((argc < 2) || (argc > 4)) {
- printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &user_rid);
-
- if (argc > 2)
- sscanf(argv[2], "%i", &info_level);
-
- if (argc > 3)
- sscanf(argv[3], "%x", &access_mask);
-
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -306,7 +281,7 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
goto done;
result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
user_rid, &user_pol);
if (!NT_STATUS_IS_OK(result))
@@ -333,9 +308,9 @@ static void display_group_info1(GROUP_INFO1 *info1)
{
fstring temp;
- unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
+ unistr2_to_unix(temp, &info1->uni_acct_name, sizeof(temp)-1);
printf("\tGroup Name:\t%s\n", temp);
- unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
+ unistr2_to_unix(temp, &info1->uni_acct_desc, sizeof(temp)-1);
printf("\tDescription:\t%s\n", temp);
printf("\tunk1:%d\n", info1->unknown_1);
printf("\tNum Members:%d\n", info1->num_members);
@@ -348,7 +323,7 @@ static void display_group_info4(GROUP_INFO4 *info4)
{
fstring desc;
- unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
+ unistr2_to_unix(desc, &info4->uni_acct_desc, sizeof(desc)-1);
printf("\tGroup Description:%s\n", desc);
}
@@ -374,34 +349,27 @@ static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
*/
static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 info_level = 1;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
GROUP_INFO_CTR *group_ctr;
fstring server;
uint32 group_rid;
- if ((argc < 2) || (argc > 4)) {
- printf("Usage: %s rid [info level] [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &group_rid);
-
- if (argc > 2)
- sscanf(argv[2], "%i", &info_level);
-
- if (argc > 3)
- sscanf(argv[3], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -414,7 +382,7 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
goto done;
result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
group_rid, &group_pol);
if (!NT_STATUS_IS_OK(result))
@@ -436,7 +404,7 @@ done:
static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol,
domain_pol,
@@ -444,49 +412,45 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 num_groups,
user_rid;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
DOM_GID *user_gids;
int i;
fstring server;
- if ((argc < 2) || (argc > 3)) {
- printf("Usage: %s rid [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &user_rid);
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
user_rid, &user_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
&num_groups, &user_gids);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
for (i = 0; i < num_groups; i++) {
printf("\tgroup rid:[0x%x] attr:[0x%x]\n",
@@ -500,13 +464,12 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
/* Query aliases a user is a member of */
static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 user_rid, num_aliases, *alias_rids;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
int i;
fstring server;
DOM_SID tmp_sid;
@@ -515,47 +478,45 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
string_to_sid(&global_sid_Builtin, "S-1-5-32");
- if ((argc < 3) || (argc > 4)) {
- printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
+ if (argc != 3) {
+ printf("Usage: %s builtin|domain rid\n", argv[0]);
return NT_STATUS_OK;
}
sscanf(argv[2], "%i", &user_rid);
-
- if (argc > 3)
- sscanf(argv[3], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
if (StrCaseCmp(argv[1], "domain")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&global_sid_Builtin, &domain_pol);
else
return NT_STATUS_OK;
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
sid_copy(&tmp_sid, &domain_sid);
sid_append_rid(&tmp_sid, user_rid);
init_dom_sid2(&sid, &tmp_sid);
result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol, 1, &sid, &num_aliases, &alias_rids);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
for (i = 0; i < num_aliases; i++) {
printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
@@ -569,54 +530,50 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 num_members, *group_rids, *group_attrs, group_rid;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
int i;
fstring server;
- if ((argc < 2) || (argc > 3)) {
- printf("Usage: %s rid [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &group_rid);
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
-
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
group_rid, &group_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
for (i = 0; i < num_members; i++) {
printf("\trid:[0x%x] attr:[0x%x]\n", group_rids[i],
@@ -627,232 +584,113 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
return result;
}
-/* Enumerate domain users */
-
-static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx, size, num_dom_users, i;
- char **dom_users;
- uint32 *dom_rids;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- uint16 acb_mask = ACB_NORMAL;
- BOOL got_connect_pol = False, got_domain_pol = False;
-
- if ((argc < 1) || (argc > 2)) {
- printf("Usage: %s [access_mask]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- if (argc > 1)
- sscanf(argv[1], "%x", &access_mask);
-
- /* Get sam policy handle */
-
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_connect_pol = True;
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
- &domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- got_domain_pol = True;
-
- /* Enumerate domain users */
-
- start_idx = 0;
- size = 0xffff;
-
- do {
- result = cli_samr_enum_dom_users(
- cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
- size, &dom_users, &dom_rids, &num_dom_users);
-
- if (NT_STATUS_IS_OK(result) ||
- NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
-
- for (i = 0; i < num_dom_users; i++)
- printf("user:[%s] rid:[0x%x]\n",
- dom_users[i], dom_rids[i]);
- }
-
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
-
- done:
- if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
-
- if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
-
- return result;
-}
-
/* Enumerate domain groups */
static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx, size, num_dom_groups, i;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
struct acct_info *dom_groups;
- BOOL got_connect_pol = False, got_domain_pol = False;
- if ((argc < 1) || (argc > 2)) {
- printf("Usage: %s [access_mask]\n", argv[0]);
+ if (argc != 1) {
+ printf("Usage: %s\n", argv[0]);
return NT_STATUS_OK;
}
-
- if (argc > 1)
- sscanf(argv[1], "%x", &access_mask);
/* Get sam policy handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
-
- got_connect_pol = True;
+ }
/* Get domain policy handle */
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
-
- got_domain_pol = True;
+ }
/* Enumerate domain groups */
start_idx = 0;
size = 0xffff;
- do {
- result = cli_samr_enum_dom_groups(
- cli, mem_ctx, &domain_pol, &start_idx, size,
- &dom_groups, &num_dom_groups);
-
- if (NT_STATUS_IS_OK(result) ||
- NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
-
- for (i = 0; i < num_dom_groups; i++)
- printf("group:[%s] rid:[0x%x]\n",
- dom_groups[i].acct_name,
- dom_groups[i].rid);
- }
+ result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
+ &start_idx, size,
+ &dom_groups, &num_dom_groups);
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+ for (i = 0; i < num_dom_groups; i++)
+ printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
+ dom_groups[i].rid);
done:
- if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
-
- if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
-
return result;
}
-/* Enumerate alias groups */
+/* Enumerate domain groups */
static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx, size, num_als_groups, i;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- struct acct_info *als_groups;
+ uint32 start_idx, size, num_dom_groups, i;
+ struct acct_info *dom_groups;
DOM_SID global_sid_Builtin;
- BOOL got_connect_pol = False, got_domain_pol = False;
string_to_sid(&global_sid_Builtin, "S-1-5-32");
- if ((argc < 2) || (argc > 3)) {
- printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s builtin|domain\n", argv[0]);
return NT_STATUS_OK;
}
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
/* Get sam policy handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
-
- got_connect_pol = True;
+ }
/* Get domain policy handle */
if (StrCaseCmp(argv[1], "domain")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&global_sid_Builtin, &domain_pol);
else
return NT_STATUS_OK;
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
- got_domain_pol = True;
-
- /* Enumerate alias groups */
+ /* Enumerate domain groups */
start_idx = 0;
- size = 0xffff; /* Number of groups to retrieve */
+ size = 0xffff;
- do {
- result = cli_samr_enum_als_groups(
- cli, mem_ctx, &domain_pol, &start_idx, size,
- &als_groups, &num_als_groups);
+ result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
+ &start_idx, size,
+ &dom_groups, &num_dom_groups);
- if (NT_STATUS_IS_OK(result) ||
- NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
-
- for (i = 0; i < num_als_groups; i++)
- printf("group:[%s] rid:[0x%x]\n",
- als_groups[i].acct_name,
- als_groups[i].rid);
- }
- } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+ for (i = 0; i < num_dom_groups; i++)
+ printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
+ dom_groups[i].rid);
done:
- if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
-
- if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
-
return result;
}
@@ -860,64 +698,51 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, alias_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 alias_rid, num_members, i;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
DOM_SID *alias_sids;
- DOM_SID global_sid_Builtin;
-
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
- if ((argc < 3) || (argc > 4)) {
- printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return NT_STATUS_OK;
}
- sscanf(argv[2], "%i", &alias_rid);
-
- if (argc > 3)
- sscanf(argv[3], "%x", &access_mask);
+ sscanf(argv[1], "%i", &alias_rid);
/* Open SAMR handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Open handle on domain */
-
- if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol);
- else if (StrCaseCmp(argv[1], "builtin")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &global_sid_Builtin, &domain_pol);
- else
- return NT_STATUS_OK;
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Open handle on alias */
result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
alias_rid, &alias_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
&num_members, &alias_sids);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
for (i = 0; i < num_members; i++) {
fstring sid_str;
@@ -934,13 +759,12 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries, i;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- uint32 info_level = 1;
+ int info_level = 1;
SAM_DISPINFO_CTR ctr;
SAM_DISPINFO_1 info1;
SAM_DISPINFO_2 info2;
@@ -950,8 +774,8 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
int loop_count = 0;
BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
- if (argc > 5) {
- printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
+ if (argc > 4) {
+ printf("Usage: %s [info level] [start index] [max entries] [max_size]\n", argv[0]);
return NT_STATUS_OK;
}
@@ -965,41 +789,37 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
sscanf(argv[3], "%i", &max_entries);
got_params = True;
}
-
+
if (argc >= 5) {
sscanf(argv[4], "%i", &max_size);
got_params = True;
}
-
- if (argc >= 6)
- sscanf(argv[5], "%x", &access_mask);
/* Get sam policy handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Get domain policy handle */
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Query display info */
ZERO_STRUCT(ctr);
ZERO_STRUCT(info1);
-
+
switch (info_level) {
case 1:
ZERO_STRUCT(info1);
- ctr.sam.info1 = &info1;
+ ctr.sam.info1 = &info1;
break;
case 2:
ZERO_STRUCT(info2);
@@ -1020,46 +840,39 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
}
- while(1) {
+ do {
- if (!got_params)
- get_query_dispinfo_params(
- loop_count, &max_entries, &max_size);
-
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
- &start_idx, info_level,
- &num_entries, max_entries,
- max_size, &ctr);
+ if (!got_params)
+ get_query_dispinfo_params(
+ loop_count, &max_entries, &max_size);
- loop_count++;
+ result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ &start_idx, info_level,
+ &num_entries, max_entries,
+ max_size, &ctr);
- if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- break;
+ loop_count++;
- if (num_entries == 0)
+ for (i = 0; i < num_entries; i++) {
+ switch (info_level) {
+ case 1:
+ display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
break;
-
- for (i = 0; i < num_entries; i++) {
- switch (info_level) {
- case 1:
- display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
- break;
case 2:
display_sam_info_2(&ctr.sam.info2->sam[i], &ctr.sam.info2->str[i]);
break;
case 3:
display_sam_info_3(&ctr.sam.info3->sam[i], &ctr.sam.info3->str[i]);
break;
- case 4:
- display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
- break;
+ case 4:
+ display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
+ break;
case 5:
display_sam_info_5(&ctr.sam.info5->sam[i], &ctr.sam.info5->str[i]);
break;
- }
}
}
-
+ } while (!NT_STATUS_IS_OK(result));
done:
return result;
}
@@ -1068,53 +881,49 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 switch_level = 2;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
+ int switch_value = 2;
SAM_UNK_CTR ctr;
if (argc > 2) {
- printf("Usage: %s [info level] [access mask]\n", argv[0]);
+ printf("Usage: %s [infolevel]\n", argv[0]);
return NT_STATUS_OK;
}
- if (argc > 1)
- sscanf(argv[1], "%i", &switch_level);
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
+ if (argc == 2)
+ sscanf(argv[1], "%i", &switch_value);
/* Get sam policy handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Get domain policy handle */
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Query domain info */
result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
- switch_level, &ctr);
-
- if (!NT_STATUS_IS_OK(result))
+ switch_value, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Display domain info */
- switch (switch_level) {
+ switch (switch_value) {
case 1:
display_sam_unk_info_1(&ctr.info.inf1);
break;
@@ -1123,7 +932,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
break;
default:
printf("cannot display domain info for switch value %d\n",
- switch_level);
+ switch_value);
break;
}
@@ -1138,41 +947,37 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- const char *acct_name;
+ char *acct_name;
uint16 acb_info;
uint32 unknown, user_rid;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- if ((argc < 2) || (argc > 3)) {
- printf("Usage: %s username [access mask]\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s username\n", argv[0]);
return NT_STATUS_OK;
}
acct_name = argv[1];
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
/* Get sam policy handle */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Get domain policy handle */
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Create domain user */
@@ -1182,9 +987,9 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
acct_name, acb_info, unknown,
&user_pol, &user_rid);
-
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
done:
return result;
@@ -1194,7 +999,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol;
@@ -1215,16 +1020,17 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
/* Get sam policy and domain handles */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol);
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
@@ -1232,8 +1038,9 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
else
return NT_STATUS_OK;
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Look up names */
@@ -1247,8 +1054,9 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
flags, num_names, names,
&num_rids, &rids, &name_types);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Display results */
@@ -1264,7 +1072,7 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol;
@@ -1280,18 +1088,20 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
/* Get sam policy and domain handles */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Look up rids */
@@ -1305,8 +1115,9 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
flags, num_rids, rids,
&num_names, &names, &name_types);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Display results */
@@ -1321,34 +1132,32 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol, user_pol;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- if ((argc < 2) || (argc > 3)) {
+ if (argc != 2) {
printf("Usage: %s username\n", argv[0]);
return NT_STATUS_OK;
}
-
- if (argc > 2)
- sscanf(argv[2], "%x", &access_mask);
/* Get sam policy and domain handles */
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Get handle on user */
@@ -1361,23 +1170,26 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
&num_rids, &user_rids,
&name_types);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- access_mask,
+ MAXIMUM_ALLOWED_ACCESS,
user_rids[0], &user_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
}
/* Delete user */
result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
/* Display results */
@@ -1390,7 +1202,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
*/
static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol, *pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1401,25 +1213,25 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
SEC_DESC_BUF *sec_desc_buf=NULL;
BOOL domain = False;
- ctx=talloc_init("cmd_samr_query_sec_obj");
+ ctx=talloc_init();
- if ((argc < 1) || (argc > 2)) {
+ if (argc > 2) {
printf("Usage: %s [rid|-d]\n", argv[0]);
printf("\tSpecify rid for security on user, -d for security on domain\n");
return NT_STATUS_OK;
}
- if (argc > 1) {
+ if (argc == 2) {
if (strcmp(argv[1], "-d") == 0)
domain = True;
else
sscanf(argv[1], "%i", &user_rid);
}
-
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
- result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -1465,97 +1277,28 @@ done:
return result;
}
-static NTSTATUS cmd_samr_get_dom_pwinfo(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint16 unk_0, unk_1;
-
- if (argc != 1) {
- printf("Usage: %s\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- result = cli_samr_get_dom_pwinfo(cli, mem_ctx, &unk_0, &unk_1) ;
-
- if (NT_STATUS_IS_OK(result)) {
- printf("unk_0 = 0x%08x\n", unk_0);
- printf("unk_1 = 0x%08x\n", unk_1);
- }
-
- return result;
-}
-
-/* Look up domain name */
-
-static NTSTATUS cmd_samr_lookup_domain(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
- fstring domain_name,sid_string;
- DOM_SID sid;
-
- if (argc != 2) {
- printf("Usage: %s domain_name\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- sscanf(argv[1], "%s", domain_name);
-
- result = try_samr_connects(cli, mem_ctx, access_mask, &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- access_mask, &domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_samr_lookup_domain(
- cli, mem_ctx, &connect_pol, domain_name, &sid);
-
- sid_to_string(sid_string,&sid);
-
- if (NT_STATUS_IS_OK(result))
- printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
- domain_name,sid_string);
-
-done:
- return result;
-}
-
-
/* List of commands exported by this module */
struct cmd_set samr_commands[] = {
{ "SAMR" },
- { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, "Query user info", "" },
- { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, "Query group info", "" },
- { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, "Query user groups", "" },
- { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, "Query user aliases", "" },
- { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, "Query group membership", "" },
- { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, "Query alias membership", "" },
- { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, "Query display info", "" },
- { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, "Query domain info", "" },
- { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, "Enumerate domain users", "" },
- { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, "Enumerate domain groups", "" },
- { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, "Enumerate alias groups", "" },
-
- { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, "Create domain user", "" },
- { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, "Look up names", "" },
- { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, "Look up names", "" },
- { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, "Delete domain user", "" },
- { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, "Query SAMR security object", "" },
- { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, "Retrieve domain password info", "" },
-
- { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, "Lookup Domain Name", "" },
+ { "queryuser", cmd_samr_query_user, PIPE_SAMR, "Query user info", "" },
+ { "querygroup", cmd_samr_query_group, PIPE_SAMR, "Query group info", "" },
+ { "queryusergroups", cmd_samr_query_usergroups, PIPE_SAMR, "Query user groups", "" },
+ { "queryuseraliases", cmd_samr_query_useraliases, PIPE_SAMR, "Query user aliases", "" },
+ { "querygroupmem", cmd_samr_query_groupmem, PIPE_SAMR, "Query group membership", "" },
+ { "queryaliasmem", cmd_samr_query_aliasmem, PIPE_SAMR, "Query alias membership", "" },
+ { "querydispinfo", cmd_samr_query_dispinfo, PIPE_SAMR, "Query display info", "" },
+ { "querydominfo", cmd_samr_query_dominfo, PIPE_SAMR, "Query domain info", "" },
+ { "enumdomgroups", cmd_samr_enum_dom_groups, PIPE_SAMR, "Enumerate domain groups", "" },
+ { "enumalsgroups", cmd_samr_enum_als_groups, PIPE_SAMR, "Enumerate alias groups", "" },
+
+ { "createdomuser", cmd_samr_create_dom_user, PIPE_SAMR, "Create domain user", "" },
+ { "samlookupnames", cmd_samr_lookup_names, PIPE_SAMR, "Look up names", "" },
+ { "samlookuprids", cmd_samr_lookup_rids, PIPE_SAMR, "Look up names", "" },
+ { "deletedomuser", cmd_samr_delete_dom_user, PIPE_SAMR, "Delete domain user", "" },
+ { "samquerysecobj", cmd_samr_query_sec_obj, PIPE_SAMR, "Query SAMR security object", "" },
+
{ NULL }
};
diff --git a/source/rpcclient/cmd_shutdown.c b/source/rpcclient/cmd_shutdown.c
deleted file mode 100644
index e42ec30ac13..00000000000
--- a/source/rpcclient/cmd_shutdown.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- Copyright (C) Simo Sorce 2001,
- Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "rpcclient.h"
-
-/****************************************************************************
-nt shutdown init
-****************************************************************************/
-static NTSTATUS cmd_shutdown_init(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- fstring msg;
- uint32 timeout = 20;
- BOOL force = False;
- BOOL reboot = False;
- int opt;
-
- *msg = 0;
- optind = 0; /* TODO: test if this hack works on other systems too --simo */
-
- while ((opt = getopt(argc, argv, "m:t:rf")) != EOF)
- {
- /*fprintf (stderr, "[%s]\n", argv[argc-1]);*/
-
- switch (opt)
- {
- case 'm':
- fstrcpy(msg, optarg);
- /*fprintf (stderr, "[%s|%s]\n", optarg, msg);*/
- break;
-
- case 't':
- timeout = atoi(optarg);
- /*fprintf (stderr, "[%s|%d]\n", optarg, timeout);*/
- break;
-
- case 'r':
- reboot = True;
- break;
-
- case 'f':
- force = True;
- break;
-
- }
- }
-
- /* create an entry */
- result = cli_shutdown_init(cli, mem_ctx, msg, timeout, reboot, force);
-
- if (NT_STATUS_IS_OK(result))
- DEBUG(5,("cmd_shutdown_init: query succeeded\n"));
- else
- DEBUG(5,("cmd_shutdown_init: query failed\n"));
-
- return result;
-}
-
-/****************************************************************************
-abort a shutdown
-****************************************************************************/
-static NTSTATUS cmd_shutdown_abort(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- result = cli_shutdown_abort(cli, mem_ctx);
-
- if (NT_STATUS_IS_OK(result))
- DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
- else
- DEBUG(5,("cmd_shutdown_abort: query failed\n"));
-
- return result;
-}
-
-
-/* List of commands exported by this module */
-struct cmd_set shutdown_commands[] = {
-
- { "SHUTDOWN" },
-
- { "shutdowninit", RPC_RTYPE_NTSTATUS, cmd_shutdown_init, NULL, PI_SHUTDOWN, "Remote Shutdown (over shutdown pipe)",
- "syntax: shutdown [-m message] [-t timeout] [-r] [-h] [-f] (-r == reboot, -h == halt, -f == force)" },
-
- { "shutdownabort", RPC_RTYPE_NTSTATUS, cmd_shutdown_abort, NULL, PI_SHUTDOWN, "Abort Shutdown (over shutdown pipe)",
- "syntax: shutdownabort" },
- { NULL }
-};
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index f5a440c024c..de951741b73 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -31,31 +31,21 @@ struct table_node {
int version;
};
-static const struct table_node archi_table[]= {
+struct table_node archi_table[]= {
{"Windows 4.0", "WIN40", 0 },
{"Windows NT x86", "W32X86", 2 },
- {"Windows NT x86", "W32X86", 3 },
{"Windows NT R4000", "W32MIPS", 2 },
{"Windows NT Alpha_AXP", "W32ALPHA", 2 },
{"Windows NT PowerPC", "W32PPC", 2 },
{NULL, "", -1 }
};
-/**
- * @file
- *
- * rpcclient module for SPOOLSS rpc pipe.
- *
- * This generally just parses and checks command lines, and then calls
- * a cli_spoolss function.
- **/
-
/****************************************************************************
function to do the mapping between the long architecture name and
the short one.
****************************************************************************/
-static const char *cmd_spoolss_get_short_archi(const char *long_archi)
+BOOL get_short_archi(char *short_archi, const char *long_archi)
{
int i=-1;
@@ -67,61 +57,63 @@ static const char *cmd_spoolss_get_short_archi(const char *long_archi)
if (archi_table[i].long_archi==NULL) {
DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
- return NULL;
+ return False;
}
- /* this might be client code - but shouldn't this be an fstrcpy etc? */
-
+ StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
+ DEBUGADD(108,("long architecture: [%s]\n", long_archi));
+ DEBUGADD(108,("short architecture: [%s]\n", short_archi));
- return archi_table[i].short_archi;
+ return True;
}
-#if 0
+
/**********************************************************************
* dummy function -- placeholder
*/
-static WERROR cmd_spoolss_not_implemented(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_not_implemented(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
printf ("(*) This command is not currently implemented.\n");
- return WERR_OK;
+ return NT_STATUS_OK;
}
-#endif
/***********************************************************************
* Get printer information
*/
-static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_open_printer_ex(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR werror;
- fstring printername;
+ pstring printername;
fstring servername, user;
POLICY_HND hnd;
-
- if (argc != 2) {
- printf("Usage: %s <printername>\n", argv[0]);
- return WERR_OK;
+ uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
+
+ if (argc != 2 && argc != 3) {
+ printf("Usage: %s <printername> [0xallowed_access]\n", argv[0]);
+ return NT_STATUS_OK;
}
if (!cli)
- return WERR_GENERAL_FAILURE;
+ return NT_STATUS_UNSUCCESSFUL;
+
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ fstrcpy (user, cli->user_name);
+ fstrcpy (printername, argv[1]);
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- fstrcpy(printername, argv[1]);
+ if (argc == 3)
+ desired_access = strtol(argv[2], NULL, 16);
/* Open the printer handle */
werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", PRINTER_ALL_ACCESS,
+ "", desired_access,
servername, user, &hnd);
if (W_ERROR_IS_OK(werror)) {
@@ -130,11 +122,14 @@ static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
if (!W_ERROR_IS_OK(werror)) {
printf("Error closing printer handle! (%s)\n",
- get_dos_error_msg(werror));
+ dos_errstr(werror));
}
+ } else {
+ printf("Failed to open printer %s: %s\n", printername,
+ dos_errstr(werror));
}
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -149,9 +144,11 @@ static void display_print_info_0(PRINTER_INFO_0 *i0)
if (!i0)
return;
- rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
+ if (i0->printername.buffer)
+ rpcstr_pull(name, i0->printername.buffer, sizeof(name), 0, STR_TERMINATE);
- rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
+ if (i0->servername.buffer)
+ rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), 0,STR_TERMINATE);
printf("\tprintername:[%s]\n", name);
printf("\tservername:[%s]\n", servername);
@@ -192,7 +189,7 @@ static void display_print_info_0(PRINTER_INFO_0 *i0)
printf("\tunknown27:[0x%x]\n", i0->unknown27);
printf("\tunknown28:[0x%x]\n", i0->unknown28);
printf("\tunknown29:[0x%x]\n", i0->unknown29);
-
+
printf("\n");
}
@@ -205,11 +202,17 @@ static void display_print_info_1(PRINTER_INFO_1 *i1)
fstring name = "";
fstring comm = "";
- rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
- STR_TERMINATE);
+ if (i1->description.buffer)
+ rpcstr_pull(desc, i1->description.buffer, sizeof(desc), 0,
+ STR_TERMINATE);
+
+ if (i1->name.buffer)
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0,
+ STR_TERMINATE);
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
- rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
+ if (i1->comment.buffer)
+ rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), 0,
+ STR_TERMINATE);
printf("\tflags:[0x%x]\n", i1->flags);
printf("\tname:[%s]\n", name);
@@ -236,27 +239,38 @@ static void display_print_info_2(PRINTER_INFO_2 *i2)
fstring datatype = "";
fstring parameters = "";
- rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
+ if (i2->servername.buffer)
+ rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), 0, STR_TERMINATE);
- rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
+ if (i2->printername.buffer)
+ rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), 0, STR_TERMINATE);
- rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
+ if (i2->sharename.buffer)
+ rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), 0, STR_TERMINATE);
- rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
+ if (i2->portname.buffer)
+ rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), 0, STR_TERMINATE);
- rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
+ if (i2->drivername.buffer)
+ rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), 0, STR_TERMINATE);
- rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
+ if (i2->comment.buffer)
+ rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), 0, STR_TERMINATE);
- rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
+ if (i2->location.buffer)
+ rpcstr_pull(location, i2->location.buffer,sizeof(location), 0, STR_TERMINATE);
- rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
+ if (i2->sepfile.buffer)
+ rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), 0, STR_TERMINATE);
- rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
+ if (i2->printprocessor.buffer)
+ rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), 0, STR_TERMINATE);
- rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
+ if (i2->datatype.buffer)
+ rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), 0, STR_TERMINATE);
- rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
+ if (i2->parameters.buffer)
+ rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), 0, STR_TERMINATE);
printf("\tservername:[%s]\n", servername);
printf("\tprintername:[%s]\n", printername);
@@ -298,30 +312,23 @@ static void display_print_info_3(PRINTER_INFO_3 *i3)
/* Enumerate printers */
-static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
uint32 info_level = 1;
PRINTER_INFO_CTR ctr;
uint32 i = 0, num_printers, needed;
- fstring name;
- if (argc > 3)
+ if (argc > 2)
{
- printf("Usage: %s [level] [name]\n", argv[0]);
- return WERR_OK;
+ printf("Usage: %s [level]\n", argv[0]);
+ return NT_STATUS_OK;
}
- if (argc == 2)
+ if (argc == 2) {
info_level = atoi(argv[1]);
-
- if (argc == 3)
- fstrcpy(name, argv[2]);
- else {
- slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
- strupper_m(name);
}
/* Enumerate printers -- Should we enumerate types other
@@ -330,12 +337,12 @@ static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
ZERO_STRUCT(ctr);
result = cli_spoolss_enum_printers(
- cli, mem_ctx, 0, &needed, name, PRINTER_ENUM_LOCAL,
+ cli, mem_ctx, 0, &needed, PRINTER_ENUM_LOCAL,
info_level, &num_printers, &ctr);
if (W_ERROR_V(result) == ERRinsufficientbuffer)
result = cli_spoolss_enum_printers(
- cli, mem_ctx, needed, NULL, name, PRINTER_ENUM_LOCAL,
+ cli, mem_ctx, needed, NULL, PRINTER_ENUM_LOCAL,
info_level, &num_printers, &ctr);
if (W_ERROR_IS_OK(result)) {
@@ -346,28 +353,28 @@ static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
}
for (i = 0; i < num_printers; i++) {
- switch(info_level) {
- case 0:
+ switch(info_level) {
+ case 0:
display_print_info_0(&ctr.printers_0[i]);
- break;
- case 1:
+ break;
+ case 1:
display_print_info_1(&ctr.printers_1[i]);
- break;
- case 2:
+ break;
+ case 2:
display_print_info_2(&ctr.printers_2[i]);
- break;
- case 3:
+ break;
+ case 3:
display_print_info_3(&ctr.printers_3[i]);
- break;
- default:
- printf("unknown info level %d\n", info_level);
+ break;
+ default:
+ printf("unknown info level %d\n", info_level);
goto done;
}
}
}
done:
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/****************************************************************************
@@ -377,7 +384,7 @@ static void display_port_info_1(PORT_INFO_1 *i1)
{
fstring buffer;
- rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
+ rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tPort Name:\t[%s]\n", buffer);
}
@@ -388,48 +395,24 @@ static void display_port_info_2(PORT_INFO_2 *i2)
{
fstring buffer;
- rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
+ rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tPort Name:\t[%s]\n", buffer);
- rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
+ rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tMonitor Name:\t[%s]\n", buffer);
- rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
+ rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tDescription:\t[%s]\n", buffer);
- printf("\tPort Type:\t" );
- if ( i2->port_type ) {
- int comma = 0; /* hack */
- printf( "[" );
- if ( i2->port_type & PORT_TYPE_READ ) {
- printf( "Read" );
- comma = 1;
- }
- if ( i2->port_type & PORT_TYPE_WRITE ) {
- printf( "%sWrite", comma ? ", " : "" );
- comma = 1;
- }
- /* These two have slightly different interpretations
- on 95/98/ME but I'm disregarding that for now */
- if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
- printf( "%sRedirected", comma ? ", " : "" );
- comma = 1;
- }
- if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
- printf( "%sNet-Attached", comma ? ", " : "" );
- }
- printf( "]\n" );
- } else {
- printf( "[Unset]\n" );
- }
+ printf("\tPort Type:\t[%d]\n", i2->port_type);
printf("\tReserved:\t[%d]\n", i2->reserved);
printf("\n");
}
/* Enumerate ports */
-static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_enum_ports(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
WERROR result;
uint32 needed, info_level = 1;
@@ -438,7 +421,7 @@ static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
if (argc > 2) {
printf("Usage: %s [level]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
if (argc == 2)
@@ -462,7 +445,7 @@ static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
switch (info_level) {
case 1:
display_port_info_1(&ctr.port.info_1[i]);
- break;
+ break;
case 2:
display_port_info_2(&ctr.port.info_2[i]);
break;
@@ -472,16 +455,16 @@ static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
}
}
}
-
- return result;
+
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/***********************************************************************
* Set printer comment - use a level2 set.
*/
-static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_setprinter(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND pol;
WERROR result;
@@ -489,15 +472,15 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
uint32 info_level = 2;
BOOL opened_hnd = False;
PRINTER_INFO_CTR ctr;
- fstring printername,
+ fstring printername,
servername,
user,
comment;
if (argc == 1 || argc > 3) {
printf("Usage: %s printername comment\n", argv[0]);
-
- return WERR_OK;
+
+ return NT_STATUS_OK;
}
/* Open a printer handle */
@@ -505,19 +488,19 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
fstrcpy(comment, argv[2]);
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(printername, argv[1]);
- fstrcpy(user, cli->user_name);
-
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ fstrcpy (printername, argv[1]);
+ fstrcpy (user, cli->user_name);
+
/* get a printer handle */
result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- PRINTER_ALL_ACCESS, servername,
- user, &pol);
+ MAXIMUM_ALLOWED_ACCESS, servername,
+ user, &pol);
if (!W_ERROR_IS_OK(result))
goto done;
-
+
opened_hnd = True;
/* Get printer info */
@@ -527,7 +510,7 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, info_level, &ctr);
if (!W_ERROR_IS_OK(result))
- goto done;
+ goto done;
/* Modify the comment. */
@@ -535,37 +518,37 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
ctr.printers_2->devmode = NULL;
ctr.printers_2->secdesc = NULL;
- result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
if (W_ERROR_IS_OK(result))
printf("Success in setting comment.\n");
- done:
- if (opened_hnd)
+ done:
+ if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/***********************************************************************
* Get printer information
*/
-static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_getprinter(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND pol;
WERROR result;
uint32 info_level = 1;
BOOL opened_hnd = False;
PRINTER_INFO_CTR ctr;
- fstring printername,
+ fstring printername,
servername,
user;
uint32 needed;
if (argc == 1 || argc > 3) {
printf("Usage: %s <printername> [level]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Open a printer handle */
@@ -573,10 +556,10 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
info_level = atoi(argv[2]);
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
- fstrcpy(user, cli->user_name);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
+ fstrcpy (user, cli->user_name);
/* get a printer handle */
@@ -625,190 +608,7 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- return result;
-}
-
-static void display_reg_value(REGISTRY_VALUE value)
-{
- pstring text;
-
- switch(value.type) {
- case REG_DWORD:
- printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
- *((uint32 *) value.data_p));
- break;
- case REG_SZ:
- rpcstr_pull(text, value.data_p, sizeof(text), value.size,
- STR_TERMINATE);
- printf("%s: REG_SZ: %s\n", value.valuename, text);
- break;
- case REG_BINARY:
- printf("%s: REG_BINARY: unknown length value not displayed\n",
- value.valuename);
- break;
- case REG_MULTI_SZ: {
- uint16 *curstr = (uint16 *) value.data_p;
- uint8 *start = value.data_p;
- printf("%s: REG_MULTI_SZ:\n", value.valuename);
- while ((*curstr != 0) &&
- ((uint8 *) curstr < start + value.size)) {
- rpcstr_pull(text, curstr, sizeof(text), -1,
- STR_TERMINATE);
- printf(" %s\n", text);
- curstr += strlen(text) + 1;
- }
- }
- break;
- default:
- printf("%s: unknown type %d\n", value.valuename, value.type);
- }
-
-}
-
-/***********************************************************************
- * Get printer data
- */
-static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- POLICY_HND pol;
- WERROR result;
- BOOL opened_hnd = False;
- fstring printername,
- servername,
- user;
- uint32 needed;
- const char *valuename;
- REGISTRY_VALUE value;
-
- if (argc != 3) {
- printf("Usage: %s <printername> <valuename>\n", argv[0]);
- printf("<printername> of . queries print server\n");
- return WERR_OK;
- }
- valuename = argv[2];
-
- /* Open a printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- if (strncmp(argv[1], ".", sizeof(".")) == 0)
- fstrcpy(printername, servername);
- else
- slprintf(printername, sizeof(servername)-1, "%s\\%s",
- servername, argv[1]);
- fstrcpy(user, cli->user_name);
-
- /* get a printer handle */
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &pol);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- opened_hnd = True;
-
- /* Get printer info */
-
- result = cli_spoolss_getprinterdata(cli, mem_ctx, 0, &needed,
- &pol, valuename, &value);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_getprinterdata(
- cli, mem_ctx, needed, NULL, &pol, valuename, &value);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* Display printer data */
-
- fstrcpy(value.valuename, valuename);
- display_reg_value(value);
-
-
- done:
- if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
-
- return result;
-}
-
-/***********************************************************************
- * Get printer data
- */
-static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- POLICY_HND pol;
- WERROR result;
- BOOL opened_hnd = False;
- fstring printername,
- servername,
- user;
- uint32 needed;
- const char *valuename, *keyname;
- REGISTRY_VALUE value;
-
- if (argc != 4) {
- printf("Usage: %s <printername> <keyname> <valuename>\n",
- argv[0]);
- printf("<printername> of . queries print server\n");
- return WERR_OK;
- }
- valuename = argv[3];
- keyname = argv[2];
-
- /* Open a printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- if (strncmp(argv[1], ".", sizeof(".")) == 0)
- fstrcpy(printername, servername);
- else
- slprintf(printername, sizeof(printername)-1, "%s\\%s",
- servername, argv[1]);
- fstrcpy(user, cli->user_name);
-
- /* get a printer handle */
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &pol);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- opened_hnd = True;
-
- /* Get printer info */
-
- result = cli_spoolss_getprinterdataex(cli, mem_ctx, 0, &needed,
- &pol, keyname, valuename,
- &value);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_getprinterdataex(cli, mem_ctx, needed,
- NULL, &pol, keyname,
- valuename, &value);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* Display printer data */
-
- fstrcpy(value.valuename, valuename);
- display_reg_value(value);
-
-
- done:
- if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
-
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/****************************************************************************
@@ -820,7 +620,7 @@ static void display_print_driver_1(DRIVER_INFO_1 *i1)
if (i1 == NULL)
return;
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
printf ("Printer Driver Info 1:\n");
printf ("\tDriver Name: [%s]\n\n", name);
@@ -841,11 +641,11 @@ static void display_print_driver_2(DRIVER_INFO_2 *i1)
if (i1 == NULL)
return;
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
- rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
- rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
- rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
- rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
printf ("Printer Driver Info 2:\n");
printf ("\tVersion: [%x]\n", i1->version);
@@ -863,15 +663,15 @@ printer info level 2 display function
****************************************************************************/
static void display_print_driver_3(DRIVER_INFO_3 *i1)
{
- fstring name = "";
- fstring architecture = "";
- fstring driverpath = "";
- fstring datafile = "";
- fstring configfile = "";
- fstring helpfile = "";
- fstring dependentfiles = "";
- fstring monitorname = "";
- fstring defaultdatatype = "";
+ fstring name;
+ fstring architecture;
+ fstring driverpath;
+ fstring datafile;
+ fstring configfile;
+ fstring helpfile;
+ fstring dependentfiles;
+ fstring monitorname;
+ fstring defaultdatatype;
int length=0;
BOOL valid = True;
@@ -879,14 +679,14 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
if (i1 == NULL)
return;
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
- rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
- rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
- rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
- rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
- rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
- rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
- rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
+ rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), 0, STR_TERMINATE);
+ rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), 0, STR_TERMINATE);
+ rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), 0, STR_TERMINATE);
printf ("Printer Driver Info 3:\n");
printf ("\tVersion: [%x]\n", i1->version);
@@ -899,7 +699,7 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
while (valid)
{
- rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
+ rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), 0, STR_TERMINATE);
length+=strlen(dependentfiles)+1;
@@ -924,12 +724,13 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
/***********************************************************************
* Get printer information
*/
-static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
POLICY_HND pol;
WERROR werror;
+ NTSTATUS result;
uint32 info_level = 3;
BOOL opened_hnd = False;
PRINTER_DRIVER_CTR ctr;
@@ -937,19 +738,18 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
servername,
user;
uint32 i;
- BOOL success = False;
if ((argc == 1) || (argc > 3))
{
printf("Usage: %s <printername> [level]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* get the arguments need to open the printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- fstrcpy(printername, argv[1]);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ fstrcpy (user, cli->user_name);
+ fstrcpy (printername, argv[1]);
if (argc == 3)
info_level = atoi(argv[2]);
@@ -959,9 +759,11 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
PRINTER_ACCESS_USE,
servername, user, &pol);
- if (!W_ERROR_IS_OK(werror)) {
+ result = W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+
+ if (!NT_STATUS_IS_OK(result)) {
printf("Error opening printer handle for %s!\n", printername);
- return werror;
+ return result;
}
opened_hnd = True;
@@ -973,25 +775,18 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
werror = cli_spoolss_getprinterdriver(
cli, mem_ctx, 0, &needed, &pol, info_level,
- archi_table[i].long_archi, archi_table[i].version,
- &ctr);
+ archi_table[i].long_archi, &ctr);
- if (W_ERROR_V(werror) == ERRinsufficientbuffer) {
+ if (W_ERROR_V(werror) == ERRinsufficientbuffer)
werror = cli_spoolss_getprinterdriver(
cli, mem_ctx, needed, NULL, &pol, info_level,
- archi_table[i].long_archi, archi_table[i].version,
- &ctr);
- }
+ archi_table[i].long_archi, &ctr);
if (!W_ERROR_IS_OK(werror))
continue;
-
- /* need at least one success */
-
- success = True;
printf ("\n[%s]\n", archi_table[i].long_archi);
-
+
switch (info_level) {
case 1:
display_print_driver_1 (ctr.info1);
@@ -1013,18 +808,15 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
if (opened_hnd)
cli_spoolss_close_printer (cli, mem_ctx, &pol);
- if ( success )
- werror = WERR_OK;
-
- return werror;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/***********************************************************************
* Get printer information
*/
-static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_enum_drivers(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR werror;
uint32 info_level = 1;
@@ -1035,7 +827,7 @@ static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
if (argc > 2)
{
printf("Usage: enumdrivers [level]\n");
- return WERR_OK;
+ return NT_STATUS_OK;
}
if (argc == 2)
@@ -1090,7 +882,7 @@ static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
}
}
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/****************************************************************************
@@ -1102,7 +894,7 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
if (i1 == NULL)
return;
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
printf ("\tDirectory Name:[%s]\n", name);
}
@@ -1110,9 +902,9 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
/***********************************************************************
* Get printer driver directory information
*/
-static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
fstring env;
@@ -1121,7 +913,7 @@ static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
if (argc > 2) {
printf("Usage: %s [environment]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get the arguments need to open the printer handle */
@@ -1139,11 +931,11 @@ static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
if (W_ERROR_V(result) == ERRinsufficientbuffer)
result = cli_spoolss_getprinterdriverdir(
cli, mem_ctx, needed, NULL, 1, env, &ctr);
-
+
if (W_ERROR_IS_OK(result))
display_printdriverdir_1(ctr.info1);
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/*******************************************************************************
@@ -1177,7 +969,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
wrapper for strtok to get the next parameter from a delimited list.
Needed to handle the empty parameter string denoted by "NULL"
*************************************************************************/
-static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
+static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
{
char *ptr;
@@ -1188,7 +980,7 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des
parameter because two consecutive delimiters
will not return an empty string. See man strtok(3)
for details */
- if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
+ if (StrCaseCmp(ptr, "NULL") == 0)
ptr = NULL;
if (dest != NULL)
@@ -1207,7 +999,7 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des
static BOOL init_drv_info_3_members (
TALLOC_CTX *mem_ctx,
DRIVER_INFO_3 *info,
- const char *args
+ char *args
)
{
char *str, *str2;
@@ -1246,7 +1038,7 @@ static BOOL init_drv_info_3_members (
}
for (i=0; i<len; i++)
{
- SSVAL(&info->dependentfiles[i], 0, str2[i]);
+ info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
}
info->dependentfiles[len] = '\0';
@@ -1254,35 +1046,34 @@ static BOOL init_drv_info_3_members (
}
-static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
uint32 level = 3;
PRINTER_DRIVER_CTR ctr;
DRIVER_INFO_3 info3;
- const char *arch;
+ fstring arch;
fstring driver_name;
/* parse the command arguements */
- if (argc != 3 && argc != 4)
+ if (argc != 3)
{
- printf ("Usage: %s <Environment> \\\n", argv[0]);
+ printf ("Usage: %s <Environment>\\\n", argv[0]);
printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
- printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
- printf ("\t[version]\n");
+ printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Fill in the DRIVER_INFO_3 struct */
ZERO_STRUCT(info3);
- if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
+ if (!get_short_archi(arch, argv[1]))
{
printf ("Error Unknown architechture [%s]\n", argv[1]);
- return WERR_INVALID_PARAM;
+ return NT_STATUS_INVALID_PARAMETER;
}
else
set_drv_info_3_env(&info3, arch);
@@ -1290,15 +1081,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
{
printf ("Error Invalid parameter list - %s.\n", argv[2]);
- return WERR_INVALID_PARAM;
- }
-
- /* if printer driver version specified, override the default version
- * used by the architecture. This allows installation of Windows
- * 2000 (version 3) printer drivers. */
- if (argc == 4)
- {
- info3.version = atoi(argv[3]);
+ return NT_STATUS_INVALID_PARAMETER;
}
@@ -1307,18 +1090,18 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
if (W_ERROR_IS_OK(result)) {
rpcstr_pull(driver_name, info3.name.buffer,
- sizeof(driver_name), -1, STR_TERMINATE);
+ sizeof(driver_name), 0, STR_TERMINATE);
printf ("Printer Driver %s successfully installed.\n",
driver_name);
}
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
WERROR result;
uint32 level = 2;
@@ -1330,13 +1113,13 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
if (argc != 5)
{
printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
- /* Fill in the DRIVER_INFO_2 struct */
+ /* Fill in the DRIVER_INFO_3 struct */
ZERO_STRUCT(info2);
#if 0 /* JERRY */
init_unistr( &info2.servername, servername);
@@ -1368,14 +1151,13 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
if (W_ERROR_IS_OK(result))
- printf ("Printer %s successfully installed.\n", argv[1]);
+ printf ("Printer %s successfully installed.\n", argv[1]);
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND pol;
WERROR result;
@@ -1392,17 +1174,17 @@ static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
if (argc != 3)
{
printf ("Usage: %s <printer> <driver>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
- fstrcpy(user, cli->user_name);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
+ fstrcpy (user, cli->user_name);
/* Get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ALL_ACCESS,
servername, user, &pol);
@@ -1416,12 +1198,10 @@ static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
ZERO_STRUCT (info2);
ctr.printers_2 = &info2;
- result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
- &pol, level, &ctr);
+ result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed, &pol, level, &ctr);
if (W_ERROR_V(result) == ERRinsufficientbuffer)
- result = cli_spoolss_getprinter(
- cli, mem_ctx, needed, NULL, &pol, level, &ctr);
+ result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, level, &ctr);
if (!W_ERROR_IS_OK(result)) {
printf ("Unable to retrieve printer information!\n");
@@ -1447,13 +1227,13 @@ done:
if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
fstring servername;
@@ -1463,11 +1243,11 @@ static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
if (argc != 2)
{
printf ("Usage: %s <driver>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
/* delete the driver for all architectures */
for (i=0; archi_table[i].long_archi; i++)
@@ -1490,12 +1270,12 @@ static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
}
}
- return result;
+ return W_ERROR_IS_OK(result) || W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
char *servername = NULL, *environment = NULL;
@@ -1505,17 +1285,17 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
/* parse the command arguements */
if (argc > 2) {
printf ("Usage: %s [environment]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
- return WERR_NOMEM;
- strupper_m(servername);
+ return NT_STATUS_NO_MEMORY;
+ strupper(servername);
if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
- PRINTER_DRIVER_ARCHITECTURE) < 0) {
+ PRINTER_DRIVER_ARCHITECTURE) < 0) {
SAFE_FREE(servername);
- return WERR_NOMEM;
+ return NT_STATUS_NO_MEMORY;
}
result = cli_spoolss_getprintprocessordirectory(
@@ -1532,13 +1312,13 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
SAFE_FREE(servername);
SAFE_FREE(environment);
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* Add a form */
-static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND handle;
WERROR werror;
@@ -1550,13 +1330,13 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc != 3) {
printf ("Usage: %s <printer> <formname>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get a printer handle */
asprintf(&servername, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ strupper(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
@@ -1577,7 +1357,7 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
form.right = 20;
form.bottom = 30;
- init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
+ init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
/* Add the form */
@@ -1591,13 +1371,13 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAFE_FREE(servername);
SAFE_FREE(printername);
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* Set a form */
-static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND handle;
WERROR werror;
@@ -1609,13 +1389,13 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc != 3) {
printf ("Usage: %s <printer> <formname>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get a printer handle */
asprintf(&servername, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ strupper(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(
@@ -1636,7 +1416,7 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
form.right = 2000;
form.bottom = 3000;
- init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
+ init_unistr2(&form.name, argv[2], strlen(argv[2]) + 1);
/* Set the form */
@@ -1649,13 +1429,13 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAFE_FREE(servername);
SAFE_FREE(printername);
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* Get a form */
-static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND handle;
WERROR werror;
@@ -1668,13 +1448,13 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc != 3) {
printf ("Usage: %s <printer> <formname>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get a printer handle */
asprintf(&servername, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ strupper(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(
@@ -1712,14 +1492,14 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAFE_FREE(servername);
SAFE_FREE(printername);
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* Delete a form */
-static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_deleteform(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND handle;
WERROR werror;
@@ -1730,13 +1510,13 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
if (argc != 3) {
printf ("Usage: %s <printer> <formname>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get a printer handle */
asprintf(&servername, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ strupper(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(
@@ -1759,14 +1539,14 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
SAFE_FREE(servername);
SAFE_FREE(printername);
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* Enumerate forms */
-static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_enum_forms(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+ char **argv)
{
POLICY_HND handle;
WERROR werror;
@@ -1779,13 +1559,13 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
if (argc != 2) {
printf ("Usage: %s <printer>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
/* Get a printer handle */
asprintf(&servername, "\\\\%s", cli->desthost);
- strupper_m(servername);
+ strupper(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(
@@ -1817,7 +1597,7 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
if (forms[i].name.buffer)
rpcstr_pull(form_name, forms[i].name.buffer,
- sizeof(form_name), -1, STR_TERMINATE);
+ sizeof(form_name), 0, STR_TERMINATE);
printf("%s\n", form_name);
}
@@ -1829,12 +1609,12 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
SAFE_FREE(servername);
SAFE_FREE(printername);
- return werror;
+ return W_ERROR_IS_OK(werror) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
+static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
WERROR result;
uint32 needed;
@@ -1842,19 +1622,18 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
POLICY_HND pol;
BOOL opened_hnd = False;
PRINTER_INFO_CTR ctr;
- PRINTER_INFO_0 info;
- REGISTRY_VALUE value;
+ PRINTER_INFO_0 *info = NULL;
/* parse the command arguements */
if (argc != 4) {
printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
- fstrcpy(user, cli->user_name);
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
+ fstrcpy (user, cli->user_name);
/* get a printer handle */
result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
@@ -1864,30 +1643,23 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
goto done;
opened_hnd = True;
-
- ctr.printers_0 = &info;
-
+
result = cli_spoolss_getprinter(cli, mem_ctx, 0, &needed,
&pol, 0, &ctr);
if (W_ERROR_V(result) == ERRinsufficientbuffer)
result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
-
+
if (!W_ERROR_IS_OK(result))
- goto done;
+ goto done;
printf("%s\n", timestring(True));
- printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
+ printf("\tchange_id (before set)\t:[0x%x]\n", info->change_id);
+
/* Set the printer data */
- fstrcpy(value.valuename, argv[2]);
- value.type = REG_SZ;
- value.size = strlen(argv[3]) + 1;
- value.data_p = talloc_memdup(mem_ctx, argv[3], value.size);
-
- result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
-
+ result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, argv[2], argv[3]);
if (!W_ERROR_IS_OK(result)) {
printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
goto done;
@@ -1900,405 +1672,17 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
result = cli_spoolss_getprinter(cli, mem_ctx, needed, NULL, &pol, 0, &ctr);
if (!W_ERROR_IS_OK(result))
- goto done;
+ goto done;
printf("%s\n", timestring(True));
- printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
+ printf("\tchange_id (after set)\t:[0x%x]\n", info->change_id);
done:
/* cleanup */
if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- return result;
-}
-
-static void display_job_info_1(JOB_INFO_1 *job)
-{
- fstring username = "", document = "", text_status = "";
-
- rpcstr_pull(username, job->username.buffer,
- sizeof(username), -1, STR_TERMINATE);
-
- rpcstr_pull(document, job->document.buffer,
- sizeof(document), -1, STR_TERMINATE);
-
- rpcstr_pull(text_status, job->text_status.buffer,
- sizeof(text_status), -1, STR_TERMINATE);
-
- printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
- username, document, text_status, job->pagesprinted,
- job->totalpages);
-}
-
-static void display_job_info_2(JOB_INFO_2 *job)
-{
- fstring username = "", document = "", text_status = "";
-
- rpcstr_pull(username, job->username.buffer,
- sizeof(username), -1, STR_TERMINATE);
-
- rpcstr_pull(document, job->document.buffer,
- sizeof(document), -1, STR_TERMINATE);
-
- rpcstr_pull(text_status, job->text_status.buffer,
- sizeof(text_status), -1, STR_TERMINATE);
-
- printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
- username, document, text_status, job->pagesprinted,
- job->totalpages, job->size);
-}
-
-/* Enumerate jobs */
-
-static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- WERROR result;
- uint32 needed, level = 1, num_jobs, i;
- BOOL got_hnd = False;
- pstring printername;
- fstring servername, user;
- POLICY_HND hnd;
- JOB_INFO_CTR ctr;
-
- if (argc < 2 || argc > 3) {
- printf("Usage: %s printername [level]\n", argv[0]);
- return WERR_OK;
- }
-
- if (argc == 3)
- level = atoi(argv[2]);
-
- /* Open printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
- strupper_m(printername);
- pstrcat(printername, argv[1]);
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- got_hnd = True;
-
- /* Enumerate ports */
-
- result = cli_spoolss_enumjobs(
- cli, mem_ctx, 0, &needed, &hnd, level, 0, 1000,
- &num_jobs, &ctr);
-
- if (W_ERROR_V(result) == ERRinsufficientbuffer)
- result = cli_spoolss_enumjobs(
- cli, mem_ctx, needed, NULL, &hnd, level, 0,
- 1000, &num_jobs, &ctr);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- for (i = 0; i < num_jobs; i++) {
- switch(level) {
- case 1:
- display_job_info_1(&ctr.job.job_info_1[i]);
- break;
- case 2:
- display_job_info_2(&ctr.job.job_info_2[i]);
- break;
- default:
- d_printf("unknown info level %d\n", level);
- break;
- }
- }
-
-done:
- if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
-
- return result;
-}
-
-/* enumerate data */
-
-static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- WERROR result;
- uint32 i=0, val_needed, data_needed;
- BOOL got_hnd = False;
- pstring printername;
- fstring servername, user;
- POLICY_HND hnd;
-
- if (argc != 2) {
- printf("Usage: %s printername\n", argv[0]);
- return WERR_OK;
- }
-
- /* Open printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
- strupper_m(printername);
- pstrcat(printername, argv[1]);
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- got_hnd = True;
-
- /* Enumerate data */
-
- result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
- &val_needed, &data_needed,
- NULL);
- while (W_ERROR_IS_OK(result)) {
- REGISTRY_VALUE value;
- result = cli_spoolss_enumprinterdata(
- cli, mem_ctx, &hnd, i++, val_needed,
- data_needed, 0, 0, &value);
- if (W_ERROR_IS_OK(result))
- display_reg_value(value);
- }
- if (W_ERROR_V(result) == ERRnomoreitems)
- result = W_ERROR(ERRsuccess);
-
-done:
- if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
-
- return result;
-}
-
-/* enumerate data for a given key */
-
-static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- WERROR result;
- uint32 needed, i;
- BOOL got_hnd = False;
- pstring printername;
- fstring servername, user;
- const char *keyname = NULL;
- POLICY_HND hnd;
- REGVAL_CTR ctr;
-
- if (argc != 3) {
- printf("Usage: %s printername <keyname>\n", argv[0]);
- return WERR_OK;
- }
-
- keyname = argv[2];
-
- /* Open printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
- strupper_m(printername);
- pstrcat(printername, argv[1]);
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- got_hnd = True;
-
- /* Enumerate subkeys */
-
- result = cli_spoolss_enumprinterdataex(
- cli, mem_ctx, 0, &needed, &hnd, keyname, NULL);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_enumprinterdataex(
- cli, mem_ctx, needed, NULL, &hnd, keyname, &ctr);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- for (i=0; i < ctr.num_values; i++) {
- display_reg_value(*(ctr.values[i]));
- }
-
- regval_ctr_destroy(&ctr);
-
-done:
- if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
-
- return result;
-}
-
-/* enumerate subkeys */
-
-static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- WERROR result;
- uint32 needed, returned;
- BOOL got_hnd = False;
- pstring printername;
- fstring servername, user;
- const char *keyname = NULL;
- POLICY_HND hnd;
- uint16 *keylist = NULL, *curkey;
-
- if (argc < 2 || argc > 3) {
- printf("Usage: %s printername [keyname]\n", argv[0]);
- return WERR_OK;
- }
-
- if (argc == 3)
- keyname = argv[2];
- else
- keyname = "";
-
- /* Open printer handle */
-
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
- strupper_m(servername);
- fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
- strupper_m(printername);
- pstrcat(printername, argv[1]);
-
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
- "", MAXIMUM_ALLOWED_ACCESS,
- servername, user, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- got_hnd = True;
-
- /* Enumerate subkeys */
-
- result = cli_spoolss_enumprinterkey(
- cli, mem_ctx, 0, &needed, &hnd, keyname, NULL, NULL);
-
- if (W_ERROR_V(result) == ERRmoredata)
- result = cli_spoolss_enumprinterkey(
- cli, mem_ctx, needed, NULL, &hnd, keyname, &keylist,
- &returned);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- curkey = keylist;
- while (*curkey != 0) {
- pstring subkey;
- rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
- STR_TERMINATE);
- printf("%s\n", subkey);
- curkey += strlen(subkey) + 1;
- }
-
- safe_free(keylist);
-
-done:
- if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
-
- return result;
-}
-
-static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
-{
- fstring servername, printername;
- POLICY_HND hnd;
- BOOL got_hnd = False;
- WERROR result;
- SPOOL_NOTIFY_OPTION option;
-
- if (argc != 2) {
- printf("Usage: %s printername\n", argv[0]);
- result = WERR_OK;
- goto done;
- }
-
- /* Open printer */
-
- slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
- strupper_m(servername);
-
- slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
- argv[1]);
- strupper_m(printername);
-
- result = cli_spoolss_open_printer_ex(
- cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
- servername, cli->user_name, &hnd);
-
- if (!W_ERROR_IS_OK(result)) {
- printf("Error opening %s\n", argv[1]);
- goto done;
- }
-
- got_hnd = True;
-
- /* Create spool options */
-
- ZERO_STRUCT(option);
-
- option.version = 2;
- option.option_type_ptr = 1;
- option.count = option.ctr.count = 2;
-
- option.ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)talloc(
- mem_ctx, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * 2);
-
- ZERO_STRUCT(option.ctr.type[0]);
- option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
- option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
- option.ctr.type[0].fields_ptr = 1;
- option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
-
- ZERO_STRUCT(option.ctr.type[1]);
- option.ctr.type[1].type = JOB_NOTIFY_TYPE;
- option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
- option.ctr.type[1].fields_ptr = 1;
- option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
-
- /* Send rffpcnex */
-
- slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
- strupper_m(servername);
-
- result = cli_spoolss_rffpcnex(
- cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
-
- if (!W_ERROR_IS_OK(result)) {
- printf("Error rffpcnex %s\n", argv[1]);
- goto done;
- }
-
-done:
- if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
-
- return result;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/* List of commands exported by this module */
@@ -2306,33 +1690,29 @@ struct cmd_set spoolss_commands[] = {
{ "SPOOLSS" },
- { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
- { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
- { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
- { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
- { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
- { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
- { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
- { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
- { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
- { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
- { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
- { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
- { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
- { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
- { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
- { "getprintprocdir",RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
- { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
- { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
- { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
- { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
- { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
- { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
- { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
- { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
- { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
- { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
- { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },
+ { "adddriver", cmd_spoolss_addprinterdriver, PIPE_SPOOLSS, "Add a print driver", "" },
+ { "addprinter", cmd_spoolss_addprinterex, PIPE_SPOOLSS, "Add a printer", "" },
+ { "deldriver", cmd_spoolss_deletedriver, PIPE_SPOOLSS, "Delete a printer driver", "" },
+ { "enumdata", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Enumerate printer data (*)", "" },
+ { "enumjobs", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Enumerate print jobs (*)", "" },
+ { "enumports", cmd_spoolss_enum_ports, PIPE_SPOOLSS, "Enumerate printer ports", "" },
+ { "enumdrivers", cmd_spoolss_enum_drivers, PIPE_SPOOLSS, "Enumerate installed printer drivers", "" },
+ { "enumprinters", cmd_spoolss_enum_printers, PIPE_SPOOLSS, "Enumerate printers", "" },
+ { "getdata", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Get print driver data (*)", "" },
+ { "getdriver", cmd_spoolss_getdriver, PIPE_SPOOLSS, "Get print driver information", "" },
+ { "getdriverdir", cmd_spoolss_getdriverdir, PIPE_SPOOLSS, "Get print driver upload directory", "" },
+ { "getprinter", cmd_spoolss_getprinter, PIPE_SPOOLSS, "Get printer info", "" },
+ { "getprintprocdir", cmd_spoolss_getprintprocdir, PIPE_SPOOLSS, "Get print processor directory", "" },
+ { "openprinter", cmd_spoolss_open_printer_ex, PIPE_SPOOLSS, "Open printer handle", "" },
+ { "setdriver", cmd_spoolss_setdriver, PIPE_SPOOLSS, "Set printer driver", "" },
+ { "getprintprocdir", cmd_spoolss_getprintprocdir, PIPE_SPOOLSS, "Get print processor directory", "" },
+ { "addform", cmd_spoolss_addform, PIPE_SPOOLSS, "Add form", "" },
+ { "setform", cmd_spoolss_setform, PIPE_SPOOLSS, "Set form", "" },
+ { "getform", cmd_spoolss_getform, PIPE_SPOOLSS, "Get form", "" },
+ { "deleteform", cmd_spoolss_deleteform, PIPE_SPOOLSS, "Delete form", "" },
+ { "enumforms", cmd_spoolss_enum_forms, PIPE_SPOOLSS, "Enumerate forms", "" },
+ { "setprinter", cmd_spoolss_setprinter, PIPE_SPOOLSS, "Set printer comment", "" },
+ { "setprinterdata", cmd_spoolss_setprinterdata, PIPE_SPOOLSS, "Set REG_SZ printer data", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_srvsvc.c b/source/rpcclient/cmd_srvsvc.c
index 3e569f51cea..d6c1fd544f3 100644
--- a/source/rpcclient/cmd_srvsvc.c
+++ b/source/rpcclient/cmd_srvsvc.c
@@ -4,7 +4,7 @@
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
- Copyright (C) Tim Potter 2000,2002
+ Copyright (C) Tim Potter 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -142,8 +142,8 @@ static void display_srv_info_101(SRV_INFO_101 *sv101)
fstring name;
fstring comment;
- unistr2_to_ascii(name, &sv101->uni_name, sizeof(name) - 1);
- unistr2_to_ascii(comment, &sv101->uni_comment, sizeof(comment) - 1);
+ unistr2_to_unix(name, &sv101->uni_name, sizeof(name) - 1);
+ unistr2_to_unix(comment, &sv101->uni_comment, sizeof(comment) - 1);
display_server(name, sv101->srv_type, comment);
@@ -160,9 +160,9 @@ static void display_srv_info_102(SRV_INFO_102 *sv102)
fstring comment;
fstring usr_path;
- unistr2_to_ascii(name, &sv102->uni_name, sizeof(name) - 1);
- unistr2_to_ascii(comment, &sv102->uni_comment, sizeof(comment) - 1);
- unistr2_to_ascii(usr_path, &sv102->uni_usr_path, sizeof(usr_path) - 1);
+ unistr2_to_unix(name, &sv102->uni_name, sizeof(name) - 1);
+ unistr2_to_unix(comment, &sv102->uni_comment, sizeof(comment) - 1);
+ unistr2_to_unix(usr_path, &sv102->uni_usr_path, sizeof(usr_path) - 1);
display_server(name, sv102->srv_type, comment);
@@ -179,17 +179,18 @@ static void display_srv_info_102(SRV_INFO_102 *sv102)
}
/* Server query info */
-static WERROR cmd_srvsvc_srv_query_info(struct cli_state *cli,
+
+static NTSTATUS cmd_srvsvc_srv_query_info(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
uint32 info_level = 101;
SRV_INFO_CTR ctr;
- WERROR result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (argc > 2) {
printf("Usage: %s [infolevel]\n", argv[0]);
- return WERR_OK;
+ return NT_STATUS_OK;
}
if (argc == 2)
@@ -198,7 +199,7 @@ static WERROR cmd_srvsvc_srv_query_info(struct cli_state *cli,
result = cli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
&ctr);
- if (!W_ERROR_IS_OK(result)) {
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -220,142 +221,13 @@ static WERROR cmd_srvsvc_srv_query_info(struct cli_state *cli,
return result;
}
-static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
-{
- fstring netname = "", remark = "";
-
- rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
- rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
-
- printf("netname: %s\n", netname);
- printf("\tremark:\t%s\n", remark);
-}
-
-static void display_share_info_2(SRV_SHARE_INFO_2 *info2)
-{
- fstring netname = "", remark = "", path = "", passwd = "";
-
- rpcstr_pull_unistr2_fstring(netname, &info2->info_2_str.uni_netname);
- rpcstr_pull_unistr2_fstring(remark, &info2->info_2_str.uni_remark);
- rpcstr_pull_unistr2_fstring(path, &info2->info_2_str.uni_path);
- rpcstr_pull_unistr2_fstring(passwd, &info2->info_2_str.uni_passwd);
-
- printf("netname: %s\n", netname);
- printf("\tremark:\t%s\n", remark);
- printf("\tpath:\t%s\n", path);
- printf("\tpassword:\t%s\n", passwd);
-}
-
-static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- uint32 info_level = 2;
- SRV_SHARE_INFO_CTR ctr;
- WERROR result;
- ENUM_HND hnd;
- uint32 preferred_len = 0xffffffff, i;
-
- if (argc > 2) {
- printf("Usage: %s [infolevel]\n", argv[0]);
- return WERR_OK;
- }
-
- if (argc == 2)
- info_level = atoi(argv[1]);
-
- init_enum_hnd(&hnd, 0);
-
- result = cli_srvsvc_net_share_enum(
- cli, mem_ctx, info_level, &ctr, preferred_len, &hnd);
-
- if (!W_ERROR_IS_OK(result) || !ctr.num_entries)
- goto done;
-
- /* Display results */
-
- switch (info_level) {
- case 1:
- for (i = 0; i < ctr.num_entries; i++)
- display_share_info_1(&ctr.share.info1[i]);
- break;
- case 2:
- for (i = 0; i < ctr.num_entries; i++)
- display_share_info_2(&ctr.share.info2[i]);
- break;
- default:
- printf("unsupported info level %d\n", info_level);
- break;
- }
-
- done:
- return result;
-}
-
-static WERROR cmd_srvsvc_net_remote_tod(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- TIME_OF_DAY_INFO tod;
- WERROR result;
-
- if (argc > 1) {
- printf("Usage: %s\n", argv[0]);
- return WERR_OK;
- }
-
- result = cli_srvsvc_net_remote_tod(
- cli, mem_ctx, cli->srv_name_slash, &tod);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- done:
- return result;
-}
-
-static WERROR cmd_srvsvc_net_file_enum(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- uint32 info_level = 3;
- SRV_FILE_INFO_CTR ctr;
- WERROR result;
- ENUM_HND hnd;
- uint32 preferred_len = 0;
-
- if (argc > 2) {
- printf("Usage: %s [infolevel]\n", argv[0]);
- return WERR_OK;
- }
-
- if (argc == 2)
- info_level = atoi(argv[1]);
-
- init_enum_hnd(&hnd, 0);
-
- ZERO_STRUCT(ctr);
-
- result = cli_srvsvc_net_file_enum(
- cli, mem_ctx, info_level, NULL, &ctr, preferred_len, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- done:
- return result;
-}
-
/* List of commands exported by this module */
struct cmd_set srvsvc_commands[] = {
{ "SRVSVC" },
- { "srvinfo", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_srv_query_info, PI_SRVSVC, "Server query info", "" },
- { "netshareenum",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_enum, PI_SRVSVC, "Enumerate shares", "" },
- { "netfileenum", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_file_enum, PI_SRVSVC, "Enumerate open files", "" },
- { "netremotetod",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_remote_tod, PI_SRVSVC, "Fetch remote time of day", "" },
+ { "srvinfo", cmd_srvsvc_srv_query_info, PIPE_SRVSVC, "Server query info", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_wkssvc.c b/source/rpcclient/cmd_wkssvc.c
index 137ff3bdae9..79acf35943c 100644
--- a/source/rpcclient/cmd_wkssvc.c
+++ b/source/rpcclient/cmd_wkssvc.c
@@ -44,7 +44,7 @@ void cmd_wks_query_info(struct client_info *info)
fstrcpy(dest_wks, "\\\\");
fstrcat(dest_wks, info->dest_host);
- strupper_m(dest_wks);
+ strupper(dest_wks);
if (next_token_nr(NULL, tmp, NULL, sizeof(tmp)))
{
@@ -57,7 +57,7 @@ void cmd_wks_query_info(struct client_info *info)
DEBUG(5, ("cmd_wks_query_info: smb_cli->fd:%d\n", smb_cli->fd));
/* open LSARPC session. */
- res = res ? cli_nt_session_open(smb_cli, PI_WKSSVC) : False;
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WKSSVC) : False;
/* send info level: receive requested info. hopefully. */
res = res ? do_wks_query_info(smb_cli,
diff --git a/source/rpcclient/display.c b/source/rpcclient/display.c
new file mode 100755
index 00000000000..345ed7d49af
--- /dev/null
+++ b/source/rpcclient/display.c
@@ -0,0 +1,1339 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+convert a share mode to a string
+****************************************************************************/
+char *get_file_mode_str(uint32 share_mode)
+{
+ static fstring mode;
+
+ switch (GET_DENY_MODE(share_mode))
+ {
+ case DENY_NONE : fstrcpy(mode, "DENY_NONE "); break;
+ case DENY_ALL : fstrcpy(mode, "DENY_ALL "); break;
+ case DENY_DOS : fstrcpy(mode, "DENY_DOS "); break;
+ case DENY_READ : fstrcpy(mode, "DENY_READ "); break;
+ case DENY_WRITE: fstrcpy(mode, "DENY_WRITE "); break;
+ case DENY_FCB: fstrcpy(mode, "DENY_FCB "); break;
+ default : fstrcpy(mode, "DENY_???? "); break;
+ }
+
+ switch (share_mode & 0xF)
+ {
+ case 0 : fstrcat(mode, "RDONLY"); break;
+ case 1 : fstrcat(mode, "WRONLY"); break;
+ case 2 : fstrcat(mode, "RDWR "); break;
+ default: fstrcat(mode, "R??W??"); break;
+ }
+
+ return mode;
+}
+
+/****************************************************************************
+convert an oplock mode to a string
+****************************************************************************/
+char *get_file_oplock_str(uint32 op_type)
+{
+ static fstring oplock;
+ BOOL excl = ((op_type & EXCLUSIVE_OPLOCK) != 0);
+ BOOL batch = ((op_type & BATCH_OPLOCK ) != 0);
+
+ oplock[0] = 0;
+
+ if (excl ) fstrcat(oplock, "EXCLUSIVE");
+ if (excl && batch) fstrcat(oplock, "+");
+ if ( batch) fstrcat(oplock, "BATCH");
+ if (!excl && !batch) fstrcat(oplock, "NONE");
+
+ return oplock;
+}
+
+/****************************************************************************
+convert a share type enum to a string
+****************************************************************************/
+char *get_share_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ switch (type)
+ {
+ case STYPE_DISKTREE: fstrcpy(typestr, "Disk" ); break;
+ case STYPE_PRINTQ : fstrcpy(typestr, "Printer"); break;
+ case STYPE_DEVICE : fstrcpy(typestr, "Device" ); break;
+ case STYPE_IPC : fstrcpy(typestr, "IPC" ); break;
+ default : fstrcpy(typestr, "????" ); break;
+ }
+ return typestr;
+}
+
+/****************************************************************************
+convert a server type enum to a string
+****************************************************************************/
+char *get_server_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ if (type == SV_TYPE_ALL)
+ {
+ fstrcpy(typestr, "All");
+ }
+ else
+ {
+ int i;
+ typestr[0] = 0;
+ for (i = 0; i < 32; i++)
+ {
+ if (type & (1 << i))
+ {
+ switch (((unsigned)1) << i)
+ {
+ case SV_TYPE_WORKSTATION : fstrcat(typestr, "Wk " ); break;
+ case SV_TYPE_SERVER : fstrcat(typestr, "Sv " ); break;
+ case SV_TYPE_SQLSERVER : fstrcat(typestr, "Sql "); break;
+ case SV_TYPE_DOMAIN_CTRL : fstrcat(typestr, "PDC "); break;
+ case SV_TYPE_DOMAIN_BAKCTRL : fstrcat(typestr, "BDC "); break;
+ case SV_TYPE_TIME_SOURCE : fstrcat(typestr, "Tim "); break;
+ case SV_TYPE_AFP : fstrcat(typestr, "AFP "); break;
+ case SV_TYPE_NOVELL : fstrcat(typestr, "Nov "); break;
+ case SV_TYPE_DOMAIN_MEMBER : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_PRINTQ_SERVER : fstrcat(typestr, "PrQ "); break;
+ case SV_TYPE_DIALIN_SERVER : fstrcat(typestr, "Din "); break;
+ case SV_TYPE_SERVER_UNIX : fstrcat(typestr, "Unx "); break;
+ case SV_TYPE_NT : fstrcat(typestr, "NT " ); break;
+ case SV_TYPE_WFW : fstrcat(typestr, "Wfw "); break;
+ case SV_TYPE_SERVER_MFPN : fstrcat(typestr, "Mfp "); break;
+ case SV_TYPE_SERVER_NT : fstrcat(typestr, "SNT "); break;
+ case SV_TYPE_POTENTIAL_BROWSER: fstrcat(typestr, "PtB "); break;
+ case SV_TYPE_BACKUP_BROWSER : fstrcat(typestr, "BMB "); break;
+ case SV_TYPE_MASTER_BROWSER : fstrcat(typestr, "LMB "); break;
+ case SV_TYPE_DOMAIN_MASTER : fstrcat(typestr, "DMB "); break;
+ case SV_TYPE_SERVER_OSF : fstrcat(typestr, "OSF "); break;
+ case SV_TYPE_SERVER_VMS : fstrcat(typestr, "VMS "); break;
+ case SV_TYPE_WIN95_PLUS : fstrcat(typestr, "W95 "); break;
+ case SV_TYPE_ALTERNATE_XPORT : fstrcat(typestr, "Xpt "); break;
+ case SV_TYPE_LOCAL_LIST_ONLY : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_DOMAIN_ENUM : fstrcat(typestr, "Loc "); break;
+ }
+ }
+ }
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ }
+ return typestr;
+}
+
+/****************************************************************************
+server info level 101 display function
+****************************************************************************/
+void display_srv_info_101(FILE *out_hnd, enum action_type action,
+ SRV_INFO_101 *sv101)
+{
+ if (sv101 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Server Info Level 101:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+
+ rpcstr_pull(name, sv101->uni_name.buffer, sizeof(name), sv101->uni_name.uni_str_len*2, 0);
+ rpcstr_pull(comment, sv101->uni_comment.buffer, sizeof(comment), sv101->uni_comment.uni_str_len*2, 0);
+
+ display_server(out_hnd, action, name, sv101->srv_type, comment);
+
+ fprintf(out_hnd, "\tplatform_id : %d\n" , sv101->platform_id);
+ fprintf(out_hnd, "\tos version : %d.%d\n" , sv101->ver_major, sv101->ver_minor);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+server info level 102 display function
+****************************************************************************/
+void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102)
+{
+ if (sv102 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Server Info Level 102:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+ fstring usr_path;
+
+ rpcstr_pull(name, sv102->uni_name.buffer, sizeof(name), sv102->uni_name.uni_str_len*2, 0);
+ rpcstr_pull(comment, sv102->uni_comment.buffer, sizeof(comment), sv102->uni_comment.uni_str_len*2, 0);
+ rpcstr_pull(usr_path, sv102->uni_usr_path.buffer, sizeof(usr_path), sv102->uni_usr_path.uni_str_len*2, 0);
+
+ display_server(out_hnd, action, name, sv102->srv_type, comment);
+
+ fprintf(out_hnd, "\tplatform_id : %d\n" , sv102->platform_id);
+ fprintf(out_hnd, "\tos version : %d.%d\n" , sv102->ver_major, sv102->ver_minor);
+
+ fprintf(out_hnd, "\tusers : %x\n" , sv102->users );
+ fprintf(out_hnd, "\tdisc, hidden : %x,%x\n" , sv102->disc , sv102->hidden );
+ fprintf(out_hnd, "\tannounce, delta : %d, %d\n", sv102->announce , sv102->ann_delta);
+ fprintf(out_hnd, "\tlicenses : %d\n" , sv102->licenses );
+ fprintf(out_hnd, "\tuser path : %s\n" , usr_path);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+server info container display function
+****************************************************************************/
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_srv_ctr == 0)
+ {
+ fprintf(out_hnd, "Server Information: unavailable due to an error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 101:
+ {
+ display_srv_info_101(out_hnd, action, &(ctr->srv.sv101));
+ break;
+ }
+ case 102:
+ {
+ display_srv_info_102(out_hnd, action, &(ctr->srv.sv102));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "Server Information: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 0 display function
+****************************************************************************/
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+ CONN_INFO_0 *info0)
+{
+ if (info0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Connection Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\tid: %d\n", info0->id);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 1 display function
+****************************************************************************/
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+ CONN_INFO_1 *info1, CONN_INFO_1_STR *str1)
+{
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Connection Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring usr_name;
+ fstring net_name;
+
+ rpcstr_pull(usr_name, str1->uni_usr_name.buffer, sizeof(usr_name), str1->uni_usr_name.uni_str_len*2,0);
+ rpcstr_pull(net_name, str1->uni_net_name.buffer, sizeof(net_name), str1->uni_net_name.uni_str_len*2,0);
+
+ fprintf(out_hnd, "\tid : %d\n", info1->id);
+ fprintf(out_hnd, "\ttype : %s\n", get_share_type_str(info1->type));
+ fprintf(out_hnd, "\tnum_opens: %d\n", info1->num_opens);
+ fprintf(out_hnd, "\tnum_users: %d\n", info1->num_users);
+ fprintf(out_hnd, "\topen_time: %d\n", info1->open_time);
+
+ fprintf(out_hnd, "\tuser name: %s\n", usr_name);
+ fprintf(out_hnd, "\tnet name: %s\n", net_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 0 container display function
+****************************************************************************/
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_0 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_1 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_conn_ctr == 0)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ display_srv_conn_info_0_ctr(out_hnd, action,
+ &(ctr->conn.info0));
+ break;
+ }
+ case 1:
+ {
+ display_srv_conn_info_1_ctr(out_hnd, action,
+ &(ctr->conn.info1));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "display_srv_conn_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+share info level 1 display function
+****************************************************************************/
+void display_share_info_1(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_1 *info1)
+{
+ if (info1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Share Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+
+ rpcstr_pull(net_name, info1->info_1_str.uni_netname.buffer, sizeof(net_name), info1->info_1_str.uni_netname.uni_str_len*2, 0);
+ rpcstr_pull(remark, info1->info_1_str.uni_remark.buffer, sizeof(remark), info1->info_1_str.uni_remark.uni_str_len*2, 0);
+
+ display_share(out_hnd, action, net_name, info1->info_1.type, remark);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info level 2 display function
+****************************************************************************/
+void display_share_info_2(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_2 *info2)
+{
+ if (info2 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Share Info Level 2:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+ fstring path ;
+ fstring passwd ;
+
+ rpcstr_pull(net_name, info2->info_2_str.uni_netname.buffer, sizeof(net_name), info2->info_2_str.uni_netname.uni_str_len*2, 0);
+ rpcstr_pull(remark, info2->info_2_str.uni_remark.buffer, sizeof(remark), info2->info_2_str.uni_remark.uni_str_len*2, 0);
+ rpcstr_pull(path, info2->info_2_str.uni_path.buffer, sizeof(path), info2->info_2_str.uni_path.uni_str_len*2, 0);
+ rpcstr_pull(passwd, info2->info_2_str.uni_passwd.buffer, sizeof(passwd), info2->info_2_str.uni_passwd.uni_str_len*2, 0);
+
+ display_share2(out_hnd, action, net_name,
+ info2->info_2.type, remark, info2->info_2.perms,
+ info2->info_2.max_uses, info2->info_2.num_uses,
+ path, passwd);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info container display function
+****************************************************************************/
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_CTR *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_share_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries; i++)
+ {
+ switch (ctr->info_level) {
+ case 1:
+ display_share_info_1(out_hnd, ACTION_HEADER , &(ctr->share.info1[i]));
+ display_share_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->share.info1[i]));
+ display_share_info_1(out_hnd, ACTION_FOOTER , &(ctr->share.info1[i]));
+ break;
+ case 2:
+ display_share_info_2(out_hnd, ACTION_HEADER , &(ctr->share.info2[i]));
+ display_share_info_2(out_hnd, ACTION_ENUMERATE, &(ctr->share.info2[i]));
+ display_share_info_2(out_hnd, ACTION_FOOTER , &(ctr->share.info2[i]));
+ break;
+ default:
+ fprintf(out_hnd, "display_srv_share_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+file info level 3 display function
+****************************************************************************/
+void display_file_info_3(FILE *out_hnd, enum action_type action,
+ FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
+{
+ if (info3 == NULL || str3 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "File Info Level 3:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring path_name;
+ fstring user_name;
+
+ rpcstr_pull(path_name, str3->uni_path_name.buffer, sizeof(path_name), str3->uni_path_name.uni_str_len*2, 0);
+ rpcstr_pull(user_name, str3->uni_user_name.buffer, sizeof(user_name), str3->uni_user_name.uni_str_len*2, 0);
+
+ fprintf(out_hnd, "\tid : %d\n", info3->id);
+ fprintf(out_hnd, "\tperms : %s\n", get_file_mode_str(info3->perms));
+ fprintf(out_hnd, "\tnum_locks: %d\n", info3->num_locks);
+
+ fprintf(out_hnd, "\tpath name: %s\n", path_name);
+ fprintf(out_hnd, "\tuser name: %s\n", user_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+file info level 3 container display function
+****************************************************************************/
+void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_3 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_file_info_3_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_file_info_3(out_hnd, ACTION_HEADER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ display_file_info_3(out_hnd, ACTION_ENUMERATE, &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ display_file_info_3(out_hnd, ACTION_FOOTER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+file info container display function
+****************************************************************************/
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_file_ctr == 0)
+ {
+ fprintf(out_hnd, "display_srv_file_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 3:
+ {
+ display_srv_file_info_3_ctr(out_hnd, action,
+ &(ctr->file.info3));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "display_srv_file_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ print browse connection on a host
+ ****************************************************************************/
+void display_server(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-20s %s\n",
+ sname, get_server_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+print shares on a host
+****************************************************************************/
+void display_share(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-10.10s%s\n",
+ sname, get_share_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print shares on a host, level 2
+****************************************************************************/
+void display_share2(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, char *passwd)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-10.10s%s %x %x %x %s %s\n",
+ sname, get_share_type_str(type), comment,
+ perms, max_uses, num_uses, path, passwd);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print name info
+****************************************************************************/
+void display_name(FILE *out_hnd, enum action_type action,
+ char *sname)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-21.21s\n", sname);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display group rid info
+ ****************************************************************************/
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+ uint32 num_gids, DOM_GID *gid)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_gids == 0)
+ {
+ fprintf(out_hnd, "\tNo Groups\n");
+ }
+ else
+ {
+ fprintf(out_hnd, "\tGroup Info\n");
+ fprintf(out_hnd, "\t----------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_gids; i++)
+ {
+ fprintf(out_hnd, "\tGroup RID: %8x attr: %x\n",
+ gid[i].g_rid, gid[i].attr);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display alias name info
+ ****************************************************************************/
+void display_alias_name_info(FILE *out_hnd, enum action_type action,
+ uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_aliases == 0)
+ {
+ fprintf(out_hnd, "\tNo Aliases\n");
+ }
+ else
+ {
+ fprintf(out_hnd, "\tAlias Names\n");
+ fprintf(out_hnd, "\t----------- \n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ fprintf(out_hnd, "\tAlias Name: %s Attributes: %3d\n",
+ alias_name[i], num_als_usrs[i]);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display sam_user_info_21 structure
+ ****************************************************************************/
+void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tUser Info, Level 0x15\n");
+ fprintf(out_hnd, "\t---------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ pstring tmp;
+ rpcstr_pull(tmp, usr->uni_user_name.buffer, sizeof(tmp),usr->uni_user_name.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tUser Name : %s\n", tmp); /* username unicode string */
+ rpcstr_pull(tmp, usr->uni_full_name.buffer, sizeof(tmp),usr->uni_full_name.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tFull Name : %s\n", tmp); /* user's full name unicode string */
+ rpcstr_pull(tmp, usr->uni_home_dir.buffer, sizeof(tmp),usr->uni_home_dir.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tHome Drive : %s\n", tmp); /* home directory unicode string */
+ rpcstr_pull(tmp, usr->uni_dir_drive.buffer, sizeof(tmp),usr->uni_dir_drive.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tDir Drive : %s\n", tmp); /* home directory drive unicode string */
+ rpcstr_pull(tmp, usr->uni_profile_path.buffer, sizeof(tmp),usr->uni_profile_path.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tProfile Path: %s\n", tmp); /* profile path unicode string */
+ rpcstr_pull(tmp, usr->uni_logon_script.buffer, sizeof(tmp),usr->uni_logon_script.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tLogon Script: %s\n", tmp); /* logon script unicode string */
+ rpcstr_pull(tmp, usr->uni_acct_desc.buffer, sizeof(tmp),usr->uni_acct_desc.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tDescription : %s\n", tmp); /* user description unicode string */
+ rpcstr_pull(tmp, usr->uni_workstations.buffer, sizeof(tmp),usr->uni_workstations.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tWorkstations: %s\n", tmp); /* workstaions unicode string */
+ rpcstr_pull(tmp, usr->uni_unknows_str.buffer, sizeof(tmp),usr->uni_unknown_str.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tUnknown Str : %s\n", tmp); /* unknown string unicode string */
+ rpcstr_pull(tmp, usr->uni_munged_dial.buffer, sizeof(tmp),usr->uni_munged_dial.uni_str_len*2, 0);
+ fprintf(out_hnd, "\t\tRemote Dial : %s\n", tmp); /* munged remote access unicode string */
+
+ fprintf(out_hnd, "\t\tLogon Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logon_time ))));
+ fprintf(out_hnd, "\t\tLogoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logoff_time ))));
+ fprintf(out_hnd, "\t\tKickoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->kickoff_time ))));
+ fprintf(out_hnd, "\t\tPassword last set Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_last_set_time ))));
+ fprintf(out_hnd, "\t\tPassword can change Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_can_change_time ))));
+ fprintf(out_hnd, "\t\tPassword must change Time: %s\n", http_timestring(nt_time_to_unix(&(usr->pass_must_change_time))));
+
+ fprintf(out_hnd, "\t\tunknown_2[0..31]...\n"); /* user passwords? */
+
+ fprintf(out_hnd, "\t\tuser_rid : %x\n" , usr->user_rid ); /* User ID */
+ fprintf(out_hnd, "\t\tgroup_rid: %x\n" , usr->group_rid); /* Group ID */
+ fprintf(out_hnd, "\t\tacb_info : %04x\n", usr->acb_info ); /* Account Control Info */
+
+ fprintf(out_hnd, "\t\tunknown_3: %08x\n", usr->unknown_3); /* 0x00ff ffff */
+ fprintf(out_hnd, "\t\tlogon_divs: %d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ fprintf(out_hnd, "\t\tunknown_5: %08x\n", usr->unknown_5); /* 0x0002 0000 */
+
+ fprintf(out_hnd, "\t\tpadding1[0..7]...\n");
+
+ if (usr->ptr_logon_hrs)
+ {
+ fprintf(out_hnd, "\t\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_sec_mask_str(uint32 type)
+{
+ static fstring typestr;
+ int i;
+
+ switch (type)
+ {
+ case SEC_RIGHTS_FULL_CONTROL:
+ {
+ fstrcpy(typestr, "Full Control");
+ return typestr;
+ }
+
+ case SEC_RIGHTS_READ:
+ {
+ fstrcpy(typestr, "Read");
+ return typestr;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ typestr[0] = 0;
+ for (i = 0; i < 32; i++)
+ {
+ if (type & (1 << i))
+ {
+ switch (((unsigned)1) << i)
+ {
+ case SEC_RIGHTS_QUERY_VALUE : fstrcat(typestr, "Query " ); break;
+ case SEC_RIGHTS_SET_VALUE : fstrcat(typestr, "Set " ); break;
+ case SEC_RIGHTS_CREATE_SUBKEY : fstrcat(typestr, "Create "); break;
+ case SEC_RIGHTS_ENUM_SUBKEYS : fstrcat(typestr, "Enum "); break;
+ case SEC_RIGHTS_NOTIFY : fstrcat(typestr, "Notify "); break;
+ case SEC_RIGHTS_CREATE_LINK : fstrcat(typestr, "CreateLink "); break;
+ case SEC_RIGHTS_DELETE : fstrcat(typestr, "Delete "); break;
+ case SEC_RIGHTS_READ_CONTROL : fstrcat(typestr, "ReadControl "); break;
+ case SEC_RIGHTS_WRITE_DAC : fstrcat(typestr, "WriteDAC "); break;
+ case SEC_RIGHTS_WRITE_OWNER : fstrcat(typestr, "WriteOwner "); break;
+ }
+ type &= ~(1 << i);
+ }
+ }
+
+ /* remaining bits get added on as-is */
+ if (type != 0)
+ {
+ fstring tmp;
+ slprintf(tmp, sizeof(tmp)-1, "[%08x]", type);
+ fstrcat(typestr, tmp);
+ }
+
+ /* remove last space */
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ return typestr;
+}
+
+/****************************************************************************
+ display sec_access structure
+ ****************************************************************************/
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t\tPermissions: %s\n",
+ get_sec_mask_str(info->mask));
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_ace structure
+ ****************************************************************************/
+void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tACE\n");
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring sid_str;
+
+ display_sec_access(out_hnd, ACTION_HEADER , &ace->info);
+ display_sec_access(out_hnd, ACTION_ENUMERATE, &ace->info);
+ display_sec_access(out_hnd, ACTION_FOOTER , &ace->info);
+
+ sid_to_string(sid_str, &ace->sid);
+ fprintf(out_hnd, "\t\tSID: %s\n", sid_str);
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_acl structure
+ ****************************************************************************/
+void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tACL\tNum ACEs:\t%d\trevision:\t%x\n",
+ sec_acl->num_aces, sec_acl->revision);
+ fprintf(out_hnd, "\t---\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ if (sec_acl->size != 0 && sec_acl->num_aces != 0)
+ {
+ int i;
+ for (i = 0; i < sec_acl->num_aces; i++)
+ {
+ display_sec_ace(out_hnd, ACTION_HEADER , &sec_acl->ace[i]);
+ display_sec_ace(out_hnd, ACTION_ENUMERATE, &sec_acl->ace[i]);
+ display_sec_ace(out_hnd, ACTION_FOOTER , &sec_acl->ace[i]);
+ }
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_desc structure
+ ****************************************************************************/
+void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tSecurity Descriptor\trevision:\t%x\ttype:\t%x\n",
+ sec->revision, sec->type);
+ fprintf(out_hnd, "\t-------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring sid_str;
+
+ if (sec->off_sacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->sacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->sacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->sacl);
+ }
+ if (sec->off_dacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->dacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->dacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->dacl);
+ }
+ if (sec->off_owner_sid != 0)
+ {
+ sid_to_string(sid_str, sec->owner_sid);
+ fprintf(out_hnd, "\tOwner SID:\t%s\n", sid_str);
+ }
+ if (sec->off_grp_sid != 0)
+ {
+ sid_to_string(sid_str, sec->grp_sid);
+ fprintf(out_hnd, "\tParent SID:\t%s\n", sid_str);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_reg_val_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ switch (type)
+ {
+ case 0x01:
+ {
+ fstrcpy(typestr, "string");
+ return typestr;
+ }
+
+ case 0x03:
+ {
+ fstrcpy(typestr, "bytes");
+ return typestr;
+ }
+
+ case 0x04:
+ {
+ fstrcpy(typestr, "uint32");
+ return typestr;
+ }
+
+ case 0x07:
+ {
+ fstrcpy(typestr, "multi");
+ return typestr;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
+ return typestr;
+}
+
+
+static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFFER2 *value)
+{
+ fstring type;
+ pstring intvalue;
+ fstrcpy(type, get_reg_val_type_str(val_type));
+
+ switch (val_type)
+ {
+ case 0x01: /* unistr */
+ {
+ rpcstr_pull(intvalue, value->buffer, sizeof(intvalue), value->buf_len, 0);
+ /*fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_str(value));*/
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, value);
+ break;
+ }
+
+ default: /* unknown */
+ case 0x03: /* bytes */
+ {
+ if (value->buf_len <= 8)
+ {
+ fprintf(out_hnd,"\t%s:\t%s:\t", val_name, type);
+ out_data(out_hnd, (char*)value->buffer, value->buf_len, 8);
+ }
+ else
+ {
+ fprintf(out_hnd,"\t%s:\t%s:\n", val_name, type);
+ out_data(out_hnd, (char*)value->buffer, value->buf_len, 16);
+ }
+ break;
+ }
+
+ case 0x04: /* uint32 */
+ {
+ fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type, buffer2_to_uint32(value));
+ break;
+ }
+
+ case 0x07: /* multiunistr */
+ {
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_multistr(value));
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_reg_value_info(FILE *out_hnd, enum action_type action,
+ char *val_name, uint32 val_type, BUFFER2 *value)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ print_reg_value(out_hnd, val_name, val_type, value);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_reg_key_info(FILE *out_hnd, enum action_type action,
+ char *key_name, time_t key_mod_time)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%s\t(%s)\n",
+ key_name, http_timestring(key_mod_time));
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+#if COPY_THIS_TEMPLATE
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+ void display_(FILE *out_hnd, enum action_type action, *)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\t\n");
+ fprintf(out_hnd, "\t-------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+#endif
diff --git a/source/rpcclient/display_sec.c b/source/rpcclient/display_sec.c
index 2a93c915f1a..5c23bf42ffa 100644
--- a/source/rpcclient/display_sec.c
+++ b/source/rpcclient/display_sec.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "rpcclient.h"
+
/****************************************************************************
convert a security permissions into a string
****************************************************************************/
@@ -54,7 +55,7 @@ char *get_sec_mask_str(uint32 type)
if (type & DELETE_ACCESS)
fstrcat(typestr, "DELETE_ACCESS ");
- printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SPECIFIC_RIGHTS_MASK);
+ printf("\t\tSpecific bits: 0x%lx\n", type&SPECIFIC_RIGHTS_MASK);
return typestr;
}
@@ -106,7 +107,7 @@ void display_sec_acl(SEC_ACL *sec_acl)
int i;
printf("\tACL\tNum ACEs:\t%d\trevision:\t%x\n",
- sec_acl->num_aces, sec_acl->revision);
+ sec_acl->num_aces, sec_acl->revision);
printf("\t---\n");
if (sec_acl->size != 0 && sec_acl->num_aces != 0)
diff --git a/source/rpcclient/display_spool.c b/source/rpcclient/display_spool.c
new file mode 100755
index 00000000000..b4baf570f17
--- /dev/null
+++ b/source/rpcclient/display_spool.c
@@ -0,0 +1,927 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+printer info level 0 display function
+****************************************************************************/
+static void display_print_info_0(FILE *out_hnd, PRINTER_INFO_0 *i1)
+{
+ fstring name;
+ fstring server;
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->printername.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(server, i1->servername.buffer, sizeof(server), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tprintername:[%s]\n", name);
+ report(out_hnd, "\tservername:[%s]\n", server);
+ report(out_hnd, "\tcjobs:[%x]\n", i1->cjobs);
+ report(out_hnd, "\ttotal_jobs:[%x]\n", i1->total_jobs);
+
+ report(out_hnd, "\t:date: [%d]-[%d]-[%d] (%d)\n", i1->year, i1->month, i1->day, i1->dayofweek);
+ report(out_hnd, "\t:time: [%d]-[%d]-[%d]-[%d]\n", i1->hour, i1->minute, i1->second, i1->milliseconds);
+
+ report(out_hnd, "\tglobal_counter:[%x]\n", i1->global_counter);
+ report(out_hnd, "\ttotal_pages:[%x]\n", i1->total_pages);
+
+ report(out_hnd, "\tmajorversion:[%x]\n", i1->major_version);
+ report(out_hnd, "\tbuildversion:[%x]\n", i1->build_version);
+
+ report(out_hnd, "\tunknown7:[%x]\n", i1->unknown7);
+ report(out_hnd, "\tunknown8:[%x]\n", i1->unknown8);
+ report(out_hnd, "\tunknown9:[%x]\n", i1->unknown9);
+ report(out_hnd, "\tsession_counter:[%x]\n", i1->session_counter);
+ report(out_hnd, "\tunknown11:[%x]\n", i1->unknown11);
+ report(out_hnd, "\tprinter_errors:[%x]\n", i1->printer_errors);
+ report(out_hnd, "\tunknown13:[%x]\n", i1->unknown13);
+ report(out_hnd, "\tunknown14:[%x]\n", i1->unknown14);
+ report(out_hnd, "\tunknown15:[%x]\n", i1->unknown15);
+ report(out_hnd, "\tunknown16:[%x]\n", i1->unknown16);
+ report(out_hnd, "\tchange_id:[%x]\n", i1->change_id);
+ report(out_hnd, "\tunknown18:[%x]\n", i1->unknown18);
+ report(out_hnd, "\tstatus:[%x]\n", i1->status);
+ report(out_hnd, "\tunknown20:[%x]\n", i1->unknown20);
+ report(out_hnd, "\tc_setprinter:[%x]\n", i1->c_setprinter);
+ report(out_hnd, "\tunknown22:[%x]\n", i1->unknown22);
+ report(out_hnd, "\tunknown23:[%x]\n", i1->unknown23);
+ report(out_hnd, "\tunknown24:[%x]\n", i1->unknown24);
+ report(out_hnd, "\tunknown25:[%x]\n", i1->unknown25);
+ report(out_hnd, "\tunknown26:[%x]\n", i1->unknown26);
+ report(out_hnd, "\tunknown27:[%x]\n", i1->unknown27);
+ report(out_hnd, "\tunknown28:[%x]\n", i1->unknown28);
+ report(out_hnd, "\tunknown29:[%x]\n", i1->unknown29);
+}
+
+/****************************************************************************
+printer info level 1 display function
+****************************************************************************/
+static void display_print_info_1(FILE *out_hnd, PRINTER_INFO_1 *i1)
+{
+ fstring desc;
+ fstring name;
+ fstring comm;
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(desc, i1->description.buffer, sizeof(desc), 0, STR_TERMINATE);
+ rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tflags:[%x]\n", i1->flags);
+ report(out_hnd, "\tname:[%s]\n", name);
+ report(out_hnd, "\tdescription:[%s]\n", desc);
+ report(out_hnd, "\tcomment:[%s]\n\n", comm);
+}
+
+/****************************************************************************
+printer info level 2 display function
+****************************************************************************/
+static void display_print_info_2(FILE *out_hnd, PRINTER_INFO_2 *i2)
+{
+ fstring servername;
+ fstring printername;
+ fstring sharename;
+ fstring portname;
+ fstring drivername;
+ fstring comment;
+ fstring location;
+ fstring sepfile;
+ fstring printprocessor;
+ fstring datatype;
+ fstring parameters;
+
+ if (i2 == NULL)
+ return;
+
+ rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), 0, STR_TERMINATE);
+ rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), 0, STR_TERMINATE);
+ rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), 0, STR_TERMINATE);
+ rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), 0, STR_TERMINATE);
+ rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), 0, STR_TERMINATE);
+ rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), 0, STR_TERMINATE);
+ rpcstr_pull(location, i2->location.buffer,sizeof(location), 0, STR_TERMINATE);
+ rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), 0, STR_TERMINATE);
+ rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), 0, STR_TERMINATE);
+ rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), 0, STR_TERMINATE);
+ rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tservername:[%s]\n", servername);
+ report(out_hnd, "\tprintername:[%s]\n", printername);
+ report(out_hnd, "\tsharename:[%s]\n", sharename);
+ report(out_hnd, "\tportname:[%s]\n", portname);
+ report(out_hnd, "\tdrivername:[%s]\n", drivername);
+ report(out_hnd, "\tcomment:[%s]\n", comment);
+ report(out_hnd, "\tlocation:[%s]\n", location);
+ report(out_hnd, "\tsepfile:[%s]\n", sepfile);
+ report(out_hnd, "\tprintprocessor:[%s]\n", printprocessor);
+ report(out_hnd, "\tdatatype:[%s]\n", datatype);
+ report(out_hnd, "\tparameters:[%s]\n", parameters);
+ report(out_hnd, "\tattributes:[%x]\n", i2->attributes);
+ report(out_hnd, "\tpriority:[%x]\n", i2->priority);
+ report(out_hnd, "\tdefaultpriority:[%x]\n", i2->defaultpriority);
+ report(out_hnd, "\tstarttime:[%x]\n", i2->starttime);
+ report(out_hnd, "\tuntiltime:[%x]\n", i2->untiltime);
+ report(out_hnd, "\tstatus:[%x]\n", i2->status);
+ report(out_hnd, "\tcjobs:[%x]\n", i2->cjobs);
+ report(out_hnd, "\taverageppm:[%x]\n\n", i2->averageppm);
+
+ if (i2->secdesc != NULL)
+ {
+ display_sec_desc(out_hnd, ACTION_HEADER , i2->secdesc);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, i2->secdesc);
+ display_sec_desc(out_hnd, ACTION_FOOTER , i2->secdesc);
+ }
+}
+
+/****************************************************************************
+printer info level 3 display function
+****************************************************************************/
+static void display_print_info_3(FILE *out_hnd, PRINTER_INFO_3 *i3)
+{
+ if (i3 == NULL)
+ return;
+
+ report(out_hnd, "\tflags:[%x]\n", i3->flags);
+
+ display_sec_desc(out_hnd, ACTION_HEADER , i3->secdesc);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, i3->secdesc);
+ display_sec_desc(out_hnd, ACTION_FOOTER , i3->secdesc);
+}
+
+/****************************************************************************
+connection info level 0 container display function
+****************************************************************************/
+static void display_printer_info_0_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_INFO_CTR ctr)
+{
+ int i;
+ PRINTER_INFO_0 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer Info Level 0:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.printers_0;
+ display_print_info_0(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+static void display_printer_info_1_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_INFO_CTR ctr)
+{
+ int i;
+ PRINTER_INFO_1 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer Info Level 1:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.printers_1;
+ display_print_info_1(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 2 container display function
+****************************************************************************/
+static void display_printer_info_2_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_INFO_CTR ctr)
+{
+ int i;
+ PRINTER_INFO_2 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer Info Level 2:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.printers_2;
+ display_print_info_2(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 3 container display function
+****************************************************************************/
+static void display_printer_info_3_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_INFO_CTR ctr)
+{
+ int i;
+ PRINTER_INFO_3 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer Info Level 3:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.printers_3;
+ display_print_info_3(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_printer_info_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+ uint32 count, PRINTER_INFO_CTR ctr)
+{
+ switch (level) {
+ case 0:
+ display_printer_info_0_ctr(out_hnd, action, count, ctr);
+ break;
+ case 1:
+ display_printer_info_1_ctr(out_hnd, action, count, ctr);
+ break;
+ case 2:
+ display_printer_info_2_ctr(out_hnd, action, count, ctr);
+ break;
+ case 3:
+ display_printer_info_3_ctr(out_hnd, action, count, ctr);
+ break;
+ default:
+ report(out_hnd, "display_printer_info_ctr: Unknown Info Level\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 3 container display function
+****************************************************************************/
+static void display_port_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PORT_INFO_CTR *ctr)
+{
+ uint32 i = 0;
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Port Info Level 1:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i=0; i<count; i++)
+ display_port_info_1(out_hnd, action, &ctr->port.info_1[i]);
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 3 container display function
+****************************************************************************/
+static void display_port_info_2_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PORT_INFO_CTR *ctr)
+{
+ uint32 i = 0;
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Port Info Level 2:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i=0; i<count; i++)
+ display_port_info_2(out_hnd, action, &ctr->port.info_2[i]);
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_port_info_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+ uint32 count, PORT_INFO_CTR *ctr)
+{
+ switch (level) {
+ case 1:
+ display_port_info_1_ctr(out_hnd, action, count, ctr);
+ break;
+ case 2:
+ display_port_info_2_ctr(out_hnd, action, count, ctr);
+ break;
+ default:
+ report(out_hnd, "display_port_info_ctr: Unknown Info Level\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_port_info_1(FILE *out_hnd, enum action_type action, PORT_INFO_1 *i1)
+{
+ fstring buffer;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Port:\n");
+ break;
+ case ACTION_ENUMERATE:
+ rpcstr_pull(buffer, i1->port_name.buffer, sizeof(bufferi), 0, STR_TERMINATE);
+ fprintf (out_hnd, "\tPort Name:\t[%s]\n\n", buffer);
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_port_info_2(FILE *out_hnd, enum action_type action, PORT_INFO_2 *i2)
+{
+ fstring buffer;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Port:\n");
+ break;
+ case ACTION_ENUMERATE:
+ rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
+ fprintf (out_hnd, "\tPort Name:\t[%s]\n", buffer);
+ rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
+
+ fprintf (out_hnd, "\tMonitor Name:\t[%s]\n", buffer);
+ rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), 0, STR_TERMINATE);
+ fprintf (out_hnd, "\tDescription:\t[%s]\n", buffer);
+ fprintf (out_hnd, "\tPort Type:\t[%d]\n", i2->port_type);
+ fprintf (out_hnd, "\tReserved:\t[%d]\n", i2->reserved);
+ fprintf (out_hnd, "\n");
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_printer_enumdata(FILE *out_hnd, enum action_type action, uint32 idx,
+ uint32 valuelen, uint16 *value, uint32 rvaluelen,
+ uint32 type,
+ uint32 datalen, uint8 *data, uint32 rdatalen)
+{
+ fstring buffer;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer enum data:\n");
+ report(out_hnd, "index\tvaluelen\tvalue\t\trvaluelen");
+ report(out_hnd, "\ttype\tdatalen\tdata\trdatalen\n");
+ break;
+ case ACTION_ENUMERATE:
+ report(out_hnd, "[%d]", idx);
+ report(out_hnd, "\t[%d]", valuelen);
+ rpcstr_pull(buffer, value, sizeof(buffer), 0, STR_TERMINATE);
+ report(out_hnd, "\t[%s]", buffer);
+ report(out_hnd, "\t[%d]", rvaluelen);
+ report(out_hnd, "\t\t[%d]", type);
+ report(out_hnd, "\t[%d]", datalen);
+/* report(out_hnd, "\t[%s]", data);*/
+ report(out_hnd, "\t[%d]\n", rdatalen);
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+job info level 2 display function
+****************************************************************************/
+void display_job_info_2(FILE *out_hnd, enum action_type action,
+ JOB_INFO_2 *const i2)
+{
+ if (i2 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Job Info Level 2:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring tmp;
+
+ report(out_hnd, "\tjob id:\t%d\n", i2->jobid);
+ rpcstr_pull(tmp, i2->printername.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tprinter name:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->machinename.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tmachine name:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->username.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tusername:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->document.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tdocument:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->notifyname.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tnotify name:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->datatype.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tdata type:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->printprocessor.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tprint processor:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->parameters.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tparameters:\t%s\n", tmp);
+ rpcstr_pull(tmp, i2->drivername.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tdriver name:\t%s\n", tmp);
+ report(out_hnd, "\tDevice Mode:\tNOT DISPLAYED YET\n");
+
+ rpcstr_pull(tmp, i2->text_status.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\ttext status:\t%s\n", tmp);
+ /* SEC_DESC sec_desc;*/
+ report(out_hnd, "\tstatus:\t%d\n", i2->status);
+ report(out_hnd, "\tpriority:\t%d\n", i2->priority);
+ report(out_hnd, "\tposition:\t%d\n", i2->position);
+ report(out_hnd, "\tstarttime:\t%d\n", i2->starttime);
+ report(out_hnd, "\tuntiltime:\t%d\n", i2->untiltime);
+ report(out_hnd, "\ttotalpages:\t%d\n", i2->totalpages);
+ report(out_hnd, "\tsize:\t%d\n", i2->size);
+/*
+ SYSTEMTIME submitted;
+*/
+ report(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n");
+ report(out_hnd, "\ttimeelapsed:\t%d\n", i2->timeelapsed);
+ report(out_hnd, "\tpagesprinted:\t%d\n", i2->pagesprinted);
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+job info level 1 display function
+****************************************************************************/
+void display_job_info_1(FILE *out_hnd, enum action_type action,
+ JOB_INFO_1 *const i1)
+{
+ if (i1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Job Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring tmp;
+
+ report(out_hnd, "\tjob id:\t%d\n", i1->jobid);
+ rpcstr_pull(tmp, i1->printername.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tprinter name:\t%s\n", tmp);
+ rpcstr_pull(tmp, i1->machinename.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tmachine name:\t%s\n", tmp);
+ rpcstr_pull(tmp, i1->username.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tusername:\t%s\n", tmp);
+ rpcstr_pull(tmp, i1->document.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tdocument:\t%s\n", tmp);
+ rpcstr_pull(tmp, i1->datatype.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\tdata type:\t%s\n", tmp);
+ rpcstr_pull(tmp, i1->text_status.buffer, sizeof(tmp), 0, STR_TERMINATE);
+ report(out_hnd, "\ttext status:\t%s\n", tmp);
+ report(out_hnd, "\tstatus:\t%d\n", i1->status);
+ report(out_hnd, "\tpriority:\t%d\n", i1->priority);
+ report(out_hnd, "\tposition:\t%d\n", i1->position);
+ report(out_hnd, "\ttotalpages:\t%d\n", i1->totalpages);
+/*
+ SYSTEMTIME submitted;
+*/
+ report(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n");
+ report(out_hnd, "\tpagesprinted:\t%d\n", i1->pagesprinted);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 2 container display function
+****************************************************************************/
+void display_job_info_2_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_2 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_2_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_job_info_2(out_hnd, ACTION_HEADER , ctr[i]);
+ display_job_info_2(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_job_info_2(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_job_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_1 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_job_info_1(out_hnd, ACTION_HEADER , ctr[i]);
+ display_job_info_1(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_job_info_1(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_job_info_ctr(FILE *out_hnd, enum action_type action,
+ uint32 level, uint32 count,
+ void *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (level)
+ {
+ case 1:
+ {
+ display_job_info_1_ctr(out_hnd, action,
+ count, (JOB_INFO_1*const*const)ctr);
+ break;
+ }
+ case 2:
+ {
+ display_job_info_2_ctr(out_hnd, action,
+ count, (JOB_INFO_2*const*const)ctr);
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_job_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+printer info level 0 display function
+****************************************************************************/
+static void display_print_driver_1(FILE *out_hnd, DRIVER_INFO_1 *i1)
+{
+ fstring name;
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tname:[%s]\n", name);
+}
+
+/****************************************************************************
+printer info level 1 display function
+****************************************************************************/
+static void display_print_driver_2(FILE *out_hnd, DRIVER_INFO_2 *i1)
+{
+ fstring name;
+ fstring architecture;
+ fstring driverpath;
+ fstring datafile;
+ fstring configfile;
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->conigfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tversion:[%x]\n", i1->version);
+ report(out_hnd, "\tname:[%s]\n", name);
+ report(out_hnd, "\tarchitecture:[%s]\n", architecture);
+ report(out_hnd, "\tdriverpath:[%s]\n", driverpath);
+ report(out_hnd, "\tdatafile:[%s]\n", datafile);
+ report(out_hnd, "\tconfigfile:[%s]\n", configfile);
+}
+
+/****************************************************************************
+printer info level 2 display function
+****************************************************************************/
+static void display_print_driver_3(FILE *out_hnd, DRIVER_INFO_3 *i1)
+{
+ fstring name;
+ fstring architecture;
+ fstring driverpath;
+ fstring datafile;
+ fstring configfile;
+ fstring helpfile;
+ fstring dependentfiles;
+ fstring monitorname;
+ fstring defaultdatatype;
+
+ int length=0;
+ BOOL valid = True;
+
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
+ rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), 0, STR_TERMINATE);
+ rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), 0, STR_TERMINATE);
+ rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tversion:[%x]\n", i1->version);
+ report(out_hnd, "\tname:[%s]\n",name);
+ report(out_hnd, "\tarchitecture:[%s]\n", architecture);
+ report(out_hnd, "\tdriverpath:[%s]\n", driverpath);
+ report(out_hnd, "\tdatafile:[%s]\n", datafile);
+ report(out_hnd, "\tconfigfile:[%s]\n", configfile);
+ report(out_hnd, "\thelpfile:[%s]\n\n", helpfile);
+
+ while (valid)
+ {
+ rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), 0, STR_TERMINATE);
+ length+=strlen(dependentfiles)+1;
+
+ if (strlen(dependentfiles) > 0)
+ {
+ report(out_hnd, "\tdependentfiles:[%s]\n", dependentfiles);
+ }
+ else
+ {
+ valid = False;
+ }
+ }
+
+ report(out_hnd, "\n\tmonitorname:[%s]\n", monitorname);
+ report(out_hnd, "\tdefaultdatatype:[%s]\n", defaultdatatype);
+
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+static void display_printer_driver_1_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_DRIVER_CTR ctr)
+{
+ int i;
+ DRIVER_INFO_1 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer driver Level 1:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.info1;
+ display_print_driver_1(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 2 container display function
+****************************************************************************/
+static void display_printer_driver_2_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_DRIVER_CTR ctr)
+{
+ int i;
+ DRIVER_INFO_2 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer driver Level 2:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.info2;
+ display_print_driver_2(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info level 3 container display function
+****************************************************************************/
+static void display_printer_driver_3_ctr(FILE *out_hnd, enum action_type action, uint32 count, PRINTER_DRIVER_CTR ctr)
+{
+ int i;
+ DRIVER_INFO_3 *in;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer driver Level 3:\n");
+ break;
+ case ACTION_ENUMERATE:
+ for (i = 0; i < count; i++) {
+ in=ctr.info3;
+ display_print_driver_3(out_hnd, &(in[i]) );
+ }
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_printer_driver_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+ uint32 count, PRINTER_DRIVER_CTR ctr)
+{
+ switch (level) {
+ case 1:
+ display_printer_driver_1_ctr(out_hnd, action, count, ctr);
+ break;
+ case 2:
+ display_printer_driver_2_ctr(out_hnd, action, count, ctr);
+ break;
+ case 3:
+ display_printer_driver_3_ctr(out_hnd, action, count, ctr);
+ break;
+ default:
+ report(out_hnd, "display_printer_driver_ctr: Unknown Info Level\n");
+ break;
+ }
+}
+
+
+/****************************************************************************
+printer info level 1 display function
+****************************************************************************/
+static void display_printdriverdir_info_1(FILE *out_hnd, DRIVER_DIRECTORY_1 *i1)
+{
+ fstring name;
+ if (i1 == NULL)
+ return;
+
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+
+ report(out_hnd, "\tname:[%s]\n", name);
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+static void display_printerdriverdir_info_1_ctr(FILE *out_hnd, enum action_type action, DRIVER_DIRECTORY_CTR ctr)
+{
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ report(out_hnd, "Printer driver dir Info Level 1:\n");
+ break;
+ case ACTION_ENUMERATE:
+ display_printdriverdir_info_1(out_hnd, &(ctr.driver.info_1) );
+ break;
+ case ACTION_FOOTER:
+ report(out_hnd, "\n");
+ break;
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_printerdriverdir_info_ctr(FILE *out_hnd, enum action_type action, uint32 level,
+ DRIVER_DIRECTORY_CTR ctr)
+{
+ switch (level) {
+ case 1:
+ display_printerdriverdir_info_1_ctr(out_hnd, action, ctr);
+ break;
+ default:
+ report(out_hnd, "display_printerdriverdir_info_ctr: Unknown Info Level\n");
+ break;
+ }
+}
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 8372b75b4bd..239ff668f38 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -1,9 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2
RPC pipe client
Copyright (C) Tim Potter 2000-2001
- Copyright (C) Martin Pool 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,12 +25,7 @@
DOM_SID domain_sid;
-
-/* List to hold groups of commands.
- *
- * Commands are defined in a list of arrays: arrays are easy to
- * statically declare, and lists are easier to dynamically extend.
- */
+/* List to hold groups of commands */
static struct cmd_list {
struct cmd_list *prev, *next;
@@ -73,10 +68,7 @@ static char **completion_fn(const char *text, int start, int end)
for (i=0; commands->cmd_set[i].name; i++)
{
if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
- (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
- commands->cmd_set[i].ntfn ) ||
- ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
- commands->cmd_set[i].wfn)))
+ commands->cmd_set[i].fn)
{
matches[count] = strdup(commands->cmd_set[i].name);
if (!matches[count])
@@ -97,48 +89,130 @@ static char **completion_fn(const char *text, int start, int end)
return matches;
}
+/***********************************************************************
+ * read in username/password credentials from a file
+ */
+static void read_authfile (
+ char *filename,
+ char* username,
+ char* password,
+ char* domain
+)
+{
+ FILE *auth;
+ fstring buf;
+ uint16 len = 0;
+ char *ptr, *val, *param;
+
+ if ((auth=sys_fopen(filename, "r")) == NULL)
+ {
+ printf ("ERROR: Unable to open credentials file!\n");
+ return;
+ }
+
+ while (!feof(auth))
+ {
+ /* get a line from the file */
+ if (!fgets (buf, sizeof(buf), auth))
+ continue;
+
+ len = strlen(buf);
+
+ /* skip empty lines */
+ if ((len) && (buf[len-1]=='\n'))
+ {
+ buf[len-1] = '\0';
+ len--;
+ }
+ if (len == 0)
+ continue;
+
+ /* break up the line into parameter & value.
+ will need to eat a little whitespace possibly */
+ param = buf;
+ if (!(ptr = strchr(buf, '=')))
+ continue;
+ val = ptr+1;
+ *ptr = '\0';
+
+ /* eat leading white space */
+ while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
+ val++;
+
+ if (strwicmp("password", param) == 0)
+ fstrcpy (password, val);
+ else if (strwicmp("username", param) == 0)
+ fstrcpy (username, val);
+ else if (strwicmp("domain", param) == 0)
+ fstrcpy (domain, val);
+
+ memset(buf, 0, sizeof(buf));
+ }
+ fclose(auth);
+
+ return;
+}
+
static char* next_command (char** cmdstr)
{
static pstring command;
char *p;
+ BOOL next_cmd = False;
if (!cmdstr || !(*cmdstr))
return NULL;
- p = strchr_m(*cmdstr, ';');
- if (p)
+ printf("cmd = %s\n", *cmdstr);
+
+ p = strchr(*cmdstr, ';');
+ if (p) {
+ next_cmd = True;
*p = '\0';
+ }
pstrcpy(command, *cmdstr);
- if (p)
- *cmdstr = p + 1;
- else
- *cmdstr = NULL;
-
+ *cmdstr = p;
+ if (next_cmd)
+ p++;
+
return command;
}
+static void get_username (char *username)
+{
+ if (getenv("USER"))
+ pstrcpy(username,getenv("USER"));
+
+ if (*username == 0 && getenv("LOGNAME"))
+ pstrcpy(username,getenv("LOGNAME"));
+
+ if (*username == 0) {
+ pstrcpy(username,"GUEST");
+ }
+
+ return;
+}
+
/* Fetch the SID for this computer */
-static void fetch_machine_sid(struct cli_state *cli)
+void fetch_machine_sid(struct cli_state *cli)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_OK;
uint32 info_class = 5;
- char *domain_name = NULL;
+ fstring domain_name;
static BOOL got_domain_sid;
TALLOC_CTX *mem_ctx;
- DOM_SID *dom_sid = NULL;
if (got_domain_sid) return;
- if (!(mem_ctx=talloc_init("fetch_machine_sid")))
+ if (!(mem_ctx=talloc_init()))
{
DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
goto error;
}
- if (!cli_nt_session_open (cli, PI_LSARPC)) {
+ if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
fprintf(stderr, "could not initialise lsa pipe\n");
goto error;
}
@@ -151,13 +225,12 @@ static void fetch_machine_sid(struct cli_state *cli)
}
result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
- &domain_name, &dom_sid);
+ domain_name, &domain_sid);
if (!NT_STATUS_IS_OK(result)) {
goto error;
}
got_domain_sid = True;
- sid_copy( &domain_sid, dom_sid );
cli_lsa_close(cli, mem_ctx, &pol);
cli_nt_session_close(cli);
@@ -169,7 +242,7 @@ static void fetch_machine_sid(struct cli_state *cli)
fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
if (!NT_STATUS_IS_OK(result)) {
- fprintf(stderr, "error: %s\n", nt_errstr(result));
+ fprintf(stderr, "error: %s\n", get_nt_error_msg(result));
}
exit(1);
@@ -178,7 +251,7 @@ static void fetch_machine_sid(struct cli_state *cli)
/* List the available commands on a given pipe */
static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
struct cmd_list *tmp;
struct cmd_set *tmp_set;
@@ -223,7 +296,7 @@ static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Display help on commands */
static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
struct cmd_list *tmp;
struct cmd_set *tmp_set;
@@ -283,7 +356,7 @@ static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Change the debug level */
static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
if (argc > 2) {
printf("Usage: %s [debuglevel]\n", argv[0]);
@@ -300,155 +373,30 @@ static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
static NTSTATUS cmd_quit(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ int argc, char **argv)
{
exit(0);
return NT_STATUS_OK; /* NOTREACHED */
}
-static NTSTATUS cmd_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- if (cli->pipe_auth_flags == (AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN)) {
- return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_seal(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- if (cli->pipe_auth_flags == (AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) {
- return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
- }
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- if (cli->pipe_auth_flags == 0) {
- return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = 0;
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
- }
- cli->pipe_auth_flags = 0;
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS setup_schannel(struct cli_state *cli, int pipe_auth_flags,
- int argc, const char **argv)
-{
- NTSTATUS ret;
- static uchar zeros[16];
- uchar trust_password[16];
- uint32 sec_channel_type;
- if (argc == 2) {
- strhex_to_str((char *)cli->auth_info.sess_key,
- strlen(argv[1]),
- argv[1]);
- memcpy(cli->sess_key, cli->auth_info.sess_key, sizeof(cli->sess_key));
-
- cli->pipe_auth_flags = pipe_auth_flags;
- return NT_STATUS_OK;
- }
-
- /* Cleanup */
-
- if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)) {
- if (cli->pipe_auth_flags == pipe_auth_flags) {
- /* already in this mode nothing to do */
- return NT_STATUS_OK;
- } else {
- /* schannel is setup, just need to use it again with new flags */
- cli->pipe_auth_flags = pipe_auth_flags;
-
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
- return NT_STATUS_OK;
- }
- }
-
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
-
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password,
- NULL, &sec_channel_type)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = cli_nt_setup_netsec(cli, sec_channel_type, pipe_auth_flags, trust_password);
- if (NT_STATUS_IS_OK(ret)) {
- char *hex_session_key;
- hex_encode(cli->auth_info.sess_key,
- sizeof(cli->auth_info.sess_key),
- &hex_session_key);
- printf("Got Session key: %s\n", hex_session_key);
- SAFE_FREE(hex_session_key);
- }
- return ret;
-}
-
-
-static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- d_printf("Setting schannel - sign and seal\n");
- return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL,
- argc, argv);
-}
-
-static NTSTATUS cmd_schannel_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- d_printf("Setting schannel - sign only\n");
- return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN,
- argc, argv);
-}
-
-
-/* Built in rpcclient commands */
+/* Build in rpcclient commands */
static struct cmd_set rpcclient_commands[] = {
{ "GENERAL OPTIONS" },
- { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, "Get help on commands", "[command]" },
- { "?", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, "Get help on commands", "[command]" },
- { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL, -1, "Set debug level", "level" },
- { "list", RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, -1, "List available commands on <pipe>", "pipe" },
- { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, "Exit program", "" },
- { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, "Exit program", "" },
- { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL, -1, "Force RPC pipe connections to be signed", "" },
- { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL, -1, "Force RPC pipe connections to be sealed", "" },
- { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL, -1, "Force RPC pipe connections to be sealed with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
- { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL, -1, "Force RPC pipe connections to be signed (not sealed) with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
- { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL, -1, "Force RPC pipe connections to have no special properties", "" },
+ { "help", cmd_help, NULL, "Get help on commands", "[command]" },
+ { "?", cmd_help, NULL, "Get help on commands", "[command]" },
+ { "debuglevel", cmd_debuglevel, NULL, "Set debug level", "level" },
+ { "list", cmd_listcommands, NULL, "List available commands on <pipe>", "pipe" },
+ { "exit", cmd_quit, NULL, "Exit program", "" },
+ { "quit", cmd_quit, NULL, "Exit program", "" },
{ NULL }
};
static struct cmd_set separator_command[] = {
- { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL, -1, "----------------------" },
+ { "---------------", NULL, NULL, "----------------------" },
{ NULL }
};
@@ -462,24 +410,16 @@ extern struct cmd_set netlogon_commands[];
extern struct cmd_set srvsvc_commands[];
extern struct cmd_set dfs_commands[];
extern struct cmd_set reg_commands[];
-extern struct cmd_set ds_commands[];
-extern struct cmd_set echo_commands[];
-extern struct cmd_set shutdown_commands[];
-extern struct cmd_set epm_commands[];
static struct cmd_set *rpcclient_command_list[] = {
rpcclient_commands,
lsarpc_commands,
- ds_commands,
samr_commands,
spoolss_commands,
netlogon_commands,
srvsvc_commands,
dfs_commands,
reg_commands,
- echo_commands,
- shutdown_commands,
- epm_commands,
NULL
};
@@ -498,262 +438,344 @@ static void add_command_set(struct cmd_set *cmd_set)
DLIST_ADD(cmd_list, entry);
}
-
-/**
- * Call an rpcclient function, passing an argv array.
- *
- * @param cmd Command to run, as a single string.
- **/
-static NTSTATUS do_cmd(struct cli_state *cli,
- struct cmd_set *cmd_entry,
- int argc, char **argv)
+static NTSTATUS do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry,
+ char *cmd)
{
- NTSTATUS ntresult;
- WERROR wresult;
- uchar trust_password[16];
-
- TALLOC_CTX *mem_ctx;
-
- /* Create mem_ctx */
-
- if (!(mem_ctx = talloc_init("do_cmd"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- return NT_STATUS_NO_MEMORY;
+ char **argv = NULL;
+ const char *p = cmd;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ pstring buf;
+ int argc = 0, i;
+
+ /* Count number of arguments first time through the loop then
+ allocate memory and strdup them. */
+
+ again:
+ while(next_token(&p, buf, " ", sizeof(buf))) {
+ if (argv) {
+ argv[argc] = strdup(buf);
+ }
+
+ argc++;
}
+
+ if (!argv) {
- /* Open pipe */
+ /* Create argument list */
- if (cmd_entry->pipe_idx != -1
- && cmd_entry->pipe_idx != cli->pipe_idx) {
- if (cli->nt_pipe_fnum != 0)
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(cmd_entry->pipe_idx)));
- return NT_STATUS_UNSUCCESSFUL;
+ argv = (char **)malloc(sizeof(char *) * argc);
+ memset(argv, 0, sizeof(char *) * argc);
+
+ if (!argv) {
+ fprintf(stderr, "out of memory\n");
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
+
+ p = cmd;
+ argc = 0;
+
+ goto again;
}
- /* some of the DsXXX commands use the netlogon pipe */
+ /* Call the function */
- if (lp_client_schannel() && (cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
- uint32 sec_channel_type;
-
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password,
- NULL, &sec_channel_type)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ntresult = cli_nt_setup_creds(cli, sec_channel_type,
- trust_password,
- &neg_flags, 2);
- if (!NT_STATUS_IS_OK(ntresult)) {
- ZERO_STRUCT(cli->auth_info.sess_key);
- printf("nt_setup_creds failed with %s\n", nt_errstr(ntresult));
- return ntresult;
- }
-
- }
+ if (cmd_entry->fn) {
+ TALLOC_CTX *mem_ctx;
- /* Run command */
-
- if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
- ntresult = cmd_entry->ntfn(cli, mem_ctx, argc, (const char **) argv);
- if (!NT_STATUS_IS_OK(ntresult)) {
- printf("result was %s\n", nt_errstr(ntresult));
- }
- } else {
- wresult = cmd_entry->wfn( cli, mem_ctx, argc, (const char **) argv);
- /* print out the DOS error */
- if (!W_ERROR_IS_OK(wresult)) {
- printf( "result was %s\n", dos_errstr(wresult));
- }
- ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
- }
-
+ /* Create mem_ctx */
- /* Cleanup */
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("talloc_init() failed\n"));
+ goto done;
+ }
- talloc_destroy(mem_ctx);
+ /* Open pipe */
+
+ if (cmd_entry->pipe)
+ if (!cli_nt_session_open(cli, cmd_entry->pipe)) {
+ DEBUG(0, ("Could not initialise %s\n",
+ cmd_entry->pipe));
+ goto done;
+ }
+
+ /* Run command */
+
+ result = cmd_entry->fn(cli, mem_ctx, argc, argv);
+
+ /* Cleanup */
+
+ if (cmd_entry->pipe)
+ cli_nt_session_close(cli);
+
+ talloc_destroy(mem_ctx);
- return ntresult;
+ } else {
+ fprintf (stderr, "Invalid command\n");
+ goto done;
+ }
+
+ done:
+
+ /* Cleanup */
+
+ if (argv) {
+ for (i = 0; i < argc; i++)
+ SAFE_FREE(argv[i]);
+
+ SAFE_FREE(argv);
+ }
+
+ return result;
}
+/* Process a command entered at the prompt or as part of -c */
-/**
- * Process a command entered at the prompt or as part of -c
- *
- * @returns The NTSTATUS from running the command.
- **/
static NTSTATUS process_cmd(struct cli_state *cli, char *cmd)
{
struct cmd_list *temp_list;
+ BOOL found = False;
+ pstring buf;
+ const char *p = cmd;
NTSTATUS result = NT_STATUS_OK;
- int ret;
- int argc;
- char **argv = NULL;
+ int len = 0;
+
+ if (cmd[strlen(cmd) - 1] == '\n')
+ cmd[strlen(cmd) - 1] = '\0';
- if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
- fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
- return NT_STATUS_UNSUCCESSFUL;
+ if (!next_token(&p, buf, " ", sizeof(buf))) {
+ return NT_STATUS_OK;
}
+ /* strip the trainly \n if it exsists */
+ len = strlen(buf);
+ if (buf[len-1] == '\n')
+ buf[len-1] = '\0';
+
+ /* Search for matching commands */
- /* Walk through a dlist of arrays of commands. */
for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
struct cmd_set *temp_set = temp_list->cmd_set;
- while (temp_set->name) {
- if (strequal(argv[0], temp_set->name)) {
- if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
- !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
- fprintf (stderr, "Invalid command\n");
- goto out_free;
- }
-
- result = do_cmd(cli, temp_set, argc, argv);
+ while(temp_set->name) {
+ if (strequal(buf, temp_set->name)) {
+ found = True;
+ result = do_cmd(cli, temp_set, cmd);
- goto out_free;
+ goto done;
}
temp_set++;
}
}
- if (argv[0]) {
- printf("command not found: %s\n", argv[0]);
+ done:
+ if (!found && buf[0]) {
+ printf("command not found: %s\n", buf);
+ return NT_STATUS_OK;
}
-out_free:
-/* moved to do_cmd()
if (!NT_STATUS_IS_OK(result)) {
- printf("result was %s\n", nt_errstr(result));
+ printf("result was %s\n", get_nt_error_msg(result));
}
-*/
- if (argv) {
- /* NOTE: popt allocates the whole argv, including the
- * strings, as a single block. So a single free is
- * enough to release it -- we don't free the
- * individual strings. rtfm. */
- free(argv);
- }
-
return result;
}
+/* Print usage information */
+static void usage(void)
+{
+ printf("Usage: rpcclient [options] server\n");
+ printf("Version: %s\n", VERSION);
+
+ printf("\t-A authfile file containing user credentials\n");
+ printf("\t-c \"command string\" execute semicolon separated cmds\n");
+ printf("\t-d debuglevel set the debuglevel\n");
+ printf("\t-l logfile name of logfile to use as opposed to stdout\n");
+ printf("\t-h Print this help message.\n");
+ printf("\t-N don't ask for a password\n");
+ printf("\t-s configfile specify an alternative config file\n");
+ printf("\t-U username set the network username\n");
+ printf("\t-W domain set the domain name for user account\n");
+ printf("\n");
+}
+
/* Main function */
- int main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
+ extern char *optarg;
+ extern int optind;
+ extern pstring global_myname;
+ BOOL got_pass = False;
BOOL interactive = True;
int opt;
- static char *cmdstr = NULL;
- const char *server;
+ int olddebug;
+ pstring cmdstr = "",
+ servicesf = CONFIGFILE;
+ fstring password,
+ username,
+ domain,
+ server;
struct cli_state *cli;
- static char *opt_ipaddr=NULL;
- struct cmd_set **cmd_set;
+ pstring logfile;
+ struct cmd_set **cmd_set;
struct in_addr server_ip;
NTSTATUS nt_status;
-
- /* make sure the vars that get altered (4th field) are in
- a fixed location or certain compilers complain */
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
- {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
- POPT_COMMON_SAMBA
- POPT_COMMON_CONNECTION
- POPT_COMMON_CREDENTIALS
- POPT_TABLEEND
- };
-
- ZERO_STRUCT(server_ip);
+ extern BOOL AllowDebugChange;
setlinebuf(stdout);
- /* the following functions are part of the Samba debugging
- facilities. See lib/debug.c */
- setup_logging("rpcclient", interactive);
- if (!interactive)
- reopen_logs();
-
- /* Load smb.conf file */
-
- if (!lp_load(dyn_CONFIGFILE,True,False,False))
- fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
+ DEBUGLEVEL = 1;
+ AllowDebugChange = False;
/* Parse options */
- pc = poptGetContext("rpcclient", argc, (const char **) argv,
- long_options, 0);
-
if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
+ usage();
return 0;
}
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'I':
- if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) {
- fprintf(stderr, "%s not a valid IP address\n",
- opt_ipaddr);
+ /*
+ * M. Sweet: getopt() behaves slightly differently on various
+ * platforms. The following loop ensures that the System V,
+ * BSD, and Linux (glibc) implementations work similarly to
+ * allow the server name anywhere on the command-line.
+ */
+
+ pstrcpy(server, "");
+
+ while (argc > optind) {
+ while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:h")) != EOF) {
+ switch (opt) {
+ case 'A':
+ /* only get the username, password, and domain from the file */
+ read_authfile (optarg, username, password, domain);
+ if (strlen (password))
+ got_pass = True;
+ break;
+
+ case 'c':
+ pstrcpy(cmdstr, optarg);
+ break;
+
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+
+ case 'l':
+ slprintf(logfile, sizeof(logfile) - 1, "%s.client", optarg);
+ lp_set_logfile(logfile);
+ interactive = False;
+ break;
+
+ case 'N':
+ got_pass = True;
+ break;
+
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
+
+ case 'U': {
+ char *lp;
+ pstrcpy(username,optarg);
+ if ((lp=strchr(username,'%'))) {
+ *lp = 0;
+ pstrcpy(password,lp+1);
+ got_pass = True;
+ memset(strchr(optarg,'%')+1,'X',strlen(password));
+ }
+ break;
+ }
+
+ case 'W':
+ pstrcpy(domain, optarg);
+ break;
+
+ case 'h':
+ default:
+ usage();
return 1;
}
}
+
+ if (argc > optind) {
+ if (strncmp("//", argv[optind], 2) == 0 ||
+ strncmp("\\\\", argv[optind], 2) == 0)
+ {
+ argv[optind] += 2;
+ }
+
+ pstrcpy(server, argv[optind]);
+ optind ++;
+ }
}
- /* Get server as remaining unparsed argument. Print usage if more
- than one unparsed argument is present. */
+ if (!server[0]) {
+ usage();
+ return 1;
+ }
- server = poptGetArg(pc);
+ /* the following functions are part of the Samba debugging
+ facilities. See lib/debug.c */
+ setup_logging("rpcclient", interactive);
+ if (!interactive)
+ reopen_logs();
- if (!server || poptGetArg(pc)) {
- poptPrintHelp(pc, stderr, 0);
- return 1;
+ TimeInit();
+ charset_initialise();
+
+ /* Load smb.conf file */
+ /* FIXME! How to get this DEBUGLEVEL to last over lp_load()? */
+ olddebug = DEBUGLEVEL;
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s\n", servicesf);
}
+ DEBUGLEVEL = olddebug;
- poptFreeContext(pc);
+ codepage_initialise(lp_client_code_page());
load_interfaces();
- if (!init_names())
- return 1;
+ get_myname((*global_myname)?NULL:global_myname);
+ strupper(global_myname);
+
+ /* Resolve the IP address */
+ if (!resolve_name(server, &server_ip, 0x20)) {
+ DEBUG(1,("Unable to resolve %s\n", server));
+ return 1;
+ }
+
/*
* Get password
* from stdin if necessary
*/
-
- if (!cmdline_auth_info.got_pass) {
+
+ if (!got_pass) {
char *pass = getpass("Password:");
if (pass) {
- pstrcpy(cmdline_auth_info.password, pass);
- }
+ fstrcpy(password, pass);
}
-
- nt_status = cli_full_connection(&cli, global_myname(), server,
- opt_ipaddr ? &server_ip : NULL, 0,
+ }
+
+ if (!strlen(username) && !got_pass)
+ get_username(username);
+
+ nt_status = cli_full_connection(&cli, global_myname, server,
+ &server_ip, 0,
"IPC$", "IPC",
- cmdline_auth_info.username,
- lp_workgroup(),
- cmdline_auth_info.password,
- cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
- cmdline_auth_info.signing_state,NULL);
+ username, domain,
+ password, strlen(password));
if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
+ DEBUG(1,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
return 1;
}
-
- memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
-
+
+ memset(password,'X',sizeof(password));
+
/* Load command lists */
cmd_set = rpcclient_command_list;
@@ -767,18 +789,16 @@ out_free:
fetch_machine_sid(cli);
/* Do anything specified with -c */
- if (cmdstr && cmdstr[0]) {
+ if (cmdstr[0]) {
char *cmd;
char *p = cmdstr;
- int result = 0;
while((cmd=next_command(&p)) != NULL) {
- NTSTATUS cmd_result = process_cmd(cli, cmd);
- result = NT_STATUS_IS_ERR(cmd_result);
+ process_cmd(cli, cmd);
}
-
+
cli_shutdown(cli);
- return result;
+ return 0;
}
/* Loop around accepting commands */
@@ -797,7 +817,7 @@ out_free:
if (line[0] != '\n')
process_cmd(cli, line);
}
-
+
cli_shutdown(cli);
return 0;
}
diff --git a/source/rpcclient/rpcclient.h b/source/rpcclient/rpcclient.h
index e1e61dc43d5..a74c9dffde7 100644
--- a/source/rpcclient/rpcclient.h
+++ b/source/rpcclient/rpcclient.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2
RPC pipe client
Copyright (C) Tim Potter 2000
@@ -22,19 +23,11 @@
#ifndef RPCCLIENT_H
#define RPCCLIENT_H
-typedef enum {
- RPC_RTYPE_NTSTATUS = 0,
- RPC_RTYPE_WERROR,
- MAX_RPC_RETURN_TYPE
-} RPC_RETURN_TYPE;
-
struct cmd_set {
const char *name;
- RPC_RETURN_TYPE returntype;
- NTSTATUS (*ntfn)(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc,
- const char **argv);
- WERROR (*wfn)(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv);
- int pipe_idx;
+ NTSTATUS (*fn)(struct cli_state*, TALLOC_CTX *mem_ctx, int argc,
+ char **argv);
+ const char *pipe;
const char *description;
const char *usage;
};
diff --git a/source/rpcclient/samsync.c b/source/rpcclient/samsync.c
new file mode 100755
index 00000000000..152b5091abc
--- /dev/null
+++ b/source/rpcclient/samsync.c
@@ -0,0 +1,364 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.2
+ RPC pipe client
+
+ Copyright (C) Tim Potter 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Synchronise sam database */
+
+static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16],
+ BOOL do_smbpasswd_output)
+{
+ TALLOC_CTX *mem_ctx;
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+ uint32 database_id = 0, num_deltas;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ /* Initialise */
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0,("talloc_init failed\n"));
+ return result;
+ }
+
+ if (!cli_nt_session_open (cli, PIPE_NETLOGON)) {
+ DEBUG(0, ("Could not initialize netlogon pipe!\n"));
+ goto done;
+ }
+
+ /* Request a challenge */
+
+ if (!NT_STATUS_IS_OK(new_cli_nt_setup_creds(cli, trust_passwd))) {
+ DEBUG(0, ("Error initialising session creds\n"));
+ goto done;
+ }
+
+ /* Do sam synchronisation */
+
+ result = cli_netlogon_sam_sync(cli, mem_ctx, database_id,
+ &num_deltas, &hdr_deltas, &deltas);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Produce smbpasswd output - good for migrating from NT! */
+
+ if (do_smbpasswd_output) {
+ int i;
+
+ for (i = 0; i < num_deltas; i++) {
+ SAM_ACCOUNT_INFO *a;
+ fstring acct_name, hex_nt_passwd, hex_lm_passwd;
+ uchar lm_passwd[16], nt_passwd[16];
+
+ /* Skip non-user accounts */
+
+ if (hdr_deltas[i].type != SAM_DELTA_ACCOUNT_INFO)
+ continue;
+
+ a = &deltas[i].account_info;
+
+ unistr2_to_unix(acct_name, &a->uni_acct_name,
+ sizeof(acct_name) - 1);
+
+ /* Decode hashes from password hash */
+
+ sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd,
+ lm_passwd, 0);
+ sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd,
+ nt_passwd, 0);
+
+ /* Encode as strings */
+
+ smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd,
+ a->acb_info);
+ smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd,
+ a->acb_info);
+
+ /* Display user info */
+
+ printf("%s:%d:%s:%s:%s:LCT-0\n", acct_name,
+ a->user_rid, hex_lm_passwd, hex_nt_passwd,
+ smbpasswd_encode_acb_info(
+ deltas[i].account_info.acb_info));
+ }
+
+ goto done;
+ }
+
+ /* Update sam tdb */
+
+ done:
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Replicate sam deltas */
+
+static NTSTATUS sam_repl(struct cli_state *cli, unsigned char trust_passwde[16],
+ uint32 low_serial)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ return result;
+}
+
+/* Print usage information */
+
+static void usage(void)
+{
+ printf("Usage: samsync [options]\n");
+ printf("Version: %s\n", VERSION);
+
+ printf("\t-d debuglevel set the debuglevel\n");
+ printf("\t-h Print this help message.\n");
+ printf("\t-s configfile specify an alternative config file\n");
+ printf("\t-S synchronise sam database\n");
+ printf("\t-R replicate sam deltas\n");
+ printf("\t-U username username and password\n");
+ printf("\t-p produce smbpasswd output\n");
+ printf("\n");
+}
+
+/* Initialise client credentials for authenticated pipe access */
+
+void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
+ char* domain, char* password)
+{
+ ZERO_STRUCTP(creds);
+
+ if (lp_encrypted_passwords()) {
+ pwd_make_lm_nt_16(&creds->pwd, password);
+ } else {
+ pwd_set_cleartext(&creds->pwd, password);
+ }
+
+ fstrcpy(creds->user_name, username);
+ fstrcpy(creds->domain, domain);
+
+ if (! *username) {
+ creds->pwd.null_pwd = True;
+ }
+}
+
+/* Connect to primary domain controller */
+
+static struct cli_state *init_connection(struct cli_state *cli,
+ char *username, char *domain,
+ char *password)
+{
+ struct ntuser_creds creds;
+ extern pstring global_myname;
+ struct in_addr *dest_ip;
+ struct nmb_name calling, called;
+ int count;
+ fstring dest_host;
+
+ /* Initialise cli_state information */
+
+ ZERO_STRUCTP(cli);
+
+ if (!cli_initialise(cli)) {
+ return NULL;
+ }
+
+ init_rpcclient_creds(&creds, username, domain, password);
+ cli_init_creds(cli, &creds);
+
+ /* Look up name of PDC controller */
+
+ if (!get_dc_list(True, lp_workgroup(), &dest_ip, &count)) {
+ DEBUG(0, ("Cannot find domain controller for domain %s\n",
+ lp_workgroup()));
+ return NULL;
+ }
+
+ if (!lookup_pdc_name(global_myname, lp_workgroup(), dest_ip,
+ dest_host)) {
+ DEBUG(0, ("Could not lookup up PDC name for domain %s\n",
+ lp_workgroup()));
+ return NULL;
+ }
+
+ get_myname((*global_myname)?NULL:global_myname);
+ strupper(global_myname);
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ /* Establish a SMB connection */
+
+ if (!cli_establish_connection(cli, dest_host, dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ return NULL;
+ }
+
+ return cli;
+}
+
+/* Main function */
+
+ int main(int argc, char **argv)
+{
+ BOOL do_sam_sync = False, do_sam_repl = False;
+ pstring servicesf = CONFIGFILE;
+ struct cli_state cli;
+ NTSTATUS result;
+ int opt;
+ pstring logfile;
+ BOOL interactive = False, do_smbpasswd_output = False;
+ uint32 low_serial = 0;
+ unsigned char trust_passwd[16];
+ fstring username, domain, password;
+
+ if (argc == 1) {
+ usage();
+ return 1;
+ }
+
+ ZERO_STRUCT(username);
+ ZERO_STRUCT(domain);
+ ZERO_STRUCT(password);
+
+ /* Parse command line options */
+
+ while((opt = getopt(argc, argv, "s:d:SR:hiU:W:p")) != EOF) {
+ switch (opt) {
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 'S':
+ do_sam_sync = 1;
+ break;
+ case 'R':
+ do_sam_repl = 1;
+ low_serial = atoi(optarg);
+ break;
+ case 'i':
+ interactive = True;
+ break;
+ case 'U': {
+ char *lp;
+
+ fstrcpy(username,optarg);
+ if ((lp=strchr(username,'%'))) {
+ *lp = 0;
+ fstrcpy(password,lp+1);
+ memset(strchr(optarg, '%') + 1, 'X',
+ strlen(password));
+ }
+ break;
+ }
+ case 'W':
+ pstrcpy(domain, optarg);
+ break;
+ case 'p':
+ do_smbpasswd_output = True;
+ break;
+ case 'h':
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ argc -= optind;
+
+ if (argc > 0) {
+ usage();
+ return 1;
+ }
+
+ /* Initialise samba */
+
+ slprintf(logfile, sizeof(logfile) - 1, "%s/log.%s", LOGFILEBASE,
+ "samsync");
+ lp_set_logfile(logfile);
+
+ setup_logging("samsync", interactive);
+
+ if (!interactive)
+ reopen_logs();
+
+ if (!lp_load(servicesf, True, False, False)) {
+ fprintf(stderr, "Can't load %s\n", servicesf);
+ }
+
+ load_interfaces();
+
+ TimeInit();
+
+ /* Check arguments make sense */
+
+ if (do_sam_sync && do_sam_repl) {
+ fprintf(stderr, "cannot specify both -S and -R\n");
+ return 1;
+
+ }
+
+ if (!do_sam_sync && !do_sam_repl) {
+ fprintf(stderr, "must specify either -S or -R\n");
+ return 1;
+ }
+
+ if (do_sam_repl && low_serial == 0) {
+ fprintf(stderr, "serial number must be positive\n");
+ return 1;
+ }
+
+ /* BDC operations require the machine account password */
+
+ if (!secrets_init()) {
+ DEBUG(0, ("Unable to initialise secrets database\n"));
+ return 1;
+ }
+
+ if (!secrets_fetch_trust_account_password(lp_workgroup(),
+ trust_passwd, NULL)) {
+ DEBUG(0, ("could not fetch trust account password\n"));
+ return 1;
+ }
+
+ /* Perform sync or replication */
+
+ if (!init_connection(&cli, username, domain, password))
+ return 1;
+
+ if (do_sam_sync)
+ result = sam_sync(&cli, trust_passwd, do_smbpasswd_output);
+
+ if (do_sam_repl)
+ result = sam_repl(&cli, trust_passwd, low_serial);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("%s\n", get_nt_error_msg(result)));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/source/sam/account.c b/source/sam/account.c
deleted file mode 100644
index b8336146cda..00000000000
--- a/source/sam/account.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Jeremy Allison 1996-2001
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Gerald (Jerry) Carter 2000-2001
- Copyright (C) Andrew Bartlett 2001-2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_SAM
-
-/************************************************************
- Fill the SAM_ACCOUNT_HANDLE with default values.
- ***********************************************************/
-
-static void sam_fill_default_account(SAM_ACCOUNT_HANDLE *account)
-{
- ZERO_STRUCT(account->private); /* Don't touch the talloc context */
-
- /* Don't change these timestamp settings without a good reason.
- They are important for NT member server compatibility. */
-
- /* FIXME: We should actually call get_nt_time_max() or sthng
- * here */
- unix_to_nt_time(&(account->private.logoff_time),get_time_t_max());
- unix_to_nt_time(&(account->private.kickoff_time),get_time_t_max());
- unix_to_nt_time(&(account->private.pass_must_change_time),get_time_t_max());
- account->private.unknown_1 = 0x00ffffff; /* don't know */
- account->private.logon_divs = 168; /* hours per week */
- account->private.hours_len = 21; /* 21 times 8 bits = 168 */
- memset(account->private.hours, 0xff, account->private.hours_len); /* available at all hours */
- account->private.unknown_2 = 0x00000000; /* don't know */
- account->private.unknown_3 = 0x000004ec; /* don't know */
-}
-
-static void destroy_sam_talloc(SAM_ACCOUNT_HANDLE **account)
-{
- if (*account) {
- data_blob_clear_free(&((*account)->private.lm_pw));
- data_blob_clear_free(&((*account)->private.nt_pw));
- if((*account)->private.plaintext_pw!=NULL)
- memset((*account)->private.plaintext_pw,'\0',strlen((*account)->private.plaintext_pw));
-
- talloc_destroy((*account)->mem_ctx);
- *account = NULL;
- }
-}
-
-
-/**********************************************************************
- Alloc memory and initialises a SAM_ACCOUNT_HANDLE on supplied mem_ctx.
-***********************************************************************/
-
-NTSTATUS sam_init_account_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT_HANDLE **account)
-{
- SMB_ASSERT(*account != NULL);
-
- if (!mem_ctx) {
- DEBUG(0,("sam_init_account_talloc: mem_ctx was NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- *account=(SAM_ACCOUNT_HANDLE *)talloc(mem_ctx, sizeof(SAM_ACCOUNT_HANDLE));
-
- if (*account==NULL) {
- DEBUG(0,("sam_init_account_talloc: error while allocating memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- (*account)->mem_ctx = mem_ctx;
-
- (*account)->free_fn = NULL;
-
- sam_fill_default_account(*account);
-
- return NT_STATUS_OK;
-}
-
-
-/*************************************************************
- Alloc memory and initialises a struct sam_passwd.
- ************************************************************/
-
-NTSTATUS sam_init_account(SAM_ACCOUNT_HANDLE **account)
-{
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
-
- mem_ctx = talloc_init("sam internal SAM_ACCOUNT_HANDLE allocation");
-
- if (!mem_ctx) {
- DEBUG(0,("sam_init_account: error while doing talloc_init()\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = sam_init_account_talloc(mem_ctx, account))) {
- talloc_destroy(mem_ctx);
- return nt_status;
- }
-
- (*account)->free_fn = destroy_sam_talloc;
-
- return NT_STATUS_OK;
-}
-
-/**
- * Free the contents of the SAM_ACCOUNT_HANDLE, but not the structure.
- *
- * Also wipes the LM and NT hashes and plaintext password from
- * memory.
- *
- * @param account SAM_ACCOUNT_HANDLE to free members of.
- **/
-
-static void sam_free_account_contents(SAM_ACCOUNT_HANDLE *account)
-{
-
- /* Kill off sensitive data. Free()ed by the
- talloc mechinism */
-
- data_blob_clear_free(&(account->private.lm_pw));
- data_blob_clear_free(&(account->private.nt_pw));
- if (account->private.plaintext_pw)
- memset(account->private.plaintext_pw,'\0',strlen(account->private.plaintext_pw));
-}
-
-
-/************************************************************
- Reset the SAM_ACCOUNT_HANDLE and free the NT/LM hashes.
- ***********************************************************/
-
-NTSTATUS sam_reset_sam(SAM_ACCOUNT_HANDLE *account)
-{
- SMB_ASSERT(account != NULL);
-
- sam_free_account_contents(account);
-
- sam_fill_default_account(account);
-
- return NT_STATUS_OK;
-}
-
-
-/************************************************************
- Free the SAM_ACCOUNT_HANDLE and the member pointers.
- ***********************************************************/
-
-NTSTATUS sam_free_account(SAM_ACCOUNT_HANDLE **account)
-{
- SMB_ASSERT(*account != NULL);
-
- sam_free_account_contents(*account);
-
- if ((*account)->free_fn) {
- (*account)->free_fn(account);
- }
-
- return NT_STATUS_OK;
-}
-
-
-/**********************************************************
- Encode the account control bits into a string.
- length = length of string to encode into (including terminating
- null). length *MUST BE MORE THAN 2* !
- **********************************************************/
-
-char *sam_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
-{
- static fstring acct_str;
- size_t i = 0;
-
- acct_str[i++] = '[';
-
- if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
- if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
- if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
- if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
- if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
- if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
- if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
- if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
- if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
- if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
- if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
-
- for ( ; i < length - 2 ; i++ )
- acct_str[i] = ' ';
-
- i = length - 2;
- acct_str[i++] = ']';
- acct_str[i++] = '\0';
-
- return acct_str;
-}
-
-/**********************************************************
- Decode the account control bits from a string.
- **********************************************************/
-
-uint16 sam_decode_acct_ctrl(const char *p)
-{
- uint16 acct_ctrl = 0;
- BOOL finished = False;
-
- /*
- * Check if the account type bits have been encoded after the
- * NT password (in the form [NDHTUWSLXI]).
- */
-
- if (*p != '[')
- return 0;
-
- for (p++; *p && !finished; p++) {
- switch (*p) {
- case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
- case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
- case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
- case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
- case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
- case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
- case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
- case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
- case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
- case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
- case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
- case ' ': { break; }
- case ':':
- case '\n':
- case '\0':
- case ']':
- default: { finished = True; }
- }
- }
-
- return acct_ctrl;
-}
-
-/*************************************************************
- Routine to set 32 hex password characters from a 16 byte array.
-**************************************************************/
-
-void sam_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
-{
- if (pwd != NULL) {
- int i;
- for (i = 0; i < 16; i++)
- slprintf(&p[i*2], 3, "%02X", pwd[i]);
- } else {
- if (acct_ctrl & ACB_PWNOTREQ)
- safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
- else
- safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
- }
-}
-
-/*************************************************************
- Routine to get the 32 hex characters and turn them
- into a 16 byte array.
-**************************************************************/
-
-BOOL sam_gethexpwd(const char *p, unsigned char *pwd)
-{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
-
- if (!p)
- return (False);
-
- for (i = 0; i < 32; i += 2) {
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
-
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
-
- if (!p1 || !p2)
- return (False);
-
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
-
- pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- return (True);
-}
diff --git a/source/sam/group.c b/source/sam/group.c
deleted file mode 100644
index 101e3dd7ce1..00000000000
--- a/source/sam/group.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAM_GROUP_HANDLE /SAM_GROUP_ENUM helpers
-
- Copyright (C) Stefan (metze) Metzmacher 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_SAM
-
-/************************************************************
- Fill the SAM_GROUP_HANDLE with default values.
- ***********************************************************/
-
-static void sam_fill_default_group(SAM_GROUP_HANDLE *group)
-{
- ZERO_STRUCT(group->private); /* Don't touch the talloc context */
-
-}
-
-static void destroy_sam_group_handle_talloc(SAM_GROUP_HANDLE **group)
-{
- if (*group) {
-
- talloc_destroy((*group)->mem_ctx);
- *group = NULL;
- }
-}
-
-
-/**********************************************************************
- Alloc memory and initialises a SAM_GROUP_HANDLE on supplied mem_ctx.
-***********************************************************************/
-
-NTSTATUS sam_init_group_talloc(TALLOC_CTX *mem_ctx, SAM_GROUP_HANDLE **group)
-{
- SMB_ASSERT(*group != NULL);
-
- if (!mem_ctx) {
- DEBUG(0,("sam_init_group_talloc: mem_ctx was NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- *group=(SAM_GROUP_HANDLE *)talloc(mem_ctx, sizeof(SAM_GROUP_HANDLE));
-
- if (*group==NULL) {
- DEBUG(0,("sam_init_group_talloc: error while allocating memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- (*group)->mem_ctx = mem_ctx;
-
- (*group)->free_fn = NULL;
-
- sam_fill_default_group(*group);
-
- return NT_STATUS_OK;
-}
-
-
-/*************************************************************
- Alloc memory and initialises a struct SAM_GROUP_HANDLE.
- ************************************************************/
-
-NTSTATUS sam_init_group(SAM_GROUP_HANDLE **group)
-{
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
-
- mem_ctx = talloc_init("sam internal SAM_GROUP_HANDLE allocation");
-
- if (!mem_ctx) {
- DEBUG(0,("sam_init_group: error while doing talloc_init()\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = sam_init_group_talloc(mem_ctx, group))) {
- talloc_destroy(mem_ctx);
- return nt_status;
- }
-
- (*group)->free_fn = destroy_sam_group_handle_talloc;
-
- return NT_STATUS_OK;
-}
-
-
-/************************************************************
- Reset the SAM_GROUP_HANDLE.
- ***********************************************************/
-
-NTSTATUS sam_reset_group(SAM_GROUP_HANDLE *group)
-{
- SMB_ASSERT(group != NULL);
-
- sam_fill_default_group(group);
-
- return NT_STATUS_OK;
-}
-
-
-/************************************************************
- Free the SAM_GROUP_HANDLE and the member pointers.
- ***********************************************************/
-
-NTSTATUS sam_free_group(SAM_ACCOUNT_HANDLE **group)
-{
- SMB_ASSERT(*group != NULL);
-
- if ((*group)->free_fn) {
- (*group)->free_fn(group);
- }
-
- return NT_STATUS_OK;
-}
-
-
-/**********************************************************
- Encode the group control bits into a string.
- length = length of string to encode into (including terminating
- null). length *MUST BE MORE THAN 2* !
- **********************************************************/
-
-char *sam_encode_acct_ctrl(uint16 group_ctrl, size_t length)
-{
- static fstring group_str;
- size_t i = 0;
-
- group_str[i++] = '[';
-
- if (group_ctrl & GCB_LOCAL_GROUP ) group_str[i++] = 'L';
- if (group_ctrl & GCB_GLOBAL_GROUP ) group_str[i++] = 'G';
-
- for ( ; i < length - 2 ; i++ )
- group_str[i] = ' ';
-
- i = length - 2;
- group_str[i++] = ']';
- group_str[i++] = '\0';
-
- return group_str;
-}
-
-/**********************************************************
- Decode the group control bits from a string.
- **********************************************************/
-
-uint16 sam_decode_group_ctrl(const char *p)
-{
- uint16 group_ctrl = 0;
- BOOL finished = False;
-
- /*
- * Check if the account type bits have been encoded after the
- * NT password (in the form [NDHTUWSLXI]).
- */
-
- if (*p != '[')
- return 0;
-
- for (p++; *p && !finished; p++) {
- switch (*p) {
- case 'L': { group_ctrl |= GCB_LOCAL_GROUP; break; /* 'L'ocal Aliases Group. */ }
- case 'G': { group_ctrl |= GCB_GLOBAL_GROUP; break; /* 'G'lobal Domain Group. */ }
-
- case ' ': { break; }
- case ':':
- case '\n':
- case '\0':
- case ']':
- default: { finished = True; }
- }
- }
-
- return group_ctrl;
-}
-
diff --git a/source/sam/gums.c b/source/sam/gums.c
deleted file mode 100644
index b7191535845..00000000000
--- a/source/sam/gums.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Grops and Users Management System initializations.
- Copyright (C) Simo Sorce 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_SAM
-
-#define GMV_MAJOR 0
-#define GMV_MINOR 1
-
-static GUMS_FUNCTIONS *gums_backend = NULL;
-
-static struct gums_init_function_entry *backends = NULL;
-
-static void lazy_initialize_gums(void)
-{
- static BOOL initialized = False;
-
- if (initialized)
- return;
-
- static_init_gums;
- initialized = True;
-}
-
-static struct gums_init_function_entry *gums_find_backend_entry(const char *name);
-
-NTSTATUS gums_register_module(int version, const char *name, gums_init_function init_fn)
-{
- struct gums_init_function_entry *entry = backends;
-
- if (version != GUMS_INTERFACE_VERSION) {
- DEBUG(0,("Can't register gums backend!\n"
- "You tried to register a gums module with"
- "GUMS_INTERFACE_VERSION %d, while this version"
- "of samba uses version %d\n", version,
- GUMS_INTERFACE_VERSION));
-
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !init_fn) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5,("Attempting to register gums backend %s\n", name));
-
- /* Check for duplicates */
- if (gums_find_backend_entry(name)) {
- DEBUG(0,("There already is a gums backend registered"
- "with the name %s!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct gums_init_function_entry));
- entry->name = smb_xstrdup(name);
- entry->init_fn = init_fn;
-
- DLIST_ADD(backends, entry);
- DEBUG(5,("Successfully added gums backend '%s'\n", name));
- return NT_STATUS_OK;
-}
-
-static struct gums_init_function_entry *gums_find_backend_entry(const char *name)
-{
- struct gums_init_function_entry *entry = backends;
-
- while (entry) {
- if (strcmp(entry->name, name) == 0)
- return entry;
- entry = entry->next;
- }
-
- return NULL;
-}
-
-NTSTATUS gums_setup_backend(const char *backend)
-{
-
- TALLOC_CTX *mem_ctx;
- char *module_name = smb_xstrdup(backend);
- char *p, *module_data = NULL;
- struct gums_init_function_entry *entry;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- lazy_initialize_gums();
-
- p = strchr(module_name, ':');
- if (p) {
- *p = 0;
- module_data = p+1;
- trim_string(module_data, " ", " ");
- }
-
- trim_string(module_name, " ", " ");
-
- DEBUG(5,("Attempting to find a gums backend to match %s (%s)\n", backend, module_name));
-
- entry = gums_find_backend_entry(module_name);
-
- /* Try to find a module that contains this module */
- if (!entry) {
- DEBUG(2,("No builtin backend found, trying to load plugin\n"));
- if(NT_STATUS_IS_OK(smb_probe_module("gums", module_name)) && !(entry = gums_find_backend_entry(module_name))) {
- DEBUG(0,("Plugin is available, but doesn't register gums backend %s\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* No such backend found */
- if(!entry) {
- DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(5,("Found gums backend %s\n", module_name));
-
- /* free current functions structure if any */
- if (gums_backend) {
- gums_backend->free_private_data(gums_backend->private_data);
- talloc_destroy(gums_backend->mem_ctx);
- gums_backend = NULL;
- }
-
- /* allocate a new GUMS_FUNCTIONS structure and memory context */
- mem_ctx = talloc_init("gums_backend (%s)", module_name);
- if (!mem_ctx)
- return NT_STATUS_NO_MEMORY;
- gums_backend = talloc(mem_ctx, sizeof(GUMS_FUNCTIONS));
- if (!gums_backend)
- return NT_STATUS_NO_MEMORY;
- gums_backend->mem_ctx = mem_ctx;
-
- /* init the requested backend module */
- if (NT_STATUS_IS_OK(ret = entry->init_fn(gums_backend, module_data))) {
- DEBUG(5,("gums backend %s has a valid init\n", backend));
- } else {
- DEBUG(0,("gums backend %s did not correctly init (error was %s)\n", backend, nt_errstr(ret)));
- }
- SAFE_FREE(module_name);
- return ret;
-}
-
-NTSTATUS get_gums_fns(GUMS_FUNCTIONS **fns)
-{
- if (gums_backend != NULL) {
- *fns = gums_backend;
- return NT_STATUS_OK;
- }
-
- DEBUG(2, ("get_gums_fns: unable to get gums functions! backend uninitialized?\n"));
- return NT_STATUS_UNSUCCESSFUL;
-}
diff --git a/source/sam/gums_api.c b/source/sam/gums_api.c
deleted file mode 100644
index 5aafa7695f6..00000000000
--- a/source/sam/gums_api.c
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- GUMS structures
- Copyright (C) Simo Sorce 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* Functions to get/set info from a GUMS object */
-
-NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type)
-{
- TALLOC_CTX *mem_ctx;
- GUMS_OBJECT *go;
- NTSTATUS ret;
-
- mem_ctx = talloc_init("gums_create_object");
- if (!mem_ctx) {
- DEBUG(0, ("gums_create_object: Out of memory!\n"));
- *obj = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- go = talloc_zero(mem_ctx, sizeof(GUMS_OBJECT));
- if (!go) {
- DEBUG(0, ("gums_create_object: Out of memory!\n"));
- talloc_destroy(mem_ctx);
- *obj = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- go->mem_ctx = mem_ctx;
- go->type = type;
- go->version = GUMS_OBJECT_VERSION;
-
- switch(type) {
- case GUMS_OBJ_DOMAIN:
- go->domain = (GUMS_DOMAIN *)talloc_zero(mem_ctx, sizeof(GUMS_DOMAIN));
- if (!(go->domain)) {
- ret = NT_STATUS_NO_MEMORY;
- DEBUG(0, ("gums_create_object: Out of memory!\n"));
- goto error;
- }
-
- break;
-
-/*
- case GUMS_OBJ_WORKSTATION_TRUST:
- case GUMS_OBJ_SERVER_TRUST:
- case GUMS_OBJ_DOMAIN_TRUST:
-*/
- case GUMS_OBJ_NORMAL_USER:
- go->user = (GUMS_USER *)talloc_zero(mem_ctx, sizeof(GUMS_USER));
- if (!(go->user)) {
- ret = NT_STATUS_NO_MEMORY;
- DEBUG(0, ("gums_create_object: Out of memory!\n"));
- goto error;
- }
- gums_set_user_acct_ctrl(go, ACB_NORMAL);
- gums_set_user_hours(go, 0, NULL);
-
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- go->group = (GUMS_GROUP *)talloc_zero(mem_ctx, sizeof(GUMS_GROUP));
- if (!(go->group)) {
- ret = NT_STATUS_NO_MEMORY;
- DEBUG(0, ("gums_create_object: Out of memory!\n"));
- goto error;
- }
-
- break;
-
- default:
- /* TODO: throw error */
- ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
- goto error;
- }
-
- *obj = go;
- return NT_STATUS_OK;
-
-error:
- talloc_destroy(go->mem_ctx);
- *obj = NULL;
- return ret;
-}
-
-NTSTATUS gums_create_privilege(GUMS_PRIVILEGE **priv)
-{
- TALLOC_CTX *mem_ctx;
- GUMS_PRIVILEGE *pri;
-
- mem_ctx = talloc_init("gums_create_privilege");
- if (!mem_ctx) {
- DEBUG(0, ("gums_create_privilege: Out of memory!\n"));
- *priv = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- pri = talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE));
- if (!pri) {
- DEBUG(0, ("gums_create_privilege: Out of memory!\n"));
- talloc_destroy(mem_ctx);
- *priv = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- pri->mem_ctx = mem_ctx;
- pri->version = GUMS_PRIVILEGE_VERSION;
-
- *priv = pri;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_destroy_object(GUMS_OBJECT **obj)
-{
- if (!obj || !(*obj))
- return NT_STATUS_INVALID_PARAMETER;
-
- if ((*obj)->mem_ctx)
- talloc_destroy((*obj)->mem_ctx);
- *obj = NULL;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_destroy_privilege(GUMS_PRIVILEGE **priv)
-{
- if (!priv || !(*priv))
- return NT_STATUS_INVALID_PARAMETER;
-
- if ((*priv)->mem_ctx)
- talloc_destroy((*priv)->mem_ctx);
- *priv = NULL;
-
- return NT_STATUS_OK;
-}
-
-void gums_reset_object(GUMS_OBJECT *go)
-{
- go->seq_num = 0;
- go->sid = NULL;
- go->name = NULL;
- go->description = NULL;
-
- switch(go->type) {
- case GUMS_OBJ_DOMAIN:
- memset(go->domain, 0, sizeof(GUMS_DOMAIN));
- break;
-
-/*
- case GUMS_OBJ_WORKSTATION_TRUST:
- case GUMS_OBJ_SERVER_TRUST:
- case GUMS_OBJ_DOMAIN_TRUST:
-*/
- case GUMS_OBJ_NORMAL_USER:
- memset(go->user, 0, sizeof(GUMS_USER));
- gums_set_user_acct_ctrl(go, ACB_NORMAL);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- memset(go->group, 0, sizeof(GUMS_GROUP));
- break;
-
- default:
- return;
- }
-}
-
-uint32 gums_get_object_type(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return 0;
-
- return obj->type;
-}
-
-uint32 gums_get_object_seq_num(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return 0;
-
- return obj->seq_num;
-}
-
-uint32 gums_get_object_version(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return 0;
-
- return obj->version;
-}
-
-const SEC_DESC *gums_get_sec_desc(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return NULL;
-
- return obj->sec_desc;
-}
-
-const DOM_SID *gums_get_object_sid(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return NULL;
-
- return obj->sid;
-}
-
-const char *gums_get_object_name(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return NULL;
-
- return obj->name;
-}
-
-const char *gums_get_object_description(const GUMS_OBJECT *obj)
-{
- if (!obj)
- return NULL;
-
- return obj->description;
-}
-
-NTSTATUS gums_set_object_seq_num(GUMS_OBJECT *obj, uint32 seq_num)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->seq_num = seq_num;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_object_version(GUMS_OBJECT *obj, uint32 version)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->version = version;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_sec_desc(GUMS_OBJECT *obj, const SEC_DESC *sec_desc)
-{
- if (!obj || !sec_desc)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->sec_desc = dup_sec_desc(obj->mem_ctx, sec_desc);
- if (!(obj->sec_desc)) return NT_STATUS_UNSUCCESSFUL;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_object_sid(GUMS_OBJECT *obj, const DOM_SID *sid)
-{
- if (!obj || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->sid = sid_dup_talloc(obj->mem_ctx, sid);
- if (!(obj->sid)) return NT_STATUS_UNSUCCESSFUL;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_object_name(GUMS_OBJECT *obj, const char *name)
-{
- if (!obj || !name)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->name = (char *)talloc_strdup(obj->mem_ctx, name);
- if (!(obj->name)) return NT_STATUS_UNSUCCESSFUL;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_object_description(GUMS_OBJECT *obj, const char *description)
-{
- if (!obj || !description)
- return NT_STATUS_INVALID_PARAMETER;
-
- obj->description = (char *)talloc_strdup(obj->mem_ctx, description);
- if (!(obj->description)) return NT_STATUS_UNSUCCESSFUL;
- return NT_STATUS_OK;
-}
-
-/*
-NTSTATUS gums_get_object_privileges(PRIVILEGE_SET **priv_set, const GUMS_OBJECT *obj)
-{
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- *priv_set = obj->priv_set;
- return NT_STATUS_OK;
-}
-*/
-
-uint32 gums_get_domain_next_rid(const GUMS_OBJECT *obj)
-{
- if (obj->type != GUMS_OBJ_DOMAIN)
- return -1;
-
- return obj->domain->next_rid;
-}
-
-NTSTATUS gums_set_domain_next_rid(GUMS_OBJECT *obj, uint32 rid)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_DOMAIN)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->domain->next_rid = rid;
- return NT_STATUS_OK;
-}
-
-/* User specific functions */
-
-const DOM_SID *gums_get_user_pri_group(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->group_sid;
-}
-
-const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj)
-{
- fstring p;
-
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return data_blob(NULL, 0);
-
- pdb_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0);
- DEBUG(100, ("Reading NT Password=[%s]\n", p));
-
- return obj->user->nt_pw;
-}
-
-const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj)
-{
- fstring p;
-
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return data_blob(NULL, 0);
-
- pdb_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0);
- DEBUG(100, ("Reading LM Password=[%s]\n", p));
-
- return obj->user->lm_pw;
-}
-
-const char *gums_get_user_fullname(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->full_name;
-}
-
-const char *gums_get_user_homedir(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->home_dir;
-}
-
-const char *gums_get_user_dir_drive(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->dir_drive;
-}
-
-const char *gums_get_user_profile_path(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->profile_path;
-}
-
-const char *gums_get_user_logon_script(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->logon_script;
-}
-
-const char *gums_get_user_workstations(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->workstations;
-}
-
-const char *gums_get_user_unknown_str(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->unknown_str;
-}
-
-const char *gums_get_user_munged_dial(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->munged_dial;
-}
-
-NTTIME gums_get_user_logon_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->logon_time;
-}
-
-NTTIME gums_get_user_logoff_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->logoff_time;
-}
-
-NTTIME gums_get_user_kickoff_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->kickoff_time;
-}
-
-NTTIME gums_get_user_pass_last_set_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->pass_last_set_time;
-}
-
-NTTIME gums_get_user_pass_can_change_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->pass_can_change_time;
-}
-
-NTTIME gums_get_user_pass_must_change_time(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
- NTTIME null_time;
- init_nt_time(&null_time);
- return null_time;
- }
-
- return obj->user->pass_must_change_time;
-}
-
-uint16 gums_get_user_acct_ctrl(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->acct_ctrl;
-}
-
-uint16 gums_get_user_logon_divs(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->logon_divs;
-}
-
-uint32 gums_get_user_hours_len(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->hours_len;
-}
-
-const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return NULL;
-
- return obj->user->hours;
-}
-
-uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->unknown_3;
-}
-
-uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->bad_password_count;
-}
-
-uint16 gums_get_user_logon_count(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->logon_count;
-}
-
-uint32 gums_get_user_unknown_6(const GUMS_OBJECT *obj)
-{
- if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
- return 0;
-
- return obj->user->unknown_6;
-}
-
-NTSTATUS gums_set_user_pri_group(GUMS_OBJECT *obj, const DOM_SID *sid)
-{
- if (!obj || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->group_sid = sid_dup_talloc(obj->mem_ctx, sid);
- if (!(obj->user->group_sid)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_nt_pwd(GUMS_OBJECT *obj, const DATA_BLOB nt_pwd)
-{
- fstring p;
- unsigned char r[16];
-
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length);
-
- memcpy(r, nt_pwd.data, 16);
- pdb_sethexpwd(p, r, 0);
- DEBUG(100, ("Setting NT Password=[%s]\n", p));
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_lm_pwd(GUMS_OBJECT *obj, const DATA_BLOB lm_pwd)
-{
- fstring p;
- unsigned char r[16];
-
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length);
-
- memcpy(r, lm_pwd.data, 16);
- pdb_sethexpwd(p, r, 0);
- DEBUG(100, ("Setting LM Password=[%s]\n", p));
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_fullname(GUMS_OBJECT *obj, const char *fullname)
-{
- if (!obj || !fullname)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->full_name = (char *)talloc_strdup(obj->mem_ctx, fullname);
- if (!(obj->user->full_name)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_homedir(GUMS_OBJECT *obj, const char *homedir)
-{
- if (!obj || !homedir)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->home_dir = (char *)talloc_strdup(obj->mem_ctx, homedir);
- if (!(obj->user->home_dir)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_dir_drive(GUMS_OBJECT *obj, const char *dir_drive)
-{
- if (!obj || !dir_drive)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->dir_drive = (char *)talloc_strdup(obj->mem_ctx, dir_drive);
- if (!(obj->user->dir_drive)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_logon_script(GUMS_OBJECT *obj, const char *logon_script)
-{
- if (!obj || !logon_script)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->logon_script = (char *)talloc_strdup(obj->mem_ctx, logon_script);
- if (!(obj->user->logon_script)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_profile_path(GUMS_OBJECT *obj, const char *profile_path)
-{
- if (!obj || !profile_path)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->profile_path = (char *)talloc_strdup(obj->mem_ctx, profile_path);
- if (!(obj->user->profile_path)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_workstations(GUMS_OBJECT *obj, const char *workstations)
-{
- if (!obj || !workstations)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->workstations = (char *)talloc_strdup(obj->mem_ctx, workstations);
- if (!(obj->user->workstations)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_unknown_str(GUMS_OBJECT *obj, const char *unknown_str)
-{
- if (!obj || !unknown_str)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->unknown_str = (char *)talloc_strdup(obj->mem_ctx, unknown_str);
- if (!(obj->user->unknown_str)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_munged_dial(GUMS_OBJECT *obj, const char *munged_dial)
-{
- if (!obj || !munged_dial)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->munged_dial = (char *)talloc_strdup(obj->mem_ctx, munged_dial);
- if (!(obj->user->munged_dial)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_logon_time(GUMS_OBJECT *obj, NTTIME logon_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->logon_time = logon_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_logoff_time(GUMS_OBJECT *obj, NTTIME logoff_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->logoff_time = logoff_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_kickoff_time(GUMS_OBJECT *obj, NTTIME kickoff_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->kickoff_time = kickoff_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_pass_last_set_time(GUMS_OBJECT *obj, NTTIME pass_last_set_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->pass_last_set_time = pass_last_set_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_pass_can_change_time(GUMS_OBJECT *obj, NTTIME pass_can_change_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->pass_can_change_time = pass_can_change_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_pass_must_change_time(GUMS_OBJECT *obj, NTTIME pass_must_change_time)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->pass_must_change_time = pass_must_change_time;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_acct_ctrl(GUMS_OBJECT *obj, uint16 acct_ctrl)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->acct_ctrl = acct_ctrl;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_logon_divs(GUMS_OBJECT *obj, uint16 logon_divs)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->logon_divs = logon_divs;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *hours)
-{
- if (!obj || !hours)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->hours_len = hours_len;
- if (hours_len == 0)
- DEBUG(10, ("gums_set_user_hours: Warning, hours_len is zero!\n"));
-
- obj->user->hours = (uint8 *)talloc(obj->mem_ctx, MAX_HOURS_LEN);
- if (!(obj->user->hours))
- return NT_STATUS_NO_MEMORY;
- if (hours_len)
- memcpy(obj->user->hours, hours, hours_len);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->unknown_3 = unknown_3;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->bad_password_count = bad_password_count;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_logon_count(GUMS_OBJECT *obj, uint16 logon_count)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->logon_count = logon_count;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_user_unknown_6(GUMS_OBJECT *obj, uint32 unknown_6)
-{
- if (!obj)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->user->unknown_6 = unknown_6;
- return NT_STATUS_OK;
-}
-
-/* Group specific functions */
-
-const DOM_SID *gums_get_group_members(int *count, const GUMS_OBJECT *obj)
-{
- if (!count || !obj || !(obj->type == GUMS_OBJ_GROUP || obj->type == GUMS_OBJ_ALIAS)) {
- *count = -1;
- return NULL;
- }
-
- *count = obj->group->count;
- return obj->group->members;
-}
-
-NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members)
-{
- uint32 n;
-
- if (!obj || ((count > 0) && !members))
- return NT_STATUS_INVALID_PARAMETER;
-
- if (obj->type != GUMS_OBJ_GROUP &&
- obj->type != GUMS_OBJ_ALIAS)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
- obj->group->count = count;
-
- if (count) {
- obj->group->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID));
- if (!(obj->group->members)) {
- return NT_STATUS_NO_MEMORY;
- }
-
-
- n = 0;
- do {
- sid_copy(&(obj->group->members[n]), &(members[n]));
- n++;
- } while (n < count);
- } else {
- obj->group->members = 0;
- }
-
- return NT_STATUS_OK;
-}
-
-/* Privilege specific functions */
-
-const LUID_ATTR *gums_get_priv_luid_attr(const GUMS_PRIVILEGE *priv)
-{
- if (!priv) {
- return NULL;
- }
-
- return priv->privilege;
-}
-
-const DOM_SID *gums_get_priv_members(int *count, const GUMS_PRIVILEGE *priv)
-{
- if (!count || !priv) {
- *count = -1;
- return NULL;
- }
-
- *count = priv->count;
- return priv->members;
-}
-
-NTSTATUS gums_set_priv_luid_attr(GUMS_PRIVILEGE *priv, LUID_ATTR *luid_attr)
-{
- if (!luid_attr || !priv)
- return NT_STATUS_INVALID_PARAMETER;
-
- priv->privilege = (LUID_ATTR *)talloc_memdup(priv->mem_ctx, luid_attr, sizeof(LUID_ATTR));
- if (!(priv->privilege)) return NT_STATUS_NO_MEMORY;
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_set_priv_members(GUMS_PRIVILEGE *priv, uint32 count, DOM_SID *members)
-{
- uint32 n;
-
- if (!priv || !members || !members)
- return NT_STATUS_INVALID_PARAMETER;
-
- priv->count = count;
- priv->members = (DOM_SID *)talloc(priv->mem_ctx, count * sizeof(DOM_SID));
- if (!(priv->members))
- return NT_STATUS_NO_MEMORY;
-
- n = 0;
- do {
- sid_copy(&(priv->members[n]), &(members[n]));
- n++;
- } while (n < count);
-
- return NT_STATUS_OK;
-}
-
-/* data_store set functions */
-
-NTSTATUS gums_create_commit_set(GUMS_COMMIT_SET **com_set, DOM_SID *sid, uint32 type)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("commit_set");
- if (mem_ctx == NULL)
- return NT_STATUS_NO_MEMORY;
-
- *com_set = (GUMS_COMMIT_SET *)talloc_zero(mem_ctx, sizeof(GUMS_COMMIT_SET));
- if (*com_set == NULL) {
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*com_set)->mem_ctx = mem_ctx;
- (*com_set)->type = type;
- sid_copy(&((*com_set)->sid), sid);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_grow_data_set(GUMS_COMMIT_SET *com_set, int size)
-{
- GUMS_DATA_SET *data_set;
-
- com_set->count = com_set->count + size;
- if (com_set->count == size) { /* data set is empty*/
- data_set = (GUMS_DATA_SET *)talloc_zero(com_set->mem_ctx, sizeof(GUMS_DATA_SET));
- } else {
- data_set = (GUMS_DATA_SET *)talloc_realloc(com_set->mem_ctx, com_set->data, sizeof(GUMS_DATA_SET) * com_set->count);
- }
- if (data_set == NULL)
- return NT_STATUS_NO_MEMORY;
-
- com_set->data = data_set;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_set_sec_desc(GUMS_COMMIT_SET *com_set, SEC_DESC *sec_desc)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- SEC_DESC *new_sec_desc;
-
- if (!com_set || !sec_desc)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_SET_SEC_DESC;
- new_sec_desc = dup_sec_desc(com_set->mem_ctx, sec_desc);
- if (new_sec_desc == NULL)
- return NT_STATUS_NO_MEMORY;
-
- (SEC_DESC *)(data_set->data) = new_sec_desc;
-
- return NT_STATUS_OK;
-}
-
-/*
-NTSTATUS gums_cs_add_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- LUID_ATTR *new_priv;
-
- if (!com_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = ((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_ADD_PRIVILEGE;
- if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv)))
- return ret;
-
- (SEC_DESC *)(data_set->data) = new_priv;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_del_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- LUID_ATTR *new_priv;
-
- if (!com_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = ((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_DEL_PRIVILEGE;
- if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv)))
- return ret;
-
- (SEC_DESC *)(data_set->data) = new_priv;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_set_privilege_set(GUMS_PRIV_COMMIT_SET *com_set, PRIVILEGE_SET *priv_set)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- PRIVILEGE_SET *new_priv_set;
-
- if (!com_set || !priv_set)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = ((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_SET_PRIVILEGE;
- if (!NT_STATUS_IS_OK(ret = init_priv_set_with_ctx(com_set->mem_ctx, &new_priv_set)))
- return ret;
-
- if (!NT_STATUS_IS_OK(ret = dup_priv_set(new_priv_set, priv_set)))
- return ret;
-
- (SEC_DESC *)(data_set->data) = new_priv_set;
-
- return NT_STATUS_OK;
-}
-*/
-
-NTSTATUS gums_cs_set_string(GUMS_COMMIT_SET *com_set, uint32 type, char *str)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- char *new_str;
-
- if (!com_set || !str || type < GUMS_SET_NAME || type > GUMS_SET_MUNGED_DIAL)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = type;
- new_str = talloc_strdup(com_set->mem_ctx, str);
- if (new_str == NULL)
- return NT_STATUS_NO_MEMORY;
-
- (char *)(data_set->data) = new_str;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_set_name(GUMS_COMMIT_SET *com_set, char *name)
-{
- return gums_cs_set_string(com_set, GUMS_SET_NAME, name);
-}
-
-NTSTATUS gums_cs_set_description(GUMS_COMMIT_SET *com_set, char *desc)
-{
- return gums_cs_set_string(com_set, GUMS_SET_DESCRIPTION, desc);
-}
-
-NTSTATUS gums_cs_set_full_name(GUMS_COMMIT_SET *com_set, char *full_name)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, full_name);
-}
-
-NTSTATUS gums_cs_set_home_directory(GUMS_COMMIT_SET *com_set, char *home_dir)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, home_dir);
-}
-
-NTSTATUS gums_cs_set_drive(GUMS_COMMIT_SET *com_set, char *drive)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, drive);
-}
-
-NTSTATUS gums_cs_set_logon_script(GUMS_COMMIT_SET *com_set, char *logon_script)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, logon_script);
-}
-
-NTSTATUS gums_cs_set_profile_path(GUMS_COMMIT_SET *com_set, char *prof_path)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, prof_path);
-}
-
-NTSTATUS gums_cs_set_workstations(GUMS_COMMIT_SET *com_set, char *wks)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, wks);
-}
-
-NTSTATUS gums_cs_set_unknown_string(GUMS_COMMIT_SET *com_set, char *unkn_str)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, unkn_str);
-}
-
-NTSTATUS gums_cs_set_munged_dial(GUMS_COMMIT_SET *com_set, char *munged_dial)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_string(com_set, GUMS_SET_NAME, munged_dial);
-}
-
-NTSTATUS gums_cs_set_nttime(GUMS_COMMIT_SET *com_set, uint32 type, NTTIME *nttime)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- NTTIME *new_time;
-
- if (!com_set || !nttime || type < GUMS_SET_LOGON_TIME || type > GUMS_SET_PASS_MUST_CHANGE_TIME)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = type;
- new_time = talloc(com_set->mem_ctx, sizeof(NTTIME));
- if (new_time == NULL)
- return NT_STATUS_NO_MEMORY;
-
- new_time->low = nttime->low;
- new_time->high = nttime->high;
- (char *)(data_set->data) = new_time;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_set_logon_time(GUMS_COMMIT_SET *com_set, NTTIME *logon_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, logon_time);
-}
-
-NTSTATUS gums_cs_set_logoff_time(GUMS_COMMIT_SET *com_set, NTTIME *logoff_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_LOGOFF_TIME, logoff_time);
-}
-
-NTSTATUS gums_cs_set_kickoff_time(GUMS_COMMIT_SET *com_set, NTTIME *kickoff_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_KICKOFF_TIME, kickoff_time);
-}
-
-NTSTATUS gums_cs_set_pass_last_set_time(GUMS_COMMIT_SET *com_set, NTTIME *pls_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pls_time);
-}
-
-NTSTATUS gums_cs_set_pass_can_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pcc_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pcc_time);
-}
-
-NTSTATUS gums_cs_set_pass_must_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pmc_time)
-{
- if (com_set->type != GUMS_OBJ_NORMAL_USER)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pmc_time);
-}
-
-NTSTATUS gums_cs_add_sids_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- DOM_SID **new_sids;
- int i;
-
- if (!com_set || !sids)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_ADD_SID_LIST;
- new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
- if (new_sids == NULL)
- return NT_STATUS_NO_MEMORY;
- for (i = 0; i < count; i++) {
- new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
- if (new_sids[i] == NULL)
- return NT_STATUS_NO_MEMORY;
- }
-
- (SEC_DESC *)(data_set->data) = new_sids;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_cs_add_users_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
-{
- if (!com_set || !sids)
- return NT_STATUS_INVALID_PARAMETER;
- if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_add_sids_to_group(com_set, sids, count);
-}
-
-NTSTATUS gums_cs_add_groups_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
-{
- if (!com_set || !sids)
- return NT_STATUS_INVALID_PARAMETER;
- if (com_set->type != GUMS_OBJ_ALIAS)
- return NT_STATUS_INVALID_PARAMETER;
-
- return gums_cs_add_sids_to_group(com_set, sids, count);
-}
-
-NTSTATUS gums_cs_del_sids_from_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- DOM_SID **new_sids;
- int i;
-
- if (!com_set || !sids)
- return NT_STATUS_INVALID_PARAMETER;
- if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_DEL_SID_LIST;
- new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
- if (new_sids == NULL)
- return NT_STATUS_NO_MEMORY;
- for (i = 0; i < count; i++) {
- new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
- if (new_sids[i] == NULL)
- return NT_STATUS_NO_MEMORY;
- }
-
- (SEC_DESC *)(data_set->data) = new_sids;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_ds_set_sids_in_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
-{
- NTSTATUS ret;
- GUMS_DATA_SET *data_set;
- DOM_SID **new_sids;
- int i;
-
- if (!com_set || !sids)
- return NT_STATUS_INVALID_PARAMETER;
- if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
- return ret;
-
- data_set = &((com_set->data)[com_set->count - 1]);
-
- data_set->type = GUMS_SET_SID_LIST;
- new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
- if (new_sids == NULL)
- return NT_STATUS_NO_MEMORY;
- for (i = 0; i < count; i++) {
- new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
- if (new_sids[i] == NULL)
- return NT_STATUS_NO_MEMORY;
- }
-
- (SEC_DESC *)(data_set->data) = new_sids;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_commit_data(GUMS_COMMIT_SET *set)
-{
- NTSTATUS ret;
- GUMS_FUNCTIONS *fns;
-
- if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns))) {
- DEBUG(0, ("gums_commit_data: unable to get gums functions! backend uninitialized?\n"));
- return ret;
- }
- return fns->set_object_values(&(set->sid), set->count, set->data);
-}
-
-NTSTATUS gums_destroy_commit_set(GUMS_COMMIT_SET **com_set)
-{
- talloc_destroy((*com_set)->mem_ctx);
- *com_set = NULL;
-
- return NT_STATUS_OK;
-}
-
diff --git a/source/sam/gums_helper.c b/source/sam/gums_helper.c
deleted file mode 100644
index fcb9366cda8..00000000000
--- a/source/sam/gums_helper.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- GUMS backends helper functions
- Copyright (C) Simo Sorce 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Builtin;
-extern DOM_SID global_sid_Builtin_Administrators;
-extern DOM_SID global_sid_Builtin_Power_Users;
-extern DOM_SID global_sid_Builtin_Account_Operators;
-extern DOM_SID global_sid_Builtin_Server_Operators;
-extern DOM_SID global_sid_Builtin_Print_Operators;
-extern DOM_SID global_sid_Builtin_Backup_Operators;
-extern DOM_SID global_sid_Builtin_Replicator;
-extern DOM_SID global_sid_Builtin_Users;
-extern DOM_SID global_sid_Builtin_Guests;
-
-
-/* defines */
-
-#define ALLOC_CHECK(str, ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
-#define NTSTATUS_CHECK(err, label, str1, str2) do { if (NT_STATUS_IS_ERR(err)) { DEBUG(0, ("%s: %s\n", str1, str2)); } } while(0)
-
-/****************************************************************************
- Check if a user is a mapped group.
-
- This function will check if the group SID is mapped onto a
- system managed gid or onto a winbind manged sid.
- In the first case it will be threated like a mapped group
- and the backend should take the member list with a getgrgid
- and ignore any user that have been possibly set into the group
- object.
-
- In the second case, the group is a fully SAM managed group
- served back to the system through winbind. In this case the
- members of a Local group are "unrolled" to cope with the fact
- that unix cannot contain groups inside groups.
- The backend MUST never call any getgr* / getpw* function or
- loops with winbind may happen.
- ****************************************************************************/
-
-#if 0
-NTSTATUS is_mapped_group(BOOL *mapped, const DOM_SID *sid)
-{
- NTSTATUS result;
- gid_t id;
-
- /* look if mapping exist, do not make idmap alloc an uid if SID is not found */
- result = idmap_get_gid_from_sid(&id, sid, False);
- if (NT_STATUS_IS_OK(result)) {
- *mapped = gid_is_in_winbind_range(id);
- } else {
- *mapped = False;
- }
-
- return result;
-}
-#endif
-
-#define ALIAS_DEFAULT_SACL_SA_RIGHTS 0x01050013
-#define ALIAS_DEFAULT_DACL_SA_RIGHTS \
- (READ_CONTROL_ACCESS | \
- SA_RIGHT_ALIAS_LOOKUP_INFO | \
- SA_RIGHT_ALIAS_GET_MEMBERS) /* 0x0002000c */
-
-#define ALIAS_DEFAULT_SACL_SEC_ACE_FLAG (SEC_ACE_FLAG_FAILED_ACCESS | SEC_ACE_FLAG_SUCCESSFUL_ACCESS) /* 0xc0 */
-
-
-NTSTATUS create_builtin_alias_default_sec_desc(SEC_DESC **sec_desc, TALLOC_CTX *ctx)
-{
- DOM_SID *world = &global_sid_World;
- DOM_SID *admins = &global_sid_Builtin_Administrators;
- SEC_ACCESS sa;
- SEC_ACE sacl_ace;
- SEC_ACE dacl_aces[2];
- SEC_ACL *sacl = NULL;
- SEC_ACL *dacl = NULL;
- size_t psize;
-
- init_sec_access(&sa, ALIAS_DEFAULT_SACL_SA_RIGHTS);
- init_sec_ace(&sacl_ace, world, SEC_ACE_TYPE_SYSTEM_AUDIT, sa, ALIAS_DEFAULT_SACL_SEC_ACE_FLAG);
-
- sacl = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &sacl_ace);
- if (!sacl) {
- DEBUG(0, ("build_init_sec_desc: Failed to make SEC_ACL.\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- init_sec_access(&sa, ALIAS_DEFAULT_DACL_SA_RIGHTS);
- init_sec_ace(&(dacl_aces[0]), world, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
- init_sec_access(&sa, SA_RIGHT_ALIAS_ALL_ACCESS);
- init_sec_ace(&(dacl_aces[1]), admins, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
-
- dacl = make_sec_acl(ctx, NT4_ACL_REVISION, 2, dacl_aces);
- if (!sacl) {
- DEBUG(0, ("build_init_sec_desc: Failed to make SEC_ACL.\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- *sec_desc = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, admins, admins, sacl, dacl, &psize);
- if (!(*sec_desc)) {
- DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sec_desc_add_ace_to_dacl(SEC_DESC *sec_desc, TALLOC_CTX *ctx, DOM_SID *sid, uint32 mask)
-{
- NTSTATUS result;
- SEC_ACE *new_aces;
- unsigned num_aces;
- int i;
-
- num_aces = sec_desc->dacl->num_aces + 1;
- result = sec_ace_add_sid(ctx, &new_aces, sec_desc->dacl->ace, &num_aces, sid, mask);
- if (NT_STATUS_IS_OK(result)) {
- sec_desc->dacl->ace = new_aces;
- sec_desc->dacl->num_aces = num_aces;
- sec_desc->dacl->size = SEC_ACL_HEADER_SIZE;
- for (i = 0; i < num_aces; i++) {
- sec_desc->dacl->size += sec_desc->dacl->ace[i].size;
- }
- }
- return result;
-}
-
-NTSTATUS gums_make_domain(DOM_SID *sid, const char *name, const char *description)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- GUMS_FUNCTIONS *fns;
-
- if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns)))
- return ret;
-
- if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_DOMAIN)))
- return ret;
-
- ret = gums_set_object_sid(go, sid);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set sid!");
-
- ret = gums_set_object_name(go, name);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set name!");
-
- if (description) {
- ret = gums_set_object_description(go, description);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set description!");
- }
-
- /* make security descriptor * /
- ret = create_builtin_alias_default_sec_desc(&((*go).sec_desc), (*go).mem_ctx);
- NTSTATUS_CHECK(ret, error, "gums_init_backend", "create_builtin_alias_default_sec_desc");
- */
-
- ret = fns->set_object(go);
-
- gums_destroy_object(&go);
- return ret;
-}
-
-NTSTATUS gums_make_alias(DOM_SID *sid, const char *name, const char *description)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- GUMS_FUNCTIONS *fns;
-
- if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns)))
- return ret;
-
- if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_ALIAS)))
- return ret;
-
- ret = gums_set_object_sid(go, sid);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set sid!");
-
- ret = gums_set_object_name(go, name);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set name!");
-
- if (description) {
- ret = gums_set_object_description(go, description);
- NTSTATUS_CHECK(ret, done, "gums_make_alias", "unable to set description!");
- }
-
- /* make security descriptor * /
- ret = create_builtin_alias_default_sec_desc(&((*go).sec_desc), (*go).mem_ctx);
- NTSTATUS_CHECK(ret, error, "gums_init_backend", "create_builtin_alias_default_sec_desc");
- */
-
- ret = fns->set_object(go);
-
- gums_destroy_object(&go);
- return ret;
-}
-
-NTSTATUS gums_init_domain(DOM_SID *sid, const char *name, const char * description)
-{
- NTSTATUS ret;
-
- /* Add the weelknown Builtin Domain */
- if (!NT_STATUS_IS_OK(ret = gums_make_domain(
- sid,
- name,
- description
- ))) {
- return ret;
- }
-
- /* Add default users and groups */
- /* Administrator
- Guest
- Domain Administrators
- Domain Users
- Domain Guests
- */
-
- return ret;
-}
-
-NTSTATUS gums_init_builtin_domain(void)
-{
- NTSTATUS ret;
-
- generate_wellknown_sids();
-
- /* Add the weelknown Builtin Domain */
- if (!NT_STATUS_IS_OK(ret = gums_make_domain(
- &global_sid_Builtin,
- "BUILTIN",
- "Builtin Domain"
- ))) {
- return ret;
- }
-
- /* Add the well known Builtin Local Groups */
-
- /* Administrators */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Administrators,
- "Administrators",
- "Members can fully administer the computer/domain"
- ))) {
- return ret;
- }
- /* Administrator privilege set */
- /* From BDC join trace:
- SeSecurityPrivilege, SeBackupPrivilege, SeRestorePrivilege,
- SeSystemtimePrivilege, SeShutdownPrivilege,
- SeRemoteShutdownPrivilege, SeTakeOwnershipPrivilege,
- SeDebugPrivilege, SeSystemEnvironmentPrivilege,
- SeSystemProfilePrivilege, SeProfileSingleProcessPrivilege,
- SeIncreaseBasePriorityPrivilege, SeLocalDriverPrivilege,
- SeCreatePagefilePrivilege, SeIncreaseQuotaPrivilege
- */
-
- /* Power Users */
- /* Domain Controllers Does NOT have Power Users (?) */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Power_Users,
- "Power Users",
- "Power Users"
- ))) {
- return ret;
- }
-
- /* Power Users privilege set */
- /* (?) */
-
- /* Account Operators */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Account_Operators,
- "Account Operators",
- "Members can administer domain user and group accounts"
- ))) {
- return ret;
- }
-
- /* make privilege set */
- /* From BDC join trace:
- SeShutdownPrivilege
- */
-
- /* Server Operators */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Server_Operators,
- "Server Operators",
- "Members can administer domain servers"
- ))) {
- return ret;
- }
-
- /* make privilege set */
- /* From BDC join trace:
- SeBackupPrivilege, SeRestorePrivilege, SeSystemtimePrivilege,
- SeShutdownPrivilege, SeRemoteShutdownPrivilege
- */
-
- /* Print Operators */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Print_Operators,
- "Print Operators",
- "Members can administer domain printers"
- ))) {
- return ret;
- }
-
- /* make privilege set */
- /* From BDC join trace:
- SeShutdownPrivilege
- */
-
- /* Backup Operators */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Backup_Operators,
- "Backup Operators",
- "Members can bypass file security to backup files"
- ))) {
- return ret;
- }
-
- /* make privilege set */
- /* From BDC join trace:
- SeBackupPrivilege, SeRestorePrivilege, SeShutdownPrivilege
- */
-
- /* Replicator */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Replicator,
- "Replicator",
- "Supports file replication in a domain"
- ))) {
- return ret;
- }
-
- /* make privilege set */
- /* From BDC join trace:
- SeBackupPrivilege, SeRestorePrivilege, SeShutdownPrivilege
- */
-
- /* Users */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Users,
- "Users",
- "Ordinary users"
- ))) {
- return ret;
- }
-
- /* Users specific ACEs * /
- sec_desc_add_ace_to_dacl(go->sec_desc, go->mem_ctx, &global_sid_Builtin_Account_Operators, ALIAS_DEFAULT_DACL_SA_RIGHTS);
- sec_desc_add_ace_to_dacl(go->sec_desc, go->mem_ctx, &global_sid_Builtin_Power_Users, ALIAS_DEFAULT_DACL_SA_RIGHTS);
- */
-
- /* Guests */
- if (!NT_STATUS_IS_OK(ret = gums_make_alias(
- &global_sid_Builtin_Guests,
- "Guests",
- "Users granted guest access to the computer/domain"
- ))) {
- return ret;
- }
-
- return ret;
-}
-
diff --git a/source/sam/gums_tdbsam2.c b/source/sam/gums_tdbsam2.c
deleted file mode 100644
index 7fb9a1a997f..00000000000
--- a/source/sam/gums_tdbsam2.c
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * tdbsam2 - sam backend
- * Copyright (C) Simo Sorce 2002-2003
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "tdbsam2_parse_info.h"
-
-#if 0
-static int gums_tdbsam2_debug_class = DBGC_ALL;
-#endif
-/*
-#undef DBGC_CLASS
-#define DBGC_CLASS gums_tdbsam2_debug_class
-*/
-
-#define TDBSAM_VERSION 20021215
-#define TDB_FILE_NAME "tdbsam2.tdb"
-#define NAMEPREFIX "NAME_"
-#define SIDPREFIX "SID_"
-#define PRIVILEGEPREFIX "PRIV_"
-
-#define TDB_BASIC_OBJ_STRING "ddd"
-#define TDB_FORMAT_STRING "dddB"
-#define TDB_PRIV_FORMAT_STRING "ddB"
-
-#define TALLOC_CHECK(ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: Out of memory!\n", FUNCTION_MACRO)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
-#define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
-
-
-
-struct tdbsam2_enum_objs {
- uint32 type;
- DOM_SID *dom_sid;
- TDB_CONTEXT *db;
- TDB_DATA key;
- struct tdbsam2_enum_objs *next;
-};
-
-struct tdbsam2_private_data {
-
- const char *storage;
- struct tdbsam2_enum_objs *teo_handlers;
-};
-
-static struct tdbsam2_private_data *ts2_privs;
-
-static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size)
-{
-
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *mem_ctx;
- int iret;
- char *obj_data = NULL;
- int data_size = 0;
- int version, type, seqnum;
- int len;
-
- mem_ctx = talloc_init("init_object_from_buffer");
- if (!mem_ctx) {
- DEBUG(0, ("init_object_from_buffer: Out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- len = tdb_unpack (buffer, size, TDB_FORMAT_STRING,
- &version,
- &type,
- &seqnum,
- &data_size, &obj_data);
-
- if (len == -1 || data_size <= 0)
- goto done;
-
- /* version is checked inside this function so that backward
- compatibility code can be called eventually.
- This way we can easily handle database format upgrades */
- if (version != TDBSAM_VERSION) {
- DEBUG(3,("init_object_from_buffer: Error, db object has wrong tdbsam version!\n"));
- goto done;
- }
-
- /* be sure the string is terminated before trying to parse it */
- if (obj_data[data_size - 1] != '\0')
- obj_data[data_size - 1] = '\0';
-
- *go = (GUMS_OBJECT *)talloc_zero(mem_ctx, sizeof(GUMS_OBJECT));
- TALLOC_CHECK(*go, ret, done);
-
- switch (type) {
-
- case GUMS_OBJ_DOMAIN:
- iret = gen_parse(mem_ctx, pinfo_gums_domain, (char *)(*go), obj_data);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- iret = gen_parse(mem_ctx, pinfo_gums_group, (char *)(*go), obj_data);
- break;
-
- case GUMS_OBJ_NORMAL_USER:
- iret = gen_parse(mem_ctx, pinfo_gums_user, (char *)(*go), obj_data);
- break;
-
- default:
- DEBUG(3,("init_object_from_buffer: Error, wrong object type number!\n"));
- goto done;
- }
-
- if (iret != 0) {
- DEBUG(0, ("init_object_from_buffer: Fatal Error! Unable to parse object!\n"));
- DEBUG(0, ("init_object_from_buffer: DB Corrupt ?"));
- goto done;
- }
-
- (*go)->mem_ctx = mem_ctx;
-
- ret = NT_STATUS_OK;
-done:
- SAFE_FREE(obj_data);
- return ret;
-}
-
-static NTSTATUS init_privilege_from_buffer(GUMS_PRIVILEGE **priv, char *buffer, int size)
-{
-
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *mem_ctx;
- int iret;
- char *obj_data = NULL;
- int data_size = 0;
- int version, seqnum;
- int len;
-
- mem_ctx = talloc_init("init_privilege_from_buffer");
- if (!mem_ctx) {
- DEBUG(0, ("init_privilege_from_buffer: Out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- len = tdb_unpack (buffer, size, TDB_PRIV_FORMAT_STRING,
- &version,
- &seqnum,
- &data_size, &obj_data);
-
- if (len == -1 || data_size <= 0)
- goto done;
-
- /* version is checked inside this function so that backward
- compatibility code can be called eventually.
- This way we can easily handle database format upgrades */
- if (version != TDBSAM_VERSION) {
- DEBUG(3,("init_privilege_from_buffer: Error, db object has wrong tdbsam version!\n"));
- goto done;
- }
-
- /* be sure the string is terminated before trying to parse it */
- if (obj_data[data_size - 1] != '\0')
- obj_data[data_size - 1] = '\0';
-
- *priv = (GUMS_PRIVILEGE *)talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE));
- TALLOC_CHECK(*priv, ret, done);
-
- iret = gen_parse(mem_ctx, pinfo_gums_privilege, (char *)(*priv), obj_data);
-
- if (iret != 0) {
- DEBUG(0, ("init_privilege_from_buffer: Fatal Error! Unable to parse object!\n"));
- DEBUG(0, ("init_privilege_from_buffer: DB Corrupt ?"));
- goto done;
- }
-
- (*priv)->mem_ctx = mem_ctx;
-
- ret = NT_STATUS_OK;
-done:
- SAFE_FREE(obj_data);
- return ret;
-}
-
-static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_OBJECT *object)
-{
-
- NTSTATUS ret;
- char *genbuf = NULL;
- size_t buflen;
-
- if (!buffer)
- return NT_STATUS_INVALID_PARAMETER;
-
- switch (gums_get_object_type(object)) {
-
- case GUMS_OBJ_DOMAIN:
- genbuf = gen_dump(mem_ctx, pinfo_gums_domain, (char *)object, 0);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
- genbuf = gen_dump(mem_ctx, pinfo_gums_group, (char *)object, 0);
- break;
-
- case GUMS_OBJ_NORMAL_USER:
- genbuf = gen_dump(mem_ctx, pinfo_gums_user, (char *)object, 0);
- break;
-
- default:
- DEBUG(3,("init_buffer_from_object: Error, wrong object type number!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (genbuf == NULL) {
- DEBUG(0, ("init_buffer_from_object: Fatal Error! Unable to dump object!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- buflen = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
- TDBSAM_VERSION,
- object->type,
- object->seq_num,
- strlen(genbuf) + 1, genbuf);
-
- *buffer = talloc(mem_ctx, buflen);
- TALLOC_CHECK(*buffer, ret, done);
-
- *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING,
- TDBSAM_VERSION,
- object->type,
- object->seq_num,
- strlen(genbuf) + 1, genbuf);
-
- if (*len != buflen) {
- DEBUG(0, ("init_buffer_from_object: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n",
- buflen, *len));
- *buffer = NULL;
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- ret = NT_STATUS_OK;
-done:
- return ret;
-}
-
-static NTSTATUS init_buffer_from_privilege(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_PRIVILEGE *priv)
-{
-
- NTSTATUS ret;
- char *genbuf = NULL;
- size_t buflen;
-
- if (!buffer || !len || !mem_ctx || !priv)
- return NT_STATUS_INVALID_PARAMETER;
-
- genbuf = gen_dump(mem_ctx, pinfo_gums_privilege, (char *)priv, 0);
-
- if (genbuf == NULL) {
- DEBUG(0, ("init_buffer_from_privilege: Fatal Error! Unable to dump object!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- buflen = tdb_pack(NULL, 0, TDB_PRIV_FORMAT_STRING,
- TDBSAM_VERSION,
- priv->seq_num,
- strlen(genbuf) + 1, genbuf);
-
- *buffer = talloc(mem_ctx, buflen);
- TALLOC_CHECK(*buffer, ret, done);
-
- *len = tdb_pack(*buffer, buflen, TDB_PRIV_FORMAT_STRING,
- TDBSAM_VERSION,
- priv->seq_num,
- strlen(genbuf) + 1, genbuf);
-
- if (*len != buflen) {
- DEBUG(0, ("init_buffer_from_privilege: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n",
- buflen, *len));
- *buffer = NULL;
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- ret = NT_STATUS_OK;
-done:
- return ret;
-}
-
-static NTSTATUS opentdb(TDB_CONTEXT **tdb, BOOL readonly)
-{
- if (!tdb)
- return NT_STATUS_INVALID_PARAMETER;
-
- *tdb = tdb_open_log(ts2_privs->storage, 0, TDB_DEFAULT, readonly?(O_RDONLY):(O_RDWR | O_CREAT), 0600);
- if (!(*tdb))
- {
- DEBUG(0, ("opentdb: Unable to open database (%s)!\n", ts2_privs->storage));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS get_object_by_sid(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const DOM_SID *sid)
-{
- NTSTATUS ret;
- TDB_DATA data, key;
- fstring keystr;
-
- if (!obj || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(tdb, key);
- if (!data.dptr) {
- DEBUG(5, ("get_object_by_sid: Entry not found!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_NOT_FOUND;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(init_object_from_buffer(obj, data.dptr, data.dsize))) {
- DEBUG(0, ("get_object_by_sid: Error fetching database, malformed entry!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-static NTSTATUS make_full_object_name(TDB_CONTEXT *tdb, fstring objname, GUMS_OBJECT *object)
-{
- NTSTATUS ret;
-
- objname[0] = '\0';
-
- if (gums_get_object_type(object) == GUMS_OBJ_DOMAIN) {
-
- fstrcpy(objname, gums_get_object_name(object));
-
- } else {
- GUMS_OBJECT *domain_object;
- DOM_SID domain_sid;
- uint32 *discard_rid;
-
- sid_copy(&domain_sid, gums_get_object_sid(object));
- sid_split_rid(&domain_sid, discard_rid);
-
- if (!NT_STATUS_IS_OK(get_object_by_sid(tdb,
- &domain_object,
- &domain_sid))) {
-
- DEBUG(3, ("Object's domain not found!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- fstrcpy(objname, gums_get_object_name(domain_object));
- fstrcat(objname, "\\");
- fstrcat(objname, gums_get_object_name(object));
- }
-
- ret = NT_STATUS_OK;
-
-done:
- return ret;
-}
-
-/* name should be in DOMAIN\NAME format */
-static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char *fullname)
-{
-
- NTSTATUS ret = NT_STATUS_OK;
- TDB_DATA data, key;
- fstring keystr;
- fstring objname;
- DOM_SID sid;
- fstring sidstr;
- int sidstr_len;
-
- if (!obj || !fullname)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* Data is stored in all lower-case */
- fstrcpy(objname, fullname);
- strlower_m(objname);
-
- slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(tdb, key);
- if (!data.dptr) {
- DEBUG(5, ("get_object_by_name: Entry not found!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_NOT_FOUND;
- goto done;
- }
-
- fstrcpy(sidstr, data.dptr);
- sidstr_len = data.dsize;
-
- SAFE_FREE(data.dptr);
-
- if (sidstr_len <= 0) {
- DEBUG(5, ("get_object_by_name: Error unpacking database object!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!string_to_sid(&sid, sidstr)) {
- DEBUG(5, ("get_object_by_name: Error invalid sid string found in database object!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
-done:
- if (NT_STATUS_IS_OK(ret))
- return get_object_by_sid(tdb, obj, &sid);
- return ret;
-}
-
-/* Get object's sequence number */
-
-static NTSTATUS get_object_seq_num(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int *seq_num)
-{
-
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- TDB_DATA data, key;
- fstring keystr;
- fstring sidstr;
- int version, type, seqnum;
-
- if (!object || !seq_num)
- return NT_STATUS_INVALID_PARAMETER;
-
- fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
- slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sidstr);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(tdb, key);
- if (!data.dptr) {
- DEBUG(5, ("get_object_seq_num: Entry not found!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_NOT_FOUND;
- goto done;
- }
-
- if (tdb_unpack (data.dptr, data.dsize, TDB_BASIC_OBJ_STRING, &version, &type, &seqnum) == -1)
- goto done;
-
- *seq_num = seqnum;
- ret = NT_STATUS_OK;
-
-done:
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/* store a gums object
- * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT
- */
-
-static NTSTATUS store_object(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int flag)
-{
- NTSTATUS ret = NT_STATUS_OK;
- TDB_DATA data, data2, key, key2;
- TALLOC_CTX *mem_ctx;
- fstring keystr;
- fstring sidstr;
- fstring namestr;
- fstring objname;
- int r;
-
- /* TODO: on object renaming/replacing this function should
- * check name->sid record and delete the old one
- */
-
- mem_ctx = talloc_init("store_object");
- if (!mem_ctx) {
- DEBUG(0, ("store_object: Out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- make_full_object_name(tdb, objname, object);
-
- /* Data is stored in all lower-case */
- strlower_m(objname);
-
- if (flag == TDB_MODIFY) {
- if (!NT_STATUS_IS_OK(ret = get_object_seq_num(tdb, object, &(object->seq_num))))
- goto done;
- object->seq_num += 1;
- }
-
- if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object)))
- goto done;
-
- fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
- slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr);
- slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) {
- DEBUG(0, ("store_object: Unable to modify TDBSAM!\n"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb)));
- DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr));
- if (r == TDB_ERR_EXISTS)
- ret = NT_STATUS_UNSUCCESSFUL;
- else
- ret = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
- data2.dptr = sidstr;
- data2.dsize = strlen(sidstr) + 1;
- key2.dptr = namestr;
- key2.dsize = strlen(namestr) + 1;
-
- if ((r = tdb_store(tdb, key2, data2, flag)) != TDB_SUCCESS) {
- DEBUG(0, ("store_object: Unable to modify TDBSAM!\n"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb)));
- DEBUGADD(0, (" occured while storing name record (%s)\n", keystr));
- DEBUGADD(0, (" attempting rollback operation.\n"));
- if ((tdb_delete(tdb, key)) != TDB_SUCCESS) {
- DEBUG(0, ("store_object: Unable to rollback! Check database consitency!\n"));
- }
- if (r == TDB_ERR_EXISTS)
- ret = NT_STATUS_UNSUCCESSFUL;
- else
- ret = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
-/* TODO: update the general database counter */
-/* TODO: update this entry counter too */
-
-done:
- talloc_destroy(mem_ctx);
- return ret;
-}
-
-/* GUMM object functions */
-
-static NTSTATUS tdbsam2_get_domain_sid(DOM_SID *sid, const char* name)
-{
-
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
- GUMS_OBJECT *go;
- fstring domname;
-
- if (!sid || !name)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
- return ret;
- }
-
- /* Data is stored in all lower-case */
- fstrcpy(domname, name);
- strlower_m(domname);
-
- if (!NT_STATUS_IS_OK(ret = get_object_by_name(tdb, &go, domname))) {
- go = NULL;
- DEBUG(0, ("tdbsam2_get_domain_sid: Error fetching database!\n"));
- goto done;
- }
-
- if (gums_get_object_type(go) != GUMS_OBJ_DOMAIN) {
- DEBUG(5, ("tdbsam2_get_domain_sid: Requested object is not a domain!\n"));
- ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
- goto done;
- }
-
- sid_copy(sid, gums_get_object_sid(go));
-
- ret = NT_STATUS_OK;
-
-done:
- if (go)
- gums_destroy_object(&go);
- tdb_close(tdb);
- return ret;
-}
-
-static NTSTATUS get_next_sid(TDB_CONTEXT *tdb, DOM_SID *sid)
-{
- NTSTATUS ret;
- GUMS_OBJECT *go;
- DOM_SID dom_sid;
- TDB_DATA dom_sid_key;
- fstring dom_sid_str;
- uint32 new_rid;
-
- /* Find the domain SID */
- if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) {
- DEBUG(0, ("get_next_sid: cannot found the domain sid!!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Lock the domain record */
- sid_to_string(dom_sid_str, &dom_sid);
- dom_sid_key.dptr = dom_sid_str;
- dom_sid_key.dsize = strlen(dom_sid_key.dptr) + 1;
-
- if(tdb_chainlock(tdb, dom_sid_key) != 0) {
- DEBUG(0, ("get_next_sid: unable to lock domain record!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Get the domain object */
- ret = get_object_by_sid(tdb, &go, &dom_sid);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("get_next_sid: unable to get root Domain object!\n"));
- ret = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
- new_rid = gums_get_domain_next_rid(go);
-
- /* Increment the RID Counter */
- gums_set_domain_next_rid(go, new_rid+1);
-
- /* Store back Domain object */
- ret = store_object(tdb, go, TDB_MODIFY);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("get_next_sid: unable to update root Domain object!\n"));
- ret = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
- /* Build the Domain SID to return */
- sid_copy(sid, &dom_sid);
-
- if (!sid_append_rid(sid, new_rid)) {
- DEBUG(0, ("get_next_sid: unable to build new SID !?!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- ret = NT_STATUS_OK;
-
-done:
- /* Unlock the Domain object */
- tdb_chainunlock(tdb, dom_sid_key);
-
- return ret;
-}
-
-/* TODO */
- NTSTATUS (*get_sequence_number) (void);
-
-
-extern DOM_SID global_sid_NULL;
-
-static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj_type)
-{
-
- NTSTATUS ret = NT_STATUS_OK;
- TDB_CONTEXT *tdb;
- GUMS_OBJECT *go;
- NTTIME null_time;
- DATA_BLOB pw;
- const char *defpw = "NOPASSWORDXXXXXX";
- uint8 defhours[21] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
-
- if (!name) {
- DEBUG(0, ("tdbsam2_new_object: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
- return ret;
- }
-
- if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, obj_type))) {
- go = NULL;
- goto done;
- }
-
- if (obj_type == GUMS_OBJ_DOMAIN) {
- sid_copy(sid, get_global_sam_sid());
- } else {
- if (!NT_STATUS_IS_OK(ret = get_next_sid(tdb, sid)))
- goto done;
- }
-
- gums_set_object_sid(go, sid);
- gums_set_object_name(go, name);
- gums_set_object_seq_num(go, 1);
-
- /*obj.domain->sec_desc*/
-
- switch (obj_type) {
- case GUMS_OBJ_NORMAL_USER:
-
- init_nt_time(&null_time);
-
- gums_set_user_logon_time(go, null_time);
- gums_set_user_logoff_time(go, null_time);
- gums_set_user_kickoff_time(go, null_time);
- gums_set_user_pass_last_set_time(go, null_time);
- gums_set_user_pass_can_change_time(go, null_time);
- gums_set_user_pass_must_change_time(go, null_time);
-
- pw = data_blob(defpw, NT_HASH_LEN);
- gums_set_user_nt_pwd(go, pw);
- gums_set_user_lm_pwd(go, pw);
- data_blob_free(&pw);
-
- gums_set_user_logon_divs(go, 168);
- gums_set_user_hours(go, 21, defhours);
-
- gums_set_user_bad_password_count(go, 0);
- gums_set_user_logon_count(go, 0);
- gums_set_user_unknown_6(go, 0x000004ec);
- break;
-
- case GUMS_OBJ_GROUP:
- case GUMS_OBJ_ALIAS:
-
- break;
-
- case GUMS_OBJ_DOMAIN:
-
- gums_set_domain_next_rid(go, 0x3e9);
-
- break;
-
- default:
- ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
- goto done;
- }
-
- ret = store_object(tdb, go, TDB_INSERT);
-
-done:
- if (go)
- gums_destroy_object(&go);
- tdb_close(tdb);
- return ret;
-}
-
-/* TODO: handle privileges objects */
-
-static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
-{
- /* TODO: need to address privilege deletion */
- NTSTATUS ret = NT_STATUS_OK;
- TDB_CONTEXT *tdb;
- GUMS_OBJECT *go;
- TDB_DATA data, key;
- fstring keystr;
-
- if (!sid) {
- DEBUG(0, ("tdbsam2_delete_object: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
- return ret;
- }
-
- slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(sid));
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- data = tdb_fetch(tdb, key);
- if (!data.dptr) {
- DEBUG(5, ("tdbsam2_delete_object: Error fetching database, SID entry not found!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (tdb_delete(tdb, key) != TDB_SUCCESS) {
- DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(init_object_from_buffer(&go, data.dptr, data.dsize))) {
- DEBUG(0, ("tdbsam2_delete_object: Error fetching database, malformed entry!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go));
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- if (tdb_delete(tdb, key) != TDB_SUCCESS) {
- DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
- DEBUGADD(5, (" Key: %s\n", keystr));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
-/* TODO: update the general database counter */
-
-done:
- gums_destroy_object(&go);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type)
-{
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
-
- if (!object || !sid) {
- DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
- return ret;
- }
-
- ret = get_object_by_sid(tdb, object, sid);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret)));
- goto error;
- }
- if (obj_type && gums_get_object_type(*object) != obj_type) {
- DEBUG(0, ("tdbsam2_get_object_from_sid: the object is not of the rerquested type!\n"));
- goto error;
- }
-
- tdb_close(tdb);
- return NT_STATUS_OK;
-
-error:
- gums_destroy_object(object);
- tdb_close(tdb);
- return ret;
-}
-
-static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type)
-{
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
- fstring objname;
-
- if (!object || !name) {
- DEBUG(0, ("tdbsam2_get_object_from_name: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
- return ret;
- }
-
- if (obj_type == GUMS_OBJ_DOMAIN) {
- fstrcpy(objname, name);
- } else {
- if (!domain) {
- domain = global_myname();
- }
- fstrcpy(objname, domain);
- fstrcat(objname, "\\");
- fstrcat(objname, name);
- }
-
- *object = NULL;
- ret = get_object_by_name(tdb, object, name);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret)));
- goto error;
- }
- if (obj_type && gums_get_object_type(*object) != obj_type) {
- DEBUG(0, ("tdbsam2_get_object_from_name: the object is not of the rerquested type!\n"));
- goto error;
- }
-
- tdb_close(tdb);
- return NT_STATUS_OK;
-
-error:
- gums_destroy_object(object);
- tdb_close(tdb);
- return ret;
-}
-
- /* This function is used to get the list of all objects changed since base_time, it is
- used to support PDC<->BDC synchronization */
- NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time);
-
-static NTSTATUS tdbsam2_enumerate_objects_start(void **handle, const DOM_SID *sid, const int obj_type)
-{
- struct tdbsam2_enum_objs *teo, *t;
-
- teo = (struct tdbsam2_enum_objs *)malloc(sizeof(struct tdbsam2_enum_objs));
- if (!teo) {
- DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
- memset(teo, 0, sizeof(struct tdbsam2_enum_objs));
-
- teo->type = obj_type;
- if (sid) {
- teo->dom_sid = (DOM_SID *)malloc(sizeof(DOM_SID));
- if (!teo->dom_sid) {
- DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
- sid_copy(teo->dom_sid, sid);
- }
-
- if (!NT_STATUS_IS_OK(opentdb(&(teo->db), True)))
- {
- DEBUG(0, ("tdbsam2_enumerate_objects_start: Unable to open database (%s)!\n", ts2_privs->storage));
- SAFE_FREE(teo);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!ts2_privs->teo_handlers) {
- ts2_privs->teo_handlers = teo;
- } else {
- t = ts2_privs->teo_handlers;
- while (t->next) {
- t = t->next;
- }
- t->next = teo;
- }
-
- *handle = teo;
-
- teo->key = tdb_firstkey(teo->db);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *handle)
-{
- NTSTATUS ret;
- TDB_DATA data;
- struct tdbsam2_enum_objs *teo;
- const char *prefix = SIDPREFIX;
- const int preflen = strlen(prefix);
- fstring dom_sid_str;
- int dom_sid_str_len = 0;
-
- if (!object || !handle) {
- DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- teo = (struct tdbsam2_enum_objs *)handle;
-
- if (teo->dom_sid) {
- sid_to_string(dom_sid_str, teo->dom_sid);
- dom_sid_str_len = strlen(dom_sid_str);
- }
-
- while ((teo->key.dptr != NULL)) {
- int len, version, type, size, seqnum;
- char *ptr;
-
- if (strncmp(teo->key.dptr, prefix, preflen)) {
- teo->key = tdb_nextkey(teo->db, teo->key);
- continue;
- }
-
- if (dom_sid_str_len != 0) {
- if (strncmp(&(teo->key.dptr[preflen]), dom_sid_str, dom_sid_str_len)) {
- teo->key = tdb_nextkey(teo->db, teo->key);
- continue;
- }
- }
-
- data = tdb_fetch(teo->db, teo->key);
- if (!data.dptr) {
- DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error fetching database, SID entry not found!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(teo->db)));
- DEBUGADD(5, (" Key: %s\n", teo->key.dptr));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING,
- &version,
- &type,
- &seqnum,
- &size, &ptr);
-
- if (len == -1) {
- DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error unable to unpack data!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- SAFE_FREE(ptr);
-
- if (teo->type && type != teo->type) {
- SAFE_FREE(data.dptr);
- data.dsize = 0;
- teo->key = tdb_nextkey(teo->db, teo->key);
- continue;
- }
-
- break;
- }
-
- if (teo->key.dptr == NULL) { /* no more objs */
- ret = NT_STATUS_NO_MORE_ENTRIES;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(ret = init_object_from_buffer(object, data.dptr, data.dsize))) {
- SAFE_FREE(data.dptr);
- DEBUG(0, ("tdbsam2_enumerate_objects_get_next: Error fetching database, malformed entry!\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- SAFE_FREE(data.dptr);
-
- /* prepare next run */
- teo->key = tdb_nextkey(teo->db, teo->key);
-
-done:
- return ret;
-}
-
-static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle)
-{
- struct tdbsam2_enum_objs *teo, *t, *p;
-
- teo = (struct tdbsam2_enum_objs *)handle;
-
- if (ts2_privs->teo_handlers == teo) {
- ts2_privs->teo_handlers = teo->next;
- } else {
- t = ts2_privs->teo_handlers;
- while (t != teo) {
- p = t;
- t = t->next;
- if (t == NULL) {
- DEBUG(0, ("tdbsam2_enumerate_objects_stop: Error, handle not found!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- p = t->next;
- }
-
- tdb_close(teo->db);
- SAFE_FREE(teo->dom_sid);
- SAFE_FREE(teo);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS tdbsam2_set_object(GUMS_OBJECT *go)
-{
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
-
- if (!go)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
- return ret;
- }
-
- ret = store_object(tdb, go, TDB_REPLACE);
-
- tdb_close(tdb);
- return ret;
-}
-
-#if 0
- /* set object values function */
-static NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set);
-
- /* Group related functions */
-static NTSTATUS (*add_memberss_to_group) (const DOM_SID *group, const DOM_SID **members);
- NTSTATUS (*delete_members_from_group) (const DOM_SID *group, const DOM_SID **members);
-static NTSTATUS (*enumerate_group_members) (DOM_SID **members, const DOM_SID *sid, const int type);
-
-static NTSTATUS (*get_sid_groups) (DOM_SID **groups, const DOM_SID *sid);
-
-static NTSTATUS (*lock_sid) (const DOM_SID *sid);
-static NTSTATUS (*unlock_sid) (const DOM_SID *sid);
-
- /* privileges related functions */
-
-static NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name);
-static NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members);
-static NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members);
-static NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members);
-static NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs);
-
- /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
-static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
-#endif
-
-static void free_tdbsam2_private_data(void **vp)
-{
- struct tdbsam2_private_data **tdb_privs = (struct tdbsam2_private_data **)vp;
- while (ts2_privs->teo_handlers)
- tdbsam2_enumerate_objects_stop(ts2_privs->teo_handlers);
- *tdb_privs = NULL;
- /* No need to free any further, as it is talloc()ed */
-}
-
-static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
-{
- NTSTATUS ret;
- TDB_CONTEXT *tdb;
- DOM_SID dom_sid;
-
- fns->name = talloc_strdup(fns->mem_ctx, "tdbsam2");
-
- fns->get_domain_sid = tdbsam2_get_domain_sid;
- /* fns->get_sequence_number = tdbsam2_get_sequence_number; */
- fns->new_object = tdbsam2_new_object;
- fns->delete_object = tdbsam2_delete_object;
- fns->get_object_from_sid = tdbsam2_get_object_from_sid;
- fns->get_object_from_name = tdbsam2_get_object_from_name;
- /* fns->get_updated_objects = tdbsam2_get_updated_objects; */
- fns->enumerate_objects_start = tdbsam2_enumerate_objects_start;
- fns->enumerate_objects_get_next = tdbsam2_enumerate_objects_get_next;
- fns->enumerate_objects_stop = tdbsam2_enumerate_objects_stop;
- fns->set_object = tdbsam2_set_object;
- /* fns->set_object_values = tdbsam2_set_object_values;
- fns->add_members_to_group = tdbsam2_add_members_to_group;
- fns->delete_members_from_group = tdbsam2_delete_members_from_group;
- fns->enumerate_group_members = tdbsam2_enumerate_group_members;
- fns->get_sid_groups = tdbsam2_get_sid_groups;
- fns->lock_sid = tdbsam2_lock_sid;
- fns->unlock_sid = tdbsam2_unlock_sid;
- fns->get_privilege = tdbsam2_get_privilege;
- fns->add_members_to_privilege = tdbsam2_add_members_to_privilege;
- fns->delete_members_from_privilege = tdbsam2_delete_members_from_privilege;
- fns->enumerate_privilege_members = tdbsam2_enumerate_privilege_members;
- fns->get_sid_privileges = tdbsam2_get_sid_privileges;
- fns->set_privilege = tdbsam2_set_privilege; */
-
- ts2_privs = talloc_zero(fns->mem_ctx, sizeof(struct tdbsam2_private_data));
- if (!ts2_privs) {
- DEBUG(0, ("talloc() failed for tdbsam2 private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (storage) {
- ts2_privs->storage = talloc_strdup(fns->mem_ctx, storage);
- } else {
- pstring tdbfile;
- get_private_directory(tdbfile);
- pstrcat(tdbfile, "/");
- pstrcat(tdbfile, TDB_FILE_NAME);
- ts2_privs->storage = talloc_strdup(fns->mem_ctx, tdbfile);
- }
-
- /* check tdb exist (or create it) */
-
- /* Find the domain SID */
- if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) {
- /* db file does not exist or it is not inited */
- /* make the tdb file */
- if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
- return ret;
- }
- tdb_close(tdb);
-
- if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, "BUILTIN"))) {
- gums_init_builtin_domain();
- }
-
- gums_init_domain(get_global_sam_sid(), global_myname(), "The Domain");
- }
-
- fns->private_data = &ts2_privs;
- fns->free_private_data = free_tdbsam2_private_data;
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS gums_tdbsam2_init(void)
-{
- /*
- if ((gums_tdbsam2_debug_class = debug_add_class("gums_tdbsam2")) == -1) {
- DEBUG(0, ("gums_tdbsam2: unable to register my own debug class! going on ...\n"));
- gums_tdbsam2_debug_class = DBGC_ALL;
- }
- */
- return gums_register_module(GUMS_INTERFACE_VERSION, "tdbsam2", init_tdbsam2);
-}
diff --git a/source/sam/idmap.c b/source/sam/idmap.c
deleted file mode 100644
index 4d8b768c2fa..00000000000
--- a/source/sam/idmap.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ID Mapping
- Copyright (C) Tim Potter 2000
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
- Copyright (C) Simo Sorce 2003
- Copyright (C) Jeremy Allison 2003.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-struct idmap_function_entry {
- const char *name;
- struct idmap_methods *methods;
- struct idmap_function_entry *prev,*next;
-};
-
-static struct idmap_function_entry *backends = NULL;
-
-static struct idmap_methods *cache_map;
-static struct idmap_methods *remote_map;
-
-/**********************************************************************
- Get idmap methods. Don't allow tdb to be a remote method.
-**********************************************************************/
-
-static struct idmap_methods *get_methods(const char *name, BOOL cache_method)
-{
- struct idmap_function_entry *entry = backends;
-
- for(entry = backends; entry; entry = entry->next) {
- if (!cache_method && strequal(entry->name, "tdb"))
- continue; /* tdb is only cache method. */
- if (strequal(entry->name, name))
- return entry->methods;
- }
-
- return NULL;
-}
-
-/**********************************************************************
- Allow a module to register itself as a method.
-**********************************************************************/
-
-NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods)
-{
- struct idmap_function_entry *entry;
-
- if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
- DEBUG(0, ("smb_register_idmap: Failed to register idmap module.\n"
- "The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n"
- "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
- "Please recompile against the current version of samba!\n",
- version, SMB_IDMAP_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !name[0] || !methods) {
- DEBUG(0,("smb_register_idmap: called with NULL pointer or empty name!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (get_methods(name, False)) {
- DEBUG(0,("smb_register_idmap: idmap module %s already registered!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct idmap_function_entry));
- entry->name = smb_xstrdup(name);
- entry->methods = methods;
-
- DLIST_ADD(backends, entry);
- DEBUG(5, ("smb_register_idmap: Successfully added idmap backend '%s'\n", name));
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Initialise idmap cache and a remote backend (if configured).
-**********************************************************************/
-
-BOOL idmap_init(const char *remote_backend)
-{
- if (!backends)
- static_init_idmap;
-
- if (!cache_map) {
- cache_map = get_methods("tdb", True);
-
- if (!cache_map) {
- DEBUG(0, ("idmap_init: could not find tdb cache backend!\n"));
- return False;
- }
-
- if (!NT_STATUS_IS_OK(cache_map->init( NULL ))) {
- DEBUG(0, ("idmap_init: could not initialise tdb cache backend!\n"));
- return False;
- }
- }
-
- if (!remote_map && remote_backend && *remote_backend != 0) {
- char *rem_backend = smb_xstrdup(remote_backend);
- fstring params = "";
- char *pparams;
-
- /* get any mode parameters passed in */
-
- if ( (pparams = strchr( rem_backend, ':' )) != NULL ) {
- *pparams = '\0';
- pparams++;
- fstrcpy( params, pparams );
- }
-
- DEBUG(3, ("idmap_init: using '%s' as remote backend\n", rem_backend));
-
- if((remote_map = get_methods(rem_backend, False)) ||
- (NT_STATUS_IS_OK(smb_probe_module("idmap", rem_backend)) &&
- (remote_map = get_methods(rem_backend, False)))) {
- remote_map->init(params);
- } else {
- DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", rem_backend));
- SAFE_FREE(rem_backend);
- return False;
- }
- SAFE_FREE(rem_backend);
- }
-
- return True;
-}
-
-/**************************************************************************
- This is a rare operation, designed to allow an explicit mapping to be
- set up for a sid to a POSIX id.
-**************************************************************************/
-
-NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
-{
- struct idmap_methods *map = remote_map;
- DOM_SID tmp_sid;
-
- DEBUG(10, ("idmap_set_mapping: Set %s to %s %lu\n",
- sid_string_static(sid),
- ((id_type & ID_TYPEMASK) == ID_USERID) ? "UID" : "GID",
- ((id_type & ID_TYPEMASK) == ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid));
-
- if ( (NT_STATUS_IS_OK(cache_map->
- get_sid_from_id(&tmp_sid, id,
- id_type | ID_QUERY_ONLY))) &&
- sid_equal(sid, &tmp_sid) ) {
- /* Nothing to do, we already have that mapping */
- DEBUG(10, ("idmap_set_mapping: Mapping already there\n"));
- return NT_STATUS_OK;
- }
-
- if (map == NULL) {
- /* Ok, we don't have a authoritative remote
- mapping. So update our local cache only. */
- map = cache_map;
- }
-
- return map->set_mapping(sid, id, id_type);
-}
-
-/**************************************************************************
- Get ID from SID. This can create a mapping for a SID to a POSIX id.
-**************************************************************************/
-
-NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
-{
- NTSTATUS ret;
- int loc_type;
-
- loc_type = *id_type;
-
- if (remote_map) {
- /* We have a central remote idmap so only look in
- cache, don't allocate */
- loc_type |= ID_QUERY_ONLY;
- }
-
- ret = cache_map->get_id_from_sid(id, &loc_type, sid);
-
- if (NT_STATUS_IS_OK(ret)) {
- *id_type = loc_type & ID_TYPEMASK;
- return NT_STATUS_OK;
- }
-
- if (remote_map == NULL) {
- return ret;
- }
-
- /* Ok, the mapping was not in the cache, give the remote map a
- second try. */
-
- ret = remote_map->get_id_from_sid(id, id_type, sid);
-
- if (NT_STATUS_IS_OK(ret)) {
- /* The remote backend gave us a valid mapping, cache it. */
- ret = cache_map->set_mapping(sid, *id, *id_type);
- }
-
- return ret;
-}
-
-/**************************************************************************
- Get SID from ID. This must have been created before.
-**************************************************************************/
-
-NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
-{
- NTSTATUS ret;
- int loc_type;
-
- loc_type = id_type;
- if (remote_map) {
- loc_type = id_type | ID_QUERY_ONLY;
- }
-
- ret = cache_map->get_sid_from_id(sid, id, loc_type);
-
- if (NT_STATUS_IS_OK(ret))
- return ret;
-
- if (remote_map == NULL)
- return ret;
-
- /* We have a second chance, ask our authoritative backend */
-
- ret = remote_map->get_sid_from_id(sid, id, id_type);
-
- if (NT_STATUS_IS_OK(ret)) {
- /* The remote backend gave us a valid mapping, cache it. */
- ret = cache_map->set_mapping(sid, id, id_type);
- }
-
- return ret;
-}
-
-/**************************************************************************
- Alloocate a new UNIX uid/gid
-**************************************************************************/
-
-NTSTATUS idmap_allocate_id(unid_t *id, int id_type)
-{
- /* we have to allocate from the authoritative backend */
-
- if ( remote_map )
- return remote_map->allocate_id( id, id_type );
-
- return cache_map->allocate_id( id, id_type );
-}
-
-/**************************************************************************
- Alloocate a new RID
-**************************************************************************/
-
-NTSTATUS idmap_allocate_rid(uint32 *rid, int type)
-{
- /* we have to allocate from the authoritative backend */
-
- if ( remote_map )
- return remote_map->allocate_rid( rid, type );
-
- return cache_map->allocate_rid( rid, type );
-}
-
-/**************************************************************************
- Shutdown maps.
-**************************************************************************/
-
-NTSTATUS idmap_close(void)
-{
- NTSTATUS ret;
-
- ret = cache_map->close();
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(3, ("idmap_close: failed to close local tdb cache!\n"));
- }
- cache_map = NULL;
-
- if (remote_map) {
- ret = remote_map->close();
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n"));
- }
- remote_map = NULL;
- }
-
- return ret;
-}
-
-/**************************************************************************
- Dump backend status.
-**************************************************************************/
-
-void idmap_status(void)
-{
- cache_map->status();
- if (remote_map)
- remote_map->status();
-}
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
deleted file mode 100644
index 2124fb68793..00000000000
--- a/source/sam/idmap_ldap.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- idmap LDAP backend
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
- Copyright (C) Simo Sorce 2003
- Copyright (C) Gerald Carter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-
-#include <lber.h>
-#include <ldap.h>
-
-#include "smbldap.h"
-
-struct ldap_idmap_state {
- struct smbldap_state *smbldap_state;
- TALLOC_CTX *mem_ctx;
-};
-
-static struct ldap_idmap_state ldap_state;
-
-/* number tries while allocating new id */
-#define LDAP_MAX_ALLOC_ID 128
-
-
-/***********************************************************************
- This function cannot be called to modify a mapping, only set a new one
-***********************************************************************/
-
-static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
-{
- pstring dn;
- pstring id_str;
- fstring type;
- LDAPMod **mods = NULL;
- int rc = -1;
- int ldap_op;
- fstring sid_string;
- LDAPMessage *entry = NULL;
-
- sid_to_string( sid_string, sid );
-
- ldap_op = LDAP_MOD_ADD;
- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
- sid_string, lp_ldap_idmap_suffix());
-
- if ( id_type & ID_USERID )
- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) );
- else
- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) );
-
- pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid));
-
- smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods, type, id_str );
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods,
- get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
- sid_string );
-
- /* There may well be nothing at all to do */
-
- if (mods) {
- smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY );
- rc = smbldap_add(ldap_state.smbldap_state, dn, mods);
- ldap_mods_free( mods, True );
- } else {
- rc = LDAP_SUCCESS;
- }
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
- (ldap_op == LDAP_MOD_ADD) ? "add" : "replace",
- sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type));
- DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
- ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
- sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid), type));
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Even if the sambaDomain attribute in LDAP tells us that this RID is
- safe to use, always check before use.
-*********************************************************************/
-
-static BOOL sid_in_use(struct ldap_idmap_state *state,
- const DOM_SID *sid, int *error)
-{
- fstring filter;
- fstring sid_string;
- LDAPMessage *result = NULL;
- int count;
- int rc;
- char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
-
- slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
-
- rc = smbldap_search_suffix(state->smbldap_state,
- filter, sid_attr, &result);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
- sid_string, ld_error));
- SAFE_FREE(ld_error);
-
- *error = rc;
- return True;
- }
-
- if ((count = ldap_count_entries(state->smbldap_state->ldap_struct, result)) > 0) {
- DEBUG(3, ("Sid %s already in use - trying next RID\n",
- sid_string));
- ldap_msgfree(result);
- return True;
- }
-
- ldap_msgfree(result);
-
- /* good, sid is not in use */
- return False;
-}
-
-/**********************************************************************
- Set the new nextRid attribute, and return one we can use.
-
- This also checks that this RID is actually free - in case the admin
- manually stole it :-).
-*********************************************************************/
-
-static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
- int rid_type)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- int rc;
- LDAPMessage *domain_result = NULL;
- LDAPMessage *entry = NULL;
- char *dn;
- LDAPMod **mods = NULL;
- fstring old_rid_string;
- fstring next_rid_string;
- fstring algorithmic_rid_base_string;
- uint32 next_rid;
- uint32 alg_rid_base;
- int attempts = 0;
- char *ld_error = NULL;
-
- while (attempts < 10) {
- if (!NT_STATUS_IS_OK(ret = smbldap_search_domain_info(state->smbldap_state,
- &domain_result, get_global_sam_name(), True))) {
- return ret;
- }
-
- entry = ldap_first_entry(state->smbldap_state->ldap_struct, domain_result);
- if (!entry) {
- DEBUG(0, ("Could not get domain info entry\n"));
- ldap_msgfree(domain_result);
- return ret;
- }
-
- if ((dn = smbldap_get_dn(state->smbldap_state->ldap_struct, entry)) == NULL) {
- DEBUG(0, ("Could not get domain info DN\n"));
- ldap_msgfree(domain_result);
- return ret;
- }
-
- /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
- algorithmic_rid_base. The other two are to avoid stomping on the
- different sets of algorithmic RIDs */
-
- if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
- algorithmic_rid_base_string)) {
-
- alg_rid_base = (uint32)atol(algorithmic_rid_base_string);
- } else {
- alg_rid_base = algorithmic_rid_base();
- /* Try to make the modification atomically by enforcing the
- old value in the delete mod. */
- slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string)-1, "%d", alg_rid_base);
- smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
- algorithmic_rid_base_string);
- }
-
- next_rid = 0;
-
- if (alg_rid_base > BASE_RID) {
- /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we
- can allocate to new users */
- if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID),
- old_rid_string)) {
- *rid = (uint32)atol(old_rid_string);
- } else {
- *rid = BASE_RID;
- }
-
- next_rid = *rid+1;
- if (next_rid >= alg_rid_base) {
- ldap_msgfree(domain_result);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
-
- /* Try to make the modification atomically by enforcing the
- old value in the delete mod. */
- smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID),
- next_rid_string);
- }
-
- if (!next_rid) { /* not got one already */
- switch (rid_type) {
- case USER_RID_TYPE:
- if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
- old_rid_string)) {
- *rid = (uint32)atol(old_rid_string);
- }
- break;
- case GROUP_RID_TYPE:
- if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
- old_rid_string)) {
- *rid = (uint32)atol(old_rid_string);
- }
- break;
- }
-
- /* This is the core of the whole routine. If we had
- scheme-style closures, there would be a *lot* less code
- duplication... */
-
- next_rid = *rid+RID_MULTIPLIER;
- slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
-
- switch (rid_type) {
- case USER_RID_TYPE:
- /* Try to make the modification atomically by enforcing the
- old value in the delete mod. */
- smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
- next_rid_string);
- break;
-
- case GROUP_RID_TYPE:
- /* Try to make the modification atomically by enforcing the
- old value in the delete mod. */
- smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
- next_rid_string);
- break;
- }
- }
-
- if ((rc = smbldap_modify(state->smbldap_state, dn, mods)) == LDAP_SUCCESS) {
- DOM_SID dom_sid;
- DOM_SID sid;
- pstring domain_sid_string;
- int error = 0;
-
- if (!smbldap_get_single_pstring(state->smbldap_state->ldap_struct, domain_result,
- get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
- domain_sid_string)) {
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
- ldap_msgfree(domain_result);
- return ret;
- }
-
- if (!string_to_sid(&dom_sid, domain_sid_string)) {
- ldap_mods_free(mods, True);
- SAFE_FREE(dn);
- ldap_msgfree(domain_result);
- return ret;
- }
-
- ldap_mods_free(mods, True);
- mods = NULL;
- SAFE_FREE(dn);
- ldap_msgfree(domain_result);
-
- sid_copy(&sid, &dom_sid);
- sid_append_rid(&sid, *rid);
-
- /* check RID is not in use */
- if (sid_in_use(state, &sid, &error)) {
- if (error) {
- return ret;
- }
- continue;
- }
-
- return NT_STATUS_OK;
- }
-
- ld_error = NULL;
- ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(2, ("Failed to modify rid: %s\n", ld_error ? ld_error : "(NULL"));
- SAFE_FREE(ld_error);
-
- ldap_mods_free(mods, True);
- mods = NULL;
-
- SAFE_FREE(dn);
-
- ldap_msgfree(domain_result);
- domain_result = NULL;
-
- {
- /* Sleep for a random timeout */
- unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
- attempts += 1;
-
- sleeptime %= 100;
- smb_msleep(sleeptime);
- }
- }
-
- DEBUG(0, ("Failed to set new RID\n"));
- return ret;
-}
-
-
-/*****************************************************************************
- Allocate a new RID
-*****************************************************************************/
-
-static NTSTATUS ldap_allocate_rid(uint32 *rid, int rid_type)
-{
- return ldap_next_rid( &ldap_state, rid, rid_type );
-}
-
-/*****************************************************************************
- Allocate a new uid or gid
-*****************************************************************************/
-
-static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- int rc = LDAP_SERVER_DOWN;
- int count = 0;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring id_str, new_id_str;
- LDAPMod **mods = NULL;
- const char *type;
- char *dn = NULL;
- char **attr_list;
- pstring filter;
- uid_t luid, huid;
- gid_t lgid, hgid;
-
-
- type = (id_type & ID_USERID) ?
- get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) :
- get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
-
- pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
-
- attr_list = get_attr_list( idpool_attr_list );
-
- rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attr_list, 0, &result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL));
- goto out;
- }
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- if (count != 1) {
- DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL));
- goto out;
- }
-
- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
- if (!dn) {
- goto out;
- }
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, type, id_str)) {
- DEBUG(0,("ldap_allocate_id: %s attribute not found\n",
- type));
- goto out;
- }
-
- /* this must succeed or else we wouldn't have initialized */
-
- lp_idmap_uid( &luid, &huid);
- lp_idmap_gid( &lgid, &hgid);
-
- /* make sure we still have room to grow */
-
- if (id_type & ID_USERID) {
- id->uid = strtoul(id_str, NULL, 10);
- if (id->uid > huid ) {
- DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
- (unsigned long)huid));
- goto out;
- }
- }
- else {
- id->gid = strtoul(id_str, NULL, 10);
- if (id->gid > hgid ) {
- DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
- (unsigned long)hgid));
- goto out;
- }
- }
-
- pstr_sprintf(new_id_str, "%lu",
- ((id_type & ID_USERID) ? (unsigned long)id->uid :
- (unsigned long)id->gid) + 1);
-
- smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );
- smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
-
- if (mods == NULL) {
- DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n"));
- goto out;
- }
-
- rc = smbldap_modify(ldap_state.smbldap_state, dn, mods);
-
- ldap_mods_free( mods, True );
- if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
- type));
- goto out;
- }
-
- ret = NT_STATUS_OK;
-out:
- SAFE_FREE(dn);
- if (result != NULL)
- ldap_msgfree(result);
-
- return ret;
-}
-
-/*****************************************************************************
- get a sid from an id
-*****************************************************************************/
-
-static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
-{
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring sid_str;
- pstring filter;
- pstring suffix;
- const char *type;
- int rc;
- int count;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- char **attr_list;
-
- if ( id_type & ID_USERID )
- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
- else
- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
-
- pstrcpy( suffix, lp_ldap_idmap_suffix() );
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
- LDAP_OBJ_IDMAP_ENTRY, type,
- ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid));
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
- ldap_err2string(rc) ));
- goto out;
- }
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
- type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid)));
- goto out;
- }
-
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- if ( !smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) )
- goto out;
-
- if (!string_to_sid(sid, sid_str))
- goto out;
-
- ret = NT_STATUS_OK;
-out:
- free_attr_list( attr_list );
-
- if (result)
- ldap_msgfree(result);
-
- return ret;
-}
-
-/***********************************************************************
- Get an id from a sid
-***********************************************************************/
-
-static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
-{
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- pstring sid_str;
- pstring filter;
- pstring id_str;
- const char *suffix;
- const char *type;
- int rc;
- int count;
- char **attr_list;
- char *dn = NULL;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- sid_to_string(sid_str, sid);
-
- DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str,
- (*id_type & ID_GROUPID ? "group" : "user") ));
-
- suffix = lp_ldap_idmap_suffix();
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
-
- if ( *id_type & ID_GROUPID )
- type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER );
- else
- type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER );
-
- /* do the search and check for errors */
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
- ldap_err2string(rc) ));
- goto out;
- }
-
- /* check for the number of entries returned */
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if ( count > 1 ) {
- DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
- filter, count));
- goto out;
- }
-
- /* try to allocate a new id if we still haven't found one */
-
- if ( !count ) {
- int i;
-
- if (*id_type & ID_QUERY_ONLY) {
- DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n"));
- goto out;
- }
-
- DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
-
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
- ret = ldap_allocate_id(id, *id_type);
- if ( NT_STATUS_IS_OK(ret) )
- break;
- }
-
- if ( !NT_STATUS_IS_OK(ret) ) {
- DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
- goto out;
- }
-
- DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
- (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
-
- ret = ldap_set_mapping(sid, *id, *id_type);
-
- /* all done */
-
- goto out;
- }
-
- DEBUG(10,("ldap_get_id_from_sid: success\n"));
-
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
- if (!dn)
- goto out;
-
- DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type));
-
- if ( smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) {
- if ( (*id_type & ID_USERID) )
- id->uid = strtoul(id_str, NULL, 10);
- else
- id->gid = strtoul(id_str, NULL, 10);
-
- ret = NT_STATUS_OK;
- goto out;
- }
-
-out:
- free_attr_list( attr_list );
- if (result)
- ldap_msgfree(result);
- SAFE_FREE(dn);
-
- return ret;
-}
-
-/**********************************************************************
- Verify the sambaUnixIdPool entry in the directiry.
-**********************************************************************/
-
-static NTSTATUS verify_idpool( void )
-{
- fstring filter;
- int rc;
- char **attr_list;
- LDAPMessage *result = NULL;
- LDAPMod **mods = NULL;
- int count;
-
- fstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_IDPOOL );
-
- attr_list = get_attr_list( idpool_attr_list );
- rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result);
- free_attr_list ( attr_list );
-
- if (rc != LDAP_SUCCESS)
- return NT_STATUS_UNSUCCESSFUL;
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- ldap_msgfree(result);
-
- if ( count > 1 ) {
- DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
- filter, lp_ldap_idmap_suffix() ));
- return NT_STATUS_UNSUCCESSFUL;
- }
- else if (count == 0) {
- uid_t luid, huid;
- gid_t lgid, hgid;
- fstring uid_str, gid_str;
-
- if ( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid( &lgid, &hgid ) ) {
- DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fstr_sprintf( uid_str, "%lu", (unsigned long)luid );
- fstr_sprintf( gid_str, "%lu", (unsigned long)lgid );
-
- smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER), uid_str );
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER), gid_str );
-
- rc = smbldap_modify(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), mods);
- }
-
- return ( rc==LDAP_SUCCESS ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
-}
-
-/*****************************************************************************
- Initialise idmap database.
-*****************************************************************************/
-
-static NTSTATUS ldap_idmap_init( char *params )
-{
- NTSTATUS nt_status;
-
- ldap_state.mem_ctx = talloc_init("idmap_ldap");
- if (!ldap_state.mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- /* assume location is the only parameter */
- if (!NT_STATUS_IS_OK(nt_status =
- smbldap_init(ldap_state.mem_ctx, params,
- &ldap_state.smbldap_state))) {
- talloc_destroy(ldap_state.mem_ctx);
- return nt_status;
- }
-
- /* see if the idmap suffix and sub entries exists */
-
- nt_status = verify_idpool();
- if ( !NT_STATUS_IS_OK(nt_status) )
- return nt_status;
-
- return NT_STATUS_OK;
-}
-
-/*****************************************************************************
- End the LDAP session
-*****************************************************************************/
-
-static NTSTATUS ldap_idmap_close(void)
-{
-
- smbldap_free_struct(&(ldap_state).smbldap_state);
- talloc_destroy(ldap_state.mem_ctx);
-
- DEBUG(5,("The connection to the LDAP server was closed\n"));
- /* maybe free the results here --metze */
-
- return NT_STATUS_OK;
-}
-
-
-/* This function doesn't make as much sense in an LDAP world since the calling
- node doesn't really control the ID ranges */
-static void ldap_idmap_status(void)
-{
- DEBUG(0, ("LDAP IDMAP Status not available\n"));
-}
-
-static struct idmap_methods ldap_methods = {
- ldap_idmap_init,
- ldap_allocate_rid,
- ldap_allocate_id,
- ldap_get_sid_from_id,
- ldap_get_id_from_sid,
- ldap_set_mapping,
- ldap_idmap_close,
- ldap_idmap_status
-
-};
-
-NTSTATUS idmap_ldap_init(void)
-{
- return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap", &ldap_methods);
-}
diff --git a/source/sam/idmap_tdb.c b/source/sam/idmap_tdb.c
deleted file mode 100644
index 8ab8ec84770..00000000000
--- a/source/sam/idmap_tdb.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- idmap TDB backend
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
- Copyright (C) Simo Sorce 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-/* High water mark keys */
-#define HWM_GROUP "GROUP HWM"
-#define HWM_USER "USER HWM"
-
-/* idmap version determines auto-conversion */
-#define IDMAP_VERSION 2
-
-/* Globals */
-static TDB_CONTEXT *idmap_tdb;
-
-static struct idmap_state {
-
- /* User and group id pool */
-
- uid_t uid_low, uid_high; /* Range of uids to allocate */
- gid_t gid_low, gid_high; /* Range of gids to allocate */
-} idmap_state;
-
-/**********************************************************************
- allocate a new RID; We don't care if is a user or group
-**********************************************************************/
-
-static NTSTATUS db_allocate_rid(uint32 *rid, int rid_type)
-{
- uint32 lowrid, highrid;
- uint32 tmp_rid;
-
- /* can't handle group rids right now. This is such a mess.... */
-
- if ( rid_type == GROUP_RID_TYPE )
- return NT_STATUS_UNSUCCESSFUL;
-
- /* cannot fail since idmap is only called winbindd */
-
- get_free_rid_range( &lowrid, &highrid );
-
- tmp_rid = lowrid;
-
- if ( !tdb_change_uint32_atomic(idmap_tdb, "RID_COUNTER", &tmp_rid, RID_MULTIPLIER) ) {
- DEBUG(3,("db_allocate_rid: Failed to locate next rid record in idmap db\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if ( tmp_rid > highrid ) {
- DEBUG(0, ("db_allocate_rid: no RIDs available!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- *rid = tmp_rid;
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Allocate either a user or group id from the pool
-**********************************************************************/
-
-static NTSTATUS db_allocate_id(unid_t *id, int id_type)
-{
- BOOL ret;
- int hwm;
-
- if (!id)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* Get current high water mark */
- switch (id_type & ID_TYPEMASK) {
- case ID_USERID:
-
- if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
- /* check it is in the range */
- if (hwm > idmap_state.uid_high) {
- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n",
- (unsigned long)idmap_state.uid_high));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* fetch a new id and increment it */
- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, (unsigned int *)&hwm, 1);
- if (!ret) {
- DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* recheck it is in the range */
- if (hwm > idmap_state.uid_high) {
- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n",
- (unsigned long)idmap_state.uid_high));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- (*id).uid = hwm;
- DEBUG(10,("db_allocate_id: ID_USERID (*id).uid = %d\n", (unsigned int)hwm));
-
- break;
- case ID_GROUPID:
- if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
- /* check it is in the range */
- if (hwm > idmap_state.gid_high) {
- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n",
- (unsigned long)idmap_state.gid_high));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* fetch a new id and increment it */
- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, (unsigned int *)&hwm, 1);
-
- if (!ret) {
- DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* recheck it is in the range */
- if (hwm > idmap_state.gid_high) {
- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n",
- (unsigned long)idmap_state.gid_high));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- (*id).gid = hwm;
- DEBUG(10,("db_allocate_id: ID_GROUPID (*id).gid = %d\n", (unsigned int)hwm));
-
- break;
- default:
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return NT_STATUS_OK;
-}
-
-/* Get a sid from an id */
-static NTSTATUS internal_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
-{
- TDB_DATA key, data;
- fstring keystr;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- switch (id_type & ID_TYPEMASK) {
- case ID_USERID:
- slprintf(keystr, sizeof(keystr), "UID %lu", (unsigned long)id.uid);
- break;
- case ID_GROUPID:
- slprintf(keystr, sizeof(keystr), "GID %lu", (unsigned long)id.gid);
- break;
- default:
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- DEBUG(10,("internal_get_sid_from_id: fetching record %s\n", keystr ));
-
- data = tdb_fetch(idmap_tdb, key);
-
- if (data.dptr) {
- if (string_to_sid(sid, data.dptr)) {
- DEBUG(10,("internal_get_sid_from_id: fetching record %s -> %s\n", keystr, data.dptr ));
- ret = NT_STATUS_OK;
- }
- SAFE_FREE(data.dptr);
- }
-
- return ret;
-}
-
-/* Error codes for get_id_from_sid */
-enum getidfromsiderr { GET_ID_FROM_SID_OK = 0, GET_ID_FROM_SID_NOTFOUND, GET_ID_FROM_SID_WRONG_TYPE, GET_ID_FROM_SID_ERR };
-
-static enum getidfromsiderr internal_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
-{
- enum getidfromsiderr ret = GET_ID_FROM_SID_ERR;
- fstring keystr;
- TDB_DATA key, data;
- int type = *id_type & ID_TYPEMASK;
-
- /* Check if sid is present in database */
- sid_to_string(keystr, sid);
-
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- DEBUG(10,("internal_get_id_from_sid: fetching record %s of type 0x%x\n", keystr, type ));
-
- data = tdb_fetch(idmap_tdb, key);
- if (!data.dptr) {
- DEBUG(10,("internal_get_id_from_sid: record %s not found\n", keystr ));
- return GET_ID_FROM_SID_NOTFOUND;
- } else {
- DEBUG(10,("internal_get_id_from_sid: record %s -> %s\n", keystr, data.dptr ));
- }
-
- if (type == ID_EMPTY || type == ID_USERID) {
- fstring scanstr;
- /* Parse and return existing uid */
- fstrcpy(scanstr, "UID %d");
-
- if (sscanf(data.dptr, scanstr, &((*id).uid)) == 1) {
- /* uid ok? */
- if (type == ID_EMPTY) {
- *id_type = ID_USERID;
- }
- DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n",
- (type == ID_EMPTY) ? "ID_EMPTY" : "ID_USERID",
- keystr, data.dptr ));
- ret = GET_ID_FROM_SID_OK;
- } else {
- ret = GET_ID_FROM_SID_WRONG_TYPE;
- }
- }
-
- if ((ret != GET_ID_FROM_SID_OK) && (type == ID_EMPTY || type == ID_GROUPID)) {
- fstring scanstr;
- /* Parse and return existing gid */
- fstrcpy(scanstr, "GID %d");
-
- if (sscanf(data.dptr, scanstr, &((*id).gid)) == 1) {
- /* gid ok? */
- if (type == ID_EMPTY) {
- *id_type = ID_GROUPID;
- }
- DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n",
- (type == ID_EMPTY) ? "ID_EMPTY" : "ID_GROUPID",
- keystr, data.dptr ));
- ret = GET_ID_FROM_SID_OK;
- } else {
- ret = GET_ID_FROM_SID_WRONG_TYPE;
- }
- }
-
- SAFE_FREE(data.dptr);
-
- return ret;
-}
-
-/* Get a sid from an id */
-static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type_in)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- enum getidfromsiderr iderr;
- int id_type = id_type_in & ID_TYPEMASK;
- unid_t id_tmp = id;
- int id_type_tmp = id_type;
-
- DEBUG(10,("db_get_sid_from_id: id_type_in = 0x%x\n", id_type_in));
-
- ret = internal_get_sid_from_id(sid, id, id_type);
- if (!NT_STATUS_IS_OK(ret)) {
- return ret;
- }
-
- iderr = internal_get_id_from_sid(&id_tmp, &id_type_tmp, sid);
- if (iderr != GET_ID_FROM_SID_OK) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (id_type_tmp != id_type) {
- return NT_STATUS_UNSUCCESSFUL;
- } else if (id_type == ID_USERID) {
- if (id_tmp.uid != id.uid) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else if (id_type == ID_GROUPID) {
- if (id_tmp.gid != id.gid) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
- return NT_STATUS_UNSUCCESSFUL;
- }
- return ret;
-}
-/* Get an id from a sid */
-static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- enum getidfromsiderr iderr;
-
- DEBUG(10,("db_get_id_from_sid\n"));
-
- if (!sid || !id || !id_type)
- return NT_STATUS_INVALID_PARAMETER;
-
- iderr = internal_get_id_from_sid(id, id_type, sid);
- if (iderr == GET_ID_FROM_SID_OK) {
- DOM_SID sid_tmp;
- ret = internal_get_sid_from_id(&sid_tmp, *id, *id_type);
- if (NT_STATUS_IS_OK(ret)) {
- if (!sid_equal(&sid_tmp, sid)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- } else if (iderr == GET_ID_FROM_SID_WRONG_TYPE) {
- /* We found a record but not the type we wanted.
- * This is an error, not an opportunity to overwrite...
- * JRA.
- */
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!(*id_type & ID_QUERY_ONLY) && (iderr != GET_ID_FROM_SID_OK) &&
- (((*id_type & ID_TYPEMASK) == ID_USERID)
- || (*id_type & ID_TYPEMASK) == ID_GROUPID)) {
- TDB_DATA sid_data;
- TDB_DATA ugid_data;
- fstring sid_string;
-
- sid_to_string(sid_string, sid);
-
- sid_data.dptr = sid_string;
- sid_data.dsize = strlen(sid_string)+1;
-
- /* Lock the record for this SID. */
- if (tdb_chainlock(idmap_tdb, sid_data) != 0) {
- DEBUG(10,("db_get_id_from_sid: failed to lock record %s. Error %s\n",
- sid_string, tdb_errorstr(idmap_tdb) ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- do {
- fstring ugid_str;
-
- /* Allocate a new id for this sid */
- ret = db_allocate_id(id, *id_type);
- if (!NT_STATUS_IS_OK(ret))
- break;
-
- /* Store the UID side */
- /* Store new id */
- if (*id_type & ID_USERID) {
- slprintf(ugid_str, sizeof(ugid_str), "UID %lu",
- (unsigned long)((*id).uid));
- } else {
- slprintf(ugid_str, sizeof(ugid_str), "GID %lu",
- (unsigned long)((*id).gid));
- }
-
- ugid_data.dptr = ugid_str;
- ugid_data.dsize = strlen(ugid_str) + 1;
-
- DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",
- ugid_data.dptr, sid_data.dptr ));
-
- if (tdb_store(idmap_tdb, ugid_data, sid_data, TDB_INSERT) != -1) {
- ret = NT_STATUS_OK;
- break;
- }
- if (tdb_error(idmap_tdb) != TDB_ERR_EXISTS)
- DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));
- ret = NT_STATUS_UNSUCCESSFUL;
- } while (tdb_error(idmap_tdb) == TDB_ERR_EXISTS);
-
- if (NT_STATUS_IS_OK(ret)) {
-
- DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",
- sid_data.dptr, ugid_data.dptr ));
-
- if (tdb_store(idmap_tdb, sid_data, ugid_data, TDB_REPLACE) == -1) {
- DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));
- /* TODO: print tdb error !! */
- tdb_chainunlock(idmap_tdb, sid_data);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- tdb_chainunlock(idmap_tdb, sid_data);
- }
-
- return ret;
-}
-
-static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
-{
- TDB_DATA ksid, kid, data;
- fstring ksidstr;
- fstring kidstr;
-
- DEBUG(10,("db_set_mapping: id_type = 0x%x\n", id_type));
-
- if (!sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- sid_to_string(ksidstr, sid);
-
- ksid.dptr = ksidstr;
- ksid.dsize = strlen(ksidstr) + 1;
-
- if (id_type & ID_USERID) {
- slprintf(kidstr, sizeof(kidstr), "UID %lu", (unsigned long)id.uid);
- } else if (id_type & ID_GROUPID) {
- slprintf(kidstr, sizeof(kidstr), "GID %lu", (unsigned long)id.gid);
- } else {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- kid.dptr = kidstr;
- kid.dsize = strlen(kidstr) + 1;
-
- /* *DELETE* prevoius mappings if any.
- * This is done both SID and [U|G]ID passed in */
-
- /* Lock the record for this SID. */
- if (tdb_chainlock(idmap_tdb, ksid) != 0) {
- DEBUG(10,("db_set_mapping: failed to lock record %s. Error %s\n",
- ksidstr, tdb_errorstr(idmap_tdb) ));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("db_set_mapping: fetching %s\n", ksid.dptr));
-
- data = tdb_fetch(idmap_tdb, ksid);
- if (data.dptr) {
- DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, ksid.dptr ));
- tdb_delete(idmap_tdb, data);
- tdb_delete(idmap_tdb, ksid);
- SAFE_FREE(data.dptr);
- }
- data = tdb_fetch(idmap_tdb, kid);
- if (data.dptr) {
- DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, kid.dptr ));
- tdb_delete(idmap_tdb, data);
- tdb_delete(idmap_tdb, kid);
- SAFE_FREE(data.dptr);
- }
-
- if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) {
- DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb)));
- tdb_chainunlock(idmap_tdb, ksid);
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (tdb_store(idmap_tdb, kid, ksid, TDB_INSERT) == -1) {
- DEBUG(0, ("idb_set_mapping: tdb_store 2 error: %s\n", tdb_errorstr(idmap_tdb)));
- tdb_chainunlock(idmap_tdb, ksid);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- tdb_chainunlock(idmap_tdb, ksid);
- DEBUG(10,("db_set_mapping: stored %s -> %s and %s -> %s\n", ksid.dptr, kid.dptr, kid.dptr, ksid.dptr ));
- return NT_STATUS_OK;
-}
-
-/*****************************************************************************
- Initialise idmap database.
-*****************************************************************************/
-
-static NTSTATUS db_idmap_init( char *params )
-{
- SMB_STRUCT_STAT stbuf;
- char *tdbfile = NULL;
- int32 version;
- BOOL tdb_is_new = False;
-
- /* use the old database if present */
- tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
- if (!tdbfile) {
- DEBUG(0, ("idmap_init: out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!file_exist(tdbfile, &stbuf)) {
- tdb_is_new = True;
- }
-
- DEBUG(10,("db_idmap_init: Opening tdbfile %s\n", tdbfile ));
-
- /* Open idmap repository */
- if (!(idmap_tdb = tdb_open_log(tdbfile, 0,
- TDB_DEFAULT, O_RDWR | O_CREAT,
- 0644))) {
- DEBUG(0, ("idmap_init: Unable to open idmap database\n"));
- SAFE_FREE(tdbfile);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- SAFE_FREE(tdbfile);
-
- if (tdb_is_new) {
- /* the file didn't existed before opening it, let's
- * store idmap version as nobody else yet opened and
- * stored it. I do not like this method but didn't
- * found a way to understand if an opened tdb have
- * been just created or not --- SSS */
- tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION);
- }
-
- /* check against earlier versions */
- version = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
- if (version != IDMAP_VERSION) {
- DEBUG(0, ("idmap_init: Unable to open idmap database, it's in an old format!\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
- /* Create high water marks for group and user id */
- if (!lp_idmap_uid(&idmap_state.uid_low, &idmap_state.uid_high)) {
- DEBUG(1, ("idmap uid range missing or invalid\n"));
- DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
- } else {
- if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) {
- if (tdb_store_int32(idmap_tdb, HWM_USER, idmap_state.uid_low) == -1) {
- DEBUG(0, ("idmap_init: Unable to initialise user hwm in idmap database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
- }
- }
-
- if (!lp_idmap_gid(&idmap_state.gid_low, &idmap_state.gid_high)) {
- DEBUG(1, ("idmap gid range missing or invalid\n"));
- DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
- } else {
- if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) {
- if (tdb_store_int32(idmap_tdb, HWM_GROUP, idmap_state.gid_low) == -1) {
- DEBUG(0, ("idmap_init: Unable to initialise group hwm in idmap database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/* Close the tdb */
-static NTSTATUS db_idmap_close(void)
-{
- if (idmap_tdb) {
- if (tdb_close(idmap_tdb) == 0) {
- return NT_STATUS_OK;
- } else {
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- return NT_STATUS_OK;
-}
-
-
-/* Dump status information to log file. Display different stuff based on
- the debug level:
-
- Debug Level Information Displayed
- =================================================================
- 0 Percentage of [ug]id range allocated
- 0 High water marks (next allocated ids)
-*/
-
-#define DUMP_INFO 0
-
-static void db_idmap_status(void)
-{
- int user_hwm, group_hwm;
-
- DEBUG(0, ("winbindd idmap status:\n"));
-
- /* Get current high water marks */
-
- if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {
- DEBUG(DUMP_INFO,
- ("\tCould not get userid high water mark!\n"));
- }
-
- if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {
- DEBUG(DUMP_INFO,
- ("\tCould not get groupid high water mark!\n"));
- }
-
- /* Display next ids to allocate */
-
- if (user_hwm != -1) {
- DEBUG(DUMP_INFO,
- ("\tNext userid to allocate is %d\n", user_hwm));
- }
-
- if (group_hwm != -1) {
- DEBUG(DUMP_INFO,
- ("\tNext groupid to allocate is %d\n", group_hwm));
- }
-
- /* Display percentage of id range already allocated. */
-
- if (user_hwm != -1) {
- int num_users = user_hwm - idmap_state.uid_low;
- int total_users =
- idmap_state.uid_high - idmap_state.uid_low;
-
- DEBUG(DUMP_INFO,
- ("\tUser id range is %d%% full (%d of %d)\n",
- num_users * 100 / total_users, num_users,
- total_users));
- }
-
- if (group_hwm != -1) {
- int num_groups = group_hwm - idmap_state.gid_low;
- int total_groups =
- idmap_state.gid_high - idmap_state.gid_low;
-
- DEBUG(DUMP_INFO,
- ("\tGroup id range is %d%% full (%d of %d)\n",
- num_groups * 100 / total_groups, num_groups,
- total_groups));
- }
-
- /* Display complete mapping of users and groups to rids */
-}
-
-/**********************************************************************
- Return the TDB_CONTEXT* for winbindd_idmap. I **really** feel
- dirty doing this, but not so dirty that I want to create another
- tdb
-***********************************************************************/
-
-TDB_CONTEXT *idmap_tdb_handle( void )
-{
- if ( idmap_tdb )
- return idmap_tdb;
-
- /* go ahead an open it; db_idmap_init() doesn't use any params
- right now */
-
- db_idmap_init( NULL );
- if ( idmap_tdb )
- return idmap_tdb;
-
- return NULL;
-}
-
-static struct idmap_methods db_methods = {
-
- db_idmap_init,
- db_allocate_rid,
- db_allocate_id,
- db_get_sid_from_id,
- db_get_id_from_sid,
- db_set_mapping,
- db_idmap_close,
- db_idmap_status
-
-};
-
-NTSTATUS idmap_tdb_init(void)
-{
- return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods);
-}
diff --git a/source/sam/idmap_util.c b/source/sam/idmap_util.c
deleted file mode 100644
index f28e11cde74..00000000000
--- a/source/sam/idmap_util.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ID Mapping
- Copyright (C) Simo Sorce 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-#if 0 /* NOT USED */
-
-/**********************************************************************
- Get the free RID base if idmap is configured, otherwise return 0
-**********************************************************************/
-
-uint32 idmap_get_free_rid_base(void)
-{
- uint32 low, high;
- if (idmap_get_free_rid_range(&low, &high)) {
- return low;
- }
- return 0;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-BOOL idmap_check_ugid_is_in_free_range(uint32 id)
-{
- uint32 low, high;
-
- if (!idmap_get_free_ugid_range(&low, &high)) {
- return False;
- }
- if (id < low || id > high) {
- return False;
- }
- return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-BOOL idmap_check_rid_is_in_free_range(uint32 rid)
-{
- uint32 low, high;
-
- if (!idmap_get_free_rid_range(&low, &high)) {
- return False;
- }
- if (rid < algorithmic_rid_base()) {
- return True;
- }
-
- if (rid < low || rid > high) {
- return False;
- }
-
- return True;
-}
-
-/**********************************************************************
- if it is a foreign SID or if the SID is in the free range, return true
-**********************************************************************/
-
-BOOL idmap_check_sid_is_in_free_range(const DOM_SID *sid)
-{
- if (sid_compare_domain(get_global_sam_sid(), sid) == 0) {
-
- uint32 rid;
-
- if (sid_peek_rid(sid, &rid)) {
- return idmap_check_rid_is_in_free_range(rid);
- }
-
- return False;
- }
-
- return True;
-}
-
-#endif /* NOT USED */
-
-/*****************************************************************
- Returns SID pointer.
-*****************************************************************/
-
-NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
-{
- unid_t id;
- int flags;
-
- DEBUG(10,("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid));
-
- flags = ID_USERID;
- id.uid = uid;
-
- return idmap_get_sid_from_id(sid, id, flags);
-}
-
-/*****************************************************************
- Group mapping is used for gids that maps to Wellknown SIDs
- Returns SID pointer.
-*****************************************************************/
-
-NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
-{
- unid_t id;
- int flags;
-
- DEBUG(10,("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid));
-
- flags = ID_GROUPID;
-#if 0 /* JERRY */
- if (!idmap_check_ugid_is_in_free_range(gid)) {
- flags |= ID_QUERY_ONLY;
- }
-#endif
- id.gid = gid;
- return idmap_get_sid_from_id(sid, id, flags);
-}
-
-/*****************************************************************
- if it is a foreign sid or it is in idmap rid range check idmap,
- otherwise falls back to the legacy algorithmic mapping.
- Returns True if this name is a user sid and the conversion
- was done correctly, False if not.
-*****************************************************************/
-
-NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- unid_t id;
-
- DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_static(sid)));
-
- flags |= ID_USERID;
-
- ret = idmap_get_id_from_sid(&id, (int *)&flags, sid);
-
- if ( NT_STATUS_IS_OK(ret) ) {
- DEBUG(10,("idmap_sid_to_uid: uid = [%lu]\n", (unsigned long)id.uid));
- *uid = id.uid;
- }
-
- return ret;
-
-}
-
-/*****************************************************************
- *THE CANONICAL* convert SID to gid function.
- if it is a foreign sid or it is in idmap rid range check idmap,
- otherwise falls back to the legacy algorithmic mapping.
- Group mapping is used for gids that maps to Wellknown SIDs
- Returns True if this name is a user sid and the conversion
- was done correctly, False if not.
-*****************************************************************/
-
-NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- unid_t id;
-
- DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid)));
-
- flags |= ID_GROUPID;
-
- ret = idmap_get_id_from_sid(&id, (int *)&flags, sid);
-
- if ( NT_STATUS_IS_OK(ret) )
- {
- DEBUG(10,("idmap_sid_to_gid: gid = [%lu]\n", (unsigned long)id.gid));
- *gid = id.gid;
- }
-
- return ret;
-}
-
-
-/***************************************************************************
- Check first, call set_mapping if it doesn't already exist.
-***************************************************************************/
-
-static NTSTATUS wellknown_id_init(DOM_SID *sid, unid_t id, int flags)
-{
- unid_t storedid;
- int qflags = flags | ID_QUERY_ONLY;
-
- if (!NT_STATUS_IS_OK(idmap_get_id_from_sid(&storedid, &qflags, sid))) {
- return idmap_set_mapping(sid, id, flags);
- } else {
- if (flags == ID_USERID && id.uid != storedid.uid) {
- DEBUG(0,("wellknown_id_init: WARNING ! Stored uid %u for SID %s is not the same as the requested uid %u\n",
- (unsigned int)storedid.uid, sid_string_static(sid), (unsigned int)id.uid ));
- DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
- return idmap_set_mapping(sid, id, flags);
- } else if (flags == ID_GROUPID && id.gid != storedid.gid) {
- DEBUG(0,("wellknown_id_init: WARNING ! Stored gid %u for SID %s is not the same as the requested gid %u\n",
- (unsigned int)storedid.gid, sid_string_static(sid), (unsigned int)id.gid ));
- DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
- return idmap_set_mapping(sid, id, flags);
- }
- }
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Initialize idmap withWellknown SIDs like Guest, that are necessary
- to make samba run properly.
-***************************************************************************/
-
-BOOL idmap_init_wellknown_sids(void)
-{
- const char *guest_account = lp_guestaccount();
- struct passwd *pass;
- GROUP_MAP *map=NULL;
- int num_entries=0;
- DOM_SID sid;
- unid_t id;
- fstring sid_string;
-
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return False;
- }
-
- pass = getpwnam_alloc(guest_account);
- if (!pass) {
- return False;
- }
-
- /* Fill in the SID for the guest account. */
- id.uid = pass->pw_uid;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_USER_RID_GUEST);
-
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
- DEBUG(0, ("Failed to setup UID mapping for GUEST (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.uid));
- passwd_free(&pass);
- return False;
- }
-
- /* check if DOMAIN_GROUP_RID_GUESTS SID is set, if not store the
- * guest account gid as mapping */
- id.gid = pass->pw_gid;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_GROUP_RID_GUESTS);
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_GROUPID))) {
- DEBUG(0, ("Failed to setup GID mapping for Group DOMAIN GUESTS (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.gid));
- passwd_free(&pass);
- return False;
- }
-
- passwd_free(&pass);
- /* now fill in group mappings */
- if(pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) {
- int i;
-
- for (i = 0; i < num_entries; i++) {
- id.gid = map[i].gid;
- wellknown_id_init(&map[i].sid, id, ID_GROUPID);
- }
- SAFE_FREE(map);
- }
-
- /* Fill in the SID for the administrator account. */
- id.uid = 0;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_USER_RID_ADMIN);
-
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
- DEBUG(0, ("Failed to setup UID mapping for ADMINISTRATOR (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.uid));
- return False;
- }
-
- return True;
-}
diff --git a/source/sam/interface.c b/source/sam/interface.c
deleted file mode 100644
index 51ae561999c..00000000000
--- a/source/sam/interface.c
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password and authentication handling
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Jelmer Vernooij 2002
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Kai Krüger 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_SAM
-
-extern DOM_SID global_sid_Builtin;
-
-/** List of various built-in sam modules */
-
-const struct sam_init_function_entry builtin_sam_init_functions[] = {
- { "plugin", sam_init_plugin },
-#ifdef HAVE_LDAP
- { "ads", sam_init_ads },
-#endif
- { "skel", sam_init_skel },
- { NULL, NULL}
-};
-
-
-static NTSTATUS sam_get_methods_by_sid(const SAM_CONTEXT *context, SAM_METHODS **sam_method, const DOM_SID *domainsid)
-{
- SAM_METHODS *tmp_methods;
-
- DEBUG(5,("sam_get_methods_by_sid: %d\n", __LINE__));
-
- /* invalid sam_context specified */
- SAM_ASSERT(context && context->methods);
-
- tmp_methods = context->methods;
-
- while (tmp_methods) {
- if (sid_equal(domainsid, &(tmp_methods->domain_sid)))
- {
- (*sam_method) = tmp_methods;
- return NT_STATUS_OK;
- }
- tmp_methods = tmp_methods->next;
- }
-
- DEBUG(3,("sam_get_methods_by_sid: There is no backend specified for domain %s\n", sid_string_static(domainsid)));
-
- return NT_STATUS_NO_SUCH_DOMAIN;
-}
-
-static NTSTATUS sam_get_methods_by_name(const SAM_CONTEXT *context, SAM_METHODS **sam_method, const char *domainname)
-{
- SAM_METHODS *tmp_methods;
-
- DEBUG(5,("sam_get_methods_by_name: %d\n", __LINE__));
-
- /* invalid sam_context specified */
- SAM_ASSERT(context && context->methods);
-
- tmp_methods = context->methods;
-
- while (tmp_methods) {
- if (strequal(domainname, tmp_methods->domain_name))
- {
- (*sam_method) = tmp_methods;
- return NT_STATUS_OK;
- }
- tmp_methods = tmp_methods->next;
- }
-
- DEBUG(3,("sam_get_methods_by_sid: There is no backend specified for domain %s\n", domainname));
-
- return NT_STATUS_NO_SUCH_DOMAIN;
-}
-
-static NTSTATUS make_sam_methods(TALLOC_CTX *mem_ctx, SAM_METHODS **methods)
-{
- *methods = talloc(mem_ctx, sizeof(SAM_METHODS));
-
- if (!*methods) {
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*methods);
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************
- Free and cleanup a sam context, any associated data and anything
- that the attached modules might have associated.
- *******************************************************************/
-
-void free_sam_context(SAM_CONTEXT **context)
-{
- SAM_METHODS *sam_selected = (*context)->methods;
-
- while (sam_selected) {
- if (sam_selected->free_private_data) {
- sam_selected->free_private_data(&(sam_selected->private_data));
- }
- sam_selected = sam_selected->next;
- }
-
- talloc_destroy((*context)->mem_ctx);
- *context = NULL;
-}
-
-/******************************************************************
- Make a backend_entry from scratch
- *******************************************************************/
-
-static NTSTATUS make_backend_entry(SAM_BACKEND_ENTRY *backend_entry, char *sam_backend_string)
-{
- char *tmp = NULL;
- char *tmp_string = sam_backend_string;
-
- DEBUG(5,("make_backend_entry: %d\n", __LINE__));
-
- SAM_ASSERT(sam_backend_string && backend_entry);
-
- backend_entry->module_name = sam_backend_string;
-
- DEBUG(5,("makeing backend_entry for %s\n", backend_entry->module_name));
-
- if ((tmp = strrchr(tmp_string, '|')) != NULL) {
- DEBUGADD(20,("a domain name has been specified\n"));
- *tmp = 0;
- backend_entry->domain_name = smb_xstrdup(tmp + 1);
- tmp_string = tmp + 1;
- }
-
- if ((tmp = strchr(tmp_string, ':')) != NULL) {
- DEBUG(20,("options for the backend have been specified\n"));
- *tmp = 0;
- backend_entry->module_params = smb_xstrdup(tmp + 1);
- tmp_string = tmp + 1;
- }
-
- if (backend_entry->domain_name == NULL) {
- DEBUG(10,("make_backend_entry: no domain was specified for sam module %s. Using default domain %s\n",
- backend_entry->module_name, lp_workgroup()));
- backend_entry->domain_name = smb_xstrdup(lp_workgroup());
- }
-
- if ((backend_entry->domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID))) == NULL) {
- DEBUG(0,("make_backend_entry: failed to malloc domain_sid\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- DEBUG(10,("looking up sid for domain %s\n", backend_entry->domain_name));
-
- if (!secrets_fetch_domain_sid(backend_entry->domain_name, backend_entry->domain_sid)) {
- DEBUG(2,("make_backend_entry: There is no SID stored for domain %s. Creating a new one.\n",
- backend_entry->domain_name));
- DEBUG(0, ("FIXME in %s:%d\n", __FILE__, __LINE__));
- ZERO_STRUCTP(backend_entry->domain_sid);
- }
-
- DEBUG(5,("make_backend_entry: module name: %s, module parameters: %s, domain name: %s, domain sid: %s\n",
- backend_entry->module_name, backend_entry->module_params, backend_entry->domain_name, sid_string_static(backend_entry->domain_sid)));
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************
- create sam_methods struct based on sam_backend_entry
- *****************************************************************/
-
-static NTSTATUS make_sam_methods_backend_entry(SAM_CONTEXT *context, SAM_METHODS **methods_ptr, SAM_BACKEND_ENTRY *backend_entry)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- SAM_METHODS *methods;
- int i;
-
- DEBUG(5,("make_sam_methods_backend_entry: %d\n", __LINE__));
-
- if (!NT_STATUS_IS_OK(nt_status = make_sam_methods(context->mem_ctx, methods_ptr))) {
- return nt_status;
- }
-
- methods = *methods_ptr;
- methods->backendname = talloc_strdup(context->mem_ctx, backend_entry->module_name);
- methods->domain_name = talloc_strdup(context->mem_ctx, backend_entry->domain_name);
- sid_copy(&methods->domain_sid, backend_entry->domain_sid);
- methods->parent = context;
-
- DEBUG(5,("Attempting to find sam backend %s\n", backend_entry->module_name));
- for (i = 0; builtin_sam_init_functions[i].module_name; i++)
- {
- if (strequal(builtin_sam_init_functions[i].module_name, backend_entry->module_name))
- {
- DEBUG(5,("Found sam backend %s (at pos %d)\n", backend_entry->module_name, i));
- DEBUGADD(5,("initialising it with options=%s for domain %s\n", backend_entry->module_params, sid_string_static(backend_entry->domain_sid)));
- nt_status = builtin_sam_init_functions[i].init(methods, backend_entry->module_params);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5,("sam backend %s has a valid init\n", backend_entry->module_name));
- } else {
- DEBUG(2,("sam backend %s did not correctly init (error was %s)\n",
- backend_entry->module_name, nt_errstr(nt_status)));
- }
- return nt_status;
- }
- }
-
- DEBUG(2,("could not find backend %s\n", backend_entry->module_name));
-
- return NT_STATUS_INVALID_PARAMETER;
-}
-
-static NTSTATUS sam_context_check_default_backends(SAM_CONTEXT *context)
-{
- SAM_BACKEND_ENTRY entry;
- DOM_SID *global_sam_sid = get_global_sam_sid(); /* lp_workgroup doesn't play nicely with multiple domains */
- SAM_METHODS *methods, *tmpmethods;
- NTSTATUS ntstatus;
-
- DEBUG(5,("sam_context_check_default_backends: %d\n", __LINE__));
-
- /* Make sure domain lp_workgroup() is available */
-
- ntstatus = sam_get_methods_by_sid(context, &methods, &global_sid_Builtin);
-
- if (NT_STATUS_EQUAL(ntstatus, NT_STATUS_NO_SUCH_DOMAIN)) {
- DEBUG(4,("There was no backend specified for domain %s(%s); using %s\n",
- lp_workgroup(), sid_string_static(global_sam_sid), SAM_DEFAULT_BACKEND));
-
- SAM_ASSERT(global_sam_sid);
-
- entry.module_name = SAM_DEFAULT_BACKEND;
- entry.module_params = NULL;
- entry.domain_name = lp_workgroup();
- entry.domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID));
- sid_copy(entry.domain_sid, global_sam_sid);
-
- if (!NT_STATUS_IS_OK(ntstatus = make_sam_methods_backend_entry(context, &methods, &entry))) {
- DEBUG(4,("make_sam_methods_backend_entry failed\n"));
- return ntstatus;
- }
-
- DLIST_ADD_END(context->methods, methods, tmpmethods);
-
- } else if (!NT_STATUS_IS_OK(ntstatus)) {
- DEBUG(2, ("sam_get_methods_by_sid failed for %s\n", lp_workgroup()));
- return ntstatus;
- }
-
- /* Make sure the BUILTIN domain is available */
-
- ntstatus = sam_get_methods_by_sid(context, &methods, global_sam_sid);
-
- if (NT_STATUS_EQUAL(ntstatus, NT_STATUS_NO_SUCH_DOMAIN)) {
- DEBUG(4,("There was no backend specified for domain BUILTIN; using %s\n",
- SAM_DEFAULT_BACKEND));
- entry.module_name = SAM_DEFAULT_BACKEND;
- entry.module_params = NULL;
- entry.domain_name = "BUILTIN";
- entry.domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID));
- sid_copy(entry.domain_sid, &global_sid_Builtin);
-
- if (!NT_STATUS_IS_OK(ntstatus = make_sam_methods_backend_entry(context, &methods, &entry))) {
- DEBUG(4,("make_sam_methods_backend_entry failed\n"));
- return ntstatus;
- }
-
- DLIST_ADD_END(context->methods, methods, tmpmethods);
- } else if (!NT_STATUS_IS_OK(ntstatus)) {
- DEBUG(2, ("sam_get_methods_by_sid failed for BUILTIN\n"));
- return ntstatus;
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS check_duplicate_backend_entries(SAM_BACKEND_ENTRY **backend_entries, int *nBackends)
-{
- int i, j;
-
- DEBUG(5,("check_duplicate_backend_entries: %d\n", __LINE__));
-
- for (i = 0; i < *nBackends; i++) {
- for (j = i + 1; j < *nBackends; j++) {
- if (sid_equal((*backend_entries)[i].domain_sid, (*backend_entries)[j].domain_sid)) {
- DEBUG(0,("two backend modules claim the same domain %s\n",
- sid_string_static((*backend_entries)[j].domain_sid)));
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS make_sam_context_list(SAM_CONTEXT **context, char **sam_backends_param)
-{
- int i = 0, j = 0;
- SAM_METHODS *curmethods, *tmpmethods;
- int nBackends = 0;
- SAM_BACKEND_ENTRY *backends = NULL;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(5,("make_sam_context_from_conf: %d\n", __LINE__));
-
- if (!sam_backends_param) {
- DEBUG(1, ("no SAM backeds specified!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_sam_context(context))) {
- DEBUG(4,("make_sam_context failed\n"));
- return nt_status;
- }
-
- while (sam_backends_param[nBackends])
- nBackends++;
-
- DEBUG(6,("There are %d domains listed with their backends\n", nBackends));
-
- if ((backends = (SAM_BACKEND_ENTRY *)malloc(sizeof(*backends)*nBackends)) == NULL) {
- DEBUG(0,("make_sam_context_list: failed to allocate backends\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- memset(backends, '\0', sizeof(*backends)*nBackends);
-
- for (i = 0; i < nBackends; i++) {
- DEBUG(8,("processing %s\n",sam_backends_param[i]));
- if (!NT_STATUS_IS_OK(nt_status = make_backend_entry(&backends[i], sam_backends_param[i]))) {
- DEBUG(4,("make_backend_entry failed\n"));
- for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid);
- SAFE_FREE(backends);
- free_sam_context(context);
- return nt_status;
- }
- }
-
- if (!NT_STATUS_IS_OK(nt_status = check_duplicate_backend_entries(&backends, &nBackends))) {
- DEBUG(4,("check_duplicate_backend_entries failed\n"));
- for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid);
- SAFE_FREE(backends);
- free_sam_context(context);
- return nt_status;
- }
-
- for (i = 0; i < nBackends; i++) {
- if (!NT_STATUS_IS_OK(nt_status = make_sam_methods_backend_entry(*context, &curmethods, &backends[i]))) {
- DEBUG(4,("make_sam_methods_backend_entry failed\n"));
- for (j = 0; j < nBackends; j++) SAFE_FREE(backends[j].domain_sid);
- SAFE_FREE(backends);
- free_sam_context(context);
- return nt_status;
- }
- DLIST_ADD_END((*context)->methods, curmethods, tmpmethods);
- }
-
- for (i = 0; i < nBackends; i++) SAFE_FREE(backends[i].domain_sid);
-
- SAFE_FREE(backends);
- return NT_STATUS_OK;
-}
-
-/******************************************************************
- Make a sam_context from scratch.
- *******************************************************************/
-
-NTSTATUS make_sam_context(SAM_CONTEXT **context)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("sam_context internal allocation context");
-
- if (!mem_ctx) {
- DEBUG(0, ("make_sam_context: talloc init failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- *context = talloc(mem_ctx, sizeof(**context));
- if (!*context) {
- DEBUG(0, ("make_sam_context: talloc failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- ZERO_STRUCTP(*context);
-
- (*context)->mem_ctx = mem_ctx;
-
- (*context)->free_fn = free_sam_context;
-
- return NT_STATUS_OK;
-}
-
-/******************************************************************
- Return an already initialised sam_context, to facilitate backward
- compatibility (see functions below).
- *******************************************************************/
-
-static struct sam_context *sam_get_static_context(BOOL reload)
-{
- static SAM_CONTEXT *sam_context = NULL;
-
- if ((sam_context) && (reload)) {
- sam_context->free_fn(&sam_context);
- sam_context = NULL;
- }
-
- if (!sam_context) {
- if (!NT_STATUS_IS_OK(make_sam_context_list(&sam_context, lp_sam_backend()))) {
- DEBUG(4,("make_sam_context_list failed\n"));
- return NULL;
- }
-
- /* Make sure the required domains (default domain, builtin) are available */
- if (!NT_STATUS_IS_OK(sam_context_check_default_backends(sam_context))) {
- DEBUG(4,("sam_context_check_default_backends failed\n"));
- return NULL;
- }
- }
-
- return sam_context;
-}
-
-/***************************************************************
- Initialize the static context (at smbd startup etc).
-
- If uninitialised, context will auto-init on first use.
- ***************************************************************/
-
-BOOL initialize_sam(BOOL reload)
-{
- return (sam_get_static_context(reload) != NULL);
-}
-
-
-/**************************************************************
- External API. This is what the rest of the world calls...
-***************************************************************/
-
-/******************************************************************
- sam_* functions are used to link the external SAM interface
- with the internal backends. These functions lookup the appropriate
- backends for the domain and pass on to the function in sam_methods
- in the selected backend
-
- When the context parmater is NULL, the default is used.
- *******************************************************************/
-
-#define SAM_SETUP_CONTEXT if (!context) \
- context = sam_get_static_context(False);\
- if (!context) {\
- return NT_STATUS_UNSUCCESSFUL; \
- }\
-
-
-
-NTSTATUS sam_get_sec_desc(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *sid, SEC_DESC **sd)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_get_sec_desc: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, sid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_sec_desc) {
- DEBUG(3, ("sam_get_sec_desc: sam_methods of the domain did not specify sam_get_sec_desc\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_sec_desc(tmp_methods, access_token, sid, sd))) {
- DEBUG(4,("sam_get_sec_desc for %s in backend %s failed\n", sid_string_static(sid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_set_sec_desc(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *sid, const SEC_DESC *sd)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_set_sec_desc: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, sid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_set_sec_desc) {
- DEBUG(3, ("sam_set_sec_desc: sam_methods of the domain did not specify sam_set_sec_desc\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_set_sec_desc(tmp_methods, access_token, sid, sd))) {
- DEBUG(4,("sam_set_sec_desc for %s in backend %s failed\n", sid_string_static(sid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-
-NTSTATUS sam_lookup_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID *sid, uint32 *type)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_lookup_name: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) {
- DEBUG(4,("sam_get_methods_by_name failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_lookup_name) {
- DEBUG(3, ("sam_lookup_name: sam_methods of the domain did not specify sam_lookup_name\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_name(tmp_methods, access_token, name, sid, type))) {
- DEBUG(4,("sam_lookup_name for %s\\%s in backend %s failed\n",
- tmp_methods->domain_name, name, tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name, uint32 *type)
-{
- SAM_METHODS *tmp_methods;
- uint32 rid;
- NTSTATUS nt_status;
- DOM_SID domainsid;
-
- DEBUG(5,("sam_lookup_sid: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- sid_copy(&domainsid, sid);
- if (!sid_split_rid(&domainsid, &rid)) {
- DEBUG(3,("sam_lookup_sid: failed to split the sid\n"));
- return NT_STATUS_INVALID_SID;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_lookup_sid) {
- DEBUG(3, ("sam_lookup_sid: sam_methods of the domain did not specify sam_lookup_sid\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_sid(tmp_methods, access_token, mem_ctx, sid, name, type))) {
- DEBUG(4,("sam_lookup_name for %s in backend %s failed\n",
- sid_string_static(sid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-
-NTSTATUS sam_update_domain(const SAM_CONTEXT *context, const SAM_DOMAIN_HANDLE *domain)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_update_domain: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid domain specified */
- SAM_ASSERT(domain && domain->current_sam_methods);
-
- tmp_methods = domain->current_sam_methods;
-
- if (!tmp_methods->sam_update_domain) {
- DEBUG(3, ("sam_update_domain: sam_methods of the domain did not specify sam_update_domain\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_domain(tmp_methods, domain))){
- DEBUG(4,("sam_update_domain in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_enum_domains(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, int32 *domain_count, DOM_SID **domains, char ***domain_names)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- SEC_DESC *sd;
- size_t sd_size;
- uint32 acc_granted;
- int i = 0;
-
- DEBUG(5,("sam_enum_domains: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid parmaters specified */
- SAM_ASSERT(domain_count && domains && domain_names);
-
- if (!NT_STATUS_IS_OK(nt_status = samr_make_sam_obj_sd(context->mem_ctx, &sd, &sd_size))) {
- DEBUG(4,("samr_make_sam_obj_sd failed\n"));
- return nt_status;
- }
-
- if (!se_access_check(sd, access_token, SA_RIGHT_SAM_ENUM_DOMAINS, &acc_granted, &nt_status)) {
- DEBUG(3,("sam_enum_domains: ACCESS DENIED\n"));
- return nt_status;
- }
-
- tmp_methods= context->methods;
- *domain_count = 0;
-
- while (tmp_methods) {
- (*domain_count)++;
- tmp_methods= tmp_methods->next;
- }
-
- DEBUG(6,("sam_enum_domains: enumerating %d domains\n", (*domain_count)));
-
- tmp_methods = context->methods;
-
- if (((*domains) = malloc( sizeof(DOM_SID) * (*domain_count))) == NULL) {
- DEBUG(0,("sam_enum_domains: Out of memory allocating domain SID list\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- if (((*domain_names) = malloc( sizeof(char*) * (*domain_count))) == NULL) {
- DEBUG(0,("sam_enum_domains: Out of memory allocating domain name list\n"));
- SAFE_FREE((*domains));
- return NT_STATUS_NO_MEMORY;
- }
-
- while (tmp_methods) {
- DEBUGADD(7,(" [%d] %s: %s\n", i, tmp_methods->domain_name, sid_string_static(&tmp_methods->domain_sid)));
- sid_copy(domains[i],&tmp_methods->domain_sid);
- *domain_names[i] = smb_xstrdup(tmp_methods->domain_name);
- i++;
- tmp_methods= tmp_methods->next;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_lookup_domain(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, DOM_SID **domainsid)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- SEC_DESC *sd;
- size_t sd_size;
- uint32 acc_granted;
-
- DEBUG(5,("sam_lookup_domain: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid paramters */
- SAM_ASSERT(access_token && domain && domainsid);
-
- if (!NT_STATUS_IS_OK(nt_status = samr_make_sam_obj_sd(context->mem_ctx, &sd, &sd_size))) {
- DEBUG(4,("samr_make_sam_obj_sd failed\n"));
- return nt_status;
- }
-
- if (!se_access_check(sd, access_token, SA_RIGHT_SAM_OPEN_DOMAIN, &acc_granted, &nt_status)) {
- DEBUG(3,("sam_lookup_domain: ACCESS DENIED\n"));
- return nt_status;
- }
-
- tmp_methods= context->methods;
-
- while (tmp_methods) {
- if (strcmp(domain, tmp_methods->domain_name) == 0) {
- (*domainsid) = (DOM_SID *)malloc(sizeof(DOM_SID));
- sid_copy((*domainsid), &tmp_methods->domain_sid);
- return NT_STATUS_OK;
- }
- tmp_methods= tmp_methods->next;
- }
-
- return NT_STATUS_NO_SUCH_DOMAIN;
-}
-
-
-NTSTATUS sam_get_domain_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, SAM_DOMAIN_HANDLE **domain)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_get_domain_by_sid: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domainsid && domain);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_domain_handle) {
- DEBUG(3, ("sam_get_domain_by_sid: sam_methods of the domain did not specify sam_get_domain_handle\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_domain_handle(tmp_methods, access_token, access_desired, domain))) {
- DEBUG(4,("sam_get_domain_handle for %s in backend %s failed\n",
- sid_string_static(domainsid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_create_account(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_create_account: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid parmaters */
- SAM_ASSERT(access_token && domainsid && account_name && account);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_create_account) {
- DEBUG(3, ("sam_create_account: sam_methods of the domain did not specify sam_create_account\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_account(tmp_methods, access_token, access_desired, account_name, acct_ctrl, account))) {
- DEBUG(4,("sam_create_account in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_add_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account)
-{
- DOM_SID domainsid;
- const DOM_SID *accountsid;
- SAM_METHODS *tmp_methods;
- uint32 rid;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_add_account: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid parmaters */
- SAM_ASSERT(account);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_account_sid(account, &accountsid))) {
- DEBUG(0,("Can't get account SID\n"));
- return nt_status;
- }
-
- sid_copy(&domainsid, accountsid);
- if (!sid_split_rid(&domainsid, &rid)) {
- DEBUG(3,("sam_get_account_by_sid: failed to split the sid\n"));
- return NT_STATUS_INVALID_SID;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_add_account) {
- DEBUG(3, ("sam_add_account: sam_methods of the domain did not specify sam_add_account\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_account(tmp_methods, account))){
- DEBUG(4,("sam_add_account in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_update_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_update_account: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid account specified */
- SAM_ASSERT(account && account->current_sam_methods);
-
- tmp_methods = account->current_sam_methods;
-
- if (!tmp_methods->sam_update_account) {
- DEBUG(3, ("sam_update_account: sam_methods of the domain did not specify sam_update_account\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_account(tmp_methods, account))){
- DEBUG(4,("sam_update_account in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_delete_account(const SAM_CONTEXT *context, const SAM_ACCOUNT_HANDLE *account)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_delete_account: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid account specified */
- SAM_ASSERT(account && account->current_sam_methods);
-
- tmp_methods = account->current_sam_methods;
-
- if (!tmp_methods->sam_delete_account) {
- DEBUG(3, ("sam_delete_account: sam_methods of the domain did not specify sam_delete_account\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_account(tmp_methods, account))){
- DEBUG(4,("sam_delete_account in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_enum_accounts(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 acct_ctrl, int32 *account_count, SAM_ACCOUNT_ENUM **accounts)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_enum_accounts: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domainsid && account_count && accounts);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_enum_accounts) {
- DEBUG(3, ("sam_enum_accounts: sam_methods of the domain did not specify sam_enum_accounts\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_accounts(tmp_methods, access_token, acct_ctrl, account_count, accounts))) {
- DEBUG(4,("sam_enum_accounts for domain %s in backend %s failed\n",
- tmp_methods->domain_name, tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-
-NTSTATUS sam_get_account_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *accountsid, SAM_ACCOUNT_HANDLE **account)
-{
- SAM_METHODS *tmp_methods;
- uint32 rid;
- DOM_SID domainsid;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_get_account_by_sid: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && accountsid && account);
-
- sid_copy(&domainsid, accountsid);
- if (!sid_split_rid(&domainsid, &rid)) {
- DEBUG(3,("sam_get_account_by_sid: failed to split the sid\n"));
- return NT_STATUS_INVALID_SID;
- }
-
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_account_by_sid) {
- DEBUG(3, ("sam_get_account_by_sid: sam_methods of the domain did not specify sam_get_account_by_sid\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_account_by_sid(tmp_methods, access_token, access_desired, accountsid, account))) {
- DEBUG(4,("sam_get_account_by_sid for %s in backend %s failed\n",
- sid_string_static(accountsid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_get_account_by_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain, const char *name, SAM_ACCOUNT_HANDLE **account)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_get_account_by_name: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domain && name && account);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) {
- DEBUG(4,("sam_get_methods_by_name failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_account_by_name) {
- DEBUG(3, ("sam_get_account_by_name: sam_methods of the domain did not specify sam_get_account_by_name\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_account_by_name(tmp_methods, access_token, access_desired, name, account))) {
- DEBUG(4,("sam_get_account_by_name for %s\\%s in backend %s failed\n",
- domain, name, tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_create_group(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *group_name, uint16 group_ctrl, SAM_GROUP_HANDLE **group)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_create_group: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domainsid && group_name && group);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_create_group) {
- DEBUG(3, ("sam_create_group: sam_methods of the domain did not specify sam_create_group\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_group(tmp_methods, access_token, access_desired, group_name, group_ctrl, group))) {
- DEBUG(4,("sam_create_group in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_add_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group)
-{
- DOM_SID domainsid;
- const DOM_SID *groupsid;
- SAM_METHODS *tmp_methods;
- uint32 rid;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_add_group: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(group);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_group_sid(group, &groupsid))) {
- DEBUG(0,("Can't get group SID\n"));
- return nt_status;
- }
-
- sid_copy(&domainsid, groupsid);
- if (!sid_split_rid(&domainsid, &rid)) {
- DEBUG(3,("sam_get_group_by_sid: failed to split the sid\n"));
- return NT_STATUS_INVALID_SID;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_add_group) {
- DEBUG(3, ("sam_add_group: sam_methods of the domain did not specify sam_add_group\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_group(tmp_methods, group))){
- DEBUG(4,("sam_add_group in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_update_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_update_group: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid group specified */
- SAM_ASSERT(group && group->current_sam_methods);
-
- tmp_methods = group->current_sam_methods;
-
- if (!tmp_methods->sam_update_group) {
- DEBUG(3, ("sam_update_group: sam_methods of the domain did not specify sam_update_group\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_update_group(tmp_methods, group))){
- DEBUG(4,("sam_update_group in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_delete_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_delete_group: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid group specified */
- SAM_ASSERT(group && group->current_sam_methods);
-
- tmp_methods = group->current_sam_methods;
-
- if (!tmp_methods->sam_delete_group) {
- DEBUG(3, ("sam_delete_group: sam_methods of the domain did not specify sam_delete_group\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_group(tmp_methods, group))){
- DEBUG(4,("sam_delete_group in backend %s failed\n",
- tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_enum_groups(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 group_ctrl, uint32 *groups_count, SAM_GROUP_ENUM **groups)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_enum_groups: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domainsid && groups_count && groups);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_enum_accounts) {
- DEBUG(3, ("sam_enum_groups: sam_methods of the domain did not specify sam_enum_groups\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_groups(tmp_methods, access_token, group_ctrl, groups_count, groups))) {
- DEBUG(4,("sam_enum_groups for domain %s in backend %s failed\n",
- tmp_methods->domain_name, tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_get_group_by_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *groupsid, SAM_GROUP_HANDLE **group)
-{
- SAM_METHODS *tmp_methods;
- uint32 rid;
- NTSTATUS nt_status;
- DOM_SID domainsid;
-
- DEBUG(5,("sam_get_group_by_sid: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && groupsid && group);
-
- sid_copy(&domainsid, groupsid);
- if (!sid_split_rid(&domainsid, &rid)) {
- DEBUG(3,("sam_get_group_by_sid: failed to split the sid\n"));
- return NT_STATUS_INVALID_SID;
- }
-
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_sid(context, &tmp_methods, &domainsid))) {
- DEBUG(4,("sam_get_methods_by_sid failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_group_by_sid) {
- DEBUG(3, ("sam_get_group_by_sid: sam_methods of the domain did not specify sam_get_group_by_sid\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_group_by_sid(tmp_methods, access_token, access_desired, groupsid, group))) {
- DEBUG(4,("sam_get_group_by_sid for %s in backend %s failed\n",
- sid_string_static(groupsid), tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_get_group_by_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain, const char *name, SAM_GROUP_HANDLE **group)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- DEBUG(5,("sam_get_group_by_name: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- SAM_ASSERT(access_token && domain && name && group);
-
- if (!NT_STATUS_IS_OK(nt_status = sam_get_methods_by_name(context, &tmp_methods, domain))) {
- DEBUG(4,("sam_get_methods_by_name failed\n"));
- return nt_status;
- }
-
- if (!tmp_methods->sam_get_group_by_name) {
- DEBUG(3, ("sam_get_group_by_name: sam_methods of the domain did not specify sam_get_group_by_name\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_group_by_name(tmp_methods, access_token, access_desired, name, group))) {
- DEBUG(4,("sam_get_group_by_name for %s\\%s in backend %s failed\n",
- domain, name, tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_add_member_to_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- SAM_SETUP_CONTEXT;
-
- /* invalid group or member specified */
- SAM_ASSERT(group && group->current_sam_methods && member);
-
- tmp_methods = group->current_sam_methods;
-
- if (!tmp_methods->sam_add_member_to_group) {
- DEBUG(3, ("sam_add_member_to_group: sam_methods of the domain did not specify sam_add_member_to_group\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_add_member_to_group(tmp_methods, group, member))) {
- DEBUG(4,("sam_add_member_to_group in backend %s failed\n", tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-
-}
-
-NTSTATUS sam_delete_member_from_group(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, const SAM_GROUP_MEMBER *member)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- SAM_SETUP_CONTEXT;
-
- /* invalid group or member specified */
- SAM_ASSERT(group && group->current_sam_methods && member);
-
- tmp_methods = group->current_sam_methods;
-
- if (!tmp_methods->sam_delete_member_from_group) {
- DEBUG(3, ("sam_delete_member_from_group: sam_methods of the domain did not specify sam_delete_member_from_group\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_delete_member_from_group(tmp_methods, group, member))) {
- DEBUG(4,("sam_delete_member_from_group in backend %s failed\n", tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_enum_groupmembers(const SAM_CONTEXT *context, const SAM_GROUP_HANDLE *group, uint32 *members_count, SAM_GROUP_MEMBER **members)
-{
- const SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- SAM_SETUP_CONTEXT;
-
- /* invalid group specified */
- SAM_ASSERT(group && group->current_sam_methods && members_count && members);
-
- tmp_methods = group->current_sam_methods;
-
- if (!tmp_methods->sam_enum_groupmembers) {
- DEBUG(3, ("sam_enum_groupmembers: sam_methods of the domain did not specify sam_enum_group_members\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_enum_groupmembers(tmp_methods, group, members_count, members))) {
- DEBUG(4,("sam_enum_groupmembers in backend %s failed\n", tmp_methods->backendname));
- return nt_status;
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS sam_get_groups_of_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID **sids, uint16 group_ctrl, uint32 *group_count, SAM_GROUP_ENUM **groups)
-{
- SAM_METHODS *tmp_methods;
- NTSTATUS nt_status;
-
- uint32 tmp_group_count;
- SAM_GROUP_ENUM *tmp_groups;
-
- DEBUG(5,("sam_get_groups_of_sid: %d\n", __LINE__));
-
- SAM_SETUP_CONTEXT;
-
- /* invalid sam_context specified */
- SAM_ASSERT(access_token && sids && context && context->methods);
-
- *group_count = 0;
-
- *groups = NULL;
-
- tmp_methods= context->methods;
-
- while (tmp_methods) {
- DEBUG(5,("getting groups from domain \n"));
- if (!tmp_methods->sam_get_groups_of_sid) {
- DEBUG(3, ("sam_get_groups_of_sid: sam_methods of domain did not specify sam_get_groups_of_sid\n"));
- SAFE_FREE(*groups);
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_get_groups_of_sid(tmp_methods, access_token, sids, group_ctrl, &tmp_group_count, &tmp_groups))) {
- DEBUG(4,("sam_get_groups_of_sid in backend %s failed\n", tmp_methods->backendname));
- SAFE_FREE(*groups);
- return nt_status;
- }
-
- *groups = Realloc(*groups, ((*group_count) + tmp_group_count) * sizeof(SAM_GROUP_ENUM));
-
- memcpy(&(*groups)[*group_count], tmp_groups, tmp_group_count);
-
- SAFE_FREE(tmp_groups);
-
- *group_count += tmp_group_count;
-
- tmp_methods = tmp_methods->next;
- }
-
- return NT_STATUS_OK;
-}
-
-
diff --git a/source/script/build_env.sh b/source/script/build_env.sh
deleted file mode 100755
index eb54f37aeda..00000000000
--- a/source/script/build_env.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-if [ $# -lt 3 ]
-then
- echo "Usage: $0 srcdir builddir compiler"
- exit 1
-fi
-
-uname=`uname -a`
-date=`date`
-srcdir=$1
-builddir=$2
-compiler=$3
-
-if [ ! "x$USER" = "x" ]; then
- whoami=$USER
-else
- if [ ! "x$LOGNAME" = "x" ]; then
- whoami=$LOGNAME
- else
- whoami=`whoami || id -un`
- fi
-fi
-
-host=`hostname`
-
-cat <<EOF
-/* This file is automatically generated with "make include/build_env.h". DO NOT EDIT */
-
-#ifndef _BUILD_ENV_H
-#define _BUILD_ENV_H
-
-#define BUILD_ENV_UNAME "${uname}"
-#define BUILD_ENV_DATE "${date}"
-#define BUILD_ENV_SRCDIR "${srcdir}"
-#define BUILD_ENV_BUILDDIR "${builddir}"
-#define BUILD_ENV_USER "${whoami}"
-#define BUILD_ENV_HOST "${host}"
-#define BUILD_ENV_COMPILER "${compiler}"
-#endif /* _BUILD_ENV_H */
-EOF
diff --git a/source/script/convert_smbpasswd b/source/script/convert_smbpasswd
new file mode 100755
index 00000000000..edb775d3a67
--- /dev/null
+++ b/source/script/convert_smbpasswd
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Convert a Samba 1.9.18 smbpasswd file format into
+# a Samba 2.0 smbpasswd file format.
+# Read from stdin and write to stdout for simplicity.
+# Set the last change time to 0x363F96AD to avoid problems
+# with trying to work out how to get the seconds since 1970
+# in awk or the shell. JRA.
+#
+nawk 'BEGIN {FS=":"}
+{
+ if( $0 ~ "^#" ) {
+ print $0
+ } else {
+ printf( "%s:%s:%s:%s:[U ]:LCT-363F96AD:\n", $1, $2, $3, $4);
+ }
+}'
diff --git a/source/script/creategroup b/source/script/creategroup
deleted file mode 100755
index 01fb0659444..00000000000
--- a/source/script/creategroup
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# Example script for 'add group command'. Handle weird NT group
-# names. First attempt to create the group directly, if that fails
-# then create a random group and print the numeric group id.
-#
-# Note that this is only an example and assumes /dev/urandom.
-#
-# Volker
-
-GROUPNAME="$1"
-ITERS=0
-
-while ! /usr/sbin/groupadd "$GROUPNAME" > /dev/null 2>&1
-do
- # we had difficulties creating that group. Maybe the name was
- # too weird, or it already existed. Create a random name.
- GROUPNAME=nt-$(dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum | cut -b 1-5)
- ITERS=$(expr "$ITERS" + 1)
- if [ "$ITERS" -gt 10 ]
- then
- # Too many attempts
- exit 1
- fi
-done
-
-getent group | grep ^"$GROUPNAME": | cut -d : -f 3
diff --git a/source/script/findsmb.in b/source/script/findsmb.in
index 546cf8ce7b4..e9bb247da0d 100755
--- a/source/script/findsmb.in
+++ b/source/script/findsmb.in
@@ -1,11 +1,11 @@
-#!@PERL@
+#!/usr/bin/perl
#
# Prints info on all smb responding machines on a subnet.
# This script needs to be run on a machine without nmbd running and be
# run as root to get correct info from WIN95 clients.
#
# syntax:
-# findsmb [-d|-D] [-r] [subnet broadcast address]
+# findsmb [subnet broadcast address]
#
# with no agrument it will list machines on the current subnet
#
@@ -13,43 +13,32 @@
# local master browsers for that workgroup. There will be an "*" in front
# of the workgroup name for machines that are the domain master browser for
# that workgroup.
-#
-# Options:
-#
-# -d|-D enable debug
-# -r add -r option to nmblookup when finding netbios name
#
$SAMBABIN = "@prefix@/bin";
-for ($i = 0; $i < 2; $i++) { # test for -d and -r options
- $_ = shift;
- if (m/-d|-D/) {
- $DEBUG = 1;
- } elsif (m/-r/) {
- $R_OPTION = "-r";
- }
-}
-
-if ($_) { # set broadcast address if it was specified
- $BCAST = "-B $_";
+for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } else {
+ if ($_) {
+ $BCAST = "-B $_";
+ }
+ }
}
-
-######################################################################
-# do numeric sort on last field of IP address
-sub ipsort
+sub ipsort # do numeric sort on last field of IP address
{
- @t1 = split(/\./,$a);
- @t2 = split(/\./,$b);
- @t1[3] <=> @t2[3];
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
}
-######################################################################
# look for all machines that respond to a name lookup
-open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*' --debuglevel=0|") ||
- die("Can't run nmblookup '*'.\n");
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*'|") ||
+ die("Can't run nmblookup '*'.\n");
# get rid of all lines that are not a response IP address,
# strip everything but IP address and sort by last field in address
@@ -57,6 +46,7 @@ open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*' --debuglevel=0|") ||
@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
# print header info
+
print "\n *=DMB\n";
print " +=LMB\n";
print "IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
@@ -64,98 +54,100 @@ print "---------------------------------------------------------------------\n";
foreach $ip (@ipaddrs) # loop through each IP address found
{
- $ip =~ s/\n//; # strip newline from IP address
-
- # find the netbios names registered by each machine
-
- open(NMBLOOKUP,"$SAMBABIN/nmblookup $R_OPTION -A $ip --debuglevel=0|") ||
- die("Can't get nmb name list.\n");
- @nmblookup = <NMBLOOKUP>;
- close NMBLOOKUP;
-
- # get the first <00> name
-
- @name = grep(/<00>/,@nmblookup);
- $_ = @name[0];
-
- if ($_) { # we have a netbios name
- if (/GROUP/) { # is it a group name
- ($name, $aliases, $type, $length, @addresses) =
- gethostbyaddr(pack('C4',split('\.',$ip)),2);
- if (! $name) { # could not get name
- $name = "unknown nis name";
- }
- } else {
- # The Netbios name can contain lot of characters also '<' '>'
- # and spaces. The follwing cure inside name space but not
- # names starting or ending with spaces
- /(.{1,15})\s+<00>\s+/;
- $name = $1;
- $name =~ s/^\s+//g;
- }
-
- # do an smbclient command on the netbios name.
-
- if ( "$name" ) {
- open(SMB,"$SAMBABIN/smbclient -L $name -I $ip -N --debuglevel=1 2>&1 |") ||
- die("Can't do smbclient command.\n");
- @smb = <SMB>;
- close SMB;
-
- if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
- print "===============================================================\n";
- print @nmblookup;
- print @smb;
- }
-
- # look for the OS= string
-
- @info = grep(/OS=/,@smb);
- $_ = @info[0];
- if ($_) { # we found response
- s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
-
- } else { # no OS= string in response (WIN95 client)
-
- # for WIN95 clients get workgroup name from nmblookup response
- @name = grep(/<00> - <GROUP>/,@nmblookup);
- $_ = @name[0];
- if ($_) {
- # Same as before for space and characters
- /(.{1,15})\s+<00>\s+/;
- $_ = "[$1]";
- } else {
- $_ = "Unknown Workgroup";
- }
- }
- }
-
- # see if machine registered a local master browser name
- if (grep(/<1d>/,@nmblookup)) {
- $master = '+'; # indicate local master browser
- if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
- $master = '*'; # indicate domain master browser
- }
- } else {
- $master = ' '; # not a browse master
- }
-
- # line up info in 3 columns
-
- print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
-
- } else { # no netbios name found
- # try getting the host name
- ($name, $aliases, $type, $length, @addresses) =
- gethostbyaddr(pack('C4',split('\.',$ip)),2);
- if (! $name) { # could not get name
- $name = "unknown nis name";
- }
- if ($DEBUG) { # if -d flag print results of nmblookup
- print "===============================================================\n";
- print @nmblookup;
- }
- print "$ip".' 'x(16-length($ip))."$name\n";
- }
+ $ip =~ s/\n//; # strip newline from IP address
+
+# find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -r -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+# get the first non group <00> name
+
+ @name = grep(/<00> - /,@nmblookup);
+ $_ = @name[0];
+ if (not $_) {
+# try without the -r option
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+ @name = grep(/<00> - /,@nmblookup);
+ $_ = @name[0];
+ }
+# The Netbios name can contain lot of characters also '<' '>'
+# and spaces. The follwing cures embedded space but not
+# names starting or ending with spaces
+ /(.{1,15})\s+<00>\s+/;
+ $name = $1;
+
+ if (not $name) { # no netbios name found
+# try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown name";
+ }
+# truncate name to 15 characters
+ if (length($name) > 15) {
+ $name = substr($name,0,15);
+ }
+# do an smbclient command on the ip address
+
+ open(SMB,"$SAMBABIN/smbclient -N -L '$ip' -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+ } else { # netbios name found
+
+# do an smbclient command on the netbios name.
+
+ open(SMB,"$SAMBABIN/smbclient -N -L '$name' -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+# look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/.*Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+# for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+# Same as before for space and characters
+ /(.{1,15})\s+<00>\s+/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+
+# see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+# line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(16-length($name))."$master"."$_\n";
+
}
diff --git a/source/script/findstatic.pl b/source/script/findstatic.pl
deleted file mode 100755
index 43a4916435d..00000000000
--- a/source/script/findstatic.pl
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/perl -w
-# find a list of fns and variables in the code that could be static
-# usually called with something like this:
-# findstatic.pl `find . -name "*.o"`
-# Andrew Tridgell <tridge@samba.org>
-
-use strict;
-
-# use nm to find the symbols
-my($saved_delim) = $/;
-undef $/;
-my($syms) = `nm -o @ARGV`;
-$/ = $saved_delim;
-
-my(@lines) = split(/\n/s, $syms);
-
-my(%def);
-my(%undef);
-my(%stype);
-
-my(%typemap) = (
- "T" => "function",
- "C" => "uninitialised variable",
- "D" => "initialised variable"
- );
-
-
-# parse the symbols into defined and undefined
-for (my($i)=0; $i <= $#{@lines}; $i++) {
- my($line) = $lines[$i];
- if ($line =~ /(.*):[a-f0-9]* ([TCD]) (.*)/) {
- my($fname) = $1;
- my($symbol) = $3;
- push(@{$def{$fname}}, $symbol);
- $stype{$symbol} = $2;
- }
- if ($line =~ /(.*):\s* U (.*)/) {
- my($fname) = $1;
- my($symbol) = $2;
- push(@{$undef{$fname}}, $symbol);
- }
-}
-
-# look for defined symbols that are never referenced outside the place they
-# are defined
-foreach my $f (keys %def) {
- print "Checking $f\n";
- my($found_one) = 0;
- foreach my $s (@{$def{$f}}) {
- my($found) = 0;
- foreach my $f2 (keys %undef) {
- if ($f2 ne $f) {
- foreach my $s2 (@{$undef{$f2}}) {
- if ($s2 eq $s) {
- $found = 1;
- $found_one = 1;
- }
- }
- }
- }
- if ($found == 0) {
- my($t) = $typemap{$stype{$s}};
- print " '$s' is unique to $f ($t)\n";
- }
- }
- if ($found_one == 0) {
- print " all symbols in '$f' are unused (main program?)\n";
- }
-}
-
diff --git a/source/script/gap.awk b/source/script/gap.awk
deleted file mode 100644
index 11680d10f9e..00000000000
--- a/source/script/gap.awk
+++ /dev/null
@@ -1,39 +0,0 @@
-BEGIN { hv["0"] = 0; hv["1"] = 1; hv["2"] = 2; hv["3"] = 3;
- hv["4"] = 4; hv["5"] = 5; hv["6"] = 6; hv["7"] = 7;
- hv["8"] = 8; hv["9"] = 9; hv["A"] = 10; hv["B"] = 11;
- hv["C"] = 12; hv["D"] = 13; hv["E"] = 14; hv["F"] = 15;
- hv["a"] = 10; hv["b"] = 11; hv["c"] = 12; hv["d"] = 13;
- hv["e"] = 14; hv["f"] = 15;
-
- first = 0; last = 0; idx = 0;
-}
-
-function tonum(str)
-{
- num=0;
- cnt=1;
- while (cnt <= length(str)) {
- num *= 16;
- num += hv[substr(str,cnt,1)];
- ++cnt;
- }
- return num;
-}
-
-{
- u = tonum($1);
- if (u - last > 6)
- {
- if (last)
- {
- printf (" { 0x%04x, 0x%04x, %5d },\n",
- first, last, idx);
- idx -= u - last - 1;
- }
- first = u;
- }
- last = u;
-}
-
-END { printf (" { 0x%04x, 0x%04x, %5d },\n",
- first, last, idx); }
diff --git a/source/script/gaptab.awk b/source/script/gaptab.awk
deleted file mode 100644
index a309089cd5b..00000000000
--- a/source/script/gaptab.awk
+++ /dev/null
@@ -1,48 +0,0 @@
-BEGIN { hv["0"] = 0; hv["1"] = 1; hv["2"] = 2; hv["3"] = 3;
- hv["4"] = 4; hv["5"] = 5; hv["6"] = 6; hv["7"] = 7;
- hv["8"] = 8; hv["9"] = 9; hv["A"] = 10; hv["B"] = 11;
- hv["C"] = 12; hv["D"] = 13; hv["E"] = 14; hv["F"] = 15;
- hv["a"] = 10; hv["b"] = 11; hv["c"] = 12; hv["d"] = 13;
- hv["e"] = 14; hv["f"] = 15;
-
- first = 0; last = 0; idx = 0; f = 0;
-}
-
-function tonum(str)
-{
- num=0;
- cnt=1;
- while (cnt <= length(str)) {
- num *= 16;
- num += hv[substr(str,cnt,1)];
- ++cnt;
- }
- return num;
-}
-
-function fmt(val)
-{
- if (f++ % 8 == 0)
- { printf ("\n 0x%02x,", val); }
- else
- { printf (" 0x%02x,", val); }
-}
-
-{
- u = tonum($1); c = tonum($2);
-
- if (u - last > 6)
- {
- if (last) { idx += last - first + 1; }
- first = u;
- }
- else
- {
- for (m = last+1; m < u; m++) { fmt(0); }
- }
-
- fmt(c);
- last = u;
-}
-
-END { print "" }
diff --git a/source/script/gen-8bit-gap.awk b/source/script/gen-8bit-gap.awk
deleted file mode 100644
index 59a1a23be07..00000000000
--- a/source/script/gen-8bit-gap.awk
+++ /dev/null
@@ -1,18 +0,0 @@
-BEGIN {
- for (i=0; i<256; i++) {
- tbl[sprintf("%02x",i)] = "0x0000";
- }
-}
-
-/^<U([[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]])>[[:space:]]*.x([[:xdigit:]][[:xdigit:]])[:space:]*.*$/ {
- tbl[substr($2,3,2)]=sprintf("0x%s",substr($1,3,4));
-}
-
-END {
- for(i=0; i<32; i++) {
- for(j=0; j<8; j++) {
- printf(" %s,", tbl[sprintf("%02x",i*8+j)]);
- }
- printf "\n"
- }
-} \ No newline at end of file
diff --git a/source/script/gen-8bit-gap.sh.in b/source/script/gen-8bit-gap.sh.in
deleted file mode 100755
index bcf64a4464f..00000000000
--- a/source/script/gen-8bit-gap.sh.in
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/sh
-if test $# -ne 2 ; then
- echo "Usage: $0 <charmap file> <CHARSET NAME>"
- exit 1
-fi
-
-CHARMAP=$1
-CHARSETNAME=$2
-
-echo "/* "
-echo " * Conversion table for $CHARSETNAME charset "
-echo " * "
-echo " * Conversion tables are generated using $CHARMAP table "
-echo " * and source/script/gen-8bit-gap.sh script "
-echo " * "
-echo " * This program is free software; you can redistribute it and/or modify "
-echo " * it under the terms of the GNU General Public License as published by "
-echo " * the Free Software Foundation; either version 2 of the License, or "
-echo " * (at your option) any later version. "
-echo " * "
-echo " * This program is distributed in the hope that it will be useful,"
-echo " * but WITHOUT ANY WARRANTY; without even the implied warranty of "
-echo " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
-echo " * GNU General Public License for more details. "
-echo " * "
-echo " * You should have received a copy of the GNU General Public License "
-echo " * along with this program; if not, write to the Free Software "
-echo " * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. "
-echo " */"
-
-echo '#include "includes.h"'
-echo
-echo "static const uint16 to_ucs2[256] = {"
-cat "$CHARMAP" | @AWK@ -f @srcdir@/script/gen-8bit-gap.awk
-echo "};"
-echo
-echo "static const struct charset_gap_table from_idx[] = {"
-sed -ne 's/^<U\(....\).*/\1/p' \
- "$CHARMAP" | sort -u | @AWK@ -f @srcdir@/script/gap.awk
-echo " { 0xffff, 0xffff, 0 }"
-echo "};"
-echo
-echo "static const unsigned char from_ucs2[] = {"
-sed -ne 's/^<U\(....\)>[[:space:]]*.x\(..\).*/\1 \2/p' \
- "$CHARMAP" | sort -u | @AWK@ -f @srcdir@/script/gaptab.awk
-echo "};"
-echo
-echo "SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP($CHARSETNAME)"
-echo
diff --git a/source/script/genstruct.pl b/source/script/genstruct.pl
deleted file mode 100755
index a6abd718c95..00000000000
--- a/source/script/genstruct.pl
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/perl -w
-# a simple system for generating C parse info
-# this can be used to write generic C structer load/save routines
-# Copyright 2002 Andrew Tridgell <genstruct@tridgell.net>
-# released under the GNU General Public License v2 or later
-
-use strict;
-
-my(%enum_done) = ();
-my(%struct_done) = ();
-
-###################################################
-# general handler
-sub handle_general($$$$$$$$)
-{
- my($name) = shift;
- my($ptr_count) = shift;
- my($size) = shift;
- my($element) = shift;
- my($flags) = shift;
- my($dump_fn) = shift;
- my($parse_fn) = shift;
- my($tflags) = shift;
- my($array_len) = 0;
- my($dynamic_len) = "NULL";
-
- # handle arrays, currently treat multidimensional arrays as 1 dimensional
- while ($element =~ /(.*)\[(.*?)\]$/) {
- $element = $1;
- if ($array_len == 0) {
- $array_len = $2;
- } else {
- $array_len = "$2 * $array_len";
- }
- }
-
- if ($flags =~ /_LEN\((\w*?)\)/) {
- $dynamic_len = "\"$1\"";
- }
-
- if ($flags =~ /_NULLTERM/) {
- $tflags = "FLAG_NULLTERM";
- }
-
- print OFILE "{\"$element\", $ptr_count, $size, offsetof(struct $name, $element), $array_len, $dynamic_len, $tflags, $dump_fn, $parse_fn},\n";
-}
-
-
-####################################################
-# parse one element
-sub parse_one($$$$)
-{
- my($name) = shift;
- my($type) = shift;
- my($element) = shift;
- my($flags) = shift;
- my($ptr_count) = 0;
- my($size) = "sizeof($type)";
- my($tflags) = "0";
-
- # enums get the FLAG_ALWAYS flag
- if ($type =~ /^enum /) {
- $tflags = "FLAG_ALWAYS";
- }
-
-
- # make the pointer part of the base type
- while ($element =~ /^\*(.*)/) {
- $ptr_count++;
- $element = $1;
- }
-
- # convert spaces to _
- $type =~ s/ /_/g;
-
- my($dump_fn) = "gen_dump_$type";
- my($parse_fn) = "gen_parse_$type";
-
- handle_general($name, $ptr_count, $size, $element, $flags, $dump_fn, $parse_fn, $tflags);
-}
-
-####################################################
-# parse one element
-sub parse_element($$$)
-{
- my($name) = shift;
- my($element) = shift;
- my($flags) = shift;
- my($type);
- my($data);
-
- # pull the base type
- if ($element =~ /^struct (\S*) (.*)/) {
- $type = "struct $1";
- $data = $2;
- } elsif ($element =~ /^enum (\S*) (.*)/) {
- $type = "enum $1";
- $data = $2;
- } elsif ($element =~ /^unsigned (\S*) (.*)/) {
- $type = "unsigned $1";
- $data = $2;
- } elsif ($element =~ /^(\S*) (.*)/) {
- $type = $1;
- $data = $2;
- } else {
- die "Can't parse element '$element'";
- }
-
- # handle comma separated lists
- while ($data =~ /(\S*),[\s]?(.*)/) {
- parse_one($name, $type, $1, $flags);
- $data = $2;
- }
- parse_one($name, $type, $data, $flags);
-}
-
-
-my($first_struct) = 1;
-
-####################################################
-# parse the elements of one structure
-sub parse_elements($$)
-{
- my($name) = shift;
- my($elements) = shift;
-
- if ($first_struct) {
- $first_struct = 0;
- print "Parsing structs: $name";
- } else {
- print ", $name";
- }
-
- print OFILE "int gen_dump_struct_$name(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);\n";
- print OFILE "int gen_parse_struct_$name(TALLOC_CTX *mem_ctx, char *, const char *);\n";
-
- print OFILE "static const struct parse_struct pinfo_" . $name . "[] = {\n";
-
-
- while ($elements =~ /^.*?([a-z].*?);\s*?(\S*?)\s*?$(.*)/msi) {
- my($element) = $1;
- my($flags) = $2;
- $elements = $3;
- parse_element($name, $element, $flags);
- }
-
- print OFILE "{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};\n";
-
- print OFILE "
-int gen_dump_struct_$name(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
- return gen_dump_struct(mem_ctx, pinfo_$name, p, ptr, indent);
-}
-int gen_parse_struct_$name(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
- return gen_parse_struct(mem_ctx, pinfo_$name, ptr, str);
-}
-
-";
-}
-
-my($first_enum) = 1;
-
-####################################################
-# parse out the enum declarations
-sub parse_enum_elements($$)
-{
- my($name) = shift;
- my($elements) = shift;
-
- if ($first_enum) {
- $first_enum = 0;
- print "Parsing enums: $name";
- } else {
- print ", $name";
- }
-
- print OFILE "static const struct enum_struct einfo_" . $name . "[] = {\n";
-
- my(@enums) = split(/,/s, $elements);
- for (my($i)=0; $i <= $#{@enums}; $i++) {
- my($enum) = $enums[$i];
- if ($enum =~ /\s*(\w*)/) {
- my($e) = $1;
- print OFILE "{\"$e\", $e},\n";
- }
- }
-
- print OFILE "{NULL, 0}};\n";
-
- print OFILE "
-int gen_dump_enum_$name(struct parse_string *p, const char *ptr, unsigned indent) {
- return gen_dump_enum(einfo_$name, p, ptr, indent);
-}
-
-int gen_parse_enum_$name(char *ptr, const char *str) {
- return gen_parse_enum(einfo_$name, ptr, str);
-}
-
-";
-}
-
-####################################################
-# parse out the enum declarations
-sub parse_enums($)
-{
- my($data) = shift;
-
- while ($data =~ /^GENSTRUCT\s+enum\s+(\w*?)\s*{(.*?)}\s*;(.*)/ms) {
- my($name) = $1;
- my($elements) = $2;
- $data = $3;
-
- if (!defined($enum_done{$name})) {
- $enum_done{$name} = 1;
- parse_enum_elements($name, $elements);
- }
- }
-
- if (! $first_enum) {
- print "\n";
- }
-}
-
-####################################################
-# parse all the structures
-sub parse_structs($)
-{
- my($data) = shift;
-
- # parse into structures
- while ($data =~ /^GENSTRUCT\s+struct\s+(\w+?)\s*{\s*(.*?)\s*}\s*;(.*)/ms) {
- my($name) = $1;
- my($elements) = $2;
- $data = $3;
- if (!defined($struct_done{$name})) {
- $struct_done{$name} = 1;
- parse_elements($name, $elements);
- }
- }
-
- if (! $first_struct) {
- print "\n";
- } else {
- print "No GENSTRUCT structures found?\n";
- }
-}
-
-
-####################################################
-# parse a header file, generating a dumper structure
-sub parse_data($)
-{
- my($data) = shift;
-
- # collapse spaces
- $data =~ s/[\t ]+/ /sg;
- $data =~ s/\s*\n\s+/\n/sg;
- # strip debug lines
- $data =~ s/^\#.*?\n//smg;
-
- parse_enums($data);
- parse_structs($data);
-}
-
-
-#########################################
-# display help text
-sub ShowHelp()
-{
- print "
-generator for C structure dumpers
-Copyright Andrew Tridgell <genstruct\@tridgell.net>
-
-Sample usage:
- genstruct -o output.h gcc -E -O2 -g test.h
-
-Options:
- --help this help page
- -o OUTPUT place output in OUTPUT
-";
- exit(0);
-}
-
-########################################
-# main program
-if ($ARGV[0] ne "-o" || $#ARGV < 2) {
- ShowHelp();
-}
-
-shift;
-my($opt_ofile)=shift;
-
-print "creating $opt_ofile\n";
-
-open(OFILE, ">$opt_ofile") || die "can't open $opt_ofile";
-
-print OFILE "/* This is an automatically generated file - DO NOT EDIT! */\n\n";
-
-parse_data(`@ARGV -DGENSTRUCT=GENSTRUCT`);
-exit(0);
diff --git a/source/script/installbin.sh b/source/script/installbin.sh
index f9fd5298c09..77bded6420f 100755
--- a/source/script/installbin.sh
+++ b/source/script/installbin.sh
@@ -1,18 +1,27 @@
#!/bin/sh
INSTALLPERMS=$1
-DESTDIR=$2
-BASEDIR=`echo $3 | sed 's/\/\//\//g'`
-BINDIR=`echo $4 | sed 's/\/\//\//g'`
-LIBDIR=`echo $5 | sed 's/\/\//\//g'`
-VARDIR=`echo $6 | sed 's/\/\//\//g'`
-shift
+BASEDIR=$2
+BINDIR=$3
+LIBDIR=$4
+VARDIR=$5
shift
shift
shift
shift
shift
+for d in $BASEDIR $BINDIR $LIBDIR $VARDIR $BASEDIR/private; do
+if [ ! -d $d ]; then
+mkdir $d
+if [ ! -d $d ]; then
+ echo Failed to make directory $d
+ exit 1
+fi
+fi
+done
+
+
for p in $*; do
p2=`basename $p`
echo Installing $p as $BINDIR/$p2
@@ -25,10 +34,7 @@ for p in $*; do
# this is a special case, mount needs this in a specific location
if [ $p2 = smbmount ]; then
- if [ ! -d $DESTDIR/sbin ]; then
- mkdir $DESTDIR/sbin
- fi
- ln -sf $BINDIR/$p2 $DESTDIR/sbin/mount.smbfs
+ ln -sf $BINDIR/$p2 /sbin/mount.smbfs
fi
done
diff --git a/source/script/installcp.sh b/source/script/installcp.sh
new file mode 100755
index 00000000000..d0c5bf8ecc9
--- /dev/null
+++ b/source/script/installcp.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+srcdir=$1
+LIBDIR=$2
+CODEPAGEDIR=$3
+BINDIR=$4
+
+shift
+shift
+shift
+shift
+
+echo Installing codepage files in $CODEPAGEDIR
+for d in $LIBDIR $CODEPAGEDIR; do
+if [ ! -d $d ]; then
+mkdir $d
+if [ ! -d $d ]; then
+ echo Failed to make directory $d
+ exit 1
+fi
+fi
+done
+
+for p in $*; do
+ if [ -f ${srcdir}/codepages/codepage_def.$p ]; then
+ echo Creating codepage file $CODEPAGEDIR/codepage.$p
+ $BINDIR/make_smbcodepage c $p ${srcdir}/codepages/codepage_def.$p $CODEPAGEDIR/codepage.$p
+ fi
+ if [ -f ${srcdir}/codepages/CP${p}.TXT ]; then
+ echo Creating unicode map $CODEPAGEDIR/unicode_map.$p
+ $BINDIR/make_unicodemap $p ${srcdir}/codepages/CP${p}.TXT $CODEPAGEDIR/unicode_map.$p
+ fi
+done
+
+
+cat << EOF
+======================================================================
+The code pages have been installed. You may uninstall them using the
+command "make uninstallcp" or make "uninstall" to uninstall binaries,
+man pages, shell scripts and code pages.
+======================================================================
+EOF
+
+exit 0
+
diff --git a/source/script/installdat.sh b/source/script/installdat.sh
deleted file mode 100755
index 4a5b1de5dc8..00000000000
--- a/source/script/installdat.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-#fist version March 2002, Herb Lewis
-
-DATDIR=`echo $1 | sed 's/\/\//\//g'`
-SRCDIR=$2/
-
-echo Installing dat files in $DATDIR
-
-for f in $SRCDIR/codepages/*.dat; do
- FNAME=$DATDIR/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
-done
-
-cat << EOF
-======================================================================
-The dat files have been installed.
-======================================================================
-EOF
-
-exit 0
-
diff --git a/source/script/installdirs.sh b/source/script/installdirs.sh
deleted file mode 100755
index 1db46b82ff2..00000000000
--- a/source/script/installdirs.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-while ( test -n "$1" ); do
-
- DIRNAME=`echo $1 | sed 's/\/\//\//g'`
- if [ ! -d $DIRNAME ]; then
- mkdir -p $DIRNAME
- fi
-
- if [ ! -d $DIRNAME ]; then
- echo Failed to make directory $1
- exit 1
- fi
-
- shift;
-done
-
-
-
diff --git a/source/script/installman.sh b/source/script/installman.sh
index c7a8f450951..4eda8fd537f 100755
--- a/source/script/installman.sh
+++ b/source/script/installman.sh
@@ -1,64 +1,50 @@
#!/bin/sh
#5 July 96 Dan.Shearer@unisa.edu.au removed hardcoded values
-#
-# 13 Aug 2001 Rafal Szczesniak <mimir@spin.ict.pwr.wroc.pl>
-# modified to accomodate international man pages (inspired
-# by Japanese edition's approach)
-MANDIR=`echo $1 | sed 's/\/\//\//g'`
+MANDIR=$1
SRCDIR=$2/
-langs=$3
-
-if [ $# -ge 4 ] ; then
- GROFF=$4 # sh cmd line, including options
+if [ $# -ge 3 ] ; then
+ GROFF=$3 # sh cmd line, including options
fi
+echo Installing man pages in $MANDIR
-for lang in $langs; do
- if [ "X$lang" = Xen ]; then
- echo Installing default man pages in $MANDIR/
- lang=.
- else
- echo Installing \"$lang\" man pages in $MANDIR/lang/$lang
- fi
-
- langdir=$MANDIR/$lang
- for d in $MANDIR $langdir $langdir/man1 $langdir/man5 $langdir/man7 $langdir/man8; do
- if [ ! -d $d ]; then
- mkdir $d
- if [ ! -d $d ]; then
- echo Failed to make directory $d, does $USER have privileges?
- exit 1
- fi
- fi
- done
+for d in $MANDIR $MANDIR/man1 $MANDIR/man5 $MANDIR/man7 $MANDIR/man8; do
+if [ ! -d $d ]; then
+mkdir $d
+if [ ! -d $d ]; then
+ echo Failed to make directory $d, does $USER have privileges?
+ exit 1
+fi
+fi
+done
- for sect in 1 5 7 8 ; do
- for m in $langdir/man$sect ; do
- for s in $SRCDIR../docs/manpages/$lang/*$sect; do
- FNAME=$m/`basename $s`
+for sect in 1 5 7 8 ; do
+ for m in $MANDIR/man$sect ; do
+ for s in $SRCDIR../docs/manpages/*$sect; do
+ FNAME=$m/`basename $s`
- # Test for writability. Involves
- # blowing away existing files.
+ # Test for writability. Involves
+ # blowing away existing files.
- if (rm -f $FNAME && touch $FNAME); then
- rm $FNAME
- if [ "x$GROFF" = x ] ; then
- cp $s $m # Copy raw nroff
- else
- echo "\t$FNAME" # groff'ing can be slow, give the user
- # a warm fuzzy.
- $GROFF $s > $FNAME # Process nroff, because man(1) (on
- # this system) doesn't .
- fi
- chmod 0644 $FNAME
- else
- echo Cannot create $FNAME... does $USER have privileges?
- fi
- done
- done
+ if (rm -f $FNAME && touch $FNAME); then
+ rm $FNAME
+ if [ "x$GROFF" = x ] ; then
+ cp $s $m # Copy raw nroff
+ else
+ echo "\t$FNAME" # groff'ing can be slow, give the user
+ # a warm fuzzy.
+ $GROFF $s > $FNAME # Process nroff, because man(1) (on
+ # this system) doesn't .
+ fi
+ chmod 0644 $FNAME
+ else
+ echo Cannot create $FNAME... does $USER have privileges?
+ fi
done
+ done
done
+
cat << EOF
======================================================================
The man pages have been installed. You may uninstall them using the command
diff --git a/source/script/installmodules.sh b/source/script/installmodules.sh
deleted file mode 100755
index f7c74733381..00000000000
--- a/source/script/installmodules.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-INSTALLPERMS=$1
-BASEDIR=`echo $2 | sed 's/\/\//\//g'`
-LIBDIR=`echo $3 | sed 's/\/\//\//g'`
-shift
-shift
-shift
-
-for d in $BASEDIR $LIBDIR; do
-if [ ! -d $d ]; then
-mkdir $d
-if [ ! -d $d ]; then
- echo Failed to make directory $d
- exit 1
-fi
-fi
-done
-
-for p in $*; do
- p2=`basename $p`
- echo Installing $p as $LIBDIR/$p2
- cp -f $p $LIBDIR/
- chmod $INSTALLPERMS $LIBDIR/$p2
-done
-
-exit 0
diff --git a/source/script/installmsg.sh b/source/script/installmsg.sh
deleted file mode 100644
index 5a41fe1ca8d..00000000000
--- a/source/script/installmsg.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-# first version (Sept 2003) written by Shiro Yamada <shiro@miraclelinux.com>
-# based on the first verion (March 2002) of installdat.sh written by Herb Lewis
-
-MSGDIR=`echo $1 | sed 's/\/\//\//g'`
-SRCDIR=$2/
-
-echo Installing msg files in $MSGDIR
-
-for f in $SRCDIR/po/*.msg; do
- FNAME=$MSGDIR/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
-done
-
-cat << EOF
-======================================================================
-The msg files have been installed.
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/installscripts.sh b/source/script/installscripts.sh
index 81608c3682c..bff5423e7cb 100755
--- a/source/script/installscripts.sh
+++ b/source/script/installscripts.sh
@@ -3,7 +3,7 @@
# 5 July 96 Dan.Shearer@UniSA.Edu.Au Don't hardcode script names, get from Make
INSTALLPERMS=$1
-BINDIR=`echo $2 | sed 's/\/\//\//g'`
+BINDIR=$2
shift
shift
diff --git a/source/script/installswat.sh b/source/script/installswat.sh
index 67586a89674..8868d4cbb1f 100755
--- a/source/script/installswat.sh
+++ b/source/script/installswat.sh
@@ -1,50 +1,36 @@
#!/bin/sh
-#first version March 1998, Andrew Tridgell
+#fist version March 1998, Andrew Tridgell
-SWATDIR=`echo $1 | sed 's/\/\//\//g'`
+SWATDIR=$1
SRCDIR=$2/
BOOKDIR=$SWATDIR/using_samba
echo Installing SWAT in $SWATDIR
echo Installing the Samba Web Administration Tool
-LANGS=". `cd $SRCDIR../swat/; /bin/echo lang/??`"
-echo Installing langs are `cd $SRCDIR../swat/lang/; /bin/echo ??`
-
-for ln in $LANGS; do
- SWATLANGDIR=$SWATDIR/$ln
- for d in $SWATLANGDIR $SWATLANGDIR/help $SWATLANGDIR/images \
- $SWATLANGDIR/include; do
+for d in $SWATDIR $SWATDIR/help $SWATDIR/images $SWATDIR/include; do
if [ ! -d $d ]; then
- mkdir -p $d
+ mkdir $d
if [ ! -d $d ]; then
echo Failed to make directory $d, does $USER have privileges?
exit 1
fi
fi
- done
done
# Install images
-for ln in $LANGS; do
- for f in $SRCDIR../swat/$ln/images/*.gif; do
- if [ ! -f $f ] ; then
- continue
- fi
- FNAME=$SWATDIR/$ln/images/`basename $f`
+for f in $SRCDIR../swat/images/*.gif; do
+ FNAME=$SWATDIR/images/`basename $f`
echo $FNAME
cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
chmod 0644 $FNAME
- done
+done
- # Install html help
+# Install html help
- for f in $SRCDIR../swat/$ln/help/*.html; do
- if [ ! -f $f ] ; then
- continue
- fi
- FNAME=$SWATDIR/$ln/help/`basename $f`
+for f in $SRCDIR../swat/help/*.html; do
+ FNAME=$SWATDIR/help/`basename $f`
echo $FNAME
if [ "x$BOOKDIR" = "x" ]; then
cat $f | sed 's/@BOOKDIR@.*$//' > $f.tmp
@@ -55,70 +41,33 @@ for ln in $LANGS; do
cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
rm -f $f
chmod 0644 $FNAME
- done
+done
- # Install "server-side" includes
+# Install html documentation
- for f in $SRCDIR../swat/$ln/include/*.html; do
- if [ ! -f $f ] ; then
- continue
- fi
- FNAME=$SWATDIR/$ln/include/`basename $f`
+for f in $SRCDIR../docs/htmldocs/*.html; do
+ FNAME=$SWATDIR/help/`basename $f`
echo $FNAME
cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
chmod 0644 $FNAME
- done
-
done
-# Install html documentation (if html documentation tree is here)
+# Install "server-side" includes
-if [ -d $SRCDIR../docs/htmldocs/ ]; then
-
- for dir in htmldocs/ htmldocs/howto htmldocs/guide htmldocs/devel
- do
-
- if [ ! -d $SRCDIR../docs/$dir ]; then
- continue
- fi
-
- INSTALLDIR=$SWATDIR/help/`echo $dir | sed 's/htmldocs\///g'`
- if [ ! -d $INSTALLDIR ]; then
- mkdir $INSTALLDIR
- fi
-
- for f in $SRCDIR../docs/$dir/*.html; do
- FNAME=$INSTALLDIR/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
- done
-
- if [ -d $SRCDIR../docs/$dir/images/ ]; then
- if [ ! -d $INSTALLDIR/images/ ]; then
- mkdir $INSTALLDIR/images
- if [ ! -d $INSTALLDIR/images/ ]; then
- echo Failed to make directory $SWATDIR/help/images, does $USER have privileges?
- exit 1
- fi
- fi
- for f in $SRCDIR../docs/$dir/images/*.png; do
- FNAME=$INSTALLDIR/`basename $f`
- echo $FNAME
- cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
- chmod 0644 $FNAME
- done
- fi
- done
-fi
+for f in $SRCDIR../swat/include/*.html; do
+ FNAME=$SWATDIR/include/`basename $f`
+ echo $FNAME
+ cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
+ chmod 0644 $FNAME
+done
-# Install Using Samba book (but only if it is there)
+# Install Using Samba book
-if [ "x$BOOKDIR" != "x" -a -f $SRCDIR../docs/htmldocs/using_samba/toc.html ]; then
+if [ "x$BOOKDIR" != "x" ]; then
# Create directories
- for d in $BOOKDIR $BOOKDIR/figs ; do
+ for d in $BOOKDIR $BOOKDIR/figs $BOOKDIR/gifs; do
if [ ! -d $d ]; then
mkdir $d
if [ ! -d $d ]; then
@@ -137,17 +86,19 @@ if [ "x$BOOKDIR" != "x" -a -f $SRCDIR../docs/htmldocs/using_samba/toc.html ]; th
chmod 0644 $FNAME
done
- for f in $SRCDIR../docs/htmldocs/using_samba/*.gif; do
- FNAME=$BOOKDIR/`basename $f`
+ # Figures
+
+ for f in $SRCDIR../docs/htmldocs/using_samba/figs/*.gif; do
+ FNAME=$BOOKDIR/figs/`basename $f`
echo $FNAME
cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
chmod 0644 $FNAME
done
- # Figures
+ # Gifs
- for f in $SRCDIR../docs/htmldocs/using_samba/figs/*.gif; do
- FNAME=$BOOKDIR/figs/`basename $f`
+ for f in $SRCDIR../docs/htmldocs/using_samba/gifs/*.gif; do
+ FNAME=$BOOKDIR/gifs/`basename $f`
echo $FNAME
cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
chmod 0644 $FNAME
diff --git a/source/script/linkmodules.sh b/source/script/linkmodules.sh
deleted file mode 100755
index 16a04cc064b..00000000000
--- a/source/script/linkmodules.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-cd "$1"
-test -f "$2" || exit 0
-
-for I in $3 $4 $5 $6 $7 $8
-do
- echo "Linking $I to $2"
- ln -s $2 $I
-done
-
-exit 0
diff --git a/source/script/makeyodldocs.sh b/source/script/makeyodldocs.sh
new file mode 100755
index 00000000000..5b54df033e5
--- /dev/null
+++ b/source/script/makeyodldocs.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+SRCDIR=$1
+shift
+FILES=$@
+
+if test -z $FILES; then
+ FILES=*.yo
+fi
+
+YODLDIR=$SRCDIR/../docs/yodldocs
+MANPAGEDIR=$SRCDIR/../docs/manpages
+HTMLDIR=$SRCDIR/../docs/htmldocs
+
+echo "Re-creating man pages and HTML pages from YODL sources..."
+
+if [ ! -d $MANPAGEDIR ]; then
+ echo "directory $MANPAGEDIR does not exist, are we in the right place?"
+ exit 1
+fi
+
+if [ ! -d $HTMLDIR ]; then
+ echo "directory $HTMLDIR does not exist, are we in the right place?"
+ exit 1
+fi
+
+if [ ! -d $YODLDIR ]; then
+ echo "directory $YODLDIR does not exist, are we in the right place?"
+ exit 1
+fi
+
+cd $YODLDIR
+
+for d in $FILES
+do
+
+#
+# Create the basename from the YODL manpage
+#
+ bn=`echo $d | sed -e 's/\.yo//'`
+
+ case "$d"
+ in
+ *.[0-9].yo)
+ echo "Creating man pages..."
+ echo $d
+ rm -f $bn.man
+ yodl2man $d
+ if [ ! -f $bn.man ]; then
+ echo "Failed to make man page for $d"
+ exit 1
+ fi
+ cp $bn.man ../manpages/$bn || echo "Cannot create $YODLDIR/../manpages/$bn"
+ rm -f $bn.man
+
+ echo "Creating html versions of man pages..."
+ echo $d
+ rm -f $bn.html
+ yodl2html $d
+ if [ ! -f $bn.html ]; then
+ echo "Failed to make html page for $d"
+ exit 1
+ fi
+ cp $bn.html ../htmldocs || echo "Cannot create $YODLDIR/../htmldocs/$bn.html"
+ rm -f $bn.html
+ ;;
+ *)
+#
+# Non man-page YODL docs - just make html and text.
+#
+ echo $d
+ rm -f $bn.html
+ yodl2html $d
+ if [ ! -f $bn.html ]; then
+ echo "Failed to make html page for $d"
+ exit 1
+ fi
+ cp $bn.html ../htmldocs || echo "Cannot create $YODLDIR/../htmldocs/$bn.html"
+ rm -f $bn.html
+ rm -f $bn.txt
+ yodl2txt $d
+ if [ ! -f $bn.txt ]; then
+ echo "Failed to make text page for $d"
+ exit 1
+ fi
+ cp $bn.txt ../textdocs || echo "Cannot create $YODLDIR/../textdocs/$bn.txt"
+ rm -f $bn.txt
+ ;;
+ esac
+done
+
+echo "Remember to CVS check in your changes..."
+exit 0
diff --git a/source/script/mkbuildoptions.awk b/source/script/mkbuildoptions.awk
deleted file mode 100644
index 9c226623109..00000000000
--- a/source/script/mkbuildoptions.awk
+++ /dev/null
@@ -1,262 +0,0 @@
-BEGIN {
- print "/* ";
- print " Unix SMB/CIFS implementation.";
- print " Build Options for Samba Suite";
- print " Copyright (C) Vance Lankhaar <vlankhaar@linux.ca> 2003";
- print " Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001";
- print " ";
- print " This program is free software; you can redistribute it and/or modify";
- print " it under the terms of the GNU General Public License as published by";
- print " the Free Software Foundation; either version 2 of the License, or";
- print " (at your option) any later version.";
- print " ";
- print " This program is distributed in the hope that it will be useful,";
- print " but WITHOUT ANY WARRANTY; without even the implied warranty of";
- print " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the";
- print " GNU General Public License for more details.";
- print " ";
- print " You should have received a copy of the GNU General Public License";
- print " along with this program; if not, write to the Free Software";
- print " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.";
- print "*/";
- print "";
- print "#include \"includes.h\"";
- print "#include \"build_env.h\"";
- print "#include \"dynconfig.h\"";
- print "";
- print "static void output(BOOL screen, const char *format, ...) PRINTF_ATTRIBUTE(2,3);";
- print "";
- print "";
- print "/****************************************************************************";
- print "helper function for build_options";
- print "****************************************************************************/";
- print "static void output(BOOL screen, const char *format, ...)";
- print "{";
- print " char *ptr;";
- print " va_list ap;";
- print " ";
- print " va_start(ap, format);";
- print " vasprintf(&ptr,format,ap);";
- print " va_end(ap);";
- print "";
- print " if (screen) {";
- print " d_printf(\"%s\", ptr);";
- print " } else {";
- print " DEBUG(4,(\"%s\", ptr));";
- print " }";
- print " ";
- print " SAFE_FREE(ptr);";
- print "}";
- print "";
- print "/****************************************************************************";
- print "options set at build time for the samba suite";
- print "****************************************************************************/";
- print "void build_options(BOOL screen)";
- print "{";
- print " if ((DEBUGLEVEL < 4) && (!screen)) {";
- print " return;";
- print " }";
- print "";
- print "#ifdef _BUILD_ENV_H";
- print " /* Output information about the build environment */";
- print " output(screen,\"Build environment:\\n\");";
- print " output(screen,\" Built by: %s@%s\\n\",BUILD_ENV_USER,BUILD_ENV_HOST);";
- print " output(screen,\" Built on: %s\\n\",BUILD_ENV_DATE);";
- print "";
- print " output(screen,\" Built using: %s\\n\",BUILD_ENV_COMPILER);";
- print " output(screen,\" Build host: %s\\n\",BUILD_ENV_UNAME);";
- print " output(screen,\" SRCDIR: %s\\n\",BUILD_ENV_SRCDIR);";
- print " output(screen,\" BUILDDIR: %s\\n\",BUILD_ENV_BUILDDIR);";
- print "";
- print " ";
- print "#endif";
- print "";
-
- print " /* Output various paths to files and directories */";
- print " output(screen,\"\\nPaths:\\n\");";
-
- print " output(screen,\" SBINDIR: %s\\n\", dyn_SBINDIR);";
- print " output(screen,\" BINDIR: %s\\n\", dyn_BINDIR);";
- print " output(screen,\" SWATDIR: %s\\n\", dyn_SWATDIR);";
-
- print " output(screen,\" CONFIGFILE: %s\\n\", dyn_CONFIGFILE);";
- print " output(screen,\" LOGFILEBASE: %s\\n\", dyn_LOGFILEBASE);";
- print " output(screen,\" LMHOSTSFILE: %s\\n\",dyn_LMHOSTSFILE);";
-
- print " output(screen,\" LIBDIR: %s\\n\",dyn_LIBDIR);";
- print " output(screen,\" SHLIBEXT: %s\\n\",dyn_SHLIBEXT);";
-
- print " output(screen,\" LOCKDIR: %s\\n\",dyn_LOCKDIR);";
- print " output(screen,\" PIDDIR: %s\\n\", dyn_PIDDIR);";
-
- print " output(screen,\" SMB_PASSWD_FILE: %s\\n\",dyn_SMB_PASSWD_FILE);";
- print " output(screen,\" PRIVATE_DIR: %s\\n\",dyn_PRIVATE_DIR);";
- print "";
-
-
-##################################################
-# predefine first element of *_ary
-# predefine *_i (num of elements in *_ary)
- with_ary[0]="";
- with_i=0;
- have_ary[0]="";
- have_i=0;
- utmp_ary[0]="";
- utmp_i=0;
- misc_ary[0]="";
- misc_i=0;
- sys_ary[0]="";
- sys_i=0;
- headers_ary[0]="";
- headers_i=0;
- in_comment = 0;
-}
-
-# capture single line comments
-/^\/\* (.*?)\*\// {
- last_comment = $0;
- next;
-}
-
-# end capture multi-line comments
-/(.*?)\*\// {
- last_comment = last_comment $0;
- in_comment = 0;
- next;
-}
-
-# capture middle lines of multi-line comments
-in_comment {
- last_comment = last_comment $0;
- next;
-}
-
-# begin capture multi-line comments
-/^\/\* (.*?)/ {
- last_comment = $0;
- in_comment = 1;
- next
-}
-
-##################################################
-# if we have an #undef and a last_comment, store it
-/^\#undef/ {
- split($0,a);
- comments_ary[a[2]] = last_comment;
- last_comment = "";
-}
-
-##################################################
-# for each line, sort into appropriate section
-# then move on
-
-/^\#undef WITH/ {
- with_ary[with_i++] = a[2];
- # we want (I think) to allow --with to show up in more than one place, so no next
-}
-
-
-/^\#undef HAVE_UT_UT_/ || /^\#undef .*UTMP/ {
- utmp_ary[utmp_i++] = a[2];
- next;
-}
-
-/^\#undef HAVE_SYS_.*?_H$/ {
- sys_ary[sys_i++] = a[2];
- next;
-}
-
-/^\#undef HAVE_.*?_H$/ {
- headers_ary[headers_i++] = a[2];
- next;
-}
-
-/^\#undef HAVE_/ {
- have_ary[have_i++] = a[2];
- next;
-}
-
-/^\#undef/ {
- misc_ary[misc_i++] = a[2];
- next;
-}
-
-
-##################################################
-# simple sort function
-function sort(ARRAY, ELEMENTS) {
- for (i = 1; i <= ELEMENTS; ++i) {
- for (j = i; (j-1) in ARRAY && (j) in ARRAY && ARRAY[j-1] > ARRAY[j]; --j) {
- temp = ARRAY[j];
- ARRAY[j] = ARRAY[j-1];
- ARRAY[j-1] = temp;
- }
- }
- return;
-}
-
-
-##################################################
-# output code from list of defined
-# expects: ARRAY an array of things defined
-# ELEMENTS number of elements in ARRAY
-# TITLE title for section
-# returns: nothing
-function output(ARRAY, ELEMENTS, TITLE) {
-
- # add section header
- print "\n\t/* Show " TITLE " */";
- print "\toutput(screen, \"\\n " TITLE ":\\n\");\n";
-
-
- # sort element using bubble sort (slow, but easy)
- sort(ARRAY, ELEMENTS);
-
- # loop through array of defines, outputting code
- for (i = 0; i < ELEMENTS; i++) {
- print "#ifdef " ARRAY[i];
-
- # I don't know which one to use....
-
- print "\toutput(screen, \" " ARRAY[i] "\\n\");";
- #printf "\toutput(screen, \" %s\\n %s\\n\\n\");\n", comments_ary[ARRAY[i]], ARRAY[i];
- #printf "\toutput(screen, \" %-35s %s\\n\");\n", ARRAY[i], comments_ary[ARRAY[i]];
-
- print "#endif";
- }
- return;
-}
-
-END {
- ##################################################
- # add code to show various options
- print "/* Output various other options (as gleaned from include/config.h.in) */";
- output(sys_ary, sys_i, "System Headers");
- output(headers_ary, headers_i, "Headers");
- output(utmp_ary, utmp_i, "UTMP Options");
- output(have_ary, have_i, "HAVE_* Defines");
- output(with_ary, with_i, "--with Options");
- output(misc_ary, misc_i, "Build Options");
-
- ##################################################
- # add code to display the various type sizes
- print " /* Output the sizes of the various types */";
- print " output(screen, \"\\nType sizes:\\n\");";
- print " output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));";
- print " output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));";
- print " output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));";
- print " output(screen, \" sizeof(uint8): %lu\\n\",(unsigned long)sizeof(uint8));";
- print " output(screen, \" sizeof(uint16): %lu\\n\",(unsigned long)sizeof(uint16));";
- print " output(screen, \" sizeof(uint32): %lu\\n\",(unsigned long)sizeof(uint32));";
- print " output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));";
- print " output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));";
-
- ##################################################
- # add code to give information about modules
- print " output(screen, \"\\nBuiltin modules:\\n\");";
- print " output(screen, \" %s\\n\", STRING_STATIC_MODULES);";
-
- print "}";
-
-}
-
diff --git a/source/script/mkinstalldirs b/source/script/mkinstalldirs
deleted file mode 100755
index f945dbf2bce..00000000000
--- a/source/script/mkinstalldirs
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-errstatus=0
-
-for file
-do
- set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
- shift
-
- pathcomp=
- for d
- do
- pathcomp="$pathcomp$d"
- case "$pathcomp" in
- -* ) pathcomp=./$pathcomp ;;
- esac
-
- if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp" 1>&2
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- fi
- fi
-
- pathcomp="$pathcomp/"
- done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index b38f405e0da..af230400935 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -8,14 +8,12 @@ BEGIN {
print "#ifndef",headername
print "#define",headername
- print ""
print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
print ""
}
END {
- print ""
- print "#endif /* ",headername," */"
+ print "#endif /* _PROTO_H_ */"
}
{
@@ -41,6 +39,20 @@ END {
}
}
+# special handling for code merge of TNG to head
+/^#define OLD_NTDOMAIN 1/ {
+ printf "#if OLD_NTDOMAIN\n"
+}
+/^#undef OLD_NTDOMAIN/ {
+ printf "#endif\n"
+}
+/^#define NEW_NTDOMAIN 1/ {
+ printf "#if NEW_NTDOMAIN\n"
+}
+/^#undef NEW_NTDOMAIN/ {
+ printf "#endif\n"
+}
+
# we handle the loadparm.c fns separately
/^FN_LOCAL_BOOL/ {
@@ -48,21 +60,11 @@ END {
printf "BOOL %s(int );\n", a[2]
}
-/^FN_LOCAL_LIST/ {
- split($0,a,"[,()]")
- printf "const char **%s(int );\n", a[2]
-}
-
/^FN_LOCAL_STRING/ {
split($0,a,"[,()]")
printf "char *%s(int );\n", a[2]
}
-/^FN_LOCAL_CONST_STRING/ {
- split($0,a,"[,()]")
- printf "const char *%s(int );\n", a[2]
-}
-
/^FN_LOCAL_INT/ {
split($0,a,"[,()]")
printf "int %s(int );\n", a[2]
@@ -78,21 +80,11 @@ END {
printf "BOOL %s(void);\n", a[2]
}
-/^FN_GLOBAL_LIST/ {
- split($0,a,"[,()]")
- printf "const char **%s(void);\n", a[2]
-}
-
/^FN_GLOBAL_STRING/ {
split($0,a,"[,()]")
printf "char *%s(void);\n", a[2]
}
-/^FN_GLOBAL_CONST_STRING/ {
- split($0,a,"[,()]")
- printf "const char *%s(void);\n", a[2]
-}
-
/^FN_GLOBAL_INT/ {
split($0,a,"[,()]")
printf "int %s(void);\n", a[2]
@@ -112,7 +104,7 @@ END {
{
gotstart = 0;
- if( $0 ~ /^const|^connection_struct|^pipes_struct|^smb_np_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t|^double/ ) {
+ if( $0 ~ /^const|^connection_struct|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
gotstart = 1;
}
@@ -120,19 +112,15 @@ END {
gotstart = 1;
}
- if( $0 ~ /^ADS_STRUCT|^ADS_STATUS|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT|^NTTIME/ ) {
- gotstart = 1;
- }
-
- if( $0 ~ /^smb_iconv_t|^long|^char|^uint|^NTSTATUS|^WERROR|^CLI_POLICY_HND|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^XFILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
+ if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
gotstart = 1;
}
- if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^DEVICEMODE|^PAC_DATA|^NET_USER_INFO_3|^smb_event_id_t/ ) {
+ if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
gotstart = 1;
}
- if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE/ ) {
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^NTSTATUS|^WERROR|^CLI_POLICY_HND|^DATA_BLOB/ ) {
gotstart = 1;
}
diff --git a/source/script/mkproto.sh b/source/script/mkproto.sh
index 62041c7e331..4dbe4c204e7 100755
--- a/source/script/mkproto.sh
+++ b/source/script/mkproto.sh
@@ -25,12 +25,10 @@ header="$1"
shift
headertmp="$header.$$.tmp~"
-proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -v 'ubiqx/|wrapped|modules/getdate'`"
+proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -v 'ubiqx/|wrapped'`"
echo creating $header
-mkdir -p `dirname $header`
-
${awk} $headeropt \
-f script/mkproto.awk $proto_src > $headertmp
diff --git a/source/script/mksmbpasswd.sh b/source/script/mksmbpasswd.sh
index 119a55611ec..854e1bd1b57 100755
--- a/source/script/mksmbpasswd.sh
+++ b/source/script/mksmbpasswd.sh
@@ -2,5 +2,5 @@
awk 'BEGIN {FS=":"
printf("#\n# SMB password file.\n#\n")
}
-{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[UD ]:LCT-00000000:%s\n", $1, $3, $5) }
+{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:%s\n", $1, $3, $5) }
'
diff --git a/source/script/mkversion.sh b/source/script/mkversion.sh
deleted file mode 100755
index 917a9ed1ae3..00000000000
--- a/source/script/mkversion.sh
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/sh
-#
-
-VERSION_FILE=$1
-OUTPUT_FILE=$2
-
-if test -z "$VERSION_FILE";then
- VERSION_FILE="VERSION"
-fi
-
-if test -z "$OUTPUT_FILE";then
- OUTPUT_FILE="include/version.h"
-fi
-
-SOURCE_DIR=$3
-
-SAMBA_VERSION_MAJOR=`sed -n 's/^SAMBA_VERSION_MAJOR=//p' $SOURCE_DIR$VERSION_FILE`
-SAMBA_VERSION_MINOR=`sed -n 's/^SAMBA_VERSION_MINOR=//p' $SOURCE_DIR$VERSION_FILE`
-SAMBA_VERSION_RELEASE=`sed -n 's/^SAMBA_VERSION_RELEASE=//p' $SOURCE_DIR$VERSION_FILE`
-
-SAMBA_VERSION_PRE_RELEASE=`sed -n 's/^SAMBA_VERSION_PRE_RELEASE=//p' $SOURCE_DIR$VERSION_FILE`
-
-SAMBA_VERSION_RC_RELEASE=`sed -n 's/^SAMBA_VERSION_RC_RELEASE=//p' $SOURCE_DIR$VERSION_FILE`
-
-SAMBA_VERSION_IS_SVN_SNAPSHOT=`sed -n 's/^SAMBA_VERSION_IS_SVN_SNAPSHOT=//p' $SOURCE_DIR$VERSION_FILE`
-
-SAMBA_VERSION_VENDOR_SUFFIX=`sed -n 's/^SAMBA_VERSION_VENDOR_SUFFIX=//p' $SOURCE_DIR$VERSION_FILE`
-
-echo "/* Autogenerated by script/mkversion.sh */" > $OUTPUT_FILE
-
-echo "#define SAMBA_VERSION_MAJOR ${SAMBA_VERSION_MAJOR}" >> $OUTPUT_FILE
-echo "#define SAMBA_VERSION_MINOR ${SAMBA_VERSION_MINOR}" >> $OUTPUT_FILE
-echo "#define SAMBA_VERSION_RELEASE ${SAMBA_VERSION_RELEASE}" >> $OUTPUT_FILE
-
-
-SAMBA_VERSION_STRING="${SAMBA_VERSION_MAJOR}.${SAMBA_VERSION_MINOR}.${SAMBA_VERSION_RELEASE}"
-
-
-if test -n "${SAMBA_VERSION_PRE_RELEASE}";then
- SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}pre${SAMBA_VERSION_PRE_RELEASE}"
- echo "#define SAMBA_VERSION_PRE_RELEASE ${SAMBA_VERSION_PRE_RELEASE}" >> $OUTPUT_FILE
-elif test -n "${SAMBA_VERSION_RC_RELEASE}";then
- SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}rc${SAMBA_VERSION_RC_RELEASE}"
- echo "#define SAMBA_VERSION_RC_RELEASE ${SAMBA_VERSION_RC_RELEASE}" >> $OUTPUT_FILE
-fi
-
-
-if test x"${SAMBA_VERSION_IS_SVN_SNAPSHOT}" = x"yes";then
- HAVESVN=no
- svn info ${SOURCE_DIR} >/dev/null 2>&1 && HAVESVN=yes
- TMP_REVISION=`(svn info ${SOURCE_DIR} 2>/dev/null || svk info ${SOURCE_DIR} 2>/dev/null) |grep Revision: |sed -e 's/Revision: \([0-9]*\).*/\1/'`
- if test x"${HAVESVN}" = x"no";then
- HAVESVK=no
- svk info ${SOURCE_DIR} >/dev/null 2>&1 && HAVESVK=yes
- TMP_SVK_REVISION_STR="${TMP_REVISION}-${USER}@${HOSTNAME}"
- fi
-
- if test x"${HAVESVN}" = x"yes";then
- SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-SVN-build-${TMP_REVISION}"
- echo "#define SAMBA_VERSION_SVN_REVISION ${TMP_REVISION}" >> $OUTPUT_FILE
- elif test x"${HAVESVK}" = x"yes";then
- SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-SVK-build-${TMP_SVK_REVISION_STR}"
- else
- SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-SVN-build-UNKNOWN"
- fi
-fi
-
-if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then
- echo "#define SAMBA_VERSION_VENDOR_SUFFIX ${SAMBA_VERSION_VENDOR_SUFFIX}" >> $OUTPUT_FILE
-fi
-
-echo "#define SAMBA_VERSION_OFFICIAL_STRING \"${SAMBA_VERSION_STRING}\"" >> $OUTPUT_FILE
-
-echo "#define SAMBA_VERSION_STRING samba_version_string()" >> $OUTPUT_FILE
-
-echo "$0: 'include/version.h' created for Samba(\"${SAMBA_VERSION_STRING}\")"
-
-if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then
- echo "$0: with VENDOR_SUFFIX = ${SAMBA_VERSION_VENDOR_SUFFIX}"
-fi
-
-exit 0
diff --git a/source/script/smbadduser b/source/script/smbadduser
new file mode 100755
index 00000000000..57ef7091ba9
--- /dev/null
+++ b/source/script/smbadduser
@@ -0,0 +1,76 @@
+#!/bin/csh
+#
+# smbadduser - Written by Mike Zakharoff
+#
+unalias *
+set path = ($path /usr/local/samba/bin)
+
+set smbpasswd = /usr/local/samba/private/smbpasswd
+#set smbpasswd = /etc/samba.d/smbpasswd
+set user_map = /usr/local/samba/lib/users.map
+#set user_map = /etc/samba.d/smbusers
+#
+# Set to site specific passwd command
+#
+set passwd = "cat /etc/passwd"
+#set passwd = "niscat passwd.org_dir"
+#set passwd = "ypcat passwd"
+
+set line = "----------------------------------------------------------"
+if ($#argv == 0) then
+ echo $line
+ echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
+ echo ""
+ echo " 1) Updates $smbpasswd"
+ echo " 2) Updates $user_map"
+ echo " 3) Executes smbpasswd for each new user"
+ echo ""
+ echo "smbadduser unixid:ntid unixid:ntid ..."
+ echo ""
+ echo "Example: smbadduser zak:zakharoffm johns:smithj"
+ echo $line
+ exit 1
+endif
+
+touch $smbpasswd $user_map
+set new = ()
+foreach one ($argv)
+ echo $one | grep ':' >& /dev/null
+ if ($status != 0) then
+ echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
+ continue
+ endif
+ set unix = `echo $one | awk -F: '{print $1}'`
+ set ntid = `echo $one | awk -F: '{print $2}'`
+
+ set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#usr != 1) then
+ echo "ERROR: $unix Not in passwd database SKIPPING..."
+ continue
+ endif
+ set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#tmp != 0) then
+ echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
+ continue
+ endif
+
+ echo "Adding: $unix to $smbpasswd"
+# eval $passwd | \
+# awk -F: '$1==USR { \
+# printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
+ /usr/bin/smbpasswd -a -n $unix
+ if ($unix != $ntid) then
+ echo "Adding: {$unix = $ntid} to $user_map"
+ echo "$unix = $ntid" >> $user_map
+ endif
+ set new = ($new $unix)
+end
+
+#
+# Enter password for new users
+#
+foreach one ($new)
+ echo $line
+ echo "ENTER password for $one"
+ smbpasswd $one
+end
diff --git a/source/script/smbtar b/source/script/smbtar
index 67a794553cf..f062cba9f04 100644
--- a/source/script/smbtar
+++ b/source/script/smbtar
@@ -161,5 +161,5 @@ fi
tarargs=${tarargs}${blocksizearg}${newerarg}
eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \
--E $log -D "'$cdcmd'" ${clientargs} \
+-E -N $log -D "'$cdcmd'" ${clientargs} \
-T${tarcmd}${tarargs} $blocksize $newer $tapefile '${1+"$@"}' $verbose
diff --git a/source/script/uninstallbin.sh b/source/script/uninstallbin.sh
index 5de936fccfd..53775f89465 100755
--- a/source/script/uninstallbin.sh
+++ b/source/script/uninstallbin.sh
@@ -2,10 +2,10 @@
#4 July 96 Dan.Shearer@UniSA.edu.au
INSTALLPERMS=$1
-BASEDIR=`echo $2 | sed 's/\/\//\//g'`
-BINDIR=`echo $3 | sed 's/\/\//\//g'`
-LIBDIR=`echo $4 | sed 's/\/\//\//g'`
-VARDIR=`echo $5 | sed 's/\/\//\//g'`
+BASEDIR=$2
+BINDIR=$3
+LIBDIR=$4
+VARDIR=$5
shift
shift
shift
@@ -34,8 +34,8 @@ cat << EOF
======================================================================
The binaries have been uninstalled. You may restore the binaries using
the command "make installbin" or "make install" to install binaries,
-man pages, modules and shell scripts. You can restore a previous
-version of the binaries (if there were any) using "make revert".
+man pages and shell scripts. You can restore a previous version of the
+binaries (if there were any) using "make revert".
======================================================================
EOF
diff --git a/source/script/uninstallcp.sh b/source/script/uninstallcp.sh
new file mode 100755
index 00000000000..2a9e9d509ab
--- /dev/null
+++ b/source/script/uninstallcp.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+CPDIR=$1
+shift
+
+if [ ! -d $CPDIR ]; then
+ echo Directory $CPDIR does not exist!
+ echo Do a "make installcp" or "make install" first.
+ exit 1
+fi
+
+for p in $*; do
+ if [ ! -f $CPDIR/unicode_map.$p ]; then
+ echo $CPDIR/unicode_map.$p does not exist!
+ else
+ echo Removing $CPDIR/unicode_map.$p
+ rm -f $CPDIR/unicode_map.$p
+ if [ -f $CPDIR/unicode_map.$p ]; then
+ echo Cannot remove $CPDIR/unicode_map.$p... does $USER have privileges?
+ fi
+ fi
+done
+
+cat << EOF
+======================================================================
+The code pages have been uninstalled. You may reinstall them using
+the command "make installcp" or "make install" to install binaries,
+man pages, shell scripts and code pages. You may recover a previous version
+(if any with "make revert").
+======================================================================
+EOF
+
+exit 0
diff --git a/source/script/uninstallman.sh b/source/script/uninstallman.sh
index 0fea11cd1b2..873ca4f7208 100755
--- a/source/script/uninstallman.sh
+++ b/source/script/uninstallman.sh
@@ -1,28 +1,20 @@
#!/bin/sh
#4 July 96 Dan.Shearer@UniSA.edu.au
-#
-# 13 Aug 2001 Rafal Szczesniak <mimir@spin.ict.pwr.wroc.pl>
-# modified to accomodate international man pages (inspired
-# by Japanese edition's approach)
-
-MANDIR=`echo $1 | sed 's/\/\//\//g'`
+MANDIR=$1
SRCDIR=$2
-langs=$3
-for lang in $langs; do
- echo Uninstalling \"$lang\" man pages from $MANDIR/$lang
+echo Uninstalling man pages from $MANDIR
- for sect in 1 5 7 8 ; do
- for m in $MANDIR/$lang/man$sect ; do
- for s in $SRCDIR/../docs/manpages/$lang/*$sect; do
- FNAME=$m/`basename $s`
- if test -f $FNAME; then
- echo Deleting $FNAME
- rm -f $FNAME
- test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?
- fi
- done
+for sect in 1 5 7 8 ; do
+ for m in $MANDIR/man$sect ; do
+ for s in $SRCDIR/../docs/manpages/*$sect; do
+ FNAME=$m/`basename $s`
+ if test -f $FNAME; then
+ echo Deleting $FNAME
+ rm -f $FNAME
+ test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?
+ fi
done
done
done
diff --git a/source/script/uninstallmodules.sh b/source/script/uninstallmodules.sh
deleted file mode 100755
index ac83af3dc90..00000000000
--- a/source/script/uninstallmodules.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-#4 July 96 Dan.Shearer@UniSA.edu.au
-
-INSTALLPERMS=$1
-BASEDIR=`echo $2 | sed 's/\/\//\//g'`
-LIBDIR=`echo $3 | sed 's/\/\//\//g'`
-shift
-shift
-shift
-
-if [ ! -d $LIBDIR ]; then
- echo Directory $LIBDIR does not exist!
- echo Do a "make installmodules" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- p2=`basename $p`
- if [ -f $LIBDIR/$p2 ]; then
- echo Removing $LIBDIR/$p2
- rm -f $LIBDIR/$p2
- if [ -f $LIBDIR/$p2 ]; then
- echo Cannot remove $LIBDIR/$p2 ... does $USER have privileges?
- fi
- fi
-done
-
-
-cat << EOF
-======================================================================
-The modules have been uninstalled. You may restore the modules using
-the command "make installmodules" or "make install" to install
-binaries, modules, man pages and shell scripts.
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/uninstallscripts.sh b/source/script/uninstallscripts.sh
index cf7fd719993..13104acedd8 100755
--- a/source/script/uninstallscripts.sh
+++ b/source/script/uninstallscripts.sh
@@ -2,7 +2,7 @@
# 5 July 96 Dan.Shearer@UniSA.Edu.Au - almost identical to uninstallbin.sh
INSTALLPERMS=$1
-BINDIR=`echo $2 | sed 's/\/\//\//g'`
+BINDIR=$2
shift
shift
diff --git a/source/script/updatesmbpasswd.sh b/source/script/updatesmbpasswd.sh
deleted file mode 100755
index 1d7e0d7332f..00000000000
--- a/source/script/updatesmbpasswd.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-nawk 'BEGIN {FS=":"}
-{
- if( $0 ~ "^#" ) {
- print $0
- } else if( (length($4) == 32) && (($4 ~ "^[0-9A-F]*$") || ($4 ~ "^[X]*$") || ( $4 ~ "^[*]*$"))) {
- print $0
- } else {
- printf( "%s:%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", $1, $2, $3);
- for(i = 4; i <= NF; i++)
- printf("%s:", $i)
- printf("\n")
- }
-}'
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index c0512d5539b..1f6602502da 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
Blocking Locking functions
- Copyright (C) Jeremy Allison 1998-2003
+ Copyright (C) Jeremy Allison 1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,16 +28,16 @@ extern char *OutBuffer;
*****************************************************************************/
typedef struct {
- ubi_slNode msg_next;
- int com_type;
- files_struct *fsp;
- time_t expire_time;
- int lock_num;
- SMB_BIG_UINT offset;
- SMB_BIG_UINT count;
- uint16 lock_pid;
- char *inbuf;
- int length;
+ ubi_slNode msg_next;
+ int com_type;
+ files_struct *fsp;
+ time_t expire_time;
+ int lock_num;
+ SMB_BIG_UINT offset;
+ SMB_BIG_UINT count;
+ uint16 lock_pid;
+ char *inbuf;
+ int length;
} blocking_lock_record;
static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0};
@@ -48,8 +48,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu
static void free_blocking_lock_record(blocking_lock_record *blr)
{
- SAFE_FREE(blr->inbuf);
- SAFE_FREE(blr);
+ SAFE_FREE(blr->inbuf);
+ SAFE_FREE(blr);
}
/****************************************************************************
@@ -58,17 +58,17 @@ static void free_blocking_lock_record(blocking_lock_record *blr)
static files_struct *get_fsp_from_pkt(char *inbuf)
{
- switch(CVAL(inbuf,smb_com)) {
- case SMBlock:
- case SMBlockread:
- return file_fsp(inbuf,smb_vwv0);
- case SMBlockingX:
- return file_fsp(inbuf,smb_vwv2);
- default:
- DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n"));
- exit_server("PANIC - unknown type on blocking lock queue");
- }
- return NULL; /* Keep compiler happy. */
+ switch(CVAL(inbuf,smb_com)) {
+ case SMBlock:
+ case SMBlockread:
+ return file_fsp(inbuf,smb_vwv0);
+ case SMBlockingX:
+ return file_fsp(inbuf,smb_vwv2);
+ default:
+ DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n"));
+ exit_server("PANIC - unknown type on blocking lock queue");
+ }
+ return NULL; /* Keep compiler happy. */
}
/****************************************************************************
@@ -77,7 +77,7 @@ static files_struct *get_fsp_from_pkt(char *inbuf)
static BOOL in_chained_smb(void)
{
- return (chain_size != 0);
+ return (chain_size != 0);
}
static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len);
@@ -89,69 +89,66 @@ static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len);
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count)
{
- static BOOL set_lock_msg;
- blocking_lock_record *blr;
- BOOL my_lock_ctx = False;
- NTSTATUS status;
-
- if(in_chained_smb() ) {
- DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
- return False;
- }
-
- /*
- * Now queue an entry on the blocking lock queue. We setup
- * the expiration time here.
- */
-
- if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
- return False;
- }
-
- if((blr->inbuf = (char *)malloc(length)) == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
- SAFE_FREE(blr);
- return False;
- }
-
- blr->com_type = CVAL(inbuf,smb_com);
- blr->fsp = get_fsp_from_pkt(inbuf);
- blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
- blr->lock_num = lock_num;
- blr->lock_pid = lock_pid;
- blr->offset = offset;
- blr->count = count;
- memcpy(blr->inbuf, inbuf, length);
- blr->length = length;
-
- /* Add a pending lock record for this. */
- status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- offset, count, PENDING_LOCK, &my_lock_ctx);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
- free_blocking_lock_record(blr);
- return False;
- }
+ static BOOL set_lock_msg;
+ blocking_lock_record *blr;
+ NTSTATUS status;
+
+ if(in_chained_smb() ) {
+ DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
+ return False;
+ }
+
+ /*
+ * Now queue an entry on the blocking lock queue. We setup
+ * the expiration time here.
+ */
+
+ if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) {
+ DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
+ return False;
+ }
+
+ if((blr->inbuf = (char *)malloc(length)) == NULL) {
+ DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
+ SAFE_FREE(blr);
+ return False;
+ }
+
+ blr->com_type = CVAL(inbuf,smb_com);
+ blr->fsp = get_fsp_from_pkt(inbuf);
+ blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
+ blr->lock_num = lock_num;
+ blr->lock_pid = lock_pid;
+ blr->offset = offset;
+ blr->count = count;
+ memcpy(blr->inbuf, inbuf, length);
+ blr->length = length;
+
+ /* Add a pending lock record for this. */
+ status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ offset, count,
+ PENDING_LOCK);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
+ free_blocking_lock_record(blr);
+ return False;
+ }
- ubi_slAddTail(&blocking_lock_queue, blr);
+ ubi_slAddTail(&blocking_lock_queue, blr);
- /* Ensure we'll receive messages when this is unlocked. */
- if (!set_lock_msg) {
- message_register(MSG_SMB_UNLOCK, received_unlock_msg);
- set_lock_msg = True;
- }
+ /* Ensure we'll receive messages when this is unlocked. */
+ if (!set_lock_msg) {
+ message_register(MSG_SMB_UNLOCK, received_unlock_msg);
+ set_lock_msg = True;
+ }
- DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
+ DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
- blr->fsp->fnum, blr->fsp->fsp_name ));
+ blr->fsp->fnum, blr->fsp->fsp_name ));
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
-
- return True;
+ return True;
}
/****************************************************************************
@@ -173,27 +170,27 @@ static void send_blocking_reply(char *outbuf, int outsize)
static void reply_lockingX_success(blocking_lock_record *blr)
{
- char *outbuf = OutBuffer;
- int bufsize = BUFFER_SIZE;
- char *inbuf = blr->inbuf;
- int outsize = 0;
+ char *outbuf = OutBuffer;
+ int bufsize = BUFFER_SIZE;
+ char *inbuf = blr->inbuf;
+ int outsize = 0;
- construct_reply_common(inbuf, outbuf);
- set_message(outbuf,2,0,True);
+ construct_reply_common(inbuf, outbuf);
+ set_message(outbuf,2,0,True);
- /*
- * As this message is a lockingX call we must handle
- * any following chained message correctly.
- * This is normally handled in construct_reply(),
- * but as that calls switch_message, we can't use
- * that here and must set up the chain info manually.
- */
+ /*
+ * As this message is a lockingX call we must handle
+ * any following chained message correctly.
+ * This is normally handled in construct_reply(),
+ * but as that calls switch_message, we can't use
+ * that here and must set up the chain info manually.
+ */
- outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
+ outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
- outsize += chain_size;
+ outsize += chain_size;
- send_blocking_reply(outbuf,outsize);
+ send_blocking_reply(outbuf,outsize);
}
/****************************************************************************
@@ -303,7 +300,6 @@ static BOOL process_lockread(blocking_lock_record *blr)
NTSTATUS status;
connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
files_struct *fsp = blr->fsp;
- BOOL my_lock_ctx = False;
numtoread = SVAL(inbuf,smb_vwv1);
startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2);
@@ -311,7 +307,8 @@ static BOOL process_lockread(blocking_lock_record *blr)
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
- status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, &my_lock_ctx);
+ status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread,
+ startpos, READ_LOCK);
if (NT_STATUS_V(status)) {
if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
!NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
@@ -372,13 +369,13 @@ static BOOL process_lock(blocking_lock_record *blr)
NTSTATUS status;
connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
files_struct *fsp = blr->fsp;
- BOOL my_lock_ctx = False;
- count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
- offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
+ offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
errno = 0;
- status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
+ status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count,
+ offset, WRITE_LOCK);
if (NT_STATUS_IS_ERR(status)) {
if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
!NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
@@ -429,7 +426,6 @@ static BOOL process_lockingX(blocking_lock_record *blr)
uint16 lock_pid;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
char *data;
- BOOL my_lock_ctx = False;
NTSTATUS status = NT_STATUS_OK;
data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
@@ -452,7 +448,7 @@ static BOOL process_lockingX(blocking_lock_record *blr)
*/
errno = 0;
status = do_lock_spin(fsp,conn,lock_pid,count,offset,
- ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
+ ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
if (NT_STATUS_IS_ERR(status)) break;
}
@@ -496,18 +492,18 @@ Waiting....\n",
static BOOL blocking_lock_record_process(blocking_lock_record *blr)
{
- switch(blr->com_type) {
- case SMBlock:
- return process_lock(blr);
- case SMBlockread:
- return process_lockread(blr);
- case SMBlockingX:
- return process_lockingX(blr);
- default:
- DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
- exit_server("PANIC - unknown type on blocking lock queue");
- }
- return False; /* Keep compiler happy. */
+ switch(blr->com_type) {
+ case SMBlock:
+ return process_lock(blr);
+ case SMBlockread:
+ return process_lockread(blr);
+ case SMBlockingX:
+ return process_lockingX(blr);
+ default:
+ DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
+ exit_server("PANIC - unknown type on blocking lock queue");
+ }
+ return False; /* Keep compiler happy. */
}
/****************************************************************************
@@ -516,27 +512,27 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
void remove_pending_lock_requests_by_fid(files_struct *fsp)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
- while(blr != NULL) {
- if(blr->fsp->fnum == fsp->fnum) {
+ while(blr != NULL) {
+ if(blr->fsp->fnum == fsp->fnum) {
- DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
+ DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
+ brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
/****************************************************************************
@@ -545,32 +541,32 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
void remove_pending_lock_requests_by_mid(int mid)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
- while(blr != NULL) {
- if(SVAL(blr->inbuf,smb_mid) == mid) {
- files_struct *fsp = blr->fsp;
+ while(blr != NULL) {
+ if(SVAL(blr->inbuf,smb_mid) == mid) {
+ files_struct *fsp = blr->fsp;
- DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
+ DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
- brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ blocking_lock_reply_error(blr,NT_STATUS_CANCELLED);
+ brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
/****************************************************************************
- Set a flag as an unlock request affects one of our pending locks.
+ Set a flag as an unlock request affects one of our pending locks.
*****************************************************************************/
static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len)
@@ -580,7 +576,7 @@ static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len)
}
/****************************************************************************
- Return the number of seconds to the next blocking locks timeout, or default_timeout
+ Return the number of seconds to the next blocking locks timeout, or default_timeout.
*****************************************************************************/
unsigned blocking_locks_timeout(unsigned default_timeout)
@@ -596,8 +592,8 @@ unsigned blocking_locks_timeout(unsigned default_timeout)
t = time(NULL);
while (blr) {
- if ((blr->expire_time != (time_t)-1) &&
- (timeout > (blr->expire_time - t))) {
+ if ((blr->expire_time != (time_t)-1) &&
+ (timeout > (blr->expire_time - t))) {
timeout = blr->expire_time - t;
}
blr = (blocking_lock_record *)ubi_slNext(blr);
@@ -615,112 +611,112 @@ unsigned blocking_locks_timeout(unsigned default_timeout)
void process_blocking_lock_queue(time_t t)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
-
- if(blr == NULL)
- return;
-
- /*
- * Go through the queue and see if we can get any of the locks.
- */
-
- while(blr != NULL) {
- connection_struct *conn = NULL;
- uint16 vuid;
- files_struct *fsp = NULL;
-
- /*
- * Ensure we don't have any old chain_fsp values
- * sitting around....
- */
- chain_size = 0;
- file_chain_reset();
- fsp = blr->fsp;
-
- conn = conn_find(SVAL(blr->inbuf,smb_tid));
- vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
- SVAL(blr->inbuf,smb_uid);
-
- DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
- fsp->fnum, fsp->fsp_name ));
-
- if((blr->expire_time != -1) && (blr->expire_time <= t)) {
- /*
- * Lock expired - throw away all previously
- * obtained locks and return lock error.
- */
- DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
- fsp->fnum, fsp->fsp_name ));
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- if(!change_to_user(conn,vuid)) {
- DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
- vuid ));
- /*
- * Remove the entry and return an error to the client.
- */
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- if(!set_current_service(conn,True)) {
- DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
- /*
- * Remove the entry and return an error to the client.
- */
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- change_to_root_user();
- continue;
- }
-
- /*
- * Go through the remaining locks and try and obtain them.
- * The call returns True if all locks were obtained successfully
- * and False if we still need to wait.
- */
-
- if(blocking_lock_record_process(blr)) {
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- change_to_root_user();
- continue;
- }
-
- change_to_root_user();
-
- /*
- * Move to the next in the list.
- */
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
+
+ if(blr == NULL)
+ return;
+
+ /*
+ * Go through the queue and see if we can get any of the locks.
+ */
+
+ while(blr != NULL) {
+ connection_struct *conn = NULL;
+ uint16 vuid;
+ files_struct *fsp = NULL;
+
+ /*
+ * Ensure we don't have any old chain_fsp values
+ * sitting around....
+ */
+ chain_size = 0;
+ file_chain_reset();
+ fsp = blr->fsp;
+
+ conn = conn_find(SVAL(blr->inbuf,smb_tid));
+ vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
+ SVAL(blr->inbuf,smb_uid);
+
+ DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
+ fsp->fnum, fsp->fsp_name ));
+
+ if((blr->expire_time != -1) && (blr->expire_time <= t)) {
+ /*
+ * Lock expired - throw away all previously
+ * obtained locks and return lock error.
+ */
+ DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
+ fsp->fnum, fsp->fsp_name ));
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ if(!change_to_user(conn,vuid)) {
+ DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
+ vuid ));
+ /*
+ * Remove the entry and return an error to the client.
+ */
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ if(!set_current_service(conn,True)) {
+ DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
+ /*
+ * Remove the entry and return an error to the client.
+ */
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ change_to_root_user();
+ continue;
+ }
+
+ /*
+ * Go through the remaining locks and try and obtain them.
+ * The call returns True if all locks were obtained successfully
+ * and False if we still need to wait.
+ */
+
+ if(blocking_lock_record_process(blr)) {
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ change_to_root_user();
+ continue;
+ }
+
+ change_to_root_user();
+
+ /*
+ * Move to the next in the list.
+ */
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
diff --git a/source/smbd/change_trust_pw.c b/source/smbd/change_trust_pw.c
deleted file mode 100644
index 1178400e4db..00000000000
--- a/source/smbd/change_trust_pw.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Periodic Trust account password changing.
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1998.
- * Copyright (C) Andrew Bartlett 2001.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/************************************************************************
- Change the trust account password for a domain.
-************************************************************************/
-
-NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct in_addr pdc_ip;
- fstring dc_name;
- struct cli_state *cli;
-
- DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n",
- domain));
-
- if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
- /* Use the PDC *only* for this */
-
- if ( !get_pdc_ip(domain, &pdc_ip) ) {
- DEBUG(0,("Can't get IP for PDC for domain %s\n", domain));
- goto failed;
- }
-
- if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
- goto failed;
- } else {
- /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
- fstrcpy( dc_name, remote_machine );
- }
-
- /* if this next call fails, then give up. We can't do
- password changes on BDC's --jerry */
-
- if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name,
- NULL, 0,
- "IPC$", "IPC",
- "", "",
- "", 0, Undefined, NULL))) {
- DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto failed;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- if(cli_nt_session_open(cli, PI_NETLOGON) == False) {
- DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
- dc_name, cli_errstr(cli)));
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
- cli_shutdown(cli);
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto failed;
- }
-
- nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx, domain);
-
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
- cli_shutdown(cli);
-
-failed:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n",
- timestring(False), domain));
- }
- else
- DEBUG(5,("change_trust_account_password: sucess!\n"));
-
- return nt_status;
-}
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index ca13a167fb0..b4ddeaa5cf8 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Andrew Bartlett 2001-2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,8 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* These comments regard the code to change the user's unix password: */
-
/* fork a child process to exec passwd and write to its
* tty to change a users password. This is running as the
* user who is attempting to change the password.
@@ -32,6 +30,9 @@
* was included as a client to change passwords using the 'passwd' program
* on the remote machine.
*
+ * This routine is called by set_user_password() in password.c only if ALLOW_PASSWORD_CHANGE
+ * is defined in the compiler directives located in the Makefile.
+ *
* This code has been hacked by Bob Nance (nance@niehs.nih.gov) and Evan Patterson
* (patters2@niehs.nih.gov) at the National Institute of Environmental Health Sciences
* and rights to modify, distribute or incorporate this change to the CAP suite or
@@ -50,14 +51,6 @@
extern struct passdb_ops pdb_ops;
-static NTSTATUS check_oem_password(const char *user,
- uchar password_encrypted_with_lm_hash[516],
- const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
- const uchar old_nt_hash_encrypted[16],
- SAM_ACCOUNT **hnd, char *new_passwd,
- int new_passwd_size);
-
#if ALLOW_CHANGE_PASSWORD
static int findpty(char **slave)
@@ -65,7 +58,7 @@ static int findpty(char **slave)
int master;
static fstring line;
DIR *dirp;
- const char *dpname;
+ char *dpname;
#if defined(HAVE_GRANTPT)
/* Try to open /dev/ptmx. If that fails, fall through to old method. */
@@ -119,18 +112,20 @@ static int findpty(char **slave)
return (-1);
}
-static int dochild(int master, const char *slavedev, const struct passwd *pass,
- const char *passwordprogram, BOOL as_root)
+static int dochild(int master, char *slavedev, char *name,
+ char *passwordprogram, BOOL as_root)
{
int slave;
struct termios stermios;
+ struct passwd *pass = Get_Pwnam(name, True);
gid_t gid;
uid_t uid;
if (pass == NULL)
{
DEBUG(0,
- ("dochild: user doesn't exist in the UNIX password database.\n"));
+ ("dochild: user name %s doesn't exist in the UNIX password database.\n",
+ name));
return False;
}
@@ -169,17 +164,17 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
/* Make slave stdin/out/err of child. */
- if (sys_dup2(slave, STDIN_FILENO) != STDIN_FILENO)
+ if (dup2(slave, STDIN_FILENO) != STDIN_FILENO)
{
DEBUG(3, ("Could not re-direct stdin\n"));
return (False);
}
- if (sys_dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
+ if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
{
DEBUG(3, ("Could not re-direct stdout\n"));
return (False);
}
- if (sys_dup2(slave, STDERR_FILENO) != STDERR_FILENO)
+ if (dup2(slave, STDERR_FILENO) != STDERR_FILENO)
{
DEBUG(3, ("Could not re-direct stderr\n"));
return (False);
@@ -201,15 +196,13 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
#ifdef ONLCR
stermios.c_oflag &= ~(ONLCR);
#endif
- if (tcsetattr(0, TCSANOW, &stermios) < 0)
- {
+ if (tcsetattr(0, TCSANOW, &stermios) < 0) {
DEBUG(3, ("could not set attributes of pty\n"));
return (False);
}
/* make us completely into the right uid */
- if (!as_root)
- {
+ if (!as_root) {
become_user_permanently(uid, gid);
}
@@ -246,14 +239,13 @@ static int expect(int master, char *issue, char *expected)
if (strequal(expected, "."))
return True;
- /* Initial timeout. */
- timeout = lp_passwd_chat_timeout() * 1000;
+ timeout = 2000;
nread = 0;
buffer[nread] = 0;
- while ((len = read_socket_with_timeout(master, buffer + nread, 1,
- sizeof(buffer) - nread - 1,
- timeout)) > 0) {
+ while ((len = read_with_timeout(master, buffer + nread, 1,
+ sizeof(buffer) - nread - 1,
+ timeout)) > 0) {
nread += len;
buffer[nread] = 0;
@@ -261,12 +253,10 @@ static int expect(int master, char *issue, char *expected)
/* Eat leading/trailing whitespace before match. */
pstring str;
pstrcpy( str, buffer);
- trim_char( str, ' ', ' ');
+ trim_string( str, " ", " ");
- if ((match = (unix_wild_match(expected, str) == 0))) {
- /* Now data has started to return, lower timeout. */
- timeout = lp_passwd_chat_timeout() * 100;
- }
+ if ((match = (unix_wild_match(expected, str) == 0)))
+ timeout = 200;
}
}
@@ -328,7 +318,7 @@ static int talktochild(int master, const char *seq)
return (count > 0);
}
-static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
+static BOOL chat_with_program(char *passwordprogram, char *name,
char *chatsequence, BOOL as_root)
{
char *slavedev;
@@ -337,14 +327,12 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
int wstat;
BOOL chstat = False;
- if (pass == NULL) {
- DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n"));
- return False;
- }
-
/* allocate a pseudo-terminal device */
- if ((master = findpty(&slavedev)) < 0) {
- DEBUG(3, ("chat_with_program: Cannot Allocate pty for password change: %s\n", pass->pw_name));
+ if ((master = findpty(&slavedev)) < 0)
+ {
+ DEBUG(3,
+ ("Cannot Allocate pty for password change: %s\n",
+ name));
return (False);
}
@@ -355,30 +343,40 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
CatchChildLeaveStatus();
- if ((pid = sys_fork()) < 0) {
- DEBUG(3, ("chat_with_program: Cannot fork() child for password change: %s\n", pass->pw_name));
+ if ((pid = sys_fork()) < 0)
+ {
+ DEBUG(3,
+ ("Cannot fork() child for password change: %s\n",
+ name));
close(master);
CatchChild();
return (False);
}
/* we now have a pty */
- if (pid > 0) { /* This is the parent process */
- if ((chstat = talktochild(master, chatsequence)) == False) {
- DEBUG(3, ("chat_with_program: Child failed to change password: %s\n", pass->pw_name));
+ if (pid > 0)
+ { /* This is the parent process */
+ if ((chstat = talktochild(master, chatsequence)) == False)
+ {
+ DEBUG(3,
+ ("Child failed to change password: %s\n",
+ name));
kill(pid, SIGKILL); /* be sure to end this process */
}
- while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
- if (errno == EINTR) {
+ while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
+ {
+ if (errno == EINTR)
+ {
errno = 0;
continue;
}
break;
}
- if (wpid < 0) {
- DEBUG(3, ("chat_with_program: The process is no longer waiting!\n\n"));
+ if (wpid < 0)
+ {
+ DEBUG(3, ("The process is no longer waiting!\n\n"));
close(master);
CatchChild();
return (False);
@@ -391,23 +389,29 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
close(master);
- if (pid != wpid) {
- DEBUG(3, ("chat_with_program: We were waiting for the wrong process ID\n"));
+ if (pid != wpid)
+ {
+ DEBUG(3,
+ ("We were waiting for the wrong process ID\n"));
return (False);
}
- if (WIFEXITED(wstat) && (WEXITSTATUS(wstat) != 0)) {
- DEBUG(3, ("chat_with_program: The process exited with status %d \
-while we were waiting\n", WEXITSTATUS(wstat)));
+ if (WIFEXITED(wstat) == 0)
+ {
+ DEBUG(3,
+ ("The process exited while we were waiting\n"));
return (False);
}
-#if defined(WIFSIGNALLED) && defined(WTERMSIG)
- else if (WIFSIGNALLED(wstat)) {
- DEBUG(3, ("chat_with_program: The process was killed by signal %d \
-while we were waiting\n", WTERMSIG(wstat)));
+ if (WEXITSTATUS(wstat) != 0)
+ {
+ DEBUG(3,
+ ("The status of the process exiting was %d\n",
+ wstat));
return (False);
}
-#endif
- } else {
+
+ }
+ else
+ {
/* CHILD */
/*
@@ -421,9 +425,12 @@ while we were waiting\n", WTERMSIG(wstat)));
if (as_root)
become_root();
- DEBUG(3, ("chat_with_program: Dochild for user %s (uid=%d,gid=%d) (as_root = %s)\n", pass->pw_name,
- (int)getuid(), (int)getgid(), BOOLSTR(as_root) ));
- chstat = dochild(master, slavedev, pass, passwordprogram, as_root);
+ DEBUG(3,
+ ("Dochild for user %s (uid=%d,gid=%d)\n", name,
+ (int)getuid(), (int)getgid()));
+ chstat =
+ dochild(master, slavedev, name, passwordprogram,
+ as_root);
if (as_root)
unbecome_root();
@@ -432,40 +439,47 @@ while we were waiting\n", WTERMSIG(wstat)));
* The child should never return from dochild() ....
*/
- DEBUG(0, ("chat_with_program: Error: dochild() returned %d\n", chstat));
+ DEBUG(0,
+ ("chat_with_program: Error: dochild() returned %d\n",
+ chstat));
exit(1);
}
if (chstat)
- DEBUG(3, ("chat_with_program: Password change %ssuccessful for user %s\n",
- (chstat ? "" : "un"), pass->pw_name));
+ DEBUG(3,
+ ("Password change %ssuccessful for user %s\n",
+ (chstat ? "" : "un"), name));
return (chstat);
}
-BOOL chgpasswd(const char *name, const struct passwd *pass,
- const char *oldpass, const char *newpass, BOOL as_root)
+
+BOOL chgpasswd(char *name, const char *oldpass, const char *newpass, BOOL as_root)
{
pstring passwordprogram;
pstring chatsequence;
size_t i;
size_t len;
- if (!oldpass) {
- oldpass = "";
- }
-
- DEBUG(3, ("chgpasswd: Password change (as_root=%s) for user: %s\n", BOOLSTR(as_root), name));
+ strlower(name);
+ DEBUG(3, ("Password change for user: %s\n", name));
#if DEBUG_PASSWORD
- DEBUG(100, ("chgpasswd: Passwords: old=%s new=%s\n", oldpass, newpass));
+ DEBUG(100, ("Passwords: old=%s new=%s\n", oldpass, newpass));
#endif
/* Take the passed information and test it for minimum criteria */
+ /* Minimum password length */
+ if (strlen(newpass) < lp_min_passwd_length()) {
+ /* too short, must be at least MINPASSWDLENGTH */
+ DEBUG(0, ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
+ name, lp_min_passwd_length()));
+ return (False); /* inform the user */
+ }
/* Password is same as old password */
if (strcmp(oldpass, newpass) == 0) {
/* don't allow same password */
- DEBUG(2, ("chgpasswd: Password Change: %s, New password is same as old\n", name)); /* log the attempt */
+ DEBUG(2, ("Password Change: %s, New password is same as old\n", name)); /* log the attempt */
return (False); /* inform the user */
}
@@ -477,7 +491,8 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
len = strlen(oldpass);
for (i = 0; i < len; i++) {
if (iscntrl((int)oldpass[i])) {
- DEBUG(0, ("chgpasswd: oldpass contains control characters (disallowed).\n"));
+ DEBUG(0,
+ ("chat_with_program: oldpass contains control characters (disallowed).\n"));
return False;
}
}
@@ -485,11 +500,12 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
len = strlen(newpass);
for (i = 0; i < len; i++) {
if (iscntrl((int)newpass[i])) {
- DEBUG(0, ("chgpasswd: newpass contains control characters (disallowed).\n"));
+ DEBUG(0,
+ ("chat_with_program: newpass contains control characters (disallowed).\n"));
return False;
}
}
-
+
#ifdef WITH_PAM
if (lp_pam_password_change()) {
BOOL ret;
@@ -497,12 +513,8 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
if (as_root)
become_root();
- if (pass) {
- ret = smb_pam_passchange(pass->pw_name, oldpass, newpass);
- } else {
- ret = smb_pam_passchange(name, oldpass, newpass);
- }
-
+ ret = smb_pam_passchange(name, oldpass, newpass);
+
if (as_root)
unbecome_root();
@@ -510,13 +522,6 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
}
#endif
- /* A non-PAM password change just doen't make sense without a valid local user */
-
- if (pass == NULL) {
- DEBUG(0, ("chgpasswd: user %s doesn't exist in the UNIX password database.\n", name));
- return False;
- }
-
pstrcpy(passwordprogram, lp_passwd_program());
pstrcpy(chatsequence, lp_passwd_chat());
@@ -532,7 +537,7 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
if (as_root) {
/* The password program *must* contain the user name to work. Fail if not. */
- if (strstr_m(passwordprogram, "%u") == NULL) {
+ if (strstr(passwordprogram, "%u") == NULL) {
DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \
the string %%u, and the given string %s does not.\n", passwordprogram ));
return False;
@@ -548,15 +553,14 @@ the string %%u, and the given string %s does not.\n", passwordprogram ));
all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring));
all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
return (chat_with_program
- (passwordprogram, pass, chatsequence, as_root));
+ (passwordprogram, name, chatsequence, as_root));
}
#else /* ALLOW_CHANGE_PASSWORD */
-BOOL chgpasswd(const char *name, const struct passwd *pass,
- const char *oldpass, const char *newpass, BOOL as_root)
+BOOL chgpasswd(char *name, const char *oldpass, const char *newpass, BOOL as_root)
{
- DEBUG(0, ("chgpasswd: Unix Password changing not compiled in (user=%s)\n", name));
+ DEBUG(0, ("Password changing not compiled in (user=%s)\n", name));
return (False);
}
#endif /* ALLOW_CHANGE_PASSWORD */
@@ -568,11 +572,12 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
BOOL check_lanman_password(char *user, uchar * pass1,
uchar * pass2, SAM_ACCOUNT **hnd)
{
+ static uchar null_pw[16];
uchar unenc_new_pw[16];
uchar unenc_old_pw[16];
SAM_ACCOUNT *sampass = NULL;
uint16 acct_ctrl;
- const uint8 *lanman_pw;
+ uint8 *lanman_pw;
BOOL ret;
become_root();
@@ -581,7 +586,7 @@ BOOL check_lanman_password(char *user, uchar * pass1,
if (ret == False) {
DEBUG(0,("check_lanman_password: getsampwnam returned NULL\n"));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return False;
}
@@ -590,21 +595,24 @@ BOOL check_lanman_password(char *user, uchar * pass1,
if (acct_ctrl & ACB_DISABLED) {
DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return False;
}
- if (lanman_pw == NULL) {
- if (acct_ctrl & ACB_PWNOTREQ) {
- /* this saves the pointer for the caller */
- *hnd = sampass;
- return True;
- } else {
- DEBUG(0, ("check_lanman_password: no lanman password !\n"));
- pdb_free_sam(&sampass);
+ if ((lanman_pw == NULL) && (acct_ctrl & ACB_PWNOTREQ)) {
+ uchar no_pw[14];
+ memset(no_pw, '\0', 14);
+ E_P16(no_pw, null_pw);
+ if (!pdb_set_lanman_passwd(sampass, null_pw)) {
+ pdb_free_sam(sampass);
return False;
}
}
+ else if (lanman_pw == NULL) {
+ DEBUG(0, ("check_lanman_password: no lanman password !\n"));
+ pdb_free_sam(sampass);
+ return False;
+ }
/* Get the new lanman hash. */
D_P16(lanman_pw, pass2, unenc_new_pw);
@@ -615,12 +623,13 @@ BOOL check_lanman_password(char *user, uchar * pass1,
/* Check that the two old passwords match. */
if (memcmp(lanman_pw, unenc_old_pw, 16)) {
DEBUG(0,("check_lanman_password: old password doesn't match.\n"));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
return False;
}
/* this saves the pointer for the caller */
*hnd = sampass;
+
return True;
}
@@ -628,17 +637,16 @@ BOOL check_lanman_password(char *user, uchar * pass1,
Code to change the lanman hashed password.
It nulls out the NT hashed password as it will
no longer be valid.
- NOTE this function is designed to be called as root. Check the old password
- is correct before calling. JRA.
************************************************************/
-BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
+BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar * pass1,
+ uchar * pass2)
{
static uchar null_pw[16];
uchar unenc_new_pw[16];
BOOL ret;
uint16 acct_ctrl;
- const uint8 *pwd;
+ uint8 *pwd;
if (sampass == NULL) {
DEBUG(0,("change_lanman_password: no smb password entry.\n"));
@@ -654,39 +662,29 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
return False;
}
- if (pwd == NULL) {
- if (acct_ctrl & ACB_PWNOTREQ) {
- uchar no_pw[14];
- memset(no_pw, '\0', 14);
- E_P16(no_pw, null_pw);
-
- /* Get the new lanman hash. */
- D_P16(null_pw, pass2, unenc_new_pw);
- } else {
- DEBUG(0,("change_lanman_password: no lanman password !\n"));
+ if ((pwd == NULL) && (acct_ctrl & ACB_PWNOTREQ)) {
+ uchar no_pw[14];
+ memset(no_pw, '\0', 14);
+ E_P16(no_pw, null_pw);
+ if (!pdb_set_lanman_passwd(sampass, null_pw))
return False;
- }
- } else {
- /* Get the new lanman hash. */
- D_P16(pwd, pass2, unenc_new_pw);
}
-
- if (!pdb_set_lanman_passwd(sampass, unenc_new_pw, PDB_CHANGED)) {
+ else if (pwd == NULL) {
+ DEBUG(0,("change_lanman_password: no lanman password !\n"));
return False;
}
- if (!pdb_set_nt_passwd (sampass, NULL, PDB_CHANGED)) {
- return False; /* We lose the NT hash. Sorry. */
- }
+ /* Get the new lanman hash. */
+ D_P16(pwd, pass2, unenc_new_pw);
+
+ if (!pdb_set_lanman_passwd(sampass, unenc_new_pw))
+ return False;
+ pdb_set_nt_passwd (sampass, NULL); /* We lose the NT hash. Sorry. */
- if (!pdb_set_pass_changed_now (sampass)) {
- pdb_free_sam(&sampass);
- /* Not quite sure what this one qualifies as, but this will do */
- return False;
- }
-
/* Now flush the sam_passwd struct to persistent storage */
- ret = pdb_update_sam_account (sampass);
+ become_root();
+ ret = pdb_update_sam_account (sampass, False);
+ unbecome_root();
return ret;
}
@@ -694,73 +692,65 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
/***********************************************************
Code to check and change the OEM hashed password.
************************************************************/
-
-NTSTATUS pass_oem_change(char *user,
- uchar password_encrypted_with_lm_hash[516],
- const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
- const uchar old_nt_hash_encrypted[16])
+BOOL pass_oem_change(char *user,
+ uchar * lmdata, uchar * lmhash,
+ uchar * ntdata, uchar * nthash)
{
- pstring new_passwd;
+ fstring new_passwd;
SAM_ACCOUNT *sampass = NULL;
- NTSTATUS nt_status = check_oem_password(user, password_encrypted_with_lm_hash,
- old_lm_hash_encrypted,
- password_encrypted_with_nt_hash,
- old_nt_hash_encrypted,
- &sampass, new_passwd, sizeof(new_passwd));
-
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
+ BOOL ret = check_oem_password(user, lmdata, lmhash, ntdata, nthash,
+ &sampass, new_passwd, sizeof(new_passwd));
- /* We've already checked the old password here.... */
- become_root();
- nt_status = change_oem_password(sampass, NULL, new_passwd, True);
- unbecome_root();
+ /*
+ * At this point we have the new case-sensitive plaintext
+ * password in the fstring new_passwd. If we wanted to synchronise
+ * with UNIX passwords we would call a UNIX password changing
+ * function here. However it would have to be done as root
+ * as the plaintext of the old users password is not
+ * available. JRA.
+ */
+
+ if (ret && lp_unix_password_sync())
+ ret = chgpasswd(user, "", new_passwd, True);
+
+ if (ret)
+ ret = change_oem_password(sampass, new_passwd, False);
memset(new_passwd, 0, sizeof(new_passwd));
- pdb_free_sam(&sampass);
+ pdb_free_sam(sampass);
- return nt_status;
+ return ret;
}
/***********************************************************
- Decrypt and verify a user password change.
+ Code to check the OEM hashed password.
- The 516 byte long buffers are encrypted with the old NT and
- old LM passwords, and if the NT passwords are present, both
- buffers contain a unicode string.
+ this function ignores the 516 byte nt OEM hashed password
+ but does use the lm OEM password to check the nt hashed-hash.
- After decrypting the buffers, check the password is correct by
- matching the old hashed passwords with the passwords in the passdb.
-
************************************************************/
-static NTSTATUS check_oem_password(const char *user,
- uchar password_encrypted_with_lm_hash[516],
- const uchar old_lm_hash_encrypted[16],
- uchar password_encrypted_with_nt_hash[516],
- const uchar old_nt_hash_encrypted[16],
- SAM_ACCOUNT **hnd, char *new_passwd,
- int new_passwd_size)
+BOOL check_oem_password(char *user,
+ uchar * lmdata, uchar * lmhash,
+ uchar * ntdata, uchar * nthash,
+ SAM_ACCOUNT **hnd, char *new_passwd,
+ int new_passwd_size)
{
static uchar null_pw[16];
static uchar null_ntpw[16];
SAM_ACCOUNT *sampass = NULL;
- char *password_encrypted;
- const char *encryption_key;
- const uint8 *lanman_pw, *nt_pw;
+ uint8 *lanman_pw, *nt_pw;
uint16 acct_ctrl;
- uint32 new_pw_len;
- uchar new_nt_hash[16];
- uchar old_nt_hash_plain[16];
- uchar new_lm_hash[16];
- uchar old_lm_hash_plain[16];
+ int new_pw_len;
+ uchar new_ntp16[16];
+ uchar unenc_old_ntpw[16];
+ uchar new_p16[16];
+ uchar unenc_old_pw[16];
char no_pw[2];
BOOL ret;
- BOOL nt_pass_set = (password_encrypted_with_nt_hash && old_nt_hash_encrypted);
- BOOL lm_pass_set = (password_encrypted_with_lm_hash && old_lm_hash_encrypted);
+ BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);
*hnd = NULL;
@@ -772,72 +762,90 @@ static NTSTATUS check_oem_password(const char *user,
if (ret == False) {
DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n"));
- pdb_free_sam(&sampass);
- return NT_STATUS_NO_SUCH_USER;
+ pdb_free_sam(sampass);
+ return False;
}
acct_ctrl = pdb_get_acct_ctrl(sampass);
if (acct_ctrl & ACB_DISABLED) {
- DEBUG(2,("check_lanman_password: account %s disabled.\n", user));
- pdb_free_sam(&sampass);
- return NT_STATUS_ACCOUNT_DISABLED;
+ DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
+ pdb_free_sam(sampass);
+ return False;
}
- if (acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) {
- /* construct a null password (in case one is needed */
- no_pw[0] = 0;
- no_pw[1] = 0;
- nt_lm_owf_gen(no_pw, null_ntpw, null_pw);
- lanman_pw = null_pw;
- nt_pw = null_pw;
+ /* construct a null password (in case one is needed */
+ no_pw[0] = 0;
+ no_pw[1] = 0;
+ nt_lm_owf_gen(no_pw, null_ntpw, null_pw);
- } else {
- /* save pointers to passwords so we don't have to keep looking them up */
- if (lp_lanman_auth()) {
+ /* save pointers to passwords so we don't have to keep looking them up */
+ lanman_pw = pdb_get_lanman_passwd(sampass);
+ nt_pw = pdb_get_nt_passwd(sampass);
+
+ /* check for null passwords */
+ if (lanman_pw == NULL) {
+ if (acct_ctrl & ACB_PWNOTREQ) {
+ if (!pdb_set_lanman_passwd(sampass, null_pw)) {
+ pdb_free_sam(sampass);
+ return False;
+ }
lanman_pw = pdb_get_lanman_passwd(sampass);
+ if (!lanman_pw) {
+ pdb_free_sam(sampass);
+ return False;
+ }
} else {
- lanman_pw = NULL;
+ DEBUG(0,("check_oem_password: no lanman password !\n"));
+ pdb_free_sam(sampass);
+ return False;
}
- nt_pw = pdb_get_nt_passwd(sampass);
}
- if (nt_pw && nt_pass_set) {
- /* IDEAL Case: passwords are in unicode, and we can
- * read use the password encrypted with the NT hash
- */
- password_encrypted = password_encrypted_with_nt_hash;
- encryption_key = nt_pw;
- } else if (lanman_pw && lm_pass_set) {
- /* password may still be in unicode, but use LM hash version */
- password_encrypted = password_encrypted_with_lm_hash;
- encryption_key = lanman_pw;
- } else if (nt_pass_set) {
- DEBUG(1, ("NT password change supplied for user %s, but we have no NT password to check it with\n",
- user));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
- } else if (lm_pass_set) {
- DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
- user));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
- } else {
- DEBUG(1, ("password change requested for user %s, but no password supplied!\n",
- user));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
+ if (pdb_get_nt_passwd(sampass) == NULL && nt_pass_set) {
+ if (acct_ctrl & ACB_PWNOTREQ) {
+ pdb_set_nt_passwd(sampass, null_ntpw);
+ nt_pw = pdb_get_nt_passwd(sampass);
+ if (!nt_pw) {
+ pdb_free_sam(sampass);
+ return False;
+ }
+ } else {
+ DEBUG(0,("check_oem_password: no ntlm password !\n"));
+ pdb_free_sam(sampass);
+ return False;
+ }
}
/*
- * Decrypt the password with the key
+ * Call the hash function to get the new password.
*/
- SamOEMhash( password_encrypted, encryption_key, 516);
+ SamOEMhash((uchar *) lmdata, (uchar *)lanman_pw, 516);
- if ( !decode_pw_buffer(password_encrypted, new_passwd, new_passwd_size, &new_pw_len,
- nt_pass_set ? STR_UNICODE : STR_ASCII)) {
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+
+ new_pw_len = IVAL(lmdata, 512);
+ if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) {
+ DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ if (nt_pass_set) {
+ /*
+ * nt passwords are in unicode
+ */
+ int uni_pw_len = new_pw_len;
+ char *pw;
+ new_pw_len /= 2;
+ pw = dos_unistrn2((uint16 *)(&lmdata[512 - uni_pw_len]), new_pw_len);
+ memcpy(new_passwd, pw, new_pw_len + 1);
+ } else {
+ memcpy(new_passwd, &lmdata[512 - new_pw_len], new_pw_len);
+ new_passwd[new_pw_len] = 0;
}
/*
@@ -845,163 +853,135 @@ static NTSTATUS check_oem_password(const char *user,
* use it as a key to test the passed old password.
*/
- if (nt_pass_set) {
- /* NT passwords, verify the NT hash. */
-
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset(new_nt_hash, '\0', 16);
- E_md4hash(new_passwd, new_nt_hash);
-
- if (nt_pw) {
- /*
- * Now use new_nt_hash as the key to see if the old
- * password matches.
- */
- D_P16(new_nt_hash, old_nt_hash_encrypted, old_nt_hash_plain);
-
- if (memcmp(nt_pw, old_nt_hash_plain, 16)) {
- DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
- }
-
- /* We could check the LM password here, but there is
- * little point, we already know the password is
- * correct, and the LM password might not even be
- * present. */
-
- /* Further, LM hash generation algorithms
- * differ with charset, so we could
- * incorrectly fail a perfectly valid password
- * change */
-#ifdef DEBUG_PASSWORD
- DEBUG(100,
- ("check_oem_password: password %s ok\n", new_passwd));
-#endif
- *hnd = sampass;
- return NT_STATUS_OK;
- }
-
- if (lanman_pw) {
- /*
- * Now use new_nt_hash as the key to see if the old
- * LM password matches.
- */
- D_P16(new_nt_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
- DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
- }
-#ifdef DEBUG_PASSWORD
- DEBUG(100,
- ("check_oem_password: password %s ok\n", new_passwd));
-#endif
- *hnd = sampass;
- return NT_STATUS_OK;
- }
- }
-
- if (lanman_pw && lm_pass_set) {
-
- E_deshash(new_passwd, new_lm_hash);
+ nt_lm_owf_gen(new_passwd, new_ntp16, new_p16);
+ if (!nt_pass_set) {
/*
- * Now use new_lm_hash as the key to see if the old
+ * Now use new_p16 as the key to see if the old
* password matches.
*/
- D_P16(new_lm_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
+ D_P16(new_p16, lmhash, unenc_old_pw);
+
+ if (memcmp(lanman_pw, unenc_old_pw, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
+ pdb_free_sam(sampass);
+ return False;
}
-
+
#ifdef DEBUG_PASSWORD
DEBUG(100,
("check_oem_password: password %s ok\n", new_passwd));
#endif
*hnd = sampass;
- return NT_STATUS_OK;
+ return True;
}
- /* should not be reached */
- pdb_free_sam(&sampass);
- return NT_STATUS_WRONG_PASSWORD;
+ /*
+ * Now use new_p16 as the key to see if the old
+ * password matches.
+ */
+ D_P16(new_ntp16, lmhash, unenc_old_pw);
+ D_P16(new_ntp16, nthash, unenc_old_ntpw);
+
+ if (memcmp(lanman_pw, unenc_old_pw, 16)) {
+ DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ if (memcmp(nt_pw, unenc_old_ntpw, 16)) {
+ DEBUG(0,("check_oem_password: old nt password doesn't match.\n"));
+ pdb_free_sam(sampass);
+ return False;
+ }
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("check_oem_password: password %s ok\n", new_passwd));
+#endif
+ *hnd = sampass;
+ return True;
}
/***********************************************************
Code to change the oem password. Changes both the lanman
- and NT hashes. Old_passwd is almost always NULL.
- NOTE this function is designed to be called as root. Check the old password
- is correct before calling. JRA.
+ and NT hashes.
+ override = False, normal
+ override = True, override XXXXXXXXXX'd password
************************************************************/
-NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root)
+BOOL change_oem_password(SAM_ACCOUNT *hnd, char *new_passwd,
+ BOOL override)
{
- struct passwd *pass;
+ BOOL ret;
+ uchar new_nt_p16[16];
+ uchar new_p16[16];
+
+ nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
+
+ if (!pdb_set_lanman_passwd (hnd, new_p16))
+ return False;
+ if (!pdb_set_nt_passwd(hnd, new_nt_p16))
+ return False;
+
+ /* Now write it into the file. */
+ become_root();
+ ret = pdb_update_sam_account (hnd, override);
+ unbecome_root();
+
+ memset(new_passwd, '\0', strlen(new_passwd));
+
+ return ret;
+}
+/***********************************************************
+ Code to check a plaintext password against smbpasswd entries.
+***********************************************************/
+
+BOOL check_plaintext_password(char *user, char *old_passwd,
+ int old_passwd_size, SAM_ACCOUNT **hnd)
+{
+ SAM_ACCOUNT *sampass = NULL;
+ uchar old_pw[16], old_ntpw[16];
BOOL ret;
- uint32 min_len;
- if (time(NULL) < pdb_get_pass_can_change_time(hnd)) {
- DEBUG(1, ("user %s cannot change password now, must wait until %s\n",
- pdb_get_username(hnd), http_timestring(pdb_get_pass_can_change_time(hnd))));
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
+ *hnd = NULL;
- if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (strlen(new_passwd) < min_len)) {
- DEBUG(1, ("user %s cannot change password - password too short\n",
- pdb_get_username(hnd)));
- DEBUGADD(1, (" account policy min password len = %d\n", min_len));
- return NT_STATUS_PASSWORD_RESTRICTION;
-/* return NT_STATUS_PWD_TOO_SHORT; */
- }
+ pdb_init_sam(&sampass);
- /* Take the passed information and test it for minimum criteria */
- /* Minimum password length */
- if (strlen(new_passwd) < lp_min_passwd_length()) {
- /* too short, must be at least MINPASSWDLENGTH */
- DEBUG(1, ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
- pdb_get_username(hnd), lp_min_passwd_length()));
- return NT_STATUS_PASSWORD_RESTRICTION;
-/* return NT_STATUS_PWD_TOO_SHORT; */
- }
+ become_root();
+ ret = pdb_getsampwnam(sampass, user);
+ unbecome_root();
- pass = Get_Pwnam(pdb_get_username(hnd));
- if (!pass) {
- DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n"));
+ if (ret == False) {
+ DEBUG(0,("check_plaintext_password: getsmbpwnam returned NULL\n"));
+ pdb_free_sam(sampass);
+ return False;
}
- /*
- * If unix password sync was requested, attempt to change
- * the /etc/passwd database first. Return failure if this cannot
- * be done.
- *
- * This occurs before the oem change, because we don't want to
- * update it if chgpasswd failed.
- *
- * Conditional on lp_unix_password_sync() because we don't want
- * to touch the unix db unless we have admin permission.
- */
-
- if(lp_unix_password_sync() &&
- !chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) {
- return NT_STATUS_ACCESS_DENIED;
+ if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+ DEBUG(0,("check_plaintext_password: account %s disabled.\n", user));
+ pdb_free_sam(sampass);
+ return (False);
}
- if (!pdb_set_plaintext_passwd (hnd, new_passwd)) {
- return NT_STATUS_ACCESS_DENIED;
- }
+ nt_lm_owf_gen(old_passwd, old_ntpw, old_pw);
- /* Now write it into the file. */
- ret = pdb_update_sam_account (hnd);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("check_plaintext_password: nt_passwd \n"));
+ dump_data(100, pdb_get_nt_passwd(sampass), 16);
+ DEBUG(100, ("check_plaintext_password: old_ntpw \n"));
+ dump_data(100, old_ntpw, 16);
+ DEBUG(100, ("check_plaintext_password: lanman_passwd \n"));
+ dump_data(100, pdb_get_lanman_passwd(sampass), 16);
+ DEBUG(100, ("check_plaintext_password: old_pw\n"));
+ dump_data(100, old_pw, 16);
+#endif
- if (!ret) {
- return NT_STATUS_ACCESS_DENIED;
+ if (memcmp(pdb_get_nt_passwd(sampass), old_ntpw, 16)
+ && memcmp(pdb_get_lanman_passwd(sampass), old_pw, 16)) {
+ pdb_free_sam(sampass);
+ return (False);
+ } else {
+ *hnd = sampass;
+ return (True);
}
-
- return NT_STATUS_OK;
}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 8b3010c1b2e..f829597ed7f 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
file closing
Copyright (C) Andrew Tridgell 1992-1998
@@ -21,65 +22,64 @@
#include "includes.h"
/****************************************************************************
- Run a file if it is a magic script.
+run a file if it is a magic script
****************************************************************************/
-
static void check_magic(files_struct *fsp,connection_struct *conn)
{
- if (!*lp_magicscript(SNUM(conn)))
+ if (!*lp_magicscript(SNUM(conn)))
+ return;
+
+ DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
+
+ {
+ char *p;
+ if (!(p = strrchr(fsp->fsp_name,'/')))
+ p = fsp->fsp_name;
+ else
+ p++;
+
+ if (!strequal(lp_magicscript(SNUM(conn)),p))
+ return;
+ }
+
+ {
+ int ret;
+ pstring magic_output;
+ pstring fname;
+ SMB_STRUCT_STAT st;
+ int tmp_fd, outfd;
+
+ pstrcpy(fname,fsp->fsp_name);
+ if (*lp_magicoutput(SNUM(conn)))
+ pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
+ else
+ slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
+
+ chmod(fname,0755);
+ ret = smbrun(fname,&tmp_fd);
+ DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
+ unlink(fname);
+ if (ret != 0 || tmp_fd == -1) {
+ if (tmp_fd != -1)
+ close(tmp_fd);
+ return;
+ }
+ outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
+ if (outfd == -1) {
+ close(tmp_fd);
return;
-
- DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
-
- {
- char *p;
- if (!(p = strrchr_m(fsp->fsp_name,'/')))
- p = fsp->fsp_name;
- else
- p++;
-
- if (!strequal(lp_magicscript(SNUM(conn)),p))
- return;
}
- {
- int ret;
- pstring magic_output;
- pstring fname;
- SMB_STRUCT_STAT st;
- int tmp_fd, outfd;
-
- pstrcpy(fname,fsp->fsp_name);
- if (*lp_magicoutput(SNUM(conn)))
- pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
- else
- slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
-
- chmod(fname,0755);
- ret = smbrun(fname,&tmp_fd);
- DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
- unlink(fname);
- if (ret != 0 || tmp_fd == -1) {
- if (tmp_fd != -1)
- close(tmp_fd);
- return;
- }
- outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
- if (outfd == -1) {
- close(tmp_fd);
- return;
- }
-
- if (sys_fstat(tmp_fd,&st) == -1) {
- close(tmp_fd);
- close(outfd);
- return;
- }
-
- transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
+ if (sys_fstat(tmp_fd,&st) == -1) {
close(tmp_fd);
close(outfd);
+ return;
}
+
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
+ close(tmp_fd);
+ close(outfd);
+ }
}
/****************************************************************************
@@ -98,6 +98,8 @@ static int close_filestruct(files_struct *fsp)
delete_write_cache(fsp);
}
+ fsp->is_directory = False;
+
conn->num_files_open--;
SAFE_FREE(fsp->wbmpx_ptr);
@@ -163,8 +165,8 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
share_entry_count = del_share_mode(fsp, &share_entry);
- DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
- (unsigned long)share_entry_count, fsp->fsp_name ));
+ DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
+ share_entry_count, fsp->fsp_name ));
/*
* We delete on close if it's the last open, and the
@@ -185,7 +187,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
if (normal_close && delete_on_close) {
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
fsp->fsp_name));
- if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
+ if(fsp->conn->vfs_ops.unlink(conn,dos_to_unix_static(fsp->fsp_name)) != 0) {
/*
* This call can potentially fail as another smbd may have
* had the file open with delete on close set and deleted
@@ -193,7 +195,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* we log this but not at debug level zero.
*/
- DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
+ DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
with error %s\n", fsp->fsp_name, strerror(errno) ));
}
process_pending_change_notify_queue((time_t)0);
@@ -233,7 +235,7 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
file_free(fsp);
if (err == -1 || err1 == -1)
- return errno;
+ return -1;
else
return 0;
}
@@ -275,29 +277,30 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
string_free(&fsp->fsp_name);
file_free(fsp);
+
return 0;
}
/****************************************************************************
Close a 'stat file' opened internally.
****************************************************************************/
-
+
static int close_stat(files_struct *fsp)
{
/*
* Do the code common to files and directories.
*/
close_filestruct(fsp);
-
+
if (fsp->fsp_name)
string_free(&fsp->fsp_name);
-
+
file_free(fsp);
return 0;
}
/****************************************************************************
- Close a files_struct.
+ Close a directory opened by an NT SMB call.
****************************************************************************/
int close_file(files_struct *fsp, BOOL normal_close)
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index 0805f8e6902..3f09d7ac0e3 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Manage connections_struct structures
Copyright (C) Andrew Tridgell 1998
- Copyright (C) Alexander Bokovoy 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,11 +21,11 @@
#include "includes.h"
-/* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The
- * maximum size of the bitmap is the largest positive integer, but you will hit
- * the "max connections" limit, looong before that.
- */
-#define BITMAP_BLOCK_SZ 128
+/* set these to define the limits of the server. NOTE These are on a
+ per-client basis. Thus any one machine can't connect to more than
+ MAX_CONNECTIONS services, but any number of machines may connect at
+ one time. */
+#define MAX_CONNECTIONS 128
static connection_struct *Connections;
@@ -38,7 +38,7 @@ init the conn structures
****************************************************************************/
void conn_init(void)
{
- bmap = bitmap_allocate(BITMAP_BLOCK_SZ);
+ bmap = bitmap_allocate(MAX_CONNECTIONS);
}
/****************************************************************************
@@ -68,7 +68,7 @@ BOOL conn_snum_used(int snum)
/****************************************************************************
find a conn given a cnum
****************************************************************************/
-connection_struct *conn_find(unsigned cnum)
+connection_struct *conn_find(int cnum)
{
int count=0;
connection_struct *conn;
@@ -93,50 +93,20 @@ thinking the server is still available.
****************************************************************************/
connection_struct *conn_new(void)
{
- TALLOC_CTX *mem_ctx;
connection_struct *conn;
int i;
- int find_offset = 1;
-find_again:
- i = bitmap_find(bmap, find_offset);
+ i = bitmap_find(bmap, 1);
if (i == -1) {
- /* Expand the connections bitmap. */
- int oldsz = bmap->n;
- int newsz = bmap->n + BITMAP_BLOCK_SZ;
- struct bitmap * nbmap;
-
- if (newsz <= 0) {
- /* Integer wrap. */
- DEBUG(0,("ERROR! Out of connection structures\n"));
- return NULL;
- }
-
- DEBUG(4,("resizing connections bitmap from %d to %d\n",
- oldsz, newsz));
-
- nbmap = bitmap_allocate(newsz);
-
- bitmap_copy(nbmap, bmap);
- bitmap_free(bmap);
-
- bmap = nbmap;
- find_offset = oldsz; /* Start next search in the new portion. */
-
- goto find_again;
- }
-
- if ((mem_ctx=talloc_init("connection_struct"))==NULL) {
- DEBUG(0,("talloc_init(connection_struct) failed!\n"));
+ DEBUG(1,("ERROR! Out of connection structures\n"));
return NULL;
}
- if ((conn=(connection_struct *)talloc_zero(mem_ctx, sizeof(*conn)))==NULL) {
- DEBUG(0,("talloc_zero() failed!\n"));
- return NULL;
- }
- conn->mem_ctx = mem_ctx;
+ conn = (connection_struct *)malloc(sizeof(*conn));
+ if (!conn) return NULL;
+
+ ZERO_STRUCTP(conn);
conn->cnum = i;
bitmap_set(bmap, i);
@@ -161,7 +131,7 @@ void conn_close_all(void)
connection_struct *conn, *next;
for (conn=Connections;conn;conn=next) {
next=conn->next;
- close_cnum(conn, conn->vuid);
+ close_cnum(conn, (uint16)-1);
}
}
@@ -191,7 +161,7 @@ BOOL conn_idle_all(time_t t, int deadtime)
* idle with a handle open.
*/
- for (plist = get_first_internal_pipe(); plist; plist = get_next_internal_pipe(plist))
+ for (plist = get_first_pipe(); plist; plist = get_next_pipe(plist))
if (plist->pipe_handles && plist->pipe_handles->count)
allidle = False;
@@ -199,64 +169,27 @@ BOOL conn_idle_all(time_t t, int deadtime)
}
/****************************************************************************
- Clear a vuid out of the validity cache, and as the 'owner' of a connection.
-****************************************************************************/
-
-void conn_clear_vuid_cache(uint16 vuid)
-{
- connection_struct *conn;
- unsigned int i;
-
- for (conn=Connections;conn;conn=conn->next) {
- if (conn->vuid == vuid) {
- conn->vuid = UID_FIELD_INVALID;
- }
-
- for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
- if (conn->vuid_cache.array[i].vuid == vuid) {
- struct vuid_cache_entry *ent = &conn->vuid_cache.array[i];
- ent->vuid = UID_FIELD_INVALID;
- ent->read_only = False;
- ent->admin_user = False;
- }
- }
- }
-}
-
-/****************************************************************************
Free a conn structure.
****************************************************************************/
void conn_free(connection_struct *conn)
{
- vfs_handle_struct *handle = NULL, *thandle = NULL;
- TALLOC_CTX *mem_ctx = NULL;
-
/* Free vfs_connection_struct */
- handle = conn->vfs_handles;
- while(handle) {
- DLIST_REMOVE(conn->vfs_handles, handle);
- thandle = handle->next;
- if (handle->free_data)
- handle->free_data(&handle->data);
- handle = thandle;
+
+ if (conn->dl_handle != NULL) {
+ /* Close dlopen() handle */
+ sys_dlclose(conn->dl_handle);
}
DLIST_REMOVE(Connections, conn);
if (conn->ngroups && conn->groups) {
SAFE_FREE(conn->groups);
+ conn->groups = NULL;
conn->ngroups = 0;
}
- if (conn->nt_user_token) {
- delete_nt_token(&(conn->nt_user_token));
- }
-
- if (conn->privs) {
- destroy_privilege(&(conn->privs));
- }
-
+ delete_nt_token(&conn->nt_user_token);
free_namearray(conn->veto_list);
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
@@ -269,9 +202,8 @@ void conn_free(connection_struct *conn)
bitmap_clear(bmap, conn->cnum);
num_open--;
- mem_ctx = conn->mem_ctx;
ZERO_STRUCTP(conn);
- talloc_destroy(mem_ctx);
+ SAFE_FREE(conn);
}
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index a9ab1424615..5ef410dd269 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
connection claim routines
Copyright (C) Andrew Tridgell 1998
@@ -20,6 +21,8 @@
#include "includes.h"
+
+extern fstring remote_machine;
static TDB_CONTEXT *tdb;
/****************************************************************************
@@ -28,47 +31,30 @@ static TDB_CONTEXT *tdb;
TDB_CONTEXT *conn_tdb_ctx(void)
{
- if (!tdb)
- tdb = tdb_open_ex(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644, smbd_tdb_log);
-
return tdb;
}
-static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey)
-{
- ZERO_STRUCTP(pkey);
- pkey->pid = sys_getpid();
- pkey->cnum = conn?conn->cnum:-1;
- fstrcpy(pkey->name, name);
-#ifdef DEVELOPER
- /* valgrind fixer... */
- {
- size_t sl = strlen(pkey->name);
- if (sizeof(fstring)-sl)
- memset(&pkey->name[sl], '\0', sizeof(fstring)-sl);
- }
-#endif
-
- pkbuf->dptr = (char *)pkey;
- pkbuf->dsize = sizeof(*pkey);
-}
-
/****************************************************************************
Delete a connection record.
****************************************************************************/
-BOOL yield_connection(connection_struct *conn, const char *name)
+BOOL yield_connection(connection_struct *conn,const char *name)
{
struct connections_key key;
TDB_DATA kbuf;
- if (!tdb)
- return False;
+ if (!tdb) return False;
DEBUG(3,("Yielding connection to %s\n",name));
- make_conn_key(conn, name, &kbuf, &key);
+ ZERO_STRUCT(key);
+ key.pid = sys_getpid();
+ key.cnum = conn?conn->cnum:-1;
+ fstrcpy(key.name, name);
+ dos_to_unix(key.name); /* Convert key to unix-codepage */
+
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
if (tdb_delete(tdb, kbuf) != 0) {
int dbg_lvl = (!conn && (tdb_error(tdb) == TDB_ERR_NOEXIST)) ? 3 : 0;
@@ -124,16 +110,16 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u
Claim an entry in the connections database.
****************************************************************************/
-BOOL claim_connection(connection_struct *conn, const char *name,int max_connections,BOOL Clear, uint32 msg_flags)
+BOOL claim_connection(connection_struct *conn,const char *name,int max_connections,BOOL Clear)
{
struct connections_key key;
struct connections_data crec;
TDB_DATA kbuf, dbuf;
- if (!tdb)
- tdb = tdb_open_ex(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644, smbd_tdb_log);
-
+ if (!tdb) {
+ tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0644);
+ }
if (!tdb)
return False;
@@ -169,7 +155,14 @@ BOOL claim_connection(connection_struct *conn, const char *name,int max_connecti
DEBUG(5,("claiming %s %d\n",name,max_connections));
- make_conn_key(conn, name, &kbuf, &key);
+ ZERO_STRUCT(key);
+ key.pid = sys_getpid();
+ key.cnum = conn?conn->cnum:-1;
+ fstrcpy(key.name, name);
+ dos_to_unix(key.name); /* Convert key to unix-codepage */
+
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
/* fill in the crec */
ZERO_STRUCT(crec);
@@ -179,14 +172,13 @@ BOOL claim_connection(connection_struct *conn, const char *name,int max_connecti
if (conn) {
crec.uid = conn->uid;
crec.gid = conn->gid;
- safe_strcpy(crec.name,
- lp_servicename(SNUM(conn)),sizeof(crec.name)-1);
+ StrnCpy(crec.name,
+ lp_servicename(SNUM(conn)),sizeof(crec.name)-1);
}
crec.start = time(NULL);
- crec.bcast_msg_flags = msg_flags;
- safe_strcpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-1);
- safe_strcpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1);
+ StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
+ StrnCpy(crec.addr,conn?conn->client_address:client_addr(),sizeof(crec.addr)-1);
dbuf.dptr = (char *)&crec;
dbuf.dsize = sizeof(crec);
@@ -199,45 +191,3 @@ BOOL claim_connection(connection_struct *conn, const char *name,int max_connecti
return True;
}
-
-BOOL register_message_flags(BOOL doreg, uint32 msg_flags)
-{
- struct connections_key key;
- struct connections_data *pcrec;
- TDB_DATA kbuf, dbuf;
-
- if (!tdb)
- return False;
-
- DEBUG(10,("register_message_flags: %s flags 0x%x\n",
- doreg ? "adding" : "removing",
- (unsigned int)msg_flags ));
-
- make_conn_key(NULL, "", &kbuf, &key);
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr) {
- DEBUG(0,("register_message_flags: tdb_fetch failed\n"));
- return False;
- }
-
- pcrec = (struct connections_data *)dbuf.dptr;
- pcrec->bcast_msg_flags = msg_flags;
- if (doreg)
- pcrec->bcast_msg_flags |= msg_flags;
- else
- pcrec->bcast_msg_flags &= ~msg_flags;
-
- if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("register_message_flags: tdb_store failed with error %s.\n",
- tdb_errorstr(tdb) ));
- SAFE_FREE(dbuf.dptr);
- return False;
- }
-
- DEBUG(10,("register_message_flags: new flags 0x%x\n",
- (unsigned int)pcrec->bcast_msg_flags ));
-
- SAFE_FREE(dbuf.dptr);
- return True;
-}
diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c
index f93cdf3791e..e55e40c030d 100644
--- a/source/smbd/dfree.c
+++ b/source/smbd/dfree.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
functions to calculate the free disk space
Copyright (C) Andrew Tridgell 1998
@@ -21,8 +22,9 @@
#include "includes.h"
/****************************************************************************
-normalise for DOS usage
+ Normalise for DOS usage.
****************************************************************************/
+
static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
/* check if the disk is beyond the max disk size */
@@ -59,10 +61,10 @@ static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,
/****************************************************************************
- return number of 1K blocks available on a path and total number
+ Return number of 1K blocks available on a path and total number.
****************************************************************************/
-static SMB_BIG_UINT disk_free(const char *path, BOOL small_query,
+static SMB_BIG_UINT disk_free(char *path, BOOL small_query,
SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
int dfree_retval;
@@ -80,28 +82,28 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query,
dfree_command = lp_dfree_command();
if (dfree_command && *dfree_command) {
- const char *p;
+ char *p;
char **lines;
pstring syscmd;
slprintf(syscmd, sizeof(syscmd)-1, "%s %s", dfree_command, path);
DEBUG (3, ("disk_free: Running command %s\n", syscmd));
- lines = file_lines_pload(syscmd, NULL);
+ lines = file_lines_pload(syscmd, NULL, True);
if (lines) {
char *line = lines[0];
DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
- *dsize = STR_TO_SMB_BIG_UINT(line, &p);
- while (p && *p && isspace(*p))
+ *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10);
+ while (p && *p & isspace(*p))
p++;
if (p && *p)
- *dfree = STR_TO_SMB_BIG_UINT(p, &p);
- while (p && *p && isspace(*p))
+ *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10);
+ while (p && *p & isspace(*p))
p++;
if (p && *p)
- *bsize = STR_TO_SMB_BIG_UINT(p, NULL);
+ *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10);
else
*bsize = 1024;
file_lines_free(lines);
@@ -153,12 +155,12 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query,
return(dfree_retval);
}
-
/****************************************************************************
-wrap it to get filenames right
+ Wrap it to get filenames right.
****************************************************************************/
+
SMB_BIG_UINT sys_disk_free(const char *path, BOOL small_query,
SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
- return disk_free(path,small_query, bsize,dfree,dsize);
+ return(disk_free(dos_to_unix_static(path),small_query, bsize,dfree,dsize));
}
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 06ef23ab8cd..34aec3dd69d 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Directory handling routines
Copyright (C) Andrew Tridgell 1992-1998
@@ -49,17 +50,17 @@ static int dptrs_open = 0;
void init_dptrs(void)
{
- static BOOL dptrs_init=False;
+ static BOOL dptrs_init=False;
- if (dptrs_init)
- return;
+ if (dptrs_init)
+ return;
- dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
+ dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
- if (!dptr_bmap)
- exit_server("out of memory in init_dptrs");
+ if (!dptr_bmap)
+ exit_server("out of memory in init_dptrs\n");
- dptrs_init = True;
+ dptrs_init = True;
}
/****************************************************************************
@@ -68,12 +69,12 @@ void init_dptrs(void)
static void dptr_idle(dptr_struct *dptr)
{
- if (dptr->ptr) {
- DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
- dptrs_open--;
- CloseDir(dptr->ptr);
- dptr->ptr = NULL;
- }
+ if (dptr->ptr) {
+ DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
+ dptrs_open--;
+ CloseDir(dptr->ptr);
+ dptr->ptr = NULL;
+ }
}
/****************************************************************************
@@ -82,29 +83,29 @@ static void dptr_idle(dptr_struct *dptr)
static void dptr_idleoldest(void)
{
- dptr_struct *dptr;
+ dptr_struct *dptr;
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
- if(!dptr) {
- DEBUG(0,("No dptrs available to idle ?\n"));
- return;
- }
+ if(!dptr) {
+ DEBUG(0,("No dptrs available to idle ?\n"));
+ return;
+ }
- /*
- * Idle the oldest pointer.
- */
+ /*
+ * Idle the oldest pointer.
+ */
- for(; dptr; dptr = dptr->prev) {
- if (dptr->ptr) {
- dptr_idle(dptr);
- return;
- }
- }
+ for(; dptr; dptr = dptr->prev) {
+ if (dptr->ptr) {
+ dptr_idle(dptr);
+ return;
+ }
+ }
}
/****************************************************************************
@@ -113,22 +114,22 @@ static void dptr_idleoldest(void)
static dptr_struct *dptr_get(int key, BOOL forclose)
{
- dptr_struct *dptr;
-
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if(dptr->dnum == key) {
- if (!forclose && !dptr->ptr) {
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
- DEBUG(4,("Reopening dptr key %d\n",key));
- if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
- dptrs_open++;
- }
- DLIST_PROMOTE(dirptrs,dptr);
- return dptr;
- }
- }
- return(NULL);
+ dptr_struct *dptr;
+
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if(dptr->dnum == key) {
+ if (!forclose && !dptr->ptr) {
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
+ DEBUG(4,("Reopening dptr key %d\n",key));
+ if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
+ dptrs_open++;
+ }
+ DLIST_PROMOTE(dirptrs,dptr);
+ return dptr;
+ }
+ }
+ return(NULL);
}
/****************************************************************************
@@ -137,11 +138,11 @@ static dptr_struct *dptr_get(int key, BOOL forclose)
static void *dptr_ptr(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->ptr);
- return(NULL);
+ if (dptr)
+ return(dptr->ptr);
+ return(NULL);
}
/****************************************************************************
@@ -150,11 +151,11 @@ static void *dptr_ptr(int key)
char *dptr_path(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->path);
- return(NULL);
+ if (dptr)
+ return(dptr->path);
+ return(NULL);
}
/****************************************************************************
@@ -163,11 +164,11 @@ char *dptr_path(int key)
char *dptr_wcard(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->wcard);
- return(NULL);
+ if (dptr)
+ return(dptr->wcard);
+ return(NULL);
}
/****************************************************************************
@@ -177,13 +178,13 @@ char *dptr_wcard(int key)
BOOL dptr_set_wcard(int key, char *wcard)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr) {
- dptr->wcard = wcard;
- return True;
- }
- return False;
+ if (dptr) {
+ dptr->wcard = wcard;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -193,13 +194,13 @@ BOOL dptr_set_wcard(int key, char *wcard)
BOOL dptr_set_attr(int key, uint16 attr)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr) {
- dptr->attr = attr;
- return True;
- }
- return False;
+ if (dptr) {
+ dptr->attr = attr;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -208,11 +209,11 @@ BOOL dptr_set_attr(int key, uint16 attr)
uint16 dptr_attr(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->attr);
- return(0);
+ if (dptr)
+ return(dptr->attr);
+ return(0);
}
/****************************************************************************
@@ -221,31 +222,31 @@ uint16 dptr_attr(int key)
static void dptr_close_internal(dptr_struct *dptr)
{
- DEBUG(4,("closing dptr key %d\n",dptr->dnum));
+ DEBUG(4,("closing dptr key %d\n",dptr->dnum));
- DLIST_REMOVE(dirptrs, dptr);
+ DLIST_REMOVE(dirptrs, dptr);
- /*
- * Free the dnum in the bitmap. Remember the dnum value is always
- * biased by one with respect to the bitmap.
- */
+ /*
+ * Free the dnum in the bitmap. Remember the dnum value is always
+ * biased by one with respect to the bitmap.
+ */
- if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
- DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
+ if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
+ DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
dptr->dnum ));
- }
+ }
- bitmap_clear(dptr_bmap, dptr->dnum - 1);
+ bitmap_clear(dptr_bmap, dptr->dnum - 1);
- if (dptr->ptr) {
- CloseDir(dptr->ptr);
- dptrs_open--;
- }
+ if (dptr->ptr) {
+ CloseDir(dptr->ptr);
+ dptrs_open--;
+ }
- /* Lanman 2 specific code */
- SAFE_FREE(dptr->wcard);
- string_set(&dptr->path,"");
- SAFE_FREE(dptr);
+ /* Lanman 2 specific code */
+ SAFE_FREE(dptr->wcard);
+ string_set(&dptr->path,"");
+ SAFE_FREE(dptr);
}
/****************************************************************************
@@ -254,32 +255,32 @@ static void dptr_close_internal(dptr_struct *dptr)
void dptr_close(int *key)
{
- dptr_struct *dptr;
+ dptr_struct *dptr;
- if(*key == INVALID_DPTR_KEY)
- return;
+ if(*key == INVALID_DPTR_KEY)
+ return;
- /* OS/2 seems to use -1 to indicate "close all directories" */
- if (*key == -1) {
- dptr_struct *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- dptr_close_internal(dptr);
- }
- *key = INVALID_DPTR_KEY;
- return;
- }
+ /* OS/2 seems to use -1 to indicate "close all directories" */
+ if (*key == -1) {
+ dptr_struct *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ dptr_close_internal(dptr);
+ }
+ *key = INVALID_DPTR_KEY;
+ return;
+ }
- dptr = dptr_get(*key, True);
+ dptr = dptr_get(*key, True);
- if (!dptr) {
- DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
- return;
- }
+ if (!dptr) {
+ DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
+ return;
+ }
- dptr_close_internal(dptr);
+ dptr_close_internal(dptr);
- *key = INVALID_DPTR_KEY;
+ *key = INVALID_DPTR_KEY;
}
/****************************************************************************
@@ -288,12 +289,12 @@ void dptr_close(int *key)
void dptr_closecnum(connection_struct *conn)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (dptr->conn == conn)
- dptr_close_internal(dptr);
- }
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (dptr->conn == conn)
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
@@ -302,11 +303,11 @@ void dptr_closecnum(connection_struct *conn)
void dptr_idlecnum(connection_struct *conn)
{
- dptr_struct *dptr;
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if (dptr->conn == conn && dptr->ptr)
- dptr_idle(dptr);
- }
+ dptr_struct *dptr;
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if (dptr->conn == conn && dptr->ptr)
+ dptr_idle(dptr);
+ }
}
/****************************************************************************
@@ -315,41 +316,40 @@ void dptr_idlecnum(connection_struct *conn)
void dptr_closepath(char *path,uint16 spid)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (spid == dptr->spid && strequal(dptr->path,path))
- dptr_close_internal(dptr);
- }
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (spid == dptr->spid && strequal(dptr->path,path))
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
Start a directory listing.
****************************************************************************/
-static BOOL start_dir(connection_struct *conn, pstring directory)
+static BOOL start_dir(connection_struct *conn,char *directory)
{
- const char *dir2;
-
- DEBUG(5,("start_dir dir=%s\n",directory));
+ const char *dir2;
- if (!check_name(directory,conn))
- return(False);
+ DEBUG(5,("start_dir dir=%s\n",directory));
- /* use a const pointer from here on */
- dir2 = directory;
+ if (!check_name(directory,conn))
+ return(False);
- if (! *dir2)
- dir2 = ".";
-
- conn->dirptr = OpenDir(conn, directory, True);
- if (conn->dirptr) {
- dptrs_open++;
- string_set(&conn->dirpath,directory);
- return(True);
- }
+ if (! *directory)
+ dir2 = ".";
+ else
+ dir2 = directory;
+
+ conn->dirptr = OpenDir(conn, dir2, True);
+ if (conn->dirptr) {
+ dptrs_open++;
+ string_set(&conn->dirpath,dir2);
+ return(True);
+ }
- return(False);
+ return(False);
}
/****************************************************************************
@@ -360,32 +360,32 @@ static BOOL start_dir(connection_struct *conn, pstring directory)
static void dptr_close_oldest(BOOL old)
{
- dptr_struct *dptr;
+ dptr_struct *dptr;
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
- if(!dptr) {
- DEBUG(0,("No old dptrs available to close oldest ?\n"));
- return;
- }
+ if(!dptr) {
+ DEBUG(0,("No old dptrs available to close oldest ?\n"));
+ return;
+ }
- /*
- * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
- * does not have expect_close set. If 'old' is false, close
- * one of the new dnum handles.
- */
+ /*
+ * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
+ * does not have expect_close set. If 'old' is false, close
+ * one of the new dnum handles.
+ */
- for(; dptr; dptr = dptr->prev) {
- if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
- (!old && (dptr->dnum > 255))) {
- dptr_close_internal(dptr);
- return;
- }
- }
+ for(; dptr; dptr = dptr->prev) {
+ if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
+ (!old && (dptr->dnum > 255))) {
+ dptr_close_internal(dptr);
+ return;
+ }
+ }
}
/****************************************************************************
@@ -397,100 +397,101 @@ static void dptr_close_oldest(BOOL old)
me at Andrew's knee.... :-) :-). JRA.
****************************************************************************/
-int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid)
+int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid)
{
- dptr_struct *dptr;
+ dptr_struct *dptr;
- if (!start_dir(conn,path))
- return(-2); /* Code to say use a unix error return code. */
+ if (!start_dir(conn,path))
+ return(-2); /* Code to say use a unix error return code. */
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
- dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
- if(!dptr) {
- DEBUG(0,("malloc fail in dptr_create.\n"));
- return -1;
- }
+ dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
+ if(!dptr) {
+ DEBUG(0,("malloc fail in dptr_create.\n"));
+ return -1;
+ }
- ZERO_STRUCTP(dptr);
+ ZERO_STRUCTP(dptr);
- if(old_handle) {
+ if(old_handle) {
- /*
- * This is an old-style SMBsearch request. Ensure the
- * value we return will fit in the range 1-255.
- */
+ /*
+ * This is an old-style SMBsearch request. Ensure the
+ * value we return will fit in the range 1-255.
+ */
- dptr->dnum = bitmap_find(dptr_bmap, 0);
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
- if(dptr->dnum == -1 || dptr->dnum > 254) {
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
- /*
- * Try and close the oldest handle not marked for
- * expect close in the hope that the client has
- * finished with that one.
- */
+ /*
+ * Try and close the oldest handle not marked for
+ * expect close in the hope that the client has
+ * finished with that one.
+ */
- dptr_close_oldest(True);
+ dptr_close_oldest(True);
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 0);
- if(dptr->dnum == -1 || dptr->dnum > 254) {
- DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
- SAFE_FREE(dptr);
- return -1;
- }
- }
- } else {
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
- /*
- * This is a new-style trans2 request. Allocate from
- * a range that will return 256 - MAX_DIRECTORY_HANDLES.
- */
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
+ DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr);
+ return -1;
+ }
+ }
+ } else {
- dptr->dnum = bitmap_find(dptr_bmap, 255);
+ /*
+ * This is a new-style trans2 request. Allocate from
+ * a range that will return 256 - MAX_DIRECTORY_HANDLES.
+ */
- if(dptr->dnum == -1 || dptr->dnum < 255) {
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
- /*
- * Try and close the oldest handle close in the hope that
- * the client has finished with that one. This will only
- * happen in the case of the Win98 client bug where it leaks
- * directory handles.
- */
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
- dptr_close_oldest(False);
+ /*
+ * Try and close the oldest handle close in the hope that
+ * the client has finished with that one. This will only
+ * happen in the case of the Win98 client bug where it leaks
+ * directory handles.
+ */
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 255);
+ dptr_close_oldest(False);
- if(dptr->dnum == -1 || dptr->dnum < 255) {
- DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
- SAFE_FREE(dptr);
- return -1;
- }
- }
- }
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
+
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
+ DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr);
+ return -1;
+ }
+ }
+ }
- bitmap_set(dptr_bmap, dptr->dnum);
+ bitmap_set(dptr_bmap, dptr->dnum);
- dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
+ dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
- dptr->ptr = conn->dirptr;
- string_set(&dptr->path,path);
- dptr->conn = conn;
- dptr->spid = spid;
- dptr->expect_close = expect_close;
- dptr->wcard = NULL; /* Only used in lanman2 searches */
- dptr->attr = 0; /* Only used in lanman2 searches */
+ dptr->ptr = conn->dirptr;
+ string_set(&dptr->path,path);
+ dptr->conn = conn;
+ dptr->spid = spid;
+ dptr->expect_close = expect_close;
+ dptr->wcard = NULL; /* Only used in lanman2 searches */
+ dptr->attr = 0; /* Only used in lanman2 searches */
- DLIST_ADD(dirptrs, dptr);
+ DLIST_ADD(dirptrs, dptr);
- DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- dptr->dnum,path,expect_close));
+ DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
+ dptr->dnum,path,expect_close));
- return(dptr->dnum);
+ return(dptr->dnum);
}
/****************************************************************************
@@ -499,19 +500,19 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp
BOOL dptr_fill(char *buf1,unsigned int key)
{
- unsigned char *buf = (unsigned char *)buf1;
- void *p = dptr_ptr(key);
- uint32 offset;
- if (!p) {
- DEBUG(1,("filling null dirptr %d\n",key));
- return(False);
- }
- offset = TellDir(p);
- DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
- (long)p,(int)offset));
- buf[0] = key;
- SIVAL(buf,1,offset | DPTR_MASK);
- return(True);
+ unsigned char *buf = (unsigned char *)buf1;
+ void *p = dptr_ptr(key);
+ uint32 offset;
+ if (!p) {
+ DEBUG(1,("filling null dirptr %d\n",key));
+ return(False);
+ }
+ offset = TellDir(p);
+ DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
+ (long)p,(int)offset));
+ buf[0] = key;
+ SIVAL(buf,1,offset | DPTR_MASK);
+ return(True);
}
/****************************************************************************
@@ -520,20 +521,19 @@ BOOL dptr_fill(char *buf1,unsigned int key)
void *dptr_fetch(char *buf,int *num)
{
- unsigned int key = *(unsigned char *)buf;
- void *p = dptr_ptr(key);
- uint32 offset;
-
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",key));
- return(NULL);
- }
- *num = key;
- offset = IVAL(buf,1)&~DPTR_MASK;
- SeekDir(p,offset);
- DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
- key,dptr_path(key),offset));
- return(p);
+ unsigned int key = *(unsigned char *)buf;
+ void *p = dptr_ptr(key);
+ uint32 offset;
+ if (!p) {
+ DEBUG(3,("fetched null dirptr %d\n",key));
+ return(NULL);
+ }
+ *num = key;
+ offset = IVAL(buf,1)&~DPTR_MASK;
+ SeekDir(p,offset);
+ DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
+ key,dptr_path(key),offset));
+ return(p);
}
/****************************************************************************
@@ -542,14 +542,14 @@ void *dptr_fetch(char *buf,int *num)
void *dptr_fetch_lanman2(int dptr_num)
{
- void *p = dptr_ptr(dptr_num);
+ void *p = dptr_ptr(dptr_num);
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",dptr_num));
- return(NULL);
- }
- DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
- return(p);
+ if (!p) {
+ DEBUG(3,("fetched null dirptr %d\n",dptr_num));
+ return(NULL);
+ }
+ DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
+ return(p);
}
/****************************************************************************
@@ -578,7 +578,7 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
return True;
}
-static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
+static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask)
{
mangle_map(filename,True,False,SNUM(conn));
return mask_match(filename,mask,False);
@@ -588,163 +588,122 @@ static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *m
Get an 8.3 directory entry.
****************************************************************************/
-BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname,
+BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
{
- const char *dname;
- BOOL found = False;
- SMB_STRUCT_STAT sbuf;
- pstring path;
- pstring pathreal;
- BOOL isrootdir;
- pstring filename;
- BOOL needslash;
-
- *path = *pathreal = *filename = 0;
-
- isrootdir = (strequal(conn->dirpath,"./") ||
- strequal(conn->dirpath,".") ||
- strequal(conn->dirpath,"/"));
+ char *dname;
+ BOOL found = False;
+ SMB_STRUCT_STAT sbuf;
+ pstring path;
+ pstring pathreal;
+ BOOL isrootdir;
+ pstring filename;
+ BOOL needslash;
+
+ *path = *pathreal = *filename = 0;
+
+ isrootdir = (strequal(conn->dirpath,"./") ||
+ strequal(conn->dirpath,".") ||
+ strequal(conn->dirpath,"/"));
- needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+ needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
- if (!conn->dirptr)
- return(False);
+ if (!conn->dirptr)
+ return(False);
- while (!found) {
- dname = ReadDirName(conn->dirptr);
+ while (!found)
+ {
+ dname = ReadDirName(conn->dirptr);
- DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
- (long)conn->dirptr,TellDir(conn->dirptr)));
+ DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+ (long)conn->dirptr,TellDir(conn->dirptr)));
- if (dname == NULL)
- return(False);
+ if (dname == NULL)
+ return(False);
- pstrcpy(filename,dname);
-
- /* notice the special *.* handling. This appears to be the only difference
- between the wildcard handling in this routine and in the trans2 routines.
- see masktest for a demo
- */
- if ((strcmp(mask,"*.*") == 0) ||
- mask_match(filename,mask,False) ||
- mangle_mask_match(conn,filename,mask)) {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
-
- if (!mangle_is_8_3(filename, False))
- mangle_map(filename,True,False,SNUM(conn));
-
- pstrcpy(fname,filename);
- *path = 0;
- pstrcpy(path,conn->dirpath);
- if(needslash)
- pstrcat(path,"/");
- pstrcpy(pathreal,path);
- pstrcat(path,fname);
- pstrcat(pathreal,dname);
- if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) {
- DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
- continue;
- }
+ pstrcpy(filename,dname);
+
+ /* notice the special *.* handling. This appears to be the only difference
+ between the wildcard handling in this routine and in the trans2 routines.
+ see masktest for a demo
+ */
+ if ((strcmp(mask,"*.*") == 0) ||
+ mask_match(filename,mask,False) ||
+ mangle_mask_match(conn,filename,mask))
+ {
+ if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+ continue;
+
+ if (!mangle_is_8_3(filename, False)) {
+ mangle_map(filename,True,False,SNUM(conn));
+ }
+
+ pstrcpy(fname,filename);
+ *path = 0;
+ pstrcpy(path,conn->dirpath);
+ if(needslash)
+ pstrcat(path,"/");
+ pstrcpy(pathreal,path);
+ pstrcat(path,fname);
+ pstrcat(pathreal,dname);
+ if (conn->vfs_ops.stat(conn,dos_to_unix_static(pathreal), &sbuf) != 0)
+ {
+ DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+ continue;
+ }
- *mode = dos_mode(conn,pathreal,&sbuf);
-
- if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
- DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
- continue;
- }
+ *mode = dos_mode(conn,pathreal,&sbuf);
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ if (!dir_check_ftype(conn,*mode,&sbuf,dirtype))
+ {
+ DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+ continue;
+ }
- DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
+ *size = sbuf.st_size;
+ *date = sbuf.st_mtime;
- found = True;
- }
- }
+ DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
+
+ found = True;
+ }
+ }
- return(found);
+ return(found);
}
-typedef struct {
- int pos;
- int numentries;
- int mallocsize;
- char *data;
- char *current;
-} Dir;
-/*******************************************************************
- Check to see if a user can read a file. This is only approximate,
- it is used as part of the "hide unreadable" option. Don't
- use it for anything security sensitive.
-********************************************************************/
-static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
+typedef struct
{
- extern struct current_user current_user;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- files_struct *fsp;
- int smb_action;
- NTSTATUS status;
- uint32 access_granted;
-
- /*
- * If user is a member of the Admin group
- * we never hide files from them.
- */
-
- if (conn->admin_user)
- return True;
-
- /* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
- return False;
-
- /* Pseudo-open the file (note - no fd's created). */
+ int pos;
+ int numentries;
+ int mallocsize;
+ char *data;
+ char *current;
+} Dir;
- if(S_ISDIR(pst->st_mode))
- fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- &smb_action);
- else
- fsp = open_file_stat(conn, name, pst);
- if (!fsp)
- return False;
-
- /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
- (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
- close_file(fsp, True);
-
- /* No access if SD get failed. */
- if (!sd_size)
- return False;
-
- return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
- &access_granted, &status);
-}
/*******************************************************************
- Check to see if a user can write a file (and only files, we do not
- check dirs on this one). This is only approximate,
- it is used as part of the "hide unwriteable" option. Don't
- use it for anything security sensitive.
+check to see if a user can read a file. This is only approximate,
+it is used as part of the "hide unreadable" option. Don't
+use it for anything security sensitive
********************************************************************/
-static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
+static BOOL user_can_read_file(connection_struct *conn, char *name)
{
extern struct current_user current_user;
+ SMB_STRUCT_STAT ste;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
int smb_action;
- int access_mode;
NTSTATUS status;
uint32 access_granted;
+ ZERO_STRUCT(ste);
+
/*
* If user is a member of the Admin group
* we never hide files from them.
@@ -754,58 +713,33 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
return True;
/* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
+ if (vfs_stat(conn, name, &ste) != 0)
return False;
/* Pseudo-open the file (note - no fd's created). */
- if(S_ISDIR(pst->st_mode))
- return True;
+ if(S_ISDIR(ste.st_mode))
+ fsp = open_directory(conn, name, &ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ unix_mode(conn,aRONLY|aDIR, name), &smb_action);
else
- fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
+ fsp = open_file_stat(conn, name, &ste);
if (!fsp)
return False;
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
- (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
- close_file(fsp, False);
+ sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ close_file(fsp, True);
/* No access if SD get failed. */
if (!sd_size)
return False;
- return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
+ return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
&access_granted, &status);
}
/*******************************************************************
- Is a file a "special" type ?
-********************************************************************/
-
-static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
-{
- /*
- * If user is a member of the Admin group
- * we never hide files from them.
- */
-
- if (conn->admin_user)
- return False;
-
- /* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
- return True;
-
- if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Open a directory.
********************************************************************/
@@ -813,25 +747,24 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
{
Dir *dirp;
const char *n;
- DIR *p = SMB_VFS_OPENDIR(conn,name);
+ DIR *p = conn->vfs_ops.opendir(conn,dos_to_unix_static(name));
int used=0;
-
+
if (!p)
return(NULL);
dirp = (Dir *)malloc(sizeof(Dir));
if (!dirp) {
DEBUG(0,("Out of memory in OpenDir\n"));
- SMB_VFS_CLOSEDIR(conn,p);
+ conn->vfs_ops.closedir(conn,p);
return(NULL);
}
+
dirp->pos = dirp->numentries = dirp->mallocsize = 0;
dirp->data = dirp->current = NULL;
while (True) {
int l;
BOOL normal_entry = True;
- SMB_STRUCT_STAT st;
- char *entry = NULL;
if (used == 0) {
n = ".";
@@ -846,75 +779,48 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
if ((strcmp(".",n) == 0) ||(strcmp("..",n) == 0))
continue;
normal_entry = True;
- }
+ }
- ZERO_STRUCT(st);
l = strlen(n)+1;
+ /* Return value of vfs_readdirname has already gone through
+ unix_to_dos() */
+
/* If it's a vetoed file, pretend it doesn't even exist */
if (normal_entry && use_veto && conn && IS_VETO_PATH(conn, n))
continue;
/* Honour _hide unreadable_ option */
if (normal_entry && conn && lp_hideunreadable(SNUM(conn))) {
+ char *entry;
int ret=0;
- if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_read_file(conn, entry, &st);
- }
- if (!ret) {
- SAFE_FREE(entry);
- continue;
- }
- }
-
- /* Honour _hide unwriteable_ option */
- if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
- int ret=0;
-
- if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_write_file(conn, entry, &st);
- }
- if (!ret) {
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_read_file(conn, entry);
SAFE_FREE(entry);
- continue;
- }
- }
-
- /* Honour _hide_special_ option */
- if (normal_entry && conn && lp_hide_special_files(SNUM(conn))) {
- int ret=0;
-
- if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = file_is_special(conn, entry, &st);
}
- if (ret) {
- SAFE_FREE(entry);
+ if (!ret)
continue;
- }
}
- SAFE_FREE(entry);
-
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
char *r;
r = (char *)Realloc(dirp->data,s);
if (!r) {
DEBUG(0,("Out of memory in OpenDir\n"));
- break;
- }
+ break;
+ }
dirp->data = r;
dirp->mallocsize = s;
dirp->current = dirp->data;
}
-
- safe_strcpy_base(dirp->data+used,n, dirp->data, dirp->mallocsize);
+ pstrcpy(dirp->data+used,n);
used += l;
dirp->numentries++;
}
- SMB_VFS_CLOSEDIR(conn,p);
+ conn->vfs_ops.closedir(conn,p);
return((void *)dirp);
}
@@ -925,51 +831,49 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
void CloseDir(void *p)
{
- if (!p)
- return;
- SAFE_FREE(((Dir *)p)->data);
- SAFE_FREE(p);
+ Dir *dirp = (Dir *)p;
+ if (!dirp) return;
+ SAFE_FREE(dirp->data);
+ SAFE_FREE(dirp);
}
/*******************************************************************
Read from a directory.
********************************************************************/
-const char *ReadDirName(void *p)
+char *ReadDirName(void *p)
{
- char *ret;
- Dir *dirp = (Dir *)p;
+ char *ret;
+ Dir *dirp = (Dir *)p;
- if (!dirp || !dirp->current || dirp->pos >= dirp->numentries)
- return(NULL);
+ if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) return(NULL);
- ret = dirp->current;
- dirp->current = skip_string(dirp->current,1);
- dirp->pos++;
+ ret = dirp->current;
+ dirp->current = skip_string(dirp->current,1);
+ dirp->pos++;
- return(ret);
+ return(ret);
}
+
/*******************************************************************
Seek a dir.
********************************************************************/
BOOL SeekDir(void *p,int pos)
{
- Dir *dirp = (Dir *)p;
+ Dir *dirp = (Dir *)p;
- if (!dirp)
- return(False);
+ if (!dirp) return(False);
- if (pos < dirp->pos) {
- dirp->current = dirp->data;
- dirp->pos = 0;
- }
+ if (pos < dirp->pos) {
+ dirp->current = dirp->data;
+ dirp->pos = 0;
+ }
- while (dirp->pos < pos && ReadDirName(p))
- ;
+ while (dirp->pos < pos && ReadDirName(p)) ;
- return (dirp->pos == pos);
+ return(dirp->pos == pos);
}
/*******************************************************************
@@ -978,12 +882,11 @@ BOOL SeekDir(void *p,int pos)
int TellDir(void *p)
{
- Dir *dirp = (Dir *)p;
+ Dir *dirp = (Dir *)p;
- if (!dirp)
- return(-1);
+ if (!dirp) return(-1);
- return(dirp->pos);
+ return(dirp->pos);
}
/*******************************************************************************
@@ -992,11 +895,11 @@ int TellDir(void *p)
********************************************************************************/
typedef struct {
- ubi_dlNode node;
- char *path;
- char *name;
- char *dname;
- int snum;
+ ubi_dlNode node;
+ char *path;
+ char *name;
+ char *dname;
+ int snum;
} dir_cache_entry;
static ubi_dlNewList( dir_cache );
@@ -1012,36 +915,36 @@ static ubi_dlNewList( dir_cache );
void DirCacheAdd( const char *path, const char *name, const char *dname, int snum )
{
- int pathlen;
- int namelen;
- dir_cache_entry *entry;
-
- /*
- * Allocate the structure & string space in one go so that it can be freed
- * in one call to free().
- */
- pathlen = strlen(path) + 1; /* Bytes required to store path (with nul). */
- namelen = strlen(name) + 1; /* Bytes required to store name (with nul). */
- entry = (dir_cache_entry *)malloc( sizeof( dir_cache_entry )
- + pathlen
- + namelen
- + strlen( dname ) +1 );
- if( NULL == entry ) /* Not adding to the cache is not fatal, */
- return; /* so just return as if nothing happened. */
-
- /* Set pointers correctly and load values. */
+ int pathlen;
+ int namelen;
+ dir_cache_entry *entry;
+
+ /* Allocate the structure & string space in one go so that it can be freed
+ * in one call to free().
+ */
+ pathlen = strlen( path ) +1; /* Bytes required to store path (with nul). */
+ namelen = strlen( name ) +1; /* Bytes required to store name (with nul). */
+ entry = (dir_cache_entry *)malloc( sizeof( dir_cache_entry )
+ + pathlen
+ + namelen
+ + strlen( dname ) +1 );
+ if( NULL == entry ) /* Not adding to the cache is not fatal, */
+ return; /* so just return as if nothing happened. */
+
+ /* Set pointers correctly and load values. */
entry->path = memcpy( (char *)&entry[1], path, strlen(path)+1 );
entry->name = memcpy( &(entry->path[pathlen]), name, strlen(name)+1 );
entry->dname = memcpy( &(entry->name[namelen]), dname, strlen(dname)+1 );
- entry->snum = snum;
+ entry->snum = snum;
+
+ /* Add the new entry to the linked list. */
+ (void)ubi_dlAddHead( dir_cache, entry );
+ DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
- /* Add the new entry to the linked list. */
- (void)ubi_dlAddHead( dir_cache, entry );
- DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
+ /* Free excess cache entries. */
+ while( DIRCACHESIZE < dir_cache->count )
+ safe_free( ubi_dlRemTail( dir_cache ) );
- /* Free excess cache entries. */
- while( DIRCACHESIZE < dir_cache->count )
- safe_free( ubi_dlRemTail( dir_cache ) );
}
/*****************************************************************************
@@ -1059,20 +962,22 @@ void DirCacheAdd( const char *path, const char *name, const char *dname, int snu
char *DirCacheCheck( const char *path, const char *name, int snum )
{
- dir_cache_entry *entry;
-
- for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
- NULL != entry;
- entry = (dir_cache_entry *)ubi_dlNext( entry ) ) {
- if( entry->snum == snum
- && entry->name && 0 == strcmp( name, entry->name )
- && entry->path && 0 == strcmp( path, entry->path ) ) {
- DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
- return( entry->dname );
- }
- }
-
- return(NULL);
+ dir_cache_entry *entry;
+
+ for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
+ NULL != entry;
+ entry = (dir_cache_entry *)ubi_dlNext( entry ) )
+ {
+ if( entry->snum == snum
+ && entry->name && 0 == strcmp( name, entry->name )
+ && entry->path && 0 == strcmp( path, entry->path ) )
+ {
+ DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
+ return( entry->dname );
+ }
+ }
+
+ return(NULL);
}
/*****************************************************************************
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index d7dc63bb2fd..ee54417c247 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
dos mode handling functions
Copyright (C) Andrew Tridgell 1992-1998
@@ -21,8 +22,8 @@
#include "includes.h"
/****************************************************************************
- Change a dos mode to a unix mode.
- Base permission for files:
+ change a dos mode to a unix mode
+ base permission for files:
if inheriting
apply read/write bits from parent directory.
else
@@ -35,288 +36,151 @@
Then apply create mask,
then add force bits.
}
- Base permission for directories:
+ base permission for directories:
dos directory is represented in unix by unix's dir bit and the exec bit
if !inheriting {
Then apply create mask,
then add force bits.
}
****************************************************************************/
-
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname)
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
{
- mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
- mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
-
- if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) {
- result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- }
-
- if (fname && lp_inherit_perms(SNUM(conn))) {
- char *dname;
- SMB_STRUCT_STAT sbuf;
-
- dname = parent_dirname(fname);
- DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
- if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) {
- DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
- return(0); /* *** shouldn't happen! *** */
- }
-
- /* Save for later - but explicitly remove setuid bit for safety. */
- dir_mode = sbuf.st_mode & ~S_ISUID;
- DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
- /* Clear "result" */
- result = 0;
- }
-
- if (IS_DOS_DIR(dosmode)) {
- /* We never make directories read only for the owner as under DOS a user
- can always create a file in a read-only directory. */
- result |= (S_IFDIR | S_IWUSR);
-
- if (dir_mode) {
- /* Inherit mode of parent directory. */
- result |= dir_mode;
- } else {
- /* Provisionally add all 'x' bits */
- result |= (S_IXUSR | S_IXGRP | S_IXOTH);
-
- /* Apply directory mask */
- result &= lp_dir_mask(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_dir_mode(SNUM(conn));
- }
- } else {
- if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
- result |= S_IXUSR;
-
- if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
- result |= S_IXGRP;
+ mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
+ mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
+
+ if ( !IS_DOS_READONLY(dosmode) )
+ result |= (S_IWUSR | S_IWGRP | S_IWOTH);
+
+ if (fname && lp_inherit_perms(SNUM(conn))) {
+ char *dname;
+ SMB_STRUCT_STAT sbuf;
+
+ dname = parent_dirname(fname);
+ DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
+ if (vfs_stat(conn,dname,&sbuf) != 0) {
+ DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
+ return(0); /* *** shouldn't happen! *** */
+ }
+
+ /* Save for later - but explicitly remove setuid bit for safety. */
+ dir_mode = sbuf.st_mode & ~S_ISUID;
+ DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
+ /* Clear "result" */
+ result = 0;
+ }
+
+ if (IS_DOS_DIR(dosmode)) {
+ /* We never make directories read only for the owner as under DOS a user
+ can always create a file in a read-only directory. */
+ result |= (S_IFDIR | S_IWUSR);
+
+ if (dir_mode) {
+ /* Inherit mode of parent directory. */
+ result |= dir_mode;
+ } else {
+ /* Provisionally add all 'x' bits */
+ result |= (S_IXUSR | S_IXGRP | S_IXOTH);
+
+ /* Apply directory mask */
+ result &= lp_dir_mask(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_dir_mode(SNUM(conn));
+ }
+ } else {
+ if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
+ result |= S_IXUSR;
+
+ if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
+ result |= S_IXGRP;
- if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
- result |= S_IXOTH;
-
- if (dir_mode) {
- /* Inherit 666 component of parent directory mode */
- result |= dir_mode & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
- } else {
- /* Apply mode mask */
- result &= lp_create_mask(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_create_mode(SNUM(conn));
- }
- }
-
- DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result ));
- return(result);
+ if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
+ result |= S_IXOTH;
+
+ if (dir_mode) {
+ /* Inherit 666 component of parent directory mode */
+ result |= dir_mode
+ & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
+ } else {
+ /* Apply mode mask */
+ result &= lp_create_mask(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_create_mode(SNUM(conn));
+ }
+ }
+
+ DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result ));
+ return(result);
}
-/****************************************************************************
- Change a unix mode to a dos mode.
-****************************************************************************/
-
-uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf)
-{
- int result = 0;
-
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
-
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
-
- if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
- result |= aSYSTEM;
-
- if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
-
- if (S_ISDIR(sbuf->st_mode))
- result = aDIR | (result & aRONLY);
-
-#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE)
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
- result |= FILE_ATTRIBUTE_SPARSE;
- }
-#endif
-
-#ifdef S_ISLNK
-#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
-#endif
-#endif
-
- DEBUG(8,("dos_mode_from_sbuf returning "));
-
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
-
- DEBUG(8,("\n"));
- return result;
-}
/****************************************************************************
- Get DOS attributes from an EA.
+ change a unix mode to a dos mode
****************************************************************************/
-
-static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr)
+int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
{
- ssize_t sizeret;
- fstring attrstr;
- unsigned int dosattr;
+ int result = 0;
- if (!lp_store_dos_attributes(SNUM(conn))) {
- return False;
- }
+ DEBUG(8,("dos_mode: %s\n", path));
- *pattr = 0;
+ if ((sbuf->st_mode & S_IWUSR) == 0)
+ result |= aRONLY;
- sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr));
- if (sizeret == -1) {
-#if defined(ENOTSUP) && defined(ENOATTR)
- if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES)) {
- DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n",
- path, strerror(errno) ));
- }
-#endif
- return False;
- }
- /* Null terminate string. */
- attrstr[sizeret] = 0;
- DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n", path, attrstr));
-
- if (sizeret < 2 || attrstr[0] != '0' || attrstr[1] != 'x' ||
- sscanf(attrstr, "%x", &dosattr) != 1) {
- DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on file %s - %s\n", path, attrstr));
- return False;
- }
-
- if (S_ISDIR(sbuf->st_mode)) {
- dosattr |= aDIR;
- }
- *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
-
- DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));
-
- if (dosattr & aHIDDEN) DEBUG(8, ("h"));
- if (dosattr & aRONLY ) DEBUG(8, ("r"));
- if (dosattr & aSYSTEM) DEBUG(8, ("s"));
- if (dosattr & aDIR ) DEBUG(8, ("d"));
- if (dosattr & aARCH ) DEBUG(8, ("a"));
-
- DEBUG(8,("\n"));
-
- return True;
-}
-
-/****************************************************************************
- Set DOS attributes in an EA.
-****************************************************************************/
-
-static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode)
-{
- fstring attrstr;
- files_struct *fsp = NULL;
- BOOL ret = False;
-
- snprintf(attrstr, sizeof(attrstr)-1, "0x%x", dosmode & SAMBA_ATTRIBUTES_MASK);
- if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == -1) {
- if((errno != EPERM) && (errno != EACCES)) {
- return False;
- }
+ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ result |= aARCH;
- /* We want DOS semantics, ie allow non owner with write permission to change the
- bits on a file. Just like file_utime below.
- */
+ if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
+ result |= aSYSTEM;
- /* Check if we have write access. */
- if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
- return False;
-
- /*
- * We need to open the file with write access whilst
- * still in our current user context. This ensures we
- * are not violating security in doing the setxattr.
- */
-
- fsp = open_file_fchmod(conn,path,sbuf);
- if (!fsp)
- return ret;
- become_root();
- if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) {
- ret = True;
- }
- unbecome_root();
- close_file_fchmod(fsp);
- return ret;
- }
- DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path));
- return True;
-}
-
-/****************************************************************************
- Change a unix mode to a dos mode.
-****************************************************************************/
-
-uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
-{
- uint32 result = 0;
-
- DEBUG(8,("dos_mode: %s\n", path));
-
- if (!VALID_STAT(*sbuf)) {
- return 0;
- }
-
- /* Get the DOS attributes from an EA by preference. */
- if (get_ea_dos_attribute(conn, path, sbuf, &result)) {
- return result;
- }
-
- result = dos_mode_from_sbuf(conn, sbuf);
-
- /* Now do any modifications that depend on the path name. */
- /* hide files with a name starting with a . */
- if (lp_hide_dot_files(SNUM(conn))) {
- const char *p = strrchr_m(path,'/');
- if (p)
- p++;
- else
- p = path;
-
- if (p[0] == '.' && p[1] != '.' && p[1] != 0)
- result |= aHIDDEN;
- }
-
- /* Optimization : Only call is_hidden_path if it's not already
- hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
- result |= aHIDDEN;
- }
-
- DEBUG(8,("dos_mode returning "));
-
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
-
- DEBUG(8,("\n"));
+ if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
+ result |= aHIDDEN;
+
+ if (S_ISDIR(sbuf->st_mode))
+ result = aDIR | (result & aRONLY);
+
+#ifdef S_ISLNK
+#if LINKS_READ_ONLY
+ if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
+ result |= aRONLY;
+#endif
+#endif
- return(result);
+ /* hide files with a name starting with a . */
+ if (lp_hide_dot_files(SNUM(conn)))
+ {
+ char *p = strrchr(path,'/');
+ if (p)
+ p++;
+ else
+ p = path;
+
+ if (p[0] == '.' && p[1] != '.' && p[1] != 0)
+ result |= aHIDDEN;
+ }
+
+ /* Optimization : Only call is_hidden_path if it's not already
+ hidden. */
+ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path))
+ {
+ result |= aHIDDEN;
+ }
+
+ DEBUG(8,("dos_mode returning "));
+
+ if (result & aHIDDEN) DEBUG(8, ("h"));
+ if (result & aRONLY ) DEBUG(8, ("r"));
+ if (result & aSYSTEM) DEBUG(8, ("s"));
+ if (result & aDIR ) DEBUG(8, ("d"));
+ if (result & aARCH ) DEBUG(8, ("a"));
+
+ DEBUG(8,("\n"));
+
+ return(result);
}
/*******************************************************************
- chmod a file - but preserve some bits.
+chmod a file - but preserve some bits
********************************************************************/
-
-int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st)
+int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st)
{
SMB_STRUCT_STAT st1;
int mask=0;
@@ -324,15 +188,12 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
mode_t unixmode;
int ret = -1;
- DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
if (!st) {
st = &st1;
- if (SMB_VFS_STAT(conn,fname,st))
+ if (vfs_stat(conn,fname,st))
return(-1);
}
- get_acl_group_bits(conn, fname, &st->st_mode);
-
if (S_ISDIR(st->st_mode))
dosmode |= aDIR;
else
@@ -341,11 +202,6 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
if (dos_mode(conn,fname,st) == dosmode)
return(0);
- /* Store the DOS attributes in an EA by preference. */
- if (set_ea_dos_attribute(conn, fname, st, dosmode)) {
- return 0;
- }
-
unixmode = unix_mode(conn,dosmode,fname);
/* preserve the s bits */
@@ -378,7 +234,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
- if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0)
+ if ((ret = vfs_chmod(conn,fname,unixmode)) == 0)
return 0;
if((errno != EPERM) && (errno != EACCES))
@@ -405,7 +261,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
if (!fsp)
return -1;
become_root();
- ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode);
+ ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode);
unbecome_root();
close_file_fchmod(fsp);
}
@@ -413,71 +269,70 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
return( ret );
}
+
/*******************************************************************
- Wrapper around dos_utime that possibly allows DOS semantics rather
- than POSIX.
+Wrapper around dos_utime that possibly allows DOS semantics rather
+than POSIX.
*******************************************************************/
-
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
{
- extern struct current_user current_user;
- SMB_STRUCT_STAT sb;
- int ret = -1;
-
- errno = 0;
-
- if(SMB_VFS_UTIME(conn,fname, times) == 0)
- return 0;
-
- if((errno != EPERM) && (errno != EACCES))
- return -1;
-
- if(!lp_dos_filetimes(SNUM(conn)))
- return -1;
-
- /* We have permission (given by the Samba admin) to
- break POSIX semantics and allow a user to change
- the time on a file they don't own but can write to
- (as DOS does).
- */
-
- if(SMB_VFS_STAT(conn,fname,&sb) != 0)
- return -1;
-
- /* Check if we have write access. */
- if (CAN_WRITE(conn)) {
- if (((sb.st_mode & S_IWOTH) || conn->admin_user ||
- ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
- ((sb.st_mode & S_IWGRP) &&
- in_group(sb.st_gid,current_user.gid,
- current_user.ngroups,current_user.groups)))) {
- /* We are allowed to become root and change the filetime. */
- become_root();
- ret = SMB_VFS_UTIME(conn,fname, times);
- unbecome_root();
- }
- }
-
- return ret;
+ extern struct current_user current_user;
+ SMB_STRUCT_STAT sb;
+ int ret = -1;
+
+ errno = 0;
+
+ if(conn->vfs_ops.utime(conn,dos_to_unix_static(fname), times) == 0)
+ return 0;
+
+ if((errno != EPERM) && (errno != EACCES))
+ return -1;
+
+ if(!lp_dos_filetimes(SNUM(conn)))
+ return -1;
+
+ /* We have permission (given by the Samba admin) to
+ break POSIX semantics and allow a user to change
+ the time on a file they don't own but can write to
+ (as DOS does).
+ */
+
+ if(vfs_stat(conn,fname,&sb) != 0)
+ return -1;
+
+ /* Check if we have write access. */
+ if (CAN_WRITE(conn)) {
+ if (((sb.st_mode & S_IWOTH) ||
+ conn->admin_user ||
+ ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
+ ((sb.st_mode & S_IWGRP) &&
+ in_group(sb.st_gid,current_user.gid,
+ current_user.ngroups,current_user.groups)))) {
+ /* We are allowed to become root and change the filetime. */
+ become_root();
+ ret = conn->vfs_ops.utime(conn,dos_to_unix_static(fname), times);
+ unbecome_root();
+ }
+ }
+
+ return ret;
}
/*******************************************************************
- Change a filetime - possibly allowing DOS semantics.
+Change a filetime - possibly allowing DOS semantics.
*******************************************************************/
-
BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
{
- struct utimbuf times;
+ struct utimbuf times;
- if (null_mtime(mtime))
- return(True);
+ if (null_mtime(mtime)) return(True);
- times.modtime = times.actime = mtime;
+ times.modtime = times.actime = mtime;
- if (file_utime(conn, fname, &times)) {
- DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
- return False;
- }
+ if (file_utime(conn, fname, &times)) {
+ DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
+ return False;
+ }
- return(True);
+ return(True);
}
diff --git a/source/smbd/error.c b/source/smbd/error.c
index 9c81d465e7a..6426ea5cad0 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
error packet handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -40,9 +41,8 @@ int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file
int32 err = wbmpx->wr_error;
/* We can now delete the auxiliary struct */
- free((char *)wbmpx);
- fsp->wbmpx_ptr = NULL;
- return error_packet(outbuf,NT_STATUS_OK,eclass,err,False,line,file);
+ SAFE_FREE(wbmpx);
+ return error_packet(outbuf,NT_STATUS_OK,eclass,err,line,file);
}
/****************************************************************************
@@ -76,7 +76,7 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
}
}
- return error_packet(outbuf,ntstatus,eclass,ecode,False,line,file);
+ return error_packet(outbuf,ntstatus,eclass,ecode,line,file);
}
@@ -85,7 +85,7 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
****************************************************************************/
int error_packet(char *outbuf,NTSTATUS ntstatus,
- uint8 eclass,uint32 ecode,BOOL force_dos, int line, const char *file)
+ uint8 eclass,uint32 ecode,int line, const char *file)
{
int outsize = set_message(outbuf,0,0,True);
extern uint32 global_client_caps;
@@ -93,11 +93,6 @@ int error_packet(char *outbuf,NTSTATUS ntstatus,
if (errno != 0)
DEBUG(3,("error string = %s\n",strerror(errno)));
-#if defined(DEVELOPER)
- if (unix_ERR_class != SMB_SUCCESS || unix_ERR_code != 0 || !NT_STATUS_IS_OK(unix_ERR_ntstatus))
- smb_panic("logic error in error processing");
-#endif
-
/*
* We can explicitly force 32 bit error codes even when the
* parameter "nt status" is set to no by pre-setting the
@@ -106,7 +101,7 @@ int error_packet(char *outbuf,NTSTATUS ntstatus,
* when talking with clients that normally expect nt status codes. JRA.
*/
- if ((lp_nt_status_support() || (SVAL(outbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) && (global_client_caps & CAP_STATUS32) && (!force_dos)) {
+ if ((lp_nt_status_support() || (SVAL(outbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) && (global_client_caps & CAP_STATUS32)) {
if (NT_STATUS_V(ntstatus) == 0 && eclass)
ntstatus = dos_to_ntstatus(eclass, ecode);
SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus));
@@ -115,7 +110,7 @@ int error_packet(char *outbuf,NTSTATUS ntstatus,
file, line,
(int)CVAL(outbuf,smb_com),
smb_fn_name(CVAL(outbuf,smb_com)),
- nt_errstr(ntstatus)));
+ get_nt_error_msg(ntstatus)));
return outsize;
}
diff --git a/source/smbd/fake_file.c b/source/smbd/fake_file.c
deleted file mode 100644
index d3660addf11..00000000000
--- a/source/smbd/fake_file.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- FAKE FILE suppport, for faking up special files windows want access to
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/****************************************************************************
- Open a file with a share mode.
-****************************************************************************/
-files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname,
- SMB_STRUCT_STAT *psbuf,
- uint32 desired_access,
- int share_mode,int ofun, uint32 new_dos_attr, int oplock_request,
- int *Access,int *action)
-{
- extern struct current_user current_user;
- int flags=0;
- files_struct *fsp = NULL;
-
- if (fake_file_type == 0) {
- return open_file_shared1(conn,fname,psbuf,desired_access,
- share_mode,ofun,new_dos_attr,
- oplock_request,Access,action);
- }
-
- /* access check */
- if (current_user.uid != 0) {
- DEBUG(1,("access_denied to service[%s] file[%s] user[%s]\n",
- lp_servicename(SNUM(conn)),fname,conn->user));
- errno = EACCES;
- return NULL;
- }
-
- fsp = file_new(conn);
- if(!fsp)
- return NULL;
-
- DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n",
- fname, fsp->fnum, share_mode, ofun, oplock_request ));
-
- if (!check_name(fname,conn)) {
- file_free(fsp);
- return NULL;
- }
-
- fsp->fd = -1;
- fsp->mode = psbuf->st_mode;
- fsp->inode = psbuf->st_ino;
- fsp->dev = psbuf->st_dev;
- fsp->vuid = current_user.vuid;
- fsp->size = psbuf->st_size;
- fsp->pos = -1;
- fsp->can_lock = True;
- fsp->can_read = ((flags & O_WRONLY)==0);
- fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
- fsp->share_mode = 0;
- fsp->desired_access = desired_access;
- fsp->print_file = False;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->is_stat = False;
- fsp->directory_delete_on_close = False;
- fsp->conn = conn;
- string_set(&fsp->fsp_name,fname);
- fsp->wcp = NULL; /* Write cache pointer. */
-
- fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
-
- if (fsp->fake_file_handle==NULL) {
- file_free(fsp);
- return NULL;
- }
-
- conn->num_files_open++;
- return fsp;
-}
-
-static FAKE_FILE fake_files[] = {
-#ifdef WITH_QUOTAS
- {FAKE_FILE_NAME_QUOTA, FAKE_FILE_TYPE_QUOTA, init_quota_handle, destroy_quota_handle},
-#endif /* WITH_QUOTAS */
- {NULL, FAKE_FILE_TYPE_NONE, NULL, NULL }
-};
-
-int is_fake_file(char *fname)
-{
- int i;
-
- if (!fname)
- return 0;
-
- for (i=0;fake_files[i].name!=NULL;i++) {
- if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
- DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
- return fake_files[i].type;
- }
- }
-
- return FAKE_FILE_TYPE_NONE;
-}
-
-struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
-{
- TALLOC_CTX *mem_ctx = NULL;
- FAKE_FILE_HANDLE *fh = NULL;
- int i;
-
- for (i=0;fake_files[i].name!=NULL;i++) {
- if (fake_files[i].type==type) {
- DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
-
- if ((mem_ctx=talloc_init("fake_file_handle"))==NULL) {
- DEBUG(0,("talloc_init(fake_file_handle) failed.\n"));
- return NULL;
- }
-
- if ((fh =(FAKE_FILE_HANDLE *)talloc_zero(mem_ctx, sizeof(FAKE_FILE_HANDLE)))==NULL) {
- DEBUG(0,("talloc_zero() failed.\n"));
- talloc_destroy(mem_ctx);
- return NULL;
- }
-
- fh->type = type;
- fh->mem_ctx = mem_ctx;
-
- if (fake_files[i].init_pd)
- fh->pd = fake_files[i].init_pd(fh->mem_ctx);
-
- fh->free_pd = fake_files[i].free_pd;
-
- return fh;
- }
- }
-
- return NULL;
-}
-
-void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
-{
- if (!fh||!(*fh))
- return ;
-
- if ((*fh)->free_pd)
- (*fh)->free_pd(&(*fh)->pd);
-
- talloc_destroy((*fh)->mem_ctx);
- (*fh) = NULL;
-}
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index c2fb6e34566..7af01a323c4 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -25,11 +25,40 @@
static BOOL setup_write_cache(files_struct *, SMB_OFF_T);
/****************************************************************************
+ Seek a file. Try to avoid the seek if possible.
+****************************************************************************/
+
+SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
+{
+ SMB_OFF_T offset = 0;
+ SMB_OFF_T seek_ret;
+
+ if (fsp->print_file && lp_postscript(fsp->conn->service))
+ offset = 3;
+
+ seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET);
+
+ if(seek_ret == -1) {
+ DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n",
+ fsp->fsp_name, strerror(errno) ));
+ fsp->pos = -1;
+ return -1;
+ }
+
+ fsp->pos = seek_ret - offset;
+
+ DEBUG(10,("seek_file (%s): requested pos = %.0f, new pos = %.0f\n",
+ fsp->fsp_name, (double)(pos+offset), (double)fsp->pos ));
+
+ return(fsp->pos);
+}
+
+/****************************************************************************
Read from write cache if we can.
****************************************************************************/
-static BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
+BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
{
write_cache *wcp = fsp->wcp;
@@ -62,22 +91,21 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
* Serve from write cache if we can.
*/
- if(read_from_write_cache(fsp, data, pos, n)) {
- fsp->pos = pos + n;
- fsp->position_information = fsp->pos;
+ if(read_from_write_cache(fsp, data, pos, n))
return n;
- }
flush_write_cache(fsp, READ_FLUSH);
- fsp->pos = pos;
-
+ if (seek_file(fsp,pos) == -1) {
+ DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
+ return(ret);
+ }
+
if (n > 0) {
#ifdef DMF_FIX
int numretries = 3;
tryagain:
- readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
-
+ readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
if (readret == -1) {
if ((errno == EAGAIN) && numretries) {
DEBUG(3,("read_file EAGAIN retry in 10 seconds\n"));
@@ -88,8 +116,7 @@ tryagain:
return -1;
}
#else /* NO DMF fix. */
- readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
-
+ readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
if (readret == -1)
return -1;
#endif
@@ -100,9 +127,6 @@ tryagain:
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
- fsp->pos += ret;
- fsp->position_information = fsp->pos;
-
return(ret);
}
@@ -117,26 +141,14 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
{
ssize_t ret;
- if (pos == -1)
- ret = vfs_write_data(fsp, data, n);
- else {
- fsp->pos = pos;
- ret = vfs_pwrite_data(fsp, data, n, pos);
- }
+ if ((pos != -1) && (seek_file(fsp,pos) == -1))
+ return -1;
+
+ ret = vfs_write_data(fsp,data,n);
DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
- if (ret != -1) {
- fsp->pos += ret;
-
-/* Yes - this is correct - writes don't update this. JRA. */
-/* Found by Samba4 tests. */
-#if 0
- fsp->position_information = fsp->pos;
-#endif
- }
-
return ret;
}
@@ -150,19 +162,8 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
ssize_t total_written = 0;
int write_path = -1;
- if (fsp->print_file) {
- int snum;
- uint32 jobid;
-
- if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
- DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n",
- (unsigned int)fsp->rap_print_jobid ));
- errno = EBADF;
- return -1;
- }
-
- return print_job_write(SNUM(fsp->conn), jobid, data, n);
- }
+ if (fsp->print_file)
+ return print_job_write(fsp->print_jobid, data, n);
if (!fsp->can_write) {
errno = EPERM;
@@ -173,12 +174,11 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
SMB_STRUCT_STAT st;
fsp->modified = True;
- if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) {
+ if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
fsp->size = (SMB_BIG_UINT)st.st_size;
- if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
- file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
- }
+ if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode))
+ file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
/*
* If this is the first write and we have an exclusive oplock then setup
@@ -237,7 +237,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
if(!wcp) {
DO_PROFILE_INC(writecache_direct_writes);
total_written = real_write_file(fsp, data, pos, n);
- if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size))
+ if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size))
fsp->size = (SMB_BIG_UINT)(pos + total_written);
return total_written;
}
@@ -245,8 +245,6 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
- fsp->pos = pos + n;
-
/*
* If we have active cache and it isn't contiguous then we flush.
* NOTE: There is a small problem with running out of disk ....
@@ -684,8 +682,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
DO_PROFILE_INC(writecache_allocated_write_caches);
allocated_write_caches++;
- DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
- fsp->fsp_name, (unsigned long)wcp->alloc_size ));
+ DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n",
+ fsp->fsp_name, wcp->alloc_size ));
return True;
}
@@ -702,7 +700,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
if (fsp->wcp->data_size != 0) {
pstring msg;
slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \
-on file %s with write cache size = %lu\n", fsp->fsp_name, (unsigned long)fsp->wcp->data_size );
+on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size );
smb_panic(msg);
}
fsp->wcp->file_size = file_size;
@@ -755,7 +753,7 @@ void sync_file(connection_struct *conn, files_struct *fsp)
{
if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) {
flush_write_cache(fsp, SYNC_FLUSH);
- SMB_VFS_FSYNC(fsp,fsp->fd);
+ conn->vfs_ops.fsync(fsp,fsp->fd);
}
}
@@ -767,7 +765,7 @@ void sync_file(connection_struct *conn, files_struct *fsp)
int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
{
if (fsp->fd == -1)
- return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst);
+ return vfs_stat(fsp->conn, fsp->fsp_name, pst);
else
- return SMB_VFS_FSTAT(fsp,fsp->fd, pst);
+ return vfs_fstat(fsp,fsp->fd, pst);
}
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index e1eb4a997b7..bae5b7c6a50 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -1,8 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
filename handling routines
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 1999-2004
+ Copyright (C) Jeremy Allison 1999-200
Copyright (C) Ying Chen 2000
This program is free software; you can redistribute it and/or modify
@@ -26,6 +27,12 @@
#include "includes.h"
+extern BOOL case_sensitive;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
+extern fstring remote_machine;
+extern BOOL use_mangled_map;
+
static BOOL scan_directory(const char *path, char *name,size_t maxlength,
connection_struct *conn,BOOL docache);
@@ -34,7 +41,7 @@ static BOOL scan_directory(const char *path, char *name,size_t maxlength,
This needs to be careful about whether we are case sensitive.
****************************************************************************/
-static BOOL fname_equal(const char *name1, const char *name2, BOOL case_sensitive)
+static BOOL fname_equal(char *name1, char *name2)
{
/* Normal filename handling */
if (case_sensitive)
@@ -47,13 +54,13 @@ static BOOL fname_equal(const char *name1, const char *name2, BOOL case_sensitiv
Mangle the 2nd name and check if it is then equal to the first name.
****************************************************************************/
-static BOOL mangled_equal(const char *name1, const char *name2, int snum)
+static BOOL mangled_equal(char *name1, const char *name2, int snum)
{
pstring tmpname;
-
- pstrcpy(tmpname, name2);
- mangle_map(tmpname, True, False, snum);
- return strequal(name1, tmpname);
+
+ pstrcpy(tmpname,name2);
+ mangle_map(tmpname,True,False,snum);
+ return strequal(name1,tmpname);
}
/****************************************************************************
@@ -83,7 +90,7 @@ stat struct will be filled with zeros (and this can be detected by checking
for nlinks = 0, which can never be true for any file).
****************************************************************************/
-BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_component,
+BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
BOOL *bad_path, SMB_STRUCT_STAT *pst)
{
SMB_STRUCT_STAT st;
@@ -92,6 +99,10 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
pstring orig_path;
BOOL component_was_mangled = False;
BOOL name_has_wildcard = False;
+#if 0
+ /* Andrew's conservative code... JRA. */
+ extern char magic_char;
+#endif
ZERO_STRUCTP(pst);
@@ -109,30 +120,29 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
DEBUG(5, ("unix_convert called on file \"%s\"\n", name));
/*
- * Conversion to basic unix format is already done in check_path_syntax().
+ * Convert to basic unix format - removing \ chars and cleaning it up.
*/
+ unix_format(name);
+ unix_clean_name(name);
+
/*
- * Names must be relative to the root of the service - any leading /.
- * and trailing /'s should have been trimmed by check_path_syntax().
+ * Names must be relative to the root of the service - trim any leading /.
+ * also trim trailing /'s.
*/
-#ifdef DEVELOPER
- SMB_ASSERT(*name != '/');
-#endif
+ trim_string(name,"/","/");
/*
* If we trimmed down to a single '\0' character
* then we should use the "." directory to avoid
* searching the cache, but not if we are in a
* printing share.
- * As we know this is valid we can return true here.
*/
if (!*name) {
name[0] = '.';
name[1] = '\0';
- return(True);
}
/*
@@ -140,20 +150,32 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
*/
if(saved_last_component) {
- end = strrchr_m(name, '/');
+ end = strrchr(name, '/');
if(end)
pstrcpy(saved_last_component, end + 1);
else
pstrcpy(saved_last_component, name);
}
- if (!conn->case_sensitive && (!conn->case_preserve || (mangle_is_8_3(name, False) && !conn->short_case_preserve)))
- strnorm(name, lp_defaultcase(SNUM(conn)));
+ if (!case_sensitive && (!case_preserve || (mangle_is_8_3(name, False) && !short_case_preserve)))
+ strnorm(name);
+
+ /*
+ * If we trimmed down to a single '\0' character
+ * then we will be using the "." directory.
+ * As we know this is valid we can return true here.
+ */
+
+ if(!*name)
+ return(True);
start = name;
+ while (strncmp(start,"./",2) == 0)
+ start += 2;
+
pstrcpy(orig_path, name);
- if(!conn->case_sensitive && stat_cache_lookup(conn, name, dirpath, &start, &st)) {
+ if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
*pst = st;
return True;
}
@@ -162,8 +184,8 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* stat the name - if it exists then we are all done!
*/
- if (SMB_VFS_STAT(conn,name,&st) == 0) {
- stat_cache_add(orig_path, name, conn->case_sensitive);
+ if (vfs_stat(conn,name,&st) == 0) {
+ stat_cache_add(orig_path, name);
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
*pst = st;
return(True);
@@ -176,7 +198,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* sensitive then searching won't help.
*/
- if (conn->case_sensitive && !mangle_is_mangled(name) && !*lp_mangled_map(SNUM(conn)))
+ if (case_sensitive && !mangle_is_mangled(name) && !use_mangled_map)
return(False);
name_has_wildcard = ms_has_wild(start);
@@ -186,7 +208,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* just a component. JRA.
*/
- if (mangle_is_mangled(start))
+ if(mangle_is_mangled(start))
component_was_mangled = True;
/*
@@ -203,7 +225,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
/*
* Pinpoint the end of this section of the filename.
*/
- end = strchr_m(start, '/');
+ end = strchr(start, '/');
/*
* Chop the name at this point.
@@ -218,7 +240,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* Check if the name exists up to this point.
*/
- if (SMB_VFS_STAT(conn,name, &st) == 0) {
+ if (vfs_stat(conn,name, &st) == 0) {
/*
* It exists. it must either be a directory or this must be
* the last part of the path for it to be OK.
@@ -292,8 +314,8 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* don't normalise it.
*/
- if (!conn->case_preserve && (!strhasupper(start) || !strhaslower(start)))
- strnorm(start, lp_defaultcase(SNUM(conn)));
+ if (!case_preserve && (!strhasupper(start) || !strhaslower(start)))
+ strnorm(start);
/*
* check on the mangled stack to see if we can recover the
@@ -326,7 +348,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* JRA.
*/
- if (SMB_VFS_STAT(conn,name, &st) == 0) {
+ if (vfs_stat(conn,name, &st) == 0) {
*pst = st;
} else {
ZERO_STRUCT(st);
@@ -346,10 +368,10 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
* Don't cache a name with mangled or wildcard components
* as this can change the size.
*/
-
+
if(!component_was_mangled && !name_has_wildcard)
- stat_cache_add(orig_path, dirpath, conn->case_sensitive);
-
+ stat_cache_add(orig_path, dirpath);
+
/*
* Restore the / that we wiped out earlier.
*/
@@ -363,7 +385,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
*/
if(!component_was_mangled && !name_has_wildcard)
- stat_cache_add(orig_path, name, conn->case_sensitive);
+ stat_cache_add(orig_path, name);
/*
* The name has been resolved.
@@ -380,23 +402,20 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
a valid one for the user to access.
****************************************************************************/
-BOOL check_name(pstring name,connection_struct *conn)
+BOOL check_name(char *name,connection_struct *conn)
{
- BOOL ret = True;
+ BOOL ret;
errno = 0;
- if (IS_VETO_PATH(conn, name)) {
- /* Is it not dot or dot dot. */
- if (!((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2])))) {
+ if(IS_VETO_PATH(conn, name)) {
+ if(strcmp(name, ".") && strcmp(name, "..")) {
DEBUG(5,("file path name %s vetoed\n",name));
- return False;
+ return(0);
}
}
- if (!lp_widelinks(SNUM(conn))) {
- ret = reduce_name(conn,name,conn->connectpath);
- }
+ ret = reduce_name(conn,name,conn->connectpath,lp_widelinks(SNUM(conn)));
/* Check if we are allowing users to follow symlinks */
/* Patch from David Clerc <David.Clerc@cui.unige.ch>
@@ -405,10 +424,10 @@ BOOL check_name(pstring name,connection_struct *conn)
#ifdef S_ISLNK
if (!lp_symlinks(SNUM(conn))) {
SMB_STRUCT_STAT statbuf;
- if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) &&
+ if ( (conn->vfs_ops.lstat(conn,dos_to_unix_static(name),&statbuf) != -1) &&
(S_ISLNK(statbuf.st_mode)) ) {
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
- ret = False;
+ ret=0;
}
}
#endif
@@ -424,11 +443,11 @@ BOOL check_name(pstring name,connection_struct *conn)
If the name looks like a mangled name then try via the mangling functions
****************************************************************************/
-static BOOL scan_directory(const char *path, char *name, size_t maxlength,
+static BOOL scan_directory(const char *path, char *name,size_t maxlength,
connection_struct *conn,BOOL docache)
{
void *cur_dir;
- const char *dname;
+ char *dname;
BOOL mangled;
mangled = mangle_is_mangled(name);
@@ -445,7 +464,7 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
/*
* The incoming name can be mangled, and if we de-mangle it
* here it will not compare correctly against the filename (name2)
- * read from the directory and then mangled by the mangle_map()
+ * read from the directory and then mangled by the name_map_mangle()
* call. We need to mangle both names or neither.
* (JRA).
*/
@@ -460,11 +479,8 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
/* now scan for matching names */
while ((dname = ReadDirName(cur_dir))) {
-
- /* Is it dot or dot dot. */
- if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) {
+ if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
continue;
- }
/*
* At this point dname is the unmangled name.
@@ -477,7 +493,7 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
* against unmangled name.
*/
- if ((mangled && mangled_equal(name,dname,SNUM(conn))) || fname_equal(name, dname, conn->case_sensitive)) {
+ if ((mangled && mangled_equal(name,dname,SNUM(conn))) || fname_equal(name, dname)) {
/* we've found the file, change it's name and return */
if (docache)
DirCacheAdd(path,name,dname,SNUM(conn));
diff --git a/source/smbd/files.c b/source/smbd/files.c
index 80544c9a309..8962764a76f 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Files[] structure handling
Copyright (C) Andrew Tridgell 1998
@@ -143,22 +144,6 @@ void file_close_conn(connection_struct *conn)
}
/****************************************************************************
- Close all open files for a pid.
-****************************************************************************/
-
-void file_close_pid(uint16 smbpid)
-{
- files_struct *fsp, *next;
-
- for (fsp=Files;fsp;fsp=next) {
- next = fsp->next;
- if (fsp->file_pid == smbpid) {
- close_file(fsp,False);
- }
- }
-}
-
-/****************************************************************************
Initialise file structures.
****************************************************************************/
@@ -216,18 +201,6 @@ void file_close_user(int vuid)
}
}
-void file_dump_open_table(void)
-{
- int count=0;
- files_struct *fsp;
-
- for (fsp=Files;fsp;fsp=fsp->next,count++) {
- DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n",
- count, fsp->fnum, fsp->fsp_name, fsp->fd, (unsigned long)fsp->file_id,
- (unsigned int)fsp->dev, (double)fsp->inode ));
- }
-}
-
/****************************************************************************
Find a fsp given a file descriptor.
****************************************************************************/
@@ -374,10 +347,6 @@ void file_free(files_struct *fsp)
string_free(&fsp->fsp_name);
- if (fsp->fake_file_handle) {
- destroy_fake_file_handle(&fsp->fake_file_handle);
- }
-
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
files_used--;
@@ -405,8 +374,6 @@ files_struct *file_fsp(char *buf, int where)
if (chain_fsp)
return chain_fsp;
- if (!buf)
- return NULL;
fnum = SVAL(buf, where);
for (fsp=Files;fsp;fsp=fsp->next, count++) {
diff --git a/source/smbd/groupname.c b/source/smbd/groupname.c
new file mode 100755
index 00000000000..2c7440d75a7
--- /dev/null
+++ b/source/smbd/groupname.c
@@ -0,0 +1,240 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Jeremy Allison 1998.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef USING_GROUPNAME_MAP
+
+#include "includes.h"
+extern DOM_SID global_sam_sid;
+
+
+/**************************************************************************
+ Groupname map functionality. The code loads a groupname map file and
+ (currently) loads it into a linked list. This is slow and memory
+ hungry, but can be changed into a more efficient storage format
+ if the demands on it become excessive.
+***************************************************************************/
+
+typedef struct groupname_map {
+ ubi_slNode next;
+
+ char *windows_name;
+ DOM_SID windows_sid;
+ char *unix_name;
+ gid_t unix_gid;
+} groupname_map_entry;
+
+static ubi_slList groupname_map_list;
+
+/**************************************************************************
+ Delete all the entries in the groupname map list.
+***************************************************************************/
+
+static void delete_groupname_map_list(void)
+{
+ groupname_map_entry *gmep;
+
+ while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
+ SAFE_FREE(gmep->windows_name);
+ SAFE_FREE(gmep->unix_name);
+ SAFE_FREE(gmep);
+ }
+}
+
+/**************************************************************************
+ Load a groupname map file. Sets last accessed timestamp.
+***************************************************************************/
+
+void load_groupname_map(void)
+{
+ static time_t groupmap_file_last_modified = (time_t)0;
+ static BOOL initialized = False;
+ char *groupname_map_file = lp_groupname_map();
+ SMB_STRUCT_STAT st;
+ char **lines;
+ int i;
+ groupname_map_entry *new_ep;
+
+ if(!initialized) {
+ ubi_slInitList( &groupname_map_list );
+ initialized = True;
+ }
+
+ if (!*groupname_map_file)
+ return;
+
+ if(sys_stat(groupname_map_file, &st) != 0) {
+ DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
+ groupname_map_file, strerror(errno) ));
+ return;
+ }
+
+ /*
+ * Check if file has changed.
+ */
+ if( st.st_mtime <= groupmap_file_last_modified)
+ return;
+
+ groupmap_file_last_modified = st.st_mtime;
+
+ /*
+ * Load the file.
+ */
+
+ lines = file_lines_load(groupname_map_file,NULL,False);
+ if (!lines) {
+ DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
+ groupname_map_file, strerror(errno)));
+ return;
+ }
+ file_lines_slashcont(lines);
+
+ /*
+ * Throw away any previous list.
+ */
+ delete_groupname_map_list();
+
+ DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
+
+ for (i=0; lines[i]; i++) {
+ pstring unixname;
+ pstring windows_name;
+ gid_t gid;
+ DOM_SID tmp_sid;
+ char *s = lines[i];
+
+ DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
+
+ if (!*s || strchr("#;",*s))
+ continue;
+
+ if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
+ continue;
+
+ if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
+ continue;
+
+ trim_string(unixname, " ", " ");
+ trim_string(windows_name, " ", " ");
+
+ if (!*windows_name)
+ continue;
+
+ if(!*unixname)
+ continue;
+
+ DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
+ unixname, windows_name));
+
+ /*
+ * Attempt to get the unix gid_t for this name.
+ */
+
+ if ((gid = nametogid(unixname)) == (gid_t)-1)
+ DEBUG(0,("load_groupname_map: nametogid for group %s failed.\
+Error was %s.\n", unixname, strerror(errno) ));
+ continue;
+ }
+
+ /*
+ * Now map to an NT SID.
+ */
+
+ if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
+ /*
+ * It's not a well known name, convert the UNIX gid_t
+ * to a rid within this domain SID.
+ */
+ tmp_sid = global_sam_sid;
+ tmp_sid.sub_auths[tmp_sid.num_auths++] =
+ pdb_gid_to_group_rid(gid);
+ }
+
+ /*
+ * Create the list entry and add it onto the list.
+ */
+
+ if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
+ DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
+ fclose(fp);
+ return;
+ }
+
+ new_ep->unix_gid = gid;
+ new_ep->windows_sid = tmp_sid;
+ new_ep->windows_name = strdup( windows_name );
+ new_ep->unix_name = strdup( unixname );
+
+ if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
+ DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
+ fclose(fp);
+ SAFE_FREE(new_ep->windows_name);
+ SAFE_FREE(new_ep->unix_name);
+ SAFE_FREE(new_ep);
+ file_lines_free(lines);
+ return;
+ }
+ memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
+
+ ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
+ }
+
+ DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
+ ubi_slCount(&groupname_map_list)));
+
+ file_lines_free(lines);
+}
+
+/***********************************************************
+ Lookup a SID entry by gid_t.
+************************************************************/
+
+void map_gid_to_sid( gid_t gid, DOM_SID *psid)
+{
+ groupname_map_entry *gmep;
+
+ /*
+ * Initialize and load if not already loaded.
+ */
+ load_groupname_map();
+
+ for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
+ gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
+
+ if( gmep->unix_gid == gid) {
+ *psid = gmep->windows_sid;
+ DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
+ gmep->unix_name, gmep->windows_name ));
+ return;
+ }
+ }
+
+ /*
+ * If there's no map, convert the UNIX gid_t
+ * to a rid within this domain SID.
+ */
+ *psid = global_sam_sid;
+ psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
+
+ return;
+}
+#else /* USING_GROUPNAME_MAP */
+ void load_groupname_map(void) {;}
+#endif /* USING_GROUPNAME_MAP */
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index e5465b902c8..944f3825414 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -34,6 +35,7 @@ extern fstring local_machine;
#define NERR_notsupported 50
extern int smb_read_error;
+extern uint32 global_client_caps;
/*******************************************************************
copies parameters and data, as needed, into the smb buffer
@@ -95,12 +97,20 @@ void send_trans_reply(char *outbuf,
align = ((this_lparam)%4);
+ set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
+
if (buffer_too_large) {
- ERROR_BOTH(STATUS_BUFFER_OVERFLOW,ERRDOS,ERRmoredata);
+ /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
+ if (!(global_client_caps & CAP_STATUS32 )) {
+ /* Win9x version. */
+ SSVAL(outbuf, smb_err, ERRmoredata);
+ SCVAL(outbuf, smb_rcls, ERRDOS);
+ } else {
+ SIVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
+ SIVAL(outbuf, smb_rcls, NT_STATUS_V(STATUS_BUFFER_OVERFLOW));
+ }
}
- set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
-
copy_trans_params_and_data(outbuf, align,
rparam, tot_param_sent, this_lparam,
rdata, tot_data_sent, this_ldata);
@@ -117,7 +127,7 @@ void send_trans_reply(char *outbuf,
show_msg(outbuf);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_trans_reply: send_smb failed.");
+ exit_server("send_trans_reply: send_smb failed.\n");
tot_data_sent = this_ldata;
tot_param_sent = this_lparam;
@@ -138,9 +148,9 @@ void send_trans_reply(char *outbuf,
set_message(outbuf,10,1+this_ldata+this_lparam+align,False);
copy_trans_params_and_data(outbuf, align,
- rparam, tot_param_sent, this_lparam,
- rdata, tot_data_sent, this_ldata);
-
+ rparam, tot_param_sent, this_lparam,
+ rdata, tot_data_sent, this_ldata);
+
SSVAL(outbuf,smb_vwv3,this_lparam);
SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
SSVAL(outbuf,smb_vwv5,tot_param_sent);
@@ -151,7 +161,7 @@ void send_trans_reply(char *outbuf,
show_msg(outbuf);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_trans_reply: send_smb failed.");
+ exit_server("send_trans_reply: send_smb failed.\n");
tot_data_sent += this_ldata;
tot_param_sent += this_lparam;
@@ -162,9 +172,8 @@ void send_trans_reply(char *outbuf,
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
-static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p)
+static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
{
- BOOL is_data_outstanding;
char *rdata = malloc(p->max_trans_reply);
int data_len;
@@ -173,13 +182,12 @@ static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p)
return False;
}
- if((data_len = read_from_pipe( p, rdata, p->max_trans_reply,
- &is_data_outstanding)) < 0) {
+ if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
SAFE_FREE(rdata);
return False;
}
- send_trans_reply(outbuf, NULL, 0, rdata, data_len, is_data_outstanding);
+ send_trans_reply(outbuf, NULL, 0, rdata, data_len, p->out_data.current_pdu_len > data_len);
SAFE_FREE(rdata);
return True;
@@ -189,7 +197,7 @@ static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p)
WaitNamedPipeHandleState
****************************************************************************/
-static BOOL api_WNPHS(char *outbuf, smb_np_struct *p, char *param, int param_len)
+static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
{
uint16 priority;
@@ -212,7 +220,7 @@ static BOOL api_WNPHS(char *outbuf, smb_np_struct *p, char *param, int param_len
SetNamedPipeHandleState
****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, smb_np_struct *p, char *param, int param_len)
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
{
uint16 id;
@@ -260,7 +268,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
BOOL reply = False;
- smb_np_struct *p = NULL;
+ pipes_struct *p = NULL;
int pnum;
int subcommand;
@@ -281,19 +289,11 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
subcommand = ((int)setup[0]) & 0xFFFF;
if(!(p = get_rpc_pipe(pnum))) {
- if (subcommand == TRANSACT_WAITNAMEDPIPEHANDLESTATE) {
- /* Win9x does this call with a unicode pipe name, not a pnum. */
- /* Just return success for now... */
- DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n"));
- send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
- return -1;
- }
-
DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
return api_no_reply(outbuf, mdrcnt);
}
- DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum));
+ DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum));
/* record maximum data length that can be transmitted in an SMBtrans */
p->max_trans_reply = mdrcnt;
@@ -301,17 +301,17 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply));
switch (subcommand) {
- case TRANSACT_DCERPCCMD:
+ case 0x26:
/* dce/rpc command */
reply = write_to_pipe(p, data, tdscnt);
if (reply)
reply = api_rpc_trans_reply(outbuf, p);
break;
- case TRANSACT_WAITNAMEDPIPEHANDLESTATE:
+ case 0x53:
/* Wait Named Pipe Handle state */
reply = api_WNPHS(outbuf, p, params, tpscnt);
break;
- case TRANSACT_SETNAMEDPIPEHANDLESTATE:
+ case 0x01:
/* Set Named Pipe Handle state */
reply = api_SNPHS(outbuf, p, params, tpscnt);
break;
@@ -383,7 +383,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
START_PROFILE(SMBtrans);
memset(name, '\0',sizeof(name));
- srvstr_pull_buf(inbuf, name, smb_buf(inbuf), sizeof(name), STR_TERMINATE);
+ fstrcpy(name,smb_buf(inbuf));
if (dscnt > tdscnt || pscnt > tpscnt)
goto bad_param;
@@ -396,8 +396,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
goto bad_param;
- if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
- (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
+ if (smb_base(inbuf)+dsoff+dscnt > inbuf + size)
goto bad_param;
memcpy(data,smb_base(inbuf)+dsoff,dscnt);
@@ -412,15 +411,14 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
goto bad_param;
- if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
- (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
+ if (smb_base(inbuf)+psoff+pscnt > inbuf + size)
goto bad_param;
memcpy(params,smb_base(inbuf)+psoff,pscnt);
}
if (suwcnt) {
- unsigned int i;
+ int i;
if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n", (unsigned int)(suwcnt * sizeof(uint16))));
SAFE_FREE(data);
@@ -438,14 +436,11 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if (pscnt < tpscnt || dscnt < tdscnt) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
outsize = set_message(outbuf,0,0,True);
show_msg(outbuf);
- srv_signing_trans_stop();
if (!send_smb(smbd_server_fd(),outbuf))
exit_server("reply_trans: send_smb failed.");
}
@@ -457,13 +452,6 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
- /*
- * The sequence number for the trans reply is always
- * based on the last secondary received.
- */
-
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) {
if(ret) {
DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
@@ -475,7 +463,6 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(data);
SAFE_FREE(setup);
END_PROFILE(SMBtrans);
- srv_signing_trans_stop();
return(ERROR_DOS(ERRSRV,ERRerror));
}
@@ -506,10 +493,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
goto bad_param;
if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
goto bad_param;
- if (pdisp > tpscnt)
- goto bad_param;
- if ((smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) ||
- (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
+ if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize)
goto bad_param;
if (params + pdisp < params)
goto bad_param;
@@ -522,10 +506,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
goto bad_param;
if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
goto bad_param;
- if (ddisp > tdscnt)
- goto bad_param;
- if ((smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) ||
- (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
+ if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize)
goto bad_param;
if (data + ddisp < data)
goto bad_param;
@@ -533,10 +514,11 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
}
}
-
+
+
DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n",
name,tdscnt,tpscnt,suwcnt));
-
+
/*
* WinCE wierdness....
*/
@@ -568,8 +550,6 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(params);
SAFE_FREE(setup);
- srv_signing_trans_stop();
-
if (close_on_completion)
close_cnum(conn,vuid);
@@ -589,7 +569,6 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
bad_param:
- srv_signing_trans_stop();
DEBUG(0,("reply_trans: invalid trans parameters\n"));
SAFE_FREE(data);
SAFE_FREE(params);
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index d715ab4ddc3..1c6db9cd6af 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -33,6 +34,8 @@
#define CHECK_TYPES 0
extern fstring local_machine;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
#define NERR_Success 0
#define NERR_badpass 86
@@ -70,7 +73,8 @@ static int CopyExpanded(connection_struct *conn,
StrnCpy(buf,src,sizeof(buf)/2);
pstring_sub(buf,"%S",lp_servicename(snum));
standard_sub_conn(conn,buf,sizeof(buf));
- l = push_ascii(*dst,buf,*n, STR_TERMINATE);
+ StrnCpy(*dst,buf,*n-1);
+ l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
@@ -80,7 +84,8 @@ static int CopyAndAdvance(char** dst, char* src, int* n)
{
int l;
if (!src || !dst || !n || !(*dst)) return(0);
- l = push_ascii(*dst,src,*n, STR_TERMINATE);
+ StrnCpy(*dst,src,*n-1);
+ l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
@@ -109,7 +114,7 @@ static char* Expand(connection_struct *conn, int snum, char* s)
/*******************************************************************
check a API string for validity when we only need to check the prefix
******************************************************************/
-static BOOL prefix_ok(const char *str, const char *prefix)
+static BOOL prefix_ok(const char *str,const char *prefix)
{
return(strncmp(str,prefix,strlen(prefix)) == 0);
}
@@ -214,15 +219,27 @@ static BOOL init_package(struct pack_desc* p, int count, int subcount)
return(p->errcode == NERR_Success);
}
+#ifdef HAVE_STDARG_H
static int package(struct pack_desc* p, ...)
{
+#else
+static int package(va_alist)
+va_dcl
+{
+ struct pack_desc* p;
+#endif
va_list args;
int needed=0, stringneeded;
- const char* str=NULL;
+ char* str=NULL;
int is_string=0, stringused;
int32 temp;
+#ifdef HAVE_STDARG_H
va_start(args,p);
+#else
+ va_start(args);
+ p = va_arg(args,struct pack_desc *);
+#endif
if (!*p->curpos) {
if (!p->subcount)
@@ -329,7 +346,7 @@ static int package(struct pack_desc* p, ...)
#define PACKl(desc,t,v,l) package(desc,v,l)
#endif
-static void PACKI(struct pack_desc* desc, const char *t,int v)
+static void PACKI(struct pack_desc* desc,const char *t,int v)
{
PACK(desc,t,v);
}
@@ -349,7 +366,7 @@ static void PackDriverData(struct pack_desc* desc)
SIVAL(drivdata,0,sizeof drivdata); /* cb */
SIVAL(drivdata,4,1000); /* lVersion */
memset(drivdata+8,0,32); /* szDeviceName */
- push_ascii(drivdata+8,"NULL",-1, STR_TERMINATE);
+ pstrcpy(drivdata+8,"NULL");
PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
}
@@ -441,9 +458,9 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
/* the client expects localtime */
t -= TimeDiff(t);
- PACKI(desc,"W",pjobid_to_rap(snum,queue->job)); /* uJobId */
+ PACKI(desc,"W",queue->job); /* uJobId */
if (uLevel == 1) {
- PACKS(desc,"B21",queue->fs_user); /* szUserName */
+ PACKS(desc,"B21",dos_to_unix_static(queue->fs_user)); /* szUserName */
PACKS(desc,"B",""); /* pad */
PACKS(desc,"B16",""); /* szNotifyName */
PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
@@ -453,17 +470,17 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
PACKS(desc,"z",""); /* pszStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->fs_file); /* pszComment */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_file)); /* pszComment */
}
if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->fs_user); /* pszUserName */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_user)); /* pszUserName */
PACKI(desc,"W",n+1); /* uPosition */
PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->fs_file); /* pszDocument */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_file)); /* pszDocument */
if (uLevel == 3) {
PACKS(desc,"z",""); /* pszNotifyName */
PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
@@ -492,7 +509,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
/********************************************************************
Return a driver name given an snum.
- Returns True if from tdb, False otherwise.
+ Looks in a tdb first. Returns True if from tdb, False otherwise.
********************************************************************/
static BOOL get_driver_name(int snum, pstring drivername)
@@ -500,11 +517,13 @@ static BOOL get_driver_name(int snum, pstring drivername)
NT_PRINTER_INFO_LEVEL *info = NULL;
BOOL in_tdb = False;
- get_a_printer (NULL, &info, 2, lp_servicename(snum));
+ get_a_printer (&info, 2, lp_servicename(snum));
if (info != NULL) {
pstrcpy( drivername, info->info_2->drivername);
in_tdb = True;
free_a_printer(&info, 2);
+ } else {
+ pstrcpy( drivername, lp_printerdriver(snum));
}
return in_tdb;
@@ -514,85 +533,162 @@ static BOOL get_driver_name(int snum, pstring drivername)
Respond to the DosPrintQInfo command with a level of 52
This is used to get printer driver information for Win9x clients
********************************************************************/
-static void fill_printq_info_52(connection_struct *conn, int snum,
- struct pack_desc* desc, int count )
+static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
+ struct pack_desc* desc,
+ int count, print_queue_struct* queue,
+ print_status_struct* status)
{
- int i;
- fstring location;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int i;
+ BOOL ok = False;
+ pstring tok,driver,datafile,langmon,helpfile,datatype;
+ const char *p;
+ char **lines = NULL;
+ pstring gen_line;
+ BOOL in_tdb = False;
+ fstring location;
+ pstring drivername;
- ZERO_STRUCT(driver);
+ /*
+ * Check in the tdb *first* before checking the legacy
+ * files. This allows an NT upload to take precedence over
+ * the existing fileset. JRA.
+ *
+ * we need to lookup the driver name prior to making the call
+ * to get_a_printer_driver_9x_compatible() and not rely on the
+ * 'print driver' parameter --jerry
+ */
- if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
- lp_servicename(snum)));
- goto err;
- }
-
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
- "Windows 4.0", 0)) )
+
+ if ((get_driver_name(snum,drivername)) &&
+ ((ok = get_a_printer_driver_9x_compatible(gen_line, drivername)) == True))
+ {
+ in_tdb = True;
+ p = gen_line;
+ DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", drivername, gen_line));
+ }
+ else
{
- DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n",
- printer->info_2->drivername));
- goto err;
+ /* didn't find driver in tdb */
+
+ DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
+ snum, drivername, lp_driverfile(snum)));
+
+ lines = file_lines_load(lp_driverfile(snum),NULL, False);
+ if (!lines)
+ {
+ DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),
+ strerror(errno)));
+ desc->errcode=NERR_notsupported;
+ goto done;
+ }
+
+ /* lookup the long printer driver name in the file description */
+ for (i=0;lines[i] && !ok;i++)
+ {
+ p = lines[i];
+ if (next_token(&p,tok,":",sizeof(tok)) &&
+ (strlen(drivername) == strlen(tok)) &&
+ (!strncmp(tok,drivername,strlen(drivername))))
+ {
+ ok = True;
+ }
+ }
}
- trim_string(driver.info_3->driverpath, "\\print$\\WIN40\\0\\", 0);
- trim_string(driver.info_3->datafile, "\\print$\\WIN40\\0\\", 0);
- trim_string(driver.info_3->helpfile, "\\print$\\WIN40\\0\\", 0);
-
- PACKI(desc, "W", 0x0400); /* don't know */
- PACKS(desc, "z", driver.info_3->name); /* long printer name */
- PACKS(desc, "z", driver.info_3->driverpath); /* Driverfile Name */
- PACKS(desc, "z", driver.info_3->datafile); /* Datafile name */
- PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */
+ if (ok)
+ {
+ /* driver file name */
+ if (!next_token(&p,driver,":",sizeof(driver)))
+ goto err;
+
+ /* data file name */
+ if (!next_token(&p,datafile,":",sizeof(datafile)))
+ goto err;
+
+ /*
+ * for the next tokens - which may be empty - I have
+ * to check for empty tokens first because the
+ * next_token function will skip all empty token
+ * fields */
+
+ /* help file */
+ if (*p == ':')
+ {
+ *helpfile = '\0';
+ p++;
+ }
+ else if (!next_token(&p,helpfile,":",sizeof(helpfile)))
+ goto err;
- fstrcpy(location, "\\\\");
- fstrcat(location, get_called_name());
- fstrcat(location, "\\print$\\WIN40\\0");
- PACKS(desc,"z", location); /* share to retrieve files */
+ /* language monitor */
+ if (*p == ':')
+ {
+ *langmon = '\0';
+ p++;
+ }
+ else if (!next_token(&p,langmon,":",sizeof(langmon)))
+ goto err;
- PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */
- PACKS(desc,"z", driver.info_3->helpfile); /* helpfile name */
- PACKS(desc,"z", driver.info_3->driverpath); /* driver name */
-
- DEBUG(3,("Printer Driver Name: %s:\n",driver.info_3->name));
- DEBUG(3,("Driver: %s:\n",driver.info_3->driverpath));
- DEBUG(3,("Data File: %s:\n",driver.info_3->datafile));
- DEBUG(3,("Language Monitor: %s:\n",driver.info_3->monitorname));
- DEBUG(3,("Driver Location: %s:\n",location));
- DEBUG(3,("Data Type: %s:\n",driver.info_3->defaultdatatype));
- DEBUG(3,("Help File: %s:\n",driver.info_3->helpfile));
- PACKI(desc,"N",count); /* number of files to copy */
-
- for ( i=0; i<count && driver.info_3->dependentfiles && *driver.info_3->dependentfiles[i]; i++)
- {
- trim_string(driver.info_3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
- PACKS(desc,"z",driver.info_3->dependentfiles[i]); /* driver files to copy */
- DEBUG(3,("Dependent File: %s:\n",driver.info_3->dependentfiles[i]));
- }
+ /* default data type */
+ if (!next_token(&p,datatype,":",sizeof(datatype)))
+ goto err;
- /* sanity check */
- if ( i != count )
- DEBUG(3,("fill_printq_info_52: file count specified by client [%d] != number of dependent files [%i]\n",
- count, i));
+ PACKI(desc,"W",0x0400); /* don't know */
+ PACKS(desc,"z",drivername); /* long printer name */
+ PACKS(desc,"z",driver); /* Driverfile Name */
+ PACKS(desc,"z",datafile); /* Datafile name */
+ PACKS(desc,"z",langmon); /* language monitor */
+ if (in_tdb)
+ {
+ fstrcpy(location, "\\\\");
+ fstrcat(location, global_myname);
+ fstrcat(location, "\\print$\\WIN40\\0");
+ PACKS(desc,"z",location); /* share to retrieve files */
+ }
+ else
+ {
+ PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
+ }
+ PACKS(desc,"z",datatype); /* default data type */
+ PACKS(desc,"z",helpfile); /* helpfile name */
+ PACKS(desc,"z",driver); /* driver name */
+
+ DEBUG(3,("printerdriver:%s:\n",drivername));
+ DEBUG(3,("Driver:%s:\n",driver));
+ DEBUG(3,("Data File:%s:\n",datafile));
+ DEBUG(3,("Language Monitor:%s:\n",langmon));
+ if (in_tdb)
+ DEBUG(3,("lp_driverlocation:%s:\n",location));
+ else
+ DEBUG(3,("lp_driverlocation:%s:\n",lp_driverlocation(snum)));
+ DEBUG(3,("Data Type:%s:\n",datatype));
+ DEBUG(3,("Help File:%s:\n",helpfile));
+ PACKI(desc,"N",count); /* number of files to copy */
+
+ for (i=0;i<count;i++)
+ {
+ /* no need to check return value here
+ * - it was already tested in
+ * get_printerdrivernumber */
+ next_token(&p,tok,",",sizeof(tok));
+ PACKS(desc,"z",tok); /* driver files to copy */
+ DEBUG(3,("file:%s:\n",tok));
+ }
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", SERVICE(snum),i));
+ DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
+ SERVICE(snum),count));
- desc->errcode=NERR_Success;
- goto done;
+ desc->errcode=NERR_Success;
+ goto done;
+ }
+
+ err:
-err:
DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
desc->errcode=NERR_notsupported;
-done:
- if ( printer )
- free_a_printer( &printer, 2 );
-
- if ( driver.info_3 )
- free_a_printer_driver( driver, 3 );
+ done:
+ file_lines_free(lines);
}
@@ -670,44 +766,88 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
}
- if (uLevel==52)
- fill_printq_info_52( conn, snum, desc, count );
+ if (uLevel==52) {
+ fill_printq_info_52(conn, snum, uLevel, desc, count, queue, status);
+ }
}
/* This function returns the number of files for a given driver */
static int get_printerdrivernumber(int snum)
{
- int result = 0;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
+ int i, result = 0;
+ BOOL ok = False;
+ pstring tok;
+ const char *p;
+ char **lines = NULL;
+ pstring gen_line;
+ pstring drivername;
- ZERO_STRUCT(driver);
+ /*
+ * Check in the tdb *first* before checking the legacy
+ * files. This allows an NT upload to take precedence over
+ * the existing fileset. JRA.
+ *
+ * we need to lookup the driver name prior to making the call
+ * to get_a_printer_driver_9x_compatible() and not rely on the
+ * 'print driver' parameter --jerry
+ */
+
+ if ((get_driver_name(snum,drivername)) &&
+ (ok = get_a_printer_driver_9x_compatible(gen_line, drivername) == True))
+ {
+ p = gen_line;
+ DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", drivername, gen_line));
+ }
+ else
+ {
+ /* didn't find driver in tdb */
+
+ DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
+ snum, drivername, lp_driverfile(snum)));
+
+ lines = file_lines_load(lp_driverfile(snum), NULL, False);
+ if (!lines)
+ {
+ DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
+ goto done;
+ }
- if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
- lp_servicename(snum)));
- goto done;
+ /* lookup the long printer driver name in the file description */
+ for (i=0;lines[i] && !ok;i++)
+ {
+ p = lines[i];
+ if (next_token(&p,tok,":",sizeof(tok)) &&
+ (strlen(drivername) == strlen(tok)) &&
+ (!strncmp(tok,drivername,strlen(drivername))))
+ {
+ ok = True;
+ }
+ }
}
-
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
- "Windows 4.0", 0)) )
+
+ if( ok )
{
- DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n",
- printer->info_2->drivername));
- goto done;
- }
+ /* skip 5 fields */
+ i = 5;
+ while (*p && i) {
+ if (*p++ == ':') i--;
+ }
+ if (!*p || i) {
+ DEBUG(3,("Can't determine number of printer driver files\n"));
+ goto done;
+ }
+
+ /* count the number of files */
+ while (next_token(&p,tok,",",sizeof(tok)))
+ i++;
- /* count the number of files */
- while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
- result++;
- \
+ result = i;
+ }
+
done:
- if ( printer )
- free_a_printer( &printer, 2 );
-
- if ( driver.info_3 )
- free_a_printer_driver( driver, 3 );
-
+
+ file_lines_free(lines);
+
return result;
}
@@ -738,10 +878,10 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
str3 = p + 4;
/* remove any trailing username */
- if ((p = strchr_m(QueueName,'%')))
+ if ((p = strchr(QueueName,'%')))
*p = 0;
- DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName));
+ DEBUG(3,("api_DosPrintQGetInfo: uLevel=%d name=%s\n",uLevel,QueueName));
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh"))
@@ -796,9 +936,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
if (init_package(&desc,1,count)) {
desc.subcount = count;
fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
- }
-
- *rdata_len = desc.usedlen;
+ }
/*
* We must set the return code to ERRbuftoosmall
@@ -807,14 +945,15 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
*/
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
-
+
*rdata_len = desc.usedlen;
+
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
-
+
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
SAFE_FREE(queue);
@@ -962,7 +1101,7 @@ struct srv_info_struct
******************************************************************/
static int get_server_info(uint32 servertype,
struct srv_info_struct **servers,
- const char *domain)
+ char *domain)
{
int count=0;
int alloced=0;
@@ -970,7 +1109,7 @@ static int get_server_info(uint32 servertype,
BOOL local_list_only;
int i;
- lines = file_lines_load(lock_path(SERVER_LIST), NULL);
+ lines = file_lines_load(lock_path(SERVER_LIST), NULL, False);
if (!lines) {
DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno)));
return(0);
@@ -994,13 +1133,13 @@ static int get_server_info(uint32 servertype,
if (count == alloced) {
struct srv_info_struct *ts;
-
+
alloced += 10;
ts = (struct srv_info_struct *)
Realloc(*servers,sizeof(**servers)*alloced);
if (!ts) {
- DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
- return(0);
+ DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
+ return(0);
}
else *servers = ts;
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
@@ -1012,7 +1151,7 @@ static int get_server_info(uint32 servertype,
if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
/* this allows us to cope with an old nmbd */
- fstrcpy(s->domain,lp_workgroup());
+ fstrcpy(s->domain,global_myworkgroup);
}
if (sscanf(stype,"%X",&s->type) != 1) {
@@ -1121,15 +1260,15 @@ static int fill_srv_info(struct srv_info_struct *service,
switch (uLevel)
{
case 0:
- push_ascii(p,service->name, 15, STR_TERMINATE);
- break;
+ StrnCpy(p,service->name,15);
+ break;
case 1:
- push_ascii(p,service->name,15, STR_TERMINATE);
- SIVAL(p,18,service->type);
- SIVAL(p,22,PTR_DIFF(p2,baseaddr));
- len += CopyAndAdvance(&p2,service->comment,&l2);
- break;
+ StrnCpy(p,service->name,15);
+ SIVAL(p,18,service->type);
+ SIVAL(p,22,PTR_DIFF(p2,baseaddr));
+ len += CopyAndAdvance(&p2,service->comment,&l2);
+ break;
}
if (stringbuf)
@@ -1206,9 +1345,9 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
if (strcmp(str1, "WrLehDz") == 0) {
- pull_ascii_fstring(domain, p);
+ StrnCpy(domain, p, sizeof(fstring)-1);
} else {
- fstrcpy(domain, lp_workgroup());
+ StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);
}
if (lp_browse_list())
@@ -1381,7 +1520,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
}
if (!baseaddr) baseaddr = p;
- push_ascii(p,lp_servicename(snum),13, STR_TERMINATE);
+ StrnCpy(p,lp_servicename(snum),13);
if (uLevel > 0)
{
@@ -1389,7 +1528,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
SCVAL(p,13,0);
type = STYPE_DISKTREE;
if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC",lp_fstype(snum))) type = STYPE_IPC;
+ if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
SSVAL(p,14,type); /* device type */
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
@@ -1465,24 +1604,12 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
}
/****************************************************************************
- View the list of available shares.
-
- This function is the server side of the NetShareEnum() RAP call.
- It fills the return buffer with share names and share comments.
- Note that the return buffer normally (in all known cases) allows only
- twelve byte strings for share names (plus one for a nul terminator).
- Share names longer than 12 bytes must be skipped.
- ****************************************************************************/
-static BOOL api_RNetShareEnum( connection_struct *conn,
- uint16 vuid,
- char *param,
- char *data,
- int mdrcnt,
- int mprcnt,
- char **rdata,
- char **rparam,
- int *rdata_len,
- int *rparam_len )
+ view list of shares available
+ ****************************************************************************/
+static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
char *str1 = param+2;
char *str2 = skip_string(str1,1);
@@ -1502,9 +1629,7 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
data_len = fixed_len = string_len = 0;
for (i=0;i<count;i++)
- if( lp_browseable( i )
- && lp_snum_ok( i )
- && (strlen( lp_servicename( i ) ) < 13) ) /* Maximum name length. */
+ if (lp_browseable(i) && lp_snum_ok(i))
{
total++;
data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
@@ -1521,20 +1646,14 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
*rdata = REALLOC(*rdata,*rdata_len);
memset(*rdata,0,*rdata_len);
- p2 = (*rdata) + fixed_len; /* auxiliary data (strings) will go here */
+ p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
p = *rdata;
f_len = fixed_len;
s_len = string_len;
- for( i = 0; i < count; i++ )
- {
- if( lp_browseable( i )
- && lp_snum_ok( i )
- && (strlen( lp_servicename( i ) ) < 13) )
- {
- if( fill_share_info( conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata ) < 0 )
+ for (i = 0; i < count;i++)
+ if (lp_browseable(i) && lp_snum_ok(i))
+ if (fill_share_info(conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
break;
- }
- }
*rparam_len = 8;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -1547,375 +1666,6 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
counted,total,uLevel,
buf_len,*rdata_len,mdrcnt));
return(True);
-} /* api_RNetShareEnum */
-
-/****************************************************************************
- Add a share
- ****************************************************************************/
-static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- fstring sharename;
- fstring comment;
- pstring pathname;
- char *command, *cmdname;
- unsigned int offset;
- int snum;
- int res = ERRunsup;
-
- /* check it's a supported varient */
- if (!prefix_ok(str1, RAP_WShareAdd_REQ)) return False;
- if (!check_share_info(uLevel, str2)) return False;
- if (uLevel != 2) return False;
-
- pull_ascii_fstring(sharename, data);
- snum = find_service(sharename);
- if (snum >= 0) { /* already exists */
- res = ERRfilexists;
- goto error_exit;
- }
-
- /* only support disk share adds */
- if (SVAL(data,14) != STYPE_DISKTREE) return False;
-
- offset = IVAL(data, 16);
- if (offset >= mdrcnt) {
- res = ERRinvalidparam;
- goto error_exit;
- }
- pull_ascii_fstring(comment, offset? (data+offset) : "");
-
- offset = IVAL(data, 26);
- if (offset >= mdrcnt) {
- res = ERRinvalidparam;
- goto error_exit;
- }
- pull_ascii_pstring(pathname, offset? (data+offset) : "");
-
- string_replace(sharename, '"', ' ');
- string_replace(pathname, '"', ' ');
- string_replace(comment, '"', ' ');
-
- cmdname = lp_add_share_cmd();
-
- if (!cmdname || *cmdname == '\0') return False;
-
- asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment);
-
- if (command) {
- DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
- if ((res = smbrun(command, NULL)) != 0) {
- DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res ));
- SAFE_FREE(command);
- res = ERRnoaccess;
- goto error_exit;
- } else {
- SAFE_FREE(command);
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
- }
- } else return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam, *rparam_len);
- SSVAL(*rparam, 0, NERR_Success);
- SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam, 4, *rdata_len);
- *rdata_len = 0;
-
- return True;
-
-error_exit:
- *rparam_len = 4;
- *rparam = REALLOC(*rparam, *rparam_len);
- *rdata_len = 0;
- SSVAL(*rparam, 0, res);
- SSVAL(*rparam, 2, 0);
- return True;
-
-}
-
-/****************************************************************************
- view list of groups available
- ****************************************************************************/
-static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- int i;
- int errflags=0;
- int resume_context, cli_buf_size;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- BOOL ret;
-
- GROUP_MAP *group_list;
- int num_entries;
-
- if (strcmp(str1,"WrLeh") != 0)
- return False;
-
- /* parameters
- * W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
- * L -> length of receive buffer
- * e -> return parameter number of entries
- * h -> return parameter total number of users
- */
- if (strcmp("B21",str2) != 0)
- return False;
-
- /* get list of domain groups SID_DOMAIN_GRP=2 */
- become_root();
- ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False);
- unbecome_root();
-
- if( !ret ) {
- DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
- return False;
- }
-
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
- DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
-
- *rdata_len = cli_buf_size;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
-
- for(i=resume_context; i<num_entries; i++) {
- char* name=group_list[i].nt_name;
- if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
- /* truncate the name at 21 chars. */
- memcpy(p, name, 21);
- DEBUG(10,("adding entry %d group %s\n", i, p));
- p += 21;
- } else {
- /* set overflow error */
- DEBUG(3,("overflow on entry %d group %s\n", i, name));
- errflags=234;
- break;
- }
- }
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- SSVAL(*rparam, 0, errflags);
- SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam, 4, i-resume_context); /* is this right?? */
- SSVAL(*rparam, 6, num_entries); /* is this right?? */
-
- return(True);
-}
-
-/*******************************************************************
- get groups that a user is a member of
- ******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- const char *level_string;
- int count=0;
- SAM_ACCOUNT *sampw = NULL;
- BOOL ret = False;
- DOM_GID *gids = NULL;
- int num_groups = 0;
- int i;
- fstring grp_domain;
- fstring grp_name;
- enum SID_NAME_USE grp_type;
- DOM_SID sid, dom_sid;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
-
- if ( strcmp(str1,"zWrLeh") != 0 )
- return False;
-
- switch( uLevel ) {
- case 0:
- level_string = "B21";
- break;
- default:
- return False;
- }
-
- if (strcmp(level_string,str2) != 0)
- return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- /* Lookup the user information; This should only be one of
- our accounts (not remote domains) */
-
- pdb_init_sam( &sampw );
-
- become_root(); /* ROOT BLOCK */
-
- if ( !pdb_getsampwnam(sampw, UserName) )
- goto out;
-
- /* this next set of code is horribly inefficient, but since
- it is rarely called, I'm going to leave it like this since
- it easier to follow --jerry */
-
- /* get the list of group SIDs */
-
- if ( !get_domain_user_groups(conn->mem_ctx, &num_groups, &gids, sampw) ) {
- DEBUG(1,("api_NetUserGetGroups: get_domain_user_groups() failed!\n"));
- goto out;
- }
-
- /* convert to names (we don't support universal groups so the domain
- can only be ours) */
-
- sid_copy( &dom_sid, get_global_sam_sid() );
- for (i=0; i<num_groups; i++) {
-
- /* make the DOM_GID into a DOM_SID and then lookup
- the name */
-
- sid_copy( &sid, &dom_sid );
- sid_append_rid( &sid, gids[i].g_rid );
-
- if ( lookup_sid(&sid, grp_domain, grp_name, &grp_type) ) {
- pstrcpy(p, grp_name);
- p += 21;
- count++;
- }
- }
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,4,count); /* is this right?? */
- SSVAL(*rparam,6,count); /* is this right?? */
-
- ret = True;
-
-out:
- unbecome_root(); /* END ROOT BLOCK */
-
- pdb_free_sam( &sampw );
-
- return ret;
-}
-
-/*******************************************************************
- get all users
- ******************************************************************/
-static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- SAM_ACCOUNT *pwd=NULL;
- int count_sent=0;
- int count_total=0;
- int errflags=0;
- int resume_context, cli_buf_size;
-
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
-
- if (strcmp(str1,"WrLeh") != 0)
- return False;
- /* parameters
- * W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
- * L -> length of receive buffer
- * e -> return parameter number of entries
- * h -> return parameter total number of users
- */
-
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
- DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (strcmp("B21",str2) != 0)
- return False;
-
- *rdata_len = cli_buf_size;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
-
- /* to get user list enumerations for NetUserEnum in B21 format */
- pdb_init_sam(&pwd);
-
- /* Open the passgrp file - not for update. */
- become_root();
- if(!pdb_setsampwent(False)) {
- DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
- unbecome_root();
- return False;
- }
- errflags=NERR_Success;
-
- while ( pdb_getsampwent(pwd) ) {
- const char *name=pdb_get_username(pwd);
- if ((name) && (*(name+strlen(name)-1)!='$')) {
- count_total++;
- if(count_total>=resume_context) {
- if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21) ) {
- pstrcpy(p,name);
- DEBUG(10,("api_RNetUserEnum:adding entry %d username %s\n",count_sent,p));
- p += 21;
- count_sent++;
- } else {
- /* set overflow error */
- DEBUG(10,("api_RNetUserEnum:overflow on entry %d username %s\n",count_sent,name));
- errflags=234;
- break;
- }
- }
- }
- } ;
-
- pdb_endsampwent();
- unbecome_root();
-
- pdb_free_sam(&pwd);
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,0,errflags);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,count_sent); /* is this right?? */
- SSVAL(*rparam,6,count_total); /* is this right?? */
-
- return True;
}
@@ -1978,78 +1728,116 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *p = skip_string(param+2,2);
- fstring user;
- fstring pass1,pass2;
+ char *p = skip_string(param+2,2);
+ fstring user;
+ fstring pass1,pass2;
- pull_ascii_fstring(user,p);
+ fstrcpy(user,p);
- p = skip_string(p,1);
+ p = skip_string(p,1);
- memset(pass1,'\0',sizeof(pass1));
- memset(pass2,'\0',sizeof(pass2));
- memcpy(pass1,p,16);
- memcpy(pass2,p+16,16);
+ memset(pass1,'\0',sizeof(pass1));
+ memset(pass2,'\0',sizeof(pass2));
+ memcpy(pass1,p,16);
+ memcpy(pass2,p+16,16);
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam,0,NERR_badpass);
+ SSVAL(*rparam,2,0); /* converter word */
- DEBUG(3,("Set password for <%s>\n",user));
+ DEBUG(3,("Set password for <%s>\n",user));
- /*
- * Attempt to verify the old password against smbpasswd entries
- * Win98 clients send old and new password in plaintext for this call.
- */
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
- {
- auth_serversupplied_info *server_info = NULL;
- DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
+ (void)map_username(user);
- if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
- become_root();
- if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False))) {
- SSVAL(*rparam,0,NERR_Success);
- }
- unbecome_root();
+ /*
+ * Attempt to verify the old password against smbpasswd entries
+ * Win98 clients send old and new password in plaintext for this call.
+ */
- free_server_info(&server_info);
- }
- data_blob_clear_free(&password);
- }
+ {
+ fstring saved_pass2;
+ SAM_ACCOUNT *sampass = NULL;
- /*
- * If the plaintext change failed, attempt
- * the old encrypted method. NT will generate this
- * after trying the samr method. Note that this
- * method is done as a last resort as this
- * password change method loses the NT password hash
- * and cannot change the UNIX password as no plaintext
- * is received.
- */
+ /*
+ * Save the new password as change_oem_password overwrites it
+ * with zeros.
+ */
- if(SVAL(*rparam,0) != NERR_Success) {
- SAM_ACCOUNT *hnd = NULL;
+ fstrcpy(saved_pass2, pass2);
- if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
- become_root();
- if (change_lanman_password(hnd,(uchar *)pass2)) {
- SSVAL(*rparam,0,NERR_Success);
- }
- unbecome_root();
- pdb_free_sam(&hnd);
- }
- }
+ if (check_plaintext_password(user,pass1,strlen(pass1),&sampass) &&
+ change_oem_password(sampass,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+
+ /*
+ * If unix password sync was requested, attempt to change
+ * the /etc/passwd database also. Return failure if this cannot
+ * be done.
+ */
+
+ if(lp_unix_password_sync() && !chgpasswd(user,pass1,saved_pass2,False))
+ SSVAL(*rparam,0,NERR_badpass);
+ }
+
+ if (sampass)
+ pdb_free_sam(sampass);
+ }
+
+ /*
+ * If the above failed, attempt the plaintext password change.
+ * This tests against the /etc/passwd database only.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success)
+ {
+ if (password_ok(user, pass1,strlen(pass1),NULL) &&
+ chgpasswd(user,pass1,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ }
+
+ /*
+ * If the plaintext change failed, attempt
+ * the old encrypted method. NT will generate this
+ * after trying the samr method. Note that this
+ * method is done as a last resort as this
+ * password change method loses the NT password hash
+ * and cannot change the UNIX password as no plaintext
+ * is received.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success)
+ {
+ SAM_ACCOUNT *sampass = NULL;
+
+ if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &sampass) &&
+ change_lanman_password(sampass,(unsigned char *)pass1,(unsigned char *)pass2))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ pdb_free_sam(sampass);
+ }
- memset((char *)pass1,'\0',sizeof(fstring));
- memset((char *)pass2,'\0',sizeof(fstring));
+ memset((char *)pass1,'\0',sizeof(fstring));
+ memset((char *)pass2,'\0',sizeof(fstring));
- return(True);
+ return(True);
}
/****************************************************************************
@@ -2061,46 +1849,53 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- fstring user;
- char *p = param + 2;
- *rparam_len = 2;
- *rparam = REALLOC(*rparam,*rparam_len);
+ fstring user;
+ char *p = param + 2;
+ *rparam_len = 2;
+ *rparam = REALLOC(*rparam,*rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_badpass);
+ SSVAL(*rparam,0,NERR_badpass);
- /*
- * Check the parameter definition is correct.
- */
+ /*
+ * Check the parameter definition is correct.
+ */
+ if(!strequal(param + 2, "zsT")) {
+ DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
+ return False;
+ }
+ p = skip_string(p, 1);
- if(!strequal(param + 2, "zsT")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
- return False;
- }
- p = skip_string(p, 1);
+ if(!strequal(p, "B516B16")) {
+ DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
+ return False;
+ }
+ p = skip_string(p,1);
- if(!strequal(p, "B516B16")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
- return False;
- }
- p = skip_string(p,1);
- p += pull_ascii_fstring(user,p);
+ fstrcpy(user,p);
+ p = skip_string(p,1);
- DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
+ DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
- (void)map_username(user);
+ (void)map_username(user);
- if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))) {
- SSVAL(*rparam,0,NERR_Success);
- }
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
- return(True);
+ if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+
+ return(True);
}
/****************************************************************************
@@ -2116,14 +1911,11 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
- int errcode;
+ int jobid, errcode;
extern struct current_user current_user;
WERROR werr = WERR_OK;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
/* check it's a supported varient */
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
@@ -2133,7 +1925,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
*rparam = REALLOC(*rparam,*rparam_len);
*rdata_len = 0;
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode = NERR_JobNotFound;
goto out;
}
@@ -2142,19 +1934,19 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
- if (print_job_delete(&current_user, snum, jobid, &werr))
+ if (print_job_delete(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
- if (print_job_pause(&current_user, snum, jobid, &werr))
+ if (print_job_pause(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
- if (print_job_resume(&current_user, snum, jobid, &werr))
+ if (print_job_resume(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
}
-
+
if (!W_ERROR_IS_OK(werr))
errcode = W_ERROR_V(werr);
@@ -2210,7 +2002,6 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
}
if (!W_ERROR_IS_OK(werr)) errcode = W_ERROR_V(werr);
-
out:
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
@@ -2251,14 +2042,12 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
+ int jobid;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
int place, errcode;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -2269,7 +2058,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
(!check_printjob_info(&desc,uLevel,str2)))
return(False);
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode=NERR_JobNotFound;
goto out;
}
@@ -2281,14 +2070,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
/* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
- if (print_job_set_place(snum, jobid, place)) {
+ if (print_job_set_place(jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
- if (print_job_set_name(snum, jobid, data)) {
+ if (print_job_set_name(jobid, data)) {
errcode=NERR_Success;
}
break;
@@ -2360,8 +2149,8 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
p = *rdata;
p2 = p + struct_len;
if (uLevel != 20) {
- srvstr_push(NULL, p,local_machine,16,
- STR_ASCII|STR_UPPER|STR_TERMINATE);
+ StrnCpy(p,local_machine,16);
+ strupper(p);
}
p += 16;
if (uLevel > 0)
@@ -2371,15 +2160,15 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
pstring comment;
uint32 servertype= lp_default_server_announce();
- push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE);
+ pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
- for (i=0;i<count;i++) {
- if (strequal(servers[i].name,local_machine)) {
+ if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
+ for (i=0;i<count;i++)
+ if (strequal(servers[i].name,local_machine))
+ {
servertype = servers[i].type;
- push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);
+ pstrcpy(comment,servers[i].comment);
}
- }
}
SAFE_FREE(servers);
@@ -2449,7 +2238,7 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
pstrcpy(p2,local_machine);
- strupper_m(p2);
+ strupper(p2);
p2 = skip_string(p2,1);
p += 4;
@@ -2459,8 +2248,8 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
- pstrcpy(p2,lp_workgroup());
- strupper_m(p2);
+ pstrcpy(p2,global_myworkgroup);
+ strupper(p2);
p2 = skip_string(p2,1);
p += 4;
@@ -2469,7 +2258,7 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
p += 2;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,lp_workgroup()); /* don't know. login domain?? */
+ pstrcpy(p2,global_myworkgroup); /* don't know. login domain?? */
p2 = skip_string(p2,1);
p += 4;
@@ -2734,7 +2523,8 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
+ pstrcpy(p2, lp_logon_home());
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
@@ -2770,13 +2560,15 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(p,42,
conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
+ pstrcpy(p2,lp_logon_home());
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
SSVAL(p,52,0); /* flags */
SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
- pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
+ pstrcpy(p2,lp_logon_script());
+ standard_sub_conn( conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
if (uLevel == 2)
{
@@ -2801,7 +2593,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVALS(p,104,-1); /* num_logons */
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
pstrcpy(p2,"\\\\%L");
- standard_sub_conn(conn, p2,0);
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SSVAL(p,110,49); /* country_code */
SSVAL(p,112,860); /* code page */
@@ -2815,6 +2607,56 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
return(True);
}
+/*******************************************************************
+ get groups that a user is a member of
+ ******************************************************************/
+static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *UserName = skip_string(str2,1);
+ char *p = skip_string(UserName,1);
+ int uLevel = SVAL(p,0);
+ const char *level_string;
+ int count=0;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zWrLeh") != 0) return False;
+ switch( uLevel ) {
+ case 0: level_string = "B21"; break;
+ default: return False;
+ }
+ if (strcmp(level_string,str2) != 0) return False;
+
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+
+ /* XXXX we need a real SAM database some day */
+ pstrcpy(p,"Users"); p += 21; count++;
+ pstrcpy(p,"Domain Users"); p += 21; count++;
+ pstrcpy(p,"Guests"); p += 21; count++;
+ pstrcpy(p,"Domain Guests"); p += 21; count++;
+
+ *rdata_len = PTR_DIFF(p,*rdata);
+
+ SSVAL(*rparam,4,count); /* is this right?? */
+ SSVAL(*rparam,6,count); /* is this right?? */
+
+ return(True);
+}
+
+
static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
@@ -2826,12 +2668,6 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
int uLevel;
struct pack_desc desc;
char* name;
- /* With share level security vuid will always be zero.
- Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser != NULL)
- DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
- vuser->user.unix_name));
uLevel = SVAL(p,0);
name = p + 2;
@@ -2870,12 +2706,20 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
fstring mypath;
fstrcpy(mypath,"\\\\");
fstrcat(mypath,local_machine);
- strupper_m(mypath);
+ strupper(mypath);
PACKS(&desc,"z",mypath); /* computer */
}
- PACKS(&desc,"z",lp_workgroup());/* domain */
+ PACKS(&desc,"z",global_myworkgroup);/* domain */
- PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :""); /* script path */
+/* JHT - By calling lp_logon_script() and standard_sub() we have */
+/* made sure all macros are fully substituted and available */
+ {
+ pstring logon_script;
+ pstrcpy(logon_script,lp_logon_script());
+ standard_sub_conn( conn, logon_script,sizeof(logon_script) );
+ PACKS(&desc,"z", logon_script); /* script path */
+ }
+/* End of JHT mods */
PACKI(&desc,"D",0x00000000); /* reserved */
}
@@ -2935,7 +2779,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
int count;
int i;
int snum;
- uint32 jobid;
+ int job;
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
@@ -2952,14 +2796,14 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if (strcmp(str1,"WWrLh") != 0) return False;
if (!check_printjob_info(&desc,uLevel,str2)) return False;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ job = SVAL(p,0);
+ snum = print_job_snum(job);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
count = print_queue_status(snum,&queue,&status);
for (i = 0; i < count; i++) {
- if (queue[i].job == jobid) break;
+ if (queue[i].job == job) break;
}
if (mdrcnt > 0) {
@@ -3024,7 +2868,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
- /* check it's a supported variant */
+ /* check it's a supported varient */
if (strcmp(str1,"zWrLeh") != 0) return False;
if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
if (!check_printjob_info(&desc,uLevel,str2)) return False;
@@ -3089,7 +2933,7 @@ static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
char buf[100];
strncpy(buf,SERVICE(snum),sizeof(buf)-1);
buf[sizeof(buf)-1] = 0;
- strupper_m(buf);
+ strupper(buf);
if (uLevel <= 1) {
PACKS(desc,"B9",buf); /* szName */
if (uLevel == 1) {
@@ -3377,72 +3221,6 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
return(True);
}
-
-/****************************************************************************
- List open sessions
- ****************************************************************************/
-static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param, char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- struct pack_desc desc;
- struct sessionid *session_list;
- int i, num_sessions;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("RNetSessionEnum uLevel=%d\n",uLevel));
- DEBUG(7,("RNetSessionEnum req string=%s\n",str1));
- DEBUG(7,("RNetSessionEnum ret string=%s\n",str2));
-
- /* check it's a supported varient */
- if (strcmp(str1,RAP_NetSessionEnum_REQ) != 0) return False;
- if (uLevel != 2 || strcmp(str2,RAP_SESSION_INFO_L2) != 0) return False;
-
- num_sessions = list_sessions(&session_list);
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- memset((char *)&desc,'\0',sizeof(desc));
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (!init_package(&desc,num_sessions,0)) {
- return False;
- }
-
- for(i=0; i<num_sessions; i++) {
- PACKS(&desc, "z", session_list[i].remote_machine);
- PACKS(&desc, "z", session_list[i].username);
- PACKI(&desc, "W", 1); /* num conns */
- PACKI(&desc, "W", 0); /* num opens */
- PACKI(&desc, "W", 1); /* num users */
- PACKI(&desc, "D", 0); /* session time */
- PACKI(&desc, "D", 0); /* idle time */
- PACKI(&desc, "D", 0); /* flags */
- PACKS(&desc, "z", "Unknown Client"); /* client type string */
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter */
- SSVAL(*rparam,4,num_sessions); /* count */
-
- DEBUG(4,("RNetSessionEnum: errorcode %d\n",desc.errcode));
- return True;
-}
-
-
/****************************************************************************
The buffer was too small
****************************************************************************/
@@ -3490,53 +3268,54 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
-static const struct
+struct
{
const char *name;
int id;
BOOL (*fn)(connection_struct *,uint16,char *,char *,
int,int,char **,char **,int *,int *);
- BOOL auth_user; /* Deny anonymous access? */
+ int flags;
} api_commands[] = {
- {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum, True},
- {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo},
- {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd},
- {"RNetSessionEnum", RAP_WsessionEnum, api_RNetSessionEnum, True},
- {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo},
- {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum, True},
- {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers, True},
- {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum, True},
- {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo},
- {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups},
- {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo},
- {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum, True},
- {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo},
- {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl},
- {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl},
- {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate},
- {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo},
- {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel},
- {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel},
- {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel},
- {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum},
- {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo},
- {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD},
- {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl},
- {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum}, /* anon OK */
- {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
- {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword},
- {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon},
- {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo},
- {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum},
- {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum},
- {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum},
- {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword}, /* anon OK */
- {NULL, -1, api_Unsupported}};
-
-/* The following RAP calls are not implemented by Samba:
-
- RAP_WFileEnum2 - anon not OK
-*/
+ {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum,0},
+ {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd,0},
+#endif
+ {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum,0},
+#endif
+ {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers,0},
+#if 0 /* Not yet implemented. */
+ {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum,0},
+#endif
+ {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo,0},
+ {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups,0},
+ {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo,0},
+ {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum,0},
+ {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo,0},
+ {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl,0},
+ {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl,0},
+ {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate,0},
+ {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo,0},
+ {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel,0},
+ {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel,0},
+ {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel,0},
+ {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum,0},
+ {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo,0},
+ {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD,0},
+ {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl,0},
+ {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum,0},
+ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms,0},
+ {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword,0},
+ {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon,0},
+ {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo,0},
+ {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum,0},
+ {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum,0},
+ {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum,0},
+ {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword,0},
+ {NULL, -1, api_Unsupported,0}};
+
/****************************************************************************
Handle remote api calls
@@ -3573,15 +3352,6 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
}
}
- /* Check whether this api call can be done anonymously */
-
- if (api_commands[i].auth_user && lp_restrict_anonymous()) {
- user_struct *user = get_valid_user_struct(vuid);
-
- if (!user || user->guest)
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
-
rdata = (char *)malloc(1024);
if (rdata)
memset(rdata,'\0',1024);
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index b77fe601b69..acce5a7b640 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -23,13 +23,12 @@
static struct mangle_fns *mangle_fns;
/* this allows us to add more mangling backends */
-static const struct {
+static struct {
const char *name;
struct mangle_fns *(*init_fn)(void);
} mangle_backends[] = {
{ "hash", mangle_hash_init },
{ "hash2", mangle_hash2_init },
- /*{ "tdb", mangle_tdb_init }, */
{ NULL, NULL }
};
@@ -107,7 +106,7 @@ BOOL mangle_check_cache(char *s)
map a long filename to a 8.3 name.
*/
-void mangle_map(pstring OutName, BOOL need83, BOOL cache83, int snum)
+void mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum)
{
/* name mangling can be disabled for speed, in which case
we just truncate the string */
@@ -120,5 +119,5 @@ void mangle_map(pstring OutName, BOOL need83, BOOL cache83, int snum)
/* invoke the inane "mangled map" code */
mangle_map_filename(OutName, snum);
- mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(snum));
+ mangle_fns->name_map(OutName, need83, cache83);
}
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index 7b8cbdbddba..83c73625fc6 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Name mangling
- Copyright (C) Andrew Tridgell 1992-2002
- Copyright (C) Simo Sorce 2001
- Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,16 +19,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
/* -------------------------------------------------------------------------- **
* Notable problems...
*
* March/April 1998 CRH
* - Many of the functions in this module overwrite string buffers passed to
* them. This causes a variety of problems and is, generally speaking,
- * dangerous and scarry. See the kludge notes in name_map()
+ * dangerous and scarry. See the kludge notes in name_map_mangle()
* below.
- * - It seems that something is calling name_map() twice. The
+ * - It seems that something is calling name_map_mangle() twice. The
* first call is probably some sort of test. Names which contain
* illegal characters are being doubly mangled. I'm not sure, but
* I'm guessing the problem is in server.c.
@@ -51,6 +49,13 @@
/* -------------------------------------------------------------------------- **
+ * External Variables...
+ */
+
+extern int case_default; /* Are conforming 8.3 names all upper or lower? */
+extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
+
+/* -------------------------------------------------------------------------- **
* Other stuff...
*
* magic_char - This is the magic char used for mangling. It's
@@ -79,11 +84,11 @@
*
* isbasecahr() - Given a character, check the chartest array to see
* if that character is in the basechars set. This is
- * faster than using strchr_m().
+ * faster than using strchr().
*
* isillegal() - Given a character, check the chartest array to see
* if that character is in the illegal characters set.
- * This is faster than using strchr_m().
+ * This is faster than using strchr().
*
* mangled_cache - Cache header used for storing mangled -> original
* reverse maps.
@@ -121,249 +126,158 @@ static BOOL ct_initialized = False;
static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
static BOOL mc_initialized = False;
#define MANGLED_CACHE_MAX_ENTRIES 1024
-#define MANGLED_CACHE_MAX_MEMORY 0
+#define MANGLED_CACHE_MAX_MEMORY 0
-/* -------------------------------------------------------------------- */
-
-static NTSTATUS has_valid_83_chars(const smb_ucs2_t *s, BOOL allow_wildcards)
-{
- if (!s || !*s)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* CHECK: this should not be necessary if the ms wild chars
- are not valid in valid.dat --- simo */
- if (!allow_wildcards && ms_has_wild_w(s))
- return NT_STATUS_UNSUCCESSFUL;
-
- while (*s) {
- if(!isvalid83_w(*s))
- return NT_STATUS_UNSUCCESSFUL;
- s++;
- }
-
- return NT_STATUS_OK;
-}
-/* return False if something fail and
- * return 2 alloced unicode strings that contain prefix and extension
+/* -------------------------------------------------------------------------- **
+ * Functions...
*/
-static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **prefix,
- smb_ucs2_t **extension, BOOL allow_wildcards)
-{
- size_t ext_len;
- smb_ucs2_t *p;
-
- *extension = 0;
- *prefix = strdup_w(ucs2_string);
- if (!*prefix) {
- return NT_STATUS_NO_MEMORY;
- }
- if ((p = strrchr_w(*prefix, UCS2_CHAR('.')))) {
- ext_len = strlen_w(p+1);
- if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) &&
- (NT_STATUS_IS_OK(has_valid_83_chars(p+1,allow_wildcards)))) /* check extension */ {
- *p = 0;
- *extension = strdup_w(p+1);
- if (!*extension) {
- SAFE_FREE(*prefix);
- return NT_STATUS_NO_MEMORY;
- }
- }
- }
- return NT_STATUS_OK;
-}
-
/* ************************************************************************** **
- * Return NT_STATUS_UNSUCCESSFUL if a name is a special msdos reserved name.
+ * Initialize the static character test array.
*
- * Input: fname - String containing the name to be tested.
+ * Input: none
*
- * Output: NT_STATUS_UNSUCCESSFUL, if the name matches one of the list of reserved names.
+ * Output: none
*
- * Notes: This is a static function called by is_8_3(), below.
+ * Notes: This function changes (loads) the contents of the <chartest>
+ * array. The scope of <chartest> is this file.
*
* ************************************************************************** **
*/
+static void init_chartest( void )
+ {
+ const char *illegalchars = "*\\/?<>|\":";
+ const unsigned char *s;
+
+ memset( (char *)chartest, '\0', 256 );
-static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards, BOOL only_8_3)
-{
- smb_ucs2_t *str, *p;
- NTSTATUS ret = NT_STATUS_OK;
-
- if (!fname || !*fname)
- return NT_STATUS_INVALID_PARAMETER;
-
- /* . and .. are valid names. */
- if (strcmp_wa(fname, ".")==0 || strcmp_wa(fname, "..")==0)
- return NT_STATUS_OK;
-
- /* Name cannot start with '.' */
- if (*fname == UCS2_CHAR('.'))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (only_8_3) {
- ret = has_valid_83_chars(fname, allow_wildcards);
- if (!NT_STATUS_IS_OK(ret))
- return ret;
- }
-
- str = strdup_w(fname);
- p = strchr_w(str, UCS2_CHAR('.'));
- if (p && p[1] == UCS2_CHAR(0)) {
- /* Name cannot end in '.' */
- SAFE_FREE(str);
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (p)
- *p = 0;
- strupper_w(str);
- p = &(str[1]);
-
- switch(str[0])
- {
- case UCS2_CHAR('A'):
- if(strcmp_wa(p, "UX") == 0)
- ret = NT_STATUS_UNSUCCESSFUL;
- break;
- case UCS2_CHAR('C'):
- if((strcmp_wa(p, "LOCK$") == 0)
- || (strcmp_wa(p, "ON") == 0)
- || (strcmp_wa(p, "OM1") == 0)
- || (strcmp_wa(p, "OM2") == 0)
- || (strcmp_wa(p, "OM3") == 0)
- || (strcmp_wa(p, "OM4") == 0)
- )
- ret = NT_STATUS_UNSUCCESSFUL;
- break;
- case UCS2_CHAR('L'):
- if((strcmp_wa(p, "PT1") == 0)
- || (strcmp_wa(p, "PT2") == 0)
- || (strcmp_wa(p, "PT3") == 0)
- )
- ret = NT_STATUS_UNSUCCESSFUL;
- break;
- case UCS2_CHAR('N'):
- if(strcmp_wa(p, "UL") == 0)
- ret = NT_STATUS_UNSUCCESSFUL;
- break;
- case UCS2_CHAR('P'):
- if(strcmp_wa(p, "RN") == 0)
- ret = NT_STATUS_UNSUCCESSFUL;
- break;
- default:
- break;
- }
-
- SAFE_FREE(str);
- return ret;
-}
-
-static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards)
-{
- smb_ucs2_t *pref = 0, *ext = 0;
- size_t plen;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!fname || !*fname)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (strlen_w(fname) > 12)
- return NT_STATUS_UNSUCCESSFUL;
-
- if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
- return NT_STATUS_OK;
-
- if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
- goto done;
-
- if (!NT_STATUS_IS_OK(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
- goto done;
- plen = strlen_w(pref);
-
- if (strchr_wa(pref, '.'))
- goto done;
- if (plen < 1 || plen > 8)
- goto done;
- if (ext && (strlen_w(ext) > 3))
- goto done;
-
- ret = NT_STATUS_OK;
-
-done:
- SAFE_FREE(pref);
- SAFE_FREE(ext);
- return ret;
-}
-
-static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards)
-{
- const char *f;
- smb_ucs2_t *ucs2name;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- size_t size;
-
- if (!fname || !*fname)
- return False;
- if ((f = strrchr(fname, '/')) == NULL)
- f = fname;
- else
- f++;
-
- if (strlen(f) > 12)
- return False;
-
- size = push_ucs2_allocate(&ucs2name, f);
- if (size == (size_t)-1) {
- DEBUG(0,("is_8_3: internal error push_ucs2_allocate() failed!\n"));
- goto done;
- }
-
- ret = is_8_3_w(ucs2name, allow_wildcards);
-
-done:
- SAFE_FREE(ucs2name);
+ for( s = (const unsigned char *)illegalchars; *s; s++ )
+ chartest[*s] = ILLEGAL_MASK;
- if (!NT_STATUS_IS_OK(ret)) {
- return False;
- }
-
- return True;
-}
+ for( s = (const unsigned char *)basechars; *s; s++ )
+ chartest[*s] |= BASECHAR_MASK;
+ ct_initialized = True;
+ } /* init_chartest */
-
-/* -------------------------------------------------------------------------- **
- * Functions...
+/* ************************************************************************** **
+ * Return True if a name is a special msdos reserved name.
+ *
+ * Input: fname - String containing the name to be tested.
+ *
+ * Output: True, if the name matches one of the list of reserved names.
+ *
+ * Notes: This is a static function called by is_8_3(), below.
+ *
+ * ************************************************************************** **
*/
+static BOOL is_reserved_msdos( const char *fname )
+ {
+ char upperFname[13];
+ char *p;
+
+ StrnCpy (upperFname, fname, 12);
+
+ /* lpt1.txt and con.txt etc are also illegal */
+ p = strchr(upperFname,'.');
+ if( p )
+ *p = '\0';
+
+ strupper( upperFname );
+ p = upperFname + 1;
+ switch( upperFname[0] )
+ {
+ case 'A':
+ if( 0 == strcmp( p, "UX" ) )
+ return( True );
+ break;
+ case 'C':
+ if( (0 == strcmp( p, "LOCK$" ))
+ || (0 == strcmp( p, "ON" ))
+ || (0 == strcmp( p, "OM1" ))
+ || (0 == strcmp( p, "OM2" ))
+ || (0 == strcmp( p, "OM3" ))
+ || (0 == strcmp( p, "OM4" ))
+ )
+ return( True );
+ break;
+ case 'L':
+ if( (0 == strcmp( p, "PT1" ))
+ || (0 == strcmp( p, "PT2" ))
+ || (0 == strcmp( p, "PT3" ))
+ )
+ return( True );
+ break;
+ case 'N':
+ if( 0 == strcmp( p, "UL" ) )
+ return( True );
+ break;
+ case 'P':
+ if( 0 == strcmp( p, "RN" ) )
+ return( True );
+ break;
+ }
+
+ return( False );
+ } /* is_reserved_msdos */
/* ************************************************************************** **
- * Initialize the static character test array.
+ * Determine whether or not a given name contains illegal characters, even
+ * long names.
*
- * Input: none
+ * Input: name - The name to be tested.
*
- * Output: none
+ * Output: True if an illegal character was found in <name>, else False.
*
- * Notes: This function changes (loads) the contents of the <chartest>
- * array. The scope of <chartest> is this file.
+ * Notes: This is used to test a name on the host system, long or short,
+ * for characters that would be illegal on most client systems,
+ * particularly DOS and Windows systems. Unix and AmigaOS, for
+ * example, allow a filenames which contain such oddities as
+ * quotes ("). If a name is found which does contain an illegal
+ * character, it is mangled even if it conforms to the 8.3
+ * format.
*
* ************************************************************************** **
*/
-static void init_chartest( void )
-{
- const char *illegalchars = "*\\/?<>|\":";
- const unsigned char *s;
-
- memset( (char *)chartest, '\0', 256 );
-
- for( s = (const unsigned char *)illegalchars; *s; s++ )
- chartest[*s] = ILLEGAL_MASK;
-
- for( s = (const unsigned char *)basechars; *s; s++ )
- chartest[*s] |= BASECHAR_MASK;
-
- ct_initialized = True;
-}
+static BOOL is_illegal_name( char *name )
+ {
+ unsigned char *s;
+ int skip;
+ int namelen;
+
+ if( !name )
+ return( True );
+
+ if( !ct_initialized )
+ init_chartest();
+
+ namelen = strlen(name);
+ if (namelen &&
+ name[namelen-1] == '.' &&
+ !strequal(name, ".") &&
+ !strequal(name, ".."))
+ return True;
+
+ s = (unsigned char *)name;
+ while( *s )
+ {
+ skip = get_character_len( *s );
+ if( skip != 0 )
+ {
+ s += skip;
+ }
+ else
+ {
+ if( isillegal( *s ) )
+ return( True );
+ else
+ s++;
+ }
+ }
+
+ return( False );
+ } /* is_illegal_name */
/* ************************************************************************** **
* Return True if the name *could be* a mangled name.
@@ -382,22 +296,152 @@ static void init_chartest( void )
*
* ************************************************************************** **
*/
-static BOOL is_mangled(const char *s)
+static BOOL is_mangled( const char *s )
{
char *magic;
+ BOOL ret = False;
if( !ct_initialized )
init_chartest();
- magic = strchr_m( s, magic_char );
- while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */
+ magic = strchr( s, magic_char );
+ while( magic && magic[1] && magic[2] ) {
+ /* 3 chars, 1st is magic. */
if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
&& isbasechar( toupper(magic[1]) ) /* is 2nd char basechar? */
&& isbasechar( toupper(magic[2]) ) ) /* is 3rd char basechar? */
- return( True ); /* If all above, then true, */
- magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */
+ ret = ( True ); /* If all above, then true, */
+ magic = strchr( magic+1, magic_char ); /* else seek next magic. */
+ }
+
+ DEBUG(10,("is_mangled: %s : %s\n", s, ret ? "True" : "False"));
+
+ return ret;
+} /* is_mangled */
+
+static BOOL is_ms_wildchar(const char c)
+{
+ switch(c) {
+ case '*':
+ case '?':
+ case '<':
+ case '>':
+ case '"':
+ return True;
+ default:
+ return False;
}
- return( False );
+}
+
+/* ************************************************************************** **
+ * Return True if the name is a valid DOS name in 8.3 DOS format.
+ *
+ * Input: fname - File name to be checked.
+ * check_case - If True, and if case_mangle is True, then the
+ * name will be checked to see if all characters
+ * are the correct case. See case_mangle and
+ * case_default above.
+ * allow_wildcards - If True dos wildcard characters *?<>" are allowed as 8.3.
+ *
+ * Output: True if the name is a valid DOS name, else False.
+ *
+ * ************************************************************************** **
+ */
+
+static BOOL is_8_3( const char *cfname, BOOL check_case, BOOL allow_wildcards )
+{
+ int len;
+ int l;
+ int skip;
+ const char *p;
+ const char *dot_pos;
+ char *slash_pos;
+ const char *fname = cfname;
+
+ slash_pos = strrchr( fname, '/' );
+
+ /* If there is a directory path, skip it. */
+ if( slash_pos )
+ fname = slash_pos + 1;
+ len = strlen( fname );
+
+ DEBUG( 5, ( "Checking %s for 8.3\n", fname ) );
+
+ /* Can't be 0 chars or longer than 12 chars */
+ if( (len == 0) || (len > 12) )
+ return( False );
+
+ /* Mustn't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
+ if( is_reserved_msdos( fname ) )
+ return( False );
+
+ /* Check that all characters are the correct case, if asked to do so. */
+ if( check_case && case_mangle ) {
+ switch( case_default ) {
+ case CASE_LOWER:
+ if( strhasupper( fname ) )
+ return(False);
+ break;
+ case CASE_UPPER:
+ if( strhaslower( fname ) )
+ return(False);
+ break;
+ }
+ }
+
+ /* Can't contain invalid dos chars */
+ /* Windows use the ANSI charset.
+ But filenames are translated in the PC charset.
+ This Translation may be more or less relaxed depending
+ the Windows application. */
+
+ /* %%% A nice improvment to name mangling would be to translate
+ filename to ANSI charset on the smb server host */
+
+ p = fname;
+ dot_pos = NULL;
+ while( *p ) {
+ if( (skip = get_character_len( *p )) != 0 )
+ p += skip;
+ else {
+ if( *p == '.' && !dot_pos )
+ dot_pos = p;
+ else {
+ if( !isdoschar( *p )) {
+ if (!allow_wildcards)
+ return False;
+ if (!is_ms_wildchar(*p))
+ return False;
+ }
+ }
+ p++;
+ }
+ }
+
+ /* no dot and less than 9 means OK */
+ if( !dot_pos )
+ return( len <= 8 );
+
+ l = PTR_DIFF( dot_pos, fname );
+
+ /* base must be at least 1 char except special cases . and .. */
+ if( l == 0 )
+ return( 0 == strcmp( fname, "." ) || 0 == strcmp( fname, ".." ) );
+
+ /* base can't be greater than 8 */
+ if( l > 8 )
+ return( False );
+
+ /* extension must be between 1 and 3 */
+ if( (len - l < 2 ) || (len - l > 4) )
+ return( False );
+
+ /* extensions may not have a dot */
+ if( strchr( dot_pos+1, '.' ) )
+ return( False );
+
+ /* must be in 8.3 format */
+ return( True );
}
/* ************************************************************************** **
@@ -419,11 +463,14 @@ static BOOL is_mangled(const char *s)
*
* ************************************************************************** **
*/
+
static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
{
char *Key1 = (char *)ItemPtr;
char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1);
+ DEBUG(100,("cache_compare: %s %s\n", Key1, Key2));
+
return( StrCaseCmp( Key1, Key2 ) );
}
@@ -440,6 +487,7 @@ static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
*
* ************************************************************************** **
*/
+
static void cache_free_entry( ubi_trNodePtr WarrenZevon )
{
ZERO_STRUCTP(WarrenZevon);
@@ -463,22 +511,22 @@ static void cache_free_entry( ubi_trNodePtr WarrenZevon )
* ************************************************************************** **
*/
-static void mangle_reset( void )
+static void reset_mangled_cache( void )
{
if( !mc_initialized ) {
(void)ubi_cacheInit( mangled_cache,
- cache_compare,
- cache_free_entry,
- MANGLED_CACHE_MAX_ENTRIES,
- MANGLED_CACHE_MAX_MEMORY );
+ cache_compare,
+ cache_free_entry,
+ MANGLED_CACHE_MAX_ENTRIES,
+ MANGLED_CACHE_MAX_MEMORY );
mc_initialized = True;
} else {
(void)ubi_cacheClear( mangled_cache );
}
/*
- (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
- (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
+ (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
+ (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
*/
}
@@ -508,47 +556,49 @@ static void mangle_reset( void )
*/
static void cache_mangled_name( char *mangled_name, char *raw_name )
{
- ubi_cacheEntryPtr new_entry;
- char *s1;
- char *s2;
- size_t mangled_len;
- size_t raw_len;
- size_t i;
-
- /* If the cache isn't initialized, give up. */
- if( !mc_initialized )
- return;
-
- /* Init the string lengths. */
- mangled_len = strlen( mangled_name );
- raw_len = strlen( raw_name );
-
- /* See if the extensions are unmangled. If so, store the entry
- * without the extension, thus creating a "group" reverse map.
- */
- s1 = strrchr( mangled_name, '.' );
- if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
- i = 1;
- while( s1[i] && (tolower( s1[i] ) == s2[i]) )
- i++;
- if( !s1[i] && !s2[i] ) {
- mangled_len -= i;
- raw_len -= i;
- }
- }
-
- /* Allocate a new cache entry. If the allocation fails, just return. */
- i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
- new_entry = malloc( i );
- if( !new_entry )
- return;
-
- /* Fill the new cache entry, and add it to the cache. */
- s1 = (char *)(new_entry + 1);
- s2 = (char *)&(s1[mangled_len + 1]);
- safe_strcpy( s1, mangled_name, mangled_len );
- safe_strcpy( s2, raw_name, raw_len );
- ubi_cachePut( mangled_cache, i, new_entry, s1 );
+ ubi_cacheEntryPtr new_entry;
+ char *s1;
+ char *s2;
+ size_t mangled_len;
+ size_t raw_len;
+ size_t i;
+
+ /* If the cache isn't initialized, give up. */
+ if( !mc_initialized )
+ return;
+
+ /* Init the string lengths. */
+ mangled_len = strlen( mangled_name );
+ raw_len = strlen( raw_name );
+
+ /* See if the extensions are unmangled. If so, store the entry
+ * without the extension, thus creating a "group" reverse map.
+ */
+ s1 = strrchr( mangled_name, '.' );
+ if( s1 && (s2 = strrchr( raw_name, '.' )) )
+ {
+ i = 1;
+ while( s1[i] && (tolower( s1[i] ) == s2[i]) )
+ i++;
+ if( !s1[i] && !s2[i] )
+ {
+ mangled_len -= i;
+ raw_len -= i;
+ }
+ }
+
+ /* Allocate a new cache entry. If the allocation fails, just return. */
+ i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
+ new_entry = malloc( i );
+ if( !new_entry )
+ return;
+
+ /* Fill the new cache entry, and add it to the cache. */
+ s1 = (char *)(new_entry + 1);
+ s2 = (char *)&(s1[mangled_len + 1]);
+ (void)StrnCpy( s1, mangled_name, mangled_len );
+ (void)StrnCpy( s2, raw_name, raw_len );
+ ubi_cachePut( mangled_cache, i, new_entry, s1 );
}
/* ************************************************************************** **
@@ -566,58 +616,67 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
* ************************************************************************** **
*/
-static BOOL check_cache( char *s )
+static BOOL check_mangled_cache( char *s )
{
- ubi_cacheEntryPtr FoundPtr;
- char *ext_start = NULL;
- char *found_name;
- char *saved_ext = NULL;
-
- /* If the cache isn't initialized, give up. */
- if( !mc_initialized )
- return( False );
-
- FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
-
- /* If we didn't find the name *with* the extension, try without. */
- if( !FoundPtr ) {
- ext_start = strrchr( s, '.' );
- if( ext_start ) {
- if((saved_ext = strdup(ext_start)) == NULL)
- return False;
-
- *ext_start = '\0';
- FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
- /*
- * At this point s is the name without the
- * extension. We re-add the extension if saved_ext
- * is not null, before freeing saved_ext.
- */
- }
- }
-
- /* Okay, if we haven't found it we're done. */
- if( !FoundPtr ) {
- if(saved_ext) {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- SAFE_FREE(saved_ext);
- }
- return( False );
- }
-
- /* If we *did* find it, we need to copy it into the string buffer. */
- found_name = (char *)(FoundPtr + 1);
- found_name += (strlen( found_name ) + 1);
-
- (void)pstrcpy( s, found_name );
- if( saved_ext ) {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- SAFE_FREE(saved_ext);
- }
-
- return( True );
+ ubi_cacheEntryPtr FoundPtr;
+ char *ext_start = NULL;
+ char *found_name;
+ char *saved_ext = NULL;
+
+ /* If the cache isn't initialized, give up. */
+ if( !mc_initialized )
+ return( False );
+
+ FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
+
+ /* If we didn't find the name *with* the extension, try without. */
+ if( !FoundPtr )
+ {
+ ext_start = strrchr( s, '.' );
+ if( ext_start )
+ {
+ if((saved_ext = strdup(ext_start)) == NULL)
+ return False;
+
+ *ext_start = '\0';
+ FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
+ /*
+ * At this point s is the name without the
+ * extension. We re-add the extension if saved_ext
+ * is not null, before freeing saved_ext.
+ */
+ }
+ }
+
+ /* Okay, if we haven't found it we're done. */
+ if( !FoundPtr )
+ {
+ if(saved_ext)
+ {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ SAFE_FREE(saved_ext);
+ }
+ return( False );
+ }
+
+ /* If we *did* find it, we need to copy it into the string buffer. */
+ found_name = (char *)(FoundPtr + 1);
+ found_name += (strlen( found_name ) + 1);
+
+ DEBUG( 3, ("Found %s on mangled stack ", s) );
+
+ (void)pstrcpy( s, found_name );
+ if( saved_ext )
+ {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ SAFE_FREE(saved_ext);
+ }
+
+ DEBUG( 3, ("as %s\n", s) );
+
+ return( True );
}
/*****************************************************************************
@@ -625,67 +684,124 @@ static BOOL check_cache( char *s )
* the buffer must be able to hold 13 characters (including the null)
*****************************************************************************
*/
-static void to_8_3(char *s, int default_case)
+static void mangle_name_83( char *s)
{
- int csum;
- char *p;
- char extension[4];
- char base[9];
- int baselen = 0;
- int extlen = 0;
-
- extension[0] = 0;
- base[0] = 0;
-
- p = strrchr(s,'.');
- if( p && (strlen(p+1) < (size_t)4) ) {
- BOOL all_normal = ( strisnormal(p+1, default_case) ); /* XXXXXXXXX */
-
- if( all_normal && p[1] != 0 ) {
- *p = 0;
- csum = str_checksum( s );
- *p = '.';
- } else
- csum = str_checksum(s);
- } else
- csum = str_checksum(s);
-
- strupper_m( s );
-
- if( p ) {
- if( p == s )
- safe_strcpy( extension, "___", 3 );
- else {
- *p++ = 0;
- while( *p && extlen < 3 ) {
- if ( *p != '.') {
- extension[extlen++] = p[0];
- }
- p++;
- }
- extension[extlen] = 0;
- }
- }
-
- p = s;
+ int csum;
+ char *p;
+ char extension[4];
+ char base[9];
+ int baselen = 0;
+ int extlen = 0;
+ int skip;
+
+ extension[0] = 0;
+ base[0] = 0;
+
+ p = strrchr(s,'.');
+ if( p && (strlen(p+1) < (size_t)4) )
+ {
+ BOOL all_normal = ( strisnormal(p+1) ); /* XXXXXXXXX */
+
+ if( all_normal && p[1] != 0 )
+ {
+ *p = 0;
+ csum = str_checksum( s );
+ *p = '.';
+ }
+ else
+ csum = str_checksum(s);
+ }
+ else
+ csum = str_checksum(s);
+
+ strupper( s );
+
+ DEBUG( 5, ("Mangling name %s to ",s) );
+
+ if( p )
+ {
+ if( p == s )
+ safe_strcpy( extension, "___", 3 );
+ else
+ {
+ *p++ = 0;
+ while( *p && extlen < 3 )
+ {
+ skip = get_character_len( *p );
+ switch( skip )
+ {
+ case 2:
+ if( extlen < 2 )
+ {
+ extension[extlen++] = p[0];
+ extension[extlen++] = p[1];
+ }
+ else
+ {
+ extension[extlen++] = mangle( (unsigned char)*p );
+ }
+ p += 2;
+ break;
+ case 1:
+ extension[extlen++] = p[0];
+ p++;
+ break;
+ default:
+ if( isdoschar (*p) && *p != '.' )
+ extension[extlen++] = p[0];
+ p++;
+ break;
+ }
+ }
+ extension[extlen] = 0;
+ }
+ }
+
+ p = s;
+
+ while( *p && baselen < 5 )
+ {
+ skip = get_character_len(*p);
+ switch( skip )
+ {
+ case 2:
+ if( baselen < 4 )
+ {
+ base[baselen++] = p[0];
+ base[baselen++] = p[1];
+ }
+ else
+ {
+ base[baselen++] = mangle( (unsigned char)*p );
+ }
+ p += 2;
+ break;
+ case 1:
+ base[baselen++] = p[0];
+ p++;
+ break;
+ default:
+ if( isdoschar( *p ) && *p != '.' )
+ base[baselen++] = p[0];
+ p++;
+ break;
+ }
+ }
+ base[baselen] = 0;
+
+ csum = csum % (MANGLE_BASE*MANGLE_BASE);
+
+ (void)slprintf(s, 12, "%s%c%c%c",
+ base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
+
+ if( *extension )
+ {
+ (void)pstrcat( s, "." );
+ (void)pstrcat( s, extension );
+ }
+
+ DEBUG( 5, ( "%s\n", s ) );
- while( *p && baselen < 5 ) {
- if (*p != '.') {
- base[baselen++] = p[0];
- }
- p++;
- }
- base[baselen] = 0;
-
- csum = csum % (MANGLE_BASE*MANGLE_BASE);
-
- (void)slprintf(s, 12, "%s%c%c%c",
- base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
-
- if( *extension ) {
- (void)pstrcat( s, "." );
- (void)pstrcat( s, extension );
- }
}
/*****************************************************************************
@@ -707,36 +823,33 @@ static void to_8_3(char *s, int default_case)
* a conflicting cache entry prematurely, i.e. before
* we know whether the client is really interested in the
* current name. (See PR#13758). UKD.
+ * snum - Share number. This identifies the share in which the
+ * name exists.
*
* Output: Returns False only if the name wanted mangling but the share does
* not have name mangling turned on.
*
* ****************************************************************************
*/
-
-static void name_map(char *OutName, BOOL need83, BOOL cache83, int default_case)
+static void name_map_mangle(char *OutName, BOOL need83, BOOL cache83)
{
- smb_ucs2_t *OutName_ucs2;
- DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName,
- need83 ? "True" : "False", cache83 ? "True" : "False"));
-
- if (push_ucs2_allocate(&OutName_ucs2, OutName) == (size_t)-1) {
- DEBUG(0, ("push_ucs2_allocate failed!\n"));
- return;
- }
+ DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s )\n", OutName,
+ need83 ? "True" : "False", cache83 ? "True" : "False" ));
- if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False)))
+#ifdef MANGLE_LONG_FILENAMES
+ if( !need83 && is_illegal_name(OutName) )
need83 = True;
+#endif
/* check if it's already in 8.3 format */
- if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2, False))) {
+ if (need83 && !is_8_3(OutName, True, False)) {
char *tmp = NULL;
/* mangle it into 8.3 */
if (cache83)
tmp = strdup(OutName);
- to_8_3(OutName, default_case);
+ mangle_name_83(OutName);
if(tmp != NULL) {
cache_mangled_name(OutName, tmp);
@@ -744,26 +857,24 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83, int default_case)
}
}
- DEBUG(5,("name_map() ==> [%s]\n", OutName));
- SAFE_FREE(OutName_ucs2);
+ DEBUG(5,("name_map_mangle() ==> [%s]\n", OutName));
}
/*
- the following provides the abstraction layer to make it easier
- to drop in an alternative mangling implementation
-*/
+ * the following provides the abstraction layer to make it easier
+ * to drop in an alternative mangling implementation
+ * */
static struct mangle_fns mangle_fns = {
is_mangled,
is_8_3,
- mangle_reset,
- check_cache,
- name_map
+ reset_mangled_cache,
+ check_mangled_cache,
+ name_map_mangle
};
/* return the methods for this mangling implementation */
struct mangle_fns *mangle_hash_init(void)
{
- mangle_reset();
-
+ reset_mangled_cache();
return &mangle_fns;
}
diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c
index dcfd7663ba3..447118a6b1a 100644
--- a/source/smbd/mangle_hash2.c
+++ b/source/smbd/mangle_hash2.c
@@ -53,12 +53,6 @@
#include "includes.h"
-#if 1
-#define M_DEBUG(level, x) DEBUG(level, x)
-#else
-#define M_DEBUG(level, x)
-#endif
-
/* these flags are used to mark characters in as having particular
properties */
#define FLAG_BASECHAR 1
@@ -87,13 +81,6 @@ static unsigned char char_flags[256];
#define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag))
-/*
- this determines how many characters are used from the original filename
- in the 8.3 mangled name. A larger value leads to a weaker hash and more collisions.
- The largest possible value is 6.
-*/
-static unsigned mangle_prefix;
-
/* we will use a very simple direct mapped prefix cache. The big
advantage of this cache structure is speed and low memory usage
@@ -131,7 +118,7 @@ static u32 mangle_hash(const char *key, unsigned length)
function */
strncpy(str, key, length);
str[length] = 0;
- strupper_m(str);
+ strupper(str);
/* the length of a multi-byte string can change after a strupper_m */
length = strlen(str);
@@ -201,49 +188,45 @@ static const char *cache_lookup(u32 hash)
In this algorithm, mangled names use only pure ascii characters (no
multi-byte) so we can avoid doing a UCS2 conversion
*/
-static BOOL is_mangled_component(const char *name, size_t len)
+static BOOL is_mangled_component(const char *name)
{
- unsigned int i;
+ int len, i;
- M_DEBUG(10,("is_mangled_component %s (len %u) ?\n", name, (unsigned int)len));
+ DEBUG(10,("is_mangled_component %s ?\n", name));
/* check the length */
- if (len > 12 || len < 8)
- return False;
+ len = strlen(name);
+ if (len > 12 || len < 8) return False;
/* the best distinguishing characteristic is the ~ */
- if (name[6] != '~')
- return False;
+ if (len > 7 && name[6] != '~') return False;
/* check extension */
if (len > 8) {
- if (name[8] != '.')
- return False;
- for (i=9; name[i] && i < len; i++) {
+ if (name[8] != '.') return False;
+ for (i=9; name[i]; i++) {
if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
return False;
}
}
}
- /* check lead characters */
- for (i=0;i<mangle_prefix;i++) {
- if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
- return False;
- }
+ /* check first character */
+ if (! FLAG_CHECK(name[0], FLAG_ASCII)) {
+ return False;
}
/* check rest of hash */
if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
return False;
}
- for (i=mangle_prefix;i<6;i++) {
+ for (i=1;i<6;i++) {
if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) {
return False;
}
}
- M_DEBUG(10,("is_mangled_component %s (len %u) -> yes\n", name, (unsigned int)len));
+ DEBUG(10,("is_mangled %s -> yes\n", name));
return True;
}
@@ -266,16 +249,19 @@ static BOOL is_mangled(const char *name)
const char *p;
const char *s;
- M_DEBUG(10,("is_mangled %s ?\n", name));
+ DEBUG(10,("is_mangled %s ?\n", name));
for (s=name; (p=strchr(s, '/')); s=p+1) {
- if (is_mangled_component(s, PTR_DIFF(p, s))) {
+ char *component = strndup(s, PTR_DIFF(p, s));
+ if (is_mangled_component(component)) {
+ free(component);
return True;
}
+ free(component);
}
/* and the last part ... */
- return is_mangled_component(s,strlen(s));
+ return is_mangled_component(s);
}
@@ -304,8 +290,7 @@ static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
the result we need in this case. Using strlen_m would not
only be slower, it would be incorrect */
len = strlen(name);
- if (len > 12)
- return False;
+ if (len > 12) return False;
/* find the '.'. Note that once again we use the non-multibyte
function */
@@ -325,7 +310,7 @@ static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
prefix_len = PTR_DIFF(dot_p, name);
suffix_len = len - (prefix_len+1);
- if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) {
+ if (prefix_len > 8 || suffix_len > 3) {
return False;
}
@@ -368,19 +353,19 @@ static void mangle_reset(void)
static BOOL check_cache(char *name)
{
u32 hash, multiplier;
- unsigned int i;
+ int i;
const char *prefix;
char extension[4];
/* make sure that this is a mangled name from this cache */
if (!is_mangled(name)) {
- M_DEBUG(10,("check_cache: %s -> not mangled\n", name));
+ DEBUG(10,("check_cache: %s -> not mangled\n", name));
return False;
}
/* we need to extract the hash from the 8.3 name */
hash = base_reverse[(unsigned char)name[7]];
- for (multiplier=36, i=5;i>=mangle_prefix;i--) {
+ for (multiplier=36, i=5;i>=1;i--) {
u32 v = base_reverse[(unsigned char)name[i]];
hash += multiplier * v;
multiplier *= 36;
@@ -389,7 +374,7 @@ static BOOL check_cache(char *name)
/* now look in the prefix cache for that hash */
prefix = cache_lookup(hash);
if (!prefix) {
- M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
+ DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
return False;
}
@@ -402,10 +387,10 @@ static BOOL check_cache(char *name)
}
if (extension[0]) {
- M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
+ DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
slprintf(name, sizeof(fstring), "%s.%s", prefix, extension);
} else {
- M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
+ DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
fstrcpy(name, prefix);
}
@@ -427,7 +412,7 @@ static BOOL is_reserved_name(const char *name)
for (i=0; reserved_names[i]; i++) {
int len = strlen(reserved_names[i]);
/* note that we match on COM1 as well as COM1.foo */
- if (strnequal(name, reserved_names[i], len) &&
+ if (strncasecmp(name, reserved_names[i], len) == 0 &&
(name[len] == '.' || name[len] == 0)) {
return True;
}
@@ -449,23 +434,6 @@ static BOOL is_legal_name(const char *name)
size_t numdots = 0;
while (*name) {
- if (((unsigned int)name[0]) > 128 && (name[1] != 0)) {
- /* Possible start of mb character. */
- char mbc[2];
- /*
- * Note that if CH_UNIX is utf8 a string may be 3
- * bytes, but this is ok as mb utf8 characters don't
- * contain embedded ascii bytes. We are really checking
- * for mb UNIX asian characters like Japanese (SJIS) here.
- * JRA.
- */
- if (convert_string(CH_UNIX, CH_UCS2, name, 2, mbc, 2, False) == 2) {
- /* Was a good mb string. */
- name += 2;
- continue;
- }
- }
-
if (FLAG_CHECK(name[0], FLAG_ILLEGAL)) {
return False;
}
@@ -501,13 +469,13 @@ static BOOL is_legal_name(const char *name)
the name parameter must be able to hold 13 bytes
*/
-static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case)
+static void name_map(char *name, BOOL need83, BOOL cache83)
{
char *dot_p;
- char lead_chars[7];
+ char lead_char;
char extension[4];
- unsigned int extension_length, i;
- unsigned int prefix_len;
+ int extension_length, i;
+ int prefix_len;
u32 hash, v;
char new_name[13];
@@ -542,20 +510,15 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case)
if (i == 0 || i == 4) dot_p = NULL;
}
- /* the leading characters in the mangled name is taken from
- the first characters of the name, if they are ascii otherwise
- '_' is used
+ /* the leading character in the mangled name is taken from
+ the first character of the name, if it is ascii
+ otherwise '_' is used
*/
- for (i=0;i<mangle_prefix && name[i];i++) {
- lead_chars[i] = name[i];
- if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
- lead_chars[i] = '_';
- }
- lead_chars[i] = toupper(lead_chars[i]);
- }
- for (;i<mangle_prefix;i++) {
- lead_chars[i] = '_';
+ lead_char = name[0];
+ if (! FLAG_CHECK(lead_char, FLAG_ASCII)) {
+ lead_char = '_';
}
+ lead_char = toupper(lead_char);
/* the prefix is anything up to the first dot */
if (dot_p) {
@@ -580,12 +543,10 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case)
v = hash = mangle_hash(name, prefix_len);
/* now form the mangled name. */
- for (i=0;i<mangle_prefix;i++) {
- new_name[i] = lead_chars[i];
- }
+ new_name[0] = lead_char;
new_name[7] = base_forward(v % 36);
new_name[6] = '~';
- for (i=5; i>=mangle_prefix; i--) {
+ for (i=5; i>=1; i--) {
v = v / 36;
new_name[i] = base_forward(v % 36);
}
@@ -604,7 +565,7 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case)
cache_insert(name, prefix_len, hash);
}
- M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n",
+ DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n",
name, hash, new_name, cache83));
/* and overwrite the old name */
@@ -627,7 +588,7 @@ static void init_tables(void)
memset(char_flags, 0, sizeof(char_flags));
- for (i=1;i<128;i++) {
+ for (i=0;i<128;i++) {
if ((i >= '0' && i <= '9') ||
(i >= 'a' && i <= 'z') ||
(i >= 'A' && i <= 'Z')) {
@@ -689,15 +650,6 @@ static struct mangle_fns mangle_fns = {
/* return the methods for this mangling implementation */
struct mangle_fns *mangle_hash2_init(void)
{
- /* the mangle prefix can only be in the mange 1 to 6 */
- mangle_prefix = lp_mangle_prefix();
- if (mangle_prefix > 6) {
- mangle_prefix = 6;
- }
- if (mangle_prefix < 1) {
- mangle_prefix = 1;
- }
-
init_tables();
mangle_reset();
diff --git a/source/smbd/mangle_map.c b/source/smbd/mangle_map.c
index 9e798fd41b4..a7acd02b3cf 100644
--- a/source/smbd/mangle_map.c
+++ b/source/smbd/mangle_map.c
@@ -127,7 +127,7 @@ static char *map_filename( char *s, /* This is null terminated */
*/
static void mangled_map(char *s, const char *MangledMap)
{
- const char *start=MangledMap; /* Use this to search for mappings. */
+ const char *start=MangledMap; /* Use this to search for mappings. */
const char *end; /* Used to find the end of strings. */
char *match_string;
pstring new_string; /* Make up the result here. */
@@ -201,7 +201,7 @@ static void mangled_map(char *s, const char *MangledMap)
front end routine to the mangled map code
personally I think that the whole idea of "mangled map" is completely bogus
*/
-void mangle_map_filename(fstring fname, int snum)
+void mangle_map_filename(char *fname, int snum)
{
char *map;
diff --git a/source/smbd/message.c b/source/smbd/message.c
index f853a914753..d4e8871da94 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB messaging
Copyright (C) Andrew Tridgell 1992-1998
@@ -25,13 +26,12 @@
#include "includes.h"
-extern userdom_struct current_user_info;
-
/* look in server.c for some explanation of these variables */
+
static char msgbuf[1600];
-static int msgpos;
-static fstring msgfrom;
-static fstring msgto;
+static int msgpos=0;
+static fstring msgfrom="";
+static fstring msgto="";
/****************************************************************************
deliver the message
@@ -41,8 +41,6 @@ static void msg_deliver(void)
pstring name;
int i;
int fd;
- char *msg;
- int len;
if (! (*lp_msg_command()))
{
@@ -63,23 +61,17 @@ static void msg_deliver(void)
/*
* Incoming message is in DOS codepage format. Convert to UNIX.
*/
-
- if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **) &msg, True)) < 0 || !msg) {
- DEBUG(3,("Conversion failed, delivering message in DOS codepage format\n"));
- for (i = 0; i < msgpos;) {
- if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') {
- i++; continue;
- }
- write(fd, &msgbuf[i++], 1);
- }
- } else {
- for (i = 0; i < len;) {
- if (msg[i] == '\r' && i < (len-1) && msg[i+1] == '\n') {
- i++; continue;
- }
- write(fd, &msg[i++],1);
+
+ if(msgpos > 0) {
+ msgbuf[msgpos] = '\0'; /* Ensure null terminated. */
+ pstrcpy(msgbuf,dos_to_unix_static(msgbuf));
+ }
+
+ for (i=0;i<msgpos;) {
+ if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n') {
+ i++; continue;
}
- SAFE_FREE(msg);
+ write(fd,&msgbuf[i++],1);
}
close(fd);
@@ -94,7 +86,7 @@ static void msg_deliver(void)
pstrcpy(s,lp_msg_command());
pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,NULL,sizeof(alpha_msgfrom)));
pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,NULL,sizeof(alpha_msgto)));
- standard_sub_basic(current_user_info.smb_name, s, sizeof(s));
+ standard_sub_basic(s,sizeof(s));
pstring_sub(s,"%s",name);
smbrun(s,NULL);
}
@@ -111,10 +103,8 @@ int reply_sends(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int len;
- char *msg;
+ char *orig,*dest,*msg;
int outsize = 0;
- char *p;
-
START_PROFILE(SMBsends);
msgpos = 0;
@@ -126,11 +116,12 @@ int reply_sends(connection_struct *conn,
outsize = set_message(outbuf,0,0,True);
- p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_TERMINATE) + 1;
- p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_TERMINATE) + 1;
+ orig = smb_buf(inbuf)+1;
+ dest = skip_string(orig,1)+1;
+ msg = skip_string(dest,1)+1;
- msg = p;
+ fstrcpy(msgfrom,orig);
+ fstrcpy(msgto,dest);
len = SVAL(msg,0);
len = MIN(len,sizeof(msgbuf)-msgpos);
@@ -140,6 +131,8 @@ int reply_sends(connection_struct *conn,
memcpy(&msgbuf[msgpos],msg+2,len);
msgpos += len;
+ DEBUG( 3, ( "SMBsends (from %s to %s)\n", orig, dest ) );
+
msg_deliver();
END_PROFILE(SMBsends);
@@ -153,9 +146,8 @@ int reply_sends(connection_struct *conn,
int reply_sendstrt(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
+ char *orig,*dest;
int outsize = 0;
- char *p;
-
START_PROFILE(SMBsendstrt);
if (! (*lp_msg_command())) {
@@ -168,9 +160,11 @@ int reply_sendstrt(connection_struct *conn,
memset(msgbuf,'\0',sizeof(msgbuf));
msgpos = 0;
- p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_TERMINATE) + 1;
- p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_TERMINATE) + 1;
+ orig = smb_buf(inbuf)+1;
+ dest = skip_string(orig,1)+1;
+
+ fstrcpy(msgfrom,orig);
+ fstrcpy(msgto,dest);
DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", msgfrom, msgto ) );
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 1843c174bb5..34ca8220d82 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
negprot reply code
Copyright (C) Andrew Tridgell 1992-1998
@@ -22,36 +23,13 @@
extern int Protocol;
extern int max_recv;
-BOOL global_encrypted_passwords_negotiated = False;
-BOOL global_spnego_negotiated = False;
-struct auth_context *negprot_global_auth_context = NULL;
-
-static void get_challenge(char buff[8])
-{
- NTSTATUS nt_status;
- const uint8 *cryptkey;
-
- /* We might be called more than once, muliple negprots are premitted */
- if (negprot_global_auth_context) {
- DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
- (negprot_global_auth_context->free)(&negprot_global_auth_context);
- }
-
- DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
- DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
- smb_panic("cannot make_negprot_global_auth_context!\n");
- }
- DEBUG(10, ("get challenge: getting challenge\n"));
- cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
- memcpy(buff, cryptkey, 8);
-}
+extern fstring global_myworkgroup;
+extern fstring remote_machine;
/****************************************************************************
- Reply for the core protocol.
+reply for the core protocol
****************************************************************************/
-
-static int reply_corep(char *inbuf, char *outbuf)
+static int reply_corep(char *outbuf)
{
int outsize = set_message(outbuf,1,0,True);
@@ -60,279 +38,200 @@ static int reply_corep(char *inbuf, char *outbuf)
return outsize;
}
+
/****************************************************************************
- Reply for the coreplus protocol.
+reply for the coreplus protocol
****************************************************************************/
-
-static int reply_coreplus(char *inbuf, char *outbuf)
+static int reply_coreplus(char *outbuf)
{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int outsize = set_message(outbuf,13,0,True);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw and writebraw (possibly) */
- /* Reply, SMBlockread, SMBwritelock supported. */
- SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int outsize = set_message(outbuf,13,0,True);
+ SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
+ readbraw and writebraw (possibly) */
+ /* Reply, SMBlockread, SMBwritelock supported. */
+ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
+ SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
- Protocol = PROTOCOL_COREPLUS;
+ Protocol = PROTOCOL_COREPLUS;
- return outsize;
+ return outsize;
}
+
/****************************************************************************
- Reply for the lanman 1.0 protocol.
+reply for the lanman 1.0 protocol
****************************************************************************/
-
-static int reply_lanman1(char *inbuf, char *outbuf)
+static int reply_lanman1(char *outbuf)
{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- time_t t = time(NULL);
-
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
-
- if (lp_security()>=SEC_USER)
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
- secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
-
- set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
- SSVAL(outbuf,smb_vwv1,secword);
- /* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
- get_challenge(smb_buf(outbuf));
- SSVAL(outbuf,smb_vwv11, 8);
- }
-
- Protocol = PROTOCOL_LANMAN1;
-
- /* Reply, SMBlockread, SMBwritelock supported. */
- SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw writebraw (possibly) */
- SIVAL(outbuf,smb_vwv6,sys_getpid());
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
-
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+
+ if (lp_security()>=SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
+
+ set_message(outbuf,13,doencrypt?8:0,True);
+ SSVAL(outbuf,smb_vwv1,secword);
+ /* Create a token value and add it to the outgoing packet. */
+ if (doencrypt) {
+ generate_next_challenge(smb_buf(outbuf));
+ SSVAL(outbuf,smb_vwv11, 8);
+ }
+
+ Protocol = PROTOCOL_LANMAN1;
+
+ /* Reply, SMBlockread, SMBwritelock supported. */
+ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
+ SSVAL(outbuf,smb_vwv2,max_recv);
+ SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
+ SSVAL(outbuf,smb_vwv4,1);
+ SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
+ readbraw writebraw (possibly) */
+ SIVAL(outbuf,smb_vwv6,sys_getpid());
+ SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
+
+ put_dos_date(outbuf,smb_vwv8,t);
+
+ return (smb_len(outbuf)+4);
}
+
/****************************************************************************
- Reply for the lanman 2.0 protocol.
+reply for the lanman 2.0 protocol
****************************************************************************/
-
-static int reply_lanman2(char *inbuf, char *outbuf)
+static int reply_lanman2(char *outbuf)
{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- time_t t = time(NULL);
-
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
-
- if (lp_security()>=SEC_USER)
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
- secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
-
- set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
- SSVAL(outbuf,smb_vwv1,secword);
- SIVAL(outbuf,smb_vwv6,sys_getpid());
-
- /* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
- get_challenge(smb_buf(outbuf));
- SSVAL(outbuf,smb_vwv11, 8);
- }
-
- Protocol = PROTOCOL_LANMAN2;
-
- /* Reply, SMBlockread, SMBwritelock supported. */
- SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux());
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
+ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+ struct cli_state *cli = NULL;
+ char cryptkey[8];
+ char crypt_len = 0;
+
+ if (lp_security() == SEC_SERVER) {
+ cli = server_cryptkey();
+ }
+
+ if (cli) {
+ DEBUG(3,("using password server validation\n"));
+ doencrypt = ((cli->sec_mode & 2) != 0);
+ }
+
+ if (lp_security()>=SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
+
+ if (doencrypt) {
+ crypt_len = 8;
+ if (!cli) {
+ generate_next_challenge(cryptkey);
+ } else {
+ memcpy(cryptkey, cli->cryptkey, 8);
+ set_challenge(cli->cryptkey);
+ }
+ }
+
+ set_message(outbuf,13,crypt_len,True);
+ SSVAL(outbuf,smb_vwv1,secword);
+ SIVAL(outbuf,smb_vwv6,sys_getpid());
+ if (doencrypt) {
+ memcpy(smb_buf(outbuf), cryptkey, 8);
+ SSVAL(outbuf,smb_vwv11, 8);
+ }
+
+ Protocol = PROTOCOL_LANMAN2;
+
+ /* Reply, SMBlockread, SMBwritelock supported. */
+ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
+ SSVAL(outbuf,smb_vwv2,max_recv);
+ SSVAL(outbuf,smb_vwv3,lp_maxmux());
+ SSVAL(outbuf,smb_vwv4,1);
+ SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
+ SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
+ put_dos_date(outbuf,smb_vwv8,t);
+
+ return (smb_len(outbuf)+4);
}
+
/****************************************************************************
- Generate the spnego negprot reply blob. Return the number of bytes used.
+reply for the nt protocol
****************************************************************************/
-
-static int negprot_spnego(char *p)
+static int reply_nt1(char *outbuf)
{
- DATA_BLOB blob;
- nstring dos_name;
- fstring unix_name;
- uint8 guid[17];
- const char *OIDs_krb5[] = {OID_KERBEROS5,
- OID_KERBEROS5_OLD,
- OID_NTLMSSP,
- NULL};
- const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
- char *principal;
- int len;
-
- global_spnego_negotiated = True;
-
- ZERO_STRUCT(guid);
-
- safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
- strlower_m(unix_name);
- push_ascii_nstring(dos_name, unix_name);
- safe_strcpy((char *)guid, dos_name, sizeof(guid)-1);
-
-#ifdef DEVELOPER
- /* valgrind fixer... */
- {
- size_t sl = strlen(guid);
- if (sizeof(guid)-sl)
- memset(&guid[sl], '\0', sizeof(guid)-sl);
- }
+ /* dual names + lock_and_read + nt SMBs + remote API calls */
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_LEVEL_II_OPLOCKS|
+ (lp_nt_status_support() ? CAP_STATUS32 : 0)|
+ (lp_unix_extensions() ? CAP_UNIX : 0) |
+ (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
+ ((lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) ? CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS : 0) |
+ (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0);
+ int secword=0;
+ BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
+ int data_len;
+ struct cli_state *cli = NULL;
+ char cryptkey[8];
+ char crypt_len = 0;
+
+ if (lp_security() == SEC_SERVER) {
+ cli = server_cryptkey();
+ }
+
+ if (cli) {
+ DEBUG(3,("using password server validation\n"));
+ doencrypt = ((cli->sec_mode & 2) != 0);
+ }
+
+ if (doencrypt) {
+ crypt_len = 8;
+ if (!cli) {
+ generate_next_challenge(cryptkey);
+ } else {
+ memcpy(cryptkey, cli->cryptkey, 8);
+ set_challenge(cli->cryptkey);
+ }
+ }
+
+ if (lp_readraw() && lp_writeraw()) {
+ capabilities |= CAP_RAW_MODE;
+ }
+
+#ifdef WITH_MSDFS
+ if(lp_host_msdfs())
+ capabilities |= CAP_DFS;
#endif
-#if 0
- /* strangely enough, NT does not sent the single OID NTLMSSP when
- not a ADS member, it sends no OIDs at all
-
- we can't do this until we teach our sesssion setup parser to know
- about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)
- */
- if (lp_security() != SEC_ADS) {
- memcpy(p, guid, 16);
- return 16;
- }
-#endif
- if (lp_security() != SEC_ADS) {
- blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
- } else {
- asprintf(&principal, "%s$@%s", guid, lp_realm());
- blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal);
- free(principal);
- }
- memcpy(p, blob.data, blob.length);
- len = blob.length;
- data_blob_free(&blob);
- return len;
-}
-
-/****************************************************************************
- Reply for the nt protocol.
-****************************************************************************/
+ if (lp_security() >= SEC_USER) secword |= 1;
+ if (doencrypt) secword |= 2;
-static int reply_nt1(char *inbuf, char *outbuf)
-{
- /* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
- CAP_LEVEL_II_OPLOCKS;
+ /* decide where (if) to put the encryption challenge, and
+ follow it with the OEM'd domain name
+ */
+ data_len = crypt_len + strlen(global_myworkgroup) + 1;
- int secword=0;
- time_t t = time(NULL);
- char *p, *q;
- BOOL negotiate_spnego = False;
+ set_message(outbuf,17,data_len,True);
+ pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
+ SCVAL(outbuf,smb_vwv1,secword);
+ SSVALS(outbuf,smb_vwv16+1,crypt_len);
+ if (doencrypt)
+ memcpy(smb_buf(outbuf), cryptkey, 8);
- /* do spnego in user level security if the client
- supports it and we can do encrypted passwords */
-
- if (global_encrypted_passwords_negotiated &&
- (lp_security() != SEC_SHARE) &&
- lp_use_spnego() &&
- (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
- negotiate_spnego = True;
- capabilities |= CAP_EXTENDED_SECURITY;
- }
-
- capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
+ Protocol = PROTOCOL_NT1;
- if (lp_unix_extensions()) {
- capabilities |= CAP_UNIX;
- }
-
- if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
- capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
-
- if (SMB_OFF_T_BITS == 64)
- capabilities |= CAP_LARGE_FILES;
+ SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
+ SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
+ SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
+ SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
+ SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
+ SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
+ put_long_date(outbuf+smb_vwv11+1,t);
+ SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
+ SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
- if (lp_readraw() && lp_writeraw())
- capabilities |= CAP_RAW_MODE;
-
- if (lp_nt_status_support())
- capabilities |= CAP_STATUS32;
-
- if (lp_host_msdfs())
- capabilities |= CAP_DFS;
-
- if (lp_security() >= SEC_USER)
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
- secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
-
- if (lp_server_signing()) {
- if (lp_security() >= SEC_USER) {
- secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
- /* No raw mode with smb signing. */
- capabilities &= ~CAP_RAW_MODE;
- if (lp_server_signing() == Required)
- secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
- srv_set_signing_negotiated();
- } else {
- DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
- if (lp_server_signing() == Required) {
- exit_server("reply_nt1: smb signing required and share level security selected.");
- }
- }
- }
-
- set_message(outbuf,17,0,True);
-
- SCVAL(outbuf,smb_vwv1,secword);
-
- Protocol = PROTOCOL_NT1;
-
- SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
- SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
- SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
- SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
- SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
- SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
- put_long_date(outbuf+smb_vwv11+1,t);
- SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
-
- p = q = smb_buf(outbuf);
- if (!negotiate_spnego) {
- /* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
- /* note that we do not send a challenge at all if
- we are using plaintext */
- get_challenge(p);
- SSVALS(outbuf,smb_vwv16+1,8);
- p += 8;
- }
- p += srvstr_push(outbuf, p, lp_workgroup(), -1,
- STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
- DEBUG(3,("not using SPNEGO\n"));
- } else {
- int len = negprot_spnego(p);
-
- SSVALS(outbuf,smb_vwv16+1,len);
- p += len;
- DEBUG(3,("using SPNEGO\n"));
- }
-
- SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
- set_message_end(outbuf, p);
-
- return (smb_len(outbuf)+4);
+ return (smb_len(outbuf)+4);
}
/* these are the protocol lists used for auto architecture detection:
@@ -405,142 +304,138 @@ protocol [LANMAN2.1]
#define ARCH_ALL 0x3F
/* List of supported protocols, most desired first */
-static const struct {
- const char *proto_name;
- const char *short_name;
- int (*proto_reply_fn)(char *, char *);
- int protocol_level;
+static struct {
+ const char *proto_name;
+ const char *short_name;
+ int (*proto_reply_fn)(char *);
+ int protocol_level;
} supported_protocols[] = {
- {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
- {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
- {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
- {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
- {NULL,NULL,NULL,0},
+ {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
+ {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
+ {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
+ {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
+ {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
+ {NULL,NULL,NULL,0},
};
+
/****************************************************************************
- Reply to a negprot.
+ reply to a negprot
****************************************************************************/
-
int reply_negprot(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size,
int dum_buffsize)
{
- int outsize = set_message(outbuf,1,0,True);
- int Index=0;
- int choice= -1;
- int protocol;
- char *p;
- int bcc = SVAL(smb_buf(inbuf),-2);
- int arch = ARCH_ALL;
-
- static BOOL done_negprot = False;
-
- START_PROFILE(SMBnegprot);
-
- if (done_negprot) {
- END_PROFILE(SMBnegprot);
- exit_server("multiple negprot's are not permitted");
- }
- done_negprot = True;
-
- p = smb_buf(inbuf)+1;
- while (p < (smb_buf(inbuf) + bcc)) {
- Index++;
- DEBUG(3,("Requested protocol [%s]\n",p));
- if (strcsequal(p,"Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
- else if (strcsequal(p,"DOS LM1.2X002"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"DOS LANMAN2.1"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
- else if (strcsequal(p,"LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
- else if (strcsequal(p,"LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
- else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
- arch &= ARCH_WINNT;
- else if (strcsequal(p,"XENIX CORE"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"Samba")) {
- arch = ARCH_SAMBA;
- break;
- }
+ int outsize = set_message(outbuf,1,0,True);
+ int Index=0;
+ int choice= -1;
+ int protocol;
+ char *p;
+ int bcc = SVAL(smb_buf(inbuf),-2);
+ int arch = ARCH_ALL;
+ START_PROFILE(SMBnegprot);
+
+ p = smb_buf(inbuf)+1;
+ while (p < (smb_buf(inbuf) + bcc))
+ {
+ Index++;
+ DEBUG(3,("Requested protocol [%s]\n",p));
+ if (strcsequal(p,"Windows for Workgroups 3.1a"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
+ else if (strcsequal(p,"DOS LM1.2X002"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 );
+ else if (strcsequal(p,"DOS LANMAN2.1"))
+ arch &= ( ARCH_WFWG | ARCH_WIN95 );
+ else if (strcsequal(p,"NT LM 0.12"))
+ arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
+ else if (strcsequal(p,"LANMAN2.1"))
+ arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
+ else if (strcsequal(p,"LM1.2X002"))
+ arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
+ else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
+ arch &= ARCH_WINNT;
+ else if (strcsequal(p,"XENIX CORE"))
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
+ else if (strcsequal(p,"Samba")) {
+ arch = ARCH_SAMBA;
+ break;
+ }
- p += strlen(p) + 2;
- }
+ p += strlen(p) + 2;
+ }
- switch ( arch ) {
- case ARCH_SAMBA:
- set_remote_arch(RA_SAMBA);
- break;
- case ARCH_WFWG:
- set_remote_arch(RA_WFWG);
- break;
- case ARCH_WIN95:
- set_remote_arch(RA_WIN95);
- break;
- case ARCH_WINNT:
- if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
- set_remote_arch(RA_WIN2K);
- else
- set_remote_arch(RA_WINNT);
- break;
- case ARCH_WIN2K:
- set_remote_arch(RA_WIN2K);
- break;
- case ARCH_OS2:
- set_remote_arch(RA_OS2);
- break;
- default:
- set_remote_arch(RA_UNKNOWN);
- break;
- }
+ switch ( arch ) {
+ case ARCH_SAMBA:
+ set_remote_arch(RA_SAMBA);
+ break;
+ case ARCH_WFWG:
+ set_remote_arch(RA_WFWG);
+ break;
+ case ARCH_WIN95:
+ set_remote_arch(RA_WIN95);
+ break;
+ case ARCH_WINNT:
+ if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
+ set_remote_arch(RA_WIN2K);
+ else
+ set_remote_arch(RA_WINNT);
+ break;
+ case ARCH_WIN2K:
+ set_remote_arch(RA_WIN2K);
+ break;
+ case ARCH_OS2:
+ set_remote_arch(RA_OS2);
+ break;
+ default:
+ set_remote_arch(RA_UNKNOWN);
+ break;
+ }
- /* possibly reload - change of architecture */
- reload_services(True);
+ /* possibly reload - change of architecture */
+ reload_services(True);
- /* Check for protocols, most desirable first */
- for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
- p = smb_buf(inbuf)+1;
- Index = 0;
- if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
- (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
- while (p < (smb_buf(inbuf) + bcc)) {
- if (strequal(p,supported_protocols[protocol].proto_name))
- choice = Index;
- Index++;
- p += strlen(p) + 2;
- }
- if(choice != -1)
- break;
- }
+ /* a special case to stop password server loops */
+ if (Index == 1 && strequal(remote_machine,myhostname()) &&
+ (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
+ exit_server("Password server loop!");
- SSVAL(outbuf,smb_vwv0,choice);
- if(choice != -1) {
- extern fstring remote_proto;
- fstrcpy(remote_proto,supported_protocols[protocol].short_name);
- reload_services(True);
- outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
- DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
- } else {
- DEBUG(0,("No protocol supported !\n"));
- }
- SSVAL(outbuf,smb_vwv0,choice);
+ /* Check for protocols, most desirable first */
+ for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
+ {
+ p = smb_buf(inbuf)+1;
+ Index = 0;
+ if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
+ (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
+ while (p < (smb_buf(inbuf) + bcc))
+ {
+ if (strequal(p,supported_protocols[protocol].proto_name))
+ choice = Index;
+ Index++;
+ p += strlen(p) + 2;
+ }
+ if(choice != -1)
+ break;
+ }
- DEBUG( 5, ( "negprot index=%d\n", choice ) );
-
- if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
- exit_server("SMB signing is required and client negotiated a downlevel protocol");
- }
+ SSVAL(outbuf,smb_vwv0,choice);
+ if(choice != -1) {
+ extern fstring remote_proto;
+ fstrcpy(remote_proto,supported_protocols[protocol].short_name);
+ reload_services(True);
+ outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
+ DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
+ }
+ else {
+ DEBUG(0,("No protocol supported !\n"));
+ }
+ SSVAL(outbuf,smb_vwv0,choice);
+
+ DEBUG( 5, ( "negprot index=%d\n", choice ) );
- END_PROFILE(SMBnegprot);
- return(outsize);
+ END_PROFILE(SMBnegprot);
+ return(outsize);
}
diff --git a/source/smbd/noquotas.c b/source/smbd/noquotas.c
index 85caef57e1a..a6951d97fc5 100644
--- a/source/smbd/noquotas.c
+++ b/source/smbd/noquotas.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
No support for quotas :-).
Copyright (C) Andrew Tridgell 1992-1998
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index 9adf827c794..52df3558aa7 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
change notify handling
Copyright (C) Andrew Tridgell 2000
Copyright (C) Jeremy Allison 1994-1998
@@ -44,7 +45,6 @@ static struct change_notify *change_notify_list;
/****************************************************************************
Setup the common parts of the return packet and send it.
*****************************************************************************/
-
static void change_notify_reply_packet(char *inbuf, NTSTATUS error_code)
{
char outbuf[smb_size+38];
@@ -179,7 +179,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
struct change_notify *cnbp;
if((cnbp = (struct change_notify *)malloc(sizeof(*cnbp))) == NULL) {
- DEBUG(0,("change_notify_set: malloc fail !\n" ));
+ DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
return -1;
}
@@ -198,9 +198,6 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
DLIST_ADD(change_notify_list, cnbp);
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
-
return True;
}
@@ -211,8 +208,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
BOOL init_change_notify(void)
{
#if HAVE_KERNEL_CHANGE_NOTIFY
- if (lp_kernel_change_notify())
- cnotify = kernel_notify_init();
+ cnotify = kernel_notify_init();
#endif
if (!cnotify) cnotify = hash_notify_init();
diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c
index ec414454f9e..90eb88ac814 100644
--- a/source/smbd/notify_hash.c
+++ b/source/smbd/notify_hash.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
change notify handling - hash based implementation
Copyright (C) Jeremy Allison 1994-1998
Copyright (C) Andrew Tridgell 2000
@@ -41,14 +42,14 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
SMB_STRUCT_STAT st;
pstring full_name;
char *p;
- const char *fname;
+ char *fname;
size_t remaining_len;
size_t fullname_len;
void *dp;
ZERO_STRUCTP(data);
- if(SMB_VFS_STAT(conn,path, &st) == -1)
+ if(vfs_stat(conn,path, &st) == -1)
return False;
data->modify_time = st.st_mtime;
@@ -100,7 +101,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
/*
* Do the stat - but ignore errors.
*/
- SMB_VFS_STAT(conn,full_name, &st);
+ vfs_stat(conn,full_name, &st);
/*
* Always sum the times.
@@ -115,7 +116,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
if (flags & (FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_FILE)) {
int i;
unsigned char tmp_hash[16];
- mdfour(tmp_hash, (const unsigned char *)fname, strlen(fname));
+ mdfour(tmp_hash, (unsigned char *)fname, strlen(fname));
for (i=0;i<16;i++)
data->name_hash[i] ^= tmp_hash[i];
}
@@ -125,7 +126,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
*/
if (flags & (FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SECURITY))
- data->mode_sum += st.st_mode;
+ data->mode_sum = st.st_mode;
}
CloseDir(dp);
@@ -194,7 +195,7 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,
static void hash_remove_notify(void *datap)
{
- free(datap);
+ SAFE_FREE(datap);
}
/****************************************************************************
diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c
index 8fcc18a09f9..435b601df09 100644
--- a/source/smbd/notify_kernel.c
+++ b/source/smbd/notify_kernel.c
@@ -101,7 +101,7 @@ static BOOL kernel_check_notify(connection_struct *conn, uint16 vuid, char *path
close((int)fd_pending_array[i]);
fd_pending_array[i] = (SIG_ATOMIC_T)-1;
if (signals_received - i - 1) {
- memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
+ memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
}
data->directory_handle = -1;
@@ -129,7 +129,7 @@ static void kernel_remove_notify(void *datap)
if (fd == (int)fd_pending_array[i]) {
fd_pending_array[i] = (SIG_ATOMIC_T)-1;
if (signals_received - i - 1) {
- memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
+ memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
}
data->directory_handle = -1;
@@ -154,7 +154,7 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32
int fd;
unsigned long kernel_flags;
- fd = sys_open(path,O_RDONLY, 0);
+ fd = sys_open(dos_to_unix_static(path),O_RDONLY, 0);
if (fd == -1) {
DEBUG(3,("Failed to open directory %s for change notify\n", path));
@@ -215,16 +215,13 @@ struct cnotify_fns *kernel_notify_init(void)
static struct cnotify_fns cnotify;
struct sigaction act;
- ZERO_STRUCT(act);
-
- act.sa_handler = NULL;
- act.sa_sigaction = signal_handler;
- act.sa_flags = SA_SIGINFO;
- sigemptyset( &act.sa_mask );
- if (sigaction(RT_SIGNAL_NOTIFY, &act, NULL) != 0) {
+ act.sa_handler = NULL;
+ act.sa_sigaction = signal_handler;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(RT_SIGNAL_NOTIFY, &act, NULL) != 0) {
DEBUG(0,("Failed to setup RT_SIGNAL_NOTIFY handler\n"));
return NULL;
- }
+ }
if (!kernel_notify_available())
return NULL;
@@ -234,9 +231,6 @@ struct cnotify_fns *kernel_notify_init(void)
cnotify.remove_notify = kernel_remove_notify;
cnotify.select_time = -1;
- /* the signal can start off blocked due to a bug in bash */
- BlockSignals(False, RT_SIGNAL_NOTIFY);
-
return &cnotify;
}
diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c
deleted file mode 100644
index 555f32d773f..00000000000
--- a/source/smbd/ntquotas.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- NT QUOTA suppport
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-static SMB_BIG_UINT limit_nt2unix(SMB_BIG_UINT in, SMB_BIG_UINT bsize)
-{
- SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
-
- ret = (SMB_BIG_UINT)(in/bsize);
- if (in>0 && ret==0) {
- /* we have to make sure that a overflow didn't set NO_LIMIT */
- ret = (SMB_BIG_UINT)1;
- }
-
- if (in == SMB_NTQUOTAS_NO_LIMIT)
- ret = SMB_QUOTAS_NO_LIMIT;
- else if (in == SMB_NTQUOTAS_NO_SPACE)
- ret = SMB_QUOTAS_NO_SPACE;
- else if (in == SMB_NTQUOTAS_NO_ENTRY)
- ret = SMB_QUOTAS_NO_LIMIT;
-
- return ret;
-}
-
-static SMB_BIG_UINT limit_unix2nt(SMB_BIG_UINT in, SMB_BIG_UINT bsize)
-{
- SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
-
- ret = (SMB_BIG_UINT)(in*bsize);
-
- if (ret < in) {
- /* we overflow */
- ret = SMB_NTQUOTAS_NO_LIMIT;
- }
-
- if (in == SMB_QUOTAS_NO_LIMIT)
- ret = SMB_NTQUOTAS_NO_LIMIT;
-
- return ret;
-}
-
-static SMB_BIG_UINT limit_blk2inodes(SMB_BIG_UINT in)
-{
- SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
-
- ret = (SMB_BIG_UINT)(in/2);
-
- if (ret == 0 && in != 0)
- ret = (SMB_BIG_UINT)1;
-
- return ret;
-}
-
-int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
-{
- int ret;
- SMB_DISK_QUOTA D;
- unid_t id;
-
- ZERO_STRUCT(D);
-
- if (!fsp||!fsp->conn||!qt)
- return (-1);
-
- ZERO_STRUCT(*qt);
-
- id.uid = -1;
-
- if (psid && !NT_STATUS_IS_OK(sid_to_uid(psid, &id.uid))) {
- DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
- sid_string_static(psid)));
- }
-
- ret = SMB_VFS_GET_QUOTA(fsp->conn, qtype, id, &D);
-
- if (psid)
- qt->sid = *psid;
-
- if (ret!=0) {
- return ret;
- }
-
- qt->usedspace = (SMB_BIG_UINT)D.curblocks*D.bsize;
- qt->softlim = limit_unix2nt(D.softlimit, D.bsize);
- qt->hardlim = limit_unix2nt(D.hardlimit, D.bsize);
- qt->qflags = D.qflags;
-
-
- return 0;
-}
-
-int vfs_set_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
-{
- int ret;
- SMB_DISK_QUOTA D;
- unid_t id;
- ZERO_STRUCT(D);
-
- if (!fsp||!fsp->conn||!qt)
- return (-1);
-
- id.uid = -1;
-
- D.bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
- D.softlimit = limit_nt2unix(qt->softlim,D.bsize);
- D.hardlimit = limit_nt2unix(qt->hardlim,D.bsize);
- D.qflags = qt->qflags;
-
- D.isoftlimit = limit_blk2inodes(D.softlimit);
- D.ihardlimit = limit_blk2inodes(D.hardlimit);
-
- if (psid && !NT_STATUS_IS_OK(sid_to_uid(psid, &id.uid))) {
- DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
- sid_string_static(psid)));
- }
-
- ret = SMB_VFS_SET_QUOTA(fsp->conn, qtype, id, &D);
-
- return ret;
-}
-
-static BOOL allready_in_quota_list(SMB_NTQUOTA_LIST *qt_list, uid_t uid)
-{
- SMB_NTQUOTA_LIST *tmp_list = NULL;
-
- if (!qt_list)
- return False;
-
- for (tmp_list=qt_list;tmp_list!=NULL;tmp_list=tmp_list->next) {
- if (tmp_list->uid == uid) {
- return True;
- }
- }
-
- return False;
-}
-
-int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
-{
- struct passwd *usr;
- TALLOC_CTX *mem_ctx = NULL;
-
- if (!fsp||!fsp->conn||!qt_list)
- return (-1);
-
- *qt_list = NULL;
-
- if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
- DEBUG(0,("talloc_init() failed\n"));
- return (-1);
- }
-
- sys_setpwent();
- while ((usr = sys_getpwent()) != NULL) {
- SMB_NTQUOTA_STRUCT tmp_qt;
- SMB_NTQUOTA_LIST *tmp_list_ent;
- DOM_SID sid;
-
- ZERO_STRUCT(tmp_qt);
-
- if (allready_in_quota_list((*qt_list),usr->pw_uid)) {
- DEBUG(5,("record for uid[%ld] allready in the list\n",(long)usr->pw_uid));
- continue;
- }
-
- if (!NT_STATUS_IS_OK(uid_to_sid(&sid, usr->pw_uid))) {
- DEBUG(0,("uid_to_sid failed for %ld\n",(long)usr->pw_uid));
- continue;
- }
-
- if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) {
- DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
- sid_string_static(&sid),fsp->conn->connectpath));
- continue;
- }
-
- DEBUG(15,("quota entry for id[%s] path[%s]\n",
- sid_string_static(&sid),fsp->conn->connectpath));
-
- if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- *qt_list = NULL;
- talloc_destroy(mem_ctx);
- return (-1);
- }
-
- if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- *qt_list = NULL;
- talloc_destroy(mem_ctx);
- return (-1);
- }
-
- tmp_list_ent->uid = usr->pw_uid;
- memcpy(tmp_list_ent->quotas,&tmp_qt,sizeof(tmp_qt));
- tmp_list_ent->mem_ctx = mem_ctx;
-
- DLIST_ADD((*qt_list),tmp_list_ent);
-
- }
- sys_endpwent();
-
- return 0;
-}
-
-void *init_quota_handle(TALLOC_CTX *mem_ctx)
-{
- SMB_NTQUOTA_HANDLE *qt_handle;
-
- if (!mem_ctx)
- return False;
-
- qt_handle = (SMB_NTQUOTA_HANDLE *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_HANDLE));
- if (qt_handle==NULL) {
- DEBUG(0,("talloc_zero() failed\n"));
- return NULL;
- }
-
- return (void *)qt_handle;
-}
-
-void destroy_quota_handle(void **pqt_handle)
-{
- SMB_NTQUOTA_HANDLE *qt_handle = NULL;
- if (!pqt_handle||!(*pqt_handle))
- return;
-
- qt_handle = (*pqt_handle);
-
-
- if (qt_handle->quota_list)
- free_ntquota_list(&qt_handle->quota_list);
-
- qt_handle->quota_list = NULL;
- qt_handle->tmp_list = NULL;
- qt_handle = NULL;
-
- return;
-}
-
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index dbb74392a29..e8255284811 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB NT transaction handling
- Copyright (C) Jeremy Allison 1994-1998
- Copyright (C) Stefan (metze) Metzmacher 2003
+ Copyright (C) Jeremy Allison 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,53 +24,37 @@
extern int Protocol;
extern int smb_read_error;
extern int global_oplock_break;
-extern struct current_user current_user;
+extern BOOL case_sensitive;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
static const char *known_nt_pipes[] = {
- "\\LANMAN",
- "\\srvsvc",
- "\\samr",
- "\\wkssvc",
- "\\NETLOGON",
- "\\ntlsa",
- "\\ntsvcs",
- "\\lsass",
- "\\lsarpc",
- "\\winreg",
- "\\spoolss",
- "\\netdfs",
- "\\rpcecho",
- "\\epmapper",
- NULL
+ "\\LANMAN",
+ "\\srvsvc",
+ "\\samr",
+ "\\wkssvc",
+ "\\NETLOGON",
+ "\\ntlsa",
+ "\\ntsvcs",
+ "\\lsass",
+ "\\lsarpc",
+ "\\winreg",
+ "\\spoolss",
+#ifdef WITH_MSDFS
+ "\\netdfs",
+#endif
+ NULL
};
/* Map generic permissions to file object specific permissions */
struct generic_mapping file_generic_mapping = {
- FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_GENERIC_ALL
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_GENERIC_ALL
};
-static char *nttrans_realloc(char **ptr, size_t size)
-{
- char *tptr = NULL;
- if (ptr==NULL)
- smb_panic("nttrans_realloc() called with NULL ptr\n");
-
- tptr = Realloc_zero(*ptr, size);
- if(tptr == NULL) {
- *ptr = NULL;
- return NULL;
- }
-
- *ptr = tptr;
-
- return tptr;
-}
-
-
/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
@@ -81,183 +65,257 @@ static char *nttrans_realloc(char **ptr, size_t size)
static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
int paramsize, char *pdata, int datasize)
{
- extern int max_send;
- int data_to_send = datasize;
- int params_to_send = paramsize;
- int useable_space;
- char *pp = params;
- char *pd = pdata;
- int params_sent_thistime, data_sent_thistime, total_sent_thistime;
- int alignment_offset = 3;
- int data_alignment_offset = 0;
+ extern int max_send;
+ int data_to_send = datasize;
+ int params_to_send = paramsize;
+ int useable_space;
+ char *pp = params;
+ char *pd = pdata;
+ int params_sent_thistime, data_sent_thistime, total_sent_thistime;
+ int alignment_offset = 3;
+ int data_alignment_offset = 0;
+
+ /*
+ * Initially set the wcnt area to be 18 - this is true for all
+ * transNT replies.
+ */
+
+ set_message(outbuf,18,0,True);
+
+ if(NT_STATUS_V(nt_error)) {
+ ERROR_NT(nt_error);
+ }
+
+ /*
+ * If there genuinely are no parameters or data to send just send
+ * the empty packet.
+ */
+
+ if(params_to_send == 0 && data_to_send == 0) {
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_nt_replies: send_smb failed.");
+ return 0;
+ }
+
+ /*
+ * When sending params and data ensure that both are nicely aligned.
+ * Only do this alignment when there is also data to send - else
+ * can cause NT redirector problems.
+ */
+
+ if (((params_to_send % 4) != 0) && (data_to_send != 0))
+ data_alignment_offset = 4 - (params_to_send % 4);
+
+ /*
+ * Space is bufsize minus Netbios over TCP header minus SMB header.
+ * The alignment_offset is to align the param bytes on a four byte
+ * boundary (2 bytes for data len, one byte pad).
+ * NT needs this to work correctly.
+ */
+
+ useable_space = bufsize - ((smb_buf(outbuf)+
+ alignment_offset+data_alignment_offset) -
+ outbuf);
+
+ /*
+ * useable_space can never be more than max_send minus the
+ * alignment offset.
+ */
+
+ useable_space = MIN(useable_space,
+ max_send - (alignment_offset+data_alignment_offset));
+
+
+ while (params_to_send || data_to_send) {
+
+ /*
+ * Calculate whether we will totally or partially fill this packet.
+ */
+
+ total_sent_thistime = params_to_send + data_to_send +
+ alignment_offset + data_alignment_offset;
+
+ /*
+ * We can never send more than useable_space.
+ */
+
+ total_sent_thistime = MIN(total_sent_thistime, useable_space);
+
+ set_message(outbuf, 18, total_sent_thistime, True);
+
+ /*
+ * Set total params and data to be sent.
+ */
+
+ SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
+ SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
+
+ /*
+ * Calculate how many parameters and data we can fit into
+ * this packet. Parameters get precedence.
+ */
+
+ params_sent_thistime = MIN(params_to_send,useable_space);
+ data_sent_thistime = useable_space - params_sent_thistime;
+ data_sent_thistime = MIN(data_sent_thistime,data_to_send);
+
+ SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
+
+ if(params_sent_thistime == 0) {
+ SIVAL(outbuf,smb_ntr_ParameterOffset,0);
+ SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
+ } else {
+ /*
+ * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
+ * parameter bytes, however the first 4 bytes of outbuf are
+ * the Netbios over TCP header. Thus use smb_base() to subtract
+ * them from the calculation.
+ */
+
+ SIVAL(outbuf,smb_ntr_ParameterOffset,
+ ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
+ /*
+ * Absolute displacement of param bytes sent in this packet.
+ */
+
+ SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
+ }
+
+ /*
+ * Deal with the data portion.
+ */
+
+ SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
+
+ if(data_sent_thistime == 0) {
+ SIVAL(outbuf,smb_ntr_DataOffset,0);
+ SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
+ } else {
+ /*
+ * The offset of the data bytes is the offset of the
+ * parameter bytes plus the number of parameters being sent this time.
+ */
+
+ SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
+ smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
+ SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
+ }
- /*
- * Initially set the wcnt area to be 18 - this is true for all
- * transNT replies.
- */
-
- set_message(outbuf,18,0,True);
+ /*
+ * Copy the param bytes into the packet.
+ */
- if (NT_STATUS_V(nt_error))
- ERROR_NT(nt_error);
+ if(params_sent_thistime)
+ memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+
+ /*
+ * Copy in the data bytes
+ */
- /*
- * If there genuinely are no parameters or data to send just send
- * the empty packet.
- */
-
- if(params_to_send == 0 && data_to_send == 0) {
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.");
- return 0;
- }
+ if(data_sent_thistime)
+ memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
+ data_alignment_offset,pd,data_sent_thistime);
+
+ DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
+ params_sent_thistime, data_sent_thistime, useable_space));
+ DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
+ params_to_send, data_to_send, paramsize, datasize));
+
+ /* Send the packet */
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_nt_replies: send_smb failed.");
+
+ pp += params_sent_thistime;
+ pd += data_sent_thistime;
+
+ params_to_send -= params_sent_thistime;
+ data_to_send -= data_sent_thistime;
- /*
- * When sending params and data ensure that both are nicely aligned.
- * Only do this alignment when there is also data to send - else
- * can cause NT redirector problems.
- */
+ /*
+ * Sanity check
+ */
- if (((params_to_send % 4) != 0) && (data_to_send != 0))
- data_alignment_offset = 4 - (params_to_send % 4);
+ if(params_to_send < 0 || data_to_send < 0) {
+ DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
+ params_to_send, data_to_send));
+ return -1;
+ }
+ }
- /*
- * Space is bufsize minus Netbios over TCP header minus SMB header.
- * The alignment_offset is to align the param bytes on a four byte
- * boundary (2 bytes for data len, one byte pad).
- * NT needs this to work correctly.
- */
+ return 0;
+}
- useable_space = bufsize - ((smb_buf(outbuf)+
- alignment_offset+data_alignment_offset) -
- outbuf);
+/****************************************************************************
+ (Hopefully) temporary call to fix bugs in NT5.0beta2. This OS sends unicode
+ strings in NT calls AND DOESN'T SET THE UNICODE BIT !!!!!!!
+****************************************************************************/
+static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
+{
/*
- * useable_space can never be more than max_send minus the
- * alignment offset.
+ * We need various heuristics here to detect a unicode string... JRA.
*/
- useable_space = MIN(useable_space,
- max_send - (alignment_offset+data_alignment_offset));
-
-
- while (params_to_send || data_to_send) {
+ DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
+ if(data_len - fname_len > 1) {
/*
- * Calculate whether we will totally or partially fill this packet.
- */
-
- total_sent_thistime = params_to_send + data_to_send +
- alignment_offset + data_alignment_offset;
-
- /*
- * We can never send more than useable_space.
- */
-
- total_sent_thistime = MIN(total_sent_thistime, useable_space);
-
- set_message(outbuf, 18, total_sent_thistime, True);
-
- /*
- * Set total params and data to be sent.
- */
-
- SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
- SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
-
- /*
- * Calculate how many parameters and data we can fit into
- * this packet. Parameters get precedence.
- */
-
- params_sent_thistime = MIN(params_to_send,useable_space);
- data_sent_thistime = useable_space - params_sent_thistime;
- data_sent_thistime = MIN(data_sent_thistime,data_to_send);
-
- SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
-
- if(params_sent_thistime == 0) {
- SIVAL(outbuf,smb_ntr_ParameterOffset,0);
- SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
- } else {
- /*
- * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
- * parameter bytes, however the first 4 bytes of outbuf are
- * the Netbios over TCP header. Thus use smb_base() to subtract
- * them from the calculation.
- */
-
- SIVAL(outbuf,smb_ntr_ParameterOffset,
- ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
- /*
- * Absolute displacement of param bytes sent in this packet.
- */
-
- SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
- }
-
- /*
- * Deal with the data portion.
+ * NT 5.0 Beta 2 has kindly sent us a UNICODE string
+ * without bothering to set the unicode bit. How kind.
+ *
+ * Firstly - ensure that the data offset is aligned
+ * on a 2 byte boundary - add one if not.
*/
+ fname_len = fname_len/2;
+ if(data_offset & 1)
+ data_offset++;
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+ } else {
+ StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
+ }
+}
- SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
-
- if(data_sent_thistime == 0) {
- SIVAL(outbuf,smb_ntr_DataOffset,0);
- SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
- } else {
- /*
- * The offset of the data bytes is the offset of the
- * parameter bytes plus the number of parameters being sent this time.
- */
-
- SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
- smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
- SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
- }
+/****************************************************************************
+ Fix bugs in Win2000 final release. In trans calls this OS sends unicode
+ strings AND DOESN'T SET THE UNICODE BIT !!!!!!!
+****************************************************************************/
- /*
- * Copy the param bytes into the packet.
- */
+static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
+{
+ DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
- if(params_sent_thistime)
- memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+ /*
+ * Win2K sends a unicode filename plus one extra alingment byte.
+ * WinNT4.x send an ascii string with multiple garbage bytes on
+ * the end here.
+ */
- /*
- * Copy in the data bytes
- */
+ /*
+ * We need various heuristics here to detect a unicode string... JRA.
+ */
- if(data_sent_thistime)
- memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
- data_alignment_offset,pd,data_sent_thistime);
-
- DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
- params_sent_thistime, data_sent_thistime, useable_space));
- DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
- params_to_send, data_to_send, paramsize, datasize));
-
- /* Send the packet */
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.");
-
- pp += params_sent_thistime;
- pd += data_sent_thistime;
-
- params_to_send -= params_sent_thistime;
- data_to_send -= data_sent_thistime;
+ if( ((fname_len % 2) == 0) &&
+ (
+ (data_len == 1) ||
+ (inbuf[data_offset] == '\0') ||
+ ((fname_len > 1) && (inbuf[data_offset+1] == '\\') && (inbuf[data_offset+2] == '\0'))
+ )) {
/*
- * Sanity check
+ * Ensure that the data offset is aligned
+ * on a 2 byte boundary - add one if not.
*/
-
- if(params_to_send < 0 || data_to_send < 0) {
- DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
- params_to_send, data_to_send));
- return -1;
- }
- }
-
- return 0;
+ fname_len = fname_len/2;
+ if(data_offset & 1)
+ data_offset++;
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+ } else {
+ StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
+ }
}
/****************************************************************************
@@ -272,33 +330,33 @@ static BOOL saved_short_case_preserve;
Save case semantics.
****************************************************************************/
-static void set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)
+static void set_posix_case_semantics(uint32 file_attributes)
{
if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
return;
- saved_case_sensitive = conn->case_sensitive;
- saved_case_preserve = conn->case_preserve;
- saved_short_case_preserve = conn->short_case_preserve;
+ saved_case_sensitive = case_sensitive;
+ saved_case_preserve = case_preserve;
+ saved_short_case_preserve = short_case_preserve;
/* Set to POSIX. */
- conn->case_sensitive = True;
- conn->case_preserve = True;
- conn->short_case_preserve = True;
+ case_sensitive = True;
+ case_preserve = True;
+ short_case_preserve = True;
}
/****************************************************************************
Restore case semantics.
****************************************************************************/
-static void restore_case_semantics(connection_struct *conn, uint32 file_attributes)
+static void restore_case_semantics(uint32 file_attributes)
{
if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
return;
- conn->case_sensitive = saved_case_sensitive;
- conn->case_preserve = saved_case_preserve;
- conn->short_case_preserve = saved_short_case_preserve;
+ case_sensitive = saved_case_sensitive;
+ case_preserve = saved_case_preserve;
+ short_case_preserve = saved_short_case_preserve;
}
/****************************************************************************
@@ -338,7 +396,7 @@ static int map_create_disposition( uint32 create_disposition)
}
DEBUG(10,("map_create_disposition: Mapped create_disposition 0x%lx to 0x%x\n",
- (unsigned long)create_disposition, ret ));
+ (unsigned long)create_disposition, ret ));
return ret;
}
@@ -351,7 +409,6 @@ static int map_share_mode( char *fname, uint32 create_options,
uint32 *desired_access, uint32 share_access, uint32 file_attributes)
{
int smb_open_mode = -1;
- uint32 original_desired_access = *desired_access;
/*
* Convert GENERIC bits to specific bits.
@@ -392,9 +449,9 @@ static int map_share_mode( char *fname, uint32 create_options,
if (smb_open_mode == -1) {
if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS|
- FILE_EXECUTE|FILE_READ_ATTRIBUTES|
- FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
- FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) {
+ FILE_EXECUTE|FILE_READ_ATTRIBUTES|
+ FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
+ FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) {
smb_open_mode = DOS_OPEN_RDONLY;
} else if(*desired_access == 0) {
@@ -423,10 +480,6 @@ static int map_share_mode( char *fname, uint32 create_options,
DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
}
- if(*desired_access & DELETE_ACCESS) {
- DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
- }
-
/*
* We need to store the intent to open for Delete. This
* is what determines if a delete on close flag can be set.
@@ -434,19 +487,11 @@ static int map_share_mode( char *fname, uint32 create_options,
* is the only practical way. JRA.
*/
- if (create_options & FILE_DELETE_ON_CLOSE) {
- /*
- * W2K3 bug compatibility mode... To set delete on close
- * the redirector must have *specifically* set DELETE_ACCESS
- * in the desired_access field. Just asking for GENERIC_ALL won't do. JRA.
- */
+ if(*desired_access & DELETE_ACCESS) {
+ DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
+ }
- if (!(original_desired_access & DELETE_ACCESS)) {
- DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \
-DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n",
- fname, (unsigned long)*desired_access));
- return -1;
- }
+ if (create_options & FILE_DELETE_ON_CLOSE) {
/* Implicit delete access is *NOT* requested... */
smb_open_mode |= DELETE_ON_CLOSE_FLAG;
DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
@@ -489,7 +534,7 @@ to open_mode 0x%x\n", (unsigned long)*desired_access, (unsigned long)share_acces
static int nt_open_pipe(char *fname, connection_struct *conn,
char *inbuf, char *outbuf, int *ppnum)
{
- smb_np_struct *p = NULL;
+ pipes_struct *p = NULL;
uint16 vuid = SVAL(inbuf, smb_uid);
int i;
@@ -533,9 +578,11 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
int ret;
int pnum = -1;
char *p = NULL;
+ uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
+ ((uint32)sizeof(fname)-1));
- srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
-
+ get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
return ret;
@@ -573,20 +620,23 @@ int reply_ntcreate_and_X(connection_struct *conn,
{
int result;
pstring fname;
- enum FAKE_FILE_TYPE fake_file_type = FAKE_FILE_TYPE_NONE;
uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
+ uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
+ ((uint32)sizeof(fname)-1));
uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
SMB_BIG_UINT allocation_size = 0;
int smb_ofun;
int smb_open_mode;
+ int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
/* Breakout the oplock request bits so we can set the
reply bits separately. */
int oplock_request = 0;
+ mode_t unixmode;
int fmode=0,rmode=0;
SMB_OFF_T file_len = 0;
SMB_STRUCT_STAT sbuf;
@@ -596,7 +646,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
char *p = NULL;
time_t c_time;
BOOL extended_oplock_granted = False;
- NTSTATUS status;
START_PROFILE(SMBntcreateX);
@@ -604,7 +653,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \
create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attributes,
share_access, create_disposition,
- create_options, root_dir_fid ));
+ root_dir_fid, create_options ));
/* If it's an IPC, use the pipe handler. */
@@ -641,7 +690,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
/*
* This filename is relative to a directory fid.
*/
- pstring rel_fname;
files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
size_t dir_name_len;
@@ -652,28 +700,17 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if(!dir_fsp->is_directory) {
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(status);
- }
+ get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
/*
* Check to see if this is a mac fork of some kind.
*/
- if( strchr_m(fname, ':')) {
+ if( strchr(fname, ':')) {
END_PROFILE(SMBntcreateX);
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
-
- /*
- we need to handle the case when we get a
- relative open relative to a file and the
- pathname is blank - this is a reopen!
- (hint from demyn plantenberg)
- */
-
END_PROFILE(SMBntcreateX);
return(ERROR_DOS(ERRDOS,ERRbadfid));
}
@@ -690,47 +727,35 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
*/
if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
- pstrcat(fname, "/");
+ pstrcat(fname, "\\");
dir_name_len++;
}
- srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * This next calculation can refuse a correct filename if we're dealing
+ * with the Win2k unicode bug, but that would be rare. JRA.
+ */
+
+ if(fname_len + dir_name_len >= sizeof(pstring)) {
END_PROFILE(SMBntcreateX);
- return ERROR_NT(status);
+ return(ERROR_DOS(ERRSRV,ERRfilespecs));
}
- pstrcat(fname, rel_fname);
+
+ get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
+
} else {
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(status);
- }
+
+ get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
/*
* Check to see if this is a mac fork of some kind.
*/
- if( strchr_m(fname, ':')) {
-
-#ifdef HAVE_SYS_QUOTAS
- if ((fake_file_type=is_fake_file(fname))!=FAKE_FILE_TYPE_NONE) {
- /*
- * here we go! support for changing the disk quotas --metze
- *
- * we need to fake up to open this MAGIC QUOTA file
- * and return a valid FID
- *
- * w2k close this file directly after openening
- * xp also tries a QUERY_FILE_INFO on the file and then close it
- */
- } else {
-#endif
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
-#ifdef HAVE_SYS_QUOTAS
- }
-#endif
+ if( strchr(fname, ':')) {
+ END_PROFILE(SMBntcreateX);
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
}
@@ -744,7 +769,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
share_access,
file_attributes)) == -1) {
END_PROFILE(SMBntcreateX);
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -760,10 +785,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
* Check if POSIX semantics are wanted.
*/
- set_posix_case_semantics(conn, file_attributes);
+ set_posix_case_semantics(file_attributes);
unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+
/*
* If it's a request for a directory open, deal with it separately.
*/
@@ -777,13 +804,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
if(!fsp) {
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBntcreateX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
} else {
/*
@@ -803,21 +831,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
* before issuing an oplock break request to
* our client. JRA. */
- if (fake_file_type==FAKE_FILE_TYPE_NONE) {
- fsp = open_file_shared1(conn,fname,&sbuf,
- desired_access,
- smb_open_mode,
- smb_ofun,file_attributes,oplock_request,
- &rmode,&smb_action);
- } else {
- /* to open a fake_file --metze */
- fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf,
+ fsp = open_file_shared1(conn,fname,&sbuf,
desired_access,
smb_open_mode,
- smb_ofun,file_attributes, oplock_request,
+ smb_ofun, unixmode, oplock_request,
&rmode,&smb_action);
- }
-
+
if (!fsp) {
/* We cheat here. There are two cases we
* care about. One is a directory rename,
@@ -845,7 +864,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
*/
if (create_options & FILE_NON_DIRECTORY_FILE) {
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
SSVAL(outbuf, smb_flg2,
SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
@@ -853,23 +872,26 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
if(!fsp) {
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBntcreateX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
} else {
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
+
END_PROFILE(SMBntcreateX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
}
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
file_len = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
@@ -888,12 +910,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
#endif
if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
- if (fsp->is_directory) {
- close_file(fsp,False);
- END_PROFILE(SMBntcreateX);
- /* Can't set allocation size on a directory. */
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
close_file(fsp,False);
END_PROFILE(SMBntcreateX);
@@ -915,7 +931,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
extended_oplock_granted = True;
-#if 0
+#if 0
/* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
set_message(outbuf,42,0,True);
#else
@@ -970,15 +986,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
p += 8;
SIVAL(p,0,fmode); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
+ SOFF_T(p, 0, get_allocation_size(fsp, &sbuf));
p += 8;
SOFF_T(p,0,file_len);
- p += 8;
- if (flags & EXTENDED_RESPONSE_REQUIRED)
- SSVAL(p,2,0x7);
- p += 4;
+ p += 12;
SCVAL(p,0,fsp->is_directory ? 1 : 0);
-
+
DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
result = chain_reply(inbuf,outbuf,length,bufsize);
@@ -990,49 +1003,54 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
Reply to a NT_TRANSACT_CREATE call to open a pipe.
****************************************************************************/
-static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int do_nt_transact_create_pipe( connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize, char **ppsetup, char **ppparams,
+ char **ppdata)
{
pstring fname;
+ uint32 fname_len;
+ int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
char *params = *ppparams;
int ret;
int pnum = -1;
char *p = NULL;
- NTSTATUS status;
/*
* Ensure minimum number of parameters sent.
*/
- if(parameter_count < 54) {
- DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
+ if(total_parameter_count < 54) {
+ DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
+
+ get_filename_transact(&fname[0], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
return ret;
-
+
/* Realloc the size of parameters and data we will return */
- params = nttrans_realloc(ppparams, 69);
+ params = Realloc(*ppparams, 69);
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
-
+
+ *ppparams = params;
+
+ memset((char *)params,'\0',69);
+
p = params;
SCVAL(p,0,NO_OPLOCK_RETURN);
-
+
p += 2;
SSVAL(p,0,pnum);
p += 2;
SIVAL(p,0,FILE_WAS_OPENED);
p += 8;
-
+
p += 32;
SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
p += 20;
@@ -1040,12 +1058,12 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
/* Device state. */
SSVAL(p,2, 0x5FF); /* ? */
-
+
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
-
+
/* Send the required number of replies */
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
-
+
return -1;
}
@@ -1053,24 +1071,28 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
Internal fn to set security descriptors.
****************************************************************************/
-static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent)
+static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent, int *pdef_class,uint32 *pdef_code)
{
prs_struct pd;
SEC_DESC *psd = NULL;
TALLOC_CTX *mem_ctx;
BOOL ret;
-
+
if (sd_len == 0) {
- return NT_STATUS_OK;
+ *pdef_class = 0;
+ *pdef_code = 0;
+ return True;
}
/*
* Init the parse struct we will unmarshall from.
*/
- if ((mem_ctx = talloc_init("set_sd")) == NULL) {
+ if ((mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("set_sd: talloc_init failed.\n"));
- return NT_STATUS_NO_MEMORY;
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnomem;
+ return False;
}
prs_init(&pd, 0, mem_ctx, UNMARSHALL);
@@ -1092,9 +1114,11 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
* Return access denied for want of a better error message..
*/
talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnomem;
+ return False;
}
-
+
if (psd->off_owner_sid==0)
security_info_sent &= ~OWNER_SECURITY_INFORMATION;
if (psd->off_grp_sid==0)
@@ -1104,32 +1128,38 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
if (psd->off_dacl==0)
security_info_sent &= ~DACL_SECURITY_INFORMATION;
- ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fd, security_info_sent, psd);
-
+ ret = fsp->conn->vfs_ops.fset_nt_acl( fsp, fsp->fd, security_info_sent, psd);
+
if (!ret) {
talloc_destroy(mem_ctx);
- return NT_STATUS_ACCESS_DENIED;
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnoaccess;
+ return False;
}
-
+
talloc_destroy(mem_ctx);
-
- return NT_STATUS_OK;
+
+ *pdef_class = 0;
+ *pdef_code = 0;
+ return True;
}
/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
-static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_create(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize, char **ppsetup, char **ppparams,
+ char **ppdata)
{
pstring fname;
char *params = *ppparams;
char *data = *ppdata;
+ int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
/* Breakout the oplock request bits so we can set the reply bits separately. */
int oplock_request = 0;
+ mode_t unixmode;
int fmode=0,rmode=0;
SMB_OFF_T file_len = 0;
SMB_STRUCT_STAT sbuf;
@@ -1144,13 +1174,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
uint32 share_access;
uint32 create_disposition;
uint32 create_options;
+ uint32 fname_len;
uint32 sd_len;
uint16 root_dir_fid;
- SMB_BIG_UINT allocation_size = 0;
+ SMB_BIG_UINT allocation_size;
int smb_ofun;
int smb_open_mode;
+ int smb_attr;
+ int error_class;
+ uint32 error_code;
time_t c_time;
- NTSTATUS status;
DEBUG(5,("call_nt_transact_create\n"));
@@ -1161,10 +1194,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if (IS_IPC(conn)) {
if (lp_nt_pipe_support())
return do_nt_transact_create_pipe(conn, inbuf, outbuf, length,
- bufsize,
- ppsetup, setup_count,
- ppparams, parameter_count,
- ppdata, data_count);
+ bufsize, ppsetup, ppparams, ppdata);
else
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1173,8 +1203,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Ensure minimum number of parameters sent.
*/
- if(parameter_count < 54) {
- DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
+ if(total_parameter_count < 54) {
+ DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1185,9 +1215,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
create_disposition = IVAL(params,28);
create_options = IVAL(params,32);
sd_len = IVAL(params,36);
+ fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
root_dir_fid = (uint16)IVAL(params,4);
+ smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
if (create_options & FILE_OPEN_BY_FILE_ID) {
+ END_PROFILE(SMBntcreateX);
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
@@ -1207,6 +1240,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
/*
* This filename is relative to a directory fid.
*/
+
files_struct *dir_fsp = file_fsp(params,4);
size_t dir_name_len;
@@ -1214,19 +1248,17 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
return ERROR_DOS(ERRDOS,ERRbadfid);
if(!dir_fsp->is_directory) {
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ get_filename_transact(&fname[0], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
/*
* Check to see if this is a mac fork of some kind.
*/
- if( strchr_m(fname, ':'))
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ if( strchr(fname, ':'))
+ return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
- return ERROR_DOS(ERRDOS,ERRbadfid);
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
}
/*
@@ -1241,30 +1273,31 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
*/
if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
- pstrcat(fname, "/");
+ pstrcat(fname, "\\");
dir_name_len++;
}
- {
- pstring tmpname;
- srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
- pstrcat(fname, tmpname);
- }
+ /*
+ * This next calculation can refuse a correct filename if we're dealing
+ * with the Win2k unicode bug, but that would be rare. JRA.
+ */
+
+ if(fname_len + dir_name_len >= sizeof(pstring))
+ return(ERROR_DOS(ERRSRV,ERRfilespecs));
+
+ get_filename_transact(&fname[dir_name_len], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
+
} else {
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ get_filename_transact(&fname[0], params, 53,
+ total_parameter_count - 53 - fname_len, fname_len);
/*
* Check to see if this is a mac fork of some kind.
*/
- if( strchr_m(fname, ':'))
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ if( strchr(fname, ':'))
+ return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
}
/*
@@ -1273,8 +1306,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
*/
if((smb_open_mode = map_share_mode( fname, create_options, &desired_access,
- share_access, file_attributes)) == -1)
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ share_access, file_attributes)) == -1)
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
@@ -1283,12 +1316,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Check if POSIX semantics are wanted.
*/
- set_posix_case_semantics(conn, file_attributes);
+ set_posix_case_semantics(file_attributes);
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+
/*
* If it's a request for a directory open, deal with it separately.
*/
@@ -1297,6 +1332,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
/* Can't open a temp directory. IFS kit test. */
if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
+ END_PROFILE(SMBntcreateX);
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
@@ -1308,11 +1344,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* CreateDirectory() call.
*/
- fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
if(!fsp) {
- restore_case_semantics(conn, file_attributes);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
} else {
@@ -1321,9 +1358,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Ordinary file case.
*/
- fsp = open_file_shared1(conn,fname,&sbuf,desired_access,
- smb_open_mode,smb_ofun,file_attributes,
- oplock_request,&rmode,&smb_action);
+ fsp = open_file_shared1(conn,fname,&sbuf,desired_access,smb_open_mode,smb_ofun,unixmode,
+ oplock_request,&rmode,&smb_action);
if (!fsp) {
@@ -1334,21 +1370,25 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
*/
if (create_options & FILE_NON_DIRECTORY_FILE) {
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
-
+ fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
+
if(!fsp) {
- restore_case_semantics(conn, file_attributes);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
} else {
- restore_case_semantics(conn, file_attributes);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+
+ restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
+
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
@@ -1359,7 +1399,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if (fmode & aDIR) {
close_file(fsp,False);
- restore_case_semantics(conn, file_attributes);
+ restore_case_semantics(file_attributes);
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1380,13 +1420,13 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Now try and apply the desired SD.
*/
- if (sd_len && !NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) {
+ if (sd_len && !set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION, &error_class, &error_code)) {
close_file(fsp,False);
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(status);
+ restore_case_semantics(file_attributes);
+ return ERROR_DOS(error_class, error_code);
}
-
- restore_case_semantics(conn, file_attributes);
+
+ restore_case_semantics(file_attributes);
/* Save the requested allocation size. */
allocation_size = (SMB_BIG_UINT)IVAL(params,12);
@@ -1395,14 +1435,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
#endif
if (allocation_size && (allocation_size > file_len)) {
fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
- if (fsp->is_directory) {
- close_file(fsp,False);
- END_PROFILE(SMBntcreateX);
- /* Can't set allocation size on a directory. */
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
close_file(fsp,False);
+ END_PROFILE(SMBntcreateX);
return ERROR_NT(NT_STATUS_DISK_FULL);
}
} else {
@@ -1410,10 +1445,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
/* Realloc the size of parameters and data we will return */
- params = nttrans_realloc(ppparams, 69);
+ params = Realloc(*ppparams, 69);
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
+ *ppparams = params;
+
+ memset((char *)params,'\0',69);
+
p = params;
if (extended_oplock_granted)
SCVAL(p,0, BATCH_OPLOCK_RETURN);
@@ -1454,11 +1493,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
p += 8;
SOFF_T(p,0,file_len);
- p += 8;
- if (flags & EXTENDED_RESPONSE_REQUIRED)
- SSVAL(p,2,0x7);
- p += 4;
- SCVAL(p,0,fsp->is_directory ? 1 : 0);
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
@@ -1483,7 +1517,6 @@ int reply_ntcancel(connection_struct *conn,
START_PROFILE(SMBntcancel);
remove_pending_change_notify_requests_by_mid(mid);
remove_pending_lock_requests_by_mid(mid);
- srv_cancel_sign_response(mid);
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
@@ -1492,75 +1525,6 @@ int reply_ntcancel(connection_struct *conn,
}
/****************************************************************************
- Reply to a NT rename request.
-****************************************************************************/
-
-int reply_ntrename(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
-{
- int outsize = 0;
- pstring oldname;
- pstring newname;
- char *p;
- NTSTATUS status;
- uint16 attrs = SVAL(inbuf,smb_vwv0);
- uint16 rename_type = SVAL(inbuf,smb_vwv1);
-
- START_PROFILE(SMBntrename);
-
- if ((rename_type != RENAME_FLAG_RENAME) && (rename_type != RENAME_FLAG_HARD_LINK)) {
- END_PROFILE(SMBntrename);
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
-
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBntrename);
- return ERROR_NT(status);
- }
-
- if( strchr_m(oldname, ':')) {
- /* Can't rename a stream. */
- END_PROFILE(SMBntrename);
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
-
- p++;
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBntrename);
- return ERROR_NT(status);
- }
-
- RESOLVE_DFSPATH(oldname, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
-
- DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
-
- if (rename_type == RENAME_FLAG_RENAME) {
- status = rename_internals(conn, oldname, newname, attrs, False);
- } else {
- status = hardlink_internals(conn, oldname, newname);
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBntrename);
- return ERROR_NT(status);
- }
-
- /*
- * Win2k needs a changenotify request response before it will
- * update after a rename..
- */
- process_pending_change_notify_queue((time_t)0);
- outsize = set_message(outbuf,0,0,True);
-
- END_PROFILE(SMBntrename);
- return(outsize);
-}
-
-/****************************************************************************
Reply to an unsolicited SMBNTtranss - just ignore it!
****************************************************************************/
@@ -1577,19 +1541,16 @@ int reply_nttranss(connection_struct *conn,
Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
-
-static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_notify_change(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize,
+ char **ppsetup,
+ char **ppparams, char **ppdata)
{
char *setup = *ppsetup;
files_struct *fsp;
uint32 flags;
- if(setup_count < 6)
- return ERROR_DOS(ERRDOS,ERRbadfunc);
-
fsp = file_fsp(setup,4);
flags = IVAL(setup, 0);
@@ -1614,30 +1575,25 @@ name = %s\n", fsp->fsp_name ));
Reply to an NT transact rename command.
****************************************************************************/
-static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_rename(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize,
+ char **ppsetup, char **ppparams, char **ppdata)
{
char *params = *ppparams;
pstring new_name;
- files_struct *fsp = NULL;
- BOOL replace_if_exists = False;
+ files_struct *fsp = file_fsp(params, 0);
+ BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
NTSTATUS status;
+ uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
+ ((uint32)sizeof(new_name)-1));
- if(parameter_count < 4)
- return ERROR_DOS(ERRDOS,ERRbadfunc);
-
- fsp = file_fsp(params, 0);
- replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
CHECK_FSP(fsp, conn);
- srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ StrnCpy(new_name,params+4,fname_len);
+ new_name[fname_len] = '\0';
status = rename_internals(conn, fsp->fsp_name,
- new_name, 0, replace_if_exists);
+ new_name, replace_if_exists);
if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
@@ -1645,15 +1601,15 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
* Rename was successful.
*/
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
-
+
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
- fsp->fsp_name, new_name));
-
+ fsp->fsp_name, new_name));
+
/*
* Win2k needs a changenotify request response before it will
* update after a rename..
*/
-
+
process_pending_change_notify_queue((time_t)0);
return -1;
@@ -1673,138 +1629,143 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
sd_size = 0;
}
-
+
return sd_size;
}
/****************************************************************************
- Reply to query a security descriptor.
+ Reply to query a security descriptor - currently this is not implemented (it
+ is planned to be though). Right now it just returns the same thing NT would
+ when queried on a FAT filesystem. JRA.
****************************************************************************/
-static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_query_security_desc(connection_struct *conn,
+ char *inbuf, char *outbuf,
+ int length, int bufsize,
+ char **ppsetup, char **ppparams, char **ppdata)
{
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
- char *params = *ppparams;
- char *data = *ppdata;
- prs_struct pd;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- uint32 security_info_wanted;
- TALLOC_CTX *mem_ctx;
- files_struct *fsp = NULL;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ char *params = *ppparams;
+ char *data = *ppdata;
+ prs_struct pd;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
+ TALLOC_CTX *mem_ctx;
- if(parameter_count < 8)
- return ERROR_DOS(ERRDOS,ERRbadfunc);
+ files_struct *fsp = file_fsp(params,0);
- fsp = file_fsp(params,0);
- if(!fsp)
- return ERROR_DOS(ERRDOS,ERRbadfid);
+ if(!fsp)
+ return ERROR_DOS(ERRDOS,ERRbadfid);
- security_info_wanted = IVAL(params,4);
+ DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
- DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
+ params = Realloc(*ppparams, 4);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
- params = nttrans_realloc(ppparams, 4);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ *ppparams = params;
- if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
- DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
+ if ((mem_ctx = talloc_init()) == NULL) {
+ DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
- /*
- * Get the permissions to return.
- */
+ /*
+ * Get the permissions to return.
+ */
- if (!lp_nt_acl_support(SNUM(conn)))
- sd_size = get_null_nt_acl(mem_ctx, &psd);
- else
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd);
+ if (!lp_nt_acl_support(SNUM(conn)))
+ sd_size = get_null_nt_acl(mem_ctx, &psd);
+ else
+ sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
- if (sd_size == 0) {
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if (sd_size == 0) {
+ talloc_destroy(mem_ctx);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
+ DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
- SIVAL(params,0,(uint32)sd_size);
+ SIVAL(params,0,(uint32)sd_size);
- if(max_data_count < sd_size) {
+ if(max_data_count < sd_size) {
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
- params, 4, *ppdata, 0);
- talloc_destroy(mem_ctx);
- return -1;
- }
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+ params, 4, *ppdata, 0);
+ talloc_destroy(mem_ctx);
+ return -1;
+ }
- /*
- * Allocate the data we will point this at.
- */
+ /*
+ * Allocate the data we will point this at.
+ */
- data = nttrans_realloc(ppdata, sd_size);
- if(data == NULL) {
- talloc_destroy(mem_ctx);
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
+ data = Realloc(*ppdata, sd_size);
+ if(data == NULL) {
+ talloc_destroy(mem_ctx);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
- /*
- * Init the parse struct we will marshall into.
- */
+ *ppdata = data;
- prs_init(&pd, 0, mem_ctx, MARSHALL);
+ memset(data, '\0', sd_size);
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
+ /*
+ * Init the parse struct we will marshall into.
+ */
- prs_give_memory( &pd, data, (uint32)sd_size, False);
+ prs_init(&pd, 0, mem_ctx, MARSHALL);
- /*
- * Finally, linearize into the outgoing buffer.
- */
+ /*
+ * Setup the prs_struct to point at the memory we just
+ * allocated.
+ */
- if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
- DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
+ prs_give_memory( &pd, data, (uint32)sd_size, False);
+
+ /*
+ * Finally, linearize into the outgoing buffer.
+ */
+
+ if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
+ DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
security descriptor.\n"));
- /*
- * Return access denied for want of a better error message..
- */
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ /*
+ * Return access denied for want of a better error message..
+ */
+ talloc_destroy(mem_ctx);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- /*
- * Now we can delete the security descriptor.
- */
+ /*
+ * Now we can delete the security descriptor.
+ */
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
- return -1;
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
+ return -1;
}
/****************************************************************************
- Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
+ Reply to set a security descriptor. Map to UNIX perms.
****************************************************************************/
-static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_set_security_desc(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize, char **ppsetup,
+ char **ppparams, char **ppdata)
{
+ uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
char *params= *ppparams;
char *data = *ppdata;
+ uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
files_struct *fsp = NULL;
uint32 security_info_sent = 0;
- NTSTATUS nt_status;
+ int error_class;
+ uint32 error_code;
- if(parameter_count < 8)
+ if(total_parameter_count < 8)
return ERROR_DOS(ERRDOS,ERRbadfunc);
if((fsp = file_fsp(params,0)) == NULL)
@@ -1818,11 +1779,11 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb
DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
(unsigned int)security_info_sent ));
- if (data_count == 0)
+ if (total_data_count == 0)
return ERROR_DOS(ERRDOS, ERRnoaccess);
- if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent)))
- return ERROR_NT(nt_status);
+ if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code))
+ return ERROR_DOS(error_class, error_code);
done:
@@ -1831,629 +1792,55 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb
}
/****************************************************************************
- Reply to NT IOCTL
+ Reply to IOCTL.
****************************************************************************/
-static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+static int call_nt_transact_ioctl(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize,
+ char **ppsetup, int setup_count,
+ char **ppparams, int parameter_count,
+ char **ppdata, int data_count)
{
- uint32 function;
- uint16 fidnum;
- files_struct *fsp;
- uint8 isFSctl;
- uint8 compfilter;
+ unsigned fnum, control;
static BOOL logged_message;
- char *pdata = *ppdata;
-
+
if (setup_count != 8) {
DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
-
- function = IVAL(*ppsetup, 0);
- fidnum = SVAL(*ppsetup, 4);
- isFSctl = CVAL(*ppsetup, 6);
- compfilter = CVAL(*ppsetup, 7);
-
- DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
- function, fidnum, isFSctl, compfilter));
-
- fsp=file_fsp(*ppsetup, 4);
- /* this check is done in each implemented function case for now
- because I don't want to break anything... --metze
- FSP_BELONGS_CONN(fsp,conn);*/
-
- switch (function) {
- case FSCTL_SET_SPARSE:
+
+ fnum = SVAL(*ppsetup, 4);
+ control = IVAL(*ppsetup, 0);
+
+ DEBUG(6,("call_nt_transact_ioctl: fnum=%d control=0x%x\n",
+ fnum, control));
+
+ switch (control) {
+ case NTIOCTL_SET_SPARSE:
/* pretend this succeeded - tho strictly we should
- mark the file sparse (if the local fs supports it)
- so we can know if we need to pre-allocate or not */
-
- DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
- return -1;
-
- case FSCTL_0x000900C0:
- /* pretend this succeeded - don't know what this really is
- but works ok like this --metze
- */
-
- DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
+ mark the file sparse (if the local fs supports it)
+ so we can know if we need to pre-allocate or not */
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
-
- case FSCTL_GET_REPARSE_POINT:
- /* pretend this fail - my winXP does it like this
- * --metze
- */
-
- DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
- return -1;
-
- case FSCTL_SET_REPARSE_POINT:
- /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
- * --metze
- */
-
- DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
- return -1;
-
- case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
- {
- /*
- * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
- * and return their volume names. If max_data_count is 16, then it is just
- * asking for the number of volumes and length of the combined names.
- *
- * pdata is the data allocated by our caller, but that uses
- * total_data_count (which is 0 in our case) rather than max_data_count.
- * Allocate the correct amount and return the pointer to let
- * it be deallocated when we return.
- */
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
- SHADOW_COPY_DATA *shadow_data = NULL;
- TALLOC_CTX *shadow_mem_ctx = NULL;
- BOOL labels = False;
- uint32 labels_data_count = 0;
- uint32 i;
- char *cur_pdata;
-
- FSP_BELONGS_CONN(fsp,conn);
-
- if (max_data_count < 16) {
- DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
- max_data_count));
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- if (max_data_count > 16) {
- labels = True;
- }
-
- shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
- if (shadow_mem_ctx == NULL) {
- DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
- return ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- shadow_data = (SHADOW_COPY_DATA *)talloc_zero(shadow_mem_ctx,sizeof(SHADOW_COPY_DATA));
- if (shadow_data == NULL) {
- DEBUG(0,("talloc_zero() failed!\n"));
- return ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- shadow_data->mem_ctx = shadow_mem_ctx;
-
- /*
- * Call the VFS routine to actually do the work.
- */
- if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
- talloc_destroy(shadow_data->mem_ctx);
- if (errno == ENOSYS) {
- DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
- conn->connectpath));
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
- } else {
- DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
- conn->connectpath));
- return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- }
- }
-
- labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
-
- if (!labels) {
- data_count = 16;
- } else {
- data_count = 12+labels_data_count+4;
- }
-
- if (max_data_count<data_count) {
- DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
- max_data_count,data_count));
- talloc_destroy(shadow_data->mem_ctx);
- return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
- }
-
- pdata = nttrans_realloc(ppdata, data_count);
- if (pdata == NULL) {
- talloc_destroy(shadow_data->mem_ctx);
- return ERROR_NT(NT_STATUS_NO_MEMORY);
- }
-
- cur_pdata = pdata;
-
- /* num_volumes 4 bytes */
- SIVAL(pdata,0,shadow_data->num_volumes);
-
- if (labels) {
- /* num_labels 4 bytes */
- SIVAL(pdata,4,shadow_data->num_volumes);
- }
-
- /* needed_data_count 4 bytes */
- SIVAL(pdata,8,labels_data_count);
-
- cur_pdata+=12;
-
- DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
- shadow_data->num_volumes,fsp->fsp_name));
- if (labels && shadow_data->labels) {
- for (i=0;i<shadow_data->num_volumes;i++) {
- srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
- cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
- DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
- }
- }
-
- talloc_destroy(shadow_data->mem_ctx);
-
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
-
- return -1;
- }
-
- case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
- {
- /* pretend this succeeded -
- *
- * we have to send back a list with all files owned by this SID
- *
- * but I have to check that --metze
- */
- DOM_SID sid;
- uid_t uid;
- size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
-
- DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
-
- FSP_BELONGS_CONN(fsp,conn);
-
- /* unknown 4 bytes: this is not the length of the sid :-( */
- /*unknown = IVAL(pdata,0);*/
-
- sid_parse(pdata+4,sid_len,&sid);
- DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
-
- if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
- DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
- sid_string_static(&sid),(unsigned long)sid_len));
- uid = (-1);
- }
-
- /* we can take a look at the find source :-)
- *
- * find ./ -uid $uid -name '*' is what we need here
- *
- *
- * and send 4bytes len and then NULL terminated unicode strings
- * for each file
- *
- * but I don't know how to deal with the paged results
- * (maybe we can hang the result anywhere in the fsp struct)
- *
- * we don't send all files at once
- * and at the next we should *not* start from the beginning,
- * so we have to cache the result
- *
- * --metze
- */
-
- /* this works for now... */
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
- return -1;
- }
+
default:
if (!logged_message) {
logged_message = True; /* Only print this once... */
- DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
- function));
+ DEBUG(3,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
+ control));
}
}
-
+
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
-
-
-#ifdef HAVE_SYS_QUOTAS
-/****************************************************************************
- Reply to get user quota
-****************************************************************************/
-
-static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
-{
- NTSTATUS nt_status = NT_STATUS_OK;
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
- char *params = *ppparams;
- char *pdata = *ppdata;
- char *entry;
- int data_len=0,param_len=0;
- int qt_len=0;
- int entry_len = 0;
- files_struct *fsp = NULL;
- uint16 level = 0;
- size_t sid_len;
- DOM_SID sid;
- BOOL start_enum = True;
- SMB_NTQUOTA_STRUCT qt;
- SMB_NTQUOTA_LIST *tmp_list;
- SMB_NTQUOTA_HANDLE *qt_handle = NULL;
- extern struct current_user current_user;
-
- ZERO_STRUCT(qt);
-
- /* access check */
- if (current_user.uid != 0) {
- DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),conn->user));
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- /*
- * Ensure minimum number of parameters sent.
- */
-
- if (parameter_count < 4) {
- DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
- return ERROR_DOS(ERRDOS,ERRinvalidparam);
- }
-
- /* maybe we can check the quota_fnum */
- fsp = file_fsp(params,0);
- if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
- DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
- return ERROR_NT(NT_STATUS_INVALID_HANDLE);
- }
-
- /* the NULL pointer cheking for fsp->fake_file_handle->pd
- * is done by CHECK_NTQUOTA_HANDLE_OK()
- */
- qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
-
- level = SVAL(params,2);
-
- /* unknown 12 bytes leading in params */
-
- switch (level) {
- case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
- /* seems that we should continue with the enum here --metze */
-
- if (qt_handle->quota_list!=NULL &&
- qt_handle->tmp_list==NULL) {
-
- /* free the list */
- free_ntquota_list(&(qt_handle->quota_list));
-
- /* Realloc the size of parameters and data we will return */
- param_len = 4;
- params = nttrans_realloc(ppparams, param_len);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
-
- data_len = 0;
- SIVAL(params,0,data_len);
-
- break;
- }
-
- start_enum = False;
-
- case TRANSACT_GET_USER_QUOTA_LIST_START:
-
- if (qt_handle->quota_list==NULL &&
- qt_handle->tmp_list==NULL) {
- start_enum = True;
- }
-
- if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
- return ERROR_DOS(ERRSRV,ERRerror);
-
- /* Realloc the size of parameters and data we will return */
- param_len = 4;
- params = nttrans_realloc(ppparams, param_len);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
-
- /* we should not trust the value in max_data_count*/
- max_data_count = MIN(max_data_count,2048);
-
- pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
- if(pdata == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
-
- entry = pdata;
-
-
- /* set params Size of returned Quota Data 4 bytes*/
- /* but set it later when we know it */
-
- /* for each entry push the data */
-
- if (start_enum) {
- qt_handle->tmp_list = qt_handle->quota_list;
- }
-
- tmp_list = qt_handle->tmp_list;
-
- for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
- tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
-
- sid_len = sid_size(&tmp_list->quotas->sid);
- entry_len = 40 + sid_len;
-
- /* nextoffset entry 4 bytes */
- SIVAL(entry,0,entry_len);
-
- /* then the len of the SID 4 bytes */
- SIVAL(entry,4,sid_len);
-
- /* unknown data 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
-
- /* the used disk space 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
-
- /* the soft quotas 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,24,tmp_list->quotas->softlim);
-
- /* the hard quotas 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
-
- /* and now the SID */
- sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
- }
-
- qt_handle->tmp_list = tmp_list;
-
- /* overwrite the offset of the last entry */
- SIVAL(entry-entry_len,0,0);
-
- data_len = 4+qt_len;
- /* overwrite the params quota_data_len */
- SIVAL(params,0,data_len);
-
- break;
-
- case TRANSACT_GET_USER_QUOTA_FOR_SID:
-
- /* unknown 4 bytes IVAL(pdata,0) */
-
- if (data_count < 8) {
- DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-
- sid_len = IVAL(pdata,4);
-
- if (data_count < 8+sid_len) {
- DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-
- data_len = 4+40+sid_len;
-
- if (max_data_count < data_len) {
- DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
- max_data_count, data_len));
- param_len = 4;
- SIVAL(params,0,data_len);
- data_len = 0;
- nt_status = NT_STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- sid_parse(pdata+8,sid_len,&sid);
-
-
- if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
- ZERO_STRUCT(qt);
- /*
- * we have to return zero's in all fields
- * instead of returning an error here
- * --metze
- */
- }
-
- /* Realloc the size of parameters and data we will return */
- param_len = 4;
- params = nttrans_realloc(ppparams, param_len);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
-
- pdata = nttrans_realloc(ppdata, data_len);
- if(pdata == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
-
- entry = pdata;
-
- /* set params Size of returned Quota Data 4 bytes*/
- SIVAL(params,0,data_len);
-
- /* nextoffset entry 4 bytes */
- SIVAL(entry,0,0);
-
- /* then the len of the SID 4 bytes */
- SIVAL(entry,4,sid_len);
-
- /* unknown data 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
-
- /* the used disk space 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,16,qt.usedspace);
-
- /* the soft quotas 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,24,qt.softlim);
-
- /* the hard quotas 8 bytes SMB_BIG_UINT */
- SBIG_UINT(entry,32,qt.hardlim);
-
- /* and now the SID */
- sid_linearize(entry+40, sid_len, &sid);
-
- break;
-
- default:
- DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
- return ERROR_DOS(ERRSRV,ERRerror);
- break;
- }
-
- send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len, pdata, data_len);
-
- return -1;
-}
-
-/****************************************************************************
- Reply to set user quota
-****************************************************************************/
-
-static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **ppsetup, uint32 setup_count,
- char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
-{
- char *params = *ppparams;
- char *pdata = *ppdata;
- int data_len=0,param_len=0;
- SMB_NTQUOTA_STRUCT qt;
- size_t sid_len;
- DOM_SID sid;
- files_struct *fsp = NULL;
-
- ZERO_STRUCT(qt);
-
- /* access check */
- if (current_user.uid != 0) {
- DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),conn->user));
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- /*
- * Ensure minimum number of parameters sent.
- */
-
- if (parameter_count < 2) {
- DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
- return ERROR_DOS(ERRDOS,ERRinvalidparam);
- }
-
- /* maybe we can check the quota_fnum */
- fsp = file_fsp(params,0);
- if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
- DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
- return ERROR_NT(NT_STATUS_INVALID_HANDLE);
- }
-
- if (data_count < 40) {
- DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-
- /* offset to next quota record.
- * 4 bytes IVAL(pdata,0)
- * unused here...
- */
-
- /* sid len */
- sid_len = IVAL(pdata,4);
-
- if (data_count < 40+sid_len) {
- DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-
- /* unknown 8 bytes in pdata
- * maybe its the change time in NTTIME
- */
-
- /* the used space 8 bytes (SMB_BIG_UINT)*/
- qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
-#ifdef LARGE_SMB_OFF_T
- qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,20) != 0)&&
- ((qt.usedspace != 0xFFFFFFFF)||
- (IVAL(pdata,20)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
- qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
-#ifdef LARGE_SMB_OFF_T
- qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,28) != 0)&&
- ((qt.softlim != 0xFFFFFFFF)||
- (IVAL(pdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
- qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
-#ifdef LARGE_SMB_OFF_T
- qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,36) != 0)&&
- ((qt.hardlim != 0xFFFFFFFF)||
- (IVAL(pdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-#endif /* LARGE_SMB_OFF_T */
-
- sid_parse(pdata+40,sid_len,&sid);
- DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
-
- /* 44 unknown bytes left... */
-
- if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, pdata, data_len);
-
- return -1;
-}
-#endif /* HAVE_SYS_QUOTAS */
-
+
/****************************************************************************
Reply to a SMBNTtrans.
****************************************************************************/
int reply_nttrans(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+ char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
#if 0 /* Not used. */
@@ -2548,8 +1935,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((parameter_offset + parameter_count < parameter_offset) ||
(parameter_offset + parameter_count < parameter_count))
goto bad_param;
- if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)||
- (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
+ if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)
goto bad_param;
memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
@@ -2559,21 +1945,17 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
goto bad_param;
- if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
- (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
+ if (smb_base(inbuf) + data_offset + data_count > inbuf + length)
goto bad_param;
memcpy( data, smb_base(inbuf) + data_offset, data_count);
dump_data(10, data, data_count);
}
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
outsize = set_message(outbuf,0,0,True);
- srv_signing_trans_stop();
if (!send_smb(smbd_server_fd(),outbuf))
exit_server("reply_nttrans: send_smb failed.");
@@ -2584,13 +1966,6 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
- /*
- * The sequence number for the trans reply is always
- * based on the last secondary received.
- */
-
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
outsize = set_message(outbuf,0,0,True);
if(ret) {
@@ -2629,12 +2004,9 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((parameter_displacement + parameter_count < parameter_displacement) ||
(parameter_displacement + parameter_count < parameter_count))
goto bad_param;
- if (parameter_displacement > total_parameter_count)
+ if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize)
goto bad_param;
- if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) ||
- (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
- goto bad_param;
- if (parameter_displacement + params < params)
+ if (params + parameter_displacement < params)
goto bad_param;
memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
@@ -2646,12 +2018,9 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
if ((data_displacement + data_count < data_displacement) ||
(data_displacement + data_count < data_count))
goto bad_param;
- if (data_displacement > total_data_count)
- goto bad_param;
- if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) ||
- (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
+ if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize)
goto bad_param;
- if (data_displacement + data < data)
+ if (data + data_displacement < data)
goto bad_param;
memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
@@ -2666,79 +2035,48 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
switch(function_code) {
case NT_TRANSACT_CREATE:
START_PROFILE_NESTED(NT_transact_create);
- outsize = call_nt_transact_create(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ outsize = call_nt_transact_create(conn, inbuf, outbuf, length, bufsize,
+ &setup, &params, &data);
END_PROFILE_NESTED(NT_transact_create);
break;
case NT_TRANSACT_IOCTL:
START_PROFILE_NESTED(NT_transact_ioctl);
outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ length, bufsize,
+ &setup, setup_count,
+ &params, parameter_count,
+ &data, data_count);
END_PROFILE_NESTED(NT_transact_ioctl);
break;
case NT_TRANSACT_SET_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_set_security_desc);
outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ length, bufsize,
+ &setup, &params, &data);
END_PROFILE_NESTED(NT_transact_set_security_desc);
break;
case NT_TRANSACT_NOTIFY_CHANGE:
START_PROFILE_NESTED(NT_transact_notify_change);
outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ length, bufsize,
+ &setup, &params, &data);
END_PROFILE_NESTED(NT_transact_notify_change);
break;
case NT_TRANSACT_RENAME:
START_PROFILE_NESTED(NT_transact_rename);
- outsize = call_nt_transact_rename(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ outsize = call_nt_transact_rename(conn, inbuf, outbuf, length,
+ bufsize,
+ &setup, &params, &data);
END_PROFILE_NESTED(NT_transact_rename);
break;
case NT_TRANSACT_QUERY_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_query_security_desc);
outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
+ length, bufsize,
+ &setup, &params, &data);
END_PROFILE_NESTED(NT_transact_query_security_desc);
break;
-#ifdef HAVE_SYS_QUOTAS
- case NT_TRANSACT_GET_USER_QUOTA:
- START_PROFILE_NESTED(NT_transact_get_user_quota);
- outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
- END_PROFILE_NESTED(NT_transact_get_user_quota);
- break;
- case NT_TRANSACT_SET_USER_QUOTA:
- START_PROFILE_NESTED(NT_transact_set_user_quota);
- outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, total_parameter_count,
- &data, total_data_count);
- END_PROFILE_NESTED(NT_transact_set_user_quota);
- break;
-#endif /* HAVE_SYS_QUOTAS */
default:
/* Error in request */
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
@@ -2746,7 +2084,6 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBnttrans);
- srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -2757,8 +2094,6 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
an error packet.
*/
- srv_signing_trans_stop();
-
SAFE_FREE(setup);
SAFE_FREE(params);
SAFE_FREE(data);
@@ -2769,7 +2104,6 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
bad_param:
- srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
SAFE_FREE(setup);
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 8ab5dab6ac9..239e3d89e48 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
file opening and share modes
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001
@@ -23,23 +24,30 @@
extern userdom_struct current_user_info;
extern uint16 global_oplock_port;
-extern uint16 global_smbpid;
extern BOOL global_client_failed_oplock_break;
/****************************************************************************
fd support routines - attempt to do a dos_open.
****************************************************************************/
-static int fd_open(struct connection_struct *conn, const char *fname,
+static int fd_open(struct connection_struct *conn, char *fname,
int flags, mode_t mode)
{
int fd;
+
#ifdef O_NOFOLLOW
if (!lp_symlinks(SNUM(conn)))
flags |= O_NOFOLLOW;
#endif
- fd = SMB_VFS_OPEN(conn,fname,flags,mode);
+ fd = conn->vfs_ops.open(conn,dos_to_unix_static(fname),flags,mode);
+
+ /* Fix for files ending in '.' */
+ if((fd == -1) && (errno == ENOENT) &&
+ (strchr(fname,'.')==NULL)) {
+ pstrcat(fname,".");
+ fd = conn->vfs_ops.open(conn,dos_to_unix_static(fname),flags,mode);
+ }
DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
@@ -63,12 +71,12 @@ int fd_close(struct connection_struct *conn, files_struct *fsp)
Check a filename for the pipe string.
****************************************************************************/
-static void check_for_pipe(const char *fname)
+static void check_for_pipe(char *fname)
{
/* special case of pipe opens */
char s[10];
StrnCpy(s,fname,sizeof(s)-1);
- strlower_m(s);
+ strlower(s);
if (strstr(s,"pipe/")) {
DEBUG(3,("Rejecting named pipe open for %s\n",fname));
unix_ERR_class = ERRSRV;
@@ -82,9 +90,10 @@ static void check_for_pipe(const char *fname)
****************************************************************************/
static BOOL open_file(files_struct *fsp,connection_struct *conn,
- const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
+ const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
{
extern struct current_user current_user;
+ pstring fname;
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
@@ -92,6 +101,8 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->oplock_type = NO_OPLOCK;
errno = EPERM;
+ pstrcpy(fname,fname1);
+
/* Check permissions */
/*
@@ -116,7 +127,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
directory.
*/
flags &= ~O_CREAT;
- local_flags &= ~O_CREAT;
}
}
@@ -137,6 +147,8 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
local_flags = (flags & ~O_ACCMODE)|O_RDWR;
}
+ /* actually do the open */
+
if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
(local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
@@ -157,28 +169,14 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
local_flags |= O_NONBLOCK;
#endif
-
- /* Don't create files with Microsoft wildcard characters. */
- if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
- return False;
- }
-
- /* Actually do the open */
fsp->fd = fd_open(conn, fname, local_flags, mode);
+
if (fsp->fd == -1) {
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
fname,strerror(errno),local_flags,flags));
check_for_pipe(fname);
return False;
}
-
- /* Inherit the ACL if the file was created. */
- if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
- inherit_access_acl(conn, fname, mode);
-
} else
fsp->fd = -1; /* What we used to call a stat open. */
@@ -186,9 +184,9 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
int ret;
if (fsp->fd == -1)
- ret = SMB_VFS_STAT(conn, fname, psbuf);
+ ret = vfs_stat(conn, fname, psbuf);
else {
- ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
+ ret = vfs_fstat(fsp,fsp->fd,psbuf);
/* If we have an fd, this stat should succeed. */
if (ret == -1)
DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
@@ -217,8 +215,8 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
fsp->vuid = current_user.vuid;
- fsp->file_pid = global_smbpid;
fsp->size = psbuf->st_size;
+ fsp->pos = -1;
fsp->can_lock = True;
fsp->can_read = ((flags & O_WRONLY)==0);
fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
@@ -229,9 +227,17 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
- fsp->is_stat = False;
fsp->directory_delete_on_close = False;
+ fsp->conn = conn;
+ /*
+ * Note that the file name here is the *untranslated* name
+ * ie. it is still in the DOS codepage sent from the client.
+ * All use of this filename will pass though the sys_xxxx
+ * functions which will do the dos_to_unix translation before
+ * mapping into a UNIX filename. JRA.
+ */
string_set(&fsp->fsp_name,fname);
+ fsp->wbmpx_ptr = NULL;
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -259,7 +265,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct *
unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
return -1;
} else {
- return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0);
+ return conn->vfs_ops.ftruncate(fsp,fsp->fd,0);
}
}
@@ -268,7 +274,7 @@ return True if the filename is one of the special executable types
********************************************************************/
static BOOL is_executable(const char *fname)
{
- if ((fname = strrchr_m(fname,'.'))) {
+ if ((fname = strrchr(fname,'.'))) {
if (strequal(fname,".com") ||
strequal(fname,".dll") ||
strequal(fname,".exe") ||
@@ -564,10 +570,10 @@ static void validate_my_share_entries(int num, share_mode_entry *share_entry)
****************************************************************************/
static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
- SMB_INO_T inode,
- uint32 desired_access,
- int share_mode, int *p_flags, int *p_oplock_request,
- BOOL *p_all_current_opens_are_level_II)
+ SMB_INO_T inode,
+ uint32 desired_access,
+ int share_mode, int *p_flags, int *p_oplock_request,
+ BOOL *p_all_current_opens_are_level_II)
{
int i;
int num_share_modes;
@@ -575,28 +581,28 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
share_mode_entry *old_shares = 0;
BOOL fcbopen = False;
BOOL broke_oplock;
-
+
if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
fcbopen = True;
-
+
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
-
+
if(num_share_modes == 0)
return 0;
-
+
/*
* Check if the share modes will give us access.
*/
-
+
do {
share_mode_entry broken_entry;
-
+
broke_oplock = False;
*p_all_current_opens_are_level_II = True;
-
+
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &old_shares[i];
-
+
#if defined(DEVELOPER)
validate_my_share_entries(i, share_entry);
#endif
@@ -608,29 +614,23 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
* Check if someone has an oplock on this file. If so we must break
* it before continuing.
*/
-
+
if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
- (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
-
+ (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
+
BOOL opb_ret;
DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
-
- /* Ensure the reply for the open uses the correct sequence number. */
- /* This isn't a real deferred packet as it's response will also increment
- * the sequence.
- */
- srv_defer_sign_response(get_current_mid());
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
-
+
opb_ret = request_oplock_break(share_entry, False);
-
+
/* Now relock. */
lock_share_entry(conn, dev, inode);
-
+
if(opb_ret == False) {
DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
@@ -641,50 +641,50 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
return -1;
}
-
+
broke_oplock = True;
broken_entry = *share_entry;
break;
-
+
} else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
*p_all_current_opens_are_level_II = False;
}
-
+
/* someone else has a share lock on it, check to see if we can too */
- if (!check_share_mode(conn, share_entry, share_mode, desired_access,
+ if (!check_share_mode(conn, share_entry, share_mode, desired_access,
fname, fcbopen, p_flags)) {
SAFE_FREE(old_shares);
errno = EACCES;
return -1;
- }
-
+ }
+
} /* end for */
-
+
if(broke_oplock) {
SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
oplock_contention_count++;
-
+
/* Paranoia check that this is no longer an exlusive entry. */
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &old_shares[i];
-
+
if (share_modes_identical(&broken_entry, share_entry) &&
- EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
-
+ EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
+
/*
* This should not happen. The target left this oplock
* as exlusive.... The process *must* be dead....
*/
-
+
DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
-
+
if (process_exists(broken_entry.pid)) {
- DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
- (unsigned long)broken_entry.pid ));
+ DEBUG(0,("open_mode_check: Existent process %u left active oplock.\n",
+ (unsigned int)broken_entry.pid ));
}
-
+
if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
errno = EACCES;
unix_ERR_class = ERRDOS;
@@ -692,59 +692,51 @@ dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fn
unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
return -1;
}
-
+
/*
* We must reload the share modes after deleting the
* other process's entry.
*/
-
+
SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
break;
}
} /* end for paranoia... */
} /* end if broke_oplock */
-
+
} while(broke_oplock);
-
- if(old_shares != 0)
- SAFE_FREE(old_shares);
-
+
+ SAFE_FREE(old_shares);
+
/*
* Refuse to grant an oplock in case the contention limit is
* reached when going through the lock list multiple times.
*/
-
+
if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
*p_oplock_request = 0;
DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
- oplock_contention_count ));
+ oplock_contention_count ));
}
-
+
return num_share_modes;
}
-/****************************************************************************
-set a kernel flock on a file for NFS interoperability
-this requires a patch to Linux
-****************************************************************************/
-static void kernel_flock(files_struct *fsp, int deny_mode)
+static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
+ mode_t new_mode, mode_t *returned_mode)
{
-#if HAVE_KERNEL_SHARE_MODES
- int kernel_mode = 0;
- if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
- else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
- else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
- if (kernel_mode) flock(fsp->fd, kernel_mode);
-#endif
- ;;
-}
+ uint32 old_dos_mode, new_dos_mode;
+ uint32 noarch_old_dos_mode, noarch_new_dos_mode;
+ SMB_STRUCT_STAT sbuf;
+ ZERO_STRUCT(sbuf);
-static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode,
- mode_t existing_mode, mode_t new_mode, mode_t *returned_mode)
-{
- uint32 noarch_old_dos_mode, noarch_new_dos_mode;
+ sbuf.st_mode = existing_mode;
+ old_dos_mode = dos_mode(conn, path, &sbuf);
+
+ sbuf.st_mode = new_mode;
+ new_dos_mode = dos_mode(conn, path, &sbuf);
noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
@@ -760,11 +752,11 @@ static BOOL open_match_attributes(connection_struct *conn, const char *path, uin
old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
/* If we're mapping SYSTEM and HIDDEN ensure they match. */
- if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
+ if (lp_map_system(SNUM(conn))) {
if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
return False;
}
- if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
+ if (lp_map_hidden(SNUM(conn))) {
if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
return False;
}
@@ -772,26 +764,41 @@ static BOOL open_match_attributes(connection_struct *conn, const char *path, uin
}
/****************************************************************************
- Open a file with a share mode.
+set a kernel flock on a file for NFS interoperability
+this requires a patch to Linux
+****************************************************************************/
+static void kernel_flock(files_struct *fsp, int deny_mode)
+{
+#if HAVE_KERNEL_SHARE_MODES
+ int kernel_mode = 0;
+ if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
+ else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
+ else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
+ if (kernel_mode) flock(fsp->fd, kernel_mode);
+#endif
+ ;;
+}
+
+
+/****************************************************************************
+ Open a file with a share mode - old method.
****************************************************************************/
files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
- int share_mode,int ofun, uint32 new_dos_mode, int oplock_request,
- int *Access,int *action)
+ int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action)
{
- return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode,
- oplock_request, Access, action);
+ return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode,
+ oplock_request, Access, action);
}
/****************************************************************************
- Open a file with a share mode.
+ Open a file with a share mode - called from NTCreateAndX.
****************************************************************************/
files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
- uint32 desired_access,
- int share_mode,int ofun, uint32 new_dos_mode,
- int oplock_request,
- int *Access,int *paction)
+ uint32 desired_access,
+ int share_mode,int ofun, mode_t mode,int oplock_request,
+ int *Access,int *action)
{
int flags=0;
int flags2=0;
@@ -810,18 +817,14 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
int open_mode=0;
uint16 port = 0;
mode_t new_mode = (mode_t)0;
- int action;
- uint32 existing_dos_mode = 0;
- /* We add aARCH to this as this mode is only used if the file is created new. */
- mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
if (conn->printer) {
- /* printers are handled completely differently. Most of the passed parameters are
- ignored */
+ /* printers are handled completely differently. Most
+ of the passed parameters are ignored */
if (Access)
*Access = DOS_OPEN_WRONLY;
if (action)
- *paction = FILE_WAS_CREATED;
+ *action = FILE_WAS_CREATED;
return print_fsp_open(conn, fname);
}
@@ -829,19 +832,14 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
if(!fsp)
return NULL;
- DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
- fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request ));
+ DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
+ fname, share_mode, ofun, (int)mode, oplock_request ));
if (!check_name(fname,conn)) {
file_free(fsp);
return NULL;
}
- new_dos_mode &= SAMBA_ATTRIBUTES_MASK;
- if (file_existed) {
- existing_dos_mode = dos_mode(conn, fname, psbuf);
- }
-
/* ignore any oplock requests if oplocks are disabled */
if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
oplock_request = 0;
@@ -866,11 +864,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
fname ));
file_free(fsp);
- if (S_ISDIR(psbuf->st_mode)) {
- errno = EISDIR;
- } else {
- errno = EEXIST;
- }
+ errno = EEXIST;
return NULL;
}
@@ -882,11 +876,9 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
/* We only care about matching attributes on file exists and truncate. */
if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
- if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode,
- psbuf->st_mode, mode, &new_mode)) {
- DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
- fname, existing_dos_mode, new_dos_mode,
- (int)psbuf->st_mode, (int)mode ));
+ if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
+ DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
+ fname, psbuf->st_mode, mode ));
file_free(fsp);
errno = EACCES;
return NULL;
@@ -930,7 +922,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
#endif /* O_SYNC */
if (flags != O_RDONLY && file_existed &&
- (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) {
+ (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
if (!fcbopen) {
DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
fname, !CAN_WRITE(conn) ? "share" : "file" ));
@@ -955,10 +947,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
lock_share_entry(conn, dev, inode);
- num_share_modes = open_mode_check(conn, fname, dev, inode,
- desired_access,
- share_mode,
- &flags, &oplock_request, &all_current_opens_are_level_II);
+ num_share_modes = open_mode_check(conn, fname, dev, inode,
+ desired_access, share_mode,
+ &flags, &oplock_request, &all_current_opens_are_level_II);
+
if(num_share_modes == -1) {
/*
@@ -1003,7 +995,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
*/
if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
- (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
+ (def_acl = directory_has_default_acl(conn, dos_to_unix_static(parent_dirname(fname)))))
mode = 0777;
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
@@ -1036,22 +1028,11 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
if (!file_existed) {
- /*
- * Now the file exists and fsp is successfully opened,
- * fsp->dev and fsp->inode are valid and should replace the
- * dev=0,inode=0 from a non existent file. Spotted by
- * Nadav Danieli <nadavd@exanet.com>. JRA.
- */
-
- dev = fsp->dev;
- inode = fsp->inode;
-
lock_share_entry_fsp(fsp);
- num_share_modes = open_mode_check(conn, fname, dev, inode,
- desired_access,
- share_mode,
- &flags, &oplock_request, &all_current_opens_are_level_II);
+ num_share_modes = open_mode_check(conn, fname, dev, inode,
+ desired_access, share_mode,
+ &flags, &oplock_request, &all_current_opens_are_level_II);
if(num_share_modes == -1) {
unlock_share_entry_fsp(fsp);
@@ -1095,7 +1076,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
/*
* We are modifing the file after open - update the stat struct..
*/
- if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
+ if ((truncate_unless_locked(conn,fsp) == -1) || (vfs_fstat(fsp,fsp->fd,psbuf)==-1)) {
unlock_share_entry_fsp(fsp);
fd_close(conn,fsp);
file_free(fsp);
@@ -1121,19 +1102,16 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
- if (Access) {
+ if (Access)
(*Access) = open_mode;
- }
-
- if (file_existed && !(flags2 & O_TRUNC))
- action = FILE_WAS_OPENED;
- if (file_existed && (flags2 & O_TRUNC))
- action = FILE_WAS_OVERWRITTEN;
- if (!file_existed)
- action = FILE_WAS_CREATED;
- if (paction) {
- *paction = action;
+ if (action) {
+ if (file_existed && !(flags2 & O_TRUNC))
+ *action = FILE_WAS_OPENED;
+ if (!file_existed)
+ *action = FILE_WAS_CREATED;
+ if (file_existed && (flags2 & O_TRUNC))
+ *action = FILE_WAS_OVERWRITTEN;
}
/*
@@ -1168,23 +1146,16 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
}
- if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
- /* Files should be initially set as archive */
- if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
- file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
- }
- }
-
/*
* Take care of inherited ACLs on created files - if default ACL not
* selected.
*/
- if (!file_existed && !def_acl) {
+ if (!file_existed && !def_acl && (conn->vfs_ops.fchmod_acl != NULL)) {
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
- if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
+ if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
errno = saved_errno; /* Ignore ENOSYS */
} else if (new_mode) {
@@ -1193,9 +1164,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
/* Attributes need changing. File already existed. */
- {
+ if (conn->vfs_ops.fchmod_acl != NULL) {
int saved_errno = errno; /* We might get ENOSYS in the next call.. */
- ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
+ ret = conn->vfs_ops.fchmod_acl(fsp, fsp->fd, new_mode);
if (ret == -1 && errno == ENOSYS) {
errno = saved_errno; /* Ignore ENOSYS */
@@ -1206,7 +1177,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
}
- if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
+ if ((ret == -1) && (conn->vfs_ops.fchmod(fsp, fsp->fd, new_mode) == -1))
DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
fname, (int)new_mode));
}
@@ -1268,7 +1239,7 @@ int close_file_fchmod(files_struct *fsp)
****************************************************************************/
files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
- uint32 desired_access, int share_mode, int smb_ofun, int *action)
+ uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
{
extern struct current_user current_user;
BOOL got_stat = False;
@@ -1278,6 +1249,8 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
if(!fsp)
return NULL;
+ fsp->conn = conn; /* The vfs_fXXX() macros need this. */
+
if (VALID_STAT(*psbuf))
got_stat = True;
@@ -1312,32 +1285,14 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return NULL;
}
- if (ms_has_wild(fname)) {
- file_free(fsp);
- DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
- return NULL;
- }
-
- if( strchr_m(fname, ':')) {
- file_free(fsp);
- DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY;
- return NULL;
- }
-
- if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
+ if(vfs_mkdir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
return NULL;
}
- if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
+ if(vfs_stat(conn,fname, psbuf) != 0) {
file_free(fsp);
return NULL;
}
@@ -1352,7 +1307,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
*/
if(!got_stat) {
- DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
+ DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
return NULL;
@@ -1378,7 +1333,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->dev = psbuf->st_dev;
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
- fsp->file_pid = global_smbpid;
+ fsp->pos = -1;
fsp->can_lock = True;
fsp->can_read = False;
fsp->can_write = False;
@@ -1389,9 +1344,8 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
- fsp->is_stat = False;
fsp->directory_delete_on_close = False;
- string_set(&fsp->fsp_name,fname);
+ fsp->conn = conn;
if (delete_on_close) {
NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
@@ -1401,6 +1355,17 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return NULL;
}
}
+
+ /*
+ * Note that the file name here is the *untranslated* name
+ * ie. it is still in the DOS codepage sent from the client.
+ * All use of this filename will pass though the sys_xxxx
+ * functions which will do the dos_to_unix translation before
+ * mapping into a UNIX filename. JRA.
+ */
+ string_set(&fsp->fsp_name,fname);
+ fsp->wbmpx_ptr = NULL;
+
conn->num_files_open++;
return fsp;
@@ -1426,6 +1391,8 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_ST
if(!fsp)
return NULL;
+ fsp->conn = conn; /* The vfs_fXXX() macros need this. */
+
DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
/*
@@ -1441,7 +1408,7 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->dev = (SMB_DEV_T)0;
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
- fsp->file_pid = global_smbpid;
+ fsp->pos = -1;
fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;
@@ -1454,6 +1421,7 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->is_directory = False;
fsp->is_stat = True;
fsp->directory_delete_on_close = False;
+ fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
conn->num_files_open++;
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 19e6956d9ef..964a292464f 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.x
oplock processing
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998 - 2001
@@ -80,8 +81,8 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
fd_set fds;
int selrtn = -1;
- FD_ZERO(&fds);
smb_read_error = 0;
+ FD_ZERO(&fds);
/*
* We need to check for kernel oplocks before going into the select
@@ -167,7 +168,7 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
* Read a loopback udp message.
*/
msg_len = sys_recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
- buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen);
+ buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen);
if(msg_len < 0) {
DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
@@ -606,7 +607,7 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
prepare_break_message( outbuf, fsp, False);
if (!send_smb(smbd_server_fd(), outbuf))
- exit_server("oplock_break_level2: send_smb failed.");
+ exit_server("oplock_break_level2: send_smb failed.\n");
}
/*
@@ -660,7 +661,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
time_t start_time;
BOOL shutdown_server = False;
BOOL oplock_timeout = False;
- BOOL sign_state;
connection_struct *saved_user_conn;
connection_struct *saved_fsp_conn;
int saved_vuid;
@@ -743,16 +743,8 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
/* Remember if we just sent a break to level II on this file. */
fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
- /* Save the server smb signing state. */
- sign_state = srv_oplock_set_signing(False);
-
- if (!send_smb(smbd_server_fd(), outbuf)) {
- srv_oplock_set_signing(sign_state);
- exit_server("oplock_break: send_smb failed.");
- }
-
- /* Restore the sign state to what it was. */
- srv_oplock_set_signing(sign_state);
+ if (!send_smb(smbd_server_fd(), outbuf))
+ exit_server("oplock_break: send_smb failed.\n");
/* We need this in case a readraw crosses on the wire. */
global_oplock_break = True;
@@ -800,9 +792,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
} else if (smb_read_error == READ_ERROR) {
DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
shutdown_server = True;
- } else if (smb_read_error == READ_BAD_SIG) {
- DEBUG( 0, ("oplock_break: bad signature from client\n" ));
- shutdown_server = True;
} else if (smb_read_error == READ_TIMEOUT) {
DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n", OPLOCK_BREAK_TIMEOUT ) );
oplock_timeout = True;
@@ -878,9 +867,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
remove_oplock(fsp,True);
-#if FASCIST_OPLOCK_BACKOFF
global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
-#endif
}
/*
diff --git a/source/smbd/oplock_irix.c b/source/smbd/oplock_irix.c
index ffcf3d0af4d..3576c768fef 100644
--- a/source/smbd/oplock_irix.c
+++ b/source/smbd/oplock_irix.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.x
IRIX kernel oplock processing
Copyright (C) Andrew Tridgell 1992-1998
diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c
index 5de9dd56e68..5607b55e19d 100644
--- a/source/smbd/oplock_linux.c
+++ b/source/smbd/oplock_linux.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
kernel oplock processing for Linux
Copyright (C) Andrew Tridgell 2000
@@ -133,7 +134,7 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l
fsp = file_find_fd(fd);
fd_pending_array[0] = (SIG_ATOMIC_T)-1;
if (signals_received > 1)
- memmove((void *)&fd_pending_array[0], (void *)&fd_pending_array[1],
+ memmove((void *)&fd_pending_array[0], (void *)&fd_pending_array[1],
sizeof(SIG_ATOMIC_T)*(signals_received-1));
signals_received--;
/* now we can receive more signals */
@@ -226,8 +227,8 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i
{
/* Ensure that the msg length is correct. */
if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %lu).\n",
- msg_len, (unsigned long)KERNEL_OPLOCK_BREAK_MSG_LEN));
+ DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %d).\n",
+ msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
return False;
}
@@ -279,12 +280,9 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return NULL;
}
- ZERO_STRUCT(act);
-
act.sa_handler = NULL;
act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO;
- sigemptyset( &act.sa_mask );
if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n"));
return NULL;
@@ -297,9 +295,6 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
koplocks.msg_waiting = linux_oplock_msg_waiting;
koplocks.notification_fd = -1;
- /* the signal can start off blocked due to a bug in bash */
- BlockSignals(False, RT_SIGNAL_LEASE);
-
DEBUG(3,("Linux kernel oplocks enabled\n"));
return &koplocks;
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 141af82edc8..c82f58377c6 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Password and authentication handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -20,18 +21,67 @@
#include "includes.h"
+extern int Protocol;
+
/* users from session setup */
-static char *session_userlist = NULL;
-static int len_session_userlist = 0;
+static pstring session_users="";
+
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
+/*
+ * track the machine trust account password timeout when
+ * in domain mode security
+ */
+BOOL global_machine_password_needs_changing = False;
+
+/* Data to do lanman1/2 password challenge. */
+static unsigned char saved_challenge[8];
+static BOOL challenge_sent=False;
+
+/*******************************************************************
+Get the next challenge value - no repeats.
+********************************************************************/
+
+void generate_next_challenge(char *challenge)
+{
+ unsigned char buf[8];
+
+ generate_random_buffer(buf,8,False);
+
+ memcpy(saved_challenge, buf, 8);
+ memcpy(challenge,buf,8);
+ challenge_sent = True;
+}
+
+/*******************************************************************
+ Set the last challenge sent, usually from a password server.
+********************************************************************/
+
+BOOL set_challenge(unsigned char *challenge)
+{
+ memcpy(saved_challenge,challenge,8);
+ challenge_sent = True;
+ return(True);
+}
+
+/*******************************************************************
+ Get the last challenge sent.
+********************************************************************/
+
+static BOOL last_challenge(unsigned char *challenge)
+{
+ if (!challenge_sent)
+ return(False);
+ memcpy(challenge,saved_challenge,8);
+ return(True);
+}
/* this holds info on user ids that are already validated for this VC */
static user_struct *validated_users;
static int next_vuid = VUID_OFFSET;
static int num_validated_vuids;
-extern userdom_struct current_user_info;
-
-
/****************************************************************************
Check if a uid has been validated, and return an pointer to the user_struct
if it has. NULL if not. vuid is biased by an offset. This allows us to
@@ -68,28 +118,14 @@ void invalidate_vuid(uint16 vuid)
if (vuser == NULL)
return;
-
- SAFE_FREE(vuser->homedir);
- SAFE_FREE(vuser->unix_homedir);
- SAFE_FREE(vuser->logon_script);
-
- session_yield(vuser);
- SAFE_FREE(vuser->session_keystr);
- free_server_info(&vuser->server_info);
-
- data_blob_free(&vuser->session_key);
+ session_yield(vuid);
DLIST_REMOVE(validated_users, vuser);
- /* clear the vuid from the 'cache' on each connection, and
- from the vuid 'owner' of connections */
- conn_clear_vuid_cache(vuid);
-
SAFE_FREE(vuser->groups);
delete_nt_token(&vuser->nt_user_token);
- destroy_privilege(&vuser->privs);
- SAFE_FREE(vuser);
+ safe_free(vuser);
num_validated_vuids--;
}
@@ -108,46 +144,149 @@ void invalidate_all_vuids(void)
}
}
-/**
- * register that a valid login has been performed, establish 'session'.
- * @param server_info The token returned from the authentication process.
- * (now 'owned' by register_vuid)
- *
- * @param session_key The User session key for the login session (now also 'owned' by register_vuid)
- *
- * @param respose_blob The NT challenge-response, if available. (May be freed after this call)
- *
- * @param smb_name The untranslated name of the user
- *
- * @return Newly allocated vuid, biased by an offset. (This allows us to
- * tell random client vuid's (normally zero) from valid vuids.)
- *
- */
-
-int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name)
+/****************************************************************************
+ Return a validated username.
+****************************************************************************/
+
+char *validated_username(uint16 vuid)
+{
+ user_struct *vuser = get_valid_user_struct(vuid);
+ if (vuser == NULL)
+ return 0;
+ return(vuser->user.unix_name);
+}
+
+/****************************************************************************
+ Return a validated domain.
+****************************************************************************/
+
+char *validated_domain(uint16 vuid)
+{
+ user_struct *vuser = get_valid_user_struct(vuid);
+ if (vuser == NULL)
+ return 0;
+ return(vuser->user.domain);
+}
+
+/****************************************************************************
+ Create the SID list for this user.
+****************************************************************************/
+
+NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok)
+{
+ extern DOM_SID global_sid_World;
+ extern DOM_SID global_sid_Network;
+ extern DOM_SID global_sid_Builtin_Guests;
+ extern DOM_SID global_sid_Authenticated_Users;
+ NT_USER_TOKEN *token;
+ DOM_SID *psids;
+ int i, psid_ndx = 0;
+ size_t num_sids = 0;
+ fstring sid_str;
+
+ if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
+ return NULL;
+
+ ZERO_STRUCTP(token);
+
+ /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */
+ num_sids = 5 + ngroups;
+
+ if (sup_tok && sup_tok->num_sids)
+ num_sids += sup_tok->num_sids;
+
+ if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) {
+ SAFE_FREE(token);
+ return NULL;
+ }
+
+ psids = token->user_sids;
+
+ /*
+ * Note - user SID *MUST* be first in token !
+ * se_access_check depends on this.
+ */
+
+ uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid);
+ psid_ndx++;
+
+ /*
+ * Primary group SID is second in token. Convention.
+ */
+
+ gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid);
+ psid_ndx++;
+
+ /* Now add the group SIDs. */
+
+ for (i = 0; i < ngroups; i++) {
+ if (groups[i] != gid) {
+ gid_to_sid( &psids[psid_ndx++], groups[i]);
+ }
+ }
+
+ /* Now add the additional SIDs from the supplimentary token. */
+ if (sup_tok) {
+ for (i = 0; i < sup_tok->num_sids; i++)
+ sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] );
+ }
+
+ /*
+ * Finally add the "standard" SIDs.
+ * The only difference between guest and "anonymous" (which we
+ * don't really support) is the addition of Authenticated_Users.
+ */
+
+ sid_copy( &psids[psid_ndx++], &global_sid_World);
+ sid_copy( &psids[psid_ndx++], &global_sid_Network);
+
+ if (is_guest)
+ sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests);
+ else
+ sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users);
+
+ token->num_sids = psid_ndx;
+
+ /* Dump list of sids in token */
+
+ for (i = 0; i < token->num_sids; i++) {
+ DEBUG(5, ("user token sid %s\n",
+ sid_to_string(sid_str, &token->user_sids[i])));
+ }
+
+ return token;
+}
+
+/****************************************************************************
+ Register a uid/name pair as being valid and that a valid password
+ has been given. vuid is biased by an offset. This allows us to
+ tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+
+int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
+ char *domain,BOOL guest, NT_USER_TOKEN **pptok)
{
user_struct *vuser = NULL;
+ struct passwd *pwfile; /* for getting real name from passwd file */
/* Ensure no vuid gets registered in share level security. */
- if(lp_security() == SEC_SHARE) {
- data_blob_free(&session_key);
+ if(lp_security() == SEC_SHARE)
return UID_FIELD_INVALID;
- }
/* Limit allowed vuids to 16bits - VUID_OFFSET. */
- if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
- data_blob_free(&session_key);
+ if (num_validated_vuids >= 0xFFFF-VUID_OFFSET)
return UID_FIELD_INVALID;
- }
if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) {
DEBUG(0,("Failed to malloc users struct!\n"));
- data_blob_free(&session_key);
return UID_FIELD_INVALID;
}
ZERO_STRUCTP(vuser);
+ DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)uid, (unsigned int)gid,
+ unix_name, requested_name, domain, guest ));
+
/* Allocate a free vuid. Yes this is a linear search... :-) */
while( get_valid_user_struct(next_vuid) != NULL ) {
next_vuid++;
@@ -159,218 +298,355 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key,
DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid ));
vuser->vuid = next_vuid;
-
- /* the next functions should be done by a SID mapping system (SMS) as
- * the new real sam db won't have reference to unix uids or gids
+ vuser->uid = uid;
+ vuser->gid = gid;
+ vuser->guest = guest;
+ fstrcpy(vuser->user.unix_name,unix_name);
+ fstrcpy(vuser->user.smb_name,requested_name);
+ fstrcpy(vuser->user.domain,domain);
+
+ vuser->n_groups = 0;
+ vuser->groups = NULL;
+
+ /* Find all the groups this uid is in and store them.
+ Used by change_to_user() */
+ initialise_groups(unix_name, uid, gid);
+ get_current_groups( vuser->gid, &vuser->n_groups, &vuser->groups);
+
+#ifdef HAVE_GETGROUPS_TOO_MANY_EGIDS
+ /*
+ * Under OSes to which this applies, we get GID 0 as the first
+ * element of vuser->groups, so we put GID back in there.
+ * It is ignored by setgroups
*/
-
- vuser->uid = server_info->uid;
- vuser->gid = server_info->gid;
-
- vuser->n_groups = server_info->n_groups;
- if (vuser->n_groups) {
- if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) {
- DEBUG(0,("register_vuid: failed to memdup vuser->groups\n"));
- data_blob_free(&session_key);
- free(vuser);
- free_server_info(&server_info);
- return UID_FIELD_INVALID;
- }
+ if (vuser->n_groups) vuser->groups[0] = gid;
+#endif /* HAVE_GETGROUPS_TOO_MANY_EGIDS */
+
+ if (*pptok)
+ add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, pptok);
+
+ /* Create an NT_USER_TOKEN struct for this user. */
+ vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest, *pptok);
+
+ next_vuid++;
+ num_validated_vuids++;
+
+ DLIST_ADD(validated_users, vuser);
+
+ DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
+
+ DEBUG(3, ("Clearing default real name\n"));
+ if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
+ DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
+ fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
+ }
+
+ if (!session_claim(vuser->vuid)) {
+ DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid));
+ invalidate_vuid(vuser->vuid);
+ return -1;
}
- vuser->guest = server_info->guest;
- fstrcpy(vuser->user.unix_name, server_info->unix_name);
+ return vuser->vuid;
+}
- /* This is a potentially untrusted username */
- alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", sizeof(vuser->user.smb_name));
+/****************************************************************************
+ Add a name to the session users list.
+****************************************************************************/
- fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account));
- fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account));
+void add_session_user(char *user)
+{
+ fstring suser;
+ StrnCpy(suser,user,sizeof(suser)-1);
- {
- /* Keep the homedir handy */
- const char *homedir = pdb_get_homedir(server_info->sam_account);
- const char *logon_script = pdb_get_logon_script(server_info->sam_account);
-
- if (!IS_SAM_DEFAULT(server_info->sam_account, PDB_UNIXHOMEDIR)) {
- const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account);
- if (unix_homedir) {
- vuser->unix_homedir = smb_xstrdup(unix_homedir);
- }
- } else {
- struct passwd *passwd = getpwnam_alloc(vuser->user.unix_name);
- if (passwd) {
- vuser->unix_homedir = smb_xstrdup(passwd->pw_dir);
- passwd_free(&passwd);
- }
- }
-
- if (homedir) {
- vuser->homedir = smb_xstrdup(homedir);
- }
- if (logon_script) {
- vuser->logon_script = smb_xstrdup(logon_script);
+ if (!Get_Pwnam(suser,True))
+ return;
+
+ if (suser && *suser && !in_list(suser,session_users,False)) {
+ if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
+ DEBUG(1,("Too many session users??\n"));
+ else {
+ pstrcat(session_users," ");
+ pstrcat(session_users,suser);
}
}
+}
- vuser->session_key = session_key;
+/****************************************************************************
+ Update the encrypted smbpasswd file from the plaintext username and password.
+*****************************************************************************/
- DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n",
- (unsigned int)vuser->uid,
- (unsigned int)vuser->gid,
- vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, vuser->guest ));
+static BOOL update_smbpassword_file(char *user, char *password)
+{
+ SAM_ACCOUNT *sampass = NULL;
+ BOOL ret;
- DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name));
+ pdb_init_sam(&sampass);
+
+ become_root();
+ ret = pdb_getsampwnam(sampass, user);
+ unbecome_root();
- if (server_info->ptok) {
- vuser->nt_user_token = dup_nt_token(server_info->ptok);
- } else {
- DEBUG(1, ("server_info does not contain a user_token - cannot continue\n"));
- free_server_info(&server_info);
- data_blob_free(&session_key);
- SAFE_FREE(vuser->homedir);
- SAFE_FREE(vuser->unix_homedir);
- SAFE_FREE(vuser->logon_script);
-
- SAFE_FREE(vuser);
- return UID_FIELD_INVALID;
+ if(!ret) {
+ DEBUG(0,("update_smbpassword_file: pdb_getsampwnam failed to locate %s\n", user));
+ return False;
}
- if (server_info->privs) {
- init_privilege(&(vuser->privs));
- dup_priv_set(vuser->privs, server_info->privs);
+ /*
+ * Remove the account disabled flag - we are updating the
+ * users password from a login.
+ */
+ pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED);
+
+ /* Here, the flag is one, because we want to ignore the
+ XXXXXXX'd out password */
+ ret = change_oem_password( sampass, password, True);
+ if (ret == False) {
+ DEBUG(3,("change_oem_password returned False\n"));
}
+
+ if (sampass)
+ pdb_free_sam(sampass);
+
+ return ret;
+}
- /* use this to keep tabs on all our info from the authentication */
- vuser->server_info = server_info;
+/****************************************************************************
+ Core of smb password checking routine.
+****************************************************************************/
- DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid));
+BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8)
+{
+ /* Finish the encryption of part_passwd. */
+ unsigned char p21[21];
+ unsigned char p24[24];
- next_vuid++;
- num_validated_vuids++;
+ if (part_passwd == NULL)
+ DEBUG(10,("No password set - allowing access\n"));
- DLIST_ADD(validated_users, vuser);
+ /* No password set - always true ! */
+ if (part_passwd == NULL)
+ return True;
- if (!session_claim(vuser)) {
- DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid));
- invalidate_vuid(vuser->vuid);
- return -1;
+ memset(p21,'\0',21);
+ memcpy(p21,part_passwd,16);
+ E_P24(p21, c8, p24);
+#if DEBUG_PASSWORD
+ {
+ int i;
+ DEBUG(100,("Part password (P16) was |"));
+ for(i = 0; i < 16; i++)
+ DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Password from client was |"));
+ for(i = 0; i < 24; i++)
+ DEBUG(100,("%X ", (unsigned char)password[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Given challenge was |"));
+ for(i = 0; i < 8; i++)
+ DEBUG(100,("%X ", (unsigned char)c8[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Value from encryption was |"));
+ for(i = 0; i < 24; i++)
+ DEBUG(100,("%X ", (unsigned char)p24[i]));
+ DEBUG(100,("|\n"));
}
+#endif
+ return (memcmp(p24, password, 24) == 0);
+}
- /* Register a home dir service for this user iff
- (a) This is not a guest connection,
- (b) we have a home directory defined, and
- (c) there s not an existing static share by that name */
+/****************************************************************************
+ Do a specific test for an smb password being correct, given a smb_password and
+ the lanman and NT responses.
+****************************************************************************/
- if ( (!vuser->guest)
- && vuser->unix_homedir
- && *(vuser->unix_homedir)
- && (lp_servicenumber(vuser->user.unix_name) == -1) )
- {
- DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n",
- vuser->user.unix_name, vuser->unix_homedir));
+BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
+ uchar lm_pass[24], uchar nt_pass[24])
+{
+ uchar challenge[8];
+ char* user_name;
+ uint8 *nt_pw, *lm_pw;
- vuser->homes_snum = add_home_service(vuser->user.unix_name,
- vuser->user.unix_name, vuser->unix_homedir);
+ if (!lm_pass || !sampass)
+ return(False);
+
+ user_name = pdb_get_username(sampass);
+
+ DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",user_name));
+
+ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+ DEBUG(1,("smb_password_ok: account for user %s was disabled.\n", user_name));
+ return(False);
+ }
+
+ if (chal == NULL) {
+ DEBUG(5,("smb_password_ok: use last SMBnegprot challenge\n"));
+ if (!last_challenge(challenge)) {
+ DEBUG(1,("smb_password_ok: no challenge done - password failed\n"));
+ return False;
+ }
} else {
- vuser->homes_snum = -1;
+ DEBUG(5,("smb_password_ok: challenge received\n"));
+ memcpy(challenge, chal, 8);
}
+
+ nt_pw = pdb_get_nt_passwd(sampass);
- if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) {
- /* Try and turn on server signing on the first non-guest sessionsetup. */
- srv_set_signing(vuser->session_key, response_blob);
+ if ((Protocol >= PROTOCOL_NT1) && (nt_pw != NULL)) {
+ /* We have the NT MD4 hash challenge available - see if we can
+ use it (ie. does it exist in the smbpasswd file).
+ */
+ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
+ if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) {
+ DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n"));
+ return(True);
+ }
+ DEBUG(4,("smb_password_ok: NT MD4 password check failed\n"));
}
+
+ /* Try against the lanman password. pdb_get_lanman_passwd(sampass) == NULL
+ means no password, allow access. */
+
+ lm_pw = pdb_get_lanman_passwd(sampass);
- /* fill in the current_user_info struct */
- set_current_user_info( &vuser->user );
+ if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) {
+ DEBUG(4,("smb_password_ok: no password required for user %s\n",user_name));
+ return True;
+ }
+ if(lp_lanman_auth() && (lm_pw != NULL)) {
+ DEBUG(4,("smb_password_ok: Checking LM password\n"));
+ if(smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) {
+ DEBUG(4,("smb_password_ok: LM password check succeeded\n"));
+ return(True);
+ }
+ DEBUG(4,("smb_password_ok: LM password check failed\n"));
+ }
- return vuser->vuid;
+ return False;
}
/****************************************************************************
- Add a name to the session users list.
+ Check if a username/password is OK assuming the password is a 24 byte
+ SMB hash. Return True if the password is correct, False otherwise.
****************************************************************************/
-void add_session_user(const char *user)
+BOOL pass_check_smb(char *user, char *domain, uchar *chal,
+ uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd)
{
- fstring suser;
- struct passwd *passwd;
+ SAM_ACCOUNT *sampass = NULL;
- if (!(passwd = Get_Pwnam(user)))
- return;
+ if (!lm_pwd || !nt_pwd)
+ return(False);
- fstrcpy(suser,passwd->pw_name);
+ /* get the account information */
+ pdb_init_sam(&sampass);
+ if (!pdb_getsampwnam(sampass, user)) {
+ DEBUG(1,("Couldn't find user '%s' in passdb.\n", user));
+ pdb_free_sam(sampass);
+ return(False);
+ }
- if(!*suser)
- return;
+ /* Quit if the account was disabled. */
+ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+ DEBUG(1,("Account for user '%s' was disabled.\n", user));
+ pdb_free_sam(sampass);
+ return(False);
+ }
- if( session_userlist && in_list(suser,session_userlist,False) )
- return;
- if( !session_userlist || (strlen(suser) + strlen(session_userlist) + 2 >= len_session_userlist) ) {
- char *newlist;
+ if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) {
+ if (lp_null_passwords()) {
+ DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user));
+ pdb_free_sam(sampass);
+ return(True);
+ } else {
+ DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user));
+ pdb_free_sam(sampass);
+ return(False);
+ }
+ }
- if (len_session_userlist > 128 * PSTRING_LEN) {
- DEBUG(3,("add_session_user: session userlist already too large.\n"));
- return;
- }
- newlist = Realloc( session_userlist, len_session_userlist + PSTRING_LEN );
- if( newlist == NULL ) {
- DEBUG(1,("Unable to resize session_userlist\n"));
- return;
- }
- if (!session_userlist) {
- *newlist = '\0';
- }
- session_userlist = newlist;
- len_session_userlist += PSTRING_LEN;
+ if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) {
+ pdb_free_sam(sampass);
+ return(True);
}
- safe_strcat(session_userlist," ",len_session_userlist-1);
- safe_strcat(session_userlist,suser,len_session_userlist-1);
+ DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user));
+
+ pdb_free_sam(sampass);
+ return False;
}
/****************************************************************************
- Check if a username is valid.
+ Check if a username/password pair is OK either via the system password
+ database or the encrypted SMB password database
+ return True if the password is correct, False otherwise.
****************************************************************************/
-BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups)
+BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
{
- char **valid, **invalid;
- BOOL ret;
- valid = invalid = NULL;
- ret = True;
+ BOOL ret;
- if (lp_invalid_users(snum)) {
- str_list_copy(&invalid, lp_invalid_users(snum));
- if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) {
- if ( invalid && str_list_sub_basic(invalid, current_user_info.smb_name) ) {
- ret = !user_in_list(user, (const char **)invalid, groups, n_groups);
- }
- }
+ if ((pwlen == 0) && !lp_null_passwords()) {
+ DEBUG(4,("Null passwords not allowed.\n"));
+ return False;
}
- if (invalid)
- str_list_free (&invalid);
- if (ret && lp_valid_users(snum)) {
- str_list_copy(&valid, lp_valid_users(snum));
- if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) {
- if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) {
- ret = user_in_list(user, (const char **)valid, groups, n_groups);
- }
+ if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) {
+ /* if 24 bytes long assume it is an encrypted password */
+ uchar challenge[8];
+
+ if (!last_challenge(challenge)) {
+ DEBUG(0,("Error: challenge not done for user=%s\n", user));
+ return False;
}
- }
- if (valid)
- str_list_free (&valid);
+
+ ret = pass_check_smb(user, global_myworkgroup,
+ challenge, (uchar *)password, (uchar *)password, pwd);
+
+ /*
+ * Try with PAM (may not be compiled in - returns True if not. JRA).
+ * FIXME ! Should this be called if we're using winbindd ? What about
+ * non-local accounts ? JRA.
+ */
+
+ if (ret)
+ return (NT_STATUS_V(smb_pam_accountcheck(user)) == NT_STATUS_V(NT_STATUS_OK));
+
+ return ret;
+ }
+
+ return (pass_check(user, password, pwlen, pwd,
+ lp_update_encrypted() ?
+ update_smbpassword_file : NULL));
+}
+
+/****************************************************************************
+ Check if a username is valid
+****************************************************************************/
+
+BOOL user_ok(char *user,int snum)
+{
+ pstring valid, invalid;
+ BOOL ret;
+
+ StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)-1);
+ StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)-1);
+
+ pstring_sub(valid,"%S",lp_servicename(snum));
+ pstring_sub(invalid,"%S",lp_servicename(snum));
+
+ ret = !user_in_list(user,invalid);
+
+ if (ret && valid && *valid)
+ ret = user_in_list(user,valid);
if (ret && lp_onlyuser(snum)) {
- char **user_list = str_list_make (lp_username(snum), NULL);
- if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) {
- ret = user_in_list(user, (const char **)user_list, groups, n_groups);
- }
- if (user_list) str_list_free (&user_list);
+ char *user_list = lp_username(snum);
+ pstring_sub(user_list,"%S",lp_servicename(snum));
+ ret = user_in_list(user,user_list);
}
return(ret);
@@ -380,7 +656,7 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups)
Validate a group username entry. Return the username or NULL.
****************************************************************************/
-static char *validate_group(char *group, DATA_BLOB password,int snum)
+static char *validate_group(const char *group,char *password,int pwlen,int snum)
{
#ifdef HAVE_NETGROUP
{
@@ -388,8 +664,8 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
setnetgrent(group);
while (getnetgrent(&host, &user, &domain)) {
if (user) {
- if (user_ok(user, snum, NULL, 0) &&
- password_ok(user,password)) {
+ if (user_ok(user, snum) &&
+ password_ok(user,password,pwlen,NULL)) {
endnetgrent();
return(user);
}
@@ -399,66 +675,24 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
}
#endif
-#ifdef HAVE_GETGRENT
{
- struct group *gptr;
- setgrent();
- while ((gptr = (struct group *)getgrent())) {
- if (strequal(gptr->gr_name,group))
- break;
- }
-
- /*
- * As user_ok can recurse doing a getgrent(), we must
- * copy the member list into a pstring on the stack before
- * use. Bug pointed out by leon@eatworms.swmed.edu.
- */
-
- if (gptr) {
- pstring member_list;
- char *member;
- size_t copied_len = 0;
- int i;
-
- *member_list = '\0';
- member = member_list;
-
- for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) {
- size_t member_len = strlen(gptr->gr_mem[i]) + 1;
- if( copied_len + member_len < sizeof(pstring)) {
-
- DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i]));
-
- safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1);
- copied_len += member_len;
- member += copied_len;
- } else {
- *member = '\0';
- }
+ struct sys_userlist *user_list = get_users_in_group(group);
+ struct sys_userlist *member;
+
+ for (member = user_list; member; member = member->next) {
+ static fstring name;
+ fstrcpy(name,member->unix_name);
+ if (user_ok(name,snum) &&
+ password_ok(name,password,pwlen,NULL)) {
+ free_userlist(user_list);
+ return(&name[0]);
}
- endgrent();
-
- member = member_list;
- while (*member) {
- static fstring name;
- fstrcpy(name,member);
- if (user_ok(name,snum, NULL, 0) &&
- password_ok(name,password)) {
- endgrent();
- return(&name[0]);
- }
-
- DEBUG(10,("validate_group = member = %s\n", member));
-
- member += strlen(member) + 1;
- }
- } else {
- endgrent();
- return NULL;
+ DEBUG(10,("validate_group = member = %s\n", member->unix_name));
}
+ free_userlist(user_list);
}
-#endif
+
return(NULL);
}
@@ -467,18 +701,43 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
Note this is *NOT* used when logging on using sessionsetup_and_X.
****************************************************************************/
-BOOL authorise_login(int snum, fstring user, DATA_BLOB password,
- BOOL *guest)
+BOOL authorise_login(int snum,char *user,char *password, int pwlen,
+ BOOL *guest,BOOL *force,uint16 vuid)
{
BOOL ok = False;
-
+ user_struct *vuser = get_valid_user_struct(vuid);
+
#if DEBUG_PASSWORD
DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n",
- user,password.data));
+ user,password));
#endif
*guest = False;
+ if (GUEST_ONLY(snum))
+ *force = True;
+
+ if (!GUEST_ONLY(snum) && (lp_security() > SEC_SHARE)) {
+
+ /*
+ * We should just use the given vuid from a sessionsetup_and_X.
+ */
+
+ if (!vuser) {
+ DEBUG(1,("authorise_login: refusing user %s with no session setup\n",
+ user));
+ return False;
+ }
+
+ if (!vuser->guest && user_ok(vuser->user.unix_name,snum)) {
+ fstrcpy(user,vuser->user.unix_name);
+ *guest = False;
+ DEBUG(3,("authorise_login: ACCEPTED: validated uid ok as non-guest \
+(user=%s)\n", user));
+ return True;
+ }
+ }
+
/* there are several possibilities:
1) login as the given user with given password
2) login as a previously registered username with the given password
@@ -491,71 +750,105 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password,
if the service is guest_only then steps 1 to 5 are skipped
*/
- /* now check the list of session users */
- if (!ok) {
- char *auser;
- char *user_list = NULL;
-
- if ( session_userlist )
- user_list = strdup(session_userlist);
+ if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) {
+ /* check the given username and password */
+ if (!ok && (*user) && user_ok(user,snum)) {
+ ok = password_ok(user,password, pwlen, NULL);
+ if (ok)
+ DEBUG(3,("authorise_login: ACCEPTED: given username (%s) password ok\n",
+ user ));
+ }
- if (!user_list)
- return(False);
-
- for (auser=strtok(user_list,LIST_SEP); !ok && auser;
- auser = strtok(NULL,LIST_SEP)) {
- fstring user2;
- fstrcpy(user2,auser);
- if (!user_ok(user2,snum, NULL, 0))
- continue;
-
- if (password_ok(user2,password)) {
+ /* check for a previously registered guest username */
+ if (!ok && (vuser != 0) && vuser->guest) {
+ if (user_ok(vuser->user.unix_name,snum) &&
+ password_ok(vuser->user.unix_name, password, pwlen, NULL)) {
+ fstrcpy(user, vuser->user.unix_name);
+ vuser->guest = False;
+ DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user));
ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \
-and given password ok\n", user));
}
}
-
- SAFE_FREE(user_list);
- }
-
- /* check the user= fields and the given password */
- if (!ok && lp_username(snum)) {
- char *auser;
- pstring user_list;
- pstrcpy(user_list,lp_username(snum));
-
- pstring_sub(user_list,"%S",lp_servicename(snum));
-
- for (auser=strtok(user_list,LIST_SEP); auser && !ok;
- auser = strtok(NULL,LIST_SEP)) {
- if (*auser == '@') {
- auser = validate_group(auser+1,password,snum);
- if (auser) {
- ok = True;
- fstrcpy(user,auser);
- DEBUG(3,("authorise_login: ACCEPTED: group username \
-and given password ok (%s)\n", user));
- }
- } else {
+
+ /* now check the list of session users */
+ if (!ok) {
+ char *auser;
+ char *user_list = strdup(session_users);
+ if (!user_list)
+ return(False);
+
+ for (auser=strtok(user_list,LIST_SEP); !ok && auser;
+ auser = strtok(NULL,LIST_SEP)) {
fstring user2;
fstrcpy(user2,auser);
- if (user_ok(user2,snum, NULL, 0) && password_ok(user2,password)) {
+ if (!user_ok(user2,snum))
+ continue;
+
+ if (password_ok(user2,password, pwlen, NULL)) {
ok = True;
fstrcpy(user,user2);
- DEBUG(3,("authorise_login: ACCEPTED: user list username \
+ DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \
+and given password ok\n", user));
+ }
+ }
+
+ SAFE_FREE(user_list);
+ }
+
+ /* check for a previously validated username/password pair */
+ if (!ok && (lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest &&
+ user_ok(vuser->user.unix_name,snum)) {
+ fstrcpy(user,vuser->user.unix_name);
+ *guest = False;
+ DEBUG(3,("authorise_login: ACCEPTED: validated uid (%s) as non-guest\n",
+ user));
+ ok = True;
+ }
+
+ /* check for a rhosts entry */
+ if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) {
+ ok = True;
+ DEBUG(3,("authorise_login: ACCEPTED: hosts equiv or rhosts entry for %s\n",
+ user));
+ }
+
+ /* check the user= fields and the given password */
+ if (!ok && lp_username(snum)) {
+ char *auser;
+ pstring user_list;
+ StrnCpy(user_list,lp_username(snum),sizeof(pstring)-1);
+
+ pstring_sub(user_list,"%S",lp_servicename(snum));
+
+ for (auser=strtok(user_list,LIST_SEP); auser && !ok;
+ auser = strtok(NULL,LIST_SEP)) {
+ if (*auser == '@') {
+ auser = validate_group(auser+1,password,pwlen,snum);
+ if (auser) {
+ ok = True;
+ fstrcpy(user,auser);
+ DEBUG(3,("authorise_login: ACCEPTED: group username \
+and given password ok (%s)\n", user));
+ }
+ } else {
+ fstring user2;
+ fstrcpy(user2,auser);
+ if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL)) {
+ ok = True;
+ fstrcpy(user,user2);
+ DEBUG(3,("authorise_login: ACCEPTED: user list username \
and given password ok (%s)\n", user));
+ }
}
}
}
- }
+ } /* not guest only */
/* check for a normal guest connection */
if (!ok && GUEST_OK(snum)) {
fstring guestname;
- fstrcpy(guestname,lp_guestaccount());
- if (Get_Pwnam(guestname)) {
+ StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
+ if (Get_Pwnam(guestname,True)) {
fstrcpy(user,guestname);
ok = True;
DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n",
@@ -566,10 +859,850 @@ and given password ok (%s)\n", user));
*guest = True;
}
- if (ok && !user_ok(user, snum, NULL, 0)) {
+ if (ok && !user_ok(user,snum)) {
DEBUG(0,("authorise_login: rejected invalid user %s\n",user));
ok = False;
}
return(ok);
}
+
+/****************************************************************************
+ Read the a hosts.equiv or .rhosts file and check if it
+ allows this user from this machine.
+****************************************************************************/
+
+static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
+{
+ int plus_allowed = 1;
+ char *file_host;
+ char *file_user;
+ char **lines = file_lines_load(equiv_file, NULL, False);
+ int i;
+
+ DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
+
+ if (! lines)
+ return False;
+
+ for (i=0; lines[i]; i++) {
+ char *buf = lines[i];
+ trim_string(buf," "," ");
+
+ if (buf[0] != '#' && buf[0] != '\n') {
+ BOOL is_group = False;
+ int plus = 1;
+ char *bp = buf;
+ if (strcmp(buf, "NO_PLUS\n") == 0) {
+ DEBUG(6, ("check_user_equiv NO_PLUS\n"));
+ plus_allowed = 0;
+ } else {
+ if (buf[0] == '+') {
+ bp++;
+ if (*bp == '\n' && plus_allowed) {
+ /* a bare plus means everbody allowed */
+ DEBUG(6, ("check_user_equiv everybody allowed\n"));
+ file_lines_free(lines);
+ return True;
+ }
+ } else if (buf[0] == '-') {
+ bp++;
+ plus = 0;
+ }
+ if (*bp == '@') {
+ is_group = True;
+ bp++;
+ }
+ file_host = strtok(bp, " \t\n");
+ file_user = strtok(NULL, " \t\n");
+ DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)",
+ file_user ? file_user : "(null)" ));
+ if (file_host && *file_host) {
+ BOOL host_ok = False;
+
+#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
+ if (is_group) {
+ static char *mydomain = NULL;
+ if (!mydomain)
+ yp_get_default_domain(&mydomain);
+ if (mydomain && innetgr(file_host,remote,user,mydomain))
+ host_ok = True;
+ }
+#else
+ if (is_group) {
+ DEBUG(1,("Netgroups not configured\n"));
+ continue;
+ }
+#endif
+
+ /* is it this host */
+ /* the fact that remote has come from a call of gethostbyaddr
+ * means that it may have the fully qualified domain name
+ * so we could look up the file version to get it into
+ * a canonical form, but I would rather just type it
+ * in full in the equiv file
+ */
+ if (!host_ok && !is_group && strequal(remote, file_host))
+ host_ok = True;
+
+ if (!host_ok)
+ continue;
+
+ /* is it this user */
+ if (file_user == 0 || strequal(user, file_user)) {
+ DEBUG(5, ("check_user_equiv matched %s%s %s\n",
+ (plus ? "+" : "-"), file_host,
+ (file_user ? file_user : "")));
+ file_lines_free(lines);
+ return (plus ? True : False);
+ }
+ }
+ }
+ }
+ }
+ file_lines_free(lines);
+ return False;
+}
+
+/****************************************************************************
+ Check for a possible hosts equiv or rhosts entry for the user.
+****************************************************************************/
+
+BOOL check_hosts_equiv(char *user)
+{
+ char *fname = NULL;
+ pstring rhostsfile;
+ struct passwd *pass = Get_Pwnam(user,True);
+
+ if (!pass)
+ return(False);
+
+ fname = lp_hosts_equiv();
+
+ /* note: don't allow hosts.equiv on root */
+ if (fname && *fname && (pass->pw_uid != 0)) {
+ if (check_user_equiv(user,client_name(),fname))
+ return(True);
+ }
+
+ if (lp_use_rhosts()) {
+ char *home = get_user_service_home_dir(user);
+ if (home) {
+ slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+ if (check_user_equiv(user,client_name(),rhostsfile))
+ return(True);
+ }
+ }
+
+ return(False);
+}
+
+/****************************************************************************
+ Return the client state structure.
+****************************************************************************/
+
+struct cli_state *server_client(void)
+{
+ static struct cli_state pw_cli;
+ return &pw_cli;
+}
+
+/****************************************************************************
+ Support for server level security.
+****************************************************************************/
+
+struct cli_state *server_cryptkey(void)
+{
+ struct cli_state *cli;
+ fstring desthost;
+ struct in_addr dest_ip;
+ char *pserver;
+ const char *p;
+ BOOL connected_ok = False;
+
+ cli = server_client();
+
+ if (!cli_initialise(cli))
+ return NULL;
+
+ pserver = strdup(lp_passwordserver());
+ p = pserver;
+
+ while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
+ standard_sub_basic(desthost,sizeof(desthost));
+ strupper(desthost);
+
+ if(!resolve_name( desthost, &dest_ip, 0x20)) {
+ DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
+ continue;
+ }
+
+ if (ismyip(dest_ip)) {
+ DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
+ continue;
+ }
+
+ if (cli_connect(cli, desthost, &dest_ip)) {
+ DEBUG(3,("connected to password server %s\n",desthost));
+ connected_ok = True;
+ break;
+ }
+ }
+
+ SAFE_FREE(pserver);
+
+ if (!connected_ok) {
+ DEBUG(0,("password server not available\n"));
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip)) {
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ DEBUG(3,("got session\n"));
+
+ if (!cli_negprot(cli)) {
+ DEBUG(1,("%s rejected the negprot\n",desthost));
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ if (cli->protocol < PROTOCOL_LANMAN2 ||
+ !(cli->sec_mode & 1)) {
+ DEBUG(1,("%s isn't in user level security mode\n",desthost));
+ cli_shutdown(cli);
+ return NULL;
+ }
+
+ DEBUG(3,("password server OK\n"));
+
+ return cli;
+}
+
+/****************************************************************************
+ Validate a password with the password server.
+****************************************************************************/
+
+BOOL server_validate(char *user, char *domain,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen)
+{
+ struct cli_state *cli;
+ static unsigned char badpass[24];
+ static fstring baduser;
+ static BOOL tested_password_server = False;
+ static BOOL bad_password_server = False;
+
+ cli = server_client();
+
+ if (!cli->initialised) {
+ DEBUG(1,("password server %s is not connected\n", cli->desthost));
+ return(False);
+ }
+
+ if(badpass[0] == 0)
+ memset(badpass, 0x1f, sizeof(badpass));
+
+ if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) {
+ /*
+ * Very unlikely, our random bad password is the same as the users
+ * password.
+ */
+ memset(badpass, badpass[0]+1, sizeof(badpass));
+ }
+
+ if(baduser[0] == 0) {
+ fstrcpy(baduser, INVALID_USER_PREFIX);
+ fstrcat(baduser, global_myname);
+ }
+
+ /*
+ * Attempt a session setup with a totally incorrect password.
+ * If this succeeds with the guest bit *NOT* set then the password
+ * server is broken and is not correctly setting the guest bit. We
+ * need to detect this as some versions of NT4.x are broken. JRA.
+ */
+
+ if(!tested_password_server) {
+ if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass),
+ (char *)badpass, sizeof(badpass), domain)) {
+
+ /*
+ * We connected to the password server so we
+ * can say we've tested it.
+ */
+ tested_password_server = True;
+
+ if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) {
+ DEBUG(0,("server_validate: password server %s allows users as non-guest \
+with a bad password.\n", cli->desthost));
+ DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \
+use this machine as the password server.\n"));
+ cli_ulogoff(cli);
+
+ /*
+ * Password server has the bug.
+ */
+ bad_password_server = True;
+ return False;
+ }
+ cli_ulogoff(cli);
+ }
+ } else {
+
+ /*
+ * We have already tested the password server.
+ * Fail immediately if it has the bug.
+ */
+
+ if(bad_password_server) {
+ DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \
+with a bad password.\n", cli->desthost));
+ DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \
+use this machine as the password server.\n"));
+ return False;
+ }
+ }
+
+ /*
+ * Now we know the password server will correctly set the guest bit, or is
+ * not guest enabled, we can try with the real password.
+ */
+
+ if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
+ DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+ return False;
+ }
+
+ /* if logged in as guest then reject */
+ if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {
+ DEBUG(1,("password server %s gave us guest only\n", cli->desthost));
+ cli_ulogoff(cli);
+ return(False);
+ }
+
+ cli_ulogoff(cli);
+
+ return(True);
+}
+
+static char *mutex_server_name;
+
+static BOOL grab_server_mutex(const char *name)
+{
+ mutex_server_name = strdup(name);
+ if (!mutex_server_name) {
+ DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name));
+ return False;
+ }
+ if (!secrets_named_mutex(name, 10)) {
+ DEBUG(10,("grab_server_mutex: failed for %s\n", name));
+ SAFE_FREE(mutex_server_name);
+ return False;
+ }
+
+ return True;
+}
+
+static void release_server_mutex(void)
+{
+ if (mutex_server_name) {
+ secrets_named_mutex_release(mutex_server_name);
+ SAFE_FREE(mutex_server_name);
+ }
+}
+
+/***********************************************************************
+ Connect to a remote machine for domain security authentication
+ given a name or IP address.
+************************************************************************/
+
+static BOOL connect_to_domain_password_server(struct cli_state **ppcli,
+ char *server, unsigned char *trust_passwd)
+{
+ struct in_addr dest_ip;
+ fstring remote_machine;
+ struct cli_state *pcli = NULL;
+
+ *ppcli = NULL;
+
+ if(!(pcli = cli_initialise(NULL))) {
+ DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n"));
+ return False;
+ }
+
+ if (is_ipaddress(server)) {
+ struct in_addr to_ip;
+
+ /* we shouldn't have 255.255.255.255 forthe IP address of a password server anyways */
+ if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) {
+ DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server));
+ cli_shutdown(pcli);
+ return False;
+ }
+
+ if (!name_status_find("*", 0, 0x20, to_ip, remote_machine)) {
+ DEBUG(1, ("connect_to_domain_password_server: Can't " "resolve name for IP %s\n", server));
+ cli_shutdown(pcli);
+ return False;
+ }
+ } else {
+ fstrcpy(remote_machine, server);
+ }
+
+ standard_sub_basic(remote_machine,sizeof(remote_machine));
+ strupper(remote_machine);
+
+ if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
+ DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine));
+ cli_shutdown(pcli);
+ return False;
+ }
+
+ if (ismyip(dest_ip)) {
+ DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
+ remote_machine));
+ cli_shutdown(pcli);
+ return False;
+ }
+
+ /* we use a mutex to prevent two connections at once - when a NT PDC gets
+ two connections where one hasn't completed a negprot yet it will send a
+ TCP reset to the first connection (tridge) */
+
+ if (!grab_server_mutex(server)) {
+ cli_shutdown(pcli);
+ return False;
+ }
+
+ if (!cli_connect(pcli, remote_machine, &dest_ip)) {
+ DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) {
+ DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \
+session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ pcli->protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(pcli)) {
+ DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ if (pcli->protocol != PROTOCOL_NT1) {
+ DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n",
+ remote_machine));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ if (!(pcli->sec_mode & 1)) {
+ DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n",
+ remote_machine));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ /*
+ * We now have an anonymous connection to IPC$ on the domain password server.
+ */
+
+ /*
+ * Even if the connect succeeds we need to setup the netlogon
+ * pipe here. We do this as we may just have changed the domain
+ * account password on the PDC and yet we may be talking to
+ * a BDC that doesn't have this replicated yet. In this case
+ * a successful connect to a DC needs to take the netlogon connect
+ * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
+ */
+
+ if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) {
+ DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
+ cli_nt_session_close(pcli);
+ cli_ulogoff(pcli);
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ if (!NT_STATUS_IS_OK(cli_nt_setup_creds(pcli, trust_passwd))) {
+ DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
+%s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
+ cli_nt_session_close(pcli);
+ cli_ulogoff(pcli);
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return(False);
+ }
+
+ *ppcli = pcli;
+
+ /* We exit here with the mutex *locked*. JRA */
+ return True;
+}
+
+/***********************************************************************
+ Utility function to attempt a connection to an IP address of a DC.
+************************************************************************/
+
+static BOOL attempt_connect_to_dc(struct cli_state **ppcli, struct in_addr *ip, unsigned char *trust_passwd)
+{
+ fstring dc_name;
+
+ /*
+ * Ignore addresses we have already tried.
+ */
+
+ if (is_zero_ip(*ip))
+ return False;
+
+ if (!lookup_dc_name(global_myname, lp_workgroup(), ip, dc_name))
+ return False;
+
+ return connect_to_domain_password_server(ppcli, dc_name, trust_passwd);
+}
+
+/***********************************************************************
+ We have been asked to dynamcially determine the IP addresses of
+ the PDC and BDC's for this DOMAIN, and query them in turn.
+************************************************************************/
+
+static BOOL find_connect_pdc(struct cli_state **ppcli, unsigned char *trust_passwd, time_t last_change_time)
+{
+ struct in_addr *ip_list = NULL;
+ int count = 0;
+ int i;
+ BOOL connected_ok = False;
+ time_t time_now = time(NULL);
+ BOOL use_pdc_only = False;
+
+ /*
+ * If the time the machine password has changed
+ * was less than an hour ago then we need to contact
+ * the PDC only, as we cannot be sure domain replication
+ * has yet taken place. Bug found by Gerald (way to go
+ * Gerald !). JRA.
+ */
+
+ if (time_now - last_change_time < 3600)
+ use_pdc_only = True;
+
+ if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count))
+ return False;
+
+ /*
+ * Firstly try and contact a PDC/BDC who has the same
+ * network address as any of our interfaces.
+ */
+ for(i = 0; i < count; i++) {
+ if(!is_local_net(ip_list[i]))
+ continue;
+
+ if((connected_ok = attempt_connect_to_dc(ppcli, &ip_list[i], trust_passwd)))
+ break;
+
+ zero_ip(&ip_list[i]); /* Tried and failed. */
+ }
+
+ /*
+ * Secondly try and contact a random PDC/BDC.
+ */
+ if(!connected_ok) {
+ i = (sys_random() % count);
+
+ if (!is_zero_ip(ip_list[i])) {
+ if (!(connected_ok = attempt_connect_to_dc(ppcli, &ip_list[i], trust_passwd)))
+ zero_ip(&ip_list[i]); /* Tried and failed. */
+ }
+ }
+
+ /*
+ * Finally go through the IP list in turn, ignoring any addresses
+ * we have already tried.
+ */
+ if(!connected_ok) {
+ /*
+ * Try and connect to any of the other IP addresses in the PDC/BDC list.
+ * Note that from a WINS server the #1 IP address is the PDC.
+ */
+ for(i = 0; i < count; i++) {
+ if (is_zero_ip(ip_list[i]))
+ continue;
+
+ if((connected_ok = attempt_connect_to_dc(ppcli, &ip_list[i], trust_passwd)))
+ break;
+ }
+ }
+
+ SAFE_FREE(ip_list);
+ return connected_ok;
+}
+
+/***********************************************************************
+ Do the same as security=server, but using NT Domain calls and a session
+ key from the machine password.
+************************************************************************/
+
+BOOL domain_client_validate( char *user, char *domain,
+ char *smb_apasswd, int smb_apasslen,
+ char *smb_ntpasswd, int smb_ntpasslen,
+ BOOL *user_exists, NT_USER_TOKEN **pptoken)
+{
+ unsigned char local_challenge[8];
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
+ unsigned char trust_passwd[16];
+ fstring remote_machine;
+ const char *p;
+ const char *pserver;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 info3;
+ struct cli_state *pcli = NULL;
+ uint32 smb_uid_low;
+ BOOL connected_ok = False;
+ time_t last_change_time;
+ NTSTATUS status;
+
+ if (pptoken)
+ *pptoken = NULL;
+
+ if(user_exists != NULL)
+ *user_exists = True; /* Only set false on a very specific error. */
+
+ /*
+ * Check that the requested domain is not our own machine name.
+ * If it is, we should never check the PDC here, we use our own local
+ * password file.
+ */
+
+ if(strequal( domain, global_myname)) {
+ DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n"));
+ return False;
+ }
+
+ /*
+ * Next, check that the passwords given were encrypted.
+ */
+
+ if(((smb_apasslen != 24) && (smb_apasslen != 0)) ||
+ ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) {
+
+ /*
+ * Not encrypted - do so.
+ */
+
+ DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n"));
+ generate_random_buffer( local_challenge, 8, False);
+ SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response);
+ SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_response);
+ smb_apasslen = 24;
+ smb_ntpasslen = 24;
+ smb_apasswd = (char *)local_lm_response;
+ smb_ntpasswd = (char *)local_nt_response;
+ } else {
+
+ /*
+ * Encrypted - get the challenge we sent for these
+ * responses.
+ */
+
+ if (!last_challenge(local_challenge)) {
+ DEBUG(0,("domain_client_validate: no challenge done - password failed\n"));
+ return False;
+ }
+ }
+
+ /*
+ * Get the machine account password for our primary domain
+ */
+
+ if (!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd, &last_change_time)) {
+ DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", global_myworkgroup));
+ return False;
+ }
+
+ /* Test if machine password is expired and need to be changed */
+ if (lp_machine_password_timeout()) {
+ if (time(NULL) > last_change_time + lp_machine_password_timeout()) {
+ DEBUG(10,("domain_client_validate: machine account password needs changing. \
+Last change time = (%u) %s. Machine password timeout = %u seconds\n",
+ (unsigned int)last_change_time, http_timestring(last_change_time),
+ (unsigned int)lp_machine_password_timeout() ));
+ global_machine_password_needs_changing = True;
+ }
+ }
+
+ /*
+ * At this point, smb_apasswd points to the lanman response to
+ * the challenge in local_challenge, and smb_ntpasswd points to
+ * the NT response to the challenge in local_challenge. Ship
+ * these over the secure channel to a domain controller and
+ * see if they were valid.
+ */
+
+ /*
+ * Treat each name in the 'password server =' line as a potential
+ * PDC/BDC. Contact each in turn and try and authenticate.
+ */
+
+ pserver = lp_passwordserver();
+ if (! *pserver)
+ pserver = "*";
+ p = pserver;
+
+ while (!connected_ok &&
+ next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
+ if(strequal(remote_machine, "*")) {
+ connected_ok = find_connect_pdc(&pcli, trust_passwd, last_change_time);
+ } else {
+ connected_ok = connect_to_domain_password_server(&pcli, remote_machine, trust_passwd);
+ }
+ }
+
+ if (!connected_ok) {
+ DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
+ if (pcli)
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+
+ /* We really don't care what LUID we give the user. */
+ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
+
+ ZERO_STRUCT(info3);
+
+ status = cli_nt_login_network(pcli, domain, user, smb_uid_low, (char *)local_challenge,
+ ((smb_apasslen != 0) ? smb_apasswd : NULL),
+ ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL),
+ &ctr, &info3);
+
+ if (!NT_STATUS_IS_OK(status)) {
+
+ DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, get_nt_error_msg(status) ));
+ cli_nt_session_close(pcli);
+ cli_ulogoff(pcli);
+ cli_shutdown(pcli);
+ release_server_mutex();
+
+ if((NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NO_SUCH_USER)) && (user_exists != NULL))
+ *user_exists = False;
+
+ return False;
+ }
+
+ /*
+ * Here, if we really want it, we have lots of info about the user in info3.
+ */
+
+ /* Return group membership as returned by NT. This contains group
+ membership in nested groups which doesn't seem to be accessible by any
+ other means. We merge this into the NT_USER_TOKEN associated with the vuid
+ later on. */
+
+ if (pptoken && (info3.num_groups2 != 0)) {
+ NT_USER_TOKEN *ptok;
+ int i;
+
+ *pptoken = NULL;
+
+ if ((ptok = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) {
+ DEBUG(0, ("domain_client_validate: Out of memory allocating NT_USER_TOKEN\n"));
+ release_server_mutex();
+ return False;
+ }
+
+ ptok->num_sids = (size_t)info3.num_groups2 + info3.num_other_sids;
+ if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) {
+ DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n"));
+ SAFE_FREE(ptok);
+ release_server_mutex();
+ return False;
+ }
+
+ /* Group membership (including nested groups) is
+ stored here. */
+
+ for (i = 0; i < info3.num_groups2; i++) {
+ sid_copy(&ptok->user_sids[i], &info3.dom_sid.sid);
+ sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid);
+ }
+
+ /* Universal group memberships for other domains are
+ stored in the info3.other_sids field. We also need to
+ do sid filtering here. */
+
+ for (i = 0; i < info3.num_other_sids; i++)
+ sid_copy(&ptok->user_sids[info3.num_groups2 + i],
+ &info3.other_sids[i].sid);
+
+ *pptoken = ptok;
+ }
+
+#if 0
+ /*
+ * We don't actually need to do this - plus it fails currently with
+ * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
+ * send here. JRA.
+ */
+
+ if(cli_nt_logoff(pcli, &ctr) == False) {
+ DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(pcli)));
+ cli_nt_session_close(pcli);
+ cli_ulogoff(pcli);
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return False;
+ }
+#endif /* 0 */
+
+ /* Note - once the cli stream is shutdown the mem_ctx used
+ to allocate the other_sids and gids structures has been deleted - so
+ these pointers are no longer valid..... */
+
+ cli_nt_session_close(pcli);
+ cli_ulogoff(pcli);
+ cli_shutdown(pcli);
+ release_server_mutex();
+ return True;
+}
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index f7e9c595c13..2837187f4bf 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Pipe SMB reply routines
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
@@ -42,42 +43,40 @@ int reply_open_pipe_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
pstring fname;
- pstring pipe_name;
uint16 vuid = SVAL(inbuf, smb_uid);
- smb_np_struct *p;
+ pipes_struct *p;
int smb_ofun = SVAL(inbuf,smb_vwv8);
int size=0,fmode=0,mtime=0,rmode=0;
int i;
/* XXXX we need to handle passed times, sattr and flags */
- srvstr_pull_buf(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE);
+ pstrcpy(fname,smb_buf(inbuf));
/* If the name doesn't start \PIPE\ then this is directed */
/* at a mailslot or something we really, really don't understand, */
/* not just something we really don't understand. */
- if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 )
+ if ( strncmp(fname,PIPE,PIPELEN) != 0 )
return(ERROR_DOS(ERRSRV,ERRaccess));
- DEBUG(4,("Opening pipe %s.\n", pipe_name));
+ DEBUG(4,("Opening pipe %s.\n", fname));
/* See if it is one we want to handle. */
for( i = 0; pipe_names[i].client_pipe ; i++ )
- if( strequal(pipe_name,pipe_names[i].client_pipe) )
+ if( strequal(fname,pipe_names[i].client_pipe) )
break;
if (pipe_names[i].client_pipe == NULL)
return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
/* Strip \PIPE\ off the name. */
- pstrcpy(fname, pipe_name + PIPELEN);
-
+ pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
#if 0
/*
* Hack for NT printers... JRA.
*/
if(should_fail_next_srvsvc_open(fname))
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
#endif
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
@@ -115,7 +114,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
****************************************************************************/
int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
{
- smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
size_t numtowrite = SVAL(inbuf,smb_vwv1);
int nwritten;
int outsize;
@@ -153,7 +152,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
+ pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
size_t numtowrite = SVAL(inbuf,smb_vwv10);
int nwritten = -1;
int smb_doff = SVAL(inbuf, smb_vwv11);
@@ -209,13 +208,11 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
****************************************************************************/
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
+ pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
int smb_maxcnt = SVAL(inbuf,smb_vwv5);
int smb_mincnt = SVAL(inbuf,smb_vwv6);
int nread = -1;
char *data;
- BOOL unused;
-
/* we don't use the offset given to use for pipe reads. This
is deliberate, instead we always return the next lump of
data on the pipe */
@@ -229,7 +226,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
- nread = read_from_pipe(p, data, smb_maxcnt, &unused);
+ nread = read_from_pipe(p, data, smb_maxcnt);
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -249,7 +246,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
****************************************************************************/
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
{
- smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
int outsize = set_message(outbuf,0,0,True);
if (!p)
@@ -257,8 +254,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
- if (!close_rpc_pipe_hnd(p))
- return ERROR_DOS(ERRDOS,ERRbadfid);
+ if (!close_rpc_pipe_hnd(p, conn))
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
return(outsize);
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 158f1a0ede8..8edf96279d9 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -21,9 +21,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_ACLS
-
/****************************************************************************
Data structures representing the internal ACE format.
****************************************************************************/
@@ -45,446 +42,10 @@ typedef struct canon_ace {
enum ace_owner owner_type;
enum ace_attribute attr;
posix_id unix_ug;
- BOOL inherited;
} canon_ace;
#define ALL_ACE_PERMS (S_IRUSR|S_IWUSR|S_IXUSR)
-/*
- * EA format of user.SAMBA_PAI (Samba_Posix_Acl_Interitance)
- * attribute on disk.
- *
- * | 1 | 1 | 2 | 2 | ....
- * +------+------+-------------+---------------------+-------------+--------------------+
- * | vers | flag | num_entries | num_default_entries | ..entries.. | default_entries... |
- * +------+------+-------------+---------------------+-------------+--------------------+
- */
-
-#define PAI_VERSION_OFFSET 0
-#define PAI_FLAG_OFFSET 1
-#define PAI_NUM_ENTRIES_OFFSET 2
-#define PAI_NUM_DEFAULT_ENTRIES_OFFSET 4
-#define PAI_ENTRIES_BASE 6
-
-#define PAI_VERSION 1
-#define PAI_ACL_FLAG_PROTECTED 0x1
-#define PAI_ENTRY_LENGTH 5
-
-/*
- * In memory format of user.SAMBA_PAI attribute.
- */
-
-struct pai_entry {
- struct pai_entry *next, *prev;
- enum ace_owner owner_type;
- posix_id unix_ug;
-};
-
-struct pai_val {
- BOOL protected;
- unsigned int num_entries;
- struct pai_entry *entry_list;
- unsigned int num_def_entries;
- struct pai_entry *def_entry_list;
-};
-
-/************************************************************************
- Return a uint32 of the pai_entry principal.
-************************************************************************/
-
-static uint32 get_pai_entry_val(struct pai_entry *paie)
-{
- switch (paie->owner_type) {
- case UID_ACE:
- DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- return (uint32)paie->unix_ug.uid;
- case GID_ACE:
- DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- return (uint32)paie->unix_ug.gid;
- case WORLD_ACE:
- default:
- DEBUG(10,("get_pai_entry_val: world ace\n"));
- return (uint32)-1;
- }
-}
-
-/************************************************************************
- Return a uint32 of the entry principal.
-************************************************************************/
-
-static uint32 get_entry_val(canon_ace *ace_entry)
-{
- switch (ace_entry->owner_type) {
- case UID_ACE:
- DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid ));
- return (uint32)ace_entry->unix_ug.uid;
- case GID_ACE:
- DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid ));
- return (uint32)ace_entry->unix_ug.gid;
- case WORLD_ACE:
- default:
- DEBUG(10,("get_entry_val: world ace\n"));
- return (uint32)-1;
- }
-}
-
-/************************************************************************
- Count the inherited entries.
-************************************************************************/
-
-static unsigned int num_inherited_entries(canon_ace *ace_list)
-{
- unsigned int num_entries = 0;
-
- for (; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_entries++;
- return num_entries;
-}
-
-/************************************************************************
- Create the on-disk format. Caller must free.
-************************************************************************/
-
-static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL protected, size_t *store_size)
-{
- char *pai_buf = NULL;
- canon_ace *ace_list = NULL;
- char *entry_offset = NULL;
- unsigned int num_entries = 0;
- unsigned int num_def_entries = 0;
-
- for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_entries++;
-
- for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_def_entries++;
-
- DEBUG(10,("create_pai_buf: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries ));
-
- *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
-
- pai_buf = malloc(*store_size);
- if (!pai_buf) {
- return NULL;
- }
-
- /* Set up the header. */
- memset(pai_buf, '\0', PAI_ENTRIES_BASE);
- SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION);
- SCVAL(pai_buf,PAI_FLAG_OFFSET,(protected ? PAI_ACL_FLAG_PROTECTED : 0));
- SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries);
- SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
-
- entry_offset = pai_buf + PAI_ENTRIES_BASE;
-
- for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
- if (ace_list->inherited) {
- uint8 type_val = (unsigned char)ace_list->owner_type;
- uint32 entry_val = get_entry_val(ace_list);
-
- SCVAL(entry_offset,0,type_val);
- SIVAL(entry_offset,1,entry_val);
- entry_offset += PAI_ENTRY_LENGTH;
- }
- }
-
- for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
- if (ace_list->inherited) {
- uint8 type_val = (unsigned char)ace_list->owner_type;
- uint32 entry_val = get_entry_val(ace_list);
-
- SCVAL(entry_offset,0,type_val);
- SIVAL(entry_offset,1,entry_val);
- entry_offset += PAI_ENTRY_LENGTH;
- }
- }
-
- return pai_buf;
-}
-
-/************************************************************************
- Store the user.SAMBA_PAI attribute on disk.
-************************************************************************/
-
-static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list,
- canon_ace *dir_ace_list, BOOL protected)
-{
- int ret;
- size_t store_size;
- char *pai_buf;
-
- if (!lp_map_acl_inherit(SNUM(fsp->conn)))
- return;
-
- /*
- * Don't store if this ACL isn't protected and
- * none of the entries in it are marked as inherited.
- */
-
- if (!protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) {
- /* Instead just remove the attribute if it exists. */
- if (fsp->fd != -1)
- SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
- else
- SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
- return;
- }
-
- pai_buf = create_pai_buf(file_ace_list, dir_ace_list, protected, &store_size);
-
- if (fsp->fd != -1)
- ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, store_size, 0);
- else
- ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, store_size, 0);
-
- SAFE_FREE(pai_buf);
-
- DEBUG(10,("store_inheritance_attribute:%s for file %s\n", protected ? " (protected)" : "", fsp->fsp_name));
- if (ret == -1 && errno != ENOSYS)
- DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
-}
-
-/************************************************************************
- Delete the in memory inheritance info.
-************************************************************************/
-
-static void free_inherited_info(struct pai_val *pal)
-{
- if (pal) {
- struct pai_entry *paie, *paie_next;
- for (paie = pal->entry_list; paie; paie = paie_next) {
- paie_next = paie->next;
- SAFE_FREE(paie);
- }
- for (paie = pal->def_entry_list; paie; paie = paie_next) {
- paie_next = paie->next;
- SAFE_FREE(paie);
- }
- SAFE_FREE(pal);
- }
-}
-
-/************************************************************************
- Was this ACL protected ?
-************************************************************************/
-
-static BOOL get_protected_flag(struct pai_val *pal)
-{
- if (!pal)
- return False;
- return pal->protected;
-}
-
-/************************************************************************
- Was this ACE inherited ?
-************************************************************************/
-
-static BOOL get_inherited_flag(struct pai_val *pal, canon_ace *ace_entry, BOOL default_ace)
-{
- struct pai_entry *paie;
-
- if (!pal)
- return False;
-
- /* If the entry exists it is inherited. */
- for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) {
- if (ace_entry->owner_type == paie->owner_type &&
- get_entry_val(ace_entry) == get_pai_entry_val(paie))
- return True;
- }
- return False;
-}
-
-/************************************************************************
- Ensure an attribute just read is valid.
-************************************************************************/
-
-static BOOL check_pai_ok(char *pai_buf, size_t pai_buf_data_size)
-{
- uint16 num_entries;
- uint16 num_def_entries;
-
- if (pai_buf_data_size < PAI_ENTRIES_BASE) {
- /* Corrupted - too small. */
- return False;
- }
-
- if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION)
- return False;
-
- num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET);
- num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
-
- /* Check the entry lists match. */
- /* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */
-
- if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size)
- return False;
-
- return True;
-}
-
-
-/************************************************************************
- Convert to in-memory format.
-************************************************************************/
-
-static struct pai_val *create_pai_val(char *buf, size_t size)
-{
- char *entry_offset;
- struct pai_val *paiv = NULL;
- int i;
-
- if (!check_pai_ok(buf, size))
- return NULL;
-
- paiv = malloc(sizeof(struct pai_val));
- if (!paiv)
- return NULL;
-
- memset(paiv, '\0', sizeof(struct pai_val));
-
- paiv->protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED);
-
- paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET);
- paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
-
- entry_offset = buf + PAI_ENTRIES_BASE;
-
- DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n",
- paiv->protected ? " (protected)" : "", paiv->num_entries, paiv->num_def_entries ));
-
- for (i = 0; i < paiv->num_entries; i++) {
- struct pai_entry *paie;
-
- paie = malloc(sizeof(struct pai_entry));
- if (!paie) {
- free_inherited_info(paiv);
- return NULL;
- }
-
- paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
- switch( paie->owner_type) {
- case UID_ACE:
- paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- break;
- case GID_ACE:
- paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- break;
- case WORLD_ACE:
- paie->unix_ug.world = -1;
- DEBUG(10,("create_pai_val: world ace\n"));
- break;
- default:
- free_inherited_info(paiv);
- return NULL;
- }
- entry_offset += PAI_ENTRY_LENGTH;
- DLIST_ADD(paiv->entry_list, paie);
- }
-
- for (i = 0; i < paiv->num_def_entries; i++) {
- struct pai_entry *paie;
-
- paie = malloc(sizeof(struct pai_entry));
- if (!paie) {
- free_inherited_info(paiv);
- return NULL;
- }
-
- paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
- switch( paie->owner_type) {
- case UID_ACE:
- paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- break;
- case GID_ACE:
- paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- break;
- case WORLD_ACE:
- paie->unix_ug.world = -1;
- DEBUG(10,("create_pai_val: (def) world ace\n"));
- break;
- default:
- free_inherited_info(paiv);
- return NULL;
- }
- entry_offset += PAI_ENTRY_LENGTH;
- DLIST_ADD(paiv->def_entry_list, paie);
- }
-
- return paiv;
-}
-
-/************************************************************************
- Load the user.SAMBA_PAI attribute.
-************************************************************************/
-
-static struct pai_val *load_inherited_info(files_struct *fsp)
-{
- char *pai_buf;
- size_t pai_buf_size = 1024;
- struct pai_val *paiv = NULL;
- ssize_t ret;
-
- if (!lp_map_acl_inherit(SNUM(fsp->conn)))
- return NULL;
-
- if ((pai_buf = malloc(pai_buf_size)) == NULL)
- return NULL;
-
- do {
- if (fsp->fd != -1)
- ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, pai_buf_size);
- else
- ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, pai_buf_size);
-
- if (ret == -1) {
- if (errno != ERANGE) {
- break;
- }
- /* Buffer too small - enlarge it. */
- pai_buf_size *= 2;
- SAFE_FREE(pai_buf);
- if ((pai_buf = malloc(pai_buf_size)) == NULL)
- return NULL;
- }
- } while (ret == -1);
-
- DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
-
- if (ret == -1) {
- /* No attribute or not supported. */
-#if defined(ENOATTR)
- if (errno != ENOATTR)
- DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
-#else
- if (errno != ENOSYS)
- DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
-#endif
- SAFE_FREE(pai_buf);
- return NULL;
- }
-
- paiv = create_pai_val(pai_buf, ret);
-
- if (paiv && paiv->protected)
- DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name));
-
- SAFE_FREE(pai_buf);
- return paiv;
-}
-
/****************************************************************************
Functions to manipulate the internal ACE format.
****************************************************************************/
@@ -545,10 +106,10 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "SID = %s ", sid_to_string( str, &pace->trustee));
if (pace->owner_type == UID_ACE) {
const char *u_name = uidtoname(pace->unix_ug.uid);
- dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name );
+ dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name);
} else if (pace->owner_type == GID_ACE) {
char *g_name = gidtoname(pace->unix_ug.gid);
- dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name );
+ dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name);
} else
dbgtext( "other ");
switch (pace->type) {
@@ -568,8 +129,6 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "SMB_ACL_OTHER ");
break;
}
- if (pace->inherited)
- dbgtext( "(inherited) ");
dbgtext( "perms ");
dbgtext( "%c", pace->perms & S_IRUSR ? 'r' : '-');
dbgtext( "%c", pace->perms & S_IWUSR ? 'w' : '-');
@@ -599,9 +158,9 @@ static mode_t convert_permset_to_mode_t(connection_struct *conn, SMB_ACL_PERMSET
{
mode_t ret = 0;
- ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0);
- ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0);
- ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0);
+ ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0);
+ ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0);
+ ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0);
return ret;
}
@@ -631,18 +190,18 @@ static mode_t unix_perms_to_acl_perms(mode_t mode, int r_mask, int w_mask, int x
static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_ACL_PERMSET_T *p_permset)
{
- if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) == -1)
+ if (conn->vfs_ops.sys_acl_clear_perms(conn, *p_permset) == -1)
return -1;
if (mode & S_IRUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1)
+ if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_READ) == -1)
return -1;
}
if (mode & S_IWUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1)
+ if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_WRITE) == -1)
return -1;
}
if (mode & S_IXUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
+ if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
return -1;
}
return 0;
@@ -884,6 +443,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
{
DOM_SID owner_sid;
DOM_SID grp_sid;
+ enum SID_NAME_USE sid_type;
*puser = (uid_t)-1;
*pgrp = (gid_t)-1;
@@ -909,7 +469,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
sid_copy(&owner_sid, psd->owner_sid);
- if (!NT_STATUS_IS_OK(sid_to_uid(&owner_sid, puser))) {
+ if (!sid_to_uid( &owner_sid, puser, &sid_type)) {
#if ACL_FORCE_UNMAPPABLE
/* this allows take ownership to work reasonably */
extern struct current_user current_user;
@@ -929,7 +489,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
sid_copy(&grp_sid, psd->grp_sid);
- if (!NT_STATUS_IS_OK(sid_to_gid( &grp_sid, pgrp))) {
+ if (!sid_to_gid( &grp_sid, pgrp, &sid_type)) {
#if ACL_FORCE_UNMAPPABLE
/* this allows take group ownership to work reasonably */
extern struct current_user current_user;
@@ -1019,7 +579,7 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
* not uids/gids.
*/
- return user_in_group_list(u_name, g_name, NULL, 0);
+ return user_in_group_list(u_name, g_name);
}
/****************************************************************************
@@ -1046,6 +606,14 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
BOOL got_other = False;
canon_ace *pace_other = NULL;
canon_ace *pace_group = NULL;
+ connection_struct *conn = fsp->conn;
+ SMB_ACL_T current_posix_acl = NULL;
+ mode_t current_user_perms = 0;
+ mode_t current_grp_perms = 0;
+ mode_t current_other_perms = 0;
+ BOOL got_current_user = False;
+ BOOL got_current_grp = False;
+ BOOL got_current_other = False;
for (pace = *pp_ace; pace; pace = pace->next) {
if (pace->type == SMB_ACL_USER_OBJ) {
@@ -1078,6 +646,62 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
}
}
+ /*
+ * When setting ACLs and missing one out of SMB_ACL_USER_OBJ,
+ * SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER, try to retrieve current
+ * values. For user and other a simple vfs_stat would do, but
+ * we would get mask instead of group. Let's do it via ACL.
+ */
+
+ if (setting_acl && (!got_user || !got_grp || !got_other)) {
+
+ SMB_ACL_ENTRY_T entry;
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+
+ if(fsp->is_directory || fsp->fd == -1) {
+ current_posix_acl = conn->vfs_ops.sys_acl_get_file(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
+ } else {
+ current_posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd);
+ }
+
+ if (current_posix_acl) {
+ while (conn->vfs_ops.sys_acl_get_entry(conn, current_posix_acl, entry_id, &entry) == 1) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY)
+ entry_id = SMB_ACL_NEXT_ENTRY;
+
+ /* Is this a MASK entry ? */
+ if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
+ continue;
+
+ if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
+ continue;
+
+ switch(tagtype) {
+ case SMB_ACL_USER_OBJ:
+ current_user_perms = convert_permset_to_mode_t(conn, permset);
+ got_current_user = True;
+ break;
+ case SMB_ACL_GROUP_OBJ:
+ current_grp_perms = convert_permset_to_mode_t(conn, permset);
+ got_current_grp = True;
+ break;
+ case SMB_ACL_OTHER:
+ current_other_perms = convert_permset_to_mode_t(conn, permset);
+ got_current_other = True;
+ break;
+ }
+ }
+ conn->vfs_ops.sys_acl_free_acl(conn, current_posix_acl);
+ } else {
+ DEBUG(10,("ensure_canon_entry_valid: failed to retrieve current ACL of %s\n",
+ fsp->fsp_name));
+ }
+ }
+
if (!got_user) {
if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) {
DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
@@ -1092,13 +716,18 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->attr = ALLOW_ACE;
if (setting_acl) {
- /* If we only got an "everyone" perm, just use that. */
- if (!got_grp && got_other)
- pace->perms = pace_other->perms;
- else if (got_grp && uid_entry_in_group(pace, pace_group))
- pace->perms = pace_group->perms;
- else
- pace->perms = 0;
+ if (got_current_user) {
+ pace->perms = current_user_perms;
+ } else {
+ /* If we only got an "everyone" perm, just use that. */
+ if (!got_grp && got_other)
+ pace->perms = pace_other->perms;
+ else if (got_grp && uid_entry_in_group(pace, pace_group))
+ pace->perms = pace_group->perms;
+ else
+ pace->perms = 0;
+
+ }
apply_default_perms(fsp, pace, S_IRUSR);
} else {
@@ -1121,11 +750,15 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->trustee = *pfile_grp_sid;
pace->attr = ALLOW_ACE;
if (setting_acl) {
- /* If we only got an "everyone" perm, just use that. */
- if (got_other)
- pace->perms = pace_other->perms;
- else
- pace->perms = 0;
+ if (got_current_grp) {
+ pace->perms = current_grp_perms;
+ } else {
+ /* If we only got an "everyone" perm, just use that. */
+ if (got_other)
+ pace->perms = pace_other->perms;
+ else
+ pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
+ }
apply_default_perms(fsp, pace, S_IRGRP);
} else {
pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
@@ -1147,7 +780,10 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->trustee = global_sid_World;
pace->attr = ALLOW_ACE;
if (setting_acl) {
- pace->perms = 0;
+ if (got_current_other)
+ pace->perms = current_other_perms;
+ else
+ pace->perms = 0;
apply_default_perms(fsp, pace, S_IROTH);
} else
pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
@@ -1207,7 +843,7 @@ static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID
Unpack a SEC_DESC into two canonical ace lists.
****************************************************************************/
-static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
+static BOOL create_canon_ace_lists(files_struct *fsp,
DOM_SID *pfile_owner_sid,
DOM_SID *pfile_grp_sid,
canon_ace **ppfile_ace, canon_ace **ppdir_ace,
@@ -1302,6 +938,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
}
for(i = 0; i < dacl->num_aces; i++) {
+ enum SID_NAME_USE sid_type;
SEC_ACE *psa = &dacl->ace[i];
/*
@@ -1342,7 +979,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
current_ace->type = SMB_ACL_OTHER;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
current_ace->owner_type = UID_ACE;
- current_ace->unix_ug.uid = pst->st_uid;
+ current_ace->unix_ug.world = -1;
current_ace->type = SMB_ACL_USER_OBJ;
/*
@@ -1355,7 +992,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
current_ace->owner_type = GID_ACE;
- current_ace->unix_ug.gid = pst->st_gid;
+ current_ace->unix_ug.world = -1;
current_ace->type = SMB_ACL_GROUP_OBJ;
/*
@@ -1366,10 +1003,10 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
if (nt4_compatible_acls())
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- } else if (NT_STATUS_IS_OK(sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid))) {
+ } else if (sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid, &sid_type)) {
current_ace->owner_type = UID_ACE;
current_ace->type = SMB_ACL_USER;
- } else if (NT_STATUS_IS_OK(sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid))) {
+ } else if (sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid, &sid_type)) {
current_ace->owner_type = GID_ACE;
current_ace->type = SMB_ACL_GROUP;
} else {
@@ -1390,7 +1027,6 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
- current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
/*
* Now add the created ace to either the file list, the directory
@@ -1537,7 +1173,7 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
/****************************************************************************
ASCII art time again... JRA :-).
- We have 4 cases to process when moving from an NT ACL to a POSIX ACL. Firstly,
+ We have 3 cases to process when moving from an NT ACL to a POSIX ACL. Firstly,
we insist the ACL is in canonical form (ie. all DENY entries preceede ALLOW
entries). Secondly, the merge code has ensured that all duplicate SID entries for
allow or deny have been merged, so the same SID can only appear once in the deny
@@ -1610,15 +1246,6 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
best we can do and has the advantage of failing closed rather
than open.
---------------------------------------------------------------------------
- Fourth pass - cope with cumulative permissions.
-
- for all allow user entries, if there exists an allow group entry with
- more permissive permissions, and the user is in that group, rewrite the
- allow user permissions to contain both sets of permissions.
-
- Currently the code for this is #ifdef'ed out as these semantics make
- no sense to me. JRA.
- ---------------------------------------------------------------------------
Note we *MUST* do the deny user pass first as this will convert deny user
entries into allow user entries which can then be processed by the deny
@@ -1808,45 +1435,6 @@ static void process_deny_list( canon_ace **pp_ace_list )
}
- /* Doing this fourth pass allows Windows semantics to be layered
- * on top of POSIX semantics. I'm not sure if this is desirable.
- * For example, in W2K ACLs there is no way to say, "Group X no
- * access, user Y full access" if user Y is a member of group X.
- * This seems completely broken semantics to me.... JRA.
- */
-
-#if 0
- /* Pass 4 above - deal with allow entries. */
-
- for (curr_ace = ace_list; curr_ace; curr_ace = curr_ace_next) {
- canon_ace *allow_ace_p;
-
- curr_ace_next = curr_ace->next; /* So we can't lose the link. */
-
- if (curr_ace->attr != ALLOW_ACE)
- continue;
-
- if (curr_ace->owner_type != UID_ACE)
- continue;
-
- for (allow_ace_p = ace_list; allow_ace_p; allow_ace_p = allow_ace_p->next) {
-
- if (allow_ace_p->attr != ALLOW_ACE)
- continue;
-
- /* We process GID_ACE entries only. */
-
- if (allow_ace_p->owner_type != GID_ACE)
- continue;
-
- /* OR in the group perms. */
-
- if (uid_entry_in_group( curr_ace, allow_ace_p))
- curr_ace->perms |= allow_ace_p->perms;
- }
- }
-#endif
-
*pp_ace_list = ace_list;
}
@@ -1915,7 +1503,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* Now go through the DACL and create the canon_ace lists.
*/
- if (!create_canon_ace_lists( fsp, pst, pfile_owner_sid, pfile_grp_sid,
+ if (!create_canon_ace_lists( fsp, pfile_owner_sid, pfile_grp_sid,
&file_ace, &dir_ace, psd->dacl))
return False;
@@ -2058,7 +1646,7 @@ static void arrange_posix_perms( char *filename, canon_ace **pp_list_head)
****************************************************************************/
static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf,
- DOM_SID *powner, DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
+ DOM_SID *powner, DOM_SID *pgroup, SMB_ACL_TYPE_T the_acl_type)
{
extern DOM_SID global_sid_World;
connection_struct *conn = fsp->conn;
@@ -2070,7 +1658,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
SMB_ACL_ENTRY_T entry;
size_t ace_count;
- while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ while ( posix_acl && (conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1)) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
DOM_SID sid;
@@ -2082,10 +1670,10 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
entry_id = SMB_ACL_NEXT_ENTRY;
/* Is this a MASK entry ? */
- if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
+ if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
continue;
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
+ if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
continue;
/* Decide which SID to use based on the ACL type. */
@@ -2098,7 +1686,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
break;
case SMB_ACL_USER:
{
- uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ uid_t *puid = (uid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry);
if (puid == NULL) {
DEBUG(0,("canonicalise_acl: Failed to get uid.\n"));
continue;
@@ -2115,7 +1703,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
uid_to_sid( &sid, *puid);
unix_ug.uid = *puid;
owner_type = UID_ACE;
- SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
+ conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)puid,tagtype);
break;
}
case SMB_ACL_GROUP_OBJ:
@@ -2126,7 +1714,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
break;
case SMB_ACL_GROUP:
{
- gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ gid_t *pgid = (gid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry);
if (pgid == NULL) {
DEBUG(0,("canonicalise_acl: Failed to get gid.\n"));
continue;
@@ -2134,7 +1722,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
gid_to_sid( &sid, *pgid);
unix_ug.gid = *pgid;
owner_type = GID_ACE;
- SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
+ conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)pgid,tagtype);
break;
}
case SMB_ACL_MASK:
@@ -2165,7 +1753,6 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
- ace->inherited = get_inherited_flag(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
DLIST_ADD(list_head, ace);
}
@@ -2177,12 +1764,14 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf, False))
goto fail;
+ arrange_posix_perms(fsp->fsp_name,&list_head );
+
/*
* Now go through the list, masking the permissions with the
* acl_mask. Ensure all DENY Entries are at the start of the list.
*/
- DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" ));
+ DEBUG(10,("canonicalise_acl: ace entries before arrange :\n"));
for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) {
next_ace = ace->next;
@@ -2200,8 +1789,6 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
}
}
- arrange_posix_perms(fsp->fsp_name,&list_head );
-
print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head );
return list_head;
@@ -2220,7 +1807,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
{
connection_struct *conn = fsp->conn;
BOOL ret = False;
- SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, (int)count_canon_ace_list(the_ace) + 1);
+ SMB_ACL_T the_acl = conn->vfs_ops.sys_acl_init(conn, (int)count_canon_ace_list(the_ace) + 1);
canon_ace *p_ace;
int i;
SMB_ACL_ENTRY_T mask_entry;
@@ -2278,7 +1865,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Get the entry for this ACE.
*/
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
+ if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &the_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -2304,7 +1891,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* First tell the entry what type of ACE this is.
*/
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, p_ace->type) == -1) {
+ if (conn->vfs_ops.sys_acl_set_tag_type(conn, the_entry, p_ace->type) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -2316,7 +1903,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) {
- if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) {
+ if (conn->vfs_ops.sys_acl_set_qualifier(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -2327,7 +1914,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Convert the mode_t perms in the canon_ace to a POSIX permset.
*/
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
+ if (conn->vfs_ops.sys_acl_get_permset(conn, the_entry, &the_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to get permset on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -2343,7 +1930,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* ..and apply them to the entry.
*/
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
+ if (conn->vfs_ops.sys_acl_set_permset(conn, the_entry, the_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n",
i, strerror(errno) ));
goto done;
@@ -2351,21 +1938,20 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if( DEBUGLVL( 10 ))
print_canon_ace( p_ace, i);
-
}
if (needs_mask && !got_mask_entry) {
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &mask_entry) == -1) {
+ if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &mask_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, mask_entry, SMB_ACL_MASK) == -1) {
+ if (conn->vfs_ops.sys_acl_set_tag_type(conn, mask_entry, SMB_ACL_MASK) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, mask_entry, &mask_permset) == -1) {
+ if (conn->vfs_ops.sys_acl_get_permset(conn, mask_entry, &mask_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to get mask permset. (%s)\n", strerror(errno) ));
goto done;
}
@@ -2375,7 +1961,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
goto done;
}
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, mask_entry, mask_permset) == -1) {
+ if (conn->vfs_ops.sys_acl_set_permset(conn, mask_entry, mask_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) ));
goto done;
}
@@ -2385,7 +1971,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
* Check if the ACL is valid.
*/
- if (SMB_VFS_SYS_ACL_VALID(conn, the_acl) == -1) {
+ if (conn->vfs_ops.sys_acl_valid(conn, the_acl) == -1) {
DEBUG(0,("set_canon_ace_list: ACL type (%s) is invalid for set (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
strerror(errno) ));
@@ -2397,7 +1983,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if(default_ace || fsp->is_directory || fsp->fd == -1) {
- if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
+ if (conn->vfs_ops.sys_acl_set_file(conn, dos_to_unix_static(fsp->fsp_name), the_acl_type, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
* when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
@@ -2416,7 +2002,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
goto done;
}
} else {
- if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, the_acl) == -1) {
+ if (conn->vfs_ops.sys_acl_set_fd(fsp, fsp->fd, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
* when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
@@ -2440,7 +2026,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
done:
if (the_acl != NULL)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, the_acl);
return ret;
}
@@ -2465,17 +2051,17 @@ static struct canon_ace *canon_ace_entry_for(struct canon_ace *list, SMB_ACL_TAG
****************************************************************************/
-SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl)
+SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T acl)
{
SMB_ACL_ENTRY_T entry;
- if (!the_acl)
+ if (!acl)
return NULL;
- if (SMB_VFS_SYS_ACL_GET_ENTRY(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
- SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
+ if (conn->vfs_ops.sys_acl_get_entry(conn, acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
+ conn->vfs_ops.sys_acl_free_acl(conn, acl);
return NULL;
}
- return the_acl;
+ return acl;
}
/****************************************************************************
@@ -2553,6 +2139,16 @@ posix perms.\n", fsp->fsp_name ));
return True;
}
+static int nt_ace_comp( SEC_ACE *a1, SEC_ACE *a2)
+{
+ if (a1->type == a2->type)
+ return 0;
+
+ if (a1->type == SEC_ACE_TYPE_ACCESS_DENIED && a2->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+ return -1;
+ return 1;
+}
+
/****************************************************************************
Incoming NT ACLs on a directory can be split into a default POSIX acl (CI|OI|IO) and
a normal POSIX acl. Win2k needs these split acls re-merging into one ACL
@@ -2566,51 +2162,24 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
for (i = 0; i < num_aces; i++) {
for (j = i+1; j < num_aces; j++) {
- uint32 i_flags_ni = (nt_ace_list[i].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
- uint32 j_flags_ni = (nt_ace_list[j].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
- BOOL i_inh = (nt_ace_list[i].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
- BOOL j_inh = (nt_ace_list[j].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
-
/* We know the lower number ACE's are file entries. */
if ((nt_ace_list[i].type == nt_ace_list[j].type) &&
(nt_ace_list[i].size == nt_ace_list[j].size) &&
(nt_ace_list[i].info.mask == nt_ace_list[j].info.mask) &&
sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) &&
- (i_inh == j_inh) &&
- (i_flags_ni == 0) &&
- (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT|
- SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY))) {
+ (nt_ace_list[i].flags == 0) &&
+ (nt_ace_list[j].flags == (SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY))) {
/*
- * W2K wants to have access allowed zero access ACE's
- * at the end of the list. If the mask is zero, merge
- * the non-inherited ACE onto the inherited ACE.
+ * These are identical except for the flags.
+ * Merge the inherited ACE onto the non-inherited ACE.
*/
- if (nt_ace_list[i].info.mask == 0) {
- nt_ace_list[j].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
- if (num_aces - i - 1 > 0)
- memmove(&nt_ace_list[i], &nt_ace_list[i+1], (num_aces-i-1) *
- sizeof(SEC_ACE));
-
- DEBUG(10,("merge_default_aces: Merging zero access ACE %u onto ACE %u.\n",
- (unsigned int)i, (unsigned int)j ));
- } else {
- /*
- * These are identical except for the flags.
- * Merge the inherited ACE onto the non-inherited ACE.
- */
-
- nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
- if (num_aces - j - 1 > 0)
- memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) *
- sizeof(SEC_ACE));
-
- DEBUG(10,("merge_default_aces: Merging ACE %u onto ACE %u.\n",
- (unsigned int)j, (unsigned int)i ));
- }
+ nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT;
+ if (num_aces - j - 1 > 0)
+ memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) *
+ sizeof(SEC_ACE));
num_aces--;
break;
}
@@ -2626,7 +2195,7 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
the UNIX style get ACL.
****************************************************************************/
-size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
+size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
{
extern DOM_SID global_sid_Builtin_Administrators;
extern DOM_SID global_sid_Builtin_Users;
@@ -2647,9 +2216,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
- struct pai_val *pal = NULL;
- SEC_DESC *psd = NULL;
-
+
*ppdesc = NULL;
DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
@@ -2657,42 +2224,40 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
if(fsp->is_directory || fsp->fd == -1) {
/* Get the stat struct for the owner info. */
- if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
+ if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
return 0;
}
/*
* Get the ACL from the path.
*/
- posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
+ posix_acl = conn->vfs_ops.sys_acl_get_file(conn, dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_ACCESS);
/*
* If it's a directory get the default POSIX ACL.
*/
if(fsp->is_directory) {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ dir_acl = conn->vfs_ops.sys_acl_get_file(conn, dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_DEFAULT);
dir_acl = free_empty_sys_acl(conn, dir_acl);
}
} else {
/* Get the stat struct for the owner info. */
- if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
+ if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
return 0;
}
/*
* Get the ACL from the fd.
*/
- posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
+ posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd);
}
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
posix_acl ? "present" : "absent",
dir_acl ? "present" : "absent" ));
- pal = load_inherited_info(fsp);
-
/*
* Get the owner, group and world SIDs.
*/
@@ -2706,171 +2271,196 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
create_file_sids(&sbuf, &owner_sid, &group_sid);
}
- if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) {
+ /*
+ * In the optimum case Creator Owner and Creator Group would be used for
+ * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
+ * would lead to usability problems under Windows: The Creator entries
+ * are only available in browse lists of directories and not for files;
+ * additionally the identity of the owning group couldn't be determined.
+ * We therefore use those identities only for Default ACLs.
+ */
- /*
- * In the optimum case Creator Owner and Creator Group would be used for
- * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
- * would lead to usability problems under Windows: The Creator entries
- * are only available in browse lists of directories and not for files;
- * additionally the identity of the owning group couldn't be determined.
- * We therefore use those identities only for Default ACLs.
- */
+ /* Create the canon_ace lists. */
+ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
- /* Create the canon_ace lists. */
- file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS );
+ /* We must have *some* ACLS. */
- /* We must have *some* ACLS. */
-
- if (count_canon_ace_list(file_ace) == 0) {
- DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
- return 0;
- }
-
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
- &global_sid_Creator_Owner,
- &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
- }
-
- /*
- * Create the NT ACE list from the canonical ace lists.
- */
+ if (count_canon_ace_list(file_ace) == 0) {
+ DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
+ return 0;
+ }
- {
- canon_ace *ace;
- int nt_acl_type;
- int i;
+ if (fsp->is_directory && dir_acl) {
+ dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ &global_sid_Creator_Owner,
+ &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
+ }
- if (nt4_compatible_acls() && dir_ace) {
- /*
- * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
- * but no non-INHERIT_ONLY entry for one SID. So we only
- * remove entries from the Access ACL if the
- * corresponding Default ACL entries have also been
- * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
- * are exceptions. We can do nothing
- * intelligent if the Default ACL contains entries that
- * are not also contained in the Access ACL, so this
- * case will still fail under NT 4.
- */
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
+ {
+ canon_ace *ace;
+ int nt_acl_type;
+ int i;
- ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
- SAFE_FREE(ace);
- }
- }
+ if (nt4_compatible_acls()) {
+ /*
+ * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
+ * but no non-INHERIT_ONLY entry for one SID. So we only
+ * remove entries from the Access ACL if the
+ * corresponding Default ACL entries have also been
+ * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
+ * are exceptions. We can do nothing
+ * intelligent if the Default ACL contains entries that
+ * are not also contained in the Access ACL, so this
+ * case will still fail under NT 4.
+ */
- /*
- * WinNT doesn't usually have Creator Group
- * in browse lists, so we send this entry to
- * WinNT even if it contains no relevant
- * permissions. Once we can add
- * Creator Group to browse lists we can
- * re-enable this.
- */
+ if (!dir_ace)
+ goto simplify_file_ace_only;
-#if 0
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
- }
-#endif
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
- ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
if (ace && !ace->perms) {
DLIST_REMOVE(file_ace, ace);
SAFE_FREE(ace);
}
}
- num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
-
- /* Allocate the ace list. */
- if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
- goto done;
- }
-
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
-
/*
- * Create the NT ACE list from the canonical ace lists.
+ * WinNT doesn't usually have Creator Group
+ * in browse lists, so we send this entry to
+ * WinNT even if it contains no relevant
+ * permissions. Once we can add
+ * Creator Group to browse lists we can
+ * re-enable this.
*/
-
- ace = file_ace;
- for (i = 0; i < num_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
-
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0);
+#if 0
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
}
+#endif
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
+ }
+ } else {
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED,
- acc, 0);
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
+ }
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
}
- ace = dir_ace;
+ simplify_file_ace_only:
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
-
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY|
- (ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0));
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
}
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
-
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY|0);
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
}
+ }
- /*
- * Merge POSIX default ACLs and normal ACLs into one NT ACE.
- * Win2K needs this to get the inheritance correct when replacing ACLs
- * on a directory tree. Based on work by Jim @ IBM.
- */
+ num_acls = count_canon_ace_list(file_ace);
+ num_dir_acls = count_canon_ace_list(dir_ace);
- num_aces = merge_default_aces(nt_ace_list, num_aces);
+ /* Allocate the ace list. */
+ if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
+ goto done;
+ }
+
+ memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
+ ace = file_ace;
+
+ for (i = 0; i < num_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
+
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
}
- if (num_aces) {
- if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
- goto done;
- }
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
+
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
+ }
+
+ ace = dir_ace;
+
+ for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
+
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
+
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
+
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY);
}
- } /* security_info & DACL_SECURITY_INFORMATION */
- psd = make_standard_sec_desc( main_loop_talloc_get(),
- (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
- (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
- psa,
- &sd_size);
+ /*
+ * Merge POSIX default ACLs and normal ACLs into one NT ACE.
+ * Win2K needs this to get the inheritance correct when replacing ACLs
+ * on a directory tree. Based on work by Jim @ IBM.
+ */
+
+ num_aces = merge_default_aces(nt_ace_list, num_aces);
- if(!psd) {
+ /*
+ * Sort to force deny entries to the front.
+ */
+
+ if (num_aces)
+ qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
+ }
+
+ if (num_aces) {
+ if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+ goto done;
+ }
+ }
+
+ *ppdesc = make_standard_sec_desc( main_loop_talloc_get(), &owner_sid, &group_sid, psa, &sd_size);
+
+ if(!*ppdesc) {
DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
sd_size = 0;
} else {
@@ -2883,24 +2473,17 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
* any ACEs that are inherited dynamically. The DACL_PROTECTED
* flag doesn't seem to bother Windows NT.
*/
- if (get_protected_flag(pal))
- psd->type |= SE_DESC_DACL_PROTECTED;
+ (*ppdesc)->type |= SE_DESC_DACL_PROTECTED;
}
- if (psd->dacl)
- dacl_sort_into_canonical_order(psd->dacl->ace, (unsigned int)psd->dacl->num_aces);
-
- *ppdesc = psd;
-
done:
if (posix_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, dir_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
- free_inherited_info(pal);
SAFE_FREE(nt_ace_list);
return sd_size;
@@ -2922,14 +2505,14 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
SMB_STRUCT_STAT st;
/* try the direct way first */
- ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+ ret = vfs_chown(conn, fname, uid, gid);
if (ret == 0)
return 0;
if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
return -1;
- if (SMB_VFS_STAT(conn,fname,&st))
+ if (vfs_stat(conn,fname,&st))
return -1;
fsp = open_file_fchmod(conn,fname,&st);
@@ -2944,7 +2527,7 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
become_root();
/* Keep the current file gid the same. */
- ret = SMB_VFS_FCHOWN(fsp, fsp->fd, uid, (gid_t)-1);
+ ret = vfswrap_fchown(fsp, fsp->fd, uid, (gid_t)-1);
unbecome_root();
close_file_fchmod(fsp);
@@ -2987,10 +2570,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
*/
if(fsp->is_directory || fsp->fd == -1) {
- if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
+ if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0)
return False;
} else {
- if(SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0)
+ if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0)
return False;
}
@@ -3010,7 +2593,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* Do we need to chown ?
*/
- if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp)))
+ if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (uid_t)-1) && (orig_gid != grp)))
need_chown = True;
/*
@@ -3036,7 +2619,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
*/
if(fsp->is_directory) {
- if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
+ if(vfs_stat(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
return False;
}
} else {
@@ -3044,9 +2627,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
int ret;
if(fsp->fd == -1)
- ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
+ ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf);
else
- ret = SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf);
+ ret = vfs_fstat(fsp,fsp->fd,&sbuf);
if(ret != 0)
return False;
@@ -3114,7 +2697,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* No default ACL - delete one if it exists.
*/
- if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) {
+ if (conn->vfs_ops.sys_acl_delete_def_file(conn, dos_to_unix_static(fsp->fsp_name)) == -1) {
DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
@@ -3123,10 +2706,6 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
}
}
- if (acl_set_support)
- store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
- (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
-
/*
* If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
*/
@@ -3147,7 +2726,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
fsp->fsp_name, (unsigned int)posix_perms ));
- if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) {
+ if(conn->vfs_ops.chmod(conn,dos_to_unix_static(fsp->fsp_name), posix_perms) == -1) {
DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
free_canon_ace_list(file_ace_list);
@@ -3179,48 +2758,6 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
}
/****************************************************************************
- Get the actual group bits stored on a file with an ACL. Has no effect if
- the file has no ACL. Needed in dosmode code where the stat() will return
- the mask bits, not the real group bits, for a file with an ACL.
-****************************************************************************/
-
-int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode )
-{
- int entry_id = SMB_ACL_FIRST_ENTRY;
- SMB_ACL_ENTRY_T entry;
- SMB_ACL_T posix_acl;
-
- posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
- if (posix_acl == (SMB_ACL_T)NULL)
- return -1;
-
- while (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
- SMB_ACL_TAG_T tagtype;
- SMB_ACL_PERMSET_T permset;
-
- /* get_next... */
- if (entry_id == SMB_ACL_FIRST_ENTRY)
- entry_id = SMB_ACL_NEXT_ENTRY;
-
- if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1)
- return -1;
-
- if (tagtype == SMB_ACL_GROUP_OBJ) {
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
- return -1;
- } else {
- *mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP);
- *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0);
- *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0);
- *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0);
- return 0;;
- }
- }
- }
- return -1;
-}
-
-/****************************************************************************
Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
and set the mask to rwx. Needed to preserve complex ACLs set by NT.
****************************************************************************/
@@ -3231,7 +2768,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
SMB_ACL_ENTRY_T entry;
int num_entries = 0;
- while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
+ while ( conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
mode_t perms;
@@ -3240,10 +2777,10 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
if (entry_id == SMB_ACL_FIRST_ENTRY)
entry_id = SMB_ACL_NEXT_ENTRY;
- if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
+ if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1)
return -1;
- if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
+ if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1)
return -1;
num_entries++;
@@ -3274,7 +2811,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
if (map_acl_perms_to_permset(conn, perms, &permset) == -1)
return -1;
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) == -1)
+ if (conn->vfs_ops.sys_acl_set_permset(conn, entry, permset) == -1)
return -1;
}
@@ -3300,17 +2837,17 @@ static int copy_access_acl(connection_struct *conn, const char *from, const char
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
+ if ((posix_acl = conn->vfs_ops.sys_acl_get_file(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
goto done;
- ret = SMB_VFS_SYS_ACL_SET_FILE(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
+ ret = conn->vfs_ops.sys_acl_set_file(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
done:
- SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
return ret;
}
@@ -3352,17 +2889,17 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fd)) == NULL)
+ if ((posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fd)) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
goto done;
- ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fd, posix_acl);
+ ret = conn->vfs_ops.sys_acl_set_fd(fsp, fd, posix_acl);
done:
- SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, posix_acl);
return ret;
}
@@ -3372,14 +2909,14 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode)
BOOL directory_has_default_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ SMB_ACL_T dir_acl = conn->vfs_ops.sys_acl_get_file( conn, fname, SMB_ACL_TYPE_DEFAULT);
BOOL has_acl = False;
SMB_ACL_ENTRY_T entry;
- if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
+ if (dir_acl != NULL && (conn->vfs_ops.sys_acl_get_entry(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
has_acl = True;
if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ conn->vfs_ops.sys_acl_free_acl(conn, dir_acl);
return has_acl;
}
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 966bb63c1ea..765fdef9342 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
process incoming packets - main loop
Copyright (C) Andrew Tridgell 1992-1998
@@ -20,6 +21,9 @@
#include "includes.h"
+/* To be removed.... JRA */
+#define SMB_ALIGNMENT 1
+
struct timeval smb_last_time;
static char *InBuffer = NULL;
@@ -42,29 +46,22 @@ extern int last_message;
extern int global_oplock_break;
extern userdom_struct current_user_info;
extern int smb_read_error;
-SIG_ATOMIC_T reload_after_sighup = 0;
-SIG_ATOMIC_T got_sig_term = 0;
-BOOL global_machine_password_needs_changing = False;
+extern SIG_ATOMIC_T reload_after_sighup;
+extern SIG_ATOMIC_T got_sig_term;
+extern BOOL global_machine_password_needs_changing;
+extern fstring global_myworkgroup;
+extern pstring global_myname;
extern int max_send;
/****************************************************************************
- Function to return the current request mid from Inbuffer.
-****************************************************************************/
-
-uint16 get_current_mid(void)
-{
- return SVAL(InBuffer,smb_mid);
-}
-
-/****************************************************************************
structure to hold a linked list of queued messages.
for processing.
****************************************************************************/
typedef struct {
- ubi_slNode msg_next;
- char *msg_buf;
- int msg_len;
+ ubi_slNode msg_next;
+ char *msg_buf;
+ int msg_len;
} pending_message_list;
static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
@@ -76,30 +73,29 @@ static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0
static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
{
- pending_message_list *msg = (pending_message_list *)
+ pending_message_list *msg = (pending_message_list *)
malloc(sizeof(pending_message_list));
- if(msg == NULL) {
- DEBUG(0,("push_message: malloc fail (1)\n"));
- return False;
- }
-
- msg->msg_buf = (char *)malloc(msg_len);
- if(msg->msg_buf == NULL) {
- DEBUG(0,("push_message: malloc fail (2)\n"));
- SAFE_FREE(msg);
- return False;
- }
+ if(msg == NULL)
+ {
+ DEBUG(0,("push_message: malloc fail (1)\n"));
+ return False;
+ }
- memcpy(msg->msg_buf, buf, msg_len);
- msg->msg_len = msg_len;
+ msg->msg_buf = (char *)malloc(msg_len);
+ if(msg->msg_buf == NULL)
+ {
+ DEBUG(0,("push_message: malloc fail (2)\n"));
+ SAFE_FREE(msg);
+ return False;
+ }
- ubi_slAddTail( list_head, msg);
+ memcpy(msg->msg_buf, buf, msg_len);
+ msg->msg_len = msg_len;
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(buf,smb_mid));
+ ubi_slAddTail( list_head, msg);
- return True;
+ return True;
}
/****************************************************************************
@@ -160,7 +156,7 @@ static void async_processing(char *buffer, int buffer_len)
Returns False on timeout or error.
Else returns True.
-The timeout is in milliseconds
+The timeout is in milli seconds
****************************************************************************/
static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
@@ -266,6 +262,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
*/
if (oplock_message_waiting(&fds)) {
+ DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
async_processing(buffer, buffer_len);
/*
* After async processing we must go and do the select again, as
@@ -290,7 +287,7 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
do {
ret = receive_message_or_smb(inbuf,bufsize,timeout);
- got_keepalive = (ret && (CVAL(inbuf,0) == SMBkeepalive));
+ got_keepalive = (ret && (CVAL(inbuf,0) == 0x85));
} while (ret && got_keepalive);
return ret;
@@ -305,29 +302,28 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
void respond_to_all_remaining_local_messages(void)
{
- char buffer[1024];
-
- /*
- * Assert we have no exclusive open oplocks.
- */
-
- if(get_number_of_exclusive_open_oplocks()) {
- DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
- get_number_of_exclusive_open_oplocks() ));
- return;
- }
-
- /*
- * Keep doing receive_local_message with a 1 ms timeout until
- * we have no more messages.
- */
-
- while(receive_local_message(buffer, sizeof(buffer), 1)) {
- /* Deal with oplock break requests from other smbd's. */
- process_local_message(buffer, sizeof(buffer));
- }
-
- return;
+ char buffer[1024];
+
+ /*
+ * Assert we have no exclusive open oplocks.
+ */
+
+ if(get_number_of_exclusive_open_oplocks()) {
+ DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
+ get_number_of_exclusive_open_oplocks() ));
+ return;
+ }
+
+ /*
+ * Keep doing receive_local_message with a 1 ms timeout until
+ * we have no more messages.
+ */
+ while(receive_local_message(buffer, sizeof(buffer), 1)) {
+ /* Deal with oplock break requests from other smbd's. */
+ process_local_message(buffer, sizeof(buffer));
+ }
+
+ return;
}
@@ -350,11 +346,13 @@ force write permissions on print services.
functions. Any message that has a NULL function is unimplemented -
please feel free to contribute implementations!
*/
-static const struct smb_message_struct {
- const char *name;
- int (*fn)(connection_struct *conn, char *, char *, int, int);
- int flags;
-} smb_messages[256] = {
+struct smb_message_struct
+{
+ const char *name;
+ int (*fn)(connection_struct *conn, char *, char *, int, int);
+ int flags;
+}
+ smb_messages[256] = {
/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
@@ -384,7 +382,7 @@ static const struct smb_message_struct {
/* 0x19 */ { NULL, NULL, 0 },
/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
-/* 0x1c */ { "SMBreadBs",NULL,0 },
+/* 0x1c */ { "SMBreadBs",NULL,0},
/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
@@ -393,7 +391,7 @@ static const struct smb_message_struct {
/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
-/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
+/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
/* 0x26 */ { "SMBtranss",NULL,AS_USER | CAN_IPC},
/* 0x27 */ { "SMBioctl",reply_ioctl,0},
/* 0x28 */ { "SMBioctls",NULL,AS_USER},
@@ -516,12 +514,12 @@ static const struct smb_message_struct {
/* 0x9d */ { NULL, NULL, 0 },
/* 0x9e */ { NULL, NULL, 0 },
/* 0x9f */ { NULL, NULL, 0 },
-/* 0xa0 */ { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
+/* 0xa0 */ { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
/* 0xa1 */ { "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
/* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
/* 0xa3 */ { NULL, NULL, 0 },
/* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0 },
-/* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
+/* 0xa5 */ { NULL, NULL, 0 },
/* 0xa6 */ { NULL, NULL, 0 },
/* 0xa7 */ { NULL, NULL, 0 },
/* 0xa8 */ { NULL, NULL, 0 },
@@ -616,10 +614,9 @@ static const struct smb_message_struct {
};
/*******************************************************************
- Dump a packet to a file.
-********************************************************************/
-
-static void smb_dump(const char *name, int type, char *data, ssize_t len)
+dump a prs to a file
+ ********************************************************************/
+static void smb_dump(const char *name, int type, const char *data, ssize_t len)
{
int fd, i;
pstring fname;
@@ -637,286 +634,261 @@ static void smb_dump(const char *name, int type, char *data, ssize_t len)
if (ret != len)
DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
close(fd);
- DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
+ DEBUG(0,("created %s len %d\n", fname, len));
}
}
/****************************************************************************
- Do a switch on the message type, and return the response size
+ Do a switch on the message type, and return the response size.
****************************************************************************/
static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
{
- static pid_t pid= (pid_t)-1;
- int outsize = 0;
- extern uint16 global_smbpid;
-
- type &= 0xff;
-
- if (pid == (pid_t)-1)
- pid = sys_getpid();
-
- errno = 0;
- last_message = type;
-
- /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */
- if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size - 4))) {
- DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf)));
- exit_server("Non-SMB packet");
- return(-1);
- }
-
- /* yuck! this is an interim measure before we get rid of our
- current inbuf/outbuf system */
- global_smbpid = SVAL(inbuf,smb_pid);
-
- if (smb_messages[type].fn == NULL) {
- DEBUG(0,("Unknown message type %d!\n",type));
- smb_dump("Unknown", 1, inbuf, size);
- outsize = reply_unknown(inbuf,outbuf);
- } else {
- int flags = smb_messages[type].flags;
- static uint16 last_session_tag = UID_FIELD_INVALID;
- /* In share mode security we must ignore the vuid. */
- uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
- connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
-
- DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid));
-
- smb_dump(smb_fn_name(type), 1, inbuf, size);
- if(global_oplock_break) {
- if(flags & QUEUE_IN_OPLOCK) {
- /*
- * Queue this message as we are the process of an oplock break.
- */
-
- DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
- DEBUGADD( 2, ( "oplock break state.\n" ) );
-
- push_oplock_pending_smb_message( inbuf, size );
- return -1;
- }
- }
-
- /* Ensure this value is replaced in the incoming packet. */
- SSVAL(inbuf,smb_uid,session_tag);
-
- /*
- * Ensure the correct username is in current_user_info.
- * This is a really ugly bugfix for problems with
- * multiple session_setup_and_X's being done and
- * allowing %U and %G substitutions to work correctly.
- * There is a reason this code is done here, don't
- * move it unless you know what you're doing... :-).
- * JRA.
- */
-
- if (session_tag != last_session_tag) {
- user_struct *vuser = NULL;
-
- last_session_tag = session_tag;
- if(session_tag != UID_FIELD_INVALID)
- vuser = get_valid_user_struct(session_tag);
- if(vuser != NULL)
- set_current_user_info(&vuser->user);
- }
-
- /* does this protocol need to be run as root? */
- if (!(flags & AS_USER))
- change_to_root_user();
-
- /* does this protocol need a valid tree connection? */
- if ((flags & AS_USER) && !conn)
- return ERROR_DOS(ERRSRV, ERRinvnid);
-
-
- /* does this protocol need to be run as the connected user? */
- if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
- if (flags & AS_GUEST)
- flags &= ~AS_USER;
- else
- return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid));
- }
-
- /* this code is to work around a bug is MS client 3 without
- introducing a security hole - it needs to be able to do
- print queue checks as guest if it isn't logged in properly */
- if (flags & AS_USER)
- flags &= ~AS_GUEST;
-
- /* does it need write permission? */
- if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
- /* ipc services are limited */
- if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
- /* load service specific parameters */
- if (conn && !set_current_service(conn,(flags & AS_USER)?True:False))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
- /* does this protocol need to be run as guest? */
- if ((flags & AS_GUEST) && (!change_to_guest() ||
- !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
- last_inbuf = inbuf;
-
- outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize);
- }
-
- smb_dump(smb_fn_name(type), 0, outbuf, outsize);
-
- return(outsize);
+ static pid_t pid= (pid_t)-1;
+ int outsize = 0;
+ extern uint16 global_smbpid;
+
+ type &= 0xff;
+
+ if (pid == (pid_t)-1)
+ pid = sys_getpid();
+
+ errno = 0;
+ last_message = type;
+
+ /* make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */
+ if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size-4))) {
+ DEBUG(0,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf)));
+ exit_server("Non-SMB packet");
+ return(-1);
+ }
+
+ /* yuck! this is an interim measure before we get rid of our
+ current inbuf/outbuf system */
+ global_smbpid = SVAL(inbuf,smb_pid);
+
+ if (smb_messages[type].fn == NULL)
+ {
+ DEBUG(0,("Unknown message type %d!\n",type));
+ smb_dump("Unknown", 1, inbuf, size);
+ outsize = reply_unknown(inbuf,outbuf);
+ }
+ else
+ {
+ int flags = smb_messages[type].flags;
+ static uint16 last_session_tag = UID_FIELD_INVALID;
+ /* In share mode security we must ignore the vuid. */
+ uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
+ connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
+
+ DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid));
+
+ smb_dump(smb_fn_name(type), 1, inbuf, size);
+ if(global_oplock_break)
+ {
+ if(flags & QUEUE_IN_OPLOCK)
+ {
+ /*
+ * Queue this message as we are the process of an oplock break.
+ */
+
+ DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
+ DEBUGADD( 2, ( "oplock break state.\n" ) );
+
+ push_oplock_pending_smb_message( inbuf, size );
+ return -1;
+ }
+ }
+
+ /* Ensure this value is replaced in the incoming packet. */
+ SSVAL(inbuf,smb_uid,session_tag);
+
+ /*
+ * Ensure the correct username is in current_user_info.
+ * This is a really ugly bugfix for problems with
+ * multiple session_setup_and_X's being done and
+ * allowing %U and %G substitutions to work correctly.
+ * There is a reason this code is done here, don't
+ * move it unless you know what you're doing... :-).
+ * JRA.
+ */
+
+ if (session_tag != last_session_tag) {
+ user_struct *vuser = NULL;
+
+ last_session_tag = session_tag;
+ if(session_tag != UID_FIELD_INVALID)
+ vuser = get_valid_user_struct(session_tag);
+ if(vuser != NULL)
+ current_user_info = vuser->user;
+ }
+
+ /* does this protocol need to be run as root? */
+ if (!(flags & AS_USER))
+ change_to_root_user();
+
+ /* does this protocol need a valid tree connection? */
+ if ((flags & AS_USER) && !conn) {
+ return ERROR_DOS(ERRSRV, ERRinvnid);
+ }
+
+
+ /* does this protocol need to be run as the connected user? */
+ if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
+ if (flags & AS_GUEST)
+ flags &= ~AS_USER;
+ else
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+ }
+
+ /* this code is to work around a bug is MS client 3 without
+ introducing a security hole - it needs to be able to do
+ print queue checks as guest if it isn't logged in properly */
+ if (flags & AS_USER)
+ flags &= ~AS_GUEST;
+
+ /* does it need write permission? */
+ if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+
+ /* ipc services are limited */
+ if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) {
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+ }
+
+ /* load service specific parameters */
+ if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) {
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+ }
+
+ /* does this protocol need to be run as guest? */
+ if ((flags & AS_GUEST) &&
+ (!change_to_guest() ||
+ !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) {
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+ }
+
+ last_inbuf = inbuf;
+
+ outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize);
+ }
+
+ smb_dump(smb_fn_name(type), 0, outbuf, outsize);
+
+ return(outsize);
}
/****************************************************************************
- Construct a reply to the incoming packet.
+ construct a reply to the incoming packet
****************************************************************************/
-
static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
{
- int type = CVAL(inbuf,smb_com);
- int outsize = 0;
- int msg_type = CVAL(inbuf,0);
+ int type = CVAL(inbuf,smb_com);
+ int outsize = 0;
+ int msg_type = CVAL(inbuf,0);
- GetTimeOfDay(&smb_last_time);
+ GetTimeOfDay(&smb_last_time);
- chain_size = 0;
- file_chain_reset();
- reset_chain_p();
+ chain_size = 0;
+ file_chain_reset();
+ reset_chain_p();
- if (msg_type != 0)
- return(reply_special(inbuf,outbuf));
+ if (msg_type != 0)
+ return(reply_special(inbuf,outbuf));
- construct_reply_common(inbuf, outbuf);
+ construct_reply_common(inbuf, outbuf);
- outsize = switch_message(type,inbuf,outbuf,size,bufsize);
+ outsize = switch_message(type,inbuf,outbuf,size,bufsize);
- outsize += chain_size;
+ outsize += chain_size;
- if(outsize > 4)
- smb_setlen(outbuf,outsize - 4);
- return(outsize);
+ if(outsize > 4)
+ smb_setlen(outbuf,outsize - 4);
+ return(outsize);
}
/****************************************************************************
- Keep track of the number of running smbd's. This functionality is used to
- 'hard' limit Samba overhead on resource constrained systems.
+ process an smb from the client - split out from the process() code so
+ it can be used by the oplock break code.
****************************************************************************/
-
-static BOOL process_count_update_successful = False;
-
-static int32 increment_smbd_process_count(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes()) {
- total_smbds = 0;
- if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
- return 1;
- process_count_update_successful = True;
- return total_smbds + 1;
- }
- return 1;
-}
-
-void decrement_smbd_process_count(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes() && process_count_update_successful) {
- total_smbds = 1;
- tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
- }
-}
-
-static BOOL smbd_process_limit(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes()) {
-
- /* Always add one to the smbd process count, as exit_server() always
- * subtracts one.
- */
-
- if (!conn_tdb_ctx()) {
- DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
-set. Ignoring max smbd restriction.\n"));
- return False;
- }
-
- total_smbds = increment_smbd_process_count();
- return total_smbds > lp_max_smbd_processes();
- }
- else
- return False;
-}
-
-/****************************************************************************
- Process an smb from the client - split out from the smbd_process() code so
- it can be used by the oplock break code.
-****************************************************************************/
-
void process_smb(char *inbuf, char *outbuf)
{
- static int trans_num;
- int msg_type = CVAL(inbuf,0);
- int32 len = smb_len(inbuf);
- int nread = len + 4;
-
- DO_PROFILE_INC(smb_count);
-
- if (trans_num == 0) {
- /* on the first packet, check the global hosts allow/ hosts
- deny parameters before doing any parsing of the packet
- passed to us by the client. This prevents attacks on our
- parsing code from hosts not in the hosts allow list */
- if (smbd_process_limit() ||
- !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
- /* send a negative session response "not listening on calling name" */
- static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
- DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) );
- (void)send_smb(smbd_server_fd(),(char *)buf);
- exit_server("connection denied");
- }
- }
-
- DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
- DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
-
- if (msg_type == 0)
- show_msg(inbuf);
- else if(msg_type == SMBkeepalive)
- return; /* Keepalive packet. */
-
- nread = construct_reply(inbuf,outbuf,nread,max_send);
+#ifdef WITH_SSL
+ extern BOOL sslEnabled; /* don't use function for performance reasons */
+ static int sslConnected = 0;
+#endif /* WITH_SSL */
+ static int trans_num;
+ int msg_type = CVAL(inbuf,0);
+ int32 len = smb_len(inbuf);
+ int nread = len + 4;
+
+ DO_PROFILE_INC(smb_count);
+
+ if (trans_num == 0) {
+ /* on the first packet, check the global hosts allow/ hosts
+ deny parameters before doing any parsing of the packet
+ passed to us by the client. This prevents attacks on our
+ parsing code from hosts not in the hosts allow list */
+ if (!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
+ /* send a negative session response "not listening on calling
+ name" */
+ static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
+ DEBUG( 1, ( "Connection denied from %s\n",
+ client_addr() ) );
+ (void)send_smb(smbd_server_fd(),(char *)buf);
+ exit_server("connection denied");
+ }
+ }
+
+ DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
+ DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
+
+#ifdef WITH_SSL
+ if(sslEnabled && !sslConnected){
+ sslConnected = sslutil_negotiate_ssl(smbd_server_fd(), msg_type);
+ if(sslConnected < 0){ /* an error occured */
+ exit_server("SSL negotiation failed");
+ }else if(sslConnected){
+ trans_num++;
+ return;
+ }
+ }
+#endif /* WITH_SSL */
+
+ if (msg_type == 0)
+ show_msg(inbuf);
+ else if(msg_type == 0x85)
+ return; /* Keepalive packet. */
+
+ nread = construct_reply(inbuf,outbuf,nread,max_send);
- if(nread > 0) {
- if (CVAL(outbuf,0) == 0)
- show_msg(outbuf);
+ if(nread > 0)
+ {
+ if (CVAL(outbuf,0) == 0)
+ show_msg(outbuf);
- if (nread != smb_len(outbuf) + 4) {
- DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread, smb_len(outbuf)));
- } else if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server("process_smb: send_smb failed.");
- }
- }
- trans_num++;
+ if (nread != smb_len(outbuf) + 4)
+ {
+ DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
+ nread, smb_len(outbuf)));
+ }
+ else
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("process_smb: send_smb failed.\n");
+ }
+ trans_num++;
}
+
+
/****************************************************************************
- Return a string containing the function name of a SMB command.
+return a string containing the function name of a SMB command
****************************************************************************/
-
const char *smb_fn_name(int type)
{
- const char *unknown_name = "SMBunknown";
+ static const char *unknown_name = "SMBunknown";
if (smb_messages[type].name == NULL)
return(unknown_name);
@@ -924,128 +896,120 @@ const char *smb_fn_name(int type)
return(smb_messages[type].name);
}
+
/****************************************************************************
- Helper functions for contruct_reply.
+ Helper function for contruct_reply.
****************************************************************************/
-static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY|FLAGS2_32_BIT_ERROR_CODES;
-
-void remove_from_common_flags2(uint32 v)
-{
- common_flags2 &= ~v;
-}
-
void construct_reply_common(char *inbuf,char *outbuf)
{
- memset(outbuf,'\0',smb_size);
-
- set_message(outbuf,0,0,True);
- SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
-
- memcpy(outbuf+4,inbuf+4,4);
- SCVAL(outbuf,smb_rcls,SMB_SUCCESS);
- SCVAL(outbuf,smb_reh,0);
- SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
- SSVAL(outbuf,smb_flg2,
- (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
- common_flags2);
-
- SSVAL(outbuf,smb_err,SMB_SUCCESS);
- SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
- SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
- SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
- SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
+ memset(outbuf,'\0',smb_size);
+
+ set_message(outbuf,0,0,True);
+ SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
+
+ memcpy(outbuf+4,inbuf+4,4);
+ SCVAL(outbuf,smb_rcls,SMB_SUCCESS);
+ SCVAL(outbuf,smb_reh,0);
+ SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
+ means a reply */
+ SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS);
+ /* say we support long filenames */
+
+ SSVAL(outbuf,smb_err,SMB_SUCCESS);
+ SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
+ SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
+ SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
+ SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
}
/****************************************************************************
- Construct a chained reply and add it to the already made reply
-****************************************************************************/
-
+ construct a chained reply and add it to the already made reply
+ **************************************************************************/
int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
{
- static char *orig_inbuf;
- static char *orig_outbuf;
- int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
- unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
- char *inbuf2, *outbuf2;
- int outsize2;
- char inbuf_saved[smb_wct];
- char outbuf_saved[smb_wct];
- int wct = CVAL(outbuf,smb_wct);
- int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
-
- /* maybe its not chained */
- if (smb_com2 == 0xFF) {
- SCVAL(outbuf,smb_vwv0,0xFF);
- return outsize;
- }
-
- if (chain_size == 0) {
- /* this is the first part of the chain */
- orig_inbuf = inbuf;
- orig_outbuf = outbuf;
- }
-
- /*
- * The original Win95 redirector dies on a reply to
- * a lockingX and read chain unless the chain reply is
- * 4 byte aligned. JRA.
- */
-
- outsize = (outsize + 3) & ~3;
-
- /* we need to tell the client where the next part of the reply will be */
- SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
- SCVAL(outbuf,smb_vwv0,smb_com2);
-
- /* remember how much the caller added to the chain, only counting stuff
- after the parameter words */
- chain_size += outsize - smb_wct;
-
- /* work out pointers into the original packets. The
- headers on these need to be filled in */
- inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
- outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
-
- /* remember the original command type */
- smb_com1 = CVAL(orig_inbuf,smb_com);
-
- /* save the data which will be overwritten by the new headers */
- memcpy(inbuf_saved,inbuf2,smb_wct);
- memcpy(outbuf_saved,outbuf2,smb_wct);
-
- /* give the new packet the same header as the last part of the SMB */
- memmove(inbuf2,inbuf,smb_wct);
-
- /* create the in buffer */
- SCVAL(inbuf2,smb_com,smb_com2);
-
- /* create the out buffer */
- construct_reply_common(inbuf2, outbuf2);
-
- DEBUG(3,("Chained message\n"));
- show_msg(inbuf2);
-
- /* process the request */
- outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
- bufsize-chain_size);
-
- /* copy the new reply and request headers over the old ones, but
- preserve the smb_com field */
- memmove(orig_outbuf,outbuf2,smb_wct);
- SCVAL(orig_outbuf,smb_com,smb_com1);
-
- /* restore the saved data, being careful not to overwrite any
- data from the reply header */
- memcpy(inbuf2,inbuf_saved,smb_wct);
-
- {
- int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
- if (ofs < 0) ofs = 0;
- memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
- }
-
- return outsize2;
+ static char *orig_inbuf;
+ static char *orig_outbuf;
+ int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
+ unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
+ char *inbuf2, *outbuf2;
+ int outsize2;
+ char inbuf_saved[smb_wct];
+ char outbuf_saved[smb_wct];
+ int wct = CVAL(outbuf,smb_wct);
+ int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+
+ /* maybe its not chained */
+ if (smb_com2 == 0xFF) {
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ return outsize;
+ }
+
+ if (chain_size == 0) {
+ /* this is the first part of the chain */
+ orig_inbuf = inbuf;
+ orig_outbuf = outbuf;
+ }
+
+ /*
+ * The original Win95 redirector dies on a reply to
+ * a lockingX and read chain unless the chain reply is
+ * 4 byte aligned. JRA.
+ */
+
+ outsize = (outsize + 3) & ~3;
+
+ /* we need to tell the client where the next part of the reply will be */
+ SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
+ SCVAL(outbuf,smb_vwv0,smb_com2);
+
+ /* remember how much the caller added to the chain, only counting stuff
+ after the parameter words */
+ chain_size += outsize - smb_wct;
+
+ /* work out pointers into the original packets. The
+ headers on these need to be filled in */
+ inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
+ outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
+
+ /* remember the original command type */
+ smb_com1 = CVAL(orig_inbuf,smb_com);
+
+ /* save the data which will be overwritten by the new headers */
+ memcpy(inbuf_saved,inbuf2,smb_wct);
+ memcpy(outbuf_saved,outbuf2,smb_wct);
+
+ /* give the new packet the same header as the last part of the SMB */
+ memmove(inbuf2,inbuf,smb_wct);
+
+ /* create the in buffer */
+ SCVAL(inbuf2,smb_com,smb_com2);
+
+ /* create the out buffer */
+ construct_reply_common(inbuf2, outbuf2);
+
+ DEBUG(3,("Chained message\n"));
+ show_msg(inbuf2);
+
+ /* process the request */
+ outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
+ bufsize-chain_size);
+
+ /* copy the new reply and request headers over the old ones, but
+ preserve the smb_com field */
+ memmove(orig_outbuf,outbuf2,smb_wct);
+ SCVAL(orig_outbuf,smb_com,smb_com1);
+
+ /* restore the saved data, being careful not to overwrite any
+ data from the reply header */
+ memcpy(inbuf2,inbuf_saved,smb_wct);
+ {
+ int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
+ if (ofs < 0) ofs = 0;
+ memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
+ }
+
+ return outsize2;
}
/****************************************************************************
@@ -1061,11 +1025,7 @@ static int setup_select_timeout(void)
select_timeout *= 1000;
t = change_notify_timeout();
- if (t != -1)
- select_timeout = MIN(select_timeout, t*1000);
-
- if (print_notify_messages_pending())
- select_timeout = MIN(select_timeout, 1000);
+ if (t != -1) select_timeout = MIN(select_timeout, t*1000);
return select_timeout;
}
@@ -1076,16 +1036,17 @@ static int setup_select_timeout(void)
void check_reload(int t)
{
- static time_t last_smb_conf_reload_time = 0;
+ static time_t last_smb_conf_reload_time = 0;
- if(last_smb_conf_reload_time == 0)
- last_smb_conf_reload_time = t;
+ if(last_smb_conf_reload_time == 0)
+ last_smb_conf_reload_time = t;
- if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
- reload_services(True);
- reload_after_sighup = False;
- last_smb_conf_reload_time = t;
- }
+ if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK))
+ {
+ reload_services(True);
+ reload_after_sighup = 0;
+ last_smb_conf_reload_time = t;
+ }
}
/****************************************************************************
@@ -1094,164 +1055,151 @@ void check_reload(int t)
static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
{
- static time_t last_keepalive_sent_time = 0;
- static time_t last_idle_closed_check = 0;
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
-
- if (smb_read_error == READ_EOF) {
- DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
- return False;
- }
-
- if (smb_read_error == READ_ERROR) {
- DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
- strerror(errno)));
- return False;
- }
-
- if (smb_read_error == READ_BAD_SIG) {
- DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
- return False;
- }
-
- *last_timeout_processing_time = t = time(NULL);
-
- if(last_keepalive_sent_time == 0)
- last_keepalive_sent_time = t;
-
- if(last_idle_closed_check == 0)
- last_idle_closed_check = t;
-
- /* become root again if waiting */
- change_to_root_user();
-
- /* run all registered idle events */
- smb_run_idle_events(t);
-
- /* check if we need to reload services */
- check_reload(t);
-
- /* automatic timeout if all connections are closed */
- if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) {
- DEBUG( 2, ( "Closing idle connection\n" ) );
- return False;
- } else {
- last_idle_closed_check = t;
- }
-
- if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
- extern struct auth_context *negprot_global_auth_context;
- if (!send_keepalive(smbd_server_fd())) {
- DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
- return False;
- }
-
- /* send a keepalive for a password server or the like.
- This is attached to the auth_info created in the
- negprot */
- if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method
- && negprot_global_auth_context->challenge_set_method->send_keepalive) {
-
- negprot_global_auth_context->challenge_set_method->send_keepalive
- (&negprot_global_auth_context->challenge_set_method->private_data);
- }
-
- last_keepalive_sent_time = t;
- }
-
- /* check for connection timeouts */
- allidle = conn_idle_all(t, deadtime);
-
- if (allidle && conn_num_open()>0) {
- DEBUG(2,("Closing idle connection 2.\n"));
- return False;
- }
-
- if(global_machine_password_needs_changing &&
- /* for ADS we need to do a regular ADS password change, not a domain
- password change */
- lp_security() == SEC_DOMAIN) {
-
- unsigned char trust_passwd_hash[16];
- time_t lct;
-
- /*
- * We're in domain level security, and the code that
- * read the machine password flagged that the machine
- * password needs changing.
- */
-
- /*
- * First, open the machine password file with an exclusive lock.
- */
-
- if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
- DEBUG(0,("process: unable to lock the machine account password for \
-machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
- return True;
- }
-
- if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
- DEBUG(0,("process: unable to read the machine account password for \
-machine %s in domain %s.\n", global_myname(), lp_workgroup()));
- secrets_lock_trust_account_password(lp_workgroup(), False);
- return True;
- }
-
- /*
- * Make sure someone else hasn't already done this.
- */
-
- if(t < lct + lp_machine_password_timeout()) {
- global_machine_password_needs_changing = False;
- secrets_lock_trust_account_password(lp_workgroup(), False);
- return True;
- }
-
- /* always just contact the PDC here */
-
- change_trust_account_password( lp_workgroup(), NULL);
- global_machine_password_needs_changing = False;
- secrets_lock_trust_account_password(lp_workgroup(), False);
- }
-
- /*
- * Check to see if we have any blocking locks
- * outstanding on the queue.
- */
- process_blocking_lock_queue(t);
-
- /* update printer queue caches if necessary */
-
- update_monitored_printq_cache();
-
- /*
- * Check to see if we have any change notifies
- * outstanding on the queue.
- */
- process_pending_change_notify_queue(t);
-
- /*
- * Now we are root, check if the log files need pruning.
- * Force a log file check.
- */
- force_check_log_size();
- check_log_size();
-
- /* Send any queued printer notify message to interested smbd's. */
-
- print_notify_send_messages(0);
-
- /*
- * Modify the select timeout depending upon
- * what we have remaining in our queues.
- */
-
- *select_timeout = setup_select_timeout();
-
- return True;
+ static time_t last_keepalive_sent_time = 0;
+ static time_t last_idle_closed_check = 0;
+ time_t t;
+ BOOL allidle = True;
+ extern int keepalive;
+
+ if (smb_read_error == READ_EOF)
+ {
+ DEBUG(3,("end of file from client\n"));
+ return False;
+ }
+
+ if (smb_read_error == READ_ERROR)
+ {
+ DEBUG(3,("receive_smb error (%s) exiting\n",
+ strerror(errno)));
+ return False;
+ }
+
+ *last_timeout_processing_time = t = time(NULL);
+
+ if(last_keepalive_sent_time == 0)
+ last_keepalive_sent_time = t;
+
+ if(last_idle_closed_check == 0)
+ last_idle_closed_check = t;
+
+ /* become root again if waiting */
+ change_to_root_user();
+
+ /* check if we need to reload services */
+ check_reload(t);
+
+ /* automatic timeout if all connections are closed */
+ if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT)
+ {
+ DEBUG( 2, ( "Closing idle connection\n" ) );
+ return False;
+ }
+ else
+ last_idle_closed_check = t;
+
+ if (keepalive && (t - last_keepalive_sent_time)>keepalive)
+ {
+ struct cli_state *cli = server_client();
+ if (!send_keepalive(smbd_server_fd())) {
+ DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+ return False;
+ }
+ /* also send a keepalive to the password server if its still
+ connected */
+ if (cli && cli->initialised)
+ if (!send_keepalive(cli->fd)) {
+ DEBUG( 2, ( "password server keepalive failed.\n"));
+ cli_shutdown(cli);
+ }
+ last_keepalive_sent_time = t;
+ }
+
+ /* check for connection timeouts */
+ allidle = conn_idle_all(t, deadtime);
+
+ if (allidle && conn_num_open()>0) {
+ DEBUG(2,("Closing idle connection 2.\n"));
+ return False;
+ }
+
+ if(global_machine_password_needs_changing && lp_security() == SEC_DOMAIN)
+ {
+ unsigned char trust_passwd_hash[16];
+ time_t lct;
+ pstring remote_machine_list;
+
+ /*
+ * We're in domain level security, and the code that
+ * read the machine password flagged that the machine
+ * password needs changing.
+ */
+
+ DEBUG(10,("timeout_processing: checking to see if machine account password need changing.\n"));
+
+ /*
+ * First, open the machine password file with an exclusive lock.
+ */
+
+ if (secrets_lock_trust_account_password(global_myworkgroup, True) == False) {
+ DEBUG(0,("process: unable to lock the machine account password for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+ return True;
+ }
+
+ if(!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd_hash, &lct)) {
+ DEBUG(0,("process: unable to read the machine account password for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+ secrets_lock_trust_account_password(global_myworkgroup, False);
+ return True;
+ }
+
+ /*
+ * Make sure someone else hasn't already done this.
+ */
+
+ if(t < lct + lp_machine_password_timeout()) {
+ global_machine_password_needs_changing = False;
+ secrets_lock_trust_account_password(global_myworkgroup, False);
+ return True;
+ }
+
+ DEBUG(10,("timeout_processing: machine account password last change time = (%u) %s.\n",
+ (unsigned int)lct, http_timestring(lct)));
+
+ pstrcpy(remote_machine_list, lp_passwordserver());
+
+ change_trust_account_password( global_myworkgroup, remote_machine_list);
+ global_machine_password_needs_changing = False;
+ secrets_lock_trust_account_password(global_myworkgroup, False);
+ }
+
+ /*
+ * Check to see if we have any blocking locks
+ * outstanding on the queue.
+ */
+ process_blocking_lock_queue(t);
+
+ /*
+ * Check to see if we have any change notifies
+ * outstanding on the queue.
+ */
+ process_pending_change_notify_queue(t);
+
+ /*
+ * Now we are root, check if the log files need pruning.
+ * Force a log file check.
+ */
+ force_check_log_size();
+ check_log_size();
+
+ /*
+ * Modify the select timeout depending upon
+ * what we have remaining in our queues.
+ */
+
+ *select_timeout = setup_select_timeout();
+
+ return True;
}
/****************************************************************************
@@ -1263,20 +1211,23 @@ void smbd_process(void)
extern int smb_echo_count;
time_t last_timeout_processing_time = time(NULL);
unsigned int num_smbs = 0;
- const size_t total_buffer_size = BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN;
- InBuffer = (char *)malloc(total_buffer_size);
- OutBuffer = (char *)malloc(total_buffer_size);
+ InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
+ OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
if ((InBuffer == NULL) || (OutBuffer == NULL))
return;
-#if defined(DEVELOPER)
- clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
- clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
-#endif
+ InBuffer += SMB_ALIGNMENT;
+ OutBuffer += SMB_ALIGNMENT;
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+ /* re-initialise the timezone */
+ TimeInit();
+
+ /* register our message handlers */
+ message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
+
while (True) {
int deadtime = lp_deadtime()*60;
int select_timeout = setup_select_timeout();
@@ -1291,10 +1242,6 @@ void smbd_process(void)
lp_talloc_free();
main_loop_talloc_free();
- /* run all registered idle events */
- smb_run_idle_events(time(NULL));
-
-
/* Did someone ask for immediate checks on things like blocking locks ? */
if (select_timeout == 0) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
@@ -1302,10 +1249,6 @@ void smbd_process(void)
num_smbs = 0; /* Reset smb counter. */
}
-#if defined(DEVELOPER)
- clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
-#endif
-
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
@@ -1323,8 +1266,6 @@ void smbd_process(void)
*/
num_echos = smb_echo_count;
- clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
-
process_smb(InBuffer, OutBuffer);
if (smb_echo_count != num_echos) {
@@ -1351,17 +1292,5 @@ void smbd_process(void)
last_timeout_processing_time = new_check_time; /* Reset time. */
}
}
-
- /* The timeout_processing function isn't run nearly
- often enough to implement 'max log size' without
- overrunning the size of the file by many megabytes.
- This is especially true if we are running at debug
- level 10. Checking every 50 SMBs is a nice
- tradeoff of performance vs log file size overrun. */
-
- if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
- change_to_root_user();
- check_log_size();
- }
}
}
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index e439c1e571a..bce04fbe4c5 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
support for quotas
Copyright (C) Andrew Tridgell 1992-1998
@@ -27,18 +28,6 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_QUOTA
-
-#ifndef HAVE_SYS_QUOTAS
-
-/* just a quick hack because sysquotas.h is included before linux/quota.h */
-#ifdef QUOTABLOCK_SIZE
-#undef QUOTABLOCK_SIZE
-#endif
-
-#ifdef WITH_QUOTAS
-
#if defined(VXFS_QUOTA)
/*
@@ -62,7 +51,6 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
*/
#include "samba_linux_quota.h"
-#include "samba_xfs_quota.h"
typedef struct _LINUX_SMB_DISK_QUOTA {
SMB_BIG_UINT bsize;
@@ -78,52 +66,40 @@ typedef struct _LINUX_SMB_DISK_QUOTA {
Abstract out the XFS Quota Manager quota get call.
****************************************************************************/
-static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
{
- struct fs_disk_quota D;
- int ret;
-
- ZERO_STRUCT(D);
-
- ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
-
- if (ret)
- ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
-
- if (ret)
- return ret;
-
- dp->bsize = (SMB_BIG_UINT)512;
- dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
- dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
- dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
- dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
- dp->curinodes = (SMB_BIG_UINT)D.d_icount;
- dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
-
- return ret;
+ int ret = -1;
+ struct fs_disk_quota D;
+ ZERO_STRUCT(D);
+
+ if ((ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return ret;
+
+ dp->bsize = (SMB_BIG_UINT)512;
+ dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
+ dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
+ dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
+ dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
+ dp->curinodes = (SMB_BIG_UINT)D.d_icount;
+ dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
+ return ret;
}
/****************************************************************************
Abstract out the old and new Linux quota get calls.
****************************************************************************/
-static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_v1_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
{
struct v1_kern_dqblk D;
int ret;
ZERO_STRUCT(D);
+ dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
- ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- return ret;
+ if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return -1;
- dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
@@ -131,25 +107,20 @@ static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LIN
dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
- return ret;
+ return 0;
}
-static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_v2_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
{
struct v2_kern_dqblk D;
int ret;
ZERO_STRUCT(D);
+ dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
- ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- return ret;
+ if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return -1;
- dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
@@ -157,29 +128,24 @@ static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LIN
dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize;
- return ret;
+ return 0;
}
/****************************************************************************
Brand-new generic quota interface.
****************************************************************************/
-static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_gen_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
{
struct if_dqblk D;
int ret;
ZERO_STRUCT(D);
+ dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
- ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
-
- if (ret && errno != EDQUOT)
- return ret;
+ if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return -1;
- dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
@@ -187,7 +153,7 @@ static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LI
dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize;
- return ret;
+ return 0;
}
/****************************************************************************
@@ -204,11 +170,9 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
SMB_DEV_T devno;
int found;
uid_t euser_id;
- gid_t egrp_id;
euser_id = geteuid();
- egrp_id = getegid();
-
+
/* find the block device file */
if ( sys_stat(path, &S) == -1 )
@@ -237,15 +201,15 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
save_re_uid();
set_effective_uid(0);
- if (strcmp(mnt->mnt_type, "xfs")==0) {
- r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
- } else {
- r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
- if (r == -1 && errno != EDQUOT) {
- r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
- if (r == -1 && errno != EDQUOT)
- r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
+ if (strcmp(mnt->mnt_type, "xfs")) {
+ r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D);
+ if (r == -1) {
+ r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D);
+ if (r == -1)
+ r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D);
}
+ } else {
+ r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
}
restore_re_uid();
@@ -479,7 +443,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
host = strncat(cutstr,mnttype, sizeof(char) * len );
DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr));
DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype));
- testpath=strchr_m(mnttype, ':');
+ testpath=strchr(mnttype, ':');
args.gqa_pathp = testpath+1;
args.gqa_uid = uid;
@@ -562,7 +526,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B
DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize));
- SAFE_FREE(cutstr);
+ safe_free(cutstr);
DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
return ret;
}
@@ -994,11 +958,7 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
#elif defined(AIX)
/* AIX has both USER and GROUP quotas:
Get the USER quota (ohnielse@fysik.dtu.dk) */
- save_re_uid();
- if (set_re_uid() != 0)
- return False;
r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
- restore_re_uid();
#else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
#endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
@@ -1174,106 +1134,3 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
#endif /* SUNOS5 || ... */
#endif /* VXFS_QUOTA */
-
-#else /* WITH_QUOTAS */
-
-BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
-{
- (*bsize) = 512; /* This value should be ignored */
-
- /* And just to be sure we set some values that hopefully */
- /* will be larger that any possible real-world value */
- (*dfree) = (SMB_BIG_UINT)-1;
- (*dsize) = (SMB_BIG_UINT)-1;
-
- /* As we have select not to use quotas, allways fail */
- return False;
-}
-#endif /* WITH_QUOTAS */
-
-#else /* HAVE_SYS_QUOTAS */
-/* wrapper to the new sys_quota interface
- this file should be removed later
- */
-BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
-{
- int r;
- SMB_DISK_QUOTA D;
- unid_t id;
-
- id.uid = geteuid();
-
- ZERO_STRUCT(D);
- r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- *bsize = D.bsize;
- if (r == -1) {
- if (errno == EDQUOT) {
- *dfree =0;
- *dsize =D.curblocks;
- return (True);
- } else {
- goto try_group_quota;
- }
- }
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (D.softlimit && D.curblocks >= D.softlimit) ||
- (D.hardlimit && D.curblocks >= D.hardlimit) ||
- (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
- (D.ihardlimit && D.curinodes>=D.ihardlimit)
- ) {
- *dfree = 0;
- *dsize = D.curblocks;
- } else if (D.softlimit==0 && D.hardlimit==0) {
- goto try_group_quota;
- } else {
- if (D.softlimit == 0)
- D.softlimit = D.hardlimit;
- *dfree = D.softlimit - D.curblocks;
- *dsize = D.softlimit;
- }
-
- return True;
-
-try_group_quota:
- id.gid = getegid();
-
- ZERO_STRUCT(D);
- r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- *bsize = D.bsize;
- if (r == -1) {
- if (errno == EDQUOT) {
- *dfree =0;
- *dsize =D.curblocks;
- return (True);
- } else {
- return False;
- }
- }
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (D.softlimit && D.curblocks >= D.softlimit) ||
- (D.hardlimit && D.curblocks >= D.hardlimit) ||
- (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
- (D.ihardlimit && D.curinodes>=D.ihardlimit)
- ) {
- *dfree = 0;
- *dsize = D.curblocks;
- } else if (D.softlimit==0 && D.hardlimit==0) {
- return False;
- } else {
- if (D.softlimit == 0)
- D.softlimit = D.hardlimit;
- *dfree = D.softlimit - D.curblocks;
- *dsize = D.softlimit;
- }
-
- return (True);
-}
-#endif /* HAVE_SYS_QUOTAS */
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 2046f2370a8..921f1146f15 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1,10 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Main SMB reply routines
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jeremy Allison 1992-2004.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +23,7 @@
makes to handle specific protocols
*/
+
#include "includes.h"
/* look in server.c for some explanation of these variables */
@@ -31,142 +31,33 @@ extern int Protocol;
extern int max_send;
extern int max_recv;
extern char magic_char;
+extern BOOL case_sensitive;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
+extern userdom_struct current_user_info;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
extern int global_oplock_break;
+uint32 global_client_caps = 0;
unsigned int smb_echo_count = 0;
-extern BOOL global_encrypted_passwords_negotiated;
-
/****************************************************************************
- Ensure we check the path in *exactly* the same way as W2K.
- We're assuming here that '/' is not the second byte in any multibyte char
- set (a safe assumption). '\\' *may* be the second byte in a multibyte char
- set.
+ Report a possible attack via the password buffer overflow bug.
****************************************************************************/
-NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
+static void overflow_attack(int len)
{
- char *d = destname;
- const char *s = srcname;
- NTSTATUS ret = NT_STATUS_OK;
-
- while (*s) {
- if (IS_DIRECTORY_SEP(*s)) {
- /*
- * Safe to assume is not the second part of a mb char as this is handled below.
- */
- /* Eat multiple '/' or '\\' */
- while (IS_DIRECTORY_SEP(*s)) {
- s++;
- }
- if ((s[0] == '.') && (s[1] == '\0')) {
- ret = NT_STATUS_OBJECT_NAME_INVALID;
- break;
- }
- if ((d != destname) && (*s != '\0')) {
- /* We only care about non-leading or trailing '/' or '\\' */
- *d++ = '/';
- }
- } else if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
- /* Uh oh - "../" or "..\\" or "..\0" ! */
-
- /*
- * No mb char starts with '.' so we're safe checking the directory separator here.
- */
-
- /* If we just added a '/', delete it. */
-
- if ((d > destname) && (*(d-1) == '/')) {
- *(d-1) = '\0';
- if (d == (destname + 1)) {
- d--;
- } else {
- d -= 2;
- }
- }
- /* Are we at the start ? Can't go back further if so. */
- if (d == destname) {
- ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
- break;
- }
- /* Go back one level... */
- /* We know this is safe as '/' cannot be part of a mb sequence. */
- /* NOTE - if this assumption is invalid we are not in good shape... */
- while (d > destname) {
- if (*d == '/')
- break;
- d--;
- }
- s += 3;
- } else if ((s[0] == '.') && (IS_DIRECTORY_SEP(s[1]) || (s[1] == '\0'))) {
-
- /*
- * No mb char starts with '.' so we're safe checking the directory separator here.
- */
-
- /* "./" or ".\\" fails with a different error depending on where it is... */
-
- if (s == srcname) {
- ret = NT_STATUS_OBJECT_NAME_INVALID;
- break;
- } else {
- if (s[1] != '\0' && s[2] == '\0') {
- ret = NT_STATUS_INVALID_PARAMETER;
- break;
- }
- ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- break;
- }
- s++;
- } else {
- if (!(*s & 0x80)) {
- *d++ = *s++;
- } else {
- switch(next_mb_char_size(s)) {
- case 4:
- *d++ = *s++;
- case 3:
- *d++ = *s++;
- case 2:
- *d++ = *s++;
- case 1:
- *d++ = *s++;
- break;
- default:
- DEBUG(0,("check_path_syntax: character length assumptions invalid !\n"));
- *d = '\0';
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- }
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "ERROR: Invalid password length %d.\n", len );
+ dbgtext( "Your machine may be under attack by someone " );
+ dbgtext( "attempting to exploit an old bug.\n" );
+ dbgtext( "Attack was from IP = %s.\n", client_addr() );
}
- *d = '\0';
- return ret;
}
-/****************************************************************************
- Pull a string and check the path - provide for error return.
-****************************************************************************/
-
-size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err)
-{
- pstring tmppath;
- char *tmppath_ptr = tmppath;
- size_t ret;
-#ifdef DEVELOPER
- SMB_ASSERT(dest_len == sizeof(pstring));
-#endif
-
- if (src_len == 0) {
- ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
- } else {
- ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
- }
- *err = check_path_syntax(dest, tmppath);
- return ret;
-}
/****************************************************************************
- Reply to a special message.
+ Reply to an special message.
****************************************************************************/
int reply_special(char *inbuf,char *outbuf)
@@ -174,11 +65,12 @@ int reply_special(char *inbuf,char *outbuf)
int outsize = 4;
int msg_type = CVAL(inbuf,0);
int msg_flags = CVAL(inbuf,1);
- fstring name1,name2;
+ pstring name1,name2;
+ extern fstring remote_machine;
+ extern fstring local_machine;
+ int len;
char name_type = 0;
- static BOOL already_got_session = False;
-
*name1 = *name2 = 0;
memset(outbuf,'\0',smb_size);
@@ -187,11 +79,6 @@ int reply_special(char *inbuf,char *outbuf)
switch (msg_type) {
case 0x81: /* session request */
-
- if (already_got_session) {
- exit_server("multiple session request not permitted");
- }
-
SCVAL(outbuf,0,0x82);
SCVAL(outbuf,3,0);
if (name_len(inbuf+4) > 50 ||
@@ -200,42 +87,53 @@ int reply_special(char *inbuf,char *outbuf)
return(0);
}
name_extract(inbuf,4,name1);
- name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
+ name_extract(inbuf,4 + name_len(inbuf + 4),name2);
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
- set_local_machine_name(name1, True);
- set_remote_machine_name(name2, True);
+ fstrcpy(remote_machine,name2);
+ remote_machine[15] = 0;
+ trim_string(remote_machine," "," ");
+ strlower(remote_machine);
+ alpha_strcpy(remote_machine,remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
+
+ fstrcpy(local_machine,name1);
+ len = strlen(local_machine);
+ if (len == 16) {
+ name_type = local_machine[15];
+ local_machine[15] = 0;
+ }
+ trim_string(local_machine," "," ");
+ strlower(local_machine);
+ alpha_strcpy(local_machine,local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
- DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
- get_local_machine_name(), get_remote_machine_name(),
- name_type));
+ DEBUG(2,("netbios connect: local=%s remote=%s\n",
+ local_machine, remote_machine ));
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
no thanks! */
- SCVAL(outbuf, 0,0x83);
+ SCVAL(outbuf, 0, 0x83);
break;
}
- /* only add the client's machine name to the list
- of possibly valid usernames if we are operating
- in share mode security */
+ /* add it as a possible user name if we
+ are in share mode security */
if (lp_security() == SEC_SHARE) {
- add_session_user(get_remote_machine_name());
+ add_session_user(remote_machine);
}
reload_services(True);
reopen_logs();
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
- already_got_session = True;
break;
case 0x89: /* session keepalive request
(some old clients produce this?) */
- SCVAL(outbuf,0,SMBkeepalive);
+ SCVAL(outbuf,0,0x85);
SCVAL(outbuf,3,0);
break;
@@ -245,7 +143,7 @@ int reply_special(char *inbuf,char *outbuf)
DEBUG(0,("Unexpected session response\n"));
break;
- case SMBkeepalive: /* session keepalive */
+ case 0x85: /* session keepalive */
default:
return(0);
}
@@ -256,6 +154,53 @@ int reply_special(char *inbuf,char *outbuf)
return(outsize);
}
+/*******************************************************************
+ Work out what error to give to a failed connection.
+********************************************************************/
+
+static int connection_error(char *outbuf, int ecode)
+{
+ if (ecode == ERRnoipc || ecode == ERRnosuchshare)
+ return(ERROR_DOS(ERRDOS,ecode));
+
+ return(ERROR_DOS(ERRSRV,ecode));
+}
+
+/****************************************************************************
+ Parse a share descriptor string.
+****************************************************************************/
+
+static void parse_connect(char *p,char *service,char *user,
+ char *password,int *pwlen,char *dev)
+{
+ char *p2;
+
+ DEBUG(4,("parsing connect string %s\n",p));
+
+ p2 = strrchr(p,'\\');
+ if (p2 == NULL)
+ fstrcpy(service,p);
+ else
+ fstrcpy(service,p2+1);
+
+ p += strlen(p) + 2;
+
+ fstrcpy(password,p);
+ *pwlen = strlen(password);
+
+ p += strlen(p) + 2;
+
+ fstrcpy(dev,p);
+
+ *user = 0;
+ p = strchr(service,'%');
+ if (p != NULL)
+ {
+ *p = 0;
+ fstrcpy(user,p+1);
+ }
+}
+
/****************************************************************************
Reply to a tcon.
****************************************************************************/
@@ -263,43 +208,54 @@ int reply_special(char *inbuf,char *outbuf)
int reply_tcon(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- const char *service;
- pstring service_buf;
+ BOOL doencrypt = SMBENCRYPT();
+ pstring service;
+ pstring user;
pstring password;
pstring dev;
int outsize = 0;
uint16 vuid = SVAL(inbuf,smb_uid);
int pwlen=0;
- NTSTATUS nt_status;
- char *p;
- DATA_BLOB password_blob;
-
+ int ecode = -1;
START_PROFILE(SMBtcon);
- *service_buf = *password = *dev = 0;
+ *service = *user = *password = *dev = 0;
- p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
- pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
- p += pwlen;
- p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
+ parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
- p = strrchr_m(service_buf,'\\');
- if (p) {
- service = p+1;
- } else {
- service = service_buf;
+ /*
+ * If the vuid is valid, we should be using that....
+ */
+
+ if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) {
+ pstrcpy(user,validated_username(vuid));
}
- password_blob = data_blob(password, pwlen+1);
+ /*
+ * Ensure the user and password names are in UNIX codepage format.
+ */
+
+ pstrcpy(user,dos_to_unix_static(user));
+ if (!doencrypt)
+ pstrcpy(password,dos_to_unix_static(password));
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
- conn = make_connection(service,password_blob,dev,vuid,&nt_status);
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
- data_blob_clear_free(&password_blob);
+ conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
if (!conn) {
END_PROFILE(SMBtcon);
- return ERROR_NT(nt_status);
+ return(connection_error(outbuf,ecode));
}
outsize = set_message(outbuf,2,0,True);
@@ -307,8 +263,8 @@ int reply_tcon(connection_struct *conn,
SSVAL(outbuf,smb_vwv1,conn->cnum);
SSVAL(outbuf,smb_tid,conn->cnum);
- DEBUG(3,("tcon service=%s cnum=%d\n",
- service, conn->cnum));
+ DEBUG(3,("tcon service=%s user=%s cnum=%d\n",
+ service, user, conn->cnum));
END_PROFILE(SMBtcon);
return(outsize);
@@ -321,22 +277,18 @@ int reply_tcon(connection_struct *conn,
int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
fstring service;
- DATA_BLOB password;
-
- /* what the cleint thinks the device is */
- fstring client_devicetype;
- /* what the server tells the client the share represents */
- const char *server_devicetype;
- NTSTATUS nt_status;
+ pstring user;
+ pstring password;
+ pstring devicename;
+ BOOL doencrypt = SMBENCRYPT();
+ int ecode = -1;
uint16 vuid = SVAL(inbuf,smb_uid);
int passlen = SVAL(inbuf,smb_vwv3);
- pstring path;
- char *p, *q;
- extern BOOL global_encrypted_passwords_negotiated;
+ char *path;
+ char *p;
+ START_PROFILE(SMBtconX);
- START_PROFILE(SMBtconX);
-
- *service = *client_devicetype = 0;
+ *service = *user = *password = *devicename = 0;
/* we might have to close an old one */
if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
@@ -344,74 +296,91 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
if (passlen > MAX_PASS_LEN) {
- return ERROR_DOS(ERRDOS,ERRbuftoosmall);
+ overflow_attack(passlen);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
}
- if (global_encrypted_passwords_negotiated) {
- password = data_blob(smb_buf(inbuf),passlen);
- } else {
- password = data_blob(smb_buf(inbuf),passlen+1);
- /* Ensure correct termination */
- password.data[passlen]=0;
- }
+ memcpy(password,smb_buf(inbuf),passlen);
+ password[passlen]=0;
+ path = smb_buf(inbuf) + passlen;
- p = smb_buf(inbuf) + passlen;
- p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
+ if (passlen != 24) {
+ if (strequal(password," "))
+ *password = 0;
+ passlen = strlen(password);
+ }
/*
* the service name can be either: \\server\share
* or share directly like on the DELL PowerVault 705
*/
if (*path=='\\') {
- q = strchr_m(path+2,'\\');
- if (!q) {
+ p = strchr(path+2,'\\');
+ if (!p) {
END_PROFILE(SMBtconX);
return(ERROR_DOS(ERRDOS,ERRnosuchshare));
}
- fstrcpy(service,q+1);
+ fstrcpy(service,p+1);
}
else
fstrcpy(service,path);
- p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
+ p = strchr(service,'%');
+ if (p) {
+ *p++ = 0;
+ fstrcpy(user,p);
+ }
+ StrnCpy(devicename,path + strlen(path) + 1,6);
+ DEBUG(4,("Got device type %s\n",devicename));
- DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
+ /*
+ * If the vuid is valid, we should be using that....
+ */
- conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
-
- data_blob_clear_free(&password);
+ if (*user == '\0' && (lp_security() != SEC_SHARE) && validated_username(vuid)) {
+ pstrcpy(user,validated_username(vuid));
+ }
+
+ /*
+ * Ensure the user and password names are in UNIX codepage format.
+ */
+ pstrcpy(user,dos_to_unix_static(user));
+ if (!doencrypt)
+ pstrcpy(password,dos_to_unix_static(password));
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam(user, True);
+
+ conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
+
if (!conn) {
END_PROFILE(SMBtconX);
- return ERROR_NT(nt_status);
+ return(connection_error(outbuf,ecode));
}
- if ( IS_IPC(conn) )
- server_devicetype = "IPC";
- else if ( IS_PRINT(conn) )
- server_devicetype = "LPT1:";
- else
- server_devicetype = "A:";
-
if (Protocol < PROTOCOL_NT1) {
- set_message(outbuf,2,0,True);
- p = smb_buf(outbuf);
- p += srvstr_push(outbuf, p, server_devicetype, -1,
- STR_TERMINATE|STR_ASCII);
- set_message_end(outbuf,p);
+ set_message(outbuf,2,strlen(devicename)+1,True);
+ pstrcpy(smb_buf(outbuf),devicename);
} else {
- /* NT sets the fstype of IPC$ to the null string */
- const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
-
- set_message(outbuf,3,0,True);
+ char *fsname = lp_fstype(SNUM(conn));
+
+ set_message(outbuf,3,3,True);
p = smb_buf(outbuf);
- p += srvstr_push(outbuf, p, server_devicetype, -1,
- STR_TERMINATE|STR_ASCII);
- p += srvstr_push(outbuf, p, fstype, -1,
- STR_TERMINATE);
+ pstrcpy(p,devicename); p = skip_string(p,1); /* device name */
+ pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
- set_message_end(outbuf,p);
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
/* what does setting this bit do? It is set by NT4 and
may affect the ability to autorun mounted cdroms */
@@ -422,8 +391,8 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
- DEBUG(3,("tconX service=%s \n",
- service));
+ DEBUG(3,("tconX service=%s user=%s\n",
+ service, user));
/* set the incoming and outgoing tid to the just created one */
SSVAL(inbuf,smb_tid,conn->cnum);
@@ -460,11 +429,13 @@ int reply_ioctl(connection_struct *conn,
uint32 ioctl_code = (device << 16) + function;
int replysize, outsize;
char *p;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBioctl);
DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
- switch (ioctl_code) {
+ switch (ioctl_code)
+ {
case IOCTL_QUERY_JOB_INFO:
replysize = 32;
break;
@@ -479,19 +450,13 @@ int reply_ioctl(connection_struct *conn,
SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
p = smb_buf(outbuf) + 1; /* Allow for alignment */
- switch (ioctl_code) {
- case IOCTL_QUERY_JOB_INFO:
- {
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- if (!fsp) {
- END_PROFILE(SMBioctl);
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
- SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
- srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
- srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
- break;
- }
+ switch (ioctl_code)
+ {
+ case IOCTL_QUERY_JOB_INFO:
+ SSVAL(p,0,fsp->print_jobid); /* Job number */
+ StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
+ break;
}
END_PROFILE(SMBioctl);
@@ -499,212 +464,848 @@ int reply_ioctl(connection_struct *conn,
}
/****************************************************************************
- Reply to a chkpth.
-****************************************************************************/
+ Always return an error: it's just a matter of which one...
+ ****************************************************************************/
-int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
+ char *smb_passwd, int smb_passlen,
+ char *smb_nt_passwd, int smb_nt_passlen)
{
- int outsize = 0;
- int mode;
- pstring name;
- BOOL ok = False;
- BOOL bad_path = False;
- SMB_STRUCT_STAT sbuf;
- NTSTATUS status;
+ SAM_ACCOUNT *sam_trust_acct = NULL; /* check if trust account exists */
+ uint16 acct_ctrl;
- START_PROFILE(SMBchkpth);
-
- srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBchkpth);
- return ERROR_NT(status);
+ if (lp_security() == SEC_USER) {
+ pdb_init_sam(&sam_trust_acct);
+ pdb_getsampwnam(sam_trust_acct, user);
+ } else {
+ DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
-
- unix_convert(name,conn,0,&bad_path,&sbuf);
+ if (sam_trust_acct == NULL) {
+ /* lkclXXXX: workstation entry doesn't exist */
+ DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
+ return(ERROR_BOTH(NT_STATUS_NO_SUCH_USER,ERRDOS,1317));
+ } else {
+ if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
+ DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
- mode = SVAL(inbuf,smb_vwv0);
+ if (!smb_password_ok(sam_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd)) {
+ DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
- if (check_name(name,conn)) {
- if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
- if (!(ok = S_ISDIR(sbuf.st_mode))) {
- END_PROFILE(SMBchkpth);
- return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
- }
- }
+ acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct);
+ if (acct_ctrl & ACB_DOMTRUST) {
+ DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT,ERRDOS,1807));
+ }
- if (!ok) {
- /* We special case this - as when a Windows machine
- is parsing a path is steps through the components
- one at a time - if a component fails it expects
- ERRbadpath, not ERRbadfile.
- */
- if(errno == ENOENT) {
- /*
- * Windows returns different error codes if
- * the parent directory is valid but not the
- * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
- * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
- * if the path is invalid.
- */
- if (bad_path) {
- END_PROFILE(SMBchkpth);
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
- } else {
- END_PROFILE(SMBchkpth);
- return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
- }
- } else if (errno == ENOTDIR) {
- END_PROFILE(SMBchkpth);
- return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
+ if (acct_ctrl & ACB_SVRTRUST) {
+ DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT,ERRDOS,1809));
}
- END_PROFILE(SMBchkpth);
- return(UNIXERROR(ERRDOS,ERRbadpath));
+ if (acct_ctrl & ACB_WSTRUST) {
+ DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT,ERRDOS,1808));
+ }
}
- outsize = set_message(outbuf,0,0,True);
+ /* don't know what to do: indicate logon failure */
+ pdb_free_sam(sam_trust_acct);
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRDOS,1326));
+}
- DEBUG(3,("chkpth %s mode=%d\n", name, mode));
+/****************************************************************************
+ Create a UNIX user on demand.
+****************************************************************************/
- END_PROFILE(SMBchkpth);
- return(outsize);
+int smb_create_user(char *unix_user, char *homedir)
+{
+ pstring add_script;
+ int ret;
+
+ pstrcpy(add_script, lp_adduser_script());
+ if (! *add_script)
+ return -1;
+ all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
+ if (homedir)
+ all_string_sub(add_script, "%H", homedir, sizeof(pstring));
+ ret = smbrun(add_script,NULL);
+ DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
+ return ret;
}
/****************************************************************************
- Reply to a getatr.
+ Delete a UNIX user on demand.
****************************************************************************/
-int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+static int smb_delete_user(char *unix_user)
{
- pstring fname;
- int outsize = 0;
- SMB_STRUCT_STAT sbuf;
- BOOL ok = False;
- int mode=0;
- SMB_OFF_T size=0;
- time_t mtime=0;
- BOOL bad_path = False;
- char *p;
- NTSTATUS status;
+ pstring del_script;
+ int ret;
- START_PROFILE(SMBgetatr);
+ /*
+ * Sanity check -- do not delete 'root' account
+ */
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBgetatr);
- return ERROR_NT(status);
+ if (StrCaseCmp("root", unix_user) == 0) {
+ DEBUG(0,("smb_delete_user: Will not delete the [%s] user account!\n", unix_user));
+ return -1;
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
-
- /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
- under WfWg - weird! */
- if (! (*fname)) {
- mode = aHIDDEN | aDIR;
- if (!CAN_WRITE(conn))
- mode |= aRONLY;
- size = 0;
- mtime = 0;
- ok = True;
- } else {
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (check_name(fname,conn)) {
- if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
- mode = dos_mode(conn,fname,&sbuf);
- size = sbuf.st_size;
- mtime = sbuf.st_mtime;
- if (mode & aDIR)
- size = 0;
- ok = True;
- } else {
- DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
- }
- }
+ pstrcpy(del_script, lp_deluser_script());
+ if (! *del_script)
+ return -1;
+ all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
+ ret = smbrun(del_script,NULL);
+ DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
+ return ret;
+}
+
+/****************************************************************************
+ Check user is in correct domain if required
+****************************************************************************/
+
+static BOOL check_domain_match(char *user, char *domain)
+{
+ /*
+ * If we aren't serving to trusted domains, we must make sure that
+ * the validation request comes from an account in the same domain
+ * as the Samba server
+ */
+
+ if (!lp_allow_trusted_domains() &&
+ !strequal(lp_workgroup(), domain) ) {
+ DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
+ return False;
+ } else {
+ return True;
+ }
+}
+
+/****************************************************************************
+ Check for a valid username and password in security=server mode.
+****************************************************************************/
+
+static BOOL check_server_security(char *orig_user, char *domain, char *unix_user,
+ char *smb_apasswd, int smb_apasslen,
+ char *smb_ntpasswd, int smb_ntpasslen)
+{
+ BOOL ret = False;
+
+ if(lp_security() != SEC_SERVER)
+ return False;
+
+ if (!check_domain_match(orig_user, domain))
+ return False;
+
+ ret = server_validate(orig_user, domain,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen);
+
+ if(ret) {
+ /*
+ * User validated ok against Domain controller.
+ * If the admin wants us to try and create a UNIX
+ * user on the fly, do so.
+ * Note that we can never delete users when in server
+ * level security as we never know if it was a failure
+ * due to a bad password, or the user really doesn't exist.
+ */
+
+ if(lp_adduser_script() && !smb_getpwnam(unix_user,True))
+ smb_create_user(unix_user, NULL);
}
+
+ return ret;
+}
+
+/****************************************************************************
+ Check for a valid username and password in security=domain mode.
+****************************************************************************/
+
+static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user,
+ char *smb_apasswd, int smb_apasslen,
+ char *smb_ntpasswd, int smb_ntpasslen, NT_USER_TOKEN **pptoken)
+{
+ BOOL ret = False;
+ BOOL user_exists = True;
+ struct passwd *pwd = NULL;
+
+ if(lp_security() != SEC_DOMAIN)
+ return False;
+
+ if (!check_domain_match(orig_user, domain))
+ return False;
+
+ ret = domain_client_validate(orig_user, domain,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen,
+ &user_exists, pptoken);
+
+ if(ret) {
+ /*
+ * User validated ok against Domain controller.
+ * If the admin wants us to try and create a UNIX
+ * user on the fly, do so.
+ */
+ if(user_exists && lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True))) {
+ smb_create_user(unix_user, NULL);
+ }
+
+ if(lp_adduser_script() && *lp_adduser_script() && pwd) {
+ SMB_STRUCT_STAT st;
+
+ /*
+ * Also call smb_create_user if the users home directory
+ * doesn't exist. Used with winbindd to allow the script to
+ * create the home directory for a user mapped with winbindd.
+ */
+
+ if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
+ smb_create_user(unix_user, pwd->pw_dir);
+ }
+
+ } else {
+ /*
+ * User failed to validate ok against Domain controller.
+ * If the failure was "user doesn't exist" and admin
+ * wants us to try and delete that UNIX user on the fly,
+ * do so.
+ */
+ if(!user_exists && lp_deluser_script() && smb_getpwnam(unix_user,True)) {
+ smb_delete_user(unix_user);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ Reply to a session setup command.
+****************************************************************************/
+
+int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ int sess_vuid;
+ gid_t gid;
+ uid_t uid;
+ int smb_bufsize;
+ int smb_apasslen = 0;
+ pstring smb_apasswd;
+ int smb_ntpasslen = 0;
+ pstring smb_ntpasswd;
+ BOOL valid_nt_password = False;
+ BOOL valid_lm_password = False;
+ fstring user;
+ fstring orig_user;
+ BOOL guest=False;
+ static BOOL done_sesssetup = False;
+ BOOL doencrypt = SMBENCRYPT();
+ fstring domain;
+ NT_USER_TOKEN *ptok = NULL;
+
+ START_PROFILE(SMBsesssetupX);
+
+ *smb_apasswd = 0;
+ *smb_ntpasswd = 0;
+ *domain = 0;
+
+ smb_bufsize = SVAL(inbuf,smb_vwv2);
+
+ if (Protocol < PROTOCOL_NT1) {
+ smb_apasslen = SVAL(inbuf,smb_vwv7);
+ if (smb_apasslen > MAX_PASS_LEN) {
+ overflow_attack(smb_apasslen);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
+ }
+
+ memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
+ fstrcpy(user,smb_buf(inbuf)+smb_apasslen);
+ /*
+ * Incoming user is in DOS codepage format. Convert
+ * to UNIX.
+ */
+ fstrcpy(user,dos_to_unix_static(user));
- if (!ok) {
- END_PROFILE(SMBgetatr);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
- }
-
- outsize = set_message(outbuf,10,0,True);
+ if (!doencrypt && (lp_security() != SEC_SERVER)) {
+ smb_apasslen = strlen(smb_apasswd);
+ }
+ } else {
+ uint16 passlen1 = SVAL(inbuf,smb_vwv7);
+ uint16 passlen2 = SVAL(inbuf,smb_vwv8);
+ enum remote_arch_types ra_type = get_remote_arch();
+ char *p = smb_buf(inbuf);
+ char *username_str;
+ fstring native_lanman;
+
- SSVAL(outbuf,smb_vwv0,mode);
- if(lp_dos_filetime_resolution(SNUM(conn)) )
- put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
- else
- put_dos_date3(outbuf,smb_vwv1,mtime);
- SIVAL(outbuf,smb_vwv3,(uint32)size);
+ if(global_client_caps == 0)
+ global_client_caps = IVAL(inbuf,smb_vwv11);
- if (Protocol >= PROTOCOL_NT1)
- SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+ /* client_caps is used as final determination if client is NT or Win95.
+ This is needed to return the correct error codes in some
+ circumstances.
+ */
+
+ if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
+ if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
+ set_remote_arch( RA_WIN95);
+ }
+ }
+
+ username_str = smb_buf(inbuf)+smb_apasslen;
+ fstrcpy( native_lanman, skip_string(username_str, 4));
+
+ /*
+ * we distinguish between 2K and XP by the "Native Lan Manager"
+ * string.
+ * .NET RC2 => "Windows .NET 5.2"
+ * WinXP => "Windows 2002 5.1"
+ * Win2k => "Windows 2000 5.0"
+ * NT4 => (off by one bug) "Windows NT 4.0"
+ * Win9x => "Windows 4.0"
+ */
+ if ( ra_type == RA_WIN2K ) {
+ if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) )
+ set_remote_arch( RA_WINXP );
+ else if ( 0 == strcmp( native_lanman, "Windows .NET 5.2" ) )
+ set_remote_arch( RA_WIN2K3 );
+ }
+
+ if (passlen1 != 24 && passlen2 != 24)
+ doencrypt = False;
+
+ if (passlen1 > MAX_PASS_LEN) {
+ overflow_attack(passlen1);
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
+ }
+
+ passlen1 = MIN(passlen1, MAX_PASS_LEN);
+ passlen2 = MIN(passlen2, MAX_PASS_LEN);
+
+ if(!doencrypt) {
+ /* both Win95 and WinNT stuff up the password lengths for
+ non-encrypting systems. Uggh.
+
+ if passlen1==24 its a win95 system, and its setting the
+ password length incorrectly. Luckily it still works with the
+ default code because Win95 will null terminate the password
+ anyway
+
+ if passlen1>0 and passlen2>0 then maybe its a NT box and its
+ setting passlen2 to some random value which really stuffs
+ things up. we need to fix that one. */
+
+ if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
+ passlen2 = 0;
+ }
+
+ if (lp_restrict_anonymous()) {
+ /* there seems to be no reason behind the differences in MS clients formatting
+ * various info like the domain, NativeOS, and NativeLanMan fields. Win95
+ * in particular seems to have an extra null byte between the username and the
+ * domain, or the password length calculation is wrong, which throws off the
+ * string extraction routines below. This makes the value of domain be the
+ * empty string, which fails the restrict anonymous check further down.
+ * This compensates for that, and allows browsing to work in mixed NT and
+ * win95 environments even when restrict anonymous is true. AAB
+ */
+ dump_data(100, p, 0x70);
+ DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2));
+ if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
+ DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n"));
+ DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n"));
+ DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
+ passlen1 = 1;
+ }
+ }
+
+ if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
+ /* Save the lanman2 password and the NT md4 password. */
+ smb_apasslen = passlen1;
+ memcpy(smb_apasswd,p,smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
+ smb_ntpasslen = passlen2;
+ memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
+ smb_ntpasswd[smb_ntpasslen] = 0;
+
+ /*
+ * Ensure the plaintext passwords are in UNIX format.
+ */
+ if(!doencrypt) {
+ pstrcpy(smb_apasswd,dos_to_unix_static(smb_apasswd));
+ pstrcpy(smb_ntpasswd,dos_to_unix_static(smb_ntpasswd));
+ }
+
+ } else {
+ /* we use the first password that they gave */
+ smb_apasslen = passlen1;
+ StrnCpy(smb_apasswd,p,smb_apasslen);
+ /*
+ * Ensure the plaintext password is in UNIX format.
+ */
+ pstrcpy(smb_apasswd,dos_to_unix_static(smb_apasswd));
+
+ /* trim the password */
+ smb_apasslen = strlen(smb_apasswd);
+
+ /* wfwg sometimes uses a space instead of a null */
+ if (strequal(smb_apasswd," ")) {
+ smb_apasslen = 0;
+ *smb_apasswd = 0;
+ }
+ }
+
+ p += passlen1 + passlen2;
+ fstrcpy(user,p);
+ p = skip_string(p,1);
+ /*
+ * Incoming user and domain are in DOS codepage format. Convert
+ * to UNIX.
+ */
+ fstrcpy(user,dos_to_unix_static(user));
+ fstrcpy(domain, dos_to_unix_static(p));
+ DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
+ domain,skip_string(p,1),skip_string(p,2)));
+ }
+
+ /* don't allow strange characters in usernames or domains */
+ alpha_strcpy(user, user, ". _-$", sizeof(user));
+ alpha_strcpy(domain, domain, ". _-@", sizeof(domain));
+ if (strstr(user, "..") || strstr(domain,"..")) {
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ DEBUG(3,("sesssetupX:name=[%s]\n",user));
+
+ /* If name ends in $ then I think it's asking about whether a */
+ /* computer with that name (minus the $) has access. For now */
+ /* say yes to everything ending in $. */
+
+ if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
+ END_PROFILE(SMBsesssetupX);
+ return session_trust_account(conn, inbuf, outbuf, user,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen);
+ }
+
+ if (done_sesssetup && lp_restrict_anonymous()) {
+ /* tests show that even if browsing is done over already validated connections
+ * without a username and password the domain is still provided, which it
+ * wouldn't be if it was a purely anonymous connection. So, in order to
+ * restrict anonymous, we only deny connections that have no session
+ * information. If a domain has been provided, then it's not a purely
+ * anonymous connection. AAB
+ */
+ if (!*user && !*smb_apasswd && !*domain) {
+ DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
+ END_PROFILE(SMBsesssetupX);
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ /* setup %U substitution */
+ sub_set_smb_name(user);
+
+ /* If no username is sent use the guest account */
+ if (!*user) {
+ fstrcpy(user,lp_guestaccount(-1));
+ guest = True;
+ }
+
+ fstrcpy(current_user_info.smb_name,user);
- DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
+ reload_services(True);
+
+ /*
+ * Save the username before mapping. We will use
+ * the original username sent to us for security=server
+ * and security=domain checking.
+ */
+
+ fstrcpy( orig_user, user);
+
+ /*
+ * Always try the "DOMAIN\user" lookup first, as this is the most
+ * specific case. If this fails then try the simple "user" lookup.
+ */
+
+ {
+ fstring dom_user;
+
+ /* Work out who's who */
+
+ slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s",
+ domain, lp_winbind_separator(), user);
+
+ if (sys_getpwnam(dom_user) != NULL) {
+ fstrcpy(user, dom_user);
+ DEBUG(3,("Using unix username %s\n", dom_user));
+ }
+ }
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ smb_getpwnam(user, True);
+
+ add_session_user(user);
+
+ /*
+ * Check with orig_user for security=server and
+ * security=domain.
+ */
+
+ if (!guest && !check_server_security(orig_user, domain, user,
+ smb_apasswd, smb_apasslen, smb_ntpasswd, smb_ntpasslen) &&
+ !check_domain_security(orig_user, domain, user, smb_apasswd,
+ smb_apasslen, smb_ntpasswd, smb_ntpasslen, &ptok) &&
+ !check_hosts_equiv(user))
+ {
+
+ /*
+ * If we get here then the user wasn't guest and the remote
+ * authentication methods failed. Check the authentication
+ * methods on this local server.
+ *
+ * If an NT password was supplied try and validate with that
+ * first. This is superior as the passwords are mixed case
+ * 128 length unicode.
+ */
+
+ if(smb_ntpasslen)
+ {
+ if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
+ DEBUG(2,("NT Password did not match for user '%s'!\n", user));
+ else
+ valid_nt_password = True;
+ }
+
+
+ /* check the LanMan password only if necessary and if allowed
+ by lp_lanman_auth() */
+ if (!valid_nt_password && lp_lanman_auth())
+ {
+ DEBUG(2,("Defaulting to Lanman password for %s\n", user));
+ valid_lm_password = password_ok(user, smb_apasswd,smb_apasslen,NULL);
+ }
+
+
+ /* The true branch will be executed if
+ (1) the NT password failed (or was not tried), and
+ (2) LanMan authentication failed (or was disabled)
+ */
+ if (!valid_nt_password && !valid_lm_password)
+ {
+ if (lp_security() >= SEC_USER)
+ {
+ if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
+ {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
+ END_PROFILE(SMBsesssetupX);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
+ {
+ SAM_ACCOUNT *sampass = NULL;
+
+ pdb_init_sam(&sampass);
+
+ /*
+ * This is really bad form. We know that password_ok() failed,
+ * but the return value can't distinguish between a non-existent user
+ * and a bad password. So we try to look the user up again here
+ * to see if he or she exists. We must look up the user in the
+ * "smb passwd file" and not /etc/passwd so that we don't
+ * get confused when the two don't have a one-to-one correspondence.
+ * e.g. a standard UNIX account such as "operator" --jerry
+ */
+
+ if (pdb_getsampwnam(sampass, user))
+ {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Rejecting user '%s': bad password\n", user));
+ END_PROFILE(SMBsesssetupX);
+ pdb_free_sam(sampass);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+
+ pdb_free_sam(sampass);
+ }
+
+ /*
+ * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
+ * Then always map to guest account - as done below.
+ */
+ }
+
+ if (*smb_apasswd || !smb_getpwnam(user,True))
+ fstrcpy(user,lp_guestaccount(-1));
+ DEBUG(3,("Registered username %s for guest access\n",user));
+ guest = True;
+ }
+ }
+
+ if (!smb_getpwnam(user,True)) {
+ DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
+ fstrcpy(user,lp_guestaccount(-1));
+ guest = True;
+ }
+
+ if (!strequal(user,lp_guestaccount(-1)) &&
+ lp_servicenumber(user) < 0)
+ {
+ add_home_service(user,get_user_service_home_dir(user));
+ }
+
+
+ /* it's ok - setup a reply */
+ if (Protocol < PROTOCOL_NT1) {
+ set_message(outbuf,3,0,True);
+ } else {
+ char *p;
+ set_message(outbuf,3,3,True);
+ p = smb_buf(outbuf);
+ pstrcpy(p,"Unix"); p = skip_string(p,1);
+ pstrcpy(p,"Samba "); pstrcat(p,VERSION); p = skip_string(p,1);
+ pstrcpy(p,global_myworkgroup); unix_to_dos(p); p = skip_string(p,1);
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+ /* perhaps grab OS version here?? */
+ }
+
+ /* Set the correct uid in the outgoing and incoming packets
+ We will use this on future requests to determine which
+ user we should become.
+ */
+ {
+ const struct passwd *pw = smb_getpwnam(user,False);
+ if (!pw) {
+ delete_nt_token(&ptok);
+ DEBUG(1,("Username %s is invalid on this system\n",user));
+ END_PROFILE(SMBsesssetupX);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
+ }
+ gid = pw->pw_gid;
+ uid = pw->pw_uid;
+ }
+
+ if (guest)
+ SSVAL(outbuf,smb_vwv2,1);
+
+ /* register the name and uid as being validated, so further connections
+ to a uid can get through without a password, on the same VC */
+
+ sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest,&ptok);
+
+ delete_nt_token(&ptok);
- END_PROFILE(SMBgetatr);
- return(outsize);
+ if (sess_vuid == -1) {
+ END_PROFILE(SMBsesssetupX);
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
+
+ SSVAL(outbuf,smb_uid,sess_vuid);
+ SSVAL(inbuf,smb_uid,sess_vuid);
+
+ if (!done_sesssetup)
+ max_send = MIN(max_send,smb_bufsize);
+
+ DEBUG(6,("Client requested max send size of %d\n", max_send));
+
+ done_sesssetup = True;
+
+ END_PROFILE(SMBsesssetupX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
/****************************************************************************
- Reply to a setatr.
+ Reply to a chkpth.
****************************************************************************/
-int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring fname;
- int outsize = 0;
- BOOL ok=False;
- int mode;
- time_t mtime;
- SMB_STRUCT_STAT sbuf;
- BOOL bad_path = False;
- char *p;
- NTSTATUS status;
+ int outsize = 0;
+ int mode;
+ pstring name;
+ BOOL ok = False;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBchkpth);
+
+ pstrcpy(name,smb_buf(inbuf) + 1);
- START_PROFILE(SMBsetatr);
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBsetatr);
- return ERROR_NT(status);
- }
+ unix_convert(name,conn,0,&bad_path,&sbuf);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ mode = SVAL(inbuf,smb_vwv0);
+
+ if (check_name(name,conn)) {
+ if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0)
+ if (!(ok = S_ISDIR(sbuf.st_mode)))
+ errno = ENOTDIR;
+
+ }
+
+ if (!ok) {
+ /* We special case this - as when a Windows machine
+ is parsing a path is steps through the components
+ one at a time - if a component fails it expects
+ ERRbadpath, not ERRbadfile.
+ */
+ if(errno == ENOENT) {
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ }
+
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG(3,("chkpth %s mode=%d\n", name, mode));
+
+ END_PROFILE(SMBchkpth);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a getatr.
+****************************************************************************/
+
+int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ SMB_STRUCT_STAT sbuf;
+ BOOL ok = False;
+ int mode=0;
+ SMB_OFF_T size=0;
+ time_t mtime=0;
+ BOOL bad_path = False;
+ START_PROFILE(SMBgetatr);
+
+ pstrcpy(fname,smb_buf(inbuf) + 1);
- mode = SVAL(inbuf,smb_vwv0);
- mtime = make_unix_date3(inbuf+smb_vwv1);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- if (mode != FILE_ATTRIBUTE_NORMAL) {
- if (VALID_STAT_OF_DIR(sbuf))
- mode |= aDIR;
- else
- mode &= ~aDIR;
+ /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
+ under WfWg - weird! */
+ if (! (*fname))
+ {
+ mode = aHIDDEN | aDIR;
+ if (!CAN_WRITE(conn)) mode |= aRONLY;
+ size = 0;
+ mtime = 0;
+ ok = True;
+ }
+ else
+ {
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (check_name(fname,conn))
+ {
+ if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0)
+ {
+ mode = dos_mode(conn,fname,&sbuf);
+ size = sbuf.st_size;
+ mtime = sbuf.st_mtime;
+ if (mode & aDIR)
+ size = 0;
+ ok = True;
+ }
+ else
+ DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
+ }
+ }
+
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBgetatr);
+ return(UNIXERROR(ERRDOS,ERRbadfile));
+ }
+
+ outsize = set_message(outbuf,10,0,True);
- if (check_name(fname,conn)) {
- ok = (file_set_dosmode(conn,fname,mode,NULL) == 0);
- }
- } else {
- ok = True;
- }
+ SSVAL(outbuf,smb_vwv0,mode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv1,mtime);
+ SIVAL(outbuf,smb_vwv3,(uint32)size);
- if (ok)
- ok = set_filetime(conn,fname,mtime);
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
- if (!ok) {
- END_PROFILE(SMBsetatr);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
- }
+ DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
+
+ END_PROFILE(SMBgetatr);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a setatr.
+****************************************************************************/
+
+int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ pstring fname;
+ int outsize = 0;
+ BOOL ok=False;
+ int mode;
+ time_t mtime;
+ SMB_STRUCT_STAT sbuf;
+ BOOL bad_path = False;
+ START_PROFILE(SMBsetatr);
- outsize = set_message(outbuf,0,0,True);
+ pstrcpy(fname,smb_buf(inbuf) + 1);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+
+ mode = SVAL(inbuf,smb_vwv0);
+ mtime = make_unix_date3(inbuf+smb_vwv1);
- DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
+ if (VALID_STAT_OF_DIR(sbuf))
+ mode |= aDIR;
+ else
+ mode &= ~aDIR;
+
+ if (check_name(fname,conn))
+ ok = (file_chmod(conn,fname,mode,NULL) == 0);
+ if (ok)
+ ok = set_filetime(conn,fname,mtime);
- END_PROFILE(SMBsetatr);
- return(outsize);
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBsetatr);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
+
+ END_PROFILE(SMBsetatr);
+ return(outsize);
}
/****************************************************************************
@@ -717,7 +1318,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
SMB_BIG_UINT dfree,dsize,bsize;
START_PROFILE(SMBdskattr);
- SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
outsize = set_message(outbuf,5,0,True);
@@ -762,198 +1363,209 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring mask;
- pstring directory;
- pstring fname;
- SMB_OFF_T size;
- int mode;
- time_t date;
- int dirtype;
- int outsize = 0;
- unsigned int numentries = 0;
- unsigned int maxentries = 0;
- BOOL finished = False;
- char *p;
- BOOL ok = False;
- int status_len;
- pstring path;
- char status[21];
- int dptr_num= -1;
- BOOL check_descend = False;
- BOOL expect_close = False;
- BOOL can_open = True;
- BOOL bad_path = False;
- NTSTATUS nt_status;
- START_PROFILE(SMBsearch);
-
- *mask = *directory = *fname = 0;
-
- /* If we were called as SMBffirst then we must expect close. */
- if(CVAL(inbuf,smb_com) == SMBffirst)
- expect_close = True;
-
- outsize = set_message(outbuf,1,3,True);
- maxentries = SVAL(inbuf,smb_vwv0);
- dirtype = SVAL(inbuf,smb_vwv1);
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status);
- if (!NT_STATUS_IS_OK(nt_status)) {
- END_PROFILE(SMBsearch);
- return ERROR_NT(nt_status);
- }
- p++;
- status_len = SVAL(p, 0);
- p += 2;
+ pstring mask;
+ pstring directory;
+ pstring fname;
+ SMB_OFF_T size;
+ int mode;
+ time_t date;
+ int dirtype;
+ int outsize = 0;
+ int numentries = 0;
+ BOOL finished = False;
+ int maxentries;
+ int i;
+ char *p;
+ BOOL ok = False;
+ int status_len;
+ char *path;
+ char status[21];
+ int dptr_num= -1;
+ BOOL check_descend = False;
+ BOOL expect_close = False;
+ BOOL can_open = True;
+ BOOL bad_path = False;
+ START_PROFILE(SMBsearch);
+
+ *mask = *directory = *fname = 0;
+
+ /* If we were called as SMBffirst then we must expect close. */
+ if(CVAL(inbuf,smb_com) == SMBffirst)
+ expect_close = True;
- /* dirtype &= ~aDIR; */
-
- if (status_len == 0) {
- SMB_STRUCT_STAT sbuf;
- pstring dir2;
-
- pstrcpy(directory,path);
- pstrcpy(dir2,path);
- unix_convert(directory,conn,0,&bad_path,&sbuf);
- unix_format(dir2);
-
- if (!check_name(directory,conn))
- can_open = False;
-
- p = strrchr_m(dir2,'/');
- if (p == NULL) {
- pstrcpy(mask,dir2);
- *dir2 = 0;
- } else {
- *p = 0;
- pstrcpy(mask,p+1);
- }
-
- p = strrchr_m(directory,'/');
- if (!p)
- *directory = 0;
- else
- *p = 0;
-
- if (strlen(directory) == 0)
- pstrcpy(directory,".");
- memset((char *)status,'\0',21);
- SCVAL(status,0,(dirtype & 0x1F));
- } else {
- int status_dirtype;
-
- memcpy(status,p,21);
- status_dirtype = CVAL(status,0) & 0x1F;
- if (status_dirtype != (dirtype & 0x1F))
- dirtype = status_dirtype;
-
- conn->dirptr = dptr_fetch(status+12,&dptr_num);
- if (!conn->dirptr)
- goto SearchEmpty;
- string_set(&conn->dirpath,dptr_path(dptr_num));
- pstrcpy(mask, dptr_wcard(dptr_num));
- }
-
- if (can_open) {
- p = smb_buf(outbuf) + 3;
- ok = True;
+ outsize = set_message(outbuf,1,3,True);
+ maxentries = SVAL(inbuf,smb_vwv0);
+ dirtype = SVAL(inbuf,smb_vwv1);
+ path = smb_buf(inbuf) + 1;
+ status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
+
+ RESOLVE_DFSPATH(path, conn, inbuf, outbuf);
+ /* dirtype &= ~aDIR; */
+
+ if (status_len == 0)
+ {
+ SMB_STRUCT_STAT sbuf;
+ pstring dir2;
+
+ pstrcpy(directory,smb_buf(inbuf)+1);
+ pstrcpy(dir2,smb_buf(inbuf)+1);
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+ unix_format(dir2);
+
+ if (!check_name(directory,conn))
+ can_open = False;
+
+ p = strrchr(dir2,'/');
+ if (p == NULL)
+ {
+ pstrcpy(mask,dir2);
+ *dir2 = 0;
+ }
+ else
+ {
+ *p = 0;
+ pstrcpy(mask,p+1);
+ }
+
+ p = strrchr(directory,'/');
+ if (!p)
+ *directory = 0;
+ else
+ *p = 0;
+
+ if (strlen(directory) == 0)
+ pstrcpy(directory,"./");
+ memset((char *)status,'\0',21);
+ SCVAL(status,0,(dirtype & 0x1F));
+ }
+ else
+ {
+ int status_dirtype;
+ memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
+ status_dirtype = CVAL(status,0) & 0x1F;
+ if (status_dirtype != (dirtype & 0x1F))
+ dirtype = status_dirtype;
+ conn->dirptr = dptr_fetch(status+12,&dptr_num);
+ if (!conn->dirptr)
+ goto SearchEmpty;
+ string_set(&conn->dirpath,dptr_path(dptr_num));
+ fstrcpy(mask, dptr_wcard(dptr_num));
+ }
+
+ if (can_open)
+ {
+ p = smb_buf(outbuf) + 3;
+
+ ok = True;
- if (status_len == 0) {
- dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
- if (dptr_num < 0) {
- if(dptr_num == -2) {
- END_PROFILE(SMBsearch);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
- }
- END_PROFILE(SMBsearch);
- return ERROR_DOS(ERRDOS,ERRnofids);
- }
- dptr_set_wcard(dptr_num, strdup(mask));
- dptr_set_attr(dptr_num, dirtype);
- } else {
- dirtype = dptr_attr(dptr_num);
- }
-
- DEBUG(4,("dptr_num is %d\n",dptr_num));
-
- if (ok) {
- if ((dirtype&0x1F) == aVOLID) {
- memcpy(p,status,21);
- make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0,conn->case_sensitive);
- dptr_fill(p+12,dptr_num);
- if (dptr_zero(p+12) && (status_len==0))
- numentries = 1;
- else
- numentries = 0;
- p += DIR_STRUCT_SIZE;
- } else {
- unsigned int i;
- maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
-
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
- check_descend = True;
-
- for (i=numentries;(i<maxentries) && !finished;i++) {
- finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
- if (!finished) {
- memcpy(p,status,21);
- make_dir_struct(p,mask,fname,size,mode,date,conn->case_sensitive);
- dptr_fill(p+12,dptr_num);
- numentries++;
- }
- p += DIR_STRUCT_SIZE;
- }
- }
- } /* if (ok ) */
- }
+ if (status_len == 0)
+ {
+ dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
+ if (dptr_num < 0)
+ {
+ if(dptr_num == -2)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBsearch);
+ return (UNIXERROR(ERRDOS,ERRnofids));
+ }
+ END_PROFILE(SMBsearch);
+ return ERROR_DOS(ERRDOS,ERRnofids);
+ }
+ dptr_set_wcard(dptr_num, strdup(mask));
+ dptr_set_attr(dptr_num, dirtype);
+ } else {
+ dirtype = dptr_attr(dptr_num);
+ }
+
+ DEBUG(4,("dptr_num is %d\n",dptr_num));
+
+ if (ok)
+ {
+ if ((dirtype&0x1F) == aVOLID)
+ {
+ memcpy(p,status,21);
+ make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
+ dptr_fill(p+12,dptr_num);
+ if (dptr_zero(p+12) && (status_len==0))
+ numentries = 1;
+ else
+ numentries = 0;
+ p += DIR_STRUCT_SIZE;
+ }
+ else
+ {
+ DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
+ conn->dirpath,lp_dontdescend(SNUM(conn))));
+ if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
+ check_descend = True;
+
+ for (i=numentries;(i<maxentries) && !finished;i++)
+ {
+ /* check to make sure we have room in the buffer */
+ if ( ((PTR_DIFF(p, outbuf))+DIR_STRUCT_SIZE) > BUFFER_SIZE )
+ break;
+ finished =
+ !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
+ if (!finished)
+ {
+ memcpy(p,status,21);
+ make_dir_struct(p,mask,fname,size,mode,date);
+ dptr_fill(p+12,dptr_num);
+ numentries++;
+ }
+ p += DIR_STRUCT_SIZE;
+ }
+ }
+ } /* if (ok ) */
+ }
SearchEmpty:
- /* If we were called as SMBffirst with smb_search_id == NULL
- and no entries were found then return error and close dirptr
- (X/Open spec) */
-
- if(ok && expect_close && numentries == 0 && status_len == 0) {
- if (Protocol < PROTOCOL_NT1) {
- SCVAL(outbuf,smb_rcls,ERRDOS);
- SSVAL(outbuf,smb_err,ERRnofiles);
- }
- /* Also close the dptr - we know it's gone */
- dptr_close(&dptr_num);
- } else if (numentries == 0 || !ok) {
- if (Protocol < PROTOCOL_NT1) {
- SCVAL(outbuf,smb_rcls,ERRDOS);
- SSVAL(outbuf,smb_err,ERRnofiles);
- }
- dptr_close(&dptr_num);
- }
-
- /* If we were called as SMBfunique, then we can close the dirptr now ! */
- if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
- dptr_close(&dptr_num);
-
- SSVAL(outbuf,smb_vwv0,numentries);
- SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
- SCVAL(smb_buf(outbuf),0,5);
- SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
-
- if (Protocol >= PROTOCOL_NT1)
- SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
-
- outsize += DIR_STRUCT_SIZE*numentries;
- smb_setlen(outbuf,outsize - 4);
+ if ( (numentries == 0) || !ok)
+ {
+ SCVAL(outbuf,smb_rcls,ERRDOS);
+ SSVAL(outbuf,smb_err,ERRnofiles);
+ dptr_close(&dptr_num);
+ }
+
+ /* If we were called as SMBffirst with smb_search_id == NULL
+ and no entries were found then return error and close dirptr
+ (X/Open spec) */
+
+ if(ok && expect_close && numentries == 0 && status_len == 0)
+ {
+ SCVAL(outbuf,smb_rcls,ERRDOS);
+ SSVAL(outbuf,smb_err,ERRnofiles);
+ /* Also close the dptr - we know it's gone */
+ dptr_close(&dptr_num);
+ }
+
+ /* If we were called as SMBfunique, then we can close the dirptr now ! */
+ if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
+ dptr_close(&dptr_num);
+
+ SSVAL(outbuf,smb_vwv0,numentries);
+ SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
+ SCVAL(smb_buf(outbuf),0,5);
+ SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+
+ outsize += DIR_STRUCT_SIZE*numentries;
+ smb_setlen(outbuf,outsize - 4);
- if ((! *directory) && dptr_path(dptr_num))
- slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
+ if ((! *directory) && dptr_path(dptr_num))
+ slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
- DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask, directory, dirtype, numentries, maxentries ) );
+ DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
+ smb_fn_name(CVAL(inbuf,smb_com)),
+ mask, directory, dirtype, numentries, maxentries ) );
- END_PROFILE(SMBsearch);
- return(outsize);
+ END_PROFILE(SMBsearch);
+ return(outsize);
}
/****************************************************************************
@@ -962,45 +1574,36 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- int outsize = 0;
- int status_len;
- pstring path;
- char status[21];
- int dptr_num= -2;
- char *p;
- NTSTATUS err;
+ int outsize = 0;
+ int status_len;
+ char *path;
+ char status[21];
+ int dptr_num= -2;
+ START_PROFILE(SMBfclose);
- START_PROFILE(SMBfclose);
+ outsize = set_message(outbuf,1,0,True);
+ path = smb_buf(inbuf) + 1;
+ status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
- outsize = set_message(outbuf,1,0,True);
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err);
- if (!NT_STATUS_IS_OK(err)) {
- END_PROFILE(SMBfclose);
- return ERROR_NT(err);
- }
- p++;
- status_len = SVAL(p,0);
- p += 2;
-
- if (status_len == 0) {
- END_PROFILE(SMBfclose);
- return ERROR_DOS(ERRSRV,ERRsrverror);
- }
+
+ if (status_len == 0) {
+ END_PROFILE(SMBfclose);
+ return ERROR_DOS(ERRSRV,ERRsrverror);
+ }
- memcpy(status,p,21);
+ memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
- if(dptr_fetch(status+12,&dptr_num)) {
- /* Close the dptr - we know it's gone */
- dptr_close(&dptr_num);
- }
+ if(dptr_fetch(status+12,&dptr_num)) {
+ /* Close the dptr - we know it's gone */
+ dptr_close(&dptr_num);
+ }
- SSVAL(outbuf,smb_vwv0,0);
+ SSVAL(outbuf,smb_vwv0,0);
- DEBUG(3,("search close\n"));
+ DEBUG(3,("search close\n"));
- END_PROFILE(SMBfclose);
- return(outsize);
+ END_PROFILE(SMBfclose);
+ return(outsize);
}
/****************************************************************************
@@ -1009,69 +1612,69 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring fname;
- int outsize = 0;
- int fmode=0;
- int share_mode;
- SMB_OFF_T size = 0;
- time_t mtime=0;
- int rmode=0;
- SMB_STRUCT_STAT sbuf;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
- uint16 dos_attr = SVAL(inbuf,smb_vwv1);
- NTSTATUS status;
- START_PROFILE(SMBopen);
+ pstring fname;
+ int outsize = 0;
+ int fmode=0;
+ int share_mode;
+ SMB_OFF_T size = 0;
+ time_t mtime=0;
+ mode_t unixmode;
+ int rmode=0;
+ SMB_STRUCT_STAT sbuf;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ START_PROFILE(SMBopen);
- share_mode = SVAL(inbuf,smb_vwv0);
+ share_mode = SVAL(inbuf,smb_vwv0);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBopen);
- return ERROR_NT(status);
- }
+ pstrcpy(fname,smb_buf(inbuf)+1);
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
- fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- (uint32)dos_attr, oplock_request,&rmode,NULL);
-
- if (!fsp) {
- END_PROFILE(SMBopen);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(conn,fname,&sbuf);
- mtime = sbuf.st_mtime;
-
- if (fmode & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fname));
- close_file(fsp,False);
- END_PROFILE(SMBopen);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
+ unixmode = unix_mode(conn,aARCH,fname);
+
+ fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ unixmode, oplock_request,&rmode,NULL);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBopen);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ size = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ mtime = sbuf.st_mtime;
+
+ if (fmode & aDIR) {
+ DEBUG(3,("attempt to open a directory %s\n",fname));
+ close_file(fsp,False);
+ END_PROFILE(SMBopen);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
- outsize = set_message(outbuf,7,0,True);
- SSVAL(outbuf,smb_vwv0,fsp->fnum);
- SSVAL(outbuf,smb_vwv1,fmode);
- if(lp_dos_filetime_resolution(SNUM(conn)) )
- put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
- else
- put_dos_date3(outbuf,smb_vwv2,mtime);
- SIVAL(outbuf,smb_vwv4,(uint32)size);
- SSVAL(outbuf,smb_vwv6,rmode);
-
- if (oplock_request && lp_fake_oplocks(SNUM(conn)))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ outsize = set_message(outbuf,7,0,True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+ SSVAL(outbuf,smb_vwv1,fmode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv2,mtime);
+ SIVAL(outbuf,smb_vwv4,(uint32)size);
+ SSVAL(outbuf,smb_vwv6,rmode);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
- END_PROFILE(SMBopen);
- return(outsize);
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ END_PROFILE(SMBopen);
+ return(outsize);
}
/****************************************************************************
@@ -1080,103 +1683,108 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
- pstring fname;
- int smb_mode = SVAL(inbuf,smb_vwv3);
- int smb_attr = SVAL(inbuf,smb_vwv5);
- /* Breakout the oplock request bits so we can set the
- reply bits separately. */
- BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
- BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
- BOOL oplock_request = ex_oplock_request | core_oplock_request;
+ pstring fname;
+ int smb_mode = SVAL(inbuf,smb_vwv3);
+ int smb_attr = SVAL(inbuf,smb_vwv5);
+ /* Breakout the oplock request bits so we can set the
+ reply bits separately. */
+ BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ BOOL oplock_request = ex_oplock_request | core_oplock_request;
#if 0
- int open_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
+ int open_flags = SVAL(inbuf,smb_vwv2);
+ int smb_sattr = SVAL(inbuf,smb_vwv4);
+ uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
#endif
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- SMB_OFF_T size=0;
- int fmode=0,mtime=0,rmode=0;
- SMB_STRUCT_STAT sbuf;
- int smb_action = 0;
- BOOL bad_path = False;
- files_struct *fsp;
- NTSTATUS status;
- START_PROFILE(SMBopenX);
+ int smb_ofun = SVAL(inbuf,smb_vwv8);
+ mode_t unixmode;
+ SMB_OFF_T size=0;
+ int fmode=0,mtime=0,rmode=0;
+ SMB_STRUCT_STAT sbuf;
+ int smb_action = 0;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ START_PROFILE(SMBopenX);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ if (lp_nt_pipe_support()) {
+ END_PROFILE(SMBopenX);
+ return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
+ } else {
+ END_PROFILE(SMBopenX);
+ return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+ }
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
- if (lp_nt_pipe_support()) {
- END_PROFILE(SMBopenX);
- return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
- } else {
- END_PROFILE(SMBopenX);
- return ERROR_DOS(ERRSRV,ERRaccess);
- }
- }
+ /* XXXX we need to handle passed times, sattr and flags */
- /* XXXX we need to handle passed times, sattr and flags */
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBopenX);
- return ERROR_NT(status);
- }
+ pstrcpy(fname,smb_buf(inbuf));
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
- fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
- oplock_request, &rmode,&smb_action);
+ unixmode = unix_mode(conn,smb_attr | aARCH, fname);
- if (!fsp) {
- END_PROFILE(SMBopenX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(conn,fname,&sbuf);
- mtime = sbuf.st_mtime;
- if (fmode & aDIR) {
- close_file(fsp,False);
- END_PROFILE(SMBopenX);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- /* If the caller set the extended oplock request bit
- and we granted one (by whatever means) - set the
- correct bit for extended oplock reply.
- */
-
- if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
- smb_action |= EXTENDED_OPLOCK_GRANTED;
-
- if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- smb_action |= EXTENDED_OPLOCK_GRANTED;
-
- /* If the caller set the core oplock request bit
- and we granted one (by whatever means) - set the
- correct bit for core oplock reply.
- */
-
- if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
-
- if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
-
- set_message(outbuf,15,0,True);
- SSVAL(outbuf,smb_vwv2,fsp->fnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- if(lp_dos_filetime_resolution(SNUM(conn)) )
- put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
- else
- put_dos_date3(outbuf,smb_vwv4,mtime);
- SIVAL(outbuf,smb_vwv6,(uint32)size);
- SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,smb_action);
-
- END_PROFILE(SMBopenX);
- return chain_reply(inbuf,outbuf,length,bufsize);
+ fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
+ oplock_request, &rmode,&smb_action);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBopenX);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ size = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ mtime = sbuf.st_mtime;
+ if (fmode & aDIR) {
+ close_file(fsp,False);
+ END_PROFILE(SMBopenX);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
+ /* If the caller set the extended oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for extended oplock reply.
+ */
+
+ if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ /* If the caller set the core oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for core oplock reply.
+ */
+
+ if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
+
+ set_message(outbuf,15,0,True);
+ SSVAL(outbuf,smb_vwv2,fsp->fnum);
+ SSVAL(outbuf,smb_vwv3,fmode);
+ if(lp_dos_filetime_resolution(SNUM(conn)) )
+ put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
+ else
+ put_dos_date3(outbuf,smb_vwv4,mtime);
+ SIVAL(outbuf,smb_vwv6,(uint32)size);
+ SSVAL(outbuf,smb_vwv8,rmode);
+ SSVAL(outbuf,smb_vwv11,smb_action);
+
+ END_PROFILE(SMBopenX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
/****************************************************************************
@@ -1185,26 +1793,28 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
- uint16 vuid = SVAL(inbuf,smb_uid);
- user_struct *vuser = get_valid_user_struct(vuid);
- START_PROFILE(SMBulogoffX);
+ uint16 vuid = SVAL(inbuf,smb_uid);
+ user_struct *vuser = get_valid_user_struct(vuid);
+ START_PROFILE(SMBulogoffX);
- if(vuser == 0)
- DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
+ if(vuser == 0) {
+ DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
+ }
- /* in user level security we are supposed to close any files
- open by this user */
- if ((vuser != 0) && (lp_security() != SEC_SHARE))
- file_close_user(vuid);
+ /* in user level security we are supposed to close any files
+ open by this user */
+ if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
+ file_close_user(vuid);
+ }
- invalidate_vuid(vuid);
+ invalidate_vuid(vuid);
- set_message(outbuf,2,0,True);
+ set_message(outbuf,2,0,True);
- DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
+ DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
- END_PROFILE(SMBulogoffX);
- return chain_reply(inbuf,outbuf,length,bufsize);
+ END_PROFILE(SMBulogoffX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
/****************************************************************************
@@ -1213,65 +1823,71 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring fname;
- int com;
- int outsize = 0;
- int createmode;
- int ofun = 0;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
- SMB_STRUCT_STAT sbuf;
- NTSTATUS status;
- START_PROFILE(SMBcreate);
+ pstring fname;
+ int com;
+ int outsize = 0;
+ int createmode;
+ mode_t unixmode;
+ int ofun = 0;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBcreate);
- com = SVAL(inbuf,smb_com);
+ com = SVAL(inbuf,smb_com);
- createmode = SVAL(inbuf,smb_vwv0);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcreate);
- return ERROR_NT(status);
- }
+ createmode = SVAL(inbuf,smb_vwv0);
+ pstrcpy(fname,smb_buf(inbuf)+1);
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (createmode & aVOLID)
- DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
+ if (createmode & aVOLID) {
+ DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
+ }
- if(com == SMBmknew) {
- /* We should fail if file exists. */
- ofun = FILE_CREATE_IF_NOT_EXIST;
- } else {
- /* SMBcreate - Create if file doesn't exist, truncate if it does. */
- ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
- }
-
- /* Open file in dos compatibility share mode. */
- fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
- ofun, (uint32)createmode, oplock_request, NULL, NULL);
+ unixmode = unix_mode(conn,createmode,fname);
- if (!fsp) {
- END_PROFILE(SMBcreate);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
- }
+ if(com == SMBmknew)
+ {
+ /* We should fail if file exists. */
+ ofun = FILE_CREATE_IF_NOT_EXIST;
+ }
+ else
+ {
+ /* SMBcreate - Create if file doesn't exist, truncate if it does. */
+ ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
+ }
+
+ /* Open file in dos compatibility share mode. */
+ fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ ofun, unixmode, oplock_request, NULL, NULL);
+
+ if (!fsp)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBcreate);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fsp->fnum);
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
- if (oplock_request && lp_fake_oplocks(SNUM(conn)))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
- DEBUG( 2, ( "new file %s\n", fname ) );
- DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
+ DEBUG( 2, ( "new file %s\n", fname ) );
+ DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
+ fname, fsp->fd, createmode, (int)unixmode ) );
- END_PROFILE(SMBcreate);
- return(outsize);
+ END_PROFILE(SMBcreate);
+ return(outsize);
}
/****************************************************************************
@@ -1282,86 +1898,76 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
{
pstring fname;
int outsize = 0;
- int createattr;
+ int createmode;
+ mode_t unixmode;
BOOL bad_path = False;
files_struct *fsp;
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
int tmpfd;
SMB_STRUCT_STAT sbuf;
char *p, *s;
- NTSTATUS status;
- unsigned int namelen;
START_PROFILE(SMBctemp);
- createattr = SVAL(inbuf,smb_vwv0);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBctemp);
- return ERROR_NT(status);
- }
- if (*fname) {
- pstrcat(fname,"/TMXXXXXX");
- } else {
- pstrcat(fname,"TMXXXXXX");
- }
+ createmode = SVAL(inbuf,smb_vwv0);
+ pstrcpy(fname,smb_buf(inbuf)+1);
+ pstrcat(fname,"\\TMXXXXXX");
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
unix_convert(fname,conn,0,&bad_path,&sbuf);
-
+
+ unixmode = unix_mode(conn,createmode,fname);
+
tmpfd = smb_mkstemp(fname);
if (tmpfd == -1) {
END_PROFILE(SMBctemp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- SMB_VFS_STAT(conn,fname,&sbuf);
+ vfs_stat(conn,fname,&sbuf);
/* Open file in dos compatibility share mode. */
/* We should fail if file does not exist. */
fsp = open_file_shared(conn,fname,&sbuf,
- SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
- FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
- (uint32)createattr, oplock_request, NULL, NULL);
-
+ SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
+ unixmode, oplock_request, NULL, NULL);
/* close fd from smb_mkstemp() */
close(tmpfd);
if (!fsp) {
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBctemp);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fsp->fnum);
-
/* the returned filename is relative to the directory */
- s = strrchr_m(fname, '/');
+ s = strrchr(fname, '/');
if (!s)
s = fname;
else
s++;
+ outsize = set_message(outbuf,1,4+ strlen(fname),True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+
p = smb_buf(outbuf);
-#if 0
- /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
- thing in the byte section. JRA */
SSVALS(p, 0, -1); /* what is this? not in spec */
-#endif
- namelen = srvstr_push(outbuf, p, s, -1, STR_ASCII|STR_TERMINATE);
- p += namelen;
- outsize = set_message_end(outbuf, p);
+ SSVAL(p, 2, strlen(s));
+ p += 4;
+ pstrcpy(p,s);
- if (oplock_request && lp_fake_oplocks(SNUM(conn)))
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ }
- if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
DEBUG( 2, ( "created temp file %s\n", fname ) );
- DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
- fname, fsp->fd, sbuf.st_mode ) );
+ DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
+ fname, fsp->fd, createmode, (int)unixmode ) );
END_PROFILE(SMBctemp);
return(outsize);
@@ -1388,11 +1994,13 @@ static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT
unix_ERR_code = 0;
fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
if (!fsp) {
NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
- if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
+ if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
+ ret = unix_ERR_ntstatus;
+ else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
ret = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
@@ -1407,7 +2015,7 @@ static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT
Check if a user is allowed to delete a file.
********************************************************************/
-static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path)
+static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
{
SMB_STRUCT_STAT sbuf;
int fmode;
@@ -1415,55 +2023,36 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOO
int access_mode;
files_struct *fsp;
- DEBUG(10,("can_delete: %s, dirtype = %d\n",
- fname, dirtype ));
-
if (!CAN_WRITE(conn))
return NT_STATUS_MEDIA_WRITE_PROTECTED;
- if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
- if(errno == ENOENT) {
- if (bad_path)
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- else
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
- return map_nt_error_from_unix(errno);
- }
+ if (conn->vfs_ops.lstat(conn,dos_to_unix_static(fname),&sbuf) != 0)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
fmode = dos_mode(conn,fname,&sbuf);
-
- /* Can't delete a directory. */
if (fmode & aDIR)
return NT_STATUS_FILE_IS_A_DIRECTORY;
-#if 0 /* JRATEST */
- else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
- return NT_STATUS_OBJECT_NAME_INVALID;
-#endif /* JRATEST */
-
if (!lp_delete_readonly(SNUM(conn))) {
if (fmode & aRONLY)
return NT_STATUS_CANNOT_DELETE;
}
+
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
- return NT_STATUS_NO_SUCH_FILE;
+ return NT_STATUS_CANNOT_DELETE;
/* We need a better way to return NT status codes from open... */
unix_ERR_class = 0;
unix_ERR_code = 0;
fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
if (!fsp) {
NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
- if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
- ret = unix_ERR_ntstatus;
- else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
+ if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
ret = NT_STATUS_SHARING_VIOLATION;
unix_ERR_class = 0;
unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
return ret;
}
close_file(fsp,False);
@@ -1486,22 +2075,12 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
BOOL bad_path = False;
BOOL rc = True;
SMB_STRUCT_STAT sbuf;
-
- *directory = *mask = 0;
-
- /* We must check for wildcards in the name given
- * directly by the client - before any unmangling.
- * This prevents an unmangling of a UNIX name containing
- * a DOS wildcard like '*' or '?' from unmangling into
- * a wildcard delete which was not intended.
- * FIX for #226. JRA.
- */
- has_wild = ms_has_wild(name);
+ *directory = *mask = 0;
rc = unix_convert(name,conn,0,&bad_path,&sbuf);
-
- p = strrchr_m(name,'/');
+
+ p = strrchr(name,'/');
if (!p) {
pstrcpy(directory,".");
pstrcpy(mask,name);
@@ -1510,7 +2089,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
pstrcpy(directory,name);
pstrcpy(mask,p+1);
}
-
+
/*
* We should only check the mangled cache
* here if unix_convert failed. This means
@@ -1519,79 +2098,60 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
* for a possible mangle. This patch from
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
-
+
if (!rc && mangle_is_mangled(mask))
mangle_check_cache( mask );
-
+
+ has_wild = ms_has_wild(mask);
+
if (!has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
- error = can_delete(directory,conn,dirtype,bad_path);
+ error = can_delete(directory,conn,dirtype);
if (!NT_STATUS_IS_OK(error))
return error;
- if (SMB_VFS_UNLINK(conn,directory) == 0) {
+ if (vfs_unlink(conn,directory) == 0)
count++;
- }
} else {
void *dirptr = NULL;
- const char *dname;
-
- if (check_name(directory,conn))
- dirptr = OpenDir(conn, directory, True);
-
+ char *dname;
+ if (check_name(directory,conn))
+ dirptr = OpenDir(conn, directory, True);
+
/* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
- the pattern matches against the long name, otherwise the short name
- We don't implement this yet XXXX
+ the pattern matches against the long name, otherwise the short name
+ We don't implement this yet XXXX
*/
-
+
if (dirptr) {
- error = NT_STATUS_NO_SUCH_FILE;
-
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
while ((dname = ReadDirName(dirptr))) {
pstring fname;
- BOOL sys_direntry = False;
pstrcpy(fname,dname);
-
- /* Quick check for "." and ".." */
- if (fname[0] == '.') {
- if (!fname[1] || (fname[1] == '.' && !fname[2])) {
- if ((dirtype & aDIR)) {
- sys_direntry = True;
- } else {
- continue;
- }
- }
- }
-
- if(!mask_match(fname, mask, conn->case_sensitive))
+
+ if(!mask_match(fname, mask, case_sensitive))
continue;
-
- if (sys_direntry) {
- error = NT_STATUS_OBJECT_NAME_INVALID;
- break;
- }
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
- error = can_delete(fname,conn,dirtype,bad_path);
- if (!NT_STATUS_IS_OK(error)) {
+ error = can_delete(fname,conn,dirtype);
+ if (!NT_STATUS_IS_OK(error))
continue;
- }
- if (SMB_VFS_UNLINK(conn,fname) == 0)
+ if (vfs_unlink(conn,fname) == 0)
count++;
DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
}
CloseDir(dirptr);
}
}
-
- if (count == 0 && NT_STATUS_IS_OK(error)) {
+
+ if (count == 0 && NT_STATUS_IS_OK(error))
error = map_nt_error_from_unix(errno);
- }
-
+
return error;
}
@@ -1599,27 +2159,23 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
Reply to a unlink
****************************************************************************/
-int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
- int dum_buffsize)
+int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
pstring name;
int dirtype;
NTSTATUS status;
+
START_PROFILE(SMBunlink);
-
+
dirtype = SVAL(inbuf,smb_vwv0);
-
- srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBunlink);
- return ERROR_NT(status);
- }
-
+
+ pstrcpy(name,smb_buf(inbuf) + 1);
+
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
-
+
DEBUG(3,("reply_unlink : %s\n",name));
-
+
status = unlink_internals(conn, dirtype, name);
if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
@@ -1628,8 +2184,9 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
* Win2k needs a changenotify request response before it will
* update after a rename..
*/
+
process_pending_change_notify_queue((time_t)0);
-
+
outsize = set_message(outbuf,0,0,True);
END_PROFILE(SMBunlink);
@@ -1672,7 +2229,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
header.length = 4;
header.free = NULL;
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
/*
* Special hack for broken Linux with no 64 bit clean sendfile. If we
* return ENOSYS then pretend we just got a normal read.
@@ -1692,13 +2249,8 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
if (nread > 0) {
ret = read_file(fsp,outbuf+4,startpos,nread);
-#if 0 /* mincount appears to be ignored in a W2K server. JRA. */
if (ret < mincount)
ret = 0;
-#else
- if (ret < nread)
- ret = 0;
-#endif
}
_smb_setlen(outbuf,ret);
@@ -1720,10 +2272,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
files_struct *fsp;
START_PROFILE(SMBreadbraw);
- if (srv_is_signing_active()) {
- exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
- }
-
/*
* Special check if an oplock break has been issued
* and the readraw request croses on the wire, we must
@@ -1798,6 +2346,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
+ maxcount = MAX(mincount,maxcount);
if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
SMB_OFF_T size = fsp->size;
@@ -1805,10 +2354,8 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
if (size < sizeneeded) {
SMB_STRUCT_STAT st;
- if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
- size = st.st_size;
- if (!fsp->can_write)
- fsp->size = size;
+ if (vfs_fstat(fsp,fsp->fd,&st) == 0)
+ fsp->size = size = st.st_size;
}
if (startpos >= size)
@@ -1817,10 +2364,8 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
nread = MIN(maxcount,(size - startpos));
}
-#if 0 /* mincount appears to be ignored in a W2K server. JRA. */
if (nread < mincount)
nread = 0;
-#endif
DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
(int)maxcount, (int)mincount, (int)nread ) );
@@ -1845,7 +2390,6 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
size_t numtoread;
NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- BOOL my_lock_ctx = False;
START_PROFILE(SMBlockread);
CHECK_FSP(fsp,conn);
@@ -1859,27 +2403,19 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
outsize = set_message(outbuf,5,3,True);
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
-
+
/*
* NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
* protocol request that predates the read/write lock concept.
* Thus instead of asking for a read lock here we need to ask
* for a write lock. JRA.
- * Note that the requested lock size is unaffected by max_recv.
*/
-
+
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
- (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &my_lock_ctx);
+ (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
if (NT_STATUS_V(status)) {
-#if 0
- /*
- * We used to make lockread a blocking lock. It turns out
- * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
- * tester. JRA.
- */
-
- if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
+ if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
@@ -1891,35 +2427,24 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
return -1;
}
}
-#endif
END_PROFILE(SMBlockread);
return ERROR_NT(status);
}
- /*
- * However the requested READ size IS affected by max_recv. Insanity.... JRA.
- */
-
- if (numtoread > max_recv) {
- DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
-Returning short read of maximum allowed for compatibility with Windows 2000.\n",
- (unsigned int)numtoread, (unsigned int)max_recv ));
- numtoread = MIN(numtoread,max_recv);
- }
nread = read_file(fsp,data,startpos,numtoread);
if (nread < 0) {
END_PROFILE(SMBlockread);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
-
+
outsize += nread;
SSVAL(outbuf,smb_vwv0,nread);
SSVAL(outbuf,smb_vwv5,nread+3);
SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
- fsp->fnum, (int)numtoread, (int)nread));
+
+ DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
+ fsp->fnum, (int)numtoread, (int)nread ) );
END_PROFILE(SMBlockread);
return(outsize);
@@ -1944,19 +2469,9 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
numtoread = SVAL(inbuf,smb_vwv1);
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-
+
outsize = set_message(outbuf,5,3,True);
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
- /*
- * The requested read size cannot be greater than max_recv. JRA.
- */
- if (numtoread > max_recv) {
- DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
-Returning short read of maximum allowed for compatibility with Windows 2000.\n",
- (unsigned int)numtoread, (unsigned int)max_recv ));
- numtoread = MIN(numtoread,max_recv);
- }
-
data = smb_buf(outbuf) + 3;
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
@@ -1966,7 +2481,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
if (numtoread > 0)
nread = read_file(fsp,data,startpos,numtoread);
-
+
if (nread < 0) {
END_PROFILE(SMBread);
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2006,7 +2521,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
SMB_STRUCT_STAT sbuf;
DATA_BLOB header;
- if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
+ if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1)
return(UNIXERROR(ERRDOS,ERRnoaccess));
if (startpos > sbuf.st_size)
@@ -2024,7 +2539,6 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
* correct amount of data).
*/
- SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,smb_maxcnt);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
@@ -2034,7 +2548,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
header.length = data - outbuf;
header.free = NULL;
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
/*
* Special hack for broken Linux with no 64 bit clean sendfile. If we
* return ENOSYS then pretend we just got a normal read.
@@ -2063,7 +2577,6 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
SSVAL(smb_buf(outbuf),-2,nread);
@@ -2082,12 +2595,12 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
{
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
- ssize_t nread = -1;
size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
#if 0
size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
#endif
-
+ ssize_t nread = -1;
+ char *data;
START_PROFILE(SMBreadX);
/* If it's an IPC, pass off the pipe handler. */
@@ -2100,6 +2613,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
CHECK_READ(fsp);
set_message(outbuf,12,0,True);
+ data = smb_buf(outbuf);
if(CVAL(inbuf,smb_wct) == 12) {
#ifdef LARGE_SMB_OFF_T
@@ -2129,7 +2643,6 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
END_PROFILE(SMBreadX);
return ERROR_DOS(ERRDOS,ERRlock);
}
-
nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
if (nread != -1)
nread = chain_reply(inbuf,outbuf,length,bufsize);
@@ -2155,10 +2668,6 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
int outsize = 0;
START_PROFILE(SMBwritebraw);
- if (srv_is_signing_active()) {
- exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
- }
-
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
@@ -2258,15 +2767,12 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
/* we won't return a status if write through is not selected - this follows what WfWg does */
END_PROFILE(SMBwritebraw);
if (!write_through && total_written==tcount) {
-
-#if RABBIT_PELLET_FIX
/*
* Fix for "rabbit pellet" mode, trigger an early TCP ack by
* sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
*/
if (!send_keepalive(smbd_server_fd()))
exit_server("reply_writebraw: send of keepalive failed");
-#endif
return(-1);
}
@@ -2277,65 +2783,62 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
Reply to a writeunlock (core+).
****************************************************************************/
-int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
- int size, int dum_buffsize)
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- ssize_t nwritten = -1;
- size_t numtowrite;
- SMB_OFF_T startpos;
- char *data;
- NTSTATUS status = NT_STATUS_OK;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- int outsize = 0;
- START_PROFILE(SMBwriteunlock);
-
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
+ ssize_t nwritten = -1;
+ size_t numtowrite;
+ SMB_OFF_T startpos;
+ char *data;
+ NTSTATUS status;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwriteunlock);
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ numtowrite = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+ data = smb_buf(inbuf) + 3;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
WRITE_LOCK,False)) {
- END_PROFILE(SMBwriteunlock);
+ END_PROFILE(SMBwriteunlock);
return ERROR_DOS(ERRDOS,ERRlock);
- }
-
- /* The special X/Open SMB protocol handling of
- zero length writes is *NOT* done for
- this call */
- if(numtowrite == 0)
- nwritten = 0;
- else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ }
+
+ /* The special X/Open SMB protocol handling of
+ zero length writes is *NOT* done for
+ this call */
+ if(numtowrite == 0)
+ nwritten = 0;
+ else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
- if (lp_syncalways(SNUM(conn)))
- sync_file(conn,fsp);
+ if (lp_syncalways(SNUM(conn)))
+ sync_file(conn,fsp);
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- END_PROFILE(SMBwriteunlock);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
- }
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwriteunlock);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
- if (numtowrite) {
- status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
- (SMB_BIG_UINT)startpos);
- if (NT_STATUS_V(status)) {
- END_PROFILE(SMBwriteunlock);
- return ERROR_NT(status);
- }
- }
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten));
-
- END_PROFILE(SMBwriteunlock);
- return outsize;
+ status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
+ (SMB_BIG_UINT)startpos);
+ if (NT_STATUS_V(status)) {
+ END_PROFILE(SMBwriteunlock);
+ return ERROR_NT(status);
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVAL(outbuf,smb_vwv0,nwritten);
+
+ DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten ) );
+
+ END_PROFILE(SMBwriteunlock);
+ return(outsize);
}
/****************************************************************************
@@ -2398,7 +2901,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
END_PROFILE(SMBwrite);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
}
outsize = set_message(outbuf,1,0,True);
@@ -2422,173 +2925,181 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
- files_struct *fsp = file_fsp(inbuf,smb_vwv2);
- SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
- size_t numtowrite = SVAL(inbuf,smb_vwv10);
- BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
- ssize_t nwritten = -1;
- unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
- unsigned int smblen = smb_len(inbuf);
- char *data;
- BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
- START_PROFILE(SMBwriteX);
-
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
- END_PROFILE(SMBwriteX);
- return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
- }
-
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
-
- /* Deal with possible LARGE_WRITEX */
- if (large_writeX)
- numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
-
- if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
- END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRbadmem);
- }
-
- data = smb_base(inbuf) + smb_doff;
-
- if(CVAL(inbuf,smb_wct) == 14) {
+ files_struct *fsp = file_fsp(inbuf,smb_vwv2);
+ SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
+ size_t numtowrite = SVAL(inbuf,smb_vwv10);
+ BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
+ ssize_t nwritten = -1;
+ unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
+ unsigned int smblen = smb_len(inbuf);
+ char *data;
+ BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
+ START_PROFILE(SMBwriteX);
+
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBwriteX);
+ return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
+ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ /* Deal with possible LARGE_WRITEX */
+ if (large_writeX)
+ numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
+
+ if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRbadmem);
+ }
+
+ data = smb_base(inbuf) + smb_doff;
+
+ if(CVAL(inbuf,smb_wct) == 14) {
#ifdef LARGE_SMB_OFF_T
- /*
- * This is a large offset (64 bit) write.
- */
- startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
+ /*
+ * This is a large offset (64 bit) write.
+ */
+ startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
#else /* !LARGE_SMB_OFF_T */
- /*
- * Ensure we haven't been sent a >32 bit offset.
- */
+ /*
+ * Ensure we haven't been sent a >32 bit offset.
+ */
- if(IVAL(inbuf,smb_vwv12) != 0) {
- DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
+ if(IVAL(inbuf,smb_vwv12) != 0) {
+ DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
- END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRbadaccess);
- }
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
+ }
#endif /* LARGE_SMB_OFF_T */
- }
-
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
- END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRlock);
- }
-
- /* X/Open SMB protocol says that, unlike SMBwrite
- if the length is zero then NO truncation is
- done, just a write of zero. To truncate a file,
- use SMBwrite. */
-
- if(numtowrite == 0)
- nwritten = 0;
- else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ }
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteX);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ /* X/Open SMB protocol says that, unlike SMBwrite
+ if the length is zero then NO truncation is
+ done, just a write of zero. To truncate a file,
+ use SMBwrite. */
+ if(numtowrite == 0)
+ nwritten = 0;
+ else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- END_PROFILE(SMBwriteX);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
- }
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwriteX);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
- set_message(outbuf,6,0,True);
+ set_message(outbuf,6,0,True);
- SSVAL(outbuf,smb_vwv2,nwritten);
- if (large_writeX)
- SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
+ SSVAL(outbuf,smb_vwv2,nwritten);
+ if (large_writeX)
+ SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
- if (nwritten < (ssize_t)numtowrite) {
- SCVAL(outbuf,smb_rcls,ERRHRD);
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
+ if (nwritten < (ssize_t)numtowrite) {
+ SCVAL(outbuf,smb_rcls,ERRHRD);
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
- DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten));
+ DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten));
- if (lp_syncalways(SNUM(conn)) || write_through)
- sync_file(conn,fsp);
+ if (lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
- END_PROFILE(SMBwriteX);
- return chain_reply(inbuf,outbuf,length,bufsize);
+ END_PROFILE(SMBwriteX);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
+
/****************************************************************************
Reply to a lseek.
****************************************************************************/
int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- SMB_OFF_T startpos;
- SMB_OFF_T res= -1;
- int mode,umode;
- int outsize = 0;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBlseek);
+ SMB_OFF_T startpos;
+ SMB_OFF_T res= -1;
+ int mode,umode;
+ int outsize = 0;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBlseek);
- CHECK_FSP(fsp,conn);
+ CHECK_FSP(fsp,conn);
- flush_write_cache(fsp, SEEK_FLUSH);
+ flush_write_cache(fsp, SEEK_FLUSH);
- mode = SVAL(inbuf,smb_vwv1) & 3;
- /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
- startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
+ mode = SVAL(inbuf,smb_vwv1) & 3;
+ /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
+ startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
- switch (mode) {
- case 0:
- umode = SEEK_SET;
- res = startpos;
- break;
- case 1:
- umode = SEEK_CUR;
- res = fsp->pos + startpos;
- break;
- case 2:
- umode = SEEK_END;
- break;
- default:
- umode = SEEK_SET;
- res = startpos;
- break;
+ switch (mode) {
+ case 0: umode = SEEK_SET; break;
+ case 1: umode = SEEK_CUR; break;
+ case 2: umode = SEEK_END; break;
+ default:
+ umode = SEEK_SET; break;
+ }
+
+ if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) {
+ /*
+ * Check for the special case where a seek before the start
+ * of the file sets the offset to zero. Added in the CIFS spec,
+ * section 4.2.7.
+ */
+
+ if(errno == EINVAL) {
+ SMB_OFF_T current_pos = startpos;
+
+ if(umode == SEEK_CUR) {
+
+ if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (umode == SEEK_END) {
- if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
- if(errno == EINVAL) {
- SMB_OFF_T current_pos = startpos;
- SMB_STRUCT_STAT sbuf;
+ current_pos += startpos;
- if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
- END_PROFILE(SMBlseek);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ } else if (umode == SEEK_END) {
- current_pos += sbuf.st_size;
- if(current_pos < 0)
- res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
- }
- }
+ SMB_STRUCT_STAT sbuf;
- if(res == -1) {
- END_PROFILE(SMBlseek);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- fsp->pos = res;
+ current_pos += sbuf.st_size;
+ }
+
+ if(current_pos < 0)
+ res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
+ }
+
+ if(res == -1) {
+ END_PROFILE(SMBlseek);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ fsp->pos = res;
- outsize = set_message(outbuf,2,0,True);
- SIVAL(outbuf,smb_vwv0,res);
+ outsize = set_message(outbuf,2,0,True);
+ SIVAL(outbuf,smb_vwv0,res);
- DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
- fsp->fnum, (double)startpos, (double)res, mode));
+ DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
+ fsp->fnum, (double)startpos, (double)res, mode));
- END_PROFILE(SMBlseek);
- return(outsize);
+ END_PROFILE(SMBlseek);
+ return(outsize);
}
/****************************************************************************
@@ -2598,19 +3109,17 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
int outsize = set_message(outbuf,0,0,True);
- uint16 fnum = SVAL(inbuf,smb_vwv0);
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBflush);
- if (fnum != 0xFFFF)
- CHECK_FSP(fsp,conn);
-
+ CHECK_FSP(fsp,conn);
+
if (!fsp) {
file_sync_all(conn);
} else {
sync_file(conn,fsp);
}
-
+
DEBUG(3,("flush\n"));
END_PROFILE(SMBflush);
return(outsize);
@@ -2625,9 +3134,6 @@ int reply_exit(connection_struct *conn,
{
int outsize;
START_PROFILE(SMBexit);
-
- file_close_pid(SVAL(inbuf,smb_pid));
-
outsize = set_message(outbuf,0,0,True);
DEBUG(3,("exit\n"));
@@ -2636,6 +3142,7 @@ int reply_exit(connection_struct *conn,
return(outsize);
}
+
/****************************************************************************
Reply to a close - has to deal with closing a directory opened by NT SMB's.
****************************************************************************/
@@ -2646,7 +3153,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
extern struct current_user current_user;
int outsize = 0;
time_t mtime;
- int32 eclass = 0, err = 0;
files_struct *fsp = NULL;
START_PROFILE(SMBclose);
@@ -2712,18 +3218,12 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
- /* We have a cached error */
- if(eclass || err) {
- END_PROFILE(SMBclose);
- return ERROR_DOS(eclass,err);
- }
-
END_PROFILE(SMBclose);
return(outsize);
}
/****************************************************************************
- Reply to a writeclose (Core+ protocol).
+ Reply to a writeclose (Core+ protocol)
****************************************************************************/
int reply_writeclose(connection_struct *conn,
@@ -2747,7 +3247,7 @@ int reply_writeclose(connection_struct *conn,
mtime = make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteclose);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2756,16 +3256,7 @@ int reply_writeclose(connection_struct *conn,
set_filetime(conn, fsp->fsp_name,mtime);
- /*
- * More insanity. W2K only closes the file if writelen > 0.
- * JRA.
- */
-
- if (numtowrite) {
- DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
- fsp->fsp_name ));
- close_err = close_file(fsp,True);
- }
+ close_err = close_file(fsp,True);
DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
fsp->fnum, (int)numtowrite, (int)nwritten,
@@ -2773,7 +3264,7 @@ int reply_writeclose(connection_struct *conn,
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
END_PROFILE(SMBwriteclose);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
}
if(close_err != 0) {
@@ -2800,8 +3291,6 @@ int reply_lock(connection_struct *conn,
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- BOOL my_lock_ctx = False;
-
START_PROFILE(SMBlock);
CHECK_FSP(fsp,conn);
@@ -2814,11 +3303,9 @@ int reply_lock(connection_struct *conn,
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fd, fsp->fnum, (double)offset, (double)count));
- status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
+ status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
if (NT_STATUS_V(status)) {
-#if 0
- /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
- if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
+ if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
@@ -2829,7 +3316,6 @@ int reply_lock(connection_struct *conn,
return -1;
}
}
-#endif
END_PROFILE(SMBlock);
return ERROR_NT(status);
}
@@ -2842,31 +3328,30 @@ int reply_lock(connection_struct *conn,
Reply to a unlock.
****************************************************************************/
-int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
- int dum_buffsize)
+int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- int outsize = set_message(outbuf,0,0,True);
- SMB_BIG_UINT count,offset;
+ int outsize = set_message(outbuf,0,0,True);
+ SMB_BIG_UINT count,offset;
NTSTATUS status;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBunlock);
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBunlock);
+
+ CHECK_FSP(fsp,conn);
+
+ count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
+ offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
- CHECK_FSP(fsp,conn);
-
- count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
- offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
-
status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
if (NT_STATUS_V(status)) {
- END_PROFILE(SMBunlock);
+ END_PROFILE(SMBunlock);
return ERROR_NT(status);
- }
+ }
- DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
- fsp->fd, fsp->fnum, (double)offset, (double)count ) );
-
- END_PROFILE(SMBunlock);
- return(outsize);
+ DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
+ fsp->fd, fsp->fnum, (double)offset, (double)count ) );
+
+ END_PROFILE(SMBunlock);
+ return(outsize);
}
/****************************************************************************
@@ -2909,11 +3394,7 @@ int reply_echo(connection_struct *conn,
int outsize = set_message(outbuf,1,data_len,True);
START_PROFILE(SMBecho);
- if (data_len > BUFFER_SIZE) {
- DEBUG(0,("reply_echo: data_len too large.\n"));
- END_PROFILE(SMBecho);
- return -1;
- }
+ data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
/* copy any incoming data back out */
if (data_len > 0)
@@ -2991,7 +3472,7 @@ int reply_printclose(connection_struct *conn,
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplclose);
- return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
DEBUG(3,("printclose fd=%d fnum=%d\n",
@@ -3054,12 +3535,15 @@ int reply_printqueue(connection_struct *conn,
for (i=first;i<first+num_to_get;i++) {
+ /* check to make sure we have room in the buffer */
+ if ( (PTR_DIFF(p, outbuf)+28) > BUFFER_SIZE )
+ break;
put_dos_date2(p,0,queue[i].time);
SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
SSVAL(p,5, queue[i].job);
SIVAL(p,7,queue[i].size);
SCVAL(p,11,0);
- srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
+ StrnCpy(p+12,queue[i].fs_user,16);
p += 28;
}
@@ -3086,33 +3570,32 @@ int reply_printqueue(connection_struct *conn,
int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- int numtowrite;
- int outsize = set_message(outbuf,0,0,True);
- char *data;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
-
- START_PROFILE(SMBsplwr);
+ int numtowrite;
+ int outsize = set_message(outbuf,0,0,True);
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBsplwr);
- if (!CAN_PRINT(conn)) {
- END_PROFILE(SMBsplwr);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
+ if (!CAN_PRINT(conn)) {
+ END_PROFILE(SMBsplwr);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
- numtowrite = SVAL(smb_buf(inbuf),1);
- data = smb_buf(inbuf) + 3;
+ numtowrite = SVAL(smb_buf(inbuf),1);
+ data = smb_buf(inbuf) + 3;
- if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
- END_PROFILE(SMBsplwr);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
- }
+ if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
+ END_PROFILE(SMBsplwr);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
- DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
+ DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
- END_PROFILE(SMBsplwr);
- return(outsize);
+ END_PROFILE(SMBsplwr);
+ return(outsize);
}
/****************************************************************************
@@ -3125,30 +3608,19 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
BOOL bad_path = False;
SMB_STRUCT_STAT sbuf;
int ret= -1;
-
+
unix_convert(directory,conn,0,&bad_path,&sbuf);
-
- if( strchr_m(directory, ':')) {
- return NT_STATUS_NOT_A_DIRECTORY;
- }
-
- if (ms_has_wild(directory)) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
-
+
if (check_name(directory, conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
-
+ ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+
if (ret == -1) {
- if(errno == ENOENT) {
- if (bad_path)
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- else
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
+ NTSTATUS nterr = set_bad_path_error(errno, bad_path);
+ if (!NT_STATUS_IS_OK(nterr))
+ return nterr;
return map_nt_error_from_unix(errno);
}
-
+
return NT_STATUS_OK;
}
@@ -3163,19 +3635,13 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
NTSTATUS status;
START_PROFILE(SMBmkdir);
- srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBmkdir);
- return ERROR_NT(status);
- }
+ pstrcpy(directory,smb_buf(inbuf) + 1);
RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
status = mkdir_internal(conn, directory);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBmkdir);
+ if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
- }
outsize = set_message(outbuf,0,0,True);
@@ -3192,7 +3658,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
static BOOL recursive_rmdir(connection_struct *conn, char *directory)
{
- const char *dname = NULL;
+ char *dname = NULL;
BOOL ret = False;
void *dirptr = OpenDir(conn, directory, False);
@@ -3217,7 +3683,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
pstrcat(fullname, "/");
pstrcat(fullname, dname);
- if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
+ if(conn->vfs_ops.lstat(conn,dos_to_unix_static(fullname), &st) != 0) {
ret = True;
break;
}
@@ -3227,15 +3693,16 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
ret = True;
break;
}
- if(SMB_VFS_RMDIR(conn,fullname) != 0) {
+ if(vfs_rmdir(conn,fullname) != 0) {
ret = True;
break;
}
- } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
+ } else if(vfs_unlink(conn,fullname) != 0) {
ret = True;
break;
}
}
+
CloseDir(dirptr);
return ret;
}
@@ -3248,7 +3715,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
{
BOOL ok;
- ok = (SMB_VFS_RMDIR(conn,directory) == 0);
+ ok = (vfs_rmdir(conn,directory) == 0);
if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
/*
* Check to see if the only thing in this directory are
@@ -3257,7 +3724,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
* do a recursive delete) then fail the rmdir.
*/
BOOL all_veto_files = True;
- const char *dname;
+ char *dname;
void *dirptr = OpenDir(conn, directory, False);
if(dirptr != NULL) {
@@ -3270,7 +3737,6 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
break;
}
}
-
if(all_veto_files) {
SeekDir(dirptr,dirpos);
while ((dname = ReadDirName(dirptr))) {
@@ -3285,26 +3751,25 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
errno = ENOMEM;
break;
}
-
pstrcpy(fullname, directory);
pstrcat(fullname, "/");
pstrcat(fullname, dname);
- if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
+ if(conn->vfs_ops.lstat(conn,dos_to_unix_static(fullname), &st) != 0)
break;
if(st.st_mode & S_IFDIR) {
if(lp_recursive_veto_delete(SNUM(conn))) {
if(recursive_rmdir(conn, fullname) != 0)
break;
}
- if(SMB_VFS_RMDIR(conn,fullname) != 0)
+ if(vfs_rmdir(conn,fullname) != 0)
break;
- } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
+ } else if(vfs_unlink(conn,fullname) != 0)
break;
}
CloseDir(dirptr);
/* Retry the rmdir */
- ok = (SMB_VFS_RMDIR(conn,directory) == 0);
+ ok = (vfs_rmdir(conn,directory) == 0);
} else {
CloseDir(dirptr);
}
@@ -3312,7 +3777,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
errno = ENOTEMPTY;
}
}
-
+
if (!ok)
DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
@@ -3325,261 +3790,103 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring directory;
- int outsize = 0;
- BOOL ok = False;
- BOOL bad_path = False;
- SMB_STRUCT_STAT sbuf;
- NTSTATUS status;
- START_PROFILE(SMBrmdir);
+ pstring directory;
+ int outsize = 0;
+ BOOL ok = False;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+ START_PROFILE(SMBrmdir);
- srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBrmdir);
- return ERROR_NT(status);
- }
+ pstrcpy(directory,smb_buf(inbuf) + 1);
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+ RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
- unix_convert(directory,conn, NULL,&bad_path,&sbuf);
+ unix_convert(directory,conn, NULL,&bad_path,&sbuf);
- if (check_name(directory,conn)) {
- dptr_closepath(directory,SVAL(inbuf,smb_pid));
- ok = rmdir_internals(conn, directory);
- }
+ if (check_name(directory,conn))
+ {
+ dptr_closepath(directory,SVAL(inbuf,smb_pid));
+ ok = rmdir_internals(conn, directory);
+ }
- if (!ok) {
- END_PROFILE(SMBrmdir);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
- }
+ if (!ok)
+ {
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBrmdir);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
- outsize = set_message(outbuf,0,0,True);
+ outsize = set_message(outbuf,0,0,True);
- DEBUG( 3, ( "rmdir %s\n", directory ) );
+ DEBUG( 3, ( "rmdir %s\n", directory ) );
- END_PROFILE(SMBrmdir);
- return(outsize);
+ END_PROFILE(SMBrmdir);
+ return(outsize);
}
/*******************************************************************
Resolve wildcards in a filename rename.
- Note that name is in UNIX charset and thus potentially can be more
- than fstring buffer (255 bytes) especially in default UTF-8 case.
- Therefore, we use pstring inside and all calls should ensure that
- name2 is at least pstring-long (they do already)
********************************************************************/
-static BOOL resolve_wildcards(const char *name1, char *name2)
+static BOOL resolve_wildcards(char *name1,char *name2)
{
- pstring root1,root2;
- pstring ext1,ext2;
- char *p,*p2, *pname1, *pname2;
- int available_space, actual_space;
-
+ fstring root1,root2;
+ fstring ext1,ext2;
+ char *p,*p2;
- pname1 = strrchr_m(name1,'/');
- pname2 = strrchr_m(name2,'/');
+ name1 = strrchr(name1,'/');
+ name2 = strrchr(name2,'/');
- if (!pname1 || !pname2)
- return(False);
+ if (!name1 || !name2) return(False);
- pstrcpy(root1,pname1);
- pstrcpy(root2,pname2);
- p = strrchr_m(root1,'.');
- if (p) {
- *p = 0;
- pstrcpy(ext1,p+1);
- } else {
- pstrcpy(ext1,"");
- }
- p = strrchr_m(root2,'.');
- if (p) {
- *p = 0;
- pstrcpy(ext2,p+1);
- } else {
- pstrcpy(ext2,"");
- }
-
- p = root1;
- p2 = root2;
- while (*p2) {
- if (*p2 == '?') {
- *p2 = *p;
- p2++;
- } else if (*p2 == '*') {
- pstrcpy(p2, p);
- break;
- } else {
- p2++;
- }
- if (*p)
- p++;
- }
-
- p = ext1;
- p2 = ext2;
- while (*p2) {
- if (*p2 == '?') {
- *p2 = *p;
- p2++;
- } else if (*p2 == '*') {
- pstrcpy(p2, p);
- break;
- } else {
- p2++;
- }
- if (*p)
- p++;
- }
-
- available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
-
- if (ext2[0]) {
- actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
- if (actual_space >= available_space - 1) {
- DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
- actual_space - available_space));
- }
- } else {
- pstrcpy_base(pname2, root2, name2);
- }
-
- return(True);
-}
-
-/****************************************************************************
- Ensure open files have their names updates.
-****************************************************************************/
-
-static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
-{
- files_struct *fsp;
- BOOL did_rename = False;
-
- for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
- DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
- fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
- fsp->fsp_name, newname ));
- string_set(&fsp->fsp_name, newname);
- did_rename = True;
- }
-
- if (!did_rename)
- DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
- (unsigned int)dev, (double)inode, newname ));
-}
-
-/****************************************************************************
- Rename an open file - given an fsp.
-****************************************************************************/
-
-NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, BOOL replace_if_exists)
-{
- SMB_STRUCT_STAT sbuf;
- BOOL bad_path = False;
- pstring newname_last_component;
- NTSTATUS error = NT_STATUS_OK;
- BOOL dest_exists;
- BOOL rcdest = True;
-
- ZERO_STRUCT(sbuf);
- rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
-
- /* Quick check for "." and ".." */
- if (!bad_path && newname_last_component[0] == '.') {
- if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) {
- return NT_STATUS_ACCESS_DENIED;
- }
- }
- if (!rcdest && bad_path) {
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* Ensure newname contains a '/' */
- if(strrchr_m(newname,'/') == 0) {
- pstring tmpstr;
-
- pstrcpy(tmpstr, "./");
- pstrcat(tmpstr, newname);
- pstrcpy(newname, tmpstr);
- }
-
- /*
- * Check for special case with case preserving and not
- * case sensitive. If the old last component differs from the original
- * last component only by case, then we should allow
- * the rename (user is trying to change the case of the
- * filename).
- */
-
- if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
- strequal(newname, fsp->fsp_name)) {
- char *p;
- pstring newname_modified_last_component;
-
- /*
- * Get the last component of the modified name.
- * Note that we guarantee that newname contains a '/'
- * character above.
- */
- p = strrchr_m(newname,'/');
- pstrcpy(newname_modified_last_component,p+1);
-
- if(strcsequal(newname_modified_last_component,
- newname_last_component) == False) {
- /*
- * Replace the modified last component with
- * the original.
- */
- pstrcpy(p+1, newname_last_component);
- }
- }
-
- /*
- * If the src and dest names are identical - including case,
- * don't do the rename, just return success.
- */
-
- if (strcsequal(fsp->fsp_name, newname)) {
- DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
- newname));
- return NT_STATUS_OK;
- }
-
- dest_exists = vfs_object_exist(conn,newname,NULL);
-
- if(!replace_if_exists && dest_exists) {
- DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
- fsp->fsp_name,newname));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- error = can_rename(newname,conn,&sbuf);
-
- if (dest_exists && !NT_STATUS_IS_OK(error)) {
- DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
- nt_errstr(error), fsp->fsp_name,newname));
- if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
- error = NT_STATUS_ACCESS_DENIED;
- return error;
- }
-
- if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
- DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
- fsp->fsp_name,newname));
- rename_open_files(conn, fsp->dev, fsp->inode, newname);
- return NT_STATUS_OK;
- }
-
- if (errno == ENOTDIR || errno == EISDIR)
- error = NT_STATUS_OBJECT_NAME_COLLISION;
- else
- error = map_nt_error_from_unix(errno);
-
- DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
- nt_errstr(error), fsp->fsp_name,newname));
-
- return error;
+ fstrcpy(root1,name1);
+ fstrcpy(root2,name2);
+ p = strrchr(root1,'.');
+ if (p) {
+ *p = 0;
+ fstrcpy(ext1,p+1);
+ } else {
+ fstrcpy(ext1,"");
+ }
+ p = strrchr(root2,'.');
+ if (p) {
+ *p = 0;
+ fstrcpy(ext2,p+1);
+ } else {
+ fstrcpy(ext2,"");
+ }
+
+ p = root1;
+ p2 = root2;
+ while (*p2) {
+ if (*p2 == '?') {
+ *p2 = *p;
+ p2++;
+ } else {
+ p2++;
+ }
+ if (*p) p++;
+ }
+
+ p = ext1;
+ p2 = ext2;
+ while (*p2) {
+ if (*p2 == '?') {
+ *p2 = *p;
+ p2++;
+ } else {
+ p2++;
+ }
+ if (*p) p++;
+ }
+
+ pstrcpy(name2,root2);
+ if (ext2[0]) {
+ pstrcat(name2,".");
+ pstrcat(name2,ext2);
+ }
+
+ return(True);
}
/****************************************************************************
@@ -3587,49 +3894,24 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *
code.
****************************************************************************/
-NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists)
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
{
pstring directory;
pstring mask;
- pstring last_component_src;
- pstring last_component_dest;
+ pstring newname_last_component;
char *p;
BOOL has_wild;
- BOOL bad_path_src = False;
- BOOL bad_path_dest = False;
+ BOOL bad_path1 = False;
+ BOOL bad_path2 = False;
int count=0;
NTSTATUS error = NT_STATUS_OK;
BOOL rc = True;
- BOOL rcdest = True;
SMB_STRUCT_STAT sbuf1, sbuf2;
*directory = *mask = 0;
- ZERO_STRUCT(sbuf1);
- ZERO_STRUCT(sbuf2);
-
- rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1);
- if (!rc && bad_path_src) {
- if (ms_has_wild(last_component_src))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* Quick check for "." and ".." */
- if (last_component_src[0] == '.') {
- if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- }
-
- rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2);
-
- /* Quick check for "." and ".." */
- if (last_component_dest[0] == '.') {
- if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- }
+ rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+ unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
/*
* Split the old name into directory and last component
@@ -3639,8 +3921,8 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
* name and newname contain a / character or neither of them do
* as this is checked in resolve_wildcards().
*/
-
- p = strrchr_m(name,'/');
+
+ p = strrchr(name,'/');
if (!p) {
pstrcpy(directory,".");
pstrcpy(mask,name);
@@ -3666,6 +3948,9 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
has_wild = ms_has_wild(mask);
if (!has_wild) {
+ pstring zdirectory;
+ pstring znewname;
+
/*
* No wildcards - just process the one file.
*/
@@ -3676,7 +3961,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
pstrcat(directory,mask);
/* Ensure newname contains a '/' also */
- if(strrchr_m(newname,'/') == 0) {
+ if(strrchr(newname,'/') == 0) {
pstring tmpstr;
pstrcpy(tmpstr, "./");
@@ -3685,9 +3970,9 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
}
DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
-directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
- conn->case_sensitive, conn->case_preserve, conn->short_case_preserve, directory,
- newname, last_component_dest, is_short_name));
+directory = %s, newname = %s, newname_last_component = %s, mangle_is_8_3 = %d\n",
+ case_sensitive, case_preserve, short_case_preserve, directory,
+ newname, newname_last_component, is_short_name));
/*
* Check for special case with case preserving and not
@@ -3697,34 +3982,35 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
* the rename (user is trying to change the case of the
* filename).
*/
- if((conn->case_sensitive == False) &&
- (((conn->case_preserve == True) &&
+ if((case_sensitive == False) &&
+ (((case_preserve == True) &&
(is_short_name == False)) ||
- ((conn->short_case_preserve == True) &&
+ ((short_case_preserve == True) &&
(is_short_name == True))) &&
strcsequal(directory, newname)) {
- pstring modified_last_component;
+ pstring newname_modified_last_component;
/*
* Get the last component of the modified name.
* Note that we guarantee that newname contains a '/'
* character above.
*/
- p = strrchr_m(newname,'/');
- pstrcpy(modified_last_component,p+1);
+ p = strrchr(newname,'/');
+ pstrcpy(newname_modified_last_component,p+1);
- if(strcsequal(modified_last_component,
- last_component_dest) == False) {
+ if(strcsequal(newname_modified_last_component,
+ newname_last_component) == False) {
/*
* Replace the modified last component with
* the original.
*/
- pstrcpy(p+1, last_component_dest);
+ pstrcpy(p+1, newname_last_component);
}
}
-
+
+
resolve_wildcards(directory,newname);
-
+
/*
* The source object must exist.
*/
@@ -3739,7 +4025,7 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
* directory existed or not.
*/
- p = strrchr_m(directory, '/');
+ p = strrchr(directory, '/');
if (!p)
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
*p = '\0';
@@ -3749,32 +4035,28 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
}
error = map_nt_error_from_unix(errno);
DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
- nt_errstr(error), directory,newname));
+ get_nt_error_msg(error), directory,newname));
return error;
}
- if (!rcdest && bad_path_dest) {
- if (ms_has_wild(last_component_dest))
- return NT_STATUS_OBJECT_NAME_INVALID;
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
error = can_rename(directory,conn,&sbuf1);
if (!NT_STATUS_IS_OK(error)) {
DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
- nt_errstr(error), directory,newname));
+ get_nt_error_msg(error), directory,newname));
return error;
}
+ pstrcpy(zdirectory, dos_to_unix_static(directory));
+ pstrcpy(znewname, dos_to_unix_static(newname));
+
/*
* If the src and dest names are identical - including case,
* don't do the rename, just return success.
*/
- if (strcsequal(directory, newname)) {
- rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
+ if (strcsequal(zdirectory, znewname)) {
DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
return NT_STATUS_OK;
}
@@ -3785,10 +4067,9 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
+ if(conn->vfs_ops.rename(conn,zdirectory, znewname) == 0) {
DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
directory,newname));
- rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
return NT_STATUS_OK;
}
@@ -3798,62 +4079,45 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
error = map_nt_error_from_unix(errno);
DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
- nt_errstr(error), directory,newname));
+ get_nt_error_msg(error), directory,newname));
return error;
} else {
+
/*
* Wildcards - process each file that matches.
*/
void *dirptr = NULL;
- const char *dname;
+ char *dname;
pstring destname;
if (check_name(directory,conn))
dirptr = OpenDir(conn, directory, True);
if (dirptr) {
- error = NT_STATUS_NO_SUCH_FILE;
-/* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
while ((dname = ReadDirName(dirptr))) {
pstring fname;
- BOOL sysdir_entry = False;
pstrcpy(fname,dname);
- /* Quick check for "." and ".." */
- if (fname[0] == '.') {
- if (!fname[1] || (fname[1] == '.' && !fname[2])) {
- if (attrs & aDIR) {
- sysdir_entry = True;
- } else {
- continue;
- }
- }
- }
-
- if(!mask_match(fname, mask, conn->case_sensitive))
+ if(!mask_match(fname, mask, case_sensitive))
continue;
- if (sysdir_entry) {
- error = NT_STATUS_OBJECT_NAME_INVALID;
- break;
- }
-
error = NT_STATUS_ACCESS_DENIED;
slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
if (!vfs_object_exist(conn, fname, &sbuf1)) {
error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
+ DEBUG(6,("rename %s failed. Error %s\n", fname, get_nt_error_msg(error)));
continue;
}
error = can_rename(fname,conn,&sbuf1);
if (!NT_STATUS_IS_OK(error)) {
- DEBUG(6,("rename %s refused\n", fname));
+ DEBUG(6,("rename %s failed. Error %s\n", fname, get_nt_error_msg(error)));
continue;
}
pstrcpy(destname,newname);
@@ -3864,40 +4128,22 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
continue;
}
- if (strcsequal(fname,destname)) {
- rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
- DEBUG(3,("rename_internals: identical names in wildcard rename %s - success\n", fname));
- count++;
- error = NT_STATUS_OK;
- continue;
- }
-
if (!replace_if_exists &&
- vfs_file_exist(conn,destname, NULL)) {
+ vfs_object_exist(conn,destname, NULL)) {
DEBUG(6,("file_exist %s\n", destname));
error = NT_STATUS_OBJECT_NAME_COLLISION;
continue;
}
- if (!SMB_VFS_RENAME(conn,fname,destname)) {
- rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
+ if (!conn->vfs_ops.rename(conn,dos_to_unix_static(fname),
+ dos_to_unix_static(destname)))
count++;
- error = NT_STATUS_OK;
- }
DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
}
CloseDir(dirptr);
}
-
- if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) {
- if (!rcdest && bad_path_dest) {
- if (ms_has_wild(last_component_dest))
- return NT_STATUS_OBJECT_NAME_INVALID;
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
- }
}
-
+
if (count == 0 && NT_STATUS_IS_OK(error)) {
error = map_nt_error_from_unix(errno);
}
@@ -3909,46 +4155,31 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
Reply to a mv.
****************************************************************************/
-int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
- int dum_buffsize)
+int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
pstring name;
pstring newname;
- char *p;
- uint16 attrs = SVAL(inbuf,smb_vwv0);
NTSTATUS status;
-
START_PROFILE(SMBmv);
- p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBmv);
- return ERROR_NT(status);
- }
- p++;
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBmv);
- return ERROR_NT(status);
- }
-
+ pstrcpy(name,smb_buf(inbuf) + 1);
+ pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
+
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
-
+
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
-
- status = rename_internals(conn, name, newname, attrs, False);
+
+ status = rename_internals(conn, name, newname, False);
if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBmv);
return ERROR_NT(status);
}
/*
* Win2k needs a changenotify request response before it will
* update after a rename..
- */
+ */
process_pending_change_notify_queue((time_t)0);
outsize = set_message(outbuf,0,0,True);
@@ -3968,13 +4199,12 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
SMB_OFF_T ret=-1;
files_struct *fsp1,*fsp2;
pstring dest;
- uint32 dosattrs;
-
+
*err_ret = 0;
pstrcpy(dest,dest1);
if (target_is_directory) {
- char *p = strrchr_m(src,'/');
+ char *p = strrchr(src,'/');
if (p)
p++;
else
@@ -3987,7 +4217,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
return(False);
fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,0,&Access,&action);
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
if (!fsp1)
return(False);
@@ -3995,12 +4225,11 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
if (!target_is_directory && count)
ofun = FILE_EXISTS_OPEN;
- dosattrs = dos_mode(conn, src, &src_sbuf);
- if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
+ if (vfs_stat(conn,dest,&sbuf2) == -1)
ZERO_STRUCTP(&sbuf2);
fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
- ofun,dosattrs,0,&Access,&action);
+ ofun,src_sbuf.st_mode,0,&Access,&action);
if (!fsp2) {
close_file(fsp1,False);
@@ -4008,7 +4237,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
}
if ((ofun&3) == 1) {
- if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
+ if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
/*
* Stop the copy from occurring.
@@ -4043,174 +4272,162 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- int outsize = 0;
- pstring name;
- pstring directory;
- pstring mask,newname;
- char *p;
- int count=0;
- int error = ERRnoaccess;
- int err = 0;
- BOOL has_wild;
- BOOL exists=False;
- int tid2 = SVAL(inbuf,smb_vwv0);
- int ofun = SVAL(inbuf,smb_vwv1);
- int flags = SVAL(inbuf,smb_vwv2);
- BOOL target_is_directory=False;
- BOOL bad_path1 = False;
- BOOL bad_path2 = False;
- BOOL rc = True;
- SMB_STRUCT_STAT sbuf1, sbuf2;
- NTSTATUS status;
-
- START_PROFILE(SMBcopy);
-
- *directory = *mask = 0;
-
- p = smb_buf(inbuf);
- p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcopy);
- return ERROR_NT(status);
- }
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcopy);
- return ERROR_NT(status);
- }
+ int outsize = 0;
+ pstring name;
+ pstring directory;
+ pstring mask,newname;
+ char *p;
+ int count=0;
+ int error = ERRnoaccess;
+ int err = 0;
+ BOOL has_wild;
+ BOOL exists=False;
+ int tid2 = SVAL(inbuf,smb_vwv0);
+ int ofun = SVAL(inbuf,smb_vwv1);
+ int flags = SVAL(inbuf,smb_vwv2);
+ BOOL target_is_directory=False;
+ BOOL bad_path1 = False;
+ BOOL bad_path2 = False;
+ BOOL rc = True;
+ SMB_STRUCT_STAT sbuf1, sbuf2;
+ START_PROFILE(SMBcopy);
+
+ *directory = *mask = 0;
+
+ pstrcpy(name,smb_buf(inbuf));
+ pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name));
- DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
+ DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
- if (tid2 != conn->cnum) {
- /* can't currently handle inter share copies XXXX */
- DEBUG(3,("Rejecting inter-share copy\n"));
+ if (tid2 != conn->cnum) {
+ /* can't currently handle inter share copies XXXX */
+ DEBUG(3,("Rejecting inter-share copy\n"));
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRSRV,ERRinvdevice);
+ }
+
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
+ rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+ unix_convert(newname,conn,0,&bad_path2,&sbuf2);
+
+ target_is_directory = VALID_STAT_OF_DIR(sbuf2);
+
+ if ((flags&1) && target_is_directory) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,ERRbadfile);
+ }
+
+ if ((flags&2) && !target_is_directory) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,ERRbadpath);
+ }
+
+ if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
+ /* wants a tree copy! XXXX */
+ DEBUG(3,("Rejecting tree copy\n"));
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ p = strrchr(name,'/');
+ if (!p) {
+ pstrcpy(directory,"./");
+ pstrcpy(mask,name);
+ } else {
+ *p = 0;
+ pstrcpy(directory,name);
+ pstrcpy(mask,p+1);
+ }
+
+ /*
+ * We should only check the mangled cache
+ * here if unix_convert failed. This means
+ * that the path in 'mask' doesn't exist
+ * on the file system and so we need to look
+ * for a possible mangle. This patch from
+ * Tine Smukavec <valentin.smukavec@hermes.si>.
+ */
+
+ if (!rc && mangle_is_mangled(mask))
+ mangle_check_cache( mask );
+
+ has_wild = ms_has_wild(mask);
+
+ if (!has_wild) {
+ pstrcat(directory,"/");
+ pstrcat(directory,mask);
+ if (resolve_wildcards(directory,newname) &&
+ copy_file(directory,newname,conn,ofun,
+ count,target_is_directory,&err)) count++;
+ if(!count && err) {
+ errno = err;
END_PROFILE(SMBcopy);
- return ERROR_DOS(ERRSRV,ERRinvdevice);
- }
-
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
-
- rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
- unix_convert(newname,conn,0,&bad_path2,&sbuf2);
-
- target_is_directory = VALID_STAT_OF_DIR(sbuf2);
-
- if ((flags&1) && target_is_directory) {
- END_PROFILE(SMBcopy);
- return ERROR_DOS(ERRDOS,ERRbadfile);
- }
-
- if ((flags&2) && !target_is_directory) {
- END_PROFILE(SMBcopy);
- return ERROR_DOS(ERRDOS,ERRbadpath);
- }
-
- if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
- /* wants a tree copy! XXXX */
- DEBUG(3,("Rejecting tree copy\n"));
- END_PROFILE(SMBcopy);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- p = strrchr_m(name,'/');
- if (!p) {
- pstrcpy(directory,"./");
- pstrcpy(mask,name);
- } else {
- *p = 0;
- pstrcpy(directory,name);
- pstrcpy(mask,p+1);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
}
+ if (!count) exists = vfs_file_exist(conn,directory,NULL);
+ } else {
+ void *dirptr = NULL;
+ char *dname;
+ pstring destname;
- /*
- * We should only check the mangled cache
- * here if unix_convert failed. This means
- * that the path in 'mask' doesn't exist
- * on the file system and so we need to look
- * for a possible mangle. This patch from
- * Tine Smukavec <valentin.smukavec@hermes.si>.
- */
-
- if (!rc && mangle_is_mangled(mask))
- mangle_check_cache( mask );
-
- has_wild = ms_has_wild(mask);
-
- if (!has_wild) {
- pstrcat(directory,"/");
- pstrcat(directory,mask);
- if (resolve_wildcards(directory,newname) &&
- copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
- count++;
- if(!count && err) {
- errno = err;
- END_PROFILE(SMBcopy);
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
- if (!count) {
- exists = vfs_file_exist(conn,directory,NULL);
- }
- } else {
- void *dirptr = NULL;
- const char *dname;
- pstring destname;
+ if (check_name(directory,conn))
+ dirptr = OpenDir(conn, directory, True);
- if (check_name(directory,conn))
- dirptr = OpenDir(conn, directory, True);
-
- if (dirptr) {
- error = ERRbadfile;
+ if (dirptr) {
+ error = ERRbadfile;
- if (strequal(mask,"????????.???"))
- pstrcpy(mask,"*");
+ if (strequal(mask,"????????.???"))
+ pstrcpy(mask,"*");
- while ((dname = ReadDirName(dirptr))) {
- pstring fname;
- pstrcpy(fname,dname);
-
- if(!mask_match(fname, mask, conn->case_sensitive))
- continue;
+ while ((dname = ReadDirName(dirptr))) {
+ pstring fname;
+ pstrcpy(fname,dname);
+
+ if(!mask_match(fname, mask, case_sensitive))
+ continue;
- error = ERRnoaccess;
- slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
- pstrcpy(destname,newname);
- if (resolve_wildcards(fname,destname) &&
- copy_file(fname,destname,conn,ofun,
- count,target_is_directory,&err))
- count++;
- DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
- }
- CloseDir(dirptr);
- }
- }
+ error = ERRnoaccess;
+ slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
+ pstrcpy(destname,newname);
+ if (resolve_wildcards(fname,destname) &&
+ copy_file(fname,destname,conn,ofun,
+ count,target_is_directory,&err)) count++;
+ DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
+ }
+ CloseDir(dirptr);
+ }
+ }
- if (count == 0) {
- if(err) {
- /* Error on close... */
- errno = err;
- END_PROFILE(SMBcopy);
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
-
- if (exists) {
- END_PROFILE(SMBcopy);
- return ERROR_DOS(ERRDOS,error);
- } else {
- if((errno == ENOENT) && (bad_path1 || bad_path2)) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- END_PROFILE(SMBcopy);
- return(UNIXERROR(ERRDOS,error));
- }
- }
+ if (count == 0) {
+ if(err) {
+ /* Error on close... */
+ errno = err;
+ END_PROFILE(SMBcopy);
+ return(UNIXERROR(ERRHRD,ERRgeneral));
+ }
+
+ if (exists) {
+ END_PROFILE(SMBcopy);
+ return ERROR_DOS(ERRDOS,error);
+ } else
+ {
+ if((errno == ENOENT) && (bad_path1 || bad_path2))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ END_PROFILE(SMBcopy);
+ return(UNIXERROR(ERRDOS,error));
+ }
+ }
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,count);
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,count);
- END_PROFILE(SMBcopy);
- return(outsize);
+ END_PROFILE(SMBcopy);
+ return(outsize);
}
/****************************************************************************
@@ -4219,46 +4436,42 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- int snum;
- int outsize = 0;
- BOOL ok = False;
- pstring newdir;
- NTSTATUS status;
-
- START_PROFILE(pathworks_setdir);
+ int snum;
+ int outsize = 0;
+ BOOL ok = False;
+ pstring newdir;
+ START_PROFILE(pathworks_setdir);
- snum = SNUM(conn);
- if (!CAN_SETDIR(snum)) {
- END_PROFILE(pathworks_setdir);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(pathworks_setdir);
- return ERROR_NT(status);
- }
+ snum = SNUM(conn);
+ if (!CAN_SETDIR(snum)) {
+ END_PROFILE(pathworks_setdir);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
- if (strlen(newdir) == 0) {
- ok = True;
- } else {
- ok = vfs_directory_exist(conn,newdir,NULL);
- if (ok)
- string_set(&conn->connectpath,newdir);
- }
+ pstrcpy(newdir,smb_buf(inbuf) + 1);
+ strlower(newdir);
- if (!ok) {
- END_PROFILE(pathworks_setdir);
- return ERROR_DOS(ERRDOS,ERRbadpath);
- }
+ if (strlen(newdir) == 0) {
+ ok = True;
+ } else {
+ ok = vfs_directory_exist(conn,newdir,NULL);
+ if (ok) {
+ string_set(&conn->connectpath,newdir);
+ }
+ }
- outsize = set_message(outbuf,0,0,True);
- SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
+ if (!ok) {
+ END_PROFILE(pathworks_setdir);
+ return ERROR_DOS(ERRDOS,ERRbadpath);
+ }
- DEBUG(3,("setdir %s\n", newdir));
+ outsize = set_message(outbuf,0,0,True);
+ SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
+
+ DEBUG(3,("setdir %s\n", newdir));
- END_PROFILE(pathworks_setdir);
- return(outsize);
+ END_PROFILE(pathworks_setdir);
+ return(outsize);
}
/****************************************************************************
@@ -4279,36 +4492,36 @@ uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
{
- SMB_BIG_UINT count = 0;
+ SMB_BIG_UINT count = 0;
- if(!large_file_format) {
- count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
- } else {
+ if(!large_file_format) {
+ count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
+ } else {
#if defined(HAVE_LONGLONG)
- count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
- ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
+ count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
+ ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
#else /* HAVE_LONGLONG */
- /*
- * NT4.x seems to be broken in that it sends large file (64 bit)
- * lockingX calls even if the CAP_LARGE_FILES was *not*
- * negotiated. For boxes without large unsigned ints truncate the
- * lock count by dropping the top 32 bits.
- */
-
- if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
- DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
- (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
- (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
- SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
- }
-
- count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
+ /*
+ * NT4.x seems to be broken in that it sends large file (64 bit)
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large unsigned ints truncate the
+ * lock count by dropping the top 32 bits.
+ */
+
+ if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
+ DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
+ (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
+ (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
+ SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
+ }
+
+ count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
#endif /* HAVE_LONGLONG */
- }
+ }
- return count;
+ return count;
}
#if !defined(HAVE_LONGLONG)
@@ -4351,47 +4564,47 @@ static uint32 map_lock_offset(uint32 high, uint32 low)
SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
{
- SMB_BIG_UINT offset = 0;
+ SMB_BIG_UINT offset = 0;
- *err = False;
+ *err = False;
- if(!large_file_format) {
- offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
- } else {
+ if(!large_file_format) {
+ offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
+ } else {
#if defined(HAVE_LONGLONG)
- offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
- ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
+ offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
+ ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
#else /* HAVE_LONGLONG */
- /*
- * NT4.x seems to be broken in that it sends large file (64 bit)
- * lockingX calls even if the CAP_LARGE_FILES was *not*
- * negotiated. For boxes without large unsigned ints mangle the
- * lock offset by mapping the top 32 bits onto the lower 32.
- */
+ /*
+ * NT4.x seems to be broken in that it sends large file (64 bit)
+ * lockingX calls even if the CAP_LARGE_FILES was *not*
+ * negotiated. For boxes without large unsigned ints mangle the
+ * lock offset by mapping the top 32 bits onto the lower 32.
+ */
- if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
- uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
- uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
- uint32 new_low = 0;
-
- if((new_low = map_lock_offset(high, low)) == 0) {
- *err = True;
- return (SMB_BIG_UINT)-1;
- }
-
- DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
- (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
- SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
- SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
- }
-
- offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
+ if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
+ uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
+ uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
+ uint32 new_low = 0;
+
+ if((new_low = map_lock_offset(high, low)) == 0) {
+ *err = True;
+ return (SMB_BIG_UINT)-1;
+ }
+
+ DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
+ (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
+ SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
+ SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
+ }
+
+ offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
#endif /* HAVE_LONGLONG */
- }
+ }
- return offset;
+ return offset;
}
/****************************************************************************
@@ -4412,13 +4625,12 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
char *data;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
BOOL err;
- BOOL my_lock_ctx = False;
NTSTATUS status;
START_PROFILE(SMBlockingX);
-
+
CHECK_FSP(fsp,conn);
-
+
data = smb_buf(inbuf);
if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
@@ -4427,21 +4639,21 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
compatible! (tridge) */
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
-
+
/* Check if this is an oplock break on a file
- we have granted an oplock on.
+ we have granted an oplock on.
*/
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
/* Client can insist on breaking to none. */
BOOL break_to_none = (oplocklevel == 0);
-
+
DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
- (unsigned int)oplocklevel, fsp->fnum ));
+ (unsigned int)oplocklevel, fsp->fnum ));
/*
* Make sure we have granted an exclusive or batch oplock on this file.
*/
-
+
if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
@@ -4458,16 +4670,16 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
if (remove_oplock(fsp, break_to_none) == False) {
DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
- fsp->fsp_name ));
+ fsp->fsp_name ));
}
-
+
/* if this is a pure oplock break request then don't send a reply */
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
- chained request. */
+ chained request. */
if(CVAL(inbuf,smb_vwv0) != 0xff)
DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
- (unsigned int)CVAL(inbuf,smb_vwv0) ));
+ (unsigned int)CVAL(inbuf,smb_vwv0) ));
END_PROFILE(SMBlockingX);
return -1;
}
@@ -4477,16 +4689,16 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
* We do this check *after* we have checked this is not a oplock break
* response message. JRA.
*/
-
+
release_level_2_oplocks_on_change(fsp);
-
+
/* Data now points at the beginning of the list
- of smb_unlkrng structs */
+ of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* There is no error code marked "stupid client bug".... :-).
*/
@@ -4496,8 +4708,8 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
}
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
- (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
-
+ (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
+
status = do_unlock(fsp,conn,lock_pid,count,offset);
if (NT_STATUS_V(status)) {
END_PROFILE(SMBlockingX);
@@ -4508,18 +4720,18 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
/* Setup the timeout in seconds. */
lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
-
+
/* Now do any requested locks */
data += ((large_file_format ? 20 : 10)*num_ulocks);
-
+
/* Data now points at the beginning of the list
- of smb_lkrng structs */
-
+ of smb_lkrng structs */
+
for(i = 0; i < (int)num_locks; i++) {
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* There is no error code marked "stupid client bug".... :-).
*/
@@ -4527,21 +4739,15 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
END_PROFILE(SMBlockingX);
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
-
+
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
- (double)offset, (double)count, (unsigned int)lock_pid,
- fsp->fsp_name, (int)lock_timeout ));
-
+ (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name,
+ (int)lock_timeout ));
+
status = do_lock_spin(fsp,conn,lock_pid, count,offset,
- ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
+ ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
+
if (NT_STATUS_V(status)) {
- /*
- * Interesting fact found by IFSTEST /t LockOverlappedTest...
- * Even if it's our own lock context, we need to wait here as
- * there may be an unlock on the way.
- * So I removed a "&& !my_lock_ctx" from the following
- * if statement. JRA.
- */
if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
@@ -4556,10 +4762,10 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
break;
}
}
-
+
/* If any of the above locks failed, then we must unlock
- all of the previous locks (X/Open spec). */
- if (i != num_locks && num_locks != 0) {
+ all of the previous locks (X/Open spec). */
+ if(i != num_locks && num_locks != 0) {
/*
* Ensure we don't do a remove on the lock that just failed,
* as under POSIX rules, if we have a lock already there, we
@@ -4569,7 +4775,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* There is no error code marked "stupid client bug".... :-).
*/
@@ -4577,7 +4783,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
END_PROFILE(SMBlockingX);
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
-
+
do_unlock(fsp,conn,lock_pid,count,offset);
}
END_PROFILE(SMBlockingX);
@@ -4585,16 +4791,18 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
}
set_message(outbuf,2,0,True);
-
+
DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
-
+ fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
+
END_PROFILE(SMBlockingX);
return chain_reply(inbuf,outbuf,length,bufsize);
}
+/* Back from the dead for OS/2..... JRA. */
+
/****************************************************************************
- Reply to a SMBreadbmpx (read block multiplex) request.
+ Reply to a SMBreadbmpx (read block multiplex) request
****************************************************************************/
int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
@@ -4621,6 +4829,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
CHECK_FSP(fsp,conn);
CHECK_READ(fsp);
+ CHECK_ERROR(fsp);
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
maxcount = SVAL(inbuf,smb_vwv3);
@@ -4635,14 +4844,14 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK, False)) {
END_PROFILE(SMBreadBmpx);
return ERROR_DOS(ERRDOS,ERRlock);
}
do {
size_t N = MIN(max_per_packet,tcount-total_read);
-
+
nread = read_file(fsp,data,startpos,N);
if (nread <= 0)
@@ -4682,7 +4891,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
outsize = set_message(outbuf,0,0,True);
if(!fsp || (fsp->conn != conn)) {
- END_PROFILE(SMBgetattrE);
+ END_PROFILE(SMBsetattrE);
return ERROR_DOS(ERRDOS,ERRbadfid);
}
@@ -4690,7 +4899,6 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
* Convert the DOS times into unix times. Ignore create
* time as UNIX can't set this.
*/
-
unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
@@ -4787,6 +4995,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
wbms = fsp->wbmpx_ptr; /* Use an existing struct */
else
wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
+
if(!wbms) {
DEBUG(0,("Out of memory in reply_readmpx\n"));
END_PROFILE(SMBwriteBmpx);
@@ -4805,11 +5014,11 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
SCVAL(outbuf,smb_com,SMBwriteBmpx);
outsize = set_message(outbuf,1,0,True);
-
+
SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten ) );
+ fsp->fnum, (int)numtowrite, (int)nwritten ) );
if (write_through && tcount==nwritten) {
/* We need to send both a primary and a secondary response */
@@ -4884,8 +5093,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
if (nwritten < (ssize_t)numtowrite) {
if(write_through) {
/* We are returning an error - we can delete the aux struct */
- if (wbms)
- free((char *)wbms);
+ SAFE_FREE(wbms);
fsp->wbmpx_ptr = NULL;
END_PROFILE(SMBwriteBs);
return(ERROR_DOS(ERRHRD,ERRdiskfull));
@@ -4904,7 +5112,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
send_response = True;
}
- free((char *)wbms);
+ SAFE_FREE(wbms);
fsp->wbmpx_ptr = NULL;
}
@@ -4936,7 +5144,8 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
return ERROR_DOS(ERRDOS,ERRbadfid);
}
- /* Do an fstat on this file */
+ /* Do an stat on this file */
+
if(fsp_stat(fsp, &sbuf)) {
END_PROFILE(SMBgetattrE);
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -4944,8 +5153,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
mode = dos_mode(conn,fsp->fsp_name,&sbuf);
- /*
- * Convert the times into dos times. Set create
+ /* Convert the times into dos times. Set create
* date to be last modify date as UNIX doesn't save
* this.
*/
@@ -4953,14 +5161,12 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
-
if (mode & aDIR) {
SIVAL(outbuf,smb_vwv6,0);
SIVAL(outbuf,smb_vwv8,0);
} else {
- uint32 allocation_size = get_allocation_size(fsp, &sbuf);
SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
- SIVAL(outbuf,smb_vwv8,allocation_size);
+ SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
}
SSVAL(outbuf,smb_vwv10, mode);
diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c
index fee71b5ec96..c93ca5c4389 100644
--- a/source/smbd/sec_ctx.c
+++ b/source/smbd/sec_ctx.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
uid/user handling
Copyright (C) Tim Potter 2000
@@ -28,7 +29,6 @@ struct sec_ctx {
int ngroups;
gid_t *groups;
NT_USER_TOKEN *token;
- PRIVILEGE_SET *privs;
};
/* A stack of security contexts. We include the current context as being
@@ -169,7 +169,7 @@ int get_current_groups(gid_t gid, int *p_ngroups, gid_t **p_groups)
(*p_ngroups) = ngroups;
(*p_groups) = groups;
- DEBUG( 3, ( "get_current_groups: user is in %u groups: ", ngroups));
+ DEBUG( 3, ( "get_current_groups: user is in %u groups: ", ngroups ) );
for (i = 0; i < ngroups; i++ ) {
DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
@@ -184,6 +184,46 @@ fail:
}
/****************************************************************************
+ Delete a SID token.
+****************************************************************************/
+
+void delete_nt_token(NT_USER_TOKEN **pptoken)
+{
+ if (*pptoken) {
+ NT_USER_TOKEN *ptoken = *pptoken;
+ SAFE_FREE( ptoken->user_sids );
+ ZERO_STRUCTP(ptoken);
+ }
+ SAFE_FREE(*pptoken);
+}
+
+/****************************************************************************
+ Duplicate a SID token.
+****************************************************************************/
+
+NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
+{
+ NT_USER_TOKEN *token;
+
+ if (!ptoken)
+ return NULL;
+
+ if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
+ return NULL;
+
+ ZERO_STRUCTP(token);
+
+ if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
+ SAFE_FREE(token);
+ return NULL;
+ }
+
+ token->num_sids = ptoken->num_sids;
+
+ return token;
+}
+
+/****************************************************************************
Initialize the groups a user belongs to.
****************************************************************************/
@@ -272,14 +312,6 @@ BOOL push_sec_ctx(void)
ctx_p->groups = NULL;
}
- init_privilege(&ctx_p->privs);
- if (! NT_STATUS_IS_OK(dup_priv_set(ctx_p->privs, sec_ctx_stack[sec_ctx_stack_ndx-1].privs))) {
- DEBUG(0, ("Out of memory on dup_priv_set() in push_sec_ctx()\n"));
- delete_nt_token(&ctx_p->token);
- destroy_privilege(&ctx_p->privs);
- return False;
- }
-
return True;
}
@@ -287,7 +319,7 @@ BOOL push_sec_ctx(void)
Set the current security context to a given user.
****************************************************************************/
-void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token, PRIVILEGE_SET *privs)
+void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
{
struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
@@ -296,8 +328,17 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
(unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx));
- debug_nt_user_token(DBGC_CLASS, 5, token);
- debug_unix_user_token(DBGC_CLASS, 5, uid, gid, ngroups, groups);
+ if (ngroups) {
+ int i;
+
+ DEBUG(3, ("%d user groups: \n", ngroups));
+ for (i = 0; i < ngroups; i++) {
+ DEBUGADD(3, ("%u ", (unsigned int)groups[i]));
+ }
+
+ DEBUG(3, ("\n"));
+ }
+
gain_root();
@@ -312,14 +353,9 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
smb_panic("DUPLICATE_TOKEN");
delete_nt_token(&ctx_p->token);
- if (ctx_p->privs)
- reset_privilege(ctx_p->privs);
- else
- init_privilege(&ctx_p->privs);
ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
ctx_p->token = dup_nt_token(token);
- dup_priv_set(ctx_p->privs, privs);
become_id(uid, gid);
@@ -333,7 +369,6 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
current_user.ngroups = ngroups;
current_user.groups = groups;
current_user.nt_user_token = ctx_p->token;
- current_user.privs = ctx_p->privs;
}
/****************************************************************************
@@ -344,7 +379,7 @@ void set_root_sec_ctx(void)
{
/* May need to worry about supplementary groups at some stage */
- set_sec_ctx(0, 0, 0, NULL, NULL, NULL);
+ set_sec_ctx(0, 0, 0, NULL, NULL);
}
/****************************************************************************
@@ -374,7 +409,6 @@ BOOL pop_sec_ctx(void)
ctx_p->ngroups = 0;
delete_nt_token(&ctx_p->token);
- destroy_privilege(&ctx_p->privs);
/* Pop back previous user */
@@ -397,7 +431,6 @@ BOOL pop_sec_ctx(void)
current_user.ngroups = prev_ctx_p->ngroups;
current_user.groups = prev_ctx_p->groups;
current_user.nt_user_token = prev_ctx_p->token;
- current_user.privs = prev_ctx_p->privs;
DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
(unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx));
@@ -430,7 +463,6 @@ void init_sec_ctx(void)
get_current_groups(ctx_p->gid, &ctx_p->ngroups, &ctx_p->groups);
ctx_p->token = NULL; /* Maps to guest user. */
- ctx_p->privs = NULL;
/* Initialise current_user global */
@@ -445,5 +477,4 @@ void init_sec_ctx(void)
current_user.conn = NULL;
current_user.vuid = UID_FIELD_INVALID;
current_user.nt_user_token = NULL;
- current_user.privs = NULL;
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 53d07fd905c..01b5709f55b 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -1,9 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Main SMB server routines
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Martin Pool 2002
- Copyright (C) Jelmer Vernooij 2002-2003
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,7 +21,11 @@
#include "includes.h"
-static int am_parent = 1;
+pstring servicesf = CONFIGFILE;
+extern fstring global_myworkgroup;
+extern pstring global_myname;
+
+int am_parent = 1;
/* the last message the was processed */
int last_message = -1;
@@ -31,13 +34,13 @@ int last_message = -1;
#define LAST_MESSAGE() smb_fn_name(last_message)
extern pstring user_socket_options;
-extern SIG_ATOMIC_T got_sig_term;
-extern SIG_ATOMIC_T reload_after_sighup;
#ifdef WITH_DFS
extern int dcelogin_atmost_once;
#endif /* WITH_DFS */
+extern fstring remote_machine;
+
/* really we should have a top level context structure that has the
client file descriptor as an element. That would require a major rewrite :(
@@ -51,7 +54,7 @@ int smbd_server_fd(void)
return server_fd;
}
-static void smbd_set_server_fd(int fd)
+void smbd_set_server_fd(int fd)
{
server_fd = fd;
client_setfd(fd);
@@ -61,6 +64,8 @@ static void smbd_set_server_fd(int fd)
Terminate signal.
****************************************************************************/
+SIG_ATOMIC_T got_sig_term;
+
static void sig_term(void)
{
got_sig_term = 1;
@@ -71,6 +76,8 @@ static void sig_term(void)
Catch a sighup.
****************************************************************************/
+SIG_ATOMIC_T reload_after_sighup;
+
static void sig_hup(int sig)
{
reload_after_sighup = 1;
@@ -83,36 +90,8 @@ static void sig_hup(int sig)
static void killkids(void)
{
- if(am_parent) kill(0,SIGTERM);
-}
-
-/****************************************************************************
- Process a sam sync message - not sure whether to do this here or
- somewhere else.
-****************************************************************************/
-
-static void msg_sam_sync(int UNUSED(msg_type), pid_t UNUSED(pid),
- void *UNUSED(buf), size_t UNUSED(len))
-{
- DEBUG(10, ("** sam sync message received, ignoring\n"));
-}
-
-/****************************************************************************
- Process a sam sync replicate message - not sure whether to do this here or
- somewhere else.
-****************************************************************************/
-
-static void msg_sam_repl(int msg_type, pid_t pid, void *buf, size_t len)
-{
- uint32 low_serial;
-
- if (len != sizeof(uint32))
- return;
-
- low_serial = *((uint32 *)buf);
-
- DEBUG(3, ("received sam replication message, serial = 0x%04x\n",
- low_serial));
+ if(am_parent)
+ kill(0,SIGTERM);
}
/****************************************************************************
@@ -127,25 +106,19 @@ static BOOL open_sockets_inetd(void)
smbd_set_server_fd(dup(0));
/* close our standard file descriptors */
- close_low_fds(False); /* Don't close stderr */
+ close_low_fds();
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
+ set_socket_options(smbd_server_fd(),user_socket_options);
return True;
}
-static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
-{
- exit_server("Got a SHUTDOWN message");
-}
-
-
/****************************************************************************
Have we reached the process limit ?
****************************************************************************/
-static BOOL allowable_number_of_smbd_processes(void)
+BOOL allowable_number_of_smbd_processes(void)
{
int max_processes = lp_max_smbd_processes();
@@ -179,15 +152,13 @@ static BOOL allowable_number_of_smbd_processes(void)
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
+static BOOL open_sockets(BOOL is_daemon,BOOL interactive, int port)
{
int num_interfaces = iface_count();
- int num_sockets = 0;
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
int i;
- char *ports;
if (!is_daemon) {
return open_sockets_inetd();
@@ -206,119 +177,73 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
/* Stop zombies */
CatchChild();
-
+
+
FD_ZERO(&listen_set);
- /* use a reasonable default set of ports - listing on 445 and 139 */
- if (!smb_ports) {
- ports = lp_smb_ports();
- if (!ports || !*ports) {
- ports = smb_xstrdup(SMB_PORTS);
- } else {
- ports = smb_xstrdup(ports);
- }
- } else {
- ports = smb_xstrdup(smb_ports);
- }
-
- if (lp_interfaces() && lp_bind_interfaces_only()) {
+ if(lp_interfaces() && lp_bind_interfaces_only()) {
/* We have been given an interfaces line, and been
told to only bind to those interfaces. Create a
socket per interface and bind to only these.
*/
+ if(num_interfaces > FD_SETSIZE) {
+ DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
+max can be %d\n",
+ num_interfaces, FD_SETSIZE));
+ return False;
+ }
+
/* Now open a listen socket for each of the
interfaces. */
for(i = 0; i < num_interfaces; i++) {
struct in_addr *ifip = iface_n_ip(i);
- fstring tok;
- const char *ptr;
-
+
if(ifip == NULL) {
- DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+ DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
continue;
}
+ s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+ if(s == -1)
+ return False;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- FD_SET(s,&listen_set);
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n",strerror(errno)));
+ close(s);
+ return False;
}
+ FD_SET(s,&listen_set);
}
} else {
/* Just bind to 0.0.0.0 - accept connections
from anywhere. */
-
- fstring tok;
- const char *ptr;
-
num_interfaces = 1;
- for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
+ /* open an incoming socket */
+ s = open_socket_in(SOCK_STREAM, port, 0,
+ interpret_addr(lp_socket_address()),True);
+ if (s == -1)
+ return(False);
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return False;
- }
-
- fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
-
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
- }
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("open_sockets: listen: %s\n",
+ strerror(errno)));
+ close(s);
+ return False;
}
+
+ fd_listenset[0] = s;
+ FD_SET(s,&listen_set);
}
- SAFE_FREE(ports);
-
- /* Listen to messages */
-
- message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
- message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
- message_register(MSG_SHUTDOWN, msg_exit_server);
-
/* now accept incoming connections - forking a new process
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
@@ -344,10 +269,11 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
/* check for sighup processing */
if (reload_after_sighup) {
+ DEBUG(0,("Got SIGHUP\n"));
change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(False);
- reload_after_sighup = 0;
+ reload_after_sighup = False;
}
continue;
@@ -363,7 +289,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
socklen_t in_addrlen = sizeof(addr);
s = -1;
- for(i = 0; i < num_sockets; i++) {
+ for(i = 0; i < num_interfaces; i++) {
if(FD_ISSET(fd_listenset[i],&lfds)) {
s = fd_listenset[i];
/* Clear this so we don't look
@@ -379,46 +305,36 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
continue;
if (smbd_server_fd() == -1) {
- DEBUG(0,("open_sockets_smbd: accept: %s\n",
+ DEBUG(0,("open_sockets: accept: %s\n",
strerror(errno)));
continue;
}
-
- /* Ensure child is set to blocking mode */
- set_blocking(smbd_server_fd(),True);
-
+
if (smbd_server_fd() != -1 && interactive)
return True;
-
+
if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {
/* Child code ... */
/* close the listening socket(s) */
- for(i = 0; i < num_sockets; i++)
+ for(i = 0; i < num_interfaces; i++)
close(fd_listenset[i]);
/* close our standard file
descriptors */
- close_low_fds(False);
+ close_low_fds();
am_parent = 0;
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(),user_socket_options);
- /* this is needed so that we get decent entries
- in smbstatus for port 445 connects */
- set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
-
/* Reset global variables in util.c so
that client substitutions will be
done correctly in the process. */
reset_globals_after_fork();
- /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
- if (tdb_reopen_all() == -1) {
- DEBUG(0,("tdb_reopen_all failed.\n"));
- smb_panic("tdb_reopen_all failed.");
- }
+ /* tdb needs special fork handling */
+ tdb_reopen_all();
return True;
}
@@ -459,7 +375,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
/****************************************************************************
Reload the services file.
-**************************************************************************/
+ **************************************************************************/
BOOL reload_services(BOOL test)
{
@@ -468,9 +384,8 @@ BOOL reload_services(BOOL test)
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
- if (file_exist(fname, NULL) &&
- !strcsequal(fname, dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE, fname);
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
test = False;
}
}
@@ -482,7 +397,7 @@ BOOL reload_services(BOOL test)
lp_killunused(conn_snum_used);
- ret = lp_load(dyn_CONFIGFILE, False, False, True);
+ ret = lp_load(servicesf,False,False,True);
load_printers();
@@ -497,7 +412,7 @@ BOOL reload_services(BOOL test)
{
if (smbd_server_fd() != -1) {
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
+ set_socket_options(smbd_server_fd(),user_socket_options);
}
}
@@ -510,18 +425,17 @@ BOOL reload_services(BOOL test)
return(ret);
}
-
#if DUMP_CORE
/*******************************************************************
-prepare to dump a core file - carefully!
+ Prepare to dump a core file - carefully !
********************************************************************/
+
static BOOL dump_core(void)
{
char *p;
pstring dname;
-
pstrcpy(dname,lp_logfile());
- if ((p=strrchr_m(dname,'/'))) *p=0;
+ if ((p=strrchr(dname,'/'))) *p=0;
pstrcat(dname,"/corefiles");
mkdir(dname,0700);
sys_chown(dname,getuid(),getgid());
@@ -544,13 +458,43 @@ static BOOL dump_core(void)
#endif
- DEBUG(0,("Dumping core in %s\n", dname));
+ DEBUG(0,("Dumping core in %s\n",dname));
abort();
return(True);
}
#endif
/****************************************************************************
+update the current smbd process count
+****************************************************************************/
+
+static BOOL process_count_update_successful = False;
+
+int32 increment_smbd_process_count(void)
+{
+ int32 total_smbds;
+
+ if (lp_max_smbd_processes()) {
+ total_smbds = 0;
+ if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
+ return 1;
+ process_count_update_successful = True;
+ return total_smbds + 1;
+ }
+ return 1;
+}
+
+static void decrement_smbd_process_count(void)
+{
+ int32 total_smbds;
+
+ if (lp_max_smbd_processes() && process_count_update_successful) {
+ total_smbds = 1;
+ tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
+ }
+}
+
+/****************************************************************************
Exit the server.
****************************************************************************/
@@ -558,30 +502,21 @@ void exit_server(const char *reason)
{
static int firsttime=1;
extern char *last_inbuf;
- extern struct auth_context *negprot_global_auth_context;
- if (!firsttime)
- exit(0);
+
+ if (!firsttime) exit(0);
firsttime = 0;
change_to_root_user();
DEBUG(2,("Closing connections\n"));
- if (negprot_global_auth_context) {
- (negprot_global_auth_context->free)(&negprot_global_auth_context);
- }
-
conn_close_all();
invalidate_all_vuids();
- print_notify_send_messages(3); /* 3 second timeout. */
-
- /* run all registered exit events */
- smb_run_exit_events();
-
/* delete our entry in the connections database. */
- yield_connection(NULL,"");
+ if (lp_status(-1))
+ yield_connection(NULL,"");
respond_to_all_remaining_local_messages();
decrement_smbd_process_count();
@@ -606,7 +541,6 @@ void exit_server(const char *reason)
}
locking_end();
- printing_end();
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
exit(0);
@@ -616,15 +550,22 @@ void exit_server(const char *reason)
Initialise connect, service and file structs.
****************************************************************************/
-static BOOL init_structs(void )
+static void init_structs(void )
{
/*
* Set the machine NETBIOS name if not already
* set from the config file.
*/
- if (!init_names())
- return False;
+ if (!*global_myname) {
+ char *p;
+ fstrcpy( global_myname, myhostname() );
+ p = strchr( global_myname, '.' );
+ if (p)
+ *p = 0;
+ }
+
+ strupper( global_myname );
conn_init();
@@ -636,59 +577,148 @@ static BOOL init_structs(void )
init_dptrs();
secrets_init();
+}
- return True;
+/****************************************************************************
+ Keep track of the number of running smbd's. This functionality is used to
+ 'hard' limit Samba overhead on resource constrained systems.
+ This function is only called once per smbd.
+****************************************************************************/
+
+static BOOL smbd_process_limit(void)
+{
+ int32 total_smbds;
+
+ if (lp_max_smbd_processes()) {
+
+ /* Always add one to the smbd process count, as exit_server() always
+ * subtracts one.
+ */
+
+ if (!conn_tdb_ctx()) {
+ DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
+set. Ignoring max smbd restriction.\n"));
+ return False;
+ }
+
+ total_smbds = increment_smbd_process_count();
+ return total_smbds > lp_max_smbd_processes();
+ }
+ else
+ return False;
}
+
/****************************************************************************
- main program.
+ Usage on the program.
****************************************************************************/
-/* Declare prototype for build_options() to avoid having to run it through
- mkproto.h. Mixing $(builddir) and $(srcdir) source files in the current
- prototype generation system is too complicated. */
+static void usage(char *pname)
+{
+
+ printf("Usage: %s [-DaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+ printf(" [-O socket options] [-s services file]\n");
+ printf("\t-D Become a daemon (default)\n");
+ printf("\t-a Append to log file (default)\n");
+ printf("\t-i Run interactive (not a daemon)\n");
+ printf("\t-o Overwrite log file, don't append\n");
+ printf("\t-h Print usage\n");
+ printf("\t-? Print usage\n");
+ printf("\t-V Print version\n");
+ printf("\t-d debuglevel Set the debuglevel\n");
+ printf("\t-l log basename. Basename for log/debug files\n");
+ printf("\t-p port Listen on the specified port\n");
+ printf("\t-O socket options Socket options\n");
+ printf("\t-s services file. Filename of services file\n");
+ printf("\n");
+}
-void build_options(BOOL screen);
+/****************************************************************************
+ main program.
+****************************************************************************/
- int main(int argc,const char *argv[])
+ int main(int argc,char *argv[])
{
+ extern BOOL append_log;
+ extern BOOL AllowDebugChange;
/* shall I run as a daemon */
- static BOOL is_daemon = False;
- static BOOL interactive = False;
- static BOOL Fork = True;
- static BOOL log_stdout = False;
- static char *ports = NULL;
+ BOOL is_daemon = False;
+ BOOL interactive = False;
+ BOOL specified_logfile = False;
+ int port = SMB_PORT;
int opt;
- poptContext pc;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
- {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
- {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
- {"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
- POPT_COMMON_SAMBA
- { NULL }
- };
-
+ extern char *optarg;
+ pstring logfile;
+
#ifdef HAVE_SET_AUTH_PARAMETERS
set_auth_parameters(argc,argv);
#endif
- pc = poptGetContext("smbd", argc, argv, long_options, 0);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
+ /* this is for people who can't start the program correctly */
+ while (argc > 1 && (*argv[1] != '-')) {
+ argv++;
+ argc--;
+ }
+
+ while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dip:h?Vaof:")) )
switch (opt) {
- case 'b':
- build_options(True); /* Display output to screen as well as debug */
+ case 'O':
+ pstrcpy(user_socket_options,optarg);
+ break;
+
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+
+ case 'l':
+ specified_logfile = True;
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", optarg);
+ lp_set_logfile(logfile);
+ break;
+
+ case 'a':
+ append_log = True;
+ break;
+
+ case 'o':
+ append_log = False;
+ break;
+
+ case 'D':
+ is_daemon = True;
+ break;
+
+ case 'i':
+ interactive = True;
+ break;
+
+ case 'd':
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ AllowDebugChange = False;
+ break;
+
+ case 'p':
+ port = atoi(optarg);
+ break;
+
+ case 'h':
+ case '?':
+ usage(argv[0]);
exit(0);
break;
- }
- }
- poptFreeContext(pc);
+ case 'V':
+ printf("Version %s\n",VERSION);
+ exit(0);
+ break;
+ default:
+ DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
+ usage(argv[0]);
+ exit(1);
+ }
#ifdef HAVE_SETLUID
/* needed for SecureWare on SCO */
@@ -697,21 +727,24 @@ void build_options(BOOL screen);
sec_init();
- load_case_tables();
+ append_log = True;
- set_remote_machine_name("smbd", False);
+ TimeInit();
- if (interactive) {
- Fork = False;
- log_stdout = True;
+ if(!specified_logfile) {
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", LOGFILEBASE);
+ lp_set_logfile(logfile);
}
- if (log_stdout && Fork) {
- DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
- exit(1);
- }
+ pstrcpy(remote_machine, "smbd");
- setup_logging(argv[0],log_stdout);
+ /*
+ * Only want interactive behaviour if the user has not also
+ * specified a logfile dir etc.
+ */
+ setup_logging(argv[0],interactive & !specified_logfile);
+
+ charset_initialise();
/* we want to re-seed early to prevent time delays causing
client problems at a later date. (tridge) */
@@ -726,7 +759,7 @@ void build_options(BOOL screen);
fault_setup((void (*)(void *))exit_server);
CatchSignal(SIGTERM , SIGNAL_CAST sig_term);
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-
+
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
@@ -751,18 +784,16 @@ void build_options(BOOL screen);
umask(0);
init_sec_ctx();
+ init_conn_ctx();
reopen_logs();
- DEBUG(0,( "smbd version %s started.\n", SAMBA_VERSION_STRING));
- DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
+ DEBUG(0,( "smbd version %s started.\n", VERSION));
+ DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2003\n"));
DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
(int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
- /* Output the build options to the debug log */
- build_options(False);
-
if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
exit(1);
@@ -776,13 +807,26 @@ void build_options(BOOL screen);
return(-1);
init_structs();
-
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
- DEBUG(0,("ERROR: failed to setup profiling\n"));
+ DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
return -1;
}
-#endif
+#endif /* WITH_PROFILE */
+
+#ifdef WITH_SSL
+ {
+ extern BOOL sslEnabled;
+ sslEnabled = lp_ssl_enabled();
+ if(sslEnabled)
+ sslutil_init(True);
+ }
+#endif /* WITH_SSL */
+
+ codepage_initialise(lp_client_code_page());
+
+ fstrcpy(global_myworkgroup, lp_workgroup());
DEBUG(3,( "loaded services\n"));
@@ -800,7 +844,7 @@ void build_options(BOOL screen);
if (is_daemon && !interactive) {
DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
+ become_daemon();
}
#if HAVE_SETPGID
@@ -818,70 +862,44 @@ void build_options(BOOL screen);
if (is_daemon)
pidfile_create("smbd");
- /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
if (!message_init())
exit(1);
- if (!session_init())
- exit(1);
+ /* Setup the main smbd so that we can get messages. */
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
- if (conn_tdb_ctx() == NULL)
- exit(1);
+ /* Attempt to migrate from an old 2.0.x machine account file. */
+ if (!migrate_from_old_password_file(global_myworkgroup))
+ DEBUG(0,("Failed to migrate from old MAC file.\n"));
- if (!locking_init(0))
+ if(!pdb_generate_sam_sid()) {
+ DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
exit(1);
+ }
- if (!share_info_db_init())
+ if (!open_sockets(is_daemon,interactive,port))
exit(1);
- namecache_enable();
+ /*
+ * Everything after this point is run after the fork().
+ */
- if (!init_registry())
+ if (!locking_init(0))
exit(1);
if (!print_backend_init())
exit(1);
- /* Setup the main smbd so that we can get messages. */
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
-
- /*
- DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD
- THIS *killed* LOTS OF BUILD FARM MACHINES. IT CREATED HUNDREDS OF
- smbd PROCESSES THAT NEVER DIE
- start_background_queue();
- */
-
- if (!open_sockets_smbd(is_daemon, interactive, ports))
+ if (!share_info_db_init())
exit(1);
- /*
- * everything after this point is run after the fork()
- */
-
- /* Initialise the password backed before the global_sam_sid
- to ensure that we fetch from ldap before we make a domain sid up */
-
if(!initialize_password_db(False))
exit(1);
- if(!get_global_sam_sid()) {
- DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
- exit(1);
- }
-
- static_init_rpc;
-
- init_modules();
-
/* possibly reload the services file. */
reload_services(True);
- if (!init_account_policy()) {
- DEBUG(0,("Could not open account policy tdb.\n"));
- exit(1);
- }
-
if (*lp_rootdir()) {
if (sys_chroot(lp_rootdir()) == 0)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));
@@ -890,20 +908,19 @@ void build_options(BOOL screen);
/* Setup oplocks */
if (!init_oplocks())
exit(1);
-
+
/* Setup change notify */
if (!init_change_notify())
exit(1);
- /* re-initialise the timezone */
- TimeInit();
-
- /* register our message handlers */
- message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
-
+ if ( smbd_process_limit() ) {
+ DEBUG( 1, ( "Connection denied from %s\n",
+ client_addr() ) );
+ exit_server("connection denied");
+ }
+
smbd_process();
- namecache_shutdown();
exit_server("normal exit");
return(0);
}
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 9f4b56d8283..05d29d544ab 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
service (connection) opening and closing
Copyright (C) Andrew Tridgell 1992-1998
@@ -20,8 +21,18 @@
#include "includes.h"
+#define CHECK_PATH_ON_TCONX 1
+
extern struct timeval smb_last_time;
+extern int case_default;
+extern BOOL case_preserve;
+extern BOOL short_case_preserve;
+extern BOOL case_mangle;
+extern BOOL case_sensitive;
+extern BOOL use_mangled_map;
+extern fstring remote_machine;
extern userdom_struct current_user_info;
+extern fstring remote_machine;
/****************************************************************************
@@ -30,7 +41,6 @@ extern userdom_struct current_user_info;
BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
{
- extern char magic_char;
static connection_struct *last_conn;
int snum;
@@ -56,7 +66,12 @@ BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
last_conn = conn;
- magic_char = lp_magicchar(snum);
+ case_default = lp_defaultcase(snum);
+ case_preserve = lp_preservecase(snum);
+ short_case_preserve = lp_shortpreservecase(snum);
+ case_mangle = lp_casemangle(snum);
+ case_sensitive = lp_casesensitive(snum);
+ use_mangled_map = (*lp_mangled_map(snum) ? True:False);
return(True);
}
@@ -64,9 +79,12 @@ BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
Add a home service. Returns the new service number or -1 if fail.
****************************************************************************/
-int add_home_service(const char *service, const char *username, const char *homedir)
+int add_home_service(char *service, char *homedir)
{
int iHomeService;
+ int iService;
+ fstring new_service;
+ char *usr_p = NULL;
if (!service || !homedir)
return -1;
@@ -81,263 +99,294 @@ int add_home_service(const char *service, const char *username, const char *home
* include any macros.
*/
- {
- const char *p = strchr(service,*lp_winbind_separator());
+ fstrcpy(new_service, service);
- /* We only want the 'user' part of the string */
- if (p) {
- service = p + 1;
- }
- }
+ if ((usr_p = strchr(service,*lp_winbind_separator())) != NULL)
+ fstrcpy(new_service, usr_p+1);
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
-
- return lp_servicenumber(service);
+ lp_add_home(new_service,iHomeService,homedir);
+ iService = lp_servicenumber(new_service);
+ return iService;
}
+/****************************************************************************
+ Find a service entry. service is always in dos codepage.
+****************************************************************************/
-/**
- * Find a service entry.
- *
- * @param service is modified (to canonical form??)
- **/
-
-int find_service(fstring service)
+int find_service(char *service)
{
- int iService;
-
- all_string_sub(service,"\\","/",0);
+ int iService;
+
+ all_string_sub(service,"\\","/",0);
+
+ iService = lp_servicenumber(service);
+
+ /* now handle the special case of a home directory */
+ if (iService < 0)
+ {
+ char *phome_dir = get_user_service_home_dir(service);
+
+ if(!phome_dir)
+ {
+ /*
+ * Try mapping the servicename, it may
+ * be a Windows to unix mapped user name.
+ */
+ if(map_username(service))
+ phome_dir = get_user_service_home_dir(service);
+ }
+
+ DEBUG(3,("checking for home directory %s gave %s\n",service,
+ phome_dir?phome_dir:"(NULL)"));
+
+ iService = add_home_service(service,phome_dir);
+ }
+
+ /* If we still don't have a service, attempt to add it as a printer. */
+ if (iService < 0)
+ {
+ int iPrinterService;
+
+ if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
+ {
+ char *pszTemp;
+
+ DEBUG(3,("checking whether %s is a valid printer name...\n", service));
+ pszTemp = PRINTCAP;
+ if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
+ {
+ DEBUG(3,("%s is a valid printer name\n", service));
+ DEBUG(3,("adding %s as a printer service\n", service));
+ lp_add_printer(service,iPrinterService);
+ iService = lp_servicenumber(service);
+ if (iService < 0)
+ DEBUG(0,("failed to add %s as a printer service!\n", service));
+ }
+ else
+ DEBUG(3,("%s is not a valid printer name\n", service));
+ }
+ }
+
+ /* Check for default vfs service? Unsure whether to implement this */
+ if (iService < 0)
+ {
+ }
+
+ /* just possibly it's a default service? */
+ if (iService < 0)
+ {
+ char *pdefservice = lp_defaultservice();
+ if (pdefservice && *pdefservice &&
+ !strequal(pdefservice,service) &&
+ !strstr(service,".."))
+ {
+ /*
+ * We need to do a local copy here as lp_defaultservice()
+ * returns one of the rotating lp_string buffers that
+ * could get overwritten by the recursive find_service() call
+ * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
+ */
+ pstring defservice;
+ pstrcpy(defservice, pdefservice);
+ iService = find_service(defservice);
+ if (iService >= 0)
+ {
+ all_string_sub(service,"_","/",0);
+ iService = lp_add_service(service,iService);
+ }
+ }
+ }
+
+ if (iService >= 0)
+ if (!VALID_SNUM(iService))
+ {
+ DEBUG(0,("Invalid snum %d for %s\n",iService,service));
+ iService = -1;
+ }
+
+ if (iService < 0)
+ DEBUG(3,("find_service() failed to find service %s\n", service));
+
+ return (iService);
+}
- iService = lp_servicenumber(service);
- /* now handle the special case of a home directory */
- if (iService < 0) {
- char *phome_dir = get_user_home_dir(service);
+/****************************************************************************
+ Make a connection to a service. This function is designed to be called
+ AS ROOT and will return to being root on exit ! Modified current_user conn
+ and vuid elements.
+****************************************************************************/
- if(!phome_dir) {
- /*
- * Try mapping the servicename, it may
- * be a Windows to unix mapped user name.
- */
- if(map_username(service))
- phome_dir = get_user_home_dir(service);
- }
+connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode)
+{
+ int snum;
+ struct passwd *pass = NULL;
+ BOOL guest = False;
+ BOOL force = False;
+ connection_struct *conn;
+#if !CHECK_PATH_ON_TCONX
+ struct stat st;
+#endif
+ uid_t euid;
+ int ret;
- DEBUG(3,("checking for home directory %s gave %s\n",service,
- phome_dir?phome_dir:"(NULL)"));
+ /* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
- iService = add_home_service(service,service /* 'username' */, phome_dir);
+ if (!non_root_mode() && ((euid = geteuid()) != 0)) {
+ DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid ));
+ smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
}
- /* If we still don't have a service, attempt to add it as a printer. */
- if (iService < 0) {
- int iPrinterService;
-
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
- char *pszTemp;
+ strlower(service);
- DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- pszTemp = lp_printcapname();
- if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
- DEBUG(3,("%s is a valid printer name\n", service));
- DEBUG(3,("adding %s as a printer service\n", service));
- lp_add_printer(service, iPrinterService);
- iService = lp_servicenumber(service);
- if (iService < 0) {
- DEBUG(0,("failed to add %s as a printer service!\n", service));
- }
- } else {
- DEBUG(3,("%s is not a valid printer name\n", service));
- }
+ snum = find_service(service);
+ if (snum < 0) {
+ if (strequal(service,"IPC$") || strequal(service,"ADMIN$")) {
+ DEBUG(3,("refusing IPC connection\n"));
+ *ecode = ERRnoipc;
+ return NULL;
}
- }
- /* Check for default vfs service? Unsure whether to implement this */
- if (iService < 0) {
+ DEBUG(0,("%s (%s) couldn't find service %s\n",
+ remote_machine, client_addr(), service));
+ *ecode = ERRnosuchshare;
+ return NULL;
}
- /* just possibly it's a default service? */
- if (iService < 0) {
- char *pdefservice = lp_defaultservice();
- if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
- /*
- * We need to do a local copy here as lp_defaultservice()
- * returns one of the rotating lp_string buffers that
- * could get overwritten by the recursive find_service() call
- * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
- */
- pstring defservice;
- pstrcpy(defservice, pdefservice);
- iService = find_service(defservice);
- if (iService >= 0) {
- all_string_sub(service, "_","/",0);
- iService = lp_add_service(service, iService);
- }
+ if (strequal(service,HOMES_NAME)) {
+ if (*user && Get_Pwnam(user,True)) {
+ fstring dos_username;
+ fstrcpy(dos_username, user);
+ unix_to_dos(dos_username);
+ return(make_connection(dos_username,user,password,
+ pwlen,dev,vuid,ecode));
}
- }
- if (iService >= 0) {
- if (!VALID_SNUM(iService)) {
- DEBUG(0,("Invalid snum %d for %s\n",iService, service));
- iService = -1;
+ if(lp_security() != SEC_SHARE) {
+ if (validated_username(vuid)) {
+ fstring dos_username;
+ fstrcpy(user,validated_username(vuid));
+ fstrcpy(dos_username, user);
+ unix_to_dos(dos_username);
+ return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
+ }
+ } else {
+ /* Security = share. Try with current_user_info.smb_name
+ * as the username. */
+ if(*current_user_info.smb_name) {
+ fstring dos_username;
+ fstrcpy(user,current_user_info.smb_name);
+ fstrcpy(dos_username, user);
+ unix_to_dos(dos_username);
+ return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
+ }
}
}
- if (iService < 0)
- DEBUG(3,("find_service() failed to find service %s\n", service));
-
- return (iService);
-}
-
-
-/****************************************************************************
- do some basic sainity checks on the share.
- This function modifies dev, ecode.
-****************************************************************************/
-
-static NTSTATUS share_sanity_checks(int snum, fstring dev)
-{
-
if (!lp_snum_ok(snum) ||
!check_access(smbd_server_fd(),
lp_hostsallow(snum), lp_hostsdeny(snum))) {
- return NT_STATUS_ACCESS_DENIED;
+ *ecode = ERRaccess;
+ return NULL;
}
- if (dev[0] == '?' || !dev[0]) {
+ /* you can only connect to the IPC$ service as an ipc device */
+ if (strequal(service,"IPC$") || strequal(service,"ADMIN$"))
+ pstrcpy(dev,"IPC");
+
+ if (*dev == '?' || !*dev) {
if (lp_print_ok(snum)) {
- fstrcpy(dev,"LPT1:");
- } else if (strequal(lp_fstype(snum), "IPC")) {
- fstrcpy(dev, "IPC");
+ pstrcpy(dev,"LPT1:");
} else {
- fstrcpy(dev,"A:");
+ pstrcpy(dev,"A:");
}
}
- strupper_m(dev);
-
- if (lp_print_ok(snum)) {
- if (!strequal(dev, "LPT1:")) {
- return NT_STATUS_BAD_DEVICE_TYPE;
- }
- } else if (strequal(lp_fstype(snum), "IPC")) {
- if (!strequal(dev, "IPC")) {
- return NT_STATUS_BAD_DEVICE_TYPE;
- }
- } else if (!strequal(dev, "A:")) {
- return NT_STATUS_BAD_DEVICE_TYPE;
+ /* if the request is as a printer and you can't print then refuse */
+ strupper(dev);
+ if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
+ DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
+ *ecode = ERRinvdevice;
+ return NULL;
}
/* Behave as a printer if we are supposed to */
if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) {
- fstrcpy(dev, "LPT1:");
+ pstrcpy(dev, "LPT1:");
}
- return NT_STATUS_OK;
-}
+ /* lowercase the user name */
+ strlower(user);
-/****************************************************************************
- Make a connection, given the snum to connect to, and the vuser of the
- connecting user if appropriate.
-****************************************************************************/
-
-static connection_struct *make_connection_snum(int snum, user_struct *vuser,
- DATA_BLOB password,
- const char *pdev, NTSTATUS *status)
-{
- struct passwd *pass = NULL;
- BOOL guest = False;
- connection_struct *conn;
- struct stat st;
- fstring user;
- fstring dev;
+ /* add it as a possible user name if we
+ are in share mode security */
+ if (lp_security() == SEC_SHARE) {
+ add_session_user(service);
+ }
- *user = 0;
- fstrcpy(dev, pdev);
- if (NT_STATUS_IS_ERR(*status = share_sanity_checks(snum, dev))) {
+ /* shall we let them in? */
+ if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) {
+ DEBUG( 2, ( "Invalid username/password for %s [%s]\n", service, user ) );
+ *ecode = ERRbadpw;
return NULL;
- }
-
+ }
+
+ add_session_user(user);
+
conn = conn_new();
if (!conn) {
DEBUG(0,("Couldn't find free connection.\n"));
- *status = NT_STATUS_INSUFFICIENT_RESOURCES;
+ *ecode = ERRnoresource;
return NULL;
}
- if (lp_guest_only(snum)) {
- const char *guestname = lp_guestaccount();
- guest = True;
- pass = getpwnam_alloc(guestname);
- if (!pass) {
- DEBUG(0,("make_connection_snum: Invalid guest account %s??\n",guestname));
- conn_free(conn);
- *status = NT_STATUS_NO_SUCH_USER;
- return NULL;
- }
- fstrcpy(user,pass->pw_name);
- conn->force_user = True;
- conn->uid = pass->pw_uid;
- conn->gid = pass->pw_gid;
- string_set(&conn->user,pass->pw_name);
- passwd_free(&pass);
- DEBUG(3,("Guest only user %s\n",user));
- } else if (vuser) {
- if (vuser->guest) {
- if (!lp_guest_ok(snum)) {
- DEBUG(2, ("guest user (from session setup) not permitted to access this share (%s)\n", lp_servicename(snum)));
- conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
- return NULL;
- }
- } else {
- if (!user_ok(vuser->user.unix_name, snum, vuser->groups, vuser->n_groups)) {
- DEBUG(2, ("user '%s' (from session setup) not permitted to access this share (%s)\n", vuser->user.unix_name, lp_servicename(snum)));
- conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
- return NULL;
- }
- }
- conn->vuid = vuser->vuid;
- conn->uid = vuser->uid;
- conn->gid = vuser->gid;
- string_set(&conn->user,vuser->user.unix_name);
- fstrcpy(user,vuser->user.unix_name);
- guest = vuser->guest;
- } else if (lp_security() == SEC_SHARE) {
- /* add it as a possible user name if we
- are in share mode security */
- add_session_user(lp_servicename(snum));
- /* shall we let them in? */
- if (!authorise_login(snum,user,password,&guest)) {
- DEBUG( 2, ( "Invalid username/password for [%s]\n",
- lp_servicename(snum)) );
- conn_free(conn);
- *status = NT_STATUS_WRONG_PASSWORD;
- return NULL;
- }
- pass = Get_Pwnam(user);
- conn->force_user = True;
- conn->uid = pass->pw_uid;
- conn->gid = pass->pw_gid;
- string_set(&conn->user, pass->pw_name);
- fstrcpy(user, pass->pw_name);
-
- } else {
- DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
+ /* find out some info about the user */
+ pass = smb_getpwnam(user,True);
+
+ if (pass == NULL) {
+ DEBUG(0,( "Couldn't find account %s\n",user));
+ *ecode = ERRbaduid;
conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
return NULL;
}
- add_session_user(user);
+ conn->read_only = lp_readonly(snum);
+ DEBUG(10,("make_connection: share is set %s.\n", conn->read_only ? "read only" : "writable" ));
+
+ {
+ pstring list;
+ StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
+ pstring_sub(list,"%S",service);
+
+ if (user_in_list(user,list)) {
+ DEBUG(10,("make_connection: user in read list makes share read only\n"));
+ conn->read_only = True;
+ }
+
+ StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
+ pstring_sub(list,"%S",service);
+
+ if (user_in_list(user,list)) {
+ DEBUG(10,("make_connection: user in read list makes share writable.\n"));
+ conn->read_only = False;
+ }
+ }
- safe_strcpy(conn->client_address, client_addr(),
- sizeof(conn->client_address)-1);
+ /* Admin user check */
+
+ if (user_in_list(user,lp_admin_users(snum)) ) {
+ conn->admin_user = True;
+ DEBUG(0,("make_connection: %s logged in as admin user (root privileges)\n",user));
+ } else
+ conn->admin_user = False;
+
+ conn->force_user = force;
+ conn->vuid = vuid;
+ conn->uid = pass->pw_uid;
+ conn->gid = pass->pw_gid;
+ safe_strcpy(conn->client_address, client_addr(), sizeof(conn->client_address)-1);
conn->num_files_open = 0;
conn->lastused = time(NULL);
conn->service = snum;
@@ -345,26 +394,16 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
conn->printer = (strncmp(dev,"LPT",3) == 0);
conn->ipc = ((strncmp(dev,"IPC",3) == 0) || strequal(dev,"ADMIN$"));
conn->dirptr = NULL;
-
- /* Case options for the share. */
- conn->case_sensitive = lp_casesensitive(snum);
- conn->case_preserve = lp_preservecase(snum);
- conn->short_case_preserve = lp_shortpreservecase(snum);
-
conn->veto_list = NULL;
conn->hide_list = NULL;
conn->veto_oplock_list = NULL;
string_set(&conn->dirpath,"");
string_set(&conn->user,user);
conn->nt_user_token = NULL;
- conn->privs = NULL;
-
- conn->read_only = lp_readonly(conn->service);
- conn->admin_user = False;
-
+
/*
* If force user is true, then store the
- * given userid and also the groups
+ * given userid and also the primary groupid
* of the user we're forcing.
*/
@@ -374,24 +413,26 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstrcpy(fuser,lp_force_user(snum));
/* Allow %S to be used by force user. */
- pstring_sub(fuser,"%S",lp_servicename(snum));
+ pstring_sub(fuser,"%S",service);
- pass2 = (struct passwd *)Get_Pwnam(fuser);
+ pass2 = (struct passwd *)Get_Pwnam(fuser,True);
if (pass2) {
conn->uid = pass2->pw_uid;
conn->gid = pass2->pw_gid;
- string_set(&conn->user,pass2->pw_name);
- fstrcpy(user,pass2->pw_name);
+ string_set(&conn->user,fuser);
+ fstrcpy(user,fuser);
conn->force_user = True;
- DEBUG(3,("Forced user %s\n",user));
+ DEBUG(3,("Forced user %s\n",fuser));
} else {
DEBUG(1,("Couldn't find user %s\n",fuser));
- conn_free(conn);
- *status = NT_STATUS_NO_SUCH_USER;
- return NULL;
}
}
+ /* admin users always run as uid=0 */
+ if (conn->admin_user) {
+ conn->uid = 0;
+ }
+
#ifdef HAVE_GETGRNAM
/*
* If force group is true, then override
@@ -404,21 +445,19 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstring tmp_gname;
BOOL user_must_be_member = False;
- pstrcpy(tmp_gname,lp_force_group(snum));
-
+ StrnCpy(tmp_gname,lp_force_group(snum),sizeof(pstring)-1);
+
if (tmp_gname[0] == '+') {
user_must_be_member = True;
- /* even now, tmp_gname is null terminated */
- pstrcpy(gname,&tmp_gname[1]);
+ StrnCpy(gname,&tmp_gname[1],sizeof(pstring)-2);
} else {
- pstrcpy(gname,tmp_gname);
+ StrnCpy(gname,tmp_gname,sizeof(pstring)-1);
}
/* default service may be a group name */
- pstring_sub(gname,"%S",lp_servicename(snum));
+ pstring_sub(gname,"%S",service);
gid = nametogid(gname);
if (gid != (gid_t)-1) {
-
/*
* If the user has been forced and the forced group starts
* with a '+', then we only set the group to be the forced
@@ -426,7 +465,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
* Otherwise, the meaning of the '+' would be ignored.
*/
if (conn->force_user && user_must_be_member) {
- if (user_in_group_list( user, gname, NULL, 0)) {
+ if (user_in_group_list( user, gname )) {
conn->gid = gid;
DEBUG(3,("Forced group %s for member %s\n",gname,user));
}
@@ -434,12 +473,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
conn->gid = gid;
DEBUG(3,("Forced group %s\n",gname));
}
- conn->force_group = True;
} else {
DEBUG(1,("Couldn't find group %s\n",gname));
- conn_free(conn);
- *status = NT_STATUS_NO_SUCH_GROUP;
- return NULL;
}
}
#endif /* HAVE_GETGRNAM */
@@ -449,48 +484,50 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstrcpy(s,lp_pathname(snum));
standard_sub_conn(conn,s,sizeof(s));
string_set(&conn->connectpath,s);
- DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum)));
+ DEBUG(3,("Connect path is %s\n",s));
}
- if (conn->force_user || conn->force_group) {
+ /* groups stuff added by ih */
+ conn->ngroups = 0;
+ conn->groups = NULL;
+
+ /* Find all the groups this uid is in and
+ store them. Used by change_to_user() */
+ initialise_groups(conn->user, conn->uid, conn->gid);
+ get_current_groups(conn->gid, &conn->ngroups,&conn->groups);
- /* groups stuff added by ih */
- conn->ngroups = 0;
- conn->groups = NULL;
-
- /* Find all the groups this uid is in and
- store them. Used by change_to_user() */
- initialise_groups(conn->user, conn->uid, conn->gid);
- get_current_groups(conn->gid, &conn->ngroups,&conn->groups);
+ /* check number of connections */
+ if (!claim_connection(conn,
+ lp_servicename(SNUM(conn)),
+ lp_max_connections(SNUM(conn)),
+ False)) {
+ DEBUG(1,("too many connections - rejected\n"));
+ *ecode = ERRnoresource;
+ conn_free(conn);
+ return NULL;
+ }
- conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
- conn->ngroups, conn->groups,
- guest);
-
- init_privilege(&(conn->privs));
-
- become_root();
- pdb_get_privilege_set(conn->nt_user_token->user_sids, conn->nt_user_token->num_sids, conn->privs);
- unbecome_root();
- }
+ conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
+ conn->ngroups, conn->groups,
+ guest, NULL);
/*
* New code to check if there's a share security descripter
* added from NT server manager. This is done after the
* smb.conf checks are done as we need a uid and token. JRA.
- *
*/
{
- BOOL can_write = share_access_check(conn, snum, vuser, FILE_WRITE_DATA);
+ BOOL can_write = share_access_check(conn, snum, vuid, FILE_WRITE_DATA);
if (!can_write) {
- if (!share_access_check(conn, snum, vuser, FILE_READ_DATA)) {
+ if (!share_access_check(conn, snum, vuid, FILE_READ_DATA)) {
/* No access, read or write. */
+ *ecode = ERRaccess;
DEBUG(0,( "make_connection: connection to %s denied due to security descriptor.\n",
- lp_servicename(snum)));
+ service ));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
return NULL;
} else {
conn->read_only = True;
@@ -500,77 +537,57 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/* Initialise VFS function pointers */
if (!smbd_vfs_init(conn)) {
- DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
+ DEBUG(0, ("smbd_vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
-/* ROOT Activities: */
- /* check number of connections */
- if (!claim_connection(conn,
- lp_servicename(SNUM(conn)),
- lp_max_connections(SNUM(conn)),
- False,0)) {
- DEBUG(1,("too many connections - rejected\n"));
- conn_free(conn);
- *status = NT_STATUS_INSUFFICIENT_RESOURCES;
- return NULL;
- }
-
- /* Preexecs are done here as they might make the dir we are to ChDir to below */
/* execute any "root preexec = " line */
if (*lp_rootpreexec(SNUM(conn))) {
- int ret;
pstring cmd;
pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
standard_sub_conn(conn,cmd,sizeof(cmd));
DEBUG(5,("cmd=%s\n",cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
- DEBUG(1,("root preexec gave %d - failing connection\n", ret));
+ DEBUG(1,("preexec gave %d - failing connection\n", ret));
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
+ *ecode = ERRsrverror;
return NULL;
}
}
-
-/* USER Activites: */
+
if (!change_to_user(conn, conn->vuid)) {
- /* No point continuing if they fail the basic checks */
DEBUG(0,("Can't become connected user!\n"));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_LOGON_FAILURE;
+ *ecode = ERRbadpw;
return NULL;
}
-
- /* Remember that a different vuid can connect later without these checks... */
- /* Preexecs are done here as they might make the dir we are to ChDir to below */
/* execute any "preexec = " line */
if (*lp_preexec(SNUM(conn))) {
- int ret;
pstring cmd;
pstrcpy(cmd,lp_preexec(SNUM(conn)));
standard_sub_conn(conn,cmd,sizeof(cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_preexec_close(SNUM(conn))) {
DEBUG(1,("preexec gave %d - failing connection\n", ret));
- change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_ACCESS_DENIED;
+ *ecode = ERRsrverror;
return NULL;
}
}
-#ifdef WITH_FAKE_KASERVER
- if (lp_afs_share(SNUM(conn))) {
- afs_login(conn);
- }
-#endif
-
+ /*
+ * FIXME!!!! Reenabled this code since it current;y breaks
+ * move_driver_to_download_area() by keeping the root path
+ * of the connection at /tmp. I'll work on a real fix, but this
+ * will keep people happy for a temporary meaure. --jerry
+ */
#if CHECK_PATH_ON_TCONX
/* win2000 does not check the permissions on the directory
during the tree connect, instead relying on permission
@@ -578,22 +595,22 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
I have disabled this chdir check (tridge) */
if (vfs_ChDir(conn,conn->connectpath) != 0) {
DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
- get_remote_machine_name(), conn->client_address,
+ remote_machine, conn->client_address,
conn->connectpath,strerror(errno)));
change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_BAD_NETWORK_NAME;
+ *ecode = ERRnosuchshare;
return NULL;
}
#else
/* the alternative is just to check the directory exists */
if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
- DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
+ DEBUG(0,("%s is not a directory\n", conn->connectpath));
change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
- *status = NT_STATUS_BAD_NETWORK_NAME;
+ *ecode = ERRnosuchshare;
return NULL;
}
#endif
@@ -613,19 +630,20 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/*
* Print out the 'connected as' stuff here as we need
- * to know the effective uid and gid we will be using
- * (at least initially).
+ * to know the effective uid and gid we will be using.
*/
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
- dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
- dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
+ dbgtext( "%s (%s) ", remote_machine, conn->client_address );
dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
- dbgtext( "initially as user %s ", user );
+ dbgtext( "as user %s ", user );
dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
dbgtext( "(pid %d)\n", (int)sys_getpid() );
}
+ /* we've finished with the sensitive stuff */
+ change_to_root_user();
+
/* Add veto/hide lists */
if (!IS_IPC(conn) && !IS_PRINT(conn)) {
set_namearray( &conn->veto_list, lp_veto_files(SNUM(conn)));
@@ -635,162 +653,19 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/* Invoke VFS make connection hook */
- if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
- DEBUG(0,("make_connection: VFS make connection failed!\n"));
- change_to_root_user();
- conn_free(conn);
- *status = NT_STATUS_UNSUCCESSFUL;
- return NULL;
+ if (conn->vfs_ops.connect) {
+ DEBUG(10,("calling vfs_ops.connect for service %s (options = %s)\n", service, lp_vfs_options(SNUM(conn)) ));
+ if (conn->vfs_ops.connect(conn, service, user) < 0)
+ return NULL;
}
-
- /* we've finished with the user stuff - go back to root */
- change_to_root_user();
return(conn);
}
-/***************************************************************************************
- Simple wrapper function for make_connection() to include a call to
- vfs_chdir()
- **************************************************************************************/
-
-connection_struct *make_connection_with_chdir(const char *service_in, DATA_BLOB password,
- const char *dev, uint16 vuid, NTSTATUS *status)
-{
- connection_struct *conn = NULL;
-
- conn = make_connection(service_in, password, dev, vuid, status);
-
- /*
- * make_connection() does not change the directory for us any more
- * so we have to do it as a separate step --jerry
- */
-
- if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
- DEBUG(0,("move_driver_to_download_area: Can't change directory to %s for [print$] (%s)\n",
- conn->connectpath,strerror(errno)));
- yield_connection(conn, lp_servicename(SNUM(conn)));
- conn_free(conn);
- *status = NT_STATUS_UNSUCCESSFUL;
- return NULL;
- }
-
- return conn;
-}
-
/****************************************************************************
- Make a connection to a service.
- *
- * @param service
+ Close a cnum
****************************************************************************/
-connection_struct *make_connection(const char *service_in, DATA_BLOB password,
- const char *pdev, uint16 vuid, NTSTATUS *status)
-{
- uid_t euid;
- user_struct *vuser = NULL;
- fstring service;
- fstring dev;
- int snum = -1;
-
- fstrcpy(dev, pdev);
-
- /* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
- if (!non_root_mode() && (euid = geteuid()) != 0) {
- DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid ));
- smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
- }
-
- if(lp_security() != SEC_SHARE) {
- vuser = get_valid_user_struct(vuid);
- if (!vuser) {
- DEBUG(1,("make_connection: refusing to connect with no session setup\n"));
- *status = NT_STATUS_ACCESS_DENIED;
- return NULL;
- }
- }
-
- /* Logic to try and connect to the correct [homes] share, preferably without too many
- getpwnam() lookups. This is particulary nasty for winbind usernames, where the
- share name isn't the same as unix username.
-
- The snum of the homes share is stored on the vuser at session setup time.
- */
-
- if (strequal(service_in,HOMES_NAME)) {
- if(lp_security() != SEC_SHARE) {
- DATA_BLOB no_pw = data_blob(NULL, 0);
- if (vuser->homes_snum == -1) {
- DEBUG(2, ("[homes] share not available for this user because it was not found or created at session setup time\n"));
- *status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
- }
- DEBUG(5, ("making a connection to [homes] service created at session setup time\n"));
- return make_connection_snum(vuser->homes_snum,
- vuser, no_pw,
- dev, status);
- } else {
- /* Security = share. Try with current_user_info.smb_name
- * as the username. */
- if (*current_user_info.smb_name) {
- fstring unix_username;
- fstrcpy(unix_username,
- current_user_info.smb_name);
- map_username(unix_username);
- snum = find_service(unix_username);
- }
- if (snum != -1) {
- DEBUG(5, ("making a connection to 'homes' service %s based on security=share\n", service_in));
- return make_connection_snum(snum, NULL,
- password,
- dev, status);
- }
- }
- } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
- && strequal(service_in, lp_servicename(vuser->homes_snum))) {
- DATA_BLOB no_pw = data_blob(NULL, 0);
- DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service_in));
- return make_connection_snum(vuser->homes_snum,
- vuser, no_pw,
- dev, status);
- }
-
- fstrcpy(service, service_in);
-
- strlower_m(service);
-
- snum = find_service(service);
-
- if (snum < 0) {
- if (strequal(service,"IPC$") || strequal(service,"ADMIN$")) {
- DEBUG(3,("refusing IPC connection to %s\n", service));
- *status = NT_STATUS_ACCESS_DENIED;
- return NULL;
- }
-
- DEBUG(0,("%s (%s) couldn't find service %s\n",
- get_remote_machine_name(), client_addr(), service));
- *status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
- }
-
- /* Handle non-Dfs clients attempting connections to msdfs proxy */
- if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0')) {
- DEBUG(3, ("refusing connection to dfs proxy '%s'\n", service));
- *status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
- }
-
- DEBUG(5, ("making a connection to 'normal' service %s\n", service));
-
- return make_connection_snum(snum, vuser,
- password,
- dev, status);
-}
-
-/****************************************************************************
-close a cnum
-****************************************************************************/
void close_cnum(connection_struct *conn, uint16 vuid)
{
DirCacheFlush(SNUM(conn));
@@ -798,20 +673,22 @@ void close_cnum(connection_struct *conn, uint16 vuid)
change_to_root_user();
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
- get_remote_machine_name(),conn->client_address,
+ remote_machine,conn->client_address,
lp_servicename(SNUM(conn))));
- /* Call VFS disconnect hook */
- SMB_VFS_DISCONNECT(conn);
+ if (conn->vfs_ops.disconnect != NULL) {
+
+ /* Call VFS disconnect hook */
+
+ conn->vfs_ops.disconnect(conn);
+
+ }
yield_connection(conn, lp_servicename(SNUM(conn)));
file_close_conn(conn);
dptr_closecnum(conn);
- /* make sure we leave the directory available for unmount */
- vfs_ChDir(conn, "/");
-
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(conn)) &&
change_to_user(conn, vuid)) {
@@ -819,7 +696,6 @@ void close_cnum(connection_struct *conn, uint16 vuid)
pstrcpy(cmd,lp_postexec(SNUM(conn)));
standard_sub_conn(conn,cmd,sizeof(cmd));
smbrun(cmd,NULL);
- change_to_root_user();
}
change_to_root_user();
@@ -831,5 +707,10 @@ void close_cnum(connection_struct *conn, uint16 vuid)
smbrun(cmd,NULL);
}
+ /* make sure we leave the directory available for unmount */
+ vfs_ChDir(conn, "/");
+
conn_free(conn);
}
+
+
diff --git a/source/smbd/session.c b/source/smbd/session.c
index 61118f13dd9..7f057256cac 100644
--- a/source/smbd/session.c
+++ b/source/smbd/session.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
session handling for utmp and PAM
Copyright (C) tridge@samba.org 2001
Copyright (C) abartlet@pcug.org.au 2001
@@ -27,224 +28,155 @@
#include "includes.h"
-static TDB_CONTEXT *tdb;
-
-BOOL session_init(void)
-{
- if (tdb)
- return True;
-
- tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644, smbd_tdb_log);
- if (!tdb) {
- DEBUG(1,("session_init: failed to open sessionid tdb\n"));
- return False;
- }
+#if defined(WITH_PAM) || defined(WITH_UTMP)
- return True;
-}
+static TDB_CONTEXT *tdb;
+struct sessionid {
+ fstring username;
+ fstring hostname;
+ fstring id_str;
+ uint32 id_num;
+ uint32 pid;
+};
/* called when a session is created */
-BOOL session_claim(user_struct *vuser)
+BOOL session_claim(uint16 vuid)
{
- int i = 0;
+ user_struct *vuser = get_valid_user_struct(vuid);
+ int i;
TDB_DATA data;
- struct sockaddr sa;
- struct in_addr *client_ip;
struct sessionid sessionid;
+ pstring dbuf;
+ int dlen;
uint32 pid = (uint32)sys_getpid();
TDB_DATA key;
fstring keystr;
char * hostname;
- int tdb_store_flag; /* If using utmp, we do an inital 'lock hold' store,
- but we don't need this if we are just using the
- (unique) pid/vuid combination */
- vuser->session_keystr = NULL;
+ vuser->session_id = 0;
/* don't register sessions for the guest user - its just too
expensive to go through pam session code for browsing etc */
- if (vuser->guest) {
+ if (strequal(vuser->user.unix_name,lp_guestaccount(-1))) {
return True;
}
- if (!session_init())
- return False;
+ if (!tdb) {
+ tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0644);
+ if (!tdb) {
+ DEBUG(1,("session_claim: failed to open sessionid tdb\n"));
+ return False;
+ }
+ }
ZERO_STRUCT(sessionid);
data.dptr = NULL;
data.dsize = 0;
- if (lp_utmp()) {
- for (i=1;i<MAX_SESSION_ID;i++) {
- slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
- key.dptr = keystr;
- key.dsize = strlen(keystr)+1;
-
- if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break;
- }
-
- if (i == MAX_SESSION_ID) {
- DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
- MAX_SESSION_ID));
- return False;
- }
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_UTMP_TEMPLATE, i);
- tdb_store_flag = TDB_MODIFY;
- } else
- {
- slprintf(keystr, sizeof(keystr)-1, "ID/%lu/%u",
- (long unsigned int)sys_getpid(),
- vuser->vuid);
- slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1,
- SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
- vuser->vuid);
-
+ for (i=1;i<MAX_SESSION_ID;i++) {
+ slprintf(keystr, sizeof(keystr)-1, "ID/%d", i);
key.dptr = keystr;
key.dsize = strlen(keystr)+1;
-
- tdb_store_flag = TDB_REPLACE;
- }
- /* If 'hostname lookup' == yes, then do the DNS lookup. This is
- needed because utmp and PAM both expect DNS names
-
- client_name() handles this case internally.
- */
+ if (tdb_store(tdb, key, data, TDB_INSERT) == 0) break;
+ }
- hostname = client_name();
- if (strcmp(hostname, "UNKNOWN") == 0) {
- hostname = client_addr();
+ if (i == MAX_SESSION_ID) {
+ DEBUG(1,("session_claim: out of session IDs (max is %d)\n",
+ MAX_SESSION_ID));
+ return False;
}
+ /* Don't resolve the hostname in smbd as we can pause for a long
+ time while waiting for DNS timeouts to occur. The correct
+ place to do this is in the code that displays the session
+ information. */
+
+ hostname = client_addr();
+
fstrcpy(sessionid.username, vuser->user.unix_name);
fstrcpy(sessionid.hostname, hostname);
- sessionid.id_num = i; /* Only valid for utmp sessions */
+ slprintf(sessionid.id_str, sizeof(sessionid.id_str)-1, SESSION_TEMPLATE, i);
+ sessionid.id_num = i;
sessionid.pid = pid;
- sessionid.uid = vuser->uid;
- sessionid.gid = vuser->gid;
- fstrcpy(sessionid.remote_machine, get_remote_machine_name());
- fstrcpy(sessionid.ip_addr, client_addr());
-
- client_ip = client_inaddr(&sa);
if (!smb_pam_claim_session(sessionid.username, sessionid.id_str, sessionid.hostname)) {
DEBUG(1,("pam_session rejected the session for %s [%s]\n",
sessionid.username, sessionid.id_str));
- if (tdb_store_flag == TDB_MODIFY) {
- tdb_delete(tdb, key);
- }
+ tdb_delete(tdb, key);
return False;
}
- data.dptr = (char *)&sessionid;
- data.dsize = sizeof(sessionid);
- if (tdb_store(tdb, key, data, tdb_store_flag) != 0) {
+ dlen = tdb_pack(dbuf, sizeof(dbuf), "fffdd",
+ sessionid.username, sessionid.hostname, sessionid.id_str,
+ sessionid.id_num, sessionid.pid);
+
+ data.dptr = dbuf;
+ data.dsize = dlen;
+ if (tdb_store(tdb, key, data, TDB_MODIFY) != 0) {
DEBUG(1,("session_claim: unable to create session id record\n"));
return False;
}
+#if WITH_UTMP
if (lp_utmp()) {
sys_utmp_claim(sessionid.username, sessionid.hostname,
- client_ip,
sessionid.id_str, sessionid.id_num);
}
+#endif
- vuser->session_keystr = strdup(keystr);
- if (!vuser->session_keystr) {
- DEBUG(0, ("session_claim: strdup() failed for session_keystr\n"));
- return False;
- }
+ vuser->session_id = i;
return True;
}
/* called when a session is destroyed */
-void session_yield(user_struct *vuser)
+void session_yield(uint16 vuid)
{
- TDB_DATA dbuf;
+ user_struct *vuser = get_valid_user_struct(vuid);
+ TDB_DATA data;
struct sessionid sessionid;
- struct in_addr *client_ip;
- TDB_DATA key;
+ TDB_DATA key;
+ fstring keystr;
if (!tdb) return;
- if (!vuser->session_keystr) {
+ if (vuser->session_id == 0) {
return;
}
- key.dptr = vuser->session_keystr;
- key.dsize = strlen(vuser->session_keystr)+1;
+ slprintf(keystr, sizeof(keystr)-1, "ID/%d", vuser->session_id);
- dbuf = tdb_fetch(tdb, key);
+ key.dptr = keystr;
+ key.dsize = strlen(keystr)+1;
- if (dbuf.dsize != sizeof(sessionid))
+ data = tdb_fetch(tdb, key);
+ if (data.dptr == NULL) {
return;
+ }
- memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
-
- client_ip = interpret_addr2(sessionid.ip_addr);
+ tdb_unpack(data.dptr, data.dsize, "fffdd",
+ &sessionid.username, &sessionid.hostname, &sessionid.id_str,
+ &sessionid.id_num, &sessionid.pid);
- SAFE_FREE(dbuf.dptr);
+ safe_free(data.dptr);
+ data.dptr = NULL;
+#if WITH_UTMP
if (lp_utmp()) {
sys_utmp_yield(sessionid.username, sessionid.hostname,
- client_ip,
sessionid.id_str, sessionid.id_num);
}
+#endif
smb_pam_close_session(sessionid.username, sessionid.id_str, sessionid.hostname);
tdb_delete(tdb, key);
}
-static BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), void *state)
-{
- if (!session_init()) {
- DEBUG(3, ("No tdb opened\n"));
- return False;
- }
-
- tdb_traverse(tdb, fn, state);
- return True;
-}
-
-struct session_list {
- int count;
- struct sessionid *sessions;
-};
-
-static int gather_sessioninfo(TDB_CONTEXT *stdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- struct session_list *sesslist = (struct session_list *) state;
- const struct sessionid *current = (const struct sessionid *) dbuf.dptr;
-
- sesslist->count += 1;
- sesslist->sessions = REALLOC(sesslist->sessions, sesslist->count *
- sizeof(struct sessionid));
-
- memcpy(&sesslist->sessions[sesslist->count - 1], current,
- sizeof(struct sessionid));
- DEBUG(7,("gather_sessioninfo session from %s@%s\n",
- current->username, current->remote_machine));
- return 0;
-}
-
-int list_sessions(struct sessionid **session_list)
-{
- struct session_list sesslist;
-
- sesslist.count = 0;
- sesslist.sessions = NULL;
-
- if (!session_traverse(gather_sessioninfo, (void *) &sesslist)) {
- DEBUG(3, ("Session traverse failed\n"));
- SAFE_FREE(sesslist.sessions);
- *session_list = NULL;
- return 0;
- }
-
- *session_list = sesslist.sessions;
- return sesslist.count;
-}
+#else
+ /* null functions - no session support needed */
+ BOOL session_claim(uint16 vuid) { return True; }
+ void session_yield(uint16 vuid) {}
+#endif
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
deleted file mode 100644
index 902db2d2886..00000000000
--- a/source/smbd/sesssetup.c
+++ /dev/null
@@ -1,934 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- handle SMBsessionsetup
- Copyright (C) Andrew Tridgell 1998-2001
- Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
- Copyright (C) Luke Howard 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-uint32 global_client_caps = 0;
-
-static struct auth_ntlmssp_state *global_ntlmssp_state;
-
-/*
- on a logon error possibly map the error to success if "map to guest"
- is set approriately
-*/
-static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info,
- const char *user, const char *domain)
-{
- if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
- if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
- (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
- DEBUG(3,("No such user %s [%s] - using guest account\n",
- user, domain));
- status = make_server_info_guest(server_info);
- }
- }
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
- if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
- DEBUG(3,("Registered username %s for guest access\n",user));
- status = make_server_info_guest(server_info);
- }
- }
-
- return status;
-}
-
-/****************************************************************************
- Add the standard 'Samba' signature to the end of the session setup.
-****************************************************************************/
-
-static int add_signature(char *outbuf, char *p)
-{
- char *start = p;
- fstring lanman;
-
- fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
-
- p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
- p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE);
- p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
-
- return PTR_DIFF(p, start);
-}
-
-/****************************************************************************
- Send a security blob via a session setup reply.
-****************************************************************************/
-
-static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
- DATA_BLOB blob, NTSTATUS nt_status)
-{
- char *p;
-
- set_message(outbuf,4,0,True);
-
- nt_status = nt_status_squash(nt_status);
- SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status));
- SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
- SSVAL(outbuf, smb_vwv3, blob.length);
- p = smb_buf(outbuf);
-
- /* should we cap this? */
- memcpy(p, blob.data, blob.length);
- p += blob.length;
-
- p += add_signature( outbuf, p );
-
- set_message_end(outbuf,p);
-
- return send_smb(smbd_server_fd(),outbuf);
-}
-
-/****************************************************************************
- Do a 'guest' logon, getting back the
-****************************************************************************/
-
-static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
-{
- struct auth_context *auth_context;
- auth_usersupplied_info *user_info = NULL;
-
- NTSTATUS nt_status;
- unsigned char chal[8];
-
- ZERO_STRUCT(chal);
-
- DEBUG(3,("Got anonymous request\n"));
-
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
- return nt_status;
- }
-
- if (!make_user_info_guest(&user_info)) {
- (auth_context->free)(&auth_context);
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
- (auth_context->free)(&auth_context);
- free_user_info(&user_info);
- return nt_status;
-}
-
-
-#ifdef HAVE_KRB5
-/****************************************************************************
-reply to a session setup spnego negotiate packet for kerberos
-****************************************************************************/
-static int reply_spnego_kerberos(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- DATA_BLOB *secblob)
-{
- DATA_BLOB ticket;
- char *client, *p, *domain;
- fstring netbios_domain_name;
- struct passwd *pw;
- char *user;
- int sess_vuid;
- NTSTATUS ret;
- DATA_BLOB auth_data;
- DATA_BLOB ap_rep, ap_rep_wrapped, response;
- auth_serversupplied_info *server_info = NULL;
- DATA_BLOB session_key;
- uint8 tok_id[2];
- BOOL foreign = False;
- DATA_BLOB nullblob = data_blob(NULL, 0);
- fstring real_username;
-
- ZERO_STRUCT(ticket);
- ZERO_STRUCT(auth_data);
- ZERO_STRUCT(ap_rep);
- ZERO_STRUCT(ap_rep_wrapped);
- ZERO_STRUCT(response);
-
- if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key);
-
- data_blob_free(&ticket);
-
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(1,("Failed to verify incoming ticket!\n"));
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- data_blob_free(&auth_data);
-
- DEBUG(3,("Ticket name is [%s]\n", client));
-
- p = strchr_m(client, '@');
- if (!p) {
- DEBUG(3,("Doesn't look like a valid principal\n"));
- data_blob_free(&ap_rep);
- SAFE_FREE(client);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- *p = 0;
- if (!strequal(p+1, lp_realm())) {
- DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
- if (!lp_allow_trusted_domains()) {
- data_blob_free(&ap_rep);
- SAFE_FREE(client);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
- foreign = True;
- }
-
- /* this gives a fully qualified user name (ie. with full realm).
- that leads to very long usernames, but what else can we do? */
-
- domain = p+1;
-
- {
- /* If we have winbind running, we can (and must) shorten the
- username by using the short netbios name. Otherwise we will
- have inconsistent user names. With Kerberos, we get the
- fully qualified realm, with ntlmssp we get the short
- name. And even w2k3 does use ntlmssp if you for example
- connect to an ip address. */
-
- struct winbindd_request wb_request;
- struct winbindd_response wb_response;
- NSS_STATUS wb_result;
-
- ZERO_STRUCT(wb_request);
- ZERO_STRUCT(wb_response);
-
- DEBUG(10, ("Mapping [%s] to short name\n", domain));
-
- fstrcpy(wb_request.domain_name, domain);
-
- wb_result = winbindd_request(WINBINDD_DOMAIN_INFO,
- &wb_request, &wb_response);
-
- if (wb_result == NSS_STATUS_SUCCESS) {
-
- fstrcpy(netbios_domain_name,
- wb_response.data.domain_info.name);
- domain = netbios_domain_name;
-
- DEBUG(10, ("Mapped to [%s]\n", domain));
- } else {
- DEBUG(3, ("Could not find short name -- winbind "
- "not running?\n"));
- }
- }
-
- asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client);
-
- /* lookup the passwd struct, create a new user if necessary */
-
- pw = smb_getpwnam( user, real_username, True );
-
- if (!pw) {
- DEBUG(1,("Username %s is invalid on this system\n",user));
- SAFE_FREE(user);
- SAFE_FREE(client);
- data_blob_free(&ap_rep);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- /* setup the string used by %U */
-
- sub_set_smb_name( real_username );
- reload_services(True);
-
- if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw)))
- {
- DEBUG(1,("make_server_info_from_pw failed!\n"));
- SAFE_FREE(user);
- SAFE_FREE(client);
- data_blob_free(&ap_rep);
- return ERROR_NT(ret);
- }
-
- /* make_server_info_pw does not set the domain. Without this we end up
- * with the local netbios name in substitutions for %D. */
-
- if (server_info->sam_account != NULL) {
- pdb_set_domain(server_info->sam_account, domain, PDB_SET);
- }
-
- /* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, session_key, nullblob, client);
-
- SAFE_FREE(user);
- SAFE_FREE(client);
-
- if (sess_vuid == -1) {
- ret = NT_STATUS_LOGON_FAILURE;
- } else {
- /* current_user_info is changed on new vuid */
- reload_services( True );
-
- set_message(outbuf,4,0,True);
- SSVAL(outbuf, smb_vwv3, 0);
-
- if (server_info->guest) {
- SSVAL(outbuf,smb_vwv2,1);
- }
-
- SSVAL(outbuf, smb_uid, sess_vuid);
-
- if (!server_info->guest && !srv_signing_started()) {
- /* We need to start the signing engine
- * here but a W2K client sends the old
- * "BSRSPYL " signature instead of the
- * correct one. Subsequent packets will
- * be correct.
- */
- srv_check_sign_mac(inbuf, False);
- }
- }
-
- /* wrap that up in a nice GSS-API wrapping */
- if (NT_STATUS_IS_OK(ret)) {
- ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
- } else {
- ap_rep_wrapped = data_blob(NULL, 0);
- }
- response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
- reply_sesssetup_blob(conn, outbuf, response, ret);
-
- data_blob_free(&ap_rep);
- data_blob_free(&ap_rep_wrapped);
- data_blob_free(&response);
-
- return -1; /* already replied */
-}
-#endif
-
-/****************************************************************************
- Send a session setup reply, wrapped in SPNEGO.
- Get vuid and check first.
- End the NTLMSSP exchange context if we are OK/complete fail
-***************************************************************************/
-
-static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
- AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
- DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status)
-{
- BOOL ret;
- DATA_BLOB response;
- struct auth_serversupplied_info *server_info = NULL;
-
- if (NT_STATUS_IS_OK(nt_status)) {
- server_info = (*auth_ntlmssp_state)->server_info;
- } else {
- nt_status = do_map_to_guest(nt_status,
- &server_info,
- (*auth_ntlmssp_state)->ntlmssp_state->user,
- (*auth_ntlmssp_state)->ntlmssp_state->domain);
- }
-
- if (NT_STATUS_IS_OK(nt_status)) {
- int sess_vuid;
- DATA_BLOB nullblob = data_blob(NULL, 0);
- DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
-
- /* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
- (*auth_ntlmssp_state)->server_info = NULL;
-
- if (sess_vuid == -1) {
- nt_status = NT_STATUS_LOGON_FAILURE;
- } else {
-
- /* current_user_info is changed on new vuid */
- reload_services( True );
-
- set_message(outbuf,4,0,True);
- SSVAL(outbuf, smb_vwv3, 0);
-
- if (server_info->guest) {
- SSVAL(outbuf,smb_vwv2,1);
- }
-
- SSVAL(outbuf,smb_uid,sess_vuid);
-
- if (!server_info->guest && !srv_signing_started()) {
- /* We need to start the signing engine
- * here but a W2K client sends the old
- * "BSRSPYL " signature instead of the
- * correct one. Subsequent packets will
- * be correct.
- */
-
- srv_check_sign_mac(inbuf, False);
- }
- }
- }
-
- response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP);
- ret = reply_sesssetup_blob(conn, outbuf, response, nt_status);
- data_blob_free(&response);
-
- /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
- and the other end, that we are not finished yet. */
-
- if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- auth_ntlmssp_end(auth_ntlmssp_state);
- }
-
- return ret;
-}
-
-/****************************************************************************
- Reply to a session setup spnego negotiate packet.
-****************************************************************************/
-
-static int reply_spnego_negotiate(connection_struct *conn,
- char *inbuf,
- char *outbuf,
- int length, int bufsize,
- DATA_BLOB blob1)
-{
- char *OIDs[ASN1_MAX_OIDS];
- DATA_BLOB secblob;
- int i;
- DATA_BLOB chal;
- BOOL got_kerberos = False;
- NTSTATUS nt_status;
-
- /* parse out the OIDs and the first sec blob */
- if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- /* only look at the first OID for determining the mechToken --
- accoirding to RFC2478, we should choose the one we want
- and renegotiate, but i smell a client bug here..
-
- Problem observed when connecting to a member (samba box)
- of an AD domain as a user in a Samba domain. Samba member
- server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
- client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
- NTLMSSP mechtoken. --jerry */
-
- if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
- strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
- got_kerberos = True;
- }
-
- for (i=0;OIDs[i];i++) {
- DEBUG(3,("Got OID %s\n", OIDs[i]));
- free(OIDs[i]);
- }
- DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length));
-
-#ifdef HAVE_KRB5
- if (got_kerberos && (SEC_ADS == lp_security())) {
- int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
- length, bufsize, &secblob);
- data_blob_free(&secblob);
- return ret;
- }
-#endif
-
- if (global_ntlmssp_state) {
- auth_ntlmssp_end(&global_ntlmssp_state);
- }
-
- nt_status = auth_ntlmssp_start(&global_ntlmssp_state);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return ERROR_NT(nt_status);
- }
-
- nt_status = auth_ntlmssp_update(global_ntlmssp_state,
- secblob, &chal);
-
- data_blob_free(&secblob);
-
- reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state,
- &chal, nt_status);
-
- data_blob_free(&chal);
-
- /* already replied */
- return -1;
-}
-
-/****************************************************************************
- Reply to a session setup spnego auth packet.
-****************************************************************************/
-
-static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize,
- DATA_BLOB blob1)
-{
- DATA_BLOB auth, auth_reply;
- NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;
-
- if (!spnego_parse_auth(blob1, &auth)) {
-#if 0
- file_save("auth.dat", blob1.data, blob1.length);
-#endif
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- if (!global_ntlmssp_state) {
- /* auth before negotiatiate? */
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- nt_status = auth_ntlmssp_update(global_ntlmssp_state,
- auth, &auth_reply);
-
- data_blob_free(&auth);
-
- reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state,
- &auth_reply, nt_status);
-
- data_blob_free(&auth_reply);
-
- /* and tell smbd that we have already replied to this packet */
- return -1;
-}
-
-/****************************************************************************
- Reply to a session setup command.
-****************************************************************************/
-
-static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
- char *outbuf,
- int length,int bufsize)
-{
- uint8 *p;
- DATA_BLOB blob1;
- int ret;
- size_t bufrem;
- fstring native_os, native_lanman, primary_domain;
- char *p2;
- uint16 data_blob_len = SVAL(inbuf, smb_vwv7);
- enum remote_arch_types ra_type = get_remote_arch();
-
- DEBUG(3,("Doing spnego session setup\n"));
-
- if (global_client_caps == 0) {
- global_client_caps = IVAL(inbuf,smb_vwv10);
-
- if (!(global_client_caps & CAP_STATUS32)) {
- remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
- }
-
- }
-
- p = (uint8 *)smb_buf(inbuf);
-
- if (data_blob_len == 0) {
- /* an invalid request */
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- bufrem = smb_bufrem(inbuf, p);
- /* pull the spnego blob */
- blob1 = data_blob(p, MIN(bufrem, data_blob_len));
-
-#if 0
- file_save("negotiate.dat", blob1.data, blob1.length);
-#endif
-
- p2 = inbuf + smb_vwv13 + data_blob_len;
- p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE);
- p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE);
- p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE);
- DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
- native_os, native_lanman, primary_domain));
-
- if ( ra_type == RA_WIN2K ) {
- /* Windows 2003 doesn't set the native lanman string,
- but does set primary domain which is a bug I think */
-
- if ( !strlen(native_lanman) )
- ra_lanman_string( primary_domain );
- else
- ra_lanman_string( native_lanman );
- }
-
- if (blob1.data[0] == ASN1_APPLICATION(0)) {
- /* its a negTokenTarg packet */
- ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1);
- data_blob_free(&blob1);
- return ret;
- }
-
- if (blob1.data[0] == ASN1_CONTEXT(1)) {
- /* its a auth packet */
- ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1);
- data_blob_free(&blob1);
- return ret;
- }
-
- /* what sort of packet is this? */
- DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
-
- data_blob_free(&blob1);
-
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
-}
-
-/****************************************************************************
- On new VC == 0, shutdown *all* old connections and users.
- It seems that only NT4.x does this. At W2K and above (XP etc.).
- a new session setup with VC==0 is ignored.
-****************************************************************************/
-
-static void setup_new_vc_session(void)
-{
- DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n"));
-#if 0
- conn_close_all();
- invalidate_all_vuids();
-#endif
-}
-
-/****************************************************************************
- Reply to a session setup command.
-****************************************************************************/
-
-int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
- int length,int bufsize)
-{
- int sess_vuid;
- int smb_bufsize;
- DATA_BLOB lm_resp;
- DATA_BLOB nt_resp;
- DATA_BLOB plaintext_password;
- fstring user;
- fstring sub_user; /* Sainitised username for substituion */
- fstring domain;
- fstring native_os;
- fstring native_lanman;
- fstring primary_domain;
- static BOOL done_sesssetup = False;
- extern BOOL global_encrypted_passwords_negotiated;
- extern BOOL global_spnego_negotiated;
- extern int Protocol;
- extern int max_send;
-
- auth_usersupplied_info *user_info = NULL;
- extern struct auth_context *negprot_global_auth_context;
- auth_serversupplied_info *server_info = NULL;
-
- NTSTATUS nt_status;
-
- BOOL doencrypt = global_encrypted_passwords_negotiated;
-
- DATA_BLOB session_key;
-
- START_PROFILE(SMBsesssetupX);
-
- ZERO_STRUCT(lm_resp);
- ZERO_STRUCT(nt_resp);
- ZERO_STRUCT(plaintext_password);
-
- DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
-
- /* a SPNEGO session setup has 12 command words, whereas a normal
- NT1 session setup has 13. See the cifs spec. */
- if (CVAL(inbuf, smb_wct) == 12 &&
- (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
- if (!global_spnego_negotiated) {
- DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
- return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- }
-
- if (SVAL(inbuf,smb_vwv4) == 0) {
- setup_new_vc_session();
- }
- return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
- }
-
- smb_bufsize = SVAL(inbuf,smb_vwv2);
-
- if (Protocol < PROTOCOL_NT1) {
- uint16 passlen1 = SVAL(inbuf,smb_vwv7);
- if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- if (doencrypt) {
- lm_resp = data_blob(smb_buf(inbuf), passlen1);
- } else {
- plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
- /* Ensure null termination */
- plaintext_password.data[passlen1] = 0;
- }
-
- srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE);
- *domain = 0;
-
- } else {
- uint16 passlen1 = SVAL(inbuf,smb_vwv7);
- uint16 passlen2 = SVAL(inbuf,smb_vwv8);
- enum remote_arch_types ra_type = get_remote_arch();
- char *p = smb_buf(inbuf);
- char *save_p = smb_buf(inbuf);
- uint16 byte_count;
-
-
- if(global_client_caps == 0) {
- global_client_caps = IVAL(inbuf,smb_vwv11);
-
- if (!(global_client_caps & CAP_STATUS32)) {
- remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
- }
-
- /* client_caps is used as final determination if client is NT or Win95.
- This is needed to return the correct error codes in some
- circumstances.
- */
-
- if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
- if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
- set_remote_arch( RA_WIN95);
- }
- }
- }
-
- if (!doencrypt) {
- /* both Win95 and WinNT stuff up the password lengths for
- non-encrypting systems. Uggh.
-
- if passlen1==24 its a win95 system, and its setting the
- password length incorrectly. Luckily it still works with the
- default code because Win95 will null terminate the password
- anyway
-
- if passlen1>0 and passlen2>0 then maybe its a NT box and its
- setting passlen2 to some random value which really stuffs
- things up. we need to fix that one. */
-
- if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
- passlen2 = 0;
- }
-
- /* check for nasty tricks */
- if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
- }
-
- /* Save the lanman2 password and the NT md4 password. */
-
- if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
- doencrypt = False;
- }
-
- if (doencrypt) {
- lm_resp = data_blob(p, passlen1);
- nt_resp = data_blob(p+passlen1, passlen2);
- } else {
- pstring pass;
- BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS;
-
- if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) {
- /* NT4.0 stuffs up plaintext unicode password lengths... */
- srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1,
- sizeof(pass), passlen1, STR_TERMINATE);
- } else {
- srvstr_pull(inbuf, pass, smb_buf(inbuf),
- sizeof(pass), unic ? passlen2 : passlen1,
- STR_TERMINATE);
- }
- plaintext_password = data_blob(pass, strlen(pass)+1);
- }
-
- p += passlen1 + passlen2;
- p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE);
- p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE);
- p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE);
- p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE);
-
- /* not documented or decoded by Ethereal but there is one more string
- in the extra bytes which is the same as the PrimaryDomain when using
- extended security. Windows NT 4 and 2003 use this string to store
- the native lanman string. Windows 9x does not include a string here
- at all so we have to check if we have any extra bytes left */
-
- byte_count = SVAL(inbuf, smb_vwv13);
- if ( PTR_DIFF(p, save_p) < byte_count)
- p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE);
- else
- fstrcpy( primary_domain, "null" );
-
- DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
- domain, native_os, native_lanman, primary_domain));
-
- if ( ra_type == RA_WIN2K ) {
- if ( strlen(native_lanman) == 0 )
- ra_lanman_string( primary_domain );
- else
- ra_lanman_string( native_lanman );
- }
-
- }
-
- if (SVAL(inbuf,smb_vwv4) == 0) {
- setup_new_vc_session();
- }
-
- DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
-
- if (*user) {
- if (global_spnego_negotiated) {
-
- /* This has to be here, because this is a perfectly valid behaviour for guest logons :-( */
-
- DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
- return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- }
- fstrcpy(sub_user, user);
-
- /* setup the string used by %U */
- sub_set_smb_name(user);
- } else {
- fstrcpy(sub_user, lp_guestaccount());
- }
-
- sub_set_smb_name(sub_user);
-
- reload_services(True);
-
- if (lp_security() == SEC_SHARE) {
- /* in share level we should ignore any passwords */
-
- data_blob_free(&lm_resp);
- data_blob_free(&nt_resp);
- data_blob_clear_free(&plaintext_password);
-
- map_username(sub_user);
- add_session_user(sub_user);
- /* Then force it to null for the benfit of the code below */
- *user = 0;
- }
-
- if (!*user) {
-
- nt_status = check_guest_password(&server_info);
-
- } else if (doencrypt) {
- if (!negprot_global_auth_context) {
- DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n"));
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
- nt_status = make_user_info_for_reply_enc(&user_info, user, domain,
- lm_resp, nt_resp);
- if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
- user_info,
- &server_info);
- }
- } else {
- struct auth_context *plaintext_auth_context = NULL;
- const uint8 *chal;
- if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
- chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
-
- if (!make_user_info_for_reply(&user_info,
- user, domain, chal,
- plaintext_password)) {
- nt_status = NT_STATUS_NO_MEMORY;
- }
-
- if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
- user_info,
- &server_info);
-
- (plaintext_auth_context->free)(&plaintext_auth_context);
- }
- }
- }
-
- free_user_info(&user_info);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
- }
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
- data_blob_clear_free(&plaintext_password);
- return ERROR_NT(nt_status_squash(nt_status));
- }
-
- if (server_info->user_session_key.data) {
- session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length);
- } else {
- session_key = data_blob(NULL, 0);
- }
-
- data_blob_clear_free(&plaintext_password);
-
- /* it's ok - setup a reply */
- set_message(outbuf,3,0,True);
- if (Protocol >= PROTOCOL_NT1) {
- char *p = smb_buf( outbuf );
- p += add_signature( outbuf, p );
- set_message_end( outbuf, p );
- /* perhaps grab OS version here?? */
- }
-
- if (server_info->guest) {
- SSVAL(outbuf,smb_vwv2,1);
- }
-
- /* register the name and uid as being validated, so further connections
- to a uid can get through without a password, on the same VC */
-
- /* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, session_key, nt_resp.data ? nt_resp : lm_resp, sub_user);
- data_blob_free(&nt_resp);
- data_blob_free(&lm_resp);
-
- if (sess_vuid == -1) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- /* current_user_info is changed on new vuid */
- reload_services( True );
-
- if (!server_info->guest && !srv_signing_started() && !srv_check_sign_mac(inbuf, True)) {
- exit_server("reply_sesssetup_and_X: bad smb signature");
- }
-
- SSVAL(outbuf,smb_uid,sess_vuid);
- SSVAL(inbuf,smb_uid,sess_vuid);
-
- if (!done_sesssetup)
- max_send = MIN(max_send,smb_bufsize);
-
- done_sesssetup = True;
-
- END_PROFILE(SMBsesssetupX);
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
diff --git a/source/smbd/srvstr.c b/source/smbd/srvstr.c
deleted file mode 100644
index 409fd30a679..00000000000
--- a/source/smbd/srvstr.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- server specific string routines
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-extern int max_send;
-
-/* Make sure we can't write a string past the end of the buffer */
-
-size_t srvstr_push_fn(const char *function, unsigned int line,
- const char *base_ptr, void *dest,
- const char *src, int dest_len, int flags)
-{
- size_t buf_used = PTR_DIFF(dest, base_ptr);
- if (dest_len == -1) {
- if (((ptrdiff_t)dest < (ptrdiff_t)base_ptr) || (buf_used > (size_t)max_send)) {
-#if 0
- DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n"));
-#endif
- return push_string_fn(function, line, base_ptr, dest, src, -1, flags);
- }
- return push_string_fn(function, line, base_ptr, dest, src, max_send - buf_used, flags);
- }
-
- /* 'normal' push into size-specified buffer */
- return push_string_fn(function, line, base_ptr, dest, src, dest_len, flags);
-}
diff --git a/source/smbd/ssl.c b/source/smbd/ssl.c
new file mode 100755
index 00000000000..349ca34f959
--- /dev/null
+++ b/source/smbd/ssl.c
@@ -0,0 +1,287 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SSLeay utility functions
+ Copyright (C) Christian Starkjohann <cs@obdev.at> 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * since includes.h pulls in config.h which is were WITH_SSL will be
+ * defined, we want to include includes.h before testing for WITH_SSL
+ * RJS 26-Jan-1999
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SSL /* should always be defined if this module is compiled */
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+BOOL sslEnabled;
+SSL *ssl = NULL;
+int sslFd = -1;
+static SSL_CTX *sslContext = NULL;
+extern int DEBUGLEVEL;
+
+static int ssl_verify_cb(int ok, X509_STORE_CTX *ctx)
+{
+char buffer[256];
+
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
+ buffer, sizeof(buffer));
+ if(ok){
+ DEBUG(0, ("SSL: Certificate OK: %s\n", buffer));
+ }else{
+ switch (ctx->error){
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ DEBUG(0, ("SSL: Cert error: CA not known: %s\n", buffer));
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ DEBUG(0, ("SSL: Cert error: Cert not yet valid: %s\n", buffer));
+ break;
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ DEBUG(0, ("SSL: Cert error: illegal \'not before\' field: %s\n",
+ buffer));
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ DEBUG(0, ("SSL: Cert error: Cert expired: %s\n", buffer));
+ break;
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ DEBUG(0, ("SSL: Cert error: invalid \'not after\' field: %s\n",
+ buffer));
+ break;
+ default:
+ DEBUG(0, ("SSL: Cert error: unknown error %d in %s\n", ctx->error,
+ buffer));
+ break;
+ }
+ }
+ return ok;
+}
+
+static RSA *ssl_temp_rsa_cb(SSL *ssl, int is_export, int keylength)
+{
+static RSA *rsa = NULL;
+
+ if(rsa == NULL)
+ rsa = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
+ return rsa;
+}
+
+/* This is called before we fork. It should ask the user for the pass phrase
+ * if necessary. Error output can still go to stderr because the process
+ * has a terminal.
+ */
+int sslutil_init(int isServer)
+{
+int err, entropybytes;
+char *certfile, *keyfile, *ciphers, *cacertDir, *cacertFile;
+char *egdsocket, *entropyfile;
+
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+ egdsocket = lp_ssl_egdsocket();
+ if (egdsocket != NULL && *egdsocket != 0)
+ RAND_egd(egdsocket);
+ entropyfile = lp_ssl_entropyfile();
+ entropybytes = lp_ssl_entropybytes();
+ if (entropyfile != NULL && *entropyfile != 0)
+ RAND_load_file(entropyfile, entropybytes);
+ switch(lp_ssl_version()){
+ case SMB_SSL_V2: sslContext = SSL_CTX_new(SSLv2_method()); break;
+ case SMB_SSL_V3: sslContext = SSL_CTX_new(SSLv3_method()); break;
+ default:
+ case SMB_SSL_V23: sslContext = SSL_CTX_new(SSLv23_method()); break;
+ case SMB_SSL_TLS1: sslContext = SSL_CTX_new(TLSv1_method()); break;
+ }
+ if(sslContext == NULL){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Error allocating context: %s\n",
+ ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(lp_ssl_compatibility()){
+ SSL_CTX_set_options(sslContext, SSL_OP_ALL);
+ }
+ certfile = isServer ? lp_ssl_server_cert() : lp_ssl_client_cert();
+ if((certfile == NULL || *certfile == 0) && isServer){
+ fprintf(stderr, "SSL: No cert file specified in config file!\n");
+ fprintf(stderr, "The server MUST have a certificate!\n");
+ exit(1);
+ }
+ keyfile = isServer ? lp_ssl_server_privkey() : lp_ssl_client_privkey();
+ if(keyfile == NULL || *keyfile == 0)
+ keyfile = certfile;
+ if(certfile != NULL && *certfile != 0){
+ if(!SSL_CTX_use_certificate_chain_file(sslContext, certfile)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: error reading certificate from file %s: %s\n",
+ certfile, ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: error reading private key from file %s: %s\n",
+ keyfile, ERR_error_string(err, NULL));
+ exit(1);
+ }
+ if(!SSL_CTX_check_private_key(sslContext)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Private key does not match public key in cert!\n");
+ exit(1);
+ }
+ }
+ cacertDir = lp_ssl_cacertdir();
+ cacertFile = lp_ssl_cacertfile();
+ if(cacertDir != NULL && *cacertDir == 0)
+ cacertDir = NULL;
+ if(cacertFile != NULL && *cacertFile == 0)
+ cacertFile = NULL;
+ if(!SSL_CTX_load_verify_locations(sslContext, cacertFile, cacertDir)){
+ err = ERR_get_error();
+ if (cacertFile || cacertDir) {
+ fprintf(stderr, "SSL: Error error setting CA cert locations: %s\n",
+ ERR_error_string(err, NULL));
+ fprintf(stderr, "trying default locations.\n");
+ }
+ cacertFile = cacertDir = NULL;
+ if(!SSL_CTX_set_default_verify_paths(sslContext)){
+ err = ERR_get_error();
+ fprintf(stderr, "SSL: Error error setting default CA cert location: %s\n",
+ ERR_error_string(err, NULL));
+ exit(1);
+ }
+ }
+ SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
+ if((ciphers = lp_ssl_ciphers()) != NULL && *ciphers != 0)
+ SSL_CTX_set_cipher_list(sslContext, ciphers);
+ if((isServer && lp_ssl_reqClientCert()) || (!isServer && lp_ssl_reqServerCert())){
+ SSL_CTX_set_verify(sslContext,
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
+ }else{
+ SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, ssl_verify_cb);
+ }
+#if 1 /* don't know what this is good for, but s_server in SSLeay does it, too */
+ if(isServer){
+ SSL_CTX_set_client_CA_list(sslContext, SSL_load_client_CA_file(certfile));
+ }
+#endif
+ return 0;
+}
+
+int sslutil_accept(int fd)
+{
+int err;
+
+ if(ssl != NULL){
+ DEBUG(0, ("SSL: internal error: more than one SSL connection (server)\n"));
+ return -1;
+ }
+ if((ssl = SSL_new(sslContext)) == NULL){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error allocating handle: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ SSL_set_fd(ssl, fd);
+ sslFd = fd;
+ if(SSL_accept(ssl) <= 0){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error accepting on socket: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ DEBUG(0, ("SSL: negotiated cipher: %s\n", SSL_get_cipher(ssl)));
+ return 0;
+}
+
+int sslutil_fd_is_ssl(int fd)
+{
+ return fd == sslFd;
+}
+
+int sslutil_connect(int fd)
+{
+int err;
+
+ if(ssl != NULL){
+ DEBUG(0, ("SSL: internal error: more than one SSL connection (client)\n"));
+ return -1;
+ }
+ if((ssl = SSL_new(sslContext)) == NULL){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error allocating handle: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ SSL_set_fd(ssl, fd);
+ sslFd = fd;
+ if(SSL_connect(ssl) <= 0){
+ err = ERR_get_error();
+ DEBUG(0, ("SSL: Error conencting socket: %s\n",
+ ERR_error_string(err, NULL)));
+ return -1;
+ }
+ DEBUG(0, ("SSL: negotiated cipher: %s\n", SSL_get_cipher(ssl)));
+ return 0;
+}
+
+int sslutil_disconnect(int fd)
+{
+ if(fd == sslFd && ssl != NULL){
+ SSL_free(ssl);
+ ssl = NULL;
+ sslFd = -1;
+ }
+ return 0;
+}
+
+int sslutil_negotiate_ssl(int fd, int msg_type)
+{
+unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
+char *reqHosts, *resignHosts;
+
+ reqHosts = lp_ssl_hosts();
+ resignHosts = lp_ssl_hosts_resign();
+ if(!allow_access(resignHosts, reqHosts, get_socket_name(fd), get_socket_addr(fd))){
+ sslEnabled = False;
+ return 0;
+ }
+ if(msg_type != 0x81){ /* first packet must be a session request */
+ DEBUG( 0, ( "Client %s did not use session setup; access denied\n",
+ client_addr() ) );
+ if (!send_smb(fd, (char *)buf))
+ DEBUG(0, ("sslutil_negotiate_ssl: send_smb failed.\n"));
+ return -1;
+ }
+ buf[4] = 0x8e; /* negative session response: use SSL */
+ if (!send_smb(fd, (char *)buf)) {
+ DEBUG(0,("sslutil_negotiate_ssl: send_smb failed.\n"));
+ return -1;
+ }
+ if(sslutil_accept(fd) != 0){
+ DEBUG( 0, ( "Client %s failed SSL negotiation!\n", client_addr() ) );
+ return -1;
+ }
+ return 1;
+}
+
+#else /* WITH_SSL */
+ void ssl_dummy(void);
+ void ssl_dummy(void) {;} /* So some compilers don't complain. */
+#endif /* WITH_SSL */
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index 5e78e9a4999..fbb7dfb6873 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -1,9 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
stat cache code
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1999-2000
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,295 +23,189 @@
#include "includes.h"
+extern BOOL case_sensitive;
+
+
/****************************************************************************
Stat cache code used in unix_convert.
*****************************************************************************/
typedef struct {
- char *original_path;
- char *translated_path;
- size_t translated_path_length;
- char names[2]; /* This is extended via malloc... */
+ int name_len;
+ char names[2]; /* This is extended via malloc... */
} stat_cache_entry;
#define INIT_STAT_CACHE_SIZE 512
static hash_table stat_cache;
-/**
- * Add an entry into the stat cache.
- *
- * @param full_orig_name The original name as specified by the client
- * @param orig_translated_path The name on our filesystem.
- *
- * @note Only the first strlen(orig_translated_path) characters are stored
- * into the cache. This means that full_orig_name will be internally
- * truncated.
- *
- */
+/****************************************************************************
+ Add an entry into the stat cache.
+*****************************************************************************/
-void stat_cache_add( const char *full_orig_name, const char *orig_translated_path, BOOL case_sensitive)
+void stat_cache_add( char *full_orig_name, char *orig_translated_path)
{
- stat_cache_entry *scp;
- stat_cache_entry *found_scp;
- char *translated_path;
- size_t translated_path_length;
-
- char *original_path;
- size_t original_path_length;
-
- hash_element *hash_elem;
-
- if (!lp_stat_cache())
- return;
-
- /*
- * Don't cache trivial valid directory entries such as . and ..
- */
-
- if((*full_orig_name == '\0') || (full_orig_name[0] == '.' &&
- ((full_orig_name[1] == '\0') ||
- (full_orig_name[1] == '.' && full_orig_name[1] == '\0'))))
- return;
-
- /*
- * If we are in case insentive mode, we don't need to
- * store names that need no translation - else, it
- * would be a waste.
- */
-
- if(case_sensitive && (strcmp(full_orig_name, orig_translated_path) == 0))
- return;
-
- /*
- * Remove any trailing '/' characters from the
- * translated path.
- */
-
- translated_path = strdup(orig_translated_path);
- if (!translated_path)
- return;
-
- translated_path_length = strlen(translated_path);
-
- if(translated_path[translated_path_length-1] == '/') {
- translated_path[translated_path_length-1] = '\0';
- translated_path_length--;
- }
-
- if(case_sensitive) {
- original_path = strdup(full_orig_name);
- } else {
- original_path = strdup_upper(full_orig_name);
- }
-
- if (!original_path) {
- SAFE_FREE(translated_path);
- return;
- }
-
- original_path_length = strlen(original_path);
-
- if(original_path[original_path_length-1] == '/') {
- original_path[original_path_length-1] = '\0';
- original_path_length--;
- }
-
- if (original_path_length != translated_path_length) {
- if (original_path_length < translated_path_length) {
- DEBUG(0, ("OOPS - tried to store stat cache entry for weird length paths [%s] %lu and [%s] %lu)!\n",
- original_path, (unsigned long)original_path_length, translated_path, (unsigned long)translated_path_length));
- SAFE_FREE(original_path);
- SAFE_FREE(translated_path);
- return;
- }
-
- /* we only want to store the first part of original_path,
- up to the length of translated_path */
-
- original_path[translated_path_length] = '\0';
- original_path_length = translated_path_length;
- }
-
- /*
- * Check this name doesn't exist in the cache before we
- * add it.
- */
-
- if ((hash_elem = hash_lookup(&stat_cache, original_path))) {
- found_scp = (stat_cache_entry *)(hash_elem->value);
- if (strcmp((found_scp->translated_path), orig_translated_path) == 0) {
- /* already in hash table */
- SAFE_FREE(original_path);
- SAFE_FREE(translated_path);
- return;
- }
- /* hash collision - remove before we re-add */
- hash_remove(&stat_cache, hash_elem);
- }
-
- /*
- * New entry.
- */
-
- if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)
- +original_path_length
- +translated_path_length)) == NULL) {
- DEBUG(0,("stat_cache_add: Out of memory !\n"));
- SAFE_FREE(original_path);
- SAFE_FREE(translated_path);
- return;
- }
-
- scp->original_path = scp->names;
- /* pointer into the structure... */
- scp->translated_path = scp->names + original_path_length + 1;
- safe_strcpy(scp->original_path, original_path, original_path_length);
- safe_strcpy(scp->translated_path, translated_path, translated_path_length);
- scp->translated_path_length = translated_path_length;
-
- hash_insert(&stat_cache, (char *)scp, original_path);
-
- SAFE_FREE(original_path);
- SAFE_FREE(translated_path);
-
- DEBUG(5,("stat_cache_add: Added entry %s -> %s\n", scp->original_path, scp->translated_path));
+ stat_cache_entry *scp;
+ stat_cache_entry *found_scp;
+ pstring orig_name;
+ pstring translated_path;
+ int namelen;
+ hash_element *hash_elem;
+
+ if (!lp_stat_cache()) return;
+
+ namelen = strlen(orig_translated_path);
+
+ /*
+ * Don't cache trivial valid directory entries.
+ */
+ if((*full_orig_name == '\0') || (strcmp(full_orig_name, ".") == 0) ||
+ (strcmp(full_orig_name, "..") == 0))
+ return;
+
+ /*
+ * If we are in case insentive mode, we need to
+ * store names that need no translation - else, it
+ * would be a waste.
+ */
+
+ if(case_sensitive && (strcmp(full_orig_name, orig_translated_path) == 0))
+ return;
+
+ /*
+ * Remove any trailing '/' characters from the
+ * translated path.
+ */
+
+ pstrcpy(translated_path, orig_translated_path);
+ if(translated_path[namelen-1] == '/') {
+ translated_path[namelen-1] = '\0';
+ namelen--;
+ }
+
+ /*
+ * We will only replace namelen characters
+ * of full_orig_name.
+ * StrnCpy always null terminates.
+ */
+
+ StrnCpy(orig_name, full_orig_name, MIN(namelen, sizeof(orig_name)-1));
+ if(!case_sensitive)
+ strupper( orig_name );
+
+ /*
+ * Check this name doesn't exist in the cache before we
+ * add it.
+ */
+
+ if ((hash_elem = hash_lookup(&stat_cache, orig_name))) {
+ found_scp = (stat_cache_entry *)(hash_elem->value);
+ if (strcmp((found_scp->names+found_scp->name_len+1), translated_path) == 0) {
+ return;
+ } else {
+ hash_remove(&stat_cache, hash_elem);
+ if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+ DEBUG(0,("stat_cache_add: Out of memory !\n"));
+ return;
+ }
+ pstrcpy(scp->names, orig_name);
+ pstrcpy((scp->names+namelen+1), translated_path);
+ scp->name_len = namelen;
+ hash_insert(&stat_cache, (char *)scp, orig_name);
+ }
+ return;
+ } else {
+
+ /*
+ * New entry.
+ */
+
+ if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+ DEBUG(0,("stat_cache_add: Out of memory !\n"));
+ return;
+ }
+ pstrcpy(scp->names, orig_name);
+ pstrcpy(scp->names+namelen+1, translated_path);
+ scp->name_len = namelen;
+ hash_insert(&stat_cache, (char *)scp, orig_name);
+ }
+
+ DEBUG(5,("stat_cache_add: Added entry %s -> %s\n", scp->names, (scp->names+scp->name_len+1)));
}
-/**
- * Look through the stat cache for an entry
- *
- * The hash-table's internals will promote it to the top if found.
- *
- * @param conn A connection struct to do the stat() with.
- * @param name The path we are attempting to cache, modified by this routine
- * to be correct as far as the cache can tell us
- * @param dirpath The path as far as the stat cache told us.
- * @param start A pointer into name, for where to 'start' in fixing the rest of the name up.
- * @param psd A stat buffer, NOT from the cache, but just a side-effect.
- *
- * @return True if we translated (and did a scuccessful stat on) the entire name.
- *
- */
+/****************************************************************************
+ Look through the stat cache for an entry - promote it to the top if found.
+ Return True if we translated (and did a scuccessful stat on) the entire name.
+*****************************************************************************/
-BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
+BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
char **start, SMB_STRUCT_STAT *pst)
{
- stat_cache_entry *scp;
- char *chk_name;
- size_t namelen;
- hash_element *hash_elem;
- char *sp;
- BOOL sizechanged = False;
- unsigned int num_components = 0;
-
- if (!lp_stat_cache())
- return False;
+ stat_cache_entry *scp;
+ char *trans_name;
+ pstring chk_name;
+ int namelen;
+ hash_element *hash_elem;
+ char *sp;
+
+ if (!lp_stat_cache())
+ return False;
- namelen = strlen(name);
-
- *start = name;
-
- DO_PROFILE_INC(statcache_lookups);
-
- /*
- * Don't lookup trivial valid directory entries.
- */
- if((*name == '\0') || (name[0] == '.' &&
- ((name[1] == '\0') ||
- (name[1] == '.' && name[1] == '\0'))))
- return False;
-
- if (conn->case_sensitive) {
- chk_name = strdup(name);
- if (!chk_name) {
- DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
- return False;
- }
-
- } else {
- chk_name = strdup_upper(name);
- if (!chk_name) {
- DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n"));
- return False;
- }
-
- /*
- * In some language encodings the length changes
- * if we uppercase. We need to treat this differently
- * below.
- */
- if (strlen(chk_name) != namelen)
- sizechanged = True;
- }
-
- while (1) {
- hash_elem = hash_lookup(&stat_cache, chk_name);
- if(hash_elem == NULL) {
- DEBUG(10,("stat_cache_lookup: lookup failed for name [%s]\n", chk_name ));
- /*
- * Didn't find it - remove last component for next try.
- */
- sp = strrchr_m(chk_name, '/');
- if (sp) {
- *sp = '\0';
- /*
- * Count the number of times we have done this,
- * we'll need it when reconstructing the string.
- */
- if (sizechanged)
- num_components++;
-
- } else {
- /*
- * We reached the end of the name - no match.
- */
- DO_PROFILE_INC(statcache_misses);
- SAFE_FREE(chk_name);
- return False;
- }
- if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
- || (strcmp(chk_name, "..") == 0)) {
- DO_PROFILE_INC(statcache_misses);
- SAFE_FREE(chk_name);
- return False;
- }
- } else {
- scp = (stat_cache_entry *)(hash_elem->value);
- DEBUG(10,("stat_cache_lookup: lookup succeeded for name [%s] -> [%s]\n", chk_name, scp->translated_path ));
- DO_PROFILE_INC(statcache_hits);
- if(SMB_VFS_STAT(conn,scp->translated_path, pst) != 0) {
- /* Discard this entry - it doesn't exist in the filesystem. */
- hash_remove(&stat_cache, hash_elem);
- SAFE_FREE(chk_name);
- return False;
- }
-
- if (!sizechanged) {
- memcpy(name, scp->translated_path, MIN(sizeof(pstring)-1, scp->translated_path_length));
- } else if (num_components == 0) {
- pstrcpy(name, scp->translated_path);
- } else {
- sp = strnrchr_m(name, '/', num_components);
- if (sp) {
- pstring last_component;
- pstrcpy(last_component, sp);
- pstrcpy(name, scp->translated_path);
- pstrcat(name, last_component);
- } else {
- pstrcpy(name, scp->translated_path);
- }
- }
-
- /* set pointer for 'where to start' on fixing the rest of the name */
- *start = &name[scp->translated_path_length];
- if(**start == '/')
- ++*start;
-
- pstrcpy(dirpath, scp->translated_path);
- SAFE_FREE(chk_name);
- return (namelen == scp->translated_path_length);
- }
- }
+ namelen = strlen(name);
+
+ *start = name;
+
+ DO_PROFILE_INC(statcache_lookups);
+
+ /*
+ * Don't lookup trivial valid directory entries.
+ */
+ if((*name == '\0') || (strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
+ DO_PROFILE_INC(statcache_misses);
+ return False;
+ }
+
+ pstrcpy(chk_name, name);
+ if(!case_sensitive)
+ strupper( chk_name );
+
+ while (1) {
+ hash_elem = hash_lookup(&stat_cache, chk_name);
+ if(hash_elem == NULL) {
+ /*
+ * Didn't find it - remove last component for next try.
+ */
+ sp = strrchr(chk_name, '/');
+ if (sp) {
+ *sp = '\0';
+ } else {
+ /*
+ * We reached the end of the name - no match.
+ */
+ DO_PROFILE_INC(statcache_misses);
+ return False;
+ }
+ if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
+ || (strcmp(chk_name, "..") == 0)) {
+ DO_PROFILE_INC(statcache_misses);
+ return False;
+ }
+ } else {
+ scp = (stat_cache_entry *)(hash_elem->value);
+ DO_PROFILE_INC(statcache_hits);
+ trans_name = scp->names+scp->name_len+1;
+ if(vfs_stat(conn,trans_name, pst) != 0) {
+ /* Discard this entry - it doesn't exist in the filesystem. */
+ hash_remove(&stat_cache, hash_elem);
+ return False;
+ }
+ memcpy(name, trans_name, scp->name_len);
+ *start = &name[scp->name_len];
+ if(**start == '/')
+ ++*start;
+ StrnCpy( dirpath, trans_name, name - (*start));
+ return (namelen == scp->name_len);
+ }
+ }
}
/*************************************************************************** **
@@ -324,8 +219,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
BOOL reset_stat_cache( void )
{
static BOOL initialised;
- if (!lp_stat_cache())
- return True;
+ if (!lp_stat_cache()) return True;
if (initialised) {
hash_clear(&stat_cache);
@@ -334,4 +228,4 @@ BOOL reset_stat_cache( void )
initialised = hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE,
(compare_function)(strcmp));
return initialised;
-}
+} /* reset_stat_cache */
diff --git a/source/smbd/tdbutil.c b/source/smbd/tdbutil.c
deleted file mode 100644
index cafcde20374..00000000000
--- a/source/smbd/tdbutil.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Main SMB server routines
- Copyright (C) Jeremy Allison 2003
- Copyright (C) Gerald (Jerry) Carter 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-
-/**********************************************************************
- logging function used by smbd to detect and remove corrupted tdb's
-**********************************************************************/
-
-void smbd_tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
-{
- va_list ap;
- char *ptr = NULL;
- BOOL decrement_smbd_count;
-
- va_start(ap, format);
- vasprintf(&ptr, format, ap);
- va_end(ap);
-
- if (!ptr || !*ptr)
- return;
-
- DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr));
-
- if (tdb->ecode == TDB_ERR_CORRUPT) {
- int ret;
-
- DEBUG(0,("tdb_log: TDB %s is corrupt. Removing file and stopping this process.\n",
- tdb->name ));
-
- become_root();
- ret = unlink(tdb->name);
- if ( ret ) {
- DEBUG(0,("ERROR: %s\n", strerror(errno)));
- }
- unbecome_root();
-
-
- /* if its not connections.tdb, then make sure we decrement the
- smbd count. If connections.tdb is bad, there's nothing we
- can do and everything will eventually shut down or clean
- up anyways */
-
- if ( strcmp(tdb->name, lock_path("connections.tdb")) == 0 )
- decrement_smbd_count = False;
- else
- decrement_smbd_count = True;
-
- /* now die */
-
- smb_panic2("corrupt tdb\n", decrement_smbd_count );
- }
-
- if (tdb->ecode == TDB_ERR_IO)
- {
- if ( strcmp(tdb->name, lock_path("connections.tdb")) == 0 )
- decrement_smbd_count = False;
- else
- decrement_smbd_count = True;
-
- smb_panic2( "i/o error on tdb.\n", decrement_smbd_count );
- }
-
- SAFE_FREE(ptr);
-}
-
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 25954d44336..def880d167c 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -1,10 +1,9 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-2003
- Copyright (C) Stefan (metze) Metzmacher 2003
-
Extensively modified by Andrew Tridgell, 1995
+ Copyright (C) Jeremy Allison 1994-2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,16 +23,18 @@
#include "includes.h"
extern int Protocol;
+extern BOOL case_sensitive;
extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
extern uint32 global_client_caps;
-extern struct current_user current_user;
+extern pstring global_myname;
#define get_file_size(sbuf) ((sbuf).st_size)
/* given a stat buffer return the allocated size on disk, taking into
account sparse files */
+
SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
SMB_BIG_UINT ret;
@@ -49,381 +50,19 @@ SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
}
/****************************************************************************
- Utility functions for dealing with extended attributes.
-****************************************************************************/
-
-static const char *prohibited_ea_names[] = {
- SAMBA_POSIX_INHERITANCE_EA_NAME,
- SAMBA_XATTR_DOS_ATTRIB,
- NULL
-};
-
-/****************************************************************************
- Refuse to allow clients to overwrite our private xattrs.
-****************************************************************************/
-
-static BOOL samba_private_attr_name(const char *unix_ea_name)
-{
- int i;
-
- for (i = 0; prohibited_ea_names[i]; i++) {
- if (strequal( prohibited_ea_names[i], unix_ea_name))
- return True;
- }
- return False;
-}
-
-struct ea_list {
- struct ea_list *next, *prev;
- struct ea_struct ea;
-};
-
-/****************************************************************************
- Get one EA value. Fill in a struct ea_struct.
-****************************************************************************/
-
-static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
- const char *fname, char *ea_name, struct ea_struct *pea)
-{
- /* Get the value of this xattr. Max size is 64k. */
- size_t attr_size = 256;
- char *val = NULL;
- ssize_t sizeret;
-
- again:
-
- val = talloc_realloc(mem_ctx, val, attr_size);
- if (!val) {
- return False;
- }
-
- if (fsp && fsp->fd != -1) {
- sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
- } else {
- sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
- }
-
- if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
- attr_size = 65536;
- goto again;
- }
-
- if (sizeret == -1) {
- return False;
- }
-
- DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
- dump_data(10, val, sizeret);
-
- pea->flags = 0;
- if (strnequal(ea_name, "user.", 5)) {
- pea->name = &ea_name[5];
- } else {
- pea->name = ea_name;
- }
- pea->value.data = val;
- pea->value.length = (size_t)sizeret;
- return True;
-}
-
-/****************************************************************************
- Return a linked list of the total EA's. Plus the total size
-****************************************************************************/
-
-static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
-{
- /* Get a list of all xattrs. Max namesize is 64k. */
- size_t ea_namelist_size = 1024;
- char *ea_namelist;
- char *p;
- ssize_t sizeret;
- int i;
- struct ea_list *ea_list_head = NULL;
-
- *pea_total_len = 0;
-
- if (!lp_ea_support(SNUM(conn))) {
- return NULL;
- }
-
- for (i = 0, ea_namelist = talloc(mem_ctx, ea_namelist_size); i < 6;
- ea_namelist = talloc_realloc(mem_ctx, ea_namelist, ea_namelist_size), i++) {
- if (fsp && fsp->fd != -1) {
- sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
- } else {
- sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
- }
-
- if (sizeret == -1 && errno == ERANGE) {
- ea_namelist_size *= 2;
- } else {
- break;
- }
- }
-
- if (sizeret == -1)
- return NULL;
-
- DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
-
- if (sizeret) {
- for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
- struct ea_list *listp, *tmp;
-
- if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
- continue;
-
- listp = talloc(mem_ctx, sizeof(struct ea_list));
- if (!listp)
- return NULL;
-
- if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
- return NULL;
- }
-
- {
- fstring dos_ea_name;
- push_ascii_fstring(dos_ea_name, listp->ea.name);
- *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
- DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
- *pea_total_len, dos_ea_name,
- (unsigned int)listp->ea.value.length ));
- }
- DLIST_ADD_END(ea_list_head, listp, tmp);
- }
- /* Add on 4 for total length. */
- if (*pea_total_len) {
- *pea_total_len += 4;
- }
- }
-
- DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
- return ea_list_head;
-}
-
-/****************************************************************************
- Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
- that was filled.
-****************************************************************************/
-
-static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
- connection_struct *conn, files_struct *fsp, const char *fname)
-{
- unsigned int ret_data_size = 4;
- char *p = pdata;
- size_t total_ea_len;
- TALLOC_CTX *mem_ctx;
- struct ea_list *ea_list;
-
- SMB_ASSERT(total_data_size >= 4);
-
- SIVAL(pdata,0,0);
- if (!lp_ea_support(SNUM(conn))) {
- return 4;
- }
- mem_ctx = talloc_init("fill_ea_buffer");
- if (!mem_ctx) {
- return 4;
- }
-
- ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
- if (!ea_list) {
- talloc_destroy(mem_ctx);
- return 4;
- }
-
- if (total_ea_len > total_data_size) {
- talloc_destroy(mem_ctx);
- return 4;
- }
-
- for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
- size_t dos_namelen;
- fstring dos_ea_name;
- push_ascii_fstring(dos_ea_name, ea_list->ea.name);
- dos_namelen = strlen(dos_ea_name);
- if (dos_namelen > 255 || dos_namelen == 0) {
- break;
- }
- if (ea_list->ea.value.length > 65535) {
- break;
- }
- if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
- break;
- }
-
- /* We know we have room. */
- SCVAL(p,0,ea_list->ea.flags);
- SCVAL(p,1,dos_namelen);
- SSVAL(p,2,ea_list->ea.value.length);
- fstrcpy(p+4, dos_ea_name);
- memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
-
- total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
- p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
- }
-
- ret_data_size = PTR_DIFF(p, pdata);
- DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
- ret_data_size, total_ea_len ));
- talloc_destroy(mem_ctx);
- SIVAL(pdata,0,ret_data_size);
- return ret_data_size;
-}
-
-static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
-{
- size_t total_ea_len = 0;
- TALLOC_CTX *mem_ctx = NULL;
-
- if (!lp_ea_support(SNUM(conn))) {
- return 0;
- }
- mem_ctx = talloc_init("estimate_ea_size");
- (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
- talloc_destroy(mem_ctx);
- return total_ea_len;
-}
-
-/****************************************************************************
- Ensure the EA name is case insensitive by matching any existing EA name.
-****************************************************************************/
-
-static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
-{
- size_t total_ea_len;
- TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
- struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
-
- for (; ea_list; ea_list = ea_list->next) {
- if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
- DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
- &unix_ea_name[5], ea_list->ea.name));
- safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
- break;
- }
- }
- talloc_destroy(mem_ctx);
-}
-
-/****************************************************************************
- Set or delete an extended attribute.
-****************************************************************************/
-
-static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
- char *pdata, int total_data)
-{
- unsigned int namelen;
- unsigned int ealen;
- int ret;
- fstring unix_ea_name;
-
- if (!lp_ea_support(SNUM(conn))) {
- return NT_STATUS_EAS_NOT_SUPPORTED;
- }
-
- if (total_data < 8) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (IVAL(pdata,0) > total_data) {
- DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- pdata += 4;
- namelen = CVAL(pdata,1);
- ealen = SVAL(pdata,2);
- pdata += 4;
- if (total_data < 8 + namelen + 1 + ealen) {
- DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
- (unsigned int)total_data, namelen, ealen));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (pdata[namelen] != '\0') {
- DEBUG(10,("set_ea: ea name not null terminated\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
- pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
- pdata += (namelen + 1);
-
- canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
-
- DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
- if (ealen) {
- DEBUG(10,("set_ea: data :\n"));
- dump_data(10, pdata, ealen);
- }
-
- if (samba_private_attr_name(unix_ea_name)) {
- DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (ealen == 0) {
- /* Remove the attribute. */
- if (fsp && (fsp->fd != -1)) {
- DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
- ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
- } else {
- DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
- }
-#ifdef ENOATTR
- /* Removing a non existent attribute always succeeds. */
- if (ret == -1 && errno == ENOATTR) {
- DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
- ret = 0;
- }
-#endif
- } else {
- if (fsp && (fsp->fd != -1)) {
- DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
- ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
- } else {
- DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
- }
- }
-
- if (ret == -1) {
-#ifdef ENOTSUP
- if (errno == ENOTSUP) {
- return NT_STATUS_EAS_NOT_SUPPORTED;
- }
-#endif
- return map_nt_error_from_unix(errno);
- }
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
set correctly for the type of call.
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_trans2_replies(char *outbuf,
- int bufsize,
- char *params,
- int paramsize,
- char *pdata,
- int datasize)
+static int send_trans2_replies(char *outbuf, int bufsize, char *params, int paramsize, char *pdata, int datasize)
{
/* As we are using a protocol > LANMAN1 then the max_send
- variable must have been set in the sessetupX call.
- This takes precedence over the max_xmit field in the
- global struct. These different max_xmit variables should
- be merged as this is now too confusing */
+ variable must have been set in the sessetupX call.
+ This takes precedence over the max_xmit field in the
+ global struct. These different max_xmit variables should
+ be merged as this is now too confusing */
extern int max_send;
int data_to_send = datasize;
@@ -435,11 +74,12 @@ static int send_trans2_replies(char *outbuf,
int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
int data_alignment_offset = 0;
- /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
-
+ /* Initially set the wcnt area to be 10 - this is true for all
+ trans2 replies */
set_message(outbuf,10,0,True);
- /* If there genuinely are no parameters or data to send just send the empty packet */
+ /* If there genuinely are no parameters or data to send just send
+ the empty packet */
if(params_to_send == 0 && data_to_send == 0) {
if (!send_smb(smbd_server_fd(),outbuf))
@@ -464,6 +104,7 @@ static int send_trans2_replies(char *outbuf,
useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
+
while (params_to_send || data_to_send) {
/* Calculate whether we will totally or partially fill this packet */
@@ -486,8 +127,7 @@ static int send_trans2_replies(char *outbuf,
SSVAL(outbuf,smb_tdrcnt,datasize);
/* Calculate how many parameters and data we can fit into
- * this packet. Parameters get precedence
- */
+ this packet. Parameters get precedence */
params_sent_thistime = MIN(params_to_send,useable_space);
data_sent_thistime = useable_space - params_sent_thistime;
@@ -526,6 +166,7 @@ static int send_trans2_replies(char *outbuf,
memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
/* Copy in the data bytes */
+
if(data_sent_thistime)
memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
data_alignment_offset,pd,data_sent_thistime);
@@ -546,6 +187,7 @@ static int send_trans2_replies(char *outbuf,
data_to_send -= data_sent_thistime;
/* Sanity check */
+
if(params_to_send < 0 || data_to_send < 0) {
DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
params_to_send, data_to_send));
@@ -561,7 +203,7 @@ static int send_trans2_replies(char *outbuf,
****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *params = *pparams;
int16 open_mode;
@@ -575,7 +217,9 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
int16 open_ofun;
int32 open_size;
char *pname;
+
pstring fname;
+ mode_t unixmode;
SMB_OFF_T size=0;
int fmode=0,mtime=0,rmode;
SMB_INO_T inode = 0;
@@ -583,7 +227,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
int smb_action = 0;
BOOL bad_path = False;
files_struct *fsp;
- NTSTATUS status;
/*
* Ensure we have enough parameters to perform the operation.
@@ -604,30 +247,31 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
open_size = IVAL(params,14);
pname = &params[28];
- if (IS_IPC(conn))
- return(ERROR_DOS(ERRSRV,ERRaccess));
-
- srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ pstrcpy(fname, pname);
DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
fname,open_mode, open_attr, open_ofun, open_size));
+ if (IS_IPC(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
+
/* XXXX we need to handle passed times, sattr and flags */
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn)) {
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
- oplock_request, &rmode,&smb_action);
+ unixmode = unix_mode(conn,open_attr | aARCH, fname);
+
+ fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
+ oplock_request, &rmode,&smb_action);
if (!fsp) {
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
size = get_file_size(sbuf);
@@ -679,15 +323,9 @@ static BOOL exact_match(char *str,char *mask, BOOL case_sig)
{
if (mask[0] == '.' && mask[1] == 0)
return False;
- if (case_sig)
+ if (case_sig)
return strcmp(str,mask)==0;
- if (StrCaseCmp(str,mask) != 0) {
- return False;
- }
- if (ms_has_wild(str)) {
- return False;
- }
- return True;
+ return strcasecmp(str,mask) == 0;
}
/****************************************************************************
@@ -796,12 +434,12 @@ static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *ps
}
/****************************************************************************
- Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
+checks for SMB_TIME_NO_CHANGE and if not found
+calls interpret_long_date
****************************************************************************/
-
time_t interpret_long_unix_date(char *p)
{
- DEBUG(10,("interpret_long_unix_date\n"));
+ DEBUG(1,("interpret_long_unix_date\n"));
if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
return -1;
@@ -815,7 +453,6 @@ time_t interpret_long_unix_date(char *p)
****************************************************************************/
static BOOL get_lanman2_dir_entry(connection_struct *conn,
- void *inbuf, void *outbuf,
char *path_mask,int dirtype,int info_level,
int requires_resume_key,
BOOL dont_descend,char **ppdata,
@@ -823,17 +460,17 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
BOOL *out_of_space, BOOL *got_exact_match,
int *last_name_off)
{
- const char *dname;
+ char *dname;
BOOL found = False;
SMB_STRUCT_STAT sbuf;
pstring mask;
pstring pathreal;
pstring fname;
- char *p, *q, *pdata = *ppdata;
+ char *p, *pdata = *ppdata;
uint32 reskey=0;
int prev_dirpos=0;
int mode=0;
- SMB_OFF_T file_size = 0;
+ SMB_OFF_T size = 0;
SMB_BIG_UINT allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
@@ -849,7 +486,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
if (!conn->dirptr)
return(False);
- p = strrchr_m(path_mask,'/');
+ p = strrchr(path_mask,'/');
if(p != NULL) {
if(p[1] == '\0')
pstrcpy(mask,"*.*");
@@ -882,8 +519,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(fname,dname);
- if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
- got_match = mask_match(fname, mask, conn->case_sensitive);
+ if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
+ got_match = mask_match(fname, mask, case_sensitive);
if(!got_match && !mangle_is_8_3(fname, False)) {
@@ -897,8 +534,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstring newname;
pstrcpy( newname, fname);
mangle_map( newname, True, False, SNUM(conn));
- if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
- got_match = mask_match(newname, mask, conn->case_sensitive);
+ if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
+ got_match = mask_match(newname, mask, case_sensitive);
}
if(got_match) {
@@ -912,12 +549,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcat(pathreal,dname);
if (INFO_LEVEL_IS_UNIX(info_level)) {
- if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
+ if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
continue;
}
- } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
+ } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as
* directories */
@@ -945,7 +582,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
continue;
}
- file_size = get_file_size(sbuf);
+ size = get_file_size(sbuf);
allocation_size = get_allocation_size(NULL,&sbuf);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
@@ -958,7 +595,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
if(mode & aDIR)
- file_size = 0;
+ size = 0;
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
@@ -974,8 +611,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
switch (info_level) {
- case SMB_INFO_STANDARD:
- DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
+ case 1:
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
@@ -983,31 +619,16 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l1_fdateCreation,cdate);
put_dos_date2(p,l1_fdateLastAccess,adate);
put_dos_date2(p,l1_fdateLastWrite,mdate);
- SIVAL(p,l1_cbFile,(uint32)file_size);
+ SIVAL(p,l1_cbFile,(uint32)size);
SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l1_attrFile,mode);
- p += l1_achName;
- nameptr = p;
- p += align_string(outbuf, p, 0);
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
- if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
- if (len > 2) {
- SCVAL(nameptr, -1, len - 2);
- } else {
- SCVAL(nameptr, -1, 0);
- }
- } else {
- if (len > 1) {
- SCVAL(nameptr, -1, len - 1);
- } else {
- SCVAL(nameptr, -1, 0);
- }
- }
- p += len;
+ SCVAL(p,l1_cchName,strlen(fname));
+ pstrcpy(p + l1_achName, fname);
+ nameptr = p + l1_achName;
+ p += l1_achName + strlen(fname) + 1;
break;
- case SMB_INFO_QUERY_EA_SIZE:
- DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
+ case 2:
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
@@ -1015,222 +636,142 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l2_fdateCreation,cdate);
put_dos_date2(p,l2_fdateLastAccess,adate);
put_dos_date2(p,l2_fdateLastWrite,mdate);
- SIVAL(p,l2_cbFile,(uint32)file_size);
+ SIVAL(p,l2_cbFile,(uint32)size);
SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l2_attrFile,mode);
- {
- unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
- SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
- }
- p += l2_achName;
- nameptr = p - 1;
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
- if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
- if (len > 2) {
- len -= 2;
- } else {
- len = 0;
- }
- } else {
- if (len > 1) {
- len -= 1;
- } else {
- len = 0;
- }
+ SIVAL(p,l2_cbList,0); /* No extended attributes */
+ SCVAL(p,l2_cchName,strlen(fname));
+ pstrcpy(p + l2_achName, fname);
+ nameptr = p + l2_achName;
+ p += l2_achName + strlen(fname) + 1;
+ break;
+
+ case 3:
+ SIVAL(p,0,reskey);
+ put_dos_date2(p,4,cdate);
+ put_dos_date2(p,8,adate);
+ put_dos_date2(p,12,mdate);
+ SIVAL(p,16,(uint32)size);
+ SIVAL(p,20,(uint32)allocation_size);
+ SSVAL(p,24,mode);
+ SIVAL(p,26,4);
+ SCVAL(p,30,strlen(fname));
+ pstrcpy(p+31, fname);
+ nameptr = p+31;
+ p += 31 + strlen(fname) + 1;
+ break;
+
+ case 4:
+ if(requires_resume_key) {
+ SIVAL(p,0,reskey);
+ p += 4;
}
- SCVAL(nameptr,0,len);
- p += len;
- SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
+ SIVAL(p,0,33+strlen(fname)+1);
+ put_dos_date2(p,4,cdate);
+ put_dos_date2(p,8,adate);
+ put_dos_date2(p,12,mdate);
+ SIVAL(p,16,(uint32)size);
+ SIVAL(p,20,(uint32)allocation_size);
+ SSVAL(p,24,mode);
+ SCVAL(p,32,strlen(fname));
+ pstrcpy(p + 33, fname);
+ nameptr = p+33;
+ p += 33 + strlen(fname) + 1;
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
was_8_3 = mangle_is_8_3(fname, True);
- p += 4;
+ len = 94+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
SIVAL(p,0,reskey); p += 4;
put_long_date(p,cdate); p += 8;
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size); p += 8;
- SOFF_T(p,0,allocation_size); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
SIVAL(p,0,nt_extmode); p += 4;
- q = p; p += 4; /* q is placeholder for name length. */
- {
- unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
- SIVAL(p,0,ea_size); /* Extended attributes */
- p += 4;
- }
- /* Clear the short name buffer. This is
+ SIVAL(p,0,strlen(fname)); p += 4;
+ SIVAL(p,0,0); p += 4;
+ /* Clear the short name buffer. This is
* IMPORTANT as not doing so will trigger
* a Win2k client bug. JRA.
*/
memset(p,'\0',26);
- if (!was_8_3 && lp_manglednames(SNUM(conn))) {
- pstring mangled_name;
- pstrcpy(mangled_name, fname);
- mangle_map(mangled_name,True,True,SNUM(conn));
- mangled_name[12] = 0;
- len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
- SSVAL(p, 0, len);
+ if (!was_8_3) {
+ fstring tmpname;
+ fstrcpy(tmpname,fname);
+ mangle_map(tmpname,True,True,SNUM(conn));
+ strupper(tmpname);
+ fstrcpy(p+2,tmpname);
+ SSVAL(p, 0, strlen(tmpname));
} else {
SSVAL(p,0,0);
*(p+2) = 0;
}
p += 2 + 24;
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(q,0,len);
- p += len;
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
+ /* nameptr = p; */
+ pstrcpy(p,fname); p += strlen(p);
p = pdata + len;
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
- p += 4;
+ len = 64+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
SIVAL(p,0,reskey); p += 4;
put_long_date(p,cdate); p += 8;
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size); p += 8;
- SOFF_T(p,0,allocation_size); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
SIVAL(p,0,nt_extmode); p += 4;
- len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(p,0,len);
- p += 4 + len;
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
+ SIVAL(p,0,strlen(fname)); p += 4;
+ pstrcpy(p,fname);
p = pdata + len;
break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
- p += 4;
+ len = 68+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
SIVAL(p,0,reskey); p += 4;
put_long_date(p,cdate); p += 8;
put_long_date(p,adate); p += 8;
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size); p += 8;
- SOFF_T(p,0,allocation_size); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
SIVAL(p,0,nt_extmode); p += 4;
- q = p; p += 4; /* q is placeholder for name length. */
- {
- unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
- SIVAL(p,0,ea_size); /* Extended attributes */
- p +=4;
- }
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(q, 0, len);
- p += len;
-
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
+ SIVAL(p,0,strlen(fname)); p += 4;
+ SIVAL(p,0,0); p += 4;
+ pstrcpy(p,fname);
p = pdata + len;
break;
case SMB_FIND_FILE_NAMES_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
- p += 4;
- SIVAL(p,0,reskey); p += 4;
- p += 4;
- /* this must *not* be null terminated or w2k gets in a loop trying to set an
- acl on a dir (tridge) */
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(p, -4, len);
- p += len;
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
- break;
-
- case SMB_FIND_ID_FULL_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
- p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size); p += 8;
- SOFF_T(p,0,allocation_size); p += 8;
- SIVAL(p,0,nt_extmode); p += 4;
- q = p; p += 4; /* q is placeholder for name length. */
- {
- unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
- SIVAL(p,0,ea_size); /* Extended attributes */
- p +=4;
- }
- SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
- SIVAL(p,0,sbuf.st_dev); p += 4;
- SIVAL(p,0,sbuf.st_ino); p += 4;
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(q, 0, len);
- p += len;
- len = PTR_DIFF(p, pdata);
+ len = 12+strlen(fname);
len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
- break;
-
- case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
- was_8_3 = mangle_is_8_3(fname, True);
- p += 4;
+ SIVAL(p,0,len); p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,file_size); p += 8;
- SOFF_T(p,0,allocation_size); p += 8;
- SIVAL(p,0,nt_extmode); p += 4;
- q = p; p += 4; /* q is placeholder for name length */
- {
- unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
- SIVAL(p,0,ea_size); /* Extended attributes */
- p +=4;
- }
- /* Clear the short name buffer. This is
- * IMPORTANT as not doing so will trigger
- * a Win2k client bug. JRA.
- */
- memset(p,'\0',26);
- if (!was_8_3 && lp_manglednames(SNUM(conn))) {
- pstring mangled_name;
- pstrcpy(mangled_name, fname);
- mangle_map(mangled_name,True,True,SNUM(conn));
- mangled_name[12] = 0;
- len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
- SSVAL(p, 0, len);
- } else {
- SSVAL(p,0,0);
- *(p+2) = 0;
- }
- p += 26;
- SSVAL(p,0,0); p += 2; /* Reserved ? */
- SIVAL(p,0,sbuf.st_dev); p += 4;
- SIVAL(p,0,sbuf.st_ino); p += 4;
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
- SIVAL(q,0,len);
- p += len;
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
+ SIVAL(p,0,strlen(fname)); p += 4;
+ pstrcpy(p,fname);
p = pdata + len;
break;
/* CIFS UNIX Extension. */
case SMB_FIND_FILE_UNIX:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
- p+= 4;
+ len = 108+strlen(fname)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
+ /* +1 to be sure to transmit the termination of fname */
+ len = (len + 3) & ~3;
+
+ SIVAL(p,0,len); p+= 4; /* Offset from this structure to the beginning of the next one */
SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
/* Begin of SMB_QUERY_FILE_UNIX_BASIC */
@@ -1240,7 +781,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
p+= 8;
- put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
+ put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
p+= 24;
@@ -1275,14 +816,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,4,0);
p+= 8;
- len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
- p += len;
-
- len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
- p = pdata + len;
/* End of SMB_QUERY_FILE_UNIX_BASIC */
+ pstrcpy(p,fname);
+ p=pdata+len;
break;
@@ -1312,7 +848,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
****************************************************************************/
static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
@@ -1322,12 +858,12 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
- int dirtype = SVAL(params,0);
- int maxentries = SVAL(params,2);
- BOOL close_after_first = BITSETW(params+4,0);
- BOOL close_if_end = BITSETW(params+4,1);
- BOOL requires_resume_key = BITSETW(params+4,2);
- int info_level = SVAL(params,6);
+ int dirtype;
+ int maxentries;
+ BOOL close_after_first;
+ BOOL close_if_end;
+ BOOL requires_resume_key;
+ int info_level;
pstring directory;
pstring mask;
char *p, *wcard;
@@ -1341,27 +877,33 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
int space_remaining;
BOOL bad_path = False;
SMB_STRUCT_STAT sbuf;
- NTSTATUS ntstatus = NT_STATUS_OK;
if (total_params < 12)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
*directory = *mask = 0;
+ dirtype = SVAL(params,0);
+ maxentries = SVAL(params,2);
+ close_after_first = BITSETW(params+4,0);
+ close_if_end = BITSETW(params+4,1);
+ requires_resume_key = BITSETW(params+4,2);
+ info_level = SVAL(params,6);
+
DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
-close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
+close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
info_level, max_data_bytes));
switch (info_level) {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
case SMB_FIND_FILE_DIRECTORY_INFO:
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
case SMB_FIND_FILE_NAMES_INFO:
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- case SMB_FIND_ID_FULL_DIRECTORY_INFO:
- case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
break;
case SMB_FIND_FILE_UNIX:
if (!lp_unix_extensions())
@@ -1371,19 +913,28 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return(ERROR_DOS(ERRDOS,ERRunknownlevel));
}
- srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus);
- if (!NT_STATUS_IS_OK(ntstatus)) {
- return ERROR_NT(ntstatus);
- }
+ pstrcpy(directory, params + 12); /* Complete directory path with wildcard mask appended */
RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+ DEBUG(5,("path=%s\n",directory));
+
unix_convert(directory,conn,0,&bad_path,&sbuf);
if(!check_name(directory,conn)) {
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ set_bad_path_error(errno, bad_path);
+
+#if 0
+ /* Ugly - NT specific hack - maybe not needed ? (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && (get_remote_arch() == RA_WINNT)) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+#endif
+
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
- p = strrchr_m(directory,'/');
+ p = strrchr(directory,'/');
if(p == NULL) {
/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
if((directory[0] == '.') && (directory[1] == '\0'))
@@ -1401,13 +952,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
pdata = Realloc(*ppdata, max_data_bytes + 1024);
if( pdata == NULL )
return(ERROR_DOS(ERRDOS,ERRnomem));
-
*ppdata = pdata;
memset((char *)pdata,'\0',max_data_bytes + 1024);
/* Realloc the params space */
params = Realloc(*pparams, 10);
- if (params == NULL)
+ if( params == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
*pparams = params;
@@ -1432,7 +982,8 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
+
+ if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
dont_descend = True;
p = pdata;
@@ -1444,13 +995,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
/* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
+
if (space_remaining < DIRLEN_GUESS && numentries > 0) {
out_of_space = True;
finished = False;
} else {
- finished = !get_lanman2_dir_entry(conn,
- inbuf, outbuf,
- mask,dirtype,info_level,
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
requires_resume_key,dont_descend,
&p,pdata,space_remaining, &out_of_space, &got_exact_match,
&last_name_off);
@@ -1476,6 +1026,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
}
/* Check if we can close the dirptr */
+
if(close_after_first || (finished && close_if_end)) {
DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
dptr_close(&dptr_num);
@@ -1528,7 +1079,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
****************************************************************************/
static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
@@ -1538,14 +1089,14 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
- int dptr_num = SVAL(params,0);
- int maxentries = SVAL(params,2);
- uint16 info_level = SVAL(params,4);
- uint32 resume_key = IVAL(params,6);
- BOOL close_after_request = BITSETW(params+10,0);
- BOOL close_if_end = BITSETW(params+10,1);
- BOOL requires_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
+ int dptr_num;
+ int maxentries;
+ uint16 info_level;
+ uint32 resume_key;
+ BOOL close_after_request;
+ BOOL close_if_end;
+ BOOL requires_resume_key;
+ BOOL continue_bit;
pstring resume_name;
pstring mask;
pstring directory;
@@ -1557,17 +1108,22 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
BOOL dont_descend = False;
BOOL out_of_space = False;
int space_remaining;
- NTSTATUS ntstatus = NT_STATUS_OK;
if (total_params < 12)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ dptr_num = SVAL(params,0);
+ maxentries = SVAL(params,2);
+ info_level = SVAL(params,4);
+ resume_key = IVAL(params,6);
+ close_after_request = BITSETW(params+10,0);
+ close_if_end = BITSETW(params+10,1);
+ requires_resume_key = BITSETW(params+10,2);
+ continue_bit = BITSETW(params+10,3);
+
*mask = *directory = *resume_name = 0;
- srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus);
- if (!NT_STATUS_IS_OK(ntstatus)) {
- return ERROR_NT(ntstatus);
- }
+ pstrcpy( resume_name, params+12);
DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
close_after_request=%d, close_if_end = %d requires_resume_key = %d \
@@ -1576,8 +1132,10 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
requires_resume_key, resume_key, resume_name, continue_bit, info_level));
switch (info_level) {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
case SMB_FIND_FILE_DIRECTORY_INFO:
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
case SMB_FIND_FILE_NAMES_INFO:
@@ -1595,14 +1153,13 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
if(pdata == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
- *ppdata = pdata;
+ *ppdata = pdata;
memset((char *)pdata,'\0',max_data_bytes + 1024);
/* Realloc the params space */
params = Realloc(*pparams, 6*SIZEOFWORD);
if( params == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
-
*pparams = params;
/* Check that the dptr is valid */
@@ -1616,7 +1173,6 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
return ERROR_DOS(ERRDOS,ERRnofiles);
}
-
pstrcpy(mask, p);
pstrcpy(directory,conn->dirpath);
@@ -1624,15 +1180,13 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
dirtype = dptr_attr(dptr_num);
DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
- dptr_num, mask, dirtype,
- (long)conn->dirptr,
- TellDir(conn->dirptr)));
+ dptr_num, mask, dirtype, (long)conn->dirptr, TellDir(conn->dirptr)));
/* We don't need to check for VOL here as this is returned by
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
+ if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
dont_descend = True;
p = pdata;
@@ -1659,33 +1213,30 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
*/
int current_pos, start_pos;
- const char *dname = NULL;
- pstring dname_pstring;
+ char *dname = NULL;
void *dirptr = conn->dirptr;
start_pos = TellDir(dirptr);
+
for(current_pos = start_pos; current_pos >= 0; current_pos--) {
DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
SeekDir(dirptr, current_pos);
dname = ReadDirName(dirptr);
- if (dname) {
- /*
- * Remember, mangle_map is called by
- * get_lanman2_dir_entry(), so the resume name
- * could be mangled. Ensure we do the same
- * here.
- */
-
- /* make sure we get a copy that mangle_map can modify */
- pstrcpy(dname_pstring, dname);
- mangle_map( dname_pstring, False, True, SNUM(conn));
-
- if(strcsequal( resume_name, dname_pstring)) {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
- }
+ /*
+ * Remember, name_map_mangle is called by
+ * get_lanman2_dir_entry(), so the resume name
+ * could be mangled. Ensure we do the same
+ * here.
+ */
+
+ if(dname != NULL)
+ mangle_map( dname, False, True, SNUM(conn));
+
+ if(dname && strcsequal( resume_name, dname)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
}
}
@@ -1699,23 +1250,19 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
/*
- * Remember, mangle_map is called by
+ * Remember, name_map_mangle is called by
* get_lanman2_dir_entry(), so the resume name
* could be mangled. Ensure we do the same
* here.
*/
- if(dname) {
- /* make sure we get a copy that mangle_map can modify */
-
- pstrcpy(dname_pstring, dname);
- mangle_map(dname_pstring, False, True, SNUM(conn));
+ if(dname != NULL)
+ mangle_map( dname, False, True, SNUM(conn));
- if(strcsequal( resume_name, dname_pstring)) {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
- }
+ if(dname && strcsequal( resume_name, dname)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
}
} /* end for */
} /* end if current_pos */
@@ -1726,16 +1273,15 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
/* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
+
if (space_remaining < DIRLEN_GUESS && numentries > 0) {
out_of_space = True;
finished = False;
} else {
- finished = !get_lanman2_dir_entry(conn,
- inbuf, outbuf,
- mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_name_off);
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+ &last_name_off);
}
if (finished && out_of_space)
@@ -1763,6 +1309,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
dptr_close(&dptr_num); /* This frees up the saved mask */
}
+
/* Set up the return parameter block */
SSVAL(params,0,numentries);
SSVAL(params,2,finished);
@@ -1785,24 +1332,26 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
-static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize,
+static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **pparams, int total_params, char **ppdata, int total_data)
{
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *pdata = *ppdata;
char *params = *pparams;
- uint16 info_level = SVAL(params,0);
- int data_len, len;
+ uint16 info_level;
+ int data_len;
SMB_STRUCT_STAT st;
char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
- int quota_flag = 0;
+ if (total_params < 2)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ info_level = SVAL(params,0);
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
- if(SMB_VFS_STAT(conn,".",&st)!=0) {
+ if(vfs_stat(conn,".",&st)!=0) {
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
@@ -1815,83 +1364,70 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
memset((char *)pdata,'\0',max_data_bytes + 1024);
switch (info_level) {
- case SMB_INFO_ALLOCATION:
+ case 1:
{
- SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
+ SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
- block_size = lp_block_size(snum);
- if (bsize < block_size) {
- SMB_BIG_UINT factor = block_size/bsize;
- bsize = block_size;
- dsize /= factor;
- dfree /= factor;
- }
- if (bsize > block_size) {
- SMB_BIG_UINT factor = bsize/block_size;
- bsize = block_size;
- dsize *= factor;
- dfree *= factor;
- }
- bytes_per_sector = 512;
- sectors_per_unit = bsize/bytes_per_sector;
-
- DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
-cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
- (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
-
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
SIVAL(pdata,l1_idFileSystem,st.st_dev);
- SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
+ SIVAL(pdata,l1_cSectorUnit,bsize/512);
SIVAL(pdata,l1_cUnit,dsize);
SIVAL(pdata,l1_cUnitAvail,dfree);
- SSVAL(pdata,l1_cbSector,bytes_per_sector);
+ SSVAL(pdata,l1_cbSector,512);
+ DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
+ (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
+ (unsigned int)dfree, 512));
break;
}
- case SMB_INFO_VOLUME:
+ case 2:
+ {
/* Return volume name */
+ int volname_len = MIN(strlen(vname),11);
+ data_len = l2_vol_szVolLabel + volname_len + 1;
/*
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
- len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
- SCVAL(pdata,l2_vol_cch,len);
- data_len = l2_vol_szVolLabel + len;
+ SCVAL(pdata,l2_vol_cch,volname_len);
+ StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
- (unsigned)st.st_ctime, len, vname));
+ (unsigned)st.st_ctime, volname_len,
+ pdata+l2_vol_szVolLabel));
break;
+ }
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
-
-
-#if defined(HAVE_SYS_QUOTAS)
- quota_flag = FILE_VOLUME_QUOTAS;
-#endif
-
+ {
+ int fstype_len;
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
- quota_flag); /* FS ATTRIBUTES */
+ (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
+#if 0 /* Old code. JRA. */
+ SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
+ SIVAL(pdata,0,0x700FF);
+#endif /* Old code. */
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
and will think we can't do long filenames */
- len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
- SIVAL(pdata,8,len);
- data_len = 12 + len;
+ fstype_len = dos_PutUniCode(pdata+12,unix_to_dos_static(fstype),sizeof(pstring), False);
+ SIVAL(pdata,8,fstype_len);
+ data_len = 12 + fstype_len;
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
break;
+ }
case SMB_QUERY_FS_LABEL_INFO:
case SMB_FS_LABEL_INFORMATION:
- len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
- data_len = 4 + len;
- SIVAL(pdata,0,len);
+ data_len = 4 + strlen(vname);
+ SIVAL(pdata,0,strlen(vname));
+ pstrcpy(pdata+4,vname);
break;
case SMB_QUERY_FS_VOLUME_INFO:
case SMB_FS_VOLUME_INFORMATION:
-
/*
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
@@ -1899,11 +1435,24 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
(str_checksum(local_machine)<<16));
- len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
- SIVAL(pdata,12,len);
- data_len = 18+len;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
- (int)strlen(vname),vname, lp_servicename(snum)));
+ /* NT4 always serves this up as unicode but expects it to be
+ * delivered as ascii! (tridge && JRA)
+ */
+ if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
+ data_len = 18 + strlen(vname);
+ SIVAL(pdata,12,strlen(vname));
+ pstrcpy(pdata+18,vname);
+ } else {
+ int vnamelen;
+
+ vnamelen = dos_PutUniCode(pdata+18, vname, sizeof(pstring), False);
+ data_len = 18 + vnamelen;
+ SIVAL(pdata,12,vnamelen);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ }
+
+ DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
+ (int)strlen(vname),vname));
break;
case SMB_QUERY_FS_SIZE_INFO:
@@ -1911,7 +1460,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
- SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
@@ -1941,7 +1490,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
{
SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
- SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
block_size = lp_block_size(snum);
if (bsize < block_size) {
SMB_BIG_UINT factor = block_size/bsize;
@@ -1975,78 +1524,6 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
SIVAL(pdata,4,0); /* characteristics */
break;
-#ifdef HAVE_SYS_QUOTAS
- case SMB_FS_QUOTA_INFORMATION:
- /*
- * what we have to send --metze:
- *
- * Unknown1: 24 NULL bytes
- * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
- * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
- * Quota Flags: 2 byte :
- * Unknown3: 6 NULL bytes
- *
- * 48 bytes total
- *
- * details for Quota Flags:
- *
- * 0x0020 Log Limit: log if the user exceeds his Hard Quota
- * 0x0010 Log Warn: log if the user exceeds his Soft Quota
- * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
- * 0x0001 Enable Quotas: enable quota for this fs
- *
- */
- {
- /* we need to fake up a fsp here,
- * because its not send in this call
- */
- files_struct fsp;
- SMB_NTQUOTA_STRUCT quotas;
-
- ZERO_STRUCT(fsp);
- ZERO_STRUCT(quotas);
-
- fsp.conn = conn;
- fsp.fnum = -1;
- fsp.fd = -1;
-
- /* access check */
- if (current_user.uid != 0) {
- DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),conn->user));
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
- DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- data_len = 48;
-
- DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
-
- /* Unknown1 24 NULL bytes*/
- SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
- SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
- SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
-
- /* Default Soft Quota 8 bytes */
- SBIG_UINT(pdata,24,quotas.softlim);
-
- /* Default Hard Quota 8 bytes */
- SBIG_UINT(pdata,32,quotas.hardlim);
-
- /* Quota flag 2 bytes */
- SSVAL(pdata,40,quotas.qflags);
-
- /* Unknown3 6 NULL bytes */
- SSVAL(pdata,42,0);
- SIVAL(pdata,44,0);
-
- break;
- }
-#endif /* HAVE_SYS_QUOTAS */
case SMB_FS_OBJECTID_INFORMATION:
data_len = 64;
break;
@@ -2057,8 +1534,10 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
*/
case SMB_QUERY_CIFS_UNIX_INFO:
+
if (!lp_unix_extensions())
return ERROR_DOS(ERRDOS,ERRunknownlevel);
+
data_len = 12;
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
@@ -2080,7 +1559,6 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
-
send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
@@ -2088,148 +1566,47 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return -1;
}
-#ifdef HAVE_SYS_QUOTAS
/****************************************************************************
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
-static int call_trans2setfsinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *pdata = *ppdata;
- char *params = *pparams;
- files_struct *fsp = NULL;
- uint16 info_level;
+ /* Just say yes we did it - there is nothing that
+ can be set here so it doesn't matter. */
int outsize;
- SMB_NTQUOTA_STRUCT quotas;
-
- ZERO_STRUCT(quotas);
+ DEBUG(3,("call_trans2setfsinfo\n"));
- DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
-
- /* access check */
- if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
- DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
- lp_servicename(SNUM(conn)),conn->user));
- return ERROR_DOS(ERRSRV,ERRaccess);
- }
-
- /* */
- if (total_params < 4) {
- DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
- total_params));
- return ERROR_DOS(ERRDOS,ERRinvalidparam);
- }
-
- fsp = file_fsp(params,0);
-
- if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
- DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
- return ERROR_NT(NT_STATUS_INVALID_HANDLE);
- }
-
- info_level = SVAL(params,2);
-
- switch(info_level) {
- case SMB_FS_QUOTA_INFORMATION:
- /* note: normaly there're 48 bytes,
- * but we didn't use the last 6 bytes for now
- * --metze
- */
- if (total_data < 42) {
- DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
- total_data));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-
- /* unknown_1 24 NULL bytes in pdata*/
-
- /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
- quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
-#ifdef LARGE_SMB_OFF_T
- quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,28) != 0)&&
- ((quotas.softlim != 0xFFFFFFFF)||
- (IVAL(pdata,28)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
- quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
-#ifdef LARGE_SMB_OFF_T
- quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if ((IVAL(pdata,36) != 0)&&
- ((quotas.hardlim != 0xFFFFFFFF)||
- (IVAL(pdata,36)!=0xFFFFFFFF))) {
- /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- }
-#endif /* LARGE_SMB_OFF_T */
-
- /* quota_flags 2 bytes **/
- quotas.qflags = SVAL(pdata,40);
-
- /* unknown_2 6 NULL bytes follow*/
-
- /* now set the quotas */
- if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
- DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- break;
- default:
- DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
- info_level));
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
- break;
- }
+ if (!CAN_WRITE(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
- /*
- * sending this reply works fine,
- * but I'm not sure it's the same
- * like windows do...
- * --metze
- */
outsize = set_message(outbuf,10,0,True);
return outsize;
}
-#endif /* HAVE_SYS_QUOTAS */
/****************************************************************************
- * Utility function to set bad path error.
- ****************************************************************************/
+ Utility function to set bad path error.
+****************************************************************************/
-int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
+NTSTATUS set_bad_path_error(int err, BOOL bad_path)
{
- DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
- err, (int)bad_path ));
-
- if(err == ENOENT) {
- if (bad_path) {
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
- } else {
- return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
- }
+ if((err == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
- return UNIXERROR(def_class,def_code);
+ return NT_STATUS_OK;
}
/****************************************************************************
- Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
- file name or file id).
+ Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
+ file name or file id).
****************************************************************************/
-static int call_trans2qfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
@@ -2237,22 +1614,21 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 tran_call = SVAL(inbuf, smb_setup0);
uint16 info_level;
int mode=0;
- SMB_OFF_T file_size=0;
- SMB_BIG_UINT allocation_size=0;
+ SMB_OFF_T size=0;
+ SMB_BIG_UINT allocation_size = 0;
unsigned int data_size;
- unsigned int param_size = 2;
SMB_STRUCT_STAT sbuf;
- pstring fname, dos_fname;
+ pstring fname1;
+ char *fname;
+ pstring dos_fname;
char *fullpathname;
- char *base_name;
char *p;
+ int l;
SMB_OFF_T pos = 0;
BOOL bad_path = False;
BOOL delete_pending = False;
- int len;
time_t c_time;
files_struct *fsp = NULL;
- uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
if (!params)
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
@@ -2266,61 +1642,53 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
- if(fsp && (fsp->fake_file_handle)) {
- /*
- * This is actually for the QUOTA_FAKE_FILE --metze
- */
-
- pstrcpy(fname, fsp->fsp_name);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn)) {
- DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
- }
-
- } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
+ if(fsp && (fsp->is_directory || fsp->fd == -1)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
- pstrcpy(fname, fsp->fsp_name);
+ fname = fsp->fsp_name;
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn)) {
- DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
-
+
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ if (vfs_lstat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
delete_pending = fsp->directory_delete_on_close;
+
} else {
/*
* Original code - this is an open file.
*/
CHECK_FSP(fsp,conn);
- pstrcpy(fname, fsp->fsp_name);
- if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
- DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
+ fname = fsp->fsp_name;
+ if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- pos = fsp->position_information;
+
+ if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
delete_pending = fsp->delete_on_close;
- desired_access = fsp->desired_access;
}
} else {
- NTSTATUS status = NT_STATUS_OK;
-
/* qpathinfo */
if (total_params < 6)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
@@ -2329,63 +1697,64 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
- srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ fname = &fname1[0];
+ pstrcpy(fname,&params[6]);
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn)) {
- DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
-
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ if (vfs_lstat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
}
+
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
return ERROR_DOS(ERRDOS,ERRunknownlevel);
- DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
- fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+ DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
+ fname,info_level,tran_call,total_data));
- p = strrchr_m(fname,'/');
- if (!p)
- base_name = fname;
+ p = strrchr(fname,'/');
+ if (!p)
+ p = fname;
else
- base_name = p+1;
-
+ p++;
+ l = strlen(p);
mode = dos_mode(conn,fname,&sbuf);
- if (!mode)
- mode = FILE_ATTRIBUTE_NORMAL;
-
fullpathname = fname;
- file_size = get_file_size(sbuf);
+ size = get_file_size(sbuf);
allocation_size = get_allocation_size(fsp,&sbuf);
if (mode & aDIR)
- file_size = 0;
+ size = 0;
+ /* from now on we only want the part after the / */
+ fname = p;
+
params = Realloc(*pparams,2);
- if (params == NULL)
+ if ( params == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
- *pparams = params;
+ *pparams = params;
memset((char *)params,'\0',2);
data_size = max_data_bytes + 1024;
pdata = Realloc(*ppdata, data_size);
if ( pdata == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
- *ppdata = pdata;
+ *ppdata = pdata;
if (total_data > 0 && IVAL(pdata,0) == total_data) {
/* uggh, EAs for OS2 */
@@ -2404,388 +1773,373 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
sbuf.st_mtime &= ~1;
}
- /* NT expects the name to be in an exact form of the *full*
- filename. See the trans2 torture test */
- if (strequal(base_name,".")) {
+ /* NT expects the name to be in an exact form */
+ if (strequal(fname,"."))
pstrcpy(dos_fname, "\\");
- } else {
- pstr_sprintf(dos_fname, "\\%s", fname);
- string_replace(dos_fname, '/', '\\');
+ else {
+ snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
+ string_replace( dos_fname, '/','\\');
}
switch (info_level) {
- case SMB_INFO_STANDARD:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
- data_size = 22;
- put_dos_date2(pdata,l1_fdateCreation,c_time);
- put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
- put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
- SIVAL(pdata,l1_cbFile,(uint32)file_size);
- SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
- SSVAL(pdata,l1_attrFile,mode);
- break;
-
- case SMB_INFO_QUERY_EA_SIZE:
- {
- unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
- data_size = 26;
- put_dos_date2(pdata,l1_fdateCreation,c_time);
- put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
- put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
- SIVAL(pdata,l1_cbFile,(uint32)file_size);
- SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
- SSVAL(pdata,l1_attrFile,mode);
- SIVAL(pdata,l1_attrFile+2,ea_size);
- break;
- }
-
- case SMB_INFO_IS_NAME_VALID:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
- if (tran_call == TRANSACT2_QFILEINFO) {
- /* os/2 needs this ? really ?*/
- return ERROR_DOS(ERRDOS,ERRbadfunc);
- }
- data_size = 0;
- param_size = 0;
- break;
-
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- data_size = 24;
- put_dos_date2(pdata,0,c_time);
- put_dos_date2(pdata,4,sbuf.st_atime);
- put_dos_date2(pdata,8,sbuf.st_mtime);
- SIVAL(pdata,12,(uint32)file_size);
- SIVAL(pdata,16,(uint32)allocation_size);
- SIVAL(pdata,20,mode);
- break;
+ case SMB_INFO_STANDARD:
+ case SMB_INFO_QUERY_EA_SIZE:
+ data_size = (info_level==1?22:26);
+ put_dos_date2(pdata,l1_fdateCreation,c_time);
+ put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
+ put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
+ SIVAL(pdata,l1_cbFile,(uint32)size);
+ SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
+ SSVAL(pdata,l1_attrFile,mode);
+ SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
+ break;
- case SMB_INFO_QUERY_ALL_EAS:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
- /* We have data_size bytes to put EA's into. */
- data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
- break;
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ data_size = 24;
+ put_dos_date2(pdata,0,c_time);
+ put_dos_date2(pdata,4,sbuf.st_atime);
+ put_dos_date2(pdata,8,sbuf.st_mtime);
+ SIVAL(pdata,12,(uint32)size);
+ SIVAL(pdata,16,(uint32)allocation_size);
+ SIVAL(pdata,20,mode);
+ break;
- case SMB_FILE_BASIC_INFORMATION:
- case SMB_QUERY_FILE_BASIC_INFO:
+ case SMB_INFO_QUERY_ALL_EAS:
+ data_size = 4;
+ SIVAL(pdata,0,data_size);
+ break;
- if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
- data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
- } else {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
- data_size = 40;
- SIVAL(pdata,36,0);
- }
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
+ case 6:
+ return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
- DEBUG(5,("SMB_QFBI - "));
- {
- time_t create_time = c_time;
- DEBUG(5,("create: %s ", ctime(&create_time)));
- }
- DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
- DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("mode: %x\n", mode));
+ case SMB_FILE_BASIC_INFORMATION:
+ case SMB_QUERY_FILE_BASIC_INFO:
- break;
+ if (info_level == SMB_QUERY_FILE_BASIC_INFO)
+ data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
+ else {
+ data_size = 40;
+ SIVAL(pdata,36,0);
+ }
+ put_long_date(pdata,c_time);
+ put_long_date(pdata+8,sbuf.st_atime);
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ SIVAL(pdata,32,mode);
- case SMB_FILE_STANDARD_INFORMATION:
- case SMB_QUERY_FILE_STANDARD_INFO:
-
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
- data_size = 24;
- SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
- if (delete_pending & sbuf.st_nlink)
- SIVAL(pdata,16,sbuf.st_nlink - 1);
- else
- SIVAL(pdata,16,sbuf.st_nlink);
- SCVAL(pdata,20,0);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
- break;
+ DEBUG(5,("SMB_QFBI - "));
- case SMB_FILE_EA_INFORMATION:
- case SMB_QUERY_FILE_EA_INFO:
{
- unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
- data_size = 4;
- SIVAL(pdata,0,ea_size);
- break;
+ time_t create_time = c_time;
+ DEBUG(5,("create: %s ", ctime(&create_time)));
}
+ DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
+ DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("mode: %x\n", mode));
+
+ break;
+
+ case SMB_FILE_STANDARD_INFORMATION:
+ case SMB_QUERY_FILE_STANDARD_INFO:
+
+ data_size = 24;
+ /* Fake up allocation size. */
+ SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,8,size);
+ SIVAL(pdata,16,sbuf.st_nlink);
+ SCVAL(pdata,20,0);
+ SCVAL(pdata,21,(mode&aDIR)?1:0);
+ break;
+
+ case SMB_FILE_EA_INFORMATION:
+ case SMB_QUERY_FILE_EA_INFO:
+ data_size = 4;
+ SIVAL(pdata,0,0);
+ break;
+
/* Get the 8.3 name - used if NT SMB was negotiated. */
- case SMB_QUERY_FILE_ALT_NAME_INFO:
- case SMB_FILE_ALTERNATE_NAME_INFORMATION:
- {
- pstring short_name;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
- pstrcpy(short_name,base_name);
- /* Mangle if not already 8.3 */
- if(!mangle_is_8_3(short_name, True)) {
- mangle_map(short_name,True,True,SNUM(conn));
- }
- len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
- data_size = 4 + len;
- SIVAL(pdata,0,len);
- break;
+ case SMB_QUERY_FILE_ALT_NAME_INFO:
+ case SMB_FILE_ALTERNATE_NAME_INFORMATION:
+ {
+ pstring short_name;
+ pstrcpy(short_name,p);
+ /* Mangle if not already 8.3 */
+ if(!mangle_is_8_3(short_name, True)) {
+ mangle_map(short_name,True,True,SNUM(conn));
}
+ strupper(short_name);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ l = dos_PutUniCode(pdata + 4, short_name, sizeof(pstring), False);
+ data_size = 4 + l;
+ SIVAL(pdata,0,l);
+ break;
+ }
- case SMB_QUERY_FILE_NAME_INFO:
- /*
- this must be *exactly* right for ACLs on mapped drives to work
- */
- len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
- data_size = 4 + len;
- SIVAL(pdata,0,len);
- break;
+ case SMB_QUERY_FILE_NAME_INFO:
+ /*
+ * The first part of this code is essential
+ * to get security descriptors to work on mapped
+ * drives. Don't ask how I discovered this unless
+ * you like hearing about me suffering.... :-). JRA.
+ */
- case SMB_FILE_ALLOCATION_INFORMATION:
- case SMB_QUERY_FILE_ALLOCATION_INFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
- data_size = 8;
- SOFF_T(pdata,0,allocation_size);
- break;
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ l = dos_PutUniCode(pdata + 4, dos_fname,sizeof(pstring), False);
+ data_size = 4 + l;
+ SIVAL(pdata,0,l);
+ break;
- case SMB_FILE_END_OF_FILE_INFORMATION:
- case SMB_QUERY_FILE_END_OF_FILEINFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
- data_size = 8;
- SOFF_T(pdata,0,file_size);
- break;
+ case SMB_FILE_ALLOCATION_INFORMATION:
+ case SMB_QUERY_FILE_ALLOCATION_INFO:
+ data_size = 8;
+ SOFF_T(pdata,0,allocation_size);
+ break;
- case SMB_QUERY_FILE_ALL_INFO:
- case SMB_FILE_ALL_INFORMATION:
- {
- unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
- pdata += 40;
- SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
- if (delete_pending && sbuf.st_nlink)
- SIVAL(pdata,16,sbuf.st_nlink - 1);
- else
- SIVAL(pdata,16,sbuf.st_nlink);
- SCVAL(pdata,20,delete_pending);
- SCVAL(pdata,21,(mode&aDIR)?1:0);
- pdata += 24;
- SIVAL(pdata,0,ea_size);
- pdata += 4; /* EA info */
- len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
- SIVAL(pdata,0,len);
- pdata += 4 + len;
- data_size = PTR_DIFF(pdata,(*ppdata));
- break;
- }
- case SMB_FILE_INTERNAL_INFORMATION:
- /* This should be an index number - looks like
- dev/ino to me :-)
+ case SMB_QUERY_FILE_END_OF_FILEINFO:
+ case SMB_FILE_END_OF_FILE_INFORMATION:
+ data_size = 8;
+ SOFF_T(pdata,0,size);
+ break;
- I think this causes us to fail the IFSKIT
- BasicFileInformationTest. -tpot */
+ case SMB_QUERY_FILE_ALL_INFO:
+ put_long_date(pdata,c_time);
+ put_long_date(pdata+8,sbuf.st_atime);
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ SIVAL(pdata,32,mode);
+ pdata += 40;
+ SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,8,size);
+ SIVAL(pdata,16,sbuf.st_nlink);
+ SCVAL(pdata,20,delete_pending);
+ SCVAL(pdata,21,(mode&aDIR)?1:0);
+ pdata += 24;
+ SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
+ pdata += 8; /* index number */
+ pdata += 4; /* EA info */
+ if (mode & aRONLY)
+ SIVAL(pdata,0,0xA9);
+ else
+ SIVAL(pdata,0,0xd01BF);
+ pdata += 4;
+ SOFF_T(pdata,0,pos); /* current offset */
+ pdata += 8;
+ SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
+ pdata += 4;
+ pdata += 4; /* alignment */
+ SIVAL(pdata,0,l);
+ pstrcpy(pdata+4,dos_fname);
+ pdata += 4 + l;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+ break;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_dev);
- SIVAL(pdata,4,sbuf.st_ino);
- data_size = 8;
- break;
+ case SMB_FILE_INTERNAL_INFORMATION:
+ /* This should be an index number - looks like dev/ino to me :-) */
+ SIVAL(pdata,0,sbuf.st_dev);
+ SIVAL(pdata,4,sbuf.st_ino);
+ data_size = 8;
+ break;
- case SMB_FILE_ACCESS_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
- SIVAL(pdata,0,desired_access);
- data_size = 4;
- break;
+ case SMB_FILE_ACCESS_INFORMATION:
+ SIVAL(pdata,0,0x12019F); /* ??? */
+ data_size = 4;
+ break;
- case SMB_FILE_NAME_INFORMATION:
- /* Pathname with leading '\'. */
- {
- size_t byte_len;
- byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
- SIVAL(pdata,0,byte_len);
- data_size = 4 + byte_len;
- break;
- }
+ case SMB_FILE_NAME_INFORMATION:
+ /* Pathname with leading '\'. */
+ {
+ size_t byte_len;
- case SMB_FILE_DISPOSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
- data_size = 1;
- SCVAL(pdata,0,delete_pending);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
+ SIVAL(pdata,0,byte_len);
+ data_size = 4 + byte_len;
break;
+ }
- case SMB_FILE_POSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
- data_size = 8;
- SOFF_T(pdata,0,pos);
- break;
+ case SMB_FILE_DISPOSITION_INFORMATION:
+ data_size = 1;
+ SCVAL(pdata,0,delete_pending);
+ break;
- case SMB_FILE_MODE_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
- SIVAL(pdata,0,mode);
- data_size = 4;
- break;
+ case SMB_FILE_POSITION_INFORMATION:
+ data_size = 8;
+ SOFF_T(pdata,0,pos);
+ break;
- case SMB_FILE_ALIGNMENT_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
- SIVAL(pdata,0,0); /* No alignment needed. */
- data_size = 4;
- break;
+ case SMB_FILE_MODE_INFORMATION:
+ SIVAL(pdata,0,mode);
+ data_size = 4;
+ break;
-#if 0
- /*
- * NT4 server just returns "invalid query" to this - if we try to answer
- * it then NTws gets a BSOD! (tridge).
- * W2K seems to want this. JRA.
- */
- case SMB_QUERY_FILE_STREAM_INFO:
-#endif
- case SMB_FILE_STREAM_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
- if (mode & aDIR) {
- data_size = 0;
- } else {
- size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
- SIVAL(pdata,0,0); /* ??? */
- SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
- SOFF_T(pdata,8,file_size);
- SIVAL(pdata,16,allocation_size);
- SIVAL(pdata,20,0); /* ??? */
- data_size = 24 + byte_len;
- }
- break;
+ case SMB_FILE_ALIGNMENT_INFORMATION:
+ SIVAL(pdata,0,0); /* No alignment needed. */
+ data_size = 4;
+ break;
- case SMB_QUERY_COMPRESSION_INFO:
- case SMB_FILE_COMPRESSION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
- SOFF_T(pdata,0,file_size);
- SIVAL(pdata,8,0); /* ??? */
- SIVAL(pdata,12,0); /* ??? */
- data_size = 16;
- break;
+#if 0
+ /* Not yet finished... JRA */
+ case 1018:
+ {
+ size_t byte_len;
- case SMB_FILE_NETWORK_OPEN_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,allocation_size);
- SOFF_T(pdata,40,file_size);
- SIVAL(pdata,48,mode);
- SIVAL(pdata,52,0); /* ??? */
- data_size = 56;
+ SIVAL(pdata,32,mode);
+ SIVAL(pdata,36,0); /* ??? */
+ SIVAL(pdata,40,0x20); /* ??? */
+ SIVAL(pdata,44,0); /* ??? */
+ SOFF_T(pdata,48,size);
+ SIVAL(pdata,56,0x1); /* ??? */
+ SIVAL(pdata,60,0); /* ??? */
+ SIVAL(pdata,64,0); /* ??? */
+ SIVAL(pdata,68,length); /* Following string length in bytes. */
+ dos_PutUniCode(pdata+72,,False);
break;
+ }
+#endif
- case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
- SIVAL(pdata,0,mode);
- SIVAL(pdata,4,0);
- data_size = 8;
- break;
+#if 0
+ /*
+ * NT4 server just returns "invalid query" to this - if we try to answer
+ * it then NTws gets a BSOD! (tridge).
+ * W2K seems to want this. JRA.
+ */
+ case SMB_QUERY_FILE_STREAM_INFO:
+#endif
+ case SMB_FILE_STREAM_INFORMATION:
+ if (mode & aDIR) {
+ data_size = 0;
+ } else {
+ size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 14, False);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ SIVAL(pdata,0,0); /* Next stream (none). */
+ SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
+ SOFF_T(pdata,8,size);
+ SOFF_T(pdata,16,allocation_size);
+ data_size = 24 + byte_len;
+ }
+ break;
- /*
- * CIFS UNIX Extensions.
- */
+ case SMB_FILE_COMPRESSION_INFORMATION:
+ SOFF_T(pdata,0,size);
+ SIVAL(pdata,8,0); /* ??? */
+ SIVAL(pdata,12,0); /* ??? */
+ data_size = 16;
+ break;
- case SMB_QUERY_FILE_UNIX_BASIC:
+ case SMB_FILE_NETWORK_OPEN_INFORMATION:
+ put_long_date(pdata,c_time);
+ put_long_date(pdata+8,sbuf.st_atime);
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ SOFF_T(pdata,32,allocation_size); /* Allocation size. */
+ SOFF_T(pdata,40,size);
+ SIVAL(pdata,48,mode);
+ SIVAL(pdata,52,0); /* ??? */
+ data_size = 56;
+ break;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
- DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
+ case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
+ SIVAL(pdata,0,mode);
+ SIVAL(pdata,4,0);
+ data_size = 8;
+ break;
- SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
- pdata += 8;
+ /*
+ * CIFS UNIX Extensions.
+ */
- SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
- pdata += 8;
+ case SMB_QUERY_FILE_UNIX_BASIC:
- put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
- put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
- put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
- pdata += 24;
+ DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
- SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
- SIVAL(pdata,4,0);
- pdata += 8;
+ SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
+ pdata += 8;
- SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
- SIVAL(pdata,4,0);
- pdata += 8;
+ SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
+ pdata += 8;
- SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
- pdata += 4;
+ put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
+ put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
+ put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
+ pdata += 24;
- SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
- SIVAL(pdata,4,0);
- pdata += 8;
+ SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
+ SIVAL(pdata,4,0);
+ pdata += 8;
- SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
- SIVAL(pdata,4,0);
- pdata += 8;
+ SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
+ SIVAL(pdata,4,0);
+ pdata += 8;
- SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
- pdata += 8;
-
- SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
- SIVAL(pdata,4,0);
- pdata += 8;
+ SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
+ pdata += 4;
- SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
- SIVAL(pdata,4,0);
- pdata += 8+1;
- data_size = PTR_DIFF(pdata,(*ppdata));
+ SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
+ SIVAL(pdata,4,0);
+ pdata += 8;
- {
- int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
+ SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,4,0);
+ pdata += 8;
- for (i=0; i<100; i++)
- DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
- DEBUG(4,("\n"));
- }
+ SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
+ pdata += 8;
- break;
+ SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
+ SIVAL(pdata,4,0);
+ pdata += 8;
- case SMB_QUERY_FILE_UNIX_LINK:
- {
- pstring buffer;
+ SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
+ SIVAL(pdata,4,0);
+ pdata += 8+1;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+
+ {
+ int i;
+ DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
+
+ for (i=0; i<100; i++)
+ DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
+ DEBUG(4,("\n"));
+ }
+
+ break;
+
+ case SMB_QUERY_FILE_UNIX_LINK:
+ {
+ pstring buffer;
+ int len;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_mode))
- return(UNIXERROR(ERRSRV,ERRbadlink));
+ if(!S_ISLNK(sbuf.st_mode))
+ return(UNIXERROR(ERRSRV,ERRbadlink));
#else
- return(UNIXERROR(ERRDOS,ERRbadlink));
+ return(UNIXERROR(ERRDOS,ERRbadlink));
#endif
- len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
- if (len == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- buffer[len] = 0;
- len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
- pdata += len;
- data_size = PTR_DIFF(pdata,(*ppdata));
+ len = conn->vfs_ops.readlink(conn,dos_to_unix_static(fullpathname), buffer, sizeof(pstring)-1); /* read link */
+ if (len == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ buffer[len] = 0;
+ unix_to_dos(buffer);
+ pstrcpy(pdata,buffer); /* write '\0' terminated string */
+ pdata += strlen(buffer)+1;
+ data_size = PTR_DIFF(pdata,(*ppdata));
- break;
- }
+ break;
+ }
- default:
+ default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
- send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
+ send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
return(-1);
}
@@ -2805,7 +2159,7 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
if (delete_on_close && !CAN_WRITE(fsp->conn)) {
DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
+ return NT_STATUS_ACCESS_DENIED;
}
/*
* Only allow delete on close for files/directories opened with delete intent.
@@ -2814,7 +2168,7 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
+ return NT_STATUS_ACCESS_DENIED;
}
if(fsp->is_directory) {
@@ -2833,7 +2187,7 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
/****************************************************************************
Sets the delete on close flag over all share modes on this file.
Modify the share mode entry for all files open
- on this device and inode to tell other smbds we have
+ on this device and inode to tell other smbds we have
changed the delete on close flag. This will be noticed
in the close code, the last closer will delete the file
if flag is set.
@@ -2894,10 +2248,10 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
pstrcpy(link_dest, "./");
}
- if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
+ if (conn->vfs_ops.realpath(conn,dos_to_unix_static(link_dest),resolved_name) == NULL)
return -1;
- pstrcpy(link_dest, resolved_name);
+ pstrcpy(link_dest, unix_to_dos_static(resolved_name));
pstrcat(link_dest, "/");
pstrcat(link_dest, last_component);
@@ -2922,110 +2276,31 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in
}
/****************************************************************************
- Set a hard link (called by UNIX extensions and by NT rename with HARD link
- code.
-****************************************************************************/
-
-NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
-{
- BOOL bad_path_oldname = False;
- BOOL bad_path_newname = False;
- SMB_STRUCT_STAT sbuf1, sbuf2;
- BOOL rc, rcdest;
- pstring last_component_oldname;
- pstring last_component_newname;
- NTSTATUS status = NT_STATUS_OK;
-
- ZERO_STRUCT(sbuf1);
- ZERO_STRUCT(sbuf2);
-
- /* No wildcards. */
- if (ms_has_wild(newname) || ms_has_wild(oldname)) {
- return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
- }
-
- rc = unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
- if (!rc && bad_path_oldname) {
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* Quick check for "." and ".." */
- if (last_component_oldname[0] == '.') {
- if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- }
-
- /* source must already exist. */
- if (!VALID_STAT(sbuf1)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- rcdest = unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
- if (!rcdest && bad_path_newname) {
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
-
- /* Quick check for "." and ".." */
- if (last_component_newname[0] == '.') {
- if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- }
-
- /* Disallow if newname already exists. */
- if (VALID_STAT(sbuf2)) {
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- /* No links from a directory. */
- if (S_ISDIR(sbuf1.st_mode)) {
- return NT_STATUS_FILE_IS_A_DIRECTORY;
- }
-
- if (ensure_link_is_safe(conn, oldname, oldname) != 0)
- return NT_STATUS_ACCESS_DENIED;
-
- DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
-
- if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
- status = map_nt_error_from_unix(errno);
- DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
- nt_errstr(status), newname, oldname));
- }
-
- return status;
-}
-
-/****************************************************************************
Reply to a TRANS2_SETFILEINFO (set file info by fileid).
****************************************************************************/
-static int call_trans2setfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *params = *pparams;
char *pdata = *ppdata;
uint16 tran_call = SVAL(inbuf, smb_setup0);
uint16 info_level;
- int dosmode=0;
+ int dosmode = 0;
SMB_OFF_T size=0;
struct utimbuf tvs;
SMB_STRUCT_STAT sbuf;
- pstring fname;
+ pstring fname1;
+ char *fname = NULL;
int fd = -1;
BOOL bad_path = False;
files_struct *fsp = NULL;
uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
mode_t unixmode = 0;
- NTSTATUS status = NT_STATUS_OK;
-
- if (!params)
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
if (tran_call == TRANSACT2_SETFILEINFO) {
+
if (total_params < 4)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
@@ -3038,37 +2313,40 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
- pstrcpy(fname, fsp->fsp_name);
+ fname = fsp->fsp_name;
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
- DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
+ DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
} else if (fsp && fsp->print_file) {
/*
* Doing a DELETE_ON_CLOSE should cancel a print job.
*/
- if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
+ if (((info_level == SMB_SET_FILE_DISPOSITION_INFO)||(info_level == SMB_FILE_DISPOSITION_INFORMATION)) &&
+ CVAL(pdata,0)) {
fsp->share_mode = FILE_DELETE_ON_CLOSE;
- DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
-
+ DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
+ fsp->fsp_name ));
+
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
} else
- return (UNIXERROR(ERRDOS,ERRbadpath));
- } else {
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ } else {
/*
* Original code - this is an open file.
*/
CHECK_FSP(fsp,conn);
- pstrcpy(fname, fsp->fsp_name);
+ fname = fsp->fsp_name;
fd = fsp->fd;
- if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
+ if (vfs_fstat(fsp,fd,&sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
}
@@ -3078,25 +2356,24 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
info_level = SVAL(params,0);
- srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ fname = fname1;
+ pstrcpy(fname,&params[6]);
unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if(!check_name(fname, conn)) {
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
/*
* For CIFS UNIX extensions the target name may not exist.
*/
if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
- DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
- }
-
- if(!check_name(fname, conn)) {
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
- }
+ DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
}
if (!CAN_WRITE(conn))
@@ -3108,8 +2385,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (VALID_STAT(sbuf))
unixmode = sbuf.st_mode;
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
- tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
+ DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
+ tran_call,fname,info_level,total_data));
/* Realloc the parameter and data sizes */
params = Realloc(*pparams,2);
@@ -3136,24 +2413,25 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
switch (info_level) {
case SMB_INFO_STANDARD:
{
- if (total_data < 12)
+ if (total_data < l1_cbFile+4)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
/* access time */
tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
+
/* write time */
tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
+
+ dosmode = SVAL(pdata,l1_attrFile);
+ size = IVAL(pdata,l1_cbFile);
break;
}
case SMB_INFO_SET_EA:
- status = set_ea(conn, fsp, fname, pdata, total_data);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
- return ERROR_NT(status);
- break;
+ return(ERROR_DOS(ERRDOS,ERReasnotsupported));
/* XXXX um, i don't think this is right.
- it's also not in the cifs6.txt spec.
+ it's also not in the cifs6.txt spec.
*/
case SMB_INFO_QUERY_EAS_FROM_LIST:
if (total_data < 28)
@@ -3199,10 +2477,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (write_time > tvs.modtime && write_time != 0xffffffff) {
tvs.modtime = write_time;
}
+
/* Prefer a defined time to an undefined one. */
if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
- ? changed_time : write_time);
+ ? changed_time
+ : write_time);
/* attributes */
dosmode = IVAL(pdata,32);
@@ -3222,11 +2502,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
#ifdef LARGE_SMB_OFF_T
allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return ERROR_DOS(ERRDOS,ERRunknownlevel);
#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
- fname, (double)allocation_size ));
+ fname, (double)allocation_size ));
if (allocation_size)
allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
@@ -3250,35 +2530,32 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
push_oplock_pending_smb_message(inbuf, length);
return -1;
- }
-
+ }
+
new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
- SET_OPEN_MODE(DOS_OPEN_RDWR),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- FILE_ATTRIBUTE_NORMAL,
- 0, &access_mode, &action);
+ SET_OPEN_MODE(DOS_OPEN_RDWR),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath));
ret = vfs_allocate_file_space(new_fsp, allocation_size);
- if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
- new_fsp->fnum, strerror(errno)));
+ if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
ret = -1;
}
close_file(new_fsp,True);
} else {
ret = vfs_allocate_file_space(fsp, allocation_size);
- if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
- fsp->fnum, strerror(errno)));
+ if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
ret = -1;
}
}
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
- /* Allocate can truncate size... */
+ /* Allocate can trucate size... */
size = get_file_size(new_sbuf);
}
@@ -3306,21 +2583,20 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
{
BOOL delete_on_close;
+ NTSTATUS status;
if (total_data < 1)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
delete_on_close = (CVAL(pdata,0) ? True : False);
- /* Just ignore this set on a path. */
if (tran_call != TRANSACT2_SETFILEINFO)
- break;
+ return(ERROR_DOS(ERRDOS,ERRunknownlevel));
if (fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadfid));
status = set_delete_on_close_internal(fsp, delete_on_close);
-
if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
return ERROR_NT(status);
@@ -3332,27 +2608,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
break;
}
- case SMB_FILE_POSITION_INFORMATION:
- {
- SMB_BIG_UINT position_information;
-
- if (total_data < 8)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
-
- position_information = (SMB_BIG_UINT)IVAL(pdata,0);
-#ifdef LARGE_SMB_OFF_T
- position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
-#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
- fname, (double)position_information ));
- if (fsp)
- fsp->position_information = position_information;
- break;
- }
-
/*
* CIFS UNIX extensions.
*/
@@ -3432,11 +2687,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
0%o for file %s\n", (double)dev, unixmode, fname ));
/* Ok - do the mknod. */
- if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
+ if (conn->vfs_ops.mknod(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
- inherit_access_acl(conn, fname, unixmode);
-
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
@@ -3451,7 +2704,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (raw_unixmode != SMB_MODE_NO_CHANGE) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
(unsigned int)unixmode, fname ));
- if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
+ if (vfs_chmod(conn,fname,unixmode) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -3462,7 +2715,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
+ if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -3473,7 +2726,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
- if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
+ if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
break;
@@ -3481,27 +2734,28 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
case SMB_SET_FILE_UNIX_LINK:
{
- pstring oldname;
- char *newname = fname;
-
+ pstring link_dest;
/* Set a symbolic link. */
/* Don't allow this if follow links is false. */
if (!lp_symlinks(SNUM(conn)))
return(ERROR_DOS(ERRDOS,ERRnoaccess));
- srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ /* Disallow if already exists. */
+ if (VALID_STAT(sbuf))
+ return(ERROR_DOS(ERRDOS,ERRbadpath));
- if (ensure_link_is_safe(conn, oldname, oldname) != 0)
+ pstrcpy(link_dest, pdata);
+
+ if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ dos_to_unix(link_dest);
+ dos_to_unix(fname);
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
- fname, oldname ));
+ fname, link_dest ));
- if (SMB_VFS_SYMLINK(conn,oldname,newname) != 0)
+ if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -3510,80 +2764,32 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
case SMB_SET_FILE_UNIX_HLINK:
{
- pstring oldname;
- char *newname = fname;
+ pstring link_dest;
/* Set a hard link. */
- srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
- DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
- fname, oldname));
+ /* Disallow if already exists. */
+ if (VALID_STAT(sbuf))
+ return(ERROR_DOS(ERRDOS,ERRbadpath));
- status = hardlink_internals(conn, oldname, newname);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
-
- SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
- return(-1);
- }
+ pstrcpy(link_dest, pdata);
- case SMB_FILE_RENAME_INFORMATION:
- {
- BOOL overwrite;
- uint32 root_fid;
- uint32 len;
- pstring newname;
- pstring base_name;
- char *p;
+ if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
- if (total_data < 12)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ dos_to_unix(link_dest);
+ dos_to_unix(fname);
- overwrite = (CVAL(pdata,0) ? True : False);
- root_fid = IVAL(pdata,4);
- len = IVAL(pdata,8);
- srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
+ fname, link_dest ));
- /* Check the new name has no '/' characters. */
- if (strchr_m(newname, '/'))
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
-
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
-
- /* Create the base directory. */
- pstrcpy(base_name, fname);
- p = strrchr_m(base_name, '/');
- if (p)
- *p = '\0';
- /* Append the new name. */
- pstrcat(base_name, "/");
- pstrcat(base_name, newname);
-
- if (fsp) {
- DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp->fsp_name, base_name ));
- status = rename_internals_fsp(conn, fsp, base_name, overwrite);
- } else {
- DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
- fname, newname ));
- status = rename_internals(conn, fname, base_name, 0, overwrite);
- }
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
- process_pending_change_notify_queue((time_t)0);
+ if (conn->vfs_ops.link(conn,link_dest,fname) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
}
+
default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
@@ -3598,21 +2804,17 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
DEBUG(6,("size: %.0f ", (double)size));
-
- if (dosmode) {
- if (S_ISDIR(sbuf.st_mode))
- dosmode |= aDIR;
- else
- dosmode &= ~aDIR;
- }
+ if (S_ISDIR(sbuf.st_mode))
+ dosmode |= aDIR;
+ else
+ dosmode &= ~aDIR;
DEBUG(6,("dosmode: %x\n" , dosmode));
if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
- (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
- (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
- (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
-
+ (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
+ (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
+ (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
/*
* Only do this test if we are not explicitly
* changing the size of a file.
@@ -3625,6 +2827,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* Try and set the times, size and mode of this file -
* if they are different from the current values
*/
+
if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
if(fsp != NULL) {
/*
@@ -3636,7 +2839,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
*/
if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
- DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
+ DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
+ ctime(&tvs.modtime) ));
fsp->pending_modtime = tvs.modtime;
}
@@ -3652,15 +2856,16 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
/* check the mode isn't different, before changing it */
if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
+ fname, dosmode ));
- if(file_set_dosmode(conn, fname, dosmode, NULL)) {
- DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
+ if(file_chmod(conn, fname, dosmode, NULL)) {
+ DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
- if (size != get_file_size(sbuf)) {
+ if(size != get_file_size(sbuf)) {
int ret;
@@ -3683,10 +2888,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
new_fsp = open_file_shared(conn, fname, &sbuf,
- SET_OPEN_MODE(DOS_OPEN_RDWR),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- FILE_ATTRIBUTE_NORMAL,
- 0, &access_mode, &action);
+ SET_OPEN_MODE(DOS_OPEN_RDWR),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath));
@@ -3702,7 +2906,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
-
return(-1);
}
@@ -3710,16 +2913,14 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/
-static int call_trans2mkdir(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *params = *pparams;
pstring directory;
int ret = -1;
SMB_STRUCT_STAT sbuf;
BOOL bad_path = False;
- NTSTATUS status = NT_STATUS_OK;
if (!CAN_WRITE(conn))
return ERROR_DOS(ERRSRV,ERRaccess);
@@ -3727,20 +2928,18 @@ static int call_trans2mkdir(connection_struct *conn,
if (total_params < 4)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
- srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
- }
+ pstrcpy(directory, &params[4]);
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
unix_convert(directory,conn,0,&bad_path,&sbuf);
if (check_name(directory,conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
if(ret < 0) {
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
/* Realloc the parameter and data sizes */
@@ -3761,9 +2960,8 @@ static int call_trans2mkdir(connection_struct *conn,
We don't actually do this - we just send a null response.
****************************************************************************/
-static int call_trans2findnotifyfirst(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
static uint16 fnf_handle = 257;
char *params = *pparams;
@@ -3785,7 +2983,7 @@ static int call_trans2findnotifyfirst(connection_struct *conn,
/* Realloc the parameter and data sizes */
params = Realloc(*pparams,6);
- if(params == NULL)
+ if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
*pparams = params;
@@ -3808,9 +3006,8 @@ static int call_trans2findnotifyfirst(connection_struct *conn,
changes). Currently this does nothing.
****************************************************************************/
-static int call_trans2findnotifynext(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *params = *pparams;
@@ -3834,12 +3031,13 @@ static int call_trans2findnotifynext(connection_struct *conn,
Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *params = *pparams;
- pstring pathname;
+ enum remote_arch_types ra_type = get_remote_arch();
+ BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K) || (ra_type == RA_WINXP) || (ra_type == RA_WIN2K3));
+ pstring pathname;
int reply_size = 0;
int max_referral_level;
@@ -3853,11 +3051,18 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
if(!lp_host_msdfs())
return ERROR_DOS(ERRDOS,ERRbadfunc);
- srvstr_pull(inbuf, pathname, &params[2], sizeof(pathname), -1, STR_TERMINATE);
- if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
- return UNIXERROR(ERRDOS,ERRbadfile);
+ /* if pathname is in UNICODE, convert to DOS */
+ /* NT always sends in UNICODE, may not set UNICODE flag */
+ if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS)) {
+ unistr_to_dos(pathname, &params[2], sizeof(pathname));
+ DEBUG(10,("UNICODE referral for %s\n",pathname));
+ } else
+ pstrcpy(pathname,&params[2]);
+
+ if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
+ return ERROR_DOS(ERRDOS,ERRbadfile);
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS | FLAGS2_DFS_PATHNAMES);
send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
return(-1);
@@ -3867,21 +3072,15 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
#define LMFUNC_GETJOBID 0x60
/****************************************************************************
- Reply to a TRANS2_IOCTL - used for OS/2 printing.
+ reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/
-static int call_trans2ioctl(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
- /* check for an invalid fid before proceeding */
-
- if (!fsp)
- return(ERROR_DOS(ERRDOS,ERRbadfid));
-
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
pdata = Realloc(*ppdata, 32);
@@ -3889,12 +3088,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
return ERROR_DOS(ERRDOS,ERRnomem);
*ppdata = pdata;
- /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
- CAN ACCEPT THIS IN UNICODE. JRA. */
-
- SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
- srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
- srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
+ SSVAL(pdata,0,fsp->print_jobid); /* Job number */
+ StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
return(-1);
} else {
@@ -3907,8 +3103,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
-int reply_findclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_findclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
int dptr_num=SVALS(inbuf,smb_vwv0);
@@ -3930,8 +3125,7 @@ int reply_findclose(connection_struct *conn,
Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
-int reply_findnclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_findnclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
int dptr_num= -1;
@@ -3957,8 +3151,7 @@ int reply_findnclose(connection_struct *conn,
Reply to a SMBtranss2 - just ignore it!
****************************************************************************/
-int reply_transs2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_transs2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
START_PROFILE(SMBtranss2);
DEBUG(4,("Ignoring transs2 of length %d\n",length));
@@ -3970,8 +3163,7 @@ int reply_transs2(connection_struct *conn,
Reply to a SMBtrans2.
****************************************************************************/
-int reply_trans2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
unsigned int total_params = SVAL(inbuf, smb_tpscnt);
@@ -4059,8 +3251,7 @@ int reply_trans2(connection_struct *conn,
unsigned int psoff = SVAL(inbuf, smb_psoff);
if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
goto bad_param;
- if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
- (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
+ if (smb_base(inbuf) + psoff + num_params > inbuf + length)
goto bad_param;
memcpy( params, smb_base(inbuf) + psoff, num_params);
}
@@ -4068,19 +3259,15 @@ int reply_trans2(connection_struct *conn,
unsigned int dsoff = SVAL(inbuf, smb_dsoff);
if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
goto bad_param;
- if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
- (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
+ if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
goto bad_param;
memcpy( data, smb_base(inbuf) + dsoff, num_data);
}
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if(num_data_sofar < total_data || num_params_sofar < total_params) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
outsize = set_message(outbuf,0,0,True);
- srv_signing_trans_stop();
if (!send_smb(smbd_server_fd(),outbuf))
exit_server("reply_trans2: send_smb failed.");
@@ -4094,13 +3281,6 @@ int reply_trans2(connection_struct *conn,
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
- /*
- * The sequence number for the trans reply is always
- * based on the last secondary received.
- */
-
- srv_signing_trans_start(SVAL(inbuf,smb_mid));
-
if ((ret &&
(CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
outsize = set_message(outbuf,0,0,True);
@@ -4138,10 +3318,7 @@ int reply_trans2(connection_struct *conn,
if ((param_disp + num_params < param_disp) ||
(param_disp + num_params < num_params))
goto bad_param;
- if (param_disp > total_params)
- goto bad_param;
- if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
- (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
+ if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
goto bad_param;
if (params + param_disp < params)
goto bad_param;
@@ -4154,10 +3331,7 @@ int reply_trans2(connection_struct *conn,
if ((data_disp + num_data < data_disp) ||
(data_disp + num_data < num_data))
goto bad_param;
- if (data_disp > total_data)
- goto bad_param;
- if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
- (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
+ if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
goto bad_param;
if (data + data_disp < data)
goto bad_param;
@@ -4167,93 +3341,91 @@ int reply_trans2(connection_struct *conn,
}
}
- if (Protocol >= PROTOCOL_NT1) {
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
- }
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
/* Now we must call the relevant TRANS2 function */
switch(tran_call) {
case TRANSACT2_OPEN:
START_PROFILE_NESTED(Trans2_open);
outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_open);
break;
case TRANSACT2_FINDFIRST:
START_PROFILE_NESTED(Trans2_findfirst);
outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findfirst);
break;
case TRANSACT2_FINDNEXT:
START_PROFILE_NESTED(Trans2_findnext);
outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnext);
break;
case TRANSACT2_QFSINFO:
START_PROFILE_NESTED(Trans2_qfsinfo);
- outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
-#ifdef HAVE_SYS_QUOTAS
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
-#endif
+
case TRANSACT2_QPATHINFO:
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);
outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_qpathinfo);
break;
case TRANSACT2_SETPATHINFO:
case TRANSACT2_SETFILEINFO:
START_PROFILE_NESTED(Trans2_setpathinfo);
outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setpathinfo);
break;
case TRANSACT2_FINDNOTIFYFIRST:
START_PROFILE_NESTED(Trans2_findnotifyfirst);
outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnotifyfirst);
break;
case TRANSACT2_FINDNOTIFYNEXT:
START_PROFILE_NESTED(Trans2_findnotifynext);
outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnotifynext);
break;
case TRANSACT2_MKDIR:
START_PROFILE_NESTED(Trans2_mkdir);
outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_mkdir);
break;
case TRANSACT2_GET_DFS_REFERRAL:
START_PROFILE_NESTED(Trans2_get_dfs_referral);
outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_get_dfs_referral);
break;
case TRANSACT2_IOCTL:
START_PROFILE_NESTED(Trans2_ioctl);
outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
- &params, total_params, &data, total_data);
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_ioctl);
break;
default:
@@ -4262,7 +3434,6 @@ int reply_trans2(connection_struct *conn,
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
- srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -4273,8 +3444,6 @@ int reply_trans2(connection_struct *conn,
an error packet.
*/
- srv_signing_trans_stop();
-
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
@@ -4284,7 +3453,6 @@ int reply_trans2(connection_struct *conn,
bad_param:
- srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index 012c83d21d2..fff8e3a263f 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
uid/user handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -30,121 +31,52 @@ extern struct current_user current_user;
BOOL change_to_guest(void)
{
static struct passwd *pass=NULL;
+ static uid_t guest_uid = (uid_t)-1;
+ static gid_t guest_gid = (gid_t)-1;
+ static fstring guest_name;
if (!pass) {
- /* Don't need to free() this as its stored in a static */
- pass = getpwnam_alloc(lp_guestaccount());
+ pass = Get_Pwnam(lp_guestaccount(-1),True);
if (!pass)
return(False);
+ guest_uid = pass->pw_uid;
+ guest_gid = pass->pw_gid;
+ fstrcpy(guest_name, pass->pw_name);
}
#ifdef AIX
/* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
setting IDs */
- initgroups(pass->pw_name, pass->pw_gid);
+ initgroups(guest_name, guest_gid);
#endif
- set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL, NULL);
+ set_sec_ctx(guest_uid, guest_gid, 0, NULL, NULL);
current_user.conn = NULL;
current_user.vuid = UID_FIELD_INVALID;
- passwd_free(&pass);
-
return True;
}
-/****************************************************************************
- Readonly share for this user ?
-****************************************************************************/
-
-static BOOL is_share_read_only_for_user(connection_struct *conn, user_struct *vuser)
-{
- char **list;
- const char *service = lp_servicename(conn->service);
- BOOL read_only_ret = lp_readonly(conn->service);
-
- if (!service)
- return read_only_ret;
-
- str_list_copy(&list, lp_readlist(conn->service));
- if (list) {
- if (!str_list_sub_basic(list, vuser->user.smb_name) ) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: read list substitution failed\n"));
- }
- if (!str_list_substitute(list, "%S", service)) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: read list service substitution failed\n"));
- }
- if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) {
- read_only_ret = True;
- }
- str_list_free(&list);
- }
-
- str_list_copy(&list, lp_writelist(conn->service));
- if (list) {
- if (!str_list_sub_basic(list, vuser->user.smb_name) ) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: write list substitution failed\n"));
- }
- if (!str_list_substitute(list, "%S", service)) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: write list service substitution failed\n"));
- }
- if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) {
- read_only_ret = False;
- }
- str_list_free(&list);
- }
-
- DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user %s\n",
- service, read_only_ret ? "read-only" : "read-write", vuser->user.unix_name ));
-
- return read_only_ret;
-}
-
/*******************************************************************
Check if a username is OK.
********************************************************************/
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
{
- unsigned int i;
- struct vuid_cache_entry *ent = NULL;
- BOOL readonly_share;
-
- for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
- if (conn->vuid_cache.array[i].vuid == vuser->vuid) {
- ent = &conn->vuid_cache.array[i];
- conn->read_only = ent->read_only;
- conn->admin_user = ent->admin_user;
+ int i;
+ for (i=0;i<conn->uid_cache.entries;i++)
+ if (conn->uid_cache.list[i] == vuser->uid)
return(True);
- }
- }
- if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups))
+ if (!user_ok(vuser->user.unix_name,snum))
return(False);
- readonly_share = is_share_read_only_for_user(conn, vuser);
-
- if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) {
- return False;
- }
-
- i = conn->vuid_cache.entries % VUID_CACHE_SIZE;
- if (conn->vuid_cache.entries < VUID_CACHE_SIZE)
- conn->vuid_cache.entries++;
-
- ent = &conn->vuid_cache.array[i];
- ent->vuid = vuser->vuid;
- ent->read_only = readonly_share;
-
- if (user_in_list(vuser->user.unix_name ,lp_admin_users(conn->service), vuser->groups, vuser->n_groups)) {
- ent->admin_user = True;
- } else {
- ent->admin_user = False;
- }
+ i = conn->uid_cache.entries % UID_CACHE_SIZE;
+ conn->uid_cache.list[i] = vuser->uid;
- conn->read_only = ent->read_only;
- conn->admin_user = ent->admin_user;
+ if (conn->uid_cache.entries < UID_CACHE_SIZE)
+ conn->uid_cache.entries++;
return(True);
}
@@ -161,9 +93,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
gid_t gid;
uid_t uid;
char group_c;
- BOOL must_free_token_priv = False;
+ BOOL must_free_token = False;
NT_USER_TOKEN *token = NULL;
- PRIVILEGE_SET *privs = NULL;
if (!conn) {
DEBUG(2,("change_to_user: Connection not open\n"));
@@ -183,30 +114,35 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
return(True);
} else if ((current_user.conn == conn) &&
(vuser != 0) && (current_user.vuid == vuid) &&
- (current_user.uid == vuser->uid)) {
+ (current_user.uid == vuser->uid))
+ {
DEBUG(4,("change_to_user: Skipping user change - already user\n"));
- return(True);
+ return True;
}
snum = SNUM(conn);
- if (conn->force_user) /* security = share sets this too */ {
+ if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
+ return False;
+
+ if (conn->force_user ||
+ conn->admin_user ||
+ (lp_security() == SEC_SHARE)) {
uid = conn->uid;
gid = conn->gid;
current_user.groups = conn->groups;
current_user.ngroups = conn->ngroups;
token = conn->nt_user_token;
- privs = conn->privs;
- } else if ((vuser) && check_user_ok(conn, vuser, snum)) {
- uid = conn->admin_user ? 0 : vuser->uid;
+ } else {
+ if (!vuser) {
+ DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid));
+ return(False);
+ }
+ uid = vuser->uid;
gid = vuser->gid;
current_user.ngroups = vuser->n_groups;
current_user.groups = vuser->groups;
token = vuser->nt_user_token;
- privs = vuser->privs;
- } else {
- DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid));
- return False;
}
/*
@@ -246,29 +182,18 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
if (vuser && vuser->guest)
is_guest = True;
- token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest);
- if (!token) {
- DEBUG(1, ("change_to_user: create_nt_token failed!\n"));
- return False;
- }
-
- become_root();
- pdb_get_privilege_set(token->user_sids, token->num_sids, privs);
- unbecome_root();
-
- must_free_token_priv = True;
+ token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL);
+ must_free_token = True;
}
- set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token, privs);
+ set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token);
/*
* Free the new token (as set_sec_ctx copies it).
*/
- if (must_free_token_priv) {
+ if (must_free_token)
delete_nt_token(&token);
- destroy_privilege(&privs);
- }
current_user.conn = conn;
current_user.vuid = vuid;
@@ -309,7 +234,7 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
return False;
set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
- p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token, p->pipe_user.privs);
+ p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token);
return True;
}
@@ -384,6 +309,17 @@ static void pop_conn_ctx(void)
ctx_p->vuid = UID_FIELD_INVALID;
}
+void init_conn_ctx(void)
+{
+ int i;
+
+ /* Initialise connection context stack */
+ for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) {
+ conn_ctx_stack[i].conn = NULL;
+ conn_ctx_stack[i].vuid = UID_FIELD_INVALID;
+ }
+}
+
/****************************************************************************
Temporarily become a root user. Must match with unbecome_root(). Saves and
restores the connection context.
@@ -432,3 +368,573 @@ BOOL unbecome_user(void)
return True;
}
+/*****************************************************************
+ Convert the suplimentary SIDs returned in a netlogon into UNIX
+ group gid_t's. Add to the total group array.
+*****************************************************************/
+
+void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok)
+{
+ int total_groups;
+ int current_n_groups = *n_groups;
+ gid_t *final_groups = NULL;
+ size_t i;
+ NT_USER_TOKEN *ptok = *pptok;
+ NT_USER_TOKEN *new_tok = NULL;
+
+ if (!ptok || (ptok->num_sids == 0))
+ return;
+
+ new_tok = dup_nt_token(ptok);
+ if (!new_tok) {
+ DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n"));
+ return;
+ }
+ /* Leave the allocated space but empty the number of SIDs. */
+ new_tok->num_sids = 0;
+
+ total_groups = current_n_groups + ptok->num_sids;
+
+ final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t));
+ if (!final_groups) {
+ DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n"));
+ delete_nt_token(&new_tok);
+ return;
+ }
+
+ memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t));
+ for (i = 0; i < ptok->num_sids; i++) {
+ enum SID_NAME_USE sid_type;
+ gid_t new_grp;
+
+ if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) {
+ /*
+ * Don't add the gid_t if it is already in the current group
+ * list. Some UNIXen don't like the same group more than once.
+ */
+ int j;
+
+ for (j = 0; j < current_n_groups; j++)
+ if (final_groups[j] == new_grp)
+ break;
+
+ if ( j == current_n_groups) {
+ /* Group not already present. */
+ final_groups[current_n_groups++] = new_grp;
+ }
+ } else {
+ /* SID didn't map. Copy to the new token to be saved. */
+ sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]);
+ }
+ }
+
+ SAFE_FREE(*pp_groups);
+ *pp_groups = final_groups;
+ *n_groups = current_n_groups;
+
+ /* Replace the old token with the truncated one. */
+ delete_nt_token(&ptok);
+ *pptok = new_tok;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert name to SID function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+{
+ extern pstring global_myname;
+ extern fstring global_myworkgroup;
+ fstring sid;
+ char *sep = lp_winbind_separator();
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ if (!winbind_lookup_name(NULL, name, psid, name_type) || (*name_type != SID_NAME_USER) ) {
+ BOOL ret = False;
+
+ DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name));
+
+ /* If we are looking up a domain user, make sure it is
+ for the local machine only */
+
+ if (strchr(name, sep[0]) || strchr(name, '\\')) {
+ fstring domain, username;
+
+ split_domain_name(name, domain, username);
+
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ if (strequal(domain, global_myworkgroup)) {
+ fstrcpy(domain, global_myname);
+ ret = local_lookup_name(domain, username, psid, name_type);
+ }
+ /* No break is deliberate here. JRA. */
+ default:
+ if (strcasecmp(global_myname, domain) != 0) {
+ DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
+ ret = local_lookup_name(global_myname, username, psid, name_type);
+ }
+ }
+ } else {
+ ret = local_lookup_name(global_myname, name, psid, name_type);
+ }
+
+ if (ret) {
+ DEBUG(10,
+ ("lookup_name: (local) %s -> SID %s (type %u)\n",
+ name, sid_to_string(sid,psid),
+ (unsigned int)*name_type ));
+ } else {
+ DEBUG(10,("lookup name: (local) %s failed.\n", name));
+ }
+
+ return ret;
+ }
+
+ DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
+ name, sid_to_string(sid, psid),
+ (unsigned int)*name_type));
+ return True;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to name function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
+{
+ if (!name_type)
+ return False;
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ /* Check if this is our own sid. This should perhaps be done by
+ winbind? For the moment handle it here. */
+
+ if (sid->num_auths == 5) {
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+
+ if (sid_equal(&global_sam_sid, &tmp_sid)) {
+
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ local_lookup_rid(rid, name, name_type);
+ }
+ }
+
+ if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ fstring sid_str;
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ lookup_known_rid(&tmp_sid, rid, name, name_type);
+ }
+ return True;
+}
+
+/*****************************************************************
+ Id mapping cache. This is to avoid Winbind mappings already
+ seen by smbd to be queried too frequently, keeping winbindd
+ busy, and blocking smbd while winbindd is busy with other
+ stuff. Written by Michael Steffens <michael.steffens@hp.com>,
+ modified to use linked lists by jra.
+*****************************************************************/
+
+#define MAX_UID_SID_CACHE_SIZE 100
+#define TURNOVER_UID_SID_CACHE_SIZE 10
+#define MAX_GID_SID_CACHE_SIZE 100
+#define TURNOVER_GID_SID_CACHE_SIZE 10
+
+static size_t n_uid_sid_cache = 0;
+static size_t n_gid_sid_cache = 0;
+
+static struct uid_sid_cache {
+ struct uid_sid_cache *next, *prev;
+ uid_t uid;
+ DOM_SID sid;
+ enum SID_NAME_USE sidtype;
+} *uid_sid_cache_head;
+
+static struct gid_sid_cache {
+ struct gid_sid_cache *next, *prev;
+ gid_t gid;
+ DOM_SID sid;
+ enum SID_NAME_USE sidtype;
+} *gid_sid_cache_head;
+
+/*****************************************************************
+ Find a SID given a uid.
+*****************************************************************/
+
+static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, uid_t uid)
+{
+ struct uid_sid_cache *pc;
+
+ for (pc = uid_sid_cache_head; pc; pc = pc->next) {
+ if (pc->uid == uid) {
+ fstring sid;
+ *psid = pc->sid;
+ *psidtype = pc->sidtype;
+ DEBUG(3,("fetch sid from uid cache %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(uid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Find a uid given a SID.
+*****************************************************************/
+
+static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE sidtype)
+{
+ struct uid_sid_cache *pc;
+
+ for (pc = uid_sid_cache_head; pc; pc = pc->next) {
+ if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
+ *puid = pc->uid;
+ DEBUG(3,("fetch uid from cache %u -> %s\n",
+ (unsigned int)*puid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(uid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Store uid to SID mapping in cache.
+*****************************************************************/
+
+static void store_uid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, uid_t uid)
+{
+ struct uid_sid_cache *pc;
+
+ if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
+ /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
+ struct uid_sid_cache *pc_next;
+ size_t i;
+
+ for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
+ ;
+ for(; pc; pc = pc_next) {
+ pc_next = pc->next;
+ DLIST_REMOVE(uid_sid_cache_head,pc);
+ SAFE_FREE(pc);
+ n_uid_sid_cache--;
+ }
+ }
+
+ pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache));
+ if (!pc)
+ return;
+ pc->uid = uid;
+ sid_copy(&pc->sid, psid);
+ pc->sidtype = sidtype;
+ DLIST_ADD(uid_sid_cache_head, pc);
+ n_uid_sid_cache++;
+}
+
+/*****************************************************************
+ Find a SID given a gid.
+*****************************************************************/
+
+static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, gid_t gid)
+{
+ struct gid_sid_cache *pc;
+
+ for (pc = gid_sid_cache_head; pc; pc = pc->next) {
+ if (pc->gid == gid) {
+ fstring sid;
+ *psid = pc->sid;
+ *psidtype = pc->sidtype;
+ DEBUG(3,("fetch sid from gid cache %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(gid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Find a gid given a SID.
+*****************************************************************/
+
+static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE sidtype)
+{
+ struct gid_sid_cache *pc;
+
+ for (pc = gid_sid_cache_head; pc; pc = pc->next) {
+ if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
+ *pgid = pc->gid;
+ DEBUG(3,("fetch uid from cache %u -> %s\n",
+ (unsigned int)*pgid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(gid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Store gid to SID mapping in cache.
+*****************************************************************/
+
+static void store_gid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, gid_t gid)
+{
+ struct gid_sid_cache *pc;
+
+ if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
+ /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
+ struct gid_sid_cache *pc_next;
+ size_t i;
+
+ for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
+ ;
+ for(; pc; pc = pc_next) {
+ pc_next = pc->next;
+ DLIST_REMOVE(gid_sid_cache_head,pc);
+ SAFE_FREE(pc);
+ n_gid_sid_cache--;
+ }
+ }
+
+ pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache));
+ if (!pc)
+ return;
+ pc->gid = gid;
+ sid_copy(&pc->sid, psid);
+ pc->sidtype = sidtype;
+ DLIST_ADD(gid_sid_cache_head, pc);
+ n_gid_sid_cache++;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert uid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+ uid_t low, high;
+ enum SID_NAME_USE sidtype;
+ fstring sid;
+
+ if (fetch_sid_from_uid_cache(psid, &sidtype, uid))
+ return psid;
+
+ if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) {
+ if (winbind_uid_to_sid(psid, uid)) {
+
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_uid_sid_cache(psid, SID_NAME_USER, uid);
+ return psid;
+ }
+ }
+
+ local_uid_to_sid(psid, uid);
+
+ DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_uid_sid_cache(psid, SID_NAME_USER, uid);
+
+ return psid;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert gid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ gid_t low, high;
+ enum SID_NAME_USE sidtype;
+ fstring sid;
+
+ if (fetch_sid_from_gid_cache(psid, &sidtype, gid))
+ return psid;
+
+ if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) {
+ if (winbind_gid_to_sid(psid, gid)) {
+
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid);
+ return psid;
+ }
+ }
+
+ local_gid_to_sid(psid, gid);
+
+ DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid);
+
+ return psid;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to uid function.
+ Tries winbind first - then uses local lookup.
+ Returns True if this name is a user sid and the conversion
+ was done correctly, False if not. sidtype is set by this function.
+*****************************************************************/
+
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+ BOOL ret;
+
+ if (fetch_uid_from_cache(puid, psid, *sidtype))
+ return True;
+
+ /* if we know its local then don't try winbindd */
+ if (sid_compare_domain(&global_sam_sid, psid) == 0) {
+ ret = local_sid_to_uid(puid, psid, sidtype);
+ if (ret)
+ store_uid_sid_cache(psid, *sidtype, *puid);
+ return ret;
+ }
+
+ *sidtype = SID_NAME_UNKNOWN;
+
+ /*
+ * First we must look up the name and decide if this is a user sid.
+ */
+
+ if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) {
+ DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
+ sid_to_string(sid_str, psid) ));
+
+ ret = local_sid_to_uid(puid, psid, sidtype);
+ if (ret)
+ store_uid_sid_cache(psid, *sidtype, *puid);
+ return ret;
+ }
+
+ /*
+ * Ensure this is a user sid.
+ */
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
+ (unsigned int)name_type ));
+ return False;
+ }
+
+ *sidtype = SID_NAME_USER;
+
+ /*
+ * Get the uid for this SID.
+ */
+
+ if (!winbind_sid_to_uid(puid, psid)) {
+ DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
+ sid_to_string(sid_str, psid) ));
+ ret = local_sid_to_uid(puid, psid, sidtype);;
+ if (ret)
+ store_uid_sid_cache(psid, *sidtype, *puid);
+ return ret;
+ }
+
+ DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
+ sid_to_string(sid_str, psid),
+ (unsigned int)*puid ));
+
+ store_uid_sid_cache(psid, *sidtype, *puid);
+ return True;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to gid function.
+ Tries winbind first - then uses local lookup.
+ Returns True if this name is a user sid and the conversion
+ was done correctly, False if not.
+*****************************************************************/
+
+BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+ BOOL ret;
+
+ *sidtype = SID_NAME_UNKNOWN;
+
+ if (fetch_gid_from_cache(pgid, psid, *sidtype))
+ return True;
+
+ /*
+ * First we must look up the name and decide if this is a group sid.
+ */
+
+ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
+ sid_to_string(sid_str, psid) ));
+
+ ret = local_sid_to_gid(pgid, psid, sidtype);
+ if (ret)
+ store_gid_sid_cache(psid, *sidtype, *pgid);
+ return ret;
+ }
+
+ /*
+ * Ensure this is a group sid.
+ */
+
+ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
+ DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
+ (unsigned int)name_type ));
+
+ ret = local_sid_to_gid(pgid, psid, sidtype);
+ if (ret)
+ store_gid_sid_cache(psid, *sidtype, *pgid);
+ return ret;
+ }
+
+ *sidtype = name_type;
+
+ /*
+ * Get the gid for this SID.
+ */
+
+ if (!winbind_sid_to_gid(pgid, psid)) {
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
+ sid_to_string(sid_str, psid) ));
+ return False;
+ }
+
+ DEBUG(10,("sid_to_gid: winbindd %s -> %u\n",
+ sid_to_string(sid_str, psid),
+ (unsigned int)*pgid ));
+
+ store_gid_sid_cache(psid, *sidtype, *pgid);
+ return True;
+}
diff --git a/source/smbd/utmp.c b/source/smbd/utmp.c
index a521d0113d4..92e001cd036 100644
--- a/source/smbd/utmp.c
+++ b/source/smbd/utmp.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
utmp routines
Copyright (C) T.D.Lee@durham.ac.uk 1999
Heavily modified by Andrew Bartlett and Tridge, April 2001
@@ -21,6 +22,8 @@
#include "includes.h"
+#ifdef WITH_UTMP
+
/****************************************************************************
Reflect connection status in utmp/wtmp files.
T.D.Lee@durham.ac.uk September 1999
@@ -79,11 +82,11 @@ lastlog:
Notes:
Each connection requires a small number (starting at 0, working up)
- to represent the line. This must be unique within and across all
- smbd processes. It is the 'id_num' from Samba's session.c code.
+ to represent the line (unum). This must be unique within and across
+ all smbd processes.
The 4 byte 'ut_id' component is vital to distinguish connections,
- of which there could be several hundred or even thousand.
+ of which there could be several hundered or even thousand.
Entries seem to be printable characters, with optional NULL pads.
We need to be distinct from other entries in utmp/wtmp.
@@ -103,27 +106,13 @@ Notes:
Arbitrarily I have chosen to use a distinctive 'SM' for the
first two bytes.
- The remaining two bytes encode the session 'id_num' (see above).
- Our caller (session.c) should note our 16-bit limitation.
-
-****************************************************************************/
-
-#ifndef WITH_UTMP
-/*
- * Not WITH_UTMP? Simply supply dummy routines.
- */
+ The remaining two encode the "unum" (see above).
-void sys_utmp_claim(const char *username, const char *hostname,
- struct in_addr *ipaddr,
- const char *id_str, int id_num)
-{}
+ For "utmp consolidate" the suggestion was made to encode the pid into
+ those remaining two bytes (16 bits). But recent UNIX (e.g Solaris 8)
+ is migrating to pids > 16 bits, so we ought not to do this.
-void sys_utmp_yield(const char *username, const char *hostname,
- struct in_addr *ipaddr,
- const char *id_str, int id_num)
-{}
-
-#else /* WITH_UTMP */
+****************************************************************************/
#include <utmp.h>
@@ -138,6 +127,33 @@ void sys_utmp_yield(const char *username, const char *hostname,
#endif
/****************************************************************************
+ Obtain/release a small number (0 upwards) unique within and across smbds.
+****************************************************************************/
+/*
+ * Need a "small" number to represent this connection, unique within this
+ * smbd and across all smbds.
+ *
+ * claim:
+ * Start at 0, hunt up for free, unique number "unum" by attempting to
+ * store it as a key in a tdb database:
+ * key: unum data: pid+conn
+ * Also store its inverse, ready for yield function:
+ * key: pid+conn data: unum
+ *
+ * yield:
+ * Find key: pid+conn; data is unum; delete record
+ * Find key: unum ; delete record.
+ *
+ * Comment:
+ * The claim algorithm (a "for" loop attempting to store numbers in a tdb
+ * database) will be increasingly inefficient with larger numbers of
+ * connections. Is it possible to write a suitable primitive within tdb?
+ *
+ * However, by also storing the inverse key/data pair, we at least make
+ * the yield algorithm efficient.
+ */
+
+/****************************************************************************
Default paths to various {u,w}tmp{,x} files.
****************************************************************************/
@@ -217,13 +233,13 @@ static void uw_pathname(pstring fname, const char *uw_name, const char *uw_defau
/* For w-files, first look for explicit "wtmp dir" */
if (uw_name[0] == 'w') {
pstrcpy(dirname,lp_wtmpdir());
- trim_char(dirname,'\0','/');
+ trim_string(dirname,"","/");
}
/* For u-files and non-explicit w-dir, look for "utmp dir" */
if (dirname == 0 || strlen(dirname) == 0) {
pstrcpy(dirname,lp_utmpdir());
- trim_char(dirname,'\0','/');
+ trim_string(dirname,"","/");
}
/* If explicit directory above, use it */
@@ -283,12 +299,8 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
* man page appears not to specify (hints non-NULL)
* A correspondent suggest at least ut_name should be NULL
*/
-#if defined(HAVE_UT_UT_NAME)
memset((char *)&u->ut_name, '\0', sizeof(u->ut_name));
-#endif
-#if defined(HAVE_UT_UT_HOST)
memset((char *)&u->ut_host, '\0', sizeof(u->ut_host));
-#endif
}
/* Stolen from logwtmp function in libutil.
* May be more locking/blocking is needed?
@@ -410,9 +422,7 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
else
ux.ut_syslen = 0;
#endif
-#if defined(HAVE_UT_UT_HOST)
utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));
-#endif
uw_pathname(uname, "utmpx", ux_pathname);
uw_pathname(wname, "wtmpx", wx_pathname);
@@ -448,7 +458,7 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
static int ut_id_encode(int i, char *fourbyte)
{
int nbase;
- const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
fourbyte[0] = 'S';
fourbyte[1] = 'M';
@@ -475,7 +485,6 @@ static int ut_id_encode(int i, char *fourbyte)
*/
static BOOL sys_utmp_fill(struct utmp *u,
const char *username, const char *hostname,
- struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct timeval timeval;
@@ -495,10 +504,14 @@ static BOOL sys_utmp_fill(struct utmp *u,
/*
* ut_line:
* If size limit proves troublesome, then perhaps use "ut_id_encode()".
+ *
+ * Temporary variable "line_tmp" avoids trouble:
+ * o with unwanted trailing NULL if ut_line full;
+ * o with overflow if ut_line would be more than full.
*/
if (strlen(id_str) > sizeof(u->ut_line)) {
- DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n",
- id_str, (unsigned long)sizeof(u->ut_line)));
+ DEBUG(1,("id_str [%s] is too long for %d char utmp field\n",
+ id_str, sizeof(u->ut_line)));
return False;
}
utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
@@ -526,9 +539,8 @@ static BOOL sys_utmp_fill(struct utmp *u,
#if defined(HAVE_UT_UT_HOST)
utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
#endif
+
#if defined(HAVE_UT_UT_ADDR)
- if (ipaddr)
- u->ut_addr = ipaddr->s_addr;
/*
* "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20.
* Volunteer to implement, please ...
@@ -550,7 +562,6 @@ static BOOL sys_utmp_fill(struct utmp *u,
****************************************************************************/
void sys_utmp_yield(const char *username, const char *hostname,
- struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct utmp u;
@@ -566,7 +577,7 @@ void sys_utmp_yield(const char *username, const char *hostname,
u.ut_type = DEAD_PROCESS;
#endif
- if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
+ if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return;
sys_utmp_update(&u, NULL, False);
}
@@ -576,7 +587,6 @@ void sys_utmp_yield(const char *username, const char *hostname,
****************************************************************************/
void sys_utmp_claim(const char *username, const char *hostname,
- struct in_addr *ipaddr,
const char *id_str, int id_num)
{
struct utmp u;
@@ -587,9 +597,11 @@ void sys_utmp_claim(const char *username, const char *hostname,
u.ut_type = USER_PROCESS;
#endif
- if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
+ if (!sys_utmp_fill(&u, username, hostname, id_str, id_num)) return;
sys_utmp_update(&u, hostname, True);
}
-#endif /* WITH_UTMP */
+#else /* WITH_UTMP */
+ void dummy_utmp(void) {}
+#endif
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 5393dfc7556..6a36bd5ccb7 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Wrap disk only vfs functions to sidestep dodgy compilers.
Copyright (C) Tim Potter 1998
@@ -20,95 +21,55 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-
-/* Check for NULL pointer parameters in vfswrap_* functions */
-
/* We don't want to have NULL function pointers lying around. Someone
is sure to try and execute them. These stubs are used to prevent
this possibility. */
-int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
+int vfswrap_dummy_connect(connection_struct *conn, const char *service, const char *user)
{
return 0; /* Return >= 0 for success */
}
-void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn)
+void vfswrap_dummy_disconnect(connection_struct *conn)
{
}
/* Disk operations */
-SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
- SMB_BIG_UINT result;
-
- result = sys_disk_free(path, small_query, bsize, dfree, dsize);
- return result;
-}
-
-int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_get_quota);
- result = sys_get_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_get_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_set_quota);
- result = sys_set_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_set_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
+ SMB_BIG_UINT result;
-int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- errno = ENOSYS;
- return -1; /* Not implemented. */
+ result = sys_disk_free(path, small_query, bsize, dfree, dsize);
+ return result;
}
/* Directory operations */
-DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
+DIR *vfswrap_opendir(connection_struct *conn, const char *fname)
{
- DIR *result;
+ DIR *result;
- START_PROFILE(syscall_opendir);
- result = opendir(fname);
- END_PROFILE(syscall_opendir);
- return result;
+ START_PROFILE(syscall_opendir);
+
+ result = opendir(fname);
+ END_PROFILE(syscall_opendir);
+ return result;
}
-struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ struct dirent *result;
- START_PROFILE(syscall_readdir);
- result = readdir(dirp);
- END_PROFILE(syscall_readdir);
- return result;
+ START_PROFILE(syscall_readdir);
+
+ result = readdir(dirp);
+ END_PROFILE(syscall_readdir);
+ return result;
}
-int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode)
{
int result;
BOOL has_dacl = False;
@@ -129,161 +90,96 @@ int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char
* mess up any inherited ACL bits that were set. JRA.
*/
int saved_errno = errno; /* We may get ENOSYS */
- if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS))
- errno = saved_errno;
+ if (conn->vfs_ops.chmod_acl != NULL) {
+ if ((conn->vfs_ops.chmod_acl(conn, path, mode) == -1) && (errno == ENOSYS))
+ errno = saved_errno;
+ }
}
END_PROFILE(syscall_mkdir);
return result;
}
-int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+int vfswrap_rmdir(connection_struct *conn, const char *path)
{
- int result;
+ int result;
- START_PROFILE(syscall_rmdir);
- result = rmdir(path);
- END_PROFILE(syscall_rmdir);
- return result;
+ START_PROFILE(syscall_rmdir);
+
+ result = rmdir(path);
+ END_PROFILE(syscall_rmdir);
+ return result;
}
-int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+int vfswrap_closedir(connection_struct *conn, DIR *dirp)
{
- int result;
+ int result;
- START_PROFILE(syscall_closedir);
- result = closedir(dirp);
- END_PROFILE(syscall_closedir);
- return result;
+ START_PROFILE(syscall_closedir);
+
+ result = closedir(dirp);
+ END_PROFILE(syscall_closedir);
+ return result;
}
/* File operations */
-int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
+int vfswrap_open(connection_struct *conn, const char *fname, int flags, mode_t mode)
{
int result;
START_PROFILE(syscall_open);
+
result = sys_open(fname, flags, mode);
END_PROFILE(syscall_open);
return result;
}
-int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
+int vfswrap_close(files_struct *fsp, int fd)
{
- int result;
+ int result;
- START_PROFILE(syscall_close);
-
- result = close(fd);
- END_PROFILE(syscall_close);
- return result;
-}
-
-ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
-{
- ssize_t result;
+ START_PROFILE(syscall_close);
- START_PROFILE_BYTES(syscall_read, n);
- result = sys_read(fd, data, n);
- END_PROFILE(syscall_read);
- return result;
+ result = close(fd);
+ END_PROFILE(syscall_close);
+ return result;
}
-ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data,
- size_t n, SMB_OFF_T offset)
+ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n)
{
- ssize_t result;
-
-#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
- START_PROFILE_BYTES(syscall_pread, n);
- result = sys_pread(fd, data, n, offset);
- END_PROFILE(syscall_pread);
-
- if (result == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be seeked (sought?) on. */
- result = SMB_VFS_READ(fsp, fd, data, n);
- fsp->pos = 0;
- }
-
-#else /* HAVE_PREAD */
- SMB_OFF_T curr;
- int lerrno;
-
- curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- if (curr == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be seeked (sought?) on. */
- result = SMB_VFS_READ(fsp, fd, data, n);
- fsp->pos = 0;
- return result;
- }
-
- if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
- return -1;
- }
-
- errno = 0;
- result = SMB_VFS_READ(fsp, fd, data, n);
- lerrno = errno;
-
- SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
- errno = lerrno;
+ ssize_t result;
-#endif /* HAVE_PREAD */
+ START_PROFILE_BYTES(syscall_read, n);
- return result;
+ result = sys_read(fd, data, n);
+ END_PROFILE(syscall_read);
+ return result;
}
-ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
+ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n)
{
- ssize_t result;
+ ssize_t result;
- START_PROFILE_BYTES(syscall_write, n);
- result = sys_write(fd, data, n);
- END_PROFILE(syscall_write);
- return result;
+ START_PROFILE_BYTES(syscall_write, n);
+
+ result = sys_write(fd, data, n);
+ END_PROFILE(syscall_write);
+ return result;
}
-ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data,
- size_t n, SMB_OFF_T offset)
+ssize_t vfswrap_sendfile(int tofd, struct files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
+ SMB_OFF_T offset, size_t n)
{
ssize_t result;
-#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
- START_PROFILE_BYTES(syscall_pwrite, n);
- result = sys_pwrite(fd, data, n, offset);
- END_PROFILE(syscall_pwrite);
-
- if (result == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be sought on. */
- result = SMB_VFS_WRITE(fsp, fd, data, n);
- }
-
-#else /* HAVE_PWRITE */
- SMB_OFF_T curr;
- int lerrno;
-
- curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- if (curr == -1) {
- return -1;
- }
-
- if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
- return -1;
- }
-
- result = SMB_VFS_WRITE(fsp, fd, data, n);
- lerrno = errno;
-
- SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
- errno = lerrno;
-
-#endif /* HAVE_PWRITE */
-
+ START_PROFILE_BYTES(syscall_sendfile, n);
+ result = sys_sendfile(tofd, fromfd, hdr, offset, n);
+ END_PROFILE(syscall_sendfile);
return result;
}
-SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
+SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
{
SMB_OFF_T result = 0;
@@ -309,19 +205,8 @@ SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filede
return result;
}
-ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
- SMB_OFF_T offset, size_t n)
-{
- ssize_t result;
-
- START_PROFILE_BYTES(syscall_sendfile, n);
- result = sys_sendfile(tofd, fromfd, hdr, offset, n);
- END_PROFILE(syscall_sendfile);
- return result;
-}
-
/*********************************************************
- For rename across filesystems Patch from Warren Birnbaum
+ For rename across filesystems Patch from Warren Birnbaum
<warrenb@hpcvscdp.cv.hp.com>
**********************************************************/
@@ -359,11 +244,7 @@ static int copy_reg(const char *source, const char *dest)
* But root probably wants to know, e.g. if NFS disallows it.
*/
-#ifdef HAVE_FCHOWN
if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
-#else
- if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
-#endif
goto err;
/*
@@ -381,7 +262,7 @@ static int copy_reg(const char *source, const char *dest)
if (close (ifd) == -1)
goto err;
- if (close (ofd) == -1)
+ if (close (ofd) == -1)
return -1;
/* Try to copy the old file's modtime and access time. */
@@ -390,7 +271,7 @@ static int copy_reg(const char *source, const char *dest)
tv.actime = source_stats.st_atime;
tv.modtime = source_stats.st_mtime;
- utime(dest, &tv);
+ utime (dest, &tv);
}
if (unlink (source) == -1)
@@ -399,7 +280,6 @@ static int copy_reg(const char *source, const char *dest)
return 0;
err:
-
saved_errno = errno;
if (ifd != -1)
close(ifd);
@@ -409,80 +289,79 @@ static int copy_reg(const char *source, const char *dest)
return -1;
}
-int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
+int vfswrap_rename(connection_struct *conn, const char *oldname, const char *newname)
{
int result;
START_PROFILE(syscall_rename);
- result = rename(old, new);
+ result = rename(oldname, newname);
if (errno == EXDEV) {
/* Rename across filesystems needed. */
- result = copy_reg(old, new);
+ result = copy_reg(oldname, newname);
}
-
END_PROFILE(syscall_rename);
return result;
}
-int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
+int vfswrap_fsync(files_struct *fsp, int fd)
{
#ifdef HAVE_FSYNC
- int result;
+ int result;
- START_PROFILE(syscall_fsync);
- result = fsync(fd);
- END_PROFILE(syscall_fsync);
- return result;
+ START_PROFILE(syscall_fsync);
+ result = fsync(fd);
+ END_PROFILE(syscall_fsync);
+ return result;
#else
return 0;
#endif
}
-int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+int vfswrap_stat(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
{
- int result;
+ int result;
- START_PROFILE(syscall_stat);
- result = sys_stat(fname, sbuf);
- END_PROFILE(syscall_stat);
- return result;
+ START_PROFILE(syscall_stat);
+ result = sys_stat(fname, sbuf);
+ END_PROFILE(syscall_stat);
+ return result;
}
-int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
{
- int result;
+ int result;
- START_PROFILE(syscall_fstat);
- result = sys_fstat(fd, sbuf);
- END_PROFILE(syscall_fstat);
- return result;
+ START_PROFILE(syscall_fstat);
+ result = sys_fstat(fd, sbuf);
+ END_PROFILE(syscall_fstat);
+ return result;
}
-int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
+int vfswrap_lstat(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
{
- int result;
+ int result;
- START_PROFILE(syscall_lstat);
- result = sys_lstat(path, sbuf);
- END_PROFILE(syscall_lstat);
- return result;
+ START_PROFILE(syscall_lstat);
+ result = sys_lstat(path, sbuf);
+ END_PROFILE(syscall_lstat);
+ return result;
}
-int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+int vfswrap_unlink(connection_struct *conn, const char *path)
{
- int result;
+ int result;
- START_PROFILE(syscall_unlink);
- result = unlink(path);
- END_PROFILE(syscall_unlink);
- return result;
+ START_PROFILE(syscall_unlink);
+ result = unlink(path);
+ END_PROFILE(syscall_unlink);
+ return result;
}
-int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+int vfswrap_chmod(connection_struct *conn, const char *path, mode_t mode)
{
- int result;
+ int result;
- START_PROFILE(syscall_chmod);
+ START_PROFILE(syscall_chmod);
/*
* We need to do this due to the fact that the default POSIX ACL
@@ -491,9 +370,9 @@ int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char
*/
- {
+ if (conn->vfs_ops.chmod_acl != NULL) {
int saved_errno = errno; /* We might get ENOSYS */
- if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) {
+ if ((result = conn->vfs_ops.chmod_acl(conn, path, mode)) == 0) {
END_PROFILE(syscall_chmod);
return result;
}
@@ -501,14 +380,15 @@ int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char
errno = saved_errno;
}
- result = chmod(path, mode);
- END_PROFILE(syscall_chmod);
- return result;
+ result = chmod(path, mode);
+ END_PROFILE(syscall_chmod);
+ return result;
}
-int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
+int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode)
{
int result;
+ struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
START_PROFILE(syscall_fchmod);
@@ -518,9 +398,9 @@ int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t
* group owner bits directly. JRA.
*/
- {
+ if (vfs_ops->fchmod_acl != NULL) {
int saved_errno = errno; /* We might get ENOSYS */
- if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
+ if ((result = vfs_ops->fchmod_acl(fsp, fd, mode)) == 0) {
END_PROFILE(syscall_chmod);
return result;
}
@@ -534,64 +414,64 @@ int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t
result = -1;
errno = ENOSYS;
#endif
-
END_PROFILE(syscall_fchmod);
return result;
}
-int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+int vfswrap_chown(connection_struct *conn, const char *path, uid_t uid, gid_t gid)
{
- int result;
+ int result;
- START_PROFILE(syscall_chown);
- result = sys_chown(path, uid, gid);
- END_PROFILE(syscall_chown);
- return result;
+ START_PROFILE(syscall_chown);
+ result = sys_chown(path, uid, gid);
+ END_PROFILE(syscall_chown);
+ return result;
}
-int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
+int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid)
{
#ifdef HAVE_FCHOWN
- int result;
+ int result;
- START_PROFILE(syscall_fchown);
- result = fchown(fd, uid, gid);
- END_PROFILE(syscall_fchown);
- return result;
+ START_PROFILE(syscall_fchown);
+
+ result = fchown(fd, uid, gid);
+ END_PROFILE(syscall_fchown);
+ return result;
#else
- errno = ENOSYS;
- return -1;
+ errno = ENOSYS;
+ return -1;
#endif
}
-int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+int vfswrap_chdir(connection_struct *conn, const char *path)
{
- int result;
+ int result;
- START_PROFILE(syscall_chdir);
- result = chdir(path);
- END_PROFILE(syscall_chdir);
- return result;
+ START_PROFILE(syscall_chdir);
+ result = chdir(path);
+ END_PROFILE(syscall_chdir);
+ return result;
}
-char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path)
+char *vfswrap_getwd(connection_struct *conn, char *path)
{
- char *result;
+ char *result;
- START_PROFILE(syscall_getwd);
- result = sys_getwd(path);
- END_PROFILE(syscall_getwd);
- return result;
+ START_PROFILE(syscall_getwd);
+ result = sys_getwd(path);
+ END_PROFILE(syscall_getwd);
+ return result;
}
-int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
+int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *times)
{
- int result;
+ int result;
- START_PROFILE(syscall_utime);
- result = utime(path, times);
- END_PROFILE(syscall_utime);
- return result;
+ START_PROFILE(syscall_utime);
+ result = utime(path, times);
+ END_PROFILE(syscall_utime);
+ return result;
}
/*********************************************************************
@@ -599,21 +479,20 @@ int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char
allocate is set.
**********************************************************************/
-static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
+static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
{
+ struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
SMB_STRUCT_STAT st;
- SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ SMB_OFF_T currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
unsigned char zero_space[4096];
SMB_OFF_T space_to_write;
if (currpos == -1)
return -1;
- if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
+ if (vfs_ops->fstat(fsp, fd, &st) == -1)
return -1;
- space_to_write = len - st.st_size;
-
#ifdef S_ISFIFO
if (S_ISFIFO(st.st_mode))
return 0;
@@ -627,7 +506,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
return sys_ftruncate(fd, len);
/* Write out the real space on disk. */
- if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
+ if (vfs_ops->lseek(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
return -1;
space_to_write = len - st.st_size;
@@ -637,7 +516,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
SMB_OFF_T retlen;
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
- retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
+ retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
if (retlen <= 0)
return -1;
@@ -645,15 +524,16 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
}
/* Seek to where we were */
- if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
+ if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
return -1;
return 0;
}
-int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
+int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
{
int result = -1;
+ struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
SMB_STRUCT_STAT st;
char c = 0;
SMB_OFF_T currpos;
@@ -661,7 +541,7 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
START_PROFILE(syscall_ftruncate);
if (lp_strict_allocate(SNUM(fsp->conn))) {
- result = strict_allocate_ftruncate(handle, fsp, fd, len);
+ result = strict_allocate_ftruncate(fsp, fd, len);
END_PROFILE(syscall_ftruncate);
return result;
}
@@ -679,7 +559,7 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate. Provide alternate implementation
for this */
- currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
if (currpos == -1) {
goto done;
}
@@ -688,7 +568,7 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
size in which case the ftruncate above should have
succeeded or shorter, in which case seek to len - 1 and
write 1 byte of zero */
- if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
+ if (vfs_ops->fstat(fsp, fd, &st) == -1) {
goto done;
}
@@ -709,14 +589,14 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
goto done;
}
- if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
+ if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1)
goto done;
- if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
+ if (vfs_ops->write(fsp, fd, &c, 1)!=1)
goto done;
/* Seek to where we were */
- if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
+ if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
goto done;
result = 0;
@@ -726,37 +606,37 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
return result;
}
-BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
- BOOL result;
+ BOOL result;
- START_PROFILE(syscall_fcntl_lock);
- result = fcntl_lock(fd, op, offset, count,type);
- END_PROFILE(syscall_fcntl_lock);
- return result;
+ START_PROFILE(syscall_fcntl_lock);
+ result = fcntl_lock(fd, op, offset, count,type);
+ END_PROFILE(syscall_fcntl_lock);
+ return result;
}
-int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
+int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath)
{
- int result;
+ int result;
- START_PROFILE(syscall_symlink);
- result = sys_symlink(oldpath, newpath);
- END_PROFILE(syscall_symlink);
- return result;
+ START_PROFILE(syscall_symlink);
+ result = sys_symlink(oldpath, newpath);
+ END_PROFILE(syscall_symlink);
+ return result;
}
-int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
+int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz)
{
- int result;
+ int result;
- START_PROFILE(syscall_readlink);
- result = sys_readlink(path, buf, bufsiz);
- END_PROFILE(syscall_readlink);
- return result;
+ START_PROFILE(syscall_readlink);
+ result = sys_readlink(path, buf, bufsiz);
+ END_PROFILE(syscall_readlink);
+ return result;
}
-int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
+int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath)
{
int result;
@@ -766,7 +646,7 @@ int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char
return result;
}
-int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
+int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
{
int result;
@@ -776,7 +656,7 @@ int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char
return result;
}
-char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
+char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path)
{
char *result;
@@ -786,27 +666,27 @@ char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
+size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(fget_nt_acl);
- result = get_nt_acl(fsp, security_info, ppdesc);
+ result = get_nt_acl(fsp, ppdesc);
END_PROFILE(fget_nt_acl);
return result;
}
-size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
+size_t vfswrap_get_nt_acl(files_struct *fsp, const char *name, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(get_nt_acl);
- result = get_nt_acl(fsp, security_info, ppdesc);
+ result = get_nt_acl(fsp, ppdesc);
END_PROFILE(get_nt_acl);
return result;
}
-BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
{
BOOL result;
@@ -816,7 +696,7 @@ BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, u
return result;
}
-BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+BOOL vfswrap_set_nt_acl(files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
{
BOOL result;
@@ -826,206 +706,132 @@ BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char
return result;
}
-int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
+int vfswrap_chmod_acl(connection_struct *conn, const char *name, mode_t mode)
{
-#ifdef HAVE_NO_ACL
- errno = ENOSYS;
- return -1;
-#else
int result;
START_PROFILE(chmod_acl);
result = chmod_acl(conn, name, mode);
END_PROFILE(chmod_acl);
return result;
-#endif
}
-int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
+int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode)
{
-#ifdef HAVE_NO_ACL
- errno = ENOSYS;
- return -1;
-#else
int result;
START_PROFILE(fchmod_acl);
result = fchmod_acl(fsp, fd, mode);
END_PROFILE(fchmod_acl);
return result;
-#endif
}
-int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
{
return sys_acl_get_entry(theacl, entry_id, entry_p);
}
-int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
{
return sys_acl_get_tag_type(entry_d, tag_type_p);
}
-int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
{
return sys_acl_get_permset(entry_d, permset_p);
}
-void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
+void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
{
return sys_acl_get_qualifier(entry_d);
}
-SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
+SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
{
return sys_acl_get_file(path_p, type);
}
-SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
+SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd)
{
return sys_acl_get_fd(fd);
}
-int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
+int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset)
{
return sys_acl_clear_perms(permset);
}
-int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
{
return sys_acl_add_perm(permset, perm);
}
-char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
+char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
{
return sys_acl_to_text(theacl, plen);
}
-SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
+SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count)
{
return sys_acl_init(count);
}
-int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
{
return sys_acl_create_entry(pacl, pentry);
}
-int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
{
return sys_acl_set_tag_type(entry, tagtype);
}
-int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
+int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
{
return sys_acl_set_qualifier(entry, qual);
}
-int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
{
return sys_acl_set_permset(entry, permset);
}
-int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
+int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl )
{
return sys_acl_valid(theacl );
}
-int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
{
return sys_acl_set_file(name, acltype, theacl);
}
-int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
+int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl)
{
return sys_acl_set_fd(fd, theacl);
}
-int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path)
{
return sys_acl_delete_def_file(path);
}
-int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
{
return sys_acl_get_perm(permset, perm);
}
-int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
+int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text)
{
return sys_acl_free_text(text);
}
-int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
+int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl)
{
return sys_acl_free_acl(posix_acl);
}
-int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
+int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
{
return sys_acl_free_qualifier(qualifier, tagtype);
}
-
-/****************************************************************
- Extended attribute operations.
-*****************************************************************/
-
-ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- return sys_getxattr(path, name, value, size);
-}
-
-ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- return sys_lgetxattr(path, name, value, size);
-}
-
-ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-{
- return sys_fgetxattr(fd, name, value, size);
-}
-
-ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return sys_listxattr(path, list, size);
-}
-
-ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return sys_llistxattr(path, list, size);
-}
-
-ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
-{
- return sys_flistxattr(fd, list, size);
-}
-
-int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return sys_removexattr(path, name);
-}
-
-int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return sys_lremovexattr(path, name);
-}
-
-int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-{
- return sys_fremovexattr(fd, name);
-}
-
-int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return sys_setxattr(path, name, value, size, flags);
-}
-
-int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return sys_lsetxattr(path, name, value, size, flags);
-}
-
-int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-{
- return sys_fsetxattr(fd, name, value, size, flags);
-}
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 533220e7dfb..c72a9a28874 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -3,7 +3,6 @@
Version 1.9.
VFS initialisation and support functions
Copyright (C) Tim Potter 1999
- Copyright (C) Alexander Bokovoy 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,23 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- This work was sponsored by Optifacio Software Services, Inc.
*/
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-struct vfs_init_function_entry {
- char *name;
- vfs_op_tuple *vfs_op_tuples;
- struct vfs_init_function_entry *prev, *next;
-};
-
-static struct vfs_init_function_entry *backends = NULL;
-
/* Some structures to help us initialise the vfs operations table */
struct vfs_syminfo {
@@ -46,249 +32,146 @@ struct vfs_syminfo {
very important. They must be in the same order as defined in
vfs.h. Change at your own peril. */
-static struct vfs_ops default_vfs = {
-
- {
- /* Disk operations */
-
- vfswrap_dummy_connect,
- vfswrap_dummy_disconnect,
- vfswrap_disk_free,
- vfswrap_get_quota,
- vfswrap_set_quota,
- vfswrap_get_shadow_copy_data,
-
- /* Directory operations */
-
- vfswrap_opendir,
- vfswrap_readdir,
- vfswrap_mkdir,
- vfswrap_rmdir,
- vfswrap_closedir,
-
- /* File operations */
-
- vfswrap_open,
- vfswrap_close,
- vfswrap_read,
- vfswrap_pread,
- vfswrap_write,
- vfswrap_pwrite,
- vfswrap_lseek,
- vfswrap_sendfile,
- vfswrap_rename,
- vfswrap_fsync,
- vfswrap_stat,
- vfswrap_fstat,
- vfswrap_lstat,
- vfswrap_unlink,
- vfswrap_chmod,
- vfswrap_fchmod,
- vfswrap_chown,
- vfswrap_fchown,
- vfswrap_chdir,
- vfswrap_getwd,
- vfswrap_utime,
- vfswrap_ftruncate,
- vfswrap_lock,
- vfswrap_symlink,
- vfswrap_readlink,
- vfswrap_link,
- vfswrap_mknod,
- vfswrap_realpath,
-
- /* Windows ACL operations. */
- vfswrap_fget_nt_acl,
- vfswrap_get_nt_acl,
- vfswrap_fset_nt_acl,
- vfswrap_set_nt_acl,
-
- /* POSIX ACL operations. */
- vfswrap_chmod_acl,
- vfswrap_fchmod_acl,
-
- vfswrap_sys_acl_get_entry,
- vfswrap_sys_acl_get_tag_type,
- vfswrap_sys_acl_get_permset,
- vfswrap_sys_acl_get_qualifier,
- vfswrap_sys_acl_get_file,
- vfswrap_sys_acl_get_fd,
- vfswrap_sys_acl_clear_perms,
- vfswrap_sys_acl_add_perm,
- vfswrap_sys_acl_to_text,
- vfswrap_sys_acl_init,
- vfswrap_sys_acl_create_entry,
- vfswrap_sys_acl_set_tag_type,
- vfswrap_sys_acl_set_qualifier,
- vfswrap_sys_acl_set_permset,
- vfswrap_sys_acl_valid,
- vfswrap_sys_acl_set_file,
- vfswrap_sys_acl_set_fd,
- vfswrap_sys_acl_delete_def_file,
- vfswrap_sys_acl_get_perm,
- vfswrap_sys_acl_free_text,
- vfswrap_sys_acl_free_acl,
- vfswrap_sys_acl_free_qualifier,
-
- /* EA operations. */
- vfswrap_getxattr,
- vfswrap_lgetxattr,
- vfswrap_fgetxattr,
- vfswrap_listxattr,
- vfswrap_llistxattr,
- vfswrap_flistxattr,
- vfswrap_removexattr,
- vfswrap_lremovexattr,
- vfswrap_fremovexattr,
- vfswrap_setxattr,
- vfswrap_lsetxattr,
- vfswrap_fsetxattr
- }
+struct vfs_ops default_vfs_ops = {
+
+ /* Disk operations */
+
+ vfswrap_dummy_connect,
+ vfswrap_dummy_disconnect,
+ vfswrap_disk_free,
+
+ /* Directory operations */
+
+ vfswrap_opendir,
+ vfswrap_readdir,
+ vfswrap_mkdir,
+ vfswrap_rmdir,
+ vfswrap_closedir,
+
+ /* File operations */
+
+ vfswrap_open,
+ vfswrap_close,
+ vfswrap_read,
+ vfswrap_write,
+ vfswrap_lseek,
+ vfswrap_sendfile,
+ vfswrap_rename,
+ vfswrap_fsync,
+ vfswrap_stat,
+ vfswrap_fstat,
+ vfswrap_lstat,
+ vfswrap_unlink,
+ vfswrap_chmod,
+ vfswrap_fchmod,
+ vfswrap_chown,
+ vfswrap_fchown,
+ vfswrap_chdir,
+ vfswrap_getwd,
+ vfswrap_utime,
+ vfswrap_ftruncate,
+ vfswrap_lock,
+ vfswrap_symlink,
+ vfswrap_readlink,
+ vfswrap_link,
+ vfswrap_mknod,
+ vfswrap_realpath,
+
+ vfswrap_fget_nt_acl,
+ vfswrap_get_nt_acl,
+ vfswrap_fset_nt_acl,
+ vfswrap_set_nt_acl,
+
+ /* POSIX ACL operations. */
+#if defined(HAVE_NO_ACLS)
+ NULL,
+ NULL,
+#else
+ vfswrap_chmod_acl,
+ vfswrap_fchmod_acl,
+#endif
+ vfswrap_sys_acl_get_entry,
+ vfswrap_sys_acl_get_tag_type,
+ vfswrap_sys_acl_get_permset,
+ vfswrap_sys_acl_get_qualifier,
+ vfswrap_sys_acl_get_file,
+ vfswrap_sys_acl_get_fd,
+ vfswrap_sys_acl_clear_perms,
+ vfswrap_sys_acl_add_perm,
+ vfswrap_sys_acl_to_text,
+ vfswrap_sys_acl_init,
+ vfswrap_sys_acl_create_entry,
+ vfswrap_sys_acl_set_tag_type,
+ vfswrap_sys_acl_set_qualifier,
+ vfswrap_sys_acl_set_permset,
+ vfswrap_sys_acl_valid,
+ vfswrap_sys_acl_set_file,
+ vfswrap_sys_acl_set_fd,
+ vfswrap_sys_acl_delete_def_file,
+ vfswrap_sys_acl_get_perm,
+ vfswrap_sys_acl_free_text,
+ vfswrap_sys_acl_free_acl,
+ vfswrap_sys_acl_free_qualifier
};
/****************************************************************************
- maintain the list of available backends
+ initialise default vfs hooks
****************************************************************************/
-static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
+static BOOL vfs_init_default(connection_struct *conn)
{
- struct vfs_init_function_entry *entry = backends;
-
- while(entry) {
- if (strcmp(entry->name, name)==0) return entry;
- entry = entry->next;
- }
-
- return NULL;
-}
-
-NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples)
-{
- struct vfs_init_function_entry *entry = backends;
-
- if ((version != SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Failed to register vfs module.\n"
- "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
- "current SMB_VFS_INTERFACE_VERSION is %d.\n"
- "Please recompile against the current Samba Version!\n",
- version, SMB_VFS_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!name || !name[0] || !vfs_op_tuples) {
- DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (vfs_find_backend_entry(name)) {
- DEBUG(0,("VFS module %s already loaded!\n", name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
-
- entry = smb_xmalloc(sizeof(struct vfs_init_function_entry));
- entry->name = smb_xstrdup(name);
- entry->vfs_op_tuples = vfs_op_tuples;
+ DEBUG(3, ("Initialising default vfs hooks\n"));
- DLIST_ADD(backends, entry);
- DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
- return NT_STATUS_OK;
+ memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
+ return True;
}
/****************************************************************************
- initialise default vfs hooks
+ initialise custom vfs hooks
****************************************************************************/
-static void vfs_init_default(connection_struct *conn)
+static BOOL vfs_init_custom(connection_struct *conn)
{
- DEBUG(3, ("Initialising default vfs hooks\n"));
+ int vfs_version = -1;
+ struct vfs_ops *ops, *(*init_fptr)(int *, struct vfs_ops *);
- memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops));
- memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops));
-}
+ DEBUG(3, ("Initialising custom vfs hooks from %s\n", lp_vfsobj(SNUM(conn))));
-/****************************************************************************
- initialise custom vfs hooks
- ****************************************************************************/
+ /* Open object file */
-BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
-{
- vfs_op_tuple *ops;
- char *module_name = NULL;
- char *module_param = NULL, *p;
- int i;
- vfs_handle_struct *handle;
- struct vfs_init_function_entry *entry;
-
- if (!conn||!vfs_object||!vfs_object[0]) {
- DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n"));
+ if ((conn->dl_handle = sys_dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL)) == NULL) {
+ DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)), sys_dlerror()));
return False;
}
- if(!backends) static_init_vfs;
+ /* Get handle on vfs_init() symbol */
- DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
+ init_fptr = (struct vfs_ops *(*)(int *, struct vfs_ops *))sys_dlsym(conn->dl_handle, "vfs_init");
- module_name = smb_xstrdup(vfs_object);
+ if (init_fptr == NULL) {
+ DEBUG(0, ("No vfs_init() symbol found in %s\n", lp_vfsobj(SNUM(conn))));
+ return False;
+ }
- p = strchr(module_name, ':');
+ /* Initialise vfs_ops structure */
- if (p) {
- *p = 0;
- module_param = p+1;
- trim_char(module_param, ' ', ' ');
- }
-
- trim_char(module_name, ' ', ' ');
-
- /* First, try to load the module with the new module system */
- if((entry = vfs_find_backend_entry(module_name)) ||
- (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) &&
- (entry = vfs_find_backend_entry(module_name)))) {
-
- DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
-
- if ((ops = entry->vfs_op_tuples) == NULL) {
- DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object));
- SAFE_FREE(module_name);
- return False;
- }
- } else {
- DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
- SAFE_FREE(module_name);
+ conn->vfs_ops = default_vfs_ops;
+
+ if ((ops = init_fptr(&vfs_version, &default_vfs_ops)) == NULL) {
+ DEBUG(0, ("vfs_init function from %s failed\n", lp_vfsobj(SNUM(conn))));
return False;
}
- handle = (vfs_handle_struct *)talloc_zero(conn->mem_ctx,sizeof(vfs_handle_struct));
- if (!handle) {
- DEBUG(0,("talloc_zero() failed!\n"));
- SAFE_FREE(module_name);
+ if (vfs_version != SMB_VFS_INTERFACE_VERSION) {
+ DEBUG(0, ("vfs_init returned wrong interface version info (was %d, should be %d)\n",
+ vfs_version, SMB_VFS_INTERFACE_VERSION ));
return False;
}
- memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops));
- handle->conn = conn;
- if (module_param) {
- handle->param = talloc_strdup(conn->mem_ctx, module_param);
- }
- DLIST_ADD(conn->vfs_handles, handle);
-
- for(i=0; ops[i].op != NULL; i++) {
- DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
- if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
- /* Check whether this operation was already made opaque by different module */
- if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) {
- /* No, it isn't overloaded yet. Overload. */
- DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op;
- ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle;
- }
- }
- /* Change current VFS disposition*/
- DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op;
- ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle;
- }
-
- SAFE_FREE(module_name);
+
+ if (ops != &conn->vfs_ops) {
+ memcpy(&conn->vfs_ops, ops, sizeof(struct vfs_ops));
+ }
+
return True;
}
@@ -298,29 +181,20 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
BOOL smbd_vfs_init(connection_struct *conn)
{
- const char **vfs_objects;
- unsigned int i = 0;
- int j = 0;
-
- /* Normal share - initialise with disk access functions */
- vfs_init_default(conn);
- vfs_objects = lp_vfs_objects(SNUM(conn));
-
- /* Override VFS functions if 'vfs object' was not specified*/
- if (!vfs_objects || !vfs_objects[0])
- return True;
-
- for (i=0; vfs_objects[i] ;) {
- i++;
- }
-
- for (j=i-1; j >= 0; j--) {
- if (!vfs_init_custom(conn, vfs_objects[j])) {
- DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
+ if (*lp_vfsobj(SNUM(conn))) {
+ /* Loadable object file */
+
+ if (!vfs_init_custom(conn)) {
+ DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed\n"));
return False;
}
+
+ return True;
}
- return True;
+
+ /* Normal share - initialise with disk access functions */
+
+ return vfs_init_default(conn);
}
/*******************************************************************
@@ -335,7 +209,7 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
if (!st)
st = &st2;
- if (SMB_VFS_STAT(conn,dname,st) != 0)
+ if (vfs_stat(conn,dname,st) != 0)
return(False);
ret = S_ISDIR(st->st_mode);
@@ -346,35 +220,47 @@ BOOL vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
}
/*******************************************************************
- vfs mkdir wrapper
+ vfs mkdir wrapper that calls dos_to_unix.
********************************************************************/
-int vfs_MkDir(connection_struct *conn, const char *name, mode_t mode)
+int vfs_mkdir(connection_struct *conn, char *const fname, mode_t mode)
{
int ret;
+ pstring name;
SMB_STRUCT_STAT sbuf;
- if(!(ret=SMB_VFS_MKDIR(conn, name, mode))) {
-
- inherit_access_acl(conn, name, mode);
-
+ pstrcpy(name,dos_to_unix_static(fname)); /* paranoia copy */
+ if(!(ret=conn->vfs_ops.mkdir(conn,name,mode))) {
/*
* Check if high bits should have been set,
* then (if bits are missing): add them.
* Consider bits automagically set by UNIX, i.e. SGID bit from parent dir.
*/
if(mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
- !SMB_VFS_STAT(conn,name,&sbuf) && (mode & ~sbuf.st_mode))
- SMB_VFS_CHMOD(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode));
+ !vfs_stat(conn,name,&sbuf) && (mode & ~sbuf.st_mode))
+ vfs_chmod(conn,name,sbuf.st_mode | (mode & ~sbuf.st_mode));
}
return ret;
}
/*******************************************************************
+ vfs getwd wrapper that calls dos_to_unix.
+********************************************************************/
+
+char *vfs_getwd(connection_struct *conn, char *unix_path)
+{
+ char *wd;
+ wd = conn->vfs_ops.getwd(conn,unix_path);
+ if (wd)
+ unix_to_dos(wd);
+ return wd;
+}
+
+/*******************************************************************
Check if an object exists in the vfs.
********************************************************************/
-BOOL vfs_object_exist(connection_struct *conn,const char *fname,SMB_STRUCT_STAT *sbuf)
+BOOL vfs_object_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_STAT st;
@@ -383,7 +269,7 @@ BOOL vfs_object_exist(connection_struct *conn,const char *fname,SMB_STRUCT_STAT
ZERO_STRUCTP(sbuf);
- if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
+ if (vfs_stat(conn,fname,sbuf) == -1)
return(False);
return True;
}
@@ -401,7 +287,7 @@ BOOL vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *
ZERO_STRUCTP(sbuf);
- if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
+ if (vfs_stat(conn,fname,sbuf) == -1)
return False;
return(S_ISREG(sbuf->st_mode));
}
@@ -416,30 +302,8 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
while (total < byte_count)
{
- ssize_t ret = SMB_VFS_READ(fsp, fsp->fd, buf + total,
- byte_count - total);
-
- if (ret == 0) return total;
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- else
- return -1;
- }
- total += ret;
- }
- return (ssize_t)total;
-}
-
-ssize_t vfs_pread_data(files_struct *fsp, char *buf,
- size_t byte_count, SMB_OFF_T offset)
-{
- size_t total=0;
-
- while (total < byte_count)
- {
- ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fd, buf + total,
- byte_count - total, offset + total);
+ ssize_t ret = fsp->conn->vfs_ops.read(fsp, fsp->fd, buf + total,
+ byte_count - total);
if (ret == 0) return total;
if (ret == -1) {
@@ -463,7 +327,7 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
ssize_t ret;
while (total < N) {
- ret = SMB_VFS_WRITE(fsp,fsp->fd,buffer + total,N - total);
+ ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
if (ret == -1)
return -1;
@@ -472,28 +336,10 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
total += ret;
}
- return (ssize_t)total;
-}
-
-ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer,
- size_t N, SMB_OFF_T offset)
-{
- size_t total=0;
- ssize_t ret;
-
- while (total < N) {
- ret = SMB_VFS_PWRITE(fsp, fsp->fd, buffer + total,
- N - total, offset + total);
-
- if (ret == -1)
- return -1;
- if (ret == 0)
- return total;
- total += ret;
- }
return (ssize_t)total;
}
+
/****************************************************************************
An allocate file space call using the vfs interface.
Allocates space for a file from a filedescriptor.
@@ -505,6 +351,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
int ret;
SMB_STRUCT_STAT st;
connection_struct *conn = fsp->conn;
+ struct vfs_ops *vfs_ops = &conn->vfs_ops;
SMB_BIG_UINT space_avail;
SMB_BIG_UINT bsize,dfree,dsize;
@@ -521,7 +368,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
return -1;
}
- ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
+ ret = vfs_fstat(fsp,fsp->fd,&st);
if (ret == -1)
return ret;
@@ -535,7 +382,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
fsp->fsp_name, (double)st.st_size ));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
- if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
+ if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
set_filelen_write_cache(fsp, len);
}
return ret;
@@ -548,7 +395,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
len -= st.st_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
- space_avail = SMB_VFS_DISK_FREE(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
+ space_avail = conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail ));
@@ -574,7 +421,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
release_level_2_oplocks_on_change(fsp);
DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
- if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, len)) != -1)
+ if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1)
set_filelen_write_cache(fsp, len);
return ret;
@@ -589,12 +436,12 @@ static files_struct *out_fsp;
static ssize_t read_fn(int fd, void *buf, size_t len)
{
- return SMB_VFS_READ(in_fsp, fd, buf, len);
+ return in_fsp->conn->vfs_ops.read(in_fsp, fd, buf, len);
}
static ssize_t write_fn(int fd, const void *buf, size_t len)
{
- return SMB_VFS_WRITE(out_fsp, fd, buf, len);
+ return out_fsp->conn->vfs_ops.write(out_fsp, fd, buf, len);
}
SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
@@ -611,13 +458,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
char *vfs_readdirname(connection_struct *conn, void *p)
{
- struct dirent *ptr= NULL;
+ struct dirent *ptr;
char *dname;
if (!p)
return(NULL);
- ptr = (struct dirent *)SMB_VFS_READDIR(conn,p);
+ ptr = (struct dirent *)conn->vfs_ops.readdir(conn,p);
if (!ptr)
return(NULL);
@@ -633,9 +480,82 @@ char *vfs_readdirname(connection_struct *conn, void *p)
dname = dname - 2;
#endif
+ {
+ static pstring buf;
+ memcpy(buf, dname, NAMLEN(ptr)+1);
+ unix_to_dos(buf);
+ dname = buf;
+ }
+
return(dname);
}
+/* VFS options not quite working yet */
+
+#if 0
+
+/***************************************************************************
+ handle the interpretation of the vfs option parameter
+ *************************************************************************/
+static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
+{
+ struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
+ int i;
+
+ /* Create new vfs option */
+
+ new_option = (struct vfs_options *)malloc(sizeof(*new_option));
+ if (new_option == NULL) {
+ return False;
+ }
+
+ ZERO_STRUCTP(new_option);
+
+ /* Get name and value */
+
+ new_option->name = strtok(pszParmValue, "=");
+
+ if (new_option->name == NULL) {
+ return False;
+ }
+
+ while(isspace(*new_option->name)) {
+ new_option->name++;
+ }
+
+ for (i = strlen(new_option->name); i > 0; i--) {
+ if (!isspace(new_option->name[i - 1])) break;
+ }
+
+ new_option->name[i] = '\0';
+ new_option->name = strdup(new_option->name);
+
+ new_option->value = strtok(NULL, "=");
+
+ if (new_option->value != NULL) {
+
+ while(isspace(*new_option->value)) {
+ new_option->value++;
+ }
+
+ for (i = strlen(new_option->value); i > 0; i--) {
+ if (!isspace(new_option->value[i - 1])) break;
+ }
+
+ new_option->value[i] = '\0';
+ new_option->value = strdup(new_option->value);
+ }
+
+ /* Add to list */
+
+ DLIST_ADD(*options, new_option);
+
+ return True;
+}
+
+#endif
+
+
/*******************************************************************
A wrapper for vfs_chdir().
********************************************************************/
@@ -651,9 +571,9 @@ int vfs_ChDir(connection_struct *conn, const char *path)
if (*path == '/' && strcsequal(LastDir,path))
return(0);
- DEBUG(4,("vfs_ChDir to %s\n",path));
+ DEBUG(3,("vfs_ChDir to %s\n",path));
- res = SMB_VFS_CHDIR(conn,path);
+ res = vfs_chdir(conn,path);
if (!res)
pstrcpy(LastDir,path);
return(res);
@@ -662,7 +582,7 @@ int vfs_ChDir(connection_struct *conn, const char *path)
/* number of list structures for a caching GetWd function. */
#define MAX_GETWDCACHE (50)
-static struct {
+struct {
SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
char *dos_path; /* The pathname in DOS format. */
@@ -710,7 +630,7 @@ char *vfs_GetWd(connection_struct *conn, char *path)
*s = 0;
if (!use_getwd_cache)
- return(SMB_VFS_GETWD(conn,path));
+ return(vfs_getwd(conn,path));
/* init the cache */
if (!getwd_cache_init) {
@@ -724,9 +644,9 @@ char *vfs_GetWd(connection_struct *conn, char *path)
/* Get the inode of the current directory, if this doesn't work we're
in trouble :-) */
- if (SMB_VFS_STAT(conn, ".",&st) == -1) {
+ if (vfs_stat(conn, ".",&st) == -1) {
DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
- return(SMB_VFS_GETWD(conn,path));
+ return(vfs_getwd(conn,path));
}
@@ -734,13 +654,13 @@ char *vfs_GetWd(connection_struct *conn, char *path)
if (ino_list[i].valid) {
/* If we have found an entry with a matching inode and dev number
- then find the inode number for the directory in the cached string.
- If this agrees with that returned by the stat for the current
- directory then all is o.k. (but make sure it is a directory all
- the same...) */
+ then find the inode number for the directory in the cached string.
+ If this agrees with that returned by the stat for the current
+ directory then all is o.k. (but make sure it is a directory all
+ the same...) */
if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) {
- if (SMB_VFS_STAT(conn,ino_list[i].dos_path,&st2) == 0) {
+ if (vfs_stat(conn,ino_list[i].dos_path,&st2) == 0) {
if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev &&
(st2.st_mode & S_IFMT) == S_IFDIR) {
pstrcpy (path, ino_list[i].dos_path);
@@ -748,9 +668,10 @@ char *vfs_GetWd(connection_struct *conn, char *path)
/* promote it for future use */
array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
return (path);
+
} else {
/* If the inode is different then something's changed,
- scrub the entry and start from scratch. */
+ scrub the entry and start from scratch. */
ino_list[i].valid = False;
}
}
@@ -762,8 +683,8 @@ char *vfs_GetWd(connection_struct *conn, char *path)
The very slow getcwd, which spawns a process on some systems, or the
not quite so bad getwd. */
- if (!SMB_VFS_GETWD(conn,s)) {
- DEBUG(0,("vfs_GetWd: SMB_VFS_GETWD call failed, errno %s\n",strerror(errno)));
+ if (!vfs_getwd(conn,s)) {
+ DEBUG(0,("vfs_GetWd: vfs_getwd call failed, errno %s\n",strerror(errno)));
return (NULL);
}
@@ -788,7 +709,7 @@ char *vfs_GetWd(connection_struct *conn, char *path)
/* check if the file 'nmae' is a symlink, in that case check that it point to
a file that reside under the 'dir' tree */
-static BOOL readlink_check(connection_struct *conn, const char *dir, char *name)
+static BOOL readlink_check(connection_struct *conn, char *dir, char *name)
{
BOOL ret = True;
pstring flink;
@@ -819,8 +740,8 @@ static BOOL readlink_check(connection_struct *conn, const char *dir, char *name)
realdir[reallen] = 0;
}
- if (SMB_VFS_READLINK(conn, name, flink, sizeof(pstring) -1) != -1) {
- DEBUG(3,("readlink_check: file path name %s is a symlink\nChecking it's path\n", name));
+ if (conn->vfs_ops.readlink(conn, name, flink, sizeof(pstring) -1) != -1) {
+ DEBUG(3,("reduce_name: file path name %s is a symlink\nChecking it's path\n", name));
if (*flink == '/') {
pstrcpy(cleanlink, flink);
} else {
@@ -845,9 +766,10 @@ static BOOL readlink_check(connection_struct *conn, const char *dir, char *name)
Reduce a file name, removing .. elements and checking that
it is below dir in the heirachy. This uses vfs_GetWd() and so must be run
on the system that has the referenced file system.
+ Widelinks are allowed if widelinks is true.
********************************************************************/
-BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
+BOOL reduce_name(connection_struct *conn, char *s,char *dir,BOOL widelinks)
{
#ifndef REDUCE_PATHS
return True;
@@ -861,13 +783,27 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
*dir2 = *wd = *base_name = *newname = 0;
+ if (widelinks) {
+ unix_clean_name(s);
+ /* can't have a leading .. */
+ if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) {
+ DEBUG(3,("Illegal file name? (%s)\n",s));
+ return(False);
+ }
+
+ if (strlen(s) == 0)
+ pstrcpy(s,"./");
+
+ return(True);
+ }
+
DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
- /* We know there are no double slashes as this comes from srvstr_get_path().
- and has gone through check_path_syntax(). JRA */
+ /* remove any double slashes */
+ all_string_sub(s,"//","/",0);
pstrcpy(base_name,s);
- p = strrchr_m(base_name,'/');
+ p = strrchr(base_name,'/');
if (!p)
return readlink_check(conn, dir, s);
@@ -915,19 +851,17 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
{
size_t l = strlen(dir2);
- char *last_slash = strrchr_m(dir2, '/');
-
- if (last_slash && (last_slash[1] == '\0'))
+ if (dir2[l-1] == '/')
l--;
if (strncmp(newname,dir2,l) != 0) {
vfs_ChDir(conn,wd);
- DEBUG(2,("Bad access attempt: s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
+ DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
return(False);
}
if (!readlink_check(conn, dir, newname)) {
- DEBUG(2, ("Bad access attemt: %s is a symlink outside the share path", s));
+ DEBUG(2, ("Bad access attemt? %s is a symlink outside the share path", s));
return(False);
}
@@ -949,3 +883,4 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir)
return(True);
#endif
}
+
diff --git a/source/python/py_winreg.h b/source/smbwrapper/init.c
index 95d5fc6ea95..23d85eb4cff 100644..100755
--- a/source/python/py_winreg.h
+++ b/source/smbwrapper/init.c
@@ -1,7 +1,8 @@
/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ initialise connections in smbwrapper
+ Copyright (C) Andrew Tridgell 1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,9 +19,4 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _PY_WINREG_H
-#define _PY_WINREG_H
-
-#include "python/py_common.h"
-
-#endif /* _PY_WINREG_H */
+#include "includes.h"
diff --git a/source/smbwrapper/realcalls.c b/source/smbwrapper/realcalls.c
index b64f4a43dbf..aabde7fa87c 100644
--- a/source/smbwrapper/realcalls.c
+++ b/source/smbwrapper/realcalls.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions for calls that syscall() can't do
Copyright (C) Andrew Tridgell 1998
diff --git a/source/smbwrapper/realcalls.h b/source/smbwrapper/realcalls.h
index 6c230dba056..251c2673372 100644
--- a/source/smbwrapper/realcalls.h
+++ b/source/smbwrapper/realcalls.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
defintions of syscall entries
Copyright (C) Andrew Tridgell 1998
diff --git a/source/smbwrapper/shared.c b/source/smbwrapper/shared.c
index ca8df5841d1..a10ef05bfca 100644
--- a/source/smbwrapper/shared.c
+++ b/source/smbwrapper/shared.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions - shared variables
Copyright (C) Andrew Tridgell 1998
@@ -52,7 +53,7 @@ void smbw_setup_shared(void)
slprintf(s,sizeof(s)-1,"%d", shared_fd);
- setenv("SMBW_HANDLE", s, 1);
+ smbw_setenv("SMBW_HANDLE", s);
return;
@@ -103,7 +104,6 @@ char *smbw_getshared(const char *name)
{
int i;
struct stat st;
- char *var;
lockit();
@@ -111,9 +111,8 @@ char *smbw_getshared(const char *name)
if (fstat(shared_fd, &st)) goto failed;
if (st.st_size != shared_size) {
- var = (char *)Realloc(variables, st.st_size);
- if (!var) goto failed;
- else variables = var;
+ variables = (char *)Realloc(variables, st.st_size);
+ if (!variables) goto failed;
shared_size = st.st_size;
lseek(shared_fd, 0, SEEK_SET);
if (read(shared_fd, variables, shared_size) != shared_size) {
@@ -157,7 +156,6 @@ set a variable in the shared area
void smbw_setshared(const char *name, const char *val)
{
int l1, l2;
- char *var;
/* we don't allow variable overwrite */
if (smbw_getshared(name)) return;
@@ -167,20 +165,18 @@ void smbw_setshared(const char *name, const char *val)
l1 = strlen(name)+1;
l2 = strlen(val)+1;
- var = (char *)Realloc(variables, shared_size + l1+l2+4);
+ variables = (char *)Realloc(variables, shared_size + l1+l2+4);
- if (!var) {
+ if (!variables) {
DEBUG(0,("out of memory in smbw_setshared\n"));
exit(1);
}
-
- variables = var;
SSVAL(&variables[shared_size], 0, l1);
SSVAL(&variables[shared_size], 2, l2);
- safe_strcpy(&variables[shared_size] + 4, name, l1-1);
- safe_strcpy(&variables[shared_size] + 4 + l1, val, l2-1);
+ pstrcpy(&variables[shared_size] + 4, name);
+ pstrcpy(&variables[shared_size] + 4 + l1, val);
shared_size += l1+l2+4;
@@ -195,6 +191,24 @@ void smbw_setshared(const char *name, const char *val)
/*****************************************************************
+set an env variable - some systems don't have this
+*****************************************************************/
+int smbw_setenv(const char *name, const char *value)
+{
+ pstring s;
+ char *p;
+ int ret = -1;
+
+ slprintf(s,sizeof(s)-1,"%s=%s", name, value);
+
+ p = strdup(s);
+
+ if (p) ret = putenv(p);
+
+ return ret;
+}
+
+/*****************************************************************
return true if the passed fd is the SMBW_HANDLE
*****************************************************************/
int smbw_shared_fd(int fd)
diff --git a/source/smbwrapper/smbsh.c b/source/smbwrapper/smbsh.c
index 7a2b8e09d7a..ecf47a7ee08 100644
--- a/source/smbwrapper/smbsh.c
+++ b/source/smbwrapper/smbsh.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions - frontend
Copyright (C) Andrew Tridgell 1998
@@ -20,6 +21,8 @@
#include "includes.h"
+extern BOOL AllowDebugChange;
+
static void smbsh_usage(void)
{
printf("smbsh [options]\n\n");
@@ -36,13 +39,22 @@ static void smbsh_usage(void)
int main(int argc, char *argv[])
{
char *p, *u;
- const char *libd = dyn_LIBDIR;
+ char *libd = BINDIR;
pstring line, wd;
int opt;
extern char *optarg;
extern int optind;
+ extern FILE *dbf;
+
+ dbf = stdout;
+
+ AllowDebugChange = False;
+ DEBUGLEVEL = 0;
+
+ charset_initialise();
+ lp_load(CONFIGFILE,True,False,False);
+ codepage_initialise(lp_client_code_page());
- dbf = x_stdout;
smbw_setup_shared();
while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) {
@@ -61,9 +73,10 @@ int main(int argc, char *argv[])
break;
case 'd':
smbw_setshared("DEBUG", optarg);
+ DEBUGLEVEL = atoi(optarg);
break;
case 'U':
- p = strchr_m(optarg,'%');
+ p = strchr(optarg,'%');
if (p) {
*p=0;
smbw_setshared("PASSWORD",p+1);
@@ -83,7 +96,7 @@ int main(int argc, char *argv[])
if (!smbw_getshared("USER")) {
printf("Username: ");
- u = fgets_slash(line, sizeof(line)-1, x_stdin);
+ u = fgets_slash(line, sizeof(line)-1, stdin);
smbw_setshared("USER", u);
}
@@ -92,7 +105,7 @@ int main(int argc, char *argv[])
smbw_setshared("PASSWORD", p);
}
- setenv("PS1", "smbsh$ ", 1);
+ smbw_setenv("PS1", "smbsh$ ");
sys_getwd(wd);
@@ -101,18 +114,18 @@ int main(int argc, char *argv[])
smbw_setshared(line, wd);
slprintf(line,sizeof(line)-1,"%s/smbwrapper.so", libd);
- setenv("LD_PRELOAD", line, 1);
+ smbw_setenv("LD_PRELOAD", line);
slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so", libd);
if (file_exist(line, NULL)) {
slprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so:DEFAULT", libd);
- setenv("_RLD_LIST", line, 1);
+ smbw_setenv("_RLD_LIST", line);
slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
- setenv("_RLDN32_LIST", line, 1);
+ smbw_setenv("_RLDN32_LIST", line);
} else {
slprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
- setenv("_RLD_LIST", line, 1);
+ smbw_setenv("_RLD_LIST", line);
}
{
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 0ddacdf8ba5..9878d3c70b6 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions
Copyright (C) Andrew Tridgell 1998
@@ -27,6 +28,8 @@ static struct smbw_file *smbw_files;
static struct smbw_server *smbw_srvs;
struct bitmap *smbw_file_bmap;
+extern pstring global_myname;
+extern BOOL AllowDebugChange;
fstring smbw_prefix = SMBW_PREFIX;
@@ -43,6 +46,8 @@ void smbw_init(void)
{
extern BOOL in_client;
static int initialised;
+ static pstring servicesf = CONFIGFILE;
+ extern FILE *dbf;
char *p;
int eno;
pstring line;
@@ -55,9 +60,10 @@ void smbw_init(void)
smbw_busy++;
DEBUGLEVEL = 0;
+ AllowDebugChange = False;
setup_logging("smbsh",True);
- dbf = x_stderr;
+ dbf = stderr;
if ((p=smbw_getshared("LOGFILE"))) {
dbf = sys_fopen(p, "a");
@@ -68,18 +74,20 @@ void smbw_init(void)
exit(1);
}
+ charset_initialise();
+
in_client = True;
load_interfaces();
if ((p=smbw_getshared("SERVICESF"))) {
- pstrcpy(dyn_CONFIGFILE, p);
+ pstrcpy(servicesf, p);
}
- lp_load(dyn_CONFIGFILE,True,False,False);
+ lp_load(servicesf,True,False,False);
+ codepage_initialise(lp_client_code_page());
- if (!init_names())
- exit(1);
+ get_myname(global_myname);
if ((p=smbw_getshared("DEBUG"))) {
DEBUGLEVEL = atoi(p);
@@ -442,7 +450,7 @@ struct smbw_server *smbw_server(char *server, char *share)
pstring ipenv;
struct in_addr ip;
- zero_ip(&ip);
+ zero_ip(&ip);
ZERO_STRUCT(c);
get_auth_data_fn(server, share, &workgroup, &username, &password);
@@ -461,18 +469,18 @@ struct smbw_server *smbw_server(char *server, char *share)
return NULL;
}
- make_nmb_name(&calling, global_myname(), 0x0);
+ make_nmb_name(&calling, global_myname, 0x0);
make_nmb_name(&called , server, 0x20);
DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
- if ((p=strchr_m(server_n,'#')) &&
+ if ((p=strchr(server_n,'#')) &&
(strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
struct in_addr sip;
pstring s;
fstrcpy(group, server_n);
- p = strchr_m(group,'#');
+ p = strchr(group,'#');
*p = 0;
/* cache the workgroup master lookup */
@@ -493,7 +501,7 @@ struct smbw_server *smbw_server(char *server, char *share)
again:
slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
- zero_ip(&ip);
+ zero_ip(&ip);
if ((p=smbw_getshared(ipenv))) {
ip = *(interpret_addr2(p));
}
@@ -1480,12 +1488,8 @@ say no to acls
st64->st_atime = st->st_atime;
st64->st_mtime = st->st_mtime;
st64->st_ctime = st->st_ctime;
-#ifdef HAVE_STAT_ST_BLKSIZE
st64->st_blksize = st->st_blksize;
-#endif
-#ifdef HAVE_STAT_ST_BLOCKS
st64->st_blocks = st->st_blocks;
-#endif
}
#endif
@@ -1516,11 +1520,11 @@ struct kernel_stat {
unsigned long int st_size;
unsigned long int st_blksize;
unsigned long int st_blocks;
- unsigned long int st_atime_;
+ unsigned long int st_atime;
unsigned long int __unused1;
- unsigned long int st_mtime_;
+ unsigned long int st_mtime;
unsigned long int __unused2;
- unsigned long int st_ctime_;
+ unsigned long int st_ctime;
unsigned long int __unused3;
unsigned long int __unused4;
unsigned long int __unused5;
@@ -1549,14 +1553,10 @@ struct kernel_stat {
st->st_gid = kbuf->st_gid;
st->st_rdev = kbuf->st_rdev;
st->st_size = kbuf->st_size;
-#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = kbuf->st_blksize;
-#endif
-#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = kbuf->st_blocks;
-#endif
- st->st_atime = kbuf->st_atime_;
- st->st_mtime = kbuf->st_mtime_;
- st->st_ctime = kbuf->st_ctime_;
+ st->st_atime = kbuf->st_atime;
+ st->st_mtime = kbuf->st_mtime;
+ st->st_ctime = kbuf->st_ctime;
}
#endif
diff --git a/source/smbwrapper/smbw.h b/source/smbwrapper/smbw.h
index 3f0b1cbb443..d059b20c788 100644
--- a/source/smbwrapper/smbw.h
+++ b/source/smbwrapper/smbw.h
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions - definitions
Copyright (C) Andrew Tridgell 1998
diff --git a/source/smbwrapper/smbw_cache.c b/source/smbwrapper/smbw_cache.c
deleted file mode 100644
index fcb0eda8050..00000000000
--- a/source/smbwrapper/smbw_cache.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB wrapper directory functions
- Copyright (C) Tim Potter 2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/* We cache lists of workgroups, lists of servers in workgroups, and lists
- of shares exported by servers. */
-
-#define CACHE_TIMEOUT 30
-
-struct name_list {
- struct name_list *prev, *next;
- char *name;
- uint32 stype;
- char *comment;
-};
-
-struct cached_names {
- struct cached_names *prev, *next;
- char *key;
- struct name_list *name_list;
- time_t cache_timeout;
- int result;
-};
-
-static struct cached_names *cached_names = NULL;
-
-/* Find a list of cached name for a workgroup, server or share list */
-
-static struct cached_names *find_cached_names(char *key)
-{
- struct cached_names *tmp;
-
- for (tmp = cached_names; tmp; tmp = tmp->next) {
- if (strequal(tmp->key, key)) {
- return tmp;
- }
- }
-
- return NULL;
-}
-
-/* Add a name to a list stored in the state variable */
-
-static void add_cached_names(const char *name, uint32 stype,
- const char *comment, void *state)
-{
- struct name_list **name_list = (struct name_list **)state;
- struct name_list *new_name;
-
- new_name = (struct name_list *)malloc(sizeof(struct name_list));
- if (!new_name) return;
-
- ZERO_STRUCTP(new_name);
-
- new_name->name = strdup(name);
- new_name->stype = stype;
- new_name->comment = strdup(comment);
-
- DLIST_ADD(*name_list, new_name);
-}
-
-static void free_name_list(struct name_list *name_list)
-{
- struct name_list *tmp = name_list;
-
- while(tmp) {
- struct name_list *next;
-
- next = tmp->next;
-
- SAFE_FREE(tmp->name);
- SAFE_FREE(tmp->comment);
- SAFE_FREE(tmp);
-
- tmp = next;
- }
-}
-
-/* Wrapper for NetServerEnum function */
-
-BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(const char *, uint32, const char *, void *),
- void *state)
-{
- struct cached_names *names;
- struct name_list *tmp;
- time_t now = time(NULL);
- char key[PATH_MAX];
- BOOL result = True;
-
- slprintf(key, PATH_MAX - 1, "%s/%s#%s", cli->desthost,
- workgroup, (stype == SV_TYPE_DOMAIN_ENUM ? "DOM" : "SRV"));
-
- names = find_cached_names(key);
-
- if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
- struct cached_names *new_names = NULL;
-
- /* No names cached for this workgroup */
-
- if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
-
- ZERO_STRUCTP(new_names);
- DLIST_ADD(cached_names, new_names);
-
- } else {
-
- /* Dispose of out of date name list */
-
- free_name_list(names->name_list);
- names->name_list = NULL;
-
- new_names = names;
- }
-
- result = cli_NetServerEnum(cli, workgroup, stype,
- add_cached_names,
- &new_names->name_list);
-
- new_names->cache_timeout = now;
- new_names->result = result;
- new_names->key = strdup(key);
-
- names = new_names;
- }
-
- /* Return names by running callback function. */
-
- for (tmp = names->name_list; tmp; tmp = tmp->next)
- fn(tmp->name, stype, tmp->comment, state);
-
- return names->result;
-}
-
-/* Wrapper for RNetShareEnum function */
-
-int smbw_RNetShareEnum(struct cli_state *cli,
- void (*fn)(const char *, uint32, const char *, void *),
- void *state)
-{
- struct cached_names *names;
- struct name_list *tmp;
- time_t now = time(NULL);
- char key[PATH_MAX];
-
- slprintf(key, PATH_MAX - 1, "SHARE/%s", cli->desthost);
-
- names = find_cached_names(key);
-
- if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
- struct cached_names *new_names = NULL;
-
- /* No names cached for this server */
-
- if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
-
- ZERO_STRUCTP(new_names);
- DLIST_ADD(cached_names, new_names);
-
- } else {
-
- /* Dispose of out of date name list */
-
- free_name_list(names->name_list);
- names->name_list = NULL;
-
- new_names = names;
- }
-
- new_names->result = cli_RNetShareEnum(cli, add_cached_names,
- &new_names->name_list);
-
- new_names->cache_timeout = now;
- new_names->key = strdup(key);
-
- names = new_names;
- }
-
- /* Return names by running callback function. */
-
- for (tmp = names->name_list; tmp; tmp = tmp->next)
- fn(tmp->name, tmp->stype, tmp->comment, state);
-
- return names->result;
-}
diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c
index 0a6deede41f..a056a2ae752 100644
--- a/source/smbwrapper/smbw_dir.c
+++ b/source/smbwrapper/smbw_dir.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper directory functions
Copyright (C) Andrew Tridgell 1998
@@ -62,35 +63,30 @@ free a smbw_dir structure and all entries
*******************************************************/
static void free_dir(struct smbw_dir *dir)
{
- if(!dir) return;
-
SAFE_FREE(dir->list);
SAFE_FREE(dir->path);
ZERO_STRUCTP(dir);
SAFE_FREE(dir);
}
+
static struct smbw_dir *cur_dir;
/*****************************************************
add a entry to a directory listing
*******************************************************/
-static void smbw_dir_add(struct file_info *finfo, const char *mask,
- void *state)
+static void smbw_dir_add(struct file_info *finfo, const char *mask, void *state)
{
- struct file_info *cdl;
-
DEBUG(5,("%s\n", finfo->name));
if (cur_dir->malloced == cur_dir->count) {
- cdl = (struct file_info *)Realloc(cur_dir->list,
+ cur_dir->list = (struct file_info *)Realloc(cur_dir->list,
sizeof(cur_dir->list[0])*
(cur_dir->count+100));
- if (!cdl) {
+ if (!cur_dir->list) {
/* oops */
return;
}
- cur_dir->list = cdl;
cur_dir->malloced += 100;
}
@@ -102,7 +98,7 @@ static void smbw_dir_add(struct file_info *finfo, const char *mask,
add a entry to a directory listing
*******************************************************/
static void smbw_share_add(const char *share, uint32 type,
- const char *comment, void *state)
+ const char *comment, void *state)
{
struct file_info finfo;
@@ -203,30 +199,30 @@ int smbw_dir_open(const char *fname)
if ((p=strstr(srv->server_name,"#01"))) {
*p = 0;
- smbw_server_add(".",0,"", NULL);
- smbw_server_add("..",0,"", NULL);
- smbw_NetServerEnum(&srv->cli, srv->server_name,
- SV_TYPE_DOMAIN_ENUM, smbw_server_add, NULL);
+ smbw_server_add(".",0,"",NULL);
+ smbw_server_add("..",0,"",NULL);
+ cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_DOMAIN_ENUM,
+ smbw_server_add,NULL);
*p = '#';
} else if ((p=strstr(srv->server_name,"#1D"))) {
DEBUG(4,("doing NetServerEnum\n"));
*p = 0;
- smbw_server_add(".",0,"", NULL);
- smbw_server_add("..",0,"", NULL);
- smbw_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
- smbw_server_add, NULL);
+ smbw_server_add(".",0,"",NULL);
+ smbw_server_add("..",0,"",NULL);
+ cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
+ smbw_server_add,NULL);
*p = '#';
- } else if ((strcmp(srv->cli.dev,"IPC") == 0) || (strequal(share,"IPC$"))) {
+ } else if (strcmp(srv->cli.dev,"IPC") == 0) {
DEBUG(4,("doing NetShareEnum\n"));
- smbw_share_add(".",0,"", NULL);
- smbw_share_add("..",0,"", NULL);
- if (smbw_RNetShareEnum(&srv->cli, smbw_share_add, NULL) < 0) {
+ smbw_share_add(".",0,"",NULL);
+ smbw_share_add("..",0,"",NULL);
+ if (cli_RNetShareEnum(&srv->cli, smbw_share_add,NULL) < 0) {
errno = smbw_errno(&srv->cli);
goto failed;
}
} else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
- smbw_share_add(".",0,"", NULL);
- smbw_share_add("..",0,"", NULL);
+ smbw_share_add(".",0,"",NULL);
+ smbw_share_add("..",0,"",NULL);
if (cli_print_queue(&srv->cli, smbw_printjob_add) < 0) {
errno = smbw_errno(&srv->cli);
goto failed;
@@ -234,12 +230,11 @@ int smbw_dir_open(const char *fname)
} else {
#if 0
if (strcmp(path,"\\") == 0) {
- smbw_share_add(".",0,"");
- smbw_share_add("..",0,"");
+ smbw_share_add(".",0,"",NULL);
+ smbw_share_add("..",0,"",NULL);
}
#endif
- if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR,
- smbw_dir_add, NULL) < 0) {
+ if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR, smbw_dir_add,NULL) < 0) {
errno = smbw_errno(&srv->cli);
goto failed;
}
@@ -272,8 +267,10 @@ int smbw_dir_open(const char *fname)
return dir->fd;
failed:
- free_dir(dir);
-
+ if (dir) {
+ free_dir(dir);
+ }
+
return -1;
}
@@ -412,8 +409,7 @@ int smbw_chdir(const char *name)
goto failed;
}
- if (strncmp(srv->cli.dev,"IPC",3) &&
- !strequal(share, "IPC$") &&
+ if (strncmp(srv->cli.dev,"IPC",3) &&
strncmp(srv->cli.dev,"LPT",3) &&
!smbw_getatr(srv, path,
&mode, NULL, NULL, NULL, NULL, NULL)) {
@@ -687,3 +683,4 @@ off_t smbw_telldir(DIR *dirp)
struct smbw_dir *d = (struct smbw_dir *)dirp;
return smbw_dir_lseek(d->fd,0,SEEK_CUR);
}
+
diff --git a/source/smbwrapper/smbw_stat.c b/source/smbwrapper/smbw_stat.c
index bb76ef006a4..cf2d19cdf09 100644
--- a/source/smbwrapper/smbw_stat.c
+++ b/source/smbwrapper/smbw_stat.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper stat functions
Copyright (C) Andrew Tridgell 1998
@@ -22,6 +23,7 @@
extern int smbw_busy;
+
/*****************************************************
setup basic info in a stat structure
*******************************************************/
@@ -41,12 +43,8 @@ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
st->st_size = size;
-#ifdef HAVE_STAT_ST_BLKSIZE
st->st_blksize = 512;
-#endif
-#ifdef HAVE_STAT_ST_BLOCKS
st->st_blocks = (size+511)/512;
-#endif
st->st_uid = getuid();
st->st_gid = getgid();
if (IS_DOS_DIR(mode)) {
@@ -202,11 +200,10 @@ int smbw_stat(const char *fname, struct stat *st)
srv = smbw_server(server, share);
if (!srv) {
- /* For shares we aren't allowed to connect to, or no master
- browser found, return an empty directory */
+ /* For shares we aren't allowed to connect to, return
+ an empty directory */
- if ((server[0] && share[0] && !path[0] && errno == EACCES) ||
- (!path[0] && errno == ENOENT)) {
+ if (server[0] && share[0] && !path[0] && errno == EACCES) {
mode = aDIR | aRONLY;
smbw_setup_stat(st, path, size, mode);
goto done;
diff --git a/source/smbwrapper/wrapped.c b/source/smbwrapper/wrapped.c
index 338ee0d5b1b..904ae68f928 100644
--- a/source/smbwrapper/wrapped.c
+++ b/source/smbwrapper/wrapped.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
SMB wrapper functions
Copyright (C) Andrew Tridgell 1998
@@ -461,6 +462,13 @@
#endif
#ifdef HAVE_UTIMES
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
int utimes(const char *name, const struct timeval *tvp)
{
if (smbw_path(name)) {
diff --git a/source/stf/README.stf b/source/stf/README.stf
deleted file mode 100644
index 3fbd33cb6cc..00000000000
--- a/source/stf/README.stf
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains the Samba Testing Framework, a Python-based
-system for exercising Samba in various ways. It is quite small at the
-moment.
diff --git a/source/stf/comfychair.py b/source/stf/comfychair.py
deleted file mode 100644
index 522f9bedeba..00000000000
--- a/source/stf/comfychair.py
+++ /dev/null
@@ -1,445 +0,0 @@
-#! /usr/bin/env python
-
-# Copyright (C) 2002, 2003 by Martin Pool <mbp@samba.org>
-# Copyright (C) 2003 by Tim Potter <tpot@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-"""comfychair: a Python-based instrument of software torture.
-
-Copyright (C) 2002, 2003 by Martin Pool <mbp@samba.org>
-Copyright (C) 2003 by Tim Potter <tpot@samba.org>
-
-This is a test framework designed for testing programs written in
-Python, or (through a fork/exec interface) any other language.
-
-For more information, see the file README.comfychair.
-
-To run a test suite based on ComfyChair, just run it as a program.
-"""
-
-import sys, re
-
-
-class TestCase:
- """A base class for tests. This class defines required functions which
- can optionally be overridden by subclasses. It also provides some
- utility functions for"""
-
- def __init__(self):
- self.test_log = ""
- self.background_pids = []
- self._cleanups = []
- self._enter_rundir()
- self._save_environment()
- self.add_cleanup(self.teardown)
-
-
- # --------------------------------------------------
- # Save and restore directory
- def _enter_rundir(self):
- import os
- self.basedir = os.getcwd()
- self.add_cleanup(self._restore_directory)
- self.rundir = os.path.join(self.basedir,
- 'testtmp',
- self.__class__.__name__)
- self.tmpdir = os.path.join(self.rundir, 'tmp')
- os.system("rm -fr %s" % self.rundir)
- os.makedirs(self.tmpdir)
- os.system("mkdir -p %s" % self.rundir)
- os.chdir(self.rundir)
-
- def _restore_directory(self):
- import os
- os.chdir(self.basedir)
-
- # --------------------------------------------------
- # Save and restore environment
- def _save_environment(self):
- import os
- self._saved_environ = os.environ.copy()
- self.add_cleanup(self._restore_environment)
-
- def _restore_environment(self):
- import os
- os.environ.clear()
- os.environ.update(self._saved_environ)
-
-
- def setup(self):
- """Set up test fixture."""
- pass
-
- def teardown(self):
- """Tear down test fixture."""
- pass
-
- def runtest(self):
- """Run the test."""
- pass
-
-
- def add_cleanup(self, c):
- """Queue a cleanup to be run when the test is complete."""
- self._cleanups.append(c)
-
-
- def fail(self, reason = ""):
- """Say the test failed."""
- raise AssertionError(reason)
-
-
- #############################################################
- # Requisition methods
-
- def require(self, predicate, message):
- """Check a predicate for running this test.
-
-If the predicate value is not true, the test is skipped with a message explaining
-why."""
- if not predicate:
- raise NotRunError, message
-
- def require_root(self):
- """Skip this test unless run by root."""
- import os
- self.require(os.getuid() == 0,
- "must be root to run this test")
-
- #############################################################
- # Assertion methods
-
- def assert_(self, expr, reason = ""):
- if not expr:
- raise AssertionError(reason)
-
- def assert_equal(self, a, b):
- if not a == b:
- raise AssertionError("assertEquals failed: %s" % `(a, b)`)
-
- def assert_notequal(self, a, b):
- if a == b:
- raise AssertionError("assertNotEqual failed: %s" % `(a, b)`)
-
- def assert_re_match(self, pattern, s):
- """Assert that a string matches a particular pattern
-
- Inputs:
- pattern string: regular expression
- s string: to be matched
-
- Raises:
- AssertionError if not matched
- """
- if not re.match(pattern, s):
- raise AssertionError("string does not match regexp\n"
- " string: %s\n"
- " re: %s" % (`s`, `pattern`))
-
- def assert_re_search(self, pattern, s):
- """Assert that a string *contains* a particular pattern
-
- Inputs:
- pattern string: regular expression
- s string: to be searched
-
- Raises:
- AssertionError if not matched
- """
- if not re.search(pattern, s):
- raise AssertionError("string does not contain regexp\n"
- " string: %s\n"
- " re: %s" % (`s`, `pattern`))
-
-
- def assert_no_file(self, filename):
- import os.path
- assert not os.path.exists(filename), ("file exists but should not: %s" % filename)
-
-
- #############################################################
- # Methods for running programs
-
- def runcmd_background(self, cmd):
- import os
- self.test_log = self.test_log + "Run in background:\n" + `cmd` + "\n"
- pid = os.fork()
- if pid == 0:
- # child
- try:
- os.execvp("/bin/sh", ["/bin/sh", "-c", cmd])
- finally:
- os._exit(127)
- self.test_log = self.test_log + "pid: %d\n" % pid
- return pid
-
-
- def runcmd(self, cmd, expectedResult = 0):
- """Run a command, fail if the command returns an unexpected exit
- code. Return the output produced."""
- rc, output, stderr = self.runcmd_unchecked(cmd)
- if rc != expectedResult:
- raise AssertionError("""command returned %d; expected %s: \"%s\"
-stdout:
-%s
-stderr:
-%s""" % (rc, expectedResult, cmd, output, stderr))
-
- return output, stderr
-
-
- def run_captured(self, cmd):
- """Run a command, capturing stdout and stderr.
-
- Based in part on popen2.py
-
- Returns (waitstatus, stdout, stderr)."""
- import os, types
- pid = os.fork()
- if pid == 0:
- # child
- try:
- pid = os.getpid()
- openmode = os.O_WRONLY|os.O_CREAT|os.O_TRUNC
-
- outfd = os.open('%d.out' % pid, openmode, 0666)
- os.dup2(outfd, 1)
- os.close(outfd)
-
- errfd = os.open('%d.err' % pid, openmode, 0666)
- os.dup2(errfd, 2)
- os.close(errfd)
-
- if isinstance(cmd, types.StringType):
- cmd = ['/bin/sh', '-c', cmd]
-
- os.execvp(cmd[0], cmd)
- finally:
- os._exit(127)
- else:
- # parent
- exited_pid, waitstatus = os.waitpid(pid, 0)
- stdout = open('%d.out' % pid).read()
- stderr = open('%d.err' % pid).read()
- return waitstatus, stdout, stderr
-
-
- def runcmd_unchecked(self, cmd, skip_on_noexec = 0):
- """Invoke a command; return (exitcode, stdout, stderr)"""
- import os
- waitstatus, stdout, stderr = self.run_captured(cmd)
- assert not os.WIFSIGNALED(waitstatus), \
- ("%s terminated with signal %d" % (`cmd`, os.WTERMSIG(waitstatus)))
- rc = os.WEXITSTATUS(waitstatus)
- self.test_log = self.test_log + ("""Run command: %s
-Wait status: %#x (exit code %d, signal %d)
-stdout:
-%s
-stderr:
-%s""" % (cmd, waitstatus, os.WEXITSTATUS(waitstatus), os.WTERMSIG(waitstatus),
- stdout, stderr))
- if skip_on_noexec and rc == 127:
- # Either we could not execute the command or the command
- # returned exit code 127. According to system(3) we can't
- # tell the difference.
- raise NotRunError, "could not execute %s" % `cmd`
- return rc, stdout, stderr
-
-
- def explain_failure(self, exc_info = None):
- print "test_log:"
- print self.test_log
-
-
- def log(self, msg):
- """Log a message to the test log. This message is displayed if
- the test fails, or when the runtests function is invoked with
- the verbose option."""
- self.test_log = self.test_log + msg + "\n"
-
-
-class NotRunError(Exception):
- """Raised if a test must be skipped because of missing resources"""
- def __init__(self, value = None):
- self.value = value
-
-
-def _report_error(case, debugger):
- """Ask the test case to explain failure, and optionally run a debugger
-
- Input:
- case TestCase instance
- debugger if true, a debugger function to be applied to the traceback
-"""
- import sys
- ex = sys.exc_info()
- print "-----------------------------------------------------------------"
- if ex:
- import traceback
- traceback.print_exc(file=sys.stdout)
- case.explain_failure()
- print "-----------------------------------------------------------------"
-
- if debugger:
- tb = ex[2]
- debugger(tb)
-
-
-def runtests(test_list, verbose = 0, debugger = None):
- """Run a series of tests.
-
- Inputs:
- test_list sequence of TestCase classes
- verbose print more information as testing proceeds
- debugger debugger object to be applied to errors
-
- Returns:
- unix return code: 0 for success, 1 for failures, 2 for test failure
- """
- import traceback
- ret = 0
- for test_class in test_list:
- print "%-30s" % _test_name(test_class),
- # flush now so that long running tests are easier to follow
- sys.stdout.flush()
-
- obj = None
- try:
- try: # run test and show result
- obj = test_class()
- obj.setup()
- obj.runtest()
- print "OK"
- except KeyboardInterrupt:
- print "INTERRUPT"
- _report_error(obj, debugger)
- ret = 2
- break
- except NotRunError, msg:
- print "NOTRUN, %s" % msg.value
- except:
- print "FAIL"
- _report_error(obj, debugger)
- ret = 1
- finally:
- while obj and obj._cleanups:
- try:
- apply(obj._cleanups.pop())
- except KeyboardInterrupt:
- print "interrupted during teardown"
- _report_error(obj, debugger)
- ret = 2
- break
- except:
- print "error during teardown"
- _report_error(obj, debugger)
- ret = 1
- # Display log file if we're verbose
- if ret == 0 and verbose:
- obj.explain_failure()
-
- return ret
-
-
-def _test_name(test_class):
- """Return a human-readable name for a test class.
- """
- try:
- return test_class.__name__
- except:
- return `test_class`
-
-
-def print_help():
- """Help for people running tests"""
- import sys
- print """%s: software test suite based on ComfyChair
-
-usage:
- To run all tests, just run this program. To run particular tests,
- list them on the command line.
-
-options:
- --help show usage message
- --list list available tests
- --verbose, -v show more information while running tests
- --post-mortem, -p enter Python debugger on error
-""" % sys.argv[0]
-
-
-def print_list(test_list):
- """Show list of available tests"""
- for test_class in test_list:
- print " %s" % _test_name(test_class)
-
-
-def main(tests, extra_tests=[]):
- """Main entry point for test suites based on ComfyChair.
-
- inputs:
- tests Sequence of TestCase subclasses to be run by default.
- extra_tests Sequence of TestCase subclasses that are available but
- not run by default.
-
-Test suites should contain this boilerplate:
-
- if __name__ == '__main__':
- comfychair.main(tests)
-
-This function handles standard options such as --help and --list, and
-by default runs all tests in the suggested order.
-
-Calls sys.exit() on completion.
-"""
- from sys import argv
- import getopt, sys
-
- opt_verbose = 0
- debugger = None
-
- opts, args = getopt.getopt(argv[1:], 'pv',
- ['help', 'list', 'verbose', 'post-mortem'])
- for opt, opt_arg in opts:
- if opt == '--help':
- print_help()
- return
- elif opt == '--list':
- print_list(tests + extra_tests)
- return
- elif opt == '--verbose' or opt == '-v':
- opt_verbose = 1
- elif opt == '--post-mortem' or opt == '-p':
- import pdb
- debugger = pdb.post_mortem
-
- if args:
- all_tests = tests + extra_tests
- by_name = {}
- for t in all_tests:
- by_name[_test_name(t)] = t
- which_tests = []
- for name in args:
- which_tests.append(by_name[name])
- else:
- which_tests = tests
-
- sys.exit(runtests(which_tests, verbose=opt_verbose,
- debugger=debugger))
-
-
-if __name__ == '__main__':
- print __doc__
diff --git a/source/stf/example.py b/source/stf/example.py
deleted file mode 100755
index 96e34bf3d3b..00000000000
--- a/source/stf/example.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /usr/bin/env python
-
-# Copyright (C) 2003 by Martin Pool <mbp@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-
-"""example of using ComfyChair"""
-
-import comfychair
-
-class OnePlusOne(comfychair.TestCase):
- def runtest(self):
- self.assert_(1 + 1 == 2)
-
-class FailTest(comfychair.TestCase):
- def runtest(self):
- self.assert_(1 + 1 == 3)
-
-tests = [OnePlusOne]
-extra_tests = [FailTest]
-
-if __name__ == '__main__':
- comfychair.main(tests, extra_tests=extra_tests)
-
diff --git a/source/stf/info3cache.py b/source/stf/info3cache.py
deleted file mode 100755
index 96d5a1d4596..00000000000
--- a/source/stf/info3cache.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/python
-#
-# Upon a winbindd authentication, test that an info3 record is cached in
-# netsamlogon_cache.tdb and cache records are removed from winbindd_cache.tdb
-#
-
-import comfychair, stf
-from samba import tdb, winbind
-
-#
-# We want to implement the following test on a win2k native mode domain.
-#
-# 1. trash netsamlogon_cache.tdb
-# 2. wbinfo -r DOMAIN\Administrator [FAIL]
-# 3. wbinfo --auth-crap DOMAIN\Administrator%password [PASS]
-# 4. wbinfo -r DOMAIN\Administrator [PASS]
-#
-# Also for step 3 we want to try 'wbinfo --auth-smbd' and
-# 'wbinfo --auth-plaintext'
-#
-
-#
-# TODO: To implement this test we need to be able to
-#
-# - pass username%password combination for an invidivual winbindd request
-# (so we can get the administrator SID so we can clear the info3 cache)
-#
-# - start/restart winbindd (to trash the winbind cache)
-#
-# - from samba import dynconfig (to find location of info3 cache)
-#
-# - be able to modify the winbindd cache (to set/reset individual winbind
-# cache entries)
-#
-# - have --auth-crap present in HEAD
-#
-
-class WinbindAuthCrap(comfychair.TestCase):
- def runtest(self):
- raise comfychair.NotRunError, "not implemented"
-
-class WinbindAuthSmbd(comfychair.TestCase):
- def runtest(self):
- # Grr - winbindd in HEAD doesn't contain the auth_smbd function
- raise comfychair.NotRunError, "no auth_smbd in HEAD"
-
-class WinbindAuthPlaintext(comfychair.TestCase):
- def runtest(self):
- raise comfychair.NotRunError, "not implemented"
-
-tests = [WinbindAuthCrap, WinbindAuthSmbd, WinbindAuthPlaintext]
-
-if __name__ == "__main__":
- comfychair.main(tests)
diff --git a/source/stf/notes.txt b/source/stf/notes.txt
deleted file mode 100644
index 68aca63c237..00000000000
--- a/source/stf/notes.txt
+++ /dev/null
@@ -1,175 +0,0 @@
- -*- indented-text -*-
-
-(set lotus no)
-
-
-
-Notes on using comfychair with Samba (samba testing framework units):
-
-The tests need to rely on some external resources, such as
-
-If suitable resources are not available, need to skip particular
-tests. Must include a message indicating what resources would be
-needed to run that test. (e.g. must be root.)
-
-We want to be able to select and run particular subsets of tests, such
-as "all winbind tests".
-
-We want to keep the number of configurable parameters down as much as
-possible, to make it easy on people running the tests.
-
-Wherever possible, the tests should set up their preconditions, but a
-few basic resources need to be provided by the people running the
-tests. So for example, rather than asking the user for the name of a
-non-root user, we should give the tests the administrator name and
-password, and it can create a new user to use.
-
-This makes it simpler to get the tests running, and possible also
-makes them more reproducible.
-
-In the future, rather than using NT machines provided by the test
-person, we might have a way to drive VMWare non-persistent sessions,
-to make tests even more tightly controlled.
-
-
-Another design question is how to communicate this information to the
-tests. If there's a lot of settings, then it might need to be stored
-in a configuration file.
-
-However, if we succeed in cutting down the number of parameters, then
-it might be straightforward to pass the information on the command
-line or in an environment variable.
-
-Environment variables are probably better because they can't be seen
-by other users, and they are more easily passed down through an
-invocation of "make check".
-
-
-
-Notes on Samba Testing Framework for Unittests
-----------------------------------------------
-
-This is to be read after reading the notes.txt from comfychair. I'm
-proposing a slightly more concrete description of what's described
-there.
-
-The model of having tests require named resources looks useful for
-incorporation into a framework that can be run by many people in
-widely different environments.
-
-Some possible environments for running the test framework in are:
-
- - Casual downloader of Samba compiling from source and just wants
- to run 'make check'. May only have one Unix machine and a
- handful of clients.
-
- - Samba team member with access to a small number of other
- machines or VMware sessions.
-
- - PSA developer who may not have intimate knowledge of Samba
- internals and is only interested in testing against the PSA.
-
- - Non-team hacker wanting to run test suite after making small
- hacks.
-
- - Build farm environment (loaner machine with no physical access
- or root privilege).
-
- - HP BAT.
-
-Developers in most of these environments are also potential test case
-authors. It should be easy for people unfamiliar with the framework
-to write new tests and have them work. We should provide examples and
-the existing tests should well written and understandable.
-
-Different types of tests:
-
- - Tests that check Samba internals and link against
- libbigballofmud.so. For example:
-
- - Upper/lowercase string functions
- - user_in_list() for large lists
-
- - Tests that use the Samba Python extensions.
-
- - Tests that execute Samba command line programs, for example
- smbpasswd.
-
- - Tests that require other resources on the network such as domain
- controllers or PSAs.
-
- - Tests that are performed on the documentation or the source code
- such as:
-
- - grep for common spelling mistakes made by abartlet (-:
- - grep for company copyright (IBM, HP)
-
- - Link to other existing testing frameworks (smbtorture,
- abartlet's bash based build farm tests)
-
-I propose a TestResourceManager which would be instantiated by a test
-case. The test case would require("resourcename") as part of its
-constructor and raise a comfychair.NotRun exception if the resource
-was not present. A TestResource class could be defined which could
-read a configuration file or examine a environment variable and
-register a resource only if some condition was satisfied.
-
-It would be nice to be able to completely separate the PSA testing
-from the test framework. This would entail being able to define test
-resources dynamically, possibly with a plugin type system.
-
-class TestResourceManager:
- def __init__(self, name):
- self.resources = {}
-
- def register(self, resource):
- name = resource.name()
- if self.resources.has_key(name):
- raise "Test manager already has resource %s" % name
- self.resources[name] = resource
-
- def require(self, resource_name):
- if not self.resources.has_key(resource_name):
- raise "Test manager does not have resources %s" % resource_name
-
-class TestResource:
- def __init__(self, name):
- self.name = name
-
- def name(self):
- return self.name
-
-import os
-
-trm = TestResourceManager()
-
-if os.getuid() == 0:
- trm.register(TestResource("root"))
-
-A config-o-matic Python module can take a list of machines and
-administrator%password entries and classify them by operating system
-version and service pack. These resources would be registered with
-the TestResourceManager.
-
-Some random thoughts about named resources for network servers:
-
-require("nt4.sp3")
-require("nt4.domaincontroller")
-require("psa")
-
-Some kind of format for location of passwords, libraries:
-
-require("exec(smbpasswd)")
-require("lib(bigballofmud)")
-
-maybe require("exec.smbpasswd") looks nicer...
-
-The require() function could return a dictionary of configuration
-information or some handle to fetch dynamic information on. We may
-need to create and destroy extra users or print queues. How to manage
-cleanup of dynamic resources?
-
-Requirements for running stf:
-
- - Python, obviously
- - Samba python extensions
diff --git a/source/stf/osver.py b/source/stf/osver.py
deleted file mode 100755
index 68601fa7bb4..00000000000
--- a/source/stf/osver.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/python
-#
-# Utilities for determining the Windows operating system version remotely.
-#
-
-from samba import srvsvc
-
-# Constants
-
-PLATFORM_UNKNOWN = 0
-PLATFORM_WIN9X = 1
-PLATFORM_NT4 = 2
-PLATFORM_NT5 = 3 # Windows 2000
-
-def platform_name(platform_type):
-
- platform_names = { PLATFORM_UNKNOWN: "Unknown",
- PLATFORM_WIN9X: "Windows 9x",
- PLATFORM_NT4: "Windows NT",
- PLATFORM_NT5: "Windows 2000" }
-
- if platform_names.has_key(platform_type):
- return platform_names[platform_type]
-
- return "Unknown"
-
-def platform_type(info101):
- """Determine the operating system type from a SRV_INFO_101."""
-
- if info101['major_version'] == 4 and info101['minor_version'] == 0:
- return PLATFORM_NT4
-
- if info101['major_version'] == 5 and info101['minor_version'] == 0:
- return PLATFORM_NT5
-
- return PLATFORM_UNKNOWN
-
-def is_domain_controller(info101):
- """Return true if the server_type field from a SRV_INFO_101
- indicates a domain controller."""
- return info101['server_type'] & srvsvc.SV_TYPE_DOMAIN_CTRL
-
-def os_version(name):
- info = srvsvc.netservergetinfo("\\\\%s" % name, 101)
- return platform_type(info)
-
-if __name__ == "__main__":
- import sys
- if len(sys.argv) != 2:
- print "Usage: osver.py server"
- sys.exit(0)
- info = srvsvc.netservergetinfo("\\\\%s" % sys.argv[1], 101)
- print "platform type = %d" % platform_type(info)
- if is_domain_controller(info):
- print "%s is a domain controller" % sys.argv[1]
diff --git a/source/stf/pythoncheck.py b/source/stf/pythoncheck.py
deleted file mode 100755
index 398bb2c3d69..00000000000
--- a/source/stf/pythoncheck.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#! /usr/bin/python
-
-# Comfychair test cases for Samba python extensions
-
-# Copyright (C) 2003 by Tim Potter <tpot@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-"""These tests are run by Samba's "make check"."""
-
-import sys, comfychair
-
-class ImportTest(comfychair.TestCase):
- """Check that all modules can be imported without error."""
- def runtest(self):
- python_modules = ['spoolss', 'lsa', 'samr', 'winbind', 'winreg',
- 'srvsvc', 'tdb', 'smb', 'tdbpack']
- for m in python_modules:
- try:
- __import__('samba.%s' % m)
- except ImportError, msg:
- self.log(str(msg))
- self.fail('error importing %s module' % m)
-
-tests = [ImportTest]
-
-if __name__ == '__main__':
- # Some magic to repend build directory to python path so we see the
- # objects we have built and not previously installed stuff.
- from distutils.util import get_platform
- from os import getcwd
- sys.path.insert(0, '%s/build/lib.%s-%s' %
- (getcwd(), get_platform(), sys.version[0:3]))
-
- comfychair.main(tests)
diff --git a/source/stf/sambalib.py b/source/stf/sambalib.py
deleted file mode 100644
index 13d38e2a281..00000000000
--- a/source/stf/sambalib.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#! /usr/bin/python
-
-# Comfychair test cases for Samba string functions.
-
-# Copyright (C) 2003 by Martin Pool <mbp@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-"""Tests for Samba library functions."""
-
-import sys, re, comfychair
-from unicodenames import *
-
-class snprintf_Test(comfychair.TestCase):
- def runtest(self):
- # Everything is built in to the test
- out, err = self.runcmd('t_snprintf')
-
-# Define the tests exported by this module
-tests = [snprintf_Test]
-
-# Handle execution of this file as a main program
-if __name__ == '__main__':
- comfychair.main(tests)
-
-# Local variables:
-# coding: utf-8
-# End:
diff --git a/source/stf/smbcontrol.py b/source/stf/smbcontrol.py
deleted file mode 100755
index 30c331819c7..00000000000
--- a/source/stf/smbcontrol.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/python
-#
-# Test for smbcontrol command line argument handling.
-#
-
-import comfychair
-
-class NoArgs(comfychair.TestCase):
- """Test no arguments produces usage message."""
- def runtest(self):
- out = self.runcmd("smbcontrol", expectedResult = 1)
- self.assert_re_match("Usage: smbcontrol", out[1])
-
-class OneArg(comfychair.TestCase):
- """Test single argument produces usage message."""
- def runtest(self):
- out = self.runcmd("smbcontrol foo", expectedResult = 1)
- self.assert_re_match("Usage: smbcontrol", out[1])
-
-class SmbdDest(comfychair.TestCase):
- """Test the broadcast destination 'smbd'."""
- def runtest(self):
- out = self.runcmd("smbcontrol smbd noop")
-
-class NmbdDest(comfychair.TestCase):
- """Test the destination 'nmbd'."""
- def runtest(self):
- # We need a way to start/stop/whatever nmbd
- raise comfychair.NotRunError, "not implemented"
-
-class PidDest(comfychair.TestCase):
- """Test a pid number destination'."""
- def runtest(self):
- out = self.runcmd("smbcontrol 1234 noop")
-
-class SelfDest(comfychair.TestCase):
- """Test the destination 'self'."""
- def runtest(self):
- out = self.runcmd("smbcontrol self noop")
-
-class WinbinddDest(comfychair.TestCase):
- """Test the destination 'winbindd'."""
- def runtest(self):
- # We need a way to start/stop/whatever winbindd
- raise comfychair.NotRunError, "not implemented"
-
-class BadDest(comfychair.TestCase):
- """Test a bad destination."""
- def runtest(self):
- out = self.runcmd("smbcontrol foo noop", expectedResult = 1)
-
-class BadCmd(comfychair.TestCase):
- """Test a bad command."""
- def runtest(self):
- out = self.runcmd("smbcontrol self spottyfoot", expectedResult = 1)
- self.assert_re_match("smbcontrol: unknown command", out[1]);
-
-class NoArgCmdTest(comfychair.TestCase):
- """A test class that tests a command with no argument."""
- def runtest(self):
- self.require_root()
- out = self.runcmd("smbcontrol self %s" % self.cmd)
- out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd,
- expectedResult = 1)
-
-class ForceElection(NoArgCmdTest):
- """Test a force-election message."""
- def setup(self):
- self.cmd = "force-election"
-
-class SamSync(NoArgCmdTest):
- """Test a samsync message."""
- def setup(self):
- self.cmd = "samsync"
-
-class SamRepl(NoArgCmdTest):
- """Test a samrepl message."""
- def setup(self):
- self.cmd = "samrepl"
-
-class DmallocChanged(NoArgCmdTest):
- """Test a dmalloc-changed message."""
- def setup(self):
- self.cmd = "dmalloc-log-changed"
-
-class DmallocMark(NoArgCmdTest):
- """Test a dmalloc-mark message."""
- def setup(self):
- self.cmd = "dmalloc-mark"
-
-class Shutdown(NoArgCmdTest):
- """Test a shutdown message."""
- def setup(self):
- self.cmd = "shutdown"
-
-class Ping(NoArgCmdTest):
- """Test a ping message."""
- def setup(self):
- self.cmd = "ping"
-
-class Debuglevel(NoArgCmdTest):
- """Test a debuglevel message."""
- def setup(self):
- self.cmd = "debuglevel"
-
-class OneArgCmdTest(comfychair.TestCase):
- """A test class that tests a command with one argument."""
- def runtest(self):
- self.require_root()
- out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd)
- out = self.runcmd("smbcontrol self %s" % self.cmd, expectedResult = 1)
-
-class DrvUpgrade(OneArgCmdTest):
- """Test driver upgrade message."""
- def setup(self):
- self.cmd = "drvupgrade"
-
-class CloseShare(OneArgCmdTest):
- """Test close share message."""
- def setup(self):
- self.cmd = "close-share"
-
-class Debug(OneArgCmdTest):
- """Test a debug message."""
- def setup(self):
- self.cmd = "debug"
-
-class PrintNotify(comfychair.TestCase):
- """Test print notification commands."""
- def runtest(self):
-
- # No subcommand
-
- out = self.runcmd("smbcontrol self printnotify", expectedResult = 1)
- self.assert_re_match("Must specify subcommand", out[1]);
-
- # Invalid subcommand name
-
- out = self.runcmd("smbcontrol self printnotify spottyfoot",
- expectedResult = 1)
- self.assert_re_match("Invalid subcommand", out[1]);
-
- # Queue commands
-
- for cmd in ["queuepause", "queueresume"]:
-
- out = self.runcmd("smbcontrol self printnotify %s" % cmd,
- expectedResult = 1)
- self.assert_re_match("Usage:", out[1])
-
- out = self.runcmd("smbcontrol self printnotify %s spottyfoot"
- % cmd)
-
- # Job commands
-
- for cmd in ["jobpause", "jobresume", "jobdelete"]:
-
- out = self.runcmd("smbcontrol self printnotify %s" % cmd,
- expectedResult = 1)
- self.assert_re_match("Usage:", out[1])
-
- out = self.runcmd("smbcontrol self printnotify %s spottyfoot"
- % cmd, expectedResult = 1)
- self.assert_re_match("Usage:", out[1])
-
- out = self.runcmd("smbcontrol self printnotify %s spottyfoot 123"
- % cmd)
-
- # Printer properties
-
- out = self.runcmd("smbcontrol self printnotify printer",
- expectedResult = 1)
- self.assert_re_match("Usage", out[1])
-
- out = self.runcmd("smbcontrol self printnotify printer spottyfoot",
- expectedResult = 1)
- self.assert_re_match("Usage", out[1])
-
- for cmd in ["comment", "port", "driver"]:
-
- out = self.runcmd("smbcontrol self printnotify printer spottyfoot "
- "%s" % cmd, expectedResult = 1)
- self.assert_re_match("Usage", out[1])
-
- out = self.runcmd("smbcontrol self printnotify printer spottyfoot "
- "%s value" % cmd)
-
-class Profile(comfychair.TestCase):
- """Test setting the profiling level."""
- def runtest(self):
- self.require_root()
- out = self.runcmd("smbcontrol self profile", expectedResult = 1)
- self.assert_re_match("Usage", out[1])
-
- out = self.runcmd("smbcontrol self profile spottyfoot",
- expectedResult = 1)
- self.assert_re_match("Unknown", out[1])
-
- for cmd in ["off", "count", "on", "flush"]:
- out = self.runcmd("smbcontrol self profile %s" % cmd)
-
-class ProfileLevel(comfychair.TestCase):
- """Test requesting the current profiling level."""
- def runtest(self):
- self.require_root()
- out = self.runcmd("smbcontrol self profilelevel spottyfoot",
- expectedResult = 1)
- self.assert_re_match("Usage", out[1])
-
- out = self.runcmd("smbcontrol self profilelevel")
-
-class TimeoutArg(comfychair.TestCase):
- """Test the --timeout argument."""
- def runtest(self):
- out = self.runcmd("smbcontrol --timeout 5 self noop")
- out = self.runcmd("smbcontrol --timeout spottyfoot self noop",
- expectedResult = 1)
-
-class ConfigFileArg(comfychair.TestCase):
- """Test the --configfile argument."""
- def runtest(self):
- out = self.runcmd("smbcontrol --configfile /dev/null self noop")
-
-class BogusArg(comfychair.TestCase):
- """Test a bogus command line argument."""
- def runtest(self):
- out = self.runcmd("smbcontrol --bogus self noop", expectedResult = 1)
-
-tests = [NoArgs, OneArg, SmbdDest, NmbdDest, WinbinddDest, PidDest,
- SelfDest, BadDest, BadCmd, Debug, ForceElection, SamSync,
- SamRepl, DmallocMark, DmallocChanged, Shutdown, DrvUpgrade,
- CloseShare, Ping, Debuglevel, PrintNotify, Profile, ProfileLevel,
- TimeoutArg, ConfigFileArg, BogusArg]
-
-# Handle execution of this file as a main program
-
-if __name__ == '__main__':
- comfychair.main(tests)
diff --git a/source/stf/spoolss.py b/source/stf/spoolss.py
deleted file mode 100755
index 735291508bc..00000000000
--- a/source/stf/spoolss.py
+++ /dev/null
@@ -1,288 +0,0 @@
-#!/usr/bin/python
-
-import re
-import comfychair, stf
-from samba import spoolss
-
-class PrintServerTest(comfychair.TestCase):
- """An abstract class requiring a print server."""
- def setUp(self):
- # TODO: create a test printer
- self.server = stf.get_server(platform = "nt")
- self.require(self.server != None, "print server required")
- # TODO: remove hardcoded printer name
- self.printername = "p"
- self.uncname = "\\\\%s\\%s" % \
- (self.server["hostname"], self.printername)
-
-class W2kPrintServerTest(comfychair.TestCase):
- """An abstract class requiring a print server."""
- def setUp(self):
- # TODO: create a test printer
- self.server = stf.get_server(platform = "nt5")
- self.require(self.server != None, "print server required")
- # TODO: remove hardcoded printer name
- self.printername = "p"
- self.uncname = "\\\\%s\\%s" % \
- (self.server["hostname"], self.printername)
-
-class CredentialTest(PrintServerTest):
- """An class that calls a function with various sets of credentials."""
- def runTest(self):
-
- bad_user_creds = {"username": "spotty",
- "domain": "dog",
- "password": "bone"}
-
- cases = ((self.server["administrator"], "Admin credentials", 1),
- (bad_user_creds, "Bad credentials", 0))
-
- # TODO: add unpriv user case
-
- for creds, testname, result in cases:
- try:
- self.runTestArg(creds)
- except:
- if result:
- import traceback
- traceback.print_exc()
- self.fail("rpc with creds %s failed when it "
- "should have suceeded" % creds)
- return
-
- if not result:
- self.fail("rpc with creds %s suceeded when it should "
- "have failed" % creds)
-
-class ArgTestServer(PrintServerTest):
- """Test a RPC that takes a UNC print server name."""
- def runTest(self):
-
- # List of test cases, %s substituted for server name
-
- cases = (("", "No server name", 0),
- ("\\\\%s", "Valid server name", 1),
- ("\\%s", "Invalid unc server name", 0),
- ("\\\\%s__", "Invalid unc server name", 0))
-
- for unc, testname, result in cases:
- unc = re.sub("%s", self.server["hostname"], unc)
- try:
- self.runTestArg(unc)
- except:
- if result:
- self.fail("rpc(\"%s\") failed when it should have "
- "suceeded" % unc)
- return
-
- if not result:
- # Suceeded when we should have failed
- self.fail("rpc(\"%s\") suceeded when it should have "
- "failed" % unc)
-
-class ArgTestServerAndPrinter(ArgTestServer):
- """Test a RPC that takes a UNC print server or UNC printer name."""
- def runTest(self):
-
- ArgTestServer.runTest(self)
-
- # List of test cases, %s substituted for server name, %p substituted
- # for printer name.
-
- cases = (("\\\\%s\\%p", "Valid server and printer name", 1),
- ("\\\\%s\\%p__", "Valid server, invalid printer name", 0),
- ("\\\\%s__\\%p", "Invalid server, valid printer name", 0))
-
- for unc, testname, result in cases:
- unc = re.sub("%s", self.server["hostname"], unc)
- unc = re.sub("%p", self.printername, unc)
- try:
- self.runTestArg(unc)
- except:
- if result:
- self.fail("openprinter(\"%s\") failed when it should have "
- "suceeded" % unc)
- return
-
- if not result:
- # Suceeded when we should have failed
- self.fail("openprinter(\"%s\") suceeded when it should have "
- "failed" % unc)
-
-class OpenPrinterArg(ArgTestServerAndPrinter):
- """Test the OpenPrinter RPC with combinations of valid and invalid
- server and printer names."""
- def runTestArg(self, unc):
- spoolss.openprinter(unc)
-
-class OpenPrinterCred(CredentialTest):
- """Test opening printer with good and bad credentials."""
- def runTestArg(self, creds):
- spoolss.openprinter(self.uncname, creds = creds)
-
-class ClosePrinter(PrintServerTest):
- """Test the ClosePrinter RPC on a printer handle."""
- def runTest(self):
- hnd = spoolss.openprinter(self.uncname)
- spoolss.closeprinter(hnd)
-
-class ClosePrinterServer(PrintServerTest):
- """Test the ClosePrinter RPC on a print server handle."""
- def runTest(self):
- hnd = spoolss.openprinter("\\\\%s" % self.server["hostname"])
- spoolss.closeprinter(hnd)
-
-class GetPrinterInfo(PrintServerTest):
- """Retrieve printer info at various levels."""
-
- # Sample printer data
-
- sample_info = {
- 0: {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '\\\\win2kdc1', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': 1114112, 'name': '\\\\win2kdc1\\p', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 2, 'status': 1, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0},
- 1: {'comment': "I'm a teapot!", 'level': 1, 'flags': 8388608, 'name': '\\\\win2kdc1\\p', 'description': '\\\\win2kdc1\\p,HP LaserJet 4,Canberra office'},
- 2: {'comment': "I'm a teapot!", 'status': 1, 'print_processor': 'WinPrint', 'until_time': 0, 'share_name': 'p', 'start_time': 0, 'device_mode': {'icm_method': 1, 'bits_per_pel': 0, 'log_pixels': 0, 'orientation': 1, 'panning_width': 0, 'color': 2, 'pels_width': 0, 'print_quality': 600, 'driver_version': 24, 'display_flags': 0, 'y_resolution': 600, 'media_type': 0, 'display_frequency': 0, 'icm_intent': 0, 'pels_height': 0, 'reserved1': 0, 'size': 220, 'scale': 100, 'dither_type': 0, 'panning_height': 0, 'default_source': 7, 'duplex': 1, 'fields': 16131, 'spec_version': 1025, 'copies': 1, 'device_name': '\\\\win2kdc1\\p', 'paper_size': 1, 'paper_length': 0, 'private': 'private', 'collate': 0, 'paper_width': 0, 'form_name': 'Letter', 'reserved2': 0, 'tt_option': 0}, 'port_name': 'LPT1:', 'sepfile': '', 'parameters': '', 'security_descriptor': {'group_sid': 'S-1-5-21-1606980848-1677128483-854245398-513', 'sacl': None, 'dacl': {'ace_list': [{'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-544'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-544'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1121'}, {'flags': 10, 'type': 0, 'mask': 131072, 'trustee': 'S-1-3-0'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-3-0'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1124'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-1-0'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-550'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-550'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-549'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-549'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1106'}], 'revision': 2}, 'owner_sid': 'S-1-5-32-544', 'revision': 1}, 'name': '\\\\win2kdc1\\p', 'server_name': '\\\\win2kdc1', 'level': 2, 'datatype': 'RAW', 'cjobs': 0, 'average_ppm': 0, 'priority': 1, 'driver_name': 'HP LaserJet 4', 'location': 'Canberra office', 'attributes': 8776, 'default_priority': 0},
- 3: {'flags': 4, 'security_descriptor': {'group_sid': 'S-1-5-21-1606980848-1677128483-854245398-513', 'sacl': None, 'dacl': {'ace_list': [{'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-544'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-544'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1121'}, {'flags': 10, 'type': 0, 'mask': 131072, 'trustee': 'S-1-3-0'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-3-0'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1124'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-1-0'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-550'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-550'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-549'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-549'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1106'}], 'revision': 2}, 'owner_sid': 'S-1-5-32-544', 'revision': 1}, 'level': 3}
- }
-
- def runTest(self):
- self.hnd = spoolss.openprinter(self.uncname)
-
- # Everyone should have getprinter levels 0-3
-
- for i in (0, 1, 2, 3):
- info = self.hnd.getprinter(level = i)
- try:
- stf.dict_check(self.sample_info[i], info)
- except ValueError, msg:
- raise "info%d: %s" % (i, msg)
-
-class EnumPrinters(PrintServerTest):
- """Enumerate print info at various levels."""
-
- sample_info = {
-
- 0: {'q': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': -1833435136, 'name': 'q', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 0, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}, 'p': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': -1831337984, 'name': 'p', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 1, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}, 'magpie': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': 1114112, 'name': 'magpie', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 0, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}},
-
- 1: {'q': {'comment': 'cheepy birds', 'level': 1, 'flags': 8388608, 'name': 'q', 'description': 'q,HP LaserJet 4,'}, 'p': {'comment': "I'm a teapot!", 'level': 1, 'flags': 8388608, 'name': 'p', 'description': 'p,HP LaserJet 4,Canberra office'}, 'magpie': {'comment': '', 'level': 1, 'flags': 8388608, 'name': 'magpie', 'description': 'magpie,Generic / Text Only,'}}
- }
-
- def runTest(self):
- for i in (0, 1):
- info = spoolss.enumprinters(
- "\\\\%s" % self.server["hostname"], level = i)
- try:
- stf.dict_check(self.sample_info[i], info)
- except ValueError, msg:
- raise "info%d: %s" % (i, msg)
-
-class EnumPrintersArg(ArgTestServer):
- def runTestArg(self, unc):
- spoolss.enumprinters(unc)
-
-class EnumPrintersCred(CredentialTest):
- """Test opening printer with good and bad credentials."""
- def runTestArg(self, creds):
- spoolss.enumprinters(
- "\\\\%s" % self.server["hostname"], creds = creds)
-
-class EnumPrinterdrivers(PrintServerTest):
-
- sample_info = {
- 1: {'Okipage 10ex (PCL5E) : STANDARD': {'name': 'Okipage 10ex (PCL5E) : STANDARD', 'level': 1}, 'Generic / Text Only': {'name': 'Generic / Text Only', 'level': 1}, 'Brother HL-1030 series': {'name': 'Brother HL-1030 series', 'level': 1}, 'Brother HL-1240 series': {'name': 'Brother HL-1240 series', 'level': 1}, 'HP DeskJet 1220C Printer': {'name': 'HP DeskJet 1220C Printer', 'level': 1}, 'HP LaserJet 4100 PCL 6': {'name': 'HP LaserJet 4100 PCL 6', 'level': 1}, 'HP LaserJet 4': {'name': 'HP LaserJet 4', 'level': 1}},
- 2: {'Okipage 10ex (PCL5E) : STANDARD': {'version': 2, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\RASDDUI.DLL', 'name': 'Okipage 10ex (PCL5E) : STANDARD', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\2\\RASDD.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\OKIPAGE.DLL', 'level': 2, 'architecture': 'Windows NT x86'}, 'Generic / Text Only': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\UNIDRVUI.DLL', 'name': 'Generic / Text Only', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\UNIDRV.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\TTY.GPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'Brother HL-1030 series': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BRUHL99A.DLL', 'name': 'Brother HL-1030 series', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL99A.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL103.PPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'Brother HL-1240 series': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BRUHL99A.DLL', 'name': 'Brother HL-1240 series', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL99A.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL124.PPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP DeskJet 1220C Printer': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'name': 'HP DeskJet 1220C Printer', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP LaserJet 4100 PCL 6': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042E.DLL', 'name': 'HP LaserJet 4100 PCL 6', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042G.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042I.PMD', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP LaserJet 4': {'version': 2, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff0.dll', 'name': 'HP LaserJet 4', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff2.dll', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff39.pmd', 'level': 2, 'architecture': 'Windows NT x86'}}
- }
-
- def runTest(self):
- for i in (1, 2):
- info = spoolss.enumprinterdrivers(
- "\\\\%s" % self.server["hostname"], level = i)
- try:
- if not self.sample_info.has_key(i):
- self.log("%s" % info)
- self.fail()
- stf.dict_check(self.sample_info[i], info)
- except ValueError, msg:
- raise "info%d: %s" % (i, msg)
-
-class EnumPrinterdriversArg(ArgTestServer):
- def runTestArg(self, unc):
- spoolss.enumprinterdrivers(unc)
-
-class EnumPrinterdriversCred(CredentialTest):
- """Test opening printer with good and bad credentials."""
- def runTestArg(self, creds):
- spoolss.enumprinterdrivers(
- "\\\\%s" % self.server["hostname"], creds = creds)
-
-def usage():
- print "Usage: spoolss.py [options] [test1[,test2...]]"
- print "\t -v/--verbose Display debugging information"
- print "\t -l/--list-tests List available tests"
- print
- print "A list of comma separated test names or regular expressions"
- print "can be used to filter the tests performed."
-
-def test_match(subtest_list, test_name):
- """Return true if a test matches a comma separated list of regular
- expression of test names."""
- # re.match does an implicit ^ at the start of the pattern.
- # Explicitly anchor to end to avoid matching substrings.
- for s in string.split(subtest_list, ","):
- if re.match(s + "$", test_name):
- return 1
- return 0
-
-if __name__ == "__main__":
- import os, sys, string
- import getopt
-
- try:
- opts, args = getopt.getopt(sys.argv[1:], "vl", \
- ["verbose", "list-tests"])
- except getopt.GetoptError:
- usage()
- sys.exit(0)
-
- verbose = 0
- list_tests = 0
-
- for opt, arg in opts:
- if opt in ("-v", "--verbose"):
- verbose = 1
- if opt in ("-l", "--list-tests"):
- list_tests = 1
-
- if len(args) > 1:
- usage()
- sys.exit(0)
-
- test_list = [
- OpenPrinterArg,
- OpenPrinterCred,
- ClosePrinter,
- ClosePrinterServer,
- GetPrinterInfo,
- EnumPrinters,
- EnumPrintersCred,
- EnumPrintersArg,
- EnumPrinterdrivers,
- EnumPrinterdriversCred,
- EnumPrinterdriversArg,
- ]
-
- if len(args):
- t = []
- for test in test_list:
- if test_match(args[0], test.__name__):
- t.append(test)
- test_list = t
-
- if os.environ.has_key("SAMBA_DEBUG"):
- spoolss.setup_logging(interactive = 1)
- spoolss.set_debuglevel(10)
-
- if list_tests:
- for test in test_list:
- print test.__name__
- else:
- comfychair.runtests(test_list, verbose = verbose)
diff --git a/source/stf/standardcheck.py b/source/stf/standardcheck.py
deleted file mode 100644
index e3292353e8b..00000000000
--- a/source/stf/standardcheck.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /usr/bin/python
-
-# Comfychair test cases for Samba
-
-# Copyright (C) 2003 by Martin Pool <mbp@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-"""These tests are run by Samba's "make check"."""
-
-import strings, comfychair
-import smbcontrol, sambalib
-
-# There should not be any actual tests in here: this file just serves
-# to define the ones run by default. They're imported from other
-# modules.
-
-tests = strings.tests + smbcontrol.tests + sambalib.tests
-
-if __name__ == '__main__':
- comfychair.main(tests)
diff --git a/source/stf/stf.py b/source/stf/stf.py
deleted file mode 100755
index ee0ff735612..00000000000
--- a/source/stf/stf.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-#
-# Samba Testing Framework for Unit-testing
-#
-
-import os, string, re
-import osver
-
-def get_server_list_from_string(s):
-
- server_list = []
-
- # Format is a list of server:domain\username%password separated
- # by commas.
-
- for entry in string.split(s, ","):
-
- # Parse entry
-
- m = re.match("(.*):(.*)(\\\\|/)(.*)%(.*)", entry)
- if not m:
- raise "badly formed server list entry '%s'" % entry
-
- server = m.group(1)
- domain = m.group(2)
- username = m.group(4)
- password = m.group(5)
-
- # Categorise servers
-
- server_list.append({"platform": osver.os_version(server),
- "hostname": server,
- "administrator": {"username": username,
- "domain": domain,
- "password" : password}})
-
- return server_list
-
-def get_server_list():
- """Iterate through all sources of server info and append them all
- in one big list."""
-
- server_list = []
-
- # The $STF_SERVERS environment variable
-
- if os.environ.has_key("STF_SERVERS"):
- server_list = server_list + \
- get_server_list_from_string(os.environ["STF_SERVERS"])
-
- return server_list
-
-def get_server(platform = None):
- """Return configuration information for a server. The platform
- argument can be a string either 'nt4' or 'nt5' for Windows NT or
- Windows 2000 servers, or just 'nt' for Windows NT and higher."""
-
- server_list = get_server_list()
-
- for server in server_list:
- if platform:
- p = server["platform"]
- if platform == "nt":
- if (p == osver.PLATFORM_NT4 or p == osver.PLATFORM_NT5):
- return server
- if platform == "nt4" and p == osver.PLATFORM_NT4:
- return server
- if platform == "nt5" and p == osver.PLATFORM_NT5:
- return server
- else:
- # No filter defined, return first in list
- return server
-
- return None
-
-def dict_check(sample_dict, real_dict):
- """Check that real_dict contains all the keys present in sample_dict
- and no extras. Also check that common keys are of them same type."""
- tmp = real_dict.copy()
- for key in sample_dict.keys():
- # Check existing key and type
- if not real_dict.has_key(key):
- raise ValueError, "dict does not contain key '%s'" % key
- if type(sample_dict[key]) != type(real_dict[key]):
- raise ValueError, "dict has differing types (%s vs %s) for key " \
- "'%s'" % (type(sample_dict[key]), type(real_dict[key]), key)
- # Check dictionaries recursively
- if type(sample_dict[key]) == dict:
- dict_check(sample_dict[key], real_dict[key])
- # Delete visited keys from copy
- del(tmp[key])
- # Any keys leftover are present in the real dict but not the sample
- if len(tmp) == 0:
- return
- result = "dict has extra keys: "
- for key in tmp.keys():
- result = result + key + " "
- raise ValueError, result
-
-if __name__ == "__main__":
- print get_server(platform = "nt")
diff --git a/source/stf/strings.py b/source/stf/strings.py
deleted file mode 100755
index 86f7acdeb47..00000000000
--- a/source/stf/strings.py
+++ /dev/null
@@ -1,151 +0,0 @@
-#! /usr/bin/python
-
-# Comfychair test cases for Samba string functions.
-
-# Copyright (C) 2003 by Martin Pool <mbp@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-# XXX: All this code assumes that the Unix character set is UTF-8,
-# which is the most common setting. I guess it would be better to
-# force it to that value while running the tests. I'm not sure of the
-# best way to do that yet.
-#
-# Note that this is NOT the case in C code until the loadparm table is
-# intialized -- the default seems to be ASCII, which rather lets Samba
-# off the hook. :-) The best way seems to be to put this in the test
-# harnesses:
-#
-# lp_load("/dev/null", True, False, False);
-#
-# -- mbp
-
-import sys, re, comfychair
-from unicodenames import *
-
-def signum(a):
- if a < 0:
- return -1
- elif a > 0:
- return +1
- else:
- return 0
-
-
-class PushUCS2_Tests(comfychair.TestCase):
- """Conversion to/from UCS2"""
- def runtest(self):
- OE = LATIN_CAPITAL_LETTER_O_WITH_DIARESIS
- oe = LATIN_CAPITAL_LETTER_O_WITH_DIARESIS
- cases = ['hello',
- 'hello world',
- 'g' + OE + OE + 'gomobile',
- 'g' + OE + oe + 'gomobile',
- u'foo\u0100',
- KATAKANA_LETTER_A * 20,
- ]
- for u8str in cases:
- out, err = self.runcmd("t_push_ucs2 \"%s\"" % u8str.encode('utf-8'))
- self.assert_equal(out, "0\n")
-
-
-class StrCaseCmp(comfychair.TestCase):
- """String comparisons in simple ASCII"""
- def run_strcmp(self, a, b, expect):
- out, err = self.runcmd('t_strcmp \"%s\" \"%s\"' % (a.encode('utf-8'), b.encode('utf-8')))
- if signum(int(out)) != expect:
- self.fail("comparison failed:\n"
- " a=%s\n"
- " b=%s\n"
- " expected=%s\n"
- " result=%s\n" % (`a`, `b`, `expect`, `out`))
-
- def runtest(self):
- # A, B, strcasecmp(A, B)
- cases = [('hello', 'hello', 0),
- ('hello', 'goodbye', +1),
- ('goodbye', 'hello', -1),
- ('hell', 'hello', -1),
- ('', '', 0),
- ('a', '', +1),
- ('', 'a', -1),
- ('a', 'A', 0),
- ('aa', 'aA', 0),
- ('Aa', 'aa', 0),
- ('longstring ' * 100, 'longstring ' * 100, 0),
- ('longstring ' * 100, 'longstring ' * 100 + 'a', -1),
- ('longstring ' * 100 + 'a', 'longstring ' * 100, +1),
- (KATAKANA_LETTER_A, KATAKANA_LETTER_A, 0),
- (KATAKANA_LETTER_A, 'a', 1),
- ]
- for a, b, expect in cases:
- self.run_strcmp(a, b, expect)
-
-class strstr_m(comfychair.TestCase):
- """String comparisons in simple ASCII"""
- def run_strstr(self, a, b, expect):
- out, err = self.runcmd('t_strstr \"%s\" \"%s\"' % (a.encode('utf-8'), b.encode('utf-8')))
- if (out != (expect + '\n').encode('utf-8')):
- self.fail("comparison failed:\n"
- " a=%s\n"
- " b=%s\n"
- " expected=%s\n"
- " result=%s\n" % (`a`, `b`, `expect+'\n'`, `out`))
-
- def runtest(self):
- # A, B, strstr_m(A, B)
- cases = [('hello', 'hello', 'hello'),
- ('hello', 'goodbye', '(null)'),
- ('goodbye', 'hello', '(null)'),
- ('hell', 'hello', '(null)'),
- ('hello', 'hell', 'hello'),
- ('', '', ''),
- ('a', '', 'a'),
- ('', 'a', '(null)'),
- ('a', 'A', '(null)'),
- ('aa', 'aA', '(null)'),
- ('Aa', 'aa', '(null)'),
- ('%v foo', '%v', '%v foo'),
- ('foo %v foo', '%v', '%v foo'),
- ('foo %v', '%v', '%v'),
- ('longstring ' * 100, 'longstring ' * 99, 'longstring ' * 100),
- ('longstring ' * 99, 'longstring ' * 100, '(null)'),
- ('longstring a' * 99, 'longstring ' * 100 + 'a', '(null)'),
- ('longstring ' * 100 + 'a', 'longstring ' * 100, 'longstring ' * 100 + 'a'),
- (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', '(null)'),
- (KATAKANA_LETTER_A + 'bcde', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcde'),
- ('d'+KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd'),
- ('d'+KATAKANA_LETTER_A + 'bd', KATAKANA_LETTER_A + 'bcd', '(null)'),
-
- ('e'+KATAKANA_LETTER_A + 'bcdf', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcdf'),
- (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', '(null)'),
- (KATAKANA_LETTER_A*3, 'a', '(null)'),
- ]
- for a, b, expect in cases:
- self.run_strstr(a, b, expect)
-
-# Define the tests exported by this module
-tests = [StrCaseCmp,
- strstr_m,
- PushUCS2_Tests]
-
-# Handle execution of this file as a main program
-if __name__ == '__main__':
- comfychair.main(tests)
-
-# Local variables:
-# coding: utf-8
-# End:
diff --git a/source/stf/test.py b/source/stf/test.py
deleted file mode 100755
index fb57926cc3a..00000000000
--- a/source/stf/test.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-
-# meta-test-case / example for comfychair. Should demonstrate
-# different kinds of failure.
-
-import comfychair
-
-class NormalTest(comfychair.TestCase):
- def runtest(self):
- pass
-
-class RootTest(comfychair.TestCase):
- def setup(self):
- self.require_root()
-
- def runTest(self):
- pass
-
-class GoodExecTest(comfychair.TestCase):
- def runtest(self):
- stdout = self.runcmd("ls -l")
-
-class BadExecTest(comfychair.TestCase):
- def setup(self):
- exit, stdout = self.runcmd_unchecked("spottyfoot --slobber",
- skip_on_noexec = 1)
-
-
-tests = [NormalTest, RootTest, GoodExecTest, BadExecTest]
-
-if __name__ == '__main__':
- comfychair.main(tests)
-
diff --git a/source/stf/unicodenames.py b/source/stf/unicodenames.py
deleted file mode 100644
index d4100cb7f90..00000000000
--- a/source/stf/unicodenames.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /usr/bin/python
-
-# Copyright (C) 2003 by Martin Pool <mbp@samba.org>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-
-"""
-Defines symbolic names for a few UNICODE characters, to make test
-source code more readable on machines that don't have all the
-necessary fonts.
-
-You can do "import *" on this file safely.
-"""
-
-LATIN_CAPITAL_LETTER_N_WITH_TILDE = u'\u004e'
-LATIN_CAPITAL_LETTER_O_WITH_DIARESIS = u'\u00d6'
-LATIN_SMALL_LETTER_O_WITH_DIARESIS = u'\u00f6'
-
-KATAKANA_LETTER_A = u'\u30a2'
diff --git a/source/tdb/Makefile b/source/tdb/Makefile
index 59fbb079bd0..3417759124b 100644
--- a/source/tdb/Makefile
+++ b/source/tdb/Makefile
@@ -2,7 +2,7 @@
# Makefile for tdb directory
#
-CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1
+CFLAGS = -DSTANDALONE -DTDB_DEBUG -pg -g -DHAVE_MMAP=1
CC = gcc
PROGS = tdbtest tdbtool tdbtorture
diff --git a/source/tdb/README b/source/tdb/README
index fac3eacb4db..3715c685c20 100644
--- a/source/tdb/README
+++ b/source/tdb/README
@@ -60,7 +60,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
The hash size is advisory, use zero for a default value.
- return is NULL on error
+ Return is NULL on error, in which case errno is also set. Don't
+ try to call tdb_error or tdb_errname, just do strerror(errno).
possible tdb_flags are:
TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open
diff --git a/source/tdb/spinlock.c b/source/tdb/spinlock.c
index 24c4371decc..2370ce3bdd9 100644
--- a/source/tdb/spinlock.c
+++ b/source/tdb/spinlock.c
@@ -1,27 +1,21 @@
/*
Unix SMB/CIFS implementation.
-
- trivial database library
-
+ Samba database functions
Copyright (C) Anton Blanchard 2001
- ** NOTE! The following LGPL license applies to the tdb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if HAVE_CONFIG_H
#include <config.h>
@@ -149,47 +143,6 @@ static inline int __spin_is_locked(spinlock_t *lock)
return (*lock != 1);
}
-#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730)
-
-/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See
- * sync(3) for the details of the intrinsic operations.
- *
- * "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro.
- */
-
-#if defined(STANDALONE)
-
-/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */
-#define inline __inline
-
-#endif /* STANDALONE */
-
-/* Returns 0 if the lock is acquired, EBUSY otherwise. */
-static inline int __spin_trylock(spinlock_t *lock)
-{
- unsigned int val;
- val = __lock_test_and_set(lock, 1);
- return val == 0 ? 0 : EBUSY;
-}
-
-static inline void __spin_unlock(spinlock_t *lock)
-{
- __lock_release(lock);
-}
-
-static inline void __spin_lock_init(spinlock_t *lock)
-{
- __lock_release(lock);
-}
-
-/* Returns 1 if the lock is held, 0 otherwise. */
-static inline int __spin_is_locked(spinlock_t *lock)
-{
- unsigned int val;
- val = __add_and_fetch(lock, 0);
- return val;
-}
-
#elif defined(MIPS_SPINLOCKS)
static inline unsigned int load_linked(unsigned long addr)
@@ -268,11 +221,7 @@ static void yield_cpu(void)
static int this_is_smp(void)
{
-#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN)
- return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
-#else
return 0;
-#endif
}
/*
@@ -423,7 +372,7 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
unsigned size, i;
tdb_rwlock_t *rwlocks;
- size = TDB_SPINLOCK_SIZE(hash_size);
+ size = (hash_size + 1) * sizeof(tdb_rwlock_t);
rwlocks = malloc(size);
if (!rwlocks)
return -1;
diff --git a/source/tdb/spinlock.h b/source/tdb/spinlock.h
index 967fe37457f..d6a2ac6eb88 100644
--- a/source/tdb/spinlock.h
+++ b/source/tdb/spinlock.h
@@ -1,7 +1,7 @@
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
-#ifdef HAVE_CONFIG_H
+#if HAVE_CONFIG_H
#include <config.h>
#endif
@@ -39,8 +39,6 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
-#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t))
-
#else /* !USE_SPINLOCKS */
#if 0
#define tdb_create_rwlocks(fd, hash_size) 0
@@ -52,8 +50,6 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
#endif
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
-#define TDB_SPINLOCK_SIZE(hash_size) 0
-
#endif
#endif
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index cda9fc24750..130603e9e43 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -1,51 +1,25 @@
/*
Unix SMB/CIFS implementation.
-
- trivial database library
-
- Copyright (C) Andrew Tridgell 1999-2004
+ Samba database functions
+ Copyright (C) Andrew Tridgell 1999-2000
+ Copyright (C) Luke Kenneth Casson Leighton 2000
Copyright (C) Paul `Rusty' Russell 2000
Copyright (C) Jeremy Allison 2000-2003
- ** NOTE! The following LGPL license applies to the tdb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
-/* NOTE: If you use tdbs under valgrind, and in particular if you run
- * tdbtorture, you may get spurious "uninitialized value" warnings. I
- * think this is because valgrind doesn't understand that the mmap'd
- * area may be written to by other processes. Memory can, from the
- * point of view of the grinded process, spontaneously become
- * initialized.
- *
- * I can think of a few solutions. [mbp 20030311]
- *
- * 1 - Write suppressions for Valgrind so that it doesn't complain
- * about this. Probably the most reasonable but people need to
- * remember to use them.
- *
- * 2 - Use IO not mmap when running under valgrind. Not so nice.
- *
- * 3 - Use the special valgrind macros to mark memory as valid at the
- * right time. Probably too hard -- the process just doesn't know.
- */
-
#ifdef STANDALONE
#if HAVE_CONFIG_H
#include <config.h>
@@ -82,8 +56,6 @@
#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
-#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size))
-
/* NB assumes there is a local variable called "tdb" that is the
* current context, also takes doubly-parenthesized print-style
@@ -233,28 +205,14 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
if (ret == -1) {
if (!probe && lck_type != F_SETLK) {
- /* Ensure error code is set for log fun to examine. */
- if (errno == EINTR && palarm_fired && *palarm_fired)
- tdb->ecode = TDB_ERR_LOCK_TIMEOUT;
- else
- tdb->ecode = TDB_ERR_LOCK;
TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
tdb->fd, offset, rw_type, lck_type));
}
/* Was it an alarm timeout ? */
- if (errno == EINTR && palarm_fired && *palarm_fired) {
- TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
- tdb->fd, offset, rw_type, lck_type));
+ if (errno == EINTR && palarm_fired && *palarm_fired)
return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
- }
- /* Otherwise - generic lock error. errno set by fcntl.
- * EAGAIN is an expected return from non-blocking
- * locks. */
- if (errno != EAGAIN) {
- TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n",
- tdb->fd, offset, rw_type, lck_type,
- strerror(errno)));
- }
+ /* Otherwise - generic lock error. */
+ /* errno set by fcntl */
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
return 0;
@@ -354,8 +312,6 @@ static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe)
return 0;
if (tdb->flags & TDB_INTERNAL) {
if (!probe) {
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_IO;
TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n",
(int)len, (int)tdb->map_size));
}
@@ -367,8 +323,6 @@ static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe)
if (st.st_size < (size_t)len) {
if (!probe) {
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_IO;
TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n",
(int)len, (int)st.st_size));
}
@@ -397,8 +351,6 @@ static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len)
else if (lseek(tdb->fd, off, SEEK_SET) != off
|| write(tdb->fd, buf, len) != (ssize_t)len) {
#endif
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_IO;
TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n",
off, len, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_IO, -1);
@@ -420,8 +372,6 @@ static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv)
else if (lseek(tdb->fd, off, SEEK_SET) != off
|| read(tdb->fd, buf, len) != (ssize_t)len) {
#endif
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_IO;
TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n",
off, len, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_IO, -1);
@@ -437,8 +387,6 @@ static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len)
char *buf;
if (!(buf = malloc(len))) {
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_OOM;
TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n",
len, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_OOM, buf);
@@ -467,8 +415,6 @@ static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
return -1;
if (TDB_BAD_MAGIC(rec)) {
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_CORRUPT;
TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset));
return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
}
@@ -497,8 +443,6 @@ static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec)
}
if (rec->magic != TDB_FREE_MAGIC) {
- /* Ensure ecode is set for log fn. */
- tdb->ecode = TDB_ERR_CORRUPT;
TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n",
rec->magic, off));
return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
@@ -679,10 +623,10 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
left:
/* Look left */
left = offset - sizeof(tdb_off);
- if (left > TDB_DATA_START(tdb->header.hash_size)) {
+ if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) {
struct list_struct l;
tdb_off leftsize;
-
+
/* Read in tailer and jump back to header */
if (ofs_read(tdb, left, &leftsize) == -1) {
TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left));
@@ -862,8 +806,6 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
tdb_off rec_ptr, last_ptr, newrec_ptr;
struct list_struct newrec;
- memset(&newrec, '\0', sizeof(newrec));
-
if (tdb_lock(tdb, -1, F_WRLCK) == -1)
return 0;
@@ -1033,11 +975,12 @@ static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash)
}
/* As tdb_find, but if you succeed, keep the lock */
-static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype,
+static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype,
struct list_struct *rec)
{
- u32 rec_ptr;
+ u32 hash, rec_ptr;
+ hash = tdb_hash(&key);
if (!tdb_keylocked(tdb, hash))
return 0;
if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
@@ -1078,13 +1021,13 @@ const char *tdb_errorstr(TDB_CONTEXT *tdb)
on failure return -1.
*/
-static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf)
+static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
{
struct list_struct rec;
tdb_off rec_ptr;
/* find entry */
- if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
+ if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
return -1;
/* must be long enough key, data and tailer */
@@ -1118,11 +1061,9 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
tdb_off rec_ptr;
struct list_struct rec;
TDB_DATA ret;
- u32 hash;
/* find which hash bucket it is in */
- hash = tdb_hash(&key);
- if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
+ if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec)))
return tdb_null;
if (rec.data_len)
@@ -1141,22 +1082,16 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
this doesn't match the conventions in the rest of this module, but is
compatible with gdbm
*/
-static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
{
struct list_struct rec;
- if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
+ if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0)
return 0;
tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
return 1;
}
-int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
-{
- u32 hash = tdb_hash(&key);
- return tdb_exists_hash(tdb, key, hash);
-}
-
/* record lock stops delete underneath */
static int lock_record(TDB_CONTEXT *tdb, tdb_off off)
{
@@ -1304,7 +1239,7 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
if fn is NULL then it is not called
a non-zero return value from fn() indicates that the traversal should stop
*/
-int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private)
+int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state)
{
TDB_DATA key, dbuf;
struct list_struct rec;
@@ -1342,7 +1277,7 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private)
ret = -1;
goto out;
}
- if (fn && fn(tdb, key, dbuf, private)) {
+ if (fn && fn(tdb, key, dbuf, state)) {
/* They want us to terminate traversal */
ret = count;
if (unlock_record(tdb, tl.off) != 0) {
@@ -1413,7 +1348,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
if (!tdb->travlocks.off) {
/* No previous element: do normal find, and lock record */
- tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb_hash(&oldkey), F_WRLCK, &rec);
+ tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec);
if (!tdb->travlocks.off)
return tdb_null;
tdb->travlocks.hash = BUCKET(rec.full_hash);
@@ -1441,13 +1376,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
}
/* delete an entry in the database given a key */
-static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
{
tdb_off rec_ptr;
struct list_struct rec;
int ret;
- if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec)))
+ if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
return -1;
ret = do_delete(tdb, rec_ptr, &rec);
if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
@@ -1455,12 +1390,6 @@ static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
return ret;
}
-int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
-{
- u32 hash = tdb_hash(&key);
- return tdb_delete_hash(tdb, key, hash);
-}
-
/* store an element in the database, replacing any existing element
with the same key
@@ -1483,21 +1412,17 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
/* check for it existing, on insert. */
if (flag == TDB_INSERT) {
- if (tdb_exists_hash(tdb, key, hash)) {
+ if (tdb_exists(tdb, key)) {
tdb->ecode = TDB_ERR_EXISTS;
goto fail;
}
} else {
/* first try in-place update, on modify or replace. */
- if (tdb_update_hash(tdb, key, hash, dbuf) == 0)
+ if (tdb_update(tdb, key, dbuf) == 0)
goto out;
- if (tdb->ecode == TDB_ERR_NOEXIST &&
- flag == TDB_MODIFY) {
- /* if the record doesn't exist and we are in TDB_MODIFY mode then
- we should fail the store */
+ if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST)
goto fail;
}
- }
/* reset the error code potentially set by the tdb_update() */
tdb->ecode = TDB_SUCCESS;
@@ -1505,7 +1430,7 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
care. Doing this first reduces fragmentation, and avoids
coalescing with `allocated' block before it's updated. */
if (flag != TDB_INSERT)
- tdb_delete_hash(tdb, key, hash);
+ tdb_delete(tdb, key);
/* Copy key+value *before* allocating free space in case malloc
fails and we are left with a dead spot in the tdb. */
@@ -1519,7 +1444,9 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
if (dbuf.dsize)
memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
- /* we have to allocate some space */
+ /* now we're into insert / modify / replace of a record which
+ * we know could not be optimised by an in-place store (for
+ * various reasons). */
if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec)))
goto fail;
@@ -1552,13 +1479,13 @@ fail:
is <= the old data size and the key exists.
on failure return -1. Record must be locked before calling.
*/
-static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf)
+static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
{
struct list_struct rec;
tdb_off rec_ptr;
/* find entry */
- if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
+ if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
return -1;
/* Append of 0 is always ok. */
@@ -1600,7 +1527,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
return -1;
/* first try in-place. */
- if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0)
+ if (tdb_append_inplace(tdb, key, new_dbuf) == 0)
goto out;
/* reset the error code potentially set by the tdb_append_inplace() */
@@ -1643,7 +1570,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
care. Doing this first reduces fragmentation, and avoids
coalescing with `allocated' block before it's updated. */
- tdb_delete_hash(tdb, key, hash);
+ tdb_delete(tdb, key);
if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec)))
goto fail;
@@ -1712,7 +1639,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
{
TDB_CONTEXT *tdb;
struct stat st;
- int rev = 0, locked = 0;
+ int rev = 0, locked;
unsigned char *vp;
u32 vertest;
@@ -1770,8 +1697,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
/* we need to zero database if we are the only one with it open */
- if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
- (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) {
+ if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
+ && (tdb_flags & TDB_CLEAR_IF_FIRST)) {
open_flags |= O_CREAT;
if (ftruncate(tdb->fd, 0) == -1) {
TDB_LOG((tdb, 0, "tdb_open_ex: "
@@ -1783,7 +1710,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
|| strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
- || (tdb->header.version != TDB_VERSION
+ || tdb->header.version != TDB_VERSION
+ || (tdb->header.hash_size != hash_size
&& !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
/* its not a valid database - possibly initialise it */
if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
@@ -1844,19 +1772,10 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
name, strerror(errno)));
goto fail;
}
-
}
-
- /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
- we didn't get the initial exclusive lock as we need to let all other
- users know we're using it. */
-
- if (tdb_flags & TDB_CLEAR_IF_FIRST) {
- /* leave this lock in place to indicate it's in use */
- if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
- goto fail;
- }
-
+ /* leave this lock in place to indicate it's in use */
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
+ goto fail;
internal:
/* Internal (memory-only) databases skip all the code above to
@@ -1891,11 +1810,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
}
-/**
- * Close a database.
- *
- * @returns -1 for error; 0 for success.
- **/
+/* close a database */
int tdb_close(TDB_CONTEXT *tdb)
{
TDB_CONTEXT **i;
@@ -2034,14 +1949,12 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons
}
-/* reopen a tdb - this can be used after a fork to ensure that we have an independent
+/* reopen a tdb - this is used after a fork to ensure that we have an independent
seek pointer from our parent and to re-establish locks */
int tdb_reopen(TDB_CONTEXT *tdb)
{
struct stat st;
- if (tdb->flags & TDB_INTERNAL)
- return 0; /* Nothing to do. */
if (tdb_munmap(tdb) != 0) {
TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
goto fail;
@@ -2062,7 +1975,7 @@ int tdb_reopen(TDB_CONTEXT *tdb)
goto fail;
}
tdb_mmap(tdb);
- if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) {
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
goto fail;
}
@@ -2080,10 +1993,7 @@ int tdb_reopen_all(void)
TDB_CONTEXT *tdb;
for (tdb=tdbs; tdb; tdb = tdb->next) {
- /* Ensure no clear-if-first. */
- tdb->flags &= ~TDB_CLEAR_IF_FIRST;
- if (tdb_reopen(tdb) != 0)
- return -1;
+ if (tdb_reopen(tdb) != 0) return -1;
}
return 0;
diff --git a/source/tdb/tdb.h b/source/tdb/tdb.h
index eb120a8cecd..6f3b1ff7562 100644
--- a/source/tdb/tdb.h
+++ b/source/tdb/tdb.h
@@ -3,28 +3,22 @@
/*
Unix SMB/CIFS implementation.
+ Samba database functions
+ Copyright (C) Andrew Tridgell 1999
- trivial database library
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- Copyright (C) Andrew Tridgell 1999-2004
-
- ** NOTE! The following LGPL license applies to the tdb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __cplusplus
@@ -50,8 +44,7 @@ extern "C" {
/* error codes */
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
- TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT,
- TDB_ERR_NOEXIST};
+ TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT };
#ifndef u32
#define u32 unsigned
@@ -126,7 +119,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf);
int tdb_close(TDB_CONTEXT *tdb);
TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
-int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *);
+int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state);
int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
void tdb_unlockkeys(TDB_CONTEXT *tdb);
diff --git a/source/tdb/tdb.magic b/source/tdb/tdb.magic
deleted file mode 100644
index f5619e7327e..00000000000
--- a/source/tdb/tdb.magic
+++ /dev/null
@@ -1,10 +0,0 @@
-# Magic file(1) information about tdb files.
-#
-# Install this into /etc/magic or the corresponding location for your
-# system, or pass as a -m argument to file(1).
-
-# You may use and redistribute this file without restriction.
-
-0 string TDB\ file TDB database
->32 lelong =0x2601196D version 6, little-endian
->>36 lelong x hash size %d bytes
diff --git a/source/tdb/tdbback.c b/source/tdb/tdbback.c
deleted file mode 100644
index 68b6fadc882..00000000000
--- a/source/tdb/tdbback.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- low level tdb backup and restore utility
- Copyright (C) Andrew Tridgell 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifdef STANDALONE
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <sys/mman.h>
-
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <signal.h>
-
-#else
-#include "includes.h"
-#endif
-
-#include "tdb.h"
-
-static int failed;
-
-char *add_suffix(const char *name, const char *suffix)
-{
- char *ret;
- int len = strlen(name) + strlen(suffix) + 1;
- ret = malloc(len);
- if (!ret) {
- fprintf(stderr,"Out of memory!\n");
- exit(1);
- }
- snprintf(ret, len, "%s%s", name, suffix);
- return ret;
-}
-
-static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
-
- if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
- fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
- failed = 1;
- return 1;
- }
- return 0;
-}
-
-
-static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- return 0;
-}
-
-/*
- carefully backup a tdb, validating the contents and
- only doing the backup if its OK
- this function is also used for restore
-*/
-int backup_tdb(const char *old_name, const char *new_name)
-{
- TDB_CONTEXT *tdb;
- TDB_CONTEXT *tdb_new;
- char *tmp_name;
- struct stat st;
- int count1, count2;
-
- tmp_name = add_suffix(new_name, ".tmp");
-
- /* stat the old tdb to find its permissions */
- if (stat(old_name, &st) != 0) {
- perror(old_name);
- return 1;
- }
-
- /* open the old tdb */
- tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
- if (!tdb) {
- printf("Failed to open %s\n", old_name);
- return 1;
- }
-
- /* create the new tdb */
- unlink(tmp_name);
- tdb_new = tdb_open(tmp_name, tdb->header.hash_size,
- TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
- st.st_mode & 0777);
- if (!tdb_new) {
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* lock the old tdb */
- if (tdb_lockall(tdb) != 0) {
- fprintf(stderr,"Failed to lock %s\n", old_name);
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- failed = 0;
-
- /* traverse and copy */
- count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
- if (count1 < 0 || failed) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* close the old tdb */
- tdb_close(tdb);
-
- /* close the new tdb and re-open read-only */
- tdb_close(tdb_new);
- tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!tdb_new) {
- fprintf(stderr,"failed to reopen %s\n", tmp_name);
- unlink(tmp_name);
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* traverse the new tdb to confirm */
- count2 = tdb_traverse(tdb_new, test_fn, 0);
- if (count2 != count1) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* make sure the new tdb has reached stable storage */
- fsync(tdb_new->fd);
-
- /* close the new tdb and rename it to .bak */
- tdb_close(tdb_new);
- unlink(new_name);
- if (rename(tmp_name, new_name) != 0) {
- perror(new_name);
- free(tmp_name);
- return 1;
- }
-
- free(tmp_name);
-
- return 0;
-}
-
-
-
-/*
- verify a tdb and if it is corrupt then restore from *.bak
-*/
-int verify_tdb(const char *fname, const char *bak_name)
-{
- TDB_CONTEXT *tdb;
- int count = -1;
-
- /* open the tdb */
- tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
-
- /* traverse the tdb, then close it */
- if (tdb) {
- count = tdb_traverse(tdb, test_fn, NULL);
- tdb_close(tdb);
- }
-
- /* count is < 0 means an error */
- if (count < 0) {
- printf("restoring %s\n", fname);
- return backup_tdb(bak_name, fname);
- }
-
- printf("%s : %d records\n", fname, count);
-
- return 0;
-}
diff --git a/source/tdb/tdbback.h b/source/tdb/tdbback.h
deleted file mode 100644
index 7ebeaa494d6..00000000000
--- a/source/tdb/tdbback.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- low level tdb backup and restore utility
- Copyright (C) Andrew Tridgell 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-char *add_suffix(const char *name, const char *suffix);
-int backup_tdb(const char *old_name, const char *new_name);
-int verify_tdb(const char *fname, const char *bak_name);
diff --git a/source/tdb/tdbbackup.c b/source/tdb/tdbbackup.c
index 1a0e1c1588f..6bb0a7015d8 100644
--- a/source/tdb/tdbbackup.c
+++ b/source/tdb/tdbbackup.c
@@ -41,11 +41,6 @@
*/
-#ifdef STANDALONE
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
@@ -59,37 +54,185 @@
#include <sys/time.h>
#include <ctype.h>
#include <signal.h>
+#include "tdb.h"
+#include "version.h"
-#else
+static int failed;
-#include "includes.h"
+static char *add_suffix(const char *name, const char *suffix)
+{
+ char *ret;
+ int len = strlen(name) + strlen(suffix) + 1;
+ ret = malloc(len);
+ if (!ret) {
+ fprintf(stderr,"Out of memory!\n");
+ exit(1);
+ }
+ strncpy(ret, name, len);
+ strncat(ret, suffix, len);
+ return ret;
+}
-#endif
+static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+ TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
-#include "tdb.h"
-#include "tdbback.h"
+ if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
+ fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
+ failed = 1;
+ return 1;
+ }
+ return 0;
+}
+
+
+static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+ return 0;
+}
/*
- see if one file is newer than another
+ carefully backup a tdb, validating the contents and
+ only doing the backup if its OK
+ this function is also used for restore
*/
-static int file_newer(const char *fname1, const char *fname2)
+static int backup_tdb(const char *old_name, const char *new_name)
{
- struct stat st1, st2;
- if (stat(fname1, &st1) != 0) {
- return 0;
+ TDB_CONTEXT *tdb;
+ TDB_CONTEXT *tdb_new;
+ char *tmp_name;
+ struct stat st;
+ int count1, count2;
+
+ tmp_name = add_suffix(new_name, ".tmp");
+
+ /* stat the old tdb to find its permissions */
+ if (stat(old_name, &st) != 0) {
+ perror(old_name);
+ return 1;
+ }
+
+ /* open the old tdb */
+ tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
+ if (!tdb) {
+ printf("Failed to open %s\n", old_name);
+ return 1;
}
- if (stat(fname2, &st2) != 0) {
+
+ /* create the new tdb */
+ unlink(tmp_name);
+ tdb_new = tdb_open(tmp_name, tdb->header.hash_size,
+ TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
+ st.st_mode & 0777);
+ if (!tdb_new) {
+ perror(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* lock the old tdb */
+ if (tdb_lockall(tdb) != 0) {
+ fprintf(stderr,"Failed to lock %s\n", old_name);
+ tdb_close(tdb);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
return 1;
}
- return (st1.st_mtime > st2.st_mtime);
+
+ failed = 0;
+
+ /* traverse and copy */
+ count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
+ if (count1 < 0 || failed) {
+ fprintf(stderr,"failed to copy %s\n", old_name);
+ tdb_close(tdb);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* close the old tdb */
+ tdb_close(tdb);
+
+ /* close the new tdb and re-open read-only */
+ tdb_close(tdb_new);
+ tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
+ if (!tdb_new) {
+ fprintf(stderr,"failed to reopen %s\n", tmp_name);
+ unlink(tmp_name);
+ perror(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* traverse the new tdb to confirm */
+ count2 = tdb_traverse(tdb_new, test_fn, 0);
+ if (count2 != count1) {
+ fprintf(stderr,"failed to copy %s\n", old_name);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* make sure the new tdb has reached stable storage */
+ fsync(tdb_new->fd);
+
+ /* close the new tdb and rename it to .bak */
+ tdb_close(tdb_new);
+ unlink(new_name);
+ if (rename(tmp_name, new_name) != 0) {
+ perror(new_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ printf("%s : %d records\n", old_name, count1);
+ free(tmp_name);
+
+ return 0;
+}
+
+
+
+/*
+ verify a tdb and if it is corrupt then restore from *.bak
+*/
+static int verify_tdb(const char *fname, const char *bak_name)
+{
+ TDB_CONTEXT *tdb;
+ int count = -1;
+
+ /* open the tdb */
+ tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
+
+ /* traverse the tdb, then close it */
+ if (tdb) {
+ count = tdb_traverse(tdb, test_fn, NULL);
+ tdb_close(tdb);
+ }
+
+ /* count is < 0 means an error */
+ if (count < 0) {
+ printf("restoring %s\n", fname);
+ return backup_tdb(bak_name, fname);
+ }
+
+ printf("%s : %d records\n", fname, count);
+
+ return 0;
}
+
static void usage(void)
{
printf("Usage: tdbbackup [options] <fname...>\n\n");
+ printf("Version: %s\n", VERSION);
printf(" -h this help message\n");
printf(" -s suffix set the backup suffix\n");
- printf(" -v verify mode (restore if corrupt)\n");
+ printf(" -v veryify mode (restore if corrupt)\n");
}
@@ -136,8 +279,7 @@ static void usage(void)
ret = 1;
}
} else {
- if (file_newer(fname, bak_name) &&
- backup_tdb(fname, bak_name) != 0) {
+ if (backup_tdb(fname, bak_name) != 0) {
ret = 1;
}
}
diff --git a/source/tdb/tdbdump.c b/source/tdb/tdbdump.c
index d2530f9f54c..9c1dc2761b6 100644
--- a/source/tdb/tdbdump.c
+++ b/source/tdb/tdbdump.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <fcntl.h>
#include <time.h>
+#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <ctype.h>
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 92009dcef48..d27160e0e84 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -111,24 +111,23 @@ static void print_data(unsigned char *buf,int len)
static void help(void)
{
- printf("\n"
-"tdbtool: \n"
-" create dbname : create a database\n"
-" open dbname : open an existing database\n"
-" erase : erase the database\n"
-" dump : dump the database as strings\n"
-" insert key data : insert a record\n"
-" move key file : move a record to a destination tdb\n"
-" store key data : store a record (replace)\n"
-" show key : show a record by key\n"
-" delete key : delete a record by key\n"
-" list : print the database hash table and freelist\n"
-" free : print the database freelist\n"
-" 1 | first : print the first record\n"
-" n | next : print the next record\n"
-" q | quit : terminate\n"
-" \\n : repeat 'next' command\n"
-"\n");
+ printf(" \n \
+tdbtool: \n \
+ create dbname : create a database \n \
+ open dbname : open an existing database \n \
+ erase : erase the database \n \
+ dump : dump the database as strings \n \
+ insert key data : insert a record \n \
+ store key data : store a record (replace) \n \
+ show key : show a record by key \n \
+ delete key : delete a record by key \n \
+ list : print the database hash table and freelist \n \
+ free : print the database freelist \n \
+ 1 | first : print the first record \n \
+ n | next : print the next record \n \
+ q | quit : terminate \n \
+ \\n : repeat 'next' command \n \
+");
}
static void terror(char *why)
@@ -256,22 +255,11 @@ static void show_tdb(void)
dbuf = tdb_fetch(tdb, key);
if (!dbuf.dptr) {
- /* maybe it is non-NULL terminated key? */
- key.dsize = strlen(k);
- dbuf = tdb_fetch(tdb, key);
-
- if ( !dbuf.dptr ) {
- terror("fetch failed");
- return;
- }
+ terror("fetch failed");
+ return;
}
-
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
print_rec(tdb, key, dbuf, NULL);
-
- free( dbuf.dptr );
-
- return;
}
static void delete_tdb(void)
@@ -292,57 +280,6 @@ static void delete_tdb(void)
}
}
-static void move_rec(void)
-{
- char *k = get_token(1);
- char *file = get_token(0);
- TDB_DATA key, dbuf;
- TDB_CONTEXT *dst_tdb;
-
- if (!k) {
- help();
- return;
- }
-
- if ( !file ) {
- terror("need destination tdb name");
- return;
- }
-
- key.dptr = k;
- key.dsize = strlen(k)+1;
-
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr) {
- /* maybe it is non-NULL terminated key? */
- key.dsize = strlen(k);
- dbuf = tdb_fetch(tdb, key);
-
- if ( !dbuf.dptr ) {
- terror("fetch failed");
- return;
- }
- }
-
- print_rec(tdb, key, dbuf, NULL);
-
- dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600);
- if ( !dst_tdb ) {
- terror("unable to open destination tdb");
- return;
- }
-
- if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
- terror("failed to move record");
- }
- else
- printf("record moved\n");
-
- tdb_close( dst_tdb );
-
- return;
-}
-
#if 0
static int print_conn_key(TDB_DATA key)
{
@@ -432,10 +369,8 @@ static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
dbuf = tdb_fetch(the_tdb, *pkey);
if (!dbuf.dptr) terror("fetch failed");
- else {
- /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
- print_rec(the_tdb, *pkey, dbuf, NULL);
- }
+ /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
+ print_rec(the_tdb, *pkey, dbuf, NULL);
}
static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
@@ -517,9 +452,6 @@ int main(int argc, char *argv[])
} else if (strcmp(tok,"dump") == 0) {
bIterate = 0;
tdb_traverse(tdb, print_rec, NULL);
- } else if (strcmp(tok,"move") == 0) {
- bIterate = 0;
- move_rec();
} else if (strcmp(tok,"list") == 0) {
tdb_dump_all(tdb);
} else if (strcmp(tok, "free") == 0) {
diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c
index 3f704e537ea..c4d912a1477 100644
--- a/source/tdb/tdbtorture.c
+++ b/source/tdb/tdbtorture.c
@@ -5,7 +5,6 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
-#include <signal.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -22,7 +21,6 @@
#define REOPEN_PROB 30
#define DELETE_PROB 8
#define STORE_PROB 4
-#define APPEND_PROB 6
#define LOCKSTORE_PROB 0
#define TRAVERSE_PROB 20
#define CULL_PROB 100
@@ -124,15 +122,6 @@ static void addrec_db(void)
}
#endif
-#if APPEND_PROB
- if (random() % APPEND_PROB == 0) {
- if (tdb_append(db, key, data) != 0) {
- fatal("tdb_append failed");
- }
- goto next;
- }
-#endif
-
#if LOCKSTORE_PROB
if (random() % LOCKSTORE_PROB == 0) {
tdb_chainlock(db, lockkey);
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index 2ccfa310c60..99c5eda9c4b 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -1,8 +1,7 @@
/*
Unix SMB/CIFS implementation.
tdb utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Andrew Tridgell 1992-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,7 +19,6 @@
*/
#include "includes.h"
-#include <fnmatch.h>
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
@@ -36,23 +34,11 @@ static void gotalarm_sig(void)
gotalarm = 1;
}
-/***************************************************************
- Make a TDB_DATA and keep the const warning in one place
-****************************************************************/
-
-static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
-{
- TDB_DATA ret;
- ret.dptr = dptr;
- ret.dsize = dsize;
- return ret;
-}
-
/****************************************************************************
Lock a chain with timeout (in seconds).
****************************************************************************/
-static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
{
/* Allow tdb_chainlock to be interrupted by an alarm. */
int ret;
@@ -64,46 +50,30 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
alarm(timeout);
}
- if (rw_type == F_RDLCK)
- ret = tdb_chainlock_read(tdb, key);
- else
- ret = tdb_chainlock(tdb, key);
+ ret = tdb_chainlock(tdb, key);
if (timeout) {
alarm(0);
CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
- if (gotalarm) {
- DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
- timeout, key.dptr, tdb->name ));
- /* TODO: If we time out waiting for a lock, it might
- * be nice to use F_GETLK to get the pid of the
- * process currently holding the lock and print that
- * as part of the debugging message. -- mbp */
+ if (gotalarm)
return -1;
- }
}
return ret;
}
/****************************************************************************
- Write lock a chain. Return -1 if timeout or lock failed.
-****************************************************************************/
-
-int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
-{
- return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);
-}
-
-/****************************************************************************
Lock a chain by string. Return -1 if timeout or lock failed.
****************************************************************************/
int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout)
{
- TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
+ TDB_DATA key;
+
+ key.dptr = keyval;
+ key.dsize = strlen(keyval)+1;
- return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);
+ return tdb_chainlock_with_timeout(tdb, key, timeout);
}
/****************************************************************************
@@ -112,34 +82,14 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout
void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval)
{
- TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
-
- tdb_chainunlock(tdb, key);
-}
-
-/****************************************************************************
- Read lock a chain by string. Return -1 if timeout or lock failed.
-****************************************************************************/
-
-int tdb_read_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout)
-{
- TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
-
- return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK);
-}
+ TDB_DATA key;
-/****************************************************************************
- Read unlock a chain by string.
-****************************************************************************/
-
-void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval)
-{
- TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
+ key.dptr = keyval;
+ key.dsize = strlen(keyval)+1;
- tdb_chainunlock_read(tdb, key);
+ tdb_chainunlock(tdb, key);
}
-
/****************************************************************************
Fetch a int32 value by a arbitrary blob key, return -1 if not found.
Output is int32 in native byte order.
@@ -147,16 +97,15 @@ void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval)
int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len)
{
- TDB_DATA key = make_tdb_data(keyval, len);
- TDB_DATA data;
+ TDB_DATA key, data;
int32 ret;
+ key.dptr = keyval;
+ key.dsize = len;
data = tdb_fetch(tdb, key);
- if (!data.dptr || data.dsize != sizeof(int32)) {
- SAFE_FREE(data.dptr);
+ if (!data.dptr || data.dsize != sizeof(int32))
return -1;
- }
-
+
ret = IVAL(data.dptr,0);
SAFE_FREE(data.dptr);
return ret;
@@ -179,10 +128,11 @@ int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr)
int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v)
{
- TDB_DATA key = make_tdb_data(keystr, len);
- TDB_DATA data;
+ TDB_DATA key, data;
int32 v_store;
+ key.dptr = keystr;
+ key.dsize = len;
SIVAL(&v_store,0,v);
data.dptr = (void *)&v_store;
data.dsize = sizeof(int32);
@@ -207,15 +157,14 @@ int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v)
BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value)
{
- TDB_DATA key = make_tdb_data(keyval, len);
- TDB_DATA data;
+ TDB_DATA key, data;
+ key.dptr = keyval;
+ key.dsize = len;
data = tdb_fetch(tdb, key);
- if (!data.dptr || data.dsize != sizeof(uint32)) {
- SAFE_FREE(data.dptr);
+ if (!data.dptr || data.dsize != sizeof(uint32))
return False;
- }
-
+
*value = IVAL(data.dptr,0);
SAFE_FREE(data.dptr);
return True;
@@ -238,11 +187,12 @@ BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value)
BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value)
{
- TDB_DATA key = make_tdb_data(keystr, len);
- TDB_DATA data;
+ TDB_DATA key, data;
uint32 v_store;
BOOL ret = True;
+ key.dptr = keystr;
+ key.dsize = len;
SIVAL(&v_store, 0, value);
data.dptr = (void *)&v_store;
data.dsize = sizeof(uint32);
@@ -267,34 +217,32 @@ BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value)
on failure.
****************************************************************************/
-int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags)
+int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, void *buffer, int len)
{
- TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
-
- return tdb_store(tdb, key, data, flags);
-}
+ TDB_DATA key, data;
-/****************************************************************************
- Fetch a buffer using a null terminated string key. Don't forget to call
- free() on the result dptr.
-****************************************************************************/
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
-TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr)
-{
- TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
+ data.dptr = buffer;
+ data.dsize = len;
- return tdb_fetch(tdb, key);
+ return tdb_store(tdb, key, data, TDB_REPLACE);
}
/****************************************************************************
- Delete an entry using a null terminated string key.
+ Fetch a buffer using a null terminated string key. Don't forget to call
+ free() on the result dptr.
****************************************************************************/
-int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr)
+TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr)
{
- TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
+ TDB_DATA key;
- return tdb_delete(tdb, key);
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
+
+ return tdb_fetch(tdb, key);
}
/****************************************************************************
@@ -312,10 +260,10 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldva
if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
/* The lookup failed */
if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
- /* but not because it didn't exist */
+ /* but not becouse it didn't exist */
goto err_out;
}
-
+
/* Start with 'old' value */
val = *oldval;
@@ -323,10 +271,10 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldva
/* It worked, set return value (oldval) to tdb data */
*oldval = val;
}
-
+
/* Increment value for storage and return next time */
val += change_val;
-
+
if (tdb_store_int32(tdb, keystr, val) == -1)
goto err_out;
@@ -342,40 +290,40 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldva
Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval.
****************************************************************************/
-BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldval, uint32 change_val)
+BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, char *keystr, uint32 *oldval, uint32 change_val)
{
uint32 val;
BOOL ret = False;
-
+
if (tdb_lock_bystring(tdb, keystr,0) == -1)
return False;
-
+
if (!tdb_fetch_uint32(tdb, keystr, &val)) {
/* It failed */
- if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
- /* and not because it didn't exist */
+ if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
+ /* and not becouse it didn't exist */
goto err_out;
}
-
+
/* Start with 'old' value */
val = *oldval;
-
+
} else {
/* it worked, set return value (oldval) to tdb data */
*oldval = val;
-
+
}
-
+
/* get a new value to store */
val += change_val;
-
+
if (!tdb_store_uint32(tdb, keystr, val))
goto err_out;
-
+
ret = True;
-
+
err_out:
-
+
tdb_unlock_bystring(tdb, keystr);
return ret;
}
@@ -388,7 +336,6 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
{
va_list ap;
- uint8 bt;
uint16 w;
uint32 d;
int i;
@@ -404,50 +351,44 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
while (*fmt) {
switch ((c = *fmt++)) {
- case 'b': /* unsigned 8-bit integer */
- len = 1;
- bt = (uint8)va_arg(ap, int);
- if (bufsize && bufsize >= len)
- SSVAL(buf, 0, bt);
- break;
- case 'w': /* unsigned 16-bit integer */
+ case 'w':
len = 2;
w = (uint16)va_arg(ap, int);
- if (bufsize && bufsize >= len)
+ if (bufsize >= len)
SSVAL(buf, 0, w);
break;
- case 'd': /* signed 32-bit integer (standard int in most systems) */
+ case 'd':
len = 4;
d = va_arg(ap, uint32);
- if (bufsize && bufsize >= len)
+ if (bufsize >= len)
SIVAL(buf, 0, d);
break;
- case 'p': /* pointer */
+ case 'p':
len = 4;
p = va_arg(ap, void *);
d = p?1:0;
- if (bufsize && bufsize >= len)
+ if (bufsize >= len)
SIVAL(buf, 0, d);
break;
- case 'P': /* null-terminated string */
+ case 'P':
s = va_arg(ap,char *);
w = strlen(s);
len = w + 1;
- if (bufsize && bufsize >= len)
+ if (bufsize >= len)
memcpy(buf, s, len);
break;
- case 'f': /* null-terminated string */
+ case 'f':
s = va_arg(ap,char *);
w = strlen(s);
len = w + 1;
- if (bufsize && bufsize >= len)
+ if (bufsize >= len)
memcpy(buf, s, len);
break;
- case 'B': /* fixed-length string */
+ case 'B':
i = va_arg(ap, int);
s = va_arg(ap, char *);
len = 4+i;
- if (bufsize && bufsize >= len) {
+ if (bufsize >= len) {
SIVAL(buf, 0, i);
memcpy(buf+4, s, i);
}
@@ -460,10 +401,7 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
}
buf += len;
- if (bufsize)
- bufsize -= len;
- if (bufsize < 0)
- bufsize = 0;
+ bufsize -= len;
}
va_end(ap);
@@ -482,7 +420,6 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
{
va_list ap;
- uint8 *bt;
uint16 *w;
uint32 *d;
int len;
@@ -498,13 +435,6 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
while (*fmt) {
switch ((c=*fmt++)) {
- case 'b':
- len = 1;
- bt = va_arg(ap, uint8 *);
- if (bufsize < len)
- goto no_space;
- *bt = SVAL(buf, 0);
- break;
case 'w':
len = 2;
w = va_arg(ap, uint16 *);
@@ -582,216 +512,6 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
return -1;
}
-
-/**
- * Pack SID passed by pointer
- *
- * @param pack_buf pointer to buffer which is to be filled with packed data
- * @param bufsize size of packing buffer
- * @param sid pointer to sid to be packed
- *
- * @return length of the packed representation of the whole structure
- **/
-size_t tdb_sid_pack(char* pack_buf, int bufsize, const DOM_SID* sid)
-{
- int idx;
- size_t len = 0;
-
- if (!sid || !pack_buf) return -1;
-
- len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
- sid->num_auths);
-
- for (idx = 0; idx < 6; idx++) {
- len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]);
- }
-
- for (idx = 0; idx < MAXSUBAUTHS; idx++) {
- len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]);
- }
-
- return len;
-}
-
-
-/**
- * Unpack SID into a pointer
- *
- * @param pack_buf pointer to buffer with packed representation
- * @param bufsize size of the buffer
- * @param sid pointer to sid structure to be filled with unpacked data
- *
- * @return size of structure unpacked from buffer
- **/
-size_t tdb_sid_unpack(const char* pack_buf, int bufsize, DOM_SID* sid)
-{
- int idx, len = 0;
- char* buf = NULL;
-
- if (!sid || !pack_buf) return -1;
-
- buf = (char*)malloc(bufsize);
- memcpy((void*)buf, pack_buf, bufsize);
-
- len += tdb_unpack(buf + len, bufsize - len, "bb",
- &sid->sid_rev_num, &sid->num_auths);
-
- for (idx = 0; idx < 6; idx++) {
- len += tdb_unpack(buf + len, bufsize - len,
- "b", &sid->id_auth[idx]);
- }
-
- for (idx = 0; idx < MAXSUBAUTHS; idx++) {
- len += tdb_unpack(buf + len, bufsize - len,
- "d", &sid->sub_auths[idx]);
- }
-
- SAFE_FREE(buf);
- return len;
-}
-
-
-/**
- * Pack TRUSTED_DOM_PASS passed by pointer
- *
- * @param pack_buf pointer to buffer which is to be filled with packed data
- * @param bufsize size of the buffer
- * @param pass pointer to trusted domain password to be packed
- *
- * @return length of the packed representation of the whole structure
- **/
-size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass)
-{
- int idx, len = 0;
-
- if (!pack_buf || !pass) return -1;
-
- /* packing unicode domain name and password */
- len += tdb_pack(pack_buf + len, bufsize - len, "d", pass->uni_name_len);
-
- for (idx = 0; idx < 32; idx++)
- len += tdb_pack(pack_buf + len, bufsize - len, "w", pass->uni_name[idx]);
-
- len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len,
- pass->pass, pass->mod_time);
-
- /* packing SID structure */
- len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid);
-
- return len;
-}
-
-
-/**
- * Unpack TRUSTED_DOM_PASS passed by pointer
- *
- * @param pack_buf pointer to buffer with packed representation
- * @param bufsize size of the buffer
- * @param pass pointer to trusted domain password to be filled with unpacked data
- *
- * @return size of structure unpacked from buffer
- **/
-size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass)
-{
- int idx, len = 0;
-
- if (!pack_buf || !pass) return -1;
-
- /* unpack unicode domain name and plaintext password */
- len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
-
- for (idx = 0; idx < 32; idx++)
- len += tdb_unpack(pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]);
-
- len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass,
- &pass->mod_time);
-
- /* unpack domain sid */
- len += tdb_sid_unpack(pack_buf + len, bufsize - len, &pass->domain_sid);
-
- return len;
-}
-
-
-/**
- * Unpack SAM_TRUST_PASSWD passed by pointer
- *
- * @param pack_buf pointer to buffer with packed representation
- * @param bufsize size of the buffer
- * @param pass pointer to trusted domain password to be filled with unpacked data
- *
- * @return size of structure unpacked from buffer
- **/
-size_t tdb_trustpw_unpack(SAM_TRUST_PASSWD* trustpw, const char* pack_buf, int bufsize)
-{
- int idx, len = 0, pass_len =0;
- struct trust_passwd_data *t;
-
- if (!trustpw || !pack_buf) return -1;
- t = &trustpw->private;
-
- /* packing password type flags */
- len += tdb_unpack(pack_buf + len, bufsize - len, "w", &t->flags);
-
- /* unpack unicode domain name and plaintext password */
- len += tdb_unpack(pack_buf + len, bufsize - len, "d", &t->uni_name_len);
- for (idx = 0; idx < 32; idx++)
- len += tdb_unpack((const char*)(pack_buf + len), bufsize - len,
- "w", &t->uni_name[idx]);
-
- /* unpacking password and last modification time */
- len += tdb_unpack((const char*)(pack_buf + len), bufsize - len, "dPd",
- &pass_len, &t->pass, &t->mod_time);
-
- if (pass_len > FSTRING_LEN) return -1;
- t->pass[pass_len] = 0;
-
- /* unpack sid */
- len += tdb_sid_unpack((const char*)(pack_buf + len), bufsize - len,
- &t->domain_sid);
-
- return len;
-}
-
-
-/**
- * Pack SAM_TRUST_PASSWD passed by pointer
- *
- * @param pack_buf pointer to buffer which is to be filled with packed data
- * @param bufsize size of the buffer
- * @param pass pointer to trust password to be packed
- *
- * @return length of the packed representation of the structure
- **/
-
-size_t tdb_trustpw_pack(const SAM_TRUST_PASSWD* trustpw, char* pack_buf, int bufsize)
-{
- int idx, len = 0;
- struct trust_passwd_data t;
-
- if (!trustpw) return -1;
-
- t = trustpw->private;
-
- /* packing password type flags */
- len += tdb_pack(pack_buf + len, bufsize - len, "w", t.flags);
-
- /* packing unicode domain name and password */
- len += tdb_pack(pack_buf + len, bufsize - len, "d", t.uni_name_len);
- for (idx = 0; idx < 32; idx++)
- len += tdb_pack(pack_buf + len, bufsize - len, "w", t.uni_name[idx]);
-
- /* packing password and last modification time */
- len += tdb_pack(pack_buf + len, bufsize - len, "dPd", strlen(t.pass),
- t.pass, t.mod_time);
-
- /* packing SID structure */
- len += tdb_sid_pack(pack_buf + len, bufsize - len, &t.domain_sid);
-
- return len;
-}
-
-
/****************************************************************************
Log tdb messages via DEBUG().
****************************************************************************/
@@ -808,7 +528,7 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
if (!ptr || !*ptr)
return;
- DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr));
+ DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unknown", ptr));
SAFE_FREE(ptr);
}
@@ -843,73 +563,3 @@ int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
{
return tdb_delete(the_tdb, key);
}
-
-
-
-/**
- * Search across the whole tdb for keys that match the given pattern
- * return the result as a list of keys
- *
- * @param tdb pointer to opened tdb file context
- * @param pattern searching pattern used by fnmatch(3) functions
- *
- * @return list of keys found by looking up with given pattern
- **/
-TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern)
-{
- TDB_DATA key, next;
- TDB_LIST_NODE *list = NULL;
- TDB_LIST_NODE *rec = NULL;
- TDB_LIST_NODE *tmp = NULL;
-
- for (key = tdb_firstkey(tdb); key.dptr; key = next) {
- /* duplicate key string to ensure null-termination */
- char *key_str = (char*) strndup(key.dptr, key.dsize);
- if (!key_str) {
- DEBUG(0, ("tdb_search_keys: strndup() failed!\n"));
- smb_panic("strndup failed!\n");
- }
-
- DEBUG(18, ("checking %s for match to pattern %s\n", key_str, pattern));
-
- next = tdb_nextkey(tdb, key);
-
- /* do the pattern checking */
- if (fnmatch(pattern, key_str, 0) == 0) {
- rec = (TDB_LIST_NODE*) malloc(sizeof(*rec));
- ZERO_STRUCTP(rec);
-
- rec->node_key = key;
-
- DLIST_ADD_END(list, rec, tmp);
-
- DEBUG(18, ("checking %s matched pattern %s\n", key_str, pattern));
- } else {
- free(key.dptr);
- }
-
- /* free duplicated key string */
- free(key_str);
- }
-
- return list;
-
-}
-
-
-/**
- * Free the list returned by tdb_search_keys
- *
- * @param node list of results found by tdb_search_keys
- **/
-void tdb_search_list_free(TDB_LIST_NODE* node)
-{
- TDB_LIST_NODE *next_node;
-
- while (node) {
- next_node = node->next;
- SAFE_FREE(node->node_key.dptr);
- SAFE_FREE(node);
- node = next_node;
- };
-}
diff --git a/source/tdb/tdbutil.h b/source/tdb/tdbutil.h
deleted file mode 100644
index 1a181a962f2..00000000000
--- a/source/tdb/tdbutil.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- tdb utility functions
- Copyright (C) Andrew Tridgell 1999
- Copyright (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __TDBUTIL_H__
-#define __TDBUTIL_H__
-
-
-/* single node of a list returned by tdb_search_keys */
-typedef struct keys_node
-{
- struct keys_node *prev, *next;
- TDB_DATA node_key;
-} TDB_LIST_NODE;
-
-
-TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT*, const char*);
-void tdb_search_list_free(TDB_LIST_NODE*);
-
-
-#endif /* __TDBUTIL_H__ */
diff --git a/source/tests/shlib.c b/source/tests/shlib.c
deleted file mode 100644
index 761d9fd5c57..00000000000
--- a/source/tests/shlib.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* a trivial function used to test building shared libraries */
-
-int foo(void)
-{
- return 1;
-}
diff --git a/source/tests/sysquotas.c b/source/tests/sysquotas.c
deleted file mode 100644
index 2aa643326c0..00000000000
--- a/source/tests/sysquotas.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* this test should find out what quota api is available on the os */
-
-#if defined(HAVE_QUOTACTL_4A)
-/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ASM_TYPES_H
-#include <asm/types.h>
-#endif
-
-#if defined(HAVE_LINUX_QUOTA_H)
-# include <linux/quota.h>
-# if defined(HAVE_STRUCT_IF_DQBLK)
-# define SYS_DQBLK if_dqblk
-# elif defined(HAVE_STRUCT_MEM_DQBLK)
-# define SYS_DQBLK mem_dqblk
-# endif
-#elif defined(HAVE_SYS_QUOTA_H)
-# include <sys/quota.h>
-#endif
-
-#ifndef SYS_DQBLK
-#define SYS_DQBLK dqblk
-#endif
-
- int autoconf_quota(void)
-{
- int ret = -1;
- struct SYS_DQBLK D;
-
- ret = quotactl(Q_GETQUOTA,"/dev/hda1",0,(void *)&D);
-
- return ret;
-}
-
-#elif defined(HAVE_QUOTACTL_4B)
-/* int quotactl(const char *path, int cmd, int id, char *addr); */
-
-#ifdef HAVE_SYS_QUOTA_H
-#include <sys/quota.h>
-#else /* *BSD */
-#include <sys/types.h>
-#include <ufs/ufs/quota.h>
-#include <machine/param.h>
-#endif
-
- int autoconf_quota(void)
-{
- int ret = -1;
- struct dqblk D;
-
- ret = quotactl("/",Q_GETQUOTA,0,(char *) &D);
-
- return ret;
-}
-
-#elif defined(HAVE_QUOTACTL_3)
-/* int quotactl (char *spec, int request, char *arg); */
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_QUOTA_H
-#include <sys/quota.h>
-#endif
-
- int autoconf_quota(void)
-{
- int ret = -1;
- struct q_request request;
-
- ret = quotactl("/", Q_GETQUOTA, &request);
-
- return ret;
-}
-
-#elif defined(HAVE_QUOTACTL_2)
-
-#error HAVE_QUOTACTL_2 not implemented
-
-#else
-
-#error Unknow QUOTACTL prototype
-
-#endif
-
- int main(void)
-{
- autoconf_quota();
- return 0;
-}
diff --git a/source/tests/unixsock.c b/source/tests/unixsock.c
deleted file mode 100644
index f2765d68f67..00000000000
--- a/source/tests/unixsock.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- c-file-style: "linux" -*-
- *
- * Try creating a Unix-domain socket, opening it, and reading from it.
- * The POSIX name for these is AF_LOCAL/PF_LOCAL.
- *
- * This is used by the Samba autoconf scripts to detect systems which
- * don't have Unix-domain sockets, such as (probably) VMS, or systems
- * on which they are broken under some conditions, such as RedHat 7.0
- * (unpatched). We can't build WinBind there at the moment.
- *
- * Coding standard says to always use exit() for this, not return, so
- * we do.
- *
- * Martin Pool <mbp@samba.org>, June 2000. */
-
-/* TODO: Look for AF_LOCAL (most standard), AF_UNIX, and AF_FILE. */
-
-#include <stdio.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#if HAVE_ERRNO_DECL
-# include <errno.h>
-#else
-extern int errno;
-#endif
-
-static int bind_socket(char const *filename)
-{
- int sock_fd;
- struct sockaddr_un name;
- size_t size;
-
- /* Create the socket. */
- if ((sock_fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
- perror ("socket(PF_LOCAL, SOCK_STREAM)");
- exit(1);
- }
-
- /* Bind a name to the socket. */
- name.sun_family = AF_LOCAL;
- strncpy(name.sun_path, filename, sizeof (name.sun_path));
-
- /* The size of the address is
- the offset of the start of the filename,
- plus its length,
- plus one for the terminating null byte.
- Alternatively you can just do:
- size = SUN_LEN (&name);
- */
- size = SUN_LEN(&name);
- /* XXX: This probably won't work on unfriendly libcs */
-
- if (bind(sock_fd, (struct sockaddr *) &name, size) < 0) {
- perror ("bind");
- exit(1);
- }
-
- return sock_fd;
-}
-
-
-int main(void)
-{
- int sock_fd;
- int kid;
- char const *filename = "conftest.unixsock.sock";
-
- /* abolish hanging */
- alarm(15); /* secs */
-
- if ((sock_fd = bind_socket(filename)) < 0)
- exit(1);
-
- /* the socket will be deleted when autoconf cleans up these
- files. */
-
- exit(0);
-}
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
deleted file mode 100644
index bfce4b88b41..00000000000
--- a/source/torture/cmd_vfs.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- VFS module functions
-
- Copyright (C) Simo Sorce 2002
- Copyright (C) Eric Lorimer 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "vfstest.h"
-
-static const char *null_string = "";
-
-static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int i;
-
- if (argc < 2) {
- printf("Usage: load <modules>\n");
- return NT_STATUS_OK;
- }
-
- for (i=argc-1;i>0;i--) {
- if (!vfs_init_custom(vfs->conn, argv[i])) {
- DEBUG(0, ("load: (vfs_init_custom failed for %s)\n", argv[i]));
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- printf("load: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- char c;
- size_t size;
- if (argc != 3) {
- printf("Usage: populate <char> <size>\n");
- return NT_STATUS_OK;
- }
- c = argv[1][0];
- size = atoi(argv[2]);
- vfs->data = (char *)talloc(mem_ctx, size);
- if (vfs->data == NULL) {
- printf("populate: error=-1 (not enough memory)");
- return NT_STATUS_UNSUCCESSFUL;
- }
- memset(vfs->data, c, size);
- vfs->data_size = size;
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- size_t offset;
- size_t len;
- if (argc != 1 && argc != 3) {
- printf("Usage: showdata [<offset> <len>]\n");
- return NT_STATUS_OK;
- }
- if (vfs->data == NULL || vfs->data_size == 0) {
- printf("show_data: error=-1 (buffer empty)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (argc == 3) {
- offset = atoi(argv[1]);
- len = atoi(argv[2]);
- } else {
- offset = 0;
- len = vfs->data_size;
- }
- if ((offset + len) > vfs->data_size) {
- printf("show_data: error=-1 (not enough data in buffer)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
- dump_data(0, (char *)(vfs->data) + offset, len);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- SMB_VFS_CONNECT(vfs->conn, lp_servicename(vfs->conn->service), "vfstest");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- SMB_VFS_DISCONNECT(vfs->conn);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- SMB_BIG_UINT diskfree, bsize, dfree, dsize;
- if (argc != 2) {
- printf("Usage: disk_free <path>\n");
- return NT_STATUS_OK;
- }
-
- diskfree = SMB_VFS_DISK_FREE(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
- printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n",
- (unsigned long)diskfree,
- (unsigned long)bsize,
- (unsigned long)dfree,
- (unsigned long)dsize);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- if (argc != 2) {
- printf("Usage: opendir <fname>\n");
- return NT_STATUS_OK;
- }
-
- vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1]);
- if (vfs->currentdir == NULL) {
- printf("opendir error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("opendir: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- struct dirent *dent;
-
- if (vfs->currentdir == NULL) {
- printf("readdir: error=-1 (no open directory)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir);
- if (dent == NULL) {
- printf("readdir: NULL\n");
- return NT_STATUS_OK;
- }
-
- printf("readdir: %s\n", dent->d_name);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- if (argc != 2) {
- printf("Usage: mkdir <path>\n");
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) {
- printf("mkdir error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("mkdir: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int ret;
-
- if (vfs->currentdir == NULL) {
- printf("closedir: failure (no directory open)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = SMB_VFS_CLOSEDIR(vfs->conn, vfs->currentdir);
- if (ret == -1) {
- printf("closedir failure: %s\n", strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("closedir: ok\n");
- vfs->currentdir = NULL;
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int flags, fd;
- mode_t mode;
- const char *flagstr;
-
- mode = 00400;
-
- if (argc < 3 || argc > 5) {
- printf("Usage: open <filename> <flags> <mode>\n");
- printf(" flags: O = O_RDONLY\n");
- printf(" R = O_RDWR\n");
- printf(" W = O_WRONLY\n");
- printf(" C = O_CREAT\n");
- printf(" E = O_EXCL\n");
- printf(" T = O_TRUNC\n");
- printf(" A = O_APPEND\n");
- printf(" N = O_NONBLOCK/O_NDELAY\n");
-#ifdef O_SYNC
- printf(" S = O_SYNC\n");
-#endif
-#ifdef O_NOFOLLOW
- printf(" F = O_NOFOLLOW\n");
-#endif
- printf(" mode: see open.2\n");
- printf(" mode is ignored if C flag not present\n");
- printf(" mode defaults to 00400\n");
- return NT_STATUS_OK;
- }
- flags = 0;
- flagstr = argv[2];
- while (*flagstr) {
- switch (*flagstr) {
- case 'O':
- flags |= O_RDONLY;
- break;
- case 'R':
- flags |= O_RDWR;
- break;
- case 'W':
- flags |= O_WRONLY;
- break;
- case 'C':
- flags |= O_CREAT;
- break;
- case 'E':
- flags |= O_EXCL;
- break;
- case 'T':
- flags |= O_TRUNC;
- break;
- case 'A':
- flags |= O_APPEND;
- break;
- case 'N':
- flags |= O_NONBLOCK;
- break;
-#ifdef O_SYNC
- case 'S':
- flags |= O_SYNC;
- break;
-#endif
-#ifdef O_NOFOLLOW
- case 'F':
- flags |= O_NOFOLLOW;
- break;
-#endif
- default:
- printf("open: error=-1 (invalid flag!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
- flagstr++;
- }
- if ((flags & O_CREAT) && argc == 4) {
- if (sscanf(argv[3], "%o", &mode) == 0) {
- printf("open: error=-1 (invalid mode!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- fd = SMB_VFS_OPEN(vfs->conn, argv[1], flags, mode);
- if (fd == -1) {
- printf("open: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- vfs->files[fd] = (struct files_struct *)malloc(sizeof(struct files_struct));
- vfs->files[fd]->fsp_name = strdup(argv[1]);
- vfs->files[fd]->fd = fd;
- vfs->files[fd]->conn = vfs->conn;
- printf("open: fd=%d\n", fd);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int ret = -1;
-
- if (argc != 2) {
- printf("Usage: %s <path>\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- if (strcmp("rmdir", argv[0]) == 0 ) {
- ret = SMB_VFS_RMDIR(vfs->conn, argv[1]);
- } else if (strcmp("unlink", argv[0]) == 0 ) {
- ret = SMB_VFS_UNLINK(vfs->conn, argv[1]);
- } else if (strcmp("chdir", argv[0]) == 0 ) {
- ret = SMB_VFS_CHDIR(vfs->conn, argv[1]);
- } else {
- printf("%s: error=%d (invalid function name!)\n", argv[0], errno);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (ret == -1) {
- printf("%s: error=%d (%s)\n", argv[0], errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("%s: ok\n", argv[0]);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd, ret;
-
- if (argc != 2) {
- printf("Usage: close <fd>\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- if (vfs->files[fd] == NULL) {
- printf("close: error=-1 (invalid file descriptor)\n");
- return NT_STATUS_OK;
- }
-
- ret = SMB_VFS_CLOSE(vfs->files[fd], fd);
- if (ret == -1 )
- printf("close: error=%d (%s)\n", errno, strerror(errno));
- else
- printf("close: ok\n");
-
- SAFE_FREE(vfs->files[fd]->fsp_name);
- SAFE_FREE(vfs->files[fd]);
- vfs->files[fd] = NULL;
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd;
- size_t size, rsize;
-
- if (argc != 3) {
- printf("Usage: read <fd> <size>\n");
- return NT_STATUS_OK;
- }
-
- /* do some error checking on these */
- fd = atoi(argv[1]);
- size = atoi(argv[2]);
- vfs->data = (char *)talloc(mem_ctx, size);
- if (vfs->data == NULL) {
- printf("read: error=-1 (not enough memory)");
- return NT_STATUS_UNSUCCESSFUL;
- }
- vfs->data_size = size;
-
- rsize = SMB_VFS_READ(vfs->files[fd], fd, vfs->data, size);
- if (rsize == -1) {
- printf("read: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("read: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd, size, wsize;
-
- if (argc != 3) {
- printf("Usage: write <fd> <size>\n");
- return NT_STATUS_OK;
- }
-
- /* some error checking should go here */
- fd = atoi(argv[1]);
- size = atoi(argv[2]);
- if (vfs->data == NULL) {
- printf("write: error=-1 (buffer empty, please populate it before writing)");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (vfs->data_size < size) {
- printf("write: error=-1 (buffer too small, please put some more data in)");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- wsize = SMB_VFS_WRITE(vfs->files[fd], fd, vfs->data, size);
-
- if (wsize == -1) {
- printf("write: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("write: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd, offset, whence;
- SMB_OFF_T pos;
-
- if (argc != 4) {
- printf("Usage: lseek <fd> <offset> <whence>\n...where whence is 1 => SEEK_SET, 2 => SEEK_CUR, 3 => SEEK_END\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- offset = atoi(argv[2]);
- whence = atoi(argv[3]);
- switch (whence) {
- case 1: whence = SEEK_SET; break;
- case 2: whence = SEEK_CUR; break;
- default: whence = SEEK_END;
- }
-
- pos = SMB_VFS_LSEEK(vfs->files[fd], fd, offset, whence);
- if (pos == (SMB_OFF_T)-1) {
- printf("lseek: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("lseek: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int ret;
- if (argc != 3) {
- printf("Usage: rename <old> <new>\n");
- return NT_STATUS_OK;
- }
-
- ret = SMB_VFS_RENAME(vfs->conn, argv[1], argv[2]);
- if (ret == -1) {
- printf("rename: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("rename: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int ret, fd;
- if (argc != 2) {
- printf("Usage: fsync <fd>\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- ret = SMB_VFS_FSYNC(vfs->files[fd], fd);
- if (ret == -1) {
- printf("fsync: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("fsync: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int ret;
- const char *user;
- const char *group;
- struct passwd *pwd = NULL;
- struct group *grp = NULL;
- SMB_STRUCT_STAT st;
-
- if (argc != 2) {
- printf("Usage: stat <fname>\n");
- return NT_STATUS_OK;
- }
-
- ret = SMB_VFS_STAT(vfs->conn, argv[1], &st);
- if (ret == -1) {
- printf("stat: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = pwd->pw_name;
- else user = null_string;
- grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = grp->gr_name;
- else group = null_string;
-
- printf("stat: ok\n");
- printf(" File: %s", argv[1]);
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
-#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-#endif
-#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
-
- SAFE_FREE(pwd);
- SAFE_FREE(grp);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd;
- const char *user;
- const char *group;
- struct passwd *pwd = NULL;
- struct group *grp = NULL;
- SMB_STRUCT_STAT st;
-
- if (argc != 2) {
- printf("Usage: fstat <fd>\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- if (fd < 0 || fd > 1024) {
- printf("fstat: error=%d (file descriptor out of range)\n", EBADF);
- return NT_STATUS_OK;
- }
-
- if (vfs->files[fd] == NULL) {
- printf("fstat: error=%d (invalid file descriptor)\n", EBADF);
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_FSTAT(vfs->files[fd], fd, &st) == -1) {
- printf("fstat: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = pwd->pw_name;
- else user = null_string;
- grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = grp->gr_name;
- else group = null_string;
-
- printf("fstat: ok\n");
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
-#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-#endif
-#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
-
- SAFE_FREE(pwd);
- SAFE_FREE(grp);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- const char *user;
- const char *group;
- struct passwd *pwd = NULL;
- struct group *grp = NULL;
- SMB_STRUCT_STAT st;
-
- if (argc != 2) {
- printf("Usage: lstat <path>\n");
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_LSTAT(vfs->conn, argv[1], &st) == -1) {
- printf("lstat: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pwd = sys_getpwuid(st.st_uid);
- if (pwd != NULL) user = pwd->pw_name;
- else user = null_string;
- grp = sys_getgrgid(st.st_gid);
- if (grp != NULL) group = grp->gr_name;
- else group = null_string;
-
- printf("lstat: ok\n");
- if (S_ISREG(st.st_mode)) printf(" Regular File\n");
- else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
- else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
- else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
- else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
- else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
- else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
- printf(" Size: %10u", (unsigned int)st.st_size);
-#ifdef HAVE_STAT_ST_BLOCKS
- printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-#endif
-#ifdef HAVE_STAT_ST_BLKSIZE
- printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-#endif
- printf(" Device: 0x%10x", (unsigned int)st.st_dev);
- printf(" Inode: %10u", (unsigned int)st.st_ino);
- printf(" Links: %10u\n", (unsigned int)st.st_nlink);
- printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
- (unsigned long)st.st_gid, group);
- printf(" Access: %s", ctime(&(st.st_atime)));
- printf(" Modify: %s", ctime(&(st.st_mtime)));
- printf(" Change: %s", ctime(&(st.st_ctime)));
-
- SAFE_FREE(pwd);
- SAFE_FREE(grp);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- mode_t mode;
- if (argc != 3) {
- printf("Usage: chmod <path> <mode>\n");
- return NT_STATUS_OK;
- }
-
- mode = atoi(argv[2]);
- if (SMB_VFS_CHMOD(vfs->conn, argv[1], mode) == -1) {
- printf("chmod: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("chmod: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd;
- mode_t mode;
- if (argc != 3) {
- printf("Usage: fchmod <fd> <mode>\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- mode = atoi(argv[2]);
- if (fd < 0 || fd > 1024) {
- printf("fchmod: error=%d (file descriptor out of range)\n", EBADF);
- return NT_STATUS_OK;
- }
- if (vfs->files[fd] == NULL) {
- printf("fchmod: error=%d (invalid file descriptor)\n", EBADF);
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_FCHMOD(vfs->files[fd], fd, mode) == -1) {
- printf("fchmod: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("fchmod: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- uid_t uid;
- gid_t gid;
- if (argc != 4) {
- printf("Usage: chown <path> <uid> <gid>\n");
- return NT_STATUS_OK;
- }
-
- uid = atoi(argv[2]);
- gid = atoi(argv[3]);
- if (SMB_VFS_CHOWN(vfs->conn, argv[1], uid, gid) == -1) {
- printf("chown: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("chown: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- uid_t uid;
- gid_t gid;
- int fd;
- if (argc != 4) {
- printf("Usage: fchown <fd> <uid> <gid>\n");
- return NT_STATUS_OK;
- }
-
- uid = atoi(argv[2]);
- gid = atoi(argv[3]);
- fd = atoi(argv[1]);
- if (fd < 0 || fd > 1024) {
- printf("fchown: faliure=%d (file descriptor out of range)\n", EBADF);
- return NT_STATUS_OK;
- }
- if (vfs->files[fd] == NULL) {
- printf("fchown: error=%d (invalid file descriptor)\n", EBADF);
- return NT_STATUS_OK;
- }
- if (SMB_VFS_FCHOWN(vfs->files[fd], fd, uid, gid) == -1) {
- printf("fchown error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("fchown: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- char buf[PATH_MAX];
- if (SMB_VFS_GETWD(vfs->conn, buf) == NULL) {
- printf("getwd: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("getwd: %s\n", buf);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- struct utimbuf times;
- if (argc != 4) {
- printf("Usage: utime <path> <access> <modify>\n");
- return NT_STATUS_OK;
- }
- times.actime = atoi(argv[2]);
- times.modtime = atoi(argv[3]);
- if (SMB_VFS_UTIME(vfs->conn, argv[1], &times) != 0) {
- printf("utime: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("utime: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- int fd;
- SMB_OFF_T off;
- if (argc != 3) {
- printf("Usage: ftruncate <fd> <length>\n");
- return NT_STATUS_OK;
- }
-
- fd = atoi(argv[1]);
- off = atoi(argv[2]);
- if (fd < 0 || fd > 1024) {
- printf("ftruncate: error=%d (file descriptor out of range)\n", EBADF);
- return NT_STATUS_OK;
- }
- if (vfs->files[fd] == NULL) {
- printf("ftruncate: error=%d (invalid file descriptor)\n", EBADF);
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_FTRUNCATE(vfs->files[fd], fd, off) == -1) {
- printf("ftruncate: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("ftruncate: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- BOOL ret;
- int fd;
- int op;
- long offset;
- long count;
- int type;
- const char *typestr;
-
- if (argc != 6) {
- printf("Usage: lock <fd> <op> <offset> <count> <type>\n");
- printf(" ops: G = F_GETLK\n");
- printf(" S = F_SETLK\n");
- printf(" W = F_SETLKW\n");
- printf(" type: R = F_RDLCK\n");
- printf(" W = F_WRLCK\n");
- printf(" U = F_UNLCK\n");
- return NT_STATUS_OK;
- }
-
- if (sscanf(argv[1], "%d", &fd) == 0) {
- printf("lock: error=-1 (error parsing fd)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- op = 0;
- switch (*argv[2]) {
- case 'G':
- op = F_GETLK;
- break;
- case 'S':
- op = F_SETLK;
- break;
- case 'W':
- op = F_SETLKW;
- break;
- default:
- printf("lock: error=-1 (invalid op flag!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (sscanf(argv[3], "%ld", &offset) == 0) {
- printf("lock: error=-1 (error parsing fd)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (sscanf(argv[4], "%ld", &count) == 0) {
- printf("lock: error=-1 (error parsing fd)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- type = 0;
- typestr = argv[5];
- while(*typestr) {
- switch (*typestr) {
- case 'R':
- type |= F_RDLCK;
- break;
- case 'W':
- type |= F_WRLCK;
- break;
- case 'U':
- type |= F_UNLCK;
- break;
- default:
- printf("lock: error=-1 (invalid type flag!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
- typestr++;
- }
-
- printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type);
-
- if ((ret = SMB_VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) {
- printf("lock: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("lock: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- if (argc != 3) {
- printf("Usage: symlink <path> <link>\n");
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
- printf("symlink: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("symlink: ok\n");
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- char buffer[PATH_MAX];
- int size;
-
- if (argc != 2) {
- printf("Usage: readlink <path>\n");
- return NT_STATUS_OK;
- }
-
- if ((size = SMB_VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
- printf("readlink: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- buffer[size] = '\0';
- printf("readlink: %s\n", buffer);
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- if (argc != 3) {
- printf("Usage: link <path> <link>\n");
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) {
- printf("link: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("link: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- mode_t mode;
- unsigned int dev_val;
- SMB_DEV_T dev;
-
- if (argc != 4) {
- printf("Usage: mknod <path> <mode> <dev>\n");
- printf(" mode is octal\n");
- printf(" dev is hex\n");
- return NT_STATUS_OK;
- }
-
- if (sscanf(argv[2], "%o", &mode) == 0) {
- printf("open: error=-1 (invalid mode!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (sscanf(argv[3], "%x", &dev_val) == 0) {
- printf("open: error=-1 (invalid dev!)\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
- dev = (SMB_DEV_T)dev_val;
-
- if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) {
- printf("mknod: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("mknod: ok\n");
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- char respath[PATH_MAX];
-
- if (argc != 2) {
- printf("Usage: realpath <path>\n");
- return NT_STATUS_OK;
- }
-
- if (SMB_VFS_REALPATH(vfs->conn, argv[1], respath) == NULL) {
- printf("realpath: error=%d (%s)\n", errno, strerror(errno));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- printf("realpath: ok\n");
- return NT_STATUS_OK;
-}
-
-struct cmd_set vfs_commands[] = {
-
- { "VFS Commands" },
-
- { "load", cmd_load_module, "Load a module", "load <module.so>" },
- { "populate", cmd_populate, "Populate a data buffer", "populate <char> <size>" },
- { "showdata", cmd_show_data, "Show data currently in data buffer", "show_data [<offset> <len>]"},
- { "connect", cmd_connect, "VFS connect()", "connect" },
- { "disconnect", cmd_disconnect, "VFS disconnect()", "disconnect" },
- { "disk_free", cmd_disk_free, "VFS disk_free()", "disk_free <path>" },
- { "opendir", cmd_opendir, "VFS opendir()", "opendir <fname>" },
- { "readdir", cmd_readdir, "VFS readdir()", "readdir" },
- { "mkdir", cmd_mkdir, "VFS mkdir()", "mkdir <path>" },
- { "rmdir", cmd_pathfunc, "VFS rmdir()", "rmdir <path>" },
- { "closedir", cmd_closedir, "VFS closedir()", "closedir" },
- { "open", cmd_open, "VFS open()", "open <fname>" },
- { "close", cmd_close, "VFS close()", "close <fd>" },
- { "read", cmd_read, "VFS read()", "read <fd> <size>" },
- { "write", cmd_write, "VFS write()", "write <fd> <size>" },
- { "lseek", cmd_lseek, "VFS lseek()", "lseek <fd> <offset> <whence>" },
- { "rename", cmd_rename, "VFS rename()", "rename <old> <new>" },
- { "fsync", cmd_fsync, "VFS fsync()", "fsync <fd>" },
- { "stat", cmd_stat, "VFS stat()", "stat <fname>" },
- { "fstat", cmd_fstat, "VFS fstat()", "fstat <fd>" },
- { "lstat", cmd_lstat, "VFS lstat()", "lstat <fname>" },
- { "unlink", cmd_pathfunc, "VFS unlink()", "unlink <fname>" },
- { "chmod", cmd_chmod, "VFS chmod()", "chmod <path> <mode>" },
- { "fchmod", cmd_fchmod, "VFS fchmod()", "fchmod <fd> <mode>" },
- { "chown", cmd_chown, "VFS chown()", "chown <path> <uid> <gid>" },
- { "fchown", cmd_fchown, "VFS fchown()", "fchown <fd> <uid> <gid>" },
- { "chdir", cmd_pathfunc, "VFS chdir()", "chdir <path>" },
- { "getwd", cmd_getwd, "VFS getwd()", "getwd" },
- { "utime", cmd_utime, "VFS utime()", "utime <path> <access> <modify>" },
- { "ftruncate", cmd_ftruncate, "VFS ftruncate()", "ftruncate <fd> <length>" },
- { "lock", cmd_lock, "VFS lock()", "lock <f> <op> <offset> <count> <type>" },
- { "symlink", cmd_symlink, "VFS symlink()", "symlink <old> <new>" },
- { "readlink", cmd_readlink, "VFS readlink()", "readlink <path>" },
- { "link", cmd_link, "VFS link()", "link <oldpath> <newpath>" },
- { "mknod", cmd_mknod, "VFS mknod()", "mknod <path> <mode> <dev>" },
- { "realpath", cmd_realpath, "VFS realpath()", "realpath <path>" },
- { NULL }
-};
diff --git a/source/torture/denytest.c b/source/torture/denytest.c
deleted file mode 100644
index 89b0fdf93f6..00000000000
--- a/source/torture/denytest.c
+++ /dev/null
@@ -1,1577 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester - scanning functions
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-extern BOOL torture_showall;
-
-enum deny_result {A_0=0, A_X=1, A_R=2, A_W=3, A_RW=5};
-
-
-static const char *denystr(int denymode)
-{
- struct {
- int v;
- const char *name;
- } deny_modes[] = {
- {DENY_DOS, "DENY_DOS"},
- {DENY_ALL, "DENY_ALL"},
- {DENY_WRITE, "DENY_WRITE"},
- {DENY_READ, "DENY_READ"},
- {DENY_NONE, "DENY_NONE"},
- {DENY_FCB, "DENY_FCB"},
- {-1, NULL}};
- int i;
- for (i=0;deny_modes[i].name;i++) {
- if (deny_modes[i].v == denymode) return deny_modes[i].name;
- }
- return "DENY_XXX";
-}
-
-static const char *openstr(int mode)
-{
- struct {
- int v;
- const char *name;
- } open_modes[] = {
- {O_RDWR, "O_RDWR"},
- {O_RDONLY, "O_RDONLY"},
- {O_WRONLY, "O_WRONLY"},
- {-1, NULL}};
- int i;
- for (i=0;open_modes[i].name;i++) {
- if (open_modes[i].v == mode) return open_modes[i].name;
- }
- return "O_XXX";
-}
-
-static const char *resultstr(enum deny_result res)
-{
- struct {
- enum deny_result res;
- const char *name;
- } results[] = {
- {A_X, "X"},
- {A_0, "-"},
- {A_R, "R"},
- {A_W, "W"},
- {A_RW,"RW"}};
- int i;
- for (i=0;ARRAY_SIZE(results);i++) {
- if (results[i].res == res) return results[i].name;
- }
- return "*";
-}
-
-static struct {
- int isexe;
- int mode1, deny1;
- int mode2, deny2;
- enum deny_result result;
-} denytable2[] = {
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_READ, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_READ, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_R},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_W},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_READ, A_W},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_RW},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_W},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_READ, A_RW},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_READ, A_R},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_READ, A_W},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_0}
-};
-
-
-static struct {
- int isexe;
- int mode1, deny1;
- int mode2, deny2;
- enum deny_result result;
-} denytable1[] = {
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_READ, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_NONE, A_RW},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDWR, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_RDONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_RDONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_DOS, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_READ, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_READ, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_READ, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{1, O_WRONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{1, O_WRONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDWR, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{1, O_RDWR, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{1, O_RDWR, DENY_FCB, O_WRONLY, DENY_FCB, A_RW},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_RDONLY, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{1, O_RDONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{1, O_RDONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_RW},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{1, O_WRONLY, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{1, O_WRONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{1, O_WRONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_DOS, O_RDWR, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_DOS, O_RDONLY, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_DOS, O_WRONLY, DENY_FCB, A_RW},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_DOS, A_RW},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_DOS, A_R},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_DOS, A_W},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_DOS, O_RDWR, DENY_FCB, A_RW},
-{0, O_WRONLY, DENY_DOS, O_RDONLY, DENY_FCB, A_RW},
-{0, O_WRONLY, DENY_DOS, O_WRONLY, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_ALL, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_READ, A_R},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_NONE, A_R},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_WRITE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDWR, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_W},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_READ, A_W},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_NONE, A_W},
-{0, O_WRONLY, DENY_READ, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_READ, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDWR, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_RW},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_W},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_RDONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_RDONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_DOS, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_READ, A_RW},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_READ, A_R},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_READ, A_W},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_NONE, A_RW},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_NONE, A_R},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_NONE, A_W},
-{0, O_WRONLY, DENY_NONE, O_RDWR, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_RDONLY, DENY_FCB, A_0},
-{0, O_WRONLY, DENY_NONE, O_WRONLY, DENY_FCB, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDWR, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{0, O_RDWR, DENY_FCB, O_WRONLY, DENY_FCB, A_RW},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_RDONLY, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{0, O_RDONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{0, O_RDONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_RW},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_DOS, A_RW},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_DOS, A_R},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_DOS, A_W},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_ALL, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_WRITE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_READ, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_NONE, A_0},
-{0, O_WRONLY, DENY_FCB, O_RDWR, DENY_FCB, A_RW},
-{0, O_WRONLY, DENY_FCB, O_RDONLY, DENY_FCB, A_RW},
-{0, O_WRONLY, DENY_FCB, O_WRONLY, DENY_FCB, A_RW}
-};
-
-
-static void progress_bar(unsigned i, unsigned total)
-{
- if (i % 10 != 0) return;
- printf("%5d/%5d\r", i, total);
- fflush(stdout);
-}
-
-/*
- this produces a matrix of deny mode behaviour for 1 connection
- */
-BOOL torture_denytest1(int dummy)
-{
- struct cli_state *cli1;
- int fnum1, fnum2;
- int i;
- BOOL correct = True;
- const char *fnames[2] = {"\\denytest1.dat", "\\denytest1.exe"};
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- printf("starting denytest1\n");
-
- for (i=0;i<2;i++) {
- cli_unlink(cli1, fnames[i]);
- fnum1 = cli_open(cli1, fnames[i], O_RDWR|O_CREAT, DENY_NONE);
- cli_write(cli1, fnum1, 0, fnames[i], 0, strlen(fnames[i]));
- cli_close(cli1, fnum1);
- }
-
- printf("testing %ld entries\n", (unsigned long)ARRAY_SIZE(denytable1));
-
- for (i=0; i<ARRAY_SIZE(denytable1); i++) {
- enum deny_result res;
- const char *fname = fnames[denytable1[i].isexe];
-
- progress_bar(i, ARRAY_SIZE(denytable1));
-
- fnum1 = cli_open(cli1, fname,
- denytable1[i].mode1,
- denytable1[i].deny1);
- fnum2 = cli_open(cli1, fname,
- denytable1[i].mode2,
- denytable1[i].deny2);
-
- if (fnum1 == -1) {
- res = A_X;
- } else if (fnum2 == -1) {
- res = A_0;
- } else {
- char x = 1;
- res = A_0;
- if (cli_read(cli1, fnum2, (void *)&x, 0, 1) == 1) {
- res += A_R;
- }
- if (cli_write(cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
- res += A_W;
- }
- }
-
- if (res != denytable1[i].result) {
- correct = False;
- }
-
- if (torture_showall || res != denytable1[i].result) {
- printf("%s %8s %10s %8s %10s %s (correct=%s)\n",
- fname,
- denystr(denytable1[i].deny1),
- openstr(denytable1[i].mode1),
- denystr(denytable1[i].deny2),
- openstr(denytable1[i].mode2),
- resultstr(res),
- resultstr(denytable1[i].result));
- }
-
- cli_close(cli1, fnum1);
- cli_close(cli1, fnum2);
- }
-
- for (i=0;i<2;i++) {
- cli_unlink(cli1, fnames[i]);
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- printf("finshed denytest1\n");
- return correct;
-}
-
-
-/*
- this produces a matrix of deny mode behaviour with 2 connections
- */
-BOOL torture_denytest2(int dummy)
-{
- static struct cli_state *cli1, *cli2;
- int fnum1, fnum2;
- int i;
- BOOL correct = True;
- const char *fnames[2] = {"\\denytest2.dat", "\\denytest2.exe"};
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
-
- printf("starting denytest2\n");
-
- for (i=0;i<2;i++) {
- cli_unlink(cli1, fnames[i]);
- fnum1 = cli_open(cli1, fnames[i], O_RDWR|O_CREAT, DENY_NONE);
- cli_write(cli1, fnum1, 0, fnames[i], 0, strlen(fnames[i]));
- cli_close(cli1, fnum1);
- }
-
- for (i=0; i<ARRAY_SIZE(denytable2); i++) {
- enum deny_result res;
- const char *fname = fnames[denytable2[i].isexe];
-
- progress_bar(i, ARRAY_SIZE(denytable1));
-
- fnum1 = cli_open(cli1, fname,
- denytable2[i].mode1,
- denytable2[i].deny1);
- fnum2 = cli_open(cli2, fname,
- denytable2[i].mode2,
- denytable2[i].deny2);
-
- if (fnum1 == -1) {
- res = A_X;
- } else if (fnum2 == -1) {
- res = A_0;
- } else {
- char x = 1;
- res = A_0;
- if (cli_read(cli2, fnum2, (void *)&x, 0, 1) == 1) {
- res += A_R;
- }
- if (cli_write(cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
- res += A_W;
- }
- }
-
- if (res != denytable2[i].result) {
- correct = False;
- }
-
- if (torture_showall || res != denytable2[i].result) {
- printf("%s %8s %10s %8s %10s %s (correct=%s)\n",
- fname,
- denystr(denytable2[i].deny1),
- openstr(denytable2[i].mode1),
- denystr(denytable2[i].deny2),
- openstr(denytable2[i].mode2),
- resultstr(res),
- resultstr(denytable2[i].result));
- }
-
- cli_close(cli1, fnum1);
- cli_close(cli2, fnum2);
- }
-
- for (i=0;i<2;i++) {
- cli_unlink(cli1, fnames[i]);
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- if (!torture_close_connection(cli2)) {
- correct = False;
- }
-
- printf("finshed denytest2\n");
- return correct;
-}
-
diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c
deleted file mode 100644
index f31621b23b7..00000000000
--- a/source/torture/mangle_test.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester - mangling test
- Copyright (C) Andrew Tridgell 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static TDB_CONTEXT *tdb;
-
-#define NAME_LENGTH 20
-
-static unsigned total, collisions, failures;
-
-static BOOL test_one(struct cli_state *cli, const char *name)
-{
- int fnum;
- fstring shortname;
- fstring name2;
- NTSTATUS status;
- TDB_DATA data;
-
- total++;
-
- fnum = cli_open(cli, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum == -1) {
- printf("open of %s failed (%s)\n", name, cli_errstr(cli));
- return False;
- }
-
- if (!cli_close(cli, fnum)) {
- printf("close of %s failed (%s)\n", name, cli_errstr(cli));
- return False;
- }
-
- /* get the short name */
- status = cli_qpathinfo_alt_name(cli, name, shortname);
- if (!NT_STATUS_IS_OK(status)) {
- printf("query altname of %s failed (%s)\n", name, cli_errstr(cli));
- return False;
- }
-
- fstr_sprintf(name2, "\\mangle_test\\%s", shortname);
- if (!cli_unlink(cli, name2)) {
- printf("unlink of %s (%s) failed (%s)\n",
- name2, name, cli_errstr(cli));
- return False;
- }
-
- /* recreate by short name */
- fnum = cli_open(cli, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum == -1) {
- printf("open2 of %s failed (%s)\n", name2, cli_errstr(cli));
- return False;
- }
- if (!cli_close(cli, fnum)) {
- printf("close of %s failed (%s)\n", name, cli_errstr(cli));
- return False;
- }
-
- /* and unlink by long name */
- if (!cli_unlink(cli, name)) {
- printf("unlink2 of %s (%s) failed (%s)\n",
- name, name2, cli_errstr(cli));
- failures++;
- cli_unlink(cli, name2);
- return True;
- }
-
- /* see if the short name is already in the tdb */
- data = tdb_fetch_bystring(tdb, shortname);
- if (data.dptr) {
- /* maybe its a duplicate long name? */
- if (!strequal(name, data.dptr)) {
- /* we have a collision */
- collisions++;
- printf("Collision between %s and %s -> %s "
- " (coll/tot: %u/%u)\n",
- name, data.dptr, shortname, collisions, total);
- }
- free(data.dptr);
- } else {
- TDB_DATA namedata;
- /* store it for later */
- namedata.dptr = name;
- namedata.dsize = strlen(name)+1;
- tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
- }
-
- return True;
-}
-
-
-static void gen_name(char *name)
-{
- const char *chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._-$~... ";
- unsigned max_idx = strlen(chars);
- unsigned len;
- int i;
- char *p;
-
- fstrcpy(name, "\\mangle_test\\");
- p = name + strlen(name);
-
- len = 1 + random() % NAME_LENGTH;
-
- for (i=0;i<len;i++) {
- p[i] = chars[random() % max_idx];
- }
-
- p[i] = 0;
-
- if (strcmp(p, ".") == 0 || strcmp(p, "..") == 0) {
- p[0] = '_';
- }
-
- /* have a high probability of a common lead char */
- if (random() % 2 == 0) {
- p[0] = 'A';
- }
-
- /* and a medium probability of a common lead string */
- if (random() % 10 == 0) {
- if (strlen(p) <= 5) {
- fstrcpy(p, "ABCDE");
- } else {
- /* try not to kill off the null termination */
- memcpy(p, "ABCDE", 5);
- }
- }
-
- /* and a high probability of a good extension length */
- if (random() % 2 == 0) {
- char *s = strrchr(p, '.');
- if (s) {
- s[4] = 0;
- }
- }
-}
-
-
-BOOL torture_mangle(int dummy)
-{
- extern int torture_numops;
- static struct cli_state *cli;
- int i;
- BOOL ret = True;
-
- printf("starting mangle test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- /* we will use an internal tdb to store the names we have used */
- tdb = tdb_open(NULL, 100000, TDB_INTERNAL, 0, 0);
- if (!tdb) {
- printf("ERROR: Failed to open tdb\n");
- return False;
- }
-
- cli_unlink(cli, "\\mangle_test\\*");
- cli_rmdir(cli, "\\mangle_test");
-
- if (!cli_mkdir(cli, "\\mangle_test")) {
- printf("ERROR: Failed to make directory\n");
- return False;
- }
-
- for (i=0;i<torture_numops;i++) {
- fstring name;
- ZERO_STRUCT(name);
-
- gen_name(name);
-
- if (!test_one(cli, name)) {
- ret = False;
- break;
- }
- if (total && total % 100 == 0) {
- printf("collisions %u/%u - %.2f%% (%u failures)\r",
- collisions, total, (100.0*collisions) / total, failures);
- }
- }
-
- cli_unlink(cli, "\\mangle_test\\*");
- if (!cli_rmdir(cli, "\\mangle_test")) {
- printf("ERROR: Failed to remove directory\n");
- return False;
- }
-
- printf("\nTotal collisions %u/%u - %.2f%% (%u failures)\n",
- collisions, total, (100.0*collisions) / total, failures);
-
- torture_close_connection(cli);
-
- printf("mangle test finished\n");
- return (ret && (failures == 0));
-}
diff --git a/source/torture/nbio.c b/source/torture/nbio.c
deleted file mode 100644
index 2e79584d23f..00000000000
--- a/source/torture/nbio.c
+++ /dev/null
@@ -1,318 +0,0 @@
-#define NBDEBUG 0
-
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester
- Copyright (C) Andrew Tridgell 1997-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-#define MAX_FILES 1000
-
-static char buf[70000];
-extern int line_count;
-extern int nbio_id;
-static int nprocs;
-
-static struct {
- int fd;
- int handle;
-} ftable[MAX_FILES];
-
-static struct {
- double bytes_in, bytes_out;
- int line;
- int done;
-} *children;
-
-double nbio_total(void)
-{
- int i;
- double total = 0;
- for (i=0;i<nprocs;i++) {
- total += children[i].bytes_out + children[i].bytes_in;
- }
- return total;
-}
-
-void nb_alarm(int ignore)
-{
- int i;
- int lines=0, num_clients=0;
- if (nbio_id != -1) return;
-
- for (i=0;i<nprocs;i++) {
- lines += children[i].line;
- if (!children[i].done) num_clients++;
- }
-
- printf("%4d %8d %.2f MB/sec\r", num_clients, lines/nprocs, 1.0e-6 * nbio_total() / end_timer());
-
- signal(SIGALRM, nb_alarm);
- alarm(1);
-}
-
-void nbio_shmem(int n)
-{
- nprocs = n;
- children = shm_setup(sizeof(*children) * nprocs);
- if (!children) {
- printf("Failed to setup shared memory!\n");
- exit(1);
- }
-}
-
-#if 0
-static int ne_find_handle(int handle)
-{
- int i;
- children[nbio_id].line = line_count;
- for (i=0;i<MAX_FILES;i++) {
- if (ftable[i].handle == handle) return i;
- }
- return -1;
-}
-#endif
-
-static int find_handle(int handle)
-{
- int i;
- children[nbio_id].line = line_count;
- for (i=0;i<MAX_FILES;i++) {
- if (ftable[i].handle == handle) return i;
- }
- printf("(%d) ERROR: handle %d was not found\n",
- line_count, handle);
- exit(1);
-
- return -1; /* Not reached */
-}
-
-
-static struct cli_state *c;
-
-static void sigsegv(int sig)
-{
- char line[200];
- printf("segv at line %d\n", line_count);
- slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d",
- (int)getpid(), (int)getpid());
- system(line);
- exit(1);
-}
-
-void nb_setup(struct cli_state *cli)
-{
- signal(SIGSEGV, sigsegv);
- c = cli;
- start_timer();
- children[nbio_id].done = 0;
-}
-
-
-void nb_unlink(const char *fname)
-{
- if (!cli_unlink(c, fname)) {
-#if NBDEBUG
- printf("(%d) unlink %s failed (%s)\n",
- line_count, fname, cli_errstr(c));
-#endif
- }
-}
-
-
-void nb_createx(const char *fname,
- unsigned create_options, unsigned create_disposition, int handle)
-{
- int fd, i;
- uint32 desired_access;
-
- if (create_options & FILE_DIRECTORY_FILE) {
- desired_access = FILE_READ_DATA;
- } else {
- desired_access = FILE_READ_DATA | FILE_WRITE_DATA;
- }
-
- fd = cli_nt_create_full(c, fname, 0,
- desired_access,
- 0x0,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- create_disposition,
- create_options, 0);
- if (fd == -1 && handle != -1) {
- printf("ERROR: cli_nt_create_full failed for %s - %s\n",
- fname, cli_errstr(c));
- exit(1);
- }
- if (fd != -1 && handle == -1) {
- printf("ERROR: cli_nt_create_full succeeded for %s\n", fname);
- exit(1);
- }
- if (fd == -1) return;
-
- for (i=0;i<MAX_FILES;i++) {
- if (ftable[i].handle == 0) break;
- }
- if (i == MAX_FILES) {
- printf("(%d) file table full for %s\n", line_count,
- fname);
- exit(1);
- }
- ftable[i].handle = handle;
- ftable[i].fd = fd;
-}
-
-void nb_writex(int handle, int offset, int size, int ret_size)
-{
- int i;
-
- if (buf[0] == 0) memset(buf, 1, sizeof(buf));
-
- i = find_handle(handle);
- if (cli_write(c, ftable[i].fd, 0, buf, offset, size) != ret_size) {
- printf("(%d) ERROR: write failed on handle %d, fd %d \
-errno %d (%s)\n", line_count, handle, ftable[i].fd, errno, strerror(errno));
- exit(1);
- }
-
- children[nbio_id].bytes_out += ret_size;
-}
-
-void nb_readx(int handle, int offset, int size, int ret_size)
-{
- int i, ret;
-
- i = find_handle(handle);
- if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != ret_size) {
- printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s)\n",
- line_count, handle, offset, size, ret, ftable[i].fd, errno, strerror(errno));
- exit(1);
- }
- children[nbio_id].bytes_in += ret_size;
-}
-
-void nb_close(int handle)
-{
- int i;
- i = find_handle(handle);
- if (!cli_close(c, ftable[i].fd)) {
- printf("(%d) close failed on handle %d\n", line_count, handle);
- exit(1);
- }
- ftable[i].handle = 0;
-}
-
-void nb_rmdir(const char *fname)
-{
- if (!cli_rmdir(c, fname)) {
- printf("ERROR: rmdir %s failed (%s)\n",
- fname, cli_errstr(c));
- exit(1);
- }
-}
-
-void nb_rename(const char *old, const char *new)
-{
- if (!cli_rename(c, old, new)) {
- printf("ERROR: rename %s %s failed (%s)\n",
- old, new, cli_errstr(c));
- exit(1);
- }
-}
-
-
-void nb_qpathinfo(const char *fname)
-{
- cli_qpathinfo(c, fname, NULL, NULL, NULL, NULL, NULL);
-}
-
-void nb_qfileinfo(int fnum)
-{
- int i;
- i = find_handle(fnum);
- cli_qfileinfo(c, ftable[i].fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-void nb_qfsinfo(int level)
-{
- int bsize, total, avail;
- /* this is not the right call - we need cli_qfsinfo() */
- cli_dskattr(c, &bsize, &total, &avail);
-}
-
-static void find_fn(file_info *finfo, const char *name, void *state)
-{
- /* noop */
-}
-
-void nb_findfirst(const char *mask)
-{
- cli_list(c, mask, 0, find_fn, NULL);
-}
-
-void nb_flush(int fnum)
-{
- int i;
- i = find_handle(fnum);
- /* hmmm, we don't have cli_flush() yet */
-}
-
-static int total_deleted;
-
-static void delete_fn(file_info *finfo, const char *name, void *state)
-{
- char *s, *n;
- if (finfo->name[0] == '.') return;
-
- n = strdup(name);
- n[strlen(n)-1] = 0;
- asprintf(&s, "%s%s", n, finfo->name);
- if (finfo->mode & aDIR) {
- char *s2;
- asprintf(&s2, "%s\\*", s);
- cli_list(c, s2, aDIR, delete_fn, NULL);
- nb_rmdir(s);
- } else {
- total_deleted++;
- nb_unlink(s);
- }
- free(s);
- free(n);
-}
-
-void nb_deltree(const char *dname)
-{
- char *mask;
- asprintf(&mask, "%s\\*", dname);
-
- total_deleted = 0;
- cli_list(c, mask, aDIR, delete_fn, NULL);
- free(mask);
- cli_rmdir(c, dname);
-
- if (total_deleted) printf("WARNING: Cleaned up %d files\n", total_deleted);
-}
-
-
-void nb_cleanup(void)
-{
- cli_rmdir(c, "clients");
- children[nbio_id].done = 1;
-}
diff --git a/source/torture/nsstest.c b/source/torture/nsstest.c
deleted file mode 100644
index a803cd7e719..00000000000
--- a/source/torture/nsstest.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- nss tester for winbindd
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Tim Potter 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static const char *so_path = "/lib/libnss_winbind.so";
-static const char *nss_name = "winbind";
-static int nss_errno;
-static NSS_STATUS last_error;
-static int total_errors;
-
-static void *find_fn(const char *name)
-{
- pstring s;
- static void *h;
- void *res;
-
- pstr_sprintf(s, "_nss_%s_%s", nss_name, name);
-
- if (!h) {
- h = sys_dlopen(so_path, RTLD_LAZY);
- }
- if (!h) {
- printf("Can't open shared library %s\n", so_path);
- exit(1);
- }
- res = sys_dlsym(h, s);
- if (!res) {
- printf("Can't find function %s\n", s);
- total_errors++;
- return NULL;
- }
- return res;
-}
-
-static void report_nss_error(const char *who, NSS_STATUS status)
-{
- last_error = status;
- total_errors++;
- printf("ERROR %s: NSS_STATUS=%d %d (nss_errno=%d)\n",
- who, status, NSS_STATUS_SUCCESS, nss_errno);
-}
-
-static struct passwd *nss_getpwent(void)
-{
- NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *,
- size_t , int *) = find_fn("getpwent_r");
- static struct passwd pwd;
- static char buf[1000];
- NSS_STATUS status;
-
- if (!_nss_getpwent_r)
- return NULL;
-
- status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getpwent", status);
- return NULL;
- }
- return &pwd;
-}
-
-static struct passwd *nss_getpwnam(const char *name)
-{
- NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *,
- size_t , int *) = find_fn("getpwnam_r");
- static struct passwd pwd;
- static char buf[1000];
- NSS_STATUS status;
-
- if (!_nss_getpwnam_r)
- return NULL;
-
- status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getpwnam", status);
- return NULL;
- }
- return &pwd;
-}
-
-static struct passwd *nss_getpwuid(uid_t uid)
-{
- NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *,
- size_t , int *) = find_fn("getpwuid_r");
- static struct passwd pwd;
- static char buf[1000];
- NSS_STATUS status;
-
- if (!_nss_getpwuid_r)
- return NULL;
-
- status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getpwuid", status);
- return NULL;
- }
- return &pwd;
-}
-
-static void nss_setpwent(void)
-{
- NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent");
- NSS_STATUS status;
-
- if (!_nss_setpwent)
- return;
-
- status = _nss_setpwent();
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("setpwent", status);
- }
-}
-
-static void nss_endpwent(void)
-{
- NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent");
- NSS_STATUS status;
-
- if (!_nss_endpwent)
- return;
-
- status = _nss_endpwent();
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("endpwent", status);
- }
-}
-
-
-static struct group *nss_getgrent(void)
-{
- NSS_STATUS (*_nss_getgrent_r)(struct group *, char *,
- size_t , int *) = find_fn("getgrent_r");
- static struct group grp;
- static char *buf;
- static int buflen = 1024;
- NSS_STATUS status;
-
- if (!_nss_getgrent_r)
- return NULL;
-
- if (!buf)
- buf = malloc(buflen);
-
-again:
- status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
- if (status == NSS_STATUS_TRYAGAIN) {
- buflen *= 2;
- buf = realloc(buf, buflen);
- goto again;
- }
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getgrent", status);
- return NULL;
- }
- return &grp;
-}
-
-static struct group *nss_getgrnam(const char *name)
-{
- NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *,
- size_t , int *) = find_fn("getgrnam_r");
- static struct group grp;
- static char *buf;
- static int buflen = 1000;
- NSS_STATUS status;
-
- if (!_nss_getgrnam_r)
- return NULL;
-
- if (!buf)
- buf = malloc(buflen);
-again:
- status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
- if (status == NSS_STATUS_TRYAGAIN) {
- buflen *= 2;
- buf = realloc(buf, buflen);
- goto again;
- }
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getgrnam", status);
- return NULL;
- }
- return &grp;
-}
-
-static struct group *nss_getgrgid(gid_t gid)
-{
- NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *,
- size_t , int *) = find_fn("getgrgid_r");
- static struct group grp;
- static char *buf;
- static int buflen = 1000;
- NSS_STATUS status;
-
- if (!_nss_getgrgid_r)
- return NULL;
-
- if (!buf)
- buf = malloc(buflen);
-
-again:
- status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
- if (status == NSS_STATUS_TRYAGAIN) {
- buflen *= 2;
- buf = realloc(buf, buflen);
- goto again;
- }
- if (status == NSS_STATUS_NOTFOUND) {
- return NULL;
- }
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("getgrgid", status);
- return NULL;
- }
- return &grp;
-}
-
-static void nss_setgrent(void)
-{
- NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent");
- NSS_STATUS status;
-
- if (!_nss_setgrent)
- return;
-
- status = _nss_setgrent();
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("setgrent", status);
- }
-}
-
-static void nss_endgrent(void)
-{
- NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent");
- NSS_STATUS status;
-
- if (!_nss_endgrent)
- return;
-
- status = _nss_endgrent();
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("endgrent", status);
- }
-}
-
-static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *start, long int *size)
-{
- NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
- long int *, gid_t **, long int , int *) =
- find_fn("initgroups_dyn");
- NSS_STATUS status;
-
- if (!_nss_initgroups)
- return NSS_STATUS_UNAVAIL;
-
- status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
- if (status != NSS_STATUS_SUCCESS) {
- report_nss_error("initgroups", status);
- }
- return status;
-}
-
-static void print_passwd(struct passwd *pwd)
-{
- printf("%s:%s:%lu:%lu:%s:%s:%s\n",
- pwd->pw_name,
- pwd->pw_passwd,
- (unsigned long)pwd->pw_uid,
- (unsigned long)pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- pwd->pw_shell);
-}
-
-static void print_group(struct group *grp)
-{
- int i;
- printf("%s:%s:%lu: ",
- grp->gr_name,
- grp->gr_passwd,
- (unsigned long)grp->gr_gid);
-
- if (!grp->gr_mem[0]) {
- printf("\n");
- return;
- }
-
- for (i=0; grp->gr_mem[i+1]; i++) {
- printf("%s, ", grp->gr_mem[i]);
- }
- printf("%s\n", grp->gr_mem[i]);
-}
-
-static void nss_test_initgroups(char *name, gid_t gid)
-{
- long int size = 16;
- long int start = 1;
- gid_t *groups = NULL;
- int i;
- NSS_STATUS status;
-
- groups = (gid_t *)malloc(size * sizeof(gid_t));
- groups[0] = gid;
-
- status = nss_initgroups(name, gid, &groups, &start, &size);
- if (status == NSS_STATUS_UNAVAIL) {
- printf("No initgroups fn\n");
- return;
- }
-
- for (i=0; i<start-1; i++) {
- printf("%lu, ", (unsigned long)groups[i]);
- }
- printf("%lu\n", (unsigned long)groups[i]);
-}
-
-
-static void nss_test_users(void)
-{
- struct passwd *pwd;
-
- nss_setpwent();
- /* loop over all users */
- while ((pwd = nss_getpwent())) {
- printf("Testing user %s\n", pwd->pw_name);
- printf("getpwent: "); print_passwd(pwd);
- pwd = nss_getpwuid(pwd->pw_uid);
- if (!pwd) {
- total_errors++;
- printf("ERROR: can't getpwuid\n");
- continue;
- }
- printf("getpwuid: "); print_passwd(pwd);
- pwd = nss_getpwnam(pwd->pw_name);
- if (!pwd) {
- total_errors++;
- printf("ERROR: can't getpwnam\n");
- continue;
- }
- printf("getpwnam: "); print_passwd(pwd);
- printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
- printf("\n");
- }
- nss_endpwent();
-}
-
-static void nss_test_groups(void)
-{
- struct group *grp;
-
- nss_setgrent();
- /* loop over all groups */
- while ((grp = nss_getgrent())) {
- printf("Testing group %s\n", grp->gr_name);
- printf("getgrent: "); print_group(grp);
- grp = nss_getgrnam(grp->gr_name);
- if (!grp) {
- total_errors++;
- printf("ERROR: can't getgrnam\n");
- continue;
- }
- printf("getgrnam: "); print_group(grp);
- grp = nss_getgrgid(grp->gr_gid);
- if (!grp) {
- total_errors++;
- printf("ERROR: can't getgrgid\n");
- continue;
- }
- printf("getgrgid: "); print_group(grp);
- printf("\n");
- }
- nss_endgrent();
-}
-
-static void nss_test_errors(void)
-{
- struct passwd *pwd;
- struct group *grp;
-
- pwd = getpwnam("nosuchname");
- if (pwd || last_error != NSS_STATUS_NOTFOUND) {
- total_errors++;
- printf("ERROR Non existant user gave error %d\n", last_error);
- }
-
- pwd = getpwuid(0xFFF0);
- if (pwd || last_error != NSS_STATUS_NOTFOUND) {
- total_errors++;
- printf("ERROR Non existant uid gave error %d\n", last_error);
- }
-
- grp = getgrnam("nosuchgroup");
- if (grp || last_error != NSS_STATUS_NOTFOUND) {
- total_errors++;
- printf("ERROR Non existant group gave error %d\n", last_error);
- }
-
- grp = getgrgid(0xFFF0);
- if (grp || last_error != NSS_STATUS_NOTFOUND) {
- total_errors++;
- printf("ERROR Non existant gid gave error %d\n", last_error);
- }
-}
-
- int main(int argc, char *argv[])
-{
- if (argc > 1) so_path = argv[1];
- if (argc > 2) nss_name = argv[2];
-
- nss_test_users();
- nss_test_groups();
- nss_test_errors();
-
- printf("total_errors=%d\n", total_errors);
-
- return total_errors;
-}
diff --git a/source/torture/samtest.h b/source/torture/samtest.h
deleted file mode 100644
index a136ab191e4..00000000000
--- a/source/torture/samtest.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SAM module tester
-
- Copyright (C) Jelmer Vernooij 2002
-
- Most of this code was ripped off of rpcclient.
- Copyright (C) Tim Potter 2000-2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-struct samtest_state {
- SAM_CONTEXT *context;
- NT_USER_TOKEN *token;
-};
-
-struct cmd_set {
- char *name;
- NTSTATUS (*fn)(struct samtest_state *sam, TALLOC_CTX *mem_ctx, int argc,
- char **argv);
- char *description;
- char *usage;
-};
-
-
diff --git a/source/torture/scanner.c b/source/torture/scanner.c
deleted file mode 100644
index 93f89c105cf..00000000000
--- a/source/torture/scanner.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester - scanning functions
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-#define VERBOSE 0
-#define OP_MIN 0
-#define OP_MAX 20
-
-/****************************************************************************
-look for a partial hit
-****************************************************************************/
-static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
-{
- if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
- return;
- }
-#if VERBOSE
- printf("possible %s hit op=%3d level=%5d status=%s\n",
- format, op, level, nt_errstr(status));
-#endif
-}
-
-/****************************************************************************
-check for existance of a trans2 call
-****************************************************************************/
-static NTSTATUS try_trans2(struct cli_state *cli,
- int op,
- char *param, char *data,
- int param_len, int data_len,
- int *rparam_len, int *rdata_len)
-{
- uint16 setup = op;
- char *rparam=NULL, *rdata=NULL;
-
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- data, data_len, cli->max_xmit /* data, length, max */
- )) {
- return cli_nt_error(cli);
- }
-
- cli_receive_trans(cli, SMBtrans2,
- &rparam, rparam_len,
- &rdata, rdata_len);
-
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
-
- return cli_nt_error(cli);
-}
-
-
-static NTSTATUS try_trans2_len(struct cli_state *cli,
- const char *format,
- int op, int level,
- char *param, char *data,
- int param_len, int *data_len,
- int *rparam_len, int *rdata_len)
-{
- NTSTATUS ret=NT_STATUS_OK;
-
- ret = try_trans2(cli, op, param, data, param_len,
- sizeof(pstring), rparam_len, rdata_len);
-#if VERBOSE
- printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
-#endif
- if (!NT_STATUS_IS_OK(ret)) return ret;
-
- *data_len = 0;
- while (*data_len < sizeof(pstring)) {
- ret = try_trans2(cli, op, param, data, param_len,
- *data_len, rparam_len, rdata_len);
- if (NT_STATUS_IS_OK(ret)) break;
- *data_len += 2;
- }
- if (NT_STATUS_IS_OK(ret)) {
- printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
- format, level, *data_len, *rparam_len, *rdata_len);
- } else {
- trans2_check_hit(format, op, level, ret);
- }
- return ret;
-}
-
-/****************************************************************************
-check for existance of a trans2 call
-****************************************************************************/
-static BOOL scan_trans2(struct cli_state *cli, int op, int level,
- int fnum, int dnum, const char *fname)
-{
- int data_len = 0;
- int param_len = 0;
- int rparam_len, rdata_len;
- pstring param, data;
- NTSTATUS status;
-
- memset(data, 0, sizeof(data));
- data_len = 4;
-
- /* try with a info level only */
- param_len = 2;
- SSVAL(param, 0, level);
- status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a file descriptor */
- param_len = 6;
- SSVAL(param, 0, fnum);
- SSVAL(param, 2, level);
- SSVAL(param, 4, 0);
- status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
-
- /* try with a notify style */
- param_len = 6;
- SSVAL(param, 0, dnum);
- SSVAL(param, 2, dnum);
- SSVAL(param, 4, level);
- status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a file name */
- param_len = 6;
- SSVAL(param, 0, level);
- SSVAL(param, 2, 0);
- SSVAL(param, 4, 0);
- param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
-
- status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a new file name */
- param_len = 6;
- SSVAL(param, 0, level);
- SSVAL(param, 2, 0);
- SSVAL(param, 4, 0);
- param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
-
- status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- cli_unlink(cli, "\\newfile.dat");
- cli_rmdir(cli, "\\newfile.dat");
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try dfs style */
- cli_mkdir(cli, "\\testdir");
- param_len = 2;
- SSVAL(param, 0, level);
- param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
-
- status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- cli_rmdir(cli, "\\testdir");
- if (NT_STATUS_IS_OK(status)) return True;
-
- return False;
-}
-
-
-BOOL torture_trans2_scan(int dummy)
-{
- static struct cli_state *cli;
- int op, level;
- const char *fname = "\\scanner.dat";
- int fnum, dnum;
-
- printf("starting trans2 scan test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
- DENY_NONE);
- dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
-
- for (op=OP_MIN; op<=OP_MAX; op++) {
- printf("Scanning op=%d\n", op);
- for (level = 0; level <= 50; level++) {
- scan_trans2(cli, op, level, fnum, dnum, fname);
- }
-
- for (level = 0x100; level <= 0x130; level++) {
- scan_trans2(cli, op, level, fnum, dnum, fname);
- }
-
- for (level = 1000; level < 1050; level++) {
- scan_trans2(cli, op, level, fnum, dnum, fname);
- }
- }
-
- torture_close_connection(cli);
-
- printf("trans2 scan finished\n");
- return True;
-}
-
-
-
-
-/****************************************************************************
-look for a partial hit
-****************************************************************************/
-static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
-{
- if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
- NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
- return;
- }
-#if VERBOSE
- printf("possible %s hit op=%3d level=%5d status=%s\n",
- format, op, level, nt_errstr(status));
-#endif
-}
-
-/****************************************************************************
-check for existance of a nttrans call
-****************************************************************************/
-static NTSTATUS try_nttrans(struct cli_state *cli,
- int op,
- char *param, char *data,
- int param_len, int data_len,
- int *rparam_len, int *rdata_len)
-{
- char *rparam=NULL, *rdata=NULL;
-
- if (!cli_send_nt_trans(cli, op,
- 0,
- NULL, 0, 0,
- param, param_len, 2, /* param, length, max */
- data, data_len, cli->max_xmit /* data, length, max */
- )) {
- return cli_nt_error(cli);
- }
-
- cli_receive_nt_trans(cli,
- &rparam, rparam_len,
- &rdata, rdata_len);
-
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
-
- return cli_nt_error(cli);
-}
-
-
-static NTSTATUS try_nttrans_len(struct cli_state *cli,
- const char *format,
- int op, int level,
- char *param, char *data,
- int param_len, int *data_len,
- int *rparam_len, int *rdata_len)
-{
- NTSTATUS ret=NT_STATUS_OK;
-
- ret = try_nttrans(cli, op, param, data, param_len,
- sizeof(pstring), rparam_len, rdata_len);
-#if VERBOSE
- printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
-#endif
- if (!NT_STATUS_IS_OK(ret)) return ret;
-
- *data_len = 0;
- while (*data_len < sizeof(pstring)) {
- ret = try_nttrans(cli, op, param, data, param_len,
- *data_len, rparam_len, rdata_len);
- if (NT_STATUS_IS_OK(ret)) break;
- *data_len += 2;
- }
- if (NT_STATUS_IS_OK(ret)) {
- printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
- format, level, *data_len, *rparam_len, *rdata_len);
- } else {
- nttrans_check_hit(format, op, level, ret);
- }
- return ret;
-}
-
-/****************************************************************************
-check for existance of a nttrans call
-****************************************************************************/
-static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
- int fnum, int dnum, const char *fname)
-{
- int data_len = 0;
- int param_len = 0;
- int rparam_len, rdata_len;
- pstring param, data;
- NTSTATUS status;
-
- memset(data, 0, sizeof(data));
- data_len = 4;
-
- /* try with a info level only */
- param_len = 2;
- SSVAL(param, 0, level);
- status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a file descriptor */
- param_len = 6;
- SSVAL(param, 0, fnum);
- SSVAL(param, 2, level);
- SSVAL(param, 4, 0);
- status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
-
- /* try with a notify style */
- param_len = 6;
- SSVAL(param, 0, dnum);
- SSVAL(param, 2, dnum);
- SSVAL(param, 4, level);
- status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a file name */
- param_len = 6;
- SSVAL(param, 0, level);
- SSVAL(param, 2, 0);
- SSVAL(param, 4, 0);
- param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
-
- status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try with a new file name */
- param_len = 6;
- SSVAL(param, 0, level);
- SSVAL(param, 2, 0);
- SSVAL(param, 4, 0);
- param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
-
- status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- cli_unlink(cli, "\\newfile.dat");
- cli_rmdir(cli, "\\newfile.dat");
- if (NT_STATUS_IS_OK(status)) return True;
-
- /* try dfs style */
- cli_mkdir(cli, "\\testdir");
- param_len = 2;
- SSVAL(param, 0, level);
- param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
-
- status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
- &rparam_len, &rdata_len);
- cli_rmdir(cli, "\\testdir");
- if (NT_STATUS_IS_OK(status)) return True;
-
- return False;
-}
-
-
-BOOL torture_nttrans_scan(int dummy)
-{
- static struct cli_state *cli;
- int op, level;
- const char *fname = "\\scanner.dat";
- int fnum, dnum;
-
- printf("starting nttrans scan test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
- DENY_NONE);
- dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
-
- for (op=OP_MIN; op<=OP_MAX; op++) {
- printf("Scanning op=%d\n", op);
- for (level = 0; level <= 50; level++) {
- scan_nttrans(cli, op, level, fnum, dnum, fname);
- }
-
- for (level = 0x100; level <= 0x130; level++) {
- scan_nttrans(cli, op, level, fnum, dnum, fname);
- }
-
- for (level = 1000; level < 1050; level++) {
- scan_nttrans(cli, op, level, fnum, dnum, fname);
- }
- }
-
- torture_close_connection(cli);
-
- printf("nttrans scan finished\n");
- return True;
-}
diff --git a/source/torture/smbiconv.c b/source/torture/smbiconv.c
deleted file mode 100644
index 1dd168b0bb0..00000000000
--- a/source/torture/smbiconv.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Charset module tester
-
- Copyright (C) Jelmer Vernooij 2003
- Based on iconv/icon_prog.c from the GNU C Library,
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static int
-process_block (smb_iconv_t cd, const char *addr, size_t len, FILE *output)
-{
-#define OUTBUF_SIZE 32768
- const char *start = addr;
- char outbuf[OUTBUF_SIZE];
- char *outptr;
- size_t outlen;
- size_t n;
-
- while (len > 0)
- {
- outptr = outbuf;
- outlen = OUTBUF_SIZE;
- n = smb_iconv (cd, &addr, &len, &outptr, &outlen);
-
- if (outptr != outbuf)
- {
- /* We have something to write out. */
- int errno_save = errno;
-
- if (fwrite (outbuf, 1, outptr - outbuf, output)
- < (size_t) (outptr - outbuf)
- || ferror (output))
- {
- /* Error occurred while printing the result. */
- DEBUG (0, ("conversion stopped due to problem in writing the output"));
- return -1;
- }
-
- errno = errno_save;
- }
-
- if (errno != E2BIG)
- {
- /* iconv() ran into a problem. */
- switch (errno)
- {
- case EILSEQ:
- DEBUG(0,("illegal input sequence at position %ld",
- (long) (addr - start)));
- break;
- case EINVAL:
- DEBUG(0, ("\
-incomplete character or shift sequence at end of buffer"));
- break;
- case EBADF:
- DEBUG(0, ("internal error (illegal descriptor)"));
- break;
- default:
- DEBUG(0, ("unknown iconv() error %d", errno));
- break;
- }
-
- return -1;
- }
- }
-
- return 0;
-}
-
-
-static int
-process_fd (iconv_t cd, int fd, FILE *output)
-{
- /* we have a problem with reading from a descriptor since we must not
- provide the iconv() function an incomplete character or shift
- sequence at the end of the buffer. Since we have to deal with
- arbitrary encodings we must read the whole text in a buffer and
- process it in one step. */
- static char *inbuf = NULL;
- static size_t maxlen = 0;
- char *inptr = NULL;
- size_t actlen = 0;
-
- while (actlen < maxlen)
- {
- ssize_t n = read (fd, inptr, maxlen - actlen);
-
- if (n == 0)
- /* No more text to read. */
- break;
-
- if (n == -1)
- {
- /* Error while reading. */
- DEBUG(0, ("error while reading the input"));
- return -1;
- }
-
- inptr += n;
- actlen += n;
- }
-
- if (actlen == maxlen)
- while (1)
- {
- ssize_t n;
- char *new_inbuf;
-
- /* Increase the buffer. */
- new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
- if (new_inbuf == NULL)
- {
- DEBUG(0, ("unable to allocate buffer for input"));
- return -1;
- }
- inbuf = new_inbuf;
- maxlen += 32768;
- inptr = inbuf + actlen;
-
- do
- {
- n = read (fd, inptr, maxlen - actlen);
-
- if (n == 0)
- /* No more text to read. */
- break;
-
- if (n == -1)
- {
- /* Error while reading. */
- DEBUG(0, ("error while reading the input"));
- return -1;
- }
-
- inptr += n;
- actlen += n;
- }
- while (actlen < maxlen);
-
- if (n == 0)
- /* Break again so we leave both loops. */
- break;
- }
-
- /* Now we have all the input in the buffer. Process it in one run. */
- return process_block (cd, inbuf, actlen, output);
-}
-
-/* Main function */
-
-int main(int argc, char *argv[])
-{
- const char *file = NULL;
- char *from = "";
- char *to = "";
- char *output = NULL;
- const char *preload_modules[] = {NULL, NULL};
- FILE *out = stdout;
- int fd;
- smb_iconv_t cd;
-
- /* make sure the vars that get altered (4th field) are in
- a fixed location or certain compilers complain */
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "from-code", 'f', POPT_ARG_STRING, &from, 0, "Encoding of original text" },
- { "to-code", 't', POPT_ARG_STRING, &to, 0, "Encoding for output" },
- { "output", 'o', POPT_ARG_STRING, &output, 0, "Write output to this file" },
- { "preload-modules", 'p', POPT_ARG_STRING, &preload_modules[0], 0, "Modules to load" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
-
- setlinebuf(stdout);
-
- pc = poptGetContext("smbiconv", argc, (const char **) argv,
- long_options, 0);
-
- poptSetOtherOptionHelp(pc, "[FILE] ...");
-
- while(poptGetNextOpt(pc) != -1);
-
- /* the following functions are part of the Samba debugging
- facilities. See lib/debug.c */
- setup_logging("smbiconv", True);
-
- if (preload_modules[0]) smb_load_modules(preload_modules);
-
- if(output) {
- out = fopen(output, "w");
-
- if(!out) {
- DEBUG(0, ("Can't open output file '%s': %s, exiting...\n", output, strerror(errno)));
- return 1;
- }
- }
-
- cd = smb_iconv_open(to, from);
- if((int)cd == -1) {
- DEBUG(0,("unable to find from or to encoding, exiting...\n"));
- return 1;
- }
-
- while((file = poptGetArg(pc))) {
- if(strcmp(file, "-") == 0) fd = 0;
- else {
- fd = open(file, O_RDONLY);
-
- if(!fd) {
- DEBUG(0, ("Can't open input file '%s': %s, ignoring...\n", file, strerror(errno)));
- continue;
- }
- }
-
- /* Loop thru all arguments */
- process_fd(cd, fd, out);
-
- close(fd);
- }
- poptFreeContext(pc);
-
- fclose(out);
-
- return 0;
-}
diff --git a/source/torture/t_doschar.c b/source/torture/t_doschar.c
deleted file mode 100644
index 41698350d6e..00000000000
--- a/source/torture/t_doschar.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Samba - Unix SMB/CIFS implementation
- Test harness for check_dos_char
- Copyright (C) Martin Pool 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-
-/*
- * Just print out DOS validity or not for every character.
- *
- * DOS validity for a Unicode character set means that it can be
- * represented in DOS codepage, and that the DOS character maps back
- * to the same Unicode character.
- *
- * This depends on which DOS codepage is configured.
- */
- int main(void)
-{
- smb_ucs2_t i;
-
- for (i = 0; i < 0xffff; i++) {
- printf("%d %d\n", (int) i, (int) check_dos_char(i));
- }
-
- return 0;
-}
diff --git a/source/torture/t_push_ucs2.c b/source/torture/t_push_ucs2.c
deleted file mode 100644
index 8bfc6f7ad9e..00000000000
--- a/source/torture/t_push_ucs2.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2003 by Martin Pool
- * Copyright (C) 2003 by Andrew Bartlett
- *
- * Test harness for push_ucs2
- */
-
-#include "includes.h"
-
-static int check_push_ucs2(const char *orig)
-{
- smb_ucs2_t *dest = NULL;
- char *orig2 = NULL;
- int ret;
-
- push_ucs2_allocate(&dest, orig);
- pull_ucs2_allocate(&orig2, dest);
- ret = strcmp(orig, orig2);
- if (ret) {
- fprintf(stderr, "orig: %s\n", orig);
- fprintf(stderr, "orig (UNIX -> UCS2 -> UNIX): %s\n", orig2);
- }
-
- SAFE_FREE(dest);
- SAFE_FREE(orig2);
-
- return ret;
-}
-
-int main(int argc, char *argv[])
-{
- int i, ret = 0;
- int count = 1;
-
- /* Needed to initialize character set */
- lp_load("/dev/null", True, False, False);
-
- if (argc < 2) {
- fprintf(stderr, "usage: %s STRING1 [COUNT]\n"
- "Checks that a string translated UNIX->UCS2->UNIX is unchanged\n"
- "Should be always 0\n",
- argv[0]);
- return 2;
- }
- if (argc >= 3)
- count = atoi(argv[2]);
-
- for (i = 0; ((i < count) && (!ret)); i++)
- ret = check_push_ucs2(argv[1]);
-
- printf("%d\n", ret);
-
- return 0;
-}
diff --git a/source/torture/t_strcmp.c b/source/torture/t_strcmp.c
deleted file mode 100644
index bc8640ee550..00000000000
--- a/source/torture/t_strcmp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2003 by Martin Pool
- *
- * Test harness for StrCaseCmp
- */
-
-#include "includes.h"
-
-int main(int argc, char *argv[])
-{
- int i, ret;
- int iters = 1;
-
- /* Needed to initialize character set */
- lp_load("/dev/null", True, False, False);
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n"
- "Compares two strings, prints the results of StrCaseCmp\n",
- argv[0]);
- return 2;
- }
- if (argc >= 4)
- iters = atoi(argv[3]);
-
- for (i = 0; i < iters; i++)
- ret = StrCaseCmp(argv[1], argv[2]);
-
- printf("%d\n", ret);
-
- return 0;
-}
diff --git a/source/torture/t_stringoverflow.c b/source/torture/t_stringoverflow.c
deleted file mode 100644
index ec14d81189e..00000000000
--- a/source/torture/t_stringoverflow.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "includes.h"
-
- int main(void)
-{
- fstring dest;
- char *ptr = dest;
-
- printf("running on valgrind? %d\n", RUNNING_ON_VALGRIND);
-
- /* Try copying a string into an fstring buffer. The string
- * will actually fit, but this is still wrong because you
- * can't pstrcpy into an fstring. This should trap in a
- * developer build. */
-
-#if 0
- /* As of CVS 20030318, this will be trapped at compile time! */
- pstrcpy(dest, "hello");
-#endif /* 0 */
-
- pstrcpy(ptr, "hello!");
-
- return 0;
-}
diff --git a/source/torture/t_strstr.c b/source/torture/t_strstr.c
deleted file mode 100644
index 25709526fe8..00000000000
--- a/source/torture/t_strstr.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2003 by Martin Pool
- *
- * Test harness for strstr_m
- */
-
-#include "includes.h"
-
-int main(int argc, char *argv[])
-{
- int i;
- int iters = 1;
-
- char *ret;
-
- /* Needed to initialize character set */
- lp_load("/dev/null", True, False, False);
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n"
- "Compares two strings, prints the results of strstr_m\n",
- argv[0]);
- return 2;
- }
- if (argc >= 4)
- iters = atoi(argv[3]);
-
- for (i = 0; i < iters; i++) {
- ret = strstr_m(argv[1], argv[2]);
- }
-
- printf("%s\n", ret);
-
- return 0;
-}
diff --git a/source/torture/torture.c b/source/torture/torture.c
deleted file mode 100644
index 161aa2cd73b..00000000000
--- a/source/torture/torture.c
+++ /dev/null
@@ -1,4994 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester
- Copyright (C) Andrew Tridgell 1997-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-static fstring host, workgroup, share, password, username, myname;
-static int max_protocol = PROTOCOL_NT1;
-static const char *sockops="TCP_NODELAY";
-static int nprocs=1;
-static int port_to_use=0;
-int torture_numops=100;
-static int procnum; /* records process count number when forking */
-static struct cli_state *current_cli;
-static fstring randomfname;
-static BOOL use_oplocks;
-static BOOL use_level_II_oplocks;
-static const char *client_txt = "client_oplocks.txt";
-static BOOL use_kerberos;
-
-BOOL torture_showall = False;
-
-static double create_procs(BOOL (*fn)(int), BOOL *result);
-
-
-static struct timeval tp1,tp2;
-
-void start_timer(void)
-{
- gettimeofday(&tp1,NULL);
-}
-
-double end_timer(void)
-{
- gettimeofday(&tp2,NULL);
- return((tp2.tv_sec - tp1.tv_sec) +
- (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
-}
-
-
-/* return a pointer to a anonymous shared memory segment of size "size"
- which will persist across fork() but will disappear when all processes
- exit
-
- The memory is not zeroed
-
- This function uses system5 shared memory. It takes advantage of a property
- that the memory is not destroyed if it is attached when the id is removed
- */
-void *shm_setup(int size)
-{
- int shmid;
- void *ret;
-
- shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
- if (shmid == -1) {
- printf("can't get shared memory\n");
- exit(1);
- }
- ret = (void *)shmat(shmid, 0, 0);
- if (!ret || ret == (void *)-1) {
- printf("can't attach to shared memory\n");
- return NULL;
- }
- /* the following releases the ipc, but note that this process
- and all its children will still have access to the memory, its
- just that the shmid is no longer valid for other shm calls. This
- means we don't leave behind lots of shm segments after we exit
-
- See Stevens "advanced programming in unix env" for details
- */
- shmctl(shmid, IPC_RMID, 0);
-
- return ret;
-}
-
-
-static BOOL open_nbt_connection(struct cli_state *c)
-{
- struct nmb_name called, calling;
- struct in_addr ip;
-
- ZERO_STRUCTP(c);
-
- make_nmb_name(&calling, myname, 0x0);
- make_nmb_name(&called , host, 0x20);
-
- zero_ip(&ip);
-
- if (!cli_initialise(c)) {
- printf("Failed initialize cli_struct to connect with %s\n", host);
- return False;
- }
-
- c->port = port_to_use;
-
- if (!cli_connect(c, host, &ip)) {
- printf("Failed to connect with %s\n", host);
- return False;
- }
-
- c->use_kerberos = use_kerberos;
-
- c->timeout = 120000; /* set a really long timeout (2 minutes) */
- if (use_oplocks) c->use_oplocks = True;
- if (use_level_II_oplocks) c->use_level_II_oplocks = True;
-
- if (!cli_session_request(c, &calling, &called)) {
- /*
- * Well, that failed, try *SMBSERVER ...
- * However, we must reconnect as well ...
- */
- if (!cli_connect(c, host, &ip)) {
- printf("Failed to connect with %s\n", host);
- return False;
- }
-
- make_nmb_name(&called, "*SMBSERVER", 0x20);
- if (!cli_session_request(c, &calling, &called)) {
- printf("%s rejected the session\n",host);
- printf("We tried with a called name of %s & %s\n",
- host, "*SMBSERVER");
- cli_shutdown(c);
- return False;
- }
- }
-
- return True;
-}
-
-BOOL torture_open_connection(struct cli_state **c)
-{
- BOOL retry;
- int flags = 0;
- NTSTATUS status;
-
- if (use_kerberos)
- flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
-
- status = cli_full_connection(c, myname,
- host, NULL, port_to_use,
- share, "?????",
- username, workgroup,
- password, flags, Undefined, &retry);
- if (!NT_STATUS_IS_OK(status)) {
- return False;
- }
-
- if (use_oplocks) (*c)->use_oplocks = True;
- if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
- (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
-
- return True;
-}
-
-BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
-{
- uint16 old_vuid = cli->vuid;
- fstring old_user_name;
- size_t passlen = strlen(password);
- BOOL ret;
-
- fstrcpy(old_user_name, cli->user_name);
- cli->vuid = 0;
- ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup);
- *new_vuid = cli->vuid;
- cli->vuid = old_vuid;
- fstrcpy(cli->user_name, old_user_name);
- return ret;
-}
-
-
-BOOL torture_close_connection(struct cli_state *c)
-{
- BOOL ret = True;
- if (!cli_tdis(c)) {
- printf("tdis failed (%s)\n", cli_errstr(c));
- ret = False;
- }
-
- cli_shutdown(c);
-
- return ret;
-}
-
-
-/* check if the server produced the expected error code */
-static BOOL check_error(int line, struct cli_state *c,
- uint8 eclass, uint32 ecode, NTSTATUS nterr)
-{
- if (cli_is_dos_error(c)) {
- uint8 class;
- uint32 num;
-
- /* Check DOS error */
-
- cli_dos_error(c, &class, &num);
-
- if (eclass != class || ecode != num) {
- printf("unexpected error code class=%d code=%d\n",
- (int)class, (int)num);
- printf(" expected %d/%d %s (line=%d)\n",
- (int)eclass, (int)ecode, nt_errstr(nterr), line);
- return False;
- }
-
- } else {
- NTSTATUS status;
-
- /* Check NT error */
-
- status = cli_nt_error(c);
-
- if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
- printf("unexpected error code %s\n", nt_errstr(status));
- printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
- return False;
- }
- }
-
- return True;
-}
-
-
-static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
-{
- while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
- if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
- }
- return True;
-}
-
-
-static BOOL rw_torture(struct cli_state *c)
-{
- const char *lockfname = "\\torture.lck";
- fstring fname;
- int fnum;
- int fnum2;
- pid_t pid2, pid = getpid();
- int i, j;
- char buf[1024];
- BOOL correct = True;
-
- fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
- DENY_NONE);
- if (fnum2 == -1)
- fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
- if (fnum2 == -1) {
- printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
- return False;
- }
-
-
- for (i=0;i<torture_numops;i++) {
- unsigned n = (unsigned)sys_random()%10;
- if (i % 10 == 0) {
- printf("%d\r", i); fflush(stdout);
- }
- slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
-
- if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
- return False;
- }
-
- fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
- if (fnum == -1) {
- printf("open failed (%s)\n", cli_errstr(c));
- correct = False;
- break;
- }
-
- if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
- printf("write failed (%s)\n", cli_errstr(c));
- correct = False;
- }
-
- for (j=0;j<50;j++) {
- if (cli_write(c, fnum, 0, (char *)buf,
- sizeof(pid)+(j*sizeof(buf)),
- sizeof(buf)) != sizeof(buf)) {
- printf("write failed (%s)\n", cli_errstr(c));
- correct = False;
- }
- }
-
- pid2 = 0;
-
- if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
- printf("read failed (%s)\n", cli_errstr(c));
- correct = False;
- }
-
- if (pid2 != pid) {
- printf("data corruption!\n");
- correct = False;
- }
-
- if (!cli_close(c, fnum)) {
- printf("close failed (%s)\n", cli_errstr(c));
- correct = False;
- }
-
- if (!cli_unlink(c, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(c));
- correct = False;
- }
-
- if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
- printf("unlock failed (%s)\n", cli_errstr(c));
- correct = False;
- }
- }
-
- cli_close(c, fnum2);
- cli_unlink(c, lockfname);
-
- printf("%d\n", i);
-
- return correct;
-}
-
-static BOOL run_torture(int dummy)
-{
- struct cli_state *cli;
- BOOL ret;
-
- cli = current_cli;
-
- cli_sockopt(cli, sockops);
-
- ret = rw_torture(cli);
-
- if (!torture_close_connection(cli)) {
- ret = False;
- }
-
- return ret;
-}
-
-static BOOL rw_torture3(struct cli_state *c, char *lockfname)
-{
- int fnum = -1;
- unsigned int i = 0;
- char buf[131072];
- char buf_rd[131072];
- unsigned count;
- unsigned countprev = 0;
- ssize_t sent = 0;
- BOOL correct = True;
-
- srandom(1);
- for (i = 0; i < sizeof(buf); i += sizeof(uint32))
- {
- SIVAL(buf, i, sys_random());
- }
-
- if (procnum == 0)
- {
- fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
- DENY_NONE);
- if (fnum == -1) {
- printf("first open read/write of %s failed (%s)\n",
- lockfname, cli_errstr(c));
- return False;
- }
- }
- else
- {
- for (i = 0; i < 500 && fnum == -1; i++)
- {
- fnum = cli_open(c, lockfname, O_RDONLY,
- DENY_NONE);
- smb_msleep(10);
- }
- if (fnum == -1) {
- printf("second open read-only of %s failed (%s)\n",
- lockfname, cli_errstr(c));
- return False;
- }
- }
-
- i = 0;
- for (count = 0; count < sizeof(buf); count += sent)
- {
- if (count >= countprev) {
- printf("%d %8d\r", i, count);
- fflush(stdout);
- i++;
- countprev += (sizeof(buf) / 20);
- }
-
- if (procnum == 0)
- {
- sent = ((unsigned)sys_random()%(20))+ 1;
- if (sent > sizeof(buf) - count)
- {
- sent = sizeof(buf) - count;
- }
-
- if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
- printf("write failed (%s)\n", cli_errstr(c));
- correct = False;
- }
- }
- else
- {
- sent = cli_read(c, fnum, buf_rd+count, count,
- sizeof(buf)-count);
- if (sent < 0)
- {
- printf("read failed offset:%d size:%ld (%s)\n",
- count, (unsigned long)sizeof(buf)-count,
- cli_errstr(c));
- correct = False;
- sent = 0;
- }
- if (sent > 0)
- {
- if (memcmp(buf_rd+count, buf+count, sent) != 0)
- {
- printf("read/write compare failed\n");
- printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
- correct = False;
- break;
- }
- }
- }
-
- }
-
- if (!cli_close(c, fnum)) {
- printf("close failed (%s)\n", cli_errstr(c));
- correct = False;
- }
-
- return correct;
-}
-
-static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
-{
- const char *lockfname = "\\torture2.lck";
- int fnum1;
- int fnum2;
- int i;
- uchar buf[131072];
- uchar buf_rd[131072];
- BOOL correct = True;
- ssize_t bytes_read;
-
- if (!cli_unlink(c1, lockfname)) {
- printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
- }
-
- fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
- DENY_NONE);
- if (fnum1 == -1) {
- printf("first open read/write of %s failed (%s)\n",
- lockfname, cli_errstr(c1));
- return False;
- }
- fnum2 = cli_open(c2, lockfname, O_RDONLY,
- DENY_NONE);
- if (fnum2 == -1) {
- printf("second open read-only of %s failed (%s)\n",
- lockfname, cli_errstr(c2));
- cli_close(c1, fnum1);
- return False;
- }
-
- for (i=0;i<torture_numops;i++)
- {
- size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
- if (i % 10 == 0) {
- printf("%d\r", i); fflush(stdout);
- }
-
- generate_random_buffer(buf, buf_size, False);
-
- if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
- printf("write failed (%s)\n", cli_errstr(c1));
- correct = False;
- break;
- }
-
- if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
- printf("read failed (%s)\n", cli_errstr(c2));
- printf("read %d, expected %ld\n", bytes_read,
- (unsigned long)buf_size);
- correct = False;
- break;
- }
-
- if (memcmp(buf_rd, buf, buf_size) != 0)
- {
- printf("read/write compare failed\n");
- correct = False;
- break;
- }
- }
-
- if (!cli_close(c2, fnum2)) {
- printf("close failed (%s)\n", cli_errstr(c2));
- correct = False;
- }
- if (!cli_close(c1, fnum1)) {
- printf("close failed (%s)\n", cli_errstr(c1));
- correct = False;
- }
-
- if (!cli_unlink(c1, lockfname)) {
- printf("unlink failed (%s)\n", cli_errstr(c1));
- correct = False;
- }
-
- return correct;
-}
-
-static BOOL run_readwritetest(int dummy)
-{
- static struct cli_state *cli1, *cli2;
- BOOL test1, test2;
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting readwritetest\n");
-
- test1 = rw_torture2(cli1, cli2);
- printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
-
- if (test1) {
- test2 = rw_torture2(cli1, cli1);
- printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
- }
-
- if (!torture_close_connection(cli1)) {
- test1 = False;
- }
-
- if (!torture_close_connection(cli2)) {
- test2 = False;
- }
-
- return (test1 && test2);
-}
-
-static BOOL run_readwritemulti(int dummy)
-{
- struct cli_state *cli;
- BOOL test;
-
- cli = current_cli;
-
- cli_sockopt(cli, sockops);
-
- printf("run_readwritemulti: fname %s\n", randomfname);
- test = rw_torture3(cli, randomfname);
-
- if (!torture_close_connection(cli)) {
- test = False;
- }
-
- return test;
-}
-
-static BOOL run_readwritelarge(int dummy)
-{
- static struct cli_state *cli1;
- int fnum1;
- const char *lockfname = "\\large.dat";
- size_t fsize;
- char buf[126*1024];
- BOOL correct = True;
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
- cli_sockopt(cli1, sockops);
- memset(buf,'\0',sizeof(buf));
-
- cli1->max_xmit = 128*1024;
-
- printf("starting readwritelarge\n");
-
- cli_unlink(cli1, lockfname);
-
- fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
- return False;
- }
-
- cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
-
- if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
- printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (fsize == sizeof(buf))
- printf("readwritelarge test 1 succeeded (size = %lx)\n",
- (unsigned long)fsize);
- else {
- printf("readwritelarge test 1 failed (size = %lx)\n",
- (unsigned long)fsize);
- correct = False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (!cli_unlink(cli1, lockfname)) {
- printf("unlink failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
- return False;
- }
-
- cli1->max_xmit = 4*1024;
-
- cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
-
- if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
- printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (fsize == sizeof(buf))
- printf("readwritelarge test 2 succeeded (size = %lx)\n",
- (unsigned long)fsize);
- else {
- printf("readwritelarge test 2 failed (size = %lx)\n",
- (unsigned long)fsize);
- correct = False;
- }
-
-#if 0
- /* ToDo - set allocation. JRA */
- if(!cli_set_allocation_size(cli1, fnum1, 0)) {
- printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
- return False;
- }
- if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
- printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
- if (fsize != 0)
- printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
-#endif
-
- if (!cli_close(cli1, fnum1)) {
- printf("close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- return correct;
-}
-
-int line_count = 0;
-int nbio_id;
-
-#define ival(s) strtol(s, NULL, 0)
-
-/* run a test that simulates an approximate netbench client load */
-static BOOL run_netbench(int client)
-{
- struct cli_state *cli;
- int i;
- fstring fname;
- pstring line;
- char cname[20];
- FILE *f;
- const char *params[20];
- BOOL correct = True;
-
- cli = current_cli;
-
- nbio_id = client;
-
- cli_sockopt(cli, sockops);
-
- nb_setup(cli);
-
- slprintf(cname,sizeof(fname), "client%d", client);
-
- f = fopen(client_txt, "r");
-
- if (!f) {
- perror(client_txt);
- return False;
- }
-
- while (fgets(line, sizeof(line)-1, f)) {
- line_count++;
-
- line[strlen(line)-1] = 0;
-
- /* printf("[%d] %s\n", line_count, line); */
-
- all_string_sub(line,"client1", cname, sizeof(line));
-
- /* parse the command parameters */
- params[0] = strtok(line," ");
- i = 0;
- while (params[i]) params[++i] = strtok(NULL," ");
-
- params[i] = "";
-
- if (i < 2) continue;
-
- if (!strncmp(params[0],"SMB", 3)) {
- printf("ERROR: You are using a dbench 1 load file\n");
- exit(1);
- }
-
- if (!strcmp(params[0],"NTCreateX")) {
- nb_createx(params[1], ival(params[2]), ival(params[3]),
- ival(params[4]));
- } else if (!strcmp(params[0],"Close")) {
- nb_close(ival(params[1]));
- } else if (!strcmp(params[0],"Rename")) {
- nb_rename(params[1], params[2]);
- } else if (!strcmp(params[0],"Unlink")) {
- nb_unlink(params[1]);
- } else if (!strcmp(params[0],"Deltree")) {
- nb_deltree(params[1]);
- } else if (!strcmp(params[0],"Rmdir")) {
- nb_rmdir(params[1]);
- } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
- nb_qpathinfo(params[1]);
- } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
- nb_qfileinfo(ival(params[1]));
- } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
- nb_qfsinfo(ival(params[1]));
- } else if (!strcmp(params[0],"FIND_FIRST")) {
- nb_findfirst(params[1]);
- } else if (!strcmp(params[0],"WriteX")) {
- nb_writex(ival(params[1]),
- ival(params[2]), ival(params[3]), ival(params[4]));
- } else if (!strcmp(params[0],"ReadX")) {
- nb_readx(ival(params[1]),
- ival(params[2]), ival(params[3]), ival(params[4]));
- } else if (!strcmp(params[0],"Flush")) {
- nb_flush(ival(params[1]));
- } else {
- printf("Unknown operation %s\n", params[0]);
- exit(1);
- }
- }
- fclose(f);
-
- nb_cleanup();
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- return correct;
-}
-
-
-/* run a test that simulates an approximate netbench client load */
-static BOOL run_nbench(int dummy)
-{
- double t;
- BOOL correct = True;
-
- nbio_shmem(nprocs);
-
- nbio_id = -1;
-
- signal(SIGALRM, nb_alarm);
- alarm(1);
- t = create_procs(run_netbench, &correct);
- alarm(0);
-
- printf("\nThroughput %g MB/sec\n",
- 1.0e-6 * nbio_total() / t);
- return correct;
-}
-
-
-/*
- This test checks for two things:
-
- 1) correct support for retaining locks over a close (ie. the server
- must not use posix semantics)
- 2) support for lock timeouts
- */
-static BOOL run_locktest1(int dummy)
-{
- struct cli_state *cli1, *cli2;
- const char *fname = "\\lockt1.lck";
- int fnum1, fnum2, fnum3;
- time_t t1, t2;
- unsigned lock_timeout;
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting locktest1\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
- if (fnum3 == -1) {
- printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("lock1 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
-
- if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock2 succeeded! This is a locking bug\n");
- return False;
- } else {
- if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
- NT_STATUS_LOCK_NOT_GRANTED)) return False;
- }
-
-
- lock_timeout = (1 + (random() % 20));
- printf("Testing lock timeout with timeout=%u\n", lock_timeout);
- t1 = time(NULL);
- if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 500, WRITE_LOCK)) {
- printf("lock3 succeeded! This is a locking bug\n");
- return False;
- } else {
- if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
- NT_STATUS_FILE_LOCK_CONFLICT)) return False;
- }
- t2 = time(NULL);
-
- if (ABS(t2 - t1) < lock_timeout-1) {
- printf("error: This server appears not to support timed lock requests\n");
- }
-
- printf("server slept for %u seconds for a %u second timeout\n",
- (unsigned int)(t2-t1), lock_timeout);
-
- if (!cli_close(cli1, fnum2)) {
- printf("close1 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock4 succeeded! This is a locking bug\n");
- return False;
- } else {
- if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
- NT_STATUS_FILE_LOCK_CONFLICT)) return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli2, fnum3)) {
- printf("close3 failed (%s)\n", cli_errstr(cli2));
- return False;
- }
-
- if (!cli_unlink(cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
-
- if (!torture_close_connection(cli1)) {
- return False;
- }
-
- if (!torture_close_connection(cli2)) {
- return False;
- }
-
- printf("Passed locktest1\n");
- return True;
-}
-
-/*
- this checks to see if a secondary tconx can use open files from an
- earlier tconx
- */
-static BOOL run_tcon_test(int dummy)
-{
- static struct cli_state *cli;
- const char *fname = "\\tcontest.tmp";
- int fnum1;
- uint16 cnum1, cnum2, cnum3;
- uint16 vuid1, vuid2;
- char buf[4];
- BOOL ret = True;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
- cli_sockopt(cli, sockops);
-
- printf("starting tcontest\n");
-
- cli_unlink(cli, fname);
-
- fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- cnum1 = cli->cnum;
- vuid1 = cli->vuid;
-
- if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
- printf("initial write failed (%s)", cli_errstr(cli));
- return False;
- }
-
- if (!cli_send_tconX(cli, share, "?????",
- password, strlen(password)+1)) {
- printf("%s refused 2nd tree connect (%s)\n", host,
- cli_errstr(cli));
- cli_shutdown(cli);
- return False;
- }
-
- cnum2 = cli->cnum;
- cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
- vuid2 = cli->vuid + 1;
-
- /* try a write with the wrong tid */
- cli->cnum = cnum2;
-
- if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
- printf("* server allows write with wrong TID\n");
- ret = False;
- } else {
- printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
- }
-
-
- /* try a write with an invalid tid */
- cli->cnum = cnum3;
-
- if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
- printf("* server allows write with invalid TID\n");
- ret = False;
- } else {
- printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
- }
-
- /* try a write with an invalid vuid */
- cli->vuid = vuid2;
- cli->cnum = cnum1;
-
- if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
- printf("* server allows write with invalid VUID\n");
- ret = False;
- } else {
- printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
- }
-
- cli->cnum = cnum1;
- cli->vuid = vuid1;
-
- if (!cli_close(cli, fnum1)) {
- printf("close failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- cli->cnum = cnum2;
-
- if (!cli_tdis(cli)) {
- printf("secondary tdis failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- cli->cnum = cnum1;
-
- if (!torture_close_connection(cli)) {
- return False;
- }
-
- return ret;
-}
-
-
-/*
- checks for old style tcon support
- */
-static BOOL run_tcon2_test(int dummy)
-{
- static struct cli_state *cli;
- uint16 cnum, max_xmit;
- char *service;
- NTSTATUS status;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
- cli_sockopt(cli, sockops);
-
- printf("starting tcon2 test\n");
-
- asprintf(&service, "\\\\%s\\%s", host, share);
-
- status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
-
- if (!NT_STATUS_IS_OK(status)) {
- printf("tcon2 failed : %s\n", cli_errstr(cli));
- } else {
- printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
- (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
- }
-
- if (!torture_close_connection(cli)) {
- return False;
- }
-
- printf("Passed tcon2 test\n");
- return True;
-}
-
-static BOOL tcon_devtest(struct cli_state *cli,
- const char *myshare, const char *devtype,
- const char *return_devtype,
- NTSTATUS expected_error)
-{
- BOOL status;
- BOOL ret;
-
- status = cli_send_tconX(cli, myshare, devtype,
- password, strlen(password)+1);
-
- if (NT_STATUS_IS_OK(expected_error)) {
- if (status) {
- if (strcmp(cli->dev, return_devtype) == 0) {
- ret = True;
- } else {
- printf("tconX to share %s with type %s "
- "succeeded but returned the wrong "
- "device type (got [%s] but should have got [%s])\n",
- myshare, devtype, cli->dev, return_devtype);
- ret = False;
- }
- } else {
- printf("tconX to share %s with type %s "
- "should have succeeded but failed\n",
- myshare, devtype);
- ret = False;
- }
- cli_tdis(cli);
- } else {
- if (status) {
- printf("tconx to share %s with type %s "
- "should have failed but succeeded\n",
- myshare, devtype);
- ret = False;
- } else {
- if (NT_STATUS_EQUAL(cli_nt_error(cli),
- expected_error)) {
- ret = True;
- } else {
- printf("Returned unexpected error\n");
- ret = False;
- }
- }
- }
- return ret;
-}
-
-/*
- checks for correct tconX support
- */
-static BOOL run_tcon_devtype_test(int dummy)
-{
- static struct cli_state *cli1 = NULL;
- BOOL retry;
- int flags = 0;
- NTSTATUS status;
- BOOL ret = True;
-
- status = cli_full_connection(&cli1, myname,
- host, NULL, port_to_use,
- NULL, NULL,
- username, workgroup,
- password, flags, Undefined, &retry);
-
- if (!NT_STATUS_IS_OK(status)) {
- printf("could not open connection\n");
- return False;
- }
-
- if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
- ret = False;
-
- if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
- ret = False;
-
- if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
- ret = False;
-
- if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
- ret = False;
-
- if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
- ret = False;
-
- cli_shutdown(cli1);
-
- if (ret)
- printf("Passed tcondevtest\n");
-
- return ret;
-}
-
-
-/*
- This test checks that
-
- 1) the server supports multiple locking contexts on the one SMB
- connection, distinguished by PID.
-
- 2) the server correctly fails overlapping locks made by the same PID (this
- goes against POSIX behaviour, which is why it is tricky to implement)
-
- 3) the server denies unlock requests by an incorrect client PID
-*/
-static BOOL run_locktest2(int dummy)
-{
- static struct cli_state *cli;
- const char *fname = "\\lockt2.lck";
- int fnum1, fnum2, fnum3;
- BOOL correct = True;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- printf("starting locktest2\n");
-
- cli_unlink(cli, fname);
-
- cli_setpid(cli, 1);
-
- fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
- if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- cli_setpid(cli, 2);
-
- fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
- if (fnum3 == -1) {
- printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- cli_setpid(cli, 1);
-
- if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("lock1 failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("WRITE lock1 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
- NT_STATUS_LOCK_NOT_GRANTED)) return False;
- }
-
- if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
- printf("WRITE lock2 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
- NT_STATUS_LOCK_NOT_GRANTED)) return False;
- }
-
- if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
- printf("READ lock2 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
- NT_STATUS_FILE_LOCK_CONFLICT)) return False;
- }
-
- if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
- printf("lock at 100 failed (%s)\n", cli_errstr(cli));
- }
- cli_setpid(cli, 2);
- if (cli_unlock(cli, fnum1, 100, 4)) {
- printf("unlock at 100 succeeded! This is a locking bug\n");
- correct = False;
- }
-
- if (cli_unlock(cli, fnum1, 0, 4)) {
- printf("unlock1 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli,
- ERRDOS, ERRlock,
- NT_STATUS_RANGE_NOT_LOCKED)) return False;
- }
-
- if (cli_unlock(cli, fnum1, 0, 8)) {
- printf("unlock2 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli,
- ERRDOS, ERRlock,
- NT_STATUS_RANGE_NOT_LOCKED)) return False;
- }
-
- if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock3 succeeded! This is a locking bug\n");
- correct = False;
- } else {
- if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
- }
-
- cli_setpid(cli, 1);
-
- if (!cli_close(cli, fnum1)) {
- printf("close1 failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- if (!cli_close(cli, fnum2)) {
- printf("close2 failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- if (!cli_close(cli, fnum3)) {
- printf("close3 failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("locktest2 finished\n");
-
- return correct;
-}
-
-
-/*
- This test checks that
-
- 1) the server supports the full offset range in lock requests
-*/
-static BOOL run_locktest3(int dummy)
-{
- static struct cli_state *cli1, *cli2;
- const char *fname = "\\lockt3.lck";
- int fnum1, fnum2, i;
- uint32 offset;
- BOOL correct = True;
-
-#define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting locktest3\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
- if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- for (offset=i=0;i<torture_numops;i++) {
- NEXT_OFFSET;
- if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
- printf("lock1 %d failed (%s)\n",
- i,
- cli_errstr(cli1));
- return False;
- }
-
- if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
- printf("lock2 %d failed (%s)\n",
- i,
- cli_errstr(cli1));
- return False;
- }
- }
-
- for (offset=i=0;i<torture_numops;i++) {
- NEXT_OFFSET;
-
- if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
- printf("error: lock1 %d succeeded!\n", i);
- return False;
- }
-
- if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
- printf("error: lock2 %d succeeded!\n", i);
- return False;
- }
-
- if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
- printf("error: lock3 %d succeeded!\n", i);
- return False;
- }
-
- if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
- printf("error: lock4 %d succeeded!\n", i);
- return False;
- }
- }
-
- for (offset=i=0;i<torture_numops;i++) {
- NEXT_OFFSET;
-
- if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
- printf("unlock1 %d failed (%s)\n",
- i,
- cli_errstr(cli1));
- return False;
- }
-
- if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
- printf("unlock2 %d failed (%s)\n",
- i,
- cli_errstr(cli1));
- return False;
- }
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close1 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli2, fnum2)) {
- printf("close2 failed (%s)\n", cli_errstr(cli2));
- return False;
- }
-
- if (!cli_unlink(cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- if (!torture_close_connection(cli2)) {
- correct = False;
- }
-
- printf("finished locktest3\n");
-
- return correct;
-}
-
-#define EXPECTED(ret, v) if ((ret) != (v)) { \
- printf("** "); correct = False; \
- }
-
-/*
- looks at overlapping locks
-*/
-static BOOL run_locktest4(int dummy)
-{
- static struct cli_state *cli1, *cli2;
- const char *fname = "\\lockt4.lck";
- int fnum1, fnum2, f;
- BOOL ret;
- char buf[1000];
- BOOL correct = True;
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting locktest4\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
-
- memset(buf, 0, sizeof(buf));
-
- if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
- printf("Failed to create file\n");
- correct = False;
- goto fail;
- }
-
- ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
- cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
- cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
- (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
- EXPECTED(ret, False);
- printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
- (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
- EXPECTED(ret, True);
- printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
-
- ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
- (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
- EXPECTED(ret, False);
- printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 110, 6);
- EXPECTED(ret, False);
- printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
-
-
- ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
- (cli_read(cli2, fnum2, buf, 120, 4) == 4);
- EXPECTED(ret, False);
- printf("this server %s strict write locking\n", ret?"doesn't do":"does");
-
- ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
- (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
- EXPECTED(ret, False);
- printf("this server %s strict read locking\n", ret?"doesn't do":"does");
-
-
- ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 140, 4) &&
- cli_unlock(cli1, fnum1, 140, 4);
- EXPECTED(ret, True);
- printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
-
-
- ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 150, 4) &&
- (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
- !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
- cli_unlock(cli1, fnum1, 150, 4);
- EXPECTED(ret, True);
- printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
-
- ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 160, 4) &&
- (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
- (cli_read(cli2, fnum2, buf, 160, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
- cli_unlock(cli1, fnum1, 170, 4) &&
- (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
- (cli_read(cli2, fnum2, buf, 170, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
-
- ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 190, 4) &&
- !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
- (cli_read(cli2, fnum2, buf, 190, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
-
- cli_close(cli1, fnum1);
- cli_close(cli2, fnum2);
- fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
- cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
- cli_close(cli1, fnum1) &&
- ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
- cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
- cli_close(cli1, f);
- cli_close(cli1, fnum1);
- EXPECTED(ret, True);
- printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
-
- fail:
- cli_close(cli1, fnum1);
- cli_close(cli2, fnum2);
- cli_unlink(cli1, fname);
- torture_close_connection(cli1);
- torture_close_connection(cli2);
-
- printf("finished locktest4\n");
- return correct;
-}
-
-/*
- looks at lock upgrade/downgrade.
-*/
-static BOOL run_locktest5(int dummy)
-{
- static struct cli_state *cli1, *cli2;
- const char *fname = "\\lockt5.lck";
- int fnum1, fnum2, fnum3;
- BOOL ret;
- char buf[1000];
- BOOL correct = True;
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting locktest5\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
- fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
-
- memset(buf, 0, sizeof(buf));
-
- if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
- printf("Failed to create file\n");
- correct = False;
- goto fail;
- }
-
- /* Check for NT bug... */
- ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
- cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
- cli_close(cli1, fnum1);
- fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
- EXPECTED(ret, True);
- printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
- cli_close(cli1, fnum1);
- fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- cli_unlock(cli1, fnum3, 0, 1);
-
- ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
- cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
-
- ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
- EXPECTED(ret, False);
-
- printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
-
- /* Unlock the process 2 lock. */
- cli_unlock(cli2, fnum2, 0, 4);
-
- ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
- EXPECTED(ret, False);
-
- printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
-
- /* Unlock the process 1 fnum3 lock. */
- cli_unlock(cli1, fnum3, 0, 4);
-
- /* Stack 2 more locks here. */
- ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
- cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
-
- EXPECTED(ret, True);
- printf("the same process %s stack read locks\n", ret?"can":"cannot");
-
- /* Unlock the first process lock, then check this was the WRITE lock that was
- removed. */
-
- ret = cli_unlock(cli1, fnum1, 0, 4) &&
- cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
-
- EXPECTED(ret, True);
- printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
-
- /* Unlock the process 2 lock. */
- cli_unlock(cli2, fnum2, 0, 4);
-
- /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
-
- ret = cli_unlock(cli1, fnum1, 1, 1) &&
- cli_unlock(cli1, fnum1, 0, 4) &&
- cli_unlock(cli1, fnum1, 0, 4);
-
- EXPECTED(ret, True);
- printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
-
- /* Ensure the next unlock fails. */
- ret = cli_unlock(cli1, fnum1, 0, 4);
- EXPECTED(ret, False);
- printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
-
- /* Ensure connection 2 can get a write lock. */
- ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
- EXPECTED(ret, True);
-
- printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
-
-
- fail:
- cli_close(cli1, fnum1);
- cli_close(cli2, fnum2);
- cli_unlink(cli1, fname);
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- if (!torture_close_connection(cli2)) {
- correct = False;
- }
-
- printf("finished locktest5\n");
-
- return correct;
-}
-
-/*
- tries the unusual lockingX locktype bits
-*/
-static BOOL run_locktest6(int dummy)
-{
- static struct cli_state *cli;
- const char *fname[1] = { "\\lock6.txt" };
- int i;
- int fnum;
- NTSTATUS status;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- printf("starting locktest6\n");
-
- for (i=0;i<1;i++) {
- printf("Testing %s\n", fname[i]);
-
- cli_unlink(cli, fname[i]);
-
- fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
- cli_close(cli, fnum);
- printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
-
- fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
- status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
- cli_close(cli, fnum);
- printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
-
- cli_unlink(cli, fname[i]);
- }
-
- torture_close_connection(cli);
-
- printf("finished locktest6\n");
- return True;
-}
-
-static BOOL run_locktest7(int dummy)
-{
- struct cli_state *cli1;
- const char *fname = "\\lockt7.lck";
- int fnum1;
- char buf[200];
- BOOL correct = False;
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
-
- printf("starting locktest7\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
-
- memset(buf, 0, sizeof(buf));
-
- if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
- printf("Failed to create file\n");
- goto fail;
- }
-
- cli_setpid(cli1, 1);
-
- if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
- printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
- goto fail;
- } else {
- printf("pid1 successfully locked range 130:4 for READ\n");
- }
-
- if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
- printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
- goto fail;
- } else {
- printf("pid1 successfully read the range 130:4\n");
- }
-
- if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
- printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
- if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
- printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
- goto fail;
- }
- } else {
- printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
- goto fail;
- }
-
- cli_setpid(cli1, 2);
-
- if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
- printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
- } else {
- printf("pid2 successfully read the range 130:4\n");
- }
-
- if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
- printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
- if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
- printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
- goto fail;
- }
- } else {
- printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
- goto fail;
- }
-
- cli_setpid(cli1, 1);
- cli_unlock(cli1, fnum1, 130, 4);
-
- if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
- printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
- goto fail;
- } else {
- printf("pid1 successfully locked range 130:4 for WRITE\n");
- }
-
- if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
- printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
- goto fail;
- } else {
- printf("pid1 successfully read the range 130:4\n");
- }
-
- if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
- printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
- goto fail;
- } else {
- printf("pid1 successfully wrote to the range 130:4\n");
- }
-
- cli_setpid(cli1, 2);
-
- if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
- printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
- if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
- printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
- goto fail;
- }
- } else {
- printf("pid2 successfully read the range 130:4 (should be denied)\n");
- goto fail;
- }
-
- if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
- printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
- if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
- printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
- goto fail;
- }
- } else {
- printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
- goto fail;
- }
-
- cli_unlock(cli1, fnum1, 130, 0);
- correct = True;
-
-fail:
- cli_close(cli1, fnum1);
- cli_unlink(cli1, fname);
- torture_close_connection(cli1);
-
- printf("finished locktest7\n");
- return correct;
-}
-
-/*
-test whether fnums and tids open on one VC are available on another (a major
-security hole)
-*/
-static BOOL run_fdpasstest(int dummy)
-{
- struct cli_state *cli1, *cli2;
- const char *fname = "\\fdpass.tst";
- int fnum1;
- pstring buf;
-
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- printf("starting fdpasstest\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
- printf("write failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli2->vuid = cli1->vuid;
- cli2->cnum = cli1->cnum;
- cli2->pid = cli1->pid;
-
- if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
- printf("read succeeded! nasty security hole [%s]\n",
- buf);
- return False;
- }
-
- cli_close(cli1, fnum1);
- cli_unlink(cli1, fname);
-
- torture_close_connection(cli1);
- torture_close_connection(cli2);
-
- printf("finished fdpasstest\n");
- return True;
-}
-
-static BOOL run_fdsesstest(int dummy)
-{
- struct cli_state *cli;
- uint16 new_vuid;
- uint16 saved_vuid;
- uint16 new_cnum;
- uint16 saved_cnum;
- const char *fname = "\\fdsess.tst";
- const char *fname1 = "\\fdsess1.tst";
- int fnum1;
- int fnum2;
- pstring buf;
- BOOL ret = True;
-
- if (!torture_open_connection(&cli))
- return False;
- cli_sockopt(cli, sockops);
-
- if (!torture_cli_session_setup2(cli, &new_vuid))
- return False;
-
- saved_cnum = cli->cnum;
- if (!cli_send_tconX(cli, share, "?????", "", 1))
- return False;
- new_cnum = cli->cnum;
- cli->cnum = saved_cnum;
-
- printf("starting fdsesstest\n");
-
- cli_unlink(cli, fname);
- cli_unlink(cli, fname1);
-
- fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
- printf("write failed (%s)\n", cli_errstr(cli));
- return False;
- }
-
- saved_vuid = cli->vuid;
- cli->vuid = new_vuid;
-
- if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
- printf("read succeeded with different vuid! nasty security hole [%s]\n",
- buf);
- ret = False;
- }
- /* Try to open a file with different vuid, samba cnum. */
- fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum2 != -1) {
- printf("create with different vuid, same cnum succeeded.\n");
- cli_close(cli, fnum2);
- cli_unlink(cli, fname1);
- } else {
- printf("create with different vuid, same cnum failed.\n");
- printf("This will cause problems with service clients.\n");
- ret = False;
- }
-
- cli->vuid = saved_vuid;
-
- /* Try with same vuid, different cnum. */
- cli->cnum = new_cnum;
-
- if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
- printf("read succeeded with different cnum![%s]\n",
- buf);
- ret = False;
- }
-
- cli->cnum = saved_cnum;
- cli_close(cli, fnum1);
- cli_unlink(cli, fname);
-
- torture_close_connection(cli);
-
- printf("finished fdsesstest\n");
- return ret;
-}
-
-/*
- This test checks that
-
- 1) the server does not allow an unlink on a file that is open
-*/
-static BOOL run_unlinktest(int dummy)
-{
- struct cli_state *cli;
- const char *fname = "\\unlink.tst";
- int fnum;
- BOOL correct = True;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- printf("starting unlink test\n");
-
- cli_unlink(cli, fname);
-
- cli_setpid(cli, 1);
-
- fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- if (cli_unlink(cli, fname)) {
- printf("error: server allowed unlink on an open file\n");
- correct = False;
- } else {
- correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
- }
-
- cli_close(cli, fnum);
- cli_unlink(cli, fname);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("unlink test finished\n");
-
- return correct;
-}
-
-
-/*
-test how many open files this server supports on the one socket
-*/
-static BOOL run_maxfidtest(int dummy)
-{
- struct cli_state *cli;
- const char *template = "\\maxfid.%d.%d";
- fstring fname;
- int fnums[0x11000], i;
- int retries=4;
- BOOL correct = True;
-
- cli = current_cli;
-
- if (retries <= 0) {
- printf("failed to connect\n");
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- for (i=0; i<0x11000; i++) {
- slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
- if ((fnums[i] = cli_open(cli, fname,
- O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
- -1) {
- printf("open of %s failed (%s)\n",
- fname, cli_errstr(cli));
- printf("maximum fnum is %d\n", i);
- break;
- }
- printf("%6d\r", i);
- }
- printf("%6d\n", i);
- i--;
-
- printf("cleaning up\n");
- for (;i>=0;i--) {
- slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
- cli_close(cli, fnums[i]);
- if (!cli_unlink(cli, fname)) {
- printf("unlink of %s failed (%s)\n",
- fname, cli_errstr(cli));
- correct = False;
- }
- printf("%6d\r", i);
- }
- printf("%6d\n", 0);
-
- printf("maxfid test finished\n");
- if (!torture_close_connection(cli)) {
- correct = False;
- }
- return correct;
-}
-
-/* generate a random buffer */
-static void rand_buf(char *buf, int len)
-{
- while (len--) {
- *buf = (char)sys_random();
- buf++;
- }
-}
-
-/* send smb negprot commands, not reading the response */
-static BOOL run_negprot_nowait(int dummy)
-{
- int i;
- static struct cli_state cli;
- BOOL correct = True;
-
- printf("starting negprot nowait test\n");
-
- if (!open_nbt_connection(&cli)) {
- return False;
- }
-
- for (i=0;i<50000;i++) {
- cli_negprot_send(&cli);
- }
-
- if (!torture_close_connection(&cli)) {
- correct = False;
- }
-
- printf("finished negprot nowait test\n");
-
- return correct;
-}
-
-
-/* send random IPC commands */
-static BOOL run_randomipc(int dummy)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- int rdrcnt,rprcnt;
- pstring param;
- int api, param_len, i;
- struct cli_state *cli;
- BOOL correct = True;
- int count = 50000;
-
- printf("starting random ipc test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- for (i=0;i<count;i++) {
- api = sys_random() % 500;
- param_len = (sys_random() % 64);
-
- rand_buf(param, param_len);
-
- SSVAL(param,0,api);
-
- cli_api(cli,
- param, param_len, 8,
- NULL, 0, BUFFER_SIZE,
- &rparam, &rprcnt,
- &rdata, &rdrcnt);
- if (i % 100 == 0) {
- printf("%d/%d\r", i,count);
- }
- }
- printf("%d/%d\n", i, count);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("finished random ipc test\n");
-
- return correct;
-}
-
-
-
-static void browse_callback(const char *sname, uint32 stype,
- const char *comment, void *state)
-{
- printf("\t%20.20s %08x %s\n", sname, stype, comment);
-}
-
-
-
-/*
- This test checks the browse list code
-
-*/
-static BOOL run_browsetest(int dummy)
-{
- static struct cli_state *cli;
- BOOL correct = True;
-
- printf("starting browse test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- printf("domain list:\n");
- cli_NetServerEnum(cli, cli->server_domain,
- SV_TYPE_DOMAIN_ENUM,
- browse_callback, NULL);
-
- printf("machine list:\n");
- cli_NetServerEnum(cli, cli->server_domain,
- SV_TYPE_ALL,
- browse_callback, NULL);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("browse test finished\n");
-
- return correct;
-
-}
-
-
-/*
- This checks how the getatr calls works
-*/
-static BOOL run_attrtest(int dummy)
-{
- struct cli_state *cli;
- int fnum;
- time_t t, t2;
- const char *fname = "\\attrib123456789.tst";
- BOOL correct = True;
-
- printf("starting attrib test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_unlink(cli, fname);
- fnum = cli_open(cli, fname,
- O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- cli_close(cli, fnum);
- if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
- printf("getatr failed (%s)\n", cli_errstr(cli));
- correct = False;
- }
-
- if (abs(t - time(NULL)) > 60*60*24*10) {
- printf("ERROR: SMBgetatr bug. time is %s",
- ctime(&t));
- t = time(NULL);
- correct = True;
- }
-
- t2 = t-60*60*24; /* 1 day ago */
-
- if (!cli_setatr(cli, fname, 0, t2)) {
- printf("setatr failed (%s)\n", cli_errstr(cli));
- correct = True;
- }
-
- if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
- printf("getatr failed (%s)\n", cli_errstr(cli));
- correct = True;
- }
-
- if (t != t2) {
- printf("ERROR: getatr/setatr bug. times are\n%s",
- ctime(&t));
- printf("%s", ctime(&t2));
- correct = True;
- }
-
- cli_unlink(cli, fname);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("attrib test finished\n");
-
- return correct;
-}
-
-
-/*
- This checks a couple of trans2 calls
-*/
-static BOOL run_trans2test(int dummy)
-{
- struct cli_state *cli;
- int fnum;
- size_t size;
- time_t c_time, a_time, m_time, w_time, m_time2;
- const char *fname = "\\trans2.tst";
- const char *dname = "\\trans2";
- const char *fname2 = "\\trans2\\trans2.tst";
- pstring pname;
- BOOL correct = True;
-
- printf("starting trans2 test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_unlink(cli, fname);
- fnum = cli_open(cli, fname,
- O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
- NULL, NULL)) {
- printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
- correct = False;
- }
-
- if (!cli_qfilename(cli, fnum, pname)) {
- printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
- correct = False;
- }
-
- if (strcmp(pname, fname)) {
- printf("qfilename gave different name? [%s] [%s]\n",
- fname, pname);
- correct = False;
- }
-
- cli_close(cli, fnum);
-
- sleep(2);
-
- cli_unlink(cli, fname);
- fnum = cli_open(cli, fname,
- O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- if (fnum == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
- cli_close(cli, fnum);
-
- if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
- printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
- correct = False;
- } else {
- if (c_time != m_time) {
- printf("create time=%s", ctime(&c_time));
- printf("modify time=%s", ctime(&m_time));
- printf("This system appears to have sticky create times\n");
- }
- if (a_time % (60*60) == 0) {
- printf("access time=%s", ctime(&a_time));
- printf("This system appears to set a midnight access time\n");
- correct = False;
- }
-
- if (abs(m_time - time(NULL)) > 60*60*24*7) {
- printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
- correct = False;
- }
- }
-
-
- cli_unlink(cli, fname);
- fnum = cli_open(cli, fname,
- O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time,
- &w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
- correct = False;
- } else {
- if (w_time < 60*60*24*2) {
- printf("write time=%s", ctime(&w_time));
- printf("This system appears to set a initial 0 write time\n");
- correct = False;
- }
- }
-
- cli_unlink(cli, fname);
-
-
- /* check if the server updates the directory modification time
- when creating a new file */
- if (!cli_mkdir(cli, dname)) {
- printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
- correct = False;
- }
- sleep(3);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time,
- &w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
- correct = False;
- }
-
- fnum = cli_open(cli, fname2,
- O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
- cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2,
- &w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
- correct = False;
- } else {
- if (m_time2 == m_time) {
- printf("This system does not update directory modification times\n");
- correct = False;
- }
- }
- cli_unlink(cli, fname2);
- cli_rmdir(cli, dname);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("trans2 test finished\n");
-
- return correct;
-}
-
-/*
- This checks new W2K calls.
-*/
-
-static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
-{
- char *buf = NULL;
- uint32 len;
- BOOL correct = True;
-
- if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
- printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
- correct = False;
- } else {
- printf("qfileinfo: level %d, len = %u\n", level, len);
- dump_data(0, buf, len);
- printf("\n");
- }
- SAFE_FREE(buf);
- return correct;
-}
-
-static BOOL run_w2ktest(int dummy)
-{
- struct cli_state *cli;
- int fnum;
- const char *fname = "\\w2ktest\\w2k.tst";
- int level;
- BOOL correct = True;
-
- printf("starting w2k test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- fnum = cli_open(cli, fname,
- O_RDWR | O_CREAT , DENY_NONE);
-
- for (level = 1004; level < 1040; level++) {
- new_trans(cli, fnum, level);
- }
-
- cli_close(cli, fnum);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("w2k test finished\n");
-
- return correct;
-}
-
-
-/*
- this is a harness for some oplock tests
- */
-static BOOL run_oplock1(int dummy)
-{
- struct cli_state *cli1;
- const char *fname = "\\lockt1.lck";
- int fnum1;
- BOOL correct = True;
-
- printf("starting oplock test 1\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_unlink(cli1, fname);
-
- cli_sockopt(cli1, sockops);
-
- cli1->use_oplocks = True;
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- cli1->use_oplocks = False;
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname);
-
- if (!cli_close(cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_unlink(cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- printf("finished oplock test 1\n");
-
- return correct;
-}
-
-static BOOL run_oplock2(int dummy)
-{
- struct cli_state *cli1, *cli2;
- const char *fname = "\\lockt2.lck";
- int fnum1, fnum2;
- int saved_use_oplocks = use_oplocks;
- char buf[4];
- BOOL correct = True;
- volatile BOOL *shared_correct;
-
- shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
- *shared_correct = True;
-
- use_level_II_oplocks = True;
- use_oplocks = True;
-
- printf("starting oplock test 2\n");
-
- if (!torture_open_connection(&cli1)) {
- use_level_II_oplocks = False;
- use_oplocks = saved_use_oplocks;
- return False;
- }
-
- cli1->use_oplocks = True;
- cli1->use_level_II_oplocks = True;
-
- if (!torture_open_connection(&cli2)) {
- use_level_II_oplocks = False;
- use_oplocks = saved_use_oplocks;
- return False;
- }
-
- cli2->use_oplocks = True;
- cli2->use_level_II_oplocks = True;
-
- cli_unlink(cli1, fname);
-
- cli_sockopt(cli1, sockops);
- cli_sockopt(cli2, sockops);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- /* Don't need the globals any more. */
- use_level_II_oplocks = False;
- use_oplocks = saved_use_oplocks;
-
- if (fork() == 0) {
- /* Child code */
- fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
- if (fnum2 == -1) {
- printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
- *shared_correct = False;
- exit(0);
- }
-
- sleep(2);
-
- if (!cli_close(cli2, fnum2)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- *shared_correct = False;
- }
-
- exit(0);
- }
-
- sleep(2);
-
- /* Ensure cli1 processes the break. */
-
- if (cli_read(cli1, fnum1, buf, 0, 4) != 4) {
- printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- /* Should now be at level II. */
- /* Test if sending a write locks causes a break to none. */
-
- if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
- printf("lock failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- cli_unlock(cli1, fnum1, 0, 4);
-
- sleep(2);
-
- if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("lock failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- cli_unlock(cli1, fnum1, 0, 4);
-
- sleep(2);
-
- cli_read(cli1, fnum1, buf, 0, 4);
-
-#if 0
- if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
- printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-#endif
-
- if (!cli_close(cli1, fnum1)) {
- printf("close1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- sleep(4);
-
- if (!cli_unlink(cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- if (!*shared_correct) {
- correct = False;
- }
-
- printf("finished oplock test 2\n");
-
- return correct;
-}
-
-/* handler for oplock 3 tests */
-static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
-{
- printf("got oplock break fnum=%d level=%d\n",
- fnum, level);
- return cli_oplock_ack(cli, fnum, level);
-}
-
-static BOOL run_oplock3(int dummy)
-{
- struct cli_state *cli;
- const char *fname = "\\oplockt3.dat";
- int fnum;
- char buf[4] = "abcd";
- BOOL correct = True;
- volatile BOOL *shared_correct;
-
- shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
- *shared_correct = True;
-
- printf("starting oplock test 3\n");
-
- if (fork() == 0) {
- /* Child code */
- use_oplocks = True;
- use_level_II_oplocks = True;
- if (!torture_open_connection(&cli)) {
- *shared_correct = False;
- exit(0);
- }
- sleep(2);
- /* try to trigger a oplock break in parent */
- fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
- cli_write(cli, fnum, 0, buf, 0, 4);
- exit(0);
- }
-
- /* parent code */
- use_oplocks = True;
- use_level_II_oplocks = True;
- if (!torture_open_connection(&cli)) {
- return False;
- }
- cli_oplock_handler(cli, oplock3_handler);
- fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
- cli_write(cli, fnum, 0, buf, 0, 4);
- cli_close(cli, fnum);
- fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
- cli->timeout = 20000;
- cli_receive_smb(cli);
- printf("finished oplock test 3\n");
-
- return (correct && *shared_correct);
-
-/* What are we looking for here? What's sucess and what's FAILURE? */
-}
-
-
-
-/*
- Test delete on close semantics.
- */
-static BOOL run_deletetest(int dummy)
-{
- struct cli_state *cli1 = NULL;
- struct cli_state *cli2 = NULL;
- const char *fname = "\\delete.file";
- int fnum1 = -1;
- int fnum2 = -1;
- BOOL correct = True;
-
- printf("starting delete test\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
-
- /* Test 1 - this should delete the file on close. */
-
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
- 0, FILE_OVERWRITE_IF,
- FILE_DELETE_ON_CLOSE, 0);
-
- if (fnum1 == -1) {
- printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
-#if 0 /* JRATEST */
- {
- uint32 *accinfo = NULL;
- uint32 len;
- cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
- if (accinfo)
- printf("access mode = 0x%lx\n", *accinfo);
- SAFE_FREE(accinfo);
- }
-#endif
-
- if (!cli_close(cli1, fnum1)) {
- printf("[1] close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
- if (fnum1 != -1) {
- printf("[1] open of %s succeeded (should fail)\n", fname);
- correct = False;
- goto fail;
- }
-
- printf("first delete on close test succeeded.\n");
-
- /* Test 2 - this should delete the file on close. */
-
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
- FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[2] close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
- if (fnum1 != -1) {
- printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
- if (!cli_close(cli1, fnum1)) {
- printf("[2] close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
- cli_unlink(cli1, fname);
- } else
- printf("second delete on close test succeeded.\n");
-
- /* Test 3 - ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail with a sharing violation - open for delete is only compatible
- with SHARE_DELETE. */
-
- fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
-
- if (fnum2 != -1) {
- printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
- correct = False;
- goto fail;
- }
-
- /* This should succeed. */
-
- fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
-
- if (fnum2 == -1) {
- printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum2)) {
- printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail - file should no longer be there. */
-
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
- if (fnum1 != -1) {
- printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
- if (!cli_close(cli1, fnum1)) {
- printf("[3] close failed (%s)\n", cli_errstr(cli1));
- }
- cli_unlink(cli1, fname);
- correct = False;
- goto fail;
- } else
- printf("third delete on close test succeeded.\n");
-
- /* Test 4 ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should succeed. */
- fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
- if (fnum2 == -1) {
- printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum2)) {
- printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail - no more opens once delete on close set. */
- fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_OPEN, 0, 0);
- if (fnum2 != -1) {
- printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
- correct = False;
- goto fail;
- } else
- printf("fourth delete on close test succeeded.\n");
-
- if (!cli_close(cli1, fnum1)) {
- printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* Test 5 ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
- if (fnum1 == -1) {
- printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail - only allowed on NT opens with DELETE access. */
-
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- printf("fifth delete on close test succeeded.\n");
-
- /* Test 6 ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail - only allowed on NT opens with DELETE access. */
-
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- printf("sixth delete on close test succeeded.\n");
-
- /* Test 7 ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
- FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[7] setting delete_on_close on file failed !\n");
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
- printf("[7] unsetting delete_on_close on file failed !\n");
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This next open should succeed - we reset the flag. */
-
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
- if (fnum1 == -1) {
- printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- printf("seventh delete on close test succeeded.\n");
-
- /* Test 7 ... */
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- if (!torture_open_connection(&cli2)) {
- printf("[8] failed to open second connection.\n");
- correct = False;
- goto fail;
- }
-
- cli_sockopt(cli1, sockops);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_OPEN, 0, 0);
-
- if (fnum2 == -1) {
- printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
- printf("[8] setting delete_on_close on file failed !\n");
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- if (!cli_close(cli2, fnum2)) {
- printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
- correct = False;
- goto fail;
- }
-
- /* This should fail.. */
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
- if (fnum1 != -1) {
- printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
- goto fail;
- correct = False;
- } else
- printf("eighth delete on close test succeeded.\n");
-
- /* This should fail - we need to set DELETE_ACCESS. */
- fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
-
- if (fnum1 != -1) {
- printf("[9] open of %s succeeded should have failed!\n", fname);
- correct = False;
- goto fail;
- }
-
- printf("ninth delete on close test succeeded.\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
- FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
- if (fnum1 == -1) {
- printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should delete the file. */
- if (!cli_close(cli1, fnum1)) {
- printf("[10] close failed (%s)\n", cli_errstr(cli1));
- correct = False;
- goto fail;
- }
-
- /* This should fail.. */
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
- if (fnum1 != -1) {
- printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
- goto fail;
- correct = False;
- } else
- printf("tenth delete on close test succeeded.\n");
- printf("finished delete test\n");
-
- fail:
- /* FIXME: This will crash if we aborted before cli2 got
- * intialized, because these functions don't handle
- * uninitialized connections. */
-
- if (fnum1 != -1) cli_close(cli1, fnum1);
- if (fnum2 != -1) cli_close(cli1, fnum2);
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- if (cli1 && !torture_close_connection(cli1)) {
- correct = False;
- }
- if (cli2 && !torture_close_connection(cli2)) {
- correct = False;
- }
- return correct;
-}
-
-
-/*
- print out server properties
- */
-static BOOL run_properties(int dummy)
-{
- static struct cli_state *cli;
- BOOL correct = True;
-
- printf("starting properties test\n");
-
- ZERO_STRUCT(cli);
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- d_printf("Capabilities 0x%08x\n", cli->capabilities);
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- return correct;
-}
-
-
-
-/* FIRST_DESIRED_ACCESS 0xf019f */
-#define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
- FILE_READ_EA| /* 0xf */ \
- FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
- FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
- DELETE_ACCESS|READ_CONTROL_ACCESS|\
- WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
-/* SECOND_DESIRED_ACCESS 0xe0080 */
-#define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
- READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
- WRITE_OWNER_ACCESS /* 0xe0000 */
-
-#if 0
-#define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
- READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
- FILE_READ_DATA|\
- WRITE_OWNER_ACCESS /* */
-#endif
-
-/*
- Test ntcreate calls made by xcopy
- */
-static BOOL run_xcopy(int dummy)
-{
- static struct cli_state *cli1;
- const char *fname = "\\test.txt";
- BOOL correct = True;
- int fnum1, fnum2;
-
- printf("starting xcopy test\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- fnum1 = cli_nt_create_full(cli1, fname, 0,
- FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF,
- 0x4044, 0);
-
- if (fnum1 == -1) {
- printf("First open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli1, fname, 0,
- SECOND_DESIRED_ACCESS, 0,
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
- 0x200000, 0);
- if (fnum2 == -1) {
- printf("second open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- return correct;
-}
-
-/*
- Test rename on files open with share delete and no share delete.
- */
-static BOOL run_rename(int dummy)
-{
- static struct cli_state *cli1;
- const char *fname = "\\test.txt";
- const char *fname1 = "\\test1.txt";
- BOOL correct = True;
- int fnum1;
-
- printf("starting rename test\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("First open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_rename(cli1, fname, fname1)) {
- printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
- } else {
- printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
- correct = False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close - 1 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
-#if 0
- FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-#else
- FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
-#endif
-
- if (fnum1 == -1) {
- printf("Second open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_rename(cli1, fname, fname1)) {
- printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
- correct = False;
- } else {
- printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close - 2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("Third open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
-
-#if 0
- {
- int fnum2;
-
- fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("Fourth open failed - %s\n", cli_errstr(cli1));
- return False;
- }
- if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
- printf("[8] setting delete_on_close on file failed !\n");
- return False;
- }
-
- if (!cli_close(cli1, fnum2)) {
- printf("close - 4 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
- }
-#endif
-
- if (!cli_rename(cli1, fname, fname1)) {
- printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
- correct = False;
- } else {
- printf("Third rename succeeded (SHARE_NONE)\n");
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close - 3 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
-
- /*----*/
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("Fourth open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_rename(cli1, fname, fname1)) {
- printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
- } else {
- printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
- correct = False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close - 4 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
-
- /*--*/
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("Fifth open failed - %s\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_rename(cli1, fname, fname1)) {
- printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
- correct = False;
- } else {
- printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
- }
-
- /*
- * Now check if the first name still exists ...
- */
-
- /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("Opening original file after rename of open file fails: %s\n",
- cli_errstr(cli1));
- }
- else {
- printf("Opening original file after rename of open file works ...\n");
- (void)cli_close(cli1, fnum2);
- } */
-
- /*--*/
-
-
- if (!cli_close(cli1, fnum1)) {
- printf("close - 5 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
- cli_unlink(cli1, fname1);
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- return correct;
-}
-
-static BOOL run_pipe_number(int dummy)
-{
- struct cli_state *cli1;
- const char *pipe_name = "\\SPOOLSS";
- int fnum;
- int num_pipes = 0;
-
- printf("starting pipenumber test\n");
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
- while(1) {
- fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
-
- if (fnum == -1) {
- printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
- break;
- }
- num_pipes++;
- }
-
- printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
- torture_close_connection(cli1);
- return True;
-}
-
-/*
- Test open mode returns on read-only files.
- */
-static BOOL run_opentest(int dummy)
-{
- static struct cli_state *cli1;
- static struct cli_state *cli2;
- const char *fname = "\\readonly.file";
- int fnum1, fnum2;
- char buf[20];
- size_t fsize;
- BOOL correct = True;
- char *tmp_path;
-
- printf("starting open test\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- cli_sockopt(cli1, sockops);
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (!cli_setatr(cli1, fname, aRONLY, 0)) {
- printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
- fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
-
- if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
- NT_STATUS_ACCESS_DENIED)) {
- printf("correct error code ERRDOS/ERRnoaccess returned\n");
- }
-
- printf("finished open test 1\n");
-
- cli_close(cli1, fnum1);
-
- /* Now try not readonly and ensure ERRbadshare is returned. */
-
- cli_setatr(cli1, fname, 0, 0);
-
- fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
- if (fnum1 == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- /* This will fail - but the error should be ERRshare. */
- fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
-
- if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION)) {
- printf("correct error code ERRDOS/ERRbadshare returned\n");
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- cli_unlink(cli1, fname);
-
- printf("finished open test 2\n");
-
- /* Test truncate open disposition on file opened for read. */
-
- fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum1 == -1) {
- printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- /* write 20 bytes. */
-
- memset(buf, '\0', 20);
-
- if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
- printf("write failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- /* Ensure size == 20. */
- if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
- printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (fsize != 20) {
- printf("(3) file size != 20\n");
- return False;
- }
-
- /* Now test if we can truncate a file opened for readonly. */
-
- fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
- if (fnum1 == -1) {
- printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- /* Ensure size == 0. */
- if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
- printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
- if (fsize != 0) {
- printf("(3) file size != 0\n");
- return False;
- }
- printf("finished open test 3\n");
-
- cli_unlink(cli1, fname);
-
-
- printf("testing ctemp\n");
- fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
- if (fnum1 == -1) {
- printf("ctemp failed (%s)\n", cli_errstr(cli1));
- return False;
- }
- printf("ctemp gave path %s\n", tmp_path);
- if (!cli_close(cli1, fnum1)) {
- printf("close of temp failed (%s)\n", cli_errstr(cli1));
- }
- if (!cli_unlink(cli1, tmp_path)) {
- printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
- }
-
- /* Test the non-io opens... */
-
- if (!torture_open_connection(&cli2)) {
- return False;
- }
-
- cli_setatr(cli2, fname, 0, 0);
- cli_unlink(cli2, fname);
-
- cli_sockopt(cli2, sockops);
-
- printf("TEST #1 testing 2 non-io opens (no delete)\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- if (!cli_close(cli2, fnum2)) {
- printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("non-io open test #1 passed.\n");
-
- cli_unlink(cli1, fname);
-
- printf("TEST #2 testing 2 non-io opens (first with delete)\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- if (!cli_close(cli2, fnum2)) {
- printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- printf("non-io open test #2 passed.\n");
-
- cli_unlink(cli1, fname);
-
- printf("TEST #3 testing 2 non-io opens (second with delete)\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
- if (!cli_close(cli2, fnum2)) {
- printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("non-io open test #3 passed.\n");
-
- cli_unlink(cli1, fname);
-
- printf("TEST #4 testing 2 non-io opens (both with delete)\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 != -1) {
- printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- printf("non-io open test #4 passed.\n");
-
- cli_unlink(cli1, fname);
-
- printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli2, fnum2)) {
- printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("non-io open test #5 passed.\n");
-
- printf("TEST #6 testing 1 non-io open, one io open\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 == -1) {
- printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli2, fnum2)) {
- printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("non-io open test #6 passed.\n");
-
- printf("TEST #7 testing 1 non-io open, one io open with delete\n");
-
- cli_unlink(cli1, fname);
-
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
-
- if (fnum2 != -1) {
- printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
- return False;
- }
-
- printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
-
- if (!cli_close(cli1, fnum1)) {
- printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
- return False;
- }
-
- printf("non-io open test #7 passed.\n");
-
- cli_unlink(cli1, fname);
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- if (!torture_close_connection(cli2)) {
- correct = False;
- }
-
- return correct;
-}
-
-static uint32 open_attrs_table[] = {
- FILE_ATTRIBUTE_NORMAL,
- FILE_ATTRIBUTE_ARCHIVE,
- FILE_ATTRIBUTE_READONLY,
- FILE_ATTRIBUTE_HIDDEN,
- FILE_ATTRIBUTE_SYSTEM,
-
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
- FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
-
- FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
- FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
- FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
- FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
-};
-
-struct trunc_open_results {
- unsigned int num;
- uint32 init_attr;
- uint32 trunc_attr;
- uint32 result_attr;
-};
-
-static struct trunc_open_results attr_results[] = {
- { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
- { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
- { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
- { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
- { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
- { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
- { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
- { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
- { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
- { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
- { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
- { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
- { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
- { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
- { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
- { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
-};
-
-static BOOL run_openattrtest(int dummy)
-{
- static struct cli_state *cli1;
- const char *fname = "\\openattr.file";
- int fnum1;
- BOOL correct = True;
- uint16 attr;
- unsigned int i, j, k, l;
-
- printf("starting open attr test\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- cli_sockopt(cli1, sockops);
-
- for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
-
- if (fnum1 == -1) {
- printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
- return False;
- }
-
- for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
- fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
- FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
-
- if (fnum1 == -1) {
- for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
- if (attr_results[l].num == k) {
- printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
- k, open_attrs_table[i],
- open_attrs_table[j],
- fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
- correct = False;
- }
- }
- if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
- printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
- k, open_attrs_table[i], open_attrs_table[j],
- cli_errstr(cli1));
- correct = False;
- }
-#if 0
- printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
-#endif
- k++;
- continue;
- }
-
- if (!cli_close(cli1, fnum1)) {
- printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
- return False;
- }
-
- if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
- printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
- return False;
- }
-
-#if 0
- printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
- k, open_attrs_table[i], open_attrs_table[j], attr );
-#endif
-
- for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
- if (attr_results[l].num == k) {
- if (attr != attr_results[l].result_attr ||
- open_attrs_table[i] != attr_results[l].init_attr ||
- open_attrs_table[j] != attr_results[l].trunc_attr) {
- printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
- open_attrs_table[i],
- open_attrs_table[j],
- (unsigned int)attr,
- attr_results[l].result_attr);
- correct = False;
- }
- break;
- }
- }
- k++;
- }
- }
-
- cli_setatr(cli1, fname, 0, 0);
- cli_unlink(cli1, fname);
-
- printf("open attr test %s.\n", correct ? "passed" : "failed");
-
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- return correct;
-}
-
-static void list_fn(file_info *finfo, const char *name, void *state)
-{
-
-}
-
-/*
- test directory listing speed
- */
-static BOOL run_dirtest(int dummy)
-{
- int i;
- static struct cli_state *cli;
- int fnum;
- double t1;
- BOOL correct = True;
-
- printf("starting directory test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- srandom(0);
- for (i=0;i<torture_numops;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "\\%x", (int)random());
- fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
- if (fnum == -1) {
- fprintf(stderr,"Failed to open %s\n", fname);
- return False;
- }
- cli_close(cli, fnum);
- }
-
- t1 = end_timer();
-
- printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
- printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
- printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
-
- printf("dirtest core %g seconds\n", end_timer() - t1);
-
- srandom(0);
- for (i=0;i<torture_numops;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "\\%x", (int)random());
- cli_unlink(cli, fname);
- }
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("finished dirtest\n");
-
- return correct;
-}
-
-static void del_fn(file_info *finfo, const char *mask, void *state)
-{
- struct cli_state *pcli = (struct cli_state *)state;
- fstring fname;
- slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
-
- if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
- return;
-
- if (finfo->mode & aDIR) {
- if (!cli_rmdir(pcli, fname))
- printf("del_fn: failed to rmdir %s\n,", fname );
- } else {
- if (!cli_unlink(pcli, fname))
- printf("del_fn: failed to unlink %s\n,", fname );
- }
-}
-
-
-/*
- sees what IOCTLs are supported
- */
-BOOL torture_ioctl_test(int dummy)
-{
- static struct cli_state *cli;
- uint16 device, function;
- int fnum;
- const char *fname = "\\ioctl.dat";
- DATA_BLOB blob;
- NTSTATUS status;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- printf("starting ioctl test\n");
-
- cli_unlink(cli, fname);
-
- fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum == -1) {
- printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
- return False;
- }
-
- status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
- printf("ioctl device info: %s\n", cli_errstr(cli));
-
- status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
- printf("ioctl job info: %s\n", cli_errstr(cli));
-
- for (device=0;device<0x100;device++) {
- printf("testing device=0x%x\n", device);
- for (function=0;function<0x100;function++) {
- uint32 code = (device<<16) | function;
-
- status = cli_raw_ioctl(cli, fnum, code, &blob);
-
- if (NT_STATUS_IS_OK(status)) {
- printf("ioctl 0x%x OK : %d bytes\n", code, blob.length);
- data_blob_free(&blob);
- }
- }
- }
-
- if (!torture_close_connection(cli)) {
- return False;
- }
-
- return True;
-}
-
-
-/*
- tries varients of chkpath
- */
-BOOL torture_chkpath_test(int dummy)
-{
- static struct cli_state *cli;
- int fnum;
- BOOL ret;
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- printf("starting chkpath test\n");
-
- /* cleanup from an old run */
- cli_rmdir(cli, "\\chkpath.dir\\dir2");
- cli_unlink(cli, "\\chkpath.dir\\*");
- cli_rmdir(cli, "\\chkpath.dir");
-
- if (!cli_mkdir(cli, "\\chkpath.dir")) {
- printf("mkdir1 failed : %s\n", cli_errstr(cli));
- return False;
- }
-
- if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
- printf("mkdir2 failed : %s\n", cli_errstr(cli));
- return False;
- }
-
- fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- if (fnum == -1) {
- printf("open1 failed (%s)\n", cli_errstr(cli));
- return False;
- }
- cli_close(cli, fnum);
-
- if (!cli_chkpath(cli, "\\chkpath.dir")) {
- printf("chkpath1 failed: %s\n", cli_errstr(cli));
- ret = False;
- }
-
- if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
- printf("chkpath2 failed: %s\n", cli_errstr(cli));
- ret = False;
- }
-
- if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
- ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
- NT_STATUS_NOT_A_DIRECTORY);
- } else {
- printf("* chkpath on a file should fail\n");
- ret = False;
- }
-
- if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
- ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
- NT_STATUS_OBJECT_NAME_NOT_FOUND);
- } else {
- printf("* chkpath on a non existant file should fail\n");
- ret = False;
- }
-
- if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
- ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
- NT_STATUS_OBJECT_PATH_NOT_FOUND);
- } else {
- printf("* chkpath on a non existent component should fail\n");
- ret = False;
- }
-
- cli_rmdir(cli, "\\chkpath.dir\\dir2");
- cli_unlink(cli, "\\chkpath.dir\\*");
- cli_rmdir(cli, "\\chkpath.dir");
-
- if (!torture_close_connection(cli)) {
- return False;
- }
-
- return ret;
-}
-
-static BOOL run_eatest(int dummy)
-{
- static struct cli_state *cli;
- const char *fname = "\\eatest.txt";
- BOOL correct = True;
- int fnum, i;
- size_t num_eas;
- struct ea_struct *ea_list = NULL;
- TALLOC_CTX *mem_ctx = talloc_init("eatest");
-
- printf("starting eatest\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_unlink(cli, fname);
- fnum = cli_nt_create_full(cli, fname, 0,
- FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF,
- 0x4044, 0);
-
- if (fnum == -1) {
- printf("open failed - %s\n", cli_errstr(cli));
- return False;
- }
-
- for (i = 0; i < 10; i++) {
- fstring ea_name, ea_val;
-
- slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
- memset(ea_val, (char)i+1, i+1);
- if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
- printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
- return False;
- }
- }
-
- cli_close(cli, fnum);
- for (i = 0; i < 10; i++) {
- fstring ea_name, ea_val;
-
- slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
- memset(ea_val, (char)i+1, i+1);
- if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
- printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
- return False;
- }
- }
-
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
- correct = False;
- }
-
- printf("num_eas = %d\n", num_eas);
-
- if (num_eas != 20) {
- printf("Should be 20 EA's stored... failing.\n");
- correct = False;
- }
-
- for (i = 0; i < num_eas; i++) {
- printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
- dump_data(0, ea_list[i].value.data, ea_list[i].value.length);
- }
-
- /* Setting EA's to zero length deletes them. Test this */
- printf("Now deleting all EA's - case indepenent....\n");
-
- for (i = 0; i < 20; i++) {
- fstring ea_name;
- slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
- if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
- printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
- return False;
- }
- }
-
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
- correct = False;
- }
-
- printf("num_eas = %d\n", num_eas);
- for (i = 0; i < num_eas; i++) {
- printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
- dump_data(0, ea_list[i].value.data, ea_list[i].value.length);
- }
-
- if (num_eas != 0) {
- printf("deleting EA's failed.\n");
- correct = False;
- }
-
- /* Try and delete a non existant EA. */
- if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
- printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
- correct = False;
- }
-
- talloc_destroy(mem_ctx);
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- return correct;
-}
-
-static BOOL run_dirtest1(int dummy)
-{
- int i;
- static struct cli_state *cli;
- int fnum, num_seen;
- BOOL correct = True;
-
- printf("starting directory test\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- cli_sockopt(cli, sockops);
-
- cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
- cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
- cli_rmdir(cli, "\\LISTDIR");
- cli_mkdir(cli, "\\LISTDIR");
-
- /* Create 1000 files and 1000 directories. */
- for (i=0;i<1000;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
- fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
- if (fnum == -1) {
- fprintf(stderr,"Failed to open %s\n", fname);
- return False;
- }
- cli_close(cli, fnum);
- }
- for (i=0;i<1000;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
- if (!cli_mkdir(cli, fname)) {
- fprintf(stderr,"Failed to open %s\n", fname);
- return False;
- }
- }
-
- /* Now ensure that doing an old list sees both files and directories. */
- num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
- printf("num_seen = %d\n", num_seen );
- /* We should see 100 files + 1000 directories + . and .. */
- if (num_seen != 2002)
- correct = False;
-
- /* Ensure if we have the "must have" bits we only see the
- * relevent entries.
- */
- num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
- printf("num_seen = %d\n", num_seen );
- if (num_seen != 1002)
- correct = False;
-
- num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
- printf("num_seen = %d\n", num_seen );
- if (num_seen != 1000)
- correct = False;
-
- /* Delete everything. */
- cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
- cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
- cli_rmdir(cli, "\\LISTDIR");
-
-#if 0
- printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
- printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
- printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
-#endif
-
- if (!torture_close_connection(cli)) {
- correct = False;
- }
-
- printf("finished dirtest1\n");
-
- return correct;
-}
-
-static BOOL run_error_map_extract(int dummy) {
-
- static struct cli_state c_dos;
- static struct cli_state c_nt;
-
- uint32 error;
-
- uint32 flgs2, errnum;
- uint8 errclass;
-
- NTSTATUS nt_status;
-
- fstring user;
-
- /* NT-Error connection */
-
- if (!open_nbt_connection(&c_nt)) {
- return False;
- }
-
- c_nt.use_spnego = False;
-
- if (!cli_negprot(&c_nt)) {
- printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
- cli_shutdown(&c_nt);
- return False;
- }
-
- if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
- workgroup)) {
- printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
- return False;
- }
-
- /* DOS-Error connection */
-
- if (!open_nbt_connection(&c_dos)) {
- return False;
- }
-
- c_dos.use_spnego = False;
- c_dos.force_dos_errors = True;
-
- if (!cli_negprot(&c_dos)) {
- printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
- cli_shutdown(&c_dos);
- return False;
- }
-
- if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
- workgroup)) {
- printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
- return False;
- }
-
- for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
- fstr_sprintf(user, "%X", error);
-
- if (cli_session_setup(&c_nt, user,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
- printf("/** Session setup succeeded. This shouldn't happen...*/\n");
- }
-
- flgs2 = SVAL(c_nt.inbuf,smb_flg2);
-
- /* Case #1: 32-bit NT errors */
- if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
- nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
- } else {
- printf("/** Dos error on NT connection! (%s) */\n",
- cli_errstr(&c_nt));
- nt_status = NT_STATUS(0xc0000000);
- }
-
- if (cli_session_setup(&c_dos, user,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
- printf("/** Session setup succeeded. This shouldn't happen...*/\n");
- }
- flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
-
- /* Case #1: 32-bit NT errors */
- if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
- printf("/** NT error on DOS connection! (%s) */\n",
- cli_errstr(&c_nt));
- errnum = errclass = 0;
- } else {
- cli_dos_error(&c_dos, &errclass, &errnum);
- }
-
- if (NT_STATUS_V(nt_status) != error) {
- printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
- get_nt_error_c_code(NT_STATUS(error)),
- get_nt_error_c_code(nt_status));
- }
-
- printf("\t{%s,\t%s,\t%s},\n",
- smb_dos_err_class(errclass),
- smb_dos_err_name(errclass, errnum),
- get_nt_error_c_code(NT_STATUS(error)));
- }
- return True;
-}
-
-static double create_procs(BOOL (*fn)(int), BOOL *result)
-{
- int i, status;
- volatile pid_t *child_status;
- volatile BOOL *child_status_out;
- int synccount;
- int tries = 8;
-
- synccount = 0;
-
- child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
- if (!child_status) {
- printf("Failed to setup shared memory\n");
- return -1;
- }
-
- child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
- if (!child_status_out) {
- printf("Failed to setup result status shared memory\n");
- return -1;
- }
-
- for (i = 0; i < nprocs; i++) {
- child_status[i] = 0;
- child_status_out[i] = True;
- }
-
- start_timer();
-
- for (i=0;i<nprocs;i++) {
- procnum = i;
- if (fork() == 0) {
- pid_t mypid = getpid();
- sys_srandom(((int)mypid) ^ ((int)time(NULL)));
-
- slprintf(myname,sizeof(myname),"CLIENT%d", i);
-
- while (1) {
- if (torture_open_connection(&current_cli)) break;
- if (tries-- == 0) {
- printf("pid %d failed to start\n", (int)getpid());
- _exit(1);
- }
- smb_msleep(10);
- }
-
- child_status[i] = getpid();
-
- while (child_status[i] && end_timer() < 5) smb_msleep(2);
-
- child_status_out[i] = fn(i);
- _exit(0);
- }
- }
-
- do {
- synccount = 0;
- for (i=0;i<nprocs;i++) {
- if (child_status[i]) synccount++;
- }
- if (synccount == nprocs) break;
- smb_msleep(10);
- } while (end_timer() < 30);
-
- if (synccount != nprocs) {
- printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
- *result = False;
- return end_timer();
- }
-
- /* start the client load */
- start_timer();
-
- for (i=0;i<nprocs;i++) {
- child_status[i] = 0;
- }
-
- printf("%d clients started\n", nprocs);
-
- for (i=0;i<nprocs;i++) {
- while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
- }
-
- printf("\n");
-
- for (i=0;i<nprocs;i++) {
- if (!child_status_out[i]) {
- *result = False;
- }
- }
- return end_timer();
-}
-
-#define FLAG_MULTIPROC 1
-
-static struct {
- const char *name;
- BOOL (*fn)(int);
- unsigned flags;
-} torture_ops[] = {
- {"FDPASS", run_fdpasstest, 0},
- {"LOCK1", run_locktest1, 0},
- {"LOCK2", run_locktest2, 0},
- {"LOCK3", run_locktest3, 0},
- {"LOCK4", run_locktest4, 0},
- {"LOCK5", run_locktest5, 0},
- {"LOCK6", run_locktest6, 0},
- {"LOCK7", run_locktest7, 0},
- {"UNLINK", run_unlinktest, 0},
- {"BROWSE", run_browsetest, 0},
- {"ATTR", run_attrtest, 0},
- {"TRANS2", run_trans2test, 0},
- {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
- {"TORTURE",run_torture, FLAG_MULTIPROC},
- {"RANDOMIPC", run_randomipc, 0},
- {"NEGNOWAIT", run_negprot_nowait, 0},
- {"NBENCH", run_nbench, 0},
- {"OPLOCK1", run_oplock1, 0},
- {"OPLOCK2", run_oplock2, 0},
- {"OPLOCK3", run_oplock3, 0},
- {"DIR", run_dirtest, 0},
- {"DIR1", run_dirtest1, 0},
- {"DENY1", torture_denytest1, 0},
- {"DENY2", torture_denytest2, 0},
- {"TCON", run_tcon_test, 0},
- {"TCONDEV", run_tcon_devtype_test, 0},
- {"RW1", run_readwritetest, 0},
- {"RW2", run_readwritemulti, FLAG_MULTIPROC},
- {"RW3", run_readwritelarge, 0},
- {"OPEN", run_opentest, 0},
-#if 1
- {"OPENATTR", run_openattrtest, 0},
-#endif
- {"XCOPY", run_xcopy, 0},
- {"RENAME", run_rename, 0},
- {"DELETE", run_deletetest, 0},
- {"PROPERTIES", run_properties, 0},
- {"MANGLE", torture_mangle, 0},
- {"W2K", run_w2ktest, 0},
- {"TRANS2SCAN", torture_trans2_scan, 0},
- {"NTTRANSSCAN", torture_nttrans_scan, 0},
- {"UTABLE", torture_utable, 0},
- {"CASETABLE", torture_casetable, 0},
- {"ERRMAPEXTRACT", run_error_map_extract, 0},
- {"PIPE_NUMBER", run_pipe_number, 0},
- {"TCON2", run_tcon2_test, 0},
- {"IOCTL", torture_ioctl_test, 0},
- {"CHKPATH", torture_chkpath_test, 0},
- {"FDSESS", run_fdsesstest, 0},
- { "EATEST", run_eatest, 0},
- {NULL, NULL, 0}};
-
-
-
-/****************************************************************************
-run a specified test or "ALL"
-****************************************************************************/
-static BOOL run_test(const char *name)
-{
- BOOL ret = True;
- BOOL result = True;
- BOOL found = False;
- int i;
- double t;
- if (strequal(name,"ALL")) {
- for (i=0;torture_ops[i].name;i++) {
- run_test(torture_ops[i].name);
- }
- found = True;
- }
-
- for (i=0;torture_ops[i].name;i++) {
- fstr_sprintf(randomfname, "\\XX%x",
- (unsigned)random());
-
- if (strequal(name, torture_ops[i].name)) {
- found = True;
- printf("Running %s\n", name);
- if (torture_ops[i].flags & FLAG_MULTIPROC) {
- t = create_procs(torture_ops[i].fn, &result);
- if (!result) {
- ret = False;
- printf("TEST %s FAILED!\n", name);
- }
-
- } else {
- start_timer();
- if (!torture_ops[i].fn(0)) {
- ret = False;
- printf("TEST %s FAILED!\n", name);
- }
- t = end_timer();
- }
- printf("%s took %g secs\n\n", name, t);
- }
- }
-
- if (!found) {
- printf("Did not find a test named %s\n", name);
- ret = False;
- }
-
- return ret;
-}
-
-
-static void usage(void)
-{
- int i;
-
- printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
-
- printf("\t-d debuglevel\n");
- printf("\t-U user%%pass\n");
- printf("\t-k use kerberos\n");
- printf("\t-N numprocs\n");
- printf("\t-n my_netbios_name\n");
- printf("\t-W workgroup\n");
- printf("\t-o num_operations\n");
- printf("\t-O socket_options\n");
- printf("\t-m maximum protocol\n");
- printf("\t-L use oplocks\n");
- printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
- printf("\t-A showall\n");
- printf("\t-p port\n");
- printf("\t-s seed\n");
- printf("\n\n");
-
- printf("tests are:");
- for (i=0;torture_ops[i].name;i++) {
- printf(" %s", torture_ops[i].name);
- }
- printf("\n");
-
- printf("default test is ALL\n");
-
- exit(1);
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- int opt, i;
- char *p;
- int gotuser = 0;
- int gotpass = 0;
- extern char *optarg;
- extern int optind;
- BOOL correct = True;
-
- dbf = x_stdout;
-
-#ifdef HAVE_SETBUFFER
- setbuffer(stdout, NULL, 0);
-#endif
-
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
-
- if (argc < 2) {
- usage();
- }
-
- for(p = argv[1]; *p; p++)
- if(*p == '\\')
- *p = '/';
-
- if (strncmp(argv[1], "//", 2)) {
- usage();
- }
-
- fstrcpy(host, &argv[1][2]);
- p = strchr_m(&host[2],'/');
- if (!p) {
- usage();
- }
- *p = 0;
- fstrcpy(share, p+1);
-
- get_myname(myname);
-
- if (*username == 0 && getenv("LOGNAME")) {
- fstrcpy(username,getenv("LOGNAME"));
- }
-
- argc--;
- argv++;
-
- srandom(time(NULL));
-
- fstrcpy(workgroup, lp_workgroup());
-
- while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
- switch (opt) {
- case 'p':
- port_to_use = atoi(optarg);
- break;
- case 's':
- srandom(atoi(optarg));
- break;
- case 'W':
- fstrcpy(workgroup,optarg);
- break;
- case 'm':
- max_protocol = interpret_protocol(optarg, max_protocol);
- break;
- case 'N':
- nprocs = atoi(optarg);
- break;
- case 'o':
- torture_numops = atoi(optarg);
- break;
- case 'd':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'O':
- sockops = optarg;
- break;
- case 'L':
- use_oplocks = True;
- break;
- case 'A':
- torture_showall = True;
- break;
- case 'n':
- fstrcpy(myname, optarg);
- break;
- case 'c':
- client_txt = optarg;
- break;
- case 'k':
-#ifdef HAVE_KRB5
- use_kerberos = True;
-#else
- d_printf("No kerberos support compiled in\n");
- exit(1);
-#endif
- break;
- case 'U':
- gotuser = 1;
- fstrcpy(username,optarg);
- p = strchr_m(username,'%');
- if (p) {
- *p = 0;
- fstrcpy(password, p+1);
- gotpass = 1;
- }
- break;
- default:
- printf("Unknown option %c (%d)\n", (char)opt, opt);
- usage();
- }
- }
-
- if(use_kerberos && !gotuser) gotpass = True;
-
- while (!gotpass) {
- p = getpass("Password:");
- if (p) {
- fstrcpy(password, p);
- gotpass = 1;
- }
- }
-
- printf("host=%s share=%s user=%s myname=%s\n",
- host, share, username, myname);
-
- if (argc == optind) {
- correct = run_test("ALL");
- } else {
- for (i=optind;i<argc;i++) {
- if (!run_test(argv[i])) {
- correct = False;
- }
- }
- }
-
- if (correct) {
- return(0);
- } else {
- return(1);
- }
-}
diff --git a/source/torture/utable.c b/source/torture/utable.c
deleted file mode 100644
index ba803a0da4f..00000000000
--- a/source/torture/utable.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester - unicode table dumper
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-BOOL torture_utable(int dummy)
-{
- struct cli_state *cli;
- fstring fname, alt_name;
- int fnum;
- smb_ucs2_t c2;
- int c, len, fd;
- int chars_allowed=0, alt_allowed=0;
- uint8 valid[0x10000];
-
- printf("starting utable\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- memset(valid, 0, sizeof(valid));
-
- cli_mkdir(cli, "\\utable");
- cli_unlink(cli, "\\utable\\*");
-
- for (c=1; c < 0x10000; c++) {
- char *p;
-
- SSVAL(&c2, 0, c);
- fstrcpy(fname, "\\utable\\x");
- p = fname+strlen(fname);
- len = convert_string(CH_UCS2, CH_UNIX,
- &c2, 2,
- p, sizeof(fname)-strlen(fname), True);
- p[len] = 0;
- fstrcat(fname,"_a_long_extension");
-
- fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
- DENY_NONE);
- if (fnum == -1) continue;
-
- chars_allowed++;
-
- cli_qpathinfo_alt_name(cli, fname, alt_name);
-
- if (strncmp(alt_name, "X_A_L", 5) != 0) {
- alt_allowed++;
- valid[c] = 1;
- d_printf("fname=[%s] alt_name=[%s]\n", fname, alt_name);
- }
-
- cli_close(cli, fnum);
- cli_unlink(cli, fname);
-
- if (c % 100 == 0) {
- printf("%d (%d/%d)\r", c, chars_allowed, alt_allowed);
- }
- }
- printf("%d (%d/%d)\n", c, chars_allowed, alt_allowed);
-
- cli_rmdir(cli, "\\utable");
-
- d_printf("%d chars allowed %d alt chars allowed\n", chars_allowed, alt_allowed);
-
- fd = open("valid.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (fd == -1) {
- d_printf("Failed to create valid.dat - %s", strerror(errno));
- return False;
- }
- write(fd, valid, 0x10000);
- close(fd);
- d_printf("wrote valid.dat\n");
-
- return True;
-}
-
-
-static char *form_name(int c)
-{
- static fstring fname;
- smb_ucs2_t c2;
- char *p;
- int len;
-
- fstrcpy(fname, "\\utable\\");
- p = fname+strlen(fname);
- SSVAL(&c2, 0, c);
-
- len = convert_string(CH_UCS2, CH_UNIX,
- &c2, 2,
- p, sizeof(fname)-strlen(fname), True);
- p[len] = 0;
- return fname;
-}
-
-BOOL torture_casetable(int dummy)
-{
- static struct cli_state *cli;
- char *fname;
- int fnum;
- int c, i;
-#define MAX_EQUIVALENCE 8
- smb_ucs2_t equiv[0x10000][MAX_EQUIVALENCE];
- printf("starting casetable\n");
-
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- memset(equiv, 0, sizeof(equiv));
-
- cli_unlink(cli, "\\utable\\*");
- cli_rmdir(cli, "\\utable");
- if (!cli_mkdir(cli, "\\utable")) {
- printf("Failed to create utable directory!\n");
- return False;
- }
-
- for (c=1; c < 0x10000; c++) {
- size_t size;
-
- if (c == '.' || c == '\\') continue;
-
- printf("%04x (%c)\n", c, isprint(c)?c:'.');
-
- fname = form_name(c);
- fnum = cli_nt_create_full(cli, fname, 0,
- GENERIC_ALL_ACCESS,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE,
- FILE_OPEN_IF, 0, 0);
-
- if (fnum == -1) {
- printf("Failed to create file with char %04x\n", c);
- continue;
- }
-
- size = 0;
-
- if (!cli_qfileinfo(cli, fnum, NULL, &size,
- NULL, NULL, NULL, NULL, NULL)) continue;
-
- if (size > 0) {
- /* found a character equivalence! */
- int c2[MAX_EQUIVALENCE];
-
- if (size/sizeof(int) >= MAX_EQUIVALENCE) {
- printf("too many chars match?? size=%ld c=0x%04x\n",
- (unsigned long)size, c);
- cli_close(cli, fnum);
- return False;
- }
-
- cli_read(cli, fnum, (char *)c2, 0, size);
- printf("%04x: ", c);
- equiv[c][0] = c;
- for (i=0; i<size/sizeof(int); i++) {
- printf("%04x ", c2[i]);
- equiv[c][i+1] = c2[i];
- }
- printf("\n");
- fflush(stdout);
- }
-
- cli_write(cli, fnum, 0, (char *)&c, size, sizeof(c));
- cli_close(cli, fnum);
- }
-
- cli_unlink(cli, "\\utable\\*");
- cli_rmdir(cli, "\\utable");
-
- return True;
-}
diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c
deleted file mode 100644
index 88fe3486493..00000000000
--- a/source/torture/vfstest.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- VFS module tester
-
- Copyright (C) Simo Sorce 2002
- Copyright (C) Eric Lorimer 2002
- Copyright (C) Jelmer Vernooij 2002,2003
-
- Most of this code was ripped off of rpcclient.
- Copyright (C) Tim Potter 2000-2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "vfstest.h"
-
-/* List to hold groups of commands */
-static struct cmd_list {
- struct cmd_list *prev, *next;
- struct cmd_set *cmd_set;
-} *cmd_list;
-
-extern pstring user_socket_options;
-
-/****************************************************************************
-handle completion of commands for readline
-****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
-{
-#define MAX_COMPLETIONS 100
- char **matches;
- int i, count=0;
- struct cmd_list *commands = cmd_list;
-
- if (start)
- return NULL;
-
- /* make sure we have a list of valid commands */
- if (!commands)
- return NULL;
-
- matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
- if (!matches) return NULL;
-
- matches[count++] = strdup(text);
- if (!matches[0]) return NULL;
-
- while (commands && count < MAX_COMPLETIONS-1)
- {
- if (!commands->cmd_set)
- break;
-
- for (i=0; commands->cmd_set[i].name; i++)
- {
- if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
- commands->cmd_set[i].fn)
- {
- matches[count] = strdup(commands->cmd_set[i].name);
- if (!matches[count])
- return NULL;
- count++;
- }
- }
-
- commands = commands->next;
-
- }
-
- if (count == 2) {
- SAFE_FREE(matches[0]);
- matches[0] = strdup(matches[1]);
- }
- matches[count] = NULL;
- return matches;
-}
-
-static char* next_command(char** cmdstr)
-{
- static pstring command;
- char *p;
-
- if (!cmdstr || !(*cmdstr))
- return NULL;
-
- p = strchr_m(*cmdstr, ';');
- if (p)
- *p = '\0';
- pstrcpy(command, *cmdstr);
- *cmdstr = p;
-
- return command;
-}
-
-/* Load specified configuration file */
-static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- if (argc != 2) {
- printf("Usage: %s <smb.conf>\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- if (!lp_load(argv[1], False, True, False)) {
- printf("Error loading \"%s\"\n", argv[1]);
- return NT_STATUS_OK;
- }
-
- printf("\"%s\" successfully loaded\n", argv[1]);
- return NT_STATUS_OK;
-}
-
-/* Display help on commands */
-static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- struct cmd_list *tmp;
- struct cmd_set *tmp_set;
-
- /* Usage */
- if (argc > 2) {
- printf("Usage: %s [command]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- /* Help on one command */
-
- if (argc == 2) {
- for (tmp = cmd_list; tmp; tmp = tmp->next) {
-
- tmp_set = tmp->cmd_set;
-
- while(tmp_set->name) {
- if (strequal(argv[1], tmp_set->name)) {
- if (tmp_set->usage &&
- tmp_set->usage[0])
- printf("%s\n", tmp_set->usage);
- else
- printf("No help for %s\n", tmp_set->name);
-
- return NT_STATUS_OK;
- }
-
- tmp_set++;
- }
- }
-
- printf("No such command: %s\n", argv[1]);
- return NT_STATUS_OK;
- }
-
- /* List all commands */
-
- for (tmp = cmd_list; tmp; tmp = tmp->next) {
-
- tmp_set = tmp->cmd_set;
-
- while(tmp_set->name) {
-
- printf("%15s\t\t%s\n", tmp_set->name,
- tmp_set->description ? tmp_set->description:
- "");
-
- tmp_set++;
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/* Change the debug level */
-static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- if (argc > 2) {
- printf("Usage: %s [debuglevel]\n", argv[0]);
- return NT_STATUS_OK;
- }
-
- if (argc == 2) {
- DEBUGLEVEL = atoi(argv[1]);
- }
-
- printf("debuglevel is %d\n", DEBUGLEVEL);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- /* Cleanup */
- talloc_destroy(mem_ctx);
- mem_ctx = NULL;
- vfs->data = NULL;
- vfs->data_size = 0;
- return NT_STATUS_OK;
-}
-
-static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- /* Cleanup */
- talloc_destroy(mem_ctx);
-
- exit(0);
- return NT_STATUS_OK; /* NOTREACHED */
-}
-
-static struct cmd_set vfstest_commands[] = {
-
- { "GENERAL OPTIONS" },
-
- { "conf", cmd_conf, "Load smb configuration file", "conf <smb.conf>" },
- { "help", cmd_help, "Get help on commands", "" },
- { "?", cmd_help, "Get help on commands", "" },
- { "debuglevel", cmd_debuglevel, "Set debug level", "" },
- { "freemem", cmd_freemem, "Free currently allocated buffers", "" },
- { "exit", cmd_quit, "Exit program", "" },
- { "quit", cmd_quit, "Exit program", "" },
-
- { NULL }
-};
-
-static struct cmd_set separator_command[] = {
- { "---------------", NULL, "----------------------" },
- { NULL }
-};
-
-
-extern struct cmd_set vfs_commands[];
-static struct cmd_set *vfstest_command_list[] = {
- vfstest_commands,
- vfs_commands,
- NULL
-};
-
-static void add_command_set(struct cmd_set *cmd_set)
-{
- struct cmd_list *entry;
-
- if (!(entry = (struct cmd_list *)malloc(sizeof(struct cmd_list)))) {
- DEBUG(0, ("out of memory\n"));
- return;
- }
-
- ZERO_STRUCTP(entry);
-
- entry->cmd_set = cmd_set;
- DLIST_ADD(cmd_list, entry);
-}
-
-static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
-{
- const char *p = cmd;
- char **argv = NULL;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- pstring buf;
- TALLOC_CTX *mem_ctx = NULL;
- int argc = 0, i;
-
- /* Count number of arguments first time through the loop then
- allocate memory and strdup them. */
-
- again:
- while(next_token(&p, buf, " ", sizeof(buf))) {
- if (argv) {
- argv[argc] = strdup(buf);
- }
-
- argc++;
- }
-
- if (!argv) {
-
- /* Create argument list */
-
- argv = (char **)malloc(sizeof(char *) * argc);
- memset(argv, 0, sizeof(char *) * argc);
-
- if (!argv) {
- fprintf(stderr, "out of memory\n");
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- p = cmd;
- argc = 0;
-
- goto again;
- }
-
- /* Call the function */
-
- if (cmd_entry->fn) {
-
- if (mem_ctx == NULL) {
- /* Create mem_ctx */
- if (!(mem_ctx = talloc_init("do_cmd"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- goto done;
- }
- }
-
- /* Run command */
- result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv);
-
- } else {
- fprintf (stderr, "Invalid command\n");
- goto done;
- }
-
- done:
-
- /* Cleanup */
-
- if (argv) {
- for (i = 0; i < argc; i++)
- SAFE_FREE(argv[i]);
-
- SAFE_FREE(argv);
- }
-
- return result;
-}
-
-/* Process a command entered at the prompt or as part of -c */
-static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd)
-{
- struct cmd_list *temp_list;
- BOOL found = False;
- pstring buf;
- const char *p = cmd;
- NTSTATUS result = NT_STATUS_OK;
- int len = 0;
-
- if (cmd[strlen(cmd) - 1] == '\n')
- cmd[strlen(cmd) - 1] = '\0';
-
- if (!next_token(&p, buf, " ", sizeof(buf))) {
- return NT_STATUS_OK;
- }
-
- /* strip the trainly \n if it exsists */
- len = strlen(buf);
- if (buf[len-1] == '\n')
- buf[len-1] = '\0';
-
- /* Search for matching commands */
-
- for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
- struct cmd_set *temp_set = temp_list->cmd_set;
-
- while(temp_set->name) {
- if (strequal(buf, temp_set->name)) {
- found = True;
- result = do_cmd(vfs, temp_set, cmd);
-
- goto done;
- }
- temp_set++;
- }
- }
-
- done:
- if (!found && buf[0]) {
- printf("command not found: %s\n", buf);
- return NT_STATUS_OK;
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- printf("result was %s\n", nt_errstr(result));
- }
-
- return result;
-}
-
-static void process_file(struct vfs_state *pvfs, char *filename) {
- FILE *file;
- char command[3 * PATH_MAX];
-
- if (*filename == '-') {
- file = stdin;
- } else {
- file = fopen(filename, "r");
- if (file == NULL) {
- printf("vfstest: error reading file (%s)!", filename);
- printf("errno n.%d: %s", errno, strerror(errno));
- exit(-1);
- }
- }
-
- while (fgets(command, 3 * PATH_MAX, file) != NULL) {
- process_cmd(pvfs, command);
- }
-}
-
-void exit_server(const char *reason)
-{
- DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
- exit(0);
-}
-
-static int server_fd = -1;
-int last_message = -1;
-
-int smbd_server_fd(void)
-{
- return server_fd;
-}
-
-/****************************************************************************
- Reload the services file.
-**************************************************************************/
-
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
-
- if (lp_loaded()) {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname, NULL) &&
- !strcsequal(fname, dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE, fname);
- test = False;
- }
- }
-
- reopen_logs();
-
- if (test && !lp_file_list_changed())
- return(True);
-
- lp_killunused(conn_snum_used);
-
- ret = lp_load(dyn_CONFIGFILE, False, False, True);
-
- load_printers();
-
- /* perhaps the config filename is now set */
- if (!test)
- reload_services(True);
-
- reopen_logs();
-
- load_interfaces();
-
- {
- if (smbd_server_fd() != -1) {
- set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
- }
- }
-
- mangle_reset_cache();
- reset_stat_cache();
-
- /* this forces service parameters to be flushed */
- set_current_service(NULL,True);
-
- return (ret);
-}
-
-/* Main function */
-
-int main(int argc, char *argv[])
-{
- static char *cmdstr = NULL;
- struct cmd_set **cmd_set;
- static struct vfs_state vfs;
- int i;
- static char *filename = NULL;
-
- /* make sure the vars that get altered (4th field) are in
- a fixed location or certain compilers complain */
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"file", 'f', POPT_ARG_STRING, &filename, 0, },
- {"command", 'c', POPT_ARG_STRING, &cmdstr, 0, "Execute specified list of commands" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
-
-
- setlinebuf(stdout);
-
- pc = poptGetContext("vfstest", argc, (const char **) argv,
- long_options, 0);
-
- while(poptGetNextOpt(pc) != -1);
-
-
- poptFreeContext(pc);
-
- /* TODO: check output */
- reload_services(False);
-
- /* the following functions are part of the Samba debugging
- facilities. See lib/debug.c */
- setup_logging("vfstest", True);
-
- /* Load command lists */
-
- cmd_set = vfstest_command_list;
-
- while(*cmd_set) {
- add_command_set(*cmd_set);
- add_command_set(separator_command);
- cmd_set++;
- }
-
- /* some basic initialization stuff */
- sec_init();
- conn_init();
- vfs.conn = conn_new();
- string_set(&vfs.conn->user,"vfstest");
- for (i=0; i < 1024; i++)
- vfs.files[i] = NULL;
-
- /* some advanced initiliazation stuff */
- smbd_vfs_init(vfs.conn);
-
- /* Do we have a file input? */
- if (filename && filename[0]) {
- process_file(&vfs, filename);
- return 0;
- }
-
- /* Do anything specified with -c */
- if (cmdstr && cmdstr[0]) {
- char *cmd;
- char *p = cmdstr;
-
- while((cmd=next_command(&p)) != NULL) {
- process_cmd(&vfs, cmd);
- }
-
- return 0;
- }
-
- /* Loop around accepting commands */
-
- while(1) {
- pstring prompt;
- char *line;
-
- slprintf(prompt, sizeof(prompt) - 1, "vfstest $> ");
-
- line = smb_readline(prompt, NULL, completion_fn);
-
- if (line == NULL)
- break;
-
- if (line[0] != '\n')
- process_cmd(&vfs, line);
- }
-
- free(vfs.conn);
- return 0;
-}
diff --git a/source/torture/vfstest.h b/source/torture/vfstest.h
deleted file mode 100644
index 1e030fad047..00000000000
--- a/source/torture/vfstest.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- VFS module tester
-
- Copyright (C) Simo Sorce 2002
- Copyright (C) Eric Lorimer 2002
-
- Most of this code was ripped off of rpcclient.
- Copyright (C) Tim Potter 2000-2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-struct func_entry {
- char *name;
- int (*fn)(struct connection_struct *conn, const char *path);
-};
-
-struct vfs_state {
- struct connection_struct *conn;
- struct files_struct *files[1024];
- DIR *currentdir;
- void *data;
- size_t data_size;
-};
-
-struct cmd_set {
- const char *name;
- NTSTATUS (*fn)(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
- const char **argv);
- const char *description;
- const char *usage;
-};
diff --git a/source/utils/editreg.c b/source/utils/editreg.c
deleted file mode 100644
index a0cfa2bb07d..00000000000
--- a/source/utils/editreg.c
+++ /dev/null
@@ -1,4145 +0,0 @@
-/*
- Samba Unix/Linux SMB client utility editreg.c
- Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/*************************************************************************
-
- A utility to edit a Windows NT/2K etc registry file.
-
- Many of the ideas in here come from other people and software.
- I first looked in Wine in misc/registry.c and was also influenced by
- http://www.wednesday.demon.co.uk/dosreg.html
-
- Which seems to contain comments from someone else. I reproduce them here
- incase the site above disappears. It actually comes from
- http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt.
-
- The goal here is to read the registry into memory, manipulate it, and then
- write it out if it was changed by any actions of the user.
-
-The windows NT registry has 2 different blocks, where one can occur many
-times...
-
-the "regf"-Block
-================
-
-"regf" is obviosly the abbreviation for "Registry file". "regf" is the
-signature of the header-block which is always 4kb in size, although only
-the first 64 bytes seem to be used and a checksum is calculated over
-the first 0x200 bytes only!
-
-Offset Size Contents
-0x00000000 D-Word ID: ASCII-"regf" = 0x66676572
-0x00000004 D-Word ???? //see struct REGF
-0x00000008 D-Word ???? Always the same value as at 0x00000004
-0x0000000C Q-Word last modify date in WinNT date-format
-0x00000014 D-Word 1
-0x00000018 D-Word 3
-0x0000001C D-Word 0
-0x00000020 D-Word 1
-0x00000024 D-Word Offset of 1st key record
-0x00000028 D-Word Size of the data-blocks (Filesize-4kb)
-0x0000002C D-Word 1
-0x000001FC D-Word Sum of all D-Words from 0x00000000 to
-0x000001FB //XOR of all words. Nigel
-
-I have analyzed more registry files (from multiple machines running
-NT 4.0 german version) and could not find an explanation for the values
-marked with ???? the rest of the first 4kb page is not important...
-
-the "hbin"-Block
-================
-I don't know what "hbin" stands for, but this block is always a multiple
-of 4kb in size.
-
-Inside these hbin-blocks the different records are placed. The memory-
-management looks like a C-compiler heap management to me...
-
-hbin-Header
-===========
-Offset Size Contents
-0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268
-0x0004 D-Word Offset from the 1st hbin-Block
-0x0008 D-Word Offset to the next hbin-Block
-0x001C D-Word Block-size
-
-The values in 0x0008 and 0x001C should be the same, so I don't know
-if they are correct or swapped...
-
-From offset 0x0020 inside a hbin-block data is stored with the following
-format:
-
-Offset Size Contents
-0x0000 D-Word Data-block size //this size must be a
-multiple of 8. Nigel
-0x0004 ???? Data
-
-If the size field is negative (bit 31 set), the corresponding block
-is free and has a size of -blocksize!
-
-That does not seem to be true. All block lengths seem to be negative!
-(Richard Sharpe)
-
-The data is stored as one record per block. Block size is a multiple
-of 4 and the last block reaches the next hbin-block, leaving no room.
-
-(That also seems incorrect, in that the block size if a multiple of 8.
-That is, the block, including the 4 byte header, is always a multiple of
-8 bytes. Richard Sharpe.)
-
-Records in the hbin-blocks
-==========================
-
-nk-Record
-
- The nk-record can be treated as a kombination of tree-record and
- key-record of the win 95 registry.
-
-lf-Record
-
- The lf-record is the counterpart to the RGKN-record (the
- hash-function)
-
-vk-Record
-
- The vk-record consists information to a single value.
-
-sk-Record
-
- sk (? Security Key ?) is the ACL of the registry.
-
-Value-Lists
-
- The value-lists contain information about which values are inside a
- sub-key and don't have a header.
-
-Datas
-
- The datas of the registry are (like the value-list) stored without a
- header.
-
-All offset-values are relative to the first hbin-block and point to the
-block-size field of the record-entry. to get the file offset, you have to add
-the header size (4kb) and the size field (4 bytes)...
-
-the nk-Record
-=============
-Offset Size Contents
-0x0000 Word ID: ASCII-"nk" = 0x6B6E
-0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel
-0x0004 Q-Word write-date/time in windows nt notation
-0x0010 D-Word Offset of Owner/Parent key
-0x0014 D-Word number of sub-Keys
-0x001C D-Word Offset of the sub-key lf-Records
-0x0024 D-Word number of values
-0x0028 D-Word Offset of the Value-List
-0x002C D-Word Offset of the sk-Record
-
-0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel
-0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel
-0x0048 Word name-length
-0x004A Word class-name length
-0x004C ???? key-name
-
-the Value-List
-==============
-Offset Size Contents
-0x0000 D-Word Offset 1st Value
-0x0004 D-Word Offset 2nd Value
-0x???? D-Word Offset nth Value
-
-To determine the number of values, you have to look at the owner-nk-record!
-
-Der vk-Record
-=============
-Offset Size Contents
-0x0000 Word ID: ASCII-"vk" = 0x6B76
-0x0002 Word name length
-0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel
-0x0008 D-Word Offset of Data
-0x000C D-Word Type of value
-0x0010 Word Flag
-0x0012 Word Unused (data-trash)
-0x0014 ???? Name
-
-If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default)
-
-If the data-size is lower 5, the data-offset value is used to store the data itself!
-
-The data-types
-==============
-Wert Beteutung
-0x0001 RegSZ: character string (in UNICODE!)
-0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!)
-0x0003 RegBin: raw-binary value
-0x0004 RegDWord: Dword
-0x0007 RegMultiSZ: multiple strings, seperated with 0
- (UNICODE!)
-
-The "lf"-record
-===============
-Offset Size Contents
-0x0000 Word ID: ASCII-"lf" = 0x666C
-0x0002 Word number of keys
-0x0004 ???? Hash-Records
-
-Hash-Record
-===========
-Offset Size Contents
-0x0000 D-Word Offset of corresponding "nk"-Record
-0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv!
-
-Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the
-key-name you have to change the hash-value too!
-
-//These hashrecords must be sorted low to high within the lf record. Nigel.
-
-The "sk"-block
-==============
-(due to the complexity of the SAM-info, not clear jet)
-(This is just a self-relative security descriptor in the data. R Sharpe.)
-
-
-Offset Size Contents
-0x0000 Word ID: ASCII-"sk" = 0x6B73
-0x0002 Word Unused
-0x0004 D-Word Offset of previous "sk"-Record
-0x0008 D-Word Offset of next "sk"-Record
-0x000C D-Word usage-counter
-0x0010 D-Word Size of "sk"-record in bytes
-???? //standard self
-relative security desciptor. Nigel
-???? ???? Security and auditing settings...
-????
-
-The usage counter counts the number of references to this
-"sk"-record. You can use one "sk"-record for the entire registry!
-
-Windows nt date/time format
-===========================
-The time-format is a 64-bit integer which is incremented every
-0,0000001 seconds by 1 (I don't know how accurate it realy is!)
-It starts with 0 at the 1st of january 1601 0:00! All values are
-stored in GMT time! The time-zone is important to get the real
-time!
-
-Common values for win95 and win-nt
-==================================
-Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
-If a value has no name (length=0, flag(bit 0)=0), it is treated as the
-"Default" entry...
-If a value has no data (length=0), it is displayed as empty.
-
-simplyfied win-3.?? registry:
-=============================
-
-+-----------+
-| next rec. |---+ +----->+------------+
-| first sub | | | | Usage cnt. |
-| name | | +-->+------------+ | | length |
-| value | | | | next rec. | | | text |------->+-------+
-+-----------+ | | | name rec. |--+ +------------+ | xxxxx |
- +------------+ | | value rec. |-------->+------------+ +-------+
- v | +------------+ | Usage cnt. |
-+-----------+ | | length |
-| next rec. | | | text |------->+-------+
-| first sub |------+ +------------+ | xxxxx |
-| name | +-------+
-| value |
-+-----------+
-
-Greatly simplyfied structure of the nt-registry:
-================================================
-
-+---------------------------------------------------------------+
-| |
-v |
-+---------+ +---------->+-----------+ +----->+---------+ |
-| "nk" | | | lf-rec. | | | nk-rec. | |
-| ID | | | # of keys | | | parent |---+
-| Date | | | 1st key |--+ | .... |
-| parent | | +-----------+ +---------+
-| suk-keys|-----+
-| values |--------------------->+----------+
-| SK-rec. |---------------+ | 1. value |--> +----------+
-| class |--+ | +----------+ | vk-rec. |
-+---------+ | | | .... |
- v | | data |--> +-------+
- +------------+ | +----------+ | xxxxx |
- | Class name | | +-------+
- +------------+ |
- v
- +---------+ +---------+
- +----->| next sk |--->| Next sk |--+
- | +---| prev sk |<---| prev sk | |
- | | | .... | | ... | |
- | | +---------+ +---------+ |
- | | ^ |
- | | | |
- | +--------------------+ |
- +----------------------------------+
-
----------------------------------------------------------------------------
-
-Hope this helps.... (Although it was "fun" for me to uncover this things,
- it took me several sleepless nights ;)
-
- B.D.
-
-*************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <fcntl.h>
-
-#define False 0
-#define True 1
-#define REG_KEY_LIST_SIZE 10
-
-/*
- * Structures for dealing with the on-disk format of the registry
- */
-
-#define IVAL(buf) ((unsigned int) \
- (unsigned int)*((unsigned char *)(buf)+3)<<24| \
- (unsigned int)*((unsigned char *)(buf)+2)<<16| \
- (unsigned int)*((unsigned char *)(buf)+1)<<8| \
- (unsigned int)*((unsigned char *)(buf)+0))
-
-#define SVAL(buf) ((unsigned short) \
- (unsigned short)*((unsigned char *)(buf)+1)<<8| \
- (unsigned short)*((unsigned char *)(buf)+0))
-
-#define CVAL(buf) ((unsigned char)*((unsigned char *)(buf)))
-
-#define SIVAL(buf, val) \
- ((((unsigned char *)(buf))[0])=(unsigned char)((val)&0xFF),\
- (((unsigned char *)(buf))[1])=(unsigned char)(((val)>>8)&0xFF),\
- (((unsigned char *)(buf))[2])=(unsigned char)(((val)>>16)&0xFF),\
- (((unsigned char *)(buf))[3])=(unsigned char)((val)>>24))
-
-#define SSVAL(buf, val) \
- ((((unsigned char *)(buf))[0])=(unsigned char)((val)&0xFF),\
- (((unsigned char *)(buf))[1])=(unsigned char)((val)>>8))
-
-static int verbose = 0;
-static int print_security = 0;
-static int full_print = 0;
-static const char *def_owner_sid_str = NULL;
-
-/*
- * These definitions are for the in-memory registry structure.
- * It is a tree structure that mimics what you see with tools like regedit
- */
-
-/*
- * DateTime struct for Windows
- */
-
-typedef struct date_time_s {
- unsigned int low, high;
-} NTTIME;
-
-/*
- * Definition of a Key. It has a name, classname, date/time last modified,
- * sub-keys, values, and a security descriptor
- */
-
-#define REG_ROOT_KEY 1
-#define REG_SUB_KEY 2
-#define REG_SYM_LINK 3
-
-typedef struct key_sec_desc_s KEY_SEC_DESC;
-
-typedef struct reg_key_s {
- char *name; /* Name of the key */
- char *class_name;
- int type; /* One of REG_ROOT_KEY or REG_SUB_KEY */
- NTTIME last_mod; /* Time last modified */
- struct reg_key_s *owner;
- struct key_list_s *sub_keys;
- struct val_list_s *values;
- KEY_SEC_DESC *security;
- unsigned int offset; /* Offset of the record in the file */
-} REG_KEY;
-
-/*
- * The KEY_LIST struct lists sub-keys.
- */
-
-typedef struct key_list_s {
- int key_count;
- int max_keys;
- REG_KEY *keys[1];
-} KEY_LIST;
-
-typedef struct val_key_s {
- char *name;
- int has_name;
- int data_type;
- int data_len;
- void *data_blk; /* Might want a separate block */
-} VAL_KEY;
-
-typedef struct val_list_s {
- int val_count;
- int max_vals;
- VAL_KEY *vals[1];
-} VAL_LIST;
-
-#ifndef MAXSUBAUTHS
-#define MAXSUBAUTHS 15
-#endif
-
-typedef struct sid_s {
- unsigned char ver, auths;
- unsigned char auth[6];
- unsigned int sub_auths[MAXSUBAUTHS];
-} sid_t;
-
-typedef struct ace_struct_s {
- unsigned char type, flags;
- unsigned int perms; /* Perhaps a better def is in order */
- sid_t *trustee;
-} ACE;
-
-typedef struct acl_struct_s {
- unsigned short rev, refcnt;
- unsigned short num_aces;
- ACE *aces[1];
-} ACL;
-
-typedef struct sec_desc_s {
- unsigned int rev, type;
- sid_t *owner, *group;
- ACL *sacl, *dacl;
-} SEC_DESC;
-
-#define SEC_DESC_NON 0
-#define SEC_DESC_RES 1
-#define SEC_DESC_OCU 2
-#define SEC_DESC_NBK 3
-typedef struct sk_struct SK_HDR;
-struct key_sec_desc_s {
- struct key_sec_desc_s *prev, *next;
- int ref_cnt;
- int state;
- int offset;
- SK_HDR *sk_hdr; /* This means we must keep the registry in memory */
- SEC_DESC *sec_desc;
-};
-
-/*
- * All of the structures below actually have a four-byte length before them
- * which always seems to be negative. The following macro retrieves that
- * size as an integer
- */
-
-#define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1))
-
-typedef unsigned int DWORD;
-typedef unsigned short WORD;
-
-#define REG_REGF_ID 0x66676572
-
-typedef struct regf_block {
- DWORD REGF_ID; /* regf */
- DWORD uk1;
- DWORD uk2;
- DWORD tim1, tim2;
- DWORD uk3; /* 1 */
- DWORD uk4; /* 3 */
- DWORD uk5; /* 0 */
- DWORD uk6; /* 1 */
- DWORD first_key; /* offset */
- unsigned int dblk_size;
- DWORD uk7[116]; /* 1 */
- DWORD chksum;
-} REGF_HDR;
-
-typedef struct hbin_sub_struct {
- DWORD dblocksize;
- char data[1];
-} HBIN_SUB_HDR;
-
-#define REG_HBIN_ID 0x6E696268
-
-typedef struct hbin_struct {
- DWORD HBIN_ID; /* hbin */
- DWORD off_from_first;
- DWORD off_to_next;
- DWORD uk1;
- DWORD uk2;
- DWORD uk3;
- DWORD uk4;
- DWORD blk_size;
- HBIN_SUB_HDR hbin_sub_hdr;
-} HBIN_HDR;
-
-#define REG_NK_ID 0x6B6E
-
-typedef struct nk_struct {
- WORD NK_ID;
- WORD type;
- DWORD t1, t2;
- DWORD uk1;
- DWORD own_off;
- DWORD subk_num;
- DWORD uk2;
- DWORD lf_off;
- DWORD uk3;
- DWORD val_cnt;
- DWORD val_off;
- DWORD sk_off;
- DWORD clsnam_off;
- DWORD unk4[4];
- DWORD unk5;
- WORD nam_len;
- WORD clsnam_len;
- char key_nam[1]; /* Actual length determined by nam_len */
-} NK_HDR;
-
-#define REG_SK_ID 0x6B73
-
-struct sk_struct {
- WORD SK_ID;
- WORD uk1;
- DWORD prev_off;
- DWORD next_off;
- DWORD ref_cnt;
- DWORD rec_size;
- char sec_desc[1];
-};
-
-typedef struct ace_struct {
- unsigned char type;
- unsigned char flags;
- unsigned short length;
- unsigned int perms;
- sid_t trustee;
-} REG_ACE;
-
-typedef struct acl_struct {
- WORD rev;
- WORD size;
- DWORD num_aces;
- REG_ACE *aces; /* One or more ACEs */
-} REG_ACL;
-
-typedef struct sec_desc_rec {
- WORD rev;
- WORD type;
- DWORD owner_off;
- DWORD group_off;
- DWORD sacl_off;
- DWORD dacl_off;
-} REG_SEC_DESC;
-
-typedef struct hash_struct {
- DWORD nk_off;
- char hash[4];
-} HASH_REC;
-
-#define REG_LF_ID 0x666C
-
-typedef struct lf_struct {
- WORD LF_ID;
- WORD key_count;
- struct hash_struct hr[1]; /* Array of hash records, depending on key_count */
-} LF_HDR;
-
-typedef DWORD VL_TYPE[1]; /* Value list is an array of vk rec offsets */
-
-#define REG_VK_ID 0x6B76
-
-typedef struct vk_struct {
- WORD VK_ID;
- WORD nam_len;
- DWORD dat_len; /* If top-bit set, offset contains the data */
- DWORD dat_off;
- DWORD dat_type;
- WORD flag; /* =1, has name, else no name (=Default). */
- WORD unk1;
- char dat_name[1]; /* Name starts here ... */
-} VK_HDR;
-
-#define REG_TYPE_DELETE -1
-#define REG_TYPE_NONE 0
-#define REG_TYPE_REGSZ 1
-#define REG_TYPE_EXPANDSZ 2
-#define REG_TYPE_BIN 3
-#define REG_TYPE_DWORD 4
-#define REG_TYPE_MULTISZ 7
-
-typedef struct _val_str {
- unsigned int val;
- const char * str;
-} VAL_STR;
-
-/* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */
-typedef struct sk_map_s {
- int sk_off;
- KEY_SEC_DESC *key_sec_desc;
-} SK_MAP;
-
-/*
- * This structure keeps track of the output format of the registry
- */
-#define REG_OUTBLK_HDR 1
-#define REG_OUTBLK_HBIN 2
-
-typedef struct hbin_blk_s {
- int type, size;
- struct hbin_blk_s *next;
- char *data; /* The data block */
- unsigned int file_offset; /* Offset in file */
- unsigned int free_space; /* Amount of free space in block */
- unsigned int fsp_off; /* Start of free space in block */
- int complete, stored;
-} HBIN_BLK;
-
-/*
- * This structure keeps all the registry stuff in one place
- */
-typedef struct regf_struct_s {
- int reg_type;
- char *regfile_name, *outfile_name;
- int fd;
- struct stat sbuf;
- char *base;
- int modified;
- NTTIME last_mod_time;
- REG_KEY *root; /* Root of the tree for this file */
- int sk_count, sk_map_size;
- SK_MAP *sk_map;
- const char *owner_sid_str;
- SEC_DESC *def_sec_desc;
- /*
- * These next pointers point to the blocks used to contain the
- * keys when we are preparing to write them to a file
- */
- HBIN_BLK *blk_head, *blk_tail, *free_space;
-} REGF;
-
-/*
- * An API for accessing/creating/destroying items above
- */
-
-/*
- * Iterate over the keys, depth first, calling a function for each key
- * and indicating if it is terminal or non-terminal and if it has values.
- *
- * In addition, for each value in the list, call a value list function
- */
-
-typedef int (*key_print_f)(const char *path, char *key_name, char *class_name,
- int root, int terminal, int values);
-
-typedef int (*val_print_f)(const char *path, char *val_name, int val_type,
- int data_len, void *data_blk, int terminal,
- int first, int last);
-
-typedef int (*sec_print_f)(SEC_DESC *sec_desc);
-
-static
-int nt_key_iterator(REGF *regf, REG_KEY *key_tree, int bf, const char *path,
- key_print_f key_print, sec_print_f sec_print,
- val_print_f val_print);
-
-static
-int nt_val_list_iterator(REGF *regf, VAL_LIST *val_list, int bf, char *path,
- int terminal, val_print_f val_print)
-{
- int i;
-
- if (!val_list) return 1;
-
- if (!val_print) return 1;
-
- for (i=0; i<val_list->val_count; i++) {
- if (!val_print(path, val_list->vals[i]->name, val_list->vals[i]->data_type,
- val_list->vals[i]->data_len, val_list->vals[i]->data_blk,
- terminal,
- (i == 0),
- (i == val_list->val_count))) {
-
- return 0;
-
- }
- }
-
- return 1;
-}
-
-static
-int nt_key_list_iterator(REGF *regf, KEY_LIST *key_list, int bf,
- const char *path,
- key_print_f key_print, sec_print_f sec_print,
- val_print_f val_print)
-{
- int i;
-
- if (!key_list) return 1;
-
- for (i=0; i< key_list->key_count; i++) {
- if (!nt_key_iterator(regf, key_list->keys[i], bf, path, key_print,
- sec_print, val_print)) {
- return 0;
- }
- }
- return 1;
-}
-
-static
-int nt_key_iterator(REGF *regf, REG_KEY *key_tree, int bf, const char *path,
- key_print_f key_print, sec_print_f sec_print,
- val_print_f val_print)
-{
- int path_len = strlen(path);
- char *new_path;
-
- if (!regf || !key_tree)
- return -1;
-
- /* List the key first, then the values, then the sub-keys */
-
- if (key_print) {
-
- if (!(*key_print)(path, key_tree->name,
- key_tree->class_name,
- (key_tree->type == REG_ROOT_KEY),
- (key_tree->sub_keys == NULL),
- (key_tree->values?(key_tree->values->val_count):0)))
- return 0;
- }
-
- /*
- * If we have a security print routine, call it
- * If the security print routine returns false, stop.
- */
- if (sec_print) {
- if (key_tree->security && !(*sec_print)(key_tree->security->sec_desc))
- return 0;
- }
-
- new_path = (char *)malloc(path_len + 1 + strlen(key_tree->name) + 1);
- if (!new_path) return 0; /* Errors? */
- new_path[0] = '\0';
- strcat(new_path, path);
- strcat(new_path, key_tree->name);
- strcat(new_path, "\\");
-
- /*
- * Now, iterate through the values in the val_list
- */
-
- if (key_tree->values &&
- !nt_val_list_iterator(regf, key_tree->values, bf, new_path,
- (key_tree->values!=NULL),
- val_print)) {
-
- free(new_path);
- return 0;
- }
-
- /*
- * Now, iterate through the keys in the key list
- */
-
- if (key_tree->sub_keys &&
- !nt_key_list_iterator(regf, key_tree->sub_keys, bf, new_path, key_print,
- sec_print, val_print)) {
- free(new_path);
- return 0;
- }
-
- free(new_path);
- return 1;
-}
-
-static
-REG_KEY *nt_find_key_by_name(REG_KEY *tree, char *key);
-
-/*
- * Find key by name in a list ...
- * Take the first component and search for that in the list
- */
-static
-REG_KEY *nt_find_key_in_list_by_name(KEY_LIST *list, char *key)
-{
- int i;
- REG_KEY *res = NULL;
-
- if (!list || !key || !*key) return NULL;
-
- for (i = 0; i < list->key_count; i++)
- if ((res = nt_find_key_by_name(list->keys[i], key)))
- return res;
-
- return NULL;
-}
-
-/*
- * Find key by name in a tree ... We will assume absolute names here, but we
- * need the root of the tree ...
- */
-static
-REG_KEY *nt_find_key_by_name(REG_KEY *tree, char *key)
-{
- char *lname = NULL, *c1, *c2;
- REG_KEY *tmp;
-
- if (!tree || !key || !*key) return NULL;
-
- lname = strdup(key);
- if (!lname) return NULL;
-
- /*
- * Make sure that the first component is correct ...
- */
- c1 = lname;
- c2 = strchr(c1, '\\');
- if (c2) { /* Split here ... */
- *c2 = 0;
- c2++;
- }
- if (strcmp(c1, tree->name) != 0) goto error;
-
- if (c2) {
- tmp = nt_find_key_in_list_by_name(tree->sub_keys, c2);
- free(lname);
- return tmp;
- }
- else {
- if (lname) free(lname);
- return tree;
- }
- error:
- if (lname) free(lname);
- return NULL;
-}
-
-/* Make, delete keys */
-static
-int nt_delete_val_key(VAL_KEY *val_key)
-{
-
- if (val_key) {
- if (val_key->name) free(val_key->name);
- if (val_key->data_blk) free(val_key->data_blk);
- free(val_key);
- };
- return 1;
-}
-
-static
-int nt_delete_val_list(VAL_LIST *vl)
-{
- int i;
-
- if (vl) {
- for (i=0; i<vl->val_count; i++)
- nt_delete_val_key(vl->vals[i]);
- free(vl);
- }
- return 1;
-}
-
-static
-int nt_delete_reg_key(REG_KEY *key, int delete_name);
-
-static
-int nt_delete_key_list(KEY_LIST *key_list, int delete_name)
-{
- int i;
-
- if (key_list) {
- for (i=0; i<key_list->key_count; i++)
- nt_delete_reg_key(key_list->keys[i], False);
- free(key_list);
- }
- return 1;
-}
-
-/*
- * Find the key, and if it exists, delete it ...
- */
-static
-int nt_delete_key_by_name(REGF *regf, char *name)
-{
- REG_KEY *key;
-
- if (!name || !*name) return 0;
-
- key = nt_find_key_by_name(regf->root, name);
-
- if (key) {
- if (key == regf->root) regf->root = NULL;
- return nt_delete_reg_key(key, True);
- }
-
- return 0;
-
-}
-
-static
-int nt_delete_sid(sid_t *sid)
-{
-
- if (sid) free(sid);
- return 1;
-
-}
-
-static
-int nt_delete_ace(ACE *ace)
-{
-
- if (ace) {
- nt_delete_sid(ace->trustee);
- free(ace);
- }
- return 1;
-
-}
-
-static
-int nt_delete_acl(ACL *acl)
-{
-
- if (acl) {
- int i;
-
- for (i=0; i<acl->num_aces; i++)
- nt_delete_ace(acl->aces[i]);
-
- free(acl);
- }
- return 1;
-}
-
-static
-int nt_delete_sec_desc(SEC_DESC *sec_desc)
-{
-
- if (sec_desc) {
-
- nt_delete_sid(sec_desc->owner);
- nt_delete_sid(sec_desc->group);
- nt_delete_acl(sec_desc->sacl);
- nt_delete_acl(sec_desc->dacl);
- free(sec_desc);
-
- }
- return 1;
-}
-
-static
-int nt_delete_key_sec_desc(KEY_SEC_DESC *key_sec_desc)
-{
-
- if (key_sec_desc) {
- key_sec_desc->ref_cnt--;
- if (key_sec_desc->ref_cnt<=0) {
- /*
- * There should always be a next and prev, even if they point to us
- */
- key_sec_desc->next->prev = key_sec_desc->prev;
- key_sec_desc->prev->next = key_sec_desc->next;
- nt_delete_sec_desc(key_sec_desc->sec_desc);
- }
- }
- return 1;
-}
-
-static
-int nt_delete_reg_key(REG_KEY *key, int delete_name)
-{
-
- if (key) {
- if (key->name) free(key->name);
- if (key->class_name) free(key->class_name);
-
- /*
- * We will delete the owner if we are not the root and told to ...
- */
-
- if (key->owner && key->owner->sub_keys && delete_name) {
- REG_KEY *own;
- KEY_LIST *kl;
- int i;
- /* Find our owner, look in keylist for us and shuffle up */
- /* Perhaps should be a function */
-
- own = key->owner;
- kl = own->sub_keys;
-
- for (i=0; i < kl->key_count && kl->keys[i] != key ; i++) {
- /* Just find the entry ... */
- }
-
- if (i == kl->key_count) {
- fprintf(stderr, "Bad data structure. Key not found in key list of owner\n");
- }
- else {
- int j;
-
- /*
- * Shuffle up. Works for the last one also
- */
- for (j = i + 1; j < kl->key_count; j++) {
- kl->keys[j - 1] = kl->keys[j];
- }
-
- kl->key_count--;
- }
- }
-
- if (key->sub_keys) nt_delete_key_list(key->sub_keys, False);
- if (key->values) nt_delete_val_list(key->values);
- if (key->security) nt_delete_key_sec_desc(key->security);
- free(key);
- }
- return 1;
-}
-
-/*
- * Convert a string to a value ...
- * FIXME: Error handling and convert this at command parse time ...
- */
-static
-void *str_to_val(int type, char *val, int *len)
-{
- unsigned int *dwordp = NULL;
-
- if (!len || !val) return NULL;
-
- switch (type) {
- case REG_TYPE_REGSZ:
- *len = strlen(val);
- return (void *)val;
-
- case REG_TYPE_DWORD:
- dwordp = (unsigned int *)malloc(sizeof(unsigned int));
- if (!dwordp) return NULL;
- /* Allow for ddddd and 0xhhhhh and 0ooooo */
- if (strncmp(val, "0x", 2) == 0 || strncmp(val, "0X", 2) == 0) {
- sscanf(&val[2], "%X", dwordp);
- }
- else if (*val == '0') {
- sscanf(&val[1], "%o", dwordp);
- }
- else {
- sscanf(val, "%d", dwordp);
- }
- *len = sizeof(unsigned int);
- return (void *)dwordp;
-
- /* FIXME: Implement more of these */
-
- default:
- return NULL;
- }
-
- return NULL;
-}
-
-/*
- * Add a value to the key specified ... We have to parse the value some more
- * based on the type to get it in the correct internal form
- * An empty name will be converted to "<No Name>" before here
- * Hmmm, maybe not. has_name is for that
- */
-static
-VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
-{
- int i;
- VAL_KEY *tmp = NULL;
-
- if (!key || !key->values || !name || !*name) return NULL;
-
- assert(type != REG_TYPE_DELETE); /* We never process deletes here */
-
- for (i = 0; i < key->values->val_count; i++) {
- if ((!key->values->vals[i]->has_name && !*name) ||
- (key->values->vals[i]->has_name &&
- strcmp(name, key->values->vals[i]->name) == 0)){ /* Change the value */
- free(key->values->vals[i]->data_blk);
- key->values->vals[i]->data_blk = str_to_val(type, value, &
- key->values->vals[i]->data_len);
- return key->values->vals[i];
- }
- }
-
- /*
- * If we get here, the name was not found, so insert it
- */
-
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
- if (!tmp) goto error;
-
- memset(tmp, 0, sizeof(VAL_KEY));
- tmp->name = strdup(name);
- tmp->has_name = True;
- if (!tmp->name) goto error;
- tmp->data_type = type;
- tmp->data_blk = str_to_val(type, value, &tmp->data_len);
-
- /* Now, add to val list */
-
- if (key->values->val_count >= key->values->max_vals) {
- /*
- * Allocate some more space
- */
-
- if ((key->values = (VAL_LIST *)realloc(key->values, sizeof(VAL_LIST) +
- key->values->val_count - 1 +
- REG_KEY_LIST_SIZE))) {
- key->values->max_vals += REG_KEY_LIST_SIZE;
- }
- else goto error;
- }
-
- i = key->values->val_count;
- key->values->val_count++;
- key->values->vals[i] = tmp;
- return tmp;
-
- error:
- if (tmp) nt_delete_val_key(tmp);
- return NULL;
-}
-
-/*
- * Delete a value. We return the value and let the caller deal with it.
- */
-static
-VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name)
-{
- int i, j;
-
- if (!key || !key->values || !name || !*name) return NULL;
-
- /* FIXME: Allow empty value name */
- for (i = 0; i< key->values->val_count; i++) {
- if ((!key->values->vals[i]->has_name && !*name) ||
- (key->values->vals[i]->has_name &&
- strcmp(name, key->values->vals[i]->name) == 0)) {
- VAL_KEY *val;
-
- val = key->values->vals[i];
-
- /* Shuffle down */
- for (j = i + 1; j < key->values->val_count; j++)
- key->values->vals[j - 1] = key->values->vals[j];
-
- key->values->val_count--;
-
- return val;
- }
- }
- return NULL;
-}
-
-/*
- * Add a key to the tree ... We walk down the components matching until
- * we don't find any. There must be a match on the first component ...
- * We return the key structure for the final component as that is
- * often where we want to add values ...
- */
-
-/*
- * Convert a string of the form S-1-5-x[-y-z-r] to a SID
- */
-static
-int sid_string_to_sid(sid_t **sid, const char *sid_str)
-{
- int i = 0, auth;
- const char *lstr;
-
- *sid = (sid_t *)malloc(sizeof(sid_t));
- if (!*sid) return 0;
-
- memset(*sid, 0, sizeof(sid_t));
-
- if (strncmp(sid_str, "S-1-5", 5)) {
- fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str);
- return 0;
- }
-
- /* We only allow strings of form S-1-5... */
-
- (*sid)->ver = 1;
- (*sid)->auth[5] = 5;
-
- lstr = sid_str + 5;
-
- while (1) {
- if (!lstr || !lstr[0] || sscanf(lstr, "-%u", &auth) == 0) {
- if (i < 1) {
- fprintf(stderr, "Not of form -d-d...: %s, %u\n", lstr, i);
- return 0;
- }
- (*sid)->auths=i;
- return 1;
- }
-
- (*sid)->sub_auths[i] = auth;
- i++;
- lstr = strchr(lstr + 1, '-');
- }
-
- /*return 1; */ /* Not Reached ... */
-}
-
-/*
- * Create an ACE
- */
-static
-ACE *nt_create_ace(int type, int flags, unsigned int perms, const char *sid)
-{
- ACE *ace;
-
- ace = (ACE *)malloc(sizeof(ACE));
- if (!ace) goto error;
- ace->type = type;
- ace->flags = flags;
- ace->perms = perms;
- if (!sid_string_to_sid(&ace->trustee, sid))
- goto error;
- return ace;
-
- error:
- if (ace) nt_delete_ace(ace);
- return NULL;
-}
-
-/*
- * Create a default ACL
- */
-static
-ACL *nt_create_default_acl(REGF *regf)
-{
- ACL *acl;
-
- acl = (ACL *)malloc(sizeof(ACL) + 7*sizeof(ACE *));
- if (!acl) goto error;
-
- acl->rev = 2;
- acl->refcnt = 1;
- acl->num_aces = 8;
-
- acl->aces[0] = nt_create_ace(0x00, 0x0, 0xF003F, regf->owner_sid_str);
- if (!acl->aces[0]) goto error;
- acl->aces[1] = nt_create_ace(0x00, 0x0, 0xF003F, "S-1-5-18");
- if (!acl->aces[1]) goto error;
- acl->aces[2] = nt_create_ace(0x00, 0x0, 0xF003F, "S-1-5-32-544");
- if (!acl->aces[2]) goto error;
- acl->aces[3] = nt_create_ace(0x00, 0x0, 0x20019, "S-1-5-12");
- if (!acl->aces[3]) goto error;
- acl->aces[4] = nt_create_ace(0x00, 0x0B, 0x10000000, regf->owner_sid_str);
- if (!acl->aces[4]) goto error;
- acl->aces[5] = nt_create_ace(0x00, 0x0B, 0x10000000, "S-1-5-18");
- if (!acl->aces[5]) goto error;
- acl->aces[6] = nt_create_ace(0x00, 0x0B, 0x10000000, "S-1-5-32-544");
- if (!acl->aces[6]) goto error;
- acl->aces[7] = nt_create_ace(0x00, 0x0B, 0x80000000, "S-1-5-12");
- if (!acl->aces[7]) goto error;
- return acl;
-
- error:
- if (acl) nt_delete_acl(acl);
- return NULL;
-}
-
-/*
- * Create a default security descriptor. We pull in things from env
- * if need be
- */
-static
-SEC_DESC *nt_create_def_sec_desc(REGF *regf)
-{
- SEC_DESC *tmp;
-
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
- if (!tmp) return NULL;
-
- tmp->rev = 1;
- tmp->type = 0x8004;
- if (!sid_string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error;
- if (!sid_string_to_sid(&tmp->group, "S-1-5-18")) goto error;
- tmp->sacl = NULL;
- tmp->dacl = nt_create_default_acl(regf);
-
- return tmp;
-
- error:
- if (tmp) nt_delete_sec_desc(tmp);
- return NULL;
-}
-
-/*
- * We will implement inheritence that is based on what the parent's SEC_DESC
- * says, but the Owner and Group SIDs can be overwridden from the command line
- * and additional ACEs can be applied from the command line etc.
- */
-static
-KEY_SEC_DESC *nt_inherit_security(REG_KEY *key)
-{
-
- if (!key) return NULL;
- return key->security;
-}
-
-/*
- * Create an initial security descriptor and init other structures, if needed
- * We assume that the initial security stuff is empty ...
- */
-static
-KEY_SEC_DESC *nt_create_init_sec(REGF *regf)
-{
- KEY_SEC_DESC *tsec = NULL;
-
- tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
- if (!tsec) return NULL;
-
- tsec->ref_cnt = 1;
- tsec->state = SEC_DESC_NBK;
- tsec->offset = 0;
-
- tsec->sec_desc = regf->def_sec_desc;
-
- return tsec;
-}
-
-/*
- * Add a sub-key
- */
-static
-REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create)
-{
- int i;
- REG_KEY *ret = NULL, *tmp = NULL;
- KEY_LIST *list;
- char *lname, *c1, *c2;
-
- if (!key || !name || !*name) return NULL;
-
- list = key->sub_keys;
- if (!list) { /* Create an empty list */
-
- list = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *));
- list->key_count = 0;
- list->max_keys = REG_KEY_LIST_SIZE;
-
- }
-
- lname = strdup(name);
- if (!lname) return NULL;
-
- c1 = lname;
- c2 = strchr(c1, '\\');
- if (c2) { /* Split here ... */
- *c2 = 0;
- c2++;
- }
-
- for (i = 0; i < list->key_count; i++) {
- if (strcmp(list->keys[i]->name, c1) == 0) {
- ret = nt_add_reg_key_list(regf, list->keys[i], c2, create);
- free(lname);
- return ret;
- }
- }
-
- /*
- * If we reach here we could not find the the first component
- * so create it ...
- */
-
- if (list->key_count < list->max_keys){
- list->key_count++;
- }
- else { /* Create more space in the list ... */
- if (!(list = (KEY_LIST *)realloc(list, sizeof(KEY_LIST) +
- (list->max_keys + REG_KEY_LIST_SIZE - 1)
- * sizeof(REG_KEY *))))
- goto error;
-
- list->max_keys += REG_KEY_LIST_SIZE;
- list->key_count++;
- }
-
- /*
- * add the new key at the new slot
- * FIXME: Sort the list someday
- */
-
- /*
- * We want to create the key, and then do the rest
- */
-
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
-
- memset(tmp, 0, sizeof(REG_KEY));
-
- tmp->name = strdup(c1);
- if (!tmp->name) goto error;
- tmp->owner = key;
- tmp->type = REG_SUB_KEY;
- /*
- * Next, pull security from the parent, but override with
- * anything passed in on the command line
- */
- tmp->security = nt_inherit_security(key);
-
- list->keys[list->key_count - 1] = tmp;
-
- if (c2) {
- ret = nt_add_reg_key_list(regf, key, c2, True);
- }
-
- if (lname) free(lname);
-
- return ret;
-
- error:
- if (tmp) free(tmp);
- if (lname) free(lname);
- return NULL;
-}
-
-/*
- * This routine only adds a key from the root down.
- * It calls helper functions to handle sub-key lists and sub-keys
- */
-static
-REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create)
-{
- char *lname = NULL, *c1, *c2;
- REG_KEY * tmp = NULL;
-
- /*
- * Look until we hit the first component that does not exist, and
- * then add from there. However, if the first component does not
- * match and the path we are given is the root, then it must match
- */
- if (!regf || !name || !*name) return NULL;
-
- lname = strdup(name);
- if (!lname) return NULL;
-
- c1 = lname;
- c2 = strchr(c1, '\\');
- if (c2) { /* Split here ... */
- *c2 = 0;
- c2++;
- }
-
- /*
- * If the root does not exist, create it and make it equal to the
- * first component ...
- */
-
- if (!regf->root) {
-
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
- if (!tmp) goto error;
- memset(tmp, 0, sizeof(REG_KEY));
- tmp->name = strdup(c1);
- if (!tmp->name) goto error;
- tmp->security = nt_create_init_sec(regf);
- if (!tmp->security) goto error;
- regf->root = tmp;
-
- }
- else {
- /*
- * If we don't match, then we have to return error ...
- * If we do match on this component, check the next one in the
- * list, and if not found, add it ... short circuit, add all the
- * way down
- */
-
- if (strcmp(c1, regf->root->name) != 0)
- goto error;
- }
-
- tmp = nt_add_reg_key_list(regf, regf->root, c2, True);
- free(lname);
- return tmp;
-
- error:
- if (tmp) free(tmp);
- if (lname) free(lname);
- return NULL;
-}
-
-/*
- * Load and unload a registry file.
- *
- * Load, loads it into memory as a tree, while unload sealizes/flattens it
- */
-
-/*
- * Get the starting record for NT Registry file
- */
-
-/*
- * Where we keep all the regf stuff for one registry.
- * This is the structure that we use to tie the in memory tree etc
- * together. By keeping separate structs, we can operate on different
- * registries at the same time.
- * Currently, the SK_MAP is an array of mapping structure.
- * Since we only need this on input and output, we fill in the structure
- * as we go on input. On output, we know how many SK items we have, so
- * we can allocate the structure as we need to.
- * If you add stuff here that is dynamically allocated, add the
- * appropriate free statements below.
- */
-
-#define REGF_REGTYPE_NONE 0
-#define REGF_REGTYPE_NT 1
-#define REGF_REGTYPE_W9X 2
-
-#define TTTONTTIME(r, t1, t2) (r)->last_mod_time.low = (t1); \
- (r)->last_mod_time.high = (t2);
-
-#define REGF_HDR_BLKSIZ 0x1000
-
-#define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4)
-#define LOCN(base, f) ((base) + OFF(f))
-
-const VAL_STR reg_type_names[] = {
- { REG_TYPE_REGSZ, "REG_SZ" },
- { REG_TYPE_EXPANDSZ, "REG_EXPAND_SZ" },
- { REG_TYPE_BIN, "REG_BIN" },
- { REG_TYPE_DWORD, "REG_DWORD" },
- { REG_TYPE_MULTISZ, "REG_MULTI_SZ" },
- { 0, NULL },
-};
-
-static
-const char *val_to_str(unsigned int val, const VAL_STR *val_array)
-{
- int i = 0;
-
- if (!val_array) return NULL;
-
- while (val_array[i].val && val_array[i].str) {
-
- if (val_array[i].val == val) return val_array[i].str;
- i++;
-
- }
-
- return NULL;
-
-}
-
-/*
- * Convert from UniCode to Ascii ... Does not take into account other lang
- * Restrict by ascii_max if > 0
- */
-static
-int uni_to_ascii(unsigned char *uni, unsigned char *ascii, int ascii_max,
- int uni_max)
-{
- int i = 0;
-
- while (i < ascii_max && !(!uni[i*2] && !uni[i*2+1])) {
- if (uni_max > 0 && (i*2) >= uni_max) break;
- ascii[i] = uni[i*2];
- i++;
-
- }
-
- ascii[i] = '\0';
-
- return i;
-}
-
-/*
- * Convert a data value to a string for display
- */
-static
-int data_to_ascii(unsigned char *datap, int len, int type, char *ascii, int ascii_max)
-{
- unsigned char *asciip;
- int i;
-
- switch (type) {
- case REG_TYPE_REGSZ:
- if (verbose) fprintf(stderr, "Len: %d\n", len);
- /* FIXME. This has to be fixed. It has to be UNICODE */
- return uni_to_ascii(datap, ascii, len, ascii_max);
- break; /*NOTREACHED*/
-
- case REG_TYPE_EXPANDSZ:
- return uni_to_ascii(datap, ascii, len, ascii_max);
- break;
-
- case REG_TYPE_BIN:
- asciip = ascii;
- for (i=0; (i<len)&&(i+1)*3<ascii_max; i++) {
- int str_rem = ascii_max - ((int)asciip - (int)ascii);
- asciip += snprintf(asciip, str_rem, "%02x", *(unsigned char *)(datap+i));
- if (i < len && str_rem > 0)
- *asciip = ' '; asciip++;
- }
- *asciip = '\0';
- return ((int)asciip - (int)ascii);
- break;
-
- case REG_TYPE_DWORD:
- if (*(int *)datap == 0)
- return snprintf(ascii, ascii_max, "0");
- else
- return snprintf(ascii, ascii_max, "0x%x", *(int *)datap);
- break;
-
- case REG_TYPE_MULTISZ:
-
- break;
-
- default:
- return 0;
- break;
- }
-
- return len;
-
-}
-
-static
-REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent);
-
-static
-int nt_set_regf_input_file(REGF *regf, char *filename)
-{
- return ((regf->regfile_name = strdup(filename)) != NULL);
-}
-
-static
-int nt_set_regf_output_file(REGF *regf, char *filename)
-{
- return ((regf->outfile_name = strdup(filename)) != NULL);
-}
-
-/* Create a regf structure and init it */
-
-static
-REGF *nt_create_regf(void)
-{
- REGF *tmp = (REGF *)malloc(sizeof(REGF));
- if (!tmp) return tmp;
- memset(tmp, 0, sizeof(REGF));
- tmp->owner_sid_str = def_owner_sid_str;
- return tmp;
-}
-
-/* Free all the bits and pieces ... Assumes regf was malloc'd */
-/* If you add stuff to REGF, add the relevant free bits here */
-static
-int nt_free_regf(REGF *regf)
-{
- if (!regf) return 0;
-
- if (regf->regfile_name) free(regf->regfile_name);
- if (regf->outfile_name) free(regf->outfile_name);
-
- nt_delete_reg_key(regf->root, False); /* Free the tree */
- free(regf->sk_map);
- regf->sk_count = regf->sk_map_size = 0;
-
- free(regf);
-
- return 1;
-}
-
-/* Get the header of the registry. Return a pointer to the structure
- * If the mmap'd area has not been allocated, then mmap the input file
- */
-static
-REGF_HDR *nt_get_regf_hdr(REGF *regf)
-{
- if (!regf)
- return NULL; /* What about errors */
-
- if (!regf->regfile_name)
- return NULL; /* What about errors */
-
- if (!regf->base) { /* Try to mmap etc the file */
-
- if ((regf->fd = open(regf->regfile_name, O_RDONLY, 0000)) <0) {
- return NULL; /* What about errors? */
- }
-
- if (fstat(regf->fd, &regf->sbuf) < 0) {
- return NULL;
- }
-
- regf->base = mmap(0, regf->sbuf.st_size, PROT_READ, MAP_SHARED, regf->fd, 0);
-
- if ((int)regf->base == 1) {
- fprintf(stderr, "Could not mmap file: %s, %s\n", regf->regfile_name,
- strerror(errno));
- return NULL;
- }
- }
-
- /*
- * At this point, regf->base != NULL, and we should be able to read the
- * header
- */
-
- assert(regf->base != NULL);
-
- return (REGF_HDR *)regf->base;
-}
-
-/*
- * Validate a regf header
- * For now, do nothing, but we should check the checksum
- */
-static
-int valid_regf_hdr(REGF_HDR *regf_hdr)
-{
- if (!regf_hdr) return 0;
-
- return 1;
-}
-
-/*
- * Process an SK header ...
- * Every time we see a new one, add it to the map. Otherwise, just look it up.
- * We will do a simple linear search for the moment, since many KEYs have the
- * same security descriptor.
- * We allocate the map in increments of 10 entries.
- */
-
-/*
- * Create a new entry in the map, and increase the size of the map if needed
- */
-static
-SK_MAP *alloc_sk_map_entry(REGF *regf, KEY_SEC_DESC *tmp, int sk_off)
-{
- if (!regf->sk_map) { /* Allocate a block of 10 */
- regf->sk_map = (SK_MAP *)malloc(sizeof(SK_MAP) * 10);
- if (!regf->sk_map) {
- free(tmp);
- return NULL;
- }
- regf->sk_map_size = 10;
- regf->sk_count = 1;
- (regf->sk_map)[0].sk_off = sk_off;
- (regf->sk_map)[0].key_sec_desc = tmp;
- }
- else { /* Simply allocate a new slot, unless we have to expand the list */
- int ndx = regf->sk_count;
- if (regf->sk_count >= regf->sk_map_size) {
- regf->sk_map = (SK_MAP *)realloc(regf->sk_map,
- (regf->sk_map_size + 10)*sizeof(SK_MAP));
- if (!regf->sk_map) {
- free(tmp);
- return NULL;
- }
- /*
- * ndx already points at the first entry of the new block
- */
- regf->sk_map_size += 10;
- }
- (regf->sk_map)[ndx].sk_off = sk_off;
- (regf->sk_map)[ndx].key_sec_desc = tmp;
- regf->sk_count++;
- }
- return regf->sk_map;
-}
-
-/*
- * Search for a KEY_SEC_DESC in the sk_map, but don't create one if not
- * found
- */
-static
-KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off)
-{
- int i;
-
- if (!sk_map) return NULL;
-
- for (i = 0; i < count; i++) {
-
- if (sk_map[i].sk_off == sk_off)
- return sk_map[i].key_sec_desc;
-
- }
-
- return NULL;
-
-}
-
-/*
- * Allocate a KEY_SEC_DESC if we can't find one in the map
- */
-static
-KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
-{
- KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off);
-
- if (tmp) {
- return tmp;
- }
- else { /* Allocate a new one */
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
- if (!tmp) {
- return NULL;
- }
- memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */
- tmp->state = SEC_DESC_RES;
- if (!alloc_sk_map_entry(regf, tmp, sk_off)) {
- return NULL;
- }
- return tmp;
- }
-}
-
-/*
- * Allocate storage and duplicate a SID
- * We could allocate the SID to be only the size needed, but I am too lazy.
- */
-static
-sid_t *dup_sid(sid_t *sid)
-{
- sid_t *tmp = (sid_t *)malloc(sizeof(sid_t));
- int i;
-
- if (!tmp) return NULL;
- tmp->ver = sid->ver;
- tmp->auths = sid->auths;
- for (i=0; i<6; i++) {
- tmp->auth[i] = sid->auth[i];
- }
- for (i=0; i<tmp->auths&&i<MAXSUBAUTHS; i++) {
- tmp->sub_auths[i] = sid->sub_auths[i];
- }
- return tmp;
-}
-
-/*
- * Allocate space for an ACE and duplicate the registry encoded one passed in
- */
-static
-ACE *dup_ace(REG_ACE *ace)
-{
- ACE *tmp = NULL;
-
- tmp = (ACE *)malloc(sizeof(ACE));
-
- if (!tmp) return NULL;
-
- tmp->type = CVAL(&ace->type);
- tmp->flags = CVAL(&ace->flags);
- tmp->perms = IVAL(&ace->perms);
- tmp->trustee = dup_sid(&ace->trustee);
- return tmp;
-}
-
-/*
- * Allocate space for an ACL and duplicate the registry encoded one passed in
- */
-static
-ACL *dup_acl(REG_ACL *acl)
-{
- ACL *tmp = NULL;
- REG_ACE* ace;
- int i, num_aces;
-
- num_aces = IVAL(&acl->num_aces);
-
- tmp = (ACL *)malloc(sizeof(ACL) + (num_aces - 1)*sizeof(ACE *));
- if (!tmp) return NULL;
-
- tmp->num_aces = num_aces;
- tmp->refcnt = 1;
- tmp->rev = SVAL(&acl->rev);
- if (verbose) fprintf(stdout, "ACL: refcnt: %u, rev: %u\n", tmp->refcnt,
- tmp->rev);
- ace = (REG_ACE *)&acl->aces;
- for (i=0; i<num_aces; i++) {
- tmp->aces[i] = dup_ace(ace);
- ace = (REG_ACE *)((char *)ace + SVAL(&ace->length));
- /* XXX: FIXME, should handle malloc errors */
- }
-
- return tmp;
-}
-
-static
-SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc)
-{
- SEC_DESC *tmp = NULL;
-
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
-
- if (!tmp) {
- return NULL;
- }
-
- tmp->rev = SVAL(&sec_desc->rev);
- tmp->type = SVAL(&sec_desc->type);
- if (verbose) fprintf(stdout, "SEC_DESC Rev: %0X, Type: %0X\n",
- tmp->rev, tmp->type);
- if (verbose) fprintf(stdout, "SEC_DESC Owner Off: %0X\n",
- IVAL(&sec_desc->owner_off));
- if (verbose) fprintf(stdout, "SEC_DESC Group Off: %0X\n",
- IVAL(&sec_desc->group_off));
- if (verbose) fprintf(stdout, "SEC_DESC DACL Off: %0X\n",
- IVAL(&sec_desc->dacl_off));
- tmp->owner = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->owner_off)));
- if (!tmp->owner) {
- free(tmp);
- return NULL;
- }
- tmp->group = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->group_off)));
- if (!tmp->group) {
- free(tmp);
- return NULL;
- }
-
- /* Now pick up the SACL and DACL */
-
- if (sec_desc->sacl_off)
- tmp->sacl = dup_acl((REG_ACL *)((char *)sec_desc + IVAL(&sec_desc->sacl_off)));
- else
- tmp->sacl = NULL;
-
- if (sec_desc->dacl_off)
- tmp->dacl = dup_acl((REG_ACL *)((char *)sec_desc + IVAL(&sec_desc->dacl_off)));
- else
- tmp->dacl = NULL;
-
- return tmp;
-}
-
-static
-KEY_SEC_DESC *process_sk(REGF *regf, SK_HDR *sk_hdr, int sk_off, int size)
-{
- KEY_SEC_DESC *tmp = NULL;
- int sk_next_off, sk_prev_off, sk_size;
- REG_SEC_DESC *sec_desc;
-
- if (!sk_hdr) return NULL;
-
- if (SVAL(&sk_hdr->SK_ID) != REG_SK_ID) {
- fprintf(stderr, "Unrecognized SK Header ID: %08X, %s\n", (int)sk_hdr,
- regf->regfile_name);
- return NULL;
- }
-
- if (-size < (sk_size = IVAL(&sk_hdr->rec_size))) {
- fprintf(stderr, "Incorrect SK record size: %d vs %d. %s\n",
- -size, sk_size, regf->regfile_name);
- return NULL;
- }
-
- /*
- * Now, we need to look up the SK Record in the map, and return it
- * Since the map contains the SK_OFF mapped to KEY_SEC_DESC, we can
- * use that
- */
-
- if (regf->sk_map &&
- ((tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off)) != NULL)
- && (tmp->state == SEC_DESC_OCU)) {
- tmp->ref_cnt++;
- return tmp;
- }
-
- /* Here, we have an item in the map that has been reserved, or tmp==NULL. */
-
- assert(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON));
-
- /*
- * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the
- * new KEY_SEC_DESC to the mapping structure, since the offset supplied is
- * the actual offset of structure. The same offset will be used by
- * all future references to this structure
- * We could put all this unpleasantness in a function.
- */
-
- if (!tmp) {
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
- if (!tmp) return NULL;
- memset(tmp, 0, sizeof(KEY_SEC_DESC));
-
- /*
- * Allocate an entry in the SK_MAP ...
- * We don't need to free tmp, because that is done for us if the
- * sm_map entry can't be expanded when we need more space in the map.
- */
-
- if (!alloc_sk_map_entry(regf, tmp, sk_off)) {
- return NULL;
- }
- }
-
- tmp->ref_cnt++;
- tmp->state = SEC_DESC_OCU;
-
- /*
- * Now, process the actual sec desc and plug the values in
- */
-
- sec_desc = (REG_SEC_DESC *)&sk_hdr->sec_desc[0];
- tmp->sec_desc = process_sec_desc(regf, sec_desc);
-
- /*
- * Now forward and back links. Here we allocate an entry in the sk_map
- * if it does not exist, and mark it reserved
- */
-
- sk_prev_off = IVAL(&sk_hdr->prev_off);
- tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off);
- assert(tmp->prev != NULL);
- sk_next_off = IVAL(&sk_hdr->next_off);
- tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off);
- assert(tmp->next != NULL);
-
- return tmp;
-}
-
-/*
- * Process a VK header and return a value
- */
-static
-VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size)
-{
- char val_name[1024];
- int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
- const char *val_type;
- VAL_KEY *tmp = NULL;
-
- if (!vk_hdr) return NULL;
-
- if ((vk_id = SVAL(&vk_hdr->VK_ID)) != REG_VK_ID) {
- fprintf(stderr, "Unrecognized VK header ID: %0X, block: %0X, %s\n",
- vk_id, (int)vk_hdr, regf->regfile_name);
- return NULL;
- }
-
- nam_len = SVAL(&vk_hdr->nam_len);
- val_name[nam_len] = '\0';
- flag = SVAL(&vk_hdr->flag);
- dat_type = IVAL(&vk_hdr->dat_type);
- dat_len = IVAL(&vk_hdr->dat_len); /* If top bit, offset contains data */
- dat_off = IVAL(&vk_hdr->dat_off);
-
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
- if (!tmp) {
- goto error;
- }
- memset(tmp, 0, sizeof(VAL_KEY));
- tmp->has_name = flag;
- tmp->data_type = dat_type;
-
- if (flag & 0x01) {
- strncpy(val_name, vk_hdr->dat_name, nam_len);
- tmp->name = strdup(val_name);
- if (!tmp->name) {
- goto error;
- }
- }
- else
- strncpy(val_name, "<No Name>", 10);
-
- /*
- * Allocate space and copy the data as a BLOB
- */
-
- if (dat_len) {
-
- char *dtmp = (char *)malloc(dat_len&0x7FFFFFFF);
-
- if (!dtmp) {
- goto error;
- }
-
- tmp->data_blk = dtmp;
-
- if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */
- char *dat_ptr = LOCN(regf->base, dat_off);
- bcopy(dat_ptr, dtmp, dat_len);
- }
- else { /* The data is in the offset or type */
- /*
- * FIXME.
- * Some registry files seem to have wierd fields. If top bit is set,
- * but len is 0, the type seems to be the value ...
- * Not sure how to handle this last type for the moment ...
- */
- dat_len = dat_len & 0x7FFFFFFF;
- bcopy(&dat_off, dtmp, dat_len);
- }
-
- tmp->data_len = dat_len;
- }
-
- val_type = val_to_str(dat_type, reg_type_names);
-
- /*
- * We need to save the data area as well
- */
-
- if (verbose) fprintf(stdout, " %s : %s : \n", val_name, val_type);
-
- return tmp;
-
- error:
- if (tmp) nt_delete_val_key(tmp);
- return NULL;
-
-}
-
-/*
- * Process a VL Header and return a list of values
- */
-static
-VAL_LIST *process_vl(REGF *regf, VL_TYPE vl, int count, int size)
-{
- int i, vk_off;
- VK_HDR *vk_hdr;
- VAL_LIST *tmp = NULL;
-
- if (!vl) return NULL;
-
- if (-size < (count+1)*sizeof(int)){
- fprintf(stderr, "Error in VL header format. Size less than space required. %d\n", -size);
- return NULL;
- }
-
- tmp = (VAL_LIST *)malloc(sizeof(VAL_LIST) + (count - 1) * sizeof(VAL_KEY *));
- if (!tmp) {
- goto error;
- }
-
- for (i=0; i<count; i++) {
- vk_off = IVAL(&vl[i]);
- vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off);
- tmp->vals[i] = process_vk(regf, vk_hdr, BLK_SIZE(vk_hdr));
- if (!tmp->vals[i]){
- goto error;
- }
- }
-
- tmp->val_count = count;
- tmp->max_vals = count;
-
- return tmp;
-
- error:
- /* XXX: FIXME, free the partially allocated structure */
- return NULL;
-}
-
-/*
- * Process an LF Header and return a list of sub-keys
- */
-static
-KEY_LIST *process_lf(REGF *regf, LF_HDR *lf_hdr, int size, REG_KEY *parent)
-{
- int count, i, nk_off;
- unsigned int lf_id;
- KEY_LIST *tmp;
-
- if (!lf_hdr) return NULL;
-
- if ((lf_id = SVAL(&lf_hdr->LF_ID)) != REG_LF_ID) {
- fprintf(stderr, "Unrecognized LF Header format: %0X, Block: %0X, %s.\n",
- lf_id, (int)lf_hdr, regf->regfile_name);
- return NULL;
- }
-
- assert(size < 0);
-
- count = SVAL(&lf_hdr->key_count);
- if (verbose) fprintf(stdout, "Key Count: %u\n", count);
- if (count <= 0) return NULL;
-
- /* Now, we should allocate a KEY_LIST struct and fill it in ... */
-
- tmp = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (count - 1) * sizeof(REG_KEY *));
- if (!tmp) {
- goto error;
- }
-
- tmp->key_count = count;
- tmp->max_keys = count;
-
- for (i=0; i<count; i++) {
- NK_HDR *nk_hdr;
-
- nk_off = IVAL(&lf_hdr->hr[i].nk_off);
- if (verbose) fprintf(stdout, "NK Offset: %0X\n", nk_off);
- nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off);
- tmp->keys[i] = nt_get_key_tree(regf, nk_hdr, BLK_SIZE(nk_hdr), parent);
- if (!tmp->keys[i]) {
- goto error;
- }
- }
-
- return tmp;
-
- error:
- if (tmp) nt_delete_key_list(tmp, False);
- return NULL;
-}
-
-/*
- * This routine is passed an NK_HDR pointer and retrieves the entire tree
- * from there down. It returns a REG_KEY *.
- */
-static
-REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
-{
- REG_KEY *tmp = NULL, *own;
- int name_len, clsname_len, lf_off, val_off, val_count, sk_off, own_off;
- unsigned int nk_id;
- LF_HDR *lf_hdr;
- VL_TYPE *vl;
- SK_HDR *sk_hdr;
- char key_name[1024], cls_name[1024];
-
- if (!nk_hdr) return NULL;
-
- if ((nk_id = SVAL(&nk_hdr->NK_ID)) != REG_NK_ID) {
- fprintf(stderr, "Unrecognized NK Header format: %08X, Block: %0X. %s\n",
- nk_id, (int)nk_hdr, regf->regfile_name);
- return NULL;
- }
-
- assert(size < 0);
-
- name_len = SVAL(&nk_hdr->nam_len);
- clsname_len = SVAL(&nk_hdr->clsnam_len);
-
- /*
- * The value of -size should be ge
- * (sizeof(NK_HDR) - 1 + name_len)
- * The -1 accounts for the fact that we included the first byte of
- * the name in the structure. clsname_len is the length of the thing
- * pointed to by clsnam_off
- */
-
- if (-size < (sizeof(NK_HDR) - 1 + name_len)) {
- fprintf(stderr, "Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr);
- fprintf(stderr, "Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n",
- sizeof(NK_HDR), name_len, clsname_len);
- /*return NULL;*/
- }
-
- if (verbose) fprintf(stdout, "NK HDR: Name len: %d, class name len: %d\n",
- name_len, clsname_len);
-
- /* Fish out the key name and process the LF list */
-
- assert(name_len < sizeof(key_name));
-
- /* Allocate the key struct now */
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
- if (!tmp) return tmp;
- memset(tmp, 0, sizeof(REG_KEY));
-
- tmp->type = (SVAL(&nk_hdr->type)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
-
- strncpy(key_name, nk_hdr->key_nam, name_len);
- key_name[name_len] = '\0';
-
- if (verbose) fprintf(stdout, "Key name: %s\n", key_name);
-
- tmp->name = strdup(key_name);
- if (!tmp->name) {
- goto error;
- }
-
- /*
- * Fish out the class name, it is in UNICODE, while the key name is
- * ASCII :-)
- */
-
- if (clsname_len) { /* Just print in Ascii for now */
- char *clsnamep;
- int clsnam_off;
-
- clsnam_off = IVAL(&nk_hdr->clsnam_off);
- clsnamep = LOCN(regf->base, clsnam_off);
- if (verbose) fprintf(stdout, "Class Name Offset: %0X\n", clsnam_off);
-
- memset(cls_name, 0, clsname_len);
- uni_to_ascii(clsnamep, cls_name, sizeof(cls_name), clsname_len);
-
- /*
- * I am keeping class name as an ascii string for the moment.
- * That means it needs to be converted on output.
- * It will also piss off people who need Unicode/UTF-8 strings. Sorry.
- * XXX: FIXME
- */
-
- tmp->class_name = strdup(cls_name);
- if (!tmp->class_name) {
- goto error;
- }
-
- if (verbose) fprintf(stdout, " Class Name: %s\n", cls_name);
-
- }
-
- /*
- * Process the owner offset ...
- */
-
- own_off = IVAL(&nk_hdr->own_off);
- own = (REG_KEY *)LOCN(regf->base, own_off);
- if (verbose) fprintf(stdout, "Owner Offset: %0X\n", own_off);
-
- if (verbose) fprintf(stdout, " Owner locn: %0X, Our locn: %0X\n",
- (unsigned int)own, (unsigned int)nk_hdr);
-
- /*
- * We should verify that the owner field is correct ...
- * for now, we don't worry ...
- */
-
- tmp->owner = parent;
-
- /*
- * If there are any values, process them here
- */
-
- val_count = IVAL(&nk_hdr->val_cnt);
- if (verbose) fprintf(stdout, "Val Count: %d\n", val_count);
- if (val_count) {
-
- val_off = IVAL(&nk_hdr->val_off);
- vl = (VL_TYPE *)LOCN(regf->base, val_off);
- if (verbose) fprintf(stdout, "Val List Offset: %0X\n", val_off);
-
- tmp->values = process_vl(regf, *vl, val_count, BLK_SIZE(vl));
- if (!tmp->values) {
- goto error;
- }
-
- }
-
- /*
- * Also handle the SK header ...
- */
-
- sk_off = IVAL(&nk_hdr->sk_off);
- sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off);
- if (verbose) fprintf(stdout, "SK Offset: %0X\n", sk_off);
-
- if (sk_off != -1) {
-
- tmp->security = process_sk(regf, sk_hdr, sk_off, BLK_SIZE(sk_hdr));
-
- }
-
- lf_off = IVAL(&nk_hdr->lf_off);
- if (verbose) fprintf(stdout, "SubKey list offset: %0X\n", lf_off);
-
- /*
- * No more subkeys if lf_off == -1
- */
-
- if (lf_off != -1) {
-
- lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off);
-
- tmp->sub_keys = process_lf(regf, lf_hdr, BLK_SIZE(lf_hdr), tmp);
- if (!tmp->sub_keys){
- goto error;
- }
-
- }
-
- return tmp;
-
- error:
- if (tmp) nt_delete_reg_key(tmp, False);
- return NULL;
-}
-
-static
-int nt_load_registry(REGF *regf)
-{
- REGF_HDR *regf_hdr;
- unsigned int regf_id, hbin_id;
- HBIN_HDR *hbin_hdr;
- NK_HDR *first_key;
-
- /* Get the header */
-
- if ((regf_hdr = nt_get_regf_hdr(regf)) == NULL) {
- return -1;
- }
-
- /* Now process that header and start to read the rest in */
-
- if ((regf_id = IVAL(&regf_hdr->REGF_ID)) != REG_REGF_ID) {
- fprintf(stderr, "Unrecognized NT registry header id: %0X, %s\n",
- regf_id, regf->regfile_name);
- return -1;
- }
-
- /*
- * Validate the header ...
- */
- if (!valid_regf_hdr(regf_hdr)) {
- fprintf(stderr, "Registry file header does not validate: %s\n",
- regf->regfile_name);
- return -1;
- }
-
- /* Update the last mod date, and then go get the first NK record and on */
-
- TTTONTTIME(regf, IVAL(&regf_hdr->tim1), IVAL(&regf_hdr->tim2));
-
- /*
- * The hbin hdr seems to be just uninteresting garbage. Check that
- * it is there, but that is all.
- */
-
- hbin_hdr = (HBIN_HDR *)(regf->base + REGF_HDR_BLKSIZ);
-
- if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID)) != REG_HBIN_ID) {
- fprintf(stderr, "Unrecognized registry hbin hdr ID: %0X, %s\n",
- hbin_id, regf->regfile_name);
- return -1;
- }
-
- /*
- * Get a pointer to the first key from the hreg_hdr
- */
-
- if (verbose) fprintf(stdout, "First Key: %0X\n",
- IVAL(&regf_hdr->first_key));
-
- first_key = (NK_HDR *)LOCN(regf->base, IVAL(&regf_hdr->first_key));
- if (verbose) fprintf(stdout, "First Key Offset: %0X\n",
- IVAL(&regf_hdr->first_key));
-
- if (verbose) fprintf(stdout, "Data Block Size: %d\n",
- IVAL(&regf_hdr->dblk_size));
-
- if (verbose) fprintf(stdout, "Offset to next hbin block: %0X\n",
- IVAL(&hbin_hdr->off_to_next));
-
- if (verbose) fprintf(stdout, "HBIN block size: %0X\n",
- IVAL(&hbin_hdr->blk_size));
-
- /*
- * Now, get the registry tree by processing that NK recursively
- */
-
- regf->root = nt_get_key_tree(regf, first_key, BLK_SIZE(first_key), NULL);
-
- assert(regf->root != NULL);
-
- /*
- * Unmap the registry file, as we might want to read in another
- * tree etc.
- */
-
- if (regf->base) munmap(regf->base, regf->sbuf.st_size);
- regf->base = NULL;
- close(regf->fd); /* Ignore the error :-) */
-
- return 1;
-}
-
-/*
- * Allocate a new hbin block, set up the header for the block etc
- */
-static
-HBIN_BLK *nt_create_hbin_blk(REGF *regf, int size)
-{
- HBIN_BLK *tmp;
- HBIN_HDR *hdr;
-
- if (!regf || !size) return NULL;
-
- /* Round size up to multiple of REGF_HDR_BLKSIZ */
-
- size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1);
-
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
- memset(tmp, 0, sizeof(HBIN_BLK));
-
- tmp->data = malloc(size);
- if (!tmp->data) goto error;
-
- memset(tmp->data, 0, size); /* Make it pristine */
-
- tmp->size = size;
- tmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;
-
- tmp->free_space = size - (sizeof(HBIN_HDR) - sizeof(HBIN_SUB_HDR));
- tmp->fsp_off = size - tmp->free_space;
-
- /*
- * Now, build the header in the data block
- */
- hdr = (HBIN_HDR *)tmp->data;
- hdr->HBIN_ID = REG_HBIN_ID;
- hdr->off_from_first = tmp->file_offset - REGF_HDR_BLKSIZ;
- hdr->off_to_next = tmp->size;
- hdr->blk_size = tmp->size;
-
- /*
- * Now link it in
- */
-
- regf->blk_tail->next = tmp;
- regf->blk_tail = tmp;
- if (!regf->free_space) regf->free_space = tmp;
-
- return tmp;
- error:
- if (tmp) free(tmp);
- return NULL;
-}
-
-/*
- * Allocate a unit of space ... and return a pointer as function param
- * and the block's offset as a side effect
- */
-static
-void *nt_alloc_regf_space(REGF *regf, int size, unsigned int *off)
-{
- int tmp = 0;
- void *ret = NULL;
- HBIN_BLK *blk;
-
- if (!regf || !size || !off) return NULL;
-
- assert(regf->blk_head != NULL);
-
- /*
- * round up size to include header and then to 8-byte boundary
- */
- size = (size + 4 + 7) & ~7;
-
- /*
- * Check if there is space, if none, grab a block
- */
- if (!regf->free_space) {
- if (!nt_create_hbin_blk(regf, REGF_HDR_BLKSIZ))
- return NULL;
- }
-
- /*
- * Now, chain down the list of blocks looking for free space
- */
-
- for (blk = regf->free_space; blk != NULL; blk = blk->next) {
- if (blk->free_space <= size) {
- tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ;
- ret = blk->data + blk->fsp_off;
- blk->free_space -= size;
- blk->fsp_off += size;
-
- /* Insert the header */
- ((HBIN_SUB_HDR *)ret)->dblocksize = -size;
-
- /*
- * Fix up the free space ptr
- * If it is NULL, we fix it up next time
- */
-
- if (!blk->free_space)
- regf->free_space = blk->next;
-
- *off = tmp;
- return (((char *)ret)+4);/* The pointer needs to be to the data struct */
- }
- }
-
- /*
- * If we got here, we need to add another block, which might be
- * larger than one block -- deal with that later
- */
- if (nt_create_hbin_blk(regf, REGF_HDR_BLKSIZ)) {
- blk = regf->free_space;
- tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ;
- ret = blk->data + blk->fsp_off;
- blk->free_space -= size;
- blk->fsp_off += size;
-
- /* Insert the header */
- ((HBIN_SUB_HDR *)ret)->dblocksize = -size;
-
- /*
- * Fix up the free space ptr
- * If it is NULL, we fix it up next time
- */
-
- if (!blk->free_space)
- regf->free_space = blk->next;
-
- *off = tmp;
- return (((char *)ret) + 4);/* The pointer needs to be to the data struct */
- }
-
- return NULL;
-}
-
-/*
- * Compute the size of a SID stored ...
- */
-static
-unsigned int sid_size(sid_t *sid)
-{
- unsigned int size;
-
- if (!sid) return 0;
-
- size = 8 + (sid->auths * sizeof(unsigned int));
-
- return size;
-}
-
-/*
- * Compute the size of an ACE on disk from its components
- */
-static
-unsigned int ace_size(ACE *ace)
-{
- unsigned int size;
-
- if (!ace) return 0;
-
- size = 8 + sid_size(ace->trustee);
-
- return size;
-}
-
-/*
- * Compute the size of an ACL from its components ...
- */
-static
-unsigned int acl_size(ACL *acl)
-{
- unsigned int size;
- int i;
-
- if (!acl) return 0;
-
- size = 8;
- for (i = 0; i < acl->num_aces; i++)
- size += ace_size(acl->aces[i]);
-
- return size;
-}
-
-/*
- * Compute the size of the sec desc as a self-relative SD
- */
-static
-unsigned int sec_desc_size(SEC_DESC *sd)
-{
- unsigned int size;
-
- if (!sd) return 0;
-
- size = 20;
-
- if (sd->owner) size += sid_size(sd->owner);
- if (sd->group) size += sid_size(sd->group);
- if (sd->sacl) size += acl_size(sd->sacl);
- if (sd->dacl) size += acl_size(sd->dacl);
-
- return size;
-}
-
-/*
- * Store a SID at the location provided
- */
-static
-int nt_store_SID(REGF *regf, sid_t *sid, unsigned char *locn)
-{
- int i;
- unsigned char *p = locn;
-
- if (!regf || !sid || !locn) return 0;
-
- *p = sid->ver; p++;
- *p = sid->auths; p++;
-
- for (i=0; i < 6; i++) {
- *p = sid->auth[i]; p++;
- }
-
- for (i=0; i < sid->auths; i++) {
- SIVAL(p, sid->sub_auths[i]); p+=4;
- }
-
- return p - locn;
-
-}
-
-static
-int nt_store_ace(REGF *regf, ACE *ace, unsigned char *locn)
-{
- int size = 0;
- REG_ACE *reg_ace = (REG_ACE *)locn;
- unsigned char *p;
-
- if (!regf || !ace || !locn) return 0;
-
- reg_ace->type = ace->type;
- reg_ace->flags = ace->flags;
-
- /* Deal with the length when we have stored the SID */
-
- p = (unsigned char *)&reg_ace->perms;
-
- SIVAL(p, ace->perms); p += 4;
-
- size = nt_store_SID(regf, ace->trustee, p);
-
- size += 8; /* Size of the fixed header */
-
- p = (unsigned char *)&reg_ace->length;
-
- SSVAL(p, size);
-
- return size;
-}
-
-/*
- * Store an ACL at the location provided
- */
-static
-int nt_store_acl(REGF *regf, ACL *acl, unsigned char *locn)
-{
- int size = 0, i;
- unsigned char *p = locn, *s;
-
- if (!regf || !acl || !locn) return 0;
-
- /*
- * Now store the header and then the ACEs ...
- */
-
- SSVAL(p, acl->rev);
-
- p += 2; s = p; /* Save this for the size field */
-
- p += 2;
-
- SIVAL(p, acl->num_aces);
-
- p += 4;
-
- for (i = 0; i < acl->num_aces; i++) {
- size = nt_store_ace(regf, acl->aces[i], p);
- p += size;
- }
-
- size = s - locn;
- SSVAL(s, size);
- return size;
-}
-
-/*
- * Flatten and store the Sec Desc
- * Windows lays out the DACL first, but since there is no SACL, it might be
- * that first, then the owner, then the group SID. So, we do it that way
- * too.
- */
-static
-unsigned int nt_store_sec_desc(REGF *regf, SEC_DESC *sd, char *locn)
-{
- REG_SEC_DESC *rsd = (REG_SEC_DESC *)locn;
- unsigned int size = 0, off = 0;
-
- if (!regf || !sd || !locn) return 0;
-
- /*
- * Now, fill in the first two fields, then lay out the various fields
- * as needed
- */
-
- rsd->rev = 0x01;
- /* Self relative, DACL pres, owner and group not defaulted */
- rsd->type = 0x8004;
-
- off = 4 * sizeof(DWORD) + 4;
-
- if (sd->sacl){
- size = nt_store_acl(regf, sd->sacl, (char *)(locn + off));
- rsd->sacl_off = off;
- }
- else
- rsd->sacl_off = 0;
-
- off += size;
-
- if (sd->dacl) {
- rsd->dacl_off = off;
- size = nt_store_acl(regf, sd->dacl, (char *)(locn + off));
- }
- else {
- rsd->dacl_off = 0;
- }
-
- off += size;
-
- /* Now the owner and group SIDs */
-
- if (sd->owner) {
- rsd->owner_off = off;
- size = nt_store_SID(regf, sd->owner, (char *)(locn + off));
- }
- else {
- rsd->owner_off = 0;
- }
-
- off += size;
-
- if (sd->group) {
- rsd->group_off = off;
- size = nt_store_SID(regf, sd->group, (char *)(locn + off));
- }
- else {
- rsd->group_off = 0;
- }
-
- off += size;
-
- return size;
-}
-
-/*
- * Store the security information
- *
- * If it has already been stored, just get its offset from record
- * otherwise, store it and record its offset
- */
-static
-unsigned int nt_store_security(REGF *regf, KEY_SEC_DESC *sec)
-{
- int size = 0;
- unsigned int sk_off;
- SK_HDR *sk_hdr;
-
- if (sec->offset) return sec->offset;
-
- /*
- * OK, we don't have this one in the file yet. We must compute the
- * size taken by the security descriptor as a self-relative SD, which
- * means making one pass over each structure and figuring it out
- */
-
- size = sec_desc_size(sec->sec_desc);
-
- /* Allocate that much space */
-
- sk_hdr = nt_alloc_regf_space(regf, size, &sk_off);
- sec->sk_hdr = sk_hdr;
-
- if (!sk_hdr) return 0;
-
- /* Now, lay out the sec_desc in the space provided */
-
- sk_hdr->SK_ID = REG_SK_ID;
-
- /*
- * We can't deal with the next and prev offset in the SK_HDRs until the
- * whole tree has been stored, then we can go and deal with them
- */
-
- sk_hdr->ref_cnt = sec->ref_cnt;
- sk_hdr->rec_size = size; /* Is this correct */
-
- /* Now, lay out the sec_desc */
-
- if (!nt_store_sec_desc(regf, sec->sec_desc, (char *)&sk_hdr->sec_desc))
- return 0;
-
- return sk_off;
-
-}
-
-/*
- * Store a VAL LIST
- */
-static
-int nt_store_val_list(REGF *regf, VAL_LIST * values)
-{
-
- return 0;
-}
-
-/*
- * Store a KEY in the file ...
- *
- * We store this depth first, and defer storing the lf struct until
- * all the sub-keys have been stored.
- *
- * We store the NK hdr, any SK header, class name, and VK structure, then
- * recurse down the LF structures ...
- *
- * We return the offset of the NK struct
- * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ...
- */
-static
-int nt_store_reg_key(REGF *regf, REG_KEY *key)
-{
- NK_HDR *nk_hdr;
- unsigned int nk_off, sk_off, size;
-
- if (!regf || !key) return 0;
-
- size = sizeof(NK_HDR) + strlen(key->name) - 1;
- nk_hdr = nt_alloc_regf_space(regf, size, &nk_off);
- if (!nk_hdr) goto error;
-
- key->offset = nk_off; /* We will need this later */
-
- /*
- * Now fill in each field etc ...
- */
-
- nk_hdr->NK_ID = REG_NK_ID;
- if (key->type == REG_ROOT_KEY)
- nk_hdr->type = 0x2C;
- else
- nk_hdr->type = 0x20;
-
- /* FIXME: Fill in the time of last update */
-
- if (key->type != REG_ROOT_KEY)
- nk_hdr->own_off = key->owner->offset;
-
- if (key->sub_keys)
- nk_hdr->subk_num = key->sub_keys->key_count;
-
- /*
- * Now, process the Sec Desc and then store its offset
- */
-
- sk_off = nt_store_security(regf, key->security);
- nk_hdr->sk_off = sk_off;
-
- /*
- * Then, store the val list and store its offset
- */
- if (key->values) {
- nk_hdr->val_cnt = key->values->val_count;
- nk_hdr->val_off = nt_store_val_list(regf, key->values);
- }
- else {
- nk_hdr->val_off = -1;
- nk_hdr->val_cnt = 0;
- }
-
- /*
- * Finally, store the subkeys, and their offsets
- */
-
- error:
- return 0;
-}
-
-/*
- * Store the registry header ...
- * We actually create the registry header block and link it to the chain
- * of output blocks.
- */
-static
-REGF_HDR *nt_get_reg_header(REGF *regf)
-{
- HBIN_BLK *tmp = NULL;
-
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
- if (!tmp) return 0;
-
- memset(tmp, 0, sizeof(HBIN_BLK));
- tmp->type = REG_OUTBLK_HDR;
- tmp->size = REGF_HDR_BLKSIZ;
- tmp->data = malloc(REGF_HDR_BLKSIZ);
- if (!tmp->data) goto error;
-
- memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */
- regf->blk_head = regf->blk_tail = tmp;
-
- return (REGF_HDR *)tmp->data;
-
- error:
- if (tmp) free(tmp);
- return NULL;
-}
-
-/*
- * Store the registry in the output file
- * We write out the header and then each of the keys etc into the file
- * We have to flatten the data structure ...
- *
- * The structures are stored in a depth-first fashion, with all records
- * aligned on 8-byte boundaries, with sub-keys and values layed down before
- * the lists that contain them. SK records are layed down first, however.
- * The lf fields are layed down after all sub-keys have been layed down, it
- * seems, including the whole tree associated with each sub-key.
- */
-static
-int nt_store_registry(REGF *regf)
-{
- REGF_HDR *reg;
- int fkey, fd;
-
- /*
- * Get a header ... and partially fill it in ...
- */
- reg = nt_get_reg_header(regf);
-
- /*
- * Store the first key, which will store the whole thing
- */
- fkey = nt_store_reg_key(regf, regf->root);
-
- /*
- * At this point we have the registry as a series of blocks, so
- * run down that series of blocks and save them ...
- */
-
- if (!regf->outfile_name) {
- fprintf(stderr, "Cannot write file without a name!\n");
- return 0;
- }
-
- if ((fd = open(regf->outfile_name, O_WRONLY, 0666)) < 0) {
- fprintf(stderr, "Unable to create file %s: %s\n", regf->outfile_name,
- strerror(errno));
- return 0;
- }
-
- return 1;
-}
-
-/*
- * Routines to parse a REGEDIT4 file
- *
- * The file consists of:
- *
- * REGEDIT4
- * \[[-]key-path\]\n
- * <value-spec>*
- *
- * Format:
- * [cmd:]name=type:value
- *
- * cmd = a|d|c|add|delete|change|as|ds|cs
- *
- * There can be more than one key-path and value-spec.
- *
- * Since we want to support more than one type of file format, we
- * construct a command-file structure that keeps info about the command file
- */
-
-#define FMT_UNREC -1
-#define FMT_REGEDIT4 0
-#define FMT_EDITREG1_1 1
-
-#define FMT_STRING_REGEDIT4 "REGEDIT4"
-#define FMT_STRING_EDITREG1_0 "EDITREG1.0"
-
-#define CMD_NONE 0
-#define CMD_ADD_KEY 1
-#define CMD_DEL_KEY 2
-
-#define CMD_KEY 1
-#define CMD_VAL 2
-
-typedef struct val_spec_list {
- struct val_spec_list *next;
- char *name;
- int type;
- char *val; /* Kept as a char string, really? */
-} VAL_SPEC_LIST;
-
-typedef struct command_s {
- int cmd;
- char *key;
- int val_count;
- VAL_SPEC_LIST *val_spec_list, *val_spec_last;
-} CMD;
-
-typedef struct cmd_line {
- int len, line_len;
- char *line;
-} CMD_LINE;
-
-static
-void free_val_spec_list(VAL_SPEC_LIST *vl)
-{
- if (!vl) return;
- if (vl->name) free(vl->name);
- if (vl->val) free(vl->val);
- free(vl);
-
-}
-
-/*
- * Some routines to handle lines of info in the command files
- */
-static
-void skip_to_eol(int fd)
-{
- int rc;
- char ch = 0;
-
- while ((rc = read(fd, &ch, 1)) == 1) {
- if (ch == 0x0A) return;
- }
- if (rc < 0) {
- fprintf(stderr, "Could not read file descriptor: %d, %s\n",
- fd, strerror(errno));
- exit(1);
- }
-}
-
-static
-void free_cmd(CMD *cmd)
-{
- if (!cmd) return;
-
- while (cmd->val_spec_list) {
- VAL_SPEC_LIST *tmp;
-
- tmp = cmd->val_spec_list;
- cmd->val_spec_list = tmp->next;
- free(tmp);
- }
-
- free(cmd);
-
-}
-
-static
-void free_cmd_line(CMD_LINE *cmd_line)
-{
- if (cmd_line) {
- if (cmd_line->line) free(cmd_line->line);
- free(cmd_line);
- }
-}
-
-static
-void print_line(struct cmd_line *cl)
-{
- char *pl;
-
- if (!cl) return;
-
- if ((pl = malloc(cl->line_len + 1)) == NULL) {
- fprintf(stderr, "Unable to allocate space to print line: %s\n",
- strerror(errno));
- exit(1);
- }
-
- strncpy(pl, cl->line, cl->line_len);
- pl[cl->line_len] = 0;
-
- fprintf(stdout, "%s\n", pl);
- free(pl);
-}
-
-#define INIT_ALLOC 10
-
-/*
- * Read a line from the input file.
- * NULL returned when EOF and no chars read
- * Otherwise we return a cmd_line *
- * Exit if other errors
- */
-static
-struct cmd_line *get_cmd_line(int fd)
-{
- struct cmd_line *cl = (CMD_LINE *)malloc(sizeof(CMD_LINE));
- int i = 0, rc;
- unsigned char ch;
-
- if (!cl) {
- fprintf(stderr, "Unable to allocate structure for command line: %s\n",
- strerror(errno));
- exit(1);
- }
-
- cl->len = INIT_ALLOC;
-
- /*
- * Allocate some space for the line. We extend later if needed.
- */
-
- if ((cl->line = (char *)malloc(INIT_ALLOC)) == NULL) {
- fprintf(stderr, "Unable to allocate initial space for line: %s\n",
- strerror(errno));
- exit(1);
- }
-
- /*
- * Now read in the chars to EOL. Don't store the EOL in the
- * line. What about CR?
- */
-
- while ((rc = read(fd, &ch, 1)) == 1 && ch != '\n') {
- if (ch == '\r') continue; /* skip CR */
- if (i == cl->len) {
- /*
- * Allocate some more memory
- */
- if ((cl->line = realloc(cl->line, cl->len + INIT_ALLOC)) == NULL) {
- fprintf(stderr, "Unable to realloc space for line: %s\n",
- strerror(errno));
- exit(1);
- }
- cl->len += INIT_ALLOC;
- }
- cl->line[i] = ch;
- i++;
- }
-
- /* read 0 and we were at loc'n 0, return NULL */
- if (rc == 0 && i == 0) {
- free_cmd_line(cl);
- return NULL;
- }
-
- cl->line_len = i;
-
- return cl;
-
-}
-
-/*
- * parse_value: parse out a value. We pull it apart as:
- *
- * <value> ::= <value-name>=<type>:<value-string>
- *
- * <value-name> ::= char-string-without-spaces | '"' char-string '"'
- *
- * If it parsed OK, return the <value-name> as a string, and the
- * value type and value-string in parameters.
- *
- * The value name can be empty. There can only be one empty name in
- * a list of values. A value of - removes the value entirely.
- */
-static
-char *dup_str(char *s, int len)
-{
- char *nstr;
- nstr = (char *)malloc(len + 1);
- if (nstr) {
- memcpy(nstr, s, len);
- nstr[len] = 0;
- }
- return nstr;
-}
-
-static
-char *parse_name(char *nstr)
-{
- int len = 0, start = 0;
- if (!nstr) return NULL;
-
- len = strlen(nstr);
-
- while (len && nstr[len - 1] == ' ') len--;
-
- nstr[len] = 0; /* Trim any spaces ... if there were none, doesn't matter */
-
- /*
- * Beginning and end should be '"' or neither should be so
- */
- if ((nstr[0] == '"' && nstr[len - 1] != '"') ||
- (nstr[0] != '"' && nstr[len - 1] == '"'))
- return NULL;
-
- if (nstr[0] == '"') {
- start = 1;
- len -= 2;
- }
-
- return dup_str(&nstr[start], len);
-}
-
-static
-int parse_value_type(char *tstr)
-{
- int len = strlen(tstr);
-
- while (len && tstr[len - 1] == ' ') len--;
- tstr[len] = 0;
-
- if (strcmp(tstr, "REG_DWORD") == 0)
- return REG_TYPE_DWORD;
- else if (strcmp(tstr, "dword") == 0)
- return REG_TYPE_DWORD;
- else if (strcmp(tstr, "REG_EXPAND_SZ") == 0)
- return REG_TYPE_EXPANDSZ;
- else if (strcmp(tstr, "REG_BIN") == 0)
- return REG_TYPE_BIN;
- else if (strcmp(tstr, "REG_SZ") == 0)
- return REG_TYPE_REGSZ;
- else if (strcmp(tstr, "REG_MULTI_SZ") == 0)
- return REG_TYPE_MULTISZ;
- else if (strcmp(tstr, "-") == 0)
- return REG_TYPE_DELETE;
-
- return 0;
-}
-
-static
-char *parse_val_str(char *vstr)
-{
-
- return dup_str(vstr, strlen(vstr));
-
-}
-
-static
-char *parse_value(struct cmd_line *cl, int *vtype, char **val)
-{
- char *p1 = NULL, *p2 = NULL, *nstr = NULL, *tstr = NULL, *vstr = NULL;
-
- if (!cl || !vtype || !val) return NULL;
- if (!cl->line_len) return NULL;
-
- p1 = dup_str(cl->line, cl->line_len);
- /* FIXME: Better return codes etc ... */
- if (!p1) return NULL;
- p2 = strchr(p1, '=');
- if (!p2) return NULL;
-
- *p2 = 0; p2++; /* Split into two strings at p2 */
-
- /* Now, parse the name ... */
-
- nstr = parse_name(p1);
- if (!nstr) goto error;
-
- /* Now, split the remainder and parse on type and val ... */
-
- tstr = p2;
- while (*tstr == ' ') tstr++; /* Skip leading white space */
- p2 = strchr(p2, ':');
-
- if (p2) {
- *p2 = 0; p2++; /* split on the : */
- }
-
- *vtype = parse_value_type(tstr);
-
- if (!vtype) goto error;
-
- if (!p2 || !*p2) return nstr;
-
- /* Now, parse the value string. It should return a newly malloc'd string */
-
- while (*p2 == ' ') p2++; /* Skip leading space */
- vstr = parse_val_str(p2);
-
- if (!vstr) goto error;
-
- *val = vstr;
-
- return nstr;
-
- error:
- if (p1) free(p1);
- if (nstr) free(nstr);
- if (vstr) free(vstr);
- return NULL;
-}
-
-/*
- * Parse out a key. Look for a correctly formatted key [...]
- * and whether it is a delete or add? A delete is signalled
- * by a - in front of the key.
- * Assumes that there are no leading and trailing spaces
- */
-
-static
-char *parse_key(struct cmd_line *cl, int *cmd)
-{
- int start = 1;
- char *tmp;
-
- if (cl->line[0] != '[' ||
- cl->line[cl->line_len - 1] != ']') return NULL;
- if (cl->line_len == 2) return NULL;
- *cmd = CMD_ADD_KEY;
- if (cl->line[1] == '-') {
- if (cl->line_len == 3) return NULL;
- start = 2;
- *cmd = CMD_DEL_KEY;
- }
- tmp = malloc(cl->line_len - 1 - start + 1);
- if (!tmp) return tmp; /* Bail out on no mem ... FIXME */
- strncpy(tmp, &cl->line[start], cl->line_len - 1 - start);
- tmp[cl->line_len - 1 - start] = 0;
- return tmp;
-}
-
-/*
- * Parse a line to determine if we have a key or a value
- * We only check for key or val ...
- */
-
-static
-int parse_line(struct cmd_line *cl)
-{
-
- if (!cl || cl->len == 0) return 0;
-
- if (cl->line[0] == '[') /* No further checking for now */
- return CMD_KEY;
- else
- return CMD_VAL;
-}
-
-/*
- * We seek to offset 0, read in the required number of bytes,
- * and compare to the correct value.
- * We then seek back to the original location
- */
-static
-int regedit4_file_type(int fd)
-{
- int cur_ofs = 0;
- char desc[9];
-
- cur_ofs = lseek(fd, 0, SEEK_CUR); /* Get current offset */
- if (cur_ofs < 0) {
- fprintf(stderr, "Unable to get current offset: %s\n", strerror(errno));
- exit(1); /* FIXME */
- }
-
- if (cur_ofs) {
- lseek(fd, 0, SEEK_SET);
- }
-
- if (read(fd, desc, 8) < 8) {
- fprintf(stderr, "Unable to read command file format\n");
- exit(2); /* FIXME */
- }
-
- desc[8] = 0;
-
- if (strcmp(desc, FMT_STRING_REGEDIT4) == 0) {
- if (cur_ofs) {
- lseek(fd, cur_ofs, SEEK_SET);
- }
- else {
- skip_to_eol(fd);
- }
- return FMT_REGEDIT4;
- }
-
- return FMT_UNREC;
-}
-
-/*
- * Run though the data in the line and strip anything after a comment
- * char.
- */
-static
-void strip_comment(struct cmd_line *cl)
-{
- int i;
-
- if (!cl) return;
-
- for (i = 0; i < cl->line_len; i++) {
- if (cl->line[i] == ';') {
- cl->line_len = i;
- return;
- }
- }
-}
-
-/*
- * trim leading space
- */
-
-static
-void trim_leading_spaces(struct cmd_line *cl)
-{
- int i;
-
- if (!cl) return;
-
- for (i = 0; i < cl->line_len; i++) {
- if (cl->line[i] != ' '){
- if (i) memcpy(cl->line, &cl->line[i], cl->line_len - i);
- return;
- }
- }
-}
-
-/*
- * trim trailing spaces
- */
-static
-void trim_trailing_spaces(struct cmd_line *cl)
-{
- int i;
-
- if (!cl) return;
-
- for (i = cl->line_len; i == 0; i--) {
- if (cl->line[i-1] != ' ' &&
- cl->line[i-1] != '\t') {
- cl->line_len = i;
- }
- }
-}
-
-/*
- * Get a command ... This consists of possibly multiple lines:
- * [key]
- * values*
- * possibly Empty line
- *
- * value ::= <value-name>=<value-type>':'<value-string>
- * <value-name> is some path, possibly enclosed in quotes ...
- * We alctually look for the next key to terminate a previous key
- * if <value-type> == '-', then it is a delete type.
- */
-static
-CMD *regedit4_get_cmd(int fd)
-{
- struct command_s *cmd = NULL;
- struct cmd_line *cl = NULL;
- struct val_spec_list *vl = NULL;
-
- if ((cmd = (struct command_s *)malloc(sizeof(struct command_s))) == NULL) {
- fprintf(stderr, "Unable to malloc space for command: %s\n",
- strerror(errno));
- exit(1);
- }
-
- cmd->cmd = CMD_NONE;
- cmd->key = NULL;
- cmd->val_count = 0;
- cmd->val_spec_list = cmd->val_spec_last = NULL;
- while ((cl = get_cmd_line(fd))) {
-
- /*
- * If it is an empty command line, and we already have a key
- * then exit from here ... FIXME: Clean up the parser
- */
-
- if (cl->line_len == 0 && cmd->key) {
- free_cmd_line(cl);
- break;
- }
-
- strip_comment(cl); /* remove anything beyond a comment char */
- trim_trailing_spaces(cl);
- trim_leading_spaces(cl);
-
- if (cl->line_len == 0) { /* An empty line */
- free_cmd_line(cl);
- }
- else { /* Else, non-empty ... */
- /*
- * Parse out the bits ...
- */
- switch (parse_line(cl)) {
- case CMD_KEY:
- if ((cmd->key = parse_key(cl, &cmd->cmd)) == NULL) {
- fprintf(stderr, "Error parsing key from line: ");
- print_line(cl);
- fprintf(stderr, "\n");
- }
- break;
-
- case CMD_VAL:
- /*
- * We need to add the value stuff to the list
- * There could be a \ on the end which we need to
- * handle at some time
- */
- vl = (struct val_spec_list *)malloc(sizeof(struct val_spec_list));
- if (!vl) goto error;
- vl->next = NULL;
- vl->val = NULL;
- vl->name = parse_value(cl, &vl->type, &vl->val);
- if (!vl->name) goto error;
- if (cmd->val_spec_list == NULL) {
- cmd->val_spec_list = cmd->val_spec_last = vl;
- }
- else {
- cmd->val_spec_last->next = vl;
- cmd->val_spec_last = vl;
- }
- cmd->val_count++;
- break;
-
- default:
- fprintf(stderr, "Unrecognized line in command file: \n");
- print_line(cl);
- break;
- }
- }
-
- }
- if (!cmd->cmd) goto error; /* End of file ... */
-
- return cmd;
-
- error:
- if (vl) free(vl);
- if (cmd) free_cmd(cmd);
- return NULL;
-}
-
-static
-int regedit4_exec_cmd(CMD *cmd)
-{
-
- return 0;
-}
-
-static
-int editreg_1_0_file_type(int fd)
-{
- int cur_ofs = 0;
- char desc[11];
-
- cur_ofs = lseek(fd, 0, SEEK_CUR); /* Get current offset */
- if (cur_ofs < 0) {
- fprintf(stderr, "Unable to get current offset: %s\n", strerror(errno));
- exit(1); /* FIXME */
- }
-
- if (cur_ofs) {
- lseek(fd, 0, SEEK_SET);
- }
-
- if (read(fd, desc, 10) < 10) {
- fprintf(stderr, "Unable to read command file format\n");
- exit(2); /* FIXME */
- }
-
- desc[10] = 0;
-
- if (strcmp(desc, FMT_STRING_EDITREG1_0) == 0) {
- lseek(fd, cur_ofs, SEEK_SET);
- return FMT_REGEDIT4;
- }
-
- return FMT_UNREC;
-}
-
-static
-CMD *editreg_1_0_get_cmd(int fd)
-{
- return NULL;
-}
-
-static
-int editreg_1_0_exec_cmd(CMD *cmd)
-{
-
- return -1;
-}
-
-typedef struct command_ops_s {
- int type;
- int (*file_type)(int fd);
- CMD *(*get_cmd)(int fd);
- int (*exec_cmd)(CMD *cmd);
-} CMD_OPS;
-
-CMD_OPS default_cmd_ops[] = {
- {0, regedit4_file_type, regedit4_get_cmd, regedit4_exec_cmd},
- {1, editreg_1_0_file_type, editreg_1_0_get_cmd, editreg_1_0_exec_cmd},
- {-1, NULL, NULL, NULL}
-};
-
-typedef struct command_file_s {
- char *name;
- int type, fd;
- CMD_OPS cmd_ops;
-} CMD_FILE;
-
-/*
- * Create a new command file structure
- */
-
-static
-CMD_FILE *cmd_file_create(char *file)
-{
- CMD_FILE *tmp;
- struct stat sbuf;
- int i = 0;
-
- /*
- * Let's check if the file exists ...
- * No use creating the cmd_file structure if the file does not exist
- */
-
- if (stat(file, &sbuf) < 0) { /* Not able to access file */
-
- return NULL;
- }
-
- tmp = (CMD_FILE *)malloc(sizeof(CMD_FILE));
- if (!tmp) {
- return NULL;
- }
-
- /*
- * Let's fill in some of the fields;
- */
-
- tmp->name = strdup(file);
-
- if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) {
- free(tmp);
- return NULL;
- }
-
- /*
- * Now, try to find the format by indexing through the table
- */
- while (default_cmd_ops[i].type != -1) {
- if ((tmp->type = default_cmd_ops[i].file_type(tmp->fd)) >= 0) {
- tmp->cmd_ops = default_cmd_ops[i];
- return tmp;
- }
- i++;
- }
-
- /*
- * If we got here, return NULL, as we could not figure out the type
- * of command file.
- *
- * What about errors?
- */
-
- free(tmp);
- return NULL;
-}
-
-/*
- * Extract commands from the command file, and execute them.
- * We pass a table of command callbacks for that
- */
-
-/*
- * Main code from here on ...
- */
-
-/*
- * key print function here ...
- */
-
-static
-int print_key(const char *path, char *name, char *class_name, int root,
- int terminal, int vals)
-{
-
- if (full_print || terminal) fprintf(stdout, "[%s%s]\n", path, name);
-
- return 1;
-}
-
-/*
- * Sec Desc print functions
- */
-
-static
-void print_type(unsigned char type)
-{
- switch (type) {
- case 0x00:
- fprintf(stdout, " ALLOW");
- break;
- case 0x01:
- fprintf(stdout, " DENY");
- break;
- case 0x02:
- fprintf(stdout, " AUDIT");
- break;
- case 0x03:
- fprintf(stdout, " ALARM");
- break;
- case 0x04:
- fprintf(stdout, "ALLOW CPD");
- break;
- case 0x05:
- fprintf(stdout, "OBJ ALLOW");
- break;
- case 0x06:
- fprintf(stdout, " OBJ DENY");
- default:
- fprintf(stdout, " UNKNOWN");
- break;
- }
-}
-
-static
-void print_flags(unsigned char flags)
-{
- char flg_output[21];
- int some = 0;
-
- flg_output[0] = 0;
- if (!flags) {
- fprintf(stdout, " ");
- return;
- }
- if (flags & 0x01) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "OI");
- }
- if (flags & 0x02) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "CI");
- }
- if (flags & 0x04) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "NP");
- }
- if (flags & 0x08) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "IO");
- }
- if (flags & 0x10) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "IA");
- }
- if (flags == 0xF) {
- if (some) strcat(flg_output, ",");
- some = 1;
- strcat(flg_output, "VI");
- }
- fprintf(stdout, " %s", flg_output);
-}
-
-static
-void print_perms(int perms)
-{
- fprintf(stdout, " %8X", perms);
-}
-
-static
-void print_sid(sid_t *sid)
-{
- int i, comps = sid->auths;
- fprintf(stdout, "S-%u-%u", sid->ver, sid->auth[5]);
-
- for (i = 0; i < comps; i++) {
-
- fprintf(stdout, "-%u", sid->sub_auths[i]);
-
- }
- fprintf(stdout, "\n");
-}
-
-static
-void print_acl(ACL *acl, const char *prefix)
-{
- int i;
-
- for (i = 0; i < acl->num_aces; i++) {
- fprintf(stdout, ";;%s", prefix);
- print_type(acl->aces[i]->type);
- print_flags(acl->aces[i]->flags);
- print_perms(acl->aces[i]->perms);
- fprintf(stdout, " ");
- print_sid(acl->aces[i]->trustee);
- }
-}
-
-static
-int print_sec(SEC_DESC *sec_desc)
-{
- if (!print_security) return 1;
- fprintf(stdout, ";; SECURITY\n");
- fprintf(stdout, ";; Owner: ");
- print_sid(sec_desc->owner);
- fprintf(stdout, ";; Group: ");
- print_sid(sec_desc->group);
- if (sec_desc->sacl) {
- fprintf(stdout, ";; SACL:\n");
- print_acl(sec_desc->sacl, " ");
- }
- if (sec_desc->dacl) {
- fprintf(stdout, ";; DACL:\n");
- print_acl(sec_desc->dacl, " ");
- }
- return 1;
-}
-
-/*
- * Value print function here ...
- */
-static
-int print_val(const char *path, char *val_name, int val_type, int data_len,
- void *data_blk, int terminal, int first, int last)
-{
- char data_asc[1024];
-
- memset(data_asc, 0, sizeof(data_asc));
- if (!terminal && first)
- fprintf(stdout, "%s\n", path);
- data_to_ascii((unsigned char *)data_blk, data_len, val_type, data_asc,
- sizeof(data_asc) - 1);
- fprintf(stdout, " %s = %s : %s\n", (val_name?val_name:"<No Name>"),
- val_to_str(val_type, reg_type_names), data_asc);
- return 1;
-}
-
-static
-void usage(void)
-{
- fprintf(stderr, "Usage: editreg [-f] [-v] [-p] [-k] [-s] [-c <command-file>] <registryfile>\n");
- fprintf(stderr, "Version: 0.1\n\n");
- fprintf(stderr, "\n\t-v\t sets verbose mode");
- fprintf(stderr, "\n\t-f\t sets full print mode where non-terminals are printed");
- fprintf(stderr, "\n\t-p\t prints the registry");
- fprintf(stderr, "\n\t-s\t prints security descriptors");
- fprintf(stderr, "\n\t-c <command-file>\t specifies a command file");
- fprintf(stderr, "\n");
-}
-
-int main(int argc, char *argv[])
-{
- REGF *regf;
- extern char *optarg;
- extern int optind;
- int opt, print_keys = 0;
- int regf_opt = 1; /* Command name */
- int commands = 0, modified = 0;
- char *cmd_file_name = NULL;
- char *out_file_name = NULL;
- CMD_FILE *cmd_file = NULL;
- sid_t *lsid;
-
- if (argc < 2) {
- usage();
- exit(1);
- }
-
- /*
- * Now, process the arguments
- */
-
- while ((opt = getopt(argc, argv, "fspvko:O:c:")) != EOF) {
- switch (opt) {
- case 'c':
- commands = 1;
- cmd_file_name = optarg;
- regf_opt += 2;
- break;
-
- case 'f':
- full_print = 1;
- regf_opt++;
- break;
-
- case 'o':
- out_file_name = optarg;
- regf_opt += 2;
- break;
-
- case 'O':
- def_owner_sid_str = strdup(optarg);
- regf_opt += 2;
- if (!sid_string_to_sid(&lsid, def_owner_sid_str)) {
- fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n",
- def_owner_sid_str);
- free(&def_owner_sid_str[0]);
- def_owner_sid_str = NULL;
- }
- else
- nt_delete_sid(lsid);
- break;
-
- case 'p':
- print_keys++;
- regf_opt++;
- break;
-
- case 's':
- print_security++;
- full_print++;
- regf_opt++;
- break;
-
- case 'v':
- verbose++;
- regf_opt++;
- break;
-
- case 'k':
- regf_opt++;
- break;
-
- default:
- usage();
- exit(1);
- break;
- }
- }
-
- /*
- * We only want to complain about the lack of a default owner SID if
- * we need one. This approximates that need
- */
- if (!def_owner_sid_str) {
- def_owner_sid_str = "S-1-5-21-1-2-3-4";
- if (out_file_name || verbose)
- fprintf(stderr, "Warning, default owner SID not set. Setting to %s\n",
- def_owner_sid_str);
- }
-
- if ((regf = nt_create_regf()) == NULL) {
- fprintf(stderr, "Could not create registry object: %s\n", strerror(errno));
- exit(2);
- }
-
- if (regf_opt < argc) { /* We have a registry file */
- if (!nt_set_regf_input_file(regf, argv[regf_opt])) {
- fprintf(stderr, "Could not set name of registry file: %s, %s\n",
- argv[regf_opt], strerror(errno));
- exit(3);
- }
-
- /* Now, open it, and bring it into memory :-) */
-
- if (nt_load_registry(regf) < 0) {
- fprintf(stderr, "Could not load registry: %s\n", argv[1]);
- exit(4);
- }
- }
-
- if (out_file_name) {
- if (!nt_set_regf_output_file(regf, out_file_name)) {
- fprintf(stderr, "Could not set name of output registry file: %s, %s\n",
- out_file_name, strerror(errno));
- exit(3);
- }
-
- }
-
- if (commands) {
- CMD *cmd;
-
- cmd_file = cmd_file_create(cmd_file_name);
-
- while ((cmd = cmd_file->cmd_ops.get_cmd(cmd_file->fd)) != NULL) {
-
- /*
- * Now, apply the requests to the tree ...
- */
- switch (cmd->cmd) {
- case CMD_ADD_KEY: {
- REG_KEY *tmp = NULL;
-
- tmp = nt_find_key_by_name(regf->root, cmd->key);
-
- /* If we found it, apply the other bits, else create such a key */
-
- if (!tmp) {
- tmp = nt_add_reg_key(regf, cmd->key, True);
- modified = 1;
- }
-
- while (cmd->val_count) {
- VAL_SPEC_LIST *val = cmd->val_spec_list;
- VAL_KEY *reg_val = NULL;
-
- if (val->type == REG_TYPE_DELETE) {
- reg_val = nt_delete_reg_value(tmp, val -> name);
- if (reg_val) nt_delete_val_key(reg_val);
- modified = 1;
- }
- else {
- reg_val = nt_add_reg_value(tmp, val->name, val->type,
- val->val);
- modified = 1;
- }
-
- cmd->val_spec_list = val->next;
- free_val_spec_list(val);
- cmd->val_count--;
- }
-
- break;
- }
-
- case CMD_DEL_KEY:
- /*
- * Any value does not matter ...
- * Find the key if it exists, and delete it ...
- */
-
- nt_delete_key_by_name(regf, cmd->key);
- modified = 1;
- break;
- }
- }
- free_cmd(cmd);
- }
-
- /*
- * At this point, we should have a registry in memory and should be able
- * to iterate over it.
- */
-
- if (print_keys) {
- nt_key_iterator(regf, regf->root, 0, "", print_key, print_sec, print_val);
- }
-
- /*
- * If there was an out_file_name and the tree was modified, print it
- */
- if (modified && out_file_name)
- if (!nt_store_registry(regf)) {
- fprintf(stdout, "Error storing registry\n");
- }
-
- return 0;
-}
diff --git a/source/torture/locktest.c b/source/utils/locktest.c
index 86379bf3b6d..f34e12885be 100644..100755
--- a/source/torture/locktest.c
+++ b/source/utils/locktest.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
randomised byte range lock tester
Copyright (C) Andrew Tridgell 1999
@@ -22,27 +23,26 @@
#include "includes.h"
-static fstring password[2];
-static fstring username[2];
-static int got_user;
+static fstring password;
+static fstring username;
static int got_pass;
-static BOOL use_kerberos;
static int numops = 1000;
static BOOL showall;
static BOOL analyze;
static BOOL hide_unlock_fails;
static BOOL use_oplocks;
-static unsigned lock_range = 100;
-static unsigned lock_base = 0;
-static unsigned min_length = 0;
-static BOOL exact_error_codes;
-static BOOL zero_zero;
#define FILENAME "\\locktest.dat"
+#define LOCKRANGE 1000
+#define LOCKBASE 0
+
+/*
+#define LOCKBASE (0x40000000 - 50)
+*/
#define READ_PCT 50
-#define LOCK_PCT 45
-#define UNLOCK_PCT 70
+#define LOCK_PCT 35
+#define UNLOCK_PCT 55
#define RANGE_MULTIPLE 1
#define NSERVERS 2
#define NCONNECTIONS 2
@@ -51,11 +51,9 @@ static BOOL zero_zero;
#define NASTY_POSIX_LOCK_HACK 0
-enum lock_op {OP_LOCK, OP_UNLOCK, OP_REOPEN};
struct record {
- enum lock_op lock_op;
- enum brl_type lock_type;
+ char r1, r2;
char conn, f;
SMB_BIG_UINT start, len;
char needed;
@@ -65,37 +63,10 @@ struct record {
#if PRESETS
static struct record preset[] = {
-{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 3, 0, 1},
-{OP_UNLOCK, 0 , 0, 0, 2, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
-{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, READ_LOCK, 0, 0, 1, 1, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
-{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 3, 1, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
-{OP_LOCK, READ_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 1, 1, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
-{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, READ_LOCK, 0, 0, 1, 1, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
-{OP_LOCK, WRITE_LOCK, 0, 0, 2, 0, 1},
-{OP_LOCK, READ_LOCK, 0, 0, 3, 1, 1},
-{OP_LOCK, WRITE_LOCK, 0, 0, 0, 0, 1},
-{OP_REOPEN, 0, 0, 0, 0, 0, 1},
-
+{36, 5, 0, 0, 0, 8, 1},
+{ 2, 6, 0, 1, 0, 1, 1},
+{53, 92, 0, 0, 0, 0, 1},
+{99, 11, 0, 0, 7, 1, 1},
};
#endif
@@ -137,7 +108,7 @@ static void show_locks(void)
/*****************************************************
return a connection to a server
*******************************************************/
-static struct cli_state *connect_one(char *share, int snum)
+struct cli_state *connect_one(char *share)
{
struct cli_state *c;
struct nmb_name called, calling;
@@ -148,31 +119,30 @@ static struct cli_state *connect_one(char *share, int snum)
static int count;
fstrcpy(server,share+2);
- share = strchr_m(server,'\\');
+ share = strchr(server,'\\');
if (!share) return NULL;
*share = 0;
share++;
server_n = server;
- zero_ip(&ip);
+ zero_ip(&ip);
- slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
+ slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++);
make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , server, 0x20);
again:
- zero_ip(&ip);
+ zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
+ !cli_connect(c, server_n, &ip)) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
- c->use_kerberos = use_kerberos;
-
if (!cli_session_request(c, &calling, &called)) {
DEBUG(0,("session request to %s failed\n", called.name));
cli_shutdown(c);
@@ -194,19 +164,13 @@ static struct cli_state *connect_one(char *share, int snum)
if (!got_pass) {
char *pass = getpass("Password: ");
if (pass) {
- fstrcpy(password[0], pass);
- fstrcpy(password[1], pass);
+ pstrcpy(password, pass);
}
}
- if (got_pass == 1) {
- fstrcpy(password[1], password[0]);
- fstrcpy(username[1], username[0]);
- }
-
- if (!cli_session_setup(c, username[snum],
- password[snum], strlen(password[snum]),
- password[snum], strlen(password[snum]),
+ if (!cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
lp_workgroup())) {
DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
return NULL;
@@ -227,7 +191,7 @@ static struct cli_state *connect_one(char *share, int snum)
DEBUG(4,(" session setup ok\n"));
if (!cli_send_tconX(c, share, "?????",
- password[snum], strlen(password[snum])+1)) {
+ password, strlen(password)+1)) {
DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
return NULL;
@@ -250,15 +214,14 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NS
for (conn=0;conn<NCONNECTIONS;conn++) {
if (cli[server][conn]) {
for (f=0;f<NFILES;f++) {
- if (fnum[server][conn][f] != -1) {
- cli_close(cli[server][conn], fnum[server][conn][f]);
- fnum[server][conn][f] = -1;
- }
+ cli_close(cli[server][conn], fnum[server][conn][f]);
}
cli_ulogoff(cli[server][conn]);
cli_shutdown(cli[server][conn]);
+ SAFE_FREE(cli[server][conn]);
+ cli[server][conn] = NULL;
}
- cli[server][conn] = connect_one(share[server], server);
+ cli[server][conn] = connect_one(share[server]);
if (!cli[server][conn]) {
DEBUG(0,("Failed to connect to %s\n", share[server]));
exit(1);
@@ -276,61 +239,53 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
unsigned f = rec->f;
SMB_BIG_UINT start = rec->start;
SMB_BIG_UINT len = rec->len;
- enum brl_type op = rec->lock_type;
+ unsigned r1 = rec->r1;
+ unsigned r2 = rec->r2;
+ unsigned op;
int server;
BOOL ret[NSERVERS];
- NTSTATUS status[NSERVERS];
- switch (rec->lock_op) {
- case OP_LOCK:
+ if (r1 < READ_PCT) {
+ op = READ_LOCK;
+ } else {
+ op = WRITE_LOCK;
+ }
+
+ if (r2 < LOCK_PCT) {
/* set a lock */
for (server=0;server<NSERVERS;server++) {
ret[server] = cli_lock64(cli[server][conn],
fnum[server][conn][f],
start, len, LOCK_TIMEOUT, op);
- status[server] = cli_nt_error(cli[server][conn]);
- if (!exact_error_codes &&
- NT_STATUS_EQUAL(status[server],
- NT_STATUS_FILE_LOCK_CONFLICT)) {
- status[server] = NT_STATUS_LOCK_NOT_GRANTED;
- }
}
- if (showall || !NT_STATUS_EQUAL(status[0],status[1])) {
- printf("lock conn=%u f=%u range=%.0f(%.0f) op=%s -> %s:%s\n",
+ if (showall || ret[0] != ret[1]) {
+ printf("lock conn=%u f=%u range=%.0f:%.0f(%.0f) op=%s -> %u:%u\n",
conn, f,
- (double)start, (double)len,
+ (double)start, (double)start+len-1, (double)len,
op==READ_LOCK?"READ_LOCK":"WRITE_LOCK",
- nt_errstr(status[0]), nt_errstr(status[1]));
+ ret[0], ret[1]);
}
- if (showall || !NT_STATUS_EQUAL(status[0],status[1])) show_locks();
- if (!NT_STATUS_EQUAL(status[0],status[1])) return False;
- break;
-
- case OP_UNLOCK:
+ if (showall || ret[0] != ret[1]) show_locks();
+ if (ret[0] != ret[1]) return False;
+ } else if (r2 < LOCK_PCT+UNLOCK_PCT) {
/* unset a lock */
for (server=0;server<NSERVERS;server++) {
ret[server] = cli_unlock64(cli[server][conn],
fnum[server][conn][f],
start, len);
- status[server] = cli_nt_error(cli[server][conn]);
}
- if (showall ||
- (!hide_unlock_fails && !NT_STATUS_EQUAL(status[0],status[1]))) {
- printf("unlock conn=%u f=%u range=%.0f(%.0f) -> %s:%s\n",
+ if (showall || (!hide_unlock_fails && (ret[0] != ret[1]))) {
+ printf("unlock conn=%u f=%u range=%.0f:%.0f(%.0f) -> %u:%u\n",
conn, f,
- (double)start, (double)len,
- nt_errstr(status[0]), nt_errstr(status[1]));
+ (double)start, (double)start+len-1, (double)len,
+ ret[0], ret[1]);
}
- if (showall || !NT_STATUS_EQUAL(status[0],status[1])) show_locks();
- if (!hide_unlock_fails && !NT_STATUS_EQUAL(status[0],status[1]))
- return False;
- break;
-
- case OP_REOPEN:
+ if (showall || ret[0] != ret[1]) show_locks();
+ if (!hide_unlock_fails && ret[0] != ret[1]) return False;
+ } else {
/* reopen the file */
for (server=0;server<NSERVERS;server++) {
cli_close(cli[server][conn], fnum[server][conn][f]);
- fnum[server][conn][f] = -1;
}
for (server=0;server<NSERVERS;server++) {
fnum[server][conn][f] = cli_open(cli[server][conn], FILENAME,
@@ -346,9 +301,7 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
conn, f);
show_locks();
}
- break;
}
-
return True;
}
@@ -418,7 +371,7 @@ static void test_locks(char *share[NSERVERS])
{
struct cli_state *cli[NSERVERS][NCONNECTIONS];
int fnum[NSERVERS][NCONNECTIONS][NFILES];
- int n, i, n1, skip, r1, r2;
+ int n, i, n1;
ZERO_STRUCT(fnum);
ZERO_STRUCT(cli);
@@ -429,36 +382,20 @@ static void test_locks(char *share[NSERVERS])
#if PRESETS
if (n < sizeof(preset) / sizeof(preset[0])) {
recorded[n] = preset[n];
- } else {
+ } else
#endif
+ {
recorded[n].conn = random() % NCONNECTIONS;
recorded[n].f = random() % NFILES;
- recorded[n].start = lock_base + ((unsigned)random() % (lock_range-1));
- recorded[n].len = min_length +
- random() % (lock_range-(recorded[n].start-lock_base));
+ recorded[n].start = LOCKBASE + ((unsigned)random() % (LOCKRANGE-1));
+ recorded[n].len = 1 +
+ random() % (LOCKRANGE-(recorded[n].start-LOCKBASE));
recorded[n].start *= RANGE_MULTIPLE;
recorded[n].len *= RANGE_MULTIPLE;
- r1 = random() % 100;
- r2 = random() % 100;
- if (r1 < READ_PCT) {
- recorded[n].lock_type = READ_LOCK;
- } else {
- recorded[n].lock_type = WRITE_LOCK;
- }
- if (r2 < LOCK_PCT) {
- recorded[n].lock_op = OP_LOCK;
- } else if (r2 < UNLOCK_PCT) {
- recorded[n].lock_op = OP_UNLOCK;
- } else {
- recorded[n].lock_op = OP_REOPEN;
- }
+ recorded[n].r1 = random() % 100;
+ recorded[n].r2 = random() % 100;
recorded[n].needed = True;
- if (!zero_zero && recorded[n].start==0 && recorded[n].len==0) {
- recorded[n].len = 1;
- }
-#if PRESETS
}
-#endif
}
reconnect(cli, fnum, share);
@@ -468,8 +405,6 @@ static void test_locks(char *share[NSERVERS])
if (n == numops || !analyze) return;
n++;
- skip = n/2;
-
while (1) {
n1 = n;
@@ -477,37 +412,26 @@ static void test_locks(char *share[NSERVERS])
reconnect(cli, fnum, share);
open_files(cli, fnum);
- for (i=0;i<n-skip;i+=skip) {
- int m, j;
- printf("excluding %d-%d\n", i, i+skip-1);
- for (j=i;j<i+skip;j++) {
- recorded[j].needed = False;
- }
+ for (i=0;i<n-1;i++) {
+ int m;
+ recorded[i].needed = False;
close_files(cli, fnum);
open_files(cli, fnum);
m = retest(cli, fnum, n);
if (m == n) {
- for (j=i;j<i+skip;j++) {
- recorded[j].needed = True;
- }
+ recorded[i].needed = True;
} else {
- if (i+(skip-1) < m) {
- memmove(&recorded[i], &recorded[i+skip],
- (m-(i+skip-1))*sizeof(recorded[0]));
+ if (i < m) {
+ memmove(&recorded[i], &recorded[i+1],
+ (m-i)*sizeof(recorded[0]));
}
- n = m-(skip-1);
+ n = m;
i--;
}
}
- if (skip > 1) {
- skip = skip/2;
- printf("skip=%d\n", skip);
- continue;
- }
-
if (n1 == n) break;
}
@@ -522,9 +446,9 @@ static void test_locks(char *share[NSERVERS])
close_files(cli, fnum);
for (i=0;i<n;i++) {
- printf("{%d, %d, %u, %u, %.0f, %.0f, %u},\n",
- recorded[i].lock_op,
- recorded[i].lock_type,
+ printf("{%u, %u, %u, %u, %.0f, %.0f, %u},\n",
+ recorded[i].r1,
+ recorded[i].r2,
recorded[i].conn,
recorded[i].f,
(double)recorded[i].start,
@@ -541,19 +465,12 @@ static void usage(void)
"Usage:\n\
locktest //server1/share1 //server2/share2 [options..]\n\
options:\n\
- -U user%%pass (may be specified twice)\n\
- -k use kerberos\n\
+ -U user%%pass\n\
-s seed\n\
-o numops\n\
-u hide unlock fails\n\
-a (show all ops)\n\
- -A analyse for minimal ops\n\
-O use oplocks\n\
- -E enable exact error code checking\n\
- -Z enable the zero/zero lock\n\
- -R range set lock range\n\
- -B base set lock base\n\
- -M min set min lock length\n\
");
}
@@ -565,13 +482,15 @@ static void usage(void)
char *share[NSERVERS];
extern char *optarg;
extern int optind;
+ extern FILE *dbf;
int opt;
char *p;
int seed, server;
+ static pstring servicesf = CONFIGFILE;
setlinebuf(stdout);
- dbf = x_stderr;
+ dbf = stderr;
if (argc < 3 || argv[1][0] == '-') {
usage();
@@ -588,49 +507,30 @@ static void usage(void)
argc -= NSERVERS;
argv += NSERVERS;
- lp_load(dyn_CONFIGFILE,True,False,False);
+ TimeInit();
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
+
+ lp_load(servicesf,True,False,False);
load_interfaces();
if (getenv("USER")) {
- fstrcpy(username[0],getenv("USER"));
- fstrcpy(username[1],getenv("USER"));
+ pstrcpy(username,getenv("USER"));
}
seed = time(NULL);
- while ((opt = getopt(argc, argv, "U:s:ho:aAW:OkR:B:M:EZ")) != EOF) {
+ while ((opt = getopt(argc, argv, "U:s:ho:aAW:O")) != EOF) {
switch (opt) {
- case 'k':
-#ifdef HAVE_KRB5
- use_kerberos = True;
-#else
- d_printf("No kerberos support compiled in\n");
- exit(1);
-#endif
- break;
case 'U':
- got_user = 1;
- if (got_pass == 2) {
- d_printf("Max of 2 usernames\n");
- exit(1);
- }
- fstrcpy(username[got_pass],optarg);
- p = strchr_m(username[got_pass],'%');
+ pstrcpy(username,optarg);
+ p = strchr(username,'%');
if (p) {
*p = 0;
- fstrcpy(password[got_pass], p+1);
- got_pass++;
+ pstrcpy(password, p+1);
+ got_pass = 1;
}
break;
- case 'R':
- lock_range = strtol(optarg, NULL, 0);
- break;
- case 'B':
- lock_base = strtol(optarg, NULL, 0);
- break;
- case 'M':
- min_length = strtol(optarg, NULL, 0);
- break;
case 's':
seed = atoi(optarg);
break;
@@ -649,12 +549,6 @@ static void usage(void)
case 'A':
analyze = True;
break;
- case 'Z':
- zero_zero = True;
- break;
- case 'E':
- exact_error_codes = True;
- break;
case 'h':
usage();
exit(1);
@@ -664,14 +558,13 @@ static void usage(void)
}
}
- if(use_kerberos && !got_user) got_pass = True;
-
argc -= optind;
argv += optind;
DEBUG(0,("seed=%u\n", seed));
srandom(seed);
+ locking_init(1);
test_locks(share);
return(0);
diff --git a/source/torture/locktest2.c b/source/utils/locktest2.c
index 5fbaf9ec584..ac16055c0f1 100644..100755
--- a/source/torture/locktest2.c
+++ b/source/utils/locktest2.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
byte range lock tester - with local filesystem support
Copyright (C) Andrew Tridgell 1999
@@ -62,7 +63,7 @@ struct record {
static struct record *recorded;
-static int try_open(struct cli_state *c, char *nfs, int fstype, const char *fname, int flags)
+static int try_open(struct cli_state *c, char *nfs, int fstype, char *fname, int flags)
{
pstring path;
@@ -94,7 +95,7 @@ static BOOL try_close(struct cli_state *c, int fstype, int fd)
static BOOL try_lock(struct cli_state *c, int fstype,
int fd, unsigned start, unsigned len,
- enum brl_type op)
+ int op)
{
struct flock lock;
@@ -149,41 +150,97 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
/*****************************************************
return a connection to a server
*******************************************************/
-static struct cli_state *connect_one(char *share)
+struct cli_state *connect_one(char *share)
{
struct cli_state *c;
+ struct nmb_name called, calling;
char *server_n;
fstring server;
+ struct in_addr ip;
fstring myname;
static int count;
- NTSTATUS nt_status;
fstrcpy(server,share+2);
- share = strchr_m(server,'\\');
+ share = strchr(server,'\\');
if (!share) return NULL;
*share = 0;
share++;
server_n = server;
+ zero_ip(&ip);
+
+ slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++);
+
+ make_nmb_name(&calling, myname, 0x0);
+ make_nmb_name(&called , server, 0x20);
+
+ again:
+ zero_ip(&ip);
+
+ /* have to open a new connection */
+ if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
+ !cli_connect(c, server_n, &ip)) {
+ DEBUG(0,("Connection to %s failed\n", server_n));
+ return NULL;
+ }
+
+ if (!cli_session_request(c, &calling, &called)) {
+ DEBUG(0,("session request to %s failed\n", called.name));
+ cli_shutdown(c);
+ if (strcmp(called.name, "*SMBSERVER")) {
+ make_nmb_name(&called , "*SMBSERVER", 0x20);
+ goto again;
+ }
+ return NULL;
+ }
+
+ DEBUG(4,(" session request ok\n"));
+
+ if (!cli_negprot(c)) {
+ DEBUG(0,("protocol negotiation failed\n"));
+ cli_shutdown(c);
+ return NULL;
+ }
+
if (!got_pass) {
char *pass = getpass("Password: ");
if (pass) {
- fstrcpy(password, pass);
+ pstrcpy(password, pass);
}
}
- slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
+ if (!cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ lp_workgroup())) {
+ DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
+ return NULL;
+ }
- nt_status = cli_full_connection(&c, myname, server_n, NULL, 0, share, "?????",
- username, lp_workgroup(), password, 0,
- Undefined, NULL);
+ /*
+ * These next two lines are needed to emulate
+ * old client behaviour for people who have
+ * scripts based on client output.
+ * QUESTION ? Do we want to have a 'client compatibility
+ * mode to turn these on/off ? JRA.
+ */
+
+ if (*c->server_domain || *c->server_os || *c->server_type)
+ DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+ c->server_domain,c->server_os,c->server_type));
+
+ DEBUG(4,(" session setup ok\n"));
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status)));
+ if (!cli_send_tconX(c, share, "?????",
+ password, strlen(password)+1)) {
+ DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ cli_shutdown(c);
return NULL;
}
+ DEBUG(4,(" tconx ok\n"));
+
c->use_oplocks = use_oplocks;
return c;
@@ -210,6 +267,8 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS],
}
cli_ulogoff(cli[server][conn]);
cli_shutdown(cli[server][conn]);
+ SAFE_FREE(cli[server][conn]);
+ cli[server][conn] = NULL;
}
cli[server][conn] = connect_one(share[server]);
if (!cli[server][conn]) {
@@ -233,7 +292,7 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
unsigned len = rec->len;
unsigned r1 = rec->r1;
unsigned r2 = rec->r2;
- enum brl_type op;
+ unsigned op;
int server;
BOOL ret[NSERVERS];
@@ -474,13 +533,15 @@ static void usage(void)
char *share1, *share2, *nfspath1, *nfspath2;
extern char *optarg;
extern int optind;
+ extern FILE *dbf;
int opt;
char *p;
int seed;
+ static pstring servicesf = CONFIGFILE;
setlinebuf(stdout);
- dbf = x_stderr;
+ dbf = stderr;
if (argc < 5 || argv[1][0] == '-') {
usage();
@@ -500,11 +561,15 @@ static void usage(void)
argc -= 4;
argv += 4;
- lp_load(dyn_CONFIGFILE,True,False,False);
+ TimeInit();
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
+
+ lp_load(servicesf,True,False,False);
load_interfaces();
if (getenv("USER")) {
- fstrcpy(username,getenv("USER"));
+ pstrcpy(username,getenv("USER"));
}
seed = time(NULL);
@@ -512,11 +577,11 @@ static void usage(void)
while ((opt = getopt(argc, argv, "U:s:ho:aAW:O")) != EOF) {
switch (opt) {
case 'U':
- fstrcpy(username,optarg);
- p = strchr_m(username,'%');
+ pstrcpy(username,optarg);
+ p = strchr(username,'%');
if (p) {
*p = 0;
- fstrcpy(password, p+1);
+ pstrcpy(password, p+1);
got_pass = 1;
}
break;
diff --git a/source/utils/log2pcaphex.c b/source/utils/log2pcaphex.c
deleted file mode 100644
index 4804b993382..00000000000
--- a/source/utils/log2pcaphex.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Utility to extract pcap files from samba (log level 10) log files
-
- Copyright (C) Jelmer Vernooij 2003
- Thanks to Tim Potter for the genial idea
-
- Portions (from capconvert.c) (C) Andrew Tridgell 1997
- Portions (from text2pcap.c) (C) Ashok Narayanan 2001
-
- Example use with -h parameter:
- log2pcaphex < samba-log-file | text2pcap -T 139,139 - foo.pcap
-
- TODO: Have correct IP and TCP checksums.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include <assert.h>
-
-int quiet = 0;
-int hexformat = 0;
-
-#define itoa(a) ((a) < 0xa?'0'+(a):'A' + (a-0xa))
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
-/* tcpdump file format */
-struct tcpdump_file_header {
- uint32 magic;
- uint16 major;
- uint16 minor;
- int32 zone;
- uint32 sigfigs;
- uint32 snaplen;
- uint32 linktype;
-};
-
-struct tcpdump_packet {
- struct timeval ts;
- uint32 caplen;
- uint32 len;
-};
-
-typedef struct {
- uint8 ver_hdrlen;
- uint8 dscp;
- uint16 packet_length;
- uint16 identification;
- uint8 flags;
- uint8 fragment;
- uint8 ttl;
- uint8 protocol;
- uint16 hdr_checksum;
- uint32 src_addr;
- uint32 dest_addr;
-} hdr_ip_t;
-
-static hdr_ip_t HDR_IP = {0x45, 0, 0, 0x3412, 0, 0, 0xff, 6, 0, 0x01010101, 0x02020202};
-
-typedef struct {
- uint16 source_port;
- uint16 dest_port;
- uint32 seq_num;
- uint32 ack_num;
- uint8 hdr_length;
- uint8 flags;
- uint16 window;
- uint16 checksum;
- uint16 urg;
-} hdr_tcp_t;
-
-static hdr_tcp_t HDR_TCP = {139, 139, 0, 0, 0x50, 0, 0, 0, 0};
-
-void print_pcap_header(FILE *out)
-{
- struct tcpdump_file_header h;
- h.magic = TCPDUMP_MAGIC;
- h.major = 2;
- h.minor = 4;
- h.zone = 0;
- h.sigfigs = 0;
- h.snaplen = 102400; /* As long packets as possible */
- h.linktype = 101; /* Raw IP */
- fwrite(&h, sizeof(struct tcpdump_file_header), 1, out);
-}
-
-void print_pcap_packet(FILE *out, unsigned char *data, long length, long caplen)
-{
- static int i = 0;
- struct tcpdump_packet p;
- i++;
- p.ts.tv_usec = 0;
- p.ts.tv_sec = 0;
- p.caplen = caplen;
- p.len = length;
- fwrite(&p, sizeof(struct tcpdump_packet), 1, out);
- fwrite(data, sizeof(unsigned char), caplen, out);
-}
-
-void print_hex_packet(FILE *out, unsigned char *data, long length)
-{
- long i,cur = 0;
- while(cur < length) {
- fprintf(out, "%06lX ", cur);
- for(i = cur; i < length && i < cur + 16; i++) {
- fprintf(out, "%02x ", data[i]);
- }
-
- cur = i;
- fprintf(out, "\n");
- }
-}
-
-void print_netbios_packet(FILE *out, unsigned char *data, long length, long actual_length)
-{
- unsigned char *newdata; long offset = 0;
- long newlen;
-
- newlen = length+sizeof(HDR_IP)+sizeof(HDR_TCP);
- newdata = malloc(newlen);
-
- HDR_IP.packet_length = htons(newlen);
- HDR_TCP.window = htons(0x2000);
- HDR_TCP.source_port = HDR_TCP.dest_port = htons(139);
-
- memcpy(newdata+offset, &HDR_IP, sizeof(HDR_IP));offset+=sizeof(HDR_IP);
- memcpy(newdata+offset, &HDR_TCP, sizeof(HDR_TCP));offset+=sizeof(HDR_TCP);
- memcpy(newdata+offset,data,length);
-
- print_pcap_packet(out, newdata, newlen, actual_length+offset);
- free(newdata);
-}
-
-unsigned char *curpacket = NULL;
-long curpacket_len = 0;
-
-void read_log_msg(FILE *in, unsigned char **_buffer, long *buffersize, long *data_offset, long *data_length)
-{
- unsigned char *buffer;
- int tmp; long i;
- assert(fscanf(in, " size=%ld\n", buffersize));
- *buffersize+=4; /* for netbios */
- buffer = malloc(*buffersize);
- memset(buffer, 0, *buffersize);
- /* NetBIOS */
- buffer[0] = 0x00;
- buffer[1] = 0x00;
- memcpy(buffer+2, &buffersize, 2);
- buffer[4] = 0xFF;
- buffer[5] = 'S';
- buffer[6] = 'M';
- buffer[7] = 'B';
- assert(fscanf(in, " smb_com=0x%x\n", &tmp)); buffer[smb_com] = tmp;
- assert(fscanf(in, " smb_rcls=%d\n", &tmp)); buffer[smb_rcls] = tmp;
- assert(fscanf(in, " smb_reh=%d\n", &tmp)); buffer[smb_reh] = tmp;
- assert(fscanf(in, " smb_err=%d\n", &tmp)); memcpy(buffer+smb_err, &tmp, 2);
- assert(fscanf(in, " smb_flg=%d\n", &tmp)); buffer[smb_flg] = tmp;
- assert(fscanf(in, " smb_flg2=%d\n", &tmp)); memcpy(buffer+smb_flg2, &tmp, 2);
- assert(fscanf(in, " smb_tid=%d\n", &tmp)); memcpy(buffer+smb_tid, &tmp, 2);
- assert(fscanf(in, " smb_pid=%d\n", &tmp)); memcpy(buffer+smb_pid, &tmp, 2);
- assert(fscanf(in, " smb_uid=%d\n", &tmp)); memcpy(buffer+smb_uid, &tmp, 2);
- assert(fscanf(in, " smb_mid=%d\n", &tmp)); memcpy(buffer+smb_mid, &tmp, 2);
- assert(fscanf(in, " smt_wct=%d\n", &tmp)); buffer[smb_wct] = tmp;
- for(i = 0; i < buffer[smb_wct]; i++) {
- assert(fscanf(in, " smb_vwv[%*2d]=%*5d (0x%X)\n", &tmp));
- memcpy(buffer+smb_vwv+i*2, &tmp, 2);
- }
-
- *data_offset = smb_vwv+buffer[smb_wct]*2;
- assert(fscanf(in, " smb_bcc=%ld\n", data_length)); buffer[(*data_offset)] = *data_length;
- (*data_offset)+=2;
- *_buffer = buffer;
-}
-
-long read_log_data(FILE *in, unsigned char *buffer, long data_length)
-{
- long i, addr; char real[2][16]; int ret;
- unsigned char tmp;
- for(i = 0; i < data_length; i++) {
- if(i % 16 == 0){
- if(i != 0) { /* Read data after each line */
- assert(fscanf(in, "%8s %8s", real[0], real[1]) == 2);
- }
- ret = fscanf(in, " [%03lX]", &addr);
- if(!ret) {
- if(!quiet)fprintf(stderr, "Only first %ld bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i);
- return i-1;
- }
- assert(addr == i);
- }
- if(!fscanf(in, "%02lX", &tmp)) {
- if(!quiet)fprintf(stderr, "Only first %ld bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i-1);
- return i-1;
- }
- buffer[i] = tmp;
- }
- return data_length;
-}
-
-int main (int argc, char **argv)
-{
- const char *infile, *outfile;
- FILE *out, *in;
- int opt;
- poptContext pc;
- char buffer[4096];
- long data_offset, data_length;
- long data_bytes_read;
- int in_packet = 0;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "quiet", 'q', POPT_ARG_NONE, &quiet, 0, "Be quiet, don't output warnings" },
- { "hex", 'h', POPT_ARG_NONE, &hexformat, 0, "Output format readable by text2pcap" },
- POPT_TABLEEND
- };
-
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
- poptSetOtherOptionHelp(pc, "[<infile> [<outfile>]]");
-
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- }
- }
-
- poptGetArg(pc); /* Drop argv[0], the program name */
-
- infile = poptGetArg(pc);
-
- if(infile) {
- in = fopen(infile, "r");
- if(!in) {
- perror("fopen");
- return 1;
- }
- } else in = stdin;
-
- outfile = poptGetArg(pc);
-
- if(outfile) {
- out = fopen(outfile, "w+");
- if(!out) {
- perror("fopen");
- fprintf(stderr, "Can't find %s, using stdout...\n", outfile);
- }
- }
-
- if(!outfile) out = stdout;
-
- if(!hexformat)print_pcap_header(out);
-
- while(!feof(in)) {
- fgets(buffer, sizeof(buffer), in);
- if(buffer[0] == '[') { /* Header */
- if(strstr(buffer, "show_msg")) {
- in_packet++;
- if(in_packet == 1)continue;
- read_log_msg(in, &curpacket, &curpacket_len, &data_offset, &data_length);
- } else if(in_packet && strstr(buffer, "dump_data")) {
- data_bytes_read = read_log_data(in, curpacket+data_offset, data_length);
- } else {
- if(in_packet){
- if(hexformat) print_hex_packet(out, curpacket, curpacket_len);
- else print_netbios_packet(out, curpacket, curpacket_len, data_bytes_read+data_offset);
- free(curpacket);
- }
- in_packet = 0;
- }
- }
- }
-
- return 0;
-}
diff --git a/source/utils/make_printerdef.c b/source/utils/make_printerdef.c
new file mode 100755
index 00000000000..ee808c73f3c
--- /dev/null
+++ b/source/utils/make_printerdef.c
@@ -0,0 +1,591 @@
+ /*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Create printer definition files.
+
+ Copyright (C) Jean-Francois.Micouleau@utc.fr, 10/26/97 - 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+#define DEBUGIT
+*/
+
+char *files_to_copy;
+char *driverfile, *datafile, *helpfile, *languagemonitor, *vendorsetup;
+const char *datatype;
+char buffer[50][sizeof(pstring)];
+char sbuffer[50][sizeof(pstring)];
+char sub_dir[50][2][sizeof(pstring)];
+
+static void usage(char *name)
+{
+ fprintf(stderr,"%s: printer.def \"Printer Name\"\n", name);
+}
+
+static char *myfgets(char *s, int n, FILE *stream)
+{
+ char *LString1;
+ char *LString2;
+ char *temp;
+ pstring String;
+ pstring NewString;
+ int i;
+
+ fgets(s,n,stream);
+ while ((LString1 = strchr(s,'%')) != NULL) {
+ if (!(LString2 = strchr(LString1+1,'%'))) break;
+ *LString2 = '\0';
+ pstrcpy(String,LString1+1);
+ i = 0;
+ while(*sbuffer[i]!='\0') {
+ if (strncmp(sbuffer[i],String,strlen(String))==0)
+ {
+ pstrcpy(String,sbuffer[i]);
+ if ((temp = strchr(String,'=')) != NULL) ++temp;
+ pstrcpy(String,temp);
+ break;
+ }
+ i++;
+ }
+ *LString1 = '\0';
+ pstrcpy(NewString,s);
+ pstrcat(NewString,String);
+ pstrcat(NewString,LString2+1);
+ pstrcpy(s, NewString);
+ }
+ return(s);
+}
+
+/*
+ This function split a line in two parts
+ on both side of the equal sign
+ "entry=value"
+*/
+static char *scan(char *chaine,char **entry)
+{
+ char *value;
+ char *temp;
+ int i=0;
+
+ *entry=(char *)malloc(sizeof(pstring));
+ value=(char *)malloc(sizeof(pstring));
+
+ if(*entry == NULL || value == NULL) {
+ fprintf(stderr,"scan: malloc fail !\n");
+ exit(1);
+ }
+
+ pstrcpy(*entry,chaine);
+ temp=chaine;
+ while( temp[i]!='=' && temp[i]!='\0') {
+ i++;
+ }
+ (*entry)[i]='\0';
+ if (temp[i]!='\0') {
+ i++;
+ }
+ while( temp[i]==' ' && temp[i]!='\0') {
+ i++;
+ }
+ pstrcpy(value,temp+i);
+ return (value);
+}
+
+static void build_subdir(void)
+{
+ int i=0;
+ int j=0;
+ char *entry;
+ char *data;
+
+ while (*buffer[i]!='\0') {
+ data=scan(buffer[i],&entry);
+#ifdef DEBUGIT
+ fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
+#endif
+ j = strlen(entry);
+ while (j) {
+ if (entry[j-1] != ' ') break;
+ j--;
+ }
+ entry[j] = '\0';
+
+ if (strncmp(data,"11",2)==0) {
+ pstrcpy(sub_dir[i][0],entry);
+ pstrcpy(sub_dir[i][1],"");
+ }
+ if (strncmp(data,"23",2)==0) {
+ pstrcpy(sub_dir[i][0],entry);
+ pstrcpy(sub_dir[i][1],"color\\");
+ }
+#ifdef DEBUGIT
+ fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
+#endif
+ i++;
+ }
+}
+
+/*
+ Lockup Strings entry in a file
+ Return all the lines between the entry and the next one or the end of file
+ An entry is something between braces.
+*/
+static void lookup_strings(FILE *fichier)
+{
+ int found=0,pointeur=0,i=0;
+ char *temp,*temp2;
+
+ temp=(char *)malloc(sizeof(pstring));
+ temp2=(char *)malloc(sizeof(pstring));
+
+ if(temp == NULL || temp2 == NULL) {
+ safe_free(temp);
+ safe_free(temp2);
+ fprintf(stderr,"lookup_strings: malloc fail !\n");
+ exit(1);
+ }
+
+ *sbuffer[0]='\0';
+
+ pstrcpy(temp2,"[Strings]");
+
+ rewind(fichier);
+#ifdef DEBUGIT
+ fprintf(stderr,"\tLooking for Strings\n");
+#endif
+
+ while (!feof(fichier) && found==0) {
+ *temp='\0';
+ fgets(temp,255,fichier);
+ if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
+ }
+
+
+ while (!feof(fichier) && found==1) {
+ *temp='\0';
+ fgets(temp,255,fichier);
+ if (*temp=='[') {
+ found=2;
+ *sbuffer[pointeur]='\0';
+ }
+ else {
+ pstrcpy(sbuffer[pointeur],temp);
+ i=strlen(sbuffer[pointeur])-1;
+ while (sbuffer[pointeur][i]=='\r' || sbuffer[pointeur][i]=='\n')
+ sbuffer[pointeur][i--]='\0';
+ pointeur++;
+ }
+ }
+
+ /* CCMRCF Mod, seg fault or worse if not found */
+ if (pointeur == 0) {
+ fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
+ exit(2);
+ }
+
+#ifdef DEBUGIT
+ fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
+#endif
+}
+
+
+/*
+ Lockup an entry in a file
+ Return all the lines between the entry and the next one or the end of file
+ An entry is something between braces.
+*/
+static void lookup_entry(FILE *fichier,const char *chaine)
+{
+ int found=0,pointeur=0,i=0;
+ char *temp,*temp2;
+
+ temp=(char *)malloc(sizeof(pstring));
+ temp2=(char *)malloc(sizeof(pstring));
+
+ if(temp == NULL || temp2 == NULL) {
+ safe_free(temp);
+ safe_free(temp2);
+ fprintf(stderr,"lookup_entry: malloc fail !\n");
+ exit(1);
+ }
+
+ *buffer[0]='\0';
+
+ pstrcpy(temp2,"[");
+ pstrcat(temp2,chaine);
+ pstrcat(temp2,"]");
+
+ rewind(fichier);
+#ifdef DEBUGIT
+ fprintf(stderr,"\tLooking for %s\n",chaine);
+#endif
+
+ while (!feof(fichier) && found==0) {
+ *temp='\0';
+ myfgets(temp,255,fichier);
+ if (strncmp(temp,temp2,strlen(temp2))==0) found=1;
+ }
+
+
+ while (!feof(fichier) && found==1) {
+ *temp='\0';
+ myfgets(temp,255,fichier);
+ if (*temp=='[') {
+ found=2;
+ *buffer[pointeur]='\0';
+ }
+ else {
+ pstrcpy(buffer[pointeur],temp);
+ i=strlen(buffer[pointeur])-1;
+ while (buffer[pointeur][i]=='\r' || buffer[pointeur][i]=='\n')
+ buffer[pointeur][i--]='\0';
+ pointeur++;
+ }
+ }
+#ifdef DEBUGIT
+ fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
+#endif
+}
+
+static char *find_desc(FILE *fichier,char *text)
+{
+ char *chaine;
+ char *long_desc;
+ char *short_desc;
+ char *crap = NULL;
+ char *p;
+
+ int found=0;
+
+ chaine=(char *)malloc(sizeof(pstring));
+ long_desc=(char *)malloc(sizeof(pstring));
+ short_desc=(char *)malloc(sizeof(pstring));
+ if (!chaine || !long_desc || !short_desc) {
+ safe_free(chaine);
+ safe_free(long_desc);
+ safe_free(short_desc);
+ fprintf(stderr,"find_desc: Unable to malloc memory\n");
+ exit(1);
+ }
+
+ rewind(fichier);
+ while (!feof(fichier) && found==0)
+ {
+ myfgets(chaine,255,fichier);
+
+ long_desc=strtok(chaine,"=");
+ crap=strtok(NULL,",\r");
+
+ p=long_desc;
+ while(*p!='"' && *p!='\0')
+ p++;
+ if (*p=='"' && *(p+1)!='\0') p++;
+ long_desc=p;
+
+ if (*p!='\0')
+ {
+ p++;
+ while(*p!='\"')
+ p++;
+ *p='\0';
+ }
+ if (!strcmp(text,long_desc))
+ found=1;
+ }
+ SAFE_FREE(chaine);
+ if (!found || !crap) return(NULL);
+ while(*crap==' ') crap++;
+ pstrcpy(short_desc,crap);
+ return(short_desc);
+}
+
+static void scan_copyfiles(FILE *fichier, char *chaine)
+{
+ char *part;
+ char *mpart;
+ int i;
+ pstring direc;
+#ifdef DEBUGIT
+ fprintf(stderr,"In scan_copyfiles Lookup up of %s\n",chaine);
+#endif
+ fprintf(stderr,"\nCopy the following files to your printer$ share location:\n");
+ part=strtok(chaine,",");
+ do {
+ /* If the entry start with a @ then it's a file to copy
+ else it's an entry refering to files to copy
+ the main difference is when it's an entry
+ you can have a directory to append before the file name
+ */
+ if (*part=='@') {
+ if (strlen(files_to_copy) != 0)
+ pstrcat(files_to_copy,",");
+ pstrcat(files_to_copy,&part[1]);
+ fprintf(stderr,"%s\n",&part[1]);
+ } else {
+ lookup_entry(fichier,part);
+ i=0;
+ pstrcpy(direc,"");
+ while (*sub_dir[i][0]!='\0') {
+#ifdef DEBUGIT
+ fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
+#endif
+ if (strcmp(sub_dir[i][0],part)==0)
+ pstrcpy(direc,sub_dir[i][1]);
+ i++;
+ }
+ i=0;
+ while (*buffer[i]!='\0') {
+/*
+ * HP inf files have strange entries that this attempts to address
+ * Entries in the Copy sections normally have only a single file name
+ * on each line. I have seen the following format in various HP inf files:
+ *
+ * pscript.hlp = pscript.hl_
+ * hpdcmon.dll,hpdcmon.dl_
+ * MSVCRT.DLL,MSVCRT.DL_,,32
+ * ctl3dv2.dll,ctl3dv2.dl_,ctl3dv2.tmp
+ *
+ * In the first 2 cases you want the first file name - in the last case
+ * you only want the last file name (at least that is what a Win95
+ * machine sent). In the third case you also want the first file name
+ * (detect by the last component being just a number ?).
+ * This may still be wrong but at least I get the same list
+ * of files as seen on a printer test page.
+ */
+ part = strchr(buffer[i],'=');
+ if (part) {
+ /*
+ * Case (1) eg. pscript.hlp = pscript.hl_ - chop after the first name.
+ */
+
+ *part = '\0';
+
+ /*
+ * Now move back to the start and print that.
+ */
+
+ while (--part > buffer[i]) {
+ if ((*part == ' ') || (*part =='\t'))
+ *part = '\0';
+ else
+ break;
+ }
+ } else {
+ part = strchr(buffer[i],',');
+ if (part) {
+ /*
+ * Cases (2-4)
+ */
+
+ if ((mpart = strrchr(part+1,','))!=NULL) {
+ /*
+ * Second ',' - case 3 or 4.
+ * Check if the last part is just a number,
+ * if so we need the first part.
+ */
+
+ char *endptr = NULL;
+ BOOL isnumber = False;
+
+ mpart++;
+ (void)strtol(mpart, &endptr, 10);
+
+ isnumber = ((endptr > mpart) && isdigit(*mpart));
+ if(!isnumber)
+ pstrcpy(buffer[i],mpart+1);
+ else
+ *part = '\0';
+ } else {
+ *part = '\0';
+ }
+ while (--part > buffer[i])
+ if ((*part == ' ') || (*part =='\t')) *part = '\0';
+ else break;
+ }
+ }
+ if (*buffer[i] != ';') {
+ if (strlen(files_to_copy) != 0)
+ pstrcat(files_to_copy,",");
+ pstrcat(files_to_copy,direc);
+ pstrcat(files_to_copy,buffer[i]);
+ fprintf(stderr,"%s%s\n",direc,buffer[i]);
+ }
+ i++;
+ } /* end while */
+ }
+ part=strtok(NULL,",");
+ if (part) {
+ while( *part ==' ' && *part != '\0') {
+ part++;
+ }
+ }
+ } while (part!=NULL);
+ fprintf(stderr,"\n");
+}
+
+
+static void scan_short_desc(FILE *fichier, char *short_desc)
+{
+ int i=0;
+ char *temp;
+ char *copyfiles=0,*datasection=0;
+
+ helpfile=0;
+ languagemonitor=0;
+ vendorsetup=0;
+ datatype="RAW";
+ if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
+ fprintf(stderr, "scan_short_desc: malloc fail !\n");
+ exit(1);
+ }
+
+ driverfile=short_desc;
+ datafile=short_desc;
+
+ lookup_entry(fichier,short_desc);
+
+ while(*buffer[i]!='\0') {
+#ifdef DEBUGIT
+ fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
+#endif
+ if (strncasecmp(buffer[i],"CopyFiles",9)==0)
+ copyfiles=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DataSection",11)==0)
+ datasection=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DataFile",8)==0)
+ datafile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DriverFile",10)==0)
+ driverfile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"HelpFile",8)==0)
+ helpfile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0)
+ languagemonitor=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
+ datatype=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
+ vendorsetup=scan(buffer[i],&temp);
+ i++;
+ }
+
+ if (datasection) {
+ lookup_entry(fichier,datasection);
+
+ i = 0;
+ while(*buffer[i]!='\0') {
+#ifdef DEBUGIT
+ fprintf(stderr,"\tLookup up of %s\n",buffer[i]);
+#endif
+ if (strncasecmp(buffer[i],"CopyFiles",9)==0)
+ copyfiles=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DataSection",11)==0)
+ datasection=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DataFile",8)==0)
+ datafile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DriverFile",10)==0)
+ driverfile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"HelpFile",8)==0)
+ helpfile=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"LanguageMonitor",15)==0)
+ languagemonitor=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
+ datatype=scan(buffer[i],&temp);
+ else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
+ vendorsetup=scan(buffer[i],&temp);
+ i++;
+ }
+ }
+
+ if (languagemonitor) {
+ temp = strtok(languagemonitor,",");
+ if (*temp == '"') ++temp;
+ pstrcpy(languagemonitor,temp);
+ if ((temp = strchr(languagemonitor,'"'))!=NULL) *temp = '\0';
+ }
+
+ if (i) fprintf(stderr,"End of section found\n");
+
+ fprintf(stderr,"CopyFiles: %s\n",
+ copyfiles?copyfiles:"(null)");
+ fprintf(stderr,"Datasection: %s\n",
+ datasection?datasection:"(null)");
+ fprintf(stderr,"Datafile: %s\n",
+ datafile?datafile:"(null)");
+ fprintf(stderr,"Driverfile: %s\n",
+ driverfile?driverfile:"(null)");
+ fprintf(stderr,"Helpfile: %s\n",
+ helpfile?helpfile:"(null)");
+ fprintf(stderr,"LanguageMonitor: %s\n",
+ languagemonitor?languagemonitor:"(null)");
+ fprintf(stderr,"VendorSetup: %s\n",
+ vendorsetup?vendorsetup:"(null)");
+ if (copyfiles) scan_copyfiles(fichier,copyfiles);
+}
+
+int main(int argc, char *argv[])
+{
+ char *short_desc;
+ FILE *inf_file;
+
+ fprintf( stderr, "This tool has been deprecated in favor of the new printer administration\n");
+ fprintf( stderr, "model included in Samba 2.2. Please see the HOWTO in docs/textdocs/printer_driver2.html\n");
+ fprintf( stderr, "for details.\n");
+
+ if (argc!=3)
+ {
+ usage(argv[0]);
+ return(-1);
+ }
+
+ inf_file=sys_fopen(argv[1],"r");
+ if (!inf_file)
+ {
+ fprintf(stderr,"Description file not found, bye\n");
+ return(-1);
+ }
+
+ lookup_strings(inf_file);
+
+ short_desc=find_desc(inf_file,argv[2]);
+ if (short_desc==NULL)
+ {
+ fprintf(stderr,"Printer not found\n");
+ return(-1);
+ }
+ else fprintf(stderr,"Found:%s\n",short_desc);
+
+ lookup_entry(inf_file,"DestinationDirs");
+ build_subdir();
+
+ if((files_to_copy=(char *)malloc(2048*sizeof(char))) == NULL) {
+ fprintf(stderr, "%s: malloc fail.\n", argv[0] );
+ exit(1);
+ }
+ *files_to_copy='\0';
+ scan_short_desc(inf_file,short_desc);
+ fprintf(stdout,"%s:%s:%s:",
+ argv[2],driverfile,datafile);
+ fprintf(stdout,"%s:",
+ helpfile?helpfile:"");
+ fprintf(stdout,"%s:",
+ languagemonitor?languagemonitor:"");
+ fprintf(stdout,"%s:",datatype);
+ fprintf(stdout,"%s\n",files_to_copy);
+ return 0;
+}
+
diff --git a/source/utils/make_smbcodepage.c b/source/utils/make_smbcodepage.c
new file mode 100755
index 00000000000..61f4153f5b2
--- /dev/null
+++ b/source/utils/make_smbcodepage.c
@@ -0,0 +1,476 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Create codepage files from codepage_def.XXX files.
+
+ Copyright (C) Jeremy Allison 1997-1999.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static char *prog_name = NULL;
+
+/*
+ * Print program usage and die.
+ */
+
+static void codepage_usage(char *progname)
+{
+ fprintf(stderr, "Usage is : %s [c|d] <codepage> <inputfile> <outputfile>\n",
+ progname);
+ exit(1);
+}
+
+/*
+ * Read a line from a buffer into a line buffer. Ensure null
+ * terminated.
+ */
+
+static void read_line( char **buf, char *line_buf, int size)
+{
+ char *p = *buf;
+ int num = 0;
+
+ for(; *p && (*p != '\n'); p++)
+ {
+ if(num < (size - 1))
+ line_buf[num++] = *p;
+ }
+ if(*p)
+ p++; /* Go past the '\n' */
+ line_buf[num] = '\0';
+ *buf = p;
+}
+
+/*
+ * Strip comment lines and blank lines from the data.
+ * Copies into a new buffer and frees the old.
+ * Returns the number of lines copied.
+ */
+
+static int clean_data( char **buf, size_t *size)
+{
+ pstring linebuf;
+ char *p = *buf;
+ int num_lines = 0;
+ char *newbuf = (char *)malloc( *size + 1);
+ char *newbuf_p = NULL;
+
+ if(newbuf == NULL)
+ {
+ fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, *size + 1);
+ exit(1);
+ }
+
+ newbuf_p = newbuf;
+ *newbuf_p = '\0';
+
+ while( *p )
+ {
+ char *cp;
+
+ read_line( &p, linebuf, sizeof(linebuf));
+ /* Null terminate after comment. */
+ if((cp = strchr( linebuf, '#'))!= NULL)
+ *cp = '\0';
+
+ for(cp = linebuf;*cp && isspace(*cp); cp++)
+ ;
+
+ if(*cp == '\0')
+ continue;
+
+ safe_strcpy(newbuf_p, cp, *size - (newbuf_p - newbuf));
+ num_lines++;
+ newbuf_p += (strlen(newbuf_p) + 1);
+ }
+
+ SAFE_FREE(*buf);
+ *buf = newbuf;
+ return num_lines;
+}
+
+/*
+ * Parse a byte from a codepage file.
+ */
+
+static BOOL parse_byte(char *buf, unsigned char *bp)
+{
+ unsigned int b;
+ char *endptr = NULL;
+
+ b = (unsigned int)strtol(buf, &endptr, 0);
+ if(endptr == buf || b > 255)
+ return False;
+
+ *bp = (unsigned char)b;
+ return True;
+}
+
+/*
+ * Parse a bool from a codepage file.
+ */
+
+static BOOL parse_bool(char *buf, unsigned char *bp)
+{
+ if(isdigit((int)*buf))
+ {
+ char *endptr = NULL;
+
+ *bp = (unsigned char)strtol(buf, &endptr, 0);
+ if(endptr == buf )
+ return False;
+ if(*bp != 0)
+ *bp = 1;
+ } else {
+ if(strcasecmp(buf, "True") && strcasecmp(buf, "False"))
+ return False;
+ if(strcasecmp(buf, "True")==0)
+ *bp = 1;
+ else
+ *bp = 0;
+ }
+ return True;
+}
+
+/*
+ * Print a parse error and exit.
+ */
+
+static void parse_error(char *buf, const char *msg)
+{
+ fprintf(stderr, "%s: %s whilst parsing line \n%s\n", prog_name,
+ msg, buf);
+ exit(1);
+}
+
+/*
+ * Create a compiled codepage file from a codepage definition file.
+ */
+
+static int do_compile(int codepage, char *input_file, char *output_file)
+{
+ FILE *fp = NULL;
+ size_t size = 0;
+ char *buf = NULL;
+ char *orig_buf = NULL;
+ char output_buf[CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES];
+ int num_lines = 0;
+ int i = 0;
+ SMB_STRUCT_STAT st;
+
+ /* Get the size of the input file. Read the entire thing into memory. */
+ if(sys_stat((char *)input_file, &st)!= 0)
+ {
+ fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ size = (uint32)st.st_size;
+
+ /* I don't believe these things should be bigger than 100k :-) */
+ if(size > 100*1024)
+ {
+ fprintf(stderr, "%s: filesize %d is too large for a codepage definition file. \
+The maximum size I will believe is 100k.\n", prog_name, size);
+ exit(1);
+ }
+
+ if((fp = sys_fopen(input_file, "r")) == NULL)
+ {
+ fprintf(stderr, "%s: cannot open file %s for input.\n", prog_name, input_file);
+ exit(1);
+ }
+
+ /* As we will be reading text, allocate one more byte for a '\0' */
+ if((buf = (char *)malloc( size + 1 )) == NULL)
+ {
+ fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, size + 1);
+ fclose(fp);
+ exit(1);
+ }
+
+ if(fread( buf, 1, size, fp) != size)
+ {
+ fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name,
+ input_file, strerror(errno));
+ SAFE_FREE(buf);
+ fclose(fp);
+ exit(1);
+ }
+
+ /* Null terminate the text read. */
+ buf[size] = '\0';
+
+ /* Go through the data line by line, strip out comments (anything
+ after a '#' to end-of-line) and blank lines. The rest should be
+ the codepage data.
+ */
+
+ num_lines = clean_data( &buf, &size);
+
+ orig_buf = buf; /* Save for free(). */
+
+ /* There can be a maximum of MAXCODEPAGELINES lines. */
+ if(num_lines > MAXCODEPAGELINES)
+ {
+ fprintf(stderr, "%s: There can be a maximum %d lines of data in a codepage \
+definition file. File %s has %d.\n", prog_name, MAXCODEPAGELINES, input_file, num_lines);
+ exit(1);
+ }
+
+ /* Setup the output file header. */
+ SSVAL(output_buf,CODEPAGE_VERSION_OFFSET,CODEPAGE_FILE_VERSION_ID);
+ SSVAL(output_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET,(uint16)codepage);
+ SIVAL(output_buf,CODEPAGE_LENGTH_OFFSET,(num_lines * 4));
+
+ /* Now convert the lines into the compiled form. */
+ for(i = 0; i < num_lines; i++)
+ {
+ char token_buf[512];
+ const char *p = buf;
+ unsigned char b = 0;
+
+ /* Get the 'lower' value. */
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf)))
+ parse_error(buf, "cannot parse first value");
+ if(!parse_byte( token_buf, &b))
+ parse_error(buf, "first value doesn't resolve to a byte");
+
+ /* Add this to the output buffer. */
+ SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4),b);
+
+ /* Get the 'upper' value. */
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf)))
+ parse_error(buf, "cannot parse second value");
+ if(!parse_byte( token_buf, &b))
+ parse_error(buf, "second value doesn't resolve to a byte");
+
+ /* Add this to the output buffer. */
+ SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 1,b);
+
+ /* Get the 'upper to lower' value. */
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf)))
+ parse_error(buf, "cannot parse third value");
+ if(!parse_bool( token_buf, &b))
+ parse_error(buf, "third value doesn't resolve to a boolean");
+
+ /* Add this to the output buffer. */
+ SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 2,b);
+
+ /* Get the 'lower to upper' value. */
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf)))
+ parse_error(buf, "cannot parse fourth value");
+ if(!parse_bool( token_buf, &b))
+ parse_error(buf, "fourth value doesn't resolve to a boolean");
+
+ /* Add this to the output buffer. */
+ SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 3,b);
+
+ buf += (strlen(buf) + 1);
+ }
+
+ /* Now write out the output_buf. */
+ if((fp = sys_fopen(output_file, "w"))==NULL)
+ {
+ fprintf(stderr, "%s: Cannot open output file %s. Error was %s.\n",
+ prog_name, output_file, strerror(errno));
+ exit(1);
+ }
+
+ if(fwrite(output_buf, 1, CODEPAGE_HEADER_SIZE + (num_lines*4), fp) !=
+ CODEPAGE_HEADER_SIZE + (num_lines*4))
+ {
+ fprintf(stderr, "%s: Cannot write output file %s. Error was %s.\n",
+ prog_name, output_file, strerror(errno));
+ exit(1);
+ }
+
+ fclose(fp);
+
+ SAFE_FREE(orig_buf);
+ return 0;
+}
+
+/*
+ * Placeholder for now.
+ */
+
+static int do_decompile( int codepage, char *input_file, char *output_file)
+{
+ size_t size = 0;
+ SMB_STRUCT_STAT st;
+ char header_buf[CODEPAGE_HEADER_SIZE];
+ char *buf = NULL;
+ FILE *fp = NULL;
+ int num_lines = 0;
+ int i = 0;
+
+ /* Get the size of the input file. Read the entire thing into memory. */
+ if(sys_stat((char *)input_file, &st)!= 0)
+ {
+ fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ size = (size_t)st.st_size;
+
+ if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
+ {
+ fprintf(stderr, "%s: file %s is an incorrect size for a \
+code page file.\n", prog_name, input_file);
+ exit(1);
+ }
+
+ /* Read the first 8 bytes of the codepage file - check
+ the version number and code page number. All the data
+ is held in little endian format.
+ */
+
+ if((fp = sys_fopen( input_file, "r")) == NULL)
+ {
+ fprintf(stderr, "%s: cannot open file %s. Error was %s\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ if(fread( header_buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE)
+ {
+ fprintf(stderr, "%s: cannot read header from file %s. Error was %s\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ /* Check the version value */
+ if(SVAL(header_buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID)
+ {
+ fprintf(stderr, "%s: filename %s has incorrect version id. \
+Needed %hu, got %hu.\n",
+ prog_name, input_file, (uint16)CODEPAGE_FILE_VERSION_ID,
+ SVAL(header_buf,CODEPAGE_VERSION_OFFSET));
+ exit(1);
+ }
+
+ /* Check the codepage matches */
+ if(SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)codepage)
+ {
+ fprintf(stderr, "%s: filename %s has incorrect codepage. \
+Needed %hu, got %hu.\n",
+ prog_name, input_file, (uint16)codepage,
+ SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET));
+ exit(1);
+ }
+
+ /* Check the length is correct. */
+ if(IVAL(header_buf,CODEPAGE_LENGTH_OFFSET) !=
+ (unsigned int)(size - CODEPAGE_HEADER_SIZE))
+ {
+ fprintf(stderr, "%s: filename %s has incorrect size headers. \
+Needed %u, got %u.\n", prog_name, input_file, size - CODEPAGE_HEADER_SIZE,
+ IVAL(header_buf,CODEPAGE_LENGTH_OFFSET));
+ exit(1);
+ }
+
+ size -= CODEPAGE_HEADER_SIZE; /* Remove header */
+
+ /* Make sure the size is a multiple of 4. */
+ if((size % 4 ) != 0)
+ {
+ fprintf(stderr, "%s: filename %s has a codepage size not a \
+multiple of 4.\n", prog_name, input_file);
+ exit(1);
+ }
+
+ /* Allocate space for the code page file and read it all in. */
+ if((buf = (char *)malloc( size )) == NULL)
+ {
+ fprintf (stderr, "%s: malloc fail for size %d.\n",
+ prog_name, size );
+ exit(1);
+ }
+
+ if(fread( buf, 1, size, fp)!=size)
+ {
+ fprintf(stderr, "%s: read fail on file %s. Error was %s.\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ fclose(fp);
+
+ /* Now dump the codepage into an ascii file. */
+ if((fp = sys_fopen(output_file, "w")) == NULL)
+ {
+ fprintf(stderr, "%s: cannot open file %s. Error was %s\n",
+ prog_name, output_file, strerror(errno));
+ exit(1);
+ }
+
+ fprintf(fp, "#\n# Codepage definition file for IBM Code Page %d.\n#\n",
+ codepage);
+ fprintf(fp, "# This file was automatically generated.\n#\n");
+ fprintf(fp, "# defines lower->upper mapping.\n");
+ fprintf(fp, "#\n#The columns are :\n# lower\tupper\tu-t-l\tl-t-u\n#\n");
+
+ num_lines = size / 4;
+ for( i = 0; i < num_lines; i++)
+ {
+ fprintf(fp, "0x%02X\t0x%02X\t%s\t%s\n", CVAL(buf, (i*4)), CVAL(buf, (i*4)+1),
+ CVAL(buf, (i*4)+2) ? "True" : "False",
+ CVAL(buf, (i*4)+3) ? "True" : "False");
+ }
+ fclose(fp);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int codepage = 0;
+ char *input_file = NULL;
+ char *output_file = NULL;
+ BOOL compile = False;
+
+ prog_name = argv[0];
+
+ if(argc != 5)
+ codepage_usage(prog_name);
+
+ if(argv[1][0] != 'c' && argv[1][0] != 'C' && argv[1][0] != 'd' &&
+ argv[1][0] != 'D')
+ codepage_usage(prog_name);
+
+ input_file = argv[3];
+ output_file = argv[4];
+
+ /* Are we compiling or decompiling. */
+ if(argv[1][0] == 'c' || argv[1][0] == 'C')
+ compile = True;
+
+ /* Convert the second argument into a client codepage value. */
+ if((codepage = atoi(argv[2])) == 0)
+ {
+ fprintf(stderr, "%s: %s is not a valid codepage.\n", prog_name, argv[2]);
+ exit(1);
+ }
+
+ if(compile)
+ return do_compile( codepage, input_file, output_file);
+ else
+ return do_decompile( codepage, input_file, output_file);
+}
diff --git a/source/utils/make_unicodemap.c b/source/utils/make_unicodemap.c
new file mode 100755
index 00000000000..2e33bbf3ea7
--- /dev/null
+++ b/source/utils/make_unicodemap.c
@@ -0,0 +1,313 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.x.
+ Create unicode map files from unicode_def.XXX files.
+
+ Copyright (C) Jeremy Allison 1997-1999.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static char *prog_name = NULL;
+
+/*
+ * Print program usage and die.
+ */
+
+static void unicode_map_usage(char *progname)
+{
+ fprintf(stderr, "Usage is : %s <codepage> <inputfile> <outputfile>\n",
+ progname);
+ exit(1);
+}
+
+/*
+ * Read a line from a buffer into a line buffer. Ensure null
+ * terminated.
+ */
+
+static void read_line( char **buf, char *line_buf, size_t size)
+{
+ char *p = *buf;
+ size_t num = 0;
+
+ for(; *p && (*p != '\n') && (*p != '\032'); p++) {
+ if(num < (size - 1))
+ line_buf[num++] = *p;
+ }
+ if(*p)
+ p++; /* Go past the '\n' */
+ line_buf[num] = '\0';
+ *buf = p;
+}
+
+/*
+ * Strip comment lines and blank lines from the data.
+ * Copies into a new buffer and frees the old.
+ * Returns the number of lines copied.
+ */
+
+static size_t clean_data( char **buf, size_t *size)
+{
+ pstring linebuf;
+ char *p = *buf;
+ size_t num_lines = 0;
+ char *newbuf = (char *)malloc( *size + 1);
+ char *newbuf_p = NULL;
+
+ if(newbuf == NULL) {
+ fprintf(stderr, "%s: malloc fail for size %u.\n", prog_name, (unsigned int)(*size + 1));
+ exit(1);
+ }
+
+ newbuf_p = newbuf;
+ *newbuf_p = '\0';
+
+ while( *p ) {
+ char *cp;
+
+ read_line( &p, linebuf, sizeof(linebuf));
+ /* Null terminate after comment. */
+ if((cp = strchr( linebuf, '#'))!= NULL)
+ *cp = '\0';
+
+ for(cp = linebuf;*cp && isspace(*cp); cp++)
+ ;
+
+ if(*cp == '\0')
+ continue;
+
+ safe_strcpy(newbuf_p, cp, *size - (newbuf_p - newbuf));
+ num_lines++;
+ newbuf_p += (strlen(newbuf_p) + 1);
+ }
+
+ SAFE_FREE(*buf);
+ *buf = newbuf;
+ return num_lines;
+}
+
+/*
+ * Parse a uint16 from a codepage file.
+ */
+
+static BOOL parse_uint16(char *buf, uint16 *uip)
+{
+ unsigned int ui;
+ char *endptr = NULL;
+
+ ui = (unsigned int)strtol(buf, &endptr, 0);
+ if(endptr == buf || ui > 65535)
+ return False;
+
+ *uip = (uint16)ui;
+ return True;
+}
+
+/*
+ * Print a parse error and exit.
+ */
+
+static void parse_error(const char *buf, const char *input_file, const char *msg)
+{
+ fprintf(stderr, "%s: In file %s : %s whilst parsing line \n%s\n", prog_name,
+ input_file, msg, buf);
+ exit(1);
+}
+
+/*
+ * Create a compiled unicode map file from a unicode map definition file.
+ */
+
+static int do_compile(const char *codepage, const char *input_file, const char *output_file)
+{
+ FILE *fp = NULL;
+ size_t size = 0;
+ size_t offset = 0;
+ char *buf = NULL;
+ char *orig_buf = NULL;
+ char *output_buf = NULL;
+ uint16 cp_to_ucs2[65536];
+ uint16 ucs2_to_cp[65536];
+ BOOL multibyte_code_page = False;
+ int num_lines = 0;
+ int i = 0;
+ SMB_STRUCT_STAT st;
+
+ /* Get the size of the input file. Read the entire thing into memory. */
+ if(sys_stat(input_file, &st)!= 0) {
+ fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n",
+ prog_name, input_file, strerror(errno));
+ exit(1);
+ }
+
+ size = (size_t)st.st_size;
+
+ if((fp = sys_fopen(input_file, "r")) == NULL) {
+ fprintf(stderr, "%s: cannot open file %s for input.\n", prog_name, input_file);
+ exit(1);
+ }
+
+ /* As we will be reading text, allocate one more byte for a '\0' */
+ if((buf = (char *)malloc( size + 1 )) == NULL) {
+ fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, size + 1);
+ fclose(fp);
+ exit(1);
+ }
+
+ if(fread( buf, 1, size, fp) != size) {
+ fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name,
+ input_file, strerror(errno));
+ SAFE_FREE(buf);
+ fclose(fp);
+ exit(1);
+ }
+
+ /* Null terminate the text read. */
+ buf[size] = '\0';
+
+ /* Go through the data line by line, strip out comments (anything
+ after a '#' to end-of-line) and blank lines. The rest should be
+ the codepage data.
+ */
+
+ num_lines = clean_data( &buf, &size);
+
+ orig_buf = buf; /* Store for free(). */
+
+ /*
+ * Initialize the output data.
+ */
+
+ memset(cp_to_ucs2, '\0', sizeof(cp_to_ucs2));
+ ucs2_to_cp[0] = 0;
+ for (i = 1; i < 65536; i++)
+ ucs2_to_cp[i] = (uint16)'_';
+
+ /* Now convert the lines into the compiled form. */
+
+ for(i = 0; i < num_lines; i++) {
+ char token_buf[512];
+ const char *p = buf;
+ uint16 cp = 0;
+ uint16 ucs2 = 0;
+
+ /* Get the codepage value. */
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf)))
+ parse_error(buf, input_file, "cannot parse first value");
+
+ if(!parse_uint16( token_buf, &cp))
+ parse_error(buf, input_file, "first value doesn't resolve to an unsigned 16 bit integer");
+
+ if(cp > 255)
+ multibyte_code_page = True;
+
+ /* Get the ucs2 value. */
+
+ if(!next_token(&p, token_buf, NULL, sizeof(token_buf))) {
+
+ /*
+ * Some of the multibyte codepage to unicode map files
+ * list a single byte as a leading multibyte and have no
+ * second value.
+ */
+
+ buf += (strlen(buf) + 1);
+ continue;
+ }
+
+ if(!parse_uint16( token_buf, &ucs2))
+ parse_error(buf, input_file, "second value doesn't resolve to an unsigned 16 bit integer");
+
+ /*
+ * Set up the cross reference in little-endian format.
+ */
+
+ SSVAL(((char *)&cp_to_ucs2[cp]),0,ucs2);
+ SSVAL(((char *)&ucs2_to_cp[ucs2]),0,cp);
+
+ /*
+ * Next line.
+ */
+ buf += (strlen(buf) + 1);
+ }
+
+ size = UNICODE_MAP_HEADER_SIZE + (multibyte_code_page ? (4*65536) : (2*256 + 2*65536));
+
+ if((output_buf = (char *)malloc( size )) == NULL) {
+ fprintf(stderr, "%s: output buffer malloc fail for size %d.\n", prog_name, size);
+ fclose(fp);
+ exit(1);
+ }
+
+ /* Setup the output file header. */
+ SSVAL(output_buf,UNICODE_MAP_VERSION_OFFSET,UNICODE_MAP_FILE_VERSION_ID);
+ memset(&output_buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET],'\0',UNICODE_MAP_CODEPAGE_ID_SIZE);
+ safe_strcpy(&output_buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage, UNICODE_MAP_CODEPAGE_ID_SIZE - 1);
+ output_buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET+UNICODE_MAP_CODEPAGE_ID_SIZE-1] = '\0';
+
+ offset = UNICODE_MAP_HEADER_SIZE;
+
+ if (multibyte_code_page) {
+ SIVAL(output_buf,UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET,2*65536);
+ memcpy(output_buf+offset, (char *)cp_to_ucs2, 2*65536);
+ offset += 2*65536;
+ } else {
+ SIVAL(output_buf,UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET,2*256);
+ memcpy(output_buf+offset, (char *)cp_to_ucs2, 2*256);
+ offset += 2*256;
+ }
+ SIVAL(output_buf,UNICODE_MAP_UNICODE_TO_CP_LENGTH_OFFSET,65536*2);
+ memcpy(output_buf+offset, (char *)ucs2_to_cp, 2*65536);
+
+ /* Now write out the output_buf. */
+ if((fp = sys_fopen(output_file, "w"))==NULL) {
+ fprintf(stderr, "%s: Cannot open output file %s. Error was %s.\n",
+ prog_name, output_file, strerror(errno));
+ exit(1);
+ }
+
+ if(fwrite(output_buf, 1, size, fp) != size) {
+ fprintf(stderr, "%s: Cannot write output file %s. Error was %s.\n",
+ prog_name, output_file, strerror(errno));
+ exit(1);
+ }
+
+ fclose(fp);
+
+ SAFE_FREE(orig_buf);
+ SAFE_FREE(output_buf);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ const char *codepage = NULL;
+ char *input_file = NULL;
+ char *output_file = NULL;
+
+ prog_name = argv[0];
+
+ if(argc != 4)
+ unicode_map_usage(prog_name);
+
+ codepage = argv[1];
+ input_file = argv[2];
+ output_file = argv[3];
+
+ return do_compile( codepage, input_file, output_file);
+}
diff --git a/source/torture/masktest.c b/source/utils/masktest.c
index 8c44f35f958..e477f09b535 100644..100755
--- a/source/torture/masktest.c
+++ b/source/utils/masktest.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.0
mask_match tester
Copyright (C) Andrew Tridgell 1999
@@ -28,17 +29,16 @@ static int got_pass;
static int max_protocol = PROTOCOL_NT1;
static BOOL showall = False;
static BOOL old_list = False;
-static const char *maskchars = "<>\"?*abc.";
-static const char *filechars = "abcdefghijklm.";
+static char *maskchars = "<>\"?*abc.";
+static char *filechars = "abcdefghijklm.";
static int verbose;
static int die_on_error;
static int NumLoops = 0;
-static int ignore_dot_errors = 0;
/* a test fn for LANMAN mask support */
-int ms_fnmatch_lanman_core(const char *pattern, const char *string)
+int ms_fnmatch_lanman_core(char *pattern, char *string)
{
- const char *p = pattern, *n = string;
+ char *p = pattern, *n = string;
char c;
if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match;
@@ -76,7 +76,7 @@ int ms_fnmatch_lanman_core(const char *pattern, const char *string)
case '<':
for (; *n; n++) {
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
- if (*n == '.' && !strchr_m(n+1,'.')) {
+ if (*n == '.' && !strchr(n+1,'.')) {
n++;
break;
}
@@ -110,12 +110,10 @@ next:
return 0;
}
-int ms_fnmatch_lanman(const char *pattern, const char *string)
+int ms_fnmatch_lanman(char *pattern, char *string)
{
if (!strpbrk(pattern, "?*<>\"")) {
- if (strcmp(string,"..") == 0)
- string = ".";
-
+ if (strcmp(string,"..") == 0) string = ".";
return strcmp(pattern, string);
}
@@ -127,7 +125,7 @@ int ms_fnmatch_lanman(const char *pattern, const char *string)
return ms_fnmatch_lanman_core(pattern, string);
}
-static BOOL reg_match_one(struct cli_state *cli, const char *pattern, const char *file)
+static BOOL reg_match_one(char *pattern, char *file)
{
/* oh what a weird world this is */
if (old_list && strcmp(pattern, "*.*") == 0) return True;
@@ -140,20 +138,20 @@ static BOOL reg_match_one(struct cli_state *cli, const char *pattern, const char
if (strcmp(file,"..") == 0) file = ".";
- return ms_fnmatch(pattern, file, cli->protocol, False /* not case sensitive */)==0;
+ return ms_fnmatch(pattern, file)==0;
}
-static char *reg_test(struct cli_state *cli, char *pattern, char *long_name, char *short_name)
+static char *reg_test(char *pattern, char *long_name, char *short_name)
{
static fstring ret;
fstrcpy(ret, "---");
- pattern = 1+strrchr_m(pattern,'\\');
+ pattern = 1+strrchr(pattern,'\\');
- if (reg_match_one(cli, pattern, ".")) ret[0] = '+';
- if (reg_match_one(cli, pattern, "..")) ret[1] = '+';
- if (reg_match_one(cli, pattern, long_name) ||
- (*short_name && reg_match_one(cli, pattern, short_name))) ret[2] = '+';
+ if (reg_match_one(pattern, ".")) ret[0] = '+';
+ if (reg_match_one(pattern, "..")) ret[1] = '+';
+ if (reg_match_one(pattern, long_name) ||
+ (*short_name && reg_match_one(pattern, short_name))) ret[2] = '+';
return ret;
}
@@ -170,23 +168,24 @@ struct cli_state *connect_one(char *share)
struct in_addr ip;
server = share+2;
- share = strchr_m(server,'\\');
+ share = strchr(server,'\\');
if (!share) return NULL;
*share = 0;
share++;
server_n = server;
- zero_ip(&ip);
+ zero_ip(&ip);
make_nmb_name(&calling, "masktest", 0x0);
make_nmb_name(&called , server, 0x20);
again:
- zero_ip(&ip);
+ zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
+ !cli_connect(c, server_n, &ip)) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
@@ -214,7 +213,7 @@ struct cli_state *connect_one(char *share)
if (!got_pass) {
char *pass = getpass("Password: ");
if (pass) {
- fstrcpy(password, pass);
+ pstrcpy(password, pass);
}
}
@@ -253,9 +252,9 @@ struct cli_state *connect_one(char *share)
}
static char *resultp;
-static file_info *f_info;
+static file_info *finfo;
-static void listfn(file_info *f, const char *s, void *state)
+void listfn(file_info *f, const char *s, void *state)
{
if (strcmp(f->name,".") == 0) {
resultp[0] = '+';
@@ -264,7 +263,7 @@ static void listfn(file_info *f, const char *s, void *state)
} else {
resultp[2] = '+';
}
- f_info = f;
+ finfo = f;
}
static void get_real_name(struct cli_state *cli,
@@ -277,11 +276,11 @@ static void get_real_name(struct cli_state *cli,
} else {
cli_list_new(cli, "\\masktest\\*", aHIDDEN | aDIR, listfn, NULL);
}
- if (f_info) {
- fstrcpy(short_name, f_info->short_name);
- strlower_m(short_name);
- pstrcpy(long_name, f_info->name);
- strlower_m(long_name);
+ if (finfo) {
+ fstrcpy(short_name, finfo->short_name);
+ strlower(short_name);
+ pstrcpy(long_name, finfo->name);
+ strlower(long_name);
}
if (*short_name == 0) {
@@ -289,7 +288,7 @@ static void get_real_name(struct cli_state *cli,
}
#if 0
- if (!strchr_m(short_name,'.')) {
+ if (!strchr(short_name,'.')) {
fstrcat(short_name,".");
}
#endif
@@ -317,17 +316,15 @@ static void testpair(struct cli_state *cli, char *mask, char *file)
resultp = res1;
fstrcpy(short_name, "");
- f_info = NULL;
+ finfo = NULL;
get_real_name(cli, long_name, short_name);
- f_info = NULL;
+ finfo = NULL;
fstrcpy(res1, "---");
cli_list(cli, mask, aHIDDEN | aDIR, listfn, NULL);
- res2 = reg_test(cli, mask, long_name, short_name);
+ res2 = reg_test(mask, long_name, short_name);
- if (showall ||
- ((strcmp(res1, res2) && !ignore_dot_errors) ||
- (strcmp(res1+2, res2+2) && ignore_dot_errors))) {
+ if (showall || strcmp(res1, res2)) {
DEBUG(0,("%s %s %d mask=[%s] file=[%s] rfile=[%s/%s]\n",
res1, res2, count, mask, file, long_name, short_name));
if (die_on_error) exit(1);
@@ -387,7 +384,7 @@ static void test_mask(int argc, char *argv[],
testpair(cli, mask, file);
if (NumLoops && (--NumLoops == 0))
- break;
+ break;
}
finished:
@@ -406,13 +403,12 @@ static void usage(void)
-W workgroup\n\
-U user%%pass\n\
-s seed\n\
- -M max protocol\n\
+ -M max protocol\n\
-f filechars (default %s)\n\
-m maskchars (default %s)\n\
- -v verbose mode\n\
- -E die on error\n\
+ -v verbose mode\n\
+ -E die on error\n\
-a show all tests\n\
- -i ignore . and .. errors\n\
\n\
This program tests wildcard matching between two servers. It generates\n\
random pairs of filenames/masks and tests that they match in the same\n\
@@ -430,17 +426,19 @@ static void usage(void)
struct cli_state *cli;
extern char *optarg;
extern int optind;
+ extern FILE *dbf;
extern BOOL AllowDebugChange;
int opt;
char *p;
int seed;
+ static pstring servicesf = CONFIGFILE;
+ extern int Protocol;
setlinebuf(stdout);
- dbf = x_stderr;
-
- DEBUGLEVEL = 0;
AllowDebugChange = False;
+ DEBUGLEVEL = 0;
+ dbf = stderr;
if (argc < 2 || argv[1][0] == '-') {
usage();
@@ -456,16 +454,16 @@ static void usage(void)
argc -= 1;
argv += 1;
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
+ TimeInit();
+ charset_initialise();
if (getenv("USER")) {
- fstrcpy(username,getenv("USER"));
+ pstrcpy(username,getenv("USER"));
}
seed = time(NULL);
- while ((opt = getopt(argc, argv, "n:d:U:s:hm:f:aoW:M:vEi")) != EOF) {
+ while ((opt = getopt(argc, argv, "n:d:U:s:hm:f:aoW:M:vE")) != EOF) {
switch (opt) {
case 'n':
NumLoops = atoi(optarg);
@@ -476,9 +474,6 @@ static void usage(void)
case 'E':
die_on_error = 1;
break;
- case 'i':
- ignore_dot_errors = 1;
- break;
case 'v':
verbose++;
break;
@@ -486,11 +481,11 @@ static void usage(void)
max_protocol = interpret_protocol(optarg, max_protocol);
break;
case 'U':
- fstrcpy(username,optarg);
- p = strchr_m(username,'%');
+ pstrcpy(username,optarg);
+ p = strchr(username,'%');
if (p) {
*p = 0;
- fstrcpy(password, p+1);
+ pstrcpy(password, p+1);
got_pass = 1;
}
break;
@@ -521,12 +516,16 @@ static void usage(void)
argc -= optind;
argv += optind;
+ lp_load(servicesf,True,False,False);
+ load_interfaces();
+ codepage_initialise(lp_client_code_page());
cli = connect_one(share);
if (!cli) {
DEBUG(0,("Failed to connect to %s\n", share));
exit(1);
}
+ Protocol = cli->protocol;
/* need to init seed after connect as clientgen uses random numbers */
DEBUG(0,("seed=%d\n", seed));
diff --git a/source/torture/msgtest.c b/source/utils/msgtest.c
index c40973a75c8..3fbf95af8fa 100644..100755
--- a/source/torture/msgtest.c
+++ b/source/utils/msgtest.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Copyright (C) Andrew Tridgell 2000
This program is free software; you can redistribute it and/or modify
@@ -39,11 +40,15 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len)
{
pid_t pid;
int i, n;
+ static pstring servicesf = CONFIGFILE;
char buf[12];
+ TimeInit();
setup_logging(argv[0],True);
- lp_load(dyn_CONFIGFILE,False,False,False);
+ charset_initialise();
+
+ lp_load(servicesf,False,False,False);
message_init();
@@ -63,7 +68,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len)
while (pong_count < i) {
message_dispatch();
- smb_msleep(1);
+ msleep(1);
}
/* Now test that the duplicate filtering code works. */
@@ -78,7 +83,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len)
for (i=0;i<n;i++) {
message_dispatch();
- smb_msleep(1);
+ msleep(1);
}
if (pong_count != 2) {
diff --git a/source/utils/nbio.c b/source/utils/nbio.c
new file mode 100755
index 00000000000..4866e52d4ec
--- /dev/null
+++ b/source/utils/nbio.c
@@ -0,0 +1,240 @@
+#define NBDEBUG 0
+
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB torture tester
+ Copyright (C) Andrew Tridgell 1997-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+#define MAX_FILES 1000
+
+static char buf[70000];
+extern int line_count;
+
+static struct {
+ int fd;
+ int handle;
+} ftable[MAX_FILES];
+
+static struct cli_state *c;
+
+static void sigsegv(int sig)
+{
+ char line[200];
+ printf("segv at line %d\n", line_count);
+ slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d",
+ (int)getpid(), (int)getpid());
+ system(line);
+ exit(1);
+}
+
+void nb_setup(struct cli_state *cli)
+{
+ signal(SIGSEGV, sigsegv);
+ c = cli;
+}
+
+
+void nb_unlink(char *fname)
+{
+ strupper(fname);
+
+ if (!cli_unlink(c, fname)) {
+#if NBDEBUG
+ printf("(%d) unlink %s failed (%s)\n",
+ line_count, fname, cli_errstr(c));
+#endif
+ }
+}
+
+void nb_open(char *fname, int handle, int size)
+{
+ int fd, i;
+ int flags = O_RDWR|O_CREAT;
+ size_t st_size;
+ static int count;
+
+ strupper(fname);
+
+ if (size == 0) flags |= O_TRUNC;
+
+ fd = cli_open(c, fname, flags, DENY_NONE);
+ if (fd == -1) {
+#if NBDEBUG
+ printf("(%d) open %s failed for handle %d (%s)\n",
+ line_count, fname, handle, cli_errstr(c));
+#endif
+ return;
+ }
+ cli_getattrE(c, fd, NULL, &st_size, NULL, NULL, NULL);
+ if (size > st_size) {
+#if NBDEBUG
+ printf("(%d) needs expanding %s to %d from %d\n",
+ line_count, fname, size, (int)st_size);
+#endif
+ } else if (size < st_size) {
+#if NBDEBUG
+ printf("(%d) needs truncating %s to %d from %d\n",
+ line_count, fname, size, (int)st_size);
+#endif
+ }
+ for (i=0;i<MAX_FILES;i++) {
+ if (ftable[i].handle == 0) break;
+ }
+ if (i == MAX_FILES) {
+ printf("file table full for %s\n", fname);
+ exit(1);
+ }
+ ftable[i].handle = handle;
+ ftable[i].fd = fd;
+ if (count++ % 100 == 0) {
+ printf(".");
+ }
+}
+
+void nb_write(int handle, int size, int offset)
+{
+ int i;
+
+ if (buf[0] == 0) memset(buf, 1, sizeof(buf));
+
+ for (i=0;i<MAX_FILES;i++) {
+ if (ftable[i].handle == handle) break;
+ }
+ if (i == MAX_FILES) {
+#if NBDEBUG
+ printf("(%d) nb_write: handle %d was not open size=%d ofs=%d\n",
+ line_count, handle, size, offset);
+#endif
+ return;
+ }
+ if (cli_smbwrite(c, ftable[i].fd, buf, offset, size) != size) {
+ printf("(%d) write failed on handle %d, fd %d \
+errno %d (%s)\n", line_count, handle, ftable[i].fd, errno, strerror(errno));
+ if (errno == ENOSPC) {
+ printf("Halting.\n");
+ fflush(stdout);
+ fflush(stderr);
+ exit(3);
+ }
+ }
+}
+
+void nb_read(int handle, int size, int offset)
+{
+ int i, ret;
+
+ for (i=0;i<MAX_FILES;i++) {
+ if (ftable[i].handle == handle) break;
+ }
+ if (i == MAX_FILES) {
+ printf("(%d) nb_read: handle %d was not open size=%d ofs=%d\n",
+ line_count, handle, size, offset);
+ return;
+ }
+ if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != size) {
+#if NBDEBUG
+ printf("(%d) read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s)\n",
+ line_count, handle, offset, size, ret, ftable[i].fd, errno, strerror(errno));
+#endif
+ }
+}
+
+void nb_close(int handle)
+{
+ int i;
+ for (i=0;i<MAX_FILES;i++) {
+ if (ftable[i].handle == handle) break;
+ }
+ if (i == MAX_FILES) {
+ printf("(%d) nb_close: handle %d was not open\n",
+ line_count, handle);
+ return;
+ }
+ cli_close(c, ftable[i].fd);
+ ftable[i].handle = 0;
+}
+
+void nb_mkdir(char *fname)
+{
+ strupper(fname);
+
+ if (!cli_mkdir(c, fname)) {
+#if NBDEBUG
+ printf("mkdir %s failed (%s)\n",
+ fname, cli_errstr(c));
+#endif
+ }
+}
+
+void nb_rmdir(char *fname)
+{
+ strupper(fname);
+
+ if (!cli_rmdir(c, fname)) {
+#if NBDEBUG
+ printf("rmdir %s failed (%s)\n",
+ fname, cli_errstr(c));
+#endif
+ }
+}
+
+void nb_rename(char *old, char *new)
+{
+ strupper(old);
+ strupper(new);
+
+ if (!cli_rename(c, old, new)) {
+#if NBDEBUG
+ printf("rename %s %s failed (%s)\n",
+ old, new, cli_errstr(c));
+#endif
+ }
+}
+
+
+void nb_stat(char *fname, int size)
+{
+ size_t st_size;
+
+ strupper(fname);
+
+ if (!cli_getatr(c, fname, NULL, &st_size, NULL)) {
+#if NBDEBUG
+ printf("(%d) nb_stat: %s size=%d %s\n",
+ line_count, fname, size, cli_errstr(c));
+#endif
+ return;
+ }
+ if (st_size != size) {
+#if NBDEBUG
+ printf("(%d) nb_stat: %s wrong size %d %d\n",
+ line_count, fname, (int)st_size, size);
+#endif
+ }
+}
+
+void nb_create(char *fname, int size)
+{
+ nb_open(fname, 5000, size);
+ nb_close(5000);
+}
diff --git a/source/utils/net.c b/source/utils/net.c
deleted file mode 100644
index b78cedf23c6..00000000000
--- a/source/utils/net.c
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
- Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
- Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
-
- Originally written by Steve and Jim. Largely rewritten by tridge in
- November 2001.
-
- Reworked again by abartlet in December 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/*****************************************************/
-/* */
-/* Distributed SMB/CIFS Server Management Utility */
-/* */
-/* The intent was to make the syntax similar */
-/* to the NET utility (first developed in DOS */
-/* with additional interesting & useful functions */
-/* added in later SMB server network operating */
-/* systems). */
-/* */
-/*****************************************************/
-
-#include "includes.h"
-#include "../utils/net.h"
-
-/***********************************************************************/
-/* Beginning of internationalization section. Translatable constants */
-/* should be kept in this area and referenced in the rest of the code. */
-/* */
-/* No functions, outside of Samba or LSB (Linux Standards Base) should */
-/* be used (if possible). */
-/***********************************************************************/
-
-#define YES_STRING "Yes"
-#define NO_STRING "No"
-
-/************************************************************************************/
-/* end of internationalization section */
-/************************************************************************************/
-
-/* Yes, these buggers are globals.... */
-const char *opt_requester_name = NULL;
-const char *opt_host = NULL;
-const char *opt_password = NULL;
-const char *opt_user_name = NULL;
-BOOL opt_user_specified = False;
-const char *opt_workgroup = NULL;
-int opt_long_list_entries = 0;
-int opt_reboot = 0;
-int opt_force = 0;
-int opt_port = 0;
-int opt_verbose = 0;
-int opt_maxusers = -1;
-const char *opt_comment = "";
-const char *opt_container = "cn=Users";
-int opt_flags = -1;
-int opt_timeout = 0;
-const char *opt_target_workgroup = NULL;
-int opt_machine_pass = 0;
-BOOL opt_localgroup = False;
-BOOL opt_domaingroup = False;
-const char *opt_newntname = "";
-int opt_rid = 0;
-
-BOOL opt_have_ip = False;
-struct in_addr opt_dest_ip;
-
-extern BOOL AllowDebugChange;
-
-uint32 get_sec_channel_type(const char *param)
-{
- if (!(param && *param)) {
- return get_default_sec_channel();
- } else {
- if (strequal(param, "PDC")) {
- return SEC_CHAN_BDC;
- } else if (strequal(param, "BDC")) {
- return SEC_CHAN_BDC;
- } else if (strequal(param, "MEMBER")) {
- return SEC_CHAN_WKSTA;
-#if 0
- } else if (strequal(param, "DOMAIN")) {
- return SEC_CHAN_DOMAIN;
-#endif
- } else {
- return get_default_sec_channel();
- }
- }
-}
-
-/*
- run a function from a function table. If not found then
- call the specified usage function
-*/
-int net_run_function(int argc, const char **argv, struct functable *table,
- int (*usage_fn)(int argc, const char **argv))
-{
- int i;
-
- if (argc < 1) {
- d_printf("\nUsage: \n");
- return usage_fn(argc, argv);
- }
- for (i=0; table[i].funcname; i++) {
- if (StrCaseCmp(argv[0], table[i].funcname) == 0)
- return table[i].fn(argc-1, argv+1);
- }
- d_printf("No command: %s\n", argv[0]);
- return usage_fn(argc, argv);
-}
-
-
-/****************************************************************************
-connect to \\server\ipc$
-****************************************************************************/
-NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
- const char *server_name)
-{
- NTSTATUS nt_status;
-
- if (!opt_password && !opt_machine_pass) {
- char *pass = getpass("Password:");
- if (pass) {
- opt_password = strdup(pass);
- }
- }
-
- nt_status = cli_full_connection(c, opt_requester_name, server_name,
- server_ip, opt_port,
- "IPC$", "IPC",
- opt_user_name, opt_workgroup,
- opt_password, 0, Undefined, NULL);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- } else {
- d_printf("Could not connect to server %s\n", server_name);
-
- /* Display a nicer message depending on the result */
-
- if (NT_STATUS_V(nt_status) ==
- NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
- d_printf("The username or password was not correct.\n");
-
- if (NT_STATUS_V(nt_status) ==
- NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
- d_printf("The account was locked out.\n");
-
- if (NT_STATUS_V(nt_status) ==
- NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
- d_printf("The account was disabled.\n");
-
- return nt_status;
- }
-}
-
-/****************************************************************************
-connect to \\server\ipc$ anonymously
-****************************************************************************/
-NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
- struct in_addr *server_ip, const char *server_name)
-{
- NTSTATUS nt_status;
-
- nt_status = cli_full_connection(c, opt_requester_name, server_name,
- server_ip, opt_port,
- "IPC$", "IPC",
- "", "",
- "", 0, Undefined, NULL);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- } else {
- DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status)));
- return nt_status;
- }
-}
-
-/****************************************************************************
- Use the local machine's password for this session
-****************************************************************************/
-int net_use_machine_password(void)
-{
- char *user_name = NULL;
-
- if (!secrets_init()) {
- d_printf("ERROR: Unable to open secrets database\n");
- exit(1);
- }
-
- user_name = NULL;
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
- if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
- return -1;
- }
- opt_user_name = user_name;
- return 0;
-}
-
-BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
-{
-
- if (opt_host) {
- *server_name = strdup(opt_host);
- }
-
- if (opt_have_ip) {
- *server_ip = opt_dest_ip;
- if (!*server_name) {
- *server_name = strdup(inet_ntoa(opt_dest_ip));
- }
- } else if (*server_name) {
- /* resolve the IP address */
- if (!resolve_name(*server_name, server_ip, 0x20)) {
- DEBUG(1,("Unable to resolve server name\n"));
- return False;
- }
- } else if (flags & NET_FLAGS_PDC) {
- struct in_addr pdc_ip;
-
- if (get_pdc_ip(opt_target_workgroup, &pdc_ip)) {
- fstring dc_name;
-
- if (is_zero_ip(pdc_ip))
- return False;
-
- if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
- return False;
-
- *server_name = strdup(dc_name);
- *server_ip = pdc_ip;
- }
-
- } else if (flags & NET_FLAGS_DMB) {
- struct in_addr msbrow_ip;
- /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
- if (!resolve_name(opt_target_workgroup, &msbrow_ip, 0x1B)) {
- DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
- return False;
- } else {
- *server_ip = msbrow_ip;
- }
- *server_name = strdup(inet_ntoa(opt_dest_ip));
- } else if (flags & NET_FLAGS_MASTER) {
- struct in_addr brow_ips;
- if (!resolve_name(opt_target_workgroup, &brow_ips, 0x1D)) {
- /* go looking for workgroups */
- DEBUG(1,("Unable to resolve master browser via name lookup\n"));
- return False;
- } else {
- *server_ip = brow_ips;
- }
- *server_name = strdup(inet_ntoa(opt_dest_ip));
- } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
- extern struct in_addr loopback_ip;
- *server_ip = loopback_ip;
- *server_name = strdup("127.0.0.1");
- }
-
- if (!server_name || !*server_name) {
- DEBUG(1,("no server to connect to\n"));
- return False;
- }
-
- return True;
-}
-
-
-BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
-{
- if (get_pdc_ip(domain_name, server_ip)) {
- if (is_zero_ip(*server_ip))
- return False;
-
- if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
- return False;
-
- return True;
- }
- else
- return False;
-}
-
-
-struct cli_state *net_make_ipc_connection(unsigned flags)
-{
- char *server_name = NULL;
- struct in_addr server_ip;
- struct cli_state *cli = NULL;
- NTSTATUS nt_status;
-
- if (!net_find_server(flags, &server_ip, &server_name)) {
- d_printf("\nUnable to find a suitable server\n");
- return NULL;
- }
-
- if (flags & NET_FLAGS_ANONYMOUS) {
- nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name);
- } else {
- nt_status = connect_to_ipc(&cli, &server_ip, server_name);
- }
-
- SAFE_FREE(server_name);
- if (NT_STATUS_IS_OK(nt_status)) {
- return cli;
- } else {
- return NULL;
- }
-}
-
-static int net_user(int argc, const char **argv)
-{
- if (net_ads_check() == 0)
- return net_ads_user(argc, argv);
-
- /* if server is not specified, default to PDC? */
- if (net_rpc_check(NET_FLAGS_PDC))
- return net_rpc_user(argc, argv);
-
- return net_rap_user(argc, argv);
-}
-
-static int net_group(int argc, const char **argv)
-{
- if (net_ads_check() == 0)
- return net_ads_group(argc, argv);
-
- if (argc == 0 && net_rpc_check(NET_FLAGS_PDC))
- return net_rpc_group(argc, argv);
-
- return net_rap_group(argc, argv);
-}
-
-static int net_join(int argc, const char **argv)
-{
- if (net_ads_check() == 0) {
- if (net_ads_join(argc, argv) == 0)
- return 0;
- else
- d_printf("ADS join did not work, falling back to RPC...\n");
- }
- return net_rpc_join(argc, argv);
-}
-
-static int net_changetrustpw(int argc, const char **argv)
-{
- if (net_ads_check() == 0)
- return net_ads_changetrustpw(argc, argv);
-
- return net_rpc_changetrustpw(argc, argv);
-}
-
-static int net_changesecretpw(int argc, const char **argv)
-{
- char *trust_pw;
- uint32 sec_channel_type = SEC_CHAN_WKSTA;
-
- if(opt_force) {
- trust_pw = getpass("Enter machine password: ");
-
- if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
- d_printf("Unable to write the machine account password in the secrets database");
- return 1;
- }
- else {
- d_printf("Modified trust account password in secrets database\n");
- }
- }
- else {
- d_printf("Machine account password change requires the -f flag.\n");
- d_printf("Do NOT use this function unless you know what it does!\n");
- d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n");
- }
-
- return 0;
-}
-
-static int net_share(int argc, const char **argv)
-{
- if (net_rpc_check(0))
- return net_rpc_share(argc, argv);
- return net_rap_share(argc, argv);
-}
-
-static int net_file(int argc, const char **argv)
-{
- if (net_rpc_check(0))
- return net_rpc_file(argc, argv);
- return net_rap_file(argc, argv);
-}
-
-/*
- Retrieve our local SID or the SID for the specified name
- */
-static int net_getlocalsid(int argc, const char **argv)
-{
- DOM_SID sid;
- const char *name;
- fstring sid_str;
-
- if (argc >= 1) {
- name = argv[0];
- }
- else {
- name = global_myname();
- }
-
- if(!initialize_password_db(False)) {
- DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
- "backend knowlege (such as the sid stored in LDAP)\n"));
- }
-
- /* Generate one, if it doesn't exist */
- get_global_sam_sid();
-
- if (!secrets_fetch_domain_sid(name, &sid)) {
- DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
- return 1;
- }
- sid_to_string(sid_str, &sid);
- d_printf("SID for domain %s is: %s\n", name, sid_str);
- return 0;
-}
-
-static int net_setlocalsid(int argc, const char **argv)
-{
- DOM_SID sid;
-
- if ( (argc != 1)
- || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
- || (!string_to_sid(&sid, argv[0]))
- || (sid.num_auths != 4)) {
- d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n");
- return 1;
- }
-
- if (!secrets_store_domain_sid(global_myname(), &sid)) {
- DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
- return 1;
- }
-
- return 0;
-}
-
-static int net_getdomainsid(int argc, const char **argv)
-{
- DOM_SID domain_sid;
- fstring sid_str;
-
- if(!initialize_password_db(False)) {
- DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n"
- "backend knowlege (such as the sid stored in LDAP)\n"));
- }
-
- /* Generate one, if it doesn't exist */
- get_global_sam_sid();
-
- if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
- d_printf("Could not fetch local SID\n");
- return 1;
- }
- sid_to_string(sid_str, &domain_sid);
- d_printf("SID for domain %s is: %s\n", global_myname(), sid_str);
-
- if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) {
- d_printf("Could not fetch domain SID\n");
- return 1;
- }
-
- sid_to_string(sid_str, &domain_sid);
- d_printf("SID for domain %s is: %s\n", opt_workgroup, sid_str);
-
- return 0;
-}
-
-#ifdef WITH_FAKE_KASERVER
-
-int net_afskey_usage(int argc, const char **argv)
-{
- d_printf(" net afskey filename\n"
- "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n");
- return -1;
-}
-
-static int net_afskey(int argc, const char **argv)
-{
- int fd;
- struct afs_keyfile keyfile;
-
- if (argc != 2) {
- d_printf("usage: 'net afskey <keyfile> cell'\n");
- return -1;
- }
-
- if (!secrets_init()) {
- d_printf("Could not open secrets.tdb\n");
- return -1;
- }
-
- if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
- d_printf("Could not open %s\n", argv[0]);
- return -1;
- }
-
- if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
- d_printf("Could not read keyfile\n");
- return -1;
- }
-
- if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
- d_printf("Could not write keyfile to secrets.tdb\n");
- return -1;
- }
-
- return 0;
-}
-
-#endif /* WITH_FAKE_KASERVER */
-
-static uint32 get_maxrid(void)
-{
- SAM_ACCOUNT *pwd = NULL;
- uint32 max_rid = 0;
- GROUP_MAP *map = NULL;
- int num_entries = 0;
- int i;
-
- if (!pdb_setsampwent(False)) {
- DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
- return 0;
- }
-
- for (; (NT_STATUS_IS_OK(pdb_init_sam(&pwd)))
- && pdb_getsampwent(pwd) == True; pwd=NULL) {
- uint32 rid;
-
- if (!sid_peek_rid(pdb_get_user_sid(pwd), &rid)) {
- DEBUG(0, ("can't get RID for user '%s'\n",
- pdb_get_username(pwd)));
- pdb_free_sam(&pwd);
- continue;
- }
-
- if (rid > max_rid)
- max_rid = rid;
-
- DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd)));
- pdb_free_sam(&pwd);
- }
-
- pdb_endsampwent();
- pdb_free_sam(&pwd);
-
- if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
- ENUM_ONLY_MAPPED))
- return max_rid;
-
- for (i = 0; i < num_entries; i++) {
- uint32 rid;
-
- if (!sid_peek_check_rid(get_global_sam_sid(), &map[i].sid,
- &rid)) {
- DEBUG(3, ("skipping map for group '%s', SID %s\n",
- map[i].nt_name,
- sid_string_static(&map[i].sid)));
- continue;
- }
- DEBUG(1,("%d is group '%s'\n", rid, map[i].nt_name));
-
- if (rid > max_rid)
- max_rid = rid;
- }
-
- SAFE_FREE(map);
-
- return max_rid;
-}
-
-static int net_maxrid(int argc, const char **argv)
-{
- uint32 rid;
-
- if (argc != 0) {
- DEBUG(0, ("usage: net maxrid\n"));
- return 1;
- }
-
- if ((rid = get_maxrid()) == 0) {
- DEBUG(0, ("can't get current maximum rid\n"));
- return 1;
- }
-
- d_printf("Currently used maximum rid: %d\n", rid);
-
- return 0;
-}
-
-/* main function table */
-static struct functable net_func[] = {
- {"RPC", net_rpc},
- {"RAP", net_rap},
- {"ADS", net_ads},
-
- /* eventually these should auto-choose the transport ... */
- {"FILE", net_file},
- {"SHARE", net_share},
- {"SESSION", net_rap_session},
- {"SERVER", net_rap_server},
- {"DOMAIN", net_rap_domain},
- {"PRINTQ", net_rap_printq},
- {"USER", net_user},
- {"GROUP", net_group},
- {"GROUPMAP", net_groupmap},
- {"VALIDATE", net_rap_validate},
- {"GROUPMEMBER", net_rap_groupmember},
- {"ADMIN", net_rap_admin},
- {"SERVICE", net_rap_service},
- {"PASSWORD", net_rap_password},
- {"CHANGETRUSTPW", net_changetrustpw},
- {"CHANGESECRETPW", net_changesecretpw},
- {"TIME", net_time},
- {"LOOKUP", net_lookup},
- {"JOIN", net_join},
- {"CACHE", net_cache},
- {"GETLOCALSID", net_getlocalsid},
- {"SETLOCALSID", net_setlocalsid},
- {"GETDOMAINSID", net_getdomainsid},
- {"MAXRID", net_maxrid},
- {"IDMAP", net_idmap},
- {"STATUS", net_status},
-#ifdef WITH_FAKE_KASERVER
- {"AFSKEY", net_afskey},
-#endif
- {"PRIV", net_priv},
-
- {"HELP", net_help},
- {NULL, NULL}
-};
-
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc, const char **argv)
-{
- int opt,i;
- char *p;
- int rc = 0;
- int argc_new = 0;
- const char ** argv_new;
- poptContext pc;
-
- struct poptOption long_options[] = {
- {"help", 'h', POPT_ARG_NONE, 0, 'h'},
- {"workgroup", 'w', POPT_ARG_STRING, &opt_target_workgroup},
- {"user", 'U', POPT_ARG_STRING, &opt_user_name, 'U'},
- {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'},
- {"port", 'p', POPT_ARG_INT, &opt_port},
- {"myname", 'n', POPT_ARG_STRING, &opt_requester_name},
- {"server", 'S', POPT_ARG_STRING, &opt_host},
- {"container", 'c', POPT_ARG_STRING, &opt_container},
- {"comment", 'C', POPT_ARG_STRING, &opt_comment},
- {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers},
- {"flags", 'F', POPT_ARG_INT, &opt_flags},
- {"long", 'l', POPT_ARG_NONE, &opt_long_list_entries},
- {"reboot", 'r', POPT_ARG_NONE, &opt_reboot},
- {"force", 'f', POPT_ARG_NONE, &opt_force},
- {"timeout", 't', POPT_ARG_INT, &opt_timeout},
- {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass},
- {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
- {"verbose", 'v', POPT_ARG_NONE, &opt_verbose},
- /* Options for 'net groupmap set' */
- {"local", 'L', POPT_ARG_NONE, &opt_localgroup},
- {"domain", 'D', POPT_ARG_NONE, &opt_domaingroup},
- {"ntname", 'N', POPT_ARG_STRING, &opt_newntname},
- {"rid", 'R', POPT_ARG_INT, &opt_rid},
-
- POPT_COMMON_SAMBA
- { 0, 0, 0, 0}
- };
-
- zero_ip(&opt_dest_ip);
-
- /* set default debug level to 0 regardless of what smb.conf sets */
- DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
- dbf = x_stderr;
-
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'h':
- net_help(argc, argv);
- exit(0);
- break;
- case 'I':
- opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
- if (is_zero_ip(opt_dest_ip))
- d_printf("\nInvalid ip address specified\n");
- else
- opt_have_ip = True;
- break;
- case 'U':
- opt_user_specified = True;
- opt_user_name = strdup(opt_user_name);
- p = strchr(opt_user_name,'%');
- if (p) {
- *p = 0;
- opt_password = p+1;
- }
- break;
- default:
- d_printf("\nInvalid option %s: %s\n",
- poptBadOption(pc, 0), poptStrerror(opt));
- net_help(argc, argv);
- exit(1);
- }
- }
-
- /*
- * Don't load debug level from smb.conf. It should be
- * set by cmdline arg or remain default (0)
- */
- AllowDebugChange = False;
- lp_load(dyn_CONFIGFILE,True,False,False);
-
- argv_new = (const char **)poptGetArgs(pc);
-
- argc_new = argc;
- for (i=0; i<argc; i++) {
- if (argv_new[i] == NULL) {
- argc_new = i;
- break;
- }
- }
-
- if (!opt_requester_name) {
- static fstring myname;
- get_myname(myname);
- opt_requester_name = myname;
- }
-
- if (!opt_user_name && getenv("LOGNAME")) {
- opt_user_name = getenv("LOGNAME");
- }
-
- if (!opt_workgroup) {
- opt_workgroup = smb_xstrdup(lp_workgroup());
- }
-
- if (!opt_target_workgroup) {
- opt_target_workgroup = smb_xstrdup(lp_workgroup());
- }
-
- if (!init_names())
- exit(1);
-
- load_interfaces();
-
- /* this makes sure that when we do things like call scripts,
- that it won't assert becouse we are not root */
- sec_init();
-
- if (opt_machine_pass) {
- /* it is very useful to be able to make ads queries as the
- machine account for testing purposes and for domain leave */
-
- net_use_machine_password();
- }
-
- if (!opt_password) {
- opt_password = getenv("PASSWD");
- }
-
- rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
-
- DEBUG(2,("return code = %d\n", rc));
- return rc;
-}
diff --git a/source/utils/net.h b/source/utils/net.h
deleted file mode 100644
index ba3a4e14352..00000000000
--- a/source/utils/net.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "../utils/net_proto.h"
-
-#define NET_FLAGS_MASTER 1
-#define NET_FLAGS_DMB 2
-
-/* Would it be insane to set 'localhost' as the default
- remote host for this operation?
-
- For example, localhost is insane for a 'join' operation.
-*/
-#define NET_FLAGS_LOCALHOST_DEFAULT_INSANE 4
-
-/* We want to find the PDC only */
-#define NET_FLAGS_PDC 8
-
-/* We want an anonymous connection */
-#define NET_FLAGS_ANONYMOUS 16
-
-/* don't open an RPC pipe */
-#define NET_FLAGS_NO_PIPE 32
-
-extern int opt_maxusers;
-extern const char *opt_comment;
-extern const char *opt_container;
-extern int opt_flags;
-
-extern const char *opt_comment;
-
-extern const char *opt_target_workgroup;
-extern const char *opt_workgroup;
-extern int opt_long_list_entries;
-extern int opt_verbose;
-extern int opt_reboot;
-extern int opt_force;
-extern int opt_machine_pass;
-extern int opt_timeout;
-extern const char *opt_host;
-extern const char *opt_user_name;
-extern const char *opt_password;
-extern BOOL opt_user_specified;
-
-extern BOOL opt_localgroup;
-extern BOOL opt_domaingroup;
-extern const char *opt_newntname;
-extern int opt_rid;
-
-extern BOOL opt_have_ip;
-extern struct in_addr opt_dest_ip;
-
-extern const char *share_type[];
-
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
deleted file mode 100644
index 6eec71aedf3..00000000000
--- a/source/utils/net_ads.c
+++ /dev/null
@@ -1,1328 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net ads commands
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
- Copyright (C) 2001 Remus Koos (remuskoos@yahoo.com)
- Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "../utils/net.h"
-
-#ifdef HAVE_ADS
-
-int net_ads_usage(int argc, const char **argv)
-{
- d_printf(
-"\nnet ads join <org_unit>"\
-"\n\tjoins the local machine to a ADS realm\n"\
-"\nnet ads leave"\
-"\n\tremoves the local machine from a ADS realm\n"\
-"\nnet ads testjoin"\
-"\n\ttests that an exiting join is OK\n"\
-"\nnet ads user"\
-"\n\tlist, add, or delete users in the realm\n"\
-"\nnet ads group"\
-"\n\tlist, add, or delete groups in the realm\n"\
-"\nnet ads info"\
-"\n\tshows some info on the server\n"\
-"\nnet ads status"\
-"\n\tdump the machine account details to stdout\n"
-"\nnet ads lookup"\
-"\n\tperform a CLDAP search on the server\n"
-"\nnet ads password <username@realm> <password> -Uadmin_username@realm%%admin_pass"\
-"\n\tchange a user's password using an admin account"\
-"\n\t(note: use realm in UPPERCASE, prompts if password is obmitted)\n"\
-"\nnet ads changetrustpw"\
-"\n\tchange the trust account password of this machine in the AD tree\n"\
-"\nnet ads printer [info | publish | remove] <printername> <servername>"\
-"\n\t lookup, add, or remove directory entry for a printer\n"\
-"\nnet ads search"\
-"\n\tperform a raw LDAP search and dump the results\n"
-"\nnet ads dn"\
-"\n\tperform a raw LDAP search and dump attributes of a particular DN\n"
- );
- return -1;
-}
-
-
-/*
- this implements the CLDAP based netlogon lookup requests
- for finding the domain controller of a ADS domain
-*/
-static int net_ads_lookup(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
-
- ads = ads_init(NULL, opt_target_workgroup, opt_host);
- if (ads) {
- ads->auth.flags |= ADS_AUTH_NO_BIND;
- }
-
- ads_connect(ads);
-
- if (!ads || !ads->config.realm) {
- d_printf("Didn't find the cldap server!\n");
- return -1;
- }
-
- return ads_cldap_netlogon(ads);
-}
-
-
-
-static int net_ads_info(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
-
- ads = ads_init(NULL, opt_target_workgroup, opt_host);
-
- if (ads) {
- ads->auth.flags |= ADS_AUTH_NO_BIND;
- }
-
- ads_connect(ads);
-
- if (!ads || !ads->config.realm) {
- d_printf("Didn't find the ldap server!\n");
- return -1;
- }
-
- d_printf("LDAP server: %s\n", inet_ntoa(ads->ldap_ip));
- d_printf("LDAP server name: %s\n", ads->config.ldap_server_name);
- d_printf("Realm: %s\n", ads->config.realm);
- d_printf("Bind Path: %s\n", ads->config.bind_path);
- d_printf("LDAP port: %d\n", ads->ldap_port);
- d_printf("Server time: %s\n", http_timestring(ads->config.current_time));
-
- d_printf("KDC server: %s\n", ads->auth.kdc_server );
- d_printf("Server time offset: %d\n", ads->auth.time_offset );
-
- return 0;
-}
-
-static void use_in_memory_ccache(void) {
- /* Use in-memory credentials cache so we do not interfere with
- * existing credentials */
- setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
-}
-
-static ADS_STRUCT *ads_startup(void)
-{
- ADS_STRUCT *ads;
- ADS_STATUS status;
- BOOL need_password = False;
- BOOL second_time = False;
- char *cp;
-
- /* lp_realm() should be handled by a command line param,
- However, the join requires that realm be set in smb.conf
- and compares our realm with the remote server's so this is
- ok until someone needs more flexibility */
-
- ads = ads_init(lp_realm(), opt_target_workgroup, opt_host);
-
- if (!opt_user_name) {
- opt_user_name = "administrator";
- }
-
- if (opt_user_specified) {
- need_password = True;
- }
-
-retry:
- if (!opt_password && need_password && !opt_machine_pass) {
- char *prompt;
- asprintf(&prompt,"%s's password: ", opt_user_name);
- opt_password = getpass(prompt);
- free(prompt);
- }
-
- if (opt_password) {
- use_in_memory_ccache();
- ads->auth.password = smb_xstrdup(opt_password);
- }
-
- ads->auth.user_name = smb_xstrdup(opt_user_name);
-
- /*
- * If the username is of the form "name@realm",
- * extract the realm and convert to upper case.
- * This is only used to establish the connection.
- */
- if ((cp = strchr(ads->auth.user_name, '@'))!=0) {
- *cp++ = '\0';
- ads->auth.realm = smb_xstrdup(cp);
- strupper_m(ads->auth.realm);
- }
-
- status = ads_connect(ads);
-
- if (!ADS_ERR_OK(status)) {
- if (!need_password && !second_time) {
- need_password = True;
- second_time = True;
- goto retry;
- } else {
- DEBUG(1,("ads_connect: %s\n", ads_errstr(status)));
- return NULL;
- }
- }
- return ads;
-}
-
-
-/*
- Check to see if connection can be made via ads.
- ads_startup() stores the password in opt_password if it needs to so
- that rpc or rap can use it without re-prompting.
-*/
-int net_ads_check(void)
-{
- ADS_STRUCT *ads;
-
- ads = ads_startup();
- if (!ads)
- return -1;
- ads_destroy(&ads);
- return 0;
-}
-
-/*
- determine the netbios workgroup name for a domain
- */
-static int net_ads_workgroup(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- TALLOC_CTX *ctx;
- const char *workgroup;
-
- if (!(ads = ads_startup())) return -1;
-
- if (!(ctx = talloc_init("net_ads_workgroup"))) {
- return -1;
- }
-
- if (!ADS_ERR_OK(ads_workgroup_name(ads, ctx, &workgroup))) {
- d_printf("Failed to find workgroup for realm '%s'\n",
- ads->config.realm);
- talloc_destroy(ctx);
- return -1;
- }
-
- d_printf("Workgroup: %s\n", workgroup);
-
- talloc_destroy(ctx);
-
- return 0;
-}
-
-
-
-static BOOL usergrp_display(char *field, void **values, void *data_area)
-{
- char **disp_fields = (char **) data_area;
-
- if (!field) { /* must be end of record */
- if (!strchr_m(disp_fields[0], '$')) {
- if (disp_fields[1])
- d_printf("%-21.21s %s\n",
- disp_fields[0], disp_fields[1]);
- else
- d_printf("%s\n", disp_fields[0]);
- }
- SAFE_FREE(disp_fields[0]);
- SAFE_FREE(disp_fields[1]);
- return True;
- }
- if (!values) /* must be new field, indicate string field */
- return True;
- if (StrCaseCmp(field, "sAMAccountName") == 0) {
- disp_fields[0] = strdup((char *) values[0]);
- }
- if (StrCaseCmp(field, "description") == 0)
- disp_fields[1] = strdup((char *) values[0]);
- return True;
-}
-
-static int net_ads_user_usage(int argc, const char **argv)
-{
- return net_help_user(argc, argv);
-}
-
-static int ads_user_add(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS status;
- char *upn, *userdn;
- void *res=NULL;
- int rc = -1;
-
- if (argc < 1) return net_ads_user_usage(argc, argv);
-
- if (!(ads = ads_startup())) return -1;
-
- status = ads_find_user_acct(ads, &res, argv[0]);
-
- if (!ADS_ERR_OK(status)) {
- d_printf("ads_user_add: %s\n", ads_errstr(status));
- goto done;
- }
-
- if (ads_count_replies(ads, res)) {
- d_printf("ads_user_add: User %s already exists\n", argv[0]);
- goto done;
- }
-
- status = ads_add_user_acct(ads, argv[0], opt_container, opt_comment);
-
- if (!ADS_ERR_OK(status)) {
- d_printf("Could not add user %s: %s\n", argv[0],
- ads_errstr(status));
- goto done;
- }
-
- /* if no password is to be set, we're done */
- if (argc == 1) {
- d_printf("User %s added\n", argv[0]);
- rc = 0;
- goto done;
- }
-
- /* try setting the password */
- asprintf(&upn, "%s@%s", argv[0], ads->config.realm);
- status = ads_krb5_set_password(ads->auth.kdc_server, upn, argv[1],
- ads->auth.time_offset);
- safe_free(upn);
- if (ADS_ERR_OK(status)) {
- d_printf("User %s added\n", argv[0]);
- rc = 0;
- goto done;
- }
-
- /* password didn't set, delete account */
- d_printf("Could not add user %s. Error setting password %s\n",
- argv[0], ads_errstr(status));
- ads_msgfree(ads, res);
- status=ads_find_user_acct(ads, &res, argv[0]);
- if (ADS_ERR_OK(status)) {
- userdn = ads_get_dn(ads, res);
- ads_del_dn(ads, userdn);
- ads_memfree(ads, userdn);
- }
-
- done:
- if (res)
- ads_msgfree(ads, res);
- ads_destroy(&ads);
- return rc;
-}
-
-static int ads_user_info(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- void *res;
- const char *attrs[] = {"memberOf", NULL};
- char *searchstring=NULL;
- char **grouplist;
- char *escaped_user = escape_ldap_string_alloc(argv[0]);
-
- if (argc < 1) return net_ads_user_usage(argc, argv);
-
- if (!(ads = ads_startup())) return -1;
-
- if (!escaped_user) {
- d_printf("ads_user_info: failed to escape user %s\n", argv[0]);
- return -1;
- }
-
- asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user);
- rc = ads_search(ads, &res, searchstring, attrs);
- safe_free(searchstring);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_search: %s\n", ads_errstr(rc));
- return -1;
- }
-
- grouplist = ldap_get_values(ads->ld, res, "memberOf");
-
- if (grouplist) {
- int i;
- char **groupname;
- for (i=0;grouplist[i];i++) {
- groupname = ldap_explode_dn(grouplist[i], 1);
- d_printf("%s\n", groupname[0]);
- ldap_value_free(groupname);
- }
- ldap_value_free(grouplist);
- }
-
- ads_msgfree(ads, res);
-
- ads_destroy(&ads);
- return 0;
-}
-
-static int ads_user_delete(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- void *res;
- char *userdn;
-
- if (argc < 1) return net_ads_user_usage(argc, argv);
-
- if (!(ads = ads_startup())) return -1;
-
- rc = ads_find_user_acct(ads, &res, argv[0]);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(0, ("User %s does not exist\n", argv[0]));
- return -1;
- }
- userdn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
- rc = ads_del_dn(ads, userdn);
- ads_memfree(ads, userdn);
- if (!ADS_ERR_OK(rc)) {
- d_printf("User %s deleted\n", argv[0]);
- return 0;
- }
- d_printf("Error deleting user %s: %s\n", argv[0],
- ads_errstr(rc));
- return -1;
-}
-
-int net_ads_user(int argc, const char **argv)
-{
- struct functable func[] = {
- {"ADD", ads_user_add},
- {"INFO", ads_user_info},
- {"DELETE", ads_user_delete},
- {NULL, NULL}
- };
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *shortattrs[] = {"sAMAccountName", NULL};
- const char *longattrs[] = {"sAMAccountName", "description", NULL};
- char *disp_fields[2] = {NULL, NULL};
-
- if (argc == 0) {
- if (!(ads = ads_startup())) return -1;
-
- if (opt_long_list_entries)
- d_printf("\nUser name Comment"\
- "\n-----------------------------\n");
-
- rc = ads_do_search_all_fn(ads, ads->config.bind_path,
- LDAP_SCOPE_SUBTREE,
- "(objectclass=user)",
- opt_long_list_entries ? longattrs :
- shortattrs, usergrp_display,
- disp_fields);
- ads_destroy(&ads);
- return 0;
- }
-
- return net_run_function(argc, argv, func, net_ads_user_usage);
-}
-
-static int net_ads_group_usage(int argc, const char **argv)
-{
- return net_help_group(argc, argv);
-}
-
-static int ads_group_add(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS status;
- void *res=NULL;
- int rc = -1;
-
- if (argc < 1) return net_ads_group_usage(argc, argv);
-
- if (!(ads = ads_startup())) return -1;
-
- status = ads_find_user_acct(ads, &res, argv[0]);
-
- if (!ADS_ERR_OK(status)) {
- d_printf("ads_group_add: %s\n", ads_errstr(status));
- goto done;
- }
-
- if (ads_count_replies(ads, res)) {
- d_printf("ads_group_add: Group %s already exists\n", argv[0]);
- ads_msgfree(ads, res);
- goto done;
- }
-
- status = ads_add_group_acct(ads, argv[0], opt_container, opt_comment);
-
- if (ADS_ERR_OK(status)) {
- d_printf("Group %s added\n", argv[0]);
- rc = 0;
- } else {
- d_printf("Could not add group %s: %s\n", argv[0],
- ads_errstr(status));
- }
-
- done:
- if (res)
- ads_msgfree(ads, res);
- ads_destroy(&ads);
- return rc;
-}
-
-static int ads_group_delete(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- void *res;
- char *groupdn;
-
- if (argc < 1) return net_ads_group_usage(argc, argv);
-
- if (!(ads = ads_startup())) return -1;
-
- rc = ads_find_user_acct(ads, &res, argv[0]);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(0, ("Group %s does not exist\n", argv[0]));
- return -1;
- }
- groupdn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
- rc = ads_del_dn(ads, groupdn);
- ads_memfree(ads, groupdn);
- if (!ADS_ERR_OK(rc)) {
- d_printf("Group %s deleted\n", argv[0]);
- return 0;
- }
- d_printf("Error deleting group %s: %s\n", argv[0],
- ads_errstr(rc));
- return -1;
-}
-
-int net_ads_group(int argc, const char **argv)
-{
- struct functable func[] = {
- {"ADD", ads_group_add},
- {"DELETE", ads_group_delete},
- {NULL, NULL}
- };
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *shortattrs[] = {"sAMAccountName", NULL};
- const char *longattrs[] = {"sAMAccountName", "description", NULL};
- char *disp_fields[2] = {NULL, NULL};
-
- if (argc == 0) {
- if (!(ads = ads_startup())) return -1;
-
- if (opt_long_list_entries)
- d_printf("\nGroup name Comment"\
- "\n-----------------------------\n");
- rc = ads_do_search_all_fn(ads, ads->config.bind_path,
- LDAP_SCOPE_SUBTREE,
- "(objectclass=group)",
- opt_long_list_entries ? longattrs :
- shortattrs, usergrp_display,
- disp_fields);
-
- ads_destroy(&ads);
- return 0;
- }
- return net_run_function(argc, argv, func, net_ads_group_usage);
-}
-
-static int net_ads_status(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- void *res;
-
- if (!(ads = ads_startup())) return -1;
-
- rc = ads_find_machine_acct(ads, &res, global_myname());
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
- return -1;
- }
-
- if (ads_count_replies(ads, res) == 0) {
- d_printf("No machine account for '%s' found\n", global_myname());
- return -1;
- }
-
- ads_dump(ads, res);
-
- return 0;
-}
-
-static int net_ads_leave(int argc, const char **argv)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS rc;
-
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- if (!opt_password) {
- net_use_machine_password();
- }
-
- if (!(ads = ads_startup())) {
- return -1;
- }
-
- rc = ads_leave_realm(ads, global_myname());
- if (!ADS_ERR_OK(rc)) {
- d_printf("Failed to delete host '%s' from the '%s' realm.\n",
- global_myname(), ads->config.realm);
- return -1;
- }
-
- d_printf("Removed '%s' from realm '%s'\n", global_myname(), ads->config.realm);
-
- return 0;
-}
-
-static int net_ads_join_ok(void)
-{
- ADS_STRUCT *ads = NULL;
-
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- net_use_machine_password();
-
- if (!(ads = ads_startup())) {
- return -1;
- }
-
- ads_destroy(&ads);
- return 0;
-}
-
-/*
- check that an existing join is OK
- */
-int net_ads_testjoin(int argc, const char **argv)
-{
- use_in_memory_ccache();
-
- /* Display success or failure */
- if (net_ads_join_ok() != 0) {
- fprintf(stderr,"Join to domain is not valid\n");
- return -1;
- }
-
- printf("Join is OK\n");
- return 0;
-}
-
-/*
- join a domain using ADS
- */
-int net_ads_join(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- char *password;
- char *machine_account = NULL;
- char *tmp_password;
- const char *org_unit = "Computers";
- char *dn;
- void *res;
- DOM_SID dom_sid;
- char *ou_str;
- uint32 sec_channel_type = SEC_CHAN_WKSTA;
- uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
- const char *short_domain_name = NULL;
- TALLOC_CTX *ctx = NULL;
-
- if (argc > 0) org_unit = argv[0];
-
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
- password = strdup(tmp_password);
-
- if (!(ads = ads_startup())) return -1;
-
- if (!*lp_realm()) {
- d_printf("realm must be set in in smb.conf for ADS join to succeed.\n");
- return -1;
- }
-
- if (strcmp(ads->config.realm, lp_realm()) != 0) {
- d_printf("realm of remote server (%s) and realm in smb.conf (%s) DO NOT match. Aborting join\n", ads->config.realm, lp_realm());
- return -1;
- }
-
- ou_str = ads_ou_string(org_unit);
- asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
- free(ou_str);
-
- rc = ads_search_dn(ads, &res, dn, NULL);
- ads_msgfree(ads, res);
-
- if (rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) {
- d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n",
- org_unit, dn);
- return -1;
- }
- free(dn);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_join_realm: %s\n", ads_errstr(rc));
- return -1;
- }
-
- rc = ads_join_realm(ads, global_myname(), account_type, org_unit);
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_join_realm: %s\n", ads_errstr(rc));
- return -1;
- }
-
- rc = ads_domain_sid(ads, &dom_sid);
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
- return -1;
- }
-
- if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
- d_printf("asprintf failed\n");
- return -1;
- }
-
- rc = ads_set_machine_password(ads, machine_account, password);
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
- return -1;
- }
-
- /* make sure we get the right workgroup */
-
- if ( !(ctx = talloc_init("net ads join")) ) {
- d_printf("talloc_init() failed!\n");
- return -1;
- }
-
- rc = ads_workgroup_name(ads, ctx, &short_domain_name);
- if ( ADS_ERR_OK(rc) ) {
- if ( !strequal(lp_workgroup(), short_domain_name) ) {
- d_printf("The workgroup in smb.conf does not match the short\n");
- d_printf("domain name obtained from the server.\n");
- d_printf("Using the name [%s] from the server.\n", short_domain_name);
- d_printf("You should set \"workgroup = %s\" in smb.conf.\n", short_domain_name);
- }
- }
- else
- short_domain_name = lp_workgroup();
-
- d_printf("Using short domain name -- %s\n", short_domain_name);
-
- /* HACK ALRET! Store the sid and password under bother the lp_workgroup()
- value from smb.conf and the string returned from the server. The former is
- neede to bootstrap winbindd's first connection to the DC to get the real
- short domain name --jerry */
-
- if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
- DEBUG(1,("Failed to save domain sid\n"));
- return -1;
- }
-
- if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) {
- DEBUG(1,("Failed to save machine password\n"));
- return -1;
- }
-
- if (!secrets_store_domain_sid(short_domain_name, &dom_sid)) {
- DEBUG(1,("Failed to save domain sid\n"));
- return -1;
- }
-
- if (!secrets_store_machine_password(password, short_domain_name, sec_channel_type)) {
- DEBUG(1,("Failed to save machine password\n"));
- return -1;
- }
-
- d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
-
- SAFE_FREE(password);
- SAFE_FREE(machine_account);
- if ( ctx )
- talloc_destroy(ctx);
- return 0;
-}
-
-int net_ads_printer_usage(int argc, const char **argv)
-{
- d_printf(
-"\nnet ads printer search <printer>"
-"\n\tsearch for a printer in the directory"
-"\nnet ads printer info <printer> <server>"
-"\n\tlookup info in directory for printer on server"
-"\n\t(note: printer defaults to \"*\", server defaults to local)\n"
-"\nnet ads printer publish <printername>"
-"\n\tpublish printer in directory"
-"\n\t(note: printer name is required)\n"
-"\nnet ads printer remove <printername>"
-"\n\tremove printer from directory"
-"\n\t(note: printer name is required)\n");
- return -1;
-}
-
-static int net_ads_printer_search(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- void *res = NULL;
-
- if (!(ads = ads_startup()))
- return -1;
-
- rc = ads_find_printers(ads, &res);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_find_printer: %s\n", ads_errstr(rc));
- ads_msgfree(ads, res);
- return -1;
- }
-
- if (ads_count_replies(ads, res) == 0) {
- d_printf("No results found\n");
- ads_msgfree(ads, res);
- return -1;
- }
-
- ads_dump(ads, res);
- ads_msgfree(ads, res);
-
- return 0;
-}
-
-static int net_ads_printer_info(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *servername, *printername;
- void *res = NULL;
-
- if (!(ads = ads_startup())) return -1;
-
- if (argc > 0)
- printername = argv[0];
- else
- printername = "*";
-
- if (argc > 1)
- servername = argv[1];
- else
- servername = global_myname();
-
- rc = ads_find_printer_on_server(ads, &res, printername, servername);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
- ads_msgfree(ads, res);
- return -1;
- }
-
- if (ads_count_replies(ads, res) == 0) {
- d_printf("Printer '%s' not found\n", printername);
- ads_msgfree(ads, res);
- return -1;
- }
-
- ads_dump(ads, res);
- ads_msgfree(ads, res);
-
- return 0;
-}
-
-void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
-{
- return;
-}
-
-static int net_ads_printer_publish(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *servername, *printername;
- struct cli_state *cli;
- struct in_addr server_ip;
- NTSTATUS nt_status;
- TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish");
- ADS_MODLIST mods = ads_init_mods(mem_ctx);
- char *prt_dn, *srv_dn, **srv_cn;
- void *res = NULL;
-
- if (!(ads = ads_startup())) return -1;
-
- if (argc < 1)
- return net_ads_printer_usage(argc, argv);
-
- printername = argv[0];
-
- if (argc == 2)
- servername = argv[1];
- else
- servername = global_myname();
-
- /* Get printer data from SPOOLSS */
-
- resolve_name(servername, &server_ip, 0x20);
-
- nt_status = cli_full_connection(&cli, global_myname(), servername,
- &server_ip, 0,
- "IPC$", "IPC",
- opt_user_name, opt_workgroup,
- opt_password ? opt_password : "",
- CLI_FULL_CONNECTION_USE_KERBEROS,
- Undefined, NULL);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- d_printf("Unable to open a connnection to %s to obtain data "
- "for %s\n", servername, printername);
- return -1;
- }
-
- /* Publish on AD server */
-
- ads_find_machine_acct(ads, &res, servername);
-
- if (ads_count_replies(ads, res) == 0) {
- d_printf("Could not find machine account for server %s\n",
- servername);
- return -1;
- }
-
- srv_dn = ldap_get_dn(ads->ld, res);
- srv_cn = ldap_explode_dn(srv_dn, 1);
-
- asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0], printername, srv_dn);
-
- cli_nt_session_open(cli, PI_SPOOLSS);
- get_remote_printer_publishing_data(cli, mem_ctx, &mods, printername);
-
- rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_publish_printer: %s\n", ads_errstr(rc));
- return -1;
- }
-
- d_printf("published printer\n");
-
- return 0;
-}
-
-static int net_ads_printer_remove(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *servername;
- char *prt_dn;
- void *res = NULL;
-
- if (!(ads = ads_startup())) return -1;
-
- if (argc < 1)
- return net_ads_printer_usage(argc, argv);
-
- if (argc > 1)
- servername = argv[1];
- else
- servername = global_myname();
-
- rc = ads_find_printer_on_server(ads, &res, argv[0], servername);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
- ads_msgfree(ads, res);
- return -1;
- }
-
- if (ads_count_replies(ads, res) == 0) {
- d_printf("Printer '%s' not found\n", argv[1]);
- ads_msgfree(ads, res);
- return -1;
- }
-
- prt_dn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
- rc = ads_del_dn(ads, prt_dn);
- ads_memfree(ads, prt_dn);
-
- if (!ADS_ERR_OK(rc)) {
- d_printf("ads_del_dn: %s\n", ads_errstr(rc));
- return -1;
- }
-
- return 0;
-}
-
-static int net_ads_printer(int argc, const char **argv)
-{
- struct functable func[] = {
- {"SEARCH", net_ads_printer_search},
- {"INFO", net_ads_printer_info},
- {"PUBLISH", net_ads_printer_publish},
- {"REMOVE", net_ads_printer_remove},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_ads_printer_usage);
-}
-
-
-static int net_ads_password(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- const char *auth_principal = opt_user_name;
- const char *auth_password = opt_password;
- char *realm = NULL;
- char *new_password = NULL;
- char *c, *prompt;
- const char *user;
- ADS_STATUS ret;
-
- if (opt_user_name == NULL || opt_password == NULL) {
- d_printf("You must supply an administrator username/password\n");
- return -1;
- }
-
-
- if (argc < 1) {
- d_printf("ERROR: You must say which username to change password for\n");
- return -1;
- }
-
- user = argv[0];
- if (!strchr(user, '@')) {
- asprintf(&c, "%s@%s", argv[0], lp_realm());
- user = c;
- }
-
- use_in_memory_ccache();
- c = strchr(auth_principal, '@');
- if (c) {
- realm = ++c;
- } else {
- realm = lp_realm();
- }
-
- /* use the realm so we can eventually change passwords for users
- in realms other than default */
- if (!(ads = ads_init(realm, NULL, NULL))) return -1;
-
- /* we don't actually need a full connect, but it's the easy way to
- fill in the KDC's addresss */
- ads_connect(ads);
-
- if (!ads || !ads->config.realm) {
- d_printf("Didn't find the kerberos server!\n");
- return -1;
- }
-
- if (argv[1]) {
- new_password = (char *)argv[1];
- } else {
- asprintf(&prompt, "Enter new password for %s:", user);
- new_password = getpass(prompt);
- free(prompt);
- }
-
- ret = kerberos_set_password(ads->auth.kdc_server, auth_principal,
- auth_password, user, new_password, ads->auth.time_offset);
- if (!ADS_ERR_OK(ret)) {
- d_printf("Password change failed :-( ...\n");
- ads_destroy(&ads);
- return -1;
- }
-
- d_printf("Password change for %s completed.\n", user);
- ads_destroy(&ads);
-
- return 0;
-}
-
-
-int net_ads_changetrustpw(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- char *host_principal;
- char *hostname;
- ADS_STATUS ret;
-
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- net_use_machine_password();
-
- use_in_memory_ccache();
-
- if (!(ads = ads_startup())) {
- return -1;
- }
-
- hostname = strdup(global_myname());
- strlower_m(hostname);
- asprintf(&host_principal, "%s@%s", hostname, ads->config.realm);
- SAFE_FREE(hostname);
- d_printf("Changing password for principal: HOST/%s\n", host_principal);
-
- ret = ads_change_trust_account_password(ads, host_principal);
-
- if (!ADS_ERR_OK(ret)) {
- d_printf("Password change failed :-( ...\n");
- ads_destroy(&ads);
- SAFE_FREE(host_principal);
- return -1;
- }
-
- d_printf("Password change for principal HOST/%s succeeded.\n", host_principal);
- ads_destroy(&ads);
- SAFE_FREE(host_principal);
-
- return 0;
-}
-
-/*
- help for net ads search
-*/
-static int net_ads_search_usage(int argc, const char **argv)
-{
- d_printf(
- "\nnet ads search <expression> <attributes...>\n"\
- "\nperform a raw LDAP search on a ADS server and dump the results\n"\
- "The expression is a standard LDAP search expression, and the\n"\
- "attributes are a list of LDAP fields to show in the results\n\n"\
- "Example: net ads search '(objectCategory=group)' sAMAccountName\n\n"
- );
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-
-/*
- general ADS search function. Useful in diagnosing problems in ADS
-*/
-static int net_ads_search(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *ldap_exp;
- const char **attrs;
- void *res = NULL;
-
- if (argc < 1) {
- return net_ads_search_usage(argc, argv);
- }
-
- if (!(ads = ads_startup())) {
- return -1;
- }
-
- ldap_exp = argv[0];
- attrs = (argv + 1);
-
- rc = ads_do_search_all(ads, ads->config.bind_path,
- LDAP_SCOPE_SUBTREE,
- ldap_exp, attrs, &res);
- if (!ADS_ERR_OK(rc)) {
- d_printf("search failed: %s\n", ads_errstr(rc));
- return -1;
- }
-
- d_printf("Got %d replies\n\n", ads_count_replies(ads, res));
-
- /* dump the results */
- ads_dump(ads, res);
-
- ads_msgfree(ads, res);
- ads_destroy(&ads);
-
- return 0;
-}
-
-
-/*
- help for net ads search
-*/
-static int net_ads_dn_usage(int argc, const char **argv)
-{
- d_printf(
- "\nnet ads dn <dn> <attributes...>\n"\
- "\nperform a raw LDAP search on a ADS server and dump the results\n"\
- "The DN standard LDAP DN, and the attributes are a list of LDAP fields \n"\
- "to show in the results\n\n"\
- "Example: net ads dn 'CN=administrator,CN=Users,DC=my,DC=domain' sAMAccountName\n\n"
- );
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-
-/*
- general ADS search function. Useful in diagnosing problems in ADS
-*/
-static int net_ads_dn(int argc, const char **argv)
-{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
- const char *dn;
- const char **attrs;
- void *res = NULL;
-
- if (argc < 1) {
- return net_ads_dn_usage(argc, argv);
- }
-
- if (!(ads = ads_startup())) {
- return -1;
- }
-
- dn = argv[0];
- attrs = (argv + 1);
-
- rc = ads_do_search_all(ads, dn,
- LDAP_SCOPE_BASE,
- "(objectclass=*)", attrs, &res);
- if (!ADS_ERR_OK(rc)) {
- d_printf("search failed: %s\n", ads_errstr(rc));
- return -1;
- }
-
- d_printf("Got %d replies\n\n", ads_count_replies(ads, res));
-
- /* dump the results */
- ads_dump(ads, res);
-
- ads_msgfree(ads, res);
- ads_destroy(&ads);
-
- return 0;
-}
-
-
-int net_ads_help(int argc, const char **argv)
-{
- struct functable func[] = {
- {"USER", net_ads_user_usage},
- {"GROUP", net_ads_group_usage},
- {"PRINTER", net_ads_printer_usage},
- {"SEARCH", net_ads_search_usage},
-#if 0
- {"INFO", net_ads_info},
- {"JOIN", net_ads_join},
- {"LEAVE", net_ads_leave},
- {"STATUS", net_ads_status},
- {"PASSWORD", net_ads_password},
- {"CHANGETRUSTPW", net_ads_changetrustpw},
-#endif
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_ads_usage);
-}
-
-int net_ads(int argc, const char **argv)
-{
- struct functable func[] = {
- {"INFO", net_ads_info},
- {"JOIN", net_ads_join},
- {"TESTJOIN", net_ads_testjoin},
- {"LEAVE", net_ads_leave},
- {"STATUS", net_ads_status},
- {"USER", net_ads_user},
- {"GROUP", net_ads_group},
- {"PASSWORD", net_ads_password},
- {"CHANGETRUSTPW", net_ads_changetrustpw},
- {"PRINTER", net_ads_printer},
- {"SEARCH", net_ads_search},
- {"DN", net_ads_dn},
- {"WORKGROUP", net_ads_workgroup},
- {"LOOKUP", net_ads_lookup},
- {"HELP", net_ads_help},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_ads_usage);
-}
-
-#else
-
-static int net_ads_noads(void)
-{
- d_printf("ADS support not compiled in\n");
- return -1;
-}
-
-int net_ads_usage(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-int net_ads_help(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-int net_ads_changetrustpw(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-int net_ads_join(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-int net_ads_user(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-int net_ads_group(int argc, const char **argv)
-{
- return net_ads_noads();
-}
-
-/* this one shouldn't display a message */
-int net_ads_check(void)
-{
- return -1;
-}
-
-int net_ads(int argc, const char **argv)
-{
- return net_ads_usage(argc, argv);
-}
-
-#endif
diff --git a/source/utils/net_ads_cldap.c b/source/utils/net_ads_cldap.c
deleted file mode 100644
index 1903172cf75..00000000000
--- a/source/utils/net_ads_cldap.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net ads cldap functions
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
- Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "../utils/net.h"
-
-#ifdef HAVE_ADS
-
-#define MAX_DNS_LABEL 255 + 1
-
-struct cldap_netlogon_reply {
- uint32 type;
- uint32 flags;
- UUID_FLAT guid;
-
- char forest[MAX_DNS_LABEL];
- char domain[MAX_DNS_LABEL];
- char hostname[MAX_DNS_LABEL];
-
- char netbios_domain[MAX_DNS_LABEL];
- char netbios_hostname[MAX_DNS_LABEL];
-
- char unk[MAX_DNS_LABEL];
- char user_name[MAX_DNS_LABEL];
- char site_name[MAX_DNS_LABEL];
- char site_name_2[MAX_DNS_LABEL];
-
- uint32 version;
- uint16 lmnt_token;
- uint16 lm20_token;
-};
-
-/*
- These seem to be strings as described in RFC1035 4.1.4 and can be:
-
- - a sequence of labels ending in a zero octet
- - a pointer
- - a sequence of labels ending with a pointer
-
- A label is a byte where the first two bits must be zero and the remaining
- bits represent the length of the label followed by the label itself.
- Therefore, the length of a label is at max 64 bytes. Under RFC1035, a
- sequence of labels cannot exceed 255 bytes.
-
- A pointer consists of a 14 bit offset from the beginning of the data.
-
- struct ptr {
- unsigned ident:2; // must be 11
- unsigned offset:14; // from the beginning of data
- };
-
- This is used as a method to compress the packet by eliminated duplicate
- domain components. Since a UDP packet should probably be < 512 bytes and a
- DNS name can be up to 255 bytes, this actually makes a lot of sense.
-*/
-static unsigned pull_netlogon_string(char *ret, const char *ptr,
- const char *data)
-{
- char *pret = ret;
- int followed_ptr = 0;
- unsigned ret_len = 0;
-
- memset(pret, 0, MAX_DNS_LABEL);
- do {
- if ((*ptr & 0xc0) == 0xc0) {
- uint16 len;
-
- if (!followed_ptr) {
- ret_len += 2;
- followed_ptr = 1;
- }
- len = ((ptr[0] & 0x3f) << 8) | ptr[1];
- ptr = data + len;
- } else if (*ptr) {
- uint8 len = (uint8)*(ptr++);
-
- if ((pret - ret + len + 1) >= MAX_DNS_LABEL) {
- d_printf("DC returning too long DNS name\n");
- return 0;
- }
-
- if (pret != ret) {
- *pret = '.';
- pret++;
- }
- memcpy(pret, ptr, len);
- pret += len;
- ptr += len;
-
- if (!followed_ptr) {
- ret_len += (len + 1);
- }
- }
- } while (*ptr);
-
- return followed_ptr ? ret_len : ret_len + 1;
-}
-
-/*
- do a cldap netlogon query
-*/
-static int send_cldap_netlogon(int sock, const char *domain,
- const char *hostname, unsigned ntversion)
-{
- ASN1_DATA data;
- char ntver[4];
-#ifdef CLDAP_USER_QUERY
- char aac[4];
-
- SIVAL(aac, 0, 0x00000180);
-#endif
- SIVAL(ntver, 0, ntversion);
-
- memset(&data, 0, sizeof(data));
-
- asn1_push_tag(&data,ASN1_SEQUENCE(0));
- asn1_write_Integer(&data, 4);
- asn1_push_tag(&data, ASN1_APPLICATION(3));
- asn1_write_OctetString(&data, NULL, 0);
- asn1_write_enumerated(&data, 0);
- asn1_write_enumerated(&data, 0);
- asn1_write_Integer(&data, 0);
- asn1_write_Integer(&data, 0);
- asn1_write_BOOLEAN2(&data, False);
- asn1_push_tag(&data, ASN1_CONTEXT(0));
-
- asn1_push_tag(&data, ASN1_CONTEXT(3));
- asn1_write_OctetString(&data, "DnsDomain", 9);
- asn1_write_OctetString(&data, domain, strlen(domain));
- asn1_pop_tag(&data);
-
- asn1_push_tag(&data, ASN1_CONTEXT(3));
- asn1_write_OctetString(&data, "Host", 4);
- asn1_write_OctetString(&data, hostname, strlen(hostname));
- asn1_pop_tag(&data);
-
-#ifdef CLDAP_USER_QUERY
- asn1_push_tag(&data, ASN1_CONTEXT(3));
- asn1_write_OctetString(&data, "User", 4);
- asn1_write_OctetString(&data, "SAMBA$", 6);
- asn1_pop_tag(&data);
-
- asn1_push_tag(&data, ASN1_CONTEXT(3));
- asn1_write_OctetString(&data, "AAC", 4);
- asn1_write_OctetString(&data, aac, 4);
- asn1_pop_tag(&data);
-#endif
-
- asn1_push_tag(&data, ASN1_CONTEXT(3));
- asn1_write_OctetString(&data, "NtVer", 5);
- asn1_write_OctetString(&data, ntver, 4);
- asn1_pop_tag(&data);
-
- asn1_pop_tag(&data);
-
- asn1_push_tag(&data,ASN1_SEQUENCE(0));
- asn1_write_OctetString(&data, "NetLogon", 8);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
-
- if (data.has_error) {
- d_printf("Failed to build cldap netlogon at offset %d\n", (int)data.ofs);
- asn1_free(&data);
- return -1;
- }
-
- if (write(sock, data.data, data.length) != (ssize_t)data.length) {
- d_printf("failed to send cldap query (%s)\n", strerror(errno));
- }
-
- asn1_free(&data);
-
- return 0;
-}
-
-
-/*
- receive a cldap netlogon reply
-*/
-static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
-{
- int ret;
- ASN1_DATA data;
- DATA_BLOB blob;
- DATA_BLOB os1, os2, os3;
- uint32 i1;
- char *p;
-
- blob = data_blob(NULL, 8192);
-
- ret = read(sock, blob.data, blob.length);
-
- if (ret <= 0) {
- d_printf("no reply received to cldap netlogon\n");
- return -1;
- }
- blob.length = ret;
-
- asn1_load(&data, blob);
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_read_Integer(&data, &i1);
- asn1_start_tag(&data, ASN1_APPLICATION(4));
- asn1_read_OctetString(&data, &os1);
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_read_OctetString(&data, &os2);
- asn1_start_tag(&data, ASN1_SET);
- asn1_read_OctetString(&data, &os3);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
-
- if (data.has_error) {
- d_printf("Failed to parse cldap reply\n");
- return -1;
- }
-
- p = (char *)os3.data;
-
- reply->type = IVAL(p, 0); p += 4;
- reply->flags = IVAL(p, 0); p += 4;
-
- memcpy(&reply->guid.info, p, UUID_FLAT_SIZE);
- p += UUID_FLAT_SIZE;
-
- p += pull_netlogon_string(reply->forest, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->domain, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->unk, p, (const char *)os3.data);
-
- if (reply->type == SAMLOGON_AD_R) {
- p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data);
- } else {
- *reply->user_name = 0;
- }
-
- p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data);
-
- reply->version = IVAL(p, 0);
- reply->lmnt_token = SVAL(p, 4);
- reply->lm20_token = SVAL(p, 6);
-
- data_blob_free(&os1);
- data_blob_free(&os2);
- data_blob_free(&os3);
- data_blob_free(&blob);
-
- return 0;
-}
-
-/*
- do a cldap netlogon query
-*/
-int ads_cldap_netlogon(ADS_STRUCT *ads)
-{
- int sock;
- int ret;
- struct cldap_netlogon_reply reply;
-
- sock = open_udp_socket(inet_ntoa(ads->ldap_ip), ads->ldap_port);
- if (sock == -1) {
- d_printf("Failed to open udp socket to %s:%u\n",
- inet_ntoa(ads->ldap_ip),
- ads->ldap_port);
- return -1;
-
- }
-
- ret = send_cldap_netlogon(sock, ads->config.realm, global_myname(), 6);
- if (ret != 0) {
- return ret;
- }
- ret = recv_cldap_netlogon(sock, &reply);
- close(sock);
-
- if (ret == -1) {
- return -1;
- }
-
- d_printf("Information for Domain Controller: %s\n\n",
- ads->config.ldap_server_name);
-
- d_printf("Response Type: ");
- switch (reply.type) {
- case SAMLOGON_AD_UNK_R:
- d_printf("SAMLOGON\n");
- break;
- case SAMLOGON_AD_R:
- d_printf("SAMLOGON_USER\n");
- break;
- default:
- d_printf("0x%x\n", reply.type);
- break;
- }
- d_printf("GUID: %s\n",
- smb_uuid_string_static(smb_uuid_unpack_static(reply.guid)));
- d_printf("Flags:\n"
- "\tIs a PDC: %s\n"
- "\tIs a GC of the forest: %s\n"
- "\tIs an LDAP server: %s\n"
- "\tSupports DS: %s\n"
- "\tIs running a KDC: %s\n"
- "\tIs running time services: %s\n"
- "\tIs the closest DC: %s\n"
- "\tIs writable: %s\n"
- "\tHas a hardware clock: %s\n"
- "\tIs a non-domain NC serviced by LDAP server: %s\n",
- (reply.flags & ADS_PDC) ? "yes" : "no",
- (reply.flags & ADS_GC) ? "yes" : "no",
- (reply.flags & ADS_LDAP) ? "yes" : "no",
- (reply.flags & ADS_DS) ? "yes" : "no",
- (reply.flags & ADS_KDC) ? "yes" : "no",
- (reply.flags & ADS_TIMESERV) ? "yes" : "no",
- (reply.flags & ADS_CLOSEST) ? "yes" : "no",
- (reply.flags & ADS_WRITABLE) ? "yes" : "no",
- (reply.flags & ADS_GOOD_TIMESERV) ? "yes" : "no",
- (reply.flags & ADS_NDNC) ? "yes" : "no");
-
- printf("Forest:\t\t\t%s\n", reply.forest);
- printf("Domain:\t\t\t%s\n", reply.domain);
- printf("Domain Controller:\t%s\n", reply.hostname);
-
- printf("Pre-Win2k Domain:\t%s\n", reply.netbios_domain);
- printf("Pre-Win2k Hostname:\t%s\n", reply.netbios_hostname);
-
- if (*reply.unk) printf("Unk:\t\t\t%s\n", reply.unk);
- if (*reply.user_name) printf("User name:\t%s\n", reply.user_name);
-
- printf("Site Name:\t\t%s\n", reply.site_name);
- printf("Site Name (2):\t\t%s\n", reply.site_name_2);
-
- d_printf("NT Version: %d\n", reply.version);
- d_printf("LMNT Token: %.2x\n", reply.lmnt_token);
- d_printf("LM20 Token: %.2x\n", reply.lm20_token);
-
- return ret;
-}
-
-
-#endif
diff --git a/source/utils/net_cache.c b/source/utils/net_cache.c
deleted file mode 100644
index a9559164587..00000000000
--- a/source/utils/net_cache.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) Rafal Szczesniak 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-#include "includes.h"
-#include "net.h"
-
-/**
- * @file net_cache.c
- * @brief This is part of the net tool which is basically command
- * line wrapper for gencache.c functions (mainly for testing)
- *
- **/
-
-
-/*
- * These routines are used via gencache_iterate() to display the cache's contents
- * (print_cache_entry) and to flush it (delete_cache_entry).
- * Both of them are defined by first arg of gencache_iterate() routine.
- */
-static void print_cache_entry(const char* keystr, const char* datastr,
- const time_t timeout, void* dptr)
-{
- char* timeout_str;
- time_t now_t = time(NULL);
- struct tm timeout_tm, *now_tm;
- /* localtime returns statically allocated pointer, so timeout_tm
- has to be copied somewhere else */
- memcpy(&timeout_tm, localtime(&timeout), sizeof(struct tm));
- now_tm = localtime(&now_t);
-
- /* form up timeout string depending whether it's today's date or not */
- if (timeout_tm.tm_year != now_tm->tm_year ||
- timeout_tm.tm_mon != now_tm->tm_mon ||
- timeout_tm.tm_mday != now_tm->tm_mday) {
-
- timeout_str = asctime(&timeout_tm);
- timeout_str[strlen(timeout_str) - 1] = '\0'; /* remove tailing CR */
- } else
- asprintf(&timeout_str, "%.2d:%.2d:%.2d", timeout_tm.tm_hour,
- timeout_tm.tm_min, timeout_tm.tm_sec);
-
- d_printf("Key: %s\t Timeout: %s\t Value: %s %s\n", keystr,
- timeout_str, datastr, timeout > now_t ? "": "(expired)");
-}
-
-static void delete_cache_entry(const char* keystr, const char* datastr,
- const time_t timeout, void* dptr)
-{
- if (!gencache_del(keystr))
- d_printf("Couldn't delete entry! key = %s\n", keystr);
-}
-
-
-/**
- * Parse text representation of timeout value
- *
- * @param timeout_str string containing text representation of the timeout
- * @return numeric timeout of time_t type
- **/
-static time_t parse_timeout(const char* timeout_str)
-{
- char sign = '\0', *number = NULL, unit = '\0';
- int len, number_begin, number_end;
- time_t timeout;
-
- /* sign detection */
- if (timeout_str[0] == '!' || timeout_str[0] == '+') {
- sign = timeout_str[0];
- number_begin = 1;
- } else {
- number_begin = 0;
- }
-
- /* unit detection */
- len = strlen(timeout_str);
- switch (timeout_str[len - 1]) {
- case 's':
- case 'm':
- case 'h':
- case 'd':
- case 'w': unit = timeout_str[len - 1];
- }
-
- /* number detection */
- len = (sign) ? strlen(&timeout_str[number_begin]) : len;
- number_end = (unit) ? len - 1 : len;
- number = strndup(&timeout_str[number_begin], number_end);
-
- /* calculate actual timeout value */
- timeout = (time_t)atoi(number);
-
- switch (unit) {
- case 'm': timeout *= 60; break;
- case 'h': timeout *= 60*60; break;
- case 'd': timeout *= 60*60*24; break;
- case 'w': timeout *= 60*60*24*7; break; /* that's fair enough, I think :) */
- }
-
- switch (sign) {
- case '!': timeout = time(NULL) - timeout; break;
- case '+':
- default: timeout += time(NULL); break;
- }
-
- if (number) SAFE_FREE(number);
- return timeout;
-}
-
-
-/**
- * Add an entry to the cache. If it does exist, then set it.
- *
- * @param argv key, value and timeout are passed in command line
- * @return 0 on success, otherwise failure
- **/
-static int net_cache_add(int argc, const char **argv)
-{
- const char *keystr, *datastr, *timeout_str;
- time_t timeout;
-
- if (argc < 3) {
- d_printf("\nUsage: net cache add <key string> <data string> <timeout>\n");
- return -1;
- }
-
- keystr = argv[0];
- datastr = argv[1];
- timeout_str = argv[2];
-
- /* parse timeout given in command line */
- timeout = parse_timeout(timeout_str);
- if (!timeout) {
- d_printf("Invalid timeout argument.\n");
- return -1;
- }
-
- if (gencache_set(keystr, datastr, timeout)) {
- d_printf("New cache entry stored successfully.\n");
- gencache_shutdown();
- return 0;
- }
-
- d_printf("Entry couldn't be added. Perhaps there's already such a key.\n");
- gencache_shutdown();
- return -1;
-}
-
-
-/**
- * Set new value of an existing entry in the cache. Fail If the entry doesn't
- * exist.
- *
- * @param argv key being searched and new value and timeout to set in the entry
- * @return 0 on success, otherwise failure
- **/
-static int net_cache_set(int argc, const char **argv)
-{
- const char *keystr, *datastr, *timeout_str;
- time_t timeout;
-
- if (argc < 3) {
- d_printf("\nUsage: net cache set <key string> <data string> <timeout>\n");
- return -1;
- }
-
- keystr = argv[0];
- datastr = argv[1];
- timeout_str = argv[2];
-
- /* parse timeout given in command line */
- timeout = parse_timeout(timeout_str);
- if (!timeout) {
- d_printf("Invalid timeout argument.\n");
- return -1;
- }
-
- if (gencache_set_only(keystr, datastr, timeout)) {
- d_printf("Cache entry set successfully.\n");
- gencache_shutdown();
- return 0;
- }
-
- d_printf("Entry couldn't be set. Perhaps there's no such a key.\n");
- gencache_shutdown();
- return -1;
-}
-
-
-/**
- * Delete an entry in the cache
- *
- * @param argv key to delete an entry of
- * @return 0 on success, otherwise failure
- **/
-static int net_cache_del(int argc, const char **argv)
-{
- const char *keystr = argv[0];
-
- if (argc < 1) {
- d_printf("\nUsage: net cache del <key string>\n");
- return -1;
- }
-
- if(gencache_del(keystr)) {
- d_printf("Entry deleted.\n");
- return 0;
- }
-
- d_printf("Couldn't delete specified entry\n");
- return -1;
-}
-
-
-/**
- * Get and display an entry from the cache
- *
- * @param argv key to search an entry of
- * @return 0 on success, otherwise failure
- **/
-static int net_cache_get(int argc, const char **argv)
-{
- const char* keystr = argv[0];
- char* valuestr;
- time_t timeout;
-
- if (argc < 1) {
- d_printf("\nUsage: net cache get <key>\n");
- return -1;
- }
-
- if (gencache_get(keystr, &valuestr, &timeout)) {
- print_cache_entry(keystr, valuestr, timeout, NULL);
- return 0;
- }
-
- d_printf("Failed to find entry\n");
- return -1;
-}
-
-
-/**
- * Search an entry/entries in the cache
- *
- * @param argv key pattern to match the entries to
- * @return 0 on success, otherwise failure
- **/
-static int net_cache_search(int argc, const char **argv)
-{
- const char* pattern;
-
- if (argc < 1) {
- d_printf("Usage: net cache search <pattern>\n");
- return -1;
- }
-
- pattern = argv[0];
- gencache_iterate(print_cache_entry, NULL, pattern);
- return 0;
-}
-
-
-/**
- * List the contents of the cache
- *
- * @param argv ignored in this functionailty
- * @return always returns 0
- **/
-static int net_cache_list(int argc, const char **argv)
-{
- const char* pattern = "*";
- gencache_iterate(print_cache_entry, NULL, pattern);
- gencache_shutdown();
- return 0;
-}
-
-
-/**
- * Flush the whole cache
- *
- * @param argv ignored in this functionality
- * @return always returns 0
- **/
-static int net_cache_flush(int argc, const char **argv)
-{
- const char* pattern = "*";
- gencache_iterate(delete_cache_entry, NULL, pattern);
- gencache_shutdown();
- return 0;
-}
-
-
-/**
- * Short help
- *
- * @param argv ignored in this functionality
- * @return always returns -1
- **/
-static int net_cache_usage(int argc, const char **argv)
-{
- d_printf(" net cache add \t add add new cache entry\n");
- d_printf(" net cache set \t set new value for existing cache entry\n");
- d_printf(" net cache del \t delete existing cache entry by key\n");
- d_printf(" net cache flush \t delete all entries existing in the cache\n");
- d_printf(" net cache get \t get cache entry by key\n");
- d_printf(" net cache search \t search for entries in the cache, by given pattern\n");
- d_printf(" net cache list \t list all cache entries (just like search for \"*\")\n");
- return -1;
-}
-
-
-/**
- * Entry point to 'net cache' subfunctionality
- *
- * @param argv arguments passed to further called functions
- * @return whatever further functions return
- **/
-int net_cache(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", net_cache_add},
- {"set", net_cache_set},
- {"del", net_cache_del},
- {"get", net_cache_get},
- {"search", net_cache_search},
- {"list", net_cache_list},
- {"flush", net_cache_flush},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_cache_usage);
-}
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
deleted file mode 100644
index 78e763e1818..00000000000
--- a/source/utils/net_groupmap.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2001.
- * Copyright (C) Gerald Carter 2003.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-#include "../utils/net.h"
-
-
-/*********************************************************
- utility function to parse an integer parameter from
- "parameter = value"
-**********************************************************/
-static uint32 get_int_param( const char* param )
-{
- char *p;
-
- p = strchr( param, '=' );
- if ( !p )
- return 0;
-
- return atoi(p+1);
-}
-
-/*********************************************************
- utility function to parse an integer parameter from
- "parameter = value"
-**********************************************************/
-static char* get_string_param( const char* param )
-{
- char *p;
-
- p = strchr( param, '=' );
- if ( !p )
- return NULL;
-
- return (p+1);
-}
-
-/*********************************************************
- Figure out if the input was an NT group or a SID string.
- Return the SID.
-**********************************************************/
-static BOOL get_sid_from_input(DOM_SID *sid, char *input)
-{
- GROUP_MAP map;
-
- if (StrnCaseCmp( input, "S-", 2)) {
- /* Perhaps its the NT group name? */
- if (!pdb_getgrnam(&map, input)) {
- printf("NT Group %s doesn't exist in mapping DB\n", input);
- return False;
- } else {
- *sid = map.sid;
- }
- } else {
- if (!string_to_sid(sid, input)) {
- printf("converting sid %s from a string failed!\n", input);
- return False;
- }
- }
- return True;
-}
-
-/*********************************************************
- Dump a GROUP_MAP entry to stdout (long or short listing)
-**********************************************************/
-
-static void print_map_entry ( GROUP_MAP map, BOOL long_list )
-{
- fstring string_sid;
- fstring group_type;
-
- decode_sid_name_use(group_type, map.sid_name_use);
- sid_to_string(string_sid, &map.sid);
-
- if (!long_list)
- d_printf("%s (%s) -> %s\n", map.nt_name, string_sid, gidtoname(map.gid));
- else {
- d_printf("%s\n", map.nt_name);
- d_printf("\tSID : %s\n", string_sid);
- d_printf("\tUnix group: %s\n", gidtoname(map.gid));
- d_printf("\tGroup type: %s\n", group_type);
- d_printf("\tComment : %s\n", map.comment);
- }
-
-}
-/*********************************************************
- List the groups.
-**********************************************************/
-static int net_groupmap_list(int argc, const char **argv)
-{
- int entries;
- BOOL long_list = False;
- int i;
- fstring ntgroup = "";
- fstring sid_string = "";
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if ( !StrCaseCmp(argv[i], "verbose")) {
- long_list = True;
- }
- else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
- fstrcpy( ntgroup, get_string_param( argv[i] ) );
- if ( !ntgroup[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
- fstrcpy( sid_string, get_string_param( argv[i] ) );
- if ( !sid_string[0] ) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- /* list a single group is given a name */
- if ( ntgroup[0] || sid_string[0] ) {
- DOM_SID sid;
- GROUP_MAP map;
-
- if ( sid_string[0] )
- fstrcpy( ntgroup, sid_string);
-
- if (!get_sid_from_input(&sid, ntgroup)) {
- return -1;
- }
-
- /* Get the current mapping from the database */
- if(!pdb_getgrsid(&map, sid)) {
- d_printf("Failure to local group SID in the database\n");
- return -1;
- }
-
- print_map_entry( map, long_list );
- }
- else {
- GROUP_MAP *map=NULL;
- /* enumerate all group mappings */
- if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries, ENUM_ALL_MAPPED))
- return -1;
-
- for (i=0; i<entries; i++) {
- print_map_entry( map[i], long_list );
- }
-
- SAFE_FREE(map);
- }
-
- return 0;
-}
-
-/*********************************************************
- Add a new group mapping entry
-**********************************************************/
-
-static int net_groupmap_add(int argc, const char **argv)
-{
- DOM_SID sid;
- fstring ntgroup = "";
- fstring unixgrp = "";
- fstring string_sid = "";
- fstring type = "";
- fstring ntcomment = "";
- enum SID_NAME_USE sid_type = SID_NAME_DOM_GRP;
- uint32 rid = 0;
- gid_t gid;
- int i;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if ( !StrnCaseCmp(argv[i], "rid", strlen("rid")) ) {
- rid = get_int_param(argv[i]);
- if ( rid < DOMAIN_GROUP_RID_ADMINS ) {
- d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) {
- fstrcpy( unixgrp, get_string_param( argv[i] ) );
- if ( !unixgrp[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
- fstrcpy( ntgroup, get_string_param( argv[i] ) );
- if ( !ntgroup[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
- fstrcpy( string_sid, get_string_param( argv[i] ) );
- if ( !string_sid[0] ) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) {
- fstrcpy( ntcomment, get_string_param( argv[i] ) );
- if ( !ntcomment[0] ) {
- d_printf("must supply a comment string\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "type", strlen("type")) ) {
- fstrcpy( type, get_string_param( argv[i] ) );
- switch ( type[0] ) {
- case 'b':
- case 'B':
- sid_type = SID_NAME_WKN_GRP;
- break;
- case 'd':
- case 'D':
- sid_type = SID_NAME_DOM_GRP;
- break;
- case 'l':
- case 'L':
- sid_type = SID_NAME_ALIAS;
- break;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if ( !unixgrp[0] ) {
- d_printf("Usage: net groupmap add {rid=<int>|sid=<string>} unixgroup=<string> [type=<domain|local|builtin>] [ntgroup=<string>] [comment=<string>]\n");
- return -1;
- }
-
- if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
- d_printf("Can't lookup UNIX group %s\n", unixgrp);
- return -1;
- }
-
- if ( (rid == 0) && (string_sid[0] == '\0') ) {
- d_printf("No rid or sid specified, choosing algorithmic mapping\n");
- rid = pdb_gid_to_group_rid(gid);
- }
-
- /* append the rid to our own domain/machine SID if we don't have a full SID */
- if ( !string_sid[0] ) {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- sid_to_string(string_sid, &sid);
- }
-
- if (!ntcomment[0])
- fstrcpy(ntcomment, "Local Unix group");
-
- if (!ntgroup[0] )
- fstrcpy( ntgroup, unixgrp );
-
-
- if (!add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment)) {
- d_printf("adding entry for group %s failed!\n", ntgroup);
- return -1;
- }
-
- d_printf("Successully added group %s to the mapping db\n", ntgroup);
- return 0;
-}
-
-static int net_groupmap_modify(int argc, const char **argv)
-{
- DOM_SID sid;
- GROUP_MAP map;
- fstring ntcomment = "";
- fstring type = "";
- fstring ntgroup = "";
- fstring unixgrp = "";
- fstring sid_string = "";
- enum SID_NAME_USE sid_type = SID_NAME_UNKNOWN;
- int i;
- gid_t gid;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
- fstrcpy( ntgroup, get_string_param( argv[i] ) );
- if ( !ntgroup[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
- fstrcpy( sid_string, get_string_param( argv[i] ) );
- if ( !sid_string[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) {
- fstrcpy( ntcomment, get_string_param( argv[i] ) );
- if ( !ntcomment[0] ) {
- d_printf("must supply a comment string\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) {
- fstrcpy( unixgrp, get_string_param( argv[i] ) );
- if ( !unixgrp[0] ) {
- d_printf("must supply a group name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "type", strlen("type")) ) {
- fstrcpy( type, get_string_param( argv[i] ) );
- switch ( type[0] ) {
- case 'd':
- case 'D':
- sid_type = SID_NAME_DOM_GRP;
- break;
- case 'l':
- case 'L':
- sid_type = SID_NAME_ALIAS;
- break;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if ( !ntgroup[0] && !sid_string[0] ) {
- d_printf("Usage: net groupmap modify {ntgroup=<string>|sid=<SID>} [comment=<string>] [unixgroup=<string>] [type=<domain|local>]\n");
- return -1;
- }
-
- /* give preference to the SID; if both the ntgroup name and SID
- are defined, use the SID and assume that the group name could be a
- new name */
-
- if ( sid_string[0] ) {
- if (!get_sid_from_input(&sid, sid_string)) {
- return -1;
- }
- }
- else {
- if (!get_sid_from_input(&sid, ntgroup)) {
- return -1;
- }
- }
-
- /* Get the current mapping from the database */
- if(!pdb_getgrsid(&map, sid)) {
- d_printf("Failure to local group SID in the database\n");
- return -1;
- }
-
- /*
- * Allow changing of group type only between domain and local
- * We disallow changing Builtin groups !!! (SID problem)
- */
- if (sid_type != SID_NAME_UNKNOWN) {
- if (map.sid_name_use == SID_NAME_WKN_GRP) {
- d_printf("You can only change between domain and local groups.\n");
- return -1;
- }
-
- map.sid_name_use=sid_type;
- }
-
- /* Change comment if new one */
- if ( ntcomment[0] )
- fstrcpy( map.comment, ntcomment );
-
- if ( ntgroup[0] )
- fstrcpy( map.nt_name, ntgroup );
-
- if ( unixgrp[0] ) {
- gid = nametogid( unixgrp );
- if ( gid == -1 ) {
- d_printf("Unable to lookup UNIX group %s. Make sure the group exists.\n",
- unixgrp);
- return -1;
- }
-
- map.gid = gid;
- }
-
- if ( !pdb_update_group_mapping_entry(&map) ) {
- d_printf("Could not update group database\n");
- return -1;
- }
-
- d_printf("Updated mapping entry for %s\n", map.nt_name);
-
- return 0;
-}
-
-static int net_groupmap_delete(int argc, const char **argv)
-{
- DOM_SID sid;
- fstring ntgroup = "";
- fstring sid_string = "";
- int i;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
- fstrcpy( ntgroup, get_string_param( argv[i] ) );
- if ( !ntgroup[0] ) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
- fstrcpy( sid_string, get_string_param( argv[i] ) );
- if ( !sid_string[0] ) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if ( !ntgroup[0] && !sid_string[0]) {
- d_printf("Usage: net groupmap delete {ntgroup=<string>|sid=<SID>}\n");
- return -1;
- }
-
- /* give preference to the SID if we have that */
-
- if ( sid_string[0] )
- fstrcpy( ntgroup, sid_string );
-
- if ( !get_sid_from_input(&sid, ntgroup) ) {
- d_printf("Unable to resolve group %s to a SID\n", ntgroup);
- return -1;
- }
-
- if ( !pdb_delete_group_mapping_entry(sid) ) {
- printf("Failed to removing group %s from the mapping db!\n", ntgroup);
- return -1;
- }
-
- d_printf("Sucessfully removed %s from the mapping db\n", ntgroup);
-
- return 0;
-}
-
-static int net_groupmap_set(int argc, const char **argv)
-{
- const char *ntgroup = NULL;
- struct group *grp = NULL;
- GROUP_MAP map;
- BOOL have_map = False;
-
- if ((argc < 1) || (argc > 2)) {
- d_printf("Usage: net groupmap set \"NT Group\" "
- "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n");
- return -1;
- }
-
- if ( opt_localgroup && opt_domaingroup ) {
- d_printf("Can only specify -L or -D, not both\n");
- return -1;
- }
-
- ntgroup = argv[0];
-
- if (argc == 2) {
- grp = getgrnam(argv[1]);
-
- if (grp == NULL) {
- d_printf("Could not find unix group %s\n", argv[1]);
- return -1;
- }
- }
-
- have_map = pdb_getgrnam(&map, ntgroup);
-
- if (!have_map) {
- DOM_SID sid;
- have_map = ( (strncmp(ntgroup, "S-", 2) == 0) &&
- string_to_sid(&sid, ntgroup) &&
- pdb_getgrsid(&map, sid) );
- }
-
- if (!have_map) {
-
- /* Ok, add it */
-
- if (grp == NULL) {
- d_printf("Could not find group mapping for %s\n",
- ntgroup);
- return -1;
- }
-
- map.gid = grp->gr_gid;
-
- if (opt_rid == 0) {
- opt_rid = pdb_gid_to_group_rid(map.gid);
- }
-
- sid_copy(&map.sid, get_global_sam_sid());
- sid_append_rid(&map.sid, opt_rid);
-
- map.sid_name_use = SID_NAME_DOM_GRP;
- fstrcpy(map.nt_name, ntgroup);
- fstrcpy(map.comment, "");
-
- if (!pdb_add_group_mapping_entry(&map)) {
- d_printf("Could not add mapping entry for %s\n",
- ntgroup);
- return -1;
- }
- }
-
- /* Now we have a mapping entry, update that stuff */
-
- if ( opt_localgroup || opt_domaingroup ) {
- if (map.sid_name_use == SID_NAME_WKN_GRP) {
- d_printf("Can't change type of the BUILTIN group %s\n",
- map.nt_name);
- return -1;
- }
- }
-
- if (opt_localgroup)
- map.sid_name_use = SID_NAME_ALIAS;
-
- if (opt_domaingroup)
- map.sid_name_use = SID_NAME_DOM_GRP;
-
- /* The case (opt_domaingroup && opt_localgroup) was tested for above */
-
- if (strlen(opt_comment) > 0)
- fstrcpy(map.comment, opt_comment);
-
- if (strlen(opt_newntname) > 0)
- fstrcpy(map.nt_name, opt_newntname);
-
- if (grp != NULL)
- map.gid = grp->gr_gid;
-
- if (!pdb_update_group_mapping_entry(&map)) {
- d_printf("Could not update group mapping for %s\n", ntgroup);
- return -1;
- }
-
- return 0;
-}
-
-static int net_groupmap_cleanup(int argc, const char **argv)
-{
- GROUP_MAP *map = NULL;
- int i, entries;
-
- if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries,
- ENUM_ALL_MAPPED)) {
- d_printf("Could not list group mappings\n");
- return -1;
- }
-
- for (i=0; i<entries; i++) {
-
- if (map[i].sid_name_use == SID_NAME_WKN_GRP)
- continue;
-
- if (map[i].gid == -1)
- printf("Group %s is not mapped\n", map[i].nt_name);
-
- if (!sid_check_is_in_our_domain(&map[i].sid)) {
- printf("Deleting mapping for NT Group %s, sid %s\n",
- map[i].nt_name,
- sid_string_static(&map[i].sid));
- pdb_delete_group_mapping_entry(map[i].sid);
- }
- }
-
- SAFE_FREE(map);
-
- return 0;
-}
-
-static int net_groupmap_addmem(int argc, const char **argv)
-{
- DOM_SID alias, member;
-
- if ( (argc != 2) ||
- !string_to_sid(&alias, argv[0]) ||
- !string_to_sid(&member, argv[1]) ) {
- d_printf("Usage: net groupmap addmem alias-sid member-sid\n");
- return -1;
- }
-
- if (!pdb_add_aliasmem(&alias, &member)) {
- d_printf("Could not add sid %s to alias %s\n",
- argv[1], argv[0]);
- return -1;
- }
-
- return 0;
-}
-
-static int net_groupmap_delmem(int argc, const char **argv)
-{
- DOM_SID alias, member;
-
- if ( (argc != 2) ||
- !string_to_sid(&alias, argv[0]) ||
- !string_to_sid(&member, argv[1]) ) {
- d_printf("Usage: net groupmap delmem alias-sid member-sid\n");
- return -1;
- }
-
- if (!pdb_del_aliasmem(&alias, &member)) {
- d_printf("Could not delete sid %s from alias %s\n",
- argv[1], argv[0]);
- return -1;
- }
-
- return 0;
-}
-
-static int net_groupmap_listmem(int argc, const char **argv)
-{
- DOM_SID alias;
- DOM_SID *members;
- int i, num;
- NTSTATUS result;
-
- if ( (argc != 1) ||
- !string_to_sid(&alias, argv[0]) ) {
- d_printf("Usage: net groupmap listmem alias-sid\n");
- return -1;
- }
-
- if (!pdb_enum_aliasmem(&alias, &members, &num)) {
- d_printf("Could not list members for sid %s: %s\n",
- argv[0], nt_errstr(result));
- return -1;
- }
-
- for (i = 0; i < num; i++) {
- printf("%s\n", sid_string_static(&(members[i])));
- }
-
- SAFE_FREE(members);
-
- return 0;
-}
-
-static int net_groupmap_memberships(int argc, const char **argv)
-{
- DOM_SID member;
- DOM_SID *aliases;
- int i, num;
- NTSTATUS result;
-
- if ( (argc != 1) ||
- !string_to_sid(&member, argv[0]) ) {
- d_printf("Usage: net groupmap memberof sid\n");
- return -1;
- }
-
- if (!pdb_enum_alias_memberships(&member, &aliases, &num)) {
- d_printf("Could not list memberships for sid %s: %s\n",
- argv[0], nt_errstr(result));
- return -1;
- }
-
- for (i = 0; i < num; i++) {
- printf("%s\n", sid_string_static(&(aliases[i])));
- }
-
- SAFE_FREE(aliases);
-
- return 0;
-}
-
-int net_help_groupmap(int argc, const char **argv)
-{
- d_printf("net groupmap add"\
- "\n Create a new group mapping\n");
- d_printf("net groupmap modify"\
- "\n Update a group mapping\n");
- d_printf("net groupmap delete"\
- "\n Remove a group mapping\n");
- d_printf("net groupmap addmember"\
- "\n Add a foreign alias member\n");
- d_printf("net groupmap delmember"\
- "\n Delete a foreign alias member\n");
- d_printf("net groupmap listmembers"\
- "\n List foreign group members\n");
- d_printf("net groupmap memberships"\
- "\n List foreign group memberships\n");
- d_printf("net groupmap list"\
- "\n List current group map\n");
- d_printf("net groupmap set"\
- "\n Set group mapping\n");
- d_printf("net groupmap cleanup"\
- "\n Remove foreign group mapping entries\n");
-
- return -1;
-}
-
-
-/***********************************************************
- migrated functionality from smbgroupedit
- **********************************************************/
-int net_groupmap(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", net_groupmap_add},
- {"modify", net_groupmap_modify},
- {"delete", net_groupmap_delete},
- {"set", net_groupmap_set},
- {"cleanup", net_groupmap_cleanup},
- {"addmem", net_groupmap_addmem},
- {"delmem", net_groupmap_delmem},
- {"listmem", net_groupmap_listmem},
- {"memberships", net_groupmap_memberships},
- {"list", net_groupmap_list},
- {"help", net_help_groupmap},
- {NULL, NULL}
- };
-
- /* we shouldn't have silly checks like this */
-#if 0
- if (getuid() != 0) {
- d_printf("You must be root to edit group mappings.\nExiting...\n");
- return -1;
- }
-#endif
-
- if ( argc )
- return net_run_function(argc, argv, func, net_help_groupmap);
-
- return net_help_groupmap( argc, argv );
-}
-
diff --git a/source/utils/net_help.c b/source/utils/net_help.c
deleted file mode 100644
index 38261be90a7..00000000000
--- a/source/utils/net_help.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net help commands
- Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "../utils/net.h"
-
-int net_common_methods_usage(int argc, const char**argv)
-{
- d_printf("Valid methods: (auto-detected if not specified)\n");
- d_printf("\tads\t\t\t\tActive Directory (LDAP/Kerberos)\n");
- d_printf("\trpc\t\t\t\tDCE-RPC\n");
- d_printf("\trap\t\t\t\tRAP (older systems)\n");
- d_printf("\n");
- return 0;
-}
-
-int net_common_flags_usage(int argc, const char **argv)
-{
- d_printf("Valid targets: choose one (none defaults to localhost)\n");
- d_printf("\t-S or --server=<server>\t\tserver name\n");
- d_printf("\t-I or --ipaddress=<ipaddr>\taddress of target server\n");
- d_printf("\t-w or --workgroup=<wg>\t\ttarget workgroup or domain\n");
-
- d_printf("\n");
- d_printf("Valid miscellaneous options are:\n"); /* misc options */
- d_printf("\t-p or --port=<port>\t\tconnection port on target\n");
- d_printf("\t-W or --myworkgroup=<wg>\tclient workgroup\n");
- d_printf("\t-d or --debuglevel=<level>\tdebug level (0-10)\n");
- d_printf("\t-n or --myname=<name>\t\tclient name\n");
- d_printf("\t-U or --user=<name>\t\tuser name\n");
- d_printf("\t-s or --configfile=<path>\tpathname of smb.conf file\n");
- d_printf("\t-l or --long\t\t\tDisplay full information\n");
- d_printf("\t-V or --version\t\t\tPrint samba version information\n");
- d_printf("\t-P or --machine-pass\t\tAuthenticate as machine account\n");
- return -1;
-}
-
-static int help_usage(int argc, const char **argv)
-{
- d_printf(
-"\n"\
-"Usage: net help <function>\n"\
-"\n"\
-"Valid functions are:\n"\
-" RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\
-" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP GETLOCALSID SETLOCALSID\n"\
-" CHANGESCRETPW\n");
- return -1;
-}
-
-int net_help_user(int argc, const char **argv)
-{
- d_printf("\nnet [<method>] user [misc. options] [targets]"\
- "\n\tList users\n\n");
- d_printf("net [<method>] user DELETE <name> [misc. options] [targets]"\
- "\n\tDelete specified user\n");
- d_printf("\nnet [<method>] user INFO <name> [misc. options] [targets]"\
- "\n\tList the domain groups of the specified user\n");
- d_printf("\nnet [<method>] user ADD <name> [password] [-c container] "\
- "[-F user flags] [misc. options]"\
- " [targets]\n\tAdd specified user\n");
-
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
- d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
- d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
- return -1;
-}
-
-int net_help_group(int argc, const char **argv)
-{
- d_printf("net [<method>] group [misc. options] [targets]"\
- "\n\tList user groups\n\n");
- d_printf("net rpc group LIST [global|local|builtin]* [misc. options]"\
- "\n\tList specific user groups\n\n");
- d_printf("net [<method>] group DELETE <name> "\
- "[misc. options] [targets]"\
- "\n\tDelete specified group\n");
- d_printf("\nnet [<method>] group ADD <name> [-C comment] [-c container]"\
- " [misc. options] [targets]\n\tCreate specified group\n");
- d_printf("\nnet rpc group MEMBERS <name>\n\tList Group Members\n\n");
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
- d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
- d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
- return -1;
-}
-
-int net_help_join(int argc, const char **argv)
-{
- d_printf("\nnet [<method>] join [misc. options]\n"
- "\tjoins this server to a domain\n");
- d_printf("Valid methods: (auto-detected if not specified)\n");
- d_printf("\tads\t\t\t\tActive Directory (LDAP/Kerberos)\n");
- d_printf("\trpc\t\t\t\tDCE-RPC\n");
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-int net_help_share(int argc, const char **argv)
-{
- d_printf(
- "\nnet [<method>] share [misc. options] [targets] \n"
- "\tenumerates all exported resources (network shares) "
- "on target server\n\n"
- "net [<method>] share ADD <name=serverpath> [misc. options] [targets]"
- "\n\tAdds a share from a server (makes the export active)\n\n"
- "net [<method>] share DELETE <sharename> [misc. options] [targets]\n"
- "\n\tDeletes a share from a server (makes the export inactive)\n");
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
- d_printf(
- "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"
- "\t-M or --maxusers=<num>\t\tmax users allowed for share\n");
- return -1;
-}
-
-int net_help_file(int argc, const char **argv)
-{
- d_printf("net [<method>] file [misc. options] [targets]\n"\
- "\tlists all open files on file server\n\n");
- d_printf("net [<method>] file USER <username> "\
- "[misc. options] [targets]"\
- "\n\tlists all files opened by username on file server\n\n");
- d_printf("net [<method>] file CLOSE <id> [misc. options] [targets]\n"\
- "\tcloses specified file on target server\n\n");
- d_printf("net [rap] file INFO <id> [misc. options] [targets]\n"\
- "\tdisplays information about the specified open file\n");
-
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-int net_help_status(int argc, const char **argv)
-{
- d_printf(" net status sessions [parseable] "
- "Show list of open sessions\n");
- d_printf(" net status shares [parseable] "
- "Show list of open shares\n");
- return -1;
-}
-
-static int net_usage(int argc, const char **argv)
-{
- d_printf(" net time\t\tto view or set time information\n"\
- " net lookup\t\tto lookup host name or ip address\n"\
- " net user\t\tto manage users\n"\
- " net group\t\tto manage groups\n"\
- " net groupmap\t\tto manage group mappings\n"\
- " net join\t\tto join a domain\n"\
- " net cache\t\tto operate on cache tdb file\n"\
- " net getlocalsid [NAME]\tto get the SID for local name\n"\
- " net setlocalsid SID\tto set the local domain SID\n"\
- " net changesecretpw\tto change the machine password in the local secrets database only\n"\
- " \tthis requires the -f flag as a safety barrier\n"\
- " net status\t\tShow server status\n"\
- "\n"\
- " net ads <command>\tto run ADS commands\n"\
- " net rap <command>\tto run RAP (pre-RPC) commands\n"\
- " net rpc <command>\tto run RPC commands\n"\
- "\n"\
- "Type \"net help <option>\" to get more information on that option\n");
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-/*
- handle "net help *" subcommands
-*/
-int net_help(int argc, const char **argv)
-{
- struct functable func[] = {
- {"ADS", net_ads_help},
- {"RAP", net_rap_help},
- {"RPC", net_rpc_help},
-
- {"FILE", net_help_file},
- {"SHARE", net_help_share},
- {"SESSION", net_rap_session_usage},
- {"SERVER", net_rap_server_usage},
- {"DOMAIN", net_rap_domain_usage},
- {"PRINTQ", net_rap_printq_usage},
- {"USER", net_help_user},
- {"GROUP", net_help_group},
- {"GROUPMAP", net_help_groupmap},
- {"JOIN", net_help_join},
- {"VALIDATE", net_rap_validate_usage},
- {"GROUPMEMBER", net_rap_groupmember_usage},
- {"ADMIN", net_rap_admin_usage},
- {"SERVICE", net_rap_service_usage},
- {"PASSWORD", net_rap_password_usage},
- {"TIME", net_time_usage},
- {"LOOKUP", net_lookup_usage},
-#ifdef WITH_FAKE_KASERVER
- {"AFSKEY", net_afskey_usage},
-#endif
-
- {"HELP", help_usage},
- {NULL, NULL}};
-
- return net_run_function(argc, argv, func, net_usage);
-}
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
deleted file mode 100644
index f5b4bf1b4a7..00000000000
--- a/source/utils/net_idmap.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2003 Andrew Bartlett (abartlet@samba.org)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-
-/***********************************************************
- Helper function for net_idmap_dump. Dump one entry.
- **********************************************************/
-static int net_idmap_dump_one_entry(TDB_CONTEXT *tdb,
- TDB_DATA key,
- TDB_DATA data,
- void *unused)
-{
- if (strcmp(key.dptr, "USER HWM") == 0) {
- printf("USER HWM %d\n", IVAL(data.dptr,0));
- return 0;
- }
-
- if (strcmp(key.dptr, "GROUP HWM") == 0) {
- printf("GROUP HWM %d\n", IVAL(data.dptr,0));
- return 0;
- }
-
- if (strncmp(key.dptr, "S-", 2) != 0)
- return 0;
-
- printf("%s %s\n", data.dptr, key.dptr);
- return 0;
-}
-
-/***********************************************************
- Dump the current idmap
- **********************************************************/
-static int net_idmap_dump(int argc, const char **argv)
-{
- TDB_CONTEXT *idmap_tdb;
-
- if ( argc != 1 )
- return net_help_idmap( argc, argv );
-
- idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0);
-
- if (idmap_tdb == NULL) {
- d_printf("Could not open idmap: %s\n", argv[0]);
- return -1;
- }
-
- tdb_traverse(idmap_tdb, net_idmap_dump_one_entry, NULL);
-
- tdb_close(idmap_tdb);
-
- return 0;
-}
-
-/***********************************************************
- Fix up the HWMs after a idmap restore.
- **********************************************************/
-
-struct hwms {
- BOOL ok;
- int user_hwm;
- int group_hwm;
-};
-
-static int net_idmap_find_max_id(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data,
- void *handle)
-{
- struct hwms *hwms = (struct hwms *)handle;
- int *idptr = NULL;
- int id;
-
- if (strncmp(key.dptr, "S-", 2) != 0)
- return 0;
-
- if (sscanf(data.dptr, "GID %d", &id) == 1) {
- idptr = &hwms->group_hwm;
- }
-
- if (sscanf(data.dptr, "UID %d", &id) == 1) {
- idptr = &hwms->user_hwm;
- }
-
- if (idptr == NULL) {
- d_printf("Illegal idmap entry: [%s]->[%s]\n",
- key.dptr, data.dptr);
- hwms->ok = False;
- return -1;
- }
-
- if (*idptr <= id)
- *idptr = id+1;
-
- return 0;
-}
-
-static NTSTATUS net_idmap_fixup_hwm(void)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- TDB_CONTEXT *idmap_tdb;
- char *tdbfile = NULL;
-
- struct hwms hwms;
- struct hwms highest;
-
- if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) ||
- !lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) {
- d_printf("idmap range missing\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
- if (!tdbfile) {
- DEBUG(0, ("idmap_init: out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0);
-
- if (idmap_tdb == NULL) {
- d_printf("Could not open idmap: %s\n", tdbfile);
- return NT_STATUS_NO_SUCH_FILE;
- }
-
- hwms.ok = True;
-
- tdb_traverse(idmap_tdb, net_idmap_find_max_id, &hwms);
-
- if (!hwms.ok) {
- goto done;
- }
-
- d_printf("USER HWM: %d GROUP HWM: %d\n",
- hwms.user_hwm, hwms.group_hwm);
-
- if (hwms.user_hwm >= highest.user_hwm) {
- d_printf("Highest UID out of uid range\n");
- goto done;
- }
-
- if (hwms.group_hwm >= highest.group_hwm) {
- d_printf("Highest GID out of gid range\n");
- goto done;
- }
-
- if ((tdb_store_int32(idmap_tdb, "USER HWM", hwms.user_hwm) != 0) ||
- (tdb_store_int32(idmap_tdb, "GROUP HWM", hwms.group_hwm) != 0)) {
- d_printf("Could not store HWMs\n");
- goto done;
- }
-
- result = NT_STATUS_OK;
- done:
- tdb_close(idmap_tdb);
- return result;
-}
-
-/***********************************************************
- Write entries from stdin to current local idmap
- **********************************************************/
-static int net_idmap_restore(int argc, const char **argv)
-{
- if (!idmap_init(lp_idmap_backend())) {
- d_printf("Could not init idmap\n");
- return -1;
- }
-
- while (!feof(stdin)) {
- fstring line, sid_string;
- int len;
- unid_t id;
- int type = ID_EMPTY;
- DOM_SID sid;
-
- if (fgets(line, sizeof(line)-1, stdin) == NULL)
- break;
-
- len = strlen(line);
-
- if ( (len > 0) && (line[len-1] == '\n') )
- line[len-1] = '\0';
-
- /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */
-
- if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) {
- type = ID_GROUPID;
- }
-
- /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */
-
- if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) {
- type = ID_USERID;
- }
-
- if (type == ID_EMPTY) {
- d_printf("ignoring invalid line [%s]\n", line);
- continue;
- }
-
- if (!string_to_sid(&sid, sid_string)) {
- d_printf("ignoring invalid sid [%s]\n", sid_string);
- continue;
- }
-
- if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
- d_printf("Could not set mapping of %s %lu to sid %s\n",
- (type == ID_GROUPID) ? "GID" : "UID",
- (type == ID_GROUPID) ? (unsigned long)id.gid:
- (unsigned long)id.uid,
- sid_string_static(&sid));
- continue;
- }
-
- }
-
- idmap_close();
-
- return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1;
-}
-
-int net_help_idmap(int argc, const char **argv)
-{
- d_printf("net idmap dump filename"\
- "\n Dump current id mapping\n");
-
- d_printf("net idmap restore"\
- "\n Restore entries from stdin to current local idmap\n");
-
- return -1;
-}
-
-/***********************************************************
- Look at the current idmap
- **********************************************************/
-int net_idmap(int argc, const char **argv)
-{
- struct functable func[] = {
- {"dump", net_idmap_dump},
- {"restore", net_idmap_restore},
- {"help", net_help_idmap},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_help_idmap);
-}
-
-
diff --git a/source/utils/net_lookup.c b/source/utils/net_lookup.c
deleted file mode 100644
index cef0ea5fbed..00000000000
--- a/source/utils/net_lookup.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net lookup command
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-int net_lookup_usage(int argc, const char **argv)
-{
- d_printf(
-" net lookup [host] HOSTNAME[#<type>]\n\tgives IP for a hostname\n\n"
-" net lookup ldap [domain]\n\tgives IP of domain's ldap server\n\n"
-" net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n"
-" net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n"
-" net lookup master [domain|wg]\n\tgive IP of master browser\n\n"
-);
- return -1;
-}
-
-/* lookup a hostname giving an IP */
-static int net_lookup_host(int argc, const char **argv)
-{
- struct in_addr ip;
- int name_type = 0x20;
- const char *name = argv[0];
- char *p;
-
- if (argc == 0)
- return net_lookup_usage(argc, argv);
-
- p = strchr_m(name,'#');
- if (p) {
- *p = '\0';
- sscanf(++p,"%x",&name_type);
- }
-
- if (!resolve_name(name, &ip, name_type)) {
- /* we deliberately use DEBUG() here to send it to stderr
- so scripts aren't mucked up */
- DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
- return -1;
- }
-
- d_printf("%s\n", inet_ntoa(ip));
- return 0;
-}
-
-static void print_ldap_srvlist(char *srvlist)
-{
- char *cur, *next;
- struct in_addr ip;
- BOOL printit;
-
- cur = srvlist;
- do {
- next = strchr(cur,':');
- if (next) *next++='\0';
- printit = resolve_name(cur, &ip, 0x20);
- cur=next;
- next=cur ? strchr(cur,' ') :NULL;
- if (next)
- *next++='\0';
- if (printit)
- d_printf("%s:%s\n", inet_ntoa(ip), cur?cur:"");
- cur = next;
- } while (next);
-}
-
-
-static int net_lookup_ldap(int argc, const char **argv)
-{
-#ifdef HAVE_LDAP
- char *srvlist;
- const char *domain;
- int rc;
- struct in_addr addr;
- struct hostent *hostent;
-
- if (argc > 0)
- domain = argv[0];
- else
- domain = opt_target_workgroup;
-
- DEBUG(9, ("Lookup up ldap for domain %s\n", domain));
- rc = ldap_domain2hostlist(domain, &srvlist);
- if ((rc == LDAP_SUCCESS) && srvlist) {
- print_ldap_srvlist(srvlist);
- return 0;
- }
-
- DEBUG(9, ("Looking up DC for domain %s\n", domain));
- if (!get_pdc_ip(domain, &addr))
- return -1;
-
- hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr),
- AF_INET);
- if (!hostent)
- return -1;
-
- DEBUG(9, ("Found DC with DNS name %s\n", hostent->h_name));
- domain = strchr(hostent->h_name, '.');
- if (!domain)
- return -1;
- domain++;
-
- DEBUG(9, ("Looking up ldap for domain %s\n", domain));
- rc = ldap_domain2hostlist(domain, &srvlist);
- if ((rc == LDAP_SUCCESS) && srvlist) {
- print_ldap_srvlist(srvlist);
- return 0;
- }
- return -1;
-#endif
- DEBUG(1,("No LDAP support\n"));
- return -1;
-}
-
-static int net_lookup_dc(int argc, const char **argv)
-{
- struct ip_service *ip_list;
- struct in_addr addr;
- char *pdc_str = NULL;
- const char *domain=opt_target_workgroup;
- int count, i;
-
- if (argc > 0)
- domain=argv[0];
-
- /* first get PDC */
- if (!get_pdc_ip(domain, &addr))
- return -1;
-
- asprintf(&pdc_str, "%s", inet_ntoa(addr));
- d_printf("%s\n", pdc_str);
-
- if (!get_sorted_dc_list(domain, &ip_list, &count, False)) {
- SAFE_FREE(pdc_str);
- return 0;
- }
- for (i=0;i<count;i++) {
- char *dc_str = inet_ntoa(ip_list[i].ip);
- if (!strequal(pdc_str, dc_str))
- d_printf("%s\n", dc_str);
- }
- SAFE_FREE(pdc_str);
- return 0;
-}
-
-static int net_lookup_master(int argc, const char **argv)
-{
- struct in_addr master_ip;
- const char *domain=opt_target_workgroup;
-
- if (argc > 0)
- domain=argv[0];
-
- if (!find_master_ip(domain, &master_ip))
- return -1;
- d_printf("%s\n", inet_ntoa(master_ip));
- return 0;
-}
-
-static int net_lookup_kdc(int argc, const char **argv)
-{
-#ifdef HAVE_KRB5
- krb5_error_code rc;
- krb5_context ctx;
- struct sockaddr_in *addrs;
- int num_kdcs,i;
- krb5_data realm;
- char **realms;
-
- rc = krb5_init_context(&ctx);
- if (rc) {
- DEBUG(1,("krb5_init_context failed (%s)\n",
- error_message(rc)));
- return -1;
- }
-
- if (argc>0) {
- realm.data = (krb5_pointer) argv[0];
- realm.length = strlen(argv[0]);
- } else if (lp_realm() && *lp_realm()) {
- realm.data = (krb5_pointer) lp_realm();
- realm.length = strlen(realm.data);
- } else {
- rc = krb5_get_host_realm(ctx, NULL, &realms);
- if (rc) {
- DEBUG(1,("krb5_gethost_realm failed (%s)\n",
- error_message(rc)));
- return -1;
- }
- realm.data = (krb5_pointer) *realms;
- realm.length = strlen(realm.data);
- }
-
- rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0);
- if (rc) {
- DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
- return -1;
- }
- for (i=0;i<num_kdcs;i++)
- if (addrs[i].sin_family == AF_INET)
- d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr),
- ntohs(addrs[i].sin_port));
- return 0;
-
-#endif
- DEBUG(1, ("No kerberos support\n"));
- return -1;
-}
-
-
-/* lookup hosts or IP addresses using internal samba lookup fns */
-int net_lookup(int argc, const char **argv)
-{
- int i;
-
- struct functable table[] = {
- {"HOST", net_lookup_host},
- {"LDAP", net_lookup_ldap},
- {"DC", net_lookup_dc},
- {"MASTER", net_lookup_master},
- {"KDC", net_lookup_kdc},
- {NULL, NULL}
- };
-
- if (argc < 1) {
- d_printf("\nUsage: \n");
- return net_lookup_usage(argc, argv);
- }
- for (i=0; table[i].funcname; i++) {
- if (StrCaseCmp(argv[0], table[i].funcname) == 0)
- return table[i].fn(argc-1, argv+1);
- }
-
- /* Default to lookup a hostname so 'net lookup foo#1b' can be
- used instead of 'net lookup host foo#1b'. The host syntax
- is a bit confusing as non #00 names can't really be
- considered hosts as such. */
-
- return net_lookup_host(argc, argv);
-}
diff --git a/source/utils/net_privileges.c b/source/utils/net_privileges.c
deleted file mode 100644
index b5ccfae137e..00000000000
--- a/source/utils/net_privileges.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Net Utility
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Gerald Carter 2003,
- * Copyright (C) Simo Sorce 2003.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-#include "../utils/net.h"
-
-extern PRIVS privs[];
-
-/*********************************************************
- utility function to parse an integer parameter from
- "parameter = value"
-**********************************************************/
-static uint32 get_int_param( const char* param )
-{
- char *p;
-
- p = strchr( param, '=' );
- if ( !p )
- return 0;
-
- return atoi(p+1);
-}
-
-/*********************************************************
- utility function to parse an integer parameter from
- "parameter = value"
-**********************************************************/
-static char* get_string_param( const char* param )
-{
- char *p;
-
- p = strchr( param, '=' );
- if ( !p )
- return NULL;
-
- return (p+1);
-}
-
-/*********************************************************
- Dump a GROUP_MAP entry to stdout (long or short listing)
-**********************************************************/
-
-static void print_priv_entry(const char *privname, const char *description, const DOM_SID *sid_list, int sid_count)
-{
- d_printf("%s\n", privname);
-
- if (description) {
- d_printf("\tdescription: %s\n", description);
- }
-
- if (sid_count != 0) {
- int i;
- pstring sid_str;
-
- d_printf("\tSIDs: ");
-
- for (i = 0; i < sid_count; i++) {
- sid_to_string(sid_str, &sid_list[i]);
- if (i != 0) d_printf(",");
- d_printf(sid_str);
- }
-
- d_printf("\n");
- } else {
- d_printf("\tNo SIDs in this privilege\n");
- }
-}
-
-/*********************************************************
- List the groups.
-**********************************************************/
-static int net_priv_list(int argc, const char **argv)
-{
- fstring privname = "";
- fstring sid_string = "";
- int i;
- BOOL verbose = False;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if (StrnCaseCmp(argv[i], "privname", strlen("privname")) == 0) {
- fstrcpy(privname, get_string_param(argv[i]));
- if (!privname[0]) {
- d_printf("must supply a name\n");
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
- fstrcpy(sid_string, get_string_param(argv[i]));
- if (!sid_string[0]) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "verbose", strlen("verbose")) == 0) {
- verbose = True;
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if (sid_string[0] != '\0') {
- /* list all privileges of a single sid */
-
- } else {
- DOM_SID *sid_list;
- int sid_count;
-
- if (privname[0] != '\0') {
- const char *description = NULL;
-
- BOOL found = False;
-
- for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
- if (StrCaseCmp(privs[i].priv, privname) == 0) {
- description = privs[i].description;
- found = True;
- break;
- }
- }
- if (!found) {
- d_printf("No such privilege!\n");
- return -1;
- }
-
- /* Get the current privilege from the database */
- sid_list = NULL;
- sid_count = 0;
-
- pdb_get_privilege_entry(privname, &sid_list, &sid_count);
- print_priv_entry(privname, description, sid_list, sid_count);
-
- SAFE_FREE(sid_list);
-
- } else for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
-
- sid_list = NULL;
- sid_count = 0;
-
- if (!NT_STATUS_IS_OK(pdb_get_privilege_entry(privs[i].priv, &sid_list, &sid_count))) {
- if (!verbose) {
- SAFE_FREE(sid_list);
- continue;
- }
- }
-
- print_priv_entry(privs[i].priv, privs[i].description, sid_list, sid_count);
-
- SAFE_FREE(sid_list);
- }
- }
-
- return 0;
-}
-
-/*********************************************************
- Add a sid to a privilege entry
-**********************************************************/
-
-static int net_priv_add(int argc, const char **argv)
-{
- DOM_SID sid;
- fstring privname = "";
- fstring sid_string = "";
- uint32 rid = 0;
- int i;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if (StrnCaseCmp(argv[i], "rid", strlen("rid")) == 0) {
- rid = get_int_param(argv[i]);
- if (rid < DOMAIN_GROUP_RID_ADMINS) {
- d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
- BOOL found = False;
- int j;
-
- fstrcpy(privname, get_string_param(argv[i]));
- if (!privname[0]) {
- d_printf("must supply a name\n");
- return -1;
- }
- for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
- if (StrCaseCmp(privs[j].priv, privname) == 0) {
- found = True;
- }
- }
- if (!found) {
- d_printf("unknown privilege name");
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
- fstrcpy(sid_string, get_string_param(argv[i]));
- if (!sid_string[0]) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if (privname[0] == '\0') {
- d_printf("Usage: net priv add {rid=<int>|sid=<string>} privilege=<string>\n");
- return -1;
- }
-
- if ((rid == 0) && (sid_string[0] == '\0')) {
- d_printf("No rid or sid specified\n");
- d_printf("Usage: net priv add {rid=<int>|sid=<string>} privilege=<string>\n");
- return -1;
- }
-
- /* append the rid to our own domain/machine SID if we don't have a full SID */
- if (sid_string[0] == '\0') {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- sid_to_string(sid_string, &sid);
- } else {
- string_to_sid(&sid, sid_string);
- }
-
- if (!NT_STATUS_IS_OK(pdb_add_privilege_to_sid(privname, &sid))) {
- d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname);
- return -1;
- }
-
- d_printf("Successully added SID %s to privilege %s\n", sid_string, privname);
- return 0;
-}
-
-/*********************************************************
- Remove a SID froma privilege entry
-**********************************************************/
-
-static int net_priv_remove(int argc, const char **argv)
-{
- DOM_SID sid;
- fstring privname = "";
- fstring sid_string = "";
- uint32 rid = 0;
- int i;
-
- /* get the options */
- for ( i=0; i<argc; i++ ) {
- if (StrnCaseCmp(argv[i], "rid", strlen("rid")) == 0) {
- rid = get_int_param(argv[i]);
- if (rid < DOMAIN_GROUP_RID_ADMINS) {
- d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
- BOOL found = False;
- int j;
-
- fstrcpy(privname, get_string_param(argv[i]));
- if (!privname[0]) {
- d_printf("must supply a name\n");
- return -1;
- }
- for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
- if (StrCaseCmp(privs[j].priv, privname) == 0) {
- found = True;
- }
- }
- if (!found) {
- d_printf("unknown privilege name");
- return -1;
- }
- }
- else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
- fstrcpy(sid_string, get_string_param(argv[i]));
- if (!sid_string[0]) {
- d_printf("must supply a SID\n");
- return -1;
- }
- }
- else {
- d_printf("Bad option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if (privname[0] == '\0') {
- d_printf("Usage: net priv remove {rid=<int>|sid=<string>} privilege=<string>\n");
- return -1;
- }
-
- if ((rid == 0) && (sid_string[0] == '\0')) {
- d_printf("No rid or sid specified\n");
- d_printf("Usage: net priv remove {rid=<int>|sid=<string>} privilege=<string>\n");
- return -1;
- }
-
- /* append the rid to our own domain/machine SID if we don't have a full SID */
- if (sid_string[0] == '\0') {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- sid_to_string(sid_string, &sid);
- } else {
- string_to_sid(&sid, sid_string);
- }
-
- if (!NT_STATUS_IS_OK(pdb_remove_privilege_from_sid(privname, &sid))) {
- d_printf("removing sid %s from privilege %s failed!\n", sid_string, privname);
- return -1;
- }
-
- d_printf("Successully removed SID %s from privilege %s\n", sid_string, privname);
- return 0;
-}
-
-int net_help_priv(int argc, const char **argv)
-{
- d_printf("net priv add sid\n" \
- " Add sid to privilege\n");
- d_printf("net priv remove sid\n"\
- " Remove sid from privilege\n");
- d_printf("net priv list\n"\
- " List sids per privilege\n");
-
- return -1;
-}
-
-
-/***********************************************************
- migrated functionality from smbgroupedit
- **********************************************************/
-int net_priv(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", net_priv_add},
- {"remove", net_priv_remove},
- {"list", net_priv_list},
- {"help", net_help_priv},
- {NULL, NULL}
- };
-
- /* we shouldn't have silly checks like this */
- if (getuid() != 0) {
- d_printf("You must be root to edit privilege mappings.\nExiting...\n");
- return -1;
- }
-
- if ( argc )
- return net_run_function(argc, argv, func, net_help_priv);
-
- return net_help_priv(argc, argv);
-}
-
diff --git a/source/utils/net_rap.c b/source/utils/net_rap.c
deleted file mode 100644
index 39254641abf..00000000000
--- a/source/utils/net_rap.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
- Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
- Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
-
- Originally written by Steve and Jim. Largely rewritten by tridge in
- November 2001.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-/* The following messages were for error checking that is not properly
- reported at the moment. Which should be reinstated? */
-#define ERRMSG_TARGET_WG_NOT_VALID "\nTarget workgroup option not valid "\
- "except on net rap server command, ignored"
-#define ERRMSG_INVALID_HELP_OPTION "\nInvalid help option\n"
-
-#define ERRMSG_BOTH_SERVER_IPADDRESS "\nTarget server and IP address both "\
- "specified. Do not set both at the same time. The target IP address was used\n"
-
-const char *share_type[] = {
- "Disk",
- "Print",
- "Dev",
- "IPC"
-};
-
-static int errmsg_not_implemented(void)
-{
- d_printf("\nNot implemented\n");
- return 0;
-}
-
-int net_rap_file_usage(int argc, const char **argv)
-{
- return net_help_file(argc, argv);
-}
-
-/***************************************************************************
- list info on an open file
-***************************************************************************/
-static void file_fn(const char * pPath, const char * pUser, uint16 perms,
- uint16 locks, uint32 id)
-{
- d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
- id, pUser, perms, locks, pPath);
-}
-
-static void one_file_fn(const char *pPath, const char *pUser, uint16 perms,
- uint16 locks, uint32 id)
-{
- d_printf("File ID %d\n"\
- "User name %s\n"\
- "Locks 0x%-4.2x\n"\
- "Path %s\n"\
- "Permissions 0x%x\n",
- id, pUser, locks, pPath, perms);
-}
-
-
-static int rap_file_close(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc == 0) {
- d_printf("\nMissing fileid of file to close\n\n");
- return net_rap_file_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetFileClose(cli, atoi(argv[0]));
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_file_info(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc == 0)
- return net_rap_file_usage(argc, argv);
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetFileGetInfo(cli, atoi(argv[0]), one_file_fn);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_file_user(int argc, const char **argv)
-{
- if (argc == 0)
- return net_rap_file_usage(argc, argv);
-
- d_printf("net rap file user not implemented yet\n");
- return -1;
-}
-
-int net_rap_file(int argc, const char **argv)
-{
- struct functable func[] = {
- {"CLOSE", rap_file_close},
- {"USER", rap_file_user},
- {"INFO", rap_file_info},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- /* list open files */
- d_printf(
- "\nEnumerating open files on remote server:\n\n"\
- "\nFileId Opened by Perms Locks Path \n"\
- "------ --------- ----- ----- ---- \n");
- ret = cli_NetFileEnum(cli, NULL, NULL, file_fn);
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_file_usage);
-}
-
-int net_rap_share_usage(int argc, const char **argv)
-{
- return net_help_share(argc, argv);
-}
-
-static void long_share_fn(const char *share_name, uint32 type,
- const char *comment, void *state)
-{
- d_printf("%-12s %-8.8s %-50s\n",
- share_name, share_type[type], comment);
-}
-
-static void share_fn(const char *share_name, uint32 type,
- const char *comment, void *state)
-{
- d_printf("%s\n", share_name);
-}
-
-static int rap_share_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (argc == 0) {
- d_printf("\n\nShare name not specified\n");
- return net_rap_share_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetShareDelete(cli, argv[0]);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_share_add(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- RAP_SHARE_INFO_2 sinfo;
- char *p;
- char *sharename;
-
- if (argc == 0) {
- d_printf("\n\nShare name not specified\n");
- return net_rap_share_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- sharename = strdup(argv[0]);
- p = strchr(sharename, '=');
- *p = 0;
- strlcpy(sinfo.share_name, sharename, sizeof(sinfo.share_name));
- sinfo.reserved1 = '\0';
- sinfo.share_type = 0;
- sinfo.comment = smb_xstrdup(opt_comment);
- sinfo.perms = 0;
- sinfo.maximum_users = opt_maxusers;
- sinfo.active_users = 0;
- sinfo.path = p+1;
- memset(sinfo.password, '\0', sizeof(sinfo.password));
- sinfo.reserved2 = '\0';
-
- ret = cli_NetShareAdd(cli, &sinfo);
- cli_shutdown(cli);
- return ret;
-}
-
-
-int net_rap_share(int argc, const char **argv)
-{
- struct functable func[] = {
- {"DELETE", rap_share_delete},
- {"CLOSE", rap_share_delete},
- {"ADD", rap_share_add},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- if (opt_long_list_entries) {
- d_printf(
- "\nEnumerating shared resources (exports) on remote server:\n\n"\
- "\nShare name Type Description\n"\
- "---------- ---- -----------\n");
- ret = cli_RNetShareEnum(cli, long_share_fn, NULL);
- } else {
- ret = cli_RNetShareEnum(cli, share_fn, NULL);
- }
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_share_usage);
-}
-
-
-int net_rap_session_usage(int argc, const char **argv)
-{
- d_printf(
- "\nnet rap session [misc. options] [targets]"\
- "\n\tenumerates all active SMB/CIFS sessions on target server\n");
- d_printf(
- "\nnet rap session DELETE <client_name> [misc. options] [targets] \n"\
- "\tor"\
- "\nnet rap session CLOSE <client_name> [misc. options] [targets]"\
- "\n\tDeletes (closes) a session from specified client to server\n");
- d_printf(
- "\nnet rap session INFO <client_name>"\
- "\n\tEnumerates all open files in specified session\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-static void list_sessions_func(char *wsname, char *username, uint16 conns,
- uint16 opens, uint16 users, uint32 sess_time,
- uint32 idle_time, uint32 user_flags, char *clitype)
-{
- int hrs = idle_time / 3600;
- int min = (idle_time / 60) % 60;
- int sec = idle_time % 60;
-
- d_printf("\\\\%-18.18s %-20.20s %-18.18s %5d %2.2d:%2.2d:%2.2d\n",
- wsname, username, clitype, opens, hrs, min, sec);
-}
-
-static void display_session_func(const char *wsname, const char *username,
- uint16 conns, uint16 opens, uint16 users,
- uint32 sess_time, uint32 idle_time,
- uint32 user_flags, const char *clitype)
-{
- int ihrs = idle_time / 3600;
- int imin = (idle_time / 60) % 60;
- int isec = idle_time % 60;
- int shrs = sess_time / 3600;
- int smin = (sess_time / 60) % 60;
- int ssec = sess_time % 60;
- d_printf("User name %-20.20s\n"\
- "Computer %-20.20s\n"\
- "Guest logon %-20.20s\n"\
- "Client Type %-40.40s\n"\
- "Sess time %2.2d:%2.2d:%2.2d\n"\
- "Idle time %2.2d:%2.2d:%2.2d\n",
- username, wsname,
- (user_flags&0x0)?"yes":"no", clitype,
- shrs, smin, ssec, ihrs, imin, isec);
-}
-
-static void display_conns_func(uint16 conn_id, uint16 conn_type, uint16 opens,
- uint16 users, uint32 conn_time,
- const char *username, const char *netname)
-{
- d_printf("%-14.14s %-8.8s %5d\n",
- netname, share_type[conn_type], opens);
-}
-
-static int rap_session_info(int argc, const char **argv)
-{
- const char *sessname;
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- if (argc == 0)
- return net_rap_session_usage(argc, argv);
-
- sessname = argv[0];
-
- ret = cli_NetSessionGetInfo(cli, sessname, display_session_func);
- if (ret < 0) {
- cli_shutdown(cli);
- return ret;
- }
-
- d_printf("Share name Type # Opens\n-------------------------"\
- "-----------------------------------------------------\n");
- ret = cli_NetConnectionEnum(cli, sessname, display_conns_func);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_session_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- if (argc == 0)
- return net_rap_session_usage(argc, argv);
-
- ret = cli_NetSessionDel(cli, argv[0]);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_session(int argc, const char **argv)
-{
- struct functable func[] = {
- {"INFO", rap_session_info},
- {"DELETE", rap_session_delete},
- {"CLOSE", rap_session_delete},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- d_printf("Computer User name "\
- "Client Type Opens Idle time\n"\
- "------------------------------------------"\
- "------------------------------------\n");
- ret = cli_NetSessionEnum(cli, list_sessions_func);
-
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_session_usage);
-}
-
-/****************************************************************************
-list a server name
-****************************************************************************/
-static void display_server_func(const char *name, uint32 m,
- const char *comment, void * reserved)
-{
- d_printf("\t%-16.16s %s\n", name, comment);
-}
-
-
-int net_rap_server_usage(int argc, const char **argv)
-{
- d_printf("net rap server [misc. options] [target]\n\t"\
- "lists the servers in the specified domain or workgroup.\n");
- d_printf("\n\tIf domain is not specified, it uses the current"\
- " domain or workgroup as\n\tthe default.\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-int net_rap_server(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- d_printf("\nEnumerating servers in this domain or workgroup: \n\n"\
- "\tServer name Server description\n"\
- "\t------------- ----------------------------\n");
-
- ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL,
- display_server_func,NULL);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_domain_usage(int argc, const char **argv)
-{
- d_printf("net rap domain [misc. options] [target]\n\tlists the"\
- " domains or workgroups visible on the current network\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-
-int net_rap_domain(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- d_printf("\nEnumerating domains:\n\n"\
- "\tDomain name Server name of Browse Master\n"\
- "\t------------- ----------------------------\n");
-
- ret = cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM,
- display_server_func,NULL);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_printq_usage(int argc, const char **argv)
-{
- d_printf(
- "net rap printq [misc. options] [targets]\n"\
- "\tor\n"\
- "net rap printq list [<queue_name>] [misc. options] [targets]\n"\
- "\tlists the specified queue and jobs on the target server.\n"\
- "\tIf the queue name is not specified, all queues are listed.\n\n");
- d_printf(
- "net rap printq delete [<queue name>] [misc. options] [targets]\n"\
- "\tdeletes the specified job number on the target server, or the\n"\
- "\tprinter queue if no job number is specified\n");
-
- net_common_flags_usage(argc, argv);
-
- return -1;
-}
-
-static void enum_queue(const char *queuename, uint16 pri, uint16 start,
- uint16 until, const char *sep, const char *pproc,
- const char *dest, const char *qparms,
- const char *qcomment, uint16 status, uint16 jobcount)
-{
- d_printf("%-17.17s Queue %5d jobs ",
- queuename, jobcount);
-
- switch (status) {
- case 0:
- d_printf("*Printer Active*\n");
- break;
- case 1:
- d_printf("*Printer Paused*\n");
- break;
- case 2:
- d_printf("*Printer error*\n");
- break;
- case 3:
- d_printf("*Delete Pending*\n");
- break;
- default:
- d_printf("**UNKNOWN STATUS**\n");
- }
-}
-
-static void enum_jobs(uint16 jobid, const char *ownername,
- const char *notifyname, const char *datatype,
- const char *jparms, uint16 pos, uint16 status,
- const char *jstatus, unsigned int submitted, unsigned int jobsize,
- const char *comment)
-{
- d_printf(" %-23.23s %5d %9d ",
- ownername, jobid, jobsize);
- switch (status) {
- case 0:
- d_printf("Waiting\n");
- break;
- case 1:
- d_printf("Held in queue\n");
- break;
- case 2:
- d_printf("Spooling\n");
- break;
- case 3:
- d_printf("Printing\n");
- break;
- default:
- d_printf("**UNKNOWN STATUS**\n");
- }
-}
-
-#define PRINTQ_ENUM_DISPLAY \
- "Print queues at \\\\%s\n\n"\
- "Name Job # Size Status\n\n"\
- "------------------------------------------------------------------"\
- "-------------\n"
-
-static int rap_printq_info(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (argc == 0)
- return net_rap_printq_usage(argc, argv);
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
- ret = cli_NetPrintQGetInfo(cli, argv[0], enum_queue, enum_jobs);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_printq_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (argc == 0)
- return net_rap_printq_usage(argc, argv);
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_printjob_del(cli, atoi(argv[0]));
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_printq(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- struct functable func[] = {
- {"INFO", rap_printq_info},
- {"DELETE", rap_printq_delete},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- d_printf(PRINTQ_ENUM_DISPLAY, cli->desthost); /* list header */
- ret = cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_printq_usage);
-}
-
-
-static int net_rap_user_usage(int argc, const char **argv)
-{
- return net_help_user(argc, argv);
-}
-
-static void user_fn(const char *user_name, const char *comment,
- const char * home_dir, const char * logon_script,
- void *state)
-{
- d_printf("%-21.21s\n", user_name);
-}
-
-static void long_user_fn(const char *user_name, const char *comment,
- const char * home_dir, const char * logon_script,
- void *state)
-{
- d_printf("%-21.21s %s\n",
- user_name, comment);
-}
-
-static void group_member_fn(const char *user_name, void *state)
-{
- d_printf("%-21.21s\n", user_name);
-}
-
-static int rap_user_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (argc == 0) {
- d_printf("\n\nUser name not specified\n");
- return net_rap_user_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetUserDelete(cli, argv[0]);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_user_add(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- RAP_USER_INFO_1 userinfo;
-
- if (argc == 0) {
- d_printf("\n\nUser name not specified\n");
- return net_rap_user_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name)-1);
- if (opt_flags == -1)
- opt_flags = 0x21;
-
- userinfo.userflags = opt_flags;
- userinfo.reserved1 = '\0';
- userinfo.comment = smb_xstrdup(opt_comment);
- userinfo.priv = 1;
- userinfo.home_dir = NULL;
- userinfo.logon_script = NULL;
-
- ret = cli_NetUserAdd(cli, &userinfo);
-
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_user_info(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc == 0) {
- d_printf("\n\nUser name not specified\n");
- return net_rap_user_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetUserGetGroups(cli, argv[0], group_member_fn, NULL);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_user(int argc, const char **argv)
-{
- int ret = -1;
- struct functable func[] = {
- {"ADD", rap_user_add},
- {"INFO", rap_user_info},
- {"DELETE", rap_user_delete},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- if (!(cli = net_make_ipc_connection(0)))
- goto done;
- if (opt_long_list_entries) {
- d_printf("\nUser name Comment"\
- "\n-----------------------------\n");
- ret = cli_RNetUserEnum(cli, long_user_fn, NULL);
- cli_shutdown(cli);
- goto done;
- }
- ret = cli_RNetUserEnum(cli, user_fn, NULL);
- cli_shutdown(cli);
- goto done;
- }
-
- ret = net_run_function(argc, argv, func, net_rap_user_usage);
- done:
- if (ret != 0) {
- DEBUG(1, ("Net user returned: %d\n", ret));
- }
- return ret;
-}
-
-
-int net_rap_group_usage(int argc, const char **argv)
-{
- return net_help_group(argc, argv);
-}
-
-static void long_group_fn(const char *group_name, const char *comment,
- void *state)
-{
- d_printf("%-21.21s %s\n", group_name, comment);
-}
-
-static void group_fn(const char *group_name, const char *comment, void *state)
-{
- d_printf("%-21.21s\n", group_name);
-}
-
-static int rap_group_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc == 0) {
- d_printf("\n\nGroup name not specified\n");
- return net_rap_group_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetGroupDelete(cli, argv[0]);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_group_add(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- RAP_GROUP_INFO_1 grinfo;
-
- if (argc == 0) {
- d_printf("\n\nGroup name not specified\n");
- return net_rap_group_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- /* BB check for length 21 or smaller explicitly ? BB */
- safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
- grinfo.reserved1 = '\0';
- grinfo.comment = smb_xstrdup(opt_comment);
-
- ret = cli_NetGroupAdd(cli, &grinfo);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_group(int argc, const char **argv)
-{
- struct functable func[] = {
- {"ADD", rap_group_add},
- {"DELETE", rap_group_delete},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- int ret;
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
- if (opt_long_list_entries) {
- d_printf("Group name Comment\n");
- d_printf("-----------------------------\n");
- ret = cli_RNetGroupEnum(cli, long_group_fn, NULL);
- cli_shutdown(cli);
- return ret;
- }
- ret = cli_RNetGroupEnum(cli, group_fn, NULL);
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_group_usage);
-}
-
-int net_rap_groupmember_usage(int argc, const char **argv)
-{
- d_printf(
- "net rap groupmember LIST <group> [misc. options] [targets]"\
- "\n\t Enumerate users in a group\n"\
- "\nnet rap groupmember DELETE <group> <user> [misc. options] "\
- "[targets]\n\t Delete sepcified user from specified group\n"\
- "\nnet rap groupmember ADD <group> <user> [misc. options] [targets]"\
- "\n\t Add specified user to specified group\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-
-static int rap_groupmember_add(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc != 2) {
- d_printf("\n\nGroup or user name not specified\n");
- return net_rap_groupmember_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetGroupAddUser(cli, argv[0], argv[1]);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_groupmember_delete(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc != 2) {
- d_printf("\n\nGroup or user name not specified\n");
- return net_rap_groupmember_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetGroupDelUser(cli, argv[0], argv[1]);
- cli_shutdown(cli);
- return ret;
-}
-
-static int rap_groupmember_list(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
- if (argc == 0) {
- d_printf("\n\nGroup name not specified\n");
- return net_rap_groupmember_usage(argc, argv);
- }
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- ret = cli_NetGroupGetUsers(cli, argv[0], group_member_fn, NULL );
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_groupmember(int argc, const char **argv)
-{
- struct functable func[] = {
- {"ADD", rap_groupmember_add},
- {"LIST", rap_groupmember_list},
- {"DELETE", rap_groupmember_delete},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_rap_groupmember_usage);
-}
-
-int net_rap_validate_usage(int argc, const char **argv)
-{
- d_printf("net rap validate <username> [password]\n"\
- "\tValidate user and password to check whether they"\
- " can access target server or domain\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-int net_rap_validate(int argc, const char **argv)
-{
- return errmsg_not_implemented();
-}
-
-int net_rap_service_usage(int argc, const char **argv)
-{
- d_printf("net rap service [misc. options] [targets] \n"\
- "\tlists all running service daemons on target server\n");
- d_printf("\nnet rap service START <name> [service startup arguments]"\
- " [misc. options] [targets]"\
- "\n\tStart named service on remote server\n");
- d_printf("\nnet rap service STOP <name> [misc. options] [targets]\n"\
- "\n\tStop named service on remote server\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-static int rap_service_start(int argc, const char **argv)
-{
- return errmsg_not_implemented();
-}
-
-static int rap_service_stop(int argc, const char **argv)
-{
- return errmsg_not_implemented();
-}
-
-int net_rap_service(int argc, const char **argv)
-{
- struct functable func[] = {
- {"START", rap_service_start},
- {"STOP", rap_service_stop},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- struct cli_state *cli;
- int ret;
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- if (opt_long_list_entries) {
- d_printf("Service name Comment\n");
- d_printf("-----------------------------\n");
- ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
- }
- ret = cli_RNetServiceEnum(cli, group_fn, NULL);
- cli_shutdown(cli);
- return ret;
- }
-
- return net_run_function(argc, argv, func, net_rap_service_usage);
-}
-
-int net_rap_password_usage(int argc, const char **argv)
-{
- d_printf(
- "net rap password <user> <oldpwo> <newpw> [misc. options] [target]\n"\
- "\tchanges the password for the specified user at target\n");
-
- return -1;
-}
-
-
-int net_rap_password(int argc, const char **argv)
-{
- struct cli_state *cli;
- int ret;
-
- if (argc < 3)
- return net_rap_password_usage(argc, argv);
-
- if (!(cli = net_make_ipc_connection(0)))
- return -1;
-
- /* BB Add check for password lengths? */
- ret = cli_oem_change_password(cli, argv[0], argv[2], argv[1]);
- cli_shutdown(cli);
- return ret;
-}
-
-int net_rap_admin_usage(int argc, const char **argv)
-{
- d_printf(
- "net rap admin <remote command> [cmd args [env]] [misc. options] [targets]"\
- "\n\texecutes a remote command on an os/2 target server\n");
-
- return -1;
-}
-
-
-int net_rap_admin(int argc, const char **argv)
-{
- return errmsg_not_implemented();
-}
-
-/* The help subsystem for the RAP subcommand */
-
-int net_rap_usage(int argc, const char **argv)
-{
- d_printf(" net rap domain \tto list domains \n"\
- " net rap file \t\tto list open files on a server \n"\
- " net rap group \tto list user groups \n"\
- " net rap groupmember \tto list users in a group \n"\
- " net rap password \tto change the password of a user\n"\
- " net rap printq \tto list the print queues on a server\n"\
- " net rap server \tto list servers in a domain\n"\
- " net rap session \tto list clients with open sessions to a server\n"\
- " net rap share \tto list shares exported by a server\n"\
- " net rap user \t\tto list users\n"\
- " net rap validate \tto check whether a user and the corresponding password are valid\n"\
- " net rap help\n"\
- "\nType \"net help <option>\" to get more information on that option\n\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-/*
- handle "net rap help *" subcommands
-*/
-int net_rap_help(int argc, const char **argv)
-{
- struct functable func[] = {
- {"FILE", net_rap_file_usage},
- {"SHARE", net_rap_share_usage},
- {"SESSION", net_rap_session_usage},
- {"SERVER", net_rap_server_usage},
- {"DOMAIN", net_rap_domain_usage},
- {"PRINTQ", net_rap_printq_usage},
- {"USER", net_rap_user_usage},
- {"GROUP", net_rap_group_usage},
- {"VALIDATE", net_rap_validate_usage},
- {"GROUPMEMBER", net_rap_groupmember_usage},
- {"ADMIN", net_rap_admin_usage},
- {"SERVICE", net_rap_service_usage},
- {"PASSWORD", net_rap_password_usage},
- {NULL, NULL}};
-
- return net_run_function(argc, argv, func, net_rap_usage);
-}
-
-/* Entry-point for all the RAP functions. */
-
-int net_rap(int argc, const char **argv)
-{
- struct functable func[] = {
- {"FILE", net_rap_file},
- {"SHARE", net_rap_share},
- {"SESSION", net_rap_session},
- {"SERVER", net_rap_server},
- {"DOMAIN", net_rap_domain},
- {"PRINTQ", net_rap_printq},
- {"USER", net_rap_user},
- {"GROUP", net_rap_group},
- {"VALIDATE", net_rap_validate},
- {"GROUPMEMBER", net_rap_groupmember},
- {"ADMIN", net_rap_admin},
- {"SERVICE", net_rap_service},
- {"PASSWORD", net_rap_password},
- {"HELP", net_rap_help},
- {NULL, NULL}
- };
-
- return net_run_function(argc, argv, func, net_rap_usage);
-}
-
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
deleted file mode 100644
index 96f0fe96efc..00000000000
--- a/source/utils/net_rpc.c
+++ /dev/null
@@ -1,3589 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
- Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-/**
- * @file net_rpc.c
- *
- * @brief RPC based subcommands for the 'net' utility.
- *
- * This file should contain much of the functionality that used to
- * be found in rpcclient, execpt that the commands should change
- * less often, and the fucntionality should be sane (the user is not
- * expected to know a rid/sid before they conduct an operation etc.)
- *
- * @todo Perhaps eventually these should be split out into a number
- * of files, as this could get quite big.
- **/
-
-
-/* A function of this type is passed to the 'run_rpc_command' wrapper */
-typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *,
- struct cli_state *, TALLOC_CTX *, int, const char **);
-
-/**
- * Many of the RPC functions need the domain sid. This function gets
- * it at the start of every run
- *
- * @param cli A cli_state already connected to the remote machine
- *
- * @return The Domain SID of the remote machine.
- **/
-
-static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **domain_name)
-{
- DOM_SID *domain_sid;
- POLICY_HND pol;
- NTSTATUS result = NT_STATUS_OK;
- uint32 info_class = 5;
-
- if (!cli_nt_session_open (cli, PI_LSARPC)) {
- fprintf(stderr, "could not initialise lsa pipe\n");
- goto error;
- }
-
- result = cli_lsa_open_policy(cli, mem_ctx, False,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto error;
- }
-
- result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
- domain_name, &domain_sid);
- if (!NT_STATUS_IS_OK(result)) {
- error:
- fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
-
- if (!NT_STATUS_IS_OK(result)) {
- fprintf(stderr, "error: %s\n", nt_errstr(result));
- }
-
- exit(1);
- }
-
- cli_lsa_close(cli, mem_ctx, &pol);
- cli_nt_session_close(cli);
-
- return domain_sid;
-}
-
-/**
- * Run a single RPC command, from start to finish.
- *
- * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
- * @param conn_flag a NET_FLAG_ combination. Passed to
- * net_make_ipc_connection.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- * @return A shell status integer (0 for success)
- */
-
-static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
- rpc_command_fn fn,
- int argc, const char **argv)
-{
- struct cli_state *cli = NULL;
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
- DOM_SID *domain_sid;
- char *domain_name;
-
- /* make use of cli_state handed over as an argument, if possible */
- if (!cli_arg)
- cli = net_make_ipc_connection(conn_flags);
- else
- cli = cli_arg;
-
- if (!cli) {
- return -1;
- }
-
- /* Create mem_ctx */
-
- if (!(mem_ctx = talloc_init("run_rpc_command"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- cli_shutdown(cli);
- return -1;
- }
-
- domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name);
-
- if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
- if (!cli_nt_session_open(cli, pipe_idx)) {
- DEBUG(0, ("Could not initialise pipe\n"));
- }
- }
-
- nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
- } else {
- DEBUG(5, ("rpc command function succedded\n"));
- }
-
- if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
- if (cli->nt_pipe_fnum)
- cli_nt_session_close(cli);
- }
-
- /* close the connection only if it was opened here */
- if (!cli_arg)
- cli_shutdown(cli);
-
- talloc_destroy(mem_ctx);
-
- return (!NT_STATUS_IS_OK(nt_status));
-}
-
-
-/****************************************************************************/
-
-
-/**
- * Force a change of the trust acccount password.
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid aquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on compleation of the function.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
- return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
-}
-
-/**
- * Force a change of the trust acccount password.
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-int net_rpc_changetrustpw(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_changetrustpw_internals,
- argc, argv);
-}
-
-
-/****************************************************************************/
-
-
-/**
- * Join a domain, the old way.
- *
- * This uses 'machinename' as the inital password, and changes it.
- *
- * The password should be created with 'server manager' or equiv first.
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid aquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on compleation of the function.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
- fstring trust_passwd;
- unsigned char orig_trust_passwd_hash[16];
- NTSTATUS result;
- uint32 sec_channel_type;
-
- /*
- check what type of join - if the user want's to join as
- a BDC, the server must agree that we are a BDC.
- */
- if (argc >= 0) {
- sec_channel_type = get_sec_channel_type(argv[0]);
- } else {
- sec_channel_type = get_sec_channel_type(NULL);
- }
-
- fstrcpy(trust_passwd, global_myname());
- strlower_m(trust_passwd);
-
- /*
- * Machine names can be 15 characters, but the max length on
- * a password is 14. --jerry
- */
-
- trust_passwd[14] = '\0';
-
- E_md4hash(trust_passwd, orig_trust_passwd_hash);
-
- result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
- orig_trust_passwd_hash,
- sec_channel_type);
-
- if (NT_STATUS_IS_OK(result))
- printf("Joined domain %s.\n",opt_target_workgroup);
-
-
- if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
- DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
- result = NT_STATUS_UNSUCCESSFUL;
- }
-
- return result;
-}
-
-/**
- * Join a domain, the old way.
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int net_rpc_perform_oldjoin(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_NETLOGON,
- NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_oldjoin_internals,
- argc, argv);
-}
-
-/**
- * Join a domain, the old way. This function exists to allow
- * the message to be displayed when oldjoin was explicitly
- * requested, but not when it was implied by "net rpc join"
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int net_rpc_oldjoin(int argc, const char **argv)
-{
- int rc = net_rpc_perform_oldjoin(argc, argv);
-
- if (rc) {
- d_printf("Failed to join domain\n");
- }
-
- return rc;
-}
-
-/**
- * Basic usage function for 'net rpc join'
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- **/
-
-static int rpc_join_usage(int argc, const char **argv)
-{
- d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
- "\t to join a domain with admin username & password\n"\
- "\t\t password will be prompted if needed and none is specified\n"\
- "\t <type> can be (default MEMBER)\n"\
- "\t\t BDC - Join as a BDC\n"\
- "\t\t PDC - Join as a PDC\n"\
- "\t\t MEMBER - Join as a MEMBER server\n");
-
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-/**
- * 'net rpc join' entrypoint.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * Main 'net_rpc_join()' (where the admain username/password is used) is
- * in net_rpc_join.c
- * Try to just change the password, but if that doesn't work, use/prompt
- * for a username/password.
- **/
-
-int net_rpc_join(int argc, const char **argv)
-{
- if ((net_rpc_perform_oldjoin(argc, argv) == 0))
- return 0;
-
- return net_rpc_join_newstyle(argc, argv);
-}
-
-
-
-/**
- * display info about a rpc domain
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- SAM_UNK_CTR ctr;
- fstring sid_str;
-
- sid_to_string(sid_str, domain_sid);
-
- /* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- ZERO_STRUCT(ctr);
- result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
- 2, &ctr);
- if (NT_STATUS_IS_OK(result)) {
- TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
- d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
- d_printf("Domain SID: %s\n", sid_str);
- d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
- d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
- d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
- d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
- talloc_destroy(ctx);
- }
-
- done:
- return result;
-}
-
-
-/**
- * 'net rpc info' entrypoint.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- **/
-int net_rpc_info(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_info_internals,
- argc, argv);
-}
-
-
-/**
- * Fetch domain SID into the local secrets.tdb
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- fstring sid_str;
-
- sid_to_string(sid_str, domain_sid);
- d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
- sid_str, domain_name);
-
- if (!secrets_store_domain_sid(domain_name, domain_sid)) {
- DEBUG(0,("Can't store domain SID\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
-}
-
-
-/**
- * 'net rpc getsid' entrypoint.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- **/
-int net_rpc_getsid(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
- rpc_getsid_internals,
- argc, argv);
-}
-
-
-/****************************************************************************/
-
-/**
- * Basic usage function for 'net rpc user'
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
- **/
-
-static int rpc_user_usage(int argc, const char **argv)
-{
- return net_help_user(argc, argv);
-}
-
-/**
- * Add a new user to a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- const char *acct_name;
- uint16 acb_info;
- uint32 unknown, user_rid;
-
- if (argc != 1) {
- d_printf("User must be specified\n");
- rpc_user_usage(argc, argv);
- return NT_STATUS_OK;
- }
-
- acct_name = argv[0];
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Create domain user */
-
- acb_info = ACB_NORMAL;
- unknown = 0xe005000b; /* No idea what this is - a permission mask? */
-
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
- &user_pol, &user_rid);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- done:
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Failed to add user %s - %s\n", acct_name,
- nt_errstr(result));
- } else {
- d_printf("Added user %s\n", acct_name);
- }
- return result;
-}
-
-/**
- * Add a new user to a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_user_add(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
- argc, argv);
-}
-
-/**
- * Delete a user from a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND connect_pol, domain_pol, user_pol;
-
- if (argc < 1) {
- d_printf("User must be specified\n");
- rpc_user_usage(argc, argv);
- return NT_STATUS_OK;
- }
- /* Get sam policy and domain handles */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get handle on user */
-
- {
- uint32 *user_rids, num_rids, *name_types;
- uint32 flags = 0x000003e8; /* Unknown */
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, 1, &argv[0],
- &num_rids, &user_rids,
- &name_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rids[0], &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
- }
-
- /* Delete user */
-
- result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Display results */
-
- done:
- return result;
-
-}
-
-/**
- * Delete a user from a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_user_delete(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
- argc, argv);
-}
-
-/**
- * Set a password for a user on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND connect_pol, domain_pol, user_pol;
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- uchar pwbuf[516];
- const char *user;
- const char *new_password;
- char *prompt = NULL;
-
- if (argc < 1) {
- d_printf("User must be specified\n");
- rpc_user_usage(argc, argv);
- return NT_STATUS_OK;
- }
-
- user = argv[0];
-
- if (argv[1]) {
- new_password = argv[1];
- } else {
- asprintf(&prompt, "Enter new password for %s:", user);
- new_password = getpass(prompt);
- SAFE_FREE(prompt);
- }
-
- /* Get sam policy and domain handles */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get handle on user */
-
- {
- uint32 *user_rids, num_rids, *name_types;
- uint32 flags = 0x000003e8; /* Unknown */
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, 1, &user,
- &num_rids, &user_rids,
- &name_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rids[0], &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
- }
-
- /* Set password on account */
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
-
- init_sam_user_info24(&p24, (char *)pwbuf,24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
- &cli->user_session_key, &ctr);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Display results */
-
- done:
- return result;
-
-}
-
-/**
- * Set a user's password on a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_user_password(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
- argc, argv);
-}
-
-/**
- * List user's groups on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 *rids, num_rids, *name_types, num_names;
- uint32 flags = 0x000003e8; /* Unknown */
- int i;
- char **names;
- DOM_GID *user_gids;
-
- if (argc < 1) {
- d_printf("User must be specified\n");
- rpc_user_usage(argc, argv);
- return NT_STATUS_OK;
- }
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get handle on user */
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, 1, &argv[0],
- &num_rids, &rids, &name_types);
-
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- rids[0], &user_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
- &num_rids, &user_gids);
-
- /* Look up rids */
-
- rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
-
- for (i = 0; i < num_rids; i++)
- rids[i] = user_gids[i].g_rid;
-
- result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
- flags, num_rids, rids,
- &num_names, &names, &name_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Display results */
-
- for (i = 0; i < num_names; i++)
- printf("%s\n", names[i]);
-
- done:
- return result;
-}
-
-/**
- * List a user's groups from a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_user_info(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
- argc, argv);
-}
-
-/**
- * List users on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx=0, num_entries, i, loop_count = 0;
- SAM_DISPINFO_CTR ctr;
- SAM_DISPINFO_1 info1;
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Query domain users */
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(info1);
- ctr.sam.info1 = &info1;
- if (opt_long_list_entries)
- d_printf("\nUser name Comment"\
- "\n-----------------------------\n");
- do {
- fstring user, desc;
- uint32 max_entries, max_size;
-
- get_query_dispinfo_params(
- loop_count, &max_entries, &max_size);
-
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
- &start_idx, 1, &num_entries,
- max_entries, max_size, &ctr);
- loop_count++;
-
- for (i = 0; i < num_entries; i++) {
- unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
- if (opt_long_list_entries)
- unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
-
- if (opt_long_list_entries)
- printf("%-21.21s %s\n", user, desc);
- else
- printf("%s\n", user);
- }
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- done:
- return result;
-}
-
-/**
- * 'net rpc user' entrypoint.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_user(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", rpc_user_add},
- {"info", rpc_user_info},
- {"delete", rpc_user_delete},
- {"password", rpc_user_password},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- if (opt_long_list_entries) {
- } else {
- }
- return run_rpc_command(NULL,PI_SAMR, 0,
- rpc_user_list_internals,
- argc, argv);
- }
-
- return net_run_function(argc, argv, func, rpc_user_usage);
-}
-
-
-/****************************************************************************/
-
-/**
- * Basic usage function for 'net rpc group'
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
- **/
-
-static int rpc_group_usage(int argc, const char **argv)
-{
- return net_help_group(argc, argv);
-}
-
-/**
- * Delete group on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
- BOOL group_is_primary = False;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- uint32 *group_rids, num_rids, *name_types, num_members,
- *group_attrs, num_names, *user_rids, GROUP_RID;
- uint32 flags = 0x000003e8; /* Unknown */
- /* char **names; */
- int i;
- /* DOM_GID *user_gids; */
- SAM_USERINFO_CTR *user_ctr;
- fstring temp;
-
- if (argc < 1) {
- d_printf("specify group\n");
- rpc_group_usage(argc,argv);
- return NT_STATUS_OK; /* ok? */
- }
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Request samr_connect failed\n");
- goto done;
- }
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Request open_domain failed\n");
- goto done;
- }
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, 1, &argv[0],
- &num_rids, &group_rids,
- &name_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Lookup of '%s' failed\n",argv[0]);
- goto done;
- }
-
- switch (name_types[0])
- {
- case SID_NAME_DOM_GRP:
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rids[0], &group_pol);
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Request open_group failed");
- goto done;
- }
-
- GROUP_RID = group_rids[0];
-
- result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
- &num_members, &group_rids,
- &group_attrs);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Unable to query group members of %s",argv[0]);
- goto done;
- }
-
- if (opt_verbose) {
- d_printf("Domain Group %s (rid: %d) has %d members\n",
- argv[0],GROUP_RID,num_members);
- }
-
- /* Check if group is anyone's primary group */
- for (i = 0; i < num_members; i++)
- {
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rids[i], &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Unable to open group member %d\n",group_rids[i]);
- goto done;
- }
-
- ZERO_STRUCT(user_ctr);
-
- result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
- 21, &user_ctr);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Unable to lookup userinfo for group member %d\n",group_rids[i]);
- goto done;
- }
-
- if (user_ctr->info.id21->group_rid == GROUP_RID) {
- unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
- sizeof(temp)-1);
- if (opt_verbose)
- d_printf("Group is primary group of %s\n",temp);
- group_is_primary = True;
- }
- }
-
- if (group_is_primary) {
- if (opt_verbose) {
- d_printf("Unable to delete group because some of it's members have it as rimary group\n");
- }
- result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
- goto done;
- }
-
- /* remove all group members */
- for (i = 0; i < num_members; i++)
- {
- if (opt_verbose)
- d_printf("Remove group member %d...",group_rids[i]);
- result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, group_rids[i]);
-
- if (NT_STATUS_IS_OK(result)) {
- if (opt_verbose)
- d_printf("ok\n");
- } else {
- if (opt_verbose)
- d_printf("failed\n");
- goto done;
- }
- }
-
- result = cli_samr_delete_dom_group(cli, mem_ctx, &group_pol);
-
- break;
- /* removing a local group is easier... */
- case SID_NAME_ALIAS:
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rids[0], &group_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Request open_alias failed\n");
- goto done;
- }
-
- result = cli_samr_delete_dom_alias(cli, mem_ctx, &group_pol);
- break;
- default:
- d_printf("%s is of type %s. This command is only for deleting local or global groups\n",
- argv[0],sid_type_lookup(name_types[0]));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
-
- if (NT_STATUS_IS_OK(result)) {
- if (opt_verbose)
- d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
- } else {
- d_printf("Deleting of %s failed: %s\n",argv[0],
- get_friendly_nt_error_msg(result));
- }
-
- done:
- return result;
-
-}
-
-static int rpc_group_delete(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
- argc,argv);
-}
-
-static NTSTATUS
-rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol, group_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- GROUP_INFO_CTR group_info;
-
- if (argc != 1) {
- d_printf("Group name must be specified\n");
- rpc_group_usage(argc, argv);
- return NT_STATUS_OK;
- }
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Create the group */
-
- result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
- argv[0], MAXIMUM_ALLOWED_ACCESS,
- &group_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- if (strlen(opt_comment) == 0) goto done;
-
- /* We've got a comment to set */
-
- group_info.switch_value1 = 4;
- init_samr_group_info4(&group_info.group.info4, opt_comment);
-
- result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &group_info);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- done:
- if (NT_STATUS_IS_OK(result))
- DEBUG(5, ("add group succeeded\n"));
- else
- d_printf("add group failed: %s\n", nt_errstr(result));
-
- return result;
-}
-
-static NTSTATUS
-rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol, alias_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- ALIAS_INFO_CTR alias_info;
-
- if (argc != 1) {
- d_printf("Group name must be specified\n");
- rpc_group_usage(argc, argv);
- return NT_STATUS_OK;
- }
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Create the group */
-
- result = cli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
- argv[0], &alias_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- if (strlen(opt_comment) == 0) goto done;
-
- /* We've got a comment to set */
-
- alias_info.switch_value1 = 3;
- alias_info.switch_value2 = 3;
- init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
-
- result = cli_samr_set_aliasinfo(cli, mem_ctx, &alias_pol, &alias_info);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- done:
- if (NT_STATUS_IS_OK(result))
- DEBUG(5, ("add group succeeded\n"));
- else
- d_printf("add group failed: %s\n", nt_errstr(result));
-
- return result;
-}
-
-static int rpc_group_add(int argc, const char **argv)
-{
- if (opt_localgroup)
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_alias_add_internals,
- argc, argv);
-
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_add_internals,
- argc, argv);
-}
-
-static NTSTATUS
-get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name,
- DOM_SID *sid, enum SID_NAME_USE *type)
-{
- int current_pipe = cli->pipe_idx;
-
- DOM_SID *sids = NULL;
- uint32 *types = NULL;
- POLICY_HND lsa_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (current_pipe != PI_LSARPC) {
-
- if (current_pipe != -1)
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, PI_LSARPC))
- goto done;
- }
-
- result = cli_lsa_open_policy(cli, mem_ctx, False,
- SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_lsa_lookup_names(cli, mem_ctx, &lsa_pol, 1,
- &name, &sids, &types);
-
- if (NT_STATUS_IS_OK(result)) {
- sid_copy(sid, &sids[0]);
- *type = types[0];
- }
-
- cli_lsa_close(cli, mem_ctx, &lsa_pol);
-
- done:
- if (current_pipe != PI_LSARPC) {
- cli_nt_session_close(cli);
- if (current_pipe != -1)
- cli_nt_session_open(cli, current_pipe);
- }
-
- if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
-
- /* Try as S-1-5-whatever */
-
- DOM_SID tmp_sid;
-
- if (string_to_sid(&tmp_sid, name)) {
- sid_copy(sid, &tmp_sid);
- *type = SID_NAME_UNKNOWN;
- result = NT_STATUS_OK;
- }
- }
-
- return result;
-}
-
-static NTSTATUS
-rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, const char *member)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result;
- uint32 group_rid;
- POLICY_HND group_pol;
-
- uint32 num_rids;
- uint32 *rids = NULL;
- uint32 *rid_types = NULL;
-
- DOM_SID sid;
-
- sid_copy(&sid, group_sid);
-
- if (!sid_split_rid(&sid, &group_rid))
- return NT_STATUS_UNSUCCESSFUL;
-
- /* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
- 1, &member,
- &num_rids, &rids, &rid_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not lookup up group member %s\n", member);
- goto done;
- }
-
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rid, &group_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_samr_add_groupmem(cli, mem_ctx, &group_pol, rids[0]);
-
- done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
- return result;
-}
-
-static NTSTATUS
-rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *alias_sid, const char *member)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result;
- uint32 alias_rid;
- POLICY_HND alias_pol;
-
- DOM_SID member_sid;
- enum SID_NAME_USE member_type;
-
- DOM_SID sid;
-
- sid_copy(&sid, alias_sid);
-
- if (!sid_split_rid(&sid, &alias_rid))
- return NT_STATUS_UNSUCCESSFUL;
-
- result = get_sid_from_name(cli, mem_ctx, member,
- &member_sid, &member_type);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not lookup up group member %s\n", member);
- return result;
- }
-
- /* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- alias_rid, &alias_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_add_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
- return result;
-}
-
-static NTSTATUS
-rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- DOM_SID group_sid;
- enum SID_NAME_USE group_type;
-
- if (argc != 2) {
- d_printf("Usage: 'net rpc group addmem <group> <member>\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
- &group_sid, &group_type))) {
- d_printf("Could not lookup group name %s\n", argv[0]);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (group_type == SID_NAME_DOM_GRP) {
- NTSTATUS result = rpc_add_groupmem(cli, mem_ctx,
- &group_sid, argv[1]);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not add %s to %s: %s\n",
- argv[1], argv[0], nt_errstr(result));
- }
- return result;
- }
-
- if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_add_aliasmem(cli, mem_ctx,
- &group_sid, argv[1]);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not add %s to %s: %s\n",
- argv[1], argv[0], nt_errstr(result));
- }
- return result;
- }
-
- d_printf("Can only add members to global or local groups which "
- "%s is not\n", argv[0]);
-
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-static int rpc_group_addmem(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_addmem_internals,
- argc, argv);
-}
-
-static NTSTATUS
-rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, const char *member)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result;
- uint32 group_rid;
- POLICY_HND group_pol;
-
- uint32 num_rids;
- uint32 *rids = NULL;
- uint32 *rid_types = NULL;
-
- DOM_SID sid;
-
- sid_copy(&sid, group_sid);
-
- if (!sid_split_rid(&sid, &group_rid))
- return NT_STATUS_UNSUCCESSFUL;
-
- /* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
- 1, &member,
- &num_rids, &rids, &rid_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not lookup up group member %s\n", member);
- goto done;
- }
-
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rid, &group_pol);
-
- if (!NT_STATUS_IS_OK(result))
- goto done;
-
- result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, rids[0]);
-
- done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
- return result;
-}
-
-static NTSTATUS
-rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *alias_sid, const char *member)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result;
- uint32 alias_rid;
- POLICY_HND alias_pol;
-
- DOM_SID member_sid;
- enum SID_NAME_USE member_type;
-
- DOM_SID sid;
-
- sid_copy(&sid, alias_sid);
-
- if (!sid_split_rid(&sid, &alias_rid))
- return NT_STATUS_UNSUCCESSFUL;
-
- result = get_sid_from_name(cli, mem_ctx, member,
- &member_sid, &member_type);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not lookup up group member %s\n", member);
- return result;
- }
-
- /* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- alias_rid, &alias_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_del_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
- return result;
-}
-
-static NTSTATUS
-rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- DOM_SID group_sid;
- enum SID_NAME_USE group_type;
-
- if (argc != 2) {
- d_printf("Usage: 'net rpc group delmem <group> <member>\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
- &group_sid, &group_type))) {
- d_printf("Could not lookup group name %s\n", argv[0]);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (group_type == SID_NAME_DOM_GRP) {
- NTSTATUS result = rpc_del_groupmem(cli, mem_ctx,
- &group_sid, argv[1]);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not del %s from %s: %s\n",
- argv[1], argv[0], nt_errstr(result));
- }
- return result;
- }
-
- if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_del_aliasmem(cli, mem_ctx,
- &group_sid, argv[1]);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Could not del %s from %s: %s\n",
- argv[1], argv[0], nt_errstr(result));
- }
- return result;
- }
-
- d_printf("Can only delete members from global or local groups which "
- "%s is not\n", argv[0]);
-
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-static int rpc_group_delmem(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_delmem_internals,
- argc, argv);
-}
-
-/**
- * List groups on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
- struct acct_info *groups;
- DOM_SID global_sid_Builtin;
- BOOL global = False;
- BOOL local = False;
- BOOL builtin = False;
-
- if (argc == 0) {
- global = True;
- local = True;
- builtin = True;
- }
-
- for (i=0; i<argc; i++) {
- if (strequal(argv[i], "global"))
- global = True;
-
- if (strequal(argv[i], "local"))
- local = True;
-
- if (strequal(argv[i], "builtin"))
- builtin = True;
- }
-
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Query domain groups */
- if (opt_long_list_entries)
- d_printf("\nGroup name Comment"\
- "\n-----------------------------\n");
- do {
- SAM_DISPINFO_CTR ctr;
- SAM_DISPINFO_3 info3;
- uint32 max_size;
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(info3);
- ctr.sam.info3 = &info3;
-
- if (!global) break;
-
- get_query_dispinfo_params(
- loop_count, &max_entries, &max_size);
-
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
- &start_idx, 3, &num_entries,
- max_entries, max_size, &ctr);
-
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- break;
-
- for (i = 0; i < num_entries; i++) {
-
- fstring group, desc;
-
- unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
- unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
-
- if (opt_long_list_entries)
- printf("%-21.21s %-50.50s\n",
- group, desc);
- else
- printf("%s\n", group);
- }
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
- /* query domain aliases */
- start_idx = 0;
- do {
- if (!local) break;
-
- result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
- &start_idx, max_entries,
- &groups, &num_entries);
-
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- break;
-
- for (i = 0; i < num_entries; i++) {
-
- char *description = NULL;
-
- if (opt_long_list_entries) {
-
- POLICY_HND alias_pol;
- ALIAS_INFO_CTR ctr;
-
- if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
- &domain_pol,
- 0x8,
- groups[i].rid,
- &alias_pol))) &&
- (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
- &alias_pol, 3,
- &ctr))) &&
- (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
- &alias_pol)))) {
- description = unistr2_tdup(mem_ctx,
- &ctr.alias.info3.uni_acct_desc);
- }
- }
-
- if (description != NULL) {
- printf("%-21.21s %-50.50s\n",
- groups[i].acct_name,
- description);
- } else {
- printf("%s\n", groups[i].acct_name);
- }
- }
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
- cli_samr_close(cli, mem_ctx, &domain_pol);
- /* Get builtin policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &global_sid_Builtin, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
- /* query builtin aliases */
- start_idx = 0;
- do {
- if (!builtin) break;
-
- result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
- &start_idx, max_entries,
- &groups, &num_entries);
-
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- break;
-
- for (i = 0; i < num_entries; i++) {
-
- char *description = NULL;
-
- if (opt_long_list_entries) {
-
- POLICY_HND alias_pol;
- ALIAS_INFO_CTR ctr;
-
- if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
- &domain_pol,
- 0x8,
- groups[i].rid,
- &alias_pol))) &&
- (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
- &alias_pol, 3,
- &ctr))) &&
- (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
- &alias_pol)))) {
- description = unistr2_tdup(mem_ctx,
- &ctr.alias.info3.uni_acct_desc);
- }
- }
-
- if (description != NULL) {
- printf("%-21.21s %-50.50s\n",
- groups[i].acct_name,
- description);
- } else {
- printf("%s\n", groups[i].acct_name);
- }
- }
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- done:
- return result;
-}
-
-static int rpc_group_list(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_list_internals,
- argc, argv);
-}
-
-static NTSTATUS
-rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *domain_name, const DOM_SID *domain_sid,
- POLICY_HND *domain_pol, uint32 rid)
-{
- NTSTATUS result;
- POLICY_HND group_pol;
- uint32 num_members, *group_rids, *group_attrs;
- uint32 num_names;
- char **names;
- uint32 *name_types;
- int i;
-
- fstring sid_str;
- sid_to_string(sid_str, domain_sid);
-
- result = cli_samr_open_group(cli, mem_ctx, domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- rid, &group_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
- &num_members, &group_rids,
- &group_attrs);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- while (num_members > 0) {
- int this_time = 512;
-
- if (num_members < this_time)
- this_time = num_members;
-
- result = cli_samr_lookup_rids(cli, mem_ctx, domain_pol, 1000,
- this_time, group_rids,
- &num_names, &names, &name_types);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /* We only have users as members, but make the output
- the same as the output of alias members */
-
- for (i = 0; i < this_time; i++) {
-
- if (opt_long_list_entries) {
- printf("%s-%d %s\\%s %d\n", sid_str,
- group_rids[i], domain_name, names[i],
- SID_NAME_USER);
- } else {
- printf("%s\\%s\n", domain_name, names[i]);
- }
- }
-
- num_members -= this_time;
- group_rids += 512;
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS
-rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 rid)
-{
- NTSTATUS result;
- POLICY_HND alias_pol, lsa_pol;
- uint32 num_members;
- DOM_SID *alias_sids;
- char **domains;
- char **names;
- uint32 *types;
- int i;
-
- result = cli_samr_open_alias(cli, mem_ctx, domain_pol,
- MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
- &num_members, &alias_sids);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Couldn't list alias members\n");
- return result;
- }
-
- if (num_members == 0) {
- return NT_STATUS_OK;
- }
-
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- d_printf("Couldn't open LSA pipe\n");
- return result;
- }
-
- result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Couldn't open LSA policy handle\n");
- return result;
- }
-
- result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, num_members,
- alias_sids,
- &domains, &names, &types);
-
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) {
- d_printf("Couldn't lookup SIDs\n");
- return result;
- }
-
- for (i = 0; i < num_members; i++) {
- fstring sid_str;
- sid_to_string(sid_str, &alias_sids[i]);
-
- if (opt_long_list_entries) {
- printf("%s %s\\%s %d\n", sid_str,
- (domains&&domains[i]) ? domains[i]:"*unknown*",
- names[i] ? names[i] : "*unknown*", types[i]);
- } else {
- if (domains && domains[i])
- printf("%s\\%s\n", domains[i], names[i]);
- else
- printf("%s\n", sid_str);
- }
- }
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS
-rpc_group_members_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- NTSTATUS result;
- POLICY_HND connect_pol, domain_pol;
- uint32 num_rids, *rids, *rid_types;
-
- /* Get sam policy handle */
-
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /* Get domain policy handle */
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
- 1, argv, &num_rids, &rids, &rid_types);
-
- if (!NT_STATUS_IS_OK(result)) {
-
- /* Ok, did not find it in the global sam, try with builtin */
-
- DOM_SID sid_Builtin;
-
- cli_samr_close(cli, mem_ctx, &domain_pol);
-
- string_to_sid(&sid_Builtin, "S-1-5-32");
-
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &sid_Builtin, &domain_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Couldn't find group %s\n", argv[0]);
- return result;
- }
-
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
- 1, argv, &num_rids,
- &rids, &rid_types);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Couldn't find group %s\n", argv[0]);
- return result;
- }
- }
-
- if (num_rids != 1) {
- d_printf("Couldn't find group %s\n", argv[0]);
- return result;
- }
-
- if (rid_types[0] == SID_NAME_DOM_GRP) {
- return rpc_list_group_members(cli, mem_ctx, domain_name,
- domain_sid, &domain_pol,
- rids[0]);
- }
-
- if (rid_types[0] == SID_NAME_ALIAS) {
- return rpc_list_alias_members(cli, mem_ctx, &domain_pol,
- rids[0]);
- }
-
- return NT_STATUS_NO_SUCH_GROUP;
-}
-
-static int rpc_group_members(int argc, const char **argv)
-{
- if (argc != 1) {
- return rpc_group_usage(argc, argv);
- }
-
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_members_internals,
- argc, argv);
-}
-
-/**
- * 'net rpc group' entrypoint.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_group(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", rpc_group_add},
- {"delete", rpc_group_delete},
- {"addmem", rpc_group_addmem},
- {"delmem", rpc_group_delmem},
- {"list", rpc_group_list},
- {"members", rpc_group_members},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- if (opt_long_list_entries) {
- } else {
- }
- return run_rpc_command(NULL, PI_SAMR, 0,
- rpc_group_list_internals,
- argc, argv);
- }
-
- return net_run_function(argc, argv, func, rpc_group_usage);
-}
-
-/****************************************************************************/
-
-static int rpc_share_usage(int argc, const char **argv)
-{
- return net_help_share(argc, argv);
-}
-
-/**
- * Add a share on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-static NTSTATUS
-rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,int argc, const char **argv)
-{
- WERROR result;
- char *sharename=talloc_strdup(mem_ctx, argv[0]);
- char *path;
- uint32 type=0; /* only allow disk shares to be added */
- uint32 num_users=0, perms=0;
- char *password=NULL; /* don't allow a share password */
-
- path = strchr(sharename, '=');
- if (!path)
- return NT_STATUS_UNSUCCESSFUL;
- *path++ = '\0';
-
- result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
- opt_comment, perms, opt_maxusers,
- num_users, path, password);
- return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static int rpc_share_add(int argc, const char **argv)
-{
- if ((argc < 1) || !strchr(argv[0], '=')) {
- DEBUG(1,("Sharename or path not specified on add\n"));
- return rpc_share_usage(argc, argv);
- }
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_share_add_internals,
- argc, argv);
-}
-
-/**
- * Delete a share on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-static NTSTATUS
-rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,int argc, const char **argv)
-{
- WERROR result;
-
- result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
- return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-/**
- * Delete a share on a remote RPC server
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-static int rpc_share_delete(int argc, const char **argv)
-{
- if (argc < 1) {
- DEBUG(1,("Sharename not specified on delete\n"));
- return rpc_share_usage(argc, argv);
- }
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_share_del_internals,
- argc, argv);
-}
-
-/**
- * Formatted print of share info
- *
- * @param info1 pointer to SRV_SHARE_INFO_1 to format
- **/
-
-static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
-{
- fstring netname = "", remark = "";
-
- rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
- rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
-
- if (opt_long_list_entries) {
- d_printf("%-12s %-8.8s %-50s\n",
- netname, share_type[info1->info_1.type], remark);
- } else {
- d_printf("%s\n", netname);
- }
-
-}
-
-/**
- * List shares on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- SRV_SHARE_INFO_CTR ctr;
- WERROR result;
- ENUM_HND hnd;
- uint32 preferred_len = 0xffffffff, i;
-
- init_enum_hnd(&hnd, 0);
-
- result = cli_srvsvc_net_share_enum(
- cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* Display results */
-
- if (opt_long_list_entries) {
- d_printf(
- "\nEnumerating shared resources (exports) on remote server:\n\n"\
- "\nShare name Type Description\n"\
- "---------- ---- -----------\n");
- }
- for (i = 0; i < ctr.num_entries; i++)
- display_share_info_1(&ctr.share.info1[i]);
- done:
- return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-/**
- * 'net rpc share' entrypoint.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_share(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", rpc_share_add},
- {"delete", rpc_share_delete},
- {NULL, NULL}
- };
-
- if (argc == 0)
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_share_list_internals,
- argc, argv);
-
- return net_run_function(argc, argv, func, rpc_share_usage);
-}
-
-/****************************************************************************/
-
-static int rpc_file_usage(int argc, const char **argv)
-{
- return net_help_file(argc, argv);
-}
-
-/**
- * Close a file on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-static NTSTATUS
-rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- WERROR result;
- result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
- return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-/**
- * Close a file on a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-static int rpc_file_close(int argc, const char **argv)
-{
- if (argc < 1) {
- DEBUG(1, ("No fileid given on close\n"));
- return(rpc_file_usage(argc, argv));
- }
-
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_file_close_internals,
- argc, argv);
-}
-
-/**
- * Formatted print of open file info
- *
- * @param info3 FILE_INFO_3 contents
- * @param str3 strings for FILE_INFO_3
- **/
-
-static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
-{
- fstring user = "", path = "";
-
- rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
- rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
-
- d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
- info3->id, user, info3->perms, info3->num_locks, path);
-}
-
-/**
- * List open files on a remote RPC server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid acquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS
-rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
-{
- SRV_FILE_INFO_CTR ctr;
- WERROR result;
- ENUM_HND hnd;
- uint32 preferred_len = 0xffffffff, i;
- const char *username=NULL;
-
- init_enum_hnd(&hnd, 0);
-
- /* if argc > 0, must be user command */
- if (argc > 0)
- username = smb_xstrdup(argv[0]);
-
- result = cli_srvsvc_net_file_enum(
- cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- /* Display results */
-
- d_printf(
- "\nEnumerating open files on remote server:\n\n"\
- "\nFileId Opened by Perms Locks Path"\
- "\n------ --------- ----- ----- ---- \n");
- for (i = 0; i < ctr.num_entries; i++)
- display_file_info_3(&ctr.file.info3[i].info_3,
- &ctr.file.info3[i].info_3_str);
- done:
- return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-
-/**
- * List files for a user on a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-static int rpc_file_user(int argc, const char **argv)
-{
- if (argc < 1) {
- DEBUG(1, ("No username given\n"));
- return(rpc_file_usage(argc, argv));
- }
-
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_file_list_internals,
- argc, argv);
-}
-
-
-/**
- * 'net rpc file' entrypoint.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_file(int argc, const char **argv)
-{
- struct functable func[] = {
- {"close", rpc_file_close},
- {"user", rpc_file_user},
-#if 0
- {"info", rpc_file_info},
-#endif
- {NULL, NULL}
- };
-
- if (argc == 0)
- return run_rpc_command(NULL, PI_SRVSVC, 0,
- rpc_file_list_internals,
- argc, argv);
-
- return net_run_function(argc, argv, func, rpc_file_usage);
-}
-
-/****************************************************************************/
-
-
-
-/**
- * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
- *
- * @param domain_sid The domain sid aquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on compleation of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- result = cli_shutdown_abort(cli, mem_ctx);
-
- if (NT_STATUS_IS_OK(result))
- DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
- else
- DEBUG(5,("cmd_shutdown_abort: query failed\n"));
-
- return result;
-}
-
-
-/**
- * ABORT the shutdown of a remote RPC Server, over winreg pipe
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
- *
- * @param domain_sid The domain sid aquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on compleation of the function.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- result = cli_reg_abort_shutdown(cli, mem_ctx);
-
- if (NT_STATUS_IS_OK(result))
- DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
- else
- DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
-
- return result;
-}
-
-/**
- * ABORT the Shut down of a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_shutdown_abort(int argc, const char **argv)
-{
- int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
- rpc_shutdown_abort_internals,
- argc, argv);
-
- if (rc == 0)
- return rc;
-
- DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
-
- return run_rpc_command(NULL, PI_WINREG, 0,
- rpc_reg_shutdown_abort_internals,
- argc, argv);
-}
-
-/**
- * Shut down a remote RPC Server
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passes through.
- *
- * @param domain_sid The domain sid aquired from the remote server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on compleation of the function.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return Normal NTSTATUS return.
- **/
-
-static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- const char *msg = "This machine will be shutdown shortly";
- uint32 timeout = 20;
-#if 0
- poptContext pc;
- int rc;
-
- struct poptOption long_options[] = {
- {"message", 'm', POPT_ARG_STRING, &msg},
- {"timeout", 't', POPT_ARG_INT, &timeout},
- {"reboot", 'r', POPT_ARG_NONE, &reboot},
- {"force", 'f', POPT_ARG_NONE, &force},
- { 0, 0, 0, 0}
- };
-
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- rc = poptGetNextOpt(pc);
-
- if (rc < -1) {
- /* an error occurred during option processing */
- DEBUG(0, ("%s: %s\n",
- poptBadOption(pc, POPT_BADOPTION_NOALIAS),
- poptStrerror(rc)));
- return NT_STATUS_INVALID_PARAMETER;
- }
-#endif
- if (opt_comment) {
- msg = opt_comment;
- }
- if (opt_timeout) {
- timeout = opt_timeout;
- }
-
- /* create an entry */
- result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
-
- if (NT_STATUS_IS_OK(result))
- DEBUG(5,("Shutdown of remote machine succeeded\n"));
- else
- DEBUG(0,("Shutdown of remote machine failed!\n"));
-
- return result;
-}
-
-/**
- * Shut down a remote RPC server
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return A shell status integer (0 for success)
- **/
-
-static int rpc_shutdown(int argc, const char **argv)
-{
- return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
- argc, argv);
-}
-
-/***************************************************************************
- NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
-
- ***************************************************************************/
-
-/**
- * Add interdomain trust account to the RPC server.
- * All parameters (except for argc and argv) are passed by run_rpc_command
- * function.
- *
- * @param domain_sid The domain sid acquired from the server
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destoyed on completion of the function.
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped
- *
- * @return normal NTSTATUS return code
- */
-
-static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- char *acct_name;
- uint16 acb_info;
- uint32 unknown, user_rid;
-
- if (argc != 2) {
- d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * Make valid trusting domain account (ie. uppercased and with '$' appended)
- */
-
- if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
- return NT_STATUS_NO_MEMORY;
- }
-
- strupper_m(acct_name);
-
- /* Get samr policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- domain_sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Create trusting domain's account */
- acb_info = ACB_DOMTRUST;
- unknown = 0xe00500b0; /* No idea what this is - a permission mask?
- mimir: yes, most probably it is */
-
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
- &user_pol, &user_rid);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- {
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- uchar pwbuf[516];
-
- encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE);
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- init_sam_user_info24(&p24, (char *)pwbuf, 24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
- &cli->user_session_key, &ctr);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("Could not set trust account password: %s\n",
- nt_errstr(result)));
- goto done;
- }
- }
-
- done:
- SAFE_FREE(acct_name);
- return result;
-}
-
-/**
- * Create interdomain trust account for a remote domain.
- *
- * @param argc standard argc
- * @param argv standard argv without initial components
- *
- * @return Integer status (0 means success)
- **/
-
-static int rpc_trustdom_add(int argc, const char **argv)
-{
- if (argc > 0) {
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
- argc, argv);
- } else {
- d_printf("Usage: net rpc trustdom add <domain>\n");
- return -1;
- }
-}
-
-
-/**
- * Delete interdomain trust account for a remote domain.
- *
- * @param argc standard argc
- * @param argv standard argv without initial components
- *
- * @return Integer status (0 means success)
- **/
-
-static int rpc_trustdom_del(int argc, const char **argv)
-{
- d_printf("Sorry, not yet implemented.\n");
- d_printf("Use 'smbpasswd -x -i' instead.\n");
- return -1;
-}
-
-
-/**
- * Establish trust relationship to a trusting domain.
- * Interdomain account must already be created on remote PDC.
- *
- * @param argc standard argc
- * @param argv standard argv without initial components
- *
- * @return Integer status (0 means success)
- **/
-
-static int rpc_trustdom_establish(int argc, const char **argv)
-{
- struct cli_state *cli;
- struct in_addr server_ip;
- POLICY_HND connect_hnd;
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
- DOM_SID *domain_sid;
- WKS_INFO_100 wks_info;
-
- char* domain_name;
- char* domain_name_pol;
- char* acct_name;
- fstring pdc_name;
-
- /*
- * Connect to \\server\ipc$ as 'our domain' account with password
- */
-
- if (argc != 1) {
- d_printf("Usage: net rpc trustdom establish <domain_name>\n");
- return -1;
- }
-
- domain_name = smb_xstrdup(argv[0]);
- strupper_m(domain_name);
-
- /* account name used at first is our domain's name with '$' */
- asprintf(&acct_name, "%s$", lp_workgroup());
- strupper_m(acct_name);
-
- /*
- * opt_workgroup will be used by connection functions further,
- * hence it should be set to remote domain name instead of ours
- */
- if (opt_workgroup) {
- opt_workgroup = smb_xstrdup(domain_name);
- };
-
- opt_user_name = acct_name;
-
- /* find the domain controller */
- if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
- DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
- return -1;
- }
-
- /* connect to ipc$ as username/password */
- nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
- if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
-
- /* Is it trusting domain account for sure ? */
- DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- }
-
- /*
- * Connect to \\server\ipc$ again (this time anonymously)
- */
-
- nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
- domain_name, nt_errstr(nt_status)));
- }
-
- /*
- * Use NetServerEnum2 to make sure we're talking to a proper server
- */
-
- if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
- DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
- for domain %s\n", domain_name));
- }
-
- /*
- * Call WksQueryInfo to check remote server's capabilities
- * note: It is now used only to get unicode domain name
- */
-
- if (!cli_nt_session_open(cli, PI_WKSSVC)) {
- DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
- return -1;
- }
-
- if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
- domain_name))) {
- DEBUG(0, ("talloc_init() failed\n"));
- cli_shutdown(cli);
- return -1;
- }
-
- nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("WksQueryInfo call failed.\n"));
- return -1;
- }
-
- if (cli->nt_pipe_fnum)
- cli_nt_session_close(cli);
-
-
- /*
- * Call LsaOpenPolicy and LsaQueryInfo
- */
-
- if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- cli_shutdown(cli);
- return -1;
- }
-
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
- cli_shutdown(cli);
- return -1;
- }
-
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
- &connect_hnd);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- }
-
- /* Querying info level 5 */
-
- nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
- 5 /* info level */, &domain_name_pol,
- &domain_sid);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- }
-
-
-
-
- /* There should be actually query info level 3 (following nt serv behaviour),
- but I still don't know if it's _really_ necessary */
-
- /*
- * Store the password in secrets db
- */
-
- if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
- wks_info.uni_lan_grp.uni_str_len, opt_password,
- *domain_sid)) {
- DEBUG(0, ("Storing password for trusted domain failed.\n"));
- return -1;
- }
-
- /*
- * Close the pipes and clean up
- */
-
- nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- }
-
- if (cli->nt_pipe_fnum)
- cli_nt_session_close(cli);
-
- talloc_destroy(mem_ctx);
-
- d_printf("Trust to domain %s established\n", domain_name);
- return 0;
-}
-
-/**
- * Revoke trust relationship to the remote domain
- *
- * @param argc standard argc
- * @param argv standard argv without initial components
- *
- * @return Integer status (0 means success)
- **/
-
-static int rpc_trustdom_revoke(int argc, const char **argv)
-{
- char* domain_name;
-
- if (argc < 1) return -1;
-
- /* generate upper cased domain name */
- domain_name = smb_xstrdup(argv[0]);
- strupper_m(domain_name);
-
- /* delete password of the trust */
- if (!trusted_domain_password_delete(domain_name)) {
- DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
- domain_name));
- return -1;
- };
-
- return 0;
-}
-
-/**
- * Usage for 'net rpc trustdom' command
- *
- * @param argc standard argc
- * @param argv standard argv without inital components
- *
- * @return Integer status returned to shell
- **/
-
-static int rpc_trustdom_usage(int argc, const char **argv)
-{
- d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
- d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
- d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
- d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
- d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
- return -1;
-}
-
-
-static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- fstring str_sid;
- sid_to_string(str_sid, domain_sid);
- d_printf("%s\n", str_sid);
- return NT_STATUS_OK;
-}
-
-
-static int rpc_trustdom_list(int argc, const char **argv)
-{
- /* common variables */
- TALLOC_CTX* mem_ctx;
- struct cli_state *cli, *remote_cli;
- NTSTATUS nt_status;
- const char *domain_name = NULL;
- DOM_SID *queried_dom_sid;
- fstring ascii_sid, padding;
- int ascii_dom_name_len;
- POLICY_HND connect_hnd;
-
- /* trusted domains listing variables */
- unsigned int num_domains, enum_ctx = 0;
- int i, pad_len, col_len = 20;
- DOM_SID *domain_sids;
- char **trusted_dom_names;
- fstring pdc_name;
- char *dummy;
-
- /* trusting domains listing variables */
- POLICY_HND domain_hnd;
- char **trusting_dom_names;
- uint32 *trusting_dom_rids;
-
- /*
- * Listing trusted domains (stored in secrets.tdb, if local)
- */
-
- mem_ctx = talloc_init("trust relationships listing");
-
- /*
- * set domain and pdc name to local samba server (default)
- * or to remote one given in command line
- */
-
- if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
- domain_name = opt_workgroup;
- opt_target_workgroup = opt_workgroup;
- } else {
- fstrcpy(pdc_name, global_myname());
- domain_name = talloc_strdup(mem_ctx, lp_workgroup());
- opt_target_workgroup = domain_name;
- };
-
- /* open \PIPE\lsarpc and open policy handle */
- if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
- DEBUG(0, ("Couldn't connect to domain controller\n"));
- return -1;
- };
-
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
- return -1;
- };
-
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
- &connect_hnd);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- /* query info level 5 to obtain sid of a domain being queried */
- nt_status = cli_lsa_query_info_policy(
- cli, mem_ctx, &connect_hnd, 5 /* info level */,
- &dummy, &queried_dom_sid);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- }
-
- /*
- * Keep calling LsaEnumTrustdom over opened pipe until
- * the end of enumeration is reached
- */
-
- d_printf("Trusted domains list:\n\n");
-
- do {
- nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
- &num_domains,
- &trusted_dom_names, &domain_sids);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- for (i = 0; i < num_domains; i++) {
- /* convert sid into ascii string */
- sid_to_string(ascii_sid, &(domain_sids[i]));
-
- /* calculate padding space for d_printf to look nicer */
- pad_len = col_len - strlen(trusted_dom_names[i]);
- padding[pad_len] = 0;
- do padding[--pad_len] = ' '; while (pad_len);
-
- d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
- };
-
- /*
- * in case of no trusted domains say something rather
- * than just display blank line
- */
- if (!num_domains) d_printf("none\n");
-
- } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
-
- /* close this connection before doing next one */
- nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- cli_nt_session_close(cli);
-
- /*
- * Listing trusting domains (stored in passdb backend, if local)
- */
-
- d_printf("\nTrusting domains list:\n\n");
-
- /*
- * Open \PIPE\samr and get needed policy handles
- */
- if (!cli_nt_session_open(cli, PI_SAMR)) {
- DEBUG(0, ("Could not initialise samr pipe\n"));
- return -1;
- };
-
- /* SamrConnect */
- nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
- &connect_hnd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- /* SamrOpenDomain - we have to open domain policy handle in order to be
- able to enumerate accounts*/
- nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
- SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
- queried_dom_sid, &domain_hnd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("Couldn't open domain object. Error was %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- /*
- * perform actual enumeration
- */
-
- enum_ctx = 0; /* reset enumeration context from last enumeration */
- do {
-
- nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
- &enum_ctx, ACB_DOMTRUST, 0xffff,
- &trusting_dom_names, &trusting_dom_rids,
- &num_domains);
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
- nt_errstr(nt_status)));
- return -1;
- };
-
- for (i = 0; i < num_domains; i++) {
-
- /*
- * get each single domain's sid (do we _really_ need this ?):
- * 1) connect to domain's pdc
- * 2) query the pdc for domain's sid
- */
-
- /* get rid of '$' tail */
- ascii_dom_name_len = strlen(trusting_dom_names[i]);
- if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
- trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
-
- /* calculate padding space for d_printf to look nicer */
- pad_len = col_len - strlen(trusting_dom_names[i]);
- padding[pad_len] = 0;
- do padding[--pad_len] = ' '; while (pad_len);
-
- /* set opt_* variables to remote domain */
- strupper_m(trusting_dom_names[i]);
- opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
- opt_target_workgroup = opt_workgroup;
-
- d_printf("%s%s", trusting_dom_names[i], padding);
-
- /* connect to remote domain controller */
- remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
- if (remote_cli) {
- /* query for domain's sid */
- if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
- d_printf("couldn't get domain's sid\n");
-
- cli_shutdown(remote_cli);
-
- } else {
- d_printf("domain controller is not responding\n");
- };
- };
-
- if (!num_domains) d_printf("none\n");
-
- } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
-
- /* close opened samr and domain policy handles */
- nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
- };
-
- nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
- };
-
- /* close samr pipe and connection to IPC$ */
- cli_nt_session_close(cli);
- cli_shutdown(cli);
-
- talloc_destroy(mem_ctx);
- return 0;
-}
-
-/**
- * Entrypoint for 'net rpc trustdom' code
- *
- * @param argc standard argc
- * @param argv standard argv without initial components
- *
- * @return Integer status (0 means success)
- */
-
-static int rpc_trustdom(int argc, const char **argv)
-{
- struct functable func[] = {
- {"add", rpc_trustdom_add},
- {"del", rpc_trustdom_del},
- {"establish", rpc_trustdom_establish},
- {"revoke", rpc_trustdom_revoke},
- {"help", rpc_trustdom_usage},
- {"list", rpc_trustdom_list},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- rpc_trustdom_usage(argc, argv);
- return -1;
- }
-
- return (net_run_function(argc, argv, func, rpc_user_usage));
-}
-
-/**
- * Check if a server will take rpc commands
- * @param flags Type of server to connect to (PDC, DMB, localhost)
- * if the host is not explicitly specified
- * @return BOOL (true means rpc supported)
- */
-BOOL net_rpc_check(unsigned flags)
-{
- struct cli_state cli;
- BOOL ret = False;
- struct in_addr server_ip;
- char *server_name = NULL;
-
- /* flags (i.e. server type) may depend on command */
- if (!net_find_server(flags, &server_ip, &server_name))
- return False;
-
- ZERO_STRUCT(cli);
- if (cli_initialise(&cli) == False)
- return False;
-
- if (!cli_connect(&cli, server_name, &server_ip))
- goto done;
- if (!attempt_netbios_session_request(&cli, global_myname(),
- server_name, &server_ip))
- goto done;
- if (!cli_negprot(&cli))
- goto done;
- if (cli.protocol < PROTOCOL_NT1)
- goto done;
-
- ret = True;
- done:
- cli_shutdown(&cli);
- return ret;
-}
-
-/* dump sam database via samsync rpc calls */
-static int rpc_samdump(int argc, const char **argv) {
- return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
- argc, argv);
-}
-
-/* syncronise sam database via samsync rpc calls */
-static int rpc_vampire(int argc, const char **argv) {
- return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
- argc, argv);
-}
-/****************************************************************************/
-
-
-/**
- * Basic usage function for 'net rpc'
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_usage(int argc, const char **argv)
-{
- d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
- d_printf(" net rpc join \t\t\tto join a domain \n");
- d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n");
- d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
- d_printf(" net rpc user \t\t\tto add, delete and list users\n");
- d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass");
- d_printf(" net rpc group \t\tto list groups\n");
- d_printf(" net rpc share \t\tto add, delete, and list shares\n");
- d_printf(" net rpc file \t\t\tto list open files\n");
- d_printf(" net rpc changetrustpw \tto change the trust account password\n");
- d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
- d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
- d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
- d_printf(" net rpc trustdom \t\tto create trusting domain's account\n"
- "\t\t\t\t\tor establish trust\n");
- d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
- d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
- d_printf("\n");
- d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
- d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
- d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
- d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
- d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
- return -1;
-}
-
-
-/**
- * Help function for 'net rpc'. Calls command specific help if requested
- * or displays usage of net rpc
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc_help(int argc, const char **argv)
-{
- struct functable func[] = {
- {"join", rpc_join_usage},
- {"user", rpc_user_usage},
- {"group", rpc_group_usage},
- {"share", rpc_share_usage},
- /*{"changetrustpw", rpc_changetrustpw_usage}, */
- {"trustdom", rpc_trustdom_usage},
- /*{"abortshutdown", rpc_shutdown_abort_usage},*/
- /*{"shutdown", rpc_shutdown_usage}, */
- {NULL, NULL}
- };
-
- if (argc == 0) {
- net_rpc_usage(argc, argv);
- return -1;
- }
-
- return (net_run_function(argc, argv, func, rpc_user_usage));
-}
-
-
-/**
- * 'net rpc' entrypoint.
- * @param argc Standard main() style argc
- * @param argv Standard main() style argv. Initial components are already
- * stripped
- **/
-
-int net_rpc(int argc, const char **argv)
-{
- struct functable func[] = {
- {"info", net_rpc_info},
- {"join", net_rpc_join},
- {"oldjoin", net_rpc_oldjoin},
- {"testjoin", net_rpc_testjoin},
- {"user", net_rpc_user},
- {"password", rpc_user_password},
- {"group", net_rpc_group},
- {"share", net_rpc_share},
- {"file", net_rpc_file},
- {"changetrustpw", net_rpc_changetrustpw},
- {"trustdom", rpc_trustdom},
- {"abortshutdown", rpc_shutdown_abort},
- {"shutdown", rpc_shutdown},
- {"samdump", rpc_samdump},
- {"vampire", rpc_vampire},
- {"getsid", net_rpc_getsid},
- {"help", net_rpc_help},
- {NULL, NULL}
- };
- return net_run_function(argc, argv, func, net_rpc_usage);
-}
diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c
deleted file mode 100644
index 52e295949e0..00000000000
--- a/source/utils/net_rpc_join.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- Distributed SMB/CIFS Server Management Utility
- Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
- Copyright (C) Tim Potter 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-/* Macro for checking RPC error codes to make things more readable */
-
-#define CHECK_RPC_ERR(rpc, msg) \
- if (!NT_STATUS_IS_OK(result = rpc)) { \
- DEBUG(0, (msg ": %s\n", nt_errstr(result))); \
- goto done; \
- }
-
-#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \
- if (!NT_STATUS_IS_OK(result = rpc)) { \
- DEBUG(0, debug_args); \
- goto done; \
- }
-
-
-/**
- * confirm that a domain join is still valid
- *
- * @return A shell status integer (0 for success)
- *
- **/
-static int net_rpc_join_ok(const char *domain)
-{
- struct cli_state *cli;
- uchar stored_md4_trust_password[16];
- int retval = 1;
- uint32 channel;
- NTSTATUS result;
-
- /* Connect to remote machine */
- if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
- return 1;
- }
-
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
- goto done;
- }
-
- if (!secrets_fetch_trust_account_password(domain,
- stored_md4_trust_password,
- NULL, &channel)) {
- DEBUG(0,("Could not retreive domain trust secret"));
- goto done;
- }
-
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, domain);
- if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, channel, stored_md4_trust_password))) {
- DEBUG(0,("Error in domain join verfication (fresh connection)\n"));
- goto done;
- }
-
- retval = 0; /* Success! */
-
-done:
- /* Close down pipe - this will clean up open policy handles */
- if (cli->nt_pipe_fnum)
- cli_nt_session_close(cli);
-
- cli_shutdown(cli);
-
- return retval;
-}
-
-/**
- * Join a domain using the administrator username and password
- *
- * @param argc Standard main() style argc
- * @param argc Standard main() style argv. Initial components are already
- * stripped. Currently not used.
- * @return A shell status integer (0 for success)
- *
- **/
-
-int net_rpc_join_newstyle(int argc, const char **argv)
-{
-
- /* libsmb variables */
-
- struct cli_state *cli;
- TALLOC_CTX *mem_ctx;
- uint32 acb_info = ACB_WSTRUST;
- uint32 sec_channel_type;
-
- /* rpc variables */
-
- POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol;
- DOM_SID *domain_sid;
- uint32 user_rid;
-
- /* Password stuff */
-
- char *clear_trust_password = NULL;
- uchar pwbuf[516];
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- SAM_USER_INFO_10 p10;
- uchar md4_trust_password[16];
-
- /* Misc */
-
- NTSTATUS result;
- int retval = 1;
- char *domain;
- uint32 num_rids, *name_types, *user_rids;
- uint32 flags = 0x3e8;
- char *acct_name;
- const char *const_acct_name;
-
- /* check what type of join */
- if (argc >= 0) {
- sec_channel_type = get_sec_channel_type(argv[0]);
- } else {
- sec_channel_type = get_sec_channel_type(NULL);
- }
-
- switch (sec_channel_type) {
- case SEC_CHAN_WKSTA:
- acb_info = ACB_WSTRUST;
- break;
- case SEC_CHAN_BDC:
- acb_info = ACB_SVRTRUST;
- break;
-#if 0
- case SEC_CHAN_DOMAIN:
- acb_info = ACB_DOMTRUST;
- break;
-#endif
- }
-
- /* Connect to remote machine */
-
- if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC)))
- return 1;
-
- if (!(mem_ctx = talloc_init("net_rpc_join_newstyle"))) {
- DEBUG(0, ("Could not initialise talloc context\n"));
- goto done;
- }
-
- /* Fetch domain sid */
-
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Error connecting to LSA pipe\n"));
- goto done;
- }
-
-
- CHECK_RPC_ERR(cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &lsa_pol),
- "error opening lsa policy handle");
-
- CHECK_RPC_ERR(cli_lsa_query_info_policy(cli, mem_ctx, &lsa_pol,
- 5, &domain, &domain_sid),
- "error querying info policy");
-
- cli_lsa_close(cli, mem_ctx, &lsa_pol);
-
- cli_nt_session_close(cli); /* Done with this pipe */
-
- /* Create domain user */
- if (!cli_nt_session_open(cli, PI_SAMR)) {
- DEBUG(0, ("Error connecting to SAM pipe\n"));
- goto done;
- }
-
- CHECK_RPC_ERR(cli_samr_connect(cli, mem_ctx,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &sam_pol),
- "could not connect to SAM database");
-
-
- CHECK_RPC_ERR(cli_samr_open_domain(cli, mem_ctx, &sam_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- domain_sid, &domain_pol),
- "could not open domain");
-
- /* Create domain user */
- acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname());
- strlower_m(acct_name);
- const_acct_name = acct_name;
-
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info,
- 0xe005000b, &user_pol,
- &user_rid);
-
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_USER_EXISTS)) {
- d_printf("Create of workstation account failed\n");
-
- /* If NT_STATUS_ACCESS_DENIED then we have a valid
- username/password combo but the user does not have
- administrator access. */
-
- if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED))
- d_printf("User specified does not have administrator privileges\n");
-
- goto done;
- }
-
- /* We *must* do this.... don't ask... */
-
- if (NT_STATUS_IS_OK(result))
- cli_samr_close(cli, mem_ctx, &user_pol);
-
- CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx,
- &domain_pol, flags,
- 1, &const_acct_name,
- &num_rids,
- &user_rids, &name_types),
- ("error looking up rid for user %s: %s\n",
- acct_name, nt_errstr(result)));
-
- if (name_types[0] != SID_NAME_USER) {
- DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0]));
- goto done;
- }
-
- user_rid = user_rids[0];
-
- /* Open handle on user */
-
- CHECK_RPC_ERR_DEBUG(
- cli_samr_open_user(cli, mem_ctx, &domain_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- user_rid, &user_pol),
- ("could not re-open existing user %s: %s\n",
- acct_name, nt_errstr(result)));
-
- /* Create a random machine account password */
-
- {
- char *str;
- str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
- clear_trust_password = strdup(str);
- E_md4hash(clear_trust_password, md4_trust_password);
- }
-
- encode_pw_buffer(pwbuf, clear_trust_password, STR_UNICODE);
-
- /* Set password on machine account */
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- init_sam_user_info24(&p24, (char *)pwbuf,24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- CHECK_RPC_ERR(cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
- &cli->user_session_key, &ctr),
- "error setting trust account password");
-
- /* Why do we have to try to (re-)set the ACB to be the same as what
- we passed in the samr_create_dom_user() call? When a NT
- workstation is joined to a domain by an administrator the
- acb_info is set to 0x80. For a normal user with "Add
- workstations to the domain" rights the acb_info is 0x84. I'm
- not sure whether it is supposed to make a difference or not. NT
- seems to cope with either value so don't bomb out if the set
- userinfo2 level 0x10 fails. -tpot */
-
- ZERO_STRUCT(ctr);
- ctr.switch_value = 0x10;
- ctr.info.id10 = &p10;
-
- init_sam_user_info10(&p10, acb_info);
-
- /* Ignoring the return value is necessary for joining a domain
- as a normal user with "Add workstation to domain" privilege. */
-
- result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10,
- &cli->user_session_key, &ctr);
-
- /* Now check the whole process from top-to-bottom */
- cli_samr_close(cli, mem_ctx, &user_pol);
- cli_nt_session_close(cli); /* Done with this pipe */
-
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
- goto done;
- }
-
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, domain);
-
- result = cli_nt_establish_netlogon(cli, sec_channel_type,
- md4_trust_password);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("Error domain join verification (reused connection): %s\n\n",
- nt_errstr(result)));
-
- if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
- (sec_channel_type == SEC_CHAN_BDC) ) {
- d_printf("Please make sure that no computer account\n"
- "named like this machine (%s) exists in the domain\n",
- global_myname());
- }
-
- goto done;
- }
-
- /* Now store the secret in the secrets database */
-
- strupper_m(domain);
-
- if (!secrets_store_domain_sid(domain, domain_sid)) {
- DEBUG(0, ("error storing domain sid for %s\n", domain));
- goto done;
- }
-
- if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) {
- DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain));
- }
-
- /* double-check, connection from scratch */
- retval = net_rpc_join_ok(domain);
-
-done:
- /* Close down pipe - this will clean up open policy handles */
-
- if (cli->nt_pipe_fnum)
- cli_nt_session_close(cli);
-
- /* Display success or failure */
-
- if (retval != 0) {
- fprintf(stderr,"Unable to join domain %s.\n",domain);
- } else {
- printf("Joined domain %s.\n",domain);
- }
-
- cli_shutdown(cli);
-
- SAFE_FREE(clear_trust_password);
-
- return retval;
-}
-
-
-/**
- * check that a join is OK
- *
- * @return A shell status integer (0 for success)
- *
- **/
-int net_rpc_testjoin(int argc, const char **argv)
-{
- char *domain = smb_xstrdup(opt_target_workgroup);
-
- /* Display success or failure */
- if (net_rpc_join_ok(domain) != 0) {
- fprintf(stderr,"Join to domain '%s' is not valid\n",domain);
- free(domain);
- return -1;
- }
-
- printf("Join to '%s' is OK\n",domain);
- free(domain);
- return 0;
-}
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
deleted file mode 100644
index 882f3a02bc2..00000000000
--- a/source/utils/net_rpc_samsync.c
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- dump the remote SAM using rpc samsync operations
-
- Copyright (C) Andrew Tridgell 2002
- Copyright (C) Tim Potter 2001,2002
- Modified by Volker Lendecke 2002
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "../utils/net.h"
-
-extern DOM_SID global_sid_Builtin;
-
-static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
-{
- int i;
- d_printf("Group mem %u: ", rid);
- for (i=0;i<g->num_members;i++) {
- d_printf("%u ", g->rids[i]);
- }
- d_printf("\n");
-}
-
-static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a)
-{
- d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name));
- d_printf("desc='%s' rid=%u\n", unistr2_static(&a->uni_als_desc), a->als_rid);
-}
-
-static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a)
-{
- int i;
- d_printf("Alias rid %u: ", rid);
- for (i=0;i<a->num_members;i++) {
- d_printf("%s ", sid_string_static(&a->sids[i].sid));
- }
- d_printf("\n");
-}
-
-static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a)
-{
- fstring hex_nt_passwd, hex_lm_passwd;
- uchar lm_passwd[16], nt_passwd[16];
- static uchar zero_buf[16];
-
- /* Decode hashes from password hash (if they are not NULL) */
-
- if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) {
- sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0);
- pdb_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info);
- } else {
- pdb_sethexpwd(hex_lm_passwd, NULL, 0);
- }
-
- if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) {
- sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0);
- pdb_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info);
- } else {
- pdb_sethexpwd(hex_nt_passwd, NULL, 0);
- }
-
- printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name),
- a->user_rid, hex_lm_passwd, hex_nt_passwd,
- pdb_encode_acct_ctrl(a->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN));
-}
-
-static void display_domain_info(SAM_DOMAIN_INFO *a)
-{
- d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name));
-}
-
-static void display_group_info(uint32 rid, SAM_GROUP_INFO *a)
-{
- d_printf("Group '%s' ", unistr2_static(&a->uni_grp_name));
- d_printf("desc='%s', rid=%u\n", unistr2_static(&a->uni_grp_desc), rid);
-}
-
-static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta)
-{
- switch (hdr_delta->type) {
- case SAM_DELTA_ACCOUNT_INFO:
- display_account_info(hdr_delta->target_rid, &delta->account_info);
- break;
- case SAM_DELTA_GROUP_MEM:
- display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info);
- break;
- case SAM_DELTA_ALIAS_INFO:
- display_alias_info(hdr_delta->target_rid, &delta->alias_info);
- break;
- case SAM_DELTA_ALIAS_MEM:
- display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info);
- break;
- case SAM_DELTA_DOMAIN_INFO:
- display_domain_info(&delta->domain_info);
- break;
- case SAM_DELTA_GROUP_INFO:
- display_group_info(hdr_delta->target_rid, &delta->group_info);
- break;
- /* The following types are recognised but not handled */
- case SAM_DELTA_RENAME_GROUP:
- d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
- break;
- case SAM_DELTA_RENAME_USER:
- d_printf("SAM_DELTA_RENAME_USER not handled\n");
- break;
- case SAM_DELTA_RENAME_ALIAS:
- d_printf("SAM_DELTA_RENAME_ALIAS not handled\n");
- break;
- case SAM_DELTA_POLICY_INFO:
- d_printf("SAM_DELTA_POLICY_INFO not handled\n");
- break;
- case SAM_DELTA_TRUST_DOMS:
- d_printf("SAM_DELTA_TRUST_DOMS not handled\n");
- break;
- case SAM_DELTA_PRIVS_INFO:
- d_printf("SAM_DELTA_PRIVS_INFO not handled\n");
- break;
- case SAM_DELTA_SECRET_INFO:
- d_printf("SAM_DELTA_SECRET_INFO not handled\n");
- break;
- case SAM_DELTA_DELETE_GROUP:
- d_printf("SAM_DELTA_DELETE_GROUP not handled\n");
- break;
- case SAM_DELTA_DELETE_USER:
- d_printf("SAM_DELTA_DELETE_USER not handled\n");
- break;
- case SAM_DELTA_MODIFIED_COUNT:
- d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n");
- break;
- default:
- d_printf("Unknown delta record type %d\n", hdr_delta->type);
- break;
- }
-}
-
-
-static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds)
-{
- unsigned sync_context = 0;
- NTSTATUS result;
- int i;
- TALLOC_CTX *mem_ctx;
- SAM_DELTA_HDR *hdr_deltas;
- SAM_DELTA_CTR *deltas;
- uint32 num_deltas;
-
- if (!(mem_ctx = talloc_init("dump_database"))) {
- return;
- }
-
- switch( db_type ) {
- case SAM_DATABASE_DOMAIN:
- d_printf("Dumping DOMAIN database\n");
- break;
- case SAM_DATABASE_BUILTIN:
- d_printf("Dumping BUILTIN database\n");
- break;
- case SAM_DATABASE_PRIVS:
- d_printf("Dumping PRIVS databases\n");
- break;
- default:
- d_printf("Dumping unknown database type %u\n", db_type );
- break;
- }
-
- do {
- result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type,
- sync_context,
- &num_deltas, &hdr_deltas, &deltas);
- if (NT_STATUS_IS_ERR(result))
- break;
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds);
- for (i = 0; i < num_deltas; i++) {
- display_sam_entry(&hdr_deltas[i], &deltas[i]);
- }
- sync_context += 1;
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- talloc_destroy(mem_ctx);
-}
-
-/* dump sam database via samsync rpc calls */
-NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- uchar trust_password[16];
- DOM_CRED ret_creds;
- uint32 sec_channel;
-
- ZERO_STRUCT(ret_creds);
-
- fstrcpy(cli->domain, domain_name);
-
- if (!secrets_fetch_trust_account_password(domain_name,
- trust_password,
- NULL, &sec_channel)) {
- DEBUG(0,("Could not fetch trust account password\n"));
- goto fail;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = cli_nt_establish_netlogon(cli, sec_channel,
- trust_password))) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
- goto fail;
- }
-
- dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds);
- dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds);
- dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds);
-
- nt_status = NT_STATUS_OK;
-
-fail:
- cli_nt_session_close(cli);
- return nt_status;
-}
-
-/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
-#define STRING_CHANGED (old_string && !new_string) ||\
- (!old_string && new_string) ||\
- (old_string && new_string && (strcmp(old_string, new_string) != 0))
-
-static NTSTATUS
-sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
-{
- const char *old_string, *new_string;
- time_t unix_time, stored_time;
- uchar lm_passwd[16], nt_passwd[16];
- static uchar zero_buf[16];
-
- /* Username, fullname, home dir, dir drive, logon script, acct
- desc, workstations, profile. */
-
- if (delta->hdr_acct_name.buffer) {
- old_string = pdb_get_nt_username(account);
- new_string = unistr2_static(&delta->uni_acct_name);
-
- if (STRING_CHANGED) {
- pdb_set_nt_username(account, new_string, PDB_CHANGED);
-
- }
-
- /* Unix username is the same - for sanity */
- old_string = pdb_get_username( account );
- if (STRING_CHANGED) {
- pdb_set_username(account, new_string, PDB_CHANGED);
- }
- }
-
- if (delta->hdr_full_name.buffer) {
- old_string = pdb_get_fullname(account);
- new_string = unistr2_static(&delta->uni_full_name);
-
- if (STRING_CHANGED)
- pdb_set_fullname(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_home_dir.buffer) {
- old_string = pdb_get_homedir(account);
- new_string = unistr2_static(&delta->uni_home_dir);
-
- if (STRING_CHANGED)
- pdb_set_homedir(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_dir_drive.buffer) {
- old_string = pdb_get_dir_drive(account);
- new_string = unistr2_static(&delta->uni_dir_drive);
-
- if (STRING_CHANGED)
- pdb_set_dir_drive(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_logon_script.buffer) {
- old_string = pdb_get_logon_script(account);
- new_string = unistr2_static(&delta->uni_logon_script);
-
- if (STRING_CHANGED)
- pdb_set_logon_script(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_acct_desc.buffer) {
- old_string = pdb_get_acct_desc(account);
- new_string = unistr2_static(&delta->uni_acct_desc);
-
- if (STRING_CHANGED)
- pdb_set_acct_desc(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_workstations.buffer) {
- old_string = pdb_get_workstations(account);
- new_string = unistr2_static(&delta->uni_workstations);
-
- if (STRING_CHANGED)
- pdb_set_workstations(account, new_string, PDB_CHANGED);
- }
-
- if (delta->hdr_profile.buffer) {
- old_string = pdb_get_profile_path(account);
- new_string = unistr2_static(&delta->uni_profile);
-
- if (STRING_CHANGED)
- pdb_set_profile_path(account, new_string, PDB_CHANGED);
- }
-
- /* User and group sid */
- if (pdb_get_user_rid(account) != delta->user_rid)
- pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED);
- if (pdb_get_group_rid(account) != delta->group_rid)
- pdb_set_group_sid_from_rid(account, delta->group_rid, PDB_CHANGED);
-
- /* Logon and password information */
- if (!nt_time_is_zero(&delta->logon_time)) {
- unix_time = nt_time_to_unix(&delta->logon_time);
- stored_time = pdb_get_logon_time(account);
- if (stored_time != unix_time)
- pdb_set_logon_time(account, unix_time, PDB_CHANGED);
- }
-
- if (!nt_time_is_zero(&delta->logoff_time)) {
- unix_time = nt_time_to_unix(&delta->logoff_time);
- stored_time = pdb_get_logoff_time(account);
- if (stored_time != unix_time)
- pdb_set_logoff_time(account, unix_time,PDB_CHANGED);
- }
-
- if (pdb_get_logon_divs(account) != delta->logon_divs)
- pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED);
-
- /* TODO: logon hours */
- /* TODO: bad password count */
- /* TODO: logon count */
-
- if (!nt_time_is_zero(&delta->pwd_last_set_time)) {
- unix_time = nt_time_to_unix(&delta->pwd_last_set_time);
- stored_time = pdb_get_pass_last_set_time(account);
- if (stored_time != unix_time)
- pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED);
- }
-
-#if 0
-/* No kickoff time in the delta? */
- if (!nt_time_is_zero(&delta->kickoff_time)) {
- unix_time = nt_time_to_unix(&delta->kickoff_time);
- stored_time = pdb_get_kickoff_time(account);
- if (stored_time != unix_time)
- pdb_set_kickoff_time(account, unix_time, PDB_CHANGED);
- }
-#endif
-
- /* Decode hashes from password hash
- Note that win2000 may send us all zeros for the hashes if it doesn't
- think this channel is secure enough - don't set the passwords at all
- in that case
- */
- if (memcmp(delta->pass.buf_lm_pwd, zero_buf, 16) != 0) {
- sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0);
- pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
- }
-
- if (memcmp(delta->pass.buf_nt_pwd, zero_buf, 16) != 0) {
- sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0);
- pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
- }
-
- /* TODO: account expiry time */
-
- if (pdb_get_acct_ctrl(account) != delta->acb_info)
- pdb_set_acct_ctrl(account, delta->acb_info, PDB_CHANGED);
-
- pdb_set_domain(account, lp_workgroup(), PDB_CHANGED);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
-{
- NTSTATUS nt_ret;
- fstring account;
- pstring add_script;
- SAM_ACCOUNT *sam_account=NULL;
- GROUP_MAP map;
- struct group *grp;
- DOM_SID user_sid;
- DOM_SID group_sid;
- struct passwd *passwd;
- fstring sid_string;
-
- fstrcpy(account, unistr2_static(&delta->uni_acct_name));
- d_printf("Creating account: %s\n", account);
-
- if (!NT_STATUS_IS_OK(nt_ret = pdb_init_sam(&sam_account)))
- return nt_ret;
-
- if (!(passwd = Get_Pwnam(account))) {
- /* Create appropriate user */
- if (delta->acb_info & ACB_NORMAL) {
- pstrcpy(add_script, lp_adduser_script());
- } else if ( (delta->acb_info & ACB_WSTRUST) ||
- (delta->acb_info & ACB_SVRTRUST) ||
- (delta->acb_info & ACB_DOMTRUST) ) {
- pstrcpy(add_script, lp_addmachine_script());
- } else {
- DEBUG(1, ("Unknown user type: %s\n",
- pdb_encode_acct_ctrl(delta->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN)));
- nt_ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- if (*add_script) {
- int add_ret;
- all_string_sub(add_script, "%u", account,
- sizeof(account));
- add_ret = smbrun(add_script,NULL);
- DEBUG(1,("fetch_account: Running the command `%s' "
- "gave %d\n", add_script, add_ret));
- } else {
- DEBUG(8,("fetch_account_info: no add user/machine script. Asking winbindd\n"));
-
- /* don't need a RID allocated since the user already has a SID */
- if ( !winbind_create_user( account, NULL ) )
- DEBUG(4,("fetch_account_info: winbind_create_user() failed\n"));
- }
-
- /* try and find the possible unix account again */
- if ( !(passwd = Get_Pwnam(account)) ) {
- d_printf("Could not create posix account info for '%s'\n", account);
- nt_ret = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
- }
-
- sid_copy(&user_sid, get_global_sam_sid());
- sid_append_rid(&user_sid, delta->user_rid);
-
- DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n", sid_to_string(sid_string, &user_sid), account));
- if (!pdb_getsampwsid(sam_account, &user_sid)) {
- sam_account_from_delta(sam_account, delta);
- DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
- sid_to_string(sid_string, &user_sid), pdb_get_username(sam_account)));
- if (!pdb_add_sam_account(sam_account)) {
- DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
- account));
- return NT_STATUS_ACCESS_DENIED;
- }
- } else {
- sam_account_from_delta(sam_account, delta);
- DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
- sid_to_string(sid_string, &user_sid), pdb_get_username(sam_account)));
- if (!pdb_update_sam_account(sam_account)) {
- DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
- account));
- pdb_free_sam(&sam_account);
- return NT_STATUS_ACCESS_DENIED;
- }
- }
-
- group_sid = *pdb_get_group_sid(sam_account);
-
- if (!pdb_getgrsid(&map, group_sid)) {
- DEBUG(0, ("Primary group of %s has no mapping!\n",
- pdb_get_username(sam_account)));
- } else {
- if (map.gid != passwd->pw_gid) {
- if (!(grp = getgrgid(map.gid))) {
- DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
- (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid)));
- } else {
- smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
- }
- }
- }
-
- if ( !passwd ) {
- DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
- pdb_get_username(sam_account)));
- }
-
- done:
- pdb_free_sam(&sam_account);
- return nt_ret;
-}
-
-static NTSTATUS
-fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
-{
- fstring name;
- fstring comment;
- struct group *grp = NULL;
- DOM_SID group_sid;
- fstring sid_string;
- GROUP_MAP map;
- BOOL insert = True;
-
- unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1);
- unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1);
-
- /* add the group to the mapping table */
- sid_copy(&group_sid, get_global_sam_sid());
- sid_append_rid(&group_sid, rid);
- sid_to_string(sid_string, &group_sid);
-
- if (pdb_getgrsid(&map, group_sid)) {
- if ( map.gid != -1 )
- grp = getgrgid(map.gid);
- insert = False;
- }
-
- if (grp == NULL) {
- gid_t gid;
-
- /* No group found from mapping, find it from its name. */
- if ((grp = getgrnam(name)) == NULL) {
-
- /* No appropriate group found, create one */
-
- d_printf("Creating unix group: '%s'\n", name);
-
- if (smb_create_group(name, &gid) != 0)
- return NT_STATUS_ACCESS_DENIED;
-
- if ((grp = getgrnam(name)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
- }
- }
-
- map.gid = grp->gr_gid;
- map.sid = group_sid;
- map.sid_name_use = SID_NAME_DOM_GRP;
- fstrcpy(map.nt_name, name);
- if (delta->hdr_grp_desc.buffer) {
- fstrcpy(map.comment, comment);
- } else {
- fstrcpy(map.comment, "");
- }
-
- if (insert)
- pdb_add_group_mapping_entry(&map);
- else
- pdb_update_group_mapping_entry(&map);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS
-fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
-{
- int i;
- TALLOC_CTX *t = NULL;
- char **nt_members = NULL;
- char **unix_members;
- DOM_SID group_sid;
- GROUP_MAP map;
- struct group *grp;
-
- if (delta->num_members == 0) {
- return NT_STATUS_OK;
- }
-
- sid_copy(&group_sid, get_global_sam_sid());
- sid_append_rid(&group_sid, rid);
-
- if (!get_domain_group_from_sid(group_sid, &map)) {
- DEBUG(0, ("Could not find global group %d\n", rid));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- if (!(grp = getgrgid(map.gid))) {
- DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- d_printf("Group members of %s: ", grp->gr_name);
-
- if (!(t = talloc_init("fetch_group_mem_info"))) {
- DEBUG(0, ("could not talloc_init\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_members = talloc_zero(t, sizeof(char *) * delta->num_members);
-
- for (i=0; i<delta->num_members; i++) {
- NTSTATUS nt_status;
- SAM_ACCOUNT *member = NULL;
- DOM_SID member_sid;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(t, &member))) {
- talloc_destroy(t);
- return nt_status;
- }
-
- sid_copy(&member_sid, get_global_sam_sid());
- sid_append_rid(&member_sid, delta->rids[i]);
-
- if (!pdb_getsampwsid(member, &member_sid)) {
- DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
- delta->rids[i], sid_string_static(&member_sid), grp->gr_name));
- pdb_free_sam(&member);
- continue;
- }
-
- if (pdb_get_group_rid(member) == rid) {
- d_printf("%s(primary),", pdb_get_username(member));
- pdb_free_sam(&member);
- continue;
- }
-
- d_printf("%s,", pdb_get_username(member));
- nt_members[i] = talloc_strdup(t, pdb_get_username(member));
- pdb_free_sam(&member);
- }
-
- d_printf("\n");
-
- unix_members = grp->gr_mem;
-
- while (*unix_members) {
- BOOL is_nt_member = False;
- for (i=0; i<delta->num_members; i++) {
- if (nt_members[i] == NULL) {
- /* This was a primary group */
- continue;
- }
-
- if (strcmp(*unix_members, nt_members[i]) == 0) {
- is_nt_member = True;
- break;
- }
- }
- if (!is_nt_member) {
- /* We look at a unix group member that is not
- an nt group member. So, remove it. NT is
- boss here. */
- smb_delete_user_group(grp->gr_name, *unix_members);
- }
- unix_members += 1;
- }
-
- for (i=0; i<delta->num_members; i++) {
- BOOL is_unix_member = False;
-
- if (nt_members[i] == NULL) {
- /* This was the primary group */
- continue;
- }
-
- unix_members = grp->gr_mem;
-
- while (*unix_members) {
- if (strcmp(*unix_members, nt_members[i]) == 0) {
- is_unix_member = True;
- break;
- }
- unix_members += 1;
- }
-
- if (!is_unix_member) {
- /* We look at a nt group member that is not a
- unix group member currently. So, add the nt
- group member. */
- smb_add_user_group(grp->gr_name, nt_members[i]);
- }
- }
-
- talloc_destroy(t);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
- DOM_SID dom_sid)
-{
- fstring name;
- fstring comment;
- struct group *grp = NULL;
- DOM_SID alias_sid;
- fstring sid_string;
- GROUP_MAP map;
- BOOL insert = True;
-
- unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)-1);
- unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)-1);
-
- /* Find out whether the group is already mapped */
- sid_copy(&alias_sid, &dom_sid);
- sid_append_rid(&alias_sid, rid);
- sid_to_string(sid_string, &alias_sid);
-
- if (pdb_getgrsid(&map, alias_sid)) {
- grp = getgrgid(map.gid);
- insert = False;
- }
-
- if (grp == NULL) {
- gid_t gid;
-
- /* No group found from mapping, find it from its name. */
- if ((grp = getgrnam(name)) == NULL) {
- /* No appropriate group found, create one */
- d_printf("Creating unix group: '%s'\n", name);
- if (smb_create_group(name, &gid) != 0)
- return NT_STATUS_ACCESS_DENIED;
- if ((grp = getgrgid(gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
- }
- }
-
- map.gid = grp->gr_gid;
- map.sid = alias_sid;
-
- if (sid_equal(&dom_sid, &global_sid_Builtin))
- map.sid_name_use = SID_NAME_WKN_GRP;
- else
- map.sid_name_use = SID_NAME_ALIAS;
-
- fstrcpy(map.nt_name, name);
- fstrcpy(map.comment, comment);
-
- if (insert)
- pdb_add_group_mapping_entry(&map);
- else
- pdb_update_group_mapping_entry(&map);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS
-fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
-{
-#if 0 /*
- * commented out right now after talking to Volker. Can't
- * do much with the membership but seemed a shame to waste
- * somewhat working code. Needs testing because the membership
- * that shows up surprises me. Also can't do much with groups
- * in groups (e.g. Domain Admins being a member of Adminsitrators).
- * --jerry
- */
-
- int i;
- TALLOC_CTX *t = NULL;
- char **nt_members = NULL;
- char **unix_members;
- DOM_SID group_sid;
- GROUP_MAP map;
- struct group *grp;
- enum SID_NAME_USE sid_type;
-
- if (delta->num_members == 0) {
- return NT_STATUS_OK;
- }
-
- sid_copy(&group_sid, &dom_sid);
- sid_append_rid(&group_sid, rid);
-
- if (sid_equal(&dom_sid, &global_sid_Builtin)) {
- sid_type = SID_NAME_WKN_GRP;
- if (!get_builtin_group_from_sid(&group_sid, &map, False)) {
- DEBUG(0, ("Could not find builtin group %s\n", sid_string_static(&group_sid)));
- return NT_STATUS_NO_SUCH_GROUP;
- }
- } else {
- sid_type = SID_NAME_ALIAS;
- if (!get_local_group_from_sid(&group_sid, &map, False)) {
- DEBUG(0, ("Could not find local group %s\n", sid_string_static(&group_sid)));
- return NT_STATUS_NO_SUCH_GROUP;
- }
- }
-
- if (!(grp = getgrgid(map.gid))) {
- DEBUG(0, ("Could not find unix group %d\n", map.gid));
- return NT_STATUS_NO_SUCH_GROUP;
- }
-
- d_printf("Group members of %s: ", grp->gr_name);
-
- if (!(t = talloc_init("fetch_group_mem_info"))) {
- DEBUG(0, ("could not talloc_init\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_members = talloc_zero(t, sizeof(char *) * delta->num_members);
-
- for (i=0; i<delta->num_members; i++) {
- NTSTATUS nt_status;
- SAM_ACCOUNT *member = NULL;
- DOM_SID member_sid;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(t, &member))) {
- talloc_destroy(t);
- return nt_status;
- }
-
- sid_copy(&member_sid, &delta->sids[i].sid);
-
- if (!pdb_getsampwsid(member, &member_sid)) {
- DEBUG(1, ("Found bogus group member: (member_sid=%s group=%s)\n",
- sid_string_static(&member_sid), grp->gr_name));
- pdb_free_sam(&member);
- continue;
- }
-
- if (pdb_get_group_rid(member) == rid) {
- d_printf("%s(primary),", pdb_get_username(member));
- pdb_free_sam(&member);
- continue;
- }
-
- d_printf("%s,", pdb_get_username(member));
- nt_members[i] = talloc_strdup(t, pdb_get_username(member));
- pdb_free_sam(&member);
- }
-
- d_printf("\n");
-
- unix_members = grp->gr_mem;
-
- while (*unix_members) {
- BOOL is_nt_member = False;
- for (i=0; i<delta->num_members; i++) {
- if (nt_members[i] == NULL) {
- /* This was a primary group */
- continue;
- }
-
- if (strcmp(*unix_members, nt_members[i]) == 0) {
- is_nt_member = True;
- break;
- }
- }
- if (!is_nt_member) {
- /* We look at a unix group member that is not
- an nt group member. So, remove it. NT is
- boss here. */
- smb_delete_user_group(grp->gr_name, *unix_members);
- }
- unix_members += 1;
- }
-
- for (i=0; i<delta->num_members; i++) {
- BOOL is_unix_member = False;
-
- if (nt_members[i] == NULL) {
- /* This was the primary group */
- continue;
- }
-
- unix_members = grp->gr_mem;
-
- while (*unix_members) {
- if (strcmp(*unix_members, nt_members[i]) == 0) {
- is_unix_member = True;
- break;
- }
- unix_members += 1;
- }
-
- if (!is_unix_member) {
- /* We look at a nt group member that is not a
- unix group member currently. So, add the nt
- group member. */
- smb_add_user_group(grp->gr_name, nt_members[i]);
- }
- }
-
- talloc_destroy(t);
-
-#endif /* end of fetch_alias_mem() */
-
- return NT_STATUS_OK;
-}
-
-static void
-fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
- DOM_SID dom_sid)
-{
- switch(hdr_delta->type) {
- case SAM_DELTA_ACCOUNT_INFO:
- fetch_account_info(hdr_delta->target_rid,
- &delta->account_info);
- break;
- case SAM_DELTA_GROUP_INFO:
- fetch_group_info(hdr_delta->target_rid,
- &delta->group_info);
- break;
- case SAM_DELTA_GROUP_MEM:
- fetch_group_mem_info(hdr_delta->target_rid,
- &delta->grp_mem_info);
- break;
- case SAM_DELTA_ALIAS_INFO:
- fetch_alias_info(hdr_delta->target_rid,
- &delta->alias_info, dom_sid);
- break;
- case SAM_DELTA_ALIAS_MEM:
- fetch_alias_mem(hdr_delta->target_rid,
- &delta->als_mem_info, dom_sid);
- break;
- /* The following types are recognised but not handled */
- case SAM_DELTA_DOMAIN_INFO:
- d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
- break;
- case SAM_DELTA_RENAME_GROUP:
- d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
- break;
- case SAM_DELTA_RENAME_USER:
- d_printf("SAM_DELTA_RENAME_USER not handled\n");
- break;
- case SAM_DELTA_RENAME_ALIAS:
- d_printf("SAM_DELTA_RENAME_ALIAS not handled\n");
- break;
- case SAM_DELTA_POLICY_INFO:
- d_printf("SAM_DELTA_POLICY_INFO not handled\n");
- break;
- case SAM_DELTA_TRUST_DOMS:
- d_printf("SAM_DELTA_TRUST_DOMS not handled\n");
- break;
- case SAM_DELTA_PRIVS_INFO:
- d_printf("SAM_DELTA_PRIVS_INFO not handled\n");
- break;
- case SAM_DELTA_SECRET_INFO:
- d_printf("SAM_DELTA_SECRET_INFO not handled\n");
- break;
- case SAM_DELTA_DELETE_GROUP:
- d_printf("SAM_DELTA_DELETE_GROUP not handled\n");
- break;
- case SAM_DELTA_DELETE_USER:
- d_printf("SAM_DELTA_DELETE_USER not handled\n");
- break;
- case SAM_DELTA_MODIFIED_COUNT:
- d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n");
- break;
- default:
- d_printf("Unknown delta record type %d\n", hdr_delta->type);
- break;
- }
-}
-
-static NTSTATUS
-fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
- DOM_SID dom_sid)
-{
- unsigned sync_context = 0;
- NTSTATUS result;
- int i;
- TALLOC_CTX *mem_ctx;
- SAM_DELTA_HDR *hdr_deltas;
- SAM_DELTA_CTR *deltas;
- uint32 num_deltas;
-
- if (!(mem_ctx = talloc_init("fetch_database")))
- return NT_STATUS_NO_MEMORY;
-
- switch( db_type ) {
- case SAM_DATABASE_DOMAIN:
- d_printf("Fetching DOMAIN database\n");
- break;
- case SAM_DATABASE_BUILTIN:
- d_printf("Fetching BUILTIN database\n");
- break;
- case SAM_DATABASE_PRIVS:
- d_printf("Fetching PRIVS databases\n");
- break;
- default:
- d_printf("Fetching unknown database type %u\n", db_type );
- break;
- }
-
- do {
- result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds,
- db_type, sync_context,
- &num_deltas,
- &hdr_deltas, &deltas);
-
- if (NT_STATUS_IS_OK(result) ||
- NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
- ret_creds);
-
- for (i = 0; i < num_deltas; i++) {
- fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
- }
- } else
- return result;
-
- sync_context += 1;
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
-
- talloc_destroy(mem_ctx);
-
- return result;
-}
-
-/* dump sam database via samsync rpc calls */
-NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- NTSTATUS result;
- uchar trust_password[16];
- DOM_CRED ret_creds;
- fstring my_dom_sid_str;
- fstring rem_dom_sid_str;
- uint32 sec_channel;
-
- ZERO_STRUCT(ret_creds);
-
- if (!sid_equal(domain_sid, get_global_sam_sid())) {
- d_printf("Cannot import users from %s at this time, "
- "as the current domain:\n\t%s: %s\nconflicts "
- "with the remote domain\n\t%s: %s\n"
- "Perhaps you need to set: \n\n\tsecurity=user\n\tworkgroup=%s\n\n in your smb.conf?\n",
- domain_name,
- get_global_sam_name(), sid_to_string(my_dom_sid_str,
- get_global_sam_sid()),
- domain_name, sid_to_string(rem_dom_sid_str, domain_sid),
- domain_name);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fstrcpy(cli->domain, domain_name);
-
- if (!secrets_fetch_trust_account_password(domain_name,
- trust_password, NULL,
- &sec_channel)) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- d_printf("Could not retrieve domain trust secret\n");
- goto fail;
- }
-
- result = cli_nt_establish_netlogon(cli, sec_channel, trust_password);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Failed to setup BDC creds\n");
- goto fail;
- }
-
- result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, *domain_sid);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Failed to fetch domain database: %s\n",
- nt_errstr(result));
- if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED))
- d_printf("Perhaps %s is a Windows 2000 native mode "
- "domain?\n", domain_name);
- goto fail;
- }
-
- result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds,
- global_sid_Builtin);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Failed to fetch builtin database: %s\n",
- nt_errstr(result));
- goto fail;
- }
-
- /* Currently we crash on PRIVS somewhere in unmarshalling */
- /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
-
-fail:
- return result;
-}
diff --git a/source/utils/net_status.c b/source/utils/net_status.c
deleted file mode 100644
index 0543f457cfc..00000000000
--- a/source/utils/net_status.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net status command -- possible replacement for smbstatus
- Copyright (C) 2003 Volker Lendecke (vl@samba.org)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- BOOL *parseable = (BOOL *)state;
- struct sessionid sessionid;
-
- if (dbuf.dsize != sizeof(sessionid))
- return 0;
-
- memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
-
- if (!process_exists(sessionid.pid)) {
- return 0;
- }
-
- if (*parseable) {
- d_printf("%d\\%s\\%s\\%s\\%s\n",
- (int)sessionid.pid, uidtoname(sessionid.uid),
- gidtoname(sessionid.gid),
- sessionid.remote_machine, sessionid.hostname);
- } else {
- d_printf("%5d %-12s %-12s %-12s (%s)\n",
- (int)sessionid.pid, uidtoname(sessionid.uid),
- gidtoname(sessionid.gid),
- sessionid.remote_machine, sessionid.hostname);
- }
-
- return 0;
-}
-
-static int net_status_sessions(int argc, const char **argv)
-{
- TDB_CONTEXT *tdb;
- BOOL parseable;
-
- if (argc == 0) {
- parseable = False;
- } else if ((argc == 1) && strequal(argv[0], "parseable")) {
- parseable = True;
- } else {
- return net_help_status(argc, argv);
- }
-
- if (!parseable) {
- d_printf("PID Username Group Machine"
- " \n");
- d_printf("-------------------------------------------"
- "------------------------\n");
- }
-
- tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (tdb == NULL) {
- d_printf("%s not initialised\n", lock_path("sessionid.tdb"));
- return -1;
- }
-
- tdb_traverse(tdb, show_session, &parseable);
- tdb_close(tdb);
-
- return 0;
-}
-
-static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- struct connections_data crec;
-
- if (dbuf.dsize != sizeof(crec))
- return 0;
-
- memcpy(&crec, dbuf.dptr, sizeof(crec));
-
- if (crec.cnum == -1)
- return 0;
-
- if (!process_exists(crec.pid)) {
- return 0;
- }
-
- d_printf("%-10.10s %5d %-12s %s",
- crec.name,(int)crec.pid,
- crec.machine,
- asctime(LocalTime(&crec.start)));
-
- return 0;
-}
-
-struct sessionids {
- int num_entries;
- struct sessionid *entries;
-};
-
-static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- struct sessionids *ids = (struct sessionids *)state;
- struct sessionid sessionid;
-
- if (dbuf.dsize != sizeof(sessionid))
- return 0;
-
- memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
-
- if (!process_exists(sessionid.pid))
- return 0;
-
- ids->num_entries += 1;
- ids->entries = Realloc(ids->entries,
- sizeof(struct sessionid) * ids->num_entries);
- ids->entries[ids->num_entries-1] = sessionid;
-
- return 0;
-}
-
-static int show_share_parseable(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
-{
- struct sessionids *ids = (struct sessionids *)state;
- struct connections_data crec;
- int i;
- BOOL guest = True;
-
- if (dbuf.dsize != sizeof(crec))
- return 0;
-
- memcpy(&crec, dbuf.dptr, sizeof(crec));
-
- if (crec.cnum == -1)
- return 0;
-
- if (!process_exists(crec.pid)) {
- return 0;
- }
-
- for (i=0; i<ids->num_entries; i++) {
- if (ids->entries[i].pid == crec.pid) {
- guest = False;
- break;
- }
- }
-
- d_printf("%s\\%d\\%s\\%s\\%s\\%s\\%s",
- crec.name,(int)crec.pid,
- guest ? "" : uidtoname(ids->entries[i].uid),
- guest ? "" : gidtoname(ids->entries[i].gid),
- crec.machine,
- guest ? "" : ids->entries[i].hostname,
- asctime(LocalTime(&crec.start)));
-
- return 0;
-}
-
-static int net_status_shares_parseable(int argc, const char **argv)
-{
- struct sessionids ids;
- TDB_CONTEXT *tdb;
-
- ids.num_entries = 0;
- ids.entries = NULL;
-
- tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (tdb == NULL) {
- d_printf("%s not initialised\n", lock_path("sessionid.tdb"));
- return -1;
- }
-
- tdb_traverse(tdb, collect_pid, &ids);
- tdb_close(tdb);
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (tdb == NULL) {
- d_printf("%s not initialised\n", lock_path("connections.tdb"));
- d_printf("This is normal if no SMB client has ever connected "
- "to your server.\n");
- return -1;
- }
-
- tdb_traverse(tdb, show_share_parseable, &ids);
- tdb_close(tdb);
-
- SAFE_FREE(ids.entries);
-
- return 0;
-}
-
-static int net_status_shares(int argc, const char **argv)
-{
- TDB_CONTEXT *tdb;
-
- if (argc == 0) {
-
- d_printf("\nService pid machine "
- "Connected at\n");
- d_printf("-------------------------------------"
- "------------------\n");
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
-
- if (tdb == NULL) {
- d_printf("%s not initialised\n",
- lock_path("connections.tdb"));
- d_printf("This is normal if no SMB client has ever "
- "connected to your server.\n");
- return -1;
- }
-
- tdb_traverse(tdb, show_share, NULL);
- tdb_close(tdb);
-
- return 0;
- }
-
- if ((argc != 1) || !strequal(argv[0], "parseable")) {
- return net_help_status(argc, argv);
- }
-
- return net_status_shares_parseable(argc, argv);
-}
-
-int net_status(int argc, const char **argv)
-{
- struct functable func[] = {
- {"sessions", net_status_sessions},
- {"shares", net_status_shares},
- {NULL, NULL}
- };
- return net_run_function(argc, argv, func, net_help_status);
-}
diff --git a/source/utils/net_time.c b/source/utils/net_time.c
deleted file mode 100644
index 45c17838055..00000000000
--- a/source/utils/net_time.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- Samba Unix/Linux SMB client library
- net time command
- Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "../utils/net.h"
-
-
-/*
- return the time on a server. This does not require any authentication
-*/
-static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
-{
- struct nmb_name calling, called;
- time_t ret = 0;
- struct cli_state *cli = NULL;
-
- cli = cli_initialise(NULL);
- if (!cli) goto done;
-
- if (!cli_connect(cli, host, ip)) {
- fprintf(stderr,"Can't contact server\n");
- goto done;
- }
-
- make_nmb_name(&calling, global_myname(), 0x0);
- if (host) {
- make_nmb_name(&called, host, 0x20);
- } else {
- make_nmb_name(&called, "*SMBSERVER", 0x20);
- }
-
- if (!cli_session_request(cli, &calling, &called)) {
- fprintf(stderr,"Session request failed\n");
- goto done;
- }
- if (!cli_negprot(cli)) {
- fprintf(stderr,"Protocol negotiation failed\n");
- goto done;
- }
-
- ret = cli->servertime;
- if (zone) *zone = cli->serverzone;
-
-done:
- if (cli) cli_shutdown(cli);
- return ret;
-}
-
-/* find the servers time on the opt_host host */
-static time_t nettime(int *zone)
-{
- return cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, zone);
-}
-
-/* return a time as a string ready to be passed to /bin/date */
-static char *systime(time_t t)
-{
- static fstring s;
- struct tm *tm;
-
- tm = localtime(&t);
-
- fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
- tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
- tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
- return s;
-}
-
-int net_time_usage(int argc, const char **argv)
-{
- d_printf(
-"net time\n\tdisplays time on a server\n\n"\
-"net time system\n\tdisplays time on a server in a format ready for /bin/date\n\n"\
-"net time set\n\truns /bin/date with the time from the server\n\n"\
-"net time zone\n\tdisplays the timezone in hours from GMT on the remote computer\n\n"\
-"\n");
- net_common_flags_usage(argc, argv);
- return -1;
-}
-
-/* try to set the system clock using /bin/date */
-static int net_time_set(int argc, const char **argv)
-{
- time_t t = nettime(NULL);
- char *cmd;
-
- if (t == 0) return -1;
-
- /* yes, I know this is cheesy. Use "net time system" if you want to
- roll your own. I'm putting this in as it works on a large number
- of systems and the user has a choice in whether its used or not */
- asprintf(&cmd, "/bin/date %s", systime(t));
- system(cmd);
- free(cmd);
-
- return 0;
-}
-
-/* display the time on a remote box in a format ready for /bin/date */
-static int net_time_system(int argc, const char **argv)
-{
- time_t t = nettime(NULL);
-
- if (t == 0) return -1;
-
- printf("%s\n", systime(t));
-
- return 0;
-}
-
-/* display the time on a remote box in a format ready for /bin/date */
-static int net_time_zone(int argc, const char **argv)
-{
- int zone = 0;
- int hours, mins;
- char zsign;
- time_t t;
-
- t = nettime(&zone);
-
- if (t == 0) return -1;
-
- zsign = (zone > 0) ? '-' : '+';
- if (zone < 0) zone = -zone;
-
- zone /= 60;
- hours = zone / 60;
- mins = zone % 60;
-
- printf("%c%02d%02d\n", zsign, hours, mins);
-
- return 0;
-}
-
-/* display or set the time on a host */
-int net_time(int argc, const char **argv)
-{
- time_t t;
- struct functable func[] = {
- {"SYSTEM", net_time_system},
- {"SET", net_time_set},
- {"ZONE", net_time_zone},
- {NULL, NULL}
- };
-
- if (!opt_host && !opt_have_ip &&
- !find_master_ip(opt_target_workgroup, &opt_dest_ip)) {
- d_printf("Could not locate a time server. Try "\
- "specifying a target host.\n");
- net_time_usage(argc,argv);
- return -1;
- }
-
- if (argc != 0) {
- return net_run_function(argc, argv, func, net_time_usage);
- }
-
- /* default - print the time */
- t = cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, NULL);
- if (t == 0) return -1;
-
- d_printf("%s", ctime(&t));
- return 0;
-}
diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c
index 3c5a22841ea..4fffed74fd9 100644
--- a/source/utils/nmblookup.c
+++ b/source/utils/nmblookup.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
NBT client - used to lookup netbios names
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Jelmer Vernooij 2003 (Conversion to popt)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -55,6 +55,31 @@ static BOOL open_sockets(void)
return True;
}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(void)
+{
+ printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n");
+ printf("Version %s\n",VERSION);
+ printf("\t-d debuglevel set the debuglevel\n");
+ printf("\t-B broadcast address the address to use for broadcasts\n");
+ printf("\t-f lists flags returned from a name query\n");
+ printf("\t-U unicast address the address to use for unicast\n");
+ printf("\t-M searches for a master browser\n");
+ printf("\t-R set recursion desired in packet\n");
+ printf("\t-S lookup node status as well\n");
+ printf("\t-T translate IP addresses into names\n");
+ printf("\t-r Use root port 137 (Win95 only replies to this)\n");
+ printf("\t-A Do a node status on <name> as an IP Address\n");
+ printf("\t-i NetBIOS scope Use the given NetBIOS scope for name queries\n");
+ printf("\t-s smb.conf file Use the given path to the smb.conf file\n");
+ printf("\t-h Print this help message.\n");
+ printf("\n If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n");
+ printf("\n");
+}
+
/****************************************************************************
turn a node status flags field into a string
****************************************************************************/
@@ -97,73 +122,73 @@ static char *query_flags(int flags)
/****************************************************************************
do a node status query
****************************************************************************/
-static void do_node_status(int fd, const char *name, int type, struct in_addr ip)
+static void do_node_status(int fd, char *name, int type, struct in_addr ip)
{
struct nmb_name nname;
int count, i, j;
struct node_status *status;
fstring cleanname;
- d_printf("Looking up status of %s\n",inet_ntoa(ip));
+ printf("Looking up status of %s\n",inet_ntoa(ip));
make_nmb_name(&nname, name, type);
status = node_status_query(fd,&nname,ip, &count);
if (status) {
for (i=0;i<count;i++) {
- pull_ascii_fstring(cleanname, status[i].name);
+ fstrcpy(cleanname, status[i].name);
for (j=0;cleanname[j];j++) {
if (!isprint((int)cleanname[j])) cleanname[j] = '.';
}
- d_printf("\t%-15s <%02x> - %s\n",
+ printf("\t%-15s <%02x> - %s\n",
cleanname,status[i].type,
node_status_flags(status[i].flags));
}
SAFE_FREE(status);
}
- d_printf("\n");
+ printf("\n");
}
/****************************************************************************
send out one query
****************************************************************************/
-static BOOL query_one(const char *lookup, unsigned int lookup_type)
+static BOOL query_one(char *lookup, unsigned int lookup_type)
{
- int j, count, flags = 0;
+ int j, count, flags;
struct in_addr *ip_list=NULL;
if (got_bcast) {
- d_printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
+ printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
use_bcast?True:recursion_desired,
- bcast_addr,&count, &flags, NULL);
+ bcast_addr,&count, &flags);
} else {
struct in_addr *bcast;
for (j=iface_count() - 1;
!ip_list && j >= 0;
j--) {
bcast = iface_n_bcast(j);
- d_printf("querying %s on %s\n",
+ printf("querying %s on %s\n",
lookup, inet_ntoa(*bcast));
ip_list = name_query(ServerFD,lookup,lookup_type,
use_bcast,
use_bcast?True:recursion_desired,
- *bcast,&count, &flags, NULL);
+ *bcast,&count, &flags);
}
}
- if (!ip_list) return False;
-
if (give_flags)
- d_printf("Flags: %s\n", query_flags(flags));
+ printf("Flags: %s\n", query_flags(flags));
+
+ if (!ip_list) return False;
for (j=0;j<count;j++) {
if (translate_addresses) {
struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
if (host) {
- d_printf("%s, ", host -> h_name);
+ printf("%s, ", host -> h_name);
}
}
- d_printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
+ printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
}
/* We can only do find_status if the ip address returned
@@ -186,107 +211,131 @@ int main(int argc,char *argv[])
{
int opt;
unsigned int lookup_type = 0x0;
- fstring lookup;
- static BOOL find_master=False;
- static BOOL lookup_by_ip = False;
- poptContext pc;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
- { "flags", 'f', POPT_ARG_VAL, &give_flags, True, "List the NMB flags returned" },
- { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
- { "master-browser", 'M', POPT_ARG_VAL, &find_master, True, "Search for a master browser" },
- { "recursion", 'R', POPT_ARG_VAL, &recursion_desired, True, "Set recursion desired in package" },
- { "status", 'S', POPT_ARG_VAL, &find_status, True, "Lookup node status as well" },
- { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
- { "root-port", 'r', POPT_ARG_VAL, &RootPort, True, "Use root port 137 (Win95 only replies to this)" },
- { "lookup-by-ip", 'A', POPT_ARG_VAL, &lookup_by_ip, True, "Do a node status on <name> as an IP Address" },
- POPT_COMMON_SAMBA
- POPT_COMMON_CONNECTION
- { 0, 0, 0, 0 }
- };
-
- *lookup = 0;
+ pstring lookup;
+ extern int optind;
+ extern char *optarg;
+ BOOL find_master=False;
+ int i;
+ static pstring servicesf = CONFIGFILE;
+ BOOL lookup_by_ip = False;
+
+ DEBUGLEVEL = 1;
+ /* Prevent smb.conf setting from overridding */
+ AllowDebugChange = False;
- setup_logging(argv[0],True);
+ *lookup = 0;
- pc = poptGetContext("nmblookup", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- poptSetOtherOptionHelp(pc, "<NODE> ...");
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'B':
- bcast_addr = *interpret_addr2(poptGetOptArg(pc));
- got_bcast = True;
- use_bcast = True;
- break;
- case 'U':
- bcast_addr = *interpret_addr2(poptGetOptArg(pc));
- got_bcast = True;
- use_bcast = False;
- break;
- case 'T':
- translate_addresses = !translate_addresses;
- break;
- }
- }
+ TimeInit();
- poptGetArg(pc); /* Remove argv[0] */
+ setup_logging(argv[0],True);
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
+ charset_initialise();
+
+ while ((opt = getopt(argc, argv, "d:fB:U:i:s:SMrhART")) != EOF)
+ switch (opt)
+ {
+ case 'B':
+ bcast_addr = *interpret_addr2(optarg);
+ got_bcast = True;
+ use_bcast = True;
+ break;
+ case 'f':
+ give_flags = True;
+ break;
+ case 'U':
+ bcast_addr = *interpret_addr2(optarg);
+ got_bcast = True;
+ use_bcast = False;
+ break;
+ case 'T':
+ translate_addresses = !translate_addresses;
+ break;
+ case 'i':
+ {
+ extern pstring global_scope;
+ pstrcpy(global_scope,optarg);
+ strupper(global_scope);
+ }
+ break;
+ case 'M':
+ find_master = True;
+ break;
+ case 'S':
+ find_status = True;
+ break;
+ case 'R':
+ recursion_desired = True;
+ break;
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
+ case 'r':
+ RootPort = True;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ break;
+ case 'A':
+ lookup_by_ip = True;
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+
+ if (argc < 2) {
+ usage();
+ exit(1);
}
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
load_interfaces();
if (!open_sockets()) return(1);
- while(poptPeekArg(pc))
+ for (i=optind;i<argc;i++)
{
- char *p;
- struct in_addr ip;
-
- fstrcpy(lookup,poptGetArg(pc));
-
- if(lookup_by_ip)
- {
- ip = *interpret_addr2(lookup);
- fstrcpy(lookup,"*");
- do_node_status(ServerFD, lookup, lookup_type, ip);
- continue;
- }
-
- if (find_master) {
- if (*lookup == '-') {
- fstrcpy(lookup,"\01\02__MSBROWSE__\02");
- lookup_type = 1;
- } else {
- lookup_type = 0x1d;
- }
- }
-
- p = strchr_m(lookup,'#');
- if (p) {
- *p = '\0';
- sscanf(++p,"%x",&lookup_type);
- }
-
- if (!query_one(lookup, lookup_type)) {
- d_printf( "name_query failed to find name %s", lookup );
- if( 0 != lookup_type )
- d_printf( "#%02x", lookup_type );
- d_printf( "\n" );
- }
+ char *p;
+ struct in_addr ip;
+
+ fstrcpy(lookup,argv[i]);
+
+ if(lookup_by_ip)
+ {
+ fstrcpy(lookup,"*");
+ ip = *interpret_addr2(argv[i]);
+ do_node_status(ServerFD, lookup, lookup_type, ip);
+ continue;
+ }
+
+ if (find_master) {
+ if (*lookup == '-') {
+ fstrcpy(lookup,"\01\02__MSBROWSE__\02");
+ lookup_type = 1;
+ } else {
+ lookup_type = 0x1d;
+ }
+ }
+
+ p = strchr(lookup,'#');
+ if (p) {
+ *p = '\0';
+ sscanf(++p,"%x",&lookup_type);
+ }
+
+ if (!query_one(lookup, lookup_type)) {
+ printf( "name_query failed to find name %s", lookup );
+ if( 0 != lookup_type )
+ printf( "#%02x", lookup_type );
+ printf( "\n" );
+ }
}
-
- poptFreeContext(pc);
-
+
return(0);
}
diff --git a/source/utils/nsstest.c b/source/utils/nsstest.c
new file mode 100755
index 00000000000..76108876dff
--- /dev/null
+++ b/source/utils/nsstest.c
@@ -0,0 +1,302 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ nss tester for winbindd
+ Copyright (C) Andrew Tridgell 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static char *so_path = "/lib/libnss_winbind.so";
+static int nss_errno;
+
+static void *find_fn(const char *name)
+{
+ static void *h;
+ void *res;
+ if (!h) {
+ h = dlopen(so_path, RTLD_LAZY);
+ }
+ if (!h) {
+ printf("Can't open shared library %s\n", so_path);
+ exit(1);
+ }
+ res = dlsym(h, name);
+ if (!res) {
+ printf("Can't find function %s\n", name);
+ exit(1);
+ }
+ return res;
+}
+
+static void report_nss_error(NSS_STATUS status)
+{
+ if (status >= NSS_STATUS_SUCCESS) return;
+ printf("NSS_STATUS=%d %d\n", status, NSS_STATUS_SUCCESS);
+}
+
+static struct passwd *nss_getpwent(void)
+{
+ NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getpwent_r");
+ static struct passwd pwd;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &pwd;
+}
+
+static struct passwd *nss_getpwnam(const char *name)
+{
+ NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getpwnam_r");
+ static struct passwd pwd;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &pwd;
+}
+
+static struct passwd *nss_getpwuid(uid_t uid)
+{
+ NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getpwuid_r");
+ static struct passwd pwd;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &pwd;
+}
+
+static void nss_setpwent(void)
+{
+ NSS_STATUS (*_nss_setpwent)(void) = find_fn("_nss_winbind_setpwent");
+
+ report_nss_error(_nss_setpwent());
+}
+
+static void nss_endpwent(void)
+{
+ NSS_STATUS (*_nss_endpwent)(void) = find_fn("_nss_winbind_endpwent");
+
+ report_nss_error(_nss_endpwent());
+}
+
+
+static struct group *nss_getgrent(void)
+{
+ NSS_STATUS (*_nss_getgrent_r)(struct group *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getgrent_r");
+ static struct group grp;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getgrent_r(&grp, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &grp;
+}
+
+static struct group *nss_getgrnam(const char *name)
+{
+ NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getgrnam_r");
+ static struct group grp;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getgrnam_r(name, &grp, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &grp;
+}
+
+static struct group *nss_getgrgid(gid_t gid)
+{
+ NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *,
+ size_t , int *) = find_fn("_nss_winbind_getgrgid_r");
+ static struct group grp;
+ static char buf[1000];
+ NSS_STATUS status;
+
+ status = _nss_getgrgid_r(gid, &grp, buf, sizeof(buf), &nss_errno);
+ if (status == NSS_STATUS_NOTFOUND) {
+ return NULL;
+ }
+ if (status == NSS_STATUS_RETURN) {
+ report_nss_error(status);
+ return NULL;
+ }
+ return &grp;
+}
+
+static void nss_setgrent(void)
+{
+ NSS_STATUS (*_nss_setgrent)(void) = find_fn("_nss_winbind_setgrent");
+
+ report_nss_error(_nss_setgrent());
+}
+
+static void nss_endgrent(void)
+{
+ NSS_STATUS (*_nss_endgrent)(void) = find_fn("_nss_winbind_endgrent");
+
+ report_nss_error(_nss_endgrent());
+}
+
+static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *start, long int *size)
+{
+ NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
+ long int *, gid_t **, long int , int *) =
+ find_fn("_nss_winbind_initgroups_dyn");
+ NSS_STATUS status;
+
+ status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
+ report_nss_error(status);
+ return status;
+}
+
+static void print_passwd(struct passwd *pwd)
+{
+ printf("%s:%s:%d:%d:%s:%s:%s\n",
+ pwd->pw_name,
+ pwd->pw_passwd,
+ pwd->pw_uid,
+ pwd->pw_gid,
+ pwd->pw_gecos,
+ pwd->pw_dir,
+ pwd->pw_shell);
+}
+
+static void print_group(struct group *grp)
+{
+ int i;
+ printf("%s:%s:%d: ",
+ grp->gr_name,
+ grp->gr_passwd,
+ grp->gr_gid);
+
+ if (!grp->gr_mem[0]) {
+ printf("\n");
+ return;
+ }
+
+ for (i=0; grp->gr_mem[i+1]; i++) {
+ printf("%s, ", grp->gr_mem[i]);
+ }
+ printf("%s\n", grp->gr_mem[i]);
+}
+
+static void nss_test_initgroups(char *name, gid_t gid)
+{
+ long int size = 16;
+ long int start = 1;
+ gid_t *groups = NULL;
+ int i;
+
+ groups = (gid_t *)malloc(size * sizeof(gid_t));
+ groups[0] = gid;
+
+ nss_initgroups(name, gid, &groups, &start, &size);
+ for (i=0; i<start-1; i++) {
+ printf("%d, ", groups[i]);
+ }
+ printf("%d\n", groups[i]);
+}
+
+
+static void nss_test_users(void)
+{
+ struct passwd *pwd;
+
+ nss_setpwent();
+ /* loop over all users */
+ while ((pwd = nss_getpwent())) {
+ printf("Testing user %s\n", pwd->pw_name);
+ printf("getpwent: "); print_passwd(pwd);
+ pwd = nss_getpwnam(pwd->pw_name);
+ printf("getpwnam: "); print_passwd(pwd);
+ pwd = nss_getpwuid(pwd->pw_uid);
+ printf("getpwuid: "); print_passwd(pwd);
+ printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
+ printf("\n");
+ }
+ nss_endpwent();
+}
+
+static void nss_test_groups(void)
+{
+ struct group *grp;
+
+ nss_setgrent();
+ /* loop over all groups */
+ while ((grp = nss_getgrent())) {
+ printf("Testing group %s\n", grp->gr_name);
+ printf("getgrent: "); print_group(grp);
+ grp = nss_getgrnam(grp->gr_name);
+ printf("getgrnam: "); print_group(grp);
+ grp = nss_getgrgid(grp->gr_gid);
+ printf("getgrgid: "); print_group(grp);
+ printf("\n");
+ }
+ nss_endgrent();
+}
+
+
+ int main(int argc, char *argv[])
+{
+ if (argc > 1) so_path = argv[1];
+
+ nss_test_users();
+ nss_test_groups();
+
+ return 0;
+}
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
deleted file mode 100644
index 45a919c5841..00000000000
--- a/source/utils/ntlm_auth.c
+++ /dev/null
@@ -1,2246 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind status program.
-
- Copyright (C) Tim Potter 2000-2003
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
- Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-#define SQUID_BUFFER_SIZE 2010
-
-enum stdio_helper_mode {
- SQUID_2_4_BASIC,
- SQUID_2_5_BASIC,
- SQUID_2_5_NTLMSSP,
- NTLMSSP_CLIENT_1,
- GSS_SPNEGO,
- GSS_SPNEGO_CLIENT,
- NUM_HELPER_MODES
-};
-
-enum ntlm_break {
- BREAK_NONE,
- BREAK_LM,
- BREAK_NT,
- NO_LM,
- NO_NT
-};
-
-typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static const struct {
- enum stdio_helper_mode mode;
- const char *name;
- stdio_helper_function fn;
-} stdio_helper_protocols[] = {
- { SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request},
- { SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request},
- { SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request},
- { NTLMSSP_CLIENT_1, "ntlmssp-client-1", manage_client_ntlmssp_request},
- { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request},
- { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request},
- { NUM_HELPER_MODES, NULL, NULL}
-};
-
-extern int winbindd_fd;
-
-static const char *opt_username;
-static const char *opt_domain;
-static const char *opt_workstation;
-static const char *opt_password;
-static DATA_BLOB opt_challenge;
-static DATA_BLOB opt_lm_response;
-static DATA_BLOB opt_nt_response;
-static int request_lm_key;
-static int request_user_session_key;
-
-static const char *require_membership_of;
-static const char *require_membership_sid;
-
-static char winbind_separator(void)
-{
- struct winbindd_response response;
- static BOOL got_sep;
- static char sep;
-
- if (got_sep)
- return sep;
-
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- if (winbindd_request(WINBINDD_INFO, NULL, &response) !=
- NSS_STATUS_SUCCESS) {
- d_printf("could not obtain winbind separator!\n");
- return *lp_winbind_separator();
- }
-
- sep = response.data.info.winbind_separator;
- got_sep = True;
-
- if (!sep) {
- d_printf("winbind separator was NULL!\n");
- return *lp_winbind_separator();
- }
-
- return sep;
-}
-
-static const char *get_winbind_domain(void)
-{
- struct winbindd_response response;
-
- static fstring winbind_domain;
- if (*winbind_domain) {
- return winbind_domain;
- }
-
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
- NSS_STATUS_SUCCESS) {
- DEBUG(0, ("could not obtain winbind domain name!\n"));
- return lp_workgroup();
- }
-
- fstrcpy(winbind_domain, response.data.domain_name);
-
- return winbind_domain;
-
-}
-
-static const char *get_winbind_netbios_name(void)
-{
- struct winbindd_response response;
-
- static fstring winbind_netbios_name;
-
- if (*winbind_netbios_name) {
- return winbind_netbios_name;
- }
-
- ZERO_STRUCT(response);
-
- /* Send off request */
-
- if (winbindd_request(WINBINDD_NETBIOS_NAME, NULL, &response) !=
- NSS_STATUS_SUCCESS) {
- DEBUG(0, ("could not obtain winbind netbios name!\n"));
- return global_myname();
- }
-
- fstrcpy(winbind_netbios_name, response.data.netbios_name);
-
- return winbind_netbios_name;
-
-}
-
-/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
- form DOMAIN/user into a domain and a user */
-
-static BOOL parse_ntlm_auth_domain_user(const char *domuser, fstring domain,
- fstring user)
-{
-
- char *p = strchr(domuser,winbind_separator());
-
- if (!p) {
- return False;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- strupper_m(domain);
-
- return True;
-}
-
-static BOOL get_require_membership_sid(void) {
- struct winbindd_request request;
- struct winbindd_response response;
-
- if (!require_membership_of) {
- return True;
- }
-
- if (require_membership_sid) {
- return True;
- }
-
- /* Otherwise, ask winbindd for the name->sid request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!parse_ntlm_auth_domain_user(require_membership_of,
- request.data.name.dom_name,
- request.data.name.name)) {
- DEBUG(0, ("Could not parse %s into seperate domain/name parts!\n",
- require_membership_of));
- return False;
- }
-
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n",
- require_membership_of));
- return False;
- }
-
- require_membership_sid = strdup(response.data.sid.sid);
-
- if (require_membership_sid)
- return True;
-
- return False;
-}
-/* Authenticate a user with a plaintext password */
-
-static BOOL check_plaintext_auth(const char *user, const char *pass,
- BOOL stdout_diagnostics)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
-
- if (!get_require_membership_sid()) {
- return False;
- }
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.auth.user, user);
- fstrcpy(request.data.auth.pass, pass);
- if (require_membership_sid)
- fstrcpy(request.data.auth.required_membership_sid, require_membership_sid);
-
- result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
-
- /* Display response */
-
- if (stdout_diagnostics) {
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
- d_printf("Reading winbind reply failed! (0x01)\n");
- }
-
- d_printf("%s: %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.error_string,
- response.data.auth.nt_status);
- } else {
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
- DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));
- }
-
- DEBUG(3, ("%s: %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.error_string,
- response.data.auth.nt_status));
- }
-
- return (result == NSS_STATUS_SUCCESS);
-}
-
-/* authenticate a user with an encrypted username/password */
-
-static NTSTATUS contact_winbind_auth_crap(const char *username,
- const char *domain,
- const char *workstation,
- const DATA_BLOB *challenge,
- const DATA_BLOB *lm_response,
- const DATA_BLOB *nt_response,
- uint32 flags,
- uint8 lm_key[8],
- uint8 user_session_key[16],
- char **error_string,
- char **unix_name)
-{
- NTSTATUS nt_status;
- NSS_STATUS result;
- struct winbindd_request request;
- struct winbindd_response response;
-
- if (!get_require_membership_sid()) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.flags = flags;
-
- if (require_membership_sid)
- fstrcpy(request.data.auth_crap.required_membership_sid, require_membership_sid);
-
- if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
- *error_string = smb_xstrdup(
- "unable to create utf8 string for username");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (push_utf8_fstring(request.data.auth_crap.domain, domain) == -1) {
- *error_string = smb_xstrdup(
- "unable to create utf8 string for domain");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (push_utf8_fstring(request.data.auth_crap.workstation,
- workstation) == -1) {
- *error_string = smb_xstrdup(
- "unable to create utf8 string for workstation");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
-
- if (lm_response && lm_response->length) {
- memcpy(request.data.auth_crap.lm_resp,
- lm_response->data,
- MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
- request.data.auth_crap.lm_resp_len = lm_response->length;
- }
-
- if (nt_response && nt_response->length) {
- memcpy(request.data.auth_crap.nt_resp,
- nt_response->data,
- MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
- request.data.auth_crap.nt_resp_len = nt_response->length;
- }
-
- result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
-
- /* Display response */
-
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- if (error_string)
- *error_string = smb_xstrdup("Reading winbind reply failed!");
- return nt_status;
- }
-
- nt_status = (NT_STATUS(response.data.auth.nt_status));
- if (!NT_STATUS_IS_OK(nt_status)) {
- if (error_string)
- *error_string = smb_xstrdup(response.data.auth.error_string);
- return nt_status;
- }
-
- if ((flags & WBFLAG_PAM_LMKEY) && lm_key) {
- memcpy(lm_key, response.data.auth.first_8_lm_hash,
- sizeof(response.data.auth.first_8_lm_hash));
- }
- if ((flags & WBFLAG_PAM_USER_SESSION_KEY) && user_session_key) {
- memcpy(user_session_key, response.data.auth.user_session_key,
- sizeof(response.data.auth.user_session_key));
- }
-
- if (flags & WBFLAG_PAM_UNIX_NAME) {
- if (pull_utf8_allocate(unix_name, (char *)response.extra_data) == -1) {
- return NT_STATUS_NO_MEMORY;
- }
- }
-
- return nt_status;
-}
-
-static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
-{
- static const char zeros[16];
- NTSTATUS nt_status;
- char *error_string;
- uint8 lm_key[8];
- uint8 user_sess_key[16];
- char *unix_name;
-
- nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
- ntlmssp_state->workstation,
- &ntlmssp_state->chal,
- &ntlmssp_state->lm_resp,
- &ntlmssp_state->nt_resp,
- WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,
- lm_key, user_sess_key,
- &error_string, &unix_name);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- if (memcmp(lm_key, zeros, 8) != 0) {
- *lm_session_key = data_blob(NULL, 16);
- memcpy(lm_session_key->data, lm_key, 8);
- memset(lm_session_key->data+8, '\0', 8);
- }
-
- if (memcmp(user_sess_key, zeros, 16) != 0) {
- *user_session_key = data_blob(user_sess_key, 16);
- }
- ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state->mem_ctx, unix_name);
- SAFE_FREE(unix_name);
- } else {
- DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3,
- ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
- ntlmssp_state->domain, ntlmssp_state->user,
- ntlmssp_state->workstation,
- error_string ? error_string : "unknown error (NULL)"));
- ntlmssp_state->auth_context = NULL;
- }
- return nt_status;
-}
-
-static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
-{
- NTSTATUS nt_status;
- uint8 lm_pw[16], nt_pw[16];
-
- nt_lm_owf_gen (opt_password, nt_pw, lm_pw);
-
- nt_status = ntlm_password_check(ntlmssp_state->mem_ctx,
- &ntlmssp_state->chal,
- &ntlmssp_state->lm_resp,
- &ntlmssp_state->nt_resp,
- NULL, NULL,
- ntlmssp_state->user,
- ntlmssp_state->user,
- ntlmssp_state->domain,
- lm_pw, nt_pw, user_session_key, lm_session_key);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx,
- "%s%c%s", ntlmssp_state->domain,
- *lp_winbind_separator(),
- ntlmssp_state->user);
- } else {
- DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
- ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation,
- nt_errstr(nt_status)));
- ntlmssp_state->auth_context = NULL;
- }
- return nt_status;
-}
-
-static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state)
-{
- NTSTATUS status;
- if ( (opt_username == NULL) || (opt_domain == NULL) ) {
- DEBUG(1, ("Need username and domain for NTLMSSP\n"));
- return status;
- }
-
- status = ntlmssp_client_start(client_ntlmssp_state);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not start NTLMSSP client: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- status = ntlmssp_set_username(*client_ntlmssp_state, opt_username);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set username: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set domain: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set password: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
- return NT_STATUS_OK;
-}
-
-static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state)
-{
- NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not start NTLMSSP client: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- /* Have we been given a local password, or should we ask winbind? */
- if (opt_password) {
- (*ntlmssp_state)->check_password = local_pw_check;
- (*ntlmssp_state)->get_domain = lp_workgroup;
- (*ntlmssp_state)->get_global_myname = global_myname;
- } else {
- (*ntlmssp_state)->check_password = winbind_pw_check;
- (*ntlmssp_state)->get_domain = get_winbind_domain;
- (*ntlmssp_state)->get_global_myname = get_winbind_netbios_name;
- }
- return NT_STATUS_OK;
-}
-
-static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- static NTLMSSP_STATE *ntlmssp_state = NULL;
- DATA_BLOB request, reply;
- NTSTATUS nt_status;
-
- if (strlen(buf) < 2) {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (strlen(buf) > 3) {
- request = base64_decode_data_blob(buf + 3);
- } else {
- request = data_blob(NULL, 0);
- }
-
- if ((strncmp(buf, "PW ", 3) == 0)) {
- /* The calling application wants us to use a local password (rather than winbindd) */
-
- opt_password = strndup((const char *)request.data, request.length);
-
- if (opt_password == NULL) {
- DEBUG(1, ("Out of memory\n"));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- return;
- }
-
- x_fprintf(x_stdout, "OK\n");
- data_blob_free(&request);
- return;
- }
-
- if (strncmp(buf, "YR", 2) == 0) {
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- } else if (strncmp(buf, "KK", 2) == 0) {
-
- } else {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (!ntlmssp_state) {
- if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- return;
- }
- }
-
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.data, request.length);
-
- nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- char *reply_base64 = base64_encode_data_blob(reply);
- x_fprintf(x_stdout, "TT %s\n", reply_base64);
- SAFE_FREE(reply_base64);
- data_blob_free(&reply);
- DEBUG(10, ("NTLMSSP challenge\n"));
- } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
-
- ntlmssp_end(&ntlmssp_state);
- } else if (!NT_STATUS_IS_OK(nt_status)) {
- x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status));
- DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status)));
- } else {
- x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context);
- DEBUG(10, ("NTLMSSP OK!\n"));
- }
-
- data_blob_free(&request);
-}
-
-static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- static NTLMSSP_STATE *ntlmssp_state = NULL;
- DATA_BLOB request, reply;
- NTSTATUS nt_status;
- BOOL first = False;
-
- if (strlen(buf) < 2) {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (strlen(buf) > 3) {
- request = base64_decode_data_blob(buf + 3);
- } else {
- request = data_blob(NULL, 0);
- }
-
- if (strncmp(buf, "PW ", 3) == 0) {
- /* We asked for a password and obviously got it :-) */
-
- opt_password = strndup((const char *)request.data, request.length);
-
- if (opt_password == NULL) {
- DEBUG(1, ("Out of memory\n"));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- return;
- }
-
- x_fprintf(x_stdout, "OK\n");
- data_blob_free(&request);
- return;
- }
-
- if (opt_password == NULL) {
-
- /* Request a password from the calling process. After
- sending it, the calling process should retry asking for the negotiate. */
-
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return;
- }
-
- if (strncmp(buf, "YR", 2) == 0) {
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- } else if (strncmp(buf, "TT", 2) == 0) {
-
- } else {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (!ntlmssp_state) {
- if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- return;
- }
- first = True;
- }
-
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.data, request.length);
-
- nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- char *reply_base64 = base64_encode_data_blob(reply);
- if (first) {
- x_fprintf(x_stdout, "YR %s\n", reply_base64);
- } else {
- x_fprintf(x_stdout, "KK %s\n", reply_base64);
- }
- SAFE_FREE(reply_base64);
- data_blob_free(&reply);
- DEBUG(10, ("NTLMSSP challenge\n"));
- } else if (NT_STATUS_IS_OK(nt_status)) {
- x_fprintf(x_stdout, "AF\n");
- DEBUG(10, ("NTLMSSP OK!\n"));
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- } else {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- }
-
- data_blob_free(&request);
-}
-
-static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- char *user, *pass;
- user=buf;
-
- pass=memchr(buf,' ',length);
- if (!pass) {
- DEBUG(2, ("Password not found. Denying access\n"));
- x_fprintf(x_stderr, "ERR\n");
- return;
- }
- *pass='\0';
- pass++;
-
- if (stdio_helper_mode == SQUID_2_5_BASIC) {
- rfc1738_unescape(user);
- rfc1738_unescape(pass);
- }
-
- if (check_plaintext_auth(user, pass, False)) {
- x_fprintf(x_stdout, "OK\n");
- } else {
- x_fprintf(x_stdout, "ERR\n");
- }
-}
-
-static void offer_gss_spnego_mechs(void) {
-
- DATA_BLOB token;
- SPNEGO_DATA spnego;
- ssize_t len;
- char *reply_base64;
-
- pstring principal;
- pstring myname_lower;
-
- ZERO_STRUCT(spnego);
-
- pstrcpy(myname_lower, global_myname());
- strlower_m(myname_lower);
-
- pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
-
- /* Server negTokenInit (mech offerings) */
- spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 3);
-#ifdef HAVE_KRB5
- spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
- spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
- spnego.negTokenInit.mechTypes[2] = NULL;
-#else
- spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
- spnego.negTokenInit.mechTypes[1] = NULL;
-#endif
-
-
- spnego.negTokenInit.mechListMIC = data_blob(principal,
- strlen(principal));
-
- len = write_spnego_data(&token, &spnego);
- free_spnego_data(&spnego);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- reply_base64 = base64_encode_data_blob(token);
- x_fprintf(x_stdout, "TT %s *\n", reply_base64);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&token);
- DEBUG(10, ("sent SPNEGO negTokenInit\n"));
- return;
-}
-
-static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- static NTLMSSP_STATE *ntlmssp_state = NULL;
- SPNEGO_DATA request, response;
- DATA_BLOB token;
- NTSTATUS status;
- ssize_t len;
-
- char *user = NULL;
- char *domain = NULL;
-
- const char *reply_code;
- char *reply_base64;
- pstring reply_argument;
-
- if (strlen(buf) < 2) {
-
- if (ntlmssp_state != NULL) {
- DEBUG(1, ("Request for initial SPNEGO request where "
- "we already have a state\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if ( (strlen(buf) == 2) && (strcmp(buf, "YR") == 0) ) {
-
- /* Initial request, get the negTokenInit offering
- mechanisms */
-
- offer_gss_spnego_mechs();
- return;
- }
-
- /* All subsequent requests are "KK" (Knock, Knock ;)) and have
- a blob. This might be negTokenInit or negTokenTarg */
-
- if ( (strlen(buf) <= 3) || (strncmp(buf, "KK", 2) != 0) ) {
- DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- token = base64_decode_data_blob(buf + 3);
- len = read_spnego_data(token, &request);
- data_blob_free(&token);
-
- if (len == -1) {
- DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (request.type == SPNEGO_NEG_TOKEN_INIT) {
-
- /* Second request from Client. This is where the
- client offers its mechanism to use. */
-
- if ( (request.negTokenInit.mechTypes == NULL) ||
- (request.negTokenInit.mechTypes[0] == NULL) ) {
- DEBUG(1, ("Client did not offer any mechanism"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
-
- if ( request.negTokenInit.mechToken.data == NULL ) {
- DEBUG(1, ("Client did not provide NTLMSSP data\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if ( ntlmssp_state != NULL ) {
- DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
- "already got one\n"));
- x_fprintf(x_stdout, "BH\n");
- ntlmssp_end(&ntlmssp_state);
- return;
- }
-
- if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
- return;
- }
-
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.negTokenInit.mechToken.data,
- request.negTokenInit.mechToken.length);
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
-
- status = ntlmssp_update(ntlmssp_state,
- request.negTokenInit.mechToken,
- &response.negTokenTarg.responseToken);
- }
-
-#ifdef HAVE_KRB5
- if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
-
- char *principal;
- DATA_BLOB auth_data;
- DATA_BLOB ap_rep;
- DATA_BLOB session_key;
-
- if ( request.negTokenInit.mechToken.data == NULL ) {
- DEBUG(1, ("Client did not provide Kerberos data\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_KERBEROS5_OLD);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
- response.negTokenTarg.responseToken = data_blob(NULL, 0);
-
- status = ads_verify_ticket(lp_realm(),
- &request.negTokenInit.mechToken,
- &principal, &auth_data, &ap_rep,
- &session_key);
-
- /* Now in "principal" we have the name we are
- authenticated as. */
-
- if (NT_STATUS_IS_OK(status)) {
-
- domain = strchr(principal, '@');
-
- if (domain == NULL) {
- DEBUG(1, ("Did not get a valid principal "
- "from ads_verify_ticket\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- *domain++ = '\0';
- domain = strdup(domain);
- user = strdup(principal);
-
- data_blob_free(&ap_rep);
- data_blob_free(&auth_data);
-
- SAFE_FREE(principal);
- }
- }
-#endif
-
- } else {
-
- if ( (request.negTokenTarg.supportedMech == NULL) ||
- ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {
- /* Kerberos should never send a negTokenTarg, OID_NTLMSSP
- is the only one we support that sends this stuff */
- DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",
- request.negTokenTarg.supportedMech));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (request.negTokenTarg.responseToken.data == NULL) {
- DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- status = ntlmssp_update(ntlmssp_state,
- request.negTokenTarg.responseToken,
- &response.negTokenTarg.responseToken);
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
-
- if (NT_STATUS_IS_OK(status)) {
- user = strdup(ntlmssp_state->user);
- domain = strdup(ntlmssp_state->domain);
- ntlmssp_end(&ntlmssp_state);
- }
- }
-
- free_spnego_data(&request);
-
- if (NT_STATUS_IS_OK(status)) {
- response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
- reply_code = "AF";
- pstr_sprintf(reply_argument, "%s\\%s", domain, user);
- } else if (NT_STATUS_EQUAL(status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
- reply_code = "TT";
- pstr_sprintf(reply_argument, "*");
- } else {
- response.negTokenTarg.negResult = SPNEGO_REJECT;
- reply_code = "NA";
- pstrcpy(reply_argument, nt_errstr(status));
- }
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
-
- len = write_spnego_data(&token, &response);
- free_spnego_data(&response);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- reply_base64 = base64_encode_data_blob(token);
-
- x_fprintf(x_stdout, "%s %s %s\n",
- reply_code, reply_base64, reply_argument);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&token);
-
- return;
-}
-
-static NTLMSSP_STATE *client_ntlmssp_state = NULL;
-
-static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
-{
- NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB to_server;
- char *to_server_base64;
- const char *my_mechs[] = {OID_NTLMSSP, NULL};
-
- DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));
-
- if (client_ntlmssp_state != NULL) {
- DEBUG(1, ("Request for initial SPNEGO request where "
- "we already have a state\n"));
- return False;
- }
-
- if (!client_ntlmssp_state) {
- if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
- return False;
- }
- }
-
-
- if (opt_password == NULL) {
-
- /* Request a password from the calling process. After
- sending it, the calling process should retry with
- the negTokenInit. */
-
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return True;
- }
-
- spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = my_mechs;
- spnego.negTokenInit.reqFlags = 0;
- spnego.negTokenInit.mechListMIC = null_blob;
-
- status = ntlmssp_update(client_ntlmssp_state, null_blob,
- &spnego.negTokenInit.mechToken);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
- nt_errstr(status)));
- ntlmssp_end(&client_ntlmssp_state);
- return False;
- }
-
- write_spnego_data(&to_server, &spnego);
- data_blob_free(&spnego.negTokenInit.mechToken);
-
- to_server_base64 = base64_encode_data_blob(to_server);
- data_blob_free(&to_server);
- x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
- return True;
-}
-
-static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
-{
- NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB request;
- DATA_BLOB to_server;
- char *to_server_base64;
-
- DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n"));
-
- if (client_ntlmssp_state == NULL) {
- DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));
- x_fprintf(x_stdout, "BH\n");
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
- x_fprintf(x_stdout, "NA\n");
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
- x_fprintf(x_stdout, "AF\n");
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- status = ntlmssp_update(client_ntlmssp_state,
- spnego.negTokenTarg.responseToken,
- &request);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
- "ntlmssp_client_update, got: %s\n",
- nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- spnego.type = SPNEGO_NEG_TOKEN_TARG;
- spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
- spnego.negTokenTarg.supportedMech = OID_NTLMSSP;
- spnego.negTokenTarg.responseToken = request;
- spnego.negTokenTarg.mechListMIC = null_blob;
-
- write_spnego_data(&to_server, &spnego);
- data_blob_free(&request);
-
- to_server_base64 = base64_encode_data_blob(to_server);
- data_blob_free(&to_server);
- x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
- return;
-}
-
-#ifdef HAVE_KRB5
-
-static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
-{
- char *principal;
- DATA_BLOB tkt, to_server;
- DATA_BLOB session_key_krb5;
- SPNEGO_DATA reply;
- char *reply_base64;
- int retval;
-
- const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
- ssize_t len;
-
- if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
- (spnego.negTokenInit.mechListMIC.length == 0) ) {
- DEBUG(1, ("Did not get a principal for krb5\n"));
- return False;
- }
-
- principal = malloc(spnego.negTokenInit.mechListMIC.length+1);
-
- if (principal == NULL) {
- DEBUG(1, ("Could not malloc principal\n"));
- return False;
- }
-
- memcpy(principal, spnego.negTokenInit.mechListMIC.data,
- spnego.negTokenInit.mechListMIC.length);
- principal[spnego.negTokenInit.mechListMIC.length] = '\0';
-
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5);
-
- if (retval) {
-
- pstring user;
-
- /* Let's try to first get the TGT, for that we need a
- password. */
-
- if (opt_password == NULL) {
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return True;
- }
-
- pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
-
- if ((retval = kerberos_kinit_password(user, opt_password,
- 0, NULL))) {
- DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval)));
- x_fprintf(x_stdout, "NA\n");
- return True;
- }
-
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5);
-
- if (retval) {
- DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
- }
- }
-
- data_blob_free(&session_key_krb5);
-
- ZERO_STRUCT(reply);
-
- reply.type = SPNEGO_NEG_TOKEN_INIT;
- reply.negTokenInit.mechTypes = my_mechs;
- reply.negTokenInit.reqFlags = 0;
- reply.negTokenInit.mechToken = tkt;
- reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
-
- len = write_spnego_data(&to_server, &reply);
- data_blob_free(&tkt);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- return False;
- }
-
- reply_base64 = base64_encode_data_blob(to_server);
- x_fprintf(x_stdout, "KK %s *\n", reply_base64);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&to_server);
- DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
- return True;
-}
-
-static void manage_client_krb5_targ(SPNEGO_DATA spnego)
-{
- switch (spnego.negTokenTarg.negResult) {
- case SPNEGO_ACCEPT_INCOMPLETE:
- DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
- x_fprintf(x_stdout, "BH\n");
- break;
- case SPNEGO_ACCEPT_COMPLETED:
- DEBUG(10, ("Accept completed\n"));
- x_fprintf(x_stdout, "AF\n");
- break;
- case SPNEGO_REJECT:
- DEBUG(10, ("Rejected\n"));
- x_fprintf(x_stdout, "NA\n");
- break;
- default:
- DEBUG(1, ("Got an invalid negTokenTarg\n"));
- x_fprintf(x_stdout, "AF\n");
- }
-}
-
-#endif
-
-static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- DATA_BLOB request;
- SPNEGO_DATA spnego;
- ssize_t len;
-
- if (strlen(buf) <= 3) {
- DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- request = base64_decode_data_blob(buf+3);
-
- if (strncmp(buf, "PW ", 3) == 0) {
-
- /* We asked for a password and obviously got it :-) */
-
- opt_password = strndup((const char *)request.data, request.length);
-
- if (opt_password == NULL) {
- DEBUG(1, ("Out of memory\n"));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- return;
- }
-
- x_fprintf(x_stdout, "OK\n");
- data_blob_free(&request);
- return;
- }
-
- if ( (strncmp(buf, "TT ", 3) != 0) &&
- (strncmp(buf, "AF ", 3) != 0) &&
- (strncmp(buf, "NA ", 3) != 0) ) {
- DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- return;
- }
-
- /* So we got a server challenge to generate a SPNEGO
- client-to-server request... */
-
- len = read_spnego_data(request, &spnego);
- data_blob_free(&request);
-
- if (len == -1) {
- DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {
-
- /* The server offers a list of mechanisms */
-
- const char **mechType = spnego.negTokenInit.mechTypes;
-
- while (*mechType != NULL) {
-
-#ifdef HAVE_KRB5
- if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
- (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
- if (manage_client_krb5_init(spnego))
- goto out;
- }
-#endif
-
- if (strcmp(*mechType, OID_NTLMSSP) == 0) {
- if (manage_client_ntlmssp_init(spnego))
- goto out;
- }
-
- mechType++;
- }
-
- DEBUG(1, ("Server offered no compatible mechanism\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
-
- if (spnego.negTokenTarg.supportedMech == NULL) {
- /* On accept/reject Windows does not send the
- mechanism anymore. Handle that here and
- shut down the mechanisms. */
-
- switch (spnego.negTokenTarg.negResult) {
- case SPNEGO_ACCEPT_COMPLETED:
- x_fprintf(x_stdout, "AF\n");
- break;
- case SPNEGO_REJECT:
- x_fprintf(x_stdout, "NA\n");
- break;
- default:
- DEBUG(1, ("Got a negTokenTarg with no mech and an "
- "unknown negResult: %d\n",
- spnego.negTokenTarg.negResult));
- x_fprintf(x_stdout, "BH\n");
- }
-
- ntlmssp_end(&client_ntlmssp_state);
- goto out;
- }
-
- if (strcmp(spnego.negTokenTarg.supportedMech,
- OID_NTLMSSP) == 0) {
- manage_client_ntlmssp_targ(spnego);
- goto out;
- }
-
-#if HAVE_KRB5
- if (strcmp(spnego.negTokenTarg.supportedMech,
- OID_KERBEROS5_OLD) == 0) {
- manage_client_krb5_targ(spnego);
- goto out;
- }
-#endif
-
- }
-
- DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
-
- out:
- free_spnego_data(&spnego);
- return;
-}
-
-static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn)
-{
- char buf[SQUID_BUFFER_SIZE+1];
- int length;
- char *c;
- static BOOL err;
-
- /* this is not a typo - x_fgets doesn't work too well under squid */
- if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
- DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin),
- strerror(ferror(stdin))));
- exit(1); /* BIIG buffer */
- }
-
- c=memchr(buf,'\n',sizeof(buf)-1);
- if (c) {
- *c = '\0';
- length = c-buf;
- } else {
- err = 1;
- return;
- }
- if (err) {
- DEBUG(2, ("Oversized message\n"));
- x_fprintf(x_stderr, "ERR\n");
- err = 0;
- return;
- }
-
- DEBUG(10, ("Got '%s' from squid (length: %d).\n",buf,length));
-
- if (buf[0] == '\0') {
- DEBUG(2, ("Invalid Request\n"));
- x_fprintf(x_stderr, "ERR\n");
- return;
- }
-
- fn(helper_mode, buf, length);
-}
-
-
-static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_function fn) {
- /* initialize FDescs */
- x_setbuf(x_stdout, NULL);
- x_setbuf(x_stderr, NULL);
- while(1) {
- manage_squid_request(stdio_mode, fn);
- }
-}
-
-
-/* Authenticate a user with a challenge/response */
-
-static BOOL check_auth_crap(void)
-{
- NTSTATUS nt_status;
- uint32 flags = 0;
- char lm_key[8];
- char user_session_key[16];
- char *hex_lm_key;
- char *hex_user_session_key;
- char *error_string;
- static uint8 zeros[16];
-
- x_setbuf(x_stdout, NULL);
-
- if (request_lm_key)
- flags |= WBFLAG_PAM_LMKEY;
-
- if (request_user_session_key)
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- flags |= WBFLAG_PAM_NT_STATUS_SQUASH;
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &opt_challenge,
- &opt_lm_response,
- &opt_nt_response,
- flags,
- (unsigned char *)lm_key,
- (unsigned char *)user_session_key,
- &error_string, NULL);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- x_fprintf(x_stdout, "%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return False;
- }
-
- if (request_lm_key
- && (memcmp(zeros, lm_key,
- sizeof(lm_key)) != 0)) {
- hex_encode((const unsigned char *)lm_key,
- sizeof(lm_key),
- &hex_lm_key);
- x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key);
- SAFE_FREE(hex_lm_key);
- }
- if (request_user_session_key
- && (memcmp(zeros, user_session_key,
- sizeof(user_session_key)) != 0)) {
- hex_encode((const unsigned char *)user_session_key,
- sizeof(user_session_key),
- &hex_user_session_key);
- x_fprintf(x_stdout, "NT_KEY: %s\n", hex_user_session_key);
- SAFE_FREE(hex_user_session_key);
- }
-
- return True;
-}
-
-/*
- Authenticate a user with a challenge/response, checking session key
- and valid authentication types
-*/
-
-static DATA_BLOB get_challenge(void)
-{
- static DATA_BLOB chal;
- if (opt_challenge.length)
- return opt_challenge;
-
- chal = data_blob(NULL, 8);
-
- generate_random_buffer(chal.data, chal.length, False);
- return chal;
-}
-
-/*
- * Test the normal 'LM and NTLM' combination
- */
-
-static BOOL test_lm_ntlm_broken(enum ntlm_break break_which)
-{
- BOOL pass = True;
- NTSTATUS nt_status;
- uint32 flags = 0;
- DATA_BLOB lm_response = data_blob(NULL, 24);
- DATA_BLOB nt_response = data_blob(NULL, 24);
- DATA_BLOB session_key = data_blob(NULL, 16);
-
- uchar lm_key[8];
- uchar user_session_key[16];
- uchar lm_hash[16];
- uchar nt_hash[16];
- DATA_BLOB chall = get_challenge();
- char *error_string;
-
- ZERO_STRUCT(lm_key);
- ZERO_STRUCT(user_session_key);
-
- flags |= WBFLAG_PAM_LMKEY;
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- SMBencrypt(opt_password,chall.data,lm_response.data);
- E_deshash(opt_password, lm_hash);
-
- SMBNTencrypt(opt_password,chall.data,nt_response.data);
-
- E_md4hash(opt_password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
-
- switch (break_which) {
- case BREAK_NONE:
- break;
- case BREAK_LM:
- lm_response.data[0]++;
- break;
- case BREAK_NT:
- nt_response.data[0]++;
- break;
- case NO_LM:
- data_blob_free(&lm_response);
- break;
- case NO_NT:
- data_blob_free(&nt_response);
- break;
- }
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &chall,
- &lm_response,
- &nt_response,
- flags,
- lm_key,
- user_session_key,
- &error_string, NULL);
-
- data_blob_free(&lm_response);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return break_which == BREAK_NT;
- }
-
- if (memcmp(lm_hash, lm_key,
- sizeof(lm_key)) != 0) {
- DEBUG(1, ("LM Key does not match expectations!\n"));
- DEBUG(1, ("lm_key:\n"));
- dump_data(1, (const char *)lm_key, 8);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)lm_hash, 8);
- pass = False;
- }
-
- if (break_which == NO_NT) {
- if (memcmp(lm_hash, user_session_key,
- 8) != 0) {
- DEBUG(1, ("NT Session Key does not match expectations (should be LM hash)!\n"));
- DEBUG(1, ("user_session_key:\n"));
- dump_data(1, (const char *)user_session_key, sizeof(user_session_key));
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)lm_hash, sizeof(lm_hash));
- pass = False;
- }
- } else {
- if (memcmp(session_key.data, user_session_key,
- sizeof(user_session_key)) != 0) {
- DEBUG(1, ("NT Session Key does not match expectations!\n"));
- DEBUG(1, ("user_session_key:\n"));
- dump_data(1, (const char *)user_session_key, 16);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)session_key.data, session_key.length);
- pass = False;
- }
- }
- return pass;
-}
-
-/*
- * Test LM authentication, no NT response supplied
- */
-
-static BOOL test_lm(void)
-{
-
- return test_lm_ntlm_broken(NO_NT);
-}
-
-/*
- * Test the NTLM response only, no LM.
- */
-
-static BOOL test_ntlm(void)
-{
- return test_lm_ntlm_broken(NO_LM);
-}
-
-/*
- * Test the NTLM response only, but in the LM field.
- */
-
-static BOOL test_ntlm_in_lm(void)
-{
- BOOL pass = True;
- NTSTATUS nt_status;
- uint32 flags = 0;
- DATA_BLOB nt_response = data_blob(NULL, 24);
-
- uchar lm_key[8];
- uchar lm_hash[16];
- uchar user_session_key[16];
- DATA_BLOB chall = get_challenge();
- char *error_string;
-
- ZERO_STRUCT(user_session_key);
-
- flags |= WBFLAG_PAM_LMKEY;
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- SMBNTencrypt(opt_password,chall.data,nt_response.data);
-
- E_deshash(opt_password, lm_hash);
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &chall,
- &nt_response,
- NULL,
- flags,
- lm_key,
- user_session_key,
- &error_string, NULL);
-
- data_blob_free(&nt_response);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return False;
- }
-
- if (memcmp(lm_hash, lm_key,
- sizeof(lm_key)) != 0) {
- DEBUG(1, ("LM Key does not match expectations!\n"));
- DEBUG(1, ("lm_key:\n"));
- dump_data(1, (const char *)lm_key, 8);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)lm_hash, 8);
- pass = False;
- }
- if (memcmp(lm_hash, user_session_key, 8) != 0) {
- DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n"));
- DEBUG(1, ("user_session_key:\n"));
- dump_data(1, (const char *)user_session_key, 16);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)lm_hash, 8);
- pass = False;
- }
- return pass;
-}
-
-/*
- * Test the NTLM response only, but in the both the NT and LM fields.
- */
-
-static BOOL test_ntlm_in_both(void)
-{
- BOOL pass = True;
- NTSTATUS nt_status;
- uint32 flags = 0;
- DATA_BLOB nt_response = data_blob(NULL, 24);
- DATA_BLOB session_key = data_blob(NULL, 16);
-
- char lm_key[8];
- char lm_hash[16];
- char user_session_key[16];
- char nt_hash[16];
- DATA_BLOB chall = get_challenge();
- char *error_string;
-
- ZERO_STRUCT(lm_key);
- ZERO_STRUCT(user_session_key);
-
- flags |= WBFLAG_PAM_LMKEY;
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- SMBNTencrypt(opt_password,chall.data,nt_response.data);
- E_md4hash(opt_password, (unsigned char *)nt_hash);
- SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data);
-
- E_deshash(opt_password, (unsigned char *)lm_hash);
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &chall,
- &nt_response,
- &nt_response,
- flags,
- (unsigned char *)lm_key,
- (unsigned char *)user_session_key,
- &error_string, NULL);
-
- data_blob_free(&nt_response);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return False;
- }
-
- if (memcmp(lm_hash, lm_key,
- sizeof(lm_key)) != 0) {
- DEBUG(1, ("LM Key does not match expectations!\n"));
- DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
- DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
- pass = False;
- }
- if (memcmp(session_key.data, user_session_key,
- sizeof(user_session_key)) != 0) {
- DEBUG(1, ("NT Session Key does not match expectations!\n"));
- DEBUG(1, ("user_session_key:\n"));
- dump_data(1, user_session_key, 16);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)session_key.data, session_key.length);
- pass = False;
- }
-
-
- return pass;
-}
-
-/*
- * Test the NTLMv2 and LMv2 responses
- */
-
-static BOOL test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
-{
- BOOL pass = True;
- NTSTATUS nt_status;
- uint32 flags = 0;
- DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
- DATA_BLOB lmv2_response = data_blob(NULL, 0);
- DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
- DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain());
-
- uchar user_session_key[16];
- DATA_BLOB chall = get_challenge();
- char *error_string;
-
- ZERO_STRUCT(user_session_key);
-
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
- &names_blob,
- &lmv2_response, &ntlmv2_response,
- &ntlmv2_session_key)) {
- data_blob_free(&names_blob);
- return False;
- }
- data_blob_free(&names_blob);
-
- switch (break_which) {
- case BREAK_NONE:
- break;
- case BREAK_LM:
- lmv2_response.data[0]++;
- break;
- case BREAK_NT:
- ntlmv2_response.data[0]++;
- break;
- case NO_LM:
- data_blob_free(&lmv2_response);
- break;
- case NO_NT:
- data_blob_free(&ntlmv2_response);
- break;
- }
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &chall,
- &lmv2_response,
- &ntlmv2_response,
- flags,
- NULL,
- user_session_key,
- &error_string, NULL);
-
- data_blob_free(&lmv2_response);
- data_blob_free(&ntlmv2_response);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return break_which == BREAK_NT;
- }
-
- if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key,
- sizeof(user_session_key)) != 0) {
- DEBUG(1, ("USER (NTLMv2) Session Key does not match expectations!\n"));
- DEBUG(1, ("user_session_key:\n"));
- dump_data(1, (const char *)user_session_key, 16);
- DEBUG(1, ("expected:\n"));
- dump_data(1, (const char *)ntlmv2_session_key.data, ntlmv2_session_key.length);
- pass = False;
- }
- return pass;
-}
-
-/*
- * Test the NTLMv2 and LMv2 responses
- */
-
-static BOOL test_lmv2_ntlmv2(void)
-{
- return test_lmv2_ntlmv2_broken(BREAK_NONE);
-}
-
-/*
- * Test the LMv2 response only
- */
-
-static BOOL test_lmv2(void)
-{
- return test_lmv2_ntlmv2_broken(NO_NT);
-}
-
-/*
- * Test the NTLMv2 response only
- */
-
-static BOOL test_ntlmv2(void)
-{
- return test_lmv2_ntlmv2_broken(NO_LM);
-}
-
-static BOOL test_lm_ntlm(void)
-{
- return test_lm_ntlm_broken(BREAK_NONE);
-}
-
-static BOOL test_ntlm_lm_broken(void)
-{
- return test_lm_ntlm_broken(BREAK_LM);
-}
-
-static BOOL test_ntlm_ntlm_broken(void)
-{
- return test_lm_ntlm_broken(BREAK_NT);
-}
-
-static BOOL test_ntlmv2_lmv2_broken(void)
-{
- return test_lmv2_ntlmv2_broken(BREAK_LM);
-}
-
-static BOOL test_ntlmv2_ntlmv2_broken(void)
-{
- return test_lmv2_ntlmv2_broken(BREAK_NT);
-}
-
-static BOOL test_plaintext(enum ntlm_break break_which)
-{
- NTSTATUS nt_status;
- uint32 flags = 0;
- DATA_BLOB nt_response = data_blob(NULL, 0);
- DATA_BLOB lm_response = data_blob(NULL, 0);
- char *password;
-
- uchar user_session_key[16];
- uchar lm_key[16];
- static const uchar zeros[8];
- DATA_BLOB chall = data_blob(zeros, sizeof(zeros));
- char *error_string;
-
- ZERO_STRUCT(user_session_key);
-
- flags |= WBFLAG_PAM_LMKEY;
- flags |= WBFLAG_PAM_USER_SESSION_KEY;
-
- if ((push_ucs2_allocate((smb_ucs2_t **)&nt_response.data, opt_password)) == -1) {
- DEBUG(0, ("push_ucs2_allocate failed!\n"));
- exit(1);
- }
-
- nt_response.length = strlen_w(((void *)nt_response.data))*sizeof(smb_ucs2_t);
-
- password = strdup_upper(opt_password);
-
- if ((convert_string_allocate(NULL, CH_UNIX,
- CH_DOS, password,
- strlen(password)+1,
- (void**)&lm_response.data,True)) == -1) {
- DEBUG(0, ("push_ascii_allocate failed!\n"));
- exit(1);
- }
-
- SAFE_FREE(password);
-
- lm_response.length = strlen(lm_response.data);
-
- switch (break_which) {
- case BREAK_NONE:
- break;
- case BREAK_LM:
- lm_response.data[0]++;
- break;
- case BREAK_NT:
- nt_response.data[0]++;
- break;
- case NO_LM:
- SAFE_FREE(lm_response.data);
- lm_response.length = 0;
- break;
- case NO_NT:
- SAFE_FREE(nt_response.data);
- nt_response.length = 0;
- break;
- }
-
- nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
- opt_workstation,
- &chall,
- &lm_response,
- &nt_response,
- flags,
- lm_key,
- user_session_key,
- &error_string, NULL);
-
- SAFE_FREE(nt_response.data);
- SAFE_FREE(lm_response.data);
- data_blob_free(&chall);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- d_printf("%s (0x%x)\n",
- error_string,
- NT_STATUS_V(nt_status));
- SAFE_FREE(error_string);
- return break_which == BREAK_NT;
- }
-
- return break_which != BREAK_NT;
-}
-
-static BOOL test_plaintext_none_broken(void) {
- return test_plaintext(BREAK_NONE);
-}
-
-static BOOL test_plaintext_lm_broken(void) {
- return test_plaintext(BREAK_LM);
-}
-
-static BOOL test_plaintext_nt_broken(void) {
- return test_plaintext(BREAK_NT);
-}
-
-static BOOL test_plaintext_nt_only(void) {
- return test_plaintext(NO_LM);
-}
-
-static BOOL test_plaintext_lm_only(void) {
- return test_plaintext(NO_NT);
-}
-
-/*
- Tests:
-
- - LM only
- - NT and LM
- - NT
- - NT in LM field
- - NT in both fields
- - NTLMv2
- - NTLMv2 and LMv2
- - LMv2
- - plaintext tests (in challenge-response feilds)
-
- check we get the correct session key in each case
- check what values we get for the LM session key
-
-*/
-
-static const struct ntlm_tests {
- BOOL (*fn)(void);
- const char *name;
-} test_table[] = {
- {test_lm, "LM"},
- {test_lm_ntlm, "LM and NTLM"},
- {test_ntlm, "NTLM"},
- {test_ntlm_in_lm, "NTLM in LM"},
- {test_ntlm_in_both, "NTLM in both"},
- {test_ntlmv2, "NTLMv2"},
- {test_lmv2_ntlmv2, "NTLMv2 and LMv2"},
- {test_lmv2, "LMv2"},
- {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken"},
- {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken"},
- {test_ntlm_lm_broken, "NTLM and LM, LM broken"},
- {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken"},
- {test_plaintext_none_broken, "Plaintext"},
- {test_plaintext_lm_broken, "Plaintext LM broken"},
- {test_plaintext_nt_broken, "Plaintext NT broken"},
- {test_plaintext_nt_only, "Plaintext NT only"},
- {test_plaintext_lm_only, "Plaintext LM only"}
-};
-
-static BOOL diagnose_ntlm_auth(void)
-{
- unsigned int i;
- BOOL pass = True;
-
- for (i=0; test_table[i].fn; i++) {
- if (!test_table[i].fn()) {
- DEBUG(1, ("Test %s failed!\n", test_table[i].name));
- pass = False;
- }
- }
-
- return pass;
-}
-
-/* Main program */
-
-enum {
- OPT_USERNAME = 1000,
- OPT_DOMAIN,
- OPT_WORKSTATION,
- OPT_CHALLENGE,
- OPT_RESPONSE,
- OPT_LM,
- OPT_NT,
- OPT_PASSWORD,
- OPT_LM_KEY,
- OPT_USER_SESSION_KEY,
- OPT_DIAGNOSTICS,
- OPT_REQUIRE_MEMBERSHIP
-};
-
- int main(int argc, const char **argv)
-{
- int opt;
- static const char *helper_protocol;
- static int diagnostics;
-
- static const char *hex_challenge;
- static const char *hex_lm_response;
- static const char *hex_nt_response;
-
- poptContext pc;
-
- /* NOTE: DO NOT change this interface without considering the implications!
- This is an external interface, which other programs will use to interact
- with this helper.
- */
-
- /* We do not use single-letter command abbreviations, because they harm future
- interface stability. */
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "helper-protocol", 0, POPT_ARG_STRING, &helper_protocol, OPT_DOMAIN, "operate as a stdio-based helper", "helper protocol to use"},
- { "username", 0, POPT_ARG_STRING, &opt_username, OPT_USERNAME, "username"},
- { "domain", 0, POPT_ARG_STRING, &opt_domain, OPT_DOMAIN, "domain name"},
- { "workstation", 0, POPT_ARG_STRING, &opt_workstation, OPT_WORKSTATION, "workstation"},
- { "challenge", 0, POPT_ARG_STRING, &hex_challenge, OPT_CHALLENGE, "challenge (HEX encoded)"},
- { "lm-response", 0, POPT_ARG_STRING, &hex_lm_response, OPT_LM, "LM Response to the challenge (HEX encoded)"},
- { "nt-response", 0, POPT_ARG_STRING, &hex_nt_response, OPT_NT, "NT or NTLMv2 Response to the challenge (HEX encoded)"},
- { "password", 0, POPT_ARG_STRING, &opt_password, OPT_PASSWORD, "User's plaintext password"},
- { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retreive LM session key"},
- { "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retreive User (NT) session key"},
- { "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"},
- { "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
-
- /* Samba client initialisation */
-
- dbf = x_stderr;
-
- /* Samba client initialisation */
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
- dyn_CONFIGFILE, strerror(errno));
- exit(1);
- }
-
- /* Parse options */
-
- pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0);
-
- /* Parse command line options */
-
- if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
- return 1;
- }
-
- pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case OPT_CHALLENGE:
- opt_challenge = strhex_to_data_blob(hex_challenge);
- if (opt_challenge.length != 8) {
- x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n",
- hex_challenge,
- (int)opt_challenge.length);
- exit(1);
- }
- break;
- case OPT_LM:
- opt_lm_response = strhex_to_data_blob(hex_lm_response);
- if (opt_lm_response.length != 24) {
- x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n",
- hex_lm_response,
- (int)opt_lm_response.length);
- exit(1);
- }
- break;
-
- case OPT_NT:
- opt_nt_response = strhex_to_data_blob(hex_nt_response);
- if (opt_nt_response.length < 24) {
- x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n",
- hex_nt_response,
- (int)opt_nt_response.length);
- exit(1);
- }
- break;
-
- case OPT_REQUIRE_MEMBERSHIP:
- if (StrnCaseCmp("S-", require_membership_of, 2) == 0) {
- require_membership_sid = require_membership_of;
- }
- break;
- }
- }
-
- if (helper_protocol) {
- int i;
- for (i=0; i<NUM_HELPER_MODES; i++) {
- if (strcmp(helper_protocol, stdio_helper_protocols[i].name) == 0) {
- squid_stream(stdio_helper_protocols[i].mode, stdio_helper_protocols[i].fn);
- exit(0);
- }
- }
- x_fprintf(x_stderr, "unknown helper protocol [%s]\n\nValid helper protools:\n\n", helper_protocol);
-
- for (i=0; i<NUM_HELPER_MODES; i++) {
- x_fprintf(x_stderr, "%s\n", stdio_helper_protocols[i].name);
- }
-
- exit(1);
- }
-
- if (!opt_username) {
- x_fprintf(x_stderr, "username must be specified!\n\n");
- poptPrintHelp(pc, stderr, 0);
- exit(1);
- }
-
- if (opt_domain == NULL) {
- opt_domain = get_winbind_domain();
- }
-
- if (opt_workstation == NULL) {
- opt_workstation = "";
- }
-
- if (opt_challenge.length) {
- if (!check_auth_crap()) {
- exit(1);
- }
- exit(0);
- }
-
- if (!opt_password) {
- opt_password = getpass("password: ");
- }
-
- if (diagnostics) {
- if (!diagnose_ntlm_auth()) {
- return 1;
- }
- } else {
- fstring user;
-
- fstr_sprintf(user, "%s%c%s", opt_domain, winbind_separator(), opt_username);
- if (!check_plaintext_auth(user, opt_password, True)) {
- return 1;
- }
- }
-
- /* Exit code */
-
- poptFreeContext(pc);
- return 0;
-}
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index ddbf448aac2..7691e1d577f 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -1,11 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
passdb editing frontend
+ Version 3.0
- Copyright (C) Simo Sorce 2000
- Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jelmer Vernooij 2002
- Copyright (C) Rafal Szczesniak 2004
+ Copyright (C) Simo Sorce 2000
+ Copyright (C) Andrew Bartlett 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,94 +21,53 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-
-#define BIT_BACKEND 0x00000004
-#define BIT_VERBOSE 0x00000008
-#define BIT_SPSTYLE 0x00000010
-#define BIT_RESERV_1 0x00000020
-#define BIT_RESERV_2 0x00000040
-#define BIT_RESERV_3 0x00000080
-#define BIT_FULLNAME 0x00000100
-#define BIT_HOMEDIR 0x00000200
-#define BIT_HDIRDRIVE 0x00000400
-#define BIT_LOGSCRIPT 0x00000800
-#define BIT_PROFILE 0x00001000
-#define BIT_MACHINE 0x00002000
-#define BIT_RESERV_4 0x00004000
-#define BIT_USER 0x00008000
-#define BIT_LIST 0x00010000
-#define BIT_MODIFY 0x00020000
-#define BIT_CREATE 0x00040000
-#define BIT_DELETE 0x00080000
-#define BIT_ACCPOLICY 0x00100000
-#define BIT_ACCPOLVAL 0x00200000
-#define BIT_ACCTCTRL 0x00400000
-#define BIT_RESERV_7 0x00800000
-#define BIT_IMPORT 0x01000000
-#define BIT_EXPORT 0x02000000
-#define BIT_FIX_INIT 0x04000000
-#define BIT_BADPWRESET 0x08000000
-#define BIT_TRUSTDOM 0x10000000
-#define BIT_TRUSTPW 0x20000000
-#define BIT_TRUSTSID 0x40000000
-#define BIT_TRUSTFLAGS 0x80000000
-
-#define MASK_ALWAYS_GOOD 0x0000001F
-#define MASK_USER_GOOD 0x00401F00
-
-/*********************************************************
- Add all currently available users to another db
- ********************************************************/
-
-static int export_database (struct pdb_context *in, struct pdb_context *out) {
- SAM_ACCOUNT *user = NULL;
-
- if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0))) {
- fprintf(stderr, "Can't sampwent!\n");
- return 1;
- }
+/* base uid for trust accounts is set to 60000 !
+ * May be we should add the defines in smb.h to make it possible having
+ * different values on different platforms?
+ */
- if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
- fprintf(stderr, "Can't initialize new SAM_ACCOUNT!\n");
- return 1;
- }
+#define BASE_MACHINE_UID 60000
+#define MAX_MACHINE_UID 65500 /* 5500 trust accounts aren't enough? */
- while (NT_STATUS_IS_OK(in->pdb_getsampwent(in, user))) {
- out->pdb_add_sam_account(out, user);
- if (!NT_STATUS_IS_OK(pdb_reset_sam(user))){
- fprintf(stderr, "Can't reset SAM_ACCOUNT!\n");
- return 1;
- }
- }
+#include "includes.h"
- in->pdb_endsampwent(in);
+extern pstring global_myname;
+extern BOOL AllowDebugChange;
- return 0;
-}
+/*
+ * Next two lines needed for SunOS and don't
+ * hurt anything else...
+ */
+extern char *optarg;
+extern int optind;
/*********************************************************
- Add all currently available group mappings to another db
- ********************************************************/
-
-static int export_groups (struct pdb_context *in, struct pdb_context *out) {
- GROUP_MAP *maps = NULL;
- int i, entries = 0;
-
- if (NT_STATUS_IS_ERR(in->pdb_enum_group_mapping(in, SID_NAME_UNKNOWN,
- &maps, &entries,
- False))) {
- fprintf(stderr, "Can't get group mappings!\n");
- return 1;
- }
-
- for (i=0; i<entries; i++) {
- out->pdb_add_group_mapping_entry(out, &(maps[i]));
- }
-
- SAFE_FREE(maps);
-
- return 0;
+ Print command usage on stderr and die.
+ **********************************************************/
+static void usage(void)
+{
+ if (getuid() == 0) {
+ printf("pdbedit options\n");
+ } else {
+ printf("You need to be root to use this tool!\n");
+ }
+ printf("(actually to add a user you need to use smbpasswd)\n");
+ printf("options:\n");
+ printf(" -l list usernames\n");
+ printf(" -v verbose output\n");
+ printf(" -w smbpasswd file style\n");
+ printf(" -u username print user's info\n");
+ printf(" -f fullname set Full Name\n");
+ printf(" -h homedir set home directory\n");
+ printf(" -d drive set home dir drive\n");
+ printf(" -s script set logon script\n");
+ printf(" -p profile set profile path\n");
+ printf(" -a create new account\n");
+ printf(" -m it is a machine trust\n");
+ printf(" -x delete this user\n");
+ printf(" -i file import account from file (smbpasswd style)\n");
+ printf(" -t read password from STDIN\n");
+ exit(1);
}
/*********************************************************
@@ -118,74 +76,41 @@ static int export_groups (struct pdb_context *in, struct pdb_context *out) {
static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdstyle)
{
- uid_t uid;
- time_t tmp;
-
/* TODO: chaeck if entry is a user or a workstation */
if (!sam_pwent) return -1;
if (verbosity) {
- printf ("Unix username: %s\n", pdb_get_username(sam_pwent));
- printf ("NT username: %s\n", pdb_get_nt_username(sam_pwent));
- printf ("Account Flags: %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
- printf ("User SID: %s\n",
- sid_string_static(pdb_get_user_sid(sam_pwent)));
- printf ("Primary Group SID: %s\n",
- sid_string_static(pdb_get_group_sid(sam_pwent)));
- printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent));
- printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent));
- printf ("HomeDir Drive: %s\n", pdb_get_dir_drive(sam_pwent));
- printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent));
- printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent));
- printf ("Domain: %s\n", pdb_get_domain(sam_pwent));
- printf ("Account desc: %s\n", pdb_get_acct_desc(sam_pwent));
- printf ("Workstations: %s\n", pdb_get_workstations(sam_pwent));
- printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent));
-
- tmp = pdb_get_logon_time(sam_pwent);
- printf ("Logon time: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_logoff_time(sam_pwent);
- printf ("Logoff time: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_kickoff_time(sam_pwent);
- printf ("Kickoff time: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_pass_last_set_time(sam_pwent);
- printf ("Password last set: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_pass_can_change_time(sam_pwent);
- printf ("Password can change: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_pass_must_change_time(sam_pwent);
- printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : "0");
-
- tmp = pdb_get_bad_password_time(sam_pwent);
- printf ("Last bad password : %s\n", tmp ? http_timestring(tmp) : "0");
- printf ("Bad password count : %d\n",
- pdb_get_bad_password_count(sam_pwent));
-
+ printf ("username: %s\n", sam_pwent->username);
+ printf ("user ID/Group: %d/%d\n", sam_pwent->uid,
+ sam_pwent->gid);
+ printf ("user RID/GRID: %d/%d\n", sam_pwent->user_rid,
+ sam_pwent->group_rid);
+ printf ("Full Name: %s\n", sam_pwent->full_name);
+ printf ("Home Directory: %s\n", sam_pwent->home_dir);
+ printf ("HomeDir Drive: %s\n", sam_pwent->dir_drive);
+ printf ("Logon Script: %s\n", sam_pwent->logon_script);
+ printf ("Profile Path: %s\n", sam_pwent->profile_path);
} else if (smbpwdstyle) {
char lm_passwd[33];
char nt_passwd[33];
-
- uid = nametouid(pdb_get_username(sam_pwent));
- pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
- pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
-
- printf("%s:%lu:%s:%s:%s:LCT-%08X:\n",
- pdb_get_username(sam_pwent),
- (unsigned long)uid,
- lm_passwd,
- nt_passwd,
- pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
- (uint32)pdb_get_pass_last_set_time(sam_pwent));
+ pdb_sethexpwd(lm_passwd,
+ pdb_get_lanman_passwd(sam_pwent),
+ pdb_get_acct_ctrl(sam_pwent));
+ pdb_sethexpwd(nt_passwd,
+ pdb_get_nt_passwd(sam_pwent),
+ pdb_get_acct_ctrl(sam_pwent));
+
+ printf("%s:%d:%s:%s:%s:LCT-%08X:\n",
+ pdb_get_username(sam_pwent),
+ pdb_get_uid(sam_pwent),
+ lm_passwd,
+ nt_passwd,
+ pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
+ (uint32)pdb_get_pass_last_set_time(sam_pwent));
} else {
- uid = nametouid(pdb_get_username(sam_pwent));
- printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
- pdb_get_fullname(sam_pwent));
- }
-
+ printf ("%s:%d:%s\n", sam_pwent->username, sam_pwent->uid, sam_pwent->full_name);
+ }
+
return 0;
}
@@ -193,264 +118,53 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
Get an Print User Info
**********************************************************/
-static int print_user_info (struct pdb_context *in, const char *username, BOOL verbosity, BOOL smbpwdstyle)
+static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle)
{
SAM_ACCOUNT *sam_pwent=NULL;
BOOL ret;
- BOOL updated_autolock = False, updated_badpw = False;
-
- if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pwent))) {
- return -1;
- }
-
- ret = NT_STATUS_IS_OK(in->pdb_getsampwnam (in, sam_pwent, username));
+
+ pdb_init_sam(&sam_pwent);
+
+ ret = pdb_getsampwnam (sam_pwent, username);
if (ret==False) {
fprintf (stderr, "Username not found!\n");
- pdb_free_sam(&sam_pwent);
+ pdb_free_sam(sam_pwent);
return -1;
}
-
- if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock))
- DEBUG(2,("pdb_update_autolock_flag failed.\n"));
-
- if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw))
- DEBUG(2,("pdb_update_bad_password_count failed.\n"));
-
- if (updated_autolock || updated_badpw) {
- become_root();
- if(!pdb_update_sam_account(sam_pwent))
- DEBUG(1, ("Failed to modify entry.\n"));
- unbecome_root();
- }
-
+
ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle);
- pdb_free_sam(&sam_pwent);
+ pdb_free_sam(sam_pwent);
return ret;
}
-
-
-/**
- * Trust password flag name to flag conversion
- *
- * @param flag_name SAM_TRUST_PASSWD structure flag name
- * @return flag value
- **/
-
-static int trustpw_flag(const char* flag_name)
-{
- const int flag_num = 5;
- typedef struct { const char *name; int val; } flag_conv;
- flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT },
- { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT },
- { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT },
- { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS },
- { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }};
- int i;
-
- for (i = 0; i < flag_num; i++) {
- if (!StrCaseCmp(flags[i].name, flag_name)) {
- return flags[i].val;
- }
- }
-
- return 0;
-}
-
-
-/**
- * Trust password flag to flag name conversion
- *
- * @param val SAM_TRUST_PASSWD structure flag
- * @return passed flag name
- **/
-
-static char* trustpw_flag_name(const int val)
-{
- const int flag_num = 5;
- typedef struct { const char *name; int val; } flag_conv;
- flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT },
- { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT },
- { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT },
- { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS },
- { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }};
- int i;
-
- for (i = 0; i < flag_num; i++) {
- if (flags[i].val == val) {
- return strdup(flags[i].name);
- }
- }
-
- return strdup("unknown flag");
-}
-
-
-/**
- * Print trust password structure information
- *
- * @param mem_ctx memory context (for unicode name conversion)
- * @param trust SAM_TRUST_PASSWD structure
- * @param verbose verbose mode on/off
- * @return 0 on success, otherwise failure
- **/
-
-static int print_trustpw_info(TALLOC_CTX *mem_ctx, SAM_TRUST_PASSWD *trust, BOOL verbose)
-{
- char *dom_name;
- size_t uni_name_len;
- if (!mem_ctx || !trust) return -1;
-
- /* convert unicode domain name to char* */
- if (!pull_ucs2_talloc(mem_ctx, &dom_name, trust->private.uni_name)) return -1;
- uni_name_len = trust->private.uni_name_len;
- dom_name[uni_name_len > 32 ? 32 : uni_name_len] = 0;
-
- /* different output depending on level of verbosity */
- if (verbose) {
- printf("Domain name: %s\n", dom_name);
- printf("Domain SID: %s\n", sid_string_static(&trust->private.domain_sid));
- printf("Trust password %s\n", trust->private.pass);
- printf("Trust type: %s\n", trustpw_flag_name(trust->private.flags));
- printf("Last modified %s\n", trust->private.mod_time ? http_timestring(trust->private.mod_time) : "0");
-
- } else {
- printf("%s:%s\n", dom_name, sid_string_static(&trust->private.domain_sid));
- }
-
- return 0;
-}
-
-
-/**
- * Print trust password information by given name
- *
- * @param in initialised pdb_context
- * @param name domain name of the trust password
- * @param verbose verbose mode on/off
- * @param smbpwdstyle smbpassword-style output (ignored here)
- * @return 0 on success, otherwise failure
- **/
-
-static int print_trust_info(struct pdb_context *in, const char *name, BOOL verbose, BOOL smbpwdstyle)
-{
- SAM_TRUST_PASSWD trust;
- TALLOC_CTX *mem_ctx = NULL;
-
- mem_ctx = talloc_init("pdbedit: trust passwords listing");
-
- if (NT_STATUS_IS_OK(in->pdb_gettrustpwnam(in, &trust, name))) {
- return print_trustpw_info(mem_ctx, &trust, verbose);
- }
-
- return -1;
-}
/*********************************************************
List Users
**********************************************************/
-static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwdstyle)
+static int print_users_list (BOOL verbosity, BOOL smbpwdstyle)
{
SAM_ACCOUNT *sam_pwent=NULL;
- BOOL check, ret;
+ BOOL ret;
- check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
- if (!check) {
- return 1;
- }
+ pdb_init_sam(&sam_pwent);
- check = True;
- if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1;
+ ret = pdb_setsampwent(False);
+ if (ret && errno == ENOENT) {
+ fprintf (stderr,"Password database not found!\n");
+ pdb_free_sam(sam_pwent);
+ exit(1);
+ }
- while (check && (ret = NT_STATUS_IS_OK(in->pdb_getsampwent (in, sam_pwent)))) {
+ while ((ret = pdb_getsampwent (sam_pwent))) {
if (verbosity)
printf ("---------------\n");
print_sam_info (sam_pwent, verbosity, smbpwdstyle);
- pdb_free_sam(&sam_pwent);
- check = NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent));
+ pdb_reset_sam(sam_pwent);
}
- if (check) pdb_free_sam(&sam_pwent);
- in->pdb_endsampwent(in);
- return 0;
-}
-
-
-/**
- * List trust passwords
- *
- * @param in initialised pdb context
- * @param verbose turn on/off verbose mode
- * @param smbpwdstyle ignored here (there was no trust passwords in smbpasswd file)
- * @return 0 on success, otherwise failure
- **/
-
-static int print_trustpw_list(struct pdb_context *in, BOOL verbose, BOOL smbpwdstyle)
-{
- SAM_TRUST_PASSWD trust;
- TALLOC_CTX *mem_ctx = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- /* start enumeration and initialise memory context */
- status = in->pdb_settrustpwent(in);
- if (NT_STATUS_IS_ERR(status)) return -1;
- mem_ctx = talloc_init("pdbedit: trust passwords listing");
-
- /* small separation to make it clear these are not regular accounts */
- if (!verbose) printf("---\n");
-
- /* first trust password */
- status = in->pdb_gettrustpwent(in, &trust);
-
- while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
- /* print trust password info */
- if (verbose) printf ("---------------\n");
- print_trustpw_info(mem_ctx, &trust, verbose);
-
- /* fetch next trust password */
- status = in->pdb_gettrustpwent(in, &trust);
- }
-
- in->pdb_endtrustpwent(in);
- talloc_destroy(mem_ctx);
-
- return 0;
-}
-
-
-/*********************************************************
- Fix a list of Users for uninitialised passwords
-**********************************************************/
-static int fix_users_list (struct pdb_context *in)
-{
- SAM_ACCOUNT *sam_pwent=NULL;
- BOOL check, ret;
-
- check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
- if (!check) {
- return 1;
- }
-
- check = True;
- if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1;
-
- while (check && (ret = NT_STATUS_IS_OK(in->pdb_getsampwent (in, sam_pwent)))) {
- printf("Updating record for user %s\n", pdb_get_username(sam_pwent));
-
- if (!pdb_update_sam_account(sam_pwent)) {
- printf("Update of user %s failed!\n", pdb_get_username(sam_pwent));
- }
- pdb_free_sam(&sam_pwent);
- check = NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent));
- if (!check) {
- fprintf(stderr, "Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n");
- }
-
- }
- if (check) pdb_free_sam(&sam_pwent);
-
- in->pdb_endsampwent(in);
+ pdb_endsampwent ();
+ pdb_free_sam(sam_pwent);
return 0;
}
@@ -458,191 +172,183 @@ static int fix_users_list (struct pdb_context *in)
Set User Info
**********************************************************/
-static int set_user_info (struct pdb_context *in, const char *username,
- const char *fullname, const char *homedir,
- const char *drive, const char *script,
- const char *profile, const char *account_control,
- const char *user_sid, const char *group_sid,
- const BOOL badpw)
+static int set_user_info (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
{
SAM_ACCOUNT *sam_pwent=NULL;
BOOL ret;
pdb_init_sam(&sam_pwent);
- ret = NT_STATUS_IS_OK(in->pdb_getsampwnam (in, sam_pwent, username));
+ ret = pdb_getsampwnam (sam_pwent, username);
if (ret==False) {
fprintf (stderr, "Username not found!\n");
- pdb_free_sam(&sam_pwent);
+ pdb_free_sam(sam_pwent);
return -1;
}
if (fullname)
- pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
+ pdb_set_fullname(sam_pwent, fullname);
if (homedir)
- pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
+ pdb_set_homedir(sam_pwent, homedir, True);
if (drive)
- pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
+ pdb_set_dir_drive(sam_pwent, drive, True);
if (script)
- pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
+ pdb_set_logon_script(sam_pwent, script, True);
if (profile)
- pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
+ pdb_set_profile_path (sam_pwent, profile, True);
+
+ if (pdb_update_sam_account (sam_pwent, True))
+ print_user_info (username, True, False);
+ else {
+ fprintf (stderr, "Unable to modify entry!\n");
+ pdb_free_sam(sam_pwent);
+ return -1;
+ }
+ pdb_free_sam(sam_pwent);
+ return 0;
+}
- if (account_control) {
- uint16 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ|
- ACB_PWNOEXP|ACB_AUTOLOCK);
+/*********************************************************
+ A strdup with exit
+**********************************************************/
- uint16 newflag = pdb_decode_acct_ctrl(account_control);
+static char *strdup_x(const char *s)
+{
+ char *new_s = strdup(s);
+ if (!new_s) {
+ fprintf(stderr,"out of memory\n");
+ exit(1);
+ }
+ return new_s;
+}
- if (newflag & not_settable) {
- fprintf(stderr, "Can only set [NDHLX] flags\n");
- pdb_free_sam(&sam_pwent);
- return -1;
- }
+/*************************************************************
+ Utility function to prompt for passwords from stdin. Each
+ password entered must end with a newline.
+*************************************************************/
+static char *stdin_new_passwd(void)
+{
+ static fstring new_passwd;
+ size_t len;
- pdb_set_acct_ctrl(sam_pwent,
- (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag,
- PDB_CHANGED);
- }
- if (user_sid) {
- DOM_SID u_sid;
- if (!string_to_sid(&u_sid, user_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int u_rid;
-
- if (sscanf(user_sid, "%d", &u_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
- return -1;
- }
- sid_copy(&u_sid, get_global_sam_sid());
- sid_append_rid(&u_sid, u_rid);
- }
- pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
- }
- if (group_sid) {
- DOM_SID g_sid;
- if (!string_to_sid(&g_sid, group_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int g_rid;
-
- if (sscanf(group_sid, "%d", &g_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete group SID or RID!\n");
- return -1;
- }
- sid_copy(&g_sid, get_global_sam_sid());
- sid_append_rid(&g_sid, g_rid);
+ ZERO_ARRAY(new_passwd);
+
+ /*
+ * if no error is reported from fgets() and string at least contains
+ * the newline that ends the password, then replace the newline with
+ * a null terminator.
+ */
+ if ( fgets(new_passwd, sizeof(new_passwd), stdin) != NULL) {
+ if ((len = strlen(new_passwd)) > 0) {
+ if(new_passwd[len-1] == '\n')
+ new_passwd[len - 1] = 0;
}
- pdb_set_group_sid (sam_pwent, &g_sid, PDB_CHANGED);
}
+ return(new_passwd);
+}
- if (badpw) {
- pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
- pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
+/*************************************************************
+ Utility function to get passwords via tty or stdin
+ Used if the '-s' option is set to silently get passwords
+ to enable scripting.
+ _copied_ from smbpasswd
+*************************************************************/
+static char *get_pass( char *prompt, BOOL stdin_get)
+{
+ char *p;
+ if (stdin_get) {
+ p = stdin_new_passwd();
+ } else {
+ p = getpass(prompt);
}
-
- if (NT_STATUS_IS_OK(in->pdb_update_sam_account (in, sam_pwent)))
- print_user_info (in, username, True, False);
- else {
- fprintf (stderr, "Unable to modify entry!\n");
- pdb_free_sam(&sam_pwent);
- return -1;
+ return strdup_x(p);
+}
+
+/*************************************************************
+ Utility function to prompt for new password.
+ _copied_ from smbpasswd
+*************************************************************/
+static char *prompt_for_new_password(BOOL stdin_get)
+{
+ char *p;
+ fstring new_passwd;
+
+ ZERO_ARRAY(new_passwd);
+
+ p = get_pass("New SMB password:", stdin_get);
+
+ fstrcpy(new_passwd, p);
+ safe_free(p);
+
+ p = get_pass("Retype new SMB password:", stdin_get);
+
+ if (strcmp(p, new_passwd)) {
+ fprintf(stderr, "Mismatch - password unchanged.\n");
+ ZERO_ARRAY(new_passwd);
+ safe_free(p);
+ return NULL;
}
- pdb_free_sam(&sam_pwent);
- return 0;
+
+ return p;
}
+
/*********************************************************
Add New User
**********************************************************/
-static int new_user (struct pdb_context *in, const char *username,
- const char *fullname, const char *homedir,
- const char *drive, const char *script,
- const char *profile, char *user_sid, char *group_sid)
+static int new_user (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile, BOOL stdin_get)
{
SAM_ACCOUNT *sam_pwent=NULL;
- NTSTATUS nt_status;
- char *password1, *password2, *staticpass;
+ struct passwd *pwd = NULL;
+ char *password;
- get_global_sam_sid();
+ ZERO_STRUCT(sam_pwent);
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pwent, username, 0))) {
- DEBUG(0, ("could not create account to add new user %s\n", username));
+ pdb_init_sam (&sam_pwent);
+
+ if (!(pwd = sys_getpwnam(username))) {
+ fprintf (stderr, "User %s does not exist in system passwd!\n", username);
+ pdb_free_sam (sam_pwent);
return -1;
}
- staticpass = getpass("new password:");
- password1 = strdup(staticpass);
- memset(staticpass, 0, strlen(staticpass));
- staticpass = getpass("retype new password:");
- password2 = strdup(staticpass);
- memset(staticpass, 0, strlen(staticpass));
- if (strcmp (password1, password2)) {
- fprintf (stderr, "Passwords does not match!\n");
- memset(password1, 0, strlen(password1));
- SAFE_FREE(password1);
- memset(password2, 0, strlen(password2));
- SAFE_FREE(password2);
- pdb_free_sam (&sam_pwent);
- return -1;
+ password = prompt_for_new_password(stdin_get);
+ if (!password) {
+ fprintf (stderr, "Passwords do not match!\n");
+ pdb_free_sam (sam_pwent);
+ return -1;
}
- pdb_set_plaintext_passwd(sam_pwent, password1);
- memset(password1, 0, strlen(password1));
- SAFE_FREE(password1);
- memset(password2, 0, strlen(password2));
- SAFE_FREE(password2);
+ pdb_set_plaintext_passwd(sam_pwent, password);
+ pdb_set_username(sam_pwent, username);
if (fullname)
- pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
+ pdb_set_fullname(sam_pwent, fullname);
if (homedir)
- pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED);
+ pdb_set_homedir (sam_pwent, homedir, True);
if (drive)
- pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED);
+ pdb_set_dir_drive (sam_pwent, drive, True);
if (script)
- pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
+ pdb_set_logon_script(sam_pwent, script, True);
if (profile)
- pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
- if (user_sid) {
- DOM_SID u_sid;
- if (!string_to_sid(&u_sid, user_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int u_rid;
-
- if (sscanf(user_sid, "%d", &u_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
- return -1;
- }
- sid_copy(&u_sid, get_global_sam_sid());
- sid_append_rid(&u_sid, u_rid);
- }
- pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
- }
- if (group_sid) {
- DOM_SID g_sid;
- if (!string_to_sid(&g_sid, group_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int g_rid;
-
- if (sscanf(group_sid, "%d", &g_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete group SID or RID!\n");
- return -1;
- }
- sid_copy(&g_sid, get_global_sam_sid());
- sid_append_rid(&g_sid, g_rid);
- }
- pdb_set_group_sid (sam_pwent, &g_sid, PDB_CHANGED);
- }
+ pdb_set_profile_path (sam_pwent, profile, True);
- pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED);
+ /* TODO: Check uid not being in MACHINE UID range!! */
+ pdb_set_uid (sam_pwent, pwd->pw_uid);
+ pdb_set_gid (sam_pwent, pwd->pw_gid);
+ pdb_set_user_rid (sam_pwent, pdb_uid_to_user_rid (pwd->pw_uid));
+ pdb_set_group_rid (sam_pwent, pdb_gid_to_group_rid (pwd->pw_gid));
+
+ pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL);
- if (NT_STATUS_IS_OK(in->pdb_add_sam_account (in, sam_pwent))) {
- print_user_info (in, username, True, False);
+ if (pdb_add_sam_account (sam_pwent)) {
+ print_user_info (username, True, False);
} else {
- fprintf (stderr, "Unable to add user! (does it already exist?)\n");
- pdb_free_sam (&sam_pwent);
+ fprintf (stderr, "Unable to add user! (does it alredy exist?)\n");
+ pdb_free_sam (sam_pwent);
return -1;
}
- pdb_free_sam (&sam_pwent);
+ pdb_free_sam (sam_pwent);
return 0;
}
@@ -650,305 +356,296 @@ static int new_user (struct pdb_context *in, const char *username,
Add New Machine
**********************************************************/
-static int new_machine (struct pdb_context *in, const char *machine_in)
+static int new_machine (char *machinename)
{
SAM_ACCOUNT *sam_pwent=NULL;
- fstring machinename;
- fstring machineaccount;
- struct passwd *pwd = NULL;
+ SAM_ACCOUNT *sam_trust=NULL;
+ char name[16];
+ char *password = NULL;
+ uid_t uid;
- get_global_sam_sid();
-
- fstrcpy(machinename, machine_in);
- machinename[15]= '\0';
+ pdb_init_sam (&sam_pwent);
if (machinename[strlen (machinename) -1] == '$')
machinename[strlen (machinename) -1] = '\0';
- strlower_m(machinename);
+ safe_strcpy (name, machinename, 16);
+ safe_strcat (name, "$", 16);
- fstrcpy(machineaccount, machinename);
- fstrcat(machineaccount, "$");
-
- if ((pwd = getpwnam_alloc(machineaccount))) {
- if (!NT_STATUS_IS_OK(pdb_init_sam_pw( &sam_pwent, pwd))) {
- fprintf(stderr, "Could not init sam from pw\n");
- passwd_free(&pwd);
- return -1;
- }
- passwd_free(&pwd);
- } else {
- if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pwent))) {
- fprintf(stderr, "Could not init sam from pw\n");
- return -1;
- }
- }
-
- pdb_set_plaintext_passwd (sam_pwent, machinename);
-
- pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED);
+ string_set (&password, machinename);
+ strlower(password);
- pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED);
-
- pdb_set_group_sid_from_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS, PDB_CHANGED);
-
- if (NT_STATUS_IS_OK(in->pdb_add_sam_account (in, sam_pwent))) {
- print_user_info (in, machineaccount, True, False);
- } else {
- fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
- pdb_free_sam (&sam_pwent);
- return -1;
- }
- pdb_free_sam (&sam_pwent);
- return 0;
-}
-
+ pdb_set_plaintext_passwd (sam_pwent, password);
-/**
- * Add new trusting domain account
- *
- * @param in initialised pdb_context
- * @param dom_name trusted domain name given in command line
- *
- * @return 0 on success, -1 otherwise
- **/
-
-static int new_trustdom(struct pdb_context *in, const char *dom_name)
-{
- /* TODO */
- return -1;
-}
-
-
-/**
- * Add new trust relationship password
- *
- * @param in initialised pdb_context
- * @param dom_name trusting domain name given in command line
- * @param dom_sid domain sid given in command line
- * @param flag trust password type flag given in command line
- *
- * @return 0 on success, -1 otherwise
- **/
-
-static int new_trustpw(struct pdb_context *in, const char *dom_name,
- const char *dom_sid, const char* flag)
-{
- TALLOC_CTX *mem_ctx = NULL;
- SAM_TRUST_PASSWD trust;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- smb_ucs2_t *uni_name = NULL;
- char *givenpass;
- time_t lct;
-
- if (!dom_name) return -1;
-
- mem_ctx = talloc_init("pdbedit: adding new trust password");
+ pdb_set_username (sam_pwent, name);
- /* unicode name */
- trust.private.uni_name_len = strnlen(dom_name, 32);
- push_ucs2_talloc(mem_ctx, &uni_name, dom_name);
- strncpy_w(trust.private.uni_name, uni_name, 32);
-
- /* flags */
- if (!flag) {
- printf("No trust type flag given!\n");
- return -1;
- }
-
- /* is it the correct one ? */
- trust.private.flags = trustpw_flag(flag);
- if (!trust.private.flags) {
- printf("Unknown trust type flag!\n");
- return -1;
- }
-
- /* trusting SID */
- if (!dom_sid) {
- /* copying zeroed sid to trust password structure
- it'll be handled and filled at nearest opportunity */
- ZERO_STRUCT(trust.private.domain_sid);
-
-
- } else {
- if (!string_to_sid(&trust.private.domain_sid, dom_sid)) {
- printf("Error: incorrect SID specified !\n");
- return -1;
+ for (uid=BASE_MACHINE_UID; uid<=MAX_MACHINE_UID; uid++) {
+ pdb_init_sam (&sam_trust);
+ if (pdb_getsampwuid (sam_trust, uid)) {
+ pdb_free_sam (sam_trust);
+ } else {
+ break;
}
}
-
- /* password */
- givenpass = getpass("password:");
- memset(trust.private.pass, '\0', FSTRING_LEN);
- strncpy(trust.private.pass, givenpass, FSTRING_LEN);
-
- /* last change time */
- lct = time(NULL);
- trust.private.mod_time = lct;
-
- /* store trust password in passdb */
- nt_status = in->pdb_add_trust_passwd(in, &trust);
-
- talloc_destroy(mem_ctx);
- if (NT_STATUS_IS_OK(nt_status)) {
- return 0;
- } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
- printf("Error: this functionality is not supported by your current passdb backend!\n");
+ if (uid>MAX_MACHINE_UID) {
+ fprintf (stderr, "No more free UIDs available to Machine accounts!\n");
+ pdb_free_sam(sam_pwent);
return -1;
}
-
- return -1;
-}
-
-/**
- * Update trust relationship password
- *
- * @param in initialised pdb_context
- * @param dom_name trusting domain name given in command line
- * @param dom_sid domain sid given in command line
- * @param flag trust password type flag given in command line
- *
- * @return 0 on success, -1 otherwise
- **/
-
-static int update_trustpw(struct pdb_context *in, const char *dom_name,
- const char *dom_sid, const char* flag)
-{
- SAM_TRUST_PASSWD trust;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *givenpass = NULL;
- time_t lct;
-
- if (!dom_name) return -1;
-
- /* fetch existing password to fill the structure before
- the changes themselves */
- nt_status = in->pdb_gettrustpwnam(in, &trust, dom_name);
- if (!NT_STATUS_IS_OK(nt_status)) {
- printf("Wrong domain name - seems non-existent!\n");
+ pdb_set_uid (sam_pwent, uid);
+ pdb_set_gid (sam_pwent, BASE_MACHINE_UID); /* TODO: set there more appropriate value!! */
+ pdb_set_user_rid (sam_pwent,pdb_uid_to_user_rid (uid));
+ pdb_set_group_rid (sam_pwent, pdb_gid_to_group_rid (BASE_MACHINE_UID));
+ pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST);
+
+ if (pdb_add_sam_account (sam_pwent)) {
+ print_user_info (name, True, False);
+ } else {
+ fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
+ pdb_free_sam (sam_pwent);
return -1;
}
-
- /* domain sid */
- if (dom_sid) {
- /* copying sid to trust password structure */
- if (!string_to_sid(&trust.private.domain_sid, dom_sid)) {
- printf("Error: incorrect SID specified !\n");
- return -1;
- }
- }
-
- /* flags */
- if (flag) {
- trust.private.flags = trustpw_flag(flag);
- }
-
- /* password */
- givenpass = getpass("password (type Enter to leave it untouched):");
- if (strlen(givenpass))
- strncpy(trust.private.pass, givenpass, FSTRING_LEN);
-
- /* last change time */
- lct = time(NULL);
- trust.private.mod_time = lct;
-
- /* update the trust password */
- nt_status = in->pdb_update_trust_passwd(in, &trust);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- printf("Coulnd't modify trust password\n");
- }
-
- return NT_STATUS_IS_OK(nt_status) ? 0 : -1;
+ pdb_free_sam (sam_pwent);
+ return 0;
}
-
/*********************************************************
Delete user entry
**********************************************************/
-static int delete_user_entry (struct pdb_context *in, const char *username)
+static int delete_user_entry (char *username)
{
- SAM_ACCOUNT *samaccount = NULL;
-
- if (!NT_STATUS_IS_OK(pdb_init_sam (&samaccount))) {
- return -1;
- }
-
- if (!NT_STATUS_IS_OK(in->pdb_getsampwnam(in, samaccount, username))) {
- fprintf (stderr, "user %s does not exist in the passdb\n", username);
- return -1;
- }
-
- if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) {
- fprintf (stderr, "Unable to delete user %s\n", username);
- return -1;
- }
- return 0;
+ return (! pdb_delete_sam_account (username));
}
/*********************************************************
Delete machine entry
**********************************************************/
-static int delete_machine_entry (struct pdb_context *in, const char *machinename)
+static int delete_machine_entry (char *machinename)
{
- fstring name;
- SAM_ACCOUNT *samaccount = NULL;
+ char name[16];
- fstrcpy(name, machinename);
- name[15] = '\0';
- if (name[strlen(name)-1] != '$')
- fstrcat (name, "$");
-
- if (!NT_STATUS_IS_OK(pdb_init_sam (&samaccount))) {
- return -1;
- }
+ safe_strcpy (name, machinename, 16);
+ if (name[strlen(name)] != '$')
+ safe_strcat (name, "$", 16);
+ return (! pdb_delete_sam_account (name));
+}
- if (!NT_STATUS_IS_OK(in->pdb_getsampwnam(in, samaccount, name))) {
- fprintf (stderr, "machine %s does not exist in the passdb\n", name);
- return -1;
- }
+/*********************************************************
+ Import smbpasswd style file
+**********************************************************/
- if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) {
- fprintf (stderr, "Unable to delete machine %s\n", name);
+static int import_users (char *filename)
+{
+ FILE *fp = NULL;
+ SAM_ACCOUNT *sam_pwent = NULL;
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ char linebuf[256];
+ size_t linebuf_len;
+ unsigned char c;
+ unsigned char *p;
+ long uidval;
+ int line = 0;
+ int good = 0;
+
+ if (!pdb_init_sam (&sam_pwent)) {
+ fprintf (stderr, "pdb_init_sam FAILED!\n");
+ }
+
+ if((fp = sys_fopen(filename, "rb")) == NULL) {
+ fprintf (stderr, "%s\n", strerror (ferror (fp)));
return -1;
}
+
+ while (!feof(fp)) {
+ /*Get a new line*/
+ linebuf[0] = '\0';
+ fgets(linebuf, 256, fp);
+ if (ferror(fp)) {
+ fprintf (stderr, "%s\n", strerror (ferror (fp)));
+ pdb_free_sam(sam_pwent);
+ return -1;
+ }
+ if ((linebuf_len = strlen(linebuf)) == 0) {
+ line++;
+ continue;
+ }
+ if (linebuf[linebuf_len - 1] != '\n') {
+ c = '\0';
+ while (!ferror(fp) && !feof(fp)) {
+ c = fgetc(fp);
+ if (c == '\n') break;
+ }
+ } else
+ linebuf[linebuf_len - 1] = '\0';
+ linebuf[linebuf_len] = '\0';
+ if ((linebuf[0] == 0) && feof(fp)) {
+ /*end of file!!*/
+ pdb_free_sam(sam_pwent);
+ return 0;
+ }
+ line++;
+ if (linebuf[0] == '#' || linebuf[0] == '\0')
+ continue;
+
+ pdb_set_acct_ctrl (sam_pwent,ACB_NORMAL);
+
+ /* Get user name */
+ p = (unsigned char *) strchr(linebuf, ':');
+ if (p == NULL) {
+ fprintf (stderr, "Error: malformed password entry at line %d !!\n", line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
+ user_name[PTR_DIFF(p, linebuf)] = '\0';
+
+ /* Get smb uid. */
+ p++;
+ if(*p == '-') {
+ fprintf (stderr, "Error: negative uid at line %d\n", line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ if (!isdigit(*p)) {
+ fprintf (stderr, "Error: malformed password entry at line %d (uid not number)\n", line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ uidval = atoi((char *) p);
+ while (*p && isdigit(*p)) p++;
+ if (*p != ':') {
+ fprintf (stderr, "Error: malformed password entry at line %d (no : after uid)\n", line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+
+ pdb_set_username(sam_pwent, user_name);
+ pdb_set_uid (sam_pwent, uidval);
+
+ /* Get passwords */
+ p++;
+ if (*p == '*' || *p == 'X') {
+ /* Password deliberately invalid */
+ fprintf (stderr, "Warning: entry invalidated for user %s\n", user_name);
+ pdb_set_lanman_passwd(sam_pwent, NULL);
+ pdb_set_nt_passwd(sam_pwent,NULL);
+ pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_DISABLED);
+ } else {
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
+ fprintf (stderr, "Error: malformed password entry at line %d (password too short)\n",line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ if (p[32] != ':') {
+ fprintf (stderr, "Error: malformed password entry at line %d (no terminating :)\n",line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+ pdb_set_lanman_passwd(sam_pwent, NULL);
+ pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_PWNOTREQ);
+ } else {
+ if (!pdb_gethexpwd((char *)p, smbpwd)) {
+ fprintf (stderr, "Error: malformed Lanman password entry at line %d (non hex chars)\n", line);
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ pdb_set_lanman_passwd(sam_pwent, smbpwd);
+ }
+ /* NT password */
+ pdb_set_nt_passwd(sam_pwent, smbpwd);
+ p += 33;
+ if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
+ if (*p != '*' && *p != 'X') {
+ if (pdb_gethexpwd((char *)p,smbntpwd)) {
+ pdb_set_nt_passwd(sam_pwent, smbntpwd);
+ }
+ }
+ p += 33;
+ }
+ }
- return 0;
-}
+ /* Get ACCT_CTRL field if any */
+ if (*p == '[') {
+ uint16 acct_ctrl;
+ unsigned char *end_p = (unsigned char *)strchr((char *)p, ']');
+
+ acct_ctrl = pdb_decode_acct_ctrl((char*)p);
+ if (acct_ctrl)
+ acct_ctrl = ACB_NORMAL;
+ pdb_set_acct_ctrl(sam_pwent, acct_ctrl);
+
+ /* Get last change time */
+ if(end_p)
+ p = end_p + 1;
+ if(*p == ':') {
+ p++;
+ if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
+ int i;
+
+ p += 4;
+ for(i = 0; i < 8; i++) {
+ if(p[i] == '\0' || !isxdigit(p[i])) break;
+ }
+ if(i == 8) {
+ pdb_set_pass_last_set_time (sam_pwent, (time_t)strtol((char *)p, NULL, 16));
+ }
+ }
+ }
+ }
-/**
- * Delete trust relationship password
- *
- * @param in intitialised pdb_context
- * @param domain trusting domain name given in command line
- *
- * @return 0 on success, -1 otherwise
- **/
+ /* Old-style workstation account code droped. */
-static int delete_trustpw(struct pdb_context *in, char* domain)
-{
- SAM_TRUST_PASSWD trust;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- BOOL status = False;
-
- /* unicode name and its null-termination */
- trust.private.uni_name_len = strnlen(domain, 32);
- domain[trust.private.uni_name_len] = 0;
- push_ucs2(NULL, trust.private.uni_name, domain, 32, 0);
-
- /* deletion is based on domain name only, so there's no need
- to fill the rest of the structure */
- nt_status = in->pdb_delete_trust_passwd(in, &trust);
+ if (pdb_get_acct_ctrl(sam_pwent) & ACB_WSTRUST) {
+ if ((uidval < BASE_MACHINE_UID) || (uidval > MAX_MACHINE_UID)) {
+ fprintf (stderr, "Warning: Machine UID out of normal range %d-%d\n",
+ BASE_MACHINE_UID,
+ MAX_MACHINE_UID);
+ }
+ pdb_set_uid(sam_pwent, BASE_MACHINE_UID);
+ }
- status = NT_STATUS_IS_OK(nt_status) ? 0 : -1;
- return status;
-}
+ /* Test if user is valid */
+ if (pdb_get_acct_ctrl(sam_pwent) & ACB_NORMAL) {
+ struct passwd *pwd = NULL;
+ if (!(pwd = sys_getpwnam(user_name))) {
+ fprintf (stderr, "Error: User %s does not exist in system passwd!\n", user_name);
+ continue;
+ }
+ pdb_set_gid(sam_pwent, pwd->pw_gid);
+ }
+
+ /* Fill in sam_pwent structure */
+ pdb_set_user_rid(sam_pwent, pdb_uid_to_user_rid (pdb_get_uid(sam_pwent)));
+ pdb_set_group_rid(sam_pwent, pdb_gid_to_group_rid (pdb_get_gid(sam_pwent)));
+
+ /* TODO: set also full_name, home_dir, dir_drive, logon_script, profile_path, ecc...
+ * when defaults will be available (after passdb redesign)
+ * let them blank just now they are not used anyway
+ */
+
+ /* Now ADD the entry */
+ if (!(pdb_add_sam_account (sam_pwent))) {
+ fprintf (stderr, "Unable to add user entry!\n");
+ pdb_reset_sam (sam_pwent);
+ continue;
+ }
+ printf ("%s imported!\n", user_name);
+ good++;
+ pdb_reset_sam (sam_pwent);
+ }
+ printf ("%d lines read.\n%d entries imported\n", line, good);
+ pdb_free_sam(sam_pwent);
+ return 0;
+}
/*********************************************************
Start here.
@@ -956,308 +653,161 @@ static int delete_trustpw(struct pdb_context *in, char* domain)
int main (int argc, char **argv)
{
- static BOOL list_users = False;
- static BOOL verbose = False;
- static BOOL spstyle = False;
- static BOOL machine = False;
- static BOOL trustdom = False;
- static BOOL add_user = False;
- static BOOL delete_user = False;
- static BOOL modify_user = False;
- uint32 setparms, checkparms;
- int opt;
- static char *full_name = NULL;
- static const char *user_name = NULL;
- static char *home_dir = NULL;
- static char *home_drive = NULL;
- static char *backend = NULL;
- static char *backend_in = NULL;
- static char *backend_out = NULL;
- static BOOL transfer_groups = False;
- static BOOL force_initialised_password = False;
- static char *logon_script = NULL;
- static char *profile_path = NULL;
- static char *account_control = NULL;
- static char *account_policy = NULL;
- static char *user_sid = NULL;
- static char *group_sid = NULL;
- static long int account_policy_value = 0;
- BOOL account_policy_value_set = False;
- static BOOL badpw_reset = False;
- /* trust password parameters */
- static char *trustpw = NULL;
- static char *trustsid = NULL;
- static char *trustflags = NULL;
-
- struct pdb_context *bin;
- struct pdb_context *bout;
- struct pdb_context *bdef;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"list", 'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
- {"verbose", 'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL },
- {"smbpasswd-style", 'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL},
- {"user", 'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" },
- {"fullname", 'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL},
- {"homedir", 'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL},
- {"drive", 'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
- {"script", 'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
- {"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
- {"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
- {"group SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL},
- {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
- {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
- {"delete", 'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL},
- {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
- {"trustdom", 'I', POPT_ARG_NONE, &trustdom, 0, "account is a domain trust account", NULL},
- {"trustpw", 'N', POPT_ARG_STRING, &trustpw, 0, "trust password's domain name", NULL},
- {"trustsid", 'T', POPT_ARG_STRING, &trustsid, 0, "trust password's domain sid", NULL},
- {"trustflags", 'F', POPT_ARG_STRING, &trustflags, 0, "trust password flags", NULL},
- {"backend", 'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL},
- {"import", 'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
- {"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
- {"group", 'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
- {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
- {"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
- {"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
- {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
- {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
+ int ch;
+ static pstring servicesf = CONFIGFILE;
+ BOOL list_users = False;
+ BOOL verbose = False;
+ BOOL spstyle = False;
+ BOOL setparms = False;
+ BOOL machine = False;
+ BOOL add_user = False;
+ BOOL delete_user = False;
+ BOOL import = False;
+ BOOL pw_from_stdin = False;
+ char *user_name = NULL;
+ char *full_name = NULL;
+ char *home_dir = NULL;
+ char *home_drive = NULL;
+ char *logon_script = NULL;
+ char *profile_path = NULL;
+ char *smbpasswd = NULL;
+
+ TimeInit();
setup_logging("pdbedit", True);
-
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'C':
- account_policy_value_set = True;
- break;
- }
- }
- poptGetArg(pc); /* Drop argv[0], the program name */
+ charset_initialise();
- if (user_name == NULL)
- user_name = poptGetArg(pc);
+ if (argc < 2) {
+ usage();
+ return 0;
+ }
+
+ DEBUGLEVEL = 0;
+ AllowDebugChange = False;
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ servicesf);
exit(1);
}
- if(!initialize_password_db(False))
- exit(1);
+ secrets_init();
- if (!init_names())
+ if(!initialize_password_db(True)) {
+ fprintf(stderr, "Can't setup password database vectors.\n");
exit(1);
-
- setparms = (backend ? BIT_BACKEND : 0) +
- (verbose ? BIT_VERBOSE : 0) +
- (spstyle ? BIT_SPSTYLE : 0) +
- (full_name ? BIT_FULLNAME : 0) +
- (home_dir ? BIT_HOMEDIR : 0) +
- (home_drive ? BIT_HDIRDRIVE : 0) +
- (logon_script ? BIT_LOGSCRIPT : 0) +
- (profile_path ? BIT_PROFILE : 0) +
- (machine ? BIT_MACHINE : 0) +
- (trustdom ? BIT_TRUSTDOM : 0) +
- (trustpw ? BIT_TRUSTPW : 0) +
- (trustsid ? BIT_TRUSTSID : 0) +
- (trustflags ? BIT_TRUSTFLAGS : 0) +
- (user_name ? BIT_USER : 0) +
- (list_users ? BIT_LIST : 0) +
- (force_initialised_password ? BIT_FIX_INIT : 0) +
- (modify_user ? BIT_MODIFY : 0) +
- (add_user ? BIT_CREATE : 0) +
- (delete_user ? BIT_DELETE : 0) +
- (account_control ? BIT_ACCTCTRL : 0) +
- (account_policy ? BIT_ACCPOLICY : 0) +
- (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
- (backend_in ? BIT_IMPORT : 0) +
- (backend_out ? BIT_EXPORT : 0) +
- (badpw_reset ? BIT_BADPWRESET : 0);
-
- if (setparms & BIT_BACKEND) {
- if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
- fprintf(stderr, "Can't initialize passdb backend.\n");
- return 1;
- }
- } else {
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&bdef, lp_passdb_backend()))) {
- fprintf(stderr, "Can't initialize passdb backend.\n");
- return 1;
- }
}
- /* the lowest bit options are always accepted */
- checkparms = setparms & ~MASK_ALWAYS_GOOD;
-
- if (checkparms & BIT_FIX_INIT) {
- return fix_users_list(bdef);
- }
-
- /* account policy operations */
- if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
- uint32 value;
- int field = account_policy_name_to_fieldnum(account_policy);
- if (field == 0) {
- fprintf(stderr, "No account policy by that name\n");
- exit(1);
- }
- if (!account_policy_get(field, &value)) {
- fprintf(stderr, "valid account policy, but unable to fetch value!\n");
- exit(1);
- }
- if (account_policy_value_set) {
- printf("account policy value for %s was %u\n", account_policy, value);
- if (!account_policy_set(field, account_policy_value)) {
- fprintf(stderr, "valid account policy, but unable to set value!\n");
- exit(1);
- }
- printf("account policy value for %s is now %lu\n", account_policy, account_policy_value);
- exit(0);
- } else {
- printf("account policy value for %s is %u\n", account_policy, value);
- exit(0);
- }
- }
+
+ codepage_initialise(lp_client_code_page());
- /* import and export operations */
- if (((checkparms & BIT_IMPORT) || (checkparms & BIT_EXPORT))
- && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT))) {
- if (backend_in) {
- if (!NT_STATUS_IS_OK(make_pdb_context_string(&bin, backend_in))) {
- fprintf(stderr, "Can't initialize passdb backend.\n");
- return 1;
- }
- } else {
- bin = bdef;
- }
- if (backend_out) {
- if (!NT_STATUS_IS_OK(make_pdb_context_string(&bout, backend_out))) {
- fprintf(stderr, "Can't initialize %s.\n", backend_out);
- return 1;
- }
- } else {
- bout = bdef;
- }
- if (transfer_groups) {
- return export_groups(bin, bout);
- } else {
- return export_database(bin, bout);
+ while ((ch = getopt(argc, argv, "abd:f:h:i:lmp:s:u:vwxD:")) != EOF) {
+ switch(ch) {
+ case 'a':
+ add_user = True;
+ break;
+ case 'b':
+ pw_from_stdin = True;
+ break;
+ case 'm':
+ machine = True;
+ break;
+ case 'l':
+ list_users = True;
+ break;
+ case 'v':
+ verbose = True;
+ break;
+ case 'w':
+ spstyle = True;
+ break;
+ case 'u':
+ user_name = optarg;
+ break;
+ case 'f':
+ setparms = True;
+ full_name = optarg;
+ break;
+ case 'h':
+ setparms = True;
+ home_dir = optarg;
+ break;
+ case 'd':
+ setparms = True;
+ home_drive = optarg;
+ break;
+ case 's':
+ setparms = True;
+ logon_script = optarg;
+ break;
+ case 'p':
+ setparms = True;
+ profile_path = optarg;
+ break;
+ case 'x':
+ delete_user = True;
+ break;
+ case 'i':
+ import = True;
+ smbpasswd = optarg;
+ break;
+ case 'D':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ default:
+ usage();
}
}
-
- /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */
- /* fake up BIT_LIST if only BIT_USER is defined */
- if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
- checkparms += BIT_LIST;
- }
-
- /* modify flag is optional to maintain backwards compatibility */
- /* fake up BIT_MODIFY if BIT_USER and at least one of MASK_USER_GOOD is defined */
- if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
- checkparms += BIT_MODIFY;
+ if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) > 1) {
+ fprintf (stderr, "Incompatible options on command line!\n");
+ usage();
+ exit(1);
}
- /* list users operations */
- if (checkparms & BIT_LIST) {
- if (!(checkparms & ~BIT_LIST)) {
- print_users_list (bdef, verbose, spstyle);
- return print_trustpw_list(bdef, verbose, spstyle);
- }
- if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
- return print_user_info (bdef, user_name, verbose, spstyle);
-
- } else if (!(checkparms & ~(BIT_TRUSTPW + BIT_LIST))) {
- return print_trust_info(bdef, trustpw, verbose, spstyle);
+ if (add_user) {
+ if (!user_name) {
+ fprintf (stderr, "Username not specified! (use -u option)\n");
+ return -1;
}
+ if (machine)
+ return new_machine (user_name);
+ else
+ return new_user (user_name, full_name, home_dir, home_drive, logon_script, profile_path, pw_from_stdin);
}
-
- /* mask out users options */
- checkparms &= ~MASK_USER_GOOD;
- /* if bad password count is reset, we must be modifying */
- if (checkparms & BIT_BADPWRESET) {
- checkparms |= BIT_MODIFY;
- checkparms &= ~BIT_BADPWRESET;
- }
-
- /* account operation */
- if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
- /* check use of -u option */
- if (!(checkparms & (BIT_USER + BIT_TRUSTPW))) {
+ if (delete_user) {
+ if (!user_name) {
fprintf (stderr, "Username not specified! (use -u option)\n");
return -1;
}
-
- /* account creation operations */
- if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE + BIT_TRUSTDOM))) {
- /* machine trust account */
- if (checkparms & BIT_MACHINE) {
- return new_machine (bdef, user_name);
- /* interdomain trust account */
- } else if (checkparms & BIT_TRUSTDOM) {
- return new_trustdom(bdef, user_name);
-
- /* ordinary user account */
- } else {
- return new_user (bdef, user_name, full_name, home_dir,
- home_drive, logon_script,
- profile_path, user_sid, group_sid);
- }
- }
-
- /* account deletion operations */
- if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
- if (checkparms & BIT_MACHINE) {
- return delete_machine_entry (bdef, user_name);
- } else {
- return delete_user_entry (bdef, user_name);
- }
- }
-
- /* account modification operations */
- if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
- return set_user_info (bdef, user_name, full_name,
- home_dir,
- home_drive,
- logon_script,
- profile_path, account_control,
- user_sid, group_sid,
- badpw_reset);
- }
+ if (machine)
+ return delete_machine_entry (user_name);
+ else
+ return delete_user_entry (user_name);
+ }
+
+ if (user_name) {
+ if (setparms)
+ set_user_info ( user_name, full_name,
+ home_dir,
+ home_drive,
+ logon_script,
+ profile_path);
+ else
+ return print_user_info (user_name, verbose, spstyle);
+
+ return 0;
}
- /* trust password operation */
- if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
- /* trust password creation */
- if (!(checkparms & ~(BIT_CREATE + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) {
- return new_trustpw(bdef, trustpw, trustsid, trustflags);
- }
-
- /* trust password modification */
- if (!(checkparms & ~(BIT_MODIFY + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) {
- return update_trustpw(bdef, trustpw, trustsid, trustflags);
- }
-
- /* trust password deletion */
- if (!(checkparms & ~(BIT_DELETE + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) {
- return delete_trustpw(bdef, trustpw);
- }
- }
+ if (list_users)
+ return print_users_list (verbose, spstyle);
- if (setparms >= 0x20) {
- fprintf (stderr, "Incompatible or insufficient options on command line!\n");
- }
- poptPrintHelp(pc, stderr, 0);
+ if (import)
+ return import_users (smbpasswd);
+
+ usage();
- return 1;
+ return 0;
}
-
diff --git a/source/utils/profiles.c b/source/utils/profiles.c
deleted file mode 100644
index a31674dfb2e..00000000000
--- a/source/utils/profiles.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- Samba Unix/Linux SMB client utility profiles.c
- Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
- Copyright (C) 2003 Jelmer Vernooij (conversion to popt)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/*************************************************************************
-
- A utility to report and change SIDs in registry files
-
- Many of the ideas in here come from other people and software.
- I first looked in Wine in misc/registry.c and was also influenced by
- http://www.wednesday.demon.co.uk/dosreg.html
-
- Which seems to contain comments from someone else. I reproduce them here
- incase the site above disappears. It actually comes from
- http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt.
-
-The windows NT registry has 2 different blocks, where one can occure many
-times...
-
-the "regf"-Block
-================
-
-"regf" is obviously the abbreviation for "Registry file". "regf" is the
-signature of the header-block which is always 4kb in size, although only
-the first 64 bytes seem to be used and a checksum is calculated over
-the first 0x200 bytes only!
-
-Offset Size Contents
-0x00000000 D-Word ID: ASCII-"regf" = 0x66676572
-0x00000004 D-Word ???? //see struct REGF
-0x00000008 D-Word ???? Always the same value as at 0x00000004
-0x0000000C Q-Word last modify date in WinNT date-format
-0x00000014 D-Word 1
-0x00000018 D-Word 3
-0x0000001C D-Word 0
-0x00000020 D-Word 1
-0x00000024 D-Word Offset of 1st key record
-0x00000028 D-Word Size of the data-blocks (Filesize-4kb)
-0x0000002C D-Word 1
-0x000001FC D-Word Sum of all D-Words from 0x00000000 to
-0x000001FB //XOR of all words. Nigel
-
-I have analyzed more registry files (from multiple machines running
-NT 4.0 german version) and could not find an explanation for the values
-marked with ???? the rest of the first 4kb page is not important...
-
-the "hbin"-Block
-================
-I don't know what "hbin" stands for, but this block is always a multiple
-of 4kb in size.
-
-Inside these hbin-blocks the different records are placed. The memory-
-management looks like a C-compiler heap management to me...
-
-hbin-Header
-===========
-Offset Size Contents
-0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268
-0x0004 D-Word Offset from the 1st hbin-Block
-0x0008 D-Word Offset to the next hbin-Block
-0x001C D-Word Block-size
-
-The values in 0x0008 and 0x001C should be the same, so I don't know
-if they are correct or swapped...
-
-From offset 0x0020 inside a hbin-block data is stored with the following
-format:
-
-Offset Size Contents
-0x0000 D-Word Data-block size //this size must be a
-multiple of 8. Nigel
-0x0004 ???? Data
-
-If the size field is negative (bit 31 set), the corresponding block
-is free and has a size of -blocksize!
-
-The data is stored as one record per block. Block size is a multiple
-of 4 and the last block reaches the next hbin-block, leaving no room.
-
-Records in the hbin-blocks
-==========================
-
-nk-Record
-
- The nk-record can be treated as a kombination of tree-record and
- key-record of the win 95 registry.
-
-lf-Record
-
- The lf-record is the counterpart to the RGKN-record (the
- hash-function)
-
-vk-Record
-
- The vk-record consists information to a single value.
-
-sk-Record
-
- sk (? Security Key ?) is the ACL of the registry.
-
-Value-Lists
-
- The value-lists contain information about which values are inside a
- sub-key and don't have a header.
-
-Datas
-
- The datas of the registry are (like the value-list) stored without a
- header.
-
-All offset-values are relative to the first hbin-block and point to the
-block-size field of the record-entry. to get the file offset, you have to add
-the header size (4kb) and the size field (4 bytes)...
-
-the nk-Record
-=============
-Offset Size Contents
-0x0000 Word ID: ASCII-"nk" = 0x6B6E
-0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel
-0x0004 Q-Word write-date/time in windows nt notation
-0x0010 D-Word Offset of Owner/Parent key
-0x0014 D-Word number of sub-Keys
-0x001C D-Word Offset of the sub-key lf-Records
-0x0024 D-Word number of values
-0x0028 D-Word Offset of the Value-List
-0x002C D-Word Offset of the sk-Record
-
-0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel
-0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel
-0x0048 Word name-length
-0x004A Word class-name length
-0x004C ???? key-name
-
-the Value-List
-==============
-Offset Size Contents
-0x0000 D-Word Offset 1st Value
-0x0004 D-Word Offset 2nd Value
-0x???? D-Word Offset nth Value
-
-To determine the number of values, you have to look at the owner-nk-record!
-
-Der vk-Record
-=============
-Offset Size Contents
-0x0000 Word ID: ASCII-"vk" = 0x6B76
-0x0002 Word name length
-0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel
-0x0008 D-Word Offset of Data
-0x000C D-Word Type of value
-0x0010 Word Flag
-0x0012 Word Unused (data-trash)
-0x0014 ???? Name
-
-If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default)
-
-If the data-size is lower 5, the data-offset value is used to store the data itself!
-
-The data-types
-==============
-Wert Beteutung
-0x0001 RegSZ: character string (in UNICODE!)
-0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!)
-0x0003 RegBin: raw-binary value
-0x0004 RegDWord: Dword
-0x0007 RegMultiSZ: multiple strings, separated with 0
- (UNICODE!)
-
-The "lf"-record
-===============
-Offset Size Contents
-0x0000 Word ID: ASCII-"lf" = 0x666C
-0x0002 Word number of keys
-0x0004 ???? Hash-Records
-
-Hash-Record
-===========
-Offset Size Contents
-0x0000 D-Word Offset of corresponding "nk"-Record
-0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv!
-
-Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the
-key-name you have to change the hash-value too!
-
-//These hashrecords must be sorted low to high within the lf record. Nigel.
-
-The "sk"-block
-==============
-(due to the complexity of the SAM-info, not clear jet)
-
-Offset Size Contents
-0x0000 Word ID: ASCII-"sk" = 0x6B73
-0x0002 Word Unused
-0x0004 D-Word Offset of previous "sk"-Record
-0x0008 D-Word Offset of next "sk"-Record
-0x000C D-Word usage-counter
-0x0010 D-Word Size of "sk"-record in bytes
-???? //standard self
-relative security desciptor. Nigel
-???? ???? Security and auditing settings...
-????
-
-The usage counter counts the number of references to this
-"sk"-record. You can use one "sk"-record for the entire registry!
-
-Windows nt date/time format
-===========================
-The time-format is a 64-bit integer which is incremented every
-0,0000001 seconds by 1 (I don't know how accurate it realy is!)
-It starts with 0 at the 1st of january 1601 0:00! All values are
-stored in GMT time! The time-zone is important to get the real
-time!
-
-Common values for win95 and win-nt
-==================================
-Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
-If a value has no name (length=0, flag(bit 0)=0), it is treated as the
-"Default" entry...
-If a value has no data (length=0), it is displayed as empty.
-
-simplyfied win-3.?? registry:
-=============================
-
-+-----------+
-| next rec. |---+ +----->+------------+
-| first sub | | | | Usage cnt. |
-| name | | +-->+------------+ | | length |
-| value | | | | next rec. | | | text |------->+-------+
-+-----------+ | | | name rec. |--+ +------------+ | xxxxx |
- +------------+ | | value rec. |-------->+------------+ +-------+
- v | +------------+ | Usage cnt. |
-+-----------+ | | length |
-| next rec. | | | text |------->+-------+
-| first sub |------+ +------------+ | xxxxx |
-| name | +-------+
-| value |
-+-----------+
-
-Greatly simplyfied structure of the nt-registry:
-================================================
-
-+---------------------------------------------------------------+
-| |
-v |
-+---------+ +---------->+-----------+ +----->+---------+ |
-| "nk" | | | lf-rec. | | | nk-rec. | |
-| ID | | | # of keys | | | parent |---+
-| Date | | | 1st key |--+ | .... |
-| parent | | +-----------+ +---------+
-| suk-keys|-----+
-| values |--------------------->+----------+
-| SK-rec. |---------------+ | 1. value |--> +----------+
-| class |--+ | +----------+ | vk-rec. |
-+---------+ | | | .... |
- v | | data |--> +-------+
- +------------+ | +----------+ | xxxxx |
- | Class name | | +-------+
- +------------+ |
- v
- +---------+ +---------+
- +----->| next sk |--->| Next sk |--+
- | +---| prev sk |<---| prev sk | |
- | | | .... | | ... | |
- | | +---------+ +---------+ |
- | | ^ | |
- | +----------+ |
- +-------------------------------+
-
----------------------------------------------------------------------------
-
-Hope this helps.... (Although it was "fun" for me to uncover this things,
- it took me several sleepless nights ;)
-
- B.D.
-
-*************************************************************************/
-#include "includes.h"
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-typedef unsigned int DWORD;
-typedef unsigned short WORD;
-
-#define REG_REGF_ID 0x66676572
-
-typedef struct regf_block {
- DWORD REGF_ID; /* regf */
- DWORD uk1;
- DWORD uk2;
- DWORD tim1, tim2;
- DWORD uk3; /* 1 */
- DWORD uk4; /* 3 */
- DWORD uk5; /* 0 */
- DWORD uk6; /* 1 */
- DWORD first_key; /* offset */
- unsigned int dblk_size;
- DWORD uk7[116]; /* 1 */
- DWORD chksum;
-} REGF_HDR;
-
-typedef struct hbin_sub_struct {
- DWORD dblocksize;
- char data[1];
-} HBIN_SUB_HDR;
-
-#define REG_HBIN_ID 0x6E696268
-
-typedef struct hbin_struct {
- DWORD HBIN_ID; /* hbin */
- DWORD next_off;
- DWORD prev_off;
- DWORD uk1;
- DWORD uk2;
- DWORD uk3;
- DWORD uk4;
- DWORD blk_size;
- HBIN_SUB_HDR hbin_sub_hdr;
-} HBIN_HDR;
-
-#define REG_NK_ID 0x6B6E
-
-typedef struct nk_struct {
- WORD NK_ID;
- WORD type;
- DWORD t1, t2;
- DWORD uk1;
- DWORD own_off;
- DWORD subk_num;
- DWORD uk2;
- DWORD lf_off;
- DWORD uk3;
- DWORD val_cnt;
- DWORD val_off;
- DWORD sk_off;
- DWORD clsnam_off;
-} NK_HDR;
-
-#define REG_SK_ID 0x6B73
-
-typedef struct sk_struct {
- WORD SK_ID;
- WORD uk1;
- DWORD prev_off;
- DWORD next_off;
- DWORD ref_cnt;
- DWORD rec_size;
- char sec_desc[1];
-} SK_HDR;
-
-typedef struct sec_desc_rec {
- WORD rev;
- WORD type;
- DWORD owner_off;
- DWORD group_off;
- DWORD sacl_off;
- DWORD dacl_off;
-} MY_SEC_DESC;
-
-typedef struct ace_struct {
- unsigned char type;
- unsigned char flags;
- unsigned short length;
- unsigned int perms;
- DOM_SID trustee;
-} ACE;
-
-typedef struct acl_struct {
- WORD rev;
- WORD size;
- DWORD num_aces;
- ACE *aces; /* One or more ACEs */
-} ACL;
-
-#define OFF(f) (0x1000 + (f) + 4)
-
-static void print_sid(DOM_SID *sid);
-
-int verbose = 1;
-DOM_SID old_sid, new_sid;
-int change = 0, new = 0;
-
-/* Compare two SIDs for equality */
-static int my_sid_equal(DOM_SID *s1, DOM_SID *s2)
-{
- int sa1, sa2;
-
- if (s1->sid_rev_num != s2->sid_rev_num) return 0;
-
- sa1 = s1->num_auths; sa2 = s2->num_auths;
-
- if (sa1 != sa2) return 0;
-
- return !memcmp((char *)&s1->id_auth, (char *)&s2->id_auth,
- 6 + sa1 * 4);
-
-}
-
-/*
- * Quick and dirty to read a SID in S-1-5-21-x-y-z-rid format and
- * construct a DOM_SID
- */
-static int get_sid(DOM_SID *sid, const unsigned char *sid_str)
-{
- int i = 0, auth;
- const unsigned char *lstr;
-
- if (strncmp(sid_str, "S-1-5", 5)) {
- fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str);
- return 0;
- }
-
- /* We only allow strings of form S-1-5... */
-
- sid->sid_rev_num = 1;
- sid->id_auth[5] = 5;
-
- lstr = sid_str + 5;
-
- while (1) {
- if (!lstr || !lstr[0] || sscanf(lstr, "-%u", &auth) == 0) {
- if (i < 4) {
- fprintf(stderr, "Not of form -d-d...: %s, %u\n", lstr, i);
- return 0;
- }
- sid->num_auths=i;
- print_sid(sid);
- return 1;
- }
-
- SIVAL(&sid->sub_auths[i], 0, auth);
- i++;
- lstr = (const unsigned char *)strchr(lstr + 1, '-');
- }
-
- return 1;
-}
-
-#if 0
-
-/*
- * Replace SID1, component by component with SID2
- * Assumes will never be called with unequal length SIDS
- * so only touches 21-x-y-z-rid portion
- * This routine does not need to deal with endianism as
- * long as the incoming SIDs are both in the same (LE) format.
- */
-static void change_sid(DOM_SID *s1, DOM_SID *s2)
-{
- int i;
-
- for (i=0; i<s1->num_auths; i++) {
- s1->sub_auths[i] = s2->sub_auths[i];
- }
-}
-
-#endif
-
-static void print_sid(DOM_SID *sid)
-{
- int i, comps = sid->num_auths;
- fprintf(stdout, "S-%u-%u", sid->sid_rev_num, sid->id_auth[5]);
-
- for (i = 0; i < comps; i++) {
-
- fprintf(stdout, "-%u", IVAL(&sid->sub_auths[i],0));
-
- }
- fprintf(stdout, "\n");
-}
-
-static void process_sid(DOM_SID *sid, DOM_SID *o_sid, DOM_SID *n_sid)
-{
- int i;
- if (my_sid_equal(sid, o_sid)) {
-
- for (i=0; i<sid->num_auths; i++) {
- sid->sub_auths[i] = n_sid->sub_auths[i];
-
- }
-
- }
-
-}
-
-static void process_acl(ACL *acl, const char *prefix)
-{
- int ace_cnt, i;
- ACE *ace;
-
- ace_cnt = IVAL(&acl->num_aces, 0);
- ace = (ACE *)&acl->aces;
- if (verbose) fprintf(stdout, "%sACEs: %u\n", prefix, ace_cnt);
- for (i=0; i<ace_cnt; i++) {
- if (verbose) fprintf(stdout, "%s Perms: %08X, SID: ", prefix,
- IVAL(&ace->perms, 0));
- if (change)
- process_sid(&ace->trustee, &old_sid, &new_sid);
- print_sid(&ace->trustee);
- ace = (ACE *)((char *)ace + SVAL(&ace->length, 0));
- }
-}
-
-int main(int argc, char *argv[])
-{
- int opt;
- int fd, start = 0;
- char *base;
- struct stat sbuf;
- REGF_HDR *regf_hdr;
- HBIN_HDR *hbin_hdr;
- NK_HDR *nk_hdr;
- SK_HDR *sk_hdr;
- DWORD first_sk_off, sk_off;
- MY_SEC_DESC *sec_desc;
- int *ptr;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "Sets verbose mode" },
- { "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" },
- { "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" },
- { 0, 0, 0, 0 }
- };
-
- poptContext pc;
-
- pc = poptGetContext("profiles", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- poptSetOtherOptionHelp(pc, "<profilefile>");
-
- /*
- * Now, process the arguments
- */
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'c':
- change = 1;
- if (!get_sid(&old_sid, poptGetOptArg(pc))) {
- fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n");
- poptPrintUsage(pc, stderr, 0);
- exit(254);
- }
- break;
-
- case 'n':
- new = 1;
- if (!get_sid(&new_sid, poptGetOptArg(pc))) {
- fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n");
- poptPrintUsage(pc, stderr, 0);
- exit(253);
- }
-
- break;
-
- case 'v':
- verbose++;
- break;
- }
- }
-
- if (!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
-
- if ((!change & new) || (change & !new)) {
- fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n");
- poptPrintUsage(pc, stderr, 0);
- exit(252);
- }
-
- poptGetArg(pc); /* To get argv[0] */
-
- fd = open(poptPeekArg(pc), O_RDWR, 0000);
-
- if (fd < 0) {
- fprintf(stderr, "Could not open %s: %s\n", poptPeekArg(pc),
- strerror(errno));
- exit(2);
- }
-
- if (fstat(fd, &sbuf) < 0) {
- fprintf(stderr, "Could not stat file %s, %s\n", poptPeekArg(pc),
- strerror(errno));
- exit(3);
- }
-
- /*
- * Now, mmap the file into memory, check the header and start
- * dealing with the records. We are interested in the sk record
- */
- start = 0;
-
-#ifdef HAVE_MMAP
- base = mmap(&start, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-#else
- base = (char *)-1;
- errno = ENOSYS;
-#endif
-
- if ((int)base == -1) {
- fprintf(stderr, "Could not mmap file: %s, %s\n", poptPeekArg(pc),
- strerror(errno));
- exit(4);
- }
-
- /*
- * In what follows, and in places above, in order to work on both LE and
- * BE platforms, we have to use the Samba macros to extract SHORT, LONG
- * and associated UNSIGNED quantities from the data in the mmap'd file.
- * NOTE, however, that we do not need to do anything with memory
- * addresses that we construct from pointers in our address space.
- * For example,
- *
- * sec_desc = (MY_SEC_DESC *)&(sk_hdr->sec_desc[0]);
- *
- * is simply taking the address of a structure we already have the address
- * of in our address space, while, the fields within it, will have to
- * be accessed with the macros:
- *
- * owner_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] +
- * IVAL(&sec_desc->owner_off, 0));
- *
- * Which is pulling out an offset and adding it to an existing pointer.
- *
- */
-
- regf_hdr = (REGF_HDR *)base;
-
- if (verbose) fprintf(stdout, "Registry file size: %u\n", (unsigned int)sbuf.st_size);
-
- if (IVAL(&regf_hdr->REGF_ID, 0) != REG_REGF_ID) {
- fprintf(stderr, "Incorrect Registry file (doesn't have header ID): %s\n", poptPeekArg(pc));
- exit(5);
- }
-
- if (verbose) fprintf(stdout, "First Key Off: %u, Data Block Size: %u\n",
- IVAL(&regf_hdr->first_key, 0),
- IVAL(&regf_hdr->dblk_size, 0));
-
- hbin_hdr = (HBIN_HDR *)(base + 0x1000); /* No need for Endian stuff */
-
- /*
- * This should be the hbin_hdr
- */
-
- if (IVAL(&hbin_hdr->HBIN_ID, 0) != REG_HBIN_ID) {
- fprintf(stderr, "Incorrect hbin hdr: %s\n", poptPeekArg(pc));
- exit(6);
- }
-
- if (verbose) fprintf(stdout, "Next Off: %u, Prev Off: %u\n",
- IVAL(&hbin_hdr->next_off, 0),
- IVAL(&hbin_hdr->prev_off, 0));
-
- nk_hdr = (NK_HDR *)(base + 0x1000 + IVAL(&regf_hdr->first_key, 0) + 4);
-
- if (SVAL(&nk_hdr->NK_ID, 0) != REG_NK_ID) {
- fprintf(stderr, "Incorrect NK Header: %s\n", poptPeekArg(pc));
- exit(7);
- }
-
- sk_off = first_sk_off = IVAL(&nk_hdr->sk_off, 0);
- if (verbose) {
- fprintf(stdout, "Type: %0x\n", SVAL(&nk_hdr->type, 0));
- fprintf(stdout, "SK Off : %o\n", (0x1000 + sk_off + 4));
- }
-
- sk_hdr = (SK_HDR *)(base + 0x1000 + sk_off + 4);
-
- do {
- DOM_SID *owner_sid, *group_sid;
- ACL *sacl, *dacl;
- if (SVAL(&sk_hdr->SK_ID, 0) != REG_SK_ID) {
- fprintf(stderr, "Incorrect SK Header format: %08X\n",
- (0x1000 + sk_off + 4));
- exit(8);
- }
- ptr = (int *)sk_hdr;
- if (verbose) fprintf(stdout, "Off: %08X, Refs: %u, Size: %u\n",
- sk_off, IVAL(&sk_hdr->ref_cnt, 0),
- IVAL(&sk_hdr->rec_size, 0));
-
- sec_desc = (MY_SEC_DESC *)&(sk_hdr->sec_desc[0]);
- owner_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] +
- IVAL(&sec_desc->owner_off, 0));
- group_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] +
- IVAL(&sec_desc->group_off, 0));
- sacl = (ACL *)(&sk_hdr->sec_desc[0] +
- IVAL(&sec_desc->sacl_off, 0));
- dacl = (ACL *)(&sk_hdr->sec_desc[0] +
- IVAL(&sec_desc->dacl_off, 0));
- if (verbose)fprintf(stdout, " Owner SID: ");
- if (change) process_sid(owner_sid, &old_sid, &new_sid);
- if (verbose) print_sid(owner_sid);
- if (verbose) fprintf(stdout, " Group SID: ");
- if (change) process_sid(group_sid, &old_sid, &new_sid);
- if (verbose) print_sid(group_sid);
- fprintf(stdout, " SACL: ");
- if (!sec_desc->sacl_off) { /* LE zero == BE zero */
- if (verbose) fprintf(stdout, "NONE\n");
- }
- else
- process_acl(sacl, " ");
- if (verbose) fprintf(stdout, " DACL: ");
- if (!sec_desc->dacl_off) {
- if (verbose) fprintf(stdout, "NONE\n");
- }
- else
- process_acl(dacl, " ");
- sk_off = IVAL(&sk_hdr->prev_off, 0);
- sk_hdr = (SK_HDR *)(base + OFF(IVAL(&sk_hdr->prev_off, 0)));
- } while (sk_off != first_sk_off);
-
-#ifdef HAVE_MMAP
- munmap(base, sbuf.st_size);
-#endif
-
- poptFreeContext(pc);
-
- close(fd);
- return 0;
-}
diff --git a/source/utils/rpccheck.c b/source/utils/rpccheck.c
index ae109f69b65..e8e61e9f718 100644
--- a/source/utils/rpccheck.c
+++ b/source/utils/rpccheck.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.
Copyright (C) Jean François Micouleau 2001
@@ -38,13 +39,14 @@ main()
setup_logging("", True);
DEBUGLEVEL=10;
- ctx=talloc_init("main");
- if (!ctx) exit(1);
+ ctx=talloc_init();
+ if (!ctx)
+ exit(1);
prs_init(&ps, 1600, 4, ctx, MARSHALL);
while (scanf("%s", s)!=-1) {
- if (strlen(s)==2 && strchr_m(filter, *s)!=NULL && strchr_m(filter, *(s+1))!=NULL) {
+ if (strlen(s)==2 && strchr(filter, *s)!=NULL && strchr(filter, *(s+1))!=NULL) {
d=strtol(s, NULL, 16);
if(!prs_append_data(&ps, &d, 1))
printf("error while reading data\n");
diff --git a/source/torture/rpctorture.c b/source/utils/rpctorture.c
index d95c0cee0fe..3cef9b51b64 100644..100755
--- a/source/torture/rpctorture.c
+++ b/source/utils/rpctorture.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
SMB client
Copyright (C) Andrew Tridgell 1994-1998
@@ -18,6 +19,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
#include "includes.h"
#ifndef REGISTER
@@ -193,7 +198,7 @@ static void usage(char *pname)
fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
pname);
- fprintf(out_hnd, "\nVersion %s\n",SAMBA_VERSION_STRING);
+ fprintf(out_hnd, "\nVersion %s\n",VERSION);
fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n");
fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n");
@@ -220,8 +225,10 @@ enum client_action
{
char *pname = argv[0];
int opt;
+ extern FILE *dbf;
extern char *optarg;
extern int optind;
+ static pstring servicesf = CONFIGFILE;
pstring term_code;
BOOL got_pass = False;
char *cmd_str="";
@@ -242,11 +249,13 @@ enum client_action
*term_code = 0;
#endif /* KANJI */
- if (!lp_load(dyn_CONFIGFILE,True, False, False))
+ if (!lp_load(servicesf,True, False, False))
{
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
+ codepage_initialise(lp_client_code_page());
+
DEBUGLEVEL = 0;
cli_info.put_total_size = 0;
@@ -289,6 +298,9 @@ enum client_action
setup_logging(pname, True);
+ TimeInit();
+ charset_initialise();
+
if (!get_myname(global_myname))
{
fprintf(stderr, "Failed to get my hostname.\n");
@@ -363,7 +375,7 @@ enum client_action
case 'S':
{
pstrcpy(cli_info.dest_host,optarg);
- strupper_m(cli_info.dest_host);
+ strupper(cli_info.dest_host);
cli_action = CLIENT_IPC;
break;
}
@@ -378,12 +390,12 @@ enum client_action
{
char *lp;
pstrcpy(smb_cli->user_name,optarg);
- if ((lp=strchr_m(smb_cli->user_name,'%')))
+ if ((lp=strchr(smb_cli->user_name,'%')))
{
*lp = 0;
pstrcpy(password,lp+1);
got_pass = True;
- memset(strchr_m(optarg,'%')+1,'X',strlen(password));
+ memset(strchr(optarg,'%')+1,'X',strlen(password));
}
break;
}
@@ -396,14 +408,14 @@ enum client_action
case 'E':
{
- dbf = x_stderr;
+ dbf = stderr;
break;
}
case 'I':
{
cli_info.dest_ip = *interpret_addr2(optarg);
- if (is_zero_ip(cli_info.dest_ip))
+ if (zero_ip(cli_info.dest_ip))
{
exit(1);
}
@@ -461,7 +473,7 @@ enum client_action
case 's':
{
- pstrcpy(dyn_CONFIGFILE, optarg);
+ pstrcpy(servicesf, optarg);
break;
}
@@ -486,16 +498,16 @@ enum client_action
exit(1);
}
- strupper_m(global_myname);
+ strupper(global_myname);
fstrcpy(cli_info.myhostname, global_myname);
- DEBUG(3,("%s client started (version %s)\n",timestring(False),SAMBA_VERSION_STRING));
+ DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
if (*smb_cli->domain == 0)
{
pstrcpy(smb_cli->domain,lp_workgroup());
}
- strupper_m(smb_cli->domain);
+ strupper(smb_cli->domain);
load_interfaces();
@@ -506,7 +518,7 @@ enum client_action
}
fstrcpy(cli_info.mach_acct, cli_info.myhostname);
- strupper_m(cli_info.mach_acct);
+ strupper(cli_info.mach_acct);
fstrcat(cli_info.mach_acct, "$");
/* set the password cache info */
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 5a70d168842..13e00a2d915 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -5,7 +5,6 @@
Copyright (C) Andrew Tridgell 2000
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2000
- Copyright (C) Jelmer Vernooij 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,16 +23,21 @@
#include "includes.h"
+static fstring password;
+static pstring username;
static pstring owner_username;
static fstring server;
-static int test_args = False;
-static TALLOC_CTX *ctx;
+static fstring workgroup = "";
+static int got_pass;
+static int test_args;
+TALLOC_CTX *ctx;
#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
+#define CREATE_ACCESS_WRITE (WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS)
/* numeric is set when the user wants numeric SIDs and ACEs rather
than going via LSA calls to resolve them */
-static BOOL numeric = False;
+static int numeric;
enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD };
enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP};
@@ -46,7 +50,7 @@ struct perm_value {
/* These values discovered by inspection */
-static const struct perm_value special_values[] = {
+static struct perm_value special_values[] = {
{ "R", 0x00120089 },
{ "W", 0x00120116 },
{ "X", 0x001200a0 },
@@ -56,32 +60,31 @@ static const struct perm_value special_values[] = {
{ NULL, 0 },
};
-static const struct perm_value standard_values[] = {
+static struct perm_value standard_values[] = {
{ "READ", 0x001200a9 },
{ "CHANGE", 0x001301bf },
{ "FULL", 0x001f01ff },
{ NULL, 0 },
};
-static struct cli_state *global_hack_cli;
-static POLICY_HND pol;
-static BOOL got_policy_hnd;
-
-static struct cli_state *connect_one(const char *share);
+struct cli_state lsa_cli;
+POLICY_HND pol;
+struct ntuser_creds creds;
+BOOL got_policy_hnd;
/* Open cli connection and policy handle */
static BOOL cacls_open_policy_hnd(void)
{
+ creds.pwd.null_pwd = 1;
+
/* Initialise cli LSA connection */
- if (!global_hack_cli) {
- global_hack_cli = connect_one("IPC$");
- if (!cli_nt_session_open (global_hack_cli, PI_LSARPC)) {
- return False;
- }
+ if (!lsa_cli.initialised &&
+ !cli_lsa_initialise(&lsa_cli, server, &creds)) {
+ return False;
}
-
+
/* Open policy handle */
if (!got_policy_hnd) {
@@ -89,8 +92,8 @@ static BOOL cacls_open_policy_hnd(void)
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
- if (!NT_STATUS_IS_OK(cli_lsa_open_policy(global_hack_cli, global_hack_cli->mem_ctx, True,
- GENERIC_EXECUTE_ACCESS, &pol))) {
+ if (!NT_STATUS_IS_OK(cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True,
+ GENERIC_EXECUTE_ACCESS, &pol))) {
return False;
}
@@ -111,10 +114,17 @@ static void SidToString(fstring str, DOM_SID *sid)
if (numeric) return;
+ if (strcmp(str, "S-1-1-0") == 0) {
+
+ fstrcpy(str, "everyone");
+ return;
+
+ }
+
/* Ask LSA to convert the sid to a name */
if (!cacls_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_sids(global_hack_cli, global_hack_cli->mem_ctx,
+ !NT_STATUS_IS_OK(cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx,
&pol, 1, sid, &domains,
&names, &types)) ||
!domains || !domains[0] || !names || !names[0]) {
@@ -122,7 +132,7 @@ static void SidToString(fstring str, DOM_SID *sid)
}
/* Converted OK */
-
+
slprintf(str, sizeof(fstring) - 1, "%s%s%s",
domains[0], lp_winbind_separator(),
names[0]);
@@ -135,13 +145,13 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
uint32 *types = NULL;
DOM_SID *sids = NULL;
BOOL result = True;
-
+
if (strncmp(str, "S-", 2) == 0) {
return string_to_sid(sid, str);
}
if (!cacls_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_names(global_hack_cli, global_hack_cli->mem_ctx,
+ !NT_STATUS_IS_OK(cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx,
&pol, 1, &str, &sids,
&types))) {
result = False;
@@ -149,6 +159,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
}
sid_copy(sid, &sids[0]);
+
done:
return result;
@@ -158,7 +169,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
/* print an ACE on a FILE, using either numeric or ascii representation */
static void print_ace(FILE *f, SEC_ACE *ace)
{
- const struct perm_value *v;
+ struct perm_value *v;
fstring sidstr;
int do_print = 0;
uint32 got_mask;
@@ -231,13 +242,14 @@ static BOOL parse_ace(SEC_ACE *ace, char *str)
unsigned atype, aflags, amask;
DOM_SID sid;
SEC_ACCESS mask;
- const struct perm_value *v;
+ struct perm_value *v;
ZERO_STRUCTP(ace);
- p = strchr_m(str,':');
+ p = strchr(str,':');
if (!p) return False;
*p = '\0';
p++;
+
/* Try to parse numeric form */
if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
@@ -389,7 +401,7 @@ static SEC_DESC *sec_desc_parse(char *str)
return NULL;
}
- ret = make_sec_desc(ctx,revision, SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid,
+ ret = make_sec_desc(ctx,revision, owner_sid, grp_sid,
NULL, dacl, &sd_size);
SAFE_FREE(grp_sid);
@@ -405,7 +417,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
fstring sidstr;
uint32 i;
- fprintf(f, "REVISION:%d\n", sd->revision);
+ printf("REVISION:%d\n", sd->revision);
/* Print owner and group sid */
@@ -415,7 +427,7 @@ static void sec_desc_print(FILE *f, SEC_DESC *sd)
fstrcpy(sidstr, "");
}
- fprintf(f, "OWNER:%s\n", sidstr);
+ printf("OWNER:%s\n", sidstr);
if (sd->grp_sid) {
SidToString(sidstr, sd->grp_sid);
@@ -440,36 +452,29 @@ dump the acls for a file
*******************************************************/
static int cacl_dump(struct cli_state *cli, char *filename)
{
- int result = EXIT_FAILED;
- int fnum = -1;
+ int fnum;
SEC_DESC *sd;
- if (test_args)
- return EXIT_OK;
+ if (test_args) return EXIT_OK;
fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
-
if (fnum == -1) {
printf("Failed to open %s: %s\n", filename, cli_errstr(cli));
- goto done;
+ return EXIT_FAILED;
}
sd = cli_query_secdesc(cli, fnum, ctx);
if (!sd) {
printf("ERROR: secdesc query failed: %s\n", cli_errstr(cli));
- goto done;
+ return EXIT_FAILED;
}
sec_desc_print(stdout, sd);
- result = EXIT_OK;
-
-done:
- if (fnum != -1)
- cli_close(cli, fnum);
+ cli_close(cli, fnum);
- return result;
+ return EXIT_OK;
}
/*****************************************************
@@ -504,12 +509,12 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode,
return EXIT_FAILED;
}
- sd = make_sec_desc(ctx,old->revision, old->type,
- (change_mode == REQUEST_CHOWN) ? &sid : NULL,
- (change_mode == REQUEST_CHGRP) ? &sid : NULL,
- NULL, NULL, &sd_size);
+ sd = make_sec_desc(ctx,old->revision,
+ (change_mode == REQUEST_CHOWN) ? &sid : old->owner_sid,
+ (change_mode == REQUEST_CHGRP) ? &sid : old->grp_sid,
+ NULL, old->dacl, &sd_size);
- fnum = cli_nt_create(cli, filename, WRITE_OWNER_ACCESS);
+ fnum = cli_nt_create(cli, filename, CREATE_ACCESS_WRITE);
if (fnum == -1) {
printf("Failed to open %s: %s\n", filename, cli_errstr(cli));
@@ -679,10 +684,10 @@ static int cacl_set(struct cli_state *cli, char *filename,
sort_acl(old->dacl);
/* Create new security descriptor and set it */
- sd = make_sec_desc(ctx,old->revision, old->type, NULL, NULL,
+ sd = make_sec_desc(ctx,old->revision, old->owner_sid, old->grp_sid,
NULL, old->dacl, &sd_size);
- fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS);
+ fnum = cli_nt_create(cli, filename, CREATE_ACCESS_WRITE);
if (fnum == -1) {
printf("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli));
@@ -705,143 +710,247 @@ static int cacl_set(struct cli_state *cli, char *filename,
/*****************************************************
return a connection to a server
*******************************************************/
-static struct cli_state *connect_one(const char *share)
+struct cli_state *connect_one(char *share)
{
struct cli_state *c;
+ struct nmb_name called, calling;
struct in_addr ip;
- NTSTATUS nt_status;
+ extern pstring global_myname;
+
+ fstrcpy(server,share+2);
+ share = strchr(server,'\\');
+ if (!share) return NULL;
+ *share = 0;
+ share++;
+
zero_ip(&ip);
-
- if (!cmdline_auth_info.got_pass) {
+
+ make_nmb_name(&calling, global_myname, 0x0);
+ make_nmb_name(&called , server, 0x20);
+
+ again:
+ zero_ip(&ip);
+
+ /* have to open a new connection */
+ if (!(c=cli_initialise(NULL)) || !cli_connect(c, server, &ip)) {
+ DEBUG(0,("Connection to %s failed\n", server));
+ cli_shutdown(c);
+ return NULL;
+ }
+
+ if (!cli_session_request(c, &calling, &called)) {
+ DEBUG(0,("session request to %s failed\n", called.name));
+ cli_shutdown(c);
+ if (strcmp(called.name, "*SMBSERVER")) {
+ make_nmb_name(&called , "*SMBSERVER", 0x20);
+ goto again;
+ }
+ return NULL;
+ }
+
+ DEBUG(4,(" session request ok\n"));
+
+ if (!cli_negprot(c)) {
+ DEBUG(0,("protocol negotiation failed\n"));
+ cli_shutdown(c);
+ return NULL;
+ }
+
+ if (!got_pass) {
char *pass = getpass("Password: ");
if (pass) {
- pstrcpy(cmdline_auth_info.password, pass);
- cmdline_auth_info.got_pass = True;
+ pstrcpy(password, pass);
}
}
- if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,
- &ip, 0,
- share, "?????",
- cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0,
- cmdline_auth_info.signing_state, NULL))) {
- return c;
- } else {
- DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
+ if (!cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ (workgroup[0] ? workgroup : lp_workgroup()))) {
+ DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
+ cli_shutdown(c);
return NULL;
}
+
+ DEBUG(4,(" session setup ok\n"));
+
+ if (!cli_send_tconX(c, share, "?????",
+ password, strlen(password)+1)) {
+ DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ cli_shutdown(c);
+ return NULL;
+ }
+
+ DEBUG(4,(" tconx ok\n"));
+
+ return c;
+}
+
+
+static void usage(void)
+{
+ printf("Usage: smbcacls //server1/share1 filename [options]\n");
+ printf("Version: %s\n", VERSION);
+ printf(
+"\n\
+\t-D <acls> delete an acl\n\
+\t-M <acls> modify an acl\n\
+\t-A <acls> add an acl\n\
+\t-S <acls> set acls\n\
+\t-C username change ownership of a file\n\
+\t-G username change group ownership of a file\n\
+\t-n don't resolve sids or masks to names\n\
+\t-h print help\n\
+\t-d debuglevel set debug output level\n\
+\t-U username user to autheticate as\n\
+\t-W workgroup or domain workgroup or domain user is in\n\
+\n\
+The username can be of the form username%%password or\n\
+workgroup\\username%%password.\n\n\
+An acl is of the form ACL:<SID>:type/flags/mask\n\
+You can string acls together with spaces, commas or newlines\n\
+");
}
/****************************************************************************
main program
****************************************************************************/
- int main(int argc, const char *argv[])
+ int main(int argc,char *argv[])
{
char *share;
+ pstring filename;
+ extern char *optarg;
+ extern int optind;
+ extern FILE *dbf;
int opt;
+ char *p;
+ static pstring servicesf = CONFIGFILE;
+ struct cli_state *cli=NULL;
enum acl_mode mode = SMB_ACL_SET;
- static char *the_acl = NULL;
+ char *the_acl = NULL;
enum chown_mode change_mode = REQUEST_NONE;
int result;
- fstring path;
- pstring filename;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "delete", 'D', POPT_ARG_STRING, NULL, 'D', "Delete an acl", "ACL" },
- { "modify", 'M', POPT_ARG_STRING, NULL, 'M', "Modify an acl", "ACL" },
- { "add", 'a', POPT_ARG_STRING, NULL, 'a', "Add an acl", "ACL" },
- { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls", "ACLS" },
- { "chown", 'C', POPT_ARG_STRING, NULL, 'C', "Change ownership of a file", "USERNAME" },
- { "chgrp", 'G', POPT_ARG_STRING, NULL, 'G', "Change group ownership of a file", "GROUPNAME" },
- { "numeric", 0, POPT_ARG_NONE, &numeric, True, "Don't resolve sids or masks to names" },
- { "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"},
- POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
- { NULL }
- };
-
- struct cli_state *cli;
-
- ctx=talloc_init("main");
+
+ ctx=talloc_init();
setlinebuf(stdout);
- dbf = x_stderr;
+ dbf = stderr;
+
+ if (argc < 3 || argv[1][0] == '-') {
+ usage();
+ talloc_destroy(ctx);
+ exit(EXIT_PARSE_ERROR);
+ }
setup_logging(argv[0],True);
- lp_load(dyn_CONFIGFILE,True,False,False);
+ share = argv[1];
+ pstrcpy(filename, argv[2]);
+ all_string_sub(share,"/","\\",0);
+
+ argc -= 2;
+ argv += 2;
+
+ TimeInit();
+ charset_initialise();
+
+ lp_load(servicesf,True,False,False);
+ codepage_initialise(lp_client_code_page());
load_interfaces();
- pc = poptGetContext("smbcacls", argc, argv, long_options, 0);
-
- poptSetOtherOptionHelp(pc, "//server1/share1 filename");
+ if (getenv("USER")) {
+ pstrcpy(username,getenv("USER"));
+
+ if ((p=strchr(username,'%'))) {
+ *p = 0;
+ pstrcpy(password,p+1);
+ got_pass = True;
+ memset(strchr(getenv("USER"), '%') + 1, 'X',
+ strlen(password));
+ }
+ }
- while ((opt = poptGetNextOpt(pc)) != -1) {
+ while ((opt = getopt(argc, argv, "U:nhdS:D:A:M:C:G:t")) != EOF) {
switch (opt) {
+ case 'U':
+ pstrcpy(username,optarg);
+ p = strchr(username,'%');
+ if (p) {
+ *p = 0;
+ pstrcpy(password, p+1);
+ got_pass = 1;
+ }
+ break;
+
+ case 'W':
+ pstrcpy(workgroup, optarg);
+ break;
+
case 'S':
- the_acl = smb_xstrdup(poptGetOptArg(pc));
+ the_acl = optarg;
mode = SMB_ACL_SET;
break;
case 'D':
- the_acl = smb_xstrdup(poptGetOptArg(pc));
+ the_acl = optarg;
mode = SMB_ACL_DELETE;
break;
case 'M':
- the_acl = smb_xstrdup(poptGetOptArg(pc));
+ the_acl = optarg;
mode = SMB_ACL_MODIFY;
break;
- case 'a':
- the_acl = smb_xstrdup(poptGetOptArg(pc));
+ case 'A':
+ the_acl = optarg;
mode = SMB_ACL_ADD;
break;
case 'C':
- pstrcpy(owner_username,poptGetOptArg(pc));
+ pstrcpy(owner_username,optarg);
change_mode = REQUEST_CHOWN;
break;
case 'G':
- pstrcpy(owner_username,poptGetOptArg(pc));
+ pstrcpy(owner_username,optarg);
change_mode = REQUEST_CHGRP;
break;
- }
- }
- /* Make connection to server */
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- return -1;
- }
-
- fstrcpy(path, poptGetArg(pc));
-
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- return -1;
- }
-
- pstrcpy(filename, poptGetArg(pc));
+ case 'n':
+ numeric = 1;
+ break;
+
+ case 't':
+ test_args = 1;
+ break;
+
+ case 'h':
+ usage();
+ talloc_destroy(ctx);
+ exit(EXIT_PARSE_ERROR);
- all_string_sub(path,"/","\\",0);
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ break;
- fstrcpy(server,path+2);
- share = strchr_m(server,'\\');
- if (!share) {
- share = strchr_m(server,'/');
- if (!share) {
- printf("Invalid argument: %s\n", share);
- return -1;
+ default:
+ printf("Unknown option %c (%d)\n", (char)opt, opt);
+ talloc_destroy(ctx);
+ exit(EXIT_PARSE_ERROR);
}
}
- *share = 0;
- share++;
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0) {
+ usage();
+ talloc_destroy(ctx);
+ exit(EXIT_PARSE_ERROR);
+ }
+
+ /* Make connection to server */
if (!test_args) {
cli = connect_one(share);
@@ -849,15 +958,13 @@ static struct cli_state *connect_one(const char *share)
talloc_destroy(ctx);
exit(EXIT_FAILED);
}
- } else {
- exit(0);
}
all_string_sub(filename, "/", "\\", 0);
if (filename[0] != '\\') {
pstring s;
s[0] = '\\';
- safe_strcpy(&s[1], filename, sizeof(pstring)-2);
+ safe_strcpy(&s[1], filename, sizeof(pstring)-1);
pstrcpy(filename, s);
}
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index 2eb661c8b68..96b8cb92668 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -1,12 +1,8 @@
/*
- Unix SMB/CIFS implementation.
-
- Send messages to other Samba daemons
-
- Copyright (C) Tim Potter 2003
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ program to send control messages to Samba processes
Copyright (C) Andrew Tridgell 1994-1998
- Copyright (C) Martin Pool 2001-2002
- Copyright (C) Simo Sorce 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,731 +21,394 @@
#include "includes.h"
-/* Default timeout value when waiting for replies (in seconds) */
-
-#define DEFAULT_TIMEOUT 10
-
-static int timeout = DEFAULT_TIMEOUT;
-static int num_replies; /* Used by message callback fns */
-
-/* Send a message to a destination pid. Zero means broadcast smbd. */
-
-static BOOL send_message(pid_t pid, int msg_type, const void *buf, int len,
- BOOL duplicates)
-{
- TDB_CONTEXT *tdb;
- BOOL ret;
- int n_sent = 0;
-
- if (!message_init())
- return False;
-
- if (pid != 0)
- return message_send_pid(pid, msg_type, buf, len, duplicates);
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDWR, 0);
- if (!tdb) {
- fprintf(stderr,"Failed to open connections database"
- ": %s\n", strerror(errno));
- return False;
- }
-
- ret = message_send_all(tdb,msg_type, buf, len, duplicates,
- &n_sent);
- DEBUG(10,("smbcontrol/send_message: broadcast message to "
- "%d processes\n", n_sent));
-
- tdb_close(tdb);
-
- return ret;
-}
+extern BOOL AllowDebugChange;
-/* Wait for one or more reply messages */
-
-static void wait_replies(BOOL multiple_replies)
-{
- time_t start_time = time(NULL);
-
- /* Wait around a bit. This is pretty disgusting - we have to
- busy-wait here as there is no nicer way to do it. */
-
- do {
- message_dispatch();
- if (num_replies > 0 && !multiple_replies)
- break;
- sleep(1);
- } while (timeout - (time(NULL) - start_time) > 0);
-}
-
-/* Message handler callback that displays the PID and a string on stdout */
-
-static void print_pid_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
-{
- printf("PID %u: %.*s", (unsigned int)pid, (int)len, (const char *)buf);
- num_replies++;
-}
-
-/* Message handler callback that displays a string on stdout */
-
-static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
-{
- printf("%.*s", (int)len, (const char *)buf);
- num_replies++;
-}
-
-/* Send no message. Useful for testing. */
-
-static BOOL do_noop(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> noop\n");
- return False;
- }
+static struct {
+ const char *name;
+ int value;
+} msg_types[] = {
+ {"debug", MSG_DEBUG},
+ {"force-election", MSG_FORCE_ELECTION},
+ {"ping", MSG_PING},
+ {"profile", MSG_PROFILE},
+ {"profilelevel", MSG_REQ_PROFILELEVEL},
+ {"debuglevel", MSG_REQ_DEBUGLEVEL},
+ {"printer-notify", MSG_PRINTER_NOTIFY},
+ {"close-share", MSG_SMB_FORCE_TDIS},
+ {NULL, -1}
+};
- /* Move along, nothing to see here */
+time_t timeout_start;
- return True;
-}
+#define MAX_WAIT 10
-/* Send a debug string */
-
-static BOOL do_debug(const pid_t pid, const int argc, const char **argv)
+static void usage(BOOL doexit)
{
- if (argc != 2) {
- fprintf(stderr, "Usage: smbcontrol <dest> debug "
- "<debug-string>\n");
- return False;
+ int i;
+ if (doexit) {
+ printf("Usage: smbcontrol [-d debuglevel] [-s configfile] [-i]\n");
+ printf(" smbcontrol [-d debuglevel] [-s configfile] <destination> <message-type> <parameters>\n\n");
+ } else {
+ printf("<destination> <message-type> <parameters>\n\n");
}
-
- return send_message(
- pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False);
+ printf("\t<destination> is one of \"nmbd\", \"smbd\" or a process ID\n");
+ printf("\t<message-type> is one of: ");
+ for (i=0; msg_types[i].name; i++)
+ printf("%s%s", i?", ":"",msg_types[i].name);
+ printf("\n");
+ if (doexit) exit(1);
}
-/* Force a browser election */
-
-static BOOL do_election(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> force-election\n");
- return False;
- }
-
- return send_message(
- pid, MSG_FORCE_ELECTION, NULL, 0, False);
-}
+static int pong_count;
+static BOOL got_level;
+static BOOL pong_registered = False;
+static BOOL debuglevel_registered = False;
+static BOOL profilelevel_registered = False;
-/* Ping a samba daemon process */
-static void pong_cb(int msg_type, pid_t pid, void *buf, size_t len)
+/****************************************************************************
+a useful function for testing the message system
+****************************************************************************/
+void pong_function(int msg_type, pid_t src, void *buf, size_t len)
{
- printf("PONG from pid %u\n", (unsigned int)pid);
- num_replies++;
+ pong_count++;
+ printf("PONG from PID %u\n",(unsigned int)src);
}
-static BOOL do_ping(const pid_t pid, const int argc, const char **argv)
+/****************************************************************************
+Prints out the current Debug level returned by MSG_DEBUGLEVEL
+****************************************************************************/
+void debuglevel_function(int msg_type, pid_t src, void *buf, size_t len)
{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> ping\n");
- return False;
- }
-
- /* Send a message and register our interest in a reply */
-
- if (!send_message(pid, MSG_PING, NULL, 0, False))
- return False;
-
- message_register(MSG_PONG, pong_cb);
-
- wait_replies(pid == 0);
-
- /* No replies were received within the timeout period */
+ int i;
+ int debuglevel_class[DBGC_LAST];
- if (num_replies == 0)
- printf("No replies received\n");
+ memcpy(debuglevel_class, buf, len);
- message_deregister(MSG_PONG);
+ printf("Current debug level of PID %u is %d ",(unsigned int)src, debuglevel_class[0]);
+ for (i=1;i<DBGC_LAST;i++)
+ if (debuglevel_class[i])
+ printf("%s:%d ", debug_classname_from_index(i), debuglevel_class[i]);
+ printf("\n");
- return num_replies;
+ got_level = True;
}
-/* Set profiling options */
-
-static BOOL do_profile(const pid_t pid, const int argc, const char **argv)
+/****************************************************************************
+Prints out the current Profile level returned by MSG_PROFILELEVEL
+****************************************************************************/
+void profilelevel_function(int msg_type, pid_t src, void *buf, size_t len)
{
- int v;
+ int level;
+ const char *s=NULL;
+ memcpy(&level, buf, sizeof(int));
- if (argc != 2) {
- fprintf(stderr, "Usage: smbcontrol <dest> profile "
- "<off|count|on|flush>\n");
- return False;
- }
-
- if (strcmp(argv[1], "off") == 0) {
- v = 0;
- } else if (strcmp(argv[1], "count") == 0) {
- v = 1;
- } else if (strcmp(argv[1], "on") == 0) {
- v = 2;
- } else if (strcmp(argv[1], "flush") == 0) {
- v = 3;
- } else {
- fprintf(stderr, "Unknown profile command '%s'\n", argv[1]);
- return False;
- }
-
- return send_message(pid, MSG_PROFILE, &v, sizeof(int), False);
-}
-
-/* Return the profiling level */
-
-static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len)
-{
- int level;
- const char *s;
-
- num_replies++;
-
- if (len != sizeof(int)) {
- fprintf(stderr, "invalid message length %ld returned\n",
- (unsigned long)len);
- return;
- }
-
- memcpy(&level, buf, sizeof(int));
-
- switch (level) {
- case 0:
- s = "not enabled";
- break;
- case 1:
+ if (level) {
+ switch (level) {
+ case 1:
s = "off";
break;
- case 3:
+ case 3:
s = "count only";
break;
- case 7:
+ case 7:
s = "count and time";
break;
- default:
- s = "BOGUS";
- break;
+ }
+ printf("Profiling %s on PID %u\n",s,(unsigned int)src);
+ } else {
+ printf("Profiling not available on PID %u\n",(unsigned int)src);
}
-
- printf("Profiling %s on pid %u\n",s,(unsigned int)pid);
+ got_level = True;
}
-static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len)
+/****************************************************************************
+send a message to a named destination
+****************************************************************************/
+static BOOL send_message(char *dest, int msg_type, void *buf, int len, BOOL duplicates)
{
- int v = 0;
-
- /* Send back a dummy reply */
+ BOOL retval = False;
+ pid_t pid = 0;
+ TDB_CONTEXT *the_tdb;
- send_message(pid, MSG_PROFILELEVEL, &v, sizeof(int), False);
-}
-
-static BOOL do_profilelevel(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> profilelevel\n");
+ the_tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDWR, 0);
+ if (!the_tdb) {
+ fprintf(stderr,"Failed to open connections database in send_message.\n");
return False;
}
- /* Send a message and register our interest in a reply */
-
- if (!send_message(pid, MSG_REQ_PROFILELEVEL, NULL, 0, False))
- return False;
-
- message_register(MSG_PROFILELEVEL, profilelevel_cb);
- message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst);
-
- wait_replies(pid == 0);
-
- /* No replies were received within the timeout period */
-
- if (num_replies == 0)
- printf("No replies received\n");
-
- message_deregister(MSG_PROFILE);
-
- return num_replies;
+ /* "smbd" is the only broadcast operation */
+ if (strequal(dest,"smbd")) {
+ retval = message_send_all(the_tdb,msg_type, buf, len, duplicates, NULL);
+ } else if (strequal(dest,"nmbd")) {
+ pid = pidfile_pid(dest);
+ if (pid == 0) {
+ fprintf(stderr,"Can't find pid for nmbd\n");
+ }
+ } else if (strequal(dest,"self")) {
+ pid = getpid();
+ } else {
+ pid = atoi(dest);
+ if (pid == 0) {
+ fprintf(stderr,"Not a valid pid\n");
+ }
+ }
+
+ tdb_close(the_tdb);
+ if (pid)
+ return message_send_pid(pid, msg_type, buf, len, duplicates);
+ else
+ return retval;
}
-/* Display debug level settings */
-
-static BOOL do_debuglevel(const pid_t pid, const int argc, const char **argv)
+/****************************************************************************
+evaluate a message type string
+****************************************************************************/
+static int parse_type(char *mtype)
{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> debuglevel\n");
- return False;
+ int i;
+ for (i=0;msg_types[i].name;i++) {
+ if (strequal(mtype, msg_types[i].name)) return msg_types[i].value;
}
-
- /* Send a message and register our interest in a reply */
-
- if (!send_message(pid, MSG_REQ_DEBUGLEVEL, NULL, 0, False))
- return False;
-
- message_register(MSG_DEBUGLEVEL, print_pid_string_cb);
-
- wait_replies(pid == 0);
-
- /* No replies were received within the timeout period */
-
- if (num_replies == 0)
- printf("No replies received\n");
-
- message_deregister(MSG_DEBUGLEVEL);
-
- return num_replies;
+ return -1;
}
-/* Send a print notify message */
-static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
+/****************************************************************************
+do command
+****************************************************************************/
+static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
{
- const char *cmd;
-
- /* Check for subcommand */
-
- if (argc == 1) {
- fprintf(stderr, "Must specify subcommand:\n");
- fprintf(stderr, "\tqueuepause <printername>\n");
- fprintf(stderr, "\tqueueresume <printername>\n");
- fprintf(stderr, "\tjobpause <printername> <unix jobid>\n");
- fprintf(stderr, "\tjobresume <printername> <unix jobid>\n");
- fprintf(stderr, "\tjobdelete <printername> <unix jobid>\n");
- fprintf(stderr, "\tprinter <printername> <comment|port|"
- "driver> <value>\n");
-
- return False;
+ int i, n, v;
+ int mtype;
+ BOOL retval=False;
+ int debuglevel_class[DBGC_LAST];
+
+ mtype = parse_type(msg_name);
+ if (mtype == -1) {
+ fprintf(stderr,"Couldn't resolve message type: %s\n", msg_name);
+ return(False);
}
- cmd = argv[1];
-
- if (strcmp(cmd, "queuepause") == 0) {
-
- if (argc != 3) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify"
- " queuepause <printername>\n");
- return False;
+ switch (mtype) {
+ case MSG_DEBUG:
+ if (!params || !params[0]) {
+ fprintf(stderr,"MSG_DEBUG needs a parameter\n");
+ return(False);
}
-
- notify_printer_status_byname(argv[2], PRINTER_STATUS_PAUSED);
- goto send;
-
- } else if (strcmp(cmd, "queueresume") == 0) {
+ ZERO_ARRAY(debuglevel_class);
+ if (!debug_parse_params(params, debuglevel_class)) {
+ fprintf(stderr, "MSG_DEBUG error. Expected <class name>:level\n");
+ return(False);
+ } else
+ send_message(dest, MSG_DEBUG, debuglevel_class, sizeof(debuglevel_class), False);
+ break;
- if (argc != 3) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify"
- " queuereume <printername>\n");
- return False;
+ case MSG_PROFILE:
+ if (!params || !params[0]) {
+ fprintf(stderr,"MSG_PROFILE needs a parameter\n");
+ return(False);
}
-
- notify_printer_status_byname(argv[2], PRINTER_STATUS_OK);
-
- goto send;
-
- } else if (strcmp(cmd, "jobpause") == 0) {
- int jobid;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify"
- " jobpause <printername> <unix-jobid>\n");
- return False;
+ if (strequal(params[0], "off")) {
+ v = 0;
+ } else if (strequal(params[0], "count")) {
+ v = 1;
+ } else if (strequal(params[0], "on")) {
+ v = 2;
+ } else if (strequal(params[0], "flush")) {
+ v = 3;
+ } else {
+ fprintf(stderr,
+ "MSG_PROFILE parameter must be off, count, on, or flush\n");
+ return(False);
}
+ send_message(dest, MSG_PROFILE, &v, sizeof(int), False);
+ break;
- jobid = atoi(argv[3]);
-
- notify_job_status_byname(
- argv[2], jobid, JOB_STATUS_PAUSED,
- SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
-
- goto send;
-
- } else if (strcmp(cmd, "jobresume") == 0) {
- int jobid;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify"
- " jobpause <printername> <unix-jobid>\n");
- return False;
+ case MSG_FORCE_ELECTION:
+ if (!strequal(dest, "nmbd")) {
+ fprintf(stderr,"force-election can only be sent to nmbd\n");
+ return(False);
}
+ send_message(dest, MSG_FORCE_ELECTION, NULL, 0, False);
+ break;
- jobid = atoi(argv[3]);
-
- notify_job_status_byname(
- argv[2], jobid, JOB_STATUS_QUEUED,
- SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
-
- goto send;
-
- } else if (strcmp(cmd, "jobdelete") == 0) {
- int jobid;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify"
- " jobpause <printername> <unix-jobid>\n");
- return False;
+ case MSG_REQ_PROFILELEVEL:
+ if (!profilelevel_registered) {
+ message_register(MSG_PROFILELEVEL, profilelevel_function);
+ profilelevel_registered = True;
}
-
- jobid = atoi(argv[3]);
-
- notify_job_status_byname(
- argv[2], jobid, JOB_STATUS_DELETING,
- SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
-
- notify_job_status_byname(
- argv[2], jobid, JOB_STATUS_DELETING|
- JOB_STATUS_DELETED,
- SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
-
- goto send;
-
- } else if (strcmp(cmd, "printer") == 0) {
- uint32 attribute;
-
- if (argc != 5) {
- fprintf(stderr, "Usage: smbcontrol <dest> printnotify "
- "printer <printername> <comment|port|driver> "
- "<value>\n");
- return False;
+ got_level = False;
+ retval = send_message(dest, MSG_REQ_PROFILELEVEL, NULL, 0, True);
+ if (retval) {
+ timeout_start = time(NULL);
+ while (!got_level) {
+ message_dispatch();
+ if ((time(NULL) - timeout_start) > MAX_WAIT) {
+ fprintf(stderr,"profilelevel timeout\n");
+ break;
+ }
+ }
}
+ break;
- if (strcmp(argv[3], "comment") == 0) {
- attribute = PRINTER_NOTIFY_COMMENT;
- } else if (strcmp(argv[3], "port") == 0) {
- attribute = PRINTER_NOTIFY_PORT_NAME;
- } else if (strcmp(argv[3], "driver") == 0) {
- attribute = PRINTER_NOTIFY_DRIVER_NAME;
- } else {
- fprintf(stderr, "Invalid printer command '%s'\n",
- argv[3]);
- return False;
+ case MSG_REQ_DEBUGLEVEL:
+ if (!debuglevel_registered) {
+ message_register(MSG_DEBUGLEVEL, debuglevel_function);
+ debuglevel_registered = True;
}
+ got_level = False;
+ retval = send_message(dest, MSG_REQ_DEBUGLEVEL, NULL, 0, True);
+ if (retval) {
+ timeout_start = time(NULL);
+ while (!got_level) {
+ message_dispatch();
+ if ((time(NULL) - timeout_start) > MAX_WAIT) {
+ fprintf(stderr,"debuglevel timeout\n");
+ break;
+ }
+ }
+ }
+ break;
- notify_printer_byname(argv[2], attribute, argv[4]);
-
- goto send;
- }
-
- fprintf(stderr, "Invalid subcommand '%s'\n", cmd);
- return False;
-
-send:
- print_notify_send_messages(0);
- return True;
-}
-
-/* Close a share */
-
-static BOOL do_closeshare(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 2) {
- fprintf(stderr, "Usage: smbcontrol <dest> close-share "
- "<sharename>\n");
- return False;
- }
-
- return send_message(
- pid, MSG_SMB_FORCE_TDIS, argv[1], strlen(argv[1]) + 1, False);
-}
-
-/* Force a SAM synchronisation */
-
-static BOOL do_samsync(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> samsync\n");
- return False;
- }
-
- return send_message(
- pid, MSG_SMB_SAM_SYNC, NULL, 0, False);
-}
-
-/* Force a SAM replication */
-
-static BOOL do_samrepl(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> samrepl\n");
- return False;
- }
-
- return send_message(
- pid, MSG_SMB_SAM_REPL, NULL, 0, False);
-}
-
-/* Display talloc pool usage */
-
-static BOOL do_poolusage(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> pool-usage\n");
- return False;
- }
-
- /* Send a message and register our interest in a reply */
-
- if (!send_message(pid, MSG_REQ_POOL_USAGE, NULL, 0, False))
- return False;
-
- message_register(MSG_POOL_USAGE, print_string_cb);
-
- wait_replies(pid == 0);
-
- /* No replies were received within the timeout period */
-
- if (num_replies == 0)
- printf("No replies received\n");
-
- message_deregister(MSG_POOL_USAGE);
-
- return num_replies;
-}
-
-/* Perform a dmalloc mark */
-
-static BOOL do_dmalloc_mark(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> dmalloc-mark\n");
- return False;
- }
-
- return send_message(
- pid, MSG_REQ_DMALLOC_MARK, NULL, 0, False);
-}
-
-/* Perform a dmalloc changed */
-
-static BOOL do_dmalloc_changed(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> "
- "dmalloc-log-changed\n");
- return False;
- }
-
- return send_message(
- pid, MSG_REQ_DMALLOC_LOG_CHANGED, NULL, 0, False);
-}
-
-/* Shutdown a server process */
-
-static BOOL do_shutdown(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> shutdown\n");
- return False;
- }
-
- return send_message(pid, MSG_SHUTDOWN, NULL, 0, False);
-}
-
-/* Notify a driver upgrade */
-
-static BOOL do_drvupgrade(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 2) {
- fprintf(stderr, "Usage: smbcontrol <dest> drvupgrade "
- "<driver-name>\n");
- return False;
- }
-
- return send_message(
- pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False);
-}
-
-static BOOL do_reload_config(const pid_t pid, const int argc, const char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "Usage: smbcontrol <dest> reload-config\n");
- return False;
- }
-
- return send_message(pid, MSG_SMB_CONF_UPDATED, NULL, 0, False);
-}
-
-/* A list of message type supported */
-
-static const struct {
- const char *name; /* Option name */
- BOOL (*fn)(const pid_t pid, const int argc, const char **argv);
- const char *help; /* Short help text */
-} msg_types[] = {
- { "debug", do_debug, "Set debuglevel" },
- { "force-election", do_election,
- "Force a browse election" },
- { "ping", do_ping, "Elicit a response" },
- { "profile", do_profile, "" },
- { "profilelevel", do_profilelevel, "" },
- { "debuglevel", do_debuglevel, "Display current debuglevels" },
- { "printnotify", do_printnotify, "Send a print notify message" },
- { "close-share", do_closeshare, "Forcibly disconnect a share" },
- { "samsync", do_samsync, "Initiate SAM synchronisation" },
- { "samrepl", do_samrepl, "Initiate SAM replication" },
- { "pool-usage", do_poolusage, "Display talloc memory usage" },
- { "dmalloc-mark", do_dmalloc_mark, "" },
- { "dmalloc-log-changed", do_dmalloc_changed, "" },
- { "shutdown", do_shutdown, "Shut down daemon" },
- { "drvupgrade", do_drvupgrade, "Notify a printer driver has changed" },
- { "reload-config", do_reload_config, "Force smbd or winbindd to reload config file"},
- { "noop", do_noop, "Do nothing" },
- { NULL }
-};
-
-/* Display usage information */
-
-static void usage(poptContext *pc)
-{
- int i;
-
- poptPrintHelp(*pc, stderr, 0);
-
- fprintf(stderr, "\n");
- fprintf(stderr, "<destination> is one of \"nmbd\", \"smbd\" or a "
- "process ID\n");
-
- fprintf(stderr, "\n");
- fprintf(stderr, "<message-type> is one of:\n");
-
- for (i = 0; msg_types[i].name; i++)
- fprintf(stderr, "\t%-30s%s\n", msg_types[i].name,
- msg_types[i].help);
-
- fprintf(stderr, "\n");
-
- exit(1);
-}
-
-/* Return the pid number for a string destination */
-
-static pid_t parse_dest(const char *dest)
-{
- pid_t pid;
-
- /* Zero is a special return value for broadcast smbd */
-
- if (strequal(dest, "smbd"))
- return 0;
-
- /* Try self - useful for testing */
-
- if (strequal(dest, "self"))
- return sys_getpid();
-
- /* Check for numeric pid number */
-
- if ((pid = atoi(dest)) != 0)
- return pid;
-
- /* Look up other destinations in pidfile directory */
-
- if ((pid = pidfile_pid(dest)) != 0)
- return pid;
-
- fprintf(stderr,"Can't find pid for destination '%s'\n", dest);
-
- return -1;
-}
-
-/* Execute smbcontrol command */
-
-static BOOL do_command(int argc, const char **argv)
-{
- const char *dest = argv[0], *command = argv[1];
- pid_t pid;
- int i;
-
- /* Check destination */
+ case MSG_PRINTER_NOTIFY:
+ if (!strequal(dest, "smbd")) {
+ fprintf(stderr,"printer-notify can only be sent to smbd\n");
+ return(False);
+ }
+ if (!params || !params[0]) {
+ fprintf(stderr, "printer-notify needs a printer name\n");
+ return (False);
+ }
+ {
+ char msg[8 + sizeof(fstring)+4];
+ SIVAL(msg,0,PRINTER_CHANGE_ALL);
+ SIVAL(msg,4,0);
+ fstrcpy(&msg[8], params[0]);
+ SIVAL(msg,8+strlen(params[0])+1, PRINTER_MESSAGE_DRIVER);
+
+ retval = send_message(dest, MSG_PRINTER_NOTIFY, msg, 8 + strlen(params[0]) + 1 + 4, False);
+ }
+ break;
- if ((pid = parse_dest(dest)) == -1)
- return False;
+ case MSG_SMB_FORCE_TDIS:
+ if (!strequal(dest, "smbd")) {
+ fprintf(stderr,"close-share can only be sent to smbd\n");
+ return(False);
+ }
+ if (!params || !params[0]) {
+ fprintf(stderr, "close-share needs a share name or '*'\n");
+ return (False);
+ }
+ retval = send_message(dest, MSG_SMB_FORCE_TDIS, params[0],
+ strlen(params[0]) + 1, False);
+ break;
- /* Check command */
+ case MSG_PING:
+ if (!pong_registered) {
+ message_register(MSG_PONG, pong_function);
+ pong_registered = True;
+ }
+ if (!params || !params[0]) {
+ fprintf(stderr,"MSG_PING needs a parameter\n");
+ return(False);
+ }
+ n = atoi(params[0]);
+ pong_count = 0;
+ for (i=0;i<n;i++) {
+ if (iparams > 1)
+ retval = send_message(dest, MSG_PING, params[1], strlen(params[1]) + 1, True);
+ else
+ retval = send_message(dest, MSG_PING, NULL, 0, True);
+ if (retval == False) break;
+ }
+ if (retval) {
+ timeout_start = time(NULL);
+ while (pong_count < n) {
+ message_dispatch();
+ if ((time(NULL) - timeout_start) > MAX_WAIT) {
+ fprintf(stderr,"PING timeout\n");
+ break;
+ }
+ }
+ }
+ break;
- for (i = 0; msg_types[i].name; i++) {
- if (strequal(command, msg_types[i].name))
- return msg_types[i].fn(pid, argc - 1, argv + 1);
}
-
- fprintf(stderr, "smbcontrol: unknown command '%s'\n", command);
-
- return False;
+
+ return (True);
}
-/* Main program */
-
-int main(int argc, const char **argv)
+ int main(int argc, char *argv[])
{
- poptContext pc;
int opt;
+ char temp[255];
+ extern char *optarg;
+ extern int optind;
+ pstring servicesf = CONFIGFILE;
+ BOOL interactive = False;
- static struct poptOption wbinfo_options[] = {
- { "timeout", 't', POPT_ARG_INT, &timeout, 't',
- "Set timeout value in seconds", "TIMEOUT" },
-
- { "configfile", 's', POPT_ARG_STRING, NULL, 's',
- "Use alternative configuration file", "CONFIGFILE" },
-
- POPT_TABLEEND
- };
-
- struct poptOption options[] = {
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, wbinfo_options, 0,
- "Options" },
-
- POPT_AUTOHELP
- POPT_COMMON_VERSION
- POPT_TABLEEND
- };
-
+ TimeInit();
setup_logging(argv[0],True);
- /* Parse command line arguments using popt */
-
- pc = poptGetContext(
- "smbcontrol", argc, (const char **)argv, options, 0);
-
- poptSetOtherOptionHelp(pc, "[OPTION...] <destination> <message-type> "
- "<parameters>");
+ AllowDebugChange = False;
+ DEBUGLEVEL = 0;
+ charset_initialise();
- if (argc == 1)
- usage(&pc);
+ if (argc < 2) usage(True);
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch(opt) {
- case 't': /* --timeout */
- argc -= 2;
+ while ((opt = getopt(argc, argv,"is:d:")) != EOF) {
+ switch (opt) {
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
break;
- case 's': /* --configfile */
- pstrcpy(dyn_CONFIGFILE, poptGetOptArg(pc));
- argc -= 2;
+ case 'i':
+ interactive = True;
break;
- default:
- fprintf(stderr, "Invalid option\n");
- poptPrintHelp(pc, stderr, 0);
+ case 's':
+ pstrcpy(servicesf, optarg);
break;
+ default:
+ printf("Unknown option %c (%d)\n", (char)opt, opt);
+ usage(True);
}
}
- /* We should now have the remaining command line arguments in
- argv. The argc parameter should have been decremented to the
- correct value in the above switch statement. */
+ lp_load(servicesf,False,False,False);
- argv = (const char **)poptGetArgs(pc);
- argc--; /* Don't forget about argv[0] */
+ if (!message_init()) exit(1);
- if (argc == 1)
- usage(&pc);
+ argc -= optind;
+ argv = &argv[optind];
- lp_load(dyn_CONFIGFILE,False,False,False);
+ if (!interactive) {
+ if (argc < 2) usage(True);
+ /*
+ * We want to return !do_command so we get the
+ * right shell semantics (0 = success, 1 = fail)
+ */
+ return (!do_command(argv[0],argv[1], argc-2, argc > 2 ? &argv[2] : 0));
+ }
- /* Need to invert sense of return code -- samba
- * routines mostly return True==1 for success, but
- * shell needs 0. */
-
- return !do_command(argc, argv);
+ while (True) {
+ char *myargv[4];
+ int myargc;
+
+ printf("smbcontrol> ");
+ if (!fgets(temp, sizeof(temp)-1, stdin)) break;
+ myargc = 0;
+ while ((myargc < 4) &&
+ (myargv[myargc] = strtok(myargc?NULL:temp," \t\n"))) {
+ myargc++;
+ }
+ if (!myargc) break;
+ if (strequal(myargv[0],"q")) break;
+ if (myargc < 2)
+ usage(False);
+ else if (!do_command(myargv[0],myargv[1],myargc-2,myargc > 2 ? &myargv[2] : 0))
+ usage(False);
+ }
+ return(0);
}
+
diff --git a/source/utils/smbcquotas.c b/source/utils/smbcquotas.c
deleted file mode 100644
index 0bd87554209..00000000000
--- a/source/utils/smbcquotas.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- QUOTA get/set utility
-
- Copyright (C) Andrew Tridgell 2000
- Copyright (C) Tim Potter 2000
- Copyright (C) Jeremy Allison 2000
- Copyright (C) Stefan (metze) Metzmacher 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static pstring server;
-
-/* numeric is set when the user wants numeric SIDs and ACEs rather
- than going via LSA calls to resolve them */
-static BOOL numeric;
-static BOOL verbose;
-
-enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA};
-enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
-
-static struct cli_state *cli_ipc = NULL;
-static POLICY_HND pol;
-static BOOL got_policy_hnd;
-
-static struct cli_state *connect_one(const char *share);
-
-/* Open cli connection and policy handle */
-
-static BOOL cli_open_policy_hnd(void)
-{
- /* Initialise cli LSA connection */
-
- if (!cli_ipc) {
- cli_ipc = connect_one("IPC$");
- if (!cli_nt_session_open (cli_ipc, PI_LSARPC)) {
- return False;
- }
- }
-
- /* Open policy handle */
-
- if (!got_policy_hnd) {
-
- /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
- but NT sends 0x2000000 so we might as well do it too. */
-
- if (!NT_STATUS_IS_OK(cli_lsa_open_policy(cli_ipc, cli_ipc->mem_ctx, True,
- GENERIC_EXECUTE_ACCESS, &pol))) {
- return False;
- }
-
- got_policy_hnd = True;
- }
-
- return True;
-}
-
-/* convert a SID to a string, either numeric or username/group */
-static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric)
-{
- char **domains = NULL;
- char **names = NULL;
- uint32 *types = NULL;
-
- sid_to_string(str, sid);
-
- if (_numeric) return;
-
- /* Ask LSA to convert the sid to a name */
-
- if (!cli_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_sids(cli_ipc, cli_ipc->mem_ctx,
- &pol, 1, sid, &domains,
- &names, &types)) ||
- !domains || !domains[0] || !names || !names[0]) {
- return;
- }
-
- /* Converted OK */
-
- slprintf(str, sizeof(fstring) - 1, "%s%s%s",
- domains[0], lp_winbind_separator(),
- names[0]);
-
-}
-
-/* convert a string to a SID, either numeric or username/group */
-static BOOL StringToSid(DOM_SID *sid, const char *str)
-{
- uint32 *types = NULL;
- DOM_SID *sids = NULL;
- BOOL result = True;
-
- if (strncmp(str, "S-", 2) == 0) {
- return string_to_sid(sid, str);
- }
-
- if (!cli_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx,
- &pol, 1, &str, &sids,
- &types))) {
- result = False;
- goto done;
- }
-
- sid_copy(sid, &sids[0]);
- done:
-
- return result;
-}
-
-#define QUOTA_GET 1
-#define QUOTA_SETLIM 2
-#define QUOTA_SETFLAGS 3
-#define QUOTA_LIST 4
-
-enum {PARSE_FLAGS,PARSE_LIM};
-
-static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt)
-{
- char *p = set_str,*p2;
- int todo;
- BOOL stop = False;
- BOOL enable = False;
- BOOL deny = False;
-
- if (strnequal(set_str,"UQLIM:",6)) {
- p += 6;
- *qtype = SMB_USER_QUOTA_TYPE;
- *cmd = QUOTA_SETLIM;
- todo = PARSE_LIM;
- if ((p2=strstr(p,":"))==NULL) {
- return -1;
- }
-
- *p2 = '\0';
- p2++;
-
- fstrcpy(username_str,p);
- p = p2;
- } else if (strnequal(set_str,"FSQLIM:",7)) {
- p +=7;
- *qtype = SMB_USER_FS_QUOTA_TYPE;
- *cmd = QUOTA_SETLIM;
- todo = PARSE_LIM;
- } else if (strnequal(set_str,"FSQFLAGS:",9)) {
- p +=9;
- todo = PARSE_FLAGS;
- *qtype = SMB_USER_FS_QUOTA_TYPE;
- *cmd = QUOTA_SETFLAGS;
- } else {
- return -1;
- }
-
- switch (todo) {
- case PARSE_LIM:
-#if defined(HAVE_LONGLONG)
- if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) {
-#else
- if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) {
-#endif
- return -1;
- }
-
- break;
- case PARSE_FLAGS:
- while (!stop) {
-
- if ((p2=strstr(p,"/"))==NULL) {
- stop = True;
- } else {
- *p2 = '\0';
- p2++;
- }
-
- if (strnequal(p,"QUOTA_ENABLED",13)) {
- enable = True;
- } else if (strnequal(p,"DENY_DISK",9)) {
- deny = True;
- } else if (strnequal(p,"LOG_SOFTLIMIT",13)) {
- pqt->qflags |= QUOTAS_LOG_THRESHOLD;
- } else if (strnequal(p,"LOG_HARDLIMIT",13)) {
- pqt->qflags |= QUOTAS_LOG_LIMIT;
- } else {
- return -1;
- }
-
- p=p2;
- }
-
- if (deny) {
- pqt->qflags |= QUOTAS_DENY_DISK;
- } else if (enable) {
- pqt->qflags |= QUOTAS_ENABLED;
- }
-
- break;
- }
-
- return 0;
-}
-
-static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt)
-{
- uint32 fs_attrs = 0;
- int quota_fnum = 0;
- SMB_NTQUOTA_LIST *qtl = NULL;
- SMB_NTQUOTA_STRUCT qt;
- ZERO_STRUCT(qt);
-
- if (!cli_get_fs_attr_info(cli, &fs_attrs)) {
- d_printf("Failed to get the filesystem attributes %s.\n",
- cli_errstr(cli));
- return -1;
- }
-
- if (!(fs_attrs & FILE_VOLUME_QUOTAS)) {
- d_printf("Quotas are not supported by the server.\n");
- return 0;
- }
-
- if (!cli_get_quota_handle(cli, &quota_fnum)) {
- d_printf("Failed to open \\%s %s.\n",
- FAKE_FILE_NAME_QUOTA,cli_errstr(cli));
- return -1;
- }
-
- switch(qtype) {
- case SMB_USER_QUOTA_TYPE:
- if (!StringToSid(&qt.sid, username_str)) {
- d_printf("StringToSid() failed for [%s]\n",username_str);
- return -1;
- }
-
- switch(cmd) {
- case QUOTA_GET:
- if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_user_quota %s\n",
- cli_errstr(cli),username_str);
- return -1;
- }
- dump_ntquota(&qt,verbose,numeric,SidToString);
- break;
- case QUOTA_SETLIM:
- pqt->sid = qt.sid;
- if (!cli_set_user_quota(cli, quota_fnum, pqt)) {
- d_printf("%s cli_set_user_quota %s\n",
- cli_errstr(cli),username_str);
- return -1;
- }
- if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_user_quota %s\n",
- cli_errstr(cli),username_str);
- return -1;
- }
- dump_ntquota(&qt,verbose,numeric,SidToString);
- break;
- case QUOTA_LIST:
- if (!cli_list_user_quota(cli, quota_fnum, &qtl)) {
- d_printf("%s cli_set_user_quota %s\n",
- cli_errstr(cli),username_str);
- return -1;
- }
- dump_ntquota_list(&qtl,verbose,numeric,SidToString);
- free_ntquota_list(&qtl);
- break;
- default:
- d_printf("Unknown Error\n");
- return -1;
- }
- break;
- case SMB_USER_FS_QUOTA_TYPE:
- switch(cmd) {
- case QUOTA_GET:
- if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- dump_ntquota(&qt,True,numeric,NULL);
- break;
- case QUOTA_SETLIM:
- if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- qt.softlim = pqt->softlim;
- qt.hardlim = pqt->hardlim;
- if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_set_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- dump_ntquota(&qt,True,numeric,NULL);
- break;
- case QUOTA_SETFLAGS:
- if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- qt.qflags = pqt->qflags;
- if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_set_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
- d_printf("%s cli_get_fs_quota_info\n",
- cli_errstr(cli));
- return -1;
- }
- dump_ntquota(&qt,True,numeric,NULL);
- break;
- default:
- d_printf("Unknown Error\n");
- return -1;
- }
- break;
- default:
- d_printf("Unknown Error\n");
- return -1;
- }
-
- cli_close(cli, quota_fnum);
-
- return 0;
-}
-
-/*****************************************************
-return a connection to a server
-*******************************************************/
-static struct cli_state *connect_one(const char *share)
-{
- struct cli_state *c;
- struct in_addr ip;
- NTSTATUS nt_status;
- zero_ip(&ip);
-
- if (!cmdline_auth_info.got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(cmdline_auth_info.password, pass);
- cmdline_auth_info.got_pass = True;
- }
- }
-
- if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,
- &ip, 0,
- share, "?????",
- cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0,
- cmdline_auth_info.signing_state, NULL))) {
- return c;
- } else {
- DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
- return NULL;
- }
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc, const char *argv[])
-{
- char *share;
- int opt;
- int result;
- int todo = 0;
- pstring username_str = {0};
- pstring path = {0};
- pstring set_str = {0};
- enum SMB_QUOTA_TYPE qtype;
- int cmd = 0;
- static BOOL test_args = False;
- struct cli_state *cli;
- BOOL fix_user = False;
- SMB_NTQUOTA_STRUCT qt;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "user", 'u', POPT_ARG_STRING, NULL, 'u', "Show quotas for user", "user" },
- { "list", 'L', POPT_ARG_NONE, NULL, 'L', "List user quotas" },
- { "fs", 'F', POPT_ARG_NONE, NULL, 'F', "Show filesystem quotas" },
- { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls\n\
-SETSTRING:\n\
-UQLIM:<username>/<softlimit>/<hardlimit> for user quotas\n\
-FSQLIM:<softlimit>/<hardlimit> for filesystem defaults\n\
-FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT", "SETSTRING" },
- { "numeric", 'n', POPT_ARG_NONE, &numeric, True, "Don't resolve sids or limits to names" },
- { "verbose", 'v', POPT_ARG_NONE, &verbose, True, "be verbose" },
- { "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"},
- POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
- { NULL }
- };
-
- ZERO_STRUCT(qt);
-
- setlinebuf(stdout);
-
- dbf = x_stderr;
-
- fault_setup(NULL);
-
- setup_logging(argv[0],True);
-
-
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
-
- pc = poptGetContext("smbcquotas", argc, argv, long_options, 0);
-
- poptSetOtherOptionHelp(pc, "//server1/share1");
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'L':
- if (todo != 0) {
- d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
- exit(EXIT_PARSE_ERROR);
- }
- todo = LIST_QUOTA;
- break;
-
- case 'F':
- if (todo != 0) {
- d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
- exit(EXIT_PARSE_ERROR);
- }
- todo = FS_QUOTA;
- break;
-
- case 'u':
- if (todo != 0) {
- d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
- exit(EXIT_PARSE_ERROR);
- }
- pstrcpy(username_str,poptGetOptArg(pc));
- todo = USER_QUOTA;
- fix_user = True;
- break;
-
- case 'S':
- if (todo != 0) {
- d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
- exit(EXIT_PARSE_ERROR);
- }
- pstrcpy(set_str,poptGetOptArg(pc));
- todo = SET_QUOTA;
- break;
- }
- }
-
- if (todo == 0)
- todo = USER_QUOTA;
-
- if (!fix_user)
- pstrcpy(username_str,cmdline_auth_info.username);
-
- /* Make connection to server */
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- exit(EXIT_PARSE_ERROR);
- }
-
- pstrcpy(path, poptGetArg(pc));
-
- all_string_sub(path,"/","\\",0);
-
- pstrcpy(server,path+2);
- share = strchr_m(server,'\\');
- if (!share) {
- share = strchr_m(server,'/');
- if (!share) {
- printf("Invalid argument: %s\n", share);
- exit(EXIT_PARSE_ERROR);
- }
- }
-
- *share = 0;
- share++;
-
- if (todo == SET_QUOTA) {
- if (parse_quota_set(set_str, username_str, &qtype, &cmd, &qt)) {
- printf("Invalid argument: -S %s\n", set_str);
- exit(EXIT_PARSE_ERROR);
- }
- }
-
- if (!test_args) {
- cli = connect_one(share);
- if (!cli) {
- exit(EXIT_FAILED);
- }
- } else {
- exit(EXIT_OK);
- }
-
-
- /* Perform requested action */
-
- switch (todo) {
- case FS_QUOTA:
- result = do_quota(cli,SMB_USER_FS_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
- break;
- case LIST_QUOTA:
- result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL);
- break;
- case USER_QUOTA:
- result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
- break;
- case SET_QUOTA:
- result = do_quota(cli, qtype, cmd, username_str, &qt);
- break;
- default:
-
- result = EXIT_FAILED;
- break;
- }
-
- return result;
-}
-
diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c
index 5d67c8fc7cf..6be0860c928 100644
--- a/source/utils/smbfilter.c
+++ b/source/utils/smbfilter.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2
SMB filter/socket plugin
Copyright (C) Andrew Tridgell 1999
@@ -19,12 +20,13 @@
*/
#include "includes.h"
+#include "smb.h"
#define SECURITY_MASK 0
#define SECURITY_SET 0
/* this forces non-unicode */
-#define CAPABILITY_MASK 0
+#define CAPABILITY_MASK (CAP_NT_SMBS | CAP_RPC_REMOTE_APIS)
#define CAPABILITY_SET 0
/* and non-unicode for the client too */
@@ -34,22 +36,6 @@
static char *netbiosname;
static char packet[BUFFER_SIZE];
-static void save_file(const char *fname, void *packet, size_t length)
-{
- int fd;
- fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (fd == -1) {
- perror(fname);
- return;
- }
- if (write(fd, packet, length) != length) {
- fprintf(stderr,"Failed to write %s\n", fname);
- return;
- }
- close(fd);
- printf("Wrote %ld bytes to %s\n", (unsigned long)length, fname);
-}
-
static void filter_reply(char *buf)
{
int msg_type = CVAL(buf,0);
@@ -89,8 +75,8 @@ static void filter_request(char *buf)
/* session request */
name_extract(buf,4,name1);
name_extract(buf,4 + name_len(buf + 4),name2);
- d_printf("sesion_request: %s -> %s\n",
- name1, name2);
+ DEBUG(0,("sesion_request: %s -> %s\n",
+ name1, name2));
if (netbiosname) {
/* replace the destination netbios name */
name_mangle(netbiosname, buf+4, 0x20);
@@ -104,10 +90,6 @@ static void filter_request(char *buf)
case SMBsesssetupX:
/* force the client capabilities */
x = IVAL(buf,smb_vwv11);
- d_printf("SMBsesssetupX cap=0x%08x\n", x);
- d_printf("pwlen=%d/%d\n", SVAL(buf, smb_vwv7), SVAL(buf, smb_vwv8));
- system("mv sessionsetup.dat sessionsetup1.dat");
- save_file("sessionsetup.dat", smb_buf(buf), SVAL(buf, smb_vwv7));
x = (x | CLI_CAPABILITY_SET) & ~CLI_CAPABILITY_MASK;
SIVAL(buf, smb_vwv11, x);
break;
@@ -121,10 +103,10 @@ static void filter_child(int c, struct in_addr dest_ip)
int s;
/* we have a connection from a new client, now connect to the server */
- s = open_socket_out(SOCK_STREAM, &dest_ip, 445, LONG_CONNECT_TIMEOUT);
+ s = open_socket_out(SOCK_STREAM, &dest_ip, 139, LONG_CONNECT_TIMEOUT);
if (s == -1) {
- d_printf("Unable to connect to %s\n", inet_ntoa(dest_ip));
+ DEBUG(0,("Unable to connect to %s\n", inet_ntoa(dest_ip)));
exit(1);
}
@@ -141,28 +123,28 @@ static void filter_child(int c, struct in_addr dest_ip)
if (c != -1 && FD_ISSET(c, &fds)) {
if (!receive_smb(c, packet, 0)) {
- d_printf("client closed connection\n");
+ DEBUG(0,("client closed connection\n"));
exit(0);
}
filter_request(packet);
if (!send_smb(s, packet)) {
- d_printf("server is dead\n");
+ DEBUG(0,("server is dead\n"));
exit(1);
}
}
if (s != -1 && FD_ISSET(s, &fds)) {
if (!receive_smb(s, packet, 0)) {
- d_printf("server closed connection\n");
+ DEBUG(0,("server closed connection\n"));
exit(0);
}
filter_reply(packet);
if (!send_smb(c, packet)) {
- d_printf("client is dead\n");
+ DEBUG(0,("client is dead\n"));
exit(1);
}
}
}
- d_printf("Connection closed\n");
+ DEBUG(0,("Connection closed\n"));
exit(0);
}
@@ -174,20 +156,20 @@ static void start_filter(char *desthost)
CatchChild();
- /* start listening on port 445 locally */
- s = open_socket_in(SOCK_STREAM, 445, 0, 0, True);
+ /* start listening on port 139 locally */
+ s = open_socket_in(SOCK_STREAM, 139, 0, 0, True);
if (s == -1) {
- d_printf("bind failed\n");
+ DEBUG(0,("bind failed\n"));
exit(1);
}
if (listen(s, 5) == -1) {
- d_printf("listen failed\n");
+ DEBUG(0,("listen failed\n"));
}
if (!resolve_name(desthost, &dest_ip, 0x20)) {
- d_printf("Unable to resolve host %s\n", desthost);
+ DEBUG(0,("Unable to resolve host %s\n", desthost));
exit(1);
}
@@ -222,9 +204,13 @@ int main(int argc, char *argv[])
char *desthost;
pstring configfile;
+ TimeInit();
+
setup_logging(argv[0],True);
- pstrcpy(configfile,dyn_CONFIGFILE);
+ charset_initialise();
+
+ pstrcpy(configfile,CONFIGFILE);
if (argc < 2) {
fprintf(stderr,"smbfilter <desthost> <netbiosname>\n");
@@ -237,7 +223,7 @@ int main(int argc, char *argv[])
}
if (!lp_load(configfile,True,False,False)) {
- d_printf("Unable to load config file\n");
+ DEBUG(0,("Unable to load config file\n"));
}
start_filter(desthost);
diff --git a/source/utils/smbget.c b/source/utils/smbget.c
deleted file mode 100644
index 64630bba8fd..00000000000
--- a/source/utils/smbget.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- smbget: a wget-like utility with support for recursive downloading and
- smb:// urls
- Copyright (C) 2003-2004 Jelmer Vernooij <jelmer@samba.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "includes.h"
-#include "libsmbclient.h"
-
-#if _FILE_OFFSET_BITS==64
-#define OFF_T_FORMAT "%lld"
-#else
-#define OFF_T_FORMAT "%ld"
-#endif
-
-int columns = 0;
-
-time_t total_start_time = 0;
-off_t total_bytes = 0;
-
-#define SMB_MAXPATHLEN MAXPATHLEN
-
-/* Number of bytes to read when checking whether local and remote file are really the same file */
-#define RESUME_CHECK_SIZE 512
-#define RESUME_DOWNLOAD_OFFSET 1024
-#define RESUME_CHECK_OFFSET RESUME_DOWNLOAD_OFFSET+RESUME_CHECK_SIZE
-/* Number of bytes to read at once */
-#define SMB_DEFAULT_BLOCKSIZE 64000
-
-const char *username = NULL, *password = NULL, *workgroup = NULL;
-int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0, send_stdout = 0;
-int blocksize = SMB_DEFAULT_BLOCKSIZE;
-
-int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile);
-
-int get_num_cols(void)
-{
-#ifdef TIOCGWINSZ
- struct winsize ws;
- if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
- return 0;
- }
- return ws.ws_col;
-#else
-#warning No support for TIOCGWINSZ
- char *cols = getenv("COLUMNS");
- if(!cols) return 0;
- return atoi(cols);
-#endif
-}
-
-void change_columns(int sig)
-{
- columns = get_num_cols();
-}
-
-void human_readable(off_t s, char *buffer, int l)
-{
- if(s > 1024 * 1024 * 1024) snprintf(buffer, l, "%.2fGb", 1.0 * s / (1024 * 1024 * 1024));
- else if(s > 1024 * 1024) snprintf(buffer, l, "%.2fMb", 1.0 * s / (1024 * 1024));
- else if(s > 1024) snprintf(buffer, l, "%.2fkb", 1.0 * s / 1024);
- else snprintf(buffer, l, OFF_T_FORMAT"b", s);
-}
-
-void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen)
-{
- static char hasasked = 0;
- char *wgtmp, *usertmp;
- char tmp[128];
-
- if(hasasked) return;
- hasasked = 1;
-
- if(!nonprompt && !username) {
- printf("Username for %s at %s [guest] ", shr, srv);
- fgets(tmp, sizeof(tmp), stdin);
- if(tmp[strlen(tmp)-1] == '\n')tmp[strlen(tmp)-1] = '\0';
- strncpy(un, tmp, unlen-1);
- } else if(username) strncpy(un, username, unlen-1);
-
- if(!nonprompt && !password) {
- char *prompt, *pass;
- asprintf(&prompt, "Password for %s at %s: ", shr, srv);
- pass = getpass(prompt);
- free(prompt);
- strncpy(pw, pass, pwlen-1);
- } else if(password) strncpy(pw, password, pwlen-1);
-
- if(workgroup)strncpy(wg, workgroup, wglen-1);
-
- wgtmp = strndup(wg, wglen);
- usertmp = strndup(un, unlen);
- if(!quiet)printf("Using workgroup %s, %s%s\n", wgtmp, *usertmp?"user ":"guest user", usertmp);
- free(wgtmp); free(usertmp);
-}
-
-int smb_download_dir(const char *base, const char *name, int resume)
-{
- char path[SMB_MAXPATHLEN];
- int dirhandle;
- struct smbc_dirent *dirent;
- const char *relname = name;
- char *tmpname;
- struct stat remotestat;
- snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (base[0] && name[0] && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name);
-
- /* List files in directory and call smb_download_file on them */
- dirhandle = smbc_opendir(path);
- if(dirhandle < 1) {
- if(errno == ENOTDIR) return smb_download_file(base, name, 1, resume, NULL);
- fprintf(stderr, "Can't open directory %s: %s\n", path, strerror(errno));
- return 0;
- }
-
- while(*relname == '/')relname++;
- mkdir(relname, 0755);
-
- tmpname = strdup(name);
-
- while((dirent = smbc_readdir(dirhandle))) {
- char *newname;
- if(!strcmp(dirent->name, ".") || !strcmp(dirent->name, ".."))continue;
- asprintf(&newname, "%s/%s", tmpname, dirent->name);
- switch(dirent->smbc_type) {
- case SMBC_DIR:
- smb_download_dir(base, newname, resume);
- break;
-
- case SMBC_WORKGROUP:
- smb_download_dir("smb://", dirent->name, resume);
- break;
-
- case SMBC_SERVER:
- smb_download_dir("smb://", dirent->name, resume);
- break;
-
- case SMBC_FILE:
- smb_download_file(base, newname, 1, resume, NULL);
- break;
-
- case SMBC_FILE_SHARE:
- smb_download_dir(base, newname, resume);
- break;
-
- case SMBC_PRINTER_SHARE:
- if(!quiet)printf("Ignoring printer share %s\n", dirent->name);
- break;
-
- case SMBC_COMMS_SHARE:
- if(!quiet)printf("Ignoring comms share %s\n", dirent->name);
- break;
-
- case SMBC_IPC_SHARE:
- if(!quiet)printf("Ignoring ipc$ share %s\n", dirent->name);
- break;
-
- default:
- fprintf(stderr, "Ignoring file '%s' of type '%d'\n", newname, dirent->smbc_type);
- break;
- }
- free(newname);
- }
- free(tmpname);
-
- if(keep_permissions) {
- if(smbc_fstat(dirhandle, &remotestat) < 0) {
- fprintf(stderr, "Unable to get stats on %s on remote server\n", path);
- smbc_closedir(dirhandle);
- return 0;
- }
-
- if(chmod(relname, remotestat.st_mode) < 0) {
- fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode);
- smbc_closedir(dirhandle);
- return 0;
- }
- }
-
- smbc_closedir(dirhandle);
- return 1;
-}
-
-char *print_time(long t)
-{
- static char buffer[100];
- int secs, mins, hours;
- if(t < -1) {
- strncpy(buffer, "Unknown", sizeof(buffer));
- return buffer;
- }
-
- secs = (int)t % 60;
- mins = (int)t / 60 % 60;
- hours = (int)t / (60 * 60);
- snprintf(buffer, sizeof(buffer)-1, "%02d:%02d:%02d", hours, mins, secs);
- return buffer;
-}
-
-void print_progress(const char *name, time_t start, time_t now, off_t start_pos, off_t pos, off_t total)
-{
- double avg = 0.0;
- long eta = -1;
- double prcnt = 0.0;
- char hpos[20], htotal[20], havg[20];
- char *status, *filename;
- int len;
- if(now - start)avg = 1.0 * (pos - start_pos) / (now - start);
- eta = (total - pos) / avg;
- if(total)prcnt = 100.0 * pos / total;
-
- human_readable(pos, hpos, sizeof(hpos));
- human_readable(total, htotal, sizeof(htotal));
- human_readable(avg, havg, sizeof(havg));
-
- len = asprintf(&status, "%s of %s (%.2f%%) at %s/s ETA: %s", hpos, htotal, prcnt, havg, print_time(eta));
-
- if(columns) {
- int required = strlen(name), available = columns - len - strlen("[] ");
- if(required > available) asprintf(&filename, "...%s", name + required - available + 3);
- else filename = strndup(name, available);
- } else filename = strdup(name);
-
- fprintf(stderr, "\r[%s] %s", filename, status);
-
- free(filename); free(status);
-}
-
-int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile) {
- int remotehandle, localhandle;
- time_t start_time = time(NULL);
- const char *newpath;
- char path[SMB_MAXPATHLEN];
- char checkbuf[2][RESUME_CHECK_SIZE];
- char *readbuf = NULL;
- off_t offset_download = 0, offset_check = 0, curpos = 0, start_offset = 0;
- struct stat localstat, remotestat;
-
- snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (*base && *name && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name);
-
- remotehandle = smbc_open(path, O_RDONLY, 0755);
-
- if(remotehandle < 0) {
- switch(errno) {
- case EISDIR:
- if(!recursive) {
- fprintf(stderr, "%s is a directory. Specify -R to download recursively\n", path);
- return 0;
- }
- smb_download_dir(base, name, resume);
- return 0;
-
- case ENOENT:
- fprintf(stderr, "%s can't be found on the remote server\n", path);
- return 0;
-
- case ENOMEM:
- fprintf(stderr, "Not enough memory\n");
- exit(1);
- return 0;
-
- case ENODEV:
- fprintf(stderr, "The share name used in %s does not exist\n", path);
- return 0;
-
- case EACCES:
- fprintf(stderr, "You don't have enough permissions to access %s\n", path);
- return 0;
-
- default:
- perror("smbc_open");
- return 0;
- }
- }
-
- if(smbc_fstat(remotehandle, &remotestat) < 0) {
- fprintf(stderr, "Can't stat %s: %s\n", path, strerror(errno));
- return 0;
- }
-
- if(outfile) newpath = outfile;
- else if(!name[0]) {
- newpath = strrchr(base, '/');
- if(newpath)newpath++; else newpath = base;
- } else newpath = name;
-
- if(newpath[0] == '/')newpath++;
-
- /* Open local file and, if necessary, resume */
- if(!send_stdout) {
- localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755);
- if(localhandle < 0) {
- fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno));
- smbc_close(remotehandle);
- return 0;
- }
-
- fstat(localhandle, &localstat);
-
- start_offset = localstat.st_size;
-
- if(localstat.st_size && localstat.st_size == remotestat.st_size) {
- if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path);
- else if(!quiet)fprintf(stderr, "%s\n", path);
- smbc_close(remotehandle);
- close(localhandle);
- return 1;
- }
-
- if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) {
- offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET;
- offset_check = localstat.st_size - RESUME_CHECK_OFFSET;
- if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n"
- "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check,
- localstat.st_size, remotestat.st_size);
- }
-
- if(offset_check) {
- off_t off1, off2;
- /* First, check all bytes from offset_check to offset_download */
- off1 = lseek(localhandle, offset_check, SEEK_SET);
- if(off1 < 0) {
- fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath);
- smbc_close(remotehandle); close(localhandle);
- return 0;
- }
-
- off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET);
- if(off2 < 0) {
- fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath);
- smbc_close(remotehandle); close(localhandle);
- return 0;
- }
-
- if(off1 != off2) {
- fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2);
- return 0;
- }
-
- if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) {
- fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path);
- smbc_close(remotehandle); close(localhandle);
- return 0;
- }
-
- if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) {
- fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name);
- smbc_close(remotehandle); close(localhandle);
- return 0;
- }
-
- if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) {
- if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download);
- } else {
- fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path);
- smbc_close(remotehandle); close(localhandle);
- return 0;
- }
- }
- } else {
- localhandle = STDOUT_FILENO;
- start_offset = 0;
- offset_download = 0;
- offset_check = 0;
- }
-
- readbuf = malloc(blocksize);
-
- /* Now, download all bytes from offset_download to the end */
- for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) {
- ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize);
- if(bytesread < 0) {
- fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path);
- smbc_close(remotehandle);
- if (localhandle != STDOUT_FILENO) close(localhandle);
- free(readbuf);
- return 0;
- }
-
- total_bytes += bytesread;
-
- if(write(localhandle, readbuf, bytesread) < 0) {
- fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos);
- free(readbuf);
- smbc_close(remotehandle);
- if (localhandle != STDOUT_FILENO) close(localhandle);
- return 0;
- }
-
- if(dots)fputc('.', stderr);
- else if(!quiet) {
- print_progress(newpath, start_time, time(NULL), start_offset, curpos, remotestat.st_size);
- }
- }
-
- free(readbuf);
-
- if(dots){
- fputc('\n', stderr);
- printf("%s downloaded\n", path);
- } else if(!quiet) {
- int i;
- fprintf(stderr, "\r%s", path);
- if(columns) {
- for(i = strlen(path); i < columns; i++) {
- fputc(' ', stderr);
- }
- }
- fputc('\n', stderr);
- }
-
- if(keep_permissions && !send_stdout) {
- if(fchmod(localhandle, remotestat.st_mode) < 0) {
- fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode);
- smbc_close(remotehandle);
- close(localhandle);
- return 0;
- }
- }
-
- smbc_close(remotehandle);
- if (localhandle != STDOUT_FILENO) close(localhandle);
- return 1;
-}
-
-void clean_exit(void)
-{
- char bs[100];
- human_readable(total_bytes, bs, sizeof(bs));
- if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, time(NULL) - total_start_time);
- exit(0);
-}
-
-void signal_quit(int v)
-{
- clean_exit();
-}
-
-int readrcfile(const char *name, const struct poptOption long_options[])
-{
- FILE *fd = fopen(name, "r");
- int lineno = 0, i;
- char var[101], val[101];
- char found;
- int *intdata; char **stringdata;
- if(!fd) {
- fprintf(stderr, "Can't open RC file %s\n", name);
- return 1;
- }
-
- while(!feof(fd)) {
- lineno++;
- if(fscanf(fd, "%100s %100s\n", var, val) < 2) {
- fprintf(stderr, "Can't parse line %d of %s, ignoring.\n", lineno, name);
- continue;
- }
-
- found = 0;
-
- for(i = 0; long_options[i].shortName; i++) {
- if(!long_options[i].longName)continue;
- if(strcmp(long_options[i].longName, var)) continue;
- if(!long_options[i].arg)continue;
-
- switch(long_options[i].argInfo) {
- case POPT_ARG_NONE:
- intdata = (int *)long_options[i].arg;
- if(!strcmp(val, "on")) *intdata = 1;
- else if(!strcmp(val, "off")) *intdata = 0;
- else fprintf(stderr, "Illegal value %s for %s at line %d in %s\n", val, var, lineno, name);
- break;
- case POPT_ARG_INT:
- intdata = (int *)long_options[i].arg;
- *intdata = atoi(val);
- break;
- case POPT_ARG_STRING:
- stringdata = (char **)long_options[i].arg;
- *stringdata = strdup(val);
- break;
- default:
- fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name);
- break;
- }
-
- found = 1;
- }
- if(!found) {
- fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name);
- }
- }
-
- fclose(fd);
- return 0;
-}
-
-int main(int argc, const char **argv)
-{
- int resume = 0, recursive = 0;
- int c = 0;
- int debuglevel = 0;
- const char *file = NULL;
- char *rcfile = NULL;
- char *outputfile = NULL;
- struct poptOption long_options[] = {
- {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" },
- {"resume", 'r', POPT_ARG_NONE, &resume, 0, "Automatically resume aborted files" },
- {"recursive", 'R', POPT_ARG_NONE, &recursive, 0, "Recursively download files" },
- {"username", 'u', POPT_ARG_STRING, &username, 'u', "Username to use" },
- {"password", 'p', POPT_ARG_STRING, &password, 'p', "Password to use" },
- {"workgroup", 'w', POPT_ARG_STRING, &workgroup, 'w', "Workgroup to use (optional)" },
- {"nonprompt", 'n', POPT_ARG_NONE, &nonprompt, 'n', "Don't ask anything (non-interactive)" },
- {"debuglevel", 'd', POPT_ARG_INT, &debuglevel, 'd', "Debuglevel to use" },
- {"outputfile", 'o', POPT_ARG_STRING, &outputfile, 'o', "Write downloaded data to specified file" },
- {"stdout", 'O', POPT_ARG_NONE, &send_stdout, 'O', "Write data to stdout" },
- {"dots", 'D', POPT_ARG_NONE, &dots, 'D', "Show dots as progress indication" },
- {"quiet", 'q', POPT_ARG_NONE, &quiet, 'q', "Be quiet" },
- {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" },
- {"keep-permissions", 'P', POPT_ARG_NONE, &keep_permissions, 'P', "Keep permissions" },
- {"blocksize", 'b', POPT_ARG_INT, &blocksize, 'b', "Change number of bytes in a block"},
- {"rcfile", 'f', POPT_ARG_STRING, NULL, 0, "Use specified rc file"},
- POPT_AUTOHELP
- POPT_TABLEEND
- };
- poptContext pc;
-
- /* only read rcfile if it exists */
- asprintf(&rcfile, "%s/.smbgetrc", getenv("HOME"));
- if(access(rcfile, F_OK) == 0) readrcfile(rcfile, long_options);
- free(rcfile);
-
-#ifdef SIGWINCH
- signal(SIGWINCH, change_columns);
-#endif
- signal(SIGINT, signal_quit);
- signal(SIGTERM, signal_quit);
-
- pc = poptGetContext(argv[0], argc, argv, long_options, 0);
-
- while((c = poptGetNextOpt(pc)) >= 0) {
- switch(c) {
- case 'f':
- readrcfile(poptGetOptArg(pc), long_options);
- break;
- case 'a':
- username = ""; password = "";
- break;
- }
- }
-
- if((send_stdout || outputfile) && recursive) {
- fprintf(stderr, "The -o or -O and -R options can not be used together.\n");
- return 1;
- }
-
- if(outputfile && send_stdout) {
- fprintf(stderr, "The -o and -O options cannot be used together.\n");
- return 1;
- }
-
- if(smbc_init(get_auth_data, debuglevel) < 0) {
- fprintf(stderr, "Unable to initialize libsmbclient\n");
- return 1;
- }
-
- columns = get_num_cols();
-
- total_start_time = time(NULL);
-
- while((file = poptGetArg(pc))) {
- if(!recursive) return smb_download_file(file, "", recursive, resume, outputfile);
- else return smb_download_dir(file, "", resume);
- }
-
- clean_exit();
-
- return 0;
-}
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 0476a2e39c0..87d13f33e92 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -1,5 +1,8 @@
+
/*
- * Unix SMB/CIFS implementation.
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * smbpasswd module.
* Copyright (C) Jeremy Allison 1995-1998
* Copyright (C) Tim Potter 2001
*
@@ -19,6 +22,7 @@
#include "includes.h"
+extern pstring global_myname;
extern BOOL AllowDebugChange;
/*
@@ -29,13 +33,36 @@ extern char *optarg;
extern int optind;
/* forced running in root-mode */
-static BOOL got_pass = False, got_username = False;
+static BOOL local_mode;
+static BOOL joining_domain = False, got_pass = False, got_username = False, changing_trust_pw = False, changing_trust_pw_secrets_only = False;
+static int local_flags = 0;
static BOOL stdin_passwd_get = False;
static fstring user_name, user_password;
+static char *new_domain = NULL;
static char *new_passwd = NULL;
+static const char *old_passwd = NULL;
static const char *remote_machine = NULL;
+static pstring servicesf = CONFIGFILE;
+#ifdef WITH_LDAP_SAM
static fstring ldap_secret;
+#endif
+
+
+
+/*********************************************************
+ A strdup with exit
+**********************************************************/
+
+static char *strdup_x(const char *s)
+{
+ char *new_s = strdup(s);
+ if (!new_s) {
+ fprintf(stderr,"out of memory\n");
+ exit(1);
+ }
+ return new_s;
+}
/*********************************************************
@@ -48,6 +75,7 @@ static void usage(void)
printf("otherwise:\n");
printf(" smbpasswd [options] [password]\n\n");
+ printf("Version: %s\n", VERSION);
printf("options:\n");
printf(" -L local mode (must be first option)\n");
printf(" -h print this usage message\n");
@@ -61,13 +89,20 @@ static void usage(void)
printf(" -a add user\n");
printf(" -d disable user\n");
printf(" -e enable user\n");
- printf(" -i interdomain trust account\n");
printf(" -m machine trust account\n");
printf(" -n set no password\n");
- printf(" -w PASSWORD ldap admin password\n");
+#ifdef WITH_LDAP_SAM
+ printf(" -w ldap admin password\n");
+#endif
printf(" -x delete user\n");
+ printf(" -j DOMAIN join domain name\n");
+ printf(" -t DOMAIN change trust account password on domain\n");
+ printf(" -T DOMAIN change trust account password in secrets database only\n");
+ printf(" -S DOMAIN Retrieve the domain SID for DOMAIN\n");
printf(" -R ORDER name resolve order\n");
-
+ printf(" -W S-1-5-... Write the SID S-1-5-... to the secrets file\n");
+ printf(" -X SERVER|DOMAIN Extract SID for SERVER or DOMAIN from the secrets file\n");
+
exit(1);
}
@@ -79,60 +114,74 @@ static void set_line_buffering(FILE *f)
/*******************************************************************
Process command line options
******************************************************************/
-static int process_options(int argc, char **argv, int local_flags)
+static void process_options(int argc, char **argv, BOOL amroot)
{
int ch;
- pstring configfile;
- pstrcpy(configfile, dyn_CONFIGFILE);
-
- local_flags |= LOCAL_SET_PASSWORD;
-
- ZERO_STRUCT(user_name);
- ZERO_STRUCT(user_password);
+ DOM_SID dom_sid;
+ fstring sid_str;
user_name[0] = '\0';
- while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:L")) != EOF) {
+ while ((ch = getopt(argc, argv, "c:axdehmnj:t:T:r:sw:R:D:U:LSW:X:")) != EOF) {
switch(ch) {
case 'L':
- local_flags |= LOCAL_AM_ROOT;
+ local_mode = amroot = True;
break;
case 'c':
- pstrcpy(configfile,optarg);
+ pstrcpy(servicesf,optarg);
break;
case 'a':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_ADD_USER;
break;
case 'x':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_DELETE_USER;
- local_flags &= ~LOCAL_SET_PASSWORD;
+ new_passwd = strdup_x("XXXXXX");
break;
case 'd':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_DISABLE_USER;
- local_flags &= ~LOCAL_SET_PASSWORD;
+ new_passwd = strdup_x("XXXXXX");
break;
case 'e':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_ENABLE_USER;
- local_flags &= ~LOCAL_SET_PASSWORD;
break;
case 'm':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_TRUST_ACCOUNT;
break;
- case 'i':
- local_flags |= LOCAL_INTERDOM_ACCOUNT;
- break;
- case 'j':
- d_printf("See 'net join' for this functionality\n");
- exit(1);
- break;
case 'n':
+ if (!amroot) goto bad_args;
local_flags |= LOCAL_SET_NO_PASSWORD;
- local_flags &= ~LOCAL_SET_PASSWORD;
- new_passwd = smb_xstrdup("NO PASSWORD");
+ new_passwd = strdup_x("NO PASSWORD");
+ break;
+ case 'j':
+ if (!amroot) goto bad_args;
+ new_domain = optarg;
+ strupper(new_domain);
+ joining_domain = True;
break;
+ case 't':
+ if (!amroot) goto bad_args;
+ new_domain = optarg;
+ strupper(new_domain);
+ changing_trust_pw = True;
+ break;
+ case 'T':
+ if (!amroot) goto bad_args;
+ new_domain = optarg;
+ strupper(new_domain);
+ changing_trust_pw_secrets_only = True;
+ break;
case 'r':
remote_machine = optarg;
break;
+ case 'S':
+ if (!amroot) goto bad_args;
+ local_flags |= LOCAL_GET_DOM_SID;
+ break;
case 's':
set_line_buffering(stdin);
set_line_buffering(stdout);
@@ -140,10 +189,17 @@ static int process_options(int argc, char **argv, int local_flags)
stdin_passwd_get = True;
break;
case 'w':
+ if (!amroot) goto bad_args;
+#ifdef WITH_LDAP_SAM
local_flags |= LOCAL_SET_LDAP_ADMIN_PW;
fstrcpy(ldap_secret, optarg);
break;
+#else
+ printf("-w not available unless configured --with-ldapsam\n");
+ goto bad_args;
+#endif
case 'R':
+ if (!amroot) goto bad_args;
lp_set_name_resolve_order(optarg);
break;
case 'D':
@@ -159,14 +215,67 @@ static int process_options(int argc, char **argv, int local_flags)
*lp = 0;
fstrcpy(user_password, lp + 1);
got_pass = True;
- memset(strchr_m(optarg, '%') + 1, 'X',
+ memset(strchr(optarg, '%') + 1, 'X',
strlen(user_password));
}
- break;
}
+ break;
+
+ case 'W': /* Take the SID on the command line and make it ours */
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ servicesf);
+ exit(1);
+ }
+
+ if (!string_to_sid(&dom_sid, optarg)) {
+ fprintf(stderr, "Invalid SID: %s\n", optarg);
+ exit(1);
+ }
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to open secrets database!\n");
+ exit(1);
+ }
+ if (!secrets_store_domain_sid(global_myname, &dom_sid)) {
+ fprintf(stderr, "Unable to write the new SID %s as the server SID for %s\n", optarg, global_myname);
+ exit(1);
+ }
+ /*
+ * Now, write it to the workgroup as well, to make
+ * things consistent. This is a risk however.
+ */
+ if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
+ fprintf(stderr, "Unable to write the new SID %s as the domain SID for %s\n", optarg, lp_workgroup());
+ exit(1);
+ }
+
+ exit(0);
+ break;
+
+ case 'X': /* Extract the SID for a domain from secrets */
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ servicesf);
+ exit(1);
+ }
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to open secrets database!\n");
+ exit(1);
+ }
+ if (secrets_fetch_domain_sid(optarg, &dom_sid)) {
+ sid_to_string(sid_str, &dom_sid);
+ printf("SID for domain %s is: %s\n", optarg, sid_str);
+ exit(0);
+ }
+ else {
+ fprintf(stderr, "Could not retrieve SID for domain: %s\n", optarg);
+ exit(1);
+ }
+ break;
case 'h':
default:
+bad_args:
usage();
}
}
@@ -174,41 +283,481 @@ static int process_options(int argc, char **argv, int local_flags)
argc -= optind;
argv += optind;
+ if (joining_domain && (argc != 0))
+ usage();
+
switch(argc) {
case 0:
if (!got_username)
fstrcpy(user_name, "");
break;
case 1:
- if (!(local_flags & LOCAL_AM_ROOT)) {
+ if (!amroot == 1) {
new_passwd = argv[0];
- } else {
- if (got_username) {
- usage();
- } else {
- fstrcpy(user_name, argv[0]);
- }
+ break;
}
+ if (got_username)
+ usage();
+ fstrcpy(user_name, argv[0]);
break;
case 2:
- if (!(local_flags & LOCAL_AM_ROOT) || got_username || got_pass) {
+ if (!amroot || got_username || got_pass)
usage();
- }
-
fstrcpy(user_name, argv[0]);
- new_passwd = smb_xstrdup(argv[1]);
+ new_passwd = strdup_x(argv[1]);
break;
default:
usage();
}
- if (!lp_load(configfile,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n",
- dyn_CONFIGFILE);
- exit(1);
+}
+
+/* Initialise client credentials for authenticated pipe access */
+
+void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
+ char* domain, char* password)
+{
+ ZERO_STRUCTP(creds);
+
+ if (lp_encrypted_passwords()) {
+ pwd_make_lm_nt_16(&creds->pwd, password);
+ } else {
+ pwd_set_cleartext(&creds->pwd, password);
}
- return local_flags;
+ fstrcpy(creds->user_name, username);
+ fstrcpy(creds->domain, domain);
+}
+
+/*********************************************************
+Join a domain using the administrator username and password
+**********************************************************/
+
+/* Macro for checking RPC error codes to make things more readable */
+
+#define CHECK_RPC_ERR(rpc, msg) \
+ if (!NT_STATUS_IS_OK(result = rpc)) { \
+ DEBUG(0, (msg ": %s\n", get_nt_error_msg(result))); \
+ goto done; \
+ }
+
+#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \
+ if (!NT_STATUS_IS_OK(result = rpc)) { \
+ DEBUG(0, debug_args); \
+ goto done; \
+ }
+
+static int join_domain_byuser(char *domain, const char *remote,
+ char *username, char *password)
+{
+ /* libsmb variables */
+
+ pstring pdc_name;
+ struct nmb_name calling, called;
+ struct ntuser_creds creds;
+ struct cli_state cli;
+ fstring acct_name;
+ struct in_addr dest_ip;
+ TALLOC_CTX *mem_ctx;
+
+ /* rpc variables */
+
+ POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol;
+ DOM_SID domain_sid;
+ uint32 user_rid;
+
+ /* Password stuff */
+
+ char *machine_pwd;
+ int plen = 0;
+ uchar pwbuf[516], ntpw[16], sess_key[16];
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_24 p24;
+ SAM_USER_INFO_10 p10;
+
+ /* Misc */
+
+ NTSTATUS result;
+ int retval = 1;
+
+ pstrcpy(pdc_name, remote ? remote : "");
+
+ /* Connect to remote machine */
+
+ ZERO_STRUCT(cli);
+ ZERO_STRUCT(creds);
+ ZERO_STRUCT(dest_ip); /* Make sure no nasty surprises */
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("Could not initialise talloc context\n"));
+ goto done;
+ }
+
+ if (!cli_initialise(&cli)) {
+ DEBUG(0, ("Could not initialise client structure\n"));
+ goto done;
+ }
+
+ init_rpcclient_creds(&creds, username, domain, password);
+ cli_init_creds(&cli, &creds);
+
+ /*
+ * If we are given a remote machine assume this is the PDC.
+ */
+
+ if(remote == NULL || !strcmp(remote, "*")) {
+ struct in_addr *ip_list;
+ int addr_count;
+ if (!get_dc_list(True /* PDC only*/, domain, &ip_list, &addr_count)) {
+ fprintf(stderr, "Unable to find the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ if ((addr_count < 1) || (is_zero_ip(ip_list[0]))) {
+ fprintf(stderr, "Incorrect entries returned when finding the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+
+ if (!lookup_dc_name(global_myname, domain, &ip_list[0], pdc_name)) {
+ fprintf(stderr, "Unable to lookup the name for the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ dest_ip = ip_list[0];
+ }
+
+ make_nmb_name(&called, pdc_name, 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ if (!cli_establish_connection(&cli, pdc_name, &dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_error(&cli))) {
+ DEBUG(0, ("Error connecting to %s - %s\n", pdc_name,cli_errstr(&cli)));
+ } else {
+ DEBUG(0, ("Error connecting to %s\n", pdc_name));
+ }
+ goto done;
+ }
+
+ /* Fetch domain sid */
+
+ if (!cli_nt_session_open(&cli, PIPE_LSARPC)) {
+ DEBUG(0, ("Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+
+ CHECK_RPC_ERR(cli_lsa_open_policy(&cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &lsa_pol),
+ "error opening lsa policy handle");
+
+ CHECK_RPC_ERR(cli_lsa_query_info_policy(&cli, mem_ctx, &lsa_pol,
+ 5, domain, &domain_sid),
+ "error querying info policy");
+
+ cli_lsa_close(&cli, mem_ctx, &lsa_pol);
+
+ cli_nt_session_close(&cli); /* Done with this pipe */
+
+ /* Create domain user */
+
+ if (!cli_nt_session_open(&cli, PIPE_SAMR)) {
+ DEBUG(0, ("Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+ CHECK_RPC_ERR(cli_samr_connect(&cli, mem_ctx,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &sam_pol),
+ "could not connect to SAM database");
+
+
+ CHECK_RPC_ERR(cli_samr_open_domain(&cli, mem_ctx, &sam_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain_sid, &domain_pol),
+ "could not open domain");
+
+ /* Create domain user */
+
+ fstrcpy(acct_name, global_myname);
+ fstrcat(acct_name, "$");
+
+ strlower(acct_name);
+
+ {
+ uint32 unknown = 0xe005000b;
+
+ result = cli_samr_create_dom_user(&cli, mem_ctx, &domain_pol,
+ acct_name, ACB_WSTRUST,
+ unknown, &user_pol,
+ &user_rid);
+ }
+
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ /* We *must* do this.... don't ask... */
+
+ CHECK_RPC_ERR_DEBUG(cli_samr_close(&cli, mem_ctx, &user_pol), ("error closing user policy"));
+ result = NT_STATUS_USER_EXISTS;
+ }
+
+ if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_USER_EXISTS)) {
+ uint32 num_rids, *name_types, *user_rids;
+ uint32 flags = 0x3e8;
+ const char *names;
+
+ /* Look up existing rid */
+
+ names = (char *)&acct_name[0];
+
+ CHECK_RPC_ERR_DEBUG(
+ cli_samr_lookup_names(&cli, mem_ctx,
+ &domain_pol, flags,
+ 1, &names, &num_rids,
+ &user_rids, &name_types),
+ ("error looking up rid for user %s: %s\n",
+ acct_name, get_nt_error_msg(result)));
+
+ if (name_types[0] != SID_NAME_USER) {
+ DEBUG(0, ("%s is not a user account\n", acct_name));
+ goto done;
+ }
+
+ user_rid = user_rids[0];
+
+ /* Open handle on user */
+
+ CHECK_RPC_ERR_DEBUG(
+ cli_samr_open_user(&cli, mem_ctx, &domain_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ user_rid, &user_pol),
+ ("could not re-open existing user %s: %s\n",
+ acct_name, get_nt_error_msg(result)));
+
+ } else if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("error creating domain user: %s\n",
+ get_nt_error_msg(result)));
+ goto done;
+ }
+
+ /* Create a random machine account password */
+
+ {
+ UNISTR2 upw; /* Unicode password */
+
+ upw.buffer = (uint16 *)talloc_zero(mem_ctx, 0xc *
+ sizeof(uint16));
+
+ upw.uni_str_len = 0xc;
+ upw.uni_max_len = 0xc;
+
+ machine_pwd = (char *)upw.buffer;
+ plen = upw.uni_str_len * 2;
+ generate_random_buffer((unsigned char *)machine_pwd, plen, True);
+
+ encode_pw_buffer((char *)pwbuf, machine_pwd, plen, False);
+
+ mdfour( ntpw, (unsigned char *)upw.buffer, plen);
+ }
+
+ /* Set password on machine account */
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(p24);
+
+ init_sam_user_info24(&p24, (char *)pwbuf,24);
+
+ ctr.switch_value = 24;
+ ctr.info.id24 = &p24;
+
+ /* I don't think this is quite the right place for this
+ calculation. It should be moved somewhere where the credentials
+ are calculated. )-: */
+
+ mdfour(sess_key, cli.pwd.smb_nt_pwd, 16);
+
+ CHECK_RPC_ERR(cli_samr_set_userinfo(&cli, mem_ctx, &user_pol, 24,
+ sess_key, &ctr),
+ "error setting trust account password");
+
+ /* Why do we have to try to (re-)set the ACB to be the same as what
+ we passed in the samr_create_dom_user() call? When a NT
+ workstation is joined to a domain by an administrator the
+ acb_info is set to 0x80. For a normal user with "Add
+ workstations to the domain" rights the acb_info is 0x84. I'm
+ not sure whether it is supposed to make a difference or not. NT
+ seems to cope with either value so don't bomb out if the set
+ userinfo2 level 0x10 fails. -tpot */
+
+ ZERO_STRUCT(ctr);
+ ctr.switch_value = 0x10;
+ ctr.info.id10 = &p10;
+
+ init_sam_user_info10(&p10, ACB_WSTRUST);
+
+ /* Ignoring the return value is necessary for joining a domain
+ as a normal user with "Add workstation to domain" privilege. */
+
+ result = cli_samr_set_userinfo2(&cli, mem_ctx, &user_pol, 0x10,
+ sess_key, &ctr);
+
+ /* Now store the secret in the secrets database */
+
+ strupper(domain);
+
+ if (!secrets_store_domain_sid(domain, &domain_sid) ||
+ !secrets_store_trust_account_password(domain, ntpw)) {
+ DEBUG(0, ("error storing domain secrets\n"));
+ goto done;
+ }
+
+ retval = 0; /* Success! */
+
+ done:
+ /* Close down pipe - this will clean up open policy handles */
+
+ if (cli.nt_pipe_fnum)
+ cli_nt_session_close(&cli);
+
+ /* Display success or failure */
+
+ if (retval != 0) {
+ trust_password_delete(domain);
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
+
+ return retval;
+}
+
+/*********************************************************
+Join a domain. Old server manager method.
+**********************************************************/
+
+static int join_domain(char *domain, const char *remote)
+{
+ pstring pdc_name;
+ fstring trust_passwd;
+ unsigned char orig_trust_passwd_hash[16];
+ DOM_SID domain_sid;
+ BOOL ret;
+
+ pstrcpy(pdc_name, remote ? remote : "");
+ fstrcpy(trust_passwd, global_myname);
+ strlower(trust_passwd);
+
+ /*
+ * Machine names can be 15 characters, but the max length on
+ * a password is 14. --jerry
+ */
+ trust_passwd[14] = '\0';
+
+ E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
+
+ /* Ensure that we are not trying to join a
+ domain if we are locally set up as a domain
+ controller. */
+
+ if(strequal(remote, global_myname)) {
+ fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
+ return 1;
+ }
+
+ /*
+ * Write the old machine account password.
+ */
+
+ if(!secrets_store_trust_account_password(domain, orig_trust_passwd_hash)) {
+ fprintf(stderr, "Unable to write the machine account password for \
+machine %s in domain %s.\n", global_myname, domain);
+ return 1;
+ }
+
+ /*
+ * If we are given a remote machine assume this is the PDC.
+ */
+
+ if(remote == NULL || !strcmp(remote, "*")) {
+ struct in_addr *ip_list = NULL;
+ int addr_count;
+ if (!get_dc_list(True /* PDC only*/, domain, &ip_list, &addr_count)) {
+ fprintf(stderr, "Unable to find the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ if ((addr_count < 1) || (is_zero_ip(ip_list[0]))) {
+ fprintf(stderr, "Incorrect entries returned when finding the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+
+ if (!lookup_dc_name(global_myname, domain, &ip_list[0], pdc_name)) {
+ fprintf(stderr, "Unable to lookup the name for the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ }
+
+ if (!fetch_domain_sid( domain, pdc_name, &domain_sid) ||
+ !secrets_store_domain_sid(domain, &domain_sid)) {
+ fprintf(stderr,"Failed to get domain SID. Unable to join domain %s.\n",domain);
+ return 1;
+ }
+
+ ret = change_trust_account_password( domain, pdc_name);
+
+ if(!ret) {
+ trust_password_delete(domain);
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ return 1;
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
+
+ return 0;
+}
+
+static int set_domain_sid_from_dc( char *domain, const char *remote )
+{
+ pstring pdc_name;
+ DOM_SID domain_sid;
+ fstring sid_str;
+
+ pstrcpy(pdc_name, remote ? remote : "");
+
+ if(strequal(pdc_name, global_myname)) {
+ fprintf(stderr, "Cannot fetch domain sid for %s as the domain controller name is our own.\n", domain);
+ return 1;
+ }
+
+ if(remote == NULL || !strcmp(remote, "*")) {
+ struct in_addr *ip_list = NULL;
+ int addr_count;
+ if (!get_dc_list(False , domain, &ip_list, &addr_count)) {
+ fprintf(stderr, "Unable to find the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ if ((addr_count < 1) || (is_zero_ip(ip_list[0]))) {
+ fprintf(stderr, "Incorrect entries returned when finding the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+
+ if (!lookup_dc_name(global_myname, domain, &ip_list[0], pdc_name)) {
+ fprintf(stderr, "Unable to lookup the name for the domain controller for domain %s.\n", domain);
+ return 1;
+ }
+ }
+
+ if (!fetch_domain_sid( domain, pdc_name, &domain_sid)
+ || !secrets_store_domain_sid(global_myname, &domain_sid))
+ {
+ fprintf(stderr,"Failed to get domain SID for %s.\n",domain);
+ return 1;
+ }
+
+ sid_to_string(sid_str, &domain_sid);
+ printf("Successfully set domain SID to %s.\n", sid_str);
+
+ return 0;
+
}
/*************************************************************
@@ -217,23 +766,23 @@ static int process_options(int argc, char **argv, int local_flags)
*************************************************************/
static char *stdin_new_passwd(void)
{
- static fstring new_pw;
+ static fstring new_pwd;
size_t len;
- ZERO_ARRAY(new_pw);
+ ZERO_ARRAY(new_pwd);
/*
* if no error is reported from fgets() and string at least contains
* the newline that ends the password, then replace the newline with
* a null terminator.
*/
- if ( fgets(new_pw, sizeof(new_pw), stdin) != NULL) {
- if ((len = strlen(new_pw)) > 0) {
- if(new_pw[len-1] == '\n')
- new_pw[len - 1] = 0;
+ if ( fgets(new_pwd, sizeof(new_pwd), stdin) != NULL) {
+ if ((len = strlen(new_pwd)) > 0) {
+ if(new_pwd[len-1] == '\n')
+ new_pwd[len - 1] = 0;
}
}
- return(new_pw);
+ return(new_pwd);
}
@@ -250,7 +799,7 @@ static char *get_pass( const char *prompt, BOOL stdin_get)
} else {
p = getpass(prompt);
}
- return smb_xstrdup(p);
+ return strdup_x(p);
}
/*************************************************************
@@ -259,21 +808,21 @@ static char *get_pass( const char *prompt, BOOL stdin_get)
static char *prompt_for_new_password(BOOL stdin_get)
{
char *p;
- fstring new_pw;
+ fstring new_pwd;
- ZERO_ARRAY(new_pw);
+ ZERO_ARRAY(new_pwd);
p = get_pass("New SMB password:", stdin_get);
- fstrcpy(new_pw, p);
- SAFE_FREE(p);
+ fstrcpy(new_pwd, p);
+ safe_free(p);
p = get_pass("Retype new SMB password:", stdin_get);
- if (strcmp(p, new_pw)) {
+ if (strcmp(p, new_pwd)) {
fprintf(stderr, "Mismatch - password unchanged.\n");
- ZERO_ARRAY(new_pw);
- SAFE_FREE(p);
+ ZERO_ARRAY(new_pwd);
+ safe_free(p);
return NULL;
}
@@ -285,27 +834,27 @@ static char *prompt_for_new_password(BOOL stdin_get)
Change a password either locally or remotely.
*************************************************************/
-static BOOL password_change(const char *remote_mach, char *username,
- char *old_passwd, char *new_pw, int local_flags)
+static BOOL password_change(const char *rem_machine, char *usr_name,
+ const char *old_pwd, char *new_pwd, int loc_flags)
{
BOOL ret;
pstring err_str;
pstring msg_str;
- if (remote_mach != NULL) {
- if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|
+ if (rem_machine != NULL) {
+ if (loc_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|
LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) {
/* these things can't be done remotely yet */
return False;
}
- ret = remote_password_change(remote_mach, username,
- old_passwd, new_pw, err_str, sizeof(err_str));
+ ret = remote_password_change(rem_machine, usr_name,
+ old_pwd, new_pwd, err_str, sizeof(err_str));
if(*err_str)
fprintf(stderr, err_str);
return ret;
}
- ret = local_password_change(username, local_flags, new_pw,
+ ret = local_password_change(usr_name, loc_flags, new_pwd,
err_str, sizeof(err_str), msg_str, sizeof(msg_str));
if(*msg_str)
@@ -316,11 +865,12 @@ static BOOL password_change(const char *remote_mach, char *username,
return ret;
}
+#ifdef WITH_LDAP_SAM
/*******************************************************************
Store the LDAP admin password in secrets.tdb
******************************************************************/
static BOOL store_ldap_admin_pw (char* pw)
-{
+{
if (!pw)
return False;
@@ -329,55 +879,132 @@ static BOOL store_ldap_admin_pw (char* pw)
return secrets_store_ldap_pw(lp_ldap_admin_dn(), pw);
}
+#endif
/*************************************************************
Handle password changing for root.
*************************************************************/
-static int process_root(int local_flags)
+static int process_root(void)
{
struct passwd *pwd;
int result = 0;
- char *old_passwd = NULL;
- if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) {
+#ifdef WITH_LDAP_SAM
+ if (local_flags & LOCAL_SET_LDAP_ADMIN_PW)
+ {
printf("Setting stored password for \"%s\" in secrets.tdb\n",
lp_ldap_admin_dn());
if (!store_ldap_admin_pw(ldap_secret))
DEBUG(0,("ERROR: Failed to store the ldap admin password!\n"));
goto done;
}
-
- /* Ensure passdb startup(). */
- if(!initialize_password_db(False)) {
- DEBUG(0, ("Failed to open passdb!\n"));
- exit(1);
- }
-
- /* Ensure we have a SAM sid. */
- get_global_sam_sid();
+#endif
/*
* Ensure both add/delete user are not set
* Ensure add/delete user and either remote machine or join domain are
* not both set.
*/
- if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) ||
- ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) &&
- (remote_machine != NULL))) {
+ if ( ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER))
+ || ( (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER))
+ && ((remote_machine != NULL) || joining_domain || changing_trust_pw) ) )
+ {
usage();
}
/* Only load interfaces if we are doing network operations. */
- if (remote_machine) {
+ if ( joining_domain || remote_machine || (local_flags & LOCAL_GET_DOM_SID) ) {
load_interfaces();
}
- if (!user_name[0] && (pwd = getpwuid_alloc(geteuid()))) {
+ /* Join a domain */
+
+ if (joining_domain) {
+
+ /* smb.conf must specify both security = domain and encrypt passwords = yes */
+
+ if (!lp_encrypted_passwords() || lp_security() != SEC_DOMAIN) {
+ DEBUG(0,("ERROR: Must have both SECURITY = DOMAIN and ENCRYPT PASSWORDS = YES!\n"));
+ return 1;
+ }
+
+ /* Are we joining by specifing an admin username and
+ password? */
+
+ if (user_name[0]) {
+
+ /* Get administrator password if not specified */
+
+ if (!got_pass) {
+ char *pass = get_pass("Password: ",stdin_passwd_get);
+
+ if (pass)
+ pstrcpy(user_password, pass);
+ }
+
+ return join_domain_byuser(new_domain, remote_machine,
+ user_name, user_password);
+ } else {
+
+ /* Or just with the server manager? */
+
+ return join_domain(new_domain, remote_machine);
+ }
+ }
+
+
+ /* Change Trust Password */
+
+ if (changing_trust_pw) {
+ if (change_trust_account_password(new_domain, remote_machine)) {
+ return 0;
+ }
+ return 1;
+ }
+
+ /* Change trust password in secrets database only */
+ if (changing_trust_pw_secrets_only)
+ {
+ char *trust_pw;
+ char trust_pw_hash[16];
+
+ trust_pw = get_pass("Trust account password: ",stdin_passwd_get);
+
+ E_md4hash(trust_pw,trust_pw_hash);
+
+ if(!secrets_store_trust_account_password(new_domain,trust_pw_hash))
+ {
+ fprintf(stderr, "Unable to write the machine account password for \
+ machine %s in domain %s.\n", global_myname, new_domain);
+ return 1;
+ }
+ else
+ {
+ fprintf(stdout, "Modified trust account password in secrets database\n");
+ }
+
+ return 0;
+ }
+
+ /*
+ * get the domain sid from a PDC and store it in secrets.tdb
+ * Used for Samba PDC/BDC installations.
+ *
+ */
+
+ if (local_flags & LOCAL_GET_DOM_SID) {
+ return set_domain_sid_from_dc(lp_workgroup(), remote_machine);
+ }
+
+ /*
+ * Deal with root - can add a user, but only locally.
+ */
+
+ if (!user_name[0] && (pwd = sys_getpwuid(0))) {
fstrcpy(user_name, pwd->pw_name);
- passwd_free(&pwd);
}
if (!user_name[0]) {
@@ -399,9 +1026,9 @@ static int process_root(int local_flags)
}
if (local_flags & LOCAL_ADD_USER) {
- SAFE_FREE(new_passwd);
- new_passwd = smb_xstrdup(user_name);
- strlower_m(new_passwd);
+ safe_free(new_passwd);
+ new_passwd = strdup_x(user_name);
+ strlower(new_passwd);
}
/*
@@ -411,64 +1038,50 @@ static int process_root(int local_flags)
slprintf(buf, sizeof(buf)-1, "%s$", user_name);
fstrcpy(user_name, buf);
- } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
- static fstring buf;
+ }
- if ((local_flags & LOCAL_ADD_USER) && (new_passwd == NULL)) {
- /*
- * Prompt for trusting domain's account password
- */
- new_passwd = prompt_for_new_password(stdin_passwd_get);
- if(!new_passwd) {
- fprintf(stderr, "Unable to get newpassword.\n");
- exit(1);
- }
- }
-
- /* prepare uppercased and '$' terminated username */
- slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
- fstrcpy(user_name, buf);
-
- } else {
-
- if (remote_machine != NULL) {
- old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
- }
-
- if (!(local_flags & LOCAL_SET_PASSWORD)) {
+ if (remote_machine != NULL) {
+ old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
+ }
+
+ if (!new_passwd) {
+
+ /*
+ * If we are trying to enable a user, first we need to find out
+ * if they are using a modern version of the smbpasswd file that
+ * disables a user by just writing a flag into the file. If so
+ * then we can re-enable a user without prompting for a new
+ * password. If not (ie. they have a no stored password in the
+ * smbpasswd file) then we need to prompt for a new password.
+ */
+
+ if(local_flags & LOCAL_ENABLE_USER) {
- /*
- * If we are trying to enable a user, first we need to find out
- * if they are using a modern version of the smbpasswd file that
- * disables a user by just writing a flag into the file. If so
- * then we can re-enable a user without prompting for a new
- * password. If not (ie. they have a no stored password in the
- * smbpasswd file) then we need to prompt for a new password.
- */
+ SAM_ACCOUNT *sampass = NULL;
- if(local_flags & LOCAL_ENABLE_USER) {
- SAM_ACCOUNT *sampass = NULL;
- BOOL ret;
-
- pdb_init_sam(&sampass);
- ret = pdb_getsampwnam(sampass, user_name);
- if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) {
- local_flags |= LOCAL_SET_PASSWORD;
- }
- pdb_free_sam(&sampass);
+ pdb_init_sam(&sampass);
+ if (!pdb_getsampwnam(sampass, user_name)) {
+ printf("ERROR: Unable to locate %s in passdb!\n", user_name);
+ pdb_free_sam(sampass);
+ result = 1;
+ goto done;
+ }
+ if((sampass != NULL) && (pdb_get_lanman_passwd(sampass) != NULL)) {
+ new_passwd = strdup_x("XXXX"); /* Don't care. */
}
+
+ pdb_free_sam(sampass);
}
-
- if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
+
+ if(!new_passwd)
new_passwd = prompt_for_new_password(stdin_passwd_get);
-
- if(!new_passwd) {
- fprintf(stderr, "Unable to get new password.\n");
- exit(1);
- }
+
+ if(!new_passwd) {
+ fprintf(stderr, "Unable to get new password.\n");
+ exit(1);
}
}
-
+
if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) {
fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
result = 1;
@@ -477,24 +1090,32 @@ static int process_root(int local_flags)
if(remote_machine) {
printf("Password changed for user %s on %s.\n", user_name, remote_machine );
- } else if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD|LOCAL_SET_PASSWORD))) {
+ } else if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) {
SAM_ACCOUNT *sampass = NULL;
- BOOL ret;
+ uint16 acct_ctrl;
pdb_init_sam(&sampass);
- ret = pdb_getsampwnam(sampass, user_name);
-
+
+ if (!pdb_getsampwnam(sampass, user_name)) {
+ printf("ERROR: Unable to locate %s in passdb!\n", user_name);
+ pdb_free_sam(sampass);
+ result = 1;
+ goto done;
+ }
+
printf("Password changed for user %s.", user_name );
- if( (ret != False) && (pdb_get_acct_ctrl(sampass)&ACB_DISABLED) )
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+ if(acct_ctrl & ACB_DISABLED)
printf(" User has disabled flag set.");
- if((ret != False) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) )
+ if(acct_ctrl & ACB_PWNOTREQ)
printf(" User has no password flag set.");
printf("\n");
- pdb_free_sam(&sampass);
+
+ pdb_free_sam(sampass);
}
done:
- SAFE_FREE(new_passwd);
+ safe_free(new_passwd);
return result;
}
@@ -503,25 +1124,19 @@ static int process_root(int local_flags)
Handle password changing for non-root.
*************************************************************/
-static int process_nonroot(int local_flags)
+static int process_nonroot(void)
{
struct passwd *pwd = NULL;
int result = 0;
- char *old_pw = NULL;
char *new_pw = NULL;
-
- if (local_flags & ~(LOCAL_AM_ROOT | LOCAL_SET_PASSWORD)) {
- /* Extra flags that we can't honor non-root */
- usage();
- }
+ char *old_pw = NULL;
if (!user_name[0]) {
- pwd = getpwuid_alloc(getuid());
+ pwd = sys_getpwuid(getuid());
if (pwd) {
fstrcpy(user_name,pwd->pw_name);
- passwd_free(&pwd);
} else {
- fprintf(stderr, "smbpasswd: you don't exist - go away\n");
+ fprintf(stderr,"you don't exist - go away\n");
exit(1);
}
}
@@ -546,7 +1161,7 @@ static int process_nonroot(int local_flags)
new_pw = prompt_for_new_password(stdin_passwd_get);
}
else
- new_pw = smb_xstrdup(new_passwd);
+ new_pw = strdup_x(new_passwd);
if (!new_pw) {
fprintf(stderr, "Unable to get new password.\n");
@@ -575,40 +1190,58 @@ static int process_nonroot(int local_flags)
**********************************************************/
int main(int argc, char **argv)
{
- int local_flags = 0;
-
+ BOOL amroot = getuid() == 0;
+
+ DEBUGLEVEL = 0;
AllowDebugChange = False;
#if defined(HAVE_SET_AUTH_PARAMETERS)
set_auth_parameters(argc, argv);
#endif /* HAVE_SET_AUTH_PARAMETERS */
- if (getuid() == 0) {
- local_flags = LOCAL_AM_ROOT;
+ charset_initialise();
+
+ process_options(argc, argv, amroot);
+ TimeInit();
+
+ setup_logging("smbpasswd", True);
+
+ if(!initialize_password_db(False)) {
+ fprintf(stderr, "Can't setup password database vectors.\n");
+ exit(1);
}
- local_flags = process_options(argc, argv, local_flags);
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ servicesf);
+ exit(1);
+ }
- setup_logging("smbpasswd", True);
-
/*
* Set the machine NETBIOS name if not already
* set from the config file.
*/
- if (!init_names())
- return 1;
+ if (!*global_myname) {
+ char *p;
+ fstrcpy(global_myname, myhostname());
+ p = strchr(global_myname, '.' );
+ if (p) *p = 0;
+ }
+ strupper(global_myname);
+
+ codepage_initialise(lp_client_code_page());
/* Check the effective uid - make sure we are not setuid */
- if (is_setuid_root()) {
+ if ((geteuid() == (uid_t)0) && (getuid() != (uid_t)0)) {
fprintf(stderr, "smbpasswd must *NOT* be setuid root.\n");
exit(1);
}
- if (local_flags & LOCAL_AM_ROOT) {
+ if (local_mode || amroot) {
secrets_init();
- return process_root(local_flags);
+ return process_root();
}
- return process_nonroot(local_flags);
+ return process_nonroot();
}
diff --git a/source/utils/smbtree.c b/source/utils/smbtree.c
deleted file mode 100644
index cbe1bd448f8..00000000000
--- a/source/utils/smbtree.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Network neighbourhood browser.
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Jelmer Vernooij 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-static BOOL use_bcast;
-
-/* How low can we go? */
-
-enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE};
-static enum tree_level level = LEV_SHARE;
-
-/* Holds a list of workgroups or servers */
-
-struct name_list {
- struct name_list *prev, *next;
- pstring name, comment;
- uint32 server_type;
-};
-
-static struct name_list *workgroups, *servers, *shares;
-
-static void free_name_list(struct name_list *list)
-{
- while(list)
- DLIST_REMOVE(list, list);
-}
-
-static void add_name(const char *machine_name, uint32 server_type,
- const char *comment, void *state)
-{
- struct name_list **name_list = (struct name_list **)state;
- struct name_list *new_name;
-
- new_name = (struct name_list *)malloc(sizeof(struct name_list));
-
- if (!new_name)
- return;
-
- ZERO_STRUCTP(new_name);
-
- pstrcpy(new_name->name, machine_name);
- pstrcpy(new_name->comment, comment);
- new_name->server_type = server_type;
-
- DLIST_ADD(*name_list, new_name);
-}
-
-/****************************************************************************
- display tree of smb workgroups, servers and shares
-****************************************************************************/
-static BOOL get_workgroups(struct user_auth_info *user_info)
-{
- struct cli_state *cli;
- struct in_addr server_ip;
- pstring master_workgroup;
-
- /* Try to connect to a #1d name of our current workgroup. If that
- doesn't work broadcast for a master browser and then jump off
- that workgroup. */
-
- pstrcpy(master_workgroup, lp_workgroup());
-
- if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) {
- DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n",
- master_workgroup));
- use_bcast = True;
- } else if(!use_bcast) {
- if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
- return False;
- }
-
- if (!(cli = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) {
- DEBUG(4, ("Unable to find master browser by "
- "broadcast\n"));
- return False;
- }
-
- if (!cli_NetServerEnum(cli, master_workgroup,
- SV_TYPE_DOMAIN_ENUM, add_name, &workgroups))
- return False;
-
- return True;
-}
-
-/* Retrieve the list of servers for a given workgroup */
-
-static BOOL get_servers(char *workgroup, struct user_auth_info *user_info)
-{
- struct cli_state *cli;
- struct in_addr server_ip;
-
- /* Open an IPC$ connection to the master browser for the workgroup */
-
- if (!find_master_ip(workgroup, &server_ip)) {
- DEBUG(4, ("Cannot find master browser for workgroup %s\n",
- workgroup));
- return False;
- }
-
- if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
- return False;
-
- if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name,
- &servers))
- return False;
-
- return True;
-}
-
-static BOOL get_shares(char *server_name, struct user_auth_info *user_info)
-{
- struct cli_state *cli;
-
- if (!(cli = get_ipc_connect(server_name, NULL, user_info)))
- return False;
-
- if (!cli_RNetShareEnum(cli, add_name, &shares))
- return False;
-
- return True;
-}
-
-static BOOL print_tree(struct user_auth_info *user_info)
-{
- struct name_list *wg, *sv, *sh;
-
- /* List workgroups */
-
- if (!get_workgroups(user_info))
- return False;
-
- for (wg = workgroups; wg; wg = wg->next) {
-
- printf("%s\n", wg->name);
-
- /* List servers */
-
- free_name_list(servers);
- servers = NULL;
-
- if (level == LEV_WORKGROUP ||
- !get_servers(wg->name, user_info))
- continue;
-
- for (sv = servers; sv; sv = sv->next) {
-
- printf("\t\\\\%-15s\t\t%s\n",
- sv->name, sv->comment);
-
- /* List shares */
-
- free_name_list(shares);
- shares = NULL;
-
- if (level == LEV_SERVER ||
- !get_shares(sv->name, user_info))
- continue;
-
- for (sh = shares; sh; sh = sh->next) {
- printf("\t\t\\\\%s\\%-15s\t%s\n",
- sv->name, sh->name, sh->comment);
- }
- }
- }
-
- return True;
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "broadcast", 'b', POPT_ARG_VAL, &use_bcast, True, "Use broadcast instead of using the master browser" },
- { "domains", 'D', POPT_ARG_VAL, &level, LEV_WORKGROUP, "List only domains (workgroups) of tree" },
- { "servers", 'S', POPT_ARG_VAL, &level, LEV_SERVER, "List domains(workgroups) and servers of tree" },
- POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
- POPT_TABLEEND
- };
- poptContext pc;
-
- /* Initialise samba stuff */
-
- setlinebuf(stdout);
-
- dbf = x_stderr;
-
- setup_logging(argv[0],True);
-
- pc = poptGetContext("smbtree", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
- while(poptGetNextOpt(pc) != -1);
- poptFreeContext(pc);
-
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
-
- /* Parse command line args */
-
- if (!cmdline_auth_info.got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(cmdline_auth_info.password, pass);
- }
- cmdline_auth_info.got_pass = True;
- }
-
- /* Now do our stuff */
-
- if (!print_tree(&cmdline_auth_info))
- return 1;
-
- return 0;
-}
diff --git a/source/utils/smbw_sample.c b/source/utils/smbw_sample.c
index 5cd792df7a2..cf94743411d 100644
--- a/source/utils/smbw_sample.c
+++ b/source/utils/smbw_sample.c
@@ -4,22 +4,25 @@
#include <dirent.h>
#include <sys/stat.h>
+extern DIR *smbw_opendir(const char *fname);
+extern struct dirent *smbw_readdir(DIR *dirp);
+
static void usage(void)
{
- printf("
-smbw_sample - a sample program that uses smbw
-
-smbw_sample <options> path
-
- options:
- -W workgroup
- -l logfile
- -P prefix
- -d debuglevel
- -U username%%password
- -R resolve order
-
-note that path must start with /smb/
+ printf("\n \
+smbw_sample - a sample program that uses smbw\n \
+\n \
+smbw_sample <options> path\n \
+\n \
+ options:\n \
+ -W workgroup\n \
+ -l logfile\n \
+ -P prefix\n \
+ -d debuglevel\n \
+ -U username%%password\n \
+ -R resolve order\n \
+\n \
+note that path must start with /smb/\n \
");
}
@@ -33,7 +36,9 @@ int main(int argc, char *argv[])
extern int optind;
char *path;
- lp_load(dyn_CONFIGFILE,1,0,0);
+ charset_initialise();
+ lp_load(CONFIGFILE,1,0,0);
+ codepage_initialise(lp_client_code_page());
smbw_setup_shared();
while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) {
@@ -51,7 +56,7 @@ int main(int argc, char *argv[])
smbw_setshared("DEBUG", optarg);
break;
case 'U':
- p = strchr_m(optarg,'%');
+ p = strchr(optarg,'%');
if (p) {
*p=0;
smbw_setshared("PASSWORD",p+1);
diff --git a/source/utils/status.c b/source/utils/status.c
index 4585b101b28..e04b567ae28 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
status reporting
Copyright (C) Andrew Tridgell 1994-1998
@@ -35,111 +36,107 @@
#include "includes.h"
-#define SMB_MAXPIDS 2048
-static pstring Ucrit_username = ""; /* added by OH */
-static pid_t Ucrit_pid[SMB_MAXPIDS]; /* Ugly !!! */ /* added by OH */
-static int Ucrit_MaxPid=0; /* added by OH */
-static unsigned int Ucrit_IsActive = 0; /* added by OH */
-
+struct session_record{
+ pid_t pid;
+ uid_t uid;
+ char machine[31];
+ time_t start;
+ struct session_record *next;
+} *srecs;
+
+extern FILE *dbf;
+extern BOOL AllowDebugChange;
+
+static pstring Ucrit_username = ""; /* added by OH */
+static pid_t Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */
+static int Ucrit_MaxPid=0; /* added by OH */
+static unsigned int Ucrit_IsActive = 0; /* added by OH */
static int verbose, brief;
static int shares_only = 0; /* Added by RJS */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
static int show_brl;
+/* we need these because we link to locking*.o */
+ void become_root(void) {}
+ void unbecome_root(void) {}
+
+
/* added by OH */
-static void Ucrit_addUsername(const char *username)
+static void Ucrit_addUsername(char *username)
{
pstrcpy(Ucrit_username, username);
-
- if ( strlen(Ucrit_username) > 0 )
+ if(strlen(Ucrit_username) > 0)
Ucrit_IsActive = 1;
}
-static unsigned int Ucrit_checkUsername(const char *username)
+static unsigned int Ucrit_checkUsername(char *username)
{
- if ( !Ucrit_IsActive )
- return 1;
-
- if ( strcmp(Ucrit_username,username) == 0 )
- return 1;
-
+ if ( !Ucrit_IsActive) return 1;
+ if (strcmp(Ucrit_username,username) ==0) return 1;
return 0;
}
-static unsigned int Ucrit_checkPid(pid_t pid)
+static void Ucrit_addPid(pid_t pid)
{
int i;
-
- if ( !Ucrit_IsActive )
- return 1;
-
- for (i=0;i<Ucrit_MaxPid;i++) {
- if( pid == Ucrit_pid[i] )
- return 1;
- }
-
- return 0;
+ if ( !Ucrit_IsActive) return;
+ for (i=0;i<Ucrit_MaxPid;i++)
+ if( pid == Ucrit_pid[i] ) return;
+ Ucrit_pid[Ucrit_MaxPid++] = pid;
}
-static BOOL Ucrit_addPid( pid_t pid )
+static unsigned int Ucrit_checkPid(pid_t pid)
{
- if ( !Ucrit_IsActive )
- return True;
-
- if ( Ucrit_MaxPid >= SMB_MAXPIDS ) {
- d_printf("ERROR: More than %d pids for user %s!\n",
- SMB_MAXPIDS, Ucrit_username);
-
- return False;
- }
-
- Ucrit_pid[Ucrit_MaxPid++] = pid;
-
- return True;
+ int i;
+ if ( !Ucrit_IsActive) return 1;
+ for (i=0;i<Ucrit_MaxPid;i++)
+ if( pid == Ucrit_pid[i] ) return 1;
+ return 0;
}
+
static void print_share_mode(share_mode_entry *e, char *fname)
{
static int count;
if (count==0) {
- d_printf("Locked files:\n");
- d_printf("Pid DenyMode Access R/W Oplock Name\n");
- d_printf("--------------------------------------------------------------\n");
+ printf("Locked files:\n");
+ printf("Pid DenyMode Access R/W Oplock Name\n");
+ printf("--------------------------------------------------------------\n");
}
count++;
if (Ucrit_checkPid(e->pid)) {
- d_printf("%-5d ",(int)e->pid);
+ printf("%-5d ",(int)e->pid);
switch (GET_DENY_MODE(e->share_mode)) {
- case DENY_NONE: d_printf("DENY_NONE "); break;
- case DENY_ALL: d_printf("DENY_ALL "); break;
- case DENY_DOS: d_printf("DENY_DOS "); break;
- case DENY_READ: d_printf("DENY_READ "); break;
+ case DENY_NONE: printf("DENY_NONE "); break;
+ case DENY_ALL: printf("DENY_ALL "); break;
+ case DENY_DOS: printf("DENY_DOS "); break;
+ case DENY_READ: printf("DENY_READ "); break;
case DENY_WRITE:printf("DENY_WRITE "); break;
- case DENY_FCB: d_printf("DENY_FCB "); break;
+ case DENY_FCB: printf("DENY_FCB "); break;
}
- d_printf("0x%-8x ",(unsigned int)e->desired_access);
+ printf("0x%-8x ",(unsigned int)e->desired_access);
switch (e->share_mode&0xF) {
- case 0: d_printf("RDONLY "); break;
- case 1: d_printf("WRONLY "); break;
- case 2: d_printf("RDWR "); break;
+ case 0: printf("RDONLY "); break;
+ case 1: printf("WRONLY "); break;
+ case 2: printf("RDWR "); break;
}
if((e->op_type &
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- d_printf("EXCLUSIVE+BATCH ");
+ printf("EXCLUSIVE+BATCH ");
else if (e->op_type & EXCLUSIVE_OPLOCK)
- d_printf("EXCLUSIVE ");
+ printf("EXCLUSIVE ");
else if (e->op_type & BATCH_OPLOCK)
- d_printf("BATCH ");
+ printf("BATCH ");
else if (e->op_type & LEVEL_II_OPLOCK)
- d_printf("LEVEL_II ");
+ printf("LEVEL_II ");
else
- d_printf("NONE ");
+ printf("NONE ");
- d_printf(" %s %s",fname,
+ printf(" %s %s",dos_to_unix_static(fname),
asctime(LocalTime((time_t *)&e->time.tv_sec)));
}
}
@@ -150,13 +147,13 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
{
static int count;
if (count==0) {
- d_printf("Byte range locks:\n");
- d_printf(" Pid dev:inode R/W start size\n");
- d_printf("------------------------------------------------\n");
+ printf("Byte range locks:\n");
+ printf(" Pid dev:inode R/W start size\n");
+ printf("------------------------------------------------\n");
}
count++;
- d_printf("%6d %05x:%05x %s %9.0f %9.0f\n",
+ printf("%6d %05x:%05x %s %9.0f %9.0f\n",
(int)pid, (int)dev, (int)ino,
lock_type==READ_LOCK?"R":"W",
(double)start, (double)size);
@@ -174,358 +171,354 @@ static int profile_dump(void)
return -1;
}
- d_printf("smb_count: %u\n", profile_p->smb_count);
- d_printf("uid_changes: %u\n", profile_p->uid_changes);
- d_printf("************************ System Calls ****************************\n");
- d_printf("opendir_count: %u\n", profile_p->syscall_opendir_count);
- d_printf("opendir_time: %u\n", profile_p->syscall_opendir_time);
- d_printf("readdir_count: %u\n", profile_p->syscall_readdir_count);
- d_printf("readdir_time: %u\n", profile_p->syscall_readdir_time);
- d_printf("mkdir_count: %u\n", profile_p->syscall_mkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->syscall_mkdir_time);
- d_printf("rmdir_count: %u\n", profile_p->syscall_rmdir_count);
- d_printf("rmdir_time: %u\n", profile_p->syscall_rmdir_time);
- d_printf("closedir_count: %u\n", profile_p->syscall_closedir_count);
- d_printf("closedir_time: %u\n", profile_p->syscall_closedir_time);
- d_printf("open_count: %u\n", profile_p->syscall_open_count);
- d_printf("open_time: %u\n", profile_p->syscall_open_time);
- d_printf("close_count: %u\n", profile_p->syscall_close_count);
- d_printf("close_time: %u\n", profile_p->syscall_close_time);
- d_printf("read_count: %u\n", profile_p->syscall_read_count);
- d_printf("read_time: %u\n", profile_p->syscall_read_time);
- d_printf("read_bytes: %u\n", profile_p->syscall_read_bytes);
- d_printf("write_count: %u\n", profile_p->syscall_write_count);
- d_printf("write_time: %u\n", profile_p->syscall_write_time);
- d_printf("write_bytes: %u\n", profile_p->syscall_write_bytes);
- d_printf("pread_count: %u\n", profile_p->syscall_pread_count);
- d_printf("pread_time: %u\n", profile_p->syscall_pread_time);
- d_printf("pread_bytes: %u\n", profile_p->syscall_pread_bytes);
- d_printf("pwrite_count: %u\n", profile_p->syscall_pwrite_count);
- d_printf("pwrite_time: %u\n", profile_p->syscall_pwrite_time);
- d_printf("pwrite_bytes: %u\n", profile_p->syscall_pwrite_bytes);
+ printf("smb_count: %u\n", profile_p->smb_count);
+ printf("uid_changes: %u\n", profile_p->uid_changes);
+ printf("************************ System Calls ****************************\n");
+ printf("opendir_count: %u\n", profile_p->syscall_opendir_count);
+ printf("opendir_time: %u\n", profile_p->syscall_opendir_time);
+ printf("readdir_count: %u\n", profile_p->syscall_readdir_count);
+ printf("readdir_time: %u\n", profile_p->syscall_readdir_time);
+ printf("mkdir_count: %u\n", profile_p->syscall_mkdir_count);
+ printf("mkdir_time: %u\n", profile_p->syscall_mkdir_time);
+ printf("rmdir_count: %u\n", profile_p->syscall_rmdir_count);
+ printf("rmdir_time: %u\n", profile_p->syscall_rmdir_time);
+ printf("closedir_count: %u\n", profile_p->syscall_closedir_count);
+ printf("closedir_time: %u\n", profile_p->syscall_closedir_time);
+ printf("open_count: %u\n", profile_p->syscall_open_count);
+ printf("open_time: %u\n", profile_p->syscall_open_time);
+ printf("close_count: %u\n", profile_p->syscall_close_count);
+ printf("close_time: %u\n", profile_p->syscall_close_time);
+ printf("read_count: %u\n", profile_p->syscall_read_count);
+ printf("read_time: %u\n", profile_p->syscall_read_time);
+ printf("read_bytes: %u\n", profile_p->syscall_read_bytes);
+ printf("write_count: %u\n", profile_p->syscall_write_count);
+ printf("write_time: %u\n", profile_p->syscall_write_time);
+ printf("write_bytes: %u\n", profile_p->syscall_write_bytes);
#ifdef WITH_SENDFILE
- d_printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count);
- d_printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time);
- d_printf("sendfile_bytes: %u\n", profile_p->syscall_sendfile_bytes);
+ printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count);
+ printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time);
+ printf("sendfile_bytes: %u\n", profile_p->syscall_sendfile_bytes);
#endif
- d_printf("lseek_count: %u\n", profile_p->syscall_lseek_count);
- d_printf("lseek_time: %u\n", profile_p->syscall_lseek_time);
- d_printf("rename_count: %u\n", profile_p->syscall_rename_count);
- d_printf("rename_time: %u\n", profile_p->syscall_rename_time);
- d_printf("fsync_count: %u\n", profile_p->syscall_fsync_count);
- d_printf("fsync_time: %u\n", profile_p->syscall_fsync_time);
- d_printf("stat_count: %u\n", profile_p->syscall_stat_count);
- d_printf("stat_time: %u\n", profile_p->syscall_stat_time);
- d_printf("fstat_count: %u\n", profile_p->syscall_fstat_count);
- d_printf("fstat_time: %u\n", profile_p->syscall_fstat_time);
- d_printf("lstat_count: %u\n", profile_p->syscall_lstat_count);
- d_printf("lstat_time: %u\n", profile_p->syscall_lstat_time);
- d_printf("unlink_count: %u\n", profile_p->syscall_unlink_count);
- d_printf("unlink_time: %u\n", profile_p->syscall_unlink_time);
- d_printf("chmod_count: %u\n", profile_p->syscall_chmod_count);
- d_printf("chmod_time: %u\n", profile_p->syscall_chmod_time);
- d_printf("fchmod_count: %u\n", profile_p->syscall_fchmod_count);
- d_printf("fchmod_time: %u\n", profile_p->syscall_fchmod_time);
- d_printf("chown_count: %u\n", profile_p->syscall_chown_count);
- d_printf("chown_time: %u\n", profile_p->syscall_chown_time);
- d_printf("fchown_count: %u\n", profile_p->syscall_fchown_count);
- d_printf("fchown_time: %u\n", profile_p->syscall_fchown_time);
- d_printf("chdir_count: %u\n", profile_p->syscall_chdir_count);
- d_printf("chdir_time: %u\n", profile_p->syscall_chdir_time);
- d_printf("getwd_count: %u\n", profile_p->syscall_getwd_count);
- d_printf("getwd_time: %u\n", profile_p->syscall_getwd_time);
- d_printf("utime_count: %u\n", profile_p->syscall_utime_count);
- d_printf("utime_time: %u\n", profile_p->syscall_utime_time);
- d_printf("ftruncate_count: %u\n", profile_p->syscall_ftruncate_count);
- d_printf("ftruncate_time: %u\n", profile_p->syscall_ftruncate_time);
- d_printf("fcntl_lock_count: %u\n", profile_p->syscall_fcntl_lock_count);
- d_printf("fcntl_lock_time: %u\n", profile_p->syscall_fcntl_lock_time);
- d_printf("readlink_count: %u\n", profile_p->syscall_readlink_count);
- d_printf("readlink_time: %u\n", profile_p->syscall_readlink_time);
- d_printf("symlink_count: %u\n", profile_p->syscall_symlink_count);
- d_printf("symlink_time: %u\n", profile_p->syscall_symlink_time);
- d_printf("************************ Statcache *******************************\n");
- d_printf("lookups: %u\n", profile_p->statcache_lookups);
- d_printf("misses: %u\n", profile_p->statcache_misses);
- d_printf("hits: %u\n", profile_p->statcache_hits);
- d_printf("************************ Writecache ******************************\n");
- d_printf("read_hits: %u\n", profile_p->writecache_read_hits);
- d_printf("abutted_writes: %u\n", profile_p->writecache_abutted_writes);
- d_printf("total_writes: %u\n", profile_p->writecache_total_writes);
- d_printf("non_oplock_writes: %u\n", profile_p->writecache_non_oplock_writes);
- d_printf("direct_writes: %u\n", profile_p->writecache_direct_writes);
- d_printf("init_writes: %u\n", profile_p->writecache_init_writes);
- d_printf("flushed_writes[SEEK]: %u\n", profile_p->writecache_flushed_writes[SEEK_FLUSH]);
- d_printf("flushed_writes[READ]: %u\n", profile_p->writecache_flushed_writes[READ_FLUSH]);
- d_printf("flushed_writes[WRITE]: %u\n", profile_p->writecache_flushed_writes[WRITE_FLUSH]);
- d_printf("flushed_writes[READRAW]: %u\n", profile_p->writecache_flushed_writes[READRAW_FLUSH]);
- d_printf("flushed_writes[OPLOCK_RELEASE]: %u\n", profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH]);
- d_printf("flushed_writes[CLOSE]: %u\n", profile_p->writecache_flushed_writes[CLOSE_FLUSH]);
- d_printf("flushed_writes[SYNC]: %u\n", profile_p->writecache_flushed_writes[SYNC_FLUSH]);
- d_printf("flushed_writes[SIZECHANGE]: %u\n", profile_p->writecache_flushed_writes[SIZECHANGE_FLUSH]);
- d_printf("num_perfect_writes: %u\n", profile_p->writecache_num_perfect_writes);
- d_printf("num_write_caches: %u\n", profile_p->writecache_num_write_caches);
- d_printf("allocated_write_caches: %u\n", profile_p->writecache_allocated_write_caches);
- d_printf("************************ SMB Calls *******************************\n");
- d_printf("mkdir_count: %u\n", profile_p->SMBmkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->SMBmkdir_time);
- d_printf("rmdir_count: %u\n", profile_p->SMBrmdir_count);
- d_printf("rmdir_time: %u\n", profile_p->SMBrmdir_time);
- d_printf("open_count: %u\n", profile_p->SMBopen_count);
- d_printf("open_time: %u\n", profile_p->SMBopen_time);
- d_printf("create_count: %u\n", profile_p->SMBcreate_count);
- d_printf("create_time: %u\n", profile_p->SMBcreate_time);
- d_printf("close_count: %u\n", profile_p->SMBclose_count);
- d_printf("close_time: %u\n", profile_p->SMBclose_time);
- d_printf("flush_count: %u\n", profile_p->SMBflush_count);
- d_printf("flush_time: %u\n", profile_p->SMBflush_time);
- d_printf("unlink_count: %u\n", profile_p->SMBunlink_count);
- d_printf("unlink_time: %u\n", profile_p->SMBunlink_time);
- d_printf("mv_count: %u\n", profile_p->SMBmv_count);
- d_printf("mv_time: %u\n", profile_p->SMBmv_time);
- d_printf("getatr_count: %u\n", profile_p->SMBgetatr_count);
- d_printf("getatr_time: %u\n", profile_p->SMBgetatr_time);
- d_printf("setatr_count: %u\n", profile_p->SMBsetatr_count);
- d_printf("setatr_time: %u\n", profile_p->SMBsetatr_time);
- d_printf("read_count: %u\n", profile_p->SMBread_count);
- d_printf("read_time: %u\n", profile_p->SMBread_time);
- d_printf("write_count: %u\n", profile_p->SMBwrite_count);
- d_printf("write_time: %u\n", profile_p->SMBwrite_time);
- d_printf("lock_count: %u\n", profile_p->SMBlock_count);
- d_printf("lock_time: %u\n", profile_p->SMBlock_time);
- d_printf("unlock_count: %u\n", profile_p->SMBunlock_count);
- d_printf("unlock_time: %u\n", profile_p->SMBunlock_time);
- d_printf("ctemp_count: %u\n", profile_p->SMBctemp_count);
- d_printf("ctemp_time: %u\n", profile_p->SMBctemp_time);
- d_printf("mknew_count: %u\n", profile_p->SMBmknew_count);
- d_printf("mknew_time: %u\n", profile_p->SMBmknew_time);
- d_printf("chkpth_count: %u\n", profile_p->SMBchkpth_count);
- d_printf("chkpth_time: %u\n", profile_p->SMBchkpth_time);
- d_printf("exit_count: %u\n", profile_p->SMBexit_count);
- d_printf("exit_time: %u\n", profile_p->SMBexit_time);
- d_printf("lseek_count: %u\n", profile_p->SMBlseek_count);
- d_printf("lseek_time: %u\n", profile_p->SMBlseek_time);
- d_printf("lockread_count: %u\n", profile_p->SMBlockread_count);
- d_printf("lockread_time: %u\n", profile_p->SMBlockread_time);
- d_printf("writeunlock_count: %u\n", profile_p->SMBwriteunlock_count);
- d_printf("writeunlock_time: %u\n", profile_p->SMBwriteunlock_time);
- d_printf("readbraw_count: %u\n", profile_p->SMBreadbraw_count);
- d_printf("readbraw_time: %u\n", profile_p->SMBreadbraw_time);
- d_printf("readBmpx_count: %u\n", profile_p->SMBreadBmpx_count);
- d_printf("readBmpx_time: %u\n", profile_p->SMBreadBmpx_time);
- d_printf("readBs_count: %u\n", profile_p->SMBreadBs_count);
- d_printf("readBs_time: %u\n", profile_p->SMBreadBs_time);
- d_printf("writebraw_count: %u\n", profile_p->SMBwritebraw_count);
- d_printf("writebraw_time: %u\n", profile_p->SMBwritebraw_time);
- d_printf("writeBmpx_count: %u\n", profile_p->SMBwriteBmpx_count);
- d_printf("writeBmpx_time: %u\n", profile_p->SMBwriteBmpx_time);
- d_printf("writeBs_count: %u\n", profile_p->SMBwriteBs_count);
- d_printf("writeBs_time: %u\n", profile_p->SMBwriteBs_time);
- d_printf("writec_count: %u\n", profile_p->SMBwritec_count);
- d_printf("writec_time: %u\n", profile_p->SMBwritec_time);
- d_printf("setattrE_count: %u\n", profile_p->SMBsetattrE_count);
- d_printf("setattrE_time: %u\n", profile_p->SMBsetattrE_time);
- d_printf("getattrE_count: %u\n", profile_p->SMBgetattrE_count);
- d_printf("getattrE_time: %u\n", profile_p->SMBgetattrE_time);
- d_printf("lockingX_count: %u\n", profile_p->SMBlockingX_count);
- d_printf("lockingX_time: %u\n", profile_p->SMBlockingX_time);
- d_printf("trans_count: %u\n", profile_p->SMBtrans_count);
- d_printf("trans_time: %u\n", profile_p->SMBtrans_time);
- d_printf("transs_count: %u\n", profile_p->SMBtranss_count);
- d_printf("transs_time: %u\n", profile_p->SMBtranss_time);
- d_printf("ioctl_count: %u\n", profile_p->SMBioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->SMBioctl_time);
- d_printf("ioctls_count: %u\n", profile_p->SMBioctls_count);
- d_printf("ioctls_time: %u\n", profile_p->SMBioctls_time);
- d_printf("copy_count: %u\n", profile_p->SMBcopy_count);
- d_printf("copy_time: %u\n", profile_p->SMBcopy_time);
- d_printf("move_count: %u\n", profile_p->SMBmove_count);
- d_printf("move_time: %u\n", profile_p->SMBmove_time);
- d_printf("echo_count: %u\n", profile_p->SMBecho_count);
- d_printf("echo_time: %u\n", profile_p->SMBecho_time);
- d_printf("writeclose_count: %u\n", profile_p->SMBwriteclose_count);
- d_printf("writeclose_time: %u\n", profile_p->SMBwriteclose_time);
- d_printf("openX_count: %u\n", profile_p->SMBopenX_count);
- d_printf("openX_time: %u\n", profile_p->SMBopenX_time);
- d_printf("readX_count: %u\n", profile_p->SMBreadX_count);
- d_printf("readX_time: %u\n", profile_p->SMBreadX_time);
- d_printf("writeX_count: %u\n", profile_p->SMBwriteX_count);
- d_printf("writeX_time: %u\n", profile_p->SMBwriteX_time);
- d_printf("trans2_count: %u\n", profile_p->SMBtrans2_count);
- d_printf("trans2_time: %u\n", profile_p->SMBtrans2_time);
- d_printf("transs2_count: %u\n", profile_p->SMBtranss2_count);
- d_printf("transs2_time: %u\n", profile_p->SMBtranss2_time);
- d_printf("findclose_count: %u\n", profile_p->SMBfindclose_count);
- d_printf("findclose_time: %u\n", profile_p->SMBfindclose_time);
- d_printf("findnclose_count: %u\n", profile_p->SMBfindnclose_count);
- d_printf("findnclose_time: %u\n", profile_p->SMBfindnclose_time);
- d_printf("tcon_count: %u\n", profile_p->SMBtcon_count);
- d_printf("tcon_time: %u\n", profile_p->SMBtcon_time);
- d_printf("tdis_count: %u\n", profile_p->SMBtdis_count);
- d_printf("tdis_time: %u\n", profile_p->SMBtdis_time);
- d_printf("negprot_count: %u\n", profile_p->SMBnegprot_count);
- d_printf("negprot_time: %u\n", profile_p->SMBnegprot_time);
- d_printf("sesssetupX_count: %u\n", profile_p->SMBsesssetupX_count);
- d_printf("sesssetupX_time: %u\n", profile_p->SMBsesssetupX_time);
- d_printf("ulogoffX_count: %u\n", profile_p->SMBulogoffX_count);
- d_printf("ulogoffX_time: %u\n", profile_p->SMBulogoffX_time);
- d_printf("tconX_count: %u\n", profile_p->SMBtconX_count);
- d_printf("tconX_time: %u\n", profile_p->SMBtconX_time);
- d_printf("dskattr_count: %u\n", profile_p->SMBdskattr_count);
- d_printf("dskattr_time: %u\n", profile_p->SMBdskattr_time);
- d_printf("search_count: %u\n", profile_p->SMBsearch_count);
- d_printf("search_time: %u\n", profile_p->SMBsearch_time);
- d_printf("ffirst_count: %u\n", profile_p->SMBffirst_count);
- d_printf("ffirst_time: %u\n", profile_p->SMBffirst_time);
- d_printf("funique_count: %u\n", profile_p->SMBfunique_count);
- d_printf("funique_time: %u\n", profile_p->SMBfunique_time);
- d_printf("fclose_count: %u\n", profile_p->SMBfclose_count);
- d_printf("fclose_time: %u\n", profile_p->SMBfclose_time);
- d_printf("nttrans_count: %u\n", profile_p->SMBnttrans_count);
- d_printf("nttrans_time: %u\n", profile_p->SMBnttrans_time);
- d_printf("nttranss_count: %u\n", profile_p->SMBnttranss_count);
- d_printf("nttranss_time: %u\n", profile_p->SMBnttranss_time);
- d_printf("ntcreateX_count: %u\n", profile_p->SMBntcreateX_count);
- d_printf("ntcreateX_time: %u\n", profile_p->SMBntcreateX_time);
- d_printf("ntcancel_count: %u\n", profile_p->SMBntcancel_count);
- d_printf("ntcancel_time: %u\n", profile_p->SMBntcancel_time);
- d_printf("splopen_count: %u\n", profile_p->SMBsplopen_count);
- d_printf("splopen_time: %u\n", profile_p->SMBsplopen_time);
- d_printf("splwr_count: %u\n", profile_p->SMBsplwr_count);
- d_printf("splwr_time: %u\n", profile_p->SMBsplwr_time);
- d_printf("splclose_count: %u\n", profile_p->SMBsplclose_count);
- d_printf("splclose_time: %u\n", profile_p->SMBsplclose_time);
- d_printf("splretq_count: %u\n", profile_p->SMBsplretq_count);
- d_printf("splretq_time: %u\n", profile_p->SMBsplretq_time);
- d_printf("sends_count: %u\n", profile_p->SMBsends_count);
- d_printf("sends_time: %u\n", profile_p->SMBsends_time);
- d_printf("sendb_count: %u\n", profile_p->SMBsendb_count);
- d_printf("sendb_time: %u\n", profile_p->SMBsendb_time);
- d_printf("fwdname_count: %u\n", profile_p->SMBfwdname_count);
- d_printf("fwdname_time: %u\n", profile_p->SMBfwdname_time);
- d_printf("cancelf_count: %u\n", profile_p->SMBcancelf_count);
- d_printf("cancelf_time: %u\n", profile_p->SMBcancelf_time);
- d_printf("getmac_count: %u\n", profile_p->SMBgetmac_count);
- d_printf("getmac_time: %u\n", profile_p->SMBgetmac_time);
- d_printf("sendstrt_count: %u\n", profile_p->SMBsendstrt_count);
- d_printf("sendstrt_time: %u\n", profile_p->SMBsendstrt_time);
- d_printf("sendend_count: %u\n", profile_p->SMBsendend_count);
- d_printf("sendend_time: %u\n", profile_p->SMBsendend_time);
- d_printf("sendtxt_count: %u\n", profile_p->SMBsendtxt_count);
- d_printf("sendtxt_time: %u\n", profile_p->SMBsendtxt_time);
- d_printf("invalid_count: %u\n", profile_p->SMBinvalid_count);
- d_printf("invalid_time: %u\n", profile_p->SMBinvalid_time);
- d_printf("************************ Pathworks Calls *************************\n");
- d_printf("setdir_count: %u\n", profile_p->pathworks_setdir_count);
- d_printf("setdir_time: %u\n", profile_p->pathworks_setdir_time);
- d_printf("************************ Trans2 Calls ****************************\n");
- d_printf("open_count: %u\n", profile_p->Trans2_open_count);
- d_printf("open_time: %u\n", profile_p->Trans2_open_time);
- d_printf("findfirst_count: %u\n", profile_p->Trans2_findfirst_count);
- d_printf("findfirst_time: %u\n", profile_p->Trans2_findfirst_time);
- d_printf("findnext_count: %u\n", profile_p->Trans2_findnext_count);
- d_printf("findnext_time: %u\n", profile_p->Trans2_findnext_time);
- d_printf("qfsinfo_count: %u\n", profile_p->Trans2_qfsinfo_count);
- d_printf("qfsinfo_time: %u\n", profile_p->Trans2_qfsinfo_time);
- d_printf("setfsinfo_count: %u\n", profile_p->Trans2_setfsinfo_count);
- d_printf("setfsinfo_time: %u\n", profile_p->Trans2_setfsinfo_time);
- d_printf("qpathinfo_count: %u\n", profile_p->Trans2_qpathinfo_count);
- d_printf("qpathinfo_time: %u\n", profile_p->Trans2_qpathinfo_time);
- d_printf("setpathinfo_count: %u\n", profile_p->Trans2_setpathinfo_count);
- d_printf("setpathinfo_time: %u\n", profile_p->Trans2_setpathinfo_time);
- d_printf("qfileinfo_count: %u\n", profile_p->Trans2_qfileinfo_count);
- d_printf("qfileinfo_time: %u\n", profile_p->Trans2_qfileinfo_time);
- d_printf("setfileinfo_count: %u\n", profile_p->Trans2_setfileinfo_count);
- d_printf("setfileinfo_time: %u\n", profile_p->Trans2_setfileinfo_time);
- d_printf("fsctl_count: %u\n", profile_p->Trans2_fsctl_count);
- d_printf("fsctl_time: %u\n", profile_p->Trans2_fsctl_time);
- d_printf("ioctl_count: %u\n", profile_p->Trans2_ioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->Trans2_ioctl_time);
- d_printf("findnotifyfirst_count: %u\n", profile_p->Trans2_findnotifyfirst_count);
- d_printf("findnotifyfirst_time: %u\n", profile_p->Trans2_findnotifyfirst_time);
- d_printf("findnotifynext_count: %u\n", profile_p->Trans2_findnotifynext_count);
- d_printf("findnotifynext_time: %u\n", profile_p->Trans2_findnotifynext_time);
- d_printf("mkdir_count: %u\n", profile_p->Trans2_mkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->Trans2_mkdir_time);
- d_printf("session_setup_count: %u\n", profile_p->Trans2_session_setup_count);
- d_printf("session_setup_time: %u\n", profile_p->Trans2_session_setup_time);
- d_printf("get_dfs_referral_count: %u\n", profile_p->Trans2_get_dfs_referral_count);
- d_printf("get_dfs_referral_time: %u\n", profile_p->Trans2_get_dfs_referral_time);
- d_printf("report_dfs_inconsistancy_count: %u\n", profile_p->Trans2_report_dfs_inconsistancy_count);
- d_printf("report_dfs_inconsistancy_time: %u\n", profile_p->Trans2_report_dfs_inconsistancy_time);
- d_printf("************************ NT Transact Calls ***********************\n");
- d_printf("create_count: %u\n", profile_p->NT_transact_create_count);
- d_printf("create_time: %u\n", profile_p->NT_transact_create_time);
- d_printf("ioctl_count: %u\n", profile_p->NT_transact_ioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->NT_transact_ioctl_time);
- d_printf("set_security_desc_count: %u\n", profile_p->NT_transact_set_security_desc_count);
- d_printf("set_security_desc_time: %u\n", profile_p->NT_transact_set_security_desc_time);
- d_printf("notify_change_count: %u\n", profile_p->NT_transact_notify_change_count);
- d_printf("notify_change_time: %u\n", profile_p->NT_transact_notify_change_time);
- d_printf("rename_count: %u\n", profile_p->NT_transact_rename_count);
- d_printf("rename_time: %u\n", profile_p->NT_transact_rename_time);
- d_printf("query_security_desc_count: %u\n", profile_p->NT_transact_query_security_desc_count);
- d_printf("query_security_desc_time: %u\n", profile_p->NT_transact_query_security_desc_time);
- d_printf("************************ ACL Calls *******************************\n");
- d_printf("get_nt_acl_count: %u\n", profile_p->get_nt_acl_count);
- d_printf("get_nt_acl_time: %u\n", profile_p->get_nt_acl_time);
- d_printf("fget_nt_acl_count: %u\n", profile_p->fget_nt_acl_count);
- d_printf("fget_nt_acl_time: %u\n", profile_p->fget_nt_acl_time);
- d_printf("set_nt_acl_count: %u\n", profile_p->set_nt_acl_count);
- d_printf("set_nt_acl_time: %u\n", profile_p->set_nt_acl_time);
- d_printf("fset_nt_acl_count: %u\n", profile_p->fset_nt_acl_count);
- d_printf("fset_nt_acl_time: %u\n", profile_p->fset_nt_acl_time);
- d_printf("chmod_acl_count: %u\n", profile_p->chmod_acl_count);
- d_printf("chmod_acl_time: %u\n", profile_p->chmod_acl_time);
- d_printf("fchmod_acl_count: %u\n", profile_p->fchmod_acl_count);
- d_printf("fchmod_acl_time: %u\n", profile_p->fchmod_acl_time);
- d_printf("************************ NMBD Calls ****************************\n");
- d_printf("name_release_count: %u\n", profile_p->name_release_count);
- d_printf("name_release_time: %u\n", profile_p->name_release_time);
- d_printf("name_refresh_count: %u\n", profile_p->name_refresh_count);
- d_printf("name_refresh_time: %u\n", profile_p->name_refresh_time);
- d_printf("name_registration_count: %u\n", profile_p->name_registration_count);
- d_printf("name_registration_time: %u\n", profile_p->name_registration_time);
- d_printf("node_status_count: %u\n", profile_p->node_status_count);
- d_printf("node_status_time: %u\n", profile_p->node_status_time);
- d_printf("name_query_count: %u\n", profile_p->name_query_count);
- d_printf("name_query_time: %u\n", profile_p->name_query_time);
- d_printf("host_announce_count: %u\n", profile_p->host_announce_count);
- d_printf("host_announce_time: %u\n", profile_p->host_announce_time);
- d_printf("workgroup_announce_count: %u\n", profile_p->workgroup_announce_count);
- d_printf("workgroup_announce_time: %u\n", profile_p->workgroup_announce_time);
- d_printf("local_master_announce_count: %u\n", profile_p->local_master_announce_count);
- d_printf("local_master_announce_time: %u\n", profile_p->local_master_announce_time);
- d_printf("master_browser_announce_count: %u\n", profile_p->master_browser_announce_count);
- d_printf("master_browser_announce_time: %u\n", profile_p->master_browser_announce_time);
- d_printf("lm_host_announce_count: %u\n", profile_p->lm_host_announce_count);
- d_printf("lm_host_announce_time: %u\n", profile_p->lm_host_announce_time);
- d_printf("get_backup_list_count: %u\n", profile_p->get_backup_list_count);
- d_printf("get_backup_list_time: %u\n", profile_p->get_backup_list_time);
- d_printf("reset_browser_count: %u\n", profile_p->reset_browser_count);
- d_printf("reset_browser_time: %u\n", profile_p->reset_browser_time);
- d_printf("announce_request_count: %u\n", profile_p->announce_request_count);
- d_printf("announce_request_time: %u\n", profile_p->announce_request_time);
- d_printf("lm_announce_request_count: %u\n", profile_p->lm_announce_request_count);
- d_printf("lm_announce_request_time: %u\n", profile_p->lm_announce_request_time);
- d_printf("domain_logon_count: %u\n", profile_p->domain_logon_count);
- d_printf("domain_logon_time: %u\n", profile_p->domain_logon_time);
- d_printf("sync_browse_lists_count: %u\n", profile_p->sync_browse_lists_count);
- d_printf("sync_browse_lists_time: %u\n", profile_p->sync_browse_lists_time);
- d_printf("run_elections_count: %u\n", profile_p->run_elections_count);
- d_printf("run_elections_time: %u\n", profile_p->run_elections_time);
- d_printf("election_count: %u\n", profile_p->election_count);
- d_printf("election_time: %u\n", profile_p->election_time);
-#else /* WITH_PROFILE */
- fprintf(stderr, "Profile data unavailable\n");
+ printf("lseek_count: %u\n", profile_p->syscall_lseek_count);
+ printf("lseek_time: %u\n", profile_p->syscall_lseek_time);
+ printf("rename_count: %u\n", profile_p->syscall_rename_count);
+ printf("rename_time: %u\n", profile_p->syscall_rename_time);
+ printf("fsync_count: %u\n", profile_p->syscall_fsync_count);
+ printf("fsync_time: %u\n", profile_p->syscall_fsync_time);
+ printf("stat_count: %u\n", profile_p->syscall_stat_count);
+ printf("stat_time: %u\n", profile_p->syscall_stat_time);
+ printf("fstat_count: %u\n", profile_p->syscall_fstat_count);
+ printf("fstat_time: %u\n", profile_p->syscall_fstat_time);
+ printf("lstat_count: %u\n", profile_p->syscall_lstat_count);
+ printf("lstat_time: %u\n", profile_p->syscall_lstat_time);
+ printf("unlink_count: %u\n", profile_p->syscall_unlink_count);
+ printf("unlink_time: %u\n", profile_p->syscall_unlink_time);
+ printf("chmod_count: %u\n", profile_p->syscall_chmod_count);
+ printf("chmod_time: %u\n", profile_p->syscall_chmod_time);
+ printf("fchmod_count: %u\n", profile_p->syscall_fchmod_count);
+ printf("fchmod_time: %u\n", profile_p->syscall_fchmod_time);
+ printf("chown_count: %u\n", profile_p->syscall_chown_count);
+ printf("chown_time: %u\n", profile_p->syscall_chown_time);
+ printf("fchown_count: %u\n", profile_p->syscall_fchown_count);
+ printf("fchown_time: %u\n", profile_p->syscall_fchown_time);
+ printf("chdir_count: %u\n", profile_p->syscall_chdir_count);
+ printf("chdir_time: %u\n", profile_p->syscall_chdir_time);
+ printf("getwd_count: %u\n", profile_p->syscall_getwd_count);
+ printf("getwd_time: %u\n", profile_p->syscall_getwd_time);
+ printf("utime_count: %u\n", profile_p->syscall_utime_count);
+ printf("utime_time: %u\n", profile_p->syscall_utime_time);
+ printf("ftruncate_count: %u\n", profile_p->syscall_ftruncate_count);
+ printf("ftruncate_time: %u\n", profile_p->syscall_ftruncate_time);
+ printf("fcntl_lock_count: %u\n", profile_p->syscall_fcntl_lock_count);
+ printf("fcntl_lock_time: %u\n", profile_p->syscall_fcntl_lock_time);
+ printf("readlink_count: %u\n", profile_p->syscall_readlink_count);
+ printf("readlink_time: %u\n", profile_p->syscall_readlink_time);
+ printf("symlink_count: %u\n", profile_p->syscall_symlink_count);
+ printf("symlink_time: %u\n", profile_p->syscall_symlink_time);
+ printf("************************ Statcache *******************************\n");
+ printf("lookups: %u\n", profile_p->statcache_lookups);
+ printf("misses: %u\n", profile_p->statcache_misses);
+ printf("hits: %u\n", profile_p->statcache_hits);
+ printf("************************ Writecache ******************************\n");
+ printf("read_hits: %u\n", profile_p->writecache_read_hits);
+ printf("abutted_writes: %u\n", profile_p->writecache_abutted_writes);
+ printf("total_writes: %u\n", profile_p->writecache_total_writes);
+ printf("non_oplock_writes: %u\n", profile_p->writecache_non_oplock_writes);
+ printf("direct_writes: %u\n", profile_p->writecache_direct_writes);
+ printf("init_writes: %u\n", profile_p->writecache_init_writes);
+ printf("flushed_writes[SEEK]: %u\n", profile_p->writecache_flushed_writes[SEEK_FLUSH]);
+ printf("flushed_writes[READ]: %u\n", profile_p->writecache_flushed_writes[READ_FLUSH]);
+ printf("flushed_writes[WRITE]: %u\n", profile_p->writecache_flushed_writes[WRITE_FLUSH]);
+ printf("flushed_writes[READRAW]: %u\n", profile_p->writecache_flushed_writes[READRAW_FLUSH]);
+ printf("flushed_writes[OPLOCK_RELEASE]: %u\n", profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH]);
+ printf("flushed_writes[CLOSE]: %u\n", profile_p->writecache_flushed_writes[CLOSE_FLUSH]);
+ printf("flushed_writes[SYNC]: %u\n", profile_p->writecache_flushed_writes[SYNC_FLUSH]);
+ printf("flushed_writes[SIZECHANGE]: %u\n", profile_p->writecache_flushed_writes[SIZECHANGE_FLUSH]);
+ printf("num_perfect_writes: %u\n", profile_p->writecache_num_perfect_writes);
+ printf("num_write_caches: %u\n", profile_p->writecache_num_write_caches);
+ printf("allocated_write_caches: %u\n", profile_p->writecache_allocated_write_caches);
+ printf("************************ SMB Calls *******************************\n");
+ printf("mkdir_count: %u\n", profile_p->SMBmkdir_count);
+ printf("mkdir_time: %u\n", profile_p->SMBmkdir_time);
+ printf("rmdir_count: %u\n", profile_p->SMBrmdir_count);
+ printf("rmdir_time: %u\n", profile_p->SMBrmdir_time);
+ printf("open_count: %u\n", profile_p->SMBopen_count);
+ printf("open_time: %u\n", profile_p->SMBopen_time);
+ printf("create_count: %u\n", profile_p->SMBcreate_count);
+ printf("create_time: %u\n", profile_p->SMBcreate_time);
+ printf("close_count: %u\n", profile_p->SMBclose_count);
+ printf("close_time: %u\n", profile_p->SMBclose_time);
+ printf("flush_count: %u\n", profile_p->SMBflush_count);
+ printf("flush_time: %u\n", profile_p->SMBflush_time);
+ printf("unlink_count: %u\n", profile_p->SMBunlink_count);
+ printf("unlink_time: %u\n", profile_p->SMBunlink_time);
+ printf("mv_count: %u\n", profile_p->SMBmv_count);
+ printf("mv_time: %u\n", profile_p->SMBmv_time);
+ printf("getatr_count: %u\n", profile_p->SMBgetatr_count);
+ printf("getatr_time: %u\n", profile_p->SMBgetatr_time);
+ printf("setatr_count: %u\n", profile_p->SMBsetatr_count);
+ printf("setatr_time: %u\n", profile_p->SMBsetatr_time);
+ printf("read_count: %u\n", profile_p->SMBread_count);
+ printf("read_time: %u\n", profile_p->SMBread_time);
+ printf("write_count: %u\n", profile_p->SMBwrite_count);
+ printf("write_time: %u\n", profile_p->SMBwrite_time);
+ printf("lock_count: %u\n", profile_p->SMBlock_count);
+ printf("lock_time: %u\n", profile_p->SMBlock_time);
+ printf("unlock_count: %u\n", profile_p->SMBunlock_count);
+ printf("unlock_time: %u\n", profile_p->SMBunlock_time);
+ printf("ctemp_count: %u\n", profile_p->SMBctemp_count);
+ printf("ctemp_time: %u\n", profile_p->SMBctemp_time);
+ printf("mknew_count: %u\n", profile_p->SMBmknew_count);
+ printf("mknew_time: %u\n", profile_p->SMBmknew_time);
+ printf("chkpth_count: %u\n", profile_p->SMBchkpth_count);
+ printf("chkpth_time: %u\n", profile_p->SMBchkpth_time);
+ printf("exit_count: %u\n", profile_p->SMBexit_count);
+ printf("exit_time: %u\n", profile_p->SMBexit_time);
+ printf("lseek_count: %u\n", profile_p->SMBlseek_count);
+ printf("lseek_time: %u\n", profile_p->SMBlseek_time);
+ printf("lockread_count: %u\n", profile_p->SMBlockread_count);
+ printf("lockread_time: %u\n", profile_p->SMBlockread_time);
+ printf("writeunlock_count: %u\n", profile_p->SMBwriteunlock_count);
+ printf("writeunlock_time: %u\n", profile_p->SMBwriteunlock_time);
+ printf("readbraw_count: %u\n", profile_p->SMBreadbraw_count);
+ printf("readbraw_time: %u\n", profile_p->SMBreadbraw_time);
+ printf("readBmpx_count: %u\n", profile_p->SMBreadBmpx_count);
+ printf("readBmpx_time: %u\n", profile_p->SMBreadBmpx_time);
+ printf("readBs_count: %u\n", profile_p->SMBreadBs_count);
+ printf("readBs_time: %u\n", profile_p->SMBreadBs_time);
+ printf("writebraw_count: %u\n", profile_p->SMBwritebraw_count);
+ printf("writebraw_time: %u\n", profile_p->SMBwritebraw_time);
+ printf("writeBmpx_count: %u\n", profile_p->SMBwriteBmpx_count);
+ printf("writeBmpx_time: %u\n", profile_p->SMBwriteBmpx_time);
+ printf("writeBs_count: %u\n", profile_p->SMBwriteBs_count);
+ printf("writeBs_time: %u\n", profile_p->SMBwriteBs_time);
+ printf("writec_count: %u\n", profile_p->SMBwritec_count);
+ printf("writec_time: %u\n", profile_p->SMBwritec_time);
+ printf("setattrE_count: %u\n", profile_p->SMBsetattrE_count);
+ printf("setattrE_time: %u\n", profile_p->SMBsetattrE_time);
+ printf("getattrE_count: %u\n", profile_p->SMBgetattrE_count);
+ printf("getattrE_time: %u\n", profile_p->SMBgetattrE_time);
+ printf("lockingX_count: %u\n", profile_p->SMBlockingX_count);
+ printf("lockingX_time: %u\n", profile_p->SMBlockingX_time);
+ printf("trans_count: %u\n", profile_p->SMBtrans_count);
+ printf("trans_time: %u\n", profile_p->SMBtrans_time);
+ printf("transs_count: %u\n", profile_p->SMBtranss_count);
+ printf("transs_time: %u\n", profile_p->SMBtranss_time);
+ printf("ioctl_count: %u\n", profile_p->SMBioctl_count);
+ printf("ioctl_time: %u\n", profile_p->SMBioctl_time);
+ printf("ioctls_count: %u\n", profile_p->SMBioctls_count);
+ printf("ioctls_time: %u\n", profile_p->SMBioctls_time);
+ printf("copy_count: %u\n", profile_p->SMBcopy_count);
+ printf("copy_time: %u\n", profile_p->SMBcopy_time);
+ printf("move_count: %u\n", profile_p->SMBmove_count);
+ printf("move_time: %u\n", profile_p->SMBmove_time);
+ printf("echo_count: %u\n", profile_p->SMBecho_count);
+ printf("echo_time: %u\n", profile_p->SMBecho_time);
+ printf("writeclose_count: %u\n", profile_p->SMBwriteclose_count);
+ printf("writeclose_time: %u\n", profile_p->SMBwriteclose_time);
+ printf("openX_count: %u\n", profile_p->SMBopenX_count);
+ printf("openX_time: %u\n", profile_p->SMBopenX_time);
+ printf("readX_count: %u\n", profile_p->SMBreadX_count);
+ printf("readX_time: %u\n", profile_p->SMBreadX_time);
+ printf("writeX_count: %u\n", profile_p->SMBwriteX_count);
+ printf("writeX_time: %u\n", profile_p->SMBwriteX_time);
+ printf("trans2_count: %u\n", profile_p->SMBtrans2_count);
+ printf("trans2_time: %u\n", profile_p->SMBtrans2_time);
+ printf("transs2_count: %u\n", profile_p->SMBtranss2_count);
+ printf("transs2_time: %u\n", profile_p->SMBtranss2_time);
+ printf("findclose_count: %u\n", profile_p->SMBfindclose_count);
+ printf("findclose_time: %u\n", profile_p->SMBfindclose_time);
+ printf("findnclose_count: %u\n", profile_p->SMBfindnclose_count);
+ printf("findnclose_time: %u\n", profile_p->SMBfindnclose_time);
+ printf("tcon_count: %u\n", profile_p->SMBtcon_count);
+ printf("tcon_time: %u\n", profile_p->SMBtcon_time);
+ printf("tdis_count: %u\n", profile_p->SMBtdis_count);
+ printf("tdis_time: %u\n", profile_p->SMBtdis_time);
+ printf("negprot_count: %u\n", profile_p->SMBnegprot_count);
+ printf("negprot_time: %u\n", profile_p->SMBnegprot_time);
+ printf("sesssetupX_count: %u\n", profile_p->SMBsesssetupX_count);
+ printf("sesssetupX_time: %u\n", profile_p->SMBsesssetupX_time);
+ printf("ulogoffX_count: %u\n", profile_p->SMBulogoffX_count);
+ printf("ulogoffX_time: %u\n", profile_p->SMBulogoffX_time);
+ printf("tconX_count: %u\n", profile_p->SMBtconX_count);
+ printf("tconX_time: %u\n", profile_p->SMBtconX_time);
+ printf("dskattr_count: %u\n", profile_p->SMBdskattr_count);
+ printf("dskattr_time: %u\n", profile_p->SMBdskattr_time);
+ printf("search_count: %u\n", profile_p->SMBsearch_count);
+ printf("search_time: %u\n", profile_p->SMBsearch_time);
+ printf("ffirst_count: %u\n", profile_p->SMBffirst_count);
+ printf("ffirst_time: %u\n", profile_p->SMBffirst_time);
+ printf("funique_count: %u\n", profile_p->SMBfunique_count);
+ printf("funique_time: %u\n", profile_p->SMBfunique_time);
+ printf("fclose_count: %u\n", profile_p->SMBfclose_count);
+ printf("fclose_time: %u\n", profile_p->SMBfclose_time);
+ printf("nttrans_count: %u\n", profile_p->SMBnttrans_count);
+ printf("nttrans_time: %u\n", profile_p->SMBnttrans_time);
+ printf("nttranss_count: %u\n", profile_p->SMBnttranss_count);
+ printf("nttranss_time: %u\n", profile_p->SMBnttranss_time);
+ printf("ntcreateX_count: %u\n", profile_p->SMBntcreateX_count);
+ printf("ntcreateX_time: %u\n", profile_p->SMBntcreateX_time);
+ printf("ntcancel_count: %u\n", profile_p->SMBntcancel_count);
+ printf("ntcancel_time: %u\n", profile_p->SMBntcancel_time);
+ printf("splopen_count: %u\n", profile_p->SMBsplopen_count);
+ printf("splopen_time: %u\n", profile_p->SMBsplopen_time);
+ printf("splwr_count: %u\n", profile_p->SMBsplwr_count);
+ printf("splwr_time: %u\n", profile_p->SMBsplwr_time);
+ printf("splclose_count: %u\n", profile_p->SMBsplclose_count);
+ printf("splclose_time: %u\n", profile_p->SMBsplclose_time);
+ printf("splretq_count: %u\n", profile_p->SMBsplretq_count);
+ printf("splretq_time: %u\n", profile_p->SMBsplretq_time);
+ printf("sends_count: %u\n", profile_p->SMBsends_count);
+ printf("sends_time: %u\n", profile_p->SMBsends_time);
+ printf("sendb_count: %u\n", profile_p->SMBsendb_count);
+ printf("sendb_time: %u\n", profile_p->SMBsendb_time);
+ printf("fwdname_count: %u\n", profile_p->SMBfwdname_count);
+ printf("fwdname_time: %u\n", profile_p->SMBfwdname_time);
+ printf("cancelf_count: %u\n", profile_p->SMBcancelf_count);
+ printf("cancelf_time: %u\n", profile_p->SMBcancelf_time);
+ printf("getmac_count: %u\n", profile_p->SMBgetmac_count);
+ printf("getmac_time: %u\n", profile_p->SMBgetmac_time);
+ printf("sendstrt_count: %u\n", profile_p->SMBsendstrt_count);
+ printf("sendstrt_time: %u\n", profile_p->SMBsendstrt_time);
+ printf("sendend_count: %u\n", profile_p->SMBsendend_count);
+ printf("sendend_time: %u\n", profile_p->SMBsendend_time);
+ printf("sendtxt_count: %u\n", profile_p->SMBsendtxt_count);
+ printf("sendtxt_time: %u\n", profile_p->SMBsendtxt_time);
+ printf("invalid_count: %u\n", profile_p->SMBinvalid_count);
+ printf("invalid_time: %u\n", profile_p->SMBinvalid_time);
+ printf("************************ Pathworks Calls *************************\n");
+ printf("setdir_count: %u\n", profile_p->pathworks_setdir_count);
+ printf("setdir_time: %u\n", profile_p->pathworks_setdir_time);
+ printf("************************ Trans2 Calls ****************************\n");
+ printf("open_count: %u\n", profile_p->Trans2_open_count);
+ printf("open_time: %u\n", profile_p->Trans2_open_time);
+ printf("findfirst_count: %u\n", profile_p->Trans2_findfirst_count);
+ printf("findfirst_time: %u\n", profile_p->Trans2_findfirst_time);
+ printf("findnext_count: %u\n", profile_p->Trans2_findnext_count);
+ printf("findnext_time: %u\n", profile_p->Trans2_findnext_time);
+ printf("qfsinfo_count: %u\n", profile_p->Trans2_qfsinfo_count);
+ printf("qfsinfo_time: %u\n", profile_p->Trans2_qfsinfo_time);
+ printf("setfsinfo_count: %u\n", profile_p->Trans2_setfsinfo_count);
+ printf("setfsinfo_time: %u\n", profile_p->Trans2_setfsinfo_time);
+ printf("qpathinfo_count: %u\n", profile_p->Trans2_qpathinfo_count);
+ printf("qpathinfo_time: %u\n", profile_p->Trans2_qpathinfo_time);
+ printf("setpathinfo_count: %u\n", profile_p->Trans2_setpathinfo_count);
+ printf("setpathinfo_time: %u\n", profile_p->Trans2_setpathinfo_time);
+ printf("qfileinfo_count: %u\n", profile_p->Trans2_qfileinfo_count);
+ printf("qfileinfo_time: %u\n", profile_p->Trans2_qfileinfo_time);
+ printf("setfileinfo_count: %u\n", profile_p->Trans2_setfileinfo_count);
+ printf("setfileinfo_time: %u\n", profile_p->Trans2_setfileinfo_time);
+ printf("fsctl_count: %u\n", profile_p->Trans2_fsctl_count);
+ printf("fsctl_time: %u\n", profile_p->Trans2_fsctl_time);
+ printf("ioctl_count: %u\n", profile_p->Trans2_ioctl_count);
+ printf("ioctl_time: %u\n", profile_p->Trans2_ioctl_time);
+ printf("findnotifyfirst_count: %u\n", profile_p->Trans2_findnotifyfirst_count);
+ printf("findnotifyfirst_time: %u\n", profile_p->Trans2_findnotifyfirst_time);
+ printf("findnotifynext_count: %u\n", profile_p->Trans2_findnotifynext_count);
+ printf("findnotifynext_time: %u\n", profile_p->Trans2_findnotifynext_time);
+ printf("mkdir_count: %u\n", profile_p->Trans2_mkdir_count);
+ printf("mkdir_time: %u\n", profile_p->Trans2_mkdir_time);
+ printf("session_setup_count: %u\n", profile_p->Trans2_session_setup_count);
+ printf("session_setup_time: %u\n", profile_p->Trans2_session_setup_time);
+ printf("get_dfs_referral_count: %u\n", profile_p->Trans2_get_dfs_referral_count);
+ printf("get_dfs_referral_time: %u\n", profile_p->Trans2_get_dfs_referral_time);
+ printf("report_dfs_inconsistancy_count: %u\n", profile_p->Trans2_report_dfs_inconsistancy_count);
+ printf("report_dfs_inconsistancy_time: %u\n", profile_p->Trans2_report_dfs_inconsistancy_time);
+ printf("************************ NT Transact Calls ***********************\n");
+ printf("create_count: %u\n", profile_p->NT_transact_create_count);
+ printf("create_time: %u\n", profile_p->NT_transact_create_time);
+ printf("ioctl_count: %u\n", profile_p->NT_transact_ioctl_count);
+ printf("ioctl_time: %u\n", profile_p->NT_transact_ioctl_time);
+ printf("set_security_desc_count: %u\n", profile_p->NT_transact_set_security_desc_count);
+ printf("set_security_desc_time: %u\n", profile_p->NT_transact_set_security_desc_time);
+ printf("notify_change_count: %u\n", profile_p->NT_transact_notify_change_count);
+ printf("notify_change_time: %u\n", profile_p->NT_transact_notify_change_time);
+ printf("rename_count: %u\n", profile_p->NT_transact_rename_count);
+ printf("rename_time: %u\n", profile_p->NT_transact_rename_time);
+ printf("query_security_desc_count: %u\n", profile_p->NT_transact_query_security_desc_count);
+ printf("query_security_desc_time: %u\n", profile_p->NT_transact_query_security_desc_time);
+ printf("************************ ACL Calls *******************************\n");
+ printf("get_nt_acl_count: %u\n", profile_p->get_nt_acl_count);
+ printf("get_nt_acl_time: %u\n", profile_p->get_nt_acl_time);
+ printf("fget_nt_acl_count: %u\n", profile_p->fget_nt_acl_count);
+ printf("fget_nt_acl_time: %u\n", profile_p->fget_nt_acl_time);
+ printf("set_nt_acl_count: %u\n", profile_p->set_nt_acl_count);
+ printf("set_nt_acl_time: %u\n", profile_p->set_nt_acl_time);
+ printf("fset_nt_acl_count: %u\n", profile_p->fset_nt_acl_count);
+ printf("fset_nt_acl_time: %u\n", profile_p->fset_nt_acl_time);
+ printf("chmod_acl_count: %u\n", profile_p->chmod_acl_count);
+ printf("chmod_acl_time: %u\n", profile_p->chmod_acl_time);
+ printf("fchmod_acl_count: %u\n", profile_p->fchmod_acl_count);
+ printf("fchmod_acl_time: %u\n", profile_p->fchmod_acl_time);
+ printf("************************ NMBD Calls ****************************\n");
+ printf("name_release_count: %u\n", profile_p->name_release_count);
+ printf("name_release_time: %u\n", profile_p->name_release_time);
+ printf("name_refresh_count: %u\n", profile_p->name_refresh_count);
+ printf("name_refresh_time: %u\n", profile_p->name_refresh_time);
+ printf("name_registration_count: %u\n", profile_p->name_registration_count);
+ printf("name_registration_time: %u\n", profile_p->name_registration_time);
+ printf("node_status_count: %u\n", profile_p->node_status_count);
+ printf("node_status_time: %u\n", profile_p->node_status_time);
+ printf("name_query_count: %u\n", profile_p->name_query_count);
+ printf("name_query_time: %u\n", profile_p->name_query_time);
+ printf("host_announce_count: %u\n", profile_p->host_announce_count);
+ printf("host_announce_time: %u\n", profile_p->host_announce_time);
+ printf("workgroup_announce_count: %u\n", profile_p->workgroup_announce_count);
+ printf("workgroup_announce_time: %u\n", profile_p->workgroup_announce_time);
+ printf("local_master_announce_count: %u\n", profile_p->local_master_announce_count);
+ printf("local_master_announce_time: %u\n", profile_p->local_master_announce_time);
+ printf("master_browser_announce_count: %u\n", profile_p->master_browser_announce_count);
+ printf("master_browser_announce_time: %u\n", profile_p->master_browser_announce_time);
+ printf("lm_host_announce_count: %u\n", profile_p->lm_host_announce_count);
+ printf("lm_host_announce_time: %u\n", profile_p->lm_host_announce_time);
+ printf("get_backup_list_count: %u\n", profile_p->get_backup_list_count);
+ printf("get_backup_list_time: %u\n", profile_p->get_backup_list_time);
+ printf("reset_browser_count: %u\n", profile_p->reset_browser_count);
+ printf("reset_browser_time: %u\n", profile_p->reset_browser_time);
+ printf("announce_request_count: %u\n", profile_p->announce_request_count);
+ printf("announce_request_time: %u\n", profile_p->announce_request_time);
+ printf("lm_announce_request_count: %u\n", profile_p->lm_announce_request_count);
+ printf("lm_announce_request_time: %u\n", profile_p->lm_announce_request_time);
+ printf("domain_logon_count: %u\n", profile_p->domain_logon_count);
+ printf("domain_logon_time: %u\n", profile_p->domain_logon_time);
+ printf("sync_browse_lists_count: %u\n", profile_p->sync_browse_lists_count);
+ printf("sync_browse_lists_time: %u\n", profile_p->sync_browse_lists_time);
+ printf("run_elections_count: %u\n", profile_p->run_elections_count);
+ printf("run_elections_time: %u\n", profile_p->run_elections_time);
+ printf("election_count: %u\n", profile_p->election_count);
+ printf("election_time: %u\n", profile_p->election_time);
+
+#else /* ndef WITH_PROFILE */
+ fprintf(stderr,"Profile data unavailable\n");
#endif /* WITH_PROFILE */
-
return 0;
}
static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
+ static pid_t last_pid;
+ struct session_record *ptr;
struct connections_data crec;
if (dbuf.dsize != sizeof(crec))
@@ -540,33 +533,43 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
return 0;
}
- d_printf("%-10.10s %5d %-12s %s",
- crec.name,(int)crec.pid,
- crec.machine,
- asctime(LocalTime(&crec.start)));
-
- return 0;
-}
-
-static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
- struct sessionid sessionid;
-
- if (dbuf.dsize != sizeof(sessionid))
- return 0;
-
- memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
-
- if (!process_exists(sessionid.pid) || !Ucrit_checkUsername(uidtoname(sessionid.uid))) {
- return 0;
+ if (brief) {
+ ptr=srecs;
+ while (ptr!=NULL) {
+ if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) {
+ if (ptr->start > crec.start)
+ ptr->start=crec.start;
+ break;
+ }
+ ptr=ptr->next;
+ }
+ if (ptr==NULL) {
+ ptr=(struct session_record *) malloc(sizeof(struct session_record));
+ if (!ptr)
+ return 0;
+ ptr->uid=crec.uid;
+ ptr->pid=crec.pid;
+ ptr->start=crec.start;
+ strncpy(ptr->machine,crec.machine,30);
+ ptr->machine[30]='\0';
+ ptr->next=srecs;
+ srecs=ptr;
+ }
+ } else {
+ Ucrit_addPid(crec.pid);
+ if (processes_only) {
+ if (last_pid != crec.pid)
+ printf("%d\n",(int)crec.pid);
+ last_pid = crec.pid; /* XXXX we can still get repeats, have to
+ add a sort at some time */
+ } else {
+ printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s",
+ crec.name,uidtoname(crec.uid),gidtoname(crec.gid),(int)crec.pid,
+ crec.machine,crec.addr,
+ asctime(LocalTime(&crec.start)));
+ }
}
- Ucrit_addPid( sessionid.pid );
-
- d_printf("%5d %-12s %-12s %-12s (%s)\n",
- (int)sessionid.pid, uidtoname(sessionid.uid), gidtoname(sessionid.gid),
- sessionid.remote_machine, sessionid.hostname);
-
return 0;
}
@@ -575,112 +578,137 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
int main(int argc, char *argv[])
{
+ pstring fname;
int c;
- static int profile_only = 0;
+ static pstring servicesf = CONFIGFILE;
+ extern char *optarg;
+ int profile_only = 0;
TDB_CONTEXT *tdb;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"processes", 'p', POPT_ARG_NONE, &processes_only, 'p', "Show processes only" },
- {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" },
- {"locks", 'L', POPT_ARG_NONE, &locks_only, 'L', "Show locks only" },
- {"shares", 'S', POPT_ARG_NONE, &shares_only, 'S', "Show shares only" },
- {"user", 'u', POPT_ARG_STRING, 0, 'u', "Switch to user" },
- {"brief", 'b', POPT_ARG_NONE, &brief, 'b', "Be brief" },
-#ifdef WITH_PROFILE
- {"profile", 'P', POPT_ARG_NONE, &profile_only, 'P', "Do profiling" },
-#endif /* WITH_PROFILE */
- {"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"},
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
+ struct session_record *ptr;
+ TimeInit();
setup_logging(argv[0],True);
- dbf = x_stderr;
+ charset_initialise();
+
+ AllowDebugChange = False;
+ DEBUGLEVEL = 0;
+ dbf = stderr;
if (getuid() != geteuid()) {
- d_printf("smbstatus should not be run setuid\n");
+ printf("smbstatus should not be run setuid\n");
return(1);
}
-
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
- while ((c = poptGetNextOpt(pc)) != -1) {
+ while ((c = getopt(argc, argv, "pdLSs:u:bPB")) != EOF) {
switch (c) {
+ case 'b':
+ brief = 1;
+ break;
+ case 'B':
+ show_brl = 1;
+ break;
+ case 'd':
+ verbose = 1;
+ break;
+ case 'L':
+ locks_only = 1;
+ break;
+ case 'p':
+ processes_only = 1;
+ break;
+ case 'P':
+ profile_only = 1;
+ break;
+ case 'S':
+ shares_only = 1;
+ break;
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
case 'u':
- Ucrit_addUsername(poptGetOptArg(pc));
+ Ucrit_addUsername(optarg);
break;
+ default:
+ fprintf(stderr, "Usage: %s [-P] [-d] [-L] [-p] [-S] [-s configfile] [-u username]\n", *argv);
+ return (-1);
}
}
-
- if (verbose) {
- d_printf("using configfile = %s\n", dyn_CONFIGFILE);
- }
-
- if (!lp_load(dyn_CONFIGFILE,False,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+
+ if (!lp_load(servicesf,False,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
return (-1);
}
+ if (verbose) {
+ printf("using configfile = %s\n", servicesf);
+ }
+
if (profile_only) {
return profile_dump();
}
- tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!tdb) {
- d_printf("sessionid.tdb not initialised\n");
- } else {
- if (locks_only) goto locks;
-
- d_printf("\nSamba version %s\n",SAMBA_VERSION_STRING);
- d_printf("PID Username Group Machine \n");
- d_printf("-------------------------------------------------------------------\n");
-
- tdb_traverse(tdb, traverse_sessionid, NULL);
- tdb_close(tdb);
- }
-
tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb) {
- d_printf("%s not initialised\n", lock_path("connections.tdb"));
- d_printf("This is normal if an SMB client has never connected to your server.\n");
- } else {
- if (verbose) {
- d_printf("Opened %s\n", lock_path("connections.tdb"));
+ printf("%s not initialized.\n", lock_path("connections.tdb"));
+ printf("This is normal if an SMB client has never connected to your server.\n");
+ if (!lp_status(-1)) {
+ printf("You need to have status=yes in your smb config file\n");
}
+ return(0);
+ } else if (verbose) {
+ slprintf (fname, sizeof(fname)-1, "%s/%s", lp_lockdir(), "connections.tdb");
+ printf("Opened %s\n", fname);
+ }
- if (brief)
- exit(0);
-
- d_printf("\nService pid machine Connected at\n");
- d_printf("-------------------------------------------------------\n");
+ if (locks_only) goto locks;
- tdb_traverse(tdb, traverse_fn1, NULL);
- tdb_close(tdb);
+ printf("\nSamba version %s\n",VERSION);
+ if (brief) {
+ printf("PID Username Machine Time logged in\n");
+ printf("-------------------------------------------------------------------\n");
+ } else {
+ printf("Service uid gid pid machine\n");
+ printf("----------------------------------------------\n");
}
+ tdb_traverse(tdb, traverse_fn1, NULL);
+
locks:
if (processes_only) exit(0);
+
+ if (brief) {
+ ptr=srecs;
+ while (ptr!=NULL) {
+ printf("%-8d%-10.10s%-30.30s%s",
+ (int)ptr->pid,uidtoname(ptr->uid),
+ ptr->machine,
+ asctime(LocalTime(&(ptr->start))));
+ ptr=ptr->next;
+ }
+ printf("\n");
+ exit(0);
+ }
+
+ printf("\n");
if (!shares_only) {
int ret;
if (!locking_init(1)) {
- d_printf("Can't initialise locking module - exiting\n");
+ printf("Can't initialise locking module - exiting\n");
exit(1);
}
ret = share_mode_forall(print_share_mode);
if (ret == 0) {
- d_printf("No locked files\n");
+ printf("No locked files\n");
} else if (ret == -1) {
- d_printf("locked file list truncated\n");
+ printf("locked file list truncated\n");
}
- d_printf("\n");
+ printf("\n");
if (show_brl) {
brl_forall(print_brl);
@@ -691,3 +719,4 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
return (0);
}
+
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index 9db6d538d24..1e2b4b170ec 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -1,10 +1,10 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Test validity of smb.conf
Copyright (C) Karl Auer 1993, 1994-1998
Extensively modified by Andrew Tridgell, 1995
- Converted to popt by Jelmer Vernooij (jelmer@nl.linux.org), 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,8 +33,13 @@
*/
#include "includes.h"
+#include "smb.h"
extern BOOL AllowDebugChange;
+extern int parsed_debuglevel_class[DBGC_LAST];
+
+/* these live in util.c */
+extern FILE *dbf;
/***********************************************
Here we do a set of 'hard coded' checks for bad
@@ -46,29 +51,29 @@ static int do_global_checks(void)
int ret = 0;
SMB_STRUCT_STAT st;
- if (lp_security() >= SEC_DOMAIN && !lp_encrypted_passwords()) {
- fprintf(stderr, "ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n");
+ if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
+ printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
ret = 1;
}
- if (lp_wins_support() && lp_wins_server_list()) {
- fprintf(stderr, "ERROR: both 'wins support = true' and 'wins server = <server list>' \
+ if (lp_wins_support() && *lp_wins_server()) {
+ printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
ret = 1;
}
if (!directory_exist(lp_lockdir(), &st)) {
- fprintf(stderr, "ERROR: lock directory %s does not exist\n",
+ printf("ERROR: lock directory %s does not exist\n",
lp_lockdir());
ret = 1;
} else if ((st.st_mode & 0777) != 0755) {
- fprintf(stderr, "WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
+ printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
lp_lockdir());
ret = 1;
}
if (!directory_exist(lp_piddir(), &st)) {
- fprintf(stderr, "ERROR: pid directory %s does not exist\n",
+ printf("ERROR: pid directory %s does not exist\n",
lp_piddir());
ret = 1;
}
@@ -77,28 +82,18 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
* Password server sanity checks.
*/
- if((lp_security() == SEC_SERVER || lp_security() >= SEC_DOMAIN) && !lp_passwordserver()) {
+ if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
pstring sec_setting;
if(lp_security() == SEC_SERVER)
pstrcpy(sec_setting, "server");
else if(lp_security() == SEC_DOMAIN)
pstrcpy(sec_setting, "domain");
- fprintf(stderr, "ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
+ printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
to a valid password server.\n", sec_setting );
ret = 1;
}
-
- /*
- * Check 'hosts equiv' and 'use rhosts' compatibility with 'hostname lookup' value.
- */
-
- if(*lp_hosts_equiv() && !lp_hostname_lookups()) {
- fprintf(stderr, "ERROR: The setting 'hosts equiv = %s' requires that 'hostname lookups = yes'.\n", lp_hosts_equiv());
- ret = 1;
- }
-
/*
* Password chat sanity checks.
*/
@@ -114,7 +109,7 @@ to a valid password server.\n", sec_setting );
#endif
if(lp_passwd_program() == NULL) {
- fprintf( stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
+ printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
parameter.\n" );
ret = 1;
} else {
@@ -128,7 +123,7 @@ parameter.\n" );
next_token(&p, truncated_prog, NULL, sizeof(pstring));
if(access(truncated_prog, F_OK) == -1) {
- fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
+ printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
ret = 1;
}
@@ -139,7 +134,7 @@ cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
#endif
if(lp_passwd_chat() == NULL) {
- fprintf(stderr, "ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
+ printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
parameter.\n");
ret = 1;
}
@@ -150,218 +145,191 @@ parameter.\n");
*/
if(lp_encrypted_passwords()) {
- if(strstr_m( lp_passwd_chat(), "%o")!=NULL) {
- fprintf(stderr, "ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
+ if(strstr( lp_passwd_chat(), "%o")!=NULL) {
+ printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
ret = 1;
}
}
}
- if (strlen(lp_winbind_separator()) != 1) {
- fprintf(stderr,"ERROR: the 'winbind separator' parameter must be a single character.\n");
+ if (!lp_status(-1) && lp_max_smbd_processes()) {
+ printf("ERROR: the 'max smbd processes' parameter is set and the 'status' parameter is set to 'no'.\n");
ret = 1;
}
- if (*lp_winbind_separator() == '+') {
- fprintf(stderr,"'winbind separator = +' might cause problems with group membership.\n");
- }
-
- if (lp_algorithmic_rid_base() < BASE_RID) {
- /* Try to prevent admin foot-shooting, we can't put algorithmic
- rids below 1000, that's the 'well known RIDs' on NT */
- fprintf(stderr,"'algorithmic rid base' must be equal to or above %lu\n", BASE_RID);
- }
-
- if (lp_algorithmic_rid_base() & 1) {
- fprintf(stderr,"'algorithmic rid base' must be even.\n");
- }
-
-#ifndef HAVE_DLOPEN
- if (lp_preload_modules()) {
- fprintf(stderr,"WARNING: 'preload modules = ' set while loading plugins not supported.\n");
+ if (strlen(lp_winbind_separator()) != 1) {
+ printf("ERROR: the 'winbind separator' parameter must be a single character.\n");
+ ret = 1;
}
-#endif
- if (!lp_passdb_backend()) {
- fprintf(stderr,"ERROR: passdb backend must have a value or be left out\n");
+ if (*lp_winbind_separator() == '+') {
+ printf("'winbind separator = +' might cause problems with group membership.\n");
}
return ret;
}
- int main(int argc, const char *argv[])
+static void usage(char *pname)
{
- const char *config_file = dyn_CONFIGFILE;
- int s;
- static BOOL silent_mode = False;
- int ret = 0;
- poptContext pc;
- static const char *term_code = "";
- static char *new_local_machine = NULL;
- const char *cname;
- const char *caddr;
- static int show_defaults;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"},
- {"verbose", 'v', POPT_ARG_NONE, &show_defaults, 1, "Show default options too"},
- {"server", 'L',POPT_ARG_STRING, &new_local_machine, 0, "Set %%L macro to servername\n"},
- {"encoding", 't', POPT_ARG_STRING, &term_code, 0, "Print parameters with encoding"},
- POPT_COMMON_VERSION
- POPT_TABLEEND
- };
-
- pc = poptGetContext(NULL, argc, argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
- poptSetOtherOptionHelp(pc, "[OPTION...] <config-file> [host-name] [host-ip]");
-
- while(poptGetNextOpt(pc) != -1);
-
- setup_logging(poptGetArg(pc), True);
-
- if (poptPeekArg(pc))
- config_file = poptGetArg(pc);
-
- cname = poptGetArg(pc);
- caddr = poptGetArg(pc);
-
- if ( cname && ! caddr ) {
- printf ( "ERROR: You must specify both a machine name and an IP address.\n" );
- return(1);
- }
-
- if (new_local_machine) {
- set_local_machine_name(new_local_machine, True);
- }
-
- dbf = x_stderr;
- DEBUGLEVEL = 2;
- AllowDebugChange = False;
-
- fprintf(stderr,"Load smb config files from %s\n",config_file);
-
- if (!lp_load(config_file,False,True,False)) {
- fprintf(stderr,"Error loading services.\n");
- return(1);
- }
-
- fprintf(stderr,"Loaded services file OK.\n");
-
- ret = do_global_checks();
-
- for (s=0;s<1000;s++) {
- if (VALID_SNUM(s))
- if (strlen(lp_servicename(s)) > 12) {
- fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" );
- fprintf(stderr, "These may not be accessible to some older clients.\n" );
- fprintf(stderr, "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" );
- break;
- }
- }
-
- for (s=0;s<1000;s++) {
- if (VALID_SNUM(s)) {
- const char **deny_list = lp_hostsdeny(s);
- const char **allow_list = lp_hostsallow(s);
- int i;
- if(deny_list) {
- for (i=0; deny_list[i]; i++) {
- char *hasstar = strchr_m(deny_list[i], '*');
- char *hasquery = strchr_m(deny_list[i], '?');
- if(hasstar || hasquery) {
- fprintf(stderr,"Invalid character %c in hosts deny list (%s) for service %s.\n",
- hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) );
- }
- }
- }
-
- if(allow_list) {
- for (i=0; allow_list[i]; i++) {
- char *hasstar = strchr_m(allow_list[i], '*');
- char *hasquery = strchr_m(allow_list[i], '?');
- if(hasstar || hasquery) {
- fprintf(stderr,"Invalid character %c in hosts allow list (%s) for service %s.\n",
- hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) );
- }
- }
- }
-
- if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
- fprintf(stderr,"Invalid combination of parameters for service %s. \
- Level II oplocks can only be set if oplocks are also set.\n",
- lp_servicename(s) );
- }
-
- if (lp_map_hidden(s) && !(lp_create_mask(s) & S_IXOTH)) {
- fprintf(stderr,"Invalid combination of parameters for service %s. \
- Map hidden can only work if create mask includes octal 01 (S_IXOTH).\n",
- lp_servicename(s) );
- }
- if (lp_map_hidden(s) && (lp_force_create_mode(s) & S_IXOTH)) {
- fprintf(stderr,"Invalid combination of parameters for service %s. \
- Map hidden can only work if force create mode excludes octal 01 (S_IXOTH).\n",
- lp_servicename(s) );
- }
- if (lp_map_system(s) && !(lp_create_mask(s) & S_IXGRP)) {
- fprintf(stderr,"Invalid combination of parameters for service %s. \
- Map system can only work if create mask includes octal 010 (S_IXGRP).\n",
- lp_servicename(s) );
- }
- if (lp_map_system(s) && (lp_force_create_mode(s) & S_IXGRP)) {
- fprintf(stderr,"Invalid combination of parameters for service %s. \
- Map system can only work if force create mode excludes octal 010 (S_IXGRP).\n",
- lp_servicename(s) );
- }
- }
- }
-
-
- if (!silent_mode) {
- fprintf(stderr,"Server role: ");
- switch(lp_server_role()) {
- case ROLE_STANDALONE:
- fprintf(stderr,"ROLE_STANDALONE\n");
- break;
- case ROLE_DOMAIN_MEMBER:
- fprintf(stderr,"ROLE_DOMAIN_MEMBER\n");
- break;
- case ROLE_DOMAIN_BDC:
- fprintf(stderr,"ROLE_DOMAIN_BDC\n");
- break;
- case ROLE_DOMAIN_PDC:
- fprintf(stderr,"ROLE_DOMAIN_PDC\n");
- break;
- default:
- fprintf(stderr,"Unknown -- internal error?\n");
- break;
- }
- }
+ printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
+ printf("\t-s Suppress prompt for enter\n");
+ printf("\t-x Print only smb.conf parameters with values that are non-default\n");
+ printf("\t-h Print usage\n");
+ printf("\t-L servername Set %%L macro to servername\n");
+ printf("\t-t encoding Print parameters with encoding\n");
+ printf("\tconfigfilename Configuration file to test\n");
+ printf("\thostname hostIP. Hostname and Host IP address to test\n");
+ printf("\t against \"host allow\" and \"host deny\"\n");
+ printf("\n");
+}
- if (!cname) {
- if (!silent_mode) {
- fprintf(stderr,"Press enter to see a dump of your service definitions\n");
- fflush(stdout);
- getc(stdin);
- }
- lp_dump(stdout, show_defaults, lp_numservices());
- }
- if(cname && caddr){
- /* this is totally ugly, a real `quick' hack */
- for (s=0;s<1000;s++) {
- if (VALID_SNUM(s)) {
- if (allow_access(lp_hostsdeny(-1), lp_hostsallow(-1), cname, caddr)
- && allow_access(lp_hostsdeny(s), lp_hostsallow(s), cname, caddr)) {
- fprintf(stderr,"Allow connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- } else {
- fprintf(stderr,"Deny connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
- }
- }
- }
- return(ret);
+int main(int argc, char *argv[])
+{
+ extern char *optarg;
+ extern int optind;
+ extern fstring local_machine;
+ pstring configfile;
+ int opt;
+ int s;
+ BOOL show_defaults=True;
+ BOOL silent_mode = False;
+ int ret = 0;
+ pstring term_code;
+
+ *term_code = 0;
+
+ TimeInit();
+
+ setup_logging(argv[0],True);
+
+ charset_initialise();
+
+ while ((opt = getopt(argc, argv,"shL:t:x")) != EOF) {
+ switch (opt) {
+ case 's':
+ silent_mode = True;
+ break;
+ case 'L':
+ fstrcpy(local_machine,optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ break;
+ case 't':
+ pstrcpy(term_code,optarg);
+ break;
+ case 'x':
+ show_defaults=False;
+ break;
+ default:
+ printf("Incorrect program usage\n");
+ usage(argv[0]);
+ exit(1);
+ break;
+ }
+ }
+
+ argc += (1 - optind);
+
+ if ((argc == 1) || (argc == 3))
+ pstrcpy(configfile,CONFIGFILE);
+ else if ((argc == 2) || (argc == 4))
+ pstrcpy(configfile,argv[optind]);
+
+ dbf = stdout;
+ DEBUGLEVEL = 2;
+ AllowDebugChange = False;
+
+ printf("Load smb config files from %s\n",configfile);
+
+ if (!lp_load(configfile,False,True,False)) {
+ printf("Error loading services.\n");
+ return(1);
+ }
+
+ printf("Loaded services file OK.\n");
+
+ ret = do_global_checks();
+
+ for (s=0;s<1000;s++) {
+ if (VALID_SNUM(s))
+ if (strlen(lp_servicename(s)) > 8) {
+ printf("WARNING: You have some share names that are longer than 8 chars\n");
+ printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
+ break;
+ }
+ }
+
+ for (s=0;s<1000;s++) {
+ if (VALID_SNUM(s)) {
+ char *deny_list = lp_hostsdeny(s);
+ char *allow_list = lp_hostsallow(s);
+ if(deny_list) {
+ char *hasstar = strchr(deny_list, '*');
+ char *hasquery = strchr(deny_list, '?');
+ if(hasstar || hasquery) {
+ printf("Invalid character %c in hosts deny list %s for service %s.\n",
+ hasstar ? *hasstar : *hasquery, deny_list, lp_servicename(s) );
+ }
+ }
+
+ if(allow_list) {
+ char *hasstar = strchr(allow_list, '*');
+ char *hasquery = strchr(allow_list, '?');
+ if(hasstar || hasquery) {
+ printf("Invalid character %c in hosts allow list %s for service %s.\n",
+ hasstar ? *hasstar : *hasquery, allow_list, lp_servicename(s) );
+ }
+ }
+
+ if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
+ printf("Invalid combination of parameters for service %s. \
+Level II oplocks can only be set if oplocks are also set.\n",
+ lp_servicename(s) );
+ }
+ }
+ }
+
+ if (*term_code)
+ interpret_coding_system(term_code);
+
+ if (argc < 3) {
+ if (!silent_mode) {
+ printf("Press enter to see a dump of your service definitions\n");
+ fflush(stdout);
+ getc(stdin);
+ }
+ memcpy(DEBUGLEVEL_CLASS,parsed_debuglevel_class,sizeof(parsed_debuglevel_class));
+ lp_dump(stdout,show_defaults, lp_numservices(), _dos_to_unix_static);
+ }
+
+ if (argc >= 3) {
+ char *cname;
+ char *caddr;
+
+ if (argc == 3) {
+ cname = argv[optind];
+ caddr = argv[optind+1];
+ } else {
+ cname = argv[optind+1];
+ caddr = argv[optind+2];
+ }
+
+ /* this is totally ugly, a real `quick' hack */
+ for (s=0;s<1000;s++) {
+ if (VALID_SNUM(s)) {
+ if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
+ printf("Allow connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ } else {
+ printf("Deny connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ }
+ }
+ }
+ }
+ return(ret);
}
diff --git a/source/utils/testprns.c b/source/utils/testprns.c
index 7e52b86afb6..8feb977f497 100644
--- a/source/utils/testprns.c
+++ b/source/utils/testprns.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
test printer setup
Copyright (C) Karl Auer 1993, 1994-1998
@@ -31,18 +32,26 @@
*/
#include "includes.h"
+#include "smb.h"
+
+/* these live in util.c */
+extern FILE *dbf;
int main(int argc, char *argv[])
{
const char *pszTemp;
+ TimeInit();
+
setup_logging(argv[0],True);
+ charset_initialise();
+
if (argc < 2 || argc > 3)
printf("Usage: testprns printername [printcapfile]\n");
else
{
- dbf = x_fopen("test.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ dbf = sys_fopen("test.log", "w");
if (dbf == NULL) {
printf("Unable to open logfile.\n");
} else {
@@ -54,8 +63,9 @@ int main(int argc, char *argv[])
printf("Printer name %s is not valid.\n", argv[1]);
else
printf("Printer name %s is valid.\n", argv[1]);
- x_fclose(dbf);
+ fclose(dbf);
}
}
return (0);
}
+
diff --git a/source/utils/torture.c b/source/utils/torture.c
new file mode 100755
index 00000000000..ac3416188c7
--- /dev/null
+++ b/source/utils/torture.c
@@ -0,0 +1,4975 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB torture tester
+ Copyright (C) Andrew Tridgell 1997-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+#define MAX_USERS 10
+#define MAX_TIDS 10
+#define MAX_FIDS_PER_TID MAX_USERS
+
+struct cli_state *seed;
+
+typedef struct test_vuser {
+
+ struct cli_state cli;
+
+ fstring username;
+ fstring password;
+ BOOL gotpass;
+ fstring fname;
+
+ int vuid;
+ BOOL vuid_valid;
+ BOOL files_valid;
+
+ struct {
+
+ int tid;
+ int tid_valid;
+
+ int fnum[MAX_FIDS_PER_TID];
+ int backup_fnum[MAX_FIDS_PER_TID];
+ } per_tid[MAX_TIDS];
+
+} TEST_VUSERS;
+
+#if 0
+static struct {
+ fstring *first;
+ fstring *last;
+} errtab; /*keep a list of known errors to reduce noise*/
+#endif
+
+static fstring shares[MAX_TIDS];
+static TEST_VUSERS vusers[MAX_USERS];
+
+static fstring host, workgroup, myname;
+static char *username = vusers[0].username;
+static char *password = vusers[0].password;
+static char *share = shares[0];
+
+static int max_protocol = PROTOCOL_NT1;
+static char *sockops="TCP_NODELAY";
+static int nprocs=1, numops=100;
+static int nusers=1, nshares=0;
+static int procnum; /* records process count number when forking */
+static struct cli_state current_cli;
+static fstring randomfname;
+static BOOL use_oplocks;
+static BOOL use_level_II_oplocks;
+
+static double create_procs(BOOL (*fn)(int), BOOL *result);
+
+static struct timeval tp1,tp2;
+
+static void start_timer(void)
+{
+ gettimeofday(&tp1,NULL);
+}
+
+static double end_timer(void)
+{
+ gettimeofday(&tp2,NULL);
+ return((tp2.tv_sec - tp1.tv_sec) +
+ (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+}
+
+
+/* return a pointer to a anonymous shared memory segment of size "size"
+ which will persist across fork() but will disappear when all processes
+ exit
+
+ The memory is not zeroed
+
+ This function uses system5 shared memory. It takes advantage of a property
+ that the memory is not destroyed if it is attached when the id is removed
+ */
+static void *shm_setup(int size)
+{
+ int shmid;
+ void *ret;
+
+ shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+ if (shmid == -1) {
+ printf("can't get shared memory\n");
+ exit(1);
+ }
+ ret = (void *)shmat(shmid, 0, 0);
+ if (!ret || ret == (void *)-1) {
+ printf("can't attach to shared memory\n");
+ return NULL;
+ }
+ /* the following releases the ipc, but note that this process
+ and all its children will still have access to the memory, its
+ just that the shmid is no longer valid for other shm calls. This
+ means we don't leave behind lots of shm segments after we exit
+
+ See Stevens "advanced programming in unix env" for details
+ */
+ shmctl(shmid, IPC_RMID, 0);
+
+ return ret;
+}
+
+static BOOL open_nbt_connection(struct cli_state *c)
+{
+ struct nmb_name called, calling;
+ struct in_addr ip;
+
+ ZERO_STRUCTP(c);
+
+ make_nmb_name(&calling, myname, 0x0);
+ make_nmb_name(&called , host, 0x20);
+
+ zero_ip(&ip);
+
+ if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
+ printf("Failed to connect with %s\n", host);
+ return False;
+ }
+
+ c->timeout = 120000; /* set a really long timeout (2 minutes) */
+ if (use_oplocks) c->use_oplocks = True;
+ if (use_level_II_oplocks) c->use_level_II_oplocks = True;
+
+ if (!cli_session_request(c, &calling, &called)) {
+ printf("%s rejected the session\n",host);
+ cli_shutdown(c);
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL open_connection(struct cli_state *c)
+{
+ ZERO_STRUCTP(c);
+
+ if (!open_nbt_connection(c)) {
+ return False;
+ }
+
+ if (!cli_negprot(c)) {
+ printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
+ cli_shutdown(c);
+ return False;
+ }
+
+ if (!cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup)) {
+ printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
+ cli_shutdown(c);
+ return False;
+ }
+
+ if (!cli_send_tconX(c, share, "?????",
+ password, strlen(password)+1)) {
+ printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
+ cli_shutdown(c);
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL close_connection(struct cli_state *c)
+{
+ BOOL ret = True;
+ if (!cli_tdis(c)) {
+ printf("tdis failed (%s)\n", cli_errstr(c));
+ ret = False;
+ }
+
+ cli_shutdown(c);
+
+ return ret;
+}
+
+
+/* check if the server produced the expected error code */
+static BOOL check_error(struct cli_state *c,
+ uint8 eclass, uint32 ecode, uint32 nterr)
+{
+ uint8 class;
+ uint32 num;
+
+ (void)cli_dos_error(c, &class, &num);
+ if ((eclass != class || ecode != num) &&
+ num != (nterr&0xFFFFFF)) {
+ printf("unexpected error code class=%d code=%d\n",
+ (int)class, (int)num);
+ printf(" expected %d/%d %d\n",
+ (int)eclass, (int)ecode, (int)nterr);
+ return False;
+ }
+ return True;
+}
+
+
+static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
+{
+ while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
+ if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
+ }
+ return True;
+}
+
+
+static BOOL rw_torture(struct cli_state *c)
+{
+ char *lockfname = "\\torture.lck";
+ fstring fname;
+ int fnum;
+ int fnum2;
+ pid_t pid2, pid = getpid();
+ int i, j;
+ char buf[1024];
+ BOOL correct = True;
+
+ fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
+ DENY_NONE);
+ if (fnum2 == -1)
+ fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
+ if (fnum2 == -1) {
+ printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
+ return False;
+ }
+
+
+ for (i=0;i<numops;i++) {
+ unsigned n = (unsigned)sys_random()%10;
+ if (i % 10 == 0) {
+ printf("%d\r", i); fflush(stdout);
+ }
+ slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
+
+ if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
+ return False;
+ }
+
+ fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
+ if (fnum == -1) {
+ printf("open failed (%s)\n", cli_errstr(c));
+ correct = False;
+ break;
+ }
+
+ if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
+ printf("write failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+
+ for (j=0;j<50;j++) {
+ if (cli_write(c, fnum, 0, (char *)buf,
+ sizeof(pid)+(j*sizeof(buf)),
+ sizeof(buf)) != sizeof(buf)) {
+ printf("write failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+ }
+
+ pid2 = 0;
+
+ if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
+ printf("read failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+
+ if (pid2 != pid) {
+ printf("data corruption!\n");
+ correct = False;
+ }
+
+ if (!cli_close(c, fnum)) {
+ printf("close failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+
+ if (!cli_unlink(c, fname)) {
+ printf("unlink failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+
+ if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
+ printf("unlock failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+ }
+
+ cli_close(c, fnum2);
+ cli_unlink(c, lockfname);
+
+ printf("%d\n", i);
+
+ return correct;
+}
+
+static BOOL run_torture(int dummy)
+{
+ struct cli_state cli;
+ BOOL ret;
+
+ cli = current_cli;
+
+ cli_sockopt(&cli, sockops);
+
+ ret = rw_torture(&cli);
+
+ if (!close_connection(&cli)) {
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL rw_torture3(struct cli_state *c, char *lockfname)
+{
+ int fnum = -1;
+ int i = 0;
+ char buf[131072];
+ char buf_rd[131072];
+ unsigned count;
+ unsigned countprev = 0;
+ unsigned sent = 0;
+ BOOL correct = True;
+
+ srandom(1);
+ for (i = 0; i < sizeof(buf); i += sizeof(uint32))
+ {
+ SIVAL(buf, i, sys_random());
+ }
+
+ if (procnum == 0)
+ {
+ fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
+ DENY_NONE);
+ if (fnum == -1) {
+ printf("first open read/write of %s failed (%s)\n",
+ lockfname, cli_errstr(c));
+ return False;
+ }
+ }
+ else
+ {
+ for (i = 0; i < 500 && fnum == -1; i++)
+ {
+ fnum = cli_open(c, lockfname, O_RDONLY,
+ DENY_NONE);
+ msleep(10);
+ }
+ if (fnum == -1) {
+ printf("second open read-only of %s failed (%s)\n",
+ lockfname, cli_errstr(c));
+ return False;
+ }
+ }
+
+ i = 0;
+ for (count = 0; count < sizeof(buf); count += sent)
+ {
+ if (count >= countprev) {
+ printf("%d %8d\r", i, count);
+ fflush(stdout);
+ i++;
+ countprev += (sizeof(buf) / 20);
+ }
+
+ if (procnum == 0)
+ {
+ sent = ((unsigned)sys_random()%(20))+ 1;
+ if (sent > sizeof(buf) - count)
+ {
+ sent = sizeof(buf) - count;
+ }
+
+ if (cli_write(c, fnum, 0, buf+count, count, sent) != sent) {
+ printf("write failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+ }
+ else
+ {
+ sent = cli_read(c, fnum, buf_rd+count, count,
+ sizeof(buf)-count);
+ if (sent < 0)
+ {
+ printf("read failed offset:%d size:%d (%s)\n",
+ count, sizeof(buf)-count,
+ cli_errstr(c));
+ correct = False;
+ sent = 0;
+ }
+ if (sent > 0)
+ {
+ if (memcmp(buf_rd+count, buf+count, sent) != 0)
+ {
+ printf("read/write compare failed\n");
+ printf("offset: %d req %d recvd %d\n",
+ count, sizeof(buf)-count, sent);
+ correct = False;
+ break;
+ }
+ }
+ }
+
+ }
+
+ if (!cli_close(c, fnum)) {
+ printf("close failed (%s)\n", cli_errstr(c));
+ correct = False;
+ }
+
+ return correct;
+}
+
+static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
+{
+ char *lockfname = "\\torture.lck";
+ int fnum1;
+ int fnum2;
+ int i;
+ char buf[131072];
+ char buf_rd[131072];
+ BOOL correct = True;
+ ssize_t bytes_read;
+
+ if (!cli_unlink(c1, lockfname)) {
+ printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
+ }
+
+ fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
+ DENY_NONE);
+ if (fnum1 == -1) {
+ printf("first open read/write of %s failed (%s)\n",
+ lockfname, cli_errstr(c1));
+ return False;
+ }
+ fnum2 = cli_open(c2, lockfname, O_RDONLY,
+ DENY_NONE);
+ if (fnum2 == -1) {
+ printf("second open read-only of %s failed (%s)\n",
+ lockfname, cli_errstr(c2));
+ cli_close(c1, fnum1);
+ return False;
+ }
+
+ for (i=0;i<numops;i++)
+ {
+ size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
+ if (i % 10 == 0) {
+ printf("%d\r", i); fflush(stdout);
+ }
+
+ generate_random_buffer(buf, buf_size, False);
+
+ if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
+ printf("write failed (%s)\n", cli_errstr(c1));
+ correct = False;
+ }
+
+ if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
+ printf("read failed (%s)\n", cli_errstr(c2));
+ printf("read %d, expected %d\n", bytes_read, buf_size);
+ correct = False;
+ }
+
+ if (memcmp(buf_rd, buf, buf_size) != 0)
+ {
+ printf("read/write compare failed\n");
+ correct = False;
+ }
+ }
+
+ if (!cli_close(c2, fnum2)) {
+ printf("close failed (%s)\n", cli_errstr(c2));
+ correct = False;
+ }
+ if (!cli_close(c1, fnum1)) {
+ printf("close failed (%s)\n", cli_errstr(c1));
+ correct = False;
+ }
+
+ if (!cli_unlink(c1, lockfname)) {
+ printf("unlink failed (%s)\n", cli_errstr(c1));
+ correct = False;
+ }
+
+ return correct;
+}
+
+static BOOL run_readwritetest(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ BOOL test1, test2;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting readwritetest\n");
+
+ test1 = rw_torture2(&cli1, &cli2);
+ printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
+
+ test2 = rw_torture2(&cli1, &cli1);
+ printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
+
+ if (!close_connection(&cli1)) {
+ test1 = False;
+ }
+
+ if (!close_connection(&cli2)) {
+ test2 = False;
+ }
+
+ return (test1 && test2);
+}
+
+static BOOL run_readwritemulti(int dummy)
+{
+ static struct cli_state cli;
+ BOOL test;
+
+ cli = current_cli;
+
+ cli_sockopt(&cli, sockops);
+
+ printf("run_readwritemulti: fname %s\n", randomfname);
+ test = rw_torture3(&cli, randomfname);
+
+ if (!close_connection(&cli)) {
+ test = False;
+ }
+
+ return test;
+}
+
+static BOOL run_readwritelarge(int dummy)
+{
+ static struct cli_state cli1;
+ int fnum1;
+ char *lockfname = "\\large.dat";
+ size_t fsize;
+ char buf[0x10000];
+ BOOL correct = True;
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ memset(buf,'\0',sizeof(buf));
+
+ cli1.max_xmit = 0x11000;
+
+ printf("starting readwritelarge\n");
+
+ cli_unlink(&cli1, lockfname);
+
+ fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
+ return False;
+ }
+
+ cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
+ printf("qpathinfo failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ if (fsize == sizeof(buf))
+ printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
+ else {
+ printf("readwritelarge test 1 failed (size = %x)\n", fsize);
+ correct = False;
+ }
+
+ if (!cli_unlink(&cli1, lockfname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
+ return False;
+ }
+
+ cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+ return correct;
+ }
+
+int line_count = 0;
+
+/* run a test that simulates an approximate netbench client load */
+static BOOL run_netbench(int client)
+{
+ struct cli_state cli;
+ int i;
+ fstring fname;
+ pstring line;
+ char cname[20];
+ FILE *f;
+ char *params[20];
+ BOOL correct = True;
+
+ cli = current_cli;
+
+ cli_sockopt(&cli, sockops);
+
+ nb_setup(&cli);
+
+ slprintf(cname,sizeof(fname), "CLIENT%d", client);
+
+ f = fopen("client.txt", "r");
+
+ if (!f) {
+ perror("client.txt");
+ return False;
+ }
+
+ while (fgets(line, sizeof(line)-1, f)) {
+ line_count++;
+
+ line[strlen(line)-1] = 0;
+
+ /* printf("[%d] %s\n", line_count, line); */
+
+ all_string_sub(line,"CLIENT1", cname, sizeof(line));
+
+ for (i=0;i<20;i++) params[i] = "";
+
+ /* parse the command parameters */
+ params[0] = strtok(line," ");
+ i = 0;
+ while (params[i]) params[++i] = strtok(NULL," ");
+
+ params[i] = "";
+
+ if (i < 2) continue;
+
+ if (strcmp(params[1],"REQUEST") == 0) {
+ if (!strcmp(params[0],"SMBopenX")) {
+ fstrcpy(fname, params[5]);
+ } else if (!strcmp(params[0],"SMBclose")) {
+ nb_close(atoi(params[3]));
+ } else if (!strcmp(params[0],"SMBmkdir")) {
+ nb_mkdir(params[3]);
+ } else if (!strcmp(params[0],"CREATE")) {
+ nb_create(params[3], atoi(params[5]));
+ } else if (!strcmp(params[0],"SMBrmdir")) {
+ nb_rmdir(params[3]);
+ } else if (!strcmp(params[0],"SMBunlink")) {
+ fstrcpy(fname, params[3]);
+ } else if (!strcmp(params[0],"SMBmv")) {
+ nb_rename(params[3], params[5]);
+ } else if (!strcmp(params[0],"SMBgetatr")) {
+ fstrcpy(fname, params[3]);
+ } else if (!strcmp(params[0],"SMBwrite")) {
+ nb_write(atoi(params[3]),
+ atoi(params[5]), atoi(params[7]));
+ } else if (!strcmp(params[0],"SMBwritebraw")) {
+ nb_write(atoi(params[3]),
+ atoi(params[7]), atoi(params[5]));
+ } else if (!strcmp(params[0],"SMBreadbraw")) {
+ nb_read(atoi(params[3]),
+ atoi(params[7]), atoi(params[5]));
+ } else if (!strcmp(params[0],"SMBread")) {
+ nb_read(atoi(params[3]),
+ atoi(params[5]), atoi(params[7]));
+ }
+ } else {
+ if (!strcmp(params[0],"SMBopenX")) {
+ if (!strncmp(params[2], "ERR", 3)) continue;
+ nb_open(fname, atoi(params[3]), atoi(params[5]));
+ } else if (!strcmp(params[0],"SMBgetatr")) {
+ if (!strncmp(params[2], "ERR", 3)) continue;
+ nb_stat(fname, atoi(params[3]));
+ } else if (!strcmp(params[0],"SMBunlink")) {
+ if (!strncmp(params[2], "ERR", 3)) continue;
+ nb_unlink(fname);
+ }
+ }
+ }
+ fclose(f);
+
+ slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
+ rmdir(fname);
+ rmdir("CLIENTS");
+
+ printf("+");
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ return correct;
+}
+
+
+/* run a test that simulates an approximate netbench w9X client load */
+static BOOL run_nbw95(int dummy)
+{
+ double t;
+ BOOL correct = True;
+ t = create_procs(run_netbench, &correct);
+ /* to produce a netbench result we scale accoding to the
+ netbench measured throughput for the run that produced the
+ sniff that was used to produce client.txt. That run used 2
+ clients and ran for 660 seconds to produce a result of
+ 4MBit/sec. */
+ printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
+ 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
+ return correct;
+}
+
+/* run a test that simulates an approximate netbench wNT client load */
+static BOOL run_nbwnt(int dummy)
+{
+ double t;
+ BOOL correct = True;
+ t = create_procs(run_netbench, &correct);
+ printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
+ 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
+ return correct;
+}
+
+
+
+/*
+ This test checks for two things:
+
+ 1) correct support for retaining locks over a close (ie. the server
+ must not use posix semantics)
+ 2) support for lock timeouts
+ */
+static BOOL run_locktest1(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ char *fname = "\\lockt1.lck";
+ int fnum1, fnum2, fnum3;
+ time_t t1, t2;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting locktest1\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+ fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ if (fnum2 == -1) {
+ printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+ fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+ if (fnum3 == -1) {
+ printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+ return False;
+ }
+
+ if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+
+ if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock2 succeeded! This is a locking bug\n");
+ return False;
+ } else {
+ if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
+ }
+
+
+ printf("Testing lock timeouts\n");
+ t1 = time(NULL);
+ if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
+ printf("lock3 succeeded! This is a locking bug\n");
+ return False;
+ } else {
+ if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
+ }
+ t2 = time(NULL);
+
+ if (t2 - t1 < 5) {
+ printf("error: This server appears not to support timed lock requests\n");
+ }
+
+ if (!cli_close(&cli1, fnum2)) {
+ printf("close1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock4 succeeded! This is a locking bug\n");
+ return False;
+ } else {
+ if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli2, fnum3)) {
+ printf("close3 failed (%s)\n", cli_errstr(&cli2));
+ return False;
+ }
+
+ if (!cli_unlink(&cli1, fname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+
+ if (!close_connection(&cli1)) {
+ return False;
+ }
+
+ if (!close_connection(&cli2)) {
+ return False;
+ }
+
+ printf("Passed locktest1\n");
+ return True;
+}
+
+/*
+ checks for correct tconX support
+ */
+static BOOL run_tcon_test(int dummy)
+{
+ static struct cli_state cli1;
+ char *fname = "\\tcontest.tmp";
+ int fnum1;
+ uint16 cnum;
+ char buf[4];
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+
+ printf("starting tcontest\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1)
+ {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ cnum = cli1.cnum;
+
+ if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
+ {
+ printf("write failed (%s)", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_send_tconX(&cli1, share, "?????",
+ password, strlen(password)+1)) {
+ printf("%s refused 2nd tree connect (%s)\n", host,
+ cli_errstr(&cli1));
+ cli_shutdown(&cli1);
+ return False;
+ }
+
+ if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
+ {
+ printf("write succeeded (%s)", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (cli_close(&cli1, fnum1)) {
+ printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_tdis(&cli1)) {
+ printf("tdis failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ cli1.cnum = cnum;
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!close_connection(&cli1)) {
+ return False;
+ }
+
+ printf("Passed tcontest\n");
+ return True;
+}
+
+
+/*
+ This test checks that
+
+ 1) the server supports multiple locking contexts on the one SMB
+ connection, distinguished by PID.
+
+ 2) the server correctly fails overlapping locks made by the same PID (this
+ goes against POSIX behaviour, which is why it is tricky to implement)
+
+ 3) the server denies unlock requests by an incorrect client PID
+*/
+static BOOL run_locktest2(int dummy)
+{
+ static struct cli_state cli;
+ char *fname = "\\lockt2.lck";
+ int fnum1, fnum2, fnum3;
+ BOOL correct = True;
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ cli_sockopt(&cli, sockops);
+
+ printf("starting locktest2\n");
+
+ cli_unlink(&cli, fname);
+
+ cli_setpid(&cli, 1);
+
+ fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
+
+ fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
+ if (fnum2 == -1) {
+ printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
+
+ cli_setpid(&cli, 2);
+
+ fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
+ if (fnum3 == -1) {
+ printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
+
+ cli_setpid(&cli, 1);
+
+ if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock1 failed (%s)\n", cli_errstr(&cli));
+ return False;
+ }
+
+ if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
+ printf("WRITE lock1 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
+ }
+
+ if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
+ printf("WRITE lock2 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
+ }
+
+ if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
+ printf("READ lock2 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
+ }
+
+ if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
+ printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
+ }
+ cli_setpid(&cli, 2);
+ if (cli_unlock(&cli, fnum1, 100, 4)) {
+ printf("unlock at 100 succeeded! This is a locking bug\n");
+ correct = False;
+ }
+
+ if (cli_unlock(&cli, fnum1, 0, 4)) {
+ printf("unlock1 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
+ }
+
+ if (cli_unlock(&cli, fnum1, 0, 8)) {
+ printf("unlock2 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
+ }
+
+ if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock3 succeeded! This is a locking bug\n");
+ correct = False;
+ } else {
+ if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
+ }
+
+ cli_setpid(&cli, 1);
+
+ if (!cli_close(&cli, fnum1)) {
+ printf("close1 failed (%s)\n", cli_errstr(&cli));
+ return False;
+ }
+
+ if (!cli_close(&cli, fnum2)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli));
+ return False;
+ }
+
+ if (!cli_close(&cli, fnum3)) {
+ printf("close3 failed (%s)\n", cli_errstr(&cli));
+ return False;
+ }
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("locktest2 finished\n");
+
+ return correct;
+}
+
+
+/*
+ This test checks that
+
+ 1) the server supports the full offset range in lock requests
+*/
+static BOOL run_locktest3(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ char *fname = "\\lockt3.lck";
+ int fnum1, fnum2, i;
+ uint32 offset;
+ BOOL correct = True;
+
+#define NEXT_OFFSET offset += (~(uint32)0) / numops
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting locktest3\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+ fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+ if (fnum2 == -1) {
+ printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+ return False;
+ }
+
+ for (offset=i=0;i<numops;i++) {
+ NEXT_OFFSET;
+ if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
+ printf("lock1 %d failed (%s)\n",
+ i,
+ cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
+ printf("lock2 %d failed (%s)\n",
+ i,
+ cli_errstr(&cli1));
+ return False;
+ }
+ }
+
+ for (offset=i=0;i<numops;i++) {
+ NEXT_OFFSET;
+
+ if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
+ printf("error: lock1 %d succeeded!\n", i);
+ return False;
+ }
+
+ if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
+ printf("error: lock2 %d succeeded!\n", i);
+ return False;
+ }
+
+ if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
+ printf("error: lock3 %d succeeded!\n", i);
+ return False;
+ }
+
+ if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
+ printf("error: lock4 %d succeeded!\n", i);
+ return False;
+ }
+ }
+
+ for (offset=i=0;i<numops;i++) {
+ NEXT_OFFSET;
+
+ if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
+ printf("unlock1 %d failed (%s)\n",
+ i,
+ cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
+ printf("unlock2 %d failed (%s)\n",
+ i,
+ cli_errstr(&cli1));
+ return False;
+ }
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli2, fnum2)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli2));
+ return False;
+ }
+
+ if (!cli_unlink(&cli1, fname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+
+ if (!close_connection(&cli2)) {
+ correct = False;
+ }
+
+ printf("finished locktest3\n");
+
+ return correct;
+}
+
+#define EXPECTED(ret, v) if ((ret) != (v)) { \
+ printf("** "); correct = False; \
+ }
+
+/*
+ looks at overlapping locks
+*/
+static BOOL run_locktest4(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ char *fname = "\\lockt4.lck";
+ int fnum1, fnum2, f;
+ BOOL ret;
+ char buf[1000];
+ BOOL correct = True;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting locktest4\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+
+ memset(buf, 0, sizeof(buf));
+
+ if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+ printf("Failed to create file\n");
+ correct = False;
+ goto fail;
+ }
+
+ ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
+ EXPECTED(ret, False);
+ printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
+ EXPECTED(ret, True);
+ printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
+ EXPECTED(ret, False);
+ printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
+ cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
+ EXPECTED(ret, True);
+ printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
+
+ ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
+ (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
+ EXPECTED(ret, False);
+ printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
+
+ ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
+ (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
+ EXPECTED(ret, True);
+ printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
+ EXPECTED(ret, True);
+ printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
+ EXPECTED(ret, False);
+ printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
+ EXPECTED(ret, False);
+ printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
+ EXPECTED(ret, True);
+ printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
+
+ ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
+ (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
+ EXPECTED(ret, False);
+ printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
+ cli_unlock(&cli1, fnum1, 110, 6);
+ EXPECTED(ret, False);
+ printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
+
+
+ ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
+ (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
+ EXPECTED(ret, False);
+ printf("this server %s strict write locking\n", ret?"doesn't do":"does");
+
+ ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
+ (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
+ EXPECTED(ret, False);
+ printf("this server %s strict read locking\n", ret?"doesn't do":"does");
+
+
+ ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
+ cli_unlock(&cli1, fnum1, 140, 4) &&
+ cli_unlock(&cli1, fnum1, 140, 4);
+ EXPECTED(ret, True);
+ printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
+
+
+ ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
+ cli_unlock(&cli1, fnum1, 150, 4) &&
+ (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
+ !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
+ cli_unlock(&cli1, fnum1, 150, 4);
+ EXPECTED(ret, True);
+ printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
+
+ ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
+ cli_unlock(&cli1, fnum1, 160, 4) &&
+ (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
+ (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
+ EXPECTED(ret, True);
+ printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
+ cli_unlock(&cli1, fnum1, 170, 4) &&
+ (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
+ (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
+ EXPECTED(ret, True);
+ printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
+ cli_unlock(&cli1, fnum1, 190, 4) &&
+ !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
+ (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
+ EXPECTED(ret, True);
+ printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
+
+ cli_close(&cli1, fnum1);
+ cli_close(&cli2, fnum2);
+ fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
+ cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
+ cli_close(&cli1, fnum1) &&
+ ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
+ cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
+ cli_close(&cli1, f);
+ EXPECTED(ret, True);
+ printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
+
+ fail:
+ cli_close(&cli1, fnum1);
+ cli_close(&cli2, fnum2);
+ cli_unlink(&cli1, fname);
+ close_connection(&cli1);
+ close_connection(&cli2);
+
+ printf("finished locktest4\n");
+ return correct;
+}
+
+/*
+ looks at lock upgrade/downgrade.
+*/
+static BOOL run_locktest5(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ char *fname = "\\lockt5.lck";
+ int fnum1, fnum2, fnum3;
+ BOOL ret;
+ char buf[1000];
+ BOOL correct = True;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting locktest5\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+ fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+
+ memset(buf, 0, sizeof(buf));
+
+ if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+ printf("Failed to create file\n");
+ correct = False;
+ goto fail;
+ }
+
+ /* Check for NT bug... */
+ ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
+ cli_close(&cli1, fnum1);
+ fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
+ EXPECTED(ret, True);
+ printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
+ cli_close(&cli1, fnum1);
+ fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ cli_unlock(&cli1, fnum3, 0, 1);
+
+ ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
+ cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
+ EXPECTED(ret, True);
+ printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
+
+ ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
+ EXPECTED(ret, False);
+
+ printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
+
+ /* Unlock the process 2 lock. */
+ cli_unlock(&cli2, fnum2, 0, 4);
+
+ ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
+ EXPECTED(ret, False);
+
+ printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
+
+ /* Unlock the process 1 fnum3 lock. */
+ cli_unlock(&cli1, fnum3, 0, 4);
+
+ /* Stack 2 more locks here. */
+ ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
+ cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
+
+ EXPECTED(ret, True);
+ printf("the same process %s stack read locks\n", ret?"can":"cannot");
+
+ /* Unlock the first process lock, then check this was the WRITE lock that was
+ removed. */
+
+ ret = cli_unlock(&cli1, fnum1, 0, 4) &&
+ cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
+
+ EXPECTED(ret, True);
+ printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
+
+ /* Unlock the process 2 lock. */
+ cli_unlock(&cli2, fnum2, 0, 4);
+
+ /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
+
+ ret = cli_unlock(&cli1, fnum1, 1, 1) &&
+ cli_unlock(&cli1, fnum1, 0, 4) &&
+ cli_unlock(&cli1, fnum1, 0, 4);
+
+ EXPECTED(ret, True);
+ printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
+
+ /* Ensure the next unlock fails. */
+ ret = cli_unlock(&cli1, fnum1, 0, 4);
+ EXPECTED(ret, False);
+ printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
+
+ /* Ensure connection 2 can get a write lock. */
+ ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
+ EXPECTED(ret, True);
+
+ printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
+
+
+ fail:
+ cli_close(&cli1, fnum1);
+ cli_close(&cli2, fnum2);
+ cli_unlink(&cli1, fname);
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+ if (!close_connection(&cli2)) {
+ correct = False;
+ }
+
+ printf("finished locktest5\n");
+
+ return correct;
+}
+
+
+/*
+ this produces a matrix of deny mode behaviour
+ */
+static BOOL run_denytest1(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ int fnum1, fnum2;
+ int f, d1, d2, o1, o2, x=0;
+ char *fnames[] = {"\\denytest1.exe", "\\denytest1.dat", NULL};
+ struct {
+ int v;
+ char *name;
+ } deny_modes[] = {
+ {DENY_DOS, "DENY_DOS"},
+ {DENY_ALL, "DENY_ALL"},
+ {DENY_WRITE, "DENY_WRITE"},
+ {DENY_READ, "DENY_READ"},
+ {DENY_NONE, "DENY_NONE"},
+ {DENY_FCB, "DENY_FCB"},
+ {-1, NULL}};
+ struct {
+ int v;
+ char *name;
+ } open_modes[] = {
+ {O_RDWR, "O_RDWR"},
+ {O_RDONLY, "O_RDONLY"},
+ {O_WRONLY, "O_WRONLY"},
+ {-1, NULL}};
+ BOOL correct = True;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting denytest1\n");
+
+ for (f=0;fnames[f];f++) {
+ cli_unlink(&cli1, fnames[f]);
+
+ fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
+ cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
+ cli_close(&cli1, fnum1);
+
+ for (d1=0;deny_modes[d1].name;d1++)
+ for (o1=0;open_modes[o1].name;o1++)
+ for (d2=0;deny_modes[d2].name;d2++)
+ for (o2=0;open_modes[o2].name;o2++) {
+ fnum1 = cli_open(&cli1, fnames[f],
+ open_modes[o1].v,
+ deny_modes[d1].v);
+ fnum2 = cli_open(&cli2, fnames[f],
+ open_modes[o2].v,
+ deny_modes[d2].v);
+
+ printf("%s %8s %10s %8s %10s ",
+ fnames[f],
+ open_modes[o1].name,
+ deny_modes[d1].name,
+ open_modes[o2].name,
+ deny_modes[d2].name);
+
+ if (fnum1 == -1) {
+ printf("X");
+ } else if (fnum2 == -1) {
+ printf("-");
+ } else {
+ if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
+ printf("R");
+ }
+ if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ printf("W");
+ }
+ }
+
+ printf("\n");
+ cli_close(&cli1, fnum1);
+ cli_close(&cli2, fnum2);
+ }
+
+ cli_unlink(&cli1, fnames[f]);
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+ if (!close_connection(&cli2)) {
+ correct = False;
+ }
+
+ printf("finshed denytest1\n");
+ return correct;
+}
+
+
+/*
+ this produces a matrix of deny mode behaviour for two opens on the
+ same connection
+ */
+static BOOL run_denytest2(int dummy)
+{
+ static struct cli_state cli1;
+ int fnum1, fnum2;
+ int f, d1, d2, o1, o2, x=0;
+ char *fnames[] = {"\\denytest2.exe", "\\denytest2.dat", NULL};
+ struct {
+ int v;
+ char *name;
+ } deny_modes[] = {
+ {DENY_DOS, "DENY_DOS"},
+ {DENY_ALL, "DENY_ALL"},
+ {DENY_WRITE, "DENY_WRITE"},
+ {DENY_READ, "DENY_READ"},
+ {DENY_NONE, "DENY_NONE"},
+ {DENY_FCB, "DENY_FCB"},
+ {-1, NULL}};
+ struct {
+ int v;
+ char *name;
+ } open_modes[] = {
+ {O_RDWR, "O_RDWR"},
+ {O_RDONLY, "O_RDONLY"},
+ {O_WRONLY, "O_WRONLY"},
+ {-1, NULL}};
+ BOOL correct = True;
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+
+ printf("starting denytest2\n");
+
+ for (f=0;fnames[f];f++) {
+ cli_unlink(&cli1, fnames[f]);
+
+ fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
+ cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
+ cli_close(&cli1, fnum1);
+
+ for (d1=0;deny_modes[d1].name;d1++)
+ for (o1=0;open_modes[o1].name;o1++)
+ for (d2=0;deny_modes[d2].name;d2++)
+ for (o2=0;open_modes[o2].name;o2++) {
+ fnum1 = cli_open(&cli1, fnames[f],
+ open_modes[o1].v,
+ deny_modes[d1].v);
+ fnum2 = cli_open(&cli1, fnames[f],
+ open_modes[o2].v,
+ deny_modes[d2].v);
+
+ printf("%s %8s %10s %8s %10s ",
+ fnames[f],
+ open_modes[o1].name,
+ deny_modes[d1].name,
+ open_modes[o2].name,
+ deny_modes[d2].name);
+
+ if (fnum1 == -1) {
+ printf("X");
+ } else if (fnum2 == -1) {
+ printf("-");
+ } else {
+ if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
+ printf("R");
+ }
+ if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ printf("W");
+ }
+ }
+
+ printf("\n");
+ cli_close(&cli1, fnum1);
+ cli_close(&cli1, fnum2);
+ }
+
+ cli_unlink(&cli1, fnames[f]);
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+
+ printf("finshed denytest2\n");
+ return correct;
+}
+
+/*
+test whether fnums and tids open on one VC are available on another (a major
+security hole)
+*/
+static BOOL run_fdpasstest(int dummy)
+{
+ static struct cli_state cli1, cli2, cli3;
+ char *fname = "\\fdpass.tst";
+ int fnum1;
+ pstring buf;
+
+ if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ return False;
+ }
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ printf("starting fdpasstest\n");
+
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
+ printf("write failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ cli3 = cli2;
+ cli3.vuid = cli1.vuid;
+ cli3.cnum = cli1.cnum;
+ cli3.pid = cli1.pid;
+
+ if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
+ printf("read succeeded! nasty security hole [%s]\n",
+ buf);
+ return False;
+ }
+
+ cli_close(&cli1, fnum1);
+ cli_unlink(&cli1, fname);
+
+ close_connection(&cli1);
+ close_connection(&cli2);
+
+ printf("finished fdpasstest\n");
+ return True;
+}
+
+/*test multiple users over a single tcp connection*/
+/*test multiple users over a single tcp connection ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/*test multiple users over a single tcp connection*/
+
+
+typedef struct subtaboid {
+
+ struct subtaboid *next;
+
+ BOOL status;
+ fstring name;
+ fstring op_error;
+ fstring sys_error;
+
+} SUBTABOID;
+
+typedef struct taboid {
+
+ int owner, share, as_user;
+
+ void *arg;
+
+ SUBTABOID *subtaboids[2];
+
+} TABOID;
+
+static void init_TABOID(TABOID *t, int owner, int share, int as_user)
+{
+ memset( t, '\0', sizeof(*t));
+ t->owner = owner;
+ t->share = share;
+ t->as_user = as_user;
+}
+
+static BOOL run_vusertest_op_null(TABOID *t)
+{
+ return True;
+}
+
+static BOOL run_vusertest_report_full(
+ const char *operation,
+ const char *sub_operation,
+ BOOL failure,
+ BOOL report,
+ fstring *buf,
+ TABOID *t)
+{
+
+ (*buf)[0] = '\0';
+
+ snprintf(*buf,
+ sizeof(*buf),
+ "%8s[%s]:%10s file %10s user %10s(%5d). share %10s tid %5d owner %10s(%5d). fnum %5d was %5d (%s).",
+ operation,
+ failure?"FAILURE":"SUCCESS",
+ sub_operation,
+ vusers[t->owner].fname,
+ vusers[t->as_user].username,
+ /*vusers[t->as_user].vuid,*/
+ vusers[t->as_user].cli.vuid,
+ shares[t->share],
+ /*vusers[t->owner].per_tid[t->share].tid,*/
+ vusers[t->as_user].cli.cnum,
+ vusers[t->owner].username,
+ /*vusers[t->owner].vuid,*/
+ vusers[t->owner].cli.vuid,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner],
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner],
+ failure?cli_errstr(&vusers[t->as_user].cli):""
+ );
+
+ if(report)
+ printf("%s\n", *buf);
+
+ return True;
+}
+
+static BOOL run_vusertest_report(
+ const char *operation,
+ const char *sub_operation,
+ BOOL failure,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, failure, True, &buf, t);
+}
+
+static BOOL run_vusertest_report_failure(
+ const char *operation,
+ const char *sub_operation,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, True, True, &buf, t);
+}
+
+static BOOL run_vusertest_report_success(
+ const char *operation,
+ const char *sub_operation,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, False, True, &buf, t);
+}
+
+static BOOL run_vusertest_op_init(TABOID *t)
+{
+
+ int i, j;
+
+ vusers[t->owner].fname[0] = '\0';
+
+ vusers[t->owner].vuid = 0;
+ vusers[t->owner].vuid_valid = False;
+ vusers[t->owner].files_valid = False;
+
+ for(i = 0; i < sizeof(vusers[t->owner].per_tid)/sizeof(vusers[t->owner].per_tid[0]); i++) {
+
+ vusers[t->owner].per_tid[i].tid = 0;
+ vusers[t->owner].per_tid[i].tid_valid = False;
+
+ for(j = 0; j < sizeof(vusers[t->owner].per_tid[i].fnum)/sizeof(vusers[t->owner].per_tid[i].fnum[0]); j++) {
+
+ vusers[t->owner].per_tid[i].fnum[j] = vusers[t->owner].per_tid[i].backup_fnum[j] = -1;
+ }
+ }
+
+ return True;
+}
+
+static BOOL run_vusertest_op_create(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+ snprintf(vusers[t->owner].fname, sizeof(vusers[t->owner].fname), "muserconn_%d", t->owner);
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(!cli_unlink(&vusers[t->as_user].cli, vusers[t->owner].fname)) {
+
+ run_vusertest_report_failure("CREATE", "unlink", t);
+
+ return should_work?False:True;
+ }
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] =
+ cli_open(&vusers[t->as_user].cli, vusers[t->owner].fname, O_RDWR|O_CREAT, DENY_NONE);
+
+ if (vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1) {
+
+ run_vusertest_report_failure("CREATE", "create", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("CREATE", "created", t);
+
+ vusers[t->as_user].files_valid = True; /*not true for all!*/
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_write(TABOID *t)
+{
+
+ BOOL should_work = (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid
+ );
+
+ fstring msg;
+ int msglen;
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ run_vusertest_report_full("WRITE", "write 2", False, False, &msg, t);
+
+ msglen = strlen(msg)+1;
+
+ if (cli_write(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], 0, (char *)&msglen, 0, sizeof(msglen)) != sizeof(msglen)) {
+
+ run_vusertest_report_failure("WRITE", "write 1", t);
+
+ return should_work?False:True;
+ }
+
+ if (cli_write(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], 0, msg, sizeof(msglen), msglen) != msglen) {
+
+ run_vusertest_report_failure("WRITE", "write 2", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("WRITE", "write", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_create_and_write(TABOID *t)
+{
+
+ BOOL ret = True;
+
+ if(!run_vusertest_op_create(t)) {
+
+ ret = False;
+ }
+
+ if(!run_vusertest_op_write(t)) {
+
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_openr(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] =
+ cli_open(&vusers[t->as_user].cli, vusers[t->owner].fname, O_RDONLY, DENY_NONE);
+
+ if (vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1) {
+
+ run_vusertest_report_failure("OPENR", "open", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("OPENR", "open", t);
+
+ vusers[t->as_user].files_valid = True; /*not true for all!*/
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_read(TABOID *t)
+{
+
+ fstring msg;
+ int msglen = 0;
+
+ BOOL should_work = (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid &&
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] != -1
+ );
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if (cli_read(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], (char *)&msglen, 0, sizeof(msglen)) != sizeof(msglen)) {
+
+ run_vusertest_report_failure("READ", "read 1", t);
+
+ return should_work?False:True;
+ }
+
+ if (cli_read(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], msg, sizeof(msglen), msglen) != msglen) {
+
+ run_vusertest_report_failure("READ", "read 2", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("READ", "read", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_openr_and_read(TABOID *t)
+{
+
+ BOOL ret = True;
+
+ if(!run_vusertest_op_openr(t)) {
+
+ ret = False;
+ }
+
+ if(!run_vusertest_op_read(t)) {
+
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_backup_open_fids(TABOID *t)
+{
+
+ memcpy(vusers[t->as_user].per_tid[t->share].backup_fnum,
+ vusers[t->as_user].per_tid[t->share].fnum,
+ sizeof(vusers[t->as_user].per_tid[t->share].fnum));
+
+ return True;
+}
+
+static BOOL run_vusertest_op_close(TABOID *t)
+{
+
+ BOOL should_work = (
+ (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid
+ )
+ ||
+ (
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1 &&
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] == -1
+ )
+ );
+
+ BOOL ret = should_work?True:False;
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(vusers[t->as_user].per_tid[t->share].fnum[t->owner] != -1) {
+
+ if(!cli_close(&vusers[t->as_user].cli, vusers[t->as_user].per_tid[t->share].fnum[t->owner])) {
+
+ run_vusertest_report_failure("CLOSE", "close", t);
+
+ ret = should_work?False:True;
+ } else {
+
+ run_vusertest_report_success("CLOSE", "close", t);
+ }
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] = -1;
+ }
+
+ if(vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] != -1 &&
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] != 0) {
+
+ if(!cli_close(&vusers[t->as_user].cli, vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner])) {
+
+ run_vusertest_report_failure("CLOSE", "close backup", t);
+
+ ret = should_work?False:True;
+
+ } else {
+
+ run_vusertest_report_success("CLOSE", "close backup", t);
+ }
+
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] = -1;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_tcon(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->as_user].vuid_valid);
+
+ vusers[t->owner].per_tid[t->share].tid_valid = False;
+
+ if (!cli_send_tconX(&vusers[t->as_user].cli,
+ shares[t->share],
+ "?????",
+ vusers[t->as_user].password,
+ strlen(vusers[t->as_user].password)+1)) {
+
+ run_vusertest_report_failure("TCON", "tcon", t);
+
+ return should_work?False:True;
+ }
+
+ vusers[t->owner].per_tid[t->share].tid_valid = True;
+ vusers[t->owner].per_tid[t->share].tid = vusers[t->as_user].cli.cnum;
+
+ run_vusertest_report_success("TCON", "tcon", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_tdis(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+#if 0
+ if(!vusers[t->owner].per_tid[t->share].tid_valid) {
+
+ return True;
+ }
+#endif
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(!cli_tdis(&vusers[t->as_user].cli)) {
+
+ run_vusertest_report_failure("TDIS", "tdis", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("TDIS", "tdis", t);
+
+ vusers[t->owner].per_tid[t->share].tid_valid = False;
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_ulogon(TABOID *t)
+{
+
+ vusers[t->owner].cli = *seed;
+
+ vusers[t->owner].vuid_valid = False;
+
+ if (!cli_session_setup(&vusers[t->owner].cli,
+ vusers[t->owner].username,
+ vusers[t->owner].password,
+ strlen(vusers[t->owner].password),
+ vusers[t->owner].password,
+ strlen(vusers[t->owner].password),
+ workgroup)) {
+
+
+ run_vusertest_report_failure("ULOGON", "logon", t);
+
+ return False;
+ }
+
+ run_vusertest_report_success("ULOGON", "logon", t);
+
+ vusers[t->owner].vuid_valid = True;
+ vusers[t->owner].vuid = vusers[t->owner].cli.vuid;
+
+ return True;
+}
+
+static BOOL run_vusertest_op_ulogoff(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].vuid_valid);
+
+#if 0
+ if(!vusers[t->owner].vuid_valid) {
+
+ return True;
+ }
+#endif
+
+ if(!cli_ulogoff(&vusers[t->owner].cli)) {
+
+ run_vusertest_report_failure("ULOGOFF", "logoff", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("ULOGOFF", "logoff", t);
+
+ vusers[t->owner].vuid_valid = False;
+ vusers[t->owner].files_valid = False;
+
+ return should_work?True:False;
+}
+
+/***********************************************************/
+/***********************************************************/
+
+static BOOL run_vusertest_owner_op(BOOL (*op)(TABOID *t))
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ TABOID t;
+ init_TABOID(&t, owner, 0, owner);
+
+ if(!op(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_op(BOOL (*op)(TABOID *t))
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!op(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_preop_user_op(
+ BOOL (*preop)(TABOID *t),
+ BOOL (*op)(TABOID *t),
+ BOOL (*postop)(TABOID *t)
+ )
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!preop(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ for(t.as_user = 0; t.as_user < nusers; t.as_user++) {
+
+ if(!op(&t)) {
+
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+
+ t.as_user = owner;
+
+ if(!postop(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_user_preop_op(
+ BOOL (*preop)(TABOID *t),
+ BOOL (*op)(TABOID *t),
+ BOOL (*postop)(TABOID *t)
+ )
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ int as_user = 0;
+
+ for(; as_user < nusers; as_user++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!preop(&t)) {
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ t.as_user = as_user;
+
+ if(!op(&t)) {
+
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ t.as_user = owner;
+
+ if(!postop(&t)) {
+
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*user applies op*/
+
+#define VU_INIT (run_vusertest_owner_op(run_vusertest_op_init))
+
+#define VU_ULOGON (run_vusertest_owner_op(run_vusertest_op_ulogon))
+#define VU_ULOGOFF (run_vusertest_owner_op(run_vusertest_op_ulogoff))
+
+/*each user applies op to each of their shares*/
+
+#define VU_TCON (run_vusertest_owner_share_op(run_vusertest_op_tcon))
+#define VU_TDIS (run_vusertest_owner_share_op(run_vusertest_op_tdis))
+
+#define VU_CREATE_AND_WRITE (run_vusertest_owner_share_op(run_vusertest_op_create_and_write))
+#define VU_OPEN_AND_READ (run_vusertest_owner_share_op(run_vusertest_op_openr_and_read))
+#define VU_READ (run_vusertest_owner_share_op(run_vusertest_op_read))
+#define VU_FCLOSE (run_vusertest_owner_share_op(run_vusertest_op_close))
+#define VU_BACKUP_FIDS (run_vusertest_owner_share_op(run_vusertest_op_backup_open_fids))
+
+/*for u1 for u2 apply op as u2 on u1's tid*/
+
+#define VU_CROSS_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_read,\
+ run_vusertest_op_null))
+#define VU_CROSS_OPEN_AND_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_openr_and_read,\
+ run_vusertest_op_null))
+#define VU_CROSS_FCLOSE (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_close,\
+ run_vusertest_op_null))
+
+#define VU_TCON_TDIS_OPEN_AND_READ (run_vusertest_owner_share_user_preop_op(run_vusertest_op_tcon,\
+ run_vusertest_op_tdis,\
+ run_vusertest_op_openr_and_read))
+
+
+
+/*
+ Check relationship between:
+
+ files open
+
+ session logoff (Samba closes all files for vuid)
+
+ tree disconnection (Samba set conn->used to False then calls close_cnum(conn, vuid), this flushes dir cache, closes files on the conn, frees the conn structure)
+
+ 1. can a user access a tid connected by another
+
+ for u1 {
+ for u2 {
+ u2 opens file on u1's tid
+ }
+ }
+
+ 2. can one user disconnect a tid connected by another
+
+ for u1 {
+ for u2 {
+ connect u1's tid as u1
+ disconnect u1's tid as u2;
+ open and read files as u1
+ }
+}
+
+ 2a. does a disconnect by another invalidate the tid for the original connector
+
+ 3. does a disconnect invalidate a tid with no files open on it
+
+ close files
+ for u1 {
+ disconnect u1's tid
+ open and read files on u1's tid
+ }
+
+ 4. does a disconnect invalidate a tid with files open on it
+
+ open files
+ for u1 {
+ disconnect u1's tid
+ open and read files on u1's tid as u1
+ }
+
+ 5. does a disconnect invalidate files open on a tid.
+
+ open files
+ for u1 {
+ disconnect u1's tid
+ read files on u1's tid as u1
+ }
+
+ 6. can a user session exist with no tid and no open files
+
+ close files
+ for u1 {
+
+ disconnect u1's tid
+ }
+
+ for u1 {
+
+ reconnect u1's tid
+ }
+
+
+ 7. does a logoff invalidate a tid with no files open on it
+
+ close files
+ for u1 {
+ logoff u1
+ open and read files on u1's tid
+ }
+
+ close files
+ for u1 {
+ logon u1
+ open and read files on u1's tid
+ }
+
+ 8. does a logoff invalidate a tid with files open on it
+
+ open files
+ for u1 {
+ logoff u1
+ open and read files on u1's tid
+ }
+
+ for u1 {
+ logon u1
+ open and read files on u1's tid
+ }
+
+ 9. does a logoff invalidate a fid.
+
+ open files
+ for u1 {
+ logoff u1
+ read files on u1's tid
+ }
+
+ for u1 {
+ logon u1
+ read files on u1's tid
+ }
+
+
+ 10. does a logoff invalidate a vuid.
+
+ see 8
+
+ 11. can a connection survive close files, close tids, logoff users
+
+ close files
+ for u1 {
+ disconnect u1's tids
+ logoff u1
+ }
+
+ for u1 {
+ logon u1
+ reconnect u1's tids
+ open and read
+ }
+
+
+
+*/
+
+static BOOL run_vusertest(int dummy)
+{
+ BOOL ret = True;
+
+ int testcnt = 0;
+
+ seed = &vusers[0].cli;
+
+ ZERO_STRUCTP(seed);
+
+ printf("\nopen nbt connection\n");
+
+ if (!open_nbt_connection(seed)) {
+
+ return False;
+ }
+
+ cli_sockopt(seed, sockops);
+
+ printf("\nnegotiate protocol\n");
+
+ /*the CIFS spec says this should be done only once on a VC and W2K doesn't like it more than once. Samba doesn't mind*/
+
+ if (!cli_negprot(seed)) {
+ printf("%s rejected the negprot (%s)\n",host, cli_errstr(seed));
+ cli_shutdown(seed);
+ return False;
+ }
+
+ printf("\nnegotiate protocol again.\n");
+
+ if (!cli_negprot(seed)) {
+
+ printf("%s rejected a second negprot (%s)\n",host, cli_errstr(seed));
+
+ printf("\nshutdown client\n");
+
+ cli_shutdown(seed);
+
+ ZERO_STRUCTP(seed);
+
+ printf("\nopen new nbt session\n");
+
+ if (!open_nbt_connection(seed)) {
+
+ return False;
+ }
+
+ cli_sockopt(seed, sockops);
+
+ printf("\nre negotiate protocol\n");
+
+ if (!cli_negprot(seed)) {
+ printf("%s rejected the negprot (%s)\n",host, cli_errstr(seed));
+ cli_shutdown(seed);
+ return False;
+ }
+ }
+
+ printf("starting vusertest with %d users and %d shares.\n", nusers, nshares);
+
+ /***********************************************************/
+ /***********************************************************/
+
+ printf("\ninitialise\n\n");
+
+ if(!VU_INIT) {
+
+ printf("initialisation failed.\n");
+ return False;
+ }
+
+ printf("\nsetup sessions\n\n");
+
+ if(!VU_ULOGON) {
+
+ printf("setup sessions failed.\n");
+ return False;
+ }
+
+ printf("\nconnect to shares\n\n");
+
+ if(!VU_TCON) {
+
+ printf("connect to shares failed.\n");
+ return False;
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+
+ {
+ char *test = "create and write files";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_CREATE_AND_WRITE) {
+
+ printf("%s failed.\n", test);
+ return False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can a user access a tid connected by another?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_CROSS_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can one user disconnect a tid connected by another.\n2a does disconnect by another invalidate tid for all?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_TCON_TDIS_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate a tid with no files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate a tid with files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate files open on a tid?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "can a user session exist with no tid and no open files?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a logoff invalidate a tid with no files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "does a logoff invalidate a tid with files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "does a logoff invalidate a fid?";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ printf("\nTEST:%d does a logoff invalidate a vuid? see 8.\n\n", testcnt);
+
+ testcnt++;
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can a connection survive close files, disconnect tids, logoff users?";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "clean up.";
+ BOOL tret = True;
+
+ printf("\nTEST:%s\n\n", test);
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ cli_shutdown(seed);
+
+ printf("finished vusertest.\n");
+ return ret;
+}
+
+/*
+ This test checks that
+
+ 1) the server does not allow an unlink on a file that is open
+*/
+static BOOL run_unlinktest(int dummy)
+{
+ static struct cli_state cli;
+ char *fname = "\\unlink.tst";
+ int fnum;
+ BOOL correct = True;
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ cli_sockopt(&cli, sockops);
+
+ printf("starting unlink test\n");
+
+ cli_unlink(&cli, fname);
+
+ cli_setpid(&cli, 1);
+
+ fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
+
+ if (cli_unlink(&cli, fname)) {
+ printf("error: server allowed unlink on an open file\n");
+ correct = False;
+ }
+
+ cli_close(&cli, fnum);
+ cli_unlink(&cli, fname);
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("unlink test finished\n");
+
+ return correct;
+}
+
+
+/*
+test how many open files this server supports on the one socket
+*/
+static BOOL run_maxfidtest(int dummy)
+{
+ static struct cli_state cli;
+ char *template = "\\maxfid.%d.%d";
+ fstring fname;
+ int fnum;
+ int retries=4;
+ BOOL correct = True;
+
+ cli = current_cli;
+
+ if (retries <= 0) {
+ printf("failed to connect\n");
+ return False;
+ }
+
+ cli_sockopt(&cli, sockops);
+
+ fnum = 0;
+ while (1) {
+ slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
+ if (cli_open(&cli, fname,
+ O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
+ -1) {
+ printf("open of %s failed (%s)\n",
+ fname, cli_errstr(&cli));
+ printf("maximum fnum is %d\n", fnum);
+ break;
+ }
+ fnum++;
+ if (fnum % 100 == 0) printf("%d\r", fnum);
+ }
+ printf("%d\n", fnum);
+
+ printf("cleaning up\n");
+ while (fnum > 0) {
+ fnum--;
+ slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
+ cli_close(&cli, fnum);
+ if (!cli_unlink(&cli, fname)) {
+ printf("unlink of %s failed (%s)\n",
+ fname, cli_errstr(&cli));
+ correct = False;
+ }
+ }
+
+ printf("maxfid test finished\n");
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+ return correct;
+}
+
+/* generate a random buffer */
+static void rand_buf(char *buf, int len)
+{
+ while (len--) {
+ *buf = (char)sys_random();
+ buf++;
+ }
+}
+
+/* send smb negprot commands, not reading the response */
+static BOOL run_negprot_nowait(int dummy)
+{
+ int i;
+ static struct cli_state cli;
+ BOOL correct = True;
+
+ printf("starting negprot nowait test\n");
+
+ if (!open_nbt_connection(&cli)) {
+ return False;
+ }
+
+ for (i=0;i<50000;i++) {
+ cli_negprot_send(&cli);
+ }
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("finished negprot nowait test\n");
+
+ return correct;
+}
+
+
+/* send random IPC commands */
+static BOOL run_randomipc(int dummy)
+{
+ char *rparam = NULL;
+ char *rdata = NULL;
+ int rdrcnt,rprcnt;
+ pstring param;
+ int api, param_len, i;
+ static struct cli_state cli;
+ BOOL correct = True;
+
+ printf("starting random ipc test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ for (i=0;i<50000;i++) {
+ api = sys_random() % 500;
+ param_len = (sys_random() % 64);
+
+ rand_buf(param, param_len);
+
+ SSVAL(param,0,api);
+
+ cli_api(&cli,
+ param, param_len, 8,
+ NULL, 0, BUFFER_SIZE,
+ &rparam, &rprcnt,
+ &rdata, &rdrcnt);
+ }
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("finished random ipc test\n");
+
+ return correct;
+}
+
+
+
+static void browse_callback(const char *sname, uint32 stype,
+ const char *comment, void *state)
+{
+ printf("\t%20.20s %08x %s\n", sname, stype, comment);
+}
+
+
+
+/*
+ This test checks the browse list code
+
+*/
+static BOOL run_browsetest(int dummy)
+{
+ static struct cli_state cli;
+ BOOL correct = True;
+
+ printf("starting browse test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ printf("domain list:\n");
+ cli_NetServerEnum(&cli, cli.server_domain,
+ SV_TYPE_DOMAIN_ENUM,
+ browse_callback, NULL);
+
+ printf("machine list:\n");
+ cli_NetServerEnum(&cli, cli.server_domain,
+ SV_TYPE_ALL,
+ browse_callback, NULL);
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("browse test finished\n");
+
+ return correct;
+
+}
+
+
+/*
+ This checks how the getatr calls works
+*/
+static BOOL run_attrtest(int dummy)
+{
+ static struct cli_state cli;
+ int fnum;
+ time_t t, t2;
+ char *fname = "\\attrib.tst";
+ BOOL correct = True;
+
+ printf("starting attrib test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ cli_unlink(&cli, fname);
+ fnum = cli_open(&cli, fname,
+ O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ cli_close(&cli, fnum);
+ if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
+ printf("getatr failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ }
+
+ if (abs(t - time(NULL)) > 2) {
+ printf("ERROR: SMBgetatr bug. time is %s",
+ ctime(&t));
+ t = time(NULL);
+ correct = True;
+ }
+
+ t2 = t-60*60*24; /* 1 day ago */
+
+ if (!cli_setatr(&cli, fname, 0, t2)) {
+ printf("setatr failed (%s)\n", cli_errstr(&cli));
+ correct = True;
+ }
+
+ if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
+ printf("getatr failed (%s)\n", cli_errstr(&cli));
+ correct = True;
+ }
+
+ if (t != t2) {
+ printf("ERROR: getatr/setatr bug. times are\n%s",
+ ctime(&t));
+ printf("%s", ctime(&t2));
+ correct = True;
+ }
+
+ cli_unlink(&cli, fname);
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("attrib test finished\n");
+
+ return correct;
+}
+
+
+/*
+ This checks a couple of trans2 calls
+*/
+static BOOL run_trans2test(int dummy)
+{
+ static struct cli_state cli;
+ int fnum;
+ size_t size;
+ time_t c_time, a_time, m_time, w_time, m_time2;
+ char *fname = "\\trans2.tst";
+ char *dname = "\\trans2";
+ char *fname2 = "\\trans2\\trans2.tst";
+ BOOL correct = True;
+
+ printf("starting trans2 test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ cli_unlink(&cli, fname);
+ fnum = cli_open(&cli, fname,
+ O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
+ NULL, NULL)) {
+ printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ }
+ cli_close(&cli, fnum);
+
+ sleep(2);
+
+ cli_unlink(&cli, fname);
+ fnum = cli_open(&cli, fname,
+ O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ if (fnum == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
+ cli_close(&cli, fnum);
+
+ if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
+ printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ } else {
+ if (c_time != m_time) {
+ printf("create time=%s", ctime(&c_time));
+ printf("modify time=%s", ctime(&m_time));
+ printf("This system appears to have sticky create times\n");
+ correct = False;
+ }
+ if (a_time % (60*60) == 0) {
+ printf("access time=%s", ctime(&a_time));
+ printf("This system appears to set a midnight access time\n");
+ correct = False;
+ }
+
+ if (abs(m_time - time(NULL)) > 60*60*24*7) {
+ printf("ERROR: totally incorrect times - maybe word reversed?\n");
+ correct = False;
+ }
+ }
+
+
+ cli_unlink(&cli, fname);
+ fnum = cli_open(&cli, fname,
+ O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ cli_close(&cli, fnum);
+ if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
+ &w_time, &size, NULL, NULL)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ } else {
+ if (w_time < 60*60*24*2) {
+ printf("write time=%s", ctime(&w_time));
+ printf("This system appears to set a initial 0 write time\n");
+ correct = False;
+ }
+ }
+
+ cli_unlink(&cli, fname);
+
+
+ /* check if the server updates the directory modification time
+ when creating a new file */
+ if (!cli_mkdir(&cli, dname)) {
+ printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ }
+ sleep(3);
+ if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
+ &w_time, &size, NULL, NULL)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ }
+
+ fnum = cli_open(&cli, fname2,
+ O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
+ cli_close(&cli, fnum);
+ if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
+ &w_time, &size, NULL, NULL)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ correct = False;
+ } else {
+ if (m_time2 == m_time) {
+ printf("This system does not update directory modification times\n");
+ correct = False;
+ }
+ }
+ cli_unlink(&cli, fname2);
+ cli_rmdir(&cli, dname);
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("trans2 test finished\n");
+
+ return correct;
+}
+
+/*
+ This checks new W2K calls.
+*/
+
+static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
+{
+ char buf[4096];
+ BOOL correct = True;
+
+ memset(buf, 0xff, sizeof(buf));
+
+ if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
+ printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
+ correct = False;
+ } else {
+ printf("qfileinfo: level %d\n", level);
+ dump_data(0, buf, 256);
+ printf("\n");
+ }
+ return correct;
+}
+
+/****************************************************************************
+ Set or clear the delete on close flag.
+****************************************************************************/
+
+int cli_setfileinfo_test(struct cli_state *cli, int fnum, int level, char *data, int data_len)
+{
+ int param_len = 6;
+ uint16 setup = TRANSACT2_SETFILEINFO;
+ pstring param;
+ char *rparam=NULL, *rdata=NULL;
+
+ memset(param, 0, param_len);
+ SSVAL(param,0,fnum);
+ SSVAL(param,2,level);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+static BOOL run_w2ktest(int dummy)
+{
+ static struct cli_state cli;
+ int fnum;
+ char *fname = "\\w2ktest\\w2k.tst";
+ char *fname1 = "\\w2ktest\\w2k.dir";
+ int level;
+ char data;
+ BOOL correct = True;
+
+ printf("starting w2k test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ fnum = cli_open(&cli, fname,
+ O_RDWR | O_CREAT , DENY_NONE);
+
+ for (level = 1004; level < 1040; level++) {
+ new_trans(&cli, fnum, level);
+ }
+
+ cli_close(&cli, fnum);
+ cli_unlink(&cli, fname);
+
+ /* Check the strange 1013 setinfo call. */
+ cli_mkdir(&cli, fname1);
+ fnum = cli_nt_create_full( &cli, fname1, 0x60080, 0, 7,
+ 1, 0);
+
+ data = 1;
+ if (!cli_setfileinfo_test( &cli, fnum, 1013, &data, 1)) {
+ printf("setfileinfo test 1 failed with %s\n", cli_errstr(&cli));
+ }
+ data = 0;
+ if (!cli_setfileinfo_test( &cli, fnum, 1013, &data, 1)) {
+ printf("setfileinfo test 2 failed with %s\n", cli_errstr(&cli));
+ }
+
+ cli_close(&cli, fnum);
+ cli_rmdir(&cli, fname1);
+
+ fnum = cli_open(&cli, fname, O_RDWR | O_CREAT , DENY_NONE);
+
+ cli_write(&cli, fnum, 0, (char *)&data, 0, sizeof(data));
+ cli_close(&cli, fnum);
+ cli_ulogoff(&cli);
+
+ fnum = cli_open(&cli, fname, O_RDWR , DENY_NONE);
+ if (cli_read(&cli, fnum, &data, 0, 1) != 1) {
+ printf("x test 2 failed with %s\n", cli_errstr(&cli));
+ }
+ cli_close(&cli, fnum);
+ cli_unlink(&cli, fname);
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("w2k test finished\n");
+
+ return correct;
+}
+
+
+/*
+ this is a harness for some oplock tests
+ */
+static BOOL run_oplock1(int dummy)
+{
+ static struct cli_state cli1;
+ char *fname = "\\lockt1.lck";
+ int fnum1;
+ BOOL correct = True;
+
+ printf("starting oplock test 1\n");
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+
+ cli_unlink(&cli1, fname);
+
+ cli_sockopt(&cli1, sockops);
+
+ cli1.use_oplocks = True;
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ cli1.use_oplocks = False;
+
+ cli_unlink(&cli1, fname);
+ cli_unlink(&cli1, fname);
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_unlink(&cli1, fname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+
+ printf("finished oplock test 1\n");
+
+ return correct;
+}
+
+static BOOL run_oplock2(int dummy)
+{
+ static struct cli_state cli1, cli2;
+ char *fname = "\\lockt2.lck";
+ int fnum1, fnum2;
+ int saved_use_oplocks = use_oplocks;
+ char buf[4];
+ BOOL correct = True;
+ volatile BOOL *shared_correct;
+
+ shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
+ *shared_correct = True;
+
+ use_level_II_oplocks = True;
+ use_oplocks = True;
+
+ printf("starting oplock test 2\n");
+
+ if (!open_connection(&cli1)) {
+ use_level_II_oplocks = False;
+ use_oplocks = saved_use_oplocks;
+ return False;
+ }
+
+ cli1.use_oplocks = True;
+ cli1.use_level_II_oplocks = True;
+
+ if (!open_connection(&cli2)) {
+ use_level_II_oplocks = False;
+ use_oplocks = saved_use_oplocks;
+ return False;
+ }
+
+ cli2.use_oplocks = True;
+ cli2.use_level_II_oplocks = True;
+
+ cli_unlink(&cli1, fname);
+
+ cli_sockopt(&cli1, sockops);
+ cli_sockopt(&cli2, sockops);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* Don't need the globals any more. */
+ use_level_II_oplocks = False;
+ use_oplocks = saved_use_oplocks;
+
+ if (fork() == 0) {
+ /* Child code */
+ fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+ if (fnum2 == -1) {
+ printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ *shared_correct = False;
+ exit(0);
+ }
+
+ sleep(2);
+
+ if (!cli_close(&cli2, fnum2)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ *shared_correct = False;
+ }
+
+ exit(0);
+ }
+
+ sleep(2);
+
+ /* Ensure cli1 processes the break. */
+
+ if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
+ printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ /* Should now be at level II. */
+ /* Test if sending a write locks causes a break to none. */
+
+ if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
+ printf("lock failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ cli_unlock(&cli1, fnum1, 0, 4);
+
+ sleep(2);
+
+ if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
+ printf("lock failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ cli_unlock(&cli1, fnum1, 0, 4);
+
+ sleep(2);
+
+ cli_read(&cli1, fnum1, buf, 0, 4);
+
+#if 0
+ if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
+ printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+#endif
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close1 failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ sleep(4);
+
+ if (!cli_unlink(&cli1, fname)) {
+ printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+
+ if (!*shared_correct) {
+ correct = False;
+ }
+
+ printf("finished oplock test 2\n");
+
+ return correct;
+}
+
+
+/*
+ Test delete on close semantics.
+ */
+static BOOL run_deletetest(int dummy)
+{
+ static struct cli_state cli1;
+ static struct cli_state cli2;
+ char *fname = "\\delete.file";
+ int fnum1, fnum2;
+ BOOL correct = True;
+
+ printf("starting delete test\n");
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+
+ cli_sockopt(&cli1, sockops);
+
+ /* Test 1 - this should *NOT* delete the file on close. */
+
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG);
+
+ if (fnum1 == -1) {
+ printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[1] close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[1] close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ printf("first delete on close test succeeded.\n");
+
+ /* Test 2 - this should delete the file on close. */
+
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[2] close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+ if (fnum1 != -1) {
+ printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[2] close failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+ cli_unlink(&cli1, fname);
+ } else
+ printf("second delete on close test succeeded.\n");
+
+
+ /* Test 3 - ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should fail with a sharing violation - open for delete is only compatible
+ with SHARE_DELETE. */
+
+ fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
+
+ if (fnum2 != -1) {
+ printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
+ return False;
+ }
+
+ /* This should succeed. */
+
+ fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+
+ if (fnum2 == -1) {
+ printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum2)) {
+ printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should fail - file should no longer be there. */
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+ if (fnum1 != -1) {
+ printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[3] close failed (%s)\n", cli_errstr(&cli1));
+ }
+ cli_unlink(&cli1, fname);
+ correct = False;
+ } else
+ printf("third delete on close test succeeded.\n");
+
+ /* Test 4 ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should succeed. */
+ fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+ if (fnum2 == -1) {
+ printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum2)) {
+ printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should fail - no more opens once delete on close set. */
+ fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+ if (fnum2 != -1) {
+ printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
+ return False;
+ } else
+ printf("fourth delete on close test succeeded.\n");
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* Test 5 ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should fail - only allowed on NT opens with DELETE access. */
+
+ if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ printf("fifth delete on close test succeeded.\n");
+
+ /* Test 6 ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This should fail - only allowed on NT opens with DELETE access. */
+
+ if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ printf("sixth delete on close test succeeded.\n");
+
+ /* Test 7 ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[7] setting delete_on_close on file failed !\n");
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
+ printf("[7] unsetting delete_on_close on file failed !\n");
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This next open should succeed - we reset the flag. */
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ printf("seventh delete on close test succeeded.\n");
+
+ /* Test 7 ... */
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ if (!open_connection(&cli2)) {
+ printf("[8] failed to open second connection.\n");
+ return False;
+ }
+
+ cli_sockopt(&cli1, sockops);
+
+ fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
+
+ if (fnum1 == -1) {
+ printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+
+ if (fnum2 == -1) {
+ printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+ printf("[8] setting delete_on_close on file failed !\n");
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli2, fnum2)) {
+ printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
+ return False;
+ }
+
+ /* This should fail.. */
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+ if (fnum1 != -1) {
+ printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
+ if (!cli_close(&cli1, fnum1)) {
+ printf("[8] close failed (%s)\n", cli_errstr(&cli1));
+ }
+ cli_unlink(&cli1, fname);
+ correct = False;
+ } else
+ printf("eighth delete on close test succeeded.\n");
+
+ printf("finished delete test\n");
+
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+ if (!close_connection(&cli2)) {
+ correct = False;
+ }
+ return correct;
+}
+
+/*
+ Test open mode returns on read-only files.
+ */
+static BOOL run_opentest(int dummy)
+{
+ static struct cli_state cli1;
+ char *fname = "\\readonly.file";
+ int fnum1, fnum2;
+ uint8 eclass;
+ uint32 errnum;
+ char buf[20];
+ size_t fsize;
+ BOOL correct = True;
+
+ printf("starting open test\n");
+
+ if (!open_connection(&cli1)) {
+ return False;
+ }
+
+ cli_setatr(&cli1, fname, 0, 0);
+ cli_unlink(&cli1, fname);
+
+ cli_sockopt(&cli1, sockops);
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
+ printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
+ fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
+
+ cli_dos_error( &cli1, &eclass, &errnum);
+
+ if (eclass != ERRDOS || errnum != ERRnoaccess) {
+ printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
+ (unsigned int)errnum, cli_errstr(&cli1) );
+ correct = False;
+ } else {
+ printf("correct error code ERRDOS/ERRnoaccess returned\n");
+ }
+
+
+ printf("finished open test 1\n");
+
+ cli_close(&cli1, fnum1);
+
+ /* Now try not readonly and ensure ERRbadshare is returned. */
+
+ cli_setatr(&cli1, fname, 0, 0);
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
+ if (fnum1 == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* This will fail - but the error should be ERRshare. */
+ fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
+
+ cli_dos_error( &cli1, &eclass, &errnum);
+
+ if (eclass != ERRDOS || errnum != ERRbadshare) {
+ printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
+ (unsigned int)errnum, cli_errstr(&cli1) );
+ correct = False;
+ } else {
+ printf("correct error code ERRDOS/ERRbadshare returned\n");
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ cli_unlink(&cli1, fname);
+
+ printf("finished open test 2\n");
+
+ /* Test truncate open disposition on file opened for read. */
+
+ fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ /* write 20 bytes. */
+
+ memset(buf, '\0', 20);
+
+ if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
+ printf("write failed (%s)\n", cli_errstr(&cli1));
+ correct = False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* Ensure size == 20. */
+ if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
+ printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (fsize != 20) {
+ printf("(3) file size != 20\n");
+ return False;
+ }
+
+ /* Now test if we can truncate a file opened for readonly. */
+
+ fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
+ if (fnum1 == -1) {
+ printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ return False;
+ }
+
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ /* Ensure size == 0. */
+ if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
+ printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+
+ if (fsize != 0) {
+ printf("(3) file size != 0\n");
+ return False;
+ }
+ printf("finished open test 3\n");
+
+ cli_unlink(&cli1, fname);
+
+
+ printf("testing ctemp\n");
+ {
+ char *tmp_path;
+ fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
+ if (fnum1 == -1) {
+ printf("ctemp failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+ printf("ctemp gave path %s\n", tmp_path);
+ cli_close(&cli1, fnum1);
+ cli_unlink(&cli1, tmp_path);
+ }
+
+ if (!close_connection(&cli1)) {
+ correct = False;
+ }
+
+ return correct;
+}
+
+static void list_fn(file_info *finfo, const char *name, void *state)
+{
+
+}
+
+/*
+ test directory listing speed
+ */
+static BOOL run_dirtest(int dummy)
+{
+ int i;
+ static struct cli_state cli;
+ int fnum;
+ double t1;
+ BOOL correct = True;
+
+ printf("starting directory test\n");
+
+ if (!open_connection(&cli)) {
+ return False;
+ }
+
+ cli_sockopt(&cli, sockops);
+
+ srandom(0);
+ for (i=0;i<numops;i++) {
+ fstring fname;
+ slprintf(fname, sizeof(fname), "%x", (int)random());
+ fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
+ if (fnum == -1) {
+ fprintf(stderr,"Failed to open %s\n", fname);
+ return False;
+ }
+ cli_close(&cli, fnum);
+ }
+
+ t1 = end_timer();
+
+ printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
+ printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
+ printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
+
+ printf("dirtest core %g seconds\n", end_timer() - t1);
+
+ srandom(0);
+ for (i=0;i<numops;i++) {
+ fstring fname;
+ slprintf(fname, sizeof(fname), "%x", (int)random());
+ cli_unlink(&cli, fname);
+ }
+
+ if (!close_connection(&cli)) {
+ correct = False;
+ }
+
+ printf("finished dirtest\n");
+
+ return correct;
+}
+
+static double create_procs(BOOL (*fn)(int), BOOL *result)
+{
+ int i, status;
+ volatile pid_t *child_status;
+ volatile BOOL *child_status_out;
+ int synccount;
+ int tries = 8;
+
+ synccount = 0;
+
+ child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
+ if (!child_status) {
+ printf("Failed to setup shared memory\n");
+ return -1;
+ }
+
+ child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
+ if (!child_status_out) {
+ printf("Failed to setup result status shared memory\n");
+ return -1;
+ }
+
+ memset(child_status, 0, sizeof(pid_t)*nprocs);
+ memset(child_status_out, True, sizeof(BOOL)*nprocs);
+
+ start_timer();
+
+ for (i=0;i<nprocs;i++) {
+ procnum = i;
+ if (fork() == 0) {
+ pid_t mypid = getpid();
+ sys_srandom(((int)mypid) ^ ((int)time(NULL)));
+
+ slprintf(myname,sizeof(myname),"CLIENT%d", i);
+
+ while (1) {
+ memset(&current_cli, 0, sizeof(current_cli));
+ if (open_connection(&current_cli)) break;
+ if (tries-- == 0) {
+ printf("pid %d failed to start\n", (int)getpid());
+ _exit(1);
+ }
+ msleep(10);
+ }
+
+ child_status[i] = getpid();
+
+ while (child_status[i] && end_timer() < 5) msleep(2);
+
+ child_status_out[i] = fn(i);
+ _exit(0);
+ }
+ }
+
+ do {
+ synccount = 0;
+ for (i=0;i<nprocs;i++) {
+ if (child_status[i]) synccount++;
+ }
+ if (synccount == nprocs) break;
+ msleep(10);
+ } while (end_timer() < 30);
+
+ if (synccount != nprocs) {
+ printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
+ *result = False;
+ return end_timer();
+ }
+
+ /* start the client load */
+ start_timer();
+
+ for (i=0;i<nprocs;i++) {
+ child_status[i] = 0;
+ }
+
+ printf("%d clients started\n", nprocs);
+
+ for (i=0;i<nprocs;i++) {
+ waitpid(0, &status, 0);
+ printf("*");
+ }
+
+ printf("\n");
+
+ for (i=0;i<nprocs;i++) {
+ if (!child_status_out[i]) {
+ *result = False;
+ }
+ }
+ return end_timer();
+}
+
+
+#define FLAG_MULTIPROC (1<<0)
+#define FLAG_MULTIUSER (1<<1)
+#define FLAG_MULTISHARE (1<<2)
+#define FLAG_PROBE (1<<3)
+
+static struct {
+ char *name;
+ BOOL (*fn)(int);
+ unsigned flags;
+} torture_ops[] = {
+ {"FDPASS", run_fdpasstest, 0},
+ {"LOCK1", run_locktest1, 0},
+ {"LOCK2", run_locktest2, 0},
+ {"LOCK3", run_locktest3, 0},
+ {"LOCK4", run_locktest4, 0},
+ {"LOCK5", run_locktest5, 0},
+ {"UNLINK", run_unlinktest, 0},
+ {"BROWSE", run_browsetest, 0},
+ {"ATTR", run_attrtest, 0},
+ {"TRANS2", run_trans2test, 0},
+ {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
+ {"TORTURE",run_torture, FLAG_MULTIPROC},
+ {"RANDOMIPC", run_randomipc, 0},
+ {"NEGNOWAIT", run_negprot_nowait, 0},
+ {"NBW95", run_nbw95, 0},
+ {"NBWNT", run_nbwnt, 0},
+ {"OPLOCK1", run_oplock1, 0},
+ {"OPLOCK2", run_oplock2, 0},
+ {"DIR", run_dirtest, 0},
+ {"DENY1", run_denytest1, 0},
+ {"DENY2", run_denytest2, 0},
+ {"TCON", run_tcon_test, 0},
+ {"RW1", run_readwritetest, 0},
+ {"RW2", run_readwritemulti, FLAG_MULTIPROC},
+ {"RW3", run_readwritelarge, 0},
+ {"OPEN", run_opentest, 0},
+ {"DELETE", run_deletetest, 0},
+ {"W2K", run_w2ktest, 0},
+ {"VU", run_vusertest, FLAG_MULTIUSER | FLAG_MULTISHARE},
+ {NULL, NULL, 0}};
+
+
+
+/****************************************************************************
+run a specified test or "ALL"
+****************************************************************************/
+
+static BOOL get_test_flags(char *name, BOOL *flags) {
+
+ int i;
+
+ BOOL all = strequal(name,"ALL") == 0;
+
+ for (i=0;torture_ops[i].name;i++) {
+
+ if (all || strequal(name, torture_ops[i].name)) {
+
+ *flags |= torture_ops[i].flags;
+
+ if(!all) {
+
+ break;
+ }
+ }
+ }
+
+ return True;
+}
+
+static BOOL run_test(char *name)
+{
+ BOOL ret = True;
+ BOOL result = True;
+ int i;
+ double t;
+ if (strequal(name,"ALL")) {
+ for (i=0;torture_ops[i].name;i++) {
+ run_test(torture_ops[i].name);
+ }
+ }
+
+ for (i=0;torture_ops[i].name;i++) {
+ snprintf(randomfname, sizeof(randomfname), "\\XX%x",
+ (unsigned)random());
+
+ if (strequal(name, torture_ops[i].name)) {
+ printf("Running %s\n", name);
+ if (torture_ops[i].flags & FLAG_MULTIPROC) {
+ t = create_procs(torture_ops[i].fn, &result);
+ if (!result) {
+ ret = False;
+ printf("TEST %s FAILED!\n", name);
+ }
+
+ } else {
+ start_timer();
+ if (!torture_ops[i].fn(0)) {
+ ret = False;
+ printf("TEST %s FAILED!\n", name);
+ }
+ t = end_timer();
+ }
+ printf("%s took %g secs\n\n", name, t);
+ }
+ }
+ return ret;
+}
+
+
+static void usage(void)
+{
+ int i;
+
+ printf("Usage: smbtorture //server/share[,share...] <options> TEST1 TEST2 ...\n");
+
+ printf("\t-d debuglevel\n");
+ printf("\t-U user%%pass\n");
+ printf("\t-u user%%pass[,user%%pass...]\n");
+ printf("\t-N numprocs\n");
+ printf("\t-n my_netbios_name\n");
+ printf("\t-W workgroup\n");
+ printf("\t-o num_operations\n");
+ printf("\t-O socket_options\n");
+ printf("\t-m maximum protocol\n");
+ printf("\t-L use oplocks\n");
+ printf("\n\n");
+
+ printf("tests are:");
+ for (i=0;torture_ops[i].name;i++) {
+ printf(" %s", torture_ops[i].name);
+ }
+ printf("\n");
+
+ printf("default test is ALL\n");
+
+ exit(1);
+}
+
+static BOOL split_password_from_username(char *username, char *password) {
+
+ char * pp = strchr(username,'%');
+ if (pp) {
+ *pp = 0;
+ pstrcpy(password, pp+1);
+ return True;
+ }
+
+ return False;
+}
+
+static BOOL extract_users(char *user_list) {
+
+ const char *separators = ",";
+
+ char *p = strtok(user_list, separators);
+
+ while(p && nusers < MAX_USERS) {
+
+ vusers[nusers].username[0] = '\0';
+ vusers[nusers].password[0] = '\0';
+ vusers[nusers].gotpass = False;
+
+ pstrcpy(vusers[nusers].username, p);
+
+ vusers[nusers].gotpass = split_password_from_username(vusers[nusers].username, vusers[nusers].password);
+
+ nusers++;
+
+ p = strtok(NULL, separators);
+ }
+
+ return True;
+}
+
+static BOOL extract_shares(char *share_list) {
+
+ const char *separators = ",";
+
+ char *p = strtok(share_list, separators);
+
+ while(p && nshares < MAX_TIDS) {
+
+ pstrcpy(shares[nshares], p);
+
+ nshares++;
+
+ p = strtok(NULL, separators);
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+
+ int main(int argc,char *argv[])
+{
+ int opt, i;
+ char *p;
+ int test_flags = 0;
+ BOOL *gotpass = &vusers[0].gotpass;
+ extern char *optarg;
+ extern int optind;
+ extern FILE *dbf;
+ static pstring servicesf = CONFIGFILE;
+ BOOL correct = True;
+ fstring user_list;
+ fstring share_list;
+
+ dbf = stdout;
+
+#ifdef HAVE_SETBUFFER
+ setbuffer(stdout, NULL, 0);
+#endif
+ charset_initialise();
+
+ codepage_initialise(lp_client_code_page());
+
+ codepage_initialise(lp_client_code_page());
+
+ lp_load(servicesf,True,False,False);
+ load_interfaces();
+
+ if (argc < 2) {
+ usage();
+ }
+
+ for(p = argv[1]; *p; p++)
+ if(*p == '\\')
+ *p = '/';
+
+ if (strncmp(argv[1], "//", 2)) {
+ usage();
+ }
+
+ fstrcpy(host, &argv[1][2]);
+ p = strchr(&host[2],'/');
+ if (!p) {
+ usage();
+ }
+
+ *p = 0;
+ fstrcpy(share_list, p+1);
+
+ get_myname(myname);
+
+ if (*username == 0 && getenv("LOGNAME")) {
+
+ pstrcpy(username,getenv("LOGNAME"));
+ }
+
+ argc--;
+ argv++;
+
+ fstrcpy(workgroup, lp_workgroup());
+
+ while ((opt = getopt(argc, argv, "hW:U:u:n:N:O:o:m:Ld:")) != EOF) {
+ switch (opt) {
+ case 'W':
+ fstrcpy(workgroup,optarg);
+ break;
+ case 'm':
+ max_protocol = interpret_protocol(optarg, max_protocol);
+ break;
+ case 'N':
+ nprocs = atoi(optarg);
+ break;
+ case 'o':
+ numops = atoi(optarg);
+ break;
+ case 'd':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 'O':
+ sockops = optarg;
+ break;
+ case 'L':
+ use_oplocks = True;
+ break;
+ case 'n':
+ fstrcpy(myname, optarg);
+ break;
+ case 'U':
+ pstrcpy(username,optarg);
+ *gotpass = split_password_from_username(username, password);
+ break;
+ case 'u':
+ pstrcpy(user_list, optarg);
+ if(!extract_users(user_list)) {
+ usage();
+ }
+ break;
+ default:
+ printf("Unknown option %c (%d)\n", (char)opt, opt);
+ usage();
+ }
+ }
+
+ if (argc == 1) {
+ get_test_flags("ALL", &test_flags);
+ } else {
+ for (i=1;i<argc;i++) {
+
+ get_test_flags(argv[i], &test_flags);
+ }
+ }
+
+ while (!*gotpass) {
+ fstring s;
+ snprintf(s, sizeof(s), "Password for user %s:", username);
+ p = getpass(s);
+ if (p) {
+ pstrcpy(password, p);
+ *gotpass = True;
+ }
+ }
+
+ extract_shares(share_list);
+
+ if(test_flags & FLAG_MULTIUSER) {
+
+ if(nusers == 1) {
+
+ /*generate another user from the one that is already specified*/
+
+ vusers[nusers] = vusers[nusers-1];
+
+ nusers++;
+ }
+
+ for(i = 1; i < nusers; i++) {
+
+ fstring s;
+
+ if(vusers[i].gotpass) {
+
+ continue;
+ }
+
+ snprintf(s, sizeof(s), "Password for user %s:", vusers[i].username);
+
+ p = getpass(s);
+ if (p) {
+
+ pstrcpy(vusers[i].password, p);
+ vusers[i].gotpass = True;
+ }
+ }
+ }
+
+ user_list[0] = '\0';
+
+ for(i = 0; i < nusers; i++) {
+
+ if(!vusers[i].gotpass) {
+
+ continue;
+ }
+
+ if(i) {
+
+ fstrcat(user_list, ", ");
+ }
+
+ fstrcat(user_list, vusers[i].username);
+ }
+
+ printf("host=%s shares=%s users=%s myname=%s\n", host, share_list, user_list, myname);
+
+ if (argc == 1) {
+ correct = run_test("ALL");
+ } else {
+ for (i=1;i<argc;i++) {
+ if (!run_test(argv[i])) {
+ correct = False;
+ }
+ }
+ }
+
+ if (correct) {
+ return(0);
+ } else {
+ return(1);
+ }
+}
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 07b9f52ff77..bd7309e9f70 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -19,7 +19,7 @@
#include "includes.h"
-#include "../web/swat_proto.h"
+#include "smb.h"
#define MAX_VARIABLES 10000
@@ -46,6 +46,43 @@ static char *C_user;
static BOOL inetd_server;
static BOOL got_request;
+static void unescape(char *buf)
+{
+ char *p=buf;
+
+ while ((p=strchr(p,'+')))
+ *p = ' ';
+
+ p = buf;
+
+ while (p && *p && (p=strchr(p,'%'))) {
+ int c1 = p[1];
+ int c2 = p[2];
+
+ if (c1 >= '0' && c1 <= '9')
+ c1 = c1 - '0';
+ else if (c1 >= 'A' && c1 <= 'F')
+ c1 = 10 + c1 - 'A';
+ else if (c1 >= 'a' && c1 <= 'f')
+ c1 = 10 + c1 - 'a';
+ else {p++; continue;}
+
+ if (c2 >= '0' && c2 <= '9')
+ c2 = c2 - '0';
+ else if (c2 >= 'A' && c2 <= 'F')
+ c2 = 10 + c2 - 'A';
+ else if (c2 >= 'a' && c2 <= 'f')
+ c2 = 10 + c2 - 'a';
+ else {p++; continue;}
+
+ *p = (c1<<4) | c2;
+
+ memmove(p+1, p+3, strlen(p+3)+1);
+ p++;
+ }
+}
+
+
static char *grab_line(FILE *f, int *cl)
{
char *ret = NULL;
@@ -74,7 +111,7 @@ static char *grab_line(FILE *f, int *cl)
if (c == '\r') continue;
- if (strchr_m("\n&", c)) break;
+ if (strchr("\n&", c)) break;
ret[i++] = c;
@@ -85,52 +122,45 @@ static char *grab_line(FILE *f, int *cl)
return ret;
}
-/**
- URL encoded strings can have a '+', which should be replaced with a space
-
- (This was in rfc1738_unescape(), but that broke the squid helper)
-**/
-
-static void plus_to_space_unescape(char *buf)
-{
- char *p=buf;
-
- while ((p=strchr_m(p,'+')))
- *p = ' ';
-}
-
/***************************************************************************
load all the variables passed to the CGI program. May have multiple variables
with the same name and the same or different values. Takes a file parameter
for simulating CGI invocation eg loading saved preferences.
***************************************************************************/
-void cgi_load_variables(void)
+void cgi_load_variables(FILE *f1)
{
+ FILE *f = f1;
static char *line;
char *p, *s, *tok;
- int len, i;
- FILE *f = stdin;
+ int len;
#ifdef DEBUG_COMMENTS
char dummy[100]="";
print_title(dummy);
- d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
+ printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
#endif
- if (!content_length) {
- p = getenv("CONTENT_LENGTH");
- len = p?atoi(p):0;
+ if (!f1) {
+ f = stdin;
+ if (!content_length) {
+ p = getenv("CONTENT_LENGTH");
+ len = p?atoi(p):0;
+ } else {
+ len = content_length;
+ }
} else {
- len = content_length;
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ fseek(f, 0, SEEK_SET);
}
if (len > 0 &&
- (request_post ||
+ (f1 || request_post ||
((s=getenv("REQUEST_METHOD")) &&
- strequal(s,"POST")))) {
+ strcasecmp(s,"POST")==0))) {
while (len && (line=grab_line(f, &len))) {
- p = strchr_m(line,'=');
+ p = strchr(line,'=');
if (!p) continue;
*p = 0;
@@ -144,10 +174,8 @@ void cgi_load_variables(void)
!variables[num_variables].value)
continue;
- plus_to_space_unescape(variables[num_variables].value);
- rfc1738_unescape(variables[num_variables].value);
- plus_to_space_unescape(variables[num_variables].name);
- rfc1738_unescape(variables[num_variables].name);
+ unescape(variables[num_variables].value);
+ unescape(variables[num_variables].name);
#ifdef DEBUG_COMMENTS
printf("<!== POST var %s has value \"%s\" ==>\n",
@@ -160,12 +188,19 @@ void cgi_load_variables(void)
}
}
+ if (f1) {
+#ifdef DEBUG_COMMENTS
+ printf("<!== End dump in cgi_load_variables() ==>\n");
+#endif
+ return;
+ }
+
fclose(stdin);
open("/dev/null", O_RDWR);
if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) {
- p = strchr_m(tok,'=');
+ p = strchr(tok,'=');
if (!p) continue;
*p = 0;
@@ -177,10 +212,8 @@ void cgi_load_variables(void)
!variables[num_variables].value)
continue;
- plus_to_space_unescape(variables[num_variables].value);
- rfc1738_unescape(variables[num_variables].value);
- plus_to_space_unescape(variables[num_variables].name);
- rfc1738_unescape(variables[num_variables].name);
+ unescape(variables[num_variables].value);
+ unescape(variables[num_variables].name);
#ifdef DEBUG_COMMENTS
printf("<!== Commandline var %s has value \"%s\" ==>\n",
@@ -195,24 +228,6 @@ void cgi_load_variables(void)
#ifdef DEBUG_COMMENTS
printf("<!== End dump in cgi_load_variables() ==>\n");
#endif
-
- /* variables from the client are in display charset - convert them
- to our internal charset before use */
- for (i=0;i<num_variables;i++) {
- pstring dest;
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].name, -1,
- dest, sizeof(dest), True);
- free(variables[i].name);
- variables[i].name = strdup(dest);
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].value, -1,
- dest, sizeof(dest), True);
- free(variables[i].value);
- variables[i].value = strdup(dest);
- }
}
@@ -242,15 +257,15 @@ static void cgi_setup_error(const char *err, const char *header, const char *inf
/* damn browsers don't like getting cut off before they give a request */
char line[1024];
while (fgets(line, sizeof(line)-1, stdin)) {
- if (strnequal(line,"GET ", 4) ||
- strnequal(line,"POST ", 5) ||
- strnequal(line,"PUT ", 4)) {
+ if (strncasecmp(line,"GET ", 4)==0 ||
+ strncasecmp(line,"POST ", 5)==0 ||
+ strncasecmp(line,"PUT ", 4)==0) {
break;
}
}
}
- d_printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
+ printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
fclose(stdin);
fclose(stdout);
exit(0);
@@ -277,55 +292,62 @@ static void cgi_auth_error(void)
exit(0);
}
+
/***************************************************************************
-authenticate when we are running as a CGI
+decode a base64 string in-place - simple and slow algorithm
***************************************************************************/
-static void cgi_web_auth(void)
+static void base64_decode(char *s)
{
- const char *user = getenv("REMOTE_USER");
- struct passwd *pwd;
- const char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n";
- const char *tail = "</BODY></HTML>\r\n";
-
- if (!user) {
- printf("%sREMOTE_USER not set. Not authenticated by web server.<br>%s\n",
- head, tail);
- exit(0);
- }
+ const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ int bit_offset, byte_offset, idx, i, n;
+ unsigned char *d = (unsigned char *)s;
+ char *p;
- pwd = getpwnam_alloc(user);
- if (!pwd) {
- printf("%sCannot find user %s<br>%s\n", head, user, tail);
- exit(0);
- }
+ n=i=0;
- setuid(0);
- setuid(pwd->pw_uid);
- if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
- printf("%sFailed to become user %s - uid=%d/%d<br>%s\n",
- head, user, (int)geteuid(), (int)getuid(), tail);
- exit(0);
+ while (*s && (p=strchr(b64,*s))) {
+ idx = (int)(p - b64);
+ byte_offset = (i*6)/8;
+ bit_offset = (i*6)%8;
+ d[byte_offset] &= ~((1<<(8-bit_offset))-1);
+ if (bit_offset < 3) {
+ d[byte_offset] |= (idx << (2-bit_offset));
+ n = byte_offset+1;
+ } else {
+ d[byte_offset] |= (idx >> (bit_offset-2));
+ d[byte_offset+1] = 0;
+ d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
+ n = byte_offset+2;
+ }
+ s++; i++;
}
- passwd_free(&pwd);
+ /* null terminate */
+ d[n] = 0;
}
-
/***************************************************************************
handle a http authentication line
***************************************************************************/
static BOOL cgi_handle_authorization(char *line)
{
- char *p;
- fstring user, user_pass;
+ char *p, *user, *user_pass;
struct passwd *pass = NULL;
+ BOOL got_name = False;
+ BOOL tested_pass = False;
+ fstring default_user_lookup;
+ fstring default_user_pass;
+
+ /* Dummy user lookup to take the same time as a valid user. */
+ fstrcpy(default_user_lookup, "zzzz bibble");
+ fstrcpy(default_user_pass, "123456789");
- if (!strnequal(line,"Basic ", 6)) {
+ if (strncasecmp(line,"Basic ", 6)) {
goto err;
}
line += 6;
while (line[0] == ' ') line++;
- base64_decode_inplace(line);
- if (!(p=strchr_m(line,':'))) {
+ base64_decode(line);
+ if (!(p=strchr(line,':'))) {
/*
* Always give the same error so a cracker
* cannot tell why we fail.
@@ -333,51 +355,60 @@ static BOOL cgi_handle_authorization(char *line)
goto err;
}
*p = 0;
-
- convert_string(CH_DISPLAY, CH_UNIX,
- line, -1,
- user, sizeof(user), True);
-
- convert_string(CH_DISPLAY, CH_UNIX,
- p+1, -1,
- user_pass, sizeof(user_pass), True);
+ user = line;
+ user_pass = p+1;
/*
* Try and get the user from the UNIX password file.
*/
-
- pass = getpwnam_alloc(user);
-
+
+ if(!(pass = Get_Pwnam(user,False))) {
+ /*
+ * Always give the same error so a cracker
+ * cannot tell why we fail.
+ */
+ got_name = True;
+ goto err;
+ }
+
/*
* Validate the password they have given.
*/
-
- if NT_STATUS_IS_OK(pass_check(pass, user, user_pass,
- strlen(user_pass), NULL, False)) {
-
- if (pass) {
+
+ tested_pass = True;
+
+ if(pass_check(user, user_pass, strlen(user_pass), NULL, NULL) == True) {
+
+ /*
+ * Password was ok.
+ */
+
+ if(pass->pw_uid != 0) {
/*
- * Password was ok.
+ * We have not authenticated as root,
+ * become the user *permanently*.
*/
-
- if ( initgroups(pass->pw_name, pass->pw_gid) != 0 )
- goto err;
-
become_user_permanently(pass->pw_uid, pass->pw_gid);
-
- /* Save the users name */
- C_user = strdup(user);
- passwd_free(&pass);
- return True;
}
+
+ /* Save the users name */
+ C_user = strdup(user);
+ return True;
}
-
-err:
- cgi_setup_error("401 Bad Authorization",
- "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
+
+ err:
+
+ /* Always take the same time. */
+ if (!got_name)
+ Get_Pwnam(default_user_lookup,False);
+
+ if (!tested_pass)
+ pass_check(default_user_lookup, default_user_pass,
+ strlen(default_user_pass), NULL, NULL);
+
+ cgi_setup_error("401 Bad Authorization", "",
"username or password incorrect");
- passwd_free(&pass);
return False;
}
@@ -411,11 +442,10 @@ static void cgi_download(char *file)
char buf[1024];
int fd, l, i;
char *p;
- char *lang;
/* sanitise the filename */
for (i=0;file[i];i++) {
- if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) {
+ if (!isalnum((int)file[i]) && !strchr("/.-_", file[i])) {
cgi_setup_error("404 File Not Found","",
"Illegal character in filename");
}
@@ -425,14 +455,13 @@ static void cgi_download(char *file)
cgi_setup_error("404 File Not Found","",
"The requested file was not found");
}
-
- fd = web_open(file,O_RDONLY,0);
+ fd = sys_open(file,O_RDONLY,0);
if (fd == -1) {
cgi_setup_error("404 File Not Found","",
"The requested file was not found");
}
printf("HTTP/1.0 200 OK\r\n");
- if ((p=strrchr_m(file,'.'))) {
+ if ((p=strrchr(file,'.'))) {
if (strcmp(p,".gif")==0) {
printf("Content-Type: image/gif\r\n");
} else if (strcmp(p,".jpg")==0) {
@@ -445,11 +474,6 @@ static void cgi_download(char *file)
}
printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME));
- lang = lang_tdb_current();
- if (lang) {
- printf("Content-Language: %s\r\n", lang);
- }
-
printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
while ((l=read(fd,buf,sizeof(buf)))>0) {
fwrite(buf, 1, l, stdout);
@@ -459,40 +483,26 @@ static void cgi_download(char *file)
}
-
-
-/**
- * @brief Setup the CGI framework.
- *
- * Setup the cgi framework, handling the possibility that this program
- * is either run as a true CGI program with a gateway to a web server, or
- * is itself a mini web server.
- **/
+/***************************************************************************
+setup the cgi framework, handling the possability that this program is either
+run as a true cgi program by a web browser or is itself a mini web server
+ ***************************************************************************/
void cgi_setup(const char *rootdir, int auth_required)
{
BOOL authenticated = False;
char line[1024];
char *url=NULL;
char *p;
- char *lang;
if (chdir(rootdir)) {
- cgi_setup_error("500 Server Error", "",
+ cgi_setup_error("400 Server Error", "",
"chdir failed - the server is not configured correctly");
}
- /* Handle the possibility we might be running as non-root */
- sec_init();
-
- if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) {
- /* if running as a cgi program */
- web_set_lang(lang);
- }
-
/* maybe we are running under a web server */
if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
if (auth_required) {
- cgi_web_auth();
+ cgi_auth_error();
}
return;
}
@@ -500,7 +510,7 @@ void cgi_setup(const char *rootdir, int auth_required)
inetd_server = True;
if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) {
- cgi_setup_error("403 Forbidden", "",
+ cgi_setup_error("400 Server Error", "",
"Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf ");
}
@@ -508,23 +518,21 @@ void cgi_setup(const char *rootdir, int auth_required)
and handle authentication etc */
while (fgets(line, sizeof(line)-1, stdin)) {
if (line[0] == '\r' || line[0] == '\n') break;
- if (strnequal(line,"GET ", 4)) {
+ if (strncasecmp(line,"GET ", 4)==0) {
got_request = True;
url = strdup(&line[4]);
- } else if (strnequal(line,"POST ", 5)) {
+ } else if (strncasecmp(line,"POST ", 5)==0) {
got_request = True;
request_post = 1;
url = strdup(&line[5]);
- } else if (strnequal(line,"PUT ", 4)) {
+ } else if (strncasecmp(line,"PUT ", 4)==0) {
got_request = True;
cgi_setup_error("400 Bad Request", "",
"This server does not accept PUT requests");
- } else if (strnequal(line,"Authorization: ", 15)) {
+ } else if (strncasecmp(line,"Authorization: ", 15)==0) {
authenticated = cgi_handle_authorization(&line[15]);
- } else if (strnequal(line,"Content-Length: ", 16)) {
+ } else if (strncasecmp(line,"Content-Length: ", 16)==0) {
content_length = atoi(&line[16]);
- } else if (strnequal(line,"Accept-Language: ", 17)) {
- web_set_lang(&line[17]);
}
/* ignore all other requests! */
}
@@ -539,15 +547,15 @@ void cgi_setup(const char *rootdir, int auth_required)
}
/* trim the URL */
- if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
+ if ((p = strchr(url,' ')) || (p=strchr(url,'\t'))) {
*p = 0;
}
- while (*url && strchr_m("\r\n",url[strlen(url)-1])) {
+ while (*url && strchr("\r\n",url[strlen(url)-1])) {
url[strlen(url)-1] = 0;
}
/* anything following a ? in the URL is part of the query string */
- if ((p=strchr_m(url,'?'))) {
+ if ((p=strchr(url,'?'))) {
query_string = p+1;
*p = 0;
}
@@ -597,7 +605,7 @@ return the hostname of the client
char *cgi_remote_host(void)
{
if (inetd_server) {
- return get_peer_name(1,False);
+ return get_socket_name(1);
}
return getenv("REMOTE_HOST");
}
@@ -608,7 +616,7 @@ return the hostname of the client
char *cgi_remote_addr(void)
{
if (inetd_server) {
- return get_peer_addr(1);
+ return get_socket_addr(1);
}
return getenv("REMOTE_ADDR");
}
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index 46432c41f85..efe1ef5a2c4 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
diagnosis tools for web admin
Copyright (C) Andrew Tridgell 1998
@@ -19,21 +20,8 @@
*/
#include "includes.h"
-#include "../web/swat_proto.h"
+#include "smb.h"
-#ifdef WITH_WINBIND
-
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-/* check to see if winbind is running by pinging it */
-
-BOOL winbindd_running(void)
-{
- return winbind_ping();
-}
-#endif
/* check to see if nmbd is running on localhost by looking for a __SAMBA__
response */
@@ -47,7 +35,7 @@ BOOL nmbd_running(void)
interpret_addr("127.0.0.1"), True)) != -1) {
if ((ip_list = name_query(fd, "__SAMBA__", 0,
True, True, loopback_ip,
- &count, &flags, NULL)) != NULL) {
+ &count, &flags)) != NULL) {
SAFE_FREE(ip_list);
close(fd);
return True;
@@ -69,7 +57,7 @@ BOOL smbd_running(void)
if (!cli_initialise(&cli))
return False;
- if (!cli_connect(&cli, global_myname(), &loopback_ip)) {
+ if (!cli_connect(&cli, "localhost", &loopback_ip)) {
cli_shutdown(&cli);
return False;
}
diff --git a/source/web/neg_lang.c b/source/web/neg_lang.c
deleted file mode 100644
index da974f78a4a..00000000000
--- a/source/web/neg_lang.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SWAT language handling
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Created by Ryo Kawahara <rkawa@lbe.co.jp>
-*/
-
-#include "includes.h"
-#include "../web/swat_proto.h"
-
-/*
- during a file download we first check to see if there is a language
- specific file available. If there is then use that, otherwise
- just open the specified file
-*/
-int web_open(const char *fname, int flags, mode_t mode)
-{
- char *p = NULL;
- char *lang = lang_tdb_current();
- int fd;
- if (lang) {
- asprintf(&p, "lang/%s/%s", lang, fname);
- if (p) {
- fd = sys_open(p, flags, mode);
- free(p);
- if (fd != -1) {
- return fd;
- }
- }
- }
-
- /* fall through to default name */
- return sys_open(fname, flags, mode);
-}
-
-
-struct pri_list {
- float pri;
- char *string;
-};
-
-static int qsort_cmp_list(const void *x, const void *y) {
- struct pri_list *a = (struct pri_list *)x;
- struct pri_list *b = (struct pri_list *)y;
- if (a->pri > b->pri) return -1;
- if (a->pri == b->pri) return 0;
- return 1;
-}
-
-/*
- choose from a list of languages. The list can be comma or space
- separated
- Keep choosing until we get a hit
- Changed to habdle priority -- Simo
-*/
-
-void web_set_lang(const char *lang_string)
-{
- char **lang_list, **count;
- struct pri_list *pl;
- int lang_num, i;
-
- /* build the lang list */
- lang_list = str_list_make(lang_string, ", \t\r\n");
- if (!lang_list) return;
-
- /* sort the list by priority */
- lang_num = 0;
- count = lang_list;
- while (*count && **count) {
- count++;
- lang_num++;
- }
- pl = (struct pri_list *)malloc(sizeof(struct pri_list) * lang_num);
- for (i = 0; i < lang_num; i++) {
- char *pri_code;
- if ((pri_code=strstr(lang_list[i], ";q="))) {
- *pri_code = '\0';
- pri_code += 3;
- sscanf(pri_code, "%f", &(pl[i].pri));
- } else {
- pl[i].pri = 1;
- }
- pl[i].string = strdup(lang_list[i]);
- }
- str_list_free(&lang_list);
-
- qsort(pl, lang_num, sizeof(struct pri_list), &qsort_cmp_list);
-
- /* it's not an error to not initialise - we just fall back to
- the default */
-
- for (i = 0; i < lang_num; i++) {
- if (lang_tdb_init(pl[i].string)) break;
- }
-
- for (i = 0; i < lang_num; i++) {
- SAFE_FREE(pl[i].string);
- }
- SAFE_FREE(pl);
-
- return;
-}
diff --git a/source/web/po/Makefile b/source/web/po/Makefile
new file mode 100755
index 00000000000..a440dd02966
--- /dev/null
+++ b/source/web/po/Makefile
@@ -0,0 +1,43 @@
+GETTEXT = xgettext --keyword --keyword=_ --keyword=__
+
+# Enter here all .po files
+POFILES = ja.po
+MOFILES = $(POFILES:.po=.mo)
+
+SOURCES = ../cgi.c ../diagnose.c ../startstop.c ../statuspage.c ../swat.c
+
+catalog: $(SOURCES)
+ pofiles='$(POFILES)'; \
+ for pof in $$pofiles; do \
+ $(GETTEXT) $(SOURCES) ; \
+ if [ -f $$pof ]; then \
+ msgmerge $$pof messages.po > $$pof.new; \
+ else \
+ mv messages.po $$pof; \
+ fi ; \
+ rm -f messages.po ; \
+ done
+
+install: text
+ mofiles='$(MOFILES)'; \
+ for mof in $$mofiles; do \
+ lang=`echo $$mof | sed 's/.mo$$//'`; \
+ mkdir -p $(PREFIX)/usr/share/locale/$$lang/LC_MESSAGES; \
+ cp -a $$mof $(PREFIX)/usr/share/locale/$$lang/LC_MESSAGES/swat.mo; \
+ done
+
+text: $(POFILES)
+ pofiles='$(POFILES)'; \
+ for pof in $$pofiles; do \
+ msgfmt $$pof ; \
+ lang=`echo $$pof | sed 's/.po$$//'`; \
+ mv messages $$lang.mo; \
+ done
+
+clean:
+ rm -f $(MOFILES)
+ rm -f *.new
+ rm -f *~
+
+
+
diff --git a/source/web/po/ja.po b/source/web/po/ja.po
new file mode 100755
index 00000000000..16b9bbbc312
--- /dev/null
+++ b/source/web/po/ja.po
@@ -0,0 +1,336 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: swat(samba 2.0.5a)\n"
+"POT-Creation-Date: 1999-08-30 18:18-0700\n"
+"PO-Revision-Date: 1999-08-30 15:52-0700\n"
+"Last-Translator: Kazutomo Yoshii <kazutomo@turbolinux.com>\n"
+"Language-Team: TLJ DEV <tlj@pht.co.jp>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-2022-jp\n"
+"Content-Transfer-Encoding: EUC\n"
+
+#: cgi.c:296
+msgid "Installation Error"
+msgstr "$B%$%s%9%H%l!<%7%g%s%(%i!<(B"
+
+#: cgi.c:297
+msgid "SWAT must be installed via inetd. It cannot be run as a CGI script"
+msgstr ""
+"SWAT$B$O!"(BCGI$B%9%/%j%W%H$7$F<B9T$9$k$N$G$J$/!"(Binetd$B7PM3$G5/F0$5$l$k$Y$-$G$9!#(B"
+
+#: statuspage.c:149
+msgid "Server Status"
+msgstr "$B%5!<%P!<%9%F!<%?%9(B"
+
+#: statuspage.c:155
+msgid "Auto Refresh"
+msgstr "$B<+F0%j%U%l%C%7%e(B"
+
+#: statuspage.c:157 statuspage.c:164
+msgid "Refresh Interval"
+msgstr "$B%j%U%l%C%7%e4V3V(B"
+
+#: statuspage.c:162
+msgid "Stop Refreshing"
+msgstr "$B%j%U%l%C%7%eDd;_(B"
+
+#: statuspage.c:173
+msgid "Couldn't open status file"
+msgstr "$B%9%F!<%?%9%U%!%$%k$r3+$1$^$;$s$G$7$?!#(B"
+
+#: statuspage.c:176
+msgid "You need to have status=yes in your smb config file"
+msgstr "smb$B%3%s%U%#%0%U%!%$%k$G(B status=yes$B$K$9$kI,MW$,$"$j$^$9(B"
+
+#: statuspage.c:184
+msgid "version"
+msgstr "$B%P!<%8%g%s(B"
+
+#: statuspage.c:191
+msgid "Stop smbd"
+msgstr "smbd$B$NDd;_(B"
+
+#: statuspage.c:194
+msgid "Start smbd"
+msgstr "smbd$B$N3+;O(B"
+
+#: statuspage.c:197
+msgid "Restart smbd"
+msgstr "smbd$B$N:F5/F0(B"
+
+#: statuspage.c:206
+msgid "Stop nmbd"
+msgstr "nmbd$B$NDd;_(B"
+
+#: statuspage.c:209
+msgid "Start nmbd"
+msgstr "nmbd$B$N3+;O(B"
+
+#: statuspage.c:212
+msgid "Restart nmbd"
+msgstr "nmbd$B$N:F5/F0(B"
+
+#: statuspage.c:220
+msgid "Active Connections"
+msgstr "$B%"%/%F%#%V$J@\B3(B"
+
+#: statuspage.c:225 statuspage.c:257
+msgid "Client"
+msgstr "$B%/%i%$%"%s%H(B"
+
+#: statuspage.c:225
+msgid "IP address"
+msgstr "IP$B%"%I%l%9(B"
+
+#: statuspage.c:254
+msgid "Active Shares"
+msgstr "$B%"%/%F%#%V$J6&M-(B"
+
+#: statuspage.c:257
+msgid "Share"
+msgstr "$B6&M-(B"
+
+#: statuspage.c:257
+#, fuzzy
+msgid "User"
+msgstr "$B%f!<%6!<(B"
+
+#: statuspage.c:257
+msgid "Group"
+msgstr "$B%0%k!<%W(B"
+
+#: statuspage.c:257
+msgid "Data"
+msgstr "$B%G!<%?(B"
+
+#: statuspage.c:275
+msgid "Open Files"
+msgstr "$B%U%!%$%k(B"
+
+#: statuspage.c:278
+msgid "Sharing"
+msgstr "$B6&M-(B"
+
+#: statuspage.c:278
+msgid "File"
+msgstr "$B%U%!%$%k(B"
+
+#: statuspage.c:278
+msgid "Date"
+msgstr "$BF|IU(B"
+
+#: swat.c:150
+msgid "Samba Web Administration Tool"
+msgstr "Samba Web $B4IM}%D!<%k(B"
+
+#: swat.c:177
+msgid "Help"
+msgstr "$B$X%k%W(B"
+
+#: swat.c:185 swat.c:196 swat.c:206 swat.c:217 swat.c:228 swat.c:236
+#: swat.c:244 swat.c:255
+msgid "Set Default"
+msgstr "$B%G%U%)%k%H(B"
+
+#: swat.c:330
+msgid "Base Options"
+msgstr "$B4pK\%*%W%7%g%s(B"
+
+#: swat.c:331
+msgid "Security Options"
+msgstr "$B%;%-%e%j%F%#(B $B%*%W%7%g%s(B"
+
+#: swat.c:332
+msgid "Logging Options"
+msgstr "$B%m%.%s%0(B $B%*%W%7%g%s(B"
+
+#: swat.c:333
+msgid "Browse Options"
+msgstr "$B%V%i%&%:(B $B%*%W%7%g%s(B"
+
+#: swat.c:334
+msgid "WINS Options"
+msgstr "WINS $B%*%W%7%g%s(B"
+
+#: swat.c:335
+msgid "Miscellaneous Options"
+msgstr "$B$=$N$[$+$N%*%W%7%g%s(B"
+
+#: swat.c:336
+msgid "Locking Options"
+msgstr "$B%m%C%-%s%0%*%W%7%g%s(B"
+
+#: swat.c:337
+msgid "Logon Options"
+msgstr "$B%m%0%*%s%*%W%7%g%s(B"
+
+#: swat.c:338
+msgid "Domain Options"
+msgstr "$B%I%a%$%s%*%W%7%g%s(B"
+
+#: swat.c:339
+msgid "Protocol Options"
+msgstr "$B%W%m%H%3%k%*%W%7%g%s(B"
+
+#: swat.c:340
+msgid "Tuning Options"
+msgstr "$B%A%e!<%K%s%0%*%W%7%g%s(B"
+
+#: swat.c:341
+msgid "Printing Options"
+msgstr "$B0u:~%*%W%7%g%s(B"
+
+#: swat.c:342
+msgid "Filename Handling"
+msgstr "$B%U%!%$%kL>$N=hM}(B"
+
+#: swat.c:492
+msgid "Current Config"
+msgstr "$B8=:_$N@_Dj(B"
+
+#: swat.c:497
+msgid "Normal View"
+msgstr "$BI8=`E*$JI=<((B"
+
+#: swat.c:500
+msgid "Full View"
+msgstr "$BA4$FI=<((B"
+
+#: swat.c:517
+msgid "Global Variables"
+msgstr "$B%0%m!<%P%k@_Dj(B"
+
+#: swat.c:531 swat.c:636 swat.c:1006
+msgid "Commit Changes"
+msgstr "$BE,MQ(B"
+
+#: swat.c:536 swat.c:640 swat.c:1009
+msgid "Reset Values"
+msgstr "$B%j%;%C%H(B"
+
+#: swat.c:540 swat.c:643 swat.c:1012
+msgid "Advanced View"
+msgstr "$B>\:Y$JI=<((B"
+
+#: swat.c:543 swat.c:646 swat.c:1015
+msgid "Basic View"
+msgstr "$B4pK\E*$JI=<((B"
+
+#: swat.c:553 swat.c:1028
+msgid "Advanced"
+msgstr "$B>\:Y(B"
+
+#: swat.c:574
+msgid "Share Parameters"
+msgstr "$B6&M-%Q%i%a!<%?(B"
+
+#: swat.c:604
+msgid "Choose Share"
+msgstr "$B6&M-A*Br(B"
+
+#: swat.c:612 swat.c:978 swat.c:982
+msgid "SELECTED"
+msgstr "$BA*Br:Q(B"
+
+#: swat.c:619
+msgid "Delete Share"
+msgstr "$B6&M-:o=|(B"
+
+#: swat.c:627
+msgid "Create Share"
+msgstr "$B6&M-:n@.(B"
+
+#: swat.c:797
+msgid "Server Password Management"
+msgstr "$B%5!<%P!<%Q%9%o!<%I4IM}(B"
+
+#: swat.c:807 swat.c:869
+msgid "User Name"
+msgstr "$B%f!<%6!<L>(B"
+
+#: swat.c:811 swat.c:872
+msgid "Old Password"
+msgstr "$B5l%Q%9%o!<%I(B"
+
+#: swat.c:815 swat.c:875
+msgid "New Password"
+msgstr "$B?7%Q%9%o!<%I(B"
+
+#: swat.c:818 swat.c:878
+msgid "Re-type New Password"
+msgstr "$B?7%Q%9%o!<%I$N3NG'(B"
+
+#: swat.c:828 swat.c:894
+msgid "Change Password"
+msgstr "$B%Q%9%o!<%I$NJQ99(B"
+
+#: swat.c:840
+msgid "Add New User"
+msgstr "$B%f!<%6!<DI2C(B"
+
+#: swat.c:842
+msgid "Disable User"
+msgstr "$B%f!<%6!<Hs5v2D(B"
+
+#: swat.c:844
+msgid "Enable User"
+msgstr "$B%f!<%6!<5v2D(B"
+
+#: swat.c:859
+msgid "Client/Server Password Management"
+msgstr "$B%/%i%$%"%s%H(B/$B%5!<%P(B $B%Q%9%o!<%I4IM}(B"
+
+#: swat.c:881
+msgid "Remote Machine"
+msgstr "$B%j%b!<%H%^%7%s(B"
+
+#: swat.c:924
+msgid "Printer Parameters"
+msgstr "$B%W%j%s%?!<%Q%i%a!<%?(B"
+
+#: swat.c:927
+msgid "Important Note"
+msgstr "$B=EMW;v9`(B"
+
+#: swat.c:929
+msgid "Printer names marked with [*] in the Choose Printer drop-down box"
+msgstr "*$B$,IU$$$F$$$k%W%j%s%?!<$O!"(B"
+
+#: swat.c:931
+msgid "are autoloaded printers from "
+msgstr "$B<+F0@_Dj$5$l$F$$$^$9!#(B"
+
+#: swat.c:933
+msgid "Printcap Name"
+msgstr "($B;2>H(B Printcap Name)"
+
+#: swat.c:935
+msgid "Attempting to delete these printers from SWAT will have no effect.\n"
+msgstr "$B$3$l$i$N%W%j%s%?!<$r(BSWAT$B$+$i:o=|$7$h$&$H$7$F$b2?$b$*$3$j$^$;$s!#(B\n"
+
+#: swat.c:969
+msgid "Choose Printer"
+msgstr "$B%W%j%s%?!<A*Br(B"
+
+#: swat.c:989
+msgid "Delete Printer"
+msgstr "$B%W%j%s%?!<:o=|(B"
+
+#: swat.c:997
+msgid "Create Printer"
+msgstr "$B%W%j%s%?!<:n@.(B"
+
+
+
+
+
+
+
+
+
+
diff --git a/source/web/po/swatlang.h b/source/web/po/swatlang.h
new file mode 100755
index 00000000000..6ce090c85d3
--- /dev/null
+++ b/source/web/po/swatlang.h
@@ -0,0 +1,13 @@
+#ifndef __SWATLANG_H_DEFINED__
+#define __SWATLANG_H_DEFINED__
+
+typedef struct {
+ char *name;
+ char *lang;
+} SwatLang;
+
+static SwatLang swatlang[] = {
+ "English", "",
+ "Japanese", "ja_JP.ujis",
+ NULL, NULL };
+#endif
diff --git a/source/web/startstop.c b/source/web/startstop.c
index 93e8650c2bc..9eeac96cc0c 100644
--- a/source/web/startstop.c
+++ b/source/web/startstop.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
start/stop nmbd and smbd
Copyright (C) Andrew Tridgell 1998
@@ -19,11 +20,12 @@
*/
#include "includes.h"
-#include "../web/swat_proto.h"
-#include "dynconfig.h"
+#include "smb.h"
+/* need to wait for daemons to startup */
+#define SLEEP_TIME 3
-/** Startup smbd from web interface. */
+/* startup smbd */
void start_smbd(void)
{
pstring binfile;
@@ -31,12 +33,13 @@ void start_smbd(void)
if (geteuid() != 0) return;
if (fork()) {
+ sleep(SLEEP_TIME);
return;
}
- slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", dyn_SBINDIR);
+ slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", SBINDIR);
- become_daemon(True);
+ become_daemon();
execl(binfile, binfile, "-D", NULL);
@@ -51,38 +54,19 @@ void start_nmbd(void)
if (geteuid() != 0) return;
if (fork()) {
+ sleep(SLEEP_TIME);
return;
}
- slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", dyn_SBINDIR);
+ slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", SBINDIR);
- become_daemon(True);
+ become_daemon();
execl(binfile, binfile, "-D", NULL);
exit(0);
}
-/** Startup winbindd from web interface. */
-void start_winbindd(void)
-{
- pstring binfile;
-
- if (geteuid() != 0) return;
-
- if (fork()) {
- return;
- }
-
- slprintf(binfile, sizeof(pstring) - 1, "%s/winbindd", dyn_SBINDIR);
-
- become_daemon(True);
-
- execl(binfile, binfile, NULL);
-
- exit(0);
-}
-
/* stop smbd */
void stop_smbd(void)
@@ -91,7 +75,7 @@ void stop_smbd(void)
if (geteuid() != 0) return;
- if (pid <= 0) return;
+ if (pid == 0) return;
kill(pid, SIGTERM);
}
@@ -103,23 +87,11 @@ void stop_nmbd(void)
if (geteuid() != 0) return;
- if (pid <= 0) return;
+ if (pid == 0) return;
kill(pid, SIGTERM);
}
-#ifdef WITH_WINBIND
-/* stop winbindd */
-void stop_winbindd(void)
-{
- pid_t pid = pidfile_pid("winbindd");
- if (geteuid() != 0) return;
-
- if (pid <= 0) return;
-
- kill(pid, SIGTERM);
-}
-#endif
/* kill a specified process */
void kill_pid(pid_t pid)
{
@@ -128,4 +100,5 @@ void kill_pid(pid_t pid)
if (pid <= 0) return;
kill(pid, SIGTERM);
+ sleep(SLEEP_TIME);
}
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index 3d70796830d..12bb307d34a 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.
web status page
Copyright (C) Andrew Tridgell 1997-1998
@@ -19,13 +20,9 @@
*/
#include "includes.h"
-#include "../web/swat_proto.h"
#define PIDMAP struct PidMap
-/* how long to wait for start/stops to take effect */
-#define SLEEP_TIME 3
-
PIDMAP {
PIDMAP *next, *prev;
pid_t pid;
@@ -93,7 +90,7 @@ static char *mapPid2Machine (pid_t pid)
}
/* PID not in list or machine name NULL? return pid as string */
- snprintf (pidbuf, sizeof (pidbuf) - 1, "%lu", (unsigned long)pid);
+ snprintf (pidbuf, sizeof (pidbuf) - 1, "%d", pid);
return pidbuf;
}
@@ -107,42 +104,42 @@ static char *tstring(time_t t)
static void print_share_mode(share_mode_entry *e, char *fname)
{
- d_printf("<tr><td>%s</td>",_(mapPid2Machine(e->pid)));
- d_printf("<td>");
+ printf("<tr><td>%s</td>", mapPid2Machine (e->pid));
+ printf("<td>");
switch ((e->share_mode>>4)&0xF) {
- case DENY_NONE: d_printf("DENY_NONE"); break;
- case DENY_ALL: d_printf("DENY_ALL "); break;
- case DENY_DOS: d_printf("DENY_DOS "); break;
- case DENY_READ: d_printf("DENY_READ "); break;
- case DENY_WRITE:d_printf("DENY_WRITE "); break;
+ case DENY_NONE: printf("DENY_NONE"); break;
+ case DENY_ALL: printf("DENY_ALL "); break;
+ case DENY_DOS: printf("DENY_DOS "); break;
+ case DENY_READ: printf("DENY_READ "); break;
+ case DENY_WRITE:printf("DENY_WRITE "); break;
}
- d_printf("</td>");
+ printf("</td>");
- d_printf("<td>");
+ printf("<td>");
switch (e->share_mode&0xF) {
- case 0: d_printf("%s", _("RDONLY ")); break;
- case 1: d_printf("%s", _("WRONLY ")); break;
- case 2: d_printf("%s", _("RDWR ")); break;
+ case 0: printf("RDONLY "); break;
+ case 1: printf("WRONLY "); break;
+ case 2: printf("RDWR "); break;
}
- d_printf("</td>");
+ printf("</td>");
- d_printf("<td>");
+ printf("<td>");
if((e->op_type &
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
(EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- d_printf("EXCLUSIVE+BATCH ");
+ printf("EXCLUSIVE+BATCH ");
else if (e->op_type & EXCLUSIVE_OPLOCK)
- d_printf("EXCLUSIVE ");
+ printf("EXCLUSIVE ");
else if (e->op_type & BATCH_OPLOCK)
- d_printf("BATCH ");
+ printf("BATCH ");
else if (e->op_type & LEVEL_II_OPLOCK)
- d_printf("LEVEL_II ");
+ printf("LEVEL_II ");
else
- d_printf("NONE ");
- d_printf("</td>");
+ printf("NONE ");
+ printf("</td>");
- d_printf("<td>%s</td><td>%s</td></tr>\n",
- fname,tstring(e->time.tv_sec));
+ printf("<td>%s</td><td>%s</td></tr>\n",
+ dos_to_unix_static(fname),tstring(e->time.tv_sec));
}
@@ -161,7 +158,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
if (cgi_variable(buf)) {
kill_pid(crec.pid);
- sleep(SLEEP_TIME);
}
}
return 0;
@@ -177,20 +173,20 @@ static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
memcpy(&crec, dbuf.dptr, sizeof(crec));
- if (crec.cnum == -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
+ if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
return 0;
addPid2Machine (crec.pid, crec.machine);
- d_printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
+ printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
(int)crec.pid,
crec.machine,crec.addr,
tstring(crec.start));
if (geteuid() == 0) {
- d_printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
+ printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
(int)crec.pid);
}
- d_printf("</tr>\n");
+ printf("</tr>\n");
return 0;
}
@@ -208,7 +204,7 @@ static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
if (crec.cnum == -1 || !process_exists(crec.pid))
return 0;
- d_printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
+ printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
crec.name,uidtoname(crec.uid),
gidtoname(crec.gid),(int)crec.pid,
crec.machine,
@@ -224,63 +220,34 @@ void status_page(void)
int autorefresh=0;
int refresh_interval=30;
TDB_CONTEXT *tdb;
- int nr_running=0;
- BOOL waitup = False;
smbd_pid = pidfile_pid("smbd");
- if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
+ if (cgi_variable("smbd_restart")) {
stop_smbd();
start_smbd();
- waitup=True;
}
- if (cgi_variable("smbd_start") || cgi_variable("all_start")) {
+ if (cgi_variable("smbd_start")) {
start_smbd();
- waitup=True;
}
- if (cgi_variable("smbd_stop") || cgi_variable("all_stop")) {
+ if (cgi_variable("smbd_stop")) {
stop_smbd();
- waitup=True;
}
- if (cgi_variable("nmbd_restart") || cgi_variable("all_restart")) {
+ if (cgi_variable("nmbd_restart")) {
stop_nmbd();
start_nmbd();
- waitup=True;
}
- if (cgi_variable("nmbd_start") || cgi_variable("all_start")) {
+ if (cgi_variable("nmbd_start")) {
start_nmbd();
- waitup=True;
}
- if (cgi_variable("nmbd_stop")|| cgi_variable("all_stop")) {
+ if (cgi_variable("nmbd_stop")) {
stop_nmbd();
- waitup=True;
- }
-
-#ifdef WITH_WINBIND
- if (cgi_variable("winbindd_restart") || cgi_variable("all_restart")) {
- stop_winbindd();
- start_winbindd();
- waitup=True;
- }
-
- if (cgi_variable("winbindd_start") || cgi_variable("all_start")) {
- start_winbindd();
- waitup=True;
}
- if (cgi_variable("winbindd_stop") || cgi_variable("all_stop")) {
- stop_winbindd();
- waitup=True;
- }
-#endif
- /* wait for daemons to start/stop */
- if (waitup)
- sleep(SLEEP_TIME);
-
if (cgi_variable("autorefresh")) {
autorefresh = 1;
} else if (cgi_variable("norefresh")) {
@@ -297,145 +264,112 @@ void status_page(void)
PID_or_Machine = 1;
}
- if (cgi_variable("show_pid_in_col_1")) {
- PID_or_Machine = 0;
- }
-
tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (tdb) tdb_traverse(tdb, traverse_fn1, NULL);
-
+
initPid2Machine ();
- d_printf("<H2>%s</H2>\n", _("Server Status"));
+ printf("<H2>Server Status</H2>\n");
- d_printf("<FORM method=post>\n");
+ printf("<FORM method=post>\n");
if (!autorefresh) {
- d_printf("<input type=submit value=\"%s\" name=\"autorefresh\">\n", _("Auto Refresh"));
- d_printf("<br>%s", _("Refresh Interval: "));
- d_printf("<input type=text size=2 name=\"refresh_interval\" value=\"%d\">\n",
+ printf("<input type=submit value=\"Auto Refresh\" name=autorefresh>\n");
+ printf("<br>Refresh Interval: ");
+ printf("<input type=text size=2 name=\"refresh_interval\" value=%d>\n",
refresh_interval);
} else {
- d_printf("<input type=submit value=\"%s\" name=\"norefresh\">\n", _("Stop Refreshing"));
- d_printf("<br>%s%d\n", _("Refresh Interval: "), refresh_interval);
- d_printf("<input type=hidden name=\"refresh\" value=\"1\">\n");
+ printf("<input type=submit value=\"Stop Refreshing\" name=norefresh>\n");
+ printf("<br>Refresh Interval: %d\n", refresh_interval);
+ printf("<input type=hidden name=refresh value=1>\n");
}
- d_printf("<p>\n");
+ printf("<p>\n");
if (!tdb) {
/* open failure either means no connections have been
- made */
+ made or status=no */
+ if (!lp_status(-1))
+ printf("You need to have status=yes in your smb config file\n");
}
- d_printf("<table>\n");
+ printf("<table>\n");
- d_printf("<tr><td>%s</td><td>%s</td></tr>", _("version:"), SAMBA_VERSION_STRING);
+ printf("<tr><td>version:</td><td>%s</td></tr>",VERSION);
fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("smbd:"), smbd_running()?_("running"):_("not running"));
+ printf("<tr><td>smbd:</td><td>%srunning</td>\n",smbd_running()?"":"not ");
if (geteuid() == 0) {
if (smbd_running()) {
- nr_running++;
- d_printf("<td><input type=submit name=\"smbd_stop\" value=\"%s\"></td>\n", _("Stop smbd"));
+ printf("<td><input type=submit name=\"smbd_stop\" value=\"Stop smbd\"></td>\n");
} else {
- d_printf("<td><input type=submit name=\"smbd_start\" value=\"%s\"></td>\n", _("Start smbd"));
+ printf("<td><input type=submit name=\"smbd_start\" value=\"Start smbd\"></td>\n");
}
- d_printf("<td><input type=submit name=\"smbd_restart\" value=\"%s\"></td>\n", _("Restart smbd"));
+ printf("<td><input type=submit name=\"smbd_restart\" value=\"Restart smbd\"></td>\n");
}
- d_printf("</tr>\n");
+ printf("</tr>\n");
fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("nmbd:"), nmbd_running()?_("running"):_("not running"));
+ printf("<tr><td>nmbd:</td><td>%srunning</td>\n",nmbd_running()?"":"not ");
if (geteuid() == 0) {
if (nmbd_running()) {
- nr_running++;
- d_printf("<td><input type=submit name=\"nmbd_stop\" value=\"%s\"></td>\n", _("Stop nmbd"));
+ printf("<td><input type=submit name=\"nmbd_stop\" value=\"Stop nmbd\"></td>\n");
} else {
- d_printf("<td><input type=submit name=\"nmbd_start\" value=\"%s\"></td>\n", _("Start nmbd"));
+ printf("<td><input type=submit name=\"nmbd_start\" value=\"Start nmbd\"></td>\n");
}
- d_printf("<td><input type=submit name=\"nmbd_restart\" value=\"%s\"></td>\n", _("Restart nmbd"));
+ printf("<td><input type=submit name=\"nmbd_restart\" value=\"Restart nmbd\"></td>\n");
}
- d_printf("</tr>\n");
+ printf("</tr>\n");
-#ifdef WITH_WINBIND
- fflush(stdout);
- d_printf("<tr><td>%s</td><td>%s</td>\n", _("winbindd:"), winbindd_running()?_("running"):_("not running"));
- if (geteuid() == 0) {
- if (winbindd_running()) {
- nr_running++;
- d_printf("<td><input type=submit name=\"winbindd_stop\" value=\"%s\"></td>\n", _("Stop winbindd"));
- } else {
- d_printf("<td><input type=submit name=\"winbindd_start\" value=\"%s\"></td>\n", _("Start winbindd"));
- }
- d_printf("<td><input type=submit name=\"winbindd_restart\" value=\"%s\"></td>\n", _("Restart winbindd"));
- }
- d_printf("</tr>\n");
-#endif
-
- if (geteuid() == 0) {
- d_printf("<tr><td></td><td></td>\n");
- if (nr_running >= 1) {
- /* stop, restart all */
- d_printf("<td><input type=submit name=\"all_stop\" value=\"%s\"></td>\n", _("Stop All"));
- d_printf("<td><input type=submit name=\"all_restart\" value=\"%s\"></td>\n", _("Restart All"));
- }
- else if (nr_running == 0) {
- /* start all */
- d_printf("<td><input type=submit name=\"all_start\" value=\"%s\"></td>\n", _("Start All"));
- }
- d_printf("</tr>\n");
- }
- d_printf("</table>\n");
+ printf("</table>\n");
fflush(stdout);
- d_printf("<p><h3>%s</h3>\n", _("Active Connections"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th>\n", _("PID"), _("Client"), _("IP address"), _("Date"));
+ printf("<p><h3>Active Connections</h3>\n");
+ printf("<table border=1>\n");
+ printf("<tr><th>PID</th><th>Client</th><th>IP address</th><th>Date</th>\n");
if (geteuid() == 0) {
- d_printf("<th>%s</th>\n", _("Kill"));
+ printf("<th>Kill</th>\n");
}
- d_printf("</tr>\n");
+ printf("</tr>\n");
if (tdb) tdb_traverse(tdb, traverse_fn2, NULL);
- d_printf("</table><p>\n");
+ printf("</table><p>\n");
- d_printf("<p><h3>%s</h3>\n", _("Active Shares"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n\n",
- _("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date"));
+ printf("<p><h3>Active Shares</h3>\n");
+ printf("<table border=1>\n");
+ printf("<tr><th>Share</th><th>User</th><th>Group</th><th>PID</th><th>Client</th><th>Date</th></tr>\n\n");
if (tdb) tdb_traverse(tdb, traverse_fn3, NULL);
- d_printf("</table><p>\n");
+ printf("</table><p>\n");
- d_printf("<h3>%s</h3>\n", _("Open Files"));
- d_printf("<table border=1>\n");
- d_printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", _("PID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date"));
+ printf("<h3>Open Files</h3>\n");
+ printf("<table border=1>\n");
+ printf("<tr><th>%s</th><th>Sharing</th><th>R/W</th><th>Oplock</th><th>File</th><th>Date</th></tr>\n", PID_or_Machine ? "Client" : "PID");
locking_init(1);
share_mode_forall(print_share_mode);
locking_end();
- d_printf("</table>\n");
+ printf("</table>\n");
if (tdb) tdb_close(tdb);
- d_printf("<br><input type=submit name=\"show_client_in_col_1\" value=\"%s\">\n", _("Show Client in col 1"));
- d_printf("<input type=submit name=\"show_pid_in_col_1\" value=\"%s\">\n", _("Show PID in col 1"));
+ printf("<br><input type=submit name=\"show_client_in_col_1\" value=\"Show Client in col 1\">\n");
+ printf("<input type=submit name=\"show_pid_in_col_1\" value=\"Show PID in col 1\">\n");
- d_printf("</FORM>\n");
+ printf("</FORM>\n");
if (autorefresh) {
/* this little JavaScript allows for automatic refresh
of the page. There are other methods but this seems
to be the best alternative */
- d_printf("<script language=\"JavaScript\">\n");
- d_printf("<!--\nsetTimeout('window.location.replace(\"%s/status?refresh_interval=%d&refresh=1\")', %d)\n",
+ printf("<script language=\"JavaScript\">\n");
+ printf("<!--\nsetTimeout('window.location.replace(\"%s/status?refresh_interval=%d&refresh=1\")', %d)\n",
cgi_baseurl(),
refresh_interval,
refresh_interval*1000);
- d_printf("//-->\n</script>\n");
+ printf("//-->\n</script>\n");
}
}
diff --git a/source/web/swat.c b/source/web/swat.c
index ed53d0d7128..fd1bac335fd 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -1,7 +1,7 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 2.2.6
Samba Web Administration Tool
- Version 3.0.0
Copyright (C) Andrew Tridgell 1997-2002
Copyright (C) John H Terpstra 2002
@@ -20,17 +20,16 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/**
- * @defgroup swat SWAT - Samba Web Administration Tool
- * @{
- * @file swat.c
- *
- * @brief Samba Web Administration Tool.
- **/
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
#include "includes.h"
-#include "../web/swat_proto.h"
+#include "smb.h"
+
+#define GLOBALS_SNUM -1
+static pstring servicesf = CONFIGFILE;
static BOOL demo_mode = False;
static BOOL have_write_access = False;
static BOOL have_read_access = False;
@@ -51,10 +50,26 @@ static int iNumNonAutoPrintServices = 0;
#define ENABLE_USER_FLAG "enable_user_flag"
#define RHOST "remote_host"
+typedef struct html_conversion {
+ const char src;
+ const char *dest;
+} html_conversion;
+
+static const html_conversion entities[] = {
+ { '"', "&quot;" },
+ { '&', "&amp;" },
+ { '<', "&lt;" },
+ { '>', "&gt;" },
+ { '\0', NULL },
+};
+
+/* we need these because we link to locking*.o */
+ void become_root(void) {}
+ void unbecome_root(void) {}
/****************************************************************************
****************************************************************************/
-static int enum_index(int value, const struct enum_list *enumlist)
+static int enum_index(int value, struct enum_list *enumlist)
{
int i;
for (i=0;enumlist[i].name;i++)
@@ -62,7 +77,7 @@ static int enum_index(int value, const struct enum_list *enumlist)
return(i);
}
-static char *fix_backslash(const char *str)
+static char *fix_backslash(char *str)
{
static char newstring[1024];
char *p = newstring;
@@ -76,15 +91,60 @@ static char *fix_backslash(const char *str)
return newstring;
}
-static char *stripspaceupper(const char *str)
+static char *htmlentities(char *str)
{
- static char newstring[1024];
- char *p = newstring;
+ int i,j, destlen = 0;
+ int length = strlen(str);
+ /* Feel free to use a pstring if appropriate -- I haven't
+ checked if it's guaranteed to be long enough, and suspect it
+ isn't. -SRL */
+ char *dststr = NULL;
+ char *p;
- while (*str) {
- if (*str != ' ') *p++ = toupper(*str);
- ++str;
+ for (i = 0; i < length; i++) {
+ for (j = 0; entities[j].src; j++) {
+ if (str[i] == entities[j].src) {
+ destlen += strlen(entities[j].dest);
+ break;
+ }
+ }
+ if (!entities[j].src) {
+ destlen++;
+ }
+ }
+ if (length == destlen) {
+ return(strdup(str));
}
+ p = dststr = malloc(destlen + 1);
+ if (!dststr) {
+ return(NULL);
+ }
+ dststr[destlen] = '\0';
+ for (i = 0; i < length; i++) {
+ for (j = 0; entities[j].src; j++) {
+ if (str[i] == entities[j].src) {
+ strncpy(p, entities[j].dest,
+ strlen(entities[j].dest));
+ p += strlen(entities[j].dest);
+ break;
+ }
+ }
+ if (!entities[j].src) {
+ *p++ = str[i];
+ }
+ }
+ return(dststr);
+}
+
+static char *stripspace(const char *str)
+{
+static char newstring[1024];
+char *p = newstring;
+
+ while (*str) {
+ if (*str != ' ') *p++ = *str;
+ ++str;
+ }
*p = '\0';
return newstring;
}
@@ -108,23 +168,22 @@ static char *make_parm_name(const char *label)
****************************************************************************/
static int include_html(const char *fname)
{
- int fd;
+ FILE *f = sys_fopen(fname,"r");
char buf[1024];
int ret;
- fd = web_open(fname, O_RDONLY, 0);
-
- if (fd == -1) {
- d_printf(_("ERROR: Can't open %s"), fname);
- d_printf("\n");
+ if (!f) {
+ printf("ERROR: Can't open %s\n", fname);
return 0;
}
- while ((ret = read(fd, buf, sizeof(buf))) > 0) {
- write(1, buf, ret);
+ while (!feof(f)) {
+ ret = fread(buf, 1, sizeof(buf), f);
+ if (ret <= 0) break;
+ fwrite(buf, 1, ret, stdout);
}
- close(fd);
+ fclose(f);
return 1;
}
@@ -134,55 +193,23 @@ static int include_html(const char *fname)
static void print_header(void)
{
if (!cgi_waspost()) {
- d_printf("Expires: 0\r\n");
+ printf("Expires: 0\r\n");
}
- d_printf("Content-type: text/html\r\n\r\n");
+ printf("Content-type: text/html\r\n\r\n");
if (!include_html("include/header.html")) {
- d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
- d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
+ printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
+ printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
}
}
-/* *******************************************************************
- show parameter label with translated name in the following form
- because showing original and translated label in one line looks
- too long, and showing translated label only is unusable for
- heavy users.
- -------------------------------
- HELP security [combo box][button]
- SECURITY
- -------------------------------
- (capital words are translated by gettext.)
- if no translation is available, then same form as original is
- used.
- "i18n_translated_parm" class is used to change the color of the
- translated parameter with CSS.
- **************************************************************** */
-static const char* get_parm_translated(
- const char* pAnchor, const char* pHelp, const char* pLabel)
-{
- const char* pTranslated = _(pLabel);
- static pstring output;
- if(strcmp(pLabel, pTranslated) != 0)
- {
- pstr_sprintf(output,
- "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
- pAnchor, pHelp, pLabel, pTranslated);
- return output;
- }
- pstr_sprintf(output,
- "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
- pAnchor, pHelp, pLabel);
- return output;
-}
/****************************************************************************
finish off the page
****************************************************************************/
static void print_footer(void)
{
if (!include_html("include/footer.html")) {
- d_printf("\n</BODY>\n</HTML>\n");
+ printf("\n</BODY>\n</HTML>\n");
}
}
@@ -193,111 +220,102 @@ static void show_parameter(int snum, struct parm_struct *parm)
{
int i;
void *ptr = parm->ptr;
+ char* str;
if (parm->class == P_LOCAL && snum >= 0) {
ptr = lp_local_ptr(snum, ptr);
}
- d_printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
+ str = stripspace(parm->label);
+ strupper (str);
+ printf("<tr><td><A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\">Help</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s</td><td>",
+ str, parm->label);
+
switch (parm->type) {
case P_CHAR:
- d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
+ printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
make_parm_name(parm->label), *(char *)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
- _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
- break;
-
- case P_LIST:
- d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
- make_parm_name(parm->label));
- if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
- char **list = *(char ***)ptr;
- for (;*list;list++) {
- /* enclose in quotes if the string contains a space */
- if ( strchr_m(*list, ' ') )
- d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
- else
- d_printf("%s%s", *list, ((*(list+1))?", ":""));
- }
- }
- d_printf("\">");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
- _("Set Default"), make_parm_name(parm->label));
- if (parm->def.lvalue) {
- char **list = (char **)(parm->def.lvalue);
- for (; *list; list++) {
- /* enclose in quotes if the string contains a space */
- if ( strchr_m(*list, ' ') )
- d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
- else
- d_printf("%s%s", *list, ((*(list+1))?", ":""));
- }
- }
- d_printf("\'\">");
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
+ make_parm_name(parm->label),(char)(parm->def.cvalue));
break;
case P_STRING:
case P_USTRING:
- d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
- make_parm_name(parm->label), *(char **)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
+ str = htmlentities(*(char **)ptr);
+ printf("<input type=\"text\" size=\"40\" name=\"parm_%s\" value=\"%s\">",
+ make_parm_name(parm->label), str);
+ if (str != NULL) {
+ free(str);
+ }
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
+ make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
break;
case P_GSTRING:
case P_UGSTRING:
- d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
+ printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
make_parm_name(parm->label), (char *)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
+ make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
break;
case P_BOOL:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
- d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
- d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
+ printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
+ printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
+ printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
+ printf("</select>");
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
+ make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
break;
case P_BOOLREV:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
- d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
- d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
+ printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
+ printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
+ printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
+ printf("</select>");
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
+ make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
break;
case P_INTEGER:
- d_printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
+ if (strequal(parm->label,"log level")) {
+ printf("<input type=text size=40 name=\"parm_%s\" value=%d",
+ make_parm_name(parm->label),*(int *)ptr);
+ for (i = 1; i < DBGC_LAST; i ++) {
+ if (((int *)ptr)[i])
+ printf(",%s:%d",debug_classname_from_index(i),((int *)ptr)[i]);
+ }
+ printf(">");
+ } else {
+ printf("<input type=text size=8 name=\"parm_%s\" value=%d>",
+ make_parm_name(parm->label), *(int *)ptr);
+ }
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
+ make_parm_name(parm->label),(int)(parm->def.ivalue));
break;
case P_OCTAL:
- d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- _("Set Default"), make_parm_name(parm->label),
+ printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
+ make_parm_name(parm->label),
octal_string((int)(parm->def.ivalue)));
break;
case P_ENUM:
- d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
+ printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
for (i=0;parm->enum_list[i].name;i++) {
if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
- d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
+ printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
}
}
- d_printf("</select>");
- d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
- _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
+ printf("</select>");
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
+ make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
break;
case P_SEP:
break;
}
- d_printf("</td></tr>\n");
+ printf("</td></tr>\n");
}
/****************************************************************************
@@ -322,10 +340,9 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
if (printers & !(parm->flags & FLAG_PRINT)) continue;
if (!printers & !(parm->flags & FLAG_SHARE)) continue;
}
-
- if (!( parm_filter & FLAG_ADVANCED )) {
+ if (parm_filter == FLAG_BASIC) {
if (!(parm->flags & FLAG_BASIC)) {
- void *ptr = parm->ptr;
+ void *ptr = parm->ptr;
if (parm->class == P_LOCAL && snum >= 0) {
ptr = lp_local_ptr(snum, ptr);
@@ -336,10 +353,6 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
break;
- case P_LIST:
- if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
- break;
-
case P_STRING:
case P_USTRING:
if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
@@ -357,6 +370,8 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
case P_INTEGER:
case P_OCTAL:
+ if (strequal(parm->label,"log level"))
+ break;
if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
break;
@@ -366,17 +381,15 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
break;
case P_SEP:
continue;
- }
+ }
}
if (printers && !(parm->flags & FLAG_PRINT)) continue;
}
-
- if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
-
- if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
-
+ if (parm_filter == FLAG_WIZARD) {
+ if (!((parm->flags & FLAG_WIZARD))) continue;
+ }
if (heading && heading != last_heading) {
- d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
+ printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", heading);
last_heading = heading;
}
show_parameter(snum, parm);
@@ -389,19 +402,20 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
static BOOL load_config(BOOL save_def)
{
lp_resetnumservices();
- return lp_load(dyn_CONFIGFILE,False,save_def,False);
+ return lp_load(servicesf,False,save_def,False);
}
/****************************************************************************
write a config file
****************************************************************************/
-static void write_config(FILE *f, BOOL show_defaults)
+
+static void write_config(FILE *f, BOOL show_defaults, char *(*dos_to_ext)(const char *))
{
fprintf(f, "# Samba config file created using SWAT\n");
fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
fprintf(f, "# Date: %s\n\n", timestring(False));
- lp_dump(f, show_defaults, iNumNonAutoPrintServices);
+ lp_dump(f, show_defaults, iNumNonAutoPrintServices, dos_to_ext);
}
/****************************************************************************
@@ -412,10 +426,9 @@ static int save_reload(int snum)
FILE *f;
struct stat st;
- f = sys_fopen(dyn_CONFIGFILE,"w");
+ f = sys_fopen(servicesf,"w");
if (!f) {
- d_printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
- d_printf("\n");
+ printf("failed to open %s for writing\n", servicesf);
return 0;
}
@@ -425,20 +438,19 @@ static int save_reload(int snum)
#if defined HAVE_FCHMOD
fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
#else
- chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
+ chmod(servicesf, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
#endif
}
- write_config(f, False);
+ write_config(f, False, _dos_to_unix_static);
if (snum)
- lp_dump_one(f, False, snum);
+ lp_dump_one(f, False, snum, _dos_to_unix_static);
fclose(f);
lp_killunused(NULL);
if (!load_config(False)) {
- d_printf(_("Can't reload %s"), dyn_CONFIGFILE);
- d_printf("\n");
+ printf("Can't reload %s\n", servicesf);
return 0;
}
iNumNonAutoPrintServices = lp_numservices();
@@ -450,10 +462,17 @@ static int save_reload(int snum)
/****************************************************************************
commit one parameter
****************************************************************************/
-static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
+static void commit_parameter(int snum, struct parm_struct *parm, const char *cv)
{
int i;
char *s;
+ pstring v;
+
+ pstrcpy(v, cv);
+
+ /* lp_do_parameter() will do unix_to_dos(v). */
+ if(parm->flags & FLAG_DOS_STRING)
+ dos_to_unix(v);
if (snum < 0 && parm->class == P_LOCAL) {
/* this handles the case where we are changing a local
@@ -492,9 +511,9 @@ static void commit_parameters(int snum)
/****************************************************************************
spit out the html for a link with an image
****************************************************************************/
-static void image_link(const char *name, const char *hlink, const char *src)
+static void image_link(const char *name,const char *hlink, const char *src)
{
- d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
+ printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
cgi_baseurl(), hlink, src, name);
}
@@ -507,38 +526,23 @@ static void show_main_buttons(void)
char *p;
if ((p = cgi_user_name()) && strcmp(p, "root")) {
- d_printf(_("Logged in as <b>%s</b>"), p);
- d_printf("<p>\n");
+ printf("Logged in as <b>%s</b><p>\n", p);
}
- image_link(_("Home"), "", "images/home.gif");
+ image_link("Home", "", "images/home.gif");
if (have_write_access) {
- image_link(_("Globals"), "globals", "images/globals.gif");
- image_link(_("Shares"), "shares", "images/shares.gif");
- image_link(_("Printers"), "printers", "images/printers.gif");
- image_link(_("Wizard"), "wizard", "images/wizard.gif");
+ image_link("Globals", "globals", "images/globals.gif");
+ image_link("Shares", "shares", "images/shares.gif");
+ image_link("Printers", "printers", "images/printers.gif");
+ image_link("Wizard", "wizard", "images/wizard.gif");
}
if (have_read_access) {
- image_link(_("Status"), "status", "images/status.gif");
- image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
+ image_link("Status", "status", "images/status.gif");
+ image_link("View Config", "viewconfig","images/viewconfig.gif");
}
- image_link(_("Password Management"), "passwd", "images/passwd.gif");
+ image_link("Password Management", "passwd", "images/passwd.gif");
- d_printf("<HR>\n");
-}
-
-/****************************************************************************
- * Handle Display/Edit Mode CGI
- ****************************************************************************/
-static void ViewModeBoxes(int mode)
-{
- d_printf("<p>%s:&nbsp;\n", _("Current View Is"));
- d_printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
- d_printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
- d_printf("<br>%s:&nbsp;\n", _("Change View To"));
- d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
- d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
- d_printf("</p><br>\n");
+ printf("<HR>\n");
}
/****************************************************************************
@@ -560,19 +564,19 @@ static void viewconfig_page(void)
full_view = 1;
}
- d_printf("<H2>%s</H2>\n", _("Current Config"));
- d_printf("<form method=post>\n");
+ printf("<H2>Current Config</H2>\n");
+ printf("<form method=post>\n");
if (full_view) {
- d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
+ printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
} else {
- d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
+ printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
}
- d_printf("<p><pre>");
- write_config(stdout, full_view);
- d_printf("</pre>");
- d_printf("</form>\n");
+ printf("<p><pre>");
+ write_config(stdout, full_view, _dos_to_dos_static);
+ printf("</pre>");
+ printf("</form>\n");
}
/****************************************************************************
@@ -585,26 +589,26 @@ static void wizard_params_page(void)
/* Here we first set and commit all the parameters that were selected
in the previous screen. */
- d_printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
+ printf("<H2>Wizard Parameter Edit Page ...</H2>\n");
if (cgi_variable("Commit")) {
- commit_parameters(GLOBAL_SECTION_SNUM);
+ commit_parameters(GLOBALS_SNUM);
save_reload(0);
}
- d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
+ printf("<form name=\"swatform\" method=post action=wizard_params>\n");
if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
+ printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
- d_printf("<p>\n");
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
+ printf("<p>\n");
- d_printf("<table>\n");
- show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
- d_printf("</table>\n");
- d_printf("</form>\n");
+ printf("<table>\n");
+ show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
+ printf("</table>\n");
+ printf("</form>\n");
}
/****************************************************************************
@@ -612,9 +616,9 @@ static void wizard_params_page(void)
****************************************************************************/
static void rewritecfg_file(void)
{
- commit_parameters(GLOBAL_SECTION_SNUM);
+ commit_parameters(GLOBALS_SNUM);
save_reload(0);
- d_printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
+ printf("<H2>Note: smb.conf file has been read and rewritten</H2>\n");
}
/****************************************************************************
@@ -646,37 +650,37 @@ static void wizard_page(void)
HomeExpo = atoi(cgi_variable("HomeExpo"));
/* Plain text passwords are too badly broken - use encrypted passwords only */
- lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
+ lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
switch ( SerType ){
case 0:
/* Stand-alone Server */
- lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
+ lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
+ lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
break;
case 1:
/* Domain Member */
- lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
+ lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
+ lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
break;
case 2:
/* Domain Controller */
- lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
+ lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
+ lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
break;
}
switch ( winstype ) {
case 0:
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
+ lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
+ lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
break;
case 1:
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
+ lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
+ lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
break;
case 2:
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
- lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
+ lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
+ lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
break;
}
@@ -684,9 +688,9 @@ static void wizard_page(void)
if ((HomeExpo == 1) && (have_home == -1)) {
pstring unix_share;
- pstrcpy(unix_share,HOMES_NAME);
+ pstrcpy(unix_share, dos_to_unix_static(HOMES_NAME));
load_config(False);
- lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
+ lp_copy_service(GLOBALS_SNUM, unix_share);
iNumNonAutoPrintServices = lp_numservices();
have_home = lp_servicenumber(HOMES_NAME);
lp_do_parameter( have_home, "read only", "No");
@@ -701,7 +705,7 @@ static void wizard_page(void)
have_home = -1;
}
- commit_parameters(GLOBAL_SECTION_SNUM);
+ commit_parameters(GLOBALS_SNUM);
save_reload(0);
}
else
@@ -709,9 +713,8 @@ static void wizard_page(void)
/* Now determine smb.conf WINS settings */
if (lp_wins_support())
winstype = 1;
- if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
- winstype = 2;
-
+ if (strlen(lp_wins_server()) != 0 )
+ winstype = 2;
/* Do we have a homes share? */
have_home = lp_servicenumber(HOMES_NAME);
@@ -722,116 +725,99 @@ static void wizard_page(void)
role = lp_server_role();
/* Here we go ... */
- d_printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
- d_printf("<form method=post action=wizard>\n");
+ printf("<H2>Samba Configuration Wizard</H2>\n");
+ printf("<form method=post action=wizard>\n");
if (have_write_access) {
- d_printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
- d_printf("%s", _("The same will happen if you press the commit button."));
- d_printf("<br><br>\n");
- d_printf("<center>");
- d_printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
- d_printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
- d_printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
- d_printf("</center>\n");
- }
-
- d_printf("<hr>");
- d_printf("<center><table border=0>");
- d_printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
- d_printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
- d_printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
- d_printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
- d_printf("</tr>\n");
+ printf("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n");
+ printf("The same will happen if you press the commit button.");
+ printf("<br><br>");
+ printf("<center>");
+ printf("<input type=submit name=\"Rewrite\" value=\"Rewrite smb.conf file\"> &nbsp;&nbsp;");
+ printf("<input type=submit name=\"Commit\" value=\"Commit\"> &nbsp;&nbsp;");
+ printf("<input type=submit name=\"GetWizardParams\" value=\"Edit Parameter Values\">");
+ printf("</center>");
+ }
+
+ printf("<hr>");
+ printf("<center><table border=0>");
+ printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
+ printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
+ printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
+ printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
+ printf("</tr>");
if (role == ROLE_DOMAIN_BDC) {
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
- }
- d_printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
- d_printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
- d_printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
- d_printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
- d_printf("</tr>\n");
- d_printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
-
- /* Print out the list of wins servers */
- if(lp_wins_server_list()) {
- int i;
- const char **wins_servers = lp_wins_server_list();
- for(i = 0; wins_servers[i]; i++) d_printf("%s ", wins_servers[i]);
+ printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
}
-
- d_printf("\"></td></tr>\n");
+ printf("<tr><td><b>%s</b></td>\n", "Configure WINS As:&nbsp;");
+ printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
+ printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
+ printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
+ printf("<tr><td></td><td></td><td></td><td>Remote WINS Server&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"%s\"></td></tr>",lp_wins_server());
if (winstype == 3) {
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
- d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
- }
- d_printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
- d_printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
- d_printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
- d_printf("<td></td></tr>\n");
+ printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Error: WINS Server Mode and WINS Support both set in smb.conf</font></td></tr>");
+ printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
+ }
+ printf("</tr>");
+ printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
+ printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
+ printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
+ printf("<td></td></tr>");
/* Enable this when we are ready ....
- * d_printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
- * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
- * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
- * d_printf("<td></td></tr>\n");
+ * printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
+ * printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
+ * printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
+ * printf("<td></td></tr>");
*/
- d_printf("</table></center>");
- d_printf("<hr>");
+ printf("</table></center>");
+ printf("<hr>");
- d_printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
- d_printf("</form>\n");
+ printf("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n");
+ printf("</form>\n");
}
-
/****************************************************************************
display a globals editing page
****************************************************************************/
static void globals_page(void)
{
unsigned int parm_filter = FLAG_BASIC;
- int mode = 0;
- d_printf("<H2>%s</H2>\n", _("Global Parameters"));
+ printf("<H2>Global Variables</H2>\n");
+
+ if (cgi_variable("Advanced") && !cgi_variable("Basic"))
+ parm_filter = FLAG_ADVANCED;
if (cgi_variable("Commit")) {
- commit_parameters(GLOBAL_SECTION_SNUM);
+ commit_parameters(GLOBALS_SNUM);
save_reload(0);
}
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
- if ( cgi_variable("BasicMode"))
- mode = 0;
- if ( cgi_variable("AdvMode"))
- mode = 1;
-
- d_printf("<form name=\"swatform\" method=post action=globals>\n");
+ printf("<FORM name=\"swatform\" method=post>\n");
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- }
- d_printf("<br>\n");
if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
- _("Commit Changes"));
+ printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
+ }
+
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
+ if (parm_filter != FLAG_ADVANCED) {
+ printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
+ } else {
+ printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
}
+ printf("<p>\n");
+
+ printf("<table>\n");
+ show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
+ printf("</table>\n");
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
- _("Reset Values"));
+ if (parm_filter == FLAG_ADVANCED) {
+ printf("<input type=hidden name=\"Advanced\" value=1>\n");
+ }
- d_printf("<p>\n");
- d_printf("<table>\n");
- show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
- d_printf("</table>\n");
- d_printf("</form>\n");
+ printf("</FORM>\n");
}
/****************************************************************************
@@ -842,15 +828,17 @@ static void shares_page(void)
{
const char *share = cgi_variable("share");
char *s;
- int snum = -1;
+ int snum=-1;
int i;
- int mode = 0;
unsigned int parm_filter = FLAG_BASIC;
if (share)
snum = lp_servicenumber(share);
- d_printf("<H2>%s</H2>\n", _("Share Parameters"));
+ printf("<H2>Share Parameters</H2>\n");
+
+ if (cgi_variable("Advanced") && !cgi_variable("Basic"))
+ parm_filter = FLAG_ADVANCED;
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
@@ -865,77 +853,73 @@ static void shares_page(void)
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+ /* add_a_service() which is called by lp_copy_service()
+ will do unix_to_dos() conversion, so we need dos_to_unix() before the lp_copy_service(). */
+ pstring unix_share;
+ pstrcpy(unix_share, dos_to_unix_static(share));
load_config(False);
- lp_copy_service(GLOBAL_SECTION_SNUM, share);
+ lp_copy_service(GLOBALS_SNUM, unix_share);
iNumNonAutoPrintServices = lp_numservices();
save_reload(0);
snum = lp_servicenumber(share);
}
- d_printf("<FORM name=\"swatform\" method=post>\n");
+ printf("<FORM name=\"swatform\" method=post>\n");
- d_printf("<table>\n");
-
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
- if ( cgi_variable("BasicMode"))
- mode = 0;
- if ( cgi_variable("AdvMode"))
- mode = 1;
-
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- }
- d_printf("<br><tr>\n");
- d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
- d_printf("<td><select name=share>\n");
+ printf("<table>\n");
+ printf("<tr>\n");
+ printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
+ printf("<td><select name=share>\n");
if (snum < 0)
- d_printf("<option value=\" \"> \n");
+ printf("<option value=\" \"> \n");
for (i=0;i<lp_numservices();i++) {
s = lp_servicename(i);
if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
- d_printf("<option %s value=\"%s\">%s\n",
+ printf("<option %s value=\"%s\">%s\n",
(share && strcmp(share,s)==0)?"SELECTED":"",
s, s);
}
}
- d_printf("</select></td>\n");
+ printf("</select></td>\n");
if (have_write_access) {
- d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
+ printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
}
- d_printf("</tr>\n");
- d_printf("</table>");
- d_printf("<table>");
+ printf("</tr>\n");
+ printf("</table>");
+ printf("<table>");
if (have_write_access) {
- d_printf("<tr>\n");
- d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
- d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
+ printf("<tr>\n");
+ printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
+ printf("<td><input type=text size=30 name=newshare></td></tr>\n");
}
- d_printf("</table>");
+ printf("</table>");
if (snum >= 0) {
if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
+ printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
- d_printf("<p>\n");
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
+ if (parm_filter != FLAG_ADVANCED) {
+ printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
+ } else {
+ printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
+ }
+ printf("<p>\n");
}
if (snum >= 0) {
- d_printf("<table>\n");
+ printf("<table>\n");
show_parameters(snum, 1, parm_filter, 0);
- d_printf("</table>\n");
+ printf("</table>\n");
+ }
+
+ if (parm_filter == FLAG_ADVANCED) {
+ printf("<input type=hidden name=\"Advanced\" value=1>\n");
}
- d_printf("</FORM>\n");
+ printf("</FORM>\n");
}
/*************************************************************
@@ -950,7 +934,7 @@ static BOOL change_password(const char *remote_machine, const char *user_name,
pstring msg_str;
if (demo_mode) {
- d_printf("%s\n<p>", _("password change in demo mode rejected"));
+ printf("password change in demo mode rejected\n<p>");
return False;
}
@@ -958,12 +942,12 @@ static BOOL change_password(const char *remote_machine, const char *user_name,
ret = remote_password_change(remote_machine, user_name, old_passwd,
new_passwd, err_str, sizeof(err_str));
if(*err_str)
- d_printf("%s\n<p>", err_str);
+ printf("%s\n<p>", err_str);
return ret;
}
- if(!initialize_password_db(True)) {
- d_printf("%s\n<p>", _("Can't setup password database vectors."));
+ if(!initialize_password_db(False)) {
+ printf("Can't setup password database vectors.\n<p>");
return False;
}
@@ -971,9 +955,9 @@ static BOOL change_password(const char *remote_machine, const char *user_name,
msg_str, sizeof(msg_str));
if(*msg_str)
- d_printf("%s\n<p>", msg_str);
+ printf("%s\n<p>", msg_str);
if(*err_str)
- d_printf("%s\n<p>", err_str);
+ printf("%s\n<p>", err_str);
return ret;
}
@@ -989,7 +973,7 @@ static void chg_passwd(void)
/* Make sure users name has been specified */
if (strlen(cgi_variable(SWAT_USER)) == 0) {
- d_printf("<p>%s\n", _(" Must specify \"User Name\" "));
+ printf("<p> Must specify \"User Name\" \n");
return;
}
@@ -1005,26 +989,26 @@ static void chg_passwd(void)
*/
if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
- d_printf("<p>%s\n", _(" Must specify \"Old Password\" "));
+ printf("<p> Must specify \"Old Password\" \n");
return;
}
/* If changing a users password on a remote hosts we have to know what host */
if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
- d_printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
+ printf("<p> Must specify \"Remote Machine\" \n");
return;
}
/* Make sure new passwords have been specified */
if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
(strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
- d_printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
+ printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
return;
}
/* Make sure new passwords was typed correctly twice */
if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
- d_printf("<p>%s\n", _(" Re-typed password didn't match new password "));
+ printf("<p> Re-typed password didn't match new password\n");
return;
}
}
@@ -1042,26 +1026,20 @@ static void chg_passwd(void)
*/
local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
- local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
- local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
-
rslt = change_password(host,
cgi_variable(SWAT_USER),
cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
local_flags);
- if(cgi_variable(CHG_S_PASSWD_FLAG)) {
- d_printf("<p>");
+ if(local_flags == 0) {
if (rslt == True) {
- d_printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
- d_printf("\n");
+ printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
} else {
- d_printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
- d_printf("\n");
+ printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
}
}
@@ -1085,43 +1063,43 @@ static void passwd_page(void)
if (!new_name) new_name = "";
- d_printf("<H2>%s</H2>\n", _("Server Password Management"));
+ printf("<H2>Server Password Management</H2>\n");
- d_printf("<FORM name=\"swatform\" method=post>\n");
+ printf("<FORM name=\"swatform\" method=post>\n");
- d_printf("<table>\n");
+ printf("<table>\n");
/*
* Create all the dialog boxes for data collection
*/
- d_printf("<tr><td> %s : </td>\n", _("User Name"));
- d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
+ printf("<tr><td> User Name : </td>\n");
+ printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
if (!am_root()) {
- d_printf("<tr><td> %s : </td>\n", _("Old Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
+ printf("<tr><td> Old Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
}
- d_printf("<tr><td> %s : </td>\n", _("New Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
- d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
- d_printf("</table>\n");
+ printf("<tr><td> New Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
+ printf("<tr><td> Re-type New Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
+ printf("</table>\n");
/*
* Create all the control buttons for requesting action
*/
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- CHG_S_PASSWD_FLAG, _("Change Password"));
+ printf("<input type=submit name=%s value=\"Change Password\">\n",
+ CHG_S_PASSWD_FLAG);
if (demo_mode || am_root()) {
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- ADD_USER_FLAG, _("Add New User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- DELETE_USER_FLAG, _("Delete User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- DISABLE_USER_FLAG, _("Disable User"));
- d_printf("<input type=submit name=%s value=\"%s\">\n",
- ENABLE_USER_FLAG, _("Enable User"));
+ printf("<input type=submit name=%s value=\"Add New User\">\n",
+ ADD_USER_FLAG);
+ printf("<input type=submit name=%s value=\"Delete User\">\n",
+ DELETE_USER_FLAG);
+ printf("<input type=submit name=%s value=\"Disable User\">\n",
+ DISABLE_USER_FLAG);
+ printf("<input type=submit name=%s value=\"Enable User\">\n",
+ ENABLE_USER_FLAG);
}
- d_printf("<p></FORM>\n");
+ printf("<p></FORM>\n");
/*
* Do some work if change, add, disable or enable was
@@ -1132,35 +1110,35 @@ static void passwd_page(void)
chg_passwd();
}
- d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
+ printf("<H2>Client/Server Password Management</H2>\n");
- d_printf("<FORM name=\"swatform\" method=post>\n");
+ printf("<FORM name=\"swatform\" method=post>\n");
- d_printf("<table>\n");
+ printf("<table>\n");
/*
* Create all the dialog boxes for data collection
*/
- d_printf("<tr><td> %s : </td>\n", _("User Name"));
- d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
- d_printf("<tr><td> %s : </td>\n", _("Old Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
- d_printf("<tr><td> %s : </td>\n", _("New Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
- d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
- d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
- d_printf("<tr><td> %s : </td>\n", _("Remote Machine"));
- d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
-
- d_printf("</table>");
+ printf("<tr><td> User Name : </td>\n");
+ printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
+ printf("<tr><td> Old Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
+ printf("<tr><td> New Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
+ printf("<tr><td> Re-type New Password : </td>\n");
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
+ printf("<tr><td> Remote Machine : </td>\n");
+ printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
+
+ printf("</table>");
/*
* Create all the control buttons for requesting action
*/
- d_printf("<input type=submit name=%s value=\"%s\">",
- CHG_R_PASSWD_FLAG, _("Change Password"));
+ printf("<input type=submit name=%s value=\"Change Password\">",
+ CHG_R_PASSWD_FLAG);
- d_printf("<p></FORM>\n");
+ printf("<p></FORM>\n");
/*
* Do some work if a request has been made to change the
@@ -1182,19 +1160,21 @@ static void printers_page(void)
char *s;
int snum=-1;
int i;
- int mode = 0;
unsigned int parm_filter = FLAG_BASIC;
if (share)
snum = lp_servicenumber(share);
- d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
-
- d_printf("<H3>%s</H3>\n", _("Important Note:"));
- d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
- d_printf(_("are autoloaded printers from "));
- d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
- d_printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
+ printf("<H2>Printer Parameters</H2>\n");
+
+ printf("<H3>Important Note:</H3>\n");
+ printf("Printer names marked with [*] in the Choose Printer drop-down box ");
+ printf("are autoloaded printers from ");
+ printf("<A HREF=\"/swat/help/smb.conf.5.html#PRINTCAPNAME\" target=\"docs\">Printcap Name</A>.\n");
+ printf("Attempting to delete these printers from SWAT will have no effect.\n");
+
+ if (cgi_variable("Advanced") && !cgi_variable("Basic"))
+ parm_filter = FLAG_ADVANCED;
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
@@ -1212,8 +1192,12 @@ static void printers_page(void)
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+ /* add_a_service() which is called by lp_copy_service()
+ will do unix_to_dos() conversion, so we need dos_to_unix() before the lp_copy_service(). */
+ pstring unix_share;
+ pstrcpy(unix_share, dos_to_unix_static(share));
load_config(False);
- lp_copy_service(GLOBAL_SECTION_SNUM, share);
+ lp_copy_service(GLOBALS_SNUM, unix_share);
iNumNonAutoPrintServices = lp_numservices();
snum = lp_servicenumber(share);
lp_do_parameter(snum, "print ok", "Yes");
@@ -1221,88 +1205,77 @@ static void printers_page(void)
snum = lp_servicenumber(share);
}
- d_printf("<FORM name=\"swatform\" method=post>\n");
+ printf("<FORM name=\"swatform\" method=post>\n");
- if ( cgi_variable("ViewMode") )
- mode = atoi(cgi_variable("ViewMode"));
- if ( cgi_variable("BasicMode"))
- mode = 0;
- if ( cgi_variable("AdvMode"))
- mode = 1;
-
- ViewModeBoxes( mode );
- switch ( mode ) {
- case 0:
- parm_filter = FLAG_BASIC;
- break;
- case 1:
- parm_filter = FLAG_ADVANCED;
- break;
- }
- d_printf("<table>\n");
- d_printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
- d_printf("<td><select name=\"share\">\n");
+ printf("<table>\n");
+ printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
+ printf("<td><select name=share>\n");
if (snum < 0 || !lp_print_ok(snum))
- d_printf("<option value=\" \"> \n");
+ printf("<option value=\" \"> \n");
for (i=0;i<lp_numservices();i++) {
s = lp_servicename(i);
if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
if (i >= iNumNonAutoPrintServices)
- d_printf("<option %s value=\"%s\">[*]%s\n",
+ printf("<option %s value=\"%s\">[*]%s\n",
(share && strcmp(share,s)==0)?"SELECTED":"",
s, s);
else
- d_printf("<option %s value=\"%s\">%s\n",
+ printf("<option %s value=\"%s\">%s\n",
(share && strcmp(share,s)==0)?"SELECTED":"",
s, s);
}
}
- d_printf("</select></td>");
+ printf("</select></td>");
if (have_write_access) {
- d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
+ printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
}
- d_printf("</tr>");
- d_printf("</table>\n");
+ printf("</tr>");
+ printf("</table>\n");
if (have_write_access) {
- d_printf("<table>\n");
- d_printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
- d_printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
- d_printf("</table>");
+ printf("<table>\n");
+ printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
+ printf("<td><input type=text size=30 name=newshare></td></tr>\n");
+ printf("</table>");
}
if (snum >= 0) {
if (have_write_access) {
- d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
+ printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
- d_printf("<p>\n");
+ printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
+ if (parm_filter != FLAG_ADVANCED) {
+ printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
+ } else {
+ printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
+ }
+ printf("<p>\n");
}
if (snum >= 0) {
- d_printf("<table>\n");
+ printf("<table>\n");
show_parameters(snum, 1, parm_filter, 1);
- d_printf("</table>\n");
+ printf("</table>\n");
}
- d_printf("</FORM>\n");
-}
+ if (parm_filter == FLAG_ADVANCED) {
+ printf("<input type=hidden name=\"Advanced\" value=1>\n");
+ }
+
+ printf("</FORM>\n");
+}
-/**
- * main function for SWAT.
- **/
+/****************************************************************************
+ MAIN()
+****************************************************************************/
int main(int argc, char *argv[])
{
+ extern char *optarg;
+ extern int optind;
+ extern FILE *dbf;
int opt;
const char *page;
- poptContext pc;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
fault_setup(NULL);
umask(S_IWGRP | S_IWOTH);
@@ -1314,50 +1287,54 @@ static void printers_page(void)
/* just in case it goes wild ... */
alarm(300);
- setlinebuf(stdout);
-
/* we don't want any SIGPIPE messages */
BlockSignals(True,SIGPIPE);
- dbf = x_fopen("/dev/null", O_WRONLY, 0);
- if (!dbf) dbf = x_stderr;
+ dbf = sys_fopen("/dev/null", "w");
+ if (!dbf) dbf = stderr;
/* we don't want stderr screwing us up */
close(2);
open("/dev/null", O_WRONLY);
- pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
-
- /* Parse command line options */
-
- while((opt = poptGetNextOpt(pc)) != -1) { }
-
- poptFreeContext(pc);
-
+ while ((opt = getopt(argc, argv,"s:a")) != EOF) {
+ switch (opt) {
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+ case 'a':
+ demo_mode = True;
+ break;
+ }
+ }
+
setup_logging(argv[0],False);
+ charset_initialise();
load_config(True);
iNumNonAutoPrintServices = lp_numservices();
load_printers();
+ codepage_initialise(lp_client_code_page());
- cgi_setup(dyn_SWATDIR, !demo_mode);
+ cgi_setup(SWATDIR, !demo_mode);
print_header();
+
+ cgi_load_variables(NULL);
- cgi_load_variables();
-
- if (!file_exist(dyn_CONFIGFILE, NULL)) {
+ if (!file_exist(servicesf, NULL)) {
have_read_access = True;
have_write_access = True;
} else {
/* check if the authenticated user has write access - if not then
don't show write options */
- have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
+ have_write_access = (access(servicesf,W_OK) == 0);
/* if the user doesn't have read access to smb.conf then
don't let them view it */
- have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
+ have_read_access = (access(servicesf,R_OK) == 0);
}
+
show_main_buttons();
page = cgi_pathinfo();
@@ -1369,18 +1346,18 @@ static void printers_page(void)
shares_page();
} else if (have_read_access && strcmp(page,"printers")==0) {
printers_page();
- } else if (have_read_access && strcmp(page,"status")==0) {
- status_page();
- } else if (have_read_access && strcmp(page,"viewconfig")==0) {
- viewconfig_page();
- } else if (strcmp(page,"passwd")==0) {
- passwd_page();
} else if (have_read_access && strcmp(page,"wizard")==0) {
wizard_page();
} else if (have_read_access && strcmp(page,"wizard_params")==0) {
wizard_params_page();
+ } else if (have_read_access && strcmp(page,"status")==0) {
+ status_page();
+ } else if (have_read_access && strcmp(page,"viewconfig")==0) {
+ viewconfig_page();
} else if (have_read_access && strcmp(page,"rewritecfg")==0) {
rewritecfg_file();
+ } else if (strcmp(page,"passwd")==0) {
+ passwd_page();
} else {
welcome_page();
}
@@ -1388,5 +1365,3 @@ static void printers_page(void)
print_footer();
return 0;
}
-
-/** @} **/
diff --git a/source/wrepld/parser.c b/source/wrepld/parser.c
deleted file mode 100644
index b619cb0cef5..00000000000
--- a/source/wrepld/parser.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Jean François Micouleau 1998-2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern TALLOC_CTX *mem_ctx;
-
-/****************************************************************************
-grow the send buffer if necessary
-****************************************************************************/
-BOOL grow_buffer(struct BUFFER *buffer, int more)
-{
- char *temp;
-
- DEBUG(10,("grow_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
-
- /* grow by at least 256 bytes */
- if (more<256)
- more=256;
-
- if (buffer->offset+more >= buffer->length) {
- temp=(char *)talloc_realloc(mem_ctx, buffer->buffer, sizeof(char)* (buffer->length+more) );
- if (temp==NULL) {
- DEBUG(0,("grow_buffer: can't grow buffer\n"));
- return False;
- }
- buffer->length+=more;
- buffer->buffer=temp;
- }
-
- return True;
-}
-
-/****************************************************************************
-check if the buffer has that much data
-****************************************************************************/
-static BOOL check_buffer(struct BUFFER *buffer, int more)
-{
- DEBUG(10,("check_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
-
- if (buffer->offset+more > buffer->length) {
- DEBUG(10,("check_buffer: buffer smaller than requested, size is: %d needed: %d\n", buffer->length, buffer->offset+more));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-decode a WINS_OWNER struct
-****************************************************************************/
-static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner)
-{
- if(!check_buffer(inbuf, 24))
- return;
-
- wins_owner->address.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+4))<<32;
- wins_owner->max_version|=RIVAL(inbuf->buffer, inbuf->offset+8);
- wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+12))<<32;
- wins_owner->min_version|=RIVAL(inbuf->buffer, inbuf->offset+16);
- wins_owner->type=RIVAL(inbuf->buffer, inbuf->offset+20);
- inbuf->offset+=24;
-
-}
-
-/****************************************************************************
-decode a WINS_NAME struct
-****************************************************************************/
-static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
-{
- char *p;
- int i;
-
- if(!check_buffer(outbuf, 40))
- return;
-
- wins_name->name_len=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- memcpy(wins_name->name,outbuf->buffer+outbuf->offset, 15);
- wins_name->name[15]='\0';
- if((p = strchr(wins_name->name,' ')) != NULL)
- *p = 0;
-
- outbuf->offset+=15;
-
- wins_name->type=(int)outbuf->buffer[outbuf->offset++];
-
- /*
- * fix to bug in WINS replication,
- * present in all versions including W2K SP2 !
- */
- if (wins_name->name[0]==0x1B) {
- wins_name->name[0]=(char)wins_name->type;
- wins_name->type=0x1B;
- }
-
- wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- wins_name->name_flag=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- wins_name->group_flag=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf->buffer, outbuf->offset))<<32;
- outbuf->offset+=4;
- wins_name->id|=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- /* special groups have multiple address */
- if (wins_name->name_flag & 2) {
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- }
- else
- wins_name->num_ip=1;
-
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->owner.s_addr=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- wins_name->others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*wins_name->num_ip);
- if (wins_name->others==NULL)
- return;
-
- if(!check_buffer(outbuf, 4*wins_name->num_ip))
- return;
- for (i=0; i<wins_name->num_ip; i++) {
- wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
- }
- }
-
- if(!check_buffer(outbuf, 4))
- return;
- wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a update notification request
-****************************************************************************/
-static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
- un_rq->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- un_rq->wins_owner=(WINS_OWNER *)talloc(mem_ctx, un_rq->partner_count*sizeof(WINS_OWNER));
- if (un_rq->wins_owner==NULL)
- return;
-
- for (i=0; i<un_rq->partner_count; i++)
- decode_wins_owner(inbuf, &un_rq->wins_owner[i]);
-
- if(!check_buffer(inbuf, 4))
- return;
- un_rq->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-}
-
-/****************************************************************************
-decode a send entries request
-****************************************************************************/
-static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq)
-{
- decode_wins_owner(inbuf, &se_rq->wins_owner);
-}
-
-/****************************************************************************
-decode a send entries reply
-****************************************************************************/
-static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
- se_rp->max_names = RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- se_rp->wins_name=(WINS_NAME *)talloc(mem_ctx, se_rp->max_names*sizeof(WINS_NAME));
- if (se_rp->wins_name==NULL)
- return;
-
- for (i=0; i<se_rp->max_names; i++)
- decode_wins_name(inbuf, &se_rp->wins_name[i]);
-}
-
-/****************************************************************************
-decode a add version number map table reply
-****************************************************************************/
-static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep)
-{
- int i;
-
- if(!check_buffer(inbuf, 4))
- return;
-
- avmt_rep->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-
- avmt_rep->wins_owner=(WINS_OWNER *)talloc(mem_ctx, avmt_rep->partner_count*sizeof(WINS_OWNER));
- if (avmt_rep->wins_owner==NULL)
- return;
-
- for (i=0; i<avmt_rep->partner_count; i++)
- decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]);
-
- if(!check_buffer(inbuf, 4))
- return;
- avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
- inbuf->offset+=4;
-}
-
-/****************************************************************************
-decode a replicate packet and fill a structure
-****************************************************************************/
-static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep)
-{
- if(!check_buffer(inbuf, 4))
- return;
-
- rep->msg_type = RIVAL(inbuf->buffer, inbuf->offset);
-
- inbuf->offset+=4;
-
- switch (rep->msg_type) {
- case 0:
- break;
- case 1:
- /* add version number map table reply */
- decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep);
- break;
- case 2:
- /* send entry request */
- decode_send_entries_request(inbuf, &rep->se_rq);
- break;
- case 3:
- /* send entry request */
- decode_send_entries_reply(inbuf, &rep->se_rp);
- break;
- case 4:
- /* update notification request */
- decode_update_notify_request(inbuf, &rep->un_rq);
- break;
- default:
- DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type));
- break;
- }
-}
-
-/****************************************************************************
-read the generic header and fill the struct.
-****************************************************************************/
-static void read_generic_header(struct BUFFER *inbuf, generic_header *q)
-{
- if(!check_buffer(inbuf, 16))
- return;
-
- q->data_size = RIVAL(inbuf->buffer, inbuf->offset+0);
- q->opcode = RIVAL(inbuf->buffer, inbuf->offset+4);
- q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+8);
- q->mess_type = RIVAL(inbuf->buffer, inbuf->offset+12);
-}
-
-/*******************************************************************
-decode a start association request
-********************************************************************/
-static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q)
-{
- if(!check_buffer(inbuf, 8))
- return;
-
- q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+0);
- q->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
- q->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r)
-{
- if(!check_buffer(inbuf, 8))
- return;
-
- r->assoc_ctx=RIVAL(inbuf->buffer, inbuf->offset+0);
- r->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
- r->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r)
-{
- if(!check_buffer(inbuf, 4))
- return;
-
- r->reason=RIVAL(inbuf->buffer, inbuf->offset);
-}
-
-/****************************************************************************
-decode a packet and fill a generic structure
-****************************************************************************/
-void decode_generic_packet(struct BUFFER *inbuf, GENERIC_PACKET *q)
-{
- read_generic_header(inbuf, &q->header);
-
- inbuf->offset+=16;
-
- switch (q->header.mess_type) {
- case 0:
- decode_start_assoc_request(inbuf, &q->sa_rq);
- break;
- case 1:
- decode_start_assoc_reply(inbuf, &q->sa_rp);
- break;
- case 2:
- decode_stop_assoc(inbuf, &q->so);
- break;
- case 3:
- decode_replicate(inbuf, &q->rep);
- break;
- default:
- DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type));
- break;
- }
-}
-
-/****************************************************************************
-encode a WINS_OWNER struct
-****************************************************************************/
-static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner)
-{
- if (!grow_buffer(outbuf, 24))
- return;
-
- SIVAL(outbuf->buffer, outbuf->offset, wins_owner->address.s_addr);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version>>32));
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, (int)(wins_owner->max_version&0xffffffff));
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version>>32);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->min_version&0xffffffff);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_owner->type);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-encode a WINS_NAME struct
-****************************************************************************/
-static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
-{
- int i;
-
- if (!grow_buffer(outbuf, 48+(4*wins_name->num_ip)))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_len);
- outbuf->offset+=4;
-
- memset(outbuf->buffer+outbuf->offset, ' ', 15);
-
- /* to prevent copying the leading \0 */
- memcpy(outbuf->buffer+outbuf->offset, wins_name->name, strlen(wins_name->name));
- outbuf->offset+=15;
-
- outbuf->buffer[outbuf->offset++]=(char)wins_name->type;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->empty);
- outbuf->offset+=4;
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->name_flag);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->group_flag);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id>>32);
- outbuf->offset+=4;
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->id);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->num_ip);
- outbuf->offset+=4;
- }
-
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->owner.s_addr);
- outbuf->offset+=4;
-
- if (wins_name->name_flag & 2) {
- for (i=0;i<wins_name->num_ip;i++) {
- SIVAL(outbuf->buffer, outbuf->offset, wins_name->others[i].s_addr);
- outbuf->offset+=4;
- }
- }
-
- RSIVAL(outbuf->buffer, outbuf->offset, wins_name->foo);
- outbuf->offset+=4;
-}
-
-/****************************************************************************
-encode a update notification request
-****************************************************************************/
-static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq)
-{
- int i;
-
- if (!grow_buffer(outbuf, 8))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, un_rq->partner_count);
- outbuf->offset+=4;
-
- for (i=0; i<un_rq->partner_count; i++)
- encode_wins_owner(outbuf, &un_rq->wins_owner[i]);
-
- SIVAL(outbuf->buffer, outbuf->offset, un_rq->initiating_wins_server.s_addr);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a send entries request
-****************************************************************************/
-static void encode_send_entries_request(struct BUFFER *outbuf, SEND_ENTRIES_REQUEST *se_rq)
-{
- encode_wins_owner(outbuf, &se_rq->wins_owner);
-}
-
-/****************************************************************************
-decode a send entries reply
-****************************************************************************/
-static void encode_send_entries_reply(struct BUFFER *outbuf, SEND_ENTRIES_REPLY *se_rp)
-{
- int i;
-
- if (!grow_buffer(outbuf, 4))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, se_rp->max_names);
- outbuf->offset+=4;
-
- for (i=0; i<se_rp->max_names; i++)
- encode_wins_name(outbuf, &se_rp->wins_name[i]);
-
-}
-
-/****************************************************************************
-encode a add version number map table reply
-****************************************************************************/
-static void encode_add_version_number_map_table_reply(struct BUFFER *outbuf, AVMT_REP *avmt_rep)
-{
- int i;
-
- if (!grow_buffer(outbuf, 8))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, avmt_rep->partner_count);
- outbuf->offset+=4;
-
- for (i=0; i<avmt_rep->partner_count; i++)
- encode_wins_owner(outbuf, &avmt_rep->wins_owner[i]);
-
- SIVAL(outbuf->buffer, outbuf->offset, avmt_rep->initiating_wins_server.s_addr);
- outbuf->offset+=4;
-
-}
-
-/****************************************************************************
-decode a replicate packet and fill a structure
-****************************************************************************/
-static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep)
-{
- if (!grow_buffer(outbuf, 4))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, rep->msg_type);
- outbuf->offset+=4;
-
- switch (rep->msg_type) {
- case 0:
- break;
- case 1:
- /* add version number map table reply */
- encode_add_version_number_map_table_reply(outbuf, &rep->avmt_rep);
- break;
- case 2:
- /* send entry request */
- encode_send_entries_request(outbuf, &rep->se_rq);
- break;
- case 3:
- /* send entry request */
- encode_send_entries_reply(outbuf, &rep->se_rp);
- break;
- case 4:
- /* update notification request */
- encode_update_notify_request(outbuf, &rep->un_rq);
- break;
- default:
- DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type));
- break;
- }
-}
-
-/****************************************************************************
-write the generic header.
-****************************************************************************/
-static void write_generic_header(struct BUFFER *outbuf, generic_header *r)
-{
- RSIVAL(outbuf->buffer, 0, r->data_size);
- RSIVAL(outbuf->buffer, 4, r->opcode);
- RSIVAL(outbuf->buffer, 8, r->assoc_ctx);
- RSIVAL(outbuf->buffer,12, r->mess_type);
-}
-
-/*******************************************************************
-decode a start association request
-********************************************************************/
-static void encode_start_assoc_request(struct BUFFER *outbuf, START_ASSOC_REQUEST *q)
-{
- if (!grow_buffer(outbuf, 45))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, q->assoc_ctx);
- RSSVAL(outbuf->buffer, outbuf->offset+4, q->min_ver);
- RSSVAL(outbuf->buffer, outbuf->offset+6, q->maj_ver);
-
- outbuf->offset=45;
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void encode_start_assoc_reply(struct BUFFER *outbuf, START_ASSOC_REPLY *r)
-{
- if (!grow_buffer(outbuf, 45))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, r->assoc_ctx);
- RSSVAL(outbuf->buffer, outbuf->offset+4, r->min_ver);
- RSSVAL(outbuf->buffer, outbuf->offset+6, r->maj_ver);
-
- outbuf->offset=45;
-}
-
-/*******************************************************************
-decode a start association reply
-********************************************************************/
-static void encode_stop_assoc(struct BUFFER *outbuf, STOP_ASSOC *r)
-{
- if (!grow_buffer(outbuf, 44))
- return;
-
- RSIVAL(outbuf->buffer, outbuf->offset, r->reason);
-
- outbuf->offset=44;
-}
-
-/****************************************************************************
-write the generic header size.
-****************************************************************************/
-static void write_generic_header_size(generic_header *r, int size)
-{
- /* the buffer size is the total size minus the size field */
- r->data_size=size-4;
-}
-
-/****************************************************************************
-encode a packet and read a generic structure
-****************************************************************************/
-void encode_generic_packet(struct BUFFER *outbuf, GENERIC_PACKET *q)
-{
- if (!grow_buffer(outbuf, 16))
- return;
-
- outbuf->offset=16;
-
- switch (q->header.mess_type) {
- case 0:
- encode_start_assoc_request(outbuf, &q->sa_rq);
- break;
- case 1:
- encode_start_assoc_reply(outbuf, &q->sa_rp);
- break;
- case 2:
- encode_stop_assoc(outbuf, &q->so);
- break;
- case 3:
- encode_replicate(outbuf, &q->rep);
- break;
- default:
- DEBUG(0,("encode_generic_packet: unknown message type:%d\n", q->header.mess_type));
- break;
- }
-
- write_generic_header_size(&q->header, outbuf->offset);
- write_generic_header(outbuf, &q->header);
-}
-
-
-/****************************************************************************
-dump a WINS_OWNER structure
-****************************************************************************/
-static void dump_wins_owner(WINS_OWNER *wins_owner)
-{
- DEBUGADD(10,("\t\t\t\taddress : %s\n", inet_ntoa(wins_owner->address)));
- DEBUGADD(10,("\t\t\t\tmax version: %d\n", (int)wins_owner->max_version));
- DEBUGADD(10,("\t\t\t\tmin version: %d\n", (int)wins_owner->min_version));
- DEBUGADD(10,("\t\t\t\ttype : %d\n", wins_owner->type));
-}
-
-/****************************************************************************
-dump a WINS_NAME structure
-****************************************************************************/
-static void dump_wins_name(WINS_NAME *wins_name)
-{
- fstring name;
- int i;
-
- strncpy(name, wins_name->name, 15);
-
- DEBUGADD(10,("name: %d, %s<%02x> %x,%x, %d %s %d ", wins_name->name_len, name, wins_name->type,
- wins_name->name_flag, wins_name->group_flag, (int)wins_name->id,
- inet_ntoa(wins_name->owner), wins_name->num_ip));
-
- if (wins_name->num_ip!=1)
- for (i=0; i<wins_name->num_ip; i++)
- DEBUGADD(10,("%s ", inet_ntoa(wins_name->others[i])));
-
- DEBUGADD(10,("\n"));
-}
-
-/****************************************************************************
-dump a replicate structure
-****************************************************************************/
-static void dump_replicate(REPLICATE *rep)
-{
- int i;
-
- DEBUGADD(5,("\t\tmsg_type: %d ", rep->msg_type));
-
- switch (rep->msg_type) {
- case 0:
- DEBUGADD(5,("(Add Version Map Table Request)\n"));
- break;
- case 1:
- DEBUGADD(5,("(Add Version Map Table Reply)\n"));
- DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->avmt_rep.partner_count));
- for (i=0; i<rep->avmt_rep.partner_count; i++)
- dump_wins_owner(&rep->avmt_rep.wins_owner[i]);
- DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->avmt_rep.initiating_wins_server)));
- break;
- case 2:
- DEBUGADD(5,("(Send Entries Request)\n"));
- dump_wins_owner(&rep->se_rq.wins_owner);
- break;
- case 3:
- DEBUGADD(5,("(Send Entries Reply)\n"));
- DEBUGADD(5,("\t\t\tmax_names : %d\n", rep->se_rp.max_names));
- for (i=0; i<rep->se_rp.max_names; i++)
- dump_wins_name(&rep->se_rp.wins_name[i]);
- break;
- case 4:
- DEBUGADD(5,("(Update Notify Request)\n"));
- DEBUGADD(5,("\t\t\tpartner_count : %d\n", rep->un_rq.partner_count));
- for (i=0; i<rep->un_rq.partner_count; i++)
- dump_wins_owner(&rep->un_rq.wins_owner[i]);
- DEBUGADD(5,("\t\t\tinitiating_wins_server: %s\n", inet_ntoa(rep->un_rq.initiating_wins_server)));
- break;
- default:
- DEBUG(5,("\n"));
- break;
- }
-}
-
-/****************************************************************************
-dump a generic structure
-****************************************************************************/
-void dump_generic_packet(GENERIC_PACKET *q)
-{
- DEBUG(5,("dump_generic_packet:\n"));
- DEBUGADD(5,("\tdata_size: %08x\n", q->header.data_size));
- DEBUGADD(5,("\topcode : %08x\n", q->header.opcode));
- DEBUGADD(5,("\tassoc_ctx: %08x\n", q->header.assoc_ctx));
- DEBUGADD(5,("\tmess_type: %08x ", q->header.mess_type));
-
- switch (q->header.mess_type) {
- case 0:
- DEBUGADD(5,("(Start Association Request)\n"));
- DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rq.assoc_ctx));
- DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rq.min_ver));
- DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rq.maj_ver));
- break;
- case 1:
- DEBUGADD(5,("(Start Association Reply)\n"));
- DEBUGADD(5,("\t\tassoc_ctx: %08x\n", q->sa_rp.assoc_ctx));
- DEBUGADD(5,("\t\tmin_ver : %04x\n", q->sa_rp.min_ver));
- DEBUGADD(5,("\t\tmaj_ver : %04x\n", q->sa_rp.maj_ver));
- break;
- case 2:
- DEBUGADD(5,("(Stop Association)\n"));
- DEBUGADD(5,("\t\treason: %08x\n", q->so.reason));
- break;
- case 3:
- DEBUGADD(5,("(Replication Message)\n"));
- dump_replicate(&q->rep);
- break;
- default:
- DEBUG(5,("\n"));
- break;
- }
-
-}
-
-/****************************************************************************
-generate a stop packet
-****************************************************************************/
-void stop_packet(GENERIC_PACKET *q, GENERIC_PACKET *r, int reason)
-{
- r->header.opcode=OPCODE_NON_NBT;
- r->header.assoc_ctx=get_server_assoc(q->header.assoc_ctx);
- r->header.mess_type=MESSAGE_TYPE_STOP_ASSOC;
- r->so.reason=reason;
-
-}
-
-
diff --git a/source/wrepld/partners.c b/source/wrepld/partners.c
deleted file mode 100644
index 2387f5b45f6..00000000000
--- a/source/wrepld/partners.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-/* we can exchange info with 64 partners at any given time */
-WINS_PARTNER current_partners[64];
-int total_current_partners;
-
-/*******************************************************************
-verify if we know this partner
-********************************************************************/
-BOOL check_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-add a new entry to the list
-********************************************************************/
-BOOL add_partner(int client_assoc, int server_assoc, BOOL pull, BOOL push)
-{
- DEBUG(5,("add_partner: total_current_partners: %d\n", total_current_partners));
-
- if (total_current_partners==64)
- return False;
-
- current_partners[total_current_partners].client_assoc=client_assoc;
- current_partners[total_current_partners].server_assoc=server_assoc;
- current_partners[total_current_partners].pull_partner=pull;
- current_partners[total_current_partners].push_partner=push;
-
- total_current_partners++;
-
- return True;
-}
-
-/*******************************************************************
-remove an entry to the list
-********************************************************************/
-BOOL remove_partner(int client_assoc)
-{
- int i,j;
-
- DEBUG(5,("remove_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; current_partners[i].client_assoc!=client_assoc && i<total_current_partners; i++)
- ;
-
- if (i==total_current_partners)
- return False;
-
- for (j=i+1; j<total_current_partners; j++) {
- current_partners[j-1].client_assoc=current_partners[j].client_assoc;
- current_partners[j-1].server_assoc=current_partners[j].server_assoc;
- current_partners[j-1].pull_partner=current_partners[j].pull_partner;
- current_partners[j-1].push_partner=current_partners[j].push_partner;
- current_partners[j-1].partner_server.s_addr=current_partners[j].partner_server.s_addr;
- current_partners[j-1].other_server.s_addr=current_partners[j].other_server.s_addr;
- }
-
- total_current_partners--;
-
- return True;
-}
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL update_server_partner(int client_assoc, int server_assoc)
-{
- int i;
-
- DEBUG(5,("update_server_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- current_partners[i].server_assoc=server_assoc;
- return True;
- }
-
- return False;
-}
-
-/*******************************************************************
-verify if it's a pull partner
-********************************************************************/
-BOOL check_pull_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_pull_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc &&
- current_partners[i].pull_partner==True)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-verify if it's a push partner
-********************************************************************/
-BOOL check_push_partner(int assoc)
-{
- int i;
-
- DEBUG(5,("check_push_partner: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc &&
- current_partners[i].push_partner==True)
- return True;
-
- return False;
-}
-
-/*******************************************************************
-return the server ctx linked to the client ctx
-********************************************************************/
-int get_server_assoc(int assoc)
-{
- int i;
-
- DEBUG(5,("get_server_assoc: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==assoc)
- return current_partners[i].server_assoc;
-
- return 0;
-}
-
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL write_server_assoc_table(int client_assoc, struct in_addr partner, struct in_addr server)
-{
- int i;
-
- DEBUG(5,("write_server_assoc_table: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- current_partners[i].partner_server=partner;
- current_partners[i].other_server=server;
- return True;
- }
-
- return False;
-}
-
-/*******************************************************************
-link the client and server context
-********************************************************************/
-BOOL get_server_assoc_table(int client_assoc, struct in_addr *partner, struct in_addr *server)
-{
- int i;
-
- DEBUG(5,("get_server_assoc_table: total_current_partners: %d\n", total_current_partners));
-
- for (i=0; i<total_current_partners; i++)
- if (current_partners[i].client_assoc==client_assoc) {
- partner->s_addr=current_partners[i].partner_server.s_addr;
- server->s_addr=current_partners[i].other_server.s_addr;
- return True;
- }
-
- return False;
-}
-
-
diff --git a/source/wrepld/process.c b/source/wrepld/process.c
deleted file mode 100644
index 0e9a9b34610..00000000000
--- a/source/wrepld/process.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern fd_set *listen_set;
-extern int listen_number;
-extern int *sock_array;
-
-WINS_OWNER global_wins_table[64][64];
-int partner_count;
-
-TALLOC_CTX *mem_ctx;
-
-#define WINS_LIST "wins.tdb"
-#define INFO_VERSION "INFO/version"
-#define INFO_COUNT "INFO/num_entries"
-#define INFO_ID_HIGH "INFO/id_high"
-#define INFO_ID_LOW "INFO/id_low"
-#define ENTRY_PREFIX "ENTRY/"
-
-
-/*******************************************************************
-fill the header of a reply.
-********************************************************************/
-static void fill_header(GENERIC_PACKET *g, int opcode, int ctx, int mess)
-{
- if (g==NULL)
- return;
-
- g->header.opcode=opcode;
- g->header.assoc_ctx=ctx;
- g->header.mess_type=mess;
-}
-
-/*******************************************************************
-dump the global table, that's a debug code.
-********************************************************************/
-static void dump_global_table(void)
-{
- int i,j;
-
- for (i=0;i<partner_count;i++) {
- DEBUG(10,("\n%d ", i));
- for (j=0; global_wins_table[i][j].address.s_addr!=0; j++)
- DEBUG(10,("%s:%d \t", inet_ntoa(global_wins_table[i][j].address),
- (int)global_wins_table[i][j].max_version));
- }
- DEBUG(10,("\n"));
-}
-
-/*******************************************************************
-start association
-********************************************************************/
-static void start_assoc_process(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- /*
- * add this request to our current wins partners list
- * this list is used to know with who we are in contact
- *
- */
- r->sa_rp.assoc_ctx=time(NULL);
- fill_header(r, OPCODE_NON_NBT, q->sa_rq.assoc_ctx, MESSAGE_TYPE_START_ASSOC_REPLY);
-
- /* reply we are a NT4 server */
-
- /* w2K is min=2, maj=5 */
-
- r->sa_rp.min_ver=1;
- r->sa_rp.maj_ver=1;
-
- add_partner(r->sa_rp.assoc_ctx, q->sa_rq.assoc_ctx, False, False);
-}
-
-/*******************************************************************
-start association reply
-********************************************************************/
-static void start_assoc_reply(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i;
-
- /* check if we have already registered this client */
- if (!check_partner(q->header.assoc_ctx)) {
- DEBUG(0,("start_assoc_reply: unknown client\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- if (!update_server_partner(q->header.assoc_ctx, q->sa_rp.assoc_ctx)) {
- DEBUG(0,("start_assoc_reply: can't update server ctx\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- /* if pull, request map table */
- if (check_pull_partner(q->header.assoc_ctx)) {
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST;
- DEBUG(5,("start_assoc_reply: requesting map table\n"));
-
- return;
- }
-
- /* if push, send our table */
- if (check_push_partner(q->header.assoc_ctx)) {
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
- r->rep.msg_type=MESSAGE_REP_UPDATE_NOTIFY_REQUEST;
- r->rep.un_rq.partner_count=partner_count;
-
- r->rep.un_rq.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER));
- if (r->rep.un_rq.wins_owner==NULL) {
- DEBUG(0,("start_assoc_reply: can't alloc memory\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- for (i=0; i<partner_count; i++)
- r->rep.un_rq.wins_owner[i]=global_wins_table[0][i];
-
- DEBUG(5,("start_assoc_reply: sending update table\n"));
- return;
- }
-
- /* neither push/pull, stop */
- /* we should not come here */
- DEBUG(0,("we have a partner which is neither push nor pull !\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-initialise and fill the in-memory partner table.
-****************************************************************************/
-int init_wins_partner_table(void)
-{
- int i=1,j=0,k;
- char **partner = str_list_make(lp_wins_partners(), NULL);
-
- if (partner==NULL) {
- DEBUG(0,("wrepld: no partner list in smb.conf, exiting\n"));
- exit_server("normal exit");
- return(0);
- }
-
- DEBUG(4, ("init_wins_partner_table: partners: %s\n", lp_wins_partners()));
-
- global_wins_table[0][0].address=*iface_n_ip(0);
- global_wins_table[0][0].max_version=0;
- global_wins_table[0][0].min_version=0;
- global_wins_table[0][0].type=0;
-
- while (partner[j]!=NULL) {
- DEBUG(3,("init_wins_partner_table, adding partner: %s\n", partner[j]));
-
- global_wins_table[0][i].address=*interpret_addr2(partner[j]);
- global_wins_table[0][i].max_version=0;
- global_wins_table[0][i].min_version=0;
- global_wins_table[0][i].type=0;
- global_wins_table[0][i].last_pull=0;
- global_wins_table[0][i].last_push=0;
-
- i++;
- j++;
- }
-
- for (k=1; k<i;k++)
- for (j=0; j<i; j++)
- global_wins_table[k][j]=global_wins_table[0][j];
-
- str_list_free (&partner);
-
- return i;
-}
-
-/****************************************************************************
-read the last ID from the wins tdb file.
-****************************************************************************/
-static void get_our_last_id(WINS_OWNER *wins_owner)
-{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("get_our_last_id: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
-
- wins_owner->max_version=((SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_HIGH))<<32 |
- (SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_LOW);
-
- tdb_close(tdb);
-}
-
-/****************************************************************************
-send the list of wins server we know.
-****************************************************************************/
-static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(5, ("send_version_number_map_table: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- /*
- * return an array of wins servers, we are partner with.
- * each entry contains the IP address and the version info
- * version: ID of the last entry we've got
- */
-
- /* the first wins server must be self */
-
- /*
- * get our last ID from the wins database
- * it can have been updated since last read
- * as nmbd got registration/release.
- */
- get_our_last_id(&global_wins_table[0][0]);
-
- r->rep.avmt_rep.wins_owner=(WINS_OWNER *)talloc(mem_ctx, partner_count*sizeof(WINS_OWNER));
- if (r->rep.avmt_rep.wins_owner==NULL) {
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- DEBUG(5,("send_version_number_map_table: partner_count: %d\n", partner_count));
-
- for (i=0; i<partner_count; i++) {
- DEBUG(5,("send_version_number_map_table, partner: %d -> %s, \n", i, inet_ntoa(global_wins_table[0][i].address)));
- r->rep.avmt_rep.wins_owner[i]=global_wins_table[0][i];
- }
-
- r->rep.msg_type=1;
- r->rep.avmt_rep.partner_count=partner_count;
- r->rep.avmt_rep.initiating_wins_server.s_addr=0; /* blatant lie, NT4/w2K do the same ! */
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
-}
-
-/****************************************************************************
-for a given partner, ask it to send entries we don't have.
-****************************************************************************/
-static BOOL check_partners_and_send_entries(GENERIC_PACKET *q, GENERIC_PACKET *r, int partner)
-{
- int server;
- int other;
- SMB_BIG_UINT temp;
- SMB_BIG_UINT current;
-
-
- /*
- * we check if our partner has more records than us.
- * we need to check more than our direct partners as
- * we can have this case:
- * us: A, partners: B,C, indirect partner: D
- * A<->B, A<->C, B<->D, C<->D
- *
- * So if we're talking to B, we need to check if between
- * B and C, which one have more records about D.
- * and also check if we don't already have the records.
- */
-
-
- /* check all servers even indirect */
- for (server=1; global_wins_table[0][server].address.s_addr!=0; server++) {
- current = global_wins_table[partner][server].max_version;
-
- temp=0;
-
- for (other=1; other<partner_count; other++) {
- /* skip the partner itself */
- if (other==partner)
- continue;
-
- if (global_wins_table[other][server].max_version > temp)
- temp=global_wins_table[other][server].max_version;
- }
-
- if (current >= temp && current > global_wins_table[0][server].max_version) {
- /*
- * it has more records than every body else and more than us,
- * ask it the difference between what we have and what it has
- */
- fill_header(r, OPCODE_NON_NBT, get_server_assoc(q->header.assoc_ctx), MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REQUEST;
- r->rep.se_rq.wins_owner.address=global_wins_table[partner][server].address;
-
- r->rep.se_rq.wins_owner.max_version=global_wins_table[partner][server].max_version;
- r->rep.se_rq.wins_owner.min_version=global_wins_table[0][server].max_version;
- r->rep.se_rq.wins_owner.type=0;
-
- write_server_assoc_table(q->header.assoc_ctx, global_wins_table[0][partner].address, global_wins_table[partner][server].address);
-
- /*
- * and we update our version for this server
- * as we can't use the IDs returned in the send_entries function
- * the max ID can be larger than the largest ID returned
- */
-
- global_wins_table[0][server].max_version=global_wins_table[partner][server].max_version;
-
- return True;
- }
- }
- return False;
-}
-
-/****************************************************************************
-receive the list of wins server we know.
-****************************************************************************/
-static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- fstring peer;
- struct in_addr addr;
- int i,j,k,l;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(5, ("receive_version_number_map_table: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- fstrcpy(peer,get_peer_addr(q->fd));
- addr=*interpret_addr2(peer);
-
- get_our_last_id(&global_wins_table[0][0]);
-
- DEBUG(5,("receive_version_number_map_table: received a map of %d server from: %s\n",
- q->rep.avmt_rep.partner_count ,inet_ntoa(q->rep.avmt_rep.initiating_wins_server)));
- DEBUG(5,("real peer is: %s\n", peer));
-
- for (i=0; global_wins_table[0][i].address.s_addr!=addr.s_addr && i<partner_count;i++)
- ;
-
- if (i==partner_count) {
- DEBUG(5,("receive_version_number_map_table: unknown partner: %s\n", peer));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- for (j=0; j<q->rep.avmt_rep.partner_count;j++) {
- /*
- * search if we already have this entry or if it's a new one
- * it can be a new one in case of propagation
- */
- for (k=0; global_wins_table[0][k].address.s_addr!=0 &&
- global_wins_table[0][k].address.s_addr!=q->rep.avmt_rep.wins_owner[j].address.s_addr; k++);
-
- global_wins_table[i][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr;
- global_wins_table[i][k].max_version=q->rep.avmt_rep.wins_owner[j].max_version;
- global_wins_table[i][k].min_version=q->rep.avmt_rep.wins_owner[j].min_version;
- global_wins_table[i][k].type=q->rep.avmt_rep.wins_owner[j].type;
-
- /*
- * in case it's a new one, rewrite the address for all the partner
- * to reserve the slot.
- */
-
- for(l=0; l<partner_count; l++)
- global_wins_table[l][k].address.s_addr=q->rep.avmt_rep.wins_owner[j].address.s_addr;
- }
-
- dump_global_table();
-
- /*
- * if this server have newer records than what we have
- * for several wins servers, we need to ask it.
- * Alas a send entry request is only on one server.
- * So in the send entry reply, we'll ask for the next server if required.
- */
-
- if (check_partners_and_send_entries(q, r, i))
- return;
-
- /* it doesn't have more entries than us */
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-add an entry to the wins list we'll send.
-****************************************************************************/
-static BOOL add_record_to_winsname(WINS_NAME **wins_name, int *max_names, char *name, int type, int wins_flags, int id, struct in_addr *ip_list, int num_ips)
-{
- WINS_NAME *temp_list;
- int i;
- int current=*max_names;
-
- temp_list=talloc_realloc(mem_ctx, *wins_name, (current+1)*sizeof(WINS_NAME));
- if (temp_list==NULL)
- return False;
-
- temp_list[current].name_len=0x11;
-
- safe_strcpy(temp_list[current].name, name, 15);
-
- temp_list[current].type=type;
- temp_list[current].empty=0;
-
- temp_list[current].name_flag=wins_flags;
-
- if ( (wins_flags&0x03) == 1 || (wins_flags&0x03)==2)
- temp_list[current].group_flag=0x01000000;
- else
- temp_list[current].group_flag=0x00000000;
-
- temp_list[current].id=id;
-
- temp_list[current].owner.s_addr=ip_list[0].s_addr;
-
- if (temp_list[current].name_flag & 2) {
- temp_list[current].num_ip=num_ips;
- temp_list[current].others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*num_ips);
- if (temp_list[current].others==NULL)
- return False;
-
- for (i=0; i<num_ips; i++)
- temp_list[current].others[i].s_addr=ip_list[i].s_addr;
-
- } else
- temp_list[current].num_ip=1;
-
- temp_list[current].foo=0xffffffff;
-
- *wins_name=temp_list;
-
- return True;
-}
-
-/****************************************************************************
-send the list of name we have.
-****************************************************************************/
-static void send_entry_request(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int max_names=0;
- int i;
- time_t time_now = time(NULL);
- WINS_OWNER *wins_owner;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
- int num_interfaces = iface_count();
-
- if (s_ctx==0) {
- DEBUG(1, ("send_entry_request: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
-
- wins_owner=&q->rep.se_rq.wins_owner;
- r->rep.se_rp.wins_name=NULL;
-
- DEBUG(3,("send_entry_request: we have been asked to send the list of wins records\n"));
- DEBUGADD(3,("owned by: %s and between min: %d and max: %d\n", inet_ntoa(wins_owner->address),
- (int)wins_owner->min_version, (int)wins_owner->max_version));
-
- /*
- * if we are asked to send records owned by us
- * we overwrite the wins ip with 0.0.0.0
- * to make it easy in case of multihomed
- */
-
- for (i=0; i<num_interfaces; i++)
- if (ip_equal(wins_owner->address, *iface_n_ip(i))) {
- wins_owner->address=*interpret_addr2("0.0.0.0");
- break;
- }
-
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("send_entry_request: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
-
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
- fstring name_type;
- pstring name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int low, high;
- SMB_BIG_UINT version;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
- pstrcpy(name, name_type);
-
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags,
- &high,
- &low,
- ip_str,
- &ttl,
- &num_ips,
- &wins_flags);
-
- wins_ip=*interpret_addr2(ip_str);
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)talloc(mem_ctx, num_ips * sizeof(struct in_addr))) == NULL) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("initialise_wins: talloc fail !\n"));
- return;
- }
-
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
-
- SAFE_FREE(dbuf.dptr);
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
-
- DEBUG( 4, ("send_entry_request: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- /* add the record to the list to send */
- version=((SMB_BIG_UINT)high)<<32 | low;
-
- if (wins_owner->min_version<=version && wins_owner->max_version>=version &&
- wins_owner->address.s_addr==wins_ip.s_addr) {
- if(!add_record_to_winsname(&r->rep.se_rp.wins_name, &max_names, name, type, wins_flags, version, ip_list, num_ips))
- return;
- max_names++;
- }
-
- } else {
- DEBUG(4, ("send_entry_request: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
- }
-
- tdb_close(tdb);
-
- DEBUG(4,("send_entry_request, sending %d records\n", max_names));
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
- r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REPLY; /* reply */
- r->rep.se_rp.max_names=max_names;
-}
-
-
-/****************************************************************************
-.
-****************************************************************************/
-static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i,j,k,l;
- UPDATE_NOTIFY_REQUEST *u;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
-
- if (s_ctx==0) {
- DEBUG(4, ("update_notify_request: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- u=&q->rep.un_rq;
-
- /* check if we already have the range of records */
-
- DEBUG(5,("update_notify_request: wins server: %s offered this list of %d records:\n",
- inet_ntoa(u->initiating_wins_server), u->partner_count));
-
- get_our_last_id(&global_wins_table[0][0]);
-
- for (i=0; i<partner_count; i++) {
- if (global_wins_table[0][i].address.s_addr==u->initiating_wins_server.s_addr) {
- DEBUG(5,("update_notify_request: found initiator at index %d\n", i));
- break;
- }
- }
-
- /*
- * some explanation is required, before someone say it's crap.
- *
- * let's take an example, we have 2 wins partners, we already now
- * that our max id is 10, partner 1 ID is 20 and partner 2 ID is 30
- * the array looks like:
- *
- * 0 1 2
- * 0 10 20 30
- * 1
- * 2
- *
- * we receive an update from partner 2 saying he has: 1:15, 2:40, 3:50
- * we must enlarge the array to add partner 3, it will look like:
- *
- * 0 1 2 3
- * 0 10 20 30
- * 1
- * 2 15 40 50
- *
- * now we know, we should pull from partner 2, the records 30->40 of 2 and 0->50 of 3.
- * once the pull will be over, our table will look like:
- *
- * 0 1 2 3
- * 0 10 20 40 50
- * 1
- * 2 15 40 50
- *
- *
- */
-
- for (j=0; j<u->partner_count;j++) {
- /*
- * search if we already have this entry or if it's a new one
- * it can be a new one in case of propagation
- */
-
- for (k=0; global_wins_table[0][k].address.s_addr!=0 &&
- global_wins_table[0][k].address.s_addr!=u->wins_owner[j].address.s_addr; k++);
-
- global_wins_table[i][k].address.s_addr=u->wins_owner[j].address.s_addr;
- global_wins_table[i][k].max_version=u->wins_owner[j].max_version;
- global_wins_table[i][k].min_version=u->wins_owner[j].min_version;
- global_wins_table[i][k].type=u->wins_owner[j].type;
-
- /*
- * in case it's a new one, rewrite the address for all the partner
- * to reserve the slot.
- */
-
- for(l=0; l<partner_count; l++)
- global_wins_table[l][k].address.s_addr=u->wins_owner[j].address.s_addr;
- }
-
- dump_global_table();
-
- stop_packet(q, r, STOP_REASON_USER_REASON);
-}
-
-/****************************************************************************
-.
-****************************************************************************/
-static void send_entry_reply(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- int i,j,k;
- struct in_addr partner, server;
- pid_t pid;
- int s_ctx=get_server_assoc(q->header.assoc_ctx);
- WINS_RECORD record;
-
- if (s_ctx==0) {
- DEBUG(1, ("send_entry_reply: request for a partner not in our table\n"));
- stop_packet(q, r, STOP_REASON_USER_REASON);
- return;
- }
-
- DEBUG(5,("send_entry_reply:got %d new records\n", q->rep.se_rp.max_names));
-
- /* we got records from a wins partner but that can be from another wins server */
- /* hopefully we track that */
-
- /* and the only doc available from MS is wrong ! */
-
- get_server_assoc_table(q->header.assoc_ctx, &partner, &server);
-
- for (j=0; global_wins_table[0][j].address.s_addr!=0; j++) {
- if (global_wins_table[0][j].address.s_addr==server.s_addr) {
- DEBUG(5,("send_entry_reply: found server at index %d\n", j));
- break;
- }
- }
-
- pid = pidfile_pid("nmbd");
- if (pid == 0) {
- DEBUG(0,("send_entry_reply: Can't find pid for nmbd\n"));
- return;
- }
-
- for (k=0; k<q->rep.se_rp.max_names; k++) {
- DEBUG(5,("send_entry_reply: %s<%02x> %d\n", q->rep.se_rp.wins_name[k].name, q->rep.se_rp.wins_name[k].type,
- (int)q->rep.se_rp.wins_name[k].id));
-
- safe_strcpy(record.name, q->rep.se_rp.wins_name[k].name, 16);
- record.type=q->rep.se_rp.wins_name[k].type;
- record.id=q->rep.se_rp.wins_name[k].id;
- record.wins_flags=q->rep.se_rp.wins_name[k].name_flag&0x00ff;
- record.num_ips=q->rep.se_rp.wins_name[k].num_ip;
-
- record.wins_ip.s_addr=server.s_addr;
-
- if (record.num_ips==1)
- record.ip[0]=q->rep.se_rp.wins_name[k].owner;
- else
- for (i=0; i<record.num_ips; i++)
- record.ip[i]=q->rep.se_rp.wins_name[k].others[i];
-
- record.nb_flags=0;
-
- if (record.wins_flags&WINS_NGROUP || record.wins_flags&WINS_SGROUP)
- record.nb_flags|=NB_GROUP;
-
- if (record.wins_flags&WINS_ACTIVE)
- record.nb_flags|=NB_ACTIVE;
-
- record.nb_flags|=record.wins_flags&WINS_HNODE;
-
- message_send_pid(pid, MSG_WINS_NEW_ENTRY, &record, sizeof(record), False);
-
- }
-
- dump_global_table();
-
- /*
- * we got some entries,
- * ask the partner to send us the map table again
- * to get the other servers entries.
- *
- * we're getting the map table 1 time more than really
- * required. We could remove that call, but that
- * would complexify the code. I prefer this trade-of.
- */
- fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
-
- r->rep.msg_type=MESSAGE_REP_ADD_VERSION_REQUEST;
-}
-
-/****************************************************************************
-decode the replication message and reply.
-****************************************************************************/
-static void replicate(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- switch (q->rep.msg_type) {
- case 0:
- /* add version number map table request */
- send_version_number_map_table(q, r);
- break;
- case 1:
- receive_version_number_map_table(q, r);
- break;
- case 2:
- /* send entry request */
- send_entry_request(q, r);
- break;
- case 3:
- /* send entry reply */
- send_entry_reply(q, r);
- break;
- case 4:
- /* update notification request */
- update_notify_request(q, r);
- break;
- }
-}
-
-/****************************************************************************
-do a switch on the message type, and return the response size
-****************************************************************************/
-static BOOL switch_message(GENERIC_PACKET *q, GENERIC_PACKET *r)
-{
- switch (q->header.mess_type) {
- case 0:
- /* Start association type */
- start_assoc_process(q, r);
- return True;
- break;
- case 1:
- /* start association reply */
- start_assoc_reply(q, r);
- return True;
- break;
- case 2:
- /* stop association message */
- return False;
- break;
- case 3:
- /* replication message */
- replicate(q, r);
- return True;
- break;
- }
-
- return False;
-}
-
-
-/****************************************************************************
- construct a reply to the incoming packet
-****************************************************************************/
-void construct_reply(struct wins_packet_struct *p)
-{
- GENERIC_PACKET r;
- struct BUFFER buffer;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- DEBUG(5,("dump: received packet\n"));
- dump_generic_packet(p->packet);
-
- /* Verify if the request we got is from a listed partner */
- if (!check_partner(p->packet->header.assoc_ctx)) {
- fstring peer;
- struct in_addr addr;
- int i;
- fstrcpy(peer,get_peer_addr(p->fd));
- addr=*interpret_addr2(peer);
-
- for (i=1; i<partner_count; i++)
- if (ip_equal(addr, global_wins_table[0][i].address))
- break;
-
- if (i==partner_count) {
- DEBUG(1,("construct_reply: got a request from a non peer machine: %s\n", peer));
- stop_packet(p->packet, &r, STOP_REASON_AUTH_FAILED);
- p->stop_packet=True;
- encode_generic_packet(&buffer, &r);
- if (!send_smb(p->fd, buffer.buffer))
- exit_server("process_smb: send_smb failed.");
- return;
- }
- }
-
- if (switch_message(p->packet, &r)) {
- encode_generic_packet(&buffer, &r);
- DEBUG(5,("dump: sending packet\n"));
- dump_generic_packet(&r);
-
- if(buffer.offset > 0) {
- if (!send_smb(p->fd, buffer.buffer))
- exit_server("process_smb: send_smb failed.");
- }
- }
-
- /* if we got a stop assoc or if we send a stop assoc, close the fd after */
- if (p->packet->header.mess_type==MESSAGE_TYPE_STOP_ASSOC ||
- r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC) {
- remove_partner(p->packet->header.assoc_ctx);
- p->stop_packet=True;
- }
-}
-
-/****************************************************************************
- contact periodically our wins partner to do a pull replication
-****************************************************************************/
-void run_pull_replication(time_t t)
-{
- /* we pull every 30 minutes to query about new records*/
- int i, s;
- struct BUFFER buffer;
- GENERIC_PACKET p;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- for (i=1; i<partner_count; i++) {
- if (global_wins_table[0][i].last_pull < t) {
- global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */
-
- /* contact the wins server */
- p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST;
- p.header.opcode=OPCODE_NON_NBT;
- p.header.assoc_ctx=0;
- p.sa_rq.assoc_ctx=(int)t;
- p.sa_rq.min_ver=1;
- p.sa_rq.maj_ver=1;
-
- DEBUG(3,("run_pull_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- encode_generic_packet(&buffer, &p);
- dump_generic_packet(&p);
-
- /* send the packet to the server and add the descriptor to receive answers */
- s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT);
- if (s==-1) {
- DEBUG(0,("run_pull_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- return;
- }
-
- if(buffer.offset > 0) {
- if (!send_smb(s, buffer.buffer))
- exit_server("run_pull_replication: send_smb failed.");
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
-
- /* add ourself as a client */
- add_partner((int)t, 0, True, False);
- }
- }
-}
-
-/****************************************************************************
- contact periodically our wins partner to do a push replication
-****************************************************************************/
-void run_push_replication(time_t t)
-{
- /* we push every 30 minutes or 25 new entries */
- int i, s;
- struct BUFFER buffer;
- GENERIC_PACKET p;
-
- buffer.buffer=NULL;
- buffer.offset=0;
- buffer.length=0;
-
- for (i=1; i<partner_count; i++) {
- if (global_wins_table[0][i].last_pull < t) {
- global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */
-
- /* contact the wins server */
- p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST;
- p.header.opcode=OPCODE_NON_NBT;
- p.header.assoc_ctx=0;
- p.sa_rq.assoc_ctx=(int)t;
- p.sa_rq.min_ver=1;
- p.sa_rq.maj_ver=1;
-
- DEBUG(3,("run_push_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- encode_generic_packet(&buffer, &p);
- dump_generic_packet(&p);
-
- /* send the packet to the server and add the descriptor to receive answers */
- s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT);
- if (s==-1) {
- DEBUG(0,("run_push_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
- return;
- }
-
- if(buffer.offset > 0) {
- if (!send_smb(s, buffer.buffer))
- exit_server("run_push_replication: send_smb failed.");
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
-
- /* add ourself as a client */
- add_partner((int)t, 0, False, True);
- }
- }
-}
-
diff --git a/source/wrepld/server.c b/source/wrepld/server.c
deleted file mode 100644
index 80694a616bb..00000000000
--- a/source/wrepld/server.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Main SMB server routines
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-extern pstring user_socket_options;
-
-extern WINS_OWNER *global_wins_table;
-extern int partner_count;
-
-extern fd_set *listen_set;
-extern int listen_number;
-extern int *sock_array;
-
-extern TALLOC_CTX *mem_ctx;
-
-int wins_port = 42;
-
-/****************************************************************************
- when exiting, take the whole family
-****************************************************************************/
-static void *dflt_sig(void)
-{
- exit_server("caught signal");
- return NULL;
-}
-
-/****************************************************************************
- reload the services file
- **************************************************************************/
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
-
- if (lp_loaded()) {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE,fname);
- test = False;
- }
- }
-
- reopen_logs();
-
- if (test && !lp_file_list_changed())
- return(True);
-
- ret = lp_load(dyn_CONFIGFILE,False,False,True);
-
-
- /* perhaps the config filename is now set */
- if (!test)
- reload_services(True);
-
- reopen_logs();
-
- load_interfaces();
-
- return(ret);
-}
-
-/****************************************************************************
- Catch a sighup.
-****************************************************************************/
-
-VOLATILE sig_atomic_t reload_after_sighup = False;
-
-static void sig_hup(int sig)
-{
- BlockSignals(True,SIGHUP);
- DEBUG(0,("Got SIGHUP\n"));
-
- sys_select_signal();
- reload_after_sighup = True;
- BlockSignals(False,SIGHUP);
-}
-
-#if DUMP_CORE
-/*******************************************************************
-prepare to dump a core file - carefully!
-********************************************************************/
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy(dname,lp_logfile());
- if ((p=strrchr_m(dname,'/'))) *p=0;
- pstrcat(dname,"/corefiles");
- mkdir(dname,0700);
- sys_chown(dname,getuid(),getgid());
- chmod(dname,0700);
- if (chdir(dname)) return(False);
- umask(~(0700));
-
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit(RLIMIT_CORE, &rlp);
- rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
- setrlimit(RLIMIT_CORE, &rlp);
- getrlimit(RLIMIT_CORE, &rlp);
- DEBUG(3,("Core limits now %d %d\n",
- (int)rlp.rlim_cur,(int)rlp.rlim_max));
- }
-#endif
-#endif
-
-
- DEBUG(0,("Dumping core in %s\n",dname));
- abort();
- return(True);
-}
-#endif
-
-/****************************************************************************
-exit the server
-****************************************************************************/
-void exit_server(const char *reason)
-{
- static int firsttime=1;
-
- if (!firsttime)
- exit(0);
- firsttime = 0;
-
- DEBUG(2,("Closing connections\n"));
-
- if (!reason) {
- int oldlevel = DEBUGLEVEL;
- DEBUGLEVEL = 10;
- DEBUGLEVEL = oldlevel;
- DEBUG(0,("===============================================================\n"));
-#if DUMP_CORE
- if (dump_core()) return;
-#endif
- }
-
- DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
- exit(0);
-}
-
-/****************************************************************************
- Create an fd_set containing all the sockets in the subnet structures,
- plus the broadcast sockets.
-***************************************************************************/
-
-static BOOL create_listen_fdset(void)
-{
- int i;
- int num_interfaces = iface_count();
- int s;
-
- listen_set = (fd_set *)malloc(sizeof(fd_set));
- if(listen_set == NULL) {
- DEBUG(0,("create_listen_fdset: malloc fail !\n"));
- return True;
- }
-
-#ifdef HAVE_ATEXIT
- {
- static int atexit_set;
- if(atexit_set == 0) {
- atexit_set=1;
- }
- }
-#endif
-
- FD_ZERO(listen_set);
-
- if(lp_interfaces() && lp_bind_interfaces_only()) {
- /* We have been given an interfaces line, and been
- told to only bind to those interfaces. Create a
- socket per interface and bind to only these.
- */
-
- if(num_interfaces > FD_SETSIZE) {
- DEBUG(0,("create_listen_fdset: Too many interfaces specified to bind to. Number was %d max can be %d\n", num_interfaces, FD_SETSIZE));
- return False;
- }
-
- /* Now open a listen socket for each of the interfaces. */
- for(i = 0; i < num_interfaces; i++) {
- struct in_addr *ifip = iface_n_ip(i);
-
- if(ifip == NULL) {
- DEBUG(0,("create_listen_fdset: interface %d has NULL IP address !\n", i));
- continue;
- }
- s = open_socket_in(SOCK_STREAM, wins_port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- if (listen(s, 5) == -1) {
- DEBUG(5,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
- }
- } else {
- /* Just bind to 0.0.0.0 - accept connections from anywhere. */
- num_interfaces = 1;
-
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, wins_port, 0, interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- if (listen(s, 5) == -1) {
- DEBUG(0,("create_listen_fdset: listen: %s\n", strerror(errno)));
- close(s);
- return False;
- }
-
- add_fd_to_sock_array(s);
- FD_SET(s, listen_set);
- }
-
- return True;
-}
-
-/*******************************************************************
- read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket
- ******************************************************************/
-static struct wins_packet_struct *read_wins_packet(int fd, int timeout)
-{
- struct wins_packet_struct *p;
- GENERIC_PACKET *q;
- struct BUFFER inbuf;
- ssize_t len=0;
- size_t total=0;
- ssize_t ret;
- BOOL ok = False;
-
- inbuf.buffer=NULL;
- inbuf.length=0;
- inbuf.offset=0;
-
- if(!grow_buffer(&inbuf, 4))
- return NULL;
-
- ok = (read(fd, inbuf.buffer,4) == 4);
- if (!ok)
- return NULL;
- len = smb_len(inbuf.buffer);
-
- if (len<=0)
- return NULL;
-
- if(!grow_buffer(&inbuf, len))
- return NULL;
-
- while (total < len) {
- ret = read(fd, inbuf.buffer + total + 4, len - total);
- if (ret == 0) {
- DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(len - total), strerror(errno) ));
- return NULL;
- }
- if (ret == -1) {
- DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(len - total), strerror(errno) ));
- return NULL;
- }
- total += ret;
- }
-
- q = (GENERIC_PACKET *)talloc(mem_ctx, sizeof(GENERIC_PACKET));
- p = (struct wins_packet_struct *)talloc(mem_ctx, sizeof(*p));
- if (q==NULL || p==NULL)
- return NULL;
-
- decode_generic_packet(&inbuf, q);
-
- q->fd=fd;
-
- p->next = NULL;
- p->prev = NULL;
- p->stop_packet = False;
- p->timestamp = time(NULL);
- p->fd = fd;
- p->packet=q;
-
- return p;
-}
-
-static struct wins_packet_struct *packet_queue = NULL;
-
-/*******************************************************************
- Queue a packet into a packet queue
-******************************************************************/
-static void queue_packet(struct wins_packet_struct *packet)
-{
- struct wins_packet_struct *p;
-
- if (!packet_queue) {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
-
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
- ;
-
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
-}
-
-/****************************************************************************
- Listens for NMB or DGRAM packets, and queues them.
- return True if the socket is dead
-***************************************************************************/
-static BOOL listen_for_wins_packets(void)
-{
- int num_interfaces = iface_count();
- fd_set fds;
- int i, num, s, new_s;
- struct timeval timeout;
-
- if(listen_set == NULL) {
- if(!create_listen_fdset()) {
- DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
- return True;
- }
- }
-
- memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
-
- timeout.tv_sec = NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
-
- /* Prepare for the select - allow certain signals. */
-
- BlockSignals(False, SIGTERM);
-
- num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
-
- /* We can only take signals when we are in the select - block them again here. */
-
- BlockSignals(True, SIGTERM);
-
- if(num == -1)
- return False;
-
- for (; num > 0; num--) {
- s = -1;
- /* check the sockets we are only listening on, waiting to accept */
- for (i=0; i<num_interfaces; i++) {
- struct sockaddr addr;
- socklen_t in_addrlen = sizeof(addr);
-
- if(FD_ISSET(sock_array[i], &fds)) {
- s = sock_array[i];
- /* Clear this so we don't look at it again. */
- FD_CLR(sock_array[i], &fds);
-
- /* accept and add the new socket to the listen set */
- new_s=accept(s, &addr, &in_addrlen);
-
- if (new_s < 0)
- continue;
-
- DEBUG(5,("listen_for_wins_packets: new connection, old: %d, new : %d\n", s, new_s));
-
- set_socket_options(new_s, "SO_KEEPALIVE");
- set_socket_options(new_s, user_socket_options);
- FD_SET(new_s, listen_set);
- add_fd_to_sock_array(new_s);
- }
- }
-
- /*
- * check for the sockets we are waiting data from
- * either client sending datas
- * or reply to our requests
- */
- for (i=num_interfaces; i<listen_number; i++) {
- if(FD_ISSET(sock_array[i], &fds)) {
- struct wins_packet_struct *packet = read_wins_packet(sock_array[i], timeout.tv_sec);
- if (packet) {
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- DEBUG(2,("listen_for_wins_packets: some data on fd %d\n", sock_array[i]));
- FD_CLR(sock_array[i], &fds);
- break;
- }
-
- }
-
- }
-
- return False;
-}
-
-
-/*******************************************************************
- Run elements off the packet queue till its empty
-******************************************************************/
-
-static void run_wins_packet_queue(void)
-{
- struct wins_packet_struct *p;
-
- while ((p = packet_queue)) {
- packet_queue = p->next;
- if (packet_queue)
- packet_queue->prev = NULL;
- p->next = p->prev = NULL;
-
- construct_reply(p);
-
- /* if it was a stop assoc, close the connection */
- if (p->stop_packet) {
- FD_CLR(p->fd, listen_set);
- remove_fd_from_sock_array(p->fd);
- close(p->fd);
- }
- }
-}
-
-/**************************************************************************** **
- The main select loop.
- **************************************************************************** */
-static void process(void)
-{
-
- while( True ) {
- time_t t = time(NULL);
-
- /* check for internal messages */
- message_dispatch();
-
- if(listen_for_wins_packets())
- return;
-
- run_wins_packet_queue();
-
- run_pull_replication(t);
-
- run_push_replication(t);
-
- /*
- * Reload the services file if we got a sighup.
- */
-
- if(reload_after_sighup) {
- reload_services( True );
- reopen_logs();
- reload_after_sighup = False;
- }
-
- /* free temp memory */
- talloc_destroy_pool(mem_ctx);
-
- /* free up temp memory */
- lp_talloc_free();
- }
-} /* process */
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- /* shall I run as a daemon */
- static BOOL is_daemon = False;
- static BOOL interactive = False;
- static BOOL Fork = True;
- static BOOL log_stdout = False;
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
- { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc)" },
- { "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Run interactive (not a daemon)" },
- { "port", 'p', POPT_ARG_INT, &wins_port, 'p', "Listen on the specified port" },
- POPT_COMMON_SAMBA
- POPT_TABLEEND
- };
- int opt;
- poptContext pc;
-
-#ifdef HAVE_SET_AUTH_PARAMETERS
- set_auth_parameters(argc,argv);
-#endif
-
- pc = poptGetContext("wrepld", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'i':
- interactive = True;
- Fork = False;
- log_stdout = True;
- break;
- }
- }
-
-
- if (log_stdout && Fork) {
- d_printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
-
-#ifdef HAVE_SETLUID
- /* needed for SecureWare on SCO */
- setluid(0);
-#endif
-
- sec_init();
-
- load_case_tables();
-
- set_remote_machine_name("wrepld", False);
-
- setup_logging(argv[0],log_stdout);
-
- /* we want to re-seed early to prevent time delays causing
- client problems at a later date. (tridge) */
- generate_random_buffer(NULL, 0, False);
-
- /* make absolutely sure we run as root - to handle cases where people
- are crazy enough to have it setuid */
-
- gain_root_privilege();
- gain_root_group_privilege();
-
- fault_setup((void (*)(void *))exit_server);
- CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
-
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
-
-#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
-#endif
-
-#if defined(SIGUSR2)
- /* We are no longer interested in USR2 */
- BlockSignals(True,SIGUSR2);
-#endif
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't recieve them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
-
- /* we want total control over the permissions on created files,
- so set our umask to 0 */
- umask(0);
-
- reopen_logs();
-
- DEBUG(1,( "wrepld version %s started.\n", SAMBA_VERSION_STRING));
- DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
-
- DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
- (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
-
- if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
- DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
- exit(1);
- }
-
- /*
- * Do this before reload_services.
- */
-
- if (!reload_services(False))
- return(-1);
-
- if (!init_names())
- return -1;
-
-#ifdef WITH_PROFILE
- if (!profile_setup(False)) {
- DEBUG(0,("ERROR: failed to setup profiling\n"));
- return -1;
- }
-#endif
-
- CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-
- DEBUG(3,( "loaded services\n"));
-
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
-
- if (is_daemon && !interactive) {
- DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork);
- }
-
-#if HAVE_SETPGID
- /*
- * If we're interactive we want to set our own process group for
- * signal management.
- */
- if (interactive)
- setpgid( (pid_t)0, (pid_t)0);
-#endif
-
- if (!directory_exist(lp_lockdir(), NULL)) {
- mkdir(lp_lockdir(), 0755);
- }
-
- if (is_daemon) {
- pidfile_create("wrepld");
- }
-
- if (!message_init()) {
- exit(1);
- }
-
- /* Initialise the memory context */
- mem_ctx=talloc_init("wins repl talloc ctx");
-
- /* initialise the global partners table */
- partner_count=init_wins_partner_table();
-
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
- process();
-
- poptFreeContext(pc);
- exit_server("normal exit");
- return(0);
-}
diff --git a/source/wrepld/socket.c b/source/wrepld/socket.c
deleted file mode 100644
index 3d759f0ab89..00000000000
--- a/source/wrepld/socket.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- process incoming packets - main loop
- Copyright (C) Jean François Micouleau 1998-2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "wins_repl.h"
-
-fd_set *listen_set = NULL;
-int listen_number = 0;
-int *sock_array = NULL;
-
-/*******************************************************************
- Add an fd from the sock_array
-******************************************************************/
-void add_fd_to_sock_array(int fd)
-{
- int *temp_sock=NULL;
-
- temp_sock=(int *)Realloc(sock_array, (listen_number+1)*sizeof(int));
- if (temp_sock==NULL)
- return;
-
- sock_array=temp_sock;
- sock_array[listen_number]=fd;
- listen_number++;
-}
-
-
-/*******************************************************************
- Remove an fd from the sock_array
-******************************************************************/
-void remove_fd_from_sock_array(int fd)
-{
- int i,j;
-
- for (i=0; sock_array[i]!=fd && i<listen_number; i++)
- ;
-
- if (i==listen_number) {
- DEBUG(0,("remove_fd_from_sock_array: unknown fd: %d\n", fd));
- return;
- }
-
- if (i==listen_number-1) {
- sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int));
- return;
- }
-
- for (j=i; j<listen_number-1; j++)
- sock_array[j]=sock_array[j+1];
-
- sock_array=(int *)Realloc(sock_array, --listen_number*sizeof(int));
-}
diff --git a/source/wrepld/wins_repl.h b/source/wrepld/wins_repl.h
deleted file mode 100644
index 25b44422121..00000000000
--- a/source/wrepld/wins_repl.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Jean François Micouleau 1998-2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define OPCODE_NON_NBT 0x00007800
-
-/* the messages */
-#define MESSAGE_TYPE_START_ASSOC_REQUEST 0
-#define MESSAGE_TYPE_START_ASSOC_REPLY 1
-#define MESSAGE_TYPE_STOP_ASSOC 2
-#define MESSAGE_TYPE_REPLICATE 3
-
-/* the replication sub-message */
-#define MESSAGE_REP_ADD_VERSION_REQUEST 0
-#define MESSAGE_REP_ADD_VERSION_REPLY 1
-#define MESSAGE_REP_SEND_ENTRIES_REQUEST 2
-#define MESSAGE_REP_SEND_ENTRIES_REPLY 3
-#define MESSAGE_REP_UPDATE_NOTIFY_REQUEST 4
-
-/* stop reasons */
-#define STOP_REASON_USER_REASON 0
-#define STOP_REASON_AUTH_FAILED 1
-#define STOP_REASON_INCOMPLETE_VERSION 2
-#define STOP_REASON_BUG_CHECK 3
-#define STOP_REASON_MESSAGE_ERROR 4
-
-
-typedef struct _WINS_OWNER {
- struct in_addr address;
- SMB_BIG_UINT max_version;
- SMB_BIG_UINT min_version;
- int type;
- time_t last_pull;
- time_t last_push;
-} WINS_OWNER;
-
-typedef struct _WINS_NAME {
- int name_len; /* always 0x11 */
- char name[16];
- char type;
- int empty;
- int name_flag;
- int group_flag;
- SMB_BIG_UINT id;
- int num_ip;
- struct in_addr owner;
- struct in_addr *others;
- int foo; /* 0xffffff */
-} WINS_NAME;
-
-typedef struct _WINS_PARTNERS
-{
- int client_assoc;
- int server_assoc;
- BOOL pull_partner;
- BOOL push_partner;
- struct in_addr partner_server;
- struct in_addr other_server;
-} WINS_PARTNER;
-
-typedef struct _generic_header{
- int data_size;
- int opcode;
- int assoc_ctx;
- int mess_type;
-} generic_header;
-
-typedef struct _START_ASSOC_REQUEST {
- int assoc_ctx;
- int min_ver;
- int maj_ver;
-} START_ASSOC_REQUEST;
-
-typedef struct _START_ASSOC_REPLY {
- int assoc_ctx;
- int min_ver;
- int maj_ver;
-} START_ASSOC_REPLY;
-
-typedef struct _STOP_ASSOC {
- int reason;
-} STOP_ASSOC;
-
-typedef struct _AVMT_REP {
- int partner_count;
- WINS_OWNER *wins_owner;
- struct in_addr initiating_wins_server;
-} AVMT_REP;
-
-typedef struct _SEND_ENTRIES_REQUEST {
- WINS_OWNER wins_owner;
-} SEND_ENTRIES_REQUEST;
-
-typedef struct _SEND_ENTRIES_REPLY {
- int max_names;
- WINS_NAME *wins_name;
-} SEND_ENTRIES_REPLY;
-
-typedef struct _UPDATE_NOTIFY_REQUEST {
- int partner_count;
- WINS_OWNER *wins_owner;
- struct in_addr initiating_wins_server;
-} UPDATE_NOTIFY_REQUEST;
-
-typedef struct _REPLICATE {
- int msg_type;
-
- AVMT_REP avmt_rep;
- SEND_ENTRIES_REQUEST se_rq;
- SEND_ENTRIES_REPLY se_rp;
- UPDATE_NOTIFY_REQUEST un_rq;
-} REPLICATE;
-
-
-typedef struct _GENERIC_PACKET {
- int fd;
-
- generic_header header;
-
- START_ASSOC_REQUEST sa_rq;
- START_ASSOC_REPLY sa_rp;
- STOP_ASSOC so;
- REPLICATE rep;
-} GENERIC_PACKET;
-
-struct wins_packet_struct
-{
- struct wins_packet_struct *next;
- struct wins_packet_struct *prev;
- BOOL stop_packet;
- int fd;
- time_t timestamp;
- GENERIC_PACKET *packet;
-};
-
-struct BUFFER {
- char *buffer;
- int offset;
- int length;
-};
-
-
-
-#include "wrepld_proto.h"
-
diff --git a/swat/README b/swat/README
new file mode 100755
index 00000000000..657a5937d71
--- /dev/null
+++ b/swat/README
@@ -0,0 +1,82 @@
+This is a brief description of how to install and use the Samba Web
+Administration Tool on your machine.
+
+Installation
+------------
+
+After compiling Samba (via a "make"), running "make install" will
+install the swat binary and the various help files and images for
+you. A default install would put these in:
+
+/usr/local/samba/bin/swat
+/usr/local/samba/swat/images/*
+/usr/local/samba/swat/help/*
+
+Running via inetd
+-----------------
+
+You then need to edit your /etc/inetd.conf and /etc/services to enable
+SWAT to be launched via inetd.
+
+In /etc/services you need to add a line like this:
+
+swat 901/tcp
+
+the choice of port number isn't really important except that it should
+be less than 1024 and not currently used (using a number above 1024
+presents an obscure security hole depending on the implementation
+details of your inetd daemon).
+
+In /etc/inetd.conf you should add a line like this:
+
+swat stream tcp nowait.400 root /usr/local/samba/bin/swat swat
+
+One you have edited /etc/services and /etc/inetd.conf you need to send
+a HUP signal to inetd. On many systems "killall -1 inetd" will do this
+on others you will need to use "kill -1 PID" where PID is the process
+ID of the inetd daemon.
+
+
+
+Launching
+---------
+
+To launch SWAT just run your favourite web browser and point it at
+http://localhost:901/
+
+Note that you can attach to SWAT from any IP connected machine but
+connecting from a remote machine leaves your connection open to
+password sniffing as passwords will be sent in the clear over the
+wire.
+
+You should be prompted for a username/password when you connect. You
+will need to provide the username "root" and the correct root
+password.
+
+Running
+-------
+
+Just follow your nose! If you can't work out how to use it then maybe
+you should use "vi smb.conf" instead.
+
+
+WARNINGS
+--------
+
+SWAT will rewrite your smb.conf file. It will rearrange the entries
+and delete all comments, include= and copy= options. If you have a
+carefully crafted smb.conf then back it up or don't use SWAT!
+
+There is also a short HOWTO for configuring secure, remote access
+to SWAT (swat does not natively support HTTPS) at your favorite
+samba.org mirror (see http://samba.org for a list) at
+/samba/docs/swat_ssl.html
+
+
+Development
+-----------
+
+Please join the samba-technical@samba.org (http://lists.samba.org/listinfo/samba-technical)
+mailing list if you want to discuss the development of SWAT. Note that this list
+is for technical developer discussions and is not a general help list.
+
diff --git a/swat/help/welcome.html b/swat/help/welcome.html
index 91d4d7eb008..43047843624 100644
--- a/swat/help/welcome.html
+++ b/swat/help/welcome.html
@@ -22,9 +22,8 @@ Please choose a configuration action using one of the above buttons
<li><a href="/swat/help/smbcontrol.1.html" target="docs">smbcontrol</a> - send control messages to Samba daemons
<li><a href="/swat/help/smbpasswd.8.html" target="docs">smbpasswd</a> - managing SMB passwords
<li><a href="/swat/help/swat.8.html" target="docs">SWAT</a> - web configuration tool
- <li><a href="/swat/help/net.8.html" target="docs">net</a> - tool for administration of Samba and remote CIFS servers
- <li><a href="/swat/help/pdbedit.8.html" target="docs">pdbedit</a> - Samba user account management tool
- <li><a href="/swat/help/tdbbackup.8.html" target="docs">tdbbackup</a> - Tool for backing up TDB databases
+ <li><a href="/swat/help/make_smbcodepage.1.html" target="docs">make_smbcodepage</a> - codepage creation
+ <li><a href="/swat/help/make_unicodemap.1.html" target="docs">make_unicodemap</a> - unicode map file creation
</ul>
<li><b>Client Tools</b>
<ul>
@@ -33,12 +32,8 @@ Please choose a configuration action using one of the above buttons
<li><a href="/swat/help/smbclient.1.html" target="docs">smbclient</a> - command line SMB client
<li><a href="/swat/help/smbmnt.8.html" target="docs">smbmnt</a> - helper utility for mounting SMB filesystems on Linux hosts
<li><a href="/swat/help/smbmount.8.html" target="docs">smbmount</a> - user space tool for mounting SMB filesystems under Linux
+ <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - command line SMB print client
<li><a href="/swat/help/smbumount.8.html" target="docs">smbumount</a> - user space tool for umounting SMB filesystems under Linux
- <li><a href="/swat/help/ntlm_auth.1.html" target="docs">ntlm_auth</a> - allow external programs to use NTLM authentication
- <li><a href="/swat/help/smbcquotas.1.html" target="docs">smbcquotas</a> - get or set quotas on NTFS 5 shares
- <li><a href="/swat/help/smbsh.1.html" target="docs">smbsh</a> - Allow access to remote SMB shares using a UNIX shell
- <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - Send a print job to an SMB printer
- <li><a href="/swat/help/smbtree.1.html" target="docs">smbtree</a> - Text-based SMB network browsing
</ul>
<li><b>Diagnostic Utilities</b>
<ul>
@@ -46,20 +41,28 @@ Please choose a configuration action using one of the above buttons
<li><a href="/swat/help/testparm.1.html" target="docs">testparm</a> - validating your config file
<li><a href="/swat/help/testprns.1.html" target="docs">testprns</a> - testing printer configuration
<li><a href="/swat/help/nmblookup.1.html" target="docs">nmblookup</a> - NetBIOS name query tool
- <li><a href="/swat/help/wbinfo.1.html" target="docs">wbinfo</a> - Tool for getting winbind information
</ul>
- <li><b>Misc. Utilities</b>
+ <li><b>Books</b>
<ul>
- <li><a href="/swat/help/profiles.1.html" target="docs">profiles</a> - migrating profiles from one domain to another
- <li><a href="/swat/help/editreg.1.html" target="docs">editreg</a> - editing windows registry files
- <li><a href="/swat/help/log2pcap.1.html" target="docs">log2pcap</a> - generate pcap files from samba log files
+ <li><a href="/swat/using_samba/index.html" target="docs">Using Samba</a> - by Robert Eckstein, David Collier-Brown and Peter Kelly
</ul>
- <li><b>Books</b>
+ <li><b>Samba HOWTO Collection</b></li>
<ul>
- <li><a href="/swat/using_samba/toc.html" target="docs">Using Samba, 2ed.</a> - by Jay Ts, Robert Eckstein, and David Collier-Brown
- <li><a href="/swat/help/howto/">The Official Samba HOWTO and Reference Guide</a>
- <li><a href="/swat/help/guide/">Samba 3 by Example</a>
- <li><a href="/swat/help/devel/">The Samba Developer Guide</a>
+ <li><a href="/swat/help/Samba-HOWTO-Collection.html">Entire Collection (one file)</a>
+ <li><a href="/swat/help/UNIX_INSTALL.html">HOWTO Install and Test Samba</a>
+ <li><a href="/swat/help/ENCRYPTION.html">How To Configure Samba to use Encrypted Passwords</a>
+ <li><a href="/swat/help/DOMAIN_MEMBER.html">security = domain in Samba 2.x</a>
+ <li><a href="/swat/help/winbind.html">Unified Logons between Windows NT and UNIX Using Winbind</a>
+ <li><a href="/swat/help/msdfs_setup.html">Setting Samba as an MS-DFS server</a>
+ <li><a href="/swat/help/NT_Security.html">UNIX Permission Bits and Samba 2.x</a>
+ <li><a href="/swat/help/OS2-Client-HOWTO.html">OS/2 Clients and Samba</a>
+ <li><a href="/swat/help/printer_driver2.html">Printing under Samba 2.2.x</a>
+ <li><a href="/swat/help/Integrating-with-Windows.html">Integrating Name Resolution and Authentication Services</a>
+ <li><a href="/swat/help/PAM-Authentication-And-Samba.html">Configuring Samba and PAM</a>
+ <li><a href="/swat/help/CVS-Access.html">CVS Access to Samba code</a>
+ <li><a href="/swat/help/Samba-PDC-HOWTO.html">How To Configure Samba as a Primary Domain Controller</a>
+ <li><a href="/swat/help/Samba-BDC-HOWTO.html">How To Configure Samba as a Backup Domain Controller for a Samba PDC</a>
+ <li><a href="/swat/help/Samba-LDAP-HOWTO.html">How to Replace smbpasswd with an LDAP Directory</a>
</ul>
</ul>
diff --git a/swat/images/globals.gif b/swat/images/globals.gif
index 7a9a8510d77..75e874f380c 100644
--- a/swat/images/globals.gif
+++ b/swat/images/globals.gif
Binary files differ
diff --git a/swat/images/home.gif b/swat/images/home.gif
index 84b1dd032f8..364a2955c84 100644
--- a/swat/images/home.gif
+++ b/swat/images/home.gif
Binary files differ
diff --git a/swat/images/passwd.gif b/swat/images/passwd.gif
index 17393a14020..2fc88fb182e 100644
--- a/swat/images/passwd.gif
+++ b/swat/images/passwd.gif
Binary files differ
diff --git a/swat/images/printers.gif b/swat/images/printers.gif
index db9ec3f0e0a..212a70c6640 100644
--- a/swat/images/printers.gif
+++ b/swat/images/printers.gif
Binary files differ
diff --git a/swat/images/shares.gif b/swat/images/shares.gif
index b3af15e35d6..2c04ca8b9c7 100644
--- a/swat/images/shares.gif
+++ b/swat/images/shares.gif
Binary files differ
diff --git a/swat/images/status.gif b/swat/images/status.gif
index 81ef0bcf16f..48e2f07fcd7 100644
--- a/swat/images/status.gif
+++ b/swat/images/status.gif
Binary files differ
diff --git a/swat/images/viewconfig.gif b/swat/images/viewconfig.gif
index bdeac1cf967..5dee5156690 100644
--- a/swat/images/viewconfig.gif
+++ b/swat/images/viewconfig.gif
Binary files differ
diff --git a/swat/images/wizard.gif b/swat/images/wizard.gif
index a4614e936bb..a2474e0f008 100644
--- a/swat/images/wizard.gif
+++ b/swat/images/wizard.gif
Binary files differ
diff --git a/swat/lang/ja/help/welcome.html b/swat/lang/ja/help/welcome.html
deleted file mode 100644
index 240ad22ceff..00000000000
--- a/swat/lang/ja/help/welcome.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<h3>SWAT ‚ւ悤‚±‚»!</h3>
-
-ã‚̃{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚µ‚ÄÝ’è‚ðs‚Á‚Ä‚­‚¾‚³‚¢B
-
-<h3><a href="/swat/help/samba.7.html" target="docs">Samba</a> ƒhƒLƒ…ƒƒ“ƒg</h3>
-
-<ul>
- <li><b>ƒf[ƒ‚ƒ“</b>
- <ul>
- <li><a href="/swat/help/smbd.8.html" target="docs">smbd</a> - SMB ƒf[ƒ‚ƒ“
- <li><a href="/swat/help/nmbd.8.html" target="docs">nmbd</a> - NetBIOS ƒl[ƒ€ƒT[ƒo
- <li><a href="/swat/help/winbindd.8.html" target="docs">winbindd</a> - winbind ƒf[ƒ‚ƒ“
- </ul>
- <li><b>Ý’èƒtƒ@ƒCƒ‹</b>
- <ul>
- <li><a href="/swat/help/smb.conf.5.html" target="docs">smb.conf</a> - Samba Ý’èƒtƒ@ƒCƒ‹
- <li><a href="/swat/help/lmhosts.5.html" target="docs">lmhosts</a> - NetBIOS ‚Ì hosts ƒtƒ@ƒCƒ‹
- <li><a href="/swat/help/smbpasswd.5.html" target="docs">smbpasswd</a> - SMB ƒpƒXƒ[ƒhƒtƒ@ƒCƒ‹
- </ul>
- <li><b>ŠÇ—ƒ†[ƒeƒBƒŠƒeƒB</b>
- <ul>
- <li><a href="/swat/help/smbcontrol.1.html" target="docs">smbcontrol</a> - Samba ƒf[ƒ‚ƒ“‚ւ̃Rƒ“ƒgƒ[ƒ‹ƒƒbƒZ[ƒW‚Ì‘—o
- <li><a href="/swat/help/smbpasswd.8.html" target="docs">smbpasswd</a> - SMB ƒpƒXƒ[ƒh‚ÌŠÇ—
- <li><a href="/swat/help/swat.8.html" target="docs">SWAT</a> - Web Ý’èƒc[ƒ‹
- <li><a href="/swat/help/net.8.html" target="docs">net</a> - Samba ‚¨‚æ‚уŠƒ‚[ƒg‚Ì CIFS ƒT[ƒo‚ÌŠÇ—ƒc[ƒ‹
- <li><a href="/swat/help/pdbedit.8.html" target="docs">pdbedit</a> - Samba ‚̃†[ƒUƒAƒJƒEƒ“ƒgŠÇ—ƒc[ƒ‹
- <li><a href="/swat/help/tdbbackup.8.html" target="docs">tdbbackup</a> - TDB ƒf[ƒ^ƒx[ƒX‚̃oƒbƒNƒAƒbƒvƒc[ƒ‹
- </ul>
- <li><b>ƒNƒ‰ƒCƒAƒ“ƒgƒc[ƒ‹</b>
- <ul>
- <li><a href="/swat/help/rpcclient.1.html" target="docs">rpcclient</a> - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì MS-RPC ƒNƒ‰ƒCƒAƒ“ƒg
- <li><a href="/swat/help/smbtar.1.html" target="docs">smbtar</a> - SMB ƒoƒbƒNƒAƒbƒvƒc[ƒ‹
- <li><a href="/swat/help/smbclient.1.html" target="docs">smbclient</a> - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì SMB ƒNƒ‰ƒCƒAƒ“ƒg
- <li><a href="/swat/help/smbmnt.8.html" target="docs">smbmnt</a> - Linux ã‚Ì SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚ðƒ}ƒEƒ“ƒg‚·‚éۂ̕╃c[ƒ‹
- <li><a href="/swat/help/smbmount.8.html" target="docs">smbmount</a> - Linux ‚É‚¨‚¯‚é SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚̃}ƒEƒ“ƒg‚ðŽÀŒ»‚·‚郆[ƒU‹óŠÔ‚̃c[ƒ‹
- <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì SMB ˆóüƒNƒ‰ƒCƒAƒ“ƒg
- <li><a href="/swat/help/smbumount.8.html" target="docs">smbumount</a> - Linux ‚É‚¨‚¯‚é SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚̃Aƒ“ƒ}ƒEƒ“ƒg‚ðŽÀŒ»‚·‚郆[ƒU‹óŠÔ‚̃c[ƒ‹
- <li><a href="/swat/help/ntlm_auth.1.html" target="docs">ntlm_auth</a> - •ÊƒvƒƒOƒ‰ƒ€‚©‚ç‚Ì NTLM ”FØ‚ÌŽg—p‚ðŽÀŒ»
- <li><a href="/swat/help/smbcquotas.1.html" target="docs">smbcquotas</a> - NTFS 5 ‹¤—L‚̃NƒH[ƒ^î•ñ‚ÌÝ’è‚Ǝ擾
- <li><a href="/swat/help/smbsh.1.html" target="docs">smbsh</a> - UNIX ƒVƒFƒ‹‚ð—p‚¢‚½ƒŠƒ‚[ƒg SMB ‹¤—L‚ւ̃AƒNƒZƒX‚ðŽÀŒ»
- <li><a href="/swat/help/smbtree.1.html" target="docs">smbtree</a> - ƒeƒLƒXƒgƒx[ƒX‚Ì SMB ƒlƒbƒgƒ[ƒNƒuƒ‰ƒEƒWƒ“ƒO
- <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - ˆóüƒWƒ‡ƒu‚ð SMB ƒvƒŠƒ“ƒ^‚É‘—M
- </ul>
- <li><b>f’fƒ†[ƒeƒBƒŠƒeƒB</b>
- <ul>
- <li><a href="/swat/help/smbstatus.1.html" target="docs">smbstatus</a> - Samba ‚ÌŠÄŽ‹
- <li><a href="/swat/help/testparm.1.html" target="docs">testparm</a> - Ý’èƒtƒ@ƒCƒ‹‚Ì®‡«‚ÌŒŸ¸
- <li><a href="/swat/help/testprns.1.html" target="docs">testprns</a> - ƒvƒŠƒ“ƒ^Ý’è‚ÌŒŸ¸
- <li><a href="/swat/help/nmblookup.1.html" target="docs">nmblookup</a> - NetBIOS –¼‚ÌŒŸõƒc[ƒ‹
- <li><a href="/swat/help/wbinfo.1.html" target="docs">wbinfo</a> - winbind î•ñ‚̎擾ƒc[ƒ‹
- </ul>
- <li><b>‚»‚Ì‘¼‚̃†[ƒeƒBƒŠƒeƒB</b>
- <ul>
- <li><a href="/swat/help/profiles.1.html" target="docs">profiles</a> - •ÊƒhƒƒCƒ“‚ւ̃vƒƒtƒ@ƒCƒ‹‚̈Ús
- <li><a href="/swat/help/editreg.1.html" target="docs">editreg</a> - Windows ƒŒƒWƒXƒgƒŠƒtƒ@ƒCƒ‹‚Ì•ÒW
- <li><a href="/swat/help/log2pcap.1.html" target="docs">log2pcap</a> - Samba ‚̃ƒOƒtƒ@ƒCƒ‹‚©‚ç pcap ƒtƒ@ƒCƒ‹‚̶¬
- </ul>
- <li><b>‘Ð</b>
- <ul>
- <li><a href="/swat/using_samba/toc.html" target="docs">Using Samba ‘æ“ñ”Å</a> - ’˜ŽÒ: Jay Ts, Robert Eckstein, David Collier-Brown
- <li><a href="/swat/help/Samba-HOWTO-Collection.html">Samba HOWTO ƒRƒŒƒNƒVƒ‡ƒ“</a>
- </ul>
-</ul>
-
- <h3>ƒtƒB[ƒhƒoƒbƒN</h3>
-
- ‚±‚̃o[ƒWƒ‡ƒ“‚Ì SWAT ‚ÉŠÖ‚·‚é–â‘è‚ɂ‚¢‚Ä‚Ì‹c˜_‚ðs‚È‚¢‚½‚¢•û‚ÍA
- <A HREF="http://lists.samba.org/">samba</A> ƒ[ƒŠƒ“ƒOƒŠƒXƒg‚Ö‚ÌŽQ‰Á‚ð‚¨Šè‚¢‚µ‚Ü‚·B
-<small>(‚à‚µ‚­‚Í <A HREF="http://www.samba.gr.jp/ml/">sugj-tech</A> ƒ[ƒŠƒ“ƒOƒŠƒXƒg‚É“ú–{Œê‚Å‚¨Šè‚¢‚µ‚Ü‚·)</small>
diff --git a/swat/lang/ja/include/footer.html b/swat/lang/ja/include/footer.html
deleted file mode 100644
index 7c3b483684c..00000000000
--- a/swat/lang/ja/include/footer.html
+++ /dev/null
@@ -1,3 +0,0 @@
-</TD></TR></TABLE></CENTER>
-</BODY>
-</HTML>
diff --git a/swat/lang/ja/include/header.html b/swat/lang/ja/include/header.html
deleted file mode 100644
index 2fbe9bb7546..00000000000
--- a/swat/lang/ja/include/header.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
-<TITLE>Samba Web Administration Tool</TITLE>
-<link rel="STYLESHEET" type="text/css" href="/swat/include/header_css.html">
-</HEAD>
-<BODY bgcolor="white">
-<CENTER>
-<IMG SRC="/swat/images/samba.gif" ALT="[ Samba ]" border=0><BR>
-<TABLE WIDTH="98%" CELLSPACING=1 CELLPADDING=4 BORDER=1>
-<TR><TD BGCOLOR="#ddddd0">
diff --git a/swat/lang/ja/include/header.nocss.html b/swat/lang/ja/include/header.nocss.html
deleted file mode 100644
index 56d13dbc6d1..00000000000
--- a/swat/lang/ja/include/header.nocss.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
-<TITLE>Samba Web Administration Tool</TITLE>
-</HEAD>
-<BODY bgcolor="white">
-<CENTER>
-<IMG SRC="/swat/images/samba.gif" ALT="[ Samba ]" border=0><BR>
-<TABLE WIDTH="98%" CELLSPACING=1 CELLPADDING=4 BORDER=1>
-<TR><TD BGCOLOR="#ddddd0">
diff --git a/swat/lang/ja/include/header_css.html b/swat/lang/ja/include/header_css.html
deleted file mode 100644
index b70876b6f82..00000000000
--- a/swat/lang/ja/include/header_css.html
+++ /dev/null
@@ -1 +0,0 @@
-.i18n_translated_parm {color: #555555}
diff --git a/swat/lang/tr/help/welcome.html b/swat/lang/tr/help/welcome.html
deleted file mode 100644
index 617f3678d39..00000000000
--- a/swat/lang/tr/help/welcome.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<h3>Swat'a Hoþgeldiniz!</h3>
-
-Yukarýdaki düðmelerden birini kullanarak bir ayar eylemi seçin.
-
-<h3><a href="/swat/help/samba.7.html" target="docs">Samba</a> Dökümantasyon</h3>
-
-<ul>
- <li><b>Sunucular</b>
- <ul>
- <li><a href="/swat/help/smbd.8.html" target="docs">smbd</a> - SMB sunucusu
- <li><a href="/swat/help/nmbd.8.html" target="docs">nmbd</a> - NetBIOS isim sunucusu
- <li><a href="/swat/help/winbindd.8.html" target="docs">winbindd</a> - winbind sunucusu
- </ul>
- <li><b>Ayar dosyalarý</b>
- <ul>
- <li><a href="/swat/help/smb.conf.5.html" target="docs">smb.conf</a> - ana Samba ayar dosyasý
- <li><a href="/swat/help/lmhosts.5.html" target="docs">lmhosts</a> - NetBIOS hosts dosyasý
- <li><a href="/swat/help/smbpasswd.5.html" target="docs">smbpasswd</a> - SMB þifre dosyasý
- </ul>
- <li><b>Yönetim Araçlarý</b>
- <ul>
- <li><a href="/swat/help/smbcontrol.1.html" target="docs">smbcontrol</a> - Samba sunucularýna kontrol iletileri gönderir
- <li><a href="/swat/help/smbpasswd.8.html" target="docs">smbpasswd</a> - SMB þifrelerini düzenler
- <li><a href="/swat/help/swat.8.html" target="docs">SWAT</a> - web arayüzlü ayar aracý
- <li><a href="/swat/help/make_smbcodepage.1.html" target="docs">make_smbcodepage</a> - kod sayfasý oluþturur
- <li><a href="/swat/help/make_unicodemap.1.html" target="docs">make_unicodemap</a> - unicode eþleþme dosyasý oluþturur
- <li><a href="/swat/help/smbrun.1.html" target="docs">smbrun</a> - içsel smbd aracý
- </ul>
- <li><b>Ýstemci Araçlarý</b>
- <ul>
- <li><a href="/swat/help/rpcclient.1.html" target="docs">rpcclient</a> - komut satýrý MS-RPC istemcisi
- <li><a href="/swat/help/smbtar.1.html" target="docs">smbtar</a> - SMB yedekleme aracý
- <li><a href="/swat/help/smbclient.1.html" target="docs">smbclient</a> - komut satýrý SMB istemcisi
- <li><a href="/swat/help/smbmnt.8.html" target="docs">smbmnt</a> - Linux makinalarýna SMB dosya sistemlerini baðlamak için yardýmcý araç
- <li><a href="/swat/help/smbmount.8.html" target="docs">smbmount</a> - Linux altýnda SMB dosya sistemlerini baðlamak için kullanýcý aracý
- <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - komut satýrý SMB yazýcý istemcisi
- <li><a href="/swat/help/smbumount.8.html" target="docs">smbumount</a> - Linux altýnda SMB dosya sistemlerini çözmek için kullanýcý aracý
- </ul>
- <li><b>Teþhis Araçlarý</b>
- <ul>
- <li><a href="/swat/help/smbstatus.1.html" target="docs">smbstatus</a> - Samba gözlemcisi
- <li><a href="/swat/help/testparm.1.html" target="docs">testparm</a> - ayar dosyasýný kontrol eder
- <li><a href="/swat/help/testprns.1.html" target="docs">testprns</a> - yazýcý ayarlarýný kontrol eder
- <li><a href="/swat/help/nmblookup.1.html" target="docs">nmblookup</a> - NetBIOS isim sorgulama aracý
- </ul>
- <li><b>Kitaplar</b>
- <ul>
- <li><a href="/swat/using_samba/index.html" target="docs">Samba'yý Kullanmak</a> - Yazan: Robert Eckstein, David Collier-Brown ve Peter Kelly
- </ul>
- <li><b>Samba HOWTO (Nasýl Yapýlýr?) Koleksiyonu</b></li>
- <ul>
- <li><a href="/swat/help/Samba-HOWTO-Collection.html">Bütün koleksiyon (tek dosya)</a>
- <li><a href="/swat/help/DOMAIN_MEMBER.html">Samba 2.x'de security = domain </a>
- <li><a href="/swat/help/winbind.html">Winbind Kullanarak Windows NT ve UNIX Arasýnda Birleþik Sistem Giriþi</a>
- <li><a href="/swat/help/msdfs_setup.html">Samba'yý bir MS-DFS Sunucusu Olarak Ayarlamak</a>
- <li><a href="/swat/help/NT_Security.html">UNIX Ýzin Bitleri ve Samba 2.x</a>
- <li><a href="/swat/help/OS2-Client-HOWTO.html">OS/2 Ýstemcileri ve Samba</a>
- <li><a href="/swat/help/printer_driver2.html">Samba 2.2.x Altýnda Yazýcý Kullanýmý</a>
- <li><a href="/swat/help/UNIX_INSTALL.html">Samba Nasýl Kurulur ve Kontrol Edilir?</a>
- <li><a href="/swat/help/Integrating-with-Windows.html">Ýsim Çözünme ve Yetkilendirme Ýþlemlerini Birleþtirmek</a>
- <li><a href="/swat/help/CVS-Access.html">Samba yazýlýmlarýna CVS Eriþimi</a>
- </ul>
-</ul>
-
- <h3>Ýletiþim</h3>
-
- Eðer SWAT'ýn bu sürümü ile ilgili konularý tartýþmak istiyorsanýz, lütfen
-<A HREF="http://lists.samba.org/">samba</A> eposta listesine üye olun.
- \ No newline at end of file
diff --git a/swat/lang/tr/images/globals.gif b/swat/lang/tr/images/globals.gif
deleted file mode 100644
index c0722d2df52..00000000000
--- a/swat/lang/tr/images/globals.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/home.gif b/swat/lang/tr/images/home.gif
deleted file mode 100644
index 119b6da6edf..00000000000
--- a/swat/lang/tr/images/home.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/passwd.gif b/swat/lang/tr/images/passwd.gif
deleted file mode 100644
index 25652f211b1..00000000000
--- a/swat/lang/tr/images/passwd.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/printers.gif b/swat/lang/tr/images/printers.gif
deleted file mode 100644
index a3caf2543b2..00000000000
--- a/swat/lang/tr/images/printers.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/samba.gif b/swat/lang/tr/images/samba.gif
deleted file mode 100644
index 3ec3d2195ff..00000000000
--- a/swat/lang/tr/images/samba.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/shares.gif b/swat/lang/tr/images/shares.gif
deleted file mode 100644
index bbac9d5411e..00000000000
--- a/swat/lang/tr/images/shares.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/status.gif b/swat/lang/tr/images/status.gif
deleted file mode 100644
index c606d6fcb07..00000000000
--- a/swat/lang/tr/images/status.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/images/viewconfig.gif b/swat/lang/tr/images/viewconfig.gif
deleted file mode 100644
index 3261ab4d8ba..00000000000
--- a/swat/lang/tr/images/viewconfig.gif
+++ /dev/null
Binary files differ
diff --git a/swat/lang/tr/include/header.html b/swat/lang/tr/include/header.html
deleted file mode 100644
index 7c11fd0ef9f..00000000000
--- a/swat/lang/tr/include/header.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<TITLE>Samba Web Yönetim Aracý</TITLE>
-</HEAD>
-<BODY bgcolor="white">
-<CENTER>
-<IMG SRC="/swat/images/samba.gif" ALT="[ Samba ]" border=0><BR>
-<TABLE WIDTH="98%" CELLSPACING=1 CELLPADDING=4 BORDER=1>
-<TR><TD BGCOLOR="#ddddd0">
diff --git a/testsuite/README b/testsuite/README
index 0d5157325a9..3ef5f4d8994 100644
--- a/testsuite/README
+++ b/testsuite/README
@@ -10,10 +10,3 @@ The Samba testsuite is divided up into the following subdirectories.
- server Miscellaneous server tests
- rpc_client Tests for the RPC client library code
- rpcclient Tests for the rpcclient program
-
- - build_farm Tests designed to run automatically on the build farm
-
-All the scripts except those in build_farm require an unreleased
-version of DejaGNU, and although they contain some useful tests they
-are not so useful at the moment. All scripts are migrating to a
-single test framework, Satyr. <cvs://cvs.samba.org/data/cvs/satyr>
diff --git a/testsuite/build_farm/backtrace b/testsuite/build_farm/backtrace
deleted file mode 100755
index efaa9f2dcde..00000000000
--- a/testsuite/build_farm/backtrace
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-# Modified version of tridge's backtrace script.
-# we want everything on stderr, so the program is not disturbed
-exec 1>&2
-
-PID=$1
-TMPFILE=$prefix/backtrace.$$
-cat << EOF > $TMPFILE
-set height 0
-up 8
-bt full
-quit
-EOF
-gdb -x $TMPFILE $prefix/sbin/smbd $PID
-/bin/rm -f $TMPFILE
diff --git a/testsuite/build_farm/basicsmb-domainsec-nt4.test b/testsuite/build_farm/basicsmb-domainsec-nt4.test
deleted file mode 100644
index 4e68acabec5..00000000000
--- a/testsuite/build_farm/basicsmb-domainsec-nt4.test
+++ /dev/null
@@ -1,28 +0,0 @@
-. basicsmb.fns
-
-test_joindomain_nt4() {
-
- echo $prefix/bin/smbpasswd -L -a -m buildfarm$
- $prefix/bin/smbpasswd -L -a -m buildfarm$
-
- echo $prefix/bin/net rpc oldjoin -S localhost
- $prefix/bin/net rpc oldjoin -S localhost
- status=$?
- if [ $status = 0 ]; then
- echo "'net rpc oldjoin' correctly joined the domain"
- else
- echo "'net rpc oldjoin' failed to join the domain! (status $status)"
- return 1
- fi
- return 0
-}
-
-password=samba
-security=DOMAIN
-(test_smb_conf_setup && test_smbpasswd $password ) || exit 1
-
-test_joindomain_nt4 $password || exit 1
-
-test_listfilesauth $security || exit 1
-test_listfilesnpw $security || exit 1
-
diff --git a/testsuite/build_farm/basicsmb-domainsec.test b/testsuite/build_farm/basicsmb-domainsec.test
index eb0a5c81aa1..0674e75bb82 100644
--- a/testsuite/build_farm/basicsmb-domainsec.test
+++ b/testsuite/build_farm/basicsmb-domainsec.test
@@ -1,27 +1,9 @@
-
. basicsmb.fns
-test_joindomain() {
- test_join_domain_password="$1"
-
- echo "$prefix/bin/net rpc join -S localhost -U $whoami%$test_join_domain_password"
- $prefix/bin/net rpc join -S localhost -U $whoami%$test_join_domain_password
- status=$?
- if [ $status = 0 ]; then
- echo "'net rpc join' correctly joined the domain"
- else
- echo "'net rpc join' failed to join the domain! (status $status)"
- return 1
- fi
- return 0
-}
-
password=samba
+security=DOMAIN
(test_smb_conf_setup && test_smbpasswd $password ) || exit 1
-test_joindomain $password || exit 1
-
-security=DOMAIN
test_listfilesauth $security || exit 1
test_listfilesnpw $security || exit 1
diff --git a/testsuite/build_farm/basicsmb-hostsdeny.test b/testsuite/build_farm/basicsmb-hostsdeny.test
deleted file mode 100644
index c7f6bec62f7..00000000000
--- a/testsuite/build_farm/basicsmb-hostsdeny.test
+++ /dev/null
@@ -1,18 +0,0 @@
-. basicsmb.fns
-
-password="samba"
-security="hostsdeny"
-(test_smb_conf_setup && test_smbpasswd $password) || exit 1
-
-(test_listfilesauth_should_deny $security) || exit 1
-
-
-
-
-
-
-
-
-
-
-
diff --git a/testsuite/build_farm/basicsmb-hostsequiv.test b/testsuite/build_farm/basicsmb-hostsequiv.test
deleted file mode 100644
index d424743d116..00000000000
--- a/testsuite/build_farm/basicsmb-hostsequiv.test
+++ /dev/null
@@ -1,26 +0,0 @@
-if [ $whoami = "root" ]; then
- exit 0;
-fi
-
-. basicsmb.fns
-
-test_listfilesrootnpw() {
- remote_name="$1"
- echo $prefix/bin/smbclient //$remote_name/samba -n buildclient -Uroot% -c 'ls'
- $prefix/bin/smbclient //$remote_name/samba -n buildclient -Uroot% -c 'ls'
- status=$?
- if [ $status = 0 ]; then
- echo "smbd listed files AS ROOT with NO PASSWORD (hosts equiv test)!"
- return 1
- else
- echo "listing files with smbd failed with status $status (correct)"
- fi
- return 0
-}
-
-password="not-a-valid-password"
-security="hostsequiv"
-(test_smb_conf_setup ) || exit 1
-
-(test_listfilesauth $security) || exit 1
-(test_listfilesrootnpw $security) || exit 1
diff --git a/testsuite/build_farm/basicsmb-invalidusers.test b/testsuite/build_farm/basicsmb-invalidusers.test
deleted file mode 100644
index 7d67cc2fc71..00000000000
--- a/testsuite/build_farm/basicsmb-invalidusers.test
+++ /dev/null
@@ -1,10 +0,0 @@
-. basicsmb.fns
-
-password="samba"
-security="invalidusers"
-(test_smb_conf_setup && test_smbpasswd $password) || exit 1
-
-(test_listfilesauth_should_deny $security) || exit 1
-
-security="validusers"
-(test_listfilesauth $security) || exit 1
diff --git a/testsuite/build_farm/basicsmb-local-pass-change.test b/testsuite/build_farm/basicsmb-local-pass-change.test
deleted file mode 100644
index 432376c6662..00000000000
--- a/testsuite/build_farm/basicsmb-local-pass-change.test
+++ /dev/null
@@ -1,10 +0,0 @@
-. basicsmb.fns
-
-passwordold=samba
-password=samba2
-security=USER
-(test_smb_conf_setup && test_smbpasswd $passwordold && test_smbpasswd_local $passwordold $password) || exit 1
-
-test_listfilesauth $security || exit 1
-test_listfilesnpw $security || exit 1
-
diff --git a/testsuite/build_farm/basicsmb-preexec.test b/testsuite/build_farm/basicsmb-preexec.test
deleted file mode 100644
index fc072e5fdb6..00000000000
--- a/testsuite/build_farm/basicsmb-preexec.test
+++ /dev/null
@@ -1,28 +0,0 @@
-. basicsmb.fns
-
-password=samba
-(test_smb_conf_setup && test_smbpasswd $password ) || exit 1
-
-rm -f $prefix/testdir/preexec_touch
-
-mode=PREEXEC
-(test_listfilesauth $mode) || exit 1
-
-if [ -f $prefix/testdir/preexec_touch ]; then
- rm -f $prefix/testdir/preexec_touch
-else
- exit 1;
-fi
-
-mode=PREEXEC_close
-(test_listfilesauth $mode) || exit 1
-
-if [ -f $prefix/testdir/preexec_touch ]; then
- rm -f $prefix/testdir/preexec_touch
-else
- exit 1;
-fi
-
-mode=PREEXEC_cl_fl
-(test_listfilesauth_should_deny $mode) || exit 1
-
diff --git a/testsuite/build_farm/basicsmb-remote-pass-change.test b/testsuite/build_farm/basicsmb-remote-pass-change.test
deleted file mode 100644
index adfe0dc3ebc..00000000000
--- a/testsuite/build_farm/basicsmb-remote-pass-change.test
+++ /dev/null
@@ -1,10 +0,0 @@
-. basicsmb.fns
-
-passwordold=samba
-password=samba2
-security=USER
-(test_smb_conf_setup && test_smbpasswd $passwordold && test_smbpasswd_remote $passwordold $password) || exit 1
-
-test_listfilesauth $security || exit 1
-test_listfilesnpw $security || exit 1
-
diff --git a/testsuite/build_farm/basicsmb-shareguest.test b/testsuite/build_farm/basicsmb-shareguest.test
index 4ba445a17e3..7b0175a6639 100644
--- a/testsuite/build_farm/basicsmb-shareguest.test
+++ b/testsuite/build_farm/basicsmb-shareguest.test
@@ -14,7 +14,8 @@ test_listfilesguestshare() {
return 0
}
+password=samba
security=SHARE
-( test_smb_conf_setup ) || exit 1
+( test_smb_conf_setup && ( test_smbpasswd $password ) ) || exit 1
( test_listfilesguestshare $security ) || exit 1 \ No newline at end of file
diff --git a/testsuite/build_farm/basicsmb-sharelist.test b/testsuite/build_farm/basicsmb-sharelist.test
index 188e985658d..87c3e475525 100644
--- a/testsuite/build_farm/basicsmb-sharelist.test
+++ b/testsuite/build_farm/basicsmb-sharelist.test
@@ -12,10 +12,7 @@ test_sharelist() {
return 0
}
-# Need guest account
-password=samba
-security=USER
-(test_smb_conf_setup && test_smbpasswd $password ) || exit 1
+(test_smb_conf_setup) || exit 1
test_sharelist || exit 1
diff --git a/testsuite/build_farm/basicsmb.fns b/testsuite/build_farm/basicsmb.fns
index 3a9080f473b..d9ac08639b5 100644
--- a/testsuite/build_farm/basicsmb.fns
+++ b/testsuite/build_farm/basicsmb.fns
@@ -1,135 +1,34 @@
-#! /bin/sh
-
-# Common functions for Samba build scripts.
-
-# Copyright (C) 2001 by Martin Pool <mbp@samba.org> and others
-
-# The following variables are passed in by the calling script. They
-# originate in either the buildfarm scripts or the configured
-# Makefile.
-
-# PREFIX = Installed prefix of samba test installation. Used to
-# locate binaries, configuration files, etc.
-
-# XXX: It's pretty bad to clobber the installed configuration file and
-# other data in $prefix, because somebody might unwittingly run this
-# with prefix=/usr.
-
-# Really what we want is a consistent way to pass the location of the
-# configuration and all other files into *all* Samba programs
-# (smbclient, smd, ...) and be able to set them to a temporary
-# directory when testing. Some of them take a -c parameter, but tpot
-# says it's not done consistently.
-
-template_setup() {
- cat template/$1 | \
+test_smb_conf_setup() {
+ cat basicsmb.smb.conf.template | \
sed "s|PREFIX|$prefix|g" | \
sed "s|BUILD_FARM|$test_root|g" | \
sed "s|WHOAMI|$whoami|g" | \
sed "s|LOGLEVEL|$loglevel|g" \
- > $prefix/$2
- echo "template_setup: Created $prefix/$2"
-}
-
-template_smb_conf_setup() {
- template_setup "basicsmb.smb.conf$1" "lib/smb.conf$1"
-}
-
-test_smb_conf_setup() {
- echo "test_smb_conf_setup: Configuring: "
- echo " PREFIX=$prefix"
- echo " BUILD_FARM=$test_root"
- echo " WHOAMI=$whoami"
- echo " LOGLEVEL=$loglevel"
- echo " TREE=$tree"
-
- case "$prefix" in
- /usr*|/|//)
- echo "** I don't want to clobber your installation in "
- echo "** $prefix"
- echo "** by running tests there. Please reconfigure this source tree to"
- echo "** use a different prefix."
- exit 1
- esac
-
-# Please keep these names under 15 characters,
-# so that the final name is 31 characters or fewer.
-
- template_smb_conf_setup
- template_smb_conf_setup .hostsequiv
- template_smb_conf_setup .validusers
- template_smb_conf_setup .invalidusers
- template_smb_conf_setup .preexec
- template_smb_conf_setup .preexec_close
- template_smb_conf_setup .preexec_cl_fl
-
- template_smb_conf_setup .share
- template_smb_conf_setup .user
- template_smb_conf_setup .server
- template_smb_conf_setup .domain
-
- template_setup preexec lib/preexec
+ > $prefix/lib/smb.conf
+ echo "127.0.0.1 localhost">$prefix/lib/lmhosts
+ echo "127.0.0.1 SHARE">>$prefix/lib/lmhosts
+ echo "127.0.0.1 USER">>$prefix/lib/lmhosts
+ echo "127.0.0.1 SERVER">>$prefix/lib/lmhosts
+ echo "127.0.0.1 DOMAIN">>$prefix/lib/lmhosts
+ cp basicsmb.smb.conf.share $prefix/lib/smb.conf.share
+ cp basicsmb.smb.conf.user $prefix/lib/smb.conf.user
+ cp basicsmb.smb.conf.server $prefix/lib/smb.conf.server
+ cp basicsmb.smb.conf.domain $prefix/lib/smb.conf.domain
touch $prefix/lib/smb.conf.
touch $prefix/lib/smb.conf.localhost
-
- echo "127.0.0.1 localhost">$prefix/lib/lmhosts
- echo "127.0.0.2 BUILDFARM">>$prefix/lib/lmhosts
- echo "127.0.0.3 SHARE">>$prefix/lib/lmhosts
- echo "127.0.0.4 USER">>$prefix/lib/lmhosts
- echo "127.0.0.5 SERVER">>$prefix/lib/lmhosts
- echo "127.0.0.6 DOMAIN">>$prefix/lib/lmhosts
- echo "127.0.0.7 HOSTSEQUIV">>$prefix/lib/lmhosts
- echo "127.0.0.7 VALIDUSERS">>$prefix/lib/lmhosts
- echo "127.0.0.7 INVALIDUSERS">>$prefix/lib/lmhosts
- echo "127.0.0.7 PREEXEC">>$prefix/lib/lmhosts
- echo "127.0.0.7 PREEXEC_CLOSE">>$prefix/lib/lmhosts
- echo "127.0.0.7 PREEXEC_CL_FL">>$prefix/lib/lmhosts
-
-
- echo "127.0.0.1" > $prefix/lib/hosts.equiv
-
}
test_smbpasswd() {
test_smbpasswd_password="$1"
rm -f $prefix/private/smbpasswd
- echo "( echo $test_smbpasswd_password ; echo $test_smbpasswd_password; ) | $prefix/bin/smbpasswd -L -D $loglevel -s -a $whoami"
- ( echo $test_smbpasswd_password; echo $test_smbpasswd_password; ) | $prefix/bin/smbpasswd -L -D $loglevel -s -a $whoami
+ echo "( echo $test_smbpasswd_password ; echo $test_smbpasswd_password; ) | $prefix/bin/smbpasswd -L -s -a $whoami"
+ ( echo $password ; echo $password; ) | $prefix/bin/smbpasswd -L -s -a $whoami
status=$?
if [ $status = 0 ]; then
- echo "smbpasswd correctly set initial password ($test_smbpasswd_password)"
+ echo "smbpasswd correctly set inital password ($test_smbpasswd_password)"
else
- echo "smbpasswd failed to set initial password ($test_smbpasswd_password)! (status $status)"
- return 1
- fi
- return 0
-}
-
-test_smbpasswd_remote() {
- test_smbpasswd_rem_password="$1"
- test_smbpasswd_rem_newpassword="$2"
- echo "( echo $test_smbpasswd_rem_password; echo $test_smbpasswd_rem_newpassword; echo $test_smbpasswd_rem_newpassword; ) | $prefix/bin/smbpasswd -r localhost -s -U $whoami"
- ( echo $test_smbpasswd_rem_password; echo $test_smbpasswd_rem_newpassword; echo $test_smbpasswd_rem_newpassword; ) | $prefix/bin/smbpasswd -r localhost -s -U $whoami
- status=$?
- if [ $status = 0 ]; then
- echo "smbpasswd correctly remotely changed password ($test_smbpasswd_rem_password -> $test_smbpasswd_rem_newpassword)"
- else
- echo "smbpasswd failed to remotely changed password ($test_smbpasswd_rem_password -> $test_smbpasswd_rem_newpassword)! (status $status)"
- return 1
- fi
- return 0
-}
-
-test_smbpasswd_local() {
- test_smbpasswd_newpassword="$2"
- echo "( echo $test_smbpasswd_newpassword ; echo $test_smbpasswd_newpassword; ) | $prefix/bin/smbpasswd -L -s $whoami"
- ( echo $test_smbpasswd_newpassword ; echo $test_smbpasswd_newpassword; ) | $prefix/bin/smbpasswd -L -s $whoami
- status=$?
- if [ $status = 0 ]; then
- echo "smbpasswd correctly locally changed password ($test_smbpasswd_password -> $test_smbpasswd_newpassword)"
- else
- echo "smbpasswd failed to locallly changed password ($test_smbpasswd_password -> $test_smbpasswd_newpassword)! (status $status)"
+ echo "smbpasswd failed to set inital password ($test_smbpasswd_password)! (status $status)"
return 1
fi
return 0
@@ -137,7 +36,7 @@ test_smbpasswd_local() {
test_listfilesauth() {
remote_name="$1"
- echo $prefix/bin/smbclient //$remote_name/samba -n buildclient -U$whoami%$password -c 'ls'
+ echo $prefix/bin/smbclient//$remote_name/samba -n buildclient -U$whoami%$password -c 'ls'
$prefix/bin/smbclient //$remote_name/samba -n buildclient -U$whoami%$password -c 'ls'
status=$?
if [ $status = 0 ]; then
@@ -163,42 +62,3 @@ test_listfilesnpw() {
return 0
}
-test_listfilesauth_should_deny() {
- remote_name="$1"
- echo $prefix/bin/smbclient //$remote_name/samba -n buildclient -U$whoami%$password -c 'ls'
- $prefix/bin/smbclient //$remote_name/samba -n buildclient -U$whoami%$password -c 'ls'
- status=$?
- if [ $status = 0 ]; then
- echo "smbd LISTED FILES despite smb.conf entires to the contary!"
- return 1
- else
- echo "listing files with smbd failed with status $status (correct)"
- fi
- return 0
-}
-
-echo "LIBSMB_PROG=$LIBSMB_PROG" >&2
-
-
-
-# Give sensible defaults to some variables.
-
-# "What's my age again?"
-
-if [ ! $USER = "" ]; then
- whoami=$USER
-else
- if [ ! $LOGNAME = "" ]; then
- whoami=$LOGNAME
- else
- whoami=build
- fi
-fi
-
-
-
-if test -z "$loglevel"
-then
- loglevel=1
-fi
-
diff --git a/testsuite/build_farm/basicsmb.smb.conf.domain b/testsuite/build_farm/basicsmb.smb.conf.domain
new file mode 100755
index 00000000000..ddb515362c1
--- /dev/null
+++ b/testsuite/build_farm/basicsmb.smb.conf.domain
@@ -0,0 +1,2 @@
+security=domain
+password server=127.0.0.1
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.server b/testsuite/build_farm/basicsmb.smb.conf.server
index 016f84cd353..976d662bac4 100644..100755
--- a/testsuite/build_farm/template/basicsmb.smb.conf.server
+++ b/testsuite/build_farm/basicsmb.smb.conf.server
@@ -1,3 +1,3 @@
security=server
password server=user
-smb passwd file=NON_EXISTANT_FILE
+smb password file=NON_EXISTANT_FILE
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.share b/testsuite/build_farm/basicsmb.smb.conf.share
index 8e69cc199a5..8e69cc199a5 100644..100755
--- a/testsuite/build_farm/template/basicsmb.smb.conf.share
+++ b/testsuite/build_farm/basicsmb.smb.conf.share
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf b/testsuite/build_farm/basicsmb.smb.conf.template
index 234419b6885..6785866fc10 100644..100755
--- a/testsuite/build_farm/template/basicsmb.smb.conf
+++ b/testsuite/build_farm/basicsmb.smb.conf.template
@@ -13,16 +13,6 @@
include = PREFIX/lib/smb.conf.%L
- add machine script = useradd %u -d /dev/null -s /bin/false
-
- panic action = /bin/sh BUILD_FARM/samba/testsuite/build_farm/backtrace %d
-
- passdb backend = smbpasswd
-
- idmap uid = 10000-200000
- map hidden = yes
- create mask = 0777
-
[test]
path = PREFIX/testdir
read only = no
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.user b/testsuite/build_farm/basicsmb.smb.conf.user
index 9d294b9c396..9d294b9c396 100644..100755
--- a/testsuite/build_farm/template/basicsmb.smb.conf.user
+++ b/testsuite/build_farm/basicsmb.smb.conf.user
diff --git a/testsuite/build_farm/runlist b/testsuite/build_farm/runlist
index 594c172b6ff..aac41215aa2 100644
--- a/testsuite/build_farm/runlist
+++ b/testsuite/build_farm/runlist
@@ -1,18 +1,3 @@
-TEST_ALL="basicsmb-sharelist basicsmb-local-pass-change \
-basicsmb-sharesec basicsmb-usersec \
-basicsmb-serversec \
-basicsmb-shareguest basicsmb-hostsequiv basicsmb-invalidusers \
-basicsmb-hostsdeny basicsmb-remote-pass-change \
-basicsmb-preexec \
-torture-FDPASS torture-LOCK1 torture-LOCK2 \
-torture-LOCK3 torture-LOCK4 torture-LOCK5 \
-torture-LOCK6 torture-LOCK7 \
-torture-UNLINK torture-BROWSE torture-ATTR \
-torture-TRANS2 torture-TORTURE torture-OPLOCK1 \
-torture-OPLOCK3 torture-DIR torture-DIR1 torture-DENY1 \
-torture-DENY2 torture-TCON torture-TCON2 torture-TCONDEV \
-torture-RW1 torture-RW2 torture-OPEN torture-XCOPY \
-torture-RENAME torture-DELETE torture-PROPERTIES \
-torture-MANGLE torture-FDSESS"
+TEST_ALL="basicsmb-sharelist basicsmb-sharesec basicsmb-usersec basicsmb-shareguest torture-FDPASS torture-LOCK1 torture-LOCK2 torture-LOCK3 torture-LOCK4 torture-LOCK5 torture-UNLINK torture-BROWSE torture-ATTR torture-TRANS2 torture-TORTURE torture-OPLOCK1 torture-OPLOCK3 torture-DIR torture-DENY1 torture-DENY2 torture-TCON torture-RW1 torture-RW2 torture-OPEN torture-DELETE"
-#basicsmb-domainsec basicsmb-domainsec-nt4 \ No newline at end of file
+#basicsmb-serversec
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.domain b/testsuite/build_farm/template/basicsmb.smb.conf.domain
deleted file mode 100644
index 8b9728838e1..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.domain
+++ /dev/null
@@ -1,2 +0,0 @@
-security=domain
-password server=user
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.hostsdeny b/testsuite/build_farm/template/basicsmb.smb.conf.hostsdeny
deleted file mode 100644
index 3fce0bdbf4e..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.hostsdeny
+++ /dev/null
@@ -1 +0,0 @@
- hosts deny = 127. \ No newline at end of file
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.hostsequiv b/testsuite/build_farm/template/basicsmb.smb.conf.hostsequiv
deleted file mode 100644
index 750af74f59c..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.hostsequiv
+++ /dev/null
@@ -1,3 +0,0 @@
- hostname lookups = no
- hosts equiv=PREFIX/lib/hosts.equiv
- auth methods = hostsequiv
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.invalidusers b/testsuite/build_farm/template/basicsmb.smb.conf.invalidusers
deleted file mode 100644
index a96a316db9f..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.invalidusers
+++ /dev/null
@@ -1 +0,0 @@
- invalid users = WHOAMI
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.preexec b/testsuite/build_farm/template/basicsmb.smb.conf.preexec
deleted file mode 100644
index cc34872c5df..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.preexec
+++ /dev/null
@@ -1 +0,0 @@
-preexec = /bin/sh PREFIX/lib/preexec
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.preexec_cl_fl b/testsuite/build_farm/template/basicsmb.smb.conf.preexec_cl_fl
deleted file mode 100644
index 4a6fae57bc0..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.preexec_cl_fl
+++ /dev/null
@@ -1,2 +0,0 @@
-preexec close = yes
-preexec = PREFIX/lib/preexec_does_not_exist
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.preexec_close b/testsuite/build_farm/template/basicsmb.smb.conf.preexec_close
deleted file mode 100644
index 3aac6998bfc..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.preexec_close
+++ /dev/null
@@ -1,2 +0,0 @@
-preexec close = yes
-preexec = /bin/sh PREFIX/lib/preexec
diff --git a/testsuite/build_farm/template/basicsmb.smb.conf.validusers b/testsuite/build_farm/template/basicsmb.smb.conf.validusers
deleted file mode 100644
index d4a85e0a028..00000000000
--- a/testsuite/build_farm/template/basicsmb.smb.conf.validusers
+++ /dev/null
@@ -1 +0,0 @@
- valid users = WHOAMI
diff --git a/testsuite/build_farm/template/preexec b/testsuite/build_farm/template/preexec
deleted file mode 100644
index 23809aaf893..00000000000
--- a/testsuite/build_farm/template/preexec
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-echo "Test worked" > PREFIX/testdir/preexec_touch
diff --git a/testsuite/build_farm/torture-DIR1.test b/testsuite/build_farm/torture-DIR1.test
deleted file mode 100644
index 6cc075e9ba9..00000000000
--- a/testsuite/build_farm/torture-DIR1.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "DIR1"
diff --git a/testsuite/build_farm/torture-FDPASS.test b/testsuite/build_farm/torture-FDPASS.test
index 40ffdb666d7..e8af277d430 100644
--- a/testsuite/build_farm/torture-FDPASS.test
+++ b/testsuite/build_farm/torture-FDPASS.test
@@ -1,2 +1,2 @@
. torture_setup.fns
-test_torture "FDSESS"
+test_torture "FDPASS"
diff --git a/testsuite/build_farm/torture-FDSESS.test b/testsuite/build_farm/torture-FDSESS.test
deleted file mode 100644
index e8af277d430..00000000000
--- a/testsuite/build_farm/torture-FDSESS.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "FDPASS"
diff --git a/testsuite/build_farm/torture-LOCK6.test b/testsuite/build_farm/torture-LOCK6.test
deleted file mode 100644
index 78e139e3103..00000000000
--- a/testsuite/build_farm/torture-LOCK6.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "LOCK6"
diff --git a/testsuite/build_farm/torture-LOCK7.test b/testsuite/build_farm/torture-LOCK7.test
deleted file mode 100644
index fc967fca57d..00000000000
--- a/testsuite/build_farm/torture-LOCK7.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "LOCK7"
diff --git a/testsuite/build_farm/torture-MANGLE.test b/testsuite/build_farm/torture-MANGLE.test
deleted file mode 100644
index 5a3d478a456..00000000000
--- a/testsuite/build_farm/torture-MANGLE.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "MANGLE"
diff --git a/testsuite/build_farm/torture-PROPERTIES.test b/testsuite/build_farm/torture-PROPERTIES.test
deleted file mode 100644
index 91fde27f8af..00000000000
--- a/testsuite/build_farm/torture-PROPERTIES.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "PROPERTIES"
diff --git a/testsuite/build_farm/torture-RENAME.test b/testsuite/build_farm/torture-RENAME.test
deleted file mode 100644
index 58cb8eb466f..00000000000
--- a/testsuite/build_farm/torture-RENAME.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "RENAME"
diff --git a/testsuite/build_farm/torture-RW2.test b/testsuite/build_farm/torture-RW2.test
index dc457decab1..a647d9de2e9 100644
--- a/testsuite/build_farm/torture-RW2.test
+++ b/testsuite/build_farm/torture-RW2.test
@@ -1,2 +1,2 @@
. torture_setup.fns
-test_torture "RW2"
+test_torture "RW22"
diff --git a/testsuite/build_farm/torture-TCON1.test b/testsuite/build_farm/torture-TCON1.test
deleted file mode 100644
index 3c9267640de..00000000000
--- a/testsuite/build_farm/torture-TCON1.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "TCON1"
diff --git a/testsuite/build_farm/torture-TCON2.test b/testsuite/build_farm/torture-TCON2.test
deleted file mode 100644
index 1f30a975daa..00000000000
--- a/testsuite/build_farm/torture-TCON2.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "TCON2"
diff --git a/testsuite/build_farm/torture-TCONDEV.test b/testsuite/build_farm/torture-TCONDEV.test
deleted file mode 100644
index 18bd5345fb7..00000000000
--- a/testsuite/build_farm/torture-TCONDEV.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "TCONDEV"
diff --git a/testsuite/build_farm/torture-XCOPY.test b/testsuite/build_farm/torture-XCOPY.test
deleted file mode 100644
index 94cc7979769..00000000000
--- a/testsuite/build_farm/torture-XCOPY.test
+++ /dev/null
@@ -1,2 +0,0 @@
-. torture_setup.fns
-test_torture "XCOPY"
diff --git a/testsuite/build_farm/torture_setup.fns b/testsuite/build_farm/torture_setup.fns
index a42be94129b..bf5146148ea 100644
--- a/testsuite/build_farm/torture_setup.fns
+++ b/testsuite/build_farm/torture_setup.fns
@@ -12,7 +12,7 @@ test_torture() {
if [ $status = 0 ]; then
echo "smbtorture test $torture_test worked"
else
- echo "smbtorture test $torture_test FAILED (status $status)!"
+ echo "smbtorture test $torture_test FAILED!"
return 1
fi
return 0
diff --git a/testsuite/config/default-nt-names.exp b/testsuite/config/default-nt-names.exp
new file mode 100755
index 00000000000..4a868e71bcb
--- /dev/null
+++ b/testsuite/config/default-nt-names.exp
@@ -0,0 +1,17 @@
+#
+# A list of default domain/local users/groups
+#
+
+# Domain users and groups
+
+set domain_users [list "$domain/Administrator" "$domain/Guest"]
+
+set domain_groups [list "$domain/Domain Admins" "$domain/Domain Guests" \
+ "$domain/Domain Users"]
+
+# Local groups
+
+set local_groups [list "BUILTIN/Replicator" "BUILTIN/Server Operators" \
+ "BUILTIN/Account Operators" "BUILTIN/Backup Operators" \
+ "BUILTIN/Print Operators" "BUILTIN/Guests" "BUILTIN/Users" \
+ "BUILTIN/Administrators"]
diff --git a/testsuite/config/env.exp b/testsuite/config/env.exp
new file mode 100755
index 00000000000..503d058c3f3
--- /dev/null
+++ b/testsuite/config/env.exp
@@ -0,0 +1,26 @@
+#
+# Load environment variables
+#
+
+# Domain set through environment variable
+
+catch {set domain "$env(TEST_WORKGROUP)"} tmp
+
+if {[regexp "^can't read" $tmp]} {
+ error "Environment variable \$TEST_WORKGROUP not set"
+}
+
+# NT user and server
+
+catch {set ntserver "$env(TEST_NTSERVER)"} tmp
+
+if {[regexp "^can't read" $tmp]} {
+ error "Environment variable \$TEST_NTSERVER not set"
+}
+
+catch {set ntuser "$env(TEST_NTUSER)"} tmp
+
+if {[regexp "^can't read" $tmp]} {
+ error "Environment variable \$TEST_NTUSER not set"
+}
+
diff --git a/testsuite/lib/smbclient.exp b/testsuite/lib/smbclient.exp
index dc55d72139c..3fd920e07f5 100644
--- a/testsuite/lib/smbclient.exp
+++ b/testsuite/lib/smbclient.exp
@@ -46,7 +46,7 @@ proc do_smbclient { args } {
expect {
$smb_prompt {}
timeout { perror "timed out $description"; return -1}
- eof { perror "end of file $description"; return -1 }
+ eof { perror "end of file description"; return -1 }
}
verbose $expect_out(buffer)
diff --git a/testsuite/libsmbclient/src/Makefile b/testsuite/libsmbclient/src/Makefile
deleted file mode 100644
index a59f1342801..00000000000
--- a/testsuite/libsmbclient/src/Makefile
+++ /dev/null
@@ -1,817 +0,0 @@
-CC = gcc
-CFLAGS = -Wall -W -O2 -g
-LFLAGS = -L/root/samba-head-old/source/bin
-
-LIBS= -L/usr/lib -lsmbclient
-INCPATH= -I. -I/usr/include -I./include
-BIN_DIR=bin
-
-SUB_DIRS=init fstat open unlink chown close opendir closedir rename lseek lseekdir stat \
- getdents creat read readdir mkdir rmdir write chmod open_print_job list_print_jobs \
- print_file telldir unlink_print_job
-
-
-G_INIT = $(BIN_DIR)/init_1 \
- $(BIN_DIR)/init_2 \
- $(BIN_DIR)/init_3 \
- $(BIN_DIR)/init_4
-
-G_FSTAT = $(BIN_DIR)/fstat_1 \
- $(BIN_DIR)/fstat_2 \
- $(BIN_DIR)/fstat_3 \
- $(BIN_DIR)/fstat_4 \
- $(BIN_DIR)/fstat_5 \
- $(BIN_DIR)/fstat_6
-
-G_OPEN = $(BIN_DIR)/open_1 \
- $(BIN_DIR)/open_2 \
- $(BIN_DIR)/open_3 \
- $(BIN_DIR)/open_4 \
- $(BIN_DIR)/open_5
-
-G_UNLINK = $(BIN_DIR)/unlink_1 \
- $(BIN_DIR)/unlink_2 \
- $(BIN_DIR)/unlink_3 \
- $(BIN_DIR)/unlink_4 \
- $(BIN_DIR)/unlink_5 \
- $(BIN_DIR)/unlink_6 \
- $(BIN_DIR)/unlink_7 \
- $(BIN_DIR)/unlink_8 \
- $(BIN_DIR)/unlink_9 \
- $(BIN_DIR)/unlink_10 \
- $(BIN_DIR)/unlink_11 \
- $(BIN_DIR)/unlink_12
-
-
-G_CLOSE = $(BIN_DIR)/close_1 \
- $(BIN_DIR)/close_2
-
-G_OPENDIR = $(BIN_DIR)/opendir_1 \
- $(BIN_DIR)/opendir_2 \
- $(BIN_DIR)/opendir_3 \
- $(BIN_DIR)/opendir_4
-
-G_CLOSEDIR = $(BIN_DIR)/closedir_1 \
- $(BIN_DIR)/closedir_2 \
- $(BIN_DIR)/closedir_3 \
- $(BIN_DIR)/closedir_4
-
-G_RENAME = $(BIN_DIR)/rename_1 \
- $(BIN_DIR)/rename_2 \
- $(BIN_DIR)/rename_3 \
- $(BIN_DIR)/rename_4 \
- $(BIN_DIR)/rename_5 \
- $(BIN_DIR)/rename_6 \
- $(BIN_DIR)/rename_7 \
- $(BIN_DIR)/rename_8 \
- $(BIN_DIR)/rename_9 \
- $(BIN_DIR)/rename_10 \
- $(BIN_DIR)/rename_11 \
- $(BIN_DIR)/rename_12 \
- $(BIN_DIR)/rename_13 \
- $(BIN_DIR)/rename_14
-
-G_LSEEK = $(BIN_DIR)/lseek_1 \
- $(BIN_DIR)/lseek_2 \
- $(BIN_DIR)/lseek_3 \
- $(BIN_DIR)/lseek_4 \
- $(BIN_DIR)/lseek_5 \
- $(BIN_DIR)/lseek_6 \
- $(BIN_DIR)/lseek_7 \
- $(BIN_DIR)/lseek_8
-
-G_LSEEKDIR = $(BIN_DIR)/lseekdir_1 \
- $(BIN_DIR)/lseekdir_2 \
- $(BIN_DIR)/lseekdir_3 \
- $(BIN_DIR)/lseekdir_4 \
- $(BIN_DIR)/lseekdir_5 \
- $(BIN_DIR)/lseekdir_6
-
-G_STAT = $(BIN_DIR)/stat_1 \
- $(BIN_DIR)/stat_2 \
- $(BIN_DIR)/stat_3 \
- $(BIN_DIR)/stat_4 \
- $(BIN_DIR)/stat_5 \
- $(BIN_DIR)/stat_6
-
-G_GETDENTS = $(BIN_DIR)/getdents_1 \
- $(BIN_DIR)/getdents_2 \
- $(BIN_DIR)/getdents_3 \
- $(BIN_DIR)/getdents_4 \
- $(BIN_DIR)/getdents_5
-
-G_CREAT = $(BIN_DIR)/creat_1 \
- $(BIN_DIR)/creat_2 \
- $(BIN_DIR)/creat_3
-
-G_READ = $(BIN_DIR)/read_1 \
- $(BIN_DIR)/read_2 \
- $(BIN_DIR)/read_3 \
- $(BIN_DIR)/read_4 \
- $(BIN_DIR)/read_5 \
- $(BIN_DIR)/read_6 \
- $(BIN_DIR)/read_7 \
- $(BIN_DIR)/read_8 \
- $(BIN_DIR)/read_9 \
- $(BIN_DIR)/read_10 \
- $(BIN_DIR)/read_11 \
- $(BIN_DIR)/read_12 \
- $(BIN_DIR)/read_13
-
-G_MKDIR = $(BIN_DIR)/mkdir_1 \
- $(BIN_DIR)/mkdir_2 \
- $(BIN_DIR)/mkdir_3 \
- $(BIN_DIR)/mkdir_4
-
-G_RMDIR = $(BIN_DIR)/rmdir_1 \
- $(BIN_DIR)/rmdir_2 \
- $(BIN_DIR)/rmdir_3 \
- $(BIN_DIR)/rmdir_4 \
- $(BIN_DIR)/rmdir_5 \
- $(BIN_DIR)/rmdir_6
-
-G_READDIR = $(BIN_DIR)/readdir_1 \
- $(BIN_DIR)/readdir_2 \
- $(BIN_DIR)/readdir_3 \
- $(BIN_DIR)/readdir_4 \
- $(BIN_DIR)/readdir_5
-
-G_WRITE = $(BIN_DIR)/write_1 \
- $(BIN_DIR)/write_2 \
- $(BIN_DIR)/write_3 \
- $(BIN_DIR)/write_4 \
- $(BIN_DIR)/write_5 \
- $(BIN_DIR)/write_6 \
- $(BIN_DIR)/write_7 \
- $(BIN_DIR)/write_8 \
- $(BIN_DIR)/write_9 \
- $(BIN_DIR)/write_10 \
- $(BIN_DIR)/write_11 \
- $(BIN_DIR)/write_12 \
- $(BIN_DIR)/write_13
-
-G_TELLDIR = $(BIN_DIR)/telldir_1 \
- $(BIN_DIR)/telldir_2 \
- $(BIN_DIR)/telldir_3 \
- $(BIN_DIR)/telldir_4 \
- $(BIN_DIR)/telldir_5
-
-G_CHMOD = $(BIN_DIR)/chmod_1
-
-G_CHOWN = $(BIN_DIR)/chown_1
-
-G_PRINT_FILE = $(BIN_DIR)/print_file_1 \
- $(BIN_DIR)/print_file_2 \
- $(BIN_DIR)/print_file_3 \
- $(BIN_DIR)/print_file_4
-
-G_OPEN_PRINT_JOB = $(BIN_DIR)/open_print_job_1 \
- $(BIN_DIR)/open_print_job_2
-
-G_LIST_PRINT_JOBS = $(BIN_DIR)/list_print_jobs_1 \
- $(BIN_DIR)/list_print_jobs_2 \
- $(BIN_DIR)/list_print_jobs_3 \
- $(BIN_DIR)/list_print_jobs_4 \
- $(BIN_DIR)/list_print_jobs_5 \
- $(BIN_DIR)/list_print_jobs_6 \
- $(BIN_DIR)/list_print_jobs_7
-
-G_UNLINK_PRINT_JOB = $(BIN_DIR)/unlink_print_job_1 \
- $(BIN_DIR)/unlink_print_job_2 \
- $(BIN_DIR)/unlink_print_job_3 \
- $(BIN_DIR)/unlink_print_job_4 \
- $(BIN_DIR)/unlink_print_job_5
-
-GROUPS= $(G_CHMOD) $(G_CHOWN) $(G_CLOSE) $(G_CLOSEDIR) $(G_CREAT) $(G_FSTAT)\
- $(G_GETDENTS) $(G_INIT) $(G_LIST_PRINT_JOBS) $(G_LSEEK) $(G_LSEEKDIR) \
- $(G_MKDIR) $(G_OPEN) $(G_OPENDIR) $(G_OPEN_PRINT_JOB) $(G_PRINT_FILE)\
- $(G_READ) $(G_READDIR) $(G_RENAME) $(G_RMDIR) $(G_STAT) $(G_TELLDIR) $(G_UNLINK) \
- $(G_UNLINK_PRINT_JOB) $(G_WRITE)
-
-.c.o:
- @echo Compiling $*.c
- @$(CC) -c $(CFLAGS) -o $@ $(INCPATH) $<
-
-
-all: $(GROUPS)
-
-init: $(G_INIT)
-fstat: $(G_FSTAT)
-open: $(G_OPEN)
-unlink: $(G_UNLINK)
-chown: $(G_CHOWN)
-close: $(G_CLOSE)
-opendir: $(G_OPENDIR)
-closedir: $(G_CLOSEDIR)
-rename: $(G_RENAME)
-readdir: $(G_READDIR)
-lseek: $(G_LSEEK)
-lseekdir: $(G_LSEEKDIR)
-stat: $(G_STAT)
-getdents: $(G_GETDENTS)
-creat: $(G_CREAT)
-read: $(G_READ)
-mkdir: $(G_MKDIR)
-rmdir: $(G_RMDIR)
-write: $(G_WRITE)
-chmod: $(G_CHMOD)
-telldir: $(G_TELLDIR)
-print_file: $(G_PRINT_FILE)
-open_print_job: $(G_OPEN_PRINT_JOB)
-list_print_jobs: $(G_LIST_PRINT_JOBS)
-unlink_print_job: $(G_UNLINK_PRINT_JOB)
-
-
-$(BIN_DIR)/testsmbc: testsmbc.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ testsmbc.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/init_1: init/init_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ init/init_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/init_2: init/init_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ init/init_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/init_3: init/init_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ init/init_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/init_4: init/init_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ init/init_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_1: fstat/fstat_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_2: fstat/fstat_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_3: fstat/fstat_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_4: fstat/fstat_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_5: fstat/fstat_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/fstat_6: fstat/fstat_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ fstat/fstat_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_1: open/open_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open/open_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_2: open/open_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open/open_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_3: open/open_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open/open_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_4: open/open_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open/open_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_5: open/open_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open/open_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_1: unlink/unlink_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_2: unlink/unlink_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_3: unlink/unlink_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_4: unlink/unlink_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_5: unlink/unlink_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_6: unlink/unlink_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_7: unlink/unlink_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_8: unlink/unlink_8.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_8.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_9: unlink/unlink_9.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_9.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_10: unlink/unlink_10.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_10.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_11: unlink/unlink_11.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_11.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_12: unlink/unlink_12.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink/unlink_12.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/chown_1: chown/chown_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ chown/chown_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/close_1: close/close_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ close/close_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/close_2: close/close_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ close/close_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/opendir_1: opendir/opendir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ opendir/opendir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/opendir_2: opendir/opendir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ opendir/opendir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/opendir_3: opendir/opendir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ opendir/opendir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/opendir_4: opendir/opendir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ opendir/opendir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/closedir_1: closedir/closedir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ closedir/closedir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/closedir_2: closedir/closedir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ closedir/closedir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/closedir_3: closedir/closedir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ closedir/closedir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/closedir_4: closedir/closedir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ closedir/closedir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_1: rename/rename_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_2: rename/rename_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_3: rename/rename_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_4: rename/rename_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_5: rename/rename_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_6: rename/rename_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_7: rename/rename_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_8: rename/rename_8.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_8.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_9: rename/rename_9.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_9.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_10: rename/rename_10.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_10.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_11: rename/rename_11.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_11.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_12: rename/rename_12.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_12.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_13: rename/rename_13.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_13.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rename_14: rename/rename_14.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rename/rename_14.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_1: lseek/lseek_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_2: lseek/lseek_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_3: lseek/lseek_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_4: lseek/lseek_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_5: lseek/lseek_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_6: lseek/lseek_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_7: lseek/lseek_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseek_8: lseek/lseek_8.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseek/lseek_8.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_1: lseekdir/lseekdir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_2: lseekdir/lseekdir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_3: lseekdir/lseekdir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_4: lseekdir/lseekdir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_5: lseekdir/lseekdir_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/lseekdir_6: lseekdir/lseekdir_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ lseekdir/lseekdir_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_1: stat/stat_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_2: stat/stat_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_3: stat/stat_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_4: stat/stat_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_5: stat/stat_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/stat_6: stat/stat_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ stat/stat_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/getdents_1: getdents/getdents_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ getdents/getdents_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/getdents_2: getdents/getdents_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ getdents/getdents_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/getdents_3: getdents/getdents_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ getdents/getdents_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/getdents_4: getdents/getdents_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ getdents/getdents_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/getdents_5: getdents/getdents_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ getdents/getdents_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/creat_1: creat/creat_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ creat/creat_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/creat_2: creat/creat_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ creat/creat_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/creat_3: creat/creat_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ creat/creat_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/mkdir_1: mkdir/mkdir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ mkdir/mkdir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/mkdir_2: mkdir/mkdir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ mkdir/mkdir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/mkdir_3: mkdir/mkdir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ mkdir/mkdir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/mkdir_4: mkdir/mkdir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ mkdir/mkdir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/readdir_1: readdir/readdir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ readdir/readdir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/readdir_2: readdir/readdir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ readdir/readdir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/readdir_3: readdir/readdir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ readdir/readdir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/readdir_4: readdir/readdir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ readdir/readdir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/readdir_5: readdir/readdir_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ readdir/readdir_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_1: rmdir/rmdir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_2: rmdir/rmdir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_3: rmdir/rmdir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_4: rmdir/rmdir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_5: rmdir/rmdir_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/rmdir_6: rmdir/rmdir_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ rmdir/rmdir_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_1: write/write_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_2: write/write_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_3: write/write_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_4: write/write_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_5: write/write_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_6: write/write_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_7: write/write_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_8: write/write_8.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_8.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_9: write/write_9.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_9.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_10: write/write_10.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_10.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_11: write/write_11.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_11.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_12: write/write_12.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_12.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/write_13: write/write_13.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ write/write_13.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_1: read/read_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_2: read/read_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_3: read/read_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_4: read/read_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_5: read/read_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_6: read/read_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_7: read/read_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_8: read/read_8.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_8.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_9: read/read_9.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_9.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_10: read/read_10.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_10.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_11: read/read_11.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_11.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_12: read/read_12.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_12.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/read_13: read/read_13.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ read/read_13.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/chmod_1: chmod/chmod_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ chmod/chmod_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/telldir_1: telldir/telldir_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ telldir/telldir_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/telldir_2: telldir/telldir_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ telldir/telldir_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/telldir_3: telldir/telldir_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ telldir/telldir_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/telldir_4: telldir/telldir_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ telldir/telldir_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/telldir_5: telldir/telldir_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ telldir/telldir_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/print_file_1: print_file/print_file_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ print_file/print_file_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/print_file_2: print_file/print_file_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ print_file/print_file_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/print_file_3: print_file/print_file_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ print_file/print_file_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/print_file_4: print_file/print_file_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ print_file/print_file_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_print_job_1: open_print_job/open_print_job_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open_print_job/open_print_job_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/open_print_job_2: open_print_job/open_print_job_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ open_print_job/open_print_job_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_1: list_print_jobs/list_print_jobs_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_2: list_print_jobs/list_print_jobs_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_3: list_print_jobs/list_print_jobs_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_4: list_print_jobs/list_print_jobs_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_5: list_print_jobs/list_print_jobs_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_5.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_6: list_print_jobs/list_print_jobs_6.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_6.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/list_print_jobs_7: list_print_jobs/list_print_jobs_7.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ list_print_jobs/list_print_jobs_7.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_print_job_1: unlink_print_job/unlink_print_job_1.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink_print_job/unlink_print_job_1.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_print_job_2: unlink_print_job/unlink_print_job_2.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink_print_job/unlink_print_job_2.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_print_job_3: unlink_print_job/unlink_print_job_3.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink_print_job/unlink_print_job_3.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_print_job_4: unlink_print_job/unlink_print_job_4.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink_print_job/unlink_print_job_4.o $(INCPATH) $(LIBS)
-
-$(BIN_DIR)/unlink_print_job_5: unlink_print_job/unlink_print_job_5.o
- @echo Linking $@
- @$(CC) $(LFLAGS) -o $@ unlink_print_job/unlink_print_job_5.o $(INCPATH) $(LIBS)
-
-
-clean:
- @for i in $(SUB_DIRS); do \
- rm -f $$i/*.o; \
- done
-
- @rm -f $(GROUPS)
- @echo "Done"
-
diff --git a/testsuite/libsmbclient/src/chmod/chmod_1.c b/testsuite/libsmbclient/src/chmod/chmod_1.c
deleted file mode 100644
index 47c86b1f809..00000000000
--- a/testsuite/libsmbclient/src/chmod/chmod_1.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- fd = smbc_init(auth_fn, 0);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/chown/chown_1.c b/testsuite/libsmbclient/src/chown/chown_1.c
deleted file mode 100644
index 47c86b1f809..00000000000
--- a/testsuite/libsmbclient/src/chown/chown_1.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- fd = smbc_init(auth_fn, 0);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/close/close_1.c b/testsuite/libsmbclient/src/close/close_1.c
deleted file mode 100644
index 983e627d897..00000000000
--- a/testsuite/libsmbclient/src/close/close_1.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- err = smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/close/close_2.c b/testsuite/libsmbclient/src/close/close_2.c
deleted file mode 100644
index b0319e41d9d..00000000000
--- a/testsuite/libsmbclient/src/close/close_2.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/closedir/closedir_1.c b/testsuite/libsmbclient/src/closedir/closedir_1.c
deleted file mode 100644
index 702b92c24ab..00000000000
--- a/testsuite/libsmbclient/src/closedir/closedir_1.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_closedir(dh);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/closedir/closedir_2.c b/testsuite/libsmbclient/src/closedir/closedir_2.c
deleted file mode 100644
index 88b6e2ce7e8..00000000000
--- a/testsuite/libsmbclient/src/closedir/closedir_2.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- smbc_closedir(dh);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/closedir/closedir_3.c b/testsuite/libsmbclient/src/closedir/closedir_3.c
deleted file mode 100644
index 4fdc9c849c5..00000000000
--- a/testsuite/libsmbclient/src/closedir/closedir_3.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_closedir(dh);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/closedir/closedir_4.c b/testsuite/libsmbclient/src/closedir/closedir_4.c
deleted file mode 100644
index ee1d72bae39..00000000000
--- a/testsuite/libsmbclient/src/closedir/closedir_4.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- smbc_closedir(dh);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/creat/creat_1.c b/testsuite/libsmbclient/src/creat/creat_1.c
deleted file mode 100644
index 9ccab002c13..00000000000
--- a/testsuite/libsmbclient/src/creat/creat_1.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_creat(url, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/creat/creat_2.c b/testsuite/libsmbclient/src/creat/creat_2.c
deleted file mode 100644
index 599a1845d34..00000000000
--- a/testsuite/libsmbclient/src/creat/creat_2.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
- fd = 0;
- fd = smbc_creat(url, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/creat/creat_3.c b/testsuite/libsmbclient/src/creat/creat_3.c
deleted file mode 100644
index ae27a2a1c90..00000000000
--- a/testsuite/libsmbclient/src/creat/creat_3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_creat(url, 0666);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_1.c b/testsuite/libsmbclient/src/fstat/fstat_1.c
deleted file mode 100644
index fd63400869d..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_1.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- smbc_init(auth_fn, 0);
-
- fd = 11234;
- err = smbc_fstat(fd,&st);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_2.c b/testsuite/libsmbclient/src/fstat/fstat_2.c
deleted file mode 100644
index ea2e7e3145f..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_2.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- smbc_init(auth_fn, 0);
-
- fd = 11234;
- smbc_fstat(fd,&st);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_3.c b/testsuite/libsmbclient/src/fstat/fstat_3.c
deleted file mode 100644
index 57bb3b7557d..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_3.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
-
- err = smbc_fstat(fd, &st);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_4.c b/testsuite/libsmbclient/src/fstat/fstat_4.c
deleted file mode 100644
index 57bb3b7557d..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_4.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
-
- err = smbc_fstat(fd, &st);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_5.c b/testsuite/libsmbclient/src/fstat/fstat_5.c
deleted file mode 100644
index 9ebdd602646..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_5.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
-
- smbc_fstat(fd,&st);
-
- smbc_close(fd);
- free(message);
-
- if ( st.st_size != msg_len )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/fstat/fstat_6.c b/testsuite/libsmbclient/src/fstat/fstat_6.c
deleted file mode 100644
index 8a38e5be346..00000000000
--- a/testsuite/libsmbclient/src/fstat/fstat_6.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- unsigned int mode_mask = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
-
- smbc_fstat(fd,&st);
-
- smbc_close(fd);
- free(message);
-
- mode_mask = mode_mask | S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* 0666 or 33206 */
-
- if ( st.st_mode != mode_mask )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/getdents/getdents_1.c b/testsuite/libsmbclient/src/getdents/getdents_1.c
deleted file mode 100644
index 6e253f78c5c..00000000000
--- a/testsuite/libsmbclient/src/getdents/getdents_1.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- /* int dirsize = 0; */
- /* int dircount = 0; */
-
- struct smbc_dirent *dirptr;
-
- char url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- err = smbc_getdents( dh, dirptr, sizeof(dirbuff));
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/getdents/getdents_2.c b/testsuite/libsmbclient/src/getdents/getdents_2.c
deleted file mode 100644
index e7eb959a8f5..00000000000
--- a/testsuite/libsmbclient/src/getdents/getdents_2.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- /* int dirsize = 0; */
- /* int dircount = 0; */
-
- struct smbc_dirent *dirptr;
-
- char url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- err = smbc_getdents( dh, dirptr, sizeof(dirbuff));
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/getdents/getdents_3.c b/testsuite/libsmbclient/src/getdents/getdents_3.c
deleted file mode 100644
index 58c8f709a96..00000000000
--- a/testsuite/libsmbclient/src/getdents/getdents_3.c
+++ /dev/null
@@ -1,155 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- int j = 0;
- char *file_name;
- char *tmp_file_ptr;
- int direntsize = 0;
- int diramount = 0;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- diramount = smbc_getdents( dh, dirptr, sizeof(dirbuff));
-
- err = 0;
- i = 0;
- bzero(buff,MAX_BUFF_SIZE);
- bzero(tmp_file_ptr,MAX_BUFF_SIZE-9);
-
- while ( diramount > 0 )
- {
- direntsize = dirptr->dirlen;
- /* printf("Name: %s\n",dirptr->name); */
- if ( j == 0 )
- {
- if ( !(( strncmp(dirptr->name,".",1) == 0 )) )
- {
- break;
- err = 1;
- }
-
- } else if ( j == 1 ) {
-
- if ( !(( strncmp(dirptr->name,"..",2) == 0 )) )
- {
- break;
- err = 1;
- }
-
- } else if ( j > 1 ) {
-
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
-
- if ( !((strcmp(dirptr->name,file_url) == 0 )) ) /* make sure entries match */
- {
- err = 1;
- break;
- }
-
- i++;
-
- }
-
- (char *)dirptr += direntsize;
- (char *)diramount -= direntsize;
- j++;
-
- }
-
- if ( ! err )
- {
- if ( (j - 2) != entry_num ) /* Make sure that all entries created are counted and returned - minus . and .. */
- err = 1;
- }
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/getdents/getdents_4.c b/testsuite/libsmbclient/src/getdents/getdents_4.c
deleted file mode 100644
index 4afd3539b8e..00000000000
--- a/testsuite/libsmbclient/src/getdents/getdents_4.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
- int diramount = 0;
-
- struct smbc_dirent *dirptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- diramount = smbc_getdents( dh, dirptr, 20 /*sizeof(dirbuff)*/ );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/getdents/getdents_5.c b/testsuite/libsmbclient/src/getdents/getdents_5.c
deleted file mode 100644
index 5cf7c1b9282..00000000000
--- a/testsuite/libsmbclient/src/getdents/getdents_5.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
- int diramount = 0;
-
- struct smbc_dirent *dirptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- diramount = smbc_getdents( dh, dirptr, 20 /* sizeof(dirbuff)*/);
-
- if ( diramount < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/init/init_1.c b/testsuite/libsmbclient/src/init/init_1.c
deleted file mode 100644
index bc928ac3d5c..00000000000
--- a/testsuite/libsmbclient/src/init/init_1.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-
-int main()
-{
- int err = -1;
-
- err = smbc_init(NULL, 0);
-
- if ( err < 0 )
- err = 1;
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/init/init_2.c b/testsuite/libsmbclient/src/init/init_2.c
deleted file mode 100644
index 120160297b6..00000000000
--- a/testsuite/libsmbclient/src/init/init_2.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-
-int main(int argc, char **argv )
-{
- int err = -1;
-
- if ( argc > 1 )
- {
- err = smbc_init(NULL, atoi(argv[1]));
-
- if ( err < 0 )
- err = 1;
-
- }
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/init/init_3.c b/testsuite/libsmbclient/src/init/init_3.c
deleted file mode 100644
index f49ed982e18..00000000000
--- a/testsuite/libsmbclient/src/init/init_3.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- err = smbc_init(auth_fn, atoi(argv[4]));
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/init/init_4.c b/testsuite/libsmbclient/src/init/init_4.c
deleted file mode 100644
index d8e44b50eed..00000000000
--- a/testsuite/libsmbclient/src/init/init_4.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-
-int main( )
-{
- int err = -1;
-
- err = smbc_init(NULL, 0);
-
- err = errno;
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_1.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_1.c
deleted file mode 100644
index 714f08fd723..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_1.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-int call_back_flag;
-int print_queue_empty;
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn_2(struct print_job_info *pji)
-{
- print_queue_empty = 0;
- g_print_id = pji->id;
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- call_back_flag = 1;
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
-
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
- call_back_flag = 0;
- print_queue_empty = 0;
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- while ( ! print_queue_empty ) /* Wait until the queue is empty */
- {
- sleep(1);
- print_queue_empty = 1;
- smbc_list_print_jobs(url,print_list_fn_2);
- }
-
- smbc_list_print_jobs(url,print_list_fn);
-
- if ( call_back_flag )
-
- err = 0;
-
- else
- err = 1;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_2.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_2.c
deleted file mode 100644
index 6d6874716cc..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_2.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-int print_queue_empty;
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn_2(struct print_job_info *pji)
-{
- print_queue_empty = 0;
- g_print_id = pji->id;
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
-
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- print_queue_empty = 0;
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- while ( ! print_queue_empty ) /* Wait until the queue is empty */
- {
- sleep(1);
- print_queue_empty = 1;
- smbc_list_print_jobs(url,print_list_fn_2);
- }
-
- err = smbc_list_print_jobs(url,print_list_fn);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_3.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_3.c
deleted file mode 100644
index 1cb52d08941..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_3.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- err = smbc_list_print_jobs(argv[6],print_list_fn);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_4.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_4.c
deleted file mode 100644
index ad207724b46..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_4.c
+++ /dev/null
@@ -1,99 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- err = smbc_list_print_jobs(argv[6],print_list_fn);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_5.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_5.c
deleted file mode 100644
index 874bc896d06..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_5.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-int print_queue_empty;
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn_2(struct print_job_info *pji)
-{
- print_queue_empty = 0;
- g_print_id = pji->id;
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
-
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- print_queue_empty = 0;
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- while ( ! print_queue_empty ) /* Wait until the queue is empty */
- {
- sleep(1);
- print_queue_empty = 1;
- smbc_list_print_jobs(url,print_list_fn_2);
- }
-
- smbc_list_print_jobs(url,print_list_fn);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_6.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_6.c
deleted file mode 100644
index 7b691ae75ac..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_6.c
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-int print_fn_call_flag;
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-
- print_fn_call_flag = 1;
-
-}
-
-int main(int argc, char** argv)
-{
-
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char * message;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- print_fn_call_flag = 0;
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(url,print_list_fn);
-
- if ( print_fn_call_flag == 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_7.c b/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_7.c
deleted file mode 100644
index d25d20721b1..00000000000
--- a/testsuite/libsmbclient/src/list_print_jobs/list_print_jobs_7.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(argv[6],print_list_fn);
-
-
- if (( (g_print_size > 0) && (g_print_size > 0) && (strcasecmp(g_username,g_print_user)==0) ))
- /* && (strlen(g_print_name) > 0) )) */
- err = 0;
-
- else
- err = 1;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_1.c b/testsuite/libsmbclient/src/lseek/lseek_1.c
deleted file mode 100644
index c358565d31c..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_1.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- smbc_init(auth_fn, 0);
-
- fd = -1;
- err = smbc_lseek(fd, 0, SEEK_SET);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_2.c b/testsuite/libsmbclient/src/lseek/lseek_2.c
deleted file mode 100644
index 8b58ade0836..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_2.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- smbc_init(auth_fn, 0);
-
- fd = -1;
- smbc_lseek(fd, 0, SEEK_SET);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_3.c b/testsuite/libsmbclient/src/lseek/lseek_3.c
deleted file mode 100644
index c8a62e682b2..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_3.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,msg_len,SEEK_SET);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_4.c b/testsuite/libsmbclient/src/lseek/lseek_4.c
deleted file mode 100644
index c8a62e682b2..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_4.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,msg_len,SEEK_SET);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_5.c b/testsuite/libsmbclient/src/lseek/lseek_5.c
deleted file mode 100644
index 2e40c96410c..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_5.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,msg_len,SEEK_SET);
- smbc_close(fd);
-
- if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_6.c b/testsuite/libsmbclient/src/lseek/lseek_6.c
deleted file mode 100644
index b5236b8537e..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_6.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,msg_len,SEEK_SET);
- err = errno;
- smbc_close(fd);
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_7.c b/testsuite/libsmbclient/src/lseek/lseek_7.c
deleted file mode 100644
index e3ef6cdd544..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_7.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,0,SEEK_END);
- smbc_close(fd);
-
- if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseek/lseek_8.c b/testsuite/libsmbclient/src/lseek/lseek_8.c
deleted file mode 100644
index e70f3ca6b55..00000000000
--- a/testsuite/libsmbclient/src/lseek/lseek_8.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_lseek(fd,0,SEEK_END);
- err = errno;
- smbc_close(fd);
-
- free(message);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_1.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_1.c
deleted file mode 100644
index 010ca382a59..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_1.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_lseekdir(dh,0);
- /* printf("err: %i\n",err); */
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_2.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_2.c
deleted file mode 100644
index cb729d8642e..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_2.c
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- smbc_lseekdir(dh,0);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_3.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_3.c
deleted file mode 100644
index ede9cef0815..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_3.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_lseekdir(dh,0);
- /* printf("err: %i\n",err); */
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_4.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_4.c
deleted file mode 100644
index 1bc9a7e45d0..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_4.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- smbc_lseekdir(dh,0);
- err = errno;
- /* printf("err: %i\n",err); */
-
-
- }
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_5.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_5.c
deleted file mode 100644
index 08af806f5fe..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_5.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- int dirsize = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- err = 0;
-
- while ( 1 )
- {
- dirptr = smbc_readdir(dh);
-
- if ( dirptr == NULL )
- {
- break;
- }
-
- (char*)dirsize += dirptr->dirlen;
-
- }
-
- smbc_lseekdir(dh,0);
- err = smbc_telldir(dh);
-
- if ( err != 0 )
- err = 1;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/lseekdir/lseekdir_6.c b/testsuite/libsmbclient/src/lseekdir/lseekdir_6.c
deleted file mode 100644
index 543cbafe140..00000000000
--- a/testsuite/libsmbclient/src/lseekdir/lseekdir_6.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- int offset = 0;
- int dirsize = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- err = 0;
-
- while ( 1 )
- {
- dirptr = smbc_readdir(dh);
-
- if ( dirptr == NULL )
- {
- break;
- }
-
- (char*)dirsize += dirptr->dirlen;
-
- }
-
- smbc_lseekdir(dh,0); /* move to front */
- smbc_lseekdir(dh,dirsize); /* move to end */
- offset = smbc_telldir(dh);
-
- if ( offset != dirsize )
- {
- /* printf("offset: %i dirsize: %i\n",offset,dirsize); */
- err = 1;
- }
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/mkdir/mkdir_1.c b/testsuite/libsmbclient/src/mkdir/mkdir_1.c
deleted file mode 100644
index 20389bcb9b6..00000000000
--- a/testsuite/libsmbclient/src/mkdir/mkdir_1.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_rmdir( url );
- err = smbc_mkdir( url, 0666 );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/mkdir/mkdir_2.c b/testsuite/libsmbclient/src/mkdir/mkdir_2.c
deleted file mode 100644
index ebbc94a18bb..00000000000
--- a/testsuite/libsmbclient/src/mkdir/mkdir_2.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_rmdir( url );
- smbc_mkdir( url, 0666 );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/mkdir/mkdir_3.c b/testsuite/libsmbclient/src/mkdir/mkdir_3.c
deleted file mode 100644
index e5a0ce2561f..00000000000
--- a/testsuite/libsmbclient/src/mkdir/mkdir_3.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_rmdir( url );
-
- smbc_mkdir( url, 0666 );
- smbc_mkdir( url, 0666 );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/mkdir/mkdir_4.c b/testsuite/libsmbclient/src/mkdir/mkdir_4.c
deleted file mode 100644
index ed1aa70f33f..00000000000
--- a/testsuite/libsmbclient/src/mkdir/mkdir_4.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_rmdir( url );
-
- smbc_mkdir( url, 0666 );
- err = smbc_mkdir( url, 0666 );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open/open_1.c b/testsuite/libsmbclient/src/open/open_1.c
deleted file mode 100644
index 9f72985cec7..00000000000
--- a/testsuite/libsmbclient/src/open/open_1.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open/open_2.c b/testsuite/libsmbclient/src/open/open_2.c
deleted file mode 100644
index 8903ee912b0..00000000000
--- a/testsuite/libsmbclient/src/open/open_2.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open/open_3.c b/testsuite/libsmbclient/src/open/open_3.c
deleted file mode 100644
index 25a663d6ab7..00000000000
--- a/testsuite/libsmbclient/src/open/open_3.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open/open_4.c b/testsuite/libsmbclient/src/open/open_4.c
deleted file mode 100644
index 2bfe30f1af1..00000000000
--- a/testsuite/libsmbclient/src/open/open_4.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
- fd = 0;
- fd = smbc_open(url, O_RDWR, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open/open_5.c b/testsuite/libsmbclient/src/open/open_5.c
deleted file mode 100644
index 93ffb4891ed..00000000000
--- a/testsuite/libsmbclient/src/open/open_5.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
- fd = smbc_open(url, O_RDWR, 0666);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open_print_job/open_print_job_1.c b/testsuite/libsmbclient/src/open_print_job/open_print_job_1.c
deleted file mode 100644
index 585fdee377f..00000000000
--- a/testsuite/libsmbclient/src/open_print_job/open_print_job_1.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open_print_job(url);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/open_print_job/open_print_job_2.c b/testsuite/libsmbclient/src/open_print_job/open_print_job_2.c
deleted file mode 100644
index f737f19bfec..00000000000
--- a/testsuite/libsmbclient/src/open_print_job/open_print_job_2.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open_print_job(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/opendir/opendir_1.c b/testsuite/libsmbclient/src/opendir/opendir_1.c
deleted file mode 100644
index 1bd01b5feeb..00000000000
--- a/testsuite/libsmbclient/src/opendir/opendir_1.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
-
- if ( dh < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/opendir/opendir_2.c b/testsuite/libsmbclient/src/opendir/opendir_2.c
deleted file mode 100644
index 60658d2cd56..00000000000
--- a/testsuite/libsmbclient/src/opendir/opendir_2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_opendir(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/opendir/opendir_3.c b/testsuite/libsmbclient/src/opendir/opendir_3.c
deleted file mode 100644
index 3b6f28eaf34..00000000000
--- a/testsuite/libsmbclient/src/opendir/opendir_3.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR|O_CREAT,0666);
- smbc_close(fd);
-
- err = smbc_opendir(url);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/opendir/opendir_4.c b/testsuite/libsmbclient/src/opendir/opendir_4.c
deleted file mode 100644
index 23b25e55063..00000000000
--- a/testsuite/libsmbclient/src/opendir/opendir_4.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR|O_CREAT,0666);
- smbc_close(fd);
-
- smbc_opendir(url);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/print_file/print_file_1.c b/testsuite/libsmbclient/src/print_file/print_file_1.c
deleted file mode 100644
index 19932aa3192..00000000000
--- a/testsuite/libsmbclient/src/print_file/print_file_1.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- err = smbc_print_file(url,argv[6]);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/print_file/print_file_2.c b/testsuite/libsmbclient/src/print_file/print_file_2.c
deleted file mode 100644
index a569cd8fe97..00000000000
--- a/testsuite/libsmbclient/src/print_file/print_file_2.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- smbc_print_file(url,argv[6]);
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/print_file/print_file_3.c b/testsuite/libsmbclient/src/print_file/print_file_3.c
deleted file mode 100644
index 4b2a6af84f2..00000000000
--- a/testsuite/libsmbclient/src/print_file/print_file_3.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
-
- char url[MAX_BUFF_SIZE];
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- err = smbc_print_file(url,argv[6]);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/print_file/print_file_4.c b/testsuite/libsmbclient/src/print_file/print_file_4.c
deleted file mode 100644
index 1650f7340df..00000000000
--- a/testsuite/libsmbclient/src/print_file/print_file_4.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
-
- char url[MAX_BUFF_SIZE];
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_print_file(url,argv[6]);
-
- err = errno;
-
- }
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/read/read_1.c b/testsuite/libsmbclient/src/read/read_1.c
deleted file mode 100644
index accf0bf8721..00000000000
--- a/testsuite/libsmbclient/src/read/read_1.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_RDWR, 0666);
- err = smbc_read(fd,response,msg_len);
-
- free(message);
- free(response);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_10.c b/testsuite/libsmbclient/src/read/read_10.c
deleted file mode 100644
index d5b66dfe635..00000000000
--- a/testsuite/libsmbclient/src/read/read_10.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message = NULL;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- msg_len = 10;
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
-
- err = errno;
-
- smbc_close(fd);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_11.c b/testsuite/libsmbclient/src/read/read_11.c
deleted file mode 100644
index 3f9ae3f97da..00000000000
--- a/testsuite/libsmbclient/src/read/read_11.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDONLY, 0666);
- smbc_read(fd,response,msg_len);
- smbc_close(fd);
-
- if ( memcmp ( message, response, msg_len) == 0 )
- err = 0;
-
- else
- err = 1;
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_12.c b/testsuite/libsmbclient/src/read/read_12.c
deleted file mode 100644
index 2747f62e1c8..00000000000
--- a/testsuite/libsmbclient/src/read/read_12.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- strncpy(g_username,"xxxxxxxx",8);
- strncpy(g_password,"xxxxxxxx",8);
-
- fd = smbc_open(url, O_RDONLY, 0666);
-
- err = smbc_read(fd,response,msg_len);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_13.c b/testsuite/libsmbclient/src/read/read_13.c
deleted file mode 100644
index 89bc68f915b..00000000000
--- a/testsuite/libsmbclient/src/read/read_13.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- strncpy(g_username,"xxxxxxxx",8);
- strncpy(g_password,"xxxxxxxx",8);
-
- fd = smbc_open(url, O_RDONLY, 0666);
-
- if (fd < 0)
-
- err = errno;
-
- else {
-
- err = smbc_read(fd,response,msg_len);
- err = errno;
-
- smbc_close(fd);
-
- }
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_2.c b/testsuite/libsmbclient/src/read/read_2.c
deleted file mode 100644
index 4b3dc9439c1..00000000000
--- a/testsuite/libsmbclient/src/read/read_2.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_RDWR, 0666);
- smbc_read(fd,response,msg_len);
- err = errno;
-
- free(message);
- free(response);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_3.c b/testsuite/libsmbclient/src/read/read_3.c
deleted file mode 100644
index 3f4493487e7..00000000000
--- a/testsuite/libsmbclient/src/read/read_3.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_WRONLY, 0666);
- err = smbc_read(fd,response,msg_len);
-
- free(message);
- free(response);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_4.c b/testsuite/libsmbclient/src/read/read_4.c
deleted file mode 100644
index dbacfa392e8..00000000000
--- a/testsuite/libsmbclient/src/read/read_4.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- bzero(response,msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_WRONLY, 0666);
- smbc_read(fd,response,msg_len);
- err = errno;
-
- free(message);
- free(response);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_5.c b/testsuite/libsmbclient/src/read/read_5.c
deleted file mode 100644
index 96891ef8da6..00000000000
--- a/testsuite/libsmbclient/src/read/read_5.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_RDONLY, 0666);
- err = smbc_read(fd,response,msg_len);
-
- free(message);
- free(response);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_6.c b/testsuite/libsmbclient/src/read/read_6.c
deleted file mode 100644
index 7839a964ee4..00000000000
--- a/testsuite/libsmbclient/src/read/read_6.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- bzero(response,msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url,O_RDONLY, 0666);
- smbc_read(fd,response,msg_len);
- err = errno;
-
- free(message);
- free(response);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_7.c b/testsuite/libsmbclient/src/read/read_7.c
deleted file mode 100644
index fa8a783d7fa..00000000000
--- a/testsuite/libsmbclient/src/read/read_7.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char* message = "Testing";
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- fd = 10345; /* Random value for File Descriptor */
- smbc_init(auth_fn, 0);
- err = smbc_read(fd, message, sizeof(message));
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_8.c b/testsuite/libsmbclient/src/read/read_8.c
deleted file mode 100644
index e3f7055d3f4..00000000000
--- a/testsuite/libsmbclient/src/read/read_8.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char* message = "Testing";
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- fd = 10345; /* Random value for File Descriptor */
- smbc_init(auth_fn, 0);
- err = smbc_read(fd, message, sizeof(message));
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/read/read_9.c b/testsuite/libsmbclient/src/read/read_9.c
deleted file mode 100644
index 77468317d92..00000000000
--- a/testsuite/libsmbclient/src/read/read_9.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message = NULL;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- msg_len = 10;
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_read(fd, message, msg_len);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/readdir/readdir_1.c b/testsuite/libsmbclient/src/readdir/readdir_1.c
deleted file mode 100644
index 5ca7e38bf8d..00000000000
--- a/testsuite/libsmbclient/src/readdir/readdir_1.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- dirptr = smbc_readdir( dh );
-
- if ( dirptr == NULL )
-
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/readdir/readdir_2.c b/testsuite/libsmbclient/src/readdir/readdir_2.c
deleted file mode 100644
index bc4f53dd859..00000000000
--- a/testsuite/libsmbclient/src/readdir/readdir_2.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- dirptr = smbc_readdir( dh );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/readdir/readdir_3.c b/testsuite/libsmbclient/src/readdir/readdir_3.c
deleted file mode 100644
index 06a4c9eded1..00000000000
--- a/testsuite/libsmbclient/src/readdir/readdir_3.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- struct smbc_dirent *dirptr;
-
-
- char url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- dirptr = smbc_readdir( dh );
-
- if ( dirptr == NULL )
-
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/readdir/readdir_4.c b/testsuite/libsmbclient/src/readdir/readdir_4.c
deleted file mode 100644
index 42b18aaa48b..00000000000
--- a/testsuite/libsmbclient/src/readdir/readdir_4.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- struct smbc_dirent *dirptr;
-
-
- char url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
-
- dh = smbc_opendir(url);
- dirptr = smbc_readdir( dh );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/readdir/readdir_5.c b/testsuite/libsmbclient/src/readdir/readdir_5.c
deleted file mode 100644
index de94c4698e3..00000000000
--- a/testsuite/libsmbclient/src/readdir/readdir_5.c
+++ /dev/null
@@ -1,155 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- int j = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
-
- err = 0;
- i = 0;
- bzero(buff,MAX_BUFF_SIZE);
- bzero(tmp_file_ptr,MAX_BUFF_SIZE-9);
-
- while ( 1 )
- {
- dirptr = smbc_readdir( dh );
- if ( dirptr == NULL )
- {
- break;
- }
-
- /* printf("Name: %s\n",dirptr->name); */
- if ( j == 0 )
- {
- if ( !(( strncmp(dirptr->name,".",1) == 0 )) )
- {
- break;
- err = 1;
- }
-
- } else if ( j == 1 ) {
-
- if ( !(( strncmp(dirptr->name,"..",2) == 0 )) )
- {
- break;
- err = 1;
- }
-
- } else if ( j > 1 ) {
-
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
-
- if ( !(( strcmp(dirptr->name,file_url) == 0 )) ) /* make sure entries match */
- {
- err = 1;
- break;
- }
-
- i++;
-
- }
-
- j++;
-
- }
-
- if ( ! err )
- {
- if ( (j - 2) != entry_num ) /* Make sure that all entries created are counted and returned - minus . and .. */
- err = 1;
- }
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_1.c b/testsuite/libsmbclient/src/rename/rename_1.c
deleted file mode 100644
index c3e1377c293..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_1.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- err = smbc_rename( url, argv[5] );
-
- if ( err < 0 )
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_10.c b/testsuite/libsmbclient/src/rename/rename_10.c
deleted file mode 100644
index 01fb144c593..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_10.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 9 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[6], strlen(argv[6]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_mkdir( argv[7], 0700 );
-
- strncpy( g_username, argv[4], strlen(argv[4]) );
- strncpy( g_password, argv[5], strlen(argv[5]) );
-
- smbc_rename( url, argv[8] );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_11.c b/testsuite/libsmbclient/src/rename/rename_11.c
deleted file mode 100644
index 0c341088026..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_11.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- err = smbc_rename( NULL, url );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_12.c b/testsuite/libsmbclient/src/rename/rename_12.c
deleted file mode 100644
index cc34e079e18..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_12.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_rename( NULL, url );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_13.c b/testsuite/libsmbclient/src/rename/rename_13.c
deleted file mode 100644
index 30b33499d60..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_13.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- err = smbc_rename( url, NULL );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_14.c b/testsuite/libsmbclient/src/rename/rename_14.c
deleted file mode 100644
index 61aad34e722..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_14.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_rename( url, NULL );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_2.c b/testsuite/libsmbclient/src/rename/rename_2.c
deleted file mode 100644
index b3d340348c8..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_2.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_rename( url, argv[5] );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_3.c b/testsuite/libsmbclient/src/rename/rename_3.c
deleted file mode 100644
index a7508e969c8..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_open(url,O_RDWR | O_CREAT,0666);
- err = smbc_rename( url, argv[5] );
-
- if ( err < 0 )
- err = 1;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_4.c b/testsuite/libsmbclient/src/rename/rename_4.c
deleted file mode 100644
index a4c26470017..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_4.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_open(url,O_RDWR | O_CREAT,0666);
- smbc_rename( url, argv[5] );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_5.c b/testsuite/libsmbclient/src/rename/rename_5.c
deleted file mode 100644
index 97fb8fe6830..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_5.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd );
- err = smbc_rename( url, argv[5] );
-
- if ( err < 0 )
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_6.c b/testsuite/libsmbclient/src/rename/rename_6.c
deleted file mode 100644
index c9c349427e4..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_6.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url,O_RDWR | O_CREAT,0666);
- smbc_close( fd );
- smbc_rename( url, argv[5] );
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_7.c b/testsuite/libsmbclient/src/rename/rename_7.c
deleted file mode 100644
index 67188abea96..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_7.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- int fd2 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_rename( url, argv[5] );
- fd1 = smbc_open( url, O_RDWR, 0666 );
- fd2 = smbc_open( argv[5], O_RDWR, 0666 );
-
- if ( fd1 == -1 && fd2 != -1 )
- err = 0;
-
- else
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_8.c b/testsuite/libsmbclient/src/rename/rename_8.c
deleted file mode 100644
index efbef5c30cd..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_8.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- int fd2 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 7 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_mkdir( argv[5], 0666 );
- smbc_rename( url, argv[6] );
-
- fd1 = smbc_open( url, O_RDWR, 0666 );
- fd2 = smbc_open( argv[6], O_RDWR, 0666 );
-
- if ( fd1 == -1 && fd2 != -1 )
- err = 0;
-
- else
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rename/rename_9.c b/testsuite/libsmbclient/src/rename/rename_9.c
deleted file mode 100644
index 1c1876dbb00..00000000000
--- a/testsuite/libsmbclient/src/rename/rename_9.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 9 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[6], strlen(argv[6]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_mkdir( argv[7], 0700 );
-
- strncpy( g_username, argv[4], strlen(argv[4]) );
- strncpy( g_password, argv[5], strlen(argv[5]) );
-
- err = smbc_rename( url, argv[8] );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_1.c b/testsuite/libsmbclient/src/rmdir/rmdir_1.c
deleted file mode 100644
index 2c64052d8be..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_1.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- err = smbc_rmdir( url );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_2.c b/testsuite/libsmbclient/src/rmdir/rmdir_2.c
deleted file mode 100644
index 700b1d7a97f..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_rmdir( url );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_3.c b/testsuite/libsmbclient/src/rmdir/rmdir_3.c
deleted file mode 100644
index c1b881d4d4d..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_3.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_mkdir( url, 700 );
-
- err = smbc_rmdir( url );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_4.c b/testsuite/libsmbclient/src/rmdir/rmdir_4.c
deleted file mode 100644
index a7723037256..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_4.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- smbc_mkdir( url, 700 );
-
- smbc_rmdir( url );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_5.c b/testsuite/libsmbclient/src/rmdir/rmdir_5.c
deleted file mode 100644
index c4f787f63bc..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_5.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- err = smbc_rmdir( url );
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/rmdir/rmdir_6.c b/testsuite/libsmbclient/src/rmdir/rmdir_6.c
deleted file mode 100644
index a44e6778322..00000000000
--- a/testsuite/libsmbclient/src/rmdir/rmdir_6.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd1 = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
- strncpy( g_workgroup, argv[1], strlen(argv[1]) );
- strncpy( g_username, argv[2], strlen(argv[2]) );
- strncpy( g_password, argv[3], strlen(argv[3]) );
- strncpy( url, argv[4], strlen(argv[4]) );
-
- smbc_init( auth_fn, 0 );
- fd1 = smbc_open( url, O_RDWR | O_CREAT, 0666 );
- smbc_close( fd1 );
-
- smbc_rmdir( url );
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_1.c b/testsuite/libsmbclient/src/stat/stat_1.c
deleted file mode 100644
index 08382acd74a..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_1.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- err = smbc_stat(url, &st);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_2.c b/testsuite/libsmbclient/src/stat/stat_2.c
deleted file mode 100644
index 80ee5dd8713..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_2.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_stat(url, &st);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_3.c b/testsuite/libsmbclient/src/stat/stat_3.c
deleted file mode 100644
index 1220577a3c7..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_3.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- err = smbc_stat(url, &st);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_4.c b/testsuite/libsmbclient/src/stat/stat_4.c
deleted file mode 100644
index 8bc544833e7..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_4.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- smbc_stat(url, &st);
-
- err = errno;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_5.c b/testsuite/libsmbclient/src/stat/stat_5.c
deleted file mode 100644
index 86028f0598a..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_5.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- smbc_stat(url,&st);
-
- free(message);
-
- if ( st.st_size != msg_len )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/stat/stat_6.c b/testsuite/libsmbclient/src/stat/stat_6.c
deleted file mode 100644
index 071bdd0f2f0..00000000000
--- a/testsuite/libsmbclient/src/stat/stat_6.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- unsigned int mode_mask = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- struct stat st;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- smbc_stat(url,&st);
-
- free(message);
-
- mode_mask = mode_mask | S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* 0666 or 33206 */
-
- if ( st.st_mode != mode_mask )
- err = 1;
-
- else
- err = 0;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/telldir/telldir_1.c b/testsuite/libsmbclient/src/telldir/telldir_1.c
deleted file mode 100644
index 725033f453c..00000000000
--- a/testsuite/libsmbclient/src/telldir/telldir_1.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_telldir(dh);
- /* printf("err: %i\n",err); */
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/telldir/telldir_2.c b/testsuite/libsmbclient/src/telldir/telldir_2.c
deleted file mode 100644
index 6971b79b0f9..00000000000
--- a/testsuite/libsmbclient/src/telldir/telldir_2.c
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- smbc_telldir(dh);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/telldir/telldir_3.c b/testsuite/libsmbclient/src/telldir/telldir_3.c
deleted file mode 100644
index 06ba59538ae..00000000000
--- a/testsuite/libsmbclient/src/telldir/telldir_3.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- err = smbc_telldir(dh);
- /* printf("err: %i\n",err); */
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/telldir/telldir_4.c b/testsuite/libsmbclient/src/telldir/telldir_4.c
deleted file mode 100644
index 14184237d76..00000000000
--- a/testsuite/libsmbclient/src/telldir/telldir_4.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int dh = 0;
-
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
-
- dh = smbc_opendir(url);
- /* printf("directory handle: %i\n",dh); */
- smbc_telldir(dh);
- err = errno;
- /* printf("err: %i\n",err); */
-
-
- }
-
- return err;
-
-}
diff --git a/testsuite/libsmbclient/src/telldir/telldir_5.c b/testsuite/libsmbclient/src/telldir/telldir_5.c
deleted file mode 100644
index 9172b2d1aba..00000000000
--- a/testsuite/libsmbclient/src/telldir/telldir_5.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int dh = 0;
- int entry_num = 0;
- int i = 0;
- int offset = 0;
- int dirsize = 0;
- char *file_name;
- char *tmp_file_ptr;
-
- struct smbc_dirent *dirptr;
-
-
- char buff[MAX_BUFF_SIZE];
- char url[MAX_BUFF_SIZE];
- char file_url[MAX_BUFF_SIZE];
- char dir_url[MAX_BUFF_SIZE];
- char dirbuff[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(file_url,MAX_BUFF_SIZE);
- bzero(dir_url,MAX_BUFF_SIZE);
- bzero(buff,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- dirptr = (struct smbc_dirent *) dirbuff;
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
- smbc_init(auth_fn, 0);
-
- strncpy(file_url,"tempfile-",9);
- tmp_file_ptr = file_url;
- tmp_file_ptr += 9;
-
- smbc_rmdir(url);
- smbc_mkdir(url,0666);
-
- entry_num = atoi(argv[5]);
- strcat(dir_url,url);
- strcat(dir_url,"/");
-
- file_name = dir_url;
- file_name += strlen(dir_url);
-
- for ( i = 0; i < entry_num; i++ )
- {
- sprintf(buff,"%d",i);
- memcpy(tmp_file_ptr,buff,strlen(buff)+4);
- strncat(tmp_file_ptr,".txt",4);
- strcpy(file_name,file_url);
- fd = smbc_open(dir_url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- }
-
- dh = smbc_opendir(url);
- err = 0;
-
- while ( 1 )
- {
- dirptr = smbc_readdir(dh);
-
- if ( dirptr == NULL )
- {
- break;
- }
-
- (char*)dirsize += dirptr->dirlen;
-
- }
-
- offset = smbc_telldir(dh);
-
- if ( offset != dirsize )
- {
- /* printf("offset: %i dirsize: %i\n",offset,dirsize); */
- err = 1;
- }
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_1.c b/testsuite/libsmbclient/src/unlink/unlink_1.c
deleted file mode 100644
index 12e9d1d0aa8..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_1.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_10.c b/testsuite/libsmbclient/src/unlink/unlink_10.c
deleted file mode 100644
index 58f541c69a1..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_10.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0000);
- smbc_close(fd);
-
- strncpy(g_username, "xxxxxx", 6);
- strncpy(g_password, "xxxxxx", 6);
-
- smbc_unlink(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_11.c b/testsuite/libsmbclient/src/unlink/unlink_11.c
deleted file mode 100644
index f94b93d0482..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_11.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0000);
- smbc_close(fd);
-
- strncpy(g_username, "xxxxxx", 6);
- strncpy(g_password, "xxxxxx", 6);
-
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_12.c b/testsuite/libsmbclient/src/unlink/unlink_12.c
deleted file mode 100644
index f6082595a35..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_12.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- smbc_unlink(url);
-
- fd = smbc_open(url, O_RDWR, 0666);
-
- if ( fd < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_2.c b/testsuite/libsmbclient/src/unlink/unlink_2.c
deleted file mode 100644
index 3980704847f..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_2.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_mkdir(url, 0666);
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_3.c b/testsuite/libsmbclient/src/unlink/unlink_3.c
deleted file mode 100644
index 551a651ae45..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_3.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_mkdir(url, 0666);
- smbc_unlink(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_4.c b/testsuite/libsmbclient/src/unlink/unlink_4.c
deleted file mode 100644
index 309dc39639d..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_4.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[6],strlen(argv[6]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- strncpy(g_username,argv[4],strlen(argv[4]));
- strncpy(g_password,argv[5],strlen(argv[5]));
-
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_5.c b/testsuite/libsmbclient/src/unlink/unlink_5.c
deleted file mode 100644
index 73a8e057a6b..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_5.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_6.c b/testsuite/libsmbclient/src/unlink/unlink_6.c
deleted file mode 100644
index 334c3653d1f..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_6.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
- smbc_unlink(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_7.c b/testsuite/libsmbclient/src/unlink/unlink_7.c
deleted file mode 100644
index cda3c9d7b07..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_7.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[6],strlen(argv[6]));
-
- smbc_init(auth_fn, 0);
- fd = smbc_open(url, O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- strncpy(g_username,argv[4],strlen(argv[4]));
- strncpy(g_password,argv[5],strlen(argv[5]));
-
- smbc_unlink(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_8.c b/testsuite/libsmbclient/src/unlink/unlink_8.c
deleted file mode 100644
index 2053be3c961..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_8.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink/unlink_9.c b/testsuite/libsmbclient/src/unlink/unlink_9.c
deleted file mode 100644
index 78f9c297481..00000000000
--- a/testsuite/libsmbclient/src/unlink/unlink_9.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- char url[MAX_BUFF_SIZE];
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- err = smbc_unlink(url);
-
- if ( err < 0 )
- err = 1;
-
-
- }
-
- return 1;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_1.c b/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_1.c
deleted file mode 100644
index b19bf228de1..00000000000
--- a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_1.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(argv[6],print_list_fn);
-
- g_print_id = -1;
- err = smbc_unlink_print_job(argv[6],g_print_id);
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_2.c b/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_2.c
deleted file mode 100644
index 52f127c3629..00000000000
--- a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_2.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(argv[6],print_list_fn);
-
- g_print_id = -1;
- smbc_unlink_print_job(argv[6],g_print_id);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_3.c b/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_3.c
deleted file mode 100644
index 5686b3f53ed..00000000000
--- a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_3.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(argv[6],print_list_fn);
-
- err = smbc_unlink_print_job(argv[6],g_print_id);
-
- if ( err < 0 )
-
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_4.c b/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_4.c
deleted file mode 100644
index 28966f8af4d..00000000000
--- a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_4.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
- smbc_print_file(url,argv[6]);
- smbc_list_print_jobs(argv[6],print_list_fn);
-
- smbc_unlink_print_job(argv[6],g_print_id);
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_5.c b/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_5.c
deleted file mode 100644
index 4fb3e30017b..00000000000
--- a/testsuite/libsmbclient/src/unlink_print_job/unlink_print_job_5.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-char g_print_user[MAX_BUFF_SIZE];
-char g_print_name[MAX_BUFF_SIZE];
-unsigned int g_print_id;
-unsigned int g_print_priority;
-unsigned int g_print_size;
-
-unsigned int print_ids[MAX_BUFF_SIZE];
-unsigned int print_id_count;
-int call_flag;
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-void print_list_fn_2(struct print_job_info *pji)
-{
-
- print_ids[print_id_count] = pji->id;
- print_id_count++;
-
- /* fprintf(stdout, "Call to Second Print Function - Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-void print_list_fn(struct print_job_info *pji)
-{
-
- g_print_id = pji->id;
- g_print_priority = pji->priority;
- g_print_size = pji->size;
- strcpy(g_print_user,pji->user);
- strcpy(g_print_name,pji->name);
-
- /* fprintf(stdout, "Call to First Print Function - Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n",
- pji->id, pji->priority, pji->size, pji->user, pji->name); */
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- unsigned int i = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
- bzero(g_print_user,MAX_BUFF_SIZE);
- bzero(g_print_name,MAX_BUFF_SIZE);
-
- g_print_id = 0;
- g_print_priority = 0;
- g_print_size = 0;
-
- print_id_count = 0;
-
- if ( argc == 7 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
- /* printf("Message: %s\n",message); */
- /* printf("Message len: %i\n",msg_len); */
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- smbc_print_file(url,argv[6]);
- smbc_print_file(url,argv[6]);
- smbc_print_file(url,argv[6]);
-
- smbc_list_print_jobs(argv[6],print_list_fn);
-
- if ( smbc_unlink_print_job(argv[6],g_print_id) == 0 )
- {
- if ( smbc_list_print_jobs(argv[6],print_list_fn_2) == 0 )
- {
- err = 0;
-
- for ( i=0; i<print_id_count; i++ )
- {
- if ( g_print_id == print_ids[i] )
- {
- err = 1;
- break;
- }
-
- }
- }
-
- } else
- err = 1;
-
-
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_1.c b/testsuite/libsmbclient/src/write/write_1.c
deleted file mode 100644
index fa147f8f503..00000000000
--- a/testsuite/libsmbclient/src/write/write_1.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- err = smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_10.c b/testsuite/libsmbclient/src/write/write_10.c
deleted file mode 100644
index 1f43c60bb75..00000000000
--- a/testsuite/libsmbclient/src/write/write_10.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message = NULL;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- msg_len = 10;
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
-
- err = errno;
-
- smbc_close(fd);
-
- free(message);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_11.c b/testsuite/libsmbclient/src/write/write_11.c
deleted file mode 100644
index 3f9ae3f97da..00000000000
--- a/testsuite/libsmbclient/src/write/write_11.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDWR, 0666);
- smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDONLY, 0666);
- smbc_read(fd,response,msg_len);
- smbc_close(fd);
-
- if ( memcmp ( message, response, msg_len) == 0 )
- err = 0;
-
- else
- err = 1;
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_12.c b/testsuite/libsmbclient/src/write/write_12.c
deleted file mode 100644
index 3528dbb36e2..00000000000
--- a/testsuite/libsmbclient/src/write/write_12.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- strncpy(g_username,"xxxxxxxx",8);
- strncpy(g_password,"xxxxxxxx",8);
-
- fd = smbc_open(url, O_RDWR, 0666);
-
- err = smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_13.c b/testsuite/libsmbclient/src/write/write_13.c
deleted file mode 100644
index f3c2ad5bc3f..00000000000
--- a/testsuite/libsmbclient/src/write/write_13.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
- char* response;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- response = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- strncpy(g_username,"xxxxxxxx",8);
- strncpy(g_password,"xxxxxxxx",8);
-
- fd = smbc_open(url, O_RDWR, 0666);
-
- if (fd < 0)
-
- err = errno;
-
- else {
-
- smbc_write(fd, message, msg_len);
- err = errno;
-
- smbc_close(fd);
-
- }
-
- free(message);
- free(response);
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_2.c b/testsuite/libsmbclient/src/write/write_2.c
deleted file mode 100644
index 49763ebe0cd..00000000000
--- a/testsuite/libsmbclient/src/write/write_2.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
-
- smbc_write(fd, message, msg_len);
- err = errno;
-
- smbc_close(fd);
-
- free(message);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_3.c b/testsuite/libsmbclient/src/write/write_3.c
deleted file mode 100644
index 254782946d7..00000000000
--- a/testsuite/libsmbclient/src/write/write_3.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDONLY, 0666);
- err = smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_4.c b/testsuite/libsmbclient/src/write/write_4.c
deleted file mode 100644
index 6ee585f0210..00000000000
--- a/testsuite/libsmbclient/src/write/write_4.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_RDONLY, 0666);
-
- smbc_write(fd, message, msg_len);
- err = errno;
-
- smbc_close(fd);
-
- free(message);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_5.c b/testsuite/libsmbclient/src/write/write_5.c
deleted file mode 100644
index 84cb50123cc..00000000000
--- a/testsuite/libsmbclient/src/write/write_5.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_WRONLY, 0666);
- err = smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- if ( err < 0 )
- err = 1;
-
- else if ( err != msg_len )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_6.c b/testsuite/libsmbclient/src/write/write_6.c
deleted file mode 100644
index c139ff81379..00000000000
--- a/testsuite/libsmbclient/src/write/write_6.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 6 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- msg_len = strlen(argv[5])+1;
- message = malloc(msg_len);
- message[msg_len - 1] = 0;
- strncpy(message,argv[5],msg_len);
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- fd = smbc_open(url, O_WRONLY, 0666);
-
- smbc_write(fd, message, msg_len);
- err = errno;
-
- smbc_close(fd);
-
- free(message);
-
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_7.c b/testsuite/libsmbclient/src/write/write_7.c
deleted file mode 100644
index bc509f1efd3..00000000000
--- a/testsuite/libsmbclient/src/write/write_7.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char* message = "Testing";
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- fd = 10345; /* Random value for File Descriptor */
- smbc_init(auth_fn, 0);
- err = smbc_write(fd, message, sizeof(message));
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_8.c b/testsuite/libsmbclient/src/write/write_8.c
deleted file mode 100644
index acc20f19586..00000000000
--- a/testsuite/libsmbclient/src/write/write_8.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- char* message = "Testing";
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
-
- if ( argc == 4 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
-
- fd = 10345; /* Random value for File Descriptor */
- smbc_init(auth_fn, 0);
- err = smbc_write(fd, message, sizeof(message));
-
- err = errno;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/libsmbclient/src/write/write_9.c b/testsuite/libsmbclient/src/write/write_9.c
deleted file mode 100644
index b707d5c688e..00000000000
--- a/testsuite/libsmbclient/src/write/write_9.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <libsmbclient.h>
-
-#define MAX_BUFF_SIZE 255
-char g_workgroup[MAX_BUFF_SIZE];
-char g_username[MAX_BUFF_SIZE];
-char g_password[MAX_BUFF_SIZE];
-char g_server[MAX_BUFF_SIZE];
-char g_share[MAX_BUFF_SIZE];
-
-
-void auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen,
- char *username, int unmaxlen, char *password, int pwmaxlen)
-{
-
- strncpy(workgroup, g_workgroup, wgmaxlen - 1);
-
- strncpy(username, g_username, unmaxlen - 1);
-
- strncpy(password, g_password, pwmaxlen - 1);
-
- strcpy(g_server, server);
- strcpy(g_share, share);
-
-}
-
-int main(int argc, char** argv)
-{
- int err = -1;
- int fd = 0;
- int msg_len = 0;
- char url[MAX_BUFF_SIZE];
- char* message = NULL;
-
- bzero(g_workgroup,MAX_BUFF_SIZE);
- bzero(url,MAX_BUFF_SIZE);
-
- if ( argc == 5 )
- {
-
- strncpy(g_workgroup,argv[1],strlen(argv[1]));
- strncpy(g_username,argv[2],strlen(argv[2]));
- strncpy(g_password,argv[3],strlen(argv[3]));
- strncpy(url,argv[4],strlen(argv[4]));
-
- smbc_init(auth_fn, 0);
- smbc_unlink(url);
- fd = smbc_open(url,O_RDWR | O_CREAT, 0666);
- smbc_close(fd);
-
- msg_len = 10;
- fd = smbc_open(url, O_RDWR, 0666);
- err = smbc_write(fd, message, msg_len);
- smbc_close(fd);
-
- free(message);
-
- if ( err < 0 )
- err = 1;
-
- else
- err = 0;
-
- }
-
- return err;
-
-}
-
diff --git a/testsuite/nsswitch/domusers.exp b/testsuite/nsswitch/domusers.exp
deleted file mode 100644
index 3b291ab398b..00000000000
--- a/testsuite/nsswitch/domusers.exp
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# @(#) Test that all users are members of the Domain Users group.
-#
-# Note that this isn't necessarily true all the time but you have to
-# explicitly move people out of that group so it should be OK for te
-#
-
-load_lib util-defs.exp
-load_lib $srcdir/lib/nsswitch-config.exp
-
-# Get list of users and stick usernames in a hash
-
-set user_list [util_start "getent" "passwd" ""]
-
-foreach { user } [split $user_list "\n"] {
- set user_elts [split $user ":"]
- set users([lindex $user_elts 0]) 1
-}
-
-# Get list of groups
-
-set group_list [util_start "getent" "group" ""]
-
-foreach { group } [split $group_list "\n"] {
- set group_elts [split $group ":"]
-
- # Look for domain users group
-
- if { ![regexp "Domain Users" [lindex $group_elts 0]] } {
- continue
- }
-
- # Check each member of group was found in getent passwd
-
- foreach { mem } [split [lindex $group_elts 3] ","] {
- set mems($mem) 1
- }
-}
diff --git a/testsuite/nsswitch/finger.exp b/testsuite/nsswitch/finger.exp
index 36bab8e1990..ab3b28f58fc 100644
--- a/testsuite/nsswitch/finger.exp
+++ b/testsuite/nsswitch/finger.exp
@@ -12,10 +12,10 @@ if { [regexp "Error" $output] } {
set user_list [split $output "\n"]
-# Look up all users using finger -m. This should test getpwnam()
+# Look up all users using finger. This should test getpwnam()
foreach { user } $user_list {
- set output [util_start "finger" "-m \"$user\"" "" "no such user"]
+ set output [util_start "finger" "-m $user" "" "no such user"]
verbose $output
if { [regexp "no such user" $output] } {
@@ -25,10 +25,12 @@ foreach { user } $user_list {
}
}
+verbose "testing finger -m"
+
# Run finger without the -m to also test set/get/endpwent()
foreach { user } $user_list {
- set output [util_start "finger" "\"$user\""]
+ set output [util_start "finger" "-m $user"]
verbose $output
if { [regexp "no such user" $output] } {
diff --git a/testsuite/printing/psec.c b/testsuite/printing/psec.c
index 7ba40b18a31..f86b5aca8f6 100644
--- a/testsuite/printing/psec.c
+++ b/testsuite/printing/psec.c
@@ -1,6 +1,5 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0
Printer security permission manipulation.
@@ -67,6 +66,8 @@
TDB_CONTEXT *tdb;
+#if 0 /* Unused */
+
/* ACE type conversions */
char *ace_type_to_str(uint ace_type)
@@ -135,7 +136,7 @@ char *ace_to_str(SEC_ACE *ace)
static pstring temp;
fstring sidstr;
- sid_to_string(sidstr, &ace->sid);
+ sid_to_string(sidstr, &ace->trustee);
slprintf(temp, sizeof(temp) - 1, "%s %d %s %s",
ace_type_to_str(ace->type), ace->flags,
@@ -155,6 +156,8 @@ void str_to_ace(SEC_ACE *ace, char *ace_str)
init_sec_ace(ace, &sid, type, sa, flags);
}
+#endif /* unused */
+
/* Get a printer security descriptor */
int psec_getsec(char *printer)
@@ -169,13 +172,11 @@ int psec_getsec(char *printer)
/* Open tdb for reading */
- slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
- lp_lockdir());
-
+ slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntprinters.tdb", LOCKDIR);
tdb = tdb_open(tdb_path, 0, 0, O_RDONLY, 0600);
if (!tdb) {
- printf("psec: failed to open nt drivers database: %s\n",
+ printf("psec: failed to open nt printers database: %s\n",
sys_errlist[errno]);
return 1;
}
@@ -195,11 +196,8 @@ int psec_getsec(char *printer)
if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
printf("error fetching descriptor for printer %s\n",
printer);
- /* cannot do a prs_mem_free() when tdb_prs_fetch fails */
- /* as the prs structure has not been initialized */
- tdb_close(tdb);
- talloc_destroy(mem_ctx);
- return 1;
+ result = 1;
+ goto done;
}
/* Unpack into security descriptor buffer */
@@ -238,7 +236,7 @@ int psec_getsec(char *printer)
for (i = 0; i < secdesc_ctr->sec->dacl->num_aces; i++) {
SEC_ACE *ace = &secdesc_ctr->sec->dacl->ace[i];
- sid_to_string(sidstr, &ace->sid);
+ sid_to_string(sidstr, &ace->trustee);
printf("%d %d 0x%08x %s\n", ace->type, ace->flags,
ace->info.mask, sidstr);
@@ -247,7 +245,6 @@ int psec_getsec(char *printer)
done:
if (tdb) tdb_close(tdb);
if (mem_ctx) talloc_destroy(mem_ctx);
- if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
prs_mem_free(&ps);
return result;
@@ -269,17 +266,23 @@ int psec_setsec(char *printer)
TALLOC_CTX *mem_ctx = NULL;
BOOL has_user_sid = False, has_group_sid = False;
+ /* Init memory */
+
ZERO_STRUCT(ps);
- /* Open tdb for reading */
+ if (!(mem_ctx = talloc_init())) {
+ printf("memory allocation error\n");
+ result = 1;
+ goto done;
+ }
- slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
- lp_lockdir());
+ /* Open tdb for reading */
+ slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntprinters.tdb", LOCKDIR);
tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);
if (!tdb) {
- printf("psec: failed to open nt drivers database: %s\n",
+ printf("psec: failed to open nt printers database: %s\n",
sys_errlist[errno]);
result = 1;
goto done;
@@ -325,36 +328,24 @@ int psec_setsec(char *printer)
num_aces++;
}
- dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
+ dacl = make_sec_acl(mem_ctx, ACL_REVISION, num_aces, ace_list);
free(ace_list);
/* Create security descriptor */
- sd = make_sec_desc(SEC_DESC_REVISION,
+ sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
has_user_sid ? &user_sid : NULL,
has_group_sid ? &group_sid : NULL,
NULL, /* System ACL */
dacl, /* Discretionary ACL */
&size);
- free_sec_acl(&dacl);
-
- sdb = make_sec_desc_buf(size, sd);
-
- free_sec_desc(&sd);
+ sdb = make_sec_desc_buf(mem_ctx, size, sd);
/* Write security descriptor to tdb */
- mem_ctx = talloc_init();
-
- if (!mem_ctx) {
- printf("memory allocation error\n");
- result = 1;
- goto done;
- }
-
prs_init(&ps, (uint32)sec_desc_size(sdb->sec) +
- sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
+ sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
printf("sec_io_desc_buf failed\n");
@@ -370,7 +361,6 @@ int psec_setsec(char *printer)
done:
if (tdb) tdb_close(tdb);
- if (sdb) free_sec_desc_buf(&sdb);
if (mem_ctx) talloc_destroy(mem_ctx);
prs_mem_free(&ps);
@@ -388,8 +378,6 @@ void usage(void)
int main(int argc, char **argv)
{
- pstring servicesf = CONFIGFILE;
-
/* Argument check */
if (argc == 1) {
@@ -397,16 +385,6 @@ int main(int argc, char **argv)
return 1;
}
- /* Load smb.conf file */
-
- charset_initialise();
-
- if (!lp_load(servicesf,False,False,True)) {
- fprintf(stderr, "Couldn't load confiuration file %s\n",
- servicesf);
- return 1;
- }
-
/* Do commands */
if (strcmp(argv[1], "setsec") == 0) {